diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..a1169c712 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,43 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at a.maggiulli@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4. diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 000000000..f506cf261 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,123 @@ +# Contributing to QLNet + +Love QLNet and want to help? Thanks so much, there's something to do for everybody! + +Please take a moment to review this document in order to make the contribution process easy and effective for everyone involved. + +Following these guidelines helps to communicate that you respect the time of the developers managing and developing this open source project. In return, they should reciprocate that respect in addressing your issue or assessing patches and features. + +## Using the issue tracker + +The [issue tracker](https://github.com/amaggiulli/qlnet/issues) is +the preferred channel for [bug reports](#bugs), [features requests](#features) +and [submitting pull requests](#pull-requests). + + +## Bug reports + +A bug is a _demonstrable problem_ that is caused by the code in the repository. +Good bug reports are extremely helpful - thank you! + +Guidelines for bug reports: + +1. **Use the GitHub issue search** — check if the issue has already been reported. + +2. **Check if the issue has been fixed** — try to reproduce it using the latest `master` or development branch in the repository. + +3. **Isolate the problem** — + +A good bug report shouldn't leave others needing to chase you up for more information. Please try to be as detailed as possible in your report. What is your environment? What steps will reproduce the issue? What OS +experience the problem? What version of .NET Framework ? All these details will help people to fix any potential bugs. + +Example: + +> Short and descriptive example bug report title +> +> A summary of the issue and the .NET/OS environment in which it occurs. If +> suitable, include the steps required to reproduce the bug. +> +> 1. This is the first step +> 2. This is the second step +> 3. Further steps, etc. +> +> `` - a link to the reduced test case +> +> Any other information you want to share that is relevant to the issue being +> reported. This might include the lines of code that you have identified as +> causing the bug, and potential solutions (and your opinions on their +> merits). + + + +## Feature requests + +Feature requests are welcome. But take a moment to find out whether your idea fits with the scope and aims of the project. It's up to *you* to make a strong case to convince the project's developers of the merits of this feature. Please provide as much detail and context as possible. + + + +## Pull requests + +Good pull requests - patches, improvements, new features - are a fantastic +help. They should remain focused in scope and avoid containing unrelated +commits. + +**Please ask first** before embarking on any significant pull request (e.g. +implementing features, refactoring code, porting to a different language), +otherwise you risk spending a lot of time working on something that the +project's developers might not want to merge into the project. + +Please adhere to the coding conventions used throughout a project (indentation, +accurate comments, etc.) and any other requirements (such as test coverage). + +Adhering to the following process is the best way to get your work +included in the project: + +1. [Fork](https://help.github.com/articles/fork-a-repo/) the project, clone your fork, and configure the remotes: + + ```bash + # Clone your fork of the repo into the current directory + git clone https://github.com//qlnet.git + # Navigate to the newly cloned directory + cd qlnet + # Assign the original repo to a remote called "upstream" + git remote add upstream https://github.com/amaggiulli/qlnet.git + ``` + +2. If you cloned a while ago, get the latest changes from upstream: + + ```bash + git checkout develop + git pull upstream develop + ``` + +3. Create a new topic branch (off the main project development branch) to contain your feature, change, or fix: + + ```bash + git checkout -b some-feature develop + ``` + +4. Commit your changes in logical chunks. Please adhere to the project git commit message guideline or your code is unlikely be merged into the main project. Use Git's [interactive rebase](https://help.github.com/articles/about-git-rebase/) feature to tidy up your commits before making them public. + +5. Locally merge (or rebase) the upstream development branch into your topic branch: + + ```bash + git pull [--rebase] upstream develop + ``` + +6. Push your topic branch up to your fork: + + ```bash + git push origin + ``` + +7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) + with a clear title and description. + +To help you get your feet wet and get you familiar with our contribution process, we have a list of [good first issues](https://github.com/amaggiulli/qlnet/issues?q=is:open+is:issue+label:"good+first+issue") that contain bugs that have a relatively limited scope. This is a great place to get started. + +If you decide to fix an issue, please be sure to check the comment thread in case somebody is already working on a fix. If nobody is working on it at the moment, please leave a comment stating that you intend to work on it so other people don’t accidentally duplicate your effort. + +If somebody claims an issue but doesn’t follow up for more than two weeks, it’s fine to take over it but you should still leave a comment. + +**IMPORTANT**: By submitting a patch, you agree to allow the project +owners to license your work under the terms of the [BSD3 License](https://github.com/amaggiulli/QLNet/blob/develop/LICENSE). diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..e2136bdb5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,31 @@ + + +## Expected Behavior + + + +## Current Behavior + + + +## Possible Solution + + + +## Steps to Reproduce (for bugs) + + +1. +2. +3. +4. + +## Context + + + +## Your Environment + +* Version used ( e.g. QLNet 1.9.2 ) +* Environment name and version (e.g. .NET Framework 4.5 on Windows 7): +* Link to your fork diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..bd7f29f44 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,23 @@ +## QLNet + +Thank you for contributing! Take a moment to review our [**contributing guidelines**](https://github.com/amaggiulli/qlnet/blob/develop/.github/CONTRIBUTING.md) +to make the process easy and effective for everyone involved. + +**You must open an issue** before embarking on any significant pull request, especially those that +add a new code or change existing tests, otherwise you risk spending a lot of time working +on something that might not end up being merged into the project. + +Before opening a pull request, please ensure: + +- [ ] You have followed our [**contributing guidelines**](https://github.com/amaggiulli/qlnet/blob/develop/.github/CONTRIBUTING.md) +- [ ] Pull request has tests +- [ ] Code is well-commented and follows project conventions +- [ ] You only changed necessary files (commits with formatting only changes will be reject, see below) +- [ ] Documentation is updated (if necessary) +- [ ] Description explains the issue/use-case resolved and auto-closes related issues +- [ ] **IMPORTANT** You have executed the format_code.bat batch in the root of your fork to format the code with qlnet standard. + +Be kind to code reviewers, please try to keep pull requests as small and focused as possible :) + +**IMPORTANT**: By submitting a patch via a Pull Request, you agree to allow the project +owners to license your work under the terms of the [BSD3 License](https://github.com/amaggiulli/qlnet/blob/develop/LICENSE). diff --git a/ChangeLog.txt b/ChangeLog.txt index 6d6e661c7..dc866ef89 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,1702 +1,2586 @@ -commit 4bd55d80a5f7320175a1f3da9224237b3423fe12 -Merge: 440c673 763bdd7 +commit 6cf92a77edb292dd6e0ac17916d40c7dd8718304 Author: Andrea Maggiulli -Date: Mon Oct 30 12:31:33 2017 +0100 +Date: Sat Jun 9 18:01:13 2018 +0200 - Merge pull request #180 from tournierjc/SviInterpolationCtorMissingParam - - Svi interpolation ctor missing param - -commit 440c6737dc545b088568f21a3166d15bed500222 -Merge: 4cb47c8 2247182 -Author: Andrea Maggiulli -Date: Mon Oct 30 12:31:23 2017 +0100 - - Merge pull request #179 from tournierjc/NewGettersBlackVarianceSurface - - New getters black variance surface - -commit 763bdd7486d34151e098dc26f4106f13b0f47c6f -Author: tournierjc -Date: Mon Oct 30 11:53:57 2017 +0100 + Added raw calculation for WeightedAverageLife given a list of dates and a list of amounts. - addParams was missing + src/QLNet/Pricingengines/Bond/BondFunctions.cs | 31 ++++++++++++++++++++++++++ + tests/QLNet.Tests/T_Bonds.cs | 19 ++++++++++++++++ + 2 files changed, 50 insertions(+) - src/QLNet/Math/Interpolations/SviInterpolation.cs | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -commit 2247182e30c33ebb831852b60c90b082c9b59641 -Author: tournierjc -Date: Mon Oct 30 11:50:03 2017 +0100 - - Add public getters for BlackVarianceSurface - - .../Volatility/equityfx/BlackVarianceSurface.cs | 19 +++++++++++++++---- - 1 file changed, 15 insertions(+), 4 deletions(-) - -commit d78aae5b43fcfb5359b73014a22c4a46d00d8f66 -Merge: 43dd1ff 4cb47c8 -Author: tournierjc -Date: Mon Oct 30 11:49:21 2017 +0100 +commit c5bd5e10a6e84a18b6fc4686aa2e691b8e747d77 +Merge: c7e5102 b4fe2d2 +Author: Andrea Maggiulli +Date: Mon Apr 9 16:52:48 2018 +0200 - Merge pull request #4 from amaggiulli/develop + Merge pull request #203 from igitur/indexmanager-trygethistory - last merge + Add helper method IndexManager.tryGetHistory -commit 4cb47c82a4b7822a2bbe8858367f09ca37b405e7 -Merge: 35fdae7 33c7ab3 -Author: Andrea Maggiulli -Date: Mon Oct 30 09:45:26 2017 +0100 +commit b4fe2d2449d853ede448844bbe765053b329c537 +Author: Francois Botha +Date: Mon Apr 9 16:22:53 2018 +0200 - Merge pull request #178 from tournierjc/FdmBermudanSwaptionHW - - Fdm bermudan swaption hw + Add helper method IndexManager.tryGetHistory -commit 35fdae7745ca66ece0e7dcad0285dcc7586f08e3 -Merge: 9f99b0e 077c4a4 -Author: Andrea Maggiulli -Date: Mon Oct 30 09:45:15 2017 +0100 + src/QLNet/Indexes/Indexmanager.cs | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) - Merge pull request #177 from tournierjc/ProjetFileFix - - Projet file fix - -commit 9f99b0e3f0286497b169fae0c78bef4cc40f973b -Merge: fae51c7 529e46d -Author: Andrea Maggiulli -Date: Mon Oct 30 09:45:02 2017 +0100 +commit c7e5102e339f2b8a6c258c10ac4565561093c3dc +Merge: 3a6a865 2b6d998 +Author: Andrea Maggiulli +Date: Thu Apr 5 16:39:57 2018 +0200 - Merge pull request #176 from tournierjc/DoubleBarrierBinaryOptionPort + Merge pull request #202 from igitur/fix-LfmCovarianceProxy-filename - Double barrier binary option port + Fix filename after rename -commit 529e46d7e8ec90c40d705e49a8a36119ffa5d859 -Author: tournierjc -Date: Fri Oct 27 09:19:15 2017 +0200 - - Fix some SonarQube issues - - .../barrier/AnalyticDoubleBarrierBinaryEngine.cs | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) +commit 2b6d998f91eca90910bc319102fd56285b052fa0 +Author: Francois Botha +Date: Thu Apr 5 16:18:01 2018 +0200 -commit 33c7ab3ed0019e0c641718cddeb2d0e96643f8dd -Author: tournierjc -Date: Fri Oct 27 09:13:44 2017 +0200 + Fix filename after rename in https://github.com/amaggiulli/QLNet/commit/c0ea99c26b198c04bf51de5dad55394b9debe3e5 - Add files via upload - - src/QLNet/Pricingengines/vanilla/FdHullWhiteSwaptionEngine.cs | 4 ++-- + src/QLNet.Old/QLNet.Old.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -commit 406f84ea86f2a0d6703b4743636952607b78c5a4 -Author: tournierjc -Date: Fri Oct 27 09:13:19 2017 +0200 - - Fix SonarQube - - .../Methods/Finitedifferences/Meshers/FdmSimpleProcess1dMesher.cs | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -commit 66c5b10998ba21a5d929bf607e915ae30ddc0ccb -Author: tournierjc -Date: Fri Oct 27 09:10:30 2017 +0200 - - Fix SonarQube - - .../Methods/Finitedifferences/Operators/FdmHullWhiteOp.cs | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -commit 243e81d3aefff54c9495af5d641c8d1d5303df0e -Author: tournierjc -Date: Fri Oct 27 09:09:53 2017 +0200 - - Fix AppVeyor - - .../Finitedifferences/StepConditions/FdmBermudanStepCondition.cs | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -commit a9ff37f70198f00b0b1a561a4014959979bb8670 -Author: tournierjc -Date: Fri Oct 27 09:09:19 2017 +0200 - - Fix SonarQube - - .../Finitedifferences/Utilities/FdmAffineModelSwapInnerValue.cs | 4 ++-- - .../Finitedifferences/Utilities/FdmAffineModelTermStructure.cs | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - -commit 43dd1fff6d26167633b975ab7c08f7bb0c8433c8 -Author: tournierjc -Date: Fri Oct 27 09:07:07 2017 +0200 - - Fix SonarQube - - .../Utilities/FdmAffineModelSwapInnerValue.cs | 132 +++++++++++++++++++++ - .../Utilities/FdmAffineModelTermStructure.cs | 59 +++++++++ - 2 files changed, 191 insertions(+) - -commit 71f929423b24dd49f21d97f6a783888f2427d3d9 -Author: tournierjc -Date: Thu Oct 26 18:54:48 2017 +0200 - - Update project file - - src/QLNet.Old/QLNet.Old.csproj | 20 +++++++++++++++++++- - 1 file changed, 19 insertions(+), 1 deletion(-) - -commit 077c4a4d9f84955e375fc10622c4960bd520019a -Author: tournierjc -Date: Thu Oct 26 18:38:05 2017 +0200 - - I missed a line in #175 - - src/QLNet.Old/QLNet.Old.csproj | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -commit 8a7dde3d2264964a904a0065c2221de7c151e77e -Author: tournierjc -Date: Thu Oct 26 18:28:31 2017 +0200 - - Update test case - - tests/QLNet.Tests/T_Bermudanswaption.cs | 56 ++++++++++++++++++++++----------- - 1 file changed, 38 insertions(+), 18 deletions(-) - -commit 4a3ffec87f2c8b156da8bb73d51952c373f67768 -Author: tournierjc -Date: Thu Oct 26 18:27:44 2017 +0200 - - Add HW swaption engine - - .../vanilla/FdHullWhiteSwaptionEngine.cs | 117 +++++++++++++++++++++ - 1 file changed, 117 insertions(+) - -commit c92776e9186201d3d4858b6bcfd074c04b08c7d7 -Author: tournierjc -Date: Thu Oct 26 18:26:48 2017 +0200 - - 1 line was missing - - src/QLNet/Methods/Finitedifferences/finitedifferencemodel.cs | 1 + - 1 file changed, 1 insertion(+) - -commit 48780ce12da77cf4595b2eb777f441b5961b4558 -Author: tournierjc -Date: Thu Oct 26 18:26:08 2017 +0200 - - Affine model utilities add - - .../Utilities/FdmAffineModelSwapInnerValue.cs | 132 +++++++++++++++++++++ - .../Utilities/FdmAffineModelTermStructure.cs | 59 +++++++++ - 2 files changed, 191 insertions(+) - -commit ac9f04a20005b7024dfc9354adb5d2e81e7964a9 -Author: tournierjc -Date: Thu Oct 26 18:25:14 2017 +0200 - - Bermudan condition bug fix - - .../Finitedifferences/StepConditions/FdmBermudanStepCondition.cs | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -commit 2ffa5dfd90f966610b8a7b1eb821cdf595e46d55 -Author: tournierjc -Date: Thu Oct 26 18:24:36 2017 +0200 - - FDM Hull White Solver add - - .../Solvers/FdmHullWhiteSolver.cs | 65 ++++++++++++++++++++++ - 1 file changed, 65 insertions(+) - -commit 103091cdb1c34ffc0202793d67ab404f5bb208de -Author: tournierjc -Date: Thu Oct 26 18:23:17 2017 +0200 - - TripleBandLinear op bug fix - - .../Finitedifferences/Operators/TripleBandLinearOp.cs | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -commit a0161badfeb67301683f48dfed1e8d84b45bc079 -Author: tournierjc -Date: Thu Oct 26 18:22:43 2017 +0200 - - Hull White operator add - - .../Finitedifferences/Operators/FdmHullWhiteOp.cs | 105 +++++++++++++++++++++ - 1 file changed, 105 insertions(+) - -commit ee20b5b90f25ee27dbaecea5163e0b37bd8a2798 -Author: tournierjc -Date: Thu Oct 26 18:21:55 2017 +0200 - - 1D Simple mesher add - - .../Meshers/FdmSimpleProcess1dMesher.cs | 74 ++++++++++++++++++++++ - 1 file changed, 74 insertions(+) - -commit 59f451c70f50e151dd653adb5fa80ad2a7ae6d26 -Author: tournierjc -Date: Wed Oct 25 17:39:06 2017 +0200 - - Add pricing engines - - .../barrier/AnalyticDoubleBarrierBinaryEngine.cs | 322 +++++++++++++++++++++ - .../barrier/BinomialDoubleBarrierEngine.cs | 154 ++++++++++ - .../barrier/DiscretizedDoubleBarrierOption.cs | 270 +++++++++++++++++ - 3 files changed, 746 insertions(+) - -commit a7eb97586af20cd17d96d4d12e4c272364a972f8 -Author: tournierjc -Date: Wed Oct 25 17:37:14 2017 +0200 - - Add test - - tests/QLNet.Tests/T_DoubleBinaryOption.cs | 282 ++++++++++++++++++++++++++++++ - 1 file changed, 282 insertions(+) - -commit 8f01ba3dc1759a3a7df6c4ec7c802d9267528aea -Author: tournierjc -Date: Wed Oct 25 17:36:39 2017 +0200 - - QLNet Tests old project file - - tests/QLNet.Tests.Old/QLNet.Tests.Old.csproj | 1 + - 1 file changed, 1 insertion(+) - -commit ce2a6c6d839c9cb5fe21bad84619042ad0da293a -Author: tournierjc -Date: Wed Oct 25 17:36:04 2017 +0200 - - QLNet Old project file - - src/QLNet.Old/QLNet.Old.csproj | 9 +++++++++ - 1 file changed, 9 insertions(+) - -commit ba2136e79db1a9185ab4318afb1c2385c27a86de -Merge: 5ae4482 fae51c7 -Author: tournierjc -Date: Wed Oct 25 16:37:29 2017 +0200 - - Merge pull request #3 from amaggiulli/develop - - Merge from QLnet - -commit fae51c7bf38743ee11b05454ab69ced327cf4244 -Merge: 4071869 0f5594d +commit 3a6a865bb791df07012c4fd7f7663d18c346c3bc Author: Andrea Maggiulli -Date: Wed Oct 25 15:03:34 2017 +0200 +Date: Wed Feb 28 15:37:21 2018 +0100 - Merge pull request #175 from tournierjc/Update_QLNet_Old - - Update QLNet Old Project files - -commit 0f5594dd7ec7d104101610e7be8d2398e51b7881 -Author: tournierjc -Date: Wed Oct 25 14:21:11 2017 +0200 + Added Range Accrual tests and fixed 2 bugs on RangeAccrual and InterpolatedSmileSection - Update QLNet.Test.Old projet file - - Were missing last PR : FdmLinearOp and CreditDefaultSwap - - tests/QLNet.Tests.Old/QLNet.Tests.Old.csproj | 1 + - 1 file changed, 1 insertion(+) - -commit d952b86afadd9cef1845f8dcf34126890081f672 -Author: tournierjc -Date: Wed Oct 25 14:20:20 2017 +0200 + src/QLNet/Cashflows/RangeAccrual.cs | 2 +- + .../Volatility/InterpolatedSmileSection.cs | 10 + + tests/QLNet.Tests/T_RangeAccrual.cs | 1584 ++++++++++++++++++++ + 3 files changed, 1595 insertions(+), 1 deletion(-) - Update QLNet.Old projet file - - Were missing last PR : FDM + Local Volatility + CDS ISDA Engine - - src/QLNet.Old/QLNet.Old.csproj | 180 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 180 insertions(+) - -commit 407186955c71e019c9899ed6af387279c16c8e9f +commit 1d2312bcd32b82d39f8fa6275280331234fb28c5 Author: Andrea Maggiulli -Date: Fri Oct 20 12:24:39 2017 +0200 +Date: Tue Feb 6 13:59:06 2018 +0100 - Traits cleanup & update. + Updated BlackVanillaOptionPricer constructor, check volatility type and shift. - .../Termstructures/Credit/ProbabilityTraits.cs | 178 ++++++++++++++++++--- - .../Termstructures/Inflation/InflationTraits.cs | 61 +------ - .../Inflation/PiecewiseYoYInflationCurve.cs | 8 - - .../Inflation/PiecewiseZeroInflationCurve.cs | 8 - - src/QLNet/Termstructures/Yield/Bootstraptraits.cs | 86 +--------- - .../Termstructures/Yield/PiecewiseYieldCurve.cs | 5 - - 6 files changed, 163 insertions(+), 183 deletions(-) + src/QLNet/Cashflows/ConundrumPricer.cs | 4 ++++ + 1 file changed, 4 insertions(+) -commit 7bd298f045176abea39eb50eb04c08ce0bbe29b6 +commit ef4dbd40e6eb76a73984b51216c1824d1a37b8de Author: Andrea Maggiulli -Date: Wed Oct 18 17:30:08 2017 +0200 +Date: Tue Feb 6 13:43:12 2018 +0100 - Added IsdaCdsEngine, InterpolatedSurvivalProbabilityCurve and SurvivalProbabilityStructure with test . + Updated day count convention and spot lag by CAD fixings. - src/QLNet/Pricingengines/credit/IsdaCdsEngine.cs | 432 +++++++++++++++++++++ - .../Credit/InterpolatedSurvivalProbabilityCurve.cs | 166 ++++++++ - .../Credit/SurvivalProbabilityStructure.cs | 74 ++++ - tests/QLNet.Tests/T_CreditDefaultSwap.cs | 144 ++++++- - 4 files changed, 815 insertions(+), 1 deletion(-) + src/QLNet/Indexes/Ibor/Cadlibor.cs | 32 +++++++++++++++++++++----------- + src/QLNet/Indexes/Ibor/Cdor.cs | 32 +++++++++++++++++--------------- + 2 files changed, 38 insertions(+), 26 deletions(-) -commit 41ed73f7b8c1ef7547c75bb0bd758360c5de583c +commit e59cdfed0bc1fcadf652d962e7a45ef968bd9b12 Author: Andrea Maggiulli -Date: Wed Oct 18 17:26:10 2017 +0200 +Date: Tue Feb 6 12:49:47 2018 +0100 - Updated Actual360 daycounter to include/exclude last day + Updated Vanna Volga test values according with previous fix to double barrier KI. - src/QLNet/Time/DayCounters/Actual360.cs | 67 ++++++++++++++++++++++----------- - 1 file changed, 46 insertions(+), 21 deletions(-) + tests/QLNet.Tests/T_DoubleBarrierOption.cs | 180 +++++++++++++---------------- + 1 file changed, 82 insertions(+), 98 deletions(-) -commit 1bdedbdd76257963549e4068ee72dbf831809de2 +commit eac972a2f10a667c96be3df15e92e81df05f0c3a Author: Andrea Maggiulli -Date: Wed Oct 18 17:25:12 2017 +0200 +Date: Tue Feb 6 12:24:01 2018 +0100 - Updated Schedule for CDS2015 with test. + Fixed bug in Vanna-Volga method for double barrier knock in options. - src/QLNet/Time/Schedule.cs | 468 ++++++++++++++++++++++------------------ - tests/QLNet.Tests/T_Schedule.cs | 44 +++- - 2 files changed, 301 insertions(+), 211 deletions(-) + .../barrier/VannaVolgaBarrierEngine.cs | 20 +++++++++++++------- + .../barrier/VannaVolgaDoubleBarrierEngine.cs | 4 ++-- + 2 files changed, 15 insertions(+), 9 deletions(-) -commit 30afffab64083a8360c8eed51db58e18d1b0f351 +commit 1e7f51dcb3590bdfcdbe68fd108b6035df4ea1f6 +Merge: 19269b8 d807825 Author: Andrea Maggiulli -Date: Wed Oct 18 17:22:50 2017 +0200 +Date: Tue Feb 6 11:55:00 2018 +0100 - Added LastPeriodDayCounter to FixedRateCoupon - - src/QLNet/Cashflows/FixedRateCoupon.cs | 28 ++++++++++++++++++++-------- - 1 file changed, 20 insertions(+), 8 deletions(-) + Merge branch 'develop' of https://github.com/amaggiulli/qlnet into develop -commit be3a170839ff5d98b5bbaf2a214305949ac1be73 +commit 19269b86bf31caad7bce1eb3f6de5ac665070d6a Author: Andrea Maggiulli -Date: Wed Oct 18 17:21:53 2017 +0200 +Date: Tue Feb 6 11:54:20 2018 +0100 - Updated CreditDefaultSwap + helper + Added Kirk Option Engine with test. - src/QLNet/Instruments/CreditDefaultSwap.cs | 523 ++++++++++++++++++----------- - src/QLNet/Instruments/MakeCDS.cs | 122 +++++++ - src/QLNet/Types.cs | 5 +- - 3 files changed, 452 insertions(+), 198 deletions(-) + src/QLNet/Instruments/SpreadOption.cs | 35 ++++ + .../Option/KirkSpreadOptionEngine.cs | 106 ++++++++++++ + tests/QLNet.Tests/T_SpreadOption.cs | 189 +++++++++++++++++++++ + 3 files changed, 330 insertions(+) -commit bb61b6794e3c01a9ed580715ba38afc70de0cd27 -Author: Andrea Maggiulli -Date: Wed Oct 18 14:05:35 2017 +0200 +commit d807825f1c925b4bae6bbe6b9977fe47e9d59672 +Author: Andrea Maggiulli +Date: Tue Feb 6 10:17:00 2018 +0100 - Fixed floating comparison + Updated CONTRIBUTING.md [skip ci] - tests/QLNet.Tests/Utilities.cs | 2 +- + .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -commit a26aeddb912b4738b1e28c26a1c97edbdd181b35 +commit 00b1f476e4743b5a69d33edca5ea97c79549efd5 Author: Andrea Maggiulli -Date: Wed Oct 18 14:03:34 2017 +0200 +Date: Tue Feb 6 00:13:24 2018 +0100 + + Updated Copyright License link to github. + + src/BermudanSwaption/BermudanSwaption.cs | 2 +- + src/Bonds/Bonds.cs | 2 +- + src/CVAIRS/CVAIRS.cs | 2 +- + src/CallableBonds/CallableBonds.cs | 4 ++-- + src/EquityOption/EquityOption.cs | 2 +- + src/FRA/FRA.cs | 2 +- + src/FittedBondCurve/FittedBondCurve.cs | 2 +- + src/QLNet/CashflowBase.cs | 2 +- + src/QLNet/Cashflows/AverageBMACoupon.cs | 2 +- + src/QLNet/Cashflows/CPICoupon.cs | 2 +- + src/QLNet/Cashflows/CPICouponPricer.cs | 2 +- + src/QLNet/Cashflows/CappedFlooredCoupon.cs | 2 +- + .../Cashflows/CappedFlooredYoYInflationCoupon.cs | 2 +- + src/QLNet/Cashflows/CashFlows.cs | 2 +- + src/QLNet/Cashflows/Cashflowvectors.cs | 2 +- + src/QLNet/Cashflows/CmsCoupon.cs | 2 +- + src/QLNet/Cashflows/CmsSpreadCoupon.cs | 2 +- + src/QLNet/Cashflows/ConundrumPricer.cs | 2 +- + src/QLNet/Cashflows/Coupon.cs | 2 +- + src/QLNet/Cashflows/CouponPricer.cs | 2 +- + src/QLNet/Cashflows/DigitalCmsCoupon.cs | 2 +- + src/QLNet/Cashflows/DigitalCoupon.cs | 2 +- + src/QLNet/Cashflows/DigitalIborCoupon.cs | 2 +- + src/QLNet/Cashflows/Dividend.cs | 2 +- + src/QLNet/Cashflows/FixedRateCoupon.cs | 2 +- + src/QLNet/Cashflows/FloatingRateCoupon.cs | 2 +- + src/QLNet/Cashflows/Iborcoupon.cs | 2 +- + src/QLNet/Cashflows/IndexedCashFlow.cs | 2 +- + src/QLNet/Cashflows/InflationCoupon.cs | 2 +- + src/QLNet/Cashflows/InflationCouponPricer.cs | 2 +- + src/QLNet/Cashflows/LinearTsrPricer.cs | 2 +- + src/QLNet/Cashflows/OvernightIndexedCoupon.cs | 2 +- + src/QLNet/Cashflows/Principal.cs | 2 +- + src/QLNet/Cashflows/PrincipalLegBase.cs | 2 +- + src/QLNet/Cashflows/RangeAccrual.cs | 2 +- + src/QLNet/Cashflows/RateLegBase.cs | 2 +- + src/QLNet/Cashflows/Replication.cs | 2 +- + src/QLNet/Cashflows/SimpleCashFlow.cs | 2 +- + src/QLNet/Cashflows/YoYInflationCoupon.cs | 2 +- + src/QLNet/Currencies/Africa.cs | 2 +- + src/QLNet/Currencies/America.cs | 2 +- + src/QLNet/Currencies/Asia.cs | 2 +- + src/QLNet/Currencies/Currency.cs | 2 +- + src/QLNet/Currencies/Europe.cs | 2 +- + src/QLNet/Currencies/ExchangeRate.cs | 2 +- + src/QLNet/Currencies/ExchangeRateManager.cs | 2 +- + src/QLNet/Currencies/Oceania.cs | 2 +- + src/QLNet/DiscretizedAsset.cs | 2 +- + src/QLNet/Event.cs | 2 +- + src/QLNet/Exercise.cs | 2 +- + src/QLNet/Extensions/DoubleExtension.cs | 2 +- + src/QLNet/Grid.cs | 2 +- + src/QLNet/Handle.cs | 2 +- + src/QLNet/Index.cs | 2 +- + src/QLNet/Indexes/BMAIndex.cs | 2 +- + src/QLNet/Indexes/IBORIndex.cs | 2 +- + src/QLNet/Indexes/Ibor/Aonia.cs | 2 +- + src/QLNet/Indexes/Ibor/Audlibor.cs | 2 +- + src/QLNet/Indexes/Ibor/Bbsw.cs | 2 +- + src/QLNet/Indexes/Ibor/Bkbm.cs | 2 +- + src/QLNet/Indexes/Ibor/Cadlibor.cs | 2 +- + src/QLNet/Indexes/Ibor/Cdor.cs | 2 +- + src/QLNet/Indexes/Ibor/Chflibor.cs | 2 +- + src/QLNet/Indexes/Ibor/Dkklibor.cs | 2 +- + src/QLNet/Indexes/Ibor/Eonia.cs | 2 +- + src/QLNet/Indexes/Ibor/Euribor.cs | 2 +- + src/QLNet/Indexes/Ibor/Eurlibor.cs | 2 +- + src/QLNet/Indexes/Ibor/FedFunds.cs | 2 +- + src/QLNet/Indexes/Ibor/Gbplibor.cs | 2 +- + src/QLNet/Indexes/Ibor/Jibar.cs | 2 +- + src/QLNet/Indexes/Ibor/Jpylibor.cs | 2 +- + src/QLNet/Indexes/Ibor/Libor.cs | 2 +- + src/QLNet/Indexes/Ibor/Nzdlibor.cs | 2 +- + src/QLNet/Indexes/Ibor/Nzocr.cs | 2 +- + src/QLNet/Indexes/Ibor/Seklibor.cs | 2 +- + src/QLNet/Indexes/Ibor/Shibor.cs | 2 +- + src/QLNet/Indexes/Ibor/Sonia.cs | 2 +- + src/QLNet/Indexes/Ibor/Tibor.cs | 2 +- + src/QLNet/Indexes/Ibor/Trylibor.cs | 2 +- + src/QLNet/Indexes/Ibor/Usdlibor.cs | 2 +- + src/QLNet/Indexes/Ibor/Zibor.cs | 2 +- + src/QLNet/Indexes/Indexmanager.cs | 2 +- + src/QLNet/Indexes/Inflation/AUCPI.cs | 2 +- + src/QLNet/Indexes/Inflation/EUHICP.cs | 2 +- + src/QLNet/Indexes/Inflation/FRHICP.cs | 2 +- + src/QLNet/Indexes/Inflation/UKRPI.cs | 2 +- + src/QLNet/Indexes/Inflation/USCPI.cs | 2 +- + src/QLNet/Indexes/Inflation/ZACPI.cs | 2 +- + src/QLNet/Indexes/InflationIndex.cs | 2 +- + src/QLNet/Indexes/InterestRateIndex.cs | 2 +- + src/QLNet/Indexes/Region.cs | 2 +- + src/QLNet/Indexes/Swapindex.cs | 2 +- + src/QLNet/Indexes/swap/ChfLiborSwap.cs | 2 +- + src/QLNet/Indexes/swap/EurLiborSwap.cs | 2 +- + src/QLNet/Indexes/swap/EuriborSwap.cs | 2 +- + src/QLNet/Indexes/swap/GbpLiborSwap.cs | 2 +- + src/QLNet/Indexes/swap/JpyLiborSwap.cs | 2 +- + src/QLNet/Indexes/swap/SwapSpreadIndex.cs | 2 +- + src/QLNet/Indexes/swap/UsdLiborSwap.cs | 2 +- + src/QLNet/Instruments/AsianOption.cs | 2 +- + src/QLNet/Instruments/AssetSwap.cs | 2 +- + src/QLNet/Instruments/AverageType.cs | 2 +- + src/QLNet/Instruments/BMASwap.cs | 2 +- + src/QLNet/Instruments/BarrierOption.cs | 2 +- + src/QLNet/Instruments/BarrierType.cs | 2 +- + src/QLNet/Instruments/BasisSwap.cs | 2 +- + src/QLNet/Instruments/BasketOption.cs | 2 +- + src/QLNet/Instruments/Bond.cs | 2 +- + src/QLNet/Instruments/Bonds/AmortizingBond.cs | 2 +- + .../Instruments/Bonds/AmortizingCmsRateBond.cs | 2 +- + .../Instruments/Bonds/AmortizingFixedRateBond.cs | 2 +- + .../Bonds/AmortizingFloatingRateBond.cs | 2 +- + src/QLNet/Instruments/Bonds/BTP.cs | 2 +- + src/QLNet/Instruments/Bonds/BondFactory.cs | 2 +- + src/QLNet/Instruments/Bonds/CPIBond.cs | 2 +- + src/QLNet/Instruments/Bonds/CallableBond.cs | 2 +- + src/QLNet/Instruments/Bonds/CmsRateBond.cs | 2 +- + src/QLNet/Instruments/Bonds/ConstantCPR.cs | 2 +- + src/QLNet/Instruments/Bonds/ConvertibleBond.cs | 2 +- + .../Bonds/DiscretizedCallableFixedRateBond.cs | 2 +- + src/QLNet/Instruments/Bonds/Fixedratebond.cs | 2 +- + src/QLNet/Instruments/Bonds/FloatingRateBond.cs | 2 +- + src/QLNet/Instruments/Bonds/IPrepayModel.cs | 2 +- + src/QLNet/Instruments/Bonds/MBSFixedRateBond.cs | 2 +- + src/QLNet/Instruments/Bonds/PSACurve.cs | 2 +- + src/QLNet/Instruments/Bonds/Zerocouponbond.cs | 2 +- + src/QLNet/Instruments/CPICapFloor.cs | 2 +- + src/QLNet/Instruments/CPISwap.cs | 2 +- + src/QLNet/Instruments/Callability.cs | 2 +- + src/QLNet/Instruments/CapFloor.cs | 2 +- + src/QLNet/Instruments/Claim.cs | 2 +- + src/QLNet/Instruments/CliquetOption.cs | 2 +- + src/QLNet/Instruments/CompositeInstrument.cs | 2 +- + src/QLNet/Instruments/CreditDefaultSwap.cs | 2 +- + src/QLNet/Instruments/DividendBarrierOption.cs | 2 +- + src/QLNet/Instruments/DividendSchedule.cs | 2 +- + src/QLNet/Instruments/DividendVanillaOption.cs | 2 +- + src/QLNet/Instruments/DoubleBarrierOption.cs | 2 +- + src/QLNet/Instruments/EuropeanOption.cs | 2 +- + src/QLNet/Instruments/FixedRateBondForward.cs | 2 +- + src/QLNet/Instruments/FloatFloatSwap.cs | 2 +- + src/QLNet/Instruments/Forward.cs | 2 +- + src/QLNet/Instruments/ForwardRateAgreement.cs | 2 +- + src/QLNet/Instruments/ForwardVanillaOption.cs | 2 +- + src/QLNet/Instruments/Futures.cs | 2 +- + src/QLNet/Instruments/ImpliedVolatility.cs | 2 +- + src/QLNet/Instruments/InflationCapFloor.cs | 2 +- + src/QLNet/Instruments/Instrument.cs | 2 +- + src/QLNet/Instruments/Loan.cs | 2 +- + src/QLNet/Instruments/LookbackOption.cs | 2 +- + src/QLNet/Instruments/MakeBasisSwap.cs | 2 +- + src/QLNet/Instruments/MakeCDS.cs | 2 +- + src/QLNet/Instruments/MakeCapFloor.cs | 2 +- + src/QLNet/Instruments/MakeCms.cs | 2 +- + src/QLNet/Instruments/MakeLoans.cs | 2 +- + src/QLNet/Instruments/MakeOIS.cs | 2 +- + src/QLNet/Instruments/Makeswaption.cs | 2 +- + src/QLNet/Instruments/Makevanillaswap.cs | 2 +- + src/QLNet/Instruments/MultiAssetOption.cs | 2 +- + src/QLNet/Instruments/OneAssetOption.cs | 2 +- + src/QLNet/Instruments/OvernightIndexedSwap.cs | 2 +- + src/QLNet/Instruments/Payoffs.cs | 2 +- + src/QLNet/Instruments/Stock.cs | 2 +- + src/QLNet/Instruments/Swap.cs | 2 +- + src/QLNet/Instruments/Swaption.cs | 2 +- + src/QLNet/Instruments/VanillaOption.cs | 2 +- + src/QLNet/Instruments/VanillaSwap.cs | 2 +- + src/QLNet/Instruments/YearOnYearInflationSwap.cs | 2 +- + src/QLNet/Instruments/ZeroCouponInflationSwap.cs | 2 +- + src/QLNet/InterestRate.cs | 2 +- + src/QLNet/Math/AbcdMathFunction.cs | 2 +- + src/QLNet/Math/BSpline.cs | 2 +- + src/QLNet/Math/BernsteinPolynomial.cs | 2 +- + src/QLNet/Math/Beta.cs | 2 +- + src/QLNet/Math/Comparison.cs | 2 +- + .../Math/Distributions/BinomialDistribution.cs | 2 +- + .../Distributions/BivariateNormalDistribution.cs | 2 +- + .../Math/Distributions/ChiSquareDistribution.cs | 2 +- + src/QLNet/Math/Distributions/GammaDistribution.cs | 2 +- + src/QLNet/Math/Distributions/NormalDistribution.cs | 2 +- + .../Math/Distributions/PoissonDistribution.cs | 2 +- + src/QLNet/Math/Factorial.cs | 2 +- + src/QLNet/Math/Interpolation.cs | 2 +- + src/QLNet/Math/Interpolations/Abcdinterpolation.cs | 2 +- + .../Interpolations/BackwardFlatInterpolation.cs | 2 +- + .../BackwardflatLinearInterpolation.cs | 2 +- + .../Interpolations/BicubicSplineInterpolation.cs | 2 +- + .../Math/Interpolations/BilinearInterpolation.cs | 2 +- + .../Interpolations/ConvexMonotoneInterpolation.cs | 2 +- + .../Math/Interpolations/CubicInterpolation.cs | 2 +- + src/QLNet/Math/Interpolations/Extrapolator.cs | 2 +- + .../Math/Interpolations/FlatExtrapolator2D.cs | 2 +- + .../Interpolations/ForwardFlatInterpolation.cs | 2 +- + src/QLNet/Math/Interpolations/Interpolation2D.cs | 2 +- + .../Math/Interpolations/KernelInterpolation.cs | 2 +- + .../Math/Interpolations/KernelInterpolation2D.cs | 2 +- + .../Math/Interpolations/Linearinterpolation.cs | 2 +- + src/QLNet/Math/Interpolations/Loginterpolation.cs | 2 +- + .../Math/Interpolations/MixedInterpolation.cs | 2 +- + src/QLNet/Math/Interpolations/MultiCubicSpline.cs | 2 +- + src/QLNet/Math/Interpolations/SABRInterpolation.cs | 2 +- + src/QLNet/Math/Interpolations/SviInterpolation.cs | 2 +- + .../Math/Interpolations/VannaVolgaInterpolation.cs | 2 +- + src/QLNet/Math/Interpolations/XABRInterpolation.cs | 2 +- + src/QLNet/Math/KernelFunctions.cs | 2 +- + src/QLNet/Math/LinearLeastSquaresRegression.cs | 2 +- + src/QLNet/Math/Matrix.cs | 2 +- + src/QLNet/Math/ModifiedBessel.cs | 2 +- + src/QLNet/Math/NumericalDifferentiation.cs | 2 +- + src/QLNet/Math/ODE/AdaptiveRungeKutta.cs | 2 +- + src/QLNet/Math/Optimization/ArmijoLineSearch.cs | 2 +- + src/QLNet/Math/Optimization/BFGS.cs | 2 +- + src/QLNet/Math/Optimization/ConjugateGradient.cs | 2 +- + src/QLNet/Math/Optimization/Constraint.cs | 2 +- + src/QLNet/Math/Optimization/CostFunction.cs | 2 +- + .../Math/Optimization/DifferentialEvolution.cs | 2 +- + src/QLNet/Math/Optimization/EndCriteria.cs | 2 +- + src/QLNet/Math/Optimization/GoldsteinLineSearch.cs | 2 +- + src/QLNet/Math/Optimization/LeastSquareProblem.cs | 2 +- + src/QLNet/Math/Optimization/LevenbergMarquardt.cs | 2 +- + src/QLNet/Math/Optimization/LineSearch.cs | 2 +- + .../Math/Optimization/LineSearchBasedMethod.cs | 2 +- + src/QLNet/Math/Optimization/LmDif.cs | 2 +- + src/QLNet/Math/Optimization/Method.cs | 2 +- + src/QLNet/Math/Optimization/Problem.cs | 2 +- + src/QLNet/Math/Optimization/ProjectedConstraint.cs | 2 +- + .../Math/Optimization/ProjectedCostFunction.cs | 2 +- + src/QLNet/Math/Optimization/Projection.cs | 2 +- + src/QLNet/Math/Optimization/Simplex.cs | 2 +- + src/QLNet/Math/Optimization/SimulatedAnnealing.cs | 2 +- + src/QLNet/Math/Optimization/SteepestDescent.cs | 2 +- + src/QLNet/Math/PascalTriangle.cs | 2 +- + src/QLNet/Math/PolynomialFunction.cs | 2 +- + src/QLNet/Math/PrimeNumbers.cs | 2 +- + src/QLNet/Math/RichardsonExtrapolation.cs | 2 +- + src/QLNet/Math/Rounding.cs | 2 +- + src/QLNet/Math/SampledCurve.cs | 2 +- + src/QLNet/Math/Solver1d.cs | 2 +- + src/QLNet/Math/Solvers1d/Bisection.cs | 2 +- + src/QLNet/Math/Solvers1d/Brent.cs | 2 +- + src/QLNet/Math/Solvers1d/FalsePosition.cs | 2 +- + .../Math/Solvers1d/FiniteDifferenceNewtonSafe.cs | 2 +- + src/QLNet/Math/Solvers1d/Newton.cs | 2 +- + src/QLNet/Math/Solvers1d/Newtonsafe.cs | 2 +- + src/QLNet/Math/Solvers1d/Ridder.cs | 2 +- + src/QLNet/Math/Solvers1d/Secant.cs | 2 +- + src/QLNet/Math/TransformedGrid.cs | 2 +- + src/QLNet/Math/Vector.cs | 2 +- + src/QLNet/Math/integrals/DiscreteIntegrals.cs | 2 +- + src/QLNet/Math/integrals/GaussLobattoIntegral.cs | 2 +- + .../Math/integrals/GaussianOrthogonalPolynomial.cs | 2 +- + src/QLNet/Math/integrals/GaussianQuadratures.cs | 2 +- + src/QLNet/Math/integrals/Integral.cs | 2 +- + src/QLNet/Math/integrals/Kronrodintegral.cs | 2 +- + src/QLNet/Math/integrals/Segmentintegral.cs | 2 +- + src/QLNet/Math/integrals/SimpsonIntegral.cs | 2 +- + src/QLNet/Math/integrals/TrapezoidIntegral.cs | 2 +- + src/QLNet/Math/matrixutilities/BiCGStab.cs | 2 +- + .../Math/matrixutilities/CholeskyDecomposition.cs | 2 +- + src/QLNet/Math/matrixutilities/GMRES.cs | 2 +- + src/QLNet/Math/matrixutilities/PseudoSqrt.cs | 2 +- + src/QLNet/Math/matrixutilities/QRDecomposition.cs | 2 +- + src/QLNet/Math/matrixutilities/SVD.cs | 2 +- + src/QLNet/Math/matrixutilities/SparseMatrix.cs | 2 +- + .../matrixutilities/SymmetricSchurDecomposition.cs | 2 +- + .../Math/matrixutilities/TqrEigenDecomposition.cs | 2 +- + src/QLNet/Math/randomnumbers/Haltonrsg.cs | 2 +- + .../Math/randomnumbers/InverseCumulativeRng.cs | 2 +- + .../Math/randomnumbers/InverseCumulativeRsg.cs | 2 +- + src/QLNet/Math/randomnumbers/MT19937UniformRng.cs | 2 +- + .../Math/randomnumbers/PrimitivePolynomials.cs | 2 +- + src/QLNet/Math/randomnumbers/RNGTraits.cs | 2 +- + .../Math/randomnumbers/RandomSequenceGenerator.cs | 2 +- + src/QLNet/Math/randomnumbers/SeedGenerator.cs | 2 +- + .../Math/randomnumbers/SobolBrownianBridgeRsg.cs | 2 +- + src/QLNet/Math/randomnumbers/SobolRsg.cs | 2 +- + src/QLNet/Math/randomnumbers/SobolRsg2.cs | 2 +- + src/QLNet/Math/statistics/ConvergenceStatistics.cs | 2 +- + src/QLNet/Math/statistics/DiscrepancyStatistics.cs | 2 +- + src/QLNet/Math/statistics/GaussianStatistics.cs | 2 +- + src/QLNet/Math/statistics/GeneralStatistics.cs | 2 +- + src/QLNet/Math/statistics/IncrementalStatistics.cs | 2 +- + src/QLNet/Math/statistics/RiskStatistics.cs | 2 +- + src/QLNet/Math/statistics/SequenceStatistics.cs | 2 +- + .../Methods/Finitedifferences/AmericanCondition.cs | 2 +- + src/QLNet/Methods/Finitedifferences/BSMOperator.cs | 2 +- + .../Methods/Finitedifferences/BoundaryCondition.cs | 2 +- + .../Methods/Finitedifferences/CrankNicolson.cs | 2 +- + src/QLNet/Methods/Finitedifferences/DMinus.cs | 2 +- + src/QLNet/Methods/Finitedifferences/DPlus.cs | 2 +- + src/QLNet/Methods/Finitedifferences/DPlusDMinus.cs | 2 +- + src/QLNet/Methods/Finitedifferences/DZero.cs | 2 +- + .../Methods/Finitedifferences/ExplicitEuler.cs | 2 +- + .../Finitedifferences/FiniteDifferenceModel.cs | 2 +- + .../Methods/Finitedifferences/ImplicitEuler.cs | 2 +- + .../Meshers/Concentrating1dMesher.cs | 2 +- + .../Finitedifferences/Meshers/Fdm1dMesher.cs | 2 +- + .../Meshers/FdmBlackScholesMesher.cs | 2 +- + .../Methods/Finitedifferences/Meshers/FdmMesher.cs | 2 +- + .../Meshers/FdmMesherComposite.cs | 2 +- + .../Meshers/FdmSimpleProcess1dMesher.cs | 2 +- + .../Finitedifferences/Meshers/Uniform1dMesher.cs | 2 +- + .../Finitedifferences/Meshers/UniformGridMesher.cs | 2 +- + src/QLNet/Methods/Finitedifferences/MixedScheme.cs | 2 +- + .../Methods/Finitedifferences/OperatorFactory.cs | 2 +- + .../Operators/FdmBlackScholesOp.cs | 2 +- + .../Finitedifferences/Operators/FdmHullWhiteOp.cs | 2 +- + .../Finitedifferences/Operators/FdmLinearOp.cs | 2 +- + .../Operators/FdmLinearOpComposite.cs | 2 +- + .../Operators/FdmLinearOpIterator.cs | 2 +- + .../Operators/FdmLinearOpLayout.cs | 2 +- + .../Operators/FirstDerivativeOp.cs | 2 +- + .../Operators/NinePointLinearOp.cs | 2 +- + .../Operators/SecondDerivativeOp.cs | 2 +- + .../Operators/SecondOrderMixedDerivativeOp.cs | 2 +- + .../Operators/TripleBandLinearOp.cs | 2 +- + .../Methods/Finitedifferences/ParallelEvolver.cs | 2 +- + src/QLNet/Methods/Finitedifferences/Pde.cs | 2 +- + src/QLNet/Methods/Finitedifferences/PdeBsm.cs | 2 +- + .../Methods/Finitedifferences/PdeShortRate.cs | 2 +- + .../Schemes/BoundaryConditionSchemeHelper.cs | 2 +- + .../Finitedifferences/Schemes/CraigSneydScheme.cs | 2 +- + .../Finitedifferences/Schemes/DouglasScheme.cs | 2 +- + .../Schemes/ExplicitEulerScheme.cs | 2 +- + .../Finitedifferences/Schemes/HundsdorferScheme.cs | 2 +- + .../Schemes/ImplicitEulerScheme.cs | 2 +- + .../Schemes/ModifiedCraigSneydScheme.cs | 2 +- + .../Methods/Finitedifferences/ShoutCondition.cs | 2 +- + .../Finitedifferences/Solvers/Fdm1DimSolver.cs | 2 +- + .../Finitedifferences/Solvers/FdmBackwardSolver.cs | 2 +- + .../Solvers/FdmBlackScholesSolver.cs | 2 +- + .../Solvers/FdmHullWhiteSolver.cs | 2 +- + .../Finitedifferences/Solvers/FdmSolverDesc.cs | 2 +- + .../Methods/Finitedifferences/StepCondition.cs | 2 +- + .../StepConditions/FdmAmericanStepCondition.cs | 2 +- + .../StepConditions/FdmBermudanStepCondition.cs | 2 +- + .../StepConditions/FdmSnapshotCondition.cs | 2 +- + .../StepConditions/FdmStepConditionComposite.cs | 2 +- + src/QLNet/Methods/Finitedifferences/TRBDF2.cs | 2 +- + .../Finitedifferences/TridiagonalOperator.cs | 2 +- + .../Utilities/FdmAffineModelSwapInnerValue.cs | 2 +- + .../Utilities/FdmAffineModelTermStructure.cs | 2 +- + .../Utilities/FdmBoundaryConditionSet.cs | 2 +- + .../Utilities/FdmDirichletBoundary.cs | 2 +- + .../Utilities/FdmDividendHandler.cs | 2 +- + .../Utilities/FdmIndicesOnBoundary.cs | 2 +- + .../Utilities/FdmInnerValueCalculator.cs | 2 +- + .../Utilities/FdmMesherIntegral.cs | 2 +- + .../Finitedifferences/Utilities/ListUtils.cs | 2 +- + .../Methods/Finitedifferences/ZeroCondition.cs | 2 +- + src/QLNet/Methods/lattices/BinominalTree.cs | 2 +- + src/QLNet/Methods/lattices/BsmLattice.cs | 2 +- + src/QLNet/Methods/lattices/Lattice.cs | 2 +- + src/QLNet/Methods/lattices/Lattice1D.cs | 2 +- + src/QLNet/Methods/lattices/Lattice2D.cs | 2 +- + src/QLNet/Methods/lattices/Tree.cs | 2 +- + src/QLNet/Methods/lattices/TrinomialTree.cs | 2 +- + src/QLNet/Methods/montecarlo/BrownianBridge.cs | 2 +- + .../Methods/montecarlo/EarlyExercisePathPricer.cs | 2 +- + .../montecarlo/LongstaffSchwartzPathPricer.cs | 2 +- + src/QLNet/Methods/montecarlo/LsmBasisSystem.cs | 2 +- + src/QLNet/Methods/montecarlo/MCTraits.cs | 2 +- + src/QLNet/Methods/montecarlo/MontecarloModel.cs | 2 +- + src/QLNet/Methods/montecarlo/MultiPath.cs | 2 +- + src/QLNet/Methods/montecarlo/MultiPathGenerator.cs | 2 +- + src/QLNet/Methods/montecarlo/Path.cs | 2 +- + src/QLNet/Methods/montecarlo/PathGenerator.cs | 2 +- + src/QLNet/Methods/montecarlo/PathPricer.cs | 2 +- + src/QLNet/Methods/montecarlo/Sample.cs | 2 +- + src/QLNet/Models/CalibrationHelper.cs | 2 +- + src/QLNet/Models/Equity/HestonModel.cs | 2 +- + src/QLNet/Models/Equity/HestonModelHelper.cs | 2 +- + .../Equity/PiecewiseTimeDependentHestonModel.cs | 2 +- + src/QLNet/Models/MarketModels/BrownianGenerator.cs | 2 +- + .../BrownianGenerators/SobolBrownianGenerator.cs | 2 +- + src/QLNet/Models/Model.cs | 2 +- + src/QLNet/Models/Parameter.cs | 2 +- + src/QLNet/Models/Shortrate/OneFactorModel.cs | 2 +- + .../Shortrate/Onefactormodels/BlackKarasinski.cs | 2 +- + .../Shortrate/Onefactormodels/CoxIngersollRoss.cs | 2 +- + .../Models/Shortrate/Onefactormodels/HullWhite.cs | 2 +- + .../Models/Shortrate/Onefactormodels/Vasicek.cs | 2 +- + src/QLNet/Models/Shortrate/TwoFactorModel.cs | 2 +- + src/QLNet/Models/Shortrate/Twofactorsmodels/G2.cs | 2 +- + .../Shortrate/calibrationhelpers/CapHelper.cs | 2 +- + .../Shortrate/calibrationhelpers/SwaptionHelper.cs | 2 +- + src/QLNet/Money.cs | 2 +- + src/QLNet/NumericalMethod.cs | 2 +- + src/QLNet/Option.cs | 2 +- + src/QLNet/Patterns/FastActivator.cs | 2 +- + src/QLNet/Patterns/LazyObject.cs | 2 +- + src/QLNet/Patterns/ObservableValue.cs | 2 +- + src/QLNet/Patterns/Observer.cs | 2 +- + src/QLNet/Patterns/Visitor.cs | 2 +- + src/QLNet/Patterns/WeakEventSource.cs | 2 +- + src/QLNet/Payoff.cs | 2 +- + src/QLNet/PricingEngine.cs | 2 +- + src/QLNet/Pricingengines/Americanpayoffatexpiry.cs | 2 +- + src/QLNet/Pricingengines/Americanpayoffathit.cs | 2 +- + src/QLNet/Pricingengines/Basket/KirkEngine.cs | 2 +- + .../Basket/MCEuropeanBasketEngine.cs | 2 +- + src/QLNet/Pricingengines/Basket/StulzEngine.cs | 2 +- + src/QLNet/Pricingengines/BlackCalculator.cs | 2 +- + src/QLNet/Pricingengines/BlackDeltaCalculator.cs | 2 +- + src/QLNet/Pricingengines/BlackFormula.cs | 2 +- + src/QLNet/Pricingengines/Blackscholescalculator.cs | 2 +- + .../Pricingengines/Bond/BlackCallableBondEngine.cs | 2 +- + src/QLNet/Pricingengines/Bond/BondFunctions.cs | 2 +- + .../Pricingengines/Bond/Discountingbondengine.cs | 2 +- + .../Pricingengines/Bond/TreeCallableBondEngine.cs | 2 +- + .../CapFloor/AnalyticCapFloorEngine.cs | 2 +- + .../CapFloor/BachelierCapFloorEngine.cs | 2 +- + .../Pricingengines/CapFloor/BlackCapFloorEngine.cs | 2 +- + .../Pricingengines/CapFloor/DiscretizedCapFloor.cs | 2 +- + .../Cliquet/AnalyticCliquetEngine.cs | 2 +- + .../Cliquet/AnalyticPerformanceEngine.cs | 2 +- + .../Forward/ForwardPerformanceVanillaEngine.cs | 2 +- + .../Pricingengines/Forward/ForwardVanillaEngine.cs | 2 +- + src/QLNet/Pricingengines/GenericModelEngine.cs | 2 +- + src/QLNet/Pricingengines/Greeks.cs | 2 +- + .../Pricingengines/LatticeShortRateModelEngine.cs | 2 +- + .../Pricingengines/Loan/DiscountingLoanEngine.cs | 2 +- + .../AnalyticContinuousFixedLookbackEngine.cs | 2 +- + .../AnalyticContinuousFloatingLookbackEngine.cs | 2 +- + ...AnalyticContinuousPartialFixedLookbackEngine.cs | 2 +- + ...lyticContinuousPartialFloatingLookbackEngine.cs | 2 +- + .../Pricingengines/MCLongstaffSchwartzEngine.cs | 2 +- + src/QLNet/Pricingengines/McSimulation.cs | 2 +- + .../Swap/CounterpartyAdjSwapEngine.cs | 2 +- + .../Swap/DiscountingBasisSwapEngine.cs | 2 +- + .../Pricingengines/Swap/Discountingswapengine.cs | 2 +- + src/QLNet/Pricingengines/Swap/DiscretizedSwap.cs | 2 +- + src/QLNet/Pricingengines/Swap/TreeSwapEngine.cs | 2 +- + ...icContinuousGeometricAveragePriceAsianEngine.cs | 2 +- + ...yticDiscreteGeometricAveragePriceAsianEngine.cs | 2 +- + ...ticDiscreteGeometricAverageStrikeAsianEngine.cs | 2 +- + .../Pricingengines/asian/McDiscreteAsianEngine.cs | 2 +- + .../asian/Mc_Discr_Arith_Av_Price.cs | 2 +- + .../asian/Mc_Discr_Arith_Av_Strike.cs | 2 +- + .../Pricingengines/asian/Mc_Discr_Geom_Av_Price.cs | 2 +- + .../barrier/AnalyticBarrierEngine.cs | 2 +- + .../barrier/AnalyticBinaryBarrierEngine.cs | 2 +- + .../barrier/AnalyticDoubleBarrierBinaryEngine.cs | 2 +- + .../barrier/AnalyticDoubleBarrierEngine.cs | 2 +- + .../barrier/BinomialBarrierEngine.cs | 2 +- + .../barrier/BinomialDoubleBarrierEngine.cs | 2 +- + .../barrier/DiscretizedBarrierOption.cs | 2 +- + .../barrier/DiscretizedDoubleBarrierOption.cs | 2 +- + .../barrier/FdBlackScholesBarrierEngine.cs | 2 +- + .../barrier/FdBlackScholesRebateEngine.cs | 2 +- + .../barrier/VannaVolgaBarrierEngine.cs | 2 +- + .../barrier/VannaVolgaDoubleBarrierEngine.cs | 2 +- + .../barrier/WulinYongDoubleBarrierEngine.cs | 2 +- + .../Pricingengines/credit/IntegralCdsEngine.cs | 2 +- + src/QLNet/Pricingengines/credit/IsdaCdsEngine.cs | 2 +- + .../Pricingengines/credit/MidPointCdsEngine.cs | 2 +- + .../inflation/InflationCapFloorEngines.cs | 2 +- + .../inflation/InterpolatingCPICapFloorEngine.cs | 2 +- + .../Pricingengines/swaption/BlackSwaptionEngine.cs | 2 +- + .../Pricingengines/swaption/DiscretizedSwaption.cs | 2 +- + .../Pricingengines/swaption/G2SwaptionEngine.cs | 2 +- + .../swaption/JamshidianSwaptionEngine.cs | 2 +- + .../Pricingengines/swaption/TreeSwaptionEngine.cs | 2 +- + .../vanilla/AnalyticBSMHullWhiteEngine.cs | 2 +- + .../vanilla/AnalyticDigitalAmericanEngine.cs | 2 +- + .../vanilla/AnalyticDividendEuropeanEngine.cs | 2 +- + .../vanilla/AnalyticEuropeanEngine.cs | 2 +- + .../Pricingengines/vanilla/AnalyticH1HWEngine.cs | 2 +- + .../Pricingengines/vanilla/AnalyticHestonEngine.cs | 2 +- + .../vanilla/AnalyticHestonHullWhiteEngine.cs | 2 +- + .../vanilla/AnalyticPTDHestonEngine.cs | 2 +- + .../vanilla/BaroneAdesiWhaleyEngine.cs | 2 +- + src/QLNet/Pricingengines/vanilla/BinomialEngine.cs | 2 +- + .../vanilla/BjerksundStenslandEngine.cs | 2 +- + .../vanilla/DiscretizedVanillaOption.cs | 2 +- + .../Pricingengines/vanilla/FDAmericanEngine.cs | 2 +- + .../Pricingengines/vanilla/FDBermudanEngine.cs | 2 +- + src/QLNet/Pricingengines/vanilla/FDConditions.cs | 2 +- + .../vanilla/FDDividendAmericanEngine.cs | 2 +- + .../Pricingengines/vanilla/FDDividendEngine.cs | 2 +- + .../vanilla/FDDividendEuropeanEngine.cs | 2 +- + .../Pricingengines/vanilla/FDEuropeanEngine.cs | 2 +- + .../Pricingengines/vanilla/FDMultiPeriodEngine.cs | 2 +- + src/QLNet/Pricingengines/vanilla/FDShoutEngine.cs | 2 +- + .../vanilla/FDStepConditionEngine.cs | 2 +- + .../Pricingengines/vanilla/FDVanillaEngine.cs | 2 +- + .../vanilla/FdBlackScholesVanillaEngine.cs | 2 +- + .../vanilla/FdHestonVanillaEngine.cs | 2 +- + .../vanilla/FdHullWhiteSwaptionEngine.cs | 2 +- + .../vanilla/HestonExpansionEngine.cs | 2 +- + src/QLNet/Pricingengines/vanilla/Integralengine.cs | 2 +- + .../Pricingengines/vanilla/Juquadraticengine.cs | 2 +- + .../vanilla/MCEuropeanHestonEngine.cs | 2 +- + .../vanilla/MCHestonHullWhiteEngine.cs | 2 +- + .../Pricingengines/vanilla/McAmericanEngine.cs | 2 +- + .../Pricingengines/vanilla/McEuropeanEngine.cs | 2 +- + .../Pricingengines/vanilla/McVanillaEngine.cs | 2 +- + src/QLNet/Quotes/CompositeQuote.cs | 2 +- + src/QLNet/Quotes/DeltaVolQuote.cs | 2 +- + src/QLNet/Quotes/DerivedQuote.cs | 2 +- + src/QLNet/Quotes/LastFixingQuote.cs | 2 +- + src/QLNet/Quotes/Quote.cs | 2 +- + src/QLNet/Quotes/SimpleQuote.cs | 2 +- + src/QLNet/Settings.cs | 2 +- + src/QLNet/StochasticProcess.cs | 2 +- + src/QLNet/Termstructures/Bootstraperror.cs | 2 +- + src/QLNet/Termstructures/Bootstraphelper.cs | 2 +- + src/QLNet/Termstructures/Credit/FlatHazardRate.cs | 2 +- + .../Termstructures/Credit/HazardRateStructure.cs | 2 +- + .../Credit/InterpolatedHazardRateCurve.cs | 2 +- + .../Credit/InterpolatedSurvivalProbabilityCurve.cs | 2 +- + .../Termstructures/Credit/ProbabilityTraits.cs | 2 +- + .../Credit/SurvivalProbabilityStructure.cs | 2 +- + src/QLNet/Termstructures/Curve.cs | 2 +- + .../DefaultProbabilityTermStructure.cs | 2 +- + .../Inflation/CPICapFloorTermPriceSurface.cs | 2 +- + .../Termstructures/Inflation/InflationHelpers.cs | 2 +- + .../Termstructures/Inflation/InflationTraits.cs | 2 +- + .../Inflation/InterpolatedYoYInflationCurve.cs | 2 +- + .../Inflation/InterpolatedZeroInflationCurve.cs | 2 +- + .../Inflation/PiecewiseYoYInflationCurve.cs | 2 +- + .../Inflation/PiecewiseZeroInflationCurve.cs | 2 +- + src/QLNet/Termstructures/Inflation/Seasonality.cs | 2 +- + src/QLNet/Termstructures/InflationTermStructure.cs | 2 +- + src/QLNet/Termstructures/InterpolatedCurve.cs | 2 +- + src/QLNet/Termstructures/Iterativebootstrap.cs | 2 +- + src/QLNet/Termstructures/LocalBootstrap.cs | 2 +- + src/QLNet/Termstructures/TermStructure.cs | 2 +- + src/QLNet/Termstructures/VolTermStructure.cs | 2 +- + .../Termstructures/Volatility/AbcdCalibration.cs | 2 +- + .../Termstructures/Volatility/AbcdFunction.cs | 2 +- + .../Termstructures/Volatility/AtmSmileSection.cs | 2 +- + .../Bond/CallableBondConstantVolatility.cs | 2 +- + .../Bond/CallableBondVolatilityStructure.cs | 2 +- + .../Volatility/CapFloor/CapFloorTermVolCurve.cs | 2 +- + .../Volatility/CapFloor/CapFloorTermVolSurface.cs | 2 +- + .../CapFloor/CapFloorTermVolatilityStructure.cs | 2 +- + .../CapFloor/ConstantCapFloorTermVolatility.cs | 2 +- + .../Termstructures/Volatility/FlatSmileSection.cs | 2 +- + .../Volatility/Inflation/CPIVolatilitySurface.cs | 2 +- + .../YoYInflationOptionletVolatilityStructure.cs | 2 +- + .../Volatility/InterpolatedSmileSection.cs | 2 +- + .../Volatility/Optionlet/CapletVarianceCurve.cs | 2 +- + .../Optionlet/ConstantOptionletVolatility.cs | 2 +- + .../Volatility/Optionlet/OptionletStripper.cs | 2 +- + .../Volatility/Optionlet/OptionletStripper1.cs | 2 +- + .../Volatility/Optionlet/OptionletStripper2.cs | 2 +- + .../Optionlet/OptionletVolatilityStructure.cs | 2 +- + .../Optionlet/SpreadedOptionletVolatility.cs | 2 +- + .../Optionlet/StrippedOptionletAdapter.cs | 2 +- + .../Volatility/Optionlet/StrippedOptionletBase.cs | 2 +- + src/QLNet/Termstructures/Volatility/Sabr.cs | 2 +- + .../Volatility/SabrInterpolatedSmileSection.cs | 2 +- + .../Termstructures/Volatility/SmileSection.cs | 2 +- + .../Volatility/SpreadedSmileSection.cs | 2 +- + src/QLNet/Termstructures/Volatility/Svi.cs | 2 +- + .../Volatility/SviInterpolatedSmileSection.cs | 2 +- + .../Termstructures/Volatility/SviSmileSection.cs | 2 +- + .../Volatility/equityfx/BlackConstantVol.cs | 2 +- + .../Volatility/equityfx/BlackVarianceCurve.cs | 2 +- + .../Volatility/equityfx/BlackVarianceSurface.cs | 2 +- + .../Volatility/equityfx/BlackVolTermStructure.cs | 2 +- + .../Volatility/equityfx/FixedLocalVolSurface.cs | 2 +- + .../Volatility/equityfx/HestonBlackVolSurface.cs | 2 +- + .../Volatility/equityfx/ImpliedVolTermStructure.cs | 2 +- + .../Volatility/equityfx/LocalConstantVol.cs | 2 +- + .../Volatility/equityfx/LocalVolCurve.cs | 2 +- + .../Volatility/equityfx/LocalVolSurface.cs | 2 +- + .../Volatility/equityfx/LocalVolTermStructure.cs | 2 +- + .../Volatility/equityfx/NoExceptLocalVolSurface.cs | 2 +- + .../swaption/SpreadedSwaptionVolatility.cs | 2 +- + .../Volatility/swaption/SwaptionConstantVol.cs | 2 +- + .../Volatility/swaption/SwaptionVolCube1.cs | 2 +- + .../Volatility/swaption/SwaptionVolCube2.cs | 2 +- + .../Volatility/swaption/SwaptionVolDiscrete.cs | 2 +- + .../Volatility/swaption/SwaptionVolMatrix.cs | 2 +- + .../Volatility/swaption/SwaptionVolatilityCube.cs | 2 +- + .../swaption/SwaptionVolatilityStructure.cs | 2 +- + src/QLNet/Termstructures/Yield/BasisSwapHelper.cs | 2 +- + src/QLNet/Termstructures/Yield/Bondhelpers.cs | 2 +- + src/QLNet/Termstructures/Yield/Bootstraptraits.cs | 2 +- + .../Yield/CompositeZeroYieldStructure.cs | 2 +- + src/QLNet/Termstructures/Yield/DiscountCurve.cs | 2 +- + .../Yield/FittedBondDiscountCurve.cs | 2 +- + src/QLNet/Termstructures/Yield/Flatforward.cs | 2 +- + src/QLNet/Termstructures/Yield/ForwardCurve.cs | 2 +- + .../Yield/ForwardSpreadedTermStructure.cs | 2 +- + src/QLNet/Termstructures/Yield/ForwardStructure.cs | 2 +- + .../Termstructures/Yield/ImpliedTermStructure.cs | 2 +- + ...terpolatedPiecewiseZeroSpreadedTermStructure.cs | 2 +- + .../Yield/NonLinearFittingMethods.cs | 2 +- + src/QLNet/Termstructures/Yield/OISRateHelper.cs | 2 +- + .../Termstructures/Yield/PiecewiseYieldCurve.cs | 2 +- + src/QLNet/Termstructures/Yield/Ratehelpers.cs | 2 +- + src/QLNet/Termstructures/Yield/ZeroCurve.cs | 2 +- + .../Yield/ZeroSpreadedTermStructure.cs | 2 +- + .../Termstructures/Yield/Zeroyieldstructure.cs | 2 +- + src/QLNet/Termstructures/YieldTermStructure.cs | 2 +- + src/QLNet/Time/ASX.cs | 2 +- + src/QLNet/Time/Calendar.cs | 2 +- + src/QLNet/Time/Calendars/Argentina.cs | 2 +- + src/QLNet/Time/Calendars/Australia.cs | 2 +- + src/QLNet/Time/Calendars/BespokeCalendar.cs | 2 +- + src/QLNet/Time/Calendars/Botswana.cs | 2 +- + src/QLNet/Time/Calendars/Brazil.cs | 2 +- + src/QLNet/Time/Calendars/Canada.cs | 2 +- + src/QLNet/Time/Calendars/China.cs | 2 +- + src/QLNet/Time/Calendars/CzechRepublic.cs | 2 +- + src/QLNet/Time/Calendars/Denmark.cs | 2 +- + src/QLNet/Time/Calendars/Finland.cs | 2 +- + src/QLNet/Time/Calendars/Germany.cs | 2 +- + src/QLNet/Time/Calendars/HongKong.cs | 2 +- + src/QLNet/Time/Calendars/Hungary.cs | 2 +- + src/QLNet/Time/Calendars/Iceland.cs | 2 +- + src/QLNet/Time/Calendars/India.cs | 2 +- + src/QLNet/Time/Calendars/Indonesia.cs | 2 +- + src/QLNet/Time/Calendars/Israel.cs | 2 +- + src/QLNet/Time/Calendars/Italy.cs | 2 +- + src/QLNet/Time/Calendars/Japan.cs | 2 +- + src/QLNet/Time/Calendars/JointCalendar.cs | 2 +- + src/QLNet/Time/Calendars/Mexico.cs | 2 +- + src/QLNet/Time/Calendars/NewZealand.cs | 2 +- + src/QLNet/Time/Calendars/Norway.cs | 2 +- + src/QLNet/Time/Calendars/NullCalendar.cs | 2 +- + src/QLNet/Time/Calendars/Poland.cs | 2 +- + src/QLNet/Time/Calendars/Romania.cs | 2 +- + src/QLNet/Time/Calendars/Russia.cs | 2 +- + src/QLNet/Time/Calendars/SaudiArabia.cs | 2 +- + src/QLNet/Time/Calendars/Singapore.cs | 2 +- + src/QLNet/Time/Calendars/Slovakia.cs | 2 +- + src/QLNet/Time/Calendars/SouthAfrica.cs | 2 +- + src/QLNet/Time/Calendars/SouthKorea.cs | 2 +- + src/QLNet/Time/Calendars/Sweden.cs | 2 +- + src/QLNet/Time/Calendars/Switzerland.cs | 2 +- + src/QLNet/Time/Calendars/TARGET.cs | 2 +- + src/QLNet/Time/Calendars/Taiwan.cs | 2 +- + src/QLNet/Time/Calendars/Turkey.cs | 2 +- + src/QLNet/Time/Calendars/Ukraine.cs | 2 +- + src/QLNet/Time/Calendars/UnitedKingdom.cs | 2 +- + src/QLNet/Time/Calendars/UnitedStates.cs | 2 +- + src/QLNet/Time/Calendars/WeekendsOnly.cs | 2 +- + src/QLNet/Time/Date.cs | 2 +- + src/QLNet/Time/DayCounter.cs | 2 +- + src/QLNet/Time/DayCounters/Actual360.cs | 2 +- + src/QLNet/Time/DayCounters/Actual365Fixed.cs | 2 +- + src/QLNet/Time/DayCounters/Actual365NoLeap.cs | 2 +- + src/QLNet/Time/DayCounters/ActualActual.cs | 2 +- + src/QLNet/Time/DayCounters/Business252.cs | 2 +- + src/QLNet/Time/DayCounters/OneDayCounter.cs | 2 +- + src/QLNet/Time/DayCounters/SimpleDayCounter.cs | 2 +- + src/QLNet/Time/DayCounters/Thirty360.cs | 2 +- + src/QLNet/Time/ECB.cs | 2 +- + src/QLNet/Time/Imm.cs | 2 +- + src/QLNet/Time/Period.cs | 2 +- + src/QLNet/Time/Schedule.cs | 2 +- + src/QLNet/TimeGrid.cs | 2 +- + src/QLNet/Types.cs | 2 +- + src/QLNet/Utils.cs | 2 +- + .../legacy/libormarketmodels/LfmCovarParam.cs | 2 +- + .../legacy/libormarketmodels/LfmCovarianceProxy.cs | 2 +- + .../legacy/libormarketmodels/LfmHullWhiteParam.cs | 2 +- + src/QLNet/legacy/libormarketmodels/LfmProcess.cs | 2 +- + .../legacy/libormarketmodels/LfmSwaptionEngine.cs | 2 +- + .../legacy/libormarketmodels/LiborForwardModel.cs | 2 +- + .../libormarketmodels/LmConstWrapperCorrModel.cs | 2 +- + .../libormarketmodels/LmConstWrapperVolModel.cs | 2 +- + src/QLNet/legacy/libormarketmodels/LmCorrModel.cs | 2 +- + .../legacy/libormarketmodels/LmExpCorrModel.cs | 2 +- + .../libormarketmodels/LmExtLinExpVolModel.cs | 2 +- + .../legacy/libormarketmodels/LmFixedVolModel.cs | 2 +- + .../legacy/libormarketmodels/LmLinExpCorrModel.cs | 2 +- + .../legacy/libormarketmodels/LmLinExpVolModel.cs | 2 +- + src/QLNet/legacy/libormarketmodels/LmVolModel.cs | 2 +- + src/QLNet/processes/BlackScholesProcess.cs | 2 +- + src/QLNet/processes/Defaultable.cs | 2 +- + src/QLNet/processes/EulerDiscretization.cs | 2 +- + src/QLNet/processes/ForwardMeasureProcess.cs | 2 +- + .../processes/GeometricBrownianMotionProcess.cs | 2 +- + src/QLNet/processes/HestonProcess.cs | 2 +- + src/QLNet/processes/HullWhiteProcess.cs | 2 +- + .../processes/HybridHestonHullWhiteProcess.cs | 2 +- + src/QLNet/processes/Ornsteinuhlenbeckprocess.cs | 2 +- + src/QLNet/processes/Squarerootprocess.cs | 2 +- + src/QLNet/processes/StochasticProcessArray.cs | 2 +- + src/Repo/Repo.cs | 2 +- + src/Swap/swapvaluation.cs | 2 +- + tests/QLNet.Tests/T_AmericanOption.cs | 2 +- + tests/QLNet.Tests/T_AsianOptions.cs | 4 ++-- + tests/QLNet.Tests/T_AssetSwap.cs | 2 +- + tests/QLNet.Tests/T_BarrierOption.cs | 2 +- + tests/QLNet.Tests/T_BasketOption.cs | 2 +- + tests/QLNet.Tests/T_Bermudanswaption.cs | 4 ++-- + tests/QLNet.Tests/T_BinaryOption.cs | 2 +- + tests/QLNet.Tests/T_BlackDeltaCalculator.cs | 2 +- + tests/QLNet.Tests/T_BlackFormula.cs | 2 +- + tests/QLNet.Tests/T_Bonds.cs | 2 +- + tests/QLNet.Tests/T_BusinessDayConvention.cs | 2 +- + tests/QLNet.Tests/T_CPISwap.cs | 2 +- + tests/QLNet.Tests/T_Calendars.cs | 2 +- + tests/QLNet.Tests/T_CapFloor.cs | 2 +- + tests/QLNet.Tests/T_CapFlooredCoupon.cs | 2 +- + tests/QLNet.Tests/T_CashFlows.cs | 2 +- + tests/QLNet.Tests/T_CliquetOption.cs | 2 +- + tests/QLNet.Tests/T_Cms.cs | 2 +- + tests/QLNet.Tests/T_CreditDefaultSwap.cs | 2 +- + tests/QLNet.Tests/T_Dates.cs | 2 +- + tests/QLNet.Tests/T_DayCounters.cs | 2 +- + tests/QLNet.Tests/T_DefaultProbabilityCurves.cs | 2 +- + tests/QLNet.Tests/T_DigitalCoupon.cs | 2 +- + tests/QLNet.Tests/T_DigitalOption.cs | 2 +- + tests/QLNet.Tests/T_DividendOption.cs | 4 ++-- + tests/QLNet.Tests/T_DoubleBarrierOption.cs | 2 +- + tests/QLNet.Tests/T_DoubleBinaryOption.cs | 2 +- + tests/QLNet.Tests/T_EuropeanOption.cs | 2 +- + tests/QLNet.Tests/T_ExchangeRate.cs | 2 +- + tests/QLNet.Tests/T_FdmLinearOp.cs | 22 ++++++++++++++++++++-- + tests/QLNet.Tests/T_ForwardOption.cs | 2 +- + tests/QLNet.Tests/T_Functions.cs | 2 +- + tests/QLNet.Tests/T_HestonModel.cs | 2 +- + .../QLNet.Tests/T_HybridHestonHullWhiteProcess.cs | 2 +- + tests/QLNet.Tests/T_Inflation.cs | 2 +- + tests/QLNet.Tests/T_InflationCPICapFloor.cs | 2 +- + tests/QLNet.Tests/T_InflationCapFloorTest.cs | 2 +- + .../QLNet.Tests/T_InflationCapFlooredCouponTest.cs | 2 +- + tests/QLNet.Tests/T_Instruments.cs | 2 +- + tests/QLNet.Tests/T_InterestRate.cs | 2 +- + tests/QLNet.Tests/T_Interpolations.cs | 2 +- + tests/QLNet.Tests/T_LiborMarketModel.cs | 4 ++-- + tests/QLNet.Tests/T_LiborMarketModelProcess.cs | 2 +- + .../QLNet.Tests/T_LinearLeastSquaresRegression.cs | 2 +- + tests/QLNet.Tests/T_LookbackOption.cs | 2 +- + tests/QLNet.Tests/T_LowDiscrepancySequences.cs | 2 +- + tests/QLNet.Tests/T_Matrices.cs | 2 +- + tests/QLNet.Tests/T_Mclongstaffschwartzengine.cs | 2 +- + tests/QLNet.Tests/T_Money.cs | 2 +- + tests/QLNet.Tests/T_Operators.cs | 2 +- + tests/QLNet.Tests/T_Optimizers.cs | 2 +- + tests/QLNet.Tests/T_OptionletStripper.cs | 2 +- + tests/QLNet.Tests/T_OvernightIndexedSwap.cs | 2 +- + tests/QLNet.Tests/T_PSACurve.cs | 2 +- + tests/QLNet.Tests/T_PathGenerator.cs | 2 +- + .../T_PiecewiseZeroSpreadedTermStructure.cs | 2 +- + tests/QLNet.Tests/T_Piecewiseyieldcurve.cs | 2 +- + tests/QLNet.Tests/T_Quotes.cs | 2 +- + tests/QLNet.Tests/T_RNGTraits.cs | 2 +- + tests/QLNet.Tests/T_RiskStats.cs | 2 +- + tests/QLNet.Tests/T_Rounding.cs | 2 +- + tests/QLNet.Tests/T_SVI.cs | 2 +- + tests/QLNet.Tests/T_SampledCurve.cs | 2 +- + tests/QLNet.Tests/T_Schedule.cs | 2 +- + tests/QLNet.Tests/T_ShortRateModels.cs | 2 +- + tests/QLNet.Tests/T_Solvers.cs | 2 +- + tests/QLNet.Tests/T_Stats.cs | 2 +- + tests/QLNet.Tests/T_Swaps.cs | 2 +- + tests/QLNet.Tests/T_Swaption.cs | 2 +- + tests/QLNet.Tests/T_SwaptionVolatilityCube.cs | 2 +- + tests/QLNet.Tests/T_SwaptionVolatilitymatrix.cs | 2 +- + tests/QLNet.Tests/T_TermStructures.cs | 2 +- + tests/QLNet.Tests/T_Vector.cs | 2 +- + tests/QLNet.Tests/Utilities.cs | 2 +- + 760 files changed, 784 insertions(+), 766 deletions(-) + +commit 9319304a01dccb62bc19f4306bea4e30e8eadb43 +Author: Andrea Maggiulli +Date: Mon Feb 5 23:53:31 2018 +0100 + + Updated PULL_REQUEST_TEMPLATE.md [skip ci] + + .github/PULL_REQUEST_TEMPLATE.md | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) - Refactored CallableBonds example +commit d47ccd8d2a3867f67f2373158f1292f0971c3350 +Author: Andrea Maggiulli +Date: Mon Feb 5 23:52:39 2018 +0100 - src/CallableBonds/CallableBonds.cs | 99 ++++++++++++++++++-------------------- - 1 file changed, 47 insertions(+), 52 deletions(-) + Renamed CONTRIBUTING.md to .github/CONTRIBUTING.md [skip ci] -commit b9c4eba498e908395203f989df223d59b11fbad4 -Author: Andrea Maggiulli -Date: Mon Oct 2 14:28:52 2017 +0200 + CONTRIBUTING.md => .github/CONTRIBUTING.md | 0 + 1 file changed, 0 insertions(+), 0 deletions(-) - Fixed Bugs issues , code refactoring & cleanup. +commit ae37d9f9381de5af0d51751f2e072eb17c0cc67f +Author: Andrea Maggiulli +Date: Mon Feb 5 23:50:06 2018 +0100 - .../Meshers/Concentrating1dMesher.cs | 445 +++++++++++---------- - .../Operators/FdmLinearOpIterator.cs | 171 ++++---- - 2 files changed, 319 insertions(+), 297 deletions(-) + Renamed CODE_OF_CONDUCT.md to .github/CODE_OF_CONDUCT.md [skip ci] -commit ee3f19954cdb6c8b8f07606a939b1bfdfb11b57a -Author: Andrea Maggiulli -Date: Mon Oct 2 14:02:46 2017 +0200 - - Fixed Vulnerability issues , code refactoring & cleanup. - - src/QLNet/Instruments/Makeswaption.cs | 9 +- - .../Math/Distributions/chisquaredistribution.cs | 242 +++++------ - src/QLNet/Math/NumericalDifferentiation.cs | 29 +- - src/QLNet/Math/ODE/AdaptiveRungeKutta.cs | 443 ++++++++++++--------- - src/QLNet/Math/integrals/DiscreteIntegrals.cs | 1 - - src/QLNet/Math/matrixutilities/BiCGStab.cs | 195 +++++---- - src/QLNet/Math/matrixutilities/GMRES.cs | 252 ++++++------ - .../Meshers/Concentrating1dMesher.cs | 3 - - .../Finitedifferences/Meshers/Fdm1dMesher.cs | 68 ++-- - .../Meshers/FdmBlackScholesMesher.cs | 1 - - .../Methods/Finitedifferences/Meshers/FdmMesher.cs | 3 - - .../Meshers/FdmMesherComposite.cs | 3 - - .../Finitedifferences/Meshers/Uniform1dMesher.cs | 47 +-- - .../Finitedifferences/Meshers/UniformGridMesher.cs | 101 ++--- - .../Operators/FdmBlackScholesOp.cs | 3 - - .../Finitedifferences/Operators/FdmLinearOp.cs | 3 - - .../Operators/FdmLinearOpComposite.cs | 3 - - .../Operators/FdmLinearOpIterator.cs | 3 - - .../Operators/FdmLinearOpLayout.cs | 3 - - .../Operators/FirstDerivativeOp.cs | 3 - - .../Operators/NinePointLinearOp.cs | 3 - - .../Operators/SecondDerivativeOp.cs | 3 - - .../Operators/SecondOrderMixedDerivativeOp.cs | 3 - - .../Operators/TripleBandLinearOp.cs | 3 - - .../Schemes/BoundaryConditionSchemeHelper.cs | 1 - - .../Finitedifferences/Schemes/CraigSneydScheme.cs | 153 +++---- - .../Finitedifferences/Schemes/DouglasScheme.cs | 134 ++++--- - .../Schemes/ExplicitEulerScheme.cs | 3 - - .../Finitedifferences/Schemes/HundsdorferScheme.cs | 154 +++---- - .../Schemes/ImplicitEulerScheme.cs | 11 +- - .../Schemes/ModifiedCraigSneydScheme.cs | 1 - - .../Finitedifferences/Solvers/Fdm1DimSolver.cs | 1 - - .../Finitedifferences/Solvers/FdmBackwardSolver.cs | 7 +- - .../Solvers/FdmBlackScholesSolver.cs | 5 - - .../Finitedifferences/Solvers/FdmSolverDesc.cs | 67 +++- - .../StepConditions/FdmAmericanStepCondition.cs | 3 - - .../StepConditions/FdmBermudanStepCondition.cs | 97 ++--- - .../StepConditions/FdmSnapshotCondition.cs | 3 - - .../StepConditions/FdmStepConditionComposite.cs | 3 - - .../Utilities/FdmBoundaryConditionSet.cs | 1 - - .../Utilities/FdmDirichletBoundary.cs | 115 +++--- - .../Utilities/FdmDividendHandler.cs | 195 ++++----- - .../Utilities/FdmIndicesOnBoundary.cs | 75 ++-- - .../Utilities/FdmInnerValueCalculator.cs | 3 - - .../Utilities/FdmMesherIntegral.cs | 1 - - src/QLNet/Methods/montecarlo/montecarlomodel.cs | 2 +- - .../Shortrate/Onefactormodels/coxingersollross.cs | 334 +++++++++------- - .../Models/Shortrate/Onefactormodels/hullwhite.cs | 422 ++++++++++---------- - .../Models/Shortrate/Onefactormodels/vasicek.cs | 94 +++-- - src/QLNet/Pricingengines/Swap/treeswapengine.cs | 129 +++--- - .../asian/mc_discr_arith_av_strike.cs | 339 ++++++++-------- - .../Pricingengines/asian/mc_discr_geom_av_price.cs | 429 ++++++++++---------- - .../barrier/FdBlackScholesBarrierEngine.cs | 355 ++++++++--------- - .../barrier/FdBlackScholesRebateEngine.cs | 5 +- - .../vanilla/FdBlackScholesVanillaEngine.cs | 3 - - .../Volatility/equityfx/FixedLocalVolSurface.cs | 2 - - .../Volatility/equityfx/NoExceptLocalVolSurface.cs | 81 ++-- - 57 files changed, 2393 insertions(+), 2262 deletions(-) - -commit 000c4a45591b42a671230f59af56abbc8fcfdadb -Merge: 44e7459 7c1a140 -Author: Andrea Maggiulli -Date: Mon Oct 2 11:19:57 2017 +0200 + CODE_OF_CONDUCT.md => .github/CODE_OF_CONDUCT.md | 0 + 1 file changed, 0 insertions(+), 0 deletions(-) - Merge pull request #173 from tournierjc/LocalVolPort - - Fixed Local Vol and No Except Local Vol +commit 3c6e4e7a5c5109c49900e1ecfb25895b9c74ba84 +Author: Andrea Maggiulli +Date: Mon Feb 5 23:40:26 2018 +0100 -commit 44e7459203ba148c6099d416be83e5ca97e45c80 -Author: Andrea Maggiulli -Date: Mon Oct 2 11:06:27 2017 +0200 + Created PULL_REQUEST_TEMPLATE.md [skip ci] - Fix pull request #172 + .github/PULL_REQUEST_TEMPLATE.md | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) - src/QLNet/Methods/Finitedifferences/Operators/NinePointLinearOp.cs | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) +commit 5d48369aa34f2c7159bf50298bf913d58e0bf70e +Author: Andrea Maggiulli +Date: Mon Feb 5 23:23:41 2018 +0100 -commit f072de7672eeb9b44816141269e08a86700a3fad -Merge: 1a0822c 0571bf8 -Author: Andrea Maggiulli -Date: Mon Oct 2 10:58:25 2017 +0200 + Created ISSUE_TEMPLATE.md [skip ci] - Merge pull request #172 from tournierjc/FiniteDifferencesMethod_Port - - Finite differences method port + .github/ISSUE_TEMPLATE.md | 31 +++++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) -commit 7c1a140ac06d727f75d6da39aa4517a8192a78f3 -Author: tournierjc -Date: Fri Sep 29 00:32:37 2017 +0200 +commit ea44f825b127bcc6bce931c01c194c489b6670d4 +Author: Andrea Maggiulli +Date: Mon Feb 5 23:13:10 2018 +0100 - SonarQube fix + Created LICENSE [skip ci] - .../Volatility/equityfx/FixedLocalVolSurface.cs | 32 ++++++++++------------ - 1 file changed, 15 insertions(+), 17 deletions(-) + LICENSE | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) -commit 0571bf85a164f1d73592b0961e78c46f84db6fae -Author: tournierjc -Date: Fri Sep 29 00:25:14 2017 +0200 +commit 281f56a5ca2b743596c325cffc7ccb6a3967b2cf +Author: Andrea Maggiulli +Date: Mon Feb 5 22:54:21 2018 +0100 - SonarQube fixes 3 + Updated CONTRIBUTING.md [skip ci] - src/QLNet/Math/NumericalDifferentiation.cs | 1 - - src/QLNet/Methods/Finitedifferences/TRBDF2.cs | 31 +++++++++++---------------- - 2 files changed, 13 insertions(+), 19 deletions(-) + CONTRIBUTING.md | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) -commit fcc1e90f9f829991b84bd2b8ff77c390246b27f1 -Author: tournierjc -Date: Fri Sep 29 00:07:40 2017 +0200 +commit 99f2d14896b638fd79ec1598d6ea1b94bf2793ce +Author: Andrea Maggiulli +Date: Mon Feb 5 22:50:40 2018 +0100 - SonarQube fixes 2 + Created CONTRIBUTING.md [skip ci] - .../Finitedifferences/Utilities/FdmDirichletBoundary.cs | 12 +++--------- - 1 file changed, 3 insertions(+), 9 deletions(-) + CONTRIBUTING.md | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 124 insertions(+) -commit 4cbf6172fce0eeaa6fa00508d168be5ac8eafe08 -Author: tournierjc -Date: Fri Sep 29 00:04:19 2017 +0200 +commit 876597239a2771b3407ade5e49d3310e58f15c76 +Author: Andrea Maggiulli +Date: Mon Feb 5 22:08:43 2018 +0100 - SonarQube fixes + Created CODE_OF_CONDUCT.md - .../Volatility/equityfx/FixedLocalVolSurface.cs | 14 +++++++------- - .../Volatility/equityfx/NoExceptLocalVolSurface.cs | 4 ++-- - src/QLNet/processes/BlackScholesProcess.cs | 2 +- - 3 files changed, 10 insertions(+), 10 deletions(-) + CODE_OF_CONDUCT.md | 43 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) -commit 06e40f4056750962bc9d9dcf1100cb541015b109 -Author: tournierjc -Date: Thu Sep 28 23:59:20 2017 +0200 - - SonarQube fixes - - .../Methods/Finitedifferences/ExplicitEuler.cs | 3 -- - .../Methods/Finitedifferences/ImplicitEuler.cs | 3 -- - .../Operators/NinePointLinearOp.cs | 35 +++++++-------- - .../Operators/SecondOrderMixedDerivativeOp.cs | 52 +++++++++++++--------- - .../Finitedifferences/Schemes/CraigSneydScheme.cs | 13 +++--- - .../Finitedifferences/Schemes/DouglasScheme.cs | 8 ++-- - .../Schemes/ExplicitEulerScheme.cs | 8 ++-- - .../Finitedifferences/Schemes/HundsdorferScheme.cs | 11 +++-- - .../Schemes/ImplicitEulerScheme.cs | 12 +++-- - .../Schemes/ModifiedCraigSneydScheme.cs | 15 +++---- - src/QLNet/Methods/Finitedifferences/TRBDF2.cs | 6 +-- - .../Finitedifferences/Utilities/ListUtils.cs | 10 ++--- - 12 files changed, 87 insertions(+), 89 deletions(-) - -commit fe07c481179730ca23946caa6403556f3bd4b741 -Author: jiskin -Date: Thu Sep 28 21:33:51 2017 +0200 - - Port Fixed Local Vol and No Except Local Vol - - .../Volatility/equityfx/FixedLocalVolSurface.cs | 233 +++++++++++++++++++++ - .../Volatility/equityfx/NoExceptLocalVolSurface.cs | 68 ++++++ - src/QLNet/processes/BlackScholesProcess.cs | 29 +++ - 3 files changed, 330 insertions(+) +commit c328d3973dbc215daa823e362fae9f2723abd87f +Merge: 5bd4f20 7ad8913 +Author: Andrea Maggiulli +Date: Mon Feb 5 17:27:40 2018 +0100 -commit 0cb99dcc6e7df1b5a152a34431ca875816d12495 -Author: jiskin -Date: Tue Sep 26 20:10:15 2017 +0200 - - First port of Finite differences method from Quantlit - - src/QLNet/Cashflows/Dividend.cs | 4 +- - src/QLNet/Instruments/DividendBarrierOption.cs | 6 +- - src/QLNet/Instruments/DividendSchedule.cs | 1 + - src/QLNet/Instruments/DividendVanillaOption.cs | 5 +- - src/QLNet/Instruments/payoffs.cs | 6 + - .../Math/Interpolations/CubicInterpolation.cs | 245 +++++- - src/QLNet/Math/Matrix.cs | 5 +- - src/QLNet/Math/NumericalDifferentiation.cs | 150 ++++ - src/QLNet/Math/ODE/AdaptiveRungeKutta.cs | 229 ++++++ - src/QLNet/Math/Vector.cs | 22 + - src/QLNet/Math/integrals/DiscreteIntegrals.cs | 109 +++ - src/QLNet/Math/integrals/Integral.cs | 8 +- - src/QLNet/Math/matrixutilities/BiCGStab.cs | 128 ++++ - src/QLNet/Math/matrixutilities/GMRES.cs | 188 +++++ - src/QLNet/Math/matrixutilities/SparseMatrix.cs | 292 ++++++++ - src/QLNet/Methods/Finitedifferences/DMinus.cs | 42 ++ - src/QLNet/Methods/Finitedifferences/DPlus.cs | 42 ++ - .../Methods/Finitedifferences/ExplicitEuler.cs | 66 ++ - .../Methods/Finitedifferences/ImplicitEuler.cs | 62 ++ - .../Meshers/Concentrating1dMesher.cs | 257 +++++++ - .../Finitedifferences/Meshers/Fdm1dMesher.cs | 50 ++ - .../Meshers/FdmBlackScholesMesher.cs | 143 ++++ - .../Methods/Finitedifferences/Meshers/FdmMesher.cs | 46 ++ - .../Meshers/FdmMesherComposite.cs | 120 +++ - .../Finitedifferences/Meshers/Uniform1dMesher.cs | 52 ++ - .../Finitedifferences/Meshers/UniformGridMesher.cs | 84 +++ - .../Operators/FdmBlackScholesOp.cs | 155 ++++ - .../Finitedifferences/Operators/FdmLinearOp.cs | 46 ++ - .../Operators/FdmLinearOpComposite.cs | 50 ++ - .../Operators/FdmLinearOpIterator.cs | 108 +++ - .../Operators/FdmLinearOpLayout.cs | 134 ++++ - .../Operators/FirstDerivativeOp.cs | 75 ++ - .../Operators/NinePointLinearOp.cs | 218 ++++++ - .../Operators/SecondDerivativeOp.cs | 67 ++ - .../Operators/SecondOrderMixedDerivativeOp.cs | 126 ++++ - .../Operators/TripleBandLinearOp.cs | 312 ++++++++ - .../Methods/Finitedifferences/ParallelEvolver.cs | 2 +- - .../Schemes/BoundaryConditionSchemeHelper.cs | 58 ++ - .../Finitedifferences/Schemes/CraigSneydScheme.cs | 101 +++ - .../Finitedifferences/Schemes/DouglasScheme.cs | 91 +++ - .../Schemes/ExplicitEulerScheme.cs | 72 ++ - .../Finitedifferences/Schemes/HundsdorferScheme.cs | 102 +++ - .../Schemes/ImplicitEulerScheme.cs | 108 +++ - .../Schemes/ModifiedCraigSneydScheme.cs | 103 +++ - .../Finitedifferences/Solvers/Fdm1DimSolver.cs | 115 +++ - .../Finitedifferences/Solvers/FdmBackwardSolver.cs | 178 +++++ - .../Solvers/FdmBlackScholesSolver.cs | 83 +++ - .../Finitedifferences/Solvers/FdmSolverDesc.cs | 37 + - .../StepConditions/FdmAmericanStepCondition.cs | 57 ++ - .../StepConditions/FdmBermudanStepCondition.cs | 79 ++ - .../StepConditions/FdmSnapshotCondition.cs | 48 ++ - .../StepConditions/FdmStepConditionComposite.cs | 111 +++ - src/QLNet/Methods/Finitedifferences/TRBDF2.cs | 155 ++++ - .../Utilities/FdmBoundaryConditionSet.cs | 30 + - .../Utilities/FdmDirichletBoundary.cs | 83 +++ - .../Utilities/FdmDividendHandler.cs | 116 +++ - .../Utilities/FdmIndicesOnBoundary.cs | 66 ++ - .../Utilities/FdmInnerValueCalculator.cs | 148 ++++ - .../Utilities/FdmMesherIntegral.cs | 67 ++ - .../Finitedifferences/Utilities/ListUtils.cs | 79 ++ - .../Methods/Finitedifferences/ZeroCondition.cs | 37 + - .../Methods/Finitedifferences/cranknicolson.cs | 3 +- - .../Finitedifferences/finitedifferencemodel.cs | 5 + - src/QLNet/Methods/Finitedifferences/mixedscheme.cs | 2 +- - .../barrier/FdBlackScholesBarrierEngine.cs | 210 ++++++ - .../barrier/FdBlackScholesRebateEngine.cs | 139 ++++ - .../vanilla/FdBlackScholesVanillaEngine.cs | 105 +++ - .../Volatility/equityfx/LocalVolSurface.cs | 26 +- - .../Volatility/swaption/swaptionvolmatrix.cs | 421 ++++++----- - tests/QLNet.Tests/T_BarrierOption.cs | 48 +- - tests/QLNet.Tests/T_FdmLinearOp.cs | 827 +++++++++++++++++++++ - tests/QLNet.Tests/T_Interpolations.cs | 2 +- - 72 files changed, 7314 insertions(+), 253 deletions(-) - -commit 5ae4482e80ff32d407311840a7949692a130cdfb -Merge: 3299974 1a0822c -Author: jiskin -Date: Tue Sep 26 19:48:08 2017 +0200 - - Merge pull request #2 from amaggiulli/develop + Merge pull request #201 from amaggiulli/formatcode - merge + Formatcode -commit 1a0822c1de59823b45ddee5d5bfec85c7e185ba5 -Merge: 6d5c724 362a815 +commit 7ad891384b81ff92c1ee556bd277a6f72c8ba404 Author: Andrea Maggiulli -Date: Mon Sep 25 18:23:19 2017 +0200 - - Merge pull request #171 from jiskin/UpdateSwaptionTestCase - - Update swaption test case - -commit 362a8158347b0351c1df7ebb5b0a7ddf362bed0c -Author: jiskin -Date: Mon Sep 25 18:07:57 2017 +0200 - - Add Cash Settled Swaption test - - tests/QLNet.Tests/T_Swaption.cs | 372 +++++++++++++++++++++++++++++++++++++--- - 1 file changed, 352 insertions(+), 20 deletions(-) - -commit 6d5c7241296ecac5624d3996c816dc983867ac3c -Merge: 6b15b1b 30f4e5d +Date: Fri Feb 2 17:27:04 2018 +0100 + + Removed unnecessary semicolons. + + src/QLNet/Cashflows/CouponPricer.cs | 2 +- + src/QLNet/Cashflows/InflationCouponPricer.cs | 2 +- + src/QLNet/Cashflows/YoYInflationCoupon.cs | 2 +- + src/QLNet/Indexes/Inflation/UKRPI.cs | 2 +- + src/QLNet/Indexes/Swapindex.cs | 2 +- + src/QLNet/Indexes/swap/ChfLiborSwap.cs | 2 +- + src/QLNet/Indexes/swap/EuriborSwap.cs | 2 +- + src/QLNet/Instruments/BMASwap.cs | 2 +- + src/QLNet/Instruments/BasisSwap.cs | 2 +- + src/QLNet/Instruments/Bonds/CallableBond.cs | 2 +- + src/QLNet/Instruments/Bonds/ConvertibleBond.cs | 4 ++-- + src/QLNet/Instruments/CPISwap.cs | 2 +- + src/QLNet/Instruments/Callability.cs | 6 +++--- + src/QLNet/Instruments/CapFloor.cs | 8 ++++---- + src/QLNet/Instruments/Forward.cs | 2 +- + src/QLNet/Instruments/Loan.cs | 2 +- + src/QLNet/Instruments/MultiAssetOption.cs | 2 +- + src/QLNet/Instruments/OvernightIndexedSwap.cs | 2 +- + src/QLNet/Instruments/Swaption.cs | 2 +- + src/QLNet/Instruments/VanillaSwap.cs | 2 +- + src/QLNet/Instruments/YearOnYearInflationSwap.cs | 4 ++-- + src/QLNet/Instruments/ZeroCouponInflationSwap.cs | 4 ++-- + src/QLNet/Math/Interpolations/ConvexMonotoneInterpolation.cs | 2 +- + src/QLNet/Math/Interpolations/KernelInterpolation.cs | 2 +- + src/QLNet/Math/Interpolations/Linearinterpolation.cs | 4 ++-- + src/QLNet/Math/Interpolations/Loginterpolation.cs | 2 +- + src/QLNet/Math/LinearLeastSquaresRegression.cs | 2 +- + src/QLNet/Math/NumericalDifferentiation.cs | 2 +- + src/QLNet/Math/Optimization/Constraint.cs | 2 +- + src/QLNet/Math/TransformedGrid.cs | 2 +- + src/QLNet/Math/matrixutilities/TqrEigenDecomposition.cs | 2 +- + src/QLNet/Math/randomnumbers/SobolRsg.cs | 2 +- + src/QLNet/Methods/Finitedifferences/BoundaryCondition.cs | 2 +- + src/QLNet/Methods/lattices/BinominalTree.cs | 2 +- + src/QLNet/Methods/lattices/Lattice2D.cs | 2 +- + src/QLNet/Methods/lattices/TrinomialTree.cs | 2 +- + src/QLNet/Methods/montecarlo/LsmBasisSystem.cs | 2 +- + .../MarketModels/BrownianGenerators/SobolBrownianGenerator.cs | 2 +- + src/QLNet/Pricingengines/credit/IsdaCdsEngine.cs | 2 +- + src/QLNet/Pricingengines/inflation/InflationCapFloorEngines.cs | 2 +- + src/QLNet/Pricingengines/swaption/BlackSwaptionEngine.cs | 2 +- + src/QLNet/Pricingengines/vanilla/AnalyticHestonEngine.cs | 2 +- + src/QLNet/Pricingengines/vanilla/HestonExpansionEngine.cs | 2 +- + src/QLNet/Pricingengines/vanilla/MCEuropeanHestonEngine.cs | 2 +- + .../Termstructures/Volatility/Optionlet/OptionletStripper.cs | 2 +- + src/QLNet/Termstructures/Volatility/Sabr.cs | 2 +- + src/QLNet/Termstructures/Volatility/swaption/SwaptionVolCube1.cs | 2 +- + src/QLNet/Time/ASX.cs | 2 +- + src/QLNet/Time/Calendars/Argentina.cs | 4 ++-- + src/QLNet/Time/Calendars/Australia.cs | 4 ++-- + src/QLNet/Time/Calendars/Canada.cs | 2 +- + src/QLNet/Time/Calendars/China.cs | 4 ++-- + src/QLNet/Time/Calendars/Germany.cs | 6 +++--- + src/QLNet/Time/Calendars/Indonesia.cs | 2 +- + src/QLNet/Time/Calendars/Italy.cs | 6 +++--- + src/QLNet/Time/Calendars/Japan.cs | 4 ++-- + src/QLNet/Time/Calendars/JointCalendar.cs | 2 +- + src/QLNet/Time/Calendars/Switzerland.cs | 4 ++-- + src/QLNet/Time/Calendars/Taiwan.cs | 4 ++-- + src/QLNet/Time/Calendars/Turkey.cs | 2 +- + src/QLNet/Time/Calendars/Ukraine.cs | 4 ++-- + src/QLNet/Time/Calendars/UnitedStates.cs | 2 +- + src/QLNet/Time/DayCounters/Actual360.cs | 2 +- + src/QLNet/Time/DayCounters/ActualActual.cs | 8 ++++---- + src/QLNet/Time/DayCounters/Thirty360.cs | 8 ++++---- + src/QLNet/Time/ECB.cs | 2 +- + src/QLNet/processes/HybridHestonHullWhiteProcess.cs | 2 +- + tests/QLNet.Tests/T_BasketOption.cs | 4 ++-- + tests/QLNet.Tests/T_EuropeanOption.cs | 2 +- + tests/QLNet.Tests/T_Inflation.cs | 2 +- + tests/QLNet.Tests/T_InterestRate.cs | 2 +- + tests/QLNet.Tests/T_LowDiscrepancySequences.cs | 6 +++--- + tests/QLNet.Tests/T_OvernightIndexedSwap.cs | 6 +++--- + tests/QLNet.Tests/T_Piecewiseyieldcurve.cs | 4 ++-- + tests/QLNet.Tests/T_Solvers.cs | 2 +- + tests/QLNet.Tests/Utilities.cs | 4 ++-- + 76 files changed, 109 insertions(+), 109 deletions(-) + +commit 56e31900bbcbed88038fdc8f81b6f542df81ca52 Author: Andrea Maggiulli -Date: Wed Sep 13 14:39:43 2017 +0200 - - Merge branch 'develop' of https://github.com/amaggiulli/qlnet into develop - -commit 6b15b1be205012b477cb6988db54fa47871dfd72 +Date: Fri Feb 2 14:11:48 2018 +0100 + + Initial tests refactoring + + tests/QLNet.Tests.Old/AssemblyInfo.cs | 16 +- + tests/QLNet.Tests/T_AmericanOption.cs | 1026 ++--- + tests/QLNet.Tests/T_AsianOptions.cs | 610 +-- + tests/QLNet.Tests/T_AssetSwap.cs | 4164 ++++++++++---------- + tests/QLNet.Tests/T_BarrierOption.cs | 992 ++--- + tests/QLNet.Tests/T_BasketOption.cs | 272 +- + tests/QLNet.Tests/T_Bermudanswaption.cs | 438 +- + tests/QLNet.Tests/T_BinaryOption.cs | 233 +- + tests/QLNet.Tests/T_BlackDeltaCalculator.cs | 624 +-- + tests/QLNet.Tests/T_BlackFormula.cs | 133 +- + tests/QLNet.Tests/T_Bonds.cs | 702 ++-- + tests/QLNet.Tests/T_BusinessDayConvention.cs | 170 +- + tests/QLNet.Tests/T_CPISwap.cs | 350 +- + tests/QLNet.Tests/T_Calendars.cs | 2443 ++++++------ + tests/QLNet.Tests/T_CapFloor.cs | 992 ++--- + tests/QLNet.Tests/T_CapFlooredCoupon.cs | 420 +- + tests/QLNet.Tests/T_CashFlows.cs | 70 +- + tests/QLNet.Tests/T_CliquetOption.cs | 194 +- + tests/QLNet.Tests/T_Cms.cs | 354 +- + tests/QLNet.Tests/T_CreditDefaultSwap.cs | 174 +- + tests/QLNet.Tests/T_Dates.cs | 229 +- + tests/QLNet.Tests/T_DayCounters.cs | 341 +- + tests/QLNet.Tests/T_DefaultProbabilityCurves.cs | 44 +- + tests/QLNet.Tests/T_DigitalCoupon.cs | 900 ++--- + tests/QLNet.Tests/T_DigitalOption.cs | 405 +- + tests/QLNet.Tests/T_DividendOption.cs | 100 +- + tests/QLNet.Tests/T_DoubleBarrierOption.cs | 526 +-- + tests/QLNet.Tests/T_DoubleBinaryOption.cs | 341 +- + tests/QLNet.Tests/T_EuropeanOption.cs | 94 +- + tests/QLNet.Tests/T_ExchangeRate.cs | 162 +- + tests/QLNet.Tests/T_FdmLinearOp.cs | 1605 ++++---- + tests/QLNet.Tests/T_ForwardOption.cs | 283 +- + tests/QLNet.Tests/T_Functions.cs | 270 +- + tests/QLNet.Tests/T_HestonModel.cs | 863 ++-- + .../QLNet.Tests/T_HybridHestonHullWhiteProcess.cs | 372 +- + tests/QLNet.Tests/T_Inflation.cs | 613 +-- + tests/QLNet.Tests/T_InflationCPICapFloor.cs | 304 +- + tests/QLNet.Tests/T_InflationCapFloorTest.cs | 964 ++--- + .../QLNet.Tests/T_InflationCapFlooredCouponTest.cs | 798 ++-- + tests/QLNet.Tests/T_Instruments.cs | 14 +- + tests/QLNet.Tests/T_InterestRate.cs | 99 +- + tests/QLNet.Tests/T_Interpolations.cs | 2013 +++++----- + tests/QLNet.Tests/T_LiborMarketModel.cs | 869 ++-- + tests/QLNet.Tests/T_LiborMarketModelProcess.cs | 670 ++-- + .../QLNet.Tests/T_LinearLeastSquaresRegression.cs | 422 +- + tests/QLNet.Tests/T_LookbackOption.cs | 327 +- + tests/QLNet.Tests/T_LowDiscrepancySequences.cs | 500 +-- + tests/QLNet.Tests/T_Matrices.cs | 616 +-- + tests/QLNet.Tests/T_Mclongstaffschwartzengine.cs | 124 +- + tests/QLNet.Tests/T_Money.cs | 34 +- + tests/QLNet.Tests/T_Operators.cs | 74 +- + tests/QLNet.Tests/T_Optimizers.cs | 952 ++--- + tests/QLNet.Tests/T_OptionletStripper.cs | 296 +- + tests/QLNet.Tests/T_OvernightIndexedSwap.cs | 345 +- + tests/QLNet.Tests/T_PSACurve.cs | 37 +- + tests/QLNet.Tests/T_PathGenerator.cs | 584 +-- + .../T_PiecewiseZeroSpreadedTermStructure.cs | 188 +- + tests/QLNet.Tests/T_Piecewiseyieldcurve.cs | 1631 ++++---- + tests/QLNet.Tests/T_Quotes.cs | 75 +- + tests/QLNet.Tests/T_RNGTraits.cs | 36 +- + tests/QLNet.Tests/T_RiskStats.cs | 502 +-- + tests/QLNet.Tests/T_Rounding.cs | 75 +- + tests/QLNet.Tests/T_SVI.cs | 209 +- + tests/QLNet.Tests/T_SampledCurve.cs | 20 +- + tests/QLNet.Tests/T_Schedule.cs | 198 +- + tests/QLNet.Tests/T_ShortRateModels.cs | 428 +- + tests/QLNet.Tests/T_Solvers.cs | 46 +- + tests/QLNet.Tests/T_Stats.cs | 208 +- + tests/QLNet.Tests/T_Swaps.cs | 178 +- + tests/QLNet.Tests/T_Swaption.cs | 1693 ++++---- + tests/QLNet.Tests/T_SwaptionVolatilityCube.cs | 290 +- + tests/QLNet.Tests/T_SwaptionVolatilitymatrix.cs | 829 ++-- + tests/QLNet.Tests/T_TermStructures.cs | 225 +- + tests/QLNet.Tests/T_Vector.cs | 56 +- + tests/QLNet.Tests/Utilities.cs | 562 +-- + 75 files changed, 19890 insertions(+), 19126 deletions(-) + +commit 59e2bf145c064afb13eb94b1447fddd3bbf9d96f Author: Andrea Maggiulli -Date: Wed Sep 13 14:39:19 2017 +0200 +Date: Fri Feb 2 14:11:21 2018 +0100 - Fixed a bug in DiscretizedCallableFixedRateBond. + Added test to code format. - src/QLNet/Instruments/Bonds/DiscretizedCallableFixedRateBond.cs | 2 +- + format_code.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -commit 32999749387a283d0efb691e75c7a7a89883b629 -Merge: 4f1ddba 30f4e5d -Author: jiskin -Date: Thu Sep 7 20:31:23 2017 +0200 - - Merge pull request #1 from amaggiulli/develop - - Merge all PR - -commit 30f4e5d33e75bea8f9a8c07b520652a36befd63f -Merge: 575c5b7 fa74976 -Author: Andrea Maggiulli -Date: Fri Sep 1 10:33:34 2017 +0200 - - Merge pull request #170 from jiskin/Allow_ZeroCurve_initialize_children - - change private to protected for initialize method - -commit fa74976741167f4be258fa87817328c11d252edf -Author: jiskin -Date: Thu Aug 31 12:37:55 2017 +0200 - - set members as protected - - ...terpolatedPiecewiseZeroSpreadedTermStructure.cs | 32 +++++++++++----------- - 1 file changed, 16 insertions(+), 16 deletions(-) - -commit 4f1ddbad2550305cc86e442581222049498dc641 -Author: jiskin -Date: Thu Aug 31 12:37:19 2017 +0200 - - set members as protected - - ...terpolatedPiecewiseZeroSpreadedTermStructure.cs | 32 +++++++++++----------- - 1 file changed, 16 insertions(+), 16 deletions(-) - -commit 1063ecfc09319c59f2b69eea02680eecd4f51f7a -Author: jiskin -Date: Thu Aug 31 12:33:40 2017 +0200 - - set members as protected - - .../Termstructures/Yield/ZeroSpreadedTermStructure.cs | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - -commit 692b803c39b93e4c0dc80d826cd2f3f641f78a92 -Author: jiskin -Date: Thu Aug 31 12:25:20 2017 +0200 - - change private to protected for initialize method - - src/QLNet/Termstructures/Yield/ZeroCurve.cs | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -commit 575c5b7e4256fc3aaf128971a33ab67061c2a4ce -Author: Andrea Maggiulli -Date: Wed Aug 30 11:52:09 2017 +0200 - - Updated double extensions. - - src/QLNet/Extensions/DoubleExtension.cs | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -commit 101cbeb323f18d4e843954355eae12a95c36d2f2 +commit c0ea99c26b198c04bf51de5dad55394b9debe3e5 Author: Andrea Maggiulli -Date: Wed Aug 30 11:51:26 2017 +0200 - - Updated documentation to standard format ( can be used as sample for other classes ). - - src/QLNet/Cashflows/averagebmacoupon.cs | 75 +++++++++++++++++++++++++-------- - 1 file changed, 57 insertions(+), 18 deletions(-) - -commit 7f0d12259585144fb1208bd4780aff872ffd6c66 +Date: Fri Feb 2 12:52:02 2018 +0100 + + Uniformed file names to CamelCase standard + + src/QLNet/Cashflows/{averagebmacoupon.cs => AverageBMACoupon.cs} | 0 + src/QLNet/{discretizedasset.cs => DiscretizedAsset.cs} | 0 + src/QLNet/{grid.cs => Grid.cs} | 0 + src/QLNet/Indexes/{bmaindex.cs => BMAIndex.cs} | 0 + src/QLNet/Instruments/{bmaswap.cs => BMASwap.cs} | 0 + .../Instruments/{fixedratebondforward.cs => FixedRateBondForward.cs} | 0 + src/QLNet/Instruments/{forward.cs => Forward.cs} | 0 + .../Instruments/{forwardrateagreement.cs => ForwardRateAgreement.cs} | 0 + src/QLNet/Instruments/{payoffs.cs => Payoffs.cs} | 0 + src/QLNet/Math/{beta.cs => Beta.cs} | 0 + .../Distributions/{binomialdistribution.cs => BinomialDistribution.cs} | 0 + .../Distributions/{chisquaredistribution.cs => ChiSquareDistribution.cs} | 0 + .../Math/Distributions/{poissondistribution.cs => PoissonDistribution.cs} | 0 + src/QLNet/Math/{factorial.cs => Factorial.cs} | 0 + .../{backwardflatinterpolation.cs => BackwardFlatInterpolation.cs} | 0 + .../Interpolations/{bilinearinterpolation.cs => BilinearInterpolation.cs} | 0 + .../{convexmonotoneinterpolation.cs => ConvexMonotoneInterpolation.cs} | 0 + .../{forwardflatinterpolation.cs => ForwardFlatInterpolation.cs} | 0 + src/QLNet/Math/Interpolations/{interpolation2d.cs => Interpolation2D.cs} | 0 + .../Math/Interpolations/{multicubicspline.cs => MultiCubicSpline.cs} | 0 + .../Math/Interpolations/{sabrinterpolation.cs => SABRInterpolation.cs} | 0 + .../{linearleastsquaresregression.cs => LinearLeastSquaresRegression.cs} | 0 + .../Math/Optimization/{levenbergmarquardt.cs => LevenbergMarquardt.cs} | 0 + src/QLNet/Math/Optimization/{lmdif.cs => LmDif.cs} | 0 + src/QLNet/Math/Optimization/{method.cs => Method.cs} | 0 + src/QLNet/Math/Optimization/{problem.cs => Problem.cs} | 0 + src/QLNet/Math/{transformedgrid.cs => TransformedGrid.cs} | 0 + .../{gaussianorthogonalpolynomial.cs => GaussianOrthogonalPolynomial.cs} | 0 + src/QLNet/Math/integrals/{simpsonintegral.cs => SimpsonIntegral.cs} | 0 + src/QLNet/Math/integrals/{trapezoidintegral.cs => TrapezoidIntegral.cs} | 0 + .../{choleskydecomposition.cs => CholeskyDecomposition.cs} | 0 + src/QLNet/Math/matrixutilities/{pseudosqrt.cs => PseudoSqrt.cs} | 0 + src/QLNet/Math/matrixutilities/{qrdecomposition.cs => QRDecomposition.cs} | 0 + src/QLNet/Math/matrixutilities/{svd.cs => SVD.cs} | 0 + .../{symmetricschurdecomposition.cs => SymmetricSchurDecomposition.cs} | 0 + .../randomnumbers/{inversecumulativerng.cs => InverseCumulativeRng.cs} | 0 + .../randomnumbers/{inversecumulativersg.cs => InverseCumulativeRsg.cs} | 0 + .../Math/randomnumbers/{mt19937uniformrng.cs => MT19937UniformRng.cs} | 0 + .../randomnumbers/{primitivepolynomials.cs => PrimitivePolynomials.cs} | 0 + src/QLNet/Math/randomnumbers/{rngtraits.cs => RNGTraits.cs} | 0 + .../{randomsequencegenerator.cs => RandomSequenceGenerator.cs} | 0 + src/QLNet/Math/randomnumbers/{seedgenerator.cs => SeedGenerator.cs} | 0 + src/QLNet/Math/randomnumbers/{sobolrsg.cs => SobolRsg.cs} | 0 + src/QLNet/Math/randomnumbers/{sobolrsg2.cs => SobolRsg2.cs} | 0 + .../statistics/{convergencestatistics.cs => ConvergenceStatistics.cs} | 0 + .../Math/statistics/{gaussianstatistics.cs => GaussianStatistics.cs} | 0 + src/QLNet/Math/statistics/{generalstatistics.cs => GeneralStatistics.cs} | 0 + .../statistics/{incrementalstatistics.cs => IncrementalStatistics.cs} | 0 + src/QLNet/Math/statistics/{riskstatistics.cs => RiskStatistics.cs} | 0 + .../Math/statistics/{sequencestatistics.cs => SequenceStatistics.cs} | 0 + src/QLNet/Methods/Finitedifferences/{bsmoperator.cs => BSMOperator.cs} | 0 + .../Methods/Finitedifferences/{cranknicolson.cs => CrankNicolson.cs} | 0 + src/QLNet/Methods/Finitedifferences/{dzero.cs => DZero.cs} | 0 + .../{finitedifferencemodel.cs => FiniteDifferenceModel.cs} | 0 + src/QLNet/Methods/Finitedifferences/{mixedscheme.cs => MixedScheme.cs} | 0 + src/QLNet/Methods/Finitedifferences/{pde.cs => Pde.cs} | 0 + src/QLNet/Methods/Finitedifferences/{pdebsm.cs => PdeBsm.cs} | 0 + src/QLNet/Methods/Finitedifferences/{pdeshortrate.cs => PdeShortRate.cs} | 0 + src/QLNet/Methods/lattices/{binominaltree.cs => BinominalTree.cs} | 0 + src/QLNet/Methods/lattices/{bsmlattice.cs => BsmLattice.cs} | 0 + src/QLNet/Methods/lattices/{lattice.cs => Lattice.cs} | 0 + src/QLNet/Methods/lattices/{lattice1d.cs => Lattice1D.cs} | 0 + src/QLNet/Methods/lattices/{lattice2d.cs => Lattice2D.cs} | 0 + src/QLNet/Methods/lattices/{tree.cs => Tree.cs} | 0 + src/QLNet/Methods/lattices/{trinomialtree.cs => TrinomialTree.cs} | 0 + src/QLNet/Methods/montecarlo/{brownianbridge.cs => BrownianBridge.cs} | 0 + .../montecarlo/{earlyexercisepathpricer.cs => EarlyExercisePathPricer.cs} | 0 + .../{longstaffschwartzpathpricer.cs => LongstaffSchwartzPathPricer.cs} | 0 + src/QLNet/Methods/montecarlo/{lsmbasissystem.cs => LsmBasisSystem.cs} | 0 + src/QLNet/Methods/montecarlo/{mctraits.cs => MCTraits.cs} | 0 + src/QLNet/Methods/montecarlo/{montecarlomodel.cs => MontecarloModel.cs} | 0 + src/QLNet/Methods/montecarlo/{multipath.cs => MultiPath.cs} | 0 + .../Methods/montecarlo/{multipathgenerator.cs => MultiPathGenerator.cs} | 0 + src/QLNet/Methods/montecarlo/{path.cs => Path.cs} | 0 + src/QLNet/Methods/montecarlo/{pathgenerator.cs => PathGenerator.cs} | 0 + src/QLNet/Methods/montecarlo/{pathpricer.cs => PathPricer.cs} | 0 + src/QLNet/Methods/montecarlo/{sample.cs => Sample.cs} | 0 + src/QLNet/Models/{model.cs => Model.cs} | 0 + .../Shortrate/Onefactormodels/{blackkarasinski.cs => BlackKarasinski.cs} | 0 + .../Onefactormodels/{coxingersollross.cs => CoxIngersollRoss.cs} | 0 + src/QLNet/Models/Shortrate/Onefactormodels/{hullwhite.cs => HullWhite.cs} | 0 + src/QLNet/Models/Shortrate/Onefactormodels/{vasicek.cs => Vasicek.cs} | 0 + src/QLNet/Models/Shortrate/{twofactormodel.cs => TwoFactorModel.cs} | 0 + src/QLNet/Models/Shortrate/Twofactorsmodels/{g2.cs => G2.cs} | 0 + .../Models/Shortrate/calibrationhelpers/{caphelper.cs => CapHelper.cs} | 0 + .../Shortrate/calibrationhelpers/{swaptionhelper.cs => SwaptionHelper.cs} | 0 + src/QLNet/{numericalmethod.cs => NumericalMethod.cs} | 0 + src/QLNet/Patterns/{observablevalue.cs => ObservableValue.cs} | 0 + src/QLNet/{payoff.cs => Payoff.cs} | 0 + src/QLNet/Pricingengines/{blackformula.cs => BlackFormula.cs} | 0 + .../CapFloor/{analyticcapfloorengine.cs => AnalyticCapFloorEngine.cs} | 0 + .../CapFloor/{discretizedcapfloor.cs => DiscretizedCapFloor.cs} | 0 + src/QLNet/Pricingengines/{genericmodelengine.cs => GenericModelEngine.cs} | 0 + .../{latticeshortratemodelengine.cs => LatticeShortRateModelEngine.cs} | 0 + .../{mclongstaffschwartzengine.cs => MCLongstaffSchwartzEngine.cs} | 0 + src/QLNet/Pricingengines/{mcsimulation.cs => McSimulation.cs} | 0 + src/QLNet/Pricingengines/Swap/{discretizedswap.cs => DiscretizedSwap.cs} | 0 + src/QLNet/Pricingengines/Swap/{treeswapengine.cs => TreeSwapEngine.cs} | 0 + .../asian/{mcdiscreteasianengine.cs => McDiscreteAsianEngine.cs} | 0 + .../asian/{mc_discr_arith_av_price.cs => Mc_Discr_Arith_Av_Price.cs} | 0 + .../asian/{mc_discr_arith_av_strike.cs => Mc_Discr_Arith_Av_Strike.cs} | 0 + .../asian/{mc_discr_geom_av_price.cs => Mc_Discr_Geom_Av_Price.cs} | 0 + .../swaption/{blackswaptionengine.cs => BlackSwaptionEngine.cs} | 0 + .../swaption/{discretizedswaption.cs => DiscretizedSwaption.cs} | 0 + .../Pricingengines/swaption/{g2swaptionengine.cs => G2SwaptionEngine.cs} | 0 + .../swaption/{jamshidianswaptionengine.cs => JamshidianSwaptionEngine.cs} | 0 + .../swaption/{treeswaptionengine.cs => TreeSwaptionEngine.cs} | 0 + .../vanilla/{baroneadesiwhaleyengine.cs => BaroneAdesiWhaleyEngine.cs} | 0 + src/QLNet/Pricingengines/vanilla/{binomialengine.cs => BinomialEngine.cs} | 0 + .../vanilla/{bjerksundstenslandengine.cs => BjerksundStenslandEngine.cs} | 0 + .../vanilla/{discretizedvanillaoption.cs => DiscretizedVanillaOption.cs} | 0 + .../Pricingengines/vanilla/{mcamericanengine.cs => McAmericanEngine.cs} | 0 + .../Pricingengines/vanilla/{mceuropeanengine.cs => McEuropeanEngine.cs} | 0 + .../Pricingengines/vanilla/{mcvanillaengine.cs => McVanillaEngine.cs} | 0 + src/QLNet/Termstructures/{interpolatedcurve.cs => InterpolatedCurve.cs} | 0 + src/QLNet/Termstructures/{localbootstrap.cs => LocalBootstrap.cs} | 0 + src/QLNet/Termstructures/{voltermstructure.cs => VolTermStructure.cs} | 0 + ...volatilitystructure.cs => YoYInflationOptionletVolatilityStructure.cs} | 0 + .../Optionlet/{capletvariancecurve.cs => CapletVarianceCurve.cs} | 0 + .../swaption/{swaptionconstantvol.cs => SwaptionConstantVol.cs} | 0 + .../swaption/{swaptionvoldiscrete.cs => SwaptionVolDiscrete.cs} | 0 + .../Volatility/swaption/{swaptionvolmatrix.cs => SwaptionVolMatrix.cs} | 0 + src/QLNet/Time/Calendars/{argentina.cs => Argentina.cs} | 0 + src/QLNet/Time/Calendars/{australia.cs => Australia.cs} | 0 + src/QLNet/Time/Calendars/{bespokecalendar.cs => BespokeCalendar.cs} | 0 + src/QLNet/Time/Calendars/{botswana.cs => Botswana.cs} | 0 + src/QLNet/Time/Calendars/{brazil.cs => Brazil.cs} | 0 + src/QLNet/Time/Calendars/{canada.cs => Canada.cs} | 0 + src/QLNet/Time/Calendars/{china.cs => China.cs} | 0 + src/QLNet/Time/Calendars/{czechrepublic.cs => CzechRepublic.cs} | 0 + src/QLNet/Time/Calendars/{denmark.cs => Denmark.cs} | 0 + src/QLNet/Time/Calendars/{finland.cs => Finland.cs} | 0 + src/QLNet/Time/Calendars/{germany.cs => Germany.cs} | 0 + src/QLNet/Time/Calendars/{hongkong.cs => HongKong.cs} | 0 + src/QLNet/Time/Calendars/{hungary.cs => Hungary.cs} | 0 + src/QLNet/Time/Calendars/{iceland.cs => Iceland.cs} | 0 + src/QLNet/Time/Calendars/{india.cs => India.cs} | 0 + src/QLNet/Time/Calendars/{indonesia.cs => Indonesia.cs} | 0 + src/QLNet/Time/Calendars/{italy.cs => Italy.cs} | 0 + src/QLNet/Time/Calendars/{japan.cs => Japan.cs} | 0 + src/QLNet/Time/Calendars/{mexico.cs => Mexico.cs} | 0 + src/QLNet/Time/Calendars/{newzealand.cs => NewZealand.cs} | 0 + src/QLNet/Time/Calendars/{norway.cs => Norway.cs} | 0 + src/QLNet/Time/Calendars/{nullcalendar.cs => NullCalendar.cs} | 0 + src/QLNet/Time/Calendars/{poland.cs => Poland.cs} | 0 + src/QLNet/Time/Calendars/{russia.cs => Russia.cs} | 0 + src/QLNet/Time/Calendars/{saudiarabia.cs => SaudiArabia.cs} | 0 + src/QLNet/Time/Calendars/{singapore.cs => Singapore.cs} | 0 + src/QLNet/Time/Calendars/{slovakia.cs => Slovakia.cs} | 0 + src/QLNet/Time/Calendars/{southafrica.cs => SouthAfrica.cs} | 0 + src/QLNet/Time/Calendars/{southkorea.cs => SouthKorea.cs} | 0 + src/QLNet/Time/Calendars/{sweden.cs => Sweden.cs} | 0 + src/QLNet/Time/Calendars/{switzerland.cs => Switzerland.cs} | 0 + src/QLNet/Time/Calendars/{taiwan.cs => Taiwan.cs} | 0 + src/QLNet/Time/Calendars/{turkey.cs => Turkey.cs} | 0 + src/QLNet/{timegrid.cs => TimeGrid.cs} | 0 + src/QLNet/legacy/libormarketmodels/{lfmcovarparam.cs => LfmCovarParam.cs} | 0 + .../legacy/libormarketmodels/{lfmcovarproxy.cs => LfmCovarianceProxy.cs} | 0 + .../libormarketmodels/{lfmhullwhiteparam.cs => LfmHullWhiteParam.cs} | 0 + src/QLNet/legacy/libormarketmodels/{lfmprocess.cs => LfmProcess.cs} | 0 + .../libormarketmodels/{lfmswaptionengine.cs => LfmSwaptionEngine.cs} | 0 + .../libormarketmodels/{liborforwardmodel.cs => LiborForwardModel.cs} | 0 + .../{lmconstwrappercorrmodel.cs => LmConstWrapperCorrModel.cs} | 0 + .../{lmconstwrappervolmodel.cs => LmConstWrapperVolModel.cs} | 0 + src/QLNet/legacy/libormarketmodels/{lmcorrmodel.cs => LmCorrModel.cs} | 0 + .../legacy/libormarketmodels/{lmexpcorrmodel.cs => LmExpCorrModel.cs} | 0 + .../libormarketmodels/{lmextlinexpvolmodel.cs => LmExtLinExpVolModel.cs} | 0 + .../legacy/libormarketmodels/{lmfixedvolmodel.cs => LmFixedVolModel.cs} | 0 + .../libormarketmodels/{lmlinexpcorrmodel.cs => LmLinExpCorrModel.cs} | 0 + .../legacy/libormarketmodels/{lmlinexpvolmodel.cs => LmLinExpVolModel.cs} | 0 + src/QLNet/legacy/libormarketmodels/{lmvolmodel.cs => LmVolModel.cs} | 0 + .../processes/{stochasticprocessarray.cs => StochasticProcessArray.cs} | 0 + 172 files changed, 0 insertions(+), 0 deletions(-) + +commit 0af035b918146b415c9b1328d7d107fd1bb538c8 Author: Andrea Maggiulli -Date: Wed Aug 30 11:50:04 2017 +0200 - - Fixed sonar code smells - - .../Pricingengines/swaption/blackswaptionengine.cs | 534 +++++++++++---------- - src/QLNet/Termstructures/Volatility/Sabr.cs | 23 +- - 2 files changed, 290 insertions(+), 267 deletions(-) - -commit eaafa76d66293e738ed77fe7199fc0b25db953da +Date: Fri Feb 2 11:36:12 2018 +0100 + + Initial code refactoring + + src/BermudanSwaption/BermudanSwaption.cs | 539 +- + src/Bonds/Bonds.cs | 999 +- + src/CVAIRS/CVAIRS.cs | 142 +- + src/CallableBonds/CallableBonds.cs | 114 +- + src/EquityOption/EquityOption.cs | 509 +- + src/FRA/FRA.cs | 345 +- + src/FittedBondCurve/FittedBondCurve.cs | 419 +- + src/QLNet.Old/AssemblyInfo.cs | 14 +- + src/QLNet/CashflowBase.cs | 52 +- + src/QLNet/Cashflows/CPICoupon.cs | 198 +- + src/QLNet/Cashflows/CPICouponPricer.cs | 59 +- + src/QLNet/Cashflows/CappedFlooredCoupon.cs | 76 +- + .../Cashflows/CappedFlooredYoYInflationCoupon.cs | 120 +- + src/QLNet/Cashflows/CashFlows.cs | 539 +- + src/QLNet/Cashflows/Cashflowvectors.cs | 178 +- + src/QLNet/Cashflows/CmsCoupon.cs | 122 +- + src/QLNet/Cashflows/CmsSpreadCoupon.cs | 82 +- + src/QLNet/Cashflows/ConundrumPricer.cs | 1848 +- + src/QLNet/Cashflows/Coupon.cs | 64 +- + src/QLNet/Cashflows/CouponPricer.cs | 232 +- + src/QLNet/Cashflows/DigitalCmsCoupon.cs | 26 +- + src/QLNet/Cashflows/DigitalCoupon.cs | 49 +- + src/QLNet/Cashflows/DigitalIborCoupon.cs | 28 +- + src/QLNet/Cashflows/Dividend.cs | 12 +- + src/QLNet/Cashflows/FixedRateCoupon.cs | 230 +- + src/QLNet/Cashflows/FloatingRateCoupon.cs | 47 +- + src/QLNet/Cashflows/Iborcoupon.cs | 82 +- + src/QLNet/Cashflows/IndexedCashFlow.cs | 24 +- + src/QLNet/Cashflows/InflationCoupon.cs | 117 +- + src/QLNet/Cashflows/InflationCouponPricer.cs | 99 +- + src/QLNet/Cashflows/LinearTsrPricer.cs | 228 +- + src/QLNet/Cashflows/OvernightIndexedCoupon.cs | 234 +- + src/QLNet/Cashflows/Principal.cs | 34 +- + src/QLNet/Cashflows/PrincipalLegBase.cs | 12 +- + src/QLNet/Cashflows/RangeAccrual.cs | 402 +- + src/QLNet/Cashflows/RateLegBase.cs | 48 +- + src/QLNet/Cashflows/Replication.cs | 47 +- + src/QLNet/Cashflows/SimpleCashFlow.cs | 58 +- + src/QLNet/Cashflows/YoYInflationCoupon.cs | 40 +- + src/QLNet/Cashflows/averagebmacoupon.cs | 124 +- + src/QLNet/Currencies/Africa.cs | 26 +- + src/QLNet/Currencies/America.cs | 270 +- + src/QLNet/Currencies/Asia.cs | 92 +- + src/QLNet/Currencies/Currency.cs | 143 +- + src/QLNet/Currencies/Europe.cs | 692 +- + src/QLNet/Currencies/ExchangeRate.cs | 117 +- + src/QLNet/Currencies/ExchangeRateManager.cs | 80 +- + src/QLNet/Currencies/Oceania.cs | 35 +- + src/QLNet/Event.cs | 28 +- + src/QLNet/Exercise.cs | 8 +- + src/QLNet/Extensions/DoubleExtension.cs | 36 +- + src/QLNet/Extensions/ListExtension.cs | 18 +- + src/QLNet/Handle.cs | 24 +- + src/QLNet/Index.cs | 101 +- + src/QLNet/Indexes/IBORIndex.cs | 100 +- + src/QLNet/Indexes/Ibor/Aonia.cs | 14 +- + src/QLNet/Indexes/Ibor/Audlibor.cs | 16 +- + src/QLNet/Indexes/Ibor/Bbsw.cs | 50 +- + src/QLNet/Indexes/Ibor/Bkbm.cs | 50 +- + src/QLNet/Indexes/Ibor/Cadlibor.cs | 22 +- + src/QLNet/Indexes/Ibor/Cdor.cs | 37 +- + src/QLNet/Indexes/Ibor/Chflibor.cs | 20 +- + src/QLNet/Indexes/Ibor/Dkklibor.cs | 16 +- + src/QLNet/Indexes/Ibor/Eonia.cs | 10 +- + src/QLNet/Indexes/Ibor/Euribor.cs | 272 +- + src/QLNet/Indexes/Ibor/Eurlibor.cs | 158 +- + src/QLNet/Indexes/Ibor/FedFunds.cs | 12 +- + src/QLNet/Indexes/Ibor/Gbplibor.cs | 26 +- + src/QLNet/Indexes/Ibor/Jibar.cs | 37 +- + src/QLNet/Indexes/Ibor/Jpylibor.cs | 22 +- + src/QLNet/Indexes/Ibor/Libor.cs | 88 +- + src/QLNet/Indexes/Ibor/Nzdlibor.cs | 16 +- + src/QLNet/Indexes/Ibor/Nzocr.cs | 16 +- + src/QLNet/Indexes/Ibor/Seklibor.cs | 18 +- + src/QLNet/Indexes/Ibor/Shibor.cs | 43 +- + src/QLNet/Indexes/Ibor/Sonia.cs | 10 +- + src/QLNet/Indexes/Ibor/Tibor.cs | 37 +- + src/QLNet/Indexes/Ibor/Trylibor.cs | 16 +- + src/QLNet/Indexes/Ibor/Usdlibor.cs | 24 +- + src/QLNet/Indexes/Ibor/Zibor.cs | 37 +- + src/QLNet/Indexes/Indexmanager.cs | 20 +- + src/QLNet/Indexes/Inflation/AUCPI.cs | 74 +- + src/QLNet/Indexes/Inflation/EUHICP.cs | 50 +- + src/QLNet/Indexes/Inflation/FRHICP.cs | 72 +- + src/QLNet/Indexes/Inflation/UKRPI.cs | 36 +- + src/QLNet/Indexes/Inflation/USCPI.cs | 70 +- + src/QLNet/Indexes/Inflation/ZACPI.cs | 108 +- + src/QLNet/Indexes/InflationIndex.cs | 235 +- + src/QLNet/Indexes/InterestRateIndex.cs | 72 +- + src/QLNet/Indexes/Region.cs | 72 +- + src/QLNet/Indexes/Swapindex.cs | 246 +- + src/QLNet/Indexes/bmaindex.cs | 72 +- + src/QLNet/Indexes/swap/ChfLiborSwap.cs | 16 +- + src/QLNet/Indexes/swap/EurLiborSwap.cs | 76 +- + src/QLNet/Indexes/swap/EuriborSwap.cs | 74 +- + src/QLNet/Indexes/swap/GbpLiborSwap.cs | 12 +- + src/QLNet/Indexes/swap/JpyLiborSwap.cs | 6 +- + src/QLNet/Indexes/swap/SwapSpreadIndex.cs | 98 +- + src/QLNet/Indexes/swap/UsdLiborSwap.cs | 8 +- + src/QLNet/Instruments/AsianOption.cs | 217 +- + src/QLNet/Instruments/AssetSwap.cs | 130 +- + src/QLNet/Instruments/AverageType.cs | 31 +- + src/QLNet/Instruments/BarrierOption.cs | 197 +- + src/QLNet/Instruments/BarrierType.cs | 35 +- + src/QLNet/Instruments/BasisSwap.cs | 73 +- + src/QLNet/Instruments/BasketOption.cs | 10 +- + src/QLNet/Instruments/Bond.cs | 106 +- + src/QLNet/Instruments/Bonds/AmortizingBond.cs | 76 +- + .../Instruments/Bonds/AmortizingCmsRateBond.cs | 74 +- + .../Instruments/Bonds/AmortizingFixedRateBond.cs | 238 +- + .../Bonds/AmortizingFloatingRateBond.cs | 40 +- + src/QLNet/Instruments/Bonds/BTP.cs | 252 +- + src/QLNet/Instruments/Bonds/BondFactory.cs | 74 +- + src/QLNet/Instruments/Bonds/CPIBond.cs | 146 +- + src/QLNet/Instruments/Bonds/CallableBond.cs | 159 +- + src/QLNet/Instruments/Bonds/CmsRateBond.cs | 96 +- + src/QLNet/Instruments/Bonds/ConstantCPR.cs | 10 +- + src/QLNet/Instruments/Bonds/ConvertibleBond.cs | 184 +- + .../Bonds/DiscretizedCallableFixedRateBond.cs | 30 +- + src/QLNet/Instruments/Bonds/Fixedratebond.cs | 130 +- + src/QLNet/Instruments/Bonds/FloatingRateBond.cs | 227 +- + src/QLNet/Instruments/Bonds/IPrepayModel.cs | 10 +- + src/QLNet/Instruments/Bonds/MBSFixedRateBond.cs | 66 +- + src/QLNet/Instruments/Bonds/PSACurve.cs | 12 +- + src/QLNet/Instruments/Bonds/Zerocouponbond.cs | 21 +- + src/QLNet/Instruments/CPICapFloor.cs | 64 +- + src/QLNet/Instruments/CPISwap.cs | 116 +- + src/QLNet/Instruments/Callability.cs | 50 +- + src/QLNet/Instruments/CapFloor.cs | 244 +- + src/QLNet/Instruments/Claim.cs | 10 +- + src/QLNet/Instruments/CliquetOption.cs | 42 +- + src/QLNet/Instruments/CompositeInstrument.cs | 26 +- + src/QLNet/Instruments/CreditDefaultSwap.cs | 672 +- + src/QLNet/Instruments/DividendBarrierOption.cs | 48 +- + src/QLNet/Instruments/DividendSchedule.cs | 10 +- + src/QLNet/Instruments/DividendVanillaOption.cs | 172 +- + src/QLNet/Instruments/DoubleBarrierOption.cs | 58 +- + src/QLNet/Instruments/EuropeanOption.cs | 22 +- + src/QLNet/Instruments/FloatFloatSwap.cs | 396 +- + src/QLNet/Instruments/ForwardVanillaOption.cs | 38 +- + src/QLNet/Instruments/Futures.cs | 8 +- + src/QLNet/Instruments/ImpliedVolatility.cs | 107 +- + src/QLNet/Instruments/InflationCapFloor.cs | 448 +- + src/QLNet/Instruments/Instrument.cs | 274 +- + src/QLNet/Instruments/Loan.cs | 137 +- + src/QLNet/Instruments/LookbackOption.cs | 106 +- + src/QLNet/Instruments/MakeBasisSwap.cs | 30 +- + src/QLNet/Instruments/MakeCDS.cs | 18 +- + src/QLNet/Instruments/MakeCapFloor.cs | 112 +- + src/QLNet/Instruments/MakeCms.cs | 324 +- + src/QLNet/Instruments/MakeLoans.cs | 36 +- + src/QLNet/Instruments/MakeOIS.cs | 122 +- + src/QLNet/Instruments/Makeswaption.cs | 28 +- + src/QLNet/Instruments/Makevanillaswap.cs | 604 +- + src/QLNet/Instruments/MultiAssetOption.cs | 8 +- + src/QLNet/Instruments/OneAssetOption.cs | 30 +- + src/QLNet/Instruments/OvernightIndexedSwap.cs | 162 +- + src/QLNet/Instruments/Stock.cs | 40 +- + src/QLNet/Instruments/Swap.cs | 165 +- + src/QLNet/Instruments/Swaption.cs | 31 +- + src/QLNet/Instruments/VanillaOption.cs | 40 +- + src/QLNet/Instruments/VanillaSwap.cs | 58 +- + src/QLNet/Instruments/YearOnYearInflationSwap.cs | 415 +- + src/QLNet/Instruments/ZeroCouponInflationSwap.cs | 106 +- + src/QLNet/Instruments/bmaswap.cs | 231 +- + src/QLNet/Instruments/fixedratebondforward.cs | 20 +- + src/QLNet/Instruments/forward.cs | 303 +- + src/QLNet/Instruments/forwardrateagreement.cs | 18 +- + src/QLNet/Instruments/payoffs.cs | 479 +- + src/QLNet/InterestRate.cs | 106 +- + src/QLNet/Math/AbcdMathFunction.cs | 78 +- + src/QLNet/Math/BSpline.cs | 42 +- + src/QLNet/Math/BernsteinPolynomial.cs | 12 +- + src/QLNet/Math/Comparison.cs | 77 +- + .../Distributions/BivariateNormalDistribution.cs | 249 +- + src/QLNet/Math/Distributions/GammaDistribution.cs | 23 +- + src/QLNet/Math/Distributions/NormalDistribution.cs | 1050 +- + .../Math/Distributions/binomialdistribution.cs | 20 +- + .../Math/Distributions/chisquaredistribution.cs | 12 +- + .../Math/Distributions/poissondistribution.cs | 12 +- + src/QLNet/Math/Interpolation.cs | 90 +- + src/QLNet/Math/Interpolations/Abcdinterpolation.cs | 140 +- + .../BackwardflatLinearInterpolation.cs | 52 +- + .../Interpolations/BicubicSplineInterpolation.cs | 130 +- + .../Math/Interpolations/CubicInterpolation.cs | 524 +- + src/QLNet/Math/Interpolations/Extrapolator.cs | 30 +- + .../Math/Interpolations/FlatExtrapolator2D.cs | 32 +- + .../Math/Interpolations/KernelInterpolation.cs | 85 +- + .../Math/Interpolations/KernelInterpolation2D.cs | 122 +- + .../Math/Interpolations/Linearinterpolation.cs | 118 +- + src/QLNet/Math/Interpolations/Loginterpolation.cs | 48 +- + .../Math/Interpolations/MixedInterpolation.cs | 186 +- + src/QLNet/Math/Interpolations/SviInterpolation.cs | 418 +- + .../Math/Interpolations/VannaVolgaInterpolation.cs | 78 +- + src/QLNet/Math/Interpolations/XABRInterpolation.cs | 69 +- + .../Interpolations/backwardflatinterpolation.cs | 111 +- + .../Math/Interpolations/bilinearinterpolation.cs | 18 +- + .../Interpolations/convexmonotoneinterpolation.cs | 1507 +- + .../Interpolations/forwardflatinterpolation.cs | 105 +- + src/QLNet/Math/Interpolations/interpolation2d.cs | 267 +- + src/QLNet/Math/Interpolations/multicubicspline.cs | 17 +- + src/QLNet/Math/Interpolations/sabrinterpolation.cs | 200 +- + src/QLNet/Math/KernelFunctions.cs | 32 +- + src/QLNet/Math/Matrix.cs | 74 +- + src/QLNet/Math/ModifiedBessel.cs | 170 +- + src/QLNet/Math/NumericalDifferentiation.cs | 223 +- + src/QLNet/Math/ODE/AdaptiveRungeKutta.cs | 130 +- + src/QLNet/Math/Optimization/ArmijoLineSearch.cs | 15 +- + src/QLNet/Math/Optimization/BFGS.cs | 32 +- + src/QLNet/Math/Optimization/ConjugateGradient.cs | 14 +- + src/QLNet/Math/Optimization/Constraint.cs | 152 +- + src/QLNet/Math/Optimization/CostFunction.cs | 62 +- + .../Math/Optimization/DifferentialEvolution.cs | 94 +- + src/QLNet/Math/Optimization/EndCriteria.cs | 270 +- + src/QLNet/Math/Optimization/GoldsteinLineSearch.cs | 42 +- + src/QLNet/Math/Optimization/LeastSquareProblem.cs | 410 +- + src/QLNet/Math/Optimization/LineSearch.cs | 18 +- + .../Math/Optimization/LineSearchBasedMethod.cs | 54 +- + src/QLNet/Math/Optimization/ProjectedConstraint.cs | 50 +- + .../Math/Optimization/ProjectedCostFunction.cs | 168 +- + src/QLNet/Math/Optimization/Projection.cs | 36 +- + src/QLNet/Math/Optimization/Simplex.cs | 356 +- + src/QLNet/Math/Optimization/SimulatedAnnealing.cs | 62 +- + src/QLNet/Math/Optimization/SteepestDescent.cs | 14 +- + src/QLNet/Math/Optimization/levenbergmarquardt.cs | 107 +- + src/QLNet/Math/Optimization/lmdif.cs | 2831 +- + src/QLNet/Math/Optimization/method.cs | 12 +- + src/QLNet/Math/Optimization/problem.cs | 179 +- + src/QLNet/Math/PascalTriangle.cs | 24 +- + src/QLNet/Math/PolynomialFunction.cs | 38 +- + src/QLNet/Math/PrimeNumbers.cs | 100 +- + src/QLNet/Math/RichardsonExtrapolation.cs | 52 +- + src/QLNet/Math/Rounding.cs | 399 +- + src/QLNet/Math/SampledCurve.cs | 26 +- + src/QLNet/Math/Solver1d.cs | 44 +- + src/QLNet/Math/Solvers1d/Bisection.cs | 82 +- + src/QLNet/Math/Solvers1d/Brent.cs | 168 +- + src/QLNet/Math/Solvers1d/FalsePosition.cs | 107 +- + .../Math/Solvers1d/FiniteDifferenceNewtonSafe.cs | 111 +- + src/QLNet/Math/Solvers1d/Newton.cs | 81 +- + src/QLNet/Math/Solvers1d/Newtonsafe.cs | 132 +- + src/QLNet/Math/Solvers1d/Ridder.cs | 137 +- + src/QLNet/Math/Solvers1d/Secant.cs | 93 +- + src/QLNet/Math/Vector.cs | 38 +- + src/QLNet/Math/beta.cs | 162 +- + src/QLNet/Math/factorial.cs | 97 +- + src/QLNet/Math/integrals/DiscreteIntegrals.cs | 173 +- + src/QLNet/Math/integrals/GaussLobattoIntegral.cs | 170 +- + src/QLNet/Math/integrals/GaussianQuadratures.cs | 279 +- + src/QLNet/Math/integrals/Integral.cs | 10 +- + src/QLNet/Math/integrals/Kronrodintegral.cs | 531 +- + src/QLNet/Math/integrals/Segmentintegral.cs | 90 +- + .../Math/integrals/gaussianorthogonalpolynomial.cs | 342 +- + src/QLNet/Math/integrals/simpsonintegral.cs | 77 +- + src/QLNet/Math/integrals/trapezoidintegral.cs | 156 +- + src/QLNet/Math/linearleastsquaresregression.cs | 248 +- + src/QLNet/Math/matrixutilities/BiCGStab.cs | 10 +- + src/QLNet/Math/matrixutilities/GMRES.cs | 38 +- + src/QLNet/Math/matrixutilities/SparseMatrix.cs | 490 +- + .../Math/matrixutilities/TqrEigenDecomposition.cs | 244 +- + .../Math/matrixutilities/choleskydecomposition.cs | 85 +- + src/QLNet/Math/matrixutilities/pseudosqrt.cs | 997 +- + src/QLNet/Math/matrixutilities/qrdecomposition.cs | 272 +- + src/QLNet/Math/matrixutilities/svd.cs | 997 +- + .../matrixutilities/symmetricschurdecomposition.cs | 314 +- + src/QLNet/Math/randomnumbers/Haltonrsg.cs | 10 +- + .../Math/randomnumbers/SobolBrownianBridgeRsg.cs | 22 +- + .../Math/randomnumbers/inversecumulativerng.cs | 10 +- + .../Math/randomnumbers/inversecumulativersg.cs | 8 +- + src/QLNet/Math/randomnumbers/mt19937uniformrng.cs | 83 +- + .../Math/randomnumbers/primitivepolynomials.cs | 42901 +++++----- + .../Math/randomnumbers/randomsequencegenerator.cs | 150 +- + src/QLNet/Math/randomnumbers/rngtraits.cs | 157 +- + src/QLNet/Math/randomnumbers/seedgenerator.cs | 81 +- + src/QLNet/Math/randomnumbers/sobolrsg.cs | 179 +- + src/QLNet/Math/randomnumbers/sobolrsg2.cs | 78509 ++++++++++--------- + src/QLNet/Math/statistics/DiscrepancyStatistics.cs | 20 +- + src/QLNet/Math/statistics/convergencestatistics.cs | 239 +- + src/QLNet/Math/statistics/gaussianstatistics.cs | 374 +- + src/QLNet/Math/statistics/generalstatistics.cs | 498 +- + src/QLNet/Math/statistics/incrementalstatistics.cs | 444 +- + src/QLNet/Math/statistics/riskstatistics.cs | 333 +- + src/QLNet/Math/statistics/sequencestatistics.cs | 434 +- + src/QLNet/Math/transformedgrid.cs | 121 +- + .../Methods/Finitedifferences/AmericanCondition.cs | 31 +- + .../Methods/Finitedifferences/BoundaryCondition.cs | 222 +- + src/QLNet/Methods/Finitedifferences/DMinus.cs | 44 +- + src/QLNet/Methods/Finitedifferences/DPlus.cs | 44 +- + src/QLNet/Methods/Finitedifferences/DPlusDMinus.cs | 43 +- + .../Methods/Finitedifferences/ExplicitEuler.cs | 86 +- + .../Methods/Finitedifferences/ImplicitEuler.cs | 78 +- + .../Meshers/Concentrating1dMesher.cs | 57 +- + .../Finitedifferences/Meshers/Fdm1dMesher.cs | 14 +- + .../Meshers/FdmBlackScholesMesher.cs | 237 +- + .../Methods/Finitedifferences/Meshers/FdmMesher.cs | 40 +- + .../Meshers/FdmMesherComposite.cs | 193 +- + .../Meshers/FdmSimpleProcess1dMesher.cs | 84 +- + .../Finitedifferences/Meshers/Uniform1dMesher.cs | 8 +- + .../Finitedifferences/Meshers/UniformGridMesher.cs | 20 +- + .../Methods/Finitedifferences/OperatorFactory.cs | 10 +- + .../Operators/FdmBlackScholesOp.cs | 262 +- + .../Finitedifferences/Operators/FdmHullWhiteOp.cs | 168 +- + .../Finitedifferences/Operators/FdmLinearOp.cs | 49 +- + .../Operators/FdmLinearOpComposite.cs | 53 +- + .../Operators/FdmLinearOpIterator.cs | 8 +- + .../Operators/FdmLinearOpLayout.cs | 230 +- + .../Operators/FirstDerivativeOp.cs | 96 +- + .../Operators/NinePointLinearOp.cs | 392 +- + .../Operators/SecondDerivativeOp.cs | 80 +- + .../Operators/SecondOrderMixedDerivativeOp.cs | 224 +- + .../Operators/TripleBandLinearOp.cs | 583 +- + .../Methods/Finitedifferences/ParallelEvolver.cs | 114 +- + .../Schemes/BoundaryConditionSchemeHelper.cs | 75 +- + .../Finitedifferences/Schemes/CraigSneydScheme.cs | 14 +- + .../Finitedifferences/Schemes/DouglasScheme.cs | 14 +- + .../Schemes/ExplicitEulerScheme.cs | 78 +- + .../Finitedifferences/Schemes/HundsdorferScheme.cs | 14 +- + .../Schemes/ImplicitEulerScheme.cs | 164 +- + .../Schemes/ModifiedCraigSneydScheme.cs | 159 +- + .../Methods/Finitedifferences/ShoutCondition.cs | 80 +- + .../Finitedifferences/Solvers/Fdm1DimSolver.cs | 184 +- + .../Finitedifferences/Solvers/FdmBackwardSolver.cs | 290 +- + .../Solvers/FdmBlackScholesSolver.cs | 111 +- + .../Solvers/FdmHullWhiteSolver.cs | 89 +- + .../Finitedifferences/Solvers/FdmSolverDesc.cs | 78 +- + .../Methods/Finitedifferences/StepCondition.cs | 176 +- + .../StepConditions/FdmAmericanStepCondition.cs | 58 +- + .../StepConditions/FdmBermudanStepCondition.cs | 20 +- + .../StepConditions/FdmSnapshotCondition.cs | 46 +- + .../StepConditions/FdmStepConditionComposite.cs | 177 +- + src/QLNet/Methods/Finitedifferences/TRBDF2.cs | 264 +- + .../Finitedifferences/TridiagonalOperator.cs | 461 +- + .../Utilities/FdmAffineModelSwapInnerValue.cs | 213 +- + .../Utilities/FdmAffineModelTermStructure.cs | 76 +- + .../Utilities/FdmBoundaryConditionSet.cs | 14 +- + .../Utilities/FdmDirichletBoundary.cs | 18 +- + .../Utilities/FdmDividendHandler.cs | 18 +- + .../Utilities/FdmIndicesOnBoundary.cs | 16 +- + .../Utilities/FdmInnerValueCalculator.cs | 245 +- + .../Utilities/FdmMesherIntegral.cs | 72 +- + .../Finitedifferences/Utilities/ListUtils.cs | 176 +- + .../Methods/Finitedifferences/ZeroCondition.cs | 33 +- + src/QLNet/Methods/Finitedifferences/bsmoperator.cs | 50 +- + .../Methods/Finitedifferences/cranknicolson.cs | 54 +- + src/QLNet/Methods/Finitedifferences/dzero.cs | 43 +- + .../Finitedifferences/finitedifferencemodel.cs | 176 +- + src/QLNet/Methods/Finitedifferences/mixedscheme.cs | 143 +- + src/QLNet/Methods/Finitedifferences/pde.cs | 154 +- + src/QLNet/Methods/Finitedifferences/pdebsm.cs | 53 +- + .../Methods/Finitedifferences/pdeshortrate.cs | 8 +- + src/QLNet/Methods/lattices/binominaltree.cs | 8 +- + src/QLNet/Methods/lattices/bsmlattice.cs | 14 +- + src/QLNet/Methods/lattices/lattice.cs | 235 +- + src/QLNet/Methods/lattices/lattice1d.cs | 42 +- + src/QLNet/Methods/lattices/lattice2d.cs | 177 +- + src/QLNet/Methods/lattices/tree.cs | 8 +- + src/QLNet/Methods/lattices/trinomialtree.cs | 295 +- + src/QLNet/Methods/montecarlo/brownianbridge.cs | 322 +- + .../Methods/montecarlo/earlyexercisepathpricer.cs | 8 +- + .../montecarlo/longstaffschwartzpathpricer.cs | 258 +- + src/QLNet/Methods/montecarlo/lsmbasissystem.cs | 262 +- + src/QLNet/Methods/montecarlo/mctraits.cs | 8 +- + src/QLNet/Methods/montecarlo/montecarlomodel.cs | 46 +- + src/QLNet/Methods/montecarlo/multipath.cs | 87 +- + src/QLNet/Methods/montecarlo/multipathgenerator.cs | 22 +- + src/QLNet/Methods/montecarlo/path.cs | 138 +- + src/QLNet/Methods/montecarlo/pathgenerator.cs | 22 +- + src/QLNet/Methods/montecarlo/pathpricer.cs | 26 +- + src/QLNet/Methods/montecarlo/sample.cs | 8 +- + src/QLNet/Models/CalibrationHelper.cs | 265 +- + src/QLNet/Models/Equity/HestonModel.cs | 50 +- + src/QLNet/Models/Equity/HestonModelHelper.cs | 76 +- + .../Equity/PiecewiseTimeDependentHestonModel.cs | 38 +- + src/QLNet/Models/MarketModels/BrownianGenerator.cs | 12 +- + .../BrownianGenerators/SobolBrownianGenerator.cs | 121 +- + src/QLNet/Models/Parameter.cs | 74 +- + src/QLNet/Models/Shortrate/OneFactorModel.cs | 30 +- + .../Shortrate/Onefactormodels/blackkarasinski.cs | 260 +- + .../Shortrate/Onefactormodels/coxingersollross.cs | 26 +- + .../Models/Shortrate/Onefactormodels/hullwhite.cs | 32 +- + .../Models/Shortrate/Onefactormodels/vasicek.cs | 10 +- + src/QLNet/Models/Shortrate/Twofactorsmodels/g2.cs | 761 +- + .../Shortrate/calibrationhelpers/caphelper.cs | 240 +- + .../Shortrate/calibrationhelpers/swaptionhelper.cs | 412 +- + src/QLNet/Models/Shortrate/twofactormodel.cs | 18 +- + src/QLNet/Models/model.cs | 659 +- + src/QLNet/Money.cs | 126 +- + src/QLNet/Option.cs | 8 +- + src/QLNet/Patterns/FastActivator.cs | 40 +- + src/QLNet/Patterns/LazyObject.cs | 194 +- + src/QLNet/Patterns/Observer.cs | 8 +- + src/QLNet/Patterns/Visitor.cs | 18 +- + src/QLNet/Patterns/WeakEventSource.cs | 46 +- + src/QLNet/Patterns/observablevalue.cs | 121 +- + src/QLNet/PricingEngine.cs | 22 +- + src/QLNet/Pricingengines/Americanpayoffatexpiry.cs | 118 +- + src/QLNet/Pricingengines/Americanpayoffathit.cs | 486 +- + src/QLNet/Pricingengines/Basket/KirkEngine.cs | 54 +- + .../Basket/MCEuropeanBasketEngine.cs | 12 +- + src/QLNet/Pricingengines/Basket/StulzEngine.cs | 124 +- + src/QLNet/Pricingengines/BlackCalculator.cs | 709 +- + src/QLNet/Pricingengines/BlackDeltaCalculator.cs | 268 +- + src/QLNet/Pricingengines/Blackscholescalculator.cs | 89 +- + .../Pricingengines/Bond/BlackCallableBondEngine.cs | 64 +- + src/QLNet/Pricingengines/Bond/BondFunctions.cs | 176 +- + .../Pricingengines/Bond/Discountingbondengine.cs | 28 +- + .../Pricingengines/Bond/TreeCallableBondEngine.cs | 60 +- + .../CapFloor/BachelierCapFloorEngine.cs | 44 +- + .../Pricingengines/CapFloor/BlackCapFloorEngine.cs | 98 +- + .../CapFloor/analyticcapfloorengine.cs | 210 +- + .../Pricingengines/CapFloor/discretizedcapfloor.cs | 176 +- + .../Cliquet/AnalyticCliquetEngine.cs | 58 +- + .../Cliquet/AnalyticPerformanceEngine.cs | 52 +- + .../Forward/ForwardPerformanceVanillaEngine.cs | 20 +- + .../Pricingengines/Forward/ForwardVanillaEngine.cs | 60 +- + src/QLNet/Pricingengines/Greeks.cs | 50 +- + .../Pricingengines/Loan/DiscountingLoanEngine.cs | 88 +- + .../AnalyticContinuousFixedLookbackEngine.cs | 92 +- + .../AnalyticContinuousFloatingLookbackEngine.cs | 58 +- + ...AnalyticContinuousPartialFixedLookbackEngine.cs | 99 +- + ...lyticContinuousPartialFloatingLookbackEngine.cs | 109 +- + .../Swap/CounterpartyAdjSwapEngine.cs | 116 +- + .../Swap/DiscountingBasisSwapEngine.cs | 85 +- + .../Pricingengines/Swap/Discountingswapengine.cs | 126 +- + src/QLNet/Pricingengines/Swap/discretizedswap.cs | 301 +- + src/QLNet/Pricingengines/Swap/treeswapengine.cs | 18 +- + ...icContinuousGeometricAveragePriceAsianEngine.cs | 68 +- + ...yticDiscreteGeometricAveragePriceAsianEngine.cs | 111 +- + ...ticDiscreteGeometricAverageStrikeAsianEngine.cs | 90 +- + .../asian/mc_discr_arith_av_price.cs | 486 +- + .../asian/mc_discr_arith_av_strike.cs | 52 +- + .../Pricingengines/asian/mc_discr_geom_av_price.cs | 64 +- + .../Pricingengines/asian/mcdiscreteasianengine.cs | 263 +- + .../barrier/AnalyticBarrierEngine.cs | 451 +- + .../barrier/AnalyticBinaryBarrierEngine.cs | 218 +- + .../barrier/AnalyticDoubleBarrierBinaryEngine.cs | 627 +- + .../barrier/AnalyticDoubleBarrierEngine.cs | 119 +- + .../barrier/BinomialBarrierEngine.cs | 72 +- + .../barrier/BinomialDoubleBarrierEngine.cs | 108 +- + .../barrier/DiscretizedBarrierOption.cs | 165 +- + .../barrier/DiscretizedDoubleBarrierOption.cs | 221 +- + .../barrier/FdBlackScholesBarrierEngine.cs | 46 +- + .../barrier/FdBlackScholesRebateEngine.cs | 221 +- + .../barrier/VannaVolgaBarrierEngine.cs | 312 +- + .../barrier/VannaVolgaDoubleBarrierEngine.cs | 272 +- + .../barrier/WulinYongDoubleBarrierEngine.cs | 127 +- + src/QLNet/Pricingengines/blackformula.cs | 557 +- + .../Pricingengines/credit/IntegralCdsEngine.cs | 272 +- + src/QLNet/Pricingengines/credit/IsdaCdsEngine.cs | 133 +- + .../Pricingengines/credit/MidPointCdsEngine.cs | 255 +- + src/QLNet/Pricingengines/genericmodelengine.cs | 34 +- + .../inflation/InflationCapFloorEngines.cs | 295 +- + .../inflation/InterpolatingCPICapFloorEngine.cs | 50 +- + .../Pricingengines/latticeshortratemodelengine.cs | 92 +- + .../Pricingengines/mclongstaffschwartzengine.cs | 134 +- + src/QLNet/Pricingengines/mcsimulation.cs | 78 +- + .../Pricingengines/swaption/blackswaptionengine.cs | 112 +- + .../Pricingengines/swaption/discretizedswaption.cs | 126 +- + .../Pricingengines/swaption/g2swaptionengine.cs | 71 +- + .../swaption/jamshidianswaptionengine.cs | 284 +- + .../Pricingengines/swaption/treeswaptionengine.cs | 193 +- + .../vanilla/AnalyticBSMHullWhiteEngine.cs | 70 +- + .../vanilla/AnalyticDigitalAmericanEngine.cs | 46 +- + .../vanilla/AnalyticDividendEuropeanEngine.cs | 170 +- + .../vanilla/AnalyticEuropeanEngine.cs | 179 +- + .../Pricingengines/vanilla/AnalyticH1HWEngine.cs | 88 +- + .../Pricingengines/vanilla/AnalyticHestonEngine.cs | 358 +- + .../vanilla/AnalyticHestonHullWhiteEngine.cs | 42 +- + .../vanilla/AnalyticPTDHestonEngine.cs | 132 +- + .../Pricingengines/vanilla/FDAmericanEngine.cs | 54 +- + .../Pricingengines/vanilla/FDBermudanEngine.cs | 109 +- + src/QLNet/Pricingengines/vanilla/FDConditions.cs | 212 +- + .../vanilla/FDDividendAmericanEngine.cs | 42 +- + .../Pricingengines/vanilla/FDDividendEngine.cs | 402 +- + .../vanilla/FDDividendEuropeanEngine.cs | 30 +- + .../Pricingengines/vanilla/FDEuropeanEngine.cs | 166 +- + .../Pricingengines/vanilla/FDMultiPeriodEngine.cs | 295 +- + src/QLNet/Pricingengines/vanilla/FDShoutEngine.cs | 52 +- + .../vanilla/FDStepConditionEngine.cs | 187 +- + .../Pricingengines/vanilla/FDVanillaEngine.cs | 395 +- + .../vanilla/FdBlackScholesVanillaEngine.cs | 161 +- + .../vanilla/FdHestonVanillaEngine.cs | 8 +- + .../vanilla/FdHullWhiteSwaptionEngine.cs | 192 +- + .../vanilla/HestonExpansionEngine.cs | 1208 +- + src/QLNet/Pricingengines/vanilla/Integralengine.cs | 111 +- + .../Pricingengines/vanilla/Juquadraticengine.cs | 24 +- + .../vanilla/MCEuropeanHestonEngine.cs | 214 +- + .../vanilla/MCHestonHullWhiteEngine.cs | 140 +- + .../vanilla/baroneadesiwhaleyengine.cs | 425 +- + src/QLNet/Pricingengines/vanilla/binomialengine.cs | 214 +- + .../vanilla/bjerksundstenslandengine.cs | 261 +- + .../vanilla/discretizedvanillaoption.cs | 120 +- + .../Pricingengines/vanilla/mcamericanengine.cs | 146 +- + .../Pricingengines/vanilla/mceuropeanengine.cs | 96 +- + .../Pricingengines/vanilla/mcvanillaengine.cs | 128 +- + src/QLNet/Quotes/CompositeQuote.cs | 11 +- + src/QLNet/Quotes/DeltaVolQuote.cs | 18 +- + src/QLNet/Quotes/DerivedQuote.cs | 21 +- + src/QLNet/Quotes/LastFixingQuote.cs | 19 +- + src/QLNet/Quotes/Quote.cs | 66 +- + src/QLNet/Quotes/SimpleQuote.cs | 77 +- + src/QLNet/Settings.cs | 162 +- + src/QLNet/StochasticProcess.cs | 492 +- + src/QLNet/Termstructures/Bootstraperror.cs | 59 +- + src/QLNet/Termstructures/Bootstraphelper.cs | 264 +- + src/QLNet/Termstructures/Credit/FlatHazardRate.cs | 20 +- + .../Termstructures/Credit/HazardRateStructure.cs | 34 +- + .../Credit/InterpolatedHazardRateCurve.cs | 314 +- + .../Credit/InterpolatedSurvivalProbabilityCurve.cs | 100 +- + .../Termstructures/Credit/ProbabilityTraits.cs | 34 +- + .../Credit/SurvivalProbabilityStructure.cs | 36 +- + src/QLNet/Termstructures/Curve.cs | 42 +- + .../DefaultProbabilityTermStructure.cs | 130 +- + .../Inflation/CPICapFloorTermPriceSurface.cs | 223 +- + .../Termstructures/Inflation/InflationHelpers.cs | 308 +- + .../Termstructures/Inflation/InflationTraits.cs | 290 +- + .../Inflation/InterpolatedYoYInflationCurve.cs | 48 +- + .../Inflation/InterpolatedZeroInflationCurve.cs | 34 +- + .../Inflation/PiecewiseYoYInflationCurve.cs | 458 +- + .../Inflation/PiecewiseZeroInflationCurve.cs | 514 +- + src/QLNet/Termstructures/Inflation/Seasonality.cs | 155 +- + src/QLNet/Termstructures/InflationTermStructure.cs | 86 +- + src/QLNet/Termstructures/Iterativebootstrap.cs | 340 +- + src/QLNet/Termstructures/TermStructure.cs | 58 +- + .../Termstructures/Volatility/AbcdCalibration.cs | 130 +- + .../Termstructures/Volatility/AbcdFunction.cs | 103 +- + .../Termstructures/Volatility/AtmSmileSection.cs | 12 +- + .../Bond/CallableBondConstantVolatility.cs | 30 +- + .../Bond/CallableBondVolatilityStructure.cs | 70 +- + .../Volatility/CapFloor/CapFloorTermVolCurve.cs | 138 +- + .../Volatility/CapFloor/CapFloorTermVolSurface.cs | 207 +- + .../CapFloor/CapFloorTermVolatilityStructure.cs | 26 +- + .../CapFloor/ConstantCapFloorTermVolatility.cs | 12 +- + .../Termstructures/Volatility/FlatSmileSection.cs | 86 +- + .../Volatility/Inflation/CPIVolatilitySurface.cs | 426 +- + .../yoyinflationoptionletvolatilitystructure.cs | 196 +- + .../Volatility/InterpolatedSmileSection.cs | 150 +- + .../Optionlet/ConstantOptionletVolatility.cs | 131 +- + .../Volatility/Optionlet/OptionletStripper.cs | 118 +- + .../Volatility/Optionlet/OptionletStripper1.cs | 84 +- + .../Volatility/Optionlet/OptionletStripper2.cs | 80 +- + .../Optionlet/OptionletVolatilityStructure.cs | 42 +- + .../Optionlet/SpreadedOptionletVolatility.cs | 18 +- + .../Optionlet/StrippedOptionletAdapter.cs | 70 +- + .../Volatility/Optionlet/StrippedOptionletBase.cs | 12 +- + .../Volatility/Optionlet/capletvariancecurve.cs | 93 +- + src/QLNet/Termstructures/Volatility/Sabr.cs | 334 +- + .../Volatility/SabrInterpolatedSmileSection.cs | 352 +- + .../Termstructures/Volatility/SmileSection.cs | 240 +- + .../Volatility/SpreadedSmileSection.cs | 14 +- + src/QLNet/Termstructures/Volatility/Svi.cs | 86 +- + .../Volatility/SviInterpolatedSmileSection.cs | 358 +- + .../Termstructures/Volatility/SviSmileSection.cs | 94 +- + .../Volatility/equityfx/BlackConstantVol.cs | 72 +- + .../Volatility/equityfx/BlackVarianceCurve.cs | 172 +- + .../Volatility/equityfx/BlackVarianceSurface.cs | 39 +- + .../Volatility/equityfx/BlackVolTermStructure.cs | 188 +- + .../Volatility/equityfx/FixedLocalVolSurface.cs | 395 +- + .../Volatility/equityfx/HestonBlackVolSurface.cs | 23 +- + .../Volatility/equityfx/ImpliedVolTermStructure.cs | 26 +- + .../Volatility/equityfx/LocalConstantVol.cs | 96 +- + .../Volatility/equityfx/LocalVolCurve.cs | 18 +- + .../Volatility/equityfx/LocalVolSurface.cs | 257 +- + .../Volatility/equityfx/LocalVolTermStructure.cs | 34 +- + .../Volatility/equityfx/NoExceptLocalVolSurface.cs | 24 +- + .../swaption/SpreadedSwaptionVolatility.cs | 32 +- + .../Volatility/swaption/SwaptionVolCube1.cs | 683 +- + .../Volatility/swaption/SwaptionVolCube2.cs | 80 +- + .../Volatility/swaption/SwaptionVolatilityCube.cs | 184 +- + .../swaption/SwaptionVolatilityStructure.cs | 104 +- + .../Volatility/swaption/swaptionconstantvol.cs | 258 +- + .../Volatility/swaption/swaptionvoldiscrete.cs | 42 +- + .../Volatility/swaption/swaptionvolmatrix.cs | 882 +- + src/QLNet/Termstructures/Yield/BasisSwapHelper.cs | 60 +- + src/QLNet/Termstructures/Yield/Bondhelpers.cs | 112 +- + src/QLNet/Termstructures/Yield/Bootstraptraits.cs | 400 +- + src/QLNet/Termstructures/Yield/DiscountCurve.cs | 38 +- + .../Yield/FittedBondDiscountCurve.cs | 186 +- + src/QLNet/Termstructures/Yield/Flatforward.cs | 141 +- + src/QLNet/Termstructures/Yield/ForwardCurve.cs | 18 +- + .../Yield/ForwardSpreadedTermStructure.cs | 93 +- + src/QLNet/Termstructures/Yield/ForwardStructure.cs | 32 +- + .../Termstructures/Yield/ImpliedTermStructure.cs | 90 +- + ...terpolatedPiecewiseZeroSpreadedTermStructure.cs | 28 +- + .../Yield/NonLinearFittingMethods.cs | 198 +- + src/QLNet/Termstructures/Yield/OISRateHelper.cs | 58 +- + .../Termstructures/Yield/PiecewiseYieldCurve.cs | 266 +- + src/QLNet/Termstructures/Yield/Ratehelpers.cs | 842 +- + src/QLNet/Termstructures/Yield/ZeroCurve.cs | 36 +- + .../Yield/ZeroSpreadedTermStructure.cs | 54 +- + .../Termstructures/Yield/Zeroyieldstructure.cs | 30 +- + src/QLNet/Termstructures/YieldTermStructure.cs | 163 +- + src/QLNet/Termstructures/interpolatedcurve.cs | 78 +- + src/QLNet/Termstructures/localbootstrap.cs | 379 +- + src/QLNet/Termstructures/voltermstructure.cs | 34 +- + src/QLNet/Time/ASX.cs | 135 +- + src/QLNet/Time/Calendar.cs | 765 +- + src/QLNet/Time/Calendars/Israel.cs | 616 +- + src/QLNet/Time/Calendars/JointCalendar.cs | 205 +- + src/QLNet/Time/Calendars/Romania.cs | 62 +- + src/QLNet/Time/Calendars/TARGET.cs | 106 +- + src/QLNet/Time/Calendars/Ukraine.cs | 66 +- + src/QLNet/Time/Calendars/UnitedKingdom.cs | 378 +- + src/QLNet/Time/Calendars/UnitedStates.cs | 425 +- + src/QLNet/Time/Calendars/WeekendsOnly.cs | 8 +- + src/QLNet/Time/Calendars/argentina.cs | 144 +- + src/QLNet/Time/Calendars/australia.cs | 136 +- + src/QLNet/Time/Calendars/bespokecalendar.cs | 89 +- + src/QLNet/Time/Calendars/botswana.cs | 10 +- + src/QLNet/Time/Calendars/brazil.cs | 256 +- + src/QLNet/Time/Calendars/canada.cs | 279 +- + src/QLNet/Time/Calendars/china.cs | 385 +- + src/QLNet/Time/Calendars/czechrepublic.cs | 142 +- + src/QLNet/Time/Calendars/denmark.cs | 126 +- + src/QLNet/Time/Calendars/finland.cs | 132 +- + src/QLNet/Time/Calendars/germany.cs | 587 +- + src/QLNet/Time/Calendars/hongkong.cs | 457 +- + src/QLNet/Time/Calendars/hungary.cs | 124 +- + src/QLNet/Time/Calendars/iceland.cs | 142 +- + src/QLNet/Time/Calendars/india.cs | 544 +- + src/QLNet/Time/Calendars/indonesia.cs | 518 +- + src/QLNet/Time/Calendars/italy.cs | 299 +- + src/QLNet/Time/Calendars/japan.cs | 215 +- + src/QLNet/Time/Calendars/mexico.cs | 100 +- + src/QLNet/Time/Calendars/newzealand.cs | 150 +- + src/QLNet/Time/Calendars/norway.cs | 126 +- + src/QLNet/Time/Calendars/nullcalendar.cs | 39 +- + src/QLNet/Time/Calendars/poland.cs | 96 +- + src/QLNet/Time/Calendars/russia.cs | 182 +- + src/QLNet/Time/Calendars/saudiarabia.cs | 123 +- + src/QLNet/Time/Calendars/singapore.cs | 206 +- + src/QLNet/Time/Calendars/slovakia.cs | 162 +- + src/QLNet/Time/Calendars/southafrica.cs | 161 +- + src/QLNet/Time/Calendars/southkorea.cs | 391 +- + src/QLNet/Time/Calendars/sweden.cs | 110 +- + src/QLNet/Time/Calendars/switzerland.cs | 124 +- + src/QLNet/Time/Calendars/taiwan.cs | 484 +- + src/QLNet/Time/Calendars/turkey.cs | 244 +- + src/QLNet/Time/Date.cs | 28 +- + src/QLNet/Time/DayCounter.cs | 107 +- + src/QLNet/Time/DayCounters/Actual360.cs | 8 +- + src/QLNet/Time/DayCounters/Actual365Fixed.cs | 52 +- + src/QLNet/Time/DayCounters/Actual365NoLeap.cs | 74 +- + src/QLNet/Time/DayCounters/ActualActual.cs | 394 +- + src/QLNet/Time/DayCounters/Business252.cs | 8 +- + src/QLNet/Time/DayCounters/OneDayCounter.cs | 54 +- + src/QLNet/Time/DayCounters/SimpleDayCounter.cs | 70 +- + src/QLNet/Time/DayCounters/Thirty360.cs | 176 +- + src/QLNet/Time/ECB.cs | 364 +- + src/QLNet/Time/Imm.cs | 308 +- + src/QLNet/Time/Period.cs | 659 +- + src/QLNet/Time/Schedule.cs | 139 +- + src/QLNet/Types.cs | 38 +- + src/QLNet/Utils.cs | 287 +- + src/QLNet/discretizedasset.cs | 16 +- + src/QLNet/grid.cs | 68 +- + .../legacy/libormarketmodels/lfmcovarparam.cs | 8 +- + .../legacy/libormarketmodels/lfmcovarproxy.cs | 236 +- + .../legacy/libormarketmodels/lfmhullwhiteparam.cs | 291 +- + src/QLNet/legacy/libormarketmodels/lfmprocess.cs | 431 +- + .../legacy/libormarketmodels/lfmswaptionengine.cs | 97 +- + .../legacy/libormarketmodels/liborforwardmodel.cs | 399 +- + .../libormarketmodels/lmconstwrappercorrmodel.cs | 8 +- + .../libormarketmodels/lmconstwrappervolmodel.cs | 8 +- + src/QLNet/legacy/libormarketmodels/lmcorrmodel.cs | 12 +- + .../legacy/libormarketmodels/lmexpcorrmodel.cs | 8 +- + .../libormarketmodels/lmextlinexpvolmodel.cs | 32 +- + .../legacy/libormarketmodels/lmfixedvolmodel.cs | 30 +- + .../legacy/libormarketmodels/lmlinexpcorrmodel.cs | 26 +- + .../legacy/libormarketmodels/lmlinexpvolmodel.cs | 10 +- + src/QLNet/legacy/libormarketmodels/lmvolmodel.cs | 8 +- + src/QLNet/numericalmethod.cs | 8 +- + src/QLNet/payoff.cs | 47 +- + src/QLNet/processes/BlackScholesProcess.cs | 198 +- + src/QLNet/processes/Defaultable.cs | 113 +- + src/QLNet/processes/EulerDiscretization.cs | 100 +- + src/QLNet/processes/ForwardMeasureProcess.cs | 24 +- + .../processes/GeometricBrownianMotionProcess.cs | 80 +- + src/QLNet/processes/HestonProcess.cs | 541 +- + src/QLNet/processes/HullWhiteProcess.cs | 104 +- + .../processes/HybridHestonHullWhiteProcess.cs | 146 +- + src/QLNet/processes/Ornsteinuhlenbeckprocess.cs | 36 +- + src/QLNet/processes/Squarerootprocess.cs | 83 +- + src/QLNet/processes/stochasticprocessarray.cs | 203 +- + src/QLNet/timegrid.cs | 33 +- + src/Repo/Repo.cs | 307 +- + src/Swap/swapvaluation.cs | 1051 +- + 687 files changed, 116004 insertions(+), 112724 deletions(-) + +commit 26c1d4c6b4c55c3180a6c549e037258bc362784e Author: Andrea Maggiulli -Date: Wed Aug 30 11:14:32 2017 +0200 - - Fixed Sonar security issue. +Date: Fri Feb 2 11:33:30 2018 +0100 - src/QLNet/Indexes/Region.cs | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) + Added Artistic Style 3.1 tool for formatting code. -commit 36edd5a72b24f79b5ced40c492b7fb1851c4eb39 -Author: Andrea Maggiulli -Date: Wed Aug 30 10:46:37 2017 +0200 - - Fix compilation ( something wrong on latest merging ). + format_code.bat | 1 + + qlnet.astyle | 28 ++++++++++++++++++++++++++++ + tools/AStyle.exe | Bin 0 -> 595456 bytes + 3 files changed, 29 insertions(+) - src/Bonds/Bonds.cs | 4 ++-- - src/QLNet/Termstructures/Volatility/Sabr.cs | 11 +++++++++-- - 2 files changed, 11 insertions(+), 4 deletions(-) +commit 5bd4f2092b01ee461a70276c441bd945a4b7dbba +Merge: fe7222a e41c3c8 +Author: Andrea Maggiulli +Date: Thu Feb 1 13:30:02 2018 +0100 -commit 55914c861f07b6beac4ce52799c76afa60b689c2 -Merge: d550cbc 660f118 -Author: Andrea Maggiulli -Date: Wed Aug 30 09:46:04 2017 +0200 - - Merge pull request #168 from jiskin/Improve_MakeCms_with_capfloors - - Add cap/floors setters for CMS and Ibor legs - -commit d550cbc70f1b348aeb97ce218a6aa365e04e749d -Merge: ec0a8ff e675bc5 -Author: Andrea Maggiulli -Date: Wed Aug 30 09:45:15 2017 +0200 - - Merge pull request #167 from jiskin/bugfix_cap_floor_to_zero + Merge pull request #200 from igitur/levenberg-precondition-checks - Bugfix when cap/floor equals zero + Add LevenbergMarquardt precondition checks -commit ec0a8fff5fd69e789687c392477949f228736f82 -Merge: c5bbcd8 076dbf8 -Author: Andrea Maggiulli -Date: Wed Aug 30 09:44:11 2017 +0200 +commit fe7222a29141e269a00094c4a74e59b92d5fb7f1 +Merge: c3fe00e fc2a9ea +Author: Andrea Maggiulli +Date: Thu Feb 1 12:30:24 2018 +0100 - Merge pull request #166 from jiskin/bad_inheritance_optionletstripper + Merge pull request #199 from igitur/composite-yield-term-structure - Issue with inheritance fixed + Implement CompositeZeroYieldStructure -commit c5bbcd8e1222154300df1ee51e7e5770af0dae5e -Merge: d22cca0 17bc2c9 -Author: Andrea Maggiulli -Date: Wed Aug 30 09:42:44 2017 +0200 +commit c3fe00e982117eee8a91bdca6c95ae88c98f50d1 +Merge: bbc2742 a591b25 +Author: Andrea Maggiulli +Date: Thu Feb 1 11:50:04 2018 +0100 - Merge pull request #165 from jiskin/Normal_Sabr_Interpolation + Merge pull request #193 from tournierjc/StrikerGetterOnHestonHelper - New feature : Normal sabr interpolation - -commit 17bc2c9ea308ccd411fd46c0ce8bf64eaf2559a7 -Merge: 00dbef0 d22cca0 -Author: Andrea Maggiulli -Date: Wed Aug 30 09:42:31 2017 +0200 + Strike and Type getters on Heston helper - Merge branch 'develop' into Normal_Sabr_Interpolation +commit fc2a9ea09639d6ce3e4216cde4b9b27dd3f3c18e +Author: Francois Botha +Date: Wed Jan 31 15:10:47 2018 +0200 -commit d22cca0fce4ec894a56b3fa2c097821e50a6b21d -Merge: b62b919 c0b727a -Author: Andrea Maggiulli -Date: Wed Aug 30 09:34:26 2017 +0200 + Clean up SonarLint warnings - Merge pull request #164 from jiskin/swaption_vol_matrix_normal_vol - - Swaption vol matrix normal vol + .../Yield/CompositeZeroYieldStructure.cs | 10 +- + tests/QLNet.Tests/T_TermStructures.cs | 159 ++++++++++----------- + 2 files changed, 83 insertions(+), 86 deletions(-) -commit b62b91932e8edca77426ac60a757bad7d97e044e -Merge: 7e10083 1d80418 -Author: Andrea Maggiulli -Date: Wed Aug 30 09:33:25 2017 +0200 +commit e41c3c899c940e4bbd7dc003a5e1762ea199e544 +Author: Francois Botha +Date: Wed Jan 31 14:41:34 2018 +0200 - Merge pull request #163 from jiskin/calibration_helper_normal_vol - - Calibration helper normal vol + Add LevenbergMarquardt precondition checks -commit 7e10083ba18c8140fe4641e5a1853437e031821a -Merge: c541db9 3ac192d -Author: Andrea Maggiulli -Date: Wed Aug 30 09:32:09 2017 +0200 + src/QLNet/Math/Optimization/levenbergmarquardt.cs | 8 ++++++++ + 1 file changed, 8 insertions(+) - Merge pull request #162 from jiskin/NewtonSafeAccessibility - - Newtonsafe class wasn't public +commit e37748a454dd204e7408157d8c9efe9841bc2dfe +Author: Francois Botha +Date: Wed Jan 31 14:37:29 2018 +0200 -commit c541db9313baecd6ee237c8bb5bdedaffdb4d8be -Merge: cd060c5 09f5507 -Author: Andrea Maggiulli -Date: Wed Aug 30 09:30:57 2017 +0200 + Implement CompositeZeroYieldStructure - Merge pull request #161 from jiskin/add_normal_vol_to_swaption - - Add normal vol to swaption + src/QLNet.Old/QLNet.Old.csproj | 5 +- + .../Yield/CompositeZeroYieldStructure.cs | 108 +++++++++++ + tests/QLNet.Tests/T_TermStructures.cs | 216 ++++++++++++++++++--- + 3 files changed, 300 insertions(+), 29 deletions(-) -commit cd060c58a6afff1e01aee9c6aefeb68c74c9f9bd -Merge: e04617e 75fcdb6 +commit bbc27424ea6814a5fe3a05bbd92e409ef0cc4b4b Author: Andrea Maggiulli -Date: Wed Aug 30 09:29:57 2017 +0200 - - Merge pull request #160 from jiskin/allow_override_forwardValue - - Put forwardValue method as virtual +Date: Tue Jan 30 16:56:52 2018 +0100 -commit e04617e4a0b7f39699b262aee89402a297ebc837 -Merge: 9434739 047346e -Author: Andrea Maggiulli -Date: Wed Aug 30 09:23:15 2017 +0200 + Cleanup code and reformat. - Merge pull request #157 from igitur/implement-discountingloanengine - - Implement DiscountingLoanEngine + src/QLNet/Math/Interpolations/XABRInterpolation.cs | 377 +++++++++++---------- + 1 file changed, 203 insertions(+), 174 deletions(-) -commit 9434739f0612f2b813019b91414c2b79834b4468 -Merge: 5c50127 d14bcd1 -Author: Andrea Maggiulli -Date: Wed Aug 30 09:16:24 2017 +0200 +commit 749d654a189b36bf8d02496d90ae2f51220f130d +Merge: 7abac70 d4e0950 +Author: Andrea Maggiulli +Date: Tue Jan 30 16:44:28 2018 +0100 - Merge pull request #156 from jiskin/update_sabr_interpolation + Merge pull request #190 from tournierjc/AllowConstraintOnXABRInterpolation - Update SABR & SVI with shift + SABR Interpolated Smile - -commit 00dbef09021ec4a2af834ba6f0800ccaed0f14f9 -Author: jiskin -Date: Mon Aug 21 10:10:25 2017 +0200 - - Allow shift for normal vol - - src/QLNet/Termstructures/Volatility/Sabr.cs | 10 +++++++--- - src/QLNet/Termstructures/Volatility/SmileSection.cs | 12 ++++++------ - 2 files changed, 13 insertions(+), 9 deletions(-) - -commit 51417cdd45d8d92eab4050e9f3c54e636cfa15be -Author: jiskin -Date: Mon Aug 21 10:09:41 2017 +0200 - - Allow shift for normal vol - - src/QLNet/Math/Interpolations/sabrinterpolation.cs | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -commit 660f118176e8a928e4d8258aa9e3b75a0d7b0afb -Author: jiskin -Date: Tue Aug 8 09:51:20 2017 +0200 - - Add cms spread - - src/QLNet/Instruments/MakeCms.cs | 13 +++++-------- - 1 file changed, 5 insertions(+), 8 deletions(-) - -commit 07dc7df9b045f4515a592e5d813748e4470710e7 -Author: jiskin -Date: Mon Aug 7 18:13:18 2017 +0200 - - Add maturity - - src/QLNet/Instruments/MakeCms.cs | 22 ++++++++++++++-------- - 1 file changed, 14 insertions(+), 8 deletions(-) - -commit 7c49350e37f4b237c24b177f6f65b3b9c4d01f5e -Author: jiskin -Date: Fri Aug 4 17:31:28 2017 +0200 + Allow constraint on XABR interpolation - Add setter floating coupon pricer - - src/QLNet/Instruments/MakeCms.cs | 26 ++++++++++++++++++++------ - 1 file changed, 20 insertions(+), 6 deletions(-) - -commit 39a43d48ba3d10ea7326a4692bc1ec239d8599a9 -Author: jiskin -Date: Fri Aug 4 17:25:47 2017 +0200 - - double as double? - - src/QLNet/Instruments/MakeCms.cs | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -commit fa40fc7e180fd59c1fa3cf9520f9ca2fe48ab270 -Author: jiskin -Date: Fri Aug 4 17:19:00 2017 +0200 - - Add cap/floors setters for CMS and Ibor legs - - src/QLNet/Instruments/MakeCms.cs | 47 +++++++++++++++++++++++++++++++++------- - 1 file changed, 39 insertions(+), 8 deletions(-) - -commit c0b727a4b3183ebb3e1f7a0f41e3cb2fab6b8e5e -Author: jiskin -Date: Fri Aug 4 12:18:37 2017 +0200 +commit a591b255e78302378d52ae047f7758d86ca759e6 +Author: tournierjc +Date: Mon Jan 22 10:13:30 2018 +0100 - Missing volatiltyType set in constructors + Add option type getter - src/QLNet/Termstructures/Volatility/swaption/swaptionvolmatrix.cs | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) + src/QLNet/Models/Equity/HestonModelHelper.cs | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) -commit 01b215ccd0afb3c9a12207a59272f9a370164c7c -Author: jiskin -Date: Thu Aug 3 15:06:48 2017 +0200 +commit 82d12b25dde4448cd51694b194392447176cfa5f +Author: tournierjc +Date: Mon Jan 22 10:11:33 2018 +0100 - Update volatility cube to allow normal vol + Add strike getter - .../Volatility/swaption/SwaptionVolCube1.cs | 37 ++++++++++------------ - .../Volatility/swaption/SwaptionVolatilityCube.cs | 2 +- - .../swaption/SwaptionVolatilityStructure.cs | 2 +- - 3 files changed, 19 insertions(+), 22 deletions(-) + src/QLNet/Models/Equity/HestonModelHelper.cs | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) -commit 9dd72972a7c738e7237d8eb74e7e9c3b316d3f7e -Author: jiskin -Date: Thu Aug 3 15:05:53 2017 +0200 +commit d4e0950d5124d667cd99d2e1b9b11db10b2c2598 +Author: tournierjc +Date: Fri Jan 19 18:05:49 2018 +0100 - Bug fix + Correct param name - src/QLNet/Termstructures/Volatility/swaption/swaptionvolmatrix.cs | 2 +- + src/QLNet/Math/Interpolations/XABRInterpolation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -commit 5e29481cc91bbfa6dd8c97431e56bda05a39194d -Author: jiskin -Date: Thu Aug 3 12:22:56 2017 +0200 - - Update smile section - - .../Termstructures/Volatility/SmileSection.cs | 51 ++++++++++++++-------- - 1 file changed, 34 insertions(+), 17 deletions(-) - -commit e675bc5ece550ad98cd67c2a1e2b3ef90695b3da -Author: jiskin -Date: Wed Aug 2 16:30:52 2017 +0200 - - Overload Get function with nullable type +commit 7abac70e2b92fd1f10db2e31a246efd1f3a3de6c +Merge: 89e4ca3 b7bb9f4 +Author: Andrea Maggiulli +Date: Fri Jan 19 17:22:34 2018 +0100 - src/QLNet/Utils.cs | 36 ++++++++++++++++++++++++++---------- - 1 file changed, 26 insertions(+), 10 deletions(-) - -commit b81b00d5c6deb9b529dd0c048ed2652acaa42dd3 -Author: jiskin -Date: Wed Aug 2 16:27:41 2017 +0200 - - Update cashflows + Merge pull request #189 from tournierjc/BugFixOnLevenberg - Allow nullable types for cap and floor - - src/QLNet/Cashflows/Cashflowvectors.cs | 12 ++++++------ - src/QLNet/Cashflows/RateLegBase.cs | 36 +++++++++++++++++----------------- - 2 files changed, 24 insertions(+), 24 deletions(-) + Bug fix on LMDIF algorithm -commit 1e21f2d1093f6a2ed279c740494244cdd77e8d40 -Author: jiskin -Date: Wed Aug 2 16:26:26 2017 +0200 +commit 89e4ca3ef37feedabde0dc391a3f5e83e31378b1 +Merge: e79b486 87f92e2 +Author: Andrea Maggiulli +Date: Fri Jan 19 17:22:00 2018 +0100 - Update bonds constructors + Merge pull request #188 from tournierjc/MissingRegisterWithUpdate - Allow nullable type for cap and floors + Missing register with update - src/QLNet/Instruments/Bonds/AmortizingCmsRateBond.cs | 8 ++++---- - src/QLNet/Instruments/Bonds/AmortizingFloatingRateBond.cs | 8 ++++---- - src/QLNet/Instruments/Bonds/BTP.cs | 4 ++-- - src/QLNet/Instruments/Bonds/CmsRateBond.cs | 8 ++++---- - src/QLNet/Instruments/Bonds/FloatingRateBond.cs | 10 +++++----- - 5 files changed, 19 insertions(+), 19 deletions(-) - -commit fce7ca07f2596708adbecbaa001bbdaf91caeceb -Author: jiskin -Date: Wed Aug 2 16:25:37 2017 +0200 - - Update MakeCms - - Default cap/floors were set to 0.0 => now set to null - - src/QLNet/Instruments/MakeCms.cs | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -commit 363c0ef647fb5afc7c0054d61cb3ba7261dd2222 -Author: jiskin -Date: Wed Aug 2 16:23:15 2017 +0200 - - Update test files - - tests/QLNet.Tests/T_AssetSwap.cs | 46 +++++++++++----------- - tests/QLNet.Tests/T_Bonds.cs | 6 +-- - tests/QLNet.Tests/T_CapFlooredCoupon.cs | 14 +++---- - .../QLNet.Tests/T_InflationCapFlooredCouponTest.cs | 20 +++++----- - 4 files changed, 43 insertions(+), 43 deletions(-) - -commit 076dbf80b569a6963263388e7e439ee842fa2dac -Author: jiskin -Date: Tue Aug 1 15:19:08 2017 +0200 - - Issue with inheritance fixed - - .../Termstructures/Volatility/Optionlet/OptionletStripper.cs | 4 ++-- - .../Volatility/Optionlet/StrippedOptionletAdapter.cs | 11 ++++++++++- - .../Volatility/Optionlet/StrippedOptionletBase.cs | 4 +++- - 3 files changed, 15 insertions(+), 4 deletions(-) - -commit 18989c8118d09851c800edf5ecbdd3dcf8b4dca7 -Author: jiskin -Date: Wed Jul 26 16:48:35 2017 +0200 - - Add normal SABR interpolation test - - tests/QLNet.Tests/T_Interpolations.cs | 176 ++++++++++++++++++++++++++++++++++ - 1 file changed, 176 insertions(+) - -commit ff47598cff280cb330ebe8afccf9e54c263d42e2 -Author: jiskin -Date: Wed Jul 26 16:47:56 2017 +0200 - - Manage forward < 0 case - - src/QLNet/Termstructures/Volatility/Sabr.cs | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -commit 43ecafe581cdce6716e38a52c9459adf8f5874fd -Author: jiskin -Date: Wed Jul 26 16:47:12 2017 +0200 - - Manage forward < 0 case in normal SABR - - src/QLNet/Math/Interpolations/sabrinterpolation.cs | 53 +++++++++++++--------- - 1 file changed, 31 insertions(+), 22 deletions(-) - -commit 9cb5f3c9f838117535d39dbfb188a18e66776f87 -Author: jiskin -Date: Wed Jul 26 16:46:30 2017 +0200 - - Remove unnecessary .Create() call - - src/QLNet/Math/Interpolations/XABRInterpolation.cs | 72 +++++++++++----------- - 1 file changed, 36 insertions(+), 36 deletions(-) - -commit 59331a1ee83dea6222836dfe75f52964c591ab06 -Author: jiskin -Date: Tue Jul 25 11:33:29 2017 +0200 - - SABR Interpolation allows normal volatility - - src/QLNet/Math/Interpolations/sabrinterpolation.cs | 103 +++++++++++++++------ - 1 file changed, 76 insertions(+), 27 deletions(-) - -commit 82dd2072ff066c1d70b6ecf07a65d0002a5bb6ea -Author: jiskin -Date: Tue Jul 25 11:32:44 2017 +0200 - - New feature : add normal volatility interpolation to SABR - - src/QLNet/Termstructures/Volatility/Sabr.cs | 179 ++++++++++++++++++++++------ - 1 file changed, 143 insertions(+), 36 deletions(-) - -commit d20cb4cd130d3dc2a204ccf3d1da7495895722a4 -Author: jiskin -Date: Mon Jul 24 18:44:53 2017 +0200 - - optionDateFromTenor as virtual - - src/QLNet/Termstructures/voltermstructure.cs | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -commit dad42146cc4bb9891df1d6be2e38304f4fef8e15 -Author: jiskin -Date: Mon Jul 24 18:43:40 2017 +0200 - - Allow normal vol - - .../Volatility/swaption/swaptionconstantvol.cs | 60 ++++++++++++++++------ - 1 file changed, 45 insertions(+), 15 deletions(-) - -commit 9305341c1d75b4624dd263cd28b74cac429ecb7c -Author: jiskin -Date: Mon Jul 24 18:42:55 2017 +0200 - - Allow normal vol - - src/QLNet/Termstructures/Volatility/FlatSmileSection.cs | 17 ++++++++++------- - 1 file changed, 10 insertions(+), 7 deletions(-) - -commit d311f6403767cc4676b69ee4e390e92b9eee4c81 -Author: jiskin -Date: Mon Jul 24 18:42:14 2017 +0200 - - Allow normal vol - - .../Volatility/swaption/swaptionvolmatrix.cs | 330 ++++++++++++++++----- - 1 file changed, 263 insertions(+), 67 deletions(-) - -commit 1d804182412c28ac8791af6181eb8b694c1ee17a -Author: jiskin -Date: Mon Jul 24 18:38:41 2017 +0200 - - Add volatility type and shift - - .../Shortrate/calibrationhelpers/swaptionhelper.cs | 44 ++++++++++++++++------ - 1 file changed, 33 insertions(+), 11 deletions(-) - -commit 2a4c2c2cfd02c7efb7149d747c9a487860bb2be0 -Author: jiskin -Date: Mon Jul 24 18:37:25 2017 +0200 - - Add volatility type and shift - - src/QLNet/Models/CalibrationHelper.cs | 29 ++++++++++++++++++++--------- - 1 file changed, 20 insertions(+), 9 deletions(-) - -commit 3ac192d457539a0999c7907f328212bcaadb0acd -Author: jiskin -Date: Wed Jul 19 16:56:44 2017 +0200 +commit 0578d7f501bd2536e789f183a79a748ee8ce4748 +Author: tournierjc +Date: Fri Jan 19 17:12:06 2018 +0100 - Newtonsafe class wasn't public + Add files via upload - src/QLNet/Math/Solvers1d/Newtonsafe.cs | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + src/QLNet/Math/Interpolations/XABRInterpolation.cs | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) -commit 09f550742cc69174fae33b4cde2cf078a573f918 -Author: jiskin -Date: Mon Jul 17 14:18:14 2017 +0200 +commit c8cf9ba8e9125fef39e7cf91bfa2f1e850f81741 +Author: tournierjc +Date: Fri Jan 19 17:07:45 2018 +0100 - Set optionDateFromTenor as overridable + Add files via upload - src/QLNet/Termstructures/voltermstructure.cs | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + src/QLNet/Math/Interpolations/XABRInterpolation.cs | 76 +++++++++++----------- + 1 file changed, 37 insertions(+), 39 deletions(-) -commit 6b1aaa8b36fa1e8cae9cb7929a729a6cd5485e5f -Author: jiskin -Date: Mon Jul 17 14:17:39 2017 +0200 +commit beffca2767b8af5e72293d18d1021aa861268ec4 +Author: tournierjc +Date: Fri Jan 19 17:06:20 2018 +0100 - Update constant vol + Add a XABR Constraint class - Take into account the shift value + This way we can add constraint on the parameters - .../Volatility/swaption/swaptionconstantvol.cs | 60 ++++++++++++++++------ - 1 file changed, 45 insertions(+), 15 deletions(-) + src/QLNet/Math/Interpolations/XABRInterpolation.cs | 50 +++++++++++++++++++--- + 1 file changed, 44 insertions(+), 6 deletions(-) -commit d56f4cf416adfc94f0c5896bc49e7f6634ab74ec -Author: jiskin -Date: Mon Jul 17 14:15:54 2017 +0200 +commit b7bb9f442a20b3744eb822d4dec349ba9c06a325 +Author: tournierjc +Date: Fri Jan 19 16:40:17 2018 +0100 - Update Swaption Engine - - - Generic interface - - Black76 engine and Bachelier engine + jacobian matrix was not updated - .../Pricingengines/swaption/blackswaptionengine.cs | 355 ++++++++++++++------- - 1 file changed, 241 insertions(+), 114 deletions(-) + src/QLNet/Math/Optimization/lmdif.cs | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) -commit 24f0b0f13dba7caf2e41ebfa091fd7de1819647b -Author: jiskin -Date: Mon Jul 17 14:14:49 2017 +0200 +commit 87f92e22ce2cdb8442476ff66f117d1850003c61 +Author: tournierjc +Date: Fri Jan 19 14:30:53 2018 +0100 - Swaption instrument update + Missing register on discount curve - src/QLNet/Instruments/Swaption.cs | 22 ++++++++++++++++++---- - 1 file changed, 18 insertions(+), 4 deletions(-) + src/QLNet/Indexes/Swapindex.cs | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) -commit 75fcdb63f7f1b3f0f745b26a58ee63f2d8afdcd5 -Author: jiskin -Date: Mon Jul 17 14:13:18 2017 +0200 +commit 8cef39963e3e9c26e546887c9d524651311cf8c7 +Author: tournierjc +Date: Wed Jan 17 17:37:21 2018 +0100 - Put forwardValue method as virtual - - Allow to override in child class + Add files via upload - src/QLNet/Instruments/forward.cs | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + .../Inflation/PiecewiseYoYInflationCurve.cs | 207 ++++++++++---------- + .../Inflation/PiecewiseZeroInflationCurve.cs | 210 +++++++++++---------- + 2 files changed, 216 insertions(+), 201 deletions(-) -commit 047346e1d8bb832e3db911f090e6f81e0d618847 -Author: Francois Botha -Date: Thu Jun 15 17:32:54 2017 +0200 +commit b2b9a48ece79175264110badd5923cbee15b3066 +Merge: d064e8f e79b486 +Author: tournierjc +Date: Wed Jan 17 17:34:09 2018 +0100 - Implement DiscountingLoanEngine + Merge pull request #8 from amaggiulli/develop + + last commits - .../Pricingengines/Loan/DiscountingLoanEngine.cs | 44 ++++++++++++++++++++++ - 1 file changed, 44 insertions(+) +commit d064e8f96e455aeb08943e139c019aa049717f3d +Author: tournierjc +Date: Tue Jan 16 19:00:46 2018 +0100 -commit d14bcd1d6bcfe7b483819a1cbf97d65114f620c8 -Author: jiskin -Date: Wed May 17 14:31:13 2017 +0200 + calculate before having baseDate - Update SVI Interpolation with addParam input + .../Inflation/PiecewiseYoYInflationCurve.cs | 207 ++++++++++---------- + .../Inflation/PiecewiseZeroInflationCurve.cs | 210 ++++++++++----------- + 2 files changed, 201 insertions(+), 216 deletions(-) - src/QLNet/Math/Interpolations/SviInterpolation.cs | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) +commit d76e254f2540454d154ed89d4b1f266fcfc3a620 +Author: tournierjc +Date: Tue Jan 16 13:34:42 2018 +0100 -commit 2cce4390c9a477c00567eefb5e5d604f86b6587b -Author: jiskin -Date: Wed May 17 14:25:59 2017 +0200 + Delete VanillaSwap.cs - Add sabr interpolated to project file + VanillaSwap.cs | 333 --------------------------------------------------------- + 1 file changed, 333 deletions(-) - src/QLNet.Old/QLNet.Old.csproj | 3 +++ - 1 file changed, 3 insertions(+) +commit e79b4861833ac6e8ae3aedc33b69633709285081 +Author: Andrea Maggiulli +Date: Wed Dec 27 17:20:44 2017 +0100 -commit 42d4102f849a60380dfdb4389e1f2e31ba29fec1 -Author: jiskin -Date: Wed May 17 14:25:17 2017 +0200 + Fixed Sonar Vulnerability issues. - Add Sabr Interpolated + update sabr & svi + src/QLNet/Instruments/FloatFloatSwap.cs | 48 ++++++++++++++++++++++----------- + 1 file changed, 33 insertions(+), 15 deletions(-) - src/QLNet/Termstructures/Volatility/Sabr.cs | 34 ++++ - .../Volatility/SabrInterpolatedSmileSection.cs | 198 +++++++++++++++++++++ - 2 files changed, 232 insertions(+) +commit 69b622772f2d5a955e0fa3e4b60194e717d2453d +Author: Andrea Maggiulli +Date: Wed Dec 27 13:03:11 2017 +0100 -commit a4d381d7543a4543faee5138214436106ddcd46c -Author: jiskin -Date: Wed May 17 14:23:59 2017 +0200 + Added new instrument FloatFloatSwap, with CmsSpreadCoupon and SwapSpreadIndex. - Add shift to SABR & XABR + src/QLNet/Cashflows/CmsSpreadCoupon.cs | 108 +++++ + src/QLNet/Indexes/swap/SwapSpreadIndex.cs | 113 ++++++ + src/QLNet/Instruments/FloatFloatSwap.cs | 653 ++++++++++++++++++++++++++++++ + 3 files changed, 874 insertions(+) - src/QLNet/Math/Interpolations/XABRInterpolation.cs | 39 ++++++++------- - src/QLNet/Math/Interpolations/sabrinterpolation.cs | 56 ++++++++++++++-------- - 2 files changed, 57 insertions(+), 38 deletions(-) +commit ef91d43fb5357d876ff15a246a7e4ee43e7e4e0b +Author: Andrea Maggiulli +Date: Thu Dec 21 17:12:38 2017 +0100 -commit 8ca8570bfc78b8b0b71f4b44f29faf91e0ede085 -Merge: 6d085c4 5c50127 -Author: jiskin -Date: Wed May 17 12:09:09 2017 +0200 + Sonar links updated [skip ci] - Merge pull request #4 from amaggiulli/develop - - merge svi bug fix + README.md | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) -commit 5c50127000c7c0eb7ed73605ab84e4d600b863a9 +commit 497826fa9fbaeba95da15bd7c90790cfa9c93a03 Author: Andrea Maggiulli -Date: Tue May 16 18:27:59 2017 +0200 +Date: Thu Dec 21 16:31:19 2017 +0100 - Sonar fix : removed useless assignment to local variable 'j' + Fixed Sonar Vulnerability issues. - src/QLNet/Math/Interpolations/SviInterpolation.cs | 2 +- + src/QLNet/Math/Optimization/DifferentialEvolution.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -commit 39ffb948f39711fabed076eba1bf9c032af0a5aa -Merge: ed1181a 0f55bae +commit 8c43b93a546606e458cccc1e0983c5b4af9f883b Author: Andrea Maggiulli -Date: Tue May 16 14:36:56 2017 +0200 - - Merge pull request #155 from jiskin/SonarQube_SVI_Fix - - SonarQube Issue fix on SVI PR - -commit 0f55bae9b0e522e33a1389bfac81bb0fa492951e -Author: jiskin -Date: Tue May 16 14:25:52 2017 +0200 - - Fix SonarQube issue on SVI Volatility +Date: Thu Dec 21 16:10:24 2017 +0100 - .../Termstructures/Volatility/SviInterpolatedSmileSection.cs | 12 ++++++------ - src/QLNet/Termstructures/Volatility/SviSmileSection.cs | 4 ++-- - 2 files changed, 8 insertions(+), 8 deletions(-) + Fixed Sonar Vulnerability issues. -commit 4b579a92a2987c0bf98480550104276f9fa65517 -Author: jiskin -Date: Tue May 16 14:25:19 2017 +0200 + .../Math/Optimization/DifferentialEvolution.cs | 28 +++++++++++----------- + 1 file changed, 14 insertions(+), 14 deletions(-) - Fix SonarQube issue on SVI Interpolation - - src/QLNet/Math/Interpolations/SviInterpolation.cs | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -commit ba47fcdbe1264277115b3a1ed4c456cabbca6a5b -Author: jiskin -Date: Tue May 16 14:24:42 2017 +0200 +commit 9fb1100d3a0c2bb3c455ff6eca8f1cc6170a59ae +Author: Andrea Maggiulli +Date: Thu Dec 21 12:00:34 2017 +0100 - Fix Count() + Cleanup - tests/QLNet.Tests/T_SVI.cs | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) + src/QLNet/Cashflows/CappedFlooredCoupon.cs | 37 +- + .../Math/Optimization/DifferentialEvolution.cs | 1021 ++++++++++---------- + src/QLNet/Math/Optimization/SimulatedAnnealing.cs | 514 +++++----- + 3 files changed, 817 insertions(+), 755 deletions(-) -commit 6d085c4e1e7a6ccb519aba82f0e0da8f33c81b80 -Merge: 17bf67d ed1181a -Author: jiskin -Date: Tue May 16 14:24:06 2017 +0200 +commit cd95b0e8aabb3727d8213d20369dac851e7de3db +Merge: d2b7a1f 726596e +Author: Andrea Maggiulli +Date: Thu Dec 21 11:45:48 2017 +0100 - Merge pull request #3 from amaggiulli/develop + Merge pull request #187 from tournierjc/BugFixProjectedConstraint - Add SVI Interpolation + Smile section + Bug fix projected constraint -commit ed1181a5f06d287ba73998a86b5033ee866017d6 -Merge: 6b0a879 7b16c24 -Author: Andrea Maggiulli -Date: Tue May 16 13:53:22 2017 +0200 +commit d2b7a1f9120acac353cc0347ddcd0ac110fbcd0b +Merge: 41adf31 152d0cd +Author: Andrea Maggiulli +Date: Thu Dec 21 10:58:00 2017 +0100 - Merge pull request #153 from jiskin/add_svi + Merge pull request #186 from tournierjc/Port_DifferentialEvolution - Port SVI Interpolation + SmileSection from QuantLib - -commit 7b16c248c324594d3fdf3626e902411ac642a811 -Author: jiskin -Date: Tue May 16 13:21:45 2017 +0200 + Ported Differential Evolution - Update QLNet Test old project file +commit 152d0cde8e685d57b86ceb57f49a86a07ff39110 +Merge: 630c999 41adf31 +Author: Andrea Maggiulli +Date: Thu Dec 21 10:57:32 2017 +0100 - tests/QLNet.Tests.Old/QLNet.Tests.Old.csproj | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) + Merge branch 'develop' into Port_DifferentialEvolution -commit 3a98951ae71d31a7407348fff4f55387f078d932 -Author: jiskin -Date: Tue May 16 13:21:19 2017 +0200 +commit 630c999f71b36ff1571d81c2d7280b5919b428ee +Merge: aaf40b6 41adf31 +Author: Andrea Maggiulli +Date: Thu Dec 21 10:56:08 2017 +0100 - Update QLNet old project file + Merge branch 'develop' into Port_DifferentialEvolution - src/QLNet.Old/QLNet.Old.csproj | 12 ++++++++++++ - 1 file changed, 12 insertions(+) +commit 41adf3125036694ac8d041c2b34be5203f8f2ff6 +Merge: cf02901 33cd9fd +Author: Andrea Maggiulli +Date: Thu Dec 21 10:30:07 2017 +0100 -commit ce701aefab03b8456fe848adf90dc9a5c02b0082 -Author: jiskin -Date: Tue May 16 12:27:36 2017 +0200 - - Add SVI Interpolated or not smile section - - src/QLNet/Termstructures/Volatility/Svi.cs | 58 ++++++ - .../Volatility/SviInterpolatedSmileSection.cs | 201 +++++++++++++++++++++ - .../Termstructures/Volatility/SviSmileSection.cs | 70 +++++++ - 3 files changed, 329 insertions(+) - -commit 9c6b08f295ad95140515bcb5b39bd1a88d304002 -Author: jiskin -Date: Tue May 16 12:26:57 2017 +0200 - - Add SVI Interpolation class + Merge pull request #184 from tournierjc/Port_SimulatedAnnealing + + Port simulated annealing - src/QLNet/Math/Interpolations/SviInterpolation.cs | 223 ++++++++++++++++++++++ - 1 file changed, 223 insertions(+) +commit 33cd9fd1bff75a5124eaa81c6e3fc2b00a203b83 +Merge: 6827380 cf02901 +Author: Andrea Maggiulli +Date: Thu Dec 21 10:28:50 2017 +0100 -commit 6407ce9294ccf286ae1f70acf1de019f96d92b0d -Author: jiskin -Date: Tue May 16 12:13:28 2017 +0200 + Merge branch 'develop' into Port_SimulatedAnnealing - Add test for SVI Calibration +commit 6827380553d60d2ebf85e0881a86a2d9bd0fce43 +Merge: ce84a80 cf02901 +Author: Andrea Maggiulli +Date: Thu Dec 21 10:26:43 2017 +0100 - tests/QLNet.Tests/T_SVI.cs | 125 +++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 125 insertions(+) + Merge branch 'develop' into Port_SimulatedAnnealing -commit 17bf67d5cec940c20fc2250ae4241ad30c0cf0bc -Merge: 22860fe 6b0a879 -Author: jiskin -Date: Mon May 15 10:27:59 2017 +0200 +commit cf02901a52452dc4fc19552c241cb2da7c8eda67 +Merge: 0f61ba3 748c278 +Author: Andrea Maggiulli +Date: Wed Dec 20 17:39:27 2017 +0100 - Merge pull request #2 from amaggiulli/develop + Merge pull request #185 from igitur/botswana-calendar - merge + Added Botswana calendar -commit 6b0a87925a708ebe9d895ea5c339e6346ffd95dc +commit 0f61ba3a1c70660eda7515892eddb85e403a1007 +Merge: c83d695 0d1b15b Author: Andrea Maggiulli -Date: Thu May 11 18:11:14 2017 +0200 - - Cpi bug fix, thx @jiskin. Close #135 +Date: Wed Dec 20 16:03:10 2017 +0100 - src/QLNet/Instruments/CPISwap.cs | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) + Merge branch 'develop' of https://github.com/amaggiulli/qlnet into develop -commit edbef7cb4e420952d9a0f3c128f02b750294263e -Merge: 78f929b 88652ad +commit c83d6952c5bc953f6ef9306cfd6ccca98f095242 Author: Andrea Maggiulli -Date: Thu May 11 15:39:22 2017 +0200 - - Merge pull request #150 from jiskin/MakeCms_AddIborGearing +Date: Wed Dec 20 16:02:48 2017 +0100 + + Index manager refactoring . Notice index name is ALWAYS uppercase. This close #182 + + src/QLNet/Cashflows/DigitalCoupon.cs | 2 +- + src/QLNet/Cashflows/OvernightIndexedCoupon.cs | 4 +- + src/QLNet/Index.cs | 16 +-- + src/QLNet/Indexes/Indexmanager.cs | 174 +++++++++++++++++--------- + src/QLNet/Indexes/InflationIndex.cs | 28 ++--- + src/QLNet/Indexes/InterestRateIndex.cs | 4 +- + src/QLNet/Quotes/LastFixingQuote.cs | 4 +- + tests/QLNet.Tests/T_ShortRateModels.cs | 10 +- + 8 files changed, 148 insertions(+), 94 deletions(-) + +commit 0d1b15b9460cc98568cb0b7cef3c86575b72b26d +Merge: d2b2ae7 e91cea3 +Author: Andrea Maggiulli +Date: Wed Dec 20 14:27:21 2017 +0100 + + Merge pull request #181 from tournierjc/BugFixSwapIndex - Add gearing interface for CMS and Floating legs + Bug fix swap index -commit 78f929be0da0cd00701abeef77b9ef65cabf5e4d -Merge: 4b555ed 6f1e9f9 -Author: Andrea Maggiulli -Date: Thu May 11 15:25:29 2017 +0200 +commit 731ccfe4d6392dbbc53b6920208d2ac6fac56676 +Author: tournierjc +Date: Fri Dec 8 12:29:35 2017 +0100 - Merge pull request #149 from jiskin/Swap_AddNewPropertyRetriever - - Retrieve payer information for each leg + Add files via upload -commit 22860fecf3834ff5ae98d4fd8b85fc29834d0725 -Merge: 835befc 4b555ed -Author: jiskin -Date: Thu May 4 23:30:19 2017 +0200 + VanillaSwap.cs | 333 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 333 insertions(+) - Merge pull request #1 from amaggiulli/develop - - Fix inflation +commit aaf40b6e4778edcc499bd19fa68b0e20e4489107 +Author: tournierjc +Date: Wed Dec 6 10:59:31 2017 +0100 -commit 88652ad57677710939f8450ef824da7d904cf2c7 -Author: jiskin -Date: Thu May 4 17:03:59 2017 +0200 + Manage NaN case - Add gearing interface for CMS and Floating legs + .../Math/Optimization/DifferentialEvolution.cs | 47 +++++----------------- + 1 file changed, 11 insertions(+), 36 deletions(-) - src/QLNet/Instruments/MakeCms.cs | 16 ++++++++++++++-- - 1 file changed, 14 insertions(+), 2 deletions(-) +commit 726596ef18bbb254c8dd7e6d3adb8b1b48108327 +Author: tournierjc +Date: Fri Dec 1 14:38:41 2017 +0100 -commit 6f1e9f935b857ea84963cf9eafdb44bc17bac1c1 -Author: jiskin -Date: Thu May 4 16:59:49 2017 +0200 + Add files via upload - Retrieve payer information for each leg + src/QLNet/Math/Optimization/Constraint.cs | 16 +++++++++++++--- + src/QLNet/Math/Optimization/ProjectedConstraint.cs | 6 +++--- + 2 files changed, 16 insertions(+), 6 deletions(-) - src/QLNet/Instruments/Swap.cs | 6 ++++++ - 1 file changed, 6 insertions(+) +commit 610009eed1e1f0ae5520f8c4408831846175273e +Author: tournierjc +Date: Fri Nov 17 17:07:48 2017 +0100 -commit 4b555ed608d160f334f459651a8627e9c9b083ea -Merge: e4b1028 53a9f3f -Author: Andrea Maggiulli -Date: Thu May 4 15:18:13 2017 +0200 + Remove unecessary header - Merge pull request #147 from igitur/ICloneable-reference-fix - - ICloneable references + src/QLNet/Methods/Finitedifferences/Utilities/ListUtils.cs | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) -commit 53a9f3f7acfa6c93ffa3b4c2e353a87d3fe8a644 -Author: Andrea Maggiulli -Date: Thu May 4 15:17:30 2017 +0200 +commit d4385e51f9d87cceda3d8a9466d3a9e05aa9455a +Author: tournierjc +Date: Fri Nov 17 17:03:27 2017 +0100 - Update T_Vector.cs + Update old project file - tests/QLNet.Tests/T_Vector.cs | 1 + - 1 file changed, 1 insertion(+) + src/QLNet.Old/QLNet.Old.csproj | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) -commit e4b1028ffcaefda638537ee0fa6673b70aed1b55 -Author: Andrea Maggiulli -Date: Thu May 4 14:37:29 2017 +0200 +commit 61697f9381e5db68aece656fe22d813d0abc2fe1 +Author: tournierjc +Date: Fri Nov 17 17:01:39 2017 +0100 - Fixed InflationIndex.needsForecast, testZeroTermStructure test and PiecewiseZeroInflationCurve.maxDate. - Thanks @igitur and @jiskin for finding and fixing. Close #146 + Update optimizer tests for Differential Evolution - src/QLNet/Indexes/InflationIndex.cs | 2 +- - .../Inflation/InterpolatedZeroInflationCurve.cs | 14 ++++++++++---- - .../Inflation/PiecewiseZeroInflationCurve.cs | 16 +++++++++++----- - tests/QLNet.Tests/T_Inflation.cs | 4 ++-- - 4 files changed, 24 insertions(+), 12 deletions(-) + tests/QLNet.Tests/T_Optimizers.cs | 193 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 193 insertions(+) -commit c3cc66d875f38b0b711b1dd0418110db0ad2fba2 -Author: Andrea Maggiulli -Date: Thu May 4 14:32:56 2017 +0200 +commit 6a7a626e5260cc07c9a07c8460f4d3db47bb623c +Author: tournierjc +Date: Fri Nov 17 17:00:35 2017 +0100 - Update T_Vector.cs - - removed unused reference + Add Differential Evolution algorithm - tests/QLNet.Tests/T_Vector.cs | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) + .../Math/Optimization/DifferentialEvolution.cs | 579 +++++++++++++++++++++ + 1 file changed, 579 insertions(+) -commit c628d8c904cd78c1de24a14c20888099bb706b17 -Author: Francois Botha -Date: Thu May 4 12:56:30 2017 +0200 +commit 6729342b346e1f08dd281d3a05b0881b0aab6d37 +Author: tournierjc +Date: Fri Nov 17 16:59:28 2017 +0100 - Boolean logic fix for when to implement ICloneable interface. The interface is already available in .NET40 and .NET45 + Add shuffle function for IList - src/QLNet/Utils.cs | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + .../Finitedifferences/Utilities/ListUtils.cs | 35 +++++++++++++++++++++- + 1 file changed, 34 insertions(+), 1 deletion(-) -commit fbb760578f3f224cead0ed0c50379f6944a8b9ea +commit 748c278e89abc463dc4e8b771895da72d5eacb52 Author: Francois Botha -Date: Thu May 4 12:34:37 2017 +0200 - - Don't reference ICloneable using namespace, or it will fail for NET40 build. +Date: Fri Nov 17 12:14:44 2017 +0200 - tests/QLNet.Tests/T_Vector.cs | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) + Add Botswana calendar -commit 8141b66969826140f647fe136f5105304fb4a413 -Author: Andrea Maggiulli -Date: Fri Apr 28 16:26:40 2017 +0200 + src/QLNet.Old/QLNet.Old.csproj | 3 + + src/QLNet/Time/Calendars/botswana.cs | 110 +++++++++++++++++++++++++++++++++++ + 2 files changed, 113 insertions(+) - Removed unnecessary cast. +commit ce84a80f9c41f960a2e38d947fcfc5966cc66b14 +Author: tournierjc +Date: Tue Nov 14 15:05:25 2017 +0100 - src/QLNet/Math/Optimization/ArmijoLineSearch.cs | 2 +- - src/QLNet/Math/Optimization/problem.cs | 4 ++-- - src/QLNet/Math/SampledCurve.cs | 12 ++++++------ - src/QLNet/Math/transformedgrid.cs | 6 +++--- - src/QLNet/Methods/Finitedifferences/TridiagonalOperator.cs | 8 ++++---- - src/QLNet/Methods/montecarlo/path.cs | 2 +- - 6 files changed, 17 insertions(+), 17 deletions(-) + Add files via upload -commit 835befc29c2d1c52b81b1a2e0ac10ef0b0574544 -Author: Andrea Maggiulli -Date: Fri Apr 28 15:55:33 2017 +0200 + src/QLNet.Old/QLNet.Old.csproj | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) - Removed Vector operator == overload , XML doc and a new test. +commit 222e311e4dbbf17c74c26889e21c22126611d4ad +Author: tournierjc +Date: Tue Nov 14 15:04:38 2017 +0100 - src/QLNet/Math/Vector.cs | 74 +++++++++++++++++++++++++++++-------------- - tests/QLNet.Tests/T_Vector.cs | 20 ++++++++++-- - 2 files changed, 69 insertions(+), 25 deletions(-) + Add files via upload -commit 0d319c22ed4a1f9dc8773836a25b7dc768efbcf9 -Author: Andrea Maggiulli -Date: Fri Apr 28 14:22:45 2017 +0200 + src/QLNet/Math/Optimization/SimulatedAnnealing.cs | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) - Fixed Vector Clone and Equals with tests. +commit de1d698030466f395e4b80e38bbe0989900acb66 +Author: tournierjc +Date: Tue Nov 14 14:20:29 2017 +0100 - src/QLNet/Math/Vector.cs | 34 +++++++--- - tests/QLNet.Tests.Old/QLNet.Tests.Old.csproj | 1 + - tests/QLNet.Tests/T_Vector.cs | 98 ++++++++++++++++++++++++++++ - tests/QLNet.Tests/Utilities.cs | 45 +++++++++++++ - 4 files changed, 169 insertions(+), 9 deletions(-) + Add files via upload -commit 7ff1dec239b6667093ce430b93b4b208eda6f7cc -Author: Andrea Maggiulli -Date: Thu Apr 27 17:36:49 2017 +0200 + src/QLNet.Old/QLNet.Old.csproj | 4199 ++++++++++++++++++++-------------------- + 1 file changed, 2101 insertions(+), 2098 deletions(-) - Removed useless optional parameter. +commit db7b7fa19374e40a4385104ebe0b8b42b3030a46 +Author: tournierjc +Date: Tue Nov 14 14:09:20 2017 +0100 - src/QLNet/Termstructures/Inflation/InterpolatedYoYInflationCurve.cs | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + Add files via upload -commit a2abf0f4d7d1d7754c94445255165d86b33e4502 -Author: Andrea Maggiulli -Date: Thu Apr 27 17:36:03 2017 +0200 + src/QLNet/Math/Optimization/Constraint.cs | 16 +- + src/QLNet/Math/Optimization/CostFunction.cs | 13 +- + src/QLNet/Math/Optimization/Simplex.cs | 2 +- + src/QLNet/Math/Optimization/SimulatedAnnealing.cs | 275 ++++++++++++++++++++++ + src/QLNet/Math/Optimization/problem.cs | 3 +- + 5 files changed, 301 insertions(+), 8 deletions(-) - Code formatted. +commit fa376549cb17d5309c7f4f2e4316ea8c35c39216 +Author: tournierjc +Date: Tue Nov 14 14:08:48 2017 +0100 - src/QLNet/Math/Matrix.cs | 672 ++++++++++++++++++++++++++--------------------- - src/QLNet/Math/Vector.cs | 332 +++++++++++++---------- - 2 files changed, 574 insertions(+), 430 deletions(-) + Add files via upload -commit c7e8c19ac242085ff584ce6f1fc6fd477e6100c4 -Author: Andrea Maggiulli -Date: Thu Apr 27 12:05:05 2017 +0200 + src/QLNet/Math/Interpolations/KernelInterpolation2D.cs | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) - Fixed QLNet.Old file name. [skip ci] +commit b8c1cc7a71e40a12a201990b5f5a8643d5e45f85 +Author: tournierjc +Date: Tue Nov 14 14:08:19 2017 +0100 - src/QLNet.Old/QLNet.Old.csproj | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + Add files via upload -commit f6fad63c9e9761ec504bb1da4a7bb470a35f1475 -Author: Andrea Maggiulli -Date: Wed Apr 26 18:34:03 2017 +0200 + src/QLNet.Old/QLNet.Old.csproj | 4197 ++++++++++++++++++++-------------------- + 1 file changed, 2099 insertions(+), 2098 deletions(-) - TEST : sonar complain about cashflow.cs., it's just a test to see if the problem is the file name . +commit 2e361187bd3fba3816fefd73deab1f5b300deab2 +Author: tournierjc +Date: Tue Nov 14 14:07:47 2017 +0100 - src/QLNet/{Cashflow.cs => CashflowBase.cs} | 0 - 1 file changed, 0 insertions(+), 0 deletions(-) + Delete MakeOIS.cs -commit ba428b56f850a5ce6ffd83088d0e9abd9a5c5180 -Author: Andrea Maggiulli -Date: Wed Apr 26 15:06:28 2017 +0200 + MakeOIS.cs | 270 ------------------------------------------------------------- + 1 file changed, 270 deletions(-) - Fixed Sonar vulnerabilities. +commit 775f6eb5298c71ca8fee0288ec6e86d96d957cdd +Merge: 2479113 d2b2ae7 +Author: tournierjc +Date: Tue Nov 14 14:06:46 2017 +0100 - src/QLNet/Instruments/BasisSwap.cs | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) + Merge pull request #6 from amaggiulli/develop + + Schedule : more accurate effective date. -commit aa8e685477d85da7b773e24611ea233d2101fb53 -Author: Andrea Maggiulli -Date: Wed Apr 26 14:24:31 2017 +0200 - - Restored old solution folders, added empty folders [skip ci] - - src/QLNet.Old/Cashflows/.gitkeep | 0 - src/QLNet.Old/Currencies/.gitkeep | 0 - src/QLNet.Old/Extensions/.gitkeep | 0 - src/QLNet.Old/Indexes/Ibor/.gitkeep | 0 - src/QLNet.Old/Indexes/Inflation/.gitkeep | 0 - src/QLNet.Old/Indexes/Swap/.gitkeep | 0 - src/QLNet.Old/Instruments/Bonds/.gitkeep | 0 - src/QLNet.Old/Math/Distributions/.gitkeep | 0 - src/QLNet.Old/Math/Interpolations/.gitkeep | 0 - src/QLNet.Old/Math/Optimization/.gitkeep | 0 - src/QLNet.Old/Math/Solvers1d/.gitkeep | 0 - src/QLNet.Old/Math/integrals/.gitkeep | 0 - src/QLNet.Old/Math/matrixutilities/.gitkeep | 0 - src/QLNet.Old/Math/randomnumbers/.gitkeep | 0 - src/QLNet.Old/Math/statistics/.gitkeep | 0 - src/QLNet.Old/Methods/Finitedifferences/.gitkeep | 0 - src/QLNet.Old/Methods/lattices/.gitkeep | 0 - src/QLNet.Old/Methods/montecarlo/.gitkeep | 0 - src/QLNet.Old/Models/Equity/.gitkeep | 0 - src/QLNet.Old/Models/MarketModels/BrownianGenerators/.gitkeep | 0 - src/QLNet.Old/Models/Shortrate/Onefactormodels/.gitkeep | 0 - src/QLNet.Old/Models/Shortrate/Twofactorsmodels/.gitkeep | 0 - src/QLNet.Old/Models/Shortrate/calibrationhelpers/.gitkeep | 0 - src/QLNet.Old/Patterns/.gitkeep | 0 - src/QLNet.Old/Pricingengines/Basket/.gitkeep | 0 - src/QLNet.Old/Pricingengines/Bond/.gitkeep | 0 - src/QLNet.Old/Pricingengines/CapFloor/.gitkeep | 0 - src/QLNet.Old/Pricingengines/Cliquet/.gitkeep | 0 - src/QLNet.Old/Pricingengines/Forward/.gitkeep | 0 - src/QLNet.Old/Pricingengines/Loan/.gitkeep | 0 - src/QLNet.Old/Pricingengines/Lookback/.gitkeep | 0 - src/QLNet.Old/Pricingengines/Swap/.gitkeep | 0 - src/QLNet.Old/Pricingengines/asian/.gitkeep | 0 - src/QLNet.Old/Pricingengines/barrier/.gitkeep | 0 - src/QLNet.Old/Pricingengines/credit/.gitkeep | 0 - src/QLNet.Old/Pricingengines/inflation/.gitkeep | 0 - src/QLNet.Old/Pricingengines/swaption/.gitkeep | 0 - src/QLNet.Old/Pricingengines/vanilla/.gitkeep | 0 - src/QLNet.Old/Quotes/.gitkeep | 0 - src/QLNet.Old/Termstructures/Credit/.gitkeep | 0 - src/QLNet.Old/Termstructures/Inflation/.gitkeep | 0 - src/QLNet.Old/Termstructures/Volatility/Bond/.gitkeep | 0 - src/QLNet.Old/Termstructures/Volatility/CapFloor/.gitkeep | 0 - src/QLNet.Old/Termstructures/Volatility/Inflation/.gitkeep | 0 - src/QLNet.Old/Termstructures/Volatility/Optionlet/.gitkeep | 0 - src/QLNet.Old/Termstructures/Volatility/equityfx/.gitkeep | 0 - src/QLNet.Old/Termstructures/Volatility/swaption/.gitkeep | 0 - src/QLNet.Old/Termstructures/Yield/.gitkeep | 0 - src/QLNet.Old/Time/Calendars/.gitkeep | 0 - src/QLNet.Old/Time/DayCounters/.gitkeep | 0 - src/QLNet.Old/legacy/libormarketmodels/.gitkeep | 0 - src/QLNet.Old/processes/.gitkeep | 0 - 52 files changed, 0 insertions(+), 0 deletions(-) - -commit 51f9c6b64880db323c45c187d5c4b49f62f508a8 -Author: Andrea Maggiulli -Date: Wed Apr 26 14:13:04 2017 +0200 +commit 2479113619684541cb2205730cdf3e689c37f783 +Author: tournierjc +Date: Mon Nov 13 12:49:15 2017 +0100 - Added Interpolated YoY Inflation Curve. Close #136 + Add files via upload - src/QLNet.Old/QLNet.Old.csproj | 3 + - .../Inflation/InterpolatedYoYInflationCurve.cs | 161 +++++++++++++++++++++ - 2 files changed, 164 insertions(+) + MakeOIS.cs | 270 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 270 insertions(+) -commit 98b0fadd6721891c8ba70ac91735f3affed47741 +commit d2b2ae71a4e867d4f8309fe3d1cc551e87fbf1fc Author: Andrea Maggiulli -Date: Wed Apr 26 14:04:04 2017 +0200 +Date: Tue Oct 31 18:21:03 2017 +0100 - Added Basis swap helper for yield curve bootstrapping. Close #142 + Schedule : more accurate effective date. - src/QLNet.Old/QLNet.Old.csproj | 3 + - src/QLNet/Instruments/BasisSwap.cs | 56 ++++++- - src/QLNet/Termstructures/Yield/BasisSwapHelper.cs | 182 ++++++++++++++++++++++ - 3 files changed, 240 insertions(+), 1 deletion(-) + src/QLNet/Time/Schedule.cs | 5 +++++ + 1 file changed, 5 insertions(+) -commit 1c689854edbb90cb297cd0d5331c3f4668c6634d -Author: Andrea Maggiulli -Date: Wed Apr 26 13:59:21 2017 +0200 +commit e91cea3569c7d17217e423e8a63de2bb01e44a91 +Author: tournierjc +Date: Mon Oct 30 16:30:14 2017 +0100 - Restored old solution folders [skip ci] + Call to base constructor is missing - src/QLNet.Old/QLNet.Old.csproj | 2291 ++++++++++++++++++++++++++++++---------- - 1 file changed, 1720 insertions(+), 571 deletions(-) \ No newline at end of file + src/QLNet/Indexes/Swapindex.cs | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..d54fa6196 --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause QLNet License + +Copyright (c) 2018, Andrea Maggiulli +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/News.txt b/News.txt index 3e33169b0..4ac9dbb88 100644 --- a/News.txt +++ b/News.txt @@ -1,48 +1,44 @@ -QLNet 1.10.0 +QLNet 1.11.0 ========================= -QLNet 1.10.0 stable version. - +QLNet 1.11.0 stable version includes 91 pull requests . The most notable changes are included below. A detailed list of changes is available in ChangeLog.txt. ENGINES -+ Added DiscountingLoanEngine -+ Updated Swaption Engine -+ Added IsdaCdsEngine, InterpolatedSurvivalProbabilityCurve and SurvivalProbabilityStructure with test -+ Added AnalyticDoubleBarrierBinaryEngine and BinomialDoubleBarrierEngine -+ Added HW swaption engine ++ Added raw calculation for WeightedAverageLife given a list of dates and a list of amounts. FRAMEWORK -+ Updated documentation to standard XML format -+ Updated to net standard 2.0 -+ Several bug fixes ++ Added Artistic Style 3.1 tool for formatting code. ++ Uniformed file names to CamelCase standard TERMSTRUCTURES -+ Added Interpolated YoY Inflation Curve -+ Added normal volatility interpolation to SABR ++ Implement CompositeZeroYieldStructure TIME - + Updated Schedule for CDS2015 with test. - + Updated Actual360 daycounter to include/exclude last day + + Add Botswana calendar INSTRUMENTS -+ Add gearing interface for CMS and Floating legs -+ Swaption instrument update -+ Updated bonds constructors -+ Added Finite differences method -+ Updated CreditDefaultSwap + helper ++ Added new instrument FloatFloatSwap, with CmsSpreadCoupon and SwapSpreadIndex. ++ Added Kirk Option Engine with test. ++ Fixed bug in Vanna-Volga method for double barrier knock in options. MATH -+ Add SVI Interpolation class -+ Add shift to SABR & XABR ++ Add Differential Evolution algorithm ++ Add a XABR Constraint class ++ Add LevenbergMarquardt precondition checks + +INDEXES + ++ Updated day count convention and spot lag by CAD fixings. CASHFLOWS -+ Added LastPeriodDayCounter to FixedRateCoupon \ No newline at end of file ++ Updated BlackVanillaOptionPricer constructor, check volatility type and shift. ++ Added Range Accrual tests and fixed 2 bugs on RangeAccrual and InterpolatedSmileSection \ No newline at end of file diff --git a/README.md b/README.md index a28cceffd..18614c059 100644 --- a/README.md +++ b/README.md @@ -9,16 +9,16 @@ QLNet also contains new developments on the bond market like MBS, Amortized Cost [![Build status](https://ci.appveyor.com/api/projects/status/iii1m7n3cdq3v5xm?svg=true)](https://ci.appveyor.com/project/amaggiulli/qlnet) [![NuGet](https://buildstats.info/nuget/qlnet)](https://www.nuget.org/packages/qlnet/) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?item_name=Donation+to+QLNet&cmd=_donations&business=a.maggiulli%40gmail.com) -[![Quality Gate](https://sonarqube.com/api/badges/gate?key=QLNet-develop)](https://sonarqube.com/dashboard/index?id=QLNet-develop) -[![Bugs](https://sonarqube.com/api/badges/measure?key=QLNet-develop&metric=bugs)](https://sonarqube.com/component_issues?id=QLNet-develop#types=BUG|resolved=false) -[![Vulnerabilities](https://sonarqube.com/api/badges/measure?key=QLNet-develop&metric=vulnerabilities)](https://sonarqube.com/component_issues?id=QLNet-develop#resolved=false|types=VULNERABILITY) -[![Code Smells](https://sonarqube.com/api/badges/measure?key=QLNet-develop&metric=code_smells)](https://sonarqube.com/component_issues?id=QLNet-develop#resolved=false|types=CODE_SMELL) -[![Duplicated Lines](https://sonarqube.com/api/badges/measure?key=QLNet-develop&metric=duplicated_lines_density)](https://sonarqube.com/component_measures/metric/duplicated_lines_density/treemap?id=QLNet-develop) -[![Blocker Issues](https://sonarqube.com/api/badges/measure?key=QLNet-develop&metric=blocker_violations)](https://sonarqube.com/component_issues/?id=QLNet-develop#resolved=false|severities=BLOCKER) -[![Critical Issues](https://sonarqube.com/api/badges/measure?key=QLNet-develop&metric=critical_violations)](https://sonarqube.com/component_issues?id=QLNet-develop#resolved=false|severities=CRITICAL) -[![Major Issues](https://sonarqube.com/api/badges/measure?key=QLNet-develop&metric=major_violations)](https://sonarqube.com/component_issues?id=QLNet-develop#resolved=false|severities=MAJOR) -[![Minor Issues](https://sonarqube.com/api/badges/measure?key=QLNet-develop&metric=minor_violations)](https://sonarqube.com/component_issues?id=QLNet-develop#resolved=false|severities=MINOR) -[![Technical Debt](https://sonarqube.com/api/badges/measure?key=QLNet-develop&metric=sqale_debt_ratio)](https://sonarqube.com/dashboard?id=QLNet-develop) +[![Quality Gate](https://sonarqube.com/api/badges/gate?key=QLNet-develop)](https://sonarcloud.io/dashboard?id=QLNet-develop) +[![Bugs](https://sonarqube.com/api/badges/measure?key=QLNet-develop&metric=bugs)](https://sonarcloud.io/project/issues?id=QLNet-develop&resolved=false&types=BUG) +[![Vulnerabilities](https://sonarqube.com/api/badges/measure?key=QLNet-develop&metric=vulnerabilities)](https://sonarcloud.io/project/issues?id=QLNet-develop&resolved=false&types=VULNERABILITY) +[![Code Smells](https://sonarqube.com/api/badges/measure?key=QLNet-develop&metric=code_smells)](https://sonarcloud.io/project/issues?id=QLNet-develop&resolved=false&types=CODE_SMELL) +[![Duplicated Lines](https://sonarqube.com/api/badges/measure?key=QLNet-develop&metric=duplicated_lines_density)](https://sonarcloud.io/component_measures?id=QLNet-develop&metric=duplicated_lines_density) +[![Blocker Issues](https://sonarqube.com/api/badges/measure?key=QLNet-develop&metric=blocker_violations)](https://sonarcloud.io/project/issues?id=QLNet-develop&resolved=false&severities=BLOCKER) +[![Critical Issues](https://sonarqube.com/api/badges/measure?key=QLNet-develop&metric=critical_violations)](https://sonarcloud.io/project/issues?id=QLNet-develop&resolved=false&severities=CRITICAL) +[![Major Issues](https://sonarqube.com/api/badges/measure?key=QLNet-develop&metric=major_violations)](https://sonarcloud.io/project/issues?id=QLNet-develop&resolved=false&severities=MAJOR) +[![Minor Issues](https://sonarqube.com/api/badges/measure?key=QLNet-develop&metric=minor_violations)](https://sonarcloud.io/project/issues?id=QLNet-develop&resolved=false&severities=MINOR) +[![Technical Debt](https://sonarqube.com/api/badges/measure?key=QLNet-develop&metric=sqale_debt_ratio)](https://sonarcloud.io/dashboard?id=QLNet-develop) ## Development workflow diff --git a/format_code.bat b/format_code.bat new file mode 100644 index 000000000..12226c3da --- /dev/null +++ b/format_code.bat @@ -0,0 +1 @@ +tools\AStyle.exe --options=qlnet.astyle --recursive src/*.cs tests/*.cs \ No newline at end of file diff --git a/qlnet.astyle b/qlnet.astyle new file mode 100644 index 000000000..c2012140b --- /dev/null +++ b/qlnet.astyle @@ -0,0 +1,28 @@ +# QLNet Coding Style Options + +# braces and indent +style=allman +indent=spaces=3 + +# indentation +min-conditional-indent=0 +max-continuation-indent=80 +indent-classes +indent-namespaces +indent-switches + +# padding +pad-oper +pad-header +unpad-paren +align-pointer=type + +# formatting +break-one-line-headers +keep-one-line-blocks +keep-one-line-statements +convert-tabs + +# other options +suffix=none +exclude=obj \ No newline at end of file diff --git a/src/BermudanSwaption/BermudanSwaption.cs b/src/BermudanSwaption/BermudanSwaption.cs index 44e7fd35a..0ef1fb7ad 100644 --- a/src/BermudanSwaption/BermudanSwaption.cs +++ b/src/BermudanSwaption/BermudanSwaption.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - + This file is part of QLNet Project http://qlnet.sourceforge.net/ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,275 +23,278 @@ under the terms of the QLNet license. You should have received a namespace BermudanSwaption { - class BermudanSwaption - { - - //Number of swaptions to be calibrated to... - const int NumRows = 5; - const int NumCols = 5; - - static readonly int[] SwapLenghts = { 1, 2, 3, 4, 5 }; - static readonly double[] SwaptionVols = { - 0.1490, 0.1340, 0.1228, 0.1189, 0.1148, - 0.1290, 0.1201, 0.1146, 0.1108, 0.1040, - 0.1149, 0.1112, 0.1070, 0.1010, 0.0957, - 0.1047, 0.1021, 0.0980, 0.0951, 0.1270, - 0.1000, 0.0950, 0.0900, 0.1230, 0.1160}; - - static void CalibrateModel(ShortRateModel model, - List helpers) - { - if (model == null) throw new ArgumentNullException("model"); - var om = new LevenbergMarquardt(); - model.calibrate(helpers, om, - new EndCriteria(400, 100, 1.0e-8, 1.0e-8, 1.0e-8), new Constraint(), - new List()); - - // Output the implied Black volatilities - for (int i = 0; i < NumRows; i++) - { - int j = NumCols - i - 1; // 1x5, 2x4, 3x3, 4x2, 5x1 - int k = i * NumCols + j; - double npv = helpers[i].modelValue(); - double implied = helpers[i].impliedVolatility(npv, 1e-4, - 1000, 0.05, 0.50); - double diff = implied - SwaptionVols[k]; - Console.WriteLine("{0}x{1}: model {2:0.00000 %}, market {3:0.00000 %}, diff {4:0.00000 %} ", - i + 1, SwapLenghts[j], implied, SwaptionVols[k], diff); - } - } - - static void Main(string[] args) - { - - DateTime timer = DateTime.Now; - - Date todaysDate = new Date(15, 2, 2002); - Calendar calendar = new TARGET(); - Date settlementDate = new Date(19, 2, 2002); - Settings.setEvaluationDate(todaysDate); - - // flat yield term structure impling 1x5 swap at 5% - Quote flatRate = new SimpleQuote(0.04875825); - Handle rhTermStructure = new Handle( - new FlatForward(settlementDate, new Handle(flatRate), - new Actual365Fixed())); - - // Define the ATM/OTM/ITM swaps - Frequency fixedLegFrequency = Frequency.Annual; - BusinessDayConvention fixedLegConvention = BusinessDayConvention.Unadjusted; - BusinessDayConvention floatingLegConvention = BusinessDayConvention.ModifiedFollowing; - DayCounter fixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European); - Frequency floatingLegFrequency = Frequency.Semiannual; - VanillaSwap.Type type = VanillaSwap.Type.Payer; - double dummyFixedRate = 0.03; - IborIndex indexSixMonths = new Euribor6M(rhTermStructure); - - Date startDate = calendar.advance(settlementDate, 1, TimeUnit.Years, - floatingLegConvention); - Date maturity = calendar.advance(startDate, 5, TimeUnit.Years, - floatingLegConvention); - Schedule fixedSchedule = new Schedule(startDate, maturity, new Period(fixedLegFrequency), - calendar, fixedLegConvention, fixedLegConvention, - DateGeneration.Rule.Forward, false); - Schedule floatSchedule = new Schedule(startDate, maturity, new Period(floatingLegFrequency), - calendar, floatingLegConvention, floatingLegConvention, - DateGeneration.Rule.Forward, false); - - VanillaSwap swap = new VanillaSwap( - type, 1000.0, - fixedSchedule, dummyFixedRate, fixedLegDayCounter, - floatSchedule, indexSixMonths, 0.0, - indexSixMonths.dayCounter()); - swap.setPricingEngine(new DiscountingSwapEngine(rhTermStructure)); - double fixedAtmRate = swap.fairRate(); - double fixedOtmRate = fixedAtmRate * 1.2; - double fixedItmRate = fixedAtmRate * 0.8; - - VanillaSwap atmSwap = new VanillaSwap( - type, 1000.0, - fixedSchedule, fixedAtmRate, fixedLegDayCounter, - floatSchedule, indexSixMonths, 0.0, - indexSixMonths.dayCounter()); - VanillaSwap otmSwap = new VanillaSwap( - type, 1000.0, - fixedSchedule, fixedOtmRate, fixedLegDayCounter, - floatSchedule, indexSixMonths, 0.0, - indexSixMonths.dayCounter()); - VanillaSwap itmSwap = new VanillaSwap( - type, 1000.0, - fixedSchedule, fixedItmRate, fixedLegDayCounter, - floatSchedule, indexSixMonths, 0.0, - indexSixMonths.dayCounter()); - - // defining the swaptions to be used in model calibration - List swaptionMaturities = new List(5); - swaptionMaturities.Add(new Period(1, TimeUnit.Years)); - swaptionMaturities.Add(new Period(2, TimeUnit.Years)); - swaptionMaturities.Add(new Period(3, TimeUnit.Years)); - swaptionMaturities.Add(new Period(4, TimeUnit.Years)); - swaptionMaturities.Add(new Period(5, TimeUnit.Years)); - - List swaptions = new List(); - - // List of times that have to be included in the timegrid - List times = new List(); - - for (int i = 0; i < NumRows; i++) - { - int j = NumCols - i - 1; // 1x5, 2x4, 3x3, 4x2, 5x1 - int k = i * NumCols + j; - Quote vol = new SimpleQuote(SwaptionVols[k]); - swaptions.Add(new SwaptionHelper(swaptionMaturities[i], - new Period(SwapLenghts[j], TimeUnit.Years), - new Handle(vol), - indexSixMonths, - indexSixMonths.tenor(), - indexSixMonths.dayCounter(), - indexSixMonths.dayCounter(), - rhTermStructure)); - swaptions.Last().addTimesTo(times); - } - - // Building time-grid - TimeGrid grid = new TimeGrid(times, times.Count, 30); - - - // defining the models - G2 modelG2 = new G2(rhTermStructure); - HullWhite modelHw = new HullWhite(rhTermStructure); - HullWhite modelHw2 = new HullWhite(rhTermStructure); - BlackKarasinski modelBk = new BlackKarasinski(rhTermStructure); - - - // model calibrations - - Console.WriteLine("G2 (analytic formulae) calibration"); - for (int i = 0; i < swaptions.Count; i++) - swaptions[i].setPricingEngine(new G2SwaptionEngine(modelG2, 6.0, 16)); - CalibrateModel(modelG2, swaptions); - Console.WriteLine("calibrated to:\n" + - "a = {0:0.000000}, " + - "sigma = {1:0.0000000}\n" + - "b = {2:0.000000}, " + - "eta = {3:0.0000000}\n" + - "rho = {4:0.00000}\n", - modelG2.parameters()[0], - modelG2.parameters()[1], - modelG2.parameters()[2], - modelG2.parameters()[3], - modelG2.parameters()[4]); - - Console.WriteLine("Hull-White (analytic formulae) calibration"); - for (int i = 0; i < swaptions.Count; i++) - swaptions[i].setPricingEngine(new JamshidianSwaptionEngine(modelHw)); - CalibrateModel(modelHw, swaptions); - Console.WriteLine("calibrated to:\n" + - "a = {0:0.000000}, " + - "sigma = {1:0.0000000}\n", - modelHw.parameters()[0], - modelHw.parameters()[1]); - - Console.WriteLine("Hull-White (numerical) calibration"); - for (int i = 0; i < swaptions.Count(); i++) - swaptions[i].setPricingEngine(new TreeSwaptionEngine(modelHw2, grid)); - CalibrateModel(modelHw2, swaptions); - Console.WriteLine("calibrated to:\n" + - "a = {0:0.000000}, " + - "sigma = {1:0.0000000}\n", - modelHw2.parameters()[0], - modelHw2.parameters()[1]); - - Console.WriteLine("Black-Karasinski (numerical) calibration"); - for (int i = 0; i < swaptions.Count; i++) - swaptions[i].setPricingEngine(new TreeSwaptionEngine(modelBk, grid)); - CalibrateModel(modelBk, swaptions); - Console.WriteLine("calibrated to:\n" + - "a = {0:0.000000}, " + - "sigma = {1:0.00000}\n", - modelBk.parameters()[0], - modelBk.parameters()[1]); - - - // ATM Bermudan swaption pricing - Console.WriteLine("Payer bermudan swaption " - + "struck at {0:0.00000 %} (ATM)", - fixedAtmRate); - - List bermudanDates = new List(); - List leg = swap.fixedLeg(); - for (int i = 0; i < leg.Count; i++) - { - Coupon coupon = (Coupon)leg[i]; - bermudanDates.Add(coupon.accrualStartDate()); - } - - Exercise bermudanExercise = new BermudanExercise(bermudanDates); - - Swaption bermudanSwaption = new Swaption(atmSwap, bermudanExercise); - - // Do the pricing for each model - - // G2 price the European swaption here, it should switch to bermudan - bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50)); - Console.WriteLine("G2: {0:0.00}", bermudanSwaption.NPV()); - - bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50)); - Console.WriteLine("HW: {0:0.000}", bermudanSwaption.NPV()); - - bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50)); - Console.WriteLine("HW (num): {0:0.000}", bermudanSwaption.NPV()); - - bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50)); - Console.WriteLine("BK: {0:0.000}", bermudanSwaption.NPV()); - - - // OTM Bermudan swaption pricing - Console.WriteLine("Payer bermudan swaption " - + "struck at {0:0.00000 %} (OTM)", - fixedOtmRate); - - Swaption otmBermudanSwaption = new Swaption(otmSwap, bermudanExercise); + class BermudanSwaption + { + + //Number of swaptions to be calibrated to... + const int NumRows = 5; + const int NumCols = 5; + + static readonly int[] SwapLenghts = { 1, 2, 3, 4, 5 }; + static readonly double[] SwaptionVols = + { + 0.1490, 0.1340, 0.1228, 0.1189, 0.1148, + 0.1290, 0.1201, 0.1146, 0.1108, 0.1040, + 0.1149, 0.1112, 0.1070, 0.1010, 0.0957, + 0.1047, 0.1021, 0.0980, 0.0951, 0.1270, + 0.1000, 0.0950, 0.0900, 0.1230, 0.1160 + }; + + static void CalibrateModel(ShortRateModel model, + List helpers) + { + if (model == null) + throw new ArgumentNullException("model"); + var om = new LevenbergMarquardt(); + model.calibrate(helpers, om, + new EndCriteria(400, 100, 1.0e-8, 1.0e-8, 1.0e-8), new Constraint(), + new List()); + + // Output the implied Black volatilities + for (int i = 0; i < NumRows; i++) + { + int j = NumCols - i - 1; // 1x5, 2x4, 3x3, 4x2, 5x1 + int k = i * NumCols + j; + double npv = helpers[i].modelValue(); + double implied = helpers[i].impliedVolatility(npv, 1e-4, + 1000, 0.05, 0.50); + double diff = implied - SwaptionVols[k]; + Console.WriteLine("{0}x{1}: model {2:0.00000 %}, market {3:0.00000 %}, diff {4:0.00000 %} ", + i + 1, SwapLenghts[j], implied, SwaptionVols[k], diff); + } + } + + static void Main(string[] args) + { + + DateTime timer = DateTime.Now; + + Date todaysDate = new Date(15, 2, 2002); + Calendar calendar = new TARGET(); + Date settlementDate = new Date(19, 2, 2002); + Settings.setEvaluationDate(todaysDate); + + // flat yield term structure impling 1x5 swap at 5% + Quote flatRate = new SimpleQuote(0.04875825); + Handle rhTermStructure = new Handle( + new FlatForward(settlementDate, new Handle(flatRate), + new Actual365Fixed())); + + // Define the ATM/OTM/ITM swaps + Frequency fixedLegFrequency = Frequency.Annual; + BusinessDayConvention fixedLegConvention = BusinessDayConvention.Unadjusted; + BusinessDayConvention floatingLegConvention = BusinessDayConvention.ModifiedFollowing; + DayCounter fixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European); + Frequency floatingLegFrequency = Frequency.Semiannual; + VanillaSwap.Type type = VanillaSwap.Type.Payer; + double dummyFixedRate = 0.03; + IborIndex indexSixMonths = new Euribor6M(rhTermStructure); + + Date startDate = calendar.advance(settlementDate, 1, TimeUnit.Years, + floatingLegConvention); + Date maturity = calendar.advance(startDate, 5, TimeUnit.Years, + floatingLegConvention); + Schedule fixedSchedule = new Schedule(startDate, maturity, new Period(fixedLegFrequency), + calendar, fixedLegConvention, fixedLegConvention, + DateGeneration.Rule.Forward, false); + Schedule floatSchedule = new Schedule(startDate, maturity, new Period(floatingLegFrequency), + calendar, floatingLegConvention, floatingLegConvention, + DateGeneration.Rule.Forward, false); + + VanillaSwap swap = new VanillaSwap( + type, 1000.0, + fixedSchedule, dummyFixedRate, fixedLegDayCounter, + floatSchedule, indexSixMonths, 0.0, + indexSixMonths.dayCounter()); + swap.setPricingEngine(new DiscountingSwapEngine(rhTermStructure)); + double fixedAtmRate = swap.fairRate(); + double fixedOtmRate = fixedAtmRate * 1.2; + double fixedItmRate = fixedAtmRate * 0.8; + + VanillaSwap atmSwap = new VanillaSwap( + type, 1000.0, + fixedSchedule, fixedAtmRate, fixedLegDayCounter, + floatSchedule, indexSixMonths, 0.0, + indexSixMonths.dayCounter()); + VanillaSwap otmSwap = new VanillaSwap( + type, 1000.0, + fixedSchedule, fixedOtmRate, fixedLegDayCounter, + floatSchedule, indexSixMonths, 0.0, + indexSixMonths.dayCounter()); + VanillaSwap itmSwap = new VanillaSwap( + type, 1000.0, + fixedSchedule, fixedItmRate, fixedLegDayCounter, + floatSchedule, indexSixMonths, 0.0, + indexSixMonths.dayCounter()); + + // defining the swaptions to be used in model calibration + List swaptionMaturities = new List(5); + swaptionMaturities.Add(new Period(1, TimeUnit.Years)); + swaptionMaturities.Add(new Period(2, TimeUnit.Years)); + swaptionMaturities.Add(new Period(3, TimeUnit.Years)); + swaptionMaturities.Add(new Period(4, TimeUnit.Years)); + swaptionMaturities.Add(new Period(5, TimeUnit.Years)); + + List swaptions = new List(); + + // List of times that have to be included in the timegrid + List times = new List(); + + for (int i = 0; i < NumRows; i++) + { + int j = NumCols - i - 1; // 1x5, 2x4, 3x3, 4x2, 5x1 + int k = i * NumCols + j; + Quote vol = new SimpleQuote(SwaptionVols[k]); + swaptions.Add(new SwaptionHelper(swaptionMaturities[i], + new Period(SwapLenghts[j], TimeUnit.Years), + new Handle(vol), + indexSixMonths, + indexSixMonths.tenor(), + indexSixMonths.dayCounter(), + indexSixMonths.dayCounter(), + rhTermStructure)); + swaptions.Last().addTimesTo(times); + } + + // Building time-grid + TimeGrid grid = new TimeGrid(times, times.Count, 30); + + + // defining the models + G2 modelG2 = new G2(rhTermStructure); + HullWhite modelHw = new HullWhite(rhTermStructure); + HullWhite modelHw2 = new HullWhite(rhTermStructure); + BlackKarasinski modelBk = new BlackKarasinski(rhTermStructure); + + + // model calibrations + + Console.WriteLine("G2 (analytic formulae) calibration"); + for (int i = 0; i < swaptions.Count; i++) + swaptions[i].setPricingEngine(new G2SwaptionEngine(modelG2, 6.0, 16)); + CalibrateModel(modelG2, swaptions); + Console.WriteLine("calibrated to:\n" + + "a = {0:0.000000}, " + + "sigma = {1:0.0000000}\n" + + "b = {2:0.000000}, " + + "eta = {3:0.0000000}\n" + + "rho = {4:0.00000}\n", + modelG2.parameters()[0], + modelG2.parameters()[1], + modelG2.parameters()[2], + modelG2.parameters()[3], + modelG2.parameters()[4]); + + Console.WriteLine("Hull-White (analytic formulae) calibration"); + for (int i = 0; i < swaptions.Count; i++) + swaptions[i].setPricingEngine(new JamshidianSwaptionEngine(modelHw)); + CalibrateModel(modelHw, swaptions); + Console.WriteLine("calibrated to:\n" + + "a = {0:0.000000}, " + + "sigma = {1:0.0000000}\n", + modelHw.parameters()[0], + modelHw.parameters()[1]); + + Console.WriteLine("Hull-White (numerical) calibration"); + for (int i = 0; i < swaptions.Count(); i++) + swaptions[i].setPricingEngine(new TreeSwaptionEngine(modelHw2, grid)); + CalibrateModel(modelHw2, swaptions); + Console.WriteLine("calibrated to:\n" + + "a = {0:0.000000}, " + + "sigma = {1:0.0000000}\n", + modelHw2.parameters()[0], + modelHw2.parameters()[1]); + + Console.WriteLine("Black-Karasinski (numerical) calibration"); + for (int i = 0; i < swaptions.Count; i++) + swaptions[i].setPricingEngine(new TreeSwaptionEngine(modelBk, grid)); + CalibrateModel(modelBk, swaptions); + Console.WriteLine("calibrated to:\n" + + "a = {0:0.000000}, " + + "sigma = {1:0.00000}\n", + modelBk.parameters()[0], + modelBk.parameters()[1]); + + + // ATM Bermudan swaption pricing + Console.WriteLine("Payer bermudan swaption " + + "struck at {0:0.00000 %} (ATM)", + fixedAtmRate); + + List bermudanDates = new List(); + List leg = swap.fixedLeg(); + for (int i = 0; i < leg.Count; i++) + { + Coupon coupon = (Coupon)leg[i]; + bermudanDates.Add(coupon.accrualStartDate()); + } + + Exercise bermudanExercise = new BermudanExercise(bermudanDates); + + Swaption bermudanSwaption = new Swaption(atmSwap, bermudanExercise); + + // Do the pricing for each model + + // G2 price the European swaption here, it should switch to bermudan + bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50)); + Console.WriteLine("G2: {0:0.00}", bermudanSwaption.NPV()); + + bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50)); + Console.WriteLine("HW: {0:0.000}", bermudanSwaption.NPV()); + + bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50)); + Console.WriteLine("HW (num): {0:0.000}", bermudanSwaption.NPV()); + + bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50)); + Console.WriteLine("BK: {0:0.000}", bermudanSwaption.NPV()); + + + // OTM Bermudan swaption pricing + Console.WriteLine("Payer bermudan swaption " + + "struck at {0:0.00000 %} (OTM)", + fixedOtmRate); + + Swaption otmBermudanSwaption = new Swaption(otmSwap, bermudanExercise); - // Do the pricing for each model - otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50)); - Console.WriteLine("G2: {0:0.0000}", otmBermudanSwaption.NPV()); - - otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50)); - Console.WriteLine("HW: {0:0.0000}", otmBermudanSwaption.NPV()); - - otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50)); - Console.WriteLine("HW (num): {0:0.000}", otmBermudanSwaption.NPV()); - - otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50)); - Console.WriteLine("BK: {0:0.0000}", otmBermudanSwaption.NPV()); - - // ITM Bermudan swaption pricing - Console.WriteLine("Payer bermudan swaption " - + "struck at {0:0.00000 %} (ITM)", - fixedItmRate); - - Swaption itmBermudanSwaption = new Swaption(itmSwap, bermudanExercise); - - // Do the pricing for each model - itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50)); - Console.WriteLine("G2: {0:0.000}", itmBermudanSwaption.NPV()); + // Do the pricing for each model + otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50)); + Console.WriteLine("G2: {0:0.0000}", otmBermudanSwaption.NPV()); + + otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50)); + Console.WriteLine("HW: {0:0.0000}", otmBermudanSwaption.NPV()); + + otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50)); + Console.WriteLine("HW (num): {0:0.000}", otmBermudanSwaption.NPV()); + + otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50)); + Console.WriteLine("BK: {0:0.0000}", otmBermudanSwaption.NPV()); + + // ITM Bermudan swaption pricing + Console.WriteLine("Payer bermudan swaption " + + "struck at {0:0.00000 %} (ITM)", + fixedItmRate); + + Swaption itmBermudanSwaption = new Swaption(itmSwap, bermudanExercise); + + // Do the pricing for each model + itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50)); + Console.WriteLine("G2: {0:0.000}", itmBermudanSwaption.NPV()); - itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50)); - Console.WriteLine("HW: {0:0.000}", itmBermudanSwaption.NPV()); + itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50)); + Console.WriteLine("HW: {0:0.000}", itmBermudanSwaption.NPV()); - itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50)); - Console.WriteLine("HW (num): {0:0.000}", itmBermudanSwaption.NPV()); + itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50)); + Console.WriteLine("HW (num): {0:0.000}", itmBermudanSwaption.NPV()); - itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50)); - Console.WriteLine("BK: {0:0.000}", itmBermudanSwaption.NPV()); + itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50)); + Console.WriteLine("BK: {0:0.000}", itmBermudanSwaption.NPV()); - Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); - Console.WriteLine(); + Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); + Console.WriteLine(); - Console.Write("Press any key to continue ..."); - Console.ReadKey(); - } - } + Console.Write("Press any key to continue ..."); + Console.ReadKey(); + } + } } diff --git a/src/BermudanSwaption/BermudanSwaption.csproj b/src/BermudanSwaption/BermudanSwaption.csproj index 1c4ba4cb1..2a1cd2afa 100644 --- a/src/BermudanSwaption/BermudanSwaption.csproj +++ b/src/BermudanSwaption/BermudanSwaption.csproj @@ -1,7 +1,7 @@  - 1.10.0 + 1.11.0 net45 $(DefineConstants);QL_NEGATIVE_RATES BermudanSwaption diff --git a/src/Bonds/Bonds.cs b/src/Bonds/Bonds.cs index f9d5ddd27..ea2624b78 100644 --- a/src/Bonds/Bonds.cs +++ b/src/Bonds/Bonds.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - * + Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) + * This file is part of QLNet Project http://qlnet.sourceforge.net/ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,493 +23,504 @@ under the terms of the QLNet license. You should have received a using System.Text; using QLNet; -namespace Bonds { - class Bonds { - static void Main(string[] args) { - - DateTime timer = DateTime.Now; - - /********************* - *** MARKET DATA *** - *********************/ - - Calendar calendar = new TARGET(); - - Date settlementDate = new Date(18, Month.September, 2008); - // must be a business day - settlementDate = calendar.adjust(settlementDate); - - int fixingDays = 3; - int settlementDays = 3; - - Date todaysDate = calendar.advance(settlementDate, -fixingDays, TimeUnit.Days); - // nothing to do with Date::todaysDate - Settings.setEvaluationDate(todaysDate); - - Console.WriteLine("Today: {0}, {1}", todaysDate.DayOfWeek, todaysDate); - Console.WriteLine("Settlement date: {0}, {1}", settlementDate.DayOfWeek, settlementDate); - - - // Building of the bonds discounting yield curve - - /********************* - *** RATE HELPERS *** - *********************/ - - // RateHelpers are built from the above quotes together with - // other instrument dependant infos. Quotes are passed in - // relinkable handles which could be relinked to some other - // data source later. - - // Common data - - // ZC rates for the short end - double zc3mQuote=0.0096; - double zc6mQuote=0.0145; - double zc1yQuote=0.0194; - - Quote zc3mRate = new SimpleQuote(zc3mQuote); - Quote zc6mRate = new SimpleQuote(zc6mQuote); - Quote zc1yRate = new SimpleQuote(zc1yQuote); - - DayCounter zcBondsDayCounter = new Actual365Fixed(); - - RateHelper zc3m = new DepositRateHelper(new Handle(zc3mRate), - new Period(3, TimeUnit.Months), fixingDays, - calendar, BusinessDayConvention.ModifiedFollowing, - true, zcBondsDayCounter); - RateHelper zc6m = new DepositRateHelper(new Handle(zc6mRate), - new Period(6, TimeUnit.Months), fixingDays, - calendar, BusinessDayConvention.ModifiedFollowing, - true, zcBondsDayCounter); - RateHelper zc1y = new DepositRateHelper(new Handle(zc1yRate), - new Period(1, TimeUnit.Years), fixingDays, - calendar, BusinessDayConvention.ModifiedFollowing, - true, zcBondsDayCounter); - - // setup bonds - double redemption = 100.0; - - const int numberOfBonds = 5; - - Date[] issueDates = { - new Date (15, Month.March, 2005), - new Date (15, Month.June, 2005), - new Date (30, Month.June, 2006), - new Date (15, Month.November, 2002), - new Date (15, Month.May, 1987) - }; - - Date[] maturities = { - new Date (31, Month.August, 2010), - new Date (31, Month.August, 2011), - new Date (31, Month.August, 2013), - new Date (15, Month.August, 2018), - new Date (15, Month.May, 2038) - }; - - double[] couponRates = { - 0.02375, - 0.04625, - 0.03125, - 0.04000, - 0.04500 - }; - - double[] marketQuotes = { - 100.390625, - 106.21875, - 100.59375, - 101.6875, - 102.140625 - }; - - List quote = new List(); - for (int i=0; i> quoteHandle = new InitializedList>(numberOfBonds); - for (int i=0; i bondsHelpers = new List(); - for (int i=0; i() { couponRates[i] }, - new ActualActual(ActualActual.Convention.Bond), - BusinessDayConvention.Unadjusted, - redemption, - issueDates[i]); - - bondsHelpers.Add(bondHelper); - } - - /********************* - ** CURVE BUILDING ** - *********************/ - - // Any DayCounter would be fine. - // ActualActual::ISDA ensures that 30 years is 30.0 - DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA); - - double tolerance = 1.0e-15; - - // A depo-bond curve - List bondInstruments = new List(); - - // Adding the ZC bonds to the curve for the short end - bondInstruments.Add(zc3m); - bondInstruments.Add(zc6m); - bondInstruments.Add(zc1y); - - // Adding the Fixed rate bonds to the curve for the long end - for (int i=0; i( - settlementDate, bondInstruments, - termStructureDayCounter, - new List>(), - new List(), - tolerance); - - // Building of the Libor forecasting curve - // deposits - double d1wQuote=0.043375; - double d1mQuote=0.031875; - double d3mQuote=0.0320375; - double d6mQuote=0.03385; - double d9mQuote=0.0338125; - double d1yQuote=0.0335125; - // swaps - double s2yQuote=0.0295; - double s3yQuote=0.0323; - double s5yQuote=0.0359; - double s10yQuote=0.0412; - double s15yQuote=0.0433; - - - /******************** - *** QUOTES *** - ********************/ - - // SimpleQuote stores a value which can be manually changed; - // other Quote subclasses could read the value from a database - // or some kind of data feed. - - // deposits - Quote d1wRate = new SimpleQuote(d1wQuote); - Quote d1mRate = new SimpleQuote(d1mQuote); - Quote d3mRate = new SimpleQuote(d3mQuote); - Quote d6mRate = new SimpleQuote(d6mQuote); - Quote d9mRate = new SimpleQuote(d9mQuote); - Quote d1yRate = new SimpleQuote(d1yQuote); - // swaps - Quote s2yRate = new SimpleQuote(s2yQuote); - Quote s3yRate = new SimpleQuote(s3yQuote); - Quote s5yRate = new SimpleQuote(s5yQuote); - Quote s10yRate = new SimpleQuote(s10yQuote); - Quote s15yRate = new SimpleQuote(s15yQuote); - - /********************* - *** RATE HELPERS *** - *********************/ - - // RateHelpers are built from the above quotes together with - // other instrument dependant infos. Quotes are passed in - // relinkable handles which could be relinked to some other - // data source later. - - // deposits - DayCounter depositDayCounter = new Actual360(); - - RateHelper d1w = new DepositRateHelper( - new Handle(d1wRate), - new Period(1, TimeUnit.Weeks), fixingDays, - calendar, BusinessDayConvention.ModifiedFollowing, - true, depositDayCounter); - RateHelper d1m = new DepositRateHelper( - new Handle(d1mRate), - new Period(1, TimeUnit.Months), fixingDays, - calendar, BusinessDayConvention.ModifiedFollowing, - true, depositDayCounter); - RateHelper d3m = new DepositRateHelper( - new Handle(d3mRate), - new Period(3, TimeUnit.Months), fixingDays, - calendar, BusinessDayConvention.ModifiedFollowing, - true, depositDayCounter); - RateHelper d6m = new DepositRateHelper( - new Handle(d6mRate), - new Period(6, TimeUnit.Months), fixingDays, - calendar, BusinessDayConvention.ModifiedFollowing, - true, depositDayCounter); - RateHelper d9m = new DepositRateHelper( - new Handle(d9mRate), - new Period(9, TimeUnit.Months), fixingDays, - calendar, BusinessDayConvention.ModifiedFollowing, - true, depositDayCounter); - RateHelper d1y = new DepositRateHelper( - new Handle(d1yRate), - new Period(1, TimeUnit.Years), fixingDays, - calendar, BusinessDayConvention.ModifiedFollowing, - true, depositDayCounter); - - // setup swaps - Frequency swFixedLegFrequency =Frequency.Annual; - BusinessDayConvention swFixedLegConvention = BusinessDayConvention.Unadjusted; - DayCounter swFixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European); - IborIndex swFloatingLegIndex = new Euribor6M(); - - Period forwardStart = new Period(1, TimeUnit.Days); - - RateHelper s2y = new SwapRateHelper( - new Handle(s2yRate), new Period(2, TimeUnit.Years), - calendar, swFixedLegFrequency, - swFixedLegConvention, swFixedLegDayCounter, - swFloatingLegIndex, new Handle(),forwardStart); - RateHelper s3y = new SwapRateHelper( - new Handle(s3yRate), new Period(3, TimeUnit.Years), - calendar, swFixedLegFrequency, - swFixedLegConvention, swFixedLegDayCounter, - swFloatingLegIndex, new Handle(),forwardStart); - RateHelper s5y = new SwapRateHelper( - new Handle(s5yRate), new Period(5, TimeUnit.Years), - calendar, swFixedLegFrequency, - swFixedLegConvention, swFixedLegDayCounter, - swFloatingLegIndex, new Handle(),forwardStart); - RateHelper s10y = new SwapRateHelper( - new Handle(s10yRate), new Period(10, TimeUnit.Years), - calendar, swFixedLegFrequency, - swFixedLegConvention, swFixedLegDayCounter, - swFloatingLegIndex, new Handle(),forwardStart); - RateHelper s15y = new SwapRateHelper( - new Handle(s15yRate), new Period(15, TimeUnit.Years), - calendar, swFixedLegFrequency, - swFixedLegConvention, swFixedLegDayCounter, - swFloatingLegIndex, new Handle(),forwardStart); - - - /********************* - ** CURVE BUILDING ** - *********************/ - - // Any DayCounter would be fine. - // ActualActual::ISDA ensures that 30 years is 30.0 - - // A depo-swap curve - List depoSwapInstruments = new List(); - depoSwapInstruments.Add(d1w); - depoSwapInstruments.Add(d1m); - depoSwapInstruments.Add(d3m); - depoSwapInstruments.Add(d6m); - depoSwapInstruments.Add(d9m); - depoSwapInstruments.Add(d1y); - depoSwapInstruments.Add(s2y); - depoSwapInstruments.Add(s3y); - depoSwapInstruments.Add(s5y); - depoSwapInstruments.Add(s10y); - depoSwapInstruments.Add(s15y); - YieldTermStructure depoSwapTermStructure = new PiecewiseYieldCurve( - settlementDate, depoSwapInstruments, - termStructureDayCounter, - new List >(), - new List(), - tolerance); - - // Term structures that will be used for pricing: - // the one used for discounting cash flows - RelinkableHandle discountingTermStructure = new RelinkableHandle(); - // the one used for forward rate forecasting - RelinkableHandle forecastingTermStructure = new RelinkableHandle(); - - /********************* - * BONDS TO BE PRICED * - **********************/ - - // Common data - double faceAmount = 100; - - // Pricing engine - IPricingEngine bondEngine = new DiscountingBondEngine(discountingTermStructure); - - // Zero coupon bond - ZeroCouponBond zeroCouponBond = new ZeroCouponBond( - settlementDays, - new UnitedStates(UnitedStates.Market.GovernmentBond), - faceAmount, - new Date(15, Month.August,2013), - BusinessDayConvention.Following, - 116.92, - new Date(15, Month.August,2003)); - - zeroCouponBond.setPricingEngine(bondEngine); - - // Fixed 4.5% US Treasury Note - Schedule fixedBondSchedule = new Schedule(new Date(15, Month.May, 2007), - new Date(15,Month.May,2017), new Period(Frequency.Semiannual), - new UnitedStates(UnitedStates.Market.GovernmentBond), - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); - - FixedRateBond fixedRateBond = new FixedRateBond( - settlementDays, - faceAmount, - fixedBondSchedule, - new List() { 0.045 }, - new ActualActual(ActualActual.Convention.Bond), - BusinessDayConvention.ModifiedFollowing, - 100.0, new Date(15, Month.May, 2007)); - - fixedRateBond.setPricingEngine(bondEngine); - - // Floating rate bond (3M USD Libor + 0.1%) - // Should and will be priced on another curve later... - - RelinkableHandle liborTermStructure = new RelinkableHandle(); - IborIndex libor3m = new USDLibor(new Period(3, TimeUnit.Months), liborTermStructure); - libor3m.addFixing(new Date(17, Month.July, 2008),0.0278625); - - Schedule floatingBondSchedule = new Schedule(new Date(21, Month.October, 2005), - new Date(21, Month.October, 2010), new Period(Frequency.Quarterly), - new UnitedStates(UnitedStates.Market.NYSE), - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, true); - - FloatingRateBond floatingRateBond = new FloatingRateBond( - settlementDays, - faceAmount, - floatingBondSchedule, - libor3m, - new Actual360(), - BusinessDayConvention.ModifiedFollowing, - 2, - // Gearings - new List() { 1.0 }, - // Spreads - new List() { 0.001 }, - // Caps - new List(), - // Floors - new List(), - // Fixing in arrears - true, - 100.0, - new Date(21, Month.October, 2005)); - - floatingRateBond.setPricingEngine(bondEngine); - - // Coupon pricers - IborCouponPricer pricer = new BlackIborCouponPricer(); - - // optionLet volatilities - double volatility = 0.0; - Handle vol; - vol = new Handle( - new ConstantOptionletVolatility( - settlementDays, - calendar, - BusinessDayConvention.ModifiedFollowing, - volatility, - new Actual365Fixed())); - - pricer.setCapletVolatility(vol); - Utils.setCouponPricer(floatingRateBond.cashflows(),pricer); - - // Yield curve bootstrapping - forecastingTermStructure.linkTo(depoSwapTermStructure); - discountingTermStructure.linkTo(bondDiscountingTermStructure); - - // We are using the depo & swap curve to estimate the future Libor rates - liborTermStructure.linkTo(depoSwapTermStructure); - - /*************** - * BOND PRICING * - ****************/ - - // write column headings - int[] widths = { 18, 10, 10, 10 }; - - Console.WriteLine("{0,18}{1,10}{2,10}{3,10}", "", "ZC", "Fixed", "Floating"); - - int width = widths[0] - + widths[1] - + widths[2] - + widths[3]; - string rule = "".PadLeft(width, '-'), dblrule = "".PadLeft(width, '='); - string tab = "".PadLeft(8, ' '); - - Console.WriteLine(rule); - - Console.WriteLine("Net present value".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}", - zeroCouponBond.NPV(), - fixedRateBond.NPV(), - floatingRateBond.NPV()); - - Console.WriteLine("Clean price".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}", - zeroCouponBond.cleanPrice(), - fixedRateBond.cleanPrice(), - floatingRateBond.cleanPrice()); - - Console.WriteLine("Dirty price".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}", - zeroCouponBond.dirtyPrice(), - fixedRateBond.dirtyPrice(), - floatingRateBond.dirtyPrice()); - - Console.WriteLine("Accrued coupon".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}", - zeroCouponBond.accruedAmount(), - fixedRateBond.accruedAmount(), - floatingRateBond.accruedAmount()); - - Console.WriteLine("Previous coupon".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}", - "N/A", - fixedRateBond.previousCouponRate(), - floatingRateBond.previousCouponRate()); - - Console.WriteLine("Next coupon".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}", - "N/A", - fixedRateBond.nextCouponRate(), - floatingRateBond.nextCouponRate()); - - Console.WriteLine("Yield".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}", - zeroCouponBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual), - fixedRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual), - floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual)); - - Console.WriteLine(); - - // Other computations - Console.WriteLine("Sample indirect computations (for the floating rate bond): "); - Console.WriteLine(rule); - - Console.WriteLine("Yield to Clean Price: {0:n2}", - floatingRateBond.cleanPrice(floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual), - new Actual360(), Compounding.Compounded, Frequency.Annual, - settlementDate)); - - Console.WriteLine("Clean Price to Yield: {0:0.00%}", - floatingRateBond.yield(floatingRateBond.cleanPrice(),new Actual360(), Compounding.Compounded, Frequency.Annual, - settlementDate)); - - /* "Yield to Price" - "Price to Yield" */ - - Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); - Console.WriteLine(); - - Console.Write("Press any key to continue ..."); - Console.ReadKey(); - } - } +namespace Bonds +{ + class Bonds + { + static void Main(string[] args) + { + + DateTime timer = DateTime.Now; + + /********************* + *** MARKET DATA *** + *********************/ + + Calendar calendar = new TARGET(); + + Date settlementDate = new Date(18, Month.September, 2008); + // must be a business day + settlementDate = calendar.adjust(settlementDate); + + int fixingDays = 3; + int settlementDays = 3; + + Date todaysDate = calendar.advance(settlementDate, -fixingDays, TimeUnit.Days); + // nothing to do with Date::todaysDate + Settings.setEvaluationDate(todaysDate); + + Console.WriteLine("Today: {0}, {1}", todaysDate.DayOfWeek, todaysDate); + Console.WriteLine("Settlement date: {0}, {1}", settlementDate.DayOfWeek, settlementDate); + + + // Building of the bonds discounting yield curve + + /********************* + *** RATE HELPERS *** + *********************/ + + // RateHelpers are built from the above quotes together with + // other instrument dependant infos. Quotes are passed in + // relinkable handles which could be relinked to some other + // data source later. + + // Common data + + // ZC rates for the short end + double zc3mQuote = 0.0096; + double zc6mQuote = 0.0145; + double zc1yQuote = 0.0194; + + Quote zc3mRate = new SimpleQuote(zc3mQuote); + Quote zc6mRate = new SimpleQuote(zc6mQuote); + Quote zc1yRate = new SimpleQuote(zc1yQuote); + + DayCounter zcBondsDayCounter = new Actual365Fixed(); + + RateHelper zc3m = new DepositRateHelper(new Handle(zc3mRate), + new Period(3, TimeUnit.Months), fixingDays, + calendar, BusinessDayConvention.ModifiedFollowing, + true, zcBondsDayCounter); + RateHelper zc6m = new DepositRateHelper(new Handle(zc6mRate), + new Period(6, TimeUnit.Months), fixingDays, + calendar, BusinessDayConvention.ModifiedFollowing, + true, zcBondsDayCounter); + RateHelper zc1y = new DepositRateHelper(new Handle(zc1yRate), + new Period(1, TimeUnit.Years), fixingDays, + calendar, BusinessDayConvention.ModifiedFollowing, + true, zcBondsDayCounter); + + // setup bonds + double redemption = 100.0; + + const int numberOfBonds = 5; + + Date[] issueDates = + { + new Date(15, Month.March, 2005), + new Date(15, Month.June, 2005), + new Date(30, Month.June, 2006), + new Date(15, Month.November, 2002), + new Date(15, Month.May, 1987) + }; + + Date[] maturities = + { + new Date(31, Month.August, 2010), + new Date(31, Month.August, 2011), + new Date(31, Month.August, 2013), + new Date(15, Month.August, 2018), + new Date(15, Month.May, 2038) + }; + + double[] couponRates = + { + 0.02375, + 0.04625, + 0.03125, + 0.04000, + 0.04500 + }; + + double[] marketQuotes = + { + 100.390625, + 106.21875, + 100.59375, + 101.6875, + 102.140625 + }; + + List quote = new List(); + for (int i = 0; i < numberOfBonds; i++) + { + SimpleQuote cp = new SimpleQuote(marketQuotes[i]); + quote.Add(cp); + } + + List> quoteHandle = new InitializedList>(numberOfBonds); + for (int i = 0; i < numberOfBonds; i++) + { + quoteHandle[i].linkTo(quote[i]); + } + + // Definition of the rate helpers + List bondsHelpers = new List(); + for (int i = 0; i < numberOfBonds; i++) + { + + Schedule schedule = new Schedule(issueDates[i], maturities[i], new Period(Frequency.Semiannual), + new UnitedStates(UnitedStates.Market.GovernmentBond), + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); + + FixedRateBondHelper bondHelper = new FixedRateBondHelper(quoteHandle[i], + settlementDays, + 100.0, + schedule, + new List() { couponRates[i] }, + new ActualActual(ActualActual.Convention.Bond), + BusinessDayConvention.Unadjusted, + redemption, + issueDates[i]); + + bondsHelpers.Add(bondHelper); + } + + /********************* + ** CURVE BUILDING ** + *********************/ + + // Any DayCounter would be fine. + // ActualActual::ISDA ensures that 30 years is 30.0 + DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA); + + double tolerance = 1.0e-15; + + // A depo-bond curve + List bondInstruments = new List(); + + // Adding the ZC bonds to the curve for the short end + bondInstruments.Add(zc3m); + bondInstruments.Add(zc6m); + bondInstruments.Add(zc1y); + + // Adding the Fixed rate bonds to the curve for the long end + for (int i = 0; i < numberOfBonds; i++) + { + bondInstruments.Add(bondsHelpers[i]); + } + + YieldTermStructure bondDiscountingTermStructure = new PiecewiseYieldCurve( + settlementDate, bondInstruments, + termStructureDayCounter, + new List>(), + new List(), + tolerance); + + // Building of the Libor forecasting curve + // deposits + double d1wQuote = 0.043375; + double d1mQuote = 0.031875; + double d3mQuote = 0.0320375; + double d6mQuote = 0.03385; + double d9mQuote = 0.0338125; + double d1yQuote = 0.0335125; + // swaps + double s2yQuote = 0.0295; + double s3yQuote = 0.0323; + double s5yQuote = 0.0359; + double s10yQuote = 0.0412; + double s15yQuote = 0.0433; + + + /******************** + *** QUOTES *** + ********************/ + + // SimpleQuote stores a value which can be manually changed; + // other Quote subclasses could read the value from a database + // or some kind of data feed. + + // deposits + Quote d1wRate = new SimpleQuote(d1wQuote); + Quote d1mRate = new SimpleQuote(d1mQuote); + Quote d3mRate = new SimpleQuote(d3mQuote); + Quote d6mRate = new SimpleQuote(d6mQuote); + Quote d9mRate = new SimpleQuote(d9mQuote); + Quote d1yRate = new SimpleQuote(d1yQuote); + // swaps + Quote s2yRate = new SimpleQuote(s2yQuote); + Quote s3yRate = new SimpleQuote(s3yQuote); + Quote s5yRate = new SimpleQuote(s5yQuote); + Quote s10yRate = new SimpleQuote(s10yQuote); + Quote s15yRate = new SimpleQuote(s15yQuote); + + /********************* + *** RATE HELPERS *** + *********************/ + + // RateHelpers are built from the above quotes together with + // other instrument dependant infos. Quotes are passed in + // relinkable handles which could be relinked to some other + // data source later. + + // deposits + DayCounter depositDayCounter = new Actual360(); + + RateHelper d1w = new DepositRateHelper( + new Handle(d1wRate), + new Period(1, TimeUnit.Weeks), fixingDays, + calendar, BusinessDayConvention.ModifiedFollowing, + true, depositDayCounter); + RateHelper d1m = new DepositRateHelper( + new Handle(d1mRate), + new Period(1, TimeUnit.Months), fixingDays, + calendar, BusinessDayConvention.ModifiedFollowing, + true, depositDayCounter); + RateHelper d3m = new DepositRateHelper( + new Handle(d3mRate), + new Period(3, TimeUnit.Months), fixingDays, + calendar, BusinessDayConvention.ModifiedFollowing, + true, depositDayCounter); + RateHelper d6m = new DepositRateHelper( + new Handle(d6mRate), + new Period(6, TimeUnit.Months), fixingDays, + calendar, BusinessDayConvention.ModifiedFollowing, + true, depositDayCounter); + RateHelper d9m = new DepositRateHelper( + new Handle(d9mRate), + new Period(9, TimeUnit.Months), fixingDays, + calendar, BusinessDayConvention.ModifiedFollowing, + true, depositDayCounter); + RateHelper d1y = new DepositRateHelper( + new Handle(d1yRate), + new Period(1, TimeUnit.Years), fixingDays, + calendar, BusinessDayConvention.ModifiedFollowing, + true, depositDayCounter); + + // setup swaps + Frequency swFixedLegFrequency = Frequency.Annual; + BusinessDayConvention swFixedLegConvention = BusinessDayConvention.Unadjusted; + DayCounter swFixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European); + IborIndex swFloatingLegIndex = new Euribor6M(); + + Period forwardStart = new Period(1, TimeUnit.Days); + + RateHelper s2y = new SwapRateHelper( + new Handle(s2yRate), new Period(2, TimeUnit.Years), + calendar, swFixedLegFrequency, + swFixedLegConvention, swFixedLegDayCounter, + swFloatingLegIndex, new Handle(), forwardStart); + RateHelper s3y = new SwapRateHelper( + new Handle(s3yRate), new Period(3, TimeUnit.Years), + calendar, swFixedLegFrequency, + swFixedLegConvention, swFixedLegDayCounter, + swFloatingLegIndex, new Handle(), forwardStart); + RateHelper s5y = new SwapRateHelper( + new Handle(s5yRate), new Period(5, TimeUnit.Years), + calendar, swFixedLegFrequency, + swFixedLegConvention, swFixedLegDayCounter, + swFloatingLegIndex, new Handle(), forwardStart); + RateHelper s10y = new SwapRateHelper( + new Handle(s10yRate), new Period(10, TimeUnit.Years), + calendar, swFixedLegFrequency, + swFixedLegConvention, swFixedLegDayCounter, + swFloatingLegIndex, new Handle(), forwardStart); + RateHelper s15y = new SwapRateHelper( + new Handle(s15yRate), new Period(15, TimeUnit.Years), + calendar, swFixedLegFrequency, + swFixedLegConvention, swFixedLegDayCounter, + swFloatingLegIndex, new Handle(), forwardStart); + + + /********************* + ** CURVE BUILDING ** + *********************/ + + // Any DayCounter would be fine. + // ActualActual::ISDA ensures that 30 years is 30.0 + + // A depo-swap curve + List depoSwapInstruments = new List(); + depoSwapInstruments.Add(d1w); + depoSwapInstruments.Add(d1m); + depoSwapInstruments.Add(d3m); + depoSwapInstruments.Add(d6m); + depoSwapInstruments.Add(d9m); + depoSwapInstruments.Add(d1y); + depoSwapInstruments.Add(s2y); + depoSwapInstruments.Add(s3y); + depoSwapInstruments.Add(s5y); + depoSwapInstruments.Add(s10y); + depoSwapInstruments.Add(s15y); + YieldTermStructure depoSwapTermStructure = new PiecewiseYieldCurve( + settlementDate, depoSwapInstruments, + termStructureDayCounter, + new List >(), + new List(), + tolerance); + + // Term structures that will be used for pricing: + // the one used for discounting cash flows + RelinkableHandle discountingTermStructure = new RelinkableHandle(); + // the one used for forward rate forecasting + RelinkableHandle forecastingTermStructure = new RelinkableHandle(); + + /********************* + * BONDS TO BE PRICED * + **********************/ + + // Common data + double faceAmount = 100; + + // Pricing engine + IPricingEngine bondEngine = new DiscountingBondEngine(discountingTermStructure); + + // Zero coupon bond + ZeroCouponBond zeroCouponBond = new ZeroCouponBond( + settlementDays, + new UnitedStates(UnitedStates.Market.GovernmentBond), + faceAmount, + new Date(15, Month.August, 2013), + BusinessDayConvention.Following, + 116.92, + new Date(15, Month.August, 2003)); + + zeroCouponBond.setPricingEngine(bondEngine); + + // Fixed 4.5% US Treasury Note + Schedule fixedBondSchedule = new Schedule(new Date(15, Month.May, 2007), + new Date(15, Month.May, 2017), new Period(Frequency.Semiannual), + new UnitedStates(UnitedStates.Market.GovernmentBond), + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); + + FixedRateBond fixedRateBond = new FixedRateBond( + settlementDays, + faceAmount, + fixedBondSchedule, + new List() { 0.045 }, + new ActualActual(ActualActual.Convention.Bond), + BusinessDayConvention.ModifiedFollowing, + 100.0, new Date(15, Month.May, 2007)); + + fixedRateBond.setPricingEngine(bondEngine); + + // Floating rate bond (3M USD Libor + 0.1%) + // Should and will be priced on another curve later... + + RelinkableHandle liborTermStructure = new RelinkableHandle(); + IborIndex libor3m = new USDLibor(new Period(3, TimeUnit.Months), liborTermStructure); + libor3m.addFixing(new Date(17, Month.July, 2008), 0.0278625); + + Schedule floatingBondSchedule = new Schedule(new Date(21, Month.October, 2005), + new Date(21, Month.October, 2010), new Period(Frequency.Quarterly), + new UnitedStates(UnitedStates.Market.NYSE), + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, true); + + FloatingRateBond floatingRateBond = new FloatingRateBond( + settlementDays, + faceAmount, + floatingBondSchedule, + libor3m, + new Actual360(), + BusinessDayConvention.ModifiedFollowing, + 2, + // Gearings + new List() { 1.0 }, + // Spreads + new List() { 0.001 }, + // Caps + new List < double? >(), + // Floors + new List < double? >(), + // Fixing in arrears + true, + 100.0, + new Date(21, Month.October, 2005)); + + floatingRateBond.setPricingEngine(bondEngine); + + // Coupon pricers + IborCouponPricer pricer = new BlackIborCouponPricer(); + + // optionLet volatilities + double volatility = 0.0; + Handle vol; + vol = new Handle( + new ConstantOptionletVolatility( + settlementDays, + calendar, + BusinessDayConvention.ModifiedFollowing, + volatility, + new Actual365Fixed())); + + pricer.setCapletVolatility(vol); + Utils.setCouponPricer(floatingRateBond.cashflows(), pricer); + + // Yield curve bootstrapping + forecastingTermStructure.linkTo(depoSwapTermStructure); + discountingTermStructure.linkTo(bondDiscountingTermStructure); + + // We are using the depo & swap curve to estimate the future Libor rates + liborTermStructure.linkTo(depoSwapTermStructure); + + /*************** + * BOND PRICING * + ****************/ + + // write column headings + int[] widths = { 18, 10, 10, 10 }; + + Console.WriteLine("{0,18}{1,10}{2,10}{3,10}", "", "ZC", "Fixed", "Floating"); + + int width = widths[0] + + widths[1] + + widths[2] + + widths[3]; + string rule = "".PadLeft(width, '-'), dblrule = "".PadLeft(width, '='); + string tab = "".PadLeft(8, ' '); + + Console.WriteLine(rule); + + Console.WriteLine("Net present value".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}", + zeroCouponBond.NPV(), + fixedRateBond.NPV(), + floatingRateBond.NPV()); + + Console.WriteLine("Clean price".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}", + zeroCouponBond.cleanPrice(), + fixedRateBond.cleanPrice(), + floatingRateBond.cleanPrice()); + + Console.WriteLine("Dirty price".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}", + zeroCouponBond.dirtyPrice(), + fixedRateBond.dirtyPrice(), + floatingRateBond.dirtyPrice()); + + Console.WriteLine("Accrued coupon".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}", + zeroCouponBond.accruedAmount(), + fixedRateBond.accruedAmount(), + floatingRateBond.accruedAmount()); + + Console.WriteLine("Previous coupon".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}", + "N/A", + fixedRateBond.previousCouponRate(), + floatingRateBond.previousCouponRate()); + + Console.WriteLine("Next coupon".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}", + "N/A", + fixedRateBond.nextCouponRate(), + floatingRateBond.nextCouponRate()); + + Console.WriteLine("Yield".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}", + zeroCouponBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual), + fixedRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual), + floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual)); + + Console.WriteLine(); + + // Other computations + Console.WriteLine("Sample indirect computations (for the floating rate bond): "); + Console.WriteLine(rule); + + Console.WriteLine("Yield to Clean Price: {0:n2}", + floatingRateBond.cleanPrice(floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual), + new Actual360(), Compounding.Compounded, Frequency.Annual, + settlementDate)); + + Console.WriteLine("Clean Price to Yield: {0:0.00%}", + floatingRateBond.yield(floatingRateBond.cleanPrice(), new Actual360(), Compounding.Compounded, Frequency.Annual, + settlementDate)); + + /* "Yield to Price" + "Price to Yield" */ + + Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); + Console.WriteLine(); + + Console.Write("Press any key to continue ..."); + Console.ReadKey(); + } + } } diff --git a/src/Bonds/Bonds.csproj b/src/Bonds/Bonds.csproj index caaa0e307..f6ac7c729 100644 --- a/src/Bonds/Bonds.csproj +++ b/src/Bonds/Bonds.csproj @@ -1,7 +1,7 @@  - 1.10.0 + 1.11.0 net45 $(DefineConstants);QL_NEGATIVE_RATES Bonds diff --git a/src/CVAIRS/CVAIRS.cs b/src/CVAIRS/CVAIRS.cs index 0499b6220..07485ea44 100644 --- a/src/CVAIRS/CVAIRS.cs +++ b/src/CVAIRS/CVAIRS.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,93 +21,93 @@ namespace CVAIRS { class CVAIRS { - static void Main( string[] args ) + static void Main(string[] args) { - try + try { DateTime timer = DateTime.Now; Calendar calendar = new TARGET(); - Date todaysDate = new Date(10,Month.March, 2004); + Date todaysDate = new Date(10, Month.March, 2004); // must be a business day todaysDate = calendar.adjust(todaysDate); Settings.setEvaluationDate(todaysDate); IborIndex yieldIndx = new Euribor3M(); - int[] tenorsSwapMkt = {5,10,15,20,25,30}; + int[] tenorsSwapMkt = {5, 10, 15, 20, 25, 30}; // rates ignoring counterparty risk: - double[] ratesSwapmkt = {.03249,.04074,.04463,.04675,.04775,.04811}; + double[] ratesSwapmkt = {.03249, .04074, .04463, .04675, .04775, .04811}; List swapHelpers = new List(); for (int i = 0; i < tenorsSwapMkt.Length; i++) swapHelpers.Add(new SwapRateHelper(new Handle(new SimpleQuote(ratesSwapmkt[i])), - new Period(tenorsSwapMkt[i],TimeUnit.Years), - new TARGET(), - Frequency.Quarterly, - BusinessDayConvention.ModifiedFollowing, - new ActualActual(ActualActual.Convention.ISDA), - yieldIndx)); - - YieldTermStructure swapTS = new PiecewiseYieldCurve(2, new TARGET(), swapHelpers, - new ActualActual(ActualActual.Convention.ISDA)); + new Period(tenorsSwapMkt[i], TimeUnit.Years), + new TARGET(), + Frequency.Quarterly, + BusinessDayConvention.ModifiedFollowing, + new ActualActual(ActualActual.Convention.ISDA), + yieldIndx)); + + YieldTermStructure swapTS = new PiecewiseYieldCurve(2, new TARGET(), swapHelpers, + new ActualActual(ActualActual.Convention.ISDA)); swapTS.enableExtrapolation(); IPricingEngine riskFreeEngine = new DiscountingSwapEngine(new Handle(swapTS)); - List> defaultIntensityTS = + List> defaultIntensityTS = new List>(); - int[] defaultTenors = {0,12,36,60,84,120,180,240,300,360}; // months + int[] defaultTenors = {0, 12, 36, 60, 84, 120, 180, 240, 300, 360}; // months // Three risk levels: - double[] intensitiesLow = {0.0036,0.0036,0.0065,0.0099,0.0111,0.0177,0.0177,0.0177,0.0177,0.0177,0.0177}; - double[] intensitiesMedium = {0.0202,0.0202,0.0231,0.0266,0.0278,0.0349,0.0349,0.0349,0.0349,0.0349,0.0349}; - double[] intensitiesHigh = {0.0534,0.0534,0.0564,0.06,0.0614,0.0696,0.0696,0.0696,0.0696,0.0696,0.0696}; + double[] intensitiesLow = {0.0036, 0.0036, 0.0065, 0.0099, 0.0111, 0.0177, 0.0177, 0.0177, 0.0177, 0.0177, 0.0177}; + double[] intensitiesMedium = {0.0202, 0.0202, 0.0231, 0.0266, 0.0278, 0.0349, 0.0349, 0.0349, 0.0349, 0.0349, 0.0349}; + double[] intensitiesHigh = {0.0534, 0.0534, 0.0564, 0.06, 0.0614, 0.0696, 0.0696, 0.0696, 0.0696, 0.0696, 0.0696}; // Recovery rates: double ctptyRRLow = 0.4, ctptyRRMedium = 0.35, ctptyRRHigh = 0.3; List defaultTSDates = new List(); - List intesitiesVLow = new List(), - intesitiesVMedium = new List(), - intesitiesVHigh = new List(); + List intesitiesVLow = new List(), + intesitiesVMedium = new List(), + intesitiesVHigh = new List(); for (int i = 0; i < defaultTenors.Length; i++) { - defaultTSDates.Add(new TARGET().advance(todaysDate,new Period(defaultTenors[i], TimeUnit.Months))); + defaultTSDates.Add(new TARGET().advance(todaysDate, new Period(defaultTenors[i], TimeUnit.Months))); intesitiesVLow.Add(intensitiesLow[i]); intesitiesVMedium.Add(intensitiesMedium[i]); intesitiesVHigh.Add(intensitiesHigh[i]); } defaultIntensityTS.Add(new Handle( - new InterpolatedHazardRateCurve( - defaultTSDates, - intesitiesVLow, - new Actual360(), - new TARGET()))); + new InterpolatedHazardRateCurve( + defaultTSDates, + intesitiesVLow, + new Actual360(), + new TARGET()))); defaultIntensityTS.Add(new Handle( - new InterpolatedHazardRateCurve( - defaultTSDates, - intesitiesVMedium, - new Actual360(), - new TARGET()))); + new InterpolatedHazardRateCurve( + defaultTSDates, + intesitiesVMedium, + new Actual360(), + new TARGET()))); defaultIntensityTS.Add(new Handle( - new InterpolatedHazardRateCurve( - defaultTSDates, - intesitiesVHigh, - new Actual360(), - new TARGET()))); + new InterpolatedHazardRateCurve( + defaultTSDates, + intesitiesVHigh, + new Actual360(), + new TARGET()))); double blackVol = 0.15; IPricingEngine ctptySwapCvaLow = new CounterpartyAdjSwapEngine(new Handle(swapTS), - blackVol,defaultIntensityTS[0],ctptyRRLow); + blackVol, defaultIntensityTS[0], ctptyRRLow); IPricingEngine ctptySwapCvaMedium = new CounterpartyAdjSwapEngine(new Handle(swapTS), - blackVol,defaultIntensityTS[1],ctptyRRMedium); + blackVol, defaultIntensityTS[1], ctptyRRMedium); IPricingEngine ctptySwapCvaHigh = new CounterpartyAdjSwapEngine(new Handle(swapTS), - blackVol,defaultIntensityTS[2],ctptyRRHigh); + blackVol, defaultIntensityTS[2], ctptyRRHigh); defaultIntensityTS[0].link.enableExtrapolation(); defaultIntensityTS[1].link.enableExtrapolation(); @@ -127,63 +127,63 @@ static void Main( string[] args ) IborIndex yieldIndxS = new Euribor3M(new Handle(swapTS)); List riskySwaps = new List(); for (int i = 0; i < tenorsSwapMkt.Length; i++) - riskySwaps.Add(new MakeVanillaSwap(new Period(tenorsSwapMkt[i],TimeUnit.Years), - yieldIndxS, - ratesSwapmkt[i], - new Period(0,TimeUnit.Days)) - .withSettlementDays(2) - .withFixedLegDayCount(fixedLegDayCounter) - .withFixedLegTenor(new Period(fixedLegFrequency)) - .withFixedLegConvention(fixedLegConvention) - .withFixedLegTerminationDateConvention(fixedLegConvention) - .withFixedLegCalendar(calendar) - .withFloatingLegCalendar(calendar) - .withNominal(100.0) - .withType(swapType).value()); - - Console.WriteLine("-- Correction in the contract fix rate in bp --" ); + riskySwaps.Add(new MakeVanillaSwap(new Period(tenorsSwapMkt[i], TimeUnit.Years), + yieldIndxS, + ratesSwapmkt[i], + new Period(0, TimeUnit.Days)) + .withSettlementDays(2) + .withFixedLegDayCount(fixedLegDayCounter) + .withFixedLegTenor(new Period(fixedLegFrequency)) + .withFixedLegConvention(fixedLegConvention) + .withFixedLegTerminationDateConvention(fixedLegConvention) + .withFixedLegCalendar(calendar) + .withFloatingLegCalendar(calendar) + .withNominal(100.0) + .withType(swapType).value()); + + Console.WriteLine("-- Correction in the contract fix rate in bp --"); /* The paper plots correction to be substracted, here is printed - with its sign + with its sign */ for (int i = 0; i < riskySwaps.Count; i++) { riskySwaps[i].setPricingEngine(riskFreeEngine); // should recover the input here: double nonRiskyFair = riskySwaps[i].fairRate(); - Console.Write( (tenorsSwapMkt[i]).ToString( "0" ).PadLeft( 6 ) ); - Console.Write( " | " + nonRiskyFair.ToString( "P3" ).PadLeft( 6 ) ); + Console.Write((tenorsSwapMkt[i]).ToString("0").PadLeft(6)); + Console.Write(" | " + nonRiskyFair.ToString("P3").PadLeft(6)); // Low Risk: riskySwaps[i].setPricingEngine(ctptySwapCvaLow); - Console.Write( " | " + ( 10000.0 * ( riskySwaps[i].fairRate() - nonRiskyFair ) ).ToString( "#0.00" ).PadLeft( 6 ) ); + Console.Write(" | " + (10000.0 * (riskySwaps[i].fairRate() - nonRiskyFair)).ToString("#0.00").PadLeft(6)); //cout << " | " << setw(6) << riskySwaps[i].NPV() ; // Medium Risk: riskySwaps[i].setPricingEngine(ctptySwapCvaMedium); - Console.Write( " | " + ( 10000.0 * ( riskySwaps[i].fairRate() - nonRiskyFair ) ).ToString( "#0.00" ).PadLeft( 6 ) ); + Console.Write(" | " + (10000.0 * (riskySwaps[i].fairRate() - nonRiskyFair)).ToString("#0.00").PadLeft(6)); //cout << " | " << setw(6) << riskySwaps[i].NPV() ; riskySwaps[i].setPricingEngine(ctptySwapCvaHigh); - Console.Write( " | " + ( 10000.0 * ( riskySwaps[i].fairRate() - nonRiskyFair ) ).ToString( "#0.00" ).PadLeft( 6 ) ); + Console.Write(" | " + (10000.0 * (riskySwaps[i].fairRate() - nonRiskyFair)).ToString("#0.00").PadLeft(6)); //cout << " | " << setw(6) << riskySwaps[i].NPV() ; Console.WriteLine(); } - Console.WriteLine(); + Console.WriteLine(); Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); Console.WriteLine(); Console.Write("Press any key to continue ..."); Console.ReadKey(); - - } + + } catch (Exception e) { Console.Write(e.Message); - Console.Write( "Press any key to continue ..." ); + Console.Write("Press any key to continue ..."); Console.ReadKey(); - } + } } } } diff --git a/src/CVAIRS/CVAIRS.csproj b/src/CVAIRS/CVAIRS.csproj index f5ab20e2c..3efa8639d 100644 --- a/src/CVAIRS/CVAIRS.csproj +++ b/src/CVAIRS/CVAIRS.csproj @@ -1,7 +1,7 @@  - 1.10.0 + 1.11.0 net45 $(DefineConstants);QL_NEGATIVE_RATES CVAIRS diff --git a/src/CallableBonds/CallableBonds.cs b/src/CallableBonds/CallableBonds.cs index 167f7a994..5b84baedb 100644 --- a/src/CallableBonds/CallableBonds.cs +++ b/src/CallableBonds/CallableBonds.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://www.qlnet.org + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -29,10 +29,10 @@ class CallableBonds { static YieldTermStructure flatRate(Date today, - double forward, - DayCounter dc, - Compounding compounding, - Frequency frequency) + double forward, + DayCounter dc, + Compounding compounding, + Frequency frequency) { return new FlatForward(today, forward, dc, compounding, frequency); @@ -43,7 +43,7 @@ static void Main(string[] args) { // boost::timer timer; - Date today = new Date(16,Month.October,2007); + Date today = new Date(16, Month.October, 2007); Settings.setEvaluationDate(today); Console.WriteLine(); @@ -51,7 +51,7 @@ static void Main(string[] args) Console.WriteLine("Hull White model w/ reversion parameter = 0.03"); Console.WriteLine("BAC4.65 09/15/12 ISIN: US06060WBJ36"); Console.WriteLine("roughly five year tenor, quarterly coupon and call dates"); - Console.WriteLine("reference date is : " + today.ToLongDateString() ); + Console.WriteLine("reference date is : " + today.ToLongDateString()); Console.WriteLine(""); /* Bloomberg OAS1: "N" model (Hull White) varying volatility parameter @@ -66,34 +66,34 @@ as documented in PFC1 as a "default" in the latter case. double bbCurveRate = 0.055; DayCounter bbDayCounter = new ActualActual(ActualActual.Convention.Bond); - InterestRate bbIR = new InterestRate(bbCurveRate,bbDayCounter,Compounding.Compounded ,Frequency.Semiannual); + InterestRate bbIR = new InterestRate(bbCurveRate, bbDayCounter, Compounding.Compounded, Frequency.Semiannual); - Handle termStructure = new Handle(flatRate( today, - bbIR.rate(), - bbIR.dayCounter(), - bbIR.compounding(), - bbIR.frequency())); + Handle termStructure = new Handle(flatRate(today, + bbIR.rate(), + bbIR.dayCounter(), + bbIR.compounding(), + bbIR.frequency())); // set up the call schedule CallabilitySchedule callSchedule = new CallabilitySchedule(); double callPrice = 100.0; int numberOfCallDates = 24; - Date callDate = new Date(15,Month.September,2006); + Date callDate = new Date(15, Month.September, 2006); - for (int i=0; i< numberOfCallDates; i++) + for (int i = 0; i < numberOfCallDates; i++) { Calendar nullCalendar = new NullCalendar(); Callability.Price myPrice = new Callability.Price(callPrice, Callability.Price.Type.Clean); - callSchedule.Add( new Callability(myPrice,Callability.Type.Call, callDate )); + callSchedule.Add(new Callability(myPrice, Callability.Type.Call, callDate)); callDate = nullCalendar.advance(callDate, 3, TimeUnit.Months); } // set up the callable bond - Date dated = new Date(16,Month.September,2004); + Date dated = new Date(16, Month.September, 2004); Date issue = dated; - Date maturity = new Date(15,Month.September,2012); + Date maturity = new Date(15, Month.September, 2012); int settlementDays = 3; // Bloomberg OAS1 settle is Oct 19, 2007 Calendar bondCalendar = new UnitedStates(UnitedStates.Market.GovernmentBond); double coupon = .0465; @@ -112,9 +112,9 @@ Therefore use ActAct(Bond) BusinessDayConvention accrualConvention = BusinessDayConvention.Unadjusted; BusinessDayConvention paymentConvention = BusinessDayConvention.Unadjusted; - Schedule sch = new Schedule( dated, maturity, new Period(frequency), bondCalendar, - accrualConvention, accrualConvention, - DateGeneration.Rule.Backward, false); + Schedule sch = new Schedule(dated, maturity, new Period(frequency), bondCalendar, + accrualConvention, accrualConvention, + DateGeneration.Rule.Backward, false); int maxIterations = 1000; double accuracy = 1e-8; @@ -125,25 +125,25 @@ Therefore use ActAct(Bond) double sigma = Const.QL_EPSILON; // core dumps if zero on Cygwin - ShortRateModel hw0 = new HullWhite(termStructure,reversionParameter,sigma); + ShortRateModel hw0 = new HullWhite(termStructure, reversionParameter, sigma); IPricingEngine engine0 = new TreeCallableFixedRateBondEngine(hw0, gridIntervals, termStructure); - CallableFixedRateBond callableBond = new CallableFixedRateBond( settlementDays, faceAmount, sch, - new InitializedList(1, coupon), - bondDayCounter, paymentConvention, - redemption, issue, callSchedule); + CallableFixedRateBond callableBond = new CallableFixedRateBond(settlementDays, faceAmount, sch, + new InitializedList(1, coupon), + bondDayCounter, paymentConvention, + redemption, issue, callSchedule); callableBond.setPricingEngine(engine0); Console.WriteLine("sigma/vol (%) = {0:0.00}", (100.0 * sigma)); Console.WriteLine("QLNet price/yld (%) {0:0.00} / {1:0.00} ", - callableBond.cleanPrice() , - 100.0 * callableBond.yield(bondDayCounter, - Compounding.Compounded, - frequency, - accuracy, - maxIterations)); + callableBond.cleanPrice(), + 100.0 * callableBond.yield(bondDayCounter, + Compounding.Compounded, + frequency, + accuracy, + maxIterations)); Console.WriteLine("Bloomberg price/yld (%) 96,50 / 5,47"); Console.WriteLine(""); // @@ -152,19 +152,19 @@ Therefore use ActAct(Bond) Console.WriteLine("sigma/vol (%) = {0:0.00}", (100.0 * sigma)); - ShortRateModel hw1 = new HullWhite(termStructure,reversionParameter,sigma); + ShortRateModel hw1 = new HullWhite(termStructure, reversionParameter, sigma); - IPricingEngine engine1 = new TreeCallableFixedRateBondEngine(hw1,gridIntervals,termStructure); + IPricingEngine engine1 = new TreeCallableFixedRateBondEngine(hw1, gridIntervals, termStructure); callableBond.setPricingEngine(engine1); Console.WriteLine("QLNet price/yld (%) {0:0.00} / {1:0.00} ", - callableBond.cleanPrice() , - 100.0 * callableBond.yield(bondDayCounter, - Compounding.Compounded, - frequency, - accuracy, - maxIterations)); + callableBond.cleanPrice(), + 100.0 * callableBond.yield(bondDayCounter, + Compounding.Compounded, + frequency, + accuracy, + maxIterations)); Console.WriteLine("Bloomberg price/yld (%) 95,68 / 5,66"); Console.WriteLine(""); @@ -182,12 +182,12 @@ Therefore use ActAct(Bond) callableBond.setPricingEngine(engine2); Console.WriteLine("QLNet price/yld (%) {0:0.00} / {1:0.00} ", - callableBond.cleanPrice(), - 100.0 * callableBond.yield(bondDayCounter, - Compounding.Compounded, - frequency, - accuracy, - maxIterations)); + callableBond.cleanPrice(), + 100.0 * callableBond.yield(bondDayCounter, + Compounding.Compounded, + frequency, + accuracy, + maxIterations)); Console.WriteLine("Bloomberg price/yld (%) 92,34 / 6,49"); Console.WriteLine(""); @@ -204,12 +204,12 @@ Therefore use ActAct(Bond) callableBond.setPricingEngine(engine3); Console.WriteLine("QLNet price/yld (%) {0:0.00} / {1:0.00} ", - callableBond.cleanPrice(), - 100.0 * callableBond.yield(bondDayCounter, - Compounding.Compounded, - frequency, - accuracy, - maxIterations)); + callableBond.cleanPrice(), + 100.0 * callableBond.yield(bondDayCounter, + Compounding.Compounded, + frequency, + accuracy, + maxIterations)); Console.WriteLine("Bloomberg price/yld (%) 87,16 / 7,83"); Console.WriteLine(""); @@ -226,12 +226,12 @@ Therefore use ActAct(Bond) callableBond.setPricingEngine(engine4); Console.WriteLine("QLNet price/yld (%) {0:0.00} / {1:0.00} ", - callableBond.cleanPrice(), - 100.0 * callableBond.yield(bondDayCounter, - Compounding.Compounded, - frequency, - accuracy, - maxIterations)); + callableBond.cleanPrice(), + 100.0 * callableBond.yield(bondDayCounter, + Compounding.Compounded, + frequency, + accuracy, + maxIterations)); Console.WriteLine("Bloomberg price/yld (%) 77,31 / 10,65"); } diff --git a/src/CallableBonds/CallableBonds.csproj b/src/CallableBonds/CallableBonds.csproj index a6bc1af52..7f23f6894 100644 --- a/src/CallableBonds/CallableBonds.csproj +++ b/src/CallableBonds/CallableBonds.csproj @@ -1,7 +1,7 @@  - 1.10.0 + 1.11.0 net45 $(DefineConstants);QL_NEGATIVE_RATES CallableBonds diff --git a/src/EquityOption/EquityOption.cs b/src/EquityOption/EquityOption.cs index 7a424018f..56654b65c 100644 --- a/src/EquityOption/EquityOption.cs +++ b/src/EquityOption/EquityOption.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project http://qlnet.sourceforge.net/ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,254 +22,257 @@ under the terms of the QLNet license. You should have received a using System.Text; using QLNet; -namespace EquityOption { - class EquityOption { - static void Main(string[] args) { - - DateTime timer = DateTime.Now; +namespace EquityOption +{ + class EquityOption + { + static void Main(string[] args) + { + + DateTime timer = DateTime.Now; - // set up dates - Calendar calendar = new TARGET(); - Date todaysDate = new Date(15, Month.May, 1998); - Date settlementDate = new Date(17, Month.May, 1998); - Settings.setEvaluationDate(todaysDate); - - // our options - Option.Type type = Option.Type.Put; - double underlying = 36; - double strike = 40; - double dividendYield = 0.00; - double riskFreeRate = 0.06; - double volatility = 0.20; - Date maturity = new Date(17, Month.May, 1999); - DayCounter dayCounter = new Actual365Fixed(); - - Console.WriteLine("Option type = " + type); - Console.WriteLine("Maturity = " + maturity); - Console.WriteLine("Underlying price = " + underlying); - Console.WriteLine("Strike = " + strike); - Console.WriteLine("Risk-free interest rate = {0:0.000000%}", riskFreeRate); - Console.WriteLine("Dividend yield = {0:0.000000%}", dividendYield); - Console.WriteLine("Volatility = {0:0.000000%}", volatility); - Console.Write("\n"); - - string method; - - Console.Write("\n"); - - // write column headings - int[] widths = new int[]{ 35, 14, 14, 14 }; - Console.Write("{0,-" + widths[0] + "}", "Method"); - Console.Write("{0,-" + widths[1] + "}", "European"); - Console.Write("{0,-" + widths[2] + "}", "Bermudan"); - Console.WriteLine("{0,-" + widths[3] + "}", "American"); - - List exerciseDates = new List(); ; - for (int i = 1; i <= 4; i++) - exerciseDates.Add(settlementDate + new Period(3 * i, TimeUnit.Months)); - - Exercise europeanExercise = new EuropeanExercise(maturity); - Exercise bermudanExercise = new BermudanExercise(exerciseDates); - Exercise americanExercise = new AmericanExercise(settlementDate, maturity); - - Handle underlyingH = new Handle(new SimpleQuote(underlying)); - - // bootstrap the yield/dividend/vol curves - var flatTermStructure = new Handle(new FlatForward(settlementDate, riskFreeRate, dayCounter)); - var flatDividendTS = new Handle(new FlatForward(settlementDate, dividendYield, dayCounter)); - var flatVolTS = new Handle(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter)); - StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike); - var bsmProcess = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS); - - // options - VanillaOption europeanOption = new VanillaOption(payoff, europeanExercise); - VanillaOption bermudanOption = new VanillaOption(payoff, bermudanExercise); - VanillaOption americanOption = new VanillaOption(payoff, americanExercise); - - - // Analytic formulas: - - // Black-Scholes for European - method = "Black-Scholes"; - europeanOption.setPricingEngine(new AnalyticEuropeanEngine(bsmProcess)); - - Console.Write("{0,-" + widths[0] + "}", method); - Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); - Console.Write("{0,-" + widths[2] + "}", "N/A"); - Console.WriteLine("{0,-" + widths[3] + "}", "N/A"); - - - // Barone-Adesi and Whaley approximation for American - method = "Barone-Adesi/Whaley"; - americanOption.setPricingEngine(new BaroneAdesiWhaleyApproximationEngine(bsmProcess)); - - Console.Write("{0,-" + widths[0] + "}", method); - Console.Write("{0,-" + widths[1] + "}", "N/A"); - Console.Write("{0,-" + widths[2] + "}", "N/A"); - Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); - - - // Bjerksund and Stensland approximation for American - method = "Bjerksund/Stensland"; - americanOption.setPricingEngine(new BjerksundStenslandApproximationEngine(bsmProcess)); - - Console.Write("{0,-" + widths[0] + "}", method); - Console.Write("{0,-" + widths[1] + "}", "N/A"); - Console.Write("{0,-" + widths[2] + "}", "N/A"); - Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); - - // Integral - method = "Integral"; - europeanOption.setPricingEngine(new IntegralEngine(bsmProcess)); - - Console.Write("{0,-" + widths[0] + "}", method); - Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); - Console.Write("{0,-" + widths[2] + "}", "N/A"); - Console.WriteLine("{0,-" + widths[3] + "}", "N/A"); - - - // Finite differences - int timeSteps = 801; - method = "Finite differences"; - europeanOption.setPricingEngine(new FDEuropeanEngine(bsmProcess,timeSteps,timeSteps-1)); - bermudanOption.setPricingEngine(new FDBermudanEngine(bsmProcess,timeSteps,timeSteps-1)); - americanOption.setPricingEngine(new FDAmericanEngine(bsmProcess,timeSteps,timeSteps-1)); - - Console.Write("{0,-" + widths[0] + "}", method); - Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); - Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); - Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); - - // Binomial method: Jarrow-Rudd - method = "Binomial Jarrow-Rudd"; - europeanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess,timeSteps)); - bermudanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess,timeSteps)); - americanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess,timeSteps)); - - Console.Write("{0,-" + widths[0] + "}", method); - Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); - Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); - Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); - - - method = "Binomial Cox-Ross-Rubinstein"; - europeanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); - bermudanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); - americanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); - - Console.Write("{0,-" + widths[0] + "}", method); - Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); - Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); - Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); - - // Binomial method: Additive equiprobabilities - method = "Additive equiprobabilities"; - europeanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); - bermudanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); - americanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); - - Console.Write("{0,-" + widths[0] + "}", method); - Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); - Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); - Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); - - // Binomial method: Binomial Trigeorgis - method = "Binomial Trigeorgis"; - europeanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess,timeSteps)); - bermudanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess,timeSteps)); - americanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess,timeSteps)); - - Console.Write("{0,-" + widths[0] + "}", method); - Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); - Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); - Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); - - // Binomial method: Binomial Tian - method = "Binomial Tian"; - europeanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess,timeSteps)); - bermudanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess,timeSteps)); - americanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess,timeSteps)); - - Console.Write("{0,-" + widths[0] + "}", method); - Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); - Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); - Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); - - // Binomial method: Binomial Leisen-Reimer - method = "Binomial Leisen-Reimer"; - europeanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess,timeSteps)); - bermudanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess,timeSteps)); - americanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess,timeSteps)); - - Console.Write("{0,-" + widths[0] + "}", method); - Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); - Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); - Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); - - // Binomial method: Binomial Joshi - method = "Binomial Joshi"; - europeanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess,timeSteps)); - bermudanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess,timeSteps)); - americanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess,timeSteps)); - - Console.Write("{0,-" + widths[0] + "}", method); - Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); - Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); - Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); - - - // Monte Carlo Method: MC (crude) - timeSteps = 1; - method = "MC (crude)"; - ulong mcSeed = 42; - IPricingEngine mcengine1 = new MakeMCEuropeanEngine(bsmProcess) - .withSteps(timeSteps) - .withAbsoluteTolerance(0.02) - .withSeed(mcSeed) - .value(); - europeanOption.setPricingEngine(mcengine1); - // Real errorEstimate = europeanOption.errorEstimate(); - Console.Write("{0,-" + widths[0] + "}", method); - Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); - Console.Write("{0,-" + widths[2] + ":0.000000}", "N/A"); - Console.WriteLine("{0,-" + widths[3] + ":0.000000}", "N/A"); - - - // Monte Carlo Method: QMC (Sobol) - method = "QMC (Sobol)"; - int nSamples = 32768; // 2^15 - - IPricingEngine mcengine2 = new MakeMCEuropeanEngine(bsmProcess) - .withSteps(timeSteps) - .withSamples(nSamples) - .value(); - europeanOption.setPricingEngine(mcengine2); - Console.Write("{0,-" + widths[0] + "}", method); - Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); - Console.Write("{0,-" + widths[2] + ":0.000000}", "N/A"); - Console.WriteLine("{0,-" + widths[3] + ":0.000000}", "N/A"); - - // Monte Carlo Method: MC (Longstaff Schwartz) - method = "MC (Longstaff Schwartz)"; - IPricingEngine mcengine3 = new MakeMCAmericanEngine(bsmProcess) - .withSteps(100) - .withAntitheticVariate() - .withCalibrationSamples(4096) - .withAbsoluteTolerance(0.02) - .withSeed(mcSeed) - .value(); - americanOption.setPricingEngine(mcengine3); - Console.Write("{0,-" + widths[0] + "}", method); - Console.Write("{0,-" + widths[1] + ":0.000000}", "N/A"); - Console.Write("{0,-" + widths[2] + ":0.000000}", "N/A"); - Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); - - // End test - Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); - Console.WriteLine(); - - Console.Write("Press any key to continue ..."); - Console.ReadKey(); - } - } + // set up dates + Calendar calendar = new TARGET(); + Date todaysDate = new Date(15, Month.May, 1998); + Date settlementDate = new Date(17, Month.May, 1998); + Settings.setEvaluationDate(todaysDate); + + // our options + Option.Type type = Option.Type.Put; + double underlying = 36; + double strike = 40; + double dividendYield = 0.00; + double riskFreeRate = 0.06; + double volatility = 0.20; + Date maturity = new Date(17, Month.May, 1999); + DayCounter dayCounter = new Actual365Fixed(); + + Console.WriteLine("Option type = " + type); + Console.WriteLine("Maturity = " + maturity); + Console.WriteLine("Underlying price = " + underlying); + Console.WriteLine("Strike = " + strike); + Console.WriteLine("Risk-free interest rate = {0:0.000000%}", riskFreeRate); + Console.WriteLine("Dividend yield = {0:0.000000%}", dividendYield); + Console.WriteLine("Volatility = {0:0.000000%}", volatility); + Console.Write("\n"); + + string method; + + Console.Write("\n"); + + // write column headings + int[] widths = new int[] { 35, 14, 14, 14 }; + Console.Write("{0,-" + widths[0] + "}", "Method"); + Console.Write("{0,-" + widths[1] + "}", "European"); + Console.Write("{0,-" + widths[2] + "}", "Bermudan"); + Console.WriteLine("{0,-" + widths[3] + "}", "American"); + + List exerciseDates = new List(); ; + for (int i = 1; i <= 4; i++) + exerciseDates.Add(settlementDate + new Period(3 * i, TimeUnit.Months)); + + Exercise europeanExercise = new EuropeanExercise(maturity); + Exercise bermudanExercise = new BermudanExercise(exerciseDates); + Exercise americanExercise = new AmericanExercise(settlementDate, maturity); + + Handle underlyingH = new Handle(new SimpleQuote(underlying)); + + // bootstrap the yield/dividend/vol curves + var flatTermStructure = new Handle(new FlatForward(settlementDate, riskFreeRate, dayCounter)); + var flatDividendTS = new Handle(new FlatForward(settlementDate, dividendYield, dayCounter)); + var flatVolTS = new Handle(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter)); + StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike); + var bsmProcess = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS); + + // options + VanillaOption europeanOption = new VanillaOption(payoff, europeanExercise); + VanillaOption bermudanOption = new VanillaOption(payoff, bermudanExercise); + VanillaOption americanOption = new VanillaOption(payoff, americanExercise); + + + // Analytic formulas: + + // Black-Scholes for European + method = "Black-Scholes"; + europeanOption.setPricingEngine(new AnalyticEuropeanEngine(bsmProcess)); + + Console.Write("{0,-" + widths[0] + "}", method); + Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); + Console.Write("{0,-" + widths[2] + "}", "N/A"); + Console.WriteLine("{0,-" + widths[3] + "}", "N/A"); + + + // Barone-Adesi and Whaley approximation for American + method = "Barone-Adesi/Whaley"; + americanOption.setPricingEngine(new BaroneAdesiWhaleyApproximationEngine(bsmProcess)); + + Console.Write("{0,-" + widths[0] + "}", method); + Console.Write("{0,-" + widths[1] + "}", "N/A"); + Console.Write("{0,-" + widths[2] + "}", "N/A"); + Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); + + + // Bjerksund and Stensland approximation for American + method = "Bjerksund/Stensland"; + americanOption.setPricingEngine(new BjerksundStenslandApproximationEngine(bsmProcess)); + + Console.Write("{0,-" + widths[0] + "}", method); + Console.Write("{0,-" + widths[1] + "}", "N/A"); + Console.Write("{0,-" + widths[2] + "}", "N/A"); + Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); + + // Integral + method = "Integral"; + europeanOption.setPricingEngine(new IntegralEngine(bsmProcess)); + + Console.Write("{0,-" + widths[0] + "}", method); + Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); + Console.Write("{0,-" + widths[2] + "}", "N/A"); + Console.WriteLine("{0,-" + widths[3] + "}", "N/A"); + + + // Finite differences + int timeSteps = 801; + method = "Finite differences"; + europeanOption.setPricingEngine(new FDEuropeanEngine(bsmProcess, timeSteps, timeSteps - 1)); + bermudanOption.setPricingEngine(new FDBermudanEngine(bsmProcess, timeSteps, timeSteps - 1)); + americanOption.setPricingEngine(new FDAmericanEngine(bsmProcess, timeSteps, timeSteps - 1)); + + Console.Write("{0,-" + widths[0] + "}", method); + Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); + Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); + Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); + + // Binomial method: Jarrow-Rudd + method = "Binomial Jarrow-Rudd"; + europeanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + bermudanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + americanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + + Console.Write("{0,-" + widths[0] + "}", method); + Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); + Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); + Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); + + + method = "Binomial Cox-Ross-Rubinstein"; + europeanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + bermudanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + americanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + + Console.Write("{0,-" + widths[0] + "}", method); + Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); + Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); + Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); + + // Binomial method: Additive equiprobabilities + method = "Additive equiprobabilities"; + europeanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + bermudanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + americanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + + Console.Write("{0,-" + widths[0] + "}", method); + Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); + Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); + Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); + + // Binomial method: Binomial Trigeorgis + method = "Binomial Trigeorgis"; + europeanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + bermudanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + americanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + + Console.Write("{0,-" + widths[0] + "}", method); + Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); + Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); + Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); + + // Binomial method: Binomial Tian + method = "Binomial Tian"; + europeanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + bermudanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + americanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + + Console.Write("{0,-" + widths[0] + "}", method); + Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); + Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); + Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); + + // Binomial method: Binomial Leisen-Reimer + method = "Binomial Leisen-Reimer"; + europeanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + bermudanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + americanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + + Console.Write("{0,-" + widths[0] + "}", method); + Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); + Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); + Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); + + // Binomial method: Binomial Joshi + method = "Binomial Joshi"; + europeanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + bermudanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + americanOption.setPricingEngine(new BinomialVanillaEngine(bsmProcess, timeSteps)); + + Console.Write("{0,-" + widths[0] + "}", method); + Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); + Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); + Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); + + + // Monte Carlo Method: MC (crude) + timeSteps = 1; + method = "MC (crude)"; + ulong mcSeed = 42; + IPricingEngine mcengine1 = new MakeMCEuropeanEngine(bsmProcess) + .withSteps(timeSteps) + .withAbsoluteTolerance(0.02) + .withSeed(mcSeed) + .value(); + europeanOption.setPricingEngine(mcengine1); + // Real errorEstimate = europeanOption.errorEstimate(); + Console.Write("{0,-" + widths[0] + "}", method); + Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); + Console.Write("{0,-" + widths[2] + ":0.000000}", "N/A"); + Console.WriteLine("{0,-" + widths[3] + ":0.000000}", "N/A"); + + + // Monte Carlo Method: QMC (Sobol) + method = "QMC (Sobol)"; + int nSamples = 32768; // 2^15 + + IPricingEngine mcengine2 = new MakeMCEuropeanEngine(bsmProcess) + .withSteps(timeSteps) + .withSamples(nSamples) + .value(); + europeanOption.setPricingEngine(mcengine2); + Console.Write("{0,-" + widths[0] + "}", method); + Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); + Console.Write("{0,-" + widths[2] + ":0.000000}", "N/A"); + Console.WriteLine("{0,-" + widths[3] + ":0.000000}", "N/A"); + + // Monte Carlo Method: MC (Longstaff Schwartz) + method = "MC (Longstaff Schwartz)"; + IPricingEngine mcengine3 = new MakeMCAmericanEngine(bsmProcess) + .withSteps(100) + .withAntitheticVariate() + .withCalibrationSamples(4096) + .withAbsoluteTolerance(0.02) + .withSeed(mcSeed) + .value(); + americanOption.setPricingEngine(mcengine3); + Console.Write("{0,-" + widths[0] + "}", method); + Console.Write("{0,-" + widths[1] + ":0.000000}", "N/A"); + Console.Write("{0,-" + widths[2] + ":0.000000}", "N/A"); + Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); + + // End test + Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); + Console.WriteLine(); + + Console.Write("Press any key to continue ..."); + Console.ReadKey(); + } + } } diff --git a/src/EquityOption/EquityOption.csproj b/src/EquityOption/EquityOption.csproj index 3d9b9caa2..054d58bde 100644 --- a/src/EquityOption/EquityOption.csproj +++ b/src/EquityOption/EquityOption.csproj @@ -1,7 +1,7 @@  - 1.10.0 + 1.11.0 net45 $(DefineConstants);QL_NEGATIVE_RATES EquityOption diff --git a/src/FRA/FRA.cs b/src/FRA/FRA.cs index c3d4f7906..00cb7334f 100644 --- a/src/FRA/FRA.cs +++ b/src/FRA/FRA.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project http://qlnet.sourceforge.net/ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,227 +23,232 @@ under the terms of the QLNet license. You should have received a using System.Text; using QLNet; -namespace FRA { - class FRA { - static void Main() { - - DateTime timer = DateTime.Now; +namespace FRA +{ + class FRA + { + static void Main() + { + + DateTime timer = DateTime.Now; - /********************* - *** MARKET DATA *** - *********************/ + /********************* + *** MARKET DATA *** + *********************/ - RelinkableHandle euriborTermStructure = new RelinkableHandle(); - IborIndex euribor3m = new Euribor3M(euriborTermStructure); + RelinkableHandle euriborTermStructure = new RelinkableHandle(); + IborIndex euribor3m = new Euribor3M(euriborTermStructure); - Date todaysDate = new Date(23, Month.May, 2006); - Settings.setEvaluationDate(todaysDate); + Date todaysDate = new Date(23, Month.May, 2006); + Settings.setEvaluationDate(todaysDate); - Calendar calendar = euribor3m.fixingCalendar(); - int fixingDays = euribor3m.fixingDays(); - Date settlementDate = calendar.advance(todaysDate, fixingDays, TimeUnit.Days); + Calendar calendar = euribor3m.fixingCalendar(); + int fixingDays = euribor3m.fixingDays(); + Date settlementDate = calendar.advance(todaysDate, fixingDays, TimeUnit.Days); - Console.WriteLine("Today: " + todaysDate.DayOfWeek + ", " + todaysDate); - Console.WriteLine("Settlement date: " + settlementDate.DayOfWeek + ", " + settlementDate); + Console.WriteLine("Today: " + todaysDate.DayOfWeek + ", " + todaysDate); + Console.WriteLine("Settlement date: " + settlementDate.DayOfWeek + ", " + settlementDate); - // 3 month term FRA quotes (index refers to monthsToStart) - double[] threeMonthFraQuote = new double[10]; + // 3 month term FRA quotes (index refers to monthsToStart) + double[] threeMonthFraQuote = new double[10]; - threeMonthFraQuote[1]=0.030; - threeMonthFraQuote[2]=0.031; - threeMonthFraQuote[3]=0.032; - threeMonthFraQuote[6]=0.033; - threeMonthFraQuote[9]=0.034; + threeMonthFraQuote[1] = 0.030; + threeMonthFraQuote[2] = 0.031; + threeMonthFraQuote[3] = 0.032; + threeMonthFraQuote[6] = 0.033; + threeMonthFraQuote[9] = 0.034; - /******************** - *** QUOTES *** - ********************/ + /******************** + *** QUOTES *** + ********************/ - // SimpleQuote stores a value which can be manually changed; - // other Quote subclasses could read the value from a database - // or some kind of data feed. + // SimpleQuote stores a value which can be manually changed; + // other Quote subclasses could read the value from a database + // or some kind of data feed. - // FRAs - SimpleQuote fra1x4Rate = new SimpleQuote(threeMonthFraQuote[1]); - SimpleQuote fra2x5Rate = new SimpleQuote(threeMonthFraQuote[2]); - SimpleQuote fra3x6Rate = new SimpleQuote(threeMonthFraQuote[3]); - SimpleQuote fra6x9Rate = new SimpleQuote(threeMonthFraQuote[6]); - SimpleQuote fra9x12Rate = new SimpleQuote(threeMonthFraQuote[9]); + // FRAs + SimpleQuote fra1x4Rate = new SimpleQuote(threeMonthFraQuote[1]); + SimpleQuote fra2x5Rate = new SimpleQuote(threeMonthFraQuote[2]); + SimpleQuote fra3x6Rate = new SimpleQuote(threeMonthFraQuote[3]); + SimpleQuote fra6x9Rate = new SimpleQuote(threeMonthFraQuote[6]); + SimpleQuote fra9x12Rate = new SimpleQuote(threeMonthFraQuote[9]); - RelinkableHandle h1x4 = new RelinkableHandle(); h1x4.linkTo(fra1x4Rate); - RelinkableHandle h2x5 = new RelinkableHandle(); h2x5.linkTo(fra2x5Rate); - RelinkableHandle h3x6 = new RelinkableHandle(); h3x6.linkTo(fra3x6Rate); - RelinkableHandle h6x9 = new RelinkableHandle(); h6x9.linkTo(fra6x9Rate); - RelinkableHandle h9x12 = new RelinkableHandle(); h9x12.linkTo(fra9x12Rate); + RelinkableHandle h1x4 = new RelinkableHandle(); h1x4.linkTo(fra1x4Rate); + RelinkableHandle h2x5 = new RelinkableHandle(); h2x5.linkTo(fra2x5Rate); + RelinkableHandle h3x6 = new RelinkableHandle(); h3x6.linkTo(fra3x6Rate); + RelinkableHandle h6x9 = new RelinkableHandle(); h6x9.linkTo(fra6x9Rate); + RelinkableHandle h9x12 = new RelinkableHandle(); h9x12.linkTo(fra9x12Rate); - /********************* - *** RATE HELPERS *** - *********************/ + /********************* + *** RATE HELPERS *** + *********************/ - // RateHelpers are built from the above quotes together with - // other instrument dependant infos. Quotes are passed in - // relinkable handles which could be relinked to some other - // data source later. + // RateHelpers are built from the above quotes together with + // other instrument dependant infos. Quotes are passed in + // relinkable handles which could be relinked to some other + // data source later. - DayCounter fraDayCounter = euribor3m.dayCounter(); - BusinessDayConvention convention = euribor3m.businessDayConvention(); - bool endOfMonth = euribor3m.endOfMonth(); + DayCounter fraDayCounter = euribor3m.dayCounter(); + BusinessDayConvention convention = euribor3m.businessDayConvention(); + bool endOfMonth = euribor3m.endOfMonth(); - RateHelper fra1x4 = new FraRateHelper(h1x4, 1, 4, - fixingDays, calendar, convention, - endOfMonth, fraDayCounter); + RateHelper fra1x4 = new FraRateHelper(h1x4, 1, 4, + fixingDays, calendar, convention, + endOfMonth, fraDayCounter); - RateHelper fra2x5 = new FraRateHelper(h2x5, 2, 5, - fixingDays, calendar, convention, - endOfMonth, fraDayCounter); + RateHelper fra2x5 = new FraRateHelper(h2x5, 2, 5, + fixingDays, calendar, convention, + endOfMonth, fraDayCounter); - RateHelper fra3x6 = new FraRateHelper(h3x6, 3, 6, - fixingDays, calendar, convention, - endOfMonth, fraDayCounter); + RateHelper fra3x6 = new FraRateHelper(h3x6, 3, 6, + fixingDays, calendar, convention, + endOfMonth, fraDayCounter); - RateHelper fra6x9 = new FraRateHelper(h6x9, 6, 9, - fixingDays, calendar, convention, - endOfMonth, fraDayCounter); + RateHelper fra6x9 = new FraRateHelper(h6x9, 6, 9, + fixingDays, calendar, convention, + endOfMonth, fraDayCounter); - RateHelper fra9x12 = new FraRateHelper(h9x12, 9, 12, - fixingDays, calendar, convention, - endOfMonth, fraDayCounter); + RateHelper fra9x12 = new FraRateHelper(h9x12, 9, 12, + fixingDays, calendar, convention, + endOfMonth, fraDayCounter); - /********************* - ** CURVE BUILDING ** - *********************/ + /********************* + ** CURVE BUILDING ** + *********************/ - // Any DayCounter would be fine. - // ActualActual::ISDA ensures that 30 years is 30.0 - DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA); + // Any DayCounter would be fine. + // ActualActual::ISDA ensures that 30 years is 30.0 + DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA); - double tolerance = 1.0e-15; + double tolerance = 1.0e-15; - // A FRA curve - List fraInstruments = new List(); + // A FRA curve + List fraInstruments = new List(); - fraInstruments.Add(fra1x4); - fraInstruments.Add(fra2x5); - fraInstruments.Add(fra3x6); - fraInstruments.Add(fra6x9); - fraInstruments.Add(fra9x12); + fraInstruments.Add(fra1x4); + fraInstruments.Add(fra2x5); + fraInstruments.Add(fra3x6); + fraInstruments.Add(fra6x9); + fraInstruments.Add(fra9x12); - YieldTermStructure fraTermStructure = new PiecewiseYieldCurve( - settlementDate, fraInstruments, termStructureDayCounter, - new List>(), new List(), tolerance); + YieldTermStructure fraTermStructure = new PiecewiseYieldCurve( + settlementDate, fraInstruments, termStructureDayCounter, + new List>(), new List(), tolerance); - // Term structures used for pricing/discounting - RelinkableHandle discountingTermStructure = new RelinkableHandle(); - discountingTermStructure.linkTo(fraTermStructure); + // Term structures used for pricing/discounting + RelinkableHandle discountingTermStructure = new RelinkableHandle(); + discountingTermStructure.linkTo(fraTermStructure); - /*********************** - *** construct FRA's *** - ***********************/ + /*********************** + *** construct FRA's *** + ***********************/ - Calendar fraCalendar = euribor3m.fixingCalendar(); - BusinessDayConvention fraBusinessDayConvention = euribor3m.businessDayConvention(); - Position.Type fraFwdType = Position.Type.Long; - double fraNotional = 100.0; - const int FraTermMonths = 3; - int[] monthsToStart = new [] { 1, 2, 3, 6, 9 }; + Calendar fraCalendar = euribor3m.fixingCalendar(); + BusinessDayConvention fraBusinessDayConvention = euribor3m.businessDayConvention(); + Position.Type fraFwdType = Position.Type.Long; + double fraNotional = 100.0; + const int FraTermMonths = 3; + int[] monthsToStart = new [] { 1, 2, 3, 6, 9 }; - euriborTermStructure.linkTo(fraTermStructure); + euriborTermStructure.linkTo(fraTermStructure); - Console.WriteLine("\nTest FRA construction, NPV calculation, and FRA purchase\n"); + Console.WriteLine("\nTest FRA construction, NPV calculation, and FRA purchase\n"); - int i; - for (i=0; i - 1.10.0 + 1.11.0 net45 $(DefineConstants);QL_NEGATIVE_RATES FRA diff --git a/src/FittedBondCurve/FittedBondCurve.cs b/src/FittedBondCurve/FittedBondCurve.cs index 6452edcea..28202f50c 100644 --- a/src/FittedBondCurve/FittedBondCurve.cs +++ b/src/FittedBondCurve/FittedBondCurve.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -33,29 +33,29 @@ namespace FittedBondCurve class FittedBondCurve { // par-rate approximation - public static double parRate(YieldTermStructure yts,List dates,DayCounter resultDayCounter) + public static double parRate(YieldTermStructure yts, List dates, DayCounter resultDayCounter) { - Utils.QL_REQUIRE(dates.Count >= 2,()=> "at least two dates are required"); + Utils.QL_REQUIRE(dates.Count >= 2, () => "at least two dates are required"); double sum = 0.0; double dt; - for (int i=1; i=0.0,()=> "unsorted dates"); + dt = resultDayCounter.yearFraction(dates[i - 1], dates[i]); + Utils.QL_REQUIRE(dt >= 0.0, () => "unsorted dates"); sum += yts.discount(dates[i]) * dt; } double result = yts.discount(dates.First()) - yts.discount(dates.Last()); - return result/sum; + return result / sum; } - public static void printOutput(string tag, FittedBondDiscountCurve curve) + public static void printOutput(string tag, FittedBondDiscountCurve curve) { Console.WriteLine(tag) ; Console.WriteLine("reference date : " + curve.referenceDate()); - Console.WriteLine("number of iterations : " + curve.fitResults().numberOfIterations() +"\n"); + Console.WriteLine("number of iterations : " + curve.fitResults().numberOfIterations() + "\n"); } - static void Main( string[] args ) + static void Main(string[] args) { try { @@ -66,30 +66,32 @@ static void Main( string[] args ) double[] cleanPrice = new double[numberOfBonds]; - for (int i=0; i quote = new List(); - for (int i=0; i[] quoteHandle = new RelinkableHandle[numberOfBonds]; - for (int i=0; i(); + quoteHandle[i] = new RelinkableHandle(); quoteHandle[i].linkTo(quote[i]); } int[] lengths = { 2, 4, 6, 8, 10, 12, 14, 16, - 18, 20, 22, 24, 26, 28, 30 }; + 18, 20, 22, 24, 26, 28, 30 + }; double[] coupons = { 0.0200, 0.0225, 0.0250, 0.0275, 0.0300, 0.0325, 0.0350, 0.0375, 0.0400, 0.0425, - 0.0450, 0.0475, 0.0500, 0.0525, 0.0550 }; + 0.0450, 0.0475, 0.0500, 0.0525, 0.0550 + }; Frequency frequency = Frequency.Annual; DayCounter dc = new SimpleDayCounter(); @@ -107,19 +109,19 @@ static void Main( string[] args ) int bondSettlementDays = 0; int curveSettlementDays = 0; - Date bondSettlementDate = calendar.advance(today, new Period(bondSettlementDays,TimeUnit.Days)); + Date bondSettlementDate = calendar.advance(today, new Period(bondSettlementDays, TimeUnit.Days)); Console.WriteLine(); - Console.WriteLine("Today's date: " + today ); - Console.WriteLine("Bonds' settlement date: " + bondSettlementDate ); - Console.WriteLine("Calculating fit for 15 bonds.....\n" ); + Console.WriteLine("Today's date: " + today); + Console.WriteLine("Bonds' settlement date: " + bondSettlementDate); + Console.WriteLine("Calculating fit for 15 bonds.....\n"); List instrumentsA = new List(); List instrumentsB = new List(); - for (int j=0; j< lengths.Length; j++) + for (int j = 0; j < lengths.Length; j++) { - Date maturity = calendar.advance(bondSettlementDate, new Period(lengths[j],TimeUnit.Years)); + Date maturity = calendar.advance(bondSettlementDate, new Period(lengths[j], TimeUnit.Years)); Schedule schedule = new Schedule(bondSettlementDate, maturity, new Period(frequency), calendar, accrualConvention, accrualConvention, @@ -129,19 +131,19 @@ static void Main( string[] args ) bondSettlementDays, 100.0, schedule, - new InitializedList(1,coupons[j]), + new InitializedList(1, coupons[j]), dc, convention, redemption); - RateHelper helperB = new FixedRateBondHelper(quoteHandle[j], - bondSettlementDays, - 100.0, - schedule, - new InitializedList(1, coupons[j]), - dc, - convention, - redemption); + RateHelper helperB = new FixedRateBondHelper(quoteHandle[j], + bondSettlementDays, + 100.0, + schedule, + new InitializedList(1, coupons[j]), + dc, + convention, + redemption); instrumentsA.Add(helperA); instrumentsB.Add(helperB); } @@ -151,20 +153,20 @@ static void Main( string[] args ) double tolerance = 1.0e-10; int max = 5000; - YieldTermStructure ts0 = new PiecewiseYieldCurve(curveSettlementDays, - calendar, - instrumentsB, - dc); + YieldTermStructure ts0 = new PiecewiseYieldCurve(curveSettlementDays, + calendar, + instrumentsB, + dc); ExponentialSplinesFitting exponentialSplines = new ExponentialSplinesFitting(constrainAtZero); FittedBondDiscountCurve ts1 = new FittedBondDiscountCurve(curveSettlementDays, - calendar, - instrumentsA, - dc, - exponentialSplines, - tolerance, - max); + calendar, + instrumentsA, + dc, + exponentialSplines, + tolerance, + max); printOutput("(a) exponential splines", ts1); @@ -199,10 +201,11 @@ static void Main( string[] args ) // n=6 (constrained problem) basis functions double[] knots = { -30.0, -20.0, 0.0, 5.0, 10.0, 15.0, - 20.0, 25.0, 30.0, 40.0, 50.0 }; + 20.0, 25.0, 30.0, 40.0, 50.0 + }; List knotVector = new List(); - for (int i=0; i< knots.Length; i++) + for (int i = 0; i < knots.Length; i++) { knotVector.Add(knots[i]); } @@ -234,15 +237,15 @@ static void Main( string[] args ) Handle discountCurve = new Handle( new FlatForward(curveSettlementDays, calendar, 0.01, dc)); - SpreadFittingMethod nelsonSiegelSpread = new SpreadFittingMethod(new NelsonSiegelFitting(),discountCurve); + SpreadFittingMethod nelsonSiegelSpread = new SpreadFittingMethod(new NelsonSiegelFitting(), discountCurve); - FittedBondDiscountCurve ts6 = new FittedBondDiscountCurve( curveSettlementDays, - calendar, - instrumentsA, - dc, - nelsonSiegelSpread, - tolerance, - max); + FittedBondDiscountCurve ts6 = new FittedBondDiscountCurve(curveSettlementDays, + calendar, + instrumentsA, + dc, + nelsonSiegelSpread, + tolerance, + max); printOutput("(f) Nelson-Siegel spreaded", ts6); @@ -250,17 +253,17 @@ static void Main( string[] args ) Console.WriteLine("Output par rates for each curve. In this case, "); Console.WriteLine("par rates should equal coupons for these par bonds.\n"); - Console.WriteLine( " tenor" + " | " - + "coupon" + " | " - + "bstrap" + " | " - + " (a)" + " | " - + " (b)" + " | " - + " (c)" + " | " - + " (d)" + " | " - + " (e)" + " | " - + " (f)" ); - - for (int i=0; i cfs = instrumentsA[i].bond().cashflows(); @@ -269,48 +272,48 @@ static void Main( string[] args ) List keyDates = new List(); keyDates.Add(bondSettlementDate); - for (int j=0; j cfs = instrumentsA[i].bond().cashflows(); @@ -345,55 +348,55 @@ static void Main( string[] args ) List keyDates = new List(); keyDates.Add(bondSettlementDate); - for (int j=0; j(curveSettlementDays, - calendar, - instrumentsB, - dc); + YieldTermStructure ts00 = new PiecewiseYieldCurve(curveSettlementDays, + calendar, + instrumentsB, + dc); FittedBondDiscountCurve ts11 = new FittedBondDiscountCurve(curveSettlementDays, calendar, @@ -458,17 +461,17 @@ static void Main( string[] args ) printOutput("(f) Nelson-Siegel spreaded", ts66); - Console.WriteLine( " tenor" + " | " - + "coupon" + " | " - + "bstrap" + " | " - + " (a)" + " | " - + " (b)" + " | " - + " (c)" + " | " - + " (d)" + " | " - + " (e)" + " | " - + " (f)" ); - - for (int i=0; i cfs = instrumentsA[i].bond().cashflows(); @@ -476,33 +479,33 @@ static void Main( string[] args ) List keyDates = new List(); keyDates.Add(bondSettlementDate); - for (int j=0; j cfs = instrumentsA[i].bond().cashflows(); @@ -547,33 +550,33 @@ static void Main( string[] args ) List keyDates = new List(); keyDates.Add(bondSettlementDate); - for (int j=0; j - 1.10.0 + 1.11.0 net45 $(DefineConstants);QL_NEGATIVE_RATES FittedBondCurve diff --git a/src/QLNet.Old/AssemblyInfo.cs b/src/QLNet.Old/AssemblyInfo.cs index d0d9b71ba..299b8eb83 100644 --- a/src/QLNet.Old/AssemblyInfo.cs +++ b/src/QLNet.Old/AssemblyInfo.cs @@ -1,7 +1,7 @@ using System.Reflection; using System.Runtime.InteropServices; -// Le informazioni generali relative a un assembly sono controllate dal seguente +// Le informazioni generali relative a un assembly sono controllate dal seguente // insieme di attributi. Per modificare le informazioni associate a un assembly // occorre quindi modificare i valori di questi attributi. [assembly: AssemblyTitle("QLNet")] @@ -9,12 +9,12 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("QLNet")] -[assembly: AssemblyCopyright("Copyright (c) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com)")] +[assembly: AssemblyCopyright("Copyright (c) 2008-2018 Andrea Maggiulli (a.maggiulli@gmail.com)")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili -// ai componenti COM. Se è necessario accedere a un tipo in questo assembly da +// Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili +// ai componenti COM. Se è necessario accedere a un tipo in questo assembly da // COM, impostare su true l'attributo ComVisible per tale tipo. [assembly: ComVisible(false)] @@ -24,11 +24,11 @@ // Le informazioni sulla versione di un assembly sono costituite dai seguenti quattro valori: // // Numero di versione principale -// Numero di versione secondario +// Numero di versione secondario // Numero build // Revisione // -// È possibile specificare tutti i valori o impostare come predefiniti i valori Numero revisione e Numero build +// È possibile specificare tutti i valori o impostare come predefiniti i valori Numero revisione e Numero build // utilizzando l'asterisco (*) come descritto di seguito: -[assembly: AssemblyVersion( "1.10.0.0" )] -[assembly: AssemblyFileVersion( "1.10.0.0" )] +[assembly: AssemblyVersion("1.11.0.0")] +[assembly: AssemblyFileVersion("1.11.0.0")] diff --git a/src/QLNet.Old/QLNet.Old.csproj b/src/QLNet.Old/QLNet.Old.csproj index e820a2466..7f6bb6b54 100644 --- a/src/QLNet.Old/QLNet.Old.csproj +++ b/src/QLNet.Old/QLNet.Old.csproj @@ -1,2099 +1,2108 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {F6E762BD-DCDF-4CA0-ABAD-CB21C7D03BEC} - Library - Properties - QLNet - QLNet - - - 3.5 - - - v4.0 - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - - true - full - false - bin\Debug\net40\ - TRACE;DEBUG;QL_NEGATIVE_RATES,NET40 - prompt - 4 - false - AllRules.ruleset - false - - - pdbonly - true - bin\Release\net40\ - TRACE;QL_NEGATIVE_RATES,QL_DOTNET_FRAMEWORK - prompt - 4 - AllRules.ruleset - false - - - true - bin\Debug\net45\ - TRACE;DEBUG;QL_NEGATIVE_RATES,QL_DOTNET_FRAMEWORK - full - v4.5 - AnyCPU - prompt - AllRules.ruleset - - - bin\Release\net45\ - TRACE;QL_NEGATIVE_RATES,QL_DOTNET_FRAMEWORK - true - pdbonly - v4.5 - AnyCPU - prompt - AllRules.ruleset - - - - - - - - - - - Cashflows\AverageBMACoupon.cs - - - Cashflows\CappedFlooredCoupon.cs - - - Cashflows\CappedFlooredYoYInflationCoupon.cs - - - Cashflows\CashFlows.cs - - - Cashflows\Cashflowvectors.cs - - - Cashflows\CmsCoupon.cs - - - Cashflows\ConundrumPricer.cs - - - Cashflows\Coupon.cs - - - Cashflows\CouponPricer.cs - - - Cashflows\CPICoupon.cs - - - Cashflows\CPICouponPricer.cs - - - Cashflows\DigitalCmsCoupon.cs - - - Cashflows\DigitalCoupon.cs - - - Cashflows\DigitalIborCoupon.cs - - - Cashflows\Dividend.cs - - - Cashflows\FixedRateCoupon.cs - - - Cashflows\FloatingRateCoupon.cs - - - Cashflows\Iborcoupon.cs - - - Cashflows\IndexedCashFlow.cs - - - Cashflows\InflationCoupon.cs - - - Cashflows\InflationCouponPricer.cs - - - Cashflows\LinearTsrPricer.cs - - - Cashflows\OvernightIndexedCoupon.cs - - - Cashflows\Principal.cs - - - Cashflows\PrincipalLegBase.cs - - - Cashflows\RangeAccrual.cs - - - Cashflows\RateLegBase.cs - - - Cashflows\Replication.cs - - - Cashflows\SimpleCashFlow.cs - - - Cashflows\YoYInflationCoupon.cs - - - Currencies\Africa.cs - - - Currencies\America.cs - - - Currencies\Asia.cs - - - Currencies\Currency.cs - - - Currencies\Europe.cs - - - Currencies\ExchangeRate.cs - - - Currencies\ExchangeRateManager.cs - - - Currencies\Oceania.cs - - - - - - Extensions\DoubleExtension.cs - - - Extensions\ListExtension.cs - - - - - - Indexes\BMAIndex.cs - - - Indexes\IborIndex.cs - - - Indexes\Ibor\Aonia.cs - - - Indexes\Ibor\Audlibor.cs - - - Indexes\Ibor\Bbsw.cs - - - Indexes\Ibor\Bkbm.cs - - - Indexes\Ibor\Cadlibor.cs - - - Indexes\Ibor\Cdor.cs - - - Indexes\Ibor\Chflibor.cs - - - Indexes\Ibor\Dkklibor.cs - - - Indexes\Ibor\Eonia.cs - - - Indexes\Ibor\Euribor.cs - - - Indexes\Ibor\Eurlibor.cs - - - Indexes\Ibor\FedFunds.cs - - - Indexes\Ibor\Gbplibor.cs - - - Indexes\Ibor\Jibar.cs - - - Indexes\Ibor\Jpylibor.cs - - - Indexes\Ibor\Libor.cs - - - Indexes\Ibor\Nzdlibor.cs - - - Indexes\Ibor\Nzocr.cs - - - Indexes\Ibor\Seklibor.cs - - - Indexes\Ibor\Shibor.cs - - - Indexes\Ibor\Sonia.cs - - - Indexes\Ibor\Tibor.cs - - - Indexes\Ibor\Trylibor.cs - - - Indexes\Ibor\Usdlibor.cs - - - Indexes\Ibor\Zibor.cs - - - Indexes\Indexmanager.cs - - - Indexes\InflationIndex.cs - - - Indexes\Inflation\AUCPI.cs - - - Indexes\Inflation\EUHICP.cs - - - Indexes\Inflation\FRHICP.cs - - - Indexes\Inflation\UKRPI.cs - - - Indexes\Inflation\USCPI.cs - - - Indexes\Inflation\ZACPI.cs - - - Indexes\InterestRateIndex.cs - - - Indexes\Region.cs - - - Indexes\Swapindex.cs - - - Indexes\Swap\ChfLiborSwap.cs - - - Indexes\Swap\EuriborSwap.cs - - - Indexes\Swap\EurLiborSwap.cs - - - Indexes\Swap\GbpLiborSwap.cs - - - Indexes\Swap\JpyLiborSwap.cs - - - Indexes\Swap\UsdLiborSwap.cs - - - Instruments\AsianOption.cs - - - Code - Instruments\AssetSwap.cs - - - Instruments\AverageType.cs - - - Instruments\BarrierOption.cs - - - Instruments\BarrierType.cs - - - Instruments\BasisSwap.cs - - - Instruments\BasketOption.cs - - - Instruments\bmaswap.cs - - - Instruments\Bond.cs - - - Instruments\Bonds\AmortizingBond.cs - - - Instruments\Bonds\AmortizingCmsRateBond.cs - - - Instruments\Bonds\AmortizingFixedRateBond.cs - - - Instruments\Bonds\AmortizingFloatingRateBond.cs - - - Instruments\Bonds\BondFactory.cs - - - Instruments\Bonds\BTP.cs - - - Instruments\Bonds\CallableBond.cs - - - Instruments\Bonds\CmsRateBond.cs - - - Instruments\Bonds\ConstantCPR.cs - - - Instruments\Bonds\ConvertibleBond.cs - - - Instruments\Bonds\CPIBond.cs - - - Instruments\Bonds\DiscretizedCallableFixedRateBond.cs - - - Instruments\Bonds\Fixedratebond.cs - - - Instruments\Bonds\FloatingRateBond.cs - - - Instruments\Bonds\IPrepayModel.cs - - - Instruments\Bonds\MBSFixedRateBond.cs - - - Instruments\Bonds\PSACurve.cs - - - Instruments\Bonds\Zerocouponbond.cs - - - Instruments\Callability.cs - - - Instruments\CapFloor.cs - - - Instruments\Claim.cs - - - Instruments\CliquetOption.cs - - - Instruments\CompositeInstrument.cs - - - Instruments\CPICapFloor.cs - - - Instruments\CPISwap.cs - - - Instruments\CreditDefaultSwap.cs - - - Instruments\DividendBarrierOption.cs - - - Instruments\DividendSchedule.cs - - - Instruments\DividendVanillaOption.cs - - - Instruments\DoubleBarrierOption.cs - - - Instruments\EuropeanOption.cs - - - Instruments\fixedratebondforward.cs - - - Instruments\forward.cs - - - Instruments\forwardrateagreement.cs - - - Instruments\ForwardVanillaOption.cs - - - Instruments\Futures.cs - - - Instruments\ImpliedVolatility.cs - - - Instruments\InflationCapFloor.cs - - - Instruments\Instrument.cs - - - Instruments\Loan.cs - - - Instruments\LookbackOption.cs - - - Instruments\MakeBasisSwap.cs - - - Instruments\MakeCapFloor.cs - - - Instruments\MakeCms.cs - - - Instruments\MakeLoans.cs - - - Instruments\MakeOIS.cs - - - Instruments\MakeCDS.cs - - - Instruments\Makeswaption.cs - - - Instruments\Makevanillaswap.cs - - - Instruments\MultiAssetOption.cs - - - Instruments\OneAssetOption.cs - - - Instruments\OvernightIndexedSwap.cs - - - - Instruments\Stock.cs - - - Instruments\Swap.cs - - - Instruments\Swaption.cs - - - Instruments\VanillaOption.cs - - - Instruments\VanillaSwap.cs - - - Instruments\YearOnYearInflationSwap.cs - - - Instruments\ZeroCouponInflationSwap.cs - - - - legacy\libormarketmodels\lfmcovarparam.cs - - - legacy\libormarketmodels\lfmcovarproxy.cs - - - legacy\libormarketmodels\lfmhullwhiteparam.cs - - - legacy\libormarketmodels\lfmprocess.cs - - - legacy\libormarketmodels\lfmswaptionengine.cs - - - legacy\libormarketmodels\liborforwardmodel.cs - - - legacy\libormarketmodels\lmconstwrappercorrmodel.cs - - - legacy\libormarketmodels\lmconstwrappervolmodel.cs - - - legacy\libormarketmodels\lmcorrmodel.cs - - - legacy\libormarketmodels\lmexpcorrmodel.cs - - - legacy\libormarketmodels\lmextlinexpvolmodel.cs - - - legacy\libormarketmodels\lmfixedvolmodel.cs - - - legacy\libormarketmodels\lmlinexpcorrmodel.cs - - - legacy\libormarketmodels\lmlinexpvolmodel.cs - - - legacy\libormarketmodels\lmvolmodel.cs - - - Math\AbcdMathFunction.cs - - - Math\BernsteinPolynomial.cs - - - Math\beta.cs - - - Math\BSpline.cs - - - Math\Comparison.cs - - - Math\NumericalDifferentiation.cs - - - Math\integrals\GaussLobattoIntegral.cs - - - Math\integrals\DiscreteIntegrals.cs - - - Math\Interpolations\Abcdinterpolation.cs - - - Math\Interpolations\BackwardflatLinearInterpolation.cs - - - Math\Interpolations\FlatExtrapolator2D.cs - - - Math\Interpolations\MixedInterpolation.cs - - - Math\Interpolations\VannaVolgaInterpolation.cs - - - Math\Interpolations\SviInterpolation.cs - - - Math\Optimization\BFGS.cs - - - Math\Optimization\CostFunction.cs - - - Math\Distributions\binomialdistribution.cs - - - Math\Distributions\BivariateNormalDistribution.cs - - - Math\Distributions\chisquaredistribution.cs - - - Math\Distributions\GammaDistribution.cs - - - Math\Distributions\NormalDistribution.cs - - - Math\Distributions\poissondistribution.cs - - - Math\factorial.cs - - - Math\integrals\gaussianorthogonalpolynomial.cs - - - Math\integrals\GaussianQuadratures.cs - - - Math\integrals\Integral.cs - - - Math\integrals\Kronrodintegral.cs - - - Math\integrals\Segmentintegral.cs - - - Math\integrals\simpsonintegral.cs - - - Math\integrals\trapezoidintegral.cs - - - Math\Interpolations\backwardflatinterpolation.cs - - - Math\Interpolations\BicubicSplineInterpolation.cs - - - Math\Interpolations\bilinearinterpolation.cs - - - Math\Interpolations\convexmonotoneinterpolation.cs - - - Math\Interpolations\CubicInterpolation.cs - - - Math\Interpolations\Extrapolator.cs - - - Math\Interpolation.cs - - - Math\Interpolations\forwardflatinterpolation.cs - - - Math\Interpolations\interpolation2d.cs - - - Math\Interpolations\KernelInterpolation.cs - - - Math\Interpolations\KernelInterpolation2D.cs - - - Math\Interpolations\Linearinterpolation.cs - - - Math\Interpolations\Loginterpolation.cs - - - Math\Interpolations\multicubicspline.cs - - - Math\Interpolations\sabrinterpolation.cs - - - Math\Interpolations\XABRInterpolation.cs - - - Math\KernelFunctions.cs - - - Math\matrixutilities\TqrEigenDecomposition.cs - - - Math\matrixutilities\BiCGStab.cs - - - Math\matrixutilities\GMRES.cs - - - Math\ODE\AdaptiveRungeKutta.cs - - - Math\matrixutilities\SparseMatrix.cs - - - Math\linearleastsquaresregression.cs - - - Math\Matrix.cs - - - Math\matrixutilities\choleskydecomposition.cs - - - Math\matrixutilities\pseudosqrt.cs - - - Math\matrixutilities\qrdecomposition.cs - - - Math\matrixutilities\svd.cs - - - Math\matrixutilities\symmetricschurdecomposition.cs - - - Math\ModifiedBessel.cs - - - Math\Optimization\ArmijoLineSearch.cs - - - Math\Optimization\ConjugateGradient.cs - - - Math\Optimization\Constraint.cs - - - Math\Optimization\EndCriteria.cs - - - Math\Optimization\GoldsteinLineSearch.cs - - - Math\Optimization\LeastSquareProblem.cs - - - Math\Optimization\levenbergmarquardt.cs - - - Math\Optimization\LineSearch.cs - - - Math\Optimization\LineSearchBasedMethod.cs - - - Math\Optimization\lmdif.cs - - - Math\Optimization\method.cs - - - Math\Optimization\problem.cs - - - Math\Optimization\ProjectedConstraint.cs - - - Math\Optimization\ProjectedCostFunction.cs - - - Math\Optimization\Projection.cs - - - Math\Optimization\Simplex.cs - - - Math\Optimization\SteepestDescent.cs - - - Math\PascalTriangle.cs - - - Math\PolynomialFunction.cs - - - Math\PrimeNumbers.cs - - - Math\randomnumbers\Haltonrsg.cs - - - Math\randomnumbers\inversecumulativerng.cs - - - Math\randomnumbers\inversecumulativersg.cs - - - Math\randomnumbers\mt19937uniformrng.cs - - - Math\randomnumbers\primitivepolynomials.cs - - - Math\randomnumbers\randomsequencegenerator.cs - - - Math\randomnumbers\rngtraits.cs - - - Math\randomnumbers\seedgenerator.cs - - - Math\randomnumbers\SobolBrownianBridgeRsg.cs - - - Math\randomnumbers\sobolrsg.cs - - - Math\randomnumbers\sobolrsg2.cs - - - Math\RichardsonExtrapolation.cs - - - Math\SampledCurve.cs - - - Math\Solver1d.cs - - - Math\Rounding.cs - - - Code - Math\Solvers1d\Bisection.cs - - - Code - Math\Solvers1d\Brent.cs - - - Code - Math\Solvers1d\FalsePosition.cs - - - Math\Solvers1d\FiniteDifferenceNewtonSafe.cs - - - Math\Solvers1d\Newton.cs - - - Math\Solvers1d\Newtonsafe.cs - - - Code - Math\Solvers1d\Ridder.cs - - - Math\Solvers1d\Secant.cs - - - Math\statistics\convergencestatistics.cs - - - Math\statistics\DiscrepancyStatistics.cs - - - Math\statistics\gaussianstatistics.cs - - - Math\statistics\generalstatistics.cs - - - Math\statistics\incrementalstatistics.cs - - - Math\statistics\riskstatistics.cs - - - Math\statistics\sequencestatistics.cs - - - Math\transformedgrid.cs - - - Math\Vector.cs - - - Methods\Finitedifferences\AmericanCondition.cs - - - Methods\Finitedifferences\BoundaryCondition.cs - - - Methods\Finitedifferences\bsmoperator.cs - - - Methods\Finitedifferences\cranknicolson.cs - - - Methods\Finitedifferences\DPlus.cs - - - Methods\Finitedifferences\DMinus.cs - - - Methods\Finitedifferences\ExplicitEuler.cs - - - Methods\Finitedifferences\ImplicitEuler.cs - - - Methods\Finitedifferences\TRBDF2.cs - - - Methods\Finitedifferences\DPlusDMinus.cs - - - Methods\Finitedifferences\dzero.cs - - - Methods\Finitedifferences\ZeroCondition.cs - - - Methods\Finitedifferences\finitedifferencemodel.cs - - - Methods\Finitedifferences\mixedscheme.cs - - - Methods\Finitedifferences\OperatorFactory.cs - - - Methods\Finitedifferences\ParallelEvolver.cs - - - Methods\Finitedifferences\pde.cs - - - Methods\Finitedifferences\pdebsm.cs - - - Methods\Finitedifferences\pdeshortrate.cs - - - Methods\Finitedifferences\ShoutCondition.cs - - - Methods\Finitedifferences\StepCondition.cs - - - Methods\Finitedifferences\TridiagonalOperator.cs - - - Methods\Finitedifferences\Meshers\Concentrating1dMesher.cs - - - Methods\Finitedifferences\Meshers\Fdm1dMesher.cs - - - Methods\Finitedifferences\Meshers\FdmSimpleProcess1dMesher.cs - - - Methods\Finitedifferences\Meshers\FdmBlackScholesMesher.cs - - - Methods\Finitedifferences\Meshers\FdmMesher.cs - - - Methods\Finitedifferences\Meshers\FdmMesherComposite.cs - - - Methods\Finitedifferences\Meshers\Uniform1dMesher.cs - - - Methods\Finitedifferences\Meshers\UniformGridMesher.cs - - - Methods\Finitedifferences\Operators\FdmBlackScholesOp.cs - - - Methods\Finitedifferences\Operators\FdmHullWhiteOp.cs - - - Methods\Finitedifferences\Operators\FdmLinearOp.cs - - - Methods\Finitedifferences\Operators\FdmLinearOpComposite.cs - - - Methods\Finitedifferences\Operators\FdmLinearOpIterator.cs - - - Methods\Finitedifferences\Operators\FdmLinearOpLayout.cs - - - Methods\Finitedifferences\Operators\FirstDerivativeOp.cs - - - Methods\Finitedifferences\Operators\NinePointLinearOp.cs - - - Methods\Finitedifferences\Operators\SecondDerivativeOp.cs - - - Methods\Finitedifferences\Operators\SecondOrderMixedDerivativeOp.cs - - - Methods\Finitedifferences\Operators\TripleBandLinearOp.cs - - - Methods\Finitedifferences\Schemes\BoundaryConditionSchemeHelper.cs - - - Methods\Finitedifferences\Schemes\CraigSneydScheme.cs - - - Methods\Finitedifferences\Schemes\DouglasScheme.cs - - - Methods\Finitedifferences\Schemes\ExplicitEulerScheme.cs - - - Methods\Finitedifferences\Schemes\HundsdorferScheme.cs - - - Methods\Finitedifferences\Schemes\ImplicitEulerScheme.cs - - - Methods\Finitedifferences\Schemes\ModifiedCraigSneydScheme.cs - - - Methods\Finitedifferences\Solvers\Fdm1DimSolver.cs - - - Methods\Finitedifferences\Solvers\FdmBackwardSolver.cs - - - Methods\Finitedifferences\Solvers\FdmBlackScholesSolver.cs - - - Methods\Finitedifferences\Solvers\FdmHullWhiteSolver.cs - - - Methods\Finitedifferences\Solvers\FdmSolverDesc.cs - - - Methods\Finitedifferences\StepConditions\FdmAmericanStepCondition.cs - - - Methods\Finitedifferences\StepConditions\FdmBermudanStepCondition.cs - - - Methods\Finitedifferences\StepConditions\FdmSnapshotCondition.cs - - - Methods\Finitedifferences\StepConditions\FdmStepConditionComposite.cs - - - Methods\Finitedifferences\Utilities\FdmBoundaryConditionSet.cs - - - Methods\Finitedifferences\Utilities\FdmDirichletBoundary.cs - - - Methods\Finitedifferences\Utilities\FdmDividendHandler.cs - - - Methods\Finitedifferences\Utilities\FdmIndicesOnBoundary.cs - - - Methods\Finitedifferences\Utilities\FdmInnerValueCalculator.cs - - - Methods\Finitedifferences\Utilities\FdmAffineModelSwapInnerValue.cs - - - Methods\Finitedifferences\Utilities\FdmAffineModelTermStructure.cs - - - Methods\Finitedifferences\Utilities\FdmMesherIntegral.cs - - - Methods\Finitedifferences\Utilities\ListUtils.cs - - - Methods\lattices\binominaltree.cs - - - Methods\lattices\bsmlattice.cs - - - Methods\lattices\lattice.cs - - - Methods\lattices\lattice1d.cs - - - Methods\lattices\lattice2d.cs - - - Methods\lattices\tree.cs - - - Methods\lattices\trinomialtree.cs - - - Methods\montecarlo\brownianbridge.cs - - - Methods\montecarlo\earlyexercisepathpricer.cs - - - Methods\montecarlo\longstaffschwartzpathpricer.cs - - - Methods\montecarlo\lsmbasissystem.cs - - - Methods\montecarlo\mctraits.cs - - - Methods\montecarlo\montecarlomodel.cs - - - Methods\montecarlo\multipath.cs - - - Methods\montecarlo\multipathgenerator.cs - - - Methods\montecarlo\path.cs - - - Methods\montecarlo\pathgenerator.cs - - - Methods\montecarlo\pathpricer.cs - - - Methods\montecarlo\sample.cs - - - Models\CalibrationHelper.cs - - - Models\Equity\HestonModel.cs - - - Models\Equity\HestonModelHelper.cs - - - Models\Equity\PiecewiseTimeDependentHestonModel.cs - - - Models\MarketModels\BrownianGenerator.cs - - - Models\MarketModels\BrownianGenerators\SobolBrownianGenerator.cs - - - Code - Models\model.cs - - - Models\Parameter.cs - - - Models\Shortrate\calibrationhelpers\caphelper.cs - - - Models\Shortrate\calibrationhelpers\swaptionhelper.cs - - - Models\Shortrate\OneFactorModel.cs - - - Models\Shortrate\Onefactormodels\blackkarasinski.cs - - - Models\Shortrate\Onefactormodels\coxingersollross.cs - - - Models\Shortrate\Onefactormodels\hullwhite.cs - - - Models\Shortrate\Onefactormodels\vasicek.cs - - - Models\Shortrate\twofactormodel.cs - - - Models\Shortrate\Twofactorsmodels\g2.cs - - - - - - Patterns\FastActivator.cs - - - Patterns\LazyObject.cs - - - Patterns\observablevalue.cs - - - Patterns\Observer.cs - - - Patterns\Visitor.cs - - - Patterns\WeakEventSource.cs - - - Instruments\payoff.cs - - - - Pricingengines\Americanpayoffatexpiry.cs - - - Pricingengines\Americanpayoffathit.cs - - - Pricingengines\asian\AnalyticContinuousGeometricAveragePriceAsianEngine.cs - - - Pricingengines\asian\AnalyticDiscreteGeometricAveragePriceAsianEngine.cs - - - Pricingengines\asian\AnalyticDiscreteGeometricAverageStrikeAsianEngine.cs - - - Pricingengines\asian\mcdiscreteasianengine.cs - - - Pricingengines\asian\mc_discr_arith_av_price.cs - - - Pricingengines\asian\mc_discr_arith_av_strike.cs - - - Pricingengines\asian\mc_discr_geom_av_price.cs - - - Pricingengines\barrier\AnalyticBarrierEngine.cs - - - Pricingengines\barrier\AnalyticBinaryBarrierEngine.cs - - - Pricingengines\barrier\AnalyticDoubleBarrierBinaryEngine.cs - - - Pricingengines\barrier\AnalyticDoubleBarrierEngine.cs - - - Pricingengines\barrier\BinomialBarrierEngine.cs - - - Pricingengines\barrier\DiscretizedBarrierOption.cs - - - Pricingengines\barrier\BinomialDoubleBarrierEngine.cs - - - Pricingengines\barrier\DiscretizedDoubleBarrierOption.cs - - - Pricingengines\barrier\FdBlackScholesBarrierEngine.cs - - - Pricingengines\barrier\FdBlackScholesRebateEngine.cs - - - Pricingengines\barrier\VannaVolgaBarrierEngine.cs - - - Pricingengines\barrier\VannaVolgaDoubleBarrierEngine.cs - - - Pricingengines\barrier\WulinYongDoubleBarrierEngine.cs - - - Pricingengines\Basket\KirkEngine.cs - - - Pricingengines\Basket\MCEuropeanBasketEngine.cs - - - Pricingengines\Basket\StulzEngine.cs - - - Pricingengines\BlackCalculator.cs - - - Pricingengines\BlackDeltaCalculator.cs - - - Pricingengines\blackformula.cs - - - Pricingengines\Blackscholescalculator.cs - - - Pricingengines\Bond\BlackCallableBondEngine.cs - - - Pricingengines\Bond\BondFunctions.cs - - - Pricingengines\Bond\Discountingbondengine.cs - - - Pricingengines\Bond\TreeCallableBondEngine.cs - - - Pricingengines\CapFloor\analyticcapfloorengine.cs - - - Pricingengines\CapFloor\BachelierCapFloorEngine.cs - - - Pricingengines\CapFloor\BlackCapFloorEngine.cs - - - Pricingengines\CapFloor\discretizedcapfloor.cs - - - Pricingengines\inflation\InterpolatingCPICapFloorEngine.cs - - - Pricingengines\Cliquet\AnalyticCliquetEngine.cs - - - Pricingengines\Cliquet\AnalyticPerformanceEngine.cs - - - Pricingengines\credit\IntegralCdsEngine.cs - - - Pricingengines\credit\IsdaCdsEngine.cs - - - Pricingengines\credit\MidPointCdsEngine.cs - - - Pricingengines\Forward\ForwardPerformanceVanillaEngine.cs - - - Pricingengines\Forward\ForwardVanillaEngine.cs - - - Pricingengines\genericmodelengine.cs - - - Pricingengines\Greeks.cs - - - Pricingengines\inflation\InflationCapFloorEngines.cs - - - Pricingengines\latticeshortratemodelengine.cs - - - Pricingengines\Loan\DiscountingLoanEngine.cs - - - Pricingengines\Lookback\AnalyticContinuousFixedLookbackEngine.cs - - - Pricingengines\Lookback\AnalyticContinuousFloatingLookbackEngine.cs - - - Pricingengines\Lookback\AnalyticContinuousPartialFixedLookbackEngine.cs - - - Pricingengines\Lookback\AnalyticContinuousPartialFloatingLookbackEngine.cs - - - Pricingengines\mclongstaffschwartzengine.cs - - - Pricingengines\mcsimulation.cs - - - Pricingengines\swaption\blackswaptionengine.cs - - - Pricingengines\swaption\discretizedswaption.cs - - - Pricingengines\swaption\g2swaptionengine.cs - - - Pricingengines\swaption\jamshidianswaptionengine.cs - - - Pricingengines\swaption\treeswaptionengine.cs - - - Pricingengines\Swap\CounterpartyAdjSwapEngine.cs - - - Pricingengines\Swap\DiscountingBasisSwapEngine.cs - - - Pricingengines\Swap\Discountingswapengine.cs - - - Pricingengines\Swap\discretizedswap.cs - - - Pricingengines\Swap\treeswapengine.cs - - - Pricingengines\vanilla\AnalyticBSMHullWhiteEngine.cs - - - Pricingengines\vanilla\AnalyticDigitalAmericanEngine.cs - - - Pricingengines\vanilla\AnalyticDividendEuropeanEngine.cs - - - Pricingengines\vanilla\AnalyticEuropeanEngine.cs - - - Pricingengines\vanilla\AnalyticH1HWEngine.cs - - - Pricingengines\vanilla\AnalyticHestonEngine.cs - - - Pricingengines\vanilla\AnalyticHestonHullWhiteEngine.cs - - - Pricingengines\vanilla\AnalyticPTDHestonEngine.cs - - - Pricingengines\vanilla\baroneadesiwhaleyengine.cs - - - Pricingengines\vanilla\binomialengine.cs - - - Pricingengines\vanilla\bjerksundstenslandengine.cs - - - Pricingengines\vanilla\discretizedvanillaoption.cs - - - Pricingengines\vanilla\FdBlackScholesVanillaEngine.cs - - - Pricingengines\vanilla\FdHullWhiteSwaptionEngine.cs - - - Pricingengines\vanilla\FDAmericanEngine.cs - - - Pricingengines\vanilla\FDBermudanEngine.cs - - - Pricingengines\vanilla\FDConditions.cs - - - Pricingengines\vanilla\FDDividendAmericanEngine.cs - - - Pricingengines\vanilla\FDDividendEngine.cs - - - Pricingengines\vanilla\FDDividendEuropeanEngine.cs - - - Pricingengines\vanilla\FDEuropeanEngine.cs - - - Pricingengines\vanilla\FdHestonVanillaEngine.cs - - - Pricingengines\vanilla\FDMultiPeriodEngine.cs - - - Pricingengines\vanilla\FDShoutEngine.cs - - - Pricingengines\vanilla\FDStepConditionEngine.cs - - - Pricingengines\vanilla\FDVanillaEngine.cs - - - Pricingengines\vanilla\HestonExpansionEngine.cs - - - Pricingengines\vanilla\Integralengine.cs - - - Pricingengines\vanilla\Juquadraticengine.cs - - - Pricingengines\vanilla\mcamericanengine.cs - - - Pricingengines\vanilla\mceuropeanengine.cs - - - Pricingengines\vanilla\MCEuropeanHestonEngine.cs - - - Pricingengines\vanilla\MCHestonHullWhiteEngine.cs - - - Pricingengines\vanilla\mcvanillaengine.cs - - - processes\BlackScholesProcess.cs - - - processes\Defaultable.cs - - - processes\EulerDiscretization.cs - - - processes\ForwardMeasureProcess.cs - - - processes\GeometricBrownianMotionProcess.cs - - - processes\HestonProcess.cs - - - processes\HullWhiteProcess.cs - - - processes\HybridHestonHullWhiteProcess.cs - - - processes\Ornsteinuhlenbeckprocess.cs - - - processes\Squarerootprocess.cs - - - processes\stochasticprocessarray.cs - - - - Quotes\CompositeQuote.cs - - - Quotes\DeltaVolQuote.cs - - - Quotes\DerivedQuote.cs - - - Quotes\LastFixingQuote.cs - - - Quotes\Quote.cs - - - Quotes\SimpleQuote.cs - - - - - Termstructures\Bootstraperror.cs - - - Termstructures\Bootstraphelper.cs - - - Termstructures\Credit\FlatHazardRate.cs - - - Termstructures\Credit\HazardRateStructure.cs - - - Termstructures\Credit\InterpolatedHazardRateCurve.cs - - - Termstructures\Credit\InterpolatedSurvivalProbabilityCurve.cs - - - Termstructures\Credit\ProbabilityTraits.cs - - - Termstructures\Credit\SurvivalProbabilityStructure.cs - - - Termstructures\Curve.cs - - - Termstructures\DefaultProbabilityTermStructure.cs - - - Termstructures\InflationTermStructure.cs - - - Termstructures\Inflation\CPICapFloorTermPriceSurface.cs - - - Termstructures\Inflation\InflationHelpers.cs - - - Termstructures\Inflation\InflationTraits.cs - - - Termstructures\Inflation\InterpolatedYoYInflationCurve.cs - - - Termstructures\Inflation\InterpolatedZeroInflationCurve.cs - - - Termstructures\Inflation\PiecewiseYoYInflationCurve.cs - - - Termstructures\Inflation\PiecewiseZeroInflationCurve.cs - - - Termstructures\Inflation\Seasonality.cs - - - Termstructures\interpolatedcurve.cs - - - Termstructures\Iterativebootstrap.cs - - - Termstructures\localbootstrap.cs - - - Termstructures\TermStructure.cs - - - Termstructures\Volatility\AbcdCalibration.cs - - - Termstructures\Volatility\AbcdFunction.cs - - - Termstructures\Volatility\AtmSmileSection.cs - - - Termstructures\Volatility\Bond\CallableBondConstantVolatility.cs - - - Termstructures\Volatility\Bond\CallableBondVolatilityStructure.cs - - - Termstructures\Volatility\CapFloor\CapFloorTermVolCurve.cs - - - Termstructures\Volatility\CapFloor\CapFloorTermVolSurface.cs - - - Termstructures\Volatility\equityfx\BlackVarianceSurface.cs - - - Termstructures\Volatility\equityfx\HestonBlackVolSurface.cs - - - Termstructures\Volatility\equityfx\ImpliedVolTermStructure.cs - - - Termstructures\Volatility\Inflation\CPIVolatilitySurface.cs - - - Termstructures\Volatility\Inflation\yoyinflationoptionletvolatilitystructure.cs - - - Termstructures\Volatility\InterpolatedSmileSection.cs - - - Termstructures\Volatility\SabrInterpolatedSmileSection.cs - - - Termstructures\Volatility\SviInterpolatedSmileSection.cs - - - Termstructures\Volatility\Optionlet\capletvariancecurve.cs - - - Termstructures\Volatility\Optionlet\OptionletStripper.cs - - - Termstructures\Volatility\Optionlet\OptionletStripper1.cs - - - Termstructures\Volatility\Optionlet\OptionletStripper2.cs - - - Termstructures\Volatility\Optionlet\SpreadedOptionletVolatility.cs - - - Termstructures\Volatility\Optionlet\StrippedOptionletAdapter.cs - - - Termstructures\Volatility\Optionlet\StrippedOptionletBase.cs - - - Termstructures\Volatility\SpreadedSmileSection.cs - - - Termstructures\Volatility\swaption\SpreadedSwaptionVolatility.cs - - - Termstructures\Volatility\swaption\swaptionconstantvol.cs - - - Termstructures\Volatility\swaption\SwaptionVolatilityCube.cs - - - Termstructures\Volatility\swaption\SwaptionVolCube1.cs - - - Termstructures\Volatility\swaption\SwaptionVolCube2.cs - - - Termstructures\Volatility\swaption\swaptionvoldiscrete.cs - - - Termstructures\Volatility\swaption\swaptionvolmatrix.cs - - - Termstructures\voltermstructure.cs - - - Termstructures\Volatility\CapFloor\CapFloorTermVolatilityStructure.cs - - - Termstructures\Volatility\CapFloor\ConstantCapFloorTermVolatility.cs - - - Termstructures\Volatility\equityfx\BlackConstantVol.cs - - - Termstructures\Volatility\equityfx\BlackVarianceCurve.cs - - - Termstructures\Volatility\equityfx\BlackVolTermStructure.cs - - - Termstructures\Volatility\equityfx\LocalConstantVol.cs - - - Termstructures\Volatility\equityfx\LocalVolCurve.cs - - - Termstructures\Volatility\equityfx\LocalVolSurface.cs - - - Termstructures\Volatility\equityfx\LocalVolTermStructure.cs - - - Termstructures\Volatility\equityfx\FixedLocalVolSurface.cs - - - Termstructures\Volatility\equityfx\NoExceptLocalVolSurface.cs - - - Termstructures\Volatility\FlatSmileSection.cs - - - Termstructures\Volatility\Optionlet\ConstantOptionletVolatility.cs - - - Termstructures\Volatility\Optionlet\OptionletVolatilityStructure.cs - - - Termstructures\Volatility\Sabr.cs - - - Termstructures\Volatility\Svi.cs - - - Termstructures\Volatility\SmileSection.cs - - - Termstructures\Volatility\SviSmileSection.cs - - - Termstructures\Volatility\swaption\SwaptionVolatilityStructure.cs - - - Termstructures\YieldTermStructure.cs - - - Termstructures\Yield\BasisSwapHelper.cs - - - Termstructures\Yield\Bondhelpers.cs - - - Termstructures\Yield\Bootstraptraits.cs - - - Termstructures\Yield\DiscountCurve.cs - - - Termstructures\Yield\FittedBondDiscountCurve.cs - - - Termstructures\Yield\Flatforward.cs - - - Termstructures\Yield\ForwardCurve.cs - - - Termstructures\Yield\ForwardSpreadedTermStructure.cs - - - Termstructures\Yield\ForwardStructure.cs - - - Termstructures\Yield\ImpliedTermStructure.cs - - - Termstructures\Yield\InterpolatedPiecewiseZeroSpreadedTermStructure.cs - - - Termstructures\Yield\NonLinearFittingMethods.cs - - - Termstructures\Yield\OISRateHelper.cs - - - Termstructures\Yield\PiecewiseYieldCurve.cs - - - Termstructures\Yield\Ratehelpers.cs - - - Termstructures\Yield\ZeroCurve.cs - - - Termstructures\Yield\ZeroSpreadedTermStructure.cs - - - Termstructures\Yield\Zeroyieldstructure.cs - - - - Time\ASX.cs - - - Time\Calendar.cs - - - Time\Calendars\argentina.cs - - - Time\Calendars\australia.cs - - - Time\Calendars\bespokecalendar.cs - - - Time\Calendars\brazil.cs - - - Time\Calendars\canada.cs - - - Time\Calendars\china.cs - - - Time\Calendars\czechrepublic.cs - - - Time\Calendars\denmark.cs - - - Time\Calendars\finland.cs - - - Time\Calendars\germany.cs - - - Time\Calendars\hongkong.cs - - - Time\Calendars\hungary.cs - - - Time\Calendars\iceland.cs - - - Time\Calendars\india.cs - - - Time\Calendars\indonesia.cs - - - Time\Calendars\Israel.cs - - - Time\Calendars\italy.cs - - - Time\Calendars\japan.cs - - - Time\Calendars\JointCalendar.cs - - - Time\Calendars\mexico.cs - - - Time\Calendars\newzealand.cs - - - Time\Calendars\norway.cs - - - Time\Calendars\nullcalendar.cs - - - Time\Calendars\poland.cs - - - Time\Calendars\Romania.cs - - - Time\Calendars\russia.cs - - - Time\Calendars\saudiarabia.cs - - - Time\Calendars\singapore.cs - - - Time\Calendars\slovakia.cs - - - Time\Calendars\southafrica.cs - - - Time\Calendars\southkorea.cs - - - Time\Calendars\sweden.cs - - - Time\Calendars\switzerland.cs - - - Time\Calendars\taiwan.cs - - - Time\Calendars\TARGET.cs - - - Time\Calendars\turkey.cs - - - Time\Calendars\Ukraine.cs - - - Time\Calendars\UnitedKingdom.cs - - - Time\Calendars\UnitedStates.cs - - - Time\Calendars\WeekendsOnly.cs - - - Time\Date.cs - - - Time\DayCounter.cs - - - Time\DayCounters\Actual360.cs - - - Time\DayCounters\Actual365Fixed.cs - - - Time\DayCounters\Actual365NoLeap.cs - - - Time\DayCounters\ActualActual.cs - - - Time\DayCounters\Business252.cs - - - Time\DayCounters\OneDayCounter.cs - - - Time\DayCounters\SimpleDayCounter.cs - - - Time\DayCounters\Thirty360.cs - - - Time\ECB.cs - - - Time\Imm.cs - - - Time\Period.cs - - - Time\Schedule.cs - - - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - - - - - - - - + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {F6E762BD-DCDF-4CA0-ABAD-CB21C7D03BEC} + Library + Properties + QLNet + QLNet + + + 3.5 + + + v4.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + + true + full + false + bin\Debug\net40\ + TRACE;DEBUG;QL_NEGATIVE_RATES,NET40 + prompt + 4 + false + AllRules.ruleset + false + + + pdbonly + true + bin\Release\net40\ + TRACE;QL_NEGATIVE_RATES,QL_DOTNET_FRAMEWORK + prompt + 4 + AllRules.ruleset + false + + + true + bin\Debug\net45\ + TRACE;DEBUG;QL_NEGATIVE_RATES,QL_DOTNET_FRAMEWORK + full + v4.5 + AnyCPU + prompt + AllRules.ruleset + + + bin\Release\net45\ + TRACE;QL_NEGATIVE_RATES,QL_DOTNET_FRAMEWORK + true + pdbonly + v4.5 + AnyCPU + prompt + AllRules.ruleset + + + + + + + + + + + Cashflows\AverageBMACoupon.cs + + + Cashflows\CappedFlooredCoupon.cs + + + Cashflows\CappedFlooredYoYInflationCoupon.cs + + + Cashflows\CashFlows.cs + + + Cashflows\Cashflowvectors.cs + + + Cashflows\CmsCoupon.cs + + + Cashflows\ConundrumPricer.cs + + + Cashflows\Coupon.cs + + + Cashflows\CouponPricer.cs + + + Cashflows\CPICoupon.cs + + + Cashflows\CPICouponPricer.cs + + + Cashflows\DigitalCmsCoupon.cs + + + Cashflows\DigitalCoupon.cs + + + Cashflows\DigitalIborCoupon.cs + + + Cashflows\Dividend.cs + + + Cashflows\FixedRateCoupon.cs + + + Cashflows\FloatingRateCoupon.cs + + + Cashflows\Iborcoupon.cs + + + Cashflows\IndexedCashFlow.cs + + + Cashflows\InflationCoupon.cs + + + Cashflows\InflationCouponPricer.cs + + + Cashflows\LinearTsrPricer.cs + + + Cashflows\OvernightIndexedCoupon.cs + + + Cashflows\Principal.cs + + + Cashflows\PrincipalLegBase.cs + + + Cashflows\RangeAccrual.cs + + + Cashflows\RateLegBase.cs + + + Cashflows\Replication.cs + + + Cashflows\SimpleCashFlow.cs + + + Cashflows\YoYInflationCoupon.cs + + + Currencies\Africa.cs + + + Currencies\America.cs + + + Currencies\Asia.cs + + + Currencies\Currency.cs + + + Currencies\Europe.cs + + + Currencies\ExchangeRate.cs + + + Currencies\ExchangeRateManager.cs + + + Currencies\Oceania.cs + + + + + + Extensions\DoubleExtension.cs + + + Extensions\ListExtension.cs + + + + + + Indexes\BMAIndex.cs + + + Indexes\IborIndex.cs + + + Indexes\Ibor\Aonia.cs + + + Indexes\Ibor\Audlibor.cs + + + Indexes\Ibor\Bbsw.cs + + + Indexes\Ibor\Bkbm.cs + + + Indexes\Ibor\Cadlibor.cs + + + Indexes\Ibor\Cdor.cs + + + Indexes\Ibor\Chflibor.cs + + + Indexes\Ibor\Dkklibor.cs + + + Indexes\Ibor\Eonia.cs + + + Indexes\Ibor\Euribor.cs + + + Indexes\Ibor\Eurlibor.cs + + + Indexes\Ibor\FedFunds.cs + + + Indexes\Ibor\Gbplibor.cs + + + Indexes\Ibor\Jibar.cs + + + Indexes\Ibor\Jpylibor.cs + + + Indexes\Ibor\Libor.cs + + + Indexes\Ibor\Nzdlibor.cs + + + Indexes\Ibor\Nzocr.cs + + + Indexes\Ibor\Seklibor.cs + + + Indexes\Ibor\Shibor.cs + + + Indexes\Ibor\Sonia.cs + + + Indexes\Ibor\Tibor.cs + + + Indexes\Ibor\Trylibor.cs + + + Indexes\Ibor\Usdlibor.cs + + + Indexes\Ibor\Zibor.cs + + + Indexes\Indexmanager.cs + + + Indexes\InflationIndex.cs + + + Indexes\Inflation\AUCPI.cs + + + Indexes\Inflation\EUHICP.cs + + + Indexes\Inflation\FRHICP.cs + + + Indexes\Inflation\UKRPI.cs + + + Indexes\Inflation\USCPI.cs + + + Indexes\Inflation\ZACPI.cs + + + Indexes\InterestRateIndex.cs + + + Indexes\Region.cs + + + Indexes\Swapindex.cs + + + Indexes\Swap\ChfLiborSwap.cs + + + Indexes\Swap\EuriborSwap.cs + + + Indexes\Swap\EurLiborSwap.cs + + + Indexes\Swap\GbpLiborSwap.cs + + + Indexes\Swap\JpyLiborSwap.cs + + + Indexes\Swap\UsdLiborSwap.cs + + + Instruments\AsianOption.cs + + + Code + Instruments\AssetSwap.cs + + + Instruments\AverageType.cs + + + Instruments\BarrierOption.cs + + + Instruments\BarrierType.cs + + + Instruments\BasisSwap.cs + + + Instruments\BasketOption.cs + + + Instruments\bmaswap.cs + + + Instruments\Bond.cs + + + Instruments\Bonds\AmortizingBond.cs + + + Instruments\Bonds\AmortizingCmsRateBond.cs + + + Instruments\Bonds\AmortizingFixedRateBond.cs + + + Instruments\Bonds\AmortizingFloatingRateBond.cs + + + Instruments\Bonds\BondFactory.cs + + + Instruments\Bonds\BTP.cs + + + Instruments\Bonds\CallableBond.cs + + + Instruments\Bonds\CmsRateBond.cs + + + Instruments\Bonds\ConstantCPR.cs + + + Instruments\Bonds\ConvertibleBond.cs + + + Instruments\Bonds\CPIBond.cs + + + Instruments\Bonds\DiscretizedCallableFixedRateBond.cs + + + Instruments\Bonds\Fixedratebond.cs + + + Instruments\Bonds\FloatingRateBond.cs + + + Instruments\Bonds\IPrepayModel.cs + + + Instruments\Bonds\MBSFixedRateBond.cs + + + Instruments\Bonds\PSACurve.cs + + + Instruments\Bonds\Zerocouponbond.cs + + + Instruments\Callability.cs + + + Instruments\CapFloor.cs + + + Instruments\Claim.cs + + + Instruments\CliquetOption.cs + + + Instruments\CompositeInstrument.cs + + + Instruments\CPICapFloor.cs + + + Instruments\CPISwap.cs + + + Instruments\CreditDefaultSwap.cs + + + Instruments\DividendBarrierOption.cs + + + Instruments\DividendSchedule.cs + + + Instruments\DividendVanillaOption.cs + + + Instruments\DoubleBarrierOption.cs + + + Instruments\EuropeanOption.cs + + + Instruments\fixedratebondforward.cs + + + Instruments\forward.cs + + + Instruments\forwardrateagreement.cs + + + Instruments\ForwardVanillaOption.cs + + + Instruments\Futures.cs + + + Instruments\ImpliedVolatility.cs + + + Instruments\InflationCapFloor.cs + + + Instruments\Instrument.cs + + + Instruments\Loan.cs + + + Instruments\LookbackOption.cs + + + Instruments\MakeBasisSwap.cs + + + Instruments\MakeCapFloor.cs + + + Instruments\MakeCms.cs + + + Instruments\MakeLoans.cs + + + Instruments\MakeOIS.cs + + + Instruments\MakeCDS.cs + + + Instruments\Makeswaption.cs + + + Instruments\Makevanillaswap.cs + + + Instruments\MultiAssetOption.cs + + + Instruments\OneAssetOption.cs + + + Instruments\OvernightIndexedSwap.cs + + + + Instruments\Stock.cs + + + Instruments\Swap.cs + + + Instruments\Swaption.cs + + + Instruments\VanillaOption.cs + + + Instruments\VanillaSwap.cs + + + Instruments\YearOnYearInflationSwap.cs + + + Instruments\ZeroCouponInflationSwap.cs + + + + legacy\libormarketmodels\lfmcovarparam.cs + + + legacy\libormarketmodels\LfmCovarianceProxy.cs + + + legacy\libormarketmodels\lfmhullwhiteparam.cs + + + legacy\libormarketmodels\lfmprocess.cs + + + legacy\libormarketmodels\lfmswaptionengine.cs + + + legacy\libormarketmodels\liborforwardmodel.cs + + + legacy\libormarketmodels\lmconstwrappercorrmodel.cs + + + legacy\libormarketmodels\lmconstwrappervolmodel.cs + + + legacy\libormarketmodels\lmcorrmodel.cs + + + legacy\libormarketmodels\lmexpcorrmodel.cs + + + legacy\libormarketmodels\lmextlinexpvolmodel.cs + + + legacy\libormarketmodels\lmfixedvolmodel.cs + + + legacy\libormarketmodels\lmlinexpcorrmodel.cs + + + legacy\libormarketmodels\lmlinexpvolmodel.cs + + + legacy\libormarketmodels\lmvolmodel.cs + + + Math\AbcdMathFunction.cs + + + Math\BernsteinPolynomial.cs + + + Math\beta.cs + + + Math\BSpline.cs + + + Math\Comparison.cs + + + Math\NumericalDifferentiation.cs + + + Math\integrals\GaussLobattoIntegral.cs + + + Math\integrals\DiscreteIntegrals.cs + + + Math\Interpolations\Abcdinterpolation.cs + + + Math\Interpolations\BackwardflatLinearInterpolation.cs + + + Math\Interpolations\FlatExtrapolator2D.cs + + + Math\Interpolations\MixedInterpolation.cs + + + Math\Interpolations\VannaVolgaInterpolation.cs + + + Math\Interpolations\SviInterpolation.cs + + + Math\Optimization\BFGS.cs + + + Math\Optimization\CostFunction.cs + + + Math\Optimization\DifferentialEvolution.cs + + + Math\Distributions\binomialdistribution.cs + + + Math\Distributions\BivariateNormalDistribution.cs + + + Math\Distributions\chisquaredistribution.cs + + + Math\Distributions\GammaDistribution.cs + + + Math\Distributions\NormalDistribution.cs + + + Math\Distributions\poissondistribution.cs + + + Math\factorial.cs + + + Math\integrals\gaussianorthogonalpolynomial.cs + + + Math\integrals\GaussianQuadratures.cs + + + Math\integrals\Integral.cs + + + Math\integrals\Kronrodintegral.cs + + + Math\integrals\Segmentintegral.cs + + + Math\integrals\simpsonintegral.cs + + + Math\integrals\trapezoidintegral.cs + + + Math\Interpolations\backwardflatinterpolation.cs + + + Math\Interpolations\BicubicSplineInterpolation.cs + + + Math\Interpolations\bilinearinterpolation.cs + + + Math\Interpolations\convexmonotoneinterpolation.cs + + + Math\Interpolations\CubicInterpolation.cs + + + Math\Interpolations\Extrapolator.cs + + + Math\Interpolation.cs + + + Math\Interpolations\forwardflatinterpolation.cs + + + Math\Interpolations\interpolation2d.cs + + + Math\Interpolations\KernelInterpolation.cs + + + Math\Interpolations\KernelInterpolation2D.cs + + + Math\Interpolations\Linearinterpolation.cs + + + Math\Interpolations\Loginterpolation.cs + + + Math\Interpolations\multicubicspline.cs + + + Math\Interpolations\sabrinterpolation.cs + + + Math\Interpolations\XABRInterpolation.cs + + + Math\KernelFunctions.cs + + + Math\matrixutilities\TqrEigenDecomposition.cs + + + Math\matrixutilities\BiCGStab.cs + + + Math\matrixutilities\GMRES.cs + + + Math\ODE\AdaptiveRungeKutta.cs + + + Math\matrixutilities\SparseMatrix.cs + + + Math\linearleastsquaresregression.cs + + + Math\Matrix.cs + + + Math\matrixutilities\choleskydecomposition.cs + + + Math\matrixutilities\pseudosqrt.cs + + + Math\matrixutilities\qrdecomposition.cs + + + Math\matrixutilities\svd.cs + + + Math\matrixutilities\symmetricschurdecomposition.cs + + + Math\ModifiedBessel.cs + + + Math\Optimization\ArmijoLineSearch.cs + + + Math\Optimization\ConjugateGradient.cs + + + Math\Optimization\Constraint.cs + + + Math\Optimization\EndCriteria.cs + + + Math\Optimization\GoldsteinLineSearch.cs + + + Math\Optimization\LeastSquareProblem.cs + + + Math\Optimization\levenbergmarquardt.cs + + + Math\Optimization\LineSearch.cs + + + Math\Optimization\LineSearchBasedMethod.cs + + + Math\Optimization\lmdif.cs + + + Math\Optimization\method.cs + + + Math\Optimization\problem.cs + + + Math\Optimization\ProjectedConstraint.cs + + + Math\Optimization\ProjectedCostFunction.cs + + + Math\Optimization\Projection.cs + + + Math\Optimization\Simplex.cs + + + Math\Optimization\SteepestDescent.cs + + + Math\PascalTriangle.cs + + + Math\PolynomialFunction.cs + + + Math\PrimeNumbers.cs + + + Math\randomnumbers\Haltonrsg.cs + + + Math\randomnumbers\inversecumulativerng.cs + + + Math\randomnumbers\inversecumulativersg.cs + + + Math\randomnumbers\mt19937uniformrng.cs + + + Math\randomnumbers\primitivepolynomials.cs + + + Math\randomnumbers\randomsequencegenerator.cs + + + Math\randomnumbers\rngtraits.cs + + + Math\randomnumbers\seedgenerator.cs + + + Math\randomnumbers\SobolBrownianBridgeRsg.cs + + + Math\randomnumbers\sobolrsg.cs + + + Math\randomnumbers\sobolrsg2.cs + + + Math\RichardsonExtrapolation.cs + + + Math\SampledCurve.cs + + + Math\Solver1d.cs + + + Math\Rounding.cs + + + Code + Math\Solvers1d\Bisection.cs + + + Code + Math\Solvers1d\Brent.cs + + + Code + Math\Solvers1d\FalsePosition.cs + + + Math\Solvers1d\FiniteDifferenceNewtonSafe.cs + + + Math\Solvers1d\Newton.cs + + + Math\Solvers1d\Newtonsafe.cs + + + Code + Math\Solvers1d\Ridder.cs + + + Math\Solvers1d\Secant.cs + + + Math\statistics\convergencestatistics.cs + + + Math\statistics\DiscrepancyStatistics.cs + + + Math\statistics\gaussianstatistics.cs + + + Math\statistics\generalstatistics.cs + + + Math\statistics\incrementalstatistics.cs + + + Math\statistics\riskstatistics.cs + + + Math\statistics\sequencestatistics.cs + + + Math\transformedgrid.cs + + + Math\Vector.cs + + + Methods\Finitedifferences\AmericanCondition.cs + + + Methods\Finitedifferences\BoundaryCondition.cs + + + Methods\Finitedifferences\bsmoperator.cs + + + Methods\Finitedifferences\cranknicolson.cs + + + Methods\Finitedifferences\DPlus.cs + + + Methods\Finitedifferences\DMinus.cs + + + Methods\Finitedifferences\ExplicitEuler.cs + + + Methods\Finitedifferences\ImplicitEuler.cs + + + Methods\Finitedifferences\TRBDF2.cs + + + Methods\Finitedifferences\DPlusDMinus.cs + + + Methods\Finitedifferences\dzero.cs + + + Methods\Finitedifferences\ZeroCondition.cs + + + Methods\Finitedifferences\finitedifferencemodel.cs + + + Methods\Finitedifferences\mixedscheme.cs + + + Methods\Finitedifferences\OperatorFactory.cs + + + Methods\Finitedifferences\ParallelEvolver.cs + + + Methods\Finitedifferences\pde.cs + + + Methods\Finitedifferences\pdebsm.cs + + + Methods\Finitedifferences\pdeshortrate.cs + + + Methods\Finitedifferences\ShoutCondition.cs + + + Methods\Finitedifferences\StepCondition.cs + + + Methods\Finitedifferences\TridiagonalOperator.cs + + + Methods\Finitedifferences\Meshers\Concentrating1dMesher.cs + + + Methods\Finitedifferences\Meshers\Fdm1dMesher.cs + + + Methods\Finitedifferences\Meshers\FdmSimpleProcess1dMesher.cs + + + Methods\Finitedifferences\Meshers\FdmBlackScholesMesher.cs + + + Methods\Finitedifferences\Meshers\FdmMesher.cs + + + Methods\Finitedifferences\Meshers\FdmMesherComposite.cs + + + Methods\Finitedifferences\Meshers\Uniform1dMesher.cs + + + Methods\Finitedifferences\Meshers\UniformGridMesher.cs + + + Methods\Finitedifferences\Operators\FdmBlackScholesOp.cs + + + Methods\Finitedifferences\Operators\FdmHullWhiteOp.cs + + + Methods\Finitedifferences\Operators\FdmLinearOp.cs + + + Methods\Finitedifferences\Operators\FdmLinearOpComposite.cs + + + Methods\Finitedifferences\Operators\FdmLinearOpIterator.cs + + + Methods\Finitedifferences\Operators\FdmLinearOpLayout.cs + + + Methods\Finitedifferences\Operators\FirstDerivativeOp.cs + + + Methods\Finitedifferences\Operators\NinePointLinearOp.cs + + + Methods\Finitedifferences\Operators\SecondDerivativeOp.cs + + + Methods\Finitedifferences\Operators\SecondOrderMixedDerivativeOp.cs + + + Methods\Finitedifferences\Operators\TripleBandLinearOp.cs + + + Methods\Finitedifferences\Schemes\BoundaryConditionSchemeHelper.cs + + + Methods\Finitedifferences\Schemes\CraigSneydScheme.cs + + + Methods\Finitedifferences\Schemes\DouglasScheme.cs + + + Methods\Finitedifferences\Schemes\ExplicitEulerScheme.cs + + + Methods\Finitedifferences\Schemes\HundsdorferScheme.cs + + + Methods\Finitedifferences\Schemes\ImplicitEulerScheme.cs + + + Methods\Finitedifferences\Schemes\ModifiedCraigSneydScheme.cs + + + Methods\Finitedifferences\Solvers\Fdm1DimSolver.cs + + + Methods\Finitedifferences\Solvers\FdmBackwardSolver.cs + + + Methods\Finitedifferences\Solvers\FdmBlackScholesSolver.cs + + + Methods\Finitedifferences\Solvers\FdmHullWhiteSolver.cs + + + Methods\Finitedifferences\Solvers\FdmSolverDesc.cs + + + Methods\Finitedifferences\StepConditions\FdmAmericanStepCondition.cs + + + Methods\Finitedifferences\StepConditions\FdmBermudanStepCondition.cs + + + Methods\Finitedifferences\StepConditions\FdmSnapshotCondition.cs + + + Methods\Finitedifferences\StepConditions\FdmStepConditionComposite.cs + + + Methods\Finitedifferences\Utilities\FdmBoundaryConditionSet.cs + + + Methods\Finitedifferences\Utilities\FdmDirichletBoundary.cs + + + Methods\Finitedifferences\Utilities\FdmDividendHandler.cs + + + Methods\Finitedifferences\Utilities\FdmIndicesOnBoundary.cs + + + Methods\Finitedifferences\Utilities\FdmInnerValueCalculator.cs + + + Methods\Finitedifferences\Utilities\FdmAffineModelSwapInnerValue.cs + + + Methods\Finitedifferences\Utilities\FdmAffineModelTermStructure.cs + + + Methods\Finitedifferences\Utilities\FdmMesherIntegral.cs + + + Methods\Finitedifferences\Utilities\ListUtils.cs + + + Methods\lattices\binominaltree.cs + + + Methods\lattices\bsmlattice.cs + + + Methods\lattices\lattice.cs + + + Methods\lattices\lattice1d.cs + + + Methods\lattices\lattice2d.cs + + + Methods\lattices\tree.cs + + + Methods\lattices\trinomialtree.cs + + + Methods\montecarlo\brownianbridge.cs + + + Methods\montecarlo\earlyexercisepathpricer.cs + + + Methods\montecarlo\longstaffschwartzpathpricer.cs + + + Methods\montecarlo\lsmbasissystem.cs + + + Methods\montecarlo\mctraits.cs + + + Methods\montecarlo\montecarlomodel.cs + + + Methods\montecarlo\multipath.cs + + + Methods\montecarlo\multipathgenerator.cs + + + Methods\montecarlo\path.cs + + + Methods\montecarlo\pathgenerator.cs + + + Methods\montecarlo\pathpricer.cs + + + Methods\montecarlo\sample.cs + + + Models\CalibrationHelper.cs + + + Models\Equity\HestonModel.cs + + + Models\Equity\HestonModelHelper.cs + + + Models\Equity\PiecewiseTimeDependentHestonModel.cs + + + Models\MarketModels\BrownianGenerator.cs + + + Models\MarketModels\BrownianGenerators\SobolBrownianGenerator.cs + + + Code + Models\model.cs + + + Models\Parameter.cs + + + Models\Shortrate\calibrationhelpers\caphelper.cs + + + Models\Shortrate\calibrationhelpers\swaptionhelper.cs + + + Models\Shortrate\OneFactorModel.cs + + + Models\Shortrate\Onefactormodels\blackkarasinski.cs + + + Models\Shortrate\Onefactormodels\coxingersollross.cs + + + Models\Shortrate\Onefactormodels\hullwhite.cs + + + Models\Shortrate\Onefactormodels\vasicek.cs + + + Models\Shortrate\twofactormodel.cs + + + Models\Shortrate\Twofactorsmodels\g2.cs + + + + + + Patterns\FastActivator.cs + + + Patterns\LazyObject.cs + + + Patterns\observablevalue.cs + + + Patterns\Observer.cs + + + Patterns\Visitor.cs + + + Patterns\WeakEventSource.cs + + + Instruments\payoff.cs + + + + Pricingengines\Americanpayoffatexpiry.cs + + + Pricingengines\Americanpayoffathit.cs + + + Pricingengines\asian\AnalyticContinuousGeometricAveragePriceAsianEngine.cs + + + Pricingengines\asian\AnalyticDiscreteGeometricAveragePriceAsianEngine.cs + + + Pricingengines\asian\AnalyticDiscreteGeometricAverageStrikeAsianEngine.cs + + + Pricingengines\asian\mcdiscreteasianengine.cs + + + Pricingengines\asian\mc_discr_arith_av_price.cs + + + Pricingengines\asian\mc_discr_arith_av_strike.cs + + + Pricingengines\asian\mc_discr_geom_av_price.cs + + + Pricingengines\barrier\AnalyticBarrierEngine.cs + + + Pricingengines\barrier\AnalyticBinaryBarrierEngine.cs + + + Pricingengines\barrier\AnalyticDoubleBarrierBinaryEngine.cs + + + Pricingengines\barrier\AnalyticDoubleBarrierEngine.cs + + + Pricingengines\barrier\BinomialBarrierEngine.cs + + + Pricingengines\barrier\DiscretizedBarrierOption.cs + + + Pricingengines\barrier\BinomialDoubleBarrierEngine.cs + + + Pricingengines\barrier\DiscretizedDoubleBarrierOption.cs + + + Pricingengines\barrier\FdBlackScholesBarrierEngine.cs + + + Pricingengines\barrier\FdBlackScholesRebateEngine.cs + + + Pricingengines\barrier\VannaVolgaBarrierEngine.cs + + + Pricingengines\barrier\VannaVolgaDoubleBarrierEngine.cs + + + Pricingengines\barrier\WulinYongDoubleBarrierEngine.cs + + + Pricingengines\Basket\KirkEngine.cs + + + Pricingengines\Basket\MCEuropeanBasketEngine.cs + + + Pricingengines\Basket\StulzEngine.cs + + + Pricingengines\BlackCalculator.cs + + + Pricingengines\BlackDeltaCalculator.cs + + + Pricingengines\blackformula.cs + + + Pricingengines\Blackscholescalculator.cs + + + Pricingengines\Bond\BlackCallableBondEngine.cs + + + Pricingengines\Bond\BondFunctions.cs + + + Pricingengines\Bond\Discountingbondengine.cs + + + Pricingengines\Bond\TreeCallableBondEngine.cs + + + Pricingengines\CapFloor\analyticcapfloorengine.cs + + + Pricingengines\CapFloor\BachelierCapFloorEngine.cs + + + Pricingengines\CapFloor\BlackCapFloorEngine.cs + + + Pricingengines\CapFloor\discretizedcapfloor.cs + + + Pricingengines\inflation\InterpolatingCPICapFloorEngine.cs + + + Pricingengines\Cliquet\AnalyticCliquetEngine.cs + + + Pricingengines\Cliquet\AnalyticPerformanceEngine.cs + + + Pricingengines\credit\IntegralCdsEngine.cs + + + Pricingengines\credit\IsdaCdsEngine.cs + + + Pricingengines\credit\MidPointCdsEngine.cs + + + Pricingengines\Forward\ForwardPerformanceVanillaEngine.cs + + + Pricingengines\Forward\ForwardVanillaEngine.cs + + + Pricingengines\genericmodelengine.cs + + + Pricingengines\Greeks.cs + + + Pricingengines\inflation\InflationCapFloorEngines.cs + + + Pricingengines\latticeshortratemodelengine.cs + + + Pricingengines\Loan\DiscountingLoanEngine.cs + + + Pricingengines\Lookback\AnalyticContinuousFixedLookbackEngine.cs + + + Pricingengines\Lookback\AnalyticContinuousFloatingLookbackEngine.cs + + + Pricingengines\Lookback\AnalyticContinuousPartialFixedLookbackEngine.cs + + + Pricingengines\Lookback\AnalyticContinuousPartialFloatingLookbackEngine.cs + + + Pricingengines\mclongstaffschwartzengine.cs + + + Pricingengines\mcsimulation.cs + + + Pricingengines\swaption\blackswaptionengine.cs + + + Pricingengines\swaption\discretizedswaption.cs + + + Pricingengines\swaption\g2swaptionengine.cs + + + Pricingengines\swaption\jamshidianswaptionengine.cs + + + Pricingengines\swaption\treeswaptionengine.cs + + + Pricingengines\Swap\CounterpartyAdjSwapEngine.cs + + + Pricingengines\Swap\DiscountingBasisSwapEngine.cs + + + Pricingengines\Swap\Discountingswapengine.cs + + + Pricingengines\Swap\discretizedswap.cs + + + Pricingengines\Swap\treeswapengine.cs + + + Pricingengines\vanilla\AnalyticBSMHullWhiteEngine.cs + + + Pricingengines\vanilla\AnalyticDigitalAmericanEngine.cs + + + Pricingengines\vanilla\AnalyticDividendEuropeanEngine.cs + + + Pricingengines\vanilla\AnalyticEuropeanEngine.cs + + + Pricingengines\vanilla\AnalyticH1HWEngine.cs + + + Pricingengines\vanilla\AnalyticHestonEngine.cs + + + Pricingengines\vanilla\AnalyticHestonHullWhiteEngine.cs + + + Pricingengines\vanilla\AnalyticPTDHestonEngine.cs + + + Pricingengines\vanilla\baroneadesiwhaleyengine.cs + + + Pricingengines\vanilla\binomialengine.cs + + + Pricingengines\vanilla\bjerksundstenslandengine.cs + + + Pricingengines\vanilla\discretizedvanillaoption.cs + + + Pricingengines\vanilla\FdBlackScholesVanillaEngine.cs + + + Pricingengines\vanilla\FdHullWhiteSwaptionEngine.cs + + + Pricingengines\vanilla\FDAmericanEngine.cs + + + Pricingengines\vanilla\FDBermudanEngine.cs + + + Pricingengines\vanilla\FDConditions.cs + + + Pricingengines\vanilla\FDDividendAmericanEngine.cs + + + Pricingengines\vanilla\FDDividendEngine.cs + + + Pricingengines\vanilla\FDDividendEuropeanEngine.cs + + + Pricingengines\vanilla\FDEuropeanEngine.cs + + + Pricingengines\vanilla\FdHestonVanillaEngine.cs + + + Pricingengines\vanilla\FDMultiPeriodEngine.cs + + + Pricingengines\vanilla\FDShoutEngine.cs + + + Pricingengines\vanilla\FDStepConditionEngine.cs + + + Pricingengines\vanilla\FDVanillaEngine.cs + + + Pricingengines\vanilla\HestonExpansionEngine.cs + + + Pricingengines\vanilla\Integralengine.cs + + + Pricingengines\vanilla\Juquadraticengine.cs + + + Pricingengines\vanilla\mcamericanengine.cs + + + Pricingengines\vanilla\mceuropeanengine.cs + + + Pricingengines\vanilla\MCEuropeanHestonEngine.cs + + + Pricingengines\vanilla\MCHestonHullWhiteEngine.cs + + + Pricingengines\vanilla\mcvanillaengine.cs + + + processes\BlackScholesProcess.cs + + + processes\Defaultable.cs + + + processes\EulerDiscretization.cs + + + processes\ForwardMeasureProcess.cs + + + processes\GeometricBrownianMotionProcess.cs + + + processes\HestonProcess.cs + + + processes\HullWhiteProcess.cs + + + processes\HybridHestonHullWhiteProcess.cs + + + processes\Ornsteinuhlenbeckprocess.cs + + + processes\Squarerootprocess.cs + + + processes\stochasticprocessarray.cs + + + Termstructures\Yield\CompositeZeroYieldStructure.cs + + + + Quotes\CompositeQuote.cs + + + Quotes\DeltaVolQuote.cs + + + Quotes\DerivedQuote.cs + + + Quotes\LastFixingQuote.cs + + + Quotes\Quote.cs + + + Quotes\SimpleQuote.cs + + + + + Termstructures\Bootstraperror.cs + + + Termstructures\Bootstraphelper.cs + + + Termstructures\Credit\FlatHazardRate.cs + + + Termstructures\Credit\HazardRateStructure.cs + + + Termstructures\Credit\InterpolatedHazardRateCurve.cs + + + Termstructures\Credit\InterpolatedSurvivalProbabilityCurve.cs + + + Termstructures\Credit\ProbabilityTraits.cs + + + Termstructures\Credit\SurvivalProbabilityStructure.cs + + + Termstructures\Curve.cs + + + Termstructures\DefaultProbabilityTermStructure.cs + + + Termstructures\InflationTermStructure.cs + + + Termstructures\Inflation\CPICapFloorTermPriceSurface.cs + + + Termstructures\Inflation\InflationHelpers.cs + + + Termstructures\Inflation\InflationTraits.cs + + + Termstructures\Inflation\InterpolatedYoYInflationCurve.cs + + + Termstructures\Inflation\InterpolatedZeroInflationCurve.cs + + + Termstructures\Inflation\PiecewiseYoYInflationCurve.cs + + + Termstructures\Inflation\PiecewiseZeroInflationCurve.cs + + + Termstructures\Inflation\Seasonality.cs + + + Termstructures\interpolatedcurve.cs + + + Termstructures\Iterativebootstrap.cs + + + Termstructures\localbootstrap.cs + + + Termstructures\TermStructure.cs + + + Termstructures\Volatility\AbcdCalibration.cs + + + Termstructures\Volatility\AbcdFunction.cs + + + Termstructures\Volatility\AtmSmileSection.cs + + + Termstructures\Volatility\Bond\CallableBondConstantVolatility.cs + + + Termstructures\Volatility\Bond\CallableBondVolatilityStructure.cs + + + Termstructures\Volatility\CapFloor\CapFloorTermVolCurve.cs + + + Termstructures\Volatility\CapFloor\CapFloorTermVolSurface.cs + + + Termstructures\Volatility\equityfx\BlackVarianceSurface.cs + + + Termstructures\Volatility\equityfx\HestonBlackVolSurface.cs + + + Termstructures\Volatility\equityfx\ImpliedVolTermStructure.cs + + + Termstructures\Volatility\Inflation\CPIVolatilitySurface.cs + + + Termstructures\Volatility\Inflation\yoyinflationoptionletvolatilitystructure.cs + + + Termstructures\Volatility\InterpolatedSmileSection.cs + + + Termstructures\Volatility\SabrInterpolatedSmileSection.cs + + + Termstructures\Volatility\SviInterpolatedSmileSection.cs + + + Termstructures\Volatility\Optionlet\capletvariancecurve.cs + + + Termstructures\Volatility\Optionlet\OptionletStripper.cs + + + Termstructures\Volatility\Optionlet\OptionletStripper1.cs + + + Termstructures\Volatility\Optionlet\OptionletStripper2.cs + + + Termstructures\Volatility\Optionlet\SpreadedOptionletVolatility.cs + + + Termstructures\Volatility\Optionlet\StrippedOptionletAdapter.cs + + + Termstructures\Volatility\Optionlet\StrippedOptionletBase.cs + + + Termstructures\Volatility\SpreadedSmileSection.cs + + + Termstructures\Volatility\swaption\SpreadedSwaptionVolatility.cs + + + Termstructures\Volatility\swaption\swaptionconstantvol.cs + + + Termstructures\Volatility\swaption\SwaptionVolatilityCube.cs + + + Termstructures\Volatility\swaption\SwaptionVolCube1.cs + + + Termstructures\Volatility\swaption\SwaptionVolCube2.cs + + + Termstructures\Volatility\swaption\swaptionvoldiscrete.cs + + + Termstructures\Volatility\swaption\swaptionvolmatrix.cs + + + Termstructures\voltermstructure.cs + + + Termstructures\Volatility\CapFloor\CapFloorTermVolatilityStructure.cs + + + Termstructures\Volatility\CapFloor\ConstantCapFloorTermVolatility.cs + + + Termstructures\Volatility\equityfx\BlackConstantVol.cs + + + Termstructures\Volatility\equityfx\BlackVarianceCurve.cs + + + Termstructures\Volatility\equityfx\BlackVolTermStructure.cs + + + Termstructures\Volatility\equityfx\LocalConstantVol.cs + + + Termstructures\Volatility\equityfx\LocalVolCurve.cs + + + Termstructures\Volatility\equityfx\LocalVolSurface.cs + + + Termstructures\Volatility\equityfx\LocalVolTermStructure.cs + + + Termstructures\Volatility\equityfx\FixedLocalVolSurface.cs + + + Termstructures\Volatility\equityfx\NoExceptLocalVolSurface.cs + + + Termstructures\Volatility\FlatSmileSection.cs + + + Termstructures\Volatility\Optionlet\ConstantOptionletVolatility.cs + + + Termstructures\Volatility\Optionlet\OptionletVolatilityStructure.cs + + + Termstructures\Volatility\Sabr.cs + + + Termstructures\Volatility\Svi.cs + + + Termstructures\Volatility\SmileSection.cs + + + Termstructures\Volatility\SviSmileSection.cs + + + Termstructures\Volatility\swaption\SwaptionVolatilityStructure.cs + + + Termstructures\YieldTermStructure.cs + + + Termstructures\Yield\BasisSwapHelper.cs + + + Termstructures\Yield\Bondhelpers.cs + + + Termstructures\Yield\Bootstraptraits.cs + + + Termstructures\Yield\DiscountCurve.cs + + + Termstructures\Yield\FittedBondDiscountCurve.cs + + + Termstructures\Yield\Flatforward.cs + + + Termstructures\Yield\ForwardCurve.cs + + + Termstructures\Yield\ForwardSpreadedTermStructure.cs + + + Termstructures\Yield\ForwardStructure.cs + + + Termstructures\Yield\ImpliedTermStructure.cs + + + Termstructures\Yield\InterpolatedPiecewiseZeroSpreadedTermStructure.cs + + + Termstructures\Yield\NonLinearFittingMethods.cs + + + Termstructures\Yield\OISRateHelper.cs + + + Termstructures\Yield\PiecewiseYieldCurve.cs + + + Termstructures\Yield\Ratehelpers.cs + + + Termstructures\Yield\ZeroCurve.cs + + + Termstructures\Yield\ZeroSpreadedTermStructure.cs + + + Termstructures\Yield\Zeroyieldstructure.cs + + + + Time\ASX.cs + + + Time\Calendar.cs + + + Time\Calendars\argentina.cs + + + Time\Calendars\australia.cs + + + Time\Calendars\bespokecalendar.cs + + + Time\Calendars\botswana.cs + + + Time\Calendars\brazil.cs + + + Time\Calendars\canada.cs + + + Time\Calendars\china.cs + + + Time\Calendars\czechrepublic.cs + + + Time\Calendars\denmark.cs + + + Time\Calendars\finland.cs + + + Time\Calendars\germany.cs + + + Time\Calendars\hongkong.cs + + + Time\Calendars\hungary.cs + + + Time\Calendars\iceland.cs + + + Time\Calendars\india.cs + + + Time\Calendars\indonesia.cs + + + Time\Calendars\Israel.cs + + + Time\Calendars\italy.cs + + + Time\Calendars\japan.cs + + + Time\Calendars\JointCalendar.cs + + + Time\Calendars\mexico.cs + + + Time\Calendars\newzealand.cs + + + Time\Calendars\norway.cs + + + Time\Calendars\nullcalendar.cs + + + Time\Calendars\poland.cs + + + Time\Calendars\Romania.cs + + + Time\Calendars\russia.cs + + + Time\Calendars\saudiarabia.cs + + + Time\Calendars\singapore.cs + + + Time\Calendars\slovakia.cs + + + Time\Calendars\southafrica.cs + + + Time\Calendars\southkorea.cs + + + Time\Calendars\sweden.cs + + + Time\Calendars\switzerland.cs + + + Time\Calendars\taiwan.cs + + + Time\Calendars\TARGET.cs + + + Time\Calendars\turkey.cs + + + Time\Calendars\Ukraine.cs + + + Time\Calendars\UnitedKingdom.cs + + + Time\Calendars\UnitedStates.cs + + + Time\Calendars\WeekendsOnly.cs + + + Time\Date.cs + + + Time\DayCounter.cs + + + Time\DayCounters\Actual360.cs + + + Time\DayCounters\Actual365Fixed.cs + + + Time\DayCounters\Actual365NoLeap.cs + + + Time\DayCounters\ActualActual.cs + + + Time\DayCounters\Business252.cs + + + Time\DayCounters\OneDayCounter.cs + + + Time\DayCounters\SimpleDayCounter.cs + + + Time\DayCounters\Thirty360.cs + + + Time\ECB.cs + + + Time\Imm.cs + + + Time\Period.cs + + + Time\Schedule.cs + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + + + + \ No newline at end of file diff --git a/src/QLNet/CashflowBase.cs b/src/QLNet/CashflowBase.cs index 15ccc88d1..79d9c1f55 100644 --- a/src/QLNet/CashflowBase.cs +++ b/src/QLNet/CashflowBase.cs @@ -1,25 +1,25 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet +namespace QLNet { //! Base class for cash flows. This class is purely virtual and acts as a base class for the actual cash flow implementations. public abstract class CashFlow : Event, IComparable @@ -28,26 +28,26 @@ public abstract class CashFlow : Event, IComparable public override bool hasOccurred(Date refDate = null, bool? includeRefDate = null) { - + // easy and quick handling of most cases - if (refDate != null) + if (refDate != null) { Date cf = date(); if (refDate < cf) return false; if (cf < refDate) return true; - } + } - if (refDate == null || refDate == Settings.evaluationDate()) - { + if (refDate == null || refDate == Settings.evaluationDate()) + { // today's date; we override the bool with the one // specified in the settings (if any) - bool? includeToday = Settings.includeTodaysCashFlows; + bool? includeToday = Settings.includeTodaysCashFlows; if (includeToday.HasValue) - includeRefDate = includeToday; - } - return base.hasOccurred(refDate, includeRefDate); + includeRefDate = includeToday; + } + return base.hasOccurred(refDate, includeRefDate); } @@ -58,22 +58,22 @@ public override bool hasOccurred(Date refDate = null, bool? includeRefDate = nul //! returns the amount of the cash flow //! The amount is not discounted, i.e., it is the actual amount paid at the cash flow date. public abstract double amount(); - //! returns the date that the cash flow trades exCoupon - public virtual Date exCouponDate() {return null;} + //! returns the date that the cash flow trades exCoupon + public virtual Date exCouponDate() {return null;} //! returns true if the cashflow is trading ex-coupon on the refDate - public bool tradingExCoupon(Date refDate = null) - { - Date ecd = exCouponDate(); - if (ecd == null) - return false; + public bool tradingExCoupon(Date refDate = null) + { + Date ecd = exCouponDate(); + if (ecd == null) + return false; - Date ref_ = refDate ?? Settings.evaluationDate(); + Date ref_ = refDate ?? Settings.evaluationDate(); + + return ecd <= ref_; + } - return ecd <= ref_; - } - #endregion - + public int CompareTo(CashFlow cf) { return date().CompareTo(cf.date()); } public override bool Equals(Object cf) diff --git a/src/QLNet/Cashflows/averagebmacoupon.cs b/src/QLNet/Cashflows/AverageBMACoupon.cs similarity index 62% rename from src/QLNet/Cashflows/averagebmacoupon.cs rename to src/QLNet/Cashflows/AverageBMACoupon.cs index 774e40df2..430b78cda 100644 --- a/src/QLNet/Cashflows/averagebmacoupon.cs +++ b/src/QLNet/Cashflows/AverageBMACoupon.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -34,28 +34,28 @@ namespace QLNet /// /// Before weights are computed, the fixing schedule is adjusted /// for the index's fixing day gap. See rate() method for details. - /// + /// public class AverageBMACoupon : FloatingRateCoupon { - public AverageBMACoupon( Date paymentDate, - double nominal, - Date startDate, - Date endDate, - BMAIndex index, - double gearing = 1.0, - double spread = 0.0, - Date refPeriodStart = null, - Date refPeriodEnd = null, - DayCounter dayCounter = null ) - : base( paymentDate, nominal, startDate, endDate, index.fixingDays(), index, gearing, spread, - refPeriodStart, refPeriodEnd, dayCounter ) + public AverageBMACoupon(Date paymentDate, + double nominal, + Date startDate, + Date endDate, + BMAIndex index, + double gearing = 1.0, + double spread = 0.0, + Date refPeriodStart = null, + Date refPeriodEnd = null, + DayCounter dayCounter = null) + : base(paymentDate, nominal, startDate, endDate, index.fixingDays(), index, gearing, spread, + refPeriodStart, refPeriodEnd, dayCounter) { fixingSchedule_ = index.fixingSchedule( - index.fixingCalendar() - .advance( startDate, new Period( -index.fixingDays() , TimeUnit.Days ), - BusinessDayConvention.Preceding ), endDate ); - setPricer( new AverageBMACouponPricer() ); + index.fixingCalendar() + .advance(startDate, new Period(-index.fixingDays(), TimeUnit.Days), + BusinessDayConvention.Preceding), endDate); + setPricer(new AverageBMACouponPricer()); } /// @@ -88,7 +88,7 @@ public override double indexFixing() /// fixings of the underlying index to be averaged /// /// A list of double - public List indexFixings() { return fixingSchedule_.dates().Select( d => index_.fixing( d ) ).ToList(); } + public List indexFixings() { return fixingSchedule_.dates().Select(d => index_.fixing(d)).ToList(); } /// /// not applicable here @@ -104,10 +104,10 @@ public override double convexityAdjustment() public class AverageBMACouponPricer : FloatingRateCouponPricer { - public override void initialize( FloatingRateCoupon coupon ) + public override void initialize(FloatingRateCoupon coupon) { coupon_ = coupon as AverageBMACoupon; - Utils.QL_REQUIRE(coupon_ != null,()=> "wrong coupon type"); + Utils.QL_REQUIRE(coupon_ != null, () => "wrong coupon type"); } public override double swapletRate() @@ -120,33 +120,33 @@ public override double swapletRate() endDate = coupon_.accrualEndDate() - cutoffDays, d1 = startDate; - Utils.QL_REQUIRE(fixingDates.Count > 0,()=> "fixing date list empty"); - Utils.QL_REQUIRE(index.valueDate(fixingDates.First()) <= startDate,()=> "first fixing date valid after period start"); - Utils.QL_REQUIRE(index.valueDate(fixingDates.Last()) >= endDate,()=> "last fixing date valid before period end"); + Utils.QL_REQUIRE(fixingDates.Count > 0, () => "fixing date list empty"); + Utils.QL_REQUIRE(index.valueDate(fixingDates.First()) <= startDate, () => "first fixing date valid after period start"); + Utils.QL_REQUIRE(index.valueDate(fixingDates.Last()) >= endDate, () => "last fixing date valid before period end"); double avgBMA = 0.0; int days = 0; - for ( int i = 0; i < fixingDates.Count - 1; ++i ) + for (int i = 0; i < fixingDates.Count - 1; ++i) { - Date valueDate = index.valueDate( fixingDates[i] ); - Date nextValueDate = index.valueDate( fixingDates[i + 1] ); + Date valueDate = index.valueDate(fixingDates[i]); + Date nextValueDate = index.valueDate(fixingDates[i + 1]); - if ( fixingDates[i] >= endDate || valueDate >= endDate ) + if (fixingDates[i] >= endDate || valueDate >= endDate) break; - if ( fixingDates[i + 1] < startDate || nextValueDate <= startDate ) + if (fixingDates[i + 1] < startDate || nextValueDate <= startDate) continue; - Date d2 = Date.Min( nextValueDate, endDate ); + Date d2 = Date.Min(nextValueDate, endDate); - avgBMA += index.fixing( fixingDates[i] ) * ( d2 - d1 ); + avgBMA += index.fixing(fixingDates[i]) * (d2 - d1); days += d2 - d1; d1 = d2; } - avgBMA /= ( endDate - startDate ); + avgBMA /= (endDate - startDate); - Utils.QL_REQUIRE(days == endDate - startDate,()=> - "averaging days " + days + " differ from " + "interest days " + (endDate - startDate)); + Utils.QL_REQUIRE(days == endDate - startDate, () => + "averaging days " + days + " differ from " + "interest days " + (endDate - startDate)); return coupon_.gearing() * avgBMA + coupon_.spread(); } @@ -163,7 +163,7 @@ public override double swapletPrice() /// /// not applicable here /// - public override double capletPrice( double d ) + public override double capletPrice(double d) { Utils.QL_FAIL("not available"); return 0; @@ -172,7 +172,7 @@ public override double capletPrice( double d ) /// /// not applicable here /// - public override double capletRate( double d ) + public override double capletRate(double d) { Utils.QL_FAIL("not available"); return 0; @@ -181,7 +181,7 @@ public override double capletRate( double d ) /// /// not applicable here /// - public override double floorletPrice( double d ) + public override double floorletPrice(double d) { Utils.QL_FAIL("not available"); return 0; @@ -190,7 +190,7 @@ public override double floorletPrice( double d ) /// /// not applicable here /// - public override double floorletRate( double d ) + public override double floorletRate(double d) { Utils.QL_FAIL("not available"); return 0; @@ -214,34 +214,34 @@ public class AverageBMALeg : RateLegBase private List gearings_; private List spreads_; - public AverageBMALeg( Schedule schedule, BMAIndex index ) + public AverageBMALeg(Schedule schedule, BMAIndex index) { schedule_ = schedule; index_ = index; paymentAdjustment_ = BusinessDayConvention.Following; } - public AverageBMALeg withPaymentDayCounter( DayCounter dayCounter ) + public AverageBMALeg withPaymentDayCounter(DayCounter dayCounter) { paymentDayCounter_ = dayCounter; return this; } - public AverageBMALeg withGearings( double gearing ) + public AverageBMALeg withGearings(double gearing) { gearings_ = new List() { gearing }; return this; } - public AverageBMALeg withGearings( List gearings ) + public AverageBMALeg withGearings(List gearings) { gearings_ = gearings; return this; } - public AverageBMALeg withSpreads( double spread ) + public AverageBMALeg withSpreads(double spread) { spreads_ = new List() { spread }; return this; } - public AverageBMALeg withSpreads( List spreads ) + public AverageBMALeg withSpreads(List spreads) { spreads_ = spreads; return this; @@ -249,7 +249,7 @@ public AverageBMALeg withSpreads( List spreads ) public override List value() { - Utils.QL_REQUIRE(!notionals_.empty(),()=> "no notional given"); + Utils.QL_REQUIRE(!notionals_.empty(), () => "no notional given"); List cashflows = new List(); @@ -260,24 +260,24 @@ public override List value() Date paymentDate; int n = schedule_.Count - 1; - for ( int i = 0; i < n; ++i ) + for (int i = 0; i < n; ++i) { - refStart = start = schedule_.date( i ); - refEnd = end = schedule_.date( i + 1 ); - paymentDate = calendar.adjust( end, paymentAdjustment_ ); - if ( i == 0 && !schedule_.isRegular( i + 1 ) ) - refStart = calendar.adjust( end - schedule_.tenor(), paymentAdjustment_ ); - if ( i == n - 1 && !schedule_.isRegular( i + 1 ) ) - refEnd = calendar.adjust( start + schedule_.tenor(), paymentAdjustment_ ); - - cashflows.Add( new AverageBMACoupon( paymentDate, - Utils.Get( notionals_, i, notionals_.Last() ), + refStart = start = schedule_.date(i); + refEnd = end = schedule_.date(i + 1); + paymentDate = calendar.adjust(end, paymentAdjustment_); + if (i == 0 && !schedule_.isRegular(i + 1)) + refStart = calendar.adjust(end - schedule_.tenor(), paymentAdjustment_); + if (i == n - 1 && !schedule_.isRegular(i + 1)) + refEnd = calendar.adjust(start + schedule_.tenor(), paymentAdjustment_); + + cashflows.Add(new AverageBMACoupon(paymentDate, + Utils.Get(notionals_, i, notionals_.Last()), start, end, index_, - Utils.Get( gearings_, i, 1.0 ), - Utils.Get( spreads_, i, 0.0 ), + Utils.Get(gearings_, i, 1.0), + Utils.Get(spreads_, i, 0.0), refStart, refEnd, - paymentDayCounter_ ) ); + paymentDayCounter_)); } return cashflows; diff --git a/src/QLNet/Cashflows/CPICoupon.cs b/src/QLNet/Cashflows/CPICoupon.cs index 54915525b..cfc8aa338 100644 --- a/src/QLNet/Cashflows/CPICoupon.cs +++ b/src/QLNet/Cashflows/CPICoupon.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -54,69 +54,71 @@ public class CPICoupon : InflationCoupon protected double spread_; protected InterpolationType observationInterpolation_; - protected override bool checkPricerImpl(InflationCouponPricer pricer) + protected override bool checkPricerImpl(InflationCouponPricer pricer) { CPICouponPricer p = pricer as CPICouponPricer; - return ( p != null ); + return (p != null); } - + // use to calculate for fixing date, allows change of // interpolation w.r.t. index. Can also be used ahead of time protected double indexFixing(Date d) { // you may want to modify the interpolation of the index - // this gives you the chance - - double I1; - // what interpolation do we use? Index / flat / linear - if (observationInterpolation() == InterpolationType.AsIndex) - { - I1 = cpiIndex().fixing(d); - } - else - { + // this gives you the chance + + double I1; + // what interpolation do we use? Index / flat / linear + if (observationInterpolation() == InterpolationType.AsIndex) + { + I1 = cpiIndex().fixing(d); + } + else + { // work out what it should be - KeyValuePair dd = Utils.inflationPeriod(d, cpiIndex().frequency()); + KeyValuePair dd = Utils.inflationPeriod(d, cpiIndex().frequency()); double indexStart = cpiIndex().fixing(dd.Key); - if (observationInterpolation() == InterpolationType.Linear) + if (observationInterpolation() == InterpolationType.Linear) + { + double indexEnd = cpiIndex().fixing(dd.Value + new Period(1, TimeUnit.Days)); + // linear interpolation + I1 = indexStart + (indexEnd - indexStart) * (d - dd.Key) + / (double)((dd.Value + new Period(1, TimeUnit.Days)) - dd.Key); // can't get to next period's value within current period + } + else { - double indexEnd = cpiIndex().fixing(dd.Value + new Period(1,TimeUnit.Days)); - // linear interpolation - I1 = indexStart + (indexEnd - indexStart) * (d - dd.Key) - / (double)((dd.Value + new Period(1, TimeUnit.Days)) - dd.Key); // can't get to next period's value within current period - } else { - // no interpolation, i.e. flat = constant, so use start-of-period value - I1 = indexStart; + // no interpolation, i.e. flat = constant, so use start-of-period value + I1 = indexStart; } - } - return I1; + } + return I1; } - + public CPICoupon(double baseCPI, // user provided, could be arbitrary - Date paymentDate, - double nominal, - Date startDate, - Date endDate, - int fixingDays, - ZeroInflationIndex index, - Period observationLag, - InterpolationType observationInterpolation, - DayCounter dayCounter, - double fixedRate, // aka gearing - double spread = 0.0, - Date refPeriodStart = null, - Date refPeriodEnd = null, - Date exCouponDate = null) - :base(paymentDate, nominal, startDate, endDate, fixingDays, index, - observationLag, dayCounter, refPeriodStart, refPeriodEnd, exCouponDate) + Date paymentDate, + double nominal, + Date startDate, + Date endDate, + int fixingDays, + ZeroInflationIndex index, + Period observationLag, + InterpolationType observationInterpolation, + DayCounter dayCounter, + double fixedRate, // aka gearing + double spread = 0.0, + Date refPeriodStart = null, + Date refPeriodEnd = null, + Date exCouponDate = null) + : base(paymentDate, nominal, startDate, endDate, fixingDays, index, + observationLag, dayCounter, refPeriodStart, refPeriodEnd, exCouponDate) { baseCPI_ = baseCPI; fixedRate_ = fixedRate; spread_ = spread; observationInterpolation_ = observationInterpolation; - Utils.QL_REQUIRE( Math.Abs( baseCPI_ ) > 1e-16, () => "|baseCPI_| < 1e-16, future divide-by-zero problem" ); + Utils.QL_REQUIRE(Math.Abs(baseCPI_) > 1e-16, () => "|baseCPI_| < 1e-16, future divide-by-zero problem"); } // Inspectors @@ -156,20 +158,20 @@ public CPICashFlow(double notional, bool growthOnly = false, InterpolationType interpolation = InterpolationType.AsIndex, Frequency frequency = Frequency.NoFrequency) - : base(notional, index, baseDate, fixingDate,paymentDate, growthOnly) + : base(notional, index, baseDate, fixingDate, paymentDate, growthOnly) { - baseFixing_= baseFixing; - interpolation_= interpolation; - frequency_=frequency; + baseFixing_ = baseFixing; + interpolation_ = interpolation; + frequency_ = frequency; - Utils.QL_REQUIRE(Math.Abs(baseFixing_) > 1e-16,()=> "|baseFixing|<1e-16, future divide-by-zero error"); + Utils.QL_REQUIRE(Math.Abs(baseFixing_) > 1e-16, () => "|baseFixing|<1e-16, future divide-by-zero error"); if (interpolation_ != InterpolationType.AsIndex) { - Utils.QL_REQUIRE( frequency_ != Frequency.NoFrequency,()=>"non-index interpolation w/o frequency"); + Utils.QL_REQUIRE(frequency_ != Frequency.NoFrequency, () => "non-index interpolation w/o frequency"); } } - + //! value used on base date /*! This does not have to agree with index on that date. */ public virtual double baseFixing() {return baseFixing_;} @@ -188,54 +190,54 @@ public override Date baseDate() //! redefined to use baseFixing() and interpolation public override double amount() - { + { double I0 = baseFixing(); double I1; // what interpolation do we use? Index / flat / linear - if (interpolation() == InterpolationType.AsIndex ) + if (interpolation() == InterpolationType.AsIndex) { - I1 = index().fixing(fixingDate()); - } - else + I1 = index().fixing(fixingDate()); + } + else { - // work out what it should be - KeyValuePair dd = Utils.inflationPeriod(fixingDate(), frequency()); - double indexStart = index().fixing(dd.Key); - if (interpolation() == InterpolationType.Linear) - { - double indexEnd = index().fixing(dd.Value + new Period(1, TimeUnit.Days)); - // linear interpolation - I1 = indexStart + (indexEnd - indexStart) * (fixingDate() - dd.Key) - / ((dd.Value + new Period(1, TimeUnit.Days)) - dd.Key); // can't get to next period's value within current period - } - else - { - // no interpolation, i.e. flat = constant, so use start-of-period value - I1 = indexStart; - } + // work out what it should be + KeyValuePair dd = Utils.inflationPeriod(fixingDate(), frequency()); + double indexStart = index().fixing(dd.Key); + if (interpolation() == InterpolationType.Linear) + { + double indexEnd = index().fixing(dd.Value + new Period(1, TimeUnit.Days)); + // linear interpolation + I1 = indexStart + (indexEnd - indexStart) * (fixingDate() - dd.Key) + / ((dd.Value + new Period(1, TimeUnit.Days)) - dd.Key); // can't get to next period's value within current period + } + else + { + // no interpolation, i.e. flat = constant, so use start-of-period value + I1 = indexStart; + } } if (growthOnly()) - return notional() * (I1 / I0 - 1.0); + return notional() * (I1 / I0 - 1.0); else - return notional() * (I1 / I0); - } - - protected double baseFixing_; - protected InterpolationType interpolation_; - protected Frequency frequency_; - } - - //! Helper class building a sequence of capped/floored CPI coupons. - /*! Also allowing for the inflated notional at the end... - especially if there is only one date in the schedule. - If a fixedRate is zero you get a FixedRateCoupon, otherwise - you get a ZeroInflationCoupon. - - payoff is: spread + fixedRate x index - */ + return notional() * (I1 / I0); + } + + protected double baseFixing_; + protected InterpolationType interpolation_; + protected Frequency frequency_; + } + + //! Helper class building a sequence of capped/floored CPI coupons. + /*! Also allowing for the inflated notional at the end... + especially if there is only one date in the schedule. + If a fixedRate is zero you get a FixedRateCoupon, otherwise + you get a ZeroInflationCoupon. + + payoff is: spread + fixedRate x index + */ public class CPILeg : CPILegBase { public CPILeg(Schedule schedule, @@ -258,14 +260,14 @@ public CPILeg(Schedule schedule, public override List value() { - Utils.QL_REQUIRE(!notionals_.empty(),()=> "no notional given"); + Utils.QL_REQUIRE(!notionals_.empty(), () => "no notional given"); int n = schedule_.Count - 1; List leg = new List(n + 1); if (n > 0) { - Utils.QL_REQUIRE(!fixedRates_.empty() || !spreads_.empty(),()=> "no fixedRates or spreads given"); + Utils.QL_REQUIRE(!fixedRates_.empty() || !spreads_.empty(), () => "no fixedRates or spreads given"); Date refStart, start, refEnd, end; @@ -297,7 +299,7 @@ public override List value() if (Utils.Get(fixedRates_, i, 1.0).IsEqual(0.0)) { // fixed coupon - leg.Add( new FixedRateCoupon( paymentDate,Utils.Get( notionals_, i, 0.0 ), + leg.Add(new FixedRateCoupon(paymentDate, Utils.Get(notionals_, i, 0.0), Utils.effectiveFixedRate(spreads_, caps_, floors_, i), paymentDayCounter_, start, end, refStart, refEnd, exCouponDate)); } @@ -341,11 +343,11 @@ public override List value() Date pDate = paymentCalendar_.adjust(schedule_.date(n), paymentAdjustment_); Date fixingDate = pDate - observationLag_; CashFlow xnl = new CPICashFlow - (Utils.Get(notionals_, n, 0.0), index_, - new Date(), // is fake, i.e. you do not have one - baseCPI_, fixingDate, pDate, - subtractInflationNominal_, observationInterpolation_, - index_.frequency()); + (Utils.Get(notionals_, n, 0.0), index_, + new Date(), // is fake, i.e. you do not have one + baseCPI_, fixingDate, pDate, + subtractInflationNominal_, observationInterpolation_, + index_.frequency()); leg.Add(xnl); diff --git a/src/QLNet/Cashflows/CPICouponPricer.cs b/src/QLNet/Cashflows/CPICouponPricer.cs index 5e05ba6c2..109007b34 100644 --- a/src/QLNet/Cashflows/CPICouponPricer.cs +++ b/src/QLNet/Cashflows/CPICouponPricer.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010, 2011 , 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -28,22 +28,23 @@ public class CPICouponPricer : InflationCouponPricer { public CPICouponPricer(Handle capletVol = null) { - if ( capletVol == null ) + if (capletVol == null) capletVol = new Handle(); - - capletVol_ = capletVol; - if( !capletVol_.empty() ) capletVol_.registerWith(update); + capletVol_ = capletVol; + + if (!capletVol_.empty()) + capletVol_.registerWith(update); } - public virtual Handle capletVolatility() + public virtual Handle capletVolatility() { return capletVol_; } public virtual void setCapletVolatility(Handle capletVol) { - Utils.QL_REQUIRE( !capletVol.empty(), () => "empty capletVol handle" ); + Utils.QL_REQUIRE(!capletVol.empty(), () => "empty capletVol handle"); capletVol_ = capletVol; capletVol_.registerWith(update); } @@ -70,7 +71,7 @@ public override double capletPrice(double effectiveCap) } public override double capletRate(double effectiveCap) { - return capletPrice(effectiveCap)/(coupon_.accrualPeriod()*discount_); + return capletPrice(effectiveCap) / (coupon_.accrualPeriod() * discount_); } public override double floorletPrice(double effectiveFloor) { @@ -79,17 +80,17 @@ public override double floorletPrice(double effectiveFloor) } public override double floorletRate(double effectiveFloor) { - return floorletPrice(effectiveFloor) / (coupon_.accrualPeriod()*discount_); + return floorletPrice(effectiveFloor) / (coupon_.accrualPeriod() * discount_); } - public override void initialize( InflationCoupon coupon) + public override void initialize(InflationCoupon coupon) { coupon_ = coupon as CPICoupon; gearing_ = coupon_.fixedRate(); spread_ = coupon_.spread(); paymentDate_ = coupon_.date(); rateCurve_ = ((ZeroInflationIndex)coupon.index()) - .zeroInflationTermStructure().link - .nominalTermStructure(); + .zeroInflationTermStructure().link + .nominalTermStructure(); // past or future fixing is managed in YoYInflationIndex::fixing() // use yield curve from index (which sets discount) @@ -98,33 +99,33 @@ public override void initialize( InflationCoupon coupon) if (paymentDate_ > rateCurve_.link.referenceDate()) discount_ = rateCurve_.link.discount(paymentDate_); - spreadLegValue_ = spread_ * coupon_.accrualPeriod()* discount_; + spreadLegValue_ = spread_ * coupon_.accrualPeriod() * discount_; } //! can replace this if really required protected virtual double optionletPrice(Option.Type optionType, double effStrike) { Date fixingDate = coupon_.fixingDate(); - if (fixingDate <= Settings.evaluationDate()) + if (fixingDate <= Settings.evaluationDate()) { // the amount is determined double a, b; - if (optionType==Option.Type.Call) + if (optionType == Option.Type.Call) { - a = coupon_.indexFixing(); - b = effStrike; - } - else + a = coupon_.indexFixing(); + b = effStrike; + } + else { - a = effStrike; - b = coupon_.indexFixing(); + a = effStrike; + b = coupon_.indexFixing(); } - return Math.Max(a - b, 0.0)* coupon_.accrualPeriod()*discount_; - } - else + return Math.Max(a - b, 0.0) * coupon_.accrualPeriod() * discount_; + } + else { // not yet determined, use Black/DD1/Bachelier/whatever from Impl - Utils.QL_REQUIRE( !capletVolatility().empty(), () => "missing optionlet volatility" ); + Utils.QL_REQUIRE(!capletVolatility().empty(), () => "missing optionlet volatility"); double stdDev = Math.Sqrt(capletVolatility().link.totalVariance(fixingDate, effStrike)); double fixing = optionletPriceImp(optionType, effStrike, @@ -145,7 +146,7 @@ protected virtual double adjustedFixing(double? fixing = null) { if (fixing == null) fixing = coupon_.indexFixing() / coupon_.baseCPI(); - + // no adjustment return fixing.Value; } diff --git a/src/QLNet/Cashflows/CappedFlooredCoupon.cs b/src/QLNet/Cashflows/CappedFlooredCoupon.cs index 488e8dcee..1b07b4c88 100644 --- a/src/QLNet/Cashflows/CappedFlooredCoupon.cs +++ b/src/QLNet/Cashflows/CappedFlooredCoupon.cs @@ -1,51 +1,38 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2009 Siarhei Novik (snovik@gmail.com) - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -using System; namespace QLNet { - - //! Capped and/or floored floating-rate coupon - // ! The payoff \f$ P \f$ of a capped floating-rate coupon is: - // \f[ P = N \times T \times \min(a L + b, C). \f] - // The payoff of a floored floating-rate coupon is: - // \f[ P = N \times T \times \max(a L + b, F). \f] - // The payoff of a collared floating-rate coupon is: - // \f[ P = N \times T \times \min(\max(a L + b, F), C). \f] - // - // where \f$ N \f$ is the notional, \f$ T \f$ is the accrual - // time, \f$ L \f$ is the floating rate, \f$ a \f$ is its - // gearing, \f$ b \f$ is the spread, and \f$ C \f$ and \f$ F \f$ - // the strikes. - // - // They can be decomposed in the following manner. - // Decomposition of a capped floating rate coupon: - // \f[ - // R = \min(a L + b, C) = (a L + b) + \min(C - b - \xi |a| L, 0) - // \f] - // where \f$ \xi = sgn(a) \f$. Then: - // \f[ - // R = (a L + b) + |a| \min(\frac{C - b}{|a|} - \xi L, 0) - // \f] - // + /// + /// Capped and/or floored floating-rate coupon + /// + /// The payoff P of a capped floating-rate coupon is: P=NTmin(aL+b,C). + /// The payoff of a floored floating-rate coupon is: P=NTmax(aL+b,F). + /// The payoff of a collared floating-rate coupon is: P=NTmin(max(aL+b,F),C). + /// where N is the notional, T is the accrual time, L is the floating rate, a is its gearing, b is the spread, and C and F the strikes. + /// They can be decomposed in the following manner. Decomposition of a capped floating rate coupon: + /// R=min(aL+b,C)=(aL+b)+min(C?b??|a|L,0) + /// where ?=sgn(a). Then: R=(aL+b)+|a|min(C?b|a|??L,0) + /// + /// public class CappedFlooredCoupon : FloatingRateCoupon { // data @@ -59,7 +46,7 @@ public class CappedFlooredCoupon : FloatingRateCoupon public CappedFlooredCoupon() { } public CappedFlooredCoupon(FloatingRateCoupon underlying, double? cap = null, double? floor = null) - : base(underlying.date(), underlying.nominal(), underlying.accrualStartDate(), underlying.accrualEndDate(), underlying.fixingDays, underlying.index(), underlying.gearing(), underlying.spread(), underlying.referencePeriodStart, underlying.referencePeriodEnd, underlying.dayCounter(), underlying.isInArrears()) + : base(underlying.date(), underlying.nominal(), underlying.accrualStartDate(), underlying.accrualEndDate(), underlying.fixingDays, underlying.index(), underlying.gearing(), underlying.spread(), underlying.referencePeriodStart, underlying.referencePeriodEnd, underlying.dayCounter(), underlying.isInArrears()) { underlying_ = underlying; isCapped_ = false; @@ -94,14 +81,14 @@ public CappedFlooredCoupon(FloatingRateCoupon underlying, double? cap = null, do if (isCapped_ && isFloored_) { Utils.QL_REQUIRE(cap >= floor, () => - "cap level (" + cap + ") less than floor level (" + floor + ")"); + "cap level (" + cap + ") less than floor level (" + floor + ")"); } underlying.registerWith(update); } // Coupon interface public override double rate() { - Utils.QL_REQUIRE(underlying_.pricer()!=null,()=> "pricer not set"); + Utils.QL_REQUIRE(underlying_.pricer() != null, () => "pricer not set"); double swapletRate = underlying_.rate(); double floorletRate = 0.0; @@ -164,7 +151,7 @@ public override void setPricer(FloatingRateCouponPricer pricer) // Factory - for Leg generators public virtual CashFlow factory(double nominal, Date paymentDate, Date startDate, Date endDate, int fixingDays, InterestRateIndex index, double gearing, double spread, double? cap, double? floor, Date refPeriodStart, Date refPeriodEnd, DayCounter dayCounter, bool isInArrears) { - return new CappedFlooredCoupon( new IborCoupon( paymentDate, nominal, startDate, endDate, fixingDays, (IborIndex )index, gearing, spread, refPeriodStart, refPeriodEnd, dayCounter, isInArrears ), cap, floor ); + return new CappedFlooredCoupon(new IborCoupon(paymentDate, nominal, startDate, endDate, fixingDays, (IborIndex)index, gearing, spread, refPeriodStart, refPeriodEnd, dayCounter, isInArrears), cap, floor); } } @@ -174,27 +161,27 @@ public class CappedFlooredIborCoupon : CappedFlooredCoupon public CappedFlooredIborCoupon() { } public CappedFlooredIborCoupon(Date paymentDate, - double nominal, - Date startDate, - Date endDate, - int fixingDays, - IborIndex index, - double gearing = 1.0, - double spread = 0.0, - double? cap = null, - double? floor = null, - Date refPeriodStart = null, - Date refPeriodEnd = null, - DayCounter dayCounter = null, + double nominal, + Date startDate, + Date endDate, + int fixingDays, + IborIndex index, + double gearing = 1.0, + double spread = 0.0, + double? cap = null, + double? floor = null, + Date refPeriodStart = null, + Date refPeriodEnd = null, + DayCounter dayCounter = null, bool isInArrears = false) - : base( new IborCoupon( paymentDate, nominal, startDate, endDate, fixingDays, index, gearing, spread, refPeriodStart, refPeriodEnd, dayCounter, isInArrears ) as FloatingRateCoupon, cap, floor ) + : base(new IborCoupon(paymentDate, nominal, startDate, endDate, fixingDays, index, gearing, spread, refPeriodStart, refPeriodEnd, dayCounter, isInArrears) as FloatingRateCoupon, cap, floor) { } // Factory - for Leg generators public virtual CashFlow factory(double nominal, Date paymentDate, Date startDate, Date endDate, int fixingDays, IborIndex index, double gearing, double spread, double? cap, double? floor, Date refPeriodStart, Date refPeriodEnd, DayCounter dayCounter, bool isInArrears) { - return new CappedFlooredIborCoupon( paymentDate, nominal, startDate, endDate, fixingDays, index, gearing, spread, cap, floor, refPeriodStart, refPeriodEnd, dayCounter, isInArrears ); + return new CappedFlooredIborCoupon(paymentDate, nominal, startDate, endDate, fixingDays, index, gearing, spread, cap, floor, refPeriodStart, refPeriodEnd, dayCounter, isInArrears); } } @@ -203,21 +190,21 @@ public class CappedFlooredCmsCoupon : CappedFlooredCoupon // need by CashFlowVectors public CappedFlooredCmsCoupon() { } - public CappedFlooredCmsCoupon(double nominal, - Date paymentDate, - Date startDate, - Date endDate, - int fixingDays, - SwapIndex index, - double gearing = 1.0, - double spread = 0.0, - double? cap = null, - double? floor = null, - Date refPeriodStart = null, - Date refPeriodEnd = null, - DayCounter dayCounter = null, + public CappedFlooredCmsCoupon(double nominal, + Date paymentDate, + Date startDate, + Date endDate, + int fixingDays, + SwapIndex index, + double gearing = 1.0, + double spread = 0.0, + double? cap = null, + double? floor = null, + Date refPeriodStart = null, + Date refPeriodEnd = null, + DayCounter dayCounter = null, bool isInArrears = false) - : base(new CmsCoupon(nominal, paymentDate, startDate, endDate, fixingDays, index, gearing, spread, refPeriodStart, refPeriodEnd, dayCounter, isInArrears) as FloatingRateCoupon, cap, floor) + : base(new CmsCoupon(nominal, paymentDate, startDate, endDate, fixingDays, index, gearing, spread, refPeriodStart, refPeriodEnd, dayCounter, isInArrears) as FloatingRateCoupon, cap, floor) { } diff --git a/src/QLNet/Cashflows/CappedFlooredYoYInflationCoupon.cs b/src/QLNet/Cashflows/CappedFlooredYoYInflationCoupon.cs index b5ec05c0c..962a2c8b9 100644 --- a/src/QLNet/Cashflows/CappedFlooredYoYInflationCoupon.cs +++ b/src/QLNet/Cashflows/CappedFlooredYoYInflationCoupon.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -61,19 +61,19 @@ public class CappedFlooredYoYInflationCoupon : YoYInflationCoupon public CappedFlooredYoYInflationCoupon(YoYInflationCoupon underlying, double? cap = null, double? floor = null) - :base(underlying.date(), - underlying.nominal(), - underlying.accrualStartDate(), - underlying.accrualEndDate(), - underlying.fixingDays(), - underlying.yoyIndex(), - underlying.observationLag(), - underlying.dayCounter(), - underlying.gearing(), - underlying.spread(), - underlying.referencePeriodStart, - underlying.referencePeriodEnd) - + : base(underlying.date(), + underlying.nominal(), + underlying.accrualStartDate(), + underlying.accrualEndDate(), + underlying.fixingDays(), + underlying.yoyIndex(), + underlying.observationLag(), + underlying.dayCounter(), + underlying.gearing(), + underlying.spread(), + underlying.referencePeriodStart, + underlying.referencePeriodEnd) + { underlying_ = underlying; isFloored_ = false; @@ -82,7 +82,7 @@ public CappedFlooredYoYInflationCoupon(YoYInflationCoupon underlying, underlying.registerWith(update); } - + // ... or not public CappedFlooredYoYInflationCoupon(Date paymentDate, double nominal, @@ -98,12 +98,12 @@ public CappedFlooredYoYInflationCoupon(Date paymentDate, double? floor = null, Date refPeriodStart = null, Date refPeriodEnd = null) - : base(paymentDate, nominal, startDate, endDate, - fixingDays, index, observationLag, dayCounter, - gearing, spread, refPeriodStart, refPeriodEnd) + : base(paymentDate, nominal, startDate, endDate, + fixingDays, index, observationLag, dayCounter, + gearing, spread, refPeriodStart, refPeriodEnd) { isFloored_ = false; - isCapped_ = false; + isCapped_ = false; setCommon(cap, floor); } @@ -113,65 +113,66 @@ public override double rate() { double swapletRate = underlying_ != null ? underlying_.rate() : base.rate(); - if(isFloored_ || isCapped_) + if (isFloored_ || isCapped_) { - if (underlying_ != null) + if (underlying_ != null) { - Utils.QL_REQUIRE( underlying_.pricer() != null, () => "pricer not set" ); - } - else + Utils.QL_REQUIRE(underlying_.pricer() != null, () => "pricer not set"); + } + else { - Utils.QL_REQUIRE( pricer_ != null, () => "pricer not set" ); + Utils.QL_REQUIRE(pricer_ != null, () => "pricer not set"); } - } - - double floorletRate = 0.0; - if(isFloored_) - { - floorletRate = - underlying_ != null? - underlying_.pricer().floorletRate(effectiveFloor()) : - pricer().floorletRate(effectiveFloor()) - ; - } - double capletRate = 0.0; - if(isCapped_) { + } + + double floorletRate = 0.0; + if (isFloored_) + { + floorletRate = + underlying_ != null? + underlying_.pricer().floorletRate(effectiveFloor()) : + pricer().floorletRate(effectiveFloor()) + ; + } + double capletRate = 0.0; + if (isCapped_) + { capletRate = - underlying_ != null ? - underlying_.pricer().capletRate(effectiveCap()) : - pricer().capletRate(effectiveCap()) - ; - } + underlying_ != null ? + underlying_.pricer().capletRate(effectiveCap()) : + pricer().capletRate(effectiveCap()) + ; + } - return swapletRate + floorletRate - capletRate; + return swapletRate + floorletRate - capletRate; } //! cap - public double? cap() + public double? cap() { - if ( (gearing_ > 0) && isCapped_) + if ((gearing_ > 0) && isCapped_) return cap_; - if ( (gearing_ < 0) && isFloored_) + if ((gearing_ < 0) && isFloored_) return floor_; return null; } //! floor - public double? floor() + public double? floor() { - if ( (gearing_ > 0) && isFloored_) + if ((gearing_ > 0) && isFloored_) return floor_; - if ( (gearing_ < 0) && isCapped_) + if ((gearing_ < 0) && isCapped_) return cap_; return null; } //! effective cap of fixing - public double effectiveCap() + public double effectiveCap() { - return (cap_ - spread())/gearing(); + return (cap_ - spread()) / gearing(); } //! effective floor of fixing public double effectiveFloor() @@ -182,11 +183,12 @@ public double effectiveFloor() public bool isCapped() { return isCapped_; } public bool isFloored() { return isFloored_; } - - public void setPricer(YoYInflationCouponPricer pricer) + + public void setPricer(YoYInflationCouponPricer pricer) { base.setPricer(pricer); - if (underlying_ != null ) underlying_.setPricer(pricer); + if (underlying_ != null) + underlying_.setPricer(pricer); } protected virtual void setCommon(double? cap, double? floor) @@ -223,7 +225,7 @@ protected virtual void setCommon(double? cap, double? floor) if (isCapped_ && isFloored_) { - Utils.QL_REQUIRE(cap >= floor,()=> "cap level (" + cap + ") less than floor level (" + floor + ")"); + Utils.QL_REQUIRE(cap >= floor, () => "cap level (" + cap + ") less than floor level (" + floor + ")"); } } diff --git a/src/QLNet/Cashflows/CashFlows.cs b/src/QLNet/Cashflows/CashFlows.cs index 3eaeeaa05..322569246 100644 --- a/src/QLNet/Cashflows/CashFlows.cs +++ b/src/QLNet/Cashflows/CashFlows.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -25,18 +25,19 @@ under the terms of the QLNet license. You should have received a using Leg = System.Collections.Generic.List; -namespace QLNet +namespace QLNet { //! %cashflow-analysis functions - public class CashFlows + public class CashFlows { const double basisPoint_ = 1.0e-4; - + #region utility functions - private static double aggregateRate(Leg leg,CashFlow cf) + private static double aggregateRate(Leg leg, CashFlow cf) { - if ( cf == null) return 0.0; + if (cf == null) + return 0.0; Date paymentDate = cf.date(); bool firstCouponFound = false; @@ -69,13 +70,13 @@ private static double aggregateRate(Leg leg,CashFlow cf) } } - Utils.QL_REQUIRE( firstCouponFound, () => "no coupon paid at cashflow date " + paymentDate ); + Utils.QL_REQUIRE(firstCouponFound, () => "no coupon paid at cashflow date " + paymentDate); return result; - } - public static double simpleDuration(Leg leg,InterestRate y, bool includeSettlementDateFlows, - Date settlementDate,Date npvDate) + } + public static double simpleDuration(Leg leg, InterestRate y, bool includeSettlementDateFlows, + Date settlementDate, Date npvDate) { - if (leg.empty()) + if (leg.empty()) return 0.0; if (settlementDate == null) @@ -91,32 +92,32 @@ public static double simpleDuration(Leg leg,InterestRate y, bool includeSettleme Date refStartDate, refEndDate; DayCounter dc = y.dayCounter(); - for (int i=0; i "compounded rate required" ); + Utils.QL_REQUIRE(y.compounding() == Compounding.Compounded, () => "compounded rate required"); - return (1.0+y.rate()/(int)y.frequency()) * - modifiedDuration(leg, y, includeSettlementDateFlows, settlementDate, npvDate); + return (1.0 + y.rate() / (int)y.frequency()) * + modifiedDuration(leg, y, includeSettlementDateFlows, settlementDate, npvDate); } #endregion #region Helper Classes - - class IrrFinder : ISolver1d + + class IrrFinder : ISolver1d { private Leg leg_; private double npv_; @@ -244,17 +245,17 @@ class IrrFinder : ISolver1d private bool includeSettlementDateFlows_; private Date settlementDate_, npvDate_; - public IrrFinder(Leg leg, double npv,DayCounter dayCounter,Compounding comp,Frequency freq, - bool includeSettlementDateFlows,Date settlementDate,Date npvDate) + public IrrFinder(Leg leg, double npv, DayCounter dayCounter, Compounding comp, Frequency freq, + bool includeSettlementDateFlows, Date settlementDate, Date npvDate) { - leg_ = leg; + leg_ = leg; npv_ = npv; dayCounter_ = dayCounter; - compounding_= comp; + compounding_ = comp; frequency_ = freq; includeSettlementDateFlows_ = includeSettlementDateFlows; - settlementDate_=settlementDate; - npvDate_=npvDate; + settlementDate_ = settlementDate; + npvDate_ = npvDate; if (settlementDate == null) settlementDate_ = Settings.evaluationDate(); @@ -264,43 +265,43 @@ public IrrFinder(Leg leg, double npv,DayCounter dayCounter,Compounding comp,Freq checkSign(); } - - public override double value(double y) + + public override double value(double y) { InterestRate yield = new InterestRate(y, dayCounter_, compounding_, frequency_); double NPV = CashFlows.npv(leg_, yield, includeSettlementDateFlows_, settlementDate_, npvDate_); return npv_ - NPV; } - public override double derivative(double y) + public override double derivative(double y) { InterestRate yield = new InterestRate(y, dayCounter_, compounding_, frequency_); - return modifiedDuration(leg_, yield,includeSettlementDateFlows_,settlementDate_, npvDate_); + return modifiedDuration(leg_, yield, includeSettlementDateFlows_, settlementDate_, npvDate_); } - private void checkSign() + private void checkSign() { // depending on the sign of the market price, check that cash // flows of the opposite sign have been specified (otherwise // IRR is nonsensical.) int lastSign = Math.Sign(-npv_), signChanges = 0; - for (int i = 0; i < leg_.Count; ++i) + for (int i = 0; i < leg_.Count; ++i) { - if (!leg_[i].hasOccurred(settlementDate_, includeSettlementDateFlows_) && - !leg_[i].tradingExCoupon(settlementDate_)) + if (!leg_[i].hasOccurred(settlementDate_, includeSettlementDateFlows_) && + !leg_[i].tradingExCoupon(settlementDate_)) { int thisSign = Math.Sign(leg_[i].amount()); if (lastSign * thisSign < 0) // sign change - signChanges++; + signChanges++; if (thisSign != 0) - lastSign = thisSign; + lastSign = thisSign; } } - Utils.QL_REQUIRE( signChanges > 0, () => - "the given cash flows cannot result in the given market " + - "price due to their sign"); + Utils.QL_REQUIRE(signChanges > 0, () => + "the given cash flows cannot result in the given market " + + "price due to their sign"); } } class ZSpreadFinder : ISolver1d @@ -312,7 +313,7 @@ class ZSpreadFinder : ISolver1d private bool includeSettlementDateFlows_; private Date settlementDate_, npvDate_; - public ZSpreadFinder(Leg leg,YieldTermStructure discountCurve,double npv,DayCounter dc,Compounding comp,Frequency freq, + public ZSpreadFinder(Leg leg, YieldTermStructure discountCurve, double npv, DayCounter dc, Compounding comp, Frequency freq, bool includeSettlementDateFlows, Date settlementDate, Date npvDate) { leg_ = leg; @@ -339,12 +340,12 @@ public override double value(double zSpread) { zSpread_.setValue(zSpread); double NPV = CashFlows.npv(leg_, curve_, includeSettlementDateFlows_, settlementDate_, npvDate_); - return npv_ - NPV; + return npv_ - NPV; } - + } - class BPSCalculator : IAcyclicVisitor + class BPSCalculator : IAcyclicVisitor { private YieldTermStructure discountCurve_; double bps_, nonSensNPV_; @@ -358,23 +359,24 @@ public BPSCalculator(YieldTermStructure discountCurve) #region IAcyclicVisitor pattern // visitor classes should implement the generic visit method in the following form - public void visit(object o) + public void visit(object o) { Type[] types = new Type[] { o.GetType() }; - MethodInfo methodInfo = Utils.GetMethodInfo( this, "visit", types ); + MethodInfo methodInfo = Utils.GetMethodInfo(this, "visit", types); - if (methodInfo != null) { - methodInfo.Invoke(this, new object[] { o }); + if (methodInfo != null) + { + methodInfo.Invoke(this, new object[] { o }); } } - public void visit(Coupon c) + public void visit(Coupon c) { double bps = c.nominal() * - c.accrualPeriod() * - discountCurve_.discount(c.date()); + c.accrualPeriod() * + discountCurve_.discount(c.date()); bps_ += bps; } - public void visit(CashFlow cf) + public void visit(CashFlow cf) { nonSensNPV_ += cf.amount() * discountCurve_.discount(cf.date()); } @@ -382,27 +384,27 @@ public void visit(CashFlow cf) public double bps() { return bps_; } public double nonSensNPV() { return nonSensNPV_; } - } + } #endregion #region Date functions public static Date startDate(Leg leg) { - Utils.QL_REQUIRE( !leg.empty(), () => "empty leg" ); + Utils.QL_REQUIRE(!leg.empty(), () => "empty leg"); Date d = Date.maxDate(); - for (int i=0; i "empty leg" ); + Utils.QL_REQUIRE(!leg.empty(), () => "empty leg"); Date d = Date.minDate(); for (int i = 0; i < leg.Count; ++i) { @@ -414,7 +416,7 @@ public static Date maturityDate(Leg leg) } return d; } - public static bool isExpired(Leg leg, bool includeSettlementDateFlows,Date settlementDate = null) + public static bool isExpired(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) { if (leg.empty()) return true; @@ -423,7 +425,7 @@ public static bool isExpired(Leg leg, bool includeSettlementDateFlows,Date settl settlementDate = Settings.evaluationDate(); for (int i = leg.Count; i > 0; --i) - if (!leg[i - 1].hasOccurred(settlementDate,includeSettlementDateFlows)) + if (!leg[i - 1].hasOccurred(settlementDate, includeSettlementDateFlows)) return false; return true; } @@ -431,9 +433,10 @@ public static bool isExpired(Leg leg, bool includeSettlementDateFlows,Date settl #region CashFlow functions //! the last cashflow paying before or at the given date - public static CashFlow previousCashFlow(Leg leg, bool includeSettlementDateFlows,Date settlementDate = null) + public static CashFlow previousCashFlow(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) { - if (leg.empty()) return null; + if (leg.empty()) + return null; Date d = (settlementDate ?? Settings.evaluationDate()); return leg.LastOrDefault(x => x.hasOccurred(d, includeSettlementDateFlows)); @@ -441,34 +444,37 @@ public static CashFlow previousCashFlow(Leg leg, bool includeSettlementDateFlows //! the first cashflow paying after the given date public static CashFlow nextCashFlow(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) { - if (leg.empty()) return null; + if (leg.empty()) + return null; Date d = (settlementDate ?? Settings.evaluationDate()); // the first coupon paying after d is the one we're after return leg.FirstOrDefault(x => !x.hasOccurred(d, includeSettlementDateFlows)); } - public static Date previousCashFlowDate(Leg leg, bool includeSettlementDateFlows,Date settlementDate = null) + public static Date previousCashFlowDate(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) { - CashFlow cf = previousCashFlow(leg, includeSettlementDateFlows, settlementDate); + CashFlow cf = previousCashFlow(leg, includeSettlementDateFlows, settlementDate); - if (cf == null) + if (cf == null) return null; - return cf.date(); + return cf.date(); } - public static Date nextCashFlowDate(Leg leg,bool includeSettlementDateFlows,Date settlementDate = null) + public static Date nextCashFlowDate(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) { CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); - if (cf == null) return null; + if (cf == null) + return null; return cf.date(); } - public static double? previousCashFlowAmount(Leg leg,bool includeSettlementDateFlows,Date settlementDate = null) + public static double? previousCashFlowAmount(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) { - + CashFlow cf = previousCashFlow(leg, includeSettlementDateFlows, settlementDate); - if (cf==null) return null; + if (cf == null) + return null; Date paymentDate = cf.date(); double? result = 0.0; @@ -476,11 +482,12 @@ public static Date nextCashFlowDate(Leg leg,bool includeSettlementDateFlows,Date return result; } - public static double? nextCashFlowAmount(Leg leg,bool includeSettlementDateFlows,Date settlementDate = null) + public static double? nextCashFlowAmount(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) { CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); - if (cf == null) return null; + if (cf == null) + return null; Date paymentDate = cf.date(); double result = 0.0; @@ -490,7 +497,7 @@ public static Date nextCashFlowDate(Leg leg,bool includeSettlementDateFlows,Date #endregion #region Coupon inspectors - + public static double previousCouponRate(List leg, bool includeSettlementDateFlows, Date settlementDate = null) { CashFlow cf = previousCashFlow(leg, includeSettlementDateFlows, settlementDate); @@ -501,10 +508,11 @@ public static double nextCouponRate(List leg, bool includeSettlementDa CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); return aggregateRate(leg, cf); } - public static double nominal(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) + public static double nominal(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) { CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); - if (cf == null) return 0.0; + if (cf == null) + return 0.0; Date paymentDate = cf.date(); @@ -514,14 +522,15 @@ public static double nominal(Leg leg, bool includeSettlementDateFlows, Date set if (cp != null) return cp.nominal(); } - return 0.0; - } - public static Date accrualStartDate(Leg leg,bool includeSettlementDateFlows,Date settlementDate = null) + return 0.0; + } + public static Date accrualStartDate(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) { - CashFlow cf = nextCashFlow(leg,includeSettlementDateFlows,settlementDate); - if ( cf == null) return null; + CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); + if (cf == null) + return null; - Date paymentDate = cf.date(); + Date paymentDate = cf.date(); foreach (CashFlow x in leg.Where(x => x.date() == paymentDate)) { @@ -530,11 +539,12 @@ public static Date accrualStartDate(Leg leg,bool includeSettlementDateFlows,Date return cp.accrualStartDate(); } return null; - } - public static Date accrualEndDate(Leg leg,bool includeSettlementDateFlows,Date settlementDate = null) + } + public static Date accrualEndDate(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) { - CashFlow cf = nextCashFlow(leg,includeSettlementDateFlows,settlementDate); - if (cf == null) return null; + CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); + if (cf == null) + return null; Date paymentDate = cf.date(); @@ -546,10 +556,11 @@ public static Date accrualEndDate(Leg leg,bool includeSettlementDateFlows,Date s } return null; } - public static Date referencePeriodStart(Leg leg, bool includeSettlementDateFlows,Date settlementDate= null) + public static Date referencePeriodStart(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) { - CashFlow cf = nextCashFlow(leg,includeSettlementDateFlows,settlementDate); - if (cf == null) return null; + CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); + if (cf == null) + return null; Date paymentDate = cf.date(); foreach (CashFlow x in leg.Where(x => x.date() == paymentDate)) @@ -560,10 +571,11 @@ public static Date referencePeriodStart(Leg leg, bool includeSettlementDateFlows } return null; } - public static Date referencePeriodEnd(Leg leg, bool includeSettlementDateFlows,Date settlementDate = null) + public static Date referencePeriodEnd(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) { CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); - if (cf == null) return null; + if (cf == null) + return null; Date paymentDate = cf.date(); foreach (CashFlow x in leg.Where(x => x.date() == paymentDate)) @@ -574,10 +586,11 @@ public static Date referencePeriodEnd(Leg leg, bool includeSettlementDateFlows,D } return null; } - public static double accrualPeriod(Leg leg, bool includeSettlementDateFlows,Date settlementDate = null) + public static double accrualPeriod(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) { CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); - if (cf == null) return 0; + if (cf == null) + return 0; Date paymentDate = cf.date(); foreach (CashFlow x in leg.Where(x => x.date() == paymentDate)) @@ -588,10 +601,11 @@ public static double accrualPeriod(Leg leg, bool includeSettlementDateFlows,Date } return 0; } - public static int accrualDays(Leg leg, bool includeSettlementDateFlows,Date settlementDate = null) + public static int accrualDays(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) { CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); - if (cf == null) return 0; + if (cf == null) + return 0; Date paymentDate = cf.date(); foreach (CashFlow x in leg.Where(x => x.date() == paymentDate)) @@ -602,13 +616,14 @@ public static int accrualDays(Leg leg, bool includeSettlementDateFlows,Date sett } return 0; } - public static double accruedPeriod(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) + public static double accruedPeriod(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) { if (settlementDate == null) settlementDate = Settings.evaluationDate(); CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); - if (cf == null) return 0; + if (cf == null) + return 0; Date paymentDate = cf.date(); foreach (CashFlow x in leg.Where(x => x.date() == paymentDate)) @@ -618,14 +633,15 @@ public static double accruedPeriod(Leg leg, bool includeSettlementDateFlows, Dat return cp.accruedPeriod(settlementDate); } return 0; - } - public static int accruedDays(Leg leg, bool includeSettlementDateFlows,Date settlementDate = null) + } + public static int accruedDays(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) { - if ( settlementDate == null ) - settlementDate = Settings.evaluationDate(); + if (settlementDate == null) + settlementDate = Settings.evaluationDate(); CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); - if (cf == null) return 0; + if (cf == null) + return 0; Date paymentDate = cf.date(); foreach (CashFlow x in leg.Where(x => x.date() == paymentDate)) @@ -636,13 +652,14 @@ public static int accruedDays(Leg leg, bool includeSettlementDateFlows,Date sett } return 0; } - public static double accruedAmount(Leg leg, bool includeSettlementDateFlows,Date settlementDate = null) + public static double accruedAmount(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) { - if ( settlementDate == null ) - settlementDate = Settings.evaluationDate(); + if (settlementDate == null) + settlementDate = Settings.evaluationDate(); CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); - if (cf == null) return 0; + if (cf == null) + return 0; Date paymentDate = cf.date(); double result = 0.0; @@ -659,8 +676,8 @@ public static double accruedAmount(Leg leg, bool includeSettlementDateFlows,Date #region YieldTermStructure functions //! NPV of the cash flows. The NPV is the sum of the cash flows, each discounted according to the given term structure. - public static double npv(Leg leg,YieldTermStructure discountCurve, bool includeSettlementDateFlows, - Date settlementDate = null, Date npvDate = null) + public static double npv(Leg leg, YieldTermStructure discountCurve, bool includeSettlementDateFlows, + Date settlementDate = null, Date npvDate = null) { if (leg.empty()) @@ -673,14 +690,14 @@ public static double npv(Leg leg,YieldTermStructure discountCurve, bool includeS npvDate = settlementDate; double totalNPV = 0.0; - for (int i=0; i "null bps: impossible atm rate" ); + Utils.QL_REQUIRE(bps.IsNotEqual(0.0), () => "null bps: impossible atm rate"); - return targetNpv.Value/bps; - } + return targetNpv.Value / bps; + } // NPV of the cash flows. // The NPV is the sum of the cash flows, each discounted @@ -800,45 +817,45 @@ public static double npv(Leg leg, InterestRate yield, bool includeSettlementDate Date lastDate = npvDate; Date refStartDate, refEndDate; - for (int i=0; i cashflows, Date settlementDate = null, int exDividendDays = 0 ) + public static double cash(List cashflows, Date settlementDate = null, int exDividendDays = 0) { if (cashflows.Count == 0) return 0.0; @@ -912,7 +929,7 @@ public static double cash(List cashflows, Date settlementDate = null, settlementDate = Settings.evaluationDate(); double totalCASH = cashflows.Where(x => !x.hasOccurred(settlementDate + exDividendDays)). - Sum(c => c.amount()); + Sum(c => c.amount()); return totalCASH; } @@ -925,13 +942,13 @@ public static double yield(Leg leg, double npv, DayCounter dayCounter, Compoundi bool includeSettlementDateFlows, Date settlementDate = null, Date npvDate = null, double accuracy = 1.0e-10, int maxIterations = 100, double guess = 0.05) { - NewtonSafe solver = new NewtonSafe(); - solver.setMaxEvaluations(maxIterations); - IrrFinder objFunction = new IrrFinder(leg, npv, - dayCounter, compounding, frequency, - includeSettlementDateFlows, - settlementDate, npvDate); - return solver.solve(objFunction, accuracy, guess, guess/10.0); + NewtonSafe solver = new NewtonSafe(); + solver.setMaxEvaluations(maxIterations); + IrrFinder objFunction = new IrrFinder(leg, npv, + dayCounter, compounding, frequency, + includeSettlementDateFlows, + settlementDate, npvDate); + return solver.solve(objFunction, accuracy, guess, guess / 10.0); } //! Cash-flow duration. @@ -947,8 +964,8 @@ public static double duration(Leg leg, InterestRate rate, Duration.Type type, bo if (npvDate == null) npvDate = settlementDate; - switch (type) - { + switch (type) + { case Duration.Type.Simple: return simpleDuration(leg, rate, includeSettlementDateFlows, settlementDate, npvDate); case Duration.Type.Modified: @@ -993,72 +1010,72 @@ public static double convexity(Leg leg, InterestRate yield, bool includeSettleme Date lastDate = npvDate; Date refStartDate, refEndDate; - for (int i=0; i discountCurveHandle = new Handle(discountCurve); Handle zSpreadQuoteHandle = new Handle(new SimpleQuote(zSpread)); - ZeroSpreadedTermStructure spreadedCurve = new ZeroSpreadedTermStructure(discountCurveHandle,zSpreadQuoteHandle, - comp, freq, dc); + ZeroSpreadedTermStructure spreadedCurve = new ZeroSpreadedTermStructure(discountCurveHandle, zSpreadQuoteHandle, + comp, freq, dc); spreadedCurve.enableExtrapolation(discountCurveHandle.link.allowsExtrapolation()); @@ -1181,8 +1198,8 @@ public static double zSpread(Leg leg, double npv, YieldTermStructure discount, D Brent solver = new Brent(); solver.setMaxEvaluations(maxIterations); - ZSpreadFinder objFunction = new ZSpreadFinder(leg,discount,npv,dayCounter, compounding, frequency, - includeSettlementDateFlows, settlementDate, npvDate); + ZSpreadFinder objFunction = new ZSpreadFinder(leg, discount, npv, dayCounter, compounding, frequency, + includeSettlementDateFlows, settlementDate, npvDate); double step = 0.01; return solver.solve(objFunction, accuracy, guess, step); } diff --git a/src/QLNet/Cashflows/Cashflowvectors.cs b/src/QLNet/Cashflows/Cashflowvectors.cs index 560588c72..01ec0ec02 100644 --- a/src/QLNet/Cashflows/Cashflowvectors.cs +++ b/src/QLNet/Cashflows/Cashflowvectors.cs @@ -2,18 +2,18 @@ Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -45,27 +45,27 @@ public static List FloatingLeg fixingDays, List gearings, List spreads, - List caps, - List floors, + List < double? > caps, + List < double? > floors, bool isInArrears, bool isZero) - where InterestRateIndexType : InterestRateIndex, new() - where FloatingCouponType : FloatingRateCoupon, new() - where CappedFlooredCouponType : CappedFlooredCoupon, new() + where InterestRateIndexType : InterestRateIndex, new () + where FloatingCouponType : FloatingRateCoupon, new () + where CappedFlooredCouponType : CappedFlooredCoupon, new () { int n = schedule.Count; - Utils.QL_REQUIRE(!nominals.empty(),()=> "no notional given"); - Utils.QL_REQUIRE(nominals.Count <= n,()=> "too many nominals (" + nominals.Count + "), only " + n + " required"); + Utils.QL_REQUIRE(!nominals.empty(), () => "no notional given"); + Utils.QL_REQUIRE(nominals.Count <= n, () => "too many nominals (" + nominals.Count + "), only " + n + " required"); if (gearings != null) - Utils.QL_REQUIRE(gearings.Count <= n,()=> "too many gearings (" + gearings.Count + "), only " + n + " required"); + Utils.QL_REQUIRE(gearings.Count <= n, () => "too many gearings (" + gearings.Count + "), only " + n + " required"); if (spreads != null) - Utils.QL_REQUIRE(spreads.Count <= n,()=> "too many spreads (" + spreads.Count + "), only " + n + " required"); - if (caps!=null) - Utils.QL_REQUIRE(caps.Count <= n,()=> "too many caps (" + caps.Count + "), only " + n + " required"); - if ( floors != null ) - Utils.QL_REQUIRE(floors.Count <= n,()=> "too many floors (" + floors.Count + "), only " + n + " required"); - Utils.QL_REQUIRE(!isZero || !isInArrears,()=> "in-arrears and zero features are not compatible"); + Utils.QL_REQUIRE(spreads.Count <= n, () => "too many spreads (" + spreads.Count + "), only " + n + " required"); + if (caps != null) + Utils.QL_REQUIRE(caps.Count <= n, () => "too many caps (" + caps.Count + "), only " + n + " required"); + if (floors != null) + Utils.QL_REQUIRE(floors.Count <= n, () => "too many floors (" + floors.Count + "), only " + n + " required"); + Utils.QL_REQUIRE(!isZero || !isInArrears, () => "in-arrears and zero features are not compatible"); List leg = new List(); @@ -98,28 +98,28 @@ public static List FloatingLeg.Create().factory( - Utils.Get(nominals, i), - paymentDate, start, end, - Utils.Get(fixingDays, i, index.fixingDays()), - index, - Utils.Get(gearings, i, 1), - Utils.Get(spreads, i), - refStart, refEnd, paymentDayCounter, - isInArrears)); + Utils.Get(nominals, i), + paymentDate, start, end, + Utils.Get(fixingDays, i, index.fixingDays()), + index, + Utils.Get(gearings, i, 1), + Utils.Get(spreads, i), + refStart, refEnd, paymentDayCounter, + isInArrears)); } else { leg.Add(FastActivator.Create().factory( - Utils.Get(nominals, i), - paymentDate, start, end, - Utils.Get(fixingDays, i, index.fixingDays()), - index, - Utils.Get(gearings, i, 1), - Utils.Get(spreads, i), - Utils.toNullable(Utils.Get(caps, i, Double.MinValue)), - Utils.toNullable(Utils.Get(floors, i, Double.MinValue)), - refStart, refEnd, paymentDayCounter, - isInArrears)); + Utils.Get(nominals, i), + paymentDate, start, end, + Utils.Get(fixingDays, i, index.fixingDays()), + index, + Utils.Get(gearings, i, 1), + Utils.Get(spreads, i), + Utils.toNullable(Utils.Get(caps, i, Double.MinValue)), + Utils.toNullable(Utils.Get(floors, i, Double.MinValue)), + refStart, refEnd, paymentDayCounter, + isInArrears)); } } } @@ -145,21 +145,21 @@ public static List FloatingDigitalLeg putDigitalPayoffs, DigitalReplication replication) - where InterestRateIndexType : InterestRateIndex, new() - where FloatingCouponType : FloatingRateCoupon, new() - where DigitalCouponType : DigitalCoupon, new() + where InterestRateIndexType : InterestRateIndex, new () + where FloatingCouponType : FloatingRateCoupon, new () + where DigitalCouponType : DigitalCoupon, new () { int n = schedule.Count; - Utils.QL_REQUIRE(!nominals.empty(),()=> "no notional given"); - Utils.QL_REQUIRE(nominals.Count <= n,()=> "too many nominals (" + nominals.Count + "), only " + n + " required"); - if (gearings != null ) - Utils.QL_REQUIRE(gearings.Count <= n,()=> "too many gearings (" + gearings.Count + "), only " + n + " required"); - if (spreads != null ) - Utils.QL_REQUIRE(spreads.Count <= n,()=> "too many spreads (" + spreads.Count + "), only " + n + " required"); - if (callStrikes != null ) - Utils.QL_REQUIRE(callStrikes.Count <= n,()=> "too many nominals (" + callStrikes.Count + "), only " + n + " required"); - if (putStrikes != null ) - Utils.QL_REQUIRE(putStrikes.Count <= n,()=> "too many nominals (" + putStrikes.Count + "), only " + n + " required"); + Utils.QL_REQUIRE(!nominals.empty(), () => "no notional given"); + Utils.QL_REQUIRE(nominals.Count <= n, () => "too many nominals (" + nominals.Count + "), only " + n + " required"); + if (gearings != null) + Utils.QL_REQUIRE(gearings.Count <= n, () => "too many gearings (" + gearings.Count + "), only " + n + " required"); + if (spreads != null) + Utils.QL_REQUIRE(spreads.Count <= n, () => "too many spreads (" + spreads.Count + "), only " + n + " required"); + if (callStrikes != null) + Utils.QL_REQUIRE(callStrikes.Count <= n, () => "too many nominals (" + callStrikes.Count + "), only " + n + " required"); + if (putStrikes != null) + Utils.QL_REQUIRE(putStrikes.Count <= n, () => "too many nominals (" + putStrikes.Count + "), only " + n + " required"); List leg = new List(); @@ -196,26 +196,26 @@ public static List FloatingDigitalLeg.Create().factory( - Utils.Get(nominals, i, 1.0), - paymentDate, start, end, - Utils.Get(fixingDays, i, index.fixingDays()), - index, - Utils.Get(gearings, i, 1.0), - Utils.Get(spreads, i, 0.0), - refStart, refEnd, - paymentDayCounter, isInArrears) as FloatingCouponType; + Utils.Get(nominals, i, 1.0), + paymentDate, start, end, + Utils.Get(fixingDays, i, index.fixingDays()), + index, + Utils.Get(gearings, i, 1.0), + Utils.Get(spreads, i, 0.0), + refStart, refEnd, + paymentDayCounter, isInArrears) as FloatingCouponType; DigitalCouponType digitalCoupon = FastActivator.Create().factory( - underlying, - Utils.toNullable(Utils.Get(callStrikes, i, Double.MinValue)), - callPosition, - isCallATMIncluded, - Utils.toNullable(Utils.Get(callDigitalPayoffs, i, Double.MinValue)), - Utils.toNullable(Utils.Get(putStrikes, i, Double.MinValue)), - putPosition, - isPutATMIncluded, - Utils.toNullable(Utils.Get(putDigitalPayoffs, i, Double.MinValue)), - replication) as DigitalCouponType; + underlying, + Utils.toNullable(Utils.Get(callStrikes, i, Double.MinValue)), + callPosition, + isCallATMIncluded, + Utils.toNullable(Utils.Get(callDigitalPayoffs, i, Double.MinValue)), + Utils.toNullable(Utils.Get(putStrikes, i, Double.MinValue)), + putPosition, + isPutATMIncluded, + Utils.toNullable(Utils.Get(putDigitalPayoffs, i, Double.MinValue)), + replication) as DigitalCouponType; leg.Add(digitalCoupon); } @@ -248,9 +248,9 @@ public static List OvernightLeg(List nominals, refEnd = end = schedule.date(i + 1); paymentDate = calendar.adjust(end, paymentAdjustment); if (i == 0 && !schedule.isRegular(i + 1)) - refStart = calendar.adjust(end - schedule.tenor(),paymentAdjustment); + refStart = calendar.adjust(end - schedule.tenor(), paymentAdjustment); if (i == n - 1 && !schedule.isRegular(i + 1)) - refEnd = calendar.adjust(start + schedule.tenor(),paymentAdjustment); + refEnd = calendar.adjust(start + schedule.tenor(), paymentAdjustment); leg.Add(new OvernightIndexedCoupon(paymentDate, Utils.Get(nominals, i), @@ -271,8 +271,8 @@ public static List yoyInflationLeg(List notionals_, List gearings_, List spreads_, DayCounter paymentDayCounter_, - List caps_, - List floors_, + List < double? > caps_, + List < double? > floors_, Calendar paymentCalendar_, List fixingDays_, Period observationLag_) @@ -280,15 +280,15 @@ public static List yoyInflationLeg(List notionals_, int n = schedule_.Count - 1; Utils.QL_REQUIRE(!notionals_.empty(), () => "no notional given"); - Utils.QL_REQUIRE(notionals_.Count <= n,()=> "too many nominals (" + notionals_.Count + "), only " + n + " required"); + Utils.QL_REQUIRE(notionals_.Count <= n, () => "too many nominals (" + notionals_.Count + "), only " + n + " required"); if (gearings_ != null) - Utils.QL_REQUIRE(gearings_.Count <= n,()=> "too many gearings (" + gearings_.Count + "), only " + n + " required"); + Utils.QL_REQUIRE(gearings_.Count <= n, () => "too many gearings (" + gearings_.Count + "), only " + n + " required"); if (spreads_ != null) - Utils.QL_REQUIRE(spreads_.Count <= n,()=> "too many spreads (" + spreads_.Count + "), only " + n + " required"); + Utils.QL_REQUIRE(spreads_.Count <= n, () => "too many spreads (" + spreads_.Count + "), only " + n + " required"); if (caps_ != null) - Utils.QL_REQUIRE(caps_.Count <= n,()=> "too many caps (" + caps_.Count + "), only " + n + " required"); + Utils.QL_REQUIRE(caps_.Count <= n, () => "too many caps (" + caps_.Count + "), only " + n + " required"); if (floors_ != null) - Utils.QL_REQUIRE(floors_.Count <= n,()=> "too many floors (" + floors_.Count + "), only " + n + " required"); + Utils.QL_REQUIRE(floors_.Count <= n, () => "too many floors (" + floors_.Count + "), only " + n + " required"); List leg = new List(n); @@ -316,7 +316,7 @@ public static List yoyInflationLeg(List notionals_, { // fixed coupon leg.Add(new FixedRateCoupon(paymentDate, Utils.Get(notionals_, i, 1.0), - Utils.effectiveFixedRate(spreads_, caps_,floors_, i), + Utils.effectiveFixedRate(spreads_, caps_, floors_, i), paymentDayCounter_, start, end, refStart, refEnd)); } @@ -347,18 +347,18 @@ public static List yoyInflationLeg(List notionals_, { // cap/floorlet leg.Add(new CappedFlooredYoYInflationCoupon( - paymentDate, - Utils.Get(notionals_, i, 1.0), - start, end, - Utils.Get(fixingDays_, i, 0), - index_, - observationLag_, - paymentDayCounter_, - Utils.Get(gearings_, i, 1.0), - Utils.Get(spreads_, i, 0.0), - Utils.toNullable(Utils.Get(caps_, i, Double.MinValue)), - Utils.toNullable(Utils.Get(floors_, i, Double.MinValue)), - refStart, refEnd)); + paymentDate, + Utils.Get(notionals_, i, 1.0), + start, end, + Utils.Get(fixingDays_, i, 0), + index_, + observationLag_, + paymentDayCounter_, + Utils.Get(gearings_, i, 1.0), + Utils.Get(spreads_, i, 0.0), + Utils.toNullable(Utils.Get(caps_, i, Double.MinValue)), + Utils.toNullable(Utils.Get(floors_, i, Double.MinValue)), + refStart, refEnd)); } } } diff --git a/src/QLNet/Cashflows/CmsCoupon.cs b/src/QLNet/Cashflows/CmsCoupon.cs index bb573db75..f717bea7f 100644 --- a/src/QLNet/Cashflows/CmsCoupon.cs +++ b/src/QLNet/Cashflows/CmsCoupon.cs @@ -1,19 +1,19 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2009 Siarhei Novik (snovik@gmail.com) - Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,64 +21,70 @@ under the terms of the QLNet license. You should have received a using System.Collections.Generic; -namespace QLNet { - //! CMS coupon class - // ! \warning This class does not perform any date adjustment, - // i.e., the start and end date passed upon construction - // should be already rolled to a business day. - // - public class CmsCoupon : FloatingRateCoupon { - // need by CashFlowVectors - public CmsCoupon() { } +namespace QLNet +{ + //! CMS coupon class + // ! \warning This class does not perform any date adjustment, + // i.e., the start and end date passed upon construction + // should be already rolled to a business day. + // + public class CmsCoupon : FloatingRateCoupon + { + // need by CashFlowVectors + public CmsCoupon() { } - public CmsCoupon(double nominal, - Date paymentDate, - Date startDate, - Date endDate, - int fixingDays, - SwapIndex swapIndex, - double gearing = 1.0, - double spread = 0.0, - Date refPeriodStart = null, - Date refPeriodEnd = null, - DayCounter dayCounter = null, - bool isInArrears = false ) - : base( paymentDate, nominal, startDate, endDate, fixingDays, swapIndex, gearing, spread, refPeriodStart, refPeriodEnd, dayCounter, isInArrears ) - { - swapIndex_ = swapIndex; - } - // Inspectors - public SwapIndex swapIndex() { - return swapIndex_; - } + public CmsCoupon(double nominal, + Date paymentDate, + Date startDate, + Date endDate, + int fixingDays, + SwapIndex swapIndex, + double gearing = 1.0, + double spread = 0.0, + Date refPeriodStart = null, + Date refPeriodEnd = null, + DayCounter dayCounter = null, + bool isInArrears = false) + : base(paymentDate, nominal, startDate, endDate, fixingDays, swapIndex, gearing, spread, refPeriodStart, refPeriodEnd, dayCounter, isInArrears) + { + swapIndex_ = swapIndex; + } + // Inspectors + public SwapIndex swapIndex() + { + return swapIndex_; + } - private SwapIndex swapIndex_; + private SwapIndex swapIndex_; - // Factory - for Leg generators - public override CashFlow factory(double nominal, Date paymentDate, Date startDate, Date endDate, int fixingDays, - InterestRateIndex index, double gearing, double spread, - Date refPeriodStart, Date refPeriodEnd, DayCounter dayCounter, bool isInArrears) - { - return new CmsCoupon(nominal, paymentDate, startDate, endDate, fixingDays, - (SwapIndex)index, gearing, spread, refPeriodStart, refPeriodEnd, dayCounter, isInArrears); - } + // Factory - for Leg generators + public override CashFlow factory(double nominal, Date paymentDate, Date startDate, Date endDate, int fixingDays, + InterestRateIndex index, double gearing, double spread, + Date refPeriodStart, Date refPeriodEnd, DayCounter dayCounter, bool isInArrears) + { + return new CmsCoupon(nominal, paymentDate, startDate, endDate, fixingDays, + (SwapIndex)index, gearing, spread, refPeriodStart, refPeriodEnd, dayCounter, isInArrears); + } - } + } - //! helper class building a sequence of capped/floored cms-rate coupons - public class CmsLeg : FloatingLegBase { - public CmsLeg(Schedule schedule, SwapIndex swapIndex) { - schedule_ = schedule; - index_ = swapIndex; - paymentAdjustment_ = BusinessDayConvention.Following; - inArrears_ = false; - zeroPayments_ = false; - } + //! helper class building a sequence of capped/floored cms-rate coupons + public class CmsLeg : FloatingLegBase + { + public CmsLeg(Schedule schedule, SwapIndex swapIndex) + { + schedule_ = schedule; + index_ = swapIndex; + paymentAdjustment_ = BusinessDayConvention.Following; + inArrears_ = false; + zeroPayments_ = false; + } - public override List value() { - return CashFlowVectors.FloatingLeg( - notionals_, schedule_, index_ as SwapIndex, paymentDayCounter_, paymentAdjustment_, fixingDays_, gearings_, spreads_, caps_, floors_, inArrears_, zeroPayments_); - } - } + public override List value() + { + return CashFlowVectors.FloatingLeg( + notionals_, schedule_, index_ as SwapIndex, paymentDayCounter_, paymentAdjustment_, fixingDays_, gearings_, spreads_, caps_, floors_, inArrears_, zeroPayments_); + } + } } diff --git a/src/QLNet/Cashflows/CmsSpreadCoupon.cs b/src/QLNet/Cashflows/CmsSpreadCoupon.cs new file mode 100644 index 000000000..eecc2581a --- /dev/null +++ b/src/QLNet/Cashflows/CmsSpreadCoupon.cs @@ -0,0 +1,108 @@ +// Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) +// +// This file is part of QLNet Project https://github.com/amaggiulli/qlnet +// QLNet is free software: you can redistribute it and/or modify it +// under the terms of the QLNet license. You should have received a +// copy of the license along with this program; if not, license is +// available at . +// +// QLNet is a based on QuantLib, a free-software/open-source library +// for financial quantitative analysts and developers - http://quantlib.org/ +// The QuantLib license is available online at http://quantlib.org/license.shtml. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the license for more details. + +using System.Collections.Generic; + +namespace QLNet +{ + /// + /// CMS spread coupon class + /// + /// This class does not perform any date adjustment, + /// i.e., the start and end date passed upon construction + /// should be already rolled to a business day. + /// + /// + public class CmsSpreadCoupon : FloatingRateCoupon + { + // need by CashFlowVectors + public CmsSpreadCoupon() { } + + public CmsSpreadCoupon(Date paymentDate, + double nominal, + Date startDate, + Date endDate, + int fixingDays, + SwapSpreadIndex index, + double gearing = 1.0, + double spread = 0.0, + Date refPeriodStart = null, + Date refPeriodEnd = null, + DayCounter dayCounter = null, + bool isInArrears = false) + : base(paymentDate, nominal, startDate, endDate, + fixingDays, index, gearing, spread, + refPeriodStart, refPeriodEnd, dayCounter, + isInArrears) + { + index_ = index; + } + + // Inspectors + public SwapSpreadIndex swapSpreadIndex() {return index_;} + + private new SwapSpreadIndex index_; + } + + public class CappedFlooredCmsSpreadCoupon : CappedFlooredCoupon + { + public CappedFlooredCmsSpreadCoupon() + {} + + public CappedFlooredCmsSpreadCoupon(Date paymentDate, + double nominal, + Date startDate, + Date endDate, + int fixingDays, + SwapSpreadIndex index, + double gearing = 1.0, + double spread = 0.0, + double? cap = null, + double? floor = null, + Date refPeriodStart = null, + Date refPeriodEnd = null, + DayCounter dayCounter = null, + bool isInArrears = false) + : base(new CmsSpreadCoupon(paymentDate, nominal, startDate, endDate, fixingDays, + index, gearing, spread, refPeriodStart, refPeriodEnd, dayCounter, isInArrears), cap, floor) + {} + } + + /// + /// helper class building a sequence of capped/floored cms-spread-rate coupons + /// + public class CmsSpreadLeg : FloatingLegBase + { + public CmsSpreadLeg(Schedule schedule, SwapSpreadIndex swapSpreadIndex) + { + schedule_ = schedule; + swapSpreadIndex_ = swapSpreadIndex; + paymentAdjustment_ = BusinessDayConvention.Following; + inArrears_ = false; + zeroPayments_ = false; + } + public override List value() + { + return CashFlowVectors.FloatingLeg( + notionals_, schedule_, swapSpreadIndex_, paymentDayCounter_, + paymentAdjustment_, fixingDays_, gearings_, spreads_, caps_, + floors_, inArrears_, zeroPayments_); + } + + private SwapSpreadIndex swapSpreadIndex_; + } + +} diff --git a/src/QLNet/Cashflows/ConundrumPricer.cs b/src/QLNet/Cashflows/ConundrumPricer.cs index 321294f5a..05288b46a 100644 --- a/src/QLNet/Cashflows/ConundrumPricer.cs +++ b/src/QLNet/Cashflows/ConundrumPricer.cs @@ -2,18 +2,18 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,874 +22,990 @@ under the terms of the QLNet license. You should have received a using System.Collections.Generic; using System.Linq; -namespace QLNet { - public abstract class VanillaOptionPricer { - public abstract double value(double strike, Option.Type optionType, double deflator); - } - - //===========================================================================// - // BlackVanillaOptionPricer // - //===========================================================================// - public class BlackVanillaOptionPricer : VanillaOptionPricer { - private double forwardValue_; - private Date expiryDate_; - private Period swapTenor_; - private SwaptionVolatilityStructure volatilityStructure_; - private SmileSection smile_; - - public BlackVanillaOptionPricer(double forwardValue, Date expiryDate, Period swapTenor, SwaptionVolatilityStructure volatilityStructure) { - forwardValue_ = forwardValue; - expiryDate_ = expiryDate; - swapTenor_ = swapTenor; - volatilityStructure_ = volatilityStructure; - smile_ = volatilityStructure_.smileSection(expiryDate_, swapTenor_); - } - - public override double value(double strike, Option.Type optionType, double deflator) { - double variance = smile_.variance(strike); - return deflator * Utils.blackFormula(optionType, strike, forwardValue_, Math.Sqrt(variance)); - } - } - - public abstract class GFunction { - public abstract double value(double x); - public abstract double firstDerivative(double x); - public abstract double secondDerivative(double x); - } - - public class GFunctionFactory { - public enum YieldCurveModel - { - Standard, - ExactYield, - ParallelShifts, - NonParallelShifts - } - public static GFunction newGFunctionStandard(int q, double delta, int swapLength) { - return new GFunctionStandard(q, delta, swapLength) as GFunction; - } - public static GFunction newGFunctionExactYield(CmsCoupon coupon) { - return new GFunctionExactYield(coupon) as GFunction; - } - public static GFunction newGFunctionWithShifts(CmsCoupon coupon, Handle meanReversion) { - return new GFunctionWithShifts(coupon, meanReversion) as GFunction; - } - - //===========================================================================// - // GFunctionStandard // - //===========================================================================// - private class GFunctionStandard : GFunction { - // number of period per year - protected int q_; - // fraction of a period between the swap start date and the pay date - protected double delta_; - // length of swap - protected int swapLength_; - - public GFunctionStandard(int q, double delta, int swapLength) { - q_ = q; - delta_ = delta; - swapLength_ = swapLength; - } - - public override double value(double x) { - double n = swapLength_ * q_; - return x / Math.Pow((1.0 + x / q_), delta_) * 1.0 / (1.0 - 1.0 / Math.Pow((1.0 + x / q_), n)); - } - - public override double firstDerivative(double x) { - double n = swapLength_ * q_; - double a = 1.0 + x / q_; - double AA = a - delta_ / q_ * x; - double B = Math.Pow(a, (n - delta_ - 1.0)) / (Math.Pow(a, n) - 1.0); - - double secNum = n * x * Math.Pow(a, (n - 1.0)); - double secDen = q_ * Math.Pow(a, delta_) * (Math.Pow(a, n) - 1.0) * (Math.Pow(a, n) - 1.0); - double sec = secNum / secDen; - - return AA * B - sec; - } - - public override double secondDerivative(double x) { - double n = swapLength_ * q_; - double a = 1.0 + x / q_; - double AA = a - delta_ / q_ * x; - double A1 = (1.0 - delta_) / q_; - double B = Math.Pow(a, (n - delta_ - 1.0)) / (Math.Pow(a, n) - 1.0); - double Num = (1.0 + delta_ - n) * Math.Pow(a, (n - delta_ - 2.0)) - (1.0 + delta_) * Math.Pow(a, (2.0 * n - delta_ - 2.0)); - double Den = (Math.Pow(a, n) - 1.0) * (Math.Pow(a, n) - 1.0); - double B1 = 1.0 / q_ * Num / Den; - - double C = x / Math.Pow(a, delta_); - double C1 = (Math.Pow(a, delta_) - delta_ / q_ * x * Math.Pow(a, (delta_ - 1.0))) / Math.Pow(a, 2 * delta_); - - double D = Math.Pow(a, (n - 1.0)) / ((Math.Pow(a, n) - 1.0) * (Math.Pow(a, n) - 1.0)); - double D1 = ((n - 1.0) * Math.Pow(a, (n - 2.0)) * (Math.Pow(a, n) - 1.0) - 2 * n * Math.Pow(a, (2 * (n - 1.0)))) / (q_ * (Math.Pow(a, n) - 1.0) * (Math.Pow(a, n) - 1.0) * (Math.Pow(a, n) - 1.0)); - - return A1 * B + AA * B1 - n / q_ * (C1 * D + C * D1); - } - } - - //===========================================================================// - // GFunctionExactYield // - //===========================================================================// - private class GFunctionExactYield : GFunction { - // fraction of a period between the swap start date and the pay date - protected double delta_; - // accruals fraction - protected List accruals_; - - public GFunctionExactYield(CmsCoupon coupon) { - - SwapIndex swapIndex = coupon.swapIndex(); - VanillaSwap swap = swapIndex.underlyingSwap(coupon.fixingDate()); - - Schedule schedule = swap.fixedSchedule(); - Handle rateCurve = swapIndex.forwardingTermStructure(); - - DayCounter dc = swapIndex.dayCounter(); - - double swapStartTime = dc.yearFraction(rateCurve.link.referenceDate(), schedule.startDate()); - double swapFirstPaymentTime = dc.yearFraction(rateCurve.link.referenceDate(), schedule.date(1)); - - double paymentTime = dc.yearFraction(rateCurve.link.referenceDate(), coupon.date()); - - delta_ = (paymentTime - swapStartTime) / (swapFirstPaymentTime - swapStartTime); - - List fixedLeg = new List(swap.fixedLeg()); - int n = fixedLeg.Count; - accruals_ = new List(); - for (int i = 0; i < n; ++i) { - Coupon coupon1 = fixedLeg[i] as Coupon; - accruals_.Add(coupon1.accrualPeriod()); - } - } - - public override double value(double x) { - double product = 1.0; - for (int i = 0; i < accruals_.Count; i++) { - product *= 1.0 / (1.0 + accruals_[i] * x); - } - return x * Math.Pow(1.0 + accruals_[0] * x, -delta_) * (1.0 / (1.0 - product)); - } - - public override double firstDerivative(double x) { - double c = -1.0; - double derC = 0.0; - List b = new List(); - for (int i = 0; i < accruals_.Count; i++) { - double temp = 1.0 / (1.0 + accruals_[i] * x); - b.Add(temp); - c *= temp; - derC += accruals_[i] * temp; - } - c += 1.0; - c = 1.0 / c; - derC *= (c - c * c); - - return -delta_ * accruals_[0] * Math.Pow(b[0], delta_ + 1.0) * x * c + Math.Pow(b[0], delta_) * c + Math.Pow(b[0], delta_) * x * derC; - } - - public override double secondDerivative(double x) { - double c = -1.0; - double sum = 0.0; - double sumOfSquare = 0.0; - List b = new List(); - for (int i = 0; i < accruals_.Count; i++) { - double temp = 1.0 / (1.0 + accruals_[i] * x); - b.Add(temp); - c *= temp; - sum += accruals_[i] * temp; - sumOfSquare += Math.Pow(accruals_[i] * temp, 2.0); - } - c += 1.0; - c = 1.0 / c; - double derC = sum * (c - c * c); - - return (-delta_ * accruals_[0] * Math.Pow(b[0], delta_ + 1.0) * c + Math.Pow(b[0], delta_) * derC) * (-delta_ * accruals_[0] * b[0] * x + 1.0 + x * (1.0 - c) * sum) + Math.Pow(b[0], delta_) * c * (delta_ * Math.Pow(accruals_[0] * b[0], 2.0) * x - delta_ * accruals_[0] * b[0] - x * derC * sum + (1.0 - c) * sum - x * (1.0 - c) * sumOfSquare); - } - } - - private class GFunctionWithShifts : GFunction { - private double swapStartTime_; - - private double shapedPaymentTime_; - private List shapedSwapPaymentTimes_; - - private List accruals_; - private List swapPaymentDiscounts_; - private double discountAtStart_; - private double discountRatio_; - - private double swapRateValue_; - private Handle meanReversion_; - - private double calibratedShift_; - private double tmpRs_; - private double accuracy_; - - private ObjectiveFunction objectiveFunction_; - - //* function describing the non-parallel shape of the curve shift*/ - private double shapeOfShift(double s) { - double x = s - swapStartTime_; - double meanReversion = meanReversion_.link.value(); - if (meanReversion > 0) { - return (1.0 - Math.Exp(-meanReversion * x)) / meanReversion; - } else { - return x; - } - } - //* calibration of shift*/ - private double calibrationOfShift(double Rs) { - if (Rs.IsNotEqual(tmpRs_)) { - double initialGuess; - double N = 0; - double D = 0; - for (int i = 0; i < accruals_.Count; i++) { - N += accruals_[i] * swapPaymentDiscounts_[i]; - D += accruals_[i] * swapPaymentDiscounts_[i] * shapedSwapPaymentTimes_[i]; - } - N *= Rs; - D *= Rs; - N += accruals_.Last() * swapPaymentDiscounts_.Last() - objectiveFunction_.gFunctionWithShifts().discountAtStart_; - D += accruals_.Last() * swapPaymentDiscounts_.Last() * shapedSwapPaymentTimes_.Last(); - initialGuess = N / D; - - objectiveFunction_.setSwapRateValue(Rs); - Newton solver = new Newton(); - solver.setMaxEvaluations(1000); - - // these boundaries migth not be big enough if the volatility - // of big swap rate values is too high . In this case the G function - // is not even integrable, so better to fix the vol than increasing - // these values - double lower = -20; - double upper = 20.0; - - try { - calibratedShift_ = solver.solve(objectiveFunction_, accuracy_, Math.Max(Math.Min(initialGuess, upper * .99), lower * .99), lower, upper); - } catch (Exception e) { - Utils.QL_FAIL("meanReversion: " + meanReversion_.link.value() + ", swapRateValue: " + swapRateValue_ + ", swapStartTime: " + swapStartTime_ + ", shapedPaymentTime: " + shapedPaymentTime_ + "\n error message: " + e.Message); - } - tmpRs_ = Rs; - } - return calibratedShift_; - } - - private double functionZ(double x) { - return Math.Exp(-shapedPaymentTime_ * x) / (1.0 - discountRatio_ * Math.Exp(-shapedSwapPaymentTimes_.Last() * x)); - } - - private double derRs_derX(double x) { - double sqrtDenominator = 0; - double derSqrtDenominator = 0; - for (int i = 0; i < accruals_.Count; i++) { - sqrtDenominator += accruals_[i] * swapPaymentDiscounts_[i] * Math.Exp(-shapedSwapPaymentTimes_[i] * x); - derSqrtDenominator -= shapedSwapPaymentTimes_[i] * accruals_[i] * swapPaymentDiscounts_[i] * Math.Exp(-shapedSwapPaymentTimes_[i] * x); - } - double denominator = sqrtDenominator * sqrtDenominator; - - double numerator = 0; - numerator += shapedSwapPaymentTimes_.Last() * swapPaymentDiscounts_.Last() * Math.Exp(-shapedSwapPaymentTimes_.Last() * x) * sqrtDenominator; - numerator -= (discountAtStart_ - swapPaymentDiscounts_.Last() * Math.Exp(-shapedSwapPaymentTimes_.Last() * x)) * derSqrtDenominator; - if (denominator.IsEqual(0.0)) - Utils.QL_FAIL("GFunctionWithShifts::derRs_derX: denominator == 0"); - return numerator / denominator; - } - - private double derZ_derX(double x) { - double sqrtDenominator = (1.0 - discountRatio_ * Math.Exp(-shapedSwapPaymentTimes_.Last() * x)); - double denominator = sqrtDenominator * sqrtDenominator; - if (denominator.IsEqual(0.0)) - Utils.QL_FAIL("GFunctionWithShifts::derZ_derX: denominator == 0"); - - double numerator = 0; - numerator -= shapedPaymentTime_ * Math.Exp(-shapedPaymentTime_ * x) * sqrtDenominator; - numerator -= shapedSwapPaymentTimes_.Last() * Math.Exp(-shapedPaymentTime_ * x) * (1.0 - sqrtDenominator); - - return numerator / denominator; - } - - private double der2Rs_derX2(double x) { - double denOfRfunztion = 0.0; - double derDenOfRfunztion = 0.0; - double der2DenOfRfunztion = 0.0; - for (int i = 0; i < accruals_.Count; i++) { - denOfRfunztion += accruals_[i] * swapPaymentDiscounts_[i] * Math.Exp(-shapedSwapPaymentTimes_[i] * x); - derDenOfRfunztion -= shapedSwapPaymentTimes_[i] * accruals_[i] * swapPaymentDiscounts_[i] * Math.Exp(-shapedSwapPaymentTimes_[i] * x); - der2DenOfRfunztion += shapedSwapPaymentTimes_[i] * shapedSwapPaymentTimes_[i] * accruals_[i] * swapPaymentDiscounts_[i] * Math.Exp(-shapedSwapPaymentTimes_[i] * x); - } - - double denominator = Math.Pow(denOfRfunztion, 4); - - double numOfDerR = 0; - numOfDerR += shapedSwapPaymentTimes_.Last() * swapPaymentDiscounts_.Last() * Math.Exp(-shapedSwapPaymentTimes_.Last() * x) * denOfRfunztion; - numOfDerR -= (discountAtStart_ - swapPaymentDiscounts_.Last() * Math.Exp(-shapedSwapPaymentTimes_.Last() * x)) * derDenOfRfunztion; - - double denOfDerR = Math.Pow(denOfRfunztion, 2); - - double derNumOfDerR = 0.0; - derNumOfDerR -= shapedSwapPaymentTimes_.Last() * shapedSwapPaymentTimes_.Last() * swapPaymentDiscounts_.Last() * Math.Exp(-shapedSwapPaymentTimes_.Last() * x) * denOfRfunztion; - derNumOfDerR += shapedSwapPaymentTimes_.Last() * swapPaymentDiscounts_.Last() * Math.Exp(-shapedSwapPaymentTimes_.Last() * x) * derDenOfRfunztion; - - derNumOfDerR -= (shapedSwapPaymentTimes_.Last() * swapPaymentDiscounts_.Last() * Math.Exp(-shapedSwapPaymentTimes_.Last() * x)) * derDenOfRfunztion; - derNumOfDerR -= (discountAtStart_ - swapPaymentDiscounts_.Last() * Math.Exp(-shapedSwapPaymentTimes_.Last() * x)) * der2DenOfRfunztion; - - double derDenOfDerR = 2 * denOfRfunztion * derDenOfRfunztion; - - double numerator = derNumOfDerR * denOfDerR - numOfDerR * derDenOfDerR; - if (denominator.IsEqual(0.0)) - Utils.QL_FAIL("GFunctionWithShifts::der2Rs_derX2: denominator == 0"); - return numerator / denominator; - } - - private double der2Z_derX2(double x) { - double denOfZfunction = (1.0 - discountRatio_ * Math.Exp(-shapedSwapPaymentTimes_.Last() * x)); - double derDenOfZfunction = shapedSwapPaymentTimes_.Last() * discountRatio_ * Math.Exp(-shapedSwapPaymentTimes_.Last() * x); - double denominator = Math.Pow(denOfZfunction, 4); - if (denominator.IsEqual(0)) - Utils.QL_FAIL("GFunctionWithShifts::der2Z_derX2: denominator == 0"); - - double numOfDerZ = 0; - numOfDerZ -= shapedPaymentTime_ * Math.Exp(-shapedPaymentTime_ * x) * denOfZfunction; - numOfDerZ -= shapedSwapPaymentTimes_.Last() * Math.Exp(-shapedPaymentTime_ * x) * (1.0 - denOfZfunction); - - double denOfDerZ = Math.Pow(denOfZfunction, 2); - double derNumOfDerZ = (-shapedPaymentTime_ * Math.Exp(-shapedPaymentTime_ * x) * (-shapedPaymentTime_ + (shapedPaymentTime_ * discountRatio_ - shapedSwapPaymentTimes_.Last() * discountRatio_) * Math.Exp(-shapedSwapPaymentTimes_.Last() * x)) - shapedSwapPaymentTimes_.Last() * Math.Exp(-shapedPaymentTime_ * x) * (shapedPaymentTime_ * discountRatio_ - shapedSwapPaymentTimes_.Last() * discountRatio_) * Math.Exp(-shapedSwapPaymentTimes_.Last() * x)); - - double derDenOfDerZ = 2 * denOfZfunction * derDenOfZfunction; - double numerator = derNumOfDerZ * denOfDerZ - numOfDerZ * derDenOfDerZ; - - return numerator / denominator; - } - - private class ObjectiveFunction : ISolver1d { - private GFunctionWithShifts o_; - private double Rs_; - private double derivative_; - - public ObjectiveFunction(GFunctionWithShifts o, double Rs) { - o_ = o; - Rs_ = Rs; - } - public override double value(double x) { - double result = 0; - derivative_ = 0; - for (int i = 0; i < o_.accruals_.Count; i++) { - double temp = o_.accruals_[i] * o_.swapPaymentDiscounts_[i] * Math.Exp(-o_.shapedSwapPaymentTimes_[i] * x); - result += temp; - derivative_ -= o_.shapedSwapPaymentTimes_[i] * temp; - } - result *= Rs_; - derivative_ *= Rs_; - double temp1 = o_.swapPaymentDiscounts_.Last() * Math.Exp(-o_.shapedSwapPaymentTimes_.Last() * x); - - result += temp1 - o_.discountAtStart_; - derivative_ -= o_.shapedSwapPaymentTimes_.Last() * temp1; - return result; - } - - public override double derivative(double UnnamedParameter1) { return derivative_; } - public void setSwapRateValue(double x) { Rs_ = x; } - public GFunctionWithShifts gFunctionWithShifts() { return o_; } - } - - //===========================================================================// - // GFunctionWithShifts // - //===========================================================================// - public GFunctionWithShifts(CmsCoupon coupon, Handle meanReversion) { - meanReversion_ = meanReversion; - calibratedShift_ = 0.03; - tmpRs_ = 10000000.0; - accuracy_ = 1.0e-14; - - SwapIndex swapIndex = coupon.swapIndex(); - VanillaSwap swap = swapIndex.underlyingSwap(coupon.fixingDate()); - - swapRateValue_ = swap.fairRate(); - - objectiveFunction_ = new ObjectiveFunction(this, swapRateValue_); - - Schedule schedule = swap.fixedSchedule(); - Handle rateCurve = swapIndex.forwardingTermStructure(); - DayCounter dc = swapIndex.dayCounter(); - - swapStartTime_ = dc.yearFraction(rateCurve.link.referenceDate(), schedule.startDate()); - discountAtStart_ = rateCurve.link.discount(schedule.startDate()); - - double paymentTime = dc.yearFraction(rateCurve.link.referenceDate(), coupon.date()); - - shapedPaymentTime_ = shapeOfShift(paymentTime); - - List fixedLeg = new List(swap.fixedLeg()); - int n = fixedLeg.Count; - - shapedSwapPaymentTimes_ = new List(); - swapPaymentDiscounts_ = new List(); - accruals_ = new List(); - - for (int i = 0; i < n; ++i) { - Coupon coupon1 = fixedLeg[i] as Coupon; - accruals_.Add(coupon1.accrualPeriod()); - Date paymentDate = new Date(coupon1.date().serialNumber()); - double swapPaymentTime = dc.yearFraction(rateCurve.link.referenceDate(), paymentDate); - shapedSwapPaymentTimes_.Add(shapeOfShift(swapPaymentTime)); - swapPaymentDiscounts_.Add(rateCurve.link.discount(paymentDate)); - } - discountRatio_ = swapPaymentDiscounts_.Last() / discountAtStart_; +namespace QLNet +{ + public abstract class VanillaOptionPricer + { + public abstract double value(double strike, Option.Type optionType, double deflator); + } + + //===========================================================================// + // BlackVanillaOptionPricer // + //===========================================================================// + public class BlackVanillaOptionPricer : VanillaOptionPricer + { + private double forwardValue_; + private Date expiryDate_; + private Period swapTenor_; + private SwaptionVolatilityStructure volatilityStructure_; + private SmileSection smile_; + + public BlackVanillaOptionPricer(double forwardValue, Date expiryDate, Period swapTenor, SwaptionVolatilityStructure volatilityStructure) + { + forwardValue_ = forwardValue; + expiryDate_ = expiryDate; + swapTenor_ = swapTenor; + volatilityStructure_ = volatilityStructure; + smile_ = volatilityStructure_.smileSection(expiryDate_, swapTenor_); + + Utils.QL_REQUIRE(volatilityStructure.volatilityType() == VolatilityType.ShiftedLognormal && + Utils.close_enough(volatilityStructure.shift(expiryDate, swapTenor), 0.0), () => + "BlackVanillaOptionPricer: zero-shift lognormal volatility required"); + } + + public override double value(double strike, Option.Type optionType, double deflator) + { + double variance = smile_.variance(strike); + return deflator * Utils.blackFormula(optionType, strike, forwardValue_, Math.Sqrt(variance)); + } + } + + public abstract class GFunction + { + public abstract double value(double x); + public abstract double firstDerivative(double x); + public abstract double secondDerivative(double x); + } + + public class GFunctionFactory + { + public enum YieldCurveModel + { + Standard, + ExactYield, + ParallelShifts, + NonParallelShifts + } + public static GFunction newGFunctionStandard(int q, double delta, int swapLength) + { + return new GFunctionStandard(q, delta, swapLength) as GFunction; + } + public static GFunction newGFunctionExactYield(CmsCoupon coupon) + { + return new GFunctionExactYield(coupon) as GFunction; + } + public static GFunction newGFunctionWithShifts(CmsCoupon coupon, Handle meanReversion) + { + return new GFunctionWithShifts(coupon, meanReversion) as GFunction; + } + + //===========================================================================// + // GFunctionStandard // + //===========================================================================// + private class GFunctionStandard : GFunction + { + // number of period per year + protected int q_; + // fraction of a period between the swap start date and the pay date + protected double delta_; + // length of swap + protected int swapLength_; + + public GFunctionStandard(int q, double delta, int swapLength) + { + q_ = q; + delta_ = delta; + swapLength_ = swapLength; + } + + public override double value(double x) + { + double n = swapLength_ * q_; + return x / Math.Pow((1.0 + x / q_), delta_) * 1.0 / (1.0 - 1.0 / Math.Pow((1.0 + x / q_), n)); + } + + public override double firstDerivative(double x) + { + double n = swapLength_ * q_; + double a = 1.0 + x / q_; + double AA = a - delta_ / q_ * x; + double B = Math.Pow(a, (n - delta_ - 1.0)) / (Math.Pow(a, n) - 1.0); + + double secNum = n * x * Math.Pow(a, (n - 1.0)); + double secDen = q_ * Math.Pow(a, delta_) * (Math.Pow(a, n) - 1.0) * (Math.Pow(a, n) - 1.0); + double sec = secNum / secDen; + + return AA * B - sec; + } + + public override double secondDerivative(double x) + { + double n = swapLength_ * q_; + double a = 1.0 + x / q_; + double AA = a - delta_ / q_ * x; + double A1 = (1.0 - delta_) / q_; + double B = Math.Pow(a, (n - delta_ - 1.0)) / (Math.Pow(a, n) - 1.0); + double Num = (1.0 + delta_ - n) * Math.Pow(a, (n - delta_ - 2.0)) - (1.0 + delta_) * Math.Pow(a, (2.0 * n - delta_ - 2.0)); + double Den = (Math.Pow(a, n) - 1.0) * (Math.Pow(a, n) - 1.0); + double B1 = 1.0 / q_ * Num / Den; + + double C = x / Math.Pow(a, delta_); + double C1 = (Math.Pow(a, delta_) - delta_ / q_ * x * Math.Pow(a, (delta_ - 1.0))) / Math.Pow(a, 2 * delta_); + + double D = Math.Pow(a, (n - 1.0)) / ((Math.Pow(a, n) - 1.0) * (Math.Pow(a, n) - 1.0)); + double D1 = ((n - 1.0) * Math.Pow(a, (n - 2.0)) * (Math.Pow(a, n) - 1.0) - 2 * n * Math.Pow(a, (2 * (n - 1.0)))) / (q_ * (Math.Pow(a, n) - 1.0) * (Math.Pow(a, n) - 1.0) * (Math.Pow(a, n) - 1.0)); + + return A1 * B + AA * B1 - n / q_ * (C1 * D + C * D1); + } + } + + //===========================================================================// + // GFunctionExactYield // + //===========================================================================// + private class GFunctionExactYield : GFunction + { + // fraction of a period between the swap start date and the pay date + protected double delta_; + // accruals fraction + protected List accruals_; + + public GFunctionExactYield(CmsCoupon coupon) + { + + SwapIndex swapIndex = coupon.swapIndex(); + VanillaSwap swap = swapIndex.underlyingSwap(coupon.fixingDate()); + + Schedule schedule = swap.fixedSchedule(); + Handle rateCurve = swapIndex.forwardingTermStructure(); + + DayCounter dc = swapIndex.dayCounter(); + + double swapStartTime = dc.yearFraction(rateCurve.link.referenceDate(), schedule.startDate()); + double swapFirstPaymentTime = dc.yearFraction(rateCurve.link.referenceDate(), schedule.date(1)); + + double paymentTime = dc.yearFraction(rateCurve.link.referenceDate(), coupon.date()); + + delta_ = (paymentTime - swapStartTime) / (swapFirstPaymentTime - swapStartTime); + + List fixedLeg = new List(swap.fixedLeg()); + int n = fixedLeg.Count; + accruals_ = new List(); + for (int i = 0; i < n; ++i) + { + Coupon coupon1 = fixedLeg[i] as Coupon; + accruals_.Add(coupon1.accrualPeriod()); + } + } + + public override double value(double x) + { + double product = 1.0; + for (int i = 0; i < accruals_.Count; i++) + { + product *= 1.0 / (1.0 + accruals_[i] * x); + } + return x * Math.Pow(1.0 + accruals_[0] * x, -delta_) * (1.0 / (1.0 - product)); + } + + public override double firstDerivative(double x) + { + double c = -1.0; + double derC = 0.0; + List b = new List(); + for (int i = 0; i < accruals_.Count; i++) + { + double temp = 1.0 / (1.0 + accruals_[i] * x); + b.Add(temp); + c *= temp; + derC += accruals_[i] * temp; + } + c += 1.0; + c = 1.0 / c; + derC *= (c - c * c); + + return -delta_ * accruals_[0] * Math.Pow(b[0], delta_ + 1.0) * x * c + Math.Pow(b[0], delta_) * c + Math.Pow(b[0], delta_) * x * derC; + } + + public override double secondDerivative(double x) + { + double c = -1.0; + double sum = 0.0; + double sumOfSquare = 0.0; + List b = new List(); + for (int i = 0; i < accruals_.Count; i++) + { + double temp = 1.0 / (1.0 + accruals_[i] * x); + b.Add(temp); + c *= temp; + sum += accruals_[i] * temp; + sumOfSquare += Math.Pow(accruals_[i] * temp, 2.0); + } + c += 1.0; + c = 1.0 / c; + double derC = sum * (c - c * c); + + return (-delta_ * accruals_[0] * Math.Pow(b[0], delta_ + 1.0) * c + Math.Pow(b[0], delta_) * derC) * (-delta_ * accruals_[0] * b[0] * x + 1.0 + x * (1.0 - c) * sum) + Math.Pow(b[0], delta_) * c * (delta_ * Math.Pow(accruals_[0] * b[0], 2.0) * x - delta_ * accruals_[0] * b[0] - x * derC * sum + (1.0 - c) * sum - x * (1.0 - c) * sumOfSquare); + } + } + + private class GFunctionWithShifts : GFunction + { + private double swapStartTime_; + + private double shapedPaymentTime_; + private List shapedSwapPaymentTimes_; + + private List accruals_; + private List swapPaymentDiscounts_; + private double discountAtStart_; + private double discountRatio_; + + private double swapRateValue_; + private Handle meanReversion_; + + private double calibratedShift_; + private double tmpRs_; + private double accuracy_; + + private ObjectiveFunction objectiveFunction_; + + //* function describing the non-parallel shape of the curve shift*/ + private double shapeOfShift(double s) + { + double x = s - swapStartTime_; + double meanReversion = meanReversion_.link.value(); + if (meanReversion > 0) + { + return (1.0 - Math.Exp(-meanReversion * x)) / meanReversion; } - - public override double value(double Rs) { - double calibratedShift = calibrationOfShift(Rs); - return Rs * functionZ(calibratedShift); - } - - public override double firstDerivative(double Rs) { - double calibratedShift = calibrationOfShift(Rs); - return functionZ(calibratedShift) + Rs * derZ_derX(calibratedShift) / derRs_derX(calibratedShift); - } - - public override double secondDerivative(double Rs) { - double calibratedShift = calibrationOfShift(Rs); - return 2.0 * derZ_derX(calibratedShift) / derRs_derX(calibratedShift) + Rs * der2Z_derX2(calibratedShift) / Math.Pow(derRs_derX(calibratedShift), 2.0) - Rs * derZ_derX(calibratedShift) * der2Rs_derX2(calibratedShift) / Math.Pow(derRs_derX(calibratedShift), 3.0); - } - } - } - - - //===========================================================================// - // HaganPricer // - //===========================================================================// - //! Base class for the pricing of a CMS coupon via static replication as in Hagan's "Conundrums..." article - public abstract class HaganPricer : CmsCouponPricer { - public override double swapletRate() { - return swapletPrice() / (coupon_.accrualPeriod() * discount_); - } - - public override double capletPrice(double effectiveCap) { - // caplet is equivalent to call option on fixing - Date today = Settings.evaluationDate(); - if (fixingDate_ <= today) { - // the fixing is determined - double Rs = Math.Max(coupon_.swapIndex().fixing(fixingDate_) - effectiveCap, 0.0); - double price = (gearing_ * Rs) * (coupon_.accrualPeriod() * discount_); - return price; - } else { - double cutoffNearZero = 1e-10; - double capletPrice = 0; - if (effectiveCap < cutoffForCaplet_) { - double effectiveStrikeForMax = Math.Max(effectiveCap, cutoffNearZero); - capletPrice = optionletPrice(Option.Type.Call, effectiveStrikeForMax); - } - return gearing_ * capletPrice; - } - } - - public override double capletRate(double effectiveCap) { - return capletPrice(effectiveCap) / (coupon_.accrualPeriod() * discount_); - } - - public override double floorletPrice(double effectiveFloor) { - // floorlet is equivalent to put option on fixing - Date today = Settings.evaluationDate(); - if (fixingDate_ <= today) { - // the fixing is determined - double Rs = Math.Max(effectiveFloor - coupon_.swapIndex().fixing(fixingDate_), 0.0); - double price = (gearing_ * Rs) * (coupon_.accrualPeriod() * discount_); - return price; - } else { - double cutoffNearZero = 1e-10; - double floorletPrice = 0; - if (effectiveFloor > cutoffForFloorlet_) { - double effectiveStrikeForMin = Math.Max(effectiveFloor, cutoffNearZero); - floorletPrice = optionletPrice(Option.Type.Put, effectiveStrikeForMin); - } - return gearing_ * floorletPrice; - } - } - public override double floorletRate(double effectiveFloor) { - return floorletPrice(effectiveFloor) / (coupon_.accrualPeriod() * discount_); - } - // - public double meanReversion() { - return meanReversion_.link.value(); - } - public void setMeanReversion(Handle meanReversion) { - if (meanReversion_ != null) - meanReversion_.unregisterWith(update); - meanReversion_ = meanReversion; - if (meanReversion_ != null) - meanReversion_.registerWith(update); - update(); - } - - protected HaganPricer(Handle swaptionVol, GFunctionFactory.YieldCurveModel modelOfYieldCurve, Handle meanReversion) - : base(swaptionVol) { - modelOfYieldCurve_ = modelOfYieldCurve; - cutoffForCaplet_ = 2; - cutoffForFloorlet_ = 0; - meanReversion_ = meanReversion; - - if (meanReversion_.link != null) - meanReversion_.registerWith(update); - } - - protected virtual double optionletPrice(Option.Type optionType,double strike) - { - throw new NotImplementedException(); - } - public override void initialize(FloatingRateCoupon coupon) { - coupon_ = coupon as CmsCoupon; - Utils.QL_REQUIRE( coupon_ != null, () => "CMS coupon needed" ); - gearing_ = coupon_.gearing(); - spread_ = coupon_.spread(); - - fixingDate_ = coupon_.fixingDate(); - paymentDate_ = coupon_.date(); - SwapIndex swapIndex = coupon_.swapIndex(); - rateCurve_ = swapIndex.forwardingTermStructure().link; - - Date today = Settings.evaluationDate(); - - if (paymentDate_ > today) - discount_ = rateCurve_.discount(paymentDate_); else - discount_ = 1.0; - - spreadLegValue_ = spread_ * coupon_.accrualPeriod() * discount_; - - if (fixingDate_ > today) { - swapTenor_ = swapIndex.tenor(); - VanillaSwap swap = swapIndex.underlyingSwap(fixingDate_); - - swapRateValue_ = swap.fairRate(); - - double bp = 1.0e-4; - annuity_ = Math.Abs( swap.fixedLegBPS() / bp ); - - int q = (int)swapIndex.fixedLegTenor().frequency(); - Schedule schedule = swap.fixedSchedule(); - DayCounter dc = swapIndex.dayCounter(); - double startTime = dc.yearFraction(rateCurve_.referenceDate(), swap.startDate()); - double swapFirstPaymentTime = dc.yearFraction(rateCurve_.referenceDate(), schedule.date(1)); - double paymentTime = dc.yearFraction(rateCurve_.referenceDate(), paymentDate_); - double delta = (paymentTime - startTime) / (swapFirstPaymentTime - startTime); - - switch (modelOfYieldCurve_) { - case GFunctionFactory.YieldCurveModel.Standard: - gFunction_ = GFunctionFactory.newGFunctionStandard(q, delta, swapTenor_.length()); - break; - case GFunctionFactory.YieldCurveModel.ExactYield: - gFunction_ = GFunctionFactory.newGFunctionExactYield(coupon_); - break; - case GFunctionFactory.YieldCurveModel.ParallelShifts: { - Handle nullMeanReversionQuote = new Handle(new SimpleQuote(0.0)); - gFunction_ = GFunctionFactory.newGFunctionWithShifts(coupon_, nullMeanReversionQuote); - } - break; - case GFunctionFactory.YieldCurveModel.NonParallelShifts: - gFunction_ = GFunctionFactory.newGFunctionWithShifts(coupon_, meanReversion_); - break; - default: - Utils.QL_FAIL("unknown/illegal gFunction type"); - break; - } - vanillaOptionPricer_ = new BlackVanillaOptionPricer(swapRateValue_, fixingDate_, swapTenor_, swaptionVolatility().link); - } - } - - protected YieldTermStructure rateCurve_; - protected GFunctionFactory.YieldCurveModel modelOfYieldCurve_; - protected GFunction gFunction_; - protected CmsCoupon coupon_; - protected Date paymentDate_; - protected Date fixingDate_; - protected double swapRateValue_; - protected double discount_; - protected double annuity_; - protected double gearing_; - protected double spread_; - protected double spreadLegValue_; - protected double cutoffForCaplet_; - protected double cutoffForFloorlet_; - protected Handle meanReversion_; - protected Period swapTenor_; - protected VanillaOptionPricer vanillaOptionPricer_; - } - - - //===========================================================================// - // NumericHaganPricer // - //===========================================================================// - // ! Prices a cms coupon via static replication as in Hagan's - // "Conundrums..." article via numerical integration based on - // prices of vanilla swaptions - public class NumericHaganPricer : HaganPricer { - private double upperLimit_; - private double stdDeviationsForUpperLimit_; - private double lowerLimit_; - private double requiredStdDeviations_; - private double precision_; - private double refiningIntegrationTolerance_; - private double hardUpperLimit_; - - public NumericHaganPricer(Handle swaptionVol, - GFunctionFactory.YieldCurveModel modelOfYieldCurve, - Handle meanReversion, - double lowerLimit = 0.0, - double upperLimit = 1.0, - double precision = 1.0e-6, - double hardUpperLimit = Double.MaxValue) - : base(swaptionVol, modelOfYieldCurve, meanReversion) { - upperLimit_ = upperLimit; - lowerLimit_ = lowerLimit; - requiredStdDeviations_ = 8; - precision_ = precision; - refiningIntegrationTolerance_ = 0.0001; - hardUpperLimit_ = hardUpperLimit; - } - - protected override double optionletPrice(Option.Type optionType, double strike) { - ConundrumIntegrand integrand = new ConundrumIntegrand(vanillaOptionPricer_, rateCurve_, gFunction_, fixingDate_, paymentDate_, annuity_, swapRateValue_, strike, optionType); - stdDeviationsForUpperLimit_ = requiredStdDeviations_; - double a; - double b; - double integralValue; - if (optionType == Option.Type.Call) { - upperLimit_ = resetUpperLimit(stdDeviationsForUpperLimit_); - integralValue = integrate(strike, upperLimit_, integrand); - } else { - a = Math.Min(strike, lowerLimit_); - b = strike; - integralValue = integrate(a, b, integrand); - } - - double dFdK = integrand.firstDerivativeOfF(strike); - double swaptionPrice = vanillaOptionPricer_.value(strike, optionType, annuity_); - - // v. HAGAN, Conundrums..., formule 2.17a, 2.18a - return coupon_.accrualPeriod() * (discount_ / annuity_) * ((1 + dFdK) * swaptionPrice + ((int)optionType) * integralValue); - } - - public double upperLimit() { return upperLimit_; } - public double stdDeviations() { return stdDeviationsForUpperLimit_; } - - public double integrate(double a, double b, ConundrumIntegrand integrand) { - double result = .0; - // we use the non adaptive algorithm only for semi infinite interval - if (a > 0) { - // we estimate the actual boudary by testing integrand values - double upperBoundary = 2 * a; - while (integrand.value(upperBoundary) > precision_) - upperBoundary *= 2.0; - // sometimes b < a because of a wrong estimation of b based on stdev - if (b > a) - upperBoundary = Math.Min(upperBoundary, b); - - GaussKronrodNonAdaptive gaussKronrodNonAdaptive = new GaussKronrodNonAdaptive(precision_, 1000000, 1.0); - // if the integration intervall is wide enough we use the - // following change variable x -> a + (b-a)*(t/(a-b))^3 - upperBoundary = Math.Max(a,Math.Min(upperBoundary, hardUpperLimit_)); - if (upperBoundary > 2 * a) { - VariableChange variableChange = new VariableChange(integrand.value, a, upperBoundary, 3); - result = gaussKronrodNonAdaptive.value(variableChange.value, .0, 1.0); - } else { - result = gaussKronrodNonAdaptive.value(integrand.value, a, upperBoundary); - } - - // if the expected precision has not been reached we use the old algorithm - if (!gaussKronrodNonAdaptive.integrationSuccess()) { - GaussKronrodAdaptive integrator = new GaussKronrodAdaptive(precision_, 100000); - b = Math.Max(a,Math.Min(b, hardUpperLimit_)); - result = integrator.value(integrand.value, a, b); - } - } // if a < b we use the old algorithm - else { - b = Math.Max(a,Math.Min(b,hardUpperLimit_)); - GaussKronrodAdaptive integrator = new GaussKronrodAdaptive(precision_, 100000); - result = integrator.value(integrand.value, a, b); - } - return result; - } - - public override double swapletPrice() { - Date today = Settings.evaluationDate(); - if (fixingDate_ <= today) { - // the fixing is determined - double Rs = coupon_.swapIndex().fixing(fixingDate_); - double price = (gearing_ * Rs + spread_) * (coupon_.accrualPeriod() * discount_); - return price; - } else { - double atmCapletPrice = optionletPrice(Option.Type.Call, swapRateValue_); - double atmFloorletPrice = optionletPrice(Option.Type.Put, swapRateValue_); - return gearing_ * (coupon_.accrualPeriod() * discount_ * swapRateValue_ + atmCapletPrice - atmFloorletPrice) + spreadLegValue_; - } - } - - public double resetUpperLimit(double stdDeviationsForUpperLimit) { - double variance = swaptionVolatility().link.blackVariance(fixingDate_, swapTenor_, swapRateValue_); - return swapRateValue_ * Math.Exp(stdDeviationsForUpperLimit * Math.Sqrt(variance)); - } - - public double refineIntegration(double integralValue, ConundrumIntegrand integrand) { - double percDiff = 1000.0; - while (Math.Abs(percDiff) < refiningIntegrationTolerance_) { - stdDeviationsForUpperLimit_ += 1.0; - double lowerLimit = upperLimit_; - upperLimit_ = resetUpperLimit(stdDeviationsForUpperLimit_); - double diff = integrate(lowerLimit, upperLimit_, integrand); - percDiff = diff / integralValue; - integralValue += diff; - } - return integralValue; - } - - #region Nested classes - public class VariableChange { - private double a_, width_; - private Func f_; - private int k_; - - public VariableChange(Func f, double a, double b, int k) { - a_ = a; - width_ = b - a; - f_ = f; - k_ = k; - } - - public double value(double x) { - double newVar; - double temp = width_; - for (int i = 1; i < k_; ++i) { - temp *= x; - } - newVar = a_ + x * temp; - return f_(newVar) * k_ * temp; - } - } - - public class Spy { - Func f_; - private List abscissas = new List(); - private List functionValues = new List(); - - public Spy(Func f) { - f_ = f; - } - public double value(double x) { - abscissas.Add(x); - double value = f_(x); - functionValues.Add(value); - return value; - } - } - - //===========================================================================// - // ConundrumIntegrand // - //===========================================================================// - public class ConundrumIntegrand : IValue { - public ConundrumIntegrand(VanillaOptionPricer o, YieldTermStructure curve, GFunction gFunction, Date fixingDate, Date paymentDate, double annuity, double forwardValue, double strike, Option.Type optionType) { - vanillaOptionPricer_ = o; - forwardValue_ = forwardValue; - annuity_ = annuity; - fixingDate_ = fixingDate; - paymentDate_ = paymentDate; - strike_ = strike; - optionType_ = optionType; - gFunction_ = gFunction; - } - - public double value(double x) { - double option = vanillaOptionPricer_.value(x, optionType_, annuity_); - return option * secondDerivativeOfF(x); - } - - protected double functionF(double x) { - double Gx = gFunction_.value(x); - double GR = gFunction_.value(forwardValue_); - return (x - strike_) * (Gx / GR - 1.0); - } - - public double firstDerivativeOfF(double x) { - double Gx = gFunction_.value(x); - double GR = gFunction_.value(forwardValue_); - double G1 = gFunction_.firstDerivative(x); - return (Gx / GR - 1.0) + G1 / GR * (x - strike_); - } - - public double secondDerivativeOfF(double x) { - double GR = gFunction_.value(forwardValue_); - double G1 = gFunction_.firstDerivative(x); - double G2 = gFunction_.secondDerivative(x); - return 2.0 * G1 / GR + (x - strike_) * G2 / GR; + { + return x; + } + } + //* calibration of shift*/ + private double calibrationOfShift(double Rs) + { + if (Rs.IsNotEqual(tmpRs_)) + { + double initialGuess; + double N = 0; + double D = 0; + for (int i = 0; i < accruals_.Count; i++) + { + N += accruals_[i] * swapPaymentDiscounts_[i]; + D += accruals_[i] * swapPaymentDiscounts_[i] * shapedSwapPaymentTimes_[i]; + } + N *= Rs; + D *= Rs; + N += accruals_.Last() * swapPaymentDiscounts_.Last() - objectiveFunction_.gFunctionWithShifts().discountAtStart_; + D += accruals_.Last() * swapPaymentDiscounts_.Last() * shapedSwapPaymentTimes_.Last(); + initialGuess = N / D; + + objectiveFunction_.setSwapRateValue(Rs); + Newton solver = new Newton(); + solver.setMaxEvaluations(1000); + + // these boundaries migth not be big enough if the volatility + // of big swap rate values is too high . In this case the G function + // is not even integrable, so better to fix the vol than increasing + // these values + double lower = -20; + double upper = 20.0; + + try + { + calibratedShift_ = solver.solve(objectiveFunction_, accuracy_, Math.Max(Math.Min(initialGuess, upper * .99), lower * .99), lower, upper); + } + catch (Exception e) + { + Utils.QL_FAIL("meanReversion: " + meanReversion_.link.value() + ", swapRateValue: " + swapRateValue_ + ", swapStartTime: " + swapStartTime_ + ", shapedPaymentTime: " + shapedPaymentTime_ + "\n error message: " + e.Message); + } + tmpRs_ = Rs; + } + return calibratedShift_; + } + + private double functionZ(double x) + { + return Math.Exp(-shapedPaymentTime_ * x) / (1.0 - discountRatio_ * Math.Exp(-shapedSwapPaymentTimes_.Last() * x)); + } + + private double derRs_derX(double x) + { + double sqrtDenominator = 0; + double derSqrtDenominator = 0; + for (int i = 0; i < accruals_.Count; i++) + { + sqrtDenominator += accruals_[i] * swapPaymentDiscounts_[i] * Math.Exp(-shapedSwapPaymentTimes_[i] * x); + derSqrtDenominator -= shapedSwapPaymentTimes_[i] * accruals_[i] * swapPaymentDiscounts_[i] * Math.Exp(-shapedSwapPaymentTimes_[i] * x); + } + double denominator = sqrtDenominator * sqrtDenominator; + + double numerator = 0; + numerator += shapedSwapPaymentTimes_.Last() * swapPaymentDiscounts_.Last() * Math.Exp(-shapedSwapPaymentTimes_.Last() * x) * sqrtDenominator; + numerator -= (discountAtStart_ - swapPaymentDiscounts_.Last() * Math.Exp(-shapedSwapPaymentTimes_.Last() * x)) * derSqrtDenominator; + if (denominator.IsEqual(0.0)) + Utils.QL_FAIL("GFunctionWithShifts::derRs_derX: denominator == 0"); + return numerator / denominator; + } + + private double derZ_derX(double x) + { + double sqrtDenominator = (1.0 - discountRatio_ * Math.Exp(-shapedSwapPaymentTimes_.Last() * x)); + double denominator = sqrtDenominator * sqrtDenominator; + if (denominator.IsEqual(0.0)) + Utils.QL_FAIL("GFunctionWithShifts::derZ_derX: denominator == 0"); + + double numerator = 0; + numerator -= shapedPaymentTime_ * Math.Exp(-shapedPaymentTime_ * x) * sqrtDenominator; + numerator -= shapedSwapPaymentTimes_.Last() * Math.Exp(-shapedPaymentTime_ * x) * (1.0 - sqrtDenominator); + + return numerator / denominator; + } + + private double der2Rs_derX2(double x) + { + double denOfRfunztion = 0.0; + double derDenOfRfunztion = 0.0; + double der2DenOfRfunztion = 0.0; + for (int i = 0; i < accruals_.Count; i++) + { + denOfRfunztion += accruals_[i] * swapPaymentDiscounts_[i] * Math.Exp(-shapedSwapPaymentTimes_[i] * x); + derDenOfRfunztion -= shapedSwapPaymentTimes_[i] * accruals_[i] * swapPaymentDiscounts_[i] * Math.Exp(-shapedSwapPaymentTimes_[i] * x); + der2DenOfRfunztion += shapedSwapPaymentTimes_[i] * shapedSwapPaymentTimes_[i] * accruals_[i] * swapPaymentDiscounts_[i] * Math.Exp(-shapedSwapPaymentTimes_[i] * x); + } + + double denominator = Math.Pow(denOfRfunztion, 4); + + double numOfDerR = 0; + numOfDerR += shapedSwapPaymentTimes_.Last() * swapPaymentDiscounts_.Last() * Math.Exp(-shapedSwapPaymentTimes_.Last() * x) * denOfRfunztion; + numOfDerR -= (discountAtStart_ - swapPaymentDiscounts_.Last() * Math.Exp(-shapedSwapPaymentTimes_.Last() * x)) * derDenOfRfunztion; + + double denOfDerR = Math.Pow(denOfRfunztion, 2); + + double derNumOfDerR = 0.0; + derNumOfDerR -= shapedSwapPaymentTimes_.Last() * shapedSwapPaymentTimes_.Last() * swapPaymentDiscounts_.Last() * Math.Exp(-shapedSwapPaymentTimes_.Last() * x) * denOfRfunztion; + derNumOfDerR += shapedSwapPaymentTimes_.Last() * swapPaymentDiscounts_.Last() * Math.Exp(-shapedSwapPaymentTimes_.Last() * x) * derDenOfRfunztion; + + derNumOfDerR -= (shapedSwapPaymentTimes_.Last() * swapPaymentDiscounts_.Last() * Math.Exp(-shapedSwapPaymentTimes_.Last() * x)) * derDenOfRfunztion; + derNumOfDerR -= (discountAtStart_ - swapPaymentDiscounts_.Last() * Math.Exp(-shapedSwapPaymentTimes_.Last() * x)) * der2DenOfRfunztion; + + double derDenOfDerR = 2 * denOfRfunztion * derDenOfRfunztion; + + double numerator = derNumOfDerR * denOfDerR - numOfDerR * derDenOfDerR; + if (denominator.IsEqual(0.0)) + Utils.QL_FAIL("GFunctionWithShifts::der2Rs_derX2: denominator == 0"); + return numerator / denominator; + } + + private double der2Z_derX2(double x) + { + double denOfZfunction = (1.0 - discountRatio_ * Math.Exp(-shapedSwapPaymentTimes_.Last() * x)); + double derDenOfZfunction = shapedSwapPaymentTimes_.Last() * discountRatio_ * Math.Exp(-shapedSwapPaymentTimes_.Last() * x); + double denominator = Math.Pow(denOfZfunction, 4); + if (denominator.IsEqual(0)) + Utils.QL_FAIL("GFunctionWithShifts::der2Z_derX2: denominator == 0"); + + double numOfDerZ = 0; + numOfDerZ -= shapedPaymentTime_ * Math.Exp(-shapedPaymentTime_ * x) * denOfZfunction; + numOfDerZ -= shapedSwapPaymentTimes_.Last() * Math.Exp(-shapedPaymentTime_ * x) * (1.0 - denOfZfunction); + + double denOfDerZ = Math.Pow(denOfZfunction, 2); + double derNumOfDerZ = (-shapedPaymentTime_ * Math.Exp(-shapedPaymentTime_ * x) * (-shapedPaymentTime_ + (shapedPaymentTime_ * discountRatio_ - shapedSwapPaymentTimes_.Last() * discountRatio_) * Math.Exp(-shapedSwapPaymentTimes_.Last() * x)) - shapedSwapPaymentTimes_.Last() * Math.Exp(-shapedPaymentTime_ * x) * (shapedPaymentTime_ * discountRatio_ - shapedSwapPaymentTimes_.Last() * discountRatio_) * Math.Exp(-shapedSwapPaymentTimes_.Last() * x)); + + double derDenOfDerZ = 2 * denOfZfunction * derDenOfZfunction; + double numerator = derNumOfDerZ * denOfDerZ - numOfDerZ * derDenOfDerZ; + + return numerator / denominator; + } + + private class ObjectiveFunction : ISolver1d + { + private GFunctionWithShifts o_; + private double Rs_; + private double derivative_; + + public ObjectiveFunction(GFunctionWithShifts o, double Rs) + { + o_ = o; + Rs_ = Rs; + } + public override double value(double x) + { + double result = 0; + derivative_ = 0; + for (int i = 0; i < o_.accruals_.Count; i++) + { + double temp = o_.accruals_[i] * o_.swapPaymentDiscounts_[i] * Math.Exp(-o_.shapedSwapPaymentTimes_[i] * x); + result += temp; + derivative_ -= o_.shapedSwapPaymentTimes_[i] * temp; + } + result *= Rs_; + derivative_ *= Rs_; + double temp1 = o_.swapPaymentDiscounts_.Last() * Math.Exp(-o_.shapedSwapPaymentTimes_.Last() * x); + + result += temp1 - o_.discountAtStart_; + derivative_ -= o_.shapedSwapPaymentTimes_.Last() * temp1; + return result; + } + + public override double derivative(double UnnamedParameter1) { return derivative_; } + public void setSwapRateValue(double x) { Rs_ = x; } + public GFunctionWithShifts gFunctionWithShifts() { return o_; } + } + + //===========================================================================// + // GFunctionWithShifts // + //===========================================================================// + public GFunctionWithShifts(CmsCoupon coupon, Handle meanReversion) + { + meanReversion_ = meanReversion; + calibratedShift_ = 0.03; + tmpRs_ = 10000000.0; + accuracy_ = 1.0e-14; + + SwapIndex swapIndex = coupon.swapIndex(); + VanillaSwap swap = swapIndex.underlyingSwap(coupon.fixingDate()); + + swapRateValue_ = swap.fairRate(); + + objectiveFunction_ = new ObjectiveFunction(this, swapRateValue_); + + Schedule schedule = swap.fixedSchedule(); + Handle rateCurve = swapIndex.forwardingTermStructure(); + DayCounter dc = swapIndex.dayCounter(); + + swapStartTime_ = dc.yearFraction(rateCurve.link.referenceDate(), schedule.startDate()); + discountAtStart_ = rateCurve.link.discount(schedule.startDate()); + + double paymentTime = dc.yearFraction(rateCurve.link.referenceDate(), coupon.date()); + + shapedPaymentTime_ = shapeOfShift(paymentTime); + + List fixedLeg = new List(swap.fixedLeg()); + int n = fixedLeg.Count; + + shapedSwapPaymentTimes_ = new List(); + swapPaymentDiscounts_ = new List(); + accruals_ = new List(); + + for (int i = 0; i < n; ++i) + { + Coupon coupon1 = fixedLeg[i] as Coupon; + accruals_.Add(coupon1.accrualPeriod()); + Date paymentDate = new Date(coupon1.date().serialNumber()); + double swapPaymentTime = dc.yearFraction(rateCurve.link.referenceDate(), paymentDate); + shapedSwapPaymentTimes_.Add(shapeOfShift(swapPaymentTime)); + swapPaymentDiscounts_.Add(rateCurve.link.discount(paymentDate)); + } + discountRatio_ = swapPaymentDiscounts_.Last() / discountAtStart_; + } + + public override double value(double Rs) + { + double calibratedShift = calibrationOfShift(Rs); + return Rs * functionZ(calibratedShift); + } + + public override double firstDerivative(double Rs) + { + double calibratedShift = calibrationOfShift(Rs); + return functionZ(calibratedShift) + Rs * derZ_derX(calibratedShift) / derRs_derX(calibratedShift); + } + + public override double secondDerivative(double Rs) + { + double calibratedShift = calibrationOfShift(Rs); + return 2.0 * derZ_derX(calibratedShift) / derRs_derX(calibratedShift) + Rs * der2Z_derX2(calibratedShift) / Math.Pow(derRs_derX(calibratedShift), 2.0) - Rs * derZ_derX(calibratedShift) * der2Rs_derX2(calibratedShift) / Math.Pow(derRs_derX(calibratedShift), 3.0); + } + } + } + + + //===========================================================================// + // HaganPricer // + //===========================================================================// + //! Base class for the pricing of a CMS coupon via static replication as in Hagan's "Conundrums..." article + public abstract class HaganPricer : CmsCouponPricer + { + public override double swapletRate() + { + return swapletPrice() / (coupon_.accrualPeriod() * discount_); + } + + public override double capletPrice(double effectiveCap) + { + // caplet is equivalent to call option on fixing + Date today = Settings.evaluationDate(); + if (fixingDate_ <= today) + { + // the fixing is determined + double Rs = Math.Max(coupon_.swapIndex().fixing(fixingDate_) - effectiveCap, 0.0); + double price = (gearing_ * Rs) * (coupon_.accrualPeriod() * discount_); + return price; + } + else + { + double cutoffNearZero = 1e-10; + double capletPrice = 0; + if (effectiveCap < cutoffForCaplet_) + { + double effectiveStrikeForMax = Math.Max(effectiveCap, cutoffNearZero); + capletPrice = optionletPrice(Option.Type.Call, effectiveStrikeForMax); + } + return gearing_ * capletPrice; + } + } + + public override double capletRate(double effectiveCap) + { + return capletPrice(effectiveCap) / (coupon_.accrualPeriod() * discount_); + } + + public override double floorletPrice(double effectiveFloor) + { + // floorlet is equivalent to put option on fixing + Date today = Settings.evaluationDate(); + if (fixingDate_ <= today) + { + // the fixing is determined + double Rs = Math.Max(effectiveFloor - coupon_.swapIndex().fixing(fixingDate_), 0.0); + double price = (gearing_ * Rs) * (coupon_.accrualPeriod() * discount_); + return price; + } + else + { + double cutoffNearZero = 1e-10; + double floorletPrice = 0; + if (effectiveFloor > cutoffForFloorlet_) + { + double effectiveStrikeForMin = Math.Max(effectiveFloor, cutoffNearZero); + floorletPrice = optionletPrice(Option.Type.Put, effectiveStrikeForMin); + } + return gearing_ * floorletPrice; + } + } + public override double floorletRate(double effectiveFloor) + { + return floorletPrice(effectiveFloor) / (coupon_.accrualPeriod() * discount_); + } + // + public double meanReversion() + { + return meanReversion_.link.value(); + } + public void setMeanReversion(Handle meanReversion) + { + if (meanReversion_ != null) + meanReversion_.unregisterWith(update); + meanReversion_ = meanReversion; + if (meanReversion_ != null) + meanReversion_.registerWith(update); + update(); + } + + protected HaganPricer(Handle swaptionVol, GFunctionFactory.YieldCurveModel modelOfYieldCurve, Handle meanReversion) + : base(swaptionVol) + { + modelOfYieldCurve_ = modelOfYieldCurve; + cutoffForCaplet_ = 2; + cutoffForFloorlet_ = 0; + meanReversion_ = meanReversion; + + if (meanReversion_.link != null) + meanReversion_.registerWith(update); + } + + protected virtual double optionletPrice(Option.Type optionType, double strike) + { + throw new NotImplementedException(); + } + public override void initialize(FloatingRateCoupon coupon) + { + coupon_ = coupon as CmsCoupon; + Utils.QL_REQUIRE(coupon_ != null, () => "CMS coupon needed"); + gearing_ = coupon_.gearing(); + spread_ = coupon_.spread(); + + fixingDate_ = coupon_.fixingDate(); + paymentDate_ = coupon_.date(); + SwapIndex swapIndex = coupon_.swapIndex(); + rateCurve_ = swapIndex.forwardingTermStructure().link; + + Date today = Settings.evaluationDate(); + + if (paymentDate_ > today) + discount_ = rateCurve_.discount(paymentDate_); + else + discount_ = 1.0; + + spreadLegValue_ = spread_ * coupon_.accrualPeriod() * discount_; + + if (fixingDate_ > today) + { + swapTenor_ = swapIndex.tenor(); + VanillaSwap swap = swapIndex.underlyingSwap(fixingDate_); + + swapRateValue_ = swap.fairRate(); + + double bp = 1.0e-4; + annuity_ = Math.Abs(swap.fixedLegBPS() / bp); + + int q = (int)swapIndex.fixedLegTenor().frequency(); + Schedule schedule = swap.fixedSchedule(); + DayCounter dc = swapIndex.dayCounter(); + double startTime = dc.yearFraction(rateCurve_.referenceDate(), swap.startDate()); + double swapFirstPaymentTime = dc.yearFraction(rateCurve_.referenceDate(), schedule.date(1)); + double paymentTime = dc.yearFraction(rateCurve_.referenceDate(), paymentDate_); + double delta = (paymentTime - startTime) / (swapFirstPaymentTime - startTime); + + switch (modelOfYieldCurve_) + { + case GFunctionFactory.YieldCurveModel.Standard: + gFunction_ = GFunctionFactory.newGFunctionStandard(q, delta, swapTenor_.length()); + break; + case GFunctionFactory.YieldCurveModel.ExactYield: + gFunction_ = GFunctionFactory.newGFunctionExactYield(coupon_); + break; + case GFunctionFactory.YieldCurveModel.ParallelShifts: + { + Handle nullMeanReversionQuote = new Handle(new SimpleQuote(0.0)); + gFunction_ = GFunctionFactory.newGFunctionWithShifts(coupon_, nullMeanReversionQuote); + } + break; + case GFunctionFactory.YieldCurveModel.NonParallelShifts: + gFunction_ = GFunctionFactory.newGFunctionWithShifts(coupon_, meanReversion_); + break; + default: + Utils.QL_FAIL("unknown/illegal gFunction type"); + break; + } + vanillaOptionPricer_ = new BlackVanillaOptionPricer(swapRateValue_, fixingDate_, swapTenor_, swaptionVolatility().link); + } + } + + protected YieldTermStructure rateCurve_; + protected GFunctionFactory.YieldCurveModel modelOfYieldCurve_; + protected GFunction gFunction_; + protected CmsCoupon coupon_; + protected Date paymentDate_; + protected Date fixingDate_; + protected double swapRateValue_; + protected double discount_; + protected double annuity_; + protected double gearing_; + protected double spread_; + protected double spreadLegValue_; + protected double cutoffForCaplet_; + protected double cutoffForFloorlet_; + protected Handle meanReversion_; + protected Period swapTenor_; + protected VanillaOptionPricer vanillaOptionPricer_; + } + + + //===========================================================================// + // NumericHaganPricer // + //===========================================================================// + // ! Prices a cms coupon via static replication as in Hagan's + // "Conundrums..." article via numerical integration based on + // prices of vanilla swaptions + public class NumericHaganPricer : HaganPricer + { + private double upperLimit_; + private double stdDeviationsForUpperLimit_; + private double lowerLimit_; + private double requiredStdDeviations_; + private double precision_; + private double refiningIntegrationTolerance_; + private double hardUpperLimit_; + + public NumericHaganPricer(Handle swaptionVol, + GFunctionFactory.YieldCurveModel modelOfYieldCurve, + Handle meanReversion, + double lowerLimit = 0.0, + double upperLimit = 1.0, + double precision = 1.0e-6, + double hardUpperLimit = Double.MaxValue) + : base(swaptionVol, modelOfYieldCurve, meanReversion) + { + upperLimit_ = upperLimit; + lowerLimit_ = lowerLimit; + requiredStdDeviations_ = 8; + precision_ = precision; + refiningIntegrationTolerance_ = 0.0001; + hardUpperLimit_ = hardUpperLimit; + } + + protected override double optionletPrice(Option.Type optionType, double strike) + { + ConundrumIntegrand integrand = new ConundrumIntegrand(vanillaOptionPricer_, rateCurve_, gFunction_, fixingDate_, paymentDate_, annuity_, swapRateValue_, strike, optionType); + stdDeviationsForUpperLimit_ = requiredStdDeviations_; + double a; + double b; + double integralValue; + if (optionType == Option.Type.Call) + { + upperLimit_ = resetUpperLimit(stdDeviationsForUpperLimit_); + integralValue = integrate(strike, upperLimit_, integrand); + } + else + { + a = Math.Min(strike, lowerLimit_); + b = strike; + integralValue = integrate(a, b, integrand); + } + + double dFdK = integrand.firstDerivativeOfF(strike); + double swaptionPrice = vanillaOptionPricer_.value(strike, optionType, annuity_); + + // v. HAGAN, Conundrums..., formule 2.17a, 2.18a + return coupon_.accrualPeriod() * (discount_ / annuity_) * ((1 + dFdK) * swaptionPrice + ((int)optionType) * integralValue); + } + + public double upperLimit() { return upperLimit_; } + public double stdDeviations() { return stdDeviationsForUpperLimit_; } + + public double integrate(double a, double b, ConundrumIntegrand integrand) + { + double result = .0; + // we use the non adaptive algorithm only for semi infinite interval + if (a > 0) + { + // we estimate the actual boudary by testing integrand values + double upperBoundary = 2 * a; + while (integrand.value(upperBoundary) > precision_) + upperBoundary *= 2.0; + // sometimes b < a because of a wrong estimation of b based on stdev + if (b > a) + upperBoundary = Math.Min(upperBoundary, b); + + GaussKronrodNonAdaptive gaussKronrodNonAdaptive = new GaussKronrodNonAdaptive(precision_, 1000000, 1.0); + // if the integration intervall is wide enough we use the + // following change variable x -> a + (b-a)*(t/(a-b))^3 + upperBoundary = Math.Max(a, Math.Min(upperBoundary, hardUpperLimit_)); + if (upperBoundary > 2 * a) + { + VariableChange variableChange = new VariableChange(integrand.value, a, upperBoundary, 3); + result = gaussKronrodNonAdaptive.value(variableChange.value, .0, 1.0); } - - protected double strike() { return strike_; } - protected double annuity() { return annuity_; } - protected Date fixingDate() { return fixingDate_; } - protected void setStrike(double strike) { strike_ = strike; } - - protected VanillaOptionPricer vanillaOptionPricer_; - protected double forwardValue_; - protected double annuity_; - protected Date fixingDate_; - protected Date paymentDate_; - protected double strike_; - protected Option.Type optionType_; - protected GFunction gFunction_; - } - #endregion - } - - //===========================================================================// - // AnalyticHaganPricer // - //===========================================================================// - public class AnalyticHaganPricer : HaganPricer { - public AnalyticHaganPricer(Handle swaptionVol, GFunctionFactory.YieldCurveModel modelOfYieldCurve, Handle meanReversion) - : base(swaptionVol, modelOfYieldCurve, meanReversion) { - } - - //Hagan, 3.5b, 3.5c - protected override double optionletPrice(Option.Type optionType, double strike) { + else + { + result = gaussKronrodNonAdaptive.value(integrand.value, a, upperBoundary); + } + + // if the expected precision has not been reached we use the old algorithm + if (!gaussKronrodNonAdaptive.integrationSuccess()) + { + GaussKronrodAdaptive integrator = new GaussKronrodAdaptive(precision_, 100000); + b = Math.Max(a, Math.Min(b, hardUpperLimit_)); + result = integrator.value(integrand.value, a, b); + } + } // if a < b we use the old algorithm + else + { + b = Math.Max(a, Math.Min(b, hardUpperLimit_)); + GaussKronrodAdaptive integrator = new GaussKronrodAdaptive(precision_, 100000); + result = integrator.value(integrand.value, a, b); + } + return result; + } + + public override double swapletPrice() + { + Date today = Settings.evaluationDate(); + if (fixingDate_ <= today) + { + // the fixing is determined + double Rs = coupon_.swapIndex().fixing(fixingDate_); + double price = (gearing_ * Rs + spread_) * (coupon_.accrualPeriod() * discount_); + return price; + } + else + { + double atmCapletPrice = optionletPrice(Option.Type.Call, swapRateValue_); + double atmFloorletPrice = optionletPrice(Option.Type.Put, swapRateValue_); + return gearing_ * (coupon_.accrualPeriod() * discount_ * swapRateValue_ + atmCapletPrice - atmFloorletPrice) + spreadLegValue_; + } + } + + public double resetUpperLimit(double stdDeviationsForUpperLimit) + { + double variance = swaptionVolatility().link.blackVariance(fixingDate_, swapTenor_, swapRateValue_); + return swapRateValue_ * Math.Exp(stdDeviationsForUpperLimit * Math.Sqrt(variance)); + } + + public double refineIntegration(double integralValue, ConundrumIntegrand integrand) + { + double percDiff = 1000.0; + while (Math.Abs(percDiff) < refiningIntegrationTolerance_) + { + stdDeviationsForUpperLimit_ += 1.0; + double lowerLimit = upperLimit_; + upperLimit_ = resetUpperLimit(stdDeviationsForUpperLimit_); + double diff = integrate(lowerLimit, upperLimit_, integrand); + percDiff = diff / integralValue; + integralValue += diff; + } + return integralValue; + } + + #region Nested classes + public class VariableChange + { + private double a_, width_; + private Func f_; + private int k_; + + public VariableChange(Func f, double a, double b, int k) + { + a_ = a; + width_ = b - a; + f_ = f; + k_ = k; + } + + public double value(double x) + { + double newVar; + double temp = width_; + for (int i = 1; i < k_; ++i) + { + temp *= x; + } + newVar = a_ + x * temp; + return f_(newVar) * k_ * temp; + } + } + + public class Spy + { + Func f_; + private List abscissas = new List(); + private List functionValues = new List(); + + public Spy(Func f) + { + f_ = f; + } + public double value(double x) + { + abscissas.Add(x); + double value = f_(x); + functionValues.Add(value); + return value; + } + } + + //===========================================================================// + // ConundrumIntegrand // + //===========================================================================// + public class ConundrumIntegrand : IValue + { + public ConundrumIntegrand(VanillaOptionPricer o, YieldTermStructure curve, GFunction gFunction, Date fixingDate, Date paymentDate, double annuity, double forwardValue, double strike, Option.Type optionType) + { + vanillaOptionPricer_ = o; + forwardValue_ = forwardValue; + annuity_ = annuity; + fixingDate_ = fixingDate; + paymentDate_ = paymentDate; + strike_ = strike; + optionType_ = optionType; + gFunction_ = gFunction; + } + + public double value(double x) + { + double option = vanillaOptionPricer_.value(x, optionType_, annuity_); + return option * secondDerivativeOfF(x); + } + + protected double functionF(double x) + { + double Gx = gFunction_.value(x); + double GR = gFunction_.value(forwardValue_); + return (x - strike_) * (Gx / GR - 1.0); + } + + public double firstDerivativeOfF(double x) + { + double Gx = gFunction_.value(x); + double GR = gFunction_.value(forwardValue_); + double G1 = gFunction_.firstDerivative(x); + return (Gx / GR - 1.0) + G1 / GR * (x - strike_); + } + + public double secondDerivativeOfF(double x) + { + double GR = gFunction_.value(forwardValue_); + double G1 = gFunction_.firstDerivative(x); + double G2 = gFunction_.secondDerivative(x); + return 2.0 * G1 / GR + (x - strike_) * G2 / GR; + } + + protected double strike() { return strike_; } + protected double annuity() { return annuity_; } + protected Date fixingDate() { return fixingDate_; } + protected void setStrike(double strike) { strike_ = strike; } + + protected VanillaOptionPricer vanillaOptionPricer_; + protected double forwardValue_; + protected double annuity_; + protected Date fixingDate_; + protected Date paymentDate_; + protected double strike_; + protected Option.Type optionType_; + protected GFunction gFunction_; + } + #endregion + } + + //===========================================================================// + // AnalyticHaganPricer // + //===========================================================================// + public class AnalyticHaganPricer : HaganPricer + { + public AnalyticHaganPricer(Handle swaptionVol, GFunctionFactory.YieldCurveModel modelOfYieldCurve, Handle meanReversion) + : base(swaptionVol, modelOfYieldCurve, meanReversion) + { + } + + //Hagan, 3.5b, 3.5c + protected override double optionletPrice(Option.Type optionType, double strike) + { + double variance = swaptionVolatility().link.blackVariance(fixingDate_, swapTenor_, swapRateValue_); + double firstDerivativeOfGAtForwardValue = gFunction_.firstDerivative(swapRateValue_); + double price = 0; + + double CK = vanillaOptionPricer_.value(strike, optionType, annuity_); + price += (discount_ / annuity_) * CK; + double sqrtSigma2T = Math.Sqrt(variance); + double lnRoverK = Math.Log(swapRateValue_ / strike); + double d32 = (lnRoverK + 1.5 * variance) / sqrtSigma2T; + double d12 = (lnRoverK + .5 * variance) / sqrtSigma2T; + double dminus12 = (lnRoverK - .5 * variance) / sqrtSigma2T; + + CumulativeNormalDistribution cumulativeOfNormal = new CumulativeNormalDistribution(); + double N32 = cumulativeOfNormal.value(((int)optionType) * d32); + double N12 = cumulativeOfNormal.value(((int)optionType) * d12); + double Nminus12 = cumulativeOfNormal.value(((int)optionType) * dminus12); + + price += ((int)optionType) * firstDerivativeOfGAtForwardValue * annuity_ * swapRateValue_ * (swapRateValue_ * Math.Exp(variance) * N32 - (swapRateValue_ + strike) * N12 + strike * Nminus12); + price *= coupon_.accrualPeriod(); + return price; + } + + //Hagan 3.4c + public override double swapletPrice() + { + Date today = Settings.evaluationDate(); + if (fixingDate_ <= today) + { + // the fixing is determined + double Rs = coupon_.swapIndex().fixing(fixingDate_); + double price = (gearing_ * Rs + spread_) * (coupon_.accrualPeriod() * discount_); + return price; + } + else + { double variance = swaptionVolatility().link.blackVariance(fixingDate_, swapTenor_, swapRateValue_); double firstDerivativeOfGAtForwardValue = gFunction_.firstDerivative(swapRateValue_); double price = 0; - - double CK = vanillaOptionPricer_.value(strike, optionType, annuity_); - price += (discount_ / annuity_) * CK; - double sqrtSigma2T = Math.Sqrt(variance); - double lnRoverK = Math.Log(swapRateValue_ / strike); - double d32 = (lnRoverK + 1.5 * variance) / sqrtSigma2T; - double d12 = (lnRoverK + .5 * variance) / sqrtSigma2T; - double dminus12 = (lnRoverK - .5 * variance) / sqrtSigma2T; - - CumulativeNormalDistribution cumulativeOfNormal = new CumulativeNormalDistribution(); - double N32 = cumulativeOfNormal.value(((int)optionType) * d32); - double N12 = cumulativeOfNormal.value(((int)optionType) * d12); - double Nminus12 = cumulativeOfNormal.value(((int)optionType) * dminus12); - - price += ((int)optionType) * firstDerivativeOfGAtForwardValue * annuity_ * swapRateValue_ * (swapRateValue_ * Math.Exp(variance) * N32 - (swapRateValue_ + strike) * N12 + strike * Nminus12); - price *= coupon_.accrualPeriod(); - return price; - } - - //Hagan 3.4c - public override double swapletPrice() { - Date today = Settings.evaluationDate(); - if (fixingDate_ <= today) { - // the fixing is determined - double Rs = coupon_.swapIndex().fixing(fixingDate_); - double price = (gearing_ * Rs + spread_) * (coupon_.accrualPeriod() * discount_); - return price; - } else { - double variance = swaptionVolatility().link.blackVariance(fixingDate_, swapTenor_, swapRateValue_); - double firstDerivativeOfGAtForwardValue = gFunction_.firstDerivative(swapRateValue_); - double price = 0; - price += discount_ * swapRateValue_; - price += firstDerivativeOfGAtForwardValue * annuity_ * swapRateValue_ * swapRateValue_ * (Math.Exp(variance) - 1.0); - return gearing_ * price * coupon_.accrualPeriod() + spreadLegValue_; - } - } - } + price += discount_ * swapRateValue_; + price += firstDerivativeOfGAtForwardValue * annuity_ * swapRateValue_ * swapRateValue_ * (Math.Exp(variance) - 1.0); + return gearing_ * price * coupon_.accrualPeriod() + spreadLegValue_; + } + } + } } diff --git a/src/QLNet/Cashflows/Coupon.cs b/src/QLNet/Cashflows/Coupon.cs index 6a0c78e8e..324ce89f1 100644 --- a/src/QLNet/Cashflows/Coupon.cs +++ b/src/QLNet/Cashflows/Coupon.cs @@ -1,40 +1,40 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet +namespace QLNet { //! %coupon accruing over a fixed period //! This class implements part of the CashFlow interface but it is // still abstract and provides derived classes with methods for accrual period calculations. - public abstract class Coupon : CashFlow + public abstract class Coupon : CashFlow { // Constructors protected Coupon() { } // default constructor // coupon does not adjust the payment date which must already be a business day - protected Coupon( Date paymentDate, - double nominal, - Date accrualStartDate, - Date accrualEndDate, - Date refPeriodStart = null, - Date refPeriodEnd = null, - Date exCouponDate = null ) + protected Coupon(Date paymentDate, + double nominal, + Date accrualStartDate, + Date accrualEndDate, + Date refPeriodStart = null, + Date refPeriodEnd = null, + Date exCouponDate = null) { paymentDate_ = paymentDate; nominal_ = nominal; @@ -45,8 +45,10 @@ protected Coupon( Date paymentDate, exCouponDate_ = exCouponDate; accrualPeriod_ = null; - if ( refPeriodStart_ == null ) refPeriodStart_ = accrualStartDate_; - if ( refPeriodEnd_ == null ) refPeriodEnd_ = accrualEndDate_; + if (refPeriodStart_ == null) + refPeriodStart_ = accrualStartDate_; + if (refPeriodEnd_ == null) + refPeriodEnd_ = accrualEndDate_; } // Event interface @@ -68,42 +70,42 @@ protected Coupon( Date paymentDate, //! accrual period as fraction of year public double accrualPeriod() { - if ( accrualPeriod_ == null ) - accrualPeriod_ = dayCounter().yearFraction( accrualStartDate_, - accrualEndDate_, refPeriodStart_, refPeriodEnd_ ); + if (accrualPeriod_ == null) + accrualPeriod_ = dayCounter().yearFraction(accrualStartDate_, + accrualEndDate_, refPeriodStart_, refPeriodEnd_); return accrualPeriod_.Value; } //! accrual period in days public int accrualDays() { - return dayCounter().dayCount( accrualStartDate_, accrualEndDate_ ); + return dayCounter().dayCount(accrualStartDate_, accrualEndDate_); } //! accrued rate public abstract double rate(); //! day counter for accrual calculation public abstract DayCounter dayCounter(); - //! accrued period as fraction of year at the given date - public double accruedPeriod( Date d ) + //! accrued period as fraction of year at the given date + public double accruedPeriod(Date d) { - if ( d <= accrualStartDate_ || d > paymentDate_ ) + if (d <= accrualStartDate_ || d > paymentDate_) return 0.0; else - return dayCounter().yearFraction( accrualStartDate_, - Date.Min( d, accrualEndDate_ ), - refPeriodStart_, - refPeriodEnd_ ); + return dayCounter().yearFraction(accrualStartDate_, + Date.Min(d, accrualEndDate_), + refPeriodStart_, + refPeriodEnd_); } //! accrued days at the given date - public int accruedDays( Date d ) + public int accruedDays(Date d) { - if ( d <= accrualStartDate_ || d > paymentDate_ ) + if (d <= accrualStartDate_ || d > paymentDate_) return 0; else - return dayCounter().dayCount( accrualStartDate_, Date.Min( d, accrualEndDate_ ) ); + return dayCounter().dayCount(accrualStartDate_, Date.Min(d, accrualEndDate_)); } //! accrued amount at the given date - public abstract double accruedAmount( Date d ); + public abstract double accruedAmount(Date d); protected double nominal_; protected Date paymentDate_; diff --git a/src/QLNet/Cashflows/CouponPricer.cs b/src/QLNet/Cashflows/CouponPricer.cs index f4146ce08..9a584f92e 100644 --- a/src/QLNet/Cashflows/CouponPricer.cs +++ b/src/QLNet/Cashflows/CouponPricer.cs @@ -1,19 +1,19 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -31,22 +31,28 @@ public abstract class FloatingRateCouponPricer : IObservable, IObserver // required interface public abstract double swapletPrice(); public abstract double swapletRate(); - public abstract double capletPrice( double effectiveCap ); - public abstract double capletRate( double effectiveCap ); - public abstract double floorletPrice( double effectiveFloor ); - public abstract double floorletRate( double effectiveFloor ); - public abstract void initialize( FloatingRateCoupon coupon ); + public abstract double capletPrice(double effectiveCap); + public abstract double capletRate(double effectiveCap); + public abstract double floorletPrice(double effectiveFloor); + public abstract double floorletRate(double effectiveFloor); + public abstract void initialize(FloatingRateCoupon coupon); #region Observer & observable private readonly WeakEventSource eventSource = new WeakEventSource(); public event Callback notifyObserversEvent { - add { eventSource.Subscribe( value ); } - remove { eventSource.Unsubscribe( value ); } + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } } - public void registerWith( Callback handler ) { notifyObserversEvent += handler; } - public void unregisterWith( Callback handler ) { notifyObserversEvent -= handler; } + public void registerWith(Callback handler) { notifyObserversEvent += handler; } + public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } protected void notifyObservers() { eventSource.Raise(); @@ -60,11 +66,11 @@ protected void notifyObservers() //! base pricer for capped/floored Ibor coupons public abstract class IborCouponPricer : FloatingRateCouponPricer { - protected IborCouponPricer( Handle v = null ) + protected IborCouponPricer(Handle v = null) { capletVol_ = v ?? new Handle(); - if ( !capletVol_.empty() ) - capletVol_.registerWith( update ); + if (!capletVol_.empty()) + capletVol_.registerWith(update); } public Handle capletVolatility() @@ -72,12 +78,12 @@ public Handle capletVolatility() return capletVol_; } - public void setCapletVolatility( Handle v = null) + public void setCapletVolatility(Handle v = null) { - capletVol_.unregisterWith( update ); + capletVol_.unregisterWith(update); capletVol_ = v ?? new Handle(); - if ( !capletVol_.empty() ) - capletVol_.registerWith( update ); + if (!capletVol_.empty()) + capletVol_.registerWith(update); update(); } @@ -93,50 +99,50 @@ The bivariate lognormal adjustment implementation is still considered experimental */ public class BlackIborCouponPricer : IborCouponPricer { - public enum TimingAdjustment { Black76, BivariateLognormal }; - public BlackIborCouponPricer( Handle v = null, - TimingAdjustment timingAdjustment = TimingAdjustment.Black76, - Handle correlation = null) - : base( v ) + public enum TimingAdjustment { Black76, BivariateLognormal } + public BlackIborCouponPricer(Handle v = null, + TimingAdjustment timingAdjustment = TimingAdjustment.Black76, + Handle correlation = null) + : base(v) { timingAdjustment_ = timingAdjustment; correlation_ = correlation ?? new Handle(new SimpleQuote(1.0)); - Utils.QL_REQUIRE( timingAdjustment_ == TimingAdjustment.Black76 || - timingAdjustment_ == TimingAdjustment.BivariateLognormal,()=> - "unknown timing adjustment (code " + timingAdjustment_ + ")" ); + Utils.QL_REQUIRE(timingAdjustment_ == TimingAdjustment.Black76 || + timingAdjustment_ == TimingAdjustment.BivariateLognormal, () => + "unknown timing adjustment (code " + timingAdjustment_ + ")"); correlation_.registerWith(update); } - public override void initialize( FloatingRateCoupon coupon ) + public override void initialize(FloatingRateCoupon coupon) { gearing_ = coupon.gearing(); spread_ = coupon.spread(); accrualPeriod_ = coupon.accrualPeriod(); - Utils.QL_REQUIRE(accrualPeriod_.IsNotEqual(0.0),()=> "null accrual period"); + Utils.QL_REQUIRE(accrualPeriod_.IsNotEqual(0.0), () => "null accrual period"); index_ = coupon.index() as IborIndex; - if (index_ == null) + if (index_ == null) { // check if the coupon was right IborCoupon c = coupon as IborCoupon; - Utils.QL_REQUIRE(c!=null,()=> "IborCoupon required"); + Utils.QL_REQUIRE(c != null, () => "IborCoupon required"); // coupon was right, index is not Utils.QL_FAIL("IborIndex required"); } Handle rateCurve = index_.forwardingTermStructure(); Date paymentDate = coupon.date(); - if ( paymentDate > rateCurve.link.referenceDate() ) - discount_ = rateCurve.link.discount( paymentDate ); + if (paymentDate > rateCurve.link.referenceDate()) + discount_ = rateCurve.link.discount(paymentDate); else discount_ = 1.0; spreadLegValue_ = spread_ * accrualPeriod_ * discount_; coupon_ = coupon ; - } + } public override double swapletPrice() { // past or future fixing is managed in InterestRateIndex::fixing() @@ -146,36 +152,36 @@ public override double swapletPrice() } public override double swapletRate() { - return swapletPrice() / ( accrualPeriod_ * discount_ ); + return swapletPrice() / (accrualPeriod_ * discount_); } - public override double capletPrice( double effectiveCap ) + public override double capletPrice(double effectiveCap) { - double capletPrice = optionletPrice( Option.Type.Call, effectiveCap ); + double capletPrice = optionletPrice(Option.Type.Call, effectiveCap); return gearing_ * capletPrice; } - public override double capletRate( double effectiveCap ) + public override double capletRate(double effectiveCap) { - return capletPrice( effectiveCap ) / ( accrualPeriod_ * discount_ ); + return capletPrice(effectiveCap) / (accrualPeriod_ * discount_); } - public override double floorletPrice( double effectiveFloor ) + public override double floorletPrice(double effectiveFloor) { - double floorletPrice = optionletPrice( Option.Type.Put, effectiveFloor ); + double floorletPrice = optionletPrice(Option.Type.Put, effectiveFloor); return gearing_ * floorletPrice; } - public override double floorletRate( double effectiveFloor ) + public override double floorletRate(double effectiveFloor) { - return floorletPrice( effectiveFloor ) / ( accrualPeriod_ * discount_ ); + return floorletPrice(effectiveFloor) / (accrualPeriod_ * discount_); } - protected double optionletPrice( Option.Type optionType, double effStrike ) + protected double optionletPrice(Option.Type optionType, double effStrike) { Date fixingDate = coupon_.fixingDate(); - if ( fixingDate <= Settings.evaluationDate() ) + if (fixingDate <= Settings.evaluationDate()) { // the amount is determined double a; double b; - if ( optionType == Option.Type.Call ) + if (optionType == Option.Type.Call) { a = coupon_.indexFixing(); b = effStrike; @@ -185,24 +191,24 @@ protected double optionletPrice( Option.Type optionType, double effStrike ) a = effStrike; b = coupon_.indexFixing(); } - return Math.Max( a - b, 0.0 ) * accrualPeriod_ * discount_; + return Math.Max(a - b, 0.0) * accrualPeriod_ * discount_; } else { // not yet determined, use Black model - Utils.QL_REQUIRE( !capletVolatility().empty(), () => "missing optionlet volatility" ); + Utils.QL_REQUIRE(!capletVolatility().empty(), () => "missing optionlet volatility"); - double stdDev = Math.Sqrt( capletVolatility().link.blackVariance( fixingDate, effStrike ) ); + double stdDev = Math.Sqrt(capletVolatility().link.blackVariance(fixingDate, effStrike)); double shift = capletVolatility().link.displacement(); bool shiftedLn = capletVolatility().link.volatilityType() == VolatilityType.ShiftedLognormal; double fixing = - shiftedLn - ? Utils.blackFormula(optionType, effStrike, adjustedFixing(),stdDev, 1.0, shift) - : Utils.bachelierBlackFormula(optionType, effStrike,adjustedFixing(), stdDev, 1.0); + shiftedLn + ? Utils.blackFormula(optionType, effStrike, adjustedFixing(), stdDev, 1.0, shift) + : Utils.bachelierBlackFormula(optionType, effStrike, adjustedFixing(), stdDev, 1.0); return fixing * accrualPeriod_ * discount_; } } - protected virtual double adjustedFixing( double? fixing = null) + protected virtual double adjustedFixing(double? fixing = null) { if (fixing == null) fixing = coupon_.indexFixing(); @@ -210,7 +216,7 @@ protected virtual double adjustedFixing( double? fixing = null) if (!coupon_.isInArrears() && timingAdjustment_ == TimingAdjustment.Black76) return fixing.Value; - Utils.QL_REQUIRE(!capletVolatility().empty(),()=> "missing optionlet volatility"); + Utils.QL_REQUIRE(!capletVolatility().empty(), () => "missing optionlet volatility"); Date d1 = coupon_.fixingDate(); Date referenceDate = capletVolatility().link.referenceDate(); if (d1 <= referenceDate) @@ -224,12 +230,12 @@ protected virtual double adjustedFixing( double? fixing = null) bool shiftedLn = capletVolatility().link.volatilityType() == VolatilityType.ShiftedLognormal; double adjustment = shiftedLn - ? (fixing.Value + shift)*(fixing.Value + shift)*variance*tau/(1.0 + fixing.Value*tau) - : variance*tau/(1.0 + fixing.Value*tau); + ? (fixing.Value + shift) * (fixing.Value + shift) * variance * tau / (1.0 + fixing.Value * tau) + : variance * tau / (1.0 + fixing.Value * tau); if (timingAdjustment_ == TimingAdjustment.BivariateLognormal) { - Utils.QL_REQUIRE(!correlation_.empty(),()=> "no correlation given"); + Utils.QL_REQUIRE(!correlation_.empty(), () => "no correlation given"); Date d4 = coupon_.date(); Date d5 = d4 >= d3 ? d3 : d2; double tau2 = index_.dayCounter().yearFraction(d5, d4); @@ -239,12 +245,12 @@ protected virtual double adjustedFixing( double? fixing = null) // Black76 in arrears adjustment if (tau2 > 0.0) { - double fixing2 = (index_.forwardingTermStructure().link.discount(d5)/ + double fixing2 = (index_.forwardingTermStructure().link.discount(d5) / index_.forwardingTermStructure().link.discount(d4) - - 1.0)/ tau2; + 1.0) / tau2; adjustment -= shiftedLn - ? correlation_.link.value()*tau2*variance* (fixing.Value + shift)*(fixing2 + shift)/ (1.0 + fixing2*tau2) - : correlation_.link.value()*tau2*variance/ (1.0 + fixing2*tau2); + ? correlation_.link.value() * tau2 * variance * (fixing.Value + shift) * (fixing2 + shift) / (1.0 + fixing2 * tau2) + : correlation_.link.value() * tau2 * variance / (1.0 + fixing2 * tau2); } } return fixing.Value + adjustment; @@ -257,7 +263,7 @@ protected virtual double adjustedFixing( double? fixing = null) protected double discount_; protected double spreadLegValue_; protected FloatingRateCoupon coupon_; - + private TimingAdjustment timingAdjustment_; private Handle correlation_; @@ -267,19 +273,19 @@ protected virtual double adjustedFixing( double? fixing = null) //! base pricer for vanilla CMS coupons public abstract class CmsCouponPricer : FloatingRateCouponPricer { - protected CmsCouponPricer( Handle v = null ) + protected CmsCouponPricer(Handle v = null) { swaptionVol_ = v ?? new Handle(); - swaptionVol_.registerWith( update ); + swaptionVol_.registerWith(update); } public Handle swaptionVolatility() {return swaptionVol_;} - public void setSwaptionVolatility( Handle v = null) + public void setSwaptionVolatility(Handle v = null) { - swaptionVol_.unregisterWith( update ); + swaptionVol_.unregisterWith(update); swaptionVol_ = v ?? new Handle(); - swaptionVol_.registerWith( update ); + swaptionVol_.registerWith(update); update(); } private Handle swaptionVol_; @@ -287,11 +293,11 @@ public void setSwaptionVolatility( Handle v = null) /*! (CMS) coupon pricer that has a mean reversion parameter which can be used to calibrate to cms market quotes */ - public interface IMeanRevertingPricer - { - double meanReversion() ; - void setMeanReversion(Handle q) ; - } + public interface IMeanRevertingPricer + { + double meanReversion() ; + void setMeanReversion(Handle q) ; + } //===========================================================================// // CouponSelectorToSetPricer // @@ -300,109 +306,109 @@ public interface IMeanRevertingPricer public class PricerSetter : IAcyclicVisitor { private FloatingRateCouponPricer pricer_; - public PricerSetter( FloatingRateCouponPricer pricer ) + public PricerSetter(FloatingRateCouponPricer pricer) { pricer_ = pricer; } - public void visit( object o ) + public void visit(object o) { Type[] types = new Type[] { o.GetType() }; - MethodInfo methodInfo = Utils.GetMethodInfo( this, "visit", types ); - if ( methodInfo != null ) + MethodInfo methodInfo = Utils.GetMethodInfo(this, "visit", types); + if (methodInfo != null) { - methodInfo.Invoke( this, new object[] { o } ); + methodInfo.Invoke(this, new object[] { o }); } } - public void visit( CashFlow c ) + public void visit(CashFlow c) { // nothing to do } - public void visit( Coupon c ) + public void visit(Coupon c) { // nothing to do } - public void visit(FloatingRateCoupon c) + public void visit(FloatingRateCoupon c) { c.setPricer(pricer_); } - public void visit( CappedFlooredCoupon c ) + public void visit(CappedFlooredCoupon c) { - c.setPricer( pricer_ ); + c.setPricer(pricer_); } - public void visit( IborCoupon c ) + public void visit(IborCoupon c) { IborCouponPricer iborCouponPricer = pricer_ as IborCouponPricer; - Utils.QL_REQUIRE( iborCouponPricer!=null,()=> "pricer not compatible with Ibor coupon" ); - c.setPricer( iborCouponPricer ); + Utils.QL_REQUIRE(iborCouponPricer != null, () => "pricer not compatible with Ibor coupon"); + c.setPricer(iborCouponPricer); } - public void visit( DigitalIborCoupon c ) + public void visit(DigitalIborCoupon c) { IborCouponPricer iborCouponPricer = pricer_ as IborCouponPricer; - Utils.QL_REQUIRE( iborCouponPricer!= null,()=> "pricer not compatible with Ibor coupon" ); - c.setPricer( iborCouponPricer ); + Utils.QL_REQUIRE(iborCouponPricer != null, () => "pricer not compatible with Ibor coupon"); + c.setPricer(iborCouponPricer); } - public void visit( CappedFlooredIborCoupon c ) + public void visit(CappedFlooredIborCoupon c) { IborCouponPricer iborCouponPricer = pricer_ as IborCouponPricer; - Utils.QL_REQUIRE( iborCouponPricer != null, () => "pricer not compatible with Ibor coupon" ); - c.setPricer( iborCouponPricer ); + Utils.QL_REQUIRE(iborCouponPricer != null, () => "pricer not compatible with Ibor coupon"); + c.setPricer(iborCouponPricer); } - public void visit( CmsCoupon c ) + public void visit(CmsCoupon c) { CmsCouponPricer cmsCouponPricer = pricer_ as CmsCouponPricer; - Utils.QL_REQUIRE( cmsCouponPricer!=null,()=> "pricer not compatible with CMS coupon" ); - c.setPricer( cmsCouponPricer ); + Utils.QL_REQUIRE(cmsCouponPricer != null, () => "pricer not compatible with CMS coupon"); + c.setPricer(cmsCouponPricer); } - public void visit( CappedFlooredCmsCoupon c ) + public void visit(CappedFlooredCmsCoupon c) { CmsCouponPricer cmsCouponPricer = pricer_ as CmsCouponPricer; - Utils.QL_REQUIRE( cmsCouponPricer != null, () => "pricer not compatible with CMS coupon" ); - c.setPricer( cmsCouponPricer ); + Utils.QL_REQUIRE(cmsCouponPricer != null, () => "pricer not compatible with CMS coupon"); + c.setPricer(cmsCouponPricer); } - public void visit( DigitalCmsCoupon c ) + public void visit(DigitalCmsCoupon c) { CmsCouponPricer cmsCouponPricer = pricer_ as CmsCouponPricer; - Utils.QL_REQUIRE( cmsCouponPricer != null, () => "pricer not compatible with CMS coupon" ); - c.setPricer( cmsCouponPricer ); + Utils.QL_REQUIRE(cmsCouponPricer != null, () => "pricer not compatible with CMS coupon"); + c.setPricer(cmsCouponPricer); } public void visit(RangeAccrualFloatersCoupon c) { RangeAccrualPricer rangeAccrualPricer = pricer_ as RangeAccrualPricer; - Utils.QL_REQUIRE(rangeAccrualPricer!=null,()=> "pricer not compatible with range-accrual coupon"); + Utils.QL_REQUIRE(rangeAccrualPricer != null, () => "pricer not compatible with range-accrual coupon"); c.setPricer(rangeAccrualPricer); } } partial class Utils { - public static void setCouponPricer( List leg, FloatingRateCouponPricer pricer ) + public static void setCouponPricer(List leg, FloatingRateCouponPricer pricer) { - PricerSetter setter = new PricerSetter( pricer ); - foreach ( CashFlow cf in leg ) + PricerSetter setter = new PricerSetter(pricer); + foreach (CashFlow cf in leg) { - cf.accept( setter ); + cf.accept(setter); } } - public static void setCouponPricers( List leg, List pricers ) + public static void setCouponPricers(List leg, List pricers) { int nCashFlows = leg.Count; - Utils.QL_REQUIRE(nCashFlows>0,()=> "no cashflows"); + Utils.QL_REQUIRE(nCashFlows > 0, () => "no cashflows"); int nPricers = pricers.Count; - Utils.QL_REQUIRE(nCashFlows >= nPricers,()=> - "mismatch between leg size (" + nCashFlows + - ") and number of pricers (" + nPricers + ")"); + Utils.QL_REQUIRE(nCashFlows >= nPricers, () => + "mismatch between leg size (" + nCashFlows + + ") and number of pricers (" + nPricers + ")"); for (int i = 0; i < nCashFlows; ++i) { - PricerSetter setter = new PricerSetter(i < nPricers ? pricers[i] : pricers[nPricers - 1]); - leg[i].accept(setter); + PricerSetter setter = new PricerSetter(i < nPricers ? pricers[i] : pricers[nPricers - 1]); + leg[i].accept(setter); } } } diff --git a/src/QLNet/Cashflows/DigitalCmsCoupon.cs b/src/QLNet/Cashflows/DigitalCmsCoupon.cs index 77bc0a312..45ddfe8ed 100644 --- a/src/QLNet/Cashflows/DigitalCmsCoupon.cs +++ b/src/QLNet/Cashflows/DigitalCmsCoupon.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,17 +29,17 @@ public class DigitalCmsCoupon : DigitalCoupon // need by CashFlowVectors public DigitalCmsCoupon() { } - public DigitalCmsCoupon(CmsCoupon underlying, + public DigitalCmsCoupon(CmsCoupon underlying, double? callStrike = null, - Position.Type callPosition = Position.Type.Long, - bool isCallATMIncluded = false, - double? callDigitalPayoff = null, + Position.Type callPosition = Position.Type.Long, + bool isCallATMIncluded = false, + double? callDigitalPayoff = null, double? putStrike = null, - Position.Type putPosition = Position.Type.Long, - bool isPutATMIncluded = false, - double? putDigitalPayoff = null, - DigitalReplication replication = null ) - : base(underlying, callStrike, callPosition, isCallATMIncluded, callDigitalPayoff, putStrike, putPosition, isPutATMIncluded, putDigitalPayoff, replication) + Position.Type putPosition = Position.Type.Long, + bool isPutATMIncluded = false, + double? putDigitalPayoff = null, + DigitalReplication replication = null) + : base(underlying, callStrike, callPosition, isCallATMIncluded, callDigitalPayoff, putStrike, putPosition, isPutATMIncluded, putDigitalPayoff, replication) { } diff --git a/src/QLNet/Cashflows/DigitalCoupon.cs b/src/QLNet/Cashflows/DigitalCoupon.cs index 55aa5cccd..effce9600 100644 --- a/src/QLNet/Cashflows/DigitalCoupon.cs +++ b/src/QLNet/Cashflows/DigitalCoupon.cs @@ -2,18 +2,18 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -38,7 +38,7 @@ namespace QLNet // where csi=+1 or csi=-1. // The evaluation of the coupon is made using the call/put spread // replication method. - // + // // ! \ingroup instruments // // \test @@ -64,7 +64,7 @@ namespace QLNet // of the call-put parity relation. // - the correctness of the returned value is tested by the relationship // between prices in case of different replication types. - // + // public class DigitalCoupon : FloatingRateCoupon { // need by CashFlowVectors @@ -72,19 +72,20 @@ public DigitalCoupon() { } //! Constructors //! general constructor - public DigitalCoupon(FloatingRateCoupon underlying, + public DigitalCoupon(FloatingRateCoupon underlying, double? callStrike = null, - Position.Type callPosition = Position.Type.Long, - bool isCallATMIncluded = false, - double? callDigitalPayoff = null, + Position.Type callPosition = Position.Type.Long, + bool isCallATMIncluded = false, + double? callDigitalPayoff = null, double? putStrike = null, - Position.Type putPosition = Position.Type.Long, - bool isPutATMIncluded = false, - double? putDigitalPayoff = null, + Position.Type putPosition = Position.Type.Long, + bool isPutATMIncluded = false, + double? putDigitalPayoff = null, DigitalReplication replication = null) - : base(underlying.date(), underlying.nominal(), underlying.accrualStartDate(), underlying.accrualEndDate(), underlying.fixingDays, underlying.index(), underlying.gearing(), underlying.spread(), underlying.referencePeriodStart, underlying.referencePeriodEnd, underlying.dayCounter(), underlying.isInArrears()) + : base(underlying.date(), underlying.nominal(), underlying.accrualStartDate(), underlying.accrualEndDate(), underlying.fixingDays, underlying.index(), underlying.gearing(), underlying.spread(), underlying.referencePeriodStart, underlying.referencePeriodEnd, underlying.dayCounter(), underlying.isInArrears()) { - if (replication == null) replication = new DigitalReplication(); + if (replication == null) + replication = new DigitalReplication(); underlying_ = underlying; callCsi_ = 0.0; @@ -102,21 +103,21 @@ public DigitalCoupon(FloatingRateCoupon underlying, replicationType_ = replication.replicationType(); - Utils.QL_REQUIRE(replication.gap() > 0.0,()=> "Non positive epsilon not allowed"); + Utils.QL_REQUIRE(replication.gap() > 0.0, () => "Non positive epsilon not allowed"); if (putStrike == null) - Utils.QL_REQUIRE(putDigitalPayoff == null,()=> "Put Cash rate non allowed if put strike is null"); + Utils.QL_REQUIRE(putDigitalPayoff == null, () => "Put Cash rate non allowed if put strike is null"); if (callStrike == null) - Utils.QL_REQUIRE(callDigitalPayoff == null,()=> "Call Cash rate non allowed if call strike is null"); + Utils.QL_REQUIRE(callDigitalPayoff == null, () => "Call Cash rate non allowed if call strike is null"); if (callStrike != null) { - Utils.QL_REQUIRE(callStrike >= 0.0,()=> "negative call strike not allowed"); + Utils.QL_REQUIRE(callStrike >= 0.0, () => "negative call strike not allowed"); hasCallStrike_ = true; callStrike_ = callStrike.GetValueOrDefault(); - Utils.QL_REQUIRE(callStrike_ >= replication.gap() / 2.0,()=> "call strike < eps/2"); + Utils.QL_REQUIRE(callStrike_ >= replication.gap() / 2.0, () => "call strike < eps/2"); switch (callPosition) { @@ -138,7 +139,7 @@ public DigitalCoupon(FloatingRateCoupon underlying, } if (putStrike != null) { - Utils.QL_REQUIRE(putStrike >= 0.0,()=> "negative put strike not allowed"); + Utils.QL_REQUIRE(putStrike >= 0.0, () => "negative put strike not allowed"); hasPutStrike_ = true; putStrike_ = putStrike.GetValueOrDefault(); switch (putPosition) @@ -249,7 +250,7 @@ public DigitalCoupon(FloatingRateCoupon underlying, public override double rate() { - Utils.QL_REQUIRE(underlying_.pricer()!=null,()=> "pricer not set"); + Utils.QL_REQUIRE(underlying_.pricer() != null, () => "pricer not set"); Date fixingDate = underlying_.fixingDate(); Date today = Settings.evaluationDate(); @@ -263,7 +264,7 @@ public override double rate() if (fixingDate == today) { // might have been fixed - double? pastFixing = IndexManager.instance().getHistory((underlying_.index()).name()).value()[fixingDate]; + double? pastFixing = IndexManager.instance().getHistory((underlying_.index()).name())[fixingDate]; if (pastFixing != null) { return underlyingRate + callCsi_ * callPayoff() + putCsi_ * putPayoff(); @@ -332,7 +333,7 @@ public FloatingRateCoupon underlying() } // ! Returns the call option rate // (multiplied by: nominal*accrualperiod*discount is the NPV of the option) - // + // public double callOptionRate() { @@ -357,7 +358,7 @@ public double callOptionRate() } // ! Returns the put option rate // (multiplied by: nominal*accrualperiod*discount is the NPV of the option) - // + // public double putOptionRate() { diff --git a/src/QLNet/Cashflows/DigitalIborCoupon.cs b/src/QLNet/Cashflows/DigitalIborCoupon.cs index 30f885c51..e1d73d640 100644 --- a/src/QLNet/Cashflows/DigitalIborCoupon.cs +++ b/src/QLNet/Cashflows/DigitalIborCoupon.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,17 +29,17 @@ public class DigitalIborCoupon : DigitalCoupon // need by CashFlowVectors public DigitalIborCoupon() { } - public DigitalIborCoupon(IborCoupon underlying, - double? callStrike = null, - Position.Type callPosition = Position.Type.Long, - bool isCallATMIncluded = false, - double? callDigitalPayoff = null, - double? putStrike = null, - Position.Type putPosition = Position.Type.Long, - bool isPutATMIncluded = false, - double? putDigitalPayoff = null, + public DigitalIborCoupon(IborCoupon underlying, + double? callStrike = null, + Position.Type callPosition = Position.Type.Long, + bool isCallATMIncluded = false, + double? callDigitalPayoff = null, + double? putStrike = null, + Position.Type putPosition = Position.Type.Long, + bool isPutATMIncluded = false, + double? putDigitalPayoff = null, DigitalReplication replication = null) - : base(underlying, callStrike, callPosition, isCallATMIncluded, callDigitalPayoff, putStrike, putPosition, isPutATMIncluded, putDigitalPayoff, replication) + : base(underlying, callStrike, callPosition, isCallATMIncluded, callDigitalPayoff, putStrike, putPosition, isPutATMIncluded, putDigitalPayoff, replication) { } diff --git a/src/QLNet/Cashflows/Dividend.cs b/src/QLNet/Cashflows/Dividend.cs index 537cb81a3..69dd343b7 100644 --- a/src/QLNet/Cashflows/Dividend.cs +++ b/src/QLNet/Cashflows/Dividend.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -78,7 +78,7 @@ public FractionalDividend(double rate, double nominal, Date date) // Dividend interface public override double amount() { - Utils.QL_REQUIRE(nominal_ != null,()=> "no nominal given"); + Utils.QL_REQUIRE(nominal_ != null, () => "no nominal given"); return rate_ * nominal_.GetValueOrDefault(); } @@ -93,7 +93,7 @@ public static partial class Utils //! helper function building a sequence of fixed dividends public static DividendSchedule DividendVector(List dividendDates, List dividends) { - QL_REQUIRE(dividendDates.Count == dividends.Count,()=>"size mismatch between dividend dates and amounts"); + QL_REQUIRE(dividendDates.Count == dividends.Count, () => "size mismatch between dividend dates and amounts"); DividendSchedule items = new DividendSchedule(); for (int i = 0; i < dividendDates.Count; i++) diff --git a/src/QLNet/Cashflows/FixedRateCoupon.cs b/src/QLNet/Cashflows/FixedRateCoupon.cs index c3de3cd87..92b2b8b5e 100644 --- a/src/QLNet/Cashflows/FixedRateCoupon.cs +++ b/src/QLNet/Cashflows/FixedRateCoupon.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,53 +21,53 @@ under the terms of the QLNet license. You should have received a using System.Collections.Generic; using System.Linq; -namespace QLNet +namespace QLNet { //! %Coupon paying a fixed interest rate - public class FixedRateCoupon : Coupon + public class FixedRateCoupon : Coupon { // constructors public FixedRateCoupon(Date paymentDate, double nominal, double rate, DayCounter dayCounter, - Date accrualStartDate, Date accrualEndDate, - Date refPeriodStart = null, Date refPeriodEnd = null,Date exCouponDate = null) - : base( paymentDate, nominal, accrualStartDate, accrualEndDate, refPeriodStart, refPeriodEnd, exCouponDate ) + Date accrualStartDate, Date accrualEndDate, + Date refPeriodStart = null, Date refPeriodEnd = null, Date exCouponDate = null) + : base(paymentDate, nominal, accrualStartDate, accrualEndDate, refPeriodStart, refPeriodEnd, exCouponDate) { - rate_ = new InterestRate(rate, dayCounter, Compounding.Simple,Frequency.Annual); + rate_ = new InterestRate(rate, dayCounter, Compounding.Simple, Frequency.Annual); } - public FixedRateCoupon(Date paymentDate, double nominal, InterestRate interestRate, + public FixedRateCoupon(Date paymentDate, double nominal, InterestRate interestRate, Date accrualStartDate, Date accrualEndDate, - Date refPeriodStart = null, Date refPeriodEnd = null, Date exCouponDate = null, double? amount = null) - : base( paymentDate, nominal, accrualStartDate, accrualEndDate, refPeriodStart, refPeriodEnd, exCouponDate ) + Date refPeriodStart = null, Date refPeriodEnd = null, Date exCouponDate = null, double? amount = null) + : base(paymentDate, nominal, accrualStartDate, accrualEndDate, refPeriodStart, refPeriodEnd, exCouponDate) { amount_ = amount; rate_ = interestRate; } //! CashFlow interface - public override double amount() + public override double amount() { - if ( amount_ != null ) + if (amount_ != null) return amount_.Value; - return nominal()*(rate_.compoundFactor(accrualStartDate_,accrualEndDate_, refPeriodStart_, refPeriodEnd_) - 1.0); + return nominal() * (rate_.compoundFactor(accrualStartDate_, accrualEndDate_, refPeriodStart_, refPeriodEnd_) - 1.0); } //! Coupon interface public override double rate() { return rate_.rate(); } public InterestRate interestRate() { return rate_; } public override DayCounter dayCounter() { return rate_.dayCounter(); } - public override double accruedAmount(Date d) + public override double accruedAmount(Date d) { if (d <= accrualStartDate_ || d > paymentDate_) return 0; - else if (tradingExCoupon(d)) - { - return -nominal()*(rate_.compoundFactor(d, - accrualEndDate_, - refPeriodStart_, - refPeriodEnd_) - 1.0); - } + else if (tradingExCoupon(d)) + { + return -nominal() * (rate_.compoundFactor(d, + accrualEndDate_, + refPeriodStart_, + refPeriodEnd_) - 1.0); + } else return nominal() * (rate_.compoundFactor(accrualStartDate_, Date.Min(d, accrualEndDate_), refPeriodStart_, refPeriodEnd_) - 1.0); @@ -79,19 +79,19 @@ public override double accruedAmount(Date d) } //! helper class building a sequence of fixed rate coupons - public class FixedRateLeg : RateLegBase + public class FixedRateLeg : RateLegBase { // properties private List couponRates_ = new List(); - private DayCounter firstPeriodDC_ , lastPeriodDC_ ; + private DayCounter firstPeriodDC_, lastPeriodDC_ ; private Calendar calendar_; - private Period exCouponPeriod_; + private Period exCouponPeriod_; private Calendar exCouponCalendar_; private BusinessDayConvention exCouponAdjustment_; private bool exCouponEndOfMonth_; // constructor - public FixedRateLeg(Schedule schedule) + public FixedRateLeg(Schedule schedule) { schedule_ = schedule; calendar_ = schedule.calendar(); @@ -99,17 +99,17 @@ public FixedRateLeg(Schedule schedule) } // other initializers - public FixedRateLeg withCouponRates(double couponRate,DayCounter paymentDayCounter) + public FixedRateLeg withCouponRates(double couponRate, DayCounter paymentDayCounter) { - return withCouponRates(couponRate,paymentDayCounter,Compounding.Simple,Frequency.Annual); + return withCouponRates(couponRate, paymentDayCounter, Compounding.Simple, Frequency.Annual); } - public FixedRateLeg withCouponRates(double couponRate,DayCounter paymentDayCounter,Compounding comp) + public FixedRateLeg withCouponRates(double couponRate, DayCounter paymentDayCounter, Compounding comp) { - return withCouponRates(couponRate,paymentDayCounter,comp,Frequency.Annual); + return withCouponRates(couponRate, paymentDayCounter, comp, Frequency.Annual); } - public FixedRateLeg withCouponRates(double couponRate,DayCounter paymentDayCounter, - Compounding comp ,Frequency freq) + public FixedRateLeg withCouponRates(double couponRate, DayCounter paymentDayCounter, + Compounding comp, Frequency freq) { couponRates_.Clear(); couponRates_.Add(new InterestRate(couponRate, paymentDayCounter, comp, freq)); @@ -127,11 +127,11 @@ public FixedRateLeg withCouponRates(List couponRates, DayCounter payment } public FixedRateLeg withCouponRates(List couponRates, DayCounter paymentDayCounter, - Compounding comp, Frequency freq) + Compounding comp, Frequency freq) { couponRates_.Clear(); foreach (double r in couponRates) - couponRates_.Add(new InterestRate(r, paymentDayCounter, comp , freq)); + couponRates_.Add(new InterestRate(r, paymentDayCounter, comp, freq)); return this; } @@ -142,13 +142,13 @@ public FixedRateLeg withCouponRates(InterestRate couponRate) return this; } - public FixedRateLeg withCouponRates(ListcouponRates) + public FixedRateLeg withCouponRates(ListcouponRates) { couponRates_ = couponRates; return this; } - public FixedRateLeg withFirstPeriodDayCounter(DayCounter dayCounter) + public FixedRateLeg withFirstPeriodDayCounter(DayCounter dayCounter) { firstPeriodDC_ = dayCounter; return this; @@ -160,27 +160,29 @@ public FixedRateLeg withLastPeriodDayCounter(DayCounter dayCounter) return this; } - public FixedRateLeg withPaymentCalendar(Calendar cal) + public FixedRateLeg withPaymentCalendar(Calendar cal) { calendar_ = cal; return this; } - public FixedRateLeg withExCouponPeriod(Period period,Calendar cal,BusinessDayConvention convention,bool endOfMonth = false) - { - exCouponPeriod_ = period; - exCouponCalendar_ = cal; - exCouponAdjustment_ = convention; - exCouponEndOfMonth_ = endOfMonth; - return this; - } + public FixedRateLeg withExCouponPeriod(Period period, Calendar cal, BusinessDayConvention convention, bool endOfMonth = false) + { + exCouponPeriod_ = period; + exCouponCalendar_ = cal; + exCouponAdjustment_ = convention; + exCouponEndOfMonth_ = endOfMonth; + return this; + } // creator - public override List value() + public override List value() { - - if (couponRates_.Count == 0) throw new ArgumentException("no coupon rates given"); - if (notionals_.Count == 0) throw new ArgumentException("no nominals given"); + + if (couponRates_.Count == 0) + throw new ArgumentException("no coupon rates given"); + if (notionals_.Count == 0) + throw new ArgumentException("no nominals given"); List leg = new List(); @@ -189,86 +191,92 @@ public override List value() // first period might be short or long Date start = schedule_[0], end = schedule_[1]; Date paymentDate = calendar_.adjust(end, paymentAdjustment_); - Date exCouponDate = null; + Date exCouponDate = null; InterestRate rate = couponRates_[0]; double nominal = notionals_[0]; - if (exCouponPeriod_ != null) - { - exCouponDate = exCouponCalendar_.advance(paymentDate, - -exCouponPeriod_, - exCouponAdjustment_, - exCouponEndOfMonth_); - } - if (schedule_.isRegular(1)) + if (exCouponPeriod_ != null) + { + exCouponDate = exCouponCalendar_.advance(paymentDate, + -exCouponPeriod_, + exCouponAdjustment_, + exCouponEndOfMonth_); + } + if (schedule_.isRegular(1)) { if (!(firstPeriodDC_ == null || firstPeriodDC_ == rate.dayCounter())) - throw new ArgumentException("regular first coupon does not allow a first-period day count"); - leg.Add( new FixedRateCoupon( paymentDate, nominal, rate, start, end, start, end, exCouponDate ) ); - } - else + throw new ArgumentException("regular first coupon does not allow a first-period day count"); + leg.Add(new FixedRateCoupon(paymentDate, nominal, rate, start, end, start, end, exCouponDate)); + } + else { - Date refer = end - schedule_.tenor(); - refer = schCalendar.adjust(refer, schedule_.businessDayConvention()); - InterestRate r = new InterestRate(rate.rate(), - (firstPeriodDC_ == null || firstPeriodDC_.empty()) ? rate.dayCounter() : firstPeriodDC_, - rate.compounding(), rate.frequency()); - leg.Add( new FixedRateCoupon( paymentDate, nominal, r, start, end, refer, end, exCouponDate ) ); + Date refer = end - schedule_.tenor(); + refer = schCalendar.adjust(refer, schedule_.businessDayConvention()); + InterestRate r = new InterestRate(rate.rate(), + (firstPeriodDC_ == null || firstPeriodDC_.empty()) ? rate.dayCounter() : firstPeriodDC_, + rate.compounding(), rate.frequency()); + leg.Add(new FixedRateCoupon(paymentDate, nominal, r, start, end, refer, end, exCouponDate)); } // regular periods - for (int i=2; i 2) { - // last period might be short or long - int N = schedule_.Count; - start = end; end = schedule_[N-1]; - paymentDate = calendar_.adjust(end, paymentAdjustment_); - if (exCouponPeriod_ != null) - { - exCouponDate = exCouponCalendar_.advance(paymentDate, - -exCouponPeriod_, - exCouponAdjustment_, - exCouponEndOfMonth_); - } - - if ((N - 2) < couponRates_.Count) + if (schedule_.Count > 2) + { + // last period might be short or long + int N = schedule_.Count; + start = end; end = schedule_[N - 1]; + paymentDate = calendar_.adjust(end, paymentAdjustment_); + if (exCouponPeriod_ != null) + { + exCouponDate = exCouponCalendar_.advance(paymentDate, + -exCouponPeriod_, + exCouponAdjustment_, + exCouponEndOfMonth_); + } + + if ((N - 2) < couponRates_.Count) rate = couponRates_[N - 2]; - else + else rate = couponRates_.Last(); - if ((N - 2) < notionals_.Count) + if ((N - 2) < notionals_.Count) nominal = notionals_[N - 2]; - else + else nominal = notionals_.Last(); InterestRate r = new InterestRate(rate.rate(), - lastPeriodDC_ == null ?rate.dayCounter() :lastPeriodDC_ , rate.compounding(), rate.frequency() ); - if (schedule_.isRegular(N-1)) - leg.Add( new FixedRateCoupon( paymentDate, nominal, r, start, end, start, end, exCouponDate ) ); - else { - Date refer = start + schedule_.tenor(); - refer = schCalendar.adjust(refer, schedule_.businessDayConvention()); - leg.Add( new FixedRateCoupon( paymentDate, nominal, r, start, end, start, refer, exCouponDate ) ); - } + lastPeriodDC_ == null ? rate.dayCounter() : lastPeriodDC_, rate.compounding(), rate.frequency()); + if (schedule_.isRegular(N - 1)) + leg.Add(new FixedRateCoupon(paymentDate, nominal, r, start, end, start, end, exCouponDate)); + else + { + Date refer = start + schedule_.tenor(); + refer = schCalendar.adjust(refer, schedule_.businessDayConvention()); + leg.Add(new FixedRateCoupon(paymentDate, nominal, r, start, end, start, refer, exCouponDate)); + } } return leg; - } - } + } + } } diff --git a/src/QLNet/Cashflows/FloatingRateCoupon.cs b/src/QLNet/Cashflows/FloatingRateCoupon.cs index 3f2e1596e..a35e33adf 100644 --- a/src/QLNet/Cashflows/FloatingRateCoupon.cs +++ b/src/QLNet/Cashflows/FloatingRateCoupon.cs @@ -2,18 +2,18 @@ Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -33,19 +33,19 @@ public class FloatingRateCoupon : Coupon, IObserver protected FloatingRateCouponPricer pricer_; // constructors - public FloatingRateCoupon(Date paymentDate, - double nominal, - Date startDate, - Date endDate, - int fixingDays, + public FloatingRateCoupon(Date paymentDate, + double nominal, + Date startDate, + Date endDate, + int fixingDays, InterestRateIndex index, - double gearing = 1.0, - double spread = 0.0, - Date refPeriodStart = null, - Date refPeriodEnd = null, - DayCounter dayCounter = null, + double gearing = 1.0, + double spread = 0.0, + Date refPeriodStart = null, + Date refPeriodEnd = null, + DayCounter dayCounter = null, bool isInArrears = false) - : base( paymentDate, nominal, startDate, endDate, refPeriodStart, refPeriodEnd ) + : base(paymentDate, nominal, startDate, endDate, refPeriodStart, refPeriodEnd) { index_ = index; dayCounter_ = dayCounter ?? new DayCounter() ; @@ -54,7 +54,8 @@ public FloatingRateCoupon(Date paymentDate, spread_ = spread; isInArrears_ = isInArrears; - if (gearing_.IsEqual(0)) throw new ArgumentException("Null gearing not allowed"); + if (gearing_.IsEqual(0)) + throw new ArgumentException("Null gearing not allowed"); if (dayCounter_.empty()) dayCounter_ = index_.dayCounter(); @@ -96,7 +97,8 @@ public override double amount() // Coupon interface public override double rate() { - if (pricer_ == null) throw new ArgumentException("pricer not set"); + if (pricer_ == null) + throw new ArgumentException("pricer not set"); pricer_.initialize(this); double result = pricer_.swapletRate(); return result; @@ -121,7 +123,8 @@ public override double accruedAmount(Date d) public InterestRateIndex index() { return index_; } //! floating index public int fixingDays { get { return fixingDays_; } } //! fixing days public virtual Date fixingDate() - { //! fixing date + { + //! fixing date // if isInArrears_ fix at the end of period Date refDate = isInArrears_ ? accrualEndDate_ : accrualStartDate_; return index_.fixingCalendar().advance(refDate, -fixingDays_, TimeUnit.Days, BusinessDayConvention.Preceding); @@ -162,11 +165,11 @@ public virtual double convexityAdjustment() // Factory - for Leg generators public virtual CashFlow factory(double nominal, Date paymentDate, Date startDate, Date endDate, int fixingDays, - InterestRateIndex index, double gearing, double spread, - Date refPeriodStart, Date refPeriodEnd, DayCounter dayCounter, bool isInArrears) + InterestRateIndex index, double gearing, double spread, + Date refPeriodStart, Date refPeriodEnd, DayCounter dayCounter, bool isInArrears) { - return new FloatingRateCoupon( paymentDate, nominal, startDate, endDate, fixingDays, - index, gearing, spread, refPeriodStart, refPeriodEnd, dayCounter, isInArrears); + return new FloatingRateCoupon(paymentDate, nominal, startDate, endDate, fixingDays, + index, gearing, spread, refPeriodStart, refPeriodEnd, dayCounter, isInArrears); } } } \ No newline at end of file diff --git a/src/QLNet/Cashflows/Iborcoupon.cs b/src/QLNet/Cashflows/Iborcoupon.cs index 26a530261..3f4dae2ee 100644 --- a/src/QLNet/Cashflows/Iborcoupon.cs +++ b/src/QLNet/Cashflows/Iborcoupon.cs @@ -2,18 +2,18 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,19 +29,19 @@ public class IborCoupon : FloatingRateCoupon public IborCoupon() { } public IborCoupon(Date paymentDate, - double nominal, - Date startDate, - Date endDate, + double nominal, + Date startDate, + Date endDate, int fixingDays, - IborIndex iborIndex, - double gearing = 1.0, + IborIndex iborIndex, + double gearing = 1.0, double spread = 0.0, - Date refPeriodStart = null, - Date refPeriodEnd = null, - DayCounter dayCounter = null, + Date refPeriodStart = null, + Date refPeriodEnd = null, + DayCounter dayCounter = null, bool isInArrears = false) : - base( paymentDate, nominal, startDate, endDate, fixingDays, iborIndex, gearing, spread, - refPeriodStart, refPeriodEnd, dayCounter, isInArrears) + base(paymentDate, nominal, startDate, endDate, fixingDays, iborIndex, gearing, spread, + refPeriodStart, refPeriodEnd, dayCounter, isInArrears) { iborIndex_ = iborIndex; @@ -52,26 +52,26 @@ public IborCoupon(Date paymentDate, fixingValueDate_ = fixingCalendar.advance(fixingDate_, indexFixingDays, TimeUnit.Days); - #if QL_USE_INDEXED_COUPON - fixingEndDate_ = index_->maturityDate(fixingValueDate_); - #else - if (isInArrears_) - fixingEndDate_ = index_.maturityDate(fixingValueDate_); - else - { - // par coupon approximation - Date nextFixingDate = fixingCalendar.advance(accrualEndDate_, -fixingDays_, TimeUnit.Days); - fixingEndDate_ = fixingCalendar.advance(nextFixingDate, indexFixingDays, TimeUnit.Days); +#if QL_USE_INDEXED_COUPON + fixingEndDate_ = index_->maturityDate(fixingValueDate_); +#else + if (isInArrears_) + fixingEndDate_ = index_.maturityDate(fixingValueDate_); + else + { + // par coupon approximation + Date nextFixingDate = fixingCalendar.advance(accrualEndDate_, -fixingDays_, TimeUnit.Days); + fixingEndDate_ = fixingCalendar.advance(nextFixingDate, indexFixingDays, TimeUnit.Days); } - #endif +#endif DayCounter dc = index_.dayCounter(); - spanningTime_ = dc.yearFraction(fixingValueDate_,fixingEndDate_); - Utils.QL_REQUIRE(spanningTime_>0.0,()=> - "\n cannot calculate forward rate between " + - fixingValueDate_ + " and " + fixingEndDate_ + - ":\n non positive time (" + spanningTime_ + - ") using " + dc.name() + " daycounter"); + spanningTime_ = dc.yearFraction(fixingValueDate_, fixingEndDate_); + Utils.QL_REQUIRE(spanningTime_ > 0.0, () => + "\n cannot calculate forward rate between " + + fixingValueDate_ + " and " + fixingEndDate_ + + ":\n non positive time (" + spanningTime_ + + ") using " + dc.name() + " daycounter"); } // Inspectors @@ -90,13 +90,13 @@ forecastFixing overload which Date today = Settings.evaluationDate(); if (fixingDate_ > today) - return iborIndex_.forecastFixing(fixingValueDate_,fixingEndDate_,spanningTime_); + return iborIndex_.forecastFixing(fixingValueDate_, fixingEndDate_, spanningTime_); if (fixingDate_ < today || Settings.enforcesTodaysHistoricFixings) { // do not catch exceptions double? result = index_.pastFixing(fixingDate_); - Utils.QL_REQUIRE(result != null,()=> "Missing " + index_.name() + " fixing for " + fixingDate_); + Utils.QL_REQUIRE(result != null, () => "Missing " + index_.name() + " fixing for " + fixingDate_); return result.Value; } @@ -111,17 +111,17 @@ forecastFixing overload which { // fall through and forecast } - return iborIndex_.forecastFixing(fixingValueDate_,fixingEndDate_,spanningTime_); + return iborIndex_.forecastFixing(fixingValueDate_, fixingEndDate_, spanningTime_); } // Factory - for Leg generators public override CashFlow factory(double nominal, Date paymentDate, Date startDate, Date endDate, int fixingDays, - InterestRateIndex index, double gearing, double spread, - Date refPeriodStart, Date refPeriodEnd, DayCounter dayCounter, bool isInArrears) + InterestRateIndex index, double gearing, double spread, + Date refPeriodStart, Date refPeriodEnd, DayCounter dayCounter, bool isInArrears) { - return new IborCoupon( paymentDate, nominal, startDate, endDate, fixingDays, - (IborIndex)index, gearing, spread, refPeriodStart, refPeriodEnd, dayCounter, isInArrears); + return new IborCoupon(paymentDate, nominal, startDate, endDate, fixingDays, + (IborIndex)index, gearing, spread, refPeriodStart, refPeriodEnd, dayCounter, isInArrears); } private IborIndex iborIndex_; @@ -145,9 +145,9 @@ public IborLeg(Schedule schedule, IborIndex index) public override List value() { List cashflows = CashFlowVectors.FloatingLeg( - notionals_, schedule_, index_ as IborIndex, paymentDayCounter_, - paymentAdjustment_, fixingDays_, gearings_, spreads_, - caps_, floors_, inArrears_, zeroPayments_); + notionals_, schedule_, index_ as IborIndex, paymentDayCounter_, + paymentAdjustment_, fixingDays_, gearings_, spreads_, + caps_, floors_, inArrears_, zeroPayments_); if (caps_.Count == 0 && floors_.Count == 0 && !inArrears_) { diff --git a/src/QLNet/Cashflows/IndexedCashFlow.cs b/src/QLNet/Cashflows/IndexedCashFlow.cs index 19bd62c26..70aa74cd9 100644 --- a/src/QLNet/Cashflows/IndexedCashFlow.cs +++ b/src/QLNet/Cashflows/IndexedCashFlow.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - * + * This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -40,10 +40,10 @@ public IndexedCashFlow(double notional, bool growthOnly = false) { notional_ = notional; - index_=index; + index_ = index; baseDate_ = baseDate; fixingDate_ = fixingDate; - paymentDate_= paymentDate; + paymentDate_ = paymentDate; growthOnly_ = growthOnly; } @@ -54,16 +54,16 @@ public IndexedCashFlow(double notional, public virtual Index index() { return index_; } public virtual bool growthOnly() { return growthOnly_; } - public override double amount() + public override double amount() { - double I0 = index_.fixing(baseDate_); - double I1 = index_.fixing(fixingDate_); + double I0 = index_.fixing(baseDate_); + double I1 = index_.fixing(fixingDate_); - if (growthOnly_) + if (growthOnly_) return notional_ * (I1 / I0 - 1.0); - else + else return notional_ * (I1 / I0); - + } private double notional_; private Index index_; diff --git a/src/QLNet/Cashflows/InflationCoupon.cs b/src/QLNet/Cashflows/InflationCoupon.cs index 79a137e0a..ca236d169 100644 --- a/src/QLNet/Cashflows/InflationCoupon.cs +++ b/src/QLNet/Cashflows/InflationCoupon.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - * + * This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -28,7 +28,7 @@ YoY coupons but not zero inflation coupons. \note inflation indices do not contain day counters or calendars. */ - public class InflationCoupon : Coupon,IObserver + public class InflationCoupon : Coupon, IObserver { public InflationCoupon(Date paymentDate, @@ -42,11 +42,11 @@ public InflationCoupon(Date paymentDate, Date refPeriodStart = null, Date refPeriodEnd = null, Date exCouponDate = null) - : base( paymentDate, nominal, startDate, endDate, refPeriodStart, refPeriodEnd, exCouponDate ) // ref period is before lag + : base(paymentDate, nominal, startDate, endDate, refPeriodStart, refPeriodEnd, exCouponDate) // ref period is before lag { index_ = index; observationLag_ = observationLag; - dayCounter_= dayCounter; + dayCounter_ = dayCounter; fixingDays_ = fixingDays; index_.registerWith(update); @@ -58,68 +58,71 @@ public override double amount() { return rate() * accrualPeriod() * nominal(); } - // Coupon interface - public double price(Handle discountingCurve) - { - return amount() * discountingCurve.link.discount(date()); - } - public override DayCounter dayCounter() { return dayCounter_; } - public override double accruedAmount(Date d) - { - if (d <= accrualStartDate_ || d > paymentDate_) { + // Coupon interface + public double price(Handle discountingCurve) + { + return amount() * discountingCurve.link.discount(date()); + } + public override DayCounter dayCounter() { return dayCounter_; } + public override double accruedAmount(Date d) + { + if (d <= accrualStartDate_ || d > paymentDate_) + { return 0.0; - } else { + } + else + { return nominal() * rate() * - dayCounter().yearFraction(accrualStartDate_, - d < accrualEndDate_ ? d : accrualEndDate_, //Math.Min(d, accrualEndDate_), - refPeriodStart_, - refPeriodEnd_); - } - } - public override double rate() - { - Utils.QL_REQUIRE(pricer_ != null,()=> "pricer not set"); - - // we know it is the correct type because checkPricerImpl checks on setting - // in general pricer_ will be a derived class, as will *this on calling - pricer_.initialize(this); - return pricer_.swapletRate(); - } - - // Inspectors - //! yoy inflation index - public InflationIndex index() { return index_; } - //! how the coupon observes the index - public Period observationLag() { return observationLag_; } - //! fixing days - public int fixingDays() { return fixingDays_; } - //! fixing date - public virtual Date fixingDate() - { - // fixing calendar is usually the null calendar for inflation indices - return index_.fixingCalendar().advance(refPeriodEnd_ - observationLag_, - -(fixingDays_), TimeUnit.Days,BusinessDayConvention.ModifiedPreceding); - } - //! fixing of the underlying index, as observed by the coupon - public virtual double indexFixing() - { - return index_.fixing(fixingDate()); - } + dayCounter().yearFraction(accrualStartDate_, + d < accrualEndDate_ ? d : accrualEndDate_, //Math.Min(d, accrualEndDate_), + refPeriodStart_, + refPeriodEnd_); + } + } + public override double rate() + { + Utils.QL_REQUIRE(pricer_ != null, () => "pricer not set"); + + // we know it is the correct type because checkPricerImpl checks on setting + // in general pricer_ will be a derived class, as will *this on calling + pricer_.initialize(this); + return pricer_.swapletRate(); + } + + // Inspectors + //! yoy inflation index + public InflationIndex index() { return index_; } + //! how the coupon observes the index + public Period observationLag() { return observationLag_; } + //! fixing days + public int fixingDays() { return fixingDays_; } + //! fixing date + public virtual Date fixingDate() + { + // fixing calendar is usually the null calendar for inflation indices + return index_.fixingCalendar().advance(refPeriodEnd_ - observationLag_, + -(fixingDays_), TimeUnit.Days, BusinessDayConvention.ModifiedPreceding); + } + //! fixing of the underlying index, as observed by the coupon + public virtual double indexFixing() + { + return index_.fixing(fixingDate()); + } public void update() { notifyObservers(); } - public void setPricer(InflationCouponPricer pricer) + public void setPricer(InflationCouponPricer pricer) { - Utils.QL_REQUIRE(checkPricerImpl(pricer),()=> "pricer given is wrong type"); + Utils.QL_REQUIRE(checkPricerImpl(pricer), () => "pricer given is wrong type"); if (pricer_ != null) pricer_.unregisterWith(update); - + pricer_ = pricer; - + if (pricer_ != null) - pricer_.registerWith(update); + pricer_.registerWith(update); update(); } diff --git a/src/QLNet/Cashflows/InflationCouponPricer.cs b/src/QLNet/Cashflows/InflationCouponPricer.cs index 0b159bd03..c50bf2e9f 100644 --- a/src/QLNet/Cashflows/InflationCouponPricer.cs +++ b/src/QLNet/Cashflows/InflationCouponPricer.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -39,7 +39,7 @@ versions are from a coupon point of view (a capped coupon has We add the inverse prices so that conventional caps can be priced simply. */ - public class InflationCouponPricer : IObserver,IObservable + public class InflationCouponPricer : IObserver, IObservable { // Interface public virtual double swapletPrice() {return 0; } @@ -54,8 +54,14 @@ public virtual void initialize(InflationCoupon i) {} private readonly WeakEventSource eventSource = new WeakEventSource(); public event Callback notifyObserversEvent { - add { eventSource.Subscribe(value); } - remove { eventSource.Unsubscribe(value); } + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } } public void registerWith(Callback handler) { notifyObserversEvent += handler; } @@ -74,27 +80,28 @@ protected void notifyObservers() } - //! base pricer for capped/floored YoY inflation coupons - /*! \note this pricer can already do swaplets but to get - volatility-dependent coupons you need the descendents. - */ + //! base pricer for capped/floored YoY inflation coupons + /*! \note this pricer can already do swaplets but to get + volatility-dependent coupons you need the descendents. + */ public class YoYInflationCouponPricer : InflationCouponPricer { public YoYInflationCouponPricer(Handle capletVol = null) { capletVol_ = capletVol ?? new Handle(); - if (!capletVol_.empty()) capletVol_.registerWith(update); + if (!capletVol_.empty()) + capletVol_.registerWith(update); } - public virtual Handle capletVolatility() + public virtual Handle capletVolatility() { return capletVol_; } public virtual void setCapletVolatility(Handle capletVol) { - Utils.QL_REQUIRE( !capletVol.empty() ,()=> "empty capletVol handle"); + Utils.QL_REQUIRE(!capletVol.empty(), () => "empty capletVol handle"); capletVol_ = capletVol; capletVol_.registerWith(update); @@ -154,7 +161,7 @@ public override void initialize(InflationCoupon coupon) if (paymentDate_ > rateCurve_.link.referenceDate()) discount_ = rateCurve_.link.discount(paymentDate_); - spreadLegValue_ = spread_ * coupon_.accrualPeriod()* discount_; + spreadLegValue_ = spread_ * coupon_.accrualPeriod() * discount_; } //! car replace this if really required @@ -162,43 +169,43 @@ protected virtual double optionletPrice(Option.Type optionType, double effStrike { Date fixingDate = coupon_.fixingDate(); - if (fixingDate <= Settings.evaluationDate()) + if (fixingDate <= Settings.evaluationDate()) { // the amount is determined double a, b; - if (optionType==Option.Type.Call) + if (optionType == Option.Type.Call) { - a = coupon_.indexFixing(); - b = effStrike; - } - else + a = coupon_.indexFixing(); + b = effStrike; + } + else { - a = effStrike; - b = coupon_.indexFixing(); + a = effStrike; + b = coupon_.indexFixing(); } - return Math.Max(a - b, 0.0)* coupon_.accrualPeriod()*discount_; - - } - else + return Math.Max(a - b, 0.0) * coupon_.accrualPeriod() * discount_; + + } + else { // not yet determined, use Black/DD1/Bachelier/whatever from Impl - Utils.QL_REQUIRE( !capletVolatility().empty() ,()=> "missing optionlet volatility"); + Utils.QL_REQUIRE(!capletVolatility().empty(), () => "missing optionlet volatility"); - double stdDev = Math.Sqrt(capletVolatility().link.totalVariance(fixingDate,effStrike)); + double stdDev = Math.Sqrt(capletVolatility().link.totalVariance(fixingDate, effStrike)); double fixing = optionletPriceImp(optionType, effStrike, adjustedFixing(), stdDev); return fixing * coupon_.accrualPeriod() * discount_; - + } } //! usually only need implement this (of course they may need //! to re-implement initialize too ...) protected virtual double optionletPriceImp(Option.Type t, double strike, - double forward, double stdDev) + double forward, double stdDev) { Utils.QL_FAIL("you must implement this to get a vol-dependent price"); return 0; @@ -228,13 +235,13 @@ protected virtual double adjustedFixing(double? fixing) } //! Black-formula pricer for capped/floored yoy inflation coupons - public class BlackYoYInflationCouponPricer : YoYInflationCouponPricer + public class BlackYoYInflationCouponPricer : YoYInflationCouponPricer { - + public BlackYoYInflationCouponPricer(Handle capletVol) : base(capletVol) {} - + protected override double optionletPriceImp(Option.Type optionType, double effStrike, double forward, double stdDev) { @@ -244,17 +251,17 @@ protected override double optionletPriceImp(Option.Type optionType, double effSt stdDev); } - } + } //! Unit-Displaced-Black-formula pricer for capped/floored yoy inflation coupons - public class UnitDisplacedBlackYoYInflationCouponPricer : YoYInflationCouponPricer + public class UnitDisplacedBlackYoYInflationCouponPricer : YoYInflationCouponPricer { public UnitDisplacedBlackYoYInflationCouponPricer(Handle capletVol = null) - : base(capletVol) + : base(capletVol) {} protected override double optionletPriceImp(Option.Type optionType, double effStrike, - double forward, double stdDev) + double forward, double stdDev) { return Utils.blackFormula(optionType, @@ -263,21 +270,21 @@ protected override double optionletPriceImp(Option.Type optionType, double effSt stdDev); } } - + //! Bachelier-formula pricer for capped/floored yoy inflation coupons - public class BachelierYoYInflationCouponPricer : YoYInflationCouponPricer + public class BachelierYoYInflationCouponPricer : YoYInflationCouponPricer { public BachelierYoYInflationCouponPricer(Handle capletVol = null) - : base(capletVol) + : base(capletVol) {} protected override double optionletPriceImp(Option.Type optionType, double effStrike, - double forward, double stdDev) + double forward, double stdDev) { return Utils.bachelierBlackFormula(optionType, - effStrike, - forward, - stdDev); + effStrike, + forward, + stdDev); } - }; + } } diff --git a/src/QLNet/Cashflows/LinearTsrPricer.cs b/src/QLNet/Cashflows/LinearTsrPricer.cs index 7e729d7a9..e8f37748a 100644 --- a/src/QLNet/Cashflows/LinearTsrPricer.cs +++ b/src/QLNet/Cashflows/LinearTsrPricer.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -44,7 +44,7 @@ there is no automatic adjustment in this case. */ public class LinearTsrPricer : CmsCouponPricer, IMeanRevertingPricer { - public class Settings + public class Settings { public Settings() { @@ -56,7 +56,7 @@ public Settings() upperRateBound_ = 2.0000; } - public Settings withRateBound( double lowerRateBound = 0.0001, double upperRateBound = 2.0000 ) + public Settings withRateBound(double lowerRateBound = 0.0001, double upperRateBound = 2.0000) { strategy_ = Strategy.RateBound; lowerRateBound_ = lowerRateBound; @@ -64,7 +64,7 @@ public Settings withRateBound( double lowerRateBound = 0.0001, double upperRateB return this; } - public Settings withVegaRatio( double vegaRatio = 0.01, double lowerRateBound = 0.0001, double upperRateBound = 2.0000 ) + public Settings withVegaRatio(double vegaRatio = 0.01, double lowerRateBound = 0.0001, double upperRateBound = 2.0000) { strategy_ = Strategy.VegaRatio; vegaRatio_ = vegaRatio; @@ -73,8 +73,8 @@ public Settings withVegaRatio( double vegaRatio = 0.01, double lowerRateBound = return this; } - public Settings withPriceThreshold( double priceThreshold = 1.0E-8, double lowerRateBound = 0.0001, - double upperRateBound = 2.0000) + public Settings withPriceThreshold(double priceThreshold = 1.0E-8, double lowerRateBound = 0.0001, + double upperRateBound = 2.0000) { strategy_ = Strategy.PriceThreshold; priceThreshold_ = priceThreshold; @@ -83,9 +83,9 @@ public Settings withPriceThreshold( double priceThreshold = 1.0E-8, double lower return this; } - public Settings withBSStdDevs( double stdDevs = 3.0, - double lowerRateBound = 0.0001, - double upperRateBound = 2.0000) + public Settings withBSStdDevs(double stdDevs = 3.0, + double lowerRateBound = 0.0001, + double upperRateBound = 2.0000) { strategy_ = Strategy.BSStdDevs; stdDevs_ = stdDevs; @@ -96,10 +96,10 @@ public Settings withBSStdDevs( double stdDevs = 3.0, public enum Strategy { - RateBound, - VegaRatio, - PriceThreshold, - BSStdDevs + RateBound, + VegaRatio, + PriceThreshold, + BSStdDevs } public Strategy strategy_ { get; set; } @@ -107,16 +107,16 @@ public enum Strategy public double priceThreshold_ { get; set; } public double stdDevs_ { get; set; } public double lowerRateBound_ { get; set; } - public double upperRateBound_{ get; set; } - + public double upperRateBound_ { get; set; } + } - public LinearTsrPricer( Handle swaptionVol, - Handle meanReversion, - Handle couponDiscountCurve = null, - Settings settings = null, - Integrator integrator = null) - :base(swaptionVol) + public LinearTsrPricer(Handle swaptionVol, + Handle meanReversion, + Handle couponDiscountCurve = null, + Settings settings = null, + Integrator integrator = null) + : base(swaptionVol) { meanReversion_ = meanReversion; couponDiscountCurve_ = couponDiscountCurve ?? new Handle(); @@ -124,56 +124,56 @@ public LinearTsrPricer( Handle swaptionVol, volDayCounter_ = swaptionVol.link.dayCounter(); integrator_ = integrator; - if (!couponDiscountCurve_.empty()) + if (!couponDiscountCurve_.empty()) couponDiscountCurve_.registerWith(update); - if (integrator_ == null) + if (integrator_ == null) integrator_ = new GaussKronrodNonAdaptive(1E-10, 5000, 1E-10); } /* */ public override double swapletPrice() { - if (fixingDate_ <= today_) + if (fixingDate_ <= today_) { // the fixing is determined double Rs = coupon_.swapIndex().fixing(fixingDate_); double price = - (gearing_ * Rs + spread_) * - (coupon_.accrualPeriod() * - discountCurve_.link.discount(paymentDate_) * couponDiscountRatio_); + (gearing_ * Rs + spread_) * + (coupon_.accrualPeriod() * + discountCurve_.link.discount(paymentDate_) * couponDiscountRatio_); return price; - } - else + } + else { double atmCapletPrice = optionletPrice(Option.Type.Call, swapRateValue_); double atmFloorletPrice = optionletPrice(Option.Type.Put, swapRateValue_); return gearing_ * (coupon_.accrualPeriod() * - discountCurve_.link.discount(paymentDate_) * - swapRateValue_ * couponDiscountRatio_ + - atmCapletPrice - atmFloorletPrice) + - spreadLegValue_; + discountCurve_.link.discount(paymentDate_) * + swapRateValue_ * couponDiscountRatio_ + + atmCapletPrice - atmFloorletPrice) + + spreadLegValue_; } } public override double swapletRate() { return swapletPrice() / - ( coupon_.accrualPeriod() * discountCurve_.link.discount( paymentDate_ ) * couponDiscountRatio_ ); + (coupon_.accrualPeriod() * discountCurve_.link.discount(paymentDate_) * couponDiscountRatio_); } public override double capletPrice(double effectiveCap) { // caplet is equivalent to call option on fixing - if (fixingDate_ <= today_) + if (fixingDate_ <= today_) { // the fixing is determined double Rs = Math.Max(coupon_.swapIndex().fixing(fixingDate_) - effectiveCap, 0.0); double price = - (gearing_ * Rs) * - (coupon_.accrualPeriod() * - discountCurve_.link.discount(paymentDate_) * couponDiscountRatio_); + (gearing_ * Rs) * + (coupon_.accrualPeriod() * + discountCurve_.link.discount(paymentDate_) * couponDiscountRatio_); return price; - } - else + } + else { double capletPrice = optionletPrice(Option.Type.Call, effectiveCap); return gearing_ * capletPrice; @@ -181,24 +181,24 @@ public override double capletPrice(double effectiveCap) } public override double capletRate(double effectiveCap) { - return capletPrice( effectiveCap ) / - ( coupon_.accrualPeriod() * - discountCurve_.link.discount( paymentDate_ ) * couponDiscountRatio_ ); + return capletPrice(effectiveCap) / + (coupon_.accrualPeriod() * + discountCurve_.link.discount(paymentDate_) * couponDiscountRatio_); } public override double floorletPrice(double effectiveFloor) { // floorlet is equivalent to put option on fixing - if (fixingDate_ <= today_) + if (fixingDate_ <= today_) { // the fixing is determined double Rs = Math.Max(effectiveFloor - coupon_.swapIndex().fixing(fixingDate_), 0.0); double price = - (gearing_ * Rs) * - (coupon_.accrualPeriod() * - discountCurve_.link.discount(paymentDate_) * couponDiscountRatio_); + (gearing_ * Rs) * + (coupon_.accrualPeriod() * + discountCurve_.link.discount(paymentDate_) * couponDiscountRatio_); return price; - } - else + } + else { double floorletPrice = optionletPrice(Option.Type.Put, effectiveFloor); return gearing_ * floorletPrice; @@ -206,13 +206,13 @@ public override double floorletPrice(double effectiveFloor) } public override double floorletRate(double effectiveFloor) { - return floorletPrice( effectiveFloor ) / - ( coupon_.accrualPeriod() * - discountCurve_.link.discount( paymentDate_ ) * couponDiscountRatio_ ); + return floorletPrice(effectiveFloor) / + (coupon_.accrualPeriod() * + discountCurve_.link.discount(paymentDate_) * couponDiscountRatio_); } /* */ public double meanReversion() { return meanReversion_.link.value(); } - public void setMeanReversion( Handle meanReversion) + public void setMeanReversion(Handle meanReversion) { meanReversion_.unregisterWith(update); meanReversion_ = meanReversion; @@ -221,57 +221,57 @@ public void setMeanReversion( Handle meanReversion) } - private double GsrG( Date d) + private double GsrG(Date d) { double yf = volDayCounter_.yearFraction(fixingDate_, d); if (Math.Abs(meanReversion_.link.value()) < 1.0E-4) return yf; else return (1.0 - Math.Exp(-meanReversion_.link.value() * yf)) / - meanReversion_.link.value(); + meanReversion_.link.value(); } - private double singularTerms( Option.Type type, double strike) + private double singularTerms(Option.Type type, double strike) { double omega = (type == Option.Type.Call ? 1.0 : -1.0); double s1 = Math.Max(omega * (swapRateValue_ - strike), 0.0) * - (a_ * swapRateValue_ + b_); + (a_ * swapRateValue_ + b_); double s2 = (a_ * strike + b_) * smileSection_.optionPrice(strike, strike < swapRateValue_ ? Option.Type.Put : Option.Type.Call); - return s1 + s2; + return s1 + s2; } private double integrand(double strike) { - return 2.0 * a_ * smileSection_.optionPrice( strike, strike < swapRateValue_ ? Option.Type.Put : Option.Type.Call); + return 2.0 * a_ * smileSection_.optionPrice(strike, strike < swapRateValue_ ? Option.Type.Put : Option.Type.Call); } private double a_, b_; private class VegaRatioHelper : ISolver1d { - public VegaRatioHelper( SmileSection section, double targetVega) + public VegaRatioHelper(SmileSection section, double targetVega) { section_ = section; targetVega_ = targetVega; } - - public override double value(double strike) + + public override double value(double strike) { return section_.vega(strike) - targetVega_; } - + SmileSection section_; double targetVega_; } private class PriceHelper : ISolver1d { - public PriceHelper( SmileSection section, Option.Type type,double targetPrice) + public PriceHelper(SmileSection section, Option.Type type, double targetPrice) { section_ = section; targetPrice_ = targetPrice; type_ = type; } - - public override double value(double strike) + + public override double value(double strike) { return section_.optionPrice(strike, type_) - targetPrice_; } @@ -281,10 +281,10 @@ public override double value(double strike) private Option.Type type_; } - public override void initialize( FloatingRateCoupon coupon) + public override void initialize(FloatingRateCoupon coupon) { coupon_ = coupon as CmsCoupon; - Utils.QL_REQUIRE(coupon_ != null,()=> "CMS coupon needed"); + Utils.QL_REQUIRE(coupon_ != null, () => "CMS coupon needed"); gearing_ = coupon_.gearing(); spread_ = coupon_.spread(); @@ -317,7 +317,7 @@ public override void initialize( FloatingRateCoupon coupon) discountCurve_.link.discount(paymentDate_) * couponDiscountRatio_; - if (fixingDate_ > today_) + if (fixingDate_ > today_) { swapTenor_ = swapIndex_.tenor(); swap_ = swapIndex_.underlyingSwap(fixingDate_); @@ -334,15 +334,15 @@ public override void initialize( FloatingRateCoupon coupon) // if the section does not provide an atm level, we enhance it to // have one, no need to exit with an exception ... - if (sectionTmp.atmLevel() ==null) - smileSection_ = new AtmSmileSection(sectionTmp, swapRateValue_); + if (sectionTmp.atmLevel() == null) + smileSection_ = new AtmSmileSection(sectionTmp, swapRateValue_); else - smileSection_ = sectionTmp; + smileSection_ = sectionTmp; // compute linear model's parameters double gx = 0.0, gy = 0.0; - for (int i = 0; i < swap_.fixedLeg().Count; i++) + for (int i = 0; i < swap_.fixedLeg().Count; i++) { Coupon c = swap_.fixedLeg()[i] as Coupon; double yf = c.accrualPeriod(); @@ -356,13 +356,13 @@ public override void initialize( FloatingRateCoupon coupon) Date lastd = swap_.fixedLeg().Last().date(); a_ = discountCurve_.link.discount(paymentDate_) * - (gamma - GsrG(paymentDate_)) / - (discountCurve_.link.discount(lastd) * GsrG(lastd) + + (gamma - GsrG(paymentDate_)) / + (discountCurve_.link.discount(lastd) * GsrG(lastd) + swapRateValue_ * gy * gamma); b_ = discountCurve_.link.discount(paymentDate_) / gy - - a_ * swapRateValue_; - } + a_ * swapRateValue_; + } } @@ -377,10 +377,10 @@ private double optionletPrice(Option.Type optionType, double strike) double lower = strike, upper = strike; - switch (settings_.strategy_) + switch (settings_.strategy_) { - case Settings.Strategy.RateBound: + case Settings.Strategy.RateBound: { if (optionType == Option.Type.Call) upper = shiftedUpperBound_; @@ -389,7 +389,7 @@ private double optionletPrice(Option.Type optionType, double strike) break; } - case Settings.Strategy.VegaRatio: + case Settings.Strategy.VegaRatio: { // strikeFromVegaRatio ensures that returned strike is on the // expected side of strike @@ -401,7 +401,7 @@ private double optionletPrice(Option.Type optionType, double strike) break; } - case Settings.Strategy.PriceThreshold: + case Settings.Strategy.PriceThreshold: { // strikeFromPrice ensures that returned strike is on the expected // side of strike @@ -413,24 +413,24 @@ private double optionletPrice(Option.Type optionType, double strike) break; } - case Settings.Strategy.BSStdDevs : + case Settings.Strategy.BSStdDevs : { double? atm = smileSection_.atmLevel(); double atmVol = smileSection_.volatility(atm.GetValueOrDefault()); double shift = smileSection_.shift(); double lowerTmp, upperTmp; - if (smileSection_.volatilityType() == VolatilityType.ShiftedLognormal) + if (smileSection_.volatilityType() == VolatilityType.ShiftedLognormal) { upperTmp = (atm.GetValueOrDefault() + shift) * - Math.Exp(settings_.stdDevs_ * atmVol - - 0.5 * atmVol * atmVol * - smileSection_.exerciseTime()) - shift; + Math.Exp(settings_.stdDevs_ * atmVol - + 0.5 * atmVol * atmVol * + smileSection_.exerciseTime()) - shift; lowerTmp = (atm.GetValueOrDefault() + shift) * - Math.Exp(-settings_.stdDevs_ * atmVol - - 0.5 * atmVol * atmVol * - smileSection_.exerciseTime()) - shift; - } - else + Math.Exp(-settings_.stdDevs_ * atmVol - + 0.5 * atmVol * atmVol * + smileSection_.exerciseTime()) - shift; + } + else { double tmp = settings_.stdDevs_ * atmVol * Math.Sqrt(smileSection_.exerciseTime()); upperTmp = atm.GetValueOrDefault() + tmp; @@ -450,17 +450,17 @@ private double optionletPrice(Option.Type optionType, double strike) double result = 0.0; double tmpBound; - if (upper > lower) + if (upper > lower) { tmpBound = Math.Min(upper, swapRateValue_); - if (tmpBound > lower) + if (tmpBound > lower) { - result += integrator_.value( integrand,lower, tmpBound); + result += integrator_.value(integrand, lower, tmpBound); } tmpBound = Math.Max(lower, swapRateValue_); - if (upper > tmpBound) + if (upper > tmpBound) { - result += integrator_.value(integrand,tmpBound, upper); + result += integrator_.value(integrand, tmpBound, upper); } result *= (optionType == Option.Type.Call ? 1.0 : -1.0); } @@ -470,30 +470,30 @@ private double optionletPrice(Option.Type optionType, double strike) return annuity_ * result * couponDiscountRatio_ * coupon_.accrualPeriod(); } - private double strikeFromVegaRatio(double ratio, Option.Type optionType,double referenceStrike) + private double strikeFromVegaRatio(double ratio, Option.Type optionType, double referenceStrike) { double a, b, min, max, k; - if (optionType == Option.Type.Call) + if (optionType == Option.Type.Call) { a = swapRateValue_; min = referenceStrike; b = max = k = Math.Min(smileSection_.maxStrike(), shiftedUpperBound_); - } - else + } + else { a = min = k = Math.Max(smileSection_.minStrike(), shiftedLowerBound_); b = swapRateValue_; max = referenceStrike; } - VegaRatioHelper h = new VegaRatioHelper(smileSection_,smileSection_.vega(swapRateValue_) * ratio); + VegaRatioHelper h = new VegaRatioHelper(smileSection_, smileSection_.vega(swapRateValue_) * ratio); Brent solver = new Brent(); - try + try { k = solver.solve(h, 1.0E-5, (a + b) / 2.0, a, b); } - catch (Exception) + catch (Exception) { // use default value set above } @@ -501,16 +501,16 @@ private double strikeFromVegaRatio(double ratio, Option.Type optionType,double r return Math.Min(Math.Max(k, min), max); } - private double strikeFromPrice(double price, Option.Type optionType,double referenceStrike) + private double strikeFromPrice(double price, Option.Type optionType, double referenceStrike) { double a, b, min, max, k; - if (optionType == Option.Type.Call) + if (optionType == Option.Type.Call) { a = swapRateValue_; min = referenceStrike; b = max = k = Math.Min(smileSection_.maxStrike(), shiftedUpperBound_); - } - else + } + else { a = min = k = Math.Max(smileSection_.minStrike(), shiftedLowerBound_); b = swapRateValue_; @@ -520,17 +520,17 @@ private double strikeFromPrice(double price, Option.Type optionType,double refer PriceHelper h = new PriceHelper(smileSection_, optionType, price); Brent solver = new Brent(); - try + try { k = solver.solve(h, 1.0E-5, swapRateValue_, a, b); } - catch (Exception) + catch (Exception) { // use default value set above } - return Math.Min(Math.Max(k, min), max); - + return Math.Min(Math.Max(k, min), max); + } private Handle meanReversion_; diff --git a/src/QLNet/Cashflows/OvernightIndexedCoupon.cs b/src/QLNet/Cashflows/OvernightIndexedCoupon.cs index e0a9dae36..4f8c7f1b5 100644 --- a/src/QLNet/Cashflows/OvernightIndexedCoupon.cs +++ b/src/QLNet/Cashflows/OvernightIndexedCoupon.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - * + * This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,9 +29,9 @@ public class OvernightIndexedCouponPricer : FloatingRateCouponPricer public override void initialize(FloatingRateCoupon coupon) { coupon_ = coupon as OvernightIndexedCoupon; - Utils.QL_REQUIRE(coupon_ != null,()=> "wrong coupon type"); + Utils.QL_REQUIRE(coupon_ != null, () => "wrong coupon type"); } - + public override double swapletRate() { OvernightIndex index = coupon_.index() as OvernightIndex; @@ -46,53 +46,53 @@ public override double swapletRate() // already fixed part Date today = Settings.evaluationDate(); - while (fixingDates[i] "Missing " + index.name() + " fixing for " + fixingDates[i].ToString()); + Utils.QL_REQUIRE(pastFixing != null, () => "Missing " + index.name() + " fixing for " + fixingDates[i].ToString()); - compoundFactor *= (1.0 + pastFixing.GetValueOrDefault()*dt[i]); + compoundFactor *= (1.0 + pastFixing.GetValueOrDefault() * dt[i]); ++i; } // today is a border case - if (fixingDates[i] == today && i curve = index.forwardingTermStructure(); - Utils.QL_REQUIRE(!curve.empty(),()=> "null term structure set to this instance of" + index.name()); - + Utils.QL_REQUIRE(!curve.empty(), () => "null term structure set to this instance of" + index.name()); + List dates = coupon_.valueDates(); double startDiscount = curve.link.discount(dates[i]); double endDiscount = curve.link.discount(dates[n]); - compoundFactor *= startDiscount/endDiscount; + compoundFactor *= startDiscount / endDiscount; } double rate = (compoundFactor - 1.0) / coupon_.accrualPeriod(); @@ -110,64 +110,64 @@ public override double swapletRate() public class OvernightIndexedCoupon : FloatingRateCoupon { public OvernightIndexedCoupon( - Date paymentDate, - double nominal, - Date startDate, - Date endDate, - OvernightIndex overnightIndex, - double gearing = 1.0, - double spread = 0.0, - Date refPeriodStart = null, - Date refPeriodEnd = null, - DayCounter dayCounter = null) - : base( paymentDate, nominal, startDate, endDate, - overnightIndex.fixingDays(), overnightIndex, - gearing, spread, - refPeriodStart, refPeriodEnd, - dayCounter, false) + Date paymentDate, + double nominal, + Date startDate, + Date endDate, + OvernightIndex overnightIndex, + double gearing = 1.0, + double spread = 0.0, + Date refPeriodStart = null, + Date refPeriodEnd = null, + DayCounter dayCounter = null) + : base(paymentDate, nominal, startDate, endDate, + overnightIndex.fixingDays(), overnightIndex, + gearing, spread, + refPeriodStart, refPeriodEnd, + dayCounter, false) { // value dates Schedule sch = new MakeSchedule() - .from(startDate) - .to(endDate) - .withTenor(new Period(1,TimeUnit.Days)) - .withCalendar(overnightIndex.fixingCalendar()) - .withConvention(overnightIndex.businessDayConvention()) - .backwards() - .value(); - + .from(startDate) + .to(endDate) + .withTenor(new Period(1, TimeUnit.Days)) + .withCalendar(overnightIndex.fixingCalendar()) + .withConvention(overnightIndex.businessDayConvention()) + .backwards() + .value(); + valueDates_ = sch.dates(); - Utils.QL_REQUIRE(valueDates_.Count >= 2,()=> "degenerate schedule"); + Utils.QL_REQUIRE(valueDates_.Count >= 2, () => "degenerate schedule"); // fixing dates - n_ = valueDates_.Count-1; - if (overnightIndex.fixingDays()==0) + n_ = valueDates_.Count - 1; + if (overnightIndex.fixingDays() == 0) { fixingDates_ = new List(valueDates_); } - else + else { fixingDates_ = new InitializedList(n_); - for (int i=0; i(n_); DayCounter dc = overnightIndex.dayCounter(); - for (int i=0; i indexFixings() { - fixings_ = new InitializedList(n_); - for (int i=0; i(n_); + for (int i = 0; i < n_; ++i) fixings_[i] = index_.fixing(fixingDates_[i]); - return fixings_; + return fixings_; } @@ -177,71 +177,71 @@ public List indexFixings() public List dt() { return dt_; } //! value dates for the rates to be compounded public List valueDates() { return valueDates_; } - + private List valueDates_, fixingDates_; private List fixings_; int n_; List dt_; } - //! helper class building a sequence of overnight coupons + //! helper class building a sequence of overnight coupons public class OvernightLeg : RateLegBase - { - public OvernightLeg(Schedule schedule,OvernightIndex overnightIndex) - { - schedule_ = schedule; - overnightIndex_ = overnightIndex; - paymentAdjustment_ = BusinessDayConvention.Following; - } - public new OvernightLeg withNotionals(double notional) - { - notionals_ = new List(); notionals_.Add(notional); - return this; - } - public new OvernightLeg withNotionals(List notionals) - { - notionals_ = notionals; - return this; - } - public OvernightLeg withPaymentDayCounter(DayCounter dayCounter) - { - paymentDayCounter_ = dayCounter; - return this; - } - public new OvernightLeg withPaymentAdjustment(BusinessDayConvention convention) - { - paymentAdjustment_ = convention; - return this; - } - public OvernightLeg withGearings(double gearing) - { - gearings_ = new List(); gearings_.Add(gearing); - return this; - } - public OvernightLeg withGearings(List gearings) - { - gearings_ = gearings; - return this; - } - public OvernightLeg withSpreads(double spread) - { - spreads_ = new List(); spreads_.Add(spread); - return this; - } - public OvernightLeg withSpreads(List spreads) - { - spreads_ = spreads; - return this; - } - - public override List value() - { - return CashFlowVectors.OvernightLeg(notionals_, schedule_, paymentAdjustment_, overnightIndex_, gearings_, spreads_, paymentDayCounter_); - } - - private OvernightIndex overnightIndex_; - private List gearings_; - private List spreads_; - } + { + public OvernightLeg(Schedule schedule, OvernightIndex overnightIndex) + { + schedule_ = schedule; + overnightIndex_ = overnightIndex; + paymentAdjustment_ = BusinessDayConvention.Following; + } + public new OvernightLeg withNotionals(double notional) + { + notionals_ = new List(); notionals_.Add(notional); + return this; + } + public new OvernightLeg withNotionals(List notionals) + { + notionals_ = notionals; + return this; + } + public OvernightLeg withPaymentDayCounter(DayCounter dayCounter) + { + paymentDayCounter_ = dayCounter; + return this; + } + public new OvernightLeg withPaymentAdjustment(BusinessDayConvention convention) + { + paymentAdjustment_ = convention; + return this; + } + public OvernightLeg withGearings(double gearing) + { + gearings_ = new List(); gearings_.Add(gearing); + return this; + } + public OvernightLeg withGearings(List gearings) + { + gearings_ = gearings; + return this; + } + public OvernightLeg withSpreads(double spread) + { + spreads_ = new List(); spreads_.Add(spread); + return this; + } + public OvernightLeg withSpreads(List spreads) + { + spreads_ = spreads; + return this; + } + + public override List value() + { + return CashFlowVectors.OvernightLeg(notionals_, schedule_, paymentAdjustment_, overnightIndex_, gearings_, spreads_, paymentDayCounter_); + } + + private OvernightIndex overnightIndex_; + private List gearings_; + private List spreads_; + } } diff --git a/src/QLNet/Cashflows/Principal.cs b/src/QLNet/Cashflows/Principal.cs index df6656b6f..c2fb4e0a2 100644 --- a/src/QLNet/Cashflows/Principal.cs +++ b/src/QLNet/Cashflows/Principal.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -37,19 +37,19 @@ public class Principal : CashFlow public Date refPeriodStart { get { return refPeriodStart_; } } public Date refPeriodEnd { get { return refPeriodEnd_; } } public override double amount() { return amount_; } - public void setAmount( double amount ) { amount_ = amount; } + public void setAmount(double amount) { amount_ = amount; } public DayCounter dayCounter() { return dayCounter_; } // Constructors public Principal() { } // default constructor - public Principal(double amount, - double nominal, - Date paymentDate, - Date accrualStartDate, - Date accrualEndDate, - DayCounter dayCounter, - Date refPeriodStart = null , - Date refPeriodEnd = null ) + public Principal(double amount, + double nominal, + Date paymentDate, + Date accrualStartDate, + Date accrualEndDate, + DayCounter dayCounter, + Date refPeriodStart = null, + Date refPeriodEnd = null) { amount_ = amount; nominal_ = nominal; @@ -59,8 +59,10 @@ public Principal(double amount, refPeriodStart_ = refPeriodStart; refPeriodEnd_ = refPeriodEnd; dayCounter_ = dayCounter; - if (refPeriodStart_ == null) refPeriodStart_ = accrualStartDate_; - if (refPeriodEnd_ == null) refPeriodEnd_ = accrualEndDate_; + if (refPeriodStart_ == null) + refPeriodStart_ = accrualStartDate_; + if (refPeriodEnd_ == null) + refPeriodEnd_ = accrualEndDate_; } } } diff --git a/src/QLNet/Cashflows/PrincipalLegBase.cs b/src/QLNet/Cashflows/PrincipalLegBase.cs index cf6b3d220..a34ebaf25 100644 --- a/src/QLNet/Cashflows/PrincipalLegBase.cs +++ b/src/QLNet/Cashflows/PrincipalLegBase.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -117,8 +117,8 @@ public class BulletPricipalLeg : PrincipalLegBase // constructor public BulletPricipalLeg(Schedule schedule) { - schedule_ = schedule; - paymentAdjustment_ = BusinessDayConvention.Following; + schedule_ = schedule; + paymentAdjustment_ = BusinessDayConvention.Following; } // creator diff --git a/src/QLNet/Cashflows/RangeAccrual.cs b/src/QLNet/Cashflows/RangeAccrual.cs index f4a078e98..73ae7ae3d 100644 --- a/src/QLNet/Cashflows/RangeAccrual.cs +++ b/src/QLNet/Cashflows/RangeAccrual.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -35,19 +35,19 @@ public RangeAccrualFloatersCoupon(Date paymentDate, Schedule observationsSchedule, double lowerTrigger, double upperTrigger) - :base(paymentDate, nominal, startDate, endDate,fixingDays, index, gearing, spread,refPeriodStart, refPeriodEnd, - dayCounter) + : base(paymentDate, nominal, startDate, endDate, fixingDays, index, gearing, spread, refPeriodStart, refPeriodEnd, + dayCounter) { observationsSchedule_ = observationsSchedule; lowerTrigger_ = lowerTrigger; upperTrigger_ = upperTrigger; - Utils.QL_REQUIRE(lowerTrigger_ "lowerTrigger_>=upperTrigger"); - Utils.QL_REQUIRE(observationsSchedule_.startDate()==startDate,()=> "incompatible start date"); - Utils.QL_REQUIRE(observationsSchedule_.endDate()==endDate,()=> "incompatible end date"); + Utils.QL_REQUIRE(lowerTrigger_ "lowerTrigger_>=upperTrigger"); + Utils.QL_REQUIRE(observationsSchedule_.startDate() == startDate, () => "incompatible start date"); + Utils.QL_REQUIRE(observationsSchedule_.endDate() == endDate, () => "incompatible end date"); - observationDates_ = observationsSchedule_.dates(); - observationDates_.RemoveAt(observationDates_.Count-1); //remove end date + observationDates_ = new List(observationsSchedule_.dates()); + observationDates_.RemoveAt(observationDates_.Count - 1); //remove end date observationDates_.RemoveAt(0); //remove start date observationsNo_ = observationDates_.Count; @@ -57,46 +57,46 @@ public RangeAccrualFloatersCoupon(Date paymentDate, startTime_ = dayCounter.yearFraction(referenceDate, startDate); endTime_ = dayCounter.yearFraction(referenceDate, endDate); observationTimes_ = new List(); - for(int i=0;i observationDates() {return observationDates_;} - public List observationTimes() {return observationTimes_;} - public Schedule observationsSchedule() {return observationsSchedule_;} + public double startTime() {return startTime_; } + public double endTime() {return endTime_; } + public double lowerTrigger() {return lowerTrigger_; } + public double upperTrigger() {return upperTrigger_; } + public int observationsNo() {return observationsNo_; } + public List observationDates() {return observationDates_;} + public List observationTimes() {return observationTimes_;} + public Schedule observationsSchedule() {return observationsSchedule_;} - public double priceWithoutOptionality(Handle discountCurve) - { - return accrualPeriod() * (gearing_*indexFixing()+spread_) * - nominal() * discountCurve.link.discount(date()); - } + public double priceWithoutOptionality(Handle discountCurve) + { + return accrualPeriod() * (gearing_ * indexFixing() + spread_) * + nominal() * discountCurve.link.discount(date()); + } - - private double startTime_; - private double endTime_; - private Schedule observationsSchedule_; - private List observationDates_; - private List observationTimes_; - private int observationsNo_; + private double startTime_; + private double endTime_; - private double lowerTrigger_; - private double upperTrigger_; + private Schedule observationsSchedule_; + private List observationDates_; + private List observationTimes_; + private int observationsNo_; + + private double lowerTrigger_; + private double upperTrigger_; } - - public class RangeAccrualPricer: FloatingRateCouponPricer + + public class RangeAccrualPricer: FloatingRateCouponPricer { // Observer interface public override double swapletPrice() {throw new NotImplementedException();} - public override double swapletRate() {return swapletPrice()/(accrualFactor_*discount_);} + public override double swapletRate() {return swapletPrice() / (accrualFactor_ * discount_);} public override double capletPrice(double effectiveCap) { Utils.QL_FAIL("RangeAccrualPricer::capletPrice not implemented"); @@ -120,18 +120,18 @@ public override double floorletRate(double effectiveFloor) public override void initialize(FloatingRateCoupon coupon) { coupon_ = coupon as RangeAccrualFloatersCoupon; - Utils.QL_REQUIRE(coupon_!=null,()=> "range-accrual coupon required"); + Utils.QL_REQUIRE(coupon_ != null, () => "range-accrual coupon required"); gearing_ = coupon_.gearing(); spread_ = coupon_.spread(); Date paymentDate = coupon_.date(); IborIndex index = coupon_.index() as IborIndex; - Utils.QL_REQUIRE(index!=null,()=> "invalid index"); + Utils.QL_REQUIRE(index != null, () => "invalid index"); Handle rateCurve = index.forwardingTermStructure(); discount_ = rateCurve.link.discount(paymentDate); accrualFactor_ = coupon_.accrualPeriod(); - spreadLegValue_ = spread_*accrualFactor_*discount_; + spreadLegValue_ = spread_ * accrualFactor_ * discount_; startTime_ = coupon_.startTime(); endTime_ = coupon_.endTime(); @@ -141,14 +141,14 @@ public override void initialize(FloatingRateCoupon coupon) observationsNo_ = coupon_.observationsNo(); List observationDates = coupon_.observationsSchedule().dates(); - Utils.QL_REQUIRE(observationDates.Count == observationsNo_ + 2,()=> "incompatible size of initialValues vector"); + Utils.QL_REQUIRE(observationDates.Count == observationsNo_ + 2, () => "incompatible size of initialValues vector"); initialValues_ = new InitializedList(observationDates.Count, 0.0); Calendar calendar = index.fixingCalendar(); for (int i = 0; i < observationDates.Count; i++) { initialValues_[i] = index.fixing( - calendar.advance(observationDates[i],-coupon_.fixingDays,TimeUnit.Days)); + calendar.advance(observationDates[i], -coupon_.fixingDays, TimeUnit.Days)); } } @@ -168,8 +168,8 @@ public override void initialize(FloatingRateCoupon coupon) protected double spread_; protected double spreadLegValue_; } - - public class RangeAccrualPricerByBgm : RangeAccrualPricer + + public class RangeAccrualPricerByBgm : RangeAccrualPricer { public RangeAccrualPricerByBgm(double correlation, SmileSection smilesOnExpiry, @@ -188,100 +188,100 @@ public RangeAccrualPricerByBgm(double correlation, public override double swapletPrice() { double result = 0.0; - double deflator = discount_*initialValues_[0]; - for(int i=0;i 0 ? driftBeforeFixing : driftAfterFixing; } - protected double derDriftDerLambdaS(double U, double lambdaS, double lambdaT,double correlation) + protected double derDriftDerLambdaS(double U, double lambdaS, double lambdaT, double correlation) { - double p = (U - startTime_)/accrualFactor_; - double q = (endTime_ - U)/accrualFactor_; + double p = (U - startTime_) / accrualFactor_; + double q = (endTime_ - U) / accrualFactor_; double L0T = initialValues_.Last(); - double driftBeforeFixing = p*accrualFactor_*L0T/(1.0 + L0T*accrualFactor_) - *(q*lambdaT*correlation) + 2*q*lambdaS + p*lambdaT*correlation; + double driftBeforeFixing = p * accrualFactor_ * L0T / (1.0 + L0T * accrualFactor_) + * (q * lambdaT * correlation) + 2 * q * lambdaS + p * lambdaT * correlation; double driftAfterFixing = 0.0; return startTime_ > 0 ? driftBeforeFixing : driftAfterFixing; } - protected double derDriftDerLambdaT(double U, double lambdaS, double lambdaT,double correlation) + protected double derDriftDerLambdaT(double U, double lambdaS, double lambdaT, double correlation) { - double p = (U - startTime_)/accrualFactor_; - double q = (endTime_ - U)/accrualFactor_; + double p = (U - startTime_) / accrualFactor_; + double q = (endTime_ - U) / accrualFactor_; double L0T = initialValues_.Last(); - double driftBeforeFixing = p*accrualFactor_*L0T/(1.0 + L0T*accrualFactor_) - *(2*p*lambdaT + q*lambdaS*correlation) + +p*lambdaS*correlation; - double driftAfterFixing = (p*accrualFactor_*L0T/(1.0 + L0T*accrualFactor_) - 0.5) - *2*lambdaT; + double driftBeforeFixing = p * accrualFactor_ * L0T / (1.0 + L0T * accrualFactor_) + * (2 * p * lambdaT + q * lambdaS * correlation) + +p * lambdaS * correlation; + double driftAfterFixing = (p * accrualFactor_ * L0T / (1.0 + L0T * accrualFactor_) - 0.5) + * 2 * lambdaT; return startTime_ > 0 ? driftBeforeFixing : driftAfterFixing; } protected double lambda(double U, double lambdaS, double lambdaT) { - double p = (U - startTime_)/accrualFactor_; - double q = (endTime_ - U)/accrualFactor_; + double p = (U - startTime_) / accrualFactor_; + double q = (endTime_ - U) / accrualFactor_; - return startTime_ > 0 ? q*lambdaS + p*lambdaT : lambdaT; + return startTime_ > 0 ? q * lambdaS + p * lambdaT : lambdaT; } protected double derLambdaDerLambdaS(double U) { - return startTime_ > 0 ? (endTime_ - U)/accrualFactor_ : 0.0; + return startTime_ > 0 ? (endTime_ - U) / accrualFactor_ : 0.0; } protected double derLambdaDerLambdaT(double U) { - return startTime_ > 0 ? (U - startTime_)/accrualFactor_ : 0.0; + return startTime_ > 0 ? (U - startTime_) / accrualFactor_ : 0.0; } - protected List driftsOverPeriod(double U, double lambdaS, double lambdaT,double correlation) + protected List driftsOverPeriod(double U, double lambdaS, double lambdaT, double correlation) { List result = new List(); - double p = (U-startTime_)/accrualFactor_; - double q = (endTime_-U)/accrualFactor_; + double p = (U - startTime_) / accrualFactor_; + double q = (endTime_ - U) / accrualFactor_; double L0T = initialValues_.Last(); double driftBeforeFixing = - p*accrualFactor_*L0T/(1.0+L0T*accrualFactor_)*(p*lambdaT*lambdaT + q*lambdaS*lambdaT*correlation) + - q*lambdaS*lambdaS + p*lambdaS*lambdaT*correlation - -0.5*lambda(U,lambdaS,lambdaT)*lambda(U,lambdaS,lambdaT); - double driftAfterFixing = (p*accrualFactor_*L0T/(1.0+L0T*accrualFactor_)-0.5)*lambdaT*lambdaT; + p * accrualFactor_ * L0T / (1.0 + L0T * accrualFactor_) * (p * lambdaT * lambdaT + q * lambdaS * lambdaT * correlation) + + q * lambdaS * lambdaS + p * lambdaS * lambdaT * correlation + - 0.5 * lambda(U, lambdaS, lambdaT) * lambda(U, lambdaS, lambdaT); + double driftAfterFixing = (p * accrualFactor_ * L0T / (1.0 + L0T * accrualFactor_) - 0.5) * lambdaT * lambdaT; result.Add(driftBeforeFixing); result.Add(driftAfterFixing); return result; } - protected List lambdasOverPeriod(double U, double lambdaS,double lambdaT) + protected List lambdasOverPeriod(double U, double lambdaS, double lambdaT) { List result = new List(); - double p = (U - startTime_)/accrualFactor_; - double q = (endTime_ - U)/accrualFactor_; + double p = (U - startTime_) / accrualFactor_; + double q = (endTime_ - U) / accrualFactor_; - double lambdaBeforeFixing = q*lambdaS + p*lambdaT; + double lambdaBeforeFixing = q * lambdaS + p * lambdaT; double lambdaAfterFixing = lambdaT; result.Add(lambdaBeforeFixing); @@ -290,94 +290,94 @@ protected List lambdasOverPeriod(double U, double lambdaS,double lambdaT return result; } - protected double digitalRangePrice(double lowerTrigger,double upperTrigger,double initialValue,double expiry, - double deflator) + protected double digitalRangePrice(double lowerTrigger, double upperTrigger, double initialValue, double expiry, + double deflator) { double lowerPrice = digitalPrice(lowerTrigger, initialValue, expiry, deflator); double upperPrice = digitalPrice(upperTrigger, initialValue, expiry, deflator); double result = lowerPrice - upperPrice; - Utils.QL_REQUIRE(result > 0.0,()=> - "RangeAccrualPricerByBgm::digitalRangePrice:\n digitalPrice(" + upperTrigger + - "): " + upperPrice + " > digitalPrice(" + lowerTrigger + "): " + lowerPrice); + Utils.QL_REQUIRE(result > 0.0, () => + "RangeAccrualPricerByBgm::digitalRangePrice:\n digitalPrice(" + upperTrigger + + "): " + upperPrice + " > digitalPrice(" + lowerTrigger + "): " + lowerPrice); return result; } - protected double digitalPrice(double strike,double initialValue,double expiry,double deflator) + protected double digitalPrice(double strike, double initialValue, double expiry, double deflator) { double result = deflator; - if (strike > eps_/2) + if (strike > eps_ / 2) { - result = withSmile_ - ? digitalPriceWithSmile(strike, initialValue, expiry, deflator) - : digitalPriceWithoutSmile(strike, initialValue, expiry, deflator); + result = withSmile_ + ? digitalPriceWithSmile(strike, initialValue, expiry, deflator) + : digitalPriceWithoutSmile(strike, initialValue, expiry, deflator); } return result; } - protected double digitalPriceWithoutSmile(double strike,double initialValue,double expiry,double deflator) + protected double digitalPriceWithoutSmile(double strike, double initialValue, double expiry, double deflator) { double lambdaS = smilesOnExpiry_.volatility(strike); double lambdaT = smilesOnPayment_.volatility(strike); List lambdaU = lambdasOverPeriod(expiry, lambdaS, lambdaT); - double variance = startTime_*lambdaU[0]*lambdaU[0] + (expiry - startTime_)*lambdaU[1]*lambdaU[1]; + double variance = startTime_ * lambdaU[0] * lambdaU[0] + (expiry - startTime_) * lambdaU[1] * lambdaU[1]; double lambdaSATM = smilesOnExpiry_.volatility(initialValue); double lambdaTATM = smilesOnPayment_.volatility(initialValue); //drift of Lognormal process (of Libor) "a_U()" nel paper List muU = driftsOverPeriod(expiry, lambdaSATM, lambdaTATM, correlation_); - double adjustment = (startTime_*muU[0] + (expiry - startTime_)*muU[1]); + double adjustment = (startTime_ * muU[0] + (expiry - startTime_) * muU[1]); - double d2 = (Math.Log(initialValue/strike) + adjustment - 0.5*variance)/Math.Sqrt(variance); + double d2 = (Math.Log(initialValue / strike) + adjustment - 0.5 * variance) / Math.Sqrt(variance); CumulativeNormalDistribution phi = new CumulativeNormalDistribution(); - double result = deflator*phi.value(d2); + double result = deflator * phi.value(d2); - Utils.QL_REQUIRE(result > 0.0,()=> - "RangeAccrualPricerByBgm::digitalPriceWithoutSmile: result< 0. Result:" + result); - Utils.QL_REQUIRE(result/deflator <= 1.0,()=> - "RangeAccrualPricerByBgm::digitalPriceWithoutSmile: result/deflator > 1. Ratio: " - + result/deflator + " result: " + result + " deflator: " + deflator); + Utils.QL_REQUIRE(result > 0.0, () => + "RangeAccrualPricerByBgm::digitalPriceWithoutSmile: result< 0. Result:" + result); + Utils.QL_REQUIRE(result / deflator <= 1.0, () => + "RangeAccrualPricerByBgm::digitalPriceWithoutSmile: result/deflator > 1. Ratio: " + + result / deflator + " result: " + result + " deflator: " + deflator); return result; } - protected double digitalPriceWithSmile(double strike,double initialValue,double expiry,double deflator) + protected double digitalPriceWithSmile(double strike, double initialValue, double expiry, double deflator) { double result; if (byCallSpread_) { // Previous strike - double previousStrike = strike - eps_/2; + double previousStrike = strike - eps_ / 2; double lambdaS = smilesOnExpiry_.volatility(previousStrike); double lambdaT = smilesOnPayment_.volatility(previousStrike); //drift of Lognormal process (of Libor) "a_U()" nel paper List lambdaU = lambdasOverPeriod(expiry, lambdaS, lambdaT); - double previousVariance = Math.Max(startTime_, 0.0)*lambdaU[0]*lambdaU[0] + - Math.Min(expiry - startTime_, expiry)*lambdaU[1]*lambdaU[1]; + double previousVariance = Math.Max(startTime_, 0.0) * lambdaU[0] * lambdaU[0] + + Math.Min(expiry - startTime_, expiry) * lambdaU[1] * lambdaU[1]; double lambdaSATM = smilesOnExpiry_.volatility(initialValue); double lambdaTATM = smilesOnPayment_.volatility(initialValue); List muU = driftsOverPeriod(expiry, lambdaSATM, lambdaTATM, correlation_); - double previousAdjustment = Math.Exp(Math.Max(startTime_, 0.0)*muU[0] + - Math.Min(expiry - startTime_, expiry)*muU[1]); - double previousForward = initialValue*previousAdjustment; + double previousAdjustment = Math.Exp(Math.Max(startTime_, 0.0) * muU[0] + + Math.Min(expiry - startTime_, expiry) * muU[1]); + double previousForward = initialValue * previousAdjustment; // Next strike - double nextStrike = strike + eps_/2; + double nextStrike = strike + eps_ / 2; lambdaS = smilesOnExpiry_.volatility(nextStrike); lambdaT = smilesOnPayment_.volatility(nextStrike); lambdaU = lambdasOverPeriod(expiry, lambdaS, lambdaT); - double nextVariance = Math.Max(startTime_, 0.0)*lambdaU[0]*lambdaU[0] + - Math.Min(expiry - startTime_, expiry)*lambdaU[1]*lambdaU[1]; + double nextVariance = Math.Max(startTime_, 0.0) * lambdaU[0] * lambdaU[0] + + Math.Min(expiry - startTime_, expiry) * lambdaU[1] * lambdaU[1]; //drift of Lognormal process (of Libor) "a_U()" nel paper muU = driftsOverPeriod(expiry, lambdaSATM, lambdaTATM, correlation_); - double nextAdjustment = Math.Exp(Math.Max(startTime_, 0.0)*muU[0] + - Math.Min(expiry - startTime_, expiry)*muU[1]); - double nextForward = initialValue*nextAdjustment; + double nextAdjustment = Math.Exp(Math.Max(startTime_, 0.0) * muU[0] + + Math.Min(expiry - startTime_, expiry) * muU[1]); + double nextForward = initialValue * nextAdjustment; result = callSpreadPrice(previousForward, nextForward, previousStrike, nextStrike, deflator, previousVariance, nextVariance); @@ -388,11 +388,11 @@ protected double digitalPriceWithSmile(double strike,double initialValue,double smileCorrection(strike, initialValue, expiry, deflator); } - Utils.QL_REQUIRE(result > -Math.Pow(eps_, .5),()=> - "RangeAccrualPricerByBgm::digitalPriceWithSmile: result< 0 Result:" + result); - Utils.QL_REQUIRE(result/deflator <= 1.0 + Math.Pow(eps_, .2),()=> - "RangeAccrualPricerByBgm::digitalPriceWithSmile: result/deflator > 1. Ratio: " - + result/deflator + " result: " + result + " deflator: " + deflator); + Utils.QL_REQUIRE(result > -Math.Pow(eps_, .5), () => + "RangeAccrualPricerByBgm::digitalPriceWithSmile: result< 0 Result:" + result); + Utils.QL_REQUIRE(result / deflator <= 1.0 + Math.Pow(eps_, .2), () => + "RangeAccrualPricerByBgm::digitalPriceWithSmile: result/deflator > 1. Ratio: " + + result / deflator + " result: " + result + " deflator: " + deflator); return result; } @@ -405,19 +405,19 @@ protected double callSpreadPrice(double previousForward, double previousVariance, double nextVariance) { - double nextCall = Utils.blackFormula(Option.Type.Call, nextStrike, nextForward, - Math.Sqrt(nextVariance), deflator); - double previousCall = Utils.blackFormula(Option.Type.Call, previousStrike, previousForward, - Math.Sqrt(previousVariance), deflator); + double nextCall = Utils.blackFormula(Option.Type.Call, nextStrike, nextForward, + Math.Sqrt(nextVariance), deflator); + double previousCall = Utils.blackFormula(Option.Type.Call, previousStrike, previousForward, + Math.Sqrt(previousVariance), deflator); - Utils.QL_REQUIRE(nextCall - "RangeAccrualPricerByBgm::callSpreadPrice: nextCall > previousCall" + - "\n nextCall: strike :" + nextStrike + "; variance: " + nextVariance + - " adjusted initial value " + nextForward + - "\n previousCall: strike :" + previousStrike + "; variance: " + previousVariance + - " adjusted initial value " + previousForward ); + Utils.QL_REQUIRE(nextCall + "RangeAccrualPricerByBgm::callSpreadPrice: nextCall > previousCall" + + "\n nextCall: strike :" + nextStrike + "; variance: " + nextVariance + + " adjusted initial value " + nextForward + + "\n previousCall: strike :" + previousStrike + "; variance: " + previousVariance + + " adjusted initial value " + previousForward); - return (previousCall-nextCall)/(nextStrike-previousStrike); + return (previousCall - nextCall) / (nextStrike - previousStrike); } protected double smileCorrection(double strike, @@ -425,13 +425,13 @@ protected double smileCorrection(double strike, double expiry, double deflator) { - double previousStrike = strike - eps_/2; - double nextStrike = strike + eps_/2; + double previousStrike = strike - eps_ / 2; + double nextStrike = strike + eps_ / 2; - double derSmileS = (smilesOnExpiry_.volatility(nextStrike) - - smilesOnExpiry_.volatility(previousStrike))/eps_; - double derSmileT = (smilesOnPayment_.volatility(nextStrike) - - smilesOnPayment_.volatility(previousStrike))/eps_; + double derSmileS = (smilesOnExpiry_.volatility(nextStrike) - + smilesOnExpiry_.volatility(previousStrike)) / eps_; + double derSmileT = (smilesOnPayment_.volatility(nextStrike) - + smilesOnPayment_.volatility(previousStrike)) / eps_; double lambdaS = smilesOnExpiry_.volatility(strike); double lambdaT = smilesOnPayment_.volatility(strike); @@ -446,32 +446,32 @@ protected double smileCorrection(double strike, //drift of Lognormal process (of Libor) "a_U()" nel paper List muU = driftsOverPeriod(expiry, lambdaSATM, lambdaTATM, correlation_); - double variance = Math.Max(startTime_, 0.0)*lambdasOverPeriodU[0]*lambdasOverPeriodU[0] + - Math.Min(expiry - startTime_, expiry)*lambdasOverPeriodU[1]*lambdasOverPeriodU[1]; + double variance = Math.Max(startTime_, 0.0) * lambdasOverPeriodU[0] * lambdasOverPeriodU[0] + + Math.Min(expiry - startTime_, expiry) * lambdasOverPeriodU[1] * lambdasOverPeriodU[1]; - double forwardAdjustment = Math.Exp(Math.Max(startTime_, 0.0)*muU[0] + - Math.Min(expiry - startTime_, expiry)*muU[1]); - double forwardAdjusted = forward*forwardAdjustment; + double forwardAdjustment = Math.Exp(Math.Max(startTime_, 0.0) * muU[0] + + Math.Min(expiry - startTime_, expiry) * muU[1]); + double forwardAdjusted = forward * forwardAdjustment; - double d1 = (Math.Log(forwardAdjusted/strike) + 0.5*variance)/Math.Sqrt(variance); + double d1 = (Math.Log(forwardAdjusted / strike) + 0.5 * variance) / Math.Sqrt(variance); - double sqrtOfTimeToExpiry = (Math.Max(startTime_, 0.0)*lambdasOverPeriodU[0] + - Math.Min(expiry - startTime_, expiry)*lambdasOverPeriodU[1])*(1.0/Math.Sqrt(variance)); + double sqrtOfTimeToExpiry = (Math.Max(startTime_, 0.0) * lambdasOverPeriodU[0] + + Math.Min(expiry - startTime_, expiry) * lambdasOverPeriodU[1]) * (1.0 / Math.Sqrt(variance)); CumulativeNormalDistribution phi = new CumulativeNormalDistribution(); NormalDistribution psi = new NormalDistribution(); - double result = -forwardAdjusted*psi.value(d1)*sqrtOfTimeToExpiry*derLambdaDerK; + double result = -forwardAdjusted * psi.value(d1) * sqrtOfTimeToExpiry * derLambdaDerK; result *= deflator; - Utils.QL_REQUIRE(Math.Abs(result/deflator) <= 1.0 + Math.Pow(eps_, .2),()=> - "RangeAccrualPricerByBgm::smileCorrection: abs(result/deflator) > 1. Ratio: " - + result/deflator + " result: " + result + " deflator: " + deflator); + Utils.QL_REQUIRE(Math.Abs(result / deflator) <= 1.0 + Math.Pow(eps_, .2), () => + "RangeAccrualPricerByBgm::smileCorrection: abs(result/deflator) > 1. Ratio: " + + result / deflator + " result: " + result + " deflator: " + deflator); return result; } - + private double correlation_; // correlation between L(S) and L(T) private bool withSmile_; private bool byCallSpread_; @@ -480,9 +480,9 @@ protected double smileCorrection(double strike, private SmileSection smilesOnPayment_; private double eps_; } - + //! helper class building a sequence of range-accrual floating-rate coupons - public class RangeAccrualLeg + public class RangeAccrualLeg { public RangeAccrualLeg(Schedule schedule, IborIndex index) { @@ -493,7 +493,7 @@ public RangeAccrualLeg(Schedule schedule, IborIndex index) } public RangeAccrualLeg withNotionals(double notional) { - notionals_ = new InitializedList(1,notional); + notionals_ = new InitializedList(1, notional); return this; } public RangeAccrualLeg withNotionals(List notionals) @@ -513,7 +513,7 @@ public RangeAccrualLeg withPaymentAdjustment(BusinessDayConvention convention) } public RangeAccrualLeg withFixingDays(int fixingDays) { - fixingDays_ = new InitializedList(1,fixingDays); + fixingDays_ = new InitializedList(1, fixingDays); return this; } public RangeAccrualLeg withFixingDays(List fixingDays) @@ -523,7 +523,7 @@ public RangeAccrualLeg withFixingDays(List fixingDays) } public RangeAccrualLeg withGearings(double gearing) { - gearings_ = new InitializedList(1,gearing); + gearings_ = new InitializedList(1, gearing); return this; } public RangeAccrualLeg withGearings(List gearings) @@ -533,7 +533,7 @@ public RangeAccrualLeg withGearings(List gearings) } public RangeAccrualLeg withSpreads(double spread) { - spreads_ = new InitializedList(1,spread); + spreads_ = new InitializedList(1, spread); return this; } public RangeAccrualLeg withSpreads(List spreads) @@ -543,7 +543,7 @@ public RangeAccrualLeg withSpreads(List spreads) } public RangeAccrualLeg withLowerTriggers(double trigger) { - lowerTriggers_ = new InitializedList(1,trigger); + lowerTriggers_ = new InitializedList(1, trigger); return this; } public RangeAccrualLeg withLowerTriggers(List triggers) @@ -553,7 +553,7 @@ public RangeAccrualLeg withLowerTriggers(List triggers) } public RangeAccrualLeg withUpperTriggers(double trigger) { - upperTriggers_ = new InitializedList(1,trigger); + upperTriggers_ = new InitializedList(1, trigger); return this; } public RangeAccrualLeg withUpperTriggers(List triggers) @@ -573,24 +573,24 @@ public RangeAccrualLeg withObservationConvention(BusinessDayConvention conventio } public List Leg() { - Utils.QL_REQUIRE(!notionals_.empty(),()=> "no notional given"); + Utils.QL_REQUIRE(!notionals_.empty(), () => "no notional given"); int n = schedule_.Count - 1; - Utils.QL_REQUIRE(notionals_.Count <= n,()=> - "too many nominals (" + notionals_.Count + "), only " + n + " required"); - Utils.QL_REQUIRE(fixingDays_.Count <= n,()=> - "too many fixingDays (" + fixingDays_.Count + "), only " + n + " required"); - Utils.QL_REQUIRE(gearings_.Count <= n,()=> - "too many gearings (" + gearings_.Count + "), only " + n + " required"); - Utils.QL_REQUIRE(spreads_.Count<= n,()=> - "too many spreads (" + spreads_.Count + "), only " + n + " required"); - Utils.QL_REQUIRE(lowerTriggers_.Count <= n,()=> - "too many lowerTriggers (" + lowerTriggers_.Count + "), only " + n + " required"); - Utils.QL_REQUIRE(upperTriggers_.Count <= n,()=> - "too many upperTriggers (" + upperTriggers_.Count + "), only " + n + " required"); - - List leg = new List(); - + Utils.QL_REQUIRE(notionals_.Count <= n, () => + "too many nominals (" + notionals_.Count + "), only " + n + " required"); + Utils.QL_REQUIRE(fixingDays_.Count <= n, () => + "too many fixingDays (" + fixingDays_.Count + "), only " + n + " required"); + Utils.QL_REQUIRE(gearings_.Count <= n, () => + "too many gearings (" + gearings_.Count + "), only " + n + " required"); + Utils.QL_REQUIRE(spreads_.Count <= n, () => + "too many spreads (" + spreads_.Count + "), only " + n + " required"); + Utils.QL_REQUIRE(lowerTriggers_.Count <= n, () => + "too many lowerTriggers (" + lowerTriggers_.Count + "), only " + n + " required"); + Utils.QL_REQUIRE(upperTriggers_.Count <= n, () => + "too many upperTriggers (" + upperTriggers_.Count + "), only " + n + " required"); + + List leg = new List(); + // the following is not always correct Calendar calendar = schedule_.calendar(); @@ -617,40 +617,40 @@ public List Leg() if (Utils.Get(gearings_, i, 1.0).IsEqual(0.0)) { // fixed coupon - leg.Add( new FixedRateCoupon(paymentDate, - Utils.Get(notionals_, i), - Utils.Get(spreads_, i, 0.0), - paymentDayCounter_, - start, end, refStart, refEnd)); + leg.Add(new FixedRateCoupon(paymentDate, + Utils.Get(notionals_, i), + Utils.Get(spreads_, i, 0.0), + paymentDayCounter_, + start, end, refStart, refEnd)); } else { // floating coupon - observationsSchedules.Add( new Schedule(start, end, - observationTenor_, calendar, - observationConvention_, - observationConvention_, - DateGeneration.Rule.Forward, false)); - - leg.Add( new RangeAccrualFloatersCoupon(paymentDate, - Utils.Get(notionals_, i), - index_, - start, end, - Utils.Get(fixingDays_, i, 2), - paymentDayCounter_, - Utils.Get(gearings_, i, 1.0), - Utils.Get(spreads_, i, 0.0), - refStart, refEnd, - observationsSchedules.Last(), - Utils.Get(lowerTriggers_, i), - Utils.Get(upperTriggers_, i))); + observationsSchedules.Add(new Schedule(start, end, + observationTenor_, calendar, + observationConvention_, + observationConvention_, + DateGeneration.Rule.Forward, false)); + + leg.Add(new RangeAccrualFloatersCoupon(paymentDate, + Utils.Get(notionals_, i), + index_, + start, end, + Utils.Get(fixingDays_, i, 2), + paymentDayCounter_, + Utils.Get(gearings_, i, 1.0), + Utils.Get(spreads_, i, 0.0), + refStart, refEnd, + observationsSchedules.Last(), + Utils.Get(lowerTriggers_, i), + Utils.Get(upperTriggers_, i))); } } return leg; - + } - - + + private Schedule schedule_; private IborIndex index_; private List notionals_; @@ -662,5 +662,5 @@ public List Leg() private List lowerTriggers_, upperTriggers_; private Period observationTenor_; private BusinessDayConvention observationConvention_; - } + } } diff --git a/src/QLNet/Cashflows/RateLegBase.cs b/src/QLNet/Cashflows/RateLegBase.cs index 516c6d4c4..cff1447c0 100644 --- a/src/QLNet/Cashflows/RateLegBase.cs +++ b/src/QLNet/Cashflows/RateLegBase.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -63,8 +63,8 @@ public abstract class FloatingLegBase : RateLegBase protected List gearings_; protected List spreads_; - protected List caps_ = new List(); - protected List floors_ = new List(); + protected List < double? > caps_ = new List < double? >(); + protected List < double? > floors_ = new List < double? >(); protected bool inArrears_; protected bool zeroPayments_; @@ -113,11 +113,11 @@ public FloatingLegBase withSpreads(List spreads) public FloatingLegBase withCaps(double? cap) { - caps_ = new List() {cap}; + caps_ = new List < double? >() {cap}; return this; } - public FloatingLegBase withCaps(List caps) + public FloatingLegBase withCaps(List < double? > caps) { caps_ = caps; return this; @@ -125,11 +125,11 @@ public FloatingLegBase withCaps(List caps) public FloatingLegBase withFloors(double? floor) { - floors_ = new List() {floor}; + floors_ = new List < double? >() {floor}; return this; } - public FloatingLegBase withFloors(List floors) + public FloatingLegBase withFloors(List < double? > floors) { floors_ = floors; return this; @@ -207,12 +207,12 @@ public yoyInflationLegBase withSpreads(List spreads) public yoyInflationLegBase withCaps(double cap) { - caps_ = new List(); + caps_ = new List < double? >(); caps_.Add(cap); return this; } - public yoyInflationLegBase withCaps(List caps) + public yoyInflationLegBase withCaps(List < double? > caps) { caps_ = caps; return this; @@ -220,12 +220,12 @@ public yoyInflationLegBase withCaps(List caps) public yoyInflationLegBase withFloors(double floor) { - floors_ = new List(); + floors_ = new List < double? >(); floors_.Add(floor); return this; } - public yoyInflationLegBase withFloors(List floors) + public yoyInflationLegBase withFloors(List < double? > floors) { floors_ = floors; return this; @@ -237,9 +237,9 @@ public yoyInflationLegBase withFloors(List floors) protected List fixingDays_; protected List gearings_; protected List spreads_; - protected List caps_, floors_; + protected List < double? > caps_, floors_; - } + } public abstract class CPILegBase : RateLegBase { @@ -251,7 +251,7 @@ public CPILegBase withObservationInterpolation(InterpolationType interp) public CPILegBase withFixedRates(double fixedRate) { - fixedRates_ = new List() { fixedRate }; + fixedRates_ = new List() { fixedRate }; return this; } @@ -279,7 +279,7 @@ public CPILegBase withPaymentCalendar(Calendar cal) return this; } - + public CPILegBase withFixingDays(int fixingDays) { fixingDays_ = new List() { fixingDays }; @@ -306,11 +306,11 @@ public CPILegBase withSpreads(List spreads) public CPILegBase withCaps(double cap) { - caps_ = new List() { cap }; + caps_ = new List < double? >() { cap }; return this; } - public CPILegBase withCaps(List cap) + public CPILegBase withCaps(List < double? > cap) { caps_ = cap; return this; @@ -318,11 +318,11 @@ public CPILegBase withCaps(List cap) public CPILegBase withFloors(double floors) { - floors_ = new List() { floors }; + floors_ = new List < double? >() { floors }; return this; } - public CPILegBase withFloors(List floors) + public CPILegBase withFloors(List < double? > floors) { floors_ = floors; return this; @@ -345,9 +345,9 @@ public CPILegBase withExCouponPeriod(Period period, Calendar cal, BusinessDayCon protected InterpolationType observationInterpolation_; protected bool subtractInflationNominal_; protected List spreads_; - protected List caps_, floors_; + protected List < double? > caps_, floors_; protected Calendar paymentCalendar_; - + protected Period exCouponPeriod_; protected Calendar exCouponCalendar_; protected BusinessDayConvention exCouponAdjustment_; diff --git a/src/QLNet/Cashflows/Replication.cs b/src/QLNet/Cashflows/Replication.cs index 522d5d568..66d9aa94f 100644 --- a/src/QLNet/Cashflows/Replication.cs +++ b/src/QLNet/Cashflows/Replication.cs @@ -2,51 +2,52 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { +namespace QLNet +{ - //! Digital option replication strategy + //! Digital option replication strategy // ! Specification of replication strategies used to price // the embedded digital option in a digital coupon. -// - public struct Replication - { - public enum Type - { - Sub, - Central, - Super - } - } - - public class DigitalReplication - { +// + public struct Replication + { + public enum Type + { + Sub, + Central, + Super + } + } + + public class DigitalReplication + { private double gap_; private Replication.Type replicationType_; public DigitalReplication(Replication.Type t = Replication.Type.Central, double gap = 1e-4) - { + { gap_ = gap; - replicationType_ = t; - } + replicationType_ = t; + } public Replication.Type replicationType() { return replicationType_; } public double gap() { return gap_; } - } + } } diff --git a/src/QLNet/Cashflows/SimpleCashFlow.cs b/src/QLNet/Cashflows/SimpleCashFlow.cs index 05f970927..c2f6c9293 100644 --- a/src/QLNet/Cashflows/SimpleCashFlow.cs +++ b/src/QLNet/Cashflows/SimpleCashFlow.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,7 +22,7 @@ under the terms of the QLNet license. You should have received a namespace QLNet { //! Predetermined cash flow - /*! This cash flow pays a predetermined amount at a given date. */ + /*! This cash flow pays a predetermined amount at a given date. */ public class SimpleCashFlow : CashFlow { private double amount_; @@ -32,36 +32,36 @@ public class SimpleCashFlow : CashFlow public SimpleCashFlow(double amount, Date date) { - Utils.QL_REQUIRE(date != null,()=>"null date SimpleCashFlow"); + Utils.QL_REQUIRE(date != null, () => "null date SimpleCashFlow"); amount_ = amount; date_ = date; } } //! Bond redemption - /*! This class specializes SimpleCashFlow so that visitors - can perform more detailed cash-flow analysis. - */ - public class Redemption : SimpleCashFlow - { - public Redemption(double amount, Date date) : base(amount, date) { } - } + /*! This class specializes SimpleCashFlow so that visitors + can perform more detailed cash-flow analysis. + */ + public class Redemption : SimpleCashFlow + { + public Redemption(double amount, Date date) : base(amount, date) { } + } - //! Amortizing payment - /*! This class specializes SimpleCashFlow so that visitors - can perform more detailed cash-flow analysis. - */ - public class AmortizingPayment : SimpleCashFlow - { - public AmortizingPayment(double amount, Date date) : base(amount, date) { } - } + //! Amortizing payment + /*! This class specializes SimpleCashFlow so that visitors + can perform more detailed cash-flow analysis. + */ + public class AmortizingPayment : SimpleCashFlow + { + public AmortizingPayment(double amount, Date date) : base(amount, date) { } + } - //! Voluntary Prepay - /*! This class specializes SimpleCashFlow so that visitors - can perform more detailed cash-flow analysis. - */ - public class VoluntaryPrepay : SimpleCashFlow - { - public VoluntaryPrepay(double amount, Date date) : base(amount, date) { } - } + //! Voluntary Prepay + /*! This class specializes SimpleCashFlow so that visitors + can perform more detailed cash-flow analysis. + */ + public class VoluntaryPrepay : SimpleCashFlow + { + public VoluntaryPrepay(double amount, Date date) : base(amount, date) { } + } } diff --git a/src/QLNet/Cashflows/YoYInflationCoupon.cs b/src/QLNet/Cashflows/YoYInflationCoupon.cs index e740f8154..9b5c1f9ae 100644 --- a/src/QLNet/Cashflows/YoYInflationCoupon.cs +++ b/src/QLNet/Cashflows/YoYInflationCoupon.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -34,16 +34,16 @@ public YoYInflationCoupon(Date paymentDate, double gearing = 1.0, double spread = 0.0, Date refPeriodStart = null, - Date refPeriodEnd = null ) - :base(paymentDate, nominal, startDate, endDate, - fixingDays, yoyIndex, observationLag, - dayCounter, refPeriodStart, refPeriodEnd) + Date refPeriodEnd = null) + : base(paymentDate, nominal, startDate, endDate, + fixingDays, yoyIndex, observationLag, + dayCounter, refPeriodStart, refPeriodEnd) { - yoyIndex_ = yoyIndex; + yoyIndex_ = yoyIndex; gearing_ = gearing; spread_ = spread; } - + // Inspectors // index gearing, i.e. multiplicative coefficient for the index public double gearing() { return gearing_; } @@ -67,7 +67,7 @@ protected override bool checkPricerImpl(InflationCouponPricer i) //! payoff is: spread + gearing x index public class yoyInflationLeg : yoyInflationLegBase { - public yoyInflationLeg(Schedule schedule,Calendar cal, + public yoyInflationLeg(Schedule schedule, Calendar cal, YoYInflationIndex index, Period observationLag) { @@ -81,19 +81,19 @@ public yoyInflationLeg(Schedule schedule,Calendar cal, public override List value() { - return CashFlowVectors.yoyInflationLeg(notionals_, - schedule_, - paymentAdjustment_, - index_, - gearings_, - spreads_, + return CashFlowVectors.yoyInflationLeg(notionals_, + schedule_, + paymentAdjustment_, + index_, + gearings_, + spreads_, paymentDayCounter_, - caps_, - floors_ , + caps_, + floors_, paymentCalendar_, fixingDays_, observationLag_); } - }; + } } diff --git a/src/QLNet/Currencies/Africa.cs b/src/QLNet/Currencies/Africa.cs index fff9e8acf..93022a2de 100644 --- a/src/QLNet/Currencies/Africa.cs +++ b/src/QLNet/Currencies/Africa.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Andrea Maggiulli - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,13 +19,13 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - /// - /// South-African rand - /// The ISO three-letter code is ZAR; the numeric code is 710. - /// It is divided into 100 cents. - /// - public class ZARCurrency : Currency - { - public ZARCurrency() : base("South-African rand", "ZAR", 710, "R", "", 100, new Rounding(), "%3% %1$.2f") { } - } + /// + /// South-African rand + /// The ISO three-letter code is ZAR; the numeric code is 710. + /// It is divided into 100 cents. + /// + public class ZARCurrency : Currency + { + public ZARCurrency() : base("South-African rand", "ZAR", 710, "R", "", 100, new Rounding(), "%3% %1$.2f") { } + } } diff --git a/src/QLNet/Currencies/America.cs b/src/QLNet/Currencies/America.cs index 15f0fced4..3d295d4aa 100644 --- a/src/QLNet/Currencies/America.cs +++ b/src/QLNet/Currencies/America.cs @@ -2,18 +2,18 @@ Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,130 +21,142 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! Argentinian peso - // ! The ISO three-letter code is ARS; the numeric code is 32. - // It is divided in 100 centavos. - // - // \ingroup currencies - // - public class ARSCurrency : Currency { - public ARSCurrency() : base("Argentinian peso", "ARS", 32, "", "", 100, new Rounding(), "%2% %1$.2f") { } - } - - //! Brazilian real - // ! The ISO three-letter code is BRL; the numeric code is 986. - // It is divided in 100 centavos. - // - // \ingroup currencies - // - public class BRLCurrency : Currency { - public BRLCurrency() : base("Brazilian real", "BRL", 986, "R$", "", 100, new Rounding(), "%3% %1$.2f") { } - } - - //! Canadian dollar - // ! The ISO three-letter code is CAD; the numeric code is 124. - // It is divided into 100 cents. - // - // \ingroup currencies - // - public class CADCurrency : Currency { - public CADCurrency() : base("Canadian dollar", "CAD", 124, "Can$", "", 100, new Rounding(), "%3% %1$.2f") { } - } - - //! Chilean peso - // ! The ISO three-letter code is CLP; the numeric code is 152. - // It is divided in 100 centavos. - // - // \ingroup currencies - // - public class CLPCurrency : Currency { - public CLPCurrency() : base("Chilean peso", "CLP", 152, "Ch$", "", 100, new Rounding(), "%3% %1$.0f") { } - } - - //! Colombian peso - // ! The ISO three-letter code is COP; the numeric code is 170. - // It is divided in 100 centavos. - // - // \ingroup currencies - // - public class COPCurrency : Currency { - public COPCurrency() : base("Colombian peso", "COP", 170, "Col$", "", 100, new Rounding(), "%3% %1$.2f") { } - } - - //! Mexican peso - // ! The ISO three-letter code is MXN; the numeric code is 484. - // It is divided in 100 centavos. - // - // \ingroup currencies - // - public class MXNCurrency : Currency { - public MXNCurrency() : base("Mexican peso", "MXN", 484, "Mex$", "", 100, new Rounding(), "%3% %1$.2f") { } - } - - //! Peruvian nuevo sol - // ! The ISO three-letter code is PEN; the numeric code is 604. - // It is divided in 100 centimos. - // - // \ingroup currencies - // - public class PENCurrency : Currency { - public PENCurrency() : base("Peruvian nuevo sol", "PEN", 604, "S/.", "", 100, new Rounding(), "%3% %1$.2f") { } - } - - //! Peruvian inti - // ! The ISO three-letter code was PEI. - // It was divided in 100 centimos. A numeric code is not available - // as per ISO 3166-1, we assign 998 as a user-defined code. - // - // Obsoleted by the nuevo sol since July 1991. - // - // \ingroup currencies - // - public class PEICurrency : Currency { - public PEICurrency() : base("Peruvian inti", "PEI", 998, "I/.", "", 100, new Rounding(), "%3% %1$.2f") { } - } - - //! Peruvian sol - // ! The ISO three-letter code was PEH. A numeric code is not available - // as per ISO 3166-1, we assign 999 as a user-defined code. - // It was divided in 100 centavos. - // - // Obsoleted by the inti since February 1985. - // - // \ingroup currencies - // - public class PEHCurrency : Currency { - public PEHCurrency() : base("Peruvian sol", "PEH", 999, "S./", "", 100, new Rounding(), "%3% %1$.2f") { } - } - - //! Trinidad & Tobago dollar - // ! The ISO three-letter code is TTD; the numeric code is 780. - // It is divided in 100 cents. - // - // \ingroup currencies - // - public class TTDCurrency : Currency { - public TTDCurrency() : base("Trinidad & Tobago dollar", "TTD", 780, "TT$", "", 100, new Rounding(), "%3% %1$.2f") { } - } - - //! U.S. dollar - // ! The ISO three-letter code is USD; the numeric code is 840. - // It is divided in 100 cents. - // - // \ingroup currencies - // - public class USDCurrency : Currency { - public USDCurrency() : base("U.S. dollar", "USD", 840, "$", "\xA2", 100, new Rounding(), "%3% %1$.2f") { } - } - - //! Venezuelan bolivar - // ! The ISO three-letter code is VEB; the numeric code is 862. - // It is divided in 100 centimos. - // - // \ingroup currencies - // - public class VEBCurrency : Currency { - public VEBCurrency() : base("Venezuelan bolivar", "VEB", 862, "Bs", "", 100, new Rounding(), "%3% %1$.2f") { } - } + //! Argentinian peso + // ! The ISO three-letter code is ARS; the numeric code is 32. + // It is divided in 100 centavos. + // + // \ingroup currencies + // + public class ARSCurrency : Currency + { + public ARSCurrency() : base("Argentinian peso", "ARS", 32, "", "", 100, new Rounding(), "%2% %1$.2f") { } + } + + //! Brazilian real + // ! The ISO three-letter code is BRL; the numeric code is 986. + // It is divided in 100 centavos. + // + // \ingroup currencies + // + public class BRLCurrency : Currency + { + public BRLCurrency() : base("Brazilian real", "BRL", 986, "R$", "", 100, new Rounding(), "%3% %1$.2f") { } + } + + //! Canadian dollar + // ! The ISO three-letter code is CAD; the numeric code is 124. + // It is divided into 100 cents. + // + // \ingroup currencies + // + public class CADCurrency : Currency + { + public CADCurrency() : base("Canadian dollar", "CAD", 124, "Can$", "", 100, new Rounding(), "%3% %1$.2f") { } + } + + //! Chilean peso + // ! The ISO three-letter code is CLP; the numeric code is 152. + // It is divided in 100 centavos. + // + // \ingroup currencies + // + public class CLPCurrency : Currency + { + public CLPCurrency() : base("Chilean peso", "CLP", 152, "Ch$", "", 100, new Rounding(), "%3% %1$.0f") { } + } + + //! Colombian peso + // ! The ISO three-letter code is COP; the numeric code is 170. + // It is divided in 100 centavos. + // + // \ingroup currencies + // + public class COPCurrency : Currency + { + public COPCurrency() : base("Colombian peso", "COP", 170, "Col$", "", 100, new Rounding(), "%3% %1$.2f") { } + } + + //! Mexican peso + // ! The ISO three-letter code is MXN; the numeric code is 484. + // It is divided in 100 centavos. + // + // \ingroup currencies + // + public class MXNCurrency : Currency + { + public MXNCurrency() : base("Mexican peso", "MXN", 484, "Mex$", "", 100, new Rounding(), "%3% %1$.2f") { } + } + + //! Peruvian nuevo sol + // ! The ISO three-letter code is PEN; the numeric code is 604. + // It is divided in 100 centimos. + // + // \ingroup currencies + // + public class PENCurrency : Currency + { + public PENCurrency() : base("Peruvian nuevo sol", "PEN", 604, "S/.", "", 100, new Rounding(), "%3% %1$.2f") { } + } + + //! Peruvian inti + // ! The ISO three-letter code was PEI. + // It was divided in 100 centimos. A numeric code is not available + // as per ISO 3166-1, we assign 998 as a user-defined code. + // + // Obsoleted by the nuevo sol since July 1991. + // + // \ingroup currencies + // + public class PEICurrency : Currency + { + public PEICurrency() : base("Peruvian inti", "PEI", 998, "I/.", "", 100, new Rounding(), "%3% %1$.2f") { } + } + + //! Peruvian sol + // ! The ISO three-letter code was PEH. A numeric code is not available + // as per ISO 3166-1, we assign 999 as a user-defined code. + // It was divided in 100 centavos. + // + // Obsoleted by the inti since February 1985. + // + // \ingroup currencies + // + public class PEHCurrency : Currency + { + public PEHCurrency() : base("Peruvian sol", "PEH", 999, "S./", "", 100, new Rounding(), "%3% %1$.2f") { } + } + + //! Trinidad & Tobago dollar + // ! The ISO three-letter code is TTD; the numeric code is 780. + // It is divided in 100 cents. + // + // \ingroup currencies + // + public class TTDCurrency : Currency + { + public TTDCurrency() : base("Trinidad & Tobago dollar", "TTD", 780, "TT$", "", 100, new Rounding(), "%3% %1$.2f") { } + } + + //! U.S. dollar + // ! The ISO three-letter code is USD; the numeric code is 840. + // It is divided in 100 cents. + // + // \ingroup currencies + // + public class USDCurrency : Currency + { + public USDCurrency() : base("U.S. dollar", "USD", 840, "$", "\xA2", 100, new Rounding(), "%3% %1$.2f") { } + } + + //! Venezuelan bolivar + // ! The ISO three-letter code is VEB; the numeric code is 862. + // It is divided in 100 centimos. + // + // \ingroup currencies + // + public class VEBCurrency : Currency + { + public VEBCurrency() : base("Venezuelan bolivar", "VEB", 862, "Bs", "", 100, new Rounding(), "%3% %1$.2f") { } + } } diff --git a/src/QLNet/Currencies/Asia.cs b/src/QLNet/Currencies/Asia.cs index 9600e0d77..9903cc21e 100644 --- a/src/QLNet/Currencies/Asia.cs +++ b/src/QLNet/Currencies/Asia.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Andrea Maggiulli - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,9 +24,9 @@ namespace QLNet It is divided in 100 paisa. \ingroup currencies */ - public class BDTCurrency : Currency + public class BDTCurrency : Currency { - public BDTCurrency() : base("Bangladesh taka", "BDT", 50,"Bt", "", 100,new Rounding(), "%3% %1$.2f"){} + public BDTCurrency() : base("Bangladesh taka", "BDT", 50, "Bt", "", 100, new Rounding(), "%3% %1$.2f") {} } //! Chinese yuan @@ -35,9 +35,9 @@ It is divided in 100 fen. \ingroup currencies */ - public class CNYCurrency : Currency + public class CNYCurrency : Currency { - public CNYCurrency() :base("Chinese yuan", "CNY", 156, "Y", "", 100, new Rounding(), "%3% %1$.2f"){} + public CNYCurrency() : base("Chinese yuan", "CNY", 156, "Y", "", 100, new Rounding(), "%3% %1$.2f") {} } //! Hong Kong dollar @@ -46,20 +46,20 @@ It is divided in 100 cents. \ingroup currencies */ - public class HKDCurrency : Currency + public class HKDCurrency : Currency { - public HKDCurrency() : base( "Hong Kong dollar", "HKD", 344, "HK$", "", 100, new Rounding(), "%3% %1$.2f" ) { } + public HKDCurrency() : base("Hong Kong dollar", "HKD", 344, "HK$", "", 100, new Rounding(), "%3% %1$.2f") { } } //! Indonesian Rupiah - /*! The ISO three-letter code is IDR; the numeric code is 360. - It is divided in 100 sen. + /*! The ISO three-letter code is IDR; the numeric code is 360. + It is divided in 100 sen. - \ingroup currencies + \ingroup currencies */ - public class IDRCurrency : Currency + public class IDRCurrency : Currency { - public IDRCurrency():base("Indonesian Rupiah", "IDR", 360,"Rp", "", 100,new Rounding(),"%3% %1$.2f") { } + public IDRCurrency(): base("Indonesian Rupiah", "IDR", 360, "Rp", "", 100, new Rounding(), "%3% %1$.2f") { } } //! Israeli shekel @@ -68,9 +68,9 @@ It is divided in 100 agorot. \ingroup currencies */ - public class ILSCurrency : Currency + public class ILSCurrency : Currency { - public ILSCurrency() : base( "Israeli shekel", "ILS", 376, "NIS", "", 100, new Rounding(), "%1$.2f %3%" ) { } + public ILSCurrency() : base("Israeli shekel", "ILS", 376, "NIS", "", 100, new Rounding(), "%1$.2f %3%") { } } //! Indian rupee @@ -79,10 +79,10 @@ It is divided in 100 paise. \ingroup currencies */ - public class INRCurrency : Currency + public class INRCurrency : Currency { public INRCurrency() - : base( "Indian rupee", "INR", 356, "Rs", "", 100,new Rounding(), "%3% %1$.2f" ) { } + : base("Indian rupee", "INR", 356, "Rs", "", 100, new Rounding(), "%3% %1$.2f") { } } //! Iraqi dinar @@ -91,10 +91,10 @@ It is divided in 1000 fils. \ingroup currencies */ - public class IQDCurrency : Currency + public class IQDCurrency : Currency { public IQDCurrency() - : base( "Iraqi dinar", "IQD", 368,"ID", "", 1000,new Rounding(), "%2% %1$.3f" ) { } + : base("Iraqi dinar", "IQD", 368, "ID", "", 1000, new Rounding(), "%2% %1$.3f") { } } //! Iranian rial @@ -103,9 +103,9 @@ It has no subdivisions. \ingroup currencies */ - public class IRRCurrency : Currency + public class IRRCurrency : Currency { - public IRRCurrency() : base( "Iranian rial", "IRR", 364, "Rls", "", 1,new Rounding(), "%3% %1$.2f" ) { } + public IRRCurrency() : base("Iranian rial", "IRR", 364, "Rls", "", 1, new Rounding(), "%3% %1$.2f") { } } /// @@ -124,9 +124,9 @@ It is divided in 100 chon. \ingroup currencies */ - public class KRWCurrency : Currency + public class KRWCurrency : Currency { - public KRWCurrency() : base( "South-Korean won", "KRW", 410, "W", "", 100,new Rounding(), "%3% %1$.0f" ) { } + public KRWCurrency() : base("South-Korean won", "KRW", 410, "W", "", 100, new Rounding(), "%3% %1$.0f") { } } //! Kuwaiti dinar @@ -135,20 +135,20 @@ It is divided in 1000 fils. \ingroup currencies */ - public class KWDCurrency : Currency + public class KWDCurrency : Currency { - public KWDCurrency() : base("Kuwaiti dinar", "KWD", 414,"KD", "", 1000,new Rounding(),"%3% %1$.3f"){} + public KWDCurrency() : base("Kuwaiti dinar", "KWD", 414, "KD", "", 1000, new Rounding(), "%3% %1$.3f") {} } //! Malaysian Ringgit - /*! The ISO three-letter code is MYR; the numeric code is 458. - It is divided in 100 sen. + /*! The ISO three-letter code is MYR; the numeric code is 458. + It is divided in 100 sen. - \ingroup currencies + \ingroup currencies */ - public class MYRCurrency : Currency + public class MYRCurrency : Currency { - public MYRCurrency() : base("Malaysian Ringgit","MYR", 458,"RM", "", 100,new Rounding(),"%3% %1$.2f"){} + public MYRCurrency() : base("Malaysian Ringgit", "MYR", 458, "RM", "", 100, new Rounding(), "%3% %1$.2f") {} } //! Nepal rupee @@ -157,9 +157,9 @@ It is divided in 100 paise. \ingroup currencies */ - public class NPRCurrency : Currency + public class NPRCurrency : Currency { - public NPRCurrency() : base("Nepal rupee", "NPR", 524, "NRs", "", 100, new Rounding(),"%3% %1$.2f"){} + public NPRCurrency() : base("Nepal rupee", "NPR", 524, "NRs", "", 100, new Rounding(), "%3% %1$.2f") {} } //! Pakistani rupee @@ -168,9 +168,9 @@ It is divided in 100 paisa. \ingroup currencies */ - public class PKRCurrency : Currency + public class PKRCurrency : Currency { - public PKRCurrency() : base("Pakistani rupee", "PKR", 586, "Rs", "", 100,new Rounding(),"%3% %1$.2f"){} + public PKRCurrency() : base("Pakistani rupee", "PKR", 586, "Rs", "", 100, new Rounding(), "%3% %1$.2f") {} } //! Saudi riyal @@ -179,9 +179,9 @@ It is divided in 100 halalat. \ingroup currencies */ - public class SARCurrency : Currency + public class SARCurrency : Currency { - public SARCurrency() : base("Saudi riyal", "SAR", 682, "SRls", "", 100,new Rounding(),"%3% %1$.2f"){} + public SARCurrency() : base("Saudi riyal", "SAR", 682, "SRls", "", 100, new Rounding(), "%3% %1$.2f") {} } //! %Singapore dollar @@ -190,9 +190,9 @@ It is divided in 100 cents. \ingroup currencies */ - public class SGDCurrency : Currency + public class SGDCurrency : Currency { - public SGDCurrency() : base("Singapore dollar", "SGD", 702, "S$", "", 100, new Rounding(),"%3% %1$.2f"){} + public SGDCurrency() : base("Singapore dollar", "SGD", 702, "S$", "", 100, new Rounding(), "%3% %1$.2f") {} } //! Thai baht @@ -201,9 +201,9 @@ It is divided in 100 stang. \ingroup currencies */ - public class THBCurrency : Currency + public class THBCurrency : Currency { - public THBCurrency() : base("Thai baht", "THB", 764, "Bht", "", 100,new Rounding(), "%1$.2f %3%"){} + public THBCurrency() : base("Thai baht", "THB", 764, "Bht", "", 100, new Rounding(), "%1$.2f %3%") {} } //! %Taiwan dollar @@ -212,9 +212,9 @@ It is divided in 100 cents. \ingroup currencies */ - public class TWDCurrency : Currency + public class TWDCurrency : Currency { - public TWDCurrency() : base( "Taiwan dollar", "TWD", 901, "NT$", "", 100, new Rounding(), "%3% %1$.2f" ) { } + public TWDCurrency() : base("Taiwan dollar", "TWD", 901, "NT$", "", 100, new Rounding(), "%3% %1$.2f") { } } //! Vietnamese Dong @@ -223,8 +223,8 @@ It was divided in 100 xu. \ingroup currencies */ - public class VNDCurrency : Currency + public class VNDCurrency : Currency { - public VNDCurrency() : base("Vietnamese Dong", "VND", 704,"", "", 100,new Rounding(),"%1$.0f %3%") {} + public VNDCurrency() : base("Vietnamese Dong", "VND", 704, "", "", 100, new Rounding(), "%1$.0f %3%") {} } } diff --git a/src/QLNet/Currencies/Currency.cs b/src/QLNet/Currencies/Currency.cs index 11c09cefb..b67d86f5a 100644 --- a/src/QLNet/Currencies/Currency.cs +++ b/src/QLNet/Currencies/Currency.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,78 +19,83 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! %Currency specification - public class Currency - { - protected string name_, code_; - protected int numeric_; - protected string symbol_, fractionSymbol_; - protected int fractionsPerUnit_; - protected Rounding rounding_; - protected Currency triangulated_; - protected string formatString_; + //! %Currency specification + public class Currency + { + protected string name_, code_; + protected int numeric_; + protected string symbol_, fractionSymbol_; + protected int fractionsPerUnit_; + protected Rounding rounding_; + protected Currency triangulated_; + protected string formatString_; - // Inspectors - public string name { get { return name_; } } //! currency name, e.g, "U.S. Dollar" - public string code { get { return code_; } } //! ISO 4217 three-letter code, e.g, "USD" - public int numericCode { get { return numeric_; } } //! ISO 4217 numeric code, e.g, "840" - public string symbol { get { return symbol_; } } //! symbol, e.g, "$" - public string fractionSymbol - { get { return fractionSymbol_; } } //! fraction symbol, e.g, "¢" - public int fractionsPerUnit - { get { return fractionsPerUnit_; } } //! number of fractionary parts in a unit, e.g, 100 - public Rounding rounding - { get { return rounding_; } } //! rounding convention - public Currency triangulationCurrency - { get { return triangulated_; } } //! currency used for triangulated exchange when required - // output format - // The format will be fed three positional parameters, namely, value, code, and symbol, in this order. - public string format { get { return formatString_; } } + // Inspectors + public string name { get { return name_; } } //! currency name, e.g, "U.S. Dollar" + public string code { get { return code_; } } //! ISO 4217 three-letter code, e.g, "USD" + public int numericCode { get { return numeric_; } } //! ISO 4217 numeric code, e.g, "840" + public string symbol { get { return symbol_; } } //! symbol, e.g, "$" + public string fractionSymbol + { get { return fractionSymbol_; } } //! fraction symbol, e.g, "¢" + public int fractionsPerUnit + { get { return fractionsPerUnit_; } } //! number of fractionary parts in a unit, e.g, 100 + public Rounding rounding + { get { return rounding_; } } //! rounding convention + public Currency triangulationCurrency + { get { return triangulated_; } } //! currency used for triangulated exchange when required + // output format + // The format will be fed three positional parameters, namely, value, code, and symbol, in this order. + public string format { get { return formatString_; } } - // default constructor - // Instances built via this constructor have undefined behavior. Such instances can only act as placeholders - // and must be reassigned to a valid currency before being used. - public Currency() { } - public Currency(string name, string code, int numericCode, string symbol, string fractionSymbol, - int fractionsPerUnit, Rounding rounding, string formatString) : - this(name, code, numericCode, symbol, fractionSymbol, fractionsPerUnit, rounding, formatString, - new Currency()) { } - public Currency(string name, string code, int numericCode, string symbol, string fractionSymbol, - int fractionsPerUnit, Rounding rounding, string formatString, - Currency triangulationCurrency) - { - name_ = name; - code_ = code; - numeric_ = numericCode; - symbol_ = symbol; - fractionSymbol_ = fractionSymbol; - fractionsPerUnit_ = fractionsPerUnit; - rounding_ = rounding; - triangulated_ = triangulationCurrency; - formatString_ = formatString; - } + // default constructor + // Instances built via this constructor have undefined behavior. Such instances can only act as placeholders + // and must be reassigned to a valid currency before being used. + public Currency() { } + public Currency(string name, string code, int numericCode, string symbol, string fractionSymbol, + int fractionsPerUnit, Rounding rounding, string formatString) : + this(name, code, numericCode, symbol, fractionSymbol, fractionsPerUnit, rounding, formatString, + new Currency()) { } + public Currency(string name, string code, int numericCode, string symbol, string fractionSymbol, + int fractionsPerUnit, Rounding rounding, string formatString, + Currency triangulationCurrency) + { + name_ = name; + code_ = code; + numeric_ = numericCode; + symbol_ = symbol; + fractionSymbol_ = fractionSymbol; + fractionsPerUnit_ = fractionsPerUnit; + rounding_ = rounding; + triangulated_ = triangulationCurrency; + formatString_ = formatString; + } - //! Other information - //! is this a usable instance? - public bool empty() { return (name_ == null); } + //! Other information + //! is this a usable instance? + public bool empty() { return (name_ == null); } - public override string ToString() { return code; } + public override string ToString() { return code; } - /*! \relates Currency */ - public static bool operator ==(Currency c1, Currency c2) - { - if ((object)c1 == null && (object)c2 == null) return true; - else if ((object)c1 == null || (object)c2 == null) return false; - else return c1.name == c2.name; - } - public static bool operator !=(Currency c1, Currency c2) { return !(c1 == c2); } - public static Money operator *(double value, Currency c) { return new Money(value, c); - } + /*! \relates Currency */ + public static bool operator ==(Currency c1, Currency c2) + { + if ((object)c1 == null && (object)c2 == null) + return true; + else if ((object)c1 == null || (object)c2 == null) + return false; + else + return c1.name == c2.name; + } + public static bool operator !=(Currency c1, Currency c2) { return !(c1 == c2); } + public static Money operator *(double value, Currency c) + { + return new Money(value, c); + } - public override bool Equals(object o) { return this == (Currency)o; } - public override int GetHashCode() { return 0; } - } + public override bool Equals(object o) { return this == (Currency)o; } + public override int GetHashCode() { return 0; } + } } diff --git a/src/QLNet/Currencies/Europe.cs b/src/QLNet/Currencies/Europe.cs index 79a56d343..9f2eac71b 100644 --- a/src/QLNet/Currencies/Europe.cs +++ b/src/QLNet/Currencies/Europe.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,348 +20,348 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - /// - /// Bulgarian lev - /// The ISO three-letter code is BGL; the numeric code is 100. - /// It is divided in 100 stotinki. - /// - public class BGLCurrency : Currency - { - public BGLCurrency() : base("Bulgarian lev", "BGL", 100, "lv", "", 100, new Rounding(), "%1$.2f %3%") { } - } - - /// - /// Belarussian ruble - /// The ISO three-letter code is BYR; the numeric code is 974. - /// It has no subdivisions. - /// - public class BYRCurrency : Currency - { - public BYRCurrency() : base("Belarussian ruble", "BYR", 974, "BR", "", 1, new Rounding(), "%2% %1$.0f") { } - } - - /// - /// Swiss franc - /// The ISO three-letter code is CHF; the numeric code is 756. - /// It is divided into 100 cents. - /// - public class CHFCurrency : Currency - { - public CHFCurrency() : base("Swiss franc", "CHF", 756, "SwF", "", 100, new Rounding(), "%3% %1$.2f") { } - } - - /// - /// Cyprus pound - /// The ISO three-letter code is CYP; the numeric code is 196. - /// It is divided in 100 cents. - /// - public class CYPCurrency : Currency - { - public CYPCurrency() : base("Cyprus pound", "CYP", 196, "\xA3C", "", 100, new Rounding(), "%3% %1$.2f") { } - } - - /// - /// Czech koruna - /// The ISO three-letter code is CZK; the numeric code is 203. - /// It is divided in 100 haleru. - /// - public class CZKCurrency : Currency - { - public CZKCurrency() : base("Czech koruna", "CZK", 203, "Kc", "", 100, new Rounding(), "%1$.2f %3%") { } - } - - /// - /// Danish krone - /// The ISO three-letter code is DKK; the numeric code is 208. - /// It is divided in 100 шre. - /// - public class DKKCurrency : Currency - { - public DKKCurrency() : base("Danish krone", "DKK", 208, "Dkr", "", 100, new Rounding(), "%3% %1$.2f") { } - } - - /// - /// Estonian kroon - /// The ISO three-letter code is EEK; the numeric code is 233. - /// It is divided in 100 senti. - /// - public class EEKCurrency : Currency - { - public EEKCurrency() : base("Estonian kroon", "EEK", 233, "KR", "", 100, new Rounding(), "%1$.2f %2%") { } - } - - /// - /// European Euro - /// The ISO three-letter code is EUR; the numeric code is 978. - /// It is divided into 100 cents. - /// - public class EURCurrency : Currency - { - public EURCurrency() : base("European Euro", "EUR", 978, "", "", 100, new Rounding(2, Rounding.Type.Closest), "%2% %1$.2f") { } - } - - /// - /// British pound sterling - /// The ISO three-letter code is GBP; the numeric code is 826. - /// It is divided into 100 pence. - /// - public class GBPCurrency : Currency - { - public GBPCurrency() : base("British pound sterling", "GBP", 826, "\xA3", "p", 100, new Rounding(), "%3% %1$.2f") { } - } - - /// - /// Hungarian forint - /// The ISO three-letter code is HUF; the numeric code is 348. - /// It has no subdivisions. - /// - public class HUFCurrency : Currency - { - public HUFCurrency() : base("Hungarian forint", "HUF", 348, "Ft", "", 1, new Rounding(), "%1$.0f %3%") { } - } - - /// - /// Icelandic krona - /// The ISO three-letter code is ISK; the numeric code is 352. - /// It is divided in 100 aurar. - /// - public class ISKCurrency : Currency - { - public ISKCurrency() : base("Iceland krona", "ISK", 352, "IKr", "", 100, new Rounding(), "%1$.2f %3%") { } - } - - /// - /// Lithuanian litas - /// The ISO three-letter code is LTL; the numeric code is 440. - /// It is divided in 100 centu. - /// - public class LTLCurrency : Currency - { - public LTLCurrency() : base("Lithuanian litas", "LTL", 440, "Lt", "", 100, new Rounding(), "%1$.2f %3%") { } - } - - /// - /// Latvian lat - /// The ISO three-letter code is LVL; the numeric code is 428. - /// It is divided in 100 santims. - /// - public class LVLCurrency : Currency - { - public LVLCurrency() : base("Latvian lat", "LVL", 428, "Ls", "", 100, new Rounding(), "%3% %1$.2f") { } - } - - /// - /// Maltese lira - /// The ISO three-letter code is MTL; the numeric code is 470. - /// It is divided in 100 cents. - /// - public class MTLCurrency : Currency - { - public MTLCurrency() : base("Maltese lira", "MTL", 470, "Lm", "", 100, new Rounding(), "%3% %1$.2f") { } - } - - /// Norwegian krone - /// The ISO three-letter code is NOK; the numeric code is 578. - /// It is divided in 100 шre. - public class NOKCurrency : Currency - { - public NOKCurrency() : base("Norwegian krone", "NOK", 578, "NKr", "", 100, new Rounding(), "%3% %1$.2f") { } - } - - /// Polish zloty - /// The ISO three-letter code is PLN; the numeric code is 985. - /// It is divided in 100 groszy. - public class PLNCurrency : Currency - { - public PLNCurrency() : base("Polish zloty", "PLN", 985, "zl", "", 100, new Rounding(), "%1$.2f %3%") { } - } - - /// Romanian leu - /// The ISO three-letter code was ROL; the numeric code was 642. - /// It was divided in 100 bani. - public class ROLCurrency : Currency - { - public ROLCurrency() : base("Romanian leu", "ROL", 642, "L", "", 100, new Rounding(), "%1$.2f %3%") { } - } - - /// Romanian new leu - /// The ISO three-letter code is RON; the numeric code is 946. - /// It is divided in 100 bani. - public class RONCurrency : Currency - { - public RONCurrency() : base("Romanian new leu", "RON", 946, "L", "", 100, new Rounding(), "%1$.2f %3%") { } - } - - //! Russian ruble - /*! The ISO three-letter code is RUB; the numeric code is 643. - It is divided in 100 kopeyki. - - \ingroup currencies - */ - public class RUBCurrency : Currency - { - public RUBCurrency():base("Russian ruble","RUB", 643,"", "", 100,new Rounding(),"%1$.2f %2%") { } - } - - /// Swedish krona - /// The ISO three-letter code is SEK; the numeric code is 752. - /// It is divided in 100 цre. - public class SEKCurrency : Currency - { - public SEKCurrency() : base("Swedish krona", "SEK", 752, "kr", "", 100, new Rounding(), "%1$.2f %3%") { } - } - - /// Slovenian tolar - /// The ISO three-letter code is SIT; the numeric code is 705. - /// It is divided in 100 stotinov. - public class SITCurrency : Currency - { - public SITCurrency() : base("Slovenian tolar", "SIT", 705, "SlT", "", 100, new Rounding(), "%1$.2f %3%") { } - } - - /// Slovak koruna - /// The ISO three-letter code is SKK; the numeric code is 703. - /// It is divided in 100 halierov. - public class SKKCurrency : Currency - { - public SKKCurrency() : base("Slovak koruna", "SKK", 703, "Sk", "", 100, new Rounding(), "%1$.2f %3%") { } - } - - /// Turkish lira - /// The ISO three-letter code was TRL; the numeric code was 792. - /// It was divided in 100 kurus. - /// Obsoleted by the new Turkish lira since 2005. - public class TRLCurrency : Currency - { - public TRLCurrency() : base("Turkish lira", "TRL", 792, "TL", "", 100, new Rounding(), "%1$.0f %3%") { } - } - - /// New Turkish lira - /// The ISO three-letter code is TRY; the numeric code is 949. - /// It is divided in 100 new kurus. - public class TRYCurrency : Currency - { - public TRYCurrency() : base("New Turkish lira", "TRY", 949, "YTL", "", 100, new Rounding(), "%1$.2f %3%") { } - } - - // currencies obsoleted by Euro - - /// Austrian shilling - /// The ISO three-letter code was ATS; the numeric code was 40. - /// It was divided in 100 groschen. - /// Obsoleted by the Euro since 1999. - public class ATSCurrency : Currency - { - public ATSCurrency() : base("Austrian shilling", "ATS", 40, "", "", 100, new Rounding(), "%2% %1$.2f", new EURCurrency()) { } - } - - /// Belgian franc - /// The ISO three-letter code was BEF; the numeric code was 56. - /// It had no subdivisions. - /// Obsoleted by the Euro since 1999. - public class BEFCurrency : Currency - { - public BEFCurrency() : base("Belgian franc", "BEF", 56, "", "", 1, new Rounding(), "%2% %1$.0f", new EURCurrency()) { } - } - - /// Deutsche mark - /// The ISO three-letter code was DEM; the numeric code was 276. - /// It was divided into 100 pfennig. - /// Obsoleted by the Euro since 1999. - public class DEMCurrency : Currency - { - public DEMCurrency() : base("Deutsche mark", "DEM", 276, "DM", "", 100, new Rounding(), "%1$.2f %3%", new EURCurrency()) { } - } - - /// Spanish peseta - /// The ISO three-letter code was ESP; the numeric code was 724. - /// It was divided in 100 centimos. - /// Obsoleted by the Euro since 1999. - public class ESPCurrency : Currency - { - public ESPCurrency() : base("Spanish peseta", "ESP", 724, "Pta", "", 100, new Rounding(), "%1$.0f %3%", new EURCurrency()) { } - } - - /// Finnish markka - /// The ISO three-letter code was FIM; the numeric code was 246. - /// It was divided in 100 penniд. - /// Obsoleted by the Euro since 1999. - public class FIMCurrency : Currency - { - public FIMCurrency() : base("Finnish markka", "FIM", 246, "mk", "", 100, new Rounding(), "%1$.2f %3%", new EURCurrency()) { } - } - - /// French franc - /// The ISO three-letter code was FRF; the numeric code was 250. - /// It was divided in 100 centimes. - /// Obsoleted by the Euro since 1999. - public class FRFCurrency : Currency - { - public FRFCurrency() : base("French franc", "FRF", 250, "", "", 100, new Rounding(), "%1$.2f %2%", new EURCurrency()) { } - } - - /// Greek drachma - /// The ISO three-letter code was GRD; the numeric code was 300. - /// It was divided in 100 lepta. - /// Obsoleted by the Euro since 1999. - public class GRDCurrency : Currency - { - public GRDCurrency() : base("Greek drachma", "GRD", 300, "", "", 100, new Rounding(), "%1$.2f %2%", new EURCurrency()) { } - } - - /// Irish punt - /// The ISO three-letter code was IEP; the numeric code was 372. - /// It was divided in 100 pence. - /// Obsoleted by the Euro since 1999. - public class IEPCurrency : Currency - { - public IEPCurrency() : base("Irish punt", "IEP", 372, "", "", 100, new Rounding(), "%2% %1$.2f", new EURCurrency()) { } - } - - /// Italian lira - /// The ISO three-letter code was ITL; the numeric code was 380. - /// It had no subdivisions. - /// Obsoleted by the Euro since 1999. - public class ITLCurrency : Currency - { - public ITLCurrency() : base("Italian lira", "ITL", 380, "L", "", 1, new Rounding(), "%3% %1$.0f", new EURCurrency()) { } - } - - /// Luxembourg franc - /// The ISO three-letter code was LUF; the numeric code was 442. - /// It was divided in 100 centimes. - /// Obsoleted by the Euro since 1999. - public class LUFCurrency : Currency - { - public LUFCurrency() : base("Luxembourg franc", "LUF", 442, "F", "", 100, new Rounding(), "%1$.0f %3%", new EURCurrency()) { } - } - - /// Dutch guilder - /// The ISO three-letter code was NLG; the numeric code was 528. - /// It was divided in 100 cents. - /// Obsoleted by the Euro since 1999. - public class NLGCurrency : Currency - { - public NLGCurrency() : base("Dutch guilder", "NLG", 528, "f", "", 100, new Rounding(), "%3% %1$.2f", new EURCurrency()) { } - } - - /// Portuguese escudo - /// The ISO three-letter code was PTE; the numeric code was 620. - /// It was divided in 100 centavos. - /// Obsoleted by the Euro since 1999. - public class PTECurrency : Currency - { - public PTECurrency() : base("Portuguese escudo", "PTE", 620, "Esc", "", 100, new Rounding(), "%1$.0f %3%", new EURCurrency()) { } - } + /// + /// Bulgarian lev + /// The ISO three-letter code is BGL; the numeric code is 100. + /// It is divided in 100 stotinki. + /// + public class BGLCurrency : Currency + { + public BGLCurrency() : base("Bulgarian lev", "BGL", 100, "lv", "", 100, new Rounding(), "%1$.2f %3%") { } + } + + /// + /// Belarussian ruble + /// The ISO three-letter code is BYR; the numeric code is 974. + /// It has no subdivisions. + /// + public class BYRCurrency : Currency + { + public BYRCurrency() : base("Belarussian ruble", "BYR", 974, "BR", "", 1, new Rounding(), "%2% %1$.0f") { } + } + + /// + /// Swiss franc + /// The ISO three-letter code is CHF; the numeric code is 756. + /// It is divided into 100 cents. + /// + public class CHFCurrency : Currency + { + public CHFCurrency() : base("Swiss franc", "CHF", 756, "SwF", "", 100, new Rounding(), "%3% %1$.2f") { } + } + + /// + /// Cyprus pound + /// The ISO three-letter code is CYP; the numeric code is 196. + /// It is divided in 100 cents. + /// + public class CYPCurrency : Currency + { + public CYPCurrency() : base("Cyprus pound", "CYP", 196, "\xA3C", "", 100, new Rounding(), "%3% %1$.2f") { } + } + + /// + /// Czech koruna + /// The ISO three-letter code is CZK; the numeric code is 203. + /// It is divided in 100 haleru. + /// + public class CZKCurrency : Currency + { + public CZKCurrency() : base("Czech koruna", "CZK", 203, "Kc", "", 100, new Rounding(), "%1$.2f %3%") { } + } + + /// + /// Danish krone + /// The ISO three-letter code is DKK; the numeric code is 208. + /// It is divided in 100 шre. + /// + public class DKKCurrency : Currency + { + public DKKCurrency() : base("Danish krone", "DKK", 208, "Dkr", "", 100, new Rounding(), "%3% %1$.2f") { } + } + + /// + /// Estonian kroon + /// The ISO three-letter code is EEK; the numeric code is 233. + /// It is divided in 100 senti. + /// + public class EEKCurrency : Currency + { + public EEKCurrency() : base("Estonian kroon", "EEK", 233, "KR", "", 100, new Rounding(), "%1$.2f %2%") { } + } + + /// + /// European Euro + /// The ISO three-letter code is EUR; the numeric code is 978. + /// It is divided into 100 cents. + /// + public class EURCurrency : Currency + { + public EURCurrency() : base("European Euro", "EUR", 978, "", "", 100, new Rounding(2, Rounding.Type.Closest), "%2% %1$.2f") { } + } + + /// + /// British pound sterling + /// The ISO three-letter code is GBP; the numeric code is 826. + /// It is divided into 100 pence. + /// + public class GBPCurrency : Currency + { + public GBPCurrency() : base("British pound sterling", "GBP", 826, "\xA3", "p", 100, new Rounding(), "%3% %1$.2f") { } + } + + /// + /// Hungarian forint + /// The ISO three-letter code is HUF; the numeric code is 348. + /// It has no subdivisions. + /// + public class HUFCurrency : Currency + { + public HUFCurrency() : base("Hungarian forint", "HUF", 348, "Ft", "", 1, new Rounding(), "%1$.0f %3%") { } + } + + /// + /// Icelandic krona + /// The ISO three-letter code is ISK; the numeric code is 352. + /// It is divided in 100 aurar. + /// + public class ISKCurrency : Currency + { + public ISKCurrency() : base("Iceland krona", "ISK", 352, "IKr", "", 100, new Rounding(), "%1$.2f %3%") { } + } + + /// + /// Lithuanian litas + /// The ISO three-letter code is LTL; the numeric code is 440. + /// It is divided in 100 centu. + /// + public class LTLCurrency : Currency + { + public LTLCurrency() : base("Lithuanian litas", "LTL", 440, "Lt", "", 100, new Rounding(), "%1$.2f %3%") { } + } + + /// + /// Latvian lat + /// The ISO three-letter code is LVL; the numeric code is 428. + /// It is divided in 100 santims. + /// + public class LVLCurrency : Currency + { + public LVLCurrency() : base("Latvian lat", "LVL", 428, "Ls", "", 100, new Rounding(), "%3% %1$.2f") { } + } + + /// + /// Maltese lira + /// The ISO three-letter code is MTL; the numeric code is 470. + /// It is divided in 100 cents. + /// + public class MTLCurrency : Currency + { + public MTLCurrency() : base("Maltese lira", "MTL", 470, "Lm", "", 100, new Rounding(), "%3% %1$.2f") { } + } + + /// Norwegian krone + /// The ISO three-letter code is NOK; the numeric code is 578. + /// It is divided in 100 шre. + public class NOKCurrency : Currency + { + public NOKCurrency() : base("Norwegian krone", "NOK", 578, "NKr", "", 100, new Rounding(), "%3% %1$.2f") { } + } + + /// Polish zloty + /// The ISO three-letter code is PLN; the numeric code is 985. + /// It is divided in 100 groszy. + public class PLNCurrency : Currency + { + public PLNCurrency() : base("Polish zloty", "PLN", 985, "zl", "", 100, new Rounding(), "%1$.2f %3%") { } + } + + /// Romanian leu + /// The ISO three-letter code was ROL; the numeric code was 642. + /// It was divided in 100 bani. + public class ROLCurrency : Currency + { + public ROLCurrency() : base("Romanian leu", "ROL", 642, "L", "", 100, new Rounding(), "%1$.2f %3%") { } + } + + /// Romanian new leu + /// The ISO three-letter code is RON; the numeric code is 946. + /// It is divided in 100 bani. + public class RONCurrency : Currency + { + public RONCurrency() : base("Romanian new leu", "RON", 946, "L", "", 100, new Rounding(), "%1$.2f %3%") { } + } + + //! Russian ruble + /*! The ISO three-letter code is RUB; the numeric code is 643. + It is divided in 100 kopeyki. + + \ingroup currencies + */ + public class RUBCurrency : Currency + { + public RUBCurrency(): base("Russian ruble", "RUB", 643, "", "", 100, new Rounding(), "%1$.2f %2%") { } + } + + /// Swedish krona + /// The ISO three-letter code is SEK; the numeric code is 752. + /// It is divided in 100 цre. + public class SEKCurrency : Currency + { + public SEKCurrency() : base("Swedish krona", "SEK", 752, "kr", "", 100, new Rounding(), "%1$.2f %3%") { } + } + + /// Slovenian tolar + /// The ISO three-letter code is SIT; the numeric code is 705. + /// It is divided in 100 stotinov. + public class SITCurrency : Currency + { + public SITCurrency() : base("Slovenian tolar", "SIT", 705, "SlT", "", 100, new Rounding(), "%1$.2f %3%") { } + } + + /// Slovak koruna + /// The ISO three-letter code is SKK; the numeric code is 703. + /// It is divided in 100 halierov. + public class SKKCurrency : Currency + { + public SKKCurrency() : base("Slovak koruna", "SKK", 703, "Sk", "", 100, new Rounding(), "%1$.2f %3%") { } + } + + /// Turkish lira + /// The ISO three-letter code was TRL; the numeric code was 792. + /// It was divided in 100 kurus. + /// Obsoleted by the new Turkish lira since 2005. + public class TRLCurrency : Currency + { + public TRLCurrency() : base("Turkish lira", "TRL", 792, "TL", "", 100, new Rounding(), "%1$.0f %3%") { } + } + + /// New Turkish lira + /// The ISO three-letter code is TRY; the numeric code is 949. + /// It is divided in 100 new kurus. + public class TRYCurrency : Currency + { + public TRYCurrency() : base("New Turkish lira", "TRY", 949, "YTL", "", 100, new Rounding(), "%1$.2f %3%") { } + } + + // currencies obsoleted by Euro + + /// Austrian shilling + /// The ISO three-letter code was ATS; the numeric code was 40. + /// It was divided in 100 groschen. + /// Obsoleted by the Euro since 1999. + public class ATSCurrency : Currency + { + public ATSCurrency() : base("Austrian shilling", "ATS", 40, "", "", 100, new Rounding(), "%2% %1$.2f", new EURCurrency()) { } + } + + /// Belgian franc + /// The ISO three-letter code was BEF; the numeric code was 56. + /// It had no subdivisions. + /// Obsoleted by the Euro since 1999. + public class BEFCurrency : Currency + { + public BEFCurrency() : base("Belgian franc", "BEF", 56, "", "", 1, new Rounding(), "%2% %1$.0f", new EURCurrency()) { } + } + + /// Deutsche mark + /// The ISO three-letter code was DEM; the numeric code was 276. + /// It was divided into 100 pfennig. + /// Obsoleted by the Euro since 1999. + public class DEMCurrency : Currency + { + public DEMCurrency() : base("Deutsche mark", "DEM", 276, "DM", "", 100, new Rounding(), "%1$.2f %3%", new EURCurrency()) { } + } + + /// Spanish peseta + /// The ISO three-letter code was ESP; the numeric code was 724. + /// It was divided in 100 centimos. + /// Obsoleted by the Euro since 1999. + public class ESPCurrency : Currency + { + public ESPCurrency() : base("Spanish peseta", "ESP", 724, "Pta", "", 100, new Rounding(), "%1$.0f %3%", new EURCurrency()) { } + } + + /// Finnish markka + /// The ISO three-letter code was FIM; the numeric code was 246. + /// It was divided in 100 penniд. + /// Obsoleted by the Euro since 1999. + public class FIMCurrency : Currency + { + public FIMCurrency() : base("Finnish markka", "FIM", 246, "mk", "", 100, new Rounding(), "%1$.2f %3%", new EURCurrency()) { } + } + + /// French franc + /// The ISO three-letter code was FRF; the numeric code was 250. + /// It was divided in 100 centimes. + /// Obsoleted by the Euro since 1999. + public class FRFCurrency : Currency + { + public FRFCurrency() : base("French franc", "FRF", 250, "", "", 100, new Rounding(), "%1$.2f %2%", new EURCurrency()) { } + } + + /// Greek drachma + /// The ISO three-letter code was GRD; the numeric code was 300. + /// It was divided in 100 lepta. + /// Obsoleted by the Euro since 1999. + public class GRDCurrency : Currency + { + public GRDCurrency() : base("Greek drachma", "GRD", 300, "", "", 100, new Rounding(), "%1$.2f %2%", new EURCurrency()) { } + } + + /// Irish punt + /// The ISO three-letter code was IEP; the numeric code was 372. + /// It was divided in 100 pence. + /// Obsoleted by the Euro since 1999. + public class IEPCurrency : Currency + { + public IEPCurrency() : base("Irish punt", "IEP", 372, "", "", 100, new Rounding(), "%2% %1$.2f", new EURCurrency()) { } + } + + /// Italian lira + /// The ISO three-letter code was ITL; the numeric code was 380. + /// It had no subdivisions. + /// Obsoleted by the Euro since 1999. + public class ITLCurrency : Currency + { + public ITLCurrency() : base("Italian lira", "ITL", 380, "L", "", 1, new Rounding(), "%3% %1$.0f", new EURCurrency()) { } + } + + /// Luxembourg franc + /// The ISO three-letter code was LUF; the numeric code was 442. + /// It was divided in 100 centimes. + /// Obsoleted by the Euro since 1999. + public class LUFCurrency : Currency + { + public LUFCurrency() : base("Luxembourg franc", "LUF", 442, "F", "", 100, new Rounding(), "%1$.0f %3%", new EURCurrency()) { } + } + + /// Dutch guilder + /// The ISO three-letter code was NLG; the numeric code was 528. + /// It was divided in 100 cents. + /// Obsoleted by the Euro since 1999. + public class NLGCurrency : Currency + { + public NLGCurrency() : base("Dutch guilder", "NLG", 528, "f", "", 100, new Rounding(), "%3% %1$.2f", new EURCurrency()) { } + } + + /// Portuguese escudo + /// The ISO three-letter code was PTE; the numeric code was 620. + /// It was divided in 100 centavos. + /// Obsoleted by the Euro since 1999. + public class PTECurrency : Currency + { + public PTECurrency() : base("Portuguese escudo", "PTE", 620, "Esc", "", 100, new Rounding(), "%1$.0f %3%", new EURCurrency()) { } + } //! Ukrainian hryvnia - /*! The ISO three-letter code is UAH; the numeric code is 980. - It is divided in 100 kopiykas. - - \ingroup currencies - */ - public class UAHCurrency : Currency - { - public UAHCurrency() : base( "Ukrainian hryvnia", "UAH", 980, "hrn", "", 100, new Rounding(), "%1$.2f %3%" ) { } - } + /*! The ISO three-letter code is UAH; the numeric code is 980. + It is divided in 100 kopiykas. + + \ingroup currencies + */ + public class UAHCurrency : Currency + { + public UAHCurrency() : base("Ukrainian hryvnia", "UAH", 980, "hrn", "", 100, new Rounding(), "%1$.2f %3%") { } + } } diff --git a/src/QLNet/Currencies/ExchangeRate.cs b/src/QLNet/Currencies/ExchangeRate.cs index 22df7541a..1db50b64a 100644 --- a/src/QLNet/Currencies/ExchangeRate.cs +++ b/src/QLNet/Currencies/ExchangeRate.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Andrea Maggiulli - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,13 +21,15 @@ under the terms of the QLNet license. You should have received a using System; using System.Collections.Generic; -namespace QLNet { +namespace QLNet +{ /// /// Exchange rate between two currencies /// application of direct and derived exchange rate is /// tested against calculations. /// - public class ExchangeRate { + public class ExchangeRate + { private Currency source_; private Currency target_; private double? rate_; @@ -39,24 +41,33 @@ public class ExchangeRate { /// public Currency source { - get { return source_ ; } + get + { + return source_ ; + } } - + /// /// the target currency. /// public Currency target { - get { return target_; } + get + { + return target_; + } } /// /// the type /// /// - public ExchangeRate.Type type + public ExchangeRate.Type type { - get { return type_;} + get + { + return type_; + } } /// @@ -65,16 +76,22 @@ public ExchangeRate.Type type /// public double rate { - get { return rate_.Value; } + get + { + return rate_.Value; + } } public bool HasValue { - get {return rate_.HasValue;} + get + { + return rate_.HasValue; + } } /// - /// given directly by the user + /// given directly by the user /// public enum Type { @@ -83,7 +100,7 @@ public enum Type /// Direct, /// - /// Derived from exchange rates between other currencies + /// Derived from exchange rates between other currencies /// Derived } @@ -146,39 +163,39 @@ public Money exchange(Money amount) /// /// public static ExchangeRate chain(ExchangeRate r1, ExchangeRate r2) - { - ExchangeRate result = new ExchangeRate(); - result.type_ = Type.Derived; - result.rateChain_ = new KeyValuePair(r1,r2); - if (r1.source_ == r2.source_) - { - result.source_ = r1.target_; - result.target_ = r2.target_; - result.rate_ = r2.rate_ / r1.rate_; - } - else if (r1.source_ == r2.target_) - { - result.source_ = r1.target_; - result.target_ = r2.source_; - result.rate_ = 1.0 / (r1.rate_ * r2.rate_); - } - else if (r1.target_ == r2.source_) - { - result.source_ = r1.source_; - result.target_ = r2.target_; - result.rate_ = r1.rate_ * r2.rate_; - } - else if (r1.target_ == r2.target_) - { - result.source_ = r1.source_; - result.target_ = r2.source_; - result.rate_ = r1.rate_ / r2.rate_; - } - else - { - Utils.QL_FAIL("exchange rates not chainable"); - } - return result; - } + { + ExchangeRate result = new ExchangeRate(); + result.type_ = Type.Derived; + result.rateChain_ = new KeyValuePair(r1, r2); + if (r1.source_ == r2.source_) + { + result.source_ = r1.target_; + result.target_ = r2.target_; + result.rate_ = r2.rate_ / r1.rate_; + } + else if (r1.source_ == r2.target_) + { + result.source_ = r1.target_; + result.target_ = r2.source_; + result.rate_ = 1.0 / (r1.rate_ * r2.rate_); + } + else if (r1.target_ == r2.source_) + { + result.source_ = r1.source_; + result.target_ = r2.target_; + result.rate_ = r1.rate_ * r2.rate_; + } + else if (r1.target_ == r2.target_) + { + result.source_ = r1.source_; + result.target_ = r2.source_; + result.rate_ = r1.rate_ / r2.rate_; + } + else + { + Utils.QL_FAIL("exchange rates not chainable"); + } + return result; + } } } diff --git a/src/QLNet/Currencies/ExchangeRateManager.cs b/src/QLNet/Currencies/ExchangeRateManager.cs index 17a0006f9..fcfb785eb 100644 --- a/src/QLNet/Currencies/ExchangeRateManager.cs +++ b/src/QLNet/Currencies/ExchangeRateManager.cs @@ -2,18 +2,18 @@ Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -33,7 +33,10 @@ public class ExchangeRateManager public static ExchangeRateManager Instance { - get { return instance_ ?? (instance_ = new ExchangeRateManager()); } + get + { + return instance_ ?? (instance_ = new ExchangeRateManager()); + } } private ExchangeRateManager() @@ -60,33 +63,53 @@ public Entry(ExchangeRate r, Date s, Date e) private void addKnownRates() { // currencies obsoleted by Euro - add(new ExchangeRate(new EURCurrency(), new ATSCurrency(), 13.7603), new Date(1, Month.January, 1999),Date.maxDate()); - add(new ExchangeRate(new EURCurrency(), new BEFCurrency(), 40.3399), new Date(1, Month.January, 1999),Date.maxDate()); - add(new ExchangeRate(new EURCurrency(), new DEMCurrency(), 1.95583), new Date(1, Month.January, 1999),Date.maxDate()); - add(new ExchangeRate(new EURCurrency(), new ESPCurrency(), 166.386), new Date(1, Month.January, 1999),Date.maxDate()); - add(new ExchangeRate(new EURCurrency(), new FIMCurrency(), 5.94573), new Date(1, Month.January, 1999),Date.maxDate()); - add(new ExchangeRate(new EURCurrency(), new FRFCurrency(), 6.55957), new Date(1, Month.January, 1999),Date.maxDate()); - add(new ExchangeRate(new EURCurrency(), new GRDCurrency(), 340.750), new Date(1, Month.January, 2001),Date.maxDate()); - add(new ExchangeRate(new EURCurrency(), new IEPCurrency(), 0.787564), new Date(1, Month.January, 1999),Date.maxDate()); - add(new ExchangeRate(new EURCurrency(), new ITLCurrency(), 1936.27), new Date(1, Month.January, 1999),Date.maxDate()); - add(new ExchangeRate(new EURCurrency(), new LUFCurrency(), 40.3399), new Date(1, Month.January, 1999),Date.maxDate()); - add(new ExchangeRate(new EURCurrency(), new NLGCurrency(), 2.20371), new Date(1, Month.January, 1999),Date.maxDate()); - add(new ExchangeRate(new EURCurrency(), new PTECurrency(), 200.482), new Date(1, Month.January, 1999),Date.maxDate()); + add + (new ExchangeRate(new EURCurrency(), new ATSCurrency(), 13.7603), new Date(1, Month.January, 1999), Date.maxDate()); + add + (new ExchangeRate(new EURCurrency(), new BEFCurrency(), 40.3399), new Date(1, Month.January, 1999), Date.maxDate()); + add + (new ExchangeRate(new EURCurrency(), new DEMCurrency(), 1.95583), new Date(1, Month.January, 1999), Date.maxDate()); + add + (new ExchangeRate(new EURCurrency(), new ESPCurrency(), 166.386), new Date(1, Month.January, 1999), Date.maxDate()); + add + (new ExchangeRate(new EURCurrency(), new FIMCurrency(), 5.94573), new Date(1, Month.January, 1999), Date.maxDate()); + add + (new ExchangeRate(new EURCurrency(), new FRFCurrency(), 6.55957), new Date(1, Month.January, 1999), Date.maxDate()); + add + (new ExchangeRate(new EURCurrency(), new GRDCurrency(), 340.750), new Date(1, Month.January, 2001), Date.maxDate()); + add + (new ExchangeRate(new EURCurrency(), new IEPCurrency(), 0.787564), new Date(1, Month.January, 1999), Date.maxDate()); + add + (new ExchangeRate(new EURCurrency(), new ITLCurrency(), 1936.27), new Date(1, Month.January, 1999), Date.maxDate()); + add + (new ExchangeRate(new EURCurrency(), new LUFCurrency(), 40.3399), new Date(1, Month.January, 1999), Date.maxDate()); + add + (new ExchangeRate(new EURCurrency(), new NLGCurrency(), 2.20371), new Date(1, Month.January, 1999), Date.maxDate()); + add + (new ExchangeRate(new EURCurrency(), new PTECurrency(), 200.482), new Date(1, Month.January, 1999), Date.maxDate()); // other obsoleted currencies - add(new ExchangeRate(new TRYCurrency(), new TRLCurrency(), 1000000.0), new Date(1, Month.January, 2005),Date.maxDate()); - add(new ExchangeRate(new RONCurrency(), new ROLCurrency(), 10000.0), new Date(1, Month.July, 2005),Date.maxDate()); - add(new ExchangeRate(new PENCurrency(), new PEICurrency(), 1000000.0), new Date(1, Month.July, 1991),Date.maxDate()); - add(new ExchangeRate(new PEICurrency(), new PEHCurrency(), 1000.0), new Date(1, Month.February, 1985),Date.maxDate()); + add + (new ExchangeRate(new TRYCurrency(), new TRLCurrency(), 1000000.0), new Date(1, Month.January, 2005), Date.maxDate()); + add + (new ExchangeRate(new RONCurrency(), new ROLCurrency(), 10000.0), new Date(1, Month.July, 2005), Date.maxDate()); + add + (new ExchangeRate(new PENCurrency(), new PEICurrency(), 1000000.0), new Date(1, Month.July, 1991), Date.maxDate()); + add + (new ExchangeRate(new PEICurrency(), new PEHCurrency(), 1000.0), new Date(1, Month.February, 1985), Date.maxDate()); } - public void add(ExchangeRate rate) + public void add + (ExchangeRate rate) { - add(rate, Date.minDate(), Date.maxDate()); + add + (rate, Date.minDate(), Date.maxDate()); } - public void add(ExchangeRate rate, Date startDate) + public void add + (ExchangeRate rate, Date startDate) { - add(rate, startDate, Date.maxDate()); + add + (rate, startDate, Date.maxDate()); } // Add an exchange rate. @@ -94,7 +117,8 @@ public void add(ExchangeRate rate, Date startDate) // If two rates are given between the same currencies // and with overlapping date ranges, the latest one // added takes precedence during lookup. - private void add(ExchangeRate rate, Date startDate, Date endDate) + private void add + (ExchangeRate rate, Date startDate, Date endDate) { int k = hash(rate.source, rate.target); if (data_.ContainsKey(k)) @@ -111,12 +135,12 @@ private void add(ExchangeRate rate, Date startDate, Date endDate) private int hash(Currency c1, Currency c2) { return Math.Min(c1.numericCode, c2.numericCode) * 1000 - + Math.Max(c1.numericCode, c2.numericCode); + + Math.Max(c1.numericCode, c2.numericCode); } private bool hashes(int k, Currency c) { - if (c.numericCode == k % 1000 || + if (c.numericCode == k % 1000 || c.numericCode == k / 1000) return true; return false; diff --git a/src/QLNet/Currencies/Oceania.cs b/src/QLNet/Currencies/Oceania.cs index fa6c6acd6..e8a8787ea 100644 --- a/src/QLNet/Currencies/Oceania.cs +++ b/src/QLNet/Currencies/Oceania.cs @@ -1,44 +1,45 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { +namespace QLNet +{ - //! Australian dollar + //! Australian dollar // ! The ISO three-letter code is AUD; the numeric code is 36. // It is divided into 100 cents. // // \ingroup currencies -// - public class AUDCurrency : Currency - { - public AUDCurrency() : base("Australian dollar", "AUD", 36, "A$", "", 100, new Rounding(), "%3% %1$.2f") { } - } +// + public class AUDCurrency : Currency + { + public AUDCurrency() : base("Australian dollar", "AUD", 36, "A$", "", 100, new Rounding(), "%3% %1$.2f") { } + } - //! New Zealand dollar + //! New Zealand dollar // ! The ISO three-letter code is NZD; the numeric code is 554. // It is divided in 100 cents. // // \ingroup currencies -// - public class NZDCurrency : Currency - { - public NZDCurrency() : base("New Zealand dollar", "NZD", 554, "NZ$", "", 100, new Rounding(), "%3% %1$.2f") { } - } +// + public class NZDCurrency : Currency + { + public NZDCurrency() : base("New Zealand dollar", "NZD", 554, "NZ$", "", 100, new Rounding(), "%3% %1$.2f") { } + } } diff --git a/src/QLNet/discretizedasset.cs b/src/QLNet/DiscretizedAsset.cs similarity index 97% rename from src/QLNet/discretizedasset.cs rename to src/QLNet/DiscretizedAsset.cs index 6569d4677..155761374 100644 --- a/src/QLNet/discretizedasset.cs +++ b/src/QLNet/DiscretizedAsset.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,7 +22,7 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! Discretized asset class used by numerical + //! Discretized asset class used by numerical public abstract class DiscretizedAsset { private Lattice method_; @@ -55,13 +55,13 @@ protected DiscretizedAsset() } /* High-level interface - + Users of discretized assets should use these methods in order to initialize, evolve and take the present value of the assets. They call the corresponding methods in the Lattice interface, to which we refer for documentation. - + */ public void initialize(Lattice method, double t) @@ -219,7 +219,7 @@ public DiscretizedOption(DiscretizedAsset underlying, Exercise.Type exerciseType public override void reset(int size) { Utils.QL_REQUIRE(method() == underlying_.method(), - () => "option and underlying were initialized on different methods"); + () => "option and underlying were initialized on different methods"); values_ = new Vector(size, 0.0); adjustValues(); } diff --git a/src/QLNet/Event.cs b/src/QLNet/Event.cs index 042666443..3f1c5c097 100644 --- a/src/QLNet/Event.cs +++ b/src/QLNet/Event.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -51,8 +51,14 @@ public virtual bool hasOccurred(Date d = null, bool? includeRefDate = null) private readonly WeakEventSource eventSource = new WeakEventSource(); public event Callback notifyObserversEvent { - add { eventSource.Subscribe(value); } - remove { eventSource.Unsubscribe(value); } + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } } public void registerWith(Callback handler) { notifyObserversEvent += handler; } @@ -68,9 +74,9 @@ protected void notifyObservers() public virtual void accept(IAcyclicVisitor v) { if (v != null) - v.visit(this); + v.visit(this); else - Utils.QL_FAIL("not an event visitor"); + Utils.QL_FAIL("not an event visitor"); } #endregion @@ -78,15 +84,15 @@ public virtual void accept(IAcyclicVisitor v) // used to create an Event instance. // to be replaced with specific events as soon as we find out which. - public class simple_event : Event + public class simple_event : Event { public simple_event(Date date) { date_ = date; } public override Date date() { return date_; } - + private Date date_; - + } } diff --git a/src/QLNet/Exercise.cs b/src/QLNet/Exercise.cs index 9f6becbe6..936d0c618 100644 --- a/src/QLNet/Exercise.cs +++ b/src/QLNet/Exercise.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Extensions/DoubleExtension.cs b/src/QLNet/Extensions/DoubleExtension.cs index b82bf95db..6e64f252f 100644 --- a/src/QLNet/Extensions/DoubleExtension.cs +++ b/src/QLNet/Extensions/DoubleExtension.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,7 +20,7 @@ namespace QLNet public static class DoubleExtension { // Fix double comparison - public static bool IsEqual(this double d1 , double d2) + public static bool IsEqual(this double d1, double d2) { if (Math.Abs(d1 - d2) <= double.Epsilon) return true; @@ -29,36 +29,44 @@ public static bool IsEqual(this double d1 , double d2) public static bool IsNotEqual(this double d1, double d2) { - return ! IsEqual(d1,d2); + return ! IsEqual(d1, d2); } // Fix double? comparison public static bool IsEqual(this double? d1, double d2) { - if (!d1.HasValue) return false; + if (!d1.HasValue) + return false; return d1.Value.IsEqual(d2); } public static bool IsNotEqual(this double? d1, double d2) { - if(!d1.HasValue) return true; + if (!d1.HasValue) + return true; return d1.Value.IsNotEqual(d2); } public static bool IsEqual(this double? d1, double? d2) { - if (!d1.HasValue && !d2.HasValue) return true; - if (!d1.HasValue ) return false; - if (!d2.HasValue) return false; + if (!d1.HasValue && !d2.HasValue) + return true; + if (!d1.HasValue) + return false; + if (!d2.HasValue) + return false; return d1.Value.IsEqual(d2.Value); } public static bool IsNotEqual(this double? d1, double? d2) { - if (!d1.HasValue && !d2.HasValue) return false; - if (!d1.HasValue) return true; - if (!d2.HasValue) return true; + if (!d1.HasValue && !d2.HasValue) + return false; + if (!d1.HasValue) + return true; + if (!d2.HasValue) + return true; return d1.Value.IsNotEqual(d2.Value); } } diff --git a/src/QLNet/Extensions/ListExtension.cs b/src/QLNet/Extensions/ListExtension.cs index ea12e84c6..80730890c 100644 --- a/src/QLNet/Extensions/ListExtension.cs +++ b/src/QLNet/Extensions/ListExtension.cs @@ -11,28 +11,28 @@ public static class ListExtension // size: desired new size // element: default value to insert - public static void Resize( this List list, int size, T element = default(T) ) + public static void Resize(this List list, int size, T element = default(T)) { int count = list.Count; - if ( size < count ) + if (size < count) { - list.RemoveRange( size, count - size ); + list.RemoveRange(size, count - size); } - else if ( size > count ) + else if (size > count) { - if ( size > list.Capacity ) // Optimization + if (size > list.Capacity) // Optimization list.Capacity = size; - list.AddRange( Enumerable.Repeat( element, size - count ) ); + list.AddRange(Enumerable.Repeat(element, size - count)); } } // erases the contents without changing the size - public static void Erase( this List list ) + public static void Erase(this List list) { - for ( int i = 0; i < list.Count; i++ ) - list[i] = default( T ); + for (int i = 0; i < list.Count; i++) + list[i] = default(T); } } } diff --git a/src/QLNet/Grid.cs b/src/QLNet/Grid.cs new file mode 100644 index 000000000..355027b7f --- /dev/null +++ b/src/QLNet/Grid.cs @@ -0,0 +1,54 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + public partial class Utils + { + + public static Vector CenteredGrid(double center, double dx, int steps) + { + Vector result = new Vector(steps + 1); + for (int i = 0; i < steps + 1; i++) + result[i] = center + (i - steps / 2.0) * dx; + return result; + } + + public static Vector BoundedGrid(double xMin, double xMax, int steps) + { + return new Vector(steps + 1, xMin, (xMax - xMin) / steps); + } + + public static Vector BoundedLogGrid(double xMin, double xMax, int steps) + { + Vector result = new Vector(steps + 1); + double gridLogSpacing = (Math.Log(xMax) - Math.Log(xMin)) / + (steps); + double edx = Math.Exp(gridLogSpacing); + result[0] = xMin; + for (int j = 1; j < steps + 1; j++) + { + result[j] = result[j - 1] * edx; + } + return result; + } + + } +} diff --git a/src/QLNet/Handle.cs b/src/QLNet/Handle.cs index 9bb7d9fa7..c845a91ce 100644 --- a/src/QLNet/Handle.cs +++ b/src/QLNet/Handle.cs @@ -6,7 +6,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -30,7 +30,7 @@ public class Handle where T : IObservable public Handle() : this(default(T)) { } - public Handle(T h ) : this(h, true) { } + public Handle(T h) : this(h, true) { } public Handle(T h, bool registerAsObserver) { @@ -47,7 +47,7 @@ public T link { get { - Utils.QL_REQUIRE(!empty(),()=> "empty Handle cannot be dereferenced"); + Utils.QL_REQUIRE(!empty(), () => "empty Handle cannot be dereferenced"); return link_.currentLink(); } } @@ -64,8 +64,10 @@ public T link public static bool operator ==(Handle here, Handle there) { - if (ReferenceEquals(here, there)) return true; - if ((object)here == null || (object)there == null) return false; + if (ReferenceEquals(here, there)) + return true; + if ((object)here == null || (object)there == null) + return false; return here.Equals(there); } @@ -105,7 +107,7 @@ public void linkTo(T h, bool registerAsObserver) h_ = h; isObserver_ = registerAsObserver; - if ( isObserver_) + if (isObserver_) { h_.registerWith(update); } @@ -126,8 +128,14 @@ public void linkTo(T h, bool registerAsObserver) public event Callback notifyObserversEvent { - add { eventSource.Subscribe(value); } - remove { eventSource.Unsubscribe(value); } + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } } public void registerWith(Callback handler) { notifyObserversEvent += handler; } @@ -149,7 +157,7 @@ public class RelinkableHandle : Handle where T : IObservable { public RelinkableHandle() : base(default(T), true) { } - public RelinkableHandle(T h ) : base(h, true) { } + public RelinkableHandle(T h) : base(h, true) { } public RelinkableHandle(T h, bool registerAsObserver) : base(h, registerAsObserver) { } diff --git a/src/QLNet/Index.cs b/src/QLNet/Index.cs index dfa6042c9..2efc981cb 100644 --- a/src/QLNet/Index.cs +++ b/src/QLNet/Index.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -32,101 +32,106 @@ public abstract class Index : IObservable // This method is used for output and comparison between indexes. // It is not meant to be used for writing switch-on-type code. public abstract string name(); - + // Returns the calendar defining valid fixing dates public abstract Calendar fixingCalendar(); - + // Returns TRUE if the fixing date is a valid one - public abstract bool isValidFixingDate( Date fixingDate ); - + public abstract bool isValidFixingDate(Date fixingDate); + // Returns the fixing at the given date // The date passed as arguments must be the actual calendar date of the fixing; no settlement days must be used. - public abstract double fixing( Date fixingDate, bool forecastTodaysFixing = false); - + public abstract double fixing(Date fixingDate, bool forecastTodaysFixing = false); + // Returns the fixing TimeSeries - public ObservableValue> timeSeries() { return IndexManager.instance().getHistory( name() ); } - + public TimeSeries < double? > timeSeries() { return IndexManager.instance().getHistory(name()); } + // Check if index allows for native fixings. // If this returns false, calls to addFixing and similar methods will raise an exception. public virtual bool allowsNativeFixings() { return true; } - + // Stores the historical fixing at the given date // The date passed as arguments must be the actual calendar date of the fixing; no settlement days must be used. - public virtual void addFixing( Date d, double v, bool forceOverwrite = false ) + public virtual void addFixing(Date d, double v, bool forceOverwrite = false) { checkNativeFixingsAllowed(); - addFixings( new TimeSeries() { { d, v } }, forceOverwrite ); + addFixings(new TimeSeries < double? >() { { d, v } }, forceOverwrite); } - + // Stores historical fixings from a TimeSeries // The dates in the TimeSeries must be the actual calendar dates of the fixings; no settlement days must be used. - public void addFixings(TimeSeries source, bool forceOverwrite = false ) + public void addFixings(TimeSeries < double? > source, bool forceOverwrite = false) { checkNativeFixingsAllowed(); - ObservableValue> target = IndexManager.instance().getHistory( name() ); - foreach ( Date d in source.Keys ) + TimeSeries < double? > target = IndexManager.instance().getHistory(name()); + foreach (Date d in source.Keys) { - if ( isValidFixingDate( d ) ) - if ( !target.value().ContainsKey( d ) ) - target.value().Add( d, source[d] ); + if (isValidFixingDate(d)) + if (!target.ContainsKey(d)) + target.Add(d, source[d]); + else if (forceOverwrite) + target[d] = source[d]; + else if (Utils.close(target[d].GetValueOrDefault(), source[d].GetValueOrDefault())) + continue; else - if ( forceOverwrite ) - target.value()[d] = source[d]; - else if ( Utils.close( target.value()[d].GetValueOrDefault(), source[d].GetValueOrDefault() ) ) - continue; - else - throw new ArgumentException( "Duplicated fixing provided: " + d + ", " + source[d] + - " while " + target.value()[d] + " value is already present" ); + throw new ArgumentException("Duplicated fixing provided: " + d + ", " + source[d] + + " while " + target[d] + " value is already present"); else - throw new ArgumentException( "Invalid fixing provided: " + d.DayOfWeek + " " + d + ", " + source[d] ); + throw new ArgumentException("Invalid fixing provided: " + d.DayOfWeek + " " + d + ", " + source[d]); } - IndexManager.instance().setHistory( name(), target ); + IndexManager.instance().setHistory(name(), target); } - + // Stores historical fixings at the given dates // The dates passed as arguments must be the actual calendar dates of the fixings; no settlement days must be used. - public void addFixings( List d, List v, bool forceOverwrite = false ) + public void addFixings(List d, List v, bool forceOverwrite = false) { - if ( ( d.Count != v.Count ) || d.Count == 0 ) - throw new ArgumentException( "Wrong collection dimensions when creating index fixings" ); + if ((d.Count != v.Count) || d.Count == 0) + throw new ArgumentException("Wrong collection dimensions when creating index fixings"); - TimeSeries t = new TimeSeries(); - for ( int i = 0; i < d.Count; i++ ) - t.Add( d[i], v[i] ); - addFixings( t, forceOverwrite ); + TimeSeries < double? > t = new TimeSeries < double? >(); + for (int i = 0; i < d.Count; i++) + t.Add(d[i], v[i]); + addFixings(t, forceOverwrite); } - + // Clears all stored historical fixings public void clearFixings() { checkNativeFixingsAllowed(); - IndexManager.instance().clearHistory( name() ); + IndexManager.instance().clearHistory(name()); } // Check if index allows for native fixings private void checkNativeFixingsAllowed() { - Utils.QL_REQUIRE( allowsNativeFixings(), ()=> - "native fixings not allowed for " + name() + "; refer to underlying indices instead" ); + Utils.QL_REQUIRE(allowsNativeFixings(), () => + "native fixings not allowed for " + name() + "; refer to underlying indices instead"); } - + #region observable interface private readonly WeakEventSource eventSource = new WeakEventSource(); public event Callback notifyObserversEvent { - add { eventSource.Subscribe( value ); } - remove { eventSource.Unsubscribe( value ); } + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } } - public void registerWith( Callback handler ) { notifyObserversEvent += handler; } - public void unregisterWith( Callback handler ) { notifyObserversEvent -= handler; } + public void registerWith(Callback handler) { notifyObserversEvent += handler; } + public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } protected void notifyObservers() { eventSource.Raise(); } #endregion } -} \ No newline at end of file +} diff --git a/src/QLNet/Indexes/bmaindex.cs b/src/QLNet/Indexes/BMAIndex.cs similarity index 52% rename from src/QLNet/Indexes/bmaindex.cs rename to src/QLNet/Indexes/BMAIndex.cs index c8f7f35ed..f9aec90e5 100644 --- a/src/QLNet/Indexes/bmaindex.cs +++ b/src/QLNet/Indexes/BMAIndex.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -30,59 +30,59 @@ correspondent of the 1M USD-Libor. */ public class BMAIndex : InterestRateIndex { - public BMAIndex( Handle h = null) - : base( "BMA", new Period( 1, TimeUnit.Weeks ), 1, new USDCurrency(), - new UnitedStates( UnitedStates.Market.NYSE ), new ActualActual( ActualActual.Convention.ISDA ) ) + public BMAIndex(Handle h = null) + : base("BMA", new Period(1, TimeUnit.Weeks), 1, new USDCurrency(), + new UnitedStates(UnitedStates.Market.NYSE), new ActualActual(ActualActual.Convention.ISDA)) { termStructure_ = h ?? new Handle(); - termStructure_.registerWith( update ); + termStructure_.registerWith(update); } // Index interface // BMA is fixed weekly on Wednesdays. public override string name() { return "BMA"; } - public override bool isValidFixingDate( Date fixingDate ) + public override bool isValidFixingDate(Date fixingDate) { Calendar cal = fixingCalendar(); // either the fixing date is last Wednesday, or all days // between last Wednesday included and the fixing date are // holidays - for ( Date d = Utils.previousWednesday( fixingDate ); d < fixingDate; ++d ) + for (Date d = Utils.previousWednesday(fixingDate); d < fixingDate; ++d) { - if ( cal.isBusinessDay( d ) ) + if (cal.isBusinessDay(d)) return false; } // also, the fixing date itself must be a business day - return cal.isBusinessDay( fixingDate ); + return cal.isBusinessDay(fixingDate); } // Inspectors public Handle forwardingTermStructure() { return termStructure_; } // Date calculations - public override Date maturityDate( Date valueDate ) + public override Date maturityDate(Date valueDate) { Calendar cal = fixingCalendar(); - Date fixingDate = cal.advance( valueDate, -1, TimeUnit.Days ); - Date nextWednesday = Utils.previousWednesday( fixingDate + 7 ); - return cal.advance( nextWednesday, 1, TimeUnit.Days ); + Date fixingDate = cal.advance(valueDate, -1, TimeUnit.Days); + Date nextWednesday = Utils.previousWednesday(fixingDate + 7); + return cal.advance(nextWednesday, 1, TimeUnit.Days); } // This method returns a schedule of fixing dates between start and end. - public Schedule fixingSchedule( Date start, Date end ) + public Schedule fixingSchedule(Date start, Date end) { - return new MakeSchedule().from( Utils.previousWednesday( start ) ) - .to( Utils.nextWednesday( end ) ) - .withFrequency( Frequency.Weekly ) - .withCalendar( fixingCalendar() ) - .withConvention( BusinessDayConvention.Following ) - .forwards() - .value(); + return new MakeSchedule().from(Utils.previousWednesday(start)) + .to(Utils.nextWednesday(end)) + .withFrequency(Frequency.Weekly) + .withCalendar(fixingCalendar()) + .withConvention(BusinessDayConvention.Following) + .forwards() + .value(); } - public override double forecastFixing( Date fixingDate ) + public override double forecastFixing(Date fixingDate) { - Utils.QL_REQUIRE( !termStructure_.empty(),()=> "null term structure set to this instance of " + name() ); - Date start = fixingCalendar().advance( fixingDate, 1, TimeUnit.Days ); - Date end = maturityDate( start ); - return termStructure_.link.forwardRate( start, end, dayCounter_, Compounding.Simple ).rate(); + Utils.QL_REQUIRE(!termStructure_.empty(), () => "null term structure set to this instance of " + name()); + Date start = fixingCalendar().advance(fixingDate, 1, TimeUnit.Days); + Date end = maturityDate(start); + return termStructure_.link.forwardRate(start, end, dayCounter_, Compounding.Simple).rate(); } protected Handle termStructure_; @@ -90,18 +90,18 @@ public override double forecastFixing( Date fixingDate ) public partial class Utils { - public static Date previousWednesday( Date date ) + public static Date previousWednesday(Date date) { int w = date.weekday(); - if ( w >= 4 ) // roll back w-4 days - return date - new Period( ( w - 4 ), TimeUnit.Days ); + if (w >= 4) // roll back w-4 days + return date - new Period((w - 4), TimeUnit.Days); else // roll forward 4-w days and back one week - return date + new Period( ( 4 - w - 7 ), TimeUnit.Days ); + return date + new Period((4 - w - 7), TimeUnit.Days); } - public static Date nextWednesday( Date date ) + public static Date nextWednesday(Date date) { - return previousWednesday( date + 7 ); + return previousWednesday(date + 7); } } } diff --git a/src/QLNet/Indexes/IBORIndex.cs b/src/QLNet/Indexes/IBORIndex.cs index fd4985644..905a0ec29 100644 --- a/src/QLNet/Indexes/IBORIndex.cs +++ b/src/QLNet/Indexes/IBORIndex.cs @@ -2,18 +2,18 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -25,43 +25,43 @@ namespace QLNet //! base class for Inter-Bank-Offered-Rate indexes (e.g. %Libor, etc.) public class IborIndex : InterestRateIndex { - public IborIndex( string familyName, - Period tenor, - int settlementDays, - Currency currency, - Calendar fixingCalendar, - BusinessDayConvention convention, - bool endOfMonth, - DayCounter dayCounter, - Handle h = null) - :base( familyName, tenor, settlementDays, currency, fixingCalendar, dayCounter ) + public IborIndex(string familyName, + Period tenor, + int settlementDays, + Currency currency, + Calendar fixingCalendar, + BusinessDayConvention convention, + bool endOfMonth, + DayCounter dayCounter, + Handle h = null) + : base(familyName, tenor, settlementDays, currency, fixingCalendar, dayCounter) { - + convention_ = convention; termStructure_ = h ?? new Handle(); endOfMonth_ = endOfMonth; // observer interface - if ( !termStructure_.empty() ) - termStructure_.registerWith( update ); + if (!termStructure_.empty()) + termStructure_.registerWith(update); } // InterestRateIndex interface - public override Date maturityDate( Date valueDate ) + public override Date maturityDate(Date valueDate) { - return fixingCalendar().advance( valueDate, tenor_, convention_, endOfMonth_ ); + return fixingCalendar().advance(valueDate, tenor_, convention_, endOfMonth_); } - public override double forecastFixing( Date fixingDate ) + public override double forecastFixing(Date fixingDate) { - Date d1 = valueDate( fixingDate ); - Date d2 = maturityDate( d1 ); - double t = dayCounter_.yearFraction( d1, d2 ); - Utils.QL_REQUIRE( t > 0.0,()=> - "\n cannot calculate forward rate between " + - d1 + " and " + d2 + - ":\n non positive time (" + t + - ") using " + dayCounter_.name() + " daycounter" ); - return forecastFixing( d1, d2, t ); + Date d1 = valueDate(fixingDate); + Date d2 = maturityDate(d1); + double t = dayCounter_.yearFraction(d1, d2); + Utils.QL_REQUIRE(t > 0.0, () => + "\n cannot calculate forward rate between " + + d1 + " and " + d2 + + ":\n non positive time (" + t + + ") using " + dayCounter_.name() + " daycounter"); + return forecastFixing(d1, d2, t); } // Inspectors public BusinessDayConvention businessDayConvention() { return convention_; } @@ -70,10 +70,10 @@ public override double forecastFixing( Date fixingDate ) public Handle forwardingTermStructure() { return termStructure_; } // Other methods // returns a copy of itself linked to a different forwarding curve - public virtual IborIndex clone( Handle forwarding ) + public virtual IborIndex clone(Handle forwarding) { - return new IborIndex( familyName(), tenor(), fixingDays(), currency(), fixingCalendar(), - businessDayConvention(), endOfMonth(), dayCounter(), forwarding ); + return new IborIndex(familyName(), tenor(), fixingDays(), currency(), fixingCalendar(), + businessDayConvention(), endOfMonth(), dayCounter(), forwarding); } protected BusinessDayConvention convention_; @@ -81,38 +81,38 @@ public virtual IborIndex clone( Handle forwarding ) protected bool endOfMonth_; - public double forecastFixing(Date d1,Date d2, double t) + public double forecastFixing(Date d1, Date d2, double t) { - Utils.QL_REQUIRE( !termStructure_.empty(),()=> "null term structure set to this instance of " + name() ); - double disc1 = termStructure_.link.discount( d1 ); - double disc2 = termStructure_.link.discount( d2 ); - return ( disc1 / disc2 - 1.0 ) / t; + Utils.QL_REQUIRE(!termStructure_.empty(), () => "null term structure set to this instance of " + name()); + double disc1 = termStructure_.link.discount(d1); + double disc2 = termStructure_.link.discount(d2); + return (disc1 / disc2 - 1.0) / t; } // need by CashFlowVectors public IborIndex() { } - + } public class OvernightIndex : IborIndex { - public OvernightIndex( string familyName, - int settlementDays, - Currency currency, - Calendar fixingCalendar, - DayCounter dayCounter, - Handle h = null) : - - base( familyName, new Period( 1, TimeUnit.Days ), settlementDays, - currency, fixingCalendar, BusinessDayConvention.Following, false, dayCounter, h ) + public OvernightIndex(string familyName, + int settlementDays, + Currency currency, + Calendar fixingCalendar, + DayCounter dayCounter, + Handle h = null) : + + base(familyName, new Period(1, TimeUnit.Days), settlementDays, + currency, fixingCalendar, BusinessDayConvention.Following, false, dayCounter, h) {} //! returns a copy of itself linked to a different forwarding curve - public new OvernightIndex clone( Handle h ) + public new OvernightIndex clone(Handle h) { - return new OvernightIndex( familyName(), fixingDays(), currency(), fixingCalendar(), - dayCounter(), h ); + return new OvernightIndex(familyName(), fixingDays(), currency(), fixingCalendar(), + dayCounter(), h); } } diff --git a/src/QLNet/Indexes/Ibor/Aonia.cs b/src/QLNet/Indexes/Ibor/Aonia.cs index cbd0c60eb..78283041e 100644 --- a/src/QLNet/Indexes/Ibor/Aonia.cs +++ b/src/QLNet/Indexes/Ibor/Aonia.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,9 +23,9 @@ namespace QLNet */ public class Aonia : OvernightIndex { - public Aonia( Handle h = null) - : base("Aonia", 0, new AUDCurrency(), new Australia(), new Actual365Fixed(), - h ?? new Handle()) + public Aonia(Handle h = null) + : base("Aonia", 0, new AUDCurrency(), new Australia(), new Actual365Fixed(), + h ?? new Handle()) {} } } diff --git a/src/QLNet/Indexes/Ibor/Audlibor.cs b/src/QLNet/Indexes/Ibor/Audlibor.cs index a1cc9afa3..09d81242b 100644 --- a/src/QLNet/Indexes/Ibor/Audlibor.cs +++ b/src/QLNet/Indexes/Ibor/Audlibor.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -25,12 +25,12 @@ namespace QLNet */ public class AUDLibor : Libor { - public AUDLibor( Period tenor ) - : base( "AUDLibor", tenor, 2, new AUDCurrency(), new Australia(), new Actual360(), new Handle() ) + public AUDLibor(Period tenor) + : base("AUDLibor", tenor, 2, new AUDCurrency(), new Australia(), new Actual360(), new Handle()) {} - public AUDLibor( Period tenor, Handle h ) - : base( "AUDLibor", tenor, 2, new AUDCurrency(), new Australia(), new Actual360(), h ) + public AUDLibor(Period tenor, Handle h) + : base("AUDLibor", tenor, 2, new AUDCurrency(), new Australia(), new Actual360(), h) {} } diff --git a/src/QLNet/Indexes/Ibor/Bbsw.cs b/src/QLNet/Indexes/Ibor/Bbsw.cs index 3218c4f17..751e81a04 100644 --- a/src/QLNet/Indexes/Ibor/Bbsw.cs +++ b/src/QLNet/Indexes/Ibor/Bbsw.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,63 +23,63 @@ namespace QLNet */ public class Bbsw : IborIndex { - public Bbsw( Period tenor, Handle h = null) - : base("Bbsw", tenor, - 0, // settlement days - new AUDCurrency(), new Australia(), - BusinessDayConvention.HalfMonthModifiedFollowing, true, - new Actual365Fixed(), h ?? new Handle()) + public Bbsw(Period tenor, Handle h = null) + : base("Bbsw", tenor, + 0, // settlement days + new AUDCurrency(), new Australia(), + BusinessDayConvention.HalfMonthModifiedFollowing, true, + new Actual365Fixed(), h ?? new Handle()) { - Utils.QL_REQUIRE(this.tenor().units() != TimeUnit.Days,()=> - "for daily tenors (" + this.tenor() + ") dedicated DailyTenor constructor must be used"); + Utils.QL_REQUIRE(this.tenor().units() != TimeUnit.Days, () => + "for daily tenors (" + this.tenor() + ") dedicated DailyTenor constructor must be used"); } } //! 1-month %Bbsw index - public class Bbsw1M : Bbsw + public class Bbsw1M : Bbsw { - public Bbsw1M( Handle h = null) - : base(new Period(1, TimeUnit.Months), h ?? new Handle()) + public Bbsw1M(Handle h = null) + : base(new Period(1, TimeUnit.Months), h ?? new Handle()) {} } //! 2-month %Bbsw index public class Bbsw2M : Bbsw { - public Bbsw2M( Handle h = null ) - : base( new Period( 2, TimeUnit.Months ), h ?? new Handle() ) + public Bbsw2M(Handle h = null) + : base(new Period(2, TimeUnit.Months), h ?? new Handle()) { } } //! 3-month %Bbsw index public class Bbsw3M : Bbsw { - public Bbsw3M( Handle h = null ) - : base( new Period( 3, TimeUnit.Months ), h ?? new Handle() ) + public Bbsw3M(Handle h = null) + : base(new Period(3, TimeUnit.Months), h ?? new Handle()) { } } //! 4-month %Bbsw index public class Bbsw4M : Bbsw { - public Bbsw4M( Handle h = null ) - : base( new Period( 4, TimeUnit.Months ), h ?? new Handle() ) + public Bbsw4M(Handle h = null) + : base(new Period(4, TimeUnit.Months), h ?? new Handle()) { } } //! 5-month %Bbsw index public class Bbsw5M : Bbsw { - public Bbsw5M( Handle h = null ) - : base( new Period( 5, TimeUnit.Months ), h ?? new Handle() ) + public Bbsw5M(Handle h = null) + : base(new Period(5, TimeUnit.Months), h ?? new Handle()) { } } //! 6-month %Bbsw index public class Bbsw6M : Bbsw { - public Bbsw6M( Handle h = null ) - : base( new Period( 6, TimeUnit.Months ), h ?? new Handle() ) + public Bbsw6M(Handle h = null) + : base(new Period(6, TimeUnit.Months), h ?? new Handle()) { } } } diff --git a/src/QLNet/Indexes/Ibor/Bkbm.cs b/src/QLNet/Indexes/Ibor/Bkbm.cs index 485e02ede..68b650fe9 100644 --- a/src/QLNet/Indexes/Ibor/Bkbm.cs +++ b/src/QLNet/Indexes/Ibor/Bkbm.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,63 +23,63 @@ namespace QLNet */ public class Bkbm : IborIndex { - public Bkbm( Period tenor, Handle h = null) - : base("Bkbm", tenor, - 0, // settlement days - new NZDCurrency(), new NewZealand(), - BusinessDayConvention.ModifiedFollowing, true, - new Actual365Fixed(), h ?? new Handle()) + public Bkbm(Period tenor, Handle h = null) + : base("Bkbm", tenor, + 0, // settlement days + new NZDCurrency(), new NewZealand(), + BusinessDayConvention.ModifiedFollowing, true, + new Actual365Fixed(), h ?? new Handle()) { - Utils.QL_REQUIRE(this.tenor().units() != TimeUnit.Days,()=> - "for daily tenors (" + this.tenor() + ") dedicated DailyTenor constructor must be used"); + Utils.QL_REQUIRE(this.tenor().units() != TimeUnit.Days, () => + "for daily tenors (" + this.tenor() + ") dedicated DailyTenor constructor must be used"); } } //! 1-month %Bkbm index - public class Bkbm1M : Bkbm + public class Bkbm1M : Bkbm { - public Bkbm1M( Handle h = null) - : base(new Period(1, TimeUnit.Months), h ?? new Handle()) + public Bkbm1M(Handle h = null) + : base(new Period(1, TimeUnit.Months), h ?? new Handle()) {} } //! 2-month %Bkbm index public class Bkbm2M : Bkbm { - public Bkbm2M( Handle h = null ) - : base( new Period( 2, TimeUnit.Months ), h ?? new Handle() ) + public Bkbm2M(Handle h = null) + : base(new Period(2, TimeUnit.Months), h ?? new Handle()) { } } //! 3-month %Bkbm index public class Bkbm3M : Bkbm { - public Bkbm3M( Handle h = null ) - : base( new Period( 3, TimeUnit.Months ), h ?? new Handle() ) + public Bkbm3M(Handle h = null) + : base(new Period(3, TimeUnit.Months), h ?? new Handle()) { } } //! 4-month %Bkbm index public class Bkbm4M : Bkbm { - public Bkbm4M( Handle h = null ) - : base( new Period( 4, TimeUnit.Months ), h ?? new Handle() ) + public Bkbm4M(Handle h = null) + : base(new Period(4, TimeUnit.Months), h ?? new Handle()) { } } //! 5-month %Bkbm index public class Bkbm5M : Bkbm { - public Bkbm5M( Handle h = null ) - : base( new Period( 5, TimeUnit.Months ), h ?? new Handle() ) + public Bkbm5M(Handle h = null) + : base(new Period(5, TimeUnit.Months), h ?? new Handle()) { } } //! 6-month %Bkbm index public class Bkbm6M : Bkbm { - public Bkbm6M( Handle h = null ) - : base( new Period( 6, TimeUnit.Months ), h ?? new Handle() ) + public Bkbm6M(Handle h = null) + : base(new Period(6, TimeUnit.Months), h ?? new Handle()) { } } diff --git a/src/QLNet/Indexes/Ibor/Cadlibor.cs b/src/QLNet/Indexes/Ibor/Cadlibor.cs index a8550138a..307c65ddf 100644 --- a/src/QLNet/Indexes/Ibor/Cadlibor.cs +++ b/src/QLNet/Indexes/Ibor/Cadlibor.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,32 +20,42 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! %CAD LIBOR rate - /*! Canadian Dollar LIBOR discontinued as of 2013. - \warning This is the rate fixed in London by BBA. Use CDOR if - you're interested in the Canadian fixing by IDA. - */ + /// + /// CAD LIBOR rate + /// + /// Conventions are taken from a number of sources including + /// OpenGamma "Interest Rate Instruments and Market Conventions + /// Guide", BBG, IKON. + /// + /// + /// Canadian Dollar LIBOR discontinued as of 2013. + /// This is the rate fixed in London by BBA. Use CDOR if + /// you're interested in the Canadian fixing by IDA. + /// + /// public class CADLibor : Libor { - public CADLibor( Period tenor ) - : base( "CADLibor", tenor, 2, new CADCurrency(), new Canada(), new Actual360(), new Handle() ) + public CADLibor(Period tenor) + : base("CADLibor", tenor, 0, new CADCurrency(), new Canada(), new Actual365Fixed(), new Handle()) {} - public CADLibor( Period tenor, Handle h ) - : base( "CADLibor", tenor, 2, new CADCurrency(), new Canada(), new Actual360(), h ) + public CADLibor(Period tenor, Handle h) + : base("CADLibor", tenor, 0, new CADCurrency(), new Canada(), new Actual365Fixed(), h) {} } - //! Overnight %CAD %Libor index + /// + /// Overnight CAD Libor index + /// public class CADLiborON : DailyTenorLibor { public CADLiborON() - : base( "CADLibor", 0, new CADCurrency(), new Canada(), new Actual360(), new Handle() ) + : base("CADLibor", 0, new CADCurrency(), new Canada(), new Actual365Fixed(), new Handle()) {} - public CADLiborON( Handle h ) - : base( "CADLibor", 0, new CADCurrency(), new Canada(), new Actual360(), h ) + public CADLiborON(Handle h) + : base("CADLibor", 0, new CADCurrency(), new Canada(), new Actual365Fixed(), h) {} } -} \ No newline at end of file +} diff --git a/src/QLNet/Indexes/Ibor/Cdor.cs b/src/QLNet/Indexes/Ibor/Cdor.cs index f09c1face..ac354efea 100644 --- a/src/QLNet/Indexes/Ibor/Cdor.cs +++ b/src/QLNet/Indexes/Ibor/Cdor.cs @@ -1,43 +1,46 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { +namespace QLNet +{ - //! %CDOR rate -// ! Canadian Dollar Offered Rate fixed by IDA. -// -// \warning This is the rate fixed in Canada by IDA. Use CADLibor -// if you're interested in the London fixing by BBA. -// -// \todo check settlement days, end-of-month adjustment, -// and day-count convention. -// - public class Cdor : IborIndex - { - public Cdor(Period tenor) - : base("CDOR", tenor, 2, new CADCurrency(), new Canada(), BusinessDayConvention.ModifiedFollowing, false, new Actual360(), new Handle()) - { - } + /// + /// CDOR rate + /// Canadian Dollar Offered Rate fixed by IDA. + /// + /// Conventions are taken from a number of sources including + /// OpenGamma "Interest Rate Instruments and Market Conventions + /// Guide", BBG, IKON. + /// + /// + /// This is the rate fixed in Canada by IDA. Use CADLibor + /// if you're interested in the London fixing by BBA. + /// + /// + public class Cdor : IborIndex + { + public Cdor(Period tenor) + : base("CDOR", tenor, 0, new CADCurrency(), new Canada(), BusinessDayConvention.ModifiedFollowing, false, new Actual365Fixed(), new Handle()) + {} - public Cdor(Period tenor, Handle h) - : base("CDOR", tenor, 2, new CADCurrency(), new Canada(), BusinessDayConvention.ModifiedFollowing, false, new Actual360(), h) - { - } - } + public Cdor(Period tenor, Handle h) + : base("CDOR", tenor, 0, new CADCurrency(), new Canada(), BusinessDayConvention.ModifiedFollowing, false, new Actual365Fixed(), h) + {} + } } diff --git a/src/QLNet/Indexes/Ibor/Chflibor.cs b/src/QLNet/Indexes/Ibor/Chflibor.cs index f60218bc6..9753b40ee 100644 --- a/src/QLNet/Indexes/Ibor/Chflibor.cs +++ b/src/QLNet/Indexes/Ibor/Chflibor.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -31,20 +31,20 @@ namespace QLNet */ public class CHFLibor : Libor { - public CHFLibor( Period tenor ) - : base( "CHFLibor", tenor, 2, new CHFCurrency(), new Switzerland(), new Actual360(), new Handle() ) + public CHFLibor(Period tenor) + : base("CHFLibor", tenor, 2, new CHFCurrency(), new Switzerland(), new Actual360(), new Handle()) {} - public CHFLibor( Period tenor, Handle h ) - : base( "CHFLibor", tenor, 2, new CHFCurrency(), new Switzerland(), new Actual360(), h ) + public CHFLibor(Period tenor, Handle h) + : base("CHFLibor", tenor, 2, new CHFCurrency(), new Switzerland(), new Actual360(), h) {} } //! base class for the one day deposit BBA %CHF %LIBOR indexes public class DailyTenorCHFLibor : DailyTenorLibor { - public DailyTenorCHFLibor( int settlementDays, Handle h ) - : base( "CHFLibor", settlementDays, new CHFCurrency(), new Switzerland(), new Actual360(), h ) + public DailyTenorCHFLibor(int settlementDays, Handle h) + : base("CHFLibor", settlementDays, new CHFCurrency(), new Switzerland(), new Actual360(), h) { } } } diff --git a/src/QLNet/Indexes/Ibor/Dkklibor.cs b/src/QLNet/Indexes/Ibor/Dkklibor.cs index 0e993e02b..49afa2c61 100644 --- a/src/QLNet/Indexes/Ibor/Dkklibor.cs +++ b/src/QLNet/Indexes/Ibor/Dkklibor.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -25,12 +25,12 @@ namespace QLNet */ public class DKKLibor : Libor { - public DKKLibor( Period tenor ) - : base( "DKKLibor", tenor, 2, new DKKCurrency(), new Denmark(), new Actual360(), new Handle() ) + public DKKLibor(Period tenor) + : base("DKKLibor", tenor, 2, new DKKCurrency(), new Denmark(), new Actual360(), new Handle()) {} - public DKKLibor( Period tenor, Handle h ) - : base( "DKKLibor", tenor, 2, new DKKCurrency(), new Denmark(), new Actual360(), h ) + public DKKLibor(Period tenor, Handle h) + : base("DKKLibor", tenor, 2, new DKKCurrency(), new Denmark(), new Actual360(), h) {} } diff --git a/src/QLNet/Indexes/Ibor/Eonia.cs b/src/QLNet/Indexes/Ibor/Eonia.cs index 31030577c..d1e5320c7 100644 --- a/src/QLNet/Indexes/Ibor/Eonia.cs +++ b/src/QLNet/Indexes/Ibor/Eonia.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - * + * This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,7 +24,7 @@ public class Eonia : OvernightIndex { public Eonia() : this(new Handle()) { } - public Eonia(Handle h) + public Eonia(Handle h) : base("Eonia", 0, new EURCurrency(), new TARGET(), new Actual360(), h) {} } } diff --git a/src/QLNet/Indexes/Ibor/Euribor.cs b/src/QLNet/Indexes/Ibor/Euribor.cs index 85a489bb2..aa2f635cc 100644 --- a/src/QLNet/Indexes/Ibor/Euribor.cs +++ b/src/QLNet/Indexes/Ibor/Euribor.cs @@ -1,144 +1,164 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - public static partial class Utils { - public static BusinessDayConvention euriborConvention(Period p) { - switch (p.units()) { - case TimeUnit.Days: - case TimeUnit.Weeks: - return BusinessDayConvention.Following; - case TimeUnit.Months: - case TimeUnit.Years: - return BusinessDayConvention.ModifiedFollowing; - default: - throw new ArgumentException("Unknown TimeUnit: " + p.units()); - } - } - - public static bool euriborEOM(Period p) { - switch (p.units()) { - case TimeUnit.Days: - case TimeUnit.Weeks: - return false; - case TimeUnit.Months: - case TimeUnit.Years: - return true; - default: - throw new ArgumentException("Unknown TimeUnit: " + p.units()); - } - } - } - /// - /// %Euribor index - /// Euribor rate fixed by the ECB. - /// This is the rate fixed by the ECB. Use EurLibor if you're interested in the London fixing by BBA. - /// - public class Euribor : IborIndex { - public Euribor(Period tenor) : this(tenor, new Handle()) { } - public Euribor(Period tenor, Handle h) : - base("Euribor", tenor, 2, // settlementDays - new EURCurrency(), new TARGET(), - Utils.euriborConvention(tenor), Utils.euriborEOM(tenor), - new Actual360(), h) { - Utils.QL_REQUIRE(this.tenor().units() != TimeUnit.Days,()=> - "for daily tenors (" + this.tenor() + ") dedicated DailyTenor constructor must be used"); - } - } - - //! Actual/365 %Euribor index - /*! Euribor rate adjusted for the mismatch between the actual/360 - convention used for Euribor and the actual/365 convention - previously used by a few pre-EUR currencies. - */ - public class Euribor365 : IborIndex { - public Euribor365(Period tenor) : this(tenor, new Handle()) { } - public Euribor365(Period tenor, Handle h) - : base("Euribor365", tenor, - 2, // settlement days - new EURCurrency(), new TARGET(), Utils.euriborConvention(tenor), Utils.euriborEOM(tenor), - new Actual365Fixed(), h) { - Utils.QL_REQUIRE(this.tenor().units() != TimeUnit.Days, () => - "for daily tenors (" + this.tenor() + ") dedicated DailyTenor constructor must be used"); - } - } - - //! 1-week %Euribor index - public class EuriborSW : Euribor { - public EuriborSW() : this(new Handle()) { } - public EuriborSW(Handle h) : base(new Period(1, TimeUnit.Weeks), h) { } - } - - //! 2-weeks %Euribor index - public class Euribor2W : Euribor { - public Euribor2W() : this(new Handle()) { } - public Euribor2W(Handle h) : base(new Period(2, TimeUnit.Weeks), h) { } - } - - //! 3-weeks %Euribor index - public class Euribor3W : Euribor { - public Euribor3W() : this(new Handle()) { } - public Euribor3W(Handle h) : base(new Period(3, TimeUnit.Weeks), h) { } - } - - //! 1-month %Euribor index - public class Euribor1M : Euribor { - public Euribor1M() : this(new Handle()) { } - public Euribor1M(Handle h) : base(new Period(1, TimeUnit.Months), h) { } - } - - //! 2-months %Euribor index - public class Euribor2M : Euribor { - public Euribor2M() : this(new Handle()) { } - public Euribor2M(Handle h) : base(new Period(2, TimeUnit.Months), h) { } - } - - // 3-months %Euribor index - public class Euribor3M : Euribor { - public Euribor3M() : this(new Handle()) { } - public Euribor3M(Handle h) : base(new Period(3, TimeUnit.Months), h) {} - } - - // 4-months %Euribor index - public class Euribor4M : Euribor { - public Euribor4M() : this(new Handle()) { } - public Euribor4M(Handle h) : base(new Period(4, TimeUnit.Months), h) { } - } - - // 5-months %Euribor index - public class Euribor5M : Euribor { - public Euribor5M() : this(new Handle()) { } - public Euribor5M(Handle h) : base(new Period(5, TimeUnit.Months), h) { } - } - - // 6-months %Euribor index - public class Euribor6M : Euribor { - public Euribor6M() : this(new Handle()) { } - public Euribor6M(Handle h) : base(new Period(6, TimeUnit.Months), h) { } - } - - // 1-year %Euribor index - public class Euribor1Y : Euribor { - public Euribor1Y() : this(new Handle()) { } - public Euribor1Y(Handle h) : base(new Period(1, TimeUnit.Years), h) { } - - } +namespace QLNet +{ + public static partial class Utils + { + public static BusinessDayConvention euriborConvention(Period p) + { + switch (p.units()) + { + case TimeUnit.Days: + case TimeUnit.Weeks: + return BusinessDayConvention.Following; + case TimeUnit.Months: + case TimeUnit.Years: + return BusinessDayConvention.ModifiedFollowing; + default: + throw new ArgumentException("Unknown TimeUnit: " + p.units()); + } + } + + public static bool euriborEOM(Period p) + { + switch (p.units()) + { + case TimeUnit.Days: + case TimeUnit.Weeks: + return false; + case TimeUnit.Months: + case TimeUnit.Years: + return true; + default: + throw new ArgumentException("Unknown TimeUnit: " + p.units()); + } + } + } + /// + /// %Euribor index + /// Euribor rate fixed by the ECB. + /// This is the rate fixed by the ECB. Use EurLibor if you're interested in the London fixing by BBA. + /// + public class Euribor : IborIndex + { + public Euribor(Period tenor) : this(tenor, new Handle()) { } + public Euribor(Period tenor, Handle h) : + base("Euribor", tenor, 2, // settlementDays + new EURCurrency(), new TARGET(), + Utils.euriborConvention(tenor), Utils.euriborEOM(tenor), + new Actual360(), h) + { + Utils.QL_REQUIRE(this.tenor().units() != TimeUnit.Days, () => + "for daily tenors (" + this.tenor() + ") dedicated DailyTenor constructor must be used"); + } + } + + //! Actual/365 %Euribor index + /*! Euribor rate adjusted for the mismatch between the actual/360 + convention used for Euribor and the actual/365 convention + previously used by a few pre-EUR currencies. + */ + public class Euribor365 : IborIndex + { + public Euribor365(Period tenor) : this(tenor, new Handle()) { } + public Euribor365(Period tenor, Handle h) + : base("Euribor365", tenor, + 2, // settlement days + new EURCurrency(), new TARGET(), Utils.euriborConvention(tenor), Utils.euriborEOM(tenor), + new Actual365Fixed(), h) + { + Utils.QL_REQUIRE(this.tenor().units() != TimeUnit.Days, () => + "for daily tenors (" + this.tenor() + ") dedicated DailyTenor constructor must be used"); + } + } + + //! 1-week %Euribor index + public class EuriborSW : Euribor + { + public EuriborSW() : this(new Handle()) { } + public EuriborSW(Handle h) : base(new Period(1, TimeUnit.Weeks), h) { } + } + + //! 2-weeks %Euribor index + public class Euribor2W : Euribor + { + public Euribor2W() : this(new Handle()) { } + public Euribor2W(Handle h) : base(new Period(2, TimeUnit.Weeks), h) { } + } + + //! 3-weeks %Euribor index + public class Euribor3W : Euribor + { + public Euribor3W() : this(new Handle()) { } + public Euribor3W(Handle h) : base(new Period(3, TimeUnit.Weeks), h) { } + } + + //! 1-month %Euribor index + public class Euribor1M : Euribor + { + public Euribor1M() : this(new Handle()) { } + public Euribor1M(Handle h) : base(new Period(1, TimeUnit.Months), h) { } + } + + //! 2-months %Euribor index + public class Euribor2M : Euribor + { + public Euribor2M() : this(new Handle()) { } + public Euribor2M(Handle h) : base(new Period(2, TimeUnit.Months), h) { } + } + + // 3-months %Euribor index + public class Euribor3M : Euribor + { + public Euribor3M() : this(new Handle()) { } + public Euribor3M(Handle h) : base(new Period(3, TimeUnit.Months), h) {} + } + + // 4-months %Euribor index + public class Euribor4M : Euribor + { + public Euribor4M() : this(new Handle()) { } + public Euribor4M(Handle h) : base(new Period(4, TimeUnit.Months), h) { } + } + + // 5-months %Euribor index + public class Euribor5M : Euribor + { + public Euribor5M() : this(new Handle()) { } + public Euribor5M(Handle h) : base(new Period(5, TimeUnit.Months), h) { } + } + + // 6-months %Euribor index + public class Euribor6M : Euribor + { + public Euribor6M() : this(new Handle()) { } + public Euribor6M(Handle h) : base(new Period(6, TimeUnit.Months), h) { } + } + + // 1-year %Euribor index + public class Euribor1Y : Euribor + { + public Euribor1Y() : this(new Handle()) { } + public Euribor1Y(Handle h) : base(new Period(1, TimeUnit.Years), h) { } + + } } diff --git a/src/QLNet/Indexes/Ibor/Eurlibor.cs b/src/QLNet/Indexes/Ibor/Eurlibor.cs index fba03f49d..41fc1bc88 100644 --- a/src/QLNet/Indexes/Ibor/Eurlibor.cs +++ b/src/QLNet/Indexes/Ibor/Eurlibor.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,9 +23,9 @@ namespace QLNet { public static partial class Utils { - public static BusinessDayConvention eurliborConvention( Period p ) + public static BusinessDayConvention eurliborConvention(Period p) { - switch ( p.units() ) + switch (p.units()) { case TimeUnit.Days: case TimeUnit.Weeks: @@ -34,13 +34,13 @@ public static BusinessDayConvention eurliborConvention( Period p ) case TimeUnit.Years: return BusinessDayConvention.ModifiedFollowing; default: - throw new ArgumentException( "Unknown TimeUnit: " + p.units() ); + throw new ArgumentException("Unknown TimeUnit: " + p.units()); } } - public static bool eurliborEOM( Period p ) + public static bool eurliborEOM(Period p) { - switch ( p.units() ) + switch (p.units()) { case TimeUnit.Days: case TimeUnit.Weeks: @@ -49,7 +49,7 @@ public static bool eurliborEOM( Period p ) case TimeUnit.Years: return true; default: - throw new ArgumentException( "Unknown TimeUnit: " + p.units() ); + throw new ArgumentException("Unknown TimeUnit: " + p.units()); } } } @@ -70,47 +70,47 @@ public class EURLibor : IborIndex // JoinBusinessDays is the fixing calendar for // all indexes but o/n - public EURLibor( Period tenor ) - : base( "EURLibor", tenor, 2, new EURCurrency(), new JointCalendar( new UnitedKingdom( UnitedKingdom.Market.Exchange ), new TARGET(), - JointCalendar.JointCalendarRule.JoinHolidays ), - Utils.eurliborConvention( tenor ), Utils.eurliborEOM( tenor ), new Actual360(), - new Handle() ) + public EURLibor(Period tenor) + : base("EURLibor", tenor, 2, new EURCurrency(), new JointCalendar(new UnitedKingdom(UnitedKingdom.Market.Exchange), new TARGET(), + JointCalendar.JointCalendarRule.JoinHolidays), + Utils.eurliborConvention(tenor), Utils.eurliborEOM(tenor), new Actual360(), + new Handle()) { target_ = new TARGET(); - Utils.QL_REQUIRE( this.tenor().units() != TimeUnit.Days,()=> - "for daily tenors (" + this.tenor() + ") dedicated DailyTenor constructor must be used" ); + Utils.QL_REQUIRE(this.tenor().units() != TimeUnit.Days, () => + "for daily tenors (" + this.tenor() + ") dedicated DailyTenor constructor must be used"); } - public EURLibor( Period tenor, Handle h ) - : base( "EURLibor", tenor, 2, new EURCurrency(), new JointCalendar( new UnitedKingdom( UnitedKingdom.Market.Exchange ), new TARGET(), - JointCalendar.JointCalendarRule.JoinHolidays ), - Utils.eurliborConvention( tenor ), Utils.eurliborEOM( tenor ), new Actual360(), h ) + public EURLibor(Period tenor, Handle h) + : base("EURLibor", tenor, 2, new EURCurrency(), new JointCalendar(new UnitedKingdom(UnitedKingdom.Market.Exchange), new TARGET(), + JointCalendar.JointCalendarRule.JoinHolidays), + Utils.eurliborConvention(tenor), Utils.eurliborEOM(tenor), new Actual360(), h) { target_ = new TARGET(); Utils.QL_REQUIRE(this.tenor().units() != TimeUnit.Days, () => - "for daily tenors (" + this.tenor() + ") dedicated DailyTenor constructor must be used" ); + "for daily tenors (" + this.tenor() + ") dedicated DailyTenor constructor must be used"); } /* Date calculations See . */ - public override Date valueDate( Date fixingDate ) + public override Date valueDate(Date fixingDate) { - Utils.QL_REQUIRE(isValidFixingDate(fixingDate),()=> "Fixing date " + fixingDate + " is not valid"); + Utils.QL_REQUIRE(isValidFixingDate(fixingDate), () => "Fixing date " + fixingDate + " is not valid"); // http://www.bba.org.uk/bba/jsp/polopoly.jsp?d=225&a=1412 : // In the case of EUR the Value Date shall be two TARGET // business days after the Fixing Date. - return target_.advance( fixingDate, fixingDays_, TimeUnit.Days ); + return target_.advance(fixingDate, fixingDays_, TimeUnit.Days); } - public override Date maturityDate( Date valueDate ) + public override Date maturityDate(Date valueDate) { // http://www.bba.org.uk/bba/jsp/polopoly.jsp?d=225&a=1412 : // In the case of EUR only, maturity dates will be based on days in // which the Target system is open. - return target_.advance( valueDate, tenor_, convention_, endOfMonth() ); + return target_.advance(valueDate, tenor_, convention_, endOfMonth()); } } @@ -130,18 +130,18 @@ public class DailyTenorEURLibor : IborIndex // no o/n or s/n fixings (as the case may be) will take place // when the principal centre of the currency concerned is // closed but London is open on the fixing day. - public DailyTenorEURLibor( int settlementDays ) - : this( settlementDays, new Handle() ) + public DailyTenorEURLibor(int settlementDays) + : this(settlementDays, new Handle()) {} public DailyTenorEURLibor() - : base( "EURLibor", new Period( 1, TimeUnit.Days ), 0, new EURCurrency(), new TARGET(), - Utils.eurliborConvention( new Period( 1, TimeUnit.Days ) ), Utils.eurliborEOM( new Period( 1, TimeUnit.Days ) ), new Actual360(), new Handle() ) + : base("EURLibor", new Period(1, TimeUnit.Days), 0, new EURCurrency(), new TARGET(), + Utils.eurliborConvention(new Period(1, TimeUnit.Days)), Utils.eurliborEOM(new Period(1, TimeUnit.Days)), new Actual360(), new Handle()) {} - public DailyTenorEURLibor( int settlementDays, Handle h ) - : base( "EURLibor", new Period( 1, TimeUnit.Days ), settlementDays, new EURCurrency(), new TARGET(), - Utils.eurliborConvention( new Period( 1, TimeUnit.Days ) ), Utils.eurliborEOM( new Period( 1, TimeUnit.Days ) ), new Actual360(), h ) + public DailyTenorEURLibor(int settlementDays, Handle h) + : base("EURLibor", new Period(1, TimeUnit.Days), settlementDays, new EURCurrency(), new TARGET(), + Utils.eurliborConvention(new Period(1, TimeUnit.Days)), Utils.eurliborEOM(new Period(1, TimeUnit.Days)), new Actual360(), h) {} } @@ -150,11 +150,11 @@ public DailyTenorEURLibor( int settlementDays, Handle h ) public class EURLiborON : DailyTenorEURLibor { public EURLiborON() - : base( 0, new Handle() ) + : base(0, new Handle()) {} - public EURLiborON( Handle h ) - : base( 0, h ) + public EURLiborON(Handle h) + : base(0, h) {} } @@ -162,10 +162,10 @@ public EURLiborON( Handle h ) public class EURLiborSW : EURLibor { public EURLiborSW() - : base( new Period( 1, TimeUnit.Weeks ), new Handle() ) + : base(new Period(1, TimeUnit.Weeks), new Handle()) {} - public EURLiborSW( Handle h ) - : base( new Period( 1, TimeUnit.Weeks ), h ) + public EURLiborSW(Handle h) + : base(new Period(1, TimeUnit.Weeks), h) {} } @@ -173,11 +173,11 @@ public EURLiborSW( Handle h ) public class EURLibor2W : EURLibor { public EURLibor2W() - : base( new Period( 2, TimeUnit.Weeks ), new Handle() ) + : base(new Period(2, TimeUnit.Weeks), new Handle()) {} - public EURLibor2W( Handle h ) - : base( new Period( 2, TimeUnit.Weeks ), h ) + public EURLibor2W(Handle h) + : base(new Period(2, TimeUnit.Weeks), h) {} } @@ -187,11 +187,11 @@ public EURLibor2W( Handle h ) public class EURLibor1M : EURLibor { public EURLibor1M() - : base( new Period( 1, TimeUnit.Months ), new Handle() ) + : base(new Period(1, TimeUnit.Months), new Handle()) {} - public EURLibor1M( Handle h ) - : base( new Period( 1, TimeUnit.Months ), h ) + public EURLibor1M(Handle h) + : base(new Period(1, TimeUnit.Months), h) {} } @@ -200,11 +200,11 @@ public EURLibor1M( Handle h ) public class EURLibor2M : EURLibor { public EURLibor2M() - : base( new Period( 2, TimeUnit.Months ), new Handle() ) + : base(new Period(2, TimeUnit.Months), new Handle()) {} - public EURLibor2M( Handle h ) - : base( new Period( 2, TimeUnit.Months ), h ) + public EURLibor2M(Handle h) + : base(new Period(2, TimeUnit.Months), h) {} } @@ -213,11 +213,11 @@ public EURLibor2M( Handle h ) public class EURLibor3M : EURLibor { public EURLibor3M() - : base( new Period( 3, TimeUnit.Months ), new Handle() ) + : base(new Period(3, TimeUnit.Months), new Handle()) {} - public EURLibor3M( Handle h ) - : base( new Period( 3, TimeUnit.Months ), h ) + public EURLibor3M(Handle h) + : base(new Period(3, TimeUnit.Months), h) {} } @@ -226,11 +226,11 @@ public EURLibor3M( Handle h ) public class EURLibor4M : EURLibor { public EURLibor4M() - : base( new Period( 4, TimeUnit.Months ), new Handle() ) + : base(new Period(4, TimeUnit.Months), new Handle()) {} - public EURLibor4M( Handle h ) - : base( new Period( 4, TimeUnit.Months ), h ) + public EURLibor4M(Handle h) + : base(new Period(4, TimeUnit.Months), h) {} } @@ -239,11 +239,11 @@ public EURLibor4M( Handle h ) public class EURLibor5M : EURLibor { public EURLibor5M() - : base( new Period( 5, TimeUnit.Months ), new Handle() ) + : base(new Period(5, TimeUnit.Months), new Handle()) {} - public EURLibor5M( Handle h ) - : base( new Period( 5, TimeUnit.Months ), h ) + public EURLibor5M(Handle h) + : base(new Period(5, TimeUnit.Months), h) {} } @@ -252,11 +252,11 @@ public EURLibor5M( Handle h ) public class EURLibor6M : EURLibor { public EURLibor6M() - : base( new Period( 6, TimeUnit.Months ), new Handle() ) + : base(new Period(6, TimeUnit.Months), new Handle()) {} - public EURLibor6M( Handle h ) - : base( new Period( 6, TimeUnit.Months ), h ) + public EURLibor6M(Handle h) + : base(new Period(6, TimeUnit.Months), h) {} } @@ -265,11 +265,11 @@ public EURLibor6M( Handle h ) public class EURLibor7M : EURLibor { public EURLibor7M() - : base( new Period( 7, TimeUnit.Months ), new Handle() ) + : base(new Period(7, TimeUnit.Months), new Handle()) {} - public EURLibor7M( Handle h ) - : base( new Period( 7, TimeUnit.Months ), h ) + public EURLibor7M(Handle h) + : base(new Period(7, TimeUnit.Months), h) {} } @@ -278,11 +278,11 @@ public EURLibor7M( Handle h ) public class EURLibor8M : EURLibor { public EURLibor8M() - : base( new Period( 8, TimeUnit.Months ), new Handle() ) + : base(new Period(8, TimeUnit.Months), new Handle()) {} - public EURLibor8M( Handle h ) - : base( new Period( 8, TimeUnit.Months ), h ) + public EURLibor8M(Handle h) + : base(new Period(8, TimeUnit.Months), h) {} } @@ -291,11 +291,11 @@ public EURLibor8M( Handle h ) public class EURLibor9M : EURLibor { public EURLibor9M() - : base( new Period( 9, TimeUnit.Months ), new Handle() ) + : base(new Period(9, TimeUnit.Months), new Handle()) {} - public EURLibor9M( Handle h ) - : base( new Period( 9, TimeUnit.Months ), h ) + public EURLibor9M(Handle h) + : base(new Period(9, TimeUnit.Months), h) {} } @@ -304,11 +304,11 @@ public EURLibor9M( Handle h ) public class EURLibor10M : EURLibor { public EURLibor10M() - : base( new Period( 10, TimeUnit.Months ), new Handle() ) + : base(new Period(10, TimeUnit.Months), new Handle()) {} - public EURLibor10M( Handle h ) - : base( new Period( 10, TimeUnit.Months ), h ) + public EURLibor10M(Handle h) + : base(new Period(10, TimeUnit.Months), h) {} } @@ -317,11 +317,11 @@ public EURLibor10M( Handle h ) public class EURLibor11M : EURLibor { public EURLibor11M() - : base( new Period( 11, TimeUnit.Months ), new Handle() ) + : base(new Period(11, TimeUnit.Months), new Handle()) {} - public EURLibor11M( Handle h ) - : base( new Period( 11, TimeUnit.Months ), h ) + public EURLibor11M(Handle h) + : base(new Period(11, TimeUnit.Months), h) {} } @@ -330,11 +330,11 @@ public EURLibor11M( Handle h ) public class EURLibor1Y : EURLibor { public EURLibor1Y() - : base( new Period( 1, TimeUnit.Years ), new Handle() ) + : base(new Period(1, TimeUnit.Years), new Handle()) {} - public EURLibor1Y( Handle h ) - : base( new Period( 1, TimeUnit.Years ), h ) + public EURLibor1Y(Handle h) + : base(new Period(1, TimeUnit.Years), h) {} } diff --git a/src/QLNet/Indexes/Ibor/FedFunds.cs b/src/QLNet/Indexes/Ibor/FedFunds.cs index dbcc9c9c7..79dbe233f 100644 --- a/src/QLNet/Indexes/Ibor/FedFunds.cs +++ b/src/QLNet/Indexes/Ibor/FedFunds.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,8 +21,8 @@ namespace QLNet { public class FedFunds : OvernightIndex { - public FedFunds(Handle h = null) - :base("FedFunds", 0, new USDCurrency(), new UnitedStates(UnitedStates.Market.Settlement), + public FedFunds(Handle h = null) + : base("FedFunds", 0, new USDCurrency(), new UnitedStates(UnitedStates.Market.Settlement), new Actual360(), h ?? new Handle()) {} } } diff --git a/src/QLNet/Indexes/Ibor/Gbplibor.cs b/src/QLNet/Indexes/Ibor/Gbplibor.cs index e436902a0..95f943bc3 100644 --- a/src/QLNet/Indexes/Ibor/Gbplibor.cs +++ b/src/QLNet/Indexes/Ibor/Gbplibor.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -28,13 +28,13 @@ namespace QLNet */ public class GBPLibor : Libor { - public GBPLibor( Period tenor ) - : base( "GBPLibor", tenor, 0, new GBPCurrency(), new UnitedKingdom( UnitedKingdom.Market.Exchange ), new Actual365Fixed(), - new Handle() ) + public GBPLibor(Period tenor) + : base("GBPLibor", tenor, 0, new GBPCurrency(), new UnitedKingdom(UnitedKingdom.Market.Exchange), new Actual365Fixed(), + new Handle()) {} - public GBPLibor( Period tenor, Handle h ) - : base( "GBPLibor", tenor, 0, new GBPCurrency(), new UnitedKingdom( UnitedKingdom.Market.Exchange ), new Actual365Fixed(), h ) + public GBPLibor(Period tenor, Handle h) + : base("GBPLibor", tenor, 0, new GBPCurrency(), new UnitedKingdom(UnitedKingdom.Market.Exchange), new Actual365Fixed(), h) {} } @@ -42,16 +42,16 @@ public GBPLibor( Period tenor, Handle h ) //! Base class for the one day deposit ICE %GBP %LIBOR indexes public class DailyTenorGBPLibor : DailyTenorLibor { - public DailyTenorGBPLibor( int settlementDays, Handle h ) - : base( "GBPLibor", settlementDays, new GBPCurrency(), new UnitedKingdom( UnitedKingdom.Market.Exchange ), - new Actual365Fixed(), h ) + public DailyTenorGBPLibor(int settlementDays, Handle h) + : base("GBPLibor", settlementDays, new GBPCurrency(), new UnitedKingdom(UnitedKingdom.Market.Exchange), + new Actual365Fixed(), h) {} } //! Overnight %GBP %Libor index public class GBPLiborON : DailyTenorGBPLibor { - public GBPLiborON( Handle h ) : base( 0, h ) + public GBPLiborON(Handle h) : base(0, h) {} } } diff --git a/src/QLNet/Indexes/Ibor/Jibar.cs b/src/QLNet/Indexes/Ibor/Jibar.cs index ba24c1c0d..f478f7d4e 100644 --- a/src/QLNet/Indexes/Ibor/Jibar.cs +++ b/src/QLNet/Indexes/Ibor/Jibar.cs @@ -1,39 +1,40 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { +namespace QLNet +{ - //! %JIBAR rate + //! %JIBAR rate // ! Johannesburg Interbank Agreed Rate // // \todo check settlement days and day-count convention. -// - public class Jibar : IborIndex - { - public Jibar(Period tenor) - : base("Jibar", tenor, 0, new ZARCurrency(), new SouthAfrica(), BusinessDayConvention.ModifiedFollowing, false, new Actual365Fixed(), new Handle()) - { - } - public Jibar(Period tenor, Handle h) - : base("Jibar", tenor, 0, new ZARCurrency(), new SouthAfrica(), BusinessDayConvention.ModifiedFollowing, false, new Actual365Fixed(), h) - { - } - } +// + public class Jibar : IborIndex + { + public Jibar(Period tenor) + : base("Jibar", tenor, 0, new ZARCurrency(), new SouthAfrica(), BusinessDayConvention.ModifiedFollowing, false, new Actual365Fixed(), new Handle()) + { + } + public Jibar(Period tenor, Handle h) + : base("Jibar", tenor, 0, new ZARCurrency(), new SouthAfrica(), BusinessDayConvention.ModifiedFollowing, false, new Actual365Fixed(), h) + { + } + } } diff --git a/src/QLNet/Indexes/Ibor/Jpylibor.cs b/src/QLNet/Indexes/Ibor/Jpylibor.cs index 9d879074b..1f6ec9295 100644 --- a/src/QLNet/Indexes/Ibor/Jpylibor.cs +++ b/src/QLNet/Indexes/Ibor/Jpylibor.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -31,12 +31,12 @@ namespace QLNet */ public class JPYLibor : Libor { - public JPYLibor( Period tenor ) - : base( "JPYLibor", tenor, 2, new JPYCurrency(), new Japan(), new Actual360(), new Handle() ) + public JPYLibor(Period tenor) + : base("JPYLibor", tenor, 2, new JPYCurrency(), new Japan(), new Actual360(), new Handle()) {} - public JPYLibor( Period tenor, Handle h ) - : base( "JPYLibor", tenor, 2, new JPYCurrency(), new Japan(), new Actual360(), h ) + public JPYLibor(Period tenor, Handle h) + : base("JPYLibor", tenor, 2, new JPYCurrency(), new Japan(), new Actual360(), h) {} } @@ -44,11 +44,11 @@ public JPYLibor( Period tenor, Handle h ) //! base class for the one day deposit ICE %JPY %LIBOR indexes public class DailyTenorJPYLibor : DailyTenorLibor { - public DailyTenorJPYLibor( int settlementDays ) : this( settlementDays, new Handle() ) + public DailyTenorJPYLibor(int settlementDays) : this(settlementDays, new Handle()) {} - public DailyTenorJPYLibor( int settlementDays, Handle h ) - : base( "JPYLibor", settlementDays, new JPYCurrency(), new Japan(), new Actual360(), h ) + public DailyTenorJPYLibor(int settlementDays, Handle h) + : base("JPYLibor", settlementDays, new JPYCurrency(), new Japan(), new Actual360(), h) {} } } diff --git a/src/QLNet/Indexes/Ibor/Libor.cs b/src/QLNet/Indexes/Ibor/Libor.cs index c19dac916..3659b37cf 100644 --- a/src/QLNet/Indexes/Ibor/Libor.cs +++ b/src/QLNet/Indexes/Ibor/Libor.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,34 +29,34 @@ public class Libor : IborIndex private Calendar financialCenterCalendar_; private Calendar jointCalendar_; - public Libor( string familyName, Period tenor, int settlementDays, Currency currency, Calendar financialCenterCalendar, - DayCounter dayCounter, Handle h ) - : base( familyName, tenor, settlementDays, currency, - // http://www.bba.org.uk/bba/jsp/polopoly.jsp?d=225&a=1412 : - // UnitedKingdom::Exchange is the fixing calendar for - // a) all currencies but EUR - // b) all indexes but o/n and s/n - new UnitedKingdom( UnitedKingdom.Market.Exchange ), - Utils.liborConvention( tenor ), Utils.liborEOM( tenor ), - dayCounter, h ) + public Libor(string familyName, Period tenor, int settlementDays, Currency currency, Calendar financialCenterCalendar, + DayCounter dayCounter, Handle h) + : base(familyName, tenor, settlementDays, currency, + // http://www.bba.org.uk/bba/jsp/polopoly.jsp?d=225&a=1412 : + // UnitedKingdom::Exchange is the fixing calendar for + // a) all currencies but EUR + // b) all indexes but o/n and s/n + new UnitedKingdom(UnitedKingdom.Market.Exchange), + Utils.liborConvention(tenor), Utils.liborEOM(tenor), + dayCounter, h) { financialCenterCalendar_ = financialCenterCalendar; - jointCalendar_ = new JointCalendar( new UnitedKingdom( UnitedKingdom.Market.Exchange ), - financialCenterCalendar, JointCalendar.JointCalendarRule.JoinHolidays ); + jointCalendar_ = new JointCalendar(new UnitedKingdom(UnitedKingdom.Market.Exchange), + financialCenterCalendar, JointCalendar.JointCalendarRule.JoinHolidays); Utils.QL_REQUIRE(this.tenor().units() != TimeUnit.Days, () => - "for daily tenors (" + this.tenor() + ") dedicated DailyTenor constructor must be used" ); - Utils.QL_REQUIRE( currency != new EURCurrency() ,()=> - "for EUR Libor dedicated EurLibor constructor must be used" ); + "for daily tenors (" + this.tenor() + ") dedicated DailyTenor constructor must be used"); + Utils.QL_REQUIRE(currency != new EURCurrency(), () => + "for EUR Libor dedicated EurLibor constructor must be used"); } /* Date calculations See . */ - public override Date valueDate( Date fixingDate ) + public override Date valueDate(Date fixingDate) { - Utils.QL_REQUIRE(isValidFixingDate(fixingDate),()=> "Fixing date " + fixingDate + " is not valid"); + Utils.QL_REQUIRE(isValidFixingDate(fixingDate), () => "Fixing date " + fixingDate + " is not valid"); // http://www.bba.org.uk/bba/jsp/polopoly.jsp?d=225&a=1412 : // For all currencies other than EUR and GBP the period between @@ -65,11 +65,11 @@ public override Date valueDate( Date fixingDate ) // business day and a business day in the principal financial centre // of the currency concerned, the next following day which is a // business day in both centres shall be the Value Date. - Date d = fixingCalendar().advance( fixingDate, fixingDays_, TimeUnit.Days ); - return jointCalendar_.adjust( d ); + Date d = fixingCalendar().advance(fixingDate, fixingDays_, TimeUnit.Days); + return jointCalendar_.adjust(d); } - public override Date maturityDate( Date valueDate ) + public override Date maturityDate(Date valueDate) { // Where a deposit is made on the final business day of a // particular calendar month, the maturity of the deposit shall @@ -79,14 +79,14 @@ public override Date maturityDate( Date valueDate ) // are dealt on an end-end basis. For instance a one month // deposit for value 28th February would mature on 31st March, // not the 28th of March. - return jointCalendar_.advance( valueDate, tenor_, convention_, endOfMonth() ); + return jointCalendar_.advance(valueDate, tenor_, convention_, endOfMonth()); } // Other methods - public override IborIndex clone( Handle h ) + public override IborIndex clone(Handle h) { - return new Libor( familyName(), tenor(), fixingDays(), currency(), financialCenterCalendar_, - dayCounter(), h ); + return new Libor(familyName(), tenor(), fixingDays(), currency(), financialCenterCalendar_, + dayCounter(), h); } } @@ -101,27 +101,27 @@ public class DailyTenorLibor : IborIndex // no o/n or s/n fixings (as the case may be) will take place // when the principal centre of the currency concerned is // closed but London is open on the fixing day. - public DailyTenorLibor( string familyName, int settlementDays, Currency currency, Calendar financialCenterCalendar, - DayCounter dayCounter ) - : this( familyName, settlementDays, currency, financialCenterCalendar, dayCounter, new Handle() ) + public DailyTenorLibor(string familyName, int settlementDays, Currency currency, Calendar financialCenterCalendar, + DayCounter dayCounter) + : this(familyName, settlementDays, currency, financialCenterCalendar, dayCounter, new Handle()) {} - public DailyTenorLibor( string familyName, int settlementDays, Currency currency, Calendar financialCenterCalendar, - DayCounter dayCounter, Handle h ) - : base( familyName, new Period( 1, TimeUnit.Days ), settlementDays, currency, - new JointCalendar( new UnitedKingdom( UnitedKingdom.Market.Exchange ), financialCenterCalendar, JointCalendar.JointCalendarRule.JoinHolidays ), - Utils.liborConvention( new Period( 1, TimeUnit.Days ) ), Utils.liborEOM( new Period( 1, TimeUnit.Days ) ), dayCounter, h ) + public DailyTenorLibor(string familyName, int settlementDays, Currency currency, Calendar financialCenterCalendar, + DayCounter dayCounter, Handle h) + : base(familyName, new Period(1, TimeUnit.Days), settlementDays, currency, + new JointCalendar(new UnitedKingdom(UnitedKingdom.Market.Exchange), financialCenterCalendar, JointCalendar.JointCalendarRule.JoinHolidays), + Utils.liborConvention(new Period(1, TimeUnit.Days)), Utils.liborEOM(new Period(1, TimeUnit.Days)), dayCounter, h) { - Utils.QL_REQUIRE( currency != new EURCurrency() ,()=> - "for EUR Libor dedicated EurLibor constructor must be used" ); + Utils.QL_REQUIRE(currency != new EURCurrency(), () => + "for EUR Libor dedicated EurLibor constructor must be used"); } } public static partial class Utils { - public static BusinessDayConvention liborConvention( Period p ) + public static BusinessDayConvention liborConvention(Period p) { - switch ( p.units() ) + switch (p.units()) { case TimeUnit.Days: case TimeUnit.Weeks: @@ -130,14 +130,14 @@ public static BusinessDayConvention liborConvention( Period p ) case TimeUnit.Years: return BusinessDayConvention.ModifiedFollowing; default: - QL_FAIL( "invalid time units" ); + QL_FAIL("invalid time units"); return BusinessDayConvention.Unadjusted; } } - public static bool liborEOM( Period p ) + public static bool liborEOM(Period p) { - switch ( p.units() ) + switch (p.units()) { case TimeUnit.Days: case TimeUnit.Weeks: @@ -146,7 +146,7 @@ public static bool liborEOM( Period p ) case TimeUnit.Years: return true; default: - QL_FAIL( "invalid time units" ); + QL_FAIL("invalid time units"); return false; } } diff --git a/src/QLNet/Indexes/Ibor/Nzdlibor.cs b/src/QLNet/Indexes/Ibor/Nzdlibor.cs index 6d4ec7cde..476c3b14c 100644 --- a/src/QLNet/Indexes/Ibor/Nzdlibor.cs +++ b/src/QLNet/Indexes/Ibor/Nzdlibor.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -25,12 +25,12 @@ namespace QLNet */ public class NZDLibor : Libor { - public NZDLibor( Period tenor ) - : base( "NZDLibor", tenor, 2, new NZDCurrency(), new NewZealand(), new Actual360(), new Handle() ) + public NZDLibor(Period tenor) + : base("NZDLibor", tenor, 2, new NZDCurrency(), new NewZealand(), new Actual360(), new Handle()) {} - public NZDLibor( Period tenor, Handle h ) - : base( "NZDLibor", tenor, 2, new NZDCurrency(), new NewZealand(), new Actual360(), h ) + public NZDLibor(Period tenor, Handle h) + : base("NZDLibor", tenor, 2, new NZDCurrency(), new NewZealand(), new Actual360(), h) {} } diff --git a/src/QLNet/Indexes/Ibor/Nzocr.cs b/src/QLNet/Indexes/Ibor/Nzocr.cs index 855a1cb3d..2a285db2e 100644 --- a/src/QLNet/Indexes/Ibor/Nzocr.cs +++ b/src/QLNet/Indexes/Ibor/Nzocr.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,10 +23,10 @@ namespace QLNet */ public class Nzocr : OvernightIndex { - public Nzocr( Handle h = null ) - :base("Nzocr", 0, new NZDCurrency(), - new NewZealand(), - new Actual365Fixed(), h ?? new Handle()) + public Nzocr(Handle h = null) + : base("Nzocr", 0, new NZDCurrency(), + new NewZealand(), + new Actual365Fixed(), h ?? new Handle()) {} } } diff --git a/src/QLNet/Indexes/Ibor/Seklibor.cs b/src/QLNet/Indexes/Ibor/Seklibor.cs index f9ac602f0..996ab362a 100644 --- a/src/QLNet/Indexes/Ibor/Seklibor.cs +++ b/src/QLNet/Indexes/Ibor/Seklibor.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,15 +22,15 @@ namespace QLNet //! %SEK %LIBOR rate /*! Sweden Krone LIBOR discontinued as of 2013. - */ + */ public class SEKLibor : Libor { - public SEKLibor( Period tenor ) - : base( "SEKLibor", tenor, 2, new SEKCurrency(), new Sweden(), new Actual360(), new Handle() ) + public SEKLibor(Period tenor) + : base("SEKLibor", tenor, 2, new SEKCurrency(), new Sweden(), new Actual360(), new Handle()) {} - public SEKLibor( Period tenor, Handle h ) - : base( "SEKLibor", tenor, 2, new SEKCurrency(), new Sweden(), new Actual360(), h ) + public SEKLibor(Period tenor, Handle h) + : base("SEKLibor", tenor, 2, new SEKCurrency(), new Sweden(), new Actual360(), h) {} } diff --git a/src/QLNet/Indexes/Ibor/Shibor.cs b/src/QLNet/Indexes/Ibor/Shibor.cs index d8775dee5..93cd36f1b 100644 --- a/src/QLNet/Indexes/Ibor/Shibor.cs +++ b/src/QLNet/Indexes/Ibor/Shibor.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,26 +21,27 @@ namespace QLNet { public class Shibor : IborIndex { - private static BusinessDayConvention shiborConvention(Period p) + private static BusinessDayConvention shiborConvention(Period p) { - switch (p.units()) { - case TimeUnit.Days: - case TimeUnit.Weeks: - return BusinessDayConvention.Following; - case TimeUnit.Months: - case TimeUnit.Years: - return BusinessDayConvention.ModifiedFollowing; - default: - Utils.QL_FAIL("invalid time units"); - return BusinessDayConvention.Unadjusted; - } - } + switch (p.units()) + { + case TimeUnit.Days: + case TimeUnit.Weeks: + return BusinessDayConvention.Following; + case TimeUnit.Months: + case TimeUnit.Years: + return BusinessDayConvention.ModifiedFollowing; + default: + Utils.QL_FAIL("invalid time units"); + return BusinessDayConvention.Unadjusted; + } + } - public Shibor( Period tenor ) - :this(tenor , new Handle()) {} + public Shibor(Period tenor) + : this(tenor, new Handle()) {} - public Shibor( Period tenor, Handle h ) - :base("Shibor", tenor, (tenor == new Period(1,TimeUnit.Days)? 0 : 1), new CNYCurrency(), + public Shibor(Period tenor, Handle h) + : base("Shibor", tenor, (tenor == new Period(1, TimeUnit.Days) ? 0 : 1), new CNYCurrency(), new China(China.Market.IB), shiborConvention(tenor), false, new Actual360(), h) {} } diff --git a/src/QLNet/Indexes/Ibor/Sonia.cs b/src/QLNet/Indexes/Ibor/Sonia.cs index b7ef36311..0f522ca01 100644 --- a/src/QLNet/Indexes/Ibor/Sonia.cs +++ b/src/QLNet/Indexes/Ibor/Sonia.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,7 +23,7 @@ public class Sonia : OvernightIndex { //! %Sonia (Sterling Overnight Index Average) rate. public Sonia(Handle h = null) - :base("Sonia", 0, new GBPCurrency(), new UnitedKingdom(UnitedKingdom.Market.Exchange), + : base("Sonia", 0, new GBPCurrency(), new UnitedKingdom(UnitedKingdom.Market.Exchange), new Actual365Fixed(), h ?? new Handle()) {} } } diff --git a/src/QLNet/Indexes/Ibor/Tibor.cs b/src/QLNet/Indexes/Ibor/Tibor.cs index d2714d379..a058828aa 100644 --- a/src/QLNet/Indexes/Ibor/Tibor.cs +++ b/src/QLNet/Indexes/Ibor/Tibor.cs @@ -1,42 +1,43 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { +namespace QLNet +{ - //! %JPY %TIBOR index + //! %JPY %TIBOR index // ! Tokyo Interbank Offered Rate. // // \warning This is the rate fixed in Tokio by JBA. Use JPYLibor // if you're interested in the London fixing by BBA. // // \todo check settlement days and end-of-month adjustment. -// - public class Tibor : IborIndex - { - public Tibor(Period tenor) - : base("Tibor", tenor, 2, new JPYCurrency(), new Japan(), BusinessDayConvention.ModifiedFollowing, false, new Actual365Fixed(), new Handle()) - { - } - public Tibor(Period tenor, Handle h) - : base("Tibor", tenor, 2, new JPYCurrency(), new Japan(), BusinessDayConvention.ModifiedFollowing, false, new Actual365Fixed(), h) - { - } - } +// + public class Tibor : IborIndex + { + public Tibor(Period tenor) + : base("Tibor", tenor, 2, new JPYCurrency(), new Japan(), BusinessDayConvention.ModifiedFollowing, false, new Actual365Fixed(), new Handle()) + { + } + public Tibor(Period tenor, Handle h) + : base("Tibor", tenor, 2, new JPYCurrency(), new Japan(), BusinessDayConvention.ModifiedFollowing, false, new Actual365Fixed(), h) + { + } + } } diff --git a/src/QLNet/Indexes/Ibor/Trylibor.cs b/src/QLNet/Indexes/Ibor/Trylibor.cs index adeba8f33..9839949d6 100644 --- a/src/QLNet/Indexes/Ibor/Trylibor.cs +++ b/src/QLNet/Indexes/Ibor/Trylibor.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,12 +29,12 @@ namespace QLNet */ public class TRLibor : IborIndex { - public TRLibor( Period tenor ) - : base( "TRLibor", tenor, 0, new TRYCurrency(), new Turkey(), BusinessDayConvention.ModifiedFollowing, false, new Actual360(), new Handle() ) + public TRLibor(Period tenor) + : base("TRLibor", tenor, 0, new TRYCurrency(), new Turkey(), BusinessDayConvention.ModifiedFollowing, false, new Actual360(), new Handle()) {} - public TRLibor( Period tenor, Handle h ) - : base( "TRLibor", tenor, 0, new TRYCurrency(), new Turkey(), BusinessDayConvention.ModifiedFollowing, false, new Actual360(), h ) + public TRLibor(Period tenor, Handle h) + : base("TRLibor", tenor, 0, new TRYCurrency(), new Turkey(), BusinessDayConvention.ModifiedFollowing, false, new Actual360(), h) {} } diff --git a/src/QLNet/Indexes/Ibor/Usdlibor.cs b/src/QLNet/Indexes/Ibor/Usdlibor.cs index d15112d2a..9b1073fc1 100644 --- a/src/QLNet/Indexes/Ibor/Usdlibor.cs +++ b/src/QLNet/Indexes/Ibor/Usdlibor.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -26,11 +26,11 @@ namespace QLNet */ public class USDLibor : Libor { - public USDLibor( Period tenor ) : this( tenor, new Handle() ) + public USDLibor(Period tenor) : this(tenor, new Handle()) {} - public USDLibor( Period tenor, Handle h ) - : base( "USDLibor", tenor, 2, new USDCurrency(), new UnitedStates( UnitedStates.Market.Settlement ), new Actual360(), h ) + public USDLibor(Period tenor, Handle h) + : base("USDLibor", tenor, 2, new USDCurrency(), new UnitedStates(UnitedStates.Market.Settlement), new Actual360(), h) {} } @@ -38,10 +38,10 @@ public USDLibor( Period tenor, Handle h ) //! base class for the one day deposit ICE %USD %LIBOR indexes public class DailyTenorUSDLibor : DailyTenorLibor { - public DailyTenorUSDLibor( int settlementDays ) : this( settlementDays, new Handle() ) + public DailyTenorUSDLibor(int settlementDays) : this(settlementDays, new Handle()) {} - public DailyTenorUSDLibor( int settlementDays, Handle h ) - : base( "USDLibor", settlementDays, new USDCurrency(), new UnitedStates( UnitedStates.Market.Settlement ), new Actual360(), h ) + public DailyTenorUSDLibor(int settlementDays, Handle h) + : base("USDLibor", settlementDays, new USDCurrency(), new UnitedStates(UnitedStates.Market.Settlement), new Actual360(), h) {} } @@ -49,10 +49,10 @@ public DailyTenorUSDLibor( int settlementDays, Handle h ) //! Overnight %USD %Libor index public class USDLiborON : DailyTenorUSDLibor { - public USDLiborON() : this( new Handle() ) + public USDLiborON() : this(new Handle()) {} - public USDLiborON( Handle h ) : base( 0, h ) + public USDLiborON(Handle h) : base(0, h) {} } diff --git a/src/QLNet/Indexes/Ibor/Zibor.cs b/src/QLNet/Indexes/Ibor/Zibor.cs index a848939fc..7c7442f92 100644 --- a/src/QLNet/Indexes/Ibor/Zibor.cs +++ b/src/QLNet/Indexes/Ibor/Zibor.cs @@ -1,25 +1,26 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { +namespace QLNet +{ - //! %CHF %ZIBOR rate + //! %CHF %ZIBOR rate // ! Zurich Interbank Offered Rate. // // \warning This is the rate fixed in Zurich by BBA. Use CHFLibor if @@ -27,17 +28,17 @@ namespace QLNet { // // \todo check settlement days, end-of-month adjustment, // and day-count convention. -// - public class Zibor : IborIndex - { - public Zibor(Period tenor) - : base("Zibor", tenor, 2, new CHFCurrency(), new Switzerland(), BusinessDayConvention.ModifiedFollowing, false, new Actual360(), new Handle()) - { - } - public Zibor(Period tenor, Handle h) - : base("Zibor", tenor, 2, new CHFCurrency(), new Switzerland(), BusinessDayConvention.ModifiedFollowing, false, new Actual360(), h) - { - } - } +// + public class Zibor : IborIndex + { + public Zibor(Period tenor) + : base("Zibor", tenor, 2, new CHFCurrency(), new Switzerland(), BusinessDayConvention.ModifiedFollowing, false, new Actual360(), new Handle()) + { + } + public Zibor(Period tenor, Handle h) + : base("Zibor", tenor, 2, new CHFCurrency(), new Switzerland(), BusinessDayConvention.ModifiedFollowing, false, new Actual360(), h) + { + } + } } diff --git a/src/QLNet/Indexes/Indexmanager.cs b/src/QLNet/Indexes/Indexmanager.cs index ed7d837c5..21e146abd 100644 --- a/src/QLNet/Indexes/Indexmanager.cs +++ b/src/QLNet/Indexes/Indexmanager.cs @@ -1,80 +1,157 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - * + Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ + using System; using System.Collections.Generic; +using history_map = System.Collections.Generic.Dictionary < string, QLNet.ObservableValue < QLNet.TimeSeries < double? >>>; + +namespace QLNet +{ + /// + /// global repository for past index fixings + /// + /// Index names are case insensitive + /// + /// + public class IndexManager + { + + // Index manager can store a callback for missing fixings + public static Func MissingPastFixingCallBack { get; set; } + + private static readonly IndexManager instance_ = new IndexManager(); + + public static IndexManager instance() + { + return instance_; + } + + private IndexManager() + { } + + /// + /// returns whether historical fixings were stored for the index + /// + /// + /// + public bool hasHistory(string name) + { + return data_.ContainsKey(name.ToUpper()) && data_[name.ToUpper()].value().Count > 0; + } + + /// + /// returns the (possibly empty) history of the index fixings + /// + /// + /// + public TimeSeries < double? > getHistory(string name) + { + checkExists(name); + return data_[name.ToUpper()].value(); + } + + /// + /// Returns the history of the index fixings if the index exists + /// A return value indicates whether the index exists. + /// + /// The index name + /// The history of the index. Populated with null if the index does not exist + /// true if the index exists; otherwise, false. + public bool tryGetHistory(string name, out TimeSeries < double? > history) + { + if (hasHistory(name)) + { + history = getHistory(name); + return true; + } + else + { + history = null; + return false; + } + } + + /// + /// stores the historical fixings of the index + /// + /// + /// + public void setHistory(string name, TimeSeries < double? > history) + { + checkExists(name); + data_[name.ToUpper()].Assign(history); + } + + /// + /// observer notifying of changes in the index fixings; + /// + /// + /// + public ObservableValue < TimeSeries < double? >> notifier(string name) + { + checkExists(name); + return data_[name.ToUpper()]; + } + + /// + /// returns all names of the indexes for which fixings were stored + /// + /// + public List histories() + { + List t = new List(); + foreach (string s in data_.Keys) + t.Add(s); + return t; + } + + /// + /// clears the historical fixings of the index + /// + /// + public void clearHistory(string name) + { + data_.Remove(name.ToUpper()); + } + + /// + /// clears ALL stored fixings + /// + public void clearHistories() + { + data_.Clear(); + } + + /// + /// checks whether index exists and adds it otherwise; for interal use only + /// + /// + private void checkExists(string name) + { + if (!data_.ContainsKey(name.ToUpper())) + data_.Add(name.ToUpper(), new ObservableValue < TimeSeries < double? >> ()); + } + + private static history_map data_ = new Dictionary < string, ObservableValue < TimeSeries < double? >>> (); + + } -namespace QLNet { - //! global repository for past index fixings - public class IndexManager { - private static Dictionary>> data_ = - new Dictionary>>(); - - // Index manager can store a callback for missing fixings - public static Func MissingPastFixingCallBack { get; set; } - - private static readonly IndexManager instance_ = new IndexManager(); - public static IndexManager instance() { return instance_; } - private IndexManager() { } - - //! returns whether historical fixings were stored for the index - public bool hasHistory(string name) { - return data_.ContainsKey(name) && data_[name].value().Count > 0; - } - - //! returns the (possibly empty) history of the index fixings - public ObservableValue> getHistory(string name) { - checkExists(name); - return data_[name]; - } - - //! stores the historical fixings of the index - public void setHistory(string name, ObservableValue> history) { - checkExists(name); - data_[name].Assign(history); - } - - //! observer notifying of changes in the index fixings; in .NET it has the same logic as getHistory - public ObservableValue> notifier(string name) { return getHistory(name); } - - //! returns all names of the indexes for which fixings were stored - public List histories() { - List t = new List(); - foreach (string s in data_.Keys) - t.Add(s); - return t; - } - - //! clears the historical fixings of the index - public void clearHistory(string name) { - data_.Remove(name.ToUpper()); - } - - //! clears all stored fixings - public void clearHistories() { - data_.Clear(); - } - - // checks whether index exists and adds it otherwise; for interal use only - private void checkExists(string name) { - if (!data_.ContainsKey(name)) - data_.Add(name, new ObservableValue>()); - } - } -} \ No newline at end of file +} diff --git a/src/QLNet/Indexes/Inflation/AUCPI.cs b/src/QLNet/Indexes/Inflation/AUCPI.cs index f07cc1176..777c3b52d 100644 --- a/src/QLNet/Indexes/Inflation/AUCPI.cs +++ b/src/QLNet/Indexes/Inflation/AUCPI.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,54 +20,54 @@ under the terms of the QLNet license. You should have received a namespace QLNet { //! AU CPI index (either quarterly or annual) - public class AUCPI : ZeroInflationIndex + public class AUCPI : ZeroInflationIndex { public AUCPI(Frequency frequency, bool revised, bool interpolated) - :this(frequency,revised,interpolated,new Handle()) {} + : this(frequency, revised, interpolated, new Handle()) {} public AUCPI(Frequency frequency, bool revised, bool interpolated, Handle ts) - : base("CPI", - new AustraliaRegion(), - revised, - interpolated, - frequency, - new Period(2, TimeUnit.Months), - new AUDCurrency(), - ts) {} + : base("CPI", + new AustraliaRegion(), + revised, + interpolated, + frequency, + new Period(2, TimeUnit.Months), + new AUDCurrency(), + ts) {} } - + //! Genuine year-on-year AU CPI (i.e. not a ratio) - public class YYAUCPI : YoYInflationIndex + public class YYAUCPI : YoYInflationIndex { public YYAUCPI(Frequency frequency, bool revised, bool interpolated) - :this(frequency,revised,interpolated,new Handle()){} + : this(frequency, revised, interpolated, new Handle()) {} public YYAUCPI(Frequency frequency, bool revised, bool interpolated, Handle ts) - : base("YY_CPI", - new AustraliaRegion(), - revised, - interpolated, - false, - frequency, - new Period(2, TimeUnit.Months), - new AUDCurrency(), - ts) {} + : base("YY_CPI", + new AustraliaRegion(), + revised, + interpolated, + false, + frequency, + new Period(2, TimeUnit.Months), + new AUDCurrency(), + ts) {} } - + //! Fake year-on-year AUCPI (i.e. a ratio) - public class YYAUCPIr : YoYInflationIndex + public class YYAUCPIr : YoYInflationIndex { public YYAUCPIr(Frequency frequency, bool revised, @@ -77,15 +77,15 @@ public YYAUCPIr(Frequency frequency, public YYAUCPIr(Frequency frequency, bool revised, bool interpolated, - Handle ts ) - : base("YYR_CPI", - new AustraliaRegion(), - revised, - interpolated, - true, - frequency, - new Period(2, TimeUnit.Months), - new AUDCurrency(), - ts) {} + Handle ts) + : base("YYR_CPI", + new AustraliaRegion(), + revised, + interpolated, + true, + frequency, + new Period(2, TimeUnit.Months), + new AUDCurrency(), + ts) {} } } diff --git a/src/QLNet/Indexes/Inflation/EUHICP.cs b/src/QLNet/Indexes/Inflation/EUHICP.cs index ee012cf19..21b0eb39f 100644 --- a/src/QLNet/Indexes/Inflation/EUHICP.cs +++ b/src/QLNet/Indexes/Inflation/EUHICP.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,35 +23,35 @@ namespace QLNet public class EUHICP : ZeroInflationIndex { public EUHICP(bool interpolated) - : this(interpolated,new Handle()) { } + : this(interpolated, new Handle()) { } public EUHICP(bool interpolated, Handle ts) - : base("HICP",new EURegion(),false,interpolated,Frequency.Monthly, - new Period(1, TimeUnit.Months), // availability - new EURCurrency(), ts) {} + : base("HICP", new EURegion(), false, interpolated, Frequency.Monthly, + new Period(1, TimeUnit.Months), // availability + new EURCurrency(), ts) {} } - //! Genuine year-on-year EU HICP (i.e. not a ratio of EU HICP) - public class YYEUHICP : YoYInflationIndex - { - public YYEUHICP(bool interpolated) - : this(interpolated, new Handle()) { } + //! Genuine year-on-year EU HICP (i.e. not a ratio of EU HICP) + public class YYEUHICP : YoYInflationIndex + { + public YYEUHICP(bool interpolated) + : this(interpolated, new Handle()) { } - public YYEUHICP(bool interpolated,Handle ts ) - : base("YY_HICP",new EURegion(),false,interpolated, false,Frequency.Monthly, - new Period(1, TimeUnit.Months),new EURCurrency(), ts) {} - } + public YYEUHICP(bool interpolated, Handle ts) + : base("YY_HICP", new EURegion(), false, interpolated, false, Frequency.Monthly, + new Period(1, TimeUnit.Months), new EURCurrency(), ts) {} + } - //! Fake year-on-year EU HICP (i.e. a ratio of EU HICP) - public class YYEUHICPr : YoYInflationIndex - { - public YYEUHICPr(bool interpolated) - : this(interpolated, new Handle()) { } + //! Fake year-on-year EU HICP (i.e. a ratio of EU HICP) + public class YYEUHICPr : YoYInflationIndex + { + public YYEUHICPr(bool interpolated) + : this(interpolated, new Handle()) { } - public YYEUHICPr(bool interpolated,Handle ts) - : base("YYR_HICP", new EURegion(), false, interpolated, true, Frequency.Monthly, - new Period(1, TimeUnit.Months),new EURCurrency(),ts) {} - } + public YYEUHICPr(bool interpolated, Handle ts) + : base("YYR_HICP", new EURegion(), false, interpolated, true, Frequency.Monthly, + new Period(1, TimeUnit.Months), new EURCurrency(), ts) {} + } } diff --git a/src/QLNet/Indexes/Inflation/FRHICP.cs b/src/QLNet/Indexes/Inflation/FRHICP.cs index 666e7e8b3..3041a5aa8 100644 --- a/src/QLNet/Indexes/Inflation/FRHICP.cs +++ b/src/QLNet/Indexes/Inflation/FRHICP.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,58 +21,58 @@ namespace QLNet { //! FR HICP index - public class FRHICP : ZeroInflationIndex + public class FRHICP : ZeroInflationIndex { public FRHICP(bool interpolated) - :this(interpolated,new Handle()){} + : this(interpolated, new Handle()) {} public FRHICP(bool interpolated, - Handle ts ) - : base("HICP", - new FranceRegion(), - false, - interpolated, - Frequency.Monthly, - new Period(1, TimeUnit.Months), - new EURCurrency(), - ts) {} + Handle ts) + : base("HICP", + new FranceRegion(), + false, + interpolated, + Frequency.Monthly, + new Period(1, TimeUnit.Months), + new EURCurrency(), + ts) {} } //! Genuine year-on-year FR HICP (i.e. not a ratio) - public class YYFRHICP : YoYInflationIndex + public class YYFRHICP : YoYInflationIndex { public YYFRHICP(bool interpolated) - :this(interpolated,new Handle()){} + : this(interpolated, new Handle()) {} public YYFRHICP(bool interpolated, Handle ts) - : base("YY_HICP", - new FranceRegion(), - false, - interpolated, - false, - Frequency.Monthly, - new Period(1, TimeUnit.Months), - new EURCurrency(), - ts) {} + : base("YY_HICP", + new FranceRegion(), + false, + interpolated, + false, + Frequency.Monthly, + new Period(1, TimeUnit.Months), + new EURCurrency(), + ts) {} } //! Fake year-on-year FR HICP (i.e. a ratio) - public class YYFRHICPr : YoYInflationIndex + public class YYFRHICPr : YoYInflationIndex { public YYFRHICPr(bool interpolated) : this(interpolated, new Handle()) { } public YYFRHICPr(bool interpolated, Handle ts) - : base("YYR_HICP", - new FranceRegion(), - false, - interpolated, - true, - Frequency.Monthly, - new Period(1, TimeUnit.Months), - new EURCurrency(), - ts) {} - } + : base("YYR_HICP", + new FranceRegion(), + false, + interpolated, + true, + Frequency.Monthly, + new Period(1, TimeUnit.Months), + new EURCurrency(), + ts) {} + } } diff --git a/src/QLNet/Indexes/Inflation/UKRPI.cs b/src/QLNet/Indexes/Inflation/UKRPI.cs index b24da3f59..2519ce58f 100644 --- a/src/QLNet/Indexes/Inflation/UKRPI.cs +++ b/src/QLNet/Indexes/Inflation/UKRPI.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,32 +23,32 @@ namespace QLNet public class UKRPI : ZeroInflationIndex { public UKRPI(bool interpolated) - : this(interpolated,new Handle()) { } + : this(interpolated, new Handle()) { } - public UKRPI(bool interpolated,Handle ts) - : base("RPI",new UKRegion(),false,interpolated,Frequency.Monthly, - new Period(1, TimeUnit.Months),new GBPCurrency(),ts) {} + public UKRPI(bool interpolated, Handle ts) + : base("RPI", new UKRegion(), false, interpolated, Frequency.Monthly, + new Period(1, TimeUnit.Months), new GBPCurrency(), ts) {} } //! Genuine year-on-year UK RPI (i.e. not a ratio of UK RPI) - public class YYUKRPI : YoYInflationIndex + public class YYUKRPI : YoYInflationIndex { public YYUKRPI(bool interpolated) - : this(interpolated,new Handle()) { } + : this(interpolated, new Handle()) { } - public YYUKRPI(bool interpolated,Handle ts) - : base("YY_RPI",new UKRegion(),false,interpolated,false,Frequency.Monthly, - new Period(1, TimeUnit.Months),new GBPCurrency(), ts) {} + public YYUKRPI(bool interpolated, Handle ts) + : base("YY_RPI", new UKRegion(), false, interpolated, false, Frequency.Monthly, + new Period(1, TimeUnit.Months), new GBPCurrency(), ts) {} } //! Fake year-on-year UK RPI (i.e. a ratio of UK RPI) - public class YYUKRPIr : YoYInflationIndex + public class YYUKRPIr : YoYInflationIndex { public YYUKRPIr(bool interpolated) - : this(interpolated,new Handle()) { } + : this(interpolated, new Handle()) { } - public YYUKRPIr(bool interpolated,Handle ts) - : base("YYR_RPI",new UKRegion(),false,interpolated,true,Frequency.Monthly, - new Period(1, TimeUnit.Months),new GBPCurrency(),ts) {} - }; + public YYUKRPIr(bool interpolated, Handle ts) + : base("YYR_RPI", new UKRegion(), false, interpolated, true, Frequency.Monthly, + new Period(1, TimeUnit.Months), new GBPCurrency(), ts) {} + } } diff --git a/src/QLNet/Indexes/Inflation/USCPI.cs b/src/QLNet/Indexes/Inflation/USCPI.cs index 6dd72255c..c361f3c5e 100644 --- a/src/QLNet/Indexes/Inflation/USCPI.cs +++ b/src/QLNet/Indexes/Inflation/USCPI.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,58 +20,58 @@ under the terms of the QLNet license. You should have received a namespace QLNet { //! US CPI index - public class USCPI : ZeroInflationIndex + public class USCPI : ZeroInflationIndex { public USCPI(bool interpolated) - :this(interpolated,new Handle()) {} + : this(interpolated, new Handle()) {} public USCPI(bool interpolated, Handle ts) - : base("CPI", - new USRegion(), - false, - interpolated, - Frequency.Monthly, - new Period(1, TimeUnit.Months), // availability - new USDCurrency(), - ts) {} + : base("CPI", + new USRegion(), + false, + interpolated, + Frequency.Monthly, + new Period(1, TimeUnit.Months), // availability + new USDCurrency(), + ts) {} } //! Genuine year-on-year US CPI (i.e. not a ratio of US CPI) - public class YYUSCPI : YoYInflationIndex + public class YYUSCPI : YoYInflationIndex { public YYUSCPI(bool interpolated) - :this(interpolated,new Handle()) {} + : this(interpolated, new Handle()) {} public YYUSCPI(bool interpolated, Handle ts) - : base("YY_CPI", - new USRegion(), - false, - interpolated, - false, - Frequency.Monthly, - new Period(1, TimeUnit.Months), - new USDCurrency(), - ts) {} + : base("YY_CPI", + new USRegion(), + false, + interpolated, + false, + Frequency.Monthly, + new Period(1, TimeUnit.Months), + new USDCurrency(), + ts) {} } //! Fake year-on-year US CPI (i.e. a ratio of US CPI) - public class YYUSCPIr : YoYInflationIndex + public class YYUSCPIr : YoYInflationIndex { public YYUSCPIr(bool interpolated) : this(interpolated, new Handle()) { } public YYUSCPIr(bool interpolated, Handle ts) - : base("YYR_CPI", - new USRegion(), - false, - interpolated, - true, - Frequency.Monthly, - new Period(1, TimeUnit.Months), - new USDCurrency(), - ts) {} - } + : base("YYR_CPI", + new USRegion(), + false, + interpolated, + true, + Frequency.Monthly, + new Period(1, TimeUnit.Months), + new USDCurrency(), + ts) {} + } } diff --git a/src/QLNet/Indexes/Inflation/ZACPI.cs b/src/QLNet/Indexes/Inflation/ZACPI.cs index e746862d4..de12c0439 100644 --- a/src/QLNet/Indexes/Inflation/ZACPI.cs +++ b/src/QLNet/Indexes/Inflation/ZACPI.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) + Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,59 +19,59 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! South African CPI index - public class ZACPI : ZeroInflationIndex - { - public ZACPI( bool interpolated ) - : this( interpolated, new Handle() ) { } + //! South African CPI index + public class ZACPI : ZeroInflationIndex + { + public ZACPI(bool interpolated) + : this(interpolated, new Handle()) { } - public ZACPI( bool interpolated, - Handle ts ) - : base( "CPI", - new ZARegion(), - false, - interpolated, - Frequency.Monthly, - new Period( 1, TimeUnit.Months ), // availability - new ZARCurrency(), - ts ) { } - } + public ZACPI(bool interpolated, + Handle ts) + : base("CPI", + new ZARegion(), + false, + interpolated, + Frequency.Monthly, + new Period(1, TimeUnit.Months), // availability + new ZARCurrency(), + ts) { } + } - //! Genuine year-on-year South African CPI (i.e. not a ratio of South African CPI) - public class YYZACPI : YoYInflationIndex - { - public YYZACPI( bool interpolated ) - : this( interpolated, new Handle() ) { } + //! Genuine year-on-year South African CPI (i.e. not a ratio of South African CPI) + public class YYZACPI : YoYInflationIndex + { + public YYZACPI(bool interpolated) + : this(interpolated, new Handle()) { } - public YYZACPI( bool interpolated, - Handle ts ) - : base( "YY_CPI", - new ZARegion(), - false, - interpolated, - false, - Frequency.Monthly, - new Period( 1, TimeUnit.Months ), - new ZARCurrency(), - ts ) { } - } + public YYZACPI(bool interpolated, + Handle ts) + : base("YY_CPI", + new ZARegion(), + false, + interpolated, + false, + Frequency.Monthly, + new Period(1, TimeUnit.Months), + new ZARCurrency(), + ts) { } + } - //! Fake year-on-year South African CPI (i.e. a ratio of South African CPI) - public class YYZACPIr : YoYInflationIndex - { - public YYZACPIr( bool interpolated ) - : this( interpolated, new Handle() ) { } + //! Fake year-on-year South African CPI (i.e. a ratio of South African CPI) + public class YYZACPIr : YoYInflationIndex + { + public YYZACPIr(bool interpolated) + : this(interpolated, new Handle()) { } - public YYZACPIr( bool interpolated, - Handle ts ) - : base( "YYR_CPI", - new ZARegion(), - false, - interpolated, - true, - Frequency.Monthly, - new Period( 1, TimeUnit.Months ), - new ZARCurrency(), - ts ) { } - } + public YYZACPIr(bool interpolated, + Handle ts) + : base("YYR_CPI", + new ZARegion(), + false, + interpolated, + true, + Frequency.Monthly, + new Period(1, TimeUnit.Months), + new ZARCurrency(), + ts) { } + } } \ No newline at end of file diff --git a/src/QLNet/Indexes/InflationIndex.cs b/src/QLNet/Indexes/InflationIndex.cs index 03df1fddd..c974d2be7 100644 --- a/src/QLNet/Indexes/InflationIndex.cs +++ b/src/QLNet/Indexes/InflationIndex.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -35,13 +35,13 @@ is because interpolation adds an addional availability give the previous period's value) and enables storage of the most recent uninterpolated value. */ - public InflationIndex( string familyName, - Region region, - bool revised, - bool interpolated, - Frequency frequency, - Period availabilitiyLag, - Currency currency ) + public InflationIndex(string familyName, + Region region, + bool revised, + bool interpolated, + Frequency frequency, + Period availabilitiyLag, + Currency currency) { familyName_ = familyName; region_ = region; @@ -50,14 +50,14 @@ public InflationIndex( string familyName, frequency_ = frequency; availabilityLag_ = availabilitiyLag; currency_ = currency; - name_ = region_.name() + " " + familyName_; - Settings.registerWith( update ); - IndexManager.instance().notifier( name() ).registerWith( update ); + name_ = region_.name() + " " + familyName_; + Settings.registerWith(update); + IndexManager.instance().notifier(name()).registerWith(update); } // Index interface - public override string name() { return name_; } + public override string name() { return name_; } /*! Inflation indices do not have fixing calendars. An inflation index value is valid for every day (including @@ -66,7 +66,7 @@ NullCalendar as its fixing calendar. */ public override Calendar fixingCalendar() { return new NullCalendar(); } - public override bool isValidFixingDate( Date fixingDate ) { return true; } + public override bool isValidFixingDate(Date fixingDate) { return true; } /*! Forecasting index values requires an inflation term structure. The inflation term structure (ITS) defines the @@ -79,26 +79,26 @@ must be so because indices are available only with a lag. publication but the inflation swaps may take as their base the index 3 months before. */ - public override double fixing( Date fixingDate, bool forecastTodaysFixing = false ) { return 0; } + public override double fixing(Date fixingDate, bool forecastTodaysFixing = false) { return 0; } /*! this method creates all the "fixings" for the relevant period of the index. E.g. for monthly indices it will put the same value in every calendar day in the month. */ - public override void addFixing( Date fixingDate, double fixing, bool forceOverwrite = false ) + public override void addFixing(Date fixingDate, double fixing, bool forceOverwrite = false) { - KeyValuePair lim = Utils.inflationPeriod( fixingDate, frequency_ ); + KeyValuePair lim = Utils.inflationPeriod(fixingDate, frequency_); int n = lim.Value - lim.Key + 1; - List dates = new List( n ); - List rates = new List( n ); + List dates = new List(n); + List rates = new List(n); - for ( int i = 0; i < n; ++i ) + for (int i = 0; i < n; ++i) { - dates.Add( lim.Key + i ); - rates.Add( fixing ); + dates.Add(lim.Key + i); + rates.Add(fixing); } - base.addFixings( dates, rates, forceOverwrite ); + base.addFixings(dates, rates, forceOverwrite); } @@ -144,48 +144,48 @@ the mid-period extrapolated value. public class ZeroInflationIndex : InflationIndex { //! Always use the evaluation date as the reference date - public ZeroInflationIndex( string familyName, + public ZeroInflationIndex(string familyName, Region region, bool revised, bool interpolated, Frequency frequency, Period availabilityLag, Currency currency, - Handle ts = null ) - : base( familyName, region, revised, interpolated, - frequency, availabilityLag, currency ) + Handle ts = null) + : base(familyName, region, revised, interpolated, + frequency, availabilityLag, currency) { zeroInflation_ = ts ?? new Handle(); - zeroInflation_.registerWith( update ); + zeroInflation_.registerWith(update); } /*! \warning the forecastTodaysFixing parameter (required by the Index interface) is currently ignored. */ - public override double fixing( Date aFixingDate, bool forecastTodaysFixing = false ) + public override double fixing(Date aFixingDate, bool forecastTodaysFixing = false) { - if ( !needsForecast( aFixingDate ) ) + if (!needsForecast(aFixingDate)) { - KeyValuePair lim = Utils.inflationPeriod( aFixingDate, frequency_ ); - Utils.QL_REQUIRE( IndexManager.instance().getHistory( name() ).value().ContainsKey( lim.Key ), () => - "Missing " + name() + " fixing for " + lim.Key ); + KeyValuePair lim = Utils.inflationPeriod(aFixingDate, frequency_); + Utils.QL_REQUIRE(IndexManager.instance().getHistory(name()).ContainsKey(lim.Key), () => + "Missing " + name() + " fixing for " + lim.Key); - double? pastFixing = IndexManager.instance().getHistory( name() ).value()[lim.Key]; + double? pastFixing = IndexManager.instance().getHistory(name())[lim.Key]; double? theFixing = pastFixing; - if ( interpolated_ ) + if (interpolated_) { // fixings stored on first day of every period - if ( aFixingDate == lim.Key ) + if (aFixingDate == lim.Key) { // we don't actually need the next fixing theFixing = pastFixing; } else { - Utils.QL_REQUIRE( IndexManager.instance().getHistory( name() ).value().ContainsKey( lim.Value + 1 ), () => - "Missing " + name() + " fixing for " + ( lim.Value + 1 ) ); + Utils.QL_REQUIRE(IndexManager.instance().getHistory(name()).ContainsKey(lim.Value + 1), () => + "Missing " + name() + " fixing for " + (lim.Value + 1)); - double? pastFixing2 = IndexManager.instance().getHistory( name() ).value()[lim.Value + 1]; + double? pastFixing2 = IndexManager.instance().getHistory(name())[lim.Value + 1]; // Use lagged period for interpolation KeyValuePair reference_period_lim = Utils.inflationPeriod(aFixingDate + zeroInflationTermStructure().link.observationLag(), frequency_); @@ -199,21 +199,21 @@ public override double fixing( Date aFixingDate, bool forecastTodaysFixing = fal } else { - return forecastFixing( aFixingDate ); + return forecastFixing(aFixingDate); } } // Other methods public Handle zeroInflationTermStructure() { return zeroInflation_; } - public ZeroInflationIndex clone( Handle h ) + public ZeroInflationIndex clone(Handle h) { - return new ZeroInflationIndex( familyName_, region_, revised_, - interpolated_, frequency_, - availabilityLag_, currency_, h ); + return new ZeroInflationIndex(familyName_, region_, revised_, + interpolated_, frequency_, + availabilityLag_, currency_, h); } - private bool needsForecast( Date fixingDate ) + private bool needsForecast(Date fixingDate) { // Stored fixings are always non-interpolated. // If an interpolated fixing is required then @@ -225,23 +225,24 @@ private bool needsForecast( Date fixingDate ) Date today = Settings.evaluationDate(); Date todayMinusLag = today - availabilityLag_; - Date historicalFixingKnown = Utils.inflationPeriod( todayMinusLag, frequency_ ).Key - 1; + Date historicalFixingKnown = Utils.inflationPeriod(todayMinusLag, frequency_).Key - 1; Date latestNeededDate = fixingDate; - if ( interpolated_ ) - { // might need the next one too - KeyValuePair p = Utils.inflationPeriod( fixingDate, frequency_ ); - if ( fixingDate > p.Key ) - latestNeededDate = latestNeededDate + new Period( frequency_ ); + if (interpolated_) + { + // might need the next one too + KeyValuePair p = Utils.inflationPeriod(fixingDate, frequency_); + if (fixingDate > p.Key) + latestNeededDate = latestNeededDate + new Period(frequency_); } - if ( latestNeededDate <= historicalFixingKnown ) + if (latestNeededDate <= historicalFixingKnown) { // the fixing date is well before the availability lag, so // we know that fixings were provided. return false; } - else if ( latestNeededDate > today ) + else if (latestNeededDate > today) { // the fixing can't be available, no matter what's in the // time series @@ -252,17 +253,17 @@ private bool needsForecast( Date fixingDate ) // we're not sure, but the fixing might be there so we // check. Todo: check which fixings are not possible, to // avoid using fixings in the future - return !timeSeries().value().ContainsKey(latestNeededDate); + return !timeSeries().ContainsKey(latestNeededDate); } } - private double forecastFixing( Date fixingDate ) + private double forecastFixing(Date fixingDate) { // the term structure is relative to the fixing value at the base date. Date baseDate = zeroInflation_.link.baseDate(); - Utils.QL_REQUIRE( !needsForecast( baseDate ), () => name() + " index fixing at base date is not available" ); - double baseFixing = fixing( baseDate, false ); + Utils.QL_REQUIRE(!needsForecast(baseDate), () => name() + " index fixing at base date is not available"); + double baseFixing = fixing(baseDate, false); Date effectiveFixingDate; - if ( interpolated() ) + if (interpolated()) { effectiveFixingDate = fixingDate; } @@ -270,7 +271,7 @@ private double forecastFixing( Date fixingDate ) { // start of period is the convention // so it's easier to do linear interpolation on fixings - effectiveFixingDate = Utils.inflationPeriod( fixingDate, frequency() ).Key; + effectiveFixingDate = Utils.inflationPeriod(fixingDate, frequency()).Key; } // no observation lag because it is the fixing for the date @@ -278,11 +279,11 @@ private double forecastFixing( Date fixingDate ) // for each period, hence the t uses the effectiveFixingDate // However, it's slightly safe to get the zeroRate with the // fixingDate to avoid potential problems at the edges of periods - double t = zeroInflation_.link.dayCounter().yearFraction( baseDate, effectiveFixingDate ); + double t = zeroInflation_.link.dayCounter().yearFraction(baseDate, effectiveFixingDate); bool forceLinearInterpolation = false; - double zero = zeroInflation_.link.zeroRate( fixingDate, new Period( 0, TimeUnit.Days ), forceLinearInterpolation ); + double zero = zeroInflation_.link.zeroRate(fixingDate, new Period(0, TimeUnit.Days), forceLinearInterpolation); // Annual compounding is the convention for zero inflation rates (or quotes) - return baseFixing * Math.Pow( 1.0 + zero, t ); + return baseFixing * Math.Pow(1.0 + zero, t); } private Handle zeroInflation_; @@ -295,54 +296,54 @@ different time points. */ public class YoYInflationIndex : InflationIndex { - public YoYInflationIndex( string familyName, - Region region, - bool revised, - bool interpolated, - bool ratio, // is this one a genuine index or a ratio? - Frequency frequency, - Period availabilityLag, - Currency currency, - Handle yoyInflation = null ) - : base( familyName, region, revised, interpolated, frequency, availabilityLag, currency ) + public YoYInflationIndex(string familyName, + Region region, + bool revised, + bool interpolated, + bool ratio, // is this one a genuine index or a ratio? + Frequency frequency, + Period availabilityLag, + Currency currency, + Handle yoyInflation = null) + : base(familyName, region, revised, interpolated, frequency, availabilityLag, currency) { ratio_ = ratio; yoyInflation_ = yoyInflation ?? new Handle(); - yoyInflation_.registerWith( update ); + yoyInflation_.registerWith(update); } // Index interface // The forecastTodaysFixing parameter (required by the Index interface) is currently ignored. - public override double fixing( Date fixingDate, bool forecastTodaysFixing = false ) + public override double fixing(Date fixingDate, bool forecastTodaysFixing = false) { Date today = Settings.evaluationDate(); Date todayMinusLag = today - availabilityLag_; - KeyValuePair limm = Utils.inflationPeriod( todayMinusLag, frequency_ ); + KeyValuePair limm = Utils.inflationPeriod(todayMinusLag, frequency_); Date lastFix = limm.Key - 1; Date flatMustForecastOn = lastFix + 1; - Date interpMustForecastOn = lastFix + 1 - new Period( frequency_ ); + Date interpMustForecastOn = lastFix + 1 - new Period(frequency_); - if ( interpolated() && fixingDate >= interpMustForecastOn ) + if (interpolated() && fixingDate >= interpMustForecastOn) { - return forecastFixing( fixingDate ); + return forecastFixing(fixingDate); } - if ( !interpolated() && fixingDate >= flatMustForecastOn ) + if (!interpolated() && fixingDate >= flatMustForecastOn) { - return forecastFixing( fixingDate ); + return forecastFixing(fixingDate); } // four cases with ratio() and interpolated() - if ( ratio() ) + if (ratio()) { - if ( interpolated() ) + if (interpolated()) { // IS ratio, IS interpolated - KeyValuePair lim = Utils.inflationPeriod( fixingDate, frequency_ ); - Date fixMinus1Y = new NullCalendar().advance( fixingDate, new Period( -1, TimeUnit.Years ), BusinessDayConvention.ModifiedFollowing ); - KeyValuePair limBef = Utils.inflationPeriod( fixMinus1Y, frequency_ ); + KeyValuePair lim = Utils.inflationPeriod(fixingDate, frequency_); + Date fixMinus1Y = new NullCalendar().advance(fixingDate, new Period(-1, TimeUnit.Years), BusinessDayConvention.ModifiedFollowing); + KeyValuePair limBef = Utils.inflationPeriod(fixMinus1Y, frequency_); double dp = lim.Value + 1 - lim.Key; double dpBef = limBef.Value + 1 - limBef.Key; double dl = fixingDate - lim.Key; @@ -351,20 +352,20 @@ public override double fixing( Date fixingDate, bool forecastTodaysFixing = fals // get the four relevant fixings // recall that they are stored flat for every day double? limFirstFix = - IndexManager.instance().getHistory( name() ).value()[lim.Key]; - Utils.QL_REQUIRE( limFirstFix != null ,()=> "Missing " + name() + " fixing for " + lim.Key ); + IndexManager.instance().getHistory(name())[lim.Key]; + Utils.QL_REQUIRE(limFirstFix != null, () => "Missing " + name() + " fixing for " + lim.Key); double? limSecondFix = - IndexManager.instance().getHistory( name() ).value()[lim.Value + 1]; - Utils.QL_REQUIRE( limSecondFix != null ,()=> "Missing " + name() + " fixing for " + lim.Value + 1 ); + IndexManager.instance().getHistory(name())[lim.Value + 1]; + Utils.QL_REQUIRE(limSecondFix != null, () => "Missing " + name() + " fixing for " + lim.Value + 1); double? limBefFirstFix = - IndexManager.instance().getHistory( name() ).value()[limBef.Key]; - Utils.QL_REQUIRE( limBefFirstFix != null ,()=> "Missing " + name() + " fixing for " + limBef.Key ); + IndexManager.instance().getHistory(name())[limBef.Key]; + Utils.QL_REQUIRE(limBefFirstFix != null, () => "Missing " + name() + " fixing for " + limBef.Key); double? limBefSecondFix = - IndexManager.instance().getHistory( name() ).value()[limBef.Value + 1]; - Utils.QL_REQUIRE( limBefSecondFix != null ,()=> "Missing " + name() + " fixing for " + limBef.Value + 1 ); + IndexManager.instance().getHistory(name())[limBef.Value + 1]; + Utils.QL_REQUIRE(limBefSecondFix != null, () => "Missing " + name() + " fixing for " + limBef.Value + 1); - double linearNow = limFirstFix.Value + ( limSecondFix.Value - limFirstFix.Value ) * dl / dp; - double linearBef = limBefFirstFix.Value + ( limBefSecondFix.Value - limBefFirstFix.Value ) * dlBef / dpBef; + double linearNow = limFirstFix.Value + (limSecondFix.Value - limFirstFix.Value) * dl / dp; + double linearBef = limBefFirstFix.Value + (limBefSecondFix.Value - limBefFirstFix.Value) * dlBef / dpBef; double wasYES = linearNow / linearBef - 1.0; return wasYES; @@ -373,28 +374,28 @@ public override double fixing( Date fixingDate, bool forecastTodaysFixing = fals else { // IS ratio, NOT interpolated - double? pastFixing = IndexManager.instance().getHistory( name() ).value()[fixingDate]; - Utils.QL_REQUIRE( pastFixing != null , ()=> "Missing " + name() + " fixing for " + fixingDate ); - Date previousDate = fixingDate - new Period( 1, TimeUnit.Years ); - double? previousFixing = IndexManager.instance().getHistory( name() ).value()[previousDate]; - Utils.QL_REQUIRE( previousFixing != null,()=> "Missing " + name() + " fixing for " + previousDate ); + double? pastFixing = IndexManager.instance().getHistory(name())[fixingDate]; + Utils.QL_REQUIRE(pastFixing != null, () => "Missing " + name() + " fixing for " + fixingDate); + Date previousDate = fixingDate - new Period(1, TimeUnit.Years); + double? previousFixing = IndexManager.instance().getHistory(name())[previousDate]; + Utils.QL_REQUIRE(previousFixing != null, () => "Missing " + name() + " fixing for " + previousDate); return pastFixing.Value / previousFixing.Value - 1.0; } } else { // NOT ratio - if ( interpolated() ) + if (interpolated()) { // NOT ratio, IS interpolated - KeyValuePair lim = Utils.inflationPeriod( fixingDate, frequency_ ); + KeyValuePair lim = Utils.inflationPeriod(fixingDate, frequency_); double dp = lim.Value + 1 - lim.Key; double dl = fixingDate - lim.Key; - double? limFirstFix = IndexManager.instance().getHistory( name() ).value()[lim.Key]; - Utils.QL_REQUIRE( limFirstFix != null,()=> "Missing " + name() + " fixing for " + lim.Key ); - double? limSecondFix = IndexManager.instance().getHistory( name() ).value()[lim.Value + 1]; - Utils.QL_REQUIRE( limSecondFix != null ,()=> "Missing " + name() + " fixing for " + lim.Value + 1 ); - double linearNow = limFirstFix.Value + ( limSecondFix.Value - limFirstFix.Value ) * dl / dp; + double? limFirstFix = IndexManager.instance().getHistory(name())[lim.Key]; + Utils.QL_REQUIRE(limFirstFix != null, () => "Missing " + name() + " fixing for " + lim.Key); + double? limSecondFix = IndexManager.instance().getHistory(name())[lim.Value + 1]; + Utils.QL_REQUIRE(limSecondFix != null, () => "Missing " + name() + " fixing for " + lim.Value + 1); + double linearNow = limFirstFix.Value + (limSecondFix.Value - limFirstFix.Value) * dl / dp; return linearNow; } @@ -402,8 +403,8 @@ public override double fixing( Date fixingDate, bool forecastTodaysFixing = fals { // NOT ratio, NOT interpolated // so just flat - double? pastFixing = IndexManager.instance().getHistory( name() ).value()[fixingDate]; - Utils.QL_REQUIRE( pastFixing != null ,()=> "Missing " + name() + " fixing for " + fixingDate ); + double? pastFixing = IndexManager.instance().getHistory(name())[fixingDate]; + Utils.QL_REQUIRE(pastFixing != null, () => "Missing " + name() + " fixing for " + fixingDate); return pastFixing.Value; } @@ -413,18 +414,18 @@ public override double fixing( Date fixingDate, bool forecastTodaysFixing = fals // Other methods public bool ratio() { return ratio_; } public Handle yoyInflationTermStructure() { return yoyInflation_; } - public YoYInflationIndex clone( Handle h ) + public YoYInflationIndex clone(Handle h) { - return new YoYInflationIndex( familyName_, region_, revised_, + return new YoYInflationIndex(familyName_, region_, revised_, interpolated_, ratio_, frequency_, - availabilityLag_, currency_, h ); + availabilityLag_, currency_, h); } - private double forecastFixing( Date fixingDate ) + private double forecastFixing(Date fixingDate) { Date d; - if ( interpolated() ) + if (interpolated()) { d = fixingDate; } @@ -432,10 +433,10 @@ private double forecastFixing( Date fixingDate ) { // if the value is not interpolated use the starting value // by internal convention this will be consistent - KeyValuePair lim = Utils.inflationPeriod( fixingDate, frequency_ ); + KeyValuePair lim = Utils.inflationPeriod(fixingDate, frequency_); d = lim.Key; } - return yoyInflation_.link.yoyRate( d, new Period( 0, TimeUnit.Days ) ); + return yoyInflation_.link.yoyRate(d, new Period(0, TimeUnit.Days)); } private bool ratio_; private Handle yoyInflation_; diff --git a/src/QLNet/Indexes/InterestRateIndex.cs b/src/QLNet/Indexes/InterestRateIndex.cs index 9bd89a5ff..94a70dfb1 100644 --- a/src/QLNet/Indexes/InterestRateIndex.cs +++ b/src/QLNet/Indexes/InterestRateIndex.cs @@ -7,13 +7,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -26,31 +26,31 @@ namespace QLNet /*! \todo add methods returning InterestRate */ public abstract class InterestRateIndex : Index, IObserver { - protected InterestRateIndex( string familyName, - Period tenor, - int fixingDays, - Currency currency, - Calendar fixingCalendar, - DayCounter dayCounter ) + protected InterestRateIndex(string familyName, + Period tenor, + int fixingDays, + Currency currency, + Calendar fixingCalendar, + DayCounter dayCounter) { familyName_ = familyName; tenor_ = tenor; fixingDays_ = fixingDays; currency_ = currency; - dayCounter_ = dayCounter; + dayCounter_ = dayCounter; fixingCalendar_ = fixingCalendar; tenor_.normalize(); string res = familyName_; - if ( tenor_ == new Period( 1, TimeUnit.Days ) ) + if (tenor_ == new Period(1, TimeUnit.Days)) { - if ( fixingDays_ == 0 ) + if (fixingDays_ == 0) res += "ON"; - else if ( fixingDays_ == 1 ) + else if (fixingDays_ == 1) res += "TN"; - else if ( fixingDays_ == 2 ) + else if (fixingDays_ == 2) res += "SN"; else res += tenor_.ToShortString(); @@ -58,11 +58,11 @@ protected InterestRateIndex( string familyName, else res += tenor_.ToShortString(); res = res + " " + dayCounter_.name(); - name_= res; + name_ = res; - Settings.registerWith( update ); + Settings.registerWith(update); // recheck - IndexManager.instance().notifier( name() ).registerWith( update ); + IndexManager.instance().notifier(name()).registerWith(update); } // Index interface @@ -71,16 +71,16 @@ public override string name() return name_; } public override Calendar fixingCalendar() { return fixingCalendar_; } - public override bool isValidFixingDate( Date fixingDate ) { return fixingCalendar().isBusinessDay( fixingDate ); } - public override double fixing( Date fixingDate, bool forecastTodaysFixing = false ) + public override bool isValidFixingDate(Date fixingDate) { return fixingCalendar().isBusinessDay(fixingDate); } + public override double fixing(Date fixingDate, bool forecastTodaysFixing = false) { - Utils.QL_REQUIRE( isValidFixingDate( fixingDate ),()=> "Fixing date " + fixingDate + " is not valid" ); + Utils.QL_REQUIRE(isValidFixingDate(fixingDate), () => "Fixing date " + fixingDate + " is not valid"); Date today = Settings.evaluationDate(); - if ( fixingDate > today || - ( fixingDate == today && forecastTodaysFixing ) ) - return forecastFixing( fixingDate ); + if (fixingDate > today || + (fixingDate == today && forecastTodaysFixing)) + return forecastFixing(fixingDate); if (fixingDate < today || Settings.enforcesTodaysHistoricFixings) { @@ -91,17 +91,17 @@ public override double fixing( Date fixingDate, bool forecastTodaysFixing = fals return result.Value; } - try + try { // might have been fixed double? result = pastFixing(fixingDate); - if (result!=null) - return result.Value; + if (result != null) + return result.Value; - } + } catch (Exception) { - + } return forecastFixing(fixingDate); } @@ -113,9 +113,9 @@ public override double fixing( Date fixingDate, bool forecastTodaysFixing = fals public string familyName() { return familyName_; } public Period tenor() { return tenor_; } public int fixingDays() { return fixingDays_; } - public Date fixingDate( Date valueDate ) + public Date fixingDate(Date valueDate) { - Date fixingDate = fixingCalendar().advance( valueDate, -fixingDays_, TimeUnit.Days ); + Date fixingDate = fixingCalendar().advance(valueDate, -fixingDays_, TimeUnit.Days); return fixingDate; } public Currency currency() { return currency_; } @@ -123,21 +123,21 @@ public Date fixingDate( Date valueDate ) // Date calculations // These methods can be overridden to implement particular conventions (e.g. EurLibor) */ - public virtual Date valueDate( Date fixingDate ) + public virtual Date valueDate(Date fixingDate) { - Utils.QL_REQUIRE( isValidFixingDate( fixingDate ),()=> fixingDate + " is not a valid fixing date" ); - return fixingCalendar().advance( fixingDate, fixingDays_, TimeUnit.Days ); + Utils.QL_REQUIRE(isValidFixingDate(fixingDate), () => fixingDate + " is not a valid fixing date"); + return fixingCalendar().advance(fixingDate, fixingDays_, TimeUnit.Days); } - public abstract Date maturityDate( Date valueDate ); + public abstract Date maturityDate(Date valueDate); // Fixing calculations //! It can be overridden to implement particular conventions - public abstract double forecastFixing( Date fixingDate ); + public abstract double forecastFixing(Date fixingDate); public virtual double? pastFixing(Date fixingDate) { - Utils.QL_REQUIRE( isValidFixingDate( fixingDate ),()=> fixingDate + " is not a valid fixing date" ); - if (timeSeries().value().ContainsKey(fixingDate)) - return timeSeries().value()[fixingDate]; + Utils.QL_REQUIRE(isValidFixingDate(fixingDate), () => fixingDate + " is not a valid fixing date"); + if (timeSeries().ContainsKey(fixingDate)) + return timeSeries()[fixingDate]; else return null; } diff --git a/src/QLNet/Indexes/Region.cs b/src/QLNet/Indexes/Region.cs index 6eca634c2..062b13b8c 100644 --- a/src/QLNet/Indexes/Region.cs +++ b/src/QLNet/Indexes/Region.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - * + * This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,7 +23,7 @@ namespace QLNet public class Region { // Inspectors - public string name() + public string name() { return data_.name; } @@ -31,26 +31,28 @@ public string code() { return data_.code; } - + protected Region() {} protected struct Data { - public readonly string name; - public readonly string code; - - public Data(string Name, string Code) - { - name = Name; - code = Code; - } + public readonly string name; + public readonly string code; + + public Data(string Name, string Code) + { + name = Name; + code = Code; + } } protected Data data_; public static bool operator ==(Region r1, Region r2) { - if ( ReferenceEquals( r1, r2 ) ) return true; - if ( (object)r1 == null || (object)r2 == null ) return false; - return r1.Equals( r2 ); + if (ReferenceEquals(r1, r2)) + return true; + if ((object)r1 == null || (object)r2 == null) + return false; + return r1.Equals(r2); } public static bool operator !=(Region r1, Region r2) @@ -60,7 +62,7 @@ public Data(string Name, string Code) public override bool Equals(object o) { - return name() == ( (Region)o ).name(); + return name() == ((Region)o).name(); } public override int GetHashCode() @@ -70,64 +72,64 @@ public override int GetHashCode() } //! Australia as geographical/economic region - public class AustraliaRegion : Region + public class AustraliaRegion : Region { public AustraliaRegion() { - Data AUdata = new Data("Australia","AU"); - data_ = AUdata; + Data AUdata = new Data("Australia", "AU"); + data_ = AUdata; } - + } //! European Union as geographical/economic region - public class EURegion : Region + public class EURegion : Region { public EURegion() { - Data EUdata = new Data("EU","EU"); - data_ = EUdata; + Data EUdata = new Data("EU", "EU"); + data_ = EUdata; } } //! France as geographical/economic region - public class FranceRegion : Region + public class FranceRegion : Region { public FranceRegion() { - Data FRdata = new Data("France","FR"); + Data FRdata = new Data("France", "FR"); data_ = FRdata; } } - + //! United Kingdom as geographical/economic region - public class UKRegion : Region + public class UKRegion : Region { public UKRegion() { - Data UKdata = new Data("UK","UK"); + Data UKdata = new Data("UK", "UK"); data_ = UKdata; } } //! USA as geographical/economic region - public class USRegion : Region + public class USRegion : Region { public USRegion() { - Data USdata = new Data( "USA", "US" ); - data_ = USdata; + Data USdata = new Data("USA", "US"); + data_ = USdata; } } - //! South Africa as geographical/economic region + //! South Africa as geographical/economic region public class ZARegion : Region { public ZARegion() { Data ZAdata = new Data("South Africa", "ZA"); data_ = ZAdata; - } + } } } diff --git a/src/QLNet/Indexes/Swapindex.cs b/src/QLNet/Indexes/Swapindex.cs index fcd3a3578..079c76552 100644 --- a/src/QLNet/Indexes/Swapindex.cs +++ b/src/QLNet/Indexes/Swapindex.cs @@ -2,18 +2,18 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -28,16 +28,16 @@ public class SwapIndex : InterestRateIndex public SwapIndex() { } - public SwapIndex( string familyName, - Period tenor, - int settlementDays, - Currency currency, - Calendar calendar, - Period fixedLegTenor, - BusinessDayConvention fixedLegConvention, - DayCounter fixedLegDayCounter, - IborIndex iborIndex ) : - base( familyName, tenor, settlementDays, currency, calendar, fixedLegDayCounter ) + public SwapIndex(string familyName, + Period tenor, + int settlementDays, + Currency currency, + Calendar calendar, + Period fixedLegTenor, + BusinessDayConvention fixedLegConvention, + DayCounter fixedLegDayCounter, + IborIndex iborIndex) : + base(familyName, tenor, settlementDays, currency, calendar, fixedLegDayCounter) { tenor_ = tenor; iborIndex_ = iborIndex; @@ -46,19 +46,20 @@ public SwapIndex( string familyName, exogenousDiscount_ = false; discount_ = new Handle(); - iborIndex_.registerWith( update ); + iborIndex_.registerWith(update); } - public SwapIndex( string familyName, - Period tenor, - int settlementDays, - Currency currency, - Calendar calendar, - Period fixedLegTenor, - BusinessDayConvention fixedLegConvention, - DayCounter fixedLegDayCounter, - IborIndex iborIndex, - Handle discountingTermStructure ) + public SwapIndex(string familyName, + Period tenor, + int settlementDays, + Currency currency, + Calendar calendar, + Period fixedLegTenor, + BusinessDayConvention fixedLegConvention, + DayCounter fixedLegDayCounter, + IborIndex iborIndex, + Handle discountingTermStructure) : + base(familyName, tenor, settlementDays, currency, calendar, fixedLegDayCounter) { tenor_ = tenor; iborIndex_ = iborIndex; @@ -67,14 +68,15 @@ public SwapIndex( string familyName, exogenousDiscount_ = true; discount_ = discountingTermStructure; - iborIndex_.registerWith( update ); + iborIndex_.registerWith(update); + discount_.registerWith(update); } // InterestRateIndex interface - public override Date maturityDate( Date valueDate ) + public override Date maturityDate(Date valueDate) { - Date fixDate = fixingDate( valueDate ); - return underlyingSwap( fixDate ).maturityDate(); + Date fixDate = fixingDate(valueDate); + return underlyingSwap(fixDate).maturityDate(); } // Inspectors public Period fixedLegTenor() { return fixedLegTenor_; } @@ -85,106 +87,106 @@ public override Date maturityDate( Date valueDate ) public bool exogenousDiscount() { return exogenousDiscount_; } // \warning Relinking the term structure underlying the index will not have effect on the returned swap. // recheck - public VanillaSwap underlyingSwap( Date fixingDate ) + public VanillaSwap underlyingSwap(Date fixingDate) { - Utils.QL_REQUIRE( fixingDate != null,()=> "null fixing date" ); + Utils.QL_REQUIRE(fixingDate != null, () => "null fixing date"); // caching mechanism - if ( lastFixingDate_ != fixingDate ) + if (lastFixingDate_ != fixingDate) { double fixedRate = 0.0; - if ( exogenousDiscount_ ) - lastSwap_ = new MakeVanillaSwap( tenor_, iborIndex_, fixedRate ) - .withEffectiveDate( valueDate( fixingDate ) ) - .withFixedLegCalendar( fixingCalendar() ) - .withFixedLegDayCount( dayCounter_ ) - .withFixedLegTenor( fixedLegTenor_ ) - .withFixedLegConvention( fixedLegConvention_ ) - .withFixedLegTerminationDateConvention( fixedLegConvention_ ) - .withDiscountingTermStructure( discount_ ) - .value(); + if (exogenousDiscount_) + lastSwap_ = new MakeVanillaSwap(tenor_, iborIndex_, fixedRate) + .withEffectiveDate(valueDate(fixingDate)) + .withFixedLegCalendar(fixingCalendar()) + .withFixedLegDayCount(dayCounter_) + .withFixedLegTenor(fixedLegTenor_) + .withFixedLegConvention(fixedLegConvention_) + .withFixedLegTerminationDateConvention(fixedLegConvention_) + .withDiscountingTermStructure(discount_) + .value(); else - lastSwap_ = new MakeVanillaSwap( tenor_, iborIndex_, fixedRate ) - .withEffectiveDate( valueDate( fixingDate ) ) - .withFixedLegCalendar( fixingCalendar() ) - .withFixedLegDayCount( dayCounter_ ) - .withFixedLegTenor( fixedLegTenor_ ) - .withFixedLegConvention( fixedLegConvention_ ) - .withFixedLegTerminationDateConvention( fixedLegConvention_ ) - .value(); + lastSwap_ = new MakeVanillaSwap(tenor_, iborIndex_, fixedRate) + .withEffectiveDate(valueDate(fixingDate)) + .withFixedLegCalendar(fixingCalendar()) + .withFixedLegDayCount(dayCounter_) + .withFixedLegTenor(fixedLegTenor_) + .withFixedLegConvention(fixedLegConvention_) + .withFixedLegTerminationDateConvention(fixedLegConvention_) + .value(); lastFixingDate_ = fixingDate; } return lastSwap_; } // Other methods // returns a copy of itself linked to a different forwarding curve - public virtual SwapIndex clone( Handle forwarding ) + public virtual SwapIndex clone(Handle forwarding) { - if ( exogenousDiscount_ ) - return new SwapIndex( familyName(), - tenor(), - fixingDays(), - currency(), - fixingCalendar(), - fixedLegTenor(), - fixedLegConvention(), - dayCounter(), - iborIndex_.clone( forwarding ), - discount_ ); + if (exogenousDiscount_) + return new SwapIndex(familyName(), + tenor(), + fixingDays(), + currency(), + fixingCalendar(), + fixedLegTenor(), + fixedLegConvention(), + dayCounter(), + iborIndex_.clone(forwarding), + discount_); else - return new SwapIndex( familyName(), - tenor(), - fixingDays(), - currency(), - fixingCalendar(), - fixedLegTenor(), - fixedLegConvention(), - dayCounter(), - iborIndex_.clone( forwarding ) ); + return new SwapIndex(familyName(), + tenor(), + fixingDays(), + currency(), + fixingCalendar(), + fixedLegTenor(), + fixedLegConvention(), + dayCounter(), + iborIndex_.clone(forwarding)); } //! returns a copy of itself linked to a different curves - public virtual SwapIndex clone( Handle forwarding, Handle discounting ) + public virtual SwapIndex clone(Handle forwarding, Handle discounting) { - return new SwapIndex( familyName(), - tenor(), - fixingDays(), - currency(), - fixingCalendar(), - fixedLegTenor(), - fixedLegConvention(), - dayCounter(), - iborIndex_.clone( forwarding ), - discounting ); + return new SwapIndex(familyName(), + tenor(), + fixingDays(), + currency(), + fixingCalendar(), + fixedLegTenor(), + fixedLegConvention(), + dayCounter(), + iborIndex_.clone(forwarding), + discounting); } //! returns a copy of itself linked to a different tenor - public virtual SwapIndex clone( Period tenor ) + public virtual SwapIndex clone(Period tenor) { - if ( exogenousDiscount_ ) - return new SwapIndex( familyName(), - tenor, - fixingDays(), - currency(), - fixingCalendar(), - fixedLegTenor(), - fixedLegConvention(), - dayCounter(), - iborIndex(), - discountingTermStructure() ); + if (exogenousDiscount_) + return new SwapIndex(familyName(), + tenor, + fixingDays(), + currency(), + fixingCalendar(), + fixedLegTenor(), + fixedLegConvention(), + dayCounter(), + iborIndex(), + discountingTermStructure()); else - return new SwapIndex( familyName(), - tenor, - fixingDays(), - currency(), - fixingCalendar(), - fixedLegTenor(), - fixedLegConvention(), - dayCounter(), - iborIndex() ); + return new SwapIndex(familyName(), + tenor, + fixingDays(), + currency(), + fixingCalendar(), + fixedLegTenor(), + fixedLegConvention(), + dayCounter(), + iborIndex()); } - public override double forecastFixing( Date fixingDate ) + public override double forecastFixing(Date fixingDate) { - return underlyingSwap( fixingDate ).fairRate(); + return underlyingSwap(fixingDate).fairRate(); } - + protected new Period tenor_; protected IborIndex iborIndex_; protected Period fixedLegTenor_; @@ -200,15 +202,15 @@ public override double forecastFixing( Date fixingDate ) //! base class for overnight indexed swap indexes public class OvernightIndexedSwapIndex : SwapIndex { - public OvernightIndexedSwapIndex( string familyName, - Period tenor, - int settlementDays, - Currency currency, - OvernightIndex overnightIndex ) - : base( familyName, tenor, settlementDays, + public OvernightIndexedSwapIndex(string familyName, + Period tenor, + int settlementDays, + Currency currency, + OvernightIndex overnightIndex) + : base(familyName, tenor, settlementDays, currency, overnightIndex.fixingCalendar(), - new Period( 1, TimeUnit.Years ), BusinessDayConvention.ModifiedFollowing, - overnightIndex.dayCounter(), overnightIndex ) + new Period(1, TimeUnit.Years), BusinessDayConvention.ModifiedFollowing, + overnightIndex.dayCounter(), overnightIndex) { overnightIndex_ = overnightIndex; } @@ -217,26 +219,26 @@ public OvernightIndexedSwapIndex( string familyName, /*! \warning Relinking the term structure underlying the index will not have effect on the returned swap. */ - public new OvernightIndexedSwap underlyingSwap( Date fixingDate ) + public new OvernightIndexedSwap underlyingSwap(Date fixingDate) { - Utils.QL_REQUIRE( fixingDate != null,()=> "null fixing date" ); - if ( lastFixingDate_ != fixingDate ) + Utils.QL_REQUIRE(fixingDate != null, () => "null fixing date"); + if (lastFixingDate_ != fixingDate) { double fixedRate = 0.0; - lastSwap_ = new MakeOIS( tenor_, overnightIndex_, fixedRate ) - .withEffectiveDate( valueDate( fixingDate ) ) - .withFixedLegDayCount( dayCounter_ ); + lastSwap_ = new MakeOIS(tenor_, overnightIndex_, fixedRate) + .withEffectiveDate(valueDate(fixingDate)) + .withFixedLegDayCount(dayCounter_); lastFixingDate_ = fixingDate; } return lastSwap_; } - + protected OvernightIndex overnightIndex_; // cache data to avoid swap recreation when the same fixing date // is used multiple time to forecast changing fixing protected new OvernightIndexedSwap lastSwap_; protected new Date lastFixingDate_; - }; + } } diff --git a/src/QLNet/Indexes/swap/ChfLiborSwap.cs b/src/QLNet/Indexes/swap/ChfLiborSwap.cs index 008c30802..c7f94b6e8 100644 --- a/src/QLNet/Indexes/swap/ChfLiborSwap.cs +++ b/src/QLNet/Indexes/swap/ChfLiborSwap.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -30,12 +30,12 @@ Reuters and Intercapital Brokers at 11am London. Reuters page ISDAFIX. */ - public class ChfLiborSwapIsdaFix : SwapIndex + public class ChfLiborSwapIsdaFix : SwapIndex { public ChfLiborSwapIsdaFix(Period tenor) : this(tenor, new Handle()) { } - public ChfLiborSwapIsdaFix(Period tenor,Handle h) + public ChfLiborSwapIsdaFix(Period tenor, Handle h) : base("ChfLiborSwapIsdaFix", // familyName tenor, 2, // settlementDays @@ -45,7 +45,7 @@ public ChfLiborSwapIsdaFix(Period tenor,Handle h) BusinessDayConvention.ModifiedFollowing, // fixedLegConvention new Thirty360(Thirty360.Thirty360Convention.BondBasis), // fixedLegDaycounter tenor > new Period(1, TimeUnit.Years) ? - new CHFLibor(new Period(6, TimeUnit.Months), h) : - new CHFLibor(new Period(3, TimeUnit.Months), h)) { } - }; + new CHFLibor(new Period(6, TimeUnit.Months), h) : + new CHFLibor(new Period(3, TimeUnit.Months), h)) { } + } } diff --git a/src/QLNet/Indexes/swap/EurLiborSwap.cs b/src/QLNet/Indexes/swap/EurLiborSwap.cs index 99a3dcc3a..50d972db5 100644 --- a/src/QLNet/Indexes/swap/EurLiborSwap.cs +++ b/src/QLNet/Indexes/swap/EurLiborSwap.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,23 +29,23 @@ Reuters and Intercapital Brokers at 10am London. Reuters page ISDAFIX. */ - public class EurLiborSwapIsdaFixA : SwapIndex + public class EurLiborSwapIsdaFixA : SwapIndex { public EurLiborSwapIsdaFixA(Period tenor) - :this(tenor,new Handle() ) {} + : this(tenor, new Handle()) {} - public EurLiborSwapIsdaFixA(Period tenor,Handle h) + public EurLiborSwapIsdaFixA(Period tenor, Handle h) : base("EurLiborSwapIsdaFixA", // familyName tenor, 2, // settlementDays new EURCurrency(), new TARGET(), - new Period(1,TimeUnit.Years), // fixedLegTenor + new Period(1, TimeUnit.Years), // fixedLegTenor BusinessDayConvention.ModifiedFollowing, // fixedLegConvention new Thirty360(Thirty360.Thirty360Convention.BondBasis), // fixedLegDaycounter - tenor > new Period(1,TimeUnit.Years) ? - new EURLibor(new Period(6,TimeUnit.Months), h) : - new EURLibor(new Period(3,TimeUnit.Months), h)) {} + tenor > new Period(1, TimeUnit.Years) ? + new EURLibor(new Period(6, TimeUnit.Months), h) : + new EURLibor(new Period(3, TimeUnit.Months), h)) {} public EurLiborSwapIsdaFixA(Period tenor, Handle forwarding, @@ -55,12 +55,12 @@ public EurLiborSwapIsdaFixA(Period tenor, 2, // settlementDays new EURCurrency(), new TARGET(), - new Period(1,TimeUnit.Years), // fixedLegTenor + new Period(1, TimeUnit.Years), // fixedLegTenor BusinessDayConvention.ModifiedFollowing, // fixedLegConvention new Thirty360(Thirty360.Thirty360Convention.BondBasis), // fixedLegDaycounter - tenor > new Period(1,TimeUnit.Years) ? - new EURLibor(new Period(6,TimeUnit.Months), forwarding) : - new EURLibor(new Period(3,TimeUnit.Months), forwarding), + tenor > new Period(1, TimeUnit.Years) ? + new EURLibor(new Period(6, TimeUnit.Months), forwarding) : + new EURLibor(new Period(3, TimeUnit.Months), forwarding), discounting) {} } @@ -74,23 +74,23 @@ Reuters and Intercapital Brokers at 11am London. Reuters page ISDAFIX. */ - public class EurLiborSwapIsdaFixB : SwapIndex + public class EurLiborSwapIsdaFixB : SwapIndex { public EurLiborSwapIsdaFixB(Period tenor) - :this(tenor,new Handle() ) {} + : this(tenor, new Handle()) {} - public EurLiborSwapIsdaFixB(Period tenor,Handle h) + public EurLiborSwapIsdaFixB(Period tenor, Handle h) : base("EurLiborSwapIsdaFixB", // familyName tenor, 2, // settlementDays new EURCurrency(), new TARGET(), - new Period(1,TimeUnit.Years), // fixedLegTenor + new Period(1, TimeUnit.Years), // fixedLegTenor BusinessDayConvention.ModifiedFollowing, // fixedLegConvention new Thirty360(Thirty360.Thirty360Convention.BondBasis), // fixedLegDaycounter - tenor > new Period(1,TimeUnit.Years) ? - new EURLibor(new Period(6,TimeUnit.Months), h) : - new EURLibor(new Period(3,TimeUnit.Months), h)) {} + tenor > new Period(1, TimeUnit.Years) ? + new EURLibor(new Period(6, TimeUnit.Months), h) : + new EURLibor(new Period(3, TimeUnit.Months), h)) {} public EurLiborSwapIsdaFixB(Period tenor, Handle forwarding, @@ -100,12 +100,12 @@ public EurLiborSwapIsdaFixB(Period tenor, 2, // settlementDays new EURCurrency(), new TARGET(), - new Period(1,TimeUnit.Years), // fixedLegTenor + new Period(1, TimeUnit.Years), // fixedLegTenor BusinessDayConvention.ModifiedFollowing, // fixedLegConvention new Thirty360(Thirty360.Thirty360Convention.BondBasis), // fixedLegDaycounter - tenor > new Period(1,TimeUnit.Years) ? - new EURLibor(new Period(6,TimeUnit.Months), forwarding) : - new EURLibor(new Period(3,TimeUnit.Months), forwarding), + tenor > new Period(1, TimeUnit.Years) ? + new EURLibor(new Period(6, TimeUnit.Months), forwarding) : + new EURLibor(new Period(3, TimeUnit.Months), forwarding), discounting) {} } @@ -116,28 +116,28 @@ distributed by Reuters page TGM42281 and by Telerate. For more info see . */ - public class EurLiborSwapIfrFix : SwapIndex + public class EurLiborSwapIfrFix : SwapIndex { public EurLiborSwapIfrFix(Period tenor) - :this(tenor,new Handle() ) {} + : this(tenor, new Handle()) {} - public EurLiborSwapIfrFix(Period tenor,Handle h) + public EurLiborSwapIfrFix(Period tenor, Handle h) : base("EurLiborSwapIfrFix", // familyName tenor, 2, // settlementDays new EURCurrency(), new TARGET(), - new Period(1,TimeUnit.Years), // fixedLegTenor + new Period(1, TimeUnit.Years), // fixedLegTenor BusinessDayConvention.ModifiedFollowing, // fixedLegConvention new Thirty360(Thirty360.Thirty360Convention.BondBasis), // fixedLegDaycounter - tenor > new Period(1,TimeUnit.Years) ? - new EURLibor(new Period(6,TimeUnit.Months), h) : - new EURLibor(new Period(3,TimeUnit.Months), h)) {} + tenor > new Period(1, TimeUnit.Years) ? + new EURLibor(new Period(6, TimeUnit.Months), h) : + new EURLibor(new Period(3, TimeUnit.Months), h)) {} + - public EurLiborSwapIfrFix(Period tenor, - Handle forwarding, - Handle discounting) + Handle forwarding, + Handle discounting) : base("EurLiborSwapIfrFix", // familyName tenor, 2, // settlementDays @@ -147,9 +147,9 @@ public EurLiborSwapIfrFix(Period tenor, BusinessDayConvention.ModifiedFollowing, // fixedLegConvention new Thirty360(Thirty360.Thirty360Convention.BondBasis), // fixedLegDaycounter tenor > new Period(1, TimeUnit.Years) ? - new EURLibor(new Period(6, TimeUnit.Months), forwarding) : - new EURLibor(new Period(3, TimeUnit.Months), forwarding), + new EURLibor(new Period(6, TimeUnit.Months), forwarding) : + new EURLibor(new Period(3, TimeUnit.Months), forwarding), discounting) {} - } + } } diff --git a/src/QLNet/Indexes/swap/EuriborSwap.cs b/src/QLNet/Indexes/swap/EuriborSwap.cs index f5a426d65..d1af23669 100644 --- a/src/QLNet/Indexes/swap/EuriborSwap.cs +++ b/src/QLNet/Indexes/swap/EuriborSwap.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,38 +29,38 @@ Reuters and Intercapital Brokers at 11am Frankfurt. Reuters page ISDAFIX. */ - public class EuriborSwapIsdaFixA : SwapIndex + public class EuriborSwapIsdaFixA : SwapIndex { public EuriborSwapIsdaFixA(Period tenor) - :this(tenor,new Handle()) {} + : this(tenor, new Handle()) {} - public EuriborSwapIsdaFixA(Period tenor,Handle h) - :base("EuriborSwapIsdaFixA", // familyName + public EuriborSwapIsdaFixA(Period tenor, Handle h) + : base("EuriborSwapIsdaFixA", // familyName tenor, 2, // settlementDays new EURCurrency(), new TARGET(), - new Period(1,TimeUnit.Years), // fixedLegTenor + new Period(1, TimeUnit.Years), // fixedLegTenor BusinessDayConvention.ModifiedFollowing, // fixedLegConvention new Thirty360(Thirty360.Thirty360Convention.BondBasis), // fixedLegDaycounter - tenor > new Period(1,TimeUnit.Years) ? - new Euribor(new Period(6,TimeUnit.Months), h) : - new Euribor(new Period(3,TimeUnit.Months), h)) {} - + tenor > new Period(1, TimeUnit.Years) ? + new Euribor(new Period(6, TimeUnit.Months), h) : + new Euribor(new Period(3, TimeUnit.Months), h)) {} + public EuriborSwapIsdaFixA(Period tenor, - Handle forwarding, + Handle forwarding, Handle discounting) : base("EuriborSwapIsdaFixA", // familyName tenor, 2, // settlementDays new EURCurrency(), new TARGET(), - new Period(1,TimeUnit.Years), // fixedLegTenor + new Period(1, TimeUnit.Years), // fixedLegTenor BusinessDayConvention.ModifiedFollowing, // fixedLegConvention new Thirty360(Thirty360.Thirty360Convention.BondBasis), // fixedLegDaycounter - tenor > new Period(1,TimeUnit.Years) ? - new Euribor(new Period(6,TimeUnit.Months), forwarding) : - new Euribor(new Period(3,TimeUnit.Months), forwarding), + tenor > new Period(1, TimeUnit.Years) ? + new Euribor(new Period(6, TimeUnit.Months), forwarding) : + new Euribor(new Period(3, TimeUnit.Months), forwarding), discounting) {} } @@ -74,23 +74,23 @@ Reuters and Intercapital Brokers at 12am Frankfurt. Reuters page ISDAFIX. */ - public class EuriborSwapIsdaFixB : SwapIndex + public class EuriborSwapIsdaFixB : SwapIndex { public EuriborSwapIsdaFixB(Period tenor) - :this(tenor,new Handle() ){} + : this(tenor, new Handle()) {} - public EuriborSwapIsdaFixB(Period tenor,Handle h) + public EuriborSwapIsdaFixB(Period tenor, Handle h) : base("EuriborSwapIsdaFixB", // familyName tenor, 2, // settlementDays new EURCurrency(), new TARGET(), - new Period(1,TimeUnit.Years), // fixedLegTenor + new Period(1, TimeUnit.Years), // fixedLegTenor BusinessDayConvention.ModifiedFollowing, // fixedLegConvention new Thirty360(Thirty360.Thirty360Convention.BondBasis), // fixedLegDaycounter - tenor > new Period(1,TimeUnit.Years) ? - new Euribor(new Period(6,TimeUnit.Months), h) : - new Euribor(new Period(3,TimeUnit.Months), h)) {} + tenor > new Period(1, TimeUnit.Years) ? + new Euribor(new Period(6, TimeUnit.Months), h) : + new Euribor(new Period(3, TimeUnit.Months), h)) {} public EuriborSwapIsdaFixB(Period tenor, @@ -101,12 +101,12 @@ public EuriborSwapIsdaFixB(Period tenor, 2, // settlementDays new EURCurrency(), new TARGET(), - new Period(1,TimeUnit.Years), // fixedLegTenor + new Period(1, TimeUnit.Years), // fixedLegTenor BusinessDayConvention.ModifiedFollowing, // fixedLegConvention new Thirty360(Thirty360.Thirty360Convention.BondBasis), // fixedLegDaycounter - tenor > new Period(1,TimeUnit.Years) ? - new Euribor(new Period(6,TimeUnit.Months), forwarding) : - new Euribor(new Period(3,TimeUnit.Months), forwarding), + tenor > new Period(1, TimeUnit.Years) ? + new Euribor(new Period(6, TimeUnit.Months), forwarding) : + new Euribor(new Period(3, TimeUnit.Months), forwarding), discounting) {} } @@ -117,23 +117,23 @@ distributed by Reuters page TGM42281 and by Telerate. For more info see . */ - public class EuriborSwapIfrFix : SwapIndex + public class EuriborSwapIfrFix : SwapIndex { public EuriborSwapIfrFix(Period tenor) : this(tenor, new Handle()) { } - public EuriborSwapIfrFix(Period tenor,Handle h) + public EuriborSwapIfrFix(Period tenor, Handle h) : base("EuriborSwapIfrFix", // familyName tenor, 2, // settlementDays new EURCurrency(), new TARGET(), - new Period(1,TimeUnit.Years), // fixedLegTenor + new Period(1, TimeUnit.Years), // fixedLegTenor BusinessDayConvention.ModifiedFollowing, // fixedLegConvention new Thirty360(Thirty360.Thirty360Convention.BondBasis), // fixedLegDaycounter - tenor > new Period(1,TimeUnit.Years) ? - new Euribor(new Period(6,TimeUnit.Months), h) : - new Euribor(new Period(3,TimeUnit.Months), h)) {} + tenor > new Period(1, TimeUnit.Years) ? + new Euribor(new Period(6, TimeUnit.Months), h) : + new Euribor(new Period(3, TimeUnit.Months), h)) {} public EuriborSwapIfrFix(Period tenor, Handle forwarding, @@ -148,9 +148,9 @@ public EuriborSwapIfrFix(Period tenor, BusinessDayConvention.ModifiedFollowing, // fixedLegConvention new Thirty360(Thirty360.Thirty360Convention.BondBasis), // fixedLegDaycounter tenor > new Period(1, TimeUnit.Years) ? - new Euribor(new Period(6, TimeUnit.Months), forwarding) : - new Euribor(new Period(3, TimeUnit.Months), forwarding), + new Euribor(new Period(6, TimeUnit.Months), forwarding) : + new Euribor(new Period(3, TimeUnit.Months), forwarding), discounting) {} - }; + } } diff --git a/src/QLNet/Indexes/swap/GbpLiborSwap.cs b/src/QLNet/Indexes/swap/GbpLiborSwap.cs index 60b09007f..7fd727fcc 100644 --- a/src/QLNet/Indexes/swap/GbpLiborSwap.cs +++ b/src/QLNet/Indexes/swap/GbpLiborSwap.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -31,11 +31,11 @@ public GbpLiborSwapIsdaFix(Period tenor, Handle h) new GBPCurrency(), new TARGET(), tenor > new Period(1, TimeUnit.Years) ? - new Period(6, TimeUnit.Months) : new Period(1, TimeUnit.Years), // fixedLegTenor + new Period(6, TimeUnit.Months) : new Period(1, TimeUnit.Years), // fixedLegTenor BusinessDayConvention.ModifiedFollowing, // fixedLegConvention new Actual365Fixed(), // fixedLegDaycounter tenor > new Period(1, TimeUnit.Years) ? - new GBPLibor(new Period(6, TimeUnit.Months), h) : - new GBPLibor(new Period(3, TimeUnit.Months), h)) { } + new GBPLibor(new Period(6, TimeUnit.Months), h) : + new GBPLibor(new Period(3, TimeUnit.Months), h)) { } } } diff --git a/src/QLNet/Indexes/swap/JpyLiborSwap.cs b/src/QLNet/Indexes/swap/JpyLiborSwap.cs index a298cfc6a..0a4110e85 100644 --- a/src/QLNet/Indexes/swap/JpyLiborSwap.cs +++ b/src/QLNet/Indexes/swap/JpyLiborSwap.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Indexes/swap/SwapSpreadIndex.cs b/src/QLNet/Indexes/swap/SwapSpreadIndex.cs new file mode 100644 index 000000000..0e60ee886 --- /dev/null +++ b/src/QLNet/Indexes/swap/SwapSpreadIndex.cs @@ -0,0 +1,113 @@ +// Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) +// +// This file is part of QLNet Project https://github.com/amaggiulli/qlnet +// QLNet is free software: you can redistribute it and/or modify it +// under the terms of the QLNet license. You should have received a +// copy of the license along with this program; if not, license is +// available at . +// +// QLNet is a based on QuantLib, a free-software/open-source library +// for financial quantitative analysts and developers - http://quantlib.org/ +// The QuantLib license is available online at http://quantlib.org/license.shtml. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the license for more details. +using System; + +namespace QLNet +{ + /// + /// class for swap-rate spread indexes + /// + public class SwapSpreadIndex : InterestRateIndex + { + public SwapSpreadIndex(String familyName, + SwapIndex swapIndex1, + SwapIndex swapIndex2, + double gearing1 = 1.0, + double gearing2 = -1.0) + : base(familyName, swapIndex1.tenor(), // does not make sense, but we have to provide one + swapIndex1.fixingDays(), swapIndex1.currency(), swapIndex1.fixingCalendar(), swapIndex1.dayCounter()) + { + swapIndex1_ = swapIndex1; + swapIndex2_ = swapIndex2; + gearing1_ = gearing1; + gearing2_ = gearing2; + + swapIndex1_.registerWith(update); + swapIndex2_.registerWith(update); + + name_ = swapIndex1_.name() + "(" + gearing1 + ") + " + + swapIndex2_.name() + "(" + gearing1 + ")"; + + Utils.QL_REQUIRE(swapIndex1_.fixingDays() == swapIndex2_.fixingDays(), () => + "index1 fixing days (" + + swapIndex1_.fixingDays() + ")" + + "must be equal to index2 fixing days (" + + swapIndex2_.fixingDays() + ")"); + + Utils.QL_REQUIRE(swapIndex1_.fixingCalendar() == swapIndex2_.fixingCalendar(), () => + "index1 fixingCalendar (" + + swapIndex1_.fixingCalendar() + ")" + + "must be equal to index2 fixingCalendar (" + + swapIndex2_.fixingCalendar() + ")"); + + Utils.QL_REQUIRE(swapIndex1_.currency() == swapIndex2_.currency(), () => + "index1 currency (" + swapIndex1_.currency() + ")" + + "must be equal to index2 currency (" + + swapIndex2_.currency() + ")"); + + Utils.QL_REQUIRE(swapIndex1_.dayCounter() == swapIndex2_.dayCounter(), () => + "index1 dayCounter (" + + swapIndex1_.dayCounter() + ")" + + "must be equal to index2 dayCounter (" + + swapIndex2_.dayCounter() + ")"); + + Utils.QL_REQUIRE(swapIndex1_.fixedLegTenor() == swapIndex2_.fixedLegTenor(), () => + "index1 fixedLegTenor (" + + swapIndex1_.fixedLegTenor() + ")" + + "must be equal to index2 fixedLegTenor (" + + swapIndex2_.fixedLegTenor()); + + Utils.QL_REQUIRE(swapIndex1_.fixedLegConvention() == swapIndex2_.fixedLegConvention(), () => + "index1 fixedLegConvention (" + + swapIndex1_.fixedLegConvention() + ")" + + "must be equal to index2 fixedLegConvention (" + + swapIndex2_.fixedLegConvention()); + + } + + // need by CashFlowVectors + public SwapSpreadIndex() { } + + // InterestRateIndex interface + public override Date maturityDate(Date valueDate) + { + Utils.QL_FAIL("SwapSpreadIndex does not provide a single maturity date"); + return null; + } + + public override double forecastFixing(Date fixingDate) + { + return gearing1_ * swapIndex1_.fixing(fixingDate, false) + + gearing2_ * swapIndex2_.fixing(fixingDate, false); + } + + public override double? pastFixing(Date fixingDate) + { + return gearing1_ * swapIndex1_.pastFixing(fixingDate) + + gearing2_ * swapIndex2_.pastFixing(fixingDate); + } + public override bool allowsNativeFixings() { return false; } + + //! \name Inspectors + public SwapIndex swapIndex1() { return swapIndex1_; } + public SwapIndex swapIndex2() { return swapIndex2_; } + public double gearing1() { return gearing1_; } + public double gearing2() { return gearing2_; } + + private SwapIndex swapIndex1_, swapIndex2_; + private double gearing1_, gearing2_; + } +} diff --git a/src/QLNet/Indexes/swap/UsdLiborSwap.cs b/src/QLNet/Indexes/swap/UsdLiborSwap.cs index 5eddb363f..c38835993 100644 --- a/src/QLNet/Indexes/swap/UsdLiborSwap.cs +++ b/src/QLNet/Indexes/swap/UsdLiborSwap.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Instruments/AsianOption.cs b/src/QLNet/Instruments/AsianOption.cs index 716ea7741..864543eae 100644 --- a/src/QLNet/Instruments/AsianOption.cs +++ b/src/QLNet/Instruments/AsianOption.cs @@ -1,141 +1,142 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System.Collections.Generic; -namespace QLNet { +namespace QLNet +{ - //! Continuous-averaging Asian option + //! Continuous-averaging Asian option // ! \todo add running average // // \ingroup instruments -// - public class ContinuousAveragingAsianOption : OneAssetOption - { - public new class Arguments : OneAssetOption.Arguments - { - public Arguments() - { - averageType = Average.Type.NULL; - } - public override void validate() - { - base.validate(); - Utils.QL_REQUIRE(averageType != Average.Type.NULL,()=> "unspecified average type"); - } - public Average.Type averageType { get; set; } - } - - public new class Engine: GenericEngine - { - } - - public ContinuousAveragingAsianOption(Average.Type averageType, StrikedTypePayoff payoff, Exercise exercise) : base(payoff, exercise) - { - averageType_ = averageType; - } - public override void setupArguments(IPricingEngineArguments args) - { - - base.setupArguments(args); - - ContinuousAveragingAsianOption.Arguments moreArgs = args as ContinuousAveragingAsianOption.Arguments; - Utils.QL_REQUIRE(moreArgs != null,()=> "wrong argument type"); - moreArgs.averageType = averageType_; - } - protected Average.Type averageType_; - } - - //! Discrete-averaging Asian option - //! \ingroup instruments - public class DiscreteAveragingAsianOption : OneAssetOption - { - public new class Arguments : OneAssetOption.Arguments - { +// + public class ContinuousAveragingAsianOption : OneAssetOption + { + public new class Arguments : OneAssetOption.Arguments + { + public Arguments() + { + averageType = Average.Type.NULL; + } + public override void validate() + { + base.validate(); + Utils.QL_REQUIRE(averageType != Average.Type.NULL, () => "unspecified average type"); + } + public Average.Type averageType { get; set; } + } + + public new class Engine: GenericEngine + { + } + + public ContinuousAveragingAsianOption(Average.Type averageType, StrikedTypePayoff payoff, Exercise exercise) : base(payoff, exercise) + { + averageType_ = averageType; + } + public override void setupArguments(IPricingEngineArguments args) + { + + base.setupArguments(args); + + ContinuousAveragingAsianOption.Arguments moreArgs = args as ContinuousAveragingAsianOption.Arguments; + Utils.QL_REQUIRE(moreArgs != null, () => "wrong argument type"); + moreArgs.averageType = averageType_; + } + protected Average.Type averageType_; + } + + //! Discrete-averaging Asian option + //! \ingroup instruments + public class DiscreteAveragingAsianOption : OneAssetOption + { + public new class Arguments : OneAssetOption.Arguments + { public Arguments() - { - averageType = Average.Type.NULL; - runningAccumulator = null; + { + averageType = Average.Type.NULL; + runningAccumulator = null; pastFixings = null; - } - public override void validate() - { - base.validate(); - - Utils.QL_REQUIRE(averageType != Average.Type.NULL,()=> "unspecified average type"); - Utils.QL_REQUIRE(pastFixings != null,()=> "null past-fixing number"); - Utils.QL_REQUIRE(runningAccumulator != null,()=> "null running product"); - - switch (averageType) - { - case Average.Type.Arithmetic: - Utils.QL_REQUIRE(runningAccumulator >= 0.0,()=> - "non negative running sum required: " + runningAccumulator + " not allowed"); - break; - case Average.Type.Geometric: - Utils.QL_REQUIRE(runningAccumulator > 0.0,()=> - "positive running product required: " + runningAccumulator + " not allowed"); - break; - default: + } + public override void validate() + { + base.validate(); + + Utils.QL_REQUIRE(averageType != Average.Type.NULL, () => "unspecified average type"); + Utils.QL_REQUIRE(pastFixings != null, () => "null past-fixing number"); + Utils.QL_REQUIRE(runningAccumulator != null, () => "null running product"); + + switch (averageType) + { + case Average.Type.Arithmetic: + Utils.QL_REQUIRE(runningAccumulator >= 0.0, () => + "non negative running sum required: " + runningAccumulator + " not allowed"); + break; + case Average.Type.Geometric: + Utils.QL_REQUIRE(runningAccumulator > 0.0, () => + "positive running product required: " + runningAccumulator + " not allowed"); + break; + default: Utils.QL_FAIL("invalid average type"); - break; - } - - // check fixingTimes_ here - } - public Average.Type averageType { get; set; } + break; + } + + // check fixingTimes_ here + } + public Average.Type averageType { get; set; } public double? runningAccumulator { get; set; } public int? pastFixings { get; set; } public List fixingDates { get; set; } } - public new class Engine: GenericEngine - { - } + public new class Engine: GenericEngine + { + } - public DiscreteAveragingAsianOption(Average.Type averageType, double? runningAccumulator, int? pastFixings, List fixingDates, StrikedTypePayoff payoff, Exercise exercise) - : base(payoff, exercise) - { - averageType_ = averageType; - runningAccumulator_ = runningAccumulator; - pastFixings_ = pastFixings; - fixingDates_ = fixingDates; + public DiscreteAveragingAsianOption(Average.Type averageType, double? runningAccumulator, int? pastFixings, List fixingDates, StrikedTypePayoff payoff, Exercise exercise) + : base(payoff, exercise) + { + averageType_ = averageType; + runningAccumulator_ = runningAccumulator; + pastFixings_ = pastFixings; + fixingDates_ = fixingDates; fixingDates_.Sort(); - } - - public override void setupArguments(IPricingEngineArguments args) - { - - base.setupArguments(args); - - DiscreteAveragingAsianOption.Arguments moreArgs = args as DiscreteAveragingAsianOption.Arguments; - Utils.QL_REQUIRE(moreArgs != null,()=> "wrong argument type"); - - moreArgs.averageType = averageType_; - moreArgs.runningAccumulator = runningAccumulator_; - moreArgs.pastFixings = pastFixings_; - moreArgs.fixingDates = fixingDates_; - } - protected Average.Type averageType_; - protected double? runningAccumulator_; - protected int? pastFixings_; - protected List fixingDates_; - } + } + + public override void setupArguments(IPricingEngineArguments args) + { + + base.setupArguments(args); + + DiscreteAveragingAsianOption.Arguments moreArgs = args as DiscreteAveragingAsianOption.Arguments; + Utils.QL_REQUIRE(moreArgs != null, () => "wrong argument type"); + + moreArgs.averageType = averageType_; + moreArgs.runningAccumulator = runningAccumulator_; + moreArgs.pastFixings = pastFixings_; + moreArgs.fixingDates = fixingDates_; + } + protected Average.Type averageType_; + protected double? runningAccumulator_; + protected int? pastFixings_; + protected List fixingDates_; + } } diff --git a/src/QLNet/Instruments/AssetSwap.cs b/src/QLNet/Instruments/AssetSwap.cs index 6ca6b8f8d..72188b8ff 100644 --- a/src/QLNet/Instruments/AssetSwap.cs +++ b/src/QLNet/Instruments/AssetSwap.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -70,7 +70,7 @@ public AssetSwap(bool payBondCoupon, Date finalDate = schedule.calendar().adjust(schedule.endDate(), paymentAdjustment); Date adjBondMaturityDate = schedule.calendar().adjust(bond_.maturityDate(), paymentAdjustment); - Utils.QL_REQUIRE( finalDate == adjBondMaturityDate, () => + Utils.QL_REQUIRE(finalDate == adjBondMaturityDate, () => "adjusted schedule end date (" + finalDate + ") must be equal to adjusted bond maturity date (" + @@ -91,15 +91,15 @@ then scaled by the full price. */ if (floatingDayCount == null) legs_[1] = new IborLeg(schedule, iborIndex) - .withSpreads(spread) - .withNotionals(notional) - .withPaymentAdjustment(paymentAdjustment); + .withSpreads(spread) + .withNotionals(notional) + .withPaymentAdjustment(paymentAdjustment); else legs_[1] = new IborLeg(schedule, iborIndex) - .withSpreads(spread) - .withPaymentDayCounter(floatingDayCount) - .withNotionals(notional) - .withPaymentAdjustment(paymentAdjustment); + .withSpreads(spread) + .withPaymentDayCounter(floatingDayCount) + .withNotionals(notional) + .withPaymentAdjustment(paymentAdjustment); foreach (CashFlow c in legs_[1]) c.registerWith(update); @@ -114,7 +114,7 @@ then scaled by the full price. */ legs_[0].Add(c); } - Utils.QL_REQUIRE( !legs_[0].empty(), () => "empty bond leg to start with" ); + Utils.QL_REQUIRE(!legs_[0].empty(), () => "empty bond leg to start with"); // special flows if (parSwap_) @@ -136,7 +136,7 @@ then scaled by the full price. */ legs_[1].Add(finalCashFlow); } - Utils.QL_REQUIRE( !legs_[0].empty(), () => "empty bond leg" ); + Utils.QL_REQUIRE(!legs_[0].empty(), () => "empty bond leg"); foreach (CashFlow c in legs_[0]) c.registerWith(update); @@ -183,14 +183,14 @@ public AssetSwap(bool parAssetSwap, if (dealMaturity == null) dealMaturity = bond_.maturityDate(); - Utils.QL_REQUIRE( dealMaturity <= tempSch.dates().Last(), () => - "deal maturity " + dealMaturity + - " cannot be later than (adjusted) bond maturity " + - tempSch.dates().Last()); - Utils.QL_REQUIRE( dealMaturity > tempSch.dates()[0], () => - "deal maturity " + dealMaturity + - " must be later than swap start date " + - tempSch.dates()[0]); + Utils.QL_REQUIRE(dealMaturity <= tempSch.dates().Last(), () => + "deal maturity " + dealMaturity + + " cannot be later than (adjusted) bond maturity " + + tempSch.dates().Last()); + Utils.QL_REQUIRE(dealMaturity > tempSch.dates()[0], () => + "deal maturity " + dealMaturity + + " must be later than swap start date " + + tempSch.dates()[0]); // the following might become an input parameter BusinessDayConvention paymentAdjustment = BusinessDayConvention.Following; @@ -213,17 +213,17 @@ then scaled by the full price. */ if (floatingDayCount == null) legs_[1] = new IborLeg(schedule, iborIndex) - .withSpreads(spread) - .withGearings(gearing) - .withNotionals(notional) - .withPaymentAdjustment(paymentAdjustment); + .withSpreads(spread) + .withGearings(gearing) + .withNotionals(notional) + .withPaymentAdjustment(paymentAdjustment); else legs_[1] = new IborLeg(schedule, iborIndex) - .withSpreads(spread) - .withGearings(gearing) - .withPaymentDayCounter(floatingDayCount) - .withNotionals(notional) - .withPaymentAdjustment(paymentAdjustment); + .withSpreads(spread) + .withGearings(gearing) + .withPaymentDayCounter(floatingDayCount) + .withNotionals(notional) + .withPaymentAdjustment(paymentAdjustment); foreach (CashFlow c in legs_[1]) c.registerWith(update); @@ -255,7 +255,7 @@ then scaled by the full price. */ CashFlow nonParRepaymentFlow = new SimpleCashFlow(nonParRepayment_, finalDate); legs_[0].Add(nonParRepaymentFlow); - Utils.QL_REQUIRE( !legs_[0].empty(), () => "empty bond leg to start with" ); + Utils.QL_REQUIRE(!legs_[0].empty(), () => "empty bond leg to start with"); // special flows if (parSwap_) @@ -277,7 +277,7 @@ then scaled by the full price. */ legs_[1].Add(finalCashFlow); } - Utils.QL_REQUIRE( !legs_[0].empty(), () => "empty bond leg" ); + Utils.QL_REQUIRE(!legs_[0].empty(), () => "empty bond leg"); foreach (CashFlow c in legs_[0]) c.registerWith(update); @@ -319,14 +319,14 @@ public double fairSpread() public double floatingLegBPS() { calculate(); - Utils.QL_REQUIRE( legBPS_.Count > 1 && legBPS_[1] != null, () => "floating-leg BPS not available" ); + Utils.QL_REQUIRE(legBPS_.Count > 1 && legBPS_[1] != null, () => "floating-leg BPS not available"); return legBPS_[1].GetValueOrDefault(); } public double floatingLegNPV() { calculate(); - Utils.QL_REQUIRE( legNPV_.Count > 1 && legNPV_[1] != null, () => "floating-leg NPV not available" ); + Utils.QL_REQUIRE(legNPV_.Count > 1 && legNPV_[1] != null, () => "floating-leg NPV not available"); return legNPV_[1].GetValueOrDefault(); } @@ -339,12 +339,12 @@ public double fairCleanPrice() } else { - Utils.QL_REQUIRE( startDiscounts_[1] != null, () => "fair clean price not available for seasoned deal" ); + Utils.QL_REQUIRE(startDiscounts_[1] != null, () => "fair clean price not available for seasoned deal"); double notional = bond_.notional(upfrontDate_); if (parSwap_) { fairCleanPrice_ = bondCleanPrice_ - payer_[1] * - NPV_ * npvDateDiscount_ / startDiscounts_[1] / (notional / 100.0); + NPV_ * npvDateDiscount_ / startDiscounts_[1] / (notional / 100.0); } else { @@ -367,10 +367,10 @@ public double fairNonParRepayment() } else { - Utils.QL_REQUIRE( endDiscounts_[1] != null, () => "fair non par repayment not available for expired leg" ); + Utils.QL_REQUIRE(endDiscounts_[1] != null, () => "fair non par repayment not available for expired leg"); double notional = bond_.notional(upfrontDate_); fairNonParRepayment_ = nonParRepayment_ - payer_[0] * - NPV_ * npvDateDiscount_ / endDiscounts_[1] / (notional / 100.0); + NPV_ * npvDateDiscount_ / endDiscounts_[1] / (notional / 100.0); return fairNonParRepayment_.Value; } } @@ -399,7 +399,7 @@ public override void setupArguments(IPricingEngineArguments args) arguments.fixedResetDates = arguments.fixedPayDates = new List(fixedCoupons.Count); arguments.fixedCoupons = new List(fixedCoupons.Count); - for (int i=0; i floatingCoupons = floatingLeg(); arguments.floatingResetDates = arguments.floatingPayDates = - arguments.floatingFixingDates = new List(floatingCoupons.Count); + arguments.floatingFixingDates = new List(floatingCoupons.Count); arguments.floatingAccrualTimes = new List(floatingCoupons.Count); arguments.floatingSpreads = new List(floatingCoupons.Count); - for (int i=0; i floatingSpreads { get; set; } public override void validate() { - Utils.QL_REQUIRE( fixedResetDates.Count == fixedPayDates.Count, () => - "number of fixed start dates different from " + - "number of fixed payment dates"); - Utils.QL_REQUIRE( fixedPayDates.Count == fixedCoupons.Count, () => - "number of fixed payment dates different from " + - "number of fixed coupon amounts"); - Utils.QL_REQUIRE( floatingResetDates.Count == floatingPayDates.Count, () => - "number of floating start dates different from " + - "number of floating payment dates"); - Utils.QL_REQUIRE( floatingFixingDates.Count == floatingPayDates.Count, () => - "number of floating fixing dates different from " + - "number of floating payment dates"); - Utils.QL_REQUIRE( floatingAccrualTimes.Count == floatingPayDates.Count, () => - "number of floating accrual times different from " + - "number of floating payment dates"); - Utils.QL_REQUIRE( floatingSpreads.Count == floatingPayDates.Count, () => - "number of floating spreads different from " + - "number of floating payment dates"); + Utils.QL_REQUIRE(fixedResetDates.Count == fixedPayDates.Count, () => + "number of fixed start dates different from " + + "number of fixed payment dates"); + Utils.QL_REQUIRE(fixedPayDates.Count == fixedCoupons.Count, () => + "number of fixed payment dates different from " + + "number of fixed coupon amounts"); + Utils.QL_REQUIRE(floatingResetDates.Count == floatingPayDates.Count, () => + "number of floating start dates different from " + + "number of floating payment dates"); + Utils.QL_REQUIRE(floatingFixingDates.Count == floatingPayDates.Count, () => + "number of floating fixing dates different from " + + "number of floating payment dates"); + Utils.QL_REQUIRE(floatingAccrualTimes.Count == floatingPayDates.Count, () => + "number of floating accrual times different from " + + "number of floating payment dates"); + Utils.QL_REQUIRE(floatingSpreads.Count == floatingPayDates.Count, () => + "number of floating spreads different from " + + "number of floating payment dates"); } } diff --git a/src/QLNet/Instruments/AverageType.cs b/src/QLNet/Instruments/AverageType.cs index 12fa872a0..21b9e40ad 100644 --- a/src/QLNet/Instruments/AverageType.cs +++ b/src/QLNet/Instruments/AverageType.cs @@ -1,34 +1,35 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { +namespace QLNet +{ - //! Placeholder for enumerated averaging types - public struct Average - { - public enum Type - { - Arithmetic, - Geometric, - NULL - } - } + //! Placeholder for enumerated averaging types + public struct Average + { + public enum Type + { + Arithmetic, + Geometric, + NULL + } + } } diff --git a/src/QLNet/Instruments/BMASwap.cs b/src/QLNet/Instruments/BMASwap.cs new file mode 100644 index 000000000..3cf34a47f --- /dev/null +++ b/src/QLNet/Instruments/BMASwap.cs @@ -0,0 +1,139 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + //! swap paying Libor against BMA coupons + public class BMASwap : Swap + { + public enum Type { Receiver = -1, Payer = 1 } + + private Type type_; + public Type type() { return type_; } + + private double nominal_; + public double nominal() { return nominal_; } + + private double liborFraction_; + public double liborFraction() { return liborFraction_; } + + private double liborSpread_; + public double liborSpread() { return liborSpread_; } + + + public BMASwap(Type type, double nominal, + // Libor leg + Schedule liborSchedule, double liborFraction, double liborSpread, IborIndex liborIndex, DayCounter liborDayCount, + // BMA leg + Schedule bmaSchedule, BMAIndex bmaIndex, DayCounter bmaDayCount) + : base(2) + { + type_ = type; + nominal_ = nominal; + liborFraction_ = liborFraction; + liborSpread_ = liborSpread; + + BusinessDayConvention convention = liborSchedule.businessDayConvention(); + + legs_[0] = new IborLeg(liborSchedule, liborIndex) + .withPaymentDayCounter(liborDayCount) + .withFixingDays(liborIndex.fixingDays()) + .withGearings(liborFraction) + .withSpreads(liborSpread) + .withNotionals(nominal) + .withPaymentAdjustment(convention); + + legs_[1] = new AverageBMALeg(bmaSchedule, bmaIndex) + .withPaymentDayCounter(bmaDayCount) + .withNotionals(nominal) + .withPaymentAdjustment(bmaSchedule.businessDayConvention()); + + for (int j = 0; j < 2; ++j) + { + for (int i = 0; i < legs_[j].Count; i++) + legs_[j][i].registerWith(update); + } + + switch (type_) + { + case Type.Payer: + payer_[0] = +1.0; + payer_[1] = -1.0; + break; + case Type.Receiver: + payer_[0] = -1.0; + payer_[1] = +1.0; + break; + default: + Utils.QL_FAIL("Unknown BMA-swap type"); + break; + } + } + + + public List liborLeg() { return legs_[0]; } + public List bmaLeg() { return legs_[1]; } + + public double liborLegBPS() + { + calculate(); + Utils.QL_REQUIRE(legBPS_[0] != null, () => "result not available"); + return legBPS_[0].GetValueOrDefault(); + } + + public double liborLegNPV() + { + calculate(); + Utils.QL_REQUIRE(legNPV_[0] != null, () => "result not available"); + return legNPV_[0].GetValueOrDefault(); + } + + public double fairLiborFraction() + { + const double basisPoint = 1.0e-4; + + double spreadNPV = (liborSpread_ / basisPoint) * liborLegBPS(); + double pureLiborNPV = liborLegNPV() - spreadNPV; + Utils.QL_REQUIRE(pureLiborNPV.IsNotEqual(0.0), () => "result not available (null libor NPV)"); + return -liborFraction_ * (bmaLegNPV() + spreadNPV) / pureLiborNPV; + } + + public double fairLiborSpread() + { + const double basisPoint = 1.0e-4; + return liborSpread_ - NPV() / (liborLegBPS() / basisPoint); + } + + public double bmaLegBPS() + { + calculate(); + Utils.QL_REQUIRE(legBPS_[1] != null, () => "result not available"); + return legBPS_[1].GetValueOrDefault(); + } + + public double bmaLegNPV() + { + calculate(); + Utils.QL_REQUIRE(legNPV_[1] != null, () => "result not available"); + return legNPV_[1].GetValueOrDefault(); + } + } +} diff --git a/src/QLNet/Instruments/BarrierOption.cs b/src/QLNet/Instruments/BarrierOption.cs index 221126e94..3ab8d1a74 100644 --- a/src/QLNet/Instruments/BarrierOption.cs +++ b/src/QLNet/Instruments/BarrierOption.cs @@ -1,133 +1,134 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { - //! %Barrier option on a single asset. - // ! The analytic pricing Engine will be used if none if passed. - // - // \ingroup instruments - // - public class BarrierOption : OneAssetOption - { - public new class Arguments : OneAssetOption.Arguments - { - public Arguments() - { - barrierType = Barrier.Type.NULL; - barrier = null; - rebate = null; - } - public Barrier.Type barrierType { get; set; } - public double? barrier { get; set; } +namespace QLNet +{ + //! %Barrier option on a single asset. + // ! The analytic pricing Engine will be used if none if passed. + // + // \ingroup instruments + // + public class BarrierOption : OneAssetOption + { + public new class Arguments : OneAssetOption.Arguments + { + public Arguments() + { + barrierType = Barrier.Type.NULL; + barrier = null; + rebate = null; + } + public Barrier.Type barrierType { get; set; } + public double? barrier { get; set; } public double? rebate { get; set; } public override void validate() - { - base.validate(); - - switch (barrierType) - { + { + base.validate(); + + switch (barrierType) + { case Barrier.Type.DownIn: case Barrier.Type.UpIn: case Barrier.Type.DownOut: case Barrier.Type.UpOut: - break; - default: + break; + default: Utils.QL_FAIL("unknown type"); - break; - } - - Utils.QL_REQUIRE(barrier != null,()=> "no barrier given"); - Utils.QL_REQUIRE(rebate != null,()=> "no rebate given"); - } - } - - public new class Engine : GenericEngine - { - protected bool triggered(double underlying) - { - switch (arguments_.barrierType) - { + break; + } + + Utils.QL_REQUIRE(barrier != null, () => "no barrier given"); + Utils.QL_REQUIRE(rebate != null, () => "no rebate given"); + } + } + + public new class Engine : GenericEngine + { + protected bool triggered(double underlying) + { + switch (arguments_.barrierType) + { case Barrier.Type.DownIn: case Barrier.Type.DownOut: - return underlying < arguments_.barrier; + return underlying < arguments_.barrier; case Barrier.Type.UpIn: case Barrier.Type.UpOut: - return underlying > arguments_.barrier; - default: - Utils.QL_FAIL("unknown type"); - return false; - } - } - } - public BarrierOption(Barrier.Type barrierType, double barrier, double rebate, StrikedTypePayoff payoff, Exercise exercise) : base(payoff, exercise) - { - barrierType_ = barrierType; - barrier_ = barrier; - rebate_ = rebate; - } - - public override void setupArguments(IPricingEngineArguments args) - { - base.setupArguments(args); - - BarrierOption.Arguments moreArgs = args as BarrierOption.Arguments; - Utils.QL_REQUIRE(moreArgs != null,()=> "wrong argument type"); - - moreArgs.barrierType = barrierType_; - moreArgs.barrier = barrier_; - moreArgs.rebate = rebate_; - } + return underlying > arguments_.barrier; + default: + Utils.QL_FAIL("unknown type"); + return false; + } + } + } + public BarrierOption(Barrier.Type barrierType, double barrier, double rebate, StrikedTypePayoff payoff, Exercise exercise) : base(payoff, exercise) + { + barrierType_ = barrierType; + barrier_ = barrier; + rebate_ = rebate; + } + + public override void setupArguments(IPricingEngineArguments args) + { + base.setupArguments(args); + + BarrierOption.Arguments moreArgs = args as BarrierOption.Arguments; + Utils.QL_REQUIRE(moreArgs != null, () => "wrong argument type"); + + moreArgs.barrierType = barrierType_; + moreArgs.barrier = barrier_; + moreArgs.rebate = rebate_; + } // ! \warning see VanillaOption for notes on implied-volatility // calculation. - // - public double impliedVolatility( double targetValue, GeneralizedBlackScholesProcess process, double accuracy = 1.0e-4, - int maxEvaluations = 100, double minVol = 1.0e-7, double maxVol = 4.0) - { - Utils.QL_REQUIRE( !isExpired(), ()=> "option expired" ); - - SimpleQuote volQuote = new SimpleQuote(); - - GeneralizedBlackScholesProcess newProcess = ImpliedVolatilityHelper.clone(process, volQuote); - - // engines are built-in for the time being - IPricingEngine engine = null; - switch (exercise_.type()) - { - case Exercise.Type.European: - engine = new AnalyticBarrierEngine(newProcess); - break; + // + public double impliedVolatility(double targetValue, GeneralizedBlackScholesProcess process, double accuracy = 1.0e-4, + int maxEvaluations = 100, double minVol = 1.0e-7, double maxVol = 4.0) + { + Utils.QL_REQUIRE(!isExpired(), () => "option expired"); + + SimpleQuote volQuote = new SimpleQuote(); + + GeneralizedBlackScholesProcess newProcess = ImpliedVolatilityHelper.clone(process, volQuote); + + // engines are built-in for the time being + IPricingEngine engine = null; + switch (exercise_.type()) + { + case Exercise.Type.European: + engine = new AnalyticBarrierEngine(newProcess); + break; case Exercise.Type.American: case Exercise.Type.Bermudan: - Utils.QL_FAIL("Engine not available for non-European barrier option"); - break; - default: + Utils.QL_FAIL("Engine not available for non-European barrier option"); + break; + default: Utils.QL_FAIL("unknown exercise type"); - break; - } - - return ImpliedVolatilityHelper.calculate( this, engine, volQuote, targetValue, accuracy, maxEvaluations, minVol, maxVol); - } - + break; + } + + return ImpliedVolatilityHelper.calculate(this, engine, volQuote, targetValue, accuracy, maxEvaluations, minVol, maxVol); + } + // Arguments protected Barrier.Type barrierType_; - protected double? barrier_; - protected double? rebate_; - } + protected double? barrier_; + protected double? rebate_; + } } diff --git a/src/QLNet/Instruments/BarrierType.cs b/src/QLNet/Instruments/BarrierType.cs index cc22270f1..9da677d9f 100644 --- a/src/QLNet/Instruments/BarrierType.cs +++ b/src/QLNet/Instruments/BarrierType.cs @@ -1,35 +1,36 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { +namespace QLNet +{ - //! Placeholder for enumerated barrier types - public struct Barrier - { - public enum Type - { - DownIn, - UpIn, - DownOut, - UpOut, - NULL - } - } + //! Placeholder for enumerated barrier types + public struct Barrier + { + public enum Type + { + DownIn, + UpIn, + DownOut, + UpOut, + NULL + } + } } diff --git a/src/QLNet/Instruments/BasisSwap.cs b/src/QLNet/Instruments/BasisSwap.cs index 46cf46a57..56ac92b48 100644 --- a/src/QLNet/Instruments/BasisSwap.cs +++ b/src/QLNet/Instruments/BasisSwap.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,10 +24,10 @@ namespace QLNet //! Basis swap. Simple Libor swap vs Libor swap public class BasisSwap : Swap { - public enum Type { Receiver = -1, Payer = 1 }; + public enum Type { Receiver = -1, Payer = 1 } private Type type_; - private double spread1_,spread2_; + private double spread1_, spread2_; private double nominal_; private Schedule floating1Schedule_; @@ -38,7 +38,7 @@ public enum Type { Receiver = -1, Payer = 1 }; private Schedule floating2Schedule_; public Schedule floating2Schedule() { return floating2Schedule_; } - private IborIndex iborIndex1_,iborIndex2_; + private IborIndex iborIndex1_, iborIndex2_; private DayCounter floating2DayCount_; private BusinessDayConvention paymentConvention_; private int longNo_, shortNo_; @@ -46,15 +46,15 @@ public enum Type { Receiver = -1, Payer = 1 }; // constructor public BasisSwap(Type type, double nominal, - Schedule float1Schedule, IborIndex iborIndex1, double spread1, DayCounter float1DayCount, - Schedule float2Schedule, IborIndex iborIndex2, double spread2, DayCounter float2DayCount) + Schedule float1Schedule, IborIndex iborIndex1, double spread1, DayCounter float1DayCount, + Schedule float2Schedule, IborIndex iborIndex2, double spread2, DayCounter float2DayCount) : this(type, nominal, float1Schedule, iborIndex1, spread1, float1DayCount, - float2Schedule, iborIndex2, spread2, float2DayCount, null) { } + float2Schedule, iborIndex2, spread2, float2DayCount, null) { } public BasisSwap(Type type, double nominal, - Schedule float1Schedule, IborIndex iborIndex1, double spread1, DayCounter float1DayCount, - Schedule float2Schedule, IborIndex iborIndex2, double spread2, DayCounter float2DayCount, - BusinessDayConvention? paymentConvention) : - base(2) + Schedule float1Schedule, IborIndex iborIndex1, double spread1, DayCounter float1DayCount, + Schedule float2Schedule, IborIndex iborIndex2, double spread2, DayCounter float2DayCount, + BusinessDayConvention ? paymentConvention) : + base(2) { type_ = type; nominal_ = nominal; @@ -73,16 +73,16 @@ public BasisSwap(Type type, double nominal, paymentConvention_ = floating1Schedule_.businessDayConvention(); List floating1Leg = new IborLeg(float1Schedule, iborIndex1) - .withPaymentDayCounter(float1DayCount) - .withSpreads(spread1) - .withNotionals(nominal) - .withPaymentAdjustment(paymentConvention_); + .withPaymentDayCounter(float1DayCount) + .withSpreads(spread1) + .withNotionals(nominal) + .withPaymentAdjustment(paymentConvention_); List floating2Leg = new IborLeg(float2Schedule, iborIndex2) - .withPaymentDayCounter(float2DayCount) - .withSpreads(spread2) - .withNotionals(nominal) - .withPaymentAdjustment(paymentConvention_); + .withPaymentDayCounter(float2DayCount) + .withSpreads(spread2) + .withNotionals(nominal) + .withPaymentAdjustment(paymentConvention_); foreach (var cf in floating1Leg) cf.registerWith(update); @@ -188,26 +188,30 @@ public override void setupArguments(IPricingEngineArguments args) public double floating1LegBPS() { calculate(); - if (legBPS_[0] == null) throw new ArgumentException("result not available"); + if (legBPS_[0] == null) + throw new ArgumentException("result not available"); return legBPS_[0].GetValueOrDefault(); } public double floating1LegNPV() { calculate(); - if (legNPV_[0] == null) throw new ArgumentException("result not available"); + if (legNPV_[0] == null) + throw new ArgumentException("result not available"); return legNPV_[0].GetValueOrDefault(); } public double floating2LegBPS() { calculate(); - if (legBPS_[1] == null) throw new ArgumentException("result not available"); + if (legBPS_[1] == null) + throw new ArgumentException("result not available"); return legBPS_[1].GetValueOrDefault(); } public double floating2LegNPV() { calculate(); - if (legNPV_[1] == null) throw new ArgumentException("result not available"); + if (legNPV_[1] == null) + throw new ArgumentException("result not available"); return legNPV_[1].GetValueOrDefault(); } @@ -222,16 +226,18 @@ public double floating2LegNPV() public double fairLongSpread() { - calculate(); - if (fairLongSpread_ == null) throw new ArgumentException("result not available"); - return fairLongSpread_.GetValueOrDefault(); + calculate(); + if (fairLongSpread_ == null) + throw new ArgumentException("result not available"); + return fairLongSpread_.GetValueOrDefault(); } - + public double fairShortSpread() { - calculate(); - if (fairShortSpread_ == null) throw new ArgumentException("result not available"); - return fairShortSpread_.GetValueOrDefault(); + calculate(); + if (fairShortSpread_ == null) + throw new ArgumentException("result not available"); + return fairShortSpread_.GetValueOrDefault(); } protected override void setupExpired() @@ -258,7 +264,7 @@ public override void fetchResults(IPricingEngineResults r) } // Long fair spread should be fine - no averaging or compounding - if (fairLongSpread_ == null && legBPS_[longNo_] != null) + if (fairLongSpread_ == null && legBPS_[longNo_] != null) { fairLongSpread_ = longSpread_ - NPV_ / (legBPS_[longNo_] / basisPoint); } @@ -310,7 +316,8 @@ public override void validate() { base.validate(); - if (nominal.IsEqual(default(double))) throw new ArgumentException("nominal null or not set"); + if (nominal.IsEqual(default(double))) + throw new ArgumentException("nominal null or not set"); if (floating1ResetDates.Count != floating1PayDates.Count) throw new ArgumentException("number of floating1 start dates different from number of floating1 payment dates"); if (floating1PayDates.Count != floating1Coupons.Count) diff --git a/src/QLNet/Instruments/BasketOption.cs b/src/QLNet/Instruments/BasketOption.cs index 93a5fed24..a7089e2b5 100644 --- a/src/QLNet/Instruments/BasketOption.cs +++ b/src/QLNet/Instruments/BasketOption.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -115,7 +115,7 @@ public override double accumulate(Vector a) } //! Basket option on a number of assets - //! \ingroup instruments + //! \ingroup instruments public class BasketOption : MultiAssetOption { public new class Engine : GenericEngine diff --git a/src/QLNet/Instruments/Bond.cs b/src/QLNet/Instruments/Bond.cs index 030ca4e07..753cdfd13 100644 --- a/src/QLNet/Instruments/Bond.cs +++ b/src/QLNet/Instruments/Bond.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -54,10 +54,10 @@ public Bond(int settlementDays, Calendar calendar, Date issueDate = null, List - "issue date (" + issueDate_ + - ") must be earlier than first payment date (" + - cashflows_[0].date() + ")"); + Utils.QL_REQUIRE(issueDate_ < cashflows_[0].date(), () => + "issue date (" + issueDate_ + + ") must be earlier than first payment date (" + + cashflows_[0].date() + ")"); } maturityDate_ = coupons.Last().date(); addRedemptionsToCashflows(); @@ -71,7 +71,7 @@ public Bond(int settlementDays, Calendar calendar, Date issueDate = null, List cashflows = null) { settlementDays_ = settlementDays; @@ -79,7 +79,7 @@ public Bond(int settlementDays, Calendar calendar, double faceAmount, Date matur if (cashflows == null) cashflows_ = new List(); else - cashflows_ = cashflows; + cashflows_ = cashflows; maturityDate_ = maturityDate; issueDate_ = issueDate; @@ -87,15 +87,15 @@ public Bond(int settlementDays, Calendar calendar, double faceAmount, Date matur { cashflows_.Sort(0, cashflows_.Count - 1, null); - if (maturityDate_ ==null) - maturityDate_ = CashFlows.maturityDate(cashflows_); + if (maturityDate_ == null) + maturityDate_ = CashFlows.maturityDate(cashflows_); if (issueDate_ != null) { - Utils.QL_REQUIRE( issueDate_ < cashflows_[0].date(), () => - "issue date (" + issueDate_ + - ") must be earlier than first payment date (" + - cashflows_[0].date() + ")"); + Utils.QL_REQUIRE(issueDate_ < cashflows_[0].date(), () => + "issue date (" + issueDate_ + + ") must be earlier than first payment date (" + + cashflows_[0].date() + ")"); } notionalSchedule_.Add(new Date()); @@ -106,7 +106,7 @@ public Bond(int settlementDays, Calendar calendar, double faceAmount, Date matur redemptions_.Add(cashflows.Last()); - + } Settings.registerWith(update); @@ -126,7 +126,7 @@ public override bool isExpired() #endregion #region Inspectors - + public int settlementDays() { return settlementDays_; } public Calendar calendar() { return calendar_; } public List notionals() { return notionals_; } @@ -163,10 +163,10 @@ public virtual double notional(Date d = null) public List cashflows() { return cashflows_; } //! returns just the redemption flows (not interest payments) public List redemptions() { return redemptions_; } - // returns the redemption, if only one is defined + // returns the redemption, if only one is defined public CashFlow redemption() { - Utils.QL_REQUIRE( redemptions_.Count == 1, () => "multiple redemption cash flows given" ); + Utils.QL_REQUIRE(redemptions_.Count == 1, () => "multiple redemption cash flows given"); return redemptions_.Last(); } public Date startDate() { return BondFunctions.startDate(this);} @@ -189,7 +189,7 @@ public Date settlementDate(Date date = null) #endregion #region Calculations - + //! theoretical clean price /*! The default bond settlement is used for calculation. @@ -217,7 +217,7 @@ public double dirtyPrice() public double settlementValue() { calculate(); - Utils.QL_REQUIRE( settlementValue_ != null, () => "settlement value not provided" ); + Utils.QL_REQUIRE(settlementValue_ != null, () => "settlement value not provided"); return settlementValue_.Value; } @@ -232,11 +232,11 @@ public double settlementValue(double cleanPrice) public double yield(DayCounter dc, Compounding comp, Frequency freq, double accuracy = 1.0e-8, int maxEvaluations = 100) { double currentNotional = notional(settlementDate()); - + if (currentNotional.IsEqual(0.0)) return 0.0; - return BondFunctions.yield(this, cleanPrice(), dc, comp, freq,settlementDate(), accuracy, maxEvaluations); + return BondFunctions.yield(this, cleanPrice(), dc, comp, freq, settlementDate(), accuracy, maxEvaluations); } //! clean price given a yield and settlement date @@ -260,7 +260,7 @@ public double dirtyPrice(double yield, DayCounter dc, Compounding comp, Frequenc //! yield given a (clean) price and settlement date /*! The default bond settlement is used if no date is given. */ public double yield(double cleanPrice, DayCounter dc, Compounding comp, Frequency freq, Date settlement = null, - double accuracy = 1.0e-8, int maxEvaluations=100) + double accuracy = 1.0e-8, int maxEvaluations = 100) { double currentNotional = notional(settlement); if (currentNotional.IsEqual(0.0)) @@ -274,7 +274,7 @@ public double yield(double cleanPrice, DayCounter dc, Compounding comp, Frequenc public virtual double accruedAmount(Date settlement = null) { double currentNotional = notional(settlement); - + if (currentNotional.IsEqual(0.0)) return 0.0; @@ -328,7 +328,7 @@ protected override void setupExpired() public override void setupArguments(IPricingEngineArguments args) { Bond.Arguments arguments = args as Bond.Arguments; - Utils.QL_REQUIRE( arguments != null, () => "wrong argument type" ); + Utils.QL_REQUIRE(arguments != null, () => "wrong argument type"); arguments.settlementDate = settlementDate(); arguments.cashflows = cashflows_; @@ -340,7 +340,7 @@ public override void fetchResults(IPricingEngineResults r) base.fetchResults(r); Bond.Results results = r as Bond.Results; - Utils.QL_REQUIRE( results != null, () => "wrong result type" ); + Utils.QL_REQUIRE(results != null, () => "wrong result type"); settlementValue_ = results.settlementValue; } @@ -374,7 +374,7 @@ protected void addRedemptionsToCashflows(List redemptions = null) { double R = i < redemptions.Count ? redemptions[i] : !redemptions.empty() ? redemptions.Last() : - 100.0; + 100.0; double amount = (R / 100.0) * (notionals_[i - 1] - notionals_[i]); CashFlow payment; if (i < notionalSchedule_.Count - 1) @@ -387,7 +387,7 @@ protected void addRedemptionsToCashflows(List redemptions = null) } // stable_sort now moves the AmortizingPayment and Redemptions to the right places // while ensuring that they follow coupons with the same date. - cashflows_ = cashflows_.OrderBy( x => x.date() ).ToList(); + cashflows_ = cashflows_.OrderBy(x => x.date()).ToList(); } /*! This method can be called by derived classes in order to @@ -431,39 +431,39 @@ protected void calculateNotionalsFromCashflows() Date lastPaymentDate = new Date(); notionalSchedule_.Add(new Date()); - for (int i=0; i "increasing coupon notionals" ); - notionals_.Add(coupon.nominal()); - // in this case, we also add the last valid date for - // the previous one... - notionalSchedule_.Add(lastPaymentDate); - // ...and store the candidate for this one. - lastPaymentDate = coupon.date(); - } - else + // ...or if it has changed. + Utils.QL_REQUIRE(notional < notionals_.Last(), () => "increasing coupon notionals"); + notionals_.Add(coupon.nominal()); + // in this case, we also add the last valid date for + // the previous one... + notionalSchedule_.Add(lastPaymentDate); + // ...and store the candidate for this one. + lastPaymentDate = coupon.date(); + } + else { - // otherwise, we just extend the valid range of dates - // for the current notional. - lastPaymentDate = coupon.date(); + // otherwise, we just extend the valid range of dates + // for the current notional. + lastPaymentDate = coupon.date(); } - + } - Utils.QL_REQUIRE( !notionals_.empty(), () => "no coupons provided" ); + Utils.QL_REQUIRE(!notionals_.empty(), () => "no coupons provided"); notionals_.Add(0.0); notionalSchedule_.Add(lastPaymentDate); } @@ -501,10 +501,10 @@ public class Arguments : IPricingEngineArguments public virtual void validate() { - Utils.QL_REQUIRE( settlementDate != null, () => "no settlement date provided" ); - Utils.QL_REQUIRE( !cashflows.empty(), () => "no cash flow provided" ); + Utils.QL_REQUIRE(settlementDate != null, () => "no settlement date provided"); + Utils.QL_REQUIRE(!cashflows.empty(), () => "no cash flow provided"); for (int i = 0; i < cashflows.Count; ++i) - Utils.QL_REQUIRE( cashflows[i] != null, () => "null cash flow provided" ); + Utils.QL_REQUIRE(cashflows[i] != null, () => "null cash flow provided"); } } } diff --git a/src/QLNet/Instruments/Bonds/AmortizingBond.cs b/src/QLNet/Instruments/Bonds/AmortizingBond.cs index cbccc6214..f8426ff66 100644 --- a/src/QLNet/Instruments/Bonds/AmortizingBond.cs +++ b/src/QLNet/Instruments/Bonds/AmortizingBond.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,12 +23,12 @@ namespace QLNet { public enum AmortizingMethod { - EffectiveInterestRate + EffectiveInterestRate } public class AmortizingBond : Bond { - + public AmortizingBond(double FaceValue, double MarketValue, double CouponRate, @@ -62,10 +62,10 @@ public AmortizingBond(double FaceValue, else _yield = gYield; - // We can have several method here + // We can have several method here // Straight-Line Amortization , Effective Interest Rate, Rule 78 // for now we start with Effective Interest Rate. - switch ( _method ) + switch (_method) { case AmortizingMethod.EffectiveInterestRate: addEffectiveInterestRateAmortizing(); @@ -86,8 +86,8 @@ void addEffectiveInterestRateAmortizing() // Amortizing Schedule Schedule schedule = new Schedule(_tradeDate, _maturityDate, new Period(_payFrequency), - _calendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + _calendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); double currentNominal = _marketValue; Date prevDate = _tradeDate; Date actualDate = _tradeDate; @@ -98,11 +98,11 @@ void addEffectiveInterestRateAmortizing() actualDate = schedule[i]; InterestRate rate = new InterestRate(_yield, _dCounter, Compounding.Simple, Frequency.Annual); InterestRate rate2 = new InterestRate(_couponRate, _dCounter, Compounding.Simple, Frequency.Annual); - FixedRateCoupon r,r2; + FixedRateCoupon r, r2; if (i > 1) { - r = new FixedRateCoupon( actualDate, currentNominal, rate, prevDate, actualDate, prevDate, actualDate ); - r2 = new FixedRateCoupon( actualDate, currentNominal, rate2, prevDate, actualDate, prevDate, actualDate, null, _originalPayment ); + r = new FixedRateCoupon(actualDate, currentNominal, rate, prevDate, actualDate, prevDate, actualDate); + r2 = new FixedRateCoupon(actualDate, currentNominal, rate2, prevDate, actualDate, prevDate, actualDate, null, _originalPayment); } else @@ -111,12 +111,12 @@ void addEffectiveInterestRateAmortizing() Period p1 = new Period(_payFrequency); Date testDate = nullCalendar.advance(actualDate, -1 * p1); - r = new FixedRateCoupon( actualDate, currentNominal, rate, testDate, actualDate, prevDate, actualDate ); - r2 = new FixedRateCoupon( actualDate, currentNominal, rate2, testDate, actualDate, prevDate, actualDate, null, _originalPayment ); + r = new FixedRateCoupon(actualDate, currentNominal, rate, testDate, actualDate, prevDate, actualDate); + r2 = new FixedRateCoupon(actualDate, currentNominal, rate2, testDate, actualDate, prevDate, actualDate, null, _originalPayment); } - double amort = Math.Round(Math.Abs(_originalPayment - r.amount()),2); - + double amort = Math.Round(Math.Abs(_originalPayment - r.amount()), 2); + AmortizingPayment p = new AmortizingPayment(amort, actualDate); if (_isPremium) currentNominal -= Math.Abs(amort); @@ -144,10 +144,10 @@ public double AmortizationValue(Date d) Date lastDate = _tradeDate; foreach (CashFlow c in cashflows_) { - if ( c.date() <= d ) + if (c.date() <= d) { lastDate = c.date(); - if ( c is QLNet.AmortizingPayment ) + if (c is QLNet.AmortizingPayment) totAmortized += (c as QLNet.AmortizingPayment).amount(); } else @@ -155,18 +155,18 @@ public double AmortizationValue(Date d) } - if (lastDate < d ) + if (lastDate < d) { // lastDate < d let calculate last interest // Base Interest - InterestRate r1 = new InterestRate(_couponRate,_dCounter,Compounding.Simple,_payFrequency); - FixedRateCoupon c1 = new FixedRateCoupon( d, _faceValue,r1, lastDate, d ); + InterestRate r1 = new InterestRate(_couponRate, _dCounter, Compounding.Simple, _payFrequency); + FixedRateCoupon c1 = new FixedRateCoupon(d, _faceValue, r1, lastDate, d); double baseInterest = c1.amount(); - // - InterestRate r2 = new InterestRate(_yield,_dCounter,Compounding.Simple,_payFrequency); - FixedRateCoupon c2 = new FixedRateCoupon( d, _marketValue,r2, lastDate, d ); + // + InterestRate r2 = new InterestRate(_yield, _dCounter, Compounding.Simple, _payFrequency); + FixedRateCoupon c2 = new FixedRateCoupon(d, _marketValue, r2, lastDate, d); double yieldInterest = c2.amount(); totAmortized += Math.Abs(baseInterest - yieldInterest); @@ -174,9 +174,9 @@ public double AmortizationValue(Date d) if (_isPremium) - return (_marketValue - totAmortized); - else - return (_marketValue + totAmortized); + return (_marketValue - totAmortized); + else + return (_marketValue + totAmortized); } @@ -187,24 +187,24 @@ private double calculateYield() // We create a bond cashflow from issue to maturity just // to calculate effective rate ( the rate that discount _marketValue ) Schedule schedule = new Schedule(_issueDate, _maturityDate, new Period(_payFrequency), - _calendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + _calendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List cashflows = new FixedRateLeg(schedule) - .withCouponRates(_couponRate, _dCounter) - .withPaymentCalendar(_calendar) - .withNotionals(_faceValue) - .withPaymentAdjustment(BusinessDayConvention.Unadjusted); + .withCouponRates(_couponRate, _dCounter) + .withPaymentCalendar(_calendar) + .withNotionals(_faceValue) + .withPaymentAdjustment(BusinessDayConvention.Unadjusted); // Add single redemption for yield calculation - Redemption r = new Redemption(_faceValue , _maturityDate); - cashflows.Add( r ); + Redemption r = new Redemption(_faceValue, _maturityDate); + cashflows.Add(r); // Calculate Amortizing Yield ( Effective Rate ) Date testDate = CashFlows.previousCashFlowDate(cashflows, false, _tradeDate); return CashFlows.yield(cashflows, _marketValue, _dCounter, Compounding.Simple, _payFrequency, - false, testDate); + false, testDate); } // temporary testing function diff --git a/src/QLNet/Instruments/Bonds/AmortizingCmsRateBond.cs b/src/QLNet/Instruments/Bonds/AmortizingCmsRateBond.cs index 9daf281eb..41484ef02 100644 --- a/src/QLNet/Instruments/Bonds/AmortizingCmsRateBond.cs +++ b/src/QLNet/Instruments/Bonds/AmortizingCmsRateBond.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,47 +23,51 @@ namespace QLNet //! amortizing CMS-rate bond public class AmortizingCmsRateBond : Bond { - public AmortizingCmsRateBond( int settlementDays, - List notionals, - Schedule schedule, - SwapIndex index, - DayCounter paymentDayCounter, - BusinessDayConvention paymentConvention = BusinessDayConvention.Following, - int fixingDays = 0, - List gearings = null, - List spreads = null, - List caps = null, - List floors = null, - bool inArrears = false, - Date issueDate = null) - :base(settlementDays, schedule.calendar(), issueDate) + public AmortizingCmsRateBond(int settlementDays, + List notionals, + Schedule schedule, + SwapIndex index, + DayCounter paymentDayCounter, + BusinessDayConvention paymentConvention = BusinessDayConvention.Following, + int fixingDays = 0, + List gearings = null, + List spreads = null, + List < double? > caps = null, + List < double? > floors = null, + bool inArrears = false, + Date issueDate = null) + : base(settlementDays, schedule.calendar(), issueDate) { // Optional value check - if ( gearings == null ) gearings = new List(){1.0}; - if ( spreads == null ) spreads = new List(){0}; - if (caps == null) caps = new List(); - if (floors == null) floors = new List(); + if (gearings == null) + gearings = new List() {1.0}; + if (spreads == null) + spreads = new List() {0}; + if (caps == null) + caps = new List < double? >(); + if (floors == null) + floors = new List < double? >(); maturityDate_ = schedule.endDate(); cashflows_ = new CmsLeg(schedule, index) - .withPaymentDayCounter(paymentDayCounter) - .withFixingDays(fixingDays) - .withGearings(gearings) - .withSpreads(spreads) - .withCaps(caps) - .withFloors(floors) - .inArrears(inArrears) - .withNotionals(notionals) - .withPaymentAdjustment(paymentConvention); + .withPaymentDayCounter(paymentDayCounter) + .withFixingDays(fixingDays) + .withGearings(gearings) + .withSpreads(spreads) + .withCaps(caps) + .withFloors(floors) + .inArrears(inArrears) + .withNotionals(notionals) + .withPaymentAdjustment(paymentConvention); addRedemptionsToCashflows(); - Utils.QL_REQUIRE( !cashflows().empty(), () => "bond with no cashflows!" ); + Utils.QL_REQUIRE(!cashflows().empty(), () => "bond with no cashflows!"); index.registerWith(update); - + } - + } } diff --git a/src/QLNet/Instruments/Bonds/AmortizingFixedRateBond.cs b/src/QLNet/Instruments/Bonds/AmortizingFixedRateBond.cs index b4fe56583..4ef894210 100644 --- a/src/QLNet/Instruments/Bonds/AmortizingFixedRateBond.cs +++ b/src/QLNet/Instruments/Bonds/AmortizingFixedRateBond.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,14 +29,14 @@ public class AmortizingFixedRateBond : Bond protected Schedule schedule_; public AmortizingFixedRateBond( - int settlementDays, - List notionals, - Schedule schedule, - List coupons, - DayCounter accrualDayCounter, - BusinessDayConvention paymentConvention = BusinessDayConvention.Following, - Date issueDate = null) - :base(settlementDays, schedule.calendar(), issueDate) + int settlementDays, + List notionals, + Schedule schedule, + List coupons, + DayCounter accrualDayCounter, + BusinessDayConvention paymentConvention = BusinessDayConvention.Following, + Date issueDate = null) + : base(settlementDays, schedule.calendar(), issueDate) { frequency_ = schedule.tenor().frequency(); dayCounter_ = accrualDayCounter; @@ -45,70 +45,70 @@ public AmortizingFixedRateBond( maturityDate_ = schedule.endDate(); cashflows_ = new FixedRateLeg(schedule) - .withCouponRates(coupons, accrualDayCounter) - .withNotionals(notionals) - .withPaymentAdjustment(paymentConvention).value(); - + .withCouponRates(coupons, accrualDayCounter) + .withNotionals(notionals) + .withPaymentAdjustment(paymentConvention).value(); + addRedemptionsToCashflows(); - Utils.QL_REQUIRE( !cashflows().empty(),()=> "bond with no cashflows!"); + Utils.QL_REQUIRE(!cashflows().empty(), () => "bond with no cashflows!"); } public AmortizingFixedRateBond( - int settlementDays, - List notionals, - Schedule schedule, - List coupons, - DayCounter accrualDayCounter, - BusinessDayConvention paymentConvention = BusinessDayConvention.Following, - Date issueDate = null) - : base(settlementDays, schedule.calendar(), issueDate) + int settlementDays, + List notionals, + Schedule schedule, + List coupons, + DayCounter accrualDayCounter, + BusinessDayConvention paymentConvention = BusinessDayConvention.Following, + Date issueDate = null) + : base(settlementDays, schedule.calendar(), issueDate) { - frequency_ = schedule.tenor().frequency(); - dayCounter_ = accrualDayCounter; - schedule_ = schedule; + frequency_ = schedule.tenor().frequency(); + dayCounter_ = accrualDayCounter; + schedule_ = schedule; - maturityDate_ = schedule.endDate(); + maturityDate_ = schedule.endDate(); - cashflows_ = new FixedRateLeg(schedule) - .withCouponRates(coupons) - .withNotionals(notionals) - .withPaymentAdjustment(paymentConvention).value(); + cashflows_ = new FixedRateLeg(schedule) + .withCouponRates(coupons) + .withNotionals(notionals) + .withPaymentAdjustment(paymentConvention).value(); - addRedemptionsToCashflows(); + addRedemptionsToCashflows(); - Utils.QL_REQUIRE(!cashflows().empty(), () => "bond with no cashflows!"); + Utils.QL_REQUIRE(!cashflows().empty(), () => "bond with no cashflows!"); } public AmortizingFixedRateBond( - int settlementDays, - Calendar calendar, - double faceAmount, - Date startDate, - Period bondTenor, - Frequency sinkingFrequency, - double coupon, - DayCounter accrualDayCounter, - BusinessDayConvention paymentConvention = BusinessDayConvention.Following, - Date issueDate = null) - :base(settlementDays, calendar, issueDate) + int settlementDays, + Calendar calendar, + double faceAmount, + Date startDate, + Period bondTenor, + Frequency sinkingFrequency, + double coupon, + DayCounter accrualDayCounter, + BusinessDayConvention paymentConvention = BusinessDayConvention.Following, + Date issueDate = null) + : base(settlementDays, calendar, issueDate) { frequency_ = sinkingFrequency; dayCounter_ = accrualDayCounter; - Utils.QL_REQUIRE( bondTenor.length() > 0,() => - "bond tenor must be positive. " - + bondTenor + " is not allowed." ); + Utils.QL_REQUIRE(bondTenor.length() > 0, () => + "bond tenor must be positive. " + + bondTenor + " is not allowed."); maturityDate_ = startDate + bondTenor; maturityDate_ = startDate + bondTenor; schedule_ = sinkingSchedule(startDate, bondTenor, sinkingFrequency, calendar); cashflows_ = new FixedRateLeg(schedule_) - .withCouponRates(coupon, accrualDayCounter) - .withNotionals(sinkingNotionals(bondTenor, sinkingFrequency, coupon, faceAmount)) - .withPaymentAdjustment(paymentConvention).value(); + .withCouponRates(coupon, accrualDayCounter) + .withNotionals(sinkingNotionals(bondTenor, sinkingFrequency, coupon, faceAmount)) + .withPaymentAdjustment(paymentConvention).value(); addRedemptionsToCashflows(); @@ -117,88 +117,90 @@ public AmortizingFixedRateBond( public Frequency frequency() { return frequency_; } public DayCounter dayCounter() { return dayCounter_; } - protected Schedule sinkingSchedule( Date startDate, - Period maturityTenor, - Frequency sinkingFrequency, - Calendar paymentCalendar) + protected Schedule sinkingSchedule(Date startDate, + Period maturityTenor, + Frequency sinkingFrequency, + Calendar paymentCalendar) { - Period freqPeriod = new Period(sinkingFrequency); - Date maturityDate = new Date(startDate + maturityTenor); - Schedule retVal = new Schedule(startDate, maturityDate, freqPeriod, - paymentCalendar,BusinessDayConvention.Unadjusted,BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); - return retVal; + Period freqPeriod = new Period(sinkingFrequency); + Date maturityDate = new Date(startDate + maturityTenor); + Schedule retVal = new Schedule(startDate, maturityDate, freqPeriod, + paymentCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); + return retVal; } protected List sinkingNotionals(Period maturityTenor, - Frequency sinkingFrequency, - double couponRate, - double initialNotional) + Frequency sinkingFrequency, + double couponRate, + double initialNotional) { - Period freqPeriod = new Period(sinkingFrequency); - int nPeriods = 0; - Utils.QL_REQUIRE(isSubPeriod(freqPeriod, maturityTenor, out nPeriods),() => - "Bond frequency is incompatible with the maturity tenor"); - - List notionals = new InitializedList(nPeriods+1); - notionals[0] = initialNotional; - double coupon = couponRate / (double)sinkingFrequency; - double compoundedInterest = 1.0; - double totalValue = Math.Pow(1.0+coupon, nPeriods); - for(int i = 0; i < nPeriods-1; ++i) + Period freqPeriod = new Period(sinkingFrequency); + int nPeriods = 0; + Utils.QL_REQUIRE(isSubPeriod(freqPeriod, maturityTenor, out nPeriods), () => + "Bond frequency is incompatible with the maturity tenor"); + + List notionals = new InitializedList(nPeriods + 1); + notionals[0] = initialNotional; + double coupon = couponRate / (double)sinkingFrequency; + double compoundedInterest = 1.0; + double totalValue = Math.Pow(1.0 + coupon, nPeriods); + for (int i = 0; i < nPeriods - 1; ++i) + { + compoundedInterest *= (1.0 + coupon); + double currentNotional = 0.0; + if (coupon < 1.0e-12) { - compoundedInterest *= (1.0 + coupon); - double currentNotional = 0.0; - if(coupon < 1.0e-12) { - currentNotional = - initialNotional*(1.0 - (i+1.0)/nPeriods); - } - else { - currentNotional = - initialNotional*(compoundedInterest - (compoundedInterest-1.0)/(1.0 - 1.0/totalValue)); - } - notionals[i+1] = currentNotional; + currentNotional = + initialNotional * (1.0 - (i + 1.0) / nPeriods); } - notionals[notionals.Count-1] = 0.0; - return notionals; - } + else + { + currentNotional = + initialNotional * (compoundedInterest - (compoundedInterest - 1.0) / (1.0 - 1.0 / totalValue)); + } + notionals[i + 1] = currentNotional; + } + notionals[notionals.Count - 1] = 0.0; + return notionals; + } - protected bool isSubPeriod(Period subPeriod,Period superPeriod,out int numSubPeriods) + protected bool isSubPeriod(Period subPeriod, Period superPeriod, out int numSubPeriods) { - numSubPeriods = 0; + numSubPeriods = 0; - KeyValuePair superDays = daysMinMax(superPeriod); - KeyValuePair subDays = daysMinMax(subPeriod); + KeyValuePair superDays = daysMinMax(superPeriod); + KeyValuePair subDays = daysMinMax(subPeriod); - //obtain the approximate time ratio - double minPeriodRatio = - ((double)superDays.Key)/((double)subDays.Value); - double maxPeriodRatio = - ((double)superDays.Value)/((double)subDays.Key); - int lowRatio = (int)(Math.Floor(minPeriodRatio)); - int highRatio = (int)(Math.Ceiling(maxPeriodRatio)); + //obtain the approximate time ratio + double minPeriodRatio = + ((double)superDays.Key) / ((double)subDays.Value); + double maxPeriodRatio = + ((double)superDays.Value) / ((double)subDays.Key); + int lowRatio = (int)(Math.Floor(minPeriodRatio)); + int highRatio = (int)(Math.Ceiling(maxPeriodRatio)); - try - { - for(int i=lowRatio; i <= highRatio; ++i) - { - Period testPeriod = subPeriod * i; - if(testPeriod == superPeriod) - { - numSubPeriods = i; - return true; - } - } - } - catch(Exception) + try + { + for (int i = lowRatio; i <= highRatio; ++i) { - return false; + Period testPeriod = subPeriod * i; + if (testPeriod == superPeriod) + { + numSubPeriods = i; + return true; + } } - + } + catch (Exception) + { return false; - } + } + + return false; + } - KeyValuePair daysMinMax(Period p) + KeyValuePair daysMinMax(Period p) { switch (p.units()) { diff --git a/src/QLNet/Instruments/Bonds/AmortizingFloatingRateBond.cs b/src/QLNet/Instruments/Bonds/AmortizingFloatingRateBond.cs index 5727cb7c3..2183ff3cd 100644 --- a/src/QLNet/Instruments/Bonds/AmortizingFloatingRateBond.cs +++ b/src/QLNet/Instruments/Bonds/AmortizingFloatingRateBond.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -32,41 +32,41 @@ public AmortizingFloatingRateBond(int settlementDays, int fixingDays = 0, List gearings = null, List spreads = null, - List caps = null, - List floors = null, + List < double? > caps = null, + List < double? > floors = null, bool inArrears = false, Date issueDate = null) - :base(settlementDays, schedule.calendar(), issueDate) + : base(settlementDays, schedule.calendar(), issueDate) { - if ( gearings == null ) + if (gearings == null) gearings = new List() {1, 1.0}; if (spreads == null) spreads = new List() { 1, 0.0 }; if (caps == null) - caps = new List() ; + caps = new List < double? >() ; if (floors == null) - floors = new List(); + floors = new List < double? >(); maturityDate_ = schedule.endDate(); cashflows_ = new IborLeg(schedule, index) - .withCaps(caps) - .withFloors(floors) - .inArrears(inArrears) - .withSpreads(spreads) - .withGearings(gearings) - .withFixingDays(fixingDays) - .withPaymentDayCounter(accrualDayCounter) - .withPaymentAdjustment(paymentConvention) - .withNotionals(notionals).value(); + .withCaps(caps) + .withFloors(floors) + .inArrears(inArrears) + .withSpreads(spreads) + .withGearings(gearings) + .withFixingDays(fixingDays) + .withPaymentDayCounter(accrualDayCounter) + .withPaymentAdjustment(paymentConvention) + .withNotionals(notionals).value(); addRedemptionsToCashflows(); - Utils.QL_REQUIRE( !cashflows().empty(), () => "bond with no cashflows!" ); + Utils.QL_REQUIRE(!cashflows().empty(), () => "bond with no cashflows!"); index.registerWith(update); diff --git a/src/QLNet/Instruments/Bonds/BTP.cs b/src/QLNet/Instruments/Bonds/BTP.cs index 8f0826306..89a8ce40a 100644 --- a/src/QLNet/Instruments/Bonds/BTP.cs +++ b/src/QLNet/Instruments/Bonds/BTP.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,30 +24,30 @@ namespace QLNet { /*! Italian CCTEU (Certificato di credito del tesoro) Euribor6M indexed floating rate bond - + \ingroup instruments */ - public class CCTEU : FloatingRateBond + public class CCTEU : FloatingRateBond { - public CCTEU(Date maturityDate,double spread,Handle fwdCurve = null, - Date startDate = null,Date issueDate = null) - :base(2, 100.0, - new Schedule(startDate, - maturityDate, new Period(6,TimeUnit.Months), - new NullCalendar(), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, true), - new Euribor6M(fwdCurve ?? new Handle() ), - new Actual360(), - BusinessDayConvention.Following, - new Euribor6M().fixingDays(), - new List{1.0}, // gearing - new List{spread}, - new List(), // caps - new List(), // floors - false, // in arrears - 100.0, // redemption - issueDate) {} + public CCTEU(Date maturityDate, double spread, Handle fwdCurve = null, + Date startDate = null, Date issueDate = null) + : base(2, 100.0, + new Schedule(startDate, + maturityDate, new Period(6, TimeUnit.Months), + new NullCalendar(), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, true), + new Euribor6M(fwdCurve ?? new Handle()), + new Actual360(), + BusinessDayConvention.Following, + new Euribor6M().fixingDays(), + new List {1.0}, // gearing + new List {spread}, + new List < double? >(), // caps + new List < double? >(), // floors + false, // in arrears + 100.0, // redemption + issueDate) {} #region Bond interface @@ -67,30 +67,30 @@ public override double accruedAmount(Date d = null) /*! \ingroup instruments */ - public class BTP : FixedRateBond + public class BTP : FixedRateBond { - public BTP(Date maturityDate,double fixedRate,Date startDate = null,Date issueDate = null) - :base(2, 100.0,new Schedule(startDate, - maturityDate, new Period(6,TimeUnit.Months), - new NullCalendar(), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, true), - new List{fixedRate}, - new ActualActual(ActualActual.Convention.ISMA), - BusinessDayConvention.ModifiedFollowing, 100.0, issueDate, new TARGET()) { } + public BTP(Date maturityDate, double fixedRate, Date startDate = null, Date issueDate = null) + : base(2, 100.0, new Schedule(startDate, + maturityDate, new Period(6, TimeUnit.Months), + new NullCalendar(), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, true), + new List {fixedRate}, + new ActualActual(ActualActual.Convention.ISMA), + BusinessDayConvention.ModifiedFollowing, 100.0, issueDate, new TARGET()) { } /*! constructor needed for legacy non-par redemption BTPs. As of today the only remaining one is IT123456789012 that will redeem 99.999 on xx-may-2037 */ - public BTP(Date maturityDate, double fixedRate, double redemption,Date startDate = null,Date issueDate = null) - :base(2, 100.0, new Schedule(startDate, - maturityDate, new Period(6,TimeUnit.Months), - new NullCalendar(), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, true), - new List{fixedRate}, - new ActualActual(ActualActual.Convention.ISMA), - BusinessDayConvention.ModifiedFollowing, redemption, issueDate, new TARGET()) { } + public BTP(Date maturityDate, double fixedRate, double redemption, Date startDate = null, Date issueDate = null) + : base(2, 100.0, new Schedule(startDate, + maturityDate, new Period(6, TimeUnit.Months), + new NullCalendar(), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, true), + new List {fixedRate}, + new ActualActual(ActualActual.Convention.ISMA), + BusinessDayConvention.ModifiedFollowing, redemption, issueDate, new TARGET()) { } #region Bond interface - + //! accrued amount at a given date /*! The default bond settlement is used if no date is given. */ public override double accruedAmount(Date d = null) @@ -98,7 +98,7 @@ public override double accruedAmount(Date d = null) double result = base.accruedAmount(d); return new ClosestRounding(5).Round(result); } - + #endregion //! BTP yield given a (clean) price and settlement date @@ -108,11 +108,11 @@ public override double accruedAmount(Date d = null) public double yield(double cleanPrice, Date settlementDate = null, double accuracy = 1.0e-8, int maxEvaluations = 100) { return base.yield(cleanPrice, new ActualActual(ActualActual.Convention.ISMA), - Compounding.Compounded, Frequency.Annual,settlementDate, accuracy, maxEvaluations); + Compounding.Compounded, Frequency.Annual, settlementDate, accuracy, maxEvaluations); } } - public class RendistatoBasket : IObserver,IObservable + public class RendistatoBasket : IObserver, IObservable { public RendistatoBasket(List btps, List outstandings, List> cleanPriceQuotes) @@ -121,46 +121,46 @@ public RendistatoBasket(List btps, List outstandings, List "empty RendistatoCalculator Basket" ); + Utils.QL_REQUIRE(!btps_.empty(), () => "empty RendistatoCalculator Basket"); int k = btps_.Count; - Utils.QL_REQUIRE( outstandings_.Count == k, () => - "mismatch between number of BTPs (" + k + - ") and number of outstandings (" + - outstandings_.Count + ")"); - Utils.QL_REQUIRE( quotes_.Count == k, () => - "mismatch between number of BTPs (" + k + - ") and number of clean prices quotes (" + - quotes_.Count + ")"); + Utils.QL_REQUIRE(outstandings_.Count == k, () => + "mismatch between number of BTPs (" + k + + ") and number of outstandings (" + + outstandings_.Count + ")"); + Utils.QL_REQUIRE(quotes_.Count == k, () => + "mismatch between number of BTPs (" + k + + ") and number of clean prices quotes (" + + quotes_.Count + ")"); // require non-negative outstanding - for (int i=0; i= 0, () => - "negative outstanding for " + i + - " bond, maturity " + btps[i].maturityDate()); + Utils.QL_REQUIRE(outstandings[i] >= 0, () => + "negative outstanding for " + i + + " bond, maturity " + btps[i].maturityDate()); // add check for prices ?? } // TODO: filter out expired bonds, zero outstanding bond, etc - Utils.QL_REQUIRE( !btps_.empty(), () => "invalid bonds only in RendistatoCalculator Basket" ); + Utils.QL_REQUIRE(!btps_.empty(), () => "invalid bonds only in RendistatoCalculator Basket"); n_ = btps_.Count; outstanding_ = 0.0; - for (int i=0; i(n_); - for (int i=0; i btps() {return btps_;} public List> cleanPriceQuotes() { return quotes_;} @@ -174,8 +174,14 @@ public RendistatoBasket(List btps, List outstandings, List btps_; private List outstandings_; private List > quotes_; private double outstanding_; private int n_; private List weights_; - } + } - public class RendistatoCalculator : LazyObject + public class RendistatoCalculator : LazyObject { public RendistatoCalculator(RendistatoBasket basket, Euribor euriborIndex, Handle discountCurve) { basket_ = basket; euriborIndex_ = euriborIndex; discountCurve_ = discountCurve; - yields_ = new InitializedList(basket_.size(), 0.05); + yields_ = new InitializedList(basket_.size(), 0.05); durations_ = new List(basket_.size()); nSwaps_ = 15; // TODO: generalize number of swaps and their lenghts swaps_ = new List(nSwaps_); swapLenghts_ = new List(nSwaps_); - swapBondDurations_ = new InitializedList(nSwaps_, null); - swapBondYields_ = new InitializedList(nSwaps_, 0.05); - swapRates_ = new InitializedList(nSwaps_, null); + swapBondDurations_ = new InitializedList < double? >(nSwaps_, null); + swapBondYields_ = new InitializedList < double? >(nSwaps_, 0.05); + swapRates_ = new InitializedList < double? >(nSwaps_, null); basket_.registerWith(update); euriborIndex_.registerWith(update); discountCurve_.registerWith(update); double dummyRate = 0.05; - for (int i=0; i durations() } // swaps public List swapLengths() { return swapLenghts_; } - public List swapRates() + public List < double? > swapRates() { calculate(); return swapRates_; } - public List swapYields() + public List < double? > swapYields() { calculate(); return swapBondYields_; } - public List swapDurations() + public List < double? > swapDurations() { calculate(); return swapBondDurations_; @@ -272,7 +278,7 @@ public List durations() #endregion #region Equivalent Swap proxy - + public VanillaSwap equivalentSwap() { calculate(); @@ -302,27 +308,27 @@ public double equivalentSwapSpread() { return yield() - equivalentSwapRate(); } - + #endregion #region LazyObject interface - + protected override void performCalculations() { List btps = basket_.btps(); List > quotes = basket_.cleanPriceQuotes(); Date bondSettlementDate = btps[0].settlementDate(); - for (int i=0; i() { swapRates_[0].Value }, - fixedDayCount, - BusinessDayConvention.Following, // paymentConvention - 100.0); // redemption + new List() { swapRates_[0].Value }, + fixedDayCount, + BusinessDayConvention.Following, // paymentConvention + 100.0); // redemption swapBondYields_[0] = BondFunctions.yield(swapBond, 100.0, // floating leg NPV including end payment - new ActualActual(ActualActual.Convention.ISMA), + new ActualActual(ActualActual.Convention.ISMA), Compounding.Compounded, Frequency.Annual, bondSettlementDate, // accuracy, maxIterations, guess 1.0e-10, 100, swapBondYields_[0].Value); swapBondDurations_[0] = BondFunctions.duration(swapBond, swapBondYields_[0].Value, - new ActualActual(ActualActual.Convention.ISMA), + new ActualActual(ActualActual.Convention.ISMA), Compounding.Compounded, Frequency.Annual, Duration.Type.Modified, bondSettlementDate); - for (int i=1; i(){swapRates_[i].Value}, - fixedDayCount, - BusinessDayConvention.Following, // paymentConvention - 100.0); // redemption + 100.0, // faceAmount + swaps_[i].fixedSchedule(), + new List() {swapRates_[i].Value}, + fixedDayCount, + BusinessDayConvention.Following, // paymentConvention + 100.0); // redemption swapBondYields_[i] = BondFunctions.yield(swapBond2, 100.0, // floating leg NPV including end payment - new ActualActual(ActualActual.Convention.ISMA), + new ActualActual(ActualActual.Convention.ISMA), Compounding.Compounded, Frequency.Annual, bondSettlementDate, // accuracy, maxIterations, guess 1.0e-10, 100, swapBondYields_[i].Value); - + swapBondDurations_[i] = BondFunctions.duration(swapBond2, swapBondYields_[i].Value, - new ActualActual(ActualActual.Convention.ISMA), + new ActualActual(ActualActual.Convention.ISMA), Compounding.Compounded, Frequency.Annual, Duration.Type.Modified, bondSettlementDate); - if (swapBondDurations_[i] > duration_) + if (swapBondDurations_[i] > duration_) { - equivalentSwapIndex_ = i-1; - break; // exit the loop + equivalentSwapIndex_ = i - 1; + break; // exit the loop } - } + } - return; + return; } - + #endregion private RendistatoBasket basket_; @@ -398,33 +404,33 @@ protected override void performCalculations() private int nSwaps_; private List swaps_; private List swapLenghts_; - private List swapBondDurations_; - private List swapBondYields_, swapRates_; - } + private List < double? > swapBondDurations_; + private List < double? > swapBondYields_, swapRates_; + } //! RendistatoCalculator equivalent swap lenth Quote adapter - public class RendistatoEquivalentSwapLengthQuote : Quote + public class RendistatoEquivalentSwapLengthQuote : Quote { public RendistatoEquivalentSwapLengthQuote(RendistatoCalculator r) { r_ = r; } public override double value() { return r_.equivalentSwapLength(); } public override bool isValid() { - try + try { value(); return true; - } - catch (Exception) + } + catch (Exception) { return false; } } - + private RendistatoCalculator r_; } //! RendistatoCalculator equivalent swap spread Quote adapter - public class RendistatoEquivalentSwapSpreadQuote : Quote + public class RendistatoEquivalentSwapSpreadQuote : Quote { public RendistatoEquivalentSwapSpreadQuote(RendistatoCalculator r) { r_ = r; } public override double value() { return r_.equivalentSwapSpread(); } diff --git a/src/QLNet/Instruments/Bonds/BondFactory.cs b/src/QLNet/Instruments/Bonds/BondFactory.cs index 787bc0c8c..b881b131c 100644 --- a/src/QLNet/Instruments/Bonds/BondFactory.cs +++ b/src/QLNet/Instruments/Bonds/BondFactory.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -30,7 +30,7 @@ public static AmortizingBond makeAmortizingBond(double FaceValue, Frequency payFrequency, DayCounter dCounter, AmortizingMethod Method, - double gYield=0) + double gYield = 0) { return new AmortizingBond(FaceValue, MarketValue, @@ -41,34 +41,34 @@ public static AmortizingBond makeAmortizingBond(double FaceValue, payFrequency, dCounter, Method, - new NullCalendar(),gYield); + new NullCalendar(), gYield); + } + + + public static AmortizingFixedRateBond makeAmortizingFixedBond(Date startDate, + Period bondLength, + DayCounter dCounter, + Frequency payFrequency, + double amount, + double rate) + { + return makeAmortizingFixedBond(startDate, bondLength, dCounter, payFrequency, amount, rate, new TARGET()); } - public static AmortizingFixedRateBond makeAmortizingFixedBond( Date startDate, - Period bondLength, - DayCounter dCounter, - Frequency payFrequency, - double amount, - double rate) - { - return makeAmortizingFixedBond(startDate, bondLength, dCounter, payFrequency, amount, rate, new TARGET()); - } - - - public static AmortizingFixedRateBond makeAmortizingFixedBond( Date startDate, - Period bondLength, - DayCounter dCounter, - Frequency payFrequency, - double amount, - double rate, - Calendar calendar) + public static AmortizingFixedRateBond makeAmortizingFixedBond(Date startDate, + Period bondLength, + DayCounter dCounter, + Frequency payFrequency, + double amount, + double rate, + Calendar calendar) { AmortizingFixedRateBond bond; - Date endDate = calendar.advance(startDate,bondLength); + Date endDate = calendar.advance(startDate, bondLength); - Schedule schedule = new Schedule(startDate,endDate,bondLength,calendar,BusinessDayConvention.Unadjusted, - BusinessDayConvention.Unadjusted,DateGeneration.Rule.Backward,false); + Schedule schedule = new Schedule(startDate, endDate, bondLength, calendar, BusinessDayConvention.Unadjusted, + BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); bond = new AmortizingFixedRateBond(0, calendar, amount, startDate, bondLength, payFrequency, rate, dCounter); @@ -77,16 +77,16 @@ public static AmortizingFixedRateBond makeAmortizingFixedBond( Date startDate, } public static MBSFixedRateBond makeMBSFixedBond(Date startDate, - Period bondLength, - Period originalLength, - DayCounter dCounter, - Frequency payFrequency, - double amount, - double WACRate, - double PassThroughRate, - PSACurve psaCurve) + Period bondLength, + Period originalLength, + DayCounter dCounter, + Frequency payFrequency, + double amount, + double WACRate, + double PassThroughRate, + PSACurve psaCurve) { - return makeMBSFixedBond(startDate, bondLength, originalLength , dCounter, payFrequency, amount, WACRate, PassThroughRate, psaCurve, new TARGET()); + return makeMBSFixedBond(startDate, bondLength, originalLength, dCounter, payFrequency, amount, WACRate, PassThroughRate, psaCurve, new TARGET()); } @@ -107,7 +107,7 @@ public static MBSFixedRateBond makeMBSFixedBond(Date startDate, Schedule schedule = new Schedule(startDate, endDate, bondLength, calendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); - bond = new MBSFixedRateBond(0, calendar, amount, startDate, bondLength, originalLength , payFrequency, WACrate, PassThroughRate, dCounter, psaCurve); + bond = new MBSFixedRateBond(0, calendar, amount, startDate, bondLength, originalLength, payFrequency, WACrate, PassThroughRate, dCounter, psaCurve); return bond; diff --git a/src/QLNet/Instruments/Bonds/CPIBond.cs b/src/QLNet/Instruments/Bonds/CPIBond.cs index 1ec72e75d..ce8d723e0 100644 --- a/src/QLNet/Instruments/Bonds/CPIBond.cs +++ b/src/QLNet/Instruments/Bonds/CPIBond.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008, 2009 , 2010, 2011 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008, 2009 , 2010, 2011 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,80 +20,80 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! cpi bond; if there is only one date in the schedule it - //! is a zero bond returning an inflated notional. - /*! \ingroup instruments + //! cpi bond; if there is only one date in the schedule it + //! is a zero bond returning an inflated notional. + /*! \ingroup instruments + + */ + public class CPIBond : Bond + { + public CPIBond(int settlementDays, + double faceAmount, + bool growthOnly, + double baseCPI, + Period observationLag, + ZeroInflationIndex cpiIndex, + InterpolationType observationInterpolation, + Schedule schedule, + List fixedRate, + DayCounter accrualDayCounter, + BusinessDayConvention paymentConvention = BusinessDayConvention.ModifiedFollowing, + Date issueDate = null, + Calendar paymentCalendar = null, + Period exCouponPeriod = null, + Calendar exCouponCalendar = null, + BusinessDayConvention exCouponConvention = BusinessDayConvention.Unadjusted, + bool exCouponEndOfMonth = false) + : base(settlementDays, paymentCalendar ?? schedule.calendar(), issueDate) + { + frequency_ = schedule.tenor().frequency(); + dayCounter_ = accrualDayCounter; + growthOnly_ = growthOnly; + baseCPI_ = baseCPI; + observationLag_ = observationLag; + cpiIndex_ = cpiIndex; + observationInterpolation_ = observationInterpolation; - */ - public class CPIBond : Bond - { - public CPIBond(int settlementDays, - double faceAmount, - bool growthOnly, - double baseCPI, - Period observationLag, - ZeroInflationIndex cpiIndex, - InterpolationType observationInterpolation, - Schedule schedule, - List fixedRate, - DayCounter accrualDayCounter, - BusinessDayConvention paymentConvention = BusinessDayConvention.ModifiedFollowing, - Date issueDate = null, - Calendar paymentCalendar = null, - Period exCouponPeriod = null, - Calendar exCouponCalendar = null, - BusinessDayConvention exCouponConvention = BusinessDayConvention.Unadjusted, - bool exCouponEndOfMonth = false) - :base(settlementDays, paymentCalendar ?? schedule.calendar(), issueDate) - { - frequency_ = schedule.tenor().frequency(); - dayCounter_ = accrualDayCounter; - growthOnly_ = growthOnly; - baseCPI_=baseCPI; - observationLag_ = observationLag; - cpiIndex_= cpiIndex; - observationInterpolation_ = observationInterpolation; + maturityDate_ = schedule.endDate(); - maturityDate_ = schedule.endDate(); + // a CPIleg know about zero legs and inclusion of base inflation notional + cashflows_ = new CPILeg(schedule, cpiIndex_, + baseCPI_, observationLag_) + .withSubtractInflationNominal(growthOnly_) + .withObservationInterpolation(observationInterpolation_) + .withPaymentDayCounter(accrualDayCounter) + .withFixedRates(fixedRate) + .withPaymentCalendar(calendar_) + .withExCouponPeriod(exCouponPeriod, + exCouponCalendar, + exCouponConvention, + exCouponEndOfMonth) + .withNotionals(faceAmount) + .withPaymentAdjustment(paymentConvention); - // a CPIleg know about zero legs and inclusion of base inflation notional - cashflows_ = new CPILeg(schedule, cpiIndex_, - baseCPI_, observationLag_) - .withSubtractInflationNominal(growthOnly_) - .withObservationInterpolation(observationInterpolation_) - .withPaymentDayCounter(accrualDayCounter) - .withFixedRates(fixedRate) - .withPaymentCalendar(calendar_) - .withExCouponPeriod(exCouponPeriod, - exCouponCalendar, - exCouponConvention, - exCouponEndOfMonth) - .withNotionals(faceAmount) - .withPaymentAdjustment(paymentConvention); - - calculateNotionalsFromCashflows(); + calculateNotionalsFromCashflows(); - cpiIndex_.registerWith(update); + cpiIndex_.registerWith(update); - foreach ( CashFlow i in cashflows_) - i.registerWith(update); - } + foreach (CashFlow i in cashflows_) + i.registerWith(update); + } - public Frequency frequency() { return frequency_; } - public DayCounter dayCounter() { return dayCounter_; } - public bool growthOnly() { return growthOnly_; } - public double baseCPI() { return baseCPI_; } - public Period observationLag() { return observationLag_; } - public ZeroInflationIndex cpiIndex() { return cpiIndex_; } - public InterpolationType observationInterpolation() { return observationInterpolation_; } + public Frequency frequency() { return frequency_; } + public DayCounter dayCounter() { return dayCounter_; } + public bool growthOnly() { return growthOnly_; } + public double baseCPI() { return baseCPI_; } + public Period observationLag() { return observationLag_; } + public ZeroInflationIndex cpiIndex() { return cpiIndex_; } + public InterpolationType observationInterpolation() { return observationInterpolation_; } - protected Frequency frequency_; - protected DayCounter dayCounter_; - protected bool growthOnly_; - protected double baseCPI_; - protected Period observationLag_; - protected ZeroInflationIndex cpiIndex_; - protected InterpolationType observationInterpolation_; - } + protected Frequency frequency_; + protected DayCounter dayCounter_; + protected bool growthOnly_; + protected double baseCPI_; + protected Period observationLag_; + protected ZeroInflationIndex cpiIndex_; + protected InterpolationType observationInterpolation_; + } } diff --git a/src/QLNet/Instruments/Bonds/CallableBond.cs b/src/QLNet/Instruments/Bonds/CallableBond.cs index 291c19fa3..4c0b4c073 100644 --- a/src/QLNet/Instruments/Bonds/CallableBond.cs +++ b/src/QLNet/Instruments/Bonds/CallableBond.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -36,7 +36,7 @@ namespace QLNet */ public class CallableBond : Bond { - public new class Arguments : Bond.Arguments + public new class Arguments : Bond.Arguments { public List couponDates { get; set; } public List couponAmounts { get; set; } @@ -50,23 +50,23 @@ public class CallableBond : Bond public List callabilityDates { get; set; } public override void validate() { - Utils.QL_REQUIRE( settlementDate != null, () => "null settlement date" ); - Utils.QL_REQUIRE( redemption >= 0.0, () => "positive redemption required: " + redemption + " not allowed" ); - Utils.QL_REQUIRE( callabilityDates.Count == callabilityPrices.Count, () => "different number of callability dates and prices" ); - Utils.QL_REQUIRE( couponDates.Count == couponAmounts.Count, () => "different number of coupon dates and amounts" ); + Utils.QL_REQUIRE(settlementDate != null, () => "null settlement date"); + Utils.QL_REQUIRE(redemption >= 0.0, () => "positive redemption required: " + redemption + " not allowed"); + Utils.QL_REQUIRE(callabilityDates.Count == callabilityPrices.Count, () => "different number of callability dates and prices"); + Utils.QL_REQUIRE(couponDates.Count == couponAmounts.Count, () => "different number of coupon dates and amounts"); } - } + } //! results for a callable bond calculation - public new class Results : Bond.Results + public new class Results : Bond.Results { // no extra results set yet } //! base class for callable fixed rate bond engine - public new class Engine : GenericEngine {}; + public new class Engine : GenericEngine {} // Inspectors //! return the bond's put/call schedule - public CallabilitySchedule callability() + public CallabilitySchedule callability() { return putCallSchedule_; } @@ -76,46 +76,46 @@ public CallabilitySchedule callability() Chapter 20, pg 536). Relevant only to European put/call schedules */ - public double impliedVolatility( double targetValue, - Handle discountCurve, - double accuracy, - int maxEvaluations, - double minVol, - double maxVol) + public double impliedVolatility(double targetValue, + Handle discountCurve, + double accuracy, + int maxEvaluations, + double minVol, + double maxVol) { calculate(); - Utils.QL_REQUIRE( !isExpired(), () => "instrument expired" ); - double guess = 0.5*(minVol + maxVol); + Utils.QL_REQUIRE(!isExpired(), () => "instrument expired"); + double guess = 0.5 * (minVol + maxVol); blackDiscountCurve_.linkTo(discountCurve, false); - ImpliedVolHelper f = new ImpliedVolHelper(this,targetValue); + ImpliedVolHelper f = new ImpliedVolHelper(this, targetValue); Brent solver = new Brent(); solver.setMaxEvaluations(maxEvaluations); return solver.solve(f, accuracy, guess, minVol, maxVol); } - protected CallableBond( int settlementDays, - Schedule schedule, - DayCounter paymentDayCounter, - Date issueDate = null, - CallabilitySchedule putCallSchedule = null) + protected CallableBond(int settlementDays, + Schedule schedule, + DayCounter paymentDayCounter, + Date issueDate = null, + CallabilitySchedule putCallSchedule = null) : base(settlementDays, schedule.calendar(), issueDate) { paymentDayCounter_ = paymentDayCounter; - putCallSchedule_ = putCallSchedule ?? new CallabilitySchedule(); + putCallSchedule_ = putCallSchedule ?? new CallabilitySchedule(); maturityDate_ = schedule.dates().Last(); - if (!putCallSchedule_.empty()) - { + if (!putCallSchedule_.empty()) + { Date finalOptionDate = Date.minDate(); - for (int i=0; i "Bond cannot mature before last call/put date" ); - } + Utils.QL_REQUIRE(finalOptionDate <= maturityDate_, () => "Bond cannot mature before last call/put date"); + } - // derived classes must set cashflows_ and frequency_ + // derived classes must set cashflows_ and frequency_ } protected DayCounter paymentDayCounter_; @@ -136,11 +136,11 @@ public ImpliedVolHelper(CallableBond bond, double targetValue) vol_ = new SimpleQuote(0.0); bond.blackVolQuote_.linkTo(vol_); - Utils.QL_REQUIRE( bond.blackEngine_ != null, () => "Must set blackEngine_ to use impliedVolatility" ); + Utils.QL_REQUIRE(bond.blackEngine_ != null, () => "Must set blackEngine_ to use impliedVolatility"); - engine_ = bond.blackEngine_; - bond.setupArguments(engine_.getArguments()); - results_ = engine_.getResults() as Instrument.Results; + engine_ = bond.blackEngine_; + bond.setupArguments(engine_.getArguments()); + results_ = engine_.getResults() as Instrument.Results; } public override double value(double x) { @@ -166,40 +166,40 @@ public override double value(double x) */ public class CallableFixedRateBond : CallableBond { - public CallableFixedRateBond( int settlementDays, - double faceAmount, - Schedule schedule, - List coupons, - DayCounter accrualDayCounter, - BusinessDayConvention paymentConvention = BusinessDayConvention.Following, - double redemption = 100.0, - Date issueDate = null, - CallabilitySchedule putCallSchedule = null) - :base(settlementDays, schedule, accrualDayCounter, issueDate, putCallSchedule) + public CallableFixedRateBond(int settlementDays, + double faceAmount, + Schedule schedule, + List coupons, + DayCounter accrualDayCounter, + BusinessDayConvention paymentConvention = BusinessDayConvention.Following, + double redemption = 100.0, + Date issueDate = null, + CallabilitySchedule putCallSchedule = null) + : base(settlementDays, schedule, accrualDayCounter, issueDate, putCallSchedule) { frequency_ = schedule.tenor().frequency(); bool isZeroCouponBond = (coupons.Count == 1 && Utils.close(coupons[0], 0.0)); - if (!isZeroCouponBond) - { + if (!isZeroCouponBond) + { cashflows_ = new FixedRateLeg(schedule) - .withCouponRates(coupons, accrualDayCounter) - .withNotionals(faceAmount) - .withPaymentAdjustment(paymentConvention); - - addRedemptionsToCashflows(new List(){redemption}); - } - else - { + .withCouponRates(coupons, accrualDayCounter) + .withNotionals(faceAmount) + .withPaymentAdjustment(paymentConvention); + + addRedemptionsToCashflows(new List() {redemption}); + } + else + { Date redemptionDate = calendar_.adjust(maturityDate_, paymentConvention); setSingleRedemption(faceAmount, redemption, redemptionDate); - } + } - // used for impliedVolatility() calculation - SimpleQuote dummyVolQuote = new SimpleQuote(0.0); - blackVolQuote_.linkTo(dummyVolQuote); - blackEngine_ = new BlackCallableFixedRateBondEngine(blackVolQuote_, blackDiscountCurve_); + // used for impliedVolatility() calculation + SimpleQuote dummyVolQuote = new SimpleQuote(0.0); + blackVolQuote_.linkTo(dummyVolQuote); + blackEngine_ = new BlackCallableFixedRateBondEngine(blackVolQuote_, blackDiscountCurve_); } public override void setupArguments(IPricingEngineArguments args) @@ -207,7 +207,7 @@ public override void setupArguments(IPricingEngineArguments args) base.setupArguments(args); CallableBond.Arguments arguments = args as CallableBond.Arguments; - Utils.QL_REQUIRE( arguments != null, () => "no arguments given" ); + Utils.QL_REQUIRE(arguments != null, () => "no arguments given"); Date settlement = arguments.settlementDate; @@ -265,19 +265,20 @@ coupon dates. */ private double accrued(Date settlement) { - if (settlement == null) settlement = settlementDate(); + if (settlement == null) + settlement = settlementDate(); bool IncludeToday = false; - for (int i = 0; i(){0.0}, dayCounter, paymentConvention, redemption, issueDate, putCallSchedule) + : base(settlementDays, faceAmount, new Schedule(issueDate, maturityDate, + new Period(Frequency.Once), + calendar, + paymentConvention, + paymentConvention, + DateGeneration.Rule.Backward, + false), + new List() {0.0}, dayCounter, paymentConvention, redemption, issueDate, putCallSchedule) {} } } diff --git a/src/QLNet/Instruments/Bonds/CmsRateBond.cs b/src/QLNet/Instruments/Bonds/CmsRateBond.cs index dd2083399..4e2514955 100644 --- a/src/QLNet/Instruments/Bonds/CmsRateBond.cs +++ b/src/QLNet/Instruments/Bonds/CmsRateBond.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008, 2009 , 2010, 2011 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008, 2009 , 2010, 2011 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,47 +20,51 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class CmsRateBond : Bond - { - public CmsRateBond(int settlementDays, - double faceAmount, - Schedule schedule, - SwapIndex index, - DayCounter paymentDayCounter, - BusinessDayConvention paymentConvention = BusinessDayConvention.Following, - int fixingDays = 0, - List gearings = null, - List spreads = null, - List caps = null, - List floors = null, - bool inArrears = false, - double redemption = 100.0, - Date issueDate = null) - : base(settlementDays, schedule.calendar(), issueDate) - { - // Optional value check - if ( gearings == null ) gearings = new List(){1}; - if ( spreads == null ) spreads = new List(){0}; - if (caps == null) caps = new List(); - if (floors == null) floors = new List(); + public class CmsRateBond : Bond + { + public CmsRateBond(int settlementDays, + double faceAmount, + Schedule schedule, + SwapIndex index, + DayCounter paymentDayCounter, + BusinessDayConvention paymentConvention = BusinessDayConvention.Following, + int fixingDays = 0, + List gearings = null, + List spreads = null, + List < double? > caps = null, + List < double? > floors = null, + bool inArrears = false, + double redemption = 100.0, + Date issueDate = null) + : base(settlementDays, schedule.calendar(), issueDate) + { + // Optional value check + if (gearings == null) + gearings = new List() {1}; + if (spreads == null) + spreads = new List() {0}; + if (caps == null) + caps = new List < double? >(); + if (floors == null) + floors = new List < double? >(); + + maturityDate_ = schedule.endDate(); + cashflows_ = new CmsLeg(schedule, index) + .withPaymentDayCounter(paymentDayCounter) + .withFixingDays(fixingDays) + .withGearings(gearings) + .withSpreads(spreads) + .withCaps(caps) + .withFloors(floors) + .inArrears(inArrears) + .withNotionals(faceAmount) + .withPaymentAdjustment(paymentConvention); - maturityDate_ = schedule.endDate(); - cashflows_ = new CmsLeg(schedule, index) - .withPaymentDayCounter(paymentDayCounter) - .withFixingDays(fixingDays) - .withGearings(gearings) - .withSpreads(spreads) - .withCaps(caps) - .withFloors(floors) - .inArrears(inArrears) - .withNotionals(faceAmount) - .withPaymentAdjustment(paymentConvention); - - addRedemptionsToCashflows(new List() { redemption }); + addRedemptionsToCashflows(new List() { redemption }); - Utils.QL_REQUIRE(cashflows().Count != 0, ()=> "bond with no cashflows!"); - Utils.QL_REQUIRE(redemptions_.Count == 1,()=> "multiple redemptions created"); - index.registerWith(update); - } - } + Utils.QL_REQUIRE(cashflows().Count != 0, () => "bond with no cashflows!"); + Utils.QL_REQUIRE(redemptions_.Count == 1, () => "multiple redemptions created"); + index.registerWith(update); + } + } } \ No newline at end of file diff --git a/src/QLNet/Instruments/Bonds/ConstantCPR.cs b/src/QLNet/Instruments/Bonds/ConstantCPR.cs index ad2e2708c..9d35a1ef1 100644 --- a/src/QLNet/Instruments/Bonds/ConstantCPR.cs +++ b/src/QLNet/Instruments/Bonds/ConstantCPR.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Instruments/Bonds/ConvertibleBond.cs b/src/QLNet/Instruments/Bonds/ConvertibleBond.cs index 9a7e474f0..05829484d 100644 --- a/src/QLNet/Instruments/Bonds/ConvertibleBond.cs +++ b/src/QLNet/Instruments/Bonds/ConvertibleBond.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -60,7 +60,7 @@ public arguments() public List callabilityDates { get; set; } public List callabilityTypes { get; set; } public List callabilityPrices { get; set; } - public List callabilityTriggers { get; set; } + public List < double? > callabilityTriggers { get; set; } public List couponDates { get; set; } public List couponAmounts { get; set; } public Date issueDate { get; set; } @@ -74,8 +74,8 @@ public override void validate() base.validate(); Utils.QL_REQUIRE(conversionRatio != null, () => "null conversion ratio"); - Utils.QL_REQUIRE(conversionRatio > 0.0, - () => "positive conversion ratio required: " + conversionRatio + " not allowed"); + Utils.QL_REQUIRE(conversionRatio > 0.0, + () => "positive conversion ratio required: " + conversionRatio + " not allowed"); Utils.QL_REQUIRE(redemption != null, () => "null redemption"); Utils.QL_REQUIRE(redemption >= 0.0, () => "positive redemption required: " + redemption + " not allowed"); @@ -85,31 +85,31 @@ public override void validate() Utils.QL_REQUIRE(settlementDays != null, () => "null settlement days"); Utils.QL_REQUIRE(callabilityDates.Count == callabilityTypes.Count, - () => "different number of callability dates and types"); + () => "different number of callability dates and types"); Utils.QL_REQUIRE(callabilityDates.Count == callabilityPrices.Count, - () => "different number of callability dates and prices"); + () => "different number of callability dates and prices"); Utils.QL_REQUIRE(callabilityDates.Count == callabilityTriggers.Count, - () => "different number of callability dates and triggers"); + () => "different number of callability dates and triggers"); - Utils.QL_REQUIRE(couponDates.Count == couponAmounts.Count, - () => "different number of coupon dates and amounts"); + Utils.QL_REQUIRE(couponDates.Count == couponAmounts.Count, + () => "different number of coupon dates and amounts"); } } public option(ConvertibleBond bond, - Exercise exercise, - double conversionRatio, - DividendSchedule dividends, - CallabilitySchedule callability, - Handle creditSpread, - List cashflows, - DayCounter dayCounter, - Schedule schedule, - Date issueDate, - int settlementDays, - double redemption) - : base( new PlainVanillaPayoff(Option.Type.Call, (bond.notionals()[0]) / 100.0 * redemption / conversionRatio), - exercise) + Exercise exercise, + double conversionRatio, + DividendSchedule dividends, + CallabilitySchedule callability, + Handle creditSpread, + List cashflows, + DayCounter dayCounter, + Schedule schedule, + Date issueDate, + int settlementDays, + double redemption) + : base(new PlainVanillaPayoff(Option.Type.Call, (bond.notionals()[0]) / 100.0 * redemption / conversionRatio), + exercise) { bond_ = bond; conversionRatio_ = conversionRatio; @@ -146,13 +146,13 @@ public override void setupArguments(IPricingEngineArguments args) else moreArgs.callabilityTypes.Clear(); - if (moreArgs.callabilityPrices == null ) + if (moreArgs.callabilityPrices == null) moreArgs.callabilityPrices = new List(); else moreArgs.callabilityPrices.Clear(); - if (moreArgs.callabilityTriggers == null ) - moreArgs.callabilityTriggers = new List(); + if (moreArgs.callabilityTriggers == null) + moreArgs.callabilityTriggers = new List < double? >(); else moreArgs.callabilityTriggers.Clear(); @@ -258,14 +258,14 @@ public Handle creditSpread() } protected ConvertibleBond(Exercise exercise, - double conversionRatio, - DividendSchedule dividends, - CallabilitySchedule callability, - Handle creditSpread, - Date issueDate, - int settlementDays, - Schedule schedule, - double redemption) + double conversionRatio, + DividendSchedule dividends, + CallabilitySchedule callability, + Handle creditSpread, + Date issueDate, + int settlementDays, + Schedule schedule, + double redemption) : base(settlementDays, schedule.calendar(), issueDate) { conversionRatio_ = conversionRatio; @@ -278,10 +278,10 @@ protected ConvertibleBond(Exercise exercise, if (!callability.empty()) { Utils.QL_REQUIRE(callability.Last().date() <= maturityDate_, () => - "last callability date (" - + callability.Last().date() - + ") later than maturity (" - + maturityDate_.ToShortDateString() + ")"); + "last callability date (" + + callability.Last().date() + + ") later than maturity (" + + maturityDate_.ToShortDateString() + ")"); } creditSpread.registerWith(update); @@ -311,18 +311,18 @@ convertibility and callability into account. public class ConvertibleZeroCouponBond : ConvertibleBond { public ConvertibleZeroCouponBond(Exercise exercise, - double conversionRatio, - DividendSchedule dividends, - CallabilitySchedule callability, - Handle creditSpread, - Date issueDate, - int settlementDays, - DayCounter dayCounter, - Schedule schedule, - double redemption = 100) + double conversionRatio, + DividendSchedule dividends, + CallabilitySchedule callability, + Handle creditSpread, + Date issueDate, + int settlementDays, + DayCounter dayCounter, + Schedule schedule, + double redemption = 100) : base( - exercise, conversionRatio, dividends, callability, creditSpread, issueDate, settlementDays, schedule, - redemption) + exercise, conversionRatio, dividends, callability, creditSpread, issueDate, settlementDays, schedule, + redemption) { cashflows_ = new List(); @@ -330,10 +330,10 @@ public ConvertibleZeroCouponBond(Exercise exercise, setSingleRedemption(100.0, redemption, maturityDate_); option_ = new option(this, exercise, conversionRatio, dividends, callability, creditSpread, cashflows_, - dayCounter, schedule, - issueDate, settlementDays, redemption); + dayCounter, schedule, + issueDate, settlementDays, redemption); } - }; + } //! convertible fixed-coupon bond /*! \warning Most methods inherited from Bond (such as yield or @@ -345,35 +345,35 @@ convertibility and callability into account. public class ConvertibleFixedCouponBond : ConvertibleBond { public ConvertibleFixedCouponBond(Exercise exercise, - double conversionRatio, - DividendSchedule dividends, - CallabilitySchedule callability, - Handle creditSpread, - Date issueDate, - int settlementDays, - List coupons, - DayCounter dayCounter, - Schedule schedule, - double redemption = 100) + double conversionRatio, + DividendSchedule dividends, + CallabilitySchedule callability, + Handle creditSpread, + Date issueDate, + int settlementDays, + List coupons, + DayCounter dayCounter, + Schedule schedule, + double redemption = 100) : base( - exercise, conversionRatio, dividends, callability, creditSpread, issueDate, settlementDays, schedule, - redemption) + exercise, conversionRatio, dividends, callability, creditSpread, issueDate, settlementDays, schedule, + redemption) { // !!! notional forcibly set to 100 cashflows_ = new FixedRateLeg(schedule) - .withCouponRates(coupons, dayCounter) - .withNotionals(100.0) - .withPaymentAdjustment(schedule.businessDayConvention()); + .withCouponRates(coupons, dayCounter) + .withNotionals(100.0) + .withPaymentAdjustment(schedule.businessDayConvention()); addRedemptionsToCashflows(new List() {redemption}); Utils.QL_REQUIRE(redemptions_.Count == 1, () => "multiple redemptions created"); option_ = new option(this, exercise, conversionRatio, dividends, callability, creditSpread, cashflows_, - dayCounter, schedule, - issueDate, settlementDays, redemption); + dayCounter, schedule, + issueDate, settlementDays, redemption); } - }; + } //! convertible floating-rate bond /*! \warning Most methods inherited from Bond (such as yield or @@ -385,38 +385,38 @@ convertibility and callability into account. public class ConvertibleFloatingRateBond : ConvertibleBond { public ConvertibleFloatingRateBond(Exercise exercise, - double conversionRatio, - DividendSchedule dividends, - CallabilitySchedule callability, - Handle creditSpread, - Date issueDate, - int settlementDays, - IborIndex index, - int fixingDays, - List spreads, - DayCounter dayCounter, - Schedule schedule, - double redemption = 100) + double conversionRatio, + DividendSchedule dividends, + CallabilitySchedule callability, + Handle creditSpread, + Date issueDate, + int settlementDays, + IborIndex index, + int fixingDays, + List spreads, + DayCounter dayCounter, + Schedule schedule, + double redemption = 100) : base( - exercise, conversionRatio, dividends, callability, creditSpread, issueDate, settlementDays, schedule, - redemption) + exercise, conversionRatio, dividends, callability, creditSpread, issueDate, settlementDays, schedule, + redemption) { // !!! notional forcibly set to 100 cashflows_ = new IborLeg(schedule, index) - .withPaymentDayCounter(dayCounter) - .withFixingDays(fixingDays) - .withSpreads(spreads) - .withNotionals(100.0) - .withPaymentAdjustment(schedule.businessDayConvention()); + .withPaymentDayCounter(dayCounter) + .withFixingDays(fixingDays) + .withSpreads(spreads) + .withNotionals(100.0) + .withPaymentAdjustment(schedule.businessDayConvention()); addRedemptionsToCashflows(new List {redemption}); Utils.QL_REQUIRE(redemptions_.Count == 1, () => "multiple redemptions created"); option_ = new option(this, exercise, conversionRatio, dividends, callability, creditSpread, cashflows_, - dayCounter, schedule, - issueDate, settlementDays, redemption); + dayCounter, schedule, + issueDate, settlementDays, redemption); } } } diff --git a/src/QLNet/Instruments/Bonds/DiscretizedCallableFixedRateBond.cs b/src/QLNet/Instruments/Bonds/DiscretizedCallableFixedRateBond.cs index ac5710a93..a8aa755c5 100644 --- a/src/QLNet/Instruments/Bonds/DiscretizedCallableFixedRateBond.cs +++ b/src/QLNet/Instruments/Bonds/DiscretizedCallableFixedRateBond.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,12 +21,12 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - + public class DiscretizedCallableFixedRateBond : DiscretizedAsset { public DiscretizedCallableFixedRateBond(CallableBond.Arguments args, - Date referenceDate, - DayCounter dayCounter) + Date referenceDate, + DayCounter dayCounter) { arguments_ = args; redemptionTime_ = dayCounter.yearFraction(referenceDate, args.redemptionDate); @@ -35,7 +35,7 @@ public DiscretizedCallableFixedRateBond(CallableBond.Arguments args, couponTimes_.Add(dayCounter.yearFraction(referenceDate, args.couponDates[i])); for (int i = 0; i < args.callabilityDates.Count ; ++i) - callabilityTimes_.Add( dayCounter.yearFraction(referenceDate, args.callabilityDates[i])); + callabilityTimes_.Add(dayCounter.yearFraction(referenceDate, args.callabilityDates[i])); // similar to the tree swaption engine, we collapse similar coupon // and exercise dates to avoid mispricing. Delete if unnecessary. @@ -121,17 +121,17 @@ protected override void postAdjustValuesImpl() private void applyCallability(int i) { int j; - switch (arguments_.putCallSchedule[i].type() ) + switch (arguments_.putCallSchedule[i].type()) { case Callability.Type.Call: - for (j=0; j. - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,9 +20,9 @@ under the terms of the QLNet license. You should have received a using System; using System.Collections.Generic; -namespace QLNet +namespace QLNet { - public class FixedRateBond : Bond + public class FixedRateBond : Bond { //! fixed-rate bond /*! \ingroup instruments @@ -30,42 +30,42 @@ public class FixedRateBond : Bond \test calculations are tested by checking results against cached values. */ - - //! simple annual compounding coupon rates - public FixedRateBond(int settlementDays, double faceAmount, Schedule schedule,List coupons, + + //! simple annual compounding coupon rates + public FixedRateBond(int settlementDays, double faceAmount, Schedule schedule, List coupons, DayCounter accrualDayCounter, BusinessDayConvention paymentConvention = BusinessDayConvention.Following, - double redemption = 100, Date issueDate = null,Calendar paymentCalendar = null, - Period exCouponPeriod = null, + double redemption = 100, Date issueDate = null, Calendar paymentCalendar = null, + Period exCouponPeriod = null, Calendar exCouponCalendar = null, - BusinessDayConvention exCouponConvention = BusinessDayConvention.Unadjusted, + BusinessDayConvention exCouponConvention = BusinessDayConvention.Unadjusted, bool exCouponEndOfMonth = false) - : base(settlementDays, paymentCalendar ?? schedule.calendar(), - issueDate) + : base(settlementDays, paymentCalendar ?? schedule.calendar(), + issueDate) { frequency_ = schedule.tenor().frequency(); dayCounter_ = accrualDayCounter; maturityDate_ = schedule.endDate(); cashflows_ = new FixedRateLeg(schedule) - .withCouponRates(coupons, accrualDayCounter) - .withExCouponPeriod(exCouponPeriod, - exCouponCalendar, - exCouponConvention, - exCouponEndOfMonth) - .withPaymentCalendar(calendar_) - .withNotionals(faceAmount) - .withPaymentAdjustment(paymentConvention); + .withCouponRates(coupons, accrualDayCounter) + .withExCouponPeriod(exCouponPeriod, + exCouponCalendar, + exCouponConvention, + exCouponEndOfMonth) + .withPaymentCalendar(calendar_) + .withNotionals(faceAmount) + .withPaymentAdjustment(paymentConvention); addRedemptionsToCashflows(new List() { redemption }); - Utils.QL_REQUIRE(cashflows().Count != 0,()=> "bond with no cashflows!"); - Utils.QL_REQUIRE(redemptions_.Count == 1,()=> "multiple redemptions created"); + Utils.QL_REQUIRE(cashflows().Count != 0, () => "bond with no cashflows!"); + Utils.QL_REQUIRE(redemptions_.Count == 1, () => "multiple redemptions created"); } - + /*! simple annual compounding coupon rates with internal schedule calculation */ - public FixedRateBond(int settlementDays, + public FixedRateBond(int settlementDays, Calendar calendar, double faceAmount, Date startDate, @@ -81,23 +81,23 @@ public FixedRateBond(int settlementDays, DateGeneration.Rule rule = DateGeneration.Rule.Backward, bool endOfMonth = false, Calendar paymentCalendar = null, - Period exCouponPeriod = null, + Period exCouponPeriod = null, Calendar exCouponCalendar = null, - BusinessDayConvention exCouponConvention = BusinessDayConvention.Unadjusted, + BusinessDayConvention exCouponConvention = BusinessDayConvention.Unadjusted, bool exCouponEndOfMonth = false) - : base(settlementDays, paymentCalendar ?? calendar, - issueDate) + : base(settlementDays, paymentCalendar ?? calendar, + issueDate) { frequency_ = tenor.frequency(); dayCounter_ = accrualDayCounter; maturityDate_ = maturityDate; - Date firstDate = null , nextToLastDate = null; + Date firstDate = null, nextToLastDate = null; - switch (rule) + switch (rule) { - + case DateGeneration.Rule.Backward: firstDate = null; nextToLastDate = stubDate; @@ -114,7 +114,7 @@ public FixedRateBond(int settlementDays, case DateGeneration.Rule.TwentiethIMM: Utils.QL_FAIL("stub date (" + stubDate + ") not allowed with " + rule + " DateGeneration::Rule"); break; - + default: Utils.QL_FAIL("unknown DateGeneration::Rule (" + rule + ")"); break; @@ -126,22 +126,22 @@ public FixedRateBond(int settlementDays, rule, endOfMonth, firstDate, nextToLastDate); - + cashflows_ = new FixedRateLeg(schedule) - .withCouponRates(coupons, accrualDayCounter) - .withExCouponPeriod(exCouponPeriod, - exCouponCalendar, - exCouponConvention, - exCouponEndOfMonth) - .withPaymentCalendar(calendar_) - .withNotionals(faceAmount) - .withPaymentAdjustment(paymentConvention); + .withCouponRates(coupons, accrualDayCounter) + .withExCouponPeriod(exCouponPeriod, + exCouponCalendar, + exCouponConvention, + exCouponEndOfMonth) + .withPaymentCalendar(calendar_) + .withNotionals(faceAmount) + .withPaymentAdjustment(paymentConvention); addRedemptionsToCashflows(new List() { redemption }); - Utils.QL_REQUIRE(cashflows().Count != 0,()=> "bond with no cashflows!"); - Utils.QL_REQUIRE(redemptions_.Count == 1,()=> "multiple redemptions created"); + Utils.QL_REQUIRE(cashflows().Count != 0, () => "bond with no cashflows!"); + Utils.QL_REQUIRE(redemptions_.Count == 1, () => "multiple redemptions created"); } public FixedRateBond(int settlementDays, @@ -152,36 +152,36 @@ public FixedRateBond(int settlementDays, double redemption = 100, Date issueDate = null, Calendar paymentCalendar = null, - Period exCouponPeriod = null, - Calendar exCouponCalendar = null, - BusinessDayConvention exCouponConvention = BusinessDayConvention.Unadjusted, - bool exCouponEndOfMonth = false) + Period exCouponPeriod = null, + Calendar exCouponCalendar = null, + BusinessDayConvention exCouponConvention = BusinessDayConvention.Unadjusted, + bool exCouponEndOfMonth = false) - : base(settlementDays,paymentCalendar ?? schedule.calendar(), + : base(settlementDays, paymentCalendar ?? schedule.calendar(), issueDate) { - + frequency_ = schedule.tenor().frequency(); dayCounter_ = coupons[0].dayCounter(); maturityDate_ = schedule.endDate(); - cashflows_ = new FixedRateLeg(schedule) - .withCouponRates(coupons) - .withExCouponPeriod(exCouponPeriod, - exCouponCalendar, - exCouponConvention, - exCouponEndOfMonth) - .withPaymentCalendar(calendar_) - .withNotionals(faceAmount) - .withPaymentAdjustment(paymentConvention); + cashflows_ = new FixedRateLeg(schedule) + .withCouponRates(coupons) + .withExCouponPeriod(exCouponPeriod, + exCouponCalendar, + exCouponConvention, + exCouponEndOfMonth) + .withPaymentCalendar(calendar_) + .withNotionals(faceAmount) + .withPaymentAdjustment(paymentConvention); + + addRedemptionsToCashflows(new List() { redemption }); - addRedemptionsToCashflows(new List() { redemption }); + Utils.QL_REQUIRE(cashflows().Count != 0, () => "bond with no cashflows!"); + Utils.QL_REQUIRE(redemptions_.Count == 1, () => "multiple redemptions created"); + } - Utils.QL_REQUIRE(cashflows().Count != 0,()=> "bond with no cashflows!"); - Utils.QL_REQUIRE(redemptions_.Count == 1,()=> "multiple redemptions created"); - } - public Frequency frequency() { return frequency_; } public DayCounter dayCounter() { return dayCounter_; } diff --git a/src/QLNet/Instruments/Bonds/FloatingRateBond.cs b/src/QLNet/Instruments/Bonds/FloatingRateBond.cs index 88f8178b3..f2f98b765 100644 --- a/src/QLNet/Instruments/Bonds/FloatingRateBond.cs +++ b/src/QLNet/Instruments/Bonds/FloatingRateBond.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,111 +19,116 @@ under the terms of the QLNet license. You should have received a using System; using System.Collections.Generic; -namespace QLNet { - //! floating-rate bond (possibly capped and/or floored) - //! \test calculations are tested by checking results against cached values. - public class FloatingRateBond : Bond { - public FloatingRateBond(int settlementDays, double faceAmount, Schedule schedule, IborIndex index, - DayCounter paymentDayCounter) - : this(settlementDays, faceAmount, schedule, index, paymentDayCounter, BusinessDayConvention.Following, - 0, new List() { 1 }, new List() { 0 }, new List(), new List(), - false, 100, null) { } - public FloatingRateBond(int settlementDays, double faceAmount, Schedule schedule, IborIndex index, - DayCounter paymentDayCounter, BusinessDayConvention paymentConvention, int fixingDays, - List gearings, List spreads) - : this(settlementDays, faceAmount, schedule, index, paymentDayCounter, BusinessDayConvention.Following, - fixingDays, gearings, spreads, new List(), new List(), false, 100, null) { } - public FloatingRateBond(int settlementDays, double faceAmount, Schedule schedule, IborIndex index, DayCounter paymentDayCounter, - BusinessDayConvention paymentConvention, int fixingDays, List gearings, List spreads, - List caps, List floors, bool inArrears, double redemption, Date issueDate) - : base(settlementDays, schedule.calendar(), issueDate) { - maturityDate_ = schedule.endDate(); - cashflows_ = new IborLeg(schedule, index) - .withPaymentDayCounter(paymentDayCounter) - .withFixingDays(fixingDays) - .withGearings(gearings) - .withSpreads(spreads) - .withCaps(caps) - .withFloors(floors) - .inArrears(inArrears) - .withNotionals(faceAmount) - .withPaymentAdjustment(paymentConvention); - - addRedemptionsToCashflows(new List() { redemption }); - - Utils.QL_REQUIRE(cashflows().Count != 0,()=> "bond with no cashflows!"); - Utils.QL_REQUIRE(redemptions_.Count == 1,()=> "multiple redemptions created"); - - index.registerWith(update); - } - - //public FloatingRateBond(int settlementDays, double faceAmount, Date startDate, Date maturityDate, Frequency couponFrequency, - // Calendar calendar, IborIndex index, DayCounter accrualDayCounter, - // BusinessDayConvention accrualConvention = Following, - // BusinessDayConvention paymentConvention = Following, - // int fixingDays = Null(), - // List gearings = std::vector(1, 1.0), - // List spreads = std::vector(1, 0.0), - // List caps = std::vector(), - // List floors = std::vector(), - // bool inArrears = false, - // double redemption = 100.0, - // Date issueDate = Date(), - // Date stubDate = Date(), - // DateGeneration.Rule rule = DateGeneration::Backward, - // bool endOfMonth = false) - public FloatingRateBond(int settlementDays, double faceAmount, Date startDate, Date maturityDate, Frequency couponFrequency, - Calendar calendar, IborIndex index, DayCounter accrualDayCounter, - BusinessDayConvention accrualConvention, BusinessDayConvention paymentConvention, - int fixingDays, List gearings, List spreads, List caps, - List floors, bool inArrears, double redemption, Date issueDate, - Date stubDate, DateGeneration.Rule rule, bool endOfMonth) - : base(settlementDays, calendar, issueDate) { - - maturityDate_ = maturityDate; - - Date firstDate = null, nextToLastDate = null; - switch (rule) { - case DateGeneration.Rule.Backward: - firstDate = null; - nextToLastDate = stubDate; - break; - case DateGeneration.Rule.Forward: - firstDate = stubDate; - nextToLastDate = null; - break; - case DateGeneration.Rule.Zero: - case DateGeneration.Rule.ThirdWednesday: - case DateGeneration.Rule.Twentieth: - case DateGeneration.Rule.TwentiethIMM: - Utils.QL_FAIL("stub date (" + stubDate + ") not allowed with " + rule + " DateGeneration::Rule"); - break; - default: - Utils.QL_FAIL("unknown DateGeneration::Rule (" + rule + ")"); - break; - } - - Schedule schedule = new Schedule(startDate, maturityDate_, new Period(couponFrequency), calendar_, - accrualConvention, accrualConvention, rule, endOfMonth, firstDate, nextToLastDate); - - cashflows_ = new IborLeg(schedule, index) - .withPaymentDayCounter(accrualDayCounter) - .withFixingDays(fixingDays) - .withGearings(gearings) - .withSpreads(spreads) - .withCaps(caps) - .withFloors(floors) - .inArrears(inArrears) - .withNotionals(faceAmount) - .withPaymentAdjustment(paymentConvention); - - addRedemptionsToCashflows(new List() { redemption }); - - Utils.QL_REQUIRE(cashflows().Count != 0,()=> "bond with no cashflows!"); - Utils.QL_REQUIRE(redemptions_.Count == 1,()=> "multiple redemptions created"); - - index.registerWith(update); - } - - } +namespace QLNet +{ + //! floating-rate bond (possibly capped and/or floored) + //! \test calculations are tested by checking results against cached values. + public class FloatingRateBond : Bond + { + public FloatingRateBond(int settlementDays, double faceAmount, Schedule schedule, IborIndex index, + DayCounter paymentDayCounter) + : this(settlementDays, faceAmount, schedule, index, paymentDayCounter, BusinessDayConvention.Following, + 0, new List() { 1 }, new List() { 0 }, new List < double? >(), new List < double? >(), + false, 100, null) { } + public FloatingRateBond(int settlementDays, double faceAmount, Schedule schedule, IborIndex index, + DayCounter paymentDayCounter, BusinessDayConvention paymentConvention, int fixingDays, + List gearings, List spreads) + : this(settlementDays, faceAmount, schedule, index, paymentDayCounter, BusinessDayConvention.Following, + fixingDays, gearings, spreads, new List < double? >(), new List < double? >(), false, 100, null) { } + public FloatingRateBond(int settlementDays, double faceAmount, Schedule schedule, IborIndex index, DayCounter paymentDayCounter, + BusinessDayConvention paymentConvention, int fixingDays, List gearings, List spreads, + List < double? > caps, List < double? > floors, bool inArrears, double redemption, Date issueDate) + : base(settlementDays, schedule.calendar(), issueDate) + { + maturityDate_ = schedule.endDate(); + cashflows_ = new IborLeg(schedule, index) + .withPaymentDayCounter(paymentDayCounter) + .withFixingDays(fixingDays) + .withGearings(gearings) + .withSpreads(spreads) + .withCaps(caps) + .withFloors(floors) + .inArrears(inArrears) + .withNotionals(faceAmount) + .withPaymentAdjustment(paymentConvention); + + addRedemptionsToCashflows(new List() { redemption }); + + Utils.QL_REQUIRE(cashflows().Count != 0, () => "bond with no cashflows!"); + Utils.QL_REQUIRE(redemptions_.Count == 1, () => "multiple redemptions created"); + + index.registerWith(update); + } + + //public FloatingRateBond(int settlementDays, double faceAmount, Date startDate, Date maturityDate, Frequency couponFrequency, + // Calendar calendar, IborIndex index, DayCounter accrualDayCounter, + // BusinessDayConvention accrualConvention = Following, + // BusinessDayConvention paymentConvention = Following, + // int fixingDays = Null(), + // List gearings = std::vector(1, 1.0), + // List spreads = std::vector(1, 0.0), + // List caps = std::vector(), + // List floors = std::vector(), + // bool inArrears = false, + // double redemption = 100.0, + // Date issueDate = Date(), + // Date stubDate = Date(), + // DateGeneration.Rule rule = DateGeneration::Backward, + // bool endOfMonth = false) + public FloatingRateBond(int settlementDays, double faceAmount, Date startDate, Date maturityDate, Frequency couponFrequency, + Calendar calendar, IborIndex index, DayCounter accrualDayCounter, + BusinessDayConvention accrualConvention, BusinessDayConvention paymentConvention, + int fixingDays, List gearings, List spreads, List < double? > caps, + List < double? > floors, bool inArrears, double redemption, Date issueDate, + Date stubDate, DateGeneration.Rule rule, bool endOfMonth) + : base(settlementDays, calendar, issueDate) + { + + maturityDate_ = maturityDate; + + Date firstDate = null, nextToLastDate = null; + switch (rule) + { + case DateGeneration.Rule.Backward: + firstDate = null; + nextToLastDate = stubDate; + break; + case DateGeneration.Rule.Forward: + firstDate = stubDate; + nextToLastDate = null; + break; + case DateGeneration.Rule.Zero: + case DateGeneration.Rule.ThirdWednesday: + case DateGeneration.Rule.Twentieth: + case DateGeneration.Rule.TwentiethIMM: + Utils.QL_FAIL("stub date (" + stubDate + ") not allowed with " + rule + " DateGeneration::Rule"); + break; + default: + Utils.QL_FAIL("unknown DateGeneration::Rule (" + rule + ")"); + break; + } + + Schedule schedule = new Schedule(startDate, maturityDate_, new Period(couponFrequency), calendar_, + accrualConvention, accrualConvention, rule, endOfMonth, firstDate, nextToLastDate); + + cashflows_ = new IborLeg(schedule, index) + .withPaymentDayCounter(accrualDayCounter) + .withFixingDays(fixingDays) + .withGearings(gearings) + .withSpreads(spreads) + .withCaps(caps) + .withFloors(floors) + .inArrears(inArrears) + .withNotionals(faceAmount) + .withPaymentAdjustment(paymentConvention); + + addRedemptionsToCashflows(new List() { redemption }); + + Utils.QL_REQUIRE(cashflows().Count != 0, () => "bond with no cashflows!"); + Utils.QL_REQUIRE(redemptions_.Count == 1, () => "multiple redemptions created"); + + index.registerWith(update); + } + + } } diff --git a/src/QLNet/Instruments/Bonds/IPrepayModel.cs b/src/QLNet/Instruments/Bonds/IPrepayModel.cs index 2ae5e7462..afd4e2cfd 100644 --- a/src/QLNet/Instruments/Bonds/IPrepayModel.cs +++ b/src/QLNet/Instruments/Bonds/IPrepayModel.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Instruments/Bonds/MBSFixedRateBond.cs b/src/QLNet/Instruments/Bonds/MBSFixedRateBond.cs index 1bc1d8d04..1af83a686 100644 --- a/src/QLNet/Instruments/Bonds/MBSFixedRateBond.cs +++ b/src/QLNet/Instruments/Bonds/MBSFixedRateBond.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,18 +24,18 @@ namespace QLNet public class MBSFixedRateBond : AmortizingFixedRateBond { public MBSFixedRateBond(int settlementDays, - Calendar calendar, - double faceAmount, - Date startDate, - Period bondTenor, - Period originalLength, - Frequency sinkingFrequency, - double WACRate, - double PassThroughRate, - DayCounter accrualDayCounter, - IPrepayModel prepayModel, - BusinessDayConvention paymentConvention = BusinessDayConvention.Following, - Date issueDate = null) + Calendar calendar, + double faceAmount, + Date startDate, + Period bondTenor, + Period originalLength, + Frequency sinkingFrequency, + double WACRate, + double PassThroughRate, + DayCounter accrualDayCounter, + IPrepayModel prepayModel, + BusinessDayConvention paymentConvention = BusinessDayConvention.Following, + Date issueDate = null) : base(settlementDays, calendar, faceAmount, startDate, bondTenor, sinkingFrequency, WACRate, accrualDayCounter, paymentConvention, issueDate) { prepayModel_ = prepayModel; @@ -66,22 +66,22 @@ public List expectedCashflows() // ADD CashFlow c1 = new VoluntaryPrepay(prepay, schedule_[i + 1]); CashFlow c2 = new AmortizingPayment(actualamort, schedule_[i + 1]); - CashFlow c3 = new FixedRateCoupon( schedule_[i + 1], currentNotional, new InterestRate(PassThroughRate_, dCounter_, Compounding.Simple,Frequency.Annual), schedule_[i], schedule_[i + 1]); + CashFlow c3 = new FixedRateCoupon(schedule_[i + 1], currentNotional, new InterestRate(PassThroughRate_, dCounter_, Compounding.Simple, Frequency.Annual), schedule_[i], schedule_[i + 1]); expectedcashflows.Add(c1); expectedcashflows.Add(c2); expectedcashflows.Add(c3); - + } notionals[notionals.Count - 1] = 0.0; - + return expectedcashflows; } - public double SMM(Date d ) + public double SMM(Date d) { - if ( prepayModel_ != null ) + if (prepayModel_ != null) { - return prepayModel_.getSMM( d + ( originalLength_ - remainingLength_ ) ); + return prepayModel_.getSMM(d + (originalLength_ - remainingLength_)); } else return 0; @@ -94,20 +94,20 @@ public double MonthlyYield() List cf = expectedCashflows(); MonthlyYieldFinder objective = new MonthlyYieldFinder(notional(settlementDate()), cf, settlementDate()); - return solver.solve(objective, 1.0e-10, 0.02, 0.0, 1.0) /100 ; + return solver.solve(objective, 1.0e-10, 0.02, 0.0, 1.0) / 100 ; } public double BondEquivalentYield() { - return 2 * ( Math.Pow(1 + MonthlyYield(), 6 )- 1); + return 2 * (Math.Pow(1 + MonthlyYield(), 6) - 1); } protected void calcBondFactor() { bondFactors_ = new InitializedList(notionals_.Count); - for ( int i = 0 ; i < notionals_.Count ; i++ ) + for (int i = 0 ; i < notionals_.Count ; i++) { - if ( i == 0 ) + if (i == 0) bondFactors_[i] = 1; else bondFactors_[i] = notionals_[i] / notionals_[0]; @@ -115,14 +115,14 @@ protected void calcBondFactor() } public List BondFactors() { if (bondFactors_ == null) calcBondFactor(); return bondFactors_; } - + protected List bondFactors_; protected IPrepayModel prepayModel_; protected Period originalLength_, remainingLength_; protected double WACRate_; protected double PassThroughRate_; protected DayCounter dCounter_; - + } public class MonthlyYieldFinder : ISolver1d @@ -131,7 +131,7 @@ public class MonthlyYieldFinder : ISolver1d private List cashflows_; private Date settlement_; - public MonthlyYieldFinder(double faceAmount, List cashflows,Date settlement) + public MonthlyYieldFinder(double faceAmount, List cashflows, Date settlement) { faceAmount_ = faceAmount; cashflows_ = cashflows; @@ -150,7 +150,7 @@ public partial class Utils public static double PVDifference(double faceAmount, List cashflows, double yield, Date settlement) { double price = 0.0; - Date actualDate = new Date(1,1,1970) ; + Date actualDate = new Date(1, 1, 1970) ; int cashflowindex = 0 ; @@ -159,13 +159,13 @@ public static double PVDifference(double faceAmount, List cashflows, d if (cashflows[i].hasOccurred(settlement)) continue; // TODO use daycounter to find cashflowindex - if ( cashflows[i].date() != actualDate ) + if (cashflows[i].date() != actualDate) { actualDate = cashflows[i].date(); cashflowindex++; } double amount = cashflows[i].amount(); - price += amount / Math.Pow((1 + yield/100), cashflowindex); + price += amount / Math.Pow((1 + yield / 100), cashflowindex); } return price - faceAmount; diff --git a/src/QLNet/Instruments/Bonds/PSACurve.cs b/src/QLNet/Instruments/Bonds/PSACurve.cs index d5fa06378..0f5a549e3 100644 --- a/src/QLNet/Instruments/Bonds/PSACurve.cs +++ b/src/QLNet/Instruments/Bonds/PSACurve.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,7 +24,7 @@ public class PSACurve : IPrepayModel { public PSACurve(Date startdate) - :this(startdate, 1 ) {} + : this(startdate, 1) {} public PSACurve(Date startdate, double multiplier) { @@ -35,7 +35,7 @@ public PSACurve(Date startdate, double multiplier) public double getCPR(Date valDate) { Thirty360 dayCounter = new Thirty360(); - int d = dayCounter.dayCount(_startDate,valDate)/30 + 1; + int d = dayCounter.dayCount(_startDate, valDate) / 30 + 1; return (d <= 30 ? 0.06 * (d / 30d) : 0.06) * _multi; } diff --git a/src/QLNet/Instruments/Bonds/Zerocouponbond.cs b/src/QLNet/Instruments/Bonds/Zerocouponbond.cs index 799b64a8b..bd54cdda4 100644 --- a/src/QLNet/Instruments/Bonds/Zerocouponbond.cs +++ b/src/QLNet/Instruments/Bonds/Zerocouponbond.cs @@ -1,32 +1,33 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { - //! zero-coupon bond - /*! \ingroup instruments +namespace QLNet +{ + //! zero-coupon bond + /*! \ingroup instruments - \test calculations are tested by checking results against cached values. - */ + \test calculations are tested by checking results against cached values. + */ public class ZeroCouponBond : Bond { public ZeroCouponBond(int settlementDays, Calendar calendar, double faceAmount, Date maturityDate, - BusinessDayConvention paymentConvention, double redemption, Date issueDate) + BusinessDayConvention paymentConvention, double redemption, Date issueDate) : base(settlementDays, calendar, issueDate) { maturityDate_ = maturityDate; diff --git a/src/QLNet/Instruments/CPICapFloor.cs b/src/QLNet/Instruments/CPICapFloor.cs index 1d4a1bf19..e8dc845c0 100644 --- a/src/QLNet/Instruments/CPICapFloor.cs +++ b/src/QLNet/Instruments/CPICapFloor.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -48,14 +48,14 @@ public class Arguments : IPricingEngineArguments public Option.Type type { get; set; } public double nominal { get; set; } public Date startDate { get; set; } - public Date fixDate{ get; set; } - public Date payDate{ get; set; } + public Date fixDate { get; set; } + public Date payDate { get; set; } public double baseCPI { get; set; } public Date maturity { get; set; } public Calendar fixCalendar { get; set; } public Calendar payCalendar { get; set; } public BusinessDayConvention fixConvention { get; set; } - public BusinessDayConvention payConvention{ get; set; } + public BusinessDayConvention payConvention { get; set; } public double strike { get; set; } public Handle infIndex { get; set; } public Period observationLag { get; set; } @@ -67,12 +67,12 @@ public void validate() } } - public new class Results : Instrument.Results + public new class Results : Instrument.Results { public override void reset() { base.reset();} } - public class Engine : GenericEngine {} + public class Engine : GenericEngine {} public CPICapFloor(Option.Type type, double nominal, @@ -88,38 +88,38 @@ public CPICapFloor(Option.Type type, Period observationLag, InterpolationType observationInterpolation = InterpolationType.AsIndex) { - type_ = type; - nominal_ = nominal; - startDate_ = startDate; + type_ = type; + nominal_ = nominal; + startDate_ = startDate; baseCPI_ = baseCPI; - maturity_ = maturity; - fixCalendar_ = fixCalendar; + maturity_ = maturity; + fixCalendar_ = fixCalendar; fixConvention_ = fixConvention; - payCalendar_ = payCalendar; + payCalendar_ = payCalendar; payConvention_ = payConvention; - strike_ = strike; - infIndex_ = infIndex; + strike_ = strike; + infIndex_ = infIndex; observationLag_ = observationLag; observationInterpolation_ = observationInterpolation; - Utils.QL_REQUIRE(fixCalendar_ != null, ()=> "CPICapFloor: fixing calendar may not be null."); - Utils.QL_REQUIRE(payCalendar_ != null, ()=> "CPICapFloor: payment calendar may not be null."); + Utils.QL_REQUIRE(fixCalendar_ != null, () => "CPICapFloor: fixing calendar may not be null."); + Utils.QL_REQUIRE(payCalendar_ != null, () => "CPICapFloor: payment calendar may not be null."); if (observationInterpolation_ == InterpolationType.Flat || - observationInterpolation_ == InterpolationType.AsIndex && !infIndex_.link.interpolated()) + observationInterpolation_ == InterpolationType.AsIndex && !infIndex_.link.interpolated()) { - Utils.QL_REQUIRE(observationLag_ >= infIndex_.link.availabilityLag(),()=> - "CPIcapfloor's observationLag must be at least availabilityLag of inflation index: " - +"when the observation is effectively flat" - + observationLag_ + " vs " + infIndex_.link.availabilityLag()); + Utils.QL_REQUIRE(observationLag_ >= infIndex_.link.availabilityLag(), () => + "CPIcapfloor's observationLag must be at least availabilityLag of inflation index: " + + "when the observation is effectively flat" + + observationLag_ + " vs " + infIndex_.link.availabilityLag()); } if (observationInterpolation_ == InterpolationType.Linear || - (observationInterpolation_ == InterpolationType.AsIndex && infIndex_.link.interpolated())) + (observationInterpolation_ == InterpolationType.AsIndex && infIndex_.link.interpolated())) { - Utils.QL_REQUIRE(observationLag_ > infIndex_.link.availabilityLag(),()=> - "CPIcapfloor's observationLag must be greater then availabilityLag of inflation index: " - +"when the observation is effectively linear" - + observationLag_ + " vs " + infIndex_.link.availabilityLag()); + Utils.QL_REQUIRE(observationLag_ > infIndex_.link.availabilityLag(), () => + "CPIcapfloor's observationLag must be greater then availabilityLag of inflation index: " + + "when the observation is effectively linear" + + observationLag_ + " vs " + infIndex_.link.availabilityLag()); } } @@ -129,8 +129,8 @@ public CPICapFloor(Option.Type type, //! \f$ K \f$ in the above formula. public double strike() { return strike_; } //! when you fix - but remember that there is an observation interpolation factor as well - public Date fixingDate() { return fixCalendar_.adjust( maturity_ - observationLag_, fixConvention_ ); } - public Date payDate() { return payCalendar_.adjust( maturity_, payConvention_ ); } + public Date fixingDate() { return fixCalendar_.adjust(maturity_ - observationLag_, fixConvention_); } + public Date payDate() { return payCalendar_.adjust(maturity_, payConvention_); } public Handle inflationIndex() { return infIndex_; } public Period observationLag() { return observationLag_; } @@ -140,7 +140,7 @@ public override void setupArguments(IPricingEngineArguments args) { // correct PricingEngine? CPICapFloor.Arguments arguments = args as CPICapFloor.Arguments; - Utils.QL_REQUIRE( arguments != null,()=> "wrong argument type, not CPICapFloor.Arguments" ); + Utils.QL_REQUIRE(arguments != null, () => "wrong argument type, not CPICapFloor.Arguments"); // data move arguments.type = type_; diff --git a/src/QLNet/Instruments/CPISwap.cs b/src/QLNet/Instruments/CPISwap.cs index 5a5772399..5bc7f5bc0 100644 --- a/src/QLNet/Instruments/CPISwap.cs +++ b/src/QLNet/Instruments/CPISwap.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -49,7 +49,7 @@ and swap settlement date are outside the scope of the */ public class CPISwap : Swap { - public enum Type { Receiver = -1, Payer = 1 }; + public enum Type { Receiver = -1, Payer = 1 } public new class Arguments : Swap.Arguments { public Arguments() @@ -57,7 +57,7 @@ public Arguments() type = Type.Receiver; nominal = null; } - + public Type type { get; set; } public double? nominal { get; set; } @@ -75,7 +75,7 @@ public override void reset() } } - public class Engine : GenericEngine + public class Engine : GenericEngine {} public CPISwap(Type type, @@ -97,29 +97,29 @@ public CPISwap(Type type, Period observationLag, ZeroInflationIndex fixedIndex, InterpolationType observationInterpolation = InterpolationType.AsIndex, - double? inflationNominal = null ) - :base(2) + double? inflationNominal = null) + : base(2) { - type_ = type; - nominal_ = nominal; + type_ = type; + nominal_ = nominal; subtractInflationNominal_ = subtractInflationNominal; - spread_ = spread; - floatDayCount_ = floatDayCount; + spread_ = spread; + floatDayCount_ = floatDayCount; floatSchedule_ = floatSchedule; - floatPaymentRoll_ = floatPaymentRoll; + floatPaymentRoll_ = floatPaymentRoll; fixingDays_ = fixingDays; floatIndex_ = floatIndex; - fixedRate_ = fixedRate; - baseCPI_ = baseCPI; - fixedDayCount_ = fixedDayCount; + fixedRate_ = fixedRate; + baseCPI_ = baseCPI; + fixedDayCount_ = fixedDayCount; fixedSchedule_ = fixedSchedule; - fixedPaymentRoll_ = fixedPaymentRoll; + fixedPaymentRoll_ = fixedPaymentRoll; fixedIndex_ = fixedIndex; observationLag_ = observationLag; observationInterpolation_ = observationInterpolation; - Utils.QL_REQUIRE(floatSchedule_.Count>0,()=> "empty float schedule"); - Utils.QL_REQUIRE(fixedSchedule_.Count>0,()=> "empty fixed schedule"); + Utils.QL_REQUIRE(floatSchedule_.Count > 0, () => "empty float schedule"); + Utils.QL_REQUIRE(fixedSchedule_.Count > 0, () => "empty fixed schedule"); // todo if roll!=unadjusted then need calendars ... inflationNominal_ = inflationNominal ?? nominal_; @@ -128,29 +128,29 @@ public CPISwap(Type type, if (floatSchedule_.Count > 1) { floatingLeg = new IborLeg(floatSchedule_, floatIndex_) - .withFixingDays(fixingDays_) - .withPaymentDayCounter(floatDayCount_) - .withSpreads(spread_) - .withNotionals(nominal_) - .withPaymentAdjustment(floatPaymentRoll_); + .withFixingDays(fixingDays_) + .withPaymentDayCounter(floatDayCount_) + .withSpreads(spread_) + .withNotionals(nominal_) + .withPaymentAdjustment(floatPaymentRoll_); } else floatingLeg = new List(); - if (floatSchedule_.Count==1 || - !subtractInflationNominal_ || - (subtractInflationNominal && Math.Abs(nominal_-inflationNominal_)>0.00001) + if (floatSchedule_.Count == 1 || + !subtractInflationNominal_ || + (subtractInflationNominal && Math.Abs(nominal_ - inflationNominal_) > 0.00001) ) { Date payNotional; - if (floatSchedule_.Count==1) - { + if (floatSchedule_.Count == 1) + { // no coupons payNotional = floatSchedule_[0]; payNotional = floatSchedule_.calendar().adjust(payNotional, floatPaymentRoll_); - } - else - { + } + else + { // use the pay date of the last coupon payNotional = floatingLeg.Last().date(); } @@ -162,12 +162,12 @@ public CPISwap(Type type, // a CPIleg know about zero legs and inclusion of base inflation notional List cpiLeg = new CPILeg(fixedSchedule_, fixedIndex_, baseCPI_, observationLag_) - .withFixedRates(fixedRate_) - .withPaymentDayCounter(fixedDayCount_) - .withObservationInterpolation(observationInterpolation_) - .withSubtractInflationNominal(subtractInflationNominal_) - .withNotionals(inflationNominal_) - .withPaymentAdjustment(fixedPaymentRoll_); + .withFixedRates(fixedRate_) + .withPaymentDayCounter(fixedDayCount_) + .withObservationInterpolation(observationInterpolation_) + .withSubtractInflationNominal(subtractInflationNominal_) + .withNotionals(inflationNominal_) + .withPaymentAdjustment(fixedPaymentRoll_); foreach (CashFlow cashFlow in cpiLeg) { @@ -187,12 +187,12 @@ public CPISwap(Type type, legs_[1] = floatingLeg; - if (type_==Type.Payer) + if (type_ == Type.Payer) { payer_[0] = 1.0; payer_[1] = -1.0; - } - else + } + else { payer_[0] = -1.0; payer_[1] = 1.0; @@ -204,27 +204,27 @@ public CPISwap(Type type, public virtual double floatLegNPV() { calculate(); - Utils.QL_REQUIRE(legNPV_[1] != null,()=> "result not available"); - return legNPV_[1].GetValueOrDefault(); + Utils.QL_REQUIRE(legNPV_[1] != null, () => "result not available"); + return legNPV_[1].GetValueOrDefault(); } public virtual double fairSpread() { calculate(); - Utils.QL_REQUIRE(fairSpread_ != null,()=> "result not available"); + Utils.QL_REQUIRE(fairSpread_ != null, () => "result not available"); return fairSpread_.GetValueOrDefault(); } // fixed rate x inflation public virtual double fixedLegNPV() { calculate(); - Utils.QL_REQUIRE(legNPV_[0] != null,()=> "result not available"); + Utils.QL_REQUIRE(legNPV_[0] != null, () => "result not available"); return legNPV_[0].GetValueOrDefault(); } public virtual double fairRate() { calculate(); - Utils.QL_REQUIRE(fairRate_ != null,()=> "result not available"); + Utils.QL_REQUIRE(fairRate_ != null, () => "result not available"); return fairRate_.GetValueOrDefault(); } @@ -269,38 +269,38 @@ public override void fetchResults(IPricingEngineResults r) CPISwap.Results results = r as CPISwap.Results; - if (results!=null) - { + if (results != null) + { // might be a swap engine, so no error is thrown fairRate_ = results.fairRate; fairSpread_ = results.fairSpread; - } - else + } + else { fairRate_ = null; fairSpread_ = null; } - if (fairRate_ == null) + if (fairRate_ == null) { // calculate it from other results if (legBPS_[0] != null) - fairRate_ = fixedRate_ - NPV_/(legBPS_[0]/basisPoint); + fairRate_ = fixedRate_ - NPV_ / (legBPS_[0] / basisPoint); } - if (fairSpread_ == null) + if (fairSpread_ == null) { // ditto if (legBPS_[1] != null) - fairSpread_ = spread_ - NPV_/(legBPS_[1]/basisPoint); + fairSpread_ = spread_ - NPV_ / (legBPS_[1] / basisPoint); } } protected override void setupExpired() { - base.setupExpired(); - legBPS_[0] = legBPS_[1] = 0.0; - fairRate_ = null; - fairSpread_ = null; + base.setupExpired(); + legBPS_[0] = legBPS_[1] = 0.0; + fairRate_ = null; + fairSpread_ = null; } private Type type_; diff --git a/src/QLNet/Instruments/Callability.cs b/src/QLNet/Instruments/Callability.cs index 62dbac742..bb7001b34 100644 --- a/src/QLNet/Instruments/Callability.cs +++ b/src/QLNet/Instruments/Callability.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,58 +24,58 @@ namespace QLNet public class Callability : Event { //! amount to be paid upon callability - public class Price + public class Price { - public enum Type { Dirty, Clean }; + public enum Type { Dirty, Clean } - public Price() - { + public Price() + { amount_ = null; } - - public Price(double amount, Type type) + + public Price(double amount, Type type) { - amount_=amount; - type_ = type; + amount_ = amount; + type_ = type; } - - public double amount() + + public double amount() { - Utils.QL_REQUIRE( amount_ != null, () => "no amount given" ); + Utils.QL_REQUIRE(amount_ != null, () => "no amount given"); return amount_.Value; } - + public Type type() { return type_; } - + private double? amount_; private Type type_; - }; + } //! type of the callability - public enum Type { Call, Put }; + public enum Type { Call, Put } public Callability(Price price, Type type, Date date) { - price_=price; - type_=type; - date_=date; + price_ = price; + type_ = type; + date_ = date; } - public Price price() + public Price price() { - Utils.QL_REQUIRE( price_ != null, () => "no price given" ); + Utils.QL_REQUIRE(price_ != null, () => "no price given"); return price_; } public Type type() { return type_; } // Event interface public override Date date() { return date_; } - + private Price price_; private Type type_; private Date date_; } - public class CallabilitySchedule : List{} + public class CallabilitySchedule : List {} } diff --git a/src/QLNet/Instruments/CapFloor.cs b/src/QLNet/Instruments/CapFloor.cs index 99eb45440..d3e50688f 100644 --- a/src/QLNet/Instruments/CapFloor.cs +++ b/src/QLNet/Instruments/CapFloor.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -42,7 +42,7 @@ namespace QLNet public class CapFloor : Instrument { #region Private Attributes - + private CapFloorType type_; private List floatingLeg_; private List capRates_; @@ -58,17 +58,17 @@ public CapFloor(CapFloorType type, List floatingLeg, List capR type_ = type; floatingLeg_ = new List(floatingLeg); capRates_ = new List(capRates); - floorRates_ = new List(floorRates); + floorRates_ = new List(floorRates); - if (type_ == CapFloorType.Cap || type_ == CapFloorType.Collar) + if (type_ == CapFloorType.Cap || type_ == CapFloorType.Collar) { - if (capRates_.Count == 0 ) + if (capRates_.Count == 0) throw new ArgumentException("no cap rates given"); while (capRates_.Count < floatingLeg_.Count) - capRates_.Add(capRates_.Last()); + capRates_.Add(capRates_.Last()); } - if (type_ == CapFloorType.Floor || type_ == CapFloorType.Collar) + if (type_ == CapFloorType.Floor || type_ == CapFloorType.Collar) { if (floorRates_.Count == 0) throw new ArgumentException("no floor rates given"); @@ -83,30 +83,30 @@ public CapFloor(CapFloorType type, List floatingLeg, List capR Settings.registerWith(update); } - public CapFloor(CapFloorType type,List floatingLeg,List strikes) + public CapFloor(CapFloorType type, List floatingLeg, List strikes) { type_ = type; floatingLeg_ = new List(floatingLeg); - - if ( strikes.Count == 0 ) + + if (strikes.Count == 0) throw new ArgumentException("no strikes given"); - if (type_ == CapFloorType.Cap) + if (type_ == CapFloorType.Cap) { capRates_ = new List(strikes); while (capRates_.Count < floatingLeg_.Count) capRates_.Add(capRates_.Last()); - } - else if (type_ == CapFloorType.Floor) + } + else if (type_ == CapFloorType.Floor) { floorRates_ = new List(strikes); - while ( floorRates_.Count < floatingLeg_.Count ) + while (floorRates_.Count < floatingLeg_.Count) floorRates_.Add(floorRates_.Last()); - } + } else throw new ArgumentException("only Cap/Floor types allowed in this constructor"); @@ -121,19 +121,21 @@ public CapFloor(CapFloorType type,List floatingLeg,List strike #region Instrument interface - public override bool isExpired() + public override bool isExpired() { Date today = Settings.evaluationDate(); foreach (var cf in floatingLeg_) - if (!cf.hasOccurred(today)) return false; + if (!cf.hasOccurred(today)) + return false; return true; } - public override void setupArguments(IPricingEngineArguments args) + public override void setupArguments(IPricingEngineArguments args) { CapFloor.Arguments arguments = args as CapFloor.Arguments; - if (arguments == null) throw new ArgumentException("wrong argument type"); + if (arguments == null) + throw new ArgumentException("wrong argument type"); int n = floatingLeg_.Count; @@ -142,22 +144,22 @@ public override void setupArguments(IPricingEngineArguments args) arguments.fixingDates = new InitializedList(n); arguments.endDates = new InitializedList(n); arguments.accrualTimes = new InitializedList(n); - arguments.forwards = new InitializedList(n); + arguments.forwards = new InitializedList < double? >(n); arguments.nominals = new InitializedList(n); arguments.gearings = new InitializedList(n); - arguments.capRates = new InitializedList(n); - arguments.floorRates = new InitializedList(n); + arguments.capRates = new InitializedList < double? >(n); + arguments.floorRates = new InitializedList < double? >(n); arguments.spreads = new InitializedList(n); arguments.type = type_; Date today = Settings.evaluationDate(); - for (int i=0; i= today) - { + if (arguments.endDates[i] >= today) + { // ...but only if needed arguments.forwards[i] = coupon.adjustedFixing; - } - else + } + else { arguments.forwards[i] = null; } @@ -185,14 +187,14 @@ public override void setupArguments(IPricingEngineArguments args) arguments.spreads[i] = spread; if (type_ == CapFloorType.Cap || type_ == CapFloorType.Collar) - arguments.capRates[i] = (capRates_[i]-spread)/gearing; + arguments.capRates[i] = (capRates_[i] - spread) / gearing; else - arguments.capRates[i] = null; + arguments.capRates[i] = null; if (type_ == CapFloorType.Floor || type_ == CapFloorType.Collar) - arguments.floorRates[i] = (floorRates_[i]-spread)/gearing; + arguments.floorRates[i] = (floorRates_[i] - spread) / gearing; else - arguments.floorRates[i] = null; + arguments.floorRates[i] = null; } } @@ -207,35 +209,35 @@ public override void setupArguments(IPricingEngineArguments args) public Date startDate() {return CashFlows.startDate(floatingLeg_);} public Date maturityDate() {return CashFlows.maturityDate(floatingLeg_);} - - public FloatingRateCoupon lastFloatingRateCoupon() + + public FloatingRateCoupon lastFloatingRateCoupon() { CashFlow lastCF = floatingLeg_.Last(); FloatingRateCoupon lastFloatingCoupon = lastCF as FloatingRateCoupon; return lastFloatingCoupon; } - public CapFloor optionlet(int i) + public CapFloor optionlet(int i) { - if ( i >= floatingLeg().Count ) - throw new ArgumentException( i + " optionlet does not exist, only " + - floatingLeg().Count); + if (i >= floatingLeg().Count) + throw new ArgumentException(i + " optionlet does not exist, only " + + floatingLeg().Count); - List cf = new List(); - cf.Add(floatingLeg()[i]); + List cf = new List(); + cf.Add(floatingLeg()[i]); - List cap = new List() ; - List floor = new List() ; + List cap = new List() ; + List floor = new List() ; - if (getType() == CapFloorType.Cap || getType() == CapFloorType.Collar) + if (getType() == CapFloorType.Cap || getType() == CapFloorType.Collar) cap.Add(capRates()[i]); - if (getType() == CapFloorType.Floor || getType() == CapFloorType.Collar) + if (getType() == CapFloorType.Floor || getType() == CapFloorType.Collar) floor.Add(floorRates()[i]); - return new CapFloor(getType(), cf, cap, floor); + return new CapFloor(getType(), cf, cap, floor); } - public double atmRate(YieldTermStructure discountCurve) + public double atmRate(YieldTermStructure discountCurve) { bool includeSettlementDateFlows = false; Date settlementDate = discountCurve.referenceDate(); @@ -243,11 +245,11 @@ public double atmRate(YieldTermStructure discountCurve) } public double impliedVolatility( - double targetValue, - Handle discountCurve, - double guess, - double accuracy, - int maxEvaluations) + double targetValue, + Handle discountCurve, + double guess, + double accuracy, + int maxEvaluations) { return impliedVolatility(targetValue, discountCurve, guess, accuracy, maxEvaluations, 1.0e-7, 4.0, VolatilityType.ShiftedLognormal, 0.0); @@ -255,18 +257,18 @@ public double impliedVolatility( public double impliedVolatility( - double targetValue, - Handle discountCurve, - double guess, - double accuracy, - int maxEvaluations, - double minVol, - double maxVol, - VolatilityType type, - double displacement) + double targetValue, + Handle discountCurve, + double guess, + double accuracy, + int maxEvaluations, + double minVol, + double maxVol, + VolatilityType type, + double displacement) { calculate(); - if (isExpired()) + if (isExpired()) throw new ArgumentException("instrument expired"); ImpliedVolHelper f = new ImpliedVolHelper(this, discountCurve, targetValue, displacement, type); @@ -286,55 +288,55 @@ public class Arguments : IPricingEngineArguments public List fixingDates { get; set; } public List endDates { get; set; } public List accrualTimes { get; set; } - public List capRates { get; set; } - public List floorRates { get; set; } - public List forwards { get; set; } + public List < double? > capRates { get; set; } + public List < double? > floorRates { get; set; } + public List < double? > forwards { get; set; } public List gearings { get; set; } public List spreads { get; set; } public List nominals { get; set; } - public void validate() + public void validate() { if (endDates.Count != startDates.Count) - throw new ArgumentException( "number of start dates (" + startDates.Count - + ") different from that of end dates (" - + endDates.Count + ")"); + throw new ArgumentException("number of start dates (" + startDates.Count + + ") different from that of end dates (" + + endDates.Count + ")"); if (accrualTimes.Count != startDates.Count) - throw new ArgumentException( "number of start dates (" + startDates.Count - + ") different from that of accrual times (" - + accrualTimes.Count + ")"); + throw new ArgumentException("number of start dates (" + startDates.Count + + ") different from that of accrual times (" + + accrualTimes.Count + ")"); - if (capRates.Count != startDates.Count && type!= CapFloorType.Floor) - throw new ArgumentException( "number of start dates (" + startDates.Count - + ") different from that of of cap rates (" - + capRates.Count + ")"); + if (capRates.Count != startDates.Count && type != CapFloorType.Floor) + throw new ArgumentException("number of start dates (" + startDates.Count + + ") different from that of of cap rates (" + + capRates.Count + ")"); - if (floorRates.Count != startDates.Count && type!= CapFloorType.Cap) - throw new ArgumentException( "number of start dates (" + startDates.Count - + ") different from that of of floor rates (" - + floorRates.Count + ")"); + if (floorRates.Count != startDates.Count && type != CapFloorType.Cap) + throw new ArgumentException("number of start dates (" + startDates.Count + + ") different from that of of floor rates (" + + floorRates.Count + ")"); if (gearings.Count != startDates.Count) throw new ArgumentException("number of start dates (" + startDates.Count - + ") different from that of gearings (" - + gearings.Count + ")"); + + ") different from that of gearings (" + + gearings.Count + ")"); if (spreads.Count != startDates.Count) throw new ArgumentException("number of start dates (" + startDates.Count - + ") different from that of spreads (" - + spreads.Count + ")"); + + ") different from that of spreads (" + + spreads.Count + ")"); if (nominals.Count != startDates.Count) throw new ArgumentException("number of start dates (" + startDates.Count - + ") different from that of nominals (" - + nominals.Count + ")"); + + ") different from that of nominals (" + + nominals.Count + ")"); if (forwards.Count != startDates.Count) throw new ArgumentException("number of start dates (" + startDates.Count - + ") different from that of forwards (" - + forwards.Count + ")"); + + ") different from that of forwards (" + + forwards.Count + ")"); - } + } } #endregion @@ -344,35 +346,35 @@ public void validate() /// Concrete cap class /// \ingroup instruments /// - public class Cap : CapFloor + public class Cap : CapFloor { - public Cap(List floatingLeg,List exerciseRates) + public Cap(List floatingLeg, List exerciseRates) : base(CapFloorType.Cap, floatingLeg, exerciseRates, new List()) {} - }; + } /// /// Concrete floor class - /// \ingroup instruments + /// \ingroup instruments /// - public class Floor : CapFloor - { - public Floor(List floatingLeg,List exerciseRates) - : base(CapFloorType.Floor, floatingLeg,new List(), exerciseRates) {} - }; + public class Floor : CapFloor + { + public Floor(List floatingLeg, List exerciseRates) + : base(CapFloorType.Floor, floatingLeg, new List(), exerciseRates) {} + } /// /// Concrete collar class /// \ingroup instruments /// - public class Collar : CapFloor - { - public Collar(List floatingLeg,List capRates, List floorRates) - : base(CapFloorType.Collar, floatingLeg, capRates, floorRates) { } - }; + public class Collar : CapFloor + { + public Collar(List floatingLeg, List capRates, List floorRates) + : base(CapFloorType.Collar, floatingLeg, capRates, floorRates) { } + } //! base class for cap/floor engines - public abstract class CapFloorEngine - : GenericEngine {}; + public abstract class CapFloorEngine + : GenericEngine {} public class ImpliedVolHelper : ISolver1d { @@ -396,19 +398,19 @@ public ImpliedVolHelper(CapFloor cap, switch (type) { - case VolatilityType.ShiftedLognormal: - engine_ = (IPricingEngine)new BlackCapFloorEngine(discountCurve_, h, new Actual365Fixed(), displacement); - break; + case VolatilityType.ShiftedLognormal: + engine_ = (IPricingEngine)new BlackCapFloorEngine(discountCurve_, h, new Actual365Fixed(), displacement); + break; - case VolatilityType.Normal: - engine_ = (IPricingEngine)new BachelierCapFloorEngine(discountCurve_, h, new Actual365Fixed()); - break; + case VolatilityType.Normal: + engine_ = (IPricingEngine)new BachelierCapFloorEngine(discountCurve_, h, new Actual365Fixed()); + break; - default: - Utils.QL_FAIL("unknown VolatilityType (" + type.ToString() + ")"); - break; + default: + Utils.QL_FAIL("unknown VolatilityType (" + type.ToString() + ")"); + break; } - + cap.setupArguments(engine_.getArguments()); results_ = engine_.getResults() as Instrument.Results; @@ -416,23 +418,23 @@ public ImpliedVolHelper(CapFloor cap, public override double value(double x) { - if (x.IsNotEqual(vol_.value())) + if (x.IsNotEqual(vol_.value())) { vol_.setValue(x); engine_.calculate(); } - return results_.value.Value -targetValue_; + return results_.value.Value - targetValue_; } - public override double derivative(double x) + public override double derivative(double x) { - if (x.IsNotEqual(vol_.value())) + if (x.IsNotEqual(vol_.value())) { vol_.setValue(x); engine_.calculate(); } - Utils.QL_REQUIRE( results_.additionalResults.Keys.Contains("vega"),()=> "vega not provided"); + Utils.QL_REQUIRE(results_.additionalResults.Keys.Contains("vega"), () => "vega not provided"); return (double) results_.additionalResults["vega"]; } } diff --git a/src/QLNet/Instruments/Claim.cs b/src/QLNet/Instruments/Claim.cs index c9ede0cd6..2d127f211 100644 --- a/src/QLNet/Instruments/Claim.cs +++ b/src/QLNet/Instruments/Claim.cs @@ -6,7 +6,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -27,8 +27,14 @@ public abstract class Claim : IObservable, IObserver public event Callback notifyObserversEvent { - add { eventSource.Subscribe(value); } - remove { eventSource.Unsubscribe(value); } + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } } public void registerWith(Callback handler) { notifyObserversEvent += handler; } diff --git a/src/QLNet/Instruments/CliquetOption.cs b/src/QLNet/Instruments/CliquetOption.cs index ea594784b..e25731220 100644 --- a/src/QLNet/Instruments/CliquetOption.cs +++ b/src/QLNet/Instruments/CliquetOption.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -32,24 +32,24 @@ percentage of the spot price at the beginning of each period. */ public class CliquetOption : OneAssetOption { - public CliquetOption( PercentageStrikePayoff payoff, EuropeanExercise maturity,List resetDates) - :base(payoff,maturity) + public CliquetOption(PercentageStrikePayoff payoff, EuropeanExercise maturity, List resetDates) + : base(payoff, maturity) { resetDates_ = new List(resetDates); } public override void setupArguments(IPricingEngineArguments args) { base.setupArguments(args); - // set accrued coupon, last fixing, caps, floors + // set accrued coupon, last fixing, caps, floors CliquetOption.Arguments moreArgs = args as CliquetOption.Arguments; - Utils.QL_REQUIRE(moreArgs != null,()=> "wrong engine type"); + Utils.QL_REQUIRE(moreArgs != null, () => "wrong engine type"); moreArgs.resetDates = new List(resetDates_); } private List resetDates_; //! %Arguments for cliquet option calculation // should inherit from a strikeless version of VanillaOption::arguments - public new class Arguments : OneAssetOption.Arguments + public new class Arguments : OneAssetOption.Arguments { public Arguments() { @@ -63,18 +63,18 @@ public Arguments() public override void validate() { PercentageStrikePayoff moneyness = payoff as PercentageStrikePayoff; - Utils.QL_REQUIRE(moneyness != null ,()=> "wrong payoff type"); - Utils.QL_REQUIRE(moneyness.strike() > 0.0,()=> "negative or zero moneyness given"); - Utils.QL_REQUIRE(accruedCoupon == null || accruedCoupon >= 0.0,()=> "negative accrued coupon"); - Utils.QL_REQUIRE(localCap == null || localCap >= 0.0,()=> "negative local cap"); - Utils.QL_REQUIRE(localFloor == null || localFloor >= 0.0,()=> "negative local floor"); - Utils.QL_REQUIRE(globalCap == null || globalCap >= 0.0,()=> "negative global cap"); - Utils.QL_REQUIRE(globalFloor == null || globalFloor >= 0.0,()=> "negative global floor"); - Utils.QL_REQUIRE(!resetDates.empty(),()=> "no reset dates given"); - for ( int i = 0; i < resetDates.Count; ++i ) + Utils.QL_REQUIRE(moneyness != null, () => "wrong payoff type"); + Utils.QL_REQUIRE(moneyness.strike() > 0.0, () => "negative or zero moneyness given"); + Utils.QL_REQUIRE(accruedCoupon == null || accruedCoupon >= 0.0, () => "negative accrued coupon"); + Utils.QL_REQUIRE(localCap == null || localCap >= 0.0, () => "negative local cap"); + Utils.QL_REQUIRE(localFloor == null || localFloor >= 0.0, () => "negative local floor"); + Utils.QL_REQUIRE(globalCap == null || globalCap >= 0.0, () => "negative global cap"); + Utils.QL_REQUIRE(globalFloor == null || globalFloor >= 0.0, () => "negative global floor"); + Utils.QL_REQUIRE(!resetDates.empty(), () => "no reset dates given"); + for (int i = 0; i < resetDates.Count; ++i) { - Utils.QL_REQUIRE( exercise.lastDate() > resetDates[i], () => "reset date greater or equal to maturity" ); - Utils.QL_REQUIRE( i == 0 || resetDates[i] > resetDates[i - 1], () => "unsorted reset dates" ); + Utils.QL_REQUIRE(exercise.lastDate() > resetDates[i], () => "reset date greater or equal to maturity"); + Utils.QL_REQUIRE(i == 0 || resetDates[i] > resetDates[i - 1], () => "unsorted reset dates"); } } public double? accruedCoupon { get; set; } @@ -87,7 +87,7 @@ public override void validate() } //! Cliquet %engine base class - public new class Engine : GenericEngine + public new class Engine : GenericEngine {} } diff --git a/src/QLNet/Instruments/CompositeInstrument.cs b/src/QLNet/Instruments/CompositeInstrument.cs index 84e58e2d2..a40d3b459 100644 --- a/src/QLNet/Instruments/CompositeInstrument.cs +++ b/src/QLNet/Instruments/CompositeInstrument.cs @@ -1,21 +1,21 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. using System.Collections.Generic; -using component= System.Collections.Generic.KeyValuePair; +using component = System.Collections.Generic.KeyValuePair; namespace QLNet { @@ -33,24 +33,26 @@ multiplied by a given factor. public class CompositeInstrument : Instrument { //! adds an instrument to the composite - public void add(Instrument instrument,double multiplier = 1.0) + public void add + (Instrument instrument, double multiplier = 1.0) { - components_.Add(new KeyValuePair(instrument,multiplier)); - instrument.registerWith(update); - update(); + components_.Add(new KeyValuePair(instrument, multiplier)); + instrument.registerWith(update); + update(); } //! shorts an instrument from the composite - public void subtract(Instrument instrument,double multiplier = 1.0) + public void subtract(Instrument instrument, double multiplier = 1.0) { - add( instrument, -multiplier ); + add + (instrument, -multiplier); } // Instrument interface public override bool isExpired() { foreach (component c in components_) { - if ( !c.Key.isExpired() ) + if (!c.Key.isExpired()) return false; } return true; diff --git a/src/QLNet/Instruments/CreditDefaultSwap.cs b/src/QLNet/Instruments/CreditDefaultSwap.cs index 57fb18fc3..000ac2958 100644 --- a/src/QLNet/Instruments/CreditDefaultSwap.cs +++ b/src/QLNet/Instruments/CreditDefaultSwap.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,7 +22,7 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public struct Protection + public struct Protection { public enum Side { Buyer, Seller } } @@ -50,7 +50,7 @@ public enum PricingModel /// /// public class CreditDefaultSwap : Instrument - { + { /// /// CDS quoted as running-spread only /// @@ -66,60 +66,60 @@ public class CreditDefaultSwap : Instrument /// The first date where a default event will trigger the contract. /// /// Day-count convention for accrual in last period - /// The protection seller pays the accrued scheduled current coupon at the start + /// The protection seller pays the accrued scheduled current coupon at the start /// of the contract. The rebate date is not provided but computed to be two days after protection start. public CreditDefaultSwap(Protection.Side side, - double notional, - double spread, - Schedule schedule, - BusinessDayConvention convention, - DayCounter dayCounter, - bool settlesAccrual = true, - bool paysAtDefaultTime = true, - Date protectionStart = null, - Claim claim = null, - DayCounter lastPeriodDayCounter = null, - bool rebatesAccrual = true) - { + double notional, + double spread, + Schedule schedule, + BusinessDayConvention convention, + DayCounter dayCounter, + bool settlesAccrual = true, + bool paysAtDefaultTime = true, + Date protectionStart = null, + Claim claim = null, + DayCounter lastPeriodDayCounter = null, + bool rebatesAccrual = true) + { side_ = side; - notional_ = notional; - upfront_ = null; - runningSpread_ = spread; - settlesAccrual_ =settlesAccrual; - paysAtDefaultTime_ = paysAtDefaultTime; - claim_ = claim; - protectionStart_ = protectionStart ?? schedule[0]; - - Utils.QL_REQUIRE( protectionStart_ <= schedule[0] || - schedule.rule() == DateGeneration.Rule.CDS || - schedule.rule() == DateGeneration.Rule.CDS2015 - , () => "protection can not start after accrual" ); - - leg_ = new FixedRateLeg(schedule) - .withLastPeriodDayCounter(lastPeriodDayCounter) - .withCouponRates(spread, dayCounter) - .withNotionals(notional) - .withPaymentAdjustment(convention); - - Date effectiveUpfrontDate = schedule.calendar().advance(protectionStart_, 2, TimeUnit.Days, convention); - // '2' is used above since the protection start is assumed to be on trade_date + 1 - if (rebatesAccrual) - { - FixedRateCoupon firstCoupon = leg_[0] as FixedRateCoupon; - - Date rebateDate = effectiveUpfrontDate; - accrualRebate_ = new SimpleCashFlow(firstCoupon.accruedAmount(protectionStart_),rebateDate); - } + notional_ = notional; + upfront_ = null; + runningSpread_ = spread; + settlesAccrual_ = settlesAccrual; + paysAtDefaultTime_ = paysAtDefaultTime; + claim_ = claim; + protectionStart_ = protectionStart ?? schedule[0]; + + Utils.QL_REQUIRE(protectionStart_ <= schedule[0] || + schedule.rule() == DateGeneration.Rule.CDS || + schedule.rule() == DateGeneration.Rule.CDS2015 + , () => "protection can not start after accrual"); + + leg_ = new FixedRateLeg(schedule) + .withLastPeriodDayCounter(lastPeriodDayCounter) + .withCouponRates(spread, dayCounter) + .withNotionals(notional) + .withPaymentAdjustment(convention); + + Date effectiveUpfrontDate = schedule.calendar().advance(protectionStart_, 2, TimeUnit.Days, convention); + // '2' is used above since the protection start is assumed to be on trade_date + 1 + if (rebatesAccrual) + { + FixedRateCoupon firstCoupon = leg_[0] as FixedRateCoupon; + + Date rebateDate = effectiveUpfrontDate; + accrualRebate_ = new SimpleCashFlow(firstCoupon.accruedAmount(protectionStart_), rebateDate); + } upfrontPayment_ = new SimpleCashFlow(0.0, effectiveUpfrontDate); - if (claim_ == null ) + if (claim_ == null) claim_ = new FaceValueClaim(); - claim_.registerWith(update); - maturity_ = schedule.dates().Last(); - } + claim_.registerWith(update); + maturity_ = schedule.dates().Last(); + } /// /// CDS quoted as upfront and running spread @@ -138,134 +138,134 @@ public CreditDefaultSwap(Protection.Side side, /// Settlement date for the upfront payment. /// /// Day-count convention for accrual in last period - /// The protection seller pays the accrued scheduled current coupon at the start + /// The protection seller pays the accrued scheduled current coupon at the start /// of the contract. The rebate date is not provided but computed to be two days after protection start. - public CreditDefaultSwap(Protection.Side side, - double notional, - double upfront, - double runningSpread, - Schedule schedule, - BusinessDayConvention convention, - DayCounter dayCounter, - bool settlesAccrual = true, - bool paysAtDefaultTime = true, - Date protectionStart = null, - Date upfrontDate = null, - Claim claim = null, - DayCounter lastPeriodDayCounter = null, + public CreditDefaultSwap(Protection.Side side, + double notional, + double upfront, + double runningSpread, + Schedule schedule, + BusinessDayConvention convention, + DayCounter dayCounter, + bool settlesAccrual = true, + bool paysAtDefaultTime = true, + Date protectionStart = null, + Date upfrontDate = null, + Claim claim = null, + DayCounter lastPeriodDayCounter = null, bool rebatesAccrual = true) - { - - side_ = side; - notional_ = notional; - upfront_ = upfront; - runningSpread_ = runningSpread; - settlesAccrual_ =settlesAccrual; - paysAtDefaultTime_ = paysAtDefaultTime; - claim_ = claim; - protectionStart_ = protectionStart ?? schedule[0]; - - Utils.QL_REQUIRE( protectionStart_ <= schedule[0] || - schedule.rule() == DateGeneration.Rule.CDS - , () => "protection can not start after accrual" ); - leg_ = new FixedRateLeg(schedule) - .withLastPeriodDayCounter(lastPeriodDayCounter) - .withCouponRates(runningSpread, dayCounter) - .withNotionals(notional) - .withPaymentAdjustment(convention); - - // If empty, adjust to T+3 standard settlement, alternatively add - // an arbitrary date to the constructor - Date effectiveUpfrontDate = upfrontDate == null ? - schedule.calendar().advance(protectionStart_, 2, TimeUnit.Days, convention) : upfrontDate; - // '2' is used above since the protection start is assumed to be - // on trade_date + 1 - upfrontPayment_ = new SimpleCashFlow(notional*upfront, effectiveUpfrontDate); - Utils.QL_REQUIRE(effectiveUpfrontDate >= protectionStart_, () => "upfront can not be due before contract start" ); - - if (rebatesAccrual) - { - FixedRateCoupon firstCoupon = leg_[0] as FixedRateCoupon; - // adjust to T+3 standard settlement, alternatively add - // an arbitrary date to the constructor - - Date rebateDate = effectiveUpfrontDate; - - accrualRebate_ = new SimpleCashFlow(firstCoupon.accruedAmount(protectionStart_),rebateDate); - } + { + + side_ = side; + notional_ = notional; + upfront_ = upfront; + runningSpread_ = runningSpread; + settlesAccrual_ = settlesAccrual; + paysAtDefaultTime_ = paysAtDefaultTime; + claim_ = claim; + protectionStart_ = protectionStart ?? schedule[0]; + + Utils.QL_REQUIRE(protectionStart_ <= schedule[0] || + schedule.rule() == DateGeneration.Rule.CDS + , () => "protection can not start after accrual"); + leg_ = new FixedRateLeg(schedule) + .withLastPeriodDayCounter(lastPeriodDayCounter) + .withCouponRates(runningSpread, dayCounter) + .withNotionals(notional) + .withPaymentAdjustment(convention); + + // If empty, adjust to T+3 standard settlement, alternatively add + // an arbitrary date to the constructor + Date effectiveUpfrontDate = upfrontDate == null ? + schedule.calendar().advance(protectionStart_, 2, TimeUnit.Days, convention) : upfrontDate; + // '2' is used above since the protection start is assumed to be + // on trade_date + 1 + upfrontPayment_ = new SimpleCashFlow(notional * upfront, effectiveUpfrontDate); + Utils.QL_REQUIRE(effectiveUpfrontDate >= protectionStart_, () => "upfront can not be due before contract start"); + + if (rebatesAccrual) + { + FixedRateCoupon firstCoupon = leg_[0] as FixedRateCoupon; + // adjust to T+3 standard settlement, alternatively add + // an arbitrary date to the constructor + + Date rebateDate = effectiveUpfrontDate; + + accrualRebate_ = new SimpleCashFlow(firstCoupon.accruedAmount(protectionStart_), rebateDate); + } if (claim_ == null) claim_ = new FaceValueClaim(); - claim_.registerWith(update); + claim_.registerWith(update); - maturity_ = schedule.dates().Last(); + maturity_ = schedule.dates().Last(); } /// /// Instrument interface /// - public override bool isExpired() - { - for (int i = leg_.Count; i > 0; --i) - if (!leg_[i - 1].hasOccurred()) - return false; - return true; - } - - public override void setupArguments(IPricingEngineArguments args) - { - CreditDefaultSwap.Arguments arguments = args as CreditDefaultSwap.Arguments; - Utils.QL_REQUIRE( arguments != null, () => "wrong argument type" ); - - arguments.side = side_; - arguments.notional = notional_; - arguments.leg = leg_; - arguments.upfrontPayment = upfrontPayment_; - arguments.accrualRebate = accrualRebate_; + public override bool isExpired() + { + for (int i = leg_.Count; i > 0; --i) + if (!leg_[i - 1].hasOccurred()) + return false; + return true; + } + + public override void setupArguments(IPricingEngineArguments args) + { + CreditDefaultSwap.Arguments arguments = args as CreditDefaultSwap.Arguments; + Utils.QL_REQUIRE(arguments != null, () => "wrong argument type"); + + arguments.side = side_; + arguments.notional = notional_; + arguments.leg = leg_; + arguments.upfrontPayment = upfrontPayment_; + arguments.accrualRebate = accrualRebate_; arguments.settlesAccrual = settlesAccrual_; - arguments.paysAtDefaultTime = paysAtDefaultTime_; - arguments.claim = claim_; - arguments.upfront = upfront_; - arguments.spread = runningSpread_; - arguments.protectionStart = protectionStart_; - arguments.maturity = maturity_; + arguments.paysAtDefaultTime = paysAtDefaultTime_; + arguments.claim = claim_; + arguments.upfront = upfront_; + arguments.spread = runningSpread_; + arguments.protectionStart = protectionStart_; + arguments.maturity = maturity_; } - public override void fetchResults(IPricingEngineResults r) - { - base.fetchResults(r); + public override void fetchResults(IPricingEngineResults r) + { + base.fetchResults(r); CreditDefaultSwap.Results results = r as CreditDefaultSwap.Results; - Utils.QL_REQUIRE( results != null, () => "wrong result type" ); - - fairSpread_ = results.fairSpread; - fairUpfront_ = results.fairUpfront; - couponLegBPS_ = results.couponLegBPS; - couponLegNPV_ = results.couponLegNPV; - defaultLegNPV_ = results.defaultLegNPV; - upfrontNPV_ = results.upfrontNPV; - upfrontBPS_ = results.upfrontBPS; - accrualRebateNPV_ = results.accrualRebateNPV; + Utils.QL_REQUIRE(results != null, () => "wrong result type"); + + fairSpread_ = results.fairSpread; + fairUpfront_ = results.fairUpfront; + couponLegBPS_ = results.couponLegBPS; + couponLegNPV_ = results.couponLegNPV; + defaultLegNPV_ = results.defaultLegNPV; + upfrontNPV_ = results.upfrontNPV; + upfrontBPS_ = results.upfrontBPS; + accrualRebateNPV_ = results.accrualRebateNPV; } // Inspectors - public Protection.Side side() { return side_; } - public double? notional() { return notional_; } - public double runningSpread() { return runningSpread_; } - public double? upfront() { return upfront_; } - public bool settlesAccrual() { return settlesAccrual_; } - public bool paysAtDefaultTime() { return paysAtDefaultTime_; } - public List coupons() { return leg_; } + public Protection.Side side() { return side_; } + public double? notional() { return notional_; } + public double runningSpread() { return runningSpread_; } + public double? upfront() { return upfront_; } + public bool settlesAccrual() { return settlesAccrual_; } + public bool paysAtDefaultTime() { return paysAtDefaultTime_; } + public List coupons() { return leg_; } /// /// The first date for which defaults will trigger the contract /// /// - public Date protectionStartDate() { return protectionStart_; } + public Date protectionStartDate() { return protectionStart_; } /// /// The last date for which defaults will trigger the contract /// /// public Date protectionEndDate() {return ((Coupon)(leg_.Last())).accrualEndDate();} - public bool rebatesAccrual() {return accrualRebate_ != null;} + public bool rebatesAccrual() {return accrualRebate_ != null;} // Results /// /// Returns the upfront spread that, given the running spread @@ -274,11 +274,11 @@ public override void fetchResults(IPricingEngineResults r) /// /// public double fairUpfront() - { - calculate(); - Utils.QL_REQUIRE( fairUpfront_ != null, () => "fair upfront not available" ); - return fairUpfront_.Value; - } + { + calculate(); + Utils.QL_REQUIRE(fairUpfront_ != null, () => "fair upfront not available"); + return fairUpfront_.Value; + } /// /// Returns the running spread that, given the quoted recovery /// rate, will make the running-only CDS have an NPV of 0. @@ -288,55 +288,55 @@ public double fairUpfront() /// account, even if one was given. /// /// - public double fairSpread() - { - calculate(); - Utils.QL_REQUIRE( fairSpread_ != null, () => "fair spread not available" ); - return fairSpread_.Value; - } + public double fairSpread() + { + calculate(); + Utils.QL_REQUIRE(fairSpread_ != null, () => "fair spread not available"); + return fairSpread_.Value; + } /*! Returns the variation of the fixed-leg value given a one-basis-point change in the running spread. */ - public double couponLegBPS() - { - calculate(); - Utils.QL_REQUIRE( couponLegBPS_ != null, () => "coupon-leg BPS not available" ); - return couponLegBPS_.Value; - } - - public double upfrontBPS() - { - calculate(); - Utils.QL_REQUIRE( upfrontBPS_ != null, () => "upfront BPS not available" ); - return upfrontBPS_.Value; - } - - public double couponLegNPV() - { - calculate(); - Utils.QL_REQUIRE( couponLegNPV_ != null, () => "coupon-leg NPV not available" ); - return couponLegNPV_.Value; - } - - public double defaultLegNPV() - { - calculate(); - Utils.QL_REQUIRE( defaultLegNPV_ != null, () => "default-leg NPV not available" ); - return defaultLegNPV_.Value; - } - - public double upfrontNPV() - { - calculate(); - Utils.QL_REQUIRE( upfrontNPV_ != null, () => "upfront NPV not available" ); - return upfrontNPV_.Value; - } - - public double accrualRebateNPV() - { - calculate(); - Utils.QL_REQUIRE(accrualRebateNPV_ != null,()=> "accrual Rebate NPV not available"); - return accrualRebateNPV_.Value; + public double couponLegBPS() + { + calculate(); + Utils.QL_REQUIRE(couponLegBPS_ != null, () => "coupon-leg BPS not available"); + return couponLegBPS_.Value; + } + + public double upfrontBPS() + { + calculate(); + Utils.QL_REQUIRE(upfrontBPS_ != null, () => "upfront BPS not available"); + return upfrontBPS_.Value; + } + + public double couponLegNPV() + { + calculate(); + Utils.QL_REQUIRE(couponLegNPV_ != null, () => "coupon-leg NPV not available"); + return couponLegNPV_.Value; + } + + public double defaultLegNPV() + { + calculate(); + Utils.QL_REQUIRE(defaultLegNPV_ != null, () => "default-leg NPV not available"); + return defaultLegNPV_.Value; + } + + public double upfrontNPV() + { + calculate(); + Utils.QL_REQUIRE(upfrontNPV_ != null, () => "upfront NPV not available"); + return upfrontNPV_.Value; + } + + public double accrualRebateNPV() + { + calculate(); + Utils.QL_REQUIRE(accrualRebateNPV_ != null, () => "accrual Rebate NPV not available"); + return accrualRebateNPV_.Value; } /// @@ -365,42 +365,42 @@ public double accrualRebateNPV() /// /// /// - public double impliedHazardRate(double targetNPV, - Handle discountCurve, - DayCounter dayCounter, - double recoveryRate = 0.4, - double accuracy = 1.0e-6, + public double impliedHazardRate(double targetNPV, + Handle discountCurve, + DayCounter dayCounter, + double recoveryRate = 0.4, + double accuracy = 1.0e-6, PricingModel model = PricingModel.Midpoint) - { - SimpleQuote flatRate = new SimpleQuote(0.0); - - Handle probability = new Handle( - new FlatHazardRate(0, new WeekendsOnly(),new Handle(flatRate), dayCounter)); - - IPricingEngine engine = null; - switch (model) - { - case PricingModel.Midpoint: - engine = new MidPointCdsEngine(probability, recoveryRate, discountCurve); - break; - case PricingModel.ISDA: - engine = new IsdaCdsEngine(probability, recoveryRate, discountCurve); - break; - default: - Utils.QL_FAIL("unknown CDS pricing model: " + model); - break; - } + { + SimpleQuote flatRate = new SimpleQuote(0.0); + + Handle probability = new Handle( + new FlatHazardRate(0, new WeekendsOnly(), new Handle(flatRate), dayCounter)); + + IPricingEngine engine = null; + switch (model) + { + case PricingModel.Midpoint: + engine = new MidPointCdsEngine(probability, recoveryRate, discountCurve); + break; + case PricingModel.ISDA: + engine = new IsdaCdsEngine(probability, recoveryRate, discountCurve); + break; + default: + Utils.QL_FAIL("unknown CDS pricing model: " + model); + break; + } setupArguments(engine.getArguments()); CreditDefaultSwap.Results results = engine.getResults() as CreditDefaultSwap.Results; ObjectiveFunction f = new ObjectiveFunction(targetNPV, flatRate, engine, results); - double guess = runningSpread_ / (1 - recoveryRate) * 365.0/ 360.0; - double step = guess*0.1; + double guess = runningSpread_ / (1 - recoveryRate) * 365.0 / 360.0; + double step = guess * 0.1; return new Brent().solve(f, accuracy, guess, step); - } + } /// /// Conventional/standard upfront-to-spread conversion @@ -438,50 +438,50 @@ public double impliedHazardRate(double targetNPV, /// /// /// - public double? conventionalSpread(double conventionalRecovery, - Handle discountCurve, - DayCounter dayCounter, - PricingModel model = PricingModel.Midpoint) - { - SimpleQuote flatRate = new SimpleQuote(0.0); - - Handle probability = new Handle( - new FlatHazardRate(0, new WeekendsOnly(),new Handle(flatRate), dayCounter)); - - IPricingEngine engine = null; - switch (model) - { - case PricingModel.Midpoint: - engine = new MidPointCdsEngine(probability, conventionalRecovery, discountCurve); - break; - case PricingModel.ISDA: - engine = new IsdaCdsEngine(probability, conventionalRecovery, discountCurve); - break; - default: - Utils.QL_FAIL("unknown CDS pricing model: " + model); - break; - } - + public double? conventionalSpread(double conventionalRecovery, + Handle discountCurve, + DayCounter dayCounter, + PricingModel model = PricingModel.Midpoint) + { + SimpleQuote flatRate = new SimpleQuote(0.0); + + Handle probability = new Handle( + new FlatHazardRate(0, new WeekendsOnly(), new Handle(flatRate), dayCounter)); + + IPricingEngine engine = null; + switch (model) + { + case PricingModel.Midpoint: + engine = new MidPointCdsEngine(probability, conventionalRecovery, discountCurve); + break; + case PricingModel.ISDA: + engine = new IsdaCdsEngine(probability, conventionalRecovery, discountCurve); + break; + default: + Utils.QL_FAIL("unknown CDS pricing model: " + model); + break; + } + setupArguments(engine.getArguments()); - CreditDefaultSwap.Results results = engine.getResults() as CreditDefaultSwap.Results; + CreditDefaultSwap.Results results = engine.getResults() as CreditDefaultSwap.Results; - ObjectiveFunction f = new ObjectiveFunction(0.0, flatRate, engine, results); - double guess = runningSpread_ / (1 - conventionalRecovery) * 365.0/ 360.0; - double step = guess * 0.1; + ObjectiveFunction f = new ObjectiveFunction(0.0, flatRate, engine, results); + double guess = runningSpread_ / (1 - conventionalRecovery) * 365.0 / 360.0; + double step = guess * 0.1; - new Brent().solve(f, 1e-9, guess, step); + new Brent().solve(f, 1e-9, guess, step); return results.fairSpread; - } + } // Instrument interface - protected override void setupExpired() - { - base.setupExpired(); - fairSpread_ = fairUpfront_ = 0.0; - couponLegBPS_ = upfrontBPS_ = 0.0; - couponLegNPV_ = defaultLegNPV_ = upfrontNPV_ = 0.0; - } + protected override void setupExpired() + { + base.setupExpired(); + fairSpread_ = fairUpfront_ = 0.0; + couponLegBPS_ = upfrontBPS_ = 0.0; + couponLegNPV_ = defaultLegNPV_ = upfrontNPV_ = 0.0; + } // data members protected Protection.Side side_; protected double? notional_; @@ -491,104 +491,104 @@ protected override void setupExpired() protected Claim claim_; protected List leg_; protected CashFlow upfrontPayment_; - protected CashFlow accrualRebate_; + protected CashFlow accrualRebate_; protected Date protectionStart_; - protected Date maturity_; + protected Date maturity_; // results protected double? fairUpfront_; protected double? fairSpread_; protected double? couponLegBPS_, couponLegNPV_; protected double? upfrontBPS_, upfrontNPV_; protected double? defaultLegNPV_; - protected double? accrualRebateNPV_; - - - private class ObjectiveFunction : ISolver1d - { - public ObjectiveFunction(double target, SimpleQuote quote, IPricingEngine engine, CreditDefaultSwap.Results results) - { - target_ = target; - quote_ = quote; - engine_ = engine; - results_ = results; - } - - public override double value(double guess) - { - quote_.setValue(guess); - engine_.calculate(); - return results_.value.GetValueOrDefault() - target_; - } - - private double target_; - private SimpleQuote quote_; - private IPricingEngine engine_; - private CreditDefaultSwap.Results results_; - - } - - public class Arguments : IPricingEngineArguments - { - public Arguments() - { - side = (Protection.Side)(-1); - notional = null; - spread = null; - } - - public Protection.Side side { get; set; } + protected double? accrualRebateNPV_; + + + private class ObjectiveFunction : ISolver1d + { + public ObjectiveFunction(double target, SimpleQuote quote, IPricingEngine engine, CreditDefaultSwap.Results results) + { + target_ = target; + quote_ = quote; + engine_ = engine; + results_ = results; + } + + public override double value(double guess) + { + quote_.setValue(guess); + engine_.calculate(); + return results_.value.GetValueOrDefault() - target_; + } + + private double target_; + private SimpleQuote quote_; + private IPricingEngine engine_; + private CreditDefaultSwap.Results results_; + + } + + public class Arguments : IPricingEngineArguments + { + public Arguments() + { + side = (Protection.Side)(-1); + notional = null; + spread = null; + } + + public Protection.Side side { get; set; } public double? notional { get; set; } public double? upfront { get; set; } public double? spread { get; set; } public List leg { get; set; } public CashFlow upfrontPayment { get; set; } - public CashFlow accrualRebate { get; set; } + public CashFlow accrualRebate { get; set; } public bool settlesAccrual { get; set; } public bool paysAtDefaultTime { get; set; } public Claim claim { get; set; } public Date protectionStart { get; set; } - public Date maturity { get; set; } + public Date maturity { get; set; } public void validate() - { - Utils.QL_REQUIRE( side != (Protection.Side)( -1 ), () => "side not set" ); - Utils.QL_REQUIRE( notional != null, () => "notional not set" ); - Utils.QL_REQUIRE( notional.IsNotEqual(0.0), () => "null notional set" ); - Utils.QL_REQUIRE( spread != null, () => "spread not set" ); - Utils.QL_REQUIRE( !leg.empty(), () => "coupons not set" ); - Utils.QL_REQUIRE( upfrontPayment != null, () => "upfront payment not set" ); - Utils.QL_REQUIRE( claim != null, () => "claim not set" ); - Utils.QL_REQUIRE( protectionStart != null, () => "protection start date not set" ); - Utils.QL_REQUIRE(maturity != null,()=> "maturity date not set"); + { + Utils.QL_REQUIRE(side != (Protection.Side)(-1), () => "side not set"); + Utils.QL_REQUIRE(notional != null, () => "notional not set"); + Utils.QL_REQUIRE(notional.IsNotEqual(0.0), () => "null notional set"); + Utils.QL_REQUIRE(spread != null, () => "spread not set"); + Utils.QL_REQUIRE(!leg.empty(), () => "coupons not set"); + Utils.QL_REQUIRE(upfrontPayment != null, () => "upfront payment not set"); + Utils.QL_REQUIRE(claim != null, () => "claim not set"); + Utils.QL_REQUIRE(protectionStart != null, () => "protection start date not set"); + Utils.QL_REQUIRE(maturity != null, () => "maturity date not set"); } - } + } - public new class Results : Instrument.Results - { - public double? fairSpread { get; set; } + public new class Results : Instrument.Results + { + public double? fairSpread { get; set; } public double? fairUpfront { get; set; } public double? couponLegBPS { get; set; } public double? couponLegNPV { get; set; } public double? defaultLegNPV { get; set; } public double? upfrontBPS { get; set; } public double? upfrontNPV { get; set; } - public double? accrualRebateNPV { get; set; } + public double? accrualRebateNPV { get; set; } public override void reset() - { - base.reset(); - fairSpread = null; - fairUpfront = null; - couponLegBPS = null; - couponLegNPV = null; - defaultLegNPV = null; - upfrontBPS = null; - upfrontNPV = null; - accrualRebateNPV = null; + { + base.reset(); + fairSpread = null; + fairUpfront = null; + couponLegBPS = null; + couponLegNPV = null; + defaultLegNPV = null; + upfrontBPS = null; + upfrontNPV = null; + accrualRebateNPV = null; } - } + } - public abstract class Engine : GenericEngine - {} + public abstract class Engine : GenericEngine + {} - } + } } diff --git a/src/QLNet/Instruments/DividendBarrierOption.cs b/src/QLNet/Instruments/DividendBarrierOption.cs index 42f31402a..39bfa1f7b 100644 --- a/src/QLNet/Instruments/DividendBarrierOption.cs +++ b/src/QLNet/Instruments/DividendBarrierOption.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,24 +22,24 @@ namespace QLNet /*! \ingroup instruments */ public class DividendBarrierOption : BarrierOption { - public DividendBarrierOption( Barrier.Type barrierType, - double barrier, - double rebate, - StrikedTypePayoff payoff, - Exercise exercise, - List dividendDates, - List dividends) - :base(barrierType, barrier, rebate, payoff, exercise) + public DividendBarrierOption(Barrier.Type barrierType, + double barrier, + double rebate, + StrikedTypePayoff payoff, + Exercise exercise, + List dividendDates, + List dividends) + : base(barrierType, barrier, rebate, payoff, exercise) { - cashFlow_ = Utils.DividendVector( dividendDates, dividends ); + cashFlow_ = Utils.DividendVector(dividendDates, dividends); } - public override void setupArguments( IPricingEngineArguments args ) + public override void setupArguments(IPricingEngineArguments args) { base.setupArguments(args); DividendBarrierOption.Arguments arguments = args as DividendBarrierOption.Arguments; - Utils.QL_REQUIRE(arguments != null,()=> "wrong engine type"); + Utils.QL_REQUIRE(arguments != null, () => "wrong engine type"); arguments.cashFlow = cashFlow_; } @@ -47,13 +47,13 @@ public override void setupArguments( IPricingEngineArguments args ) private DividendSchedule cashFlow_; - //! %Arguments for dividend barrier option calculation - public new class Arguments : BarrierOption.Arguments + //! %Arguments for dividend barrier option calculation + public new class Arguments : BarrierOption.Arguments { public DividendSchedule cashFlow { get; set; } public Arguments() { - cashFlow = new DividendSchedule(); + cashFlow = new DividendSchedule(); } public override void validate() { @@ -61,18 +61,18 @@ public override void validate() Date exerciseDate = exercise.lastDate(); - for (int i = 0; i < cashFlow.Count; i++) + for (int i = 0; i < cashFlow.Count; i++) { - Utils.QL_REQUIRE(cashFlow[i].date() <= exerciseDate,()=> - "the " + (i+1) + " dividend date ("+ cashFlow[i].date()+ ") is later than the exercise date (" - + exerciseDate + ")"); + Utils.QL_REQUIRE(cashFlow[i].date() <= exerciseDate, () => + "the " + (i + 1) + " dividend date (" + cashFlow[i].date() + ") is later than the exercise date (" + + exerciseDate + ")"); } } } //! %Dividend-barrier-option %engine base class - public new class Engine : GenericEngine {} + public new class Engine : GenericEngine {} } - + } diff --git a/src/QLNet/Instruments/DividendSchedule.cs b/src/QLNet/Instruments/DividendSchedule.cs index 1571138e5..323f38707 100644 --- a/src/QLNet/Instruments/DividendSchedule.cs +++ b/src/QLNet/Instruments/DividendSchedule.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Instruments/DividendVanillaOption.cs b/src/QLNet/Instruments/DividendVanillaOption.cs index 62c45b166..5e1f9c210 100644 --- a/src/QLNet/Instruments/DividendVanillaOption.cs +++ b/src/QLNet/Instruments/DividendVanillaOption.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,84 +20,88 @@ under the terms of the QLNet license. You should have received a using System; using System.Collections.Generic; -namespace QLNet { - //! Single-asset vanilla option (no barriers) with discrete dividends - /*! \ingroup instruments */ - public class DividendVanillaOption : OneAssetOption { - private DividendSchedule cashFlow_; - - public DividendVanillaOption(StrikedTypePayoff payoff, Exercise exercise, - List dividendDates, List dividends) - : base(payoff, exercise) { - cashFlow_ = Utils.DividendVector(dividendDates, dividends); - } - - - /*! \warning see VanillaOption for notes on implied-volatility - calculation. - */ - public double impliedVolatility(double targetValue, GeneralizedBlackScholesProcess process, - double accuracy = 1.0e-4, int maxEvaluations = 100, double minVol = 1.0e-7, double maxVol = 4.0) - { - Utils.QL_REQUIRE(!isExpired(),()=> "option expired"); - - SimpleQuote volQuote = new SimpleQuote(); - - GeneralizedBlackScholesProcess newProcess = ImpliedVolatilityHelper.clone(process, volQuote); - - // engines are built-in for the time being - IPricingEngine engine = null; - switch (exercise_.type()) - { - case Exercise.Type.European: - engine = new AnalyticDividendEuropeanEngine(newProcess); - break; - case Exercise.Type.American: - engine = new FDDividendAmericanEngine(newProcess); - break; - case Exercise.Type.Bermudan: - Utils.QL_FAIL("engine not available for Bermudan option with dividends"); - break; - default: - Utils.QL_FAIL("unknown exercise type"); - break; - } - - return ImpliedVolatilityHelper.calculate(this, engine, volQuote, targetValue, accuracy, - maxEvaluations, minVol, maxVol); - } - - - public override void setupArguments(IPricingEngineArguments args) { - base.setupArguments(args); - - Arguments arguments = args as Arguments; - Utils.QL_REQUIRE(arguments != null,()=> "wrong engine type"); - - arguments.cashFlow = cashFlow_; - } - - //! %Arguments for dividend vanilla option calculation - public new class Arguments : OneAssetOption.Arguments - { - public DividendSchedule cashFlow { get; set; } - - public override void validate() - { - base.validate(); - - Date exerciseDate = exercise.lastDate(); - - for (int i = 0; i < cashFlow.Count; i++) - { - Utils.QL_REQUIRE(cashFlow[i].date() <= exerciseDate, () => - " dividend date (" + cashFlow[i].date() + ") is later than the exercise date (" + exerciseDate + - ")"); - } - } - } - - //! %Dividend-vanilla-option %engine base class - public new class Engine : GenericEngine { } - } +namespace QLNet +{ + //! Single-asset vanilla option (no barriers) with discrete dividends + /*! \ingroup instruments */ + public class DividendVanillaOption : OneAssetOption + { + private DividendSchedule cashFlow_; + + public DividendVanillaOption(StrikedTypePayoff payoff, Exercise exercise, + List dividendDates, List dividends) + : base(payoff, exercise) + { + cashFlow_ = Utils.DividendVector(dividendDates, dividends); + } + + + /*! \warning see VanillaOption for notes on implied-volatility + calculation. + */ + public double impliedVolatility(double targetValue, GeneralizedBlackScholesProcess process, + double accuracy = 1.0e-4, int maxEvaluations = 100, double minVol = 1.0e-7, double maxVol = 4.0) + { + Utils.QL_REQUIRE(!isExpired(), () => "option expired"); + + SimpleQuote volQuote = new SimpleQuote(); + + GeneralizedBlackScholesProcess newProcess = ImpliedVolatilityHelper.clone(process, volQuote); + + // engines are built-in for the time being + IPricingEngine engine = null; + switch (exercise_.type()) + { + case Exercise.Type.European: + engine = new AnalyticDividendEuropeanEngine(newProcess); + break; + case Exercise.Type.American: + engine = new FDDividendAmericanEngine(newProcess); + break; + case Exercise.Type.Bermudan: + Utils.QL_FAIL("engine not available for Bermudan option with dividends"); + break; + default: + Utils.QL_FAIL("unknown exercise type"); + break; + } + + return ImpliedVolatilityHelper.calculate(this, engine, volQuote, targetValue, accuracy, + maxEvaluations, minVol, maxVol); + } + + + public override void setupArguments(IPricingEngineArguments args) + { + base.setupArguments(args); + + Arguments arguments = args as Arguments; + Utils.QL_REQUIRE(arguments != null, () => "wrong engine type"); + + arguments.cashFlow = cashFlow_; + } + + //! %Arguments for dividend vanilla option calculation + public new class Arguments : OneAssetOption.Arguments + { + public DividendSchedule cashFlow { get; set; } + + public override void validate() + { + base.validate(); + + Date exerciseDate = exercise.lastDate(); + + for (int i = 0; i < cashFlow.Count; i++) + { + Utils.QL_REQUIRE(cashFlow[i].date() <= exerciseDate, () => + " dividend date (" + cashFlow[i].date() + ") is later than the exercise date (" + exerciseDate + + ")"); + } + } + } + + //! %Dividend-vanilla-option %engine base class + public new class Engine : GenericEngine { } + } } diff --git a/src/QLNet/Instruments/DoubleBarrierOption.cs b/src/QLNet/Instruments/DoubleBarrierOption.cs index 23a2eeb34..03909728e 100644 --- a/src/QLNet/Instruments/DoubleBarrierOption.cs +++ b/src/QLNet/Instruments/DoubleBarrierOption.cs @@ -1,31 +1,31 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. namespace QLNet { - public struct DoubleBarrier + public struct DoubleBarrier { - public enum Type + public enum Type { KnockIn, KnockOut, KIKO, //! lower barrier KI, upper KO KOKI //! lower barrier KO, upper KI } - } + } //! %Double Barrier option on a single asset. /*! The analytic pricing engine will be used if none if passed. @@ -34,27 +34,27 @@ public enum Type */ public class DoubleBarrierOption : OneAssetOption { - + public DoubleBarrierOption(DoubleBarrier.Type barrierType, double barrier_lo, double barrier_hi, double rebate, StrikedTypePayoff payoff, Exercise exercise) - :base(payoff, exercise) + : base(payoff, exercise) { barrierType_ = barrierType; barrier_lo_ = barrier_lo; barrier_hi_ = barrier_hi; rebate_ = rebate; } - + public override void setupArguments(IPricingEngineArguments args) { base.setupArguments(args); DoubleBarrierOption.Arguments moreArgs = args as DoubleBarrierOption.Arguments; - Utils.QL_REQUIRE(moreArgs != null,()=> "wrong argument type"); + Utils.QL_REQUIRE(moreArgs != null, () => "wrong argument type"); moreArgs.barrierType = barrierType_; moreArgs.barrier_lo = barrier_lo_; moreArgs.barrier_hi = barrier_hi_; @@ -64,23 +64,23 @@ public override void setupArguments(IPricingEngineArguments args) /*! \warning see VanillaOption for notes on implied-volatility calculation. */ - public double impliedVolatility( double targetValue, - GeneralizedBlackScholesProcess process, - double accuracy = 1.0e-4, - int maxEvaluations = 100, - double minVol = 1.0e-7, - double maxVol = 4.0) + public double impliedVolatility(double targetValue, + GeneralizedBlackScholesProcess process, + double accuracy = 1.0e-4, + int maxEvaluations = 100, + double minVol = 1.0e-7, + double maxVol = 4.0) { - Utils.QL_REQUIRE(!isExpired(),()=> "option expired"); + Utils.QL_REQUIRE(!isExpired(), () => "option expired"); - SimpleQuote volQuote=new SimpleQuote(); + SimpleQuote volQuote = new SimpleQuote(); GeneralizedBlackScholesProcess newProcess = ImpliedVolatilityHelper.clone(process, volQuote); // engines are built-in for the time being IPricingEngine engine = null; - - switch (exercise_.type()) + + switch (exercise_.type()) { case Exercise.Type.European: engine = new AnalyticDoubleBarrierEngine(newProcess); @@ -94,10 +94,10 @@ public double impliedVolatility( double targetValue, break; } - return ImpliedVolatilityHelper.calculate(this,engine,volQuote,targetValue,accuracy,maxEvaluations,minVol, maxVol); + return ImpliedVolatilityHelper.calculate(this, engine, volQuote, targetValue, accuracy, maxEvaluations, minVol, maxVol); } - + // arguments protected DoubleBarrier.Type barrierType_; protected double barrier_lo_; @@ -105,7 +105,7 @@ public double impliedVolatility( double targetValue, protected double rebate_; //! %Arguments for double barrier option calculation - public new class Arguments : OneAssetOption.Arguments + public new class Arguments : OneAssetOption.Arguments { public Arguments() { @@ -124,17 +124,17 @@ public override void validate() Utils.QL_REQUIRE(barrierType == DoubleBarrier.Type.KnockIn || barrierType == DoubleBarrier.Type.KnockOut || barrierType == DoubleBarrier.Type.KIKO || - barrierType == DoubleBarrier.Type.KOKI,()=> + barrierType == DoubleBarrier.Type.KOKI, () => "Invalid barrier type"); - Utils.QL_REQUIRE(barrier_lo != null,()=> "no low barrier given"); - Utils.QL_REQUIRE(barrier_hi !=null,()=> "no high barrier given"); - Utils.QL_REQUIRE(rebate != null,()=> "no rebate given"); + Utils.QL_REQUIRE(barrier_lo != null, () => "no low barrier given"); + Utils.QL_REQUIRE(barrier_hi != null, () => "no high barrier given"); + Utils.QL_REQUIRE(rebate != null, () => "no rebate given"); } } //! %Double-Barrier-option %engine base class - public new class Engine : GenericEngine + public new class Engine : GenericEngine { protected bool triggered(double underlying) { diff --git a/src/QLNet/Instruments/EuropeanOption.cs b/src/QLNet/Instruments/EuropeanOption.cs index a2e4e5bdf..197fd6213 100644 --- a/src/QLNet/Instruments/EuropeanOption.cs +++ b/src/QLNet/Instruments/EuropeanOption.cs @@ -1,26 +1,28 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { - //! European option on a single asset - /*! \ingroup instruments */ - public class EuropeanOption : VanillaOption { - public EuropeanOption(StrikedTypePayoff payoff, Exercise exercise) : base(payoff, exercise) {} - } +namespace QLNet +{ + //! European option on a single asset + /*! \ingroup instruments */ + public class EuropeanOption : VanillaOption + { + public EuropeanOption(StrikedTypePayoff payoff, Exercise exercise) : base(payoff, exercise) {} + } } diff --git a/src/QLNet/Instruments/fixedratebondforward.cs b/src/QLNet/Instruments/FixedRateBondForward.cs similarity index 90% rename from src/QLNet/Instruments/fixedratebondforward.cs rename to src/QLNet/Instruments/FixedRateBondForward.cs index 1a8e2b188..cea432c81 100644 --- a/src/QLNet/Instruments/fixedratebondforward.cs +++ b/src/QLNet/Instruments/FixedRateBondForward.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -76,13 +76,13 @@ NPV of the contract via NPV(). constructor is irrelevant and will be ignored. */ public FixedRateBondForward(Date valueDate, Date maturityDate, Position.Type type, double strike, - int settlementDays, - DayCounter dayCounter, Calendar calendar, BusinessDayConvention businessDayConvention, - FixedRateBond fixedCouponBond, - Handle discountCurve, - Handle incomeDiscountCurve) + int settlementDays, + DayCounter dayCounter, Calendar calendar, BusinessDayConvention businessDayConvention, + FixedRateBond fixedCouponBond, + Handle discountCurve, + Handle incomeDiscountCurve) : base(dayCounter, calendar, businessDayConvention, settlementDays, new ForwardTypePayoff(type, strike), - valueDate, maturityDate, discountCurve) + valueDate, maturityDate, discountCurve) { fixedCouponBond_ = fixedCouponBond; incomeDiscountCurve_ = incomeDiscountCurve; diff --git a/src/QLNet/Instruments/FloatFloatSwap.cs b/src/QLNet/Instruments/FloatFloatSwap.cs new file mode 100644 index 000000000..c9f650075 --- /dev/null +++ b/src/QLNet/Instruments/FloatFloatSwap.cs @@ -0,0 +1,671 @@ +// Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) +// +// This file is part of QLNet Project https://github.com/amaggiulli/qlnet +// QLNet is free software: you can redistribute it and/or modify it +// under the terms of the QLNet license. You should have received a +// copy of the license along with this program; if not, license is +// available at . +// +// QLNet is a based on QuantLib, a free-software/open-source library +// for financial quantitative analysts and developers - http://quantlib.org/ +// The QuantLib license is available online at http://quantlib.org/license.shtml. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the license for more details. +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QLNet +{ + /// + /// float float swap + /// + public class FloatFloatSwap : Swap + { + public FloatFloatSwap(VanillaSwap.Type type, + double nominal1, + double nominal2, + Schedule schedule1, + InterestRateIndex index1, + DayCounter dayCount1, + Schedule schedule2, + InterestRateIndex index2, + DayCounter dayCount2, + bool intermediateCapitalExchange = false, + bool finalCapitalExchange = false, + double gearing1 = 1.0, + double spread1 = 0.0, + double? cappedRate1 = null, + double? flooredRate1 = null, + double gearing2 = 1.0, + double spread2 = 0.0, + double? cappedRate2 = null, + double? flooredRate2 = null, + BusinessDayConvention? paymentConvention1 = null, + BusinessDayConvention? paymentConvention2 = null) + : base(2) + { + type_ = type; + nominal1_ = new InitializedList (schedule1.size() - 1, nominal1); + nominal2_ = new InitializedList (schedule2.size() - 1, nominal2); + schedule1_ = schedule1; + schedule2_ = schedule2; + index1_ = index1; + index2_ = index2; + gearing1_ = new InitializedList(schedule1.size() - 1, gearing1); + gearing2_ = new InitializedList(schedule2.size() - 1, gearing2); + spread1_ = new InitializedList(schedule1.size() - 1, spread1); + spread2_ = new InitializedList(schedule2.size() - 1, spread2); + cappedRate1_ = new InitializedList < double? >(schedule1.size() - 1, cappedRate1); + flooredRate1_ = new InitializedList < double? >(schedule1.size() - 1, flooredRate1); + cappedRate2_ = new InitializedList < double? >(schedule2.size() - 1, cappedRate2); + flooredRate2_ = new InitializedList < double? >(schedule2.size() - 1, flooredRate2); + dayCount1_ = dayCount1; dayCount2_ = dayCount2; + intermediateCapitalExchange_ = intermediateCapitalExchange; + finalCapitalExchange_ = finalCapitalExchange; + + init(paymentConvention1, paymentConvention2); + } + + public FloatFloatSwap(VanillaSwap.Type type, + List nominal1, + List nominal2, + Schedule schedule1, + InterestRateIndex index1, + DayCounter dayCount1, + Schedule schedule2, + InterestRateIndex index2, + DayCounter dayCount2, + bool intermediateCapitalExchange = false, + bool finalCapitalExchange = false, + List gearing1 = null, + List spread1 = null, + List < double? > cappedRate1 = null, + List < double? > flooredRate1 = null, + List gearing2 = null, + List spread2 = null, + List < double? > cappedRate2 = null, + List < double? > flooredRate2 = null, + BusinessDayConvention? paymentConvention1 = null, + BusinessDayConvention? paymentConvention2 = null) + : base(2) + { + type_ = type; + nominal1_ = nominal1; + nominal2_ = nominal2; + schedule1_ = schedule1; + schedule2_ = schedule2; + index1_ = index1; + index2_ = index2; + gearing1_ = gearing1; + gearing2_ = gearing2; + spread1_ = spread1; + spread2_ = spread2; + cappedRate1_ = cappedRate1; + flooredRate1_ = flooredRate1; + cappedRate2_ = cappedRate2; + flooredRate2_ = flooredRate2; + dayCount1_ = dayCount1; + dayCount2_ = dayCount2; + intermediateCapitalExchange_ = intermediateCapitalExchange; + finalCapitalExchange_ = finalCapitalExchange; + + init(paymentConvention1, paymentConvention2); + } + + //! \name Inspectors + public VanillaSwap.Type type() { return type_; } + public List nominal1() { return nominal1_; } + public List nominal2() { return nominal2_; } + + public Schedule schedule1() { return schedule1_; } + public Schedule schedule2() { return schedule2_; } + + public InterestRateIndex index1() { return index1_; } + public InterestRateIndex index2() { return index2_; } + + public List spread1() { return spread1_; } + public List spread2() { return spread2_; } + + public List gearing1() { return gearing1_; } + public List gearing2() { return gearing2_; } + + public List < double? > cappedRate1() { return cappedRate1_; } + public List < double? > flooredRate1() { return flooredRate1_; } + public List < double? > cappedRate2() { return cappedRate2_; } + public List < double? > flooredRate2() { return flooredRate2_; } + + public DayCounter dayCount1() { return dayCount1_; } + public DayCounter dayCount2() { return dayCount2_; } + + public BusinessDayConvention paymentConvention1() { return paymentConvention1_; } + public BusinessDayConvention paymentConvention2() { return paymentConvention2_; } + + public List leg1() { return legs_[0]; } + public List leg2() { return legs_[1]; } + + // other + public override void setupArguments(IPricingEngineArguments args) + { + base.setupArguments(args); + + Arguments arguments = args as Arguments; + + Utils.QL_REQUIRE(arguments != null, () => "argument type does not match"); + + arguments.type = type_; + arguments.nominal1 = nominal1_; + arguments.nominal2 = nominal2_; + arguments.index1 = index1_; + arguments.index2 = index2_; + + List leg1Coupons = leg1(); + List leg2Coupons = leg2(); + + arguments.leg1ResetDates = arguments.leg1PayDates = + arguments.leg1FixingDates = new InitializedList(leg1Coupons.Count); + arguments.leg2ResetDates = arguments.leg2PayDates = + arguments.leg2FixingDates = new InitializedList(leg2Coupons.Count); + + arguments.leg1Spreads = arguments.leg1AccrualTimes = + arguments.leg1Gearings = new InitializedList(leg1Coupons.Count); + arguments.leg2Spreads = arguments.leg2AccrualTimes = + arguments.leg2Gearings = new InitializedList(leg2Coupons.Count); + + arguments.leg1Coupons = new InitializedList < double? >(leg1Coupons.Count, null); + arguments.leg2Coupons = new InitializedList < double? >(leg2Coupons.Count, null); + + arguments.leg1IsRedemptionFlow = new InitializedList(leg1Coupons.Count, false); + arguments.leg2IsRedemptionFlow = new InitializedList(leg2Coupons.Count, false); + + arguments.leg1CappedRates = arguments.leg1FlooredRates = + new InitializedList < double? >(leg1Coupons.Count, null); + arguments.leg2CappedRates = arguments.leg2FlooredRates = + new InitializedList < double? >(leg2Coupons.Count, null); + + for (int i = 0; i < leg1Coupons.Count; ++i) + { + FloatingRateCoupon coupon = leg1Coupons[i] as FloatingRateCoupon; + if (coupon != null) + { + arguments.leg1AccrualTimes[i] = coupon.accrualPeriod(); + arguments.leg1PayDates[i] = coupon.date(); + arguments.leg1ResetDates[i] = coupon.accrualStartDate(); + arguments.leg1FixingDates[i] = coupon.fixingDate(); + arguments.leg1Spreads[i] = coupon.spread(); + arguments.leg1Gearings[i] = coupon.gearing(); + try + { + arguments.leg1Coupons[i] = coupon.amount(); + } + catch (Exception) + { + arguments.leg1Coupons[i] = null; + } + CappedFlooredCoupon cfcoupon = leg1Coupons[i] as CappedFlooredCoupon; + if (cfcoupon != null) + { + arguments.leg1CappedRates[i] = cfcoupon.cap(); + arguments.leg1FlooredRates[i] = cfcoupon.floor(); + } + } + else + { + CashFlow cashflow = leg1Coupons[i] as CashFlow; + int j = arguments.leg1PayDates.FindIndex(x => x == cashflow.date()); + Utils.QL_REQUIRE(j != -1, () => + "nominal redemption on " + cashflow.date() + "has no corresponding coupon"); + int jIdx = j; // Size jIdx = j - arguments->leg1PayDates.begin(); + arguments.leg1IsRedemptionFlow[i] = true; + arguments.leg1Coupons[i] = cashflow.amount(); + arguments.leg1ResetDates[i] = arguments.leg1ResetDates[jIdx]; + arguments.leg1FixingDates[i] = arguments.leg1FixingDates[jIdx]; + arguments.leg1AccrualTimes[i] = 0.0; + arguments.leg1Spreads[i] = 0.0; + arguments.leg1Gearings[i] = 1.0; + arguments.leg1PayDates[i] = cashflow.date(); + } + } + + for (int i = 0; i < leg2Coupons.Count; ++i) + { + FloatingRateCoupon coupon = leg2Coupons[i] as FloatingRateCoupon; + if (coupon != null) + { + arguments.leg2AccrualTimes[i] = coupon.accrualPeriod(); + arguments.leg2PayDates[i] = coupon.date(); + arguments.leg2ResetDates[i] = coupon.accrualStartDate(); + arguments.leg2FixingDates[i] = coupon.fixingDate(); + arguments.leg2Spreads[i] = coupon.spread(); + arguments.leg2Gearings[i] = coupon.gearing(); + try + { + arguments.leg2Coupons[i] = coupon.amount(); + } + catch (Exception) + { + arguments.leg2Coupons[i] = null; + } + CappedFlooredCoupon cfcoupon = leg2Coupons[i] as CappedFlooredCoupon; + if (cfcoupon != null) + { + arguments.leg2CappedRates[i] = cfcoupon.cap(); + arguments.leg2FlooredRates[i] = cfcoupon.floor(); + } + } + else + { + CashFlow cashflow = leg2Coupons[i] as CashFlow; + int j = arguments.leg2PayDates.FindIndex(x => x == cashflow.date()); + Utils.QL_REQUIRE(j != -1, () => + "nominal redemption on " + cashflow.date() + "has no corresponding coupon"); + int jIdx = j; // j - arguments->leg2PayDates.begin(); + arguments.leg2IsRedemptionFlow[i] = true; + arguments.leg2Coupons[i] = cashflow.amount(); + arguments.leg2ResetDates[i] = arguments.leg2ResetDates[jIdx]; + arguments.leg2FixingDates[i] = + arguments.leg2FixingDates[jIdx]; + arguments.leg2AccrualTimes[i] = 0.0; + arguments.leg2Spreads[i] = 0.0; + arguments.leg2Gearings[i] = 1.0; + arguments.leg2PayDates[i] = cashflow.date(); + } + } + } + + + public override void fetchResults(IPricingEngineResults res) { base.fetchResults(res);} + + private void init(BusinessDayConvention? paymentConvention1, BusinessDayConvention? paymentConvention2) + { + Utils.QL_REQUIRE(nominal1_.Count == schedule1_.Count - 1, () => + "nominal1 size (" + nominal1_.Count + + ") does not match schedule1 size (" + schedule1_.size() + ")"); + Utils.QL_REQUIRE(nominal2_.Count == schedule2_.Count - 1, () => + "nominal2 size (" + nominal2_.Count + ") does not match schedule2 size (" + + nominal2_.Count + ")"); + Utils.QL_REQUIRE(gearing1_.Count == 0 || gearing1_.Count == nominal1_.Count, () => + "nominal1 size (" + nominal1_.Count + ") does not match gearing1 size (" + + gearing1_.Count + ")"); + Utils.QL_REQUIRE(gearing2_.Count == 0 || gearing2_.Count == nominal2_.Count, () => + "nominal2 size (" + nominal2_.Count + ") does not match gearing2 size (" + + gearing2_.Count + ")"); + Utils.QL_REQUIRE(cappedRate1_.Count == 0 || cappedRate1_.Count == nominal1_.Count, () => + "nominal1 size (" + nominal1_.Count + ") does not match cappedRate1 size (" + + cappedRate1_.Count + ")"); + Utils.QL_REQUIRE(cappedRate2_.Count == 0 || cappedRate2_.Count == nominal2_.Count, () => + "nominal2 size (" + nominal2_.Count + ") does not match cappedRate2 size (" + + cappedRate2_.Count + ")"); + Utils.QL_REQUIRE(flooredRate1_.Count == 0 || flooredRate1_.Count == nominal1_.Count, () => + "nominal1 size (" + nominal1_.Count + ") does not match flooredRate1 size (" + + flooredRate1_.Count + ")"); + Utils.QL_REQUIRE(flooredRate2_.Count == 0 || flooredRate2_.Count == nominal2_.Count, () => + "nominal2 size (" + nominal2_.Count + ") does not match flooredRate2 size (" + + flooredRate2_.Count + ")"); + + if (paymentConvention1 != null) + paymentConvention1_ = paymentConvention1.Value; + else + paymentConvention1_ = schedule1_.businessDayConvention(); + + if (paymentConvention2 != null) + paymentConvention2_ = paymentConvention2.Value; + else + paymentConvention2_ = schedule2_.businessDayConvention(); + + if (gearing1_.Count == 0) + gearing1_ = new InitializedList(nominal1_.Count, 1.0); + if (gearing2_.Count == 0) + gearing2_ = new InitializedList(nominal2_.Count, 1.0); + if (spread1_.Count == 0) + spread1_ = new InitializedList(nominal1_.Count, 0.0); + if (spread2_.Count == 0) + spread2_ = new InitializedList(nominal2_.Count, 0.0); + if (cappedRate1_.Count == 0) + cappedRate1_ = new InitializedList < double? >(nominal1_.Count, null); + if (cappedRate2_.Count == 0) + cappedRate2_ = new InitializedList < double? >(nominal2_.Count, null); + if (flooredRate1_.Count == 0) + flooredRate1_ = new InitializedList < double? >(nominal1_.Count, null); + if (flooredRate2_.Count == 0) + flooredRate2_ = new InitializedList < double? >(nominal2_.Count, null); + + bool isNull = cappedRate1_[0] == null; + for (int i = 0; i < cappedRate1_.Count; i++) + { + if (isNull) + Utils.QL_REQUIRE(cappedRate1_[i] == null, () => + "cappedRate1 must be null for all or none entry (" + (i + 1) + + "th is " + cappedRate1_[i] + ")"); + else + Utils.QL_REQUIRE(cappedRate1_[i] != null, () => + "cappedRate 1 must be null for all or none entry (" + + "1st is " + cappedRate1_[0] + ")"); + } + isNull = cappedRate2_[0] == null; + for (int i = 0; i < cappedRate2_.Count; i++) + { + if (isNull) + Utils.QL_REQUIRE(cappedRate2_[i] == null, () => + "cappedRate2 must be null for all or none entry (" + + (i + 1) + "th is " + cappedRate2_[i] + ")"); + else + Utils.QL_REQUIRE(cappedRate2_[i] != null, () => + "cappedRate2 must be null for all or none entry (" + + "1st is " + cappedRate2_[0] + ")"); + } + isNull = flooredRate1_[0] == null; + for (int i = 0; i < flooredRate1_.Count; i++) + { + if (isNull) + Utils.QL_REQUIRE(flooredRate1_[i] == null, () => + "flooredRate1 must be null for all or none entry (" + + (i + 1) + "th is " + flooredRate1_[i] + + ")"); + else + Utils.QL_REQUIRE(flooredRate1_[i] != null, () => + "flooredRate 1 must be null for all or none entry (" + + "1st is " + flooredRate1_[0] + ")"); + } + isNull = flooredRate2_[0] == null; + for (int i = 0; i < flooredRate2_.Count; i++) + { + if (isNull) + Utils.QL_REQUIRE(flooredRate2_[i] == null, () => + "flooredRate2 must be null for all or none entry (" + + (i + 1) + "th is " + flooredRate2_[i] + + ")"); + else + Utils.QL_REQUIRE(flooredRate2_[i] != null, () => + "flooredRate2 must be null for all or none entry (" + + "1st is " + flooredRate2_[0] + ")"); + } + + // if the gearing is zero then the ibor / cms leg will be set up with + // fixed coupons which makes trouble here in this context. We therefore + // use a dirty trick and enforce the gearing to be non zero. + for (int i = 0; i < gearing1_.Count; i++) + if (Utils.close(gearing1_[i], 0.0)) + gearing1_[i] = Const.QL_EPSILON; + for (int i = 0; i < gearing2_.Count; i++) + if (Utils.close(gearing2_[i], 0.0)) + gearing2_[i] = Const.QL_EPSILON; + + IborIndex ibor1 = index1_ as IborIndex; + IborIndex ibor2 = index2_ as IborIndex; + SwapIndex cms1 = index1_ as SwapIndex; + SwapIndex cms2 = index2_ as SwapIndex; + SwapSpreadIndex cmsspread1 = index1_ as SwapSpreadIndex; + SwapSpreadIndex cmsspread2 = index2_ as SwapSpreadIndex; + + Utils.QL_REQUIRE(ibor1 != null || cms1 != null || cmsspread1 != null, () => + "index1 must be ibor or cms or cms spread"); + Utils.QL_REQUIRE(ibor2 != null || cms2 != null || cmsspread2 != null, () => + "index2 must be ibor or cms"); + + if (ibor1 != null) + { + IborLeg leg = new IborLeg(schedule1_, ibor1); + leg = (IborLeg)leg.withPaymentDayCounter(dayCount1_) + .withSpreads(spread1_) + .withGearings(gearing1_) + .withPaymentAdjustment(paymentConvention1_) + .withNotionals(nominal1_); + + if (cappedRate1_[0] != null) + leg = (IborLeg) leg.withCaps(cappedRate1_); + if (flooredRate1_[0] != null) + leg = (IborLeg) leg.withFloors(flooredRate1_); + legs_[0] = leg; + } + + if (ibor2 != null) + { + IborLeg leg = new IborLeg(schedule2_, ibor2); + leg = (IborLeg) leg.withPaymentDayCounter(dayCount2_) + .withSpreads(spread2_) + .withGearings(gearing2_) + .withPaymentAdjustment(paymentConvention2_) + .withNotionals(nominal2_); + + if (cappedRate2_[0] != null) + leg = (IborLeg) leg.withCaps(cappedRate2_); + if (flooredRate2_[0] != null) + leg = (IborLeg) leg.withFloors(flooredRate2_); + legs_[1] = leg; + } + + if (cms1 != null) + { + CmsLeg leg = new CmsLeg(schedule1_, cms1); + leg = (CmsLeg) leg.withPaymentDayCounter(dayCount1_) + .withSpreads(spread1_) + .withGearings(gearing1_) + .withNotionals(nominal1_) + .withPaymentAdjustment(paymentConvention1_); + + if (cappedRate1_[0] != null) + leg = (CmsLeg) leg.withCaps(cappedRate1_); + if (flooredRate1_[0] != null) + leg = (CmsLeg) leg.withFloors(flooredRate1_); + legs_[0] = leg; + } + + if (cms2 != null) + { + CmsLeg leg = new CmsLeg(schedule2_, cms2); + leg = (CmsLeg) leg.withPaymentDayCounter(dayCount2_) + .withSpreads(spread2_) + .withGearings(gearing2_) + .withNotionals(nominal2_) + .withPaymentAdjustment(paymentConvention2_); + + if (cappedRate2_[0] != null) + leg = (CmsLeg) leg.withCaps(cappedRate2_); + if (flooredRate2_[0] != null) + leg = (CmsLeg) leg.withFloors(flooredRate2_); + legs_[1] = leg; + } + + if (cmsspread1 != null) + { + CmsSpreadLeg leg = new CmsSpreadLeg(schedule1_, cmsspread1); + leg = (CmsSpreadLeg) leg.withPaymentDayCounter(dayCount1_) + .withSpreads(spread1_) + .withGearings(gearing1_) + .withNotionals(nominal1_) + .withPaymentAdjustment(paymentConvention1_); + if (cappedRate1_[0] != null) + leg = (CmsSpreadLeg) leg.withCaps(cappedRate1_); + if (flooredRate1_[0] != null) + leg = (CmsSpreadLeg) leg.withFloors(flooredRate1_); + legs_[0] = leg; + } + + if (cmsspread2 != null) + { + CmsSpreadLeg leg = new CmsSpreadLeg(schedule2_, cmsspread2); + leg = (CmsSpreadLeg) leg.withPaymentDayCounter(dayCount2_) + .withSpreads(spread2_) + .withGearings(gearing2_) + .withNotionals(nominal2_) + .withPaymentAdjustment(paymentConvention2_); + + if (cappedRate2_[0] != null) + leg = (CmsSpreadLeg) leg.withCaps(cappedRate2_); + if (flooredRate2_[0] != null) + leg = (CmsSpreadLeg) leg.withFloors(flooredRate2_); + legs_[1] = leg; + } + + if (intermediateCapitalExchange_) + { + for (int i = 0; i < legs_[0].Count - 1; i++) + { + double cap = nominal1_[i] - nominal1_[i + 1]; + if (!Utils.close(cap, 0.0)) + { + legs_[0].Insert(i + 1, new Redemption(cap, legs_[0][i].date())); + nominal1_.Insert(i + 1, nominal1_[i]); + i++; + } + } + for (int i = 0; i < legs_[1].Count - 1; i++) + { + double cap = nominal2_[i] - nominal2_[i + 1]; + if (!Utils.close(cap, 0.0)) + { + legs_[1].Insert(i + 1, new Redemption(cap, legs_[1][i].date())); + nominal2_.Insert(i + 1, nominal2_[i]); + i++; + } + } + } + + if (finalCapitalExchange_) + { + legs_[0].Add(new Redemption(nominal1_.Last(), legs_[0].Last().date())); + nominal1_.Add(nominal1_.Last()); + legs_[1].Add(new Redemption(nominal2_.Last(), legs_[1].Last().date())); + nominal2_.Add(nominal2_.Last()); + } + + foreach (var c in legs_[0]) + c.registerWith(update); + + foreach (var c in legs_[1]) + c.registerWith(update); + + switch (type_) + { + case VanillaSwap.Type.Payer: + payer_[0] = -1.0; + payer_[1] = +1.0; + break; + case VanillaSwap.Type.Receiver: + payer_[0] = +1.0; + payer_[1] = -1.0; + break; + default: + Utils.QL_FAIL("Unknown float float - swap type"); + break; + } + } + + private VanillaSwap.Type type_; + private List nominal1_, nominal2_; + private Schedule schedule1_, schedule2_; + private InterestRateIndex index1_, index2_; + private List gearing1_, gearing2_, spread1_, spread2_; + private List < double? > cappedRate1_, flooredRate1_, cappedRate2_, flooredRate2_; + private DayCounter dayCount1_, dayCount2_; + //private List isRedemptionFlow1_, isRedemptionFlow2_; + private BusinessDayConvention paymentConvention1_, paymentConvention2_; + private bool intermediateCapitalExchange_, finalCapitalExchange_; + + /// + /// Arguments for float float swap calculation + /// + public new class Arguments : Swap.Arguments + { + public Arguments() { type = VanillaSwap.Type.Receiver;} + public VanillaSwap.Type type { get; set; } + public List nominal1 { get; set; } + public List nominal2 { get; set; } + + public List leg1ResetDates { get; set; } + public List leg1FixingDates { get; set; } + public List leg1PayDates { get; set; } + + public List leg2ResetDates { get; set; } + public List leg2FixingDates { get; set; } + public List leg2PayDates { get; set; } + + public List leg1Spreads { get; set; } + public List leg2Spreads { get; set; } + public List leg1Gearings { get; set; } + public List leg2Gearings { get; set; } + + public List < double? > leg1CappedRates { get; set; } + public List < double? > leg1FlooredRates { get; set; } + public List < double? > leg2CappedRates { get; set; } + public List < double? > leg2FlooredRates { get; set; } + + public List < double? > leg1Coupons { get; set; } + public List < double? > leg2Coupons { get; set; } + + public List leg1AccrualTimes { get; set; } + public List leg2AccrualTimes { get; set; } + + public InterestRateIndex index1 { get; set; } + public InterestRateIndex index2 { get; set; } + + public List leg1IsRedemptionFlow { get; set; } + public List leg2IsRedemptionFlow { get; set; } + + public override void validate() + { + base.validate(); + + Utils.QL_REQUIRE(nominal1.Count == leg1ResetDates.Count, () => + "nominal1 size is different from resetDates1 size"); + Utils.QL_REQUIRE(nominal1.Count == leg1FixingDates.Count, () => + "nominal1 size is different from fixingDates1 size"); + Utils.QL_REQUIRE(nominal1.Count == leg1PayDates.Count, () => + "nominal1 size is different from payDates1 size"); + Utils.QL_REQUIRE(nominal1.Count == leg1Spreads.Count, () => + "nominal1 size is different from spreads1 size"); + Utils.QL_REQUIRE(nominal1.Count == leg1Gearings.Count, () => + "nominal1 size is different from gearings1 size"); + Utils.QL_REQUIRE(nominal1.Count == leg1CappedRates.Count, () => + "nominal1 size is different from cappedRates1 size"); + Utils.QL_REQUIRE(nominal1.Count == leg1FlooredRates.Count, () => + "nominal1 size is different from flooredRates1 size"); + Utils.QL_REQUIRE(nominal1.Count == leg1Coupons.Count, () => + "nominal1 size is different from coupons1 size"); + Utils.QL_REQUIRE(nominal1.Count == leg1AccrualTimes.Count, () => + "nominal1 size is different from accrualTimes1 size"); + Utils.QL_REQUIRE(nominal1.Count == leg1IsRedemptionFlow.Count, () => + "nominal1 size is different from redemption1 size"); + + Utils.QL_REQUIRE(nominal2.Count == leg2ResetDates.Count, () => + "nominal2 size is different from resetDates2 size"); + Utils.QL_REQUIRE(nominal2.Count == leg2FixingDates.Count, () => + "nominal2 size is different from fixingDates2 size"); + Utils.QL_REQUIRE(nominal2.Count == leg2PayDates.Count, () => + "nominal2 size is different from payDates2 size"); + Utils.QL_REQUIRE(nominal2.Count == leg2Spreads.Count, () => + "nominal2 size is different from spreads2 size"); + Utils.QL_REQUIRE(nominal2.Count == leg2Gearings.Count, () => + "nominal2 size is different from gearings2 size"); + Utils.QL_REQUIRE(nominal2.Count == leg2CappedRates.Count, () => + "nominal2 size is different from cappedRates2 size"); + Utils.QL_REQUIRE(nominal2.Count == leg2FlooredRates.Count, () => + "nominal2 size is different from flooredRates2 size"); + Utils.QL_REQUIRE(nominal2.Count == leg2Coupons.Count, () => + "nominal2 size is different from coupons2 size"); + Utils.QL_REQUIRE(nominal2.Count == leg2AccrualTimes.Count, () => + "nominal2 size is different from accrualTimes2 size"); + Utils.QL_REQUIRE(nominal2.Count == leg2IsRedemptionFlow.Count, () => + "nominal2 size is different from redemption2 size"); + + Utils.QL_REQUIRE(index1 != null, () => "index1 is null"); + Utils.QL_REQUIRE(index2 != null, () => "index2 is null"); + + } + + } + + //! %Results from float float swap calculation + public new class Results : Swap.Results + {} + + public class Engine : GenericEngine + {} + } +} + + + diff --git a/src/QLNet/Instruments/Forward.cs b/src/QLNet/Instruments/Forward.cs new file mode 100644 index 000000000..4fcf03632 --- /dev/null +++ b/src/QLNet/Instruments/Forward.cs @@ -0,0 +1,174 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +namespace QLNet +{ + //! Abstract base forward class + /*! Derived classes must implement the virtual functions spotValue() (NPV or spot price) and spotIncome() associated + with the specific relevant underlying (e.g. bond, stock, commodity, loan/deposit). These functions must be used to set the + protected member variables underlyingSpotValue_ and underlyingIncome_ within performCalculations() in the derived + class before the base-class implementation is called. + + spotIncome() refers generically to the present value of coupons, dividends or storage costs. + + discountCurve_ is the curve used to discount forward contract cash flows back to the evaluation day, as well as to obtain + forward values for spot values/prices. + + incomeDiscountCurve_, which for generality is not automatically set to the discountCurve_, is the curve used to + discount future income/dividends/storage-costs etc back to the evaluation date. + + \todo Add preconditions and tests + + \warning This class still needs to be rigorously tested + + \ingroup instruments + */ + public abstract class Forward : Instrument + { + /*! derived classes must set this, typically via spotIncome() */ + protected double underlyingIncome_; + /*! derived classes must set this, typically via spotValue() */ + protected double underlyingSpotValue_; + + protected DayCounter dayCounter_; + protected Calendar calendar_; + protected BusinessDayConvention businessDayConvention_; + protected int settlementDays_; + protected Payoff payoff_; + /*! valueDate = settlement date (date the fwd contract starts accruing) */ + protected Date valueDate_; + //! maturityDate of the forward contract or delivery date of underlying + protected Date maturityDate_; + protected Handle discountCurve_; + /*! must set this in derived classes, based on particular underlying */ + protected Handle incomeDiscountCurve_; + + protected Forward(DayCounter dayCounter, Calendar calendar, BusinessDayConvention businessDayConvention, + int settlementDays, Payoff payoff, Date valueDate, Date maturityDate, + Handle discountCurve) + { + dayCounter_ = dayCounter; + calendar_ = calendar; + businessDayConvention_ = businessDayConvention; + settlementDays_ = settlementDays; + payoff_ = payoff; + valueDate_ = valueDate; + maturityDate_ = maturityDate; + discountCurve_ = discountCurve; + + maturityDate_ = calendar_.adjust(maturityDate_, businessDayConvention_); + + Settings.registerWith(update); + discountCurve_.registerWith(update); + } + + public virtual Date settlementDate() + { + Date d = calendar_.advance(Settings.evaluationDate(), settlementDays_, TimeUnit.Days); + return Date.Max(d, valueDate_); + } + + public override bool isExpired() + { + return new simple_event(maturityDate_).hasOccurred(settlementDate()); + } + + + //! returns spot value/price of an underlying financial instrument + public abstract double spotValue(); + //! NPV of income/dividends/storage-costs etc. of underlying instrument + public abstract double spotIncome(Handle incomeDiscountCurve); + + // Calculations + //! forward value/price of underlying, discounting income/dividends + /*! \note if this is a bond forward price, is must be a dirty + forward price. + */ + public virtual double forwardValue() + { + calculate(); + return (underlyingSpotValue_ - underlyingIncome_) / discountCurve_.link.discount(maturityDate_); + } + + /*! Simple yield calculation based on underlying spot and + forward values, taking into account underlying income. + When \f$ t>0 \f$, call with: + underlyingSpotValue=spotValue(t), + forwardValue=strikePrice, to get current yield. For a + repo, if \f$ t=0 \f$, impliedYield should reproduce the + spot repo rate. For FRA's, this should reproduce the + relevant zero rate at the FRA's maturityDate_ + */ + public InterestRate impliedYield(double underlyingSpotValue, double forwardValue, Date settlementDate, + Compounding compoundingConvention, DayCounter dayCounter) + { + + double tenor = dayCounter.yearFraction(settlementDate, maturityDate_) ; + double compoundingFactor = forwardValue / (underlyingSpotValue - spotIncome(incomeDiscountCurve_)) ; + return InterestRate.impliedRate(compoundingFactor, dayCounter, compoundingConvention, Frequency.Annual, tenor); + } + + protected override void performCalculations() + { + Utils.QL_REQUIRE(!discountCurve_.empty(), () => "no discounting term structure set to Forward"); + + ForwardTypePayoff ftpayoff = payoff_ as ForwardTypePayoff; + double fwdValue = forwardValue(); + NPV_ = ftpayoff.value(fwdValue) * discountCurve_.link.discount(maturityDate_); + } + } + + //! Class for forward type payoffs + public class ForwardTypePayoff : Payoff + { + protected Position.Type type_; + public Position.Type forwardType() { return type_; } + + protected double strike_; + public double strike() { return strike_; } + + public ForwardTypePayoff(Position.Type type, double strike) + { + type_ = type; + strike_ = strike; + Utils.QL_REQUIRE(strike >= 0.0, () => "negative strike given"); + } + + // Payoff interface + public override string name() { return "Forward";} + public override string description() + { + string result = name() + ", " + strike() + " strike"; + return result; + } + public override double value(double price) + { + switch (type_) + { + case Position.Type.Long: + return (price - strike_); + case Position.Type.Short: + return (strike_ - price); + default: + Utils.QL_FAIL("unknown/illegal position type"); + return 0; + } + } + } +} diff --git a/src/QLNet/Instruments/forwardrateagreement.cs b/src/QLNet/Instruments/ForwardRateAgreement.cs similarity index 91% rename from src/QLNet/Instruments/forwardrateagreement.cs rename to src/QLNet/Instruments/ForwardRateAgreement.cs index 2ca5ec7e3..424a1fd7f 100644 --- a/src/QLNet/Instruments/forwardrateagreement.cs +++ b/src/QLNet/Instruments/ForwardRateAgreement.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -75,10 +75,10 @@ public class ForwardRateAgreement : Forward protected IborIndex index_; public ForwardRateAgreement(Date valueDate, Date maturityDate, Position.Type type, double strikeForwardRate, - double notionalAmount, IborIndex index, Handle discountCurve) + double notionalAmount, IborIndex index, Handle discountCurve) : base( - index.dayCounter(), index.fixingCalendar(), index.businessDayConvention(), index.fixingDays(), new Payoff(), - valueDate, maturityDate, discountCurve) + index.dayCounter(), index.fixingCalendar(), index.businessDayConvention(), index.fixingDays(), new Payoff(), + valueDate, maturityDate, discountCurve) { fraType_ = type; notionalAmount_ = notionalAmount; @@ -88,7 +88,7 @@ public ForwardRateAgreement(Date valueDate, Date maturityDate, Position.Type typ // do I adjust this ? Date fixingDate = calendar_.advance(valueDate_, -settlementDays_, TimeUnit.Days); - forwardRate_ = new InterestRate(index.fixing(fixingDate), index.dayCounter(), Compounding.Simple,Frequency.Once); + forwardRate_ = new InterestRate(index.fixing(fixingDate), index.dayCounter(), Compounding.Simple, Frequency.Once); strikeForwardRate_ = new InterestRate(strikeForwardRate, index.dayCounter(), Compounding.Simple, Frequency.Once); double strike = notionalAmount_ * strikeForwardRate_.compoundFactor(valueDate_, maturityDate_); payoff_ = new ForwardTypePayoff(fraType_, strike); @@ -143,7 +143,7 @@ protected override void performCalculations() { Date fixingDate = calendar_.advance(valueDate_, -settlementDays_, TimeUnit.Days); forwardRate_ = new InterestRate(index_.fixing(fixingDate), index_.dayCounter(), - Compounding.Simple, Frequency.Once); + Compounding.Simple, Frequency.Once); underlyingSpotValue_ = spotValue(); underlyingIncome_ = 0.0; base.performCalculations(); diff --git a/src/QLNet/Instruments/ForwardVanillaOption.cs b/src/QLNet/Instruments/ForwardVanillaOption.cs index fd7ef9e4a..872d226a5 100644 --- a/src/QLNet/Instruments/ForwardVanillaOption.cs +++ b/src/QLNet/Instruments/ForwardVanillaOption.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -17,22 +17,22 @@ namespace QLNet { public class ForwardVanillaOption : OneAssetOption - { - public ForwardVanillaOption( double moneyness, - Date resetDate, - StrikedTypePayoff payoff, - Exercise exercise) - :base(payoff, exercise) + { + public ForwardVanillaOption(double moneyness, + Date resetDate, + StrikedTypePayoff payoff, + Exercise exercise) + : base(payoff, exercise) { moneyness_ = moneyness; resetDate_ = resetDate; } - + public override void setupArguments(IPricingEngineArguments args) { base.setupArguments(args); ForwardVanillaOption.Arguments arguments = args as ForwardVanillaOption.Arguments; - Utils.QL_REQUIRE(arguments != null,()=> "wrong argument type"); + Utils.QL_REQUIRE(arguments != null, () => "wrong argument type"); arguments.moneyness = moneyness_; arguments.resetDate = resetDate_; @@ -41,7 +41,7 @@ public override void fetchResults(IPricingEngineResults r) { base.fetchResults(r); ForwardVanillaOption.Results results = r as ForwardVanillaOption.Results; - Utils.QL_REQUIRE(results != null,()=> "no results returned from pricing engine"); + Utils.QL_REQUIRE(results != null, () => "no results returned from pricing engine"); delta_ = results.delta; gamma_ = results.gamma; theta_ = results.theta; @@ -49,7 +49,7 @@ public override void fetchResults(IPricingEngineResults r) rho_ = results.rho; dividendRho_ = results.dividendRho; } - + // arguments private double moneyness_; private Date resetDate_; @@ -58,14 +58,14 @@ public override void fetchResults(IPricingEngineResults r) { public override void validate() { - Utils.QL_REQUIRE(moneyness > 0.0,()=> "negative or zero moneyness given"); - Utils.QL_REQUIRE(resetDate != null,()=> "null reset date given"); - Utils.QL_REQUIRE(resetDate >= Settings.evaluationDate(),()=>"reset date in the past"); - Utils.QL_REQUIRE(this.exercise.lastDate() > resetDate,()=>"reset date later or equal to maturity"); + Utils.QL_REQUIRE(moneyness > 0.0, () => "negative or zero moneyness given"); + Utils.QL_REQUIRE(resetDate != null, () => "null reset date given"); + Utils.QL_REQUIRE(resetDate >= Settings.evaluationDate(), () => "reset date in the past"); + Utils.QL_REQUIRE(this.exercise.lastDate() > resetDate, () => "reset date later or equal to maturity"); } public double moneyness { get; set; } public Date resetDate { get; set; } } - + } } diff --git a/src/QLNet/Instruments/Futures.cs b/src/QLNet/Instruments/Futures.cs index e38fad031..cdcff5515 100644 --- a/src/QLNet/Instruments/Futures.cs +++ b/src/QLNet/Instruments/Futures.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Instruments/ImpliedVolatility.cs b/src/QLNet/Instruments/ImpliedVolatility.cs index 4cc83dd98..97375f538 100644 --- a/src/QLNet/Instruments/ImpliedVolatility.cs +++ b/src/QLNet/Instruments/ImpliedVolatility.cs @@ -1,75 +1,82 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - //! helper class for one-asset implied-volatility calculation - /*! The passed engine must be linked to the passed quote (see, - e.g., VanillaOption to see how this can be achieved.) */ - public static class ImpliedVolatilityHelper { - public static double calculate(Instrument instrument, IPricingEngine engine, SimpleQuote volQuote, - double targetValue, double accuracy, int maxEvaluations, double minVol, double maxVol) { +namespace QLNet +{ + //! helper class for one-asset implied-volatility calculation + /*! The passed engine must be linked to the passed quote (see, + e.g., VanillaOption to see how this can be achieved.) */ + public static class ImpliedVolatilityHelper + { + public static double calculate(Instrument instrument, IPricingEngine engine, SimpleQuote volQuote, + double targetValue, double accuracy, int maxEvaluations, double minVol, double maxVol) + { + + instrument.setupArguments(engine.getArguments()); + engine.getArguments().validate(); - instrument.setupArguments(engine.getArguments()); - engine.getArguments().validate(); + PriceError f = new PriceError(engine, volQuote, targetValue); + Brent solver = new Brent(); + solver.setMaxEvaluations(maxEvaluations); + double guess = (minVol + maxVol) / 2.0; + double result = solver.solve(f, accuracy, guess, minVol, maxVol); + return result; + } - PriceError f = new PriceError(engine, volQuote, targetValue); - Brent solver = new Brent(); - solver.setMaxEvaluations(maxEvaluations); - double guess = (minVol+maxVol)/2.0; - double result = solver.solve(f, accuracy, guess, minVol, maxVol); - return result; - } + public static GeneralizedBlackScholesProcess clone(GeneralizedBlackScholesProcess process, SimpleQuote volQuote) + { + Handle stateVariable = process.stateVariable(); + Handle dividendYield = process.dividendYield(); + Handle riskFreeRate = process.riskFreeRate(); - public static GeneralizedBlackScholesProcess clone(GeneralizedBlackScholesProcess process, SimpleQuote volQuote) { - Handle stateVariable = process.stateVariable(); - Handle dividendYield = process.dividendYield(); - Handle riskFreeRate = process.riskFreeRate(); + Handle blackVol = process.blackVolatility(); + var volatility = new Handle(new BlackConstantVol(blackVol.link.referenceDate(), + blackVol.link.calendar(), new Handle(volQuote), + blackVol.link.dayCounter())); - Handle blackVol = process.blackVolatility(); - var volatility = new Handle(new BlackConstantVol(blackVol.link.referenceDate(), - blackVol.link.calendar(), new Handle(volQuote), - blackVol.link.dayCounter())); + return new GeneralizedBlackScholesProcess(stateVariable, dividendYield, riskFreeRate, volatility); + } + } - return new GeneralizedBlackScholesProcess(stateVariable, dividendYield, riskFreeRate, volatility); - } - } + public class PriceError : ISolver1d + { + private IPricingEngine engine_; + private SimpleQuote vol_; + private double targetValue_; + private Instrument.Results results_; - public class PriceError : ISolver1d { - private IPricingEngine engine_; - private SimpleQuote vol_; - private double targetValue_; - private Instrument.Results results_; + public PriceError(IPricingEngine engine, SimpleQuote vol, double targetValue) + { + engine_ = engine; + vol_ = vol; + targetValue_ = targetValue; - public PriceError(IPricingEngine engine, SimpleQuote vol, double targetValue) { - engine_ = engine; - vol_ = vol; - targetValue_ = targetValue; - - results_ = engine_.getResults() as Instrument.Results; - Utils.QL_REQUIRE(results_ != null,()=> "pricing engine does not supply needed results"); - } + results_ = engine_.getResults() as Instrument.Results; + Utils.QL_REQUIRE(results_ != null, () => "pricing engine does not supply needed results"); + } - public override double value(double x) { - vol_.setValue(x); - engine_.calculate(); - return results_.value.GetValueOrDefault() - targetValue_; - } - } + public override double value(double x) + { + vol_.setValue(x); + engine_.calculate(); + return results_.value.GetValueOrDefault() - targetValue_; + } + } } diff --git a/src/QLNet/Instruments/InflationCapFloor.cs b/src/QLNet/Instruments/InflationCapFloor.cs index f56dab00b..71ed01c7d 100644 --- a/src/QLNet/Instruments/InflationCapFloor.cs +++ b/src/QLNet/Instruments/InflationCapFloor.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,114 +21,114 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! Base class for yoy inflation cap-like instruments - /*! \ingroup instruments - - Note that the standard YoY inflation cap/floor defined here is - different from nominal, because in nominal world standard - cap/floors do not have the first optionlet. This is because - they set in advance so there is no point. However, yoy - inflation generally sets (effectively) in arrears, (actually - in arrears vs lag of a few months) thus the first optionlet is - relevant. Hence we can do a parity test without a special - definition of the YoY cap/floor instrument. - - \test - - the relationship between the values of caps, floors and the - resulting collars is checked. - - the put-call parity between the values of caps, floors and - swaps is checked. - - the correctness of the returned value is tested by checking - it against a known good value. - */ - - public class YoYInflationCapFloor : Instrument - { - public YoYInflationCapFloor(CapFloorType type, List yoyLeg, List capRates,List floorRates) - { - type_ = type; - yoyLeg_ = yoyLeg; - capRates_ = capRates; - floorRates_ = floorRates; - - if (type_ == CapFloorType.Cap || type_ == CapFloorType.Collar) - { - Utils.QL_REQUIRE( !capRates_.empty(), () => "no cap rates given" ); + //! Base class for yoy inflation cap-like instruments + /*! \ingroup instruments + + Note that the standard YoY inflation cap/floor defined here is + different from nominal, because in nominal world standard + cap/floors do not have the first optionlet. This is because + they set in advance so there is no point. However, yoy + inflation generally sets (effectively) in arrears, (actually + in arrears vs lag of a few months) thus the first optionlet is + relevant. Hence we can do a parity test without a special + definition of the YoY cap/floor instrument. + + \test + - the relationship between the values of caps, floors and the + resulting collars is checked. + - the put-call parity between the values of caps, floors and + swaps is checked. + - the correctness of the returned value is tested by checking + it against a known good value. + */ + + public class YoYInflationCapFloor : Instrument + { + public YoYInflationCapFloor(CapFloorType type, List yoyLeg, List capRates, List floorRates) + { + type_ = type; + yoyLeg_ = yoyLeg; + capRates_ = capRates; + floorRates_ = floorRates; + + if (type_ == CapFloorType.Cap || type_ == CapFloorType.Collar) + { + Utils.QL_REQUIRE(!capRates_.empty(), () => "no cap rates given"); while (capRates_.Count < yoyLeg_.Count) - capRates_.Add(capRates_.Last()); - } - if (type_ == CapFloorType.Floor || type_ == CapFloorType.Collar) - { - Utils.QL_REQUIRE( !floorRates_.empty(), () => "no floor rates given" ); + capRates_.Add(capRates_.Last()); + } + if (type_ == CapFloorType.Floor || type_ == CapFloorType.Collar) + { + Utils.QL_REQUIRE(!floorRates_.empty(), () => "no floor rates given"); while (floorRates_.Count < yoyLeg_.Count) - floorRates_.Add(floorRates_.Last()); - } - - foreach (var cf in yoyLeg_) + floorRates_.Add(floorRates_.Last()); + } + + foreach (var cf in yoyLeg_) cf.registerWith(update); - - Settings.registerWith(update); - } + Settings.registerWith(update); + + } public YoYInflationCapFloor(CapFloorType type, List yoyLeg, List strikes) - { - type_ = type; - yoyLeg_ = yoyLeg; + { + type_ = type; + yoyLeg_ = yoyLeg; - Utils.QL_REQUIRE( !strikes.empty(), () => "no strikes given" ); - if (type_ == CapFloorType.Cap) - { + Utils.QL_REQUIRE(!strikes.empty(), () => "no strikes given"); + if (type_ == CapFloorType.Cap) + { capRates_ = strikes; while (capRates_.Count < yoyLeg_.Count) - capRates_.Add(capRates_.Last()); - } - else if (type_ == CapFloorType.Floor) - { + capRates_.Add(capRates_.Last()); + } + else if (type_ == CapFloorType.Floor) + { floorRates_ = strikes; while (floorRates_.Count < yoyLeg_.Count) - floorRates_.Add(floorRates_.Last()); - } - else + floorRates_.Add(floorRates_.Last()); + } + else Utils.QL_FAIL("only Cap/Floor types allowed in this constructor"); - foreach (var cf in yoyLeg_) + foreach (var cf in yoyLeg_) cf.registerWith(update); - Settings.registerWith(update); - } - - // Instrument interface - public override bool isExpired() - { - for (int i=yoyLeg_.Count; i>0; --i) - if (!yoyLeg_[i-1].hasOccurred()) - return false; - return true; - } - public override void setupArguments(IPricingEngineArguments args) - { - YoYInflationCapFloor.Arguments arguments = args as YoYInflationCapFloor.Arguments; - Utils.QL_REQUIRE( arguments != null, () => "wrong argument type" ); - - int n = yoyLeg_.Count; - - arguments.startDates = new List(n); - arguments.fixingDates=new List(n); - arguments.payDates= new List(n); - arguments.accrualTimes = new List(n); - arguments.nominals=new List(n); - arguments.gearings=new List(n); - arguments.capRates=new List(n); - arguments.floorRates=new List(n); - arguments.spreads= new List(n); - - arguments.type = type_; - - for (int i=0; i "non-YoYInflationCoupon given" ); + Settings.registerWith(update); + } + + // Instrument interface + public override bool isExpired() + { + for (int i = yoyLeg_.Count; i > 0; --i) + if (!yoyLeg_[i - 1].hasOccurred()) + return false; + return true; + } + public override void setupArguments(IPricingEngineArguments args) + { + YoYInflationCapFloor.Arguments arguments = args as YoYInflationCapFloor.Arguments; + Utils.QL_REQUIRE(arguments != null, () => "wrong argument type"); + + int n = yoyLeg_.Count; + + arguments.startDates = new List(n); + arguments.fixingDates = new List(n); + arguments.payDates = new List(n); + arguments.accrualTimes = new List(n); + arguments.nominals = new List(n); + arguments.gearings = new List(n); + arguments.capRates = new List < double? >(n); + arguments.floorRates = new List < double? >(n); + arguments.spreads = new List(n); + + arguments.type = type_; + + for (int i = 0; i < n; ++i) + { + YoYInflationCoupon coupon = yoyLeg_[i] as YoYInflationCoupon; + Utils.QL_REQUIRE(coupon != null, () => "non-YoYInflationCoupon given"); arguments.startDates.Add(coupon.accrualStartDate()); arguments.fixingDates.Add(coupon.fixingDate()); arguments.payDates.Add(coupon.date()); @@ -142,154 +142,154 @@ public override void setupArguments(IPricingEngineArguments args) arguments.gearings.Add(gearing); arguments.spreads.Add(spread); - if ( type_ == CapFloorType.Cap || type_ == CapFloorType.Collar ) - arguments.capRates.Add((capRates_[i]-spread)/gearing); + if (type_ == CapFloorType.Cap || type_ == CapFloorType.Collar) + arguments.capRates.Add((capRates_[i] - spread) / gearing); else - arguments.capRates.Add(null); + arguments.capRates.Add(null); - if ( type_ == CapFloorType.Floor || type_ == CapFloorType.Collar ) - arguments.floorRates.Add((floorRates_[i]-spread)/gearing); + if (type_ == CapFloorType.Floor || type_ == CapFloorType.Collar) + arguments.floorRates.Add((floorRates_[i] - spread) / gearing); else - arguments.floorRates.Add(null); - } - - } - - // Inspectors - public CapFloorType type() { return type_; } - public List capRates() { return capRates_; } - public List floorRates() { return floorRates_; } - public List yoyLeg() { return yoyLeg_; } - - public Date startDate() {return CashFlows.startDate(yoyLeg_);} - public Date maturityDate() { return CashFlows.maturityDate(yoyLeg_);} - public YoYInflationCoupon lastYoYInflationCoupon() - { - YoYInflationCoupon lastYoYInflationCoupon = yoyLeg_.Last() as YoYInflationCoupon; - return lastYoYInflationCoupon; - } - //! Returns the n-th optionlet as a cap/floor with only one cash flow. - public YoYInflationCapFloor optionlet( int i) - { - Utils.QL_REQUIRE( i < yoyLeg().Count, () => " optionlet does not exist, only " + yoyLeg().Count ); - List cf = new List(); - cf.Add(yoyLeg()[i]); - - List cap = new List(), floor = new List(); - if (type() == CapFloorType.Cap || type() == CapFloorType.Collar) + arguments.floorRates.Add(null); + } + + } + + // Inspectors + public CapFloorType type() { return type_; } + public List capRates() { return capRates_; } + public List floorRates() { return floorRates_; } + public List yoyLeg() { return yoyLeg_; } + + public Date startDate() {return CashFlows.startDate(yoyLeg_);} + public Date maturityDate() { return CashFlows.maturityDate(yoyLeg_);} + public YoYInflationCoupon lastYoYInflationCoupon() + { + YoYInflationCoupon lastYoYInflationCoupon = yoyLeg_.Last() as YoYInflationCoupon; + return lastYoYInflationCoupon; + } + //! Returns the n-th optionlet as a cap/floor with only one cash flow. + public YoYInflationCapFloor optionlet(int i) + { + Utils.QL_REQUIRE(i < yoyLeg().Count, () => " optionlet does not exist, only " + yoyLeg().Count); + List cf = new List(); + cf.Add(yoyLeg()[i]); + + List cap = new List(), floor = new List(); + if (type() == CapFloorType.Cap || type() == CapFloorType.Collar) cap.Add(capRates()[i]); - if (type() == CapFloorType.Floor || type() == CapFloorType.Collar) + if (type() == CapFloorType.Floor || type() == CapFloorType.Collar) floor.Add(floorRates()[i]); - return new YoYInflationCapFloor(type(), cf, cap, floor); - } + return new YoYInflationCapFloor(type(), cf, cap, floor); + } - public virtual double atmRate( YieldTermStructure discountCurve ) - { - return CashFlows.atmRate(yoyLeg_, discountCurve, + public virtual double atmRate(YieldTermStructure discountCurve) + { + return CashFlows.atmRate(yoyLeg_, discountCurve, false, discountCurve.referenceDate()); - } - - //! implied term volatility - public virtual double impliedVolatility( - double price, - Handle yoyCurve, - double guess, - double accuracy = 1.0e-4, - int maxEvaluations = 100, - double minVol = 1.0e-7, - double maxVol = 4.0) - { - Utils.QL_FAIL("not implemented yet"); - return 0; - } - + } + + //! implied term volatility + public virtual double impliedVolatility( + double price, + Handle yoyCurve, + double guess, + double accuracy = 1.0e-4, + int maxEvaluations = 100, + double minVol = 1.0e-7, + double maxVol = 4.0) + { + Utils.QL_FAIL("not implemented yet"); + return 0; + } + private CapFloorType type_; private List yoyLeg_; - private List capRates_; - private List floorRates_; + private List capRates_; + private List floorRates_; - //! %Arguments for YoY Inflation cap/floor calculation - public class Arguments : IPricingEngineArguments - { - public CapFloorType type { get; set; } + //! %Arguments for YoY Inflation cap/floor calculation + public class Arguments : IPricingEngineArguments + { + public CapFloorType type { get; set; } public YoYInflationIndex index { get; set; } public Period observationLag { get; set; } public List startDates { get; set; } public List fixingDates { get; set; } public List payDates { get; set; } public List accrualTimes { get; set; } - public List capRates { get; set; } - public List floorRates { get; set; } + public List < double? > capRates { get; set; } + public List < double? > floorRates { get; set; } public List gearings { get; set; } public List spreads { get; set; } public List nominals { get; set; } public void validate() - { - Utils.QL_REQUIRE( payDates.Count == startDates.Count, () => - "number of start dates (" + startDates.Count - + ") different from that of pay dates (" - + payDates.Count + ")"); - Utils.QL_REQUIRE( accrualTimes.Count == startDates.Count, () => - "number of start dates (" + startDates.Count - + ") different from that of accrual times (" - + accrualTimes.Count + ")"); - Utils.QL_REQUIRE(type == CapFloorType.Floor || - capRates.Count == startDates.Count, () => - "number of start dates (" + startDates.Count - + ") different from that of cap rates (" - + capRates.Count + ")"); - Utils.QL_REQUIRE(type == CapFloorType.Cap || - floorRates.Count == startDates.Count, () => - "number of start dates (" + startDates.Count - + ") different from that of floor rates (" - + floorRates.Count + ")"); - Utils.QL_REQUIRE( gearings.Count == startDates.Count, () => - "number of start dates (" + startDates.Count - + ") different from that of gearings (" - + gearings.Count + ")"); - Utils.QL_REQUIRE( spreads.Count == startDates.Count, () => - "number of start dates (" + startDates.Count - + ") different from that of spreads (" - + spreads.Count + ")"); - Utils.QL_REQUIRE( nominals.Count == startDates.Count, () => - "number of start dates (" + startDates.Count - + ") different from that of nominals (" - + nominals.Count + ")"); - } - } - - //! base class for cap/floor engines - public class Engine : GenericEngine - {} - - } - - //! Concrete YoY Inflation cap class - /*! \ingroup instruments */ - public class YoYInflationCap : YoYInflationCapFloor - { - public YoYInflationCap(List yoyLeg,List exerciseRates) - : base(CapFloorType.Cap, yoyLeg, exerciseRates,new List()) - {} - } - - //! Concrete YoY Inflation floor class - /*! \ingroup instruments */ - public class YoYInflationFloor : YoYInflationCapFloor - { - public YoYInflationFloor(List yoyLeg,List exerciseRates) - : base(CapFloorType.Floor, yoyLeg,new List(), exerciseRates) - {} - } - - //! Concrete YoY Inflation collar class - /*! \ingroup instruments */ - public class YoYInflationCollar : YoYInflationCapFloor - { + { + Utils.QL_REQUIRE(payDates.Count == startDates.Count, () => + "number of start dates (" + startDates.Count + + ") different from that of pay dates (" + + payDates.Count + ")"); + Utils.QL_REQUIRE(accrualTimes.Count == startDates.Count, () => + "number of start dates (" + startDates.Count + + ") different from that of accrual times (" + + accrualTimes.Count + ")"); + Utils.QL_REQUIRE(type == CapFloorType.Floor || + capRates.Count == startDates.Count, () => + "number of start dates (" + startDates.Count + + ") different from that of cap rates (" + + capRates.Count + ")"); + Utils.QL_REQUIRE(type == CapFloorType.Cap || + floorRates.Count == startDates.Count, () => + "number of start dates (" + startDates.Count + + ") different from that of floor rates (" + + floorRates.Count + ")"); + Utils.QL_REQUIRE(gearings.Count == startDates.Count, () => + "number of start dates (" + startDates.Count + + ") different from that of gearings (" + + gearings.Count + ")"); + Utils.QL_REQUIRE(spreads.Count == startDates.Count, () => + "number of start dates (" + startDates.Count + + ") different from that of spreads (" + + spreads.Count + ")"); + Utils.QL_REQUIRE(nominals.Count == startDates.Count, () => + "number of start dates (" + startDates.Count + + ") different from that of nominals (" + + nominals.Count + ")"); + } + } + + //! base class for cap/floor engines + public class Engine : GenericEngine + {} + + } + + //! Concrete YoY Inflation cap class + /*! \ingroup instruments */ + public class YoYInflationCap : YoYInflationCapFloor + { + public YoYInflationCap(List yoyLeg, List exerciseRates) + : base(CapFloorType.Cap, yoyLeg, exerciseRates, new List()) + {} + } + + //! Concrete YoY Inflation floor class + /*! \ingroup instruments */ + public class YoYInflationFloor : YoYInflationCapFloor + { + public YoYInflationFloor(List yoyLeg, List exerciseRates) + : base(CapFloorType.Floor, yoyLeg, new List(), exerciseRates) + {} + } + + //! Concrete YoY Inflation collar class + /*! \ingroup instruments */ + public class YoYInflationCollar : YoYInflationCapFloor + { public YoYInflationCollar(List yoyLeg, List capRates, List floorRates) - : base(CapFloorType.Collar, yoyLeg, capRates, floorRates) {} - } + : base(CapFloorType.Collar, yoyLeg, capRates, floorRates) {} + } + - } diff --git a/src/QLNet/Instruments/Instrument.cs b/src/QLNet/Instruments/Instrument.cs index d7b4062f9..3d6e06ef9 100644 --- a/src/QLNet/Instruments/Instrument.cs +++ b/src/QLNet/Instruments/Instrument.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,133 +22,143 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - // Abstract instrument class. It defines the interface of concrete instruments - public class Instrument : LazyObject - { - // The value of these attributes and any other that derived classes might declare must be set during calculation. - protected double? NPV_, errorEstimate_,CASH_; - protected Dictionary additionalResults_ = new Dictionary(); - protected IPricingEngine engine_; - protected Date valuationDate_ = null; - - //! sets the pricing engine to be used. - /*! calling this method will have no effects in case the performCalculation method - was overridden in a derived class. */ - public void setPricingEngine(IPricingEngine e) - { - if (engine_ != null) engine_.unregisterWith(update); - engine_ = e; - if (engine_ != null) engine_.registerWith(update); - - update(); // trigger (lazy) recalculation and notify observers - } - - - /*! When a derived argument structure is defined for an instrument, - * this method should be overridden to fill it. - * This is mandatory in case a pricing engine is used. */ - public virtual void setupArguments(IPricingEngineArguments a) { throw new NotImplementedException(); } - - - #region Lazy object interface - protected override void calculate() - { - if (isExpired()) - { - setupExpired(); - calculated_ = true; - } - else - { - base.calculate(); - } - } - - /* In case a pricing engine is not used, this method must be overridden to perform the actual - calculations and set any needed results. - * In case a pricing engine is used, the default implementation can be used. */ - protected override void performCalculations() - { - if (engine_ == null) throw new ArgumentException("null pricing engine"); - engine_.reset(); - setupArguments(engine_.getArguments()); - engine_.getArguments().validate(); - engine_.calculate(); - fetchResults(engine_.getResults()); - } - #endregion - - #region Results - /*! When a derived result structure is defined for an instrument, - * this method should be overridden to read from it. - * This is mandatory in case a pricing engine is used. */ - public virtual void fetchResults(IPricingEngineResults r) - { - Instrument.Results results = r as Instrument.Results; - if (results == null) throw new ArgumentException("no results returned from pricing engine"); - NPV_ = results.value; - CASH_ = results.cash; - errorEstimate_ = results.errorEstimate; - valuationDate_ = results.valuationDate; - additionalResults_ = new Dictionary(results.additionalResults); - } - - public double NPV() - { //! returns the net present value of the instrument. - calculate(); - if (NPV_ == null) throw new ArgumentException("NPV not provided"); - return NPV_.GetValueOrDefault(); - } - - public double CASH() - { //! returns the net present value of the instrument. - calculate(); - if (CASH_ == null) throw new ArgumentException("CASH not provided"); - return CASH_.GetValueOrDefault(); - } - - public double errorEstimate() - { //! returns the error estimate on the NPV when available. - calculate(); - if (errorEstimate_ == null) throw new ArgumentException("error estimate not provided"); - return errorEstimate_.GetValueOrDefault(); - } - //! returns the date the net present value refers to. - public Date valuationDate() - { - calculate(); - Utils.QL_REQUIRE( valuationDate_ != null, () => "valuation date not provided" ); - return valuationDate_; - } - - // returns any additional result returned by the pricing engine. - public object result(string tag) - { - calculate(); - try - { - return additionalResults_[tag]; - } - catch (KeyNotFoundException) - { - throw new ArgumentException(tag + " not provided"); - } - } - - // returns all additional result returned by the pricing engine. - public Dictionary additionalResults() { return additionalResults_; } - #endregion - - // This method must leave the instrument in a consistent state when the expiration condition is met. - protected virtual void setupExpired() - { - NPV_ = errorEstimate_ = CASH_ = 0.0; - valuationDate_ = null; - additionalResults_.Clear(); - } - - //! returns whether the instrument is still tradable. - public virtual bool isExpired() { throw new NotSupportedException(); } + // Abstract instrument class. It defines the interface of concrete instruments + public class Instrument : LazyObject + { + // The value of these attributes and any other that derived classes might declare must be set during calculation. + protected double? NPV_, errorEstimate_, CASH_; + protected Dictionary additionalResults_ = new Dictionary(); + protected IPricingEngine engine_; + protected Date valuationDate_ = null; + + //! sets the pricing engine to be used. + /*! calling this method will have no effects in case the performCalculation method + was overridden in a derived class. */ + public void setPricingEngine(IPricingEngine e) + { + if (engine_ != null) + engine_.unregisterWith(update); + engine_ = e; + if (engine_ != null) + engine_.registerWith(update); + + update(); // trigger (lazy) recalculation and notify observers + } + + + /*! When a derived argument structure is defined for an instrument, + * this method should be overridden to fill it. + * This is mandatory in case a pricing engine is used. */ + public virtual void setupArguments(IPricingEngineArguments a) { throw new NotImplementedException(); } + + + #region Lazy object interface + protected override void calculate() + { + if (isExpired()) + { + setupExpired(); + calculated_ = true; + } + else + { + base.calculate(); + } + } + + /* In case a pricing engine is not used, this method must be overridden to perform the actual + calculations and set any needed results. + * In case a pricing engine is used, the default implementation can be used. */ + protected override void performCalculations() + { + if (engine_ == null) + throw new ArgumentException("null pricing engine"); + engine_.reset(); + setupArguments(engine_.getArguments()); + engine_.getArguments().validate(); + engine_.calculate(); + fetchResults(engine_.getResults()); + } + #endregion + + #region Results + /*! When a derived result structure is defined for an instrument, + * this method should be overridden to read from it. + * This is mandatory in case a pricing engine is used. */ + public virtual void fetchResults(IPricingEngineResults r) + { + Instrument.Results results = r as Instrument.Results; + if (results == null) + throw new ArgumentException("no results returned from pricing engine"); + NPV_ = results.value; + CASH_ = results.cash; + errorEstimate_ = results.errorEstimate; + valuationDate_ = results.valuationDate; + additionalResults_ = new Dictionary(results.additionalResults); + } + + public double NPV() + { + //! returns the net present value of the instrument. + calculate(); + if (NPV_ == null) + throw new ArgumentException("NPV not provided"); + return NPV_.GetValueOrDefault(); + } + + public double CASH() + { + //! returns the net present value of the instrument. + calculate(); + if (CASH_ == null) + throw new ArgumentException("CASH not provided"); + return CASH_.GetValueOrDefault(); + } + + public double errorEstimate() + { + //! returns the error estimate on the NPV when available. + calculate(); + if (errorEstimate_ == null) + throw new ArgumentException("error estimate not provided"); + return errorEstimate_.GetValueOrDefault(); + } + //! returns the date the net present value refers to. + public Date valuationDate() + { + calculate(); + Utils.QL_REQUIRE(valuationDate_ != null, () => "valuation date not provided"); + return valuationDate_; + } + + // returns any additional result returned by the pricing engine. + public object result(string tag) + { + calculate(); + try + { + return additionalResults_[tag]; + } + catch (KeyNotFoundException) + { + throw new ArgumentException(tag + " not provided"); + } + } + + // returns all additional result returned by the pricing engine. + public Dictionary additionalResults() { return additionalResults_; } + #endregion + + // This method must leave the instrument in a consistent state when the expiration condition is met. + protected virtual void setupExpired() + { + NPV_ = errorEstimate_ = CASH_ = 0.0; + valuationDate_ = null; + additionalResults_.Clear(); + } + + //! returns whether the instrument is still tradable. + public virtual bool isExpired() { throw new NotSupportedException(); } public class Results : IPricingEngineResults @@ -162,7 +172,7 @@ public Results() public double? cash { get; set; } public Date valuationDate { get; set; } - public Dictionary additionalResults { get; set; } + public Dictionary additionalResults { get; set; } public virtual void reset() { diff --git a/src/QLNet/Instruments/Loan.cs b/src/QLNet/Instruments/Loan.cs index 8937ad013..7412f96e1 100644 --- a/src/QLNet/Instruments/Loan.cs +++ b/src/QLNet/Instruments/Loan.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -25,8 +25,8 @@ namespace QLNet { public class Loan : Instrument { - public enum Type { Deposit = -1, Loan = 1 }; - public enum Amortising + public enum Type { Deposit = -1, Loan = 1 } + public enum Amortising { Bullet = 1, Step = 2, @@ -35,14 +35,14 @@ public enum Amortising protected List> legs_; protected List payer_; protected List notionals_; - protected List legNPV_; + protected List < double? > legNPV_; public Loan(int legs) { - legs_ = new InitializedList>(legs); - payer_ = new InitializedList(legs); - notionals_ = new List(); - legNPV_ = new InitializedList(legs); + legs_ = new InitializedList>(legs); + payer_ = new InitializedList(legs); + notionals_ = new List(); + legNPV_ = new InitializedList < double? >(legs); } /////////////////////////////////////////////////////////////////// @@ -56,13 +56,14 @@ public override bool isExpired() protected override void setupExpired() { base.setupExpired(); - legNPV_ = new InitializedList(legNPV_.Count); + legNPV_ = new InitializedList < double? >(legNPV_.Count); } public override void setupArguments(IPricingEngineArguments args) { Loan.Arguments arguments = args as Loan.Arguments; - if (arguments == null) throw new ArgumentException("wrong argument type"); + if (arguments == null) + throw new ArgumentException("wrong argument type"); arguments.legs = legs_; arguments.payer = payer_; @@ -73,17 +74,18 @@ public override void fetchResults(IPricingEngineResults r) base.fetchResults(r); Loan.Results results = r as Loan.Results; - if (results == null) throw new ArgumentException("wrong result type"); + if (results == null) + throw new ArgumentException("wrong result type"); if (results.legNPV.Count != 0) { if (results.legNPV.Count != legNPV_.Count) throw new ArgumentException("wrong number of leg NPV returned"); - legNPV_ = new List(results.legNPV); + legNPV_ = new List < double? >(results.legNPV); } else { - legNPV_ = new InitializedList(legNPV_.Count); + legNPV_ = new InitializedList < double? >(legNPV_.Count); } } @@ -96,19 +98,20 @@ public class Arguments : IPricingEngineArguments public List payer { get; set; } public virtual void validate() { - if (legs.Count != payer.Count) throw new ArgumentException("number of legs and multipliers differ"); + if (legs.Count != payer.Count) + throw new ArgumentException("number of legs and multipliers differ"); } } public new class Results : Instrument.Results { - public List legNPV { get; set; } + public List < double? > legNPV { get; set; } public override void reset() { base.reset(); // clear all previous results - if (legNPV==null) - legNPV = new List(); + if (legNPV == null) + legNPV = new List < double? >(); else legNPV.Clear(); } @@ -131,8 +134,8 @@ public class FixedLoan : Loan public FixedLoan(Type type, double nominal, Schedule fixedSchedule, double fixedRate, DayCounter fixedDayCount, - Schedule principalSchedule, BusinessDayConvention? paymentConvention) : - base(2) + Schedule principalSchedule, BusinessDayConvention ? paymentConvention) : + base(2) { type_ = type; @@ -143,39 +146,39 @@ public FixedLoan(Type type, double nominal, principalSchedule_ = principalSchedule; if (paymentConvention.HasValue) - paymentConvention_ = paymentConvention.Value; + paymentConvention_ = paymentConvention.Value; else paymentConvention_ = fixedSchedule_.businessDayConvention(); List principalLeg = new PricipalLeg(principalSchedule, fixedDayCount) - .withNotionals(nominal) - .withPaymentAdjustment(paymentConvention_) - .withSign(type == Type.Loan ? -1 : 1 ); + .withNotionals(nominal) + .withPaymentAdjustment(paymentConvention_) + .withSign(type == Type.Loan ? -1 : 1); - // temporary - for (int i = 0; i < principalLeg.Count-1; i++ ) + // temporary + for (int i = 0; i < principalLeg.Count - 1; i++) { Principal p = (Principal)principalLeg[i]; notionals_.Add(p.nominal()); } List fixedLeg = new FixedRateLeg(fixedSchedule) - .withCouponRates(fixedRate, fixedDayCount) - .withPaymentAdjustment(paymentConvention_) - .withNotionals(notionals_); + .withCouponRates(fixedRate, fixedDayCount) + .withPaymentAdjustment(paymentConvention_) + .withNotionals(notionals_); legs_[0] = fixedLeg; legs_[1] = principalLeg; - if (type_ == Type.Loan) + if (type_ == Type.Loan) { - payer_[0] = +1; - payer_[1] = -1; - } - else + payer_[0] = +1; + payer_[1] = -1; + } + else { - payer_[0] = -1; - payer_[1] = +1; + payer_[0] = -1; + payer_[1] = +1; } } @@ -195,9 +198,9 @@ public class FloatingLoan : Loan private IborIndex iborIndex_; public FloatingLoan(Type type, double nominal, - Schedule floatingSchedule, double floatingSpread, DayCounter floatingDayCount, - Schedule principalSchedule, BusinessDayConvention? paymentConvention,IborIndex index) : - base(2) + Schedule floatingSchedule, double floatingSpread, DayCounter floatingDayCount, + Schedule principalSchedule, BusinessDayConvention ? paymentConvention, IborIndex index) : + base(2) { type_ = type; @@ -214,11 +217,11 @@ public FloatingLoan(Type type, double nominal, paymentConvention_ = floatingSchedule_.businessDayConvention(); List principalLeg = new PricipalLeg(principalSchedule, floatingDayCount) - .withNotionals(nominal) - .withPaymentAdjustment(paymentConvention_) - .withSign(type == Type.Loan ? -1 : 1); + .withNotionals(nominal) + .withPaymentAdjustment(paymentConvention_) + .withSign(type == Type.Loan ? -1 : 1); - // temporary + // temporary for (int i = 0; i < principalLeg.Count - 1; i++) { Principal p = (Principal)principalLeg[i]; @@ -226,10 +229,10 @@ public FloatingLoan(Type type, double nominal, } List floatingLeg = new IborLeg(floatingSchedule, iborIndex_) - .withPaymentDayCounter(floatingDayCount_) - .withSpreads(floatingSpread_) - .withPaymentAdjustment(paymentConvention_) - .withNotionals(notionals_); + .withPaymentDayCounter(floatingDayCount_) + .withSpreads(floatingSpread_) + .withPaymentAdjustment(paymentConvention_) + .withNotionals(notionals_); legs_[0] = floatingLeg; @@ -262,8 +265,8 @@ public class CommercialPaper : Loan public CommercialPaper(Type type, double nominal, Schedule fixedSchedule, double fixedRate, DayCounter fixedDayCount, - Schedule principalSchedule, BusinessDayConvention? paymentConvention) : - base(2) + Schedule principalSchedule, BusinessDayConvention ? paymentConvention) : + base(2) { type_ = type; @@ -279,11 +282,11 @@ public CommercialPaper(Type type, double nominal, paymentConvention_ = fixedSchedule_.businessDayConvention(); List principalLeg = new PricipalLeg(principalSchedule, fixedDayCount) - .withNotionals(nominal) - .withPaymentAdjustment(paymentConvention_) - .withSign(type == Type.Loan ? -1 : 1); + .withNotionals(nominal) + .withPaymentAdjustment(paymentConvention_) + .withSign(type == Type.Loan ? -1 : 1); - // temporary + // temporary for (int i = 0; i < principalLeg.Count - 1; i++) { Principal p = (Principal)principalLeg[i]; @@ -291,9 +294,9 @@ public CommercialPaper(Type type, double nominal, } List fixedLeg = new FixedRateLeg(fixedSchedule) - .withCouponRates(fixedRate, fixedDayCount) - .withPaymentAdjustment(paymentConvention_) - .withNotionals(notionals_); + .withCouponRates(fixedRate, fixedDayCount) + .withPaymentAdjustment(paymentConvention_) + .withNotionals(notionals_); // Discounting Pricipal notionals_.Clear(); @@ -302,14 +305,14 @@ public CommercialPaper(Type type, double nominal, { FixedRateCoupon c = (FixedRateCoupon)fixedLeg[i]; n = i > 0 ? notionals_.Last() : c.nominal(); - notionals_.Add ( n /(1+(c.rate()* c.dayCounter().yearFraction(c.referencePeriodStart, c.referencePeriodEnd)))); + notionals_.Add(n / (1 + (c.rate()* c.dayCounter().yearFraction(c.referencePeriodStart, c.referencePeriodEnd)))); } // New Leg List discountedFixedLeg = new FixedRateLeg(fixedSchedule) - .withCouponRates(fixedRate, fixedDayCount) - .withPaymentAdjustment(paymentConvention_) - .withNotionals(notionals_); + .withCouponRates(fixedRate, fixedDayCount) + .withPaymentAdjustment(paymentConvention_) + .withNotionals(notionals_); // Adjust Principal Principal p0 = (Principal)principalLeg[0]; p0.setAmount(notionals_.Last()); @@ -340,8 +343,8 @@ public class Cash : Loan private BusinessDayConvention paymentConvention_; public Cash(Type type, double nominal, - Schedule principalSchedule, BusinessDayConvention? paymentConvention) : - base(1) + Schedule principalSchedule, BusinessDayConvention ? paymentConvention) : + base(1) { type_ = type; @@ -349,10 +352,10 @@ public Cash(Type type, double nominal, principalSchedule_ = principalSchedule; paymentConvention_ = paymentConvention.Value; - List principalLeg = new PricipalLeg(principalSchedule,new Actual365Fixed()) - .withNotionals(nominal) - .withPaymentAdjustment(paymentConvention_) - .withSign(type == Type.Loan ? -1 : 1); + List principalLeg = new PricipalLeg(principalSchedule, new Actual365Fixed()) + .withNotionals(nominal) + .withPaymentAdjustment(paymentConvention_) + .withSign(type == Type.Loan ? -1 : 1); legs_[0] = principalLeg; if (type_ == Type.Loan) diff --git a/src/QLNet/Instruments/LookbackOption.cs b/src/QLNet/Instruments/LookbackOption.cs index 6285e4eed..cf14895e7 100644 --- a/src/QLNet/Instruments/LookbackOption.cs +++ b/src/QLNet/Instruments/LookbackOption.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -17,67 +17,67 @@ namespace QLNet { //! Continuous-floating lookback option - public class ContinuousFloatingLookbackOption : OneAssetOption + public class ContinuousFloatingLookbackOption : OneAssetOption { //! %Arguments for continuous fixed lookback option calculation - public new class Arguments : OneAssetOption.Arguments + public new class Arguments : OneAssetOption.Arguments { public double? minmax { get; set; } public override void validate() { base.validate(); - Utils.QL_REQUIRE(minmax != null,()=> "null prior extremum"); - Utils.QL_REQUIRE(minmax >= 0.0,()=> "nonnegative prior extremum required: " + minmax + " not allowed"); + Utils.QL_REQUIRE(minmax != null, () => "null prior extremum"); + Utils.QL_REQUIRE(minmax >= 0.0, () => "nonnegative prior extremum required: " + minmax + " not allowed"); } } //! %Continuous floating lookback %engine base class public new class Engine : GenericEngine + ContinuousFloatingLookbackOption.Results> {} - public ContinuousFloatingLookbackOption( double minmax, TypePayoff payoff, Exercise exercise ) - :base(payoff, exercise) + public ContinuousFloatingLookbackOption(double minmax, TypePayoff payoff, Exercise exercise) + : base(payoff, exercise) { minmax_ = minmax; } - public override void setupArguments(IPricingEngineArguments args ) + public override void setupArguments(IPricingEngineArguments args) { base.setupArguments(args); ContinuousFloatingLookbackOption.Arguments moreArgs = args as ContinuousFloatingLookbackOption.Arguments; - Utils.QL_REQUIRE(moreArgs != null,()=> "wrong argument type"); + Utils.QL_REQUIRE(moreArgs != null, () => "wrong argument type"); moreArgs.minmax = minmax_; } - + // arguments protected double? minmax_; - } + } //! Continuous-fixed lookback option - public class ContinuousFixedLookbackOption : OneAssetOption + public class ContinuousFixedLookbackOption : OneAssetOption { //! %Arguments for continuous fixed lookback option calculation - public new class Arguments : OneAssetOption.Arguments + public new class Arguments : OneAssetOption.Arguments { public double? minmax { get; set; } public override void validate() { base.validate(); - Utils.QL_REQUIRE(minmax != null,()=> "null prior extremum"); - Utils.QL_REQUIRE(minmax >= 0.0,()=> "nonnegative prior extremum required: " - + minmax + " not allowed"); + Utils.QL_REQUIRE(minmax != null, () => "null prior extremum"); + Utils.QL_REQUIRE(minmax >= 0.0, () => "nonnegative prior extremum required: " + + minmax + " not allowed"); } } //! %Continuous fixed lookback %engine base class public new class Engine : GenericEngine + ContinuousFixedLookbackOption.Results> {} - public ContinuousFixedLookbackOption( double minmax, StrikedTypePayoff payoff, Exercise exercise ) - :base(payoff, exercise) + public ContinuousFixedLookbackOption(double minmax, StrikedTypePayoff payoff, Exercise exercise) + : base(payoff, exercise) { minmax_ = minmax; } @@ -86,7 +86,7 @@ public override void setupArguments(IPricingEngineArguments args) base.setupArguments(args); ContinuousFixedLookbackOption.Arguments moreArgs = args as ContinuousFixedLookbackOption.Arguments; - Utils.QL_REQUIRE(moreArgs != null,()=> "wrong argument type"); + Utils.QL_REQUIRE(moreArgs != null, () => "wrong argument type"); moreArgs.minmax = minmax_; } @@ -107,10 +107,10 @@ option. Partial-time floating strike lookback options can be (1994). */ - public class ContinuousPartialFloatingLookbackOption : ContinuousFloatingLookbackOption + public class ContinuousPartialFloatingLookbackOption : ContinuousFloatingLookbackOption { //! %Arguments for continuous partial floating lookback option calculation - public new class Arguments: ContinuousFloatingLookbackOption.Arguments + public new class Arguments: ContinuousFloatingLookbackOption.Arguments { public double lambda { get; set; } public Date lookbackPeriodEnd { get; set; } @@ -119,33 +119,33 @@ public override void validate() base.validate(); EuropeanExercise europeanExercise = exercise as EuropeanExercise; - Utils.QL_REQUIRE(lookbackPeriodEnd <= europeanExercise.lastDate(), ()=> - "lookback start date must be earlier than exercise date"); - + Utils.QL_REQUIRE(lookbackPeriodEnd <= europeanExercise.lastDate(), () => + "lookback start date must be earlier than exercise date"); + FloatingTypePayoff floatingTypePayoff = payoff as FloatingTypePayoff; - - if (floatingTypePayoff.optionType() == Option.Type.Call) + + if (floatingTypePayoff.optionType() == Option.Type.Call) { - Utils.QL_REQUIRE(lambda >= 1.0,()=> - "lambda should be greater than or equal to 1 for calls"); + Utils.QL_REQUIRE(lambda >= 1.0, () => + "lambda should be greater than or equal to 1 for calls"); } - - if (floatingTypePayoff.optionType() == Option.Type.Put) + + if (floatingTypePayoff.optionType() == Option.Type.Put) { - Utils.QL_REQUIRE(lambda <= 1.0,()=> - "lambda should be smaller than or equal to 1 for puts"); + Utils.QL_REQUIRE(lambda <= 1.0, () => + "lambda should be smaller than or equal to 1 for puts"); } } } //! %Continuous partial floating lookback %engine base class public new class Engine: GenericEngine + ContinuousPartialFloatingLookbackOption.Results> {} - public ContinuousPartialFloatingLookbackOption( double minmax, double lambda, - Date lookbackPeriodEnd,TypePayoff payoff,Exercise exercise) - :base(minmax, payoff, exercise) + public ContinuousPartialFloatingLookbackOption(double minmax, double lambda, + Date lookbackPeriodEnd, TypePayoff payoff, Exercise exercise) + : base(minmax, payoff, exercise) { lambda_ = lambda; lookbackPeriodEnd_ = lookbackPeriodEnd; @@ -155,16 +155,16 @@ public override void setupArguments(IPricingEngineArguments args) base.setupArguments(args); ContinuousPartialFloatingLookbackOption.Arguments moreArgs = args as ContinuousPartialFloatingLookbackOption.Arguments; - Utils.QL_REQUIRE(moreArgs != null,()=> "wrong argument type"); + Utils.QL_REQUIRE(moreArgs != null, () => "wrong argument type"); moreArgs.lambda = lambda_; moreArgs.lookbackPeriodEnd = lookbackPeriodEnd_; } - + protected double lambda_; protected Date lookbackPeriodEnd_; } - + //! Continuous-partial-fixed lookback option /*! From http://help.rmetrics.org/fExoticOptions/LookbackOptions.html : @@ -184,10 +184,10 @@ observed price of the underlying asset during the lookback (1994). */ - public class ContinuousPartialFixedLookbackOption : ContinuousFixedLookbackOption + public class ContinuousPartialFixedLookbackOption : ContinuousFixedLookbackOption { //! %Arguments for continuous partial fixed lookback option calculation - public new class Arguments : ContinuousFixedLookbackOption.Arguments + public new class Arguments : ContinuousFixedLookbackOption.Arguments { public Date lookbackPeriodStart { get; set; } public override void validate() @@ -195,16 +195,16 @@ public override void validate() base.validate(); EuropeanExercise europeanExercise = exercise as EuropeanExercise; - Utils.QL_REQUIRE(lookbackPeriodStart <= europeanExercise.lastDate(), ()=> - "lookback start date must be earlier than exercise date"); + Utils.QL_REQUIRE(lookbackPeriodStart <= europeanExercise.lastDate(), () => + "lookback start date must be earlier than exercise date"); } } //! %Continuous partial fixed lookback %engine base class public new class Engine : GenericEngine + ContinuousPartialFixedLookbackOption.Results> {} - public ContinuousPartialFixedLookbackOption(Date lookbackPeriodStart,StrikedTypePayoff payoff,Exercise exercise) - :base(0, payoff, exercise) + public ContinuousPartialFixedLookbackOption(Date lookbackPeriodStart, StrikedTypePayoff payoff, Exercise exercise) + : base(0, payoff, exercise) { lookbackPeriodStart_ = lookbackPeriodStart; } @@ -213,10 +213,10 @@ public override void setupArguments(IPricingEngineArguments args) base.setupArguments(args); ContinuousPartialFixedLookbackOption.Arguments moreArgs = args as ContinuousPartialFixedLookbackOption.Arguments; - Utils.QL_REQUIRE(moreArgs != null,()=> "wrong argument type"); + Utils.QL_REQUIRE(moreArgs != null, () => "wrong argument type"); moreArgs.lookbackPeriodStart = lookbackPeriodStart_; } - + protected Date lookbackPeriodStart_; } diff --git a/src/QLNet/Instruments/MakeBasisSwap.cs b/src/QLNet/Instruments/MakeBasisSwap.cs index 5bc890098..aa8581d80 100644 --- a/src/QLNet/Instruments/MakeBasisSwap.cs +++ b/src/QLNet/Instruments/MakeBasisSwap.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -107,7 +107,7 @@ public MakeBasisSwap withRule(DateGeneration.Rule r) } public MakeBasisSwap withDiscountingTermStructure(Handle discountingTermStructure1, - Handle discountingTermStructure2) + Handle discountingTermStructure2) { engine_ = new DiscountingBasisSwapEngine(discountingTermStructure1, discountingTermStructure2); return this; @@ -240,20 +240,20 @@ public BasisSwap value() Schedule float1Schedule = new Schedule(startDate, endDate, - float1Tenor_, float1Calendar_, - float1Convention_, float1TerminationDateConvention_, - float1Rule_, float1EndOfMonth_, - float1FirstDate_, float1NextToLastDate_); + float1Tenor_, float1Calendar_, + float1Convention_, float1TerminationDateConvention_, + float1Rule_, float1EndOfMonth_, + float1FirstDate_, float1NextToLastDate_); Schedule float2Schedule = new Schedule(startDate, endDate, - float2Tenor_, float2Calendar_, - float2Convention_, float2TerminationDateConvention_, - float2Rule_, float2EndOfMonth_, - float2FirstDate_, float2NextToLastDate_); + float2Tenor_, float2Calendar_, + float2Convention_, float2TerminationDateConvention_, + float2Rule_, float2EndOfMonth_, + float2FirstDate_, float2NextToLastDate_); - BasisSwap swap = new BasisSwap(type_, nominal_, - float1Schedule, iborIndex1_, float1Spread_,float1DayCount_, + BasisSwap swap = new BasisSwap(type_, nominal_, + float1Schedule, iborIndex1_, float1Spread_, float1DayCount_, float2Schedule, iborIndex2_, float2Spread_, float2DayCount_); swap.setPricingEngine(engine_); return swap; diff --git a/src/QLNet/Instruments/MakeCDS.cs b/src/QLNet/Instruments/MakeCDS.cs index b2b4397f5..94c019b5d 100644 --- a/src/QLNet/Instruments/MakeCDS.cs +++ b/src/QLNet/Instruments/MakeCDS.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -26,7 +26,7 @@ public MakeCreditDefaultSwap(Period tenor, double couponRate) side_ = Protection.Side.Buyer; nominal_ = 1.0; tenor_ = tenor; - couponTenor_ = new Period(3 , TimeUnit.Months); + couponTenor_ = new Period(3, TimeUnit.Months); couponRate_ = couponRate; upfrontRate_ = 0.0; dayCounter_ = new Actual360(); @@ -48,7 +48,7 @@ public CreditDefaultSwap value() { Date evaluation = Settings.evaluationDate(); Date start = evaluation + 1; - Date upfrontDate = new WeekendsOnly().advance(evaluation, new Period(3 , TimeUnit.Days)); + Date upfrontDate = new WeekendsOnly().advance(evaluation, new Period(3, TimeUnit.Days)); Date end; if (tenor_ != null) { @@ -60,11 +60,11 @@ public CreditDefaultSwap value() } Schedule schedule = new Schedule(start, end, couponTenor_, new WeekendsOnly(), - BusinessDayConvention.Following,BusinessDayConvention.Unadjusted, DateGeneration.Rule.CDS, - false, null,null); + BusinessDayConvention.Following, BusinessDayConvention.Unadjusted, DateGeneration.Rule.CDS, + false, null, null); CreditDefaultSwap cds = new CreditDefaultSwap(side_, nominal_, upfrontRate_, couponRate_, schedule, - BusinessDayConvention.Following,dayCounter_, true, true, start, upfrontDate, null,lastPeriodDayCounter_); + BusinessDayConvention.Following, dayCounter_, true, true, start, upfrontDate, null, lastPeriodDayCounter_); cds.setPricingEngine(engine_); return cds; diff --git a/src/QLNet/Instruments/MakeCapFloor.cs b/src/QLNet/Instruments/MakeCapFloor.cs index 976d1f364..e5955d2da 100644 --- a/src/QLNet/Instruments/MakeCapFloor.cs +++ b/src/QLNet/Instruments/MakeCapFloor.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,141 +24,141 @@ to instantiate standard market cap and floor. */ public class MakeCapFloor { - public MakeCapFloor(CapFloorType capFloorType,Period tenor,IborIndex iborIndex,double? strike = null, + public MakeCapFloor(CapFloorType capFloorType, Period tenor, IborIndex iborIndex, double? strike = null, Period forwardStart = null) { capFloorType_ = capFloorType; strike_ = strike; - firstCapletExcluded_ = (forwardStart == new Period(0,TimeUnit.Days)); + firstCapletExcluded_ = (forwardStart == new Period(0, TimeUnit.Days)); asOptionlet_ = false; makeVanillaSwap_ = new MakeVanillaSwap(tenor, iborIndex, 0.0, forwardStart); } - public static implicit operator CapFloor( MakeCapFloor o ) { return o.value(); } + public static implicit operator CapFloor(MakeCapFloor o) { return o.value(); } public CapFloor value() { VanillaSwap swap = makeVanillaSwap_; - List leg = swap.floatingLeg(); - if (firstCapletExcluded_) + List leg = swap.floatingLeg(); + if (firstCapletExcluded_) leg.RemoveAt(0); - + // only leaves the last coupon - if (asOptionlet_ && leg.Count > 1) + if (asOptionlet_ && leg.Count > 1) { - leg.RemoveRange(0, leg.Count-2); // Sun Studio needs an lvalue + leg.RemoveRange(0, leg.Count - 2); // Sun Studio needs an lvalue } - List strikeVector ; - if (strike_ == null) + List strikeVector ; + if (strike_ == null) { // temporary patch... // should be fixed for every CapFloor::Engine BlackCapFloorEngine temp = engine_ as BlackCapFloorEngine; - Utils.QL_REQUIRE(temp!=null,()=> "cannot calculate ATM without a BlackCapFloorEngine"); + Utils.QL_REQUIRE(temp != null, () => "cannot calculate ATM without a BlackCapFloorEngine"); Handle discountCurve = temp.termStructure(); - strikeVector = new InitializedList( 1, CashFlows.atmRate( leg, discountCurve, false, discountCurve.link.referenceDate() ) ); - } + strikeVector = new InitializedList(1, CashFlows.atmRate(leg, discountCurve, false, discountCurve.link.referenceDate())); + } else { - strikeVector = new InitializedList( 1, strike_.Value ); + strikeVector = new InitializedList(1, strike_.Value); } - CapFloor capFloor = new CapFloor(capFloorType_, leg, strikeVector); - capFloor.setPricingEngine(engine_); - return capFloor; + CapFloor capFloor = new CapFloor(capFloorType_, leg, strikeVector); + capFloor.setPricingEngine(engine_); + return capFloor; } - public MakeCapFloor withNominal( double n ) + public MakeCapFloor withNominal(double n) { - makeVanillaSwap_.withNominal( n ); + makeVanillaSwap_.withNominal(n); return this; } - public MakeCapFloor withEffectiveDate( Date effectiveDate, bool firstCapletExcluded ) + public MakeCapFloor withEffectiveDate(Date effectiveDate, bool firstCapletExcluded) { - makeVanillaSwap_.withEffectiveDate( effectiveDate ); + makeVanillaSwap_.withEffectiveDate(effectiveDate); firstCapletExcluded_ = firstCapletExcluded; return this; } - public MakeCapFloor withTenor( Period t ) + public MakeCapFloor withTenor(Period t) { - makeVanillaSwap_.withFixedLegTenor( t ); - makeVanillaSwap_.withFloatingLegTenor( t ); + makeVanillaSwap_.withFixedLegTenor(t); + makeVanillaSwap_.withFloatingLegTenor(t); return this; } - public MakeCapFloor withCalendar( Calendar cal ) + public MakeCapFloor withCalendar(Calendar cal) { - makeVanillaSwap_.withFixedLegCalendar( cal ); - makeVanillaSwap_.withFloatingLegCalendar( cal ); + makeVanillaSwap_.withFixedLegCalendar(cal); + makeVanillaSwap_.withFloatingLegCalendar(cal); return this; } - public MakeCapFloor withConvention( BusinessDayConvention bdc ) + public MakeCapFloor withConvention(BusinessDayConvention bdc) { - makeVanillaSwap_.withFixedLegConvention( bdc ); - makeVanillaSwap_.withFloatingLegConvention( bdc ); + makeVanillaSwap_.withFixedLegConvention(bdc); + makeVanillaSwap_.withFloatingLegConvention(bdc); return this; } - public MakeCapFloor withTerminationDateConvention( BusinessDayConvention bdc ) + public MakeCapFloor withTerminationDateConvention(BusinessDayConvention bdc) { - makeVanillaSwap_.withFixedLegTerminationDateConvention( bdc ); - makeVanillaSwap_.withFloatingLegTerminationDateConvention( bdc ); + makeVanillaSwap_.withFixedLegTerminationDateConvention(bdc); + makeVanillaSwap_.withFloatingLegTerminationDateConvention(bdc); return this; } - public MakeCapFloor withRule( DateGeneration.Rule r ) + public MakeCapFloor withRule(DateGeneration.Rule r) { - makeVanillaSwap_.withFixedLegRule( r ); - makeVanillaSwap_.withFloatingLegRule( r ); + makeVanillaSwap_.withFixedLegRule(r); + makeVanillaSwap_.withFloatingLegRule(r); return this; } - public MakeCapFloor withEndOfMonth( bool flag = true ) + public MakeCapFloor withEndOfMonth(bool flag = true) { - makeVanillaSwap_.withFixedLegEndOfMonth( flag ); - makeVanillaSwap_.withFloatingLegEndOfMonth( flag ); + makeVanillaSwap_.withFixedLegEndOfMonth(flag); + makeVanillaSwap_.withFloatingLegEndOfMonth(flag); return this; } - public MakeCapFloor withFirstDate( Date d ) + public MakeCapFloor withFirstDate(Date d) { - makeVanillaSwap_.withFixedLegFirstDate( d ); - makeVanillaSwap_.withFloatingLegFirstDate( d ); + makeVanillaSwap_.withFixedLegFirstDate(d); + makeVanillaSwap_.withFloatingLegFirstDate(d); return this; } - public MakeCapFloor withNextToLastDate( Date d ) + public MakeCapFloor withNextToLastDate(Date d) { - makeVanillaSwap_.withFixedLegNextToLastDate( d ); - makeVanillaSwap_.withFloatingLegNextToLastDate( d ); - return this; + makeVanillaSwap_.withFixedLegNextToLastDate(d); + makeVanillaSwap_.withFloatingLegNextToLastDate(d); + return this; } - public MakeCapFloor withDayCount( DayCounter dc ) + public MakeCapFloor withDayCount(DayCounter dc) { - makeVanillaSwap_.withFixedLegDayCount( dc ); - makeVanillaSwap_.withFloatingLegDayCount( dc ); + makeVanillaSwap_.withFixedLegDayCount(dc); + makeVanillaSwap_.withFloatingLegDayCount(dc); return this; } //! only get last coupon - public MakeCapFloor asOptionlet( bool b = true ) + public MakeCapFloor asOptionlet(bool b = true) { asOptionlet_ = b; return this; } - public MakeCapFloor withPricingEngine( IPricingEngine engine ) + public MakeCapFloor withPricingEngine(IPricingEngine engine) { engine_ = engine; return this; } - + private CapFloorType capFloorType_; private double? strike_; private bool firstCapletExcluded_, asOptionlet_; diff --git a/src/QLNet/Instruments/MakeCms.cs b/src/QLNet/Instruments/MakeCms.cs index b3735e1e3..8f68598b2 100644 --- a/src/QLNet/Instruments/MakeCms.cs +++ b/src/QLNet/Instruments/MakeCms.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,87 +24,87 @@ to instantiate standard market constant maturity swap. */ public class MakeCms { - public MakeCms( Period swapTenor, - SwapIndex swapIndex, - IborIndex iborIndex, - double iborSpread = 0.0, - Period forwardStart = null, - Date maturityDate = null) - { - swapTenor_ = swapTenor; + public MakeCms(Period swapTenor, + SwapIndex swapIndex, + IborIndex iborIndex, + double iborSpread = 0.0, + Period forwardStart = null, + Date maturityDate = null) + { + swapTenor_ = swapTenor; swapIndex_ = swapIndex; - iborIndex_ = iborIndex; - iborSpread_ = iborSpread; - iborCap_ = null; + iborIndex_ = iborIndex; + iborSpread_ = iborSpread; + iborCap_ = null; iborFloor_ = null; - useAtmSpread_ = false; - forwardStart_ = forwardStart ?? new Period(0,TimeUnit.Days); - cmsSpread_ = 0.0; + useAtmSpread_ = false; + forwardStart_ = forwardStart ?? new Period(0, TimeUnit.Days); + cmsSpread_ = 0.0; cmsGearing_ = 1.0; - cmsCap_ = null; + cmsCap_ = null; cmsFloor_ = null; effectiveDate_ = null; cmsCalendar_ = swapIndex.fixingCalendar(); floatCalendar_ = iborIndex.fixingCalendar(); - payCms_ = true; - nominal_ = 1.0; + payCms_ = true; + nominal_ = 1.0; maturityDate_ = maturityDate; - cmsTenor_ = new Period(3,TimeUnit.Months); + cmsTenor_ = new Period(3, TimeUnit.Months); floatTenor_ = iborIndex.tenor(); cmsConvention_ = BusinessDayConvention.ModifiedFollowing; cmsTerminationDateConvention_ = BusinessDayConvention.ModifiedFollowing; floatConvention_ = iborIndex.businessDayConvention(); floatTerminationDateConvention_ = iborIndex.businessDayConvention(); - cmsRule_ = DateGeneration.Rule.Backward; + cmsRule_ = DateGeneration.Rule.Backward; floatRule_ = DateGeneration.Rule.Backward; - cmsEndOfMonth_ = false; + cmsEndOfMonth_ = false; floatEndOfMonth_ = false; - cmsFirstDate_ = null; + cmsFirstDate_ = null; cmsNextToLastDate_ = null; - floatFirstDate_ = null; + floatFirstDate_ = null; floatNextToLastDate_ = null; cmsDayCount_ = new Actual360(); floatDayCount_ = iborIndex.dayCounter(); engine_ = new DiscountingSwapEngine(swapIndex.forwardingTermStructure()); } - public MakeCms( Period swapTenor, - SwapIndex swapIndex, - double iborSpread = 0.0, - Period forwardStart = null, - Date maturityDate = null) + public MakeCms(Period swapTenor, + SwapIndex swapIndex, + double iborSpread = 0.0, + Period forwardStart = null, + Date maturityDate = null) { - swapTenor_ = swapTenor; + swapTenor_ = swapTenor; swapIndex_ = swapIndex; - iborIndex_ = swapIndex.iborIndex(); - iborSpread_ = iborSpread; - iborCap_ = null; + iborIndex_ = swapIndex.iborIndex(); + iborSpread_ = iborSpread; + iborCap_ = null; iborFloor_ = null; - useAtmSpread_ = false; - forwardStart_ = forwardStart ?? new Period(0,TimeUnit.Days); - cmsSpread_ = 0.0; + useAtmSpread_ = false; + forwardStart_ = forwardStart ?? new Period(0, TimeUnit.Days); + cmsSpread_ = 0.0; cmsGearing_ = 1.0; - cmsCap_ = null; + cmsCap_ = null; cmsFloor_ = null; effectiveDate_ = null; cmsCalendar_ = swapIndex.fixingCalendar(); floatCalendar_ = iborIndex_.fixingCalendar(); - payCms_ = true; - nominal_ = 1.0; + payCms_ = true; + nominal_ = 1.0; maturityDate_ = maturityDate; - cmsTenor_ = new Period(3,TimeUnit.Months); + cmsTenor_ = new Period(3, TimeUnit.Months); floatTenor_ = iborIndex_.tenor(); cmsConvention_ = BusinessDayConvention.ModifiedFollowing; cmsTerminationDateConvention_ = BusinessDayConvention.ModifiedFollowing; floatConvention_ = iborIndex_.businessDayConvention(); floatTerminationDateConvention_ = iborIndex_.businessDayConvention(); - cmsRule_ = DateGeneration.Rule.Backward; + cmsRule_ = DateGeneration.Rule.Backward; floatRule_ = DateGeneration.Rule.Backward; - cmsEndOfMonth_ = false; + cmsEndOfMonth_ = false; floatEndOfMonth_ = false; - cmsFirstDate_ = null; + cmsFirstDate_ = null; cmsNextToLastDate_ = null; - floatFirstDate_ = null; + floatFirstDate_ = null; floatNextToLastDate_ = null; cmsDayCount_ = new Actual360(); floatDayCount_ = iborIndex_.dayCounter(); @@ -116,89 +116,89 @@ public Swap value() Date startDate; if (effectiveDate_ != null) startDate = effectiveDate_; - else + else { int fixingDays = iborIndex_.fixingDays(); Date refDate = Settings.evaluationDate(); // if the evaluation date is not a business day // then move to the next business day refDate = floatCalendar_.adjust(refDate); - Date spotDate = floatCalendar_.advance(refDate, new Period(fixingDays,TimeUnit.Days)); - startDate = spotDate+forwardStart_; - } - - Date terminationDate = maturityDate_ == null ? startDate + swapTenor_ : maturityDate_; + Date spotDate = floatCalendar_.advance(refDate, new Period(fixingDays, TimeUnit.Days)); + startDate = spotDate + forwardStart_; + } - Schedule cmsSchedule = new Schedule(startDate, terminationDate, - cmsTenor_, cmsCalendar_, - cmsConvention_, - cmsTerminationDateConvention_, - cmsRule_, cmsEndOfMonth_, - cmsFirstDate_, cmsNextToLastDate_); + Date terminationDate = maturityDate_ == null ? startDate + swapTenor_ : maturityDate_; - Schedule floatSchedule = new Schedule(startDate, terminationDate, - floatTenor_, floatCalendar_, - floatConvention_, - floatTerminationDateConvention_, - floatRule_ , floatEndOfMonth_, - floatFirstDate_, floatNextToLastDate_); + Schedule cmsSchedule = new Schedule(startDate, terminationDate, + cmsTenor_, cmsCalendar_, + cmsConvention_, + cmsTerminationDateConvention_, + cmsRule_, cmsEndOfMonth_, + cmsFirstDate_, cmsNextToLastDate_); + + Schedule floatSchedule = new Schedule(startDate, terminationDate, + floatTenor_, floatCalendar_, + floatConvention_, + floatTerminationDateConvention_, + floatRule_, floatEndOfMonth_, + floatFirstDate_, floatNextToLastDate_); List cmsLeg = new CmsLeg(cmsSchedule, swapIndex_) - .withPaymentDayCounter(cmsDayCount_) - .withFixingDays(swapIndex_.fixingDays()) - .withGearings(cmsGearing_) - .withSpreads(cmsSpread_) - .withCaps(cmsCap_) - .withFloors(cmsFloor_) - .withNotionals(nominal_) - .withPaymentAdjustment(cmsConvention_); + .withPaymentDayCounter(cmsDayCount_) + .withFixingDays(swapIndex_.fixingDays()) + .withGearings(cmsGearing_) + .withSpreads(cmsSpread_) + .withCaps(cmsCap_) + .withFloors(cmsFloor_) + .withNotionals(nominal_) + .withPaymentAdjustment(cmsConvention_); if (couponPricer_ != null) Utils.setCouponPricer(cmsLeg, couponPricer_); double? usedSpread = iborSpread_; - if (useAtmSpread_) + if (useAtmSpread_) { - Utils.QL_REQUIRE(!iborIndex_.forwardingTermStructure().empty(),()=> - "null term structure set to this instance of " + iborIndex_.name()); - Utils.QL_REQUIRE(!swapIndex_.forwardingTermStructure().empty(),()=> - "null term structure set to this instance of " + swapIndex_.name()); - Utils.QL_REQUIRE(couponPricer_ != null,()=> "no CmsCouponPricer set (yet)"); + Utils.QL_REQUIRE(!iborIndex_.forwardingTermStructure().empty(), () => + "null term structure set to this instance of " + iborIndex_.name()); + Utils.QL_REQUIRE(!swapIndex_.forwardingTermStructure().empty(), () => + "null term structure set to this instance of " + swapIndex_.name()); + Utils.QL_REQUIRE(couponPricer_ != null, () => "no CmsCouponPricer set (yet)"); List fLeg = new IborLeg(floatSchedule, iborIndex_) - .withPaymentDayCounter(floatDayCount_) - .withFixingDays(iborIndex_.fixingDays()) - .withCaps(iborCap_) - .withFloors(iborFloor_) - .withNotionals(nominal_) - .withPaymentAdjustment(floatConvention_); - - if (iborCouponPricer_ != null) - Utils.setCouponPricer(fLeg, iborCouponPricer_); + .withPaymentDayCounter(floatDayCount_) + .withFixingDays(iborIndex_.fixingDays()) + .withCaps(iborCap_) + .withFloors(iborFloor_) + .withNotionals(nominal_) + .withPaymentAdjustment(floatConvention_); + + if (iborCouponPricer_ != null) + Utils.setCouponPricer(fLeg, iborCouponPricer_); Swap temp = new Swap(cmsLeg, fLeg); temp.setPricingEngine(engine_); - double? npv = temp.legNPV(0)+temp.legNPV(1); + double? npv = temp.legNPV(0) + temp.legNPV(1); - usedSpread = -npv/temp.legBPS(1)*1e-4; - } - else + usedSpread = -npv / temp.legBPS(1) * 1e-4; + } + else { - Utils.QL_REQUIRE(usedSpread.HasValue,()=>"null spread set"); + Utils.QL_REQUIRE(usedSpread.HasValue, () => "null spread set"); } List floatLeg = new IborLeg(floatSchedule, iborIndex_) - .withSpreads(usedSpread.Value) - .withPaymentDayCounter(floatDayCount_) - .withFixingDays(iborIndex_.fixingDays()) - .withGearings(iborGearing_) - .withCaps(iborCap_) - .withFloors(iborFloor_) - .withPaymentAdjustment(floatConvention_) - .withNotionals(nominal_); - - if (iborCouponPricer_ != null) - Utils.setCouponPricer(floatLeg, iborCouponPricer_); + .withSpreads(usedSpread.Value) + .withPaymentDayCounter(floatDayCount_) + .withFixingDays(iborIndex_.fixingDays()) + .withGearings(iborGearing_) + .withCaps(iborCap_) + .withFloors(iborFloor_) + .withPaymentAdjustment(floatConvention_) + .withNotionals(nominal_); + + if (iborCouponPricer_ != null) + Utils.setCouponPricer(floatLeg, iborCouponPricer_); Swap swap; if (payCms_) @@ -219,7 +219,7 @@ public MakeCms withNominal(double n) nominal_ = n; return this; } - public MakeCms withEffectiveDate( Date effectiveDate ) + public MakeCms withEffectiveDate(Date effectiveDate) { effectiveDate_ = effectiveDate; return this; @@ -229,7 +229,7 @@ public MakeCms withCmsLegTenor(Period t) cmsTenor_ = t; return this; } - public MakeCms withCmsLegCalendar( Calendar cal) + public MakeCms withCmsLegCalendar(Calendar cal) { cmsCalendar_ = cal; return this; @@ -239,7 +239,7 @@ public MakeCms withCmsLegConvention(BusinessDayConvention bdc) cmsConvention_ = bdc; return this; } - public MakeCms withCmsLegTerminationDateConvention( BusinessDayConvention bdc ) + public MakeCms withCmsLegTerminationDateConvention(BusinessDayConvention bdc) { cmsTerminationDateConvention_ = bdc; return this; @@ -254,27 +254,27 @@ public MakeCms withCmsLegEndOfMonth(bool flag = true) cmsEndOfMonth_ = flag; return this; } - public MakeCms withCmsLegFirstDate( Date d) + public MakeCms withCmsLegFirstDate(Date d) { cmsFirstDate_ = d; return this; } - public MakeCms withCmsLegNextToLastDate( Date d) + public MakeCms withCmsLegNextToLastDate(Date d) { cmsNextToLastDate_ = d; return this; } - public MakeCms withCmsLegDayCount( DayCounter dc) + public MakeCms withCmsLegDayCount(DayCounter dc) { cmsDayCount_ = dc; return this; } - public MakeCms withFloatingLegTenor( Period t) + public MakeCms withFloatingLegTenor(Period t) { floatTenor_ = t; return this; } - public MakeCms withFloatingLegCalendar( Calendar cal) + public MakeCms withFloatingLegCalendar(Calendar cal) { floatCalendar_ = cal; return this; @@ -284,7 +284,7 @@ public MakeCms withFloatingLegConvention(BusinessDayConvention bdc) floatConvention_ = bdc; return this; } - public MakeCms withFloatingLegTerminationDateConvention( BusinessDayConvention bdc) + public MakeCms withFloatingLegTerminationDateConvention(BusinessDayConvention bdc) { floatTerminationDateConvention_ = bdc; return this; @@ -299,82 +299,82 @@ public MakeCms withFloatingLegEndOfMonth(bool flag = true) floatEndOfMonth_ = flag; return this; } - public MakeCms withFloatingLegFirstDate( Date d) + public MakeCms withFloatingLegFirstDate(Date d) { floatFirstDate_ = d; return this; } - public MakeCms withFloatingLegNextToLastDate( Date d) + public MakeCms withFloatingLegNextToLastDate(Date d) { floatNextToLastDate_ = d; return this; } - public MakeCms withFloatingLegDayCount( DayCounter dc) + public MakeCms withFloatingLegDayCount(DayCounter dc) { floatDayCount_ = dc; return this; - } - public MakeCms withFloatingCouponPricer(IborCouponPricer couponPricer) - { - iborCouponPricer_ = couponPricer; - return this; - } - public MakeCms withFloatingLegGearing(double iborGearing) - { - iborGearing_ = iborGearing; - return this; + } + public MakeCms withFloatingCouponPricer(IborCouponPricer couponPricer) + { + iborCouponPricer_ = couponPricer; + return this; + } + public MakeCms withFloatingLegGearing(double iborGearing) + { + iborGearing_ = iborGearing; + return this; } public MakeCms withAtmSpread(bool flag = true) { useAtmSpread_ = flag; return this; } - public MakeCms withDiscountingTermStructure( Handle discountingTermStructure) + public MakeCms withDiscountingTermStructure(Handle discountingTermStructure) { engine_ = new DiscountingSwapEngine(discountingTermStructure); return this; - } - public MakeCms withCmsCouponPricer( CmsCouponPricer couponPricer) + } + public MakeCms withCmsCouponPricer(CmsCouponPricer couponPricer) { couponPricer_ = couponPricer; return this; - } - public MakeCms withCmsGearing(double cmsGearing) - { - cmsGearing_ = cmsGearing; - return this; - } - public MakeCms withCmsSpread(double cmsSpread) - { - cmsSpread_ = cmsSpread; - return this; - } - public MakeCms withCmsCap(double? cmsCap) - { - cmsCap_ = cmsCap; - return this; - } - public MakeCms withCmsFloor(double? cmsFloor) - { - cmsFloor_ = cmsFloor; - return this; - } - public MakeCms withIborCap(double? iborCap) - { - iborCap_ = iborCap; - return this; - } - public MakeCms withIborFloor(double? iborFloor) - { - iborFloor_ = iborFloor; - return this; + } + public MakeCms withCmsGearing(double cmsGearing) + { + cmsGearing_ = cmsGearing; + return this; + } + public MakeCms withCmsSpread(double cmsSpread) + { + cmsSpread_ = cmsSpread; + return this; + } + public MakeCms withCmsCap(double? cmsCap) + { + cmsCap_ = cmsCap; + return this; + } + public MakeCms withCmsFloor(double? cmsFloor) + { + cmsFloor_ = cmsFloor; + return this; + } + public MakeCms withIborCap(double? iborCap) + { + iborCap_ = iborCap; + return this; + } + public MakeCms withIborFloor(double? iborFloor) + { + iborFloor_ = iborFloor; + return this; } private Period swapTenor_; private SwapIndex swapIndex_; private IborIndex iborIndex_; - private double iborSpread_; - private double iborGearing_; + private double iborSpread_; + private double iborGearing_; private double? iborCap_, iborFloor_; private bool useAtmSpread_; private Period forwardStart_; @@ -394,12 +394,12 @@ public MakeCms withIborFloor(double? iborFloor) private DateGeneration.Rule cmsRule_, floatRule_; private bool cmsEndOfMonth_, floatEndOfMonth_; private Date cmsFirstDate_, cmsNextToLastDate_; - private Date floatFirstDate_, floatNextToLastDate_; + private Date floatFirstDate_, floatNextToLastDate_; private Date maturityDate_; private DayCounter cmsDayCount_, floatDayCount_; private IPricingEngine engine_; - private CmsCouponPricer couponPricer_; + private CmsCouponPricer couponPricer_; private IborCouponPricer iborCouponPricer_; } diff --git a/src/QLNet/Instruments/MakeLoans.cs b/src/QLNet/Instruments/MakeLoans.cs index fefa44c28..55b461150 100644 --- a/src/QLNet/Instruments/MakeLoans.cs +++ b/src/QLNet/Instruments/MakeLoans.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,7 +23,7 @@ public class MakeFixedLoan { private double nominal_; private Calendar calendar_; - private Date startDate_,endDate_; + private Date startDate_, endDate_; private Frequency frequency_; private BusinessDayConvention convention_ ; private DayCounter dayCounter_; @@ -33,7 +33,7 @@ public class MakeFixedLoan private DateGeneration.Rule rule_; private bool endOfMonth_; - public MakeFixedLoan(Date startDate, Date endDate, double fixedRate,Frequency frequency) + public MakeFixedLoan(Date startDate, Date endDate, double fixedRate, Frequency frequency) { startDate_ = startDate; endDate_ = endDate; @@ -105,17 +105,17 @@ public FixedLoan value() { Schedule fixedSchedule = new Schedule(startDate_, endDate_, new Period(frequency_), - calendar_, convention_, convention_, rule_, endOfMonth_); + calendar_, convention_, convention_, rule_, endOfMonth_); - Period principalPeriod = amortising_ == Loan.Amortising.Bullet ? - new Period(Frequency.Once) : + Period principalPeriod = amortising_ == Loan.Amortising.Bullet ? + new Period(Frequency.Once) : new Period(frequency_); Schedule principalSchedule = new Schedule(startDate_, endDate_, principalPeriod, - calendar_, convention_, convention_, rule_, endOfMonth_); + calendar_, convention_, convention_, rule_, endOfMonth_); FixedLoan fl = new FixedLoan(type_, nominal_, fixedSchedule, fixedRate_, dayCounter_, - principalSchedule, convention_); + principalSchedule, convention_); return fl; } @@ -216,17 +216,17 @@ public FloatingLoan value() { Schedule floatingSchedule = new Schedule(startDate_, endDate_, new Period(frequency_), - calendar_, convention_, convention_, rule_, endOfMonth_); + calendar_, convention_, convention_, rule_, endOfMonth_); Period principalPeriod = amortising_ == Loan.Amortising.Bullet ? new Period(Frequency.Once) : new Period(frequency_); Schedule principalSchedule = new Schedule(startDate_, endDate_, principalPeriod, - calendar_, convention_, convention_, rule_, endOfMonth_); + calendar_, convention_, convention_, rule_, endOfMonth_); FloatingLoan fl = new FloatingLoan(type_, nominal_, floatingSchedule, spread_, dayCounter_, - principalSchedule, convention_,index_); + principalSchedule, convention_, index_); return fl; } @@ -319,17 +319,17 @@ public CommercialPaper value() { Schedule fixedSchedule = new Schedule(startDate_, endDate_, new Period(frequency_), - calendar_, convention_, convention_, rule_, endOfMonth_); + calendar_, convention_, convention_, rule_, endOfMonth_); Period principalPeriod = amortising_ == Loan.Amortising.Bullet ? new Period(Frequency.Once) : new Period(frequency_); Schedule principalSchedule = new Schedule(startDate_, endDate_, principalPeriod, - calendar_, convention_, convention_, rule_, endOfMonth_); + calendar_, convention_, convention_, rule_, endOfMonth_); CommercialPaper fl = new CommercialPaper(type_, nominal_, fixedSchedule, fixedRate_, dayCounter_, - principalSchedule, convention_); + principalSchedule, convention_); return fl; } @@ -418,7 +418,7 @@ public Cash value() new Period(frequency_); Schedule principalSchedule = new Schedule(startDate_, endDate_, principalPeriod, - calendar_, convention_, convention_, rule_, endOfMonth_); + calendar_, convention_, convention_, rule_, endOfMonth_); Cash c = new Cash(type_, nominal_, principalSchedule, convention_); return c; diff --git a/src/QLNet/Instruments/MakeOIS.cs b/src/QLNet/Instruments/MakeOIS.cs index a450e0782..26aea3547 100644 --- a/src/QLNet/Instruments/MakeOIS.cs +++ b/src/QLNet/Instruments/MakeOIS.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -47,12 +47,12 @@ public class MakeOIS private IPricingEngine engine_; - public MakeOIS(Period swapTenor, OvernightIndex overnightIndex,double? fixedRate = null , Period fwdStart = null ) + public MakeOIS(Period swapTenor, OvernightIndex overnightIndex, double? fixedRate = null, Period fwdStart = null) { - swapTenor_=swapTenor; + swapTenor_ = swapTenor; overnightIndex_ = overnightIndex; - fixedRate_= fixedRate; - forwardStart_= fwdStart?? new Period(0,TimeUnit.Days); + fixedRate_ = fixedRate; + forwardStart_ = fwdStart ?? new Period(0, TimeUnit.Days); settlementDays_ = 2; calendar_ = overnightIndex.fixingCalendar(); paymentFrequency_ = Frequency.Annual; @@ -65,22 +65,22 @@ public MakeOIS(Period swapTenor, OvernightIndex overnightIndex,double? fixedRate fixedDayCount_ = overnightIndex.dayCounter(); } - public MakeOIS receiveFixed(bool flag = true) + public MakeOIS receiveFixed(bool flag = true) { - type_ = flag ? OvernightIndexedSwap.Type.Receiver : OvernightIndexedSwap.Type.Payer ; - return this; + type_ = flag ? OvernightIndexedSwap.Type.Receiver : OvernightIndexedSwap.Type.Payer ; + return this; } - public MakeOIS withType(OvernightIndexedSwap.Type type) + public MakeOIS withType(OvernightIndexedSwap.Type type) { type_ = type; return this; } - public MakeOIS withSettlementDays( int settlementDays ) + public MakeOIS withSettlementDays(int settlementDays) { settlementDays_ = settlementDays; - effectiveDate_ = null; + effectiveDate_ = null; return this; } @@ -90,7 +90,7 @@ public MakeOIS withEffectiveDate(Date effectiveDate) return this; } - public MakeOIS withTerminationDate(Date terminationDate) + public MakeOIS withTerminationDate(Date terminationDate) { terminationDate_ = terminationDate; swapTenor_ = new Period(); @@ -100,15 +100,15 @@ public MakeOIS withTerminationDate(Date terminationDate) public MakeOIS withPaymentFrequency(Frequency f) { paymentFrequency_ = f; - if (paymentFrequency_== Frequency.Once) + if (paymentFrequency_ == Frequency.Once) rule_ = DateGeneration.Rule.Zero; return this; } - public MakeOIS withRule(DateGeneration.Rule r) + public MakeOIS withRule(DateGeneration.Rule r) { rule_ = r; - if (r==DateGeneration.Rule.Zero) + if (r == DateGeneration.Rule.Zero) paymentFrequency_ = Frequency.Once; return this; } @@ -128,30 +128,30 @@ public MakeOIS withNominal(double n) public MakeOIS withDiscountingTermStructure(Handle discountingTermStructure) { - engine_ = (IPricingEngine) new DiscountingSwapEngine(discountingTermStructure,false); + engine_ = (IPricingEngine) new DiscountingSwapEngine(discountingTermStructure, false); return this; } - public MakeOIS withFixedLegDayCount(DayCounter dc) + public MakeOIS withFixedLegDayCount(DayCounter dc) { fixedDayCount_ = dc; return this; } - public MakeOIS withEndOfMonth(bool flag = true) + public MakeOIS withEndOfMonth(bool flag = true) { endOfMonth_ = flag; isDefaultEOM_ = false; return this; } - public MakeOIS withPricingEngine( IPricingEngine engine ) + public MakeOIS withPricingEngine(IPricingEngine engine) { engine_ = engine; return this; } - + // OIswap creator public static implicit operator OvernightIndexedSwap(MakeOIS o) { return o.value(); } @@ -159,83 +159,83 @@ public OvernightIndexedSwap value() { Date startDate; - if ( effectiveDate_ != null ) + if (effectiveDate_ != null) startDate = effectiveDate_; else { Date refDate = Settings.evaluationDate(); // if the evaluation date is not a business day // then move to the next business day - refDate = calendar_.adjust( refDate ); - Date spotDate = calendar_.advance( refDate, new Period( settlementDays_, TimeUnit.Days ) ); + refDate = calendar_.adjust(refDate); + Date spotDate = calendar_.advance(refDate, new Period(settlementDays_, TimeUnit.Days)); startDate = spotDate + forwardStart_; - if ( forwardStart_.length() < 0 ) - startDate = calendar_.adjust( startDate, BusinessDayConvention.Preceding ); + if (forwardStart_.length() < 0) + startDate = calendar_.adjust(startDate, BusinessDayConvention.Preceding); else - startDate = calendar_.adjust( startDate, BusinessDayConvention.Following ); + startDate = calendar_.adjust(startDate, BusinessDayConvention.Following); } // OIS end of month default bool usedEndOfMonth = - isDefaultEOM_ ? calendar_.isEndOfMonth( startDate ) : endOfMonth_; + isDefaultEOM_ ? calendar_.isEndOfMonth(startDate) : endOfMonth_; Date endDate = terminationDate_; - if ( endDate == null ) - if ( usedEndOfMonth ) - endDate = calendar_.advance( startDate, + if (endDate == null) + if (usedEndOfMonth) + endDate = calendar_.advance(startDate, swapTenor_, BusinessDayConvention.ModifiedFollowing, - usedEndOfMonth ); + usedEndOfMonth); else endDate = startDate + swapTenor_; - Schedule schedule = new Schedule( startDate, endDate, - new Period( paymentFrequency_ ), - calendar_, - BusinessDayConvention.ModifiedFollowing, - BusinessDayConvention.ModifiedFollowing, - rule_, - usedEndOfMonth ); + Schedule schedule = new Schedule(startDate, endDate, + new Period(paymentFrequency_), + calendar_, + BusinessDayConvention.ModifiedFollowing, + BusinessDayConvention.ModifiedFollowing, + rule_, + usedEndOfMonth); double? usedFixedRate = fixedRate_; - if ( fixedRate_ == null ) + if (fixedRate_ == null) { - OvernightIndexedSwap temp = new OvernightIndexedSwap( type_, nominal_, - schedule, - 0.0, // fixed rate - fixedDayCount_, - overnightIndex_, overnightSpread_ ); - if ( engine_ == null ) + OvernightIndexedSwap temp = new OvernightIndexedSwap(type_, nominal_, + schedule, + 0.0, // fixed rate + fixedDayCount_, + overnightIndex_, overnightSpread_); + if (engine_ == null) { Handle disc = overnightIndex_.forwardingTermStructure(); - Utils.QL_REQUIRE( !disc.empty(), () => "null term structure set to this instance of " + - overnightIndex_.name() ); + Utils.QL_REQUIRE(!disc.empty(), () => "null term structure set to this instance of " + + overnightIndex_.name()); bool includeSettlementDateFlows = false; - IPricingEngine engine = new DiscountingSwapEngine( disc, includeSettlementDateFlows ); - temp.setPricingEngine( engine ); + IPricingEngine engine = new DiscountingSwapEngine(disc, includeSettlementDateFlows); + temp.setPricingEngine(engine); } else - temp.setPricingEngine( engine_ ); + temp.setPricingEngine(engine_); usedFixedRate = temp.fairRate(); } - OvernightIndexedSwap ois = new OvernightIndexedSwap( type_, nominal_, - schedule, - usedFixedRate.Value, fixedDayCount_, - overnightIndex_, overnightSpread_ ); + OvernightIndexedSwap ois = new OvernightIndexedSwap(type_, nominal_, + schedule, + usedFixedRate.Value, fixedDayCount_, + overnightIndex_, overnightSpread_); - if ( engine_ == null ) + if (engine_ == null) { Handle disc = overnightIndex_.forwardingTermStructure(); bool includeSettlementDateFlows = false; - IPricingEngine engine = new DiscountingSwapEngine( disc, includeSettlementDateFlows ); - ois.setPricingEngine( engine ); + IPricingEngine engine = new DiscountingSwapEngine(disc, includeSettlementDateFlows); + ois.setPricingEngine(engine); } else - ois.setPricingEngine( engine_ ); + ois.setPricingEngine(engine_); return ois; } diff --git a/src/QLNet/Instruments/Makeswaption.cs b/src/QLNet/Instruments/Makeswaption.cs index 5518fa862..bf4ae30d9 100644 --- a/src/QLNet/Instruments/Makeswaption.cs +++ b/src/QLNet/Instruments/Makeswaption.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -75,8 +75,8 @@ public Swaption value() } else { - Utils.QL_REQUIRE(exerciseDate_ <= fixingDate_,()=> - "exercise date (" + exerciseDate_ + ") must be less " + "than or equal to fixing date (" + fixingDate_ + ")"); + Utils.QL_REQUIRE(exerciseDate_ <= fixingDate_, () => + "exercise date (" + exerciseDate_ + ") must be less " + "than or equal to fixing date (" + fixingDate_ + ")"); exercise_ = new EuropeanExercise(exerciseDate_); } @@ -85,7 +85,7 @@ public Swaption value() { // ATM on the forecasting curve Utils.QL_REQUIRE(!swapIndex_.forwardingTermStructure().empty(), () => - "no forecasting term structure set to " + swapIndex_.name()); + "no forecasting term structure set to " + swapIndex_.name()); VanillaSwap temp = swapIndex_.underlyingSwap(fixingDate_); temp.setPricingEngine(new DiscountingSwapEngine(swapIndex_.forwardingTermStructure())); usedStrike = temp.fairRate(); @@ -95,13 +95,13 @@ public Swaption value() BusinessDayConvention bdc = swapIndex_.fixedLegConvention(); underlyingSwap_ = new MakeVanillaSwap(swapIndex_.tenor(), - swapIndex_.iborIndex(), - usedStrike) - .withEffectiveDate(swapIndex_.valueDate(fixingDate_)) - .withFixedLegCalendar(swapIndex_.fixingCalendar()) - .withFixedLegDayCount(swapIndex_.dayCounter()) - .withFixedLegConvention(bdc) - .withFixedLegTerminationDateConvention(bdc); + swapIndex_.iborIndex(), + usedStrike) + .withEffectiveDate(swapIndex_.valueDate(fixingDate_)) + .withFixedLegCalendar(swapIndex_.fixingCalendar()) + .withFixedLegDayCount(swapIndex_.dayCounter()) + .withFixedLegConvention(bdc) + .withFixedLegTerminationDateConvention(bdc); Swaption swaption = new Swaption(underlyingSwap_, exercise_, delivery_); swaption.setPricingEngine(engine_); diff --git a/src/QLNet/Instruments/Makevanillaswap.cs b/src/QLNet/Instruments/Makevanillaswap.cs index e1f8085ff..e8cd398a0 100644 --- a/src/QLNet/Instruments/Makevanillaswap.cs +++ b/src/QLNet/Instruments/Makevanillaswap.cs @@ -1,312 +1,342 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { - // helper class - // This class provides a more comfortable way to instantiate standard market swap. - public class MakeVanillaSwap { - private Period forwardStart_, swapTenor_; - private IborIndex iborIndex_; - private double? fixedRate_; - private int settlementDays_; - private Date effectiveDate_, terminationDate_; - private Calendar fixedCalendar_, floatCalendar_; - - private VanillaSwap.Type type_; - private double nominal_; - private Period fixedTenor_, floatTenor_; - private BusinessDayConvention fixedConvention_, fixedTerminationDateConvention_; - private BusinessDayConvention floatConvention_, floatTerminationDateConvention_; - private DateGeneration.Rule fixedRule_, floatRule_; - private bool fixedEndOfMonth_, floatEndOfMonth_; - private Date fixedFirstDate_, fixedNextToLastDate_; - private Date floatFirstDate_, floatNextToLastDate_; - private double floatSpread_; - private DayCounter fixedDayCount_, floatDayCount_; - - IPricingEngine engine_; - - public MakeVanillaSwap(Period swapTenor, IborIndex index, double? fixedRate = null, Period forwardStart = null) - { - swapTenor_ = swapTenor; - iborIndex_ = index; - fixedRate_ = fixedRate; - forwardStart_ = forwardStart?? new Period(0,TimeUnit.Days); - settlementDays_ = iborIndex_.fixingDays(); - fixedCalendar_ = floatCalendar_ = index.fixingCalendar(); - - type_ = VanillaSwap.Type.Payer; - nominal_ = 1.0; - floatTenor_ = index.tenor(); - fixedConvention_ = fixedTerminationDateConvention_ = BusinessDayConvention.ModifiedFollowing; - floatConvention_ = floatTerminationDateConvention_ = index.businessDayConvention(); - fixedRule_ = floatRule_ = DateGeneration.Rule.Backward; - fixedEndOfMonth_ = floatEndOfMonth_ = false; - fixedFirstDate_ = fixedNextToLastDate_ = floatFirstDate_ = floatNextToLastDate_ = null; - floatSpread_ = 0.0; - floatDayCount_ = index.dayCounter(); - } - - public MakeVanillaSwap receiveFixed(bool flag = true) { - type_ = flag ? VanillaSwap.Type.Receiver : VanillaSwap.Type.Payer; - return this; - } - public MakeVanillaSwap withType(VanillaSwap.Type type) { - type_ = type; - return this; - } - public MakeVanillaSwap withNominal(double n) { - nominal_ = n; - return this; - } - public MakeVanillaSwap withSettlementDays( int settlementDays ) - { - settlementDays_ = settlementDays; - effectiveDate_ = null; - return this; - } - - public MakeVanillaSwap withEffectiveDate(Date effectiveDate) { - effectiveDate_ = effectiveDate; - return this; - } - - public MakeVanillaSwap withTerminationDate(Date terminationDate) { - terminationDate_ = terminationDate; - swapTenor_ = null; - return this; - } - - public MakeVanillaSwap withRule(DateGeneration.Rule r) { - fixedRule_ = r; - floatRule_ = r; - return this; - } - - public MakeVanillaSwap withDiscountingTermStructure(Handle discountingTermStructure) { - engine_ = new DiscountingSwapEngine(discountingTermStructure,false); - return this; - } - - public MakeVanillaSwap withPricingEngine(IPricingEngine engine) - { - engine_ = engine; - return this; - } - public MakeVanillaSwap withFixedLegTenor(Period t) { - fixedTenor_ = t; - return this; - } - public MakeVanillaSwap withFixedLegCalendar(Calendar cal) { - fixedCalendar_ = cal; - return this; - } - public MakeVanillaSwap withFixedLegConvention(BusinessDayConvention bdc) { - fixedConvention_ = bdc; - return this; - } - public MakeVanillaSwap withFixedLegTerminationDateConvention(BusinessDayConvention bdc) { - fixedTerminationDateConvention_ = bdc; - return this; - } - public MakeVanillaSwap withFixedLegRule(DateGeneration.Rule r) { - fixedRule_ = r; - return this; - } - - public MakeVanillaSwap withFixedLegEndOfMonth(bool flag = true ) { - fixedEndOfMonth_ = flag; - return this; - } - public MakeVanillaSwap withFixedLegFirstDate(Date d) { - fixedFirstDate_ = d; - return this; - } - public MakeVanillaSwap withFixedLegNextToLastDate(Date d) { - fixedNextToLastDate_ = d; - return this; - } - public MakeVanillaSwap withFixedLegDayCount(DayCounter dc) { - fixedDayCount_ = dc; - return this; - } - - public MakeVanillaSwap withFloatingLegTenor(Period t) { - floatTenor_ = t; - return this; - } - public MakeVanillaSwap withFloatingLegCalendar(Calendar cal) { - floatCalendar_ = cal; - return this; - } - public MakeVanillaSwap withFloatingLegConvention(BusinessDayConvention bdc) { - floatConvention_ = bdc; - return this; - } - public MakeVanillaSwap withFloatingLegTerminationDateConvention(BusinessDayConvention bdc) { - floatTerminationDateConvention_ = bdc; - return this; - } - public MakeVanillaSwap withFloatingLegRule(DateGeneration.Rule r) { - floatRule_ = r; - return this; - } - - public MakeVanillaSwap withFloatingLegEndOfMonth(bool flag = true) { - floatEndOfMonth_ = flag; - return this; - } - public MakeVanillaSwap withFloatingLegFirstDate(Date d) { - floatFirstDate_ = d; - return this; - } - public MakeVanillaSwap withFloatingLegNextToLastDate(Date d) { - floatNextToLastDate_ = d; - return this; - } - public MakeVanillaSwap withFloatingLegDayCount(DayCounter dc) { - floatDayCount_ = dc; - return this; - } - public MakeVanillaSwap withFloatingLegSpread(double sp) { - floatSpread_ = sp; - return this; - } - - - // swap creator - public static implicit operator VanillaSwap(MakeVanillaSwap o) { return o.value(); } - public VanillaSwap value() { - Date startDate; - - if (effectiveDate_ != null) - startDate = effectiveDate_; - else { - Date refDate = Settings.evaluationDate(); - // if the evaluation date is not a business day - // then move to the next business day - refDate = floatCalendar_.adjust( refDate ); - Date spotDate = floatCalendar_.advance( refDate, new Period( settlementDays_, TimeUnit.Days ) ); - startDate = spotDate + forwardStart_; - if ( forwardStart_.length() < 0 ) - startDate = floatCalendar_.adjust( startDate,BusinessDayConvention.Preceding); - else - startDate = floatCalendar_.adjust( startDate,BusinessDayConvention.Following ); - } +namespace QLNet +{ + // helper class + // This class provides a more comfortable way to instantiate standard market swap. + public class MakeVanillaSwap + { + private Period forwardStart_, swapTenor_; + private IborIndex iborIndex_; + private double? fixedRate_; + private int settlementDays_; + private Date effectiveDate_, terminationDate_; + private Calendar fixedCalendar_, floatCalendar_; - Date endDate = terminationDate_; - if ( endDate == null ) - if ( floatEndOfMonth_ ) - endDate = floatCalendar_.advance( startDate, - swapTenor_, - BusinessDayConvention.ModifiedFollowing, - floatEndOfMonth_ ); - else - endDate = startDate + swapTenor_; - - Currency curr = iborIndex_.currency(); - Period fixedTenor = null ; - if (fixedTenor_ != null) - fixedTenor = fixedTenor_; - else - { - if ((curr == new EURCurrency()) || - (curr == new USDCurrency()) || - (curr == new CHFCurrency()) || - (curr == new SEKCurrency()) || - (curr == new GBPCurrency() && swapTenor_ <= new Period( 1 , TimeUnit.Years))) - fixedTenor = new Period(1, TimeUnit.Years); - else if ((curr == new GBPCurrency() && swapTenor_ > new Period(1 , TimeUnit.Years) || - (curr == new JPYCurrency()) || - (curr == new AUDCurrency() && swapTenor_ >= new Period(4 , TimeUnit.Years)))) - fixedTenor = new Period(6, TimeUnit.Months); - else if ((curr == new HKDCurrency() || - (curr == new AUDCurrency() && swapTenor_ < new Period(4 , TimeUnit.Years)))) - fixedTenor = new Period(3, TimeUnit.Months); - else - Utils.QL_FAIL("unknown fixed leg default tenor for " + curr); - } - - Schedule fixedSchedule = new Schedule(startDate, endDate, - fixedTenor, fixedCalendar_, - fixedConvention_, fixedTerminationDateConvention_, - fixedRule_, fixedEndOfMonth_, - fixedFirstDate_, fixedNextToLastDate_); - - Schedule floatSchedule = new Schedule(startDate, endDate, - floatTenor_, floatCalendar_, - floatConvention_, floatTerminationDateConvention_, - floatRule_, floatEndOfMonth_, - floatFirstDate_, floatNextToLastDate_); - - DayCounter fixedDayCount = null; - if (fixedDayCount_ != null) - fixedDayCount = fixedDayCount_; - else - { - if (curr == new USDCurrency()) - fixedDayCount = new Actual360(); - else if (curr == new EURCurrency() || curr == new CHFCurrency() || curr == new SEKCurrency()) - fixedDayCount = new Thirty360(Thirty360.Thirty360Convention.BondBasis); - else if (curr == new GBPCurrency() || curr == new JPYCurrency() || curr == new AUDCurrency() || - curr == new HKDCurrency()) - fixedDayCount = new Actual365Fixed(); - else - Utils.QL_FAIL("unknown fixed leg day counter for " + curr); - } + private VanillaSwap.Type type_; + private double nominal_; + private Period fixedTenor_, floatTenor_; + private BusinessDayConvention fixedConvention_, fixedTerminationDateConvention_; + private BusinessDayConvention floatConvention_, floatTerminationDateConvention_; + private DateGeneration.Rule fixedRule_, floatRule_; + private bool fixedEndOfMonth_, floatEndOfMonth_; + private Date fixedFirstDate_, fixedNextToLastDate_; + private Date floatFirstDate_, floatNextToLastDate_; + private double floatSpread_; + private DayCounter fixedDayCount_, floatDayCount_; - double? usedFixedRate = fixedRate_; - if (fixedRate_ == null) - { - VanillaSwap temp = new VanillaSwap(type_, nominal_, fixedSchedule, 0.0, fixedDayCount, - floatSchedule, iborIndex_, floatSpread_, floatDayCount_); - - if (engine_ == null) - { - Handle disc = iborIndex_.forwardingTermStructure(); - Utils.QL_REQUIRE(!disc.empty(),()=> - "null term structure set to this instance of " + iborIndex_.name()); - bool includeSettlementDateFlows = false; - IPricingEngine engine = new DiscountingSwapEngine(disc, includeSettlementDateFlows); - temp.setPricingEngine(engine); - } - else - temp.setPricingEngine(engine_); - - usedFixedRate = temp.fairRate(); - } + IPricingEngine engine_; + + public MakeVanillaSwap(Period swapTenor, IborIndex index, double? fixedRate = null, Period forwardStart = null) + { + swapTenor_ = swapTenor; + iborIndex_ = index; + fixedRate_ = fixedRate; + forwardStart_ = forwardStart ?? new Period(0, TimeUnit.Days); + settlementDays_ = iborIndex_.fixingDays(); + fixedCalendar_ = floatCalendar_ = index.fixingCalendar(); + + type_ = VanillaSwap.Type.Payer; + nominal_ = 1.0; + floatTenor_ = index.tenor(); + fixedConvention_ = fixedTerminationDateConvention_ = BusinessDayConvention.ModifiedFollowing; + floatConvention_ = floatTerminationDateConvention_ = index.businessDayConvention(); + fixedRule_ = floatRule_ = DateGeneration.Rule.Backward; + fixedEndOfMonth_ = floatEndOfMonth_ = false; + fixedFirstDate_ = fixedNextToLastDate_ = floatFirstDate_ = floatNextToLastDate_ = null; + floatSpread_ = 0.0; + floatDayCount_ = index.dayCounter(); + } + + public MakeVanillaSwap receiveFixed(bool flag = true) + { + type_ = flag ? VanillaSwap.Type.Receiver : VanillaSwap.Type.Payer; + return this; + } + public MakeVanillaSwap withType(VanillaSwap.Type type) + { + type_ = type; + return this; + } + public MakeVanillaSwap withNominal(double n) + { + nominal_ = n; + return this; + } + public MakeVanillaSwap withSettlementDays(int settlementDays) + { + settlementDays_ = settlementDays; + effectiveDate_ = null; + return this; + } + + public MakeVanillaSwap withEffectiveDate(Date effectiveDate) + { + effectiveDate_ = effectiveDate; + return this; + } + + public MakeVanillaSwap withTerminationDate(Date terminationDate) + { + terminationDate_ = terminationDate; + swapTenor_ = null; + return this; + } + + public MakeVanillaSwap withRule(DateGeneration.Rule r) + { + fixedRule_ = r; + floatRule_ = r; + return this; + } + + public MakeVanillaSwap withDiscountingTermStructure(Handle discountingTermStructure) + { + engine_ = new DiscountingSwapEngine(discountingTermStructure, false); + return this; + } + + public MakeVanillaSwap withPricingEngine(IPricingEngine engine) + { + engine_ = engine; + return this; + } + public MakeVanillaSwap withFixedLegTenor(Period t) + { + fixedTenor_ = t; + return this; + } + public MakeVanillaSwap withFixedLegCalendar(Calendar cal) + { + fixedCalendar_ = cal; + return this; + } + public MakeVanillaSwap withFixedLegConvention(BusinessDayConvention bdc) + { + fixedConvention_ = bdc; + return this; + } + public MakeVanillaSwap withFixedLegTerminationDateConvention(BusinessDayConvention bdc) + { + fixedTerminationDateConvention_ = bdc; + return this; + } + public MakeVanillaSwap withFixedLegRule(DateGeneration.Rule r) + { + fixedRule_ = r; + return this; + } + + public MakeVanillaSwap withFixedLegEndOfMonth(bool flag = true) + { + fixedEndOfMonth_ = flag; + return this; + } + public MakeVanillaSwap withFixedLegFirstDate(Date d) + { + fixedFirstDate_ = d; + return this; + } + public MakeVanillaSwap withFixedLegNextToLastDate(Date d) + { + fixedNextToLastDate_ = d; + return this; + } + public MakeVanillaSwap withFixedLegDayCount(DayCounter dc) + { + fixedDayCount_ = dc; + return this; + } - VanillaSwap swap = new VanillaSwap(type_, nominal_, fixedSchedule, usedFixedRate.Value, fixedDayCount, + public MakeVanillaSwap withFloatingLegTenor(Period t) + { + floatTenor_ = t; + return this; + } + public MakeVanillaSwap withFloatingLegCalendar(Calendar cal) + { + floatCalendar_ = cal; + return this; + } + public MakeVanillaSwap withFloatingLegConvention(BusinessDayConvention bdc) + { + floatConvention_ = bdc; + return this; + } + public MakeVanillaSwap withFloatingLegTerminationDateConvention(BusinessDayConvention bdc) + { + floatTerminationDateConvention_ = bdc; + return this; + } + public MakeVanillaSwap withFloatingLegRule(DateGeneration.Rule r) + { + floatRule_ = r; + return this; + } + + public MakeVanillaSwap withFloatingLegEndOfMonth(bool flag = true) + { + floatEndOfMonth_ = flag; + return this; + } + public MakeVanillaSwap withFloatingLegFirstDate(Date d) + { + floatFirstDate_ = d; + return this; + } + public MakeVanillaSwap withFloatingLegNextToLastDate(Date d) + { + floatNextToLastDate_ = d; + return this; + } + public MakeVanillaSwap withFloatingLegDayCount(DayCounter dc) + { + floatDayCount_ = dc; + return this; + } + public MakeVanillaSwap withFloatingLegSpread(double sp) + { + floatSpread_ = sp; + return this; + } + + + // swap creator + public static implicit operator VanillaSwap(MakeVanillaSwap o) { return o.value(); } + public VanillaSwap value() + { + Date startDate; + + if (effectiveDate_ != null) + startDate = effectiveDate_; + else + { + Date refDate = Settings.evaluationDate(); + // if the evaluation date is not a business day + // then move to the next business day + refDate = floatCalendar_.adjust(refDate); + Date spotDate = floatCalendar_.advance(refDate, new Period(settlementDays_, TimeUnit.Days)); + startDate = spotDate + forwardStart_; + if (forwardStart_.length() < 0) + startDate = floatCalendar_.adjust(startDate, BusinessDayConvention.Preceding); + else + startDate = floatCalendar_.adjust(startDate, BusinessDayConvention.Following); + } + + Date endDate = terminationDate_; + if (endDate == null) + if (floatEndOfMonth_) + endDate = floatCalendar_.advance(startDate, + swapTenor_, + BusinessDayConvention.ModifiedFollowing, + floatEndOfMonth_); + else + endDate = startDate + swapTenor_; + + Currency curr = iborIndex_.currency(); + Period fixedTenor = null ; + if (fixedTenor_ != null) + fixedTenor = fixedTenor_; + else + { + if ((curr == new EURCurrency()) || + (curr == new USDCurrency()) || + (curr == new CHFCurrency()) || + (curr == new SEKCurrency()) || + (curr == new GBPCurrency() && swapTenor_ <= new Period(1, TimeUnit.Years))) + fixedTenor = new Period(1, TimeUnit.Years); + else if ((curr == new GBPCurrency() && swapTenor_ > new Period(1, TimeUnit.Years) || + (curr == new JPYCurrency()) || + (curr == new AUDCurrency() && swapTenor_ >= new Period(4, TimeUnit.Years)))) + fixedTenor = new Period(6, TimeUnit.Months); + else if ((curr == new HKDCurrency() || + (curr == new AUDCurrency() && swapTenor_ < new Period(4, TimeUnit.Years)))) + fixedTenor = new Period(3, TimeUnit.Months); + else + Utils.QL_FAIL("unknown fixed leg default tenor for " + curr); + } + + Schedule fixedSchedule = new Schedule(startDate, endDate, + fixedTenor, fixedCalendar_, + fixedConvention_, fixedTerminationDateConvention_, + fixedRule_, fixedEndOfMonth_, + fixedFirstDate_, fixedNextToLastDate_); + + Schedule floatSchedule = new Schedule(startDate, endDate, + floatTenor_, floatCalendar_, + floatConvention_, floatTerminationDateConvention_, + floatRule_, floatEndOfMonth_, + floatFirstDate_, floatNextToLastDate_); + + DayCounter fixedDayCount = null; + if (fixedDayCount_ != null) + fixedDayCount = fixedDayCount_; + else + { + if (curr == new USDCurrency()) + fixedDayCount = new Actual360(); + else if (curr == new EURCurrency() || curr == new CHFCurrency() || curr == new SEKCurrency()) + fixedDayCount = new Thirty360(Thirty360.Thirty360Convention.BondBasis); + else if (curr == new GBPCurrency() || curr == new JPYCurrency() || curr == new AUDCurrency() || + curr == new HKDCurrency()) + fixedDayCount = new Actual365Fixed(); + else + Utils.QL_FAIL("unknown fixed leg day counter for " + curr); + } + + double? usedFixedRate = fixedRate_; + if (fixedRate_ == null) + { + VanillaSwap temp = new VanillaSwap(type_, nominal_, fixedSchedule, 0.0, fixedDayCount, floatSchedule, iborIndex_, floatSpread_, floatDayCount_); - if (engine_ == null) - { + if (engine_ == null) + { Handle disc = iborIndex_.forwardingTermStructure(); + Utils.QL_REQUIRE(!disc.empty(), () => + "null term structure set to this instance of " + iborIndex_.name()); bool includeSettlementDateFlows = false; IPricingEngine engine = new DiscountingSwapEngine(disc, includeSettlementDateFlows); - swap.setPricingEngine(engine); - } - else - swap.setPricingEngine(engine_); - - return swap; - } - } + temp.setPricingEngine(engine); + } + else + temp.setPricingEngine(engine_); + + usedFixedRate = temp.fairRate(); + } + + VanillaSwap swap = new VanillaSwap(type_, nominal_, fixedSchedule, usedFixedRate.Value, fixedDayCount, + floatSchedule, iborIndex_, floatSpread_, floatDayCount_); + + if (engine_ == null) + { + Handle disc = iborIndex_.forwardingTermStructure(); + bool includeSettlementDateFlows = false; + IPricingEngine engine = new DiscountingSwapEngine(disc, includeSettlementDateFlows); + swap.setPricingEngine(engine); + } + else + swap.setPricingEngine(engine_); + + return swap; + } + } } diff --git a/src/QLNet/Instruments/MultiAssetOption.cs b/src/QLNet/Instruments/MultiAssetOption.cs index c88804c32..29c4f4cf3 100644 --- a/src/QLNet/Instruments/MultiAssetOption.cs +++ b/src/QLNet/Instruments/MultiAssetOption.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,7 +23,7 @@ namespace QLNet public class MultiAssetOption : Option { public class Engine : GenericEngine - {}; + {} public new class Results : Instrument.Results { diff --git a/src/QLNet/Instruments/OneAssetOption.cs b/src/QLNet/Instruments/OneAssetOption.cs index f2b910a7a..0d40e9f4c 100644 --- a/src/QLNet/Instruments/OneAssetOption.cs +++ b/src/QLNet/Instruments/OneAssetOption.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,16 +24,16 @@ public class OneAssetOption : Option { // results protected double? delta_, - deltaForward_, - elasticity_, - gamma_, - theta_, - thetaPerDay_, - vega_, - rho_, - dividendRho_, - strikeSensitivity_, - itmCashProbability_; + deltaForward_, + elasticity_, + gamma_, + theta_, + thetaPerDay_, + vega_, + rho_, + dividendRho_, + strikeSensitivity_, + itmCashProbability_; public OneAssetOption(Payoff payoff, Exercise exercise) : base(payoff, exercise) {} @@ -124,7 +124,7 @@ protected override void setupExpired() { base.setupExpired(); delta_ = deltaForward_ = elasticity_ = gamma_ = theta_ = thetaPerDay_ = vega_ = rho_ = dividendRho_ = - strikeSensitivity_ = itmCashProbability_ = 0.0; + strikeSensitivity_ = itmCashProbability_ = 0.0; } public override void fetchResults(IPricingEngineResults r) diff --git a/src/QLNet/Instruments/OvernightIndexedSwap.cs b/src/QLNet/Instruments/OvernightIndexedSwap.cs index 051b56d1d..f43fee3ef 100644 --- a/src/QLNet/Instruments/OvernightIndexedSwap.cs +++ b/src/QLNet/Instruments/OvernightIndexedSwap.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) * 2017 Jean-Camille Tournier (tournier.jc@openmailbox.org) - * + * This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,7 +23,7 @@ under the terms of the QLNet license. You should have received a namespace QLNet { //! Overnight indexed swap: fix vs compounded overnight rate - public class OvernightIndexedSwap : Swap + public class OvernightIndexedSwap : Swap { private Type type_; private double fixedNominal_; @@ -35,19 +35,19 @@ public class OvernightIndexedSwap : Swap private OvernightIndex overnightIndex_; private double spread_; - public enum Type { Receiver = -1, Payer = 1 }; - + public enum Type { Receiver = -1, Payer = 1 } + public OvernightIndexedSwap(Type type, double nominal, Schedule schedule, double fixedRate, DayCounter fixedDC, OvernightIndex overnightIndex, - double spread) : - base(2) + double spread) : + base(2) { - - type_= type; + + type_ = type; fixedNominal_ = nominal; overnightNominal_ = nominal; fixedPaymentFrequency_ = schedule.tenor().frequency(); @@ -57,16 +57,16 @@ public OvernightIndexedSwap(Type type, overnightIndex_ = overnightIndex; spread_ = spread; - if (fixedDC_== null) + if (fixedDC_ == null) fixedDC_ = overnightIndex_.dayCounter(); legs_[0] = new FixedRateLeg(schedule) - .withCouponRates(fixedRate_, fixedDC_) - .withNotionals(nominal); + .withCouponRates(fixedRate_, fixedDC_) + .withNotionals(nominal); - legs_[1] = new OvernightLeg(schedule, overnightIndex_) - .withNotionals(nominal) - .withSpreads(spread_); + legs_[1] = new OvernightLeg(schedule, overnightIndex_) + .withNotionals(nominal) + .withSpreads(spread_); for (int j = 0; j < 2; ++j) { @@ -74,7 +74,7 @@ public OvernightIndexedSwap(Type type, legs_[j][i].registerWith(update); } - switch (type_) + switch (type_) { case Type.Payer: payer_[0] = -1.0; @@ -91,59 +91,59 @@ public OvernightIndexedSwap(Type type, } public OvernightIndexedSwap(Type type, - double fixedNominal, - Schedule fixedSchedule, - double fixedRate, - DayCounter fixedDC, - double overnightNominal, - Schedule overnightSchedule, - OvernightIndex overnightIndex, - double spread) : - base(2) + double fixedNominal, + Schedule fixedSchedule, + double fixedRate, + DayCounter fixedDC, + double overnightNominal, + Schedule overnightSchedule, + OvernightIndex overnightIndex, + double spread) : + base(2) { - type_ = type; - fixedNominal_ = fixedNominal; - overnightNominal_ = overnightNominal; - fixedPaymentFrequency_ = fixedSchedule.tenor().frequency(); - overnightPaymentFrequency_ = overnightSchedule.tenor().frequency(); - fixedRate_ = fixedRate; - fixedDC_ = fixedDC; - overnightIndex_ = overnightIndex; - spread_ = spread; - - if (fixedDC_ == null) - fixedDC_ = overnightIndex_.dayCounter(); - - legs_[0] = new FixedRateLeg(fixedSchedule) - .withCouponRates(fixedRate_, fixedDC_) - .withNotionals(fixedNominal_); - - legs_[1] = new OvernightLeg(overnightSchedule, overnightIndex_) - .withNotionals(overnightNominal_) - .withSpreads(spread_); - - for (int j = 0; j < 2; ++j) - { - for (int i = 0; i < legs_[j].Count; i++) - legs_[j][i].registerWith(update); - } - - switch (type_) - { - case Type.Payer: - payer_[0] = -1.0; - payer_[1] = +1.0; - break; - case Type.Receiver: - payer_[0] = +1.0; - payer_[1] = -1.0; - break; - default: - Utils.QL_FAIL("Unknown overnight-swap type"); - break; - - } + type_ = type; + fixedNominal_ = fixedNominal; + overnightNominal_ = overnightNominal; + fixedPaymentFrequency_ = fixedSchedule.tenor().frequency(); + overnightPaymentFrequency_ = overnightSchedule.tenor().frequency(); + fixedRate_ = fixedRate; + fixedDC_ = fixedDC; + overnightIndex_ = overnightIndex; + spread_ = spread; + + if (fixedDC_ == null) + fixedDC_ = overnightIndex_.dayCounter(); + + legs_[0] = new FixedRateLeg(fixedSchedule) + .withCouponRates(fixedRate_, fixedDC_) + .withNotionals(fixedNominal_); + + legs_[1] = new OvernightLeg(overnightSchedule, overnightIndex_) + .withNotionals(overnightNominal_) + .withSpreads(spread_); + + for (int j = 0; j < 2; ++j) + { + for (int i = 0; i < legs_[j].Count; i++) + legs_[j][i].registerWith(update); + } + + switch (type_) + { + case Type.Payer: + payer_[0] = -1.0; + payer_[1] = +1.0; + break; + case Type.Receiver: + payer_[0] = +1.0; + payer_[1] = -1.0; + break; + default: + Utils.QL_FAIL("Unknown overnight-swap type"); + break; + + } } public Type type() { return type_; } @@ -159,45 +159,45 @@ public OvernightIndexedSwap(Type type, public List overnightLeg() { return legs_[1]; } - public double? fairRate() + public double? fairRate() { const double basisPoint = 1.0e-4; calculate(); - return fixedRate_ - NPV_/(fixedLegBPS()/basisPoint); + return fixedRate_ - NPV_ / (fixedLegBPS() / basisPoint); } public double? fairSpread() { - const double basisPoint = 1.0e-4; - calculate(); - return spread_ - NPV_/(overnightLegBPS()/basisPoint); + const double basisPoint = 1.0e-4; + calculate(); + return spread_ - NPV_ / (overnightLegBPS() / basisPoint); } - public double? fixedLegBPS() + public double? fixedLegBPS() { calculate(); - Utils.QL_REQUIRE(legBPS_[0] != null,()=> "result not available"); + Utils.QL_REQUIRE(legBPS_[0] != null, () => "result not available"); return legBPS_[0]; } public double? overnightLegBPS() { - calculate(); - Utils.QL_REQUIRE(legBPS_[1] != null,()=> "result not available"); - return legBPS_[1]; + calculate(); + Utils.QL_REQUIRE(legBPS_[1] != null, () => "result not available"); + return legBPS_[1]; } - public double? fixedLegNPV() + public double? fixedLegNPV() { calculate(); - Utils.QL_REQUIRE(legNPV_[0] != null,()=> "result not available"); + Utils.QL_REQUIRE(legNPV_[0] != null, () => "result not available"); return legNPV_[0]; } public double? overnightLegNPV() { calculate(); - Utils.QL_REQUIRE(legNPV_[1] != null,()=> "result not available"); + Utils.QL_REQUIRE(legNPV_[1] != null, () => "result not available"); return legNPV_[1]; } } diff --git a/src/QLNet/Instruments/Payoffs.cs b/src/QLNet/Instruments/Payoffs.cs new file mode 100644 index 000000000..fe25b5ac5 --- /dev/null +++ b/src/QLNet/Instruments/Payoffs.cs @@ -0,0 +1,273 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! Intermediate class for put/call payoffs + public class TypePayoff : Payoff + { + protected Option.Type type_; + public Option.Type optionType() { return type_; } + + public TypePayoff(Option.Type type) + { + type_ = type; + } + + // Payoff interface + public override string description() { return name() + " " + optionType(); } + } + + //! %Payoff based on a floating strike + public class FloatingTypePayoff : TypePayoff + { + public FloatingTypePayoff(Option.Type type) : base(type) {} + + // Payoff interface + public override string name() { return "FloatingType";} + + public override double value(double k) { throw new NotSupportedException("floating payoff not handled"); } + } + + //! Intermediate class for payoffs based on a fixed strike + public class StrikedTypePayoff : TypePayoff + { + protected double strike_; + + public StrikedTypePayoff(Option.Type type, double strike) : base(type) + { + strike_ = strike; + } + + public StrikedTypePayoff(Payoff p) + : base((p as StrikedTypePayoff).type_) + { + strike_ = (p as StrikedTypePayoff).strike_; + } + + // Payoff interface + public override string description() + { + return base.description() + ", " + strike() + " strike"; + } + + public double strike() { return strike_; } + } + + //! Plain-vanilla payoff + public class PlainVanillaPayoff : StrikedTypePayoff + { + public PlainVanillaPayoff(Option.Type type, double strike) : base(type, strike) {} + + // Payoff interface + public override string name() { return "Vanilla";} + public override double value(double price) + { + switch (type_) + { + case Option.Type.Call: + return Math.Max(price - strike_, 0.0); + case Option.Type.Put: + return Math.Max(strike_ - price, 0.0); + default: + throw new ArgumentException("unknown/illegal option type"); + } + } + } + + //! %Payoff with strike expressed as percentage + public class PercentageStrikePayoff : StrikedTypePayoff + { + public PercentageStrikePayoff(Option.Type type, double moneyness) : base(type, moneyness) {} + + // Payoff interface + public override string name() { return "PercentageStrike";} + public override double value(double price) + { + switch (type_) + { + case Option.Type.Call: + return price * Math.Max(1.0 - strike_, 0.0); + case Option.Type.Put: + return price * Math.Max(strike_ - 1.0, 0.0); + default: + throw new ArgumentException("unknown/illegal option type"); + } + } + } + + /*! Definitions of Binary path-independent payoffs used below, + can be found in M. Rubinstein, E. Reiner:"Unscrambling The Binary Code", Risk, Vol.4 no.9,1991. + (see: http://www.in-the-money.com/artandpap/Binary%20Options.doc) + */ + //! Binary asset-or-nothing payoff + public class AssetOrNothingPayoff : StrikedTypePayoff + { + public AssetOrNothingPayoff(Option.Type type, double strike) : base(type, strike) {} + + // Payoff interface + public override string name() { return "AssetOrNothing";} + public override double value(double price) + { + switch (type_) + { + case Option.Type.Call: + return (price - strike_ > 0.0 ? price : 0.0); + case Option.Type.Put: + return (strike_ - price > 0.0 ? price : 0.0); + default: + throw new ArgumentException("unknown/illegal option type"); + } + } + } + + //! Binary cash-or-nothing payoff + public class CashOrNothingPayoff : StrikedTypePayoff + { + protected double cashPayoff_; + public double cashPayoff() { return cashPayoff_;} + + public CashOrNothingPayoff(Option.Type type, double strike, double cashPayoff) : base(type, strike) + { + cashPayoff_ = cashPayoff; + } + // Payoff interface + public override string name() { return "CashOrNothing";} + public override string description() + { + return base.description() + ", " + cashPayoff() + " cash payoff"; + } + public override double value(double price) + { + switch (type_) + { + case Option.Type.Call: + return (price - strike_ > 0.0 ? cashPayoff_ : 0.0); + case Option.Type.Put: + return (strike_ - price > 0.0 ? cashPayoff_ : 0.0); + default: + throw new ArgumentException("unknown/illegal option type"); + } + } + } + + //! Binary gap payoff + /*! This payoff is equivalent to being a) long a PlainVanillaPayoff at + the first strike (same Call/Put type) and b) short a + CashOrNothingPayoff at the first strike (same Call/Put type) with + cash payoff equal to the difference between the second and the first + strike. + \warning this payoff can be negative depending on the strikes + */ + public class GapPayoff : StrikedTypePayoff + { + protected double secondStrike_; + public double secondStrike() { return secondStrike_;} + + public GapPayoff(Option.Type type, double strike, double secondStrike) // a.k.a. payoff strike + : base(type, strike) + { + secondStrike_ = secondStrike; + } + + // Payoff interface + public override string name() { return "Gap";} + public override string description() + { + return base.description() + ", " + secondStrike() + " strike payoff"; + } + public override double value(double price) + { + switch (type_) + { + case Option.Type.Call: + return (price - strike_ >= 0.0 ? price - secondStrike_ : 0.0); + case Option.Type.Put: + return (strike_ - price >= 0.0 ? secondStrike_ - price : 0.0); + default: + throw new ArgumentException("unknown/illegal option type"); + } + } + } + + //! Binary supershare and superfund payoffs + + //! Binary superfund payoff + /*! Superfund sometimes also called "supershare", which can lead to ambiguity; within QuantLib + the terms supershare and superfund are used consistently according to the definitions in + Bloomberg OVX function's help pages. + */ + /*! This payoff is equivalent to being (1/lowerstrike) a) long (short) an AssetOrNothing + Call (Put) at the lower strike and b) short (long) an AssetOrNothing + Call (Put) at the higher strike + */ + public class SuperFundPayoff : StrikedTypePayoff + { + protected double secondStrike_; + public double secondStrike() { return secondStrike_;} + + public SuperFundPayoff(double strike, double secondStrike) : base(Option.Type.Call, strike) + { + secondStrike_ = secondStrike; + + Utils.QL_REQUIRE(strike > 0.0, () => "strike (" + strike + ") must be positive"); + Utils.QL_REQUIRE(secondStrike > strike, () => "second strike (" + secondStrike + + ") must be higher than first strike (" + strike + ")"); + } + + // Payoff interface + public override string name() { return "SuperFund";} + public override double value(double price) + { + return (price >= strike_ && price < secondStrike_) ? price / strike_ : 0.0; + } + } + + //! Binary supershare payoff + public class SuperSharePayoff : StrikedTypePayoff + { + protected double secondStrike_; + public double secondStrike() { return secondStrike_; } + + protected double cashPayoff_; + public double cashPayoff() { return cashPayoff_; } + + public SuperSharePayoff(double strike, double secondStrike, double cashPayoff) + : base(Option.Type.Call, strike) + { + secondStrike_ = secondStrike; + cashPayoff_ = cashPayoff; + + Utils.QL_REQUIRE(secondStrike > strike, () => "second strike (" + secondStrike + + ") must be higher than first strike (" + strike + ")"); + } + + // Payoff interface + public override string name() { return "SuperShare";} + public override string description() + { + return base.description() + ", " + secondStrike() + " second strike" + ", " + cashPayoff() + " amount"; + } + public override double value(double price) + { + return (price >= strike_ && price < secondStrike_) ? cashPayoff_ : 0.0; + } + } +} diff --git a/src/QLNet/Instruments/SpreadOption.cs b/src/QLNet/Instruments/SpreadOption.cs new file mode 100644 index 000000000..6c578cddc --- /dev/null +++ b/src/QLNet/Instruments/SpreadOption.cs @@ -0,0 +1,35 @@ +// Copyright (C) 2008-2018 Andrea Maggiulli (a.maggiulli@gmail.com) +// +// This file is part of QLNet Project https://github.com/amaggiulli/qlnet +// QLNet is free software: you can redistribute it and/or modify it +// under the terms of the QLNet license. You should have received a +// copy of the license along with this program; if not, license is +// available at . +// +// QLNet is a based on QuantLib, a free-software/open-source library +// for financial quantitative analysts and developers - http://quantlib.org/ +// The QuantLib license is available online at http://quantlib.org/license.shtml. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the license for more details. + +namespace QLNet +{ + /// + /// Spread option on two assets + /// + public class SpreadOption : MultiAssetOption + { + public SpreadOption(PlainVanillaPayoff payoff, Exercise exercise) + : base(payoff, exercise) + {} + + /// + /// Spread option engine base class + /// + public new class Engine : + GenericEngine + {} + } +} diff --git a/src/QLNet/Instruments/Stock.cs b/src/QLNet/Instruments/Stock.cs index eff805855..b1762d45a 100644 --- a/src/QLNet/Instruments/Stock.cs +++ b/src/QLNet/Instruments/Stock.cs @@ -1,38 +1,42 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - //! Simple stock class - public class Stock : Instrument { - private Handle quote_; +namespace QLNet +{ + //! Simple stock class + public class Stock : Instrument + { + private Handle quote_; - public Stock(Handle quote) { - quote_ = quote; - quote_.registerWith(update); - } + public Stock(Handle quote) + { + quote_ = quote; + quote_.registerWith(update); + } - public override bool isExpired() { return false; } + public override bool isExpired() { return false; } - protected override void performCalculations() { - Utils.QL_REQUIRE(!quote_.empty(),()=> "null quote set"); - NPV_ = quote_.link.value(); - } - } + protected override void performCalculations() + { + Utils.QL_REQUIRE(!quote_.empty(), () => "null quote set"); + NPV_ = quote_.link.value(); + } + } } diff --git a/src/QLNet/Instruments/Swap.cs b/src/QLNet/Instruments/Swap.cs index 722752d7e..b3952642c 100644 --- a/src/QLNet/Instruments/Swap.cs +++ b/src/QLNet/Instruments/Swap.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -31,10 +31,10 @@ public class Swap : Instrument protected List> legs_; protected List payer_; - protected List legNPV_; - protected List legBPS_; - protected List startDiscounts_; - protected List endDiscounts_; + protected List < double? > legNPV_; + protected List < double? > legBPS_; + protected List < double? > startDiscounts_; + protected List < double? > endDiscounts_; protected double? npvDateDiscount_; public Arguments arguments { get; set; } @@ -55,11 +55,11 @@ public Swap(List firstLeg, List secondLeg) payer_ = new InitializedList(2); payer_[0] = -1.0; payer_[1] = 1.0; - legNPV_ = new InitializedList(2); - legBPS_ = new InitializedList(2); + legNPV_ = new InitializedList < double? >(2); + legBPS_ = new InitializedList < double? >(2); - startDiscounts_ = new InitializedList(2); - endDiscounts_ = new InitializedList(2); + startDiscounts_ = new InitializedList < double? >(2); + endDiscounts_ = new InitializedList < double? >(2); npvDateDiscount_ = 0.0; for (int i = 0; i < legs_.Count; i++) @@ -71,18 +71,19 @@ public Swap(List firstLeg, List secondLeg) public Swap(List> legs, List payer) { legs_ = (InitializedList>)legs; - payer_ = new InitializedList(legs.Count,1.0); - legNPV_ = new InitializedList(legs.Count,0.0); - legBPS_ = new InitializedList(legs.Count,0.0); - startDiscounts_ = new InitializedList(legs.Count, 0.0); - endDiscounts_ = new InitializedList(legs.Count, 0.0); + payer_ = new InitializedList(legs.Count, 1.0); + legNPV_ = new InitializedList < double? >(legs.Count, 0.0); + legBPS_ = new InitializedList < double? >(legs.Count, 0.0); + startDiscounts_ = new InitializedList < double? >(legs.Count, 0.0); + endDiscounts_ = new InitializedList < double? >(legs.Count, 0.0); npvDateDiscount_ = 0.0; - Utils.QL_REQUIRE( payer.Count == legs_.Count, () => "size mismatch between payer (" + payer.Count + - ") and legs (" + legs_.Count + ")"); + Utils.QL_REQUIRE(payer.Count == legs_.Count, () => "size mismatch between payer (" + payer.Count + + ") and legs (" + legs_.Count + ")"); for (int i = 0; i < legs_.Count; ++i) { - if (payer[i]) payer_[i] = -1; + if (payer[i]) + payer_[i] = -1; for (int j = 0; j < legs_[i].Count; j++) legs_[i][j].registerWith(update); } @@ -95,10 +96,10 @@ protected Swap(int legs) { legs_ = new InitializedList>(legs); payer_ = new InitializedList(legs); - legNPV_ = new InitializedList(legs,0.0); - legBPS_ = new InitializedList(legs,0.0); - startDiscounts_ = new InitializedList(legs, 0.0); - endDiscounts_ = new InitializedList(legs, 0.0); + legNPV_ = new InitializedList < double? >(legs, 0.0); + legBPS_ = new InitializedList < double? >(legs, 0.0); + startDiscounts_ = new InitializedList < double? >(legs, 0.0); + endDiscounts_ = new InitializedList < double? >(legs, 0.0); npvDateDiscount_ = 0.0; } #endregion @@ -114,17 +115,17 @@ public override bool isExpired() protected override void setupExpired() { base.setupExpired(); - legBPS_ = new InitializedList(legBPS_.Count); - legNPV_ = new InitializedList(legNPV_.Count); - startDiscounts_ = new InitializedList(startDiscounts_.Count); - endDiscounts_ = new InitializedList(endDiscounts_.Count); + legBPS_ = new InitializedList < double? >(legBPS_.Count); + legNPV_ = new InitializedList < double? >(legNPV_.Count); + startDiscounts_ = new InitializedList < double? >(startDiscounts_.Count); + endDiscounts_ = new InitializedList < double? >(endDiscounts_.Count); npvDateDiscount_ = 0.0; } public override void setupArguments(IPricingEngineArguments args) { Swap.Arguments arguments = args as Swap.Arguments; - Utils.QL_REQUIRE( arguments != null, () => "wrong argument type" ); + Utils.QL_REQUIRE(arguments != null, () => "wrong argument type"); arguments.legs = legs_; arguments.payer = payer_; @@ -135,118 +136,118 @@ public override void fetchResults(IPricingEngineResults r) base.fetchResults(r); Swap.Results results = r as Swap.Results; - Utils.QL_REQUIRE( results != null, () => "wrong result type" ); + Utils.QL_REQUIRE(results != null, () => "wrong result type"); if (!results.legNPV.empty()) { - Utils.QL_REQUIRE( results.legNPV.Count == legNPV_.Count, () => "wrong number of leg NPV returned" ); - legNPV_ = new List( results.legNPV); + Utils.QL_REQUIRE(results.legNPV.Count == legNPV_.Count, () => "wrong number of leg NPV returned"); + legNPV_ = new List < double? >(results.legNPV); } else { - legNPV_ = new InitializedList(legNPV_.Count); + legNPV_ = new InitializedList < double? >(legNPV_.Count); } if (!results.legBPS.empty()) { - Utils.QL_REQUIRE( results.legBPS.Count == legBPS_.Count, () => "wrong number of leg BPS returned" ); - legBPS_ = new List(results.legBPS); + Utils.QL_REQUIRE(results.legBPS.Count == legBPS_.Count, () => "wrong number of leg BPS returned"); + legBPS_ = new List < double? >(results.legBPS); } else { - legBPS_ = new InitializedList(legBPS_.Count); + legBPS_ = new InitializedList < double? >(legBPS_.Count); } - if (!results.startDiscounts.empty()) + if (!results.startDiscounts.empty()) { - Utils.QL_REQUIRE( results.startDiscounts.Count == startDiscounts_.Count, () => "wrong number of leg start discounts returned" ); - startDiscounts_ = new List(results.startDiscounts); - } - else + Utils.QL_REQUIRE(results.startDiscounts.Count == startDiscounts_.Count, () => "wrong number of leg start discounts returned"); + startDiscounts_ = new List < double? >(results.startDiscounts); + } + else { - startDiscounts_ = new InitializedList(startDiscounts_.Count); - } + startDiscounts_ = new InitializedList < double? >(startDiscounts_.Count); + } - if (!results.endDiscounts.empty()) + if (!results.endDiscounts.empty()) { - Utils.QL_REQUIRE( results.endDiscounts.Count == endDiscounts_.Count, () => "wrong number of leg end discounts returned" ); - endDiscounts_ = new List(results.endDiscounts); - } - else + Utils.QL_REQUIRE(results.endDiscounts.Count == endDiscounts_.Count, () => "wrong number of leg end discounts returned"); + endDiscounts_ = new List < double? >(results.endDiscounts); + } + else { - endDiscounts_ = new InitializedList(endDiscounts_.Count); + endDiscounts_ = new InitializedList < double? >(endDiscounts_.Count); } - if (results.npvDateDiscount != null) + if (results.npvDateDiscount != null) { npvDateDiscount_ = results.npvDateDiscount; - } - else + } + else { npvDateDiscount_ = null; } } - + #endregion #region Additional interface public Date startDate() { - Utils.QL_REQUIRE( !legs_.empty(), () => "no legs given" ); + Utils.QL_REQUIRE(!legs_.empty(), () => "no legs given"); return legs_.Min(leg => CashFlows.startDate(leg)); } public Date maturityDate() { - Utils.QL_REQUIRE( !legs_.empty(), () => "no legs given" ); + Utils.QL_REQUIRE(!legs_.empty(), () => "no legs given"); return legs_.Max(leg => CashFlows.maturityDate(leg)); } public double? legBPS(int j) { - Utils.QL_REQUIRE( j < legs_.Count, () => "leg# " + j + " doesn't exist!" ); + Utils.QL_REQUIRE(j < legs_.Count, () => "leg# " + j + " doesn't exist!"); calculate(); return legBPS_[j]; } public double? legNPV(int j) { - Utils.QL_REQUIRE( j < legs_.Count, () => "leg# " + j + " doesn't exist!" ); + Utils.QL_REQUIRE(j < legs_.Count, () => "leg# " + j + " doesn't exist!"); calculate(); return legNPV_[j]; } - public double? startDiscounts(int j) + public double? startDiscounts(int j) { - Utils.QL_REQUIRE( j < legs_.Count, () => "leg #" + j + " doesn't exist!" ); + Utils.QL_REQUIRE(j < legs_.Count, () => "leg #" + j + " doesn't exist!"); calculate(); return startDiscounts_[j]; } public double? endDiscounts(int j) { - Utils.QL_REQUIRE( j < legs_.Count, () => "leg #" + j + " doesn't exist!" ); + Utils.QL_REQUIRE(j < legs_.Count, () => "leg #" + j + " doesn't exist!"); calculate(); return endDiscounts_[j]; } - public double? npvDateDiscount() + public double? npvDateDiscount() { - calculate(); - return npvDateDiscount_; + calculate(); + return npvDateDiscount_; } public List leg(int j) { - Utils.QL_REQUIRE( j < legs_.Count, () => "leg #" + j + " doesn't exist!" ); + Utils.QL_REQUIRE(j < legs_.Count, () => "leg #" + j + " doesn't exist!"); return legs_[j]; } - public double payer(int j) - { - Utils.QL_REQUIRE(j < legs_.Count, () => "leg #" + j + " doesn't exist!"); - return payer_[j]; + public double payer(int j) + { + Utils.QL_REQUIRE(j < legs_.Count, () => "leg #" + j + " doesn't exist!"); + return payer_[j]; } #endregion @@ -255,42 +256,42 @@ public double payer(int j) // arguments, results, pricing engine public class Arguments : IPricingEngineArguments { - public List> legs { get; set; } + public List> legs { get; set; } public List payer { get; set; } public virtual void validate() { - Utils.QL_REQUIRE( legs.Count == payer.Count, () => "number of legs and multipliers differ" ); + Utils.QL_REQUIRE(legs.Count == payer.Count, () => "number of legs and multipliers differ"); } } public new class Results : Instrument.Results { - public List legNPV { get; set; } - public List legBPS { get; set; } - public List startDiscounts { get; set; } - public List endDiscounts { get; set; } + public List < double? > legNPV { get; set; } + public List < double? > legBPS { get; set; } + public List < double? > startDiscounts { get; set; } + public List < double? > endDiscounts { get; set; } public double? npvDateDiscount { get; set; } public override void reset() { base.reset(); // clear all previous results - if ( legNPV == null) - legNPV = new List(); + if (legNPV == null) + legNPV = new List < double? >(); else legNPV.Clear(); - if ( legBPS == null ) - legBPS = new List(); + if (legBPS == null) + legBPS = new List < double? >(); else legBPS.Clear(); - if ( startDiscounts == null ) - startDiscounts = new List(); + if (startDiscounts == null) + startDiscounts = new List < double? >(); else startDiscounts.Clear(); - if ( endDiscounts == null ) - endDiscounts = new List(); + if (endDiscounts == null) + endDiscounts = new List < double? >(); else endDiscounts.Clear(); diff --git a/src/QLNet/Instruments/Swaption.cs b/src/QLNet/Instruments/Swaption.cs index aa761fbde..791cb6923 100644 --- a/src/QLNet/Instruments/Swaption.cs +++ b/src/QLNet/Instruments/Swaption.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -25,7 +25,7 @@ namespace QLNet //! %settlement information public struct Settlement { - public enum Type { Physical, Cash }; + public enum Type { Physical, Cash } } //! %Swaption class @@ -61,7 +61,7 @@ public class Swaption : Option private VanillaSwap swap_; private Settlement.Type settlementType_; - public Swaption(VanillaSwap swap,Exercise exercise) + public Swaption(VanillaSwap swap, Exercise exercise) : base(new Payoff(), exercise) { settlementType_ = Settlement.Type.Physical; @@ -69,7 +69,7 @@ public Swaption(VanillaSwap swap,Exercise exercise) swap_.registerWith(update); } - public Swaption(VanillaSwap swap,Exercise exercise,Settlement.Type delivery) + public Swaption(VanillaSwap swap, Exercise exercise, Settlement.Type delivery) : base(new Payoff(), exercise) { settlementType_ = delivery; @@ -177,19 +177,20 @@ public ImpliedVolHelper_(Swaption swaption, // at first ImpliedVolHelper::operator()(Volatility x) call vol_ = new SimpleQuote(-1.0); Handle h = new Handle(vol_); - switch (type) { + switch (type) + { case VolatilityType.ShiftedLognormal: - engine_ = new BlackSwaptionEngine(discountCurve_, h, new Actual365Fixed(), displacement); - break; + engine_ = new BlackSwaptionEngine(discountCurve_, h, new Actual365Fixed(), displacement); + break; case VolatilityType.Normal: - engine_ = new BachelierSwaptionEngine(discountCurve_, h, new Actual365Fixed()); - break; + engine_ = new BachelierSwaptionEngine(discountCurve_, h, new Actual365Fixed()); + break; default: - Utils.QL_FAIL("unknown VolatilityType (" + type.ToString() + ")"); - break; + Utils.QL_FAIL("unknown VolatilityType (" + type.ToString() + ")"); + break; } swaption.setupArguments(engine_.getArguments()); - results_ = engine_.getResults() as Instrument.Results; + results_ = engine_.getResults() as Instrument.Results; } public override double value(double x) @@ -209,7 +210,7 @@ public override double derivative(double x) vol_.setValue(x); engine_.calculate(); } - Utils.QL_REQUIRE(results_.additionalResults.Keys.Contains("vega"),()=> "vega not provided"); + Utils.QL_REQUIRE(results_.additionalResults.Keys.Contains("vega"), () => "vega not provided"); return (double)results_.additionalResults["vega"]; } } diff --git a/src/QLNet/Instruments/VanillaOption.cs b/src/QLNet/Instruments/VanillaOption.cs index 55e3ea018..6408362d4 100644 --- a/src/QLNet/Instruments/VanillaOption.cs +++ b/src/QLNet/Instruments/VanillaOption.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,8 +24,8 @@ namespace QLNet //! Vanilla option (no discrete dividends, no barriers) on a single asset public class VanillaOption : OneAssetOption { - public VanillaOption( StrikedTypePayoff payoff, Exercise exercise ) - : base( payoff, exercise ) {} + public VanillaOption(StrikedTypePayoff payoff, Exercise exercise) + : base(payoff, exercise) {} /*! \warning currently, this method returns the Black-Scholes implied volatility using analytic formulas for @@ -45,39 +45,39 @@ failure is to have a target value that is not value lower than the intrinsic value in the case of American options. */ - public double impliedVolatility( double targetValue, - GeneralizedBlackScholesProcess process, - double accuracy = 1.0e-4, - int maxEvaluations = 100, - double minVol = 1.0e-7, - double maxVol = 4.0) + public double impliedVolatility(double targetValue, + GeneralizedBlackScholesProcess process, + double accuracy = 1.0e-4, + int maxEvaluations = 100, + double minVol = 1.0e-7, + double maxVol = 4.0) { - Utils.QL_REQUIRE( !isExpired(),()=> "option expired" ); + Utils.QL_REQUIRE(!isExpired(), () => "option expired"); SimpleQuote volQuote = new SimpleQuote(); - GeneralizedBlackScholesProcess newProcess = ImpliedVolatilityHelper.clone( process, volQuote ); + GeneralizedBlackScholesProcess newProcess = ImpliedVolatilityHelper.clone(process, volQuote); // engines are built-in for the time being IPricingEngine engine; switch (exercise_.type()) { case Exercise.Type.European: - engine = new AnalyticEuropeanEngine( newProcess ); + engine = new AnalyticEuropeanEngine(newProcess); break; case Exercise.Type.American: - engine = new FDAmericanEngine( newProcess ); + engine = new FDAmericanEngine(newProcess); break; case Exercise.Type.Bermudan: - engine = new FDBermudanEngine( newProcess ); + engine = new FDBermudanEngine(newProcess); break; default: - throw new ArgumentException( "unknown exercise type" ); + throw new ArgumentException("unknown exercise type"); } - return ImpliedVolatilityHelper.calculate( this, engine, volQuote, targetValue, accuracy, - maxEvaluations, minVol, maxVol ); + return ImpliedVolatilityHelper.calculate(this, engine, volQuote, targetValue, accuracy, + maxEvaluations, minVol, maxVol); } } } diff --git a/src/QLNet/Instruments/VanillaSwap.cs b/src/QLNet/Instruments/VanillaSwap.cs index dcd731cb6..6bea8c1b1 100644 --- a/src/QLNet/Instruments/VanillaSwap.cs +++ b/src/QLNet/Instruments/VanillaSwap.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - * + * This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,18 +29,18 @@ settlement date of the swap might be included in the NPV and therefore affect the fair-rate and fair-spread calculation. This might not be what you want. - - \test + + \test - the correctness of the returned value is tested by checking - that the price of a swap paying the fair fixed rate is null. - that the price of a swap receiving the fair floating-rate spread is null. - that the price of a swap decreases with the paid fixed rate. - that the price of a swap increases with the received floating-rate spread. - the correctness of the returned value is tested by checking it against a known good value. -*/ + */ public class VanillaSwap : Swap { - public enum Type { Receiver = -1, Payer = 1 }; + public enum Type { Receiver = -1, Payer = 1 } private Type type_; private double fixedRate_; @@ -69,8 +69,8 @@ public enum Type { Receiver = -1, Payer = 1 }; public VanillaSwap(Type type, double nominal, Schedule fixedSchedule, double fixedRate, DayCounter fixedDayCount, Schedule floatSchedule, IborIndex iborIndex, double spread, DayCounter floatingDayCount, - BusinessDayConvention? paymentConvention = null) : - base(2) + BusinessDayConvention ? paymentConvention = null) : + base(2) { type_ = type; nominal_ = nominal; @@ -88,16 +88,16 @@ public VanillaSwap(Type type, double nominal, paymentConvention_ = floatingSchedule_.businessDayConvention(); legs_[0] = new FixedRateLeg(fixedSchedule) - .withCouponRates(fixedRate, fixedDayCount) - .withPaymentAdjustment(paymentConvention_) - .withNotionals(nominal); + .withCouponRates(fixedRate, fixedDayCount) + .withPaymentAdjustment(paymentConvention_) + .withNotionals(nominal); legs_[1] = new IborLeg(floatSchedule, iborIndex) - .withPaymentDayCounter(floatingDayCount) - //.withFixingDays(iborIndex.fixingDays()) - .withSpreads(spread) - .withNotionals(nominal) - .withPaymentAdjustment(paymentConvention_); + .withPaymentDayCounter(floatingDayCount) + //.withFixingDays(iborIndex.fixingDays()) + .withSpreads(spread) + .withNotionals(nominal) + .withPaymentAdjustment(paymentConvention_); foreach (var cf in legs_[1]) cf.registerWith(update); @@ -179,40 +179,46 @@ public override void setupArguments(IPricingEngineArguments args) public double fairRate() { calculate(); - if (fairRate_ == null) throw new ArgumentException("result not available"); + if (fairRate_ == null) + throw new ArgumentException("result not available"); return fairRate_.GetValueOrDefault(); } public double fairSpread() { calculate(); - if (fairSpread_ == null) throw new ArgumentException("result not available"); + if (fairSpread_ == null) + throw new ArgumentException("result not available"); return fairSpread_.GetValueOrDefault(); } public double fixedLegBPS() { calculate(); - if (legBPS_[0] == null) throw new ArgumentException("result not available"); + if (legBPS_[0] == null) + throw new ArgumentException("result not available"); return legBPS_[0].GetValueOrDefault(); } public double fixedLegNPV() { calculate(); - if (legNPV_[0] == null) throw new ArgumentException("result not available"); + if (legNPV_[0] == null) + throw new ArgumentException("result not available"); return legNPV_[0].GetValueOrDefault(); } public double floatingLegBPS() { calculate(); - if (legBPS_[1] == null) throw new ArgumentException("result not available"); + if (legBPS_[1] == null) + throw new ArgumentException("result not available"); return legBPS_[1].GetValueOrDefault(); } public double floatingLegNPV() { calculate(); - if (legNPV_[1] == null) throw new ArgumentException("result not available"); + if (legNPV_[1] == null) + throw new ArgumentException("result not available"); return legNPV_[1].GetValueOrDefault(); } @@ -244,7 +250,8 @@ public override void fetchResults(IPricingEngineResults r) VanillaSwap.Results results = r as VanillaSwap.Results; if (results != null) - { // might be a swap engine, so no error is thrown + { + // might be a swap engine, so no error is thrown fairRate_ = results.fairRate; fairSpread_ = results.fairSpread; } @@ -296,7 +303,8 @@ public override void validate() { base.validate(); - if (nominal.IsEqual(default(double))) throw new ArgumentException("nominal null or not set"); + if (nominal.IsEqual(default(double))) + throw new ArgumentException("nominal null or not set"); if (fixedResetDates.Count != fixedPayDates.Count) throw new ArgumentException("number of fixed start dates different from number of fixed payment dates"); if (fixedPayDates.Count != fixedCoupons.Count) diff --git a/src/QLNet/Instruments/YearOnYearInflationSwap.cs b/src/QLNet/Instruments/YearOnYearInflationSwap.cs index b0939b595..990e0c0c3 100644 --- a/src/QLNet/Instruments/YearOnYearInflationSwap.cs +++ b/src/QLNet/Instruments/YearOnYearInflationSwap.cs @@ -6,13 +6,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -37,149 +37,149 @@ namespace QLNet typical VanillaSwap type design conventions w.r.t. Schedules etc. */ - public class YearOnYearInflationSwap : Swap - { - const double basisPoint = 1.0e-4; - public enum Type { Receiver = -1, Payer = 1 }; - public YearOnYearInflationSwap( - Type type, - double nominal, - Schedule fixedSchedule, - double fixedRate, - DayCounter fixedDayCount, - Schedule yoySchedule, - YoYInflationIndex yoyIndex, - Period observationLag, - double spread, - DayCounter yoyDayCount, - Calendar paymentCalendar, // inflation index does not have a calendar - BusinessDayConvention paymentConvention = BusinessDayConvention.ModifiedFollowing ) - : base( 2 ) - { - type_ = type; - nominal_ = nominal; - fixedSchedule_ = fixedSchedule; - fixedRate_ = fixedRate; - fixedDayCount_ = fixedDayCount; - yoySchedule_ = yoySchedule; - yoyIndex_ = yoyIndex; - observationLag_ = observationLag; - spread_ = spread; - yoyDayCount_ = yoyDayCount; - paymentCalendar_ = paymentCalendar; - paymentConvention_ = paymentConvention; - - // N.B. fixed leg gets its calendar from the schedule! - List fixedLeg = new FixedRateLeg( fixedSchedule_ ) - .withCouponRates( fixedRate_, fixedDayCount_ ) // Simple compounding by default - .withNotionals( nominal_ ) - .withPaymentAdjustment( paymentConvention_ ); - - List yoyLeg = new yoyInflationLeg( yoySchedule_, paymentCalendar_, yoyIndex_, observationLag_ ) - .withSpreads( spread_ ) - .withPaymentDayCounter( yoyDayCount_ ) - .withNotionals( nominal_ ) - .withPaymentAdjustment( paymentConvention_ ); - - yoyLeg.ForEach((i, x) => x.registerWith( update ) ); - - - legs_[0] = fixedLeg; - legs_[1] = yoyLeg; - if ( type_ == Type.Payer ) - { - payer_[0] = -1.0; - payer_[1] = +1.0; - } - else - { - payer_[0] = +1.0; - payer_[1] = -1.0; - } - - } + public class YearOnYearInflationSwap : Swap + { + const double basisPoint = 1.0e-4; + public enum Type { Receiver = -1, Payer = 1 } + public YearOnYearInflationSwap( + Type type, + double nominal, + Schedule fixedSchedule, + double fixedRate, + DayCounter fixedDayCount, + Schedule yoySchedule, + YoYInflationIndex yoyIndex, + Period observationLag, + double spread, + DayCounter yoyDayCount, + Calendar paymentCalendar, // inflation index does not have a calendar + BusinessDayConvention paymentConvention = BusinessDayConvention.ModifiedFollowing) + : base(2) + { + type_ = type; + nominal_ = nominal; + fixedSchedule_ = fixedSchedule; + fixedRate_ = fixedRate; + fixedDayCount_ = fixedDayCount; + yoySchedule_ = yoySchedule; + yoyIndex_ = yoyIndex; + observationLag_ = observationLag; + spread_ = spread; + yoyDayCount_ = yoyDayCount; + paymentCalendar_ = paymentCalendar; + paymentConvention_ = paymentConvention; + + // N.B. fixed leg gets its calendar from the schedule! + List fixedLeg = new FixedRateLeg(fixedSchedule_) + .withCouponRates(fixedRate_, fixedDayCount_) // Simple compounding by default + .withNotionals(nominal_) + .withPaymentAdjustment(paymentConvention_); + + List yoyLeg = new yoyInflationLeg(yoySchedule_, paymentCalendar_, yoyIndex_, observationLag_) + .withSpreads(spread_) + .withPaymentDayCounter(yoyDayCount_) + .withNotionals(nominal_) + .withPaymentAdjustment(paymentConvention_); + + yoyLeg.ForEach((i, x) => x.registerWith(update)); + + + legs_[0] = fixedLeg; + legs_[1] = yoyLeg; + if (type_ == Type.Payer) + { + payer_[0] = -1.0; + payer_[1] = +1.0; + } + else + { + payer_[0] = +1.0; + payer_[1] = -1.0; + } + + } // results - public virtual double fixedLegNPV() - { - calculate(); - Utils.QL_REQUIRE( legNPV_[0] != null, () => "result not available" ); - return legNPV_[0].Value; - } - public virtual double fairRate() - { - calculate(); - Utils.QL_REQUIRE( fairRate_ != null, () => "result not available" ); - return fairRate_.Value; - } - - public virtual double yoyLegNPV() - { - calculate(); - Utils.QL_REQUIRE( legNPV_[1] != null, () => "result not available" ); - return legNPV_[1].Value; - } - public virtual double fairSpread() - { - calculate(); - Utils.QL_REQUIRE( fairSpread_ != null, () => "result not available" ); - return fairSpread_.Value; - } + public virtual double fixedLegNPV() + { + calculate(); + Utils.QL_REQUIRE(legNPV_[0] != null, () => "result not available"); + return legNPV_[0].Value; + } + public virtual double fairRate() + { + calculate(); + Utils.QL_REQUIRE(fairRate_ != null, () => "result not available"); + return fairRate_.Value; + } + + public virtual double yoyLegNPV() + { + calculate(); + Utils.QL_REQUIRE(legNPV_[1] != null, () => "result not available"); + return legNPV_[1].Value; + } + public virtual double fairSpread() + { + calculate(); + Utils.QL_REQUIRE(fairSpread_ != null, () => "result not available"); + return fairSpread_.Value; + } // inspectors public virtual Type type() {return type_;} public virtual double nominal() { return nominal_;} public virtual Schedule fixedSchedule() {return fixedSchedule_;} public virtual double fixedRate() {return fixedRate_;} - public virtual DayCounter fixedDayCount() { return fixedDayCount_; } + public virtual DayCounter fixedDayCount() { return fixedDayCount_; } - public virtual Schedule yoySchedule() { return yoySchedule_; } - public virtual YoYInflationIndex yoyInflationIndex() { return yoyIndex_; } + public virtual Schedule yoySchedule() { return yoySchedule_; } + public virtual YoYInflationIndex yoyInflationIndex() { return yoyIndex_; } public virtual Period observationLag() { return observationLag_; } - public virtual double spread() { return spread_; } - public virtual DayCounter yoyDayCount() { return yoyDayCount_; } + public virtual double spread() { return spread_; } + public virtual DayCounter yoyDayCount() { return yoyDayCount_; } public virtual Calendar paymentCalendar() { return paymentCalendar_; } - public virtual BusinessDayConvention paymentConvention() { return paymentConvention_; } + public virtual BusinessDayConvention paymentConvention() { return paymentConvention_; } - public virtual List fixedLeg() { return legs_[0]; } - public virtual List yoyLeg() { return legs_[1]; } + public virtual List fixedLeg() { return legs_[0]; } + public virtual List yoyLeg() { return legs_[1]; } // other - public override void setupArguments( IPricingEngineArguments args ) - { - base.setupArguments(args); + public override void setupArguments(IPricingEngineArguments args) + { + base.setupArguments(args); - YearOnYearInflationSwap.Arguments arguments = args as YearOnYearInflationSwap.Arguments; + YearOnYearInflationSwap.Arguments arguments = args as YearOnYearInflationSwap.Arguments; - if (arguments == null) // it's a swap engine... + if (arguments == null) // it's a swap engine... return; - arguments.type = type_; - arguments.nominal = nominal_; + arguments.type = type_; + arguments.nominal = nominal_; - List fixedCoupons = fixedLeg(); + List fixedCoupons = fixedLeg(); - arguments.fixedResetDates = arguments.fixedPayDates = new List(fixedCoupons.Count); - arguments.fixedCoupons = new List(fixedCoupons.Count); + arguments.fixedResetDates = arguments.fixedPayDates = new List(fixedCoupons.Count); + arguments.fixedCoupons = new List(fixedCoupons.Count); - for (int i=0; i yoyCoupons = yoyLeg(); + List yoyCoupons = yoyLeg(); - arguments.yoyResetDates = arguments.yoyPayDates = arguments.yoyFixingDates =new List(yoyCoupons.Count); - arguments.yoyAccrualTimes = new List(yoyCoupons.Count); - arguments.yoySpreads = new List(yoyCoupons.Count); - arguments.yoyCoupons = new List(yoyCoupons.Count); - for (int i=0; i(yoyCoupons.Count); + arguments.yoyAccrualTimes = new List(yoyCoupons.Count); + arguments.yoySpreads = new List(yoyCoupons.Count); + arguments.yoyCoupons = new List < double? >(yoyCoupons.Count); + for (int i = 0; i < yoyCoupons.Count; ++i) + { + YoYInflationCoupon coupon = yoyCoupons[i] as YoYInflationCoupon; arguments.yoyResetDates.Add(coupon.accrualStartDate()); arguments.yoyPayDates.Add(coupon.date()); @@ -187,60 +187,61 @@ public override void setupArguments( IPricingEngineArguments args ) arguments.yoyFixingDates.Add(coupon.fixingDate()); arguments.yoyAccrualTimes.Add(coupon.accrualPeriod()); arguments.yoySpreads.Add(coupon.spread()); - try - { - arguments.yoyCoupons.Add(coupon.amount()); - } - catch (Exception ) { - arguments.yoyCoupons.Add(null); + try + { + arguments.yoyCoupons.Add(coupon.amount()); + } + catch (Exception) + { + arguments.yoyCoupons.Add(null); } - } - - } - public override void fetchResults( IPricingEngineResults r ) - { - // copy from VanillaSwap - // works because similarly simple instrument - // that we always expect to be priced with a swap engine - - base.fetchResults(r); - - YearOnYearInflationSwap.Results results = r as YearOnYearInflationSwap.Results; - if (results != null) - { - // might be a swap engine, so no error is thrown - fairRate_ = results.fairRate; - fairSpread_ = results.fairSpread; - } - else - { - fairRate_ = null; - fairSpread_ = null; - } - - if (fairRate_ == null) - { + } + + } + public override void fetchResults(IPricingEngineResults r) + { + // copy from VanillaSwap + // works because similarly simple instrument + // that we always expect to be priced with a swap engine + + base.fetchResults(r); + + YearOnYearInflationSwap.Results results = r as YearOnYearInflationSwap.Results; + if (results != null) + { + // might be a swap engine, so no error is thrown + fairRate_ = results.fairRate; + fairSpread_ = results.fairSpread; + } + else + { + fairRate_ = null; + fairSpread_ = null; + } + + if (fairRate_ == null) + { // calculate it from other results if (legBPS_[0] != null) - fairRate_ = fixedRate_ - NPV_/(legBPS_[0]/basisPoint); - } - if (fairSpread_ == null) - { + fairRate_ = fixedRate_ - NPV_ / (legBPS_[0] / basisPoint); + } + if (fairSpread_ == null) + { // ditto if (legBPS_[1] != null) - fairSpread_ = spread_ - NPV_/(legBPS_[1]/basisPoint); - } + fairSpread_ = spread_ - NPV_ / (legBPS_[1] / basisPoint); + } - } + } - protected override void setupExpired() - { - base.setupExpired(); - legBPS_[0] = legBPS_[1] = 0.0; - fairRate_ = null; - fairSpread_ = null; - } + protected override void setupExpired() + { + base.setupExpired(); + legBPS_[0] = legBPS_[1] = 0.0; + fairRate_ = null; + fairSpread_ = null; + } private Type type_; private double nominal_; private Schedule fixedSchedule_; @@ -257,16 +258,16 @@ protected override void setupExpired() private double? fairRate_; private double? fairSpread_; - //! %Arguments for YoY swap calculation - public new class Arguments : Swap.Arguments - { - public Arguments() - { - type = Type.Receiver; - nominal = null ; - } + //! %Arguments for YoY swap calculation + public new class Arguments : Swap.Arguments + { + public Arguments() + { + type = Type.Receiver; + nominal = null ; + } - public Type type { get; set; } + public Type type { get; set; } public double? nominal { get; set; } public List fixedResetDates { get; set; } @@ -278,42 +279,42 @@ public Arguments() public List fixedCoupons { get; set; } public List yoySpreads { get; set; } - public List yoyCoupons { get; set; } + public List < double? > yoyCoupons { get; set; } public override void validate() - { - base.validate(); - Utils.QL_REQUIRE( nominal != null, () => "nominal null or not set" ); - Utils.QL_REQUIRE( fixedResetDates.Count == fixedPayDates.Count, () => - "number of fixed start dates different from number of fixed payment dates"); - Utils.QL_REQUIRE( fixedPayDates.Count == fixedCoupons.Count, () => - "number of fixed payment dates different from number of fixed coupon amounts"); - Utils.QL_REQUIRE( yoyResetDates.Count == yoyPayDates.Count, () => - "number of yoy start dates different from number of yoy payment dates"); - Utils.QL_REQUIRE( yoyFixingDates.Count == yoyPayDates.Count, () => - "number of yoy fixing dates different from number of yoy payment dates"); - Utils.QL_REQUIRE( yoyAccrualTimes.Count == yoyPayDates.Count, () => - "number of yoy accrual Times different from number of yoy payment dates"); - Utils.QL_REQUIRE( yoySpreads.Count == yoyPayDates.Count, () => - "number of yoy spreads different from number of yoy payment dates"); - Utils.QL_REQUIRE( yoyPayDates.Count == yoyCoupons.Count, () => - "number of yoy payment dates different from number of yoy coupon amounts"); - } - } - - //! %Results from YoY swap calculation - public new class Results : Swap.Results - { - public double? fairRate { get; set; } + { + base.validate(); + Utils.QL_REQUIRE(nominal != null, () => "nominal null or not set"); + Utils.QL_REQUIRE(fixedResetDates.Count == fixedPayDates.Count, () => + "number of fixed start dates different from number of fixed payment dates"); + Utils.QL_REQUIRE(fixedPayDates.Count == fixedCoupons.Count, () => + "number of fixed payment dates different from number of fixed coupon amounts"); + Utils.QL_REQUIRE(yoyResetDates.Count == yoyPayDates.Count, () => + "number of yoy start dates different from number of yoy payment dates"); + Utils.QL_REQUIRE(yoyFixingDates.Count == yoyPayDates.Count, () => + "number of yoy fixing dates different from number of yoy payment dates"); + Utils.QL_REQUIRE(yoyAccrualTimes.Count == yoyPayDates.Count, () => + "number of yoy accrual Times different from number of yoy payment dates"); + Utils.QL_REQUIRE(yoySpreads.Count == yoyPayDates.Count, () => + "number of yoy spreads different from number of yoy payment dates"); + Utils.QL_REQUIRE(yoyPayDates.Count == yoyCoupons.Count, () => + "number of yoy payment dates different from number of yoy coupon amounts"); + } + } + + //! %Results from YoY swap calculation + public new class Results : Swap.Results + { + public double? fairRate { get; set; } public double? fairSpread { get; set; } public override void reset() - { - base.reset(); - fairRate = null; - fairSpread = null; - } - } + { + base.reset(); + fairRate = null; + fairSpread = null; + } + } - public class Engine : GenericEngine {}; + public class Engine : GenericEngine {} - } + } } diff --git a/src/QLNet/Instruments/ZeroCouponInflationSwap.cs b/src/QLNet/Instruments/ZeroCouponInflationSwap.cs index 113238750..248e22bfa 100644 --- a/src/QLNet/Instruments/ZeroCouponInflationSwap.cs +++ b/src/QLNet/Instruments/ZeroCouponInflationSwap.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -51,10 +51,10 @@ swap also works. \note we do not need Schedules on the legs because they use one or two dates only per leg. */ - public class ZeroCouponInflationSwap : Swap + public class ZeroCouponInflationSwap : Swap { - - public enum Type { Receiver = -1, Payer = 1 }; + + public enum Type { Receiver = -1, Payer = 1 } /* Generally inflation indices are available with a lag of 1month and then observed with a lag of 2-3 months depending whether @@ -74,7 +74,7 @@ public ZeroCouponInflationSwap(Type type, bool adjustInfObsDates = false, Calendar infCalendar = null, BusinessDayConvention? infConvention = null) - :base(2) + : base(2) { type_ = type; nominal_ = nominal; @@ -90,36 +90,36 @@ public ZeroCouponInflationSwap(Type type, dayCounter_ = dayCounter; // first check compatibility of index and swap definitions - if (infIndex_.interpolated()) + if (infIndex_.interpolated()) { Period pShift = new Period(infIndex_.frequency()); - Utils.QL_REQUIRE( observationLag_ - pShift > infIndex_.availabilityLag(), () => - "inconsistency between swap observation of index " + observationLag_ + - " index availability " + infIndex_.availabilityLag() + - " interpolated index period " + pShift + - " and index availability " + infIndex_.availabilityLag() + - " need (obsLag-index period) > availLag"); - } - else + Utils.QL_REQUIRE(observationLag_ - pShift > infIndex_.availabilityLag(), () => + "inconsistency between swap observation of index " + observationLag_ + + " index availability " + infIndex_.availabilityLag() + + " interpolated index period " + pShift + + " and index availability " + infIndex_.availabilityLag() + + " need (obsLag-index period) > availLag"); + } + else { - Utils.QL_REQUIRE( infIndex_.availabilityLag() < observationLag_, () => - "index tries to observe inflation fixings that do not yet exist: " - + " availability lag " + infIndex_.availabilityLag() - + " versus obs lag = " + observationLag_); + Utils.QL_REQUIRE(infIndex_.availabilityLag() < observationLag_, () => + "index tries to observe inflation fixings that do not yet exist: " + + " availability lag " + infIndex_.availabilityLag() + + " versus obs lag = " + observationLag_); } - if (infCalendar_== null) infCalendar_ = fixCalendar_; - if (infConvention == null) + if (infCalendar_ == null) infCalendar_ = fixCalendar_; + if (infConvention == null) infConvention_ = fixConvention_; else infConvention_ = infConvention.Value; - if (adjustInfObsDates_) + if (adjustInfObsDates_) { baseDate_ = infCalendar_.adjust(startDate - observationLag_, infConvention_); obsDate_ = infCalendar_.adjust(maturity - observationLag_, infConvention_); - } - else + } + else { baseDate_ = startDate - observationLag_; obsDate_ = maturity - observationLag_; @@ -132,37 +132,37 @@ public ZeroCouponInflationSwap(Type type, // i.e. do not want to force the existence of an inflation // term structure before allowing users to create instruments. double T = Utils.inflationYearFraction(infIndex_.frequency(), infIndex_.interpolated(), - dayCounter_, baseDate_, obsDate_); + dayCounter_, baseDate_, obsDate_); // N.B. the -1.0 is because swaps only exchange growth, not notionals as well - double fixedAmount = nominal * ( Math.Pow(1.0 + fixedRate, T) - 1.0 ); + double fixedAmount = nominal * (Math.Pow(1.0 + fixedRate, T) - 1.0); legs_[0].Add(new SimpleCashFlow(fixedAmount, fixedPayDate)); bool growthOnly = true; - legs_[1].Add(new IndexedCashFlow(nominal,infIndex,baseDate_,obsDate_,infPayDate,growthOnly)); + legs_[1].Add(new IndexedCashFlow(nominal, infIndex, baseDate_, obsDate_, infPayDate, growthOnly)); - for (int j=0; j<2; ++j) + for (int j = 0; j<2; ++j) { legs_[j].ForEach((i, x) => x.registerWith(update)); } - switch (type_) + switch (type_) { case Type.Payer: - payer_[0] = +1.0; - payer_[1] = -1.0; - break; + payer_[0] = +1.0; + payer_[1] = -1.0; + break; case Type.Receiver: - payer_[0] = -1.0; - payer_[1] = +1.0; - break; + payer_[0] = -1.0; + payer_[1] = +1.0; + break; default: - Utils.QL_FAIL("Unknown zero-inflation-swap type"); + Utils.QL_FAIL("Unknown zero-inflation-swap type"); break; } } #region Inspectors - + //! "payer" or "receiver" refer to the inflation-indexed leg public Type type() { return type_; } public double nominal() { return nominal_; } @@ -182,12 +182,12 @@ public ZeroCouponInflationSwap(Type type, public List fixedLeg() { return legs_[0]; } //! just one cashflow (that is not a coupon) in each leg public List inflationLeg() { return legs_[1]; } - + #endregion #region Instrument interface - - public override void setupArguments(IPricingEngineArguments args) + + public override void setupArguments(IPricingEngineArguments args) { base.setupArguments(args); // you don't actually need to do anything else because it is so simple @@ -195,23 +195,23 @@ public override void setupArguments(IPricingEngineArguments args) public override void fetchResults(IPricingEngineResults r) { base.fetchResults(r); - // you don't actually need to do anything else because it is so simple + // you don't actually need to do anything else because it is so simple } #endregion #region Results - + public double fixedLegNPV() { calculate(); - Utils.QL_REQUIRE( legNPV_[0] != null, () => "result not available" ); + Utils.QL_REQUIRE(legNPV_[0] != null, () => "result not available"); return legNPV_[0].Value; } public double inflationLegNPV() { calculate(); - Utils.QL_REQUIRE( legNPV_[1] != null, () => "result not available" ); + Utils.QL_REQUIRE(legNPV_[1] != null, () => "result not available"); return legNPV_[1].Value; } public double fairRate() @@ -222,7 +222,7 @@ public double fairRate() // _knowing_ the time from base to obs (etc). IndexedCashFlow icf = legs_[1][0] as IndexedCashFlow; - Utils.QL_REQUIRE( icf != null, () => "failed to downcast to IndexedCashFlow in ::fairRate()" ); + Utils.QL_REQUIRE(icf != null, () => "failed to downcast to IndexedCashFlow in ::fairRate()"); // +1 because the IndexedCashFlow has growthOnly=true double growth = icf.amount() / icf.notional() + 1.0; @@ -230,9 +230,9 @@ public double fairRate() infIndex_.interpolated(), dayCounter_, baseDate_, obsDate_); - return Math.Pow(growth,1.0/T) - 1.0; + return Math.Pow(growth, 1.0 / T) - 1.0; } - + #endregion @@ -250,12 +250,12 @@ public double fairRate() protected DayCounter dayCounter_; protected Date baseDate_, obsDate_; - public new class Arguments : Swap.Arguments - { - public double fixedRate{ get; set; } - } + public new class Arguments : Swap.Arguments + { + public double fixedRate { get; set; } + } - public class Engine : GenericEngine { }; + public class Engine : GenericEngine { } } } diff --git a/src/QLNet/Instruments/bmaswap.cs b/src/QLNet/Instruments/bmaswap.cs deleted file mode 100644 index e49200bce..000000000 --- a/src/QLNet/Instruments/bmaswap.cs +++ /dev/null @@ -1,128 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet { - //! swap paying Libor against BMA coupons - public class BMASwap : Swap { - public enum Type { Receiver = -1, Payer = 1 }; - - private Type type_; - public Type type() { return type_; } - - private double nominal_; - public double nominal() { return nominal_; } - - private double liborFraction_; - public double liborFraction() { return liborFraction_; } - - private double liborSpread_; - public double liborSpread() { return liborSpread_; } - - - public BMASwap(Type type, double nominal, - // Libor leg - Schedule liborSchedule, double liborFraction, double liborSpread, IborIndex liborIndex, DayCounter liborDayCount, - // BMA leg - Schedule bmaSchedule, BMAIndex bmaIndex, DayCounter bmaDayCount) - : base(2) { - type_ = type; - nominal_ = nominal; - liborFraction_ = liborFraction; - liborSpread_ = liborSpread; - - BusinessDayConvention convention = liborSchedule.businessDayConvention(); - - legs_[0] = new IborLeg(liborSchedule, liborIndex) - .withPaymentDayCounter(liborDayCount) - .withFixingDays(liborIndex.fixingDays()) - .withGearings(liborFraction) - .withSpreads(liborSpread) - .withNotionals(nominal) - .withPaymentAdjustment(convention); - - legs_[1] = new AverageBMALeg(bmaSchedule, bmaIndex) - .withPaymentDayCounter(bmaDayCount) - .withNotionals(nominal) - .withPaymentAdjustment(bmaSchedule.businessDayConvention()); - - for (int j=0; j<2; ++j) { - for (int i=0; i liborLeg() { return legs_[0]; } - public List bmaLeg() { return legs_[1]; } - - public double liborLegBPS() { - calculate(); - Utils.QL_REQUIRE(legBPS_[0] != null,()=> "result not available"); - return legBPS_[0].GetValueOrDefault(); - } - - public double liborLegNPV() { - calculate(); - Utils.QL_REQUIRE(legNPV_[0] != null,()=> "result not available"); - return legNPV_[0].GetValueOrDefault(); - } - - public double fairLiborFraction() { - const double basisPoint = 1.0e-4; - - double spreadNPV = (liborSpread_/basisPoint)*liborLegBPS(); - double pureLiborNPV = liborLegNPV() - spreadNPV; - Utils.QL_REQUIRE(pureLiborNPV.IsNotEqual(0.0),()=> "result not available (null libor NPV)"); - return -liborFraction_ * (bmaLegNPV() + spreadNPV) / pureLiborNPV; - } - - public double fairLiborSpread() { - const double basisPoint = 1.0e-4; - return liborSpread_ - NPV()/(liborLegBPS()/basisPoint); - } - - public double bmaLegBPS() { - calculate(); - Utils.QL_REQUIRE(legBPS_[1] != null,()=> "result not available"); - return legBPS_[1].GetValueOrDefault(); - } - - public double bmaLegNPV() { - calculate(); - Utils.QL_REQUIRE(legNPV_[1] != null,()=> "result not available"); - return legNPV_[1].GetValueOrDefault(); - } - } -} diff --git a/src/QLNet/Instruments/forward.cs b/src/QLNet/Instruments/forward.cs deleted file mode 100644 index 696c03460..000000000 --- a/src/QLNet/Instruments/forward.cs +++ /dev/null @@ -1,161 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -namespace QLNet { - //! Abstract base forward class - /*! Derived classes must implement the virtual functions spotValue() (NPV or spot price) and spotIncome() associated - with the specific relevant underlying (e.g. bond, stock, commodity, loan/deposit). These functions must be used to set the - protected member variables underlyingSpotValue_ and underlyingIncome_ within performCalculations() in the derived - class before the base-class implementation is called. - - spotIncome() refers generically to the present value of coupons, dividends or storage costs. - - discountCurve_ is the curve used to discount forward contract cash flows back to the evaluation day, as well as to obtain - forward values for spot values/prices. - - incomeDiscountCurve_, which for generality is not automatically set to the discountCurve_, is the curve used to - discount future income/dividends/storage-costs etc back to the evaluation date. - - \todo Add preconditions and tests - - \warning This class still needs to be rigorously tested - - \ingroup instruments - */ - public abstract class Forward : Instrument { - /*! derived classes must set this, typically via spotIncome() */ - protected double underlyingIncome_; - /*! derived classes must set this, typically via spotValue() */ - protected double underlyingSpotValue_; - - protected DayCounter dayCounter_; - protected Calendar calendar_; - protected BusinessDayConvention businessDayConvention_; - protected int settlementDays_; - protected Payoff payoff_; - /*! valueDate = settlement date (date the fwd contract starts accruing) */ - protected Date valueDate_; - //! maturityDate of the forward contract or delivery date of underlying - protected Date maturityDate_; - protected Handle discountCurve_; - /*! must set this in derived classes, based on particular underlying */ - protected Handle incomeDiscountCurve_; - - protected Forward(DayCounter dayCounter, Calendar calendar, BusinessDayConvention businessDayConvention, - int settlementDays, Payoff payoff, Date valueDate, Date maturityDate, - Handle discountCurve) { - dayCounter_ = dayCounter; - calendar_ = calendar; - businessDayConvention_ = businessDayConvention; - settlementDays_ = settlementDays; - payoff_ = payoff; - valueDate_ = valueDate; - maturityDate_ = maturityDate; - discountCurve_ = discountCurve; - - maturityDate_ = calendar_.adjust(maturityDate_, businessDayConvention_); - - Settings.registerWith(update); - discountCurve_.registerWith(update); - } - - public virtual Date settlementDate() { - Date d = calendar_.advance(Settings.evaluationDate(), settlementDays_, TimeUnit.Days); - return Date.Max(d,valueDate_); - } - - public override bool isExpired() { - return new simple_event(maturityDate_).hasOccurred(settlementDate()); - } - - - //! returns spot value/price of an underlying financial instrument - public abstract double spotValue(); - //! NPV of income/dividends/storage-costs etc. of underlying instrument - public abstract double spotIncome(Handle incomeDiscountCurve); - - // Calculations - //! forward value/price of underlying, discounting income/dividends - /*! \note if this is a bond forward price, is must be a dirty - forward price. - */ - public virtual double forwardValue() { - calculate(); - return (underlyingSpotValue_ - underlyingIncome_ )/ discountCurve_.link.discount(maturityDate_); - } - - /*! Simple yield calculation based on underlying spot and - forward values, taking into account underlying income. - When \f$ t>0 \f$, call with: - underlyingSpotValue=spotValue(t), - forwardValue=strikePrice, to get current yield. For a - repo, if \f$ t=0 \f$, impliedYield should reproduce the - spot repo rate. For FRA's, this should reproduce the - relevant zero rate at the FRA's maturityDate_ - */ - public InterestRate impliedYield(double underlyingSpotValue, double forwardValue, Date settlementDate, - Compounding compoundingConvention, DayCounter dayCounter) { - - double tenor = dayCounter.yearFraction(settlementDate,maturityDate_) ; - double compoundingFactor = forwardValue/ (underlyingSpotValue-spotIncome(incomeDiscountCurve_)) ; - return InterestRate.impliedRate(compoundingFactor,dayCounter,compoundingConvention,Frequency.Annual,tenor); - } - - protected override void performCalculations() { - Utils.QL_REQUIRE(!discountCurve_.empty(),()=> "no discounting term structure set to Forward"); - - ForwardTypePayoff ftpayoff = payoff_ as ForwardTypePayoff; - double fwdValue = forwardValue(); - NPV_ = ftpayoff.value(fwdValue) * discountCurve_.link.discount(maturityDate_); - } - } - - //! Class for forward type payoffs - public class ForwardTypePayoff : Payoff { - protected Position.Type type_; - public Position.Type forwardType() { return type_; } - - protected double strike_; - public double strike() { return strike_; } - - public ForwardTypePayoff(Position.Type type, double strike) { - type_ = type; - strike_ = strike; - Utils.QL_REQUIRE(strike >= 0.0,()=> "negative strike given"); - } - - // Payoff interface - public override string name() { return "Forward";} - public override string description() { - string result = name() + ", " + strike() + " strike"; - return result; - } - public override double value(double price) { - switch (type_) { - case Position.Type.Long: - return (price-strike_); - case Position.Type.Short: - return (strike_-price); - default: - Utils.QL_FAIL("unknown/illegal position type"); - return 0; - } - } - }; -} diff --git a/src/QLNet/Instruments/payoffs.cs b/src/QLNet/Instruments/payoffs.cs deleted file mode 100644 index f6cfaee78..000000000 --- a/src/QLNet/Instruments/payoffs.cs +++ /dev/null @@ -1,240 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! Intermediate class for put/call payoffs - public class TypePayoff : Payoff { - protected Option.Type type_; - public Option.Type optionType() { return type_; } - - public TypePayoff(Option.Type type) { - type_ = type; - } - - // Payoff interface - public override string description() { return name() + " " + optionType(); } - } - - //! %Payoff based on a floating strike - public class FloatingTypePayoff : TypePayoff { - public FloatingTypePayoff(Option.Type type) : base(type) {} - - // Payoff interface - public override string name() { return "FloatingType";} - - public override double value(double k) { throw new NotSupportedException("floating payoff not handled"); } - } - - //! Intermediate class for payoffs based on a fixed strike - public class StrikedTypePayoff : TypePayoff { - protected double strike_; - - public StrikedTypePayoff(Option.Type type, double strike) : base(type) { - strike_ = strike; - } - - public StrikedTypePayoff(Payoff p) - : base((p as StrikedTypePayoff).type_) - { - strike_ = (p as StrikedTypePayoff).strike_; - } - - // Payoff interface - public override string description() { - return base.description() + ", " + strike() + " strike"; - } - - public double strike() { return strike_; } - } - - //! Plain-vanilla payoff - public class PlainVanillaPayoff : StrikedTypePayoff { - public PlainVanillaPayoff(Option.Type type, double strike) : base(type, strike) {} - - // Payoff interface - public override string name() { return "Vanilla";} - public override double value(double price) { - switch (type_) { - case Option.Type.Call: - return Math.Max(price-strike_,0.0); - case Option.Type.Put: - return Math.Max(strike_ - price, 0.0); - default: - throw new ArgumentException("unknown/illegal option type"); - } - } - } - - //! %Payoff with strike expressed as percentage - public class PercentageStrikePayoff : StrikedTypePayoff { - public PercentageStrikePayoff(Option.Type type, double moneyness) : base(type, moneyness) {} - - // Payoff interface - public override string name() { return "PercentageStrike";} - public override double value(double price) { - switch (type_) { - case Option.Type.Call: - return price * Math.Max(1.0 - strike_, 0.0); - case Option.Type.Put: - return price * Math.Max(strike_ - 1.0, 0.0); - default: - throw new ArgumentException("unknown/illegal option type"); - } - } - } - - /*! Definitions of Binary path-independent payoffs used below, - can be found in M. Rubinstein, E. Reiner:"Unscrambling The Binary Code", Risk, Vol.4 no.9,1991. - (see: http://www.in-the-money.com/artandpap/Binary%20Options.doc) - */ - //! Binary asset-or-nothing payoff - public class AssetOrNothingPayoff : StrikedTypePayoff { - public AssetOrNothingPayoff(Option.Type type, double strike) : base(type, strike) {} - - // Payoff interface - public override string name() { return "AssetOrNothing";} - public override double value(double price) { - switch (type_) { - case Option.Type.Call: - return (price-strike_ > 0.0 ? price : 0.0); - case Option.Type.Put: - return (strike_-price > 0.0 ? price : 0.0); - default: - throw new ArgumentException("unknown/illegal option type"); - } - } - } - - //! Binary cash-or-nothing payoff - public class CashOrNothingPayoff : StrikedTypePayoff { - protected double cashPayoff_; - public double cashPayoff() { return cashPayoff_;} - - public CashOrNothingPayoff(Option.Type type, double strike, double cashPayoff) : base(type, strike) { - cashPayoff_ = cashPayoff; - } - // Payoff interface - public override string name() { return "CashOrNothing";} - public override string description() { - return base.description() + ", " + cashPayoff() + " cash payoff"; - } - public override double value(double price) { - switch (type_) { - case Option.Type.Call: - return (price-strike_ > 0.0 ? cashPayoff_ : 0.0); - case Option.Type.Put: - return (strike_-price > 0.0 ? cashPayoff_ : 0.0); - default: - throw new ArgumentException("unknown/illegal option type"); - } - } - } - - //! Binary gap payoff - /*! This payoff is equivalent to being a) long a PlainVanillaPayoff at - the first strike (same Call/Put type) and b) short a - CashOrNothingPayoff at the first strike (same Call/Put type) with - cash payoff equal to the difference between the second and the first - strike. - \warning this payoff can be negative depending on the strikes - */ - public class GapPayoff : StrikedTypePayoff { - protected double secondStrike_; - public double secondStrike() { return secondStrike_;} - - public GapPayoff(Option.Type type, double strike, double secondStrike) // a.k.a. payoff strike - : base(type, strike) { - secondStrike_ = secondStrike; - } - - // Payoff interface - public override string name() { return "Gap";} - public override string description() { - return base.description() + ", " + secondStrike() + " strike payoff"; - } - public override double value(double price) { - switch (type_) { - case Option.Type.Call: - return (price-strike_ >= 0.0 ? price-secondStrike_ : 0.0); - case Option.Type.Put: - return (strike_-price >= 0.0 ? secondStrike_-price : 0.0); - default: - throw new ArgumentException("unknown/illegal option type"); - } - } - } - - //! Binary supershare and superfund payoffs - - //! Binary superfund payoff - /*! Superfund sometimes also called "supershare", which can lead to ambiguity; within QuantLib - the terms supershare and superfund are used consistently according to the definitions in - Bloomberg OVX function's help pages. - */ - /*! This payoff is equivalent to being (1/lowerstrike) a) long (short) an AssetOrNothing - Call (Put) at the lower strike and b) short (long) an AssetOrNothing - Call (Put) at the higher strike - */ - public class SuperFundPayoff : StrikedTypePayoff { - protected double secondStrike_; - public double secondStrike() { return secondStrike_;} - - public SuperFundPayoff(double strike, double secondStrike) : base(Option.Type.Call, strike) { - secondStrike_ = secondStrike; - - Utils.QL_REQUIRE(strike>0.0,()=> "strike (" + strike + ") must be positive"); - Utils.QL_REQUIRE(secondStrike>strike,()=> "second strike (" + secondStrike + - ") must be higher than first strike (" + strike + ")"); - } - - // Payoff interface - public override string name() { return "SuperFund";} - public override double value(double price) { - return (price >= strike_ && price < secondStrike_) ? price / strike_ : 0.0; - } - } - - //! Binary supershare payoff - public class SuperSharePayoff : StrikedTypePayoff { - protected double secondStrike_; - public double secondStrike() { return secondStrike_; } - - protected double cashPayoff_; - public double cashPayoff() { return cashPayoff_; } - - public SuperSharePayoff(double strike, double secondStrike, double cashPayoff) - : base(Option.Type.Call, strike) { - secondStrike_ = secondStrike; - cashPayoff_ = cashPayoff; - - Utils.QL_REQUIRE(secondStrike>strike,()=> "second strike (" + secondStrike + - ") must be higher than first strike (" + strike + ")"); - } - - // Payoff interface - public override string name() { return "SuperShare";} - public override string description() { - return base.description() + ", " + secondStrike() + " second strike" + ", " + cashPayoff() + " amount"; - } - public override double value(double price) { - return (price>=strike_ && price. - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet +namespace QLNet { //! Concrete interest rate class /*! This class encapsulate the interest rate compounding algebra. @@ -28,7 +28,7 @@ namespace QLNet \test Converted rates are checked against known good results */ - public class InterestRate + public class InterestRate { #region Constructors @@ -49,14 +49,14 @@ public InterestRate(double r, DayCounter dc, Compounding comp, Frequency freq) if (comp_ == Compounding.Compounded || comp_ == Compounding.SimpleThenCompounded) { freqMakesSense_ = true; - Utils.QL_REQUIRE( freq != Frequency.Once && freq != Frequency.NoFrequency, () => "frequency not allowed for this interest rate" ); + Utils.QL_REQUIRE(freq != Frequency.Once && freq != Frequency.NoFrequency, () => "frequency not allowed for this interest rate"); freq_ = (double)freq; } } #endregion - + #region Conversions public double value() { return rate(); } // operator redefinition @@ -81,11 +81,11 @@ day counter. public double discountFactor(double t) { return 1.0 / compoundFactor(t); } //! discount factor implied by the rate compounded between two dates - public double discountFactor(Date d1, Date d2, Date refStart = null, Date refEnd = null) + public double discountFactor(Date d1, Date d2, Date refStart = null, Date refEnd = null) { - Utils.QL_REQUIRE( d2 >= d1, () => "d1 (" + d1 + ") later than d2 (" + d2 + ")" ); - double t = dc_.yearFraction(d1, d2, refStart, refEnd); - return discountFactor(t); + Utils.QL_REQUIRE(d2 >= d1, () => "d1 (" + d1 + ") later than d2 (" + d2 + ")"); + double t = dc_.yearFraction(d1, d2, refStart, refEnd); + return discountFactor(t); } //! compound factor implied by the rate compounded at time t. @@ -97,36 +97,36 @@ day counter. */ public double compoundFactor(double t) { - Utils.QL_REQUIRE( t >= 0.0, () => "negative time not allowed" ); - Utils.QL_REQUIRE( r_ != null, () => "null interest rate" ); - switch (comp_) + Utils.QL_REQUIRE(t >= 0.0, () => "negative time not allowed"); + Utils.QL_REQUIRE(r_ != null, () => "null interest rate"); + switch (comp_) { case Compounding.Simple: - return 1.0 + r_.Value*t; + return 1.0 + r_.Value * t; case Compounding.Compounded: - return Math.Pow(1.0+r_.Value/freq_, freq_*t); + return Math.Pow(1.0 + r_.Value / freq_, freq_ * t); case Compounding.Continuous: - return Math.Exp(r_.Value*t); + return Math.Exp(r_.Value * t); case Compounding.SimpleThenCompounded: - if (t<=1.0/freq_) - return 1.0 + r_.Value*t; + if (t <= 1.0 / freq_) + return 1.0 + r_.Value * t; else - return Math.Pow(1.0+r_.Value/freq_, freq_*t); + return Math.Pow(1.0 + r_.Value / freq_, freq_ * t); default: Utils.QL_FAIL("unknown compounding convention"); return 0; - } + } } //! compound factor implied by the rate compounded between two dates /*! returns the compound (a.k.a capitalization) factor implied by the rate compounded between two dates. */ - public double compoundFactor(Date d1, Date d2, Date refStart = null, Date refEnd = null) + public double compoundFactor(Date d1, Date d2, Date refStart = null, Date refEnd = null) { - Utils.QL_REQUIRE( d2 >= d1, () => "d1 (" + d1 + ") later than d2 (" + d2 + ")" ); - double t = dc_.yearFraction(d1, d2, refStart, refEnd); - return compoundFactor(t); + Utils.QL_REQUIRE(d2 >= d1, () => "d1 (" + d1 + ") later than d2 (" + d2 + ")"); + double t = dc_.yearFraction(d1, d2, refStart, refEnd); + return compoundFactor(t); } #endregion @@ -142,31 +142,31 @@ as input. */ public static InterestRate impliedRate(double compound, DayCounter resultDC, Compounding comp, Frequency freq, double t) { - Utils.QL_REQUIRE( compound > 0.0, () => "positive compound factor required" ); + Utils.QL_REQUIRE(compound > 0.0, () => "positive compound factor required"); double r = 0; - if (compound.IsEqual(1.0)) + if (compound.IsEqual(1.0)) { - Utils.QL_REQUIRE( t >= 0.0, () => "non negative time (" + t + ") required" ); + Utils.QL_REQUIRE(t >= 0.0, () => "non negative time (" + t + ") required"); r = 0.0; - } - else + } + else { - Utils.QL_REQUIRE( t > 0.0, () => "positive time (" + t + ") required" ); - switch (comp) + Utils.QL_REQUIRE(t > 0.0, () => "positive time (" + t + ") required"); + switch (comp) { case Compounding.Simple: - r = (compound - 1.0)/t; + r = (compound - 1.0) / t; break; case Compounding.Compounded: - r = (Math.Pow(compound, 1.0/(((double)freq)*t))-1.0)*((double)freq); + r = (Math.Pow(compound, 1.0 / (((double)freq) * t)) - 1.0) * ((double)freq); break; case Compounding.Continuous: - r = Math.Log(compound)/t; + r = Math.Log(compound) / t; break; case Compounding.SimpleThenCompounded: - if (t<=1.0/((double)freq)) - r = (compound - 1.0)/t; + if (t <= 1.0 / ((double)freq)) + r = (compound - 1.0) / t; else r = (Math.Pow(compound, 1.0 / (((double)freq) * t)) - 1.0) * ((double)freq); break; @@ -174,8 +174,8 @@ public static InterestRate impliedRate(double compound, DayCounter resultDC, Com Utils.QL_FAIL("unknown compounding convention (" + comp + ")"); break; } - } - return new InterestRate(r, resultDC, comp, freq); + } + return new InterestRate(r, resultDC, comp, freq); } //! implied rate for a given compound factor between two dates. @@ -183,9 +183,9 @@ public static InterestRate impliedRate(double compound, DayCounter resultDC, Com day-counting rule into account. */ public static InterestRate impliedRate(double compound, DayCounter resultDC, Compounding comp, Frequency freq, Date d1, Date d2, - Date refStart = null, Date refEnd = null) + Date refStart = null, Date refEnd = null) { - Utils.QL_REQUIRE( d2 >= d1, () => "d1 (" + d1 + ") later than d2 (" + d2 + ")" ); + Utils.QL_REQUIRE(d2 >= d1, () => "d1 (" + d1 + ") later than d2 (" + d2 + ")"); double t = resultDC.yearFraction(d1, d2, refStart, refEnd); return impliedRate(compound, resultDC, comp, freq, t); } @@ -202,9 +202,9 @@ public static InterestRate impliedRate(double compound, DayCounter resultDC, Com \warning Time must be measured using the InterestRate's own day counter. */ - public InterestRate equivalentRate(Compounding comp, Frequency freq, double t) + public InterestRate equivalentRate(Compounding comp, Frequency freq, double t) { - return impliedRate(compoundFactor(t), dc_, comp, freq, t); + return impliedRate(compoundFactor(t), dc_, comp, freq, t); } //! equivalent rate for a compounding period between two dates @@ -212,15 +212,15 @@ public InterestRate equivalentRate(Compounding comp, Frequency freq, double t) day-counting rule into account. */ public InterestRate equivalentRate(DayCounter resultDC, Compounding comp, Frequency freq, Date d1, Date d2, - Date refStart = null,Date refEnd = null) + Date refStart = null, Date refEnd = null) { - Utils.QL_REQUIRE( d2 >= d1, () => "d1 (" + d1 + ") later than d2 (" + d2 + ")" ); - double t1 = dc_.yearFraction(d1, d2, refStart, refEnd); - double t2 = resultDC.yearFraction(d1, d2, refStart, refEnd); - return impliedRate(compoundFactor(t1), resultDC, comp, freq, t2); + Utils.QL_REQUIRE(d2 >= d1, () => "d1 (" + d1 + ") later than d2 (" + d2 + ")"); + double t1 = dc_.yearFraction(d1, d2, refStart, refEnd); + double t2 = resultDC.yearFraction(d1, d2, refStart, refEnd); + return impliedRate(compoundFactor(t1), resultDC, comp, freq, t2); } - public override string ToString() + public override string ToString() { string result = ""; if (r_ == null) @@ -256,8 +256,8 @@ public override string ToString() break; default: result += "simple compounding up to " - + 12 / (int)frequency() + " months, then " - + frequency() + " compounding"; + + 12 / (int)frequency() + " months, then " + + frequency() + " compounding"; break; } break; @@ -276,6 +276,6 @@ public override string ToString() private Compounding comp_; private bool freqMakesSense_; private double freq_; - } + } } diff --git a/src/QLNet/Math/AbcdMathFunction.cs b/src/QLNet/Math/AbcdMathFunction.cs index 33ff9425e..d7fad607e 100644 --- a/src/QLNet/Math/AbcdMathFunction.cs +++ b/src/QLNet/Math/AbcdMathFunction.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,7 +23,7 @@ namespace QLNet following Rebonato's notation. */ public class AbcdMathFunction { - public AbcdMathFunction(double a = 0.002,double b = 0.001, double c = 0.16,double d = 0.0005) + public AbcdMathFunction(double a = 0.002, double b = 0.001, double c = 0.16, double d = 0.0005) { a_ = a; b_ = b; @@ -38,10 +38,10 @@ public AbcdMathFunction(double a = 0.002,double b = 0.001, double c = 0.16,doubl initialize_(); } - public AbcdMathFunction( List abcd) + public AbcdMathFunction(List abcd) { abcd_ = new List(abcd); - dabcd_= new InitializedList(4); + dabcd_ = new InitializedList(4); a_ = abcd_[0]; b_ = abcd_[1]; c_ = abcd_[2]; @@ -52,15 +52,15 @@ public AbcdMathFunction( List abcd) //! function value at time t: \f[ f(t) \f] public double value(double t) { - return t<0 ? 0.0 : (a_ + b_*t)*Math.Exp(-c_*t) + d_; + return t < 0 ? 0.0 : (a_ + b_ * t) * Math.Exp(-c_ * t) + d_; } //! time at which the function reaches maximum (if any) public double maximumLocation() { - if ( b_ .IsEqual(0.0) ) + if (b_ .IsEqual(0.0)) { - if ( a_ >= 0.0 ) + if (a_ >= 0.0) return 0.0; else return Double.MaxValue; @@ -70,15 +70,15 @@ public double maximumLocation() // TODO check if minimum // TODO check if maximum at +inf double zeroFirstDerivative = 1.0 / c_ - a_ / b_; - return ( zeroFirstDerivative > 0.0 ? zeroFirstDerivative : 0.0 ); + return (zeroFirstDerivative > 0.0 ? zeroFirstDerivative : 0.0); } //! maximum value of the function public double maximumValue() { - if (b_.IsEqual(0.0) || a_<=0.0) + if (b_.IsEqual(0.0) || a_ <= 0.0) return d_; - return this.value(maximumLocation()); + return this.value(maximumLocation()); } //! function value at time +inf: \f[ f(\inf) \f] @@ -88,21 +88,21 @@ public double maximumValue() \f[ f'(t) = [ (b-c*a) + (-c*b)*t) ] e^{-c*t} \f] */ public double derivative(double t) { - return t<0 ? 0.0 : (da_ + db_*t)*Math.Exp(-c_*t); + return t < 0 ? 0.0 : (da_ + db_ * t) * Math.Exp(-c_ * t); } - + /*! indefinite integral of the function at time t \f[ \int f(t)dt = [ (-a/c-b/c^2) + (-b/c)*t ] e^{-c*t} + d*t \f] */ public double primitive(double t) { - return t<0 ? 0.0 : (pa_ + pb_*t)*Math.Exp(-c_*t) + d_*t + K_; + return t < 0 ? 0.0 : (pa_ + pb_ * t) * Math.Exp(-c_ * t) + d_ * t + K_; } - + /*! definite integral of the function between t1 and t2 \f[ \int_{t1}^{t2} f(t)dt \f] */ public double definiteIntegral(double t1, double t2) { - return primitive( t2 ) - primitive( t1 ); + return primitive(t2) - primitive(t1); } /*! Inspectors */ @@ -119,12 +119,12 @@ public double definiteIntegral(double t1, double t2) public List definiteIntegralCoefficients(double t, double t2) { double dt = t2 - t; - double expcdt = Math.Exp(-c_*dt); + double expcdt = Math.Exp(-c_ * dt); List result = new InitializedList(4); - result[0] = diacplusbcc_ - (diacplusbcc_ + dibc_*dt)*expcdt; + result[0] = diacplusbcc_ - (diacplusbcc_ + dibc_ * dt) * expcdt; result[1] = dibc_ * (1.0 - expcdt); result[2] = c_; - result[3] = d_*dt; + result[3] = d_ * dt; return result; } @@ -133,43 +133,43 @@ public List definiteIntegralCoefficients(double t, double t2) public List definiteDerivativeCoefficients(double t, double t2) { double dt = t2 - t; - double expcdt = Math.Exp(-c_*dt); + double expcdt = Math.Exp(-c_ * dt); List result = new InitializedList(4); - result[1] = b_*c_/(1.0-expcdt); - result[0] = a_*c_ - b_ + result[1]*dt*expcdt; - result[0] /= 1.0-expcdt; + result[1] = b_ * c_ / (1.0 - expcdt); + result[0] = a_ * c_ - b_ + result[1] * dt * expcdt; + result[0] /= 1.0 - expcdt; result[2] = c_; - result[3] = d_/dt; + result[3] = d_ / dt; return result; } public static void validate(double a, double b, double c, double d) { - Utils.QL_REQUIRE(c>0,()=> "c (" + c + ") must be positive"); - Utils.QL_REQUIRE(d>=0,()=> "d (" + d + ") must be non negative"); - Utils.QL_REQUIRE(a+d>=0,()=> "a+d (" + a + "+" + d + ") must be non negative"); + Utils.QL_REQUIRE(c > 0, () => "c (" + c + ") must be positive"); + Utils.QL_REQUIRE(d >= 0, () => "d (" + d + ") must be non negative"); + Utils.QL_REQUIRE(a + d >= 0, () => "a+d (" + a + "+" + d + ") must be non negative"); - if (b>=0.0) + if (b >= 0.0) return; // the one and only stationary point... - double zeroFirstDerivative = 1.0/c-a/b; - if (zeroFirstDerivative>=0.0) + double zeroFirstDerivative = 1.0 / c - a / b; + if (zeroFirstDerivative >= 0.0) { // ... is a minimum // must be abcd(zeroFirstDerivative)>=0 - Utils.QL_REQUIRE(b>=-(d*c)/Math.Exp(c*a/b-1.0),()=> - "b (" + b + ") less than " + - -(d*c)/Math.Exp(c*a/b-1.0) + ": negative function value at stationary point " + zeroFirstDerivative); + Utils.QL_REQUIRE(b >= -(d * c) / Math.Exp(c * a / b - 1.0), () => + "b (" + b + ") less than " + + -(d * c) / Math.Exp(c * a / b - 1.0) + ": negative function value at stationary point " + zeroFirstDerivative); } } - + protected double a_, b_, c_, d_; - + private void initialize_() { - validate( a_, b_, c_, d_ ); + validate(a_, b_, c_, d_); da_ = b_ - c_ * a_; db_ = -c_ * b_; dabcd_[0] = da_; @@ -177,7 +177,7 @@ private void initialize_() dabcd_[2] = c_; dabcd_[3] = 0.0; - pa_ = -( a_ + b_ / c_ ) / c_; + pa_ = -(a_ + b_ / c_) / c_; pb_ = -b_ / c_; K_ = 0.0; diff --git a/src/QLNet/Math/BSpline.cs b/src/QLNet/Math/BSpline.cs index 0e39fd15e..23a40e96e 100644 --- a/src/QLNet/Math/BSpline.cs +++ b/src/QLNet/Math/BSpline.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -41,38 +41,38 @@ public BSpline(int p, int n, List knots) n_ = n; knots_ = knots; - Utils.QL_REQUIRE( p >= 1,()=> "lowest degree B-spline has p = 1" ); - Utils.QL_REQUIRE( n >= 1,()=> "number of control points n+1 >= 2" ); - Utils.QL_REQUIRE( p <= n,()=> "must have p <= n" ); + Utils.QL_REQUIRE(p >= 1, () => "lowest degree B-spline has p = 1"); + Utils.QL_REQUIRE(n >= 1, () => "number of control points n+1 >= 2"); + Utils.QL_REQUIRE(p <= n, () => "must have p <= n"); - Utils.QL_REQUIRE( knots.Count == p + n + 2,()=> "number of knots must equal p+n+2" ); + Utils.QL_REQUIRE(knots.Count == p + n + 2, () => "number of knots must equal p+n+2"); - for ( int i = 0; i < knots.Count - 1; ++i ) + for (int i = 0; i < knots.Count - 1; ++i) { - Utils.QL_REQUIRE( knots[i] <= knots[i + 1],()=> "knots points must be nondecreasing" ); + Utils.QL_REQUIRE(knots[i] <= knots[i + 1], () => "knots points must be nondecreasing"); } } public double value(int i, double x) { - Utils.QL_REQUIRE( i <= n_,()=> "i must not be greater than n" ); - return N( i, p_, x ); + Utils.QL_REQUIRE(i <= n_, () => "i must not be greater than n"); + return N(i, p_, x); } // recursive definition of N, the B-spline basis function private double N(int i, int p, double x) { - if (p==0) + if (p == 0) { - return (knots_[i] <= x && x < knots_[i+1]) ? 1.0 : 0.0; - } - else + return (knots_[i] <= x && x < knots_[i + 1]) ? 1.0 : 0.0; + } + else { - return ((x - knots_[i])/(knots_[i+p] - knots_[i]))*N(i,p-1,x) + - ((knots_[i+p+1]-x)/(knots_[i+p+1]-knots_[i+1]))* N(i+1,p-1,x); - } - - } + return ((x - knots_[i]) / (knots_[i + p] - knots_[i])) * N(i, p - 1, x) + + ((knots_[i + p + 1] - x) / (knots_[i + p + 1] - knots_[i + 1])) * N(i + 1, p - 1, x); + } + + } // e.g. p_=2 is a quadratic B-spline, p_=3 is a cubic B-Spline, etc. private int p_; diff --git a/src/QLNet/Math/BernsteinPolynomial.cs b/src/QLNet/Math/BernsteinPolynomial.cs index d0430ca3d..d12b9dd44 100644 --- a/src/QLNet/Math/BernsteinPolynomial.cs +++ b/src/QLNet/Math/BernsteinPolynomial.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -25,9 +25,9 @@ public class BernsteinPolynomial public static double get(uint i, uint n, double x) { double coeff = Factorial.get(n) / - (Factorial.get(n-i) * Factorial.get(i)); + (Factorial.get(n - i) * Factorial.get(i)); - return coeff * Math.Pow(x,i) * Math.Pow(1.0-x, n-i); + return coeff * Math.Pow(x, i) * Math.Pow(1.0 - x, n - i); } } } diff --git a/src/QLNet/Math/Beta.cs b/src/QLNet/Math/Beta.cs new file mode 100644 index 000000000..8feafd923 --- /dev/null +++ b/src/QLNet/Math/Beta.cs @@ -0,0 +1,112 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + public partial class Utils + { + public static double betaFunction(double z, double w) + { + return Math.Exp(GammaFunction.logValue(z) + + GammaFunction.logValue(w) - + GammaFunction.logValue(z + w)); + } + + public static double betaContinuedFraction(double a, double b, double x) + { + return betaContinuedFraction(a, b, x, 1e-16, 100); + } + public static double betaContinuedFraction(double a, double b, double x, double accuracy, int maxIteration) + { + double aa, del; + double qab = a + b; + double qap = a + 1.0; + double qam = a - 1.0; + double c = 1.0; + double d = 1.0 - qab * x / qap; + if (Math.Abs(d) < Const.QL_EPSILON) + d = Const.QL_EPSILON; + d = 1.0 / d; + double result = d; + + int m, m2; + for (m = 1; m <= maxIteration; m++) + { + m2 = 2 * m; + aa = m * (b - m) * x / ((qam + m2) * (a + m2)); + d = 1.0 + aa * d; + if (Math.Abs(d) < Const.QL_EPSILON) + d = Const.QL_EPSILON; + c = 1.0 + aa / c; + if (Math.Abs(c) < Const.QL_EPSILON) + c = Const.QL_EPSILON; + d = 1.0 / d; + result *= d * c; + aa = -(a + m) * (qab + m) * x / ((a + m2) * (qap + m2)); + d = 1.0 + aa * d; + if (Math.Abs(d) < Const.QL_EPSILON) + d = Const.QL_EPSILON; + c = 1.0 + aa / c; + if (Math.Abs(c) < Const.QL_EPSILON) + c = Const.QL_EPSILON; + d = 1.0 / d; + del = d * c; + result *= del; + if (Math.Abs(del - 1.0) < accuracy) + return result; + } + Utils.QL_FAIL("a or b too big, or maxIteration too small in betacf"); + return 0; + } + + /*! Incomplete Beta function + + The implementation of the algorithm was inspired by + "Numerical Recipes in C", 2nd edition, + Press, Teukolsky, Vetterling, Flannery, chapter 6 + */ + public static double incompleteBetaFunction(double a, double b, double x) + { + return incompleteBetaFunction(a, b, x, 1e-16, 100); + } + public static double incompleteBetaFunction(double a, double b, double x, double accuracy, int maxIteration) + { + + QL_REQUIRE(a > 0.0, () => "a must be greater than zero"); + QL_REQUIRE(b > 0.0, () => "b must be greater than zero"); + + if (x.IsEqual(0.0)) + return 0.0; + if (x.IsEqual(1.0)) + return 1.0; + QL_REQUIRE(x > 0.0 && x<1.0, () => "x must be in [0,1]"); + + double result = Math.Exp(GammaFunction.logValue(a + b) - + GammaFunction.logValue(a) - GammaFunction.logValue(b) + + a* Math.Log(x) + b* Math.Log(1.0 - x)); + + if (x < (a + 1.0) / (a + b + 2.0)) + return result* + betaContinuedFraction(a, b, x, accuracy, maxIteration) / a; + return 1.0 - result* + betaContinuedFraction(b, a, 1.0 - x, accuracy, maxIteration) / b; + } + } +} diff --git a/src/QLNet/Math/Comparison.cs b/src/QLNet/Math/Comparison.cs index c3cb4461f..805ed13ef 100644 --- a/src/QLNet/Math/Comparison.cs +++ b/src/QLNet/Math/Comparison.cs @@ -6,36 +6,37 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - public static partial class Utils +namespace QLNet +{ + public static partial class Utils { // Follows somewhat the advice of Knuth on checking for floating-point equality. public static bool close(double x, double y) { return close(x, y, 42); } - public static bool close(double x, double y, int n) + public static bool close(double x, double y, int n) { if (x.IsEqual(y)) return true; - double diff = Math.Abs(x-y), tolerance = n * Const.QL_EPSILON; + double diff = Math.Abs(x - y), tolerance = n * Const.QL_EPSILON; if ((x * y).IsEqual(0.0)) // x or y = 0.0 return diff < (tolerance * tolerance); - return diff <= tolerance*Math.Abs(x) && - diff <= tolerance*Math.Abs(y); + return diff <= tolerance * Math.Abs(x) && + diff <= tolerance * Math.Abs(y); } public static bool close(Money m1, Money m2) @@ -45,7 +46,7 @@ public static bool close(Money m1, Money m2) public static bool close_enough(double x, double y) { - return close_enough(x,y,42); + return close_enough(x, y, 42); } public static bool close_enough(double x, double y, int n) @@ -54,37 +55,37 @@ public static bool close_enough(double x, double y, int n) if (x.IsEqual(y)) return true; - double diff = Math.Abs(x-y), tolerance = n * Const.QL_EPSILON; + double diff = Math.Abs(x - y), tolerance = n * Const.QL_EPSILON; if ((x * y).IsEqual(0.0)) // x or y = 0.0 return diff < (tolerance * tolerance); - return diff <= tolerance*Math.Abs(x) || - diff <= tolerance*Math.Abs(y); - } + return diff <= tolerance * Math.Abs(x) || + diff <= tolerance * Math.Abs(y); + } - public static bool close(Money m1, Money m2, int n) - { - if (m1.currency == m2.currency) - { - return close(m1.value, m2.value, n); - } - if (Money.conversionType == Money.ConversionType.BaseCurrencyConversion) - { - Money tmp1 = m1; - Money.convertToBase(ref tmp1); - Money tmp2 = m2; - Money.convertToBase(ref tmp2); - return close(tmp1, tmp2, n); - } - if (Money.conversionType == Money.ConversionType.AutomatedConversion) - { - Money tmp = m2; - Money.convertTo(ref tmp, m1.currency); - return close(m1, tmp, n); - } - Utils.QL_FAIL("currency mismatch and no conversion specified"); - return false; - } - } + public static bool close(Money m1, Money m2, int n) + { + if (m1.currency == m2.currency) + { + return close(m1.value, m2.value, n); + } + if (Money.conversionType == Money.ConversionType.BaseCurrencyConversion) + { + Money tmp1 = m1; + Money.convertToBase(ref tmp1); + Money tmp2 = m2; + Money.convertToBase(ref tmp2); + return close(tmp1, tmp2, n); + } + if (Money.conversionType == Money.ConversionType.AutomatedConversion) + { + Money tmp = m2; + Money.convertTo(ref tmp, m1.currency); + return close(m1, tmp, n); + } + Utils.QL_FAIL("currency mismatch and no conversion specified"); + return false; + } + } } diff --git a/src/QLNet/Math/Distributions/binomialdistribution.cs b/src/QLNet/Math/Distributions/BinomialDistribution.cs similarity index 87% rename from src/QLNet/Math/Distributions/binomialdistribution.cs rename to src/QLNet/Math/Distributions/BinomialDistribution.cs index 450585473..60103312f 100644 --- a/src/QLNet/Math/Distributions/binomialdistribution.cs +++ b/src/QLNet/Math/Distributions/BinomialDistribution.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -46,8 +46,8 @@ public BinomialDistribution(double p, int n) } else { - Utils.QL_REQUIRE(p > 0,()=> "negative p not allowed"); - Utils.QL_REQUIRE(p < 1.0,()=> "p>1.0 not allowed"); + Utils.QL_REQUIRE(p > 0, () => "negative p not allowed"); + Utils.QL_REQUIRE(p < 1.0, () => "p>1.0 not allowed"); logP_ = Math.Log(p); logOneMinusP_ = Math.Log(1.0 - p); @@ -85,8 +85,8 @@ public CumulativeBinomialDistribution(double p, int n) n_ = n; p_ = p; - Utils.QL_REQUIRE(p >= 0,()=> "negative p not allowed"); - Utils.QL_REQUIRE(p <= 1.0,()=> "p>1.0 not allowed"); + Utils.QL_REQUIRE(p >= 0, () => "negative p not allowed"); + Utils.QL_REQUIRE(p <= 1.0, () => "p>1.0 not allowed"); } // function @@ -109,7 +109,7 @@ public static partial class Utils public static double PeizerPrattMethod2Inversion(double z, int n) { - QL_REQUIRE(n % 2 == 1,()=> "n must be an odd number: " + n + " not allowed"); + QL_REQUIRE(n % 2 == 1, () => "n must be an odd number: " + n + " not allowed"); double result = (z / (n + 1.0 / 3.0 + 0.1 / (n + 1.0))); result *= result; @@ -120,7 +120,7 @@ public static double PeizerPrattMethod2Inversion(double z, int n) public static double binomialCoefficientLn(int n, int k) { - QL_REQUIRE(n >= k,()=> "n= k, () => "n. - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -53,10 +53,10 @@ public class BivariateCumulativeNormalDistributionDr78 public BivariateCumulativeNormalDistributionDr78(double rho) { rho_ = rho; - rho2_ = rho*rho; + rho2_ = rho * rho; - Utils.QL_REQUIRE(rho>=-1.0, ()=> "rho must be >= -1.0 (" + rho + " not allowed)"); - Utils.QL_REQUIRE(rho<=1.0,()=> "rho must be <= 1.0 (" + rho + " not allowed)"); + Utils.QL_REQUIRE(rho >= -1.0, () => "rho must be >= -1.0 (" + rho + " not allowed)"); + Utils.QL_REQUIRE(rho <= 1.0, () => "rho must be <= 1.0 (" + rho + " not allowed)"); } // function @@ -68,56 +68,56 @@ public double value(double a, double b) double MaxCumNormDistAB = Math.Max(CumNormDistA, CumNormDistB); double MinCumNormDistAB = Math.Min(CumNormDistA, CumNormDistB); - if (1.0-MaxCumNormDistAB<1e-15) + if (1.0 - MaxCumNormDistAB < 1e-15) return MinCumNormDistAB; - if (MinCumNormDistAB<1e-15) + if (MinCumNormDistAB < 1e-15) return MinCumNormDistAB; double a1 = a / Math.Sqrt(2.0 * (1.0 - rho2_)); double b1 = b / Math.Sqrt(2.0 * (1.0 - rho2_)); - double result= -1.0; + double result = -1.0; - if (a<=0.0 && b<=0 && rho_<=0) + if (a <= 0.0 && b <= 0 && rho_ <= 0) { - double sum=0.0; - for (int i=0; i<5; i++) + double sum = 0.0; + for (int i = 0; i < 5; i++) { - for (int j=0;j<5; j++) + for (int j = 0; j < 5; j++) { - sum += x_[i]*x_[j]* Math.Exp(a1*(2.0*y_[i]-a1)+b1*(2.0*y_[j]-b1) + 2.0*rho_*(y_[i]-a1)*(y_[j]-b1)); - } + sum += x_[i] * x_[j] * Math.Exp(a1 * (2.0 * y_[i] - a1) + b1 * (2.0 * y_[j] - b1) + 2.0 * rho_ * (y_[i] - a1) * (y_[j] - b1)); + } } - result = Math.Sqrt(1.0 - rho2_)/Const.M_PI*sum; - } - else if (a<=0 && b>=0 && rho_>=0) + result = Math.Sqrt(1.0 - rho2_) / Const.M_PI * sum; + } + else if (a <= 0 && b >= 0 && rho_ >= 0) { BivariateCumulativeNormalDistributionDr78 bivCumNormalDist = new BivariateCumulativeNormalDistributionDr78(-rho_); - result= CumNormDistA - bivCumNormalDist.value(a, -b); - } - else if (a>=0.0 && b<=0.0 && rho_>=0.0) + result = CumNormDistA - bivCumNormalDist.value(a, -b); + } + else if (a >= 0.0 && b <= 0.0 && rho_ >= 0.0) { BivariateCumulativeNormalDistributionDr78 bivCumNormalDist = new BivariateCumulativeNormalDistributionDr78(-rho_); - result= CumNormDistB - bivCumNormalDist.value(-a, b); - } - else if (a>=0.0 && b>=0.0 && rho_<=0.0) + result = CumNormDistB - bivCumNormalDist.value(-a, b); + } + else if (a >= 0.0 && b >= 0.0 && rho_ <= 0.0) { - result= CumNormDistA + CumNormDistB -1.0 + (this.value(-a, -b)); - } - else if (a*b*rho_>0.0) + result = CumNormDistA + CumNormDistB - 1.0 + (this.value(-a, -b)); + } + else if (a * b * rho_ > 0.0) { - double rho1 = (rho_*a-b)*(a>0.0 ? 1.0: -1.0) / Math.Sqrt(a*a-2.0*rho_*a*b+b*b); + double rho1 = (rho_ * a - b) * (a > 0.0 ? 1.0 : -1.0) / Math.Sqrt(a * a - 2.0 * rho_ * a * b + b * b); BivariateCumulativeNormalDistributionDr78 bivCumNormalDist = new BivariateCumulativeNormalDistributionDr78(rho1); - double rho2 = (rho_*b-a)*(b>0.0 ? 1.0: -1.0) / Math.Sqrt(a*a-2.0*rho_*a*b+b*b); + double rho2 = (rho_ * b - a) * (b > 0.0 ? 1.0 : -1.0) / Math.Sqrt(a * a - 2.0 * rho_ * a * b + b * b); BivariateCumulativeNormalDistributionDr78 CBND2 = new BivariateCumulativeNormalDistributionDr78(rho2); - double delta = (1.0-(a>0.0 ? 1.0: -1.0)*(b>0.0 ? 1.0: -1.0))/4.0; + double delta = (1.0 - (a > 0.0 ? 1.0 : -1.0) * (b > 0.0 ? 1.0 : -1.0)) / 4.0; - result= bivCumNormalDist.value(a, 0.0) + CBND2.value(b, 0.0) - delta; - } - else + result = bivCumNormalDist.value(a, 0.0) + CBND2.value(b, 0.0) - delta; + } + else { Utils.QL_FAIL("case not handled"); } @@ -130,15 +130,17 @@ public double value(double a, double b) 0.39233107, 0.21141819, 0.03324666, - 0.00082485334}; - - private static double[] y_ = { 0.10024215, - 0.48281397, - 1.06094980, - 1.77972940, - 2.66976040000}; - -} + 0.00082485334 + }; + + private static double[] y_ = { 0.10024215, + 0.48281397, + 1.06094980, + 1.77972940, + 2.66976040000 + }; + + } //! Cumulative bivariate normal distibution function (West 2004) /*! The implementation derives from the article "Better @@ -162,15 +164,15 @@ code in two regards \test the correctness of the returned value is tested by checking it against known good results. */ - public class BivariateCumulativeNormalDistributionWe04DP + public class BivariateCumulativeNormalDistributionWe04DP { public BivariateCumulativeNormalDistributionWe04DP(double rho) { correlation_ = rho; - Utils.QL_REQUIRE( rho >= -1.0,()=> "rho must be >= -1.0 (" + rho + " not allowed)" ); - Utils.QL_REQUIRE( rho <= 1.0,()=> "rho must be <= 1.0 (" + rho + " not allowed)" ); + Utils.QL_REQUIRE(rho >= -1.0, () => "rho must be >= -1.0 (" + rho + " not allowed)"); + Utils.QL_REQUIRE(rho <= 1.0, () => "rho must be <= 1.0 (" + rho + " not allowed)"); } - + // function public double value(double x, double y) { @@ -190,109 +192,116 @@ to classes eqn3 and eqn6 Change some magic numbers to M_PI */ TabulatedGaussLegendre gaussLegendreQuad = new TabulatedGaussLegendre(20); - if (Math.Abs(correlation_) < 0.3) + if (Math.Abs(correlation_) < 0.3) { gaussLegendreQuad.order(6); - } - else if (Math.Abs(correlation_) < 0.75) + } + else if (Math.Abs(correlation_) < 0.75) { gaussLegendreQuad.order(12); } - double h = -x; - double k = -y; - double hk = h * k; - double BVN = 0.0; + double h = -x; + double k = -y; + double hk = h * k; + double BVN = 0.0; - if (Math.Abs(correlation_) < 0.925) - { + if (Math.Abs(correlation_) < 0.925) + { if (Math.Abs(correlation_) > 0) { - double asr = Math.Asin(correlation_); - eqn3 f = new eqn3(h,k,asr); - BVN = gaussLegendreQuad.value(f.value); - BVN *= asr * (0.25 / Const.M_PI); + double asr = Math.Asin(correlation_); + eqn3 f = new eqn3(h, k, asr); + BVN = gaussLegendreQuad.value(f.value); + BVN *= asr * (0.25 / Const.M_PI); } BVN += cumnorm_.value(-h) * cumnorm_.value(-k); - } - else - { + } + else + { if (correlation_ < 0) { - k *= -1; - hk *= -1; + k *= -1; + hk *= -1; } if (Math.Abs(correlation_) < 1) { - double Ass = (1 - correlation_) * (1 + correlation_); - double a = Math.Sqrt(Ass); - double bs = (h-k)*(h-k); - double c = (4 - hk) / 8; - double d = (12 - hk) / 16; - double asr = -(bs / Ass + hk) / 2; - if (asr > -100) - { - BVN = a * Math.Exp(asr) * + double Ass = (1 - correlation_) * (1 + correlation_); + double a = Math.Sqrt(Ass); + double bs = (h - k) * (h - k); + double c = (4 - hk) / 8; + double d = (12 - hk) / 16; + double asr = -(bs / Ass + hk) / 2; + if (asr > -100) + { + BVN = a * Math.Exp(asr) * (1 - c * (bs - Ass) * (1 - d * bs / 5) / 3 + c * d * Ass * Ass / 5); - } - if (-hk < 100) - { - double B = Math.Sqrt(bs); - BVN -= Math.Exp(-hk / 2) * 2.506628274631 * - cumnorm_.value(-B / a) * B * - (1 - c * bs * (1 - d * bs / 5) / 3); - } - a /= 2; - eqn6 f = new eqn6(a,c,d,bs,hk); - BVN += gaussLegendreQuad.value(f.value); - BVN /= (-2.0 * Const.M_PI); + } + if (-hk < 100) + { + double B = Math.Sqrt(bs); + BVN -= Math.Exp(-hk / 2) * 2.506628274631 * + cumnorm_.value(-B / a) * B * + (1 - c * bs * (1 - d * bs / 5) / 3); + } + a /= 2; + eqn6 f = new eqn6(a, c, d, bs, hk); + BVN += gaussLegendreQuad.value(f.value); + BVN /= (-2.0 * Const.M_PI); } - if (correlation_ > 0) { - BVN += cumnorm_.value(-Math.Max(h, k)); - } else { - BVN *= -1; - if (k > h) { - // evaluate cumnorm where it is most precise, that - // is in the lower tail because of double accuracy - // around 0.0 vs around 1.0 - if (h >= 0) { - BVN += cumnorm_.value(-h) - cumnorm_.value(-k); - } else { - BVN += cumnorm_.value(k) - cumnorm_.value(h); - } - } + if (correlation_ > 0) + { + BVN += cumnorm_.value(-Math.Max(h, k)); + } + else + { + BVN *= -1; + if (k > h) + { + // evaluate cumnorm where it is most precise, that + // is in the lower tail because of double accuracy + // around 0.0 vs around 1.0 + if (h >= 0) + { + BVN += cumnorm_.value(-h) - cumnorm_.value(-k); + } + else + { + BVN += cumnorm_.value(k) - cumnorm_.value(h); + } + } } - } - return BVN; + } + return BVN; } private double correlation_; private CumulativeNormalDistribution cumnorm_ = new CumulativeNormalDistribution(); } - public class eqn3 - { + public class eqn3 + { /* Relates to eqn3 Genz 2004 */ - public eqn3(double h, double k, double asr) + public eqn3(double h, double k, double asr) { hk_ = h * k; hs_ = (h * h + k * k) / 2; asr_ = asr; } - public double value(double x) + public double value(double x) { double sn = Math.Sin(asr_ * (-x + 1) * 0.5); return Math.Exp((sn * hk_ - hs_) / (1.0 - sn * sn)); } - + private double hk_, asr_, hs_; - + } - public class eqn6 - { + public class eqn6 + { /* Relates to eqn6 Genz 2004 */ public eqn6(double a, double c, double d, double bs, double hk) { @@ -302,28 +311,28 @@ public eqn6(double a, double c, double d, double bs, double hk) bs_ = bs; hk_ = hk; } - - public double value(double x) + + public double value(double x) { double xs = a_ * (-x + 1); - xs = Math.Abs(xs*xs); + xs = Math.Abs(xs * xs); double rs = Math.Sqrt(1 - xs); double asr = -(bs_ / xs + hk_) / 2; - if (asr > -100.0) + if (asr > -100.0) { return (a_ * Math.Exp(asr) * - (Math.Exp(-hk_ * (1 - rs) / (2 * (1 + rs))) / rs - + (Math.Exp(-hk_ * (1 - rs) / (2 * (1 + rs))) / rs - (1 + c_ * xs * (1 + d_ * xs)))); - } - else + } + else { return 0.0; } - + } - + private double a_, c_, d_, bs_, hk_; - + } diff --git a/src/QLNet/Math/Distributions/chisquaredistribution.cs b/src/QLNet/Math/Distributions/ChiSquareDistribution.cs similarity index 95% rename from src/QLNet/Math/Distributions/chisquaredistribution.cs rename to src/QLNet/Math/Distributions/ChiSquareDistribution.cs index 6f1ce5041..348e33f77 100644 --- a/src/QLNet/Math/Distributions/chisquaredistribution.cs +++ b/src/QLNet/Math/Distributions/ChiSquareDistribution.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -125,8 +125,8 @@ public class InverseNonCentralChiSquareDistribution private double accuracy_; public InverseNonCentralChiSquareDistribution(double df, double ncp, - int maxEvaluations, - double accuracy) + int maxEvaluations, + double accuracy) { nonCentralDist_ = new NonCentralChiSquareDistribution(df, ncp); guess_ = df + ncp; diff --git a/src/QLNet/Math/Distributions/GammaDistribution.cs b/src/QLNet/Math/Distributions/GammaDistribution.cs index 049fa2ce0..341238ce5 100644 --- a/src/QLNet/Math/Distributions/GammaDistribution.cs +++ b/src/QLNet/Math/Distributions/GammaDistribution.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,19 +20,20 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class GammaDistribution + public class GammaDistribution { private double a_; public GammaDistribution(double a) { a_ = a; - Utils.QL_REQUIRE(a > 0.0,()=> "invalid parameter for gamma distribution"); + Utils.QL_REQUIRE(a > 0.0, () => "invalid parameter for gamma distribution"); } public double value(double x) { - if (x <= 0.0) return 0.0; + if (x <= 0.0) + return 0.0; double gln = GammaFunction.logValue(a_); @@ -61,9 +62,11 @@ public double value(double x) double an = -1.0 * n * (n - a_); b += 2.0; d = an * d + b; - if (Math.Abs(d) < Const.QL_EPSILON) d = Const.QL_EPSILON; + if (Math.Abs(d) < Const.QL_EPSILON) + d = Const.QL_EPSILON; c = b + an / c; - if (Math.Abs(c) < Const.QL_EPSILON) c = Const.QL_EPSILON; + if (Math.Abs(c) < Const.QL_EPSILON) + c = Const.QL_EPSILON; d = 1.0 / d; double del = d * c; h *= del; @@ -101,7 +104,7 @@ public static class GammaFunction public static double logValue(double x) { - Utils.QL_REQUIRE(x > 0.0,()=> "positive argument required"); + Utils.QL_REQUIRE(x > 0.0, () => "positive argument required"); double temp = x + 5.5; temp -= (x + 0.5) * Math.Log(temp); diff --git a/src/QLNet/Math/Distributions/NormalDistribution.cs b/src/QLNet/Math/Distributions/NormalDistribution.cs index d7c4b3136..2daafd3b8 100644 --- a/src/QLNet/Math/Distributions/NormalDistribution.cs +++ b/src/QLNet/Math/Distributions/NormalDistribution.cs @@ -1,527 +1,567 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - //! Normal distribution function - /*! Given x, it returns its probability in a Gaussian normal distribution. - It provides the first derivative too. - - \test the correctness of the returned value is tested by - checking it against numerical calculations. Cross-checks - are also performed against the - CumulativeNormalDistribution and InverseCumulativeNormal - classes. - */ - public class NormalDistribution : IValue { - private double average_, sigma_, normalizationFactor_, denominator_, derNormalizationFactor_; - - public NormalDistribution() : this(0.0, 1.0) { } - public NormalDistribution(double average, double sigma) { - average_ = average; - sigma_ = sigma; - - Utils.QL_REQUIRE(sigma_>0.0,()=> "sigma must be greater than 0.0 (" + sigma_ + " not allowed)"); - - normalizationFactor_ = Const.M_SQRT_2*Const.M_1_SQRTPI/sigma_; - derNormalizationFactor_ = sigma_*sigma_; - denominator_ = 2.0*derNormalizationFactor_; - } - - // function - public double value(double x) { - double deltax = x-average_; - double exponent = -(deltax*deltax)/denominator_; - // debian alpha had some strange problem in the very-low range - return exponent <= -690.0 ? 0.0 : // exp(x) < 1.0e-300 anyway - normalizationFactor_*Math.Exp(exponent); - } - - public double derivative(double x) { - return (value(x) * (average_ - x)) / derNormalizationFactor_; - } - } - - - //! Cumulative normal distribution function - /*! Given x it provides an approximation to the - integral of the gaussian normal distribution: - formula here ... - - For this implementation see M. Abramowitz and I. Stegun, - Handbook of Mathematical Functions, - Dover Publications, New York (1972) - */ - public class CumulativeNormalDistribution : IValue { - private double average_, sigma_; - private NormalDistribution gaussian_ = new NormalDistribution(); - - public CumulativeNormalDistribution() : this(0.0, 1.0) { } - public CumulativeNormalDistribution(double average, double sigma) { - average_ = average; - sigma_ = sigma; - - Utils.QL_REQUIRE(sigma_>0.0,()=> "sigma must be greater than 0.0 (" + sigma_ + " not allowed)"); - } - - // function - public double value(double z) { - z = (z - average_) / sigma_; - - double result = 0.5 * (1.0 + erf(z * Const.M_SQRT_2)); - if (result <= 1e-8) { //todo: investigate the threshold level - // Asymptotic expansion for very negative z following (26.2.12) - // on page 408 in M. Abramowitz and A. Stegun, - // Pocketbook of Mathematical Functions, ISBN 3-87144818-4. - double sum = 1.0, zsqr = z * z, i = 1.0, g = 1.0, x, y, - a = double.MaxValue, lasta; - do { - lasta = a; - x = (4.0 * i - 3.0) / zsqr; - y = x * ((4.0 * i - 1) / zsqr); - a = g * (x - y); - sum -= a; - g *= y; - ++i; - a = Math.Abs(a); - } while (lasta > a && a >= Math.Abs(sum * Const.QL_EPSILON)); - result = -gaussian_.value(z) / z * sum; - } - return result; - } - - public double derivative(double x) { - double xn = (x - average_) / sigma_; - return gaussian_.value(xn) / sigma_; - } - - #region Sun Microsystems method - /* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - - /* double erf(double x) - * double erfc(double x) - * x - * 2 |\ - * erf(x) = --------- | exp(-t*t)dt - * sqrt(pi) \| - * 0 - * - * erfc(x) = 1-erf(x) - * Note that - * erf(-x) = -erf(x) - * erfc(-x) = 2 - erfc(x) - * - * Method: - * 1. For |x| in [0, 0.84375] - * erf(x) = x + x*R(x^2) - * erfc(x) = 1 - erf(x) if x in [-.84375,0.25] - * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375] - * where R = P/Q where P is an odd poly of degree 8 and - * Q is an odd poly of degree 10. - * -57.90 - * | R - (erf(x)-x)/x | <= 2 - * - * - * Remark. The formula is derived by noting - * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....) - * and that - * 2/sqrt(pi) = 1.128379167095512573896158903121545171688 - * is close to one. The interval is chosen because the fix - * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is - * near 0.6174), and by some experiment, 0.84375 is chosen to - * guarantee the error is less than one ulp for erf. - * - * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and - * c = 0.84506291151 rounded to single (24 bits) - * erf(x) = sign(x) * (c + P1(s)/Q1(s)) - * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0 - * 1+(c+P1(s)/Q1(s)) if x < 0 - * |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06 - * Remark: here we use the taylor series expansion at x=1. - * erf(1+s) = erf(1) + s*Poly(s) - * = 0.845.. + P1(s)/Q1(s) - * That is, we use rational approximation to approximate - * erf(1+s) - (c = (single)0.84506291151) - * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25] - * where - * P1(s) = degree 6 poly in s - * Q1(s) = degree 6 poly in s - * - * 3. For x in [1.25,1/0.35(~2.857143)], - * erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1) - * erf(x) = 1 - erfc(x) - * where - * R1(z) = degree 7 poly in z, (z=1/x^2) - * S1(z) = degree 8 poly in z - * - * 4. For x in [1/0.35,28] - * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0 - * = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6 x >= 28 - * erf(x) = sign(x) *(1 - tiny) (raise inexact) - * erfc(x) = tiny*tiny (raise underflow) if x > 0 - * = 2 - tiny if x<0 - * - * 7. Special case: - * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1, - * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2, - * erfc/erf(NaN) is NaN - */ - - const double tiny = Const.QL_EPSILON, - one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ - /* c = (float)0.84506291151 */ - erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */ - // - // Coefficients for approximation to erf on [0,0.84375] - // - efx = 1.28379167095512586316e-01, /* 0x3FC06EBA, 0x8214DB69 */ - efx8 = 1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */ - pp0 = 1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */ - pp1 = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */ - pp2 = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */ - pp3 = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */ - pp4 = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */ - qq1 = 3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */ - qq2 = 6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */ - qq3 = 5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */ - qq4 = 1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */ - qq5 = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */ - // - // Coefficients for approximation to erf in [0.84375,1.25] - // - pa0 = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */ - pa1 = 4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */ - pa2 = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */ - pa3 = 3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */ - pa4 = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */ - pa5 = 3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */ - pa6 = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */ - qa1 = 1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */ - qa2 = 5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */ - qa3 = 7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */ - qa4 = 1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */ - qa5 = 1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */ - qa6 = 1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */ - // - // Coefficients for approximation to erfc in [1.25,1/0.35] - // - ra0 = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */ - ra1 = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */ - ra2 = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */ - ra3 = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */ - ra4 = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */ - ra5 = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */ - ra6 = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */ - ra7 = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */ - sa1 = 1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */ - sa2 = 1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */ - sa3 = 4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */ - sa4 = 6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */ - sa5 = 4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */ - sa6 = 1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */ - sa7 = 6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */ - sa8 = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */ - // - // Coefficients for approximation to erfc in [1/.35,28] - // - rb0 = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */ - rb1 = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */ - rb2 = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */ - rb3 = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */ - rb4 = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */ - rb5 = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */ - rb6 = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */ - sb1 = 3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */ - sb2 = 3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */ - sb3 = 1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */ - sb4 = 3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */ - sb5 = 2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */ - sb6 = 4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */ - sb7 = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */ - - private double erf(double x) { - double R,S,P,Q,s,y,z,r, ax; - - ax = Math.Abs(x); - - if(ax < 0.84375) { /* |x|<0.84375 */ - if(ax < 3.7252902984e-09) { /* |x|<2**-28 */ - if (ax < double.MinValue * 16) - return 0.125*(8.0*x+efx8*x); /*avoid underflow */ - return x + efx*x; - } - z = x*x; - r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); - s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); - y = r/s; - return x + x*y; - } - if(ax <1.25) { /* 0.84375 <= |x| < 1.25 */ - s = ax-one; - P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); - Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); - if(x>=0) return erx + P/Q; else return -erx - P/Q; - } - if (ax >= 6) { /* inf>|x|>=6 */ - if(x>=0) return one-tiny; else return tiny-one; +namespace QLNet +{ + //! Normal distribution function + /*! Given x, it returns its probability in a Gaussian normal distribution. + It provides the first derivative too. + + \test the correctness of the returned value is tested by + checking it against numerical calculations. Cross-checks + are also performed against the + CumulativeNormalDistribution and InverseCumulativeNormal + classes. + */ + public class NormalDistribution : IValue + { + private double average_, sigma_, normalizationFactor_, denominator_, derNormalizationFactor_; + + public NormalDistribution() : this(0.0, 1.0) { } + public NormalDistribution(double average, double sigma) + { + average_ = average; + sigma_ = sigma; + + Utils.QL_REQUIRE(sigma_ > 0.0, () => "sigma must be greater than 0.0 (" + sigma_ + " not allowed)"); + + normalizationFactor_ = Const.M_SQRT_2 * Const.M_1_SQRTPI / sigma_; + derNormalizationFactor_ = sigma_ * sigma_; + denominator_ = 2.0 * derNormalizationFactor_; + } + + // function + public double value(double x) + { + double deltax = x - average_; + double exponent = -(deltax * deltax) / denominator_; + // debian alpha had some strange problem in the very-low range + return exponent <= -690.0 ? 0.0 : // exp(x) < 1.0e-300 anyway + normalizationFactor_ * Math.Exp(exponent); + } + + public double derivative(double x) + { + return (value(x) * (average_ - x)) / derNormalizationFactor_; + } + } + + + //! Cumulative normal distribution function + /*! Given x it provides an approximation to the + integral of the gaussian normal distribution: + formula here ... + + For this implementation see M. Abramowitz and I. Stegun, + Handbook of Mathematical Functions, + Dover Publications, New York (1972) + */ + public class CumulativeNormalDistribution : IValue + { + private double average_, sigma_; + private NormalDistribution gaussian_ = new NormalDistribution(); + + public CumulativeNormalDistribution() : this(0.0, 1.0) { } + public CumulativeNormalDistribution(double average, double sigma) + { + average_ = average; + sigma_ = sigma; + + Utils.QL_REQUIRE(sigma_ > 0.0, () => "sigma must be greater than 0.0 (" + sigma_ + " not allowed)"); + } + + // function + public double value(double z) + { + z = (z - average_) / sigma_; + + double result = 0.5 * (1.0 + erf(z * Const.M_SQRT_2)); + if (result <= 1e-8) //todo: investigate the threshold level + { + // Asymptotic expansion for very negative z following (26.2.12) + // on page 408 in M. Abramowitz and A. Stegun, + // Pocketbook of Mathematical Functions, ISBN 3-87144818-4. + double sum = 1.0, zsqr = z * z, i = 1.0, g = 1.0, x, y, + a = double.MaxValue, lasta; + do + { + lasta = a; + x = (4.0 * i - 3.0) / zsqr; + y = x * ((4.0 * i - 1) / zsqr); + a = g * (x - y); + sum -= a; + g *= y; + ++i; + a = Math.Abs(a); } - - /* Starts to lose accuracy when ax~5 */ - s = one/(ax*ax); - - if(ax < 2.85714285714285) { /* |x| < 1/0.35 */ - R = ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(ra5+s*(ra6+s*ra7)))))); - S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(sa5+s*(sa6+s*(sa7+s*sa8))))))); - } else { /* |x| >= 1/0.35 */ - R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+s*rb6))))); - S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(sb5+s*(sb6+s*sb7)))))); + while (lasta > a && a >= Math.Abs(sum * Const.QL_EPSILON)); + result = -gaussian_.value(z) / z * sum; + } + return result; + } + + public double derivative(double x) + { + double xn = (x - average_) / sigma_; + return gaussian_.value(xn) / sigma_; + } + + #region Sun Microsystems method + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + + /* double erf(double x) + * double erfc(double x) + * x + * 2 |\ + * erf(x) = --------- | exp(-t*t)dt + * sqrt(pi) \| + * 0 + * + * erfc(x) = 1-erf(x) + * Note that + * erf(-x) = -erf(x) + * erfc(-x) = 2 - erfc(x) + * + * Method: + * 1. For |x| in [0, 0.84375] + * erf(x) = x + x*R(x^2) + * erfc(x) = 1 - erf(x) if x in [-.84375,0.25] + * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375] + * where R = P/Q where P is an odd poly of degree 8 and + * Q is an odd poly of degree 10. + * -57.90 + * | R - (erf(x)-x)/x | <= 2 + * + * + * Remark. The formula is derived by noting + * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....) + * and that + * 2/sqrt(pi) = 1.128379167095512573896158903121545171688 + * is close to one. The interval is chosen because the fix + * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is + * near 0.6174), and by some experiment, 0.84375 is chosen to + * guarantee the error is less than one ulp for erf. + * + * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and + * c = 0.84506291151 rounded to single (24 bits) + * erf(x) = sign(x) * (c + P1(s)/Q1(s)) + * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0 + * 1+(c+P1(s)/Q1(s)) if x < 0 + * |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06 + * Remark: here we use the taylor series expansion at x=1. + * erf(1+s) = erf(1) + s*Poly(s) + * = 0.845.. + P1(s)/Q1(s) + * That is, we use rational approximation to approximate + * erf(1+s) - (c = (single)0.84506291151) + * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25] + * where + * P1(s) = degree 6 poly in s + * Q1(s) = degree 6 poly in s + * + * 3. For x in [1.25,1/0.35(~2.857143)], + * erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1) + * erf(x) = 1 - erfc(x) + * where + * R1(z) = degree 7 poly in z, (z=1/x^2) + * S1(z) = degree 8 poly in z + * + * 4. For x in [1/0.35,28] + * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0 + * = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6 x >= 28 + * erf(x) = sign(x) *(1 - tiny) (raise inexact) + * erfc(x) = tiny*tiny (raise underflow) if x > 0 + * = 2 - tiny if x<0 + * + * 7. Special case: + * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1, + * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2, + * erfc/erf(NaN) is NaN + */ + + const double tiny = Const.QL_EPSILON, + one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ + /* c = (float)0.84506291151 */ + erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */ + // + // Coefficients for approximation to erf on [0,0.84375] + // + efx = 1.28379167095512586316e-01, /* 0x3FC06EBA, 0x8214DB69 */ + efx8 = 1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */ + pp0 = 1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */ + pp1 = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */ + pp2 = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */ + pp3 = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */ + pp4 = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */ + qq1 = 3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */ + qq2 = 6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */ + qq3 = 5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */ + qq4 = 1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */ + qq5 = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */ + // + // Coefficients for approximation to erf in [0.84375,1.25] + // + pa0 = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */ + pa1 = 4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */ + pa2 = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */ + pa3 = 3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */ + pa4 = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */ + pa5 = 3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */ + pa6 = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */ + qa1 = 1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */ + qa2 = 5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */ + qa3 = 7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */ + qa4 = 1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */ + qa5 = 1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */ + qa6 = 1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */ + // + // Coefficients for approximation to erfc in [1.25,1/0.35] + // + ra0 = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */ + ra1 = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */ + ra2 = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */ + ra3 = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */ + ra4 = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */ + ra5 = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */ + ra6 = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */ + ra7 = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */ + sa1 = 1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */ + sa2 = 1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */ + sa3 = 4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */ + sa4 = 6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */ + sa5 = 4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */ + sa6 = 1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */ + sa7 = 6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */ + sa8 = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */ + // + // Coefficients for approximation to erfc in [1/.35,28] + // + rb0 = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */ + rb1 = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */ + rb2 = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */ + rb3 = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */ + rb4 = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */ + rb5 = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */ + rb6 = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */ + sb1 = 3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */ + sb2 = 3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */ + sb3 = 1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */ + sb4 = 3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */ + sb5 = 2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */ + sb6 = 4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */ + sb7 = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */ + + private double erf(double x) + { + double R, S, P, Q, s, y, z, r, ax; + + ax = Math.Abs(x); + + if (ax < 0.84375) /* |x|<0.84375 */ + { + if (ax < 3.7252902984e-09) /* |x|<2**-28 */ + { + if (ax < double.MinValue * 16) + return 0.125 * (8.0 * x + efx8 * x); /*avoid underflow */ + return x + efx * x; } - r = Math.Exp( -ax*ax-0.5625 +R/S); - if(x>=0) return one-r/ax; else return r/ax-one; - } - #endregion - } - - - //! Inverse cumulative normal distribution function - /*! Given x between zero and one as - the integral value of a gaussian normal distribution - this class provides the value y such that - formula here ... - - It use Acklam's approximation: - by Peter J. Acklam, University of Oslo, Statistics Division. - URL: http://home.online.no/~pjacklam/notes/invnorm/index.html - - This class can also be used to generate a gaussian normal - distribution from a uniform distribution. - This is especially useful when a gaussian normal distribution - is generated from a low discrepancy uniform distribution: - in this case the traditional Box-Muller approach and its - variants would not preserve the sequence's low-discrepancy. - - */ - public class InverseCumulativeNormal : IValue { - double average_, sigma_; - - // Coefficients for the rational approximation. - const double a1_ = -3.969683028665376e+01; - const double a2_ = 2.209460984245205e+02; - const double a3_ = -2.759285104469687e+02; - const double a4_ = 1.383577518672690e+02; - const double a5_ = -3.066479806614716e+01; - const double a6_ = 2.506628277459239e+00; - - const double b1_ = -5.447609879822406e+01; - const double b2_ = 1.615858368580409e+02; - const double b3_ = -1.556989798598866e+02; - const double b4_ = 6.680131188771972e+01; - const double b5_ = -1.328068155288572e+01; - - const double c1_ = -7.784894002430293e-03; - const double c2_ = -3.223964580411365e-01; - const double c3_ = -2.400758277161838e+00; - const double c4_ = -2.549732539343734e+00; - const double c5_ = 4.374664141464968e+00; - const double c6_ = 2.938163982698783e+00; - - const double d1_ = 7.784695709041462e-03; - const double d2_ = 3.224671290700398e-01; - const double d3_ = 2.445134137142996e+00; - const double d4_ = 3.754408661907416e+00; - - // Limits of the approximation regions - const double x_low_ = 0.02425; - const double x_high_= 1.0 - x_low_; - - - public InverseCumulativeNormal() : this(0.0, 1.0) { } - public InverseCumulativeNormal(double average, double sigma) { - average_ = average; - sigma_ = sigma; - - Utils.QL_REQUIRE(sigma_>0.0,()=> "sigma must be greater than 0.0 (" + sigma_ + " not allowed)"); - } - - // function - public double value(double x) { - if (x < 0.0 || x > 1.0) { - // try to recover if due to numerical error - if (Utils.close_enough(x, 1.0)) { - x = 1.0; - } else if (Math.Abs(x) < Const.QL_EPSILON) { - x = 0.0; - } else { - Utils.QL_FAIL("InverseCumulativeNormal(" + x + ") undefined: must be 0 < x < 1"); - } + z = x * x; + r = pp0 + z * (pp1 + z * (pp2 + z * (pp3 + z * pp4))); + s = one + z * (qq1 + z * (qq2 + z * (qq3 + z * (qq4 + z * qq5)))); + y = r / s; + return x + x * y; + } + if (ax < 1.25) /* 0.84375 <= |x| < 1.25 */ + { + s = ax - one; + P = pa0 + s * (pa1 + s * (pa2 + s * (pa3 + s * (pa4 + s * (pa5 + s * pa6))))); + Q = one + s * (qa1 + s * (qa2 + s * (qa3 + s * (qa4 + s * (qa5 + s * qa6))))); + if (x >= 0) return erx + P / Q; else return -erx - P / Q; + } + if (ax >= 6) /* inf>|x|>=6 */ + { + if (x >= 0) return one - tiny; else return tiny - one; + } + + /* Starts to lose accuracy when ax~5 */ + s = one / (ax * ax); + + if (ax < 2.85714285714285) /* |x| < 1/0.35 */ + { + R = ra0 + s * (ra1 + s * (ra2 + s * (ra3 + s * (ra4 + s * (ra5 + s * (ra6 + s * ra7)))))); + S = one + s * (sa1 + s * (sa2 + s * (sa3 + s * (sa4 + s * (sa5 + s * (sa6 + s * (sa7 + s * sa8))))))); + } + else /* |x| >= 1/0.35 */ + { + R = rb0 + s * (rb1 + s * (rb2 + s * (rb3 + s * (rb4 + s * (rb5 + s * rb6))))); + S = one + s * (sb1 + s * (sb2 + s * (sb3 + s * (sb4 + s * (sb5 + s * (sb6 + s * sb7)))))); + } + r = Math.Exp(-ax * ax - 0.5625 + R / S); + if (x >= 0) return one - r / ax; else return r / ax - one; + } + #endregion + } + + + //! Inverse cumulative normal distribution function + /*! Given x between zero and one as + the integral value of a gaussian normal distribution + this class provides the value y such that + formula here ... + + It use Acklam's approximation: + by Peter J. Acklam, University of Oslo, Statistics Division. + URL: http://home.online.no/~pjacklam/notes/invnorm/index.html + + This class can also be used to generate a gaussian normal + distribution from a uniform distribution. + This is especially useful when a gaussian normal distribution + is generated from a low discrepancy uniform distribution: + in this case the traditional Box-Muller approach and its + variants would not preserve the sequence's low-discrepancy. + + */ + public class InverseCumulativeNormal : IValue + { + double average_, sigma_; + + // Coefficients for the rational approximation. + const double a1_ = -3.969683028665376e+01; + const double a2_ = 2.209460984245205e+02; + const double a3_ = -2.759285104469687e+02; + const double a4_ = 1.383577518672690e+02; + const double a5_ = -3.066479806614716e+01; + const double a6_ = 2.506628277459239e+00; + + const double b1_ = -5.447609879822406e+01; + const double b2_ = 1.615858368580409e+02; + const double b3_ = -1.556989798598866e+02; + const double b4_ = 6.680131188771972e+01; + const double b5_ = -1.328068155288572e+01; + + const double c1_ = -7.784894002430293e-03; + const double c2_ = -3.223964580411365e-01; + const double c3_ = -2.400758277161838e+00; + const double c4_ = -2.549732539343734e+00; + const double c5_ = 4.374664141464968e+00; + const double c6_ = 2.938163982698783e+00; + + const double d1_ = 7.784695709041462e-03; + const double d2_ = 3.224671290700398e-01; + const double d3_ = 2.445134137142996e+00; + const double d4_ = 3.754408661907416e+00; + + // Limits of the approximation regions + const double x_low_ = 0.02425; + const double x_high_ = 1.0 - x_low_; + + + public InverseCumulativeNormal() : this(0.0, 1.0) { } + public InverseCumulativeNormal(double average, double sigma) + { + average_ = average; + sigma_ = sigma; + + Utils.QL_REQUIRE(sigma_ > 0.0, () => "sigma must be greater than 0.0 (" + sigma_ + " not allowed)"); + } + + // function + public double value(double x) + { + if (x < 0.0 || x > 1.0) + { + // try to recover if due to numerical error + if (Utils.close_enough(x, 1.0)) + { + x = 1.0; } - - double z, r; - - if (x < x_low_) { - // Rational approximation for the lower region 00.0,()=> "sigma must be greater than 0.0 (" + sigma_ + " not allowed)"); - } - - // function - public double value(double x) { - Utils.QL_REQUIRE(x > 0.0 && x < 1.0,()=> "MoroInverseCumulativeNormal(" + x + ") undefined: must be 0 0.0, () => "sigma must be greater than 0.0 (" + sigma_ + " not allowed)"); + } + + // function + public double value(double x) + { + Utils.QL_REQUIRE(x > 0.0 && x < 1.0, () => "MoroInverseCumulativeNormal(" + x + ") undefined: must be 0. - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -40,8 +40,8 @@ public InverseCumulativePoisson(double lambda) public double value(double x) { - Utils.QL_REQUIRE(x >= 0.0 && x <= 1.0,()=> - "Inverse cumulative Poisson distribution is only defined on the interval [0,1]"); + Utils.QL_REQUIRE(x >= 0.0 && x <= 1.0, () => + "Inverse cumulative Poisson distribution is only defined on the interval [0,1]"); if (x.IsEqual(1.0)) return double.MaxValue; diff --git a/src/QLNet/Math/Factorial.cs b/src/QLNet/Math/Factorial.cs new file mode 100644 index 000000000..db35372c6 --- /dev/null +++ b/src/QLNet/Math/Factorial.cs @@ -0,0 +1,73 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! %Factorial numbers calculator + /*! \test the correctness of the returned value is tested by + checking it against numerical calculations. + */ + public static class Factorial + { + public static double get(uint i) + { + if (i <= tabulated) + { + return firstFactorials[i]; + } + else + { + return Math.Exp(GammaFunction.logValue(i + 1)); + } + } + + public static double ln(int i) + { + if (i <= tabulated) + { + return Math.Log(firstFactorials[i]); + } + else + { + return GammaFunction.logValue(i + 1); + } + } + + static double[] firstFactorials = + { + 1.0, 1.0, + 2.0, 6.0, + 24.0, 120.0, + 720.0, 5040.0, + 40320.0, 362880.0, + 3628800.0, 39916800.0, + 479001600.0, 6227020800.0, + 87178291200.0, 1307674368000.0, + 20922789888000.0, 355687428096000.0, + 6402373705728000.0, 121645100408832000.0, + 2432902008176640000.0, 51090942171709440000.0, + 1124000727777607680000.0, 25852016738884976640000.0, + 620448401733239439360000.0, 15511210043330985984000000.0, + 403291461126605635584000000.0, 10888869450418352160768000000.0 + }; + + static int tabulated = firstFactorials.Length - 1; + } +} diff --git a/src/QLNet/Math/Interpolation.cs b/src/QLNet/Math/Interpolation.cs index 03f7d2241..7c4488497 100644 --- a/src/QLNet/Math/Interpolation.cs +++ b/src/QLNet/Math/Interpolation.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -30,7 +30,7 @@ namespace QLNet // Interpolation factory public interface IInterpolationFactory { - Interpolation interpolate( List xBegin, int size, List yBegin ); + Interpolation interpolate(List xBegin, int size, List yBegin); bool global { get; } int requiredPoints { get; } } @@ -41,22 +41,22 @@ public abstract class Interpolation : Extrapolator, IValue public bool empty() { return impl_ == null; } - public double primitive( double x, bool allowExtrapolation = false ) + public double primitive(double x, bool allowExtrapolation = false) { - checkRange( x, allowExtrapolation ); - return impl_.primitive( x ); + checkRange(x, allowExtrapolation); + return impl_.primitive(x); } - public double derivative( double x, bool allowExtrapolation = false ) + public double derivative(double x, bool allowExtrapolation = false) { - checkRange( x, allowExtrapolation ); - return impl_.derivative( x ); + checkRange(x, allowExtrapolation); + return impl_.derivative(x); } - public double secondDerivative( double x, bool allowExtrapolation = false ) + public double secondDerivative(double x, bool allowExtrapolation = false) { - checkRange( x, allowExtrapolation ); - return impl_.secondDerivative( x ); + checkRange(x, allowExtrapolation); + return impl_.secondDerivative(x); } public double xMin() @@ -67,9 +67,9 @@ public double xMax() { return impl_.xMax(); } - bool isInRange( double x ) + bool isInRange(double x) { - return impl_.isInRange( x ); + return impl_.isInRange(x); } public override void update() { @@ -77,18 +77,18 @@ public override void update() } // main method to derive an interpolated point - public double value( double x ) { return value( x, false ); } - public double value( double x, bool allowExtrapolation ) + public double value(double x) { return value(x, false); } + public double value(double x, bool allowExtrapolation) { - checkRange( x, allowExtrapolation ); - return impl_.value( x ); + checkRange(x, allowExtrapolation); + return impl_.value(x); } - protected void checkRange( double x, bool extrap ) + protected void checkRange(double x, bool extrap) { - if ( !( extrap || allowsExtrapolation() || isInRange( x ) ) ) - throw new ArgumentException( "interpolation range is [" + impl_.xMin() + ", " + impl_.xMax() - + "]: extrapolation at " + x + " not allowed" ); + if (!(extrap || allowsExtrapolation() || isInRange(x))) + throw new ArgumentException("interpolation range is [" + impl_.xMin() + ", " + impl_.xMax() + + "]: extrapolation at " + x + " not allowed"); } @@ -100,10 +100,10 @@ protected interface Impl : IValue double xMax(); List xValues(); List yValues(); - bool isInRange( double d ); - double primitive( double d ); - double derivative( double d ); - double secondDerivative( double d ); + bool isInRange(double d); + double primitive(double d); + double derivative(double d); + double secondDerivative(double d); } public abstract class templateImpl : Impl { @@ -112,46 +112,46 @@ public abstract class templateImpl : Impl protected int size_; // this method should be used for initialisation - protected templateImpl( List xBegin, int size, List yBegin, int requiredPoints = 2 ) + protected templateImpl(List xBegin, int size, List yBegin, int requiredPoints = 2) { xBegin_ = xBegin; yBegin_ = yBegin; size_ = size; - if ( size < requiredPoints ) - throw new ArgumentException( "not enough points to interpolate: at least 2 required, " - + size + " provided" ); + if (size < requiredPoints) + throw new ArgumentException("not enough points to interpolate: at least 2 required, " + + size + " provided"); } public double xMin() { return xBegin_.First(); } public double xMax() { return xBegin_[size_ - 1]; } - public List xValues() { return xBegin_.GetRange( 0, size_ ); } - public List yValues() { return yBegin_.GetRange( 0, size_ ); } + public List xValues() { return xBegin_.GetRange(0, size_); } + public List yValues() { return yBegin_.GetRange(0, size_); } - public bool isInRange( double x ) + public bool isInRange(double x) { double x1 = xMin(), x2 = xMax(); - return ( x >= x1 && x <= x2 ) || Utils.close( x, x1 ) || Utils.close( x, x2 ); + return (x >= x1 && x <= x2) || Utils.close(x, x1) || Utils.close(x, x2); } - protected int locate( double x ) + protected int locate(double x) { - int result = xBegin_.BinarySearch( x ); - if ( result < 0 ) - // The upper_bound() algorithm finds the last position in a sequence that value can occupy + int result = xBegin_.BinarySearch(x); + if (result < 0) + // The upper_bound() algorithm finds the last position in a sequence that value can occupy // without violating the sequence's ordering // if BinarySearch does not find value the value, the index of the next larger item is returned result = ~result - 1; // impose limits. we need the one before last at max or the first at min - result = Math.Max( Math.Min( result, size_ - 2 ), 0 ); + result = Math.Max(Math.Min(result, size_ - 2), 0); return result; } - public abstract double value( double d ); + public abstract double value(double d); public abstract void update(); - public abstract double primitive( double d ); - public abstract double derivative( double d ); - public abstract double secondDerivative( double d ); + public abstract double primitive(double d); + public abstract double derivative(double d); + public abstract double secondDerivative(double d); } } } diff --git a/src/QLNet/Math/Interpolations/Abcdinterpolation.cs b/src/QLNet/Math/Interpolations/Abcdinterpolation.cs index e179a1ac3..85fc28896 100644 --- a/src/QLNet/Math/Interpolations/Abcdinterpolation.cs +++ b/src/QLNet/Math/Interpolations/Abcdinterpolation.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -18,8 +18,8 @@ namespace QLNet { - - public class AbcdCoeffHolder + + public class AbcdCoeffHolder { public AbcdCoeffHolder(double? a, double? b, @@ -30,9 +30,9 @@ public AbcdCoeffHolder(double? a, bool cIsFixed, bool dIsFixed) { - a_ = a; - b_ = b; - c_ = c; + a_ = a; + b_ = b; + c_ = c; d_ = d; aIsFixed_ = false; bIsFixed_ = false; @@ -45,16 +45,20 @@ public AbcdCoeffHolder(double? a, if (a_ != null) aIsFixed_ = aIsFixed; - else a_ = -0.06; + else + a_ = -0.06; if (b_ != null) bIsFixed_ = bIsFixed; - else b_ = 0.17; + else + b_ = 0.17; if (c_ != null) cIsFixed_ = cIsFixed; - else c_ = 0.54; + else + c_ = 0.54; if (d_ != null) dIsFixed_ = dIsFixed; - else d_ = 0.17; + else + d_ = 0.17; AbcdMathFunction.validate(a_.Value, b_.Value, c_.Value, d_.Value); @@ -73,19 +77,19 @@ public AbcdCoeffHolder(double? a, public double? maxError_ { get; set; } public EndCriteria.Type abcdEndCriteria_ { get; set; } } - - public class AbcdInterpolationImpl : Interpolation.templateImpl + + public class AbcdInterpolationImpl : Interpolation.templateImpl { - public AbcdInterpolationImpl( List xBegin, int size, List yBegin, - double a, double b, double c, double d, - bool aIsFixed, - bool bIsFixed, - bool cIsFixed, - bool dIsFixed, - bool vegaWeighted, - EndCriteria endCriteria, - OptimizationMethod optMethod) - : base(xBegin, size, yBegin) + public AbcdInterpolationImpl(List xBegin, int size, List yBegin, + double a, double b, double c, double d, + bool aIsFixed, + bool bIsFixed, + bool cIsFixed, + bool dIsFixed, + bool vegaWeighted, + EndCriteria endCriteria, + OptimizationMethod optMethod) + : base(xBegin, size, yBegin) { abcdCoeffHolder_ = new AbcdCoeffHolder(a, b, c, d, aIsFixed, bIsFixed, cIsFixed, dIsFixed); endCriteria_ = endCriteria; @@ -93,29 +97,29 @@ public AbcdInterpolationImpl( List xBegin, int size, List yBegin vegaWeighted_ = vegaWeighted; } - - public override void update() + + public override void update() { List times = new List(), blackVols = new List(); - for ( int i = 0; i < xBegin_.Count; ++i) + for (int i = 0; i < xBegin_.Count; ++i) { times.Add(xBegin_[i]); blackVols.Add(yBegin_[i]); } - + abcdCalibrator_ = new AbcdCalibration(times, blackVols, - abcdCoeffHolder_.a_.Value, - abcdCoeffHolder_.b_.Value, - abcdCoeffHolder_.c_.Value, + abcdCoeffHolder_.a_.Value, + abcdCoeffHolder_.b_.Value, + abcdCoeffHolder_.c_.Value, abcdCoeffHolder_.d_.Value, - abcdCoeffHolder_.aIsFixed_, + abcdCoeffHolder_.aIsFixed_, abcdCoeffHolder_.bIsFixed_, - abcdCoeffHolder_.cIsFixed_, + abcdCoeffHolder_.cIsFixed_, abcdCoeffHolder_.dIsFixed_, vegaWeighted_, endCriteria_, optMethod_); - + abcdCalibrator_.compute(); abcdCoeffHolder_.a_ = abcdCalibrator_.a(); abcdCoeffHolder_.b_ = abcdCalibrator_.b(); @@ -126,32 +130,32 @@ public override void update() abcdCoeffHolder_.maxError_ = abcdCalibrator_.maxError(); abcdCoeffHolder_.abcdEndCriteria_ = abcdCalibrator_.endCriteria(); } - - public override double value(double x) + + public override double value(double x) { - Utils.QL_REQUIRE(x>=0.0,()=> "time must be non negative: " + x + " not allowed"); + Utils.QL_REQUIRE(x >= 0.0, () => "time must be non negative: " + x + " not allowed"); return abcdCalibrator_.value(x); } - public override double primitive(double x) + public override double primitive(double x) { Utils.QL_FAIL("Abcd primitive not implemented"); return 0; } - - public override double derivative(double x) + + public override double derivative(double x) { Utils.QL_FAIL("Abcd derivative not implemented"); return 0; } - - public override double secondDerivative(double x) + + public override double secondDerivative(double x) { Utils.QL_FAIL("Abcd secondDerivative not implemented"); return 0; } - - public double k(double t) + + public double k(double t) { LinearInterpolation li = new LinearInterpolation(this.xBegin_, this.size_, this.yBegin_); return li.value(t); @@ -165,10 +169,10 @@ public double k(double t) private AbcdCoeffHolder abcdCoeffHolder_; } - + //! %Abcd interpolation between discrete points. /*! \ingroup interpolations */ - public class AbcdInterpolation : Interpolation + public class AbcdInterpolation : Interpolation { /*! Constructor */ public AbcdInterpolation(List xBegin, int size, List yBegin, @@ -182,8 +186,8 @@ public AbcdInterpolation(List xBegin, int size, List yBegin, bool dIsFixed = false, bool vegaWeighted = false, EndCriteria endCriteria = null, - OptimizationMethod optMethod = null) - { + OptimizationMethod optMethod = null) + { impl_ = new AbcdInterpolationImpl(xBegin, size, yBegin, a, b, c, d, aIsFixed, bIsFixed, @@ -193,7 +197,7 @@ public AbcdInterpolation(List xBegin, int size, List yBegin, optMethod); impl_.update(); coeffs_ = ((AbcdInterpolationImpl)impl_).AbcdCoeffHolder(); - } + } // Inspectors public double? a() { return coeffs_.a_; } @@ -203,20 +207,20 @@ public AbcdInterpolation(List xBegin, int size, List yBegin, public List k() { return coeffs_.k_; } public double? rmsError() { return coeffs_.error_; } public double? maxError() { return coeffs_.maxError_; } - public EndCriteria.Type endCriteria(){ return coeffs_.abcdEndCriteria_; } - public double k(double t, List xBegin, int size) + public EndCriteria.Type endCriteria() { return coeffs_.abcdEndCriteria_; } + public double k(double t, List xBegin, int size) { LinearInterpolation li = new LinearInterpolation(xBegin, size, coeffs_.k_); return li.value(t); } private AbcdCoeffHolder coeffs_; - + } //! %Abcd interpolation factory and traits /*! \ingroup interpolations */ - public class Abcd + public class Abcd { public Abcd(double a, double b, double c, double d, bool aIsFixed, bool bIsFixed, @@ -225,31 +229,31 @@ public Abcd(double a, double b, double c, double d, EndCriteria endCriteria = null, OptimizationMethod optMethod = null) { - a_ = a; - b_ = b; - c_ = c; + a_ = a; + b_ = b; + c_ = c; d_ = d; - aIsFixed_ = aIsFixed; + aIsFixed_ = aIsFixed; bIsFixed_ = bIsFixed; - cIsFixed_ = cIsFixed; + cIsFixed_ = cIsFixed; dIsFixed_ = dIsFixed; vegaWeighted_ = vegaWeighted; endCriteria_ = endCriteria; optMethod_ = optMethod; global = true; } - - public Interpolation interpolate(List xBegin, int size,List yBegin) + + public Interpolation interpolate(List xBegin, int size, List yBegin) { - return new AbcdInterpolation(xBegin, size, yBegin, - a_, b_, c_, d_, - aIsFixed_, bIsFixed_, - cIsFixed_, dIsFixed_, - vegaWeighted_, - endCriteria_, optMethod_); + return new AbcdInterpolation(xBegin, size, yBegin, + a_, b_, c_, d_, + aIsFixed_, bIsFixed_, + cIsFixed_, dIsFixed_, + vegaWeighted_, + endCriteria_, optMethod_); } - public bool global { get; set; } + public bool global { get; set; } private double a_, b_, c_, d_; private bool aIsFixed_, bIsFixed_, cIsFixed_, dIsFixed_; diff --git a/src/QLNet/Math/Interpolations/BackwardFlatInterpolation.cs b/src/QLNet/Math/Interpolations/BackwardFlatInterpolation.cs new file mode 100644 index 000000000..2e4da9a61 --- /dev/null +++ b/src/QLNet/Math/Interpolations/BackwardFlatInterpolation.cs @@ -0,0 +1,86 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System.Collections.Generic; + +namespace QLNet +{ + public class BackwardFlatInterpolationImpl : Interpolation.templateImpl + { + private List primitive_; + + public BackwardFlatInterpolationImpl(List xBegin, int size, List yBegin) : base(xBegin, size, yBegin) + { + primitive_ = new InitializedList(size_); + } + + public override void update() + { + primitive_[0] = 0.0; + for (int i = 1; i < size_; i++) + { + double dx = xBegin_[i] - xBegin_[i - 1]; + primitive_[i] = primitive_[i - 1] + dx * yBegin_[i]; + } + } + + public override double value(double x) + { + if (x <= xBegin_[0]) + return yBegin_[0]; + int i = locate(x); + if (x.IsEqual(xBegin_[i])) + return yBegin_[i]; + else + return yBegin_[i + 1]; + } + + public override double primitive(double x) + { + int i = locate(x); + double dx = x - xBegin_[i]; + return primitive_[i] + dx * yBegin_[i + 1]; + } + + public override double derivative(double x) { return 0.0; } + public override double secondDerivative(double x) { return 0.0; } + } + + + //! Backward-flat interpolation between discrete points + public class BackwardFlatInterpolation : Interpolation + { + /*! \pre the \f$ x \f$ values must be sorted. */ + public BackwardFlatInterpolation(List xBegin, int size, List yBegin) + { + impl_ = new BackwardFlatInterpolationImpl(xBegin, size, yBegin); + impl_.update(); + } + } + + //! Backward-flat interpolation factory and traits + public class BackwardFlat : IInterpolationFactory + { + public Interpolation interpolate(List xBegin, int size, List yBegin) + { + return new BackwardFlatInterpolation(xBegin, size, yBegin); + } + public bool global { get { return false; } } + public int requiredPoints { get { return 2; } } + } +} diff --git a/src/QLNet/Math/Interpolations/BackwardflatLinearInterpolation.cs b/src/QLNet/Math/Interpolations/BackwardflatLinearInterpolation.cs index 1f595c429..d23708b09 100644 --- a/src/QLNet/Math/Interpolations/BackwardflatLinearInterpolation.cs +++ b/src/QLNet/Math/Interpolations/BackwardflatLinearInterpolation.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,65 +21,65 @@ namespace QLNet // backflat interpolation in first component, linear in second component public class BackwardflatLinearInterpolationImpl : Interpolation2D.templateImpl { - public BackwardflatLinearInterpolationImpl(List xBegin, int xEnd,List yBegin, int yEnd, - Matrix zData) - : base(xBegin,xEnd,yBegin,yEnd,zData) + public BackwardflatLinearInterpolationImpl(List xBegin, int xEnd, List yBegin, int yEnd, + Matrix zData) + : base(xBegin, xEnd, yBegin, yEnd, zData) { calculate(); } public override void calculate() {} - - public override double value(double x, double y) + + public override double value(double x, double y) { int j = locateY(y); double z1, z2; if (x <= xBegin_[0]) { - z1 = zData_[j,0]; - z2 = zData_[j + 1,0]; + z1 = zData_[j, 0]; + z2 = zData_[j + 1, 0]; } else { int i = locateX(x); if (x.IsEqual(xBegin_[i])) { - z1 = zData_[j,i]; - z2 = zData_[j + 1,i]; + z1 = zData_[j, i]; + z2 = zData_[j + 1, i]; } else { - z1 = zData_[j,i + 1]; - z2 = zData_[j + 1,i + 1]; + z1 = zData_[j, i + 1]; + z2 = zData_[j + 1, i + 1]; } } - double u = (y - yBegin_[j])/ (yBegin_[j + 1] - yBegin_[j]); + double u = (y - yBegin_[j]) / (yBegin_[j + 1] - yBegin_[j]); + + return (1.0 - u) * z1 + u * z2; - return (1.0 - u)*z1 + u*z2; - } - + } - public class BackwardflatLinearInterpolation : Interpolation2D + public class BackwardflatLinearInterpolation : Interpolation2D { /*! \pre the \f$ x \f$ and \f$ y \f$ values must be sorted. */ - public BackwardflatLinearInterpolation(List xBegin, int xEnd,List yBegin, int yEnd,Matrix zData) + public BackwardflatLinearInterpolation(List xBegin, int xEnd, List yBegin, int yEnd, Matrix zData) { - impl_ = new BackwardflatLinearInterpolationImpl(xBegin, xEnd,yBegin, yEnd,zData); + impl_ = new BackwardflatLinearInterpolationImpl(xBegin, xEnd, yBegin, yEnd, zData); } } - public class BackwardflatLinear + public class BackwardflatLinear { - public Interpolation2D interpolate(List xBegin, int xEnd,List yBegin, int yEnd,Matrix z) + public Interpolation2D interpolate(List xBegin, int xEnd, List yBegin, int yEnd, Matrix z) { - return new BackwardflatLinearInterpolation(xBegin,xEnd,yBegin,yEnd,z); + return new BackwardflatLinearInterpolation(xBegin, xEnd, yBegin, yEnd, z); } } - + } diff --git a/src/QLNet/Math/Interpolations/BicubicSplineInterpolation.cs b/src/QLNet/Math/Interpolations/BicubicSplineInterpolation.cs index 19d3f5268..13f6e87c2 100644 --- a/src/QLNet/Math/Interpolations/BicubicSplineInterpolation.cs +++ b/src/QLNet/Math/Interpolations/BicubicSplineInterpolation.cs @@ -6,7 +6,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -23,17 +23,17 @@ namespace QLNet { public interface IBicubicSplineDerivatives { - double derivativeX( double x, double y ); - double derivativeY( double x, double y ); - double derivativeXY( double x, double y ); - double secondDerivativeX( double x, double y ); - double secondDerivativeY( double x, double y ); + double derivativeX(double x, double y); + double derivativeY(double x, double y); + double derivativeXY(double x, double y); + double secondDerivativeX(double x, double y); + double secondDerivativeY(double x, double y); } - public class BicubicSplineImpl : Interpolation2D.templateImpl,IBicubicSplineDerivatives + public class BicubicSplineImpl : Interpolation2D.templateImpl, IBicubicSplineDerivatives { - public BicubicSplineImpl(List xBegin, int size, List yBegin,int ySize,Matrix zData) - : base(xBegin,size, yBegin,ySize,zData) + public BicubicSplineImpl(List xBegin, int size, List yBegin, int ySize, Matrix zData) + : base(xBegin, size, yBegin, ySize, zData) { calculate(); } @@ -41,94 +41,94 @@ public BicubicSplineImpl(List xBegin, int size, List yBegin,int public override void calculate() { splines_ = new List (this.zData_.rows()); - for (int i=0; i<(this.zData_.rows()); ++i) - splines_.Add( new CubicInterpolation( this.xBegin_, this.xSize_, this.zData_.row(i), - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); + for (int i = 0; i < (this.zData_.rows()); ++i) + splines_.Add(new CubicInterpolation(this.xBegin_, this.xSize_, this.zData_.row(i), + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); } public override double value(double x, double y) { - List section = new InitializedList( splines_.Count ); - for (int i=0; i section = new InitializedList(splines_.Count); + for (int i = 0; i < splines_.Count; i++) + section[i] = splines_[i].value(x, true); CubicInterpolation spline = new CubicInterpolation(this.yBegin_, this.ySize_, section, CubicInterpolation.DerivativeApprox.Spline, false, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0); - return spline.value(y,true); + return spline.value(y, true); } public double derivativeX(double x, double y) { List section = new InitializedList(this.zData_.columns()); - for (int i=0; i < section.Count; ++i) + for (int i = 0; i < section.Count; ++i) { section[i] = value(this.xBegin_[i], y); } - return new CubicInterpolation( this.xBegin_, this.xSize_, section, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0).derivative(x); + return new CubicInterpolation(this.xBegin_, this.xSize_, section, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0).derivative(x); } public double secondDerivativeX(double x, double y) { - List section = new InitializedList( this.zData_.columns() ); - for (int i=0; i < section.Count; ++i) + List section = new InitializedList(this.zData_.columns()); + for (int i = 0; i < section.Count; ++i) { section[i] = value(this.xBegin_[i], y); } - return new CubicInterpolation( this.xBegin_, this.xSize_, section, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0).secondDerivative(x); + return new CubicInterpolation(this.xBegin_, this.xSize_, section, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0).secondDerivative(x); } public double derivativeY(double x, double y) { - List section = new InitializedList( splines_.Count ); - for (int i=0; i section = new InitializedList(splines_.Count); + for (int i = 0; i < splines_.Count; i++) + section[i] = splines_[i].value(x, true); + + return new CubicInterpolation(this.yBegin_, this.ySize_, section, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0).derivative(y); } public double secondDerivativeY(double x, double y) { - List section = new InitializedList( splines_.Count ); - for (int i=0; i section = new InitializedList(splines_.Count); + for (int i = 0; i < splines_.Count; i++) + section[i] = splines_[i].value(x, true); + + return new CubicInterpolation(this.yBegin_, this.ySize_, section, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0).secondDerivative(y); } public double derivativeXY(double x, double y) { - List section = new InitializedList( this.zData_.columns() ); - for (int i=0; i < section.Count; ++i) + List section = new InitializedList(this.zData_.columns()); + for (int i = 0; i < section.Count; ++i) { section[i] = derivativeY(this.xBegin_[i], y); } - return new CubicInterpolation( this.xBegin_, this.xSize_, section, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0).derivative(x); + return new CubicInterpolation(this.xBegin_, this.xSize_, section, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0).derivative(x); } @@ -142,39 +142,43 @@ public double derivativeXY(double x, double y) public class BicubicSpline : Interpolation2D { /*! \pre the \f$ x \f$ and \f$ y \f$ values must be sorted. */ - public BicubicSpline( List xBegin, int size, List yBegin,int ySize,Matrix zData) + public BicubicSpline(List xBegin, int size, List yBegin, int ySize, Matrix zData) { impl_ = new BicubicSplineImpl(xBegin, size, yBegin, ySize, zData); } - public double derivativeX(double x, double y) { + public double derivativeX(double x, double y) + { return ((IBicubicSplineDerivatives)impl_).derivativeX(x, y); } - public double derivativeY(double x, double y) { - return ( (IBicubicSplineDerivatives)impl_ ).derivativeY( x, y ); + public double derivativeY(double x, double y) + { + return ((IBicubicSplineDerivatives)impl_).derivativeY(x, y); } - public double secondDerivativeX(double x, double y) { - return ( (IBicubicSplineDerivatives)impl_ ).secondDerivativeX( x, y ); + public double secondDerivativeX(double x, double y) + { + return ((IBicubicSplineDerivatives)impl_).secondDerivativeX(x, y); } - public double secondDerivativeY(double x, double y) { - return ( (IBicubicSplineDerivatives)impl_ ).secondDerivativeY( x, y ); + public double secondDerivativeY(double x, double y) + { + return ((IBicubicSplineDerivatives)impl_).secondDerivativeY(x, y); } - public double derivativeXY( double x, double y ) + public double derivativeXY(double x, double y) { - return ( (IBicubicSplineDerivatives)impl_ ).derivativeXY( x, y ); + return ((IBicubicSplineDerivatives)impl_).derivativeXY(x, y); } } //! bicubic-spline-interpolation factory public class Bicubic : IInterpolationFactory2D - { - public Interpolation2D interpolate(List xBegin, int size, List yBegin,int ySize,Matrix zData) + { + public Interpolation2D interpolate(List xBegin, int size, List yBegin, int ySize, Matrix zData) { - return new BicubicSpline( xBegin, size, yBegin, ySize, zData ); + return new BicubicSpline(xBegin, size, yBegin, ySize, zData); } } diff --git a/src/QLNet/Math/Interpolations/bilinearinterpolation.cs b/src/QLNet/Math/Interpolations/BilinearInterpolation.cs similarity index 78% rename from src/QLNet/Math/Interpolations/bilinearinterpolation.cs rename to src/QLNet/Math/Interpolations/BilinearInterpolation.cs index e36316fda..a5d56b89a 100644 --- a/src/QLNet/Math/Interpolations/bilinearinterpolation.cs +++ b/src/QLNet/Math/Interpolations/BilinearInterpolation.cs @@ -6,7 +6,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -24,8 +24,8 @@ namespace QLNet public class BilinearInterpolationImpl : Interpolation2D.templateImpl { public BilinearInterpolationImpl(List xBegin, int xSize, - List yBegin, int ySize, - Matrix zData) + List yBegin, int ySize, + Matrix zData) : base(xBegin, xSize, yBegin, ySize, zData) { calculate(); @@ -59,12 +59,12 @@ public class BilinearInterpolation : Interpolation2D /*! \pre the \f$ x \f$ and \f$ y \f$ values must be sorted. */ public BilinearInterpolation(List xBegin, int xSize, - List yBegin, int ySize, - Matrix zData) + List yBegin, int ySize, + Matrix zData) { - impl_ = (Interpolation2D.Impl) ( - new BilinearInterpolationImpl(xBegin, xSize, - yBegin, ySize, zData)); + impl_ = (Interpolation2D.Impl)( + new BilinearInterpolationImpl(xBegin, xSize, + yBegin, ySize, zData)); } } @@ -72,8 +72,8 @@ public BilinearInterpolation(List xBegin, int xSize, public class Bilinear : IInterpolationFactory2D { public Interpolation2D interpolate(List xBegin, int xSize, - List yBegin, int ySize, - Matrix zData) + List yBegin, int ySize, + Matrix zData) { return new BilinearInterpolation(xBegin, xSize, yBegin, ySize, zData); } diff --git a/src/QLNet/Math/Interpolations/ConvexMonotoneInterpolation.cs b/src/QLNet/Math/Interpolations/ConvexMonotoneInterpolation.cs new file mode 100644 index 000000000..76f4f35d4 --- /dev/null +++ b/src/QLNet/Math/Interpolations/ConvexMonotoneInterpolation.cs @@ -0,0 +1,859 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QLNet +{ + //the first value in the y-vector is ignored. + + #region Helpers + public interface ISectionHelper + { + double value(double x); + double primitive(double x); + double fNext(); + } + + public class ComboHelper : ISectionHelper + { + private double quadraticity_; + ISectionHelper quadraticHelper_; + ISectionHelper convMonoHelper_; + + public ComboHelper(ISectionHelper quadraticHelper, ISectionHelper convMonoHelper, double quadraticity) + { + quadraticity_ = quadraticity; + quadraticHelper_ = quadraticHelper; + convMonoHelper_ = convMonoHelper; + Utils.QL_REQUIRE(quadraticity < 1.0 && quadraticity > 0.0, () => "Quadratic value must lie between 0 and 1"); + } + + public double value(double x) + { + return (quadraticity_ * quadraticHelper_.value(x) + (1.0 - quadraticity_) * convMonoHelper_.value(x)); + } + public double primitive(double x) + { + return (quadraticity_ * quadraticHelper_.primitive(x) + (1.0 - quadraticity_) * convMonoHelper_.primitive(x)); + } + public double fNext() + { + return (quadraticity_ * quadraticHelper_.fNext() + (1.0 - quadraticity_) * convMonoHelper_.fNext()); + } + } + + public class EverywhereConstantHelper : ISectionHelper + { + private double value_; + private double prevPrimitive_; + private double xPrev_; + + public EverywhereConstantHelper(double value, double prevPrimitive, double xPrev) + { + value_ = value; + prevPrimitive_ = prevPrimitive; + xPrev_ = xPrev; + } + + public double value(double x) { return value_; } + public double primitive(double x) { return prevPrimitive_ + (x - xPrev_) * value_; } + public double fNext() { return value_; } + } + + public class ConvexMonotone2Helper : ISectionHelper + { + private double xPrev_, xScaling_, gPrev_, gNext_, fAverage_, eta2_, prevPrimitive_; + + public ConvexMonotone2Helper(double xPrev, double xNext, double gPrev, double gNext, double fAverage, double eta2, + double prevPrimitive) + { + xPrev_ = xPrev; + xScaling_ = xNext - xPrev; + gPrev_ = gPrev; + gNext_ = gNext; + fAverage_ = fAverage; + eta2_ = eta2; + prevPrimitive_ = prevPrimitive; + } + + public double value(double x) + { + double xVal = (x - xPrev_) / xScaling_; + if (xVal <= eta2_) + { + return (fAverage_ + gPrev_); + } + else + { + return (fAverage_ + gPrev_ + (gNext_ - gPrev_) / ((1 - eta2_) * (1 - eta2_)) * (xVal - eta2_) * (xVal - eta2_)); + } + } + + public double primitive(double x) + { + double xVal = (x - xPrev_) / xScaling_; + if (xVal <= eta2_) + { + return (prevPrimitive_ + xScaling_ * (fAverage_ * xVal + gPrev_ * xVal)); + } + else + { + return (prevPrimitive_ + xScaling_ * (fAverage_ * xVal + gPrev_ * xVal + (gNext_ - gPrev_) / ((1 - eta2_) * (1 - eta2_)) * + (1.0 / 3.0 * (xVal * xVal * xVal - eta2_ * eta2_ * eta2_) - eta2_ * xVal * xVal + eta2_ * eta2_ * xVal))); + } + } + public double fNext() { return (fAverage_ + gNext_); } + } + + public class ConvexMonotone3Helper : ISectionHelper + { + private double xPrev_, xScaling_, gPrev_, gNext_, fAverage_, eta3_, prevPrimitive_; + + public ConvexMonotone3Helper(double xPrev, double xNext, + double gPrev, double gNext, + double fAverage, double eta3, + double prevPrimitive) + { + xPrev_ = xPrev; + xScaling_ = xNext - xPrev; + gPrev_ = gPrev; + gNext_ = gNext; + fAverage_ = fAverage; + eta3_ = eta3; + prevPrimitive_ = prevPrimitive; + } + + public double value(double x) + { + double xVal = (x - xPrev_) / xScaling_; + if (xVal <= eta3_) + { + return (fAverage_ + gNext_ + (gPrev_ - gNext_) / (eta3_ * eta3_) * (eta3_ - xVal) * (eta3_ - xVal)); + } + else + { + return (fAverage_ + gNext_); + } + } + + public double primitive(double x) + { + double xVal = (x - xPrev_) / xScaling_; + if (xVal <= eta3_) + { + return (prevPrimitive_ + xScaling_ * (fAverage_ * xVal + gNext_ * xVal + (gPrev_ - gNext_) / (eta3_ * eta3_) * + (1.0 / 3.0 * xVal * xVal * xVal - eta3_ * xVal * xVal + eta3_ * eta3_ * xVal))); + } + else + { + return (prevPrimitive_ + xScaling_ * (fAverage_ * xVal + gNext_ * xVal + (gPrev_ - gNext_) / (eta3_ * eta3_) * + (1.0 / 3.0 * eta3_ * eta3_ * eta3_))); + } + } + public double fNext() { return (fAverage_ + gNext_); } + } + + public class ConvexMonotone4Helper : ISectionHelper + { + protected double xPrev_, xScaling_, gPrev_, gNext_, fAverage_, eta4_, prevPrimitive_; + protected double A_; + + public ConvexMonotone4Helper(double xPrev, double xNext, double gPrev, double gNext, + double fAverage, double eta4, double prevPrimitive) + { + xPrev_ = xPrev; + xScaling_ = xNext - xPrev; + gPrev_ = gPrev; + gNext_ = gNext; + fAverage_ = fAverage; + eta4_ = eta4; + prevPrimitive_ = prevPrimitive; + A_ = -0.5 * (eta4_ * gPrev_ + (1 - eta4_) * gNext_); + } + + public virtual double value(double x) + { + double xVal = (x - xPrev_) / xScaling_; + if (xVal <= eta4_) + { + return (fAverage_ + A_ + (gPrev_ - A_) * (eta4_ - xVal) * (eta4_ - xVal) / (eta4_ * eta4_)); + } + else + { + return (fAverage_ + A_ + (gNext_ - A_) * (xVal - eta4_) * (xVal - eta4_) / ((1 - eta4_) * (1 - eta4_))); + } + } + + public virtual double primitive(double x) + { + double xVal = (x - xPrev_) / xScaling_; + double retVal; + if (xVal <= eta4_) + { + retVal = prevPrimitive_ + xScaling_ * (fAverage_ + A_ + (gPrev_ - A_) / (eta4_ * eta4_) * + (eta4_ * eta4_ - eta4_ * xVal + 1.0 / 3.0 * xVal * xVal)) * xVal; + } + else + { + retVal = prevPrimitive_ + xScaling_ * (fAverage_ * xVal + A_ * xVal + (gPrev_ - A_) * (1.0 / 3.0 * eta4_) + + (gNext_ - A_) / ((1 - eta4_) * (1 - eta4_)) * + (1.0 / 3.0 * xVal * xVal * xVal - eta4_ * xVal * xVal + eta4_ * eta4_ * xVal - 1.0 / 3.0 * eta4_ * eta4_ * eta4_)); + } + return retVal; + } + public double fNext() { return (fAverage_ + gNext_); } + } + + public class ConvexMonotone4MinHelper : ConvexMonotone4Helper + { + private bool splitRegion_; + private double xRatio_, x2_, x3_; + + public ConvexMonotone4MinHelper(double xPrev, double xNext, double gPrev, double gNext, + double fAverage, double eta4, double prevPrimitive) + : base(xPrev, xNext, gPrev, gNext, fAverage, eta4, prevPrimitive) + { + + splitRegion_ = false; + if (A_ + fAverage_ <= 0.0) + { + splitRegion_ = true; + double fPrev = gPrev_ + fAverage_; + double fNext = gNext_ + fAverage_; + double reqdShift = (eta4_ * fPrev + (1 - eta4_) * fNext) / 3.0 - fAverage_; + double reqdPeriod = reqdShift * xScaling_ / (fAverage_ + reqdShift); + double xAdjust = xScaling_ - reqdPeriod; + xRatio_ = xAdjust / xScaling_; + + fAverage_ += reqdShift; + gNext_ = fNext - fAverage_; + gPrev_ = fPrev - fAverage_; + A_ = -(eta4_ * gPrev_ + (1.0 - eta4) * gNext_) / 2.0; + x2_ = xPrev_ + xAdjust * eta4_; + x3_ = xPrev_ + xScaling_ - xAdjust * (1.0 - eta4_); + } + } + + public override double value(double x) + { + if (!splitRegion_) + return base.value(x); + + double xVal = (x - xPrev_) / xScaling_; + if (x <= x2_) + { + xVal /= xRatio_; + return (fAverage_ + A_ + (gPrev_ - A_) * (eta4_ - xVal) * (eta4_ - xVal) / (eta4_ * eta4_)); + } + else if (x < x3_) + { + return 0.0; + } + else + { + xVal = 1.0 - (1.0 - xVal) / xRatio_; + return (fAverage_ + A_ + (gNext_ - A_) * (xVal - eta4_) * (xVal - eta4_) / ((1 - eta4_) * (1 - eta4_))); + } + } + + public override double primitive(double x) + { + if (!splitRegion_) + return base.primitive(x); + + double xVal = (x - xPrev_) / xScaling_; + if (x <= x2_) + { + xVal /= xRatio_; + return (prevPrimitive_ + xScaling_ * xRatio_ * (fAverage_ + A_ + (gPrev_ - A_) / (eta4_ * eta4_) * + (eta4_ * eta4_ - eta4_ * xVal + 1.0 / 3.0 * xVal * xVal)) * xVal); + } + else if (x <= x3_) + { + return (prevPrimitive_ + xScaling_ * xRatio_ * (fAverage_ * eta4_ + A_ * eta4_ + (gPrev_ - A_) / (eta4_ * eta4_) * + (1.0 / 3.0 * eta4_ * eta4_ * eta4_))); + } + else + { + xVal = 1.0 - (1.0 - xVal) / xRatio_; + return (prevPrimitive_ + xScaling_ * xRatio_ * (fAverage_ * xVal + A_ * xVal + (gPrev_ - A_) * (1.0 / 3.0 * eta4_) + + (gNext_ - A_) / ((1.0 - eta4_) * (1.0 - eta4_)) * + (1.0 / 3.0 * xVal * xVal * xVal - eta4_ * xVal * xVal + eta4_ * eta4_ * xVal - 1.0 / 3.0 * eta4_ * eta4_ * eta4_))); + } + } + } + + public class ConstantGradHelper : ISectionHelper + { + private double fPrev_, prevPrimitive_, xPrev_, fGrad_, fNext_; + + public ConstantGradHelper(double fPrev, double prevPrimitive, double xPrev, double xNext, double fNext) + { + fPrev_ = fPrev; + prevPrimitive_ = prevPrimitive; + xPrev_ = xPrev; + fGrad_ = ((fNext - fPrev) / (xNext - xPrev)); + fNext_ = fNext; + } + + public double value(double x) { return (fPrev_ + (x - xPrev_) * fGrad_); } + public double primitive(double x) { return (prevPrimitive_ + (x - xPrev_) * (fPrev_ + 0.5 * (x - xPrev_) * fGrad_)); } + public double fNext() { return fNext_; } + } + + public class QuadraticHelper : ISectionHelper + { + private double xPrev_, xNext_, fPrev_, fNext_, fAverage_, prevPrimitive_; + private double xScaling_, a_, b_, c_; + + public QuadraticHelper(double xPrev, double xNext, double fPrev, double fNext, double fAverage, double prevPrimitive) + { + xPrev_ = xPrev; + xNext_ = xNext; + fPrev_ = fPrev; + fNext_ = fNext; + fAverage_ = fAverage; + prevPrimitive_ = prevPrimitive; + a_ = 3 * fPrev_ + 3 * fNext_ - 6 * fAverage_; + b_ = -(4 * fPrev_ + 2 * fNext_ - 6 * fAverage_); + c_ = fPrev_; + xScaling_ = xNext_ - xPrev_; + } + + public double value(double x) + { + double xVal = (x - xPrev_) / xScaling_; + return (a_ * xVal * xVal + b_ * xVal + c_); + } + + public double primitive(double x) + { + double xVal = (x - xPrev_) / xScaling_; + return (prevPrimitive_ + xScaling_ * (a_ / 3 * xVal * xVal + b_ / 2 * xVal + c_) * xVal); + } + + public double fNext() { return fNext_; } + } + + public class QuadraticMinHelper : ISectionHelper + { + private bool splitRegion_; + private double x1_, x2_, x3_, x4_; + private double a_, b_, c_; + private double primitive1_, primitive2_; + private double fAverage_, fPrev_, fNext_, xScaling_, xRatio_; + + public QuadraticMinHelper(double xPrev, double xNext, double fPrev, double fNext, double fAverage, double prevPrimitive) + { + splitRegion_ = false; + x1_ = xPrev; + x4_ = xNext; + primitive1_ = prevPrimitive; + fAverage_ = fAverage; + fPrev_ = fPrev; + fNext_ = fNext; + a_ = 3 * fPrev_ + 3 * fNext_ - 6 * fAverage_; + b_ = -(4 * fPrev_ + 2 * fNext_ - 6 * fAverage_); + c_ = fPrev_; + double d = b_ * b_ - 4 * a_ * c_; + xScaling_ = x4_ - x1_; + xRatio_ = 1.0; + if (d > 0) + { + double aAv = 36; + double bAv = -24 * (fPrev_ + fNext_); + double cAv = 4 * (fPrev_ * fPrev_ + fPrev_ * fNext_ + fNext_ * fNext_); + double dAv = bAv * bAv - 4.0 * aAv * cAv; + if (dAv >= 0.0) + { + splitRegion_ = true; + double avRoot = (-bAv - Math.Sqrt(dAv)) / (2 * aAv); + + xRatio_ = fAverage_ / avRoot; + xScaling_ *= xRatio_; + + a_ = 3 * fPrev_ + 3 * fNext_ - 6 * avRoot; + b_ = -(4 * fPrev_ + 2 * fNext_ - 6 * avRoot); + c_ = fPrev_; + double xRoot = -b_ / (2 * a_); + x2_ = x1_ + xRatio_ * (x4_ - x1_) * xRoot; + x3_ = x4_ - xRatio_ * (x4_ - x1_) * (1 - xRoot); + primitive2_ = + primitive1_ + xScaling_ * (a_ / 3 * xRoot * xRoot + b_ / 2 * xRoot + c_) * xRoot; + } + } + } + + public double value(double x) + { + double xVal = (x - x1_) / (x4_ - x1_); + if (splitRegion_) + { + if (x <= x2_) + { + xVal /= xRatio_; + } + else if (x < x3_) + { + return 0.0; + } + else + { + xVal = 1.0 - (1.0 - xVal) / xRatio_; + } + } + + return c_ + b_ * xVal + a_ * xVal * xVal; + } + + public double primitive(double x) + { + double xVal = (x - x1_) / (x4_ - x1_); + if (splitRegion_) + { + if (x < x2_) + { + xVal /= xRatio_; + } + else if (x < x3_) + { + return primitive2_; + } + else + { + xVal = 1.0 - (1.0 - xVal) / xRatio_; + } + } + return primitive1_ + xScaling_ * (a_ / 3 * xVal * xVal + b_ / 2 * xVal + c_) * xVal; + } + + public double fNext() { return fNext_; } + } + #endregion + + + public class ConvexMonotoneImpl : Interpolation.templateImpl + { + private Dictionary sectionHelpers_ = new Dictionary(); + private Dictionary preSectionHelpers_ = new Dictionary(); + private ISectionHelper extrapolationHelper_; + private bool forcePositive_, constantLastPeriod_; + private double quadraticity_; + private double monotonicity_; + + public enum SectionType + { + EverywhereConstant, + ConstantGradient, + QuadraticMinimum, + QuadraticMaximum + } + + public ConvexMonotoneImpl(List xBegin, int size, List yBegin, + double quadraticity, double monotonicity, bool forcePositive, bool constantLastPeriod, + Dictionary preExistingHelpers) + : base(xBegin, size, yBegin) + { + preSectionHelpers_ = preExistingHelpers; + forcePositive_ = forcePositive; + constantLastPeriod_ = constantLastPeriod; + quadraticity_ = quadraticity; + monotonicity_ = monotonicity; + + Utils.QL_REQUIRE(monotonicity_ >= 0 && monotonicity_ <= 1, () => "Monotonicity must lie between 0 and 1"); + Utils.QL_REQUIRE(quadraticity_ >= 0 && quadraticity_ <= 1, () => "Quadraticity must lie between 0 and 1"); + Utils.QL_REQUIRE(size_ >= 2, () => "Single point provided, not supported by convex " + + "monotone method as first point is ignored"); + Utils.QL_REQUIRE((size_ - preExistingHelpers.Count) > 1, () => "Too many existing helpers have been supplied"); + } + + public override void update() + { + sectionHelpers_.Clear(); + if (size_ == 2) //single period + { + ISectionHelper singleHelper = new EverywhereConstantHelper(yBegin_[1], 0.0, xBegin_[0]); + sectionHelpers_.Add(xBegin_[1], singleHelper); + extrapolationHelper_ = singleHelper; + return; + } + + List f = new InitializedList(size_); + sectionHelpers_ = new Dictionary(preSectionHelpers_); + int startPoint = sectionHelpers_.Count + 1; + + //first derive the boundary forwards. + for (int i = startPoint; i < size_ - 1; ++i) + { + double dxPrev = xBegin_[i] - xBegin_[i - 1]; + double dx = xBegin_[i + 1] - xBegin_[i]; + f[i] = dxPrev / (dx + dxPrev) * yBegin_[i] + + dx / (dx + dxPrev) * yBegin_[i + 1]; + } + + if (startPoint > 1) + f[startPoint - 1] = preSectionHelpers_.Last().Value.fNext(); + if (startPoint == 1) + f[0] = 1.5 * yBegin_[1] - 0.5 * f[1]; + + f[size_ - 1] = 1.5 * yBegin_[size_ - 1] - 0.5 * f[size_ - 2]; + + if (forcePositive_) + { + if (f[0] < 0) + f[0] = 0.0; + if (f[size_ - 1] < 0.0) + f[size_ - 1] = 0.0; + } + + double primitive = 0.0; + for (int i = 0; i < startPoint - 1; ++i) + primitive += yBegin_[i + 1] * (xBegin_[i + 1] - xBegin_[i]); + + int endPoint = size_; + if (constantLastPeriod_) + endPoint = endPoint - 1; + + for (int i = startPoint; i < endPoint; ++i) + { + double gPrev = f[i - 1] - yBegin_[i]; + double gNext = f[i] - yBegin_[i]; + //first deal with the zero gradient case + if (Math.Abs(gPrev) < 1.0E-14 && Math.Abs(gNext) < 1.0E-14) + { + ISectionHelper singleHelper = new ConstantGradHelper(f[i - 1], primitive, + xBegin_[i - 1], + xBegin_[i], + f[i]); + sectionHelpers_.Add(xBegin_[i], singleHelper); + } + else + { + double quadraticity = quadraticity_; + ISectionHelper quadraticHelper = null; + ISectionHelper convMonotoneHelper = null; + if (quadraticity_ > 0.0) + { + if (gPrev >= -2.0 * gNext && gPrev > -0.5 * gNext && forcePositive_) + { + quadraticHelper = new QuadraticMinHelper(xBegin_[i - 1], + xBegin_[i], + f[i - 1], f[i], + yBegin_[i], + primitive); + } + else + { + quadraticHelper = new QuadraticHelper(xBegin_[i - 1], + xBegin_[i], + f[i - 1], f[i], + yBegin_[i], + primitive); + } + } + if (quadraticity_ < 1.0) + { + + if ((gPrev > 0.0 && -0.5 * gPrev >= gNext && gNext >= -2.0 * gPrev) || + (gPrev < 0.0 && -0.5 * gPrev <= gNext && gNext <= -2.0 * gPrev)) + { + quadraticity = 1.0; + if (quadraticity_.IsEqual(0.0)) + { + if (forcePositive_) + { + quadraticHelper = new QuadraticMinHelper( + xBegin_[i - 1], + xBegin_[i], + f[i - 1], f[i], + yBegin_[i], + primitive); + } + else + { + quadraticHelper = new QuadraticHelper( + xBegin_[i - 1], + xBegin_[i], + f[i - 1], f[i], + yBegin_[i], + primitive); + } + } + } + else if ((gPrev < 0.0 && gNext > -2.0 * gPrev) || + (gPrev > 0.0 && gNext < -2.0 * gPrev)) + { + + double eta = (gNext + 2.0 * gPrev) / (gNext - gPrev); + double b2 = (1.0 + monotonicity_) / 2.0; + if (eta < b2) + { + convMonotoneHelper = new ConvexMonotone2Helper( + xBegin_[i - 1], + xBegin_[i], + gPrev, gNext, + yBegin_[i], + eta, primitive); + } + else + { + if (forcePositive_) + { + convMonotoneHelper = new ConvexMonotone4MinHelper( + xBegin_[i - 1], + xBegin_[i], + gPrev, gNext, + yBegin_[i], + b2, primitive); + } + else + { + convMonotoneHelper = new ConvexMonotone4Helper( + xBegin_[i - 1], + xBegin_[i], + gPrev, gNext, + yBegin_[i], + b2, primitive); + } + } + } + else if ((gPrev > 0.0 && gNext < 0.0 && gNext > -0.5 * gPrev) || + (gPrev < 0.0 && gNext > 0.0 && gNext < -0.5 * gPrev)) + { + double eta = gNext / (gNext - gPrev) * 3.0; + double b3 = (1.0 - monotonicity_) / 2.0; + if (eta > b3) + { + convMonotoneHelper = new ConvexMonotone3Helper( + xBegin_[i - 1], + xBegin_[i], + gPrev, gNext, + yBegin_[i], + eta, primitive); + } + else + { + if (forcePositive_) + { + convMonotoneHelper = new ConvexMonotone4MinHelper( + xBegin_[i - 1], + xBegin_[i], + gPrev, gNext, + yBegin_[i], + b3, primitive); + } + else + { + convMonotoneHelper = new ConvexMonotone4Helper( + xBegin_[i - 1], + xBegin_[i], + gPrev, gNext, + yBegin_[i], + b3, primitive); + } + } + } + else + { + double eta = gNext / (gPrev + gNext); + double b2 = (1.0 + monotonicity_) / 2.0; + double b3 = (1.0 - monotonicity_) / 2.0; + if (eta > b2) + eta = b2; + if (eta < b3) + eta = b3; + if (forcePositive_) + { + convMonotoneHelper = new ConvexMonotone4MinHelper( + xBegin_[i - 1], + xBegin_[i], + gPrev, gNext, + yBegin_[i], + eta, primitive); + } + else + { + convMonotoneHelper = new ConvexMonotone4Helper( + xBegin_[i - 1], + xBegin_[i], + gPrev, gNext, + yBegin_[i], + eta, primitive); + } + } + } + + if (quadraticity.IsEqual(1.0)) + { + sectionHelpers_.Add(xBegin_[i], quadraticHelper); + } + else if (quadraticity.IsEqual(0.0)) + { + sectionHelpers_.Add(xBegin_[i], convMonotoneHelper); + } + else + { + sectionHelpers_.Add(xBegin_[i], new ComboHelper(quadraticHelper, convMonotoneHelper, quadraticity)); + } + } + primitive += yBegin_[i] * (xBegin_[i] - xBegin_[i - 1]); + } + + if (constantLastPeriod_) + { + sectionHelpers_.Add(xBegin_[size_ - 1], new EverywhereConstantHelper(yBegin_[size_ - 1], primitive, xBegin_[size_ - 2])); + extrapolationHelper_ = sectionHelpers_[xBegin_[size_ - 1]]; + } + else + { + extrapolationHelper_ = new EverywhereConstantHelper((sectionHelpers_.Last()).Value.value(xBegin_.Last()), + primitive, xBegin_.Last()); + } + } + + public override double value(double x) + { + if (x >= xBegin_.Last()) + { + return extrapolationHelper_.value(x); + } + + double i; + if (x > sectionHelpers_.Keys.Last()) + i = sectionHelpers_.Keys.Last(); + else if (x < sectionHelpers_.Keys.First()) + i = sectionHelpers_.Keys.First(); + else + i = sectionHelpers_.Keys.First(y => x < y); + return sectionHelpers_[i].value(x); + } + + public override double primitive(double x) + { + if (x >= xBegin_.Last()) + { + return extrapolationHelper_.primitive(x); + } + + double i; + if (x >= sectionHelpers_.Keys.Last()) + i = sectionHelpers_.Keys.Last(); + else if (x <= sectionHelpers_.Keys.First()) + i = sectionHelpers_.Keys.First(); + else + i = sectionHelpers_.Keys.First(y => x < y); + return sectionHelpers_[i].primitive(x); + } + + public override double derivative(double x) + { + throw new NotImplementedException("Convex-monotone spline derivative not implemented"); + } + + public override double secondDerivative(double x) + { + throw new NotImplementedException("Convex-monotone spline second derivative not implemented"); + } + + public Dictionary getExistingHelpers() + { + Dictionary retArray = new Dictionary(sectionHelpers_); + if (constantLastPeriod_) + retArray.Remove(xBegin_.Last()); + return retArray; + } + } + + //! Convex monotone yield-curve interpolation method. + /*! Enhances implementation of the convex monotone method + described in "Interpolation Methods for Curve Construction" by + Hagan & West AMF Vol 13, No2 2006. + + A setting of monotonicity = 1 and quadraticity = 0 will + reproduce the basic Hagan/West method. However, this can + produce excessive gradients which can mean P&L swings for some + curves. Setting monotonicity < 1 and/or quadraticity > 0 + produces smoother curves. Extra enhancement to avoid negative + values (if required) is in place. + */ + public class ConvexMonotoneInterpolation : Interpolation + { + public ConvexMonotoneInterpolation(List xBegin, int size, List yBegin, double quadraticity, + double monotonicity, bool forcePositive, bool flatFinalPeriod) + : this(xBegin, size, yBegin, quadraticity, monotonicity, forcePositive, flatFinalPeriod, + new Dictionary()) { } + public ConvexMonotoneInterpolation(List xBegin, int size, List yBegin, double quadraticity, + double monotonicity, bool forcePositive, bool flatFinalPeriod, + Dictionary preExistingHelpers) + { + impl_ = new ConvexMonotoneImpl(xBegin, size, yBegin, quadraticity, monotonicity, forcePositive, + flatFinalPeriod, preExistingHelpers); + impl_.update(); + } + + public Dictionary getExistingHelpers() + { + ConvexMonotoneImpl derived = impl_ as ConvexMonotoneImpl; + return derived.getExistingHelpers(); + } + } + + + //! Convex-monotone interpolation factory and traits + public class ConvexMonotone : IInterpolationFactory + { + private double quadraticity_, monotonicity_; + private bool forcePositive_; + + public ConvexMonotone() : this(0.3, 0.7, true) { } + public ConvexMonotone(double quadraticity, double monotonicity, bool forcePositive) + { + quadraticity_ = quadraticity; + monotonicity_ = monotonicity; + forcePositive_ = forcePositive; + } + + public Interpolation interpolate(List xBegin, int size, List yBegin) + { + return new ConvexMonotoneInterpolation(xBegin, size, yBegin, quadraticity_, monotonicity_, forcePositive_, false); + } + + public Interpolation localInterpolate(List xBegin, int size, List yBegin, int localisation, + ConvexMonotoneInterpolation prevInterpolation, int finalSize) + { + int length = size; + if (length - localisation == 1) // the first time this + { + // function is called + return new ConvexMonotoneInterpolation(xBegin, size, yBegin, quadraticity_, monotonicity_, forcePositive_, + length != finalSize); + } + + ConvexMonotoneInterpolation interp = prevInterpolation; + return new ConvexMonotoneInterpolation(xBegin, size, yBegin, quadraticity_, monotonicity_, + forcePositive_, length != finalSize, interp.getExistingHelpers()); + } + + public bool global { get { return true; } } + public int requiredPoints { get { return 2; } } + public int dataSizeAdjustment { get { return 1; } } + } +} diff --git a/src/QLNet/Math/Interpolations/CubicInterpolation.cs b/src/QLNet/Math/Interpolations/CubicInterpolation.cs index 24a92658c..d34a1c1c2 100644 --- a/src/QLNet/Math/Interpolations/CubicInterpolation.cs +++ b/src/QLNet/Math/Interpolations/CubicInterpolation.cs @@ -6,7 +6,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -75,11 +75,11 @@ Different boundary conditions can be used on the left and right */ Spline, - //! Overshooting minimization 1st derivative - SplineOM1, + //! Overshooting minimization 1st derivative + SplineOM1, - //! Overshooting minimization 2nd derivative - SplineOM2, + //! Overshooting minimization 2nd derivative + SplineOM2, //! Fourth-order approximation (local, non-monotone, linear) FourthOrder, @@ -94,7 +94,7 @@ Different boundary conditions can be used on the left and right Akima, //! Kruger approximation (local, monotone, non-linear) - Kruger, + Kruger, //! Weighted harmonic mean approximation (local, monotonic, non-linear) Harmonic @@ -130,8 +130,8 @@ public CubicInterpolation(List xBegin, int size, List yBegin, CubicInterpolation.BoundaryCondition rightCond, double rightConditionValue) { - impl_ = new CubicInterpolationImpl(xBegin, size, yBegin,da, monotonic,leftCond, leftConditionValue,rightCond, - rightConditionValue); + impl_ = new CubicInterpolationImpl(xBegin, size, yBegin, da, monotonic, leftCond, leftConditionValue, rightCond, + rightConditionValue); impl_.update(); } @@ -153,113 +153,115 @@ public List cCoefficients() // convenience classes - public class CubicNaturalSpline : CubicInterpolation { - /*! \pre the \f$ x \f$ values must be sorted. */ - public CubicNaturalSpline(List xBegin, int size, List yBegin) - : base(xBegin, size, yBegin, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) - {} - } - - public class MonotonicCubicNaturalSpline : CubicInterpolation { - /*! \pre the \f$ x \f$ values must be sorted. */ - public MonotonicCubicNaturalSpline(List xBegin, int size, List yBegin) - : base(xBegin, size, yBegin, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) - {} - } - - public class CubicSplineOvershootingMinimization1 : CubicInterpolation - { - /*! \pre the \f$ x \f$ values must be sorted. */ - public CubicSplineOvershootingMinimization1(List xBegin, int size, List yBegin) - : base(xBegin, size, yBegin, - CubicInterpolation.DerivativeApprox.SplineOM1, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) - {} - } - - public class CubicSplineOvershootingMinimization2 : CubicInterpolation - { - /*! \pre the \f$ x \f$ values must be sorted. */ - public CubicSplineOvershootingMinimization2(List xBegin, int size, List yBegin) - : base(xBegin, size, yBegin, - CubicInterpolation.DerivativeApprox.SplineOM2, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) - {} - } - - public class AkimaCubicInterpolation : CubicInterpolation - { - /*! \pre the \f$ x \f$ values must be sorted. */ - public AkimaCubicInterpolation(List xBegin, int size, List yBegin) - : base(xBegin, size, yBegin, - CubicInterpolation.DerivativeApprox.Akima, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) - {} - } - - public class KrugerCubic : CubicInterpolation - { - /*! \pre the \f$ x \f$ values must be sorted. */ - public KrugerCubic(List xBegin, int size, List yBegin) - : base(xBegin, size, yBegin, - CubicInterpolation.DerivativeApprox.Kruger, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) - {} - } - - public class HarmonicCubic : CubicInterpolation - { - /*! \pre the \f$ x \f$ values must be sorted. */ - public HarmonicCubic(List xBegin, int size, List yBegin) - : base(xBegin, size, yBegin, - CubicInterpolation.DerivativeApprox.Harmonic, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) - {} - } - - public class FritschButlandCubic : CubicInterpolation - { - /*! \pre the \f$ x \f$ values must be sorted. */ - public FritschButlandCubic(List xBegin, int size, List yBegin) - : base(xBegin, size, yBegin, - CubicInterpolation.DerivativeApprox.FritschButland, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) - {} - } - - public class Parabolic : CubicInterpolation - { - /*! \pre the \f$ x \f$ values must be sorted. */ - public Parabolic(List xBegin, int size, List yBegin) - : base(xBegin, size, yBegin, - CubicInterpolation.DerivativeApprox.Parabolic, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) - {} - } - - public class MonotonicParabolic : CubicInterpolation - { - /*! \pre the \f$ x \f$ values must be sorted. */ - public MonotonicParabolic(List xBegin, int size, List yBegin) - : base(xBegin, size, yBegin, - CubicInterpolation.DerivativeApprox.Parabolic, true, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) - {} - } + public class CubicNaturalSpline : CubicInterpolation + { + /*! \pre the \f$ x \f$ values must be sorted. */ + public CubicNaturalSpline(List xBegin, int size, List yBegin) + : base(xBegin, size, yBegin, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) + {} + } + + public class MonotonicCubicNaturalSpline : CubicInterpolation + { + /*! \pre the \f$ x \f$ values must be sorted. */ + public MonotonicCubicNaturalSpline(List xBegin, int size, List yBegin) + : base(xBegin, size, yBegin, + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) + {} + } + + public class CubicSplineOvershootingMinimization1 : CubicInterpolation + { + /*! \pre the \f$ x \f$ values must be sorted. */ + public CubicSplineOvershootingMinimization1(List xBegin, int size, List yBegin) + : base(xBegin, size, yBegin, + CubicInterpolation.DerivativeApprox.SplineOM1, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) + {} + } + + public class CubicSplineOvershootingMinimization2 : CubicInterpolation + { + /*! \pre the \f$ x \f$ values must be sorted. */ + public CubicSplineOvershootingMinimization2(List xBegin, int size, List yBegin) + : base(xBegin, size, yBegin, + CubicInterpolation.DerivativeApprox.SplineOM2, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) + {} + } + + public class AkimaCubicInterpolation : CubicInterpolation + { + /*! \pre the \f$ x \f$ values must be sorted. */ + public AkimaCubicInterpolation(List xBegin, int size, List yBegin) + : base(xBegin, size, yBegin, + CubicInterpolation.DerivativeApprox.Akima, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) + {} + } + + public class KrugerCubic : CubicInterpolation + { + /*! \pre the \f$ x \f$ values must be sorted. */ + public KrugerCubic(List xBegin, int size, List yBegin) + : base(xBegin, size, yBegin, + CubicInterpolation.DerivativeApprox.Kruger, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) + {} + } + + public class HarmonicCubic : CubicInterpolation + { + /*! \pre the \f$ x \f$ values must be sorted. */ + public HarmonicCubic(List xBegin, int size, List yBegin) + : base(xBegin, size, yBegin, + CubicInterpolation.DerivativeApprox.Harmonic, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) + {} + } + + public class FritschButlandCubic : CubicInterpolation + { + /*! \pre the \f$ x \f$ values must be sorted. */ + public FritschButlandCubic(List xBegin, int size, List yBegin) + : base(xBegin, size, yBegin, + CubicInterpolation.DerivativeApprox.FritschButland, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) + {} + } + + public class Parabolic : CubicInterpolation + { + /*! \pre the \f$ x \f$ values must be sorted. */ + public Parabolic(List xBegin, int size, List yBegin) + : base(xBegin, size, yBegin, + CubicInterpolation.DerivativeApprox.Parabolic, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) + {} + } + + public class MonotonicParabolic : CubicInterpolation + { + /*! \pre the \f$ x \f$ values must be sorted. */ + public MonotonicParabolic(List xBegin, int size, List yBegin) + : base(xBegin, size, yBegin, + CubicInterpolation.DerivativeApprox.Parabolic, true, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) + {} + } //! %Cubic interpolation factory and traits public class Cubic : IInterpolationFactory @@ -270,13 +272,13 @@ public class Cubic : IInterpolationFactory private double leftValue_, rightValue_; public Cubic() : this(CubicInterpolation.DerivativeApprox.Kruger, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) {} public Cubic(CubicInterpolation.DerivativeApprox da, bool monotonic, - CubicInterpolation.BoundaryCondition leftCondition, double leftConditionValue, - CubicInterpolation.BoundaryCondition rightCondition, double rightConditionValue) + CubicInterpolation.BoundaryCondition leftCondition, double leftConditionValue, + CubicInterpolation.BoundaryCondition rightCondition, double rightConditionValue) { da_ = da; monotonic_ = monotonic; @@ -289,17 +291,23 @@ public Cubic(CubicInterpolation.DerivativeApprox da, bool monotonic, public Interpolation interpolate(List xBegin, int size, List yBegin) { return new CubicInterpolation(xBegin, size, yBegin, da_, monotonic_, leftType_, leftValue_, rightType_, - rightValue_); + rightValue_); } public bool global { - get { return true; } + get + { + return true; + } } public int requiredPoints { - get { return 2; } + get + { + return 2; + } } } @@ -316,12 +324,12 @@ public class CubicInterpolationImpl : Interpolation.templateImpl private List monotonicityAdjustments_; public CubicInterpolationImpl(List xBegin, int size, List yBegin, - CubicInterpolation.DerivativeApprox da, - bool monotonic, - CubicInterpolation.BoundaryCondition leftCondition, - double leftConditionValue, - CubicInterpolation.BoundaryCondition rightCondition, - double rightConditionValue) + CubicInterpolation.DerivativeApprox da, + bool monotonic, + CubicInterpolation.BoundaryCondition leftCondition, + double leftConditionValue, + CubicInterpolation.BoundaryCondition rightCondition, + double rightConditionValue) : base(xBegin, size, yBegin) { da_ = da; @@ -342,8 +350,8 @@ public CubicInterpolationImpl(List xBegin, int size, List yBegin || rightType_ == CubicInterpolation.BoundaryCondition.Lagrange) { Utils.QL_REQUIRE(size >= 4, () => - "Lagrange boundary condition requires at least " + - "4 points (" + size.ToString() + " are given)"); + "Lagrange boundary condition requires at least " + + "4 points (" + size.ToString() + " are given)"); } } @@ -351,7 +359,7 @@ public override void update() { Vector tmp = new Vector(size_); List dx = new InitializedList(size_ - 1), - S = new InitializedList(size_ - 1); + S = new InitializedList(size_ - 1); for (int i = 0; i < size_ - 1; ++i) { @@ -391,11 +399,11 @@ public override void update() case CubicInterpolation.BoundaryCondition.Lagrange: L.setFirstRow(1.0, 0.0); tmp[0] = cubicInterpolatingPolynomialDerivative( - this.xBegin_[0], this.xBegin_[1], - this.xBegin_[2], this.xBegin_[3], - this.yBegin_[0], this.yBegin_[1], - this.yBegin_[2], this.yBegin_[3], - this.xBegin_[0]); + this.xBegin_[0], this.xBegin_[1], + this.xBegin_[2], this.xBegin_[3], + this.yBegin_[0], this.yBegin_[1], + this.yBegin_[2], this.yBegin_[3], + this.xBegin_[0]); break; default: throw new ArgumentException("unknown end condition"); @@ -407,7 +415,7 @@ public override void update() case CubicInterpolation.BoundaryCondition.NotAKnot: // ignoring end condition value L.setLastRow(-(dx[size_ - 2] + dx[size_ - 3]) * (dx[size_ - 2] + dx[size_ - 3]), - -dx[size_ - 3] * (dx[size_ - 3] + dx[size_ - 2])); + -dx[size_ - 3] * (dx[size_ - 3] + dx[size_ - 2])); tmp[size_ - 1] = -S[size_ - 3] * dx[size_ - 2] * dx[size_ - 2] - S[size_ - 2] * dx[size_ - 3] * (3.0 * dx[size_ - 2] + 2.0 * dx[size_ - 3]); break; @@ -425,11 +433,11 @@ public override void update() case CubicInterpolation.BoundaryCondition.Lagrange: L.setLastRow(0.0, 1.0); tmp[size_ - 1] = cubicInterpolatingPolynomialDerivative( - this.xBegin_[size_ - 4], this.xBegin_[size_ - 3], - this.xBegin_[size_ - 2], this.xBegin_[size_ - 1], - this.yBegin_[size_ - 4], this.yBegin_[size_ - 3], - this.yBegin_[size_ - 2], this.yBegin_[size_ - 1], - this.xBegin_[size_ - 1]); + this.xBegin_[size_ - 4], this.xBegin_[size_ - 3], + this.xBegin_[size_ - 2], this.xBegin_[size_ - 1], + this.yBegin_[size_ - 4], this.yBegin_[size_ - 3], + this.yBegin_[size_ - 2], this.yBegin_[size_ - 1], + this.xBegin_[size_ - 1]); break; default: throw new ArgumentException("unknown end condition"); @@ -438,94 +446,102 @@ public override void update() // solve the system tmp = L.solveFor(tmp); } - else if (da_== CubicInterpolation.DerivativeApprox.SplineOM1) + else if (da_ == CubicInterpolation.DerivativeApprox.SplineOM1) { - Matrix T_ = new Matrix(size_-2, size_, 0.0); - for (int i=0; iMath.Abs(3*S[0])) { - tmp[0] = 3*S[0]; - } - } - // end points [n-1] - tmp[size_-1] = ((2*dx[size_-2]+dx[size_-3])*S[size_-2]-dx[size_-2]*S[size_-3])/(dx[size_-3]+dx[size_-2]); - if (tmp[size_-1]*S[size_-2]<0.0) { - tmp[size_-1] = 0; + case CubicInterpolation.DerivativeApprox.Harmonic: + // intermediate points + for (int i = 1; i < size_ - 1; ++i) + { + double w1 = 2 * dx[i] + dx[i - 1]; + double w2 = dx[i] + 2 * dx[i - 1]; + if (S[i - 1]*S[i] <= 0.0) + // slope changes sign at point + tmp[i] = 0.0; + else + // weighted harmonic mean of S[i] and S[i-1] if they + // have the same sign; otherwise 0 + tmp[i] = (w1 + w2) / (w1 / S[i - 1] + w2 / S[i]); + } + // end points [0] + tmp[0] = ((2 * dx[0] + dx[1]) * S[0] - dx[0] * S[1]) / (dx[1] + dx[0]); + if (tmp[0]*S[0] < 0.0) + { + tmp[0] = 0; + } + else if (S[0]*S[1] < 0) + { + if (Math.Abs(tmp[0]) > Math.Abs(3 * S[0])) + { + tmp[0] = 3 * S[0]; } - else if (S[size_-2]*S[size_-3]<0) { - if (Math.Abs(tmp[size_ - 1]) > Math.Abs(3 * S[size_ - 2])) - { - tmp[size_-1] = 3*S[size_-2]; - } + } + // end points [n-1] + tmp[size_ - 1] = ((2 * dx[size_ - 2] + dx[size_ - 3]) * S[size_ - 2] - dx[size_ - 2] * S[size_ - 3]) / (dx[size_ - 3] + dx[size_ - 2]); + if (tmp[size_ - 1]*S[size_ - 2] < 0.0) + { + tmp[size_ - 1] = 0; + } + else if (S[size_ - 2]*S[size_ - 3] < 0) + { + if (Math.Abs(tmp[size_ - 1]) > Math.Abs(3 * S[size_ - 2])) + { + tmp[size_ - 1] = 3 * S[size_ - 2]; } - break; + } + break; default: throw new ArgumentException("unknown scheme"); } @@ -665,7 +687,7 @@ public override void update() { correction = tmp[i] / Math.Abs(tmp[i]) * Math.Min(Math.Abs(tmp[i]), - Math.Abs(3.0 * S[0])); + Math.Abs(3.0 * S[0])); } else { @@ -699,7 +721,7 @@ public override void update() pm = (S[i - 1] * dx[i] + S[i] * dx[i - 1]) / (dx[i - 1] + dx[i]); M = 3.0 * Math.Min(Math.Min(Math.Abs(S[i - 1]), Math.Abs(S[i])), - Math.Abs(pm)); + Math.Abs(pm)); if (i > 1) { if ((S[i - 1] - S[i - 2]) * (S[i] - S[i - 1]) > 0.0) @@ -710,7 +732,7 @@ public override void update() if (pm * pd > 0.0 && pm * (S[i - 1] - S[i - 2]) > 0.0) { M = Math.Max(M, 1.5 * Math.Min( - Math.Abs(pm), Math.Abs(pd))); + Math.Abs(pm), Math.Abs(pd))); } } } @@ -723,7 +745,7 @@ public override void update() if (pm * pu > 0.0 && -pm * (S[i] - S[i - 1]) > 0.0) { M = Math.Max(M, 1.5 * Math.Min( - Math.Abs(pm), Math.Abs(pu))); + Math.Abs(pm), Math.Abs(pu))); } } } diff --git a/src/QLNet/Math/Interpolations/Extrapolator.cs b/src/QLNet/Math/Interpolations/Extrapolator.cs index a5546ca55..da126d14e 100644 --- a/src/QLNet/Math/Interpolations/Extrapolator.cs +++ b/src/QLNet/Math/Interpolations/Extrapolator.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,16 +20,16 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! base class for classes possibly allowing extrapolation - // LazyObject should not be here but it is because of the InterpolatedYieldCurve - public abstract class Extrapolator : LazyObject - { - private bool extrapolate_; - public bool extrapolate { get { return extrapolate_; } set { extrapolate_ = value; } } + //! base class for classes possibly allowing extrapolation + // LazyObject should not be here but it is because of the InterpolatedYieldCurve + public abstract class Extrapolator : LazyObject + { + private bool extrapolate_; + public bool extrapolate { get { return extrapolate_; } set { extrapolate_ = value; } } - // some extra functionality - public bool allowsExtrapolation() { return extrapolate_; } //! tells whether extrapolation is enabled - public void enableExtrapolation(bool b = true) { extrapolate_ = b; } //! enable extrapolation in subsequent calls - public void disableExtrapolation(bool b = true) { extrapolate_ = !b; } //! disable extrapolation in subsequent calls - } + // some extra functionality + public bool allowsExtrapolation() { return extrapolate_; } //! tells whether extrapolation is enabled + public void enableExtrapolation(bool b = true) { extrapolate_ = b; } //! enable extrapolation in subsequent calls + public void disableExtrapolation(bool b = true) { extrapolate_ = !b; } //! disable extrapolation in subsequent calls + } } diff --git a/src/QLNet/Math/Interpolations/FlatExtrapolator2D.cs b/src/QLNet/Math/Interpolations/FlatExtrapolator2D.cs index 25106495d..20c7db07d 100644 --- a/src/QLNet/Math/Interpolations/FlatExtrapolator2D.cs +++ b/src/QLNet/Math/Interpolations/FlatExtrapolator2D.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,13 +19,13 @@ namespace QLNet { - public class FlatExtrapolator2D : Interpolation2D + public class FlatExtrapolator2D : Interpolation2D { - public FlatExtrapolator2D(Interpolation2D decoratedInterpolation) + public FlatExtrapolator2D(Interpolation2D decoratedInterpolation) { impl_ = new FlatExtrapolator2DImpl(decoratedInterpolation); } - + protected class FlatExtrapolator2DImpl: Interpolation2D.Impl { public FlatExtrapolator2DImpl(Interpolation2D decoratedInterpolation) @@ -42,34 +42,34 @@ public FlatExtrapolator2DImpl(Interpolation2D decoratedInterpolation) public List yValues() {return decoratedInterp_.yValues();} public int locateY(double y) {return decoratedInterp_.locateY(y);} public Matrix zData() {return decoratedInterp_.zData();} - public bool isInRange(double x, double y) {return decoratedInterp_.isInRange(x,y);} + public bool isInRange(double x, double y) {return decoratedInterp_.isInRange(x, y);} public void update() {decoratedInterp_.update();} public void calculate() { // Nothing to do here } - public double value(double x, double y) + public double value(double x, double y) { x = bindX(x); y = bindY(y); - return decoratedInterp_.value(x,y); + return decoratedInterp_.value(x, y); } private Interpolation2D decoratedInterp_; - private double bindX(double x) + private double bindX(double x) { - if(x < xMin()) + if (x < xMin()) return xMin(); - if (x > xMax()) + if (x > xMax()) return xMax(); return x; } - private double bindY(double y) + private double bindY(double y) { - if(y < yMin()) + if (y < yMin()) return yMin(); - if (y > yMax()) + if (y > yMax()) return yMax(); return y; } diff --git a/src/QLNet/Math/Interpolations/ForwardFlatInterpolation.cs b/src/QLNet/Math/Interpolations/ForwardFlatInterpolation.cs new file mode 100644 index 000000000..923e966c4 --- /dev/null +++ b/src/QLNet/Math/Interpolations/ForwardFlatInterpolation.cs @@ -0,0 +1,81 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System.Collections.Generic; + + +namespace QLNet +{ + public class ForwardFlatInterpolationImpl : Interpolation.templateImpl + { + private List primitive_; + + public ForwardFlatInterpolationImpl(List xBegin, int size, List yBegin) : base(xBegin, size, yBegin) + { + primitive_ = new InitializedList(size_); + } + + public override void update() + { + primitive_[0] = 0.0; + for (int i = 1; i < size_; i++) + { + double dx = xBegin_[i] - xBegin_[i - 1]; + primitive_[i] = primitive_[i - 1] + dx * yBegin_[i - 1]; + } + } + public override double value(double x) + { + if (x >= xBegin_[size_ - 1]) + return yBegin_[size_ - 1]; + + int i = locate(x); + return yBegin_[i]; + } + public override double primitive(double x) + { + int i = locate(x); + double dx = x - xBegin_[i]; + return primitive_[i] + dx * yBegin_[i]; + } + public override double derivative(double x) { return 0.0; } + public override double secondDerivative(double x) { return 0.0; } + } + + //! Forward-flat interpolation between discrete points + public class ForwardFlatInterpolation : Interpolation + { + /*! \pre the \f$ x \f$ values must be sorted. */ + public ForwardFlatInterpolation(List xBegin, int size, List yBegin) + { + impl_ = new ForwardFlatInterpolationImpl(xBegin, size, yBegin); + impl_.update(); + } + } + + //! Forward-flat interpolation factory and traits + public class ForwardFlat : IInterpolationFactory + { + public Interpolation interpolate(List xBegin, int size, List yBegin) + { + return new ForwardFlatInterpolation(xBegin, size, yBegin); + } + public bool global { get { return false; } } + public int requiredPoints { get { return 2; } } + } +} diff --git a/src/QLNet/Math/Interpolations/Interpolation2D.cs b/src/QLNet/Math/Interpolations/Interpolation2D.cs new file mode 100644 index 000000000..b07f9416f --- /dev/null +++ b/src/QLNet/Math/Interpolations/Interpolation2D.cs @@ -0,0 +1,186 @@ +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QLNet +{ + //! base class for 2-D interpolations. + /*! Classes derived from this class will provide interpolated + values from two sequences of length \f$ N \f$ and \f$ M \f$, + representing the discretized values of the \f$ x \f$ and \f$ y + \f$ variables, and a \f$ N \times M \f$ matrix representing + the tabulated function values. + */ + + // Interpolation factory + public interface IInterpolationFactory2D + { + Interpolation2D interpolate(List xBegin, int xSize, + List yBegin, int ySize, + Matrix zData); + } + + public abstract class Interpolation2D : Extrapolator/*, IValue */ + { + protected Impl impl_; + + public double xMin() {return impl_.xMin();} + + public double xMax() {return impl_.xMax();} + + public List xValues() {return impl_.xValues();} + + public int locateX(double x) {return impl_.locateX(x);} + + public double yMin() {return impl_.yMin();} + + public double yMax() {return impl_.yMax();} + + public List yValues() {return impl_.yValues();} + + public int locateY(double y) {return impl_.locateY(y);} + + public Matrix zData() {return impl_.zData();} + + public bool isInRange(double x, double y) {return impl_.isInRange(x, y);} + + public override void update() {impl_.calculate();} + + // main method to derive an interpolated point + public double value(double x, double y) { return value(x, y, false); } + + public double value(double x, double y, bool allowExtrapolation) + { + checkRange(x, y, allowExtrapolation); + return impl_.value(x, y); + } + + protected void checkRange(double x, double y, bool extrapolate) + { + if (!(extrapolate || allowsExtrapolation() || impl_.isInRange(x, y))) + throw new ArgumentException("interpolation range is [" + impl_.xMin() + ", " + impl_.xMax() + + "] X [" + x + impl_.yMin() + ", " + impl_.yMax() + + "]: extrapolation at (" + x + ", " + y + " not allowed"); + } + + //! abstract base class for 2-D interpolation implementations + protected interface Impl //: IValue + { + void calculate(); + double xMin(); + double xMax(); + List xValues(); + int locateX(double x); + double yMin(); + double yMax(); + List yValues(); + int locateY(double y); + Matrix zData(); + bool isInRange(double x, double y); + double value(double x, double y); + } + + public abstract class templateImpl : Impl + { + protected List xBegin_; + protected List yBegin_; + protected int xSize_; + protected int ySize_; + protected Matrix zData_; + + // this method should be used for initialisation + protected templateImpl(List xBegin, int xSize, + List yBegin, int ySize, + Matrix zData) + { + xBegin_ = xBegin; + xSize_ = xSize; + yBegin_ = yBegin; + ySize_ = ySize; + zData_ = zData; + + if (xSize < 2) + throw new ArgumentException("not enough points to interpolate: at least 2 required, " + + xSize + " provided"); + if (ySize < 2) + throw new ArgumentException("not enough points to interpolate: at least 2 required, " + + ySize + " provided"); + } + + public double xMin() { return xBegin_.First(); } + + public double xMax() { return xBegin_[xSize_ - 1]; } + + public List xValues() { return xBegin_.GetRange(0, xSize_); } + + public double yMin() { return yBegin_.First(); } + + public double yMax() { return yBegin_[ySize_ - 1]; } + + public List yValues() { return yBegin_.GetRange(0, ySize_); } + + public Matrix zData() {return zData_;} + + public bool isInRange(double x, double y) + { + double x1 = xMin(), x2 = xMax(); + bool xIsInrange = (x >= x1 && x <= x2) || Utils.close(x, x1) || Utils.close(x, x2); + if (!xIsInrange) + return false; + + double y1 = yMin(), y2 = yMax(); + return (y >= y1 && y <= y2) || Utils.close(y, y1) || Utils.close(y, y2); + } + + public int locateX(double x) + { + int result = xBegin_.BinarySearch(x); + if (result < 0) + // The upper_bound() algorithm finds the last position in a sequence that value can occupy + // without violating the sequence's ordering + // if BinarySearch does not find value the value, the index of the next larger item is returned + result = ~result - 1; + + // impose limits. we need the one before last at max or the first at min + result = Math.Max(Math.Min(result, xSize_ - 2), 0); + return result; + } + + public int locateY(double y) + { + int result = yBegin_.BinarySearch(y); + if (result < 0) + // The upper_bound() algorithm finds the last position in a sequence that value can occupy + // without violating the sequence's ordering + // if BinarySearch does not find value the value, the index of the next larger item is returned + result = ~result - 1; + + // impose limits. we need the one before last at max or the first at min + result = Math.Max(Math.Min(result, ySize_ - 2), 0); + return result; + } + + public abstract double value(double x, double y); + public abstract void calculate(); + + } + } +} diff --git a/src/QLNet/Math/Interpolations/KernelInterpolation.cs b/src/QLNet/Math/Interpolations/KernelInterpolation.cs index 6cda80f87..6cf50c709 100644 --- a/src/QLNet/Math/Interpolations/KernelInterpolation.cs +++ b/src/QLNet/Math/Interpolations/KernelInterpolation.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,48 +21,48 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - + public class KernelInterpolationImpl : Interpolation.templateImpl where Kernel: IKernelFunction { - public KernelInterpolationImpl(List xBegin, int size, List yBegin,Kernel kernel) - :base( xBegin, size, yBegin ) + public KernelInterpolationImpl(List xBegin, int size, List yBegin, Kernel kernel) + : base(xBegin, size, yBegin) { xSize_ = size; invPrec_ = 1.0e-7; - M_ = new Matrix(xSize_,xSize_); - alphaVec_ = new Vector(xSize_); + M_ = new Matrix(xSize_, xSize_); + alphaVec_ = new Vector(xSize_); yVec_ = new Vector(xSize_); kernel_ = kernel; } - public override void update() + public override void update() { updateAlphaVec(); } - public override double value(double x) + public override double value(double x) { - double res=0.0; - for( int i=0; i< xSize_;++i) + double res = 0.0; + for (int i = 0; i < xSize_; ++i) { - res+=alphaVec_[i]*kernelAbs(x,this.xBegin_[i]); + res += alphaVec_[i] * kernelAbs(x, this.xBegin_[i]); } - return res/gammaFunc(x); + return res / gammaFunc(x); } - public override double primitive(double d) + public override double primitive(double d) { Utils.QL_FAIL("Primitive calculation not implemented for kernel interpolation"); return 0; } - public override double derivative(double d) + public override double derivative(double d) { Utils.QL_FAIL("First derivative calculation not implemented for kernel interpolation"); return 0; } - public override double secondDerivative(double d) + public override double secondDerivative(double d) { Utils.QL_FAIL("Second derivative calculation not implemented for kernel interpolation"); return 0; @@ -73,17 +73,17 @@ public override double secondDerivative(double d) // M*a may not give y. Here, a failure will be thrown if // |M*a-y|>=invPrec_ - public void setInverseResultPrecision(double invPrec) { invPrec_=invPrec; } + public void setInverseResultPrecision(double invPrec) { invPrec_ = invPrec; } - private double kernelAbs(double x1, double x2){ return kernel_.value(Math.Abs(x1-x2)); } + private double kernelAbs(double x1, double x2) { return kernel_.value(Math.Abs(x1 - x2)); } private double gammaFunc(double x) { - double res=0.0; + double res = 0.0; - for(int i=0; i< xSize_;++i) + for (int i = 0; i < xSize_; ++i) { - res+=kernelAbs(x,this.xBegin_[i]); + res += kernelAbs(x, this.xBegin_[i]); } return res; } @@ -94,34 +94,35 @@ private void updateAlphaVec() // fixed pillars+values // Write Matrix M - double tmp=0.0; + double tmp = 0.0; - for(int rowIt=0; rowIt - "Inversion failed in 1d kernel interpolation"); + for (int i = 0; i < diffVec.size(); ++i) + { + Utils.QL_REQUIRE(diffVec[i] < invPrec_, () => + "Inversion failed in 1d kernel interpolation"); } - + } private int xSize_; @@ -129,7 +130,7 @@ private void updateAlphaVec() private Matrix M_; private Vector alphaVec_, yVec_; private Kernel kernel_; - + } //! Kernel interpolation between discrete points @@ -140,18 +141,18 @@ private void updateAlphaVec() The kernel in the implementation is kept general, although a Gaussian is considered in the cited text. */ - public class KernelInterpolation : Interpolation + public class KernelInterpolation : Interpolation { - + /*! \pre the \f$ x \f$ values must be sorted. \pre kernel needs a Real operator()(Real x) implementation */ - public KernelInterpolation(List xBegin, int size, List yBegin,IKernelFunction kernel) + public KernelInterpolation(List xBegin, int size, List yBegin, IKernelFunction kernel) { - impl_ = new KernelInterpolationImpl( xBegin, size, yBegin, kernel ); + impl_ = new KernelInterpolationImpl(xBegin, size, yBegin, kernel); impl_.update(); } - }; + } + - -} +} diff --git a/src/QLNet/Math/Interpolations/KernelInterpolation2D.cs b/src/QLNet/Math/Interpolations/KernelInterpolation2D.cs index 58ad1aadb..6ec68020e 100644 --- a/src/QLNet/Math/Interpolations/KernelInterpolation2D.cs +++ b/src/QLNet/Math/Interpolations/KernelInterpolation2D.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -41,78 +41,74 @@ corresponding to the grid above. */ public class KernelInterpolation2DImpl : Interpolation2D.templateImpl where Kernel: IKernelFunction { - public KernelInterpolation2DImpl(List xBegin, int size, List yBegin,int ySize, - Matrix zData, Kernel kernel) - :base( xBegin, size, yBegin,ySize,zData ) + public KernelInterpolation2DImpl(List xBegin, int size, List yBegin, int ySize, + Matrix zData, Kernel kernel) + : base(xBegin, size, yBegin, ySize, zData) { xSize_ = size; ySize_ = yBegin.Count; - xySize_ = xSize_*ySize_; + xySize_ = xSize_ * ySize_; invPrec_ = 1.0e-10; - alphaVec_ = new Vector(xySize_); + alphaVec_ = new Vector(xySize_); yVec_ = new Vector(xySize_); - M_ = new Matrix(xySize_,xySize_); - kernel_ = kernel; + M_ = new Matrix(xySize_, xySize_); + kernel_ = kernel; - Utils.QL_REQUIRE(zData.rows()==xSize_,()=> - "Z value matrix has wrong number of rows"); - Utils.QL_REQUIRE( zData.columns() == ySize_, () => - "Z value matrix has wrong number of columns"); + Utils.QL_REQUIRE(zData.rows() == xSize_, () => + "Z value matrix has wrong number of rows"); + Utils.QL_REQUIRE(zData.columns() == ySize_, () => + "Z value matrix has wrong number of columns"); } public override void calculate() { updateAlphaVec(); } - public override double value(double x1, double x2) + public override double value(double x1, double x2) { - double res=0.0; + double res = 0.0; - Vector X = new Vector(2),Xn = new Vector(2); - X[0]=x1;X[1]=x2; + Vector X = new Vector(2), Xn = new Vector(2); + X[0] = x1; X[1] = x2; - int cnt=0; // counter + int cnt = 0; // counter - for( int j=0; j< ySize_;++j){ - for( int i=0; i< xSize_;++i) + for (int j = 0; j < ySize_; ++j) + { + for (int i = 0; i < xSize_; ++i) { - Xn[0]=this.xBegin_[i]; - Xn[1]=this.yBegin_[j]; - res+=alphaVec_[cnt]*kernelAbs(X,Xn); + Xn[0] = this.xBegin_[i]; + Xn[1] = this.yBegin_[j]; + res += alphaVec_[cnt] * kernelAbs(X, Xn); cnt++; } } - return res/gammaFunc(X); + return res / gammaFunc(X); } // the calculation will solve y=M*a for a. Due to // singularity or rounding errors the recalculation // M*a may not give y. Here, a failure will be thrown if // |M*a-y|>=invPrec_ - public void setInverseResultPrecision(double invPrec){invPrec_=invPrec;} + public void setInverseResultPrecision(double invPrec) {invPrec_ = invPrec;} + - // returns K(||X-Y||) where X,Y are vectors private double kernelAbs(Vector X, Vector Y) { - return kernel_.value( vecNorm( X - Y ) ); - } - - private double vecNorm(Vector X) - { - return Math.Sqrt(Vector.DotProduct(X,X)); + return kernel_.value(Vector.Norm2(X - Y)); } private double gammaFunc(Vector X) { - double res=0.0; + double res = 0.0; Vector Xn = new Vector(X.size()); - for(int j=0; j< ySize_;++j) + for (int j = 0; j < ySize_; ++j) { - for(int i=0; i< xSize_;++i) + for (int i = 0; i < xSize_; ++i) { - Xn[0]=this.xBegin_[i]; - Xn[1]=this.yBegin_[j]; - res+=kernelAbs(X,Xn); + Xn[0] = this.xBegin_[i]; + Xn[1] = this.yBegin_[j]; + res += kernelAbs(X, Xn); } } @@ -124,31 +120,31 @@ private void updateAlphaVec() // Function calculates the alpha vector with given // fixed pillars+values - Vector Xk = new Vector(2),Xn = new Vector(2); + Vector Xk = new Vector(2), Xn = new Vector(2); - int rowCnt=0,colCnt=0; - double tmpVar=0.0; + int rowCnt = 0, colCnt = 0; + double tmpVar = 0.0; // write y-vector and M-Matrix - for(int j=0; j< ySize_;++j) + for (int j = 0; j < ySize_; ++j) { - for(int i=0; i< xSize_;++i) + for (int i = 0; i < xSize_; ++i) { - yVec_[rowCnt]=this.zData_[i,j]; + yVec_[rowCnt] = this.zData_[i, j]; // calculate X_k - Xk[0]=this.xBegin_[i]; - Xk[1]=this.yBegin_[j]; + Xk[0] = this.xBegin_[i]; + Xk[1] = this.yBegin_[j]; - tmpVar=1/gammaFunc(Xk); - colCnt=0; + tmpVar = 1 / gammaFunc(Xk); + colCnt = 0; - for(int jM=0; jM< ySize_;++jM) + for (int jM = 0; jM < ySize_; ++jM) { - for(int iM=0; iM< xSize_;++iM) + for (int iM = 0; iM < xSize_; ++iM) { - Xn[0]=this.xBegin_[iM]; - Xn[1]=this.yBegin_[jM]; - M_[rowCnt,colCnt]=kernelAbs(Xk,Xn)*tmpVar; + Xn[0] = this.xBegin_[iM]; + Xn[1] = this.yBegin_[jM]; + M_[rowCnt, colCnt] = kernelAbs(Xk, Xn) * tmpVar; colCnt++; // increase column counter }// end iM }// end jM @@ -156,15 +152,16 @@ private void updateAlphaVec() } // end i }// end j - alphaVec_= MatrixUtilities.qrSolve(M_, yVec_); + alphaVec_ = MatrixUtilities.qrSolve(M_, yVec_); // check if inversion worked up to a reasonable precision. // I've chosen not to check determinant(M_)!=0 before solving - Vector diffVec=Vector.Abs(M_*alphaVec_ - yVec_); - for (int i=0; i - "inversion failed in 2d kernel interpolation"); + Vector diffVec = Vector.Abs(M_ * alphaVec_ - yVec_); + for (int i = 0; i < diffVec.size(); ++i) + { + Utils.QL_REQUIRE(diffVec[i] + "inversion failed in 2d kernel interpolation"); } } @@ -173,8 +170,8 @@ private void updateAlphaVec() private Vector alphaVec_, yVec_; private Matrix M_; private Kernel kernel_; - -} + + } /*! Implementation of the 2D kernel interpolation approach, which can be found in "Foreign Exchange Risk" by Hakala, Wystup page @@ -188,15 +185,15 @@ public class KernelInterpolation2D : Interpolation2D /*! \pre the \f$ x \f$ values must be sorted. \pre kernel needs a Real operator()(Real x) implementation - + */ - public KernelInterpolation2D(List xBegin, int size, List yBegin,int ySize, - Matrix zData, IKernelFunction kernel) + public KernelInterpolation2D(List xBegin, int size, List yBegin, int ySize, + Matrix zData, IKernelFunction kernel) { - impl_ = new KernelInterpolation2DImpl( xBegin, size, yBegin, ySize, zData, kernel ); + impl_ = new KernelInterpolation2DImpl(xBegin, size, yBegin, ySize, zData, kernel); this.update(); } } diff --git a/src/QLNet/Math/Interpolations/Linearinterpolation.cs b/src/QLNet/Math/Interpolations/Linearinterpolation.cs index 4bac3e4e0..48d929d6c 100644 --- a/src/QLNet/Math/Interpolations/Linearinterpolation.cs +++ b/src/QLNet/Math/Interpolations/Linearinterpolation.cs @@ -1,75 +1,87 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System.Collections.Generic; -namespace QLNet { - /* linear interpolation between discrete points */ - public class LinearInterpolationImpl : Interpolation.templateImpl { - private List primitiveConst_, s_; +namespace QLNet +{ + /* linear interpolation between discrete points */ + public class LinearInterpolationImpl : Interpolation.templateImpl + { + private List primitiveConst_, s_; - public LinearInterpolationImpl(List xBegin, int size, List yBegin) - : base(xBegin, size, yBegin) { - primitiveConst_ = new InitializedList(size_); - s_ = new InitializedList(size_); - } + public LinearInterpolationImpl(List xBegin, int size, List yBegin) + : base(xBegin, size, yBegin) + { + primitiveConst_ = new InitializedList(size_); + s_ = new InitializedList(size_); + } - public override void update() { - primitiveConst_[0] = 0.0; - for (int i = 1; i < size_; ++i) { - double dx = xBegin_[i] - xBegin_[i - 1]; - s_[i - 1] = (yBegin_[i] - yBegin_[i - 1]) / dx; - primitiveConst_[i] = primitiveConst_[i - 1] + dx * (yBegin_[i - 1] + 0.5 * dx * s_[i - 1]); - } - } + public override void update() + { + primitiveConst_[0] = 0.0; + for (int i = 1; i < size_; ++i) + { + double dx = xBegin_[i] - xBegin_[i - 1]; + s_[i - 1] = (yBegin_[i] - yBegin_[i - 1]) / dx; + primitiveConst_[i] = primitiveConst_[i - 1] + dx * (yBegin_[i - 1] + 0.5 * dx * s_[i - 1]); + } + } - public override double value(double x) { - int i = locate(x); - double result = yBegin_[i] + (x - xBegin_[i]) * s_[i]; - return result; - } - public override double primitive(double x) { - int i = locate(x); - double dx = x - xBegin_[i]; - return primitiveConst_[i] + dx * (yBegin_[i] + 0.5 * dx * s_[i]); - } - public override double derivative(double x) { - int i = locate(x); - return s_[i]; - } - public override double secondDerivative(double x) { return 0.0; } - } + public override double value(double x) + { + int i = locate(x); + double result = yBegin_[i] + (x - xBegin_[i]) * s_[i]; + return result; + } + public override double primitive(double x) + { + int i = locate(x); + double dx = x - xBegin_[i]; + return primitiveConst_[i] + dx * (yBegin_[i] + 0.5 * dx * s_[i]); + } + public override double derivative(double x) + { + int i = locate(x); + return s_[i]; + } + public override double secondDerivative(double x) { return 0.0; } + } - //! %Linear interpolation between discrete points - public class LinearInterpolation : Interpolation { - /*! \pre the \f$ x \f$ values must be sorted. */ - public LinearInterpolation(List xBegin, int size, List yBegin) { - impl_ = new LinearInterpolationImpl(xBegin, size, yBegin); - impl_.update(); - } - }; + //! %Linear interpolation between discrete points + public class LinearInterpolation : Interpolation + { + /*! \pre the \f$ x \f$ values must be sorted. */ + public LinearInterpolation(List xBegin, int size, List yBegin) + { + impl_ = new LinearInterpolationImpl(xBegin, size, yBegin); + impl_.update(); + } + } - //! %Linear-interpolation factory and traits - public class Linear : IInterpolationFactory { - public Interpolation interpolate(List xBegin, int size, List yBegin) { - return new LinearInterpolation(xBegin, size, yBegin); - } - public bool global { get { return false; } } - public int requiredPoints { get { return 2; } } - }; + //! %Linear-interpolation factory and traits + public class Linear : IInterpolationFactory + { + public Interpolation interpolate(List xBegin, int size, List yBegin) + { + return new LinearInterpolation(xBegin, size, yBegin); + } + public bool global { get { return false; } } + public int requiredPoints { get { return 2; } } + } } diff --git a/src/QLNet/Math/Interpolations/Loginterpolation.cs b/src/QLNet/Math/Interpolations/Loginterpolation.cs index 06f77a59f..3bc18c6d5 100644 --- a/src/QLNet/Math/Interpolations/Loginterpolation.cs +++ b/src/QLNet/Math/Interpolations/Loginterpolation.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,7 +23,7 @@ under the terms of the QLNet license. You should have received a namespace QLNet { public class LogInterpolationImpl : Interpolation.templateImpl - where Interpolator : IInterpolationFactory, new() + where Interpolator : IInterpolationFactory, new () { private List logY_; private Interpolation interpolation_; @@ -43,7 +43,7 @@ public override void update() { for (int i = 0; i < size_; ++i) { - Utils.QL_REQUIRE(yBegin_[i] > 0.0,()=> "invalid value (" + yBegin_[i] + ") at index " + i); + Utils.QL_REQUIRE(yBegin_[i] > 0.0, () => "invalid value (" + yBegin_[i] + ") at index " + i); logY_[i] = Math.Log(yBegin_[i]); } interpolation_.update(); @@ -81,14 +81,20 @@ public Interpolation interpolate(List xBegin, int size, List yBe public bool global { - get { return false; } + get + { + return false; + } } public int requiredPoints { - get { return 2; } + get + { + return 2; + } } - }; + } //! %log-linear interpolation between discrete points public class LogLinearInterpolation : Interpolation @@ -128,17 +134,23 @@ public LogCubic(CubicInterpolation.DerivativeApprox da, bool monotonic, public Interpolation interpolate(List xBegin, int size, List yBegin) { return new LogCubicInterpolation(xBegin, size, yBegin, da_, monotonic_, - leftType_, leftValue_, rightType_, rightValue_); + leftType_, leftValue_, rightType_, rightValue_); } public bool global { - get { return true; } + get + { + return true; + } } public int requiredPoints { - get { return 2; } + get + { + return 2; + } } } @@ -148,15 +160,15 @@ public class LogCubicInterpolation : Interpolation /*! \pre the \f$ x \f$ values must be sorted. */ public LogCubicInterpolation(List xBegin, int size, List yBegin, - CubicInterpolation.DerivativeApprox da, - bool monotonic, - CubicInterpolation.BoundaryCondition leftC, - double leftConditionValue, - CubicInterpolation.BoundaryCondition rightC, - double rightConditionValue) + CubicInterpolation.DerivativeApprox da, + bool monotonic, + CubicInterpolation.BoundaryCondition leftC, + double leftConditionValue, + CubicInterpolation.BoundaryCondition rightC, + double rightConditionValue) { impl_ = new LogInterpolationImpl(xBegin, size, yBegin, - new Cubic(da, monotonic, leftC, leftConditionValue, rightC, rightConditionValue)); + new Cubic(da, monotonic, leftC, leftConditionValue, rightC, rightConditionValue)); impl_.update(); } } diff --git a/src/QLNet/Math/Interpolations/MixedInterpolation.cs b/src/QLNet/Math/Interpolations/MixedInterpolation.cs index aac569873..424501522 100644 --- a/src/QLNet/Math/Interpolations/MixedInterpolation.cs +++ b/src/QLNet/Math/Interpolations/MixedInterpolation.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -30,92 +30,92 @@ whole range defined by the passed first part of the range, and the second interpolation over the second part. */ } - - public class MixedInterpolationImpl : Interpolation.templateImpl - where Interpolator1 : IInterpolationFactory,new() - where Interpolator2 : IInterpolationFactory,new() + + public class MixedInterpolationImpl : Interpolation.templateImpl + where Interpolator1 : IInterpolationFactory, new () + where Interpolator2 : IInterpolationFactory, new () { public MixedInterpolationImpl(List xBegin, int xEnd, List yBegin, int n, Behavior behavior = Behavior.ShareRanges, Interpolator1 factory1 = default(Interpolator1), Interpolator2 factory2 = default(Interpolator2)) - : base(xBegin, xEnd, yBegin, - Math.Max(factory1 == null ? (factory1 = new Interpolator1()).requiredPoints : factory1.requiredPoints, - factory2 == null ? (factory2 = new Interpolator2()).requiredPoints : factory2.requiredPoints)) + : base(xBegin, xEnd, yBegin, + Math.Max(factory1 == null ? (factory1 = new Interpolator1()).requiredPoints : factory1.requiredPoints, + factory2 == null ? (factory2 = new Interpolator2()).requiredPoints : factory2.requiredPoints)) { n_ = n; - xBegin2_ = xBegin.GetRange( n_, xBegin.Count); - yBegin2_ = yBegin.GetRange( n_, yBegin.Count ); + xBegin2_ = xBegin.GetRange(n_, xBegin.Count); + yBegin2_ = yBegin.GetRange(n_, yBegin.Count); - Utils.QL_REQUIRE( xBegin2_.Count < size_,()=> "too large n (" + n + ") for " + size_ + "-element x sequence"); + Utils.QL_REQUIRE(xBegin2_.Count < size_, () => "too large n (" + n + ") for " + size_ + "-element x sequence"); - switch (behavior) + switch (behavior) { case Behavior.ShareRanges: - interpolation1_ = factory1.interpolate(xBegin_,size_,yBegin_); - interpolation2_ = factory2.interpolate(xBegin_,size_,yBegin_); + interpolation1_ = factory1.interpolate(xBegin_, size_, yBegin_); + interpolation2_ = factory2.interpolate(xBegin_, size_, yBegin_); break; case Behavior.SplitRanges: - interpolation1_ = factory1.interpolate(xBegin_,xBegin2_.Count+1,yBegin_); - interpolation2_ = factory2.interpolate(xBegin2_,size_,yBegin2_); + interpolation1_ = factory1.interpolate(xBegin_, xBegin2_.Count + 1, yBegin_); + interpolation2_ = factory2.interpolate(xBegin2_, size_, yBegin2_); break; default: Utils.QL_FAIL("unknown mixed-interpolation behavior: " + behavior); break; } - } + } - public override void update() + public override void update() { interpolation1_.update(); interpolation2_.update(); } - - public override double value(double x) + + public override double value(double x) { if (x<(xBegin2_.First())) return interpolation1_.value(x, true); return interpolation2_.value(x, true); } - public override double primitive(double x) + public override double primitive(double x) { if (x<(xBegin2_.First())) return interpolation1_.primitive(x, true); return interpolation2_.primitive(x, true) - - interpolation2_.primitive(xBegin2_.First(), true) + - interpolation1_.primitive( xBegin2_.First(), true ); + interpolation2_.primitive(xBegin2_.First(), true) + + interpolation1_.primitive(xBegin2_.First(), true); } - public override double derivative(double x) + public override double derivative(double x) { - if ( x < ( xBegin2_.First() ) ) + if (x < (xBegin2_.First())) return interpolation1_.derivative(x, true); return interpolation2_.derivative(x, true); - } - - public override double secondDerivative(double x) + } + + public override double secondDerivative(double x) { - if ( x < ( xBegin2_.First() ) ) + if (x < (xBegin2_.First())) return interpolation1_.secondDerivative(x, true); return interpolation2_.secondDerivative(x, true); } public int switchIndex() { return n_; } - + private List xBegin2_; private List yBegin2_; private int n_; private Interpolation interpolation1_, interpolation2_; - + } - + //! mixed linear/cubic interpolation between discrete points - public class MixedLinearCubicInterpolation : Interpolation + public class MixedLinearCubicInterpolation : Interpolation { /*! \pre the \f$ x \f$ values must be sorted. */ public MixedLinearCubicInterpolation(List xBegin, int xEnd, @@ -126,18 +126,18 @@ public MixedLinearCubicInterpolation(List xBegin, int xEnd, CubicInterpolation.BoundaryCondition leftC, double leftConditionValue, CubicInterpolation.BoundaryCondition rightC, - double rightConditionValue) + double rightConditionValue) { - impl_ = new MixedInterpolationImpl(xBegin, xEnd, yBegin, n, behavior, - new Linear(), - new Cubic(da, monotonic,leftC, leftConditionValue,rightC, rightConditionValue)); - impl_.update(); - } - } - + impl_ = new MixedInterpolationImpl(xBegin, xEnd, yBegin, n, behavior, + new Linear(), + new Cubic(da, monotonic, leftC, leftConditionValue, rightC, rightConditionValue)); + impl_.update(); + } + } + //! mixed linear/cubic interpolation factory and traits /*! \ingroup interpolations */ - public class MixedLinearCubic + public class MixedLinearCubic { public MixedLinearCubic(int n, Behavior behavior, @@ -148,11 +148,11 @@ public MixedLinearCubic(int n, CubicInterpolation.BoundaryCondition rightCondition = CubicInterpolation.BoundaryCondition.SecondDerivative, double rightConditionValue = 0.0) { - n_ = n; - behavior_ = behavior; - da_ = da; + n_ = n; + behavior_ = behavior; + da_ = da; monotonic_ = monotonic; - leftType_ = leftCondition; + leftType_ = leftCondition; rightType_ = rightCondition; leftValue_ = leftConditionValue; rightValue_ = rightConditionValue; @@ -160,7 +160,7 @@ public MixedLinearCubic(int n, requiredPoints = 3; } - public Interpolation interpolate(List xBegin, int xEnd,List yBegin) + public Interpolation interpolate(List xBegin, int xEnd, List yBegin) { return new MixedLinearCubicInterpolation(xBegin, xEnd, yBegin, n_, behavior_, @@ -170,7 +170,7 @@ public Interpolation interpolate(List xBegin, int xEnd,List yBeg } // fix below - public bool global { get; set; } + public bool global { get; set; } public int requiredPoints { get; set; } private int n_; @@ -183,75 +183,75 @@ public Interpolation interpolate(List xBegin, int xEnd,List yBeg // convenience classes - public class MixedLinearCubicNaturalSpline : MixedLinearCubicInterpolation + public class MixedLinearCubicNaturalSpline : MixedLinearCubicInterpolation { /*! \pre the \f$ x \f$ values must be sorted. */ - public MixedLinearCubicNaturalSpline(List xBegin, int xEnd,List yBegin, int n, - Behavior behavior = Behavior.ShareRanges) - : base(xBegin, xEnd, yBegin, n, behavior, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) + public MixedLinearCubicNaturalSpline(List xBegin, int xEnd, List yBegin, int n, + Behavior behavior = Behavior.ShareRanges) + : base(xBegin, xEnd, yBegin, n, behavior, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) {} } - public class MixedLinearMonotonicCubicNaturalSpline : MixedLinearCubicInterpolation + public class MixedLinearMonotonicCubicNaturalSpline : MixedLinearCubicInterpolation { /*! \pre the \f$ x \f$ values must be sorted. */ - public MixedLinearMonotonicCubicNaturalSpline(List xBegin, int xEnd,List yBegin, int n, - Behavior behavior = Behavior.ShareRanges) - : base(xBegin, xEnd, yBegin, n, behavior, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) + public MixedLinearMonotonicCubicNaturalSpline(List xBegin, int xEnd, List yBegin, int n, + Behavior behavior = Behavior.ShareRanges) + : base(xBegin, xEnd, yBegin, n, behavior, + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) {} } - public class MixedLinearKrugerCubic : MixedLinearCubicInterpolation + public class MixedLinearKrugerCubic : MixedLinearCubicInterpolation { /*! \pre the \f$ x \f$ values must be sorted. */ - public MixedLinearKrugerCubic(List xBegin, int xEnd,List yBegin, int n, - Behavior behavior = Behavior.ShareRanges) - : base(xBegin, xEnd, yBegin, n, behavior, - CubicInterpolation.DerivativeApprox.Kruger, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) + public MixedLinearKrugerCubic(List xBegin, int xEnd, List yBegin, int n, + Behavior behavior = Behavior.ShareRanges) + : base(xBegin, xEnd, yBegin, n, behavior, + CubicInterpolation.DerivativeApprox.Kruger, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) {} } - public class MixedLinearFritschButlandCubic : MixedLinearCubicInterpolation + public class MixedLinearFritschButlandCubic : MixedLinearCubicInterpolation { /*! \pre the \f$ x \f$ values must be sorted. */ - public MixedLinearFritschButlandCubic(List xBegin, int xEnd,List yBegin, int n, - Behavior behavior = Behavior.ShareRanges ) - : base(xBegin, xEnd, yBegin, n, behavior, - CubicInterpolation.DerivativeApprox.FritschButland, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) + public MixedLinearFritschButlandCubic(List xBegin, int xEnd, List yBegin, int n, + Behavior behavior = Behavior.ShareRanges) + : base(xBegin, xEnd, yBegin, n, behavior, + CubicInterpolation.DerivativeApprox.FritschButland, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) {} } - public class MixedLinearParabolic : MixedLinearCubicInterpolation + public class MixedLinearParabolic : MixedLinearCubicInterpolation { /*! \pre the \f$ x \f$ values must be sorted. */ - public MixedLinearParabolic(List xBegin, int xEnd,List yBegin, int n, - Behavior behavior = Behavior.ShareRanges) - : base(xBegin, xEnd, yBegin, n, behavior, - CubicInterpolation.DerivativeApprox.Parabolic, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) + public MixedLinearParabolic(List xBegin, int xEnd, List yBegin, int n, + Behavior behavior = Behavior.ShareRanges) + : base(xBegin, xEnd, yBegin, n, behavior, + CubicInterpolation.DerivativeApprox.Parabolic, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) {} } - public class MixedLinearMonotonicParabolic : MixedLinearCubicInterpolation + public class MixedLinearMonotonicParabolic : MixedLinearCubicInterpolation { /*! \pre the \f$ x \f$ values must be sorted. */ - public MixedLinearMonotonicParabolic(List xBegin, int xEnd,List yBegin, int n, - Behavior behavior = Behavior.ShareRanges) - : base(xBegin, xEnd, yBegin, n, behavior, - CubicInterpolation.DerivativeApprox.Parabolic, true, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) + public MixedLinearMonotonicParabolic(List xBegin, int xEnd, List yBegin, int n, + Behavior behavior = Behavior.ShareRanges) + : base(xBegin, xEnd, yBegin, n, behavior, + CubicInterpolation.DerivativeApprox.Parabolic, true, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0) {} } diff --git a/src/QLNet/Math/Interpolations/multicubicspline.cs b/src/QLNet/Math/Interpolations/MultiCubicSpline.cs similarity index 79% rename from src/QLNet/Math/Interpolations/multicubicspline.cs rename to src/QLNet/Math/Interpolations/MultiCubicSpline.cs index 24d83f408..1674c4406 100644 --- a/src/QLNet/Math/Interpolations/multicubicspline.cs +++ b/src/QLNet/Math/Interpolations/MultiCubicSpline.cs @@ -1,27 +1,28 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System.Collections.Generic; -namespace QLNet { +namespace QLNet +{ - // data structures + // data structures - // Multi-cubic spline - public class SplineGrid : InitializedList> { } + // Multi-cubic spline + public class SplineGrid : InitializedList> { } } diff --git a/src/QLNet/Math/Interpolations/sabrinterpolation.cs b/src/QLNet/Math/Interpolations/SABRInterpolation.cs similarity index 54% rename from src/QLNet/Math/Interpolations/sabrinterpolation.cs rename to src/QLNet/Math/Interpolations/SABRInterpolation.cs index c0bd51957..530c90b34 100644 --- a/src/QLNet/Math/Interpolations/sabrinterpolation.cs +++ b/src/QLNet/Math/Interpolations/SABRInterpolation.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,7 +23,7 @@ namespace QLNet { public class SABRWrapper : IWrapper { - public SABRWrapper( double t, double forward, List param, List addParams ) + public SABRWrapper(double t, double forward, List < double? > param, List < double? > addParams) { t_ = t; forward_ = forward; @@ -34,27 +34,27 @@ public SABRWrapper( double t, double forward, List param, List if (volatilityType_ == VolatilityType.ShiftedLognormal) Utils.QL_REQUIRE(forward_ + shift_ > 0.0, () => "forward+shift must be positive: " - + forward_ + " with shift " - + shift_.Value + " not allowed"); + + forward_ + " with shift " + + shift_.Value + " not allowed"); - Utils.validateSabrParameters( param[0].Value, param[1].Value, param[2].Value, param[3].Value ); + Utils.validateSabrParameters(param[0].Value, param[1].Value, param[2].Value, param[3].Value); } - public double volatility( double x ) + public double volatility(double x) { - switch (volatilityType_) - { - case VolatilityType.ShiftedLognormal: - return Utils.shiftedSabrVolatility(x, forward_, t_, params_[0].Value, params_[1].Value, params_[2].Value, params_[3].Value, shift_.Value, approximationModel_); - case VolatilityType.Normal: - return Utils.shiftedSabrNormalVolatility(x, forward_, t_, params_[0].Value, params_[1].Value, params_[2].Value, params_[3].Value, shift_.Value); - default: - return Utils.sabrVolatility(x, forward_, t_, params_[0].Value, params_[1].Value, params_[2].Value, params_[3].Value); - } + switch (volatilityType_) + { + case VolatilityType.ShiftedLognormal: + return Utils.shiftedSabrVolatility(x, forward_, t_, params_[0].Value, params_[1].Value, params_[2].Value, params_[3].Value, shift_.Value, approximationModel_); + case VolatilityType.Normal: + return Utils.shiftedSabrNormalVolatility(x, forward_, t_, params_[0].Value, params_[1].Value, params_[2].Value, params_[3].Value, shift_.Value); + default: + return Utils.sabrVolatility(x, forward_, t_, params_[0].Value, params_[1].Value, params_[2].Value, params_[3].Value); + } } private double t_, forward_; private double? shift_; - private List params_; + private List < double? > params_; private VolatilityType volatilityType_; private SabrApproximationModel approximationModel_; } @@ -62,90 +62,90 @@ public double volatility( double x ) public struct SABRSpecs : IModel { public int dimension() { return 4; } - public void defaultValues(List param, List b, double forward, double expiryTime, List addParams) + public void defaultValues(List < double? > param, List b, double forward, double expiryTime, List < double? > addParams) { shift_ = addParams == null ? 0.0 : Convert.ToDouble(addParams[0]); volatilityType_ = addParams == null ? VolatilityType.ShiftedLognormal : (addParams[1] > 0.0 ? VolatilityType.Normal : VolatilityType.ShiftedLognormal); - if ( param[1] == null ) + if (param[1] == null) param[1] = 0.5; - if (param[0] == null) - { + if (param[0] == null) + { // adapt alpha to beta level - param[0] = 0.2 * (param[1] < 0.9999 && forward + shift_ > 0.0 - ? Math.Pow(forward + shift_ - , 1.0 - param[1].Value ) - : 1.0 ); + param[0] = 0.2 * (param[1] < 0.9999 && forward + shift_ > 0.0 + ? Math.Pow(forward + shift_ + , 1.0 - param[1].Value) + : 1.0); } - if ( param[2] == null ) - param[2] = Math.Sqrt( 0.4 ); - if ( param[3] == null ) + if (param[2] == null) + param[2] = Math.Sqrt(0.4); + if (param[3] == null) param[3] = 0.0; } - public void guess(Vector values, List paramIsFixed, double forward, double expiryTime, List r, List addParams) + public void guess(Vector values, List paramIsFixed, double forward, double expiryTime, List r, List < double? > addParams) { shift_ = addParams == null ? 0.0 : Convert.ToDouble(addParams[0]); volatilityType_ = addParams == null ? VolatilityType.ShiftedLognormal : (addParams[1] > 0.0 ? VolatilityType.Normal : VolatilityType.ShiftedLognormal); int j = 0; - if ( !paramIsFixed[1] ) - values[1] = ( 1.0 - 2E-6 ) * r[j++] + 1E-6; - if ( !paramIsFixed[0] ) + if (!paramIsFixed[1]) + values[1] = (1.0 - 2E-6) * r[j++] + 1E-6; + if (!paramIsFixed[0]) { - values[0] = ( 1.0 - 2E-6 ) * r[j++] + 1E-6; // lognormal vol guess + values[0] = (1.0 - 2E-6) * r[j++] + 1E-6; // lognormal vol guess // adapt this to beta level if (values[1] < 0.999 && forward + shift_ > 0.0) - values[0] *= Math.Pow(forward + shift_, - 1.0 - values[1] ); + values[0] *= Math.Pow(forward + shift_, + 1.0 - values[1]); } - if ( !paramIsFixed[2] ) + if (!paramIsFixed[2]) values[2] = 1.5 * r[j++] + 1E-6; - if ( !paramIsFixed[3] ) - values[3] = ( 2.0 * r[j++] - 1.0 ) * ( 1.0 - 1E-6 ); + if (!paramIsFixed[3]) + values[3] = (2.0 * r[j++] - 1.0) * (1.0 - 1E-6); } public double eps1() { return .0000001; } public double eps2() { return .9999; } public double dilationFactor() { return 0.001; } - public Vector inverse( Vector y, List b, List c, double d ) + public Vector inverse(Vector y, List b, List < double? > c, double d) { - Vector x = new Vector( 4 ); + Vector x = new Vector(4); x[0] = y[0] < 25.0 + eps1() ? Math.Sqrt(Math.Max(eps1(), y[0]) - eps1()) - : ( y[0] - eps1() + 25.0 ) / 10.0; - x[1] = y[1] == 0.0 ? 0.0 : Math.Sqrt( -Math.Log( y[1] ) ); - x[2] = y[2] < 25.0 + eps1() ? Math.Sqrt( y[2] - eps1() ) - : ( y[2] - eps1() + 25.0 ) / 10.0; - x[3] = Math.Asin( y[3] / eps2() ); + : (y[0] - eps1() + 25.0) / 10.0; + x[1] = y[1] == 0.0 ? 0.0 : Math.Sqrt(-Math.Log(y[1])); + x[2] = y[2] < 25.0 + eps1() ? Math.Sqrt(y[2] - eps1()) + : (y[2] - eps1() + 25.0) / 10.0; + x[3] = Math.Asin(y[3] / eps2()); return x; } - public Vector direct( Vector x, List b, List c, double d ) + public Vector direct(Vector x, List b, List < double? > c, double d) { - Vector y = new Vector( 4 ); - y[0] = Math.Abs( x[0] ) < 5.0 - ? x[0] * x[0] + eps1() - : ( 10.0 * Math.Abs( x[0] ) - 25.0 ) + eps1(); - y[1] = Math.Abs( x[1] ) < Math.Sqrt( -Math.Log( eps1() ) ) && x[1] != 0.0 - ? Math.Exp( -( x[1] * x[1] ) ) - : (volatilityType_ == VolatilityType.ShiftedLognormal ? eps1() : 0.0); - y[2] = Math.Abs( x[2] ) < 5.0 - ? x[2] * x[2] + eps1() - : ( 10.0 * Math.Abs( x[2] ) - 25.0 ) + eps1(); - y[3] = Math.Abs( x[3] ) < 2.5 * Const.M_PI - ? eps2() * Math.Sin( x[3] ) - : eps2() * ( x[3] > 0.0 ? 1.0 : ( -1.0 ) ); + Vector y = new Vector(4); + y[0] = Math.Abs(x[0]) < 5.0 + ? x[0] * x[0] + eps1() + : (10.0 * Math.Abs(x[0]) - 25.0) + eps1(); + y[1] = Math.Abs(x[1]) < Math.Sqrt(-Math.Log(eps1())) && x[1] != 0.0 + ? Math.Exp(-(x[1] * x[1])) + : (volatilityType_ == VolatilityType.ShiftedLognormal ? eps1() : 0.0); + y[2] = Math.Abs(x[2]) < 5.0 + ? x[2] * x[2] + eps1() + : (10.0 * Math.Abs(x[2]) - 25.0) + eps1(); + y[3] = Math.Abs(x[3]) < 2.5 * Const.M_PI + ? eps2() * Math.Sin(x[3]) + : eps2() * (x[3] > 0.0 ? 1.0 : (-1.0)); return y; } - public IWrapper instance( double t, double forward, List param, List addParams ) + public IWrapper instance(double t, double forward, List < double? > param, List < double? > addParams) { shift_ = addParams == null ? 0.0 : Convert.ToDouble(addParams[0]); volatilityType_ = addParams == null ? VolatilityType.ShiftedLognormal : (addParams[1] > 0.0 ? VolatilityType.Normal : VolatilityType.ShiftedLognormal); - return new SABRWrapper( t, forward, param, addParams ); + return new SABRWrapper(t, forward, param, addParams); } - public double weight(double strike, double forward, double stdDev, List addParams) + public double weight(double strike, double forward, double stdDev, List < double? > addParams) { - if (Convert.ToDouble(addParams[1]) == 0.0) - return Utils.blackFormulaStdDevDerivative(strike, forward, stdDev, 1.0, addParams[0].Value); - else - return Utils.bachelierBlackFormulaStdDevDerivative(strike, forward, stdDev, 1.0); + if (Convert.ToDouble(addParams[1]) == 0.0) + return Utils.blackFormulaStdDevDerivative(strike, forward, stdDev, 1.0, addParams[0].Value); + else + return Utils.bachelierBlackFormulaStdDevDerivative(strike, forward, stdDev, 1.0); } private VolatilityType volatilityType_; @@ -156,7 +156,7 @@ public double weight(double strike, double forward, double stdDev, List // For volatility type Normal and when the forward < 0, it is suggested to fix beta = 0.0 public class SABRInterpolation : Interpolation { - public SABRInterpolation( List xBegin, // x = strikes + public SABRInterpolation(List xBegin, // x = strikes int xEnd, List yBegin, // y = volatilities double t, // option expiry @@ -177,23 +177,23 @@ public SABRInterpolation( List xBegin, // x = strikes int maxGuesses = 50, double shift = 0.0, VolatilityType volatilityType = VolatilityType.ShiftedLognormal, - SabrApproximationModel approximationModel = SabrApproximationModel.Hagan2002) + SabrApproximationModel approximationModel = SabrApproximationModel.Hagan2002) { - List addParams = new List(); - addParams.Add(shift); - addParams.Add(volatilityType == VolatilityType.ShiftedLognormal ? 0.0 : 1.0); - addParams.Add((double?)approximationModel); + List < double? > addParams = new List < double? >(); + addParams.Add(shift); + addParams.Add(volatilityType == VolatilityType.ShiftedLognormal ? 0.0 : 1.0); + addParams.Add((double?)approximationModel); - impl_ = new XABRInterpolationImpl( - xBegin, xEnd, yBegin, t, forward, - new List(){alpha,beta,nu,rho}, - //boost::assign::list_of(alpha)(beta)(nu)(rho), - new List(){alphaIsFixed,betaIsFixed,nuIsFixed,rhoIsFixed}, - //boost::assign::list_of(alphaIsFixed)(betaIsFixed)(nuIsFixed)(rhoIsFixed), - vegaWeighted, endCriteria, optMethod, errorAccept, useMaxError, - maxGuesses, addParams); - coeffs_ = (impl_ as XABRInterpolationImpl).coeff_; - } + impl_ = new XABRInterpolationImpl( + xBegin, xEnd, yBegin, t, forward, + new List < double? >() {alpha, beta, nu, rho}, + //boost::assign::list_of(alpha)(beta)(nu)(rho), + new List() {alphaIsFixed, betaIsFixed, nuIsFixed, rhoIsFixed}, + //boost::assign::list_of(alphaIsFixed)(betaIsFixed)(nuIsFixed)(rhoIsFixed), + vegaWeighted, endCriteria, optMethod, errorAccept, useMaxError, + maxGuesses, addParams); + coeffs_ = (impl_ as XABRInterpolationImpl).coeff_; + } public double expiry() { return coeffs_.t_; } public double forward() { return coeffs_.forward_; } public double alpha() { return coeffs_.params_[0].Value; } @@ -209,7 +209,7 @@ public SABRInterpolation( List xBegin, // x = strikes } //! %SABR interpolation factory and traits - public class SABR + public class SABR { public SABR(double t, double forward, double alpha, double beta, double nu, double rho, bool alphaIsFixed, bool betaIsFixed, bool nuIsFixed, bool rhoIsFixed, @@ -220,37 +220,37 @@ public SABR(double t, double forward, double alpha, double beta, double nu, doub VolatilityType volatilityType = VolatilityType.ShiftedLognormal, SabrApproximationModel approximationModel = SabrApproximationModel.Hagan2002) { - t_ = t; + t_ = t; forward_ = forward; - alpha_ = alpha; - beta_ = beta; - nu_ = nu; + alpha_ = alpha; + beta_ = beta; + nu_ = nu; rho_ = rho; - alphaIsFixed_ = alphaIsFixed; + alphaIsFixed_ = alphaIsFixed; betaIsFixed_ = betaIsFixed; - nuIsFixed_ = nuIsFixed; + nuIsFixed_ = nuIsFixed; rhoIsFixed_ = rhoIsFixed; vegaWeighted_ = vegaWeighted; endCriteria_ = endCriteria; - optMethod_ = optMethod; + optMethod_ = optMethod; errorAccept_ = errorAccept; - useMaxError_ = useMaxError; + useMaxError_ = useMaxError; maxGuesses_ = maxGuesses; shift_ = shift; volatilityType_ = volatilityType; approximationModel_ = approximationModel; } - public Interpolation interpolate(List xBegin, int xEnd,List yBegin) + public Interpolation interpolate(List xBegin, int xEnd, List yBegin) { - return new SABRInterpolation( xBegin, xEnd, yBegin, t_, forward_, alpha_, beta_, nu_, rho_, - alphaIsFixed_, betaIsFixed_, nuIsFixed_, rhoIsFixed_, vegaWeighted_, - endCriteria_, optMethod_, errorAccept_, useMaxError_, maxGuesses_, shift_, - volatilityType_, approximationModel_); + return new SABRInterpolation(xBegin, xEnd, yBegin, t_, forward_, alpha_, beta_, nu_, rho_, + alphaIsFixed_, betaIsFixed_, nuIsFixed_, rhoIsFixed_, vegaWeighted_, + endCriteria_, optMethod_, errorAccept_, useMaxError_, maxGuesses_, shift_, + volatilityType_, approximationModel_); } - + public const bool global = true; - + private double t_; private double shift_; private double forward_; @@ -264,6 +264,6 @@ public Interpolation interpolate(List xBegin, int xEnd,List yBeg private int maxGuesses_; private VolatilityType volatilityType_; private SabrApproximationModel approximationModel_; - } + } } diff --git a/src/QLNet/Math/Interpolations/SviInterpolation.cs b/src/QLNet/Math/Interpolations/SviInterpolation.cs index 6615b31b3..624a66f2c 100644 --- a/src/QLNet/Math/Interpolations/SviInterpolation.cs +++ b/src/QLNet/Math/Interpolations/SviInterpolation.cs @@ -1,225 +1,225 @@ -/* - Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) - 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. +/* + Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) + 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; using System.Collections.Generic; namespace QLNet { - public class SVIWrapper : IWrapper - { - public SVIWrapper(double t, double forward, List param, List addParams) - { - t_ = t; - forward_ = forward; - params_ = param; - Utils.checkSviParameters(param[0].Value, param[1].Value, param[2].Value, param[3].Value, param[4].Value); - } - public double volatility(double x) - { - return Utils.sviVolatility(x, forward_, t_, params_); - } + public class SVIWrapper : IWrapper + { + public SVIWrapper(double t, double forward, List < double? > param, List < double? > addParams) + { + t_ = t; + forward_ = forward; + params_ = param; + Utils.checkSviParameters(param[0].Value, param[1].Value, param[2].Value, param[3].Value, param[4].Value); + } + public double volatility(double x) + { + return Utils.sviVolatility(x, forward_, t_, params_); + } - private double t_, forward_; - private List params_; - } + private double t_, forward_; + private List < double? > params_; + } - public struct SVISpecs : IModel - { - public int dimension() { return 5; } - public void defaultValues(List param, List paramIsFixed, double forward, double expiryTime, List addParams) - { - if (param[2] == null) - param[2] = 0.1; - if (param[3] == null) - param[3] = -0.4; - if (param[4] == null) - param[4] = 0.0; - if (param[1] == null) - param[1] = 2.0 / (1.0 + Math.Abs(Convert.ToDouble(param[3]))); - if (param[0] == null) - param[0] = Math.Max(0.20 * 0.20 * expiryTime - - (double)param[1] * ((double)param[3] * (-(double)param[4]) + - Math.Sqrt((-(double)param[4]) * (-(double)param[4]) + - (double)param[2] * (double)param[2])), - -(double)param[1] * (double)param[2] * - Math.Sqrt(1.0 - (double)param[3] * (double)param[3]) + eps1()); - } + public struct SVISpecs : IModel + { + public int dimension() { return 5; } + public void defaultValues(List < double? > param, List paramIsFixed, double forward, double expiryTime, List < double? > addParams) + { + if (param[2] == null) + param[2] = 0.1; + if (param[3] == null) + param[3] = -0.4; + if (param[4] == null) + param[4] = 0.0; + if (param[1] == null) + param[1] = 2.0 / (1.0 + Math.Abs(Convert.ToDouble(param[3]))); + if (param[0] == null) + param[0] = Math.Max(0.20 * 0.20 * expiryTime - + (double)param[1] * ((double)param[3] * (-(double)param[4]) + + Math.Sqrt((-(double)param[4]) * (-(double)param[4]) + + (double)param[2] * (double)param[2])), + -(double)param[1] * (double)param[2] * + Math.Sqrt(1.0 - (double)param[3] * (double)param[3]) + eps1()); + } - public void guess(Vector values, List paramIsFixed, double forward, double expiryTime, List r, List addParams) - { - int j = 0; - if (!paramIsFixed[2]) - values[2] = r[j++] + eps1(); - if (!paramIsFixed[3]) - values[3] = (2.0 * r[j++] - 1.0) * eps2(); - if (!paramIsFixed[4]) - values[4] = (2.0 * r[j++] - 1.0); - if (!paramIsFixed[1]) - values[1] = r[j++] * 4.0 / (1.0 + Math.Abs(values[3])) * eps2(); - if (!paramIsFixed[0]) - values[0] = r[j++] * expiryTime - - eps2() * (values[1] * values[2] * - Math.Sqrt(1.0 - values[3] * values[3])); - } - public double eps1() { return 0.000001; } - public double eps2() { return 0.999999; } - public double dilationFactor() { return 0.001; } - public Vector inverse(Vector y, List b, List c, double d) - { - Vector x = new Vector(5); - x[2] = Math.Sqrt(y[2] - eps1()); - x[3] = Math.Asin(y[3] / eps2()); - x[4] = y[4]; - x[1] = Math.Tan(y[1] / 4.0 * (1.0 + Math.Abs(y[3])) / eps2() * Const.M_PI - - Const.M_PI / 2.0); - x[0] = Math.Sqrt(y[0] - eps1() + - y[1] * y[2] * Math.Sqrt(1.0 - y[3] * y[3])); - return x; - } - public Vector direct(Vector x, List paramIsFixed, List param, double forward) - { - Vector y = new Vector(5); - y[2] = x[2] * x[2] + eps1(); - y[3] = Math.Sin(x[3]) * eps2(); - y[4] = x[4]; - if (paramIsFixed[1]) - y[1] = Convert.ToDouble(param[1]); - else - y[1] = (Math.Atan(x[1]) + Const.M_PI / 2.0) / Const.M_PI * eps2() * 4.0 / - (1.0 + Math.Abs(y[3])); - if (paramIsFixed[0]) - y[0] = Convert.ToDouble(param[0]); - else - y[0] = eps1() + x[0] * x[0] - - y[1] * y[2] * Math.Sqrt(1.0 - y[3] * y[3]); - return y; - } - public IWrapper instance(double t, double forward, List param, List addParams) - { - return new SVIWrapper(t, forward, param, addParams); - } - public double weight(double strike, double forward, double stdDev, List addParams) - { - return Utils.blackFormulaStdDevDerivative(strike, forward, stdDev, 1.0); - } - public SVIWrapper modelInstance_ { get; set; } - } + public void guess(Vector values, List paramIsFixed, double forward, double expiryTime, List r, List < double? > addParams) + { + int j = 0; + if (!paramIsFixed[2]) + values[2] = r[j++] + eps1(); + if (!paramIsFixed[3]) + values[3] = (2.0 * r[j++] - 1.0) * eps2(); + if (!paramIsFixed[4]) + values[4] = (2.0 * r[j++] - 1.0); + if (!paramIsFixed[1]) + values[1] = r[j++] * 4.0 / (1.0 + Math.Abs(values[3])) * eps2(); + if (!paramIsFixed[0]) + values[0] = r[j++] * expiryTime - + eps2() * (values[1] * values[2] * + Math.Sqrt(1.0 - values[3] * values[3])); + } + public double eps1() { return 0.000001; } + public double eps2() { return 0.999999; } + public double dilationFactor() { return 0.001; } + public Vector inverse(Vector y, List b, List < double? > c, double d) + { + Vector x = new Vector(5); + x[2] = Math.Sqrt(y[2] - eps1()); + x[3] = Math.Asin(y[3] / eps2()); + x[4] = y[4]; + x[1] = Math.Tan(y[1] / 4.0 * (1.0 + Math.Abs(y[3])) / eps2() * Const.M_PI - + Const.M_PI / 2.0); + x[0] = Math.Sqrt(y[0] - eps1() + + y[1] * y[2] * Math.Sqrt(1.0 - y[3] * y[3])); + return x; + } + public Vector direct(Vector x, List paramIsFixed, List < double? > param, double forward) + { + Vector y = new Vector(5); + y[2] = x[2] * x[2] + eps1(); + y[3] = Math.Sin(x[3]) * eps2(); + y[4] = x[4]; + if (paramIsFixed[1]) + y[1] = Convert.ToDouble(param[1]); + else + y[1] = (Math.Atan(x[1]) + Const.M_PI / 2.0) / Const.M_PI * eps2() * 4.0 / + (1.0 + Math.Abs(y[3])); + if (paramIsFixed[0]) + y[0] = Convert.ToDouble(param[0]); + else + y[0] = eps1() + x[0] * x[0] - + y[1] * y[2] * Math.Sqrt(1.0 - y[3] * y[3]); + return y; + } + public IWrapper instance(double t, double forward, List < double? > param, List < double? > addParams) + { + return new SVIWrapper(t, forward, param, addParams); + } + public double weight(double strike, double forward, double stdDev, List < double? > addParams) + { + return Utils.blackFormulaStdDevDerivative(strike, forward, stdDev, 1.0); + } + public SVIWrapper modelInstance_ { get; set; } + } - //! %SABR smile interpolation between discrete volatility points. - public class SviInterpolation : Interpolation - { - public SviInterpolation(List xBegin, // x = strikes - int size, - List yBegin, // y = volatilities - double t, // option expiry - double forward, - double? a, - double? b, - double? sigma, - double? rho, - double? m, - bool aIsFixed, - bool bIsFixed, - bool sigmaIsFixed, - bool rhoIsFixed, - bool mIsFixed, bool vegaWeighted = true, - EndCriteria endCriteria = null, - OptimizationMethod optMethod = null, - double errorAccept = 0.0020, - bool useMaxError = false, - int maxGuesses = 50, - List addParams = null) - { + //! %SABR smile interpolation between discrete volatility points. + public class SviInterpolation : Interpolation + { + public SviInterpolation(List xBegin, // x = strikes + int size, + List yBegin, // y = volatilities + double t, // option expiry + double forward, + double? a, + double? b, + double? sigma, + double? rho, + double? m, + bool aIsFixed, + bool bIsFixed, + bool sigmaIsFixed, + bool rhoIsFixed, + bool mIsFixed, bool vegaWeighted = true, + EndCriteria endCriteria = null, + OptimizationMethod optMethod = null, + double errorAccept = 0.0020, + bool useMaxError = false, + int maxGuesses = 50, + List < double? > addParams = null) + { - impl_ = new XABRInterpolationImpl( - xBegin, size, yBegin, t, forward, - new List() { a, b, sigma, rho, m }, - new List() { aIsFixed, bIsFixed, sigmaIsFixed, rhoIsFixed, mIsFixed }, - vegaWeighted, endCriteria, optMethod, errorAccept, useMaxError, - maxGuesses, addParams); - coeffs_ = (impl_ as XABRInterpolationImpl).coeff_; - } - public double expiry() { return coeffs_.t_; } - public double forward() { return coeffs_.forward_; } - public double a() { return coeffs_.params_[0].Value; } - public double b() { return coeffs_.params_[1].Value; } - public double sigma() { return coeffs_.params_[2].Value; } - public double rho() { return coeffs_.params_[3].Value; } - public double m() { return coeffs_.params_[4].Value; } - public double rmsError() { return coeffs_.error_.Value; } - public double maxError() { return coeffs_.maxError_.Value; } - public List interpolationWeights() { return coeffs_.weights_; } - public EndCriteria.Type endCriteria() { return coeffs_.XABREndCriteria_; } + impl_ = new XABRInterpolationImpl( + xBegin, size, yBegin, t, forward, + new List < double? >() { a, b, sigma, rho, m }, + new List() { aIsFixed, bIsFixed, sigmaIsFixed, rhoIsFixed, mIsFixed }, + vegaWeighted, endCriteria, optMethod, errorAccept, useMaxError, + maxGuesses, addParams); + coeffs_ = (impl_ as XABRInterpolationImpl).coeff_; + } + public double expiry() { return coeffs_.t_; } + public double forward() { return coeffs_.forward_; } + public double a() { return coeffs_.params_[0].Value; } + public double b() { return coeffs_.params_[1].Value; } + public double sigma() { return coeffs_.params_[2].Value; } + public double rho() { return coeffs_.params_[3].Value; } + public double m() { return coeffs_.params_[4].Value; } + public double rmsError() { return coeffs_.error_.Value; } + public double maxError() { return coeffs_.maxError_.Value; } + public List interpolationWeights() { return coeffs_.weights_; } + public EndCriteria.Type endCriteria() { return coeffs_.XABREndCriteria_; } - private XABRCoeffHolder coeffs_; - } + private XABRCoeffHolder coeffs_; + } - //! %SABR interpolation factory and traits - public class SVI - { - public SVI(double t, double forward, double a, double b, double sigma, double rho, double m, - bool aIsFixed, bool bIsFixed, bool sigmaIsFixed, bool rhoIsFixed, bool mIsFixed, - bool vegaWeighted = false, - EndCriteria endCriteria = null, - OptimizationMethod optMethod = null, - double errorAccept = 0.0020, bool useMaxError = false, int maxGuesses = 50, List addParams = null) - { - t_ = t; - forward_ = forward; - a_ = a; - b_ = b; - sigma_ = sigma; - rho_ = rho; - m_ = m; - aIsFixed_ = aIsFixed; - bIsFixed_ = bIsFixed; - sigmaIsFixed_ = sigmaIsFixed; - rhoIsFixed_ = rhoIsFixed; - mIsFixed_ = mIsFixed; - vegaWeighted_ = vegaWeighted; - endCriteria_ = endCriteria; - optMethod_ = optMethod; - errorAccept_ = errorAccept; - useMaxError_ = useMaxError; - maxGuesses_ = maxGuesses; - addParams_ = addParams; - } + //! %SABR interpolation factory and traits + public class SVI + { + public SVI(double t, double forward, double a, double b, double sigma, double rho, double m, + bool aIsFixed, bool bIsFixed, bool sigmaIsFixed, bool rhoIsFixed, bool mIsFixed, + bool vegaWeighted = false, + EndCriteria endCriteria = null, + OptimizationMethod optMethod = null, + double errorAccept = 0.0020, bool useMaxError = false, int maxGuesses = 50, List < double? > addParams = null) + { + t_ = t; + forward_ = forward; + a_ = a; + b_ = b; + sigma_ = sigma; + rho_ = rho; + m_ = m; + aIsFixed_ = aIsFixed; + bIsFixed_ = bIsFixed; + sigmaIsFixed_ = sigmaIsFixed; + rhoIsFixed_ = rhoIsFixed; + mIsFixed_ = mIsFixed; + vegaWeighted_ = vegaWeighted; + endCriteria_ = endCriteria; + optMethod_ = optMethod; + errorAccept_ = errorAccept; + useMaxError_ = useMaxError; + maxGuesses_ = maxGuesses; + addParams_ = addParams; + } - public Interpolation interpolate(List xBegin, int xEnd, List yBegin) - { - return new SviInterpolation(xBegin, xEnd, yBegin, t_, forward_, a_, b_, sigma_, rho_, m_, - aIsFixed_, bIsFixed_, sigmaIsFixed_, rhoIsFixed_, mIsFixed_, vegaWeighted_, - endCriteria_, optMethod_, errorAccept_, useMaxError_, maxGuesses_); - } - public const bool global = true; + public Interpolation interpolate(List xBegin, int xEnd, List yBegin) + { + return new SviInterpolation(xBegin, xEnd, yBegin, t_, forward_, a_, b_, sigma_, rho_, m_, + aIsFixed_, bIsFixed_, sigmaIsFixed_, rhoIsFixed_, mIsFixed_, vegaWeighted_, + endCriteria_, optMethod_, errorAccept_, useMaxError_, maxGuesses_); + } + public const bool global = true; - private double t_; - private double forward_; - private double a_, b_, sigma_, rho_, m_; - private bool aIsFixed_, bIsFixed_, sigmaIsFixed_, rhoIsFixed_, mIsFixed_; - private bool vegaWeighted_; - private EndCriteria endCriteria_; - private OptimizationMethod optMethod_; - private double errorAccept_; - private bool useMaxError_; - private int maxGuesses_; - private List addParams_; - } + private double t_; + private double forward_; + private double a_, b_, sigma_, rho_, m_; + private bool aIsFixed_, bIsFixed_, sigmaIsFixed_, rhoIsFixed_, mIsFixed_; + private bool vegaWeighted_; + private EndCriteria endCriteria_; + private OptimizationMethod optMethod_; + private double errorAccept_; + private bool useMaxError_; + private int maxGuesses_; + private List < double? > addParams_; + } } \ No newline at end of file diff --git a/src/QLNet/Math/Interpolations/VannaVolgaInterpolation.cs b/src/QLNet/Math/Interpolations/VannaVolgaInterpolation.cs index 3656238ae..bcc487df7 100644 --- a/src/QLNet/Math/Interpolations/VannaVolgaInterpolation.cs +++ b/src/QLNet/Math/Interpolations/VannaVolgaInterpolation.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,8 +21,8 @@ namespace QLNet public class VannaVolgaInterpolationImpl : Interpolation.templateImpl { public VannaVolgaInterpolationImpl(List xBegin, int size, List yBegin, - double spot, double dDiscount, double fDiscount, double T) - : base(xBegin, size, yBegin, VannaVolga.requiredPoints) + double spot, double dDiscount, double fDiscount, double T) + : base(xBegin, size, yBegin, VannaVolga.requiredPoints) { spot_ = spot; dDiscount_ = dDiscount; @@ -32,60 +32,60 @@ public VannaVolgaInterpolationImpl(List xBegin, int size, List y premiaBS = new List(); premiaMKT = new List(); vegas = new List(); - - Utils.QL_REQUIRE(size == 3, ()=> "Vanna Volga Interpolator only interpolates 3 volatilities in strike space"); + + Utils.QL_REQUIRE(size == 3, () => "Vanna Volga Interpolator only interpolates 3 volatilities in strike space"); } - public override void update() + public override void update() { //atmVol should be the second vol atmVol_ = this.yBegin_[1]; - fwd_ = spot_*fDiscount_/dDiscount_; - for(int i = 0; i < 3; i++) + fwd_ = spot_ * fDiscount_ / dDiscount_; + for (int i = 0; i < 3; i++) { premiaBS.Add(Utils.blackFormula(Option.Type.Call, xBegin_[i], fwd_, atmVol_ * Math.Sqrt(T_), dDiscount_)); premiaMKT.Add(Utils.blackFormula(Option.Type.Call, xBegin_[i], fwd_, yBegin_[i] * Math.Sqrt(T_), dDiscount_)); vegas.Add(vega(xBegin_[i])); } } - - public override double value(double k) + + public override double value(double k) { - double x1 = vega(k)/vegas[0] - * (Math.Log(xBegin_[1]/k) * Math.Log(xBegin_[2]/k)) - / (Math.Log(xBegin_[1]/xBegin_[0]) * Math.Log(xBegin_[2]/xBegin_[0])); - double x2 = vega(k)/vegas[1] - * (Math.Log(k/xBegin_[0]) * Math.Log(xBegin_[2]/k)) - / (Math.Log(xBegin_[1]/xBegin_[0]) * Math.Log(xBegin_[2]/xBegin_[1])); - double x3 = vega(k)/vegas[2] - * (Math.Log(k/xBegin_[0]) * Math.Log(k/xBegin_[1])) - / (Math.Log(xBegin_[2]/xBegin_[0]) * Math.Log(xBegin_[2]/xBegin_[1])); + double x1 = vega(k) / vegas[0] + * (Math.Log(xBegin_[1] / k) * Math.Log(xBegin_[2] / k)) + / (Math.Log(xBegin_[1] / xBegin_[0]) * Math.Log(xBegin_[2] / xBegin_[0])); + double x2 = vega(k) / vegas[1] + * (Math.Log(k / xBegin_[0]) * Math.Log(xBegin_[2] / k)) + / (Math.Log(xBegin_[1] / xBegin_[0]) * Math.Log(xBegin_[2] / xBegin_[1])); + double x3 = vega(k) / vegas[2] + * (Math.Log(k / xBegin_[0]) * Math.Log(k / xBegin_[1])) + / (Math.Log(xBegin_[2] / xBegin_[0]) * Math.Log(xBegin_[2] / xBegin_[1])); double cBS = Utils.blackFormula(Option.Type.Call, k, fwd_, atmVol_ * Math.Sqrt(T_), dDiscount_); - double c = cBS + x1*(premiaMKT[0] - premiaBS[0]) + x2*(premiaMKT[1] - premiaBS[1]) + x3*(premiaMKT[2] - premiaBS[2]); + double c = cBS + x1 * (premiaMKT[0] - premiaBS[0]) + x2 * (premiaMKT[1] - premiaBS[1]) + x3 * (premiaMKT[2] - premiaBS[2]); double std = Utils.blackFormulaImpliedStdDev(Option.Type.Call, k, fwd_, c, dDiscount_); return std / Math.Sqrt(T_); } - public override double primitive(double x) + public override double primitive(double x) { Utils.QL_FAIL("Vanna Volga primitive not implemented"); return 0; } - public override double derivative(double x) + public override double derivative(double x) { Utils.QL_FAIL("Vanna Volga derivative not implemented"); return 0; } - - public override double secondDerivative(double x) + + public override double secondDerivative(double x) { Utils.QL_FAIL("Vanna Volga secondDerivative not implemented"); return 0; } - + private List premiaBS; private List premiaMKT; private List vegas; @@ -96,30 +96,30 @@ public override double secondDerivative(double x) private double fDiscount_; private double T_; - private double vega(double k) + private double vega(double k) { - double d1 = (Math.Log(fwd_/k) + 0.5 * Math.Pow(atmVol_, 2.0) * T_)/(atmVol_ * Math.Sqrt(T_)); + double d1 = (Math.Log(fwd_ / k) + 0.5 * Math.Pow(atmVol_, 2.0) * T_) / (atmVol_ * Math.Sqrt(T_)); NormalDistribution norm = new NormalDistribution(); return spot_ * dDiscount_ * Math.Sqrt(T_) * norm.value(d1); } - + } public class VannaVolgaInterpolation : Interpolation { /*! \pre the \f$ x \f$ values must be sorted. */ public VannaVolgaInterpolation(List xBegin, int size, List yBegin, - double spot,double dDiscount,double fDiscount,double T) + double spot, double dDiscount, double fDiscount, double T) { - impl_ = new VannaVolgaInterpolationImpl( xBegin, size, yBegin, spot, dDiscount, fDiscount, T); + impl_ = new VannaVolgaInterpolationImpl(xBegin, size, yBegin, spot, dDiscount, fDiscount, T); impl_.update(); } } //! %VannaVolga-interpolation factory and traits - public class VannaVolga + public class VannaVolga { - public VannaVolga(double spot,double dDiscount,double fDiscount,double T) + public VannaVolga(double spot, double dDiscount, double fDiscount, double T) { spot_ = spot; dDiscount_ = dDiscount; @@ -127,16 +127,16 @@ public VannaVolga(double spot,double dDiscount,double fDiscount,double T) T_ = T; } - public Interpolation interpolate(List xBegin, int size,List yBegin) + public Interpolation interpolate(List xBegin, int size, List yBegin) { return new VannaVolgaInterpolation(xBegin, size, yBegin, spot_, dDiscount_, fDiscount_, T_); } - + public const int requiredPoints = 3; - + private double spot_; private double dDiscount_; private double fDiscount_; private double T_; - } + } } diff --git a/src/QLNet/Math/Interpolations/XABRInterpolation.cs b/src/QLNet/Math/Interpolations/XABRInterpolation.cs index 616ab6244..b7a4c4c20 100644 --- a/src/QLNet/Math/Interpolations/XABRInterpolation.cs +++ b/src/QLNet/Math/Interpolations/XABRInterpolation.cs @@ -1,21 +1,23 @@ /* - Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) + Copyright (C) 2008-2018 Andrea Maggiulli (a.maggiulli@gmail.com) + Copyright (C) 2018 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ + using System; using System.Collections.Generic; using System.Linq; @@ -24,31 +26,35 @@ namespace QLNet { public interface IWrapper { - double volatility( double x ); + double volatility(double x); } public interface IModel { - void defaultValues( List param, List b, double forward, double expiryTime, List addParams ); + void defaultValues(List < double? > param, List b, double forward, double expiryTime, List < double? > addParams); double dilationFactor(); int dimension(); - Vector direct( Vector x, List b, List c, double d ); + Vector direct(Vector x, List b, List < double? > c, double d); double eps1(); double eps2(); - void guess(Vector values, List paramIsFixed, double forward, double expiryTime, List r, List addParams); - IWrapper instance( double t, double forward, List param, List addParams ); - Vector inverse( Vector y, List b, List c, double d ); - double weight(double strike, double forward, double stdDev, List addParams); + + void guess(Vector values, List paramIsFixed, double forward, double expiryTime, List r, + List < double? > addParams); + + IWrapper instance(double t, double forward, List < double? > param, List < double? > addParams); + Vector inverse(Vector y, List b, List < double? > c, double d); + double weight(double strike, double forward, double stdDev, List < double? > addParams); } - public class XABRCoeffHolder where Model : IModel, new() + public class XABRCoeffHolder where Model : IModel, new () { - public XABRCoeffHolder( double t, double forward, List _params, List paramIsFixed, List addParams ) + public XABRCoeffHolder(double t, double forward, List < double? > _params, List paramIsFixed, + List < double? > addParams) { t_ = t; forward_ = forward; params_ = _params; - paramIsFixed_ = new InitializedList( paramIsFixed.Count, false ); + paramIsFixed_ = new InitializedList(paramIsFixed.Count, false); addParams_ = addParams; weights_ = new List(); error_ = null; @@ -56,16 +62,16 @@ public XABRCoeffHolder( double t, double forward, List _params, List.Create(); - Utils.QL_REQUIRE( t > 0.0, () => "expiry time must be positive: " + t + " not allowed" ); + Utils.QL_REQUIRE(t > 0.0, () => "expiry time must be positive: " + t + " not allowed"); Utils.QL_REQUIRE(_params.Count == model_.dimension(), () => - "wrong number of parameters (" + _params.Count + "), should be " + model_.dimension()); + "wrong number of parameters (" + _params.Count + "), should be " + model_.dimension()); Utils.QL_REQUIRE(paramIsFixed.Count == model_.dimension(), () => - "wrong number of fixed parameters flags (" + paramIsFixed.Count + "), should be " + - model_.dimension()); + "wrong number of fixed parameters flags (" + paramIsFixed.Count + "), should be " + + model_.dimension()); - for ( int i = 0; i < _params.Count; ++i ) + for (int i = 0; i < _params.Count; ++i) { - if ( _params[i] != null ) + if (_params[i] != null) paramIsFixed_[i] = paramIsFixed[i]; } @@ -81,220 +87,239 @@ public void updateModelInstance() /*! Expiry, Forward */ public double t_ { get; set; } + public double forward_ { get; set; } + /*! Parameters */ - public List params_ { get; set; } + public List < double? > params_ { get; set; } public List paramIsFixed_ { get; set; } - public List addParams_ { get; set; } + public List < double? > addParams_ { get; set; } + public List weights_ { get; set; } + /*! Interpolation results */ public double? error_ { get; set; } public double? maxError_ { get; set; } + public EndCriteria.Type XABREndCriteria_ { get; set; } + /*! Model instance (if required) */ public IWrapper modelInstance_ { get; set; } public IModel model_ { get; set; } -} + } //template - public class XABRInterpolationImpl : Interpolation.templateImpl where Model : IModel, new() + public class XABRInterpolationImpl : Interpolation.templateImpl where Model : IModel, new () { - public XABRInterpolationImpl( List xBegin, int size, List yBegin, double t, - double forward, List _params, - List paramIsFixed, bool vegaWeighted, - EndCriteria endCriteria, - OptimizationMethod optMethod, - double errorAccept, bool useMaxError, int maxGuesses, List addParams = null ) - : base( xBegin, size, yBegin ) + public XABRInterpolationImpl(List xBegin, int size, List yBegin, double t, + double forward, List < double? > _params, + List paramIsFixed, bool vegaWeighted, + EndCriteria endCriteria, + OptimizationMethod optMethod, + double errorAccept, bool useMaxError, int maxGuesses, List < double? > addParams = null, + XABRConstraint constraint = null) + : base(xBegin, size, yBegin) { - // XABRCoeffHolder(t, forward, params, paramIsFixed), - endCriteria_ = endCriteria; - optMethod_ = optMethod; - errorAccept_ = errorAccept; - useMaxError_ = useMaxError; - maxGuesses_ = maxGuesses; - forward_ = forward; - vegaWeighted_ = vegaWeighted; - - // if no optimization method or endCriteria is provided, we provide one - if (optMethod_ == null) - optMethod_ = new LevenbergMarquardt(1e-8, 1e-8, 1e-8); - if (endCriteria_ == null) - { - endCriteria_ = new EndCriteria(60000, 100, 1e-8, 1e-8, 1e-8); - } + endCriteria_ = endCriteria ?? new EndCriteria(60000, 100, 1e-8, 1e-8, 1e-8); + optMethod_ = optMethod ?? new LevenbergMarquardt(1e-8, 1e-8, 1e-8); + errorAccept_ = errorAccept; + useMaxError_ = useMaxError; + maxGuesses_ = maxGuesses; + forward_ = forward; + vegaWeighted_ = vegaWeighted; + constraint_ = constraint ?? new NoXABRConstraint(); + coeff_ = new XABRCoeffHolder(t, forward, _params, paramIsFixed, addParams); - this.coeff_.weights_ = new InitializedList( size, 1.0 / size ); + coeff_.weights_ = new InitializedList(size, 1.0 / size); } - + public override void update() { - this.coeff_.updateModelInstance(); + coeff_.updateModelInstance(); // we should also check that y contains positive values only // we must update weights if it is vegaWeighted - if (vegaWeighted_) + if (vegaWeighted_) { coeff_.weights_.Clear(); double weightsSum = 0.0; - for ( int i = 0; i < xBegin_.Count; i++ ) + for (int i = 0; i < xBegin_.Count; i++) { - double stdDev = Math.Sqrt( ( yBegin_[i] ) * ( yBegin_[i] ) * this.coeff_.t_ ); - coeff_.weights_.Add(coeff_.model_.weight(xBegin_[i], forward_, stdDev, this.coeff_.addParams_)); + double stdDev = Math.Sqrt((yBegin_[i]) * (yBegin_[i]) * coeff_.t_); + coeff_.weights_.Add(coeff_.model_.weight(xBegin_[i], forward_, stdDev, coeff_.addParams_)); weightsSum += coeff_.weights_.Last(); } // weight normalization - for( int i = 0 ; i < coeff_.weights_.Count; i++ ) - coeff_.weights_[i] /= weightsSum; - } - - // there is nothing to optimize - if ( coeff_.paramIsFixed_.Aggregate( ( a, b ) => b && a ) ) - { - coeff_.error_ = interpolationError(); - coeff_.maxError_ = interpolationMaxError(); - coeff_.XABREndCriteria_ = EndCriteria.Type.None; - return; - } - else - { - XABRError costFunction = new XABRError( this ); - - Vector guess = new Vector( coeff_.model_.dimension() ); - for ( int i = 0; i < guess.size(); ++i ) - guess[i] = coeff_.params_[i].Value; - - int iterations = 0; - int freeParameters = 0; - double bestError = double.MaxValue; - Vector bestParameters = new Vector(); - for (int i = 0; i < coeff_.model_.dimension(); ++i) - if (!coeff_.paramIsFixed_[i]) - ++freeParameters; - HaltonRsg halton = new HaltonRsg(freeParameters, 42); - EndCriteria.Type tmpEndCriteria; - double tmpInterpolationError; - - do { - - if (iterations > 0) { - Sample > s = halton.nextSequence(); - coeff_.model_.guess(guess, coeff_.paramIsFixed_, forward_, coeff_.t_, s.value, coeff_.addParams_); - for (int i = 0; i < coeff_.paramIsFixed_.Count; ++i) - if (coeff_.paramIsFixed_[i]) - guess[i] = coeff_.params_[i].Value; - } - - Vector inversedTransformatedGuess = new Vector(coeff_.model_.inverse(guess, coeff_.paramIsFixed_, coeff_.params_, forward_)); - - ProjectedCostFunction rainedXABRError = new ProjectedCostFunction(costFunction, inversedTransformatedGuess, - coeff_.paramIsFixed_); - - Vector projectedGuess = new Vector(rainedXABRError.project(inversedTransformatedGuess)); - - NoConstraint raint = new NoConstraint(); - Problem problem = new Problem(rainedXABRError, raint, projectedGuess); - tmpEndCriteria = optMethod_.minimize(problem, endCriteria_); - Vector projectedResult = new Vector(problem.currentValue()); - Vector transfResult = new Vector(rainedXABRError.include(projectedResult)); - Vector result = coeff_.model_.direct( transfResult, coeff_.paramIsFixed_, coeff_.params_, forward_ ); - tmpInterpolationError = useMaxError_ ? interpolationMaxError() - : interpolationError(); - - if (tmpInterpolationError < bestError) - { - bestError = tmpInterpolationError; - bestParameters = result; - coeff_.XABREndCriteria_ = tmpEndCriteria; - } - - } while (++iterations < maxGuesses_ && - tmpInterpolationError > errorAccept_); - - for (int i = 0; i < bestParameters.size(); ++i) - coeff_.params_[i] = bestParameters[i]; + for (int i = 0; i < coeff_.weights_.Count; i++) + coeff_.weights_[i] /= weightsSum; + } + // there is nothing to optimize + if (coeff_.paramIsFixed_.Aggregate((a, b) => b && a)) + { coeff_.error_ = interpolationError(); coeff_.maxError_ = interpolationMaxError(); - } - } + coeff_.XABREndCriteria_ = EndCriteria.Type.None; + return; + } + + XABRError costFunction = new XABRError(this); + + Vector guess = new Vector(coeff_.model_.dimension()); + for (int i = 0; i < guess.size(); ++i) + guess[i] = coeff_.params_[i].GetValueOrDefault(); + + int iterations = 0; + int freeParameters = 0; + double bestError = double.MaxValue; + Vector bestParameters = new Vector(); + for (int i = 0; i < coeff_.model_.dimension(); ++i) + if (!coeff_.paramIsFixed_[i]) + ++freeParameters; + HaltonRsg halton = new HaltonRsg(freeParameters, 42); + EndCriteria.Type tmpEndCriteria; + double tmpInterpolationError; + + do + { + if (iterations > 0) + { + Sample> s = halton.nextSequence(); + coeff_.model_.guess(guess, coeff_.paramIsFixed_, forward_, coeff_.t_, s.value, coeff_.addParams_); + for (int i = 0; i < coeff_.paramIsFixed_.Count; ++i) + if (coeff_.paramIsFixed_[i]) + guess[i] = coeff_.params_[i].GetValueOrDefault(); + } + + Vector inversedTransformatedGuess = + new Vector(coeff_.model_.inverse(guess, coeff_.paramIsFixed_, coeff_.params_, forward_)); + + ProjectedCostFunction rainedXABRError = new ProjectedCostFunction(costFunction, + inversedTransformatedGuess, + coeff_.paramIsFixed_); + + Vector projectedGuess = new Vector(rainedXABRError.project(inversedTransformatedGuess)); + + constraint_.config(rainedXABRError, coeff_, forward_); + Problem problem = new Problem(rainedXABRError, constraint_, projectedGuess); + tmpEndCriteria = optMethod_.minimize(problem, endCriteria_); + Vector projectedResult = new Vector(problem.currentValue()); + Vector transfResult = new Vector(rainedXABRError.include(projectedResult)); + Vector result = coeff_.model_.direct(transfResult, coeff_.paramIsFixed_, coeff_.params_, forward_); + tmpInterpolationError = useMaxError_ + ? interpolationMaxError() + : interpolationError(); + + if (tmpInterpolationError < bestError) + { + bestError = tmpInterpolationError; + bestParameters = result; + coeff_.XABREndCriteria_ = tmpEndCriteria; + } + } + while (++iterations < maxGuesses_ && + tmpInterpolationError > errorAccept_); + + for (int i = 0; i < bestParameters.size(); ++i) + coeff_.params_[i] = bestParameters[i]; - public override double value( double x ) + coeff_.error_ = interpolationError(); + coeff_.maxError_ = interpolationMaxError(); + } + + public override double value(double x) + { + return coeff_.modelInstance_.volatility(x); + } + + public override double primitive(double d) { - return coeff_.modelInstance_.volatility( x ); + Utils.QL_FAIL("XABR primitive not implemented"); + return 0; } - public override double primitive( double d ) { Utils.QL_FAIL( "XABR primitive not implemented" ); return 0; } - public override double derivative( double d ) { Utils.QL_FAIL( "XABR derivative not implemented" ); return 0; } - public override double secondDerivative( double d ) { Utils.QL_FAIL( "XABR secondDerivative not implemented" ); return 0; } + public override double derivative(double d) + { + Utils.QL_FAIL("XABR derivative not implemented"); + return 0; + } + + public override double secondDerivative(double d) + { + Utils.QL_FAIL("XABR secondDerivative not implemented"); + return 0; + } // calculate total squared weighted difference (L2 norm) - public double interpolationSquaredError() + public double interpolationSquaredError() { double error, totalError = 0.0; - for ( int i = 0; i < xBegin_.Count; i++ ) + for (int i = 0; i < xBegin_.Count; i++) { - error = ( value( xBegin_[i] ) - yBegin_[i] ); - totalError += error * error * ( coeff_.weights_[i] ); + error = (value(xBegin_[i]) - yBegin_[i]); + totalError += error * error * (coeff_.weights_[i]); } + return totalError; } // calculate weighted differences - public Vector interpolationErrors( Vector v ) + public Vector interpolationErrors(Vector v) { Vector results = new Vector(xBegin_.Count); - for ( int i = 0 ; i < xBegin_.Count ; i++) + for (int i = 0; i < xBegin_.Count; i++) results[i] = (value(xBegin_[i]) - yBegin_[i]) * Math.Sqrt(coeff_.weights_[i]); return results; } - public double interpolationError() + public double interpolationError() { - int n = xBegin_.Count; - double squaredError = interpolationSquaredError(); - return Math.Sqrt(n * squaredError / (n - 1)); - } + int n = xBegin_.Count; + double squaredError = interpolationSquaredError(); + return Math.Sqrt(n * squaredError / (n - 1)); + } - public double interpolationMaxError() + public double interpolationMaxError() { double error, maxError = Double.MinValue; - for ( int i = 0 ; i < xBegin_.Count ; i++) - { - error = Math.Abs(value(xBegin_[i]) - yBegin_[i]); - maxError = Math.Max(maxError, error); - } - - return maxError; - } + for (int i = 0; i < xBegin_.Count; i++) + { + error = Math.Abs(value(xBegin_[i]) - yBegin_[i]); + maxError = Math.Max(maxError, error); + } + return maxError; + } private class XABRError : CostFunction { - public XABRError( XABRInterpolationImpl xabr ) { xabr_ = xabr; } + public XABRError(XABRInterpolationImpl xabr) + { + xabr_ = xabr; + } - public override double value( Vector x ) + public override double value(Vector x) { Vector y = xabr_.coeff_.model_.direct(x, xabr_.coeff_.paramIsFixed_, xabr_.coeff_.params_, xabr_.forward_); - for ( int i = 0; i < xabr_.coeff_.params_.Count; ++i ) + for (int i = 0; i < xabr_.coeff_.params_.Count; ++i) xabr_.coeff_.params_[i] = y[i]; xabr_.coeff_.updateModelInstance(); return xabr_.interpolationSquaredError(); } - public override Vector values( Vector x ) + public override Vector values(Vector x) { Vector y = xabr_.coeff_.model_.direct(x, xabr_.coeff_.paramIsFixed_, xabr_.coeff_.params_, xabr_.forward_); - for ( int i = 0; i < xabr_.coeff_.params_.Count; ++i ) + for (int i = 0; i < xabr_.coeff_.params_.Count; ++i) xabr_.coeff_.params_[i] = y[i]; xabr_.coeff_.updateModelInstance(); - return xabr_.interpolationErrors( x ); + return xabr_.interpolationErrors(x); } private XABRInterpolationImpl xabr_; @@ -302,6 +327,7 @@ public override Vector values( Vector x ) private EndCriteria endCriteria_; private OptimizationMethod optMethod_; + private XABRConstraint constraint_; private double errorAccept_; private bool useMaxError_; private int maxGuesses_; @@ -309,4 +335,44 @@ public override Vector values( Vector x ) private bool vegaWeighted_; public XABRCoeffHolder coeff_ { get; set; } } + + public class XABRConstraint : Constraint + { + public XABRConstraint() : base(null) + { } + + public XABRConstraint(IConstraint impl) + : base(impl) + { } + + public virtual void config(ProjectedCostFunction costFunction, XABRCoeffHolder coeff, + double forward) + where Model : IModel, new () + { } + } + + //! No constraint + public class NoXABRConstraint : XABRConstraint + { + private class Impl : IConstraint + { + public bool test(Vector param) + { + return true; + } + + public Vector upperBound(Vector parameters) + { + return new Vector(parameters.size(), Double.MaxValue); + } + + public Vector lowerBound(Vector parameters) + { + return new Vector(parameters.size(), Double.MinValue); + } + } + + public NoXABRConstraint() : base(new Impl()) + { } + } } diff --git a/src/QLNet/Math/Interpolations/backwardflatinterpolation.cs b/src/QLNet/Math/Interpolations/backwardflatinterpolation.cs deleted file mode 100644 index 1251aca01..000000000 --- a/src/QLNet/Math/Interpolations/backwardflatinterpolation.cs +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System.Collections.Generic; - -namespace QLNet { - public class BackwardFlatInterpolationImpl : Interpolation.templateImpl { - private List primitive_; - - public BackwardFlatInterpolationImpl(List xBegin, int size, List yBegin) : base(xBegin, size, yBegin) { - primitive_ = new InitializedList(size_); - } - - public override void update() { - primitive_[0] = 0.0; - for (int i=1; i xBegin, int size, List yBegin) { - impl_ = new BackwardFlatInterpolationImpl(xBegin, size, yBegin); - impl_.update(); - } - } - - //! Backward-flat interpolation factory and traits - public class BackwardFlat : IInterpolationFactory { - public Interpolation interpolate(List xBegin, int size, List yBegin) { - return new BackwardFlatInterpolation( xBegin, size, yBegin ); - } - public bool global { get { return false; } } - public int requiredPoints { get { return 2; } } - } -} diff --git a/src/QLNet/Math/Interpolations/convexmonotoneinterpolation.cs b/src/QLNet/Math/Interpolations/convexmonotoneinterpolation.cs deleted file mode 100644 index d9607d02b..000000000 --- a/src/QLNet/Math/Interpolations/convexmonotoneinterpolation.cs +++ /dev/null @@ -1,718 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace QLNet { - //the first value in the y-vector is ignored. - - #region Helpers - public interface ISectionHelper { - double value(double x); - double primitive(double x); - double fNext(); - } - - public class ComboHelper : ISectionHelper { - private double quadraticity_; - ISectionHelper quadraticHelper_; - ISectionHelper convMonoHelper_; - - public ComboHelper(ISectionHelper quadraticHelper, ISectionHelper convMonoHelper, double quadraticity) { - quadraticity_ = quadraticity; - quadraticHelper_ = quadraticHelper; - convMonoHelper_ = convMonoHelper; - Utils.QL_REQUIRE(quadraticity < 1.0 && quadraticity > 0.0,()=> "Quadratic value must lie between 0 and 1"); - } - - public double value(double x) { - return (quadraticity_ * quadraticHelper_.value(x) + (1.0 - quadraticity_) * convMonoHelper_.value(x)); - } - public double primitive(double x) { - return (quadraticity_ * quadraticHelper_.primitive(x) + (1.0 - quadraticity_) * convMonoHelper_.primitive(x)); - } - public double fNext() { - return (quadraticity_ * quadraticHelper_.fNext() + (1.0 - quadraticity_) * convMonoHelper_.fNext()); - } - } - - public class EverywhereConstantHelper : ISectionHelper { - private double value_; - private double prevPrimitive_; - private double xPrev_; - - public EverywhereConstantHelper(double value, double prevPrimitive, double xPrev) { - value_ = value; - prevPrimitive_ = prevPrimitive; - xPrev_ = xPrev; - } - - public double value(double x) { return value_; } - public double primitive(double x) { return prevPrimitive_ + (x - xPrev_) * value_; } - public double fNext() { return value_; } - } - - public class ConvexMonotone2Helper : ISectionHelper { - private double xPrev_, xScaling_, gPrev_, gNext_, fAverage_, eta2_, prevPrimitive_; - - public ConvexMonotone2Helper(double xPrev, double xNext, double gPrev, double gNext, double fAverage, double eta2, - double prevPrimitive) { - xPrev_ = xPrev; - xScaling_ = xNext - xPrev; - gPrev_ = gPrev; - gNext_ = gNext; - fAverage_ = fAverage; - eta2_ = eta2; - prevPrimitive_ = prevPrimitive; - } - - public double value(double x) { - double xVal = (x - xPrev_) / xScaling_; - if (xVal <= eta2_) { - return (fAverage_ + gPrev_); - } else { - return (fAverage_ + gPrev_ + (gNext_ - gPrev_) / ((1 - eta2_) * (1 - eta2_)) * (xVal - eta2_) * (xVal - eta2_)); - } - } - - public double primitive(double x) { - double xVal = (x - xPrev_) / xScaling_; - if (xVal <= eta2_) { - return (prevPrimitive_ + xScaling_ * (fAverage_ * xVal + gPrev_ * xVal)); - } else { - return (prevPrimitive_ + xScaling_ * (fAverage_ * xVal + gPrev_ * xVal + (gNext_ - gPrev_) / ((1 - eta2_) * (1 - eta2_)) * - (1.0 / 3.0 * (xVal * xVal * xVal - eta2_ * eta2_ * eta2_) - eta2_ * xVal * xVal + eta2_ * eta2_ * xVal))); - } - } - public double fNext() { return (fAverage_ + gNext_); } - } - - public class ConvexMonotone3Helper : ISectionHelper { - private double xPrev_, xScaling_, gPrev_, gNext_, fAverage_, eta3_, prevPrimitive_; - - public ConvexMonotone3Helper(double xPrev, double xNext, - double gPrev, double gNext, - double fAverage, double eta3, - double prevPrimitive) { - xPrev_ = xPrev; - xScaling_ = xNext - xPrev; - gPrev_ = gPrev; - gNext_ = gNext; - fAverage_ = fAverage; - eta3_ = eta3; - prevPrimitive_ = prevPrimitive; - } - - public double value(double x) { - double xVal = (x - xPrev_) / xScaling_; - if (xVal <= eta3_) { - return (fAverage_ + gNext_ + (gPrev_ - gNext_) / (eta3_ * eta3_) * (eta3_ - xVal) * (eta3_ - xVal)); - } else { - return (fAverage_ + gNext_); - } - } - - public double primitive(double x) { - double xVal = (x - xPrev_) / xScaling_; - if (xVal <= eta3_) { - return (prevPrimitive_ + xScaling_ * (fAverage_ * xVal + gNext_ * xVal + (gPrev_ - gNext_) / (eta3_ * eta3_) * - (1.0 / 3.0 * xVal * xVal * xVal - eta3_ * xVal * xVal + eta3_ * eta3_ * xVal))); - } else { - return (prevPrimitive_ + xScaling_ * (fAverage_ * xVal + gNext_ * xVal + (gPrev_ - gNext_) / (eta3_ * eta3_) * - (1.0 / 3.0 * eta3_ * eta3_ * eta3_))); - } - } - public double fNext() { return (fAverage_ + gNext_); } - } - - public class ConvexMonotone4Helper : ISectionHelper { - protected double xPrev_, xScaling_, gPrev_, gNext_, fAverage_, eta4_, prevPrimitive_; - protected double A_; - - public ConvexMonotone4Helper(double xPrev, double xNext, double gPrev, double gNext, - double fAverage, double eta4, double prevPrimitive) { - xPrev_ = xPrev; - xScaling_ = xNext - xPrev; - gPrev_ = gPrev; - gNext_ = gNext; - fAverage_ = fAverage; - eta4_ = eta4; - prevPrimitive_ = prevPrimitive; - A_ = -0.5 * (eta4_ * gPrev_ + (1 - eta4_) * gNext_); - } - - public virtual double value(double x) { - double xVal = (x - xPrev_) / xScaling_; - if (xVal <= eta4_) { - return (fAverage_ + A_ + (gPrev_ - A_) * (eta4_ - xVal) * (eta4_ - xVal) / (eta4_ * eta4_)); - } else { - return (fAverage_ + A_ + (gNext_ - A_) * (xVal - eta4_) * (xVal - eta4_) / ((1 - eta4_) * (1 - eta4_))); - } - } - - public virtual double primitive(double x) { - double xVal = (x - xPrev_) / xScaling_; - double retVal; - if (xVal <= eta4_) { - retVal = prevPrimitive_ + xScaling_ * (fAverage_ + A_ + (gPrev_ - A_) / (eta4_ * eta4_) * - (eta4_ * eta4_ - eta4_ * xVal + 1.0 / 3.0 * xVal * xVal)) * xVal; - } else { - retVal = prevPrimitive_ + xScaling_ * (fAverage_ * xVal + A_ * xVal + (gPrev_ - A_) * (1.0 / 3.0 * eta4_) + - (gNext_ - A_) / ((1 - eta4_) * (1 - eta4_)) * - (1.0 / 3.0 * xVal * xVal * xVal - eta4_ * xVal * xVal + eta4_ * eta4_ * xVal - 1.0 / 3.0 * eta4_ * eta4_ * eta4_)); - } - return retVal; - } - public double fNext() { return (fAverage_ + gNext_); } - } - - public class ConvexMonotone4MinHelper : ConvexMonotone4Helper { - private bool splitRegion_; - private double xRatio_, x2_, x3_; - - public ConvexMonotone4MinHelper(double xPrev, double xNext, double gPrev, double gNext, - double fAverage, double eta4, double prevPrimitive) - : base(xPrev, xNext, gPrev, gNext, fAverage, eta4, prevPrimitive) { - - splitRegion_ = false; - if (A_ + fAverage_ <= 0.0) { - splitRegion_ = true; - double fPrev = gPrev_ + fAverage_; - double fNext = gNext_ + fAverage_; - double reqdShift = (eta4_ * fPrev + (1 - eta4_) * fNext) / 3.0 - fAverage_; - double reqdPeriod = reqdShift * xScaling_ / (fAverage_ + reqdShift); - double xAdjust = xScaling_ - reqdPeriod; - xRatio_ = xAdjust / xScaling_; - - fAverage_ += reqdShift; - gNext_ = fNext - fAverage_; - gPrev_ = fPrev - fAverage_; - A_ = -(eta4_ * gPrev_ + (1.0 - eta4) * gNext_) / 2.0; - x2_ = xPrev_ + xAdjust * eta4_; - x3_ = xPrev_ + xScaling_ - xAdjust * (1.0 - eta4_); - } - } - - public override double value(double x) { - if (!splitRegion_) - return base.value(x); - - double xVal = (x - xPrev_) / xScaling_; - if (x <= x2_) { - xVal /= xRatio_; - return (fAverage_ + A_ + (gPrev_ - A_) * (eta4_ - xVal) * (eta4_ - xVal) / (eta4_ * eta4_)); - } else if (x < x3_) { - return 0.0; - } else { - xVal = 1.0 - (1.0 - xVal) / xRatio_; - return (fAverage_ + A_ + (gNext_ - A_) * (xVal - eta4_) * (xVal - eta4_) / ((1 - eta4_) * (1 - eta4_))); - } - } - - public override double primitive(double x) { - if (!splitRegion_) - return base.primitive(x); - - double xVal = (x - xPrev_) / xScaling_; - if (x <= x2_) { - xVal /= xRatio_; - return (prevPrimitive_ + xScaling_ * xRatio_ * (fAverage_ + A_ + (gPrev_ - A_) / (eta4_ * eta4_) * - (eta4_ * eta4_ - eta4_ * xVal + 1.0 / 3.0 * xVal * xVal)) * xVal); - } else if (x <= x3_) { - return (prevPrimitive_ + xScaling_ * xRatio_ * (fAverage_ * eta4_ + A_ * eta4_ + (gPrev_ - A_) / (eta4_ * eta4_) * - (1.0 / 3.0 * eta4_ * eta4_ * eta4_))); - } else { - xVal = 1.0 - (1.0 - xVal) / xRatio_; - return (prevPrimitive_ + xScaling_ * xRatio_ * (fAverage_ * xVal + A_ * xVal + (gPrev_ - A_) * (1.0 / 3.0 * eta4_) + - (gNext_ - A_) / ((1.0 - eta4_) * (1.0 - eta4_)) * - (1.0 / 3.0 * xVal * xVal * xVal - eta4_ * xVal * xVal + eta4_ * eta4_ * xVal - 1.0 / 3.0 * eta4_ * eta4_ * eta4_))); - } - } - } - - public class ConstantGradHelper : ISectionHelper { - private double fPrev_, prevPrimitive_, xPrev_, fGrad_, fNext_; - - public ConstantGradHelper(double fPrev, double prevPrimitive, double xPrev, double xNext, double fNext) { - fPrev_ = fPrev; - prevPrimitive_ = prevPrimitive; - xPrev_ = xPrev; - fGrad_ = ((fNext - fPrev) / (xNext - xPrev)); - fNext_ = fNext; - } - - public double value(double x) { return (fPrev_ + (x - xPrev_) * fGrad_); } - public double primitive(double x) { return (prevPrimitive_ + (x - xPrev_) * (fPrev_ + 0.5 * (x - xPrev_) * fGrad_)); } - public double fNext() { return fNext_; } - } - - public class QuadraticHelper : ISectionHelper { - private double xPrev_, xNext_, fPrev_, fNext_, fAverage_, prevPrimitive_; - private double xScaling_, a_, b_, c_; - - public QuadraticHelper(double xPrev, double xNext, double fPrev, double fNext, double fAverage, double prevPrimitive) { - xPrev_ = xPrev; - xNext_ = xNext; - fPrev_ = fPrev; - fNext_ = fNext; - fAverage_ = fAverage; - prevPrimitive_ = prevPrimitive; - a_ = 3 * fPrev_ + 3 * fNext_ - 6 * fAverage_; - b_ = -(4 * fPrev_ + 2 * fNext_ - 6 * fAverage_); - c_ = fPrev_; - xScaling_ = xNext_ - xPrev_; - } - - public double value(double x) { - double xVal = (x - xPrev_) / xScaling_; - return (a_ * xVal * xVal + b_ * xVal + c_); - } - - public double primitive(double x) { - double xVal = (x - xPrev_) / xScaling_; - return (prevPrimitive_ + xScaling_ * (a_ / 3 * xVal * xVal + b_ / 2 * xVal + c_) * xVal); - } - - public double fNext() { return fNext_; } - } - - public class QuadraticMinHelper : ISectionHelper { - private bool splitRegion_; - private double x1_, x2_, x3_, x4_; - private double a_, b_, c_; - private double primitive1_, primitive2_; - private double fAverage_, fPrev_, fNext_, xScaling_, xRatio_; - - public QuadraticMinHelper(double xPrev, double xNext, double fPrev, double fNext, double fAverage, double prevPrimitive) { - splitRegion_ = false; - x1_ = xPrev; - x4_ = xNext; - primitive1_ = prevPrimitive; - fAverage_ = fAverage; - fPrev_ = fPrev; - fNext_ = fNext; - a_ = 3 * fPrev_ + 3 * fNext_ - 6 * fAverage_; - b_ = -(4 * fPrev_ + 2 * fNext_ - 6 * fAverage_); - c_ = fPrev_; - double d = b_ * b_ - 4 * a_ * c_; - xScaling_ = x4_ - x1_; - xRatio_ = 1.0; - if (d > 0) { - double aAv = 36; - double bAv = -24 * (fPrev_ + fNext_); - double cAv = 4 * (fPrev_ * fPrev_ + fPrev_ * fNext_ + fNext_ * fNext_); - double dAv = bAv * bAv - 4.0 * aAv * cAv; - if (dAv >= 0.0) { - splitRegion_ = true; - double avRoot = (-bAv - Math.Sqrt(dAv)) / (2 * aAv); - - xRatio_ = fAverage_ / avRoot; - xScaling_ *= xRatio_; - - a_ = 3 * fPrev_ + 3 * fNext_ - 6 * avRoot; - b_ = -(4 * fPrev_ + 2 * fNext_ - 6 * avRoot); - c_ = fPrev_; - double xRoot = -b_ / (2 * a_); - x2_ = x1_ + xRatio_ * (x4_ - x1_) * xRoot; - x3_ = x4_ - xRatio_ * (x4_ - x1_) * (1 - xRoot); - primitive2_ = - primitive1_ + xScaling_ * (a_ / 3 * xRoot * xRoot + b_ / 2 * xRoot + c_) * xRoot; - } - } - } - - public double value(double x) { - double xVal = (x - x1_) / (x4_ - x1_); - if (splitRegion_) { - if (x <= x2_) { - xVal /= xRatio_; - } else if (x < x3_) { - return 0.0; - } else { - xVal = 1.0 - (1.0 - xVal) / xRatio_; - } - } - - return c_ + b_ * xVal + a_ * xVal * xVal; - } - - public double primitive(double x) { - double xVal = (x - x1_) / (x4_ - x1_); - if (splitRegion_) { - if (x < x2_) { - xVal /= xRatio_; - } else if (x < x3_) { - return primitive2_; - } else { - xVal = 1.0 - (1.0 - xVal) / xRatio_; - } - } - return primitive1_ + xScaling_ * (a_ / 3 * xVal * xVal + b_ / 2 * xVal + c_) * xVal; - } - - public double fNext() { return fNext_; } - } - #endregion - - - public class ConvexMonotoneImpl : Interpolation.templateImpl { - private Dictionary sectionHelpers_ = new Dictionary(); - private Dictionary preSectionHelpers_ = new Dictionary(); - private ISectionHelper extrapolationHelper_; - private bool forcePositive_, constantLastPeriod_; - private double quadraticity_; - private double monotonicity_; - - public enum SectionType { - EverywhereConstant, - ConstantGradient, - QuadraticMinimum, - QuadraticMaximum - }; - - public ConvexMonotoneImpl(List xBegin, int size, List yBegin, - double quadraticity, double monotonicity, bool forcePositive, bool constantLastPeriod, - Dictionary preExistingHelpers) - : base(xBegin,size,yBegin) { - preSectionHelpers_ = preExistingHelpers; - forcePositive_ = forcePositive; - constantLastPeriod_ = constantLastPeriod; - quadraticity_ = quadraticity; - monotonicity_ = monotonicity; - - Utils.QL_REQUIRE(monotonicity_ >= 0 && monotonicity_ <= 1,()=> "Monotonicity must lie between 0 and 1"); - Utils.QL_REQUIRE(quadraticity_ >= 0 && quadraticity_ <= 1,()=> "Quadraticity must lie between 0 and 1"); - Utils.QL_REQUIRE(size_ >= 2,()=> "Single point provided, not supported by convex " + - "monotone method as first point is ignored"); - Utils.QL_REQUIRE((size_ - preExistingHelpers.Count) > 1,()=> "Too many existing helpers have been supplied"); - } - - public override void update() { - sectionHelpers_.Clear(); - if (size_ == 2) { //single period - ISectionHelper singleHelper = new EverywhereConstantHelper(yBegin_[1], 0.0, xBegin_[0]); - sectionHelpers_.Add(xBegin_[1], singleHelper); - extrapolationHelper_ = singleHelper; - return; - } - - List f = new InitializedList(size_); - sectionHelpers_ = new Dictionary(preSectionHelpers_); - int startPoint = sectionHelpers_.Count+1; - - //first derive the boundary forwards. - for (int i=startPoint; i 1) - f[startPoint-1] = preSectionHelpers_.Last().Value.fNext(); - if (startPoint == 1) - f[0] = 1.5 * yBegin_[1] - 0.5 * f[1]; - - f[size_-1] = 1.5 * yBegin_[size_-1] - 0.5 * f[size_-2]; - - if (forcePositive_) { - if (f[0] < 0) - f[0] = 0.0; - if (f[size_-1] < 0.0) - f[size_-1] = 0.0; - } - - double primitive = 0.0; - for (int i = 0; i < startPoint-1; ++i) - primitive += yBegin_[i+1] * (xBegin_[i+1]-xBegin_[i]); - - int endPoint = size_; - if (constantLastPeriod_) - endPoint = endPoint-1; - - for (int i=startPoint; i< endPoint; ++i) { - double gPrev = f[i-1] - yBegin_[i]; - double gNext = f[i] - yBegin_[i]; - //first deal with the zero gradient case - if ( Math.Abs(gPrev) < 1.0E-14 && Math.Abs(gNext) < 1.0E-14 ) { - ISectionHelper singleHelper = new ConstantGradHelper(f[i - 1], primitive, - xBegin_[i-1], - xBegin_[i], - f[i]); - sectionHelpers_.Add(xBegin_[i], singleHelper); - } else { - double quadraticity = quadraticity_; - ISectionHelper quadraticHelper = null; - ISectionHelper convMonotoneHelper = null; - if (quadraticity_ > 0.0) { - if (gPrev >= -2.0*gNext && gPrev > -0.5*gNext && forcePositive_) { - quadraticHelper = new QuadraticMinHelper(xBegin_[i-1], - xBegin_[i], - f[i-1], f[i], - yBegin_[i], - primitive); - } else { - quadraticHelper = new QuadraticHelper(xBegin_[i-1], - xBegin_[i], - f[i-1], f[i], - yBegin_[i], - primitive); - } - } - if (quadraticity_ < 1.0) { - - if ((gPrev > 0.0 && -0.5*gPrev >= gNext && gNext >= -2.0*gPrev) || - (gPrev < 0.0 && -0.5*gPrev <= gNext && gNext <= -2.0*gPrev)) { - quadraticity = 1.0; - if (quadraticity_.IsEqual(0.0)) { - if (forcePositive_) { - quadraticHelper = new QuadraticMinHelper( - xBegin_[i-1], - xBegin_[i], - f[i-1], f[i], - yBegin_[i], - primitive); - } else { - quadraticHelper = new QuadraticHelper( - xBegin_[i-1], - xBegin_[i], - f[i-1], f[i], - yBegin_[i], - primitive); - } - } - } - else if ( (gPrev < 0.0 && gNext > -2.0*gPrev) || - (gPrev > 0.0 && gNext < -2.0*gPrev)) { - - double eta = (gNext + 2.0*gPrev)/(gNext - gPrev); - double b2 = (1.0 + monotonicity_)/2.0; - if (eta < b2) { - convMonotoneHelper = new ConvexMonotone2Helper( - xBegin_[i-1], - xBegin_[i], - gPrev, gNext, - yBegin_[i], - eta, primitive); - } else { - if (forcePositive_) { - convMonotoneHelper = new ConvexMonotone4MinHelper( - xBegin_[i-1], - xBegin_[i], - gPrev, gNext, - yBegin_[i], - b2, primitive); - } else { - convMonotoneHelper = new ConvexMonotone4Helper( - xBegin_[i-1], - xBegin_[i], - gPrev, gNext, - yBegin_[i], - b2, primitive); - } - } - } - else if ( (gPrev > 0.0 && gNext < 0.0 && gNext > -0.5*gPrev) || - (gPrev < 0.0 && gNext > 0.0 && gNext < -0.5*gPrev) ) { - double eta = gNext/(gNext-gPrev) * 3.0; - double b3 = (1.0 - monotonicity_) / 2.0; - if (eta > b3) { - convMonotoneHelper = new ConvexMonotone3Helper( - xBegin_[i-1], - xBegin_[i], - gPrev, gNext, - yBegin_[i], - eta, primitive); - } else { - if (forcePositive_) { - convMonotoneHelper = new ConvexMonotone4MinHelper( - xBegin_[i-1], - xBegin_[i], - gPrev, gNext, - yBegin_[i], - b3, primitive); - } else { - convMonotoneHelper = new ConvexMonotone4Helper( - xBegin_[i-1], - xBegin_[i], - gPrev, gNext, - yBegin_[i], - b3, primitive); - } - } - } else { - double eta = gNext/(gPrev + gNext); - double b2 = (1.0 + monotonicity_) / 2.0; - double b3 = (1.0 - monotonicity_) / 2.0; - if (eta > b2) - eta = b2; - if (eta < b3) - eta = b3; - if (forcePositive_) { - convMonotoneHelper = new ConvexMonotone4MinHelper( - xBegin_[i-1], - xBegin_[i], - gPrev, gNext, - yBegin_[i], - eta, primitive); - } else { - convMonotoneHelper = new ConvexMonotone4Helper( - xBegin_[i-1], - xBegin_[i], - gPrev, gNext, - yBegin_[i], - eta, primitive); - } - } - } - - if (quadraticity.IsEqual(1.0)) { - sectionHelpers_.Add(xBegin_[i], quadraticHelper); - } else if (quadraticity.IsEqual(0.0)) { - sectionHelpers_.Add(xBegin_[i], convMonotoneHelper); - } else { - sectionHelpers_.Add(xBegin_[i], new ComboHelper(quadraticHelper, convMonotoneHelper, quadraticity)); - } - } - primitive += yBegin_[i] * (xBegin_[i]-xBegin_[i-1]); - } - - if (constantLastPeriod_) { - sectionHelpers_.Add(xBegin_[size_-1], new EverywhereConstantHelper(yBegin_[size_-1], primitive, xBegin_[size_-2])); - extrapolationHelper_ = sectionHelpers_[xBegin_[size_-1]]; - } else { - extrapolationHelper_ = new EverywhereConstantHelper((sectionHelpers_.Last()).Value.value(xBegin_.Last()), - primitive, xBegin_.Last()); - } - } - - public override double value(double x) { - if (x >= xBegin_.Last()) { - return extrapolationHelper_.value(x); - } - - double i; - if (x > sectionHelpers_.Keys.Last()) - i = sectionHelpers_.Keys.Last(); - else if (x < sectionHelpers_.Keys.First()) - i = sectionHelpers_.Keys.First(); - else - i = sectionHelpers_.Keys.First(y => x < y); - return sectionHelpers_[i].value(x); - } - - public override double primitive(double x) { - if (x >= xBegin_.Last()) { - return extrapolationHelper_.primitive(x); - } - - double i; - if (x >= sectionHelpers_.Keys.Last()) - i = sectionHelpers_.Keys.Last(); - else if (x <= sectionHelpers_.Keys.First()) - i = sectionHelpers_.Keys.First(); - else - i = sectionHelpers_.Keys.First(y => x < y); - return sectionHelpers_[i].primitive(x); - } - - public override double derivative(double x) { - throw new NotImplementedException("Convex-monotone spline derivative not implemented"); - } - - public override double secondDerivative(double x) { - throw new NotImplementedException("Convex-monotone spline second derivative not implemented"); - } - - public Dictionary getExistingHelpers() { - Dictionary retArray = new Dictionary(sectionHelpers_); - if (constantLastPeriod_) - retArray.Remove(xBegin_.Last()); - return retArray; - } - } - - //! Convex monotone yield-curve interpolation method. - /*! Enhances implementation of the convex monotone method - described in "Interpolation Methods for Curve Construction" by - Hagan & West AMF Vol 13, No2 2006. - - A setting of monotonicity = 1 and quadraticity = 0 will - reproduce the basic Hagan/West method. However, this can - produce excessive gradients which can mean P&L swings for some - curves. Setting monotonicity < 1 and/or quadraticity > 0 - produces smoother curves. Extra enhancement to avoid negative - values (if required) is in place. - */ - public class ConvexMonotoneInterpolation : Interpolation { - public ConvexMonotoneInterpolation(List xBegin, int size, List yBegin, double quadraticity, - double monotonicity, bool forcePositive, bool flatFinalPeriod) - : this(xBegin, size, yBegin, quadraticity, monotonicity, forcePositive, flatFinalPeriod, - new Dictionary()) { } - public ConvexMonotoneInterpolation(List xBegin, int size, List yBegin, double quadraticity, - double monotonicity, bool forcePositive, bool flatFinalPeriod, - Dictionary preExistingHelpers) { - impl_ = new ConvexMonotoneImpl(xBegin, size, yBegin, quadraticity, monotonicity, forcePositive, - flatFinalPeriod, preExistingHelpers); - impl_.update(); - } - - public Dictionary getExistingHelpers() { - ConvexMonotoneImpl derived = impl_ as ConvexMonotoneImpl; - return derived.getExistingHelpers(); - } - } - - - //! Convex-monotone interpolation factory and traits - public class ConvexMonotone : IInterpolationFactory { - private double quadraticity_, monotonicity_; - private bool forcePositive_; - - public ConvexMonotone() : this(0.3, 0.7, true) { } - public ConvexMonotone(double quadraticity, double monotonicity, bool forcePositive) { - quadraticity_ = quadraticity; - monotonicity_ = monotonicity; - forcePositive_ = forcePositive; - } - - public Interpolation interpolate(List xBegin, int size, List yBegin) { - return new ConvexMonotoneInterpolation(xBegin, size, yBegin, quadraticity_, monotonicity_, forcePositive_, false); - } - - public Interpolation localInterpolate(List xBegin, int size, List yBegin, int localisation, - ConvexMonotoneInterpolation prevInterpolation, int finalSize) { - int length = size; - if (length - localisation == 1) { // the first time this - // function is called - return new ConvexMonotoneInterpolation(xBegin, size, yBegin, quadraticity_, monotonicity_, forcePositive_, - length != finalSize); - } - - ConvexMonotoneInterpolation interp = prevInterpolation; - return new ConvexMonotoneInterpolation(xBegin, size, yBegin, quadraticity_, monotonicity_, - forcePositive_, length != finalSize, interp.getExistingHelpers()); - } - - public bool global { get { return true; } } - public int requiredPoints { get { return 2; } } - public int dataSizeAdjustment { get { return 1; } } - } -} diff --git a/src/QLNet/Math/Interpolations/forwardflatinterpolation.cs b/src/QLNet/Math/Interpolations/forwardflatinterpolation.cs deleted file mode 100644 index 1fe95e066..000000000 --- a/src/QLNet/Math/Interpolations/forwardflatinterpolation.cs +++ /dev/null @@ -1,70 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System.Collections.Generic; - - -namespace QLNet { - public class ForwardFlatInterpolationImpl : Interpolation.templateImpl { - private List primitive_; - - public ForwardFlatInterpolationImpl(List xBegin, int size, List yBegin) : base(xBegin, size, yBegin) { - primitive_ = new InitializedList(size_); - } - - public override void update() { - primitive_[0] = 0.0; - for (int i = 1; i < size_; i++) { - double dx = xBegin_[i]-xBegin_[i-1]; - primitive_[i] = primitive_[i-1] + dx*yBegin_[i-1]; - } - } - public override double value(double x) { - if (x >= xBegin_[size_ - 1]) - return yBegin_[size_ - 1]; - - int i = locate(x); - return yBegin_[i]; - } - public override double primitive(double x) { - int i = locate(x); - double dx = x-xBegin_[i]; - return primitive_[i] + dx*yBegin_[i]; - } - public override double derivative(double x) { return 0.0; } - public override double secondDerivative(double x) { return 0.0; } - } - - //! Forward-flat interpolation between discrete points - public class ForwardFlatInterpolation : Interpolation { - /*! \pre the \f$ x \f$ values must be sorted. */ - public ForwardFlatInterpolation(List xBegin, int size, List yBegin) { - impl_ = new ForwardFlatInterpolationImpl(xBegin, size, yBegin); - impl_.update(); - } - } - - //! Forward-flat interpolation factory and traits - public class ForwardFlat : IInterpolationFactory { - public Interpolation interpolate(List xBegin, int size, List yBegin) { - return new ForwardFlatInterpolation(xBegin, size, yBegin); - } - public bool global { get { return false; } } - public int requiredPoints { get { return 2; } } - } -} diff --git a/src/QLNet/Math/Interpolations/interpolation2d.cs b/src/QLNet/Math/Interpolations/interpolation2d.cs deleted file mode 100644 index 0cfbaef06..000000000 --- a/src/QLNet/Math/Interpolations/interpolation2d.cs +++ /dev/null @@ -1,179 +0,0 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace QLNet -{ - //! base class for 2-D interpolations. - /*! Classes derived from this class will provide interpolated - values from two sequences of length \f$ N \f$ and \f$ M \f$, - representing the discretized values of the \f$ x \f$ and \f$ y - \f$ variables, and a \f$ N \times M \f$ matrix representing - the tabulated function values. - */ - - // Interpolation factory - public interface IInterpolationFactory2D - { - Interpolation2D interpolate(List xBegin, int xSize, - List yBegin, int ySize, - Matrix zData); - } - - public abstract class Interpolation2D : Extrapolator/*, IValue */ - { - protected Impl impl_; - - public double xMin(){return impl_.xMin();} - - public double xMax(){return impl_.xMax();} - - public List xValues() {return impl_.xValues();} - - public int locateX(double x) {return impl_.locateX(x);} - - public double yMin() {return impl_.yMin();} - - public double yMax() {return impl_.yMax();} - - public List yValues() {return impl_.yValues();} - - public int locateY(double y) {return impl_.locateY(y);} - - public Matrix zData() {return impl_.zData();} - - public bool isInRange(double x, double y){return impl_.isInRange(x,y);} - - public override void update(){impl_.calculate();} - - // main method to derive an interpolated point - public double value(double x, double y) { return value(x, y, false); } - - public double value(double x, double y, bool allowExtrapolation){ - checkRange(x, y, allowExtrapolation); - return impl_.value(x, y); - } - - protected void checkRange(double x, double y, bool extrapolate) { - if (!(extrapolate || allowsExtrapolation() || impl_.isInRange(x,y))) - throw new ArgumentException("interpolation range is [" + impl_.xMin() + ", " + impl_.xMax() - + "] X [" + x + impl_.yMin() + ", " + impl_.yMax() - + "]: extrapolation at (" +x+", "+y+ " not allowed"); - } - - //! abstract base class for 2-D interpolation implementations - protected interface Impl //: IValue - { - void calculate(); - double xMin(); - double xMax(); - List xValues(); - int locateX(double x); - double yMin(); - double yMax(); - List yValues(); - int locateY(double y); - Matrix zData(); - bool isInRange(double x,double y); - double value(double x, double y); - } - - public abstract class templateImpl : Impl - { - protected List xBegin_; - protected List yBegin_; - protected int xSize_; - protected int ySize_; - protected Matrix zData_; - - // this method should be used for initialisation - protected templateImpl( List xBegin, int xSize, - List yBegin, int ySize, - Matrix zData) { - xBegin_ = xBegin; - xSize_ = xSize; - yBegin_ = yBegin; - ySize_ = ySize; - zData_ = zData; - - if (xSize < 2) - throw new ArgumentException("not enough points to interpolate: at least 2 required, " - + xSize + " provided"); - if (ySize < 2) - throw new ArgumentException("not enough points to interpolate: at least 2 required, " - + ySize + " provided"); - } - - public double xMin() { return xBegin_.First(); } - - public double xMax() { return xBegin_[xSize_ - 1]; } - - public List xValues() { return xBegin_.GetRange(0, xSize_); } - - public double yMin() { return yBegin_.First(); } - - public double yMax() { return yBegin_[ySize_ - 1]; } - - public List yValues() { return yBegin_.GetRange(0, ySize_); } - - public Matrix zData() {return zData_;} - - public bool isInRange(double x, double y) { - double x1 = xMin(), x2 = xMax(); - bool xIsInrange = (x >= x1 && x <= x2) || Utils.close(x, x1) || Utils.close(x, x2); - if (!xIsInrange) return false; - - double y1 = yMin(), y2 = yMax(); - return (y >= y1 && y <= y2) || Utils.close(y, y1) || Utils.close(y, y2); - } - - public int locateX(double x) { - int result = xBegin_.BinarySearch(x); - if (result < 0) - // The upper_bound() algorithm finds the last position in a sequence that value can occupy - // without violating the sequence's ordering - // if BinarySearch does not find value the value, the index of the next larger item is returned - result = ~result - 1; - - // impose limits. we need the one before last at max or the first at min - result = Math.Max(Math.Min(result, xSize_ - 2), 0); - return result; - } - - public int locateY(double y) { - int result = yBegin_.BinarySearch(y); - if (result < 0) - // The upper_bound() algorithm finds the last position in a sequence that value can occupy - // without violating the sequence's ordering - // if BinarySearch does not find value the value, the index of the next larger item is returned - result = ~result - 1; - - // impose limits. we need the one before last at max or the first at min - result = Math.Max(Math.Min(result, ySize_ - 2), 0); - return result; - } - - public abstract double value(double x, double y); - public abstract void calculate(); - - } - } -} diff --git a/src/QLNet/Math/KernelFunctions.cs b/src/QLNet/Math/KernelFunctions.cs index e81cd1788..77bb8bef2 100644 --- a/src/QLNet/Math/KernelFunctions.cs +++ b/src/QLNet/Math/KernelFunctions.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,37 +24,37 @@ namespace QLNet Derived classes will serve as functors. */ - - public interface IKernelFunction + + public interface IKernelFunction { double value(double x) ; } - + //! Gaussian kernel function - public class GaussianKernel : IKernelFunction + public class GaussianKernel : IKernelFunction { public GaussianKernel(double average, double sigma) { - nd_ = new NormalDistribution(average,sigma); - cnd_ = new CumulativeNormalDistribution(average,sigma); + nd_ = new NormalDistribution(average, sigma); + cnd_ = new CumulativeNormalDistribution(average, sigma); // normFact is \sqrt{2*\pi}. - normFact_ = Const.M_SQRT2*Const.M_SQRTPI; + normFact_ = Const.M_SQRT2 * Const.M_SQRTPI; } - public double value( double x ) + public double value(double x) { - return nd_.value(x)*normFact_; + return nd_.value(x) * normFact_; } - public double derivative( double x ) + public double derivative(double x) { - return nd_.derivative(x)*normFact_; + return nd_.derivative(x) * normFact_; } - public double primitive( double x ) + public double primitive(double x) { - return cnd_.value(x)*normFact_; + return cnd_.value(x) * normFact_; } private NormalDistribution nd_; diff --git a/src/QLNet/Math/LinearLeastSquaresRegression.cs b/src/QLNet/Math/LinearLeastSquaresRegression.cs new file mode 100644 index 000000000..2a4b09565 --- /dev/null +++ b/src/QLNet/Math/LinearLeastSquaresRegression.cs @@ -0,0 +1,162 @@ +/* + Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QLNet +{ + //! general linear least squares regression + /*! References: + "Numerical Recipes in C", 2nd edition, + Press, Teukolsky, Vetterling, Flannery, + + \test the correctness of the returned values is tested by + checking their properties. + */ + public class LinearLeastSquaresRegression : LinearLeastSquaresRegression + { + public LinearLeastSquaresRegression(List x, List y, List> v) + : base(x, y, v) { } + } + + public class LinearLeastSquaresRegression + { + private Vector a_, err_, residuals_, standardErrors_; + + public Vector coefficients() { return a_; } + public Vector residuals() { return residuals_; } + + //! standard parameter errors as given by Excel, R etc. + public Vector standardErrors() { return standardErrors_; } + //! modeling uncertainty as definied in Numerical Recipes + + public Vector error() { return err_; } + + + public LinearLeastSquaresRegression(List x, List y, List> v) + { + a_ = new Vector(v.Count, 0); + err_ = new Vector(v.Count, 0); + residuals_ = new Vector(x.Count, 0); + standardErrors_ = new Vector(v.Count, 0); + + Utils.QL_REQUIRE(x.Count == y.Count, () => "sample set need to be of the same size"); + Utils.QL_REQUIRE(x.Count >= v.Count, () => "sample set is too small"); + + int i; + int n = x.Count; + int m = v.Count; + + Matrix A = new Matrix(n, m); + for (i = 0; i < m; ++i) + x.ForEach((jj, xx) => A[jj, i] = v[i](xx)); + + SVD svd = new SVD(A); + Matrix V = svd.V(); + Matrix U = svd.U(); + Vector w = svd.singularValues(); + double threshold = n * Const.QL_EPSILON; + + for (i = 0; i < m; ++i) + { + if (w[i] > threshold) + { + double u = 0; + U.column(i).ForEach((ii, vv) => u += vv * y[ii]); + u /= w[i]; + + for (int j = 0; j < m; ++j) + { + a_[j] += u * V[j, i]; + err_[j] += V[j, i] * V[j, i] / (w[i] * w[i]); + } + } + } + err_ = Vector.Sqrt(err_); + residuals_ = A * a_ - new Vector(y); + + double chiSq = residuals_.Sum(r => r * r); + err_.ForEach((ii, vv) => standardErrors_[ii] = vv * Math.Sqrt(chiSq / (n - 2))); + } + } + + //! linear regression y_i = a_0 + a_1*x_0 +..+a_n*x_{n-1} + eps + public class LinearRegression + { + private LinearLeastSquaresRegression> reg_; + + + //! one dimensional linear regression + public LinearRegression(List x, List y) + { + reg_ = new LinearLeastSquaresRegression>(argumentWrapper(x), y, linearFcts(1)); + } + + //! multi dimensional linear regression + public LinearRegression(List> x, List y) + { + reg_ = new LinearLeastSquaresRegression>(x, y, linearFcts(x[0].Count)); + } + + public Vector coefficients() { return reg_.coefficients(); } + + public Vector residuals() { return reg_.residuals(); } + public Vector standardErrors() { return reg_.standardErrors(); } + + + class LinearFct + { + private int i_; + + public LinearFct(int i) + { + i_ = i; + } + + public double value(List x) + { + return x[i_]; + } + } + + private List, double>> linearFcts(int dims) + { + List, double>> retVal = new List, double>>(); + retVal.Add(x => 1.0); + + for (int i = 0; i < dims; ++i) + { + retVal.Add(new LinearFct(i).value); + } + + return retVal; + } + + private List> argumentWrapper(List x) + { + List> retVal = new List>(); + + foreach (var v in x) + retVal.Add(new List() { v }); + + return retVal; + } + } +} diff --git a/src/QLNet/Math/Matrix.cs b/src/QLNet/Math/Matrix.cs index 9502ae962..df63a4efd 100644 --- a/src/QLNet/Math/Matrix.cs +++ b/src/QLNet/Math/Matrix.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -54,14 +54,26 @@ public bool empty() public double this[int i, int j] { - get { return data_[i * columns_ + j]; } - set { data_[i * columns_ + j] = value; } + get + { + return data_[i * columns_ + j]; + } + set + { + data_[i * columns_ + j] = value; + } } public double this[int i] { - get { return data_[i]; } - set { data_[i] = value; } + get + { + return data_[i]; + } + set + { + data_[i] = value; + } } public Vector row(int r) @@ -164,12 +176,12 @@ public Matrix(Matrix from) private static Matrix operMatrix(ref Matrix m1, ref Matrix m2, Func func) { Utils.QL_REQUIRE(m1.rows_ == m2.rows_ && m1.columns_ == m2.columns_, () => - "operation on matrices with different sizes"); + "operation on matrices with different sizes"); Matrix result = new Matrix(m1.rows_, m1.columns_); for (int i = 0; i < m1.rows_; i++) - for (int j = 0; j < m1.columns_; j++) - result[i, j] = func(m1[i, j], m2[i, j]); + for (int j = 0; j < m1.columns_; j++) + result[i, j] = func(m1[i, j], m2[i, j]); return result; } @@ -177,16 +189,16 @@ private static Matrix operValue(ref Matrix m1, double value, Func "vectors and matrices with different sizes (" - + v.Count + ", " + m.rows() + "x" + m.columns() + - ") cannot be multiplied"); + + v.Count + ", " + m.rows() + "x" + m.columns() + + ") cannot be multiplied"); Vector result = new Vector(m.columns()); for (int i = 0; i < result.Count; i++) result[i] = v * m.column(i); @@ -197,8 +209,8 @@ private static Matrix operValue(ref Matrix m1, double value, Func "vectors and matrices with different sizes (" - + v.Count + ", " + m.rows() + "x" + m.columns() + - ") cannot be multiplied"); + + v.Count + ", " + m.rows() + "x" + m.columns() + + ") cannot be multiplied"); Vector result = new Vector(m.rows()); for (int i = 0; i < result.Count; i++) result[i] = m.row(i) * v; @@ -209,12 +221,12 @@ private static Matrix operValue(ref Matrix m1, double value, Func "matrices with different sizes (" + - m1.rows() + "x" + m1.columns() + ", " + - m2.rows() + "x" + m2.columns() + ") cannot be multiplied"); + m1.rows() + "x" + m1.columns() + ", " + + m2.rows() + "x" + m2.columns() + ") cannot be multiplied"); Matrix result = new Matrix(m1.rows(), m2.columns()); for (int i = 0; i < result.rows(); i++) - for (int j = 0; j < result.columns(); j++) - result[i, j] = m1.row(i) * m2.column(j); + for (int j = 0; j < result.columns(); j++) + result[i, j] = m1.row(i) * m2.column(j); return result; } @@ -224,8 +236,8 @@ public static Matrix transpose(Matrix m) { Matrix result = new Matrix(m.columns(), m.rows()); for (int i = 0; i < m.rows(); i++) - for (int j = 0; j < m.columns(); j++) - result[j, i] = m[i, j]; + for (int j = 0; j < m.columns(); j++) + result[j, i] = m[i, j]; return result; } @@ -235,8 +247,8 @@ public static Matrix inverse(Matrix m) int n = m.rows(); Matrix result = new Matrix(n, n); for (int i = 0; i < n; ++i) - for (int j = 0; j < n; ++j) - result[i, j] = m[i, j]; + for (int j = 0; j < n; ++j) + result[i, j] = m[i, j]; Matrix lum; int[] perm; @@ -251,7 +263,7 @@ public static Matrix inverse(Matrix m) else b[j] = 0.0; - double[] x = Helper(lum, b); // + double[] x = Helper(lum, b); // for (int j = 0; j < n; ++j) result[j, i] = x[j]; } @@ -272,8 +284,8 @@ public static int decompose(Matrix m, out Matrix lum, out int[] perm) // Make a copy of Matrix m into result Matrix lu lum = new Matrix(n, n); for (int i = 0; i < n; ++i) - for (int j = 0; j < n; ++j) - lum[i, j] = m[i, j]; + for (int j = 0; j < n; ++j) + lum[i, j] = m[i, j]; // make perm[] @@ -281,7 +293,7 @@ public static int decompose(Matrix m, out Matrix lum, out int[] perm) for (int i = 0; i < n; ++i) perm[i] = i; - for (int j = 0; j < n - 1; ++j) // process by column. note n-1 + for (int j = 0; j < n - 1; ++j) // process by column. note n-1 { double max = Math.Abs(lum[j, j]); int piv = j; @@ -360,8 +372,8 @@ public static Matrix outerProduct(List v1begin, List v2begin) Matrix result = new Matrix(size1, size2); for (int i = 0; i < v1begin.Count; i++) - for (int j = 0; j < v2begin.Count; j++) - result[i, j] = v1begin[i] * v2begin[j]; + for (int j = 0; j < v2begin.Count; j++) + result[i, j] = v1begin[i] * v2begin[j]; return result; } diff --git a/src/QLNet/Math/ModifiedBessel.cs b/src/QLNet/Math/ModifiedBessel.cs index 56f0ed090..9fcfc23df 100644 --- a/src/QLNet/Math/ModifiedBessel.cs +++ b/src/QLNet/Math/ModifiedBessel.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -35,37 +35,37 @@ times exp(-x) resp exp(-z) public interface Weight { - T weightSmallX( T x ); - T weight1LargeX( T x ); - T weight2LargeX( T x ); + T weightSmallX(T x); + T weight1LargeX(T x); + T weight2LargeX(T x); } public class doubleUnweighted : Weight { - public double weightSmallX( double x ) { return 1.0; } - public double weight1LargeX( double x ) { return Math.Exp( x ); } - public double weight2LargeX( double x ) { return Math.Exp( -x ); } + public double weightSmallX(double x) { return 1.0; } + public double weight1LargeX(double x) { return Math.Exp(x); } + public double weight2LargeX(double x) { return Math.Exp(-x); } } public class complexUnweighted : Weight { - public Complex weightSmallX( Complex x ) { return 1.0; } - public Complex weight1LargeX( Complex x ) { return Complex.Exp( x ); } - public Complex weight2LargeX( Complex x ) { return Complex.Exp( -x ); } + public Complex weightSmallX(Complex x) { return 1.0; } + public Complex weight1LargeX(Complex x) { return Complex.Exp(x); } + public Complex weight2LargeX(Complex x) { return Complex.Exp(-x); } } public class doubleExponentiallyWeighted : Weight { - public double weightSmallX( double x ) { return Math.Exp( -x ); } - public double weight1LargeX( double x ) { return 1.0; } - public double weight2LargeX( double x ) { return Math.Exp( -2.0 * x ); } + public double weightSmallX(double x) { return Math.Exp(-x); } + public double weight1LargeX(double x) { return 1.0; } + public double weight2LargeX(double x) { return Math.Exp(-2.0 * x); } } public class complexExponentiallyWeighted : Weight { - public Complex weightSmallX( Complex x ) { return Complex.Exp( -x ); } - public Complex weight1LargeX( Complex x ) { return 1.0; } - public Complex weight2LargeX( Complex x ) { return Complex.Exp( -2.0 * x ); } + public Complex weightSmallX(Complex x) { return Complex.Exp(-x); } + public Complex weight1LargeX(Complex x) { return 1.0; } + public Complex weight2LargeX(Complex x) { return Complex.Exp(-2.0 * x); } } public interface baseValue @@ -80,70 +80,70 @@ public class doubleValue : baseValue public class complexValue : baseValue { - public Complex value() { return new Complex( 0.0, 1.0 ); } + public Complex value() { return new Complex(0.0, 1.0); } } // Implementation - public static double modifiedBesselFunction_i( double nu, double x ) + public static double modifiedBesselFunction_i(double nu, double x) { - Utils.QL_REQUIRE( x >= 0.0, () => "negative argument requires complex version of modifiedBesselFunction" ); - return modifiedBesselFunction_i_impl( nu, x ); + Utils.QL_REQUIRE(x >= 0.0, () => "negative argument requires complex version of modifiedBesselFunction"); + return modifiedBesselFunction_i_impl(nu, x); } - public static Complex modifiedBesselFunction_i( double nu, Complex z ) + public static Complex modifiedBesselFunction_i(double nu, Complex z) { - return modifiedBesselFunction_i_impl( nu, z ); + return modifiedBesselFunction_i_impl(nu, z); } - public static double modifiedBesselFunction_k( double nu, double x ) + public static double modifiedBesselFunction_k(double nu, double x) { - return modifiedBesselFunction_k_impl( nu, x ); + return modifiedBesselFunction_k_impl(nu, x); } - public static Complex modifiedBesselFunction_k(double nu, Complex z) + public static Complex modifiedBesselFunction_k(double nu, Complex z) { - return modifiedBesselFunction_k_impl( nu, z ); + return modifiedBesselFunction_k_impl(nu, z); } - public static double modifiedBesselFunction_i_exponentiallyWeighted(double nu, double x) + public static double modifiedBesselFunction_i_exponentiallyWeighted(double nu, double x) { - Utils.QL_REQUIRE(x >= 0.0, ()=>"negative argument requires complex version of modifiedBesselFunction"); - return modifiedBesselFunction_i_impl( nu, x ); + Utils.QL_REQUIRE(x >= 0.0, () => "negative argument requires complex version of modifiedBesselFunction"); + return modifiedBesselFunction_i_impl(nu, x); } - public static Complex modifiedBesselFunction_i_exponentiallyWeighted(double nu, Complex z) + public static Complex modifiedBesselFunction_i_exponentiallyWeighted(double nu, Complex z) { - return modifiedBesselFunction_i_impl( nu, z ); + return modifiedBesselFunction_i_impl(nu, z); } - public static double modifiedBesselFunction_k_exponentiallyWeighted( double nu, double x ) + public static double modifiedBesselFunction_k_exponentiallyWeighted(double nu, double x) { - return modifiedBesselFunction_k_impl( nu, x ); + return modifiedBesselFunction_k_impl(nu, x); } - public static Complex modifiedBesselFunction_k_exponentiallyWeighted(double nu, Complex z) + public static Complex modifiedBesselFunction_k_exponentiallyWeighted(double nu, Complex z) { - return modifiedBesselFunction_k_impl( nu, z ); + return modifiedBesselFunction_k_impl(nu, z); } - public static double modifiedBesselFunction_i_impl( double nu, double x ) - where T : Weight, new() - where I : baseValue, new() + public static double modifiedBesselFunction_i_impl(double nu, double x) + where T : Weight, new () + where I : baseValue, new () { - if ( Math.Abs( x ) < 13.0 ) + if (Math.Abs(x) < 13.0) { - double alpha = Math.Pow( 0.5 * x, nu ) / GammaFunction.value( 1.0 + nu ); + double alpha = Math.Pow(0.5 * x, nu) / GammaFunction.value(1.0 + nu); double Y = 0.25 * x * x; int k = 1; double sum = alpha, B_k = alpha; - while ( Math.Abs( B_k *= Y / ( k * ( k + nu ) ) ) > Math.Abs( sum ) * Const.QL_EPSILON ) + while (Math.Abs(B_k *= Y / (k * (k + nu))) > Math.Abs(sum) * Const.QL_EPSILON) { sum += B_k; - Utils.QL_REQUIRE( ++k < 1000, () => "max iterations exceeded" ); + Utils.QL_REQUIRE(++k < 1000, () => "max iterations exceeded"); } - return sum * FastActivator.Create().weightSmallX( x ); + return sum* FastActivator.Create().weightSmallX(x); } else { @@ -151,13 +151,13 @@ public static double modifiedBesselFunction_i_impl( double nu, double x ) double da_k = 1.0; double s1 = 1.0, s2 = 1.0; - for ( int k = 1; k < 30; ++k ) + for (int k = 1; k < 30; ++k) { sign *= -1; - na_k *= ( 4.0 * nu * nu - - ( 2.0 * k - 1.0 ) * - ( 2.0 * k - 1.0 ) ); - da_k *= ( 8.0 * k ) * x; + na_k *= (4.0 * nu * nu - + (2.0 * k - 1.0) * + (2.0 * k - 1.0)); + da_k *= (8.0 * k) * x; double a_k = na_k / da_k; s2 += a_k; @@ -165,43 +165,43 @@ public static double modifiedBesselFunction_i_impl( double nu, double x ) } double i = FastActivator.Create().value(); - return 1.0 / Math.Sqrt( 2 * Const.M_PI * x ) * - (FastActivator.Create().weight1LargeX( x ) * s1 + - i * Math.Exp( i * nu * Const.M_PI ) * FastActivator.Create().weight2LargeX( x ) * s2 ); + return 1.0 / Math.Sqrt(2 * Const.M_PI * x) * + (FastActivator.Create().weight1LargeX(x) * s1 + + i * Math.Exp(i * nu * Const.M_PI) * FastActivator.Create().weight2LargeX(x) * s2); } } - public static Complex modifiedBesselFunction_i_impl( double nu, Complex x ) - where T : Weight, new() - where I : baseValue, new() + public static Complex modifiedBesselFunction_i_impl(double nu, Complex x) + where T : Weight, new () + where I : baseValue, new () { - if ( Complex.Abs( x ) < 13.0 ) + if (Complex.Abs(x) < 13.0) { - Complex alpha = Complex.Pow( 0.5 * x, nu ) / GammaFunction.value( 1.0 + nu ); + Complex alpha = Complex.Pow(0.5 * x, nu) / GammaFunction.value(1.0 + nu); Complex Y = 0.25 * x * x; int k = 1; Complex sum = alpha, B_k = alpha; - while ( Complex.Abs( B_k *= Y / ( k * ( k + nu ) ) ) > Complex.Abs( sum ) * Const.QL_EPSILON ) + while (Complex.Abs(B_k *= Y / (k * (k + nu))) > Complex.Abs(sum) * Const.QL_EPSILON) { sum += B_k; - Utils.QL_REQUIRE( ++k < 1000, () => "max iterations exceeded" ); + Utils.QL_REQUIRE(++k < 1000, () => "max iterations exceeded"); } - return sum * FastActivator.Create().weightSmallX( x ); + return sum* FastActivator.Create().weightSmallX(x); } else { double na_k = 1.0, sign = 1.0; - Complex da_k = new Complex( 1.0, 0.0 ); + Complex da_k = new Complex(1.0, 0.0); - Complex s1 = new Complex( 1.0, 0.0 ), s2 = new Complex( 1.0, 0.0 ); - for ( int k = 1; k < 30; ++k ) + Complex s1 = new Complex(1.0, 0.0), s2 = new Complex(1.0, 0.0); + for (int k = 1; k < 30; ++k) { sign *= -1; - na_k *= ( 4.0 * nu * nu - - ( 2.0 * (double)k - 1.0 ) * - ( 2.0 * (double)k - 1.0 ) ); - da_k *= ( 8.0 * k ) * x; + na_k *= (4.0 * nu * nu - + (2.0 * (double)k - 1.0) * + (2.0 * (double)k - 1.0)); + da_k *= (8.0 * k) * x; Complex a_k = na_k / da_k; s2 += a_k; @@ -209,29 +209,29 @@ public static Complex modifiedBesselFunction_i_impl( double nu, Complex x } Complex i = FastActivator.Create().value(); - return 1.0 / Complex.Sqrt( 2 * Const.M_PI * x ) * - (FastActivator.Create().weight1LargeX( x ) * s1 + - i * Complex.Exp( i * nu * Const.M_PI ) * FastActivator.Create().weight2LargeX( x ) * s2 ); + return 1.0 / Complex.Sqrt(2 * Const.M_PI * x) * + (FastActivator.Create().weight1LargeX(x) * s1 + + i * Complex.Exp(i * nu * Const.M_PI) * FastActivator.Create().weight2LargeX(x) * s2); } } - public static double modifiedBesselFunction_k_impl( double nu, double x ) - where T : Weight, new() - where I : baseValue, new() + public static double modifiedBesselFunction_k_impl(double nu, double x) + where T : Weight, new () + where I : baseValue, new () { - return Const.M_PI_2 * ( modifiedBesselFunction_i_impl( -nu, x ) - - modifiedBesselFunction_i_impl( nu, x ) ) / - Math.Sin( Const.M_PI * nu ); + return Const.M_PI_2 * (modifiedBesselFunction_i_impl(-nu, x) - + modifiedBesselFunction_i_impl(nu, x)) / + Math.Sin(Const.M_PI * nu); } - public static Complex modifiedBesselFunction_k_impl( double nu, Complex x ) - where T : Weight, new() - where I : baseValue, new() + public static Complex modifiedBesselFunction_k_impl(double nu, Complex x) + where T : Weight, new () + where I : baseValue, new () { - return Const.M_PI_2 * ( modifiedBesselFunction_i_impl( -nu, x ) - - modifiedBesselFunction_i_impl( nu, x ) ) / - Math.Sin( Const.M_PI * nu ); + return Const.M_PI_2 * (modifiedBesselFunction_i_impl(-nu, x) - + modifiedBesselFunction_i_impl(nu, x)) / + Math.Sin(Const.M_PI * nu); } } } diff --git a/src/QLNet/Math/NumericalDifferentiation.cs b/src/QLNet/Math/NumericalDifferentiation.cs index 1673486f2..7f4b75e69 100644 --- a/src/QLNet/Math/NumericalDifferentiation.cs +++ b/src/QLNet/Math/NumericalDifferentiation.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -32,111 +32,120 @@ namespace QLNet /// /// public class NumericalDifferentiation - { - public enum Scheme { Central, Backward, Forward }; - - public NumericalDifferentiation(Func f, - int orderOfDerivative, - Vector x_offsets) - { - f_ = f; - offsets_ = x_offsets; - w_ = calcWeights(offsets_, orderOfDerivative); - } - - public NumericalDifferentiation(Func f, - int orderOfDerivative, - double stepSize, - int steps, - Scheme scheme) - { - f_ = f; - offsets_ = calcOffsets(stepSize, steps, scheme); - w_ = calcWeights(offsets_, orderOfDerivative); - } - - public double value(double x) - { - double s = 0.0; - for (int i=0; i < w_.size(); ++i) { - if (Math.Abs(w_[i]) > Const.QL_EPSILON * Const.QL_EPSILON) - { - s += w_[i] * f_(x+offsets_[i]); - } + { + public enum Scheme { Central, Backward, Forward } + + public NumericalDifferentiation(Func f, + int orderOfDerivative, + Vector x_offsets) + { + f_ = f; + offsets_ = x_offsets; + w_ = calcWeights(offsets_, orderOfDerivative); + } + + public NumericalDifferentiation(Func f, + int orderOfDerivative, + double stepSize, + int steps, + Scheme scheme) + { + f_ = f; + offsets_ = calcOffsets(stepSize, steps, scheme); + w_ = calcWeights(offsets_, orderOfDerivative); + } + + public double value(double x) + { + double s = 0.0; + for (int i = 0; i < w_.size(); ++i) + { + if (Math.Abs(w_[i]) > Const.QL_EPSILON * Const.QL_EPSILON) + { + s += w_[i] * f_(x + offsets_[i]); } - return s; - } - - public Vector offsets() { return offsets_; } - public Vector weights() { return w_; } - - // This is a C# implementation of the algorithm/pseudo code in - // B. Fornberg, 1998. Calculation of Weights - // in Finite Difference Formulas - // https://amath.colorado.edu/faculty/fornberg/Docs/sirev_cl.pdf - protected Vector calcWeights(Vector x, int M) { - int N = x.size(); - Utils.QL_REQUIRE(N > M, () => "number of points must be greater " - + "than the order of the derivative"); - - double[,,] d = new double[M+1,N,N]; - d[0,0,0] = 1.0; - double c1 = 1.0; - - for (int n=1; n < N; ++n) { - double c2 = 1.0; - for (int nu=0; nu < n; ++nu) { - double c3 = x[n] - x[nu]; - c2*=c3; - - for (int m=0; m <= Math.Min(n, M); ++m) { - d[m,n,nu] = (x[n]*d[m,n-1,nu] - - ((m > 0)? m*d[m-1,n-1,nu] : 0.0))/c3; - } - } - - for (int m=0; m <= M; ++m) { - d[m,n,n] = c1/c2*( ((m > 0)? m*d[m-1,n-1,n-1] : 0.0) - - x[n-1]*d[m,n-1,n-1] ); - } - c1=c2; + } + return s; + } + + public Vector offsets() { return offsets_; } + public Vector weights() { return w_; } + + // This is a C# implementation of the algorithm/pseudo code in + // B. Fornberg, 1998. Calculation of Weights + // in Finite Difference Formulas + // https://amath.colorado.edu/faculty/fornberg/Docs/sirev_cl.pdf + protected Vector calcWeights(Vector x, int M) + { + int N = x.size(); + Utils.QL_REQUIRE(N > M, () => "number of points must be greater " + + "than the order of the derivative"); + + double[,,] d = new double[M + 1, N, N]; + d[0, 0, 0] = 1.0; + double c1 = 1.0; + + for (int n = 1; n < N; ++n) + { + double c2 = 1.0; + for (int nu = 0; nu < n; ++nu) + { + double c3 = x[n] - x[nu]; + c2 *= c3; + + for (int m = 0; m <= Math.Min(n, M); ++m) + { + d[m, n, nu] = (x[n] * d[m, n - 1, nu] + - ((m > 0) ? m * d[m - 1, n - 1, nu] : 0.0)) / c3; + } } - Vector retVal = new Vector(N); - for (int i=0; i < N; ++i) { - retVal[i] = d[M,N-1,i]; + for (int m = 0; m <= M; ++m) + { + d[m, n, n] = c1 / c2 * (((m > 0) ? m * d[m - 1, n - 1, n - 1] : 0.0) - + x[n - 1] * d[m, n - 1, n - 1]); } - return retVal; - } - - protected Vector calcOffsets(double h, int n, Scheme scheme) { - Utils.QL_REQUIRE(n > 1, () => "number of steps must be greater than one"); - - Vector retVal = new Vector(n); - switch (scheme) { - case Scheme.Central: - Utils.QL_REQUIRE(n > 2 && (n % 2) > 0, - () => "number of steps must be an odd number greater than two"); - for (int i=0; i < n; ++i) - retVal[i] = (i-n/2)*h; - break; - case Scheme.Backward: - for (int i = 0; i < n; ++i) - retVal[i]=-(i*h); - break; - case Scheme.Forward: - for (int i = 0; i < n; ++i) - retVal[i]=i*h; - break; - default: - Utils.QL_FAIL("unknown numerical differentiation scheme"); - break; - } - - return retVal; - } - - protected Vector offsets_, w_; - protected Func f_; - } + c1 = c2; + } + + Vector retVal = new Vector(N); + for (int i = 0; i < N; ++i) + { + retVal[i] = d[M, N - 1, i]; + } + return retVal; + } + + protected Vector calcOffsets(double h, int n, Scheme scheme) + { + Utils.QL_REQUIRE(n > 1, () => "number of steps must be greater than one"); + + Vector retVal = new Vector(n); + switch (scheme) + { + case Scheme.Central: + Utils.QL_REQUIRE(n > 2 && (n % 2) > 0, + () => "number of steps must be an odd number greater than two"); + for (int i = 0; i < n; ++i) + retVal[i] = (i - n / 2) * h; + break; + case Scheme.Backward: + for (int i = 0; i < n; ++i) + retVal[i] = -(i * h); + break; + case Scheme.Forward: + for (int i = 0; i < n; ++i) + retVal[i] = i * h; + break; + default: + Utils.QL_FAIL("unknown numerical differentiation scheme"); + break; + } + + return retVal; + } + + protected Vector offsets_, w_; + protected Func f_; + } } diff --git a/src/QLNet/Math/ODE/AdaptiveRungeKutta.cs b/src/QLNet/Math/ODE/AdaptiveRungeKutta.cs index 79b844dd6..61e90278c 100644 --- a/src/QLNet/Math/ODE/AdaptiveRungeKutta.cs +++ b/src/QLNet/Math/ODE/AdaptiveRungeKutta.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -42,8 +42,8 @@ public class AdaptiveRungeKutta */ public AdaptiveRungeKutta(double eps = 1.0e-6, - double h1 = 1.0e-4, - double hmin = 0.0) + double h1 = 1.0e-4, + double hmin = 0.0) { eps_ = eps; h1_ = h1; @@ -87,9 +87,9 @@ public AdaptiveRungeKutta(double eps = 1.0e-6, \rightarrow K^n \f$ as \f$ f'(x) = F(x,f(x)) \f$, $K=R, C$ */ public List value(OdeFct ode, - List y1, - double x1, - double x2) + List y1, + double x1, + double x2) { int n = y1.Count; List y = new List(y1); @@ -121,23 +121,23 @@ public List value(OdeFct ode, } public double value(OdeFct1d ode, - double y1, - double x1, - double x2) + double y1, + double x1, + double x2) { return value(new OdeFctWrapper(ode).value, - new InitializedList(1, y1), x1, x2)[0]; + new InitializedList(1, y1), x1, x2)[0]; } protected void rkqs(List y, - List dydx, - ref double x, - double htry, - double eps, - List yScale, - ref double hdid, - ref double hnext, - OdeFct derivs) + List dydx, + ref double x, + double htry, + double eps, + List yScale, + ref double hdid, + ref double hnext, + OdeFct derivs) { int n = y.Count; double errmax, xnew; @@ -185,20 +185,20 @@ protected void rkqs(List y, } protected void rkck(List y, - List dydx, - ref double x, - double h, - ref List yout, - ref List yerr, - OdeFct derivs) + List dydx, + ref double x, + double h, + ref List yout, + ref List yerr, + OdeFct derivs) { int n = y.Count; List ak2 = new List(n), - ak3 = new List(n), - ak4 = new List(n), - ak5 = new List(n), - ak6 = new List(n), - ytemp = new List(n); + ak3 = new List(n), + ak4 = new List(n), + ak5 = new List(n), + ak6 = new List(n), + ytemp = new List(n); // first step for (int i = 0; i < n; i++) @@ -237,41 +237,41 @@ protected void rkck(List y, protected double eps_, h1_, hmin_; protected double a2, - a3, - a4, - a5, - a6, - b21, - b31, - b32, - b41, - b42, - b43, - b51, - b52, - b53, - b54, - b61, - b62, - b63, - b64, - b65, - c1, - c3, - c4, - c6, - dc1, - dc3, - dc4, - dc5, - dc6; + a3, + a4, + a5, + a6, + b21, + b31, + b32, + b41, + b42, + b43, + b51, + b52, + b53, + b54, + b61, + b62, + b63, + b64, + b65, + c1, + c3, + c4, + c6, + dc1, + dc3, + dc4, + dc5, + dc6; protected const double ADAPTIVERK_MAXSTP = 10000.0, - ADAPTIVERK_TINY = 1.0E-30, - ADAPTIVERK_SAFETY = 0.9, - ADAPTIVERK_PGROW = -0.2, - ADAPTIVERK_PSHRINK = -0.25, - ADAPTIVERK_ERRCON = 1.89E-4; + ADAPTIVERK_TINY = 1.0E-30, + ADAPTIVERK_SAFETY = 0.9, + ADAPTIVERK_PGROW = -0.2, + ADAPTIVERK_PSHRINK = -0.25, + ADAPTIVERK_ERRCON = 1.89E-4; public class OdeFctWrapper { diff --git a/src/QLNet/Math/Optimization/ArmijoLineSearch.cs b/src/QLNet/Math/Optimization/ArmijoLineSearch.cs index 1aa352622..8a54499ec 100644 --- a/src/QLNet/Math/Optimization/ArmijoLineSearch.cs +++ b/src/QLNet/Math/Optimization/ArmijoLineSearch.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -25,7 +25,7 @@ namespace QLNet // (see Polak, Algorithms and consistent approximations, Optimization, // volume 124 of Applied Mathematical Sciences, Springer-Verlag, NY, // 1997) - // + // public class ArmijoLineSearch : LineSearch { //! Default constructor @@ -88,8 +88,9 @@ public override double value(Problem P, ref EndCriteria.Type ecType, EndCriteria P.gradient(gradient_, xtd_); // and it squared norm maxIter = endCriteria.checkMaxIterations(loopNumber, ref ecType); - } while ((((qt_ - q0) > (-alpha_ * t * qpt_)) || ((qtold - q0) <= (-alpha_ * t * qpt_ / beta_))) && - (!maxIter)); + } + while ((((qt_ - q0) > (-alpha_ * t * qpt_)) || ((qtold - q0) <= (-alpha_ * t * qpt_ / beta_))) && + (!maxIter)); } if (maxIter) diff --git a/src/QLNet/Math/Optimization/BFGS.cs b/src/QLNet/Math/Optimization/BFGS.cs index 912eab32f..08304e333 100644 --- a/src/QLNet/Math/Optimization/BFGS.cs +++ b/src/QLNet/Math/Optimization/BFGS.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -26,21 +26,21 @@ User has to provide line-search method and optimization end criteria. */ public class BFGS : LineSearchBasedMethod { - public BFGS( LineSearch lineSearch = null) - : base(lineSearch) + public BFGS(LineSearch lineSearch = null) + : base(lineSearch) { inverseHessian_ = new Matrix(); } - + // LineSearchBasedMethod interface - protected override Vector getUpdatedDirection(Problem P,double gold2,Vector oldGradient) + protected override Vector getUpdatedDirection(Problem P, double gold2, Vector oldGradient) { if (inverseHessian_.rows() == 0) { // first time in this update, we create needed structures - inverseHessian_ = new Matrix(P.currentValue().size(),P.currentValue().size(), 0.0); + inverseHessian_ = new Matrix(P.currentValue().size(), P.currentValue().size(), 0.0); for (int i = 0; i < P.currentValue().size(); ++i) - inverseHessian_[i,i] = 1.0; + inverseHessian_[i, i] = 1.0; } Vector diffGradient = new Vector(); @@ -49,7 +49,7 @@ protected override Vector getUpdatedDirection(Problem P,double gold2,Vector oldG diffGradient = lineSearch_.lastGradient() - oldGradient; for (int i = 0; i < P.currentValue().size(); ++i) for (int j = 0; j < P.currentValue().size(); ++j) - diffGradientWithHessianApplied[i] += inverseHessian_[i,j] * diffGradient[j]; + diffGradientWithHessianApplied[i] += inverseHessian_[i, j] * diffGradient[j]; double fac, fae, fad; double sumdg, sumxi; @@ -74,9 +74,9 @@ protected override Vector getUpdatedDirection(Problem P,double gold2,Vector oldG for (int i = 0; i < P.currentValue().size(); ++i) for (int j = 0; j < P.currentValue().size(); ++j) { - inverseHessian_[i,j] += fac * lineSearch_.searchDirection[i] * lineSearch_.searchDirection[j]; - inverseHessian_[i,j] -= fad * diffGradientWithHessianApplied[i] * diffGradientWithHessianApplied[j]; - inverseHessian_[i,j] += fae * diffGradient[i] * diffGradient[j]; + inverseHessian_[i, j] += fac * lineSearch_.searchDirection[i] * lineSearch_.searchDirection[j]; + inverseHessian_[i, j] -= fad * diffGradientWithHessianApplied[i] * diffGradientWithHessianApplied[j]; + inverseHessian_[i, j] += fae * diffGradient[i] * diffGradient[j]; } } @@ -85,10 +85,10 @@ protected override Vector getUpdatedDirection(Problem P,double gold2,Vector oldG { direction[i] = 0.0; for (int j = 0; j < P.currentValue().size(); ++j) - direction[i] -= inverseHessian_[i,j] * lineSearch_.lastGradient()[j]; + direction[i] -= inverseHessian_[i, j] * lineSearch_.lastGradient()[j]; } - return direction; + return direction; } diff --git a/src/QLNet/Math/Optimization/ConjugateGradient.cs b/src/QLNet/Math/Optimization/ConjugateGradient.cs index ada602a7d..944449a2e 100644 --- a/src/QLNet/Math/Optimization/ConjugateGradient.cs +++ b/src/QLNet/Math/Optimization/ConjugateGradient.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -37,10 +37,10 @@ public ConjugateGradient(LineSearch lineSearch = null) : base(lineSearch) {} - protected override Vector getUpdatedDirection( Problem P, double gold2, Vector gradient ) + protected override Vector getUpdatedDirection(Problem P, double gold2, Vector gradient) { - return lineSearch_.lastGradient()*-1 + - ( P.gradientNormValue() / gold2 ) * lineSearch_.searchDirection; + return lineSearch_.lastGradient() * -1 + + (P.gradientNormValue() / gold2) * lineSearch_.searchDirection; } } } \ No newline at end of file diff --git a/src/QLNet/Math/Optimization/Constraint.cs b/src/QLNet/Math/Optimization/Constraint.cs index e20784e22..76747840e 100644 --- a/src/QLNet/Math/Optimization/Constraint.cs +++ b/src/QLNet/Math/Optimization/Constraint.cs @@ -2,18 +2,18 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,9 +24,9 @@ namespace QLNet { public interface IConstraint { - bool test( Vector param ); - Vector upperBound( Vector parameters ); - Vector lowerBound( Vector parameters ); + bool test(Vector param); + Vector upperBound(Vector parameters); + Vector lowerBound(Vector parameters); } //! Base constraint class @@ -35,44 +35,54 @@ public class Constraint protected IConstraint impl_; public bool empty() { return impl_ == null; } - public Constraint() : this( null ) { } - public Constraint( IConstraint impl ) + public Constraint() : this(null) { } + public Constraint(IConstraint impl) { impl_ = impl; } - public double update( ref Vector p, Vector direction, double beta ) + public double update(ref Vector p, Vector direction, double beta) { double diff = beta; Vector newParams = p + diff * direction; - bool valid = test( newParams ); + bool valid = test(newParams); int icount = 0; - while ( !valid ) + while (!valid) { - if ( icount > 200 ) - Utils.QL_FAIL( "can't update parameter vector" ); + if (icount > 200) + Utils.QL_FAIL("can't update parameter vector"); diff *= 0.5; icount++; newParams = p + diff * direction; - valid = test( newParams ); + valid = test(newParams); } p += diff * direction; return diff; } //! Tests if params satisfy the constraint - public virtual bool test( Vector p ) { return impl_.test( p ); } - + public virtual bool test(Vector p) { return impl_.test(p); } + //! Returns upper bound for given parameters - public virtual Vector upperBound(Vector parameters) + public virtual Vector upperBound(Vector parameters) { - return impl_.upperBound( parameters ); + Vector result = impl_.upperBound(parameters); + Utils.QL_REQUIRE(parameters.size() == result.size(), () => + "upper bound size (" + result.size() + + ") not equal to params size (" + + parameters.size() + ")"); + return result; } - + //! Returns lower bound for given parameters - public virtual Vector lowerBound(Vector parameters) + public virtual Vector lowerBound(Vector parameters) { - return impl_.lowerBound( parameters ); // + Vector result = impl_.lowerBound(parameters); + Utils.QL_REQUIRE(parameters.size() == result.size(), () => + "lower bound size (" + result.size() + + ") not equal to params size (" + + parameters.size() + ")"); + return result; } } @@ -81,35 +91,35 @@ public class NoConstraint : Constraint { private class Impl : IConstraint { - public bool test( Vector v ) { return true; } + public bool test(Vector v) { return true; } public Vector upperBound(Vector parameters) { - return new Vector( parameters.size(), Double.MaxValue ); + return new Vector(parameters.size(), Double.MaxValue); } public Vector lowerBound(Vector parameters) { - return new Vector( parameters.size(), Double.MinValue ); + return new Vector(parameters.size(), Double.MinValue); } } - public NoConstraint() : base( new Impl() ) { } - }; + public NoConstraint() : base(new Impl()) { } + } //! %Constraint imposing positivity to all arguments public class PositiveConstraint : Constraint { public PositiveConstraint() - : base( new PositiveConstraint.Impl() ) + : base(new PositiveConstraint.Impl()) { } private class Impl : IConstraint { - public bool test( Vector v ) + public bool test(Vector v) { - for ( int i = 0; i < v.Count; ++i ) + for (int i = 0; i < v.Count; ++i) { - if ( v[i] <= 0.0 ) + if (v[i] <= 0.0) return false; } return true; @@ -117,12 +127,12 @@ public bool test( Vector v ) public Vector upperBound(Vector parameters) { - return new Vector( parameters.size(), Double.MaxValue ); + return new Vector(parameters.size(), Double.MaxValue); } public Vector lowerBound(Vector parameters) { - return new Vector( parameters.size(), 0.0 ); + return new Vector(parameters.size(), 0.0); } } } @@ -130,8 +140,8 @@ public Vector lowerBound(Vector parameters) //! %Constraint imposing all arguments to be in [low,high] public class BoundaryConstraint : Constraint { - public BoundaryConstraint( double low, double high ) - : base( new BoundaryConstraint.Impl( low, high ) ) + public BoundaryConstraint(double low, double high) + : base(new BoundaryConstraint.Impl(low, high)) { } @@ -140,16 +150,16 @@ private class Impl : IConstraint private double low_; private double high_; - public Impl( double low, double high ) + public Impl(double low, double high) { low_ = low; high_ = high; } - public bool test( Vector v ) + public bool test(Vector v) { - for ( int i = 0; i < v.Count; i++ ) + for (int i = 0; i < v.Count; i++) { - if ( ( v[i] < low_ ) || ( v[i] > high_ ) ) + if ((v[i] < low_) || (v[i] > high_)) return false; } return true; @@ -170,21 +180,21 @@ public Vector lowerBound(Vector parameters) //! %Constraint enforcing both given sub-constraints public class CompositeConstraint : Constraint { - public CompositeConstraint( Constraint c1, Constraint c2 ) : base( new Impl( c1, c2 ) ) { } + public CompositeConstraint(Constraint c1, Constraint c2) : base(new Impl(c1, c2)) { } private class Impl : IConstraint { private Constraint c1_, c2_; - public Impl( Constraint c1, Constraint c2 ) + public Impl(Constraint c1, Constraint c2) { c1_ = c1; c2_ = c2; } - public bool test( Vector p ) + public bool test(Vector p) { - return c1_.test( p ) && c2_.test( p ); + return c1_.test(p) && c2_.test(p); } public Vector upperBound(Vector parameters) @@ -192,12 +202,12 @@ public Vector upperBound(Vector parameters) Vector c1ub = c1_.upperBound(parameters); Vector c2ub = c2_.upperBound(parameters); Vector rtrnArray = new Vector(c1ub.size(), 0.0); - - for (int iter = 0; iter < c1ub.size(); iter++) + + for (int iter = 0; iter < c1ub.size(); iter++) { rtrnArray[iter] = Math.Min(c1ub[iter], c2ub[iter]); } - + return rtrnArray; } @@ -206,58 +216,58 @@ public Vector lowerBound(Vector parameters) Vector c1lb = c1_.lowerBound(parameters); Vector c2lb = c2_.lowerBound(parameters); Vector rtrnArray = new Vector(c1lb.size(), 0.0); - - for (int iter = 0; iter < c1lb.size(); iter++) + + for (int iter = 0; iter < c1lb.size(); iter++) { rtrnArray[iter] = Math.Max(c1lb[iter], c2lb[iter]); - + } - + return rtrnArray; } } } - + //! %Constraint imposing i-th argument to be in [low_i,high_i] for all i - public class NonhomogeneousBoundaryConstraint: Constraint + public class NonhomogeneousBoundaryConstraint: Constraint { private class Impl: IConstraint { - public Impl(Vector low, Vector high) - { - low_ = low; - high_ = high; - Utils.QL_REQUIRE(low_.Count==high_.Count,()=> "Upper and lower boundaries sizes are inconsistent."); - } + public Impl(Vector low, Vector high) + { + low_ = low; + high_ = high; + Utils.QL_REQUIRE(low_.Count == high_.Count, () => "Upper and lower boundaries sizes are inconsistent."); + } public bool test(Vector parameters) { Utils.QL_REQUIRE(parameters.size() == low_.Count, () => - "Number of parameters and boundaries sizes are inconsistent."); - - for (int i = 0; i < parameters.size(); i++) + "Number of parameters and boundaries sizes are inconsistent."); + + for (int i = 0; i < parameters.size(); i++) { if ((parameters[i] < low_[i]) || (parameters[i] > high_[i])) return false; } return true; } - - public Vector upperBound(Vector v) + + public Vector upperBound(Vector v) { return high_; } - - public Vector lowerBound(Vector v) + + public Vector lowerBound(Vector v) { return low_; } - + private Vector low_, high_; } public NonhomogeneousBoundaryConstraint(Vector low, Vector high) - : base( new Impl(low, high)) + : base(new Impl(low, high)) {} } diff --git a/src/QLNet/Math/Optimization/CostFunction.cs b/src/QLNet/Math/Optimization/CostFunction.cs index 7b050d017..c76772d70 100644 --- a/src/QLNet/Math/Optimization/CostFunction.cs +++ b/src/QLNet/Math/Optimization/CostFunction.cs @@ -1,75 +1,82 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ +using System; +using System.Linq; + namespace QLNet { //! Cost function abstract class for optimization problem public abstract class CostFunction { //! method to overload to compute the cost function value in x - public abstract double value( Vector x ); + public virtual double value(Vector x) + { + Vector v = Vector.Sqrt(x); + return Math.Sqrt(v.Sum(a => a) / Convert.ToDouble(v.size())); + } //! method to overload to compute the cost function values in x - public abstract Vector values( Vector x ); + public abstract Vector values(Vector x); //! method to overload to compute grad_f, the first derivative of // the cost function with respect to x - public virtual void gradient( Vector grad, Vector x ) + public virtual void gradient(Vector grad, Vector x) { double eps = finiteDifferenceEpsilon(), fp, fm; - Vector xx = new Vector( x ); - for ( int i = 0; i < x.Count; i++ ) + Vector xx = new Vector(x); + for (int i = 0; i < x.Count; i++) { xx[i] += eps; - fp = value( xx ); + fp = value(xx); xx[i] -= 2.0 * eps; - fm = value( xx ); - grad[i] = 0.5 * ( fp - fm ) / eps; + fm = value(xx); + grad[i] = 0.5 * (fp - fm) / eps; xx[i] = x[i]; } } //! method to overload to compute grad_f, the first derivative of // the cost function with respect to x and also the cost function - public virtual double valueAndGradient( Vector grad, Vector x ) + public virtual double valueAndGradient(Vector grad, Vector x) { - gradient( grad, x ); - return value( x ); + gradient(grad, x); + return value(x); } - + //! method to overload to compute J_f, the jacobian of // the cost function with respect to x - public virtual void jacobian(Matrix jac, Vector x) + public virtual void jacobian(Matrix jac, Vector x) { double eps = finiteDifferenceEpsilon(); Vector xx = new Vector(x) ; Vector fp = new Vector() ; Vector fm = new Vector() ; - for(int i=0; i. + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QLNet +{ + /* The algorithm and strategy names are taken from here: + + Price, K., Storn, R., 1997. Differential Evolution - + A Simple and Efficient Heuristic for Global Optimization + over Continuous Spaces. + Journal of Global Optimization, Kluwer Academic Publishers, + 1997, Vol. 11, pp. 341 - 359. + + There are seven basic strategies for creating mutant population + currently implemented. Three basic crossover types are also + available. + + */ + + /// + /// Differential Evolution configuration object + /// OptimizationMethod using Differential Evolution algorithm + /// + public class DifferentialEvolution : OptimizationMethod + { + public enum Strategy + { + Rand1Standard, + BestMemberWithJitter, + CurrentToBest2Diffs, + Rand1DiffWithPerVectorDither, + Rand1DiffWithDither, + EitherOrWithOptimalRecombination, + Rand1SelfadaptiveWithRotation + } + + public enum CrossoverType + { + Normal, + Binomial, + Exponential + } + + public class Candidate : ICloneable + { + public Vector values { get; set; } + public double cost { get; set; } + + public Candidate(int size) + { + values = new Vector(size, 0.0); + cost = 0.0; + } + + public Candidate() : this(0) {} + + public object Clone() + { + Candidate c = new Candidate(values.size()); + values.ForEach((ii, vv) => c.values[ii] = vv); + c.cost = cost; + return c; + } + } + + public class sort_by_cost : IComparer + { + public int Compare(Candidate left, Candidate right) + { + if (left.cost < right.cost) + return -1; + if (left.cost.IsEqual(right.cost)) + return 0; + return 1; + } + } + + public class Configuration + { + public Strategy strategy { get; set; } + public CrossoverType crossoverType { get; set; } + public int populationMembers { get; set; } + public double stepsizeWeight { get; set; } + public double crossoverProbability { get; set; } + public ulong seed { get; set; } + public bool applyBounds { get; set; } + public bool crossoverIsAdaptive { get; set; } + + public Configuration() + { + strategy = Strategy.BestMemberWithJitter; + crossoverType = CrossoverType.Normal; + populationMembers = 100; + stepsizeWeight = 0.2; + crossoverProbability = 0.9; + seed = 0; + applyBounds = true; + crossoverIsAdaptive = false; + } + + public Configuration withBounds(bool b = true) + { + applyBounds = b; + return this; + } + + public Configuration withCrossoverProbability(double p) + { + Utils.QL_REQUIRE(p >= 0.0 && p <= 1.0, + () => "Crossover probability (" + p + + ") must be in [0,1] range"); + crossoverProbability = p; + return this; + } + + public Configuration withPopulationMembers(int n) + { + Utils.QL_REQUIRE(n > 0, () => "Positive number of population members required"); + populationMembers = n; + return this; + } + + public Configuration withSeed(ulong s) + { + seed = s; + return this; + } + + public Configuration withAdaptiveCrossover(bool b = true) + { + crossoverIsAdaptive = b; + return this; + } + + public Configuration withStepsizeWeight(double w) + { + Utils.QL_REQUIRE(w >= 0 && w <= 2.0, + () => "Step size weight (" + w + + ") must be in [0,2] range"); + stepsizeWeight = w; + return this; + } + + public Configuration withCrossoverType(CrossoverType t) + { + crossoverType = t; + return this; + } + + public Configuration withStrategy(Strategy s) + { + strategy = s; + return this; + } + } + + public DifferentialEvolution(Configuration configuration = null) + { + configuration_ = configuration ?? new Configuration(); + rng_ = new MersenneTwisterUniformRng(configuration_.seed); + } + + public override EndCriteria.Type minimize(Problem P, EndCriteria endCriteria) + { + EndCriteria.Type ecType = EndCriteria.Type.None; + + upperBound_ = P.constraint().upperBound(P.currentValue()); + lowerBound_ = P.constraint().lowerBound(P.currentValue()); + currGenSizeWeights_ = new Vector(configuration().populationMembers, + configuration().stepsizeWeight); + currGenCrossover_ = new Vector(configuration().populationMembers, + configuration().crossoverProbability); + + List population = new InitializedList(configuration().populationMembers); + population.ForEach((ii, vv) => population[ii] = new Candidate(P.currentValue().size())); + + fillInitialPopulation(population, P); + + //original quantlib use partial_sort as only first elements is needed + double fxOld = population.Min(x => x.cost); + bestMemberEver_ = (Candidate) population.First(x => x.cost.IsEqual(fxOld)).Clone(); + int iteration = 0, stationaryPointIteration = 0; + + // main loop - calculate consecutive emerging populations + while (!endCriteria.checkMaxIterations(iteration++, ref ecType)) + { + calculateNextGeneration(population, P.costFunction()); + + double fxNew = population.Min(x => x.cost); + Candidate tmp = (Candidate) population.First(x => x.cost.IsEqual(fxNew)).Clone(); + + if (fxNew < bestMemberEver_.cost) + bestMemberEver_ = tmp; + + if (endCriteria.checkStationaryFunctionValue(fxOld, fxNew, ref stationaryPointIteration, + ref ecType)) + break; + fxOld = fxNew; + } + + P.setCurrentValue(bestMemberEver_.values); + P.setFunctionValue(bestMemberEver_.cost); + return ecType; + } + + public Configuration configuration() + { + return configuration_; + } + + protected Configuration configuration_; + protected Vector upperBound_, lowerBound_; + protected Vector currGenSizeWeights_, currGenCrossover_; + protected Candidate bestMemberEver_; + protected MersenneTwisterUniformRng rng_; + + protected void fillInitialPopulation(List population, Problem p) + { + // use initial values provided by the user + population.First().values = p.currentValue().Clone(); + population.First().cost = p.costFunction().value(population.First().values); + + if (Double.IsNaN(population.First().cost)) + population.First().cost = Double.MaxValue; + + // rest of the initial population is random + for (int j = 1; j < population.Count; ++j) + { + for (int i = 0; i < p.currentValue().size(); ++i) + { + double l = lowerBound_[i], u = upperBound_[i]; + population[j].values[i] = l + (u - l) * rng_.nextReal(); + } + + population[j].cost = p.costFunction().value(population[j].values); + + if (Double.IsNaN(population[j].cost)) + population[j].cost = Double.MaxValue; + } + } + + protected void getCrossoverMask(List crossoverMask, + List invCrossoverMask, + Vector mutationProbabilities) + { + for (int cmIter = 0; cmIter < crossoverMask.Count; cmIter++) + { + for (int memIter = 0; memIter < crossoverMask[cmIter].size(); memIter++) + { + if (rng_.nextReal() < mutationProbabilities[cmIter]) + { + invCrossoverMask[cmIter][memIter] = 0.0; + } + else + { + crossoverMask[cmIter][memIter] = 0.0; + } + } + } + } + + protected Vector getMutationProbabilities( + List population) + { + Vector mutationProbabilities = currGenCrossover_.Clone(); + + switch (configuration().crossoverType) + { + case CrossoverType.Normal: + break; + case CrossoverType.Binomial: + mutationProbabilities = currGenCrossover_ + * (1.0 - 1.0 / population.First().values.size()) + + 1.0 / population.First().values.size(); + break; + case CrossoverType.Exponential: + for (int coIter = 0; coIter < currGenCrossover_.size(); coIter++) + { + mutationProbabilities[coIter] = + (1.0 - Math.Pow(currGenCrossover_[coIter], + population.First().values.size())) + / (population.First().values.size() + * (1.0 - currGenCrossover_[coIter])); + } + + break; + default: + Utils.QL_FAIL("Unknown crossover type (" + + Convert.ToInt32(configuration().crossoverType) + ")"); + break; + } + + return mutationProbabilities; + } + + protected void adaptSizeWeights() + { + // [=Fl & =Fu] respectively see Brest, J. et al., 2006, + // "Self-Adapting Control Parameters in Differential + // Evolution" + double sizeWeightLowerBound = 0.1, sizeWeightUpperBound = 0.9; + // [=tau1] A Comparative Study on Numerical Benchmark + // Problems." page 649 for reference + double sizeWeightChangeProb = 0.1; + for (int coIter = 0; coIter < currGenSizeWeights_.size(); coIter++) + { + if (rng_.nextReal() < sizeWeightChangeProb) + currGenSizeWeights_[coIter] = sizeWeightLowerBound + rng_.nextReal() * sizeWeightUpperBound; + } + } + + protected void adaptCrossover() + { + double crossoverChangeProb = 0.1; // [=tau2] + for (int coIter = 0; coIter < currGenCrossover_.size(); coIter++) + { + if (rng_.nextReal() < crossoverChangeProb) + currGenCrossover_[coIter] = rng_.nextReal(); + } + } + + protected void calculateNextGeneration(List population, + CostFunction costFunction) + { + List mirrorPopulation = null; + List oldPopulation = (List) population.Clone(); + + switch (configuration().strategy) + { + case Strategy.Rand1Standard: + { + population.Shuffle(); + List shuffledPop1 = (List) population.Clone(); + population.Shuffle(); + List shuffledPop2 = (List) population.Clone(); + population.Shuffle(); + mirrorPopulation = (List) shuffledPop1.Clone(); + + for (int popIter = 0; popIter < population.Count; popIter++) + { + population[popIter].values = population[popIter].values + + configuration().stepsizeWeight + * (shuffledPop1[popIter].values - shuffledPop2[popIter].values); + } + } + break; + + case Strategy.BestMemberWithJitter: + { + population.Shuffle(); + List shuffledPop1 = (List) population.Clone(); + population.Shuffle(); + Vector jitter = new Vector(population[0].values.size(), 0.0); + + for (int popIter = 0; popIter < population.Count; popIter++) + { + for (int jitterIter = 0; jitterIter < jitter.Count; jitterIter++) + { + jitter[jitterIter] = rng_.nextReal(); + } + + population[popIter].values = bestMemberEver_.values + + Vector.DirectMultiply( + shuffledPop1[popIter].values - population[popIter].values + , 0.0001 * jitter + configuration().stepsizeWeight); + } + + mirrorPopulation = new InitializedList(population.Count); + mirrorPopulation.ForEach((ii, vv) => mirrorPopulation[ii] = (Candidate) bestMemberEver_.Clone()); + } + break; + + case Strategy.CurrentToBest2Diffs: + { + population.Shuffle(); + List shuffledPop1 = (List) population.Clone(); + population.Shuffle(); + + for (int popIter = 0; popIter < population.Count; popIter++) + { + population[popIter].values = oldPopulation[popIter].values + + configuration().stepsizeWeight + * (bestMemberEver_.values - oldPopulation[popIter].values) + + configuration().stepsizeWeight + * (population[popIter].values - shuffledPop1[popIter].values); + } + + mirrorPopulation = (List) shuffledPop1.Clone(); + } + break; + + case Strategy.Rand1DiffWithPerVectorDither: + { + population.Shuffle(); + List shuffledPop1 = (List) population.Clone(); + population.Shuffle(); + List shuffledPop2 = (List) population.Clone(); + population.Shuffle(); + mirrorPopulation = (List) shuffledPop1.Clone(); + Vector FWeight = new Vector(population.First().values.size(), 0.0); + for (int fwIter = 0; fwIter < FWeight.Count; fwIter++) + FWeight[fwIter] = (1.0 - configuration().stepsizeWeight) + * rng_.nextReal() + configuration().stepsizeWeight; + for (int popIter = 0; popIter < population.Count; popIter++) + { + population[popIter].values = population[popIter].values + + Vector.DirectMultiply(FWeight, + shuffledPop1[popIter].values - shuffledPop2[popIter].values); + } + } + break; + + case Strategy.Rand1DiffWithDither: + { + population.Shuffle(); + List shuffledPop1 = (List) population.Clone(); + population.Shuffle(); + List shuffledPop2 = (List) population.Clone(); + population.Shuffle(); + mirrorPopulation = (List) shuffledPop1.Clone(); + double FWeight = (1.0 - configuration().stepsizeWeight) * rng_.nextReal() + + configuration().stepsizeWeight; + for (int popIter = 0; popIter < population.Count; popIter++) + { + population[popIter].values = population[popIter].values + + FWeight * (shuffledPop1[popIter].values - + shuffledPop2[popIter].values); + } + } + break; + + case Strategy.EitherOrWithOptimalRecombination: + { + population.Shuffle(); + List shuffledPop1 = (List) population.Clone(); + population.Shuffle(); + List shuffledPop2 = (List) population.Clone(); + population.Shuffle(); + mirrorPopulation = (List) shuffledPop1.Clone(); + double probFWeight = 0.5; + if (rng_.nextReal() < probFWeight) + { + for (int popIter = 0; popIter < population.Count; popIter++) + { + population[popIter].values = oldPopulation[popIter].values + + configuration().stepsizeWeight + * (shuffledPop1[popIter].values - shuffledPop2[popIter].values); + } + } + else + { + double K = 0.5 * (configuration().stepsizeWeight + 1); // invariant with respect to probFWeight used + for (int popIter = 0; popIter < population.Count; popIter++) + { + population[popIter].values = oldPopulation[popIter].values + + K + * (shuffledPop1[popIter].values - shuffledPop2[popIter].values + - 2.0 * population[popIter].values); + } + } + } + break; + + case Strategy.Rand1SelfadaptiveWithRotation: + { + population.Shuffle(); + List shuffledPop1 = (List) population.Clone(); + population.Shuffle(); + List shuffledPop2 = (List) population.Clone(); + population.Shuffle(); + mirrorPopulation = (List) shuffledPop1.Clone(); + + adaptSizeWeights(); + + for (int popIter = 0; popIter < population.Count; popIter++) + { + if (rng_.nextReal() < 0.1) + { + population[popIter].values = rotateArray(bestMemberEver_.values); + } + else + { + population[popIter].values = bestMemberEver_.values + + currGenSizeWeights_[popIter] + * (shuffledPop1[popIter].values - shuffledPop2[popIter].values); + } + } + } + break; + + default: + Utils.QL_FAIL("Unknown strategy (" + + Convert.ToInt32(configuration().strategy) + ")"); + break; + } + + // in order to avoid unnecessary copying we use the same population object for mutants + crossover(oldPopulation, population, population, mirrorPopulation, + costFunction); + } + + protected Vector rotateArray(Vector inputVector) + { + Vector shuffle = inputVector.Clone(); + shuffle.Shuffle(); + return shuffle; + } + + protected void crossover(List oldPopulation, + List population, + List mutantPopulation, + List mirrorPopulation, + CostFunction costFunction) + { + if (configuration().crossoverIsAdaptive) + { + adaptCrossover(); + } + + Vector mutationProbabilities = getMutationProbabilities(population); + + List crossoverMask = new InitializedList(population.Count); + crossoverMask.ForEach((ii, vv) => crossoverMask[ii] = new Vector(population.First().values.size(), 1.0)); + + List invCrossoverMask = new InitializedList(population.Count); + invCrossoverMask.ForEach((ii, vv) => invCrossoverMask[ii] = new Vector(population.First().values.size(), 1.0)); + + getCrossoverMask(crossoverMask, invCrossoverMask, mutationProbabilities); + + // crossover of the old and mutant population + for (int popIter = 0; popIter < population.Count; popIter++) + { + population[popIter].values = Vector.DirectMultiply(oldPopulation[popIter].values, invCrossoverMask[popIter]) + + Vector.DirectMultiply(mutantPopulation[popIter].values, + crossoverMask[popIter]); + // immediately apply bounds if specified + if (configuration().applyBounds) + { + for (int memIter = 0; memIter < population[popIter].values.size(); memIter++) + { + if (population[popIter].values[memIter] > upperBound_[memIter]) + population[popIter].values[memIter] = upperBound_[memIter] + + rng_.nextReal() + * (mirrorPopulation[popIter].values[memIter] + - upperBound_[memIter]); + if (population[popIter].values[memIter] < lowerBound_[memIter]) + population[popIter].values[memIter] = lowerBound_[memIter] + + rng_.nextReal() + * (mirrorPopulation[popIter].values[memIter] + - lowerBound_[memIter]); + } + } + + // evaluate objective function as soon as possible to avoid unnecessary loops + try + { + population[popIter].cost = costFunction.value(population[popIter].values); + + if (Double.IsNaN(population[popIter].cost)) + population[popIter].cost = Double.MaxValue; + } + catch + { + population[popIter].cost = Double.MaxValue; + } + } + } + } +} diff --git a/src/QLNet/Math/Optimization/EndCriteria.cs b/src/QLNet/Math/Optimization/EndCriteria.cs index 0c93260ca..582b16a28 100644 --- a/src/QLNet/Math/Optimization/EndCriteria.cs +++ b/src/QLNet/Math/Optimization/EndCriteria.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - * + * This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,141 +22,141 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! Criteria to end optimization process: + //! Criteria to end optimization process: // ! - maximum number of iterations AND minimum number of iterations around stationary point // - x (independent variable) stationary point // - y=f(x) (dependent variable) stationary point // - stationary gradient -// - public class EndCriteria - { - public enum Type - { - None, - MaxIterations, - StationaryPoint, - StationaryFunctionValue, - StationaryFunctionAccuracy, - ZeroGradientNorm, - Unknown - } - - //! Initialization constructor - public EndCriteria(int maxIterations, int? maxStationaryStateIterations, double rootEpsilon, double functionEpsilon, double? gradientNormEpsilon) - { - maxIterations_ = maxIterations; - maxStationaryStateIterations_ = maxStationaryStateIterations; - rootEpsilon_ = rootEpsilon; - functionEpsilon_ = functionEpsilon; - gradientNormEpsilon_ = gradientNormEpsilon; - - if (maxStationaryStateIterations_ == null) - maxStationaryStateIterations_ = Math.Min(maxIterations/2, 100); - - Utils.QL_REQUIRE(maxStationaryStateIterations_ > 1,()=> - "maxStationaryStateIterations_ (" + maxStationaryStateIterations_ + ") must be greater than one"); - - Utils.QL_REQUIRE(maxStationaryStateIterations_ < maxIterations_,()=> - "maxStationaryStateIterations_ (" + maxStationaryStateIterations_ + ") must be less than maxIterations_ (" + maxIterations_ + ")"); - - if (gradientNormEpsilon_ == null) - gradientNormEpsilon_ = functionEpsilon_; - } - - // Inspectors - - // Inspectors - public int maxIterations() - { - return maxIterations_; - } - public int maxStationaryStateIterations() - { - return maxStationaryStateIterations_.GetValueOrDefault(); - } - public double rootEpsilon() - { - return rootEpsilon_; - } - public double functionEpsilon() - { - return functionEpsilon_; - } - public double gradientNormEpsilon() - { - return gradientNormEpsilon_.GetValueOrDefault(); - } +// + public class EndCriteria + { + public enum Type + { + None, + MaxIterations, + StationaryPoint, + StationaryFunctionValue, + StationaryFunctionAccuracy, + ZeroGradientNorm, + Unknown + } + + //! Initialization constructor + public EndCriteria(int maxIterations, int? maxStationaryStateIterations, double rootEpsilon, double functionEpsilon, double? gradientNormEpsilon) + { + maxIterations_ = maxIterations; + maxStationaryStateIterations_ = maxStationaryStateIterations; + rootEpsilon_ = rootEpsilon; + functionEpsilon_ = functionEpsilon; + gradientNormEpsilon_ = gradientNormEpsilon; + + if (maxStationaryStateIterations_ == null) + maxStationaryStateIterations_ = Math.Min(maxIterations / 2, 100); + + Utils.QL_REQUIRE(maxStationaryStateIterations_ > 1, () => + "maxStationaryStateIterations_ (" + maxStationaryStateIterations_ + ") must be greater than one"); + + Utils.QL_REQUIRE(maxStationaryStateIterations_ < maxIterations_, () => + "maxStationaryStateIterations_ (" + maxStationaryStateIterations_ + ") must be less than maxIterations_ (" + maxIterations_ + ")"); + + if (gradientNormEpsilon_ == null) + gradientNormEpsilon_ = functionEpsilon_; + } + + // Inspectors + + // Inspectors + public int maxIterations() + { + return maxIterations_; + } + public int maxStationaryStateIterations() + { + return maxStationaryStateIterations_.GetValueOrDefault(); + } + public double rootEpsilon() + { + return rootEpsilon_; + } + public double functionEpsilon() + { + return functionEpsilon_; + } + public double gradientNormEpsilon() + { + return gradientNormEpsilon_.GetValueOrDefault(); + } // ! Test if the number of iterations is not too big -// and if a minimum point is not reached - public bool value(int iteration, ref int statStateIterations, bool positiveOptimization, double fold, double UnnamedParameter1, double fnew, double normgnew, ref EndCriteria.Type ecType) - { - return checkMaxIterations(iteration, ref ecType) || checkStationaryFunctionValue(fold, fnew, ref statStateIterations, ref ecType) || checkStationaryFunctionAccuracy(fnew, positiveOptimization, ref ecType) || checkZeroGradientNorm(normgnew, ref ecType); - } - - //! Test if the number of iteration is below MaxIterations - public bool checkMaxIterations(int iteration, ref EndCriteria.Type ecType) - { - if (iteration < maxIterations_) - return false; - ecType = Type.MaxIterations; - return true; - } - //! Test if the root variation is below rootEpsilon - public bool checkStationaryPoint(double xOld, double xNew, ref int statStateIterations, ref EndCriteria.Type ecType) - { - if (Math.Abs(xNew-xOld) >= rootEpsilon_) - { - statStateIterations = 0; - return false; - } - ++statStateIterations; - if (statStateIterations <= maxStationaryStateIterations_) - return false; - ecType = Type.StationaryPoint; - return true; - } - //! Test if the function variation is below functionEpsilon - public bool checkStationaryFunctionValue(double fxOld, double fxNew, ref int statStateIterations, ref EndCriteria.Type ecType) - { - if (Math.Abs(fxNew-fxOld) >= functionEpsilon_) - { - statStateIterations = 0; - return false; - } - ++statStateIterations; - if (statStateIterations <= maxStationaryStateIterations_) - return false; - ecType = Type.StationaryFunctionValue; - return true; - } - //! Test if the function value is below functionEpsilon - public bool checkStationaryFunctionAccuracy(double f, bool positiveOptimization, ref EndCriteria.Type ecType) - { - if (!positiveOptimization) - return false; - if (f >= functionEpsilon_) - return false; - ecType = Type.StationaryFunctionAccuracy; - return true; - } - - public bool checkZeroGradientNorm(double gradientNorm, ref EndCriteria.Type ecType) - { - if (gradientNorm >= gradientNormEpsilon_) - return false; - ecType = Type.ZeroGradientNorm; - return true; - } - - //! Maximum number of iterations - protected int maxIterations_; - //! Maximun number of iterations in stationary state - protected int? maxStationaryStateIterations_; - //! root, function and gradient epsilons - protected double rootEpsilon_; - protected double functionEpsilon_; - protected double? gradientNormEpsilon_; - - } +// and if a minimum point is not reached + public bool value(int iteration, ref int statStateIterations, bool positiveOptimization, double fold, double UnnamedParameter1, double fnew, double normgnew, ref EndCriteria.Type ecType) + { + return checkMaxIterations(iteration, ref ecType) || checkStationaryFunctionValue(fold, fnew, ref statStateIterations, ref ecType) || checkStationaryFunctionAccuracy(fnew, positiveOptimization, ref ecType) || checkZeroGradientNorm(normgnew, ref ecType); + } + + //! Test if the number of iteration is below MaxIterations + public bool checkMaxIterations(int iteration, ref EndCriteria.Type ecType) + { + if (iteration < maxIterations_) + return false; + ecType = Type.MaxIterations; + return true; + } + //! Test if the root variation is below rootEpsilon + public bool checkStationaryPoint(double xOld, double xNew, ref int statStateIterations, ref EndCriteria.Type ecType) + { + if (Math.Abs(xNew - xOld) >= rootEpsilon_) + { + statStateIterations = 0; + return false; + } + ++statStateIterations; + if (statStateIterations <= maxStationaryStateIterations_) + return false; + ecType = Type.StationaryPoint; + return true; + } + //! Test if the function variation is below functionEpsilon + public bool checkStationaryFunctionValue(double fxOld, double fxNew, ref int statStateIterations, ref EndCriteria.Type ecType) + { + if (Math.Abs(fxNew - fxOld) >= functionEpsilon_) + { + statStateIterations = 0; + return false; + } + ++statStateIterations; + if (statStateIterations <= maxStationaryStateIterations_) + return false; + ecType = Type.StationaryFunctionValue; + return true; + } + //! Test if the function value is below functionEpsilon + public bool checkStationaryFunctionAccuracy(double f, bool positiveOptimization, ref EndCriteria.Type ecType) + { + if (!positiveOptimization) + return false; + if (f >= functionEpsilon_) + return false; + ecType = Type.StationaryFunctionAccuracy; + return true; + } + + public bool checkZeroGradientNorm(double gradientNorm, ref EndCriteria.Type ecType) + { + if (gradientNorm >= gradientNormEpsilon_) + return false; + ecType = Type.ZeroGradientNorm; + return true; + } + + //! Maximum number of iterations + protected int maxIterations_; + //! Maximun number of iterations in stationary state + protected int? maxStationaryStateIterations_; + //! root, function and gradient epsilons + protected double rootEpsilon_; + protected double functionEpsilon_; + protected double? gradientNormEpsilon_; + + } } diff --git a/src/QLNet/Math/Optimization/GoldsteinLineSearch.cs b/src/QLNet/Math/Optimization/GoldsteinLineSearch.cs index 2785bd5c7..8347d7194 100644 --- a/src/QLNet/Math/Optimization/GoldsteinLineSearch.cs +++ b/src/QLNet/Math/Optimization/GoldsteinLineSearch.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,7 +20,7 @@ namespace QLNet public class GoldsteinLineSearch : LineSearch { //! Default constructor - public GoldsteinLineSearch(double eps = 1e-8,double alpha = 0.05,double beta = 0.65,double extrapolation = 1.5) + public GoldsteinLineSearch(double eps = 1e-8, double alpha = 0.05, double beta = 0.65, double extrapolation = 1.5) : base(eps) { alpha_ = alpha; @@ -47,51 +47,51 @@ public override double value(Problem P, // Optimization problem double tr = 0.0; qt_ = q0; - qpt_ = ( gradient_.empty() ) ? qp0 : -Vector.DotProduct( gradient_, searchDirection_ ); + qpt_ = (gradient_.empty()) ? qp0 : -Vector.DotProduct(gradient_, searchDirection_); // Initialize gradient - gradient_ = new Vector( P.currentValue().size() ); + gradient_ = new Vector(P.currentValue().size()); // Compute new point xtd_ = P.currentValue(); - t = update( ref xtd_, searchDirection_, t, constraint ); + t = update(ref xtd_, searchDirection_, t, constraint); // Compute function value at the new point - qt_ = P.value( xtd_ ); + qt_ = P.value(xtd_); - while ( ( qt_ - q0 ) < -beta_ * t * qpt_ || ( qt_ - q0 ) > -alpha_ * t * qpt_ ) + while ((qt_ - q0) < -beta_ * t * qpt_ || (qt_ - q0) > -alpha_ * t * qpt_) { - if ( ( qt_ - q0 ) > -alpha_ * t * qpt_ ) + if ((qt_ - q0) > -alpha_ * t * qpt_) tr = t; else tl = t; ++loopNumber; // calculate the new step - if ( Utils.close_enough( tr, 0.0 ) ) + if (Utils.close_enough(tr, 0.0)) t *= extrapolation_; else - t = ( tl + tr ) / 2.0; + t = (tl + tr) / 2.0; // New point value xtd_ = P.currentValue(); - t = update( ref xtd_, searchDirection_, t, constraint ); + t = update(ref xtd_, searchDirection_, t, constraint); // Compute function value at the new point - qt_ = P.value( xtd_ ); - P.gradient( gradient_, xtd_ ); + qt_ = P.value(xtd_); + P.gradient(gradient_, xtd_); // and it squared norm - maxIter = endCriteria.checkMaxIterations( loopNumber, ref ecType ); + maxIter = endCriteria.checkMaxIterations(loopNumber, ref ecType); - if ( maxIter ) + if (maxIter) break; } - if ( maxIter ) + if (maxIter) succeed_ = false; // Compute new gradient - P.gradient( gradient_, xtd_ ); + P.gradient(gradient_, xtd_); // and it squared norm - qpt_ = Vector.DotProduct( gradient_, gradient_ ); + qpt_ = Vector.DotProduct(gradient_, gradient_); // Return new step value return t; diff --git a/src/QLNet/Math/Optimization/LeastSquareProblem.cs b/src/QLNet/Math/Optimization/LeastSquareProblem.cs index 43a64cf14..76abb1732 100644 --- a/src/QLNet/Math/Optimization/LeastSquareProblem.cs +++ b/src/QLNet/Math/Optimization/LeastSquareProblem.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - * + * This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,205 +21,205 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! Base class for least square problem - public abstract class LeastSquareProblem - { - //! size of the problem ie size of target vector - public abstract int size(); - //! compute the target vector and the values of the function to fit - public abstract void targetAndValue(Vector x, ref Vector target, ref Vector fct2fit); - // ! compute the target vector, the values of the function to fit - // and the matrix of derivatives - // - public abstract void targetValueAndGradient(Vector x, ref Matrix grad_fct2fit, ref Vector target, ref Vector fct2fit); - } - - //! Cost function for least-square problems - // ! Implements a cost function using the interface provided by - // the LeastSquareProblem class. - // - public class LeastSquareFunction : CostFunction - { - //! least square problem - protected LeastSquareProblem lsp_ = null; - - //! Default constructor - public LeastSquareFunction(LeastSquareProblem lsp) - { - lsp_ = lsp; - } - - //! compute value of the least square function - public override double value(Vector x) - { - // size of target and function to fit vectors - Vector target = new Vector(lsp_.size()); - Vector fct2fit = new Vector(lsp_.size()); - // compute its values - lsp_.targetAndValue(x, ref target, ref fct2fit); - // do the difference - Vector diff = target - fct2fit; - // and compute the scalar product (square of the norm) - return Vector.DotProduct(diff, diff); - } - public override Vector values(Vector x) - { - // size of target and function to fit vectors - Vector target = new Vector(lsp_.size()); - Vector fct2fit = new Vector(lsp_.size()); - // compute its values - lsp_.targetAndValue(x, ref target, ref fct2fit); - // do the difference - Vector diff = target - fct2fit; - return Vector.DirectMultiply(diff, diff); - } - //! compute vector of derivatives of the least square function - public void gradient(ref Vector grad_f, Vector x) - { - // size of target and function to fit vectors - Vector target = new Vector(lsp_.size()); - Vector fct2fit = new Vector(lsp_.size()); - // size of gradient matrix - Matrix grad_fct2fit = new Matrix(lsp_.size(), x.size()); - // compute its values - lsp_.targetValueAndGradient(x, ref grad_fct2fit, ref target, ref fct2fit); - // do the difference - Vector diff = target - fct2fit; - // compute derivative - grad_f = -2.0 * (Matrix.transpose(grad_fct2fit) * diff); - } - //! compute value and gradient of the least square function - public double valueAndGradient(ref Vector grad_f, Vector x) - { - // size of target and function to fit vectors - Vector target = new Vector(lsp_.size()); - Vector fct2fit = new Vector(lsp_.size()); - // size of gradient matrix - Matrix grad_fct2fit = new Matrix(lsp_.size(), x.size()); - // compute its values - lsp_.targetValueAndGradient(x, ref grad_fct2fit, ref target, ref fct2fit); - // do the difference - Vector diff = target - fct2fit; - // compute derivative - grad_f = -2.0 * (Matrix.transpose(grad_fct2fit) * diff); - // and compute the scalar product (square of the norm) - return Vector.DotProduct(diff, diff); - } - } - - //! Non-linear least-square method. - // ! Using a given optimization algorithm (default is conjugate - // gradient), - // - // \f[ min \{ r(x) : x in R^n \} \f] - // - // where \f$ r(x) = |f(x)|^2 \f$ is the Euclidean norm of \f$ - // f(x) \f$ for some vector-valued function \f$ f \f$ from - // \f$ R^n \f$ to \f$ R^m \f$, - // \f[ f = (f_1, ..., f_m) \f] - // with \f$ f_i(x) = b_i - \phi(x,t_i) \f$ where \f$ b \f$ is the - // vector of target data and \f$ phi \f$ is a scalar function. - // - // Assuming the differentiability of \f$ f \f$, the gradient of - // \f$ r \f$ is defined by - // \f[ grad r(x) = f'(x)^t.f(x) \f] - // - public class NonLinearLeastSquare - { - //! solution vector - private Vector results_; - private Vector initialValue_; - //! least square residual norm - private double resnorm_; - //! Exit flag of the optimization process - private int exitFlag_; - //! required accuracy of the solver - private double accuracy_; - private double bestAccuracy_; - //! maximum and real number of iterations - private int maxIterations_; - //! Optimization method - private OptimizationMethod om_; - //constraint - private Constraint c_; - - //! Default constructor - public NonLinearLeastSquare(Constraint c, double accuracy) - : this(c, accuracy, 100) - { - } - public NonLinearLeastSquare(Constraint c) - : this(c, 1e-4, 100) - { - } - public NonLinearLeastSquare(Constraint c, double accuracy, int maxiter) - { - exitFlag_ = -1; - accuracy_ = accuracy; - maxIterations_ = maxiter; - om_ = new ConjugateGradient(); - c_ = c; - } - //! Default constructor - public NonLinearLeastSquare(Constraint c, double accuracy, int maxiter, OptimizationMethod om) - { - exitFlag_ = -1; - accuracy_ = accuracy; - maxIterations_ = maxiter; - om_ = om; - c_ = c; - } - - //! Solve least square problem using numerix solver - public Vector perform(ref LeastSquareProblem lsProblem) - { - double eps = accuracy_; - - // wrap the least square problem in an optimization function - LeastSquareFunction lsf = new LeastSquareFunction(lsProblem); - - // define optimization problem - Problem P = new Problem(lsf, c_, initialValue_); - - // minimize - EndCriteria ec = new EndCriteria(maxIterations_, Math.Min(maxIterations_ / 2, 100), eps, eps, eps); - exitFlag_ = (int)om_.minimize(P, ec); - - results_ = P.currentValue(); - resnorm_ = P.functionValue(); - bestAccuracy_ = P.functionValue(); - - return results_; - } - - public void setInitialValue(Vector initialValue) - { - initialValue_ = initialValue; - } - - //! return the results - public Vector results() - { - return results_; - } - - //! return the least square residual norm - public double residualNorm() - { - return resnorm_; - } - - //! return last function value - public double lastValue() - { - return bestAccuracy_; - } - - //! return exit flag - public int exitFlag() - { - return exitFlag_; - } - - } + //! Base class for least square problem + public abstract class LeastSquareProblem + { + //! size of the problem ie size of target vector + public abstract int size(); + //! compute the target vector and the values of the function to fit + public abstract void targetAndValue(Vector x, ref Vector target, ref Vector fct2fit); + // ! compute the target vector, the values of the function to fit + // and the matrix of derivatives + // + public abstract void targetValueAndGradient(Vector x, ref Matrix grad_fct2fit, ref Vector target, ref Vector fct2fit); + } + + //! Cost function for least-square problems + // ! Implements a cost function using the interface provided by + // the LeastSquareProblem class. + // + public class LeastSquareFunction : CostFunction + { + //! least square problem + protected LeastSquareProblem lsp_ = null; + + //! Default constructor + public LeastSquareFunction(LeastSquareProblem lsp) + { + lsp_ = lsp; + } + + //! compute value of the least square function + public override double value(Vector x) + { + // size of target and function to fit vectors + Vector target = new Vector(lsp_.size()); + Vector fct2fit = new Vector(lsp_.size()); + // compute its values + lsp_.targetAndValue(x, ref target, ref fct2fit); + // do the difference + Vector diff = target - fct2fit; + // and compute the scalar product (square of the norm) + return Vector.DotProduct(diff, diff); + } + public override Vector values(Vector x) + { + // size of target and function to fit vectors + Vector target = new Vector(lsp_.size()); + Vector fct2fit = new Vector(lsp_.size()); + // compute its values + lsp_.targetAndValue(x, ref target, ref fct2fit); + // do the difference + Vector diff = target - fct2fit; + return Vector.DirectMultiply(diff, diff); + } + //! compute vector of derivatives of the least square function + public void gradient(ref Vector grad_f, Vector x) + { + // size of target and function to fit vectors + Vector target = new Vector(lsp_.size()); + Vector fct2fit = new Vector(lsp_.size()); + // size of gradient matrix + Matrix grad_fct2fit = new Matrix(lsp_.size(), x.size()); + // compute its values + lsp_.targetValueAndGradient(x, ref grad_fct2fit, ref target, ref fct2fit); + // do the difference + Vector diff = target - fct2fit; + // compute derivative + grad_f = -2.0 * (Matrix.transpose(grad_fct2fit) * diff); + } + //! compute value and gradient of the least square function + public double valueAndGradient(ref Vector grad_f, Vector x) + { + // size of target and function to fit vectors + Vector target = new Vector(lsp_.size()); + Vector fct2fit = new Vector(lsp_.size()); + // size of gradient matrix + Matrix grad_fct2fit = new Matrix(lsp_.size(), x.size()); + // compute its values + lsp_.targetValueAndGradient(x, ref grad_fct2fit, ref target, ref fct2fit); + // do the difference + Vector diff = target - fct2fit; + // compute derivative + grad_f = -2.0 * (Matrix.transpose(grad_fct2fit) * diff); + // and compute the scalar product (square of the norm) + return Vector.DotProduct(diff, diff); + } + } + + //! Non-linear least-square method. + // ! Using a given optimization algorithm (default is conjugate + // gradient), + // + // \f[ min \{ r(x) : x in R^n \} \f] + // + // where \f$ r(x) = |f(x)|^2 \f$ is the Euclidean norm of \f$ + // f(x) \f$ for some vector-valued function \f$ f \f$ from + // \f$ R^n \f$ to \f$ R^m \f$, + // \f[ f = (f_1, ..., f_m) \f] + // with \f$ f_i(x) = b_i - \phi(x,t_i) \f$ where \f$ b \f$ is the + // vector of target data and \f$ phi \f$ is a scalar function. + // + // Assuming the differentiability of \f$ f \f$, the gradient of + // \f$ r \f$ is defined by + // \f[ grad r(x) = f'(x)^t.f(x) \f] + // + public class NonLinearLeastSquare + { + //! solution vector + private Vector results_; + private Vector initialValue_; + //! least square residual norm + private double resnorm_; + //! Exit flag of the optimization process + private int exitFlag_; + //! required accuracy of the solver + private double accuracy_; + private double bestAccuracy_; + //! maximum and real number of iterations + private int maxIterations_; + //! Optimization method + private OptimizationMethod om_; + //constraint + private Constraint c_; + + //! Default constructor + public NonLinearLeastSquare(Constraint c, double accuracy) + : this(c, accuracy, 100) + { + } + public NonLinearLeastSquare(Constraint c) + : this(c, 1e-4, 100) + { + } + public NonLinearLeastSquare(Constraint c, double accuracy, int maxiter) + { + exitFlag_ = -1; + accuracy_ = accuracy; + maxIterations_ = maxiter; + om_ = new ConjugateGradient(); + c_ = c; + } + //! Default constructor + public NonLinearLeastSquare(Constraint c, double accuracy, int maxiter, OptimizationMethod om) + { + exitFlag_ = -1; + accuracy_ = accuracy; + maxIterations_ = maxiter; + om_ = om; + c_ = c; + } + + //! Solve least square problem using numerix solver + public Vector perform(ref LeastSquareProblem lsProblem) + { + double eps = accuracy_; + + // wrap the least square problem in an optimization function + LeastSquareFunction lsf = new LeastSquareFunction(lsProblem); + + // define optimization problem + Problem P = new Problem(lsf, c_, initialValue_); + + // minimize + EndCriteria ec = new EndCriteria(maxIterations_, Math.Min(maxIterations_ / 2, 100), eps, eps, eps); + exitFlag_ = (int)om_.minimize(P, ec); + + results_ = P.currentValue(); + resnorm_ = P.functionValue(); + bestAccuracy_ = P.functionValue(); + + return results_; + } + + public void setInitialValue(Vector initialValue) + { + initialValue_ = initialValue; + } + + //! return the results + public Vector results() + { + return results_; + } + + //! return the least square residual norm + public double residualNorm() + { + return resnorm_; + } + + //! return last function value + public double lastValue() + { + return bestAccuracy_; + } + + //! return exit flag + public int exitFlag() + { + return exitFlag_; + } + + } } diff --git a/src/QLNet/Math/Optimization/levenbergmarquardt.cs b/src/QLNet/Math/Optimization/LevenbergMarquardt.cs similarity index 53% rename from src/QLNet/Math/Optimization/levenbergmarquardt.cs rename to src/QLNet/Math/Optimization/LevenbergMarquardt.cs index 9b44a946a..ea3f5bdaa 100644 --- a/src/QLNet/Math/Optimization/levenbergmarquardt.cs +++ b/src/QLNet/Math/Optimization/LevenbergMarquardt.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -49,8 +49,8 @@ public class LevenbergMarquardt : OptimizationMethod private double epsfcn_, xtol_, gtol_; - public LevenbergMarquardt() : this( 1.0e-8, 1.0e-8, 1.0e-8 ) { } - public LevenbergMarquardt( double epsfcn, double xtol, double gtol, bool useCostFunctionsJacobian = false ) + public LevenbergMarquardt() : this(1.0e-8, 1.0e-8, 1.0e-8) { } + public LevenbergMarquardt(double epsfcn, double xtol, double gtol, bool useCostFunctionsJacobian = false) { info_ = 0; epsfcn_ = epsfcn; @@ -59,23 +59,23 @@ public LevenbergMarquardt( double epsfcn, double xtol, double gtol, bool useCost useCostFunctionsJacobian_ = useCostFunctionsJacobian; } - public override EndCriteria.Type minimize( Problem P, EndCriteria endCriteria ) + public override EndCriteria.Type minimize(Problem P, EndCriteria endCriteria) { EndCriteria.Type ecType = EndCriteria.Type.None; P.reset(); Vector x_ = P.currentValue(); currentProblem_ = P; - initCostValues_ = P.costFunction().values( x_ ); + initCostValues_ = P.costFunction().values(x_); int m = initCostValues_.size(); int n = x_.size(); - if ( useCostFunctionsJacobian_ ) + if (useCostFunctionsJacobian_) { - initJacobian_ = new Matrix( m, n ); - P.costFunction().jacobian( initJacobian_, x_ ); + initJacobian_ = new Matrix(m, n); + P.costFunction().jacobian(initJacobian_, x_); } - Vector xx = new Vector( x_ ); - Vector fvec = new Vector( m ), diag = new Vector( n ); + Vector xx = new Vector(x_); + Vector fvec = new Vector(m), diag = new Vector(n); int mode = 1; double factor = 1; @@ -83,83 +83,92 @@ public override EndCriteria.Type minimize( Problem P, EndCriteria endCriteria ) int info = 0; int nfev = 0; - Matrix fjac = new Matrix( m, n ); + Matrix fjac = new Matrix(m, n); int ldfjac = m; - List ipvt = new InitializedList( n ); - Vector qtf = new Vector( n ), wa1 = new Vector( n ), wa2 = new Vector( n ), wa3 = new Vector( n ), wa4 = new Vector( m ); + List ipvt = new InitializedList(n); + Vector qtf = new Vector(n), wa1 = new Vector(n), wa2 = new Vector(n), wa3 = new Vector(n), wa4 = new Vector(m); // call lmdif to minimize the sum of the squares of m functions // in n variables by the Levenberg-Marquardt algorithm. Func j = null; - if ( useCostFunctionsJacobian_ ) + if (useCostFunctionsJacobian_) j = jacFcn; - MINPACK.lmdif( m, n, xx, ref fvec, - endCriteria.functionEpsilon(), - xtol_, - gtol_, - endCriteria.maxIterations(), - epsfcn_, - diag, mode, factor, - nprint, ref info, ref nfev, ref fjac, - ldfjac, ref ipvt, ref qtf, - wa1, wa2, wa3, wa4, - fcn, j); + // requirements; check here to get more detailed error messages. + Utils.QL_REQUIRE(n > 0, () => "no variables given"); + Utils.QL_REQUIRE(m >= n, () => $"less functions ({m}) than available variables ({n})"); + Utils.QL_REQUIRE(endCriteria.functionEpsilon() >= 0.0, () => "negative f tolerance"); + Utils.QL_REQUIRE(xtol_ >= 0.0, () => "negative x tolerance"); + Utils.QL_REQUIRE(gtol_ >= 0.0, () => "negative g tolerance"); + Utils.QL_REQUIRE(endCriteria.maxIterations() > 0, () => "null number of evaluations"); + + MINPACK.lmdif(m, n, xx, ref fvec, + endCriteria.functionEpsilon(), + xtol_, + gtol_, + endCriteria.maxIterations(), + epsfcn_, + diag, mode, factor, + nprint, ref info, ref nfev, ref fjac, + ldfjac, ref ipvt, ref qtf, + wa1, wa2, wa3, wa4, + fcn, j); info_ = info; // check requirements & endCriteria evaluation - Utils.QL_REQUIRE( info != 0 ,()=> "MINPACK: improper input parameters" ); - if ( info != 6 ) ecType = EndCriteria.Type.StationaryFunctionValue; - endCriteria.checkMaxIterations( nfev, ref ecType ); - Utils.QL_REQUIRE( info != 7 ,()=> "MINPACK: xtol is too small. no further " + - "improvement in the approximate " + - "solution x is possible." ); - Utils.QL_REQUIRE( info != 8 ,()=> "MINPACK: gtol is too small. fvec is " + - "orthogonal to the columns of the " + - "jacobian to machine precision." ); + Utils.QL_REQUIRE(info != 0, () => "MINPACK: improper input parameters"); + if (info != 6) + ecType = EndCriteria.Type.StationaryFunctionValue; + endCriteria.checkMaxIterations(nfev, ref ecType); + Utils.QL_REQUIRE(info != 7, () => "MINPACK: xtol is too small. no further " + + "improvement in the approximate " + + "solution x is possible."); + Utils.QL_REQUIRE(info != 8, () => "MINPACK: gtol is too small. fvec is " + + "orthogonal to the columns of the " + + "jacobian to machine precision."); // set problem - x_ = new Vector( xx.GetRange( 0, n ) ); - P.setCurrentValue( x_ ); - P.setFunctionValue( P.costFunction().value( x_ ) ); + x_ = new Vector(xx.GetRange(0, n)); + P.setCurrentValue(x_); + P.setFunctionValue(P.costFunction().value(x_)); return ecType; } - public Vector fcn( int m, int n, Vector x, int iflag ) + public Vector fcn(int m, int n, Vector x, int iflag) { - Vector xt = new Vector( x ); + Vector xt = new Vector(x); Vector fvec; // constraint handling needs some improvement in the future: // starting point should not be close to a constraint violation - if ( currentProblem_.constraint().test( xt ) ) + if (currentProblem_.constraint().test(xt)) { - fvec = new Vector( currentProblem_.values( xt ) ); + fvec = new Vector(currentProblem_.values(xt)); } else { - fvec = new Vector( initCostValues_ ); + fvec = new Vector(initCostValues_); } return fvec; } - public Matrix jacFcn( int m, int n, Vector x, int iflag ) + public Matrix jacFcn(int m, int n, Vector x, int iflag) { Vector xt = new Vector(x); Matrix fjac; // constraint handling needs some improvement in the future: // starting point should not be close to a constraint violation - if (currentProblem_.constraint().test(xt)) + if (currentProblem_.constraint().test(xt)) { - Matrix tmp = new Matrix(m,n); + Matrix tmp = new Matrix(m, n); currentProblem_.costFunction().jacobian(tmp, xt); Matrix tmpT = Matrix.transpose(tmp); - fjac = new Matrix( tmpT ); - } - else + fjac = new Matrix(tmpT); + } + else { Matrix tmpT = Matrix.transpose(initJacobian_); - fjac = new Matrix( tmpT ); + fjac = new Matrix(tmpT); } return fjac; } diff --git a/src/QLNet/Math/Optimization/LineSearch.cs b/src/QLNet/Math/Optimization/LineSearch.cs index e03663ea1..a16cf196a 100644 --- a/src/QLNet/Math/Optimization/LineSearch.cs +++ b/src/QLNet/Math/Optimization/LineSearch.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - * + * This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -87,8 +87,14 @@ public double update(ref Vector data, Vector direction, double beta, Constraint //! current value of the search direction public Vector searchDirection { - get { return searchDirection_; } - set { searchDirection_ = value; } + get + { + return searchDirection_; + } + set + { + searchDirection_ = value; + } } //! current values of the search direction diff --git a/src/QLNet/Math/Optimization/LineSearchBasedMethod.cs b/src/QLNet/Math/Optimization/LineSearchBasedMethod.cs index 5842f67e1..333612d0b 100644 --- a/src/QLNet/Math/Optimization/LineSearchBasedMethod.cs +++ b/src/QLNet/Math/Optimization/LineSearchBasedMethod.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,12 +24,12 @@ namespace QLNet { public class LineSearchBasedMethod : OptimizationMethod { - public LineSearchBasedMethod( LineSearch lineSearch = null ) + public LineSearchBasedMethod(LineSearch lineSearch = null) { lineSearch_ = lineSearch ?? new ArmijoLineSearch(); } - public override EndCriteria.Type minimize(Problem P,EndCriteria endCriteria) + public override EndCriteria.Type minimize(Problem P, EndCriteria endCriteria) { // Initializations double ftol = endCriteria.functionEpsilon(); @@ -39,7 +39,7 @@ public override EndCriteria.Type minimize(Problem P,EndCriteria endCriteria) Vector x_ = P.currentValue(); // store the starting point int iterationNumber_ = 0; // dimension line search - lineSearch_.searchDirection = new Vector( x_.size() ); + lineSearch_.searchDirection = new Vector(x_.size()); bool done = false; // function and squared norm of gradient values @@ -50,10 +50,10 @@ public override EndCriteria.Type minimize(Problem P,EndCriteria endCriteria) // Set gradient g at the size of the optimization problem // search direction int sz = lineSearch_.searchDirection.size(); - Vector prevGradient = new Vector( sz ), d = new Vector( sz ), sddiff = new Vector( sz ), direction = new Vector( sz ); + Vector prevGradient = new Vector(sz), d = new Vector(sz), sddiff = new Vector(sz), direction = new Vector(sz); // Initialize cost function, gradient prevGradient and search direction - P.setFunctionValue( P.valueAndGradient( prevGradient, x_ ) ); - P.setGradientNormValue( Vector.DotProduct( prevGradient, prevGradient ) ); + P.setFunctionValue(P.valueAndGradient(prevGradient, x_)); + P.setGradientNormValue(Vector.DotProduct(prevGradient, prevGradient)); lineSearch_.searchDirection = prevGradient * -1; bool first_time = true; @@ -61,11 +61,11 @@ public override EndCriteria.Type minimize(Problem P,EndCriteria endCriteria) do { // Linesearch - if ( !first_time ) + if (!first_time) prevGradient = lineSearch_.lastGradient(); - t = ( lineSearch_.value( P, ref ecType, endCriteria, t ) ); + t = (lineSearch_.value(P, ref ecType, endCriteria, t)); // don't throw: it can fail just because maxIterations exceeded - if ( lineSearch_.succeed() ) + if (lineSearch_.succeed()) { // Updates @@ -73,31 +73,31 @@ public override EndCriteria.Type minimize(Problem P,EndCriteria endCriteria) x_ = lineSearch_.lastX(); // New function value fold = P.functionValue(); - P.setFunctionValue( lineSearch_.lastFunctionValue() ); + P.setFunctionValue(lineSearch_.lastFunctionValue()); // New gradient and search direction vectors // orthogonalization coef gold2 = P.gradientNormValue(); - P.setGradientNormValue( lineSearch_.lastGradientNorm2() ); + P.setGradientNormValue(lineSearch_.lastGradientNorm2()); // conjugate gradient search direction - direction = getUpdatedDirection( P, gold2, prevGradient ); + direction = getUpdatedDirection(P, gold2, prevGradient); sddiff = direction - lineSearch_.searchDirection; lineSearch_.searchDirection = direction; // Now compute accuracy and check end criteria // Numerical Recipes exit strategy on fx (see NR in C++, p.423) fnew = P.functionValue(); - fdiff = 2.0 * Math.Abs( fnew - fold ) / - ( Math.Abs( fnew ) + Math.Abs( fold ) + Const.QL_EPSILON ); - if ( fdiff < ftol || - endCriteria.checkMaxIterations( iterationNumber_, ref ecType ) ) + fdiff = 2.0 * Math.Abs(fnew - fold) / + (Math.Abs(fnew) + Math.Abs(fold) + Const.QL_EPSILON); + if (fdiff < ftol || + endCriteria.checkMaxIterations(iterationNumber_, ref ecType)) { - endCriteria.checkStationaryFunctionValue( 0.0, 0.0, ref maxStationaryStateIterations_, ref ecType ); - endCriteria.checkMaxIterations( iterationNumber_, ref ecType ); + endCriteria.checkStationaryFunctionValue(0.0, 0.0, ref maxStationaryStateIterations_, ref ecType); + endCriteria.checkMaxIterations(iterationNumber_, ref ecType); return ecType; } - P.setCurrentValue( x_ ); // update problem current value + P.setCurrentValue(x_); // update problem current value ++iterationNumber_; // Increase iteration number first_time = false; } @@ -106,12 +106,12 @@ public override EndCriteria.Type minimize(Problem P,EndCriteria endCriteria) done = true; } } - while ( !done ); - P.setCurrentValue( x_ ); + while (!done); + P.setCurrentValue(x_); return ecType; - } + } //! computes the new search direction - protected virtual Vector getUpdatedDirection(Problem P,double gold2,Vector gradient) + protected virtual Vector getUpdatedDirection(Problem P, double gold2, Vector gradient) { throw new NotImplementedException(); } diff --git a/src/QLNet/Math/Optimization/LmDif.cs b/src/QLNet/Math/Optimization/LmDif.cs new file mode 100644 index 000000000..895dfed89 --- /dev/null +++ b/src/QLNet/Math/Optimization/LmDif.cs @@ -0,0 +1,1607 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +/* +The original Fortran version is Copyright (C) 1999 University of Chicago. +All rights reserved. + +Redistribution and use in source and binary forms, with or +without modification, are permitted provided that the +following conditions are met: + +1. Redistributions of source code must retain the above +copyright notice, this list of conditions and the following +disclaimer. + +2. Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following +disclaimer in the documentation and/or other materials +provided with the distribution. + +3. The end-user documentation included with the +redistribution, if any, must include the following +acknowledgment: + + "This product includes software developed by the + University of Chicago, as Operator of Argonne National + Laboratory. + +Alternately, this acknowledgment may appear in the software +itself, if and wherever such third-party acknowledgments +normally appear. + +4. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" +WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE +UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND +THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE +OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY +OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR +USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF +THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) +DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION +UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL +BE CORRECTED. + +5. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT +HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF +ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, +INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF +ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF +PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER +SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT +(INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, +EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE +POSSIBILITY OF SUCH LOSS OR DAMAGES. + + +C translation Copyright (C) Steve Moshier + +What you see here may be used freely but it comes with no support +or guarantee. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + public static class MINPACK + { + /* resolution of arithmetic */ + const double MACHEP = 1.2e-16; + /* smallest nonzero number */ + const double DWARF = 1.0e-38; + + /* + * ********** + * + * subroutine lmdif + * + * the purpose of lmdif is to minimize the sum of the squares of + * m nonlinear functions in n variables by a modification of + * the levenberg-marquardt algorithm. the user must provide a + * subroutine which calculates the functions. the jacobian is + * then calculated by a forward-difference approximation. + * + * the subroutine statement is + * + * subroutine lmdif(fcn,m,n,x,fvec,ftol,xtol,gtol,maxfev,epsfcn, + * diag,mode,factor,nprint,info,nfev,fjac, + * ldfjac,ipvt,qtf,wa1,wa2,wa3,wa4) + * + * where + * + * fcn is the name of the user-supplied subroutine which + * calculates the functions. fcn must be declared + * in an external statement in the user calling + * program, and should be written as follows. + * + * subroutine fcn(m,n,x,fvec,iflag) + * integer m,n,iflag + * double precision x(n),fvec(m) + * ---------- + * calculate the functions at x and + * return this vector in fvec. + * ---------- + * return + * end + * + * the value of iflag should not be changed by fcn unless + * the user wants to terminate execution of lmdif. + * in this case set iflag to a negative integer. + * + * m is a positive integer input variable set to the number + * of functions. + * + * n is a positive integer input variable set to the number + * of variables. n must not exceed m. + * + * x is an array of length n. on input x must contain + * an initial estimate of the solution vector. on output x + * contains the final estimate of the solution vector. + * + * fvec is an output array of length m which contains + * the functions evaluated at the output x. + * + * ftol is a nonnegative input variable. termination + * occurs when both the actual and predicted relative + * reductions in the sum of squares are at most ftol. + * therefore, ftol measures the relative error desired + * in the sum of squares. + * + * xtol is a nonnegative input variable. termination + * occurs when the relative error between two consecutive + * iterates is at most xtol. therefore, xtol measures the + * relative error desired in the approximate solution. + * + * gtol is a nonnegative input variable. termination + * occurs when the cosine of the angle between fvec and + * any column of the jacobian is at most gtol in absolute + * value. therefore, gtol measures the orthogonality + * desired between the function vector and the columns + * of the jacobian. + * + * maxfev is a positive integer input variable. termination + * occurs when the number of calls to fcn is at least + * maxfev by the end of an iteration. + * + * epsfcn is an input variable used in determining a suitable + * step length for the forward-difference approximation. this + * approximation assumes that the relative errors in the + * functions are of the order of epsfcn. if epsfcn is less + * than the machine precision, it is assumed that the relative + * errors in the functions are of the order of the machine + * precision. + * + * diag is an array of length n. if mode = 1 (see + * below), diag is internally set. if mode = 2, diag + * must contain positive entries that serve as + * multiplicative scale factors for the variables. + * + * mode is an integer input variable. if mode = 1, the + * variables will be scaled internally. if mode = 2, + * the scaling is specified by the input diag. other + * values of mode are equivalent to mode = 1. + * + * factor is a positive input variable used in determining the + * initial step bound. this bound is set to the product of + * factor and the euclidean norm of diag*x if nonzero, or else + * to factor itself. in most cases factor should lie in the + * interval (.1,100.). 100. is a generally recommended value. + * + * nprint is an integer input variable that enables controlled + * printing of iterates if it is positive. in this case, + * fcn is called with iflag = 0 at the beginning of the first + * iteration and every nprint iterations thereafter and + * immediately prior to return, with x and fvec available + * for printing. if nprint is not positive, no special calls + * of fcn with iflag = 0 are made. + * + * info is an integer output variable. if the user has + * terminated execution, info is set to the (negative) + * value of iflag. see description of fcn. otherwise, + * info is set as follows. + * + * info = 0 improper input parameters. + * + * info = 1 both actual and predicted relative reductions + * in the sum of squares are at most ftol. + * + * info = 2 relative error between two consecutive iterates + * is at most xtol. + * + * info = 3 conditions for info = 1 and info = 2 both hold. + * + * info = 4 the cosine of the angle between fvec and any + * column of the jacobian is at most gtol in + * absolute value. + * + * info = 5 number of calls to fcn has reached or + * exceeded maxfev. + * + * info = 6 ftol is too small. no further reduction in + * the sum of squares is possible. + * + * info = 7 xtol is too small. no further improvement in + * the approximate solution x is possible. + * + * info = 8 gtol is too small. fvec is orthogonal to the + * columns of the jacobian to machine precision. + * + * nfev is an integer output variable set to the number of + * calls to fcn. + * + * fjac is an output m by n array. the upper n by n submatrix + * of fjac contains an upper triangular matrix r with + * diagonal elements of nonincreasing magnitude such that + * + * t t t + * p *(jac *jac)*p = r *r, + * + * where p is a permutation matrix and jac is the final + * calculated jacobian. column j of p is column ipvt(j) + * (see below) of the identity matrix. the lower trapezoidal + * part of fjac contains information generated during + * the computation of r. + * + * ldfjac is a positive integer input variable not less than m + * which specifies the leading dimension of the array fjac. + * + * ipvt is an integer output array of length n. ipvt + * defines a permutation matrix p such that jac*p = q*r, + * where jac is the final calculated jacobian, q is + * orthogonal (not stored), and r is upper triangular + * with diagonal elements of nonincreasing magnitude. + * column j of p is column ipvt(j) of the identity matrix. + * + * qtf is an output array of length n which contains + * the first n elements of the vector (q transpose)*fvec. + * + * wa1, wa2, and wa3 are work arrays of length n. + * + * wa4 is a work array of length m. + * + * subprograms called + * + * user-supplied ...... fcn, jacFcn + * + * minpack-supplied ... dpmpar,enorm,fdjac2,lmpar,qrfac + * + * argonne national laboratory. minpack project. march 1980. + * burton s. garbow, kenneth e. hillstrom, jorge j. more + * + * ********** + */ + public static void lmdif(int m, int n, Vector x, ref Vector fvec, double ftol, + double xtol, double gtol, int maxfev, double epsfcn, + Vector diag, int mode, double factor, + int nprint, ref int info, ref int nfev, ref Matrix fjac, + int ldfjac, ref List ipvt, ref Vector qtf, + Vector wa1, Vector wa2, Vector wa3, Vector wa4, + Func fcn, + Func jacFcn) + { + + int i, iflag, ij, jj, iter, j, l; + double actred, delta = 0, dirder, fnorm, fnorm1, gnorm; + double par, pnorm, prered, ratio; + double sum, temp, temp1, temp2, temp3, xnorm = 0; + + const double one = 1.0; + const double p1 = 0.1; + const double p5 = 0.5; + const double p25 = 0.25; + const double p75 = 0.75; + const double p0001 = 1.0e-4; + const double zero = 0.0; + + info = 0; + iflag = 0; + nfev = 0; + + /* + * check the input parameters for errors. + */ + if ((n <= 0) || (m < n) || (ldfjac < m) || (ftol < zero) + || (xtol < zero) || (gtol < zero) || (maxfev <= 0) + || (factor <= zero)) + goto L300; + + if (mode == 2) /* scaling by diag[] */ + { + for (j = 0; j < n; j++) + { + if (diag[j] <= 0.0) + goto L300; + } + } + /* + * evaluate the function at the starting point + * and calculate its norm. + */ + iflag = 1; + fvec = fcn(m, n, x, iflag); + nfev = 1; + if (iflag < 0) + goto L300; + fnorm = enorm(m, fvec); + /* + * initialize levenberg-marquardt parameter and iteration counter. + */ + par = zero; + iter = 1; + /* + * beginning of the outer loop. + */ + + L30: + + /* + * calculate the jacobian matrix. + */ + iflag = 2; + if (jacFcn != null) // use user supplied jacobian calculation + fjac = jacFcn(m, n, x, iflag); + else + fdjac2(m, n, x, fvec, fjac, ldfjac, iflag, epsfcn, ref wa4, fcn); + nfev += n; + if (iflag < 0) + goto L300; + /* + * if requested, call fcn to enable printing of iterates. + */ + if (nprint > 0) + { + iflag = 0; + if (mod(iter - 1, nprint) == 0) + { + fvec = fcn(m, n, x, iflag); + if (iflag < 0) + goto L300; + } + } + /* + * compute the qr factorization of the jacobian. + */ + qrfac(m, n, fjac, ldfjac, 1, ref ipvt, n, ref wa1, ref wa2, wa3); + /* + * on the first iteration and if mode is 1, scale according + * to the norms of the columns of the initial jacobian. + */ + if (iter == 1) + { + if (mode != 2) + { + for (j = 0; j < n; j++) + { + diag[j] = wa2[j]; + if (wa2[j].IsEqual(zero)) + diag[j] = one; + } + } + + /* + * on the first iteration, calculate the norm of the scaled x + * and initialize the step bound delta. + */ + for (j = 0; j < n; j++) + wa3[j] = diag[j] * x[j]; + + xnorm = enorm(n, wa3); + delta = factor * xnorm; + if (delta.IsEqual(zero)) + delta = factor; + } + + /* + * form (q transpose)*fvec and store the first n components in + * qtf. + */ + for (i = 0; i < m; i++) + wa4[i] = fvec[i]; + jj = 0; + for (j = 0; j < n; j++) + { + temp3 = fjac[jj]; + if (temp3.IsNotEqual(zero)) + { + sum = zero; + ij = jj; + for (i = j; i < m; i++) + { + sum += fjac[ij] * wa4[i]; + ij += 1; /* fjac[i+m*j] */ + } + temp = -sum / temp3; + ij = jj; + for (i = j; i < m; i++) + { + wa4[i] += fjac[ij] * temp; + ij += 1; /* fjac[i+m*j] */ + } + } + fjac[jj] = wa1[j]; + jj += m + 1; /* fjac[j+m*j] */ + qtf[j] = wa4[j]; + } + + /* + * compute the norm of the scaled gradient. + */ + gnorm = zero; + if (fnorm.IsNotEqual(zero)) + { + jj = 0; + for (j = 0; j < n; j++) + { + l = ipvt[j]; + if (wa2[l].IsNotEqual(zero)) + { + sum = zero; + ij = jj; + for (i = 0; i <= j; i++) + { + sum += fjac[ij] * (qtf[i] / fnorm); + ij += 1; /* fjac[i+m*j] */ + } + gnorm = dmax1(gnorm, Math.Abs(sum / wa2[l])); + } + jj += m; + } + } + + /* + * test for convergence of the gradient norm. + */ + if (gnorm <= gtol) + info = 4; + if (info != 0) + goto L300; + /* + * rescale if necessary. + */ + if (mode != 2) + { + for (j = 0; j < n; j++) + diag[j] = dmax1(diag[j], wa2[j]); + } + + /* + * beginning of the inner loop. + */ + L200: + /* + * determine the levenberg-marquardt parameter. + */ + lmpar(n, fjac, ldfjac, ipvt, diag, qtf, delta, par, wa1, wa2, wa3, wa4); + /* + * store the direction p and x + p. calculate the norm of p. + */ + for (j = 0; j < n; j++) + { + wa1[j] = -wa1[j]; + wa2[j] = x[j] + wa1[j]; + wa3[j] = diag[j] * wa1[j]; + } + pnorm = enorm(n, wa3); + /* + * on the first iteration, adjust the initial step bound. + */ + if (iter == 1) + delta = dmin1(delta, pnorm); + /* + * evaluate the function at x + p and calculate its norm. + */ + iflag = 1; + wa4 = fcn(m, n, wa2, iflag); + nfev += 1; + if (iflag < 0) + goto L300; + fnorm1 = enorm(m, wa4); + + /* + * compute the scaled actual reduction. + */ + actred = -one; + if ((p1 * fnorm1) < fnorm) + { + temp = fnorm1 / fnorm; + actred = one - temp * temp; + } + /* + * compute the scaled predicted reduction and + * the scaled directional derivative. + */ + jj = 0; + for (j = 0; j < n; j++) + { + wa3[j] = zero; + l = ipvt[j]; + temp = wa1[l]; + ij = jj; + for (i = 0; i <= j; i++) + { + wa3[i] += fjac[ij] * temp; + ij += 1; /* fjac[i+m*j] */ + } + jj += m; + } + temp1 = enorm(n, wa3) / fnorm; + temp2 = (Math.Sqrt(par) * pnorm) / fnorm; + prered = temp1 * temp1 + (temp2 * temp2) / p5; + dirder = -(temp1 * temp1 + temp2 * temp2); + /* + * compute the ratio of the actual to the predicted + * reduction. + */ + ratio = zero; + if (prered.IsNotEqual(zero)) + ratio = actred / prered; + /* + * update the step bound. + */ + if (ratio <= p25) + { + if (actred >= zero) + temp = p5; + else + temp = p5 * dirder / (dirder + p5 * actred); + if (((p1 * fnorm1) >= fnorm) + || (temp < p1)) + temp = p1; + delta = temp * dmin1(delta, pnorm / p1); + par = par / temp; + } + else + { + if ((par.IsEqual(zero)) || (ratio >= p75)) + { + delta = pnorm / p5; + par = p5 * par; + } + } + /* + * test for successful iteration. + */ + if (ratio >= p0001) + { + /* + * successful iteration. update x, fvec, and their norms. + */ + for (j = 0; j < n; j++) + { + x[j] = wa2[j]; + wa2[j] = diag[j] * x[j]; + } + for (i = 0; i < m; i++) + fvec[i] = wa4[i]; + xnorm = enorm(n, wa2); + fnorm = fnorm1; + iter += 1; + } + /* + * tests for convergence. + */ + if ((Math.Abs(actred) <= ftol) + && (prered <= ftol) + && (p5 * ratio <= one)) + info = 1; + if (delta <= xtol * xnorm) + info = 2; + if ((Math.Abs(actred) <= ftol) + && (prered <= ftol) + && (p5 * ratio <= one) + && (info == 2)) + info = 3; + if (info != 0) + goto L300; + /* + * tests for termination and stringent tolerances. + */ + if (nfev >= maxfev) + info = 5; + if ((Math.Abs(actred) <= MACHEP) + && (prered <= MACHEP) + && (p5 * ratio <= one)) + info = 6; + if (delta <= MACHEP * xnorm) + info = 7; + if (gnorm <= MACHEP) + info = 8; + if (info != 0) + goto L300; + /* + * end of the inner loop. repeat if iteration unsuccessful. + */ + if (ratio < p0001) + goto L200; + /* + * end of the outer loop. + */ + goto L30; + + L300: + /* + * termination, either normal or user imposed. + */ + if (iflag < 0) + info = iflag; + iflag = 0; + if (nprint > 0) + fvec = fcn(m, n, x, iflag); + } + + /* + * ********** + * + * function enorm + * + * given an n-vector x, this function calculates the + * euclidean norm of x. + * + * the euclidean norm is computed by accumulating the sum of + * squares in three different sums. the sums of squares for the + * small and large components are scaled so that no overflows + * occur. non-destructive underflows are permitted. underflows + * and overflows do not occur in the computation of the unscaled + * sum of squares for the intermediate components. + * the definitions of small, intermediate and large components + * depend on two constants, rdwarf and rgiant. the main + * restrictions on these constants are that rdwarf**2 not + * underflow and rgiant**2 not overflow. the constants + * given here are suitable for every known computer. + * + * the function statement is + * + * double precision function enorm(n,x) + * + * where + * + * n is a positive integer input variable. + * + * x is an input array of length n. + * + * argonne national laboratory. minpack project. march 1980. + * burton s. garbow, kenneth e. hillstrom, jorge j. more + * + * ********** + */ + static double enorm(int n, List x) + { + int i; + double agiant, floatn, s1, s2, s3, xabs, x1max, x3max; + double ans, temp; + + const double rdwarf = 3.834e-20; + const double rgiant = 1.304e19; + const double zero = 0.0; + const double one = 1.0; + + s1 = zero; + s2 = zero; + s3 = zero; + x1max = zero; + x3max = zero; + floatn = n; + agiant = rgiant / floatn; + + for (i = 0; i < n; i++) + { + xabs = Math.Abs(x[i]); + if ((xabs > rdwarf) && (xabs < agiant)) + { + /* + * sum for intermediate components. + */ + s2 += xabs * xabs; + continue; + } + + if (xabs > rdwarf) + { + /* + * sum for large components. + */ + if (xabs > x1max) + { + temp = x1max / xabs; + s1 = one + s1 * temp * temp; + x1max = xabs; + } + else + { + temp = xabs / x1max; + s1 += temp * temp; + } + continue; + } + + /* + * sum for small components. + */ + if (xabs > x3max) + { + temp = x3max / xabs; + s3 = one + s3 * temp * temp; + x3max = xabs; + } + else + { + if (xabs.IsNotEqual(zero)) + { + temp = xabs / x3max; + s3 += temp * temp; + } + } + } + /* + * calculation of norm. + */ + if (s1.IsNotEqual(zero)) + { + temp = s1 + (s2 / x1max) / x1max; + ans = x1max * Math.Sqrt(temp); + return (ans); + } + if (s2.IsNotEqual(zero)) + { + if (s2 >= x3max) + temp = s2 * (one + (x3max / s2) * (x3max * s3)); + else + temp = x3max * ((s2 / x3max) + (x3max * s3)); + ans = Math.Sqrt(temp); + } + else + { + ans = x3max * Math.Sqrt(s3); + } + return (ans); + } + + /* + * ********** + * + * subroutine fdjac2 + * + * this subroutine computes a forward-difference approximation + * to the m by n jacobian matrix associated with a specified + * problem of m functions in n variables. + * + * the subroutine statement is + * + * subroutine fdjac2(fcn,m,n,x,fvec,fjac,ldfjac,iflag,epsfcn,wa) + * + * where + * + * fcn is the name of the user-supplied subroutine which + * calculates the functions. fcn must be declared + * in an external statement in the user calling + * program, and should be written as follows. + * + * subroutine fcn(m,n,x,fvec,iflag) + * integer m,n,iflag + * double precision x(n),fvec(m) + * ---------- + * calculate the functions at x and + * return this vector in fvec. + * ---------- + * return + * end + * + * the value of iflag should not be changed by fcn unless + * the user wants to terminate execution of fdjac2. + * in this case set iflag to a negative integer. + * + * m is a positive integer input variable set to the number + * of functions. + * + * n is a positive integer input variable set to the number + * of variables. n must not exceed m. + * + * x is an input array of length n. + * + * fvec is an input array of length m which must contain the + * functions evaluated at x. + * + * fjac is an output m by n array which contains the + * approximation to the jacobian matrix evaluated at x. + * + * ldfjac is a positive integer input variable not less than m + * which specifies the leading dimension of the array fjac. + * + * iflag is an integer variable which can be used to terminate + * the execution of fdjac2. see description of fcn. + * + * epsfcn is an input variable used in determining a suitable + * step length for the forward-difference approximation. this + * approximation assumes that the relative errors in the + * functions are of the order of epsfcn. if epsfcn is less + * than the machine precision, it is assumed that the relative + * errors in the functions are of the order of the machine + * precision. + * + * wa is a work array of length m. + * + * subprograms called + * + * user-supplied ...... fcn + * + * minpack-supplied ... dpmpar + * + * fortran-supplied ... dabs,dmax1,dsqrt + * + * argonne national laboratory. minpack project. march 1980. + * burton s. garbow, kenneth e. hillstrom, jorge j. more + * + ********** + */ + static void fdjac2(int m, int n, Vector x, Vector fvec, Matrix fjac, int dummy1, + int iflag, double epsfcn, ref Vector wa, + Func fcn) + { + int i, j, ij; + double eps, h, temp; + + double zero = 0.0; + + temp = dmax1(epsfcn, MACHEP); + eps = Math.Sqrt(temp); + ij = 0; + for (j = 0; j < n; j++) + { + temp = x[j]; + h = eps * Math.Abs(temp); + if (h.IsEqual(zero)) + h = eps; + x[j] = temp + h; + wa = fcn(m, n, x, iflag); + if (iflag < 0) + return; + x[j] = temp; + for (i = 0; i < m; i++) + { + fjac[ij] = (wa[i] - fvec[i]) / h; + ij += 1; /* fjac[i+m*j] */ + } + } + } + + + /* + * ********** + * + * subroutine qrfac + * + * this subroutine uses householder transformations with column + * pivoting (optional) to compute a qr factorization of the + * m by n matrix a. that is, qrfac determines an orthogonal + * matrix q, a permutation matrix p, and an upper trapezoidal + * matrix r with diagonal elements of nonincreasing magnitude, + * such that a*p = q*r. the householder transformation for + * column k, k = 1,2,...,min(m,n), is of the form + * + * t + * i - (1/u(k))*u*u + * + * where u has zeros in the first k-1 positions. the form of + * this transformation and the method of pivoting first + * appeared in the corresponding linpack subroutine. + * + * the subroutine statement is + * + * subroutine qrfac(m,n,a,lda,pivot,ipvt,lipvt,rdiag,acnorm,wa) + * + * where + * + * m is a positive integer input variable set to the number + * of rows of a. + * + * n is a positive integer input variable set to the number + * of columns of a. + * + * a is an m by n array. on input a contains the matrix for + * which the qr factorization is to be computed. on output + * the strict upper trapezoidal part of a contains the strict + * upper trapezoidal part of r, and the lower trapezoidal + * part of a contains a factored form of q (the non-trivial + * elements of the u vectors described above). + * + * lda is a positive integer input variable not less than m + * which specifies the leading dimension of the array a. + * + * pivot is a logical input variable. if pivot is set true, + * then column pivoting is enforced. if pivot is set false, + * then no column pivoting is done. + * + * ipvt is an integer output array of length lipvt. ipvt + * defines the permutation matrix p such that a*p = q*r. + * column j of p is column ipvt(j) of the identity matrix. + * if pivot is false, ipvt is not referenced. + * + * lipvt is a positive integer input variable. if pivot is false, + * then lipvt may be as small as 1. if pivot is true, then + * lipvt must be at least n. + * + * rdiag is an output array of length n which contains the + * diagonal elements of r. + * + * acnorm is an output array of length n which contains the + * norms of the corresponding columns of the input matrix a. + * if this information is not needed, then acnorm can coincide + * with rdiag. + * + * wa is a work array of length n. if pivot is false, then wa + * can coincide with rdiag. + * + * subprograms called + * + * minpack-supplied ... dpmpar,enorm + * + * fortran-supplied ... dmax1,dsqrt,min0 + * + * argonne national laboratory. minpack project. march 1980. + * burton s. garbow, kenneth e. hillstrom, jorge j. more + * + * ********** + */ + public static void qrfac(int m, int n, Matrix a, int dummy1, int pivot, ref List ipvt, + int dummy2, ref Vector rdiag, ref Vector acnorm, Vector wa) + { + int i, ij, jj, j, jp1, k, kmax, minmn; + double ajnorm, sum, temp; + + double zero = 0.0; + double one = 1.0; + double p05 = 0.05; + + /* + * compute the initial column norms and initialize several arrays. + */ + ij = 0; + for (j = 0; j < n; j++) + { + acnorm[j] = enorm(m, a.GetRange(ij, m)); + rdiag[j] = acnorm[j]; + wa[j] = rdiag[j]; + if (pivot != 0) + ipvt[j] = j; + ij += m; /* m*j */ + } + /* + * reduce a to r with householder transformations. + */ + minmn = min0(m, n); + for (j = 0; j < minmn; j++) + { + if (pivot == 0) + goto L40; + /* + * bring the column of largest norm into the pivot position. + */ + kmax = j; + for (k = j; k < n; k++) + { + if (rdiag[k] > rdiag[kmax]) + kmax = k; + } + if (kmax == j) + goto L40; + + ij = m * j; + jj = m * kmax; + for (i = 0; i < m; i++) + { + temp = a[ij]; /* [i+m*j] */ + a[ij] = a[jj]; /* [i+m*kmax] */ + a[jj] = temp; + ij += 1; + jj += 1; + } + rdiag[kmax] = rdiag[j]; + wa[kmax] = wa[j]; + k = ipvt[j]; + ipvt[j] = ipvt[kmax]; + ipvt[kmax] = k; + + L40: + /* + * compute the householder transformation to reduce the + * j-th column of a to a multiple of the j-th unit vector. + */ + jj = j + m * j; + ajnorm = enorm(m - j, a.GetRange(jj, m - j)); + if (ajnorm.IsEqual(zero)) + goto L100; + if (a[jj] < zero) + ajnorm = -ajnorm; + ij = jj; + for (i = j; i < m; i++) + { + a[ij] /= ajnorm; + ij += 1; /* [i+m*j] */ + } + a[jj] += one; + /* + * apply the transformation to the remaining columns + * and update the norms. + */ + jp1 = j + 1; + if (jp1 < n) + { + for (k = jp1; k < n; k++) + { + sum = zero; + ij = j + m * k; + jj = j + m * j; + for (i = j; i < m; i++) + { + sum += a[jj] * a[ij]; + ij += 1; /* [i+m*k] */ + jj += 1; /* [i+m*j] */ + } + temp = sum / a[j + m * j]; + ij = j + m * k; + jj = j + m * j; + for (i = j; i < m; i++) + { + a[ij] -= temp * a[jj]; + ij += 1; /* [i+m*k] */ + jj += 1; /* [i+m*j] */ + } + if ((pivot != 0) && (rdiag[k].IsNotEqual(zero))) + { + temp = a[j + m * k] / rdiag[k]; + temp = dmax1(zero, one - temp * temp); + rdiag[k] *= Math.Sqrt(temp); + temp = rdiag[k] / wa[k]; + if ((p05 * temp * temp) <= MACHEP) + { + rdiag[k] = enorm(m - j - 1, a.GetRange(jp1 + m * k, m - j - 1)); + wa[k] = rdiag[k]; + } + } + } + } + + L100: + rdiag[j] = -ajnorm; + } + } + + + /* + * ********** + * + * subroutine qrsolv + * + * given an m by n matrix a, an n by n diagonal matrix d, + * and an m-vector b, the problem is to determine an x which + * solves the system + * + * a*x = b , d*x = 0 , + * + * in the least squares sense. + * + * this subroutine completes the solution of the problem + * if it is provided with the necessary information from the + * qr factorization, with column pivoting, of a. that is, if + * a*p = q*r, where p is a permutation matrix, q has orthogonal + * columns, and r is an upper triangular matrix with diagonal + * elements of nonincreasing magnitude, then qrsolv expects + * the full upper triangle of r, the permutation matrix p, + * and the first n components of (q transpose)*b. the system + * a*x = b, d*x = 0, is then equivalent to + * + * t t + * r*z = q *b , p *d*p*z = 0 , + * + * where x = p*z. if this system does not have full rank, + * then a least squares solution is obtained. on output qrsolv + * also provides an upper triangular matrix s such that + * + * t t t + * p *(a *a + d*d)*p = s *s . + * + * s is computed within qrsolv and may be of separate interest. + * + * the subroutine statement is + * + * subroutine qrsolv(n,r,ldr,ipvt,diag,qtb,x,sdiag,wa) + * + * where + * + * n is a positive integer input variable set to the order of r. + * + * r is an n by n array. on input the full upper triangle + * must contain the full upper triangle of the matrix r. + * on output the full upper triangle is unaltered, and the + * strict lower triangle contains the strict upper triangle + * (transposed) of the upper triangular matrix s. + * + * ldr is a positive integer input variable not less than n + * which specifies the leading dimension of the array r. + * + * ipvt is an integer input array of length n which defines the + * permutation matrix p such that a*p = q*r. column j of p + * is column ipvt(j) of the identity matrix. + * + * diag is an input array of length n which must contain the + * diagonal elements of the matrix d. + * + * qtb is an input array of length n which must contain the first + * n elements of the vector (q transpose)*b. + * + * x is an output array of length n which contains the least + * squares solution of the system a*x = b, d*x = 0. + * + * sdiag is an output array of length n which contains the + * diagonal elements of the upper triangular matrix s. + * + * wa is a work array of length n. + * + * subprograms called + * + * fortran-supplied ... dabs,dsqrt + * + * argonne national laboratory. minpack project. march 1980. + * burton s. garbow, kenneth e. hillstrom, jorge j. more + * + * ********** + */ + public static void qrsolv(int n, Matrix r, int ldr, List ipvt, Vector diag, Vector qtb, Vector x, Vector sdiag, Vector wa) + { + int i, ij, ik, kk, j, jp1, k, kp1, l, nsing; + double cos, cotan, qtbpj, sin, sum, tan, temp; + + double zero = 0.0; + double p25 = 0.25; + double p5 = 0.5; + + /* + * copy r and (q transpose)*b to preserve input and initialize s. + * in particular, save the diagonal elements of r in x. + */ + kk = 0; + for (j = 0; j < n; j++) + { + ij = kk; + ik = kk; + for (i = j; i < n; i++) + { + r[ij] = r[ik]; + ij += 1; /* [i+ldr*j] */ + ik += ldr; /* [j+ldr*i] */ + } + x[j] = r[kk]; + wa[j] = qtb[j]; + kk += ldr + 1; /* j+ldr*j */ + } + + /* + * eliminate the diagonal matrix d using a givens rotation. + */ + for (j = 0; j < n; j++) + { + /* + * prepare the row of d to be eliminated, locating the + * diagonal element using p from the qr factorization. + */ + l = ipvt[j]; + if (diag[l].IsEqual(zero)) + goto L90; + for (k = j; k < n; k++) + sdiag[k] = zero; + sdiag[j] = diag[l]; + /* + * the transformations to eliminate the row of d + * modify only a single element of (q transpose)*b + * beyond the first n, which is initially zero. + */ + qtbpj = zero; + for (k = j; k < n; k++) + { + /* + * determine a givens rotation which eliminates the + * appropriate element in the current row of d. + */ + if (sdiag[k].IsEqual(zero)) + continue; + kk = k + ldr * k; + if (Math.Abs(r[kk]) < Math.Abs(sdiag[k])) + { + cotan = r[kk] / sdiag[k]; + sin = p5 / Math.Sqrt(p25 + p25 * cotan * cotan); + cos = sin * cotan; + } + else + { + tan = sdiag[k] / r[kk]; + cos = p5 / Math.Sqrt(p25 + p25 * tan * tan); + sin = cos * tan; + } + /* + * compute the modified diagonal element of r and + * the modified element of ((q transpose)*b,0). + */ + r[kk] = cos * r[kk] + sin * sdiag[k]; + temp = cos * wa[k] + sin * qtbpj; + qtbpj = -sin * wa[k] + cos * qtbpj; + wa[k] = temp; + /* + * accumulate the tranformation in the row of s. + */ + kp1 = k + 1; + if (n > kp1) + { + ik = kk + 1; + for (i = kp1; i < n; i++) + { + temp = cos * r[ik] + sin * sdiag[i]; + sdiag[i] = -sin * r[ik] + cos * sdiag[i]; + r[ik] = temp; + ik += 1; /* [i+ldr*k] */ + } + } + } + L90: + /* + * store the diagonal element of s and restore + * the corresponding diagonal element of r. + */ + kk = j + ldr * j; + sdiag[j] = r[kk]; + r[kk] = x[j]; + } + /* + * solve the triangular system for z. if the system is + * singular, then obtain a least squares solution. + */ + nsing = n; + for (j = 0; j < n; j++) + { + if ((sdiag[j].IsEqual(zero)) && (nsing == n)) + nsing = j; + if (nsing < n) + wa[j] = zero; + } + if (nsing < 1) + goto L150; + + for (k = 0; k < nsing; k++) + { + j = nsing - k - 1; + sum = zero; + jp1 = j + 1; + if (nsing > jp1) + { + ij = jp1 + ldr * j; + for (i = jp1; i < nsing; i++) + { + sum += r[ij] * wa[i]; + ij += 1; /* [i+ldr*j] */ + } + } + wa[j] = (wa[j] - sum) / sdiag[j]; + } + L150: + /* + * permute the components of z back to components of x. + */ + for (j = 0; j < n; j++) + { + l = ipvt[j]; + x[l] = wa[j]; + } + } + + + + /* ********** + * + * subroutine lmpar + * + * given an m by n matrix a, an n by n nonsingular diagonal + * matrix d, an m-vector b, and a positive number delta, + * the problem is to determine a value for the parameter + * par such that if x solves the system + * + * a*x = b , sqrt(par)*d*x = 0 , + * + * in the least squares sense, and dxnorm is the euclidean + * norm of d*x, then either par is zero and + * + * (dxnorm-delta) .le. 0.1*delta , + * + * or par is positive and + * + * abs(dxnorm-delta) .le. 0.1*delta . + * + * this subroutine completes the solution of the problem + * if it is provided with the necessary information from the + * qr factorization, with column pivoting, of a. that is, if + * a*p = q*r, where p is a permutation matrix, q has orthogonal + * columns, and r is an upper triangular matrix with diagonal + * elements of nonincreasing magnitude, then lmpar expects + * the full upper triangle of r, the permutation matrix p, + * and the first n components of (q transpose)*b. on output + * lmpar also provides an upper triangular matrix s such that + * + * t t t + * p *(a *a + par*d*d)*p = s *s . + * + * s is employed within lmpar and may be of separate interest. + * + * only a few iterations are generally needed for convergence + * of the algorithm. if, however, the limit of 10 iterations + * is reached, then the output par will contain the best + * value obtained so far. + * + * the subroutine statement is + * + * subroutine lmpar(n,r,ldr,ipvt,diag,qtb,delta,par,x,sdiag, + * wa1,wa2) + * + * where + * + * n is a positive integer input variable set to the order of r. + * + * r is an n by n array. on input the full upper triangle + * must contain the full upper triangle of the matrix r. + * on output the full upper triangle is unaltered, and the + * strict lower triangle contains the strict upper triangle + * (transposed) of the upper triangular matrix s. + * + * ldr is a positive integer input variable not less than n + * which specifies the leading dimension of the array r. + * + * ipvt is an integer input array of length n which defines the + * permutation matrix p such that a*p = q*r. column j of p + * is column ipvt(j) of the identity matrix. + * + * diag is an input array of length n which must contain the + * diagonal elements of the matrix d. + * + * qtb is an input array of length n which must contain the first + * n elements of the vector (q transpose)*b. + * + * delta is a positive input variable which specifies an upper + * bound on the euclidean norm of d*x. + * + * par is a nonnegative variable. on input par contains an + * initial estimate of the levenberg-marquardt parameter. + * on output par contains the final estimate. + * + * x is an output array of length n which contains the least + * squares solution of the system a*x = b, sqrt(par)*d*x = 0, + * for the output par. + * + * sdiag is an output array of length n which contains the + * diagonal elements of the upper triangular matrix s. + * + * wa1 and wa2 are work arrays of length n. + * + * subprograms called + * + * minpack-supplied ... dpmpar,enorm,qrsolv + * + * fortran-supplied ... dabs,dmax1,dmin1,dsqrt + * + * argonne national laboratory. minpack project. march 1980. + * burton s. garbow, kenneth e. hillstrom, jorge j. more + * + * ********** + */ + static void lmpar(int n, Matrix r, int ldr, List ipvt, Vector diag, + Vector qtb, double delta, double par, Vector x, Vector sdiag, + Vector wa1, Vector wa2) + { + int i, iter, ij, jj, j, jm1, jp1, k, l, nsing; + double dxnorm, fp, gnorm, parc, parl, paru; + double sum, temp; + + double zero = 0.0; + double p1 = 0.1; + double p001 = 0.001; + + /* + * compute and store in x the gauss-newton direction. if the + * jacobian is rank-deficient, obtain a least squares solution. + */ + nsing = n; + jj = 0; + for (j = 0; j < n; j++) + { + wa1[j] = qtb[j]; + if ((r[jj].IsEqual(zero)) && (nsing == n)) + nsing = j; + if (nsing < n) + wa1[j] = zero; + jj += ldr + 1; /* [j+ldr*j] */ + } + + if (nsing >= 1) + { + for (k = 0; k < nsing; k++) + { + j = nsing - k - 1; + wa1[j] = wa1[j] / r[j + ldr * j]; + temp = wa1[j]; + jm1 = j - 1; + if (jm1 >= 0) + { + ij = ldr * j; + for (i = 0; i <= jm1; i++) + { + wa1[i] -= r[ij] * temp; + ij += 1; + } + } + } + } + + for (j = 0; j < n; j++) + { + l = ipvt[j]; + x[l] = wa1[j]; + } + /* + * initialize the iteration counter. + * evaluate the function at the origin, and test + * for acceptance of the gauss-newton direction. + */ + iter = 0; + for (j = 0; j < n; j++) + wa2[j] = diag[j] * x[j]; + dxnorm = enorm(n, wa2); + fp = dxnorm - delta; + if (fp <= p1 * delta) + { + goto L220; + } + /* + * if the jacobian is not rank deficient, the newton + * step provides a lower bound, parl, for the zero of + * the function. otherwise set this bound to zero. + */ + parl = zero; + if (nsing >= n) + { + for (j = 0; j < n; j++) + { + l = ipvt[j]; + wa1[j] = diag[l] * (wa2[l] / dxnorm); + } + jj = 0; + for (j = 0; j < n; j++) + { + sum = zero; + jm1 = j - 1; + if (jm1 >= 0) + { + ij = jj; + for (i = 0; i <= jm1; i++) + { + sum += r[ij] * wa1[i]; + ij += 1; + } + } + wa1[j] = (wa1[j] - sum) / r[j + ldr * j]; + jj += ldr; /* [i+ldr*j] */ + } + temp = enorm(n, wa1); + parl = ((fp / delta) / temp) / temp; + } + /* + * calculate an upper bound, paru, for the zero of the function. + */ + jj = 0; + for (j = 0; j < n; j++) + { + sum = zero; + ij = jj; + for (i = 0; i <= j; i++) + { + sum += r[ij] * qtb[i]; + ij += 1; + } + l = ipvt[j]; + wa1[j] = sum / diag[l]; + jj += ldr; /* [i+ldr*j] */ + } + gnorm = enorm(n, wa1); + paru = gnorm / delta; + if (paru.IsEqual(zero)) + paru = DWARF / dmin1(delta, p1); + /* + * if the input par lies outside of the interval (parl,paru), + * set par to the closer endpoint. + */ + par = dmax1(par, parl); + par = dmin1(par, paru); + if (par.IsEqual(zero)) + par = gnorm / dxnorm; + + /* + * beginning of an iteration. + */ + L150: + iter += 1; + /* + * evaluate the function at the current value of par. + */ + if (par.IsEqual(zero)) + par = dmax1(DWARF, p001 * paru); + temp = Math.Sqrt(par); + for (j = 0; j < n; j++) + wa1[j] = temp * diag[j]; + qrsolv(n, r, ldr, ipvt, wa1, qtb, x, sdiag, wa2); + for (j = 0; j < n; j++) + wa2[j] = diag[j] * x[j]; + dxnorm = enorm(n, wa2); + temp = fp; + fp = dxnorm - delta; + /* + * if the function is small enough, accept the current value + * of par. also test for the exceptional cases where parl + * is zero or the number of iterations has reached 10. + */ + if ((Math.Abs(fp) <= p1 * delta) + || ((parl.IsEqual(zero)) && (fp <= temp) && (temp < zero)) + || (iter == 10)) + goto L220; + /* + * compute the newton correction. + */ + for (j = 0; j < n; j++) + { + l = ipvt[j]; + wa1[j] = diag[l] * (wa2[l] / dxnorm); + } + jj = 0; + for (j = 0; j < n; j++) + { + wa1[j] = wa1[j] / sdiag[j]; + temp = wa1[j]; + jp1 = j + 1; + if (jp1 < n) + { + ij = jp1 + jj; + for (i = jp1; i < n; i++) + { + wa1[i] -= r[ij] * temp; + ij += 1; /* [i+ldr*j] */ + } + } + jj += ldr; /* ldr*j */ + } + temp = enorm(n, wa1); + parc = ((fp / delta) / temp) / temp; + /* + * depending on the sign of the function, update parl or paru. + */ + if (fp > zero) + parl = dmax1(parl, par); + if (fp < zero) + paru = dmin1(paru, par); + /* + * compute an improved estimate for par. + */ + par = dmax1(parl, par + parc); + /* + * end of an iteration. + */ + goto L150; + + L220: + /* + * termination. + */ + if (iter == 0) + par = zero; + } + + + static double dmax1(double a, double b) { return a >= b ? a : b; } + static double dmin1(double a, double b) { return a <= b ? a : b; } + static int min0(int a, int b) { return a <= b ? a : b; } + static int mod(int k, int m) { return (k % m); } + + } +} diff --git a/src/QLNet/Math/Optimization/method.cs b/src/QLNet/Math/Optimization/Method.cs similarity index 84% rename from src/QLNet/Math/Optimization/method.cs rename to src/QLNet/Math/Optimization/Method.cs index d74219797..250ffe2be 100644 --- a/src/QLNet/Math/Optimization/method.cs +++ b/src/QLNet/Math/Optimization/Method.cs @@ -1,29 +1,29 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet +namespace QLNet { //! Abstract class for constrained optimization method public abstract class OptimizationMethod { //! minimize the optimization problem P - public abstract EndCriteria.Type minimize( Problem P, EndCriteria endCriteria ); + public abstract EndCriteria.Type minimize(Problem P, EndCriteria endCriteria); } } diff --git a/src/QLNet/Math/Optimization/Problem.cs b/src/QLNet/Math/Optimization/Problem.cs new file mode 100644 index 000000000..3b016afe2 --- /dev/null +++ b/src/QLNet/Math/Optimization/Problem.cs @@ -0,0 +1,112 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) + * + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +namespace QLNet +{ + //! Constrained optimization problem + public class Problem + { + //! Unconstrained cost function + protected CostFunction costFunction_; + public CostFunction costFunction() { return costFunction_; } + + //! Constraint + protected Constraint constraint_; + public Constraint constraint() { return constraint_; } + + //! current value of the local minimum + protected Vector currentValue_; + public Vector currentValue() { return currentValue_; } + + //! function and gradient norm values at the curentValue_ (i.e. the last step) + protected double? functionValue_, squaredNorm_; + public double functionValue() { return functionValue_.GetValueOrDefault(); } + public double gradientNormValue() { return squaredNorm_.GetValueOrDefault(); } + + //! number of evaluation of cost function and its gradient + protected int functionEvaluation_, gradientEvaluation_; + public int functionEvaluation() { return functionEvaluation_; } + public int gradientEvaluation() { return gradientEvaluation_; } + + + //! default constructor + //public Problem(CostFunction costFunction, Constraint constraint, Vector initialValue = Array()) + public Problem(CostFunction costFunction, Constraint constraint, Vector initialValue) + { + costFunction_ = costFunction; + constraint_ = constraint; + currentValue_ = initialValue.Clone(); + Utils.QL_REQUIRE(!constraint.empty(), () => "empty constraint given"); + } + + /*! \warning it does not reset the current minumum to any initial value + */ + public void reset() + { + functionEvaluation_ = gradientEvaluation_ = 0; + functionValue_ = squaredNorm_ = null; + } + + //! call cost function computation and increment evaluation counter + public double value(Vector x) + { + ++functionEvaluation_; + return costFunction_.value(x); + } + + //! call cost values computation and increment evaluation counter + public Vector values(Vector x) + { + ++functionEvaluation_; + return costFunction_.values(x); + } + + //! call cost function gradient computation and increment + // evaluation counter + public void gradient(Vector grad_f, Vector x) + { + ++gradientEvaluation_; + costFunction_.gradient(grad_f, x); + } + + //! call cost function computation and it gradient + public double valueAndGradient(Vector grad_f, Vector x) + { + ++functionEvaluation_; + ++gradientEvaluation_; + return costFunction_.valueAndGradient(grad_f, x); + } + + public void setCurrentValue(Vector currentValue) + { + currentValue_ = currentValue.Clone(); + } + + public void setFunctionValue(double functionValue) + { + functionValue_ = functionValue; + } + + public void setGradientNormValue(double squaredNorm) + { + squaredNorm_ = squaredNorm; + } + } +} diff --git a/src/QLNet/Math/Optimization/ProjectedConstraint.cs b/src/QLNet/Math/Optimization/ProjectedConstraint.cs index 76bcf3d6d..1d7809cd6 100644 --- a/src/QLNet/Math/Optimization/ProjectedConstraint.cs +++ b/src/QLNet/Math/Optimization/ProjectedConstraint.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,50 +20,50 @@ namespace QLNet { public class ProjectedConstraint : Constraint { - private class Impl : IConstraint + private class Impl : IConstraint { - public Impl( Constraint constraint, - Vector parameterValues, - ListfixParameters) + public Impl(Constraint constraint, + Vector parameterValues, + ListfixParameters) { constraint_ = constraint; projection_ = new Projection(parameterValues, fixParameters); } - public Impl( Constraint constraint, Projection projection) + public Impl(Constraint constraint, Projection projection) { constraint_ = constraint; projection_ = projection; } - - public bool test(Vector parameters) + + public bool test(Vector parameters) { return constraint_.test(projection_.include(parameters)); } - - public Vector upperBound(Vector parameters) + + public Vector upperBound(Vector parameters) { - return constraint_.upperBound(projection_.include(parameters)); + return projection_.project(constraint_.upperBound(projection_.include(parameters))); } - - public Vector lowerBound(Vector parameters) + + public Vector lowerBound(Vector parameters) { - return constraint_.lowerBound(projection_.include(parameters)); + return projection_.project(constraint_.lowerBound(projection_.include(parameters))); } - private Constraint constraint_; - private Projection projection_; + private Constraint constraint_; + private Projection projection_; } - public ProjectedConstraint( Constraint constraint, - Vector parameterValues, - List fixParameters) - : base( new Impl(constraint, parameterValues,fixParameters)) + public ProjectedConstraint(Constraint constraint, + Vector parameterValues, + List fixParameters) + : base(new Impl(constraint, parameterValues, fixParameters)) {} - public ProjectedConstraint( Constraint constraint, Projection projection) - : base(new Impl(constraint, projection)) + public ProjectedConstraint(Constraint constraint, Projection projection) + : base(new Impl(constraint, projection)) {} } diff --git a/src/QLNet/Math/Optimization/ProjectedCostFunction.cs b/src/QLNet/Math/Optimization/ProjectedCostFunction.cs index 967341d34..1b27237d1 100644 --- a/src/QLNet/Math/Optimization/ProjectedCostFunction.cs +++ b/src/QLNet/Math/Optimization/ProjectedCostFunction.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - * + * This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,86 +22,86 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! Parameterized cost function + //! Parameterized cost function // ! This class creates a proxy cost function which can depend // on any arbitrary subset of parameters (the other being fixed) -// - public class ProjectedCostFunction : CostFunction - { - private int numberOfFreeParameters_; - private Vector fixedParameters_; - private Vector actualParameters_; - private List parametersFreedoms_; - private CostFunction costFunction_; - - public ProjectedCostFunction(CostFunction costFunction, Vector parametersValues, List parametersFreedoms) - { - numberOfFreeParameters_ = 0; - fixedParameters_ = parametersValues; - actualParameters_ = parametersValues; - parametersFreedoms_ = parametersFreedoms; - costFunction_ = costFunction; - - Utils.QL_REQUIRE(fixedParameters_.Count==parametersFreedoms_.Count,()=> - "fixedParameters_.Count!=parametersFreedoms_.Count"); - - for (int i =0; i0,()=> "numberOfFreeParameters==0"); - } - - // CostFunction interface - public override double value(Vector freeParameters) - { - mapFreeParameters(freeParameters); - return costFunction_.value(actualParameters_); - } - public override Vector values(Vector freeParameters) - { - mapFreeParameters(freeParameters); - return costFunction_.values(actualParameters_); - } - - //! returns the subset of free parameters corresponding - // to set of parameters - public Vector project (Vector parameters) - { - Utils.QL_REQUIRE(parameters.Count==parametersFreedoms_.Count,()=> "parameters.Count!=parametersFreedoms_.Count"); - - Vector projectedParameters = new Vector(numberOfFreeParameters_); - int i = 0; - for (int j =0; j - "projectedParameters.Count!=numberOfFreeParameters"); - - Vector y = new Vector(fixedParameters_); - int i = 0; - for (int j =0; j - "parametersValues.Count!=numberOfFreeParameters"); - - int i = 0; - for (int j =0; j parametersFreedoms_; + private CostFunction costFunction_; + + public ProjectedCostFunction(CostFunction costFunction, Vector parametersValues, List parametersFreedoms) + { + numberOfFreeParameters_ = 0; + fixedParameters_ = parametersValues; + actualParameters_ = parametersValues; + parametersFreedoms_ = parametersFreedoms; + costFunction_ = costFunction; + + Utils.QL_REQUIRE(fixedParameters_.Count == parametersFreedoms_.Count, () => + "fixedParameters_.Count!=parametersFreedoms_.Count"); + + for (int i = 0; i < parametersFreedoms_.Count; i++) + if (!parametersFreedoms_[i]) + numberOfFreeParameters_++; + + Utils.QL_REQUIRE(numberOfFreeParameters_ > 0, () => "numberOfFreeParameters==0"); + } + + // CostFunction interface + public override double value(Vector freeParameters) + { + mapFreeParameters(freeParameters); + return costFunction_.value(actualParameters_); + } + public override Vector values(Vector freeParameters) + { + mapFreeParameters(freeParameters); + return costFunction_.values(actualParameters_); + } + + //! returns the subset of free parameters corresponding + // to set of parameters + public Vector project(Vector parameters) + { + Utils.QL_REQUIRE(parameters.Count == parametersFreedoms_.Count, () => "parameters.Count!=parametersFreedoms_.Count"); + + Vector projectedParameters = new Vector(numberOfFreeParameters_); + int i = 0; + for (int j = 0; j < parametersFreedoms_.Count; j++) + if (!parametersFreedoms_[j]) + projectedParameters[i++] = parameters[j]; + return projectedParameters; + } + + //! returns whole set of parameters corresponding to the set + // of projected parameters + public Vector include(Vector projectedParameters) + { + Utils.QL_REQUIRE(projectedParameters.Count == numberOfFreeParameters_, () => + "projectedParameters.Count!=numberOfFreeParameters"); + + Vector y = new Vector(fixedParameters_); + int i = 0; + for (int j = 0; j < y.Count; j++) + if (!parametersFreedoms_[j]) + y[j] = projectedParameters[i++]; + return y; + } + + private void mapFreeParameters(Vector parametersValues) + { + Utils.QL_REQUIRE(parametersValues.Count == numberOfFreeParameters_, () => + "parametersValues.Count!=numberOfFreeParameters"); + + int i = 0; + for (int j = 0; j < actualParameters_.Count; j++) + if (!parametersFreedoms_[j]) + actualParameters_[j] = parametersValues[i++]; + } + } } diff --git a/src/QLNet/Math/Optimization/Projection.cs b/src/QLNet/Math/Optimization/Projection.cs index dc5a3314b..872c0c2d6 100644 --- a/src/QLNet/Math/Optimization/Projection.cs +++ b/src/QLNet/Math/Optimization/Projection.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,27 +20,27 @@ namespace QLNet { public class Projection { - public Projection(Vector parameterValues,List fixParameters = null) + public Projection(Vector parameterValues, List fixParameters = null) { numberOfFreeParameters_ = 0; fixedParameters_ = parameterValues; actualParameters_ = parameterValues; fixParameters_ = fixParameters ?? new InitializedList(actualParameters_.size(), false); - Utils.QL_REQUIRE( fixedParameters_.size() == fixParameters_.Count,()=> - "fixedParameters_.size()!=parametersFreedoms_.size()" ); - for ( int i = 0; i < fixParameters_.Count; i++ ) - if ( !fixParameters_[i] ) + Utils.QL_REQUIRE(fixedParameters_.size() == fixParameters_.Count, () => + "fixedParameters_.size()!=parametersFreedoms_.size()"); + for (int i = 0; i < fixParameters_.Count; i++) + if (!fixParameters_[i]) numberOfFreeParameters_++; - Utils.QL_REQUIRE( numberOfFreeParameters_ > 0,()=> "numberOfFreeParameters==0" ); + Utils.QL_REQUIRE(numberOfFreeParameters_ > 0, () => "numberOfFreeParameters==0"); } //! returns the subset of free parameters corresponding // to set of parameters public virtual Vector project(Vector parameters) { - Utils.QL_REQUIRE(parameters.size() == fixParameters_.Count,()=> "parameters.size()!=parametersFreedoms_.size()"); + Utils.QL_REQUIRE(parameters.size() == fixParameters_.Count, () => "parameters.size()!=parametersFreedoms_.size()"); Vector projectedParameters = new Vector(numberOfFreeParameters_); int i = 0; for (int j = 0; j < fixParameters_.Count; j++) @@ -53,23 +53,23 @@ public virtual Vector project(Vector parameters) // of projected parameters public virtual Vector include(Vector projectedParameters) { - Utils.QL_REQUIRE(projectedParameters.size() == numberOfFreeParameters_,()=> - "projectedParameters.size()!=numberOfFreeParameters"); + Utils.QL_REQUIRE(projectedParameters.size() == numberOfFreeParameters_, () => + "projectedParameters.size()!=numberOfFreeParameters"); Vector y = new Vector(fixedParameters_); int i = 0; for (int j = 0; j < y.size(); j++) if (!fixParameters_[j]) - y[j] = projectedParameters[i++]; + y[j] = projectedParameters[i++]; return y; } protected void mapFreeParameters(Vector parameterValues) { - Utils.QL_REQUIRE( parameterValues.size() == numberOfFreeParameters_,()=> - "parameterValues.size()!=numberOfFreeParameters" ); + Utils.QL_REQUIRE(parameterValues.size() == numberOfFreeParameters_, () => + "parameterValues.size()!=numberOfFreeParameters"); int i = 0; - for ( int j = 0; j < actualParameters_.size(); j++ ) - if ( !fixParameters_[j] ) + for (int j = 0; j < actualParameters_.size(); j++) + if (!fixParameters_[j]) actualParameters_[j] = parameterValues[i++]; } protected int numberOfFreeParameters_; diff --git a/src/QLNet/Math/Optimization/Simplex.cs b/src/QLNet/Math/Optimization/Simplex.cs index c80b9a2fe..3554356c7 100644 --- a/src/QLNet/Math/Optimization/Simplex.cs +++ b/src/QLNet/Math/Optimization/Simplex.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - * + * This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,186 +21,190 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public static partial class Utils { - // Computes the size of the simplex - public static double computeSimplexSize(List vertices) - { - Vector center = new Vector(vertices[0].Count, 0); - for (int i = 0; i < vertices.Count; ++i) - center += vertices[i]; - center *= 1 / (double)(vertices.Count); - double result = 0; - for (int i = 0; i < vertices.Count; ++i) - { - Vector temp = vertices[i] - center; - result += Math.Sqrt(Vector.DotProduct(temp, temp)); - } - return result / (double)(vertices.Count); - } + public static partial class Utils + { + // Computes the size of the simplex + public static double computeSimplexSize(List vertices) + { + Vector center = new Vector(vertices[0].Count, 0); + for (int i = 0; i < vertices.Count; ++i) + center += vertices[i]; + center *= 1 / (double)(vertices.Count); + double result = 0; + for (int i = 0; i < vertices.Count; ++i) + { + Vector temp = vertices[i] - center; + result += Vector.Norm2(temp); + } + return result / (double)(vertices.Count); + } - } + } - //! Multi-dimensional simplex class - public class Simplex : OptimizationMethod - { - //! Constructor taking as input the characteristic length - public Simplex(double lambda) - { - lambda_ = lambda; - } - public override EndCriteria.Type minimize( Problem P, EndCriteria endCriteria ) - { - // set up of the problem - //double ftol = endCriteria.functionEpsilon(); // end criteria on f(x) (see Numerical Recipes in C++, p.410) - double xtol = endCriteria.rootEpsilon(); // end criteria on x (see GSL v. 1.9, http://www.gnu.org/software/gsl/) - int maxStationaryStateIterations_ = endCriteria.maxStationaryStateIterations(); - EndCriteria.Type ecType = EndCriteria.Type.None; - P.reset(); - Vector x_ = P.currentValue(); - int iterationNumber_ = 0; + //! Multi-dimensional simplex class + public class Simplex : OptimizationMethod + { + //! Constructor taking as input the characteristic length + public Simplex(double lambda) + { + lambda_ = lambda; + } + public override EndCriteria.Type minimize(Problem P, EndCriteria endCriteria) + { + // set up of the problem + //double ftol = endCriteria.functionEpsilon(); // end criteria on f(x) (see Numerical Recipes in C++, p.410) + double xtol = endCriteria.rootEpsilon(); // end criteria on x (see GSL v. 1.9, http://www.gnu.org/software/gsl/) + int maxStationaryStateIterations_ = endCriteria.maxStationaryStateIterations(); + EndCriteria.Type ecType = EndCriteria.Type.None; + P.reset(); + Vector x_ = P.currentValue(); + int iterationNumber_ = 0; - // Initialize vertices of the simplex - bool end = false; - int n = x_.Count; - vertices_ = new InitializedList( n + 1, x_ ); - for ( int i = 0; i < n; i++ ) - { - Vector direction = new Vector( n, 0.0 ); - Vector vertice = vertices_[i + 1]; - direction[i] = 1.0; - P.constraint().update( ref vertice, direction, lambda_ ); - vertices_[i + 1] = vertice; - } - // Initialize function values at the vertices of the simplex - values_ = new Vector( n + 1, 0.0 ); - for ( int i = 0; i <= n; i++ ) - values_[i] = P.value( vertices_[i] ); - // Loop looking for minimum - do - { - sum_ = new Vector( n, 0.0 ); - for ( int i = 0; i <= n; i++ ) - sum_ += vertices_[i]; - // Determine the best (iLowest), worst (iHighest) - // and 2nd worst (iNextHighest) vertices - int iLowest = 0; - int iHighest; - int iNextHighest; - if ( values_[0] < values_[1] ) - { - iHighest = 1; - iNextHighest = 0; - } - else - { - iHighest = 0; - iNextHighest = 1; - } - for ( int i = 1; i <= n; i++ ) - { - if ( values_[i] > values_[iHighest] ) - { - iNextHighest = iHighest; - iHighest = i; - } - else - { - if ( ( values_[i] > values_[iNextHighest] ) && i != iHighest ) - iNextHighest = i; - } - if ( values_[i] < values_[iLowest] ) - iLowest = i; - } - // Now compute accuracy, update iteration number and check end criteria - // GSL exit strategy on x (see GSL v. 1.9, http://www.gnu.org/software/gsl - double simplexSize = Utils.computeSimplexSize( vertices_ ); - ++iterationNumber_; - if ( simplexSize < xtol || endCriteria.checkMaxIterations( iterationNumber_, ref ecType ) ) - { - endCriteria.checkStationaryPoint( 0.0, 0.0, ref maxStationaryStateIterations_, ref ecType ); - endCriteria.checkMaxIterations( iterationNumber_, ref ecType ); - x_ = vertices_[iLowest]; - double low = values_[iLowest]; - P.setFunctionValue( low ); - P.setCurrentValue( x_ ); - return ecType; - } - // If end criteria is not met, continue - double factor = -1.0; - double vTry = extrapolate( ref P, iHighest, ref factor ); - if ( ( vTry <= values_[iLowest] ) && ( factor.IsEqual(-1.0) ) ) - { - factor = 2.0; - extrapolate( ref P, iHighest, ref factor ); - } - else if ( Math.Abs( factor ) > Const.QL_EPSILON ) - { - if ( vTry >= values_[iNextHighest] ) - { - double vSave = values_[iHighest]; - factor = 0.5; - vTry = extrapolate( ref P, iHighest, ref factor ); - if ( vTry >= vSave && Math.Abs( factor ) > Const.QL_EPSILON ) - { - for ( int i = 0; i <= n; i++ ) - { - if ( i != iLowest ) - { + // Initialize vertices of the simplex + bool end = false; + int n = x_.Count; + vertices_ = new InitializedList(n + 1, x_); + for (int i = 0; i < n; i++) + { + Vector direction = new Vector(n, 0.0); + Vector vertice = vertices_[i + 1]; + direction[i] = 1.0; + P.constraint().update(ref vertice, direction, lambda_); + vertices_[i + 1] = vertice; + } + // Initialize function values at the vertices of the simplex + values_ = new Vector(n + 1, 0.0); + for (int i = 0; i <= n; i++) + values_[i] = P.value(vertices_[i]); + // Loop looking for minimum + do + { + sum_ = new Vector(n, 0.0); + for (int i = 0; i <= n; i++) + sum_ += vertices_[i]; + // Determine the best (iLowest), worst (iHighest) + // and 2nd worst (iNextHighest) vertices + int iLowest = 0; + int iHighest; + int iNextHighest; + if (values_[0] < values_[1]) + { + iHighest = 1; + iNextHighest = 0; + } + else + { + iHighest = 0; + iNextHighest = 1; + } + for (int i = 1; i <= n; i++) + { + if (values_[i] > values_[iHighest]) + { + iNextHighest = iHighest; + iHighest = i; + } + else + { + if ((values_[i] > values_[iNextHighest]) && i != iHighest) + iNextHighest = i; + } + if (values_[i] < values_[iLowest]) + iLowest = i; + } + // Now compute accuracy, update iteration number and check end criteria + // GSL exit strategy on x (see GSL v. 1.9, http://www.gnu.org/software/gsl + double simplexSize = Utils.computeSimplexSize(vertices_); + ++iterationNumber_; + if (simplexSize < xtol || endCriteria.checkMaxIterations(iterationNumber_, ref ecType)) + { + endCriteria.checkStationaryPoint(0.0, 0.0, ref maxStationaryStateIterations_, ref ecType); + endCriteria.checkMaxIterations(iterationNumber_, ref ecType); + x_ = vertices_[iLowest]; + double low = values_[iLowest]; + P.setFunctionValue(low); + P.setCurrentValue(x_); + return ecType; + } + // If end criteria is not met, continue + double factor = -1.0; + double vTry = extrapolate(ref P, iHighest, ref factor); + if ((vTry <= values_[iLowest]) && (factor.IsEqual(-1.0))) + { + factor = 2.0; + extrapolate(ref P, iHighest, ref factor); + } + else if (Math.Abs(factor) > Const.QL_EPSILON) + { + if (vTry >= values_[iNextHighest]) + { + double vSave = values_[iHighest]; + factor = 0.5; + vTry = extrapolate(ref P, iHighest, ref factor); + if (vTry >= vSave && Math.Abs(factor) > Const.QL_EPSILON) + { + for (int i = 0; i <= n; i++) + { + if (i != iLowest) + { #if QL_ARRAY_EXPRESSIONS - vertices_[i] = 0.5 * (vertices_[i] + vertices_[iLowest]); + vertices_[i] = 0.5 * (vertices_[i] + vertices_[iLowest]); #else - vertices_[i] += vertices_[iLowest]; - vertices_[i] *= 0.5; + vertices_[i] += vertices_[iLowest]; + vertices_[i] *= 0.5; #endif - values_[i] = P.value( vertices_[i] ); - } - } - } - } - } - // If can't extrapolate given the constraints, exit - if ( Math.Abs( factor ) <= Const.QL_EPSILON ) - { - x_ = vertices_[iLowest]; - double low = values_[iLowest]; - P.setFunctionValue( low ); - P.setCurrentValue( x_ ); - return EndCriteria.Type.StationaryFunctionValue; - } - } while ( end == false ); - Utils.QL_FAIL( "optimization failed: unexpected behaviour" ); - return 0; - } - - private double extrapolate(ref Problem P, int iHighest, ref double factor) - { - - Vector pTry; - do - { - int dimensions = values_.Count - 1; - double factor1 = (1.0 - factor) / dimensions; - double factor2 = factor1 - factor; - pTry = sum_ * factor1 - vertices_[iHighest] * factor2; - factor *= 0.5; - } while (!P.constraint().test(pTry) && Math.Abs(factor) > Const.QL_EPSILON); - if (Math.Abs(factor) <= Const.QL_EPSILON) { - return values_[iHighest]; + values_[i] = P.value(vertices_[i]); + } + } + } + } } - factor *= 2.0; - double vTry = P.value(pTry); - if (vTry < values_[iHighest]) + // If can't extrapolate given the constraints, exit + if (Math.Abs(factor) <= Const.QL_EPSILON) { - values_[iHighest] = vTry; - sum_ += pTry - vertices_[iHighest]; - vertices_[iHighest] = pTry; + x_ = vertices_[iLowest]; + double low = values_[iLowest]; + P.setFunctionValue(low); + P.setCurrentValue(x_); + return EndCriteria.Type.StationaryFunctionValue; } - return vTry; + } + while (end == false); + Utils.QL_FAIL("optimization failed: unexpected behaviour"); + return 0; + } + + private double extrapolate(ref Problem P, int iHighest, ref double factor) + { + + Vector pTry; + do + { + int dimensions = values_.Count - 1; + double factor1 = (1.0 - factor) / dimensions; + double factor2 = factor1 - factor; + pTry = sum_ * factor1 - vertices_[iHighest] * factor2; + factor *= 0.5; + } + while (!P.constraint().test(pTry) && Math.Abs(factor) > Const.QL_EPSILON); + if (Math.Abs(factor) <= Const.QL_EPSILON) + { + return values_[iHighest]; + } + factor *= 2.0; + double vTry = P.value(pTry); + if (vTry < values_[iHighest]) + { + values_[iHighest] = vTry; + sum_ += pTry - vertices_[iHighest]; + vertices_[iHighest] = pTry; + } + return vTry; - } - private double lambda_; - private List vertices_; - private Vector values_; - private Vector sum_; - } + } + private double lambda_; + private List vertices_; + private Vector values_; + private Vector sum_; + } } \ No newline at end of file diff --git a/src/QLNet/Math/Optimization/SimulatedAnnealing.cs b/src/QLNet/Math/Optimization/SimulatedAnnealing.cs new file mode 100644 index 000000000..ca0d4823b --- /dev/null +++ b/src/QLNet/Math/Optimization/SimulatedAnnealing.cs @@ -0,0 +1,314 @@ +/* + Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QLNet +{ + /// + /// Class RNG must implement the following interface: + /// RNG.sample_type RNG.next(); + /// + /// + public class SimulatedAnnealing : OptimizationMethod where RNG : class, IRNGTraits, new () + { + public enum Scheme + { + ConstantFactor, + ConstantBudget + } + + /// + /// reduce temperature T by a factor of (1-\epsilon) after m moves + /// + /// + /// + /// + /// + /// + public SimulatedAnnealing(double lambda, double T0, double epsilon, int m, RNG rng = default(RNG)) + { + scheme_ = Scheme.ConstantFactor; + lambda_ = lambda; + T0_ = T0; + epsilon_ = epsilon; + alpha_ = 0.0; + K_ = 0; + rng_ = rng; + m_ = m; + } + + /// + /// budget a total of K moves, set temperature T to the initial + /// temperature times \f$ ( 1 - k/K )^\alpha \f$ with k being the total number + /// of moves so far. After K moves the temperature is guaranteed to be + /// zero, after that the optimization runs like a deterministic simplex + /// algorithm. + /// + /// + /// + /// + /// + /// + public SimulatedAnnealing(double lambda, double T0, int K, double alpha, RNG rng = default(RNG)) + { + scheme_ = Scheme.ConstantBudget; + lambda_ = lambda; + T0_ = T0; + epsilon_ = 0.0; + alpha_ = alpha; + K_ = K; + rng_ = rng; + } + + public override EndCriteria.Type minimize(Problem P, EndCriteria endCriteria) + { + int stationaryStateIterations_ = 0; + EndCriteria.Type ecType = EndCriteria.Type.None; + P.reset(); + Vector x = P.currentValue(); + iteration_ = 0; + n_ = x.size(); + ptry_ = new Vector(n_, 0.0); + + // build vertices + + vertices_ = new InitializedList(n_ + 1, x); + for (i_ = 0; i_ < n_; i_++) + { + Vector direction = new Vector(n_, 0.0); + direction[i_] = 1.0; + Vector tmp = vertices_[i_ + 1]; + P.constraint().update(ref tmp, direction, lambda_); + vertices_[i_ + 1] = tmp; + } + + values_ = new Vector(n_ + 1, 0.0); + for (i_ = 0; i_ <= n_; i_++) + { + if (!P.constraint().test(vertices_[i_])) + values_[i_] = Double.MaxValue; + else + values_[i_] = P.value(vertices_[i_]); + if (Double.IsNaN(ytry_)) + { + // handle NAN + values_[i_] = Double.MaxValue; + } + } + + // minimize + + T_ = T0_; + yb_ = Double.MaxValue; + pb_ = new Vector(n_, 0.0); + do + { + iterationT_ = iteration_; + do + { + sum_ = new Vector(n_, 0.0); + for (i_ = 0; i_ <= n_; i_++) + sum_ += vertices_[i_]; + tt_ = -T_; + ilo_ = 0; + ihi_ = 1; + ynhi_ = values_[0] + tt_ * Math.Log(rng_.next().value); + ylo_ = ynhi_; + yhi_ = values_[1] + tt_ * Math.Log(rng_.next().value); + if (ylo_ > yhi_) + { + ihi_ = 0; + ilo_ = 1; + ynhi_ = yhi_; + yhi_ = ylo_; + ylo_ = ynhi_; + } + + for (i_ = 2; i_ < n_ + 1; i_++) + { + yt_ = values_[i_] + tt_ * Math.Log(rng_.next().value); + if (yt_ <= ylo_) + { + ilo_ = i_; + ylo_ = yt_; + } + + if (yt_ > yhi_) + { + ynhi_ = yhi_; + ihi_ = i_; + yhi_ = yt_; + } + else + { + if (yt_ > ynhi_) + { + ynhi_ = yt_; + } + } + } + + // GSL end criterion in x (cf. above) + if (endCriteria.checkStationaryPoint(simplexSize(), 0.0, + ref stationaryStateIterations_, + ref ecType) || + endCriteria.checkMaxIterations(iteration_, ref ecType)) + { + // no matter what, we return the best ever point ! + P.setCurrentValue(pb_); + P.setFunctionValue(yb_); + return ecType; + } + + iteration_ += 2; + amotsa(P, -1.0); + if (ytry_ <= ylo_) + { + amotsa(P, 2.0); + } + else + { + if (ytry_ >= ynhi_) + { + ysave_ = yhi_; + amotsa(P, 0.5); + if (ytry_ >= ysave_) + { + for (i_ = 0; i_ < n_ + 1; i_++) + { + if (i_ != ilo_) + { + for (j_ = 0; j_ < n_; j_++) + { + sum_[j_] = 0.5 * (vertices_[i_][j_] + + vertices_[ilo_][j_]); + vertices_[i_][j_] = sum_[j_]; + } + + values_[i_] = P.value(sum_); + } + } + + iteration_ += n_; + for (i_ = 0; i_ < n_; i_++) + sum_[i_] = 0.0; + for (i_ = 0; i_ <= n_; i_++) + sum_ += vertices_[i_]; + } + } + else + { + iteration_ += 1; + } + } + } + while (iteration_ < + iterationT_ + (scheme_ == Scheme.ConstantFactor ? m_ : 1)); + + switch (scheme_) + { + case Scheme.ConstantFactor: + T_ *= (1.0 - epsilon_); + break; + case Scheme.ConstantBudget: + if (iteration_ <= K_) + T_ = T0_ * + Math.Pow(1.0 - Convert.ToDouble(iteration_) / Convert.ToDouble(K_), alpha_); + else + T_ = 0.0; + break; + } + } + while (true); + } + + protected Scheme scheme_; + protected double lambda_, T0_, epsilon_, alpha_; + protected int K_; + protected RNG rng_; + + protected double simplexSize() + { + Vector center = new Vector(vertices_.First().size(), 0); + for (int i = 0; i < vertices_.Count; ++i) + center += vertices_[i]; + + center *= 1 / Convert.ToDouble(vertices_.Count); + double result = 0; + for (int i = 0; i < vertices_.Count; ++i) + { + Vector temp = vertices_[i] - center; + result += Vector.Norm2(temp); + } + + return result / Convert.ToDouble(vertices_.Count); + } + + protected void amotsa(Problem P, double fac) + { + fac1_ = (1.0 - fac) / Convert.ToDouble(n_); + fac2_ = fac1_ - fac; + for (j_ = 0; j_ < n_; j_++) + { + ptry_[j_] = sum_[j_] * fac1_ - vertices_[ihi_][j_] * fac2_; + } + + if (!P.constraint().test(ptry_)) + ytry_ = Double.MaxValue; + else + ytry_ = P.value(ptry_); + if (Double.IsNaN(ytry_)) + { + ytry_ = Double.MaxValue; + } + + if (ytry_ <= yb_) + { + yb_ = ytry_; + pb_ = ptry_; + } + + yflu_ = ytry_ - tt_ * Math.Log(rng_.next().value); + if (yflu_ < yhi_) + { + values_[ihi_] = ytry_; + yhi_ = yflu_; + for (j_ = 0; j_ < n_; j_++) + { + sum_[j_] += ptry_[j_] - vertices_[ihi_][j_]; + vertices_[ihi_][j_] = ptry_[j_]; + } + } + + ytry_ = yflu_; + } + + protected double T_; + protected List vertices_; + protected Vector values_, sum_; + protected int i_, ihi_, ilo_, j_, m_, n_; + protected double fac1_, fac2_, yflu_; + protected double rtol_, swap_, yhi_, ylo_, ynhi_, ysave_, yt_, ytry_, yb_, tt_; + protected Vector pb_, ptry_; + protected int iteration_, iterationT_; + } +} diff --git a/src/QLNet/Math/Optimization/SteepestDescent.cs b/src/QLNet/Math/Optimization/SteepestDescent.cs index 38cce567c..1763d6c01 100644 --- a/src/QLNet/Math/Optimization/SteepestDescent.cs +++ b/src/QLNet/Math/Optimization/SteepestDescent.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,16 +24,16 @@ namespace QLNet /*! User has to provide line-search method and optimization end criteria search direction \f$ = - f'(x) \f$ - */ + */ public class SteepestDescent : LineSearchBasedMethod { public SteepestDescent(LineSearch lineSearch = null) : base(lineSearch) {} - protected override Vector getUpdatedDirection( Problem P, double gold2, Vector gradient ) + protected override Vector getUpdatedDirection(Problem P, double gold2, Vector gradient) { - return lineSearch_.lastGradient()*-1; + return lineSearch_.lastGradient() * -1; } } } \ No newline at end of file diff --git a/src/QLNet/Math/Optimization/lmdif.cs b/src/QLNet/Math/Optimization/lmdif.cs deleted file mode 100644 index 3ca7c1bbf..000000000 --- a/src/QLNet/Math/Optimization/lmdif.cs +++ /dev/null @@ -1,1514 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -/* -The original Fortran version is Copyright (C) 1999 University of Chicago. -All rights reserved. - -Redistribution and use in source and binary forms, with or -without modification, are permitted provided that the -following conditions are met: - -1. Redistributions of source code must retain the above -copyright notice, this list of conditions and the following -disclaimer. - -2. Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following -disclaimer in the documentation and/or other materials -provided with the distribution. - -3. The end-user documentation included with the -redistribution, if any, must include the following -acknowledgment: - - "This product includes software developed by the - University of Chicago, as Operator of Argonne National - Laboratory. - -Alternately, this acknowledgment may appear in the software -itself, if and wherever such third-party acknowledgments -normally appear. - -4. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" -WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE -UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND -THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE -OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY -OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR -USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF -THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) -DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION -UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL -BE CORRECTED. - -5. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT -HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF -ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, -INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF -ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF -PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER -SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT -(INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, -EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE -POSSIBILITY OF SUCH LOSS OR DAMAGES. - - -C translation Copyright (C) Steve Moshier - -What you see here may be used freely but it comes with no support -or guarantee. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet { - public static class MINPACK { - /* resolution of arithmetic */ - const double MACHEP = 1.2e-16; - /* smallest nonzero number */ - const double DWARF = 1.0e-38; - - /* - * ********** - * - * subroutine lmdif - * - * the purpose of lmdif is to minimize the sum of the squares of - * m nonlinear functions in n variables by a modification of - * the levenberg-marquardt algorithm. the user must provide a - * subroutine which calculates the functions. the jacobian is - * then calculated by a forward-difference approximation. - * - * the subroutine statement is - * - * subroutine lmdif(fcn,m,n,x,fvec,ftol,xtol,gtol,maxfev,epsfcn, - * diag,mode,factor,nprint,info,nfev,fjac, - * ldfjac,ipvt,qtf,wa1,wa2,wa3,wa4) - * - * where - * - * fcn is the name of the user-supplied subroutine which - * calculates the functions. fcn must be declared - * in an external statement in the user calling - * program, and should be written as follows. - * - * subroutine fcn(m,n,x,fvec,iflag) - * integer m,n,iflag - * double precision x(n),fvec(m) - * ---------- - * calculate the functions at x and - * return this vector in fvec. - * ---------- - * return - * end - * - * the value of iflag should not be changed by fcn unless - * the user wants to terminate execution of lmdif. - * in this case set iflag to a negative integer. - * - * m is a positive integer input variable set to the number - * of functions. - * - * n is a positive integer input variable set to the number - * of variables. n must not exceed m. - * - * x is an array of length n. on input x must contain - * an initial estimate of the solution vector. on output x - * contains the final estimate of the solution vector. - * - * fvec is an output array of length m which contains - * the functions evaluated at the output x. - * - * ftol is a nonnegative input variable. termination - * occurs when both the actual and predicted relative - * reductions in the sum of squares are at most ftol. - * therefore, ftol measures the relative error desired - * in the sum of squares. - * - * xtol is a nonnegative input variable. termination - * occurs when the relative error between two consecutive - * iterates is at most xtol. therefore, xtol measures the - * relative error desired in the approximate solution. - * - * gtol is a nonnegative input variable. termination - * occurs when the cosine of the angle between fvec and - * any column of the jacobian is at most gtol in absolute - * value. therefore, gtol measures the orthogonality - * desired between the function vector and the columns - * of the jacobian. - * - * maxfev is a positive integer input variable. termination - * occurs when the number of calls to fcn is at least - * maxfev by the end of an iteration. - * - * epsfcn is an input variable used in determining a suitable - * step length for the forward-difference approximation. this - * approximation assumes that the relative errors in the - * functions are of the order of epsfcn. if epsfcn is less - * than the machine precision, it is assumed that the relative - * errors in the functions are of the order of the machine - * precision. - * - * diag is an array of length n. if mode = 1 (see - * below), diag is internally set. if mode = 2, diag - * must contain positive entries that serve as - * multiplicative scale factors for the variables. - * - * mode is an integer input variable. if mode = 1, the - * variables will be scaled internally. if mode = 2, - * the scaling is specified by the input diag. other - * values of mode are equivalent to mode = 1. - * - * factor is a positive input variable used in determining the - * initial step bound. this bound is set to the product of - * factor and the euclidean norm of diag*x if nonzero, or else - * to factor itself. in most cases factor should lie in the - * interval (.1,100.). 100. is a generally recommended value. - * - * nprint is an integer input variable that enables controlled - * printing of iterates if it is positive. in this case, - * fcn is called with iflag = 0 at the beginning of the first - * iteration and every nprint iterations thereafter and - * immediately prior to return, with x and fvec available - * for printing. if nprint is not positive, no special calls - * of fcn with iflag = 0 are made. - * - * info is an integer output variable. if the user has - * terminated execution, info is set to the (negative) - * value of iflag. see description of fcn. otherwise, - * info is set as follows. - * - * info = 0 improper input parameters. - * - * info = 1 both actual and predicted relative reductions - * in the sum of squares are at most ftol. - * - * info = 2 relative error between two consecutive iterates - * is at most xtol. - * - * info = 3 conditions for info = 1 and info = 2 both hold. - * - * info = 4 the cosine of the angle between fvec and any - * column of the jacobian is at most gtol in - * absolute value. - * - * info = 5 number of calls to fcn has reached or - * exceeded maxfev. - * - * info = 6 ftol is too small. no further reduction in - * the sum of squares is possible. - * - * info = 7 xtol is too small. no further improvement in - * the approximate solution x is possible. - * - * info = 8 gtol is too small. fvec is orthogonal to the - * columns of the jacobian to machine precision. - * - * nfev is an integer output variable set to the number of - * calls to fcn. - * - * fjac is an output m by n array. the upper n by n submatrix - * of fjac contains an upper triangular matrix r with - * diagonal elements of nonincreasing magnitude such that - * - * t t t - * p *(jac *jac)*p = r *r, - * - * where p is a permutation matrix and jac is the final - * calculated jacobian. column j of p is column ipvt(j) - * (see below) of the identity matrix. the lower trapezoidal - * part of fjac contains information generated during - * the computation of r. - * - * ldfjac is a positive integer input variable not less than m - * which specifies the leading dimension of the array fjac. - * - * ipvt is an integer output array of length n. ipvt - * defines a permutation matrix p such that jac*p = q*r, - * where jac is the final calculated jacobian, q is - * orthogonal (not stored), and r is upper triangular - * with diagonal elements of nonincreasing magnitude. - * column j of p is column ipvt(j) of the identity matrix. - * - * qtf is an output array of length n which contains - * the first n elements of the vector (q transpose)*fvec. - * - * wa1, wa2, and wa3 are work arrays of length n. - * - * wa4 is a work array of length m. - * - * subprograms called - * - * user-supplied ...... fcn, jacFcn - * - * minpack-supplied ... dpmpar,enorm,fdjac2,lmpar,qrfac - * - * argonne national laboratory. minpack project. march 1980. - * burton s. garbow, kenneth e. hillstrom, jorge j. more - * - * ********** - */ - public static void lmdif(int m, int n, Vector x, ref Vector fvec, double ftol, - double xtol, double gtol, int maxfev, double epsfcn, - Vector diag, int mode, double factor, - int nprint, ref int info, ref int nfev, ref Matrix fjac, - int ldfjac, ref List ipvt, ref Vector qtf, - Vector wa1, Vector wa2, Vector wa3, Vector wa4, - Func fcn, - Func jacFcn ) { - - int i, iflag, ij, jj, iter, j, l; - double actred, delta = 0, dirder, fnorm, fnorm1, gnorm; - double par, pnorm, prered, ratio; - double sum, temp, temp1, temp2, temp3, xnorm = 0; - - const double one = 1.0; - const double p1 = 0.1; - const double p5 = 0.5; - const double p25 = 0.25; - const double p75 = 0.75; - const double p0001 = 1.0e-4; - const double zero = 0.0; - - info = 0; - iflag = 0; - nfev = 0; - - /* - * check the input parameters for errors. - */ - if ((n <= 0) || (m < n) || (ldfjac < m) || (ftol < zero) - || (xtol < zero) || (gtol < zero) || (maxfev <= 0) - || (factor <= zero)) - goto L300; - - if (mode == 2) { /* scaling by diag[] */ - for (j = 0; j < n; j++) { - if (diag[j] <= 0.0) - goto L300; - } - } - /* - * evaluate the function at the starting point - * and calculate its norm. - */ - iflag = 1; - fvec = fcn(m, n, x, iflag); - nfev = 1; - if (iflag < 0) - goto L300; - fnorm = enorm(m, fvec); - /* - * initialize levenberg-marquardt parameter and iteration counter. - */ - par = zero; - iter = 1; - /* - * beginning of the outer loop. - */ - - L30: - - /* - * calculate the jacobian matrix. - */ - iflag = 2; - if ( jacFcn != null ) // use user supplied jacobian calculation - jacFcn( m, n, x, iflag ); - else - fdjac2( m, n, x, fvec, fjac, ldfjac, iflag, epsfcn, ref wa4, fcn ); - nfev += n; - if (iflag < 0) - goto L300; - /* - * if requested, call fcn to enable printing of iterates. - */ - if (nprint > 0) { - iflag = 0; - if (mod(iter - 1, nprint) == 0) { - fvec = fcn(m, n, x, iflag); - if (iflag < 0) - goto L300; - } - } - /* - * compute the qr factorization of the jacobian. - */ - qrfac(m, n, fjac, ldfjac, 1, ref ipvt, n, ref wa1, ref wa2, wa3); - /* - * on the first iteration and if mode is 1, scale according - * to the norms of the columns of the initial jacobian. - */ - if (iter == 1) { - if (mode != 2) { - for (j = 0; j < n; j++) { - diag[j] = wa2[j]; - if (wa2[j].IsEqual(zero)) - diag[j] = one; - } - } - - /* - * on the first iteration, calculate the norm of the scaled x - * and initialize the step bound delta. - */ - for (j = 0; j < n; j++) - wa3[j] = diag[j] * x[j]; - - xnorm = enorm(n, wa3); - delta = factor * xnorm; - if (delta.IsEqual(zero)) - delta = factor; - } - - /* - * form (q transpose)*fvec and store the first n components in - * qtf. - */ - for (i = 0; i < m; i++) - wa4[i] = fvec[i]; - jj = 0; - for (j = 0; j < n; j++) { - temp3 = fjac[jj]; - if (temp3.IsNotEqual(zero)) { - sum = zero; - ij = jj; - for (i = j; i < m; i++) { - sum += fjac[ij] * wa4[i]; - ij += 1; /* fjac[i+m*j] */ - } - temp = -sum / temp3; - ij = jj; - for (i = j; i < m; i++) { - wa4[i] += fjac[ij] * temp; - ij += 1; /* fjac[i+m*j] */ - } - } - fjac[jj] = wa1[j]; - jj += m + 1; /* fjac[j+m*j] */ - qtf[j] = wa4[j]; - } - - /* - * compute the norm of the scaled gradient. - */ - gnorm = zero; - if (fnorm.IsNotEqual(zero)) { - jj = 0; - for (j = 0; j < n; j++) { - l = ipvt[j]; - if (wa2[l].IsNotEqual(zero)) { - sum = zero; - ij = jj; - for (i = 0; i <= j; i++) { - sum += fjac[ij] * (qtf[i] / fnorm); - ij += 1; /* fjac[i+m*j] */ - } - gnorm = dmax1(gnorm, Math.Abs(sum / wa2[l])); - } - jj += m; - } - } - - /* - * test for convergence of the gradient norm. - */ - if (gnorm <= gtol) - info = 4; - if (info != 0) - goto L300; - /* - * rescale if necessary. - */ - if (mode != 2) { - for (j = 0; j < n; j++) - diag[j] = dmax1(diag[j], wa2[j]); - } - - /* - * beginning of the inner loop. - */ - L200: - /* - * determine the levenberg-marquardt parameter. - */ - lmpar(n, fjac, ldfjac, ipvt, diag, qtf, delta, par, wa1, wa2, wa3, wa4); - /* - * store the direction p and x + p. calculate the norm of p. - */ - for (j = 0; j < n; j++) { - wa1[j] = -wa1[j]; - wa2[j] = x[j] + wa1[j]; - wa3[j] = diag[j] * wa1[j]; - } - pnorm = enorm(n, wa3); - /* - * on the first iteration, adjust the initial step bound. - */ - if (iter == 1) - delta = dmin1(delta, pnorm); - /* - * evaluate the function at x + p and calculate its norm. - */ - iflag = 1; - wa4 = fcn(m, n, wa2, iflag); - nfev += 1; - if (iflag < 0) - goto L300; - fnorm1 = enorm(m, wa4); - - /* - * compute the scaled actual reduction. - */ - actred = -one; - if ((p1 * fnorm1) < fnorm) { - temp = fnorm1 / fnorm; - actred = one - temp * temp; - } - /* - * compute the scaled predicted reduction and - * the scaled directional derivative. - */ - jj = 0; - for (j = 0; j < n; j++) { - wa3[j] = zero; - l = ipvt[j]; - temp = wa1[l]; - ij = jj; - for (i = 0; i <= j; i++) { - wa3[i] += fjac[ij] * temp; - ij += 1; /* fjac[i+m*j] */ - } - jj += m; - } - temp1 = enorm(n, wa3) / fnorm; - temp2 = (Math.Sqrt(par) * pnorm) / fnorm; - prered = temp1 * temp1 + (temp2 * temp2) / p5; - dirder = -(temp1 * temp1 + temp2 * temp2); - /* - * compute the ratio of the actual to the predicted - * reduction. - */ - ratio = zero; - if (prered.IsNotEqual(zero)) - ratio = actred / prered; - /* - * update the step bound. - */ - if (ratio <= p25) { - if (actred >= zero) - temp = p5; - else - temp = p5 * dirder / (dirder + p5 * actred); - if (((p1 * fnorm1) >= fnorm) - || (temp < p1)) - temp = p1; - delta = temp * dmin1(delta, pnorm / p1); - par = par / temp; - } else { - if ((par.IsEqual(zero)) || (ratio >= p75)) { - delta = pnorm / p5; - par = p5 * par; - } - } - /* - * test for successful iteration. - */ - if (ratio >= p0001) { - /* - * successful iteration. update x, fvec, and their norms. - */ - for (j = 0; j < n; j++) { - x[j] = wa2[j]; - wa2[j] = diag[j] * x[j]; - } - for (i = 0; i < m; i++) - fvec[i] = wa4[i]; - xnorm = enorm(n, wa2); - fnorm = fnorm1; - iter += 1; - } - /* - * tests for convergence. - */ - if ((Math.Abs(actred) <= ftol) - && (prered <= ftol) - && (p5 * ratio <= one)) - info = 1; - if (delta <= xtol * xnorm) - info = 2; - if ((Math.Abs(actred) <= ftol) - && (prered <= ftol) - && (p5 * ratio <= one) - && (info == 2)) - info = 3; - if (info != 0) - goto L300; - /* - * tests for termination and stringent tolerances. - */ - if (nfev >= maxfev) - info = 5; - if ((Math.Abs(actred) <= MACHEP) - && (prered <= MACHEP) - && (p5 * ratio <= one)) - info = 6; - if (delta <= MACHEP * xnorm) - info = 7; - if (gnorm <= MACHEP) - info = 8; - if (info != 0) - goto L300; - /* - * end of the inner loop. repeat if iteration unsuccessful. - */ - if (ratio < p0001) - goto L200; - /* - * end of the outer loop. - */ - goto L30; - - L300: - /* - * termination, either normal or user imposed. - */ - if (iflag < 0) - info = iflag; - iflag = 0; - if (nprint > 0) - fvec = fcn(m, n, x, iflag); - } - - /* - * ********** - * - * function enorm - * - * given an n-vector x, this function calculates the - * euclidean norm of x. - * - * the euclidean norm is computed by accumulating the sum of - * squares in three different sums. the sums of squares for the - * small and large components are scaled so that no overflows - * occur. non-destructive underflows are permitted. underflows - * and overflows do not occur in the computation of the unscaled - * sum of squares for the intermediate components. - * the definitions of small, intermediate and large components - * depend on two constants, rdwarf and rgiant. the main - * restrictions on these constants are that rdwarf**2 not - * underflow and rgiant**2 not overflow. the constants - * given here are suitable for every known computer. - * - * the function statement is - * - * double precision function enorm(n,x) - * - * where - * - * n is a positive integer input variable. - * - * x is an input array of length n. - * - * argonne national laboratory. minpack project. march 1980. - * burton s. garbow, kenneth e. hillstrom, jorge j. more - * - * ********** - */ - static double enorm(int n, List x) { - int i; - double agiant, floatn, s1, s2, s3, xabs, x1max, x3max; - double ans, temp; - - const double rdwarf = 3.834e-20; - const double rgiant = 1.304e19; - const double zero = 0.0; - const double one = 1.0; - - s1 = zero; - s2 = zero; - s3 = zero; - x1max = zero; - x3max = zero; - floatn = n; - agiant = rgiant / floatn; - - for (i = 0; i < n; i++) { - xabs = Math.Abs(x[i]); - if ((xabs > rdwarf) && (xabs < agiant)) { - /* - * sum for intermediate components. - */ - s2 += xabs * xabs; - continue; - } - - if (xabs > rdwarf) { - /* - * sum for large components. - */ - if (xabs > x1max) { - temp = x1max / xabs; - s1 = one + s1 * temp * temp; - x1max = xabs; - } else { - temp = xabs / x1max; - s1 += temp * temp; - } - continue; - } - - /* - * sum for small components. - */ - if (xabs > x3max) { - temp = x3max / xabs; - s3 = one + s3 * temp * temp; - x3max = xabs; - } else { - if (xabs.IsNotEqual(zero)) { - temp = xabs / x3max; - s3 += temp * temp; - } - } - } - /* - * calculation of norm. - */ - if (s1.IsNotEqual(zero)) { - temp = s1 + (s2 / x1max) / x1max; - ans = x1max * Math.Sqrt(temp); - return (ans); - } - if (s2.IsNotEqual(zero)) { - if (s2 >= x3max) - temp = s2 * (one + (x3max / s2) * (x3max * s3)); - else - temp = x3max * ((s2 / x3max) + (x3max * s3)); - ans = Math.Sqrt(temp); - } else { - ans = x3max * Math.Sqrt(s3); - } - return (ans); - } - - /* - * ********** - * - * subroutine fdjac2 - * - * this subroutine computes a forward-difference approximation - * to the m by n jacobian matrix associated with a specified - * problem of m functions in n variables. - * - * the subroutine statement is - * - * subroutine fdjac2(fcn,m,n,x,fvec,fjac,ldfjac,iflag,epsfcn,wa) - * - * where - * - * fcn is the name of the user-supplied subroutine which - * calculates the functions. fcn must be declared - * in an external statement in the user calling - * program, and should be written as follows. - * - * subroutine fcn(m,n,x,fvec,iflag) - * integer m,n,iflag - * double precision x(n),fvec(m) - * ---------- - * calculate the functions at x and - * return this vector in fvec. - * ---------- - * return - * end - * - * the value of iflag should not be changed by fcn unless - * the user wants to terminate execution of fdjac2. - * in this case set iflag to a negative integer. - * - * m is a positive integer input variable set to the number - * of functions. - * - * n is a positive integer input variable set to the number - * of variables. n must not exceed m. - * - * x is an input array of length n. - * - * fvec is an input array of length m which must contain the - * functions evaluated at x. - * - * fjac is an output m by n array which contains the - * approximation to the jacobian matrix evaluated at x. - * - * ldfjac is a positive integer input variable not less than m - * which specifies the leading dimension of the array fjac. - * - * iflag is an integer variable which can be used to terminate - * the execution of fdjac2. see description of fcn. - * - * epsfcn is an input variable used in determining a suitable - * step length for the forward-difference approximation. this - * approximation assumes that the relative errors in the - * functions are of the order of epsfcn. if epsfcn is less - * than the machine precision, it is assumed that the relative - * errors in the functions are of the order of the machine - * precision. - * - * wa is a work array of length m. - * - * subprograms called - * - * user-supplied ...... fcn - * - * minpack-supplied ... dpmpar - * - * fortran-supplied ... dabs,dmax1,dsqrt - * - * argonne national laboratory. minpack project. march 1980. - * burton s. garbow, kenneth e. hillstrom, jorge j. more - * - ********** - */ - static void fdjac2(int m, int n, Vector x, Vector fvec, Matrix fjac, int dummy1, - int iflag, double epsfcn, ref Vector wa, - Func fcn) { - int i, j, ij; - double eps, h, temp; - - double zero = 0.0; - - temp = dmax1(epsfcn, MACHEP); - eps = Math.Sqrt(temp); - ij = 0; - for (j = 0; j < n; j++) { - temp = x[j]; - h = eps * Math.Abs(temp); - if (h.IsEqual(zero)) - h = eps; - x[j] = temp + h; - wa = fcn(m, n, x, iflag); - if (iflag < 0) - return; - x[j] = temp; - for (i = 0; i < m; i++) { - fjac[ij] = (wa[i] - fvec[i]) / h; - ij += 1; /* fjac[i+m*j] */ - } - } - } - - - /* - * ********** - * - * subroutine qrfac - * - * this subroutine uses householder transformations with column - * pivoting (optional) to compute a qr factorization of the - * m by n matrix a. that is, qrfac determines an orthogonal - * matrix q, a permutation matrix p, and an upper trapezoidal - * matrix r with diagonal elements of nonincreasing magnitude, - * such that a*p = q*r. the householder transformation for - * column k, k = 1,2,...,min(m,n), is of the form - * - * t - * i - (1/u(k))*u*u - * - * where u has zeros in the first k-1 positions. the form of - * this transformation and the method of pivoting first - * appeared in the corresponding linpack subroutine. - * - * the subroutine statement is - * - * subroutine qrfac(m,n,a,lda,pivot,ipvt,lipvt,rdiag,acnorm,wa) - * - * where - * - * m is a positive integer input variable set to the number - * of rows of a. - * - * n is a positive integer input variable set to the number - * of columns of a. - * - * a is an m by n array. on input a contains the matrix for - * which the qr factorization is to be computed. on output - * the strict upper trapezoidal part of a contains the strict - * upper trapezoidal part of r, and the lower trapezoidal - * part of a contains a factored form of q (the non-trivial - * elements of the u vectors described above). - * - * lda is a positive integer input variable not less than m - * which specifies the leading dimension of the array a. - * - * pivot is a logical input variable. if pivot is set true, - * then column pivoting is enforced. if pivot is set false, - * then no column pivoting is done. - * - * ipvt is an integer output array of length lipvt. ipvt - * defines the permutation matrix p such that a*p = q*r. - * column j of p is column ipvt(j) of the identity matrix. - * if pivot is false, ipvt is not referenced. - * - * lipvt is a positive integer input variable. if pivot is false, - * then lipvt may be as small as 1. if pivot is true, then - * lipvt must be at least n. - * - * rdiag is an output array of length n which contains the - * diagonal elements of r. - * - * acnorm is an output array of length n which contains the - * norms of the corresponding columns of the input matrix a. - * if this information is not needed, then acnorm can coincide - * with rdiag. - * - * wa is a work array of length n. if pivot is false, then wa - * can coincide with rdiag. - * - * subprograms called - * - * minpack-supplied ... dpmpar,enorm - * - * fortran-supplied ... dmax1,dsqrt,min0 - * - * argonne national laboratory. minpack project. march 1980. - * burton s. garbow, kenneth e. hillstrom, jorge j. more - * - * ********** - */ - public static void qrfac(int m, int n, Matrix a, int dummy1, int pivot, ref List ipvt, - int dummy2, ref Vector rdiag, ref Vector acnorm, Vector wa) { - int i, ij, jj, j, jp1, k, kmax, minmn; - double ajnorm, sum, temp; - - double zero = 0.0; - double one = 1.0; - double p05 = 0.05; - - /* - * compute the initial column norms and initialize several arrays. - */ - ij = 0; - for (j = 0; j < n; j++) { - acnorm[j] = enorm(m, a.GetRange(ij, m)); - rdiag[j] = acnorm[j]; - wa[j] = rdiag[j]; - if (pivot != 0) - ipvt[j] = j; - ij += m; /* m*j */ - } - /* - * reduce a to r with householder transformations. - */ - minmn = min0(m, n); - for (j = 0; j < minmn; j++) { - if (pivot == 0) - goto L40; - /* - * bring the column of largest norm into the pivot position. - */ - kmax = j; - for (k = j; k < n; k++) { - if (rdiag[k] > rdiag[kmax]) - kmax = k; - } - if (kmax == j) - goto L40; - - ij = m * j; - jj = m * kmax; - for (i = 0; i < m; i++) { - temp = a[ij]; /* [i+m*j] */ - a[ij] = a[jj]; /* [i+m*kmax] */ - a[jj] = temp; - ij += 1; - jj += 1; - } - rdiag[kmax] = rdiag[j]; - wa[kmax] = wa[j]; - k = ipvt[j]; - ipvt[j] = ipvt[kmax]; - ipvt[kmax] = k; - - L40: - /* - * compute the householder transformation to reduce the - * j-th column of a to a multiple of the j-th unit vector. - */ - jj = j + m * j; - ajnorm = enorm(m - j, a.GetRange(jj, m-j)); - if (ajnorm.IsEqual(zero)) - goto L100; - if (a[jj] < zero) - ajnorm = -ajnorm; - ij = jj; - for (i = j; i < m; i++) { - a[ij] /= ajnorm; - ij += 1; /* [i+m*j] */ - } - a[jj] += one; - /* - * apply the transformation to the remaining columns - * and update the norms. - */ - jp1 = j + 1; - if (jp1 < n) { - for (k = jp1; k < n; k++) { - sum = zero; - ij = j + m * k; - jj = j + m * j; - for (i = j; i < m; i++) { - sum += a[jj] * a[ij]; - ij += 1; /* [i+m*k] */ - jj += 1; /* [i+m*j] */ - } - temp = sum / a[j + m * j]; - ij = j + m * k; - jj = j + m * j; - for (i = j; i < m; i++) { - a[ij] -= temp * a[jj]; - ij += 1; /* [i+m*k] */ - jj += 1; /* [i+m*j] */ - } - if ((pivot != 0) && (rdiag[k].IsNotEqual(zero))) { - temp = a[j + m * k] / rdiag[k]; - temp = dmax1(zero, one - temp * temp); - rdiag[k] *= Math.Sqrt(temp); - temp = rdiag[k] / wa[k]; - if ((p05 * temp * temp) <= MACHEP) { - rdiag[k] = enorm(m - j - 1, a.GetRange(jp1+m*k, m - j - 1)); - wa[k] = rdiag[k]; - } - } - } - } - - L100: - rdiag[j] = -ajnorm; - } - } - - - /* - * ********** - * - * subroutine qrsolv - * - * given an m by n matrix a, an n by n diagonal matrix d, - * and an m-vector b, the problem is to determine an x which - * solves the system - * - * a*x = b , d*x = 0 , - * - * in the least squares sense. - * - * this subroutine completes the solution of the problem - * if it is provided with the necessary information from the - * qr factorization, with column pivoting, of a. that is, if - * a*p = q*r, where p is a permutation matrix, q has orthogonal - * columns, and r is an upper triangular matrix with diagonal - * elements of nonincreasing magnitude, then qrsolv expects - * the full upper triangle of r, the permutation matrix p, - * and the first n components of (q transpose)*b. the system - * a*x = b, d*x = 0, is then equivalent to - * - * t t - * r*z = q *b , p *d*p*z = 0 , - * - * where x = p*z. if this system does not have full rank, - * then a least squares solution is obtained. on output qrsolv - * also provides an upper triangular matrix s such that - * - * t t t - * p *(a *a + d*d)*p = s *s . - * - * s is computed within qrsolv and may be of separate interest. - * - * the subroutine statement is - * - * subroutine qrsolv(n,r,ldr,ipvt,diag,qtb,x,sdiag,wa) - * - * where - * - * n is a positive integer input variable set to the order of r. - * - * r is an n by n array. on input the full upper triangle - * must contain the full upper triangle of the matrix r. - * on output the full upper triangle is unaltered, and the - * strict lower triangle contains the strict upper triangle - * (transposed) of the upper triangular matrix s. - * - * ldr is a positive integer input variable not less than n - * which specifies the leading dimension of the array r. - * - * ipvt is an integer input array of length n which defines the - * permutation matrix p such that a*p = q*r. column j of p - * is column ipvt(j) of the identity matrix. - * - * diag is an input array of length n which must contain the - * diagonal elements of the matrix d. - * - * qtb is an input array of length n which must contain the first - * n elements of the vector (q transpose)*b. - * - * x is an output array of length n which contains the least - * squares solution of the system a*x = b, d*x = 0. - * - * sdiag is an output array of length n which contains the - * diagonal elements of the upper triangular matrix s. - * - * wa is a work array of length n. - * - * subprograms called - * - * fortran-supplied ... dabs,dsqrt - * - * argonne national laboratory. minpack project. march 1980. - * burton s. garbow, kenneth e. hillstrom, jorge j. more - * - * ********** - */ - public static void qrsolv(int n, Matrix r, int ldr, List ipvt, Vector diag, Vector qtb, Vector x, Vector sdiag, Vector wa) { - int i, ij, ik, kk, j, jp1, k, kp1, l, nsing; - double cos, cotan, qtbpj, sin, sum, tan, temp; - - double zero = 0.0; - double p25 = 0.25; - double p5 = 0.5; - - /* - * copy r and (q transpose)*b to preserve input and initialize s. - * in particular, save the diagonal elements of r in x. - */ - kk = 0; - for (j = 0; j < n; j++) { - ij = kk; - ik = kk; - for (i = j; i < n; i++) { - r[ij] = r[ik]; - ij += 1; /* [i+ldr*j] */ - ik += ldr; /* [j+ldr*i] */ - } - x[j] = r[kk]; - wa[j] = qtb[j]; - kk += ldr + 1; /* j+ldr*j */ - } - - /* - * eliminate the diagonal matrix d using a givens rotation. - */ - for (j = 0; j < n; j++) { - /* - * prepare the row of d to be eliminated, locating the - * diagonal element using p from the qr factorization. - */ - l = ipvt[j]; - if (diag[l].IsEqual(zero)) - goto L90; - for (k = j; k < n; k++) - sdiag[k] = zero; - sdiag[j] = diag[l]; - /* - * the transformations to eliminate the row of d - * modify only a single element of (q transpose)*b - * beyond the first n, which is initially zero. - */ - qtbpj = zero; - for (k = j; k < n; k++) { - /* - * determine a givens rotation which eliminates the - * appropriate element in the current row of d. - */ - if (sdiag[k].IsEqual(zero)) - continue; - kk = k + ldr * k; - if (Math.Abs(r[kk]) < Math.Abs(sdiag[k])) { - cotan = r[kk] / sdiag[k]; - sin = p5 / Math.Sqrt(p25 + p25 * cotan * cotan); - cos = sin * cotan; - } else { - tan = sdiag[k] / r[kk]; - cos = p5 / Math.Sqrt(p25 + p25 * tan * tan); - sin = cos * tan; - } - /* - * compute the modified diagonal element of r and - * the modified element of ((q transpose)*b,0). - */ - r[kk] = cos * r[kk] + sin * sdiag[k]; - temp = cos * wa[k] + sin * qtbpj; - qtbpj = -sin * wa[k] + cos * qtbpj; - wa[k] = temp; - /* - * accumulate the tranformation in the row of s. - */ - kp1 = k + 1; - if (n > kp1) { - ik = kk + 1; - for (i = kp1; i < n; i++) { - temp = cos * r[ik] + sin * sdiag[i]; - sdiag[i] = -sin * r[ik] + cos * sdiag[i]; - r[ik] = temp; - ik += 1; /* [i+ldr*k] */ - } - } - } - L90: - /* - * store the diagonal element of s and restore - * the corresponding diagonal element of r. - */ - kk = j + ldr * j; - sdiag[j] = r[kk]; - r[kk] = x[j]; - } - /* - * solve the triangular system for z. if the system is - * singular, then obtain a least squares solution. - */ - nsing = n; - for (j = 0; j < n; j++) { - if ((sdiag[j].IsEqual(zero)) && (nsing == n)) - nsing = j; - if (nsing < n) - wa[j] = zero; - } - if (nsing < 1) - goto L150; - - for (k = 0; k < nsing; k++) { - j = nsing - k - 1; - sum = zero; - jp1 = j + 1; - if (nsing > jp1) { - ij = jp1 + ldr * j; - for (i = jp1; i < nsing; i++) { - sum += r[ij] * wa[i]; - ij += 1; /* [i+ldr*j] */ - } - } - wa[j] = (wa[j] - sum) / sdiag[j]; - } - L150: - /* - * permute the components of z back to components of x. - */ - for (j = 0; j < n; j++) { - l = ipvt[j]; - x[l] = wa[j]; - } - } - - - - /* ********** - * - * subroutine lmpar - * - * given an m by n matrix a, an n by n nonsingular diagonal - * matrix d, an m-vector b, and a positive number delta, - * the problem is to determine a value for the parameter - * par such that if x solves the system - * - * a*x = b , sqrt(par)*d*x = 0 , - * - * in the least squares sense, and dxnorm is the euclidean - * norm of d*x, then either par is zero and - * - * (dxnorm-delta) .le. 0.1*delta , - * - * or par is positive and - * - * abs(dxnorm-delta) .le. 0.1*delta . - * - * this subroutine completes the solution of the problem - * if it is provided with the necessary information from the - * qr factorization, with column pivoting, of a. that is, if - * a*p = q*r, where p is a permutation matrix, q has orthogonal - * columns, and r is an upper triangular matrix with diagonal - * elements of nonincreasing magnitude, then lmpar expects - * the full upper triangle of r, the permutation matrix p, - * and the first n components of (q transpose)*b. on output - * lmpar also provides an upper triangular matrix s such that - * - * t t t - * p *(a *a + par*d*d)*p = s *s . - * - * s is employed within lmpar and may be of separate interest. - * - * only a few iterations are generally needed for convergence - * of the algorithm. if, however, the limit of 10 iterations - * is reached, then the output par will contain the best - * value obtained so far. - * - * the subroutine statement is - * - * subroutine lmpar(n,r,ldr,ipvt,diag,qtb,delta,par,x,sdiag, - * wa1,wa2) - * - * where - * - * n is a positive integer input variable set to the order of r. - * - * r is an n by n array. on input the full upper triangle - * must contain the full upper triangle of the matrix r. - * on output the full upper triangle is unaltered, and the - * strict lower triangle contains the strict upper triangle - * (transposed) of the upper triangular matrix s. - * - * ldr is a positive integer input variable not less than n - * which specifies the leading dimension of the array r. - * - * ipvt is an integer input array of length n which defines the - * permutation matrix p such that a*p = q*r. column j of p - * is column ipvt(j) of the identity matrix. - * - * diag is an input array of length n which must contain the - * diagonal elements of the matrix d. - * - * qtb is an input array of length n which must contain the first - * n elements of the vector (q transpose)*b. - * - * delta is a positive input variable which specifies an upper - * bound on the euclidean norm of d*x. - * - * par is a nonnegative variable. on input par contains an - * initial estimate of the levenberg-marquardt parameter. - * on output par contains the final estimate. - * - * x is an output array of length n which contains the least - * squares solution of the system a*x = b, sqrt(par)*d*x = 0, - * for the output par. - * - * sdiag is an output array of length n which contains the - * diagonal elements of the upper triangular matrix s. - * - * wa1 and wa2 are work arrays of length n. - * - * subprograms called - * - * minpack-supplied ... dpmpar,enorm,qrsolv - * - * fortran-supplied ... dabs,dmax1,dmin1,dsqrt - * - * argonne national laboratory. minpack project. march 1980. - * burton s. garbow, kenneth e. hillstrom, jorge j. more - * - * ********** - */ - static void lmpar(int n, Matrix r, int ldr, List ipvt, Vector diag, - Vector qtb, double delta, double par, Vector x, Vector sdiag, - Vector wa1, Vector wa2) { - int i, iter, ij, jj, j, jm1, jp1, k, l, nsing; - double dxnorm, fp, gnorm, parc, parl, paru; - double sum, temp; - - double zero = 0.0; - double p1 = 0.1; - double p001 = 0.001; - - /* - * compute and store in x the gauss-newton direction. if the - * jacobian is rank-deficient, obtain a least squares solution. - */ - nsing = n; - jj = 0; - for (j = 0; j < n; j++) { - wa1[j] = qtb[j]; - if ((r[jj].IsEqual(zero)) && (nsing == n)) - nsing = j; - if (nsing < n) - wa1[j] = zero; - jj += ldr + 1; /* [j+ldr*j] */ - } - - if (nsing >= 1) { - for (k = 0; k < nsing; k++) { - j = nsing - k - 1; - wa1[j] = wa1[j] / r[j + ldr * j]; - temp = wa1[j]; - jm1 = j - 1; - if (jm1 >= 0) { - ij = ldr * j; - for (i = 0; i <= jm1; i++) { - wa1[i] -= r[ij] * temp; - ij += 1; - } - } - } - } - - for (j = 0; j < n; j++) { - l = ipvt[j]; - x[l] = wa1[j]; - } - /* - * initialize the iteration counter. - * evaluate the function at the origin, and test - * for acceptance of the gauss-newton direction. - */ - iter = 0; - for (j = 0; j < n; j++) - wa2[j] = diag[j] * x[j]; - dxnorm = enorm(n, wa2); - fp = dxnorm - delta; - if (fp <= p1 * delta) { - goto L220; - } - /* - * if the jacobian is not rank deficient, the newton - * step provides a lower bound, parl, for the zero of - * the function. otherwise set this bound to zero. - */ - parl = zero; - if (nsing >= n) { - for (j = 0; j < n; j++) { - l = ipvt[j]; - wa1[j] = diag[l] * (wa2[l] / dxnorm); - } - jj = 0; - for (j = 0; j < n; j++) { - sum = zero; - jm1 = j - 1; - if (jm1 >= 0) { - ij = jj; - for (i = 0; i <= jm1; i++) { - sum += r[ij] * wa1[i]; - ij += 1; - } - } - wa1[j] = (wa1[j] - sum) / r[j + ldr * j]; - jj += ldr; /* [i+ldr*j] */ - } - temp = enorm(n, wa1); - parl = ((fp / delta) / temp) / temp; - } - /* - * calculate an upper bound, paru, for the zero of the function. - */ - jj = 0; - for (j = 0; j < n; j++) { - sum = zero; - ij = jj; - for (i = 0; i <= j; i++) { - sum += r[ij] * qtb[i]; - ij += 1; - } - l = ipvt[j]; - wa1[j] = sum / diag[l]; - jj += ldr; /* [i+ldr*j] */ - } - gnorm = enorm(n, wa1); - paru = gnorm / delta; - if (paru.IsEqual(zero)) - paru = DWARF / dmin1(delta, p1); - /* - * if the input par lies outside of the interval (parl,paru), - * set par to the closer endpoint. - */ - par = dmax1(par, parl); - par = dmin1(par, paru); - if (par.IsEqual(zero)) - par = gnorm / dxnorm; - - /* - * beginning of an iteration. - */ - L150: - iter += 1; - /* - * evaluate the function at the current value of par. - */ - if (par.IsEqual(zero)) - par = dmax1(DWARF, p001 * paru); - temp = Math.Sqrt(par); - for (j = 0; j < n; j++) - wa1[j] = temp * diag[j]; - qrsolv(n, r, ldr, ipvt, wa1, qtb, x, sdiag, wa2); - for (j = 0; j < n; j++) - wa2[j] = diag[j] * x[j]; - dxnorm = enorm(n, wa2); - temp = fp; - fp = dxnorm - delta; - /* - * if the function is small enough, accept the current value - * of par. also test for the exceptional cases where parl - * is zero or the number of iterations has reached 10. - */ - if ((Math.Abs(fp) <= p1 * delta) - || ((parl.IsEqual(zero)) && (fp <= temp) && (temp < zero)) - || (iter == 10)) - goto L220; - /* - * compute the newton correction. - */ - for (j = 0; j < n; j++) { - l = ipvt[j]; - wa1[j] = diag[l] * (wa2[l] / dxnorm); - } - jj = 0; - for (j = 0; j < n; j++) { - wa1[j] = wa1[j] / sdiag[j]; - temp = wa1[j]; - jp1 = j + 1; - if (jp1 < n) { - ij = jp1 + jj; - for (i = jp1; i < n; i++) { - wa1[i] -= r[ij] * temp; - ij += 1; /* [i+ldr*j] */ - } - } - jj += ldr; /* ldr*j */ - } - temp = enorm(n, wa1); - parc = ((fp / delta) / temp) / temp; - /* - * depending on the sign of the function, update parl or paru. - */ - if (fp > zero) - parl = dmax1(parl, par); - if (fp < zero) - paru = dmin1(paru, par); - /* - * compute an improved estimate for par. - */ - par = dmax1(parl, par + parc); - /* - * end of an iteration. - */ - goto L150; - - L220: - /* - * termination. - */ - if (iter == 0) - par = zero; - } - - - static double dmax1(double a, double b) { return a >= b ? a : b; } - static double dmin1(double a, double b) { return a <= b ? a : b; } - static int min0(int a, int b) { return a <= b ? a : b; } - static int mod(int k, int m) { return (k % m); } - - } -} diff --git a/src/QLNet/Math/Optimization/problem.cs b/src/QLNet/Math/Optimization/problem.cs deleted file mode 100644 index b5e4ed932..000000000 --- a/src/QLNet/Math/Optimization/problem.cs +++ /dev/null @@ -1,100 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - * - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -namespace QLNet { - //! Constrained optimization problem - public class Problem { - //! Unconstrained cost function - protected CostFunction costFunction_; - public CostFunction costFunction() { return costFunction_; } - - //! Constraint - protected Constraint constraint_; - public Constraint constraint() { return constraint_; } - - //! current value of the local minimum - protected Vector currentValue_; - public Vector currentValue() { return currentValue_; } - - //! function and gradient norm values at the curentValue_ (i.e. the last step) - protected double? functionValue_, squaredNorm_; - public double functionValue() { return functionValue_.GetValueOrDefault(); } - public double gradientNormValue() { return squaredNorm_.GetValueOrDefault(); } - - //! number of evaluation of cost function and its gradient - protected int functionEvaluation_, gradientEvaluation_; - public int functionEvaluation() { return functionEvaluation_; } - public int gradientEvaluation() { return gradientEvaluation_; } - - - //! default constructor - //public Problem(CostFunction costFunction, Constraint constraint, Vector initialValue = Array()) - public Problem(CostFunction costFunction, Constraint constraint, Vector initialValue) { - costFunction_ = costFunction; - constraint_ = constraint; - currentValue_ = initialValue.Clone(); - } - - /*! \warning it does not reset the current minumum to any initial value - */ - public void reset() { - functionEvaluation_ = gradientEvaluation_ = 0; - functionValue_ = squaredNorm_ = null; - } - - //! call cost function computation and increment evaluation counter - public double value(Vector x) { - ++functionEvaluation_; - return costFunction_.value(x); - } - - //! call cost values computation and increment evaluation counter - public Vector values(Vector x) { - ++functionEvaluation_; - return costFunction_.values(x); - } - - //! call cost function gradient computation and increment - // evaluation counter - public void gradient(Vector grad_f, Vector x) { - ++gradientEvaluation_; - costFunction_.gradient(grad_f, x); - } - - //! call cost function computation and it gradient - public double valueAndGradient(Vector grad_f, Vector x) { - ++functionEvaluation_; - ++gradientEvaluation_; - return costFunction_.valueAndGradient(grad_f, x); - } - - public void setCurrentValue(Vector currentValue) { - currentValue_ = currentValue.Clone(); - } - - public void setFunctionValue(double functionValue) { - functionValue_ = functionValue; - } - - public void setGradientNormValue(double squaredNorm) { - squaredNorm_ = squaredNorm; - } - } -} diff --git a/src/QLNet/Math/PascalTriangle.cs b/src/QLNet/Math/PascalTriangle.cs index 867f27d51..10631e0cb 100644 --- a/src/QLNet/Math/PascalTriangle.cs +++ b/src/QLNet/Math/PascalTriangle.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,7 +24,7 @@ public class PascalTriangle //! Get and store one vector of coefficients after another. public static List get(int order) { - if (coefficients_.empty()) + if (coefficients_.empty()) { // order zero mandatory for bootstrap coefficients_.Add(new InitializedList(1, 1)); @@ -34,21 +34,21 @@ public static List get(int order) coefficients_[2][1] = 2; coefficients_.Add(new InitializedList(4, 1)); coefficients_[3][1] = coefficients_[3][2] = 3; - } - while (coefficients_.Count<=order) + } + while (coefficients_.Count <= order) nextOrder(); - return coefficients_[order]; + return coefficients_[order]; } - + private PascalTriangle() {} private static void nextOrder() { int order = coefficients_.Count; - coefficients_.Add(new InitializedList(order+1)); + coefficients_.Add(new InitializedList(order + 1)); coefficients_[order][0] = coefficients_[order][order] = 1; - for (int i=1; i. -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,28 +24,28 @@ public class PolynomialFunction { public PolynomialFunction(List coeff) { - Utils.QL_REQUIRE(!coeff.empty(),()=> "empty coefficient vector"); + Utils.QL_REQUIRE(!coeff.empty(), () => "empty coefficient vector"); order_ = coeff.Count; c_ = coeff; - derC_ = new InitializedList(order_-1); + derC_ = new InitializedList(order_ - 1); prC_ = new InitializedList(order_); K_ = 0.0; eqs_ = new Matrix(order_, order_, 0.0); int i; - for (i=0; i definiteIntegralCoefficients(double t, double t2) initializeEqs_(t, t2); Vector coeff = eqs_ * k; List result = new List(coeff); - return result; + return result; } /*! coefficients of a PolynomialFunction defined as definite @@ -122,16 +122,16 @@ private void initializeEqs_(double t, double t2) { double dt = t2 - t; double tau; - for (int i=0; i. - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -33,52 +33,58 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! Prime numbers calculator - /*! Taken from "Monte Carlo Methods in Finance", by Peter Jäckel - */ - public class PrimeNumbers { - //! Get and store one after another. + //! Prime numbers calculator + /*! Taken from "Monte Carlo Methods in Finance", by Peter Jäckel + */ + public class PrimeNumbers + { + //! Get and store one after another. + + private static readonly ulong[] firstPrimes = + { + // the first two primes are mandatory for bootstrapping + 2, 3, + // optional additional precomputed primes + 5, 7, 11, 13, 17, 19, 23, 29, + 31, 37, 41, 43, 47 + }; + + private static List primeNumbers_ = new List(); - private static readonly ulong[] firstPrimes = { - // the first two primes are mandatory for bootstrapping - 2, 3, - // optional additional precomputed primes - 5, 7, 11, 13, 17, 19, 23, 29, - 31, 37, 41, 43, 47 }; - - private static List primeNumbers_ = new List(); + private PrimeNumbers() + {} - private PrimeNumbers() - {} + public static ulong get(int absoluteIndex) + { + if (primeNumbers_.empty()) + primeNumbers_.AddRange(firstPrimes); - public static ulong get(int absoluteIndex) - { - if (primeNumbers_.empty()) - primeNumbers_.AddRange(firstPrimes); + while (primeNumbers_.Count <= absoluteIndex) + nextPrimeNumber(); - while (primeNumbers_.Count<=absoluteIndex) - nextPrimeNumber(); - - return primeNumbers_[absoluteIndex]; - } + return primeNumbers_[absoluteIndex]; + } - private static ulong nextPrimeNumber() - { - ulong p, n, m = primeNumbers_.Last(); - do { - // skip the even numbers - m += 2; - n = (ulong)Math.Sqrt((double)m); - // i=1 since the even numbers have already been skipped - int i = 1; - do { - p = primeNumbers_[i]; - ++i; - } - while ((m % p != 0) && p <= n); - } while ( p<=n ); - primeNumbers_.Add(m); - return m; - } - } + private static ulong nextPrimeNumber() + { + ulong p, n, m = primeNumbers_.Last(); + do + { + // skip the even numbers + m += 2; + n = (ulong)Math.Sqrt((double)m); + // i=1 since the even numbers have already been skipped + int i = 1; + do + { + p = primeNumbers_[i]; + ++i; + } + while ((m % p != 0) && p <= n); + } + while (p <= n); + primeNumbers_.Add(m); + return m; + } + } } diff --git a/src/QLNet/Math/RichardsonExtrapolation.cs b/src/QLNet/Math/RichardsonExtrapolation.cs index bfe66fd3c..2416bec3e 100644 --- a/src/QLNet/Math/RichardsonExtrapolation.cs +++ b/src/QLNet/Math/RichardsonExtrapolation.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -35,23 +35,23 @@ public class RichardsonEqn : ISolver1d { public RichardsonEqn(double fh, double ft, double fs, double t, double s) { - fdelta_h_ = fh; - ft_ = ft; - fs_ = fs; - t_ = t; + fdelta_h_ = fh; + ft_ = ft; + fs_ = fs; + t_ = t; s_ = s; } - - public override double value(double k) + + public override double value(double k) { - return ft_ + (ft_-fdelta_h_)/(Math.Pow(t_, k)-1.0) - - ( fs_ + (fs_-fdelta_h_)/(Math.Pow(s_, k)-1.0)); + return ft_ + (ft_ - fdelta_h_) / (Math.Pow(t_, k) - 1.0) + - (fs_ + (fs_ - fdelta_h_) / (Math.Pow(s_, k) - 1.0)); } - + private double fdelta_h_, ft_, fs_, t_, s_; } - public class RichardsonExtrapolation + public class RichardsonExtrapolation { /*! Richardon Extrapolation \param f function to be extrapolated to delta_h -> 0 @@ -60,7 +60,7 @@ public class RichardsonExtrapolation */ public delegate double function(double num); - public RichardsonExtrapolation( function f, double delta_h, double? n = null ) + public RichardsonExtrapolation(function f, double delta_h, double? n = null) { delta_h_ = delta_h; fdelta_h_ = f(delta_h); @@ -71,39 +71,39 @@ public RichardsonExtrapolation( function f, double delta_h, double? n = null ) /*! Extrapolation for known order of convergence \param t scaling factor for the step size */ - public double value( double t = 2.0 ) + public double value(double t = 2.0) { - Utils.QL_REQUIRE(t > 1, ()=> "scaling factor must be greater than 1"); - Utils.QL_REQUIRE(n_ != null, ()=> "order of convergence must be known"); + Utils.QL_REQUIRE(t > 1, () => "scaling factor must be greater than 1"); + Utils.QL_REQUIRE(n_ != null, () => "order of convergence must be known"); double tk = Math.Pow(t, n_.Value); - return (tk*f_(delta_h_/t)-fdelta_h_)/(tk-1.0); + return (tk * f_(delta_h_ / t) - fdelta_h_) / (tk - 1.0); } /*! Extrapolation for unknown order of convergence \param t first scaling factor for the step size \param s second scaling factor for the step size */ - public double value( double t, double s ) + public double value(double t, double s) { - Utils.QL_REQUIRE(t > 1 && s > 1, ()=>"scaling factors must be greater than 1"); - Utils.QL_REQUIRE(t > s, ()=> "t must be greater than s"); + Utils.QL_REQUIRE(t > 1 && s > 1, () => "scaling factors must be greater than 1"); + Utils.QL_REQUIRE(t > s, () => "t must be greater than s"); - double ft = f_(delta_h_/t); - double fs = f_(delta_h_/s); + double ft = f_(delta_h_ / t); + double fs = f_(delta_h_ / s); double k = new Brent().solve(new RichardsonEqn(fdelta_h_, ft, fs, t, s), - 1e-8, 0.05, 10); + 1e-8, 0.05, 10); double ts = Math.Pow(s, k); - return (ts*fs-fdelta_h_)/(ts-1.0); + return (ts * fs - fdelta_h_) / (ts - 1.0); } private double delta_h_; private double fdelta_h_; private double? n_; private function f_; - } + } } diff --git a/src/QLNet/Math/Rounding.cs b/src/QLNet/Math/Rounding.cs index 0a3187d36..b768bc545 100644 --- a/src/QLNet/Math/Rounding.cs +++ b/src/QLNet/Math/Rounding.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,196 +20,205 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! rounding methods - /*! The rounding methods follow the OMG specification available - at ftp://ftp.omg.org/pub/docs/formal/00-06-29.pdf - \warning the names of the Floor and Ceiling methods might be misleading. Check the provided reference. */ - - /// - /// Basic rounding class - /// - public class Rounding - { - private int precision_; - private Type type_; - private int digit_; - - public enum Type - { - /// - /// do not round: return the number unmodified - /// - None, - /// - /// the first decimal place past the precision will be - /// rounded up. This differs from the OMG rule which - /// rounds up only if the decimal to be rounded is - /// greater than or equal to the rounding digit - /// - Up, - /// - /// all decimal places past the precision will be - /// truncated - /// - Down, - /// - /// the first decimal place past the precision - /// will be rounded up if greater than or equal - /// to the rounding digit; this corresponds to - /// the OMG round-up rule. When the rounding - /// digit is 5, the result will be the one - /// closest to the original number, hence the - /// name. - /// - Closest, - /// - /// positive numbers will be rounded up and negative - /// numbers will be rounded down using the OMG round up - /// and round down rules - /// - Floor, - /// - /// positive numbers will be rounded down and negative - /// numbers will be rounded up using the OMG round up - /// and round down rules - /// - Ceiling - } - - /// - /// default constructor - /// Instances built through this constructor don't perform - /// any rounding. - /// - public Rounding() - { - type_ = Type.None; - } - public Rounding(int precision, Type type) - : this(precision, type, 5) - { - } - public Rounding(int precision) - : this(precision, Type.Closest, 5) - { - } - public Rounding(int precision, Type type, int digit) - { - precision_ = precision; - type_ = type; - digit_ = digit; - } - - public int Precision - { - get { return precision_; } - } - - public Type getType - { - get { return type_; } - } - - public int Digit - { - get { return digit_; } - } - - /// - /// Up-rounding - /// - /// - /// - public double Round(double value) - { - if (type_ == Type.None) - return value; - - double mult = Math.Pow(10.0, precision_); - bool neg = (value < 0.0); - double lvalue = Math.Abs(value) * mult; - double integral = 0.0; - double modVal = lvalue - (integral = Math.Floor(lvalue)); - - lvalue -= modVal; - switch (type_) - { - case Type.Down: - break; - case Type.Up: - lvalue += 1.0; - break; - case Type.Closest: - if (modVal >= (digit_ / 10.0)) - lvalue += 1.0; - break; - case Type.Floor: - if (!neg) - { - if (modVal >= (digit_ / 10.0)) - lvalue += 1.0; - } - break; - case Type.Ceiling: - if (neg) - { - if (modVal >= (digit_ / 10.0)) - lvalue += 1.0; - } - break; - default: - Utils.QL_FAIL("unknown rounding method"); - break; - } - return (neg) ? -(lvalue / mult) : lvalue / mult; - } - - } - - /// - /// Up-rounding - /// - public class UpRounding : Rounding - { - public UpRounding(int precision) : base(precision, Type.Up, 5) { } - public UpRounding(int precision, int digit) : base(precision, Type.Up, digit) { } - } - - /// - /// Down-rounding. - /// - public class DownRounding : Rounding - { - public DownRounding(int precision) : base(precision, Type.Down, 5) { } - public DownRounding(int precision, int digit) : base(precision, Type.Down, digit) { } - } - - /// - /// Closest rounding. - /// - public class ClosestRounding : Rounding - { - public ClosestRounding(int precision) : base(precision, Type.Closest, 5) { } - public ClosestRounding(int precision, int digit) : base(precision, Type.Closest, digit) { } - } - - //! - /// - /// Ceiling truncation. - /// - public class CeilingTruncation : Rounding - { - public CeilingTruncation(int precision) : base(precision, Type.Ceiling, 5) { } - public CeilingTruncation(int precision, int digit) : base(precision, Type.Ceiling, digit) { } - } - - /// - /// Floor truncation. - /// - public class FloorTruncation : Rounding - { - public FloorTruncation(int precision) : base(precision, Type.Floor, 5) { } - public FloorTruncation(int precision, int digit) : base(precision, Type.Floor, digit) { } - } + //! rounding methods + /*! The rounding methods follow the OMG specification available + at ftp://ftp.omg.org/pub/docs/formal/00-06-29.pdf + \warning the names of the Floor and Ceiling methods might be misleading. Check the provided reference. */ + + /// + /// Basic rounding class + /// + public class Rounding + { + private int precision_; + private Type type_; + private int digit_; + + public enum Type + { + /// + /// do not round: return the number unmodified + /// + None, + /// + /// the first decimal place past the precision will be + /// rounded up. This differs from the OMG rule which + /// rounds up only if the decimal to be rounded is + /// greater than or equal to the rounding digit + /// + Up, + /// + /// all decimal places past the precision will be + /// truncated + /// + Down, + /// + /// the first decimal place past the precision + /// will be rounded up if greater than or equal + /// to the rounding digit; this corresponds to + /// the OMG round-up rule. When the rounding + /// digit is 5, the result will be the one + /// closest to the original number, hence the + /// name. + /// + Closest, + /// + /// positive numbers will be rounded up and negative + /// numbers will be rounded down using the OMG round up + /// and round down rules + /// + Floor, + /// + /// positive numbers will be rounded down and negative + /// numbers will be rounded up using the OMG round up + /// and round down rules + /// + Ceiling + } + + /// + /// default constructor + /// Instances built through this constructor don't perform + /// any rounding. + /// + public Rounding() + { + type_ = Type.None; + } + public Rounding(int precision, Type type) + : this(precision, type, 5) + { + } + public Rounding(int precision) + : this(precision, Type.Closest, 5) + { + } + public Rounding(int precision, Type type, int digit) + { + precision_ = precision; + type_ = type; + digit_ = digit; + } + + public int Precision + { + get + { + return precision_; + } + } + + public Type getType + { + get + { + return type_; + } + } + + public int Digit + { + get + { + return digit_; + } + } + + /// + /// Up-rounding + /// + /// + /// + public double Round(double value) + { + if (type_ == Type.None) + return value; + + double mult = Math.Pow(10.0, precision_); + bool neg = (value < 0.0); + double lvalue = Math.Abs(value) * mult; + double integral = 0.0; + double modVal = lvalue - (integral = Math.Floor(lvalue)); + + lvalue -= modVal; + switch (type_) + { + case Type.Down: + break; + case Type.Up: + lvalue += 1.0; + break; + case Type.Closest: + if (modVal >= (digit_ / 10.0)) + lvalue += 1.0; + break; + case Type.Floor: + if (!neg) + { + if (modVal >= (digit_ / 10.0)) + lvalue += 1.0; + } + break; + case Type.Ceiling: + if (neg) + { + if (modVal >= (digit_ / 10.0)) + lvalue += 1.0; + } + break; + default: + Utils.QL_FAIL("unknown rounding method"); + break; + } + return (neg) ? -(lvalue / mult) : lvalue / mult; + } + + } + + /// + /// Up-rounding + /// + public class UpRounding : Rounding + { + public UpRounding(int precision) : base(precision, Type.Up, 5) { } + public UpRounding(int precision, int digit) : base(precision, Type.Up, digit) { } + } + + /// + /// Down-rounding. + /// + public class DownRounding : Rounding + { + public DownRounding(int precision) : base(precision, Type.Down, 5) { } + public DownRounding(int precision, int digit) : base(precision, Type.Down, digit) { } + } + + /// + /// Closest rounding. + /// + public class ClosestRounding : Rounding + { + public ClosestRounding(int precision) : base(precision, Type.Closest, 5) { } + public ClosestRounding(int precision, int digit) : base(precision, Type.Closest, digit) { } + } + + //! + /// + /// Ceiling truncation. + /// + public class CeilingTruncation : Rounding + { + public CeilingTruncation(int precision) : base(precision, Type.Ceiling, 5) { } + public CeilingTruncation(int precision, int digit) : base(precision, Type.Ceiling, digit) { } + } + + /// + /// Floor truncation. + /// + public class FloorTruncation : Rounding + { + public FloorTruncation(int precision) : base(precision, Type.Floor, 5) { } + public FloorTruncation(int precision, int digit) : base(precision, Type.Floor, digit) { } + } } diff --git a/src/QLNet/Math/SampledCurve.cs b/src/QLNet/Math/SampledCurve.cs index c86f1470c..641bef253 100644 --- a/src/QLNet/Math/SampledCurve.cs +++ b/src/QLNet/Math/SampledCurve.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -105,7 +105,7 @@ public void sample(Func f) public double valueAtCenter() { - Utils.QL_REQUIRE(!empty(),()=> "empty sampled curve"); + Utils.QL_REQUIRE(!empty(), () => "empty sampled curve"); int jmid = size() / 2; if (size() % 2 == 1) @@ -118,7 +118,7 @@ public double valueAtCenter() public double firstDerivativeAtCenter() { - Utils.QL_REQUIRE(size() >= 3,()=> "the size of the curve must be at least 3"); + Utils.QL_REQUIRE(size() >= 3, () => "the size of the curve must be at least 3"); int jmid = size() / 2; if (size() % 2 == 1) @@ -132,7 +132,7 @@ public double firstDerivativeAtCenter() public double secondDerivativeAtCenter() { - Utils.QL_REQUIRE(size() >= 4,()=> "the size of the curve must be at least 4"); + Utils.QL_REQUIRE(size() >= 4, () => "the size of the curve must be at least 4"); int jmid = size() / 2; if (size() % 2 == 1) { @@ -173,9 +173,9 @@ public void scaleGrid(double s) public void regrid(Vector new_grid) { CubicInterpolation priceSpline = new CubicInterpolation(grid_, grid_.Count, values_, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0); + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0); priceSpline.update(); Vector newValues = new Vector(new_grid.Count); @@ -194,9 +194,9 @@ public void regrid(Vector new_grid, Func func) transformed_grid[i] = func(grid_[i]); CubicInterpolation priceSpline = new CubicInterpolation(transformed_grid, transformed_grid.Count, values_, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0); + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0); priceSpline.update(); Vector newValues = new_grid.Clone(); diff --git a/src/QLNet/Math/Solver1d.cs b/src/QLNet/Math/Solver1d.cs index 556536adb..5c795d4e1 100644 --- a/src/QLNet/Math/Solver1d.cs +++ b/src/QLNet/Math/Solver1d.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -56,14 +56,14 @@ public abstract class Solver1D /*! This method returns the zero of the function \f$ f \f$, determined with the given accuracy \f$ \epsilon \f$ depending on the particular solver, this might mean that the returned \f$ x \f$ is such that \f$ |f(x)| < \epsilon \f$, or that \f$ |x-\xi| < \epsilon \f$ where \f$ \xi \f$ is the real zero. - + This method contains a bracketing routine to which an initial guess must be supplied as well as a step used to scan the range of the possible bracketing values. */ public double solve(ISolver1d f, double accuracy, double guess, double step) { - Utils.QL_REQUIRE(accuracy > 0.0,()=> "accuracy (" + accuracy + ") must be positive"); + Utils.QL_REQUIRE(accuracy > 0.0, () => "accuracy (" + accuracy + ") must be positive"); // check whether we really want to use epsilon accuracy = Math.Max(accuracy, Const.QL_EPSILON); @@ -96,8 +96,10 @@ public double solve(ISolver1d f, double accuracy, double guess, double step) { if (fxMin_ * fxMax_ <= 0.0) { - if (Utils.close(fxMin_, 0.0)) return xMin_; - if (Utils.close(fxMax_, 0.0)) return xMax_; + if (Utils.close(fxMin_, 0.0)) + return xMin_; + if (Utils.close(fxMax_, 0.0)) + return xMax_; root_ = (xMax_ + xMin_) / 2.0; return solveImpl(f, accuracy); } @@ -145,7 +147,7 @@ must bracket the zero (i.e., either \f$ f(x_\mathrm{min}) \leq 0 \leq f(x_\mathr public double solve(ISolver1d f, double accuracy, double guess, double xMin, double xMax) { - Utils.QL_REQUIRE(accuracy > 0.0,()=> "accuracy (" + accuracy + ") must be positive"); + Utils.QL_REQUIRE(accuracy > 0.0, () => "accuracy (" + accuracy + ") must be positive"); // check whether we really want to use epsilon accuracy = Math.Max(accuracy, Const.QL_EPSILON); @@ -153,24 +155,26 @@ public double solve(ISolver1d f, double accuracy, double guess, double xMin, dou xMin_ = xMin; xMax_ = xMax; - Utils.QL_REQUIRE(xMin_ < xMax_,()=> "invalid range: xMin_ (" + xMin_ + ") >= xMax_ (" + xMax_ + ")"); - Utils.QL_REQUIRE(!lowerBoundEnforced_ || xMin_ >= lowerBound_,()=> - "xMin_ (" + xMin_ + ") < enforced low bound (" + lowerBound_ + ")"); - Utils.QL_REQUIRE(!upperBoundEnforced_ || xMax_ <= upperBound_,()=> - "xMax_ (" + xMax_ + ") > enforced hi bound (" + upperBound_ + ")"); + Utils.QL_REQUIRE(xMin_ < xMax_, () => "invalid range: xMin_ (" + xMin_ + ") >= xMax_ (" + xMax_ + ")"); + Utils.QL_REQUIRE(!lowerBoundEnforced_ || xMin_ >= lowerBound_, () => + "xMin_ (" + xMin_ + ") < enforced low bound (" + lowerBound_ + ")"); + Utils.QL_REQUIRE(!upperBoundEnforced_ || xMax_ <= upperBound_, () => + "xMax_ (" + xMax_ + ") > enforced hi bound (" + upperBound_ + ")"); fxMin_ = f.value(xMin_); - if (Utils.close(fxMin_, 0.0)) return xMin_; + if (Utils.close(fxMin_, 0.0)) + return xMin_; fxMax_ = f.value(xMax_); - if (Utils.close(fxMax_, 0.0)) return xMax_; + if (Utils.close(fxMax_, 0.0)) + return xMax_; evaluationNumber_ = 2; - Utils.QL_REQUIRE(fxMin_ * fxMax_ < 0.0,()=> - "root not bracketed: f[" + xMin_ + "," + xMax_ + "] -> [" + fxMin_ + "," + fxMax_ + "]"); - Utils.QL_REQUIRE(guess > xMin_,()=> "guess (" + guess + ") < xMin_ (" + xMin_ + ")"); - Utils.QL_REQUIRE(guess < xMax_,()=> "guess (" + guess + ") > xMax_ (" + xMax_ + ")"); + Utils.QL_REQUIRE(fxMin_ * fxMax_ < 0.0, () => + "root not bracketed: f[" + xMin_ + "," + xMax_ + "] -> [" + fxMin_ + "," + fxMax_ + "]"); + Utils.QL_REQUIRE(guess > xMin_, () => "guess (" + guess + ") < xMin_ (" + xMin_ + ")"); + Utils.QL_REQUIRE(guess < xMax_, () => "guess (" + guess + ") > xMax_ (" + xMax_ + ")"); root_ = guess; diff --git a/src/QLNet/Math/Solvers1d/Bisection.cs b/src/QLNet/Math/Solvers1d/Bisection.cs index a2dd9ab34..d972b5892 100644 --- a/src/QLNet/Math/Solvers1d/Bisection.cs +++ b/src/QLNet/Math/Solvers1d/Bisection.cs @@ -1,57 +1,65 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - public class Bisection : Solver1D { - protected override double solveImpl(ISolver1d f, double xAccuracy) { - - /* The implementation of the algorithm was inspired by - Press, Teukolsky, Vetterling, and Flannery, - "Numerical Recipes in C", 2nd edition, Cambridge - University Press - */ - - double dx, xMid, fMid; - - // Orient the search so that f>0 lies at root_+dx - if (fxMin_ < 0.0) { - dx = xMax_-xMin_; - root_ = xMin_; - } else { - dx = xMin_-xMax_; - root_ = xMax_; - } +namespace QLNet +{ + public class Bisection : Solver1D + { + protected override double solveImpl(ISolver1d f, double xAccuracy) + { + + /* The implementation of the algorithm was inspired by + Press, Teukolsky, Vetterling, and Flannery, + "Numerical Recipes in C", 2nd edition, Cambridge + University Press + */ + + double dx, xMid, fMid; + + // Orient the search so that f>0 lies at root_+dx + if (fxMin_ < 0.0) + { + dx = xMax_ - xMin_; + root_ = xMin_; + } + else + { + dx = xMin_ - xMax_; + root_ = xMax_; + } - while (evaluationNumber_ <= maxEvaluations_) { - dx /= 2.0; - xMid = root_ + dx; - fMid = f.value(xMid); - evaluationNumber_++; - if (fMid <= 0.0) - root_ = xMid; - if (Math.Abs(dx) < xAccuracy || Utils.close(fMid , 0.0)) { - return root_; - } + while (evaluationNumber_ <= maxEvaluations_) + { + dx /= 2.0; + xMid = root_ + dx; + fMid = f.value(xMid); + evaluationNumber_++; + if (fMid <= 0.0) + root_ = xMid; + if (Math.Abs(dx) < xAccuracy || Utils.close(fMid, 0.0)) + { + return root_; } - throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded"); - } - } + } + throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded"); + } + } } diff --git a/src/QLNet/Math/Solvers1d/Brent.cs b/src/QLNet/Math/Solvers1d/Brent.cs index fd8903c68..01ebb3c2c 100644 --- a/src/QLNet/Math/Solvers1d/Brent.cs +++ b/src/QLNet/Math/Solvers1d/Brent.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,81 +20,97 @@ under the terms of the QLNet license. You should have received a using System; -namespace QLNet { - public class Brent : Solver1D { - protected override double solveImpl(ISolver1d f, double xAccuracy) { - /* The implementation of the algorithm was inspired by Press, Teukolsky, Vetterling, and Flannery, - "Numerical Recipes in C", 2nd edition, Cambridge University Press */ +namespace QLNet +{ + public class Brent : Solver1D + { + protected override double solveImpl(ISolver1d f, double xAccuracy) + { + /* The implementation of the algorithm was inspired by Press, Teukolsky, Vetterling, and Flannery, + "Numerical Recipes in C", 2nd edition, Cambridge University Press */ - double min1, min2; - double froot, p, q, r, s, xAcc1, xMid; - // dummy assignements to avoid compiler warning - double d = 0.0, e = 0.0; + double min1, min2; + double froot, p, q, r, s, xAcc1, xMid; + // dummy assignements to avoid compiler warning + double d = 0.0, e = 0.0; - root_ = xMax_; - froot = fxMax_; - while (evaluationNumber_ <= maxEvaluations_) { - if ((froot > 0.0 && fxMax_ > 0.0) || - (froot < 0.0 && fxMax_ < 0.0)) { + root_ = xMax_; + froot = fxMax_; + while (evaluationNumber_ <= maxEvaluations_) + { + if ((froot > 0.0 && fxMax_ > 0.0) || + (froot < 0.0 && fxMax_ < 0.0)) + { - // Rename xMin_, root_, xMax_ and adjust bounds - xMax_ = xMin_; - fxMax_ = fxMin_; - e = d = root_ - xMin_; - } - if (Math.Abs(fxMax_) < Math.Abs(froot)) { - xMin_ = root_; - root_ = xMax_; - xMax_ = xMin_; - fxMin_ = froot; - froot = fxMax_; - fxMax_ = fxMin_; - } - // Convergence check - xAcc1 = 2.0 * Const.QL_EPSILON * Math.Abs(root_) + 0.5 * xAccuracy; - xMid = (xMax_ - root_) / 2.0; - if (Math.Abs(xMid) <= xAcc1 || Utils.close(froot , 0.0)) - return root_; - if (Math.Abs(e) >= xAcc1 && - Math.Abs(fxMin_) > Math.Abs(froot)) { + // Rename xMin_, root_, xMax_ and adjust bounds + xMax_ = xMin_; + fxMax_ = fxMin_; + e = d = root_ - xMin_; + } + if (Math.Abs(fxMax_) < Math.Abs(froot)) + { + xMin_ = root_; + root_ = xMax_; + xMax_ = xMin_; + fxMin_ = froot; + froot = fxMax_; + fxMax_ = fxMin_; + } + // Convergence check + xAcc1 = 2.0 * Const.QL_EPSILON * Math.Abs(root_) + 0.5 * xAccuracy; + xMid = (xMax_ - root_) / 2.0; + if (Math.Abs(xMid) <= xAcc1 || Utils.close(froot, 0.0)) + return root_; + if (Math.Abs(e) >= xAcc1 && + Math.Abs(fxMin_) > Math.Abs(froot)) + { - // Attempt inverse quadratic interpolation - s = froot / fxMin_; - if (Utils.close(xMin_, xMax_)) { - p = 2.0 * xMid * s; - q = 1.0 - s; - } else { - q = fxMin_ / fxMax_; - r = froot / fxMax_; - p = s * (2.0 * xMid * q * (q - r) - (root_ - xMin_) * (r - 1.0)); - q = (q - 1.0) * (r - 1.0) * (s - 1.0); - } - if (p > 0.0) q = -q; // Check whether in bounds - p = Math.Abs(p); - min1 = 3.0 * xMid * q - Math.Abs(xAcc1 * q); - min2 = Math.Abs(e * q); - if (2.0 * p < (min1 < min2 ? min1 : min2)) { - e = d; // Accept interpolation - d = p / q; - } else { - d = xMid; // Interpolation failed, use bisection - e = d; - } - } else { - // Bounds decreasing too slowly, use bisection - d = xMid; - e = d; - } - xMin_ = root_; - fxMin_ = froot; - if (Math.Abs(d) > xAcc1) - root_ += d; - else - root_ += Math.Abs(xAcc1) * Math.Sign(xMid); - froot = f.value(root_); - evaluationNumber_++; + // Attempt inverse quadratic interpolation + s = froot / fxMin_; + if (Utils.close(xMin_, xMax_)) + { + p = 2.0 * xMid * s; + q = 1.0 - s; + } + else + { + q = fxMin_ / fxMax_; + r = froot / fxMax_; + p = s * (2.0 * xMid * q * (q - r) - (root_ - xMin_) * (r - 1.0)); + q = (q - 1.0) * (r - 1.0) * (s - 1.0); + } + if (p > 0.0) + q = -q; // Check whether in bounds + p = Math.Abs(p); + min1 = 3.0 * xMid * q - Math.Abs(xAcc1 * q); + min2 = Math.Abs(e * q); + if (2.0 * p < (min1 < min2 ? min1 : min2)) + { + e = d; // Accept interpolation + d = p / q; + } + else + { + d = xMid; // Interpolation failed, use bisection + e = d; + } + } + else + { + // Bounds decreasing too slowly, use bisection + d = xMid; + e = d; } - throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded"); - } - } + xMin_ = root_; + fxMin_ = froot; + if (Math.Abs(d) > xAcc1) + root_ += d; + else + root_ += Math.Abs(xAcc1) * Math.Sign(xMid); + froot = f.value(root_); + evaluationNumber_++; + } + throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded"); + } + } } diff --git a/src/QLNet/Math/Solvers1d/FalsePosition.cs b/src/QLNet/Math/Solvers1d/FalsePosition.cs index 5f57b5ab4..a959d242e 100644 --- a/src/QLNet/Math/Solvers1d/FalsePosition.cs +++ b/src/QLNet/Math/Solvers1d/FalsePosition.cs @@ -1,70 +1,81 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - public class FalsePosition : Solver1D { - protected override double solveImpl(ISolver1d f, double xAccuracy) { - /* The implementation of the algorithm was inspired by - Press, Teukolsky, Vetterling, and Flannery, - "Numerical Recipes in C", 2nd edition, - Cambridge University Press - */ +namespace QLNet +{ + public class FalsePosition : Solver1D + { + protected override double solveImpl(ISolver1d f, double xAccuracy) + { + /* The implementation of the algorithm was inspired by + Press, Teukolsky, Vetterling, and Flannery, + "Numerical Recipes in C", 2nd edition, + Cambridge University Press + */ - double fl, fh, xl, xh, dx, del, froot; + double fl, fh, xl, xh, dx, del, froot; - // Identify the limits so that xl corresponds to the low side - if (fxMin_ < 0.0) { - xl = xMin_; - fl = fxMin_; - xh = xMax_; - fh = fxMax_; - } else { - xl = xMax_; - fl = fxMax_; - xh = xMin_; - fh = fxMin_; - } - dx = xh - xl ; + // Identify the limits so that xl corresponds to the low side + if (fxMin_ < 0.0) + { + xl = xMin_; + fl = fxMin_; + xh = xMax_; + fh = fxMax_; + } + else + { + xl = xMax_; + fl = fxMax_; + xh = xMin_; + fh = fxMin_; + } + dx = xh - xl ; - while (evaluationNumber_ <= maxEvaluations_) { - // Increment with respect to latest value - root_ = xl + dx*fl/(fl-fh); - froot = f.value(root_); - evaluationNumber_++; - if (froot < 0.0) { // Replace appropriate limit - del = xl - root_; - xl = root_; - fl = froot; - } else { - del = xh - root_; - xh = root_; - fh = froot; - } - dx = xh - xl; - // Convergence criterion - if (Math.Abs(del) < xAccuracy || Utils.close( froot , 0.0)) { - return root_; - } + while (evaluationNumber_ <= maxEvaluations_) + { + // Increment with respect to latest value + root_ = xl + dx * fl / (fl - fh); + froot = f.value(root_); + evaluationNumber_++; + if (froot < 0.0) // Replace appropriate limit + { + del = xl - root_; + xl = root_; + fl = froot; + } + else + { + del = xh - root_; + xh = root_; + fh = froot; + } + dx = xh - xl; + // Convergence criterion + if (Math.Abs(del) < xAccuracy || Utils.close(froot, 0.0)) + { + return root_; } - throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded"); - } - } + } + throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded"); + } + } } diff --git a/src/QLNet/Math/Solvers1d/FiniteDifferenceNewtonSafe.cs b/src/QLNet/Math/Solvers1d/FiniteDifferenceNewtonSafe.cs index c3da17413..69c073dd2 100644 --- a/src/QLNet/Math/Solvers1d/FiniteDifferenceNewtonSafe.cs +++ b/src/QLNet/Math/Solvers1d/FiniteDifferenceNewtonSafe.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,61 +20,68 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class FiniteDifferenceNewtonSafe : Solver1D - { - protected override double solveImpl(ISolver1d f, double xAccuracy) - { - // Orient the search so that f(xl) < 0 - double xh, xl; - if (fxMin_ < 0.0) { - xl = xMin_; - xh = xMax_; - } else { - xh = xMin_; - xl = xMax_; - } + public class FiniteDifferenceNewtonSafe : Solver1D + { + protected override double solveImpl(ISolver1d f, double xAccuracy) + { + // Orient the search so that f(xl) < 0 + double xh, xl; + if (fxMin_ < 0.0) + { + xl = xMin_; + xh = xMax_; + } + else + { + xh = xMin_; + xl = xMax_; + } - double froot = f.value(root_); - ++evaluationNumber_; - // first order finite difference derivative - double dfroot = xMax_-root_ < root_-xMin_ ? - (fxMax_-froot)/(xMax_-root_) : - (fxMin_-froot)/(xMin_-root_) ; + double froot = f.value(root_); + ++evaluationNumber_; + // first order finite difference derivative + double dfroot = xMax_ - root_ < root_ - xMin_ ? + (fxMax_ - froot) / (xMax_ - root_) : + (fxMin_ - froot) / (xMin_ - root_) ; - // xMax_-xMin_>0 is verified in the constructor - double dx = xMax_-xMin_; - while (evaluationNumber_<=maxEvaluations_) { - double frootold = froot; - double rootold = root_; - double dxold = dx; - // Bisect if (out of range || not decreasing fast enough) - if ((((root_-xh)*dfroot-froot)* - ((root_-xl)*dfroot-froot) > 0.0) - || (Math.Abs(2.0*froot) > Math.Abs(dxold*dfroot))) { + // xMax_-xMin_>0 is verified in the constructor + double dx = xMax_ - xMin_; + while (evaluationNumber_ <= maxEvaluations_) + { + double frootold = froot; + double rootold = root_; + double dxold = dx; + // Bisect if (out of range || not decreasing fast enough) + if ((((root_ - xh)*dfroot - froot)* + ((root_ - xl)*dfroot - froot) > 0.0) + || (Math.Abs(2.0 * froot) > Math.Abs(dxold * dfroot))) + { - dx = (xh-xl)/2.0; - root_ = xl+dx; - } else { // Newton - dx = froot/dfroot; - root_ -= dx; - } + dx = (xh - xl) / 2.0; + root_ = xl + dx; + } + else // Newton + { + dx = froot / dfroot; + root_ -= dx; + } - // Convergence criterion - if (Math.Abs(dx) < xAccuracy) - return root_; + // Convergence criterion + if (Math.Abs(dx) < xAccuracy) + return root_; - froot = f.value(root_); - ++evaluationNumber_; - dfroot = (frootold-froot)/(rootold-root_); + froot = f.value(root_); + ++evaluationNumber_; + dfroot = (frootold - froot) / (rootold - root_); - if (froot < 0.0) - xl=root_; - else - xh=root_; - } + if (froot < 0.0) + xl = root_; + else + xh = root_; + } - throw new ArgumentException( "maximum number of function evaluations (" + maxEvaluations_ + ") exceeded" ); + throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded"); - } - } + } + } } diff --git a/src/QLNet/Math/Solvers1d/Newton.cs b/src/QLNet/Math/Solvers1d/Newton.cs index 2bd570ad5..09c83dcd7 100644 --- a/src/QLNet/Math/Solvers1d/Newton.cs +++ b/src/QLNet/Math/Solvers1d/Newton.cs @@ -1,61 +1,66 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - //! %Newton 1-D solver - /*! \note This solver requires that the passed function object - implement a method Real derivative(Real). - */ - public class Newton : Solver1D { - protected override double solveImpl(ISolver1d f, double xAccuracy) { - /* The implementation of the algorithm was inspired by Press, Teukolsky, Vetterling, and Flannery, - "Numerical Recipes in C", 2nd edition, Cambridge University Press */ +namespace QLNet +{ + //! %Newton 1-D solver + /*! \note This solver requires that the passed function object + implement a method Real derivative(Real). + */ + public class Newton : Solver1D + { + protected override double solveImpl(ISolver1d f, double xAccuracy) + { + /* The implementation of the algorithm was inspired by Press, Teukolsky, Vetterling, and Flannery, + "Numerical Recipes in C", 2nd edition, Cambridge University Press */ - double froot, dfroot, dx; + double froot, dfroot, dx; - froot = f.value(root_); - dfroot = f.derivative(root_); + froot = f.value(root_); + dfroot = f.derivative(root_); + + if (dfroot.IsEqual(default(double))) + throw new ArgumentException("Newton requires function's derivative"); + ++evaluationNumber_; - if (dfroot.IsEqual(default(double))) - throw new ArgumentException("Newton requires function's derivative"); - ++evaluationNumber_; - - while (evaluationNumber_<=maxEvaluations_) { - dx=froot/dfroot; - root_ -= dx; - // jumped out of brackets, switch to NewtonSafe - if ((xMin_-root_)*(root_-xMax_) < 0.0) { - NewtonSafe s = new NewtonSafe(); - s.setMaxEvaluations(maxEvaluations_-evaluationNumber_); - return s.solve(f, xAccuracy, root_+dx, xMin_, xMax_); - } - if (Math.Abs(dx) < xAccuracy) - return root_; - froot = f.value(root_); - dfroot = f.derivative(root_); - evaluationNumber_++; + while (evaluationNumber_ <= maxEvaluations_) + { + dx = froot / dfroot; + root_ -= dx; + // jumped out of brackets, switch to NewtonSafe + if ((xMin_ - root_) * (root_ - xMax_) < 0.0) + { + NewtonSafe s = new NewtonSafe(); + s.setMaxEvaluations(maxEvaluations_ - evaluationNumber_); + return s.solve(f, xAccuracy, root_ + dx, xMin_, xMax_); } + if (Math.Abs(dx) < xAccuracy) + return root_; + froot = f.value(root_); + dfroot = f.derivative(root_); + evaluationNumber_++; + } - Utils.QL_FAIL("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded"); - return 0; - } - } + Utils.QL_FAIL("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded"); + return 0; + } + } } diff --git a/src/QLNet/Math/Solvers1d/Newtonsafe.cs b/src/QLNet/Math/Solvers1d/Newtonsafe.cs index ba037fbcc..c0b08fcba 100644 --- a/src/QLNet/Math/Solvers1d/Newtonsafe.cs +++ b/src/QLNet/Math/Solvers1d/Newtonsafe.cs @@ -1,88 +1,98 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - public class NewtonSafe : Solver1D { - //! safe %Newton 1-D solver - /*! \note This solver requires that the passed function object - implement a method Real derivative(Real). - */ - protected override double solveImpl(ISolver1d f, double xAccuracy) { - /* The implementation of the algorithm was inspired by Press, Teukolsky, Vetterling, and Flannery, - "Numerical Recipes in C", 2nd edition, Cambridge University Press */ +namespace QLNet +{ + public class NewtonSafe : Solver1D + { + //! safe %Newton 1-D solver + /*! \note This solver requires that the passed function object + implement a method Real derivative(Real). + */ + protected override double solveImpl(ISolver1d f, double xAccuracy) + { + /* The implementation of the algorithm was inspired by Press, Teukolsky, Vetterling, and Flannery, + "Numerical Recipes in C", 2nd edition, Cambridge University Press */ - double froot, dfroot, dx, dxold; - double xh, xl; + double froot, dfroot, dx, dxold; + double xh, xl; - // Orient the search so that f(xl) < 0 - if (fxMin_ < 0.0) { - xl=xMin_; - xh=xMax_; - } else { - xh=xMin_; - xl=xMax_; - } + // Orient the search so that f(xl) < 0 + if (fxMin_ < 0.0) + { + xl = xMin_; + xh = xMax_; + } + else + { + xh = xMin_; + xl = xMax_; + } - // the "stepsize before last" - dxold=xMax_-xMin_; - // it was dxold=std::fabs(xMax_-xMin_); in Numerical Recipes - // here (xMax_-xMin_ > 0) is verified in the constructor + // the "stepsize before last" + dxold = xMax_ - xMin_; + // it was dxold=std::fabs(xMax_-xMin_); in Numerical Recipes + // here (xMax_-xMin_ > 0) is verified in the constructor - // and the last step - dx=dxold; + // and the last step + dx = dxold; - froot = f.value(root_); - dfroot = f.derivative(root_); - if (dfroot.IsEqual(default(double))) - throw new ArgumentException("Newton requires function's derivative"); - ++evaluationNumber_; + froot = f.value(root_); + dfroot = f.derivative(root_); + if (dfroot.IsEqual(default(double))) + throw new ArgumentException("Newton requires function's derivative"); + ++evaluationNumber_; - while (evaluationNumber_<=maxEvaluations_) { - // Bisect if (out of range || not decreasing fast enough) - if ((((root_-xh)*dfroot-froot)* - ((root_-xl)*dfroot-froot) > 0.0) - || (Math.Abs(2.0*froot) > Math.Abs(dxold*dfroot))) { + while (evaluationNumber_ <= maxEvaluations_) + { + // Bisect if (out of range || not decreasing fast enough) + if ((((root_ - xh)*dfroot - froot)* + ((root_ - xl)*dfroot - froot) > 0.0) + || (Math.Abs(2.0 * froot) > Math.Abs(dxold * dfroot))) + { - dxold = dx; - dx = (xh-xl)/2.0; - root_=xl+dx; - } else { - dxold=dx; - dx=froot/dfroot; - root_ -= dx; - } - // Convergence criterion - if (Math.Abs(dx) < xAccuracy) - return root_; - froot = f.value(root_); - dfroot = f.derivative(root_); - evaluationNumber_++; - if (froot < 0.0) - xl=root_; - else - xh=root_; + dxold = dx; + dx = (xh - xl) / 2.0; + root_ = xl + dx; + } + else + { + dxold = dx; + dx = froot / dfroot; + root_ -= dx; } + // Convergence criterion + if (Math.Abs(dx) < xAccuracy) + return root_; + froot = f.value(root_); + dfroot = f.derivative(root_); + evaluationNumber_++; + if (froot < 0.0) + xl = root_; + else + xh = root_; + } - Utils.QL_FAIL("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded"); - return 0; - } - } + Utils.QL_FAIL("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded"); + return 0; + } + } } diff --git a/src/QLNet/Math/Solvers1d/Ridder.cs b/src/QLNet/Math/Solvers1d/Ridder.cs index 4f7e5a9fc..606683ad7 100644 --- a/src/QLNet/Math/Solvers1d/Ridder.cs +++ b/src/QLNet/Math/Solvers1d/Ridder.cs @@ -1,91 +1,102 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - public class Ridder : Solver1D { - protected override double solveImpl(ISolver1d f, double xAcc) - { - - /* The implementation of the algorithm was inspired by - Press, Teukolsky, Vetterling, and Flannery, - "Numerical Recipes in C", 2nd edition, Cambridge - University Press - */ +namespace QLNet +{ + public class Ridder : Solver1D + { + protected override double solveImpl(ISolver1d f, double xAcc) + { - double fxMid, froot, s, xMid, nextRoot; + /* The implementation of the algorithm was inspired by + Press, Teukolsky, Vetterling, and Flannery, + "Numerical Recipes in C", 2nd edition, Cambridge + University Press + */ - // test on Black-Scholes implied volatility show that - // Ridder solver algorithm actually provides an - // accuracy 100 times below promised - double xAccuracy = xAcc/100.0; + double fxMid, froot, s, xMid, nextRoot; - // Any highly unlikely value, to simplify logic below - root_ = double.MinValue; + // test on Black-Scholes implied volatility show that + // Ridder solver algorithm actually provides an + // accuracy 100 times below promised + double xAccuracy = xAcc / 100.0; - while (evaluationNumber_ <= maxEvaluations_) { - xMid = 0.5*(xMin_ + xMax_); - // First of two function evaluations per iteraton - fxMid = f.value(xMid); - ++evaluationNumber_; - s = Math.Sqrt(fxMid*fxMid - fxMin_*fxMax_); - if (Utils.close(s , 0.0)) - return root_; - // Updating formula - nextRoot = xMid + (xMid - xMin_) * - ((fxMin_ >= fxMax_ ? 1.0 : -1.0) * fxMid / s); - if (Math.Abs(nextRoot-root_) <= xAccuracy) - return root_; + // Any highly unlikely value, to simplify logic below + root_ = double.MinValue; - root_ = nextRoot; - // Second of two function evaluations per iteration - froot = f.value(root_); - ++evaluationNumber_; - if (Utils.close(froot , 0.0)) - return root_; + while (evaluationNumber_ <= maxEvaluations_) + { + xMid = 0.5 * (xMin_ + xMax_); + // First of two function evaluations per iteraton + fxMid = f.value(xMid); + ++evaluationNumber_; + s = Math.Sqrt(fxMid * fxMid - fxMin_ * fxMax_); + if (Utils.close(s, 0.0)) + return root_; + // Updating formula + nextRoot = xMid + (xMid - xMin_) * + ((fxMin_ >= fxMax_ ? 1.0 : -1.0) * fxMid / s); + if (Math.Abs(nextRoot - root_) <= xAccuracy) + return root_; - // Bookkeeping to keep the root bracketed on next iteration - if (sign(fxMid,froot).IsNotEqual(fxMid)) { - xMin_ = xMid; - fxMin_ = fxMid; - xMax_ = root_; - fxMax_ = froot; - } else if (sign(fxMin_,froot).IsNotEqual(fxMin_)) { - xMax_ = root_; - fxMax_ = froot; - } else if (sign(fxMax_,froot).IsNotEqual(fxMax_)) { - xMin_ = root_; - fxMin_ = froot; - } else { - Utils.QL_FAIL("never get here."); - } + root_ = nextRoot; + // Second of two function evaluations per iteration + froot = f.value(root_); + ++evaluationNumber_; + if (Utils.close(froot, 0.0)) + return root_; - if (Math.Abs(xMax_-xMin_) <= xAccuracy) return root_; + // Bookkeeping to keep the root bracketed on next iteration + if (sign(fxMid, froot).IsNotEqual(fxMid)) + { + xMin_ = xMid; + fxMin_ = fxMid; + xMax_ = root_; + fxMax_ = froot; } + else if (sign(fxMin_, froot).IsNotEqual(fxMin_)) + { + xMax_ = root_; + fxMax_ = froot; + } + else if (sign(fxMax_, froot).IsNotEqual(fxMax_)) + { + xMin_ = root_; + fxMin_ = froot; + } + else + { + Utils.QL_FAIL("never get here."); + } + + if (Math.Abs(xMax_ - xMin_) <= xAccuracy) + return root_; + } - throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded"); - } - private double sign(double a, double b) - { - return b >= 0.0 ? Math.Abs(a) : -Math.Abs(a); - } + throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded"); + } + private double sign(double a, double b) + { + return b >= 0.0 ? Math.Abs(a) : -Math.Abs(a); + } - } + } } diff --git a/src/QLNet/Math/Solvers1d/Secant.cs b/src/QLNet/Math/Solvers1d/Secant.cs index 8bcb4bc53..c6518f363 100644 --- a/src/QLNet/Math/Solvers1d/Secant.cs +++ b/src/QLNet/Math/Solvers1d/Secant.cs @@ -1,61 +1,68 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - public class Secant : Solver1D { - protected override double solveImpl(ISolver1d f, double xAccuracy) { - - /* The implementation of the algorithm was inspired by - Press, Teukolsky, Vetterling, and Flannery, - "Numerical Recipes in C", 2nd edition, Cambridge - University Press - */ - - double fl, froot, dx, xl; - - // Pick the bound with the smaller function value - // as the most recent guess - if (Math.Abs(fxMin_) < Math.Abs(fxMax_)) { - root_ = xMin_; - froot = fxMin_; - xl = xMax_; - fl = fxMax_; - } else { - root_ = xMax_; - froot = fxMax_; - xl = xMin_; - fl = fxMin_; - } - while (evaluationNumber_ <= maxEvaluations_) { - dx = (xl-root_)*froot/(froot-fl); - xl = root_; - fl = froot; - root_ += dx; - froot = f.value(root_); - ++evaluationNumber_; - if (Math.Abs(dx) < xAccuracy || Utils.close(froot , 0.0)) - return root_; - } - - throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded"); - } - } +namespace QLNet +{ + public class Secant : Solver1D + { + protected override double solveImpl(ISolver1d f, double xAccuracy) + { + + /* The implementation of the algorithm was inspired by + Press, Teukolsky, Vetterling, and Flannery, + "Numerical Recipes in C", 2nd edition, Cambridge + University Press + */ + + double fl, froot, dx, xl; + + // Pick the bound with the smaller function value + // as the most recent guess + if (Math.Abs(fxMin_) < Math.Abs(fxMax_)) + { + root_ = xMin_; + froot = fxMin_; + xl = xMax_; + fl = fxMax_; + } + else + { + root_ = xMax_; + froot = fxMax_; + xl = xMin_; + fl = fxMin_; + } + while (evaluationNumber_ <= maxEvaluations_) + { + dx = (xl - root_) * froot / (froot - fl); + xl = root_; + fl = froot; + root_ += dx; + froot = f.value(root_); + ++evaluationNumber_; + if (Math.Abs(dx) < xAccuracy || Utils.close(froot, 0.0)) + return root_; + } + + throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded"); + } + } } diff --git a/src/QLNet/Math/TransformedGrid.cs b/src/QLNet/Math/TransformedGrid.cs new file mode 100644 index 000000000..f6efbdcb2 --- /dev/null +++ b/src/QLNet/Math/TransformedGrid.cs @@ -0,0 +1,90 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! transformed grid + /*! This package encapuslates an array of grid points. It is used primarily in PDE calculations. + */ + public class TransformedGrid + { + protected Vector grid_; + protected Vector transformedGrid_; + protected Vector dxm_; + protected Vector dxp_; + protected Vector dx_; + + public Vector gridArray() { return grid_;} + public Vector transformedGridArray() { return transformedGrid_;} + public Vector dxmArray() { return dxm_;} + public Vector dxpArray() { return dxp_;} + public Vector dxArray() { return dx_;} + + public TransformedGrid(Vector grid) + { + grid_ = grid.Clone(); + transformedGrid_ = grid.Clone(); + dxm_ = new Vector(grid.size()); + dxp_ = new Vector(grid.size()); + dx_ = new Vector(grid.size()); + + for (int i = 1; i < transformedGrid_.size() - 1 ; i++) + { + dxm_[i] = transformedGrid_[i] - transformedGrid_[i - 1]; + dxp_[i] = transformedGrid_[i + 1] - transformedGrid_[i]; + dx_[i] = dxm_[i] + dxp_[i]; + } + } + + public TransformedGrid(Vector grid, Func func) + { + grid_ = grid.Clone(); + transformedGrid_ = new Vector(grid.size()); + dxm_ = new Vector(grid.size()); + dxp_ = new Vector(grid.size()); + dx_ = new Vector(grid.size()); + + for (int i = 0; i < grid.size(); i++) + transformedGrid_[i] = func(grid_[i]); + + for (int i = 1; i < transformedGrid_.size() - 1 ; i++) + { + dxm_[i] = transformedGrid_[i] - transformedGrid_[i - 1]; + dxp_[i] = transformedGrid_[i + 1] - transformedGrid_[i]; + dx_[i] = dxm_[i] + dxp_[i]; + } + } + + public double grid(int i) { return grid_[i]; } + public double transformedGrid(int i) { return transformedGrid_[i]; } + public double dxm(int i) { return dxm_[i];} + public double dxp(int i) { return dxp_[i]; } + public double dx(int i) { return dx_[i]; } + public int size() {return grid_.size();} + } + + public class LogGrid : TransformedGrid + { + public LogGrid(Vector grid) : base(grid, Math.Log) {} + + public Vector logGridArray() { return transformedGridArray();} + public double logGrid(int i) { return transformedGrid(i);} + } +} diff --git a/src/QLNet/Math/Vector.cs b/src/QLNet/Math/Vector.cs index b340fca4d..745646a6b 100644 --- a/src/QLNet/Math/Vector.cs +++ b/src/QLNet/Math/Vector.cs @@ -2,18 +2,18 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - * + * This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -51,7 +51,7 @@ public Vector(int size, double value) : base(size, value) {} /// - /// Creates the vector and fills it according to + /// Creates the vector and fills it according to /// Vector[0] = value /// Vector[i]=Vector[i-1]+increment /// @@ -108,12 +108,16 @@ Object ICloneable.Clone() /// public bool Equals(Vector other) { - if (other == null) return false; - if (ReferenceEquals(this, other)) return true; - if (Count != other.Count) return false; + if (other == null) + return false; + if (ReferenceEquals(this, other)) + return true; + if (Count != other.Count) + return false; for (int i = 0; i < Count; i++) - if (other[i].IsNotEqual(this[i])) return false; + if (other[i].IsNotEqual(this[i])) + return false; return true; } @@ -183,12 +187,12 @@ public bool empty() public static Vector operator +(double value, Vector v1) { - return operValue(v1, value, (x, y) => x + y); + return operValue(v1, value, (x, y) => x + y); } public static Vector operator -(double value, Vector v1) { - return operValue(v1, value, (x, y) => y - x); + return operValue(v1, value, (x, y) => y - x); } public static Vector operator *(double value, Vector v1) @@ -209,7 +213,7 @@ public bool empty() internal static Vector operVector(Vector v1, Vector v2, Func func) { Utils.QL_REQUIRE(v1.Count == v2.Count, () => - "operation on vectors with different sizes (" + v1.Count + ", " + v2.Count); + "operation on vectors with different sizes (" + v1.Count + ", " + v2.Count); Vector temp = new Vector(v1.Count); for (int i = 0; i < v1.Count; i++) @@ -228,7 +232,7 @@ private static Vector operValue(Vector v1, double value, Func - "operation on vectors with different sizes (" + v1.Count + ", " + v2.Count); + "operation on vectors with different sizes (" + v1.Count + ", " + v2.Count); double result = 0; for (int i = 0; i < v1.Count; i++) @@ -248,7 +252,7 @@ public static double DotProduct(Vector v1, Vector v2) public static double Norm2(Vector v) { - return Math.Sqrt(v * v); + return Math.Sqrt(v * v); } public static Vector DirectMultiply(Vector v1, Vector v2) @@ -272,9 +276,9 @@ public static Vector Abs(Vector v) public static Vector Exp(Vector v) { - Vector result = new Vector(v.size()); - result.ForEach((i, x) => result[i] = Math.Exp(v[i])); - return result; + Vector result = new Vector(v.size()); + result.ForEach((i, x) => result[i] = Math.Exp(v[i])); + return result; } public void swap(int i1, int i2) diff --git a/src/QLNet/Math/beta.cs b/src/QLNet/Math/beta.cs deleted file mode 100644 index 0be54b52f..000000000 --- a/src/QLNet/Math/beta.cs +++ /dev/null @@ -1,100 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - public partial class Utils { - public static double betaFunction(double z, double w) { - return Math.Exp(GammaFunction.logValue(z) + - GammaFunction.logValue(w) - - GammaFunction.logValue(z+w)); - } - - public static double betaContinuedFraction(double a, double b, double x) { - return betaContinuedFraction(a, b, x, 1e-16, 100); - } - public static double betaContinuedFraction(double a, double b, double x, double accuracy, int maxIteration) { - double aa, del; - double qab = a+b; - double qap = a+1.0; - double qam = a-1.0; - double c = 1.0; - double d = 1.0-qab*x/qap; - if (Math.Abs(d) < Const.QL_EPSILON) - d = Const.QL_EPSILON; - d = 1.0/d; - double result = d; - - int m, m2; - for (m=1; m<=maxIteration; m++) { - m2=2*m; - aa=m*(b-m)*x/((qam+m2)*(a+m2)); - d=1.0+aa*d; - if (Math.Abs(d) < Const.QL_EPSILON) d=Const.QL_EPSILON; - c=1.0+aa/c; - if (Math.Abs(c) < Const.QL_EPSILON) c=Const.QL_EPSILON; - d=1.0/d; - result *= d*c; - aa = -(a+m)*(qab+m)*x/((a+m2)*(qap+m2)); - d=1.0+aa*d; - if (Math.Abs(d) < Const.QL_EPSILON) d=Const.QL_EPSILON; - c=1.0+aa/c; - if (Math.Abs(c) < Const.QL_EPSILON) c=Const.QL_EPSILON; - d=1.0/d; - del=d*c; - result *= del; - if (Math.Abs(del-1.0) < accuracy) - return result; - } - Utils.QL_FAIL("a or b too big, or maxIteration too small in betacf"); - return 0; - } - - /*! Incomplete Beta function - - The implementation of the algorithm was inspired by - "Numerical Recipes in C", 2nd edition, - Press, Teukolsky, Vetterling, Flannery, chapter 6 - */ - public static double incompleteBetaFunction(double a, double b, double x) { - return incompleteBetaFunction(a, b, x, 1e-16, 100); - } - public static double incompleteBetaFunction(double a, double b, double x, double accuracy, int maxIteration) { - - QL_REQUIRE(a > 0.0,()=> "a must be greater than zero"); - QL_REQUIRE(b > 0.0,()=> "b must be greater than zero"); - - if (x.IsEqual(0.0)) - return 0.0; - if (x.IsEqual(1.0)) - return 1.0; - QL_REQUIRE(x>0.0 && x<1.0,()=> "x must be in [0,1]"); - - double result = Math.Exp(GammaFunction.logValue(a+b) - - GammaFunction.logValue(a) - GammaFunction.logValue(b) + - a*Math.Log(x) + b*Math.Log(1.0-x)); - - if (x < (a+1.0)/(a+b+2.0)) - return result * - betaContinuedFraction(a, b, x, accuracy, maxIteration)/a; - return 1.0 - result * - betaContinuedFraction(b, a, 1.0-x, accuracy, maxIteration)/b; - } - } -} diff --git a/src/QLNet/Math/factorial.cs b/src/QLNet/Math/factorial.cs deleted file mode 100644 index c4a55e17d..000000000 --- a/src/QLNet/Math/factorial.cs +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! %Factorial numbers calculator - /*! \test the correctness of the returned value is tested by - checking it against numerical calculations. - */ - public static class Factorial { - public static double get(uint i) { - if (i<=tabulated) { - return firstFactorials[i]; - } else { - return Math.Exp(GammaFunction.logValue(i+1)); - } - } - - public static double ln(int i) { - if (i<=tabulated) { - return Math.Log(firstFactorials[i]); - } else { - return GammaFunction.logValue(i+1); - } - } - - static double[] firstFactorials = { - 1.0, 1.0, - 2.0, 6.0, - 24.0, 120.0, - 720.0, 5040.0, - 40320.0, 362880.0, - 3628800.0, 39916800.0, - 479001600.0, 6227020800.0, - 87178291200.0, 1307674368000.0, - 20922789888000.0, 355687428096000.0, - 6402373705728000.0, 121645100408832000.0, - 2432902008176640000.0, 51090942171709440000.0, - 1124000727777607680000.0, 25852016738884976640000.0, - 620448401733239439360000.0, 15511210043330985984000000.0, - 403291461126605635584000000.0, 10888869450418352160768000000.0 - }; - - static int tabulated = firstFactorials.Length - 1; - } -} diff --git a/src/QLNet/Math/integrals/DiscreteIntegrals.cs b/src/QLNet/Math/integrals/DiscreteIntegrals.cs index 1b06f4921..f64a2005b 100644 --- a/src/QLNet/Math/integrals/DiscreteIntegrals.cs +++ b/src/QLNet/Math/integrals/DiscreteIntegrals.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,86 +23,87 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - /*! References: - Levy, D. Numerical Integration - http://www2.math.umd.edu/~dlevy/classes/amsc466/lecture-notes/integration-chap.pdf - */ - public class DiscreteTrapezoidIntegral - { - public double value(Vector x, Vector f) - { - int n = f.size(); - Utils.QL_REQUIRE(n == x.size(), () => "inconsistent size"); - - double acc = 0; - - for (int i=0; i < n-1; ++i) { - acc += ((x[i+1]-x[i])*(f[i]+f[i+1])); - } - - return 0.5*acc; - } - } - public class DiscreteSimpsonIntegral - { - public double value(Vector x, Vector f) - { - int n = f.size(); - Utils.QL_REQUIRE(n == x.size(), () => "inconsistent size"); - - double acc = 0; - - for (int j = 0; j < n - 2; j += 2) - { - double dxj = x[j + 1] - x[j]; - double dxjp1 = x[j + 2] - x[j + 1]; - - double alpha = -dxjp1 * (2 * x[j] - 3 * x[j + 1] + x[j + 2]); - double dd = x[j + 2] - x[j]; - double k = dd / (6 * dxjp1 * dxj); - double beta = dd * dd; - double gamma = dxj * (x[j] - 3 * x[j + 1] + 2 * x[j + 2]); - - acc += (k * alpha * f[j] + k * beta * f[j + 1] + k * gamma * f[j + 2]); - } - if (!((n & 1) == 1)) - { - acc += (0.5 * (x[n - 1] - x[n - 2]) * (f[n - 1] + f[n - 2])); - } - - return acc; - } - } - public class DiscreteTrapezoidIntegrator : Integrator - { - public DiscreteTrapezoidIntegrator(int evaluations) - : base(null, evaluations) - { } - - protected override double integrate(Func f, double a, double b) - { - Vector x = new Vector(maxEvaluations(), a, (b-a)/(maxEvaluations()-1)); - Vector fv = new Vector(x.size()); - x.ForEach((g,gg) => fv[g] = f(gg)); - - increaseNumberOfEvaluations(maxEvaluations()); - return new DiscreteTrapezoidIntegral().value(x, fv); - } - } - public class DiscreteSimpsonIntegrator : Integrator - { - public DiscreteSimpsonIntegrator(int evaluations) - : base(null, evaluations) - { } - - protected override double integrate(Func f, double a, double b) - { - Vector x = new Vector(maxEvaluations(), a, (b - a) / (maxEvaluations() - 1)); - Vector fv = new Vector(x.size()); - x.ForEach((g, gg) => fv[g] = f(gg)); - - increaseNumberOfEvaluations(maxEvaluations()); - return new DiscreteSimpsonIntegral().value(x, fv); - } - } + /*! References: + Levy, D. Numerical Integration + http://www2.math.umd.edu/~dlevy/classes/amsc466/lecture-notes/integration-chap.pdf + */ + public class DiscreteTrapezoidIntegral + { + public double value(Vector x, Vector f) + { + int n = f.size(); + Utils.QL_REQUIRE(n == x.size(), () => "inconsistent size"); + + double acc = 0; + + for (int i = 0; i < n - 1; ++i) + { + acc += ((x[i + 1] - x[i]) * (f[i] + f[i + 1])); + } + + return 0.5 * acc; + } + } + public class DiscreteSimpsonIntegral + { + public double value(Vector x, Vector f) + { + int n = f.size(); + Utils.QL_REQUIRE(n == x.size(), () => "inconsistent size"); + + double acc = 0; + + for (int j = 0; j < n - 2; j += 2) + { + double dxj = x[j + 1] - x[j]; + double dxjp1 = x[j + 2] - x[j + 1]; + + double alpha = -dxjp1 * (2 * x[j] - 3 * x[j + 1] + x[j + 2]); + double dd = x[j + 2] - x[j]; + double k = dd / (6 * dxjp1 * dxj); + double beta = dd * dd; + double gamma = dxj * (x[j] - 3 * x[j + 1] + 2 * x[j + 2]); + + acc += (k * alpha * f[j] + k * beta * f[j + 1] + k * gamma * f[j + 2]); + } + if (!((n & 1) == 1)) + { + acc += (0.5 * (x[n - 1] - x[n - 2]) * (f[n - 1] + f[n - 2])); + } + + return acc; + } + } + public class DiscreteTrapezoidIntegrator : Integrator + { + public DiscreteTrapezoidIntegrator(int evaluations) + : base(null, evaluations) + { } + + protected override double integrate(Func f, double a, double b) + { + Vector x = new Vector(maxEvaluations(), a, (b - a) / (maxEvaluations() - 1)); + Vector fv = new Vector(x.size()); + x.ForEach((g, gg) => fv[g] = f(gg)); + + increaseNumberOfEvaluations(maxEvaluations()); + return new DiscreteTrapezoidIntegral().value(x, fv); + } + } + public class DiscreteSimpsonIntegrator : Integrator + { + public DiscreteSimpsonIntegrator(int evaluations) + : base(null, evaluations) + { } + + protected override double integrate(Func f, double a, double b) + { + Vector x = new Vector(maxEvaluations(), a, (b - a) / (maxEvaluations() - 1)); + Vector fv = new Vector(x.size()); + x.ForEach((g, gg) => fv[g] = f(gg)); + + increaseNumberOfEvaluations(maxEvaluations()); + return new DiscreteSimpsonIntegral().value(x, fv); + } + } } diff --git a/src/QLNet/Math/integrals/GaussLobattoIntegral.cs b/src/QLNet/Math/integrals/GaussLobattoIntegral.cs index 7fa7b2e49..1ee171362 100644 --- a/src/QLNet/Math/integrals/GaussLobattoIntegral.cs +++ b/src/QLNet/Math/integrals/GaussLobattoIntegral.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -35,132 +35,132 @@ The original MATLAB version can be downloaded here */ public class GaussLobattoIntegral : Integrator { - - public GaussLobattoIntegral( int maxIterations, - double? absAccuracy, - double? relAccuracy = null, - bool useConvergenceEstimate = true) - :base(absAccuracy, maxIterations) + + public GaussLobattoIntegral(int maxIterations, + double? absAccuracy, + double? relAccuracy = null, + bool useConvergenceEstimate = true) + : base(absAccuracy, maxIterations) { relAccuracy_ = relAccuracy; useConvergenceEstimate_ = useConvergenceEstimate; } - protected override double integrate (Func f, double a, double b) + protected override double integrate(Func f, double a, double b) { - setNumberOfEvaluations( 0 ); - double calcAbsTolerance = calculateAbsTolerance( f, a, b ); + setNumberOfEvaluations(0); + double calcAbsTolerance = calculateAbsTolerance(f, a, b); - increaseNumberOfEvaluations( 2 ); - return adaptivGaussLobattoStep( f, a, b, f( a ), f( b ), calcAbsTolerance ); + increaseNumberOfEvaluations(2); + return adaptivGaussLobattoStep(f, a, b, f(a), f(b), calcAbsTolerance); } - protected double adaptivGaussLobattoStep(Func f,double a, double b, double fa, double fb, double acc) + protected double adaptivGaussLobattoStep(Func f, double a, double b, double fa, double fb, double acc) { - Utils.QL_REQUIRE(numberOfEvaluations() < maxEvaluations(),()=> "max number of iterations reached"); - - double h=(b-a)/2; - double m=(a+b)/2; - - double mll=m-alpha_*h; - double ml =m-beta_*h; - double mr =m+beta_*h; - double mrr=m+alpha_*h; - - double fmll= f(mll); + Utils.QL_REQUIRE(numberOfEvaluations() < maxEvaluations(), () => "max number of iterations reached"); + + double h = (b - a) / 2; + double m = (a + b) / 2; + + double mll = m - alpha_*h; + double ml = m - beta_*h; + double mr = m + beta_*h; + double mrr = m + alpha_*h; + + double fmll = f(mll); double fml = f(ml); double fm = f(m); double fmr = f(mr); - double fmrr= f(mrr); + double fmrr = f(mrr); increaseNumberOfEvaluations(5); - - double integral2=(h/6)*(fa+fb+5*(fml+fmr)); - double integral1=(h/1470)*(77*(fa+fb) - +432*(fmll+fmrr)+625*(fml+fmr)+672*fm); - + + double integral2 = (h / 6)*(fa + fb + 5 * (fml + fmr)); + double integral1 = (h / 1470)*(77 * (fa + fb) + + 432 * (fmll + fmrr) + 625 * (fml + fmr) + 672 * fm); + // avoid 80 bit logic on x86 cpu - double dist = acc + (integral1-integral2); - if( dist.IsEqual(acc) || mll<=a || b<=mrr) + double dist = acc + (integral1 - integral2); + if(dist.IsEqual(acc) || mll <= a || b <= mrr) { - Utils.QL_REQUIRE(m>a && b>m,()=> "Interval contains no more machine number"); + Utils.QL_REQUIRE(m>a&& b > m, () => "Interval contains no more machine number"); return integral1; } - else + else { - return adaptivGaussLobattoStep(f,a,mll,fa,fmll,acc) - + adaptivGaussLobattoStep(f,mll,ml,fmll,fml,acc) - + adaptivGaussLobattoStep(f,ml,m,fml,fm,acc) - + adaptivGaussLobattoStep(f,m,mr,fm,fmr,acc) - + adaptivGaussLobattoStep(f,mr,mrr,fmr,fmrr,acc) - + adaptivGaussLobattoStep(f,mrr,b,fmrr,fb,acc); + return adaptivGaussLobattoStep(f, a, mll, fa, fmll, acc) + + adaptivGaussLobattoStep(f, mll, ml, fmll, fml, acc) + + adaptivGaussLobattoStep(f, ml, m, fml, fm, acc) + + adaptivGaussLobattoStep(f, m, mr, fm, fmr, acc) + + adaptivGaussLobattoStep(f, mr, mrr, fmr, fmrr, acc) + + adaptivGaussLobattoStep(f, mrr, b, fmrr, fb, acc); } } - protected double calculateAbsTolerance( Func f, double a, double b ) + protected double calculateAbsTolerance(Func f, double a, double b) { double relTol = Math.Max(relAccuracy_ ?? 0, Const.QL_EPSILON); - - double m = (a+b)/2; - double h = (b-a)/2; + + double m = (a + b) / 2; + double h = (b - a) / 2; double y1 = f(a); - double y3 = f(m-alpha_*h); - double y5 = f(m-beta_*h); + double y3 = f(m - alpha_ * h); + double y5 = f(m - beta_ * h); double y7 = f(m); - double y9 = f(m+beta_*h); - double y11= f(m+alpha_*h); - double y13= f(b); - - double f1 = f(m-x1_*h); - double f2 = f(m+x1_*h); - double f3 = f(m-x2_*h); - double f4 = f(m+x2_*h); - double f5 = f(m-x3_*h); - double f6 = f(m+x3_*h); - - double acc=h*(0.0158271919734801831*(y1+y13) - +0.0942738402188500455*(f1+f2) - +0.1550719873365853963*(y3+y11) - +0.1888215739601824544*(f3+f4) - +0.1997734052268585268*(y5+y9) - +0.2249264653333395270*(f5+f6) - +0.2426110719014077338*y7); - + double y9 = f(m + beta_ * h); + double y11 = f(m + alpha_ * h); + double y13 = f(b); + + double f1 = f(m - x1_ * h); + double f2 = f(m + x1_ * h); + double f3 = f(m - x2_ * h); + double f4 = f(m + x2_ * h); + double f5 = f(m - x3_ * h); + double f6 = f(m + x3_ * h); + + double acc = h * (0.0158271919734801831 * (y1 + y13) + + 0.0942738402188500455 * (f1 + f2) + + 0.1550719873365853963 * (y3 + y11) + + 0.1888215739601824544 * (f3 + f4) + + 0.1997734052268585268 * (y5 + y9) + + 0.2249264653333395270 * (f5 + f6) + + 0.2426110719014077338 * y7); + increaseNumberOfEvaluations(13); - if (acc.IsEqual(0.0) && ( f1.IsNotEqual(0.0) || f2.IsNotEqual(0.0) || f3.IsNotEqual(0.0) - || f4.IsNotEqual(0.0) || f5.IsNotEqual(0.0) || f6.IsNotEqual(0.0))) + if (acc.IsEqual(0.0) && (f1.IsNotEqual(0.0) || f2.IsNotEqual(0.0) || f3.IsNotEqual(0.0) + || f4.IsNotEqual(0.0) || f5.IsNotEqual(0.0) || f6.IsNotEqual(0.0))) { Utils.QL_FAIL("can not calculate absolute accuracy from relative accuracy"); } double r = 1.0; - if (useConvergenceEstimate_) + if (useConvergenceEstimate_) { - double integral2 = (h/6)*(y1+y13+5*(y5+y9)); - double integral1 = (h/1470)*(77*(y1+y13)+432*(y3+y11)+ - 625*(y5+y9)+672*y7); - - if (Math.Abs(integral2-acc).IsNotEqual(0.0)) - r = Math.Abs(integral1-acc)/Math.Abs(integral2-acc); + double integral2 = (h / 6) * (y1 + y13 + 5 * (y5 + y9)); + double integral1 = (h / 1470) * (77 * (y1 + y13) + 432 * (y3 + y11) + + 625 * (y5 + y9) + 672 * y7); + + if (Math.Abs(integral2 - acc).IsNotEqual(0.0)) + r = Math.Abs(integral1 - acc) / Math.Abs(integral2 - acc); if (r.IsEqual(0.0) || r > 1.0) - r = 1.0; + r = 1.0; } if (relAccuracy_ != null) - if ( absoluteAccuracy() != null ) - return Math.Min(absoluteAccuracy().GetValueOrDefault(), acc*relTol)/(r*Const.QL_EPSILON); + if (absoluteAccuracy() != null) + return Math.Min(absoluteAccuracy().GetValueOrDefault(), acc * relTol) / (r * Const.QL_EPSILON); else - return ( acc * relTol ) / ( r * Const.QL_EPSILON ); - else - return absoluteAccuracy().GetValueOrDefault()/(r*Const.QL_EPSILON); + return (acc * relTol) / (r * Const.QL_EPSILON); + else + return absoluteAccuracy().GetValueOrDefault() / (r * Const.QL_EPSILON); } protected double? relAccuracy_; protected bool useConvergenceEstimate_; - protected static readonly double alpha_ = Math.Sqrt( 2.0 / 3.0 ); - protected static readonly double beta_ = 1.0 / Math.Sqrt( 5.0 ); + protected static readonly double alpha_ = Math.Sqrt(2.0 / 3.0); + protected static readonly double beta_ = 1.0 / Math.Sqrt(5.0); protected static readonly double x1_ = 0.94288241569547971906; protected static readonly double x2_ = 0.64185334234578130578; protected static readonly double x3_ = 0.23638319966214988028; diff --git a/src/QLNet/Math/integrals/GaussianOrthogonalPolynomial.cs b/src/QLNet/Math/integrals/GaussianOrthogonalPolynomial.cs new file mode 100644 index 000000000..35503dfaf --- /dev/null +++ b/src/QLNet/Math/integrals/GaussianOrthogonalPolynomial.cs @@ -0,0 +1,206 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! orthogonal polynomial for Gaussian quadratures + /*! References: + Gauss quadratures and orthogonal polynomials + + G.H. Gloub and J.H. Welsch: Calculation of Gauss quadrature rule. + Math. Comput. 23 (1986), 221-230 + + "Numerical Recipes in C", 2nd edition, + Press, Teukolsky, Vetterling, Flannery, + + The polynomials are defined by the three-term recurrence relation + + */ + public abstract class GaussianOrthogonalPolynomial + { + public abstract double mu_0(); + public abstract double alpha(int i); + public abstract double beta(int i); + public abstract double w(double x); + + public double value(int n, double x) + { + if (n > 1) + { + return (x - alpha(n - 1)) * value(n - 1, x) + - beta(n - 1) * value(n - 2, x); + } + else if (n == 1) + { + return x - alpha(0); + } + return 1; + } + + public double weightedValue(int n, double x) + { + return Math.Sqrt(w(x)) * value(n, x); + } + } + + //! Gauss-Laguerre polynomial + public class GaussLaguerrePolynomial : GaussianOrthogonalPolynomial + { + private double s_; + + public GaussLaguerrePolynomial() : this(0.0) { } + public GaussLaguerrePolynomial(double s) + { + s_ = s; + Utils.QL_REQUIRE(s > -1.0, () => "s must be bigger than -1"); + } + + public override double mu_0() { return Math.Exp(GammaFunction.logValue(s_ + 1)); } + public override double alpha(int i) { return 2 * i + 1 + s_; } + public override double beta(int i) { return i * (i + s_); } + public override double w(double x) { return Math.Pow(x, s_) * Math.Exp(-x); } + } + + //! Gauss-Hermite polynomial + public class GaussHermitePolynomial : GaussianOrthogonalPolynomial + { + private double mu_; + + public GaussHermitePolynomial() : this(0.0) { } + public GaussHermitePolynomial(double mu) + { + mu_ = mu; + Utils.QL_REQUIRE(mu > -0.5, () => "mu must be bigger than -0.5"); + } + + public override double mu_0() { return Math.Exp(GammaFunction.logValue(mu_ + 0.5)); } + public override double alpha(int i) { return 0.0; } + public override double beta(int i) { return (i % 2 != 0) ? i / 2.0 + mu_ : i / 2.0; } + public override double w(double x) { return Math.Pow(Math.Abs(x), 2 * mu_) * Math.Exp(-x * x); } + } + + //! Gauss-Jacobi polynomial + public class GaussJacobiPolynomial : GaussianOrthogonalPolynomial + { + private double alpha_; + private double beta_; + + public GaussJacobiPolynomial(double alpha, double beta) + { + alpha_ = alpha; + beta_ = beta; + + Utils.QL_REQUIRE(alpha_ + beta_ > -2.0, () => "alpha+beta must be bigger than -2"); + Utils.QL_REQUIRE(alpha_ > -1.0, () => "alpha must be bigger than -1"); + Utils.QL_REQUIRE(beta_ > -1.0, () => "beta must be bigger than -1"); + } + + public override double mu_0() + { + return Math.Pow(2.0, alpha_ + beta_ + 1) + * Math.Exp(GammaFunction.logValue(alpha_ + 1) + + GammaFunction.logValue(beta_ + 1) + - GammaFunction.logValue(alpha_ + beta_ + 2)); + } + public override double alpha(int i) + { + double num = beta_ * beta_ - alpha_ * alpha_; + double denom = (2.0 * i + alpha_ + beta_) * (2.0 * i + alpha_ + beta_ + 2); + + if (denom.IsEqual(0.0)) + { + if (num.IsNotEqual(0.0)) + { + Utils.QL_FAIL("can't compute a_k for jacobi integration"); + } + else + { + // l'Hospital + num = 2 * beta_; + denom = 2 * (2.0 * i + alpha_ + beta_ + 1); + + Utils.QL_REQUIRE(denom.IsNotEqual(0.0), () => "can't compute a_k for jacobi integration"); + } + } + + return num / denom; + } + public override double beta(int i) + { + double num = 4.0 * i * (i + alpha_) * (i + beta_) * (i + alpha_ + beta_); + double denom = (2.0 * i + alpha_ + beta_) * (2.0 * i + alpha_ + beta_) + * ((2.0 * i + alpha_ + beta_) * (2.0 * i + alpha_ + beta_) - 1); + + if (denom.IsEqual(0.0)) + { + if (num.IsNotEqual(0.0)) + { + Utils.QL_FAIL("can't compute b_k for jacobi integration"); + } + else + { + // l'Hospital + num = 4.0 * i * (i + beta_) * (2.0 * i + 2 * alpha_ + beta_); + denom = 2.0 * (2.0 * i + alpha_ + beta_); + denom *= denom - 1; + Utils.QL_REQUIRE(denom.IsNotEqual(0.0), () => "can't compute b_k for jacobi integration"); + } + } + return num / denom; + } + public override double w(double x) + { + return Math.Pow(1 - x, alpha_) * Math.Pow(1 + x, beta_); + } + } + + //! Gauss-Legendre polynomial + public class GaussLegendrePolynomial : GaussJacobiPolynomial + { + public GaussLegendrePolynomial() : base(0.0, 0.0) { } + } + + //! Gauss-Chebyshev polynomial + public class GaussChebyshevPolynomial : GaussJacobiPolynomial + { + public GaussChebyshevPolynomial() : base(-0.5, -0.5) { } + } + + //! Gauss-Chebyshev polynomial (second kind) + public class GaussChebyshev2ndPolynomial : GaussJacobiPolynomial + { + public GaussChebyshev2ndPolynomial() : base(0.5, 0.5) { } + } + + //! Gauss-Gegenbauer polynomial + public class GaussGegenbauerPolynomial : GaussJacobiPolynomial + { + public GaussGegenbauerPolynomial(double lambda) : base(lambda - 0.5, lambda - 0.5) { } + } + + //! Gauss hyperbolic polynomial + public class GaussHyperbolicPolynomial : GaussianOrthogonalPolynomial + { + public override double mu_0() { return Const.M_PI; } + public override double alpha(int i) { return 0.0; } + public override double beta(int i) { return i != 0 ? Const.M_PI_2 * Const.M_PI_2 * i * i : Const.M_PI; } + public override double w(double x) { return 1 / Math.Cosh(x); } + } +} diff --git a/src/QLNet/Math/integrals/GaussianQuadratures.cs b/src/QLNet/Math/integrals/GaussianQuadratures.cs index 7aba3557a..6dfc3fea7 100644 --- a/src/QLNet/Math/integrals/GaussianQuadratures.cs +++ b/src/QLNet/Math/integrals/GaussianQuadratures.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -35,201 +35,210 @@ Math. Comput. 23 (1986), 221-230 \test the correctness of the result is tested by checking it against known good values. */ - public class GaussianQuadrature + public class GaussianQuadrature { public GaussianQuadrature(int n, GaussianOrthogonalPolynomial orthPoly) { x_ = new Vector(n); w_ = new Vector(n); - // set-up matrix to compute the roots and the weights - Vector e = new Vector(n-1); + // set-up matrix to compute the roots and the weights + Vector e = new Vector(n - 1); - int i; - for (i=1; i < n; ++i) - { + int i; + for (i = 1; i < n; ++i) + { x_[i] = orthPoly.alpha(i); - e[i-1] = Math.Sqrt(orthPoly.beta(i)); - } - x_[0] = orthPoly.alpha(0); - - TqrEigenDecomposition tqr = new TqrEigenDecomposition( x_, e, - TqrEigenDecomposition.EigenVectorCalculation.OnlyFirstRowEigenVector, - TqrEigenDecomposition.ShiftStrategy.Overrelaxation); - - x_ = tqr.eigenvalues(); - Matrix ev = tqr.eigenvectors(); - - double mu_0 = orthPoly.mu_0(); - for (i=0; i f) + + public double value(Func f) { - double sum = 0.0; - for (int i = order()-1; i >= 0; --i) - { - sum += w_[i] * f(x_[i]); - } - return sum; - } + double sum = 0.0; + for (int i = order() - 1; i >= 0; --i) + { + sum += w_[i] * f(x_[i]); + } + return sum; + } public int order() { return x_.size(); } public Vector weights() { return w_; } public Vector x() { return x_; } - - + + private Vector x_, w_; } //! generalized Gauss-Laguerre integration // This class performs a 1-dimensional Gauss-Laguerre integration. - public class GaussLaguerreIntegration : GaussianQuadrature + public class GaussLaguerreIntegration : GaussianQuadrature { public GaussLaguerreIntegration(int n, double s = 0.0) - : base(n, new GaussLaguerrePolynomial(s)) {} + : base(n, new GaussLaguerrePolynomial(s)) {} } //! generalized Gauss-Hermite integration // This class performs a 1-dimensional Gauss-Hermite integration. - public class GaussHermiteIntegration : GaussianQuadrature + public class GaussHermiteIntegration : GaussianQuadrature { - public GaussHermiteIntegration(int n, double mu = 0.0) - : base(n, new GaussHermitePolynomial(mu)) {} - } + public GaussHermiteIntegration(int n, double mu = 0.0) + : base(n, new GaussHermitePolynomial(mu)) {} + } //! Gauss-Jacobi integration // This class performs a 1-dimensional Gauss-Jacobi integration. - public class GaussJacobiIntegration : GaussianQuadrature + public class GaussJacobiIntegration : GaussianQuadrature { - public GaussJacobiIntegration(int n, double alpha, double beta) - : base(n, new GaussJacobiPolynomial(alpha, beta)) {} + public GaussJacobiIntegration(int n, double alpha, double beta) + : base(n, new GaussJacobiPolynomial(alpha, beta)) {} } //! Gauss-Hyperbolic integration // This class performs a 1-dimensional Gauss-Hyperbolic integration. - public class GaussHyperbolicIntegration : GaussianQuadrature + public class GaussHyperbolicIntegration : GaussianQuadrature { - public GaussHyperbolicIntegration(int n) - : base(n, new GaussHyperbolicPolynomial()) {} + public GaussHyperbolicIntegration(int n) + : base(n, new GaussHyperbolicPolynomial()) {} } //! Gauss-Legendre integration // This class performs a 1-dimensional Gauss-Legendre integration. - public class GaussLegendreIntegration : GaussianQuadrature + public class GaussLegendreIntegration : GaussianQuadrature { - public GaussLegendreIntegration(int n) - : base(n, new GaussJacobiPolynomial(0.0, 0.0)) {} + public GaussLegendreIntegration(int n) + : base(n, new GaussJacobiPolynomial(0.0, 0.0)) {} } //! Gauss-Chebyshev integration // This class performs a 1-dimensional Gauss-Chebyshev integration. - public class GaussChebyshevIntegration : GaussianQuadrature + public class GaussChebyshevIntegration : GaussianQuadrature { - public GaussChebyshevIntegration(int n) - : base(n, new GaussJacobiPolynomial(-0.5, -0.5)) {} + public GaussChebyshevIntegration(int n) + : base(n, new GaussJacobiPolynomial(-0.5, -0.5)) {} } //! Gauss-Chebyshev integration (second kind) // This class performs a 1-dimensional Gauss-Chebyshev integration. - public class GaussChebyshev2ndIntegration : GaussianQuadrature + public class GaussChebyshev2ndIntegration : GaussianQuadrature { - public GaussChebyshev2ndIntegration(int n) - : base(n, new GaussJacobiPolynomial(0.5, 0.5)) {} + public GaussChebyshev2ndIntegration(int n) + : base(n, new GaussJacobiPolynomial(0.5, 0.5)) {} } //! Gauss-Gegenbauer integration // This class performs a 1-dimensional Gauss-Gegenbauer integration. - public class GaussGegenbauerIntegration : GaussianQuadrature + public class GaussGegenbauerIntegration : GaussianQuadrature { - public GaussGegenbauerIntegration(int n, double lambda) - : base(n, new GaussJacobiPolynomial(lambda-0.5, lambda-0.5)) {} + public GaussGegenbauerIntegration(int n, double lambda) + : base(n, new GaussJacobiPolynomial(lambda - 0.5, lambda - 0.5)) {} } //! tabulated Gauss-Legendre quadratures - public class TabulatedGaussLegendre + public class TabulatedGaussLegendre { public TabulatedGaussLegendre(int n = 20) { order(n); } - - public double value (Func f) + + public double value(Func f) { - Utils.QL_REQUIRE( w_ != null, () => "Null weights" ); - Utils.QL_REQUIRE( x_ != null, () => "Null abscissas" ); - int startIdx; - double val; - - int isOrderOdd = order_ & 1; - - if (isOrderOdd > 0) { - Utils.QL_REQUIRE( ( n_ > 0 ), () => "assume at least 1 point in quadrature" ); - val = w_[0]*f(x_[0]); - startIdx=1; - } else { + Utils.QL_REQUIRE(w_ != null, () => "Null weights"); + Utils.QL_REQUIRE(x_ != null, () => "Null abscissas"); + int startIdx; + double val; + + int isOrderOdd = order_ & 1; + + if (isOrderOdd > 0) + { + Utils.QL_REQUIRE((n_ > 0), () => "assume at least 1 point in quadrature"); + val = w_[0] * f(x_[0]); + startIdx = 1; + } + else + { val = 0.0; - startIdx=0; - } - - for (int i=startIdx; i w_; - private List x_; - private int n_; - - private static double[] w6 = { 0.467913934572691,0.360761573048139,0.171324492379170 }; - private static double[] x6 = { 0.238619186083197, 0.661209386466265, 0.932469514203152 }; - private static int n6 = 3; - - private static double[] w7 = { 0.417959183673469,0.381830050505119,0.279705391489277,0.129484966168870 }; - private static double[] x7 = { 0.000000000000000,0.405845151377397,0.741531185599394,0.949107912342759 }; - private static int n7 = 4; - - private static double[] w12 = { 0.249147045813403,0.233492536538355,0.203167426723066,0.160078328543346, - 0.106939325995318,0.047175336386512 }; - private static double[] x12 = { 0.125233408511469,0.367831498998180,0.587317954286617,0.769902674194305, - 0.904117256370475,0.981560634246719 }; - private static int n12 = 6; - - private static double[] w20 = { 0.152753387130726,0.149172986472604,0.142096109318382,0.131688638449177, - 0.118194531961518,0.101930119817240,0.083276741576704,0.062672048334109, - 0.040601429800387,0.017614007139152 }; - private static double[] x20 = { 0.076526521133497,0.227785851141645,0.373706088715420,0.510867001950827, - 0.636053680726515,0.746331906460151,0.839116971822219,0.912234428251326, - 0.963971927277914,0.993128599185095 }; - private static int n20 = 10; - } + public void order(int order) + { + switch (order) + { + case (6): + order_ = order; x_ = x6.ToList(); w_ = w6.ToList(); n_ = n6; + break; + case (7): + order_ = order; x_ = x7.ToList(); w_ = w7.ToList(); n_ = n7; + break; + case (12): + order_ = order; x_ = x12.ToList(); w_ = w12.ToList(); n_ = n12; + break; + case (20): + order_ = order; x_ = x20.ToList(); w_ = w20.ToList(); n_ = n20; + break; + default: + Utils.QL_FAIL("order " + order + " not supported"); + break; + } + } + + public int order() { return order_; } + + + private int order_; + + private List w_; + private List x_; + private int n_; + + private static double[] w6 = { 0.467913934572691, 0.360761573048139, 0.171324492379170 }; + private static double[] x6 = { 0.238619186083197, 0.661209386466265, 0.932469514203152 }; + private static int n6 = 3; + + private static double[] w7 = { 0.417959183673469, 0.381830050505119, 0.279705391489277, 0.129484966168870 }; + private static double[] x7 = { 0.000000000000000, 0.405845151377397, 0.741531185599394, 0.949107912342759 }; + private static int n7 = 4; + + private static double[] w12 = { 0.249147045813403, 0.233492536538355, 0.203167426723066, 0.160078328543346, + 0.106939325995318, 0.047175336386512 + }; + private static double[] x12 = { 0.125233408511469, 0.367831498998180, 0.587317954286617, 0.769902674194305, + 0.904117256370475, 0.981560634246719 + }; + private static int n12 = 6; + + private static double[] w20 = { 0.152753387130726, 0.149172986472604, 0.142096109318382, 0.131688638449177, + 0.118194531961518, 0.101930119817240, 0.083276741576704, 0.062672048334109, + 0.040601429800387, 0.017614007139152 + }; + private static double[] x20 = { 0.076526521133497, 0.227785851141645, 0.373706088715420, 0.510867001950827, + 0.636053680726515, 0.746331906460151, 0.839116971822219, 0.912234428251326, + 0.963971927277914, 0.993128599185095 + }; + private static int n20 = 10; + } } diff --git a/src/QLNet/Math/integrals/Integral.cs b/src/QLNet/Math/integrals/Integral.cs index 2c98f50ad..d7458399b 100644 --- a/src/QLNet/Math/integrals/Integral.cs +++ b/src/QLNet/Math/integrals/Integral.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -30,7 +30,7 @@ protected Integrator(double? absoluteAccuracy, int maxEvaluations) maxEvaluations_ = maxEvaluations; if (absoluteAccuracy != null) Utils.QL_REQUIRE(absoluteAccuracy > double.Epsilon, () => - "required tolerance (" + absoluteAccuracy + ") not allowed. It must be > " + double.Epsilon); + "required tolerance (" + absoluteAccuracy + ") not allowed. It must be > " + double.Epsilon); } public double value(Func f, double a, double b) diff --git a/src/QLNet/Math/integrals/Kronrodintegral.cs b/src/QLNet/Math/integrals/Kronrodintegral.cs index 989862537..afb1da338 100644 --- a/src/QLNet/Math/integrals/Kronrodintegral.cs +++ b/src/QLNet/Math/integrals/Kronrodintegral.cs @@ -1,113 +1,114 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - -public static class KronrodintegralArrays +namespace QLNet { - public static double rescaleError(double err, double resultAbs, double resultAsc) - { - err = Math.Abs(err); - if (resultAsc.IsNotEqual(0.0) && err.IsNotEqual(0.0)) - { - double scale = Math.Pow((200 * err / resultAsc), 1.5); - if (scale < 1) - err = resultAsc * scale; - else - err = resultAsc; - } - if (resultAbs > Double.MinValue / (50 * Double.Epsilon)) - { - double min_err = 50 * Double.Epsilon * resultAbs; - if (min_err > err) - err = min_err; - } - return err; - } - - // Gauss-Kronrod-Patterson quadrature coefficients for use in - // quadpack routine qng. These coefficients were calculated with - // 101 decimal digit arithmetic by L. W. Fullerton, Bell Labs, Nov - // 1981. - - // x1, abscissae common to the 10-, 21-, 43- and 87-point rule + public static class KronrodintegralArrays + { + + public static double rescaleError(double err, double resultAbs, double resultAsc) + { + err = Math.Abs(err); + if (resultAsc.IsNotEqual(0.0) && err.IsNotEqual(0.0)) + { + double scale = Math.Pow((200 * err / resultAsc), 1.5); + if (scale < 1) + err = resultAsc * scale; + else + err = resultAsc; + } + if (resultAbs > Double.MinValue / (50 * Double.Epsilon)) + { + double min_err = 50 * Double.Epsilon * resultAbs; + if (min_err > err) + err = min_err; + } + return err; + } + + // Gauss-Kronrod-Patterson quadrature coefficients for use in + // quadpack routine qng. These coefficients were calculated with + // 101 decimal digit arithmetic by L. W. Fullerton, Bell Labs, Nov + // 1981. + + // x1, abscissae common to the 10-, 21-, 43- and 87-point rule private static readonly double[] x1_ = { 0.973906528517171720077964012084452, 0.865063366688984510732096688423493, 0.679409568299024406234327365114874, 0.433395394129247190799265943165784, 0.148874338981631210884826001129720 }; public static double[] x1 { get { return x1_; } } - // w10, weights of the 10-point formula + // w10, weights of the 10-point formula private static readonly double[] w10_ = { 0.066671344308688137593568809893332, 0.149451349150580593145776339657697, 0.219086362515982043995534934228163, 0.269266719309996355091226921569469, 0.295524224714752870173892994651338 }; - public static double[] w10 { get { return w10_; } } + public static double[] w10 { get { return w10_; } } - // x2, abscissae common to the 21-, 43- and 87-point rule + // x2, abscissae common to the 21-, 43- and 87-point rule private static readonly double[] x2_ = { 0.995657163025808080735527280689003, 0.930157491355708226001207180059508, 0.780817726586416897063717578345042, 0.562757134668604683339000099272694, 0.294392862701460198131126603103866 }; - public static double[] x2 { get { return x2_; } } + public static double[] x2 { get { return x2_; } } - // w21a, weights of the 21-point formula for abscissae x1 + // w21a, weights of the 21-point formula for abscissae x1 private static readonly double[] w21a_ = { 0.032558162307964727478818972459390, 0.075039674810919952767043140916190, 0.109387158802297641899210590325805, 0.134709217311473325928054001771707, 0.147739104901338491374841515972068 }; - public static double[] w21a { get { return w21a_; } } + public static double[] w21a { get { return w21a_; } } - // w21b, weights of the 21-point formula for abscissae x2 + // w21b, weights of the 21-point formula for abscissae x2 private static readonly double[] w21b_ = { 0.011694638867371874278064396062192, 0.054755896574351996031381300244580, 0.093125454583697605535065465083366, 0.123491976262065851077958109831074, 0.142775938577060080797094273138717, 0.149445554002916905664936468389821 }; - public static double[] w21b { get { return w21b_; } } + public static double[] w21b { get { return w21b_; } } - // x3, abscissae common to the 43- and 87-point rule + // x3, abscissae common to the 43- and 87-point rule private static readonly double[] x3_ = { 0.999333360901932081394099323919911, 0.987433402908088869795961478381209, 0.954807934814266299257919200290473, 0.900148695748328293625099494069092, 0.825198314983114150847066732588520, 0.732148388989304982612354848755461, 0.622847970537725238641159120344323, 0.499479574071056499952214885499755, 0.364901661346580768043989548502644, 0.222254919776601296498260928066212, 0.074650617461383322043914435796506 }; - public static double[] x3 { get { return x3_; } } + public static double[] x3 { get { return x3_; } } - // w43a, weights of the 43-point formula for abscissae x1, x3 + // w43a, weights of the 43-point formula for abscissae x1, x3 private static readonly double[] w43a_ = { 0.016296734289666564924281974617663, 0.037522876120869501461613795898115, 0.054694902058255442147212685465005, 0.067355414609478086075553166302174, 0.073870199632393953432140695251367, 0.005768556059769796184184327908655, 0.027371890593248842081276069289151, 0.046560826910428830743339154433824, 0.061744995201442564496240336030883, 0.071387267268693397768559114425516 }; - public static double[] w43a { get { return w43a_; } } + public static double[] w43a { get { return w43a_; } } - // w43b, weights of the 43-point formula for abscissae x3 + // w43b, weights of the 43-point formula for abscissae x3 private static readonly double[] w43b_ = { 0.001844477640212414100389106552965, 0.010798689585891651740465406741293, 0.021895363867795428102523123075149, 0.032597463975345689443882222526137, 0.042163137935191811847627924327955, 0.050741939600184577780189020092084, 0.058379395542619248375475369330206, 0.064746404951445885544689259517511, 0.069566197912356484528633315038405, 0.072824441471833208150939535192842, 0.074507751014175118273571813842889, 0.074722147517403005594425168280423 }; - public static double[] w43b { get { return w43b_; } } + public static double[] w43b { get { return w43b_; } } - // x4, abscissae of the 87-point rule + // x4, abscissae of the 87-point rule private static readonly double[] x4_ = { 0.999902977262729234490529830591582, 0.997989895986678745427496322365960, 0.992175497860687222808523352251425, 0.981358163572712773571916941623894, 0.965057623858384619128284110607926, 0.943167613133670596816416634507426, 0.915806414685507209591826430720050, 0.883221657771316501372117548744163, 0.845710748462415666605902011504855, 0.803557658035230982788739474980964, 0.757005730685495558328942793432020, 0.706273209787321819824094274740840, 0.651589466501177922534422205016736, 0.593223374057961088875273770349144, 0.531493605970831932285268948562671, 0.466763623042022844871966781659270, 0.399424847859218804732101665817923, 0.329874877106188288265053371824597, 0.258503559202161551802280975429025, 0.185695396568346652015917141167606, 0.111842213179907468172398359241362, 0.037352123394619870814998165437704 }; - public static double[] x4 { get { return x4_; } } + public static double[] x4 { get { return x4_; } } - // w87a, weights of the 87-point formula for abscissae x1, x2, x3 + // w87a, weights of the 87-point formula for abscissae x1, x2, x3 private static readonly double[] w87a_ = { 0.008148377384149172900002878448190, 0.018761438201562822243935059003794, 0.027347451050052286161582829741283, 0.033677707311637930046581056957588, 0.036935099820427907614589586742499, 0.002884872430211530501334156248695, 0.013685946022712701888950035273128, 0.023280413502888311123409291030404, 0.030872497611713358675466394126442, 0.035693633639418770719351355457044, 0.000915283345202241360843392549948, 0.005399280219300471367738743391053, 0.010947679601118931134327826856808, 0.016298731696787335262665703223280, 0.021081568889203835112433060188190, 0.025370969769253827243467999831710, 0.029189697756475752501446154084920, 0.032373202467202789685788194889595, 0.034783098950365142750781997949596, 0.036412220731351787562801163687577, 0.037253875503047708539592001191226 }; - public static double[] w87a { get { return w87a_; } } + public static double[] w87a { get { return w87a_; } } - // w87b, weights of the 87-point formula for abscissae x4 + // w87b, weights of the 87-point formula for abscissae x4 private static readonly double[] w87b_ = { 0.000274145563762072350016527092881, 0.001807124155057942948341311753254, 0.004096869282759164864458070683480, 0.006758290051847378699816577897424, 0.009549957672201646536053581325377, 0.012329447652244853694626639963780, 0.015010447346388952376697286041943, 0.017548967986243191099665352925900, 0.019938037786440888202278192730714, 0.022194935961012286796332102959499, 0.024339147126000805470360647041454, 0.026374505414839207241503786552615, 0.028286910788771200659968002987960, 0.030052581128092695322521110347341, 0.031646751371439929404586051078883, 0.033050413419978503290785944862689, 0.034255099704226061787082821046821, 0.035262412660156681033782717998428, 0.036076989622888701185500318003895, 0.036698604498456094498018047441094, 0.037120549269832576114119958413599, 0.037334228751935040321235449094698, 0.037361073762679023410321241766599 }; public static double[] w87b { get { return w87b_; } } - // weights for 7-point Gauss-Legendre integration - // (only 4 values out of 7 are given as they are symmetric) + // weights for 7-point Gauss-Legendre integration + // (only 4 values out of 7 are given as they are symmetric) private static readonly double[] g7w_ = { 0.417959183673469, 0.381830050505119, 0.279705391489277, 0.129484966168870 }; public static double[] g7w { get { return g7w_; } } - // weights for 15-point Gauss-Kronrod integration + // weights for 15-point Gauss-Kronrod integration private static readonly double[] k15w_ = { 0.209482141084728, 0.204432940075298, 0.190350578064785, 0.169004726639267, 0.140653259715525, 0.104790010322250, 0.063092092629979, 0.022935322010529 }; public static double[] k15w { get { return k15w_; } } - // abscissae (evaluation points) - // for 15-point Gauss-Kronrod integration + // abscissae (evaluation points) + // for 15-point Gauss-Kronrod integration private static readonly double[] k15t_ = { 0.000000000000000, 0.207784955007898, 0.405845151377397, 0.586087235467691, 0.741531185599394, 0.864864423359769, 0.949107912342758, 0.991455371120813 }; public static double[] k15t { get { return k15t_; } } -} + } - //! Integral of a 1-dimensional function using the Gauss-Kronrod methods + //! Integral of a 1-dimensional function using the Gauss-Kronrod methods // ! This class provide a non-adaptive integration procedure which // uses fixed Gauss-Kronrod abscissae to sample the integrand at // a maximum of 87 points. It is provided for fast integration @@ -122,144 +123,144 @@ public static double rescaleError(double err, double resultAbs, double resultAsc // Gauss-Kronrod rules are designed in such a way that each rule uses // all the results of its predecessors, in order to minimize the total // number of function evaluations. -// - public class GaussKronrodNonAdaptive : Integrator - { - public GaussKronrodNonAdaptive(double absoluteAccuracy, int maxEvaluations, double relativeAccuracy) : base(absoluteAccuracy, maxEvaluations) - { - relativeAccuracy_ = relativeAccuracy; - } - public double relativeAccuracy() - { - return relativeAccuracy_; - } - protected override double integrate(Func f, double a, double b) - { - double result; - double[] fv1 = new double[5]; - double[] fv2 = new double[5]; - double[] fv3 = new double[5]; - double[] fv4 = new double[5]; - double[] savfun = new double[21]; // array of function values which have been computed - double res10; // 10, 21, 43 and 87 point results - double res21; - double res43; - double res87; - double err; - double resAbs; // approximation to the integral of abs(f) - double resasc; // approximation to the integral of abs(f-i/(b-a)) - int k; - - Utils.QL_REQUIRE(a "b must be greater than a)"); - - double halfLength = 0.5 * (b - a); - double center = 0.5 * (b + a); - double fCenter = f(center); - - // Compute the integral using the 10- and 21-point formula. - - res10 = 0; - res21 = KronrodintegralArrays.w21b[5] * fCenter; - resAbs = KronrodintegralArrays.w21b[5] * Math.Abs(fCenter); - - for (k = 0; k < 5; k++) - { - double abscissa = halfLength * KronrodintegralArrays.x1[k]; - double fval1 = f(center + abscissa); - double fval2 = f(center - abscissa); - double fval = fval1 + fval2; - res10 += KronrodintegralArrays.w10[k] * fval; - res21 += KronrodintegralArrays.w21a[k] * fval; - resAbs += KronrodintegralArrays.w21a[k] * (Math.Abs(fval1) + Math.Abs(fval2)); - savfun[k] = fval; - fv1[k] = fval1; - fv2[k] = fval2; - } - - for (k = 0; k < 5; k++) - { - double abscissa = halfLength * KronrodintegralArrays.x2[k]; - double fval1 = f(center + abscissa); - double fval2 = f(center - abscissa); - double fval = fval1 + fval2; - res21 += KronrodintegralArrays.w21b[k] * fval; - resAbs += KronrodintegralArrays.w21b[k] * (Math.Abs(fval1) + Math.Abs(fval2)); - savfun[k + 5] = fval; - fv3[k] = fval1; - fv4[k] = fval2; - } - - result = res21 * halfLength; - resAbs *= halfLength; - double mean = 0.5 * res21; - resasc = KronrodintegralArrays.w21b[5] * Math.Abs(fCenter - mean); - - for (k = 0; k < 5; k++) - resasc += (KronrodintegralArrays.w21a[k] * (Math.Abs(fv1[k] - mean) + Math.Abs(fv2[k] - mean)) + KronrodintegralArrays.w21b[k] * (Math.Abs(fv3[k] - mean) + Math.Abs(fv4[k] - mean))); - - err = KronrodintegralArrays.rescaleError ((res21 - res10) * halfLength, resAbs, resasc); - resasc *= halfLength; - - // test for convergence. - if (err < absoluteAccuracy() || err < relativeAccuracy() * Math.Abs(result)) - { - setAbsoluteError(err); - setNumberOfEvaluations(21); - return result; - } - - // compute the integral using the 43-point formula. - - res43 = KronrodintegralArrays.w43b[11] * fCenter; - - for (k = 0; k < 10; k++) - res43 += savfun[k] * KronrodintegralArrays.w43a[k]; - - for (k = 0; k < 11; k++) - { - double abscissa = halfLength * KronrodintegralArrays.x3[k]; - double fval = (f(center + abscissa) + f(center - abscissa)); - res43 += fval * KronrodintegralArrays.w43b[k]; - savfun[k + 10] = fval; - } - - // test for convergence. - - result = res43 * halfLength; - err = KronrodintegralArrays.rescaleError ((res43 - res21) * halfLength, resAbs, resasc); - - if (err < absoluteAccuracy() || err < relativeAccuracy() * Math.Abs(result)) - { - setAbsoluteError(err); - setNumberOfEvaluations(43); - return result; - } - - // compute the integral using the 87-point formula. - - res87 = KronrodintegralArrays.w87b[22] * fCenter; - - for (k = 0; k < 21; k++) - res87 += savfun[k] * KronrodintegralArrays.w87a[k]; - - for (k = 0; k < 22; k++) - { - double abscissa = halfLength * KronrodintegralArrays.x4[k]; - res87 += KronrodintegralArrays.w87b[k] * (f(center + abscissa) + f(center - abscissa)); - } - - // test for convergence. - result = res87 * halfLength; - err = KronrodintegralArrays.rescaleError ((res87 - res43) * halfLength, resAbs, resasc); - - setAbsoluteError(err); - setNumberOfEvaluations(87); - return result; - } - private double relativeAccuracy_; - } - - //! Integral of a 1-dimensional function using the Gauss-Kronrod methods +// + public class GaussKronrodNonAdaptive : Integrator + { + public GaussKronrodNonAdaptive(double absoluteAccuracy, int maxEvaluations, double relativeAccuracy) : base(absoluteAccuracy, maxEvaluations) + { + relativeAccuracy_ = relativeAccuracy; + } + public double relativeAccuracy() + { + return relativeAccuracy_; + } + protected override double integrate(Func f, double a, double b) + { + double result; + double[] fv1 = new double[5]; + double[] fv2 = new double[5]; + double[] fv3 = new double[5]; + double[] fv4 = new double[5]; + double[] savfun = new double[21]; // array of function values which have been computed + double res10; // 10, 21, 43 and 87 point results + double res21; + double res43; + double res87; + double err; + double resAbs; // approximation to the integral of abs(f) + double resasc; // approximation to the integral of abs(f-i/(b-a)) + int k; + + Utils.QL_REQUIRE(a "b must be greater than a)"); + + double halfLength = 0.5 * (b - a); + double center = 0.5 * (b + a); + double fCenter = f(center); + + // Compute the integral using the 10- and 21-point formula. + + res10 = 0; + res21 = KronrodintegralArrays.w21b[5] * fCenter; + resAbs = KronrodintegralArrays.w21b[5] * Math.Abs(fCenter); + + for (k = 0; k < 5; k++) + { + double abscissa = halfLength* KronrodintegralArrays.x1[k]; + double fval1 = f(center + abscissa); + double fval2 = f(center - abscissa); + double fval = fval1 + fval2; + res10 += KronrodintegralArrays.w10[k] * fval; + res21 += KronrodintegralArrays.w21a[k] * fval; + resAbs += KronrodintegralArrays.w21a[k] * (Math.Abs(fval1) + Math.Abs(fval2)); + savfun[k] = fval; + fv1[k] = fval1; + fv2[k] = fval2; + } + + for (k = 0; k < 5; k++) + { + double abscissa = halfLength* KronrodintegralArrays.x2[k]; + double fval1 = f(center + abscissa); + double fval2 = f(center - abscissa); + double fval = fval1 + fval2; + res21 += KronrodintegralArrays.w21b[k] * fval; + resAbs += KronrodintegralArrays.w21b[k] * (Math.Abs(fval1) + Math.Abs(fval2)); + savfun[k + 5] = fval; + fv3[k] = fval1; + fv4[k] = fval2; + } + + result = res21* halfLength; + resAbs *= halfLength; + double mean = 0.5 * res21; + resasc = KronrodintegralArrays.w21b[5] * Math.Abs(fCenter - mean); + + for (k = 0; k < 5; k++) + resasc += (KronrodintegralArrays.w21a[k] * (Math.Abs(fv1[k] - mean) + Math.Abs(fv2[k] - mean)) + KronrodintegralArrays.w21b[k] * (Math.Abs(fv3[k] - mean) + Math.Abs(fv4[k] - mean))); + + err = KronrodintegralArrays.rescaleError((res21 - res10) * halfLength, resAbs, resasc); + resasc *= halfLength; + + // test for convergence. + if (err < absoluteAccuracy() || err < relativeAccuracy() * Math.Abs(result)) + { + setAbsoluteError(err); + setNumberOfEvaluations(21); + return result; + } + + // compute the integral using the 43-point formula. + + res43 = KronrodintegralArrays.w43b[11] * fCenter; + + for (k = 0; k < 10; k++) + res43 += savfun[k] * KronrodintegralArrays.w43a[k]; + + for (k = 0; k < 11; k++) + { + double abscissa = halfLength* KronrodintegralArrays.x3[k]; + double fval = (f(center + abscissa) + f(center - abscissa)); + res43 += fval* KronrodintegralArrays.w43b[k]; + savfun[k + 10] = fval; + } + + // test for convergence. + + result = res43* halfLength; + err = KronrodintegralArrays.rescaleError((res43 - res21) * halfLength, resAbs, resasc); + + if (err < absoluteAccuracy() || err < relativeAccuracy() * Math.Abs(result)) + { + setAbsoluteError(err); + setNumberOfEvaluations(43); + return result; + } + + // compute the integral using the 87-point formula. + + res87 = KronrodintegralArrays.w87b[22] * fCenter; + + for (k = 0; k < 21; k++) + res87 += savfun[k] * KronrodintegralArrays.w87a[k]; + + for (k = 0; k < 22; k++) + { + double abscissa = halfLength* KronrodintegralArrays.x4[k]; + res87 += KronrodintegralArrays.w87b[k] * (f(center + abscissa) + f(center - abscissa)); + } + + // test for convergence. + result = res87* halfLength; + err = KronrodintegralArrays.rescaleError((res87 - res43) * halfLength, resAbs, resasc); + + setAbsoluteError(err); + setNumberOfEvaluations(87); + return result; + } + private double relativeAccuracy_; + } + + //! Integral of a 1-dimensional function using the Gauss-Kronrod methods // ! This class provide an adaptive integration procedure using 15 // points Gauss-Kronrod integration rule. This is more robust in // that it allows to integrate less smooth functions (though @@ -277,72 +278,72 @@ protected override double integrate(Func f, double a, double b) // // \test the correctness of the result is tested by checking it // against known good values. -// - public class GaussKronrodAdaptive : Integrator - { - public GaussKronrodAdaptive(double absoluteAccuracy, int maxEvaluations) : base(absoluteAccuracy, maxEvaluations) - { - Utils.QL_REQUIRE(maxEvaluations >= 15,()=> - "required maxEvaluations (" + maxEvaluations + ") not allowed. It must be >= 15"); - } - protected override double integrate(Func f, double a, double b) - { - return integrateRecursively(f, a, b, absoluteAccuracy().GetValueOrDefault()); - } - private double integrateRecursively(Func f, double a, double b, double tolerance) - { - - double halflength = (b - a) / 2; - double center = (a + b) / 2; - - double g7; // will be result of G7 integral - double k15; // will be result of K15 integral - - double t; // t (abscissa) and f(t) - double fsum; - double fc = f(center); - g7 = fc * KronrodintegralArrays.g7w[0]; - k15 = fc * KronrodintegralArrays.k15w[0]; - - // calculate g7 and half of k15 - int j; - int j2; - for (j = 1, j2 = 2; j < 4; j++, j2 += 2) - { - t = halflength * KronrodintegralArrays.k15t[j2]; - fsum = f(center - t) + f(center + t); - g7 += fsum * KronrodintegralArrays.g7w[j]; - k15 += fsum * KronrodintegralArrays.k15w[j2]; - } - - // calculate other half of k15 - for (j2 = 1; j2 < 8; j2 += 2) - { - t = halflength * KronrodintegralArrays.k15t[j2]; - fsum = f(center - t) + f(center + t); - k15 += fsum * KronrodintegralArrays.k15w[j2]; - } - - // multiply by (a - b) / 2 - g7 = halflength * g7; - k15 = halflength * k15; - - // 15 more function evaluations have been used - increaseNumberOfEvaluations(15); - - // error is <= k15 - g7 - // if error is larger than tolerance then split the interval - // in two and integrate recursively - if (Math.Abs(k15 - g7) < tolerance) - { - return k15; - } - else - { - Utils.QL_REQUIRE(numberOfEvaluations() + 30 <= maxEvaluations(),()=> - "maximum number of function evaluations " + "exceeded"); - return integrateRecursively(f, a, center, tolerance/2) + integrateRecursively(f, center, b, tolerance/2); - } - } - } +// + public class GaussKronrodAdaptive : Integrator + { + public GaussKronrodAdaptive(double absoluteAccuracy, int maxEvaluations) : base(absoluteAccuracy, maxEvaluations) + { + Utils.QL_REQUIRE(maxEvaluations >= 15, () => + "required maxEvaluations (" + maxEvaluations + ") not allowed. It must be >= 15"); + } + protected override double integrate(Func f, double a, double b) + { + return integrateRecursively(f, a, b, absoluteAccuracy().GetValueOrDefault()); + } + private double integrateRecursively(Func f, double a, double b, double tolerance) + { + + double halflength = (b - a) / 2; + double center = (a + b) / 2; + + double g7; // will be result of G7 integral + double k15; // will be result of K15 integral + + double t; // t (abscissa) and f(t) + double fsum; + double fc = f(center); + g7 = fc * KronrodintegralArrays.g7w[0]; + k15 = fc * KronrodintegralArrays.k15w[0]; + + // calculate g7 and half of k15 + int j; + int j2; + for (j = 1, j2 = 2; j < 4; j++, j2 += 2) + { + t = halflength * KronrodintegralArrays.k15t[j2]; + fsum = f(center - t) + f(center + t); + g7 += fsum * KronrodintegralArrays.g7w[j]; + k15 += fsum * KronrodintegralArrays.k15w[j2]; + } + + // calculate other half of k15 + for (j2 = 1; j2 < 8; j2 += 2) + { + t = halflength * KronrodintegralArrays.k15t[j2]; + fsum = f(center - t) + f(center + t); + k15 += fsum * KronrodintegralArrays.k15w[j2]; + } + + // multiply by (a - b) / 2 + g7 = halflength * g7; + k15 = halflength * k15; + + // 15 more function evaluations have been used + increaseNumberOfEvaluations(15); + + // error is <= k15 - g7 + // if error is larger than tolerance then split the interval + // in two and integrate recursively + if (Math.Abs(k15 - g7) < tolerance) + { + return k15; + } + else + { + Utils.QL_REQUIRE(numberOfEvaluations() + 30 <= maxEvaluations(), () => + "maximum number of function evaluations " + "exceeded"); + return integrateRecursively(f, a, center, tolerance / 2) + integrateRecursively(f, center, b, tolerance / 2); + } + } + } } diff --git a/src/QLNet/Math/integrals/Segmentintegral.cs b/src/QLNet/Math/integrals/Segmentintegral.cs index 50621783e..f8d7b4a58 100644 --- a/src/QLNet/Math/integrals/Segmentintegral.cs +++ b/src/QLNet/Math/integrals/Segmentintegral.cs @@ -1,61 +1,65 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - - //! Integral of a one-dimensional function - // ! Given a number \f$ N \f$ of intervals, the integral of - // a function \f$ f \f$ between \f$ a \f$ and \f$ b \f$ is - // calculated by means of the trapezoid formula - // \f[ - // \int_{a}^{b} f \mathrm{d}x = - // \frac{1}{2} f(x_{0}) + f(x_{1}) + f(x_{2}) + \dots - // + f(x_{N-1}) + \frac{1}{2} f(x_{N}) - // \f] - // where \f$ x_0 = a \f$, \f$ x_N = b \f$, and - // \f$ x_i = a+i \Delta x \f$ with - // \f$ \Delta x = (b-a)/N \f$. - // - // \test the correctness of the result is tested by checking it - // against known good values. - // - public class SegmentIntegral : Integrator { - private int intervals_; - - public SegmentIntegral(int intervals) - : base(1, 1) { - intervals_ = intervals; - - Utils.QL_REQUIRE(intervals > 0,()=> "at least 1 interval needed, 0 given"); - } - - // inline and template definitions - protected override double integrate(Func f, double a, double b) { - double dx = (b - a) / intervals_; - double sum = 0.5 * (f(a) + f(b)); - double end = b - 0.5 * dx; - for (double x = a + dx; x < end; x += dx) - sum += f(x); - return sum * dx; - } - } +namespace QLNet +{ + + //! Integral of a one-dimensional function + // ! Given a number \f$ N \f$ of intervals, the integral of + // a function \f$ f \f$ between \f$ a \f$ and \f$ b \f$ is + // calculated by means of the trapezoid formula + // \f[ + // \int_{a}^{b} f \mathrm{d}x = + // \frac{1}{2} f(x_{0}) + f(x_{1}) + f(x_{2}) + \dots + // + f(x_{N-1}) + \frac{1}{2} f(x_{N}) + // \f] + // where \f$ x_0 = a \f$, \f$ x_N = b \f$, and + // \f$ x_i = a+i \Delta x \f$ with + // \f$ \Delta x = (b-a)/N \f$. + // + // \test the correctness of the result is tested by checking it + // against known good values. + // + public class SegmentIntegral : Integrator + { + private int intervals_; + + public SegmentIntegral(int intervals) + : base(1, 1) + { + intervals_ = intervals; + + Utils.QL_REQUIRE(intervals > 0, () => "at least 1 interval needed, 0 given"); + } + + // inline and template definitions + protected override double integrate(Func f, double a, double b) + { + double dx = (b - a) / intervals_; + double sum = 0.5 * (f(a) + f(b)); + double end = b - 0.5 * dx; + for (double x = a + dx; x < end; x += dx) + sum += f(x); + return sum * dx; + } + } } diff --git a/src/QLNet/Math/integrals/SimpsonIntegral.cs b/src/QLNet/Math/integrals/SimpsonIntegral.cs new file mode 100644 index 000000000..22e580abe --- /dev/null +++ b/src/QLNet/Math/integrals/SimpsonIntegral.cs @@ -0,0 +1,60 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! Integral of a one-dimensional function + /*! \test the correctness of the result is tested by checking it + against known good values. + */ + public class SimpsonIntegral : TrapezoidIntegral + { + public SimpsonIntegral(double accuracy, int maxIterations) : base(accuracy, maxIterations) { } + + protected override double integrate(Func f, double a, double b) + { + // start from the coarsest trapezoid... + int N = 1; + double I = (f(a) + f(b)) * (b - a) / 2.0, newI; + double adjI = I, newAdjI; + // ...and refine it + int i = 1; + + IIntegrationPolicy ip = new Default(); + do + { + newI = ip.integrate(f, a, b, I, N); + N *= 2; + newAdjI = (4.0 * newI - I) / 3.0; + // good enough? Also, don't run away immediately + if (Math.Abs(adjI - newAdjI) <= absoluteAccuracy() && i > 5) + // ok, exit + return newAdjI; + // oh well. Another step. + I = newI; + adjI = newAdjI; + i++; + } + while (i < maxEvaluations()); + Utils.QL_FAIL("max number of iterations reached"); + return 0; + } + } +} diff --git a/src/QLNet/Math/integrals/TrapezoidIntegral.cs b/src/QLNet/Math/integrals/TrapezoidIntegral.cs new file mode 100644 index 000000000..807ee0a64 --- /dev/null +++ b/src/QLNet/Math/integrals/TrapezoidIntegral.cs @@ -0,0 +1,108 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! Integral of a one-dimensional function + /*! Given a target accuracy \f$ \epsilon \f$, the integral of + a function \f$ f \f$ between \f$ a \f$ and \f$ b \f$ is + calculated by means of the trapezoid formula + \f[ + \int_{a}^{b} f \mathrm{d}x = + \frac{1}{2} f(x_{0}) + f(x_{1}) + f(x_{2}) + \dots + + f(x_{N-1}) + \frac{1}{2} f(x_{N}) + \f] + where \f$ x_0 = a \f$, \f$ x_N = b \f$, and + \f$ x_i = a+i \Delta x \f$ with + \f$ \Delta x = (b-a)/N \f$. The number \f$ N \f$ of intervals + is repeatedly increased until the target accuracy is reached. + + \test the correctness of the result is tested by checking it + against known good values. + */ + public class TrapezoidIntegral : Integrator where IntegrationPolicy : IIntegrationPolicy, new () + { + public TrapezoidIntegral(double accuracy, int maxIterations) : base(accuracy, maxIterations) { } + + protected override double integrate(Func f, double a, double b) + { + // start from the coarsest trapezoid... + int N = 1; + double I = (f(a) + f(b)) * (b - a) / 2.0, newI; + // ...and refine it + int i = 1; + + IntegrationPolicy ip = FastActivator.Create(); + do + { + newI = ip.integrate(f, a, b, I, N); + N *= ip.nbEvalutions(); + // good enough? Also, don't run away immediately + if (Math.Abs(I - newI) <= absoluteAccuracy() && i > 5) + // ok, exit + return newI; + // oh well. Another step. + I = newI; + i++; + } + while (i < maxEvaluations()); + Utils.QL_FAIL("max number of iterations reached"); + return 0; + } + } + + public interface IIntegrationPolicy + { + double integrate(Func f, double a, double b, double I, int N); + int nbEvalutions(); + } + + // Integration policies + public struct Default : IIntegrationPolicy + { + public double integrate(Func f, double a, double b, double I, int N) + { + double sum = 0.0; + double dx = (b - a) / N; + double x = a + dx / 2.0; + for (int i = 0; i < N; x += dx, ++i) + sum += f(x); + return (I + dx * sum) / 2.0; + } + public int nbEvalutions() { return 2;} + } + + public struct MidPoint : IIntegrationPolicy + { + public double integrate(Func f, double a, double b, double I, int N) + { + double sum = 0.0; + double dx = (b - a) / N; + double x = a + dx / 6.0; + double D = 2.0 * dx / 3.0; + for (int i = 0; i < N; x += dx, ++i) + sum += f(x) + f(x + D); + return (I + dx * sum) / 3.0; + } + + public int nbEvalutions() { return 3; } + } + +} diff --git a/src/QLNet/Math/integrals/gaussianorthogonalpolynomial.cs b/src/QLNet/Math/integrals/gaussianorthogonalpolynomial.cs deleted file mode 100644 index 7786ed05e..000000000 --- a/src/QLNet/Math/integrals/gaussianorthogonalpolynomial.cs +++ /dev/null @@ -1,178 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! orthogonal polynomial for Gaussian quadratures - /*! References: - Gauss quadratures and orthogonal polynomials - - G.H. Gloub and J.H. Welsch: Calculation of Gauss quadrature rule. - Math. Comput. 23 (1986), 221-230 - - "Numerical Recipes in C", 2nd edition, - Press, Teukolsky, Vetterling, Flannery, - - The polynomials are defined by the three-term recurrence relation - - */ - public abstract class GaussianOrthogonalPolynomial { - public abstract double mu_0(); - public abstract double alpha(int i); - public abstract double beta(int i); - public abstract double w(double x); - - public double value(int n, double x) { - if (n > 1) { - return (x-alpha(n-1)) * value(n-1, x) - - beta(n-1) * value(n-2, x); - } - else if (n == 1) { - return x-alpha(0); - } - return 1; - } - - public double weightedValue(int n, double x) { - return Math.Sqrt(w(x))*value(n, x); - } - } - - //! Gauss-Laguerre polynomial - public class GaussLaguerrePolynomial : GaussianOrthogonalPolynomial { - private double s_; - - public GaussLaguerrePolynomial() : this(0.0) { } - public GaussLaguerrePolynomial(double s) { - s_ = s; - Utils.QL_REQUIRE(s > -1.0,()=> "s must be bigger than -1"); - } - - public override double mu_0() { return Math.Exp(GammaFunction.logValue(s_+1)); } - public override double alpha(int i) { return 2 * i + 1 + s_; } - public override double beta(int i) { return i * (i + s_); } - public override double w(double x) { return Math.Pow(x, s_) * Math.Exp(-x); } - } - - //! Gauss-Hermite polynomial - public class GaussHermitePolynomial : GaussianOrthogonalPolynomial { - private double mu_; - - public GaussHermitePolynomial() : this(0.0) { } - public GaussHermitePolynomial(double mu) { - mu_ = mu; - Utils.QL_REQUIRE(mu > -0.5,()=> "mu must be bigger than -0.5"); - } - - public override double mu_0() { return Math.Exp(GammaFunction.logValue(mu_+0.5)); } - public override double alpha(int i) { return 0.0; } - public override double beta(int i) { return (i % 2 != 0) ? i / 2.0 + mu_ : i / 2.0; } - public override double w(double x) { return Math.Pow(Math.Abs(x), 2*mu_)*Math.Exp(-x*x); } - } - - //! Gauss-Jacobi polynomial - public class GaussJacobiPolynomial : GaussianOrthogonalPolynomial { - private double alpha_; - private double beta_; - - public GaussJacobiPolynomial(double alpha, double beta) { - alpha_ = alpha; - beta_ = beta; - - Utils.QL_REQUIRE(alpha_+beta_ > -2.0,()=> "alpha+beta must be bigger than -2"); - Utils.QL_REQUIRE(alpha_ > -1.0,()=> "alpha must be bigger than -1"); - Utils.QL_REQUIRE(beta_ > -1.0,()=> "beta must be bigger than -1"); - } - - public override double mu_0() { - return Math.Pow(2.0, alpha_+beta_+1) - * Math.Exp( GammaFunction.logValue(alpha_+1) - +GammaFunction.logValue(beta_ +1) - -GammaFunction.logValue(alpha_+beta_+2)); - } - public override double alpha(int i) { - double num = beta_*beta_ - alpha_*alpha_; - double denom = (2.0*i+alpha_+beta_)*(2.0*i+alpha_+beta_+2); - - if (denom.IsEqual(0.0)) { - if (num.IsNotEqual(0.0)) { - Utils.QL_FAIL("can't compute a_k for jacobi integration"); - } - else { - // l'Hospital - num = 2*beta_; - denom= 2*(2.0*i+alpha_+beta_+1); - - Utils.QL_REQUIRE(denom.IsNotEqual(0.0),()=> "can't compute a_k for jacobi integration"); - } - } - - return num / denom; - } - public override double beta(int i) { - double num = 4.0*i*(i+alpha_)*(i+beta_)*(i+alpha_+beta_); - double denom = (2.0*i+alpha_+beta_)*(2.0*i+alpha_+beta_) - * ((2.0*i+alpha_+beta_)*(2.0*i+alpha_+beta_)-1); - - if (denom.IsEqual(0.0)) { - if (num.IsNotEqual(0.0)) { - Utils.QL_FAIL("can't compute b_k for jacobi integration"); - } else { - // l'Hospital - num = 4.0*i*(i+beta_)* (2.0*i+2*alpha_+beta_); - denom= 2.0*(2.0*i+alpha_+beta_); - denom*=denom-1; - Utils.QL_REQUIRE(denom.IsNotEqual(0.0),()=> "can't compute b_k for jacobi integration"); - } - } - return num / denom; - } - public override double w(double x) { - return Math.Pow(1 - x, alpha_) * Math.Pow(1 + x, beta_); - } - } - - //! Gauss-Legendre polynomial - public class GaussLegendrePolynomial : GaussJacobiPolynomial { - public GaussLegendrePolynomial() : base(0.0, 0.0) { } - } - - //! Gauss-Chebyshev polynomial - public class GaussChebyshevPolynomial : GaussJacobiPolynomial { - public GaussChebyshevPolynomial() : base(-0.5, -0.5) { } - } - - //! Gauss-Chebyshev polynomial (second kind) - public class GaussChebyshev2ndPolynomial : GaussJacobiPolynomial { - public GaussChebyshev2ndPolynomial() : base(0.5, 0.5) { } - } - - //! Gauss-Gegenbauer polynomial - public class GaussGegenbauerPolynomial : GaussJacobiPolynomial { - public GaussGegenbauerPolynomial(double lambda) : base(lambda - 0.5, lambda - 0.5) { } - } - - //! Gauss hyperbolic polynomial - public class GaussHyperbolicPolynomial : GaussianOrthogonalPolynomial { - public override double mu_0() { return Const.M_PI; } - public override double alpha(int i) { return 0.0; } - public override double beta(int i) { return i != 0 ? Const.M_PI_2 * Const.M_PI_2 * i * i : Const.M_PI; } - public override double w(double x) { return 1/Math.Cosh(x); } - } -} diff --git a/src/QLNet/Math/integrals/simpsonintegral.cs b/src/QLNet/Math/integrals/simpsonintegral.cs deleted file mode 100644 index 466d6a147..000000000 --- a/src/QLNet/Math/integrals/simpsonintegral.cs +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! Integral of a one-dimensional function - /*! \test the correctness of the result is tested by checking it - against known good values. - */ - public class SimpsonIntegral : TrapezoidIntegral { - public SimpsonIntegral(double accuracy, int maxIterations) : base(accuracy, maxIterations) { } - - protected override double integrate (Func f, double a, double b) { - // start from the coarsest trapezoid... - int N = 1; - double I = (f(a)+f(b))*(b-a)/2.0, newI; - double adjI = I, newAdjI; - // ...and refine it - int i = 1; - - IIntegrationPolicy ip = new Default(); - do { - newI = ip.integrate(f, a, b, I, N); - N *= 2; - newAdjI = (4.0*newI-I)/3.0; - // good enough? Also, don't run away immediately - if (Math.Abs(adjI-newAdjI) <= absoluteAccuracy() && i > 5) - // ok, exit - return newAdjI; - // oh well. Another step. - I = newI; - adjI = newAdjI; - i++; - } while (i < maxEvaluations()); - Utils.QL_FAIL("max number of iterations reached"); - return 0; - } - } -} diff --git a/src/QLNet/Math/integrals/trapezoidintegral.cs b/src/QLNet/Math/integrals/trapezoidintegral.cs deleted file mode 100644 index 147e0a9ae..000000000 --- a/src/QLNet/Math/integrals/trapezoidintegral.cs +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! Integral of a one-dimensional function - /*! Given a target accuracy \f$ \epsilon \f$, the integral of - a function \f$ f \f$ between \f$ a \f$ and \f$ b \f$ is - calculated by means of the trapezoid formula - \f[ - \int_{a}^{b} f \mathrm{d}x = - \frac{1}{2} f(x_{0}) + f(x_{1}) + f(x_{2}) + \dots - + f(x_{N-1}) + \frac{1}{2} f(x_{N}) - \f] - where \f$ x_0 = a \f$, \f$ x_N = b \f$, and - \f$ x_i = a+i \Delta x \f$ with - \f$ \Delta x = (b-a)/N \f$. The number \f$ N \f$ of intervals - is repeatedly increased until the target accuracy is reached. - - \test the correctness of the result is tested by checking it - against known good values. - */ - public class TrapezoidIntegral : Integrator where IntegrationPolicy : IIntegrationPolicy, new() { - public TrapezoidIntegral(double accuracy, int maxIterations) : base(accuracy, maxIterations){ } - - protected override double integrate (Func f, double a, double b) { - // start from the coarsest trapezoid... - int N = 1; - double I = (f(a)+f(b))*(b-a)/2.0, newI; - // ...and refine it - int i = 1; - - IntegrationPolicy ip = FastActivator.Create(); - do { - newI = ip.integrate(f, a, b, I, N); - N *= ip.nbEvalutions(); - // good enough? Also, don't run away immediately - if (Math.Abs(I-newI) <= absoluteAccuracy() && i > 5) - // ok, exit - return newI; - // oh well. Another step. - I = newI; - i++; - } while (i < maxEvaluations()); - Utils.QL_FAIL("max number of iterations reached"); - return 0; - } - } - - public interface IIntegrationPolicy { - double integrate(Func f, double a, double b, double I, int N); - int nbEvalutions(); - } - - // Integration policies - public struct Default : IIntegrationPolicy { - public double integrate(Func f, double a, double b, double I, int N) { - double sum = 0.0; - double dx = (b-a)/N; - double x = a + dx/2.0; - for (int i=0; i f, double a, double b, double I, int N) { - double sum = 0.0; - double dx = (b - a) / N; - double x = a + dx / 6.0; - double D = 2.0 * dx / 3.0; - for (int i=0; i. - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace QLNet { - //! general linear least squares regression - /*! References: - "Numerical Recipes in C", 2nd edition, - Press, Teukolsky, Vetterling, Flannery, - - \test the correctness of the returned values is tested by - checking their properties. - */ - public class LinearLeastSquaresRegression : LinearLeastSquaresRegression { - public LinearLeastSquaresRegression(List x, List y, List> v) - : base(x,y,v) { } - } - - public class LinearLeastSquaresRegression { - private Vector a_, err_, residuals_, standardErrors_; - - public Vector coefficients() { return a_; } - public Vector residuals() { return residuals_; } - - //! standard parameter errors as given by Excel, R etc. - public Vector standardErrors() { return standardErrors_; } - //! modeling uncertainty as definied in Numerical Recipes - - public Vector error() { return err_; } - - - public LinearLeastSquaresRegression(List x, List y, List> v) { - a_ = new Vector(v.Count, 0); - err_ = new Vector(v.Count, 0); - residuals_ = new Vector(x.Count, 0); - standardErrors_ = new Vector(v.Count, 0); - - Utils.QL_REQUIRE(x.Count == y.Count,()=> "sample set need to be of the same size"); - Utils.QL_REQUIRE(x.Count >= v.Count,()=> "sample set is too small"); - - int i; - int n = x.Count; - int m = v.Count; - - Matrix A = new Matrix(n, m); - for (i = 0; i < m; ++i) - x.ForEach((jj, xx) => A[jj, i] = v[i](xx)); - - SVD svd = new SVD(A); - Matrix V = svd.V(); - Matrix U = svd.U(); - Vector w = svd.singularValues(); - double threshold = n*Const.QL_EPSILON; - - for (i=0; i threshold) { - double u = 0; - U.column(i).ForEach((ii, vv) => u += vv * y[ii]); - u /= w[i]; - - for (int j=0; j r * r); - err_.ForEach((ii, vv) => standardErrors_[ii] = vv * Math.Sqrt(chiSq / (n - 2))); - } - } - - //! linear regression y_i = a_0 + a_1*x_0 +..+a_n*x_{n-1} + eps - public class LinearRegression { - private LinearLeastSquaresRegression> reg_; - - - //! one dimensional linear regression - public LinearRegression(List x, List y) { - reg_ = new LinearLeastSquaresRegression>(argumentWrapper(x), y, linearFcts(1)); - } - - //! multi dimensional linear regression - public LinearRegression(List> x, List y) { - reg_ = new LinearLeastSquaresRegression>(x, y, linearFcts(x[0].Count)); - } - - public Vector coefficients() { return reg_.coefficients(); } - - public Vector residuals() { return reg_.residuals(); } - public Vector standardErrors() { return reg_.standardErrors(); } - - - class LinearFct { - private int i_; - - public LinearFct(int i) { - i_ = i; - } - - public double value(List x) { - return x[i_]; - } - } - - private List, double>> linearFcts(int dims) { - List, double>> retVal = new List, double>>(); - retVal.Add(x => 1.0); - - for (int i=0; i < dims; ++i) { - retVal.Add(new LinearFct(i).value); - } - - return retVal; - } - - private List> argumentWrapper(List x) { - List> retVal = new List>(); - - foreach(var v in x) - retVal.Add(new List() { v }); - - return retVal; - } - }; -} diff --git a/src/QLNet/Math/matrixutilities/BiCGStab.cs b/src/QLNet/Math/matrixutilities/BiCGStab.cs index 190e84f23..e071864e4 100644 --- a/src/QLNet/Math/matrixutilities/BiCGStab.cs +++ b/src/QLNet/Math/matrixutilities/BiCGStab.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -45,7 +45,7 @@ public class BiCGStab public delegate Vector MatrixMult(Vector x); public BiCGStab(MatrixMult A, int maxIter, double relTol, - MatrixMult preConditioner = null) + MatrixMult preConditioner = null) { A_ = A; M_ = preConditioner; diff --git a/src/QLNet/Math/matrixutilities/CholeskyDecomposition.cs b/src/QLNet/Math/matrixutilities/CholeskyDecomposition.cs new file mode 100644 index 000000000..e408f3a2d --- /dev/null +++ b/src/QLNet/Math/matrixutilities/CholeskyDecomposition.cs @@ -0,0 +1,67 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + public static partial class MatrixUtilities + { + public static Matrix CholeskyDecomposition(Matrix S, bool flexible) + { + int i, j, size = S.rows(); + + Utils.QL_REQUIRE(size == S.columns(), () => "input matrix is not a square matrix"); +#if QL_EXTRA_SAFETY_CHECKS + for (i = 0; i < S.rows(); i++) + for (j = 0; j < i; j++) + QL_REQUIRE(S[i][j] == S[j][i], () => + "input matrix is not symmetric"); +#endif + + Matrix result = new Matrix(size, size, 0.0); + double sum; + for (i = 0; i < size; i++) + { + for (j = i; j < size; j++) + { + sum = S[i, j]; + for (int k = 0; k <= i - 1; k++) + { + sum -= result[i, k] * result[j, k]; + } + if (i == j) + { + Utils.QL_REQUIRE(flexible || sum > 0.0, () => "input matrix is not positive definite"); + // To handle positive semi-definite matrices take the + // square root of sum if positive, else zero. + result[i, i] = Math.Sqrt(Math.Max(sum, 0.0)); + } + else + { + // With positive semi-definite matrices is possible + // to have result[i][i]==0.0 + // In this case sum happens to be zero as well + result[j, i] = (sum.IsEqual(0.0) ? 0.0 : sum / result[i, i]); + } + } + } + return result; + } + } +} diff --git a/src/QLNet/Math/matrixutilities/GMRES.cs b/src/QLNet/Math/matrixutilities/GMRES.cs index 92584efb6..d35c6c424 100644 --- a/src/QLNet/Math/matrixutilities/GMRES.cs +++ b/src/QLNet/Math/matrixutilities/GMRES.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,20 +23,20 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - /*! References: - Saad, Yousef. 1996, Iterative methods for sparse linear systems, - http://www-users.cs.umn.edu/~saad/books.html + /*! References: + Saad, Yousef. 1996, Iterative methods for sparse linear systems, + http://www-users.cs.umn.edu/~saad/books.html - Dongarra et al. 1994, - Templates for the Solution of Linear Systems: Building Blocks - for Iterative Methods, 2nd Edition, SIAM, Philadelphia - http://www.netlib.org/templates/templates.pdf + Dongarra et al. 1994, + Templates for the Solution of Linear Systems: Building Blocks + for Iterative Methods, 2nd Edition, SIAM, Philadelphia + http://www.netlib.org/templates/templates.pdf - Christian Kanzow - Numerik linearer Gleichungssysteme (German) - Chapter 6: GMRES und verwandte Verfahren - http://bilder.buecher.de/zusatz/12/12950/12950560_lese_1.pdf - */ + Christian Kanzow + Numerik linearer Gleichungssysteme (German) + Chapter 6: GMRES und verwandte Verfahren + http://bilder.buecher.de/zusatz/12/12950/12950560_lese_1.pdf + */ public struct GMRESResult { @@ -61,7 +61,7 @@ public class GMRES public delegate Vector MatrixMult(Vector x); public GMRES(MatrixMult A, int maxIter, double relTol, - MatrixMult preConditioner = null) + MatrixMult preConditioner = null) { Utils.QL_REQUIRE(maxIter_ > 0, () => "maxIter must be greater then zero"); @@ -121,8 +121,8 @@ protected GMRESResult solveImpl(Vector b, Vector x0) List v = new InitializedList(1, r / g); List h = new InitializedList(1, new Vector(maxIter_, 0.0)); List c = new List(maxIter_ + 1), - s = new List(maxIter_ + 1), - z = new List(maxIter_ + 1); + s = new List(maxIter_ + 1), + z = new List(maxIter_ + 1); z[0] = g; diff --git a/src/QLNet/Math/matrixutilities/PseudoSqrt.cs b/src/QLNet/Math/matrixutilities/PseudoSqrt.cs new file mode 100644 index 000000000..0b3428659 --- /dev/null +++ b/src/QLNet/Math/matrixutilities/PseudoSqrt.cs @@ -0,0 +1,568 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + public static partial class MatrixUtilitites + { + //! algorithm used for matricial pseudo square root + public enum SalvagingAlgorithm + { + None, Spectral, Hypersphere, LowerDiagonal, Higham + } + + public static void normalizePseudoRoot(Matrix matrix, Matrix pseudo) + { + int size = matrix.rows(); + Utils.QL_REQUIRE(size == pseudo.rows(), () => + "matrix/pseudo mismatch: matrix rows are " + size + " while pseudo rows are " + pseudo.columns()); + int pseudoCols = pseudo.columns(); + + // row normalization + for (int i = 0; i < size; ++i) + { + double norm = 0.0; + for (int j = 0; j < pseudoCols; ++j) + norm += pseudo[i, j] * pseudo[i, j]; + if (norm > 0.0) + { + double normAdj = Math.Sqrt(matrix[i, i] / norm); + for (int j = 0; j < pseudoCols; ++j) + pseudo[i, j] *= normAdj; + } + } + } + + + //cost function for hypersphere and lower-diagonal algorithm + class HypersphereCostFunction : CostFunction + { + private int size_; + private bool lowerDiagonal_; + private Matrix targetMatrix_; + private Vector targetVariance_; + private Matrix currentRoot_, tempMatrix_, currentMatrix_; + + public HypersphereCostFunction(Matrix targetMatrix, Vector targetVariance, bool lowerDiagonal) + { + size_ = targetMatrix.rows(); + lowerDiagonal_ = lowerDiagonal; + targetMatrix_ = targetMatrix; + targetVariance_ = targetVariance; + currentRoot_ = new Matrix(size_, size_); + tempMatrix_ = new Matrix(size_, size_); + currentMatrix_ = new Matrix(size_, size_); + } + + public override Vector values(Vector a) + { + Utils.QL_FAIL("values method not implemented"); + return null; + } + + public override double value(Vector x) + { + int i, j, k; + currentRoot_.fill(1); + if (lowerDiagonal_) + { + for (i = 0; i < size_; i++) + { + for (k = 0; k < size_; k++) + { + if (k > i) + { + currentRoot_[i, k] = 0; + } + else + { + for (j = 0; j <= k; j++) + { + if (j == k && k != i) + currentRoot_[i, k] *= Math.Cos(x[i * (i - 1) / 2 + j]); + else if (j != i) + currentRoot_[i, k] *= Math.Sin(x[i * (i - 1) / 2 + j]); + } + } + } + } + } + else + { + for (i = 0; i < size_; i++) + { + for (k = 0; k < size_; k++) + { + for (j = 0; j <= k; j++) + { + if (j == k && k != size_ - 1) + currentRoot_[i, k] *= Math.Cos(x[j * size_ + i]); + else if (j != size_ - 1) + currentRoot_[i, k] *= Math.Sin(x[j * size_ + i]); + } + } + } + } + double temp, error = 0; + tempMatrix_ = Matrix.transpose(currentRoot_); + currentMatrix_ = currentRoot_ * tempMatrix_; + for (i = 0; i < size_; i++) + { + for (j = 0; j < size_; j++) + { + temp = currentMatrix_[i, j] * targetVariance_[i] * targetVariance_[j] - targetMatrix_[i, j]; + error += temp * temp; + } + } + return error; + } + } + + + // Optimization function for hypersphere and lower-diagonal algorithm + private static Matrix hypersphereOptimize(Matrix targetMatrix, Matrix currentRoot, bool lowerDiagonal) + { + int i, j, k, size = targetMatrix.rows(); + Matrix result = new Matrix(currentRoot); + Vector variance = new Vector(size); + for (i = 0; i < size; i++) + { + variance[i] = Math.Sqrt(targetMatrix[i, i]); + } + if (lowerDiagonal) + { + Matrix approxMatrix = result * Matrix.transpose(result); + result = MatrixUtilities.CholeskyDecomposition(approxMatrix, true); + for (i = 0; i < size; i++) + { + for (j = 0; j < size; j++) + { + result[i, j] /= Math.Sqrt(approxMatrix[i, i]); + } + } + } + else + { + for (i = 0; i < size; i++) + { + for (j = 0; j < size; j++) + { + result[i, j] /= variance[i]; + } + } + } + + ConjugateGradient optimize = new ConjugateGradient(); + EndCriteria endCriteria = new EndCriteria(100, 10, 1e-8, 1e-8, 1e-8); + HypersphereCostFunction costFunction = new HypersphereCostFunction(targetMatrix, variance, lowerDiagonal); + NoConstraint constraint = new NoConstraint(); + + // hypersphere vector optimization + + if (lowerDiagonal) + { + Vector theta = new Vector(size * (size - 1) / 2); + const double eps = 1e-16; + for (i = 1; i < size; i++) + { + for (j = 0; j < i; j++) + { + theta[i * (i - 1) / 2 + j] = result[i, j]; + if (theta[i * (i - 1) / 2 + j] > 1 - eps) + theta[i * (i - 1) / 2 + j] = 1 - eps; + if (theta[i * (i - 1) / 2 + j] < -1 + eps) + theta[i * (i - 1) / 2 + j] = -1 + eps; + for (k = 0; k < j; k++) + { + theta[i * (i - 1) / 2 + j] /= Math.Sin(theta[i * (i - 1) / 2 + k]); + if (theta[i * (i - 1) / 2 + j] > 1 - eps) + theta[i * (i - 1) / 2 + j] = 1 - eps; + if (theta[i * (i - 1) / 2 + j] < -1 + eps) + theta[i * (i - 1) / 2 + j] = -1 + eps; + } + theta[i * (i - 1) / 2 + j] = Math.Acos(theta[i * (i - 1) / 2 + j]); + if (j == i - 1) + { + if (result[i, i] < 0) + theta[i * (i - 1) / 2 + j] = -theta[i * (i - 1) / 2 + j]; + } + } + } + Problem p = new Problem(costFunction, constraint, theta); + optimize.minimize(p, endCriteria); + theta = p.currentValue(); + result.fill(1); + for (i = 0; i < size; i++) + { + for (k = 0; k < size; k++) + { + if (k > i) + { + result[i, k] = 0; + } + else + { + for (j = 0; j <= k; j++) + { + if (j == k && k != i) + result[i, k] *= Math.Cos(theta[i * (i - 1) / 2 + j]); + else if (j != i) + result[i, k] *= Math.Sin(theta[i * (i - 1) / 2 + j]); + } + } + } + } + } + else + { + Vector theta = new Vector(size * (size - 1)); + const double eps = 1e-16; + for (i = 0; i < size; i++) + { + for (j = 0; j < size - 1; j++) + { + theta[j * size + i] = result[i, j]; + if (theta[j * size + i] > 1 - eps) + theta[j * size + i] = 1 - eps; + if (theta[j * size + i] < -1 + eps) + theta[j * size + i] = -1 + eps; + for (k = 0; k < j; k++) + { + theta[j * size + i] /= Math.Sin(theta[k * size + i]); + if (theta[j * size + i] > 1 - eps) + theta[j * size + i] = 1 - eps; + if (theta[j * size + i] < -1 + eps) + theta[j * size + i] = -1 + eps; + } + theta[j * size + i] = Math.Acos(theta[j * size + i]); + if (j == size - 2) + { + if (result[i, j + 1] < 0) + theta[j * size + i] = -theta[j * size + i]; + } + } + } + Problem p = new Problem(costFunction, constraint, theta); + optimize.minimize(p, endCriteria); + theta = p.currentValue(); + result.fill(1); + for (i = 0; i < size; i++) + { + for (k = 0; k < size; k++) + { + for (j = 0; j <= k; j++) + { + if (j == k && k != size - 1) + result[i, k] *= Math.Cos(theta[j * size + i]); + else if (j != size - 1) + result[i, k] *= Math.Sin(theta[j * size + i]); + } + } + } + } + + for (i = 0; i < size; i++) + { + for (j = 0; j < size; j++) + { + result[i, j] *= variance[i]; + } + } + return result; + } + + + // Matrix infinity norm. See Golub and van Loan (2.3.10) or + // + private static double normInf(Matrix M) + { + int rows = M.rows(); + int cols = M.columns(); + double norm = 0.0; + for (int i = 0; i < rows; ++i) + { + double colSum = 0.0; + for (int j = 0; j < cols; ++j) + colSum += Math.Abs(M[i, j]); + norm = Math.Max(norm, colSum); + } + return norm; + } + + + // Take a matrix and make all the diagonal entries 1. + private static Matrix projectToUnitDiagonalMatrix(Matrix M) + { + int size = M.rows(); + Utils.QL_REQUIRE(size == M.columns(), () => "matrix not square"); + + Matrix result = new Matrix(M); + for (int i = 0; i < size; ++i) + result[i, i] = 1.0; + + return result; + } + + + // Take a matrix and make all the eigenvalues non-negative + private static Matrix projectToPositiveSemidefiniteMatrix(Matrix M) + { + int size = M.rows(); + Utils.QL_REQUIRE(size == M.columns(), () => "matrix not square"); + + Matrix diagonal = new Matrix(size, size); + SymmetricSchurDecomposition jd = new SymmetricSchurDecomposition(M); + for (int i = 0; i < size; ++i) + diagonal[i, i] = Math.Max(jd.eigenvalues()[i], 0.0); + + Matrix result = jd.eigenvectors() * diagonal * Matrix.transpose(jd.eigenvectors()); + return result; + } + + + // implementation of the Higham algorithm to find the nearest correlation matrix. + private static Matrix highamImplementation(Matrix A, int maxIterations, double tolerance) + { + int size = A.rows(); + Matrix R, Y = new Matrix(A), X = new Matrix(A), deltaS = new Matrix(size, size, 0.0); + + Matrix lastX = new Matrix(X); + Matrix lastY = new Matrix(Y); + + for (int i = 0; i < maxIterations; ++i) + { + R = Y - deltaS; + X = projectToPositiveSemidefiniteMatrix(R); + deltaS = X - R; + Y = projectToUnitDiagonalMatrix(X); + + // convergence test + if (Math.Max(normInf(X - lastX) / normInf(X), + Math.Max(normInf(Y - lastY) / normInf(Y), + normInf(Y - X) / normInf(Y))) + <= tolerance) + { + break; + } + lastX = X; + lastY = Y; + } + + // ensure we return a symmetric matrix + for (int i = 0; i < size; ++i) + for (int j = 0; j < i; ++j) + Y[i, j] = Y[j, i]; + + return Y; + } + + + //! Returns the pseudo square root of a real symmetric matrix + /*! Given a matrix \f$ M \f$, the result \f$ S \f$ is defined + as the matrix such that \f$ S S^T = M. \f$ + If the matrix is not positive semi definite, it can + return an approximation of the pseudo square root + using a (user selected) salvaging algorithm. + + For more information see: "The most general methodology to create + a valid correlation matrix for risk management and option pricing + purposes", by R. Rebonato and P. Jдckel. + The Journal of Risk, 2(2), Winter 1999/2000 + http://www.rebonato.com/correlationmatrix.pdf + + Revised and extended in "Monte Carlo Methods in Finance", + by Peter Jдckel, Chapter 6. + + \pre the given matrix must be symmetric. + + \relates Matrix + + \warning Higham algorithm only works for correlation matrices. + + \test + - the correctness of the results is tested by reproducing + known good data. + - the correctness of the results is tested by checking + returned values against numerical calculations. + */ + public static Matrix pseudoSqrt(Matrix matrix, SalvagingAlgorithm sa) + { + int size = matrix.rows(); + +#if QL_EXTRA_SAFETY_CHECKS + checkSymmetry(matrix); +#else + Utils.QL_REQUIRE(size == matrix.columns(), () => + "non square matrix: " + size + " rows, " + matrix.columns() + " columns"); +#endif + + // spectral (a.k.a Principal Component) analysis + SymmetricSchurDecomposition jd = new SymmetricSchurDecomposition(matrix); + Matrix diagonal = new Matrix(size, size, 0.0); + + // salvaging algorithm + Matrix result = new Matrix(size, size); + bool negative; + switch (sa) + { + case SalvagingAlgorithm.None: + // eigenvalues are sorted in decreasing order + Utils.QL_REQUIRE(jd.eigenvalues()[size - 1] >= -1e-16, () => + "negative eigenvalue(s) (" + jd.eigenvalues()[size - 1] + ")"); + result = MatrixUtilities.CholeskyDecomposition(matrix, true); + break; + + case SalvagingAlgorithm.Spectral: + // negative eigenvalues set to zero + for (int i = 0; i < size; i++) + diagonal[i, i] = Math.Sqrt(Math.Max(jd.eigenvalues()[i], 0.0)); + + result = jd.eigenvectors() * diagonal; + normalizePseudoRoot(matrix, result); + break; + + case SalvagingAlgorithm.Hypersphere: + // negative eigenvalues set to zero + negative = false; + for (int i = 0; i < size; ++i) + { + diagonal[i, i] = Math.Sqrt(Math.Max(jd.eigenvalues()[i], 0.0)); + if (jd.eigenvalues()[i] < 0.0) + negative = true; + } + result = jd.eigenvectors() * diagonal; + normalizePseudoRoot(matrix, result); + + if (negative) + result = hypersphereOptimize(matrix, result, false); + break; + + case SalvagingAlgorithm.LowerDiagonal: + // negative eigenvalues set to zero + negative = false; + for (int i = 0; i < size; ++i) + { + diagonal[i, i] = Math.Sqrt(Math.Max(jd.eigenvalues()[i], 0.0)); + if (jd.eigenvalues()[i] < 0.0) + negative = true; + } + result = jd.eigenvectors() * diagonal; + + normalizePseudoRoot(matrix, result); + + if (negative) + result = hypersphereOptimize(matrix, result, true); + break; + + case SalvagingAlgorithm.Higham: + int maxIterations = 40; + double tol = 1e-6; + result = highamImplementation(matrix, maxIterations, tol); + result = MatrixUtilities.CholeskyDecomposition(result, true); + break; + + default: + Utils.QL_FAIL("unknown salvaging algorithm"); + break; + } + + return result; + } + + public static Matrix rankReducedSqrt(Matrix matrix, + int maxRank, + double componentRetainedPercentage, + SalvagingAlgorithm sa) + { + int size = matrix.rows(); + +#if QL_EXTRA_SAFETY_CHECKS + checkSymmetry(matrix); +#else + Utils.QL_REQUIRE(size == matrix.columns(), () => + "non square matrix: " + size + " rows, " + matrix.columns() + " columns"); +#endif + + Utils.QL_REQUIRE(componentRetainedPercentage > 0.0, () => "no eigenvalues retained"); + Utils.QL_REQUIRE(componentRetainedPercentage <= 1.0, () => "percentage to be retained > 100%"); + Utils.QL_REQUIRE(maxRank >= 1, () => "max rank required < 1"); + + // spectral (a.k.a Principal Component) analysis + SymmetricSchurDecomposition jd = new SymmetricSchurDecomposition(matrix); + Vector eigenValues = jd.eigenvalues(); + + // salvaging algorithm + switch (sa) + { + case SalvagingAlgorithm.None: + // eigenvalues are sorted in decreasing order + Utils.QL_REQUIRE(eigenValues[size - 1] >= -1e-16, () => + "negative eigenvalue(s) (" + eigenValues[size - 1] + ")"); + break; + case SalvagingAlgorithm.Spectral: + // negative eigenvalues set to zero + for (int i = 0; i < size; ++i) + eigenValues[i] = Math.Max(eigenValues[i], 0.0); + break; + case SalvagingAlgorithm.Higham: + { + int maxIterations = 40; + double tolerance = 1e-6; + Matrix adjustedMatrix = highamImplementation(matrix, maxIterations, tolerance); + jd = new SymmetricSchurDecomposition(adjustedMatrix); + eigenValues = jd.eigenvalues(); + } + break; + default: + Utils.QL_FAIL("unknown or invalid salvaging algorithm"); + break; + } + + // factor reduction + double accumulate = 0; + eigenValues.ForEach((ii, vv) => accumulate += eigenValues[ii]); + double enough = componentRetainedPercentage * accumulate; + + if (componentRetainedPercentage.IsEqual(1.0)) + { + // numerical glitches might cause some factors to be discarded + enough *= 1.1; + } + // retain at least one factor + double components = eigenValues[0]; + int retainedFactors = 1; + for (int i = 1; components < enough && i < size; ++i) + { + components += eigenValues[i]; + retainedFactors++; + } + // output is granted to have a rank<=maxRank + retainedFactors = Math.Min(retainedFactors, maxRank); + + Matrix diagonal = new Matrix(size, retainedFactors, 0.0); + for (int i = 0; i < retainedFactors; ++i) + diagonal[i, i] = Math.Sqrt(eigenValues[i]); + Matrix result = jd.eigenvectors() * diagonal; + + normalizePseudoRoot(matrix, result); + return result; + } + } +} diff --git a/src/QLNet/Math/matrixutilities/QRDecomposition.cs b/src/QLNet/Math/matrixutilities/QRDecomposition.cs new file mode 100644 index 000000000..d7bad123e --- /dev/null +++ b/src/QLNet/Math/matrixutilities/QRDecomposition.cs @@ -0,0 +1,164 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + public static partial class MatrixUtilities + { + //! QR decompoisition + /*! This implementation is based on MINPACK + (, + ) + + This subroutine uses householder transformations with column + pivoting (optional) to compute a qr factorization of the + m by n matrix A. That is, qrfac determines an orthogonal + matrix q, a permutation matrix p, and an upper trapezoidal + matrix r with diagonal elements of nonincreasing magnitude, + such that A*p = q*r. + + Return value ipvt is an integer array of length n, which + defines the permutation matrix p such that A*p = q*r. + Column j of p is column ipvt(j) of the identity matrix. + + See lmdiff.cpp for further details. + */ + public static List qrDecomposition(Matrix M, ref Matrix q, ref Matrix r, bool pivot) + { + Matrix mT = Matrix.transpose(M); + int m = M.rows(); + int n = M.columns(); + + List lipvt = new InitializedList(n); + Vector rdiag = new Vector(n); + Vector wa = new Vector(n); + + MINPACK.qrfac(m, n, mT, 0, (pivot) ? 1 : 0, ref lipvt, n, ref rdiag, ref rdiag, wa); + + if (r.columns() != n || r.rows() != n) + r = new Matrix(n, n); + + for (int i = 0; i < n; ++i) + { + r[i, i] = rdiag[i]; + if (i < m) + { + for (int j = i; j < mT.rows() - 1; j++) + r[i, j + 1] = mT[j + 1, i]; + } + } + + if (q.rows() != m || q.columns() != n) + q = new Matrix(m, n); + + Vector w = new Vector(m); + for (int k = 0; k < m; ++k) + { + w.Erase(); + w[k] = 1.0; + + for (int j = 0; j < Math.Min(n, m); ++j) + { + double t3 = mT[j, j]; + if (t3.IsNotEqual(0.0)) + { + double t = 0; + for (int kk = j ; kk < mT.columns(); kk++) + t += (mT[j, kk] * w[kk]) / t3 ; + + for (int i = j; i < m; ++i) + { + w[i] -= mT[j, i] * t; + } + } + q[k, j] = w[j]; + } + } + + List ipvt = new InitializedList(n); + if (pivot) + { + for (int i = 0; i < n; ++i) + ipvt[i] = lipvt[i]; + } + else + { + for (int i = 0; i < n; ++i) + ipvt[i] = i; + } + + return ipvt; + } + + //! QR Solve + /*! This implementation is based on MINPACK + (, + ) + + Given an m by n matrix A, an n by n diagonal matrix d, + and an m-vector b, the problem is to determine an x which + solves the system + + A*x = b , d*x = 0 , + + in the least squares sense. + + d is an input array of length n which must contain the + diagonal elements of the matrix d. + + See lmdiff.cpp for further details. + */ + public static Vector qrSolve(Matrix a, Vector b, bool pivot = true, Vector d = null) + { + int m = a.rows(); + int n = a.columns(); + if (d == null) + d = new Vector(); + Utils.QL_REQUIRE(b.Count == m, () => "dimensions of A and b don't match"); + Utils.QL_REQUIRE(d.Count == n || d.empty(), () => "dimensions of A and d don't match"); + + Matrix q = new Matrix(m, n), r = new Matrix(n, n); + + List lipvt = MatrixUtilities.qrDecomposition(a, ref q, ref r, pivot); + List ipvt = new List(n); + ipvt = lipvt; + + Matrix aT = Matrix.transpose(a); + Matrix rT = Matrix.transpose(r); + + Vector sdiag = new Vector(n); + Vector wa = new Vector(n); + + Vector ld = new Vector(n, 0.0); + if (!d.empty()) + { + ld = d; + } + Vector x = new Vector(n); + Vector qtb = Matrix.transpose(q) * b; + + MINPACK.qrsolv(n, rT, n, ipvt, ld, qtb, x, sdiag, wa); + + return x; + } + } +} \ No newline at end of file diff --git a/src/QLNet/Math/matrixutilities/SVD.cs b/src/QLNet/Math/matrixutilities/SVD.cs new file mode 100644 index 000000000..f8dcca1f2 --- /dev/null +++ b/src/QLNet/Math/matrixutilities/SVD.cs @@ -0,0 +1,580 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! Singular value decomposition + /*! Refer to Golub and Van Loan: Matrix computation, + The Johns Hopkins University Press + + \test the correctness of the returned values is tested by + checking their properties. + */ + public class SVD + { + private Matrix U_, V_; + private Vector s_; + private int m_, n_; + private bool transpose_; + + public SVD(Matrix M) + { + Matrix A; + + /* The implementation requires that rows > columns. + If this is not the case, we decompose M^T instead. + Swapping the resulting U and V gives the desired + result for M as + + M^T = U S V^T (decomposition of M^T) + + M = (U S V^T)^T (transpose) + + M = (V^T^T S^T U^T) ((AB)^T = B^T A^T) + + M = V S U^T (idempotence of transposition, + symmetry of diagonal matrix S) + */ + + if (M.rows() >= M.columns()) + { + A = new Matrix(M); + transpose_ = false; + } + else + { + A = Matrix.transpose(M); + transpose_ = true; + } + + m_ = A.rows(); + n_ = A.columns(); + + // we're sure that m_ >= n_ + s_ = new Vector(n_); + U_ = new Matrix(m_, n_); + V_ = new Matrix(n_, n_); + Vector e = new Vector(n_); + Vector work = new Vector(m_); + int i, j, k; + + // Reduce A to bidiagonal form, storing the diagonal elements + // in s and the super-diagonal elements in e. + int nct = Math.Min(m_ - 1, n_); + int nrt = Math.Max(0, n_ - 2); + for (k = 0; k < Math.Max(nct, nrt); k++) + { + if (k < nct) + { + + // Compute the transformation for the k-th column and + // place the k-th diagonal in s[k]. + // Compute 2-norm of k-th column without under/overflow. + s_[k] = 0; + for (i = k; i < m_; i++) + { + s_[k] = hypot(s_[k], A[i, k]); + } + if (s_[k].IsNotEqual(0.0)) + { + if (A[k, k] < 0.0) + { + s_[k] = -s_[k]; + } + for (i = k; i < m_; i++) + { + A[i, k] /= s_[k]; + } + A[k, k] += 1.0; + } + s_[k] = -s_[k]; + } + for (j = k + 1; j < n_; j++) + { + if ((k < nct) && (s_[k].IsNotEqual(0.0))) + { + + // Apply the transformation. + double t = 0; + for (i = k; i < m_; i++) + { + t += A[i, k] * A[i, j]; + } + t = -t / A[k, k]; + for (i = k; i < m_; i++) + { + A[i, j] += t * A[i, k]; + } + } + + // Place the k-th row of A into e for the + // subsequent calculation of the row transformation. + e[j] = A[k, j]; + } + if (k < nct) + { + // Place the transformation in U for subsequent back multiplication. + for (i = k; i < m_; i++) + { + U_[i, k] = A[i, k]; + } + } + if (k < nrt) + { + // Compute the k-th row transformation and place the k-th super-diagonal in e[k]. + // Compute 2-norm without under/overflow. + e[k] = 0; + for (i = k + 1; i < n_; i++) + { + e[k] = hypot(e[k], e[i]); + } + if (e[k].IsNotEqual(0.0)) + { + if (e[k + 1] < 0.0) + { + e[k] = -e[k]; + } + for (i = k + 1; i < n_; i++) + { + e[i] /= e[k]; + } + e[k + 1] += 1.0; + } + e[k] = -e[k]; + if ((k + 1 < m_) && (e[k].IsNotEqual(0.0))) + { + // Apply the transformation. + for (i = k + 1; i < m_; i++) + { + work[i] = 0.0; + } + for (j = k + 1; j < n_; j++) + { + for (i = k + 1; i < m_; i++) + { + work[i] += e[j] * A[i, j]; + } + } + for (j = k + 1; j < n_; j++) + { + double t = -e[j] / e[k + 1]; + for (i = k + 1; i < m_; i++) + { + A[i, j] += t * work[i]; + } + } + } + + // Place the transformation in V for subsequent back multiplication. + for (i = k + 1; i < n_; i++) + { + V_[i, k] = e[i]; + } + } + } + + // Set up the final bidiagonal matrix or order n. + if (nct < n_) + { + s_[nct] = A[nct, nct]; + } + if (nrt + 1 < n_) + { + e[nrt] = A[nrt, n_ - 1]; + } + e[n_ - 1] = 0.0; + + // generate U + for (j = nct; j < n_; j++) + { + for (i = 0; i < m_; i++) + { + U_[i, j] = 0.0; + } + U_[j, j] = 1.0; + } + for (k = nct - 1; k >= 0; --k) + { + if (s_[k].IsNotEqual(0.0)) + { + for (j = k + 1; j < n_; ++j) + { + double t = 0; + for (i = k; i < m_; i++) + { + t += U_[i, k] * U_[i, j]; + } + t = -t / U_[k, k]; + for (i = k; i < m_; i++) + { + U_[i, j] += t * U_[i, k]; + } + } + for (i = k; i < m_; i++) + { + U_[i, k] = -U_[i, k]; + } + U_[k, k] = 1.0 + U_[k, k]; + for (i = 0; i < k - 1; i++) + { + U_[i, k] = 0.0; + } + } + else + { + for (i = 0; i < m_; i++) + { + U_[i, k] = 0.0; + } + U_[k, k] = 1.0; + } + } + + // generate V + for (k = n_ - 1; k >= 0; --k) + { + if ((k < nrt) && (e[k].IsNotEqual(0.0))) + { + for (j = k + 1; j < n_; ++j) + { + double t = 0; + for (i = k + 1; i < n_; i++) + { + t += V_[i, k] * V_[i, j]; + } + t = -t / V_[k + 1, k]; + for (i = k + 1; i < n_; i++) + { + V_[i, j] += t * V_[i, k]; + } + } + } + for (i = 0; i < n_; i++) + { + V_[i, k] = 0.0; + } + V_[k, k] = 1.0; + } + + // Main iteration loop for the singular values. + int p = n_, pp = p - 1; + int iter = 0; + double eps = Math.Pow(2.0, -52.0); + while (p > 0) + { + int kase; + + // Here is where a test for too many iterations would go. + + // This section of the program inspects for + // negligible elements in the s and e arrays. On + // completion the variables kase and k are set as follows. + + // kase = 1 if s(p) and e[k-1] are negligible and k

= -1; --k) + { + if (k == -1) + { + break; + } + if (Math.Abs(e[k]) <= eps * (Math.Abs(s_[k]) + Math.Abs(s_[k + 1]))) + { + e[k] = 0.0; + break; + } + } + if (k == p - 2) + { + kase = 4; + } + else + { + int ks; + for (ks = p - 1; ks >= k; --ks) + { + if (ks == k) + { + break; + } + double t = (ks != p ? Math.Abs(e[ks]) : 0) + + (ks != k + 1 ? Math.Abs(e[ks - 1]) : 0); + if (Math.Abs(s_[ks]) <= eps * t) + { + s_[ks] = 0.0; + break; + } + } + if (ks == k) + { + kase = 3; + } + else if (ks == p - 1) + { + kase = 1; + } + else + { + kase = 2; + k = ks; + } + } + k++; + + // Perform the task indicated by kase. + switch (kase) + { + + // Deflate negligible s(p). + case 1: + { + double f = e[p - 2]; + e[p - 2] = 0.0; + for (j = p - 2; j >= k; --j) + { + double t = hypot(s_[j], f); + double cs = s_[j] / t; + double sn = f / t; + s_[j] = t; + if (j != k) + { + f = -sn * e[j - 1]; + e[j - 1] = cs * e[j - 1]; + } + for (i = 0; i < n_; i++) + { + t = cs * V_[i, j] + sn * V_[i, p - 1]; + V_[i, p - 1] = -sn * V_[i, j] + cs * V_[i, p - 1]; + V_[i, j] = t; + } + } + } + break; + + // Split at negligible s(k). + case 2: + { + double f = e[k - 1]; + e[k - 1] = 0.0; + for (j = k; j < p; j++) + { + double t = hypot(s_[j], f); + double cs = s_[j] / t; + double sn = f / t; + s_[j] = t; + f = -sn * e[j]; + e[j] = cs * e[j]; + for (i = 0; i < m_; i++) + { + t = cs * U_[i, j] + sn * U_[i, k - 1]; + U_[i, k - 1] = -sn * U_[i, j] + cs * U_[i, k - 1]; + U_[i, j] = t; + } + } + } + break; + + // Perform one qr step. + case 3: + { + // Calculate the shift. + double scale = Math.Max( + Math.Max( + Math.Max( + Math.Max(Math.Abs(s_[p - 1]), + Math.Abs(s_[p - 2])), + Math.Abs(e[p - 2])), + Math.Abs(s_[k])), + Math.Abs(e[k])); + double sp = s_[p - 1] / scale; + double spm1 = s_[p - 2] / scale; + double epm1 = e[p - 2] / scale; + double sk = s_[k] / scale; + double ek = e[k] / scale; + double b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) / 2.0; + double c = (sp * epm1) * (sp * epm1); + double shift = 0.0; + if ((b.IsNotEqual(0.0)) || (c.IsNotEqual(0.0))) + { + shift = Math.Sqrt(b * b + c); + if (b < 0.0) + { + shift = -shift; + } + shift = c / (b + shift); + } + double f = (sk + sp) * (sk - sp) + shift; + double g = sk * ek; + + // Chase zeros. + for (j = k; j < p - 1; j++) + { + double t = hypot(f, g); + double cs = f / t; + double sn = g / t; + if (j != k) + { + e[j - 1] = t; + } + f = cs * s_[j] + sn * e[j]; + e[j] = cs * e[j] - sn * s_[j]; + g = sn * s_[j + 1]; + s_[j + 1] = cs * s_[j + 1]; + for (i = 0; i < n_; i++) + { + t = cs * V_[i, j] + sn * V_[i, j + 1]; + V_[i, j + 1] = -sn * V_[i, j] + cs * V_[i, j + 1]; + V_[i, j] = t; + } + t = hypot(f, g); + cs = f / t; + sn = g / t; + s_[j] = t; + f = cs * e[j] + sn * s_[j + 1]; + s_[j + 1] = -sn * e[j] + cs * s_[j + 1]; + g = sn * e[j + 1]; + e[j + 1] = cs * e[j + 1]; + if (j < m_ - 1) + { + for (i = 0; i < m_; i++) + { + t = cs * U_[i, j] + sn * U_[i, j + 1]; + U_[i, j + 1] = -sn * U_[i, j] + cs * U_[i, j + 1]; + U_[i, j] = t; + } + } + } + e[p - 2] = f; + iter = iter + 1; + } + break; + + // Convergence. + case 4: + { + // Make the singular values positive. + if (s_[k] <= 0.0) + { + s_[k] = (s_[k] < 0.0 ? -s_[k] : 0.0); + for (i = 0; i <= pp; i++) + { + V_[i, k] = -V_[i, k]; + } + } + + // Order the singular values. + while (k < pp) + { + if (s_[k] >= s_[k + 1]) + { + break; + } + s_.swap(k, k + 1); + if (k < n_ - 1) + { + for (i = 0; i < n_; i++) + { + V_.swap(i, k, i, k + 1); + } + } + if (k < m_ - 1) + { + for (i = 0; i < m_; i++) + { + U_.swap(i, k, i, k + 1); + } + } + k++; + } + iter = 0; + --p; + } + break; + } + } + } + + + public Matrix U() { return (transpose_ ? V_ : U_); } + public Matrix V() { return (transpose_ ? U_ : V_); } + public Matrix S() + { + Matrix S = new Matrix(n_, n_); + for (int i = 0; i < n_; i++) + { + for (int j = 0; j < n_; j++) + { + S[i, j] = 0.0; + } + S[i, i] = s_[i]; + } + return S; + } + + public Vector singularValues() { return s_; } + public double norm2() { return s_[0]; } + public double cond() { return s_[0] / s_[n_ - 1]; } + public int rank() + { + double eps = Math.Pow(2.0, -52.0); + double tol = m_ * s_[0] * eps; + int r = 0; + for (int i = 0; i < s_.size(); i++) + { + if (s_[i] > tol) + { + r++; + } + } + return r; + } + + public Vector solveFor(Vector b) + { + Matrix W = new Matrix(n_, n_, 0.0); + for (int i = 0; i < n_; i++) + W[i, i] = 1.0 / s_[i]; + + Matrix inverse = V() * W * Matrix.transpose(U()); + Vector result = inverse * b; + return result; + } + + + /* returns hypotenuse of real (non-complex) scalars a and b by avoiding underflow/overflow + using (a * sqrt( 1 + (b/a) * (b/a))), rather than sqrt(a*a + b*b). */ + private double hypot(double a, double b) + { + if (a.IsEqual(0.0)) + { + return Math.Abs(b); + } + else + { + double c = b / a; + return Math.Abs(a) * Math.Sqrt(1 + c * c); + } + } + } +} diff --git a/src/QLNet/Math/matrixutilities/SparseMatrix.cs b/src/QLNet/Math/matrixutilities/SparseMatrix.cs index ad7878d85..a71f5af0e 100644 --- a/src/QLNet/Math/matrixutilities/SparseMatrix.cs +++ b/src/QLNet/Math/matrixutilities/SparseMatrix.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,270 +23,270 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //general sparse matrix taken from http://www.blackbeltcoder.com/Articles/algorithms/creating-a-sparse-matrix-in-net and completed for QLNet - public class SparseMatrix - { - // Master dictionary hold rows of column dictionary - protected Dictionary> _rows; - - //general dimensions - protected int rows_, columns_; - - ///

- /// Constructs a SparseMatrix instance. - /// - public SparseMatrix() - { - _rows = new Dictionary>(); - } - - /// - /// Constructs a SparseMatrix instance. - /// - public SparseMatrix(int rows, int columns) - { - rows_ = rows; - columns_ = columns; - _rows = new Dictionary>(); - } - - /// - /// Constructs a SparseMatrix instance. - /// - public SparseMatrix(SparseMatrix lhs) - { - rows_ = lhs.rows_; - columns_ = lhs.columns_; - _rows = new Dictionary>(); - foreach(KeyValuePair> row in lhs._rows) - { - if (!_rows.ContainsKey(row.Key)) - _rows.Add(row.Key, new Dictionary()); - - foreach(KeyValuePair col in row.Value) - { - if (!_rows[row.Key].ContainsKey(col.Key)) - _rows[row.Key].Add(col.Key, col.Value); - } - } - } - - /// - /// Gets or sets the value at the specified matrix position. - /// - /// Matrix row - /// Matrix column - public double this[int row, int col] - { - get - { - return GetAt(row, col); - } - set - { - SetAt(row, col, value); - } - } - - /// - /// Gets the value at the specified matrix position. - /// - /// Matrix row - /// Matrix column - /// Value at the specified position - public double GetAt(int row, int col) - { - Dictionary cols; - if (_rows.TryGetValue(row, out cols)) - { - double value = default(double); - if (cols.TryGetValue(col, out value)) - return value; - } - return default(double); - } - - /// - /// Sets the value at the specified matrix position. - /// - /// Matrix row - /// Matrix column - /// New value - public void SetAt(int row, int col, double value) - { - if (EqualityComparer.Default.Equals(value, default(double))) - { - // Remove any existing object if value is default(T) - RemoveAt(row, col); - } - else - { - // Set value - Dictionary cols; - if (!_rows.TryGetValue(row, out cols)) - { - cols = new Dictionary(); - _rows.Add(row, cols); - } - cols[col] = value; - } - } - - /// - /// Removes the value at the specified matrix position. - /// - /// Matrix row - /// Matrix column - public void RemoveAt(int row, int col) - { - Dictionary cols; - if (_rows.TryGetValue(row, out cols)) - { - // Remove column from this row - cols.Remove(col); - // Remove entire row if empty - if (cols.Count == 0) - _rows.Remove(row); - } - } - - /// - /// Returns all items in the specified row. - /// - /// Matrix row - public IEnumerable GetRowData(int row) - { - Dictionary cols; - if (_rows.TryGetValue(row, out cols)) + //general sparse matrix taken from http://www.blackbeltcoder.com/Articles/algorithms/creating-a-sparse-matrix-in-net and completed for QLNet + public class SparseMatrix + { + // Master dictionary hold rows of column dictionary + protected Dictionary> _rows; + + //general dimensions + protected int rows_, columns_; + + /// + /// Constructs a SparseMatrix instance. + /// + public SparseMatrix() + { + _rows = new Dictionary>(); + } + + /// + /// Constructs a SparseMatrix instance. + /// + public SparseMatrix(int rows, int columns) + { + rows_ = rows; + columns_ = columns; + _rows = new Dictionary>(); + } + + /// + /// Constructs a SparseMatrix instance. + /// + public SparseMatrix(SparseMatrix lhs) + { + rows_ = lhs.rows_; + columns_ = lhs.columns_; + _rows = new Dictionary>(); + foreach (KeyValuePair> row in lhs._rows) + { + if (!_rows.ContainsKey(row.Key)) + _rows.Add(row.Key, new Dictionary()); + + foreach (KeyValuePair col in row.Value) { - foreach (KeyValuePair pair in cols) - { - yield return pair.Value; - } + if (!_rows[row.Key].ContainsKey(col.Key)) + _rows[row.Key].Add(col.Key, col.Value); } - } - - /// - /// Returns the number of items in the specified row. - /// - /// Matrix row - public int GetRowDataCount(int row) - { + } + } + + /// + /// Gets or sets the value at the specified matrix position. + /// + /// Matrix row + /// Matrix column + public double this[int row, int col] + { + get + { + return GetAt(row, col); + } + set + { + SetAt(row, col, value); + } + } + + /// + /// Gets the value at the specified matrix position. + /// + /// Matrix row + /// Matrix column + /// Value at the specified position + public double GetAt(int row, int col) + { + Dictionary cols; + if (_rows.TryGetValue(row, out cols)) + { + double value = default(double); + if (cols.TryGetValue(col, out value)) + return value; + } + return default(double); + } + + /// + /// Sets the value at the specified matrix position. + /// + /// Matrix row + /// Matrix column + /// New value + public void SetAt(int row, int col, double value) + { + if (EqualityComparer.Default.Equals(value, default(double))) + { + // Remove any existing object if value is default(T) + RemoveAt(row, col); + } + else + { + // Set value Dictionary cols; - if (_rows.TryGetValue(row, out cols)) + if (!_rows.TryGetValue(row, out cols)) { - return cols.Count; + cols = new Dictionary(); + _rows.Add(row, cols); } - return 0; - } - - /// - /// Returns all items in the specified column. - /// This method is less efficent than GetRowData(). - /// - /// Matrix column - /// - public IEnumerable GetColumnData(int col) - { - foreach (KeyValuePair> rowdata in _rows) - { - double result; - if (rowdata.Value.TryGetValue(col, out result)) - yield return result; - } - } - - /// - /// Returns the number of items in the specified column. - /// This method is less efficent than GetRowDataCount(). - /// - /// Matrix column - public int GetColumnDataCount(int col) - { - int result = 0; - - foreach (KeyValuePair> cols in _rows) + cols[col] = value; + } + } + + /// + /// Removes the value at the specified matrix position. + /// + /// Matrix row + /// Matrix column + public void RemoveAt(int row, int col) + { + Dictionary cols; + if (_rows.TryGetValue(row, out cols)) + { + // Remove column from this row + cols.Remove(col); + // Remove entire row if empty + if (cols.Count == 0) + _rows.Remove(row); + } + } + + /// + /// Returns all items in the specified row. + /// + /// Matrix row + public IEnumerable GetRowData(int row) + { + Dictionary cols; + if (_rows.TryGetValue(row, out cols)) + { + foreach (KeyValuePair pair in cols) { - if (cols.Value.ContainsKey(col)) - result++; + yield return pair.Value; } - return result; - } + } + } + + /// + /// Returns the number of items in the specified row. + /// + /// Matrix row + public int GetRowDataCount(int row) + { + Dictionary cols; + if (_rows.TryGetValue(row, out cols)) + { + return cols.Count; + } + return 0; + } + + /// + /// Returns all items in the specified column. + /// This method is less efficent than GetRowData(). + /// + /// Matrix column + /// + public IEnumerable GetColumnData(int col) + { + foreach (KeyValuePair> rowdata in _rows) + { + double result; + if (rowdata.Value.TryGetValue(col, out result)) + yield return result; + } + } + + /// + /// Returns the number of items in the specified column. + /// This method is less efficent than GetRowDataCount(). + /// + /// Matrix column + public int GetColumnDataCount(int col) + { + int result = 0; + + foreach (KeyValuePair> cols in _rows) + { + if (cols.Value.ContainsKey(col)) + result++; + } + return result; + } - public void Clear() - { - _rows.Clear(); - } + public void Clear() + { + _rows.Clear(); + } - public int rows() { return rows_; } - public int columns() { return columns_; } - public int values() { return _rows.Sum(x => GetRowDataCount(x.Key)); } + public int rows() { return rows_; } + public int columns() { return columns_; } + public int values() { return _rows.Sum(x => GetRowDataCount(x.Key)); } - //operator overloads - public static SparseMatrix operator *(double a, SparseMatrix m) - { - SparseMatrix result = new SparseMatrix(m.rows(), m.columns()); + //operator overloads + public static SparseMatrix operator *(double a, SparseMatrix m) + { + SparseMatrix result = new SparseMatrix(m.rows(), m.columns()); - foreach (KeyValuePair> row in m._rows) + foreach (KeyValuePair> row in m._rows) + { + foreach (KeyValuePair col in row.Value) { - foreach (KeyValuePair col in row.Value) - { - double val = a * col.Value; - result.SetAt(row.Key, col.Key, val); - } + double val = a * col.Value; + result.SetAt(row.Key, col.Key, val); } - - return result; - } + } - public static Vector operator *(SparseMatrix m, Vector x) - { - Vector b = new Vector(x.size()); + return result; + } - foreach(KeyValuePair> row in m._rows) - { - double val = 0.0; - foreach (KeyValuePair col in row.Value) - val += b[col.Key] * col.Value; + public static Vector operator *(SparseMatrix m, Vector x) + { + Vector b = new Vector(x.size()); - b[row.Key] = val; - } - return b; - } + foreach (KeyValuePair> row in m._rows) + { + double val = 0.0; + foreach (KeyValuePair col in row.Value) + val += b[col.Key] * col.Value; - public static SparseMatrix operator *(SparseMatrix m1, SparseMatrix m2) - { - Utils.QL_REQUIRE(m1.columns() == m2.rows() && m1.rows() == m2.columns(), () => "invalid dimensions"); - SparseMatrix result = new SparseMatrix(m1.rows(), m2.columns()); + b[row.Key] = val; + } + return b; + } - foreach (KeyValuePair> row in m1._rows) - { - foreach (KeyValuePair colRight in m2._rows[row.Key]) - { - double val = 0.0; - foreach (KeyValuePair col in row.Value) - val += m2._rows[row.Key][colRight.Key] * col.Value; + public static SparseMatrix operator *(SparseMatrix m1, SparseMatrix m2) + { + Utils.QL_REQUIRE(m1.columns() == m2.rows() && m1.rows() == m2.columns(), () => "invalid dimensions"); + SparseMatrix result = new SparseMatrix(m1.rows(), m2.columns()); - result.SetAt(row.Key, colRight.Key, val); - } + foreach (KeyValuePair> row in m1._rows) + { + foreach (KeyValuePair colRight in m2._rows[row.Key]) + { + double val = 0.0; + foreach (KeyValuePair col in row.Value) + val += m2._rows[row.Key][colRight.Key] * col.Value; + result.SetAt(row.Key, colRight.Key, val); } - return result; - } - public static SparseMatrix operator +(SparseMatrix m1, SparseMatrix m2) - { - SparseMatrix result = new SparseMatrix(m1); + } + return result; + } + + public static SparseMatrix operator +(SparseMatrix m1, SparseMatrix m2) + { + SparseMatrix result = new SparseMatrix(m1); - foreach (KeyValuePair> row in m2._rows) + foreach (KeyValuePair> row in m2._rows) + { + foreach (KeyValuePair col in row.Value) { - foreach (KeyValuePair col in row.Value) - { - double val = result.GetAt(row.Key, col.Key) + col.Value; - result.SetAt(row.Key, col.Key, val); - } + double val = result.GetAt(row.Key, col.Key) + col.Value; + result.SetAt(row.Key, col.Key, val); } - return result; - } - } + } + return result; + } + } } diff --git a/src/QLNet/Math/matrixutilities/SymmetricSchurDecomposition.cs b/src/QLNet/Math/matrixutilities/SymmetricSchurDecomposition.cs new file mode 100644 index 000000000..c0bb5370a --- /dev/null +++ b/src/QLNet/Math/matrixutilities/SymmetricSchurDecomposition.cs @@ -0,0 +1,195 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + //! symmetric threshold Jacobi algorithm. + /*! Given a real symmetric matrix S, the Schur decomposition + finds the eigenvalues and eigenvectors of S. If D is the + diagonal matrix formed by the eigenvalues and U the + unitarian matrix of the eigenvectors we can write the + Schur decomposition as + \f[ S = U \cdot D \cdot U^T \, ,\f] + where \f$ \cdot \f$ is the standard matrix product + and \f$ ^T \f$ is the transpose operator. + This class implements the Schur decomposition using the + symmetric threshold Jacobi algorithm. For details on the + different Jacobi transfomations see "Matrix computation," + second edition, by Golub and Van Loan, + The Johns Hopkins University Press + + \test the correctness of the returned values is tested by + checking their properties. + */ + public class SymmetricSchurDecomposition + { + private Vector diagonal_; + private Matrix eigenVectors_; + + /*! \pre s must be symmetric */ + public SymmetricSchurDecomposition(Matrix s) + { + diagonal_ = new Vector(s.rows()); + eigenVectors_ = new Matrix(s.rows(), s.columns(), 0.0); + + Utils.QL_REQUIRE(s.rows() > 0 && s.columns() > 0, () => "null matrix given"); + Utils.QL_REQUIRE(s.rows() == s.columns(), () => "input matrix must be square"); + + int size = s.rows(); + for (int q = 0; q < size; q++) + { + diagonal_[q] = s[q, q]; + eigenVectors_[q, q] = 1.0; + } + Matrix ss = new Matrix(s); + + Vector tmpDiag = new Vector(diagonal_); + Vector tmpAccumulate = new Vector(size, 0.0); + double threshold, epsPrec = 1e-15; + bool keeplooping = true; + int maxIterations = 100, ite = 1; + do + { + //main loop + double sum = 0; + for (int a = 0; a < size - 1; a++) + { + for (int b = a + 1; b < size; b++) + { + sum += Math.Abs(ss[a, b]); + } + } + + if (sum.IsEqual(0.0)) + { + keeplooping = false; + } + else + { + /* To speed up computation a threshold is introduced to + make sure it is worthy to perform the Jacobi rotation + */ + if (ite < 5) + threshold = 0.2 * sum / (size * size); + else + threshold = 0.0; + + int j, k, l; + for (j = 0; j < size - 1; j++) + { + for (k = j + 1; k < size; k++) + { + double sine, rho, cosin, heig, tang, beta; + double smll = Math.Abs(ss[j, k]); + if (ite > 5 && + smll < epsPrec * Math.Abs(diagonal_[j]) && + smll < epsPrec * Math.Abs(diagonal_[k])) + { + ss[j, k] = 0; + } + else if (Math.Abs(ss[j, k]) > threshold) + { + heig = diagonal_[k] - diagonal_[j]; + if (smll < epsPrec * Math.Abs(heig)) + { + tang = ss[j, k] / heig; + } + else + { + beta = 0.5 * heig / ss[j, k]; + tang = 1.0 / (Math.Abs(beta) + + Math.Sqrt(1 + beta * beta)); + if (beta < 0) + tang = -tang; + } + cosin = 1 / Math.Sqrt(1 + tang * tang); + sine = tang * cosin; + rho = sine / (1 + cosin); + heig = tang * ss[j, k]; + tmpAccumulate[j] -= heig; + tmpAccumulate[k] += heig; + diagonal_[j] -= heig; + diagonal_[k] += heig; + ss[j, k] = 0.0; + for (l = 0; l + 1 <= j; l++) + jacobiRotate_(ss, rho, sine, l, j, l, k); + for (l = j + 1; l <= k - 1; l++) + jacobiRotate_(ss, rho, sine, j, l, l, k); + for (l = k + 1; l < size; l++) + jacobiRotate_(ss, rho, sine, j, l, k, l); + for (l = 0; l < size; l++) + jacobiRotate_(eigenVectors_, + rho, sine, l, j, l, k); + } + } + } + for (k = 0; k < size; k++) + { + tmpDiag[k] += tmpAccumulate[k]; + diagonal_[k] = tmpDiag[k]; + tmpAccumulate[k] = 0.0; + } + } + } + while (++ite <= maxIterations && keeplooping); + + Utils.QL_REQUIRE(ite <= maxIterations, () => "Too many iterations (" + maxIterations + ") reached"); + + // sort (eigenvalues, eigenvectors) + List> temp = new InitializedList>(size); + int row, col; + for (col = 0; col < size; col++) + { + Vector eigenVector = new Vector(size); + eigenVectors_.column(col).ForEach((ii, xx) => eigenVector[ii] = xx); + temp[col] = new KeyValuePair(diagonal_[col], eigenVector); + } + // sort descending: std::greater + temp.Sort((x, y) => y.Key.CompareTo(x.Key)); + double maxEv = temp[0].Key; + for (col = 0; col < size; col++) + { + // check for round-off errors + diagonal_[col] = (Math.Abs(temp[col].Key / maxEv) < 1e-16 ? 0.0 : temp[col].Key); + double sign = 1.0; + if (temp[col].Value[0] < 0.0) + sign = -1.0; + for (row = 0; row < size; row++) + { + eigenVectors_[row, col] = sign * temp[col].Value[row]; + } + } + } + + + public Vector eigenvalues() { return diagonal_; } + public Matrix eigenvectors() { return eigenVectors_; } + + private void jacobiRotate_(Matrix m, double rot, double dil, int j1, int k1, int j2, int k2) + { + double x1, x2; + x1 = m[j1, k1]; + x2 = m[j2, k2]; + m[j1, k1] = x1 - dil * (x2 + x1 * rot); + m[j2, k2] = x2 + dil * (x1 - x2 * rot); + } + } +} diff --git a/src/QLNet/Math/matrixutilities/TqrEigenDecomposition.cs b/src/QLNet/Math/matrixutilities/TqrEigenDecomposition.cs index c6e33468c..790f69be1 100644 --- a/src/QLNet/Math/matrixutilities/TqrEigenDecomposition.cs +++ b/src/QLNet/Math/matrixutilities/TqrEigenDecomposition.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -33,162 +33,166 @@ namespace QLNet \test the correctness of the result is tested by checking it against known good values. */ - public class TqrEigenDecomposition + public class TqrEigenDecomposition { - - public enum EigenVectorCalculation - { + + public enum EigenVectorCalculation + { WithEigenVector, WithoutEigenVector, - OnlyFirstRowEigenVector + OnlyFirstRowEigenVector } - public enum ShiftStrategy - { + public enum ShiftStrategy + { NoShift, Overrelaxation, - CloseEigenValue + CloseEigenValue } public TqrEigenDecomposition(Vector diag, Vector sub, EigenVectorCalculation calc = EigenVectorCalculation.WithEigenVector, - ShiftStrategy strategy = ShiftStrategy.CloseEigenValue) + ShiftStrategy strategy = ShiftStrategy.CloseEigenValue) { iter_ = 0; d_ = new Vector(diag); - + int row = calc == EigenVectorCalculation.WithEigenVector ? d_.size() : - calc == EigenVectorCalculation.WithoutEigenVector ? 0 : 1; + calc == EigenVectorCalculation.WithoutEigenVector ? 0 : 1; ev_ = new Matrix(row, d_.size(), 0.0); - + int n = diag.size(); - Utils.QL_REQUIRE( n == sub.size() + 1, () => "Wrong dimensions" ); + Utils.QL_REQUIRE(n == sub.size() + 1, () => "Wrong dimensions"); - Vector e = new Vector(n,0.0); + Vector e = new Vector(n, 0.0); int i; - for ( i = 1; i < e.Count; ++i ) + for (i = 1; i < e.Count; ++i) { - e[i] = sub[i-1]; + e[i] = sub[i - 1]; } - for (i=0; i < ev_.rows(); ++i) + for (i = 0; i < ev_.rows(); ++i) { - ev_[i,i] = 1.0; + ev_[i, i] = 1.0; } - for (int k=n-1; k >=1; --k) + for (int k = n - 1; k >= 1; --k) { - while (!offDiagIsZero(k, e)) + while (!offDiagIsZero(k, e)) { - int l = k; - while (--l > 0 && !offDiagIsZero(l,e)); - iter_++; - - double q = d_[l]; - if (strategy != ShiftStrategy.NoShift) - { - // calculated eigenvalue of 2x2 sub matrix of - // [ d_[k-1] e_[k] ] - // [ e_[k] d_[k] ] - // which is closer to d_[k+1]. - // FLOATING_POINT_EXCEPTION - double t1 = Math.Sqrt( - 0.25*(d_[k]*d_[k] + d_[k-1]*d_[k-1]) - - 0.5*d_[k-1]*d_[k] + e[k]*e[k]); - double t2 = 0.5*(d_[k]+d_[k-1]); - - double lambda = (Math.Abs(t2+t1 - d_[k]) < Math.Abs(t2-t1 - d_[k]))? - t2+t1 : t2-t1; - - if (strategy == ShiftStrategy.CloseEigenValue) - { - q-=lambda; - } - else - { - q-=((k==n-1)? 1.25 : 1.0)*lambda; - } - } - - // the QR transformation - double sine = 1.0; - double cosine = 1.0; - double u = 0.0; - - bool recoverUnderflow = false; - for (i=l+1; i <= k && !recoverUnderflow; ++i) - { - double h = cosine*e[i]; - double p = sine*e[i]; - - e[i-1] = Math.Sqrt(p*p+q*q); - if (e[i-1].IsNotEqual(0.0)) { - sine = p/e[i-1]; - cosine = q/e[i-1]; - - double g = d_[i-1]-u; - double t = (d_[i]-g)*sine+2*cosine*h; - - u = sine*t; - d_[i-1] = g + u; - q = cosine*t - h; - - for (int j=0; j < ev_.rows(); ++j) - { - double tmp = ev_[j,i-1]; - ev_[j,i-1] = sine*ev_[j,i] + cosine*tmp; - ev_[j,i] = cosine*ev_[j,i] - sine*tmp; - } - } - else - { - // recover from underflow - d_[i-1] -= u; - e[l] = 0.0; - recoverUnderflow = true; - } - } - - if (!recoverUnderflow) { - d_[k] -= u; - e[k] = q; - e[l] = 0.0; - } + int l = k; + while (--l > 0 && !offDiagIsZero(l, e)); + iter_++; + + double q = d_[l]; + if (strategy != ShiftStrategy.NoShift) + { + // calculated eigenvalue of 2x2 sub matrix of + // [ d_[k-1] e_[k] ] + // [ e_[k] d_[k] ] + // which is closer to d_[k+1]. + // FLOATING_POINT_EXCEPTION + double t1 = Math.Sqrt( + 0.25 * (d_[k] * d_[k] + d_[k - 1] * d_[k - 1]) + - 0.5 * d_[k - 1] * d_[k] + e[k] * e[k]); + double t2 = 0.5 * (d_[k] + d_[k - 1]); + + double lambda = (Math.Abs(t2 + t1 - d_[k]) < Math.Abs(t2 - t1 - d_[k]))? + t2 + t1 : t2 - t1; + + if (strategy == ShiftStrategy.CloseEigenValue) + { + q -= lambda; + } + else + { + q -= ((k == n - 1) ? 1.25 : 1.0) * lambda; + } + } + + // the QR transformation + double sine = 1.0; + double cosine = 1.0; + double u = 0.0; + + bool recoverUnderflow = false; + for (i = l + 1; i <= k && !recoverUnderflow; ++i) + { + double h = cosine * e[i]; + double p = sine * e[i]; + + e[i - 1] = Math.Sqrt(p * p + q * q); + if (e[i - 1].IsNotEqual(0.0)) + { + sine = p / e[i - 1]; + cosine = q / e[i - 1]; + + double g = d_[i - 1] - u; + double t = (d_[i] - g) * sine + 2 * cosine * h; + + u = sine * t; + d_[i - 1] = g + u; + q = cosine * t - h; + + for (int j = 0; j < ev_.rows(); ++j) + { + double tmp = ev_[j, i - 1]; + ev_[j, i - 1] = sine * ev_[j, i] + cosine * tmp; + ev_[j, i] = cosine * ev_[j, i] - sine * tmp; + } + } + else + { + // recover from underflow + d_[i - 1] -= u; + e[l] = 0.0; + recoverUnderflow = true; + } + } + + if (!recoverUnderflow) + { + d_[k] -= u; + e[k] = q; + e[l] = 0.0; + } } - } - - // sort (eigenvalues, eigenvectors), - // code taken from symmetricSchureDecomposition.cpp - List > > temp = new InitializedList>>(n); - List eigenVector = new InitializedList(ev_.rows()); - for (i=0; i > > temp = new InitializedList>>(n); + List eigenVector = new InitializedList(ev_.rows()); + for (i = 0; i < n; i++) + { if (ev_.rows() > 0) - eigenVector = ev_.column(i) ; + eigenVector = ev_.column(i) ; + + temp[i] = new KeyValuePair>(d_[i], eigenVector); + } - temp[i] = new KeyValuePair>(d_[i], eigenVector); - } - - temp.Sort( KeyValuePairCompare ); + temp.Sort(KeyValuePairCompare); - // first element is positive - for (i=0; i 0 && temp[i].Value[0]<0.0) - sign = -1.0; - for (int j=0; j 0 && temp[i].Value[0] < 0.0) + sign = -1.0; + for (int j = 0; j < ev_.rows(); ++j) + { + ev_[j, i] = sign * temp[i].Value[j]; } - } + } } - static int KeyValuePairCompare( KeyValuePair> a, KeyValuePair> b ) + static int KeyValuePairCompare(KeyValuePair> a, KeyValuePair> b) { - return a.Key.CompareTo( b.Key ); + return a.Key.CompareTo(b.Key); } public Vector eigenvalues() { return d_; } @@ -199,10 +203,10 @@ static int KeyValuePairCompare( KeyValuePair> a, KeyValuePa private bool offDiagIsZero(int k, Vector e) { - return (Math.Abs(d_[k-1])+Math.Abs(d_[k])).IsEqual(Math.Abs(d_[k - 1]) + Math.Abs(d_[k]) + Math.Abs(e[k])); + return (Math.Abs(d_[k - 1]) + Math.Abs(d_[k])).IsEqual(Math.Abs(d_[k - 1]) + Math.Abs(d_[k]) + Math.Abs(e[k])); } private int iter_; private Vector d_; private Matrix ev_; - }; + } } diff --git a/src/QLNet/Math/matrixutilities/choleskydecomposition.cs b/src/QLNet/Math/matrixutilities/choleskydecomposition.cs deleted file mode 100644 index 3e0bc07fb..000000000 --- a/src/QLNet/Math/matrixutilities/choleskydecomposition.cs +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - public static partial class MatrixUtilities { - public static Matrix CholeskyDecomposition(Matrix S, bool flexible) { - int i, j, size = S.rows(); - - Utils.QL_REQUIRE(size == S.columns(),()=> "input matrix is not a square matrix"); - #if QL_EXTRA_SAFETY_CHECKS - for (i=0; i - "input matrix is not symmetric"); - #endif - - Matrix result = new Matrix(size, size, 0.0); - double sum; - for (i=0; i 0.0,()=> "input matrix is not positive definite"); - // To handle positive semi-definite matrices take the - // square root of sum if positive, else zero. - result[i,i] = Math.Sqrt(Math.Max(sum, 0.0)); - } else { - // With positive semi-definite matrices is possible - // to have result[i][i]==0.0 - // In this case sum happens to be zero as well - result[j,i] = (sum.IsEqual(0.0) ? 0.0 : sum/result[i,i]); - } - } - } - return result; - } - } -} diff --git a/src/QLNet/Math/matrixutilities/pseudosqrt.cs b/src/QLNet/Math/matrixutilities/pseudosqrt.cs deleted file mode 100644 index 990afce0a..000000000 --- a/src/QLNet/Math/matrixutilities/pseudosqrt.cs +++ /dev/null @@ -1,501 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - public static partial class MatrixUtilitites { - //! algorithm used for matricial pseudo square root - public enum SalvagingAlgorithm { - None, Spectral, Hypersphere, LowerDiagonal, Higham - } - - public static void normalizePseudoRoot(Matrix matrix, Matrix pseudo) { - int size = matrix.rows(); - Utils.QL_REQUIRE(size == pseudo.rows(),()=> - "matrix/pseudo mismatch: matrix rows are " + size + " while pseudo rows are " + pseudo.columns()); - int pseudoCols = pseudo.columns(); - - // row normalization - for (int i=0; i0.0) { - double normAdj = Math.Sqrt(matrix[i,i]/norm); - for (int j=0; ji) { - currentRoot_[i,k]=0; - } else { - for (j=0; j<=k; j++) { - if (j == k && k!=i) - currentRoot_[i,k] *= Math.Cos(x[i*(i-1)/2+j]); - else if (j!=i) - currentRoot_[i,k] *= Math.Sin(x[i*(i-1)/2+j]); - } - } - } - } - } else { - for (i=0; i1-eps) - theta[i*(i-1)/2+j]=1-eps; - if (theta[i*(i-1)/2+j]<-1+eps) - theta[i*(i-1)/2+j]= -1+eps; - for (k=0; k1-eps) - theta[i*(i-1)/2+j]=1-eps; - if (theta[i*(i-1)/2+j]<-1+eps) - theta[i*(i-1)/2+j]= -1+eps; - } - theta[i*(i-1)/2+j] = Math.Acos(theta[i*(i-1)/2+j]); - if (j==i-1) { - if (result[i,i]<0) - theta[i*(i-1)/2+j]= -theta[i*(i-1)/2+j]; - } - } - } - Problem p = new Problem(costFunction, constraint, theta); - optimize.minimize(p, endCriteria); - theta = p.currentValue(); - result.fill(1); - for (i=0; ii) { - result[i,k]=0; - } else { - for (j=0; j<=k; j++) { - if (j == k && k!=i) - result[i,k] *= Math.Cos(theta[i*(i-1)/2+j]); - else if (j!=i) - result[i,k] *= Math.Sin(theta[i*(i-1)/2+j]); - } - } - } - } - } else { - Vector theta = new Vector(size * (size-1)); - const double eps=1e-16; - for (i=0; i1-eps) - theta[j*size+i]=1-eps; - if (theta[j*size+i]<-1+eps) - theta[j*size+i]= -1+eps; - for (k=0;k1-eps) - theta[j*size+i]=1-eps; - if (theta[j*size+i]<-1+eps) - theta[j*size+i]= -1+eps; - } - theta[j*size+i] = Math.Acos(theta[j*size+i]); - if (j==size-2) { - if (result[i,j+1]<0) - theta[j*size+i]= -theta[j*size+i]; - } - } - } - Problem p = new Problem(costFunction, constraint, theta); - optimize.minimize(p, endCriteria); - theta=p.currentValue(); - result.fill(1); - for (i = 0; i < size; i++) { - for (k=0; k - private static double normInf(Matrix M) { - int rows = M.rows(); - int cols = M.columns(); - double norm = 0.0; - for (int i=0; i "matrix not square"); - - Matrix result = new Matrix(M); - for (int i=0; i "matrix not square"); - - Matrix diagonal = new Matrix(size, size); - SymmetricSchurDecomposition jd = new SymmetricSchurDecomposition(M); - for (int i=0; i - "non square matrix: " + size + " rows, " + matrix.columns() + " columns"); - #endif - - // spectral (a.k.a Principal Component) analysis - SymmetricSchurDecomposition jd = new SymmetricSchurDecomposition(matrix); - Matrix diagonal = new Matrix(size, size, 0.0); - - // salvaging algorithm - Matrix result = new Matrix(size, size); - bool negative; - switch (sa) { - case SalvagingAlgorithm.None: - // eigenvalues are sorted in decreasing order - Utils.QL_REQUIRE(jd.eigenvalues()[size-1]>=-1e-16,()=> - "negative eigenvalue(s) (" + jd.eigenvalues()[size-1] + ")"); - result = MatrixUtilities.CholeskyDecomposition(matrix, true); - break; - - case SalvagingAlgorithm.Spectral: - // negative eigenvalues set to zero - for (int i=0; i - "non square matrix: " + size + " rows, " + matrix.columns() + " columns"); - #endif - - Utils.QL_REQUIRE(componentRetainedPercentage > 0.0,()=> "no eigenvalues retained"); - Utils.QL_REQUIRE(componentRetainedPercentage <= 1.0,()=> "percentage to be retained > 100%"); - Utils.QL_REQUIRE(maxRank >= 1,()=> "max rank required < 1"); - - // spectral (a.k.a Principal Component) analysis - SymmetricSchurDecomposition jd = new SymmetricSchurDecomposition(matrix); - Vector eigenValues = jd.eigenvalues(); - - // salvaging algorithm - switch (sa) - { - case SalvagingAlgorithm.None: - // eigenvalues are sorted in decreasing order - Utils.QL_REQUIRE(eigenValues[size - 1] >= -1e-16,()=> - "negative eigenvalue(s) (" + eigenValues[size - 1] + ")"); - break; - case SalvagingAlgorithm.Spectral: - // negative eigenvalues set to zero - for (int i = 0; i < size; ++i) - eigenValues[i] = Math.Max(eigenValues[i], 0.0); - break; - case SalvagingAlgorithm.Higham: - { - int maxIterations = 40; - double tolerance = 1e-6; - Matrix adjustedMatrix = highamImplementation(matrix, maxIterations, tolerance); - jd = new SymmetricSchurDecomposition(adjustedMatrix); - eigenValues = jd.eigenvalues(); - } - break; - default: - Utils.QL_FAIL("unknown or invalid salvaging algorithm"); - break; - } - - // factor reduction - double accumulate = 0; - eigenValues.ForEach((ii, vv) => accumulate += eigenValues[ii]); - double enough = componentRetainedPercentage * accumulate; - - if (componentRetainedPercentage.IsEqual(1.0)) - { - // numerical glitches might cause some factors to be discarded - enough *= 1.1; - } - // retain at least one factor - double components = eigenValues[0]; - int retainedFactors = 1; - for (int i = 1; components < enough && i < size; ++i) - { - components += eigenValues[i]; - retainedFactors++; - } - // output is granted to have a rank<=maxRank - retainedFactors = Math.Min(retainedFactors, maxRank); - - Matrix diagonal = new Matrix(size, retainedFactors, 0.0); - for (int i = 0; i < retainedFactors; ++i) - diagonal[i, i] = Math.Sqrt(eigenValues[i]); - Matrix result = jd.eigenvectors() * diagonal; - - normalizePseudoRoot(matrix, result); - return result; - } - } -} diff --git a/src/QLNet/Math/matrixutilities/qrdecomposition.cs b/src/QLNet/Math/matrixutilities/qrdecomposition.cs deleted file mode 100644 index 5146974aa..000000000 --- a/src/QLNet/Math/matrixutilities/qrdecomposition.cs +++ /dev/null @@ -1,156 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet { - public static partial class MatrixUtilities { - //! QR decompoisition - /*! This implementation is based on MINPACK - (, - ) - - This subroutine uses householder transformations with column - pivoting (optional) to compute a qr factorization of the - m by n matrix A. That is, qrfac determines an orthogonal - matrix q, a permutation matrix p, and an upper trapezoidal - matrix r with diagonal elements of nonincreasing magnitude, - such that A*p = q*r. - - Return value ipvt is an integer array of length n, which - defines the permutation matrix p such that A*p = q*r. - Column j of p is column ipvt(j) of the identity matrix. - - See lmdiff.cpp for further details. - */ - public static List qrDecomposition(Matrix M, ref Matrix q, ref Matrix r, bool pivot) { - Matrix mT = Matrix.transpose(M); - int m = M.rows(); - int n = M.columns(); - - List lipvt = new InitializedList(n); - Vector rdiag = new Vector(n); - Vector wa = new Vector(n); - - MINPACK.qrfac(m, n, mT, 0, (pivot)?1:0, ref lipvt, n, ref rdiag, ref rdiag, wa); - - if (r.columns() != n || r.rows() !=n) - r = new Matrix(n, n); - - for (int i=0; i < n; ++i) { - r[i, i] = rdiag[i]; - if (i < m) { - for ( int j = i; j < mT.rows()-1; j++ ) - r[i, j + 1] = mT[j+1, i]; - } - } - - if (q.rows() != m || q.columns() != n) - q = new Matrix(m, n); - - Vector w = new Vector(m); - for (int k=0; k < m; ++k) - { - w.Erase(); - w[k] = 1.0; - - for (int j=0; j < Math.Min(n, m); ++j) - { - double t3 = mT[j,j]; - if (t3.IsNotEqual(0.0)) - { - double t = 0; - for ( int kk = j ; kk < mT.columns(); kk++ ) - t += ( mT[j,kk] * w[kk] ) / t3 ; - - for (int i=j; i ipvt = new InitializedList(n); - if (pivot) { - for ( int i = 0; i < n; ++i ) - ipvt[i] = lipvt[i]; - } - else { - for (int i=0; i < n; ++i) - ipvt[i] = i; - } - - return ipvt; - } - - //! QR Solve - /*! This implementation is based on MINPACK - (, - ) - - Given an m by n matrix A, an n by n diagonal matrix d, - and an m-vector b, the problem is to determine an x which - solves the system - - A*x = b , d*x = 0 , - - in the least squares sense. - - d is an input array of length n which must contain the - diagonal elements of the matrix d. - - See lmdiff.cpp for further details. - */ - public static Vector qrSolve( Matrix a, Vector b, bool pivot = true, Vector d = null ) - { - int m = a.rows(); - int n = a.columns(); - if ( d == null ) d = new Vector(); - Utils.QL_REQUIRE( b.Count == m, () => "dimensions of A and b don't match" ); - Utils.QL_REQUIRE( d.Count == n || d.empty(), () => "dimensions of A and d don't match" ); - - Matrix q = new Matrix( m, n ), r = new Matrix( n, n ); - - List lipvt = MatrixUtilities.qrDecomposition( a, ref q, ref r, pivot ); - List ipvt = new List( n ); - ipvt = lipvt; - - Matrix aT = Matrix.transpose( a ); - Matrix rT = Matrix.transpose( r ); - - Vector sdiag = new Vector( n ); - Vector wa = new Vector( n ); - - Vector ld = new Vector( n, 0.0 ); - if ( !d.empty() ) - { - ld = d; - } - Vector x = new Vector( n ); - Vector qtb = Matrix.transpose( q ) * b; - - MINPACK.qrsolv( n, rT, n, ipvt, ld, qtb, x, sdiag, wa ); - - return x; - } - } -} \ No newline at end of file diff --git a/src/QLNet/Math/matrixutilities/svd.cs b/src/QLNet/Math/matrixutilities/svd.cs deleted file mode 100644 index 34129bc3e..000000000 --- a/src/QLNet/Math/matrixutilities/svd.cs +++ /dev/null @@ -1,479 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! Singular value decomposition - /*! Refer to Golub and Van Loan: Matrix computation, - The Johns Hopkins University Press - - \test the correctness of the returned values is tested by - checking their properties. - */ - public class SVD { - private Matrix U_, V_; - private Vector s_; - private int m_, n_; - private bool transpose_; - - public SVD(Matrix M) { - Matrix A; - - /* The implementation requires that rows > columns. - If this is not the case, we decompose M^T instead. - Swapping the resulting U and V gives the desired - result for M as - - M^T = U S V^T (decomposition of M^T) - - M = (U S V^T)^T (transpose) - - M = (V^T^T S^T U^T) ((AB)^T = B^T A^T) - - M = V S U^T (idempotence of transposition, - symmetry of diagonal matrix S) - */ - - if (M.rows() >= M.columns()) { - A = new Matrix(M); - transpose_ = false; - } else { - A = Matrix.transpose(M); - transpose_ = true; - } - - m_ = A.rows(); - n_ = A.columns(); - - // we're sure that m_ >= n_ - s_ = new Vector(n_); - U_ = new Matrix(m_, n_); - V_ = new Matrix(n_, n_); - Vector e = new Vector(n_); - Vector work = new Vector(m_); - int i, j, k; - - // Reduce A to bidiagonal form, storing the diagonal elements - // in s and the super-diagonal elements in e. - int nct = Math.Min(m_ - 1, n_); - int nrt = Math.Max(0, n_ - 2); - for (k = 0; k < Math.Max(nct, nrt); k++) { - if (k < nct) { - - // Compute the transformation for the k-th column and - // place the k-th diagonal in s[k]. - // Compute 2-norm of k-th column without under/overflow. - s_[k] = 0; - for (i = k; i < m_; i++) { - s_[k] = hypot(s_[k], A[i, k]); - } - if (s_[k].IsNotEqual(0.0)) { - if (A[k, k] < 0.0) { - s_[k] = -s_[k]; - } - for (i = k; i < m_; i++) { - A[i, k] /= s_[k]; - } - A[k, k] += 1.0; - } - s_[k] = -s_[k]; - } - for (j = k + 1; j < n_; j++) { - if ((k < nct) && (s_[k].IsNotEqual(0.0))) { - - // Apply the transformation. - double t = 0; - for (i = k; i < m_; i++) { - t += A[i, k] * A[i, j]; - } - t = -t / A[k, k]; - for (i = k; i < m_; i++) { - A[i, j] += t * A[i, k]; - } - } - - // Place the k-th row of A into e for the - // subsequent calculation of the row transformation. - e[j] = A[k, j]; - } - if (k < nct) { - // Place the transformation in U for subsequent back multiplication. - for (i = k; i < m_; i++) { - U_[i, k] = A[i, k]; - } - } - if (k < nrt) { - // Compute the k-th row transformation and place the k-th super-diagonal in e[k]. - // Compute 2-norm without under/overflow. - e[k] = 0; - for (i = k + 1; i < n_; i++) { - e[k] = hypot(e[k], e[i]); - } - if (e[k].IsNotEqual(0.0)) { - if (e[k + 1] < 0.0) { - e[k] = -e[k]; - } - for (i = k + 1; i < n_; i++) { - e[i] /= e[k]; - } - e[k + 1] += 1.0; - } - e[k] = -e[k]; - if ((k + 1 < m_) && (e[k].IsNotEqual(0.0))) { - // Apply the transformation. - for (i = k + 1; i < m_; i++) { - work[i] = 0.0; - } - for (j = k + 1; j < n_; j++) { - for (i = k + 1; i < m_; i++) { - work[i] += e[j] * A[i, j]; - } - } - for (j = k + 1; j < n_; j++) { - double t = -e[j] / e[k + 1]; - for (i = k + 1; i < m_; i++) { - A[i, j] += t * work[i]; - } - } - } - - // Place the transformation in V for subsequent back multiplication. - for (i = k + 1; i < n_; i++) { - V_[i, k] = e[i]; - } - } - } - - // Set up the final bidiagonal matrix or order n. - if (nct < n_) { - s_[nct] = A[nct, nct]; - } - if (nrt + 1 < n_) { - e[nrt] = A[nrt, n_ - 1]; - } - e[n_ - 1] = 0.0; - - // generate U - for (j = nct; j < n_; j++) { - for (i = 0; i < m_; i++) { - U_[i, j] = 0.0; - } - U_[j, j] = 1.0; - } - for (k = nct - 1; k >= 0; --k) { - if (s_[k].IsNotEqual(0.0)) { - for (j = k + 1; j < n_; ++j) { - double t = 0; - for (i = k; i < m_; i++) { - t += U_[i, k] * U_[i, j]; - } - t = -t / U_[k, k]; - for (i = k; i < m_; i++) { - U_[i, j] += t * U_[i, k]; - } - } - for (i = k; i < m_; i++) { - U_[i, k] = -U_[i, k]; - } - U_[k, k] = 1.0 + U_[k, k]; - for (i = 0; i < k - 1; i++) { - U_[i, k] = 0.0; - } - } else { - for (i = 0; i < m_; i++) { - U_[i, k] = 0.0; - } - U_[k, k] = 1.0; - } - } - - // generate V - for (k = n_ - 1; k >= 0; --k) { - if ((k < nrt) && (e[k].IsNotEqual(0.0))) { - for (j = k + 1; j < n_; ++j) { - double t = 0; - for (i = k + 1; i < n_; i++) { - t += V_[i, k] * V_[i, j]; - } - t = -t / V_[k + 1, k]; - for (i = k + 1; i < n_; i++) { - V_[i, j] += t * V_[i, k]; - } - } - } - for (i = 0; i < n_; i++) { - V_[i, k] = 0.0; - } - V_[k, k] = 1.0; - } - - // Main iteration loop for the singular values. - int p = n_, pp = p - 1; - int iter = 0; - double eps = Math.Pow(2.0, -52.0); - while (p > 0) { - int kase; - - // Here is where a test for too many iterations would go. - - // This section of the program inspects for - // negligible elements in the s and e arrays. On - // completion the variables kase and k are set as follows. - - // kase = 1 if s(p) and e[k-1] are negligible and k

= -1; --k) { - if (k == -1) { - break; - } - if (Math.Abs(e[k]) <= eps * (Math.Abs(s_[k]) + Math.Abs(s_[k + 1]))) { - e[k] = 0.0; - break; - } - } - if (k == p - 2) { - kase = 4; - } else { - int ks; - for (ks = p - 1; ks >= k; --ks) { - if (ks == k) { - break; - } - double t = (ks != p ? Math.Abs(e[ks]) : 0) + - (ks != k + 1 ? Math.Abs(e[ks - 1]) : 0); - if (Math.Abs(s_[ks]) <= eps * t) { - s_[ks] = 0.0; - break; - } - } - if (ks == k) { - kase = 3; - } else if (ks == p - 1) { - kase = 1; - } else { - kase = 2; - k = ks; - } - } - k++; - - // Perform the task indicated by kase. - switch (kase) { - - // Deflate negligible s(p). - case 1: { - double f = e[p - 2]; - e[p - 2] = 0.0; - for (j = p - 2; j >= k; --j) { - double t = hypot(s_[j], f); - double cs = s_[j] / t; - double sn = f / t; - s_[j] = t; - if (j != k) { - f = -sn * e[j - 1]; - e[j - 1] = cs * e[j - 1]; - } - for (i = 0; i < n_; i++) { - t = cs * V_[i, j] + sn * V_[i, p - 1]; - V_[i, p - 1] = -sn * V_[i, j] + cs * V_[i, p - 1]; - V_[i, j] = t; - } - } - } - break; - - // Split at negligible s(k). - case 2: { - double f = e[k - 1]; - e[k - 1] = 0.0; - for (j = k; j < p; j++) { - double t = hypot(s_[j], f); - double cs = s_[j] / t; - double sn = f / t; - s_[j] = t; - f = -sn * e[j]; - e[j] = cs * e[j]; - for (i = 0; i < m_; i++) { - t = cs * U_[i, j] + sn * U_[i, k - 1]; - U_[i, k - 1] = -sn * U_[i, j] + cs * U_[i, k - 1]; - U_[i, j] = t; - } - } - } - break; - - // Perform one qr step. - case 3: { - // Calculate the shift. - double scale = Math.Max( - Math.Max( - Math.Max( - Math.Max(Math.Abs(s_[p - 1]), - Math.Abs(s_[p - 2])), - Math.Abs(e[p - 2])), - Math.Abs(s_[k])), - Math.Abs(e[k])); - double sp = s_[p - 1] / scale; - double spm1 = s_[p - 2] / scale; - double epm1 = e[p - 2] / scale; - double sk = s_[k] / scale; - double ek = e[k] / scale; - double b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) / 2.0; - double c = (sp * epm1) * (sp * epm1); - double shift = 0.0; - if ((b.IsNotEqual(0.0)) || (c.IsNotEqual(0.0))) { - shift = Math.Sqrt(b * b + c); - if (b < 0.0) { - shift = -shift; - } - shift = c / (b + shift); - } - double f = (sk + sp) * (sk - sp) + shift; - double g = sk * ek; - - // Chase zeros. - for (j = k; j < p - 1; j++) { - double t = hypot(f, g); - double cs = f / t; - double sn = g / t; - if (j != k) { - e[j - 1] = t; - } - f = cs * s_[j] + sn * e[j]; - e[j] = cs * e[j] - sn * s_[j]; - g = sn * s_[j + 1]; - s_[j + 1] = cs * s_[j + 1]; - for (i = 0; i < n_; i++) { - t = cs * V_[i, j] + sn * V_[i, j + 1]; - V_[i, j + 1] = -sn * V_[i, j] + cs * V_[i, j + 1]; - V_[i, j] = t; - } - t = hypot(f, g); - cs = f / t; - sn = g / t; - s_[j] = t; - f = cs * e[j] + sn * s_[j + 1]; - s_[j + 1] = -sn * e[j] + cs * s_[j + 1]; - g = sn * e[j + 1]; - e[j + 1] = cs * e[j + 1]; - if (j < m_ - 1) { - for (i = 0; i < m_; i++) { - t = cs * U_[i, j] + sn * U_[i, j + 1]; - U_[i, j + 1] = -sn * U_[i, j] + cs * U_[i, j + 1]; - U_[i, j] = t; - } - } - } - e[p - 2] = f; - iter = iter + 1; - } - break; - - // Convergence. - case 4: { - // Make the singular values positive. - if (s_[k] <= 0.0) { - s_[k] = (s_[k] < 0.0 ? -s_[k] : 0.0); - for (i = 0; i <= pp; i++) { - V_[i, k] = -V_[i, k]; - } - } - - // Order the singular values. - while (k < pp) { - if (s_[k] >= s_[k + 1]) { - break; - } - s_.swap(k, k + 1); - if (k < n_ - 1) { - for (i = 0; i < n_; i++) { - V_.swap(i, k, i, k + 1); - } - } - if (k < m_ - 1) { - for (i = 0; i < m_; i++) { - U_.swap(i, k, i, k + 1); - } - } - k++; - } - iter = 0; - --p; - } - break; - } - } - } - - - public Matrix U() { return (transpose_ ? V_ : U_); } - public Matrix V() { return (transpose_ ? U_ : V_); } - public Matrix S() { - Matrix S = new Matrix(n_,n_); - for (int i = 0; i < n_; i++) { - for (int j = 0; j < n_; j++) { - S[i,j] = 0.0; - } - S[i,i] = s_[i]; - } - return S; - } - - public Vector singularValues() { return s_; } - public double norm2() { return s_[0]; } - public double cond() { return s_[0]/s_[n_-1]; } - public int rank() { - double eps = Math.Pow(2.0,-52.0); - double tol = m_*s_[0]*eps; - int r = 0; - for (int i = 0; i < s_.size(); i++) { - if (s_[i] > tol) { - r++; - } - } - return r; - } - - public Vector solveFor(Vector b) { - Matrix W = new Matrix(n_, n_, 0.0); - for (int i=0; i. - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet { - //! symmetric threshold Jacobi algorithm. - /*! Given a real symmetric matrix S, the Schur decomposition - finds the eigenvalues and eigenvectors of S. If D is the - diagonal matrix formed by the eigenvalues and U the - unitarian matrix of the eigenvectors we can write the - Schur decomposition as - \f[ S = U \cdot D \cdot U^T \, ,\f] - where \f$ \cdot \f$ is the standard matrix product - and \f$ ^T \f$ is the transpose operator. - This class implements the Schur decomposition using the - symmetric threshold Jacobi algorithm. For details on the - different Jacobi transfomations see "Matrix computation," - second edition, by Golub and Van Loan, - The Johns Hopkins University Press - - \test the correctness of the returned values is tested by - checking their properties. - */ - public class SymmetricSchurDecomposition { - private Vector diagonal_; - private Matrix eigenVectors_; - - /*! \pre s must be symmetric */ - public SymmetricSchurDecomposition(Matrix s) { - diagonal_ = new Vector(s.rows()); - eigenVectors_ = new Matrix(s.rows(), s.columns(), 0.0); - - Utils.QL_REQUIRE(s.rows() > 0 && s.columns() > 0,()=> "null matrix given"); - Utils.QL_REQUIRE(s.rows()==s.columns(),()=> "input matrix must be square"); - - int size = s.rows(); - for (int q=0; q 5 && - smllthreshold) { - heig = diagonal_[k]-diagonal_[j]; - if (smll "Too many iterations (" + maxIterations + ") reached"); - - // sort (eigenvalues, eigenvectors) - List> temp = new InitializedList>(size); - int row, col; - for (col=0; col eigenVector[ii] = xx); - temp[col] = new KeyValuePair(diagonal_[col], eigenVector); - } - // sort descending: std::greater - temp.Sort((x, y) => y.Key.CompareTo(x.Key)); - double maxEv = temp[0].Key; - for (col=0; col. - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -92,7 +92,7 @@ public Sample> nextSequence() k /= b; } sequence_.value[i] = h + randomShift_[i]; - sequence_.value[i] -= (long) (sequence_.value[i]); + sequence_.value[i] -= (long)(sequence_.value[i]); } return sequence_; } diff --git a/src/QLNet/Math/randomnumbers/inversecumulativerng.cs b/src/QLNet/Math/randomnumbers/InverseCumulativeRng.cs similarity index 93% rename from src/QLNet/Math/randomnumbers/inversecumulativerng.cs rename to src/QLNet/Math/randomnumbers/InverseCumulativeRng.cs index edb1aa25a..3f1536963 100644 --- a/src/QLNet/Math/randomnumbers/inversecumulativerng.cs +++ b/src/QLNet/Math/randomnumbers/InverseCumulativeRng.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,7 +29,7 @@ The uniform deviate is supplied by RNG. The inverse cumulative distribution is supplied by IC. */ - public class InverseCumulativeRng where RNG : IRNGTraits where IC : IValue, new() + public class InverseCumulativeRng where RNG : IRNGTraits where IC : IValue, new () { private RNG uniformGenerator_; private IC ICND_ = FastActivator.Create(); diff --git a/src/QLNet/Math/randomnumbers/inversecumulativersg.cs b/src/QLNet/Math/randomnumbers/InverseCumulativeRsg.cs similarity index 97% rename from src/QLNet/Math/randomnumbers/inversecumulativersg.cs rename to src/QLNet/Math/randomnumbers/InverseCumulativeRsg.cs index 6dacf3f30..9877c2ef3 100644 --- a/src/QLNet/Math/randomnumbers/inversecumulativersg.cs +++ b/src/QLNet/Math/randomnumbers/InverseCumulativeRsg.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Math/randomnumbers/mt19937uniformrng.cs b/src/QLNet/Math/randomnumbers/MT19937UniformRng.cs similarity index 62% rename from src/QLNet/Math/randomnumbers/mt19937uniformrng.cs rename to src/QLNet/Math/randomnumbers/MT19937UniformRng.cs index d4eacf40d..b2759572f 100644 --- a/src/QLNet/Math/randomnumbers/mt19937uniformrng.cs +++ b/src/QLNet/Math/randomnumbers/MT19937UniformRng.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -38,56 +38,65 @@ public class MersenneTwisterUniformRng : IRNGTraits /*! if the given seed is 0, a random seed will be chosen based on clock() */ public MersenneTwisterUniformRng() : this(0) {} - public MersenneTwisterUniformRng( ulong seed ) + public MersenneTwisterUniformRng(ulong seed) { - mt = new InitializedList( N ); - seedInitialization( seed ); + mt = new InitializedList(N); + seedInitialization(seed); } - public MersenneTwisterUniformRng( List seeds ) + public MersenneTwisterUniformRng(List seeds) { - mt = new InitializedList( N ); + mt = new InitializedList(N); - seedInitialization( 19650218UL ); - int i = 1, j = 0, k = ( N > seeds.Count ? N : seeds.Count ); - for ( ; k != 0; k-- ) + seedInitialization(19650218UL); + int i = 1, j = 0, k = (N > seeds.Count ? N : seeds.Count); + for (; k != 0; k--) { - mt[i] = ( mt[i] ^ ( ( mt[i - 1] ^ ( mt[i - 1] >> 30 ) ) * 1664525UL ) ) + seeds[j] + (ulong)j; /* non linear */ + mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1664525UL)) + seeds[j] + (ulong)j; /* non linear */ mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ i++; j++; - if ( i >= N ) { mt[0] = mt[N - 1]; i = 1; } - if ( j >= seeds.Count ) j = 0; + if (i >= N) + { + mt[0] = mt[N - 1]; + i = 1; + } + if (j >= seeds.Count) + j = 0; } - for ( k = N - 1; k != 0; k-- ) + for (k = N - 1; k != 0; k--) { - mt[i] = ( mt[i] ^ ( ( mt[i - 1] ^ ( mt[i - 1] >> 30 ) ) * 1566083941UL ) ) - (ulong)i; /* non linear */ + mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1566083941UL)) - (ulong)i; /* non linear */ mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ i++; - if ( i >= N ) { mt[0] = mt[N - 1]; i = 1; } + if (i >= N) + { + mt[0] = mt[N - 1]; + i = 1; + } } mt[0] = 0x80000000UL; /*MSB is 1; assuring non-zero initial array*/ } - public IRNGTraits factory( ulong seed ) { return new MersenneTwisterUniformRng( seed ); } + public IRNGTraits factory(ulong seed) { return new MersenneTwisterUniformRng(seed); } /*! returns a sample with weight 1.0 containing a random number on (0.0, 1.0)-real-interval */ public Sample next() { - return new Sample( nextReal(), 1.0 ); + return new Sample(nextReal(), 1.0); } - + //! return a random number in the (0.0, 1.0)-interval - public double nextReal() + public double nextReal() { - return (nextInt32() + 0.5)/4294967296.0; + return (nextInt32() + 0.5) / 4294967296.0; } //! return a random number on [0,0xffffffff]-interval public ulong nextInt32() { - if (mti==N) + if (mti == N) twist(); /* generate N words at a time */ ulong y = mt[mti++]; @@ -100,14 +109,14 @@ public ulong nextInt32() return y; } - private void seedInitialization( ulong seed ) + private void seedInitialization(ulong seed) { /* initializes mt with a seed */ - ulong s = ( seed != 0 ? seed : SeedGenerator.instance().get() ); + ulong s = (seed != 0 ? seed : SeedGenerator.instance().get()); mt[0] = s & 0xffffffffUL; - for ( mti = 1; mti < N; mti++ ) + for (mti = 1; mti < N; mti++) { - mt[mti] = ( 1812433253UL * ( mt[mti - 1] ^ ( mt[mti - 1] >> 30 ) ) + (ulong)mti ); + mt[mti] = (1812433253UL * (mt[mti - 1] ^ (mt[mti - 1] >> 30)) + (ulong)mti); /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ /* In the previous versions, MSBs of the seed affect */ /* only MSBs of the array mt[]. */ @@ -119,23 +128,23 @@ private void seedInitialization( ulong seed ) private void twist() { - ulong[] mag01 = { 0x0UL, MATRIX_A }; + ulong[] mag01 = { 0x0UL, MATRIX_A }; /* mag01[x] = x * MATRIX_A for x=0,1 */ int kk; ulong y; - for (kk=0;kk> 1) ^ mag01[y & 0x1UL]; + y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK); + mt[kk] = mt[kk + M] ^ (y >> 1) ^ mag01[y & 0x1UL]; } - for (;kk> 1) ^ mag01[y & 0x1UL]; + y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK); + mt[kk] = mt[(kk + M) - N] ^ (y >> 1) ^ mag01[y & 0x1UL]; } - y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); - mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; + y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK); + mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ mag01[y & 0x1UL]; mti = 0; } diff --git a/src/QLNet/Math/randomnumbers/PrimitivePolynomials.cs b/src/QLNet/Math/randomnumbers/PrimitivePolynomials.cs new file mode 100644 index 000000000..b5a2bf185 --- /dev/null +++ b/src/QLNet/Math/randomnumbers/PrimitivePolynomials.cs @@ -0,0 +1,21524 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +namespace QLNet +{ + /* this file is a slightly edited version of + * PrimitivePolynomialsModuloTwoUpToDegree27.h + * © 2002 "Monte Carlo Methods in Finance" + * as provided ready for compilation in the directory + * "PrimitivePolynomialsModuloTwo" on the CD accompanying the book + * "Monte Carlo Methods in Finance" by Peter Jдckel. + * + * =========================================================================== + * NOTE: The following copyright notice applies to the original code, + * + * Copyright (C) 2002 Peter Jдckel "Monte Carlo Methods in Finance". + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software is freely + * granted, provided that this notice is preserved. + * =========================================================================== + */ + + /* This file is provided for the use with Sobol' sequences of higher + * dimensions. The dimensionality of the Sobol' sequence can be extended to + * virtually any size you ever might need by the aid of the table of + * primitive polynomials modulo two. + * It is up to you to define a macro PPMT_MAX_DIM to a positive integer + * less than or equal to 8129334. If you don't define it, it will be set + * below to N_PRIMITIVES_UP_TO_DEGREE_18 which is 21200. That's how many + * primitive polynomials are provided by the standard primitivepolynomial.c + * distributed with QuantLib and that will be compiled into a static array. + * Should you need more, get the original version of primitivepolynomial.c + * as provided ready for compilation in the directory + * "PrimitivePolynomialsModuloTwo" on the CD accompanying the book + * "Monte Carlo Methods in Finance" by Peter Jдckel. + * The file provides polynomials up to degree 27 + * for a grand total of 8129334 dimensions. + * Since 8129334 longs compile into an object file of at least 32517336 byte + * size (in fact, gcc -c -O0 PrimitivePolynomialsModuloTwoUpToDegree27.c + * produced a file PrimitivePolynomialsModuloTwoUpToDegree27.o with 32519920 + * bytes), it is recommended to only compile as many as you may ever need. + * Worse even than the output file size is the virtual memory requirement + * for the compilation. For Visual C++ 6 you will need to use the /Zm compiler + * option to set the compiler's memory allocation limit (/Zm1500 should work) + * So really only take the maximum of what you think you might ever need. + * After all, you can always recompile with more, should you need it. + */ + + /* PPMT : Primitive Polynomials Modulo Two + * + * + * The encoding is as follows: + * + * The coefficients of each primitive polynomial are the bits of the given + * integer. The leading and trailing coefficients, which are 1 for all of the + * polynomials, have been omitted. + * + * Example: The polynomial + * + * 4 2 + * x + x + 1 + * + * is encoded as 2 in the array of polynomials of degree 4 because the + * binary sequence of coefficients + * + * 10101 + * + * becomes + * + * 0101 + * + * after stripping off the top bit, and this is converted to + * + * 010 + * + * by right-shifting and losing the rightmost bit. Similarly, we have + * + * 5 4 2 + * x + x + x + x + 1 + * + * encoded as 13 [ (1)1101(1) ] in the array for degree 5. + */ + + /* Example: replace primitivepolynomials.c provided by QuantLib standard + * distribution with the 8129334 polinomials version and + * comment out the line below if you want absolutely all of the + * provided primitive polynomials modulo two. + * + * #define PPMT_MAX_DIM 8129334 + * + * Note that PPMT_MAX_DIM will be redefined to be the nearest equal or larger + * number of polynomials up to one of the predefined macros + * N_PRIMITIVES_UP_TO_DEGREE_XX + * below. + */ + +#if NOPOLY + public partial class SobolRsg + { + public const long PPMT_MAX_DIM = 0; + public const int N_MAX_DEGREE = 0; + + public static long[][] PrimitivePolynomials; + } + +#else + + public partial class SobolRsg + { + + public const long PPMT_MAX_DIM = 21200; + public const int N_MAX_DEGREE = 18; + + static long[] PrimitivePolynomialDegree01 = + { + 0, /* x+1 (1)(1) */ + -1 + }; + + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_01 + static long[] PrimitivePolynomialDegree02 = + { + 1, /* x^2+x+1 (1)1(1) */ + -1 + }; + ////#endif + + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_02 + static long[] PrimitivePolynomialDegree03 = + { + 1, /* x^3 +x+1 (1)01(1) */ + 2, /* x^3+x^2 +1 (1)10(1) */ + -1 + }; + ////#endif + + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_03 + static long[] PrimitivePolynomialDegree04 = + { + 1, /* x^4+ +x+1 (1)001(1) */ + 4, /* x^4+x^3+ +1 (1)100(1) */ + -1 + }; + ////#endif + + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_04 + static long[] PrimitivePolynomialDegree05 = + { + 2, /* x^5 +x^2 +1 (1)0010(1) */ + 4, /* x^5 +x^3 +1 (1)0100(1) */ + 7, /* x^5 +x^3+x^2+x+1 (1)0111(1) */ + 11, /* x^5+x^4 +x^2+x+1 (1)1011(1) */ + 13, /* x^5+x^4+x^3 +x+1 (1)1101(1) */ + 14, /* x^5+x^4+x^3+x^2 +1 (1)1110(1) */ + -1 + }; + ////#endif + + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_05 + static long[] PrimitivePolynomialDegree06 = + { + 1, /* x^6 +x+1 (1)00001(1) */ + 13, /* x^6 +x^4+x^3 +x+1 (1)01101(1) */ + 16, /* x^6+x^5 +1 (1)10000(1) */ + 19, /* x^6 +x^2+x+1 (1)10011(1) */ + 22, /* x^6+x^5 +x^3+x^2 +1 (1)10110(1) */ + 25, /* x^6+x^5+x^4 +x+1 (1)11001(1) */ + -1 + }; + //#endif + + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_06 + static long[] PrimitivePolynomialDegree07 = + { + 1, /* x^7 +x+1 (1)000001(1) */ + 4, /* x^7 +x^3 +1 (1)000100(1) */ + 7, /* x^7 +x^3+x^2+x+1 (1)000111(1) */ + 8, /* x^7 +x^4 +1 (1)001000(1) */ + 14, /* x^7 +x^4+x^3+x^2 +1 (1)001110(1) */ + 19, /* x^7 +x^5 +x^2+x+1 (1)010011(1) */ + 21, /* x^7 +x^5 +x^3 +x+1 (1)010101(1) */ + 28, /* x^7 +x^5+x^4+x^3 +1 (1)011100(1) */ + 31, /* x^7 +x^5+x^4+x^3+x^2+x+1 (1)011111(1) */ + 32, /* x^7+x^6 +1 (1)100000(1) */ + 37, /* x^7+x^6 +x^3 +x+1 (1)100101(1) */ + 41, /* x^7+x^6 +x^4 +x+1 (1)101001(1) */ + 42, /* x^7+x^6 +x^4 +x^2 +1 (1)101010(1) */ + /* 32 polynomials so far ... let's go ahead */ + 50, /* x^7+x^6+x^5 +x^2 +1 (1)110010(1) */ + 55, /* x^7+x^6+x^5 +x^3+x^2+x+1 (1)110111(1) */ + 56, /* x^7+x^6+x^5+x^4 +1 (1)111000(1) */ + 59, /* x^7+x^6+x^5+x^4 +x^2+x+1 (1)111011(1) */ + 62, /* x^7+x^6+x^5+x^4+x^3+x^2 +1 (1)111110(1) */ + -1 + }; + //#endif + + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_07 + static long[] PrimitivePolynomialDegree08 = + { + 14, + 21, + 22, + 38, + 47, + 49, + 50, + 52, + 56, + 67, + 70, + 84, + 97, + 103, + 115, + 122, + -1 + }; + //#endif + + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_08 + static long[] PrimitivePolynomialDegree09 = + { + 8, + 13, + 16, + 22, + 25, + 44, + 47, + 52, + 55, + 59, + 62, + 67, + 74, + 81, + 82, + 87, + 91, + 94, + 103, + 104, + 109, + 122, + 124, + 137, + 138, + 143, + 145, + 152, + 157, + 167, + 173, + 176, + 181, + 182, + 185, + 191, + 194, + 199, + 218, + 220, + 227, + 229, + 230, + 234, + 236, + 241, + 244, + 253, + -1 + }; + //#endif + + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_09 + static long[] PrimitivePolynomialDegree10 = + { + 4, + 13, + 19, + 22, + 50, + 55, + 64, + 69, + 98, + 107, + 115, + 121, + 127, + 134, + 140, + 145, + 152, + 158, + 161, + 171, + 181, + 194, + 199, + 203, + 208, + 227, + 242, + 251, + 253, + 265, + 266, + 274, + 283, + 289, + 295, + 301, + 316, + 319, + 324, + 346, + 352, + 361, + 367, + 382, + 395, + 398, + 400, + 412, + 419, + 422, + 426, + 428, + 433, + 446, + 454, + 457, + 472, + 493, + 505, + 508, + -1 + }; + //#endif + + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_10 + static long[] PrimitivePolynomialDegree11 = + { + 2, + 11, + 21, + 22, + 35, + 49, + 50, + 56, + 61, + 70, + 74, + 79, + 84, + 88, + 103, + 104, + 112, + 115, + 117, + 122, + 134, + 137, + 146, + 148, + 157, + 158, + 162, + 164, + 168, + 173, + 185, + 186, + 191, + 193, + 199, + 213, + 214, + 220, + 227, + 236, + 242, + 251, + 256, + 259, + 265, + 266, + 276, + 292, + 304, + 310, + 316, + 319, + 322, + 328, + 334, + 339, + 341, + 345, + 346, + 362, + 367, + 372, + 375, + 376, + 381, + 385, + 388, + 392, + 409, + 415, + 416, + 421, + 428, + 431, + 434, + 439, + 446, + 451, + 453, + 457, + 458, + 471, + 475, + 478, + 484, + 493, + 494, + 499, + 502, + 517, + 518, + 524, + 527, + 555, + 560, + 565, + 569, + 578, + 580, + 587, + 589, + 590, + 601, + 607, + 611, + 614, + 617, + 618, + 625, + 628, + 635, + 641, + 647, + 654, + 659, + 662, + 672, + 675, + 682, + 684, + 689, + 695, + 696, + 713, + 719, + 724, + 733, + 734, + 740, + 747, + 749, + 752, + 755, + 762, + 770, + 782, + 784, + 787, + 789, + 793, + 796, + 803, + 805, + 810, + 815, + 824, + 829, + 830, + 832, + 841, + 847, + 849, + 861, + 871, + 878, + 889, + 892, + 901, + 908, + 920, + 923, + 942, + 949, + 950, + 954, + 961, + 968, + 971, + 973, + 979, + 982, + 986, + 998, + 1001, + 1010, + 1012, + -1 + }; + //#endif + + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_11 + static long[] PrimitivePolynomialDegree12 = + { + 41, + 52, + 61, + 62, + 76, + 104, + 117, + 131, + 143, + 145, + 157, + 167, + 171, + 176, + 181, + 194, + 217, + 236, + 239, + 262, + 283, + 286, + 307, + 313, + 319, + 348, + 352, + 357, + 391, + 398, + 400, + 412, + 415, + 422, + 440, + 460, + 465, + 468, + 515, + 536, + 539, + 551, + 558, + 563, + 570, + 595, + 598, + 617, + 647, + 654, + 678, + 713, + 738, + 747, + 750, + 757, + 772, + 803, + 810, + 812, + 850, + 862, + 906, + 908, + 929, + 930, + 954, + 964, + 982, + 985, + 991, + 992, + 1067, + 1070, + 1096, + 1099, + 1116, + 1143, + 1165, + 1178, + 1184, + 1202, + 1213, + 1221, + 1240, + 1246, + 1252, + 1255, + 1267, + 1293, + 1301, + 1305, + 1332, + 1349, + 1384, + 1392, + 1402, + 1413, + 1417, + 1423, + 1451, + 1480, + 1491, + 1503, + 1504, + 1513, + 1538, + 1544, + 1547, + 1555, + 1574, + 1603, + 1615, + 1618, + 1629, + 1634, + 1636, + 1639, + 1657, + 1667, + 1681, + 1697, + 1704, + 1709, + 1722, + 1730, + 1732, + 1802, + 1804, + 1815, + 1826, + 1832, + 1843, + 1849, + 1863, + 1905, + 1928, + 1933, + 1939, + 1976, + 1996, + 2013, + 2014, + 2020, + -1 + }; + //#endif + + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_12 + static long[] PrimitivePolynomialDegree13 = + { + 13, + 19, + 26, + 41, + 50, + 55, + 69, + 70, + 79, + 82, + 87, + 93, + 94, + 97, + 100, + 112, + 121, + 134, + 138, + 148, + 151, + 157, + 161, + 179, + 181, + 188, + 196, + 203, + 206, + 223, + 224, + 227, + 230, + 239, + 241, + 248, + 253, + 268, + 274, + 283, + 286, + 289, + 301, + 302, + 316, + 319, + 324, + 331, + 333, + 345, + 351, + 358, + 375, + 379, + 381, + 386, + 403, + 405, + 419, + 426, + 428, + 439, + 440, + 446, + 451, + 454, + 458, + 465, + 468, + 472, + 475, + 477, + 496, + 502, + 508, + 517, + 521, + 527, + 530, + 532, + 542, + 552, + 555, + 560, + 566, + 575, + 577, + 589, + 590, + 602, + 607, + 608, + 611, + 613, + 625, + 644, + 651, + 654, + 656, + 662, + 668, + 681, + 682, + 689, + 696, + 699, + 707, + 709, + 714, + 716, + 719, + 727, + 734, + 738, + 743, + 747, + 757, + 769, + 770, + 776, + 790, + 799, + 805, + 809, + 812, + 820, + 827, + 829, + 835, + 841, + 844, + 856, + 859, + 862, + 865, + 885, + 890, + 905, + 916, + 925, + 935, + 939, + 942, + 949, + 953, + 956, + 961, + 968, + 976, + 988, + 995, + 997, + 1007, + 1015, + 1016, + 1027, + 1036, + 1039, + 1041, + 1048, + 1053, + 1054, + 1058, + 1075, + 1082, + 1090, + 1109, + 1110, + 1119, + 1126, + 1130, + 1135, + 1137, + 1140, + 1149, + 1156, + 1159, + 1160, + 1165, + 1173, + 1178, + 1183, + 1184, + 1189, + 1194, + 1211, + 1214, + 1216, + 1225, + 1231, + 1239, + 1243, + 1246, + 1249, + 1259, + 1273, + 1274, + 1281, + 1287, + 1294, + 1296, + 1305, + 1306, + 1318, + 1332, + 1335, + 1336, + 1341, + 1342, + 1362, + 1364, + 1368, + 1378, + 1387, + 1389, + 1397, + 1401, + 1408, + 1418, + 1425, + 1426, + 1431, + 1435, + 1441, + 1444, + 1462, + 1471, + 1474, + 1483, + 1485, + 1494, + 1497, + 1516, + 1522, + 1534, + 1543, + 1552, + 1557, + 1558, + 1567, + 1568, + 1574, + 1592, + 1605, + 1606, + 1610, + 1617, + 1623, + 1630, + 1634, + 1640, + 1643, + 1648, + 1651, + 1653, + 1670, + 1676, + 1684, + 1687, + 1691, + 1693, + 1698, + 1709, + 1715, + 1722, + 1732, + 1735, + 1747, + 1749, + 1754, + 1777, + 1784, + 1790, + 1795, + 1801, + 1802, + 1812, + 1828, + 1831, + 1837, + 1838, + 1840, + 1845, + 1863, + 1864, + 1867, + 1870, + 1877, + 1881, + 1884, + 1903, + 1917, + 1918, + 1922, + 1924, + 1928, + 1931, + 1951, + 1952, + 1957, + 1958, + 1964, + 1967, + 1970, + 1972, + 1994, + 2002, + 2007, + 2008, + 2023, + 2030, + 2035, + 2038, + 2042, + 2047, + 2051, + 2058, + 2060, + 2071, + 2084, + 2087, + 2099, + 2108, + 2111, + 2120, + 2128, + 2138, + 2143, + 2144, + 2153, + 2156, + 2162, + 2167, + 2178, + 2183, + 2202, + 2211, + 2214, + 2223, + 2225, + 2232, + 2237, + 2257, + 2260, + 2267, + 2274, + 2276, + 2285, + 2288, + 2293, + 2294, + 2297, + 2303, + 2308, + 2311, + 2318, + 2323, + 2332, + 2341, + 2345, + 2348, + 2354, + 2368, + 2377, + 2380, + 2383, + 2388, + 2395, + 2397, + 2401, + 2411, + 2413, + 2419, + 2435, + 2442, + 2455, + 2472, + 2478, + 2490, + 2507, + 2509, + 2517, + 2524, + 2528, + 2531, + 2538, + 2545, + 2546, + 2555, + 2557, + 2564, + 2573, + 2579, + 2592, + 2598, + 2607, + 2612, + 2619, + 2621, + 2627, + 2633, + 2636, + 2642, + 2654, + 2660, + 2669, + 2675, + 2684, + 2694, + 2703, + 2706, + 2712, + 2715, + 2722, + 2727, + 2734, + 2742, + 2745, + 2751, + 2766, + 2768, + 2780, + 2790, + 2794, + 2796, + 2801, + 2804, + 2807, + 2816, + 2821, + 2831, + 2834, + 2839, + 2845, + 2852, + 2856, + 2861, + 2873, + 2874, + 2888, + 2893, + 2894, + 2902, + 2917, + 2921, + 2922, + 2929, + 2935, + 2946, + 2951, + 2957, + 2960, + 2966, + 2972, + 2976, + 2979, + 2985, + 3000, + 3003, + 3013, + 3018, + 3020, + 3025, + 3042, + 3047, + 3048, + 3051, + 3054, + 3056, + 3065, + 3073, + 3074, + 3083, + 3086, + 3091, + 3097, + 3109, + 3116, + 3124, + 3128, + 3153, + 3160, + 3165, + 3172, + 3175, + 3184, + 3193, + 3196, + 3200, + 3203, + 3205, + 3209, + 3224, + 3239, + 3251, + 3254, + 3265, + 3266, + 3275, + 3280, + 3283, + 3286, + 3301, + 3302, + 3305, + 3319, + 3323, + 3326, + 3331, + 3348, + 3351, + 3358, + 3368, + 3374, + 3376, + 3379, + 3385, + 3386, + 3396, + 3420, + 3423, + 3430, + 3433, + 3434, + 3439, + 3442, + 3444, + 3453, + 3464, + 3477, + 3478, + 3482, + 3487, + 3497, + 3500, + 3505, + 3506, + 3511, + 3512, + 3515, + 3525, + 3532, + 3538, + 3540, + 3547, + 3549, + 3560, + 3571, + 3577, + 3583, + 3590, + 3593, + 3594, + 3599, + 3601, + 3602, + 3613, + 3623, + 3630, + 3638, + 3649, + 3655, + 3662, + 3667, + 3669, + 3676, + 3683, + 3700, + 3709, + 3710, + 3713, + 3723, + 3725, + 3728, + 3734, + 3737, + 3738, + 3744, + 3750, + 3762, + 3764, + 3774, + 3776, + 3786, + 3800, + 3803, + 3809, + 3816, + 3821, + 3827, + 3829, + 3836, + 3842, + 3844, + 3847, + 3853, + 3861, + 3871, + 3872, + 3881, + 3890, + 3892, + 3909, + 3921, + 3934, + 3938, + 3947, + 3950, + 3952, + 3964, + 3974, + 3980, + 3983, + 3986, + 3995, + 3998, + 4001, + 4002, + 4004, + 4008, + 4011, + 4016, + 4033, + 4036, + 4040, + 4053, + 4058, + 4081, + 4091, + 4094, + -1 + }; + //#endif + + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_13 + static long[] PrimitivePolynomialDegree14 = + { + 21, + 28, + 41, + 47, + 61, + 84, + 87, + 93, + 94, + 103, + 117, + 121, + 134, + 137, + 157, + 161, + 205, + 206, + 211, + 214, + 218, + 234, + 236, + 248, + 262, + 299, + 304, + 319, + 322, + 334, + 355, + 357, + 358, + 369, + 372, + 375, + 388, + 400, + 415, + 446, + 451, + 458, + 471, + 484, + 501, + 502, + 517, + 545, + 569, + 617, + 618, + 623, + 625, + 637, + 661, + 668, + 684, + 695, + 716, + 719, + 722, + 731, + 738, + 747, + 755, + 761, + 767, + 775, + 782, + 787, + 794, + 803, + 812, + 817, + 824, + 829, + 850, + 866, + 871, + 877, + 920, + 935, + 959, + 979, + 992, + 1010, + 1012, + 1015, + 1033, + 1036, + 1053, + 1057, + 1069, + 1072, + 1075, + 1087, + 1089, + 1137, + 1166, + 1174, + 1180, + 1204, + 1211, + 1219, + 1236, + 1255, + 1264, + 1306, + 1330, + 1341, + 1344, + 1347, + 1349, + 1361, + 1380, + 1390, + 1404, + 1435, + 1444, + 1453, + 1461, + 1462, + 1465, + 1468, + 1474, + 1483, + 1488, + 1493, + 1500, + 1509, + 1510, + 1514, + 1519, + 1528, + 1533, + 1540, + 1550, + 1567, + 1571, + 1573, + 1578, + 1598, + 1606, + 1618, + 1630, + 1634, + 1640, + 1643, + 1654, + 1679, + 1688, + 1698, + 1703, + 1704, + 1722, + 1735, + 1750, + 1753, + 1760, + 1789, + 1792, + 1802, + 1819, + 1825, + 1828, + 1832, + 1845, + 1846, + 1857, + 1869, + 1897, + 1906, + 1908, + 1911, + 1934, + 1962, + 1967, + 1972, + 1975, + 1999, + 2004, + 2011, + 2013, + 2037, + 2051, + 2063, + 2066, + 2094, + 2128, + 2154, + 2164, + 2198, + 2217, + 2220, + 2223, + 2238, + 2245, + 2252, + 2258, + 2264, + 2280, + 2285, + 2293, + 2294, + 2298, + 2303, + 2306, + 2311, + 2326, + 2354, + 2373, + 2380, + 2385, + 2392, + 2401, + 2402, + 2408, + 2419, + 2450, + 2452, + 2477, + 2509, + 2510, + 2515, + 2524, + 2527, + 2531, + 2552, + 2561, + 2567, + 2571, + 2586, + 2588, + 2595, + 2607, + 2621, + 2630, + 2639, + 2653, + 2670, + 2672, + 2700, + 2711, + 2715, + 2748, + 2751, + 2753, + 2754, + 2760, + 2774, + 2784, + 2793, + 2804, + 2811, + 2822, + 2826, + 2836, + 2839, + 2840, + 2893, + 2901, + 2902, + 2905, + 2912, + 2915, + 2918, + 2939, + 2965, + 2966, + 2975, + 2988, + 2993, + 3006, + 3017, + 3031, + 3038, + 3041, + 3042, + 3051, + 3073, + 3088, + 3097, + 3098, + 3103, + 3104, + 3146, + 3148, + 3153, + 3159, + 3182, + 3187, + 3189, + 3199, + 3239, + 3263, + 3271, + 3275, + 3278, + 3280, + 3283, + 3290, + 3311, + 3316, + 3343, + 3346, + 3357, + 3358, + 3361, + 3362, + 3364, + 3386, + 3418, + 3424, + 3433, + 3434, + 3436, + 3463, + 3467, + 3477, + 3484, + 3505, + 3508, + 3515, + 3532, + 3553, + 3554, + 3568, + 3573, + 3587, + 3589, + 3596, + 3608, + 3620, + 3630, + 3644, + 3649, + 3664, + 3679, + 3680, + 3685, + 3686, + 3698, + 3714, + 3726, + 3737, + 3767, + 3782, + 3786, + 3793, + 3796, + 3805, + 3815, + 3841, + 3847, + 3853, + 3862, + 3875, + 3902, + 3904, + 3916, + 3947, + 3949, + 3955, + 3962, + 3971, + 3980, + 3985, + 3998, + 4001, + 4002, + 4016, + 4021, + 4026, + 4043, + 4079, + 4102, + 4106, + 4119, + 4126, + 4147, + 4149, + 4164, + 4174, + 4181, + 4185, + 4188, + 4202, + 4228, + 4232, + 4246, + 4252, + 4256, + 4286, + 4303, + 4306, + 4311, + 4317, + 4342, + 4346, + 4377, + 4401, + 4407, + 4414, + 4422, + 4431, + 4434, + 4436, + 4443, + 4459, + 4461, + 4462, + 4473, + 4497, + 4504, + 4507, + 4525, + 4534, + 4538, + 4548, + 4552, + 4560, + 4575, + 4599, + 4612, + 4619, + 4640, + 4643, + 4677, + 4687, + 4723, + 4730, + 4736, + 4741, + 4763, + 4765, + 4770, + 4781, + 4808, + 4822, + 4828, + 4831, + 4842, + 4855, + 4859, + 4867, + 4870, + 4881, + 4893, + 4910, + 4917, + 4929, + 4939, + 4947, + 4949, + 4954, + 4972, + 4975, + 5000, + 5005, + 5029, + 5039, + 5044, + 5051, + 5056, + 5073, + 5096, + 5128, + 5134, + 5161, + 5179, + 5193, + 5199, + 5202, + 5204, + 5218, + 5247, + 5260, + 5271, + 5301, + 5305, + 5319, + 5326, + 5328, + 5333, + 5364, + 5376, + 5399, + 5416, + 5421, + 5427, + 5429, + 5430, + 5434, + 5441, + 5451, + 5465, + 5466, + 5471, + 5477, + 5492, + 5495, + 5505, + 5515, + 5525, + 5529, + 5532, + 5539, + 5541, + 5556, + 5566, + 5568, + 5574, + 5595, + 5602, + 5611, + 5616, + 5622, + 5628, + 5655, + 5662, + 5675, + 5689, + 5722, + 5724, + 5728, + 5731, + 5746, + 5764, + 5771, + 5781, + 5801, + 5809, + 5810, + 5812, + 5841, + 5848, + 5853, + 5854, + 5858, + 5892, + 5907, + 5910, + 5913, + 5920, + 5929, + 5949, + 5952, + 5955, + 5962, + 5975, + 5985, + 5997, + 5998, + 6012, + 6016, + 6026, + 6036, + 6040, + 6045, + 6055, + 6059, + 6088, + 6115, + 6124, + 6127, + 6132, + 6146, + 6158, + 6169, + 6206, + 6228, + 6237, + 6244, + 6247, + 6256, + 6281, + 6282, + 6284, + 6296, + 6299, + 6302, + 6325, + 6349, + 6352, + 6362, + 6383, + 6386, + 6395, + 6397, + 6415, + 6424, + 6429, + 6439, + 6451, + 6489, + 6496, + 6502, + 6511, + 6514, + 6520, + 6523, + 6529, + 6532, + 6547, + 6549, + 6598, + 6601, + 6610, + 6622, + 6632, + 6655, + 6665, + 6666, + 6695, + 6701, + 6709, + 6710, + 6741, + 6745, + 6758, + 6767, + 6772, + 6782, + 6797, + 6800, + 6843, + 6845, + 6860, + 6865, + 6878, + 6887, + 6888, + 6901, + 6906, + 6940, + 6947, + 6953, + 6954, + 6959, + 6961, + 6964, + 6991, + 6993, + 6999, + 7016, + 7029, + 7036, + 7045, + 7076, + 7083, + 7094, + 7097, + 7123, + 7130, + 7139, + 7145, + 7146, + 7178, + 7186, + 7192, + 7198, + 7222, + 7269, + 7270, + 7276, + 7287, + 7307, + 7315, + 7334, + 7340, + 7351, + 7352, + 7357, + 7360, + 7363, + 7384, + 7396, + 7403, + 7406, + 7425, + 7437, + 7445, + 7450, + 7455, + 7461, + 7466, + 7488, + 7494, + 7515, + 7517, + 7521, + 7536, + 7546, + 7569, + 7591, + 7592, + 7598, + 7612, + 7623, + 7632, + 7637, + 7644, + 7657, + 7665, + 7672, + 7682, + 7699, + 7702, + 7724, + 7749, + 7753, + 7754, + 7761, + 7771, + 7777, + 7784, + 7804, + 7807, + 7808, + 7818, + 7835, + 7842, + 7865, + 7868, + 7880, + 7883, + 7891, + 7897, + 7907, + 7910, + 7924, + 7933, + 7934, + 7942, + 7948, + 7959, + 7984, + 7994, + 7999, + 8014, + 8021, + 8041, + 8049, + 8050, + 8068, + 8080, + 8095, + 8102, + 8106, + 8120, + 8133, + 8134, + 8143, + 8162, + 8168, + 8179, + -1 + }; + //#endif + + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_14 + static long[] PrimitivePolynomialDegree15 = + { + 1, + 8, + 11, + 22, + 26, + 47, + 59, + 64, + 67, + 73, + 82, + 97, + 103, + 110, + 115, + 122, + 128, + 138, + 146, + 171, + 174, + 176, + 182, + 194, + 208, + 211, + 220, + 229, + 230, + 239, + 254, + 265, + 285, + 290, + 319, + 324, + 327, + 333, + 357, + 364, + 395, + 397, + 405, + 409, + 419, + 422, + 431, + 433, + 436, + 440, + 453, + 460, + 471, + 478, + 482, + 488, + 524, + 529, + 535, + 536, + 539, + 563, + 566, + 572, + 577, + 587, + 592, + 602, + 623, + 635, + 638, + 654, + 656, + 659, + 665, + 675, + 677, + 687, + 696, + 701, + 704, + 710, + 721, + 728, + 738, + 740, + 749, + 758, + 761, + 772, + 776, + 782, + 789, + 810, + 812, + 818, + 830, + 832, + 852, + 855, + 859, + 865, + 877, + 895, + 901, + 902, + 906, + 916, + 920, + 949, + 962, + 964, + 967, + 981, + 982, + 985, + 991, + 1007, + 1016, + 1024, + 1051, + 1060, + 1070, + 1072, + 1084, + 1089, + 1095, + 1114, + 1123, + 1132, + 1154, + 1156, + 1163, + 1171, + 1202, + 1228, + 1239, + 1255, + 1256, + 1262, + 1270, + 1279, + 1308, + 1322, + 1329, + 1330, + 1336, + 1341, + 1347, + 1349, + 1359, + 1367, + 1368, + 1390, + 1413, + 1414, + 1437, + 1441, + 1462, + 1465, + 1480, + 1486, + 1504, + 1509, + 1514, + 1522, + 1528, + 1552, + 1555, + 1571, + 1578, + 1585, + 1588, + 1603, + 1609, + 1617, + 1620, + 1629, + 1636, + 1648, + 1667, + 1669, + 1682, + 1697, + 1704, + 1709, + 1727, + 1730, + 1732, + 1741, + 1744, + 1759, + 1765, + 1766, + 1778, + 1780, + 1783, + 1797, + 1807, + 1821, + 1832, + 1835, + 1849, + 1850, + 1863, + 1867, + 1869, + 1872, + 1887, + 1888, + 1897, + 1906, + 1917, + 1927, + 1939, + 1941, + 1948, + 1970, + 1979, + 1982, + 2002, + 2020, + 2024, + 2032, + 2053, + 2060, + 2063, + 2066, + 2075, + 2078, + 2081, + 2091, + 2096, + 2102, + 2106, + 2116, + 2120, + 2125, + 2134, + 2178, + 2180, + 2187, + 2189, + 2190, + 2208, + 2214, + 2237, + 2252, + 2257, + 2260, + 2264, + 2270, + 2279, + 2288, + 2305, + 2312, + 2317, + 2323, + 2329, + 2335, + 2342, + 2345, + 2365, + 2371, + 2378, + 2385, + 2395, + 2404, + 2414, + 2426, + 2428, + 2441, + 2456, + 2466, + 2468, + 2475, + 2489, + 2495, + 2497, + 2510, + 2512, + 2522, + 2533, + 2543, + 2551, + 2552, + 2557, + 2567, + 2581, + 2586, + 2597, + 2601, + 2622, + 2633, + 2636, + 2642, + 2644, + 2653, + 2667, + 2669, + 2672, + 2675, + 2682, + 2687, + 2691, + 2698, + 2708, + 2712, + 2718, + 2722, + 2736, + 2741, + 2756, + 2765, + 2774, + 2799, + 2804, + 2825, + 2826, + 2840, + 2843, + 2846, + 2849, + 2867, + 2876, + 2891, + 2902, + 2912, + 2917, + 2927, + 2941, + 2965, + 2970, + 2982, + 2993, + 3018, + 3023, + 3025, + 3026, + 3028, + 3032, + 3053, + 3054, + 3065, + 3071, + 3076, + 3088, + 3107, + 3146, + 3148, + 3159, + 3165, + 3170, + 3179, + 3182, + 3205, + 3212, + 3218, + 3220, + 3223, + 3227, + 3233, + 3234, + 3254, + 3263, + 3268, + 3272, + 3277, + 3292, + 3295, + 3296, + 3301, + 3306, + 3313, + 3346, + 3367, + 3371, + 3373, + 3374, + 3376, + 3382, + 3388, + 3391, + 3403, + 3406, + 3413, + 3420, + 3427, + 3441, + 3453, + 3464, + 3469, + 3481, + 3488, + 3497, + 3503, + 3511, + 3515, + 3525, + 3529, + 3547, + 3550, + 3573, + 3583, + 3594, + 3607, + 3613, + 3624, + 3630, + 3635, + 3642, + 3644, + 3650, + 3679, + 3690, + 3698, + 3704, + 3707, + 3713, + 3754, + 3756, + 3761, + 3776, + 3781, + 3788, + 3791, + 3794, + 3806, + 3841, + 3848, + 3851, + 3856, + 3868, + 3875, + 3882, + 3884, + 3889, + 3892, + 3919, + 3921, + 3958, + 3961, + 3973, + 3977, + 3985, + 3991, + 4004, + 4007, + 4019, + 4045, + 4054, + 4057, + 4058, + 4070, + 4101, + 4113, + 4114, + 4119, + 4129, + 4141, + 4142, + 4147, + 4149, + 4150, + 4164, + 4168, + 4186, + 4198, + 4207, + 4221, + 4225, + 4231, + 4238, + 4243, + 4249, + 4250, + 4252, + 4259, + 4279, + 4285, + 4288, + 4303, + 4312, + 4322, + 4327, + 4336, + 4359, + 4384, + 4387, + 4401, + 4407, + 4428, + 4436, + 4450, + 4452, + 4459, + 4461, + 4470, + 4483, + 4485, + 4486, + 4492, + 4497, + 4514, + 4533, + 4537, + 4546, + 4551, + 4555, + 4560, + 4569, + 4576, + 4582, + 4586, + 4609, + 4610, + 4612, + 4649, + 4652, + 4672, + 4677, + 4684, + 4690, + 4695, + 4696, + 4702, + 4705, + 4717, + 4726, + 4736, + 4753, + 4754, + 4756, + 4775, + 4801, + 4819, + 4828, + 4838, + 4852, + 4856, + 4873, + 4887, + 4891, + 4904, + 4912, + 4921, + 4936, + 4941, + 4942, + 4963, + 4984, + 4990, + 5005, + 5013, + 5020, + 5039, + 5048, + 5062, + 5080, + 5085, + 5086, + 5095, + 5096, + 5102, + 5107, + 5141, + 5145, + 5148, + 5157, + 5158, + 5162, + 5172, + 5182, + 5184, + 5193, + 5199, + 5201, + 5204, + 5211, + 5223, + 5230, + 5232, + 5253, + 5257, + 5260, + 5284, + 5306, + 5331, + 5334, + 5364, + 5367, + 5371, + 5382, + 5386, + 5399, + 5400, + 5409, + 5415, + 5416, + 5424, + 5436, + 5454, + 5462, + 5468, + 5481, + 5505, + 5511, + 5518, + 5530, + 5532, + 5539, + 5553, + 5573, + 5580, + 5597, + 5602, + 5608, + 5611, + 5613, + 5625, + 5632, + 5635, + 5638, + 5652, + 5659, + 5677, + 5686, + 5689, + 5698, + 5703, + 5707, + 5731, + 5738, + 5743, + 5748, + 5758, + 5762, + 5768, + 5773, + 5776, + 5815, + 5841, + 5847, + 5860, + 5870, + 5875, + 5877, + 5884, + 5892, + 5902, + 5910, + 5916, + 5919, + 5935, + 5937, + 5944, + 5947, + 5958, + 5962, + 5969, + 5981, + 5995, + 5998, + 6003, + 6010, + 6016, + 6025, + 6031, + 6036, + 6039, + 6045, + 6049, + 6052, + 6067, + 6074, + 6087, + 6101, + 6121, + 6129, + 6142, + 6151, + 6157, + 6166, + 6170, + 6175, + 6186, + 6203, + 6217, + 6231, + 6241, + 6242, + 6248, + 6256, + 6265, + 6275, + 6277, + 6302, + 6315, + 6318, + 6330, + 6343, + 6347, + 6350, + 6352, + 6371, + 6383, + 6386, + 6405, + 6409, + 6410, + 6433, + 6436, + 6439, + 6463, + 6468, + 6477, + 6496, + 6511, + 6516, + 6519, + 6523, + 6530, + 6539, + 6547, + 6589, + 6592, + 6601, + 6610, + 6616, + 6619, + 6626, + 6635, + 6637, + 6638, + 6652, + 6656, + 6662, + 6689, + 6699, + 6710, + 6714, + 6719, + 6739, + 6751, + 6775, + 6779, + 6788, + 6798, + 6815, + 6819, + 6825, + 6826, + 6836, + 6843, + 6845, + 6858, + 6868, + 6877, + 6881, + 6891, + 6896, + 6899, + 6901, + 6908, + 6914, + 6916, + 6923, + 6925, + 6928, + 6931, + 6934, + 6937, + 6938, + 6949, + 6956, + 6973, + 6976, + 6981, + 6988, + 6999, + 7016, + 7027, + 7029, + 7055, + 7058, + 7074, + 7083, + 7093, + 7100, + 7105, + 7112, + 7118, + 7120, + 7129, + 7166, + 7207, + 7216, + 7226, + 7234, + 7236, + 7246, + 7248, + 7254, + 7263, + 7273, + 7274, + 7293, + 7297, + 7310, + 7315, + 7317, + 7331, + 7338, + 7340, + 7346, + 7355, + 7366, + 7383, + 7389, + 7393, + 7396, + 7400, + 7414, + 7417, + 7426, + 7432, + 7452, + 7468, + 7488, + 7491, + 7494, + 7497, + 7515, + 7531, + 7552, + 7562, + 7564, + 7569, + 7582, + 7585, + 7588, + 7592, + 7597, + 7603, + 7610, + 7624, + 7642, + 7647, + 7653, + 7654, + 7666, + 7668, + 7684, + 7705, + 7732, + 7741, + 7749, + 7750, + 7759, + 7764, + 7777, + 7790, + 7817, + 7826, + 7831, + 7859, + 7871, + 7873, + 7876, + 7900, + 7904, + 7913, + 7916, + 7922, + 7946, + 7953, + 7956, + 7963, + 7979, + 7981, + 7984, + 7989, + 7999, + 8001, + 8021, + 8056, + 8080, + 8083, + 8089, + 8090, + 8114, + 8128, + 8133, + 8145, + 8155, + 8161, + 8182, + 8186, + 8191, + 8192, + 8195, + 8201, + 8207, + 8210, + 8228, + 8249, + 8252, + 8258, + 8267, + 8270, + 8275, + 8284, + 8293, + 8298, + 8305, + 8317, + 8328, + 8336, + 8345, + 8351, + 8367, + 8379, + 8381, + 8382, + 8393, + 8402, + 8414, + 8417, + 8420, + 8429, + 8435, + 8438, + 8450, + 8452, + 8459, + 8470, + 8486, + 8490, + 8500, + 8524, + 8536, + 8552, + 8558, + 8570, + 8576, + 8582, + 8594, + 8606, + 8619, + 8621, + 8624, + 8633, + 8641, + 8653, + 8654, + 8662, + 8675, + 8689, + 8695, + 8702, + 8706, + 8720, + 8729, + 8739, + 8741, + 8751, + 8759, + 8766, + 8777, + 8783, + 8786, + 8795, + 8802, + 8814, + 8821, + 8828, + 8831, + 8837, + 8842, + 8855, + 8856, + 8868, + 8877, + 8890, + 8892, + 8900, + 8909, + 8912, + 8921, + 8922, + 8927, + 8943, + 8948, + 8951, + 8958, + 8984, + 8994, + 9000, + 9013, + 9018, + 9020, + 9031, + 9035, + 9045, + 9052, + 9056, + 9059, + 9066, + 9076, + 9089, + 9129, + 9132, + 9147, + 9164, + 9167, + 9185, + 9195, + 9197, + 9210, + 9217, + 9229, + 9248, + 9254, + 9263, + 9266, + 9268, + 9290, + 9310, + 9316, + 9338, + 9340, + 9343, + 9344, + 9350, + 9354, + 9359, + 9361, + 9364, + 9368, + 9371, + 9373, + 9389, + 9390, + 9409, + 9443, + 9445, + 9446, + 9452, + 9490, + 9492, + 9495, + 9508, + 9523, + 9543, + 9558, + 9567, + 9580, + 9585, + 9591, + 9611, + 9613, + 9614, + 9621, + 9631, + 9642, + 9656, + 9661, + 9667, + 9694, + 9715, + 9722, + 9738, + 9745, + 9758, + 9764, + 9782, + 9791, + 9793, + 9794, + 9805, + 9808, + 9811, + 9817, + 9824, + 9836, + 9851, + 9853, + 9854, + 9877, + 9881, + 9923, + 9935, + 9937, + 9954, + 9959, + 9963, + 9968, + 9973, + 9974, + 9980, + 9983, + 9985, + 10003, + 10010, + 10034, + 10040, + 10063, + 10077, + 10081, + 10082, + 10084, + 10088, + 10091, + 10105, + 10111, + 10118, + 10127, + 10135, + 10169, + 10172, + 10183, + 10190, + 10192, + 10211, + 10218, + 10228, + 10235, + 10242, + 10244, + 10271, + 10278, + 10296, + 10299, + 10307, + 10309, + 10310, + 10314, + 10316, + 10321, + 10328, + 10338, + 10343, + 10344, + 10347, + 10352, + 10364, + 10373, + 10386, + 10391, + 10398, + 10408, + 10413, + 10422, + 10445, + 10460, + 10463, + 10464, + 10474, + 10476, + 10487, + 10494, + 10499, + 10506, + 10513, + 10516, + 10523, + 10539, + 10549, + 10550, + 10567, + 10576, + 10625, + 10635, + 10643, + 10656, + 10671, + 10676, + 10683, + 10685, + 10688, + 10697, + 10700, + 10712, + 10724, + 10728, + 10734, + 10739, + 10762, + 10772, + 10781, + 10800, + 10805, + 10827, + 10830, + 10837, + 10841, + 10847, + 10848, + 10857, + 10866, + 10868, + 10872, + 10887, + 10899, + 10901, + 10915, + 10924, + 10929, + 10942, + 10971, + 10992, + 10995, + 11002, + 11010, + 11027, + 11029, + 11045, + 11057, + 11070, + 11092, + 11099, + 11106, + 11115, + 11120, + 11126, + 11153, + 11190, + 11199, + 11222, + 11225, + 11226, + 11231, + 11244, + 11259, + 11261, + 11270, + 11273, + 11300, + 11307, + 11318, + 11332, + 11335, + 11341, + 11347, + 11354, + 11360, + 11369, + 11372, + 11378, + 11396, + 11405, + 11417, + 11424, + 11427, + 11430, + 11439, + 11442, + 11448, + 11461, + 11468, + 11471, + 11473, + 11476, + 11480, + 11489, + 11499, + 11516, + 11522, + 11531, + 11539, + 11546, + 11551, + 11564, + 11582, + 11589, + 11593, + 11601, + 11608, + 11617, + 11630, + 11663, + 11666, + 11668, + 11677, + 11682, + 11687, + 11696, + 11713, + 11728, + 11747, + 11750, + 11754, + 11759, + 11761, + 11764, + 11767, + 11797, + 11804, + 11808, + 11831, + 11832, + 11849, + 11855, + 11863, + 11880, + 11883, + 11885, + 11898, + 11916, + 11924, + 11928, + 11947, + 11955, + 11961, + 11962, + 11982, + 11990, + 12010, + 12018, + 12027, + 12029, + 12035, + 12055, + 12062, + 12068, + 12071, + 12072, + 12086, + 12097, + 12098, + 12100, + 12112, + 12118, + 12133, + 12134, + 12137, + 12161, + 12162, + 12171, + 12174, + 12185, + 12204, + 12212, + 12215, + 12216, + 12253, + 12260, + 12277, + 12289, + 12295, + 12314, + 12323, + 12325, + 12335, + 12349, + 12358, + 12372, + 12376, + 12379, + 12386, + 12395, + 12416, + 12421, + 12440, + 12452, + 12455, + 12456, + 12462, + 12467, + 12479, + 12505, + 12521, + 12535, + 12547, + 12556, + 12561, + 12568, + 12578, + 12583, + 12595, + 12604, + 12610, + 12621, + 12622, + 12624, + 12629, + 12630, + 12639, + 12640, + 12650, + 12679, + 12680, + 12698, + 12716, + 12721, + 12722, + 12731, + 12742, + 12745, + 12751, + 12759, + 12763, + 12769, + 12781, + 12793, + 12799, + 12815, + 12824, + 12836, + 12845, + 12853, + 12854, + 12857, + 12866, + 12872, + 12875, + 12878, + 12880, + 12885, + 12901, + 12902, + 12920, + 12926, + 12929, + 12939, + 12941, + 12950, + 12953, + 12992, + 13002, + 13010, + 13058, + 13072, + 13084, + 13087, + 13091, + 13097, + 13108, + 13123, + 13149, + 13150, + 13163, + 13166, + 13178, + 13180, + 13184, + 13204, + 13238, + 13242, + 13249, + 13255, + 13269, + 13270, + 13274, + 13285, + 13289, + 13298, + 13307, + 13312, + 13335, + 13345, + 13357, + 13366, + 13372, + 13380, + 13384, + 13395, + 13407, + 13408, + 13413, + 13414, + 13417, + 13437, + 13441, + 13447, + 13456, + 13459, + 13461, + 13466, + 13484, + 13487, + 13489, + 13492, + 13496, + 13510, + 13531, + 13538, + 13543, + 13547, + 13572, + 13581, + 13590, + 13605, + 13612, + 13624, + 13630, + 13632, + 13638, + 13661, + 13665, + 13668, + 13686, + 13699, + 13701, + 13708, + 13716, + 13725, + 13730, + 13742, + 13747, + 13749, + 13753, + 13754, + 13771, + 13773, + 13782, + 13785, + 13798, + 13802, + 13809, + 13828, + 13832, + 13840, + 13850, + 13861, + 13874, + 13876, + 13886, + 13897, + 13900, + 13915, + 13927, + 13951, + 13955, + 13962, + 13969, + 13979, + 13988, + 13998, + 14000, + 14005, + 14027, + 14037, + 14051, + 14054, + 14060, + 14063, + 14071, + 14078, + 14080, + 14085, + 14086, + 14095, + 14138, + 14145, + 14158, + 14166, + 14179, + 14181, + 14188, + 14193, + 14200, + 14203, + 14215, + 14224, + 14230, + 14233, + 14236, + 14246, + 14267, + 14282, + 14287, + 14301, + 14323, + 14325, + 14329, + 14339, + 14342, + 14351, + 14356, + 14359, + 14370, + 14402, + 14411, + 14421, + 14431, + 14435, + 14442, + 14447, + 14456, + 14459, + 14472, + 14477, + 14490, + 14496, + 14501, + 14505, + 14513, + 14520, + 14534, + 14562, + 14576, + 14579, + 14585, + 14586, + 14606, + 14627, + 14630, + 14634, + 14636, + 14647, + 14653, + 14659, + 14671, + 14674, + 14701, + 14716, + 14719, + 14720, + 14725, + 14730, + 14743, + 14747, + 14786, + 14788, + 14792, + 14795, + 14809, + 14831, + 14834, + 14850, + 14855, + 14859, + 14864, + 14876, + 14889, + 14890, + 14898, + 14909, + 14917, + 14924, + 14929, + 14942, + 14951, + 14969, + 14970, + 14972, + 14982, + 14988, + 14994, + 15005, + 15016, + 15024, + 15030, + 15048, + 15054, + 15066, + 15071, + 15072, + 15075, + 15119, + 15121, + 15133, + 15138, + 15143, + 15170, + 15194, + 15212, + 15223, + 15229, + 15254, + 15263, + 15270, + 15273, + 15287, + 15299, + 15301, + 15306, + 15313, + 15320, + 15323, + 15329, + 15332, + 15341, + 15359, + 15361, + 15364, + 15367, + 15379, + 15391, + 15415, + 15416, + 15419, + 15433, + 15469, + 15478, + 15481, + 15482, + 15498, + 15505, + 15517, + 15518, + 15527, + 15528, + 15545, + 15548, + 15554, + 15565, + 15577, + 15580, + 15587, + 15601, + 15604, + 15611, + 15616, + 15619, + 15625, + 15633, + 15674, + 15681, + 15691, + 15693, + 15696, + 15712, + 15717, + 15724, + 15727, + 15730, + 15746, + 15751, + 15760, + 15770, + 15782, + 15791, + 15796, + 15808, + 15814, + 15825, + 15828, + 15835, + 15844, + 15847, + 15853, + 15856, + 15877, + 15878, + 15887, + 15908, + 15917, + 15923, + 15930, + 15937, + 15958, + 15977, + 15991, + 16007, + 16011, + 16014, + 16021, + 16022, + 16028, + 16035, + 16041, + 16056, + 16069, + 16076, + 16081, + 16087, + 16088, + 16110, + 16112, + 16117, + 16150, + 16153, + 16160, + 16166, + 16172, + 16190, + 16195, + 16204, + 16216, + 16222, + 16228, + 16245, + 16255, + 16265, + 16273, + 16276, + 16283, + 16295, + 16304, + 16313, + 16319, + 16328, + 16345, + 16355, + 16364, + 16372, + 16375, + 16382, + -1 + }; + //#endif + + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_15 + static long[] PrimitivePolynomialDegree16 = + { + 22, + 28, + 31, + 41, + 94, + 107, + 151, + 158, + 167, + 174, + 203, + 208, + 214, + 223, + 227, + 266, + 268, + 274, + 279, + 302, + 310, + 322, + 328, + 336, + 370, + 398, + 421, + 436, + 440, + 451, + 454, + 463, + 465, + 494, + 508, + 532, + 555, + 563, + 577, + 580, + 584, + 607, + 608, + 665, + 675, + 692, + 707, + 737, + 750, + 757, + 800, + 805, + 809, + 837, + 865, + 949, + 950, + 956, + 961, + 1016, + 1030, + 1072, + 1119, + 1130, + 1135, + 1137, + 1144, + 1149, + 1180, + 1214, + 1221, + 1234, + 1239, + 1249, + 1250, + 1267, + 1273, + 1342, + 1344, + 1373, + 1378, + 1408, + 1417, + 1418, + 1448, + 1454, + 1510, + 1513, + 1522, + 1543, + 1550, + 1552, + 1588, + 1592, + 1597, + 1606, + 1610, + 1617, + 1623, + 1657, + 1697, + 1729, + 1735, + 1769, + 1778, + 1826, + 1858, + 1870, + 1875, + 1922, + 1924, + 1933, + 1972, + 1979, + 1987, + 1994, + 2008, + 2023, + 2029, + 2053, + 2081, + 2087, + 2094, + 2111, + 2113, + 2114, + 2123, + 2190, + 2231, + 2276, + 2285, + 2297, + 2336, + 2345, + 2353, + 2363, + 2368, + 2373, + 2391, + 2402, + 2413, + 2422, + 2425, + 2461, + 2462, + 2490, + 2492, + 2510, + 2564, + 2573, + 2598, + 2627, + 2633, + 2647, + 2660, + 2664, + 2678, + 2684, + 2691, + 2759, + 2768, + 2773, + 2794, + 2813, + 2831, + 2843, + 2846, + 2849, + 2856, + 2893, + 2901, + 2924, + 2942, + 2975, + 2979, + 2985, + 3020, + 3025, + 3028, + 3051, + 3127, + 3142, + 3145, + 3156, + 3165, + 3196, + 3199, + 3217, + 3218, + 3253, + 3258, + 3260, + 3289, + 3314, + 3326, + 3331, + 3371, + 3381, + 3396, + 3441, + 3442, + 3460, + 3477, + 3491, + 3493, + 3543, + 3549, + 3550, + 3553, + 3563, + 3568, + 3604, + 3632, + 3650, + 3662, + 3674, + 3685, + 3686, + 3700, + 3703, + 3704, + 3723, + 3743, + 3753, + 3756, + 3759, + 3762, + 3771, + 3776, + 3779, + 3839, + 3856, + 3871, + 3887, + 3896, + 3901, + 3916, + 3919, + 3937, + 3943, + 3955, + 3961, + 3988, + 3997, + 4011, + 4026, + 4033, + 4045, + 4060, + 4063, + 4064, + 4126, + 4136, + 4167, + 4173, + 4188, + 4195, + 4226, + 4291, + 4298, + 4308, + 4312, + 4336, + 4371, + 4378, + 4384, + 4393, + 4421, + 4425, + 4439, + 4440, + 4500, + 4514, + 4523, + 4534, + 4593, + 4615, + 4630, + 4636, + 4645, + 4684, + 4687, + 4723, + 4735, + 4746, + 4779, + 4782, + 4793, + 4796, + 4813, + 4850, + 4867, + 4874, + 4881, + 4894, + 4904, + 4927, + 4929, + 4989, + 5000, + 5020, + 5036, + 5041, + 5059, + 5074, + 5090, + 5110, + 5134, + 5152, + 5176, + 5181, + 5204, + 5218, + 5242, + 5253, + 5260, + 5281, + 5282, + 5313, + 5316, + 5326, + 5340, + 5347, + 5354, + 5368, + 5394, + 5396, + 5400, + 5405, + 5439, + 5442, + 5459, + 5478, + 5484, + 5508, + 5523, + 5545, + 5565, + 5566, + 5580, + 5608, + 5613, + 5647, + 5661, + 5671, + 5678, + 5680, + 5685, + 5689, + 5692, + 5724, + 5745, + 5755, + 5757, + 5786, + 5792, + 5810, + 5824, + 5869, + 5872, + 5895, + 5923, + 5925, + 5926, + 5944, + 5986, + 6012, + 6015, + 6046, + 6049, + 6061, + 6067, + 6099, + 6121, + 6155, + 6163, + 6203, + 6208, + 6231, + 6241, + 6254, + 6262, + 6266, + 6275, + 6278, + 6292, + 6329, + 6355, + 6357, + 6374, + 6380, + 6423, + 6427, + 6430, + 6436, + 6443, + 6445, + 6458, + 6478, + 6490, + 6508, + 6519, + 6520, + 6530, + 6541, + 6556, + 6607, + 6612, + 6626, + 6632, + 6649, + 6666, + 6674, + 6733, + 6782, + 6786, + 6798, + 6821, + 6840, + 6846, + 6865, + 6884, + 6891, + 6925, + 6938, + 6967, + 6988, + 6996, + 7009, + 7016, + 7030, + 7043, + 7045, + 7052, + 7073, + 7142, + 7153, + 7168, + 7174, + 7183, + 7195, + 7204, + 7214, + 7222, + 7267, + 7269, + 7279, + 7293, + 7312, + 7327, + 7334, + 7337, + 7343, + 7346, + 7372, + 7387, + 7390, + 7396, + 7423, + 7428, + 7437, + 7466, + 7474, + 7476, + 7483, + 7518, + 7527, + 7545, + 7572, + 7586, + 7597, + 7630, + 7653, + 7657, + 7671, + 7672, + 7715, + 7717, + 7732, + 7735, + 7753, + 7811, + 7817, + 7825, + 7832, + 7838, + 7841, + 7844, + 7859, + 7861, + 7873, + 7880, + 7897, + 7904, + 7910, + 7960, + 7969, + 7970, + 7976, + 7979, + 8007, + 8041, + 8047, + 8052, + 8061, + 8078, + 8128, + 8146, + 8162, + 8250, + 8270, + 8294, + 8324, + 8351, + 8357, + 8361, + 8364, + 8393, + 8396, + 8407, + 8413, + 8414, + 8432, + 8435, + 8441, + 8447, + 8449, + 8456, + 8485, + 8504, + 8512, + 8532, + 8551, + 8560, + 8566, + 8581, + 8609, + 8639, + 8641, + 8671, + 8695, + 8701, + 8711, + 8739, + 8763, + 8778, + 8783, + 8785, + 8797, + 8802, + 8816, + 8828, + 8837, + 8852, + 8859, + 8889, + 8900, + 8903, + 8909, + 8910, + 8922, + 8924, + 8955, + 8958, + 8980, + 8994, + 9006, + 9017, + 9032, + 9040, + 9061, + 9066, + 9071, + 9076, + 9086, + 9104, + 9150, + 9161, + 9164, + 9185, + 9188, + 9212, + 9230, + 9242, + 9247, + 9260, + 9280, + 9300, + 9313, + 9325, + 9343, + 9349, + 9354, + 9367, + 9368, + 9455, + 9458, + 9469, + 9481, + 9482, + 9495, + 9526, + 9530, + 9558, + 9562, + 9573, + 9583, + 9595, + 9597, + 9616, + 9638, + 9649, + 9662, + 9691, + 9700, + 9703, + 9710, + 9721, + 9724, + 9727, + 9743, + 9779, + 9785, + 9811, + 9820, + 9827, + 9851, + 9854, + 9863, + 9884, + 9894, + 9903, + 9908, + 9912, + 9925, + 9926, + 9971, + 9973, + 9977, + 10021, + 10039, + 10048, + 10051, + 10065, + 10071, + 10072, + 10101, + 10106, + 10130, + 10136, + 10148, + 10155, + 10157, + 10160, + 10166, + 10183, + 10192, + 10225, + 10241, + 10247, + 10284, + 10304, + 10322, + 10331, + 10333, + 10340, + 10347, + 10357, + 10371, + 10386, + 10404, + 10414, + 10422, + 10448, + 10451, + 10473, + 10479, + 10501, + 10530, + 10542, + 10544, + 10571, + 10628, + 10643, + 10673, + 10683, + 10736, + 10795, + 10797, + 10815, + 10817, + 10842, + 10844, + 10863, + 10899, + 10902, + 10917, + 10953, + 10967, + 11002, + 11024, + 11029, + 11030, + 11043, + 11087, + 11106, + 11130, + 11156, + 11176, + 11221, + 11267, + 11282, + 11294, + 11332, + 11353, + 11369, + 11372, + 11375, + 11413, + 11429, + 11430, + 11444, + 11462, + 11465, + 11471, + 11473, + 11495, + 11499, + 11519, + 11562, + 11576, + 11582, + 11596, + 11602, + 11611, + 11627, + 11682, + 11687, + 11691, + 11733, + 11747, + 11759, + 11778, + 11852, + 11857, + 11858, + 11893, + 11907, + 11928, + 11931, + 11933, + 11967, + 11976, + 11989, + 12003, + 12024, + 12030, + 12037, + 12044, + 12052, + 12059, + 12075, + 12083, + 12117, + 12138, + 12146, + 12202, + 12230, + 12254, + 12304, + 12316, + 12337, + 12347, + 12367, + 12398, + 12421, + 12428, + 12446, + 12449, + 12467, + 12479, + 12502, + 12521, + 12553, + 12568, + 12573, + 12592, + 12597, + 12601, + 12615, + 12619, + 12694, + 12697, + 12698, + 12713, + 12722, + 12733, + 12736, + 12790, + 12794, + 12803, + 12815, + 12829, + 12833, + 12840, + 12875, + 12877, + 12916, + 12923, + 12935, + 12949, + 12954, + 12956, + 12959, + 12978, + 13001, + 13010, + 13043, + 13049, + 13058, + 13112, + 13140, + 13149, + 13163, + 13187, + 13196, + 13237, + 13244, + 13264, + 13279, + 13292, + 13295, + 13307, + 13312, + 13317, + 13327, + 13348, + 13390, + 13413, + 13417, + 13418, + 13451, + 13475, + 13482, + 13510, + 13527, + 13543, + 13547, + 13627, + 13650, + 13683, + 13696, + 13702, + 13713, + 13739, + 13749, + 13767, + 13774, + 13781, + 13795, + 13821, + 13825, + 13838, + 13852, + 13879, + 13888, + 13897, + 13906, + 13939, + 13962, + 13981, + 13985, + 14020, + 14030, + 14041, + 14047, + 14048, + 14066, + 14092, + 14120, + 14126, + 14131, + 14143, + 14146, + 14152, + 14155, + 14157, + 14188, + 14206, + 14243, + 14278, + 14308, + 14317, + 14335, + 14354, + 14356, + 14379, + 14381, + 14384, + 14389, + 14390, + 14414, + 14425, + 14462, + 14472, + 14508, + 14511, + 14519, + 14528, + 14561, + 14574, + 14588, + 14594, + 14606, + 14614, + 14639, + 14641, + 14648, + 14668, + 14673, + 14679, + 14695, + 14702, + 14704, + 14740, + 14754, + 14774, + 14792, + 14797, + 14806, + 14812, + 14856, + 14876, + 14900, + 14910, + 14912, + 14915, + 14922, + 14939, + 14946, + 14955, + 14966, + 14976, + 14986, + 14993, + 15012, + 15041, + 15053, + 15056, + 15059, + 15110, + 15116, + 15133, + 15134, + 15137, + 15147, + 15182, + 15203, + 15215, + 15245, + 15246, + 15264, + 15269, + 15296, + 15314, + 15323, + 15364, + 15386, + 15391, + 15436, + 15460, + 15464, + 15469, + 15470, + 15477, + 15488, + 15494, + 15548, + 15551, + 15560, + 15563, + 15604, + 15607, + 15616, + 15631, + 15699, + 15701, + 15708, + 15739, + 15746, + 15772, + 15793, + 15832, + 15837, + 15866, + 15899, + 15911, + 15918, + 15952, + 15962, + 15967, + 15973, + 15977, + 16016, + 16035, + 16044, + 16067, + 16082, + 16084, + 16098, + 16107, + 16142, + 16149, + 16165, + 16172, + 16178, + 16197, + 16201, + 16215, + 16221, + 16226, + 16232, + 16246, + 16261, + 16279, + 16280, + 16290, + 16314, + 16345, + 16355, + 16361, + 16393, + 16394, + 16438, + 16450, + 16507, + 16523, + 16533, + 16603, + 16648, + 16653, + 16672, + 16682, + 16709, + 16713, + 16719, + 16733, + 16740, + 16761, + 16767, + 16771, + 16788, + 16811, + 16814, + 16816, + 16828, + 16834, + 16863, + 16864, + 16879, + 16888, + 16904, + 16909, + 16921, + 16934, + 16951, + 16983, + 16999, + 17000, + 17006, + 17020, + 17030, + 17033, + 17044, + 17051, + 17072, + 17078, + 17084, + 17087, + 17090, + 17123, + 17132, + 17140, + 17149, + 17157, + 17164, + 17170, + 17179, + 17237, + 17248, + 17260, + 17272, + 17275, + 17287, + 17294, + 17296, + 17305, + 17312, + 17321, + 17367, + 17368, + 17378, + 17433, + 17455, + 17457, + 17508, + 17559, + 17560, + 17582, + 17596, + 17599, + 17613, + 17619, + 17622, + 17655, + 17661, + 17698, + 17712, + 17715, + 17721, + 17722, + 17742, + 17778, + 17818, + 17836, + 17841, + 17856, + 17883, + 17896, + 17901, + 17926, + 17937, + 17992, + 17995, + 17998, + 18021, + 18039, + 18067, + 18122, + 18129, + 18130, + 18142, + 18148, + 18163, + 18192, + 18211, + 18228, + 18264, + 18347, + 18372, + 18409, + 18412, + 18418, + 18423, + 18433, + 18439, + 18445, + 18451, + 18467, + 18502, + 18514, + 18547, + 18575, + 18593, + 18613, + 18620, + 18637, + 18640, + 18712, + 18728, + 18742, + 18748, + 18753, + 18756, + 18771, + 18814, + 18818, + 18827, + 18835, + 18842, + 18854, + 18858, + 18895, + 18914, + 18925, + 18933, + 18937, + 18944, + 18973, + 19001, + 19012, + 19016, + 19027, + 19040, + 19074, + 19085, + 19093, + 19100, + 19107, + 19128, + 19141, + 19142, + 19156, + 19169, + 19176, + 19222, + 19226, + 19247, + 19259, + 19262, + 19291, + 19309, + 19324, + 19334, + 19338, + 19343, + 19376, + 19408, + 19413, + 19420, + 19441, + 19444, + 19454, + 19461, + 19473, + 19479, + 19489, + 19591, + 19605, + 19616, + 19619, + 19653, + 19654, + 19681, + 19711, + 19719, + 19726, + 19738, + 19767, + 19819, + 19864, + 19867, + 19885, + 19894, + 19900, + 19903, + 19941, + 19951, + 19959, + 19966, + 20009, + 20018, + 20020, + 20038, + 20049, + 20066, + 20108, + 20130, + 20132, + 20167, + 20219, + 20227, + 20263, + 20267, + 20272, + 20289, + 20296, + 20307, + 20316, + 20323, + 20335, + 20344, + 20354, + 20360, + 20368, + 20390, + 20402, + 20413, + 20425, + 20428, + 20434, + 20443, + 20488, + 20502, + 20505, + 20535, + 20541, + 20554, + 20577, + 20583, + 20602, + 20611, + 20614, + 20626, + 20628, + 20635, + 20642, + 20674, + 20716, + 20734, + 20765, + 20801, + 20804, + 20808, + 20831, + 20832, + 20862, + 20877, + 20880, + 20885, + 20889, + 20905, + 20914, + 20967, + 21028, + 21031, + 21043, + 21052, + 21058, + 21087, + 21088, + 21093, + 21106, + 21108, + 21118, + 21122, + 21131, + 21139, + 21141, + 21146, + 21162, + 21164, + 21184, + 21208, + 21211, + 21213, + 21230, + 21270, + 21276, + 21285, + 21297, + 21304, + 21310, + 21330, + 21339, + 21346, + 21391, + 21427, + 21451, + 21465, + 21468, + 21471, + 21533, + 21610, + 21615, + 21630, + 21633, + 21657, + 21658, + 21669, + 21670, + 21673, + 21701, + 21719, + 21720, + 21747, + 21819, + 21839, + 21854, + 21857, + 21864, + 21882, + 21900, + 21903, + 21928, + 21931, + 21946, + 21971, + 21974, + 21978, + 21993, + 21994, + 22030, + 22035, + 22063, + 22068, + 22086, + 22104, + 22119, + 22153, + 22168, + 22183, + 22189, + 22204, + 22230, + 22240, + 22246, + 22269, + 22282, + 22302, + 22330, + 22347, + 22349, + 22383, + 22386, + 22432, + 22450, + 22473, + 22487, + 22527, + 22537, + 22557, + 22561, + 22568, + 22573, + 22591, + 22593, + 22605, + 22620, + 22627, + 22636, + 22647, + 22697, + 22715, + 22725, + 22732, + 22749, + 22766, + 22768, + 22771, + 22788, + 22797, + 22822, + 22828, + 22851, + 22888, + 22893, + 22901, + 22902, + 22921, + 22929, + 22946, + 22948, + 22951, + 22958, + 22975, + 22983, + 22990, + 23032, + 23047, + 23053, + 23054, + 23082, + 23095, + 23116, + 23197, + 23221, + 23257, + 23260, + 23263, + 23267, + 23282, + 23284, + 23314, + 23326, + 23335, + 23368, + 23373, + 23401, + 23415, + 23432, + 23476, + 23479, + 23497, + 23505, + 23508, + 23531, + 23536, + 23542, + 23565, + 23573, + 23590, + 23593, + 23604, + 23621, + 23622, + 23636, + 23662, + 23667, + 23703, + 23725, + 23734, + 23738, + 23752, + 23800, + 23803, + 23818, + 23832, + 23842, + 23851, + 23873, + 23883, + 23888, + 23910, + 23934, + 23938, + 23949, + 23955, + 23967, + 23973, + 23991, + 24024, + 24030, + 24039, + 24067, + 24069, + 24084, + 24112, + 24115, + 24184, + 24187, + 24262, + 24276, + 24279, + 24313, + 24331, + 24336, + 24348, + 24367, + 24372, + 24402, + 24420, + 24444, + 24465, + 24466, + 24471, + 24475, + 24481, + 24488, + 24501, + 24514, + 24531, + 24534, + 24559, + 24602, + 24614, + 24637, + 24664, + 24676, + 24679, + 24697, + 24709, + 24714, + 24716, + 24731, + 24744, + 24762, + 24764, + 24769, + 24806, + 24812, + 24872, + 24878, + 24883, + 24909, + 24943, + 24946, + 24964, + 24992, + 25016, + 25022, + 25024, + 25039, + 25051, + 25060, + 25072, + 25097, + 25122, + 25148, + 25194, + 25201, + 25204, + 25238, + 25241, + 25248, + 25257, + 25275, + 25278, + 25304, + 25307, + 25320, + 25334, + 25348, + 25357, + 25372, + 25394, + 25454, + 25465, + 25472, + 25492, + 25505, + 25517, + 25530, + 25558, + 25562, + 25598, + 25609, + 25612, + 25627, + 25651, + 25653, + 25668, + 25711, + 25765, + 25770, + 25775, + 25777, + 25783, + 25801, + 25802, + 25812, + 25821, + 25897, + 25906, + 25929, + 25940, + 25950, + 25968, + 25971, + 25977, + 25994, + 25996, + 25999, + 26001, + 26030, + 26069, + 26100, + 26109, + 26131, + 26144, + 26149, + 26162, + 26167, + 26173, + 26179, + 26193, + 26230, + 26234, + 26246, + 26267, + 26283, + 26300, + 26341, + 26356, + 26377, + 26397, + 26404, + 26411, + 26422, + 26451, + 26454, + 26463, + 26488, + 26498, + 26509, + 26512, + 26517, + 26534, + 26545, + 26546, + 26636, + 26749, + 26753, + 26759, + 26774, + 26789, + 26808, + 26825, + 26831, + 26859, + 26888, + 26918, + 26929, + 26950, + 26954, + 26973, + 26997, + 26998, + 27008, + 27038, + 27109, + 27127, + 27150, + 27168, + 27178, + 27212, + 27224, + 27229, + 27246, + 27251, + 27257, + 27258, + 27260, + 27287, + 27300, + 27315, + 27329, + 27332, + 27349, + 27350, + 27354, + 27359, + 27377, + 27378, + 27383, + 27384, + 27387, + 27392, + 27402, + 27438, + 27481, + 27482, + 27494, + 27531, + 27542, + 27546, + 27564, + 27567, + 27582, + 27608, + 27611, + 27624, + 27629, + 27655, + 27667, + 27676, + 27710, + 27724, + 27745, + 27752, + 27770, + 27779, + 27781, + 27791, + 27809, + 27810, + 27815, + 27827, + 27834, + 27865, + 27899, + 27901, + 27914, + 27950, + 27994, + 28005, + 28009, + 28033, + 28039, + 28060, + 28067, + 28069, + 28099, + 28113, + 28114, + 28139, + 28142, + 28153, + 28166, + 28172, + 28183, + 28194, + 28232, + 28245, + 28246, + 28252, + 28265, + 28301, + 28323, + 28344, + 28362, + 28400, + 28417, + 28454, + 28466, + 28468, + 28477, + 28498, + 28510, + 28513, + 28571, + 28573, + 28578, + 28587, + 28601, + 28646, + 28663, + 28681, + 28682, + 28699, + 28706, + 28708, + 28717, + 28720, + 28735, + 28761, + 28783, + 28788, + 28811, + 28825, + 28838, + 28850, + 28891, + 28897, + 28932, + 28975, + 28998, + 29052, + 29090, + 29096, + 29104, + 29113, + 29133, + 29142, + 29170, + 29192, + 29221, + 29236, + 29246, + 29293, + 29305, + 29312, + 29339, + 29365, + 29389, + 29402, + 29423, + 29443, + 29445, + 29463, + 29473, + 29493, + 29506, + 29518, + 29532, + 29560, + 29590, + 29594, + 29637, + 29647, + 29650, + 29655, + 29661, + 29680, + 29721, + 29751, + 29755, + 29760, + 29772, + 29778, + 29799, + 29824, + 29841, + 29842, + 29853, + 29867, + 29949, + 29950, + 29964, + 29967, + 29985, + 29992, + 30000, + 30020, + 30024, + 30030, + 30066, + 30071, + 30078, + 30082, + 30096, + 30101, + 30102, + 30122, + 30141, + 30159, + 30168, + 30177, + 30183, + 30197, + 30213, + 30231, + 30232, + 30241, + 30253, + 30259, + 30262, + 30268, + 30297, + 30316, + 30322, + 30344, + 30350, + 30355, + 30429, + 30445, + 30477, + 30513, + 30520, + 30540, + 30551, + 30573, + 30609, + 30622, + 30635, + 30658, + 30667, + 30681, + 30684, + 30703, + 30705, + 30715, + 30742, + 30748, + 30758, + 30767, + 30770, + 30772, + 30807, + 30814, + 30824, + 30857, + 30875, + 30931, + 30933, + 30949, + 30953, + 30982, + 31010, + 31012, + 31039, + 31041, + 31061, + 31082, + 31087, + 31096, + 31115, + 31130, + 31168, + 31171, + 31177, + 31180, + 31191, + 31207, + 31247, + 31249, + 31285, + 31303, + 31310, + 31337, + 31352, + 31357, + 31374, + 31379, + 31388, + 31410, + 31416, + 31467, + 31495, + 31504, + 31507, + 31509, + 31514, + 31516, + 31530, + 31555, + 31567, + 31570, + 31586, + 31598, + 31605, + 31609, + 31612, + 31626, + 31634, + 31655, + 31681, + 31705, + 31706, + 31718, + 31735, + 31741, + 31744, + 31762, + 31774, + 31864, + 31874, + 31900, + 31910, + 31928, + 31965, + 31976, + 32016, + 32032, + 32037, + 32062, + 32069, + 32115, + 32128, + 32171, + 32173, + 32182, + 32191, + 32193, + 32194, + 32229, + 32230, + 32248, + 32263, + 32264, + 32269, + 32298, + 32335, + 32340, + 32356, + 32374, + 32390, + 32401, + 32414, + 32417, + 32442, + 32450, + 32461, + 32473, + 32479, + 32530, + 32536, + 32548, + 32577, + 32628, + 32642, + 32665, + 32666, + 32668, + 32696, + 32722, + 32757, + 32758, + -1 + }; + //#endif + + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_16 + static long[] PrimitivePolynomialDegree17 = + { + 4, + 7, + 16, + 22, + 25, + 31, + 32, + 42, + 52, + 61, + 70, + 76, + 81, + 87, + 93, + 98, + 122, + 133, + 134, + 140, + 146, + 158, + 171, + 176, + 179, + 182, + 191, + 193, + 224, + 227, + 229, + 236, + 248, + 262, + 273, + 276, + 280, + 283, + 290, + 309, + 316, + 319, + 321, + 328, + 346, + 355, + 367, + 369, + 372, + 382, + 388, + 392, + 395, + 397, + 403, + 409, + 410, + 425, + 443, + 472, + 475, + 481, + 488, + 493, + 501, + 515, + 522, + 524, + 527, + 535, + 542, + 545, + 555, + 558, + 560, + 563, + 570, + 578, + 583, + 590, + 597, + 604, + 608, + 614, + 635, + 637, + 653, + 654, + 659, + 666, + 671, + 689, + 690, + 695, + 713, + 722, + 733, + 758, + 770, + 782, + 784, + 793, + 803, + 805, + 812, + 838, + 849, + 875, + 877, + 880, + 892, + 895, + 899, + 919, + 920, + 932, + 935, + 936, + 941, + 950, + 961, + 962, + 971, + 982, + 986, + 1012, + 1021, + 1024, + 1029, + 1030, + 1051, + 1054, + 1064, + 1067, + 1082, + 1096, + 1116, + 1119, + 1129, + 1130, + 1132, + 1137, + 1147, + 1150, + 1154, + 1165, + 1166, + 1174, + 1177, + 1184, + 1194, + 1204, + 1208, + 1213, + 1219, + 1233, + 1264, + 1267, + 1281, + 1312, + 1321, + 1330, + 1332, + 1335, + 1341, + 1356, + 1371, + 1377, + 1380, + 1384, + 1395, + 1397, + 1411, + 1414, + 1426, + 1432, + 1435, + 1437, + 1442, + 1454, + 1468, + 1473, + 1488, + 1491, + 1509, + 1524, + 1533, + 1555, + 1567, + 1571, + 1586, + 1592, + 1595, + 1600, + 1606, + 1627, + 1648, + 1651, + 1654, + 1667, + 1669, + 1674, + 1687, + 1698, + 1710, + 1717, + 1722, + 1735, + 1741, + 1749, + 1750, + 1769, + 1775, + 1777, + 1778, + 1792, + 1797, + 1802, + 1822, + 1825, + 1831, + 1838, + 1852, + 1855, + 1860, + 1867, + 1869, + 1875, + 1882, + 1903, + 1908, + 1917, + 1927, + 1941, + 1945, + 1948, + 1962, + 1975, + 1976, + 1987, + 1993, + 2004, + 2020, + 2029, + 2030, + 2038, + 2041, + 2048, + 2054, + 2057, + 2058, + 2068, + 2072, + 2075, + 2077, + 2082, + 2084, + 2087, + 2101, + 2111, + 2113, + 2119, + 2147, + 2154, + 2161, + 2164, + 2177, + 2178, + 2184, + 2198, + 2201, + 2213, + 2217, + 2228, + 2240, + 2245, + 2250, + 2263, + 2267, + 2285, + 2286, + 2291, + 2298, + 2306, + 2325, + 2329, + 2332, + 2335, + 2339, + 2346, + 2351, + 2353, + 2363, + 2378, + 2383, + 2391, + 2401, + 2408, + 2414, + 2419, + 2428, + 2441, + 2444, + 2461, + 2480, + 2483, + 2486, + 2489, + 2490, + 2518, + 2527, + 2540, + 2558, + 2567, + 2571, + 2574, + 2579, + 2585, + 2615, + 2639, + 2641, + 2644, + 2663, + 2667, + 2669, + 2672, + 2687, + 2700, + 2705, + 2724, + 2728, + 2733, + 2741, + 2748, + 2751, + 2756, + 2771, + 2774, + 2793, + 2796, + 2804, + 2814, + 2822, + 2845, + 2846, + 2850, + 2855, + 2856, + 2867, + 2891, + 2894, + 2902, + 2908, + 2951, + 2970, + 2972, + 2975, + 2976, + 2981, + 2986, + 2999, + 3000, + 3006, + 3014, + 3028, + 3031, + 3035, + 3037, + 3053, + 3059, + 3065, + 3080, + 3091, + 3094, + 3109, + 3110, + 3113, + 3116, + 3136, + 3139, + 3141, + 3154, + 3160, + 3169, + 3182, + 3187, + 3189, + 3190, + 3203, + 3217, + 3229, + 3236, + 3248, + 3257, + 3278, + 3283, + 3289, + 3292, + 3302, + 3316, + 3328, + 3333, + 3337, + 3340, + 3368, + 3371, + 3376, + 3385, + 3386, + 3393, + 3399, + 3405, + 3414, + 3433, + 3436, + 3448, + 3467, + 3469, + 3472, + 3477, + 3484, + 3494, + 3505, + 3515, + 3523, + 3530, + 3543, + 3559, + 3568, + 3577, + 3578, + 3594, + 3601, + 3607, + 3608, + 3620, + 3629, + 3644, + 3656, + 3664, + 3670, + 3680, + 3685, + 3686, + 3695, + 3698, + 3703, + 3710, + 3714, + 3726, + 3731, + 3733, + 3737, + 3756, + 3759, + 3767, + 3776, + 3785, + 3793, + 3812, + 3815, + 3824, + 3844, + 3859, + 3866, + 3872, + 3884, + 3889, + 3899, + 3902, + 3909, + 3913, + 3933, + 3938, + 3949, + 3952, + 3980, + 3991, + 3992, + 4002, + 4008, + 4011, + 4016, + 4034, + 4036, + 4063, + 4067, + 4073, + 4082, + 4091, + 4093, + 4101, + 4113, + 4120, + 4125, + 4126, + 4139, + 4142, + 4144, + 4147, + 4153, + 4154, + 4164, + 4174, + 4182, + 4185, + 4188, + 4191, + 4195, + 4219, + 4225, + 4228, + 4232, + 4246, + 4255, + 4274, + 4283, + 4286, + 4306, + 4311, + 4317, + 4321, + 4324, + 4331, + 4333, + 4359, + 4360, + 4368, + 4373, + 4389, + 4394, + 4413, + 4422, + 4431, + 4436, + 4440, + 4445, + 4452, + 4462, + 4469, + 4470, + 4473, + 4479, + 4480, + 4483, + 4489, + 4503, + 4519, + 4520, + 4525, + 4526, + 4533, + 4552, + 4581, + 4585, + 4591, + 4594, + 4596, + 4599, + 4612, + 4621, + 4630, + 4636, + 4640, + 4649, + 4650, + 4660, + 4677, + 4687, + 4696, + 4701, + 4705, + 4706, + 4711, + 4720, + 4723, + 4732, + 4736, + 4742, + 4748, + 4754, + 4759, + 4769, + 4787, + 4807, + 4814, + 4837, + 4867, + 4873, + 4879, + 4884, + 4898, + 4907, + 4910, + 4918, + 4924, + 4953, + 4956, + 4965, + 4966, + 4970, + 4972, + 4983, + 4989, + 4994, + 5000, + 5005, + 5014, + 5018, + 5023, + 5039, + 5053, + 5054, + 5061, + 5065, + 5080, + 5083, + 5107, + 5119, + 5146, + 5151, + 5152, + 5155, + 5169, + 5170, + 5176, + 5179, + 5182, + 5189, + 5193, + 5196, + 5204, + 5207, + 5211, + 5220, + 5258, + 5265, + 5271, + 5277, + 5278, + 5282, + 5296, + 5299, + 5319, + 5328, + 5343, + 5353, + 5364, + 5368, + 5379, + 5381, + 5399, + 5415, + 5422, + 5441, + 5451, + 5456, + 5462, + 5490, + 5495, + 5501, + 5502, + 5505, + 5512, + 5523, + 5529, + 5548, + 5551, + 5553, + 5565, + 5568, + 5577, + 5578, + 5583, + 5585, + 5588, + 5613, + 5614, + 5616, + 5622, + 5631, + 5637, + 5638, + 5668, + 5675, + 5683, + 5695, + 5703, + 5710, + 5715, + 5727, + 5738, + 5752, + 5767, + 5773, + 5776, + 5781, + 5791, + 5792, + 5795, + 5798, + 5801, + 5810, + 5812, + 5836, + 5839, + 5841, + 5867, + 5870, + 5877, + 5881, + 5899, + 5914, + 5925, + 5929, + 5943, + 5949, + 5962, + 5969, + 5976, + 5988, + 5997, + 6006, + 6010, + 6016, + 6022, + 6026, + 6031, + 6040, + 6043, + 6050, + 6059, + 6079, + 6099, + 6101, + 6105, + 6108, + 6124, + 6132, + 6145, + 6146, + 6151, + 6152, + 6158, + 6160, + 6163, + 6165, + 6170, + 6182, + 6196, + 6199, + 6200, + 6205, + 6226, + 6228, + 6237, + 6247, + 6251, + 6253, + 6256, + 6268, + 6272, + 6275, + 6281, + 6289, + 6335, + 6338, + 6355, + 6362, + 6373, + 6386, + 6388, + 6391, + 6397, + 6405, + 6406, + 6410, + 6417, + 6443, + 6457, + 6468, + 6475, + 6486, + 6489, + 6495, + 6499, + 6505, + 6511, + 6520, + 6529, + 6542, + 6547, + 6550, + 6554, + 6556, + 6560, + 6569, + 6572, + 6590, + 6592, + 6601, + 6610, + 6632, + 6635, + 6640, + 6643, + 6649, + 6659, + 6662, + 6666, + 6690, + 6692, + 6704, + 6713, + 6728, + 6731, + 6734, + 6746, + 6755, + 6757, + 6764, + 6772, + 6792, + 6797, + 6821, + 6822, + 6831, + 6834, + 6851, + 6858, + 6860, + 6871, + 6875, + 6884, + 6888, + 6894, + 6919, + 6940, + 6950, + 6959, + 6968, + 6981, + 6988, + 6996, + 6999, + 7015, + 7019, + 7022, + 7040, + 7045, + 7049, + 7055, + 7073, + 7076, + 7085, + 7091, + 7103, + 7112, + 7117, + 7118, + 7123, + 7126, + 7154, + 7180, + 7192, + 7195, + 7207, + 7208, + 7214, + 7222, + 7234, + 7254, + 7258, + 7264, + 7279, + 7282, + 7293, + 7297, + 7322, + 7324, + 7351, + 7363, + 7380, + 7384, + 7389, + 7396, + 7413, + 7417, + 7431, + 7443, + 7445, + 7450, + 7456, + 7466, + 7468, + 7474, + 7479, + 7486, + 7497, + 7508, + 7515, + 7533, + 7542, + 7546, + 7551, + 7569, + 7572, + 7595, + 7603, + 7605, + 7629, + 7632, + 7638, + 7648, + 7654, + 7663, + 7675, + 7693, + 7705, + 7717, + 7724, + 7727, + 7735, + 7761, + 7767, + 7783, + 7784, + 7798, + 7802, + 7811, + 7817, + 7823, + 7832, + 7837, + 7842, + 7853, + 7854, + 7856, + 7861, + 7862, + 7873, + 7874, + 7886, + 7914, + 7927, + 7936, + 7951, + 7963, + 7966, + 7976, + 7993, + 8001, + 8004, + 8013, + 8021, + 8026, + 8028, + 8031, + 8035, + 8042, + 8071, + 8085, + 8092, + 8102, + 8105, + 8114, + 8123, + 8131, + 8140, + 8145, + 8157, + 8158, + 8185, + 8186, + 8188, + 8192, + 8212, + 8219, + 8221, + 8235, + 8237, + 8249, + 8260, + 8264, + 8270, + 8282, + 8291, + 8293, + 8297, + 8298, + 8305, + 8306, + 8311, + 8318, + 8327, + 8345, + 8379, + 8390, + 8394, + 8414, + 8417, + 8432, + 8437, + 8441, + 8449, + 8456, + 8473, + 8489, + 8495, + 8522, + 8524, + 8529, + 8545, + 8557, + 8565, + 8572, + 8576, + 8582, + 8594, + 8629, + 8636, + 8668, + 8678, + 8701, + 8702, + 8708, + 8712, + 8745, + 8754, + 8759, + 8763, + 8766, + 8780, + 8783, + 8786, + 8798, + 8804, + 8819, + 8826, + 8835, + 8838, + 8856, + 8862, + 8871, + 8875, + 8890, + 8892, + 8898, + 8927, + 8928, + 8945, + 8952, + 8955, + 8965, + 8972, + 8977, + 8990, + 8996, + 9025, + 9037, + 9040, + 9049, + 9062, + 9068, + 9076, + 9079, + 9099, + 9107, + 9114, + 9123, + 9126, + 9137, + 9149, + 9150, + 9155, + 9161, + 9162, + 9167, + 9172, + 9186, + 9188, + 9191, + 9198, + 9200, + 9205, + 9206, + 9215, + 9227, + 9232, + 9241, + 9244, + 9251, + 9254, + 9275, + 9283, + 9285, + 9303, + 9304, + 9313, + 9314, + 9320, + 9328, + 9333, + 9337, + 9338, + 9340, + 9353, + 9356, + 9364, + 9373, + 9374, + 9378, + 9380, + 9389, + 9395, + 9412, + 9422, + 9439, + 9450, + 9452, + 9482, + 9487, + 9489, + 9499, + 9501, + 9508, + 9515, + 9518, + 9520, + 9526, + 9537, + 9552, + 9571, + 9588, + 9613, + 9619, + 9622, + 9637, + 9652, + 9655, + 9661, + 9664, + 9669, + 9681, + 9682, + 9688, + 9697, + 9700, + 9715, + 9722, + 9727, + 9734, + 9740, + 9743, + 9745, + 9757, + 9761, + 9762, + 9767, + 9768, + 9774, + 9786, + 9796, + 9820, + 9823, + 9839, + 9844, + 9851, + 9853, + 9863, + 9864, + 9877, + 9884, + 9888, + 9897, + 9915, + 9925, + 9949, + 9954, + 9960, + 9965, + 9978, + 9986, + 9992, + 9995, + 10005, + 10026, + 10031, + 10040, + 10051, + 10057, + 10072, + 10096, + 10102, + 10105, + 10115, + 10124, + 10139, + 10145, + 10148, + 10157, + 10158, + 10163, + 10180, + 10187, + 10198, + 10208, + 10214, + 10220, + 10237, + 10238, + 10241, + 10244, + 10251, + 10253, + 10256, + 10259, + 10266, + 10284, + 10290, + 10331, + 10334, + 10350, + 10355, + 10357, + 10367, + 10368, + 10377, + 10388, + 10407, + 10421, + 10434, + 10439, + 10440, + 10443, + 10446, + 10457, + 10469, + 10476, + 10479, + 10481, + 10494, + 10501, + 10505, + 10516, + 10532, + 10541, + 10547, + 10550, + 10591, + 10597, + 10602, + 10610, + 10619, + 10631, + 10646, + 10655, + 10665, + 10673, + 10674, + 10680, + 10693, + 10700, + 10721, + 10727, + 10746, + 10748, + 10757, + 10761, + 10770, + 10776, + 10782, + 10791, + 10792, + 10805, + 10810, + 10832, + 10835, + 10841, + 10842, + 10847, + 10853, + 10860, + 10871, + 10878, + 10881, + 10888, + 10894, + 10901, + 10915, + 10918, + 10922, + 10936, + 10954, + 10968, + 10971, + 10973, + 10978, + 10998, + 11009, + 11021, + 11029, + 11030, + 11034, + 11050, + 11063, + 11064, + 11077, + 11078, + 11105, + 11106, + 11126, + 11129, + 11135, + 11151, + 11159, + 11165, + 11176, + 11179, + 11182, + 11189, + 11204, + 11216, + 11232, + 11235, + 11242, + 11250, + 11264, + 11273, + 11282, + 11288, + 11291, + 11293, + 11318, + 11321, + 11329, + 11336, + 11339, + 11342, + 11356, + 11383, + 11389, + 11405, + 11411, + 11423, + 11424, + 11430, + 11444, + 11447, + 11459, + 11465, + 11473, + 11479, + 11501, + 11510, + 11514, + 11522, + 11527, + 11533, + 11536, + 11548, + 11551, + 11552, + 11555, + 11572, + 11587, + 11601, + 11613, + 11614, + 11618, + 11624, + 11630, + 11663, + 11682, + 11684, + 11702, + 11705, + 11713, + 11731, + 11734, + 11740, + 11747, + 11754, + 11761, + 11762, + 11787, + 11792, + 11814, + 11823, + 11825, + 11837, + 11838, + 11846, + 11855, + 11864, + 11876, + 11885, + 11904, + 11909, + 11913, + 11916, + 11940, + 11943, + 11972, + 11981, + 11990, + 11993, + 12000, + 12005, + 12015, + 12020, + 12038, + 12042, + 12056, + 12065, + 12066, + 12072, + 12080, + 12083, + 12090, + 12092, + 12103, + 12109, + 12112, + 12117, + 12121, + 12137, + 12143, + 12145, + 12148, + 12168, + 12174, + 12188, + 12191, + 12192, + 12201, + 12224, + 12230, + 12239, + 12242, + 12251, + 12258, + 12264, + 12310, + 12319, + 12323, + 12325, + 12332, + 12343, + 12344, + 12352, + 12370, + 12388, + 12395, + 12403, + 12409, + 12410, + 12415, + 12419, + 12426, + 12439, + 12445, + 12459, + 12464, + 12474, + 12484, + 12491, + 12501, + 12505, + 12508, + 12511, + 12521, + 12522, + 12530, + 12544, + 12547, + 12561, + 12571, + 12580, + 12597, + 12607, + 12609, + 12610, + 12616, + 12621, + 12624, + 12639, + 12645, + 12652, + 12655, + 12660, + 12667, + 12686, + 12688, + 12697, + 12700, + 12707, + 12710, + 12719, + 12739, + 12742, + 12746, + 12754, + 12765, + 12772, + 12784, + 12789, + 12800, + 12805, + 12809, + 12815, + 12827, + 12830, + 12833, + 12840, + 12851, + 12868, + 12871, + 12886, + 12899, + 12923, + 12926, + 12932, + 12935, + 12939, + 12942, + 12953, + 12959, + 12960, + 13002, + 13004, + 13016, + 13021, + 13035, + 13038, + 13052, + 13058, + 13069, + 13082, + 13093, + 13094, + 13100, + 13115, + 13125, + 13132, + 13143, + 13144, + 13153, + 13160, + 13165, + 13173, + 13174, + 13187, + 13190, + 13204, + 13218, + 13247, + 13250, + 13262, + 13267, + 13274, + 13304, + 13309, + 13315, + 13317, + 13324, + 13332, + 13342, + 13346, + 13355, + 13358, + 13360, + 13369, + 13372, + 13398, + 13404, + 13407, + 13414, + 13426, + 13432, + 13466, + 13481, + 13490, + 13496, + 13504, + 13516, + 13527, + 13533, + 13537, + 13552, + 13561, + 13567, + 13582, + 13587, + 13589, + 13593, + 13596, + 13615, + 13617, + 13623, + 13641, + 13647, + 13650, + 13659, + 13671, + 13677, + 13678, + 13680, + 13685, + 13689, + 13701, + 13706, + 13720, + 13729, + 13735, + 13736, + 13756, + 13759, + 13761, + 13771, + 13782, + 13786, + 13798, + 13810, + 13819, + 13826, + 13831, + 13837, + 13846, + 13856, + 13862, + 13866, + 13885, + 13891, + 13893, + 13905, + 13908, + 13912, + 13917, + 13918, + 13946, + 13948, + 13964, + 13970, + 13975, + 13979, + 13997, + 14000, + 14006, + 14020, + 14023, + 14024, + 14029, + 14035, + 14044, + 14047, + 14058, + 14066, + 14075, + 14080, + 14095, + 14100, + 14114, + 14116, + 14123, + 14134, + 14143, + 14151, + 14160, + 14163, + 14179, + 14181, + 14193, + 14209, + 14210, + 14224, + 14245, + 14249, + 14255, + 14267, + 14270, + 14277, + 14305, + 14308, + 14312, + 14325, + 14332, + 14345, + 14354, + 14372, + 14387, + 14390, + 14402, + 14408, + 14413, + 14431, + 14438, + 14447, + 14455, + 14461, + 14466, + 14480, + 14490, + 14492, + 14508, + 14513, + 14516, + 14519, + 14525, + 14534, + 14537, + 14543, + 14545, + 14552, + 14562, + 14571, + 14574, + 14582, + 14611, + 14614, + 14620, + 14633, + 14641, + 14648, + 14671, + 14674, + 14689, + 14690, + 14692, + 14699, + 14710, + 14719, + 14730, + 14732, + 14743, + 14744, + 14750, + 14759, + 14763, + 14768, + 14773, + 14777, + 14786, + 14795, + 14800, + 14812, + 14816, + 14836, + 14840, + 14856, + 14859, + 14870, + 14873, + 14879, + 14880, + 14889, + 14892, + 14895, + 14900, + 14903, + 14910, + 14912, + 14942, + 14948, + 14957, + 14963, + 14975, + 14985, + 14993, + 15003, + 15010, + 15022, + 15039, + 15041, + 15047, + 15048, + 15056, + 15066, + 15068, + 15075, + 15077, + 15082, + 15096, + 15102, + 15116, + 15122, + 15127, + 15133, + 15137, + 15138, + 15149, + 15152, + 15155, + 15158, + 15187, + 15189, + 15190, + 15196, + 15199, + 15205, + 15212, + 15236, + 15243, + 15246, + 15260, + 15267, + 15274, + 15279, + 15281, + 15282, + 15284, + 15291, + 15293, + 15302, + 15319, + 15329, + 15336, + 15347, + 15353, + 15361, + 15371, + 15397, + 15404, + 15407, + 15421, + 15433, + 15441, + 15442, + 15463, + 15472, + 15478, + 15488, + 15493, + 15498, + 15511, + 15521, + 15534, + 15539, + 15541, + 15560, + 15563, + 15574, + 15578, + 15584, + 15593, + 15604, + 15614, + 15619, + 15622, + 15633, + 15639, + 15646, + 15673, + 15674, + 15684, + 15691, + 15694, + 15696, + 15701, + 15705, + 15715, + 15729, + 15730, + 15741, + 15745, + 15748, + 15757, + 15765, + 15766, + 15775, + 15776, + 15779, + 15786, + 15788, + 15813, + 15814, + 15842, + 15851, + 15862, + 15875, + 15878, + 15889, + 15896, + 15901, + 15908, + 15911, + 15915, + 15938, + 15944, + 15950, + 15955, + 15974, + 15978, + 15980, + 15983, + 15991, + 16004, + 16011, + 16016, + 16019, + 16025, + 16041, + 16064, + 16067, + 16074, + 16082, + 16103, + 16109, + 16122, + 16149, + 16170, + 16175, + 16178, + 16189, + 16202, + 16204, + 16222, + 16231, + 16238, + 16262, + 16265, + 16276, + 16285, + 16313, + 16314, + 16321, + 16327, + 16333, + 16334, + 16364, + 16369, + 16370, + 16375, + 16376, + 16379, + 16393, + 16402, + 16408, + 16418, + 16438, + 16441, + 16447, + 16450, + 16455, + 16459, + 16483, + 16490, + 16492, + 16495, + 16523, + 16528, + 16543, + 16553, + 16562, + 16564, + 16576, + 16588, + 16612, + 16630, + 16654, + 16656, + 16668, + 16672, + 16675, + 16678, + 16681, + 16689, + 16699, + 16719, + 16734, + 16737, + 16750, + 16752, + 16757, + 16761, + 16773, + 16774, + 16801, + 16802, + 16822, + 16831, + 16840, + 16854, + 16858, + 16863, + 16867, + 16876, + 16891, + 16894, + 16898, + 16907, + 16915, + 16917, + 16922, + 16924, + 16933, + 16938, + 16952, + 16960, + 16963, + 16969, + 16978, + 17014, + 17020, + 17034, + 17036, + 17042, + 17047, + 17051, + 17054, + 17063, + 17069, + 17075, + 17077, + 17089, + 17090, + 17107, + 17126, + 17135, + 17150, + 17162, + 17169, + 17172, + 17175, + 17176, + 17191, + 17209, + 17218, + 17220, + 17227, + 17229, + 17238, + 17251, + 17257, + 17258, + 17272, + 17277, + 17308, + 17311, + 17321, + 17329, + 17342, + 17344, + 17350, + 17356, + 17371, + 17374, + 17392, + 17402, + 17410, + 17421, + 17424, + 17427, + 17434, + 17449, + 17452, + 17463, + 17470, + 17477, + 17482, + 17490, + 17496, + 17508, + 17511, + 17536, + 17563, + 17570, + 17581, + 17590, + 17608, + 17616, + 17621, + 17628, + 17644, + 17649, + 17652, + 17679, + 17691, + 17693, + 17697, + 17698, + 17700, + 17704, + 17707, + 17715, + 17718, + 17721, + 17722, + 17727, + 17729, + 17747, + 17754, + 17756, + 17760, + 17765, + 17778, + 17784, + 17794, + 17805, + 17806, + 17817, + 17824, + 17839, + 17842, + 17844, + 17851, + 17862, + 17868, + 17871, + 17873, + 17896, + 17904, + 17909, + 17920, + 17923, + 17947, + 17950, + 17956, + 17959, + 17966, + 17971, + 17973, + 17992, + 18006, + 18009, + 18010, + 18022, + 18039, + 18046, + 18069, + 18074, + 18076, + 18085, + 18086, + 18095, + 18100, + 18109, + 18121, + 18127, + 18129, + 18132, + 18141, + 18146, + 18151, + 18157, + 18160, + 18183, + 18204, + 18218, + 18226, + 18238, + 18245, + 18249, + 18260, + 18267, + 18270, + 18273, + 18274, + 18276, + 18283, + 18307, + 18314, + 18321, + 18334, + 18355, + 18364, + 18372, + 18390, + 18399, + 18415, + 18420, + 18434, + 18443, + 18446, + 18460, + 18467, + 18482, + 18484, + 18501, + 18506, + 18516, + 18519, + 18547, + 18569, + 18575, + 18589, + 18590, + 18605, + 18611, + 18625, + 18652, + 18665, + 18673, + 18674, + 18683, + 18688, + 18691, + 18698, + 18717, + 18733, + 18754, + 18759, + 18760, + 18771, + 18777, + 18796, + 18799, + 18807, + 18813, + 18817, + 18820, + 18827, + 18829, + 18838, + 18842, + 18848, + 18853, + 18885, + 18890, + 18898, + 18903, + 18910, + 18913, + 18931, + 18934, + 18956, + 18961, + 18968, + 18978, + 18983, + 18987, + 18992, + 18997, + 19002, + 19004, + 19010, + 19012, + 19030, + 19043, + 19049, + 19079, + 19086, + 19100, + 19103, + 19107, + 19109, + 19113, + 19116, + 19127, + 19134, + 19141, + 19179, + 19193, + 19194, + 19201, + 19208, + 19214, + 19225, + 19226, + 19235, + 19242, + 19264, + 19267, + 19293, + 19309, + 19318, + 19324, + 19337, + 19340, + 19345, + 19346, + 19352, + 19364, + 19382, + 19391, + 19405, + 19411, + 19439, + 19442, + 19444, + 19451, + 19465, + 19471, + 19474, + 19476, + 19479, + 19485, + 19489, + 19496, + 19507, + 19513, + 19514, + 19521, + 19524, + 19546, + 19552, + 19555, + 19557, + 19575, + 19579, + 19591, + 19595, + 19605, + 19615, + 19616, + 19626, + 19631, + 19634, + 19640, + 19645, + 19678, + 19681, + 19682, + 19706, + 19708, + 19713, + 19714, + 19720, + 19725, + 19743, + 19753, + 19756, + 19759, + 19762, + 19776, + 19786, + 19799, + 19800, + 19803, + 19806, + 19815, + 19816, + 19857, + 19860, + 19874, + 19883, + 19885, + 19886, + 19893, + 19932, + 19960, + 19972, + 19975, + 20005, + 20009, + 20010, + 20012, + 20023, + 20024, + 20030, + 20038, + 20041, + 20055, + 20059, + 20061, + 20080, + 20086, + 20089, + 20095, + 20111, + 20116, + 20130, + 20136, + 20147, + 20153, + 20156, + 20167, + 20173, + 20182, + 20185, + 20202, + 20209, + 20229, + 20233, + 20236, + 20241, + 20242, + 20248, + 20278, + 20282, + 20299, + 20307, + 20313, + 20314, + 20320, + 20326, + 20332, + 20350, + 20360, + 20371, + 20373, + 20377, + 20390, + 20396, + 20404, + 20413, + 20434, + 20436, + 20440, + 20443, + 20445, + 20464, + 20476, + 20494, + 20496, + 20501, + 20518, + 20527, + 20529, + 20535, + 20544, + 20568, + 20589, + 20592, + 20601, + 20617, + 20625, + 20626, + 20632, + 20638, + 20644, + 20647, + 20662, + 20671, + 20674, + 20683, + 20704, + 20724, + 20742, + 20748, + 20765, + 20776, + 20789, + 20796, + 20802, + 20807, + 20814, + 20821, + 20832, + 20835, + 20847, + 20859, + 20871, + 20883, + 20886, + 20892, + 20906, + 20908, + 20957, + 20962, + 20968, + 20979, + 20991, + 20998, + 21007, + 21010, + 21026, + 21037, + 21038, + 21045, + 21057, + 21082, + 21093, + 21094, + 21105, + 21117, + 21121, + 21124, + 21136, + 21139, + 21142, + 21145, + 21167, + 21170, + 21175, + 21179, + 21182, + 21193, + 21194, + 21207, + 21217, + 21224, + 21244, + 21247, + 21252, + 21264, + 21273, + 21289, + 21290, + 21295, + 21297, + 21309, + 21318, + 21322, + 21324, + 21329, + 21332, + 21336, + 21342, + 21351, + 21355, + 21363, + 21372, + 21382, + 21388, + 21394, + 21403, + 21409, + 21416, + 21421, + 21424, + 21444, + 21453, + 21466, + 21471, + 21495, + 21499, + 21504, + 21507, + 21521, + 21527, + 21555, + 21558, + 21562, + 21570, + 21576, + 21579, + 21581, + 21587, + 21590, + 21599, + 21605, + 21612, + 21618, + 21630, + 21639, + 21640, + 21643, + 21648, + 21669, + 21679, + 21681, + 21687, + 21688, + 21706, + 21713, + 21714, + 21716, + 21730, + 21732, + 21749, + 21756, + 21774, + 21779, + 21781, + 21786, + 21792, + 21810, + 21819, + 21829, + 21830, + 21844, + 21853, + 21867, + 21869, + 21882, + 21891, + 21898, + 21917, + 21934, + 21946, + 21948, + 21963, + 21966, + 21968, + 21973, + 21977, + 21980, + 21984, + 21994, + 21999, + 22018, + 22020, + 22029, + 22032, + 22041, + 22047, + 22048, + 22071, + 22075, + 22078, + 22083, + 22089, + 22097, + 22110, + 22113, + 22119, + 22120, + 22126, + 22133, + 22134, + 22140, + 22147, + 22161, + 22164, + 22173, + 22197, + 22207, + 22210, + 22216, + 22234, + 22257, + 22264, + 22278, + 22284, + 22287, + 22299, + 22301, + 22308, + 22337, + 22349, + 22350, + 22357, + 22364, + 22373, + 22377, + 22380, + 22386, + 22391, + 22392, + 22411, + 22422, + 22425, + 22431, + 22438, + 22441, + 22442, + 22449, + 22452, + 22461, + 22467, + 22479, + 22484, + 22487, + 22493, + 22510, + 22521, + 22533, + 22534, + 22543, + 22548, + 22552, + 22558, + 22561, + 22562, + 22568, + 22571, + 22574, + 22581, + 22594, + 22603, + 22605, + 22606, + 22623, + 22630, + 22651, + 22657, + 22669, + 22670, + 22677, + 22682, + 22698, + 22712, + 22715, + 22729, + 22732, + 22735, + 22738, + 22740, + 22750, + 22753, + 22760, + 22765, + 22768, + 22778, + 22785, + 22809, + 22810, + 22812, + 22828, + 22840, + 22845, + 22848, + 22857, + 22877, + 22882, + 22887, + 22894, + 22912, + 22930, + 22936, + 22939, + 22957, + 22970, + 22980, + 22984, + 22992, + 22998, + 23001, + 23044, + 23061, + 23062, + 23071, + 23075, + 23089, + 23090, + 23096, + 23101, + 23114, + 23121, + 23124, + 23127, + 23128, + 23137, + 23138, + 23150, + 23155, + 23168, + 23173, + 23174, + 23195, + 23202, + 23225, + 23226, + 23239, + 23253, + 23263, + 23264, + 23281, + 23282, + 23288, + 23294, + 23302, + 23311, + 23320, + 23325, + 23356, + 23374, + 23388, + 23402, + 23415, + 23421, + 23426, + 23443, + 23446, + 23455, + 23461, + 23468, + 23471, + 23485, + 23486, + 23488, + 23498, + 23500, + 23515, + 23521, + 23527, + 23534, + 23546, + 23559, + 23560, + 23566, + 23584, + 23587, + 23594, + 23602, + 23607, + 23616, + 23621, + 23631, + 23634, + 23636, + 23649, + 23652, + 23679, + 23686, + 23697, + 23703, + 23714, + 23719, + 23723, + 23726, + 23728, + 23733, + 23740, + 23751, + 23755, + 23765, + 23766, + 23769, + 23779, + 23794, + 23796, + 23803, + 23813, + 23820, + 23841, + 23853, + 23861, + 23862, + 23873, + 23876, + 23897, + 23898, + 23903, + 23904, + 23910, + 23931, + 23933, + 23934, + 23943, + 23952, + 23955, + 23962, + 23971, + 23978, + 23998, + 24003, + 24009, + 24017, + 24045, + 24046, + 24060, + 24064, + 24076, + 24079, + 24087, + 24094, + 24100, + 24118, + 24121, + 24132, + 24147, + 24165, + 24172, + 24177, + 24184, + 24187, + 24213, + 24217, + 24223, + 24230, + 24234, + 24241, + 24248, + 24259, + 24262, + 24271, + 24279, + 24286, + 24289, + 24295, + 24296, + 24299, + 24314, + 24336, + 24342, + 24346, + 24357, + 24367, + 24370, + 24372, + 24387, + 24389, + 24402, + 24414, + 24420, + 24435, + 24437, + 24442, + 24444, + 24447, + 24468, + 24475, + 24484, + 24493, + 24494, + 24496, + 24514, + 24519, + 24533, + 24538, + 24559, + 24568, + 24573, + 24577, + 24587, + 24592, + 24601, + 24602, + 24608, + 24645, + 24650, + 24657, + 24664, + 24670, + 24673, + 24676, + 24680, + 24686, + 24700, + 24704, + 24714, + 24728, + 24731, + 24733, + 24747, + 24749, + 24750, + 24764, + 24782, + 24784, + 24793, + 24794, + 24810, + 24817, + 24820, + 24823, + 24832, + 24855, + 24859, + 24862, + 24877, + 24890, + 24900, + 24904, + 24909, + 24910, + 24915, + 24922, + 24937, + 24945, + 24962, + 24964, + 24991, + 24992, + 24995, + 25001, + 25009, + 25019, + 25021, + 25029, + 25034, + 25036, + 25039, + 25057, + 25063, + 25064, + 25075, + 25077, + 25084, + 25088, + 25091, + 25105, + 25134, + 25165, + 25183, + 25184, + 25202, + 25204, + 25211, + 25223, + 25224, + 25235, + 25241, + 25253, + 25258, + 25277, + 25278, + 25280, + 25290, + 25295, + 25300, + 25307, + 25319, + 25323, + 25326, + 25333, + 25334, + 25337, + 25348, + 25351, + 25372, + 25381, + 25403, + 25406, + 25431, + 25437, + 25453, + 25459, + 25462, + 25466, + 25477, + 25484, + 25495, + 25501, + 25506, + 25511, + 25515, + 25525, + 25529, + 25532, + 25538, + 25549, + 25552, + 25564, + 25567, + 25574, + 25577, + 25583, + 25588, + 25603, + 25610, + 25615, + 25624, + 25636, + 25639, + 25643, + 25645, + 25648, + 25671, + 25678, + 25689, + 25708, + 25716, + 25725, + 25730, + 25739, + 25747, + 25753, + 25790, + 25797, + 25804, + 25809, + 25816, + 25825, + 25831, + 25845, + 25846, + 25867, + 25870, + 25897, + 25908, + 25937, + 25940, + 25944, + 25949, + 25954, + 25960, + 25963, + 25966, + 25978, + 25996, + 26007, + 26011, + 26027, + 26032, + 26038, + 26049, + 26052, + 26055, + 26085, + 26089, + 26090, + 26098, + 26104, + 26110, + 26113, + 26126, + 26133, + 26138, + 26140, + 26156, + 26159, + 26176, + 26186, + 26203, + 26210, + 26222, + 26224, + 26229, + 26233, + 26236, + 26239, + 26267, + 26291, + 26293, + 26298, + 26303, + 26308, + 26312, + 26315, + 26342, + 26354, + 26363, + 26365, + 26383, + 26391, + 26398, + 26416, + 26421, + 26425, + 26434, + 26439, + 26453, + 26454, + 26470, + 26491, + 26493, + 26500, + 26509, + 26518, + 26531, + 26533, + 26540, + 26552, + 26566, + 26569, + 26583, + 26590, + 26596, + 26624, + 26636, + 26667, + 26669, + 26672, + 26675, + 26687, + 26689, + 26696, + 26702, + 26714, + 26716, + 26729, + 26732, + 26737, + 26747, + 26773, + 26780, + 26801, + 26811, + 26813, + 26831, + 26836, + 26839, + 26849, + 26862, + 26869, + 26873, + 26874, + 26888, + 26891, + 26896, + 26899, + 26912, + 26921, + 26935, + 26941, + 26949, + 26954, + 26967, + 26977, + 27011, + 27018, + 27026, + 27028, + 27032, + 27044, + 27053, + 27062, + 27065, + 27068, + 27080, + 27083, + 27093, + 27098, + 27107, + 27110, + 27114, + 27121, + 27127, + 27137, + 27144, + 27155, + 27171, + 27178, + 27180, + 27185, + 27191, + 27192, + 27195, + 27212, + 27215, + 27218, + 27230, + 27234, + 27245, + 27248, + 27263, + 27279, + 27288, + 27294, + 27303, + 27304, + 27312, + 27330, + 27341, + 27342, + 27344, + 27353, + 27356, + 27366, + 27369, + 27377, + 27387, + 27409, + 27437, + 27443, + 27446, + 27450, + 27452, + 27457, + 27472, + 27475, + 27487, + 27488, + 27493, + 27506, + 27508, + 27521, + 27522, + 27527, + 27536, + 27539, + 27541, + 27546, + 27557, + 27564, + 27572, + 27576, + 27584, + 27608, + 27611, + 27618, + 27620, + 27627, + 27630, + 27637, + 27638, + 27641, + 27647, + 27650, + 27676, + 27683, + 27690, + 27695, + 27700, + 27704, + 27709, + 27715, + 27727, + 27745, + 27763, + 27769, + 27770, + 27796, + 27810, + 27812, + 27834, + 27847, + 27848, + 27862, + 27868, + 27881, + 27884, + 27890, + 27895, + 27904, + 27914, + 27919, + 27921, + 27931, + 27933, + 27938, + 27943, + 27949, + 28005, + 28012, + 28017, + 28024, + 28030, + 28034, + 28045, + 28048, + 28054, + 28063, + 28069, + 28070, + 28073, + 28084, + 28096, + 28114, + 28126, + 28141, + 28149, + 28165, + 28177, + 28189, + 28190, + 28203, + 28206, + 28208, + 28220, + 28226, + 28231, + 28249, + 28256, + 28259, + 28265, + 28266, + 28271, + 28274, + 28280, + 28296, + 28316, + 28319, + 28343, + 28344, + 28357, + 28358, + 28364, + 28370, + 28372, + 28379, + 28388, + 28392, + 28395, + 28406, + 28418, + 28423, + 28435, + 28444, + 28454, + 28468, + 28477, + 28478, + 28480, + 28486, + 28489, + 28500, + 28507, + 28519, + 28523, + 28534, + 28547, + 28549, + 28562, + 28571, + 28583, + 28584, + 28595, + 28597, + 28604, + 28607, + 28609, + 28612, + 28630, + 28640, + 28669, + 28677, + 28682, + 28690, + 28695, + 28696, + 28717, + 28730, + 28737, + 28752, + 28761, + 28774, + 28783, + 28791, + 28801, + 28802, + 28814, + 28837, + 28838, + 28842, + 28844, + 28849, + 28864, + 28867, + 28881, + 28882, + 28893, + 28903, + 28907, + 28909, + 28921, + 28927, + 28929, + 28935, + 28941, + 28942, + 28954, + 28959, + 28960, + 28990, + 28992, + 29004, + 29010, + 29012, + 29021, + 29035, + 29040, + 29059, + 29068, + 29080, + 29086, + 29089, + 29090, + 29095, + 29113, + 29127, + 29131, + 29148, + 29161, + 29172, + 29179, + 29188, + 29192, + 29195, + 29206, + 29210, + 29215, + 29221, + 29222, + 29236, + 29246, + 29248, + 29253, + 29272, + 29288, + 29293, + 29294, + 29308, + 29318, + 29321, + 29322, + 29339, + 29365, + 29369, + 29372, + 29377, + 29392, + 29401, + 29402, + 29418, + 29437, + 29445, + 29446, + 29460, + 29467, + 29473, + 29476, + 29488, + 29511, + 29512, + 29517, + 29523, + 29526, + 29535, + 29539, + 29545, + 29559, + 29560, + 29589, + 29593, + 29599, + 29603, + 29610, + 29629, + 29644, + 29656, + 29662, + 29675, + 29692, + 29704, + 29707, + 29715, + 29717, + 29722, + 29731, + 29740, + 29743, + 29752, + 29760, + 29766, + 29770, + 29794, + 29796, + 29814, + 29817, + 29829, + 29841, + 29851, + 29860, + 29864, + 29869, + 29870, + 29889, + 29896, + 29901, + 29913, + 29919, + 29920, + 29947, + 29958, + 29975, + 29981, + 29985, + 29998, + 30010, + 30012, + 30044, + 30048, + 30051, + 30063, + 30065, + 30072, + 30077, + 30087, + 30088, + 30101, + 30112, + 30121, + 30122, + 30130, + 30135, + 30139, + 30142, + 30164, + 30167, + 30180, + 30202, + 30211, + 30214, + 30217, + 30223, + 30228, + 30235, + 30256, + 30265, + 30286, + 30293, + 30298, + 30310, + 30314, + 30327, + 30333, + 30334, + 30337, + 30338, + 30344, + 30349, + 30352, + 30362, + 30374, + 30380, + 30388, + 30391, + 30395, + 30403, + 30409, + 30424, + 30427, + 30430, + 30451, + 30460, + 30475, + 30480, + 30485, + 30486, + 30489, + 30492, + 30499, + 30511, + 30533, + 30534, + 30540, + 30545, + 30552, + 30557, + 30558, + 30567, + 30568, + 30581, + 30597, + 30607, + 30621, + 30632, + 30650, + 30655, + 30657, + 30660, + 30669, + 30675, + 30678, + 30682, + 30687, + 30688, + 30698, + 30711, + 30728, + 30733, + 30741, + 30746, + 30752, + 30764, + 30769, + 30784, + 30796, + 30799, + 30804, + 30811, + 30814, + 30818, + 30827, + 30838, + 30842, + 30854, + 30863, + 30865, + 30877, + 30881, + 30887, + 30908, + 30916, + 30919, + 30925, + 30928, + 30944, + 30947, + 30950, + 30968, + 30971, + 30973, + 30976, + 30986, + 30993, + 30994, + 31012, + 31016, + 31029, + 31039, + 31041, + 31042, + 31044, + 31053, + 31059, + 31062, + 31077, + 31095, + 31101, + 31105, + 31118, + 31129, + 31132, + 31141, + 31159, + 31183, + 31185, + 31195, + 31202, + 31213, + 31238, + 31241, + 31252, + 31262, + 31265, + 31295, + 31300, + 31303, + 31317, + 31318, + 31324, + 31338, + 31340, + 31345, + 31355, + 31362, + 31371, + 31373, + 31381, + 31391, + 31409, + 31410, + 31412, + 31434, + 31458, + 31467, + 31470, + 31475, + 31481, + 31482, + 31484, + 31492, + 31507, + 31514, + 31538, + 31547, + 31549, + 31555, + 31557, + 31597, + 31598, + 31610, + 31625, + 31634, + 31643, + 31645, + 31659, + 31669, + 31670, + 31682, + 31694, + 31717, + 31718, + 31729, + 31736, + 31742, + 31749, + 31773, + 31777, + 31778, + 31784, + 31801, + 31812, + 31821, + 31822, + 31836, + 31850, + 31855, + 31858, + 31860, + 31886, + 31891, + 31909, + 31928, + 31931, + 31934, + 31941, + 31942, + 31945, + 31951, + 31959, + 31963, + 31970, + 31984, + 31987, + 31990, + 32001, + 32007, + 32008, + 32025, + 32035, + 32038, + 32047, + 32049, + 32062, + 32067, + 32070, + 32073, + 32074, + 32079, + 32081, + 32082, + 32107, + 32127, + 32145, + 32151, + 32152, + 32173, + 32174, + 32186, + 32194, + 32196, + 32200, + 32208, + 32218, + 32236, + 32260, + 32263, + 32288, + 32298, + 32315, + 32332, + 32340, + 32354, + 32359, + 32366, + 32368, + 32377, + 32384, + 32399, + 32417, + 32424, + 32427, + 32429, + 32438, + 32442, + 32447, + 32469, + 32479, + 32483, + 32498, + 32503, + 32507, + 32521, + 32532, + 32539, + 32551, + 32572, + 32577, + 32578, + 32587, + 32592, + 32602, + 32604, + 32613, + 32625, + 32631, + 32641, + 32642, + 32644, + 32656, + 32678, + 32681, + 32701, + 32713, + 32721, + 32727, + 32731, + 32734, + 32740, + 32773, + 32774, + 32785, + 32788, + 32792, + 32797, + 32801, + 32811, + 32821, + 32828, + 32839, + 32854, + 32867, + 32870, + 32873, + 32881, + 32891, + 32900, + 32903, + 32910, + 32917, + 32922, + 32928, + 32945, + 32946, + 32951, + 32958, + 32965, + 32978, + 32980, + 32983, + 32987, + 33023, + 33031, + 33032, + 33035, + 33038, + 33040, + 33043, + 33050, + 33059, + 33080, + 33098, + 33108, + 33115, + 33117, + 33133, + 33134, + 33157, + 33169, + 33170, + 33176, + 33182, + 33192, + 33205, + 33212, + 33215, + 33217, + 33227, + 33229, + 33238, + 33241, + 33260, + 33271, + 33278, + 33293, + 33294, + 33296, + 33302, + 33305, + 33329, + 33330, + 33332, + 33354, + 33383, + 33387, + 33397, + 33408, + 33417, + 33420, + 33423, + 33431, + 33438, + 33442, + 33444, + 33448, + 33456, + 33459, + 33466, + 33473, + 33476, + 33491, + 33494, + 33507, + 33514, + 33521, + 33528, + 33534, + 33536, + 33551, + 33554, + 33563, + 33575, + 33579, + 33582, + 33601, + 33602, + 33614, + 33625, + 33628, + 33637, + 33656, + 33665, + 33683, + 33695, + 33696, + 33702, + 33708, + 33711, + 33716, + 33728, + 33737, + 33761, + 33774, + 33782, + 33788, + 33791, + 33793, + 33811, + 33813, + 33818, + 33829, + 33842, + 33854, + 33856, + 33868, + 33879, + 33885, + 33886, + 33892, + 33907, + 33913, + 33923, + 33925, + 33935, + 33937, + 33954, + 33963, + 33966, + 33977, + 33978, + 33991, + 33998, + 34012, + 34016, + 34025, + 34033, + 34036, + 34045, + 34065, + 34078, + 34093, + 34101, + 34108, + 34111, + 34120, + 34123, + 34125, + 34153, + 34171, + 34174, + 34178, + 34183, + 34190, + 34201, + 34211, + 34220, + 34225, + 34237, + 34249, + 34250, + 34264, + 34269, + 34276, + 34279, + 34293, + 34303, + 34310, + 34340, + 34349, + 34352, + 34355, + 34358, + 34362, + 34376, + 34381, + 34387, + 34389, + 34394, + 34410, + 34423, + 34434, + 34436, + 34448, + 34453, + 34454, + 34460, + 34464, + 34479, + 34491, + 34501, + 34508, + 34516, + 34529, + 34530, + 34553, + 34564, + 34568, + 34571, + 34582, + 34586, + 34598, + 34604, + 34610, + 34619, + 34621, + 34633, + 34634, + 34657, + 34682, + 34688, + 34691, + 34694, + 34706, + 34708, + 34724, + 34727, + 34751, + 34753, + 34759, + 34763, + 34777, + 34778, + 34780, + 34796, + 34799, + 34801, + 34817, + 34824, + 34827, + 34837, + 34841, + 34853, + 34858, + 34877, + 34886, + 34895, + 34897, + 34898, + 34916, + 34923, + 34928, + 34934, + 34940, + 34944, + 34947, + 34953, + 34956, + 34967, + 34968, + 34971, + 34974, + 34977, + 34980, + 34983, + 34998, + 35004, + 35010, + 35012, + 35030, + 35039, + 35058, + 35063, + 35082, + 35095, + 35096, + 35101, + 35102, + 35105, + 35112, + 35118, + 35120, + 35130, + 35143, + 35147, + 35152, + 35157, + 35164, + 35178, + 35195, + 35197, + 35201, + 35207, + 35231, + 35249, + 35250, + 35256, + 35259, + 35262, + 35273, + 35282, + 35298, + 35307, + 35328, + 35334, + 35343, + 35345, + 35355, + 35388, + 35399, + 35403, + 35408, + 35413, + 35418, + 35434, + 35436, + 35448, + 35460, + 35475, + 35494, + 35497, + 35503, + 35508, + 35511, + 35518, + 35520, + 35530, + 35537, + 35543, + 35560, + 35566, + 35571, + 35598, + 35609, + 35612, + 35615, + 35616, + 35622, + 35626, + 35633, + 35636, + 35645, + 35653, + 35663, + 35665, + 35682, + 35687, + 35688, + 35691, + 35696, + 35727, + 35741, + 35742, + 35746, + 35748, + 35752, + 35770, + 35811, + 35817, + 35832, + 35838, + 35850, + 35863, + 35870, + 35879, + 35880, + 35891, + 35893, + 35903, + 35905, + 35926, + 35930, + 35941, + 35956, + 35963, + 35970, + 35984, + 35996, + 36005, + 36012, + 36015, + 36030, + 36035, + 36042, + 36047, + 36049, + 36059, + 36071, + 36080, + 36085, + 36097, + 36110, + 36115, + 36118, + 36124, + 36137, + 36138, + 36155, + 36160, + 36189, + 36190, + 36203, + 36211, + 36218, + 36230, + 36241, + 36244, + 36253, + 36257, + 36264, + 36272, + 36290, + 36292, + 36301, + 36309, + 36313, + 36316, + 36319, + 36330, + 36335, + 36347, + 36353, + 36356, + 36368, + 36374, + 36377, + 36384, + 36407, + 36413, + 36419, + 36425, + 36426, + 36446, + 36461, + 36467, + 36474, + 36480, + 36486, + 36489, + 36495, + 36525, + 36526, + 36533, + 36534, + 36540, + 36555, + 36563, + 36565, + 36588, + 36593, + 36596, + 36606, + 36614, + 36626, + 36628, + 36641, + 36642, + 36651, + 36653, + 36673, + 36676, + 36679, + 36694, + 36698, + 36704, + 36714, + 36721, + 36722, + 36727, + 36749, + 36758, + 36761, + 36771, + 36788, + 36797, + 36805, + 36830, + 36833, + 36839, + 36843, + 36860, + 36866, + 36871, + 36875, + 36877, + 36880, + 36892, + 36911, + 36914, + 36916, + 36923, + 36940, + 36943, + 36948, + 36957, + 36958, + 36967, + 36974, + 36981, + 37001, + 37012, + 37015, + 37019, + 37035, + 37040, + 37063, + 37064, + 37069, + 37077, + 37093, + 37097, + 37106, + 37115, + 37118, + 37123, + 37129, + 37130, + 37135, + 37137, + 37138, + 37140, + 37144, + 37149, + 37156, + 37159, + 37163, + 37165, + 37183, + 37185, + 37195, + 37198, + 37203, + 37212, + 37233, + 37236, + 37240, + 37256, + 37264, + 37267, + 37273, + 37295, + 37315, + 37330, + 37336, + 37339, + 37342, + 37357, + 37365, + 37372, + 37381, + 37399, + 37416, + 37429, + 37436, + 37442, + 37451, + 37453, + 37475, + 37482, + 37489, + 37490, + 37523, + 37525, + 37530, + 37535, + 37539, + 37548, + 37559, + 37560, + 37566, + 37597, + 37601, + 37602, + 37604, + 37616, + 37622, + 37658, + 37660, + 37667, + 37684, + 37693, + 37694, + 37696, + 37706, + 37711, + 37730, + 37735, + 37742, + 37744, + 37759, + 37777, + 37783, + 37784, + 37793, + 37800, + 37818, + 37823, + 37825, + 37828, + 37832, + 37849, + 37856, + 37861, + 37862, + 37886, + 37893, + 37915, + 37922, + 37936, + 37939, + 37945, + 37956, + 37960, + 37971, + 37980, + 38002, + 38007, + 38018, + 38020, + 38038, + 38041, + 38044, + 38048, + 38051, + 38054, + 38065, + 38066, + 38077, + 38090, + 38109, + 38119, + 38120, + 38123, + 38146, + 38155, + 38160, + 38181, + 38188, + 38199, + 38203, + 38225, + 38226, + 38231, + 38244, + 38248, + 38259, + 38268, + 38271, + 38272, + 38278, + 38292, + 38296, + 38318, + 38326, + 38338, + 38347, + 38373, + 38378, + 38380, + 38388, + 38392, + 38397, + 38398, + 38401, + 38404, + 38422, + 38432, + 38469, + 38482, + 38493, + 38507, + 38518, + 38521, + 38527, + 38533, + 38534, + 38552, + 38561, + 38576, + 38581, + 38585, + 38594, + 38606, + 38613, + 38617, + 38634, + 38644, + 38651, + 38661, + 38665, + 38668, + 38674, + 38689, + 38695, + 38696, + 38707, + 38710, + 38716, + 38733, + 38736, + 38742, + 38751, + 38752, + 38775, + 38779, + 38792, + 38798, + 38819, + 38822, + 38839, + 38851, + 38854, + 38863, + 38865, + 38887, + 38896, + 38901, + 38912, + 38918, + 38929, + 38941, + 38948, + 38965, + 38969, + 38977, + 38987, + 38992, + 38995, + 39001, + 39004, + 39011, + 39018, + 39025, + 39031, + 39032, + 39044, + 39056, + 39065, + 39066, + 39084, + 39095, + 39099, + 39101, + 39102, + 39104, + 39109, + 39114, + 39121, + 39122, + 39127, + 39150, + 39172, + 39181, + 39184, + 39193, + 39199, + 39200, + 39206, + 39209, + 39235, + 39238, + 39242, + 39244, + 39280, + 39290, + 39292, + 39296, + 39305, + 39308, + 39311, + 39326, + 39329, + 39330, + 39336, + 39339, + 39353, + 39359, + 39374, + 39391, + 39392, + 39402, + 39409, + 39410, + 39415, + 39419, + 39431, + 39432, + 39438, + 39443, + 39445, + 39449, + 39461, + 39462, + 39485, + 39508, + 39515, + 39522, + 39533, + 39541, + 39542, + 39557, + 39570, + 39575, + 39576, + 39591, + 39597, + 39603, + 39610, + 39612, + 39617, + 39620, + 39624, + 39627, + 39635, + 39641, + 39666, + 39668, + 39686, + 39692, + 39700, + 39709, + 39726, + 39728, + 39737, + 39738, + 39755, + 39757, + 39758, + 39765, + 39766, + 39769, + 39779, + 39785, + 39794, + 39796, + 39809, + 39815, + 39829, + 39834, + 39839, + 39850, + 39857, + 39881, + 39905, + 39912, + 39938, + 39940, + 39944, + 39955, + 39961, + 39977, + 39980, + 39986, + 39988, + 39991, + 39998, + 40003, + 40005, + 40023, + 40024, + 40045, + 40046, + 40058, + 40088, + 40091, + 40098, + 40109, + 40112, + 40124, + 40130, + 40153, + 40166, + 40175, + 40183, + 40184, + 40207, + 40215, + 40225, + 40235, + 40240, + 40255, + 40263, + 40270, + 40277, + 40282, + 40297, + 40306, + 40315, + 40333, + 40334, + 40336, + 40342, + 40345, + 40348, + 40355, + 40372, + 40381, + 40390, + 40407, + 40435, + 40437, + 40441, + 40444, + 40458, + 40460, + 40481, + 40484, + 40487, + 40493, + 40494, + 40501, + 40502, + 40525, + 40550, + 40553, + 40559, + 40562, + 40573, + 40574, + 40578, + 40583, + 40584, + 40587, + 40597, + 40620, + 40623, + 40631, + 40643, + 40660, + 40667, + 40676, + 40693, + 40697, + 40708, + 40718, + 40726, + 40735, + 40739, + 40748, + 40760, + 40763, + 40773, + 40774, + 40786, + 40791, + 40798, + 40801, + 40808, + 40811, + 40813, + 40825, + 40831, + 40835, + 40856, + 40861, + 40880, + 40889, + 40912, + 40918, + 40924, + 40927, + 40928, + 40938, + 40952, + 40957, + 40961, + 40968, + 40974, + 40986, + 40992, + 41001, + 41004, + 41022, + 41033, + 41036, + 41039, + 41044, + 41064, + 41078, + 41091, + 41103, + 41108, + 41112, + 41127, + 41128, + 41136, + 41141, + 41146, + 41156, + 41159, + 41163, + 41165, + 41166, + 41184, + 41193, + 41202, + 41211, + 41216, + 41239, + 41243, + 41249, + 41262, + 41267, + 41276, + 41279, + 41305, + 41306, + 41312, + 41317, + 41321, + 41332, + 41335, + 41345, + 41346, + 41351, + 41365, + 41388, + 41399, + 41405, + 41414, + 41432, + 41454, + 41461, + 41462, + 41471, + 41478, + 41490, + 41506, + 41508, + 41512, + 41517, + 41520, + 41529, + 41530, + 41544, + 41550, + 41571, + 41577, + 41580, + 41595, + 41613, + 41622, + 41635, + 41642, + 41661, + 41676, + 41681, + 41684, + 41687, + 41688, + 41694, + 41698, + 41710, + 41712, + 41721, + 41722, + 41729, + 41744, + 41747, + 41753, + 41766, + 41783, + 41790, + 41810, + 41819, + 41825, + 41828, + 41843, + 41846, + 41862, + 41871, + 41874, + 41876, + 41892, + 41899, + 41916, + 41928, + 41957, + 41964, + 41969, + 41981, + 41996, + 41999, + 42001, + 42017, + 42023, + 42027, + 42032, + 42035, + 42044, + 42050, + 42061, + 42062, + 42073, + 42098, + 42104, + 42109, + 42120, + 42125, + 42131, + 42143, + 42153, + 42176, + 42182, + 42188, + 42203, + 42216, + 42219, + 42227, + 42234, + 42251, + 42254, + 42256, + 42259, + 42282, + 42289, + 42302, + 42307, + 42310, + 42322, + 42328, + 42338, + 42349, + 42367, + 42386, + 42398, + 42404, + 42413, + 42419, + 42421, + 42422, + 42431, + 42445, + 42448, + 42451, + 42454, + 42458, + 42470, + 42476, + 42500, + 42509, + 42538, + 42543, + 42545, + 42546, + 42563, + 42570, + 42580, + 42584, + 42589, + 42608, + 42618, + 42629, + 42636, + 42639, + 42644, + 42647, + 42651, + 42654, + 42658, + 42669, + 42678, + 42689, + 42695, + 42696, + 42710, + 42716, + 42730, + 42732, + 42747, + 42750, + 42752, + 42761, + 42772, + 42776, + 42779, + 42797, + 42815, + 42824, + 42837, + 42844, + 42868, + 42877, + 42888, + 42891, + 42912, + 42918, + 42921, + 42927, + 42949, + 42953, + 42967, + 42974, + 42989, + 42995, + 42997, + 43007, + 43018, + 43025, + 43031, + 43032, + 43038, + 43041, + 43054, + 43074, + 43085, + 43097, + 43098, + 43110, + 43119, + 43131, + 43143, + 43144, + 43152, + 43157, + 43178, + 43180, + 43192, + 43197, + 43203, + 43220, + 43236, + 43245, + 43246, + 43260, + 43265, + 43271, + 43285, + 43286, + 43290, + 43299, + 43314, + 43323, + 43337, + 43348, + 43355, + 43357, + 43358, + 43361, + 43362, + 43364, + 43368, + 43376, + 43385, + 43386, + 43391, + 43397, + 43431, + 43438, + 43440, + 43452, + 43463, + 43470, + 43478, + 43481, + 43488, + 43491, + 43506, + 43512, + 43539, + 43567, + 43579, + 43584, + 43601, + 43614, + 43617, + 43623, + 43630, + 43647, + 43658, + 43663, + 43665, + 43691, + 43701, + 43705, + 43708, + 43719, + 43731, + 43737, + 43740, + 43747, + 43749, + 43750, + 43754, + 43764, + 43767, + 43768, + 43773, + 43785, + 43788, + 43810, + 43819, + 43834, + 43853, + 43866, + 43871, + 43872, + 43881, + 43889, + 43902, + 43926, + 43935, + 43946, + 43951, + 43953, + 43971, + 44008, + 44011, + 44026, + 44033, + 44048, + 44057, + 44058, + 44067, + 44081, + 44087, + 44099, + 44105, + 44106, + 44114, + 44116, + 44130, + 44139, + 44141, + 44153, + 44159, + 44160, + 44170, + 44172, + 44187, + 44190, + 44193, + 44199, + 44213, + 44218, + 44223, + 44235, + 44243, + 44262, + 44283, + 44291, + 44293, + 44308, + 44327, + 44341, + 44346, + 44348, + 44354, + 44366, + 44368, + 44373, + 44384, + 44390, + 44393, + 44394, + 44399, + 44401, + 44408, + 44411, + 44417, + 44420, + 44424, + 44444, + 44451, + 44453, + 44466, + 44472, + 44475, + 44486, + 44500, + 44510, + 44531, + 44534, + 44553, + 44559, + 44564, + 44580, + 44583, + 44589, + 44592, + 44609, + 44627, + 44633, + 44643, + 44646, + 44650, + 44674, + 44676, + 44680, + 44683, + 44703, + 44704, + 44716, + 44733, + 44748, + 44759, + 44763, + 44781, + 44782, + 44789, + 44794, + 44799, + 44804, + 44813, + 44822, + 44838, + 44842, + 44849, + 44856, + 44870, + 44887, + 44904, + 44915, + 44917, + 44921, + 44928, + 44933, + 44934, + 44937, + 44940, + 44951, + 44961, + 44962, + 44971, + 44982, + 44985, + 44996, + 44999, + 45014, + 45029, + 45033, + 45036, + 45047, + 45065, + 45076, + 45085, + 45086, + 45090, + 45107, + 45119, + 45121, + 45128, + 45139, + 45151, + 45157, + 45162, + 45164, + 45176, + 45179, + 45198, + 45209, + 45231, + 45234, + 45236, + 45251, + 45260, + 45268, + 45277, + 45299, + 45301, + 45338, + 45344, + 45349, + 45364, + 45367, + 45371, + 45373, + 45376, + 45381, + 45400, + 45406, + 45416, + 45422, + 45427, + 45440, + 45458, + 45467, + 45474, + 45476, + 45488, + 45494, + 45497, + 45500, + 45512, + 45515, + 45523, + 45542, + 45553, + 45559, + 45589, + 45594, + 45596, + 45603, + 45605, + 45610, + 45630, + 45638, + 45641, + 45647, + 45655, + 45659, + 45665, + 45689, + 45695, + 45702, + 45708, + 45726, + 45729, + 45739, + 45744, + 45747, + 45762, + 45764, + 45773, + 45774, + 45781, + 45785, + 45792, + 45801, + 45802, + 45812, + 45816, + 45829, + 45833, + 45847, + 45851, + 45854, + 45863, + 45870, + 45901, + 45910, + 45920, + 45932, + 45938, + 45940, + 45943, + 45949, + 45953, + 45963, + 45971, + 45989, + 45999, + 46001, + 46008, + 46022, + 46026, + 46034, + 46040, + 46043, + 46045, + 46061, + 46062, + 46076, + 46084, + 46094, + 46102, + 46118, + 46149, + 46154, + 46167, + 46173, + 46177, + 46192, + 46197, + 46201, + 46214, + 46217, + 46223, + 46226, + 46228, + 46237, + 46241, + 46251, + 46259, + 46262, + 46266, + 46294, + 46300, + 46303, + 46309, + 46321, + 46331, + 46339, + 46342, + 46354, + 46370, + 46372, + 46379, + 46382, + 46393, + 46402, + 46407, + 46416, + 46425, + 46437, + 46444, + 46447, + 46449, + 46456, + 46462, + 46472, + 46475, + 46486, + 46490, + 46495, + 46501, + 46514, + 46526, + 46528, + 46538, + 46551, + 46552, + 46564, + 46579, + 46586, + 46602, + 46615, + 46616, + 46621, + 46635, + 46643, + 46645, + 46649, + 46667, + 46670, + 46672, + 46678, + 46681, + 46684, + 46687, + 46705, + 46708, + 46721, + 46724, + 46739, + 46757, + 46762, + 46764, + 46776, + 46784, + 46790, + 46796, + 46799, + 46802, + 46813, + 46814, + 46824, + 46832, + 46841, + 46856, + 46862, + 46864, + 46869, + 46874, + 46895, + 46900, + 46903, + 46927, + 46946, + 46948, + 46955, + 46965, + 46972, + 46976, + 46985, + 46999, + 47003, + 47006, + 47016, + 47030, + 47034, + 47053, + 47056, + 47059, + 47072, + 47077, + 47099, + 47105, + 47108, + 47112, + 47115, + 47117, + 47120, + 47129, + 47135, + 47151, + 47154, + 47156, + 47166, + 47171, + 47195, + 47204, + 47213, + 47222, + 47228, + 47241, + 47242, + 47247, + 47249, + 47250, + 47261, + 47266, + 47268, + 47278, + 47286, + 47312, + 47315, + 47321, + 47322, + 47324, + 47331, + 47338, + 47366, + 47372, + 47375, + 47378, + 47387, + 47389, + 47390, + 47396, + 47400, + 47405, + 47408, + 47411, + 47431, + 47443, + 47459, + 47466, + 47479, + 47480, + 47495, + 47504, + 47519, + 47520, + 47530, + 47537, + 47555, + 47558, + 47567, + 47569, + 47572, + 47582, + 47591, + 47595, + 47598, + 47609, + 47612, + 47616, + 47625, + 47640, + 47649, + 47655, + 47661, + 47688, + 47711, + 47717, + 47721, + 47724, + 47727, + 47730, + 47739, + 47745, + 47752, + 47758, + 47765, + 47770, + 47782, + 47786, + 47791, + 47793, + 47796, + 47814, + 47823, + 47826, + 47837, + 47854, + 47856, + 47871, + 47879, + 47880, + 47885, + 47886, + 47903, + 47907, + 47913, + 47916, + 47928, + 47936, + 47945, + 47948, + 47956, + 47965, + 47970, + 47972, + 47981, + 47987, + 48010, + 48012, + 48023, + 48033, + 48051, + 48071, + 48075, + 48077, + 48080, + 48099, + 48106, + 48114, + 48120, + 48128, + 48145, + 48152, + 48155, + 48182, + 48188, + 48203, + 48217, + 48218, + 48236, + 48241, + 48244, + 48264, + 48269, + 48278, + 48282, + 48288, + 48311, + 48315, + 48317, + 48329, + 48330, + 48337, + 48350, + 48353, + 48360, + 48374, + 48380, + 48405, + 48406, + 48409, + 48412, + 48416, + 48419, + 48425, + 48434, + 48443, + 48445, + 48453, + 48454, + 48482, + 48491, + 48501, + 48517, + 48518, + 48545, + 48548, + 48552, + 48569, + 48575, + 48580, + 48584, + 48590, + 48595, + 48602, + 48604, + 48618, + 48625, + 48626, + 48638, + 48668, + 48677, + 48678, + 48687, + 48692, + 48696, + 48704, + 48707, + 48714, + 48731, + 48740, + 48750, + 48761, + 48785, + 48786, + 48798, + 48807, + 48808, + 48814, + 48826, + 48828, + 48834, + 48840, + 48845, + 48858, + 48864, + 48869, + 48870, + 48879, + 48887, + 48899, + 48911, + 48920, + 48926, + 48929, + 48971, + 48974, + 48981, + 48998, + 49007, + 49028, + 49031, + 49056, + 49065, + 49079, + 49083, + 49088, + 49093, + 49100, + 49103, + 49124, + 49136, + 49139, + 49142, + 49145, + 49146, + 49171, + 49187, + 49190, + 49194, + 49196, + 49207, + 49216, + 49219, + 49222, + 49240, + 49250, + 49262, + 49276, + 49289, + 49292, + 49298, + 49319, + 49320, + 49325, + 49333, + 49340, + 49343, + 49352, + 49363, + 49375, + 49391, + 49405, + 49413, + 49420, + 49425, + 49431, + 49432, + 49441, + 49456, + 49476, + 49479, + 49504, + 49514, + 49528, + 49543, + 49544, + 49550, + 49558, + 49568, + 49578, + 49600, + 49612, + 49633, + 49634, + 49636, + 49643, + 49654, + 49657, + 49663, + 49667, + 49693, + 49700, + 49703, + 49712, + 49717, + 49718, + 49721, + 49727, + 49730, + 49735, + 49739, + 49747, + 49765, + 49770, + 49772, + 49777, + 49789, + 49817, + 49829, + 49839, + 49844, + 49851, + 49854, + 49874, + 49883, + 49886, + 49892, + 49895, + 49914, + 49931, + 49933, + 49934, + 49941, + 49952, + 49967, + 49969, + 49972, + 49976, + 49979, + 49999, + 50008, + 50030, + 50041, + 50042, + 50044, + 50057, + 50060, + 50075, + 50077, + 50091, + 50096, + 50099, + 50106, + 50116, + 50133, + 50144, + 50153, + 50154, + 50168, + 50179, + 50188, + 50194, + 50203, + 50212, + 50216, + 50222, + 50229, + 50230, + 50234, + 50251, + 50253, + 50262, + 50266, + 50272, + 50287, + 50295, + 50305, + 50306, + 50311, + 50320, + 50323, + 50325, + 50339, + 50356, + 50365, + 50366, + 50368, + 50377, + 50386, + 50397, + 50411, + 50414, + 50425, + 50451, + 50463, + 50467, + 50473, + 50487, + 50501, + 50505, + 50514, + 50516, + 50536, + 50547, + 50566, + 50572, + 50583, + 50593, + 50599, + 50613, + 50617, + 50618, + 50620, + 50628, + 50638, + 50652, + 50655, + 50662, + 50665, + 50673, + 50683, + 50689, + 50690, + 50692, + 50696, + 50704, + 50713, + 50719, + 50738, + 50757, + 50761, + 50764, + 50770, + 50776, + 50803, + 50805, + 50806, + 50816, + 50826, + 50840, + 50845, + 50852, + 50855, + 50862, + 50876, + 50879, + 50882, + 50894, + 50899, + 50905, + 50924, + 50936, + 50944, + 50973, + 50974, + 51002, + 51007, + 51009, + 51029, + 51036, + 51063, + 51067, + 51070, + 51074, + 51079, + 51083, + 51093, + 51094, + 51124, + 51131, + 51151, + 51153, + 51156, + 51165, + 51175, + 51184, + 51187, + 51203, + 51220, + 51224, + 51233, + 51234, + 51239, + 51246, + 51248, + 51251, + 51257, + 51266, + 51280, + 51285, + 51286, + 51289, + 51295, + 51296, + 51311, + 51329, + 51350, + 51356, + 51363, + 51365, + 51370, + 51372, + 51377, + 51383, + 51384, + 51397, + 51407, + 51422, + 51435, + 51440, + 51446, + 51463, + 51467, + 51491, + 51493, + 51494, + 51508, + 51518, + 51520, + 51526, + 51529, + 51530, + 51537, + 51547, + 51559, + 51565, + 51568, + 51580, + 51583, + 51584, + 51593, + 51594, + 51607, + 51608, + 51620, + 51624, + 51642, + 51649, + 51652, + 51659, + 51661, + 51670, + 51674, + 51698, + 51707, + 51725, + 51737, + 51753, + 51754, + 51779, + 51791, + 51796, + 51809, + 51816, + 51819, + 51827, + 51829, + 51834, + 51836, + 51846, + 51849, + 51855, + 51858, + 51869, + 51870, + 51874, + 51918, + 51926, + 51932, + 51936, + 51948, + 51954, + 51959, + 51971, + 51983, + 51992, + 51997, + 52016, + 52021, + 52031, + 52033, + 52034, + 52048, + 52053, + 52057, + 52067, + 52076, + 52079, + 52081, + 52109, + 52127, + 52128, + 52133, + 52148, + 52155, + 52157, + 52172, + 52178, + 52184, + 52199, + 52200, + 52205, + 52206, + 52232, + 52237, + 52243, + 52246, + 52252, + 52261, + 52265, + 52266, + 52273, + 52274, + 52288, + 52300, + 52303, + 52321, + 52322, + 52328, + 52333, + 52351, + 52357, + 52372, + 52381, + 52386, + 52395, + 52403, + 52423, + 52427, + 52432, + 52438, + 52444, + 52457, + 52468, + 52480, + 52498, + 52516, + 52520, + 52525, + 52531, + 52540, + 52545, + 52546, + 52552, + 52557, + 52569, + 52575, + 52582, + 52594, + 52615, + 52619, + 52624, + 52645, + 52663, + 52664, + 52675, + 52687, + 52696, + 52701, + 52706, + 52708, + 52711, + 52726, + 52748, + 52754, + 52756, + 52759, + 52769, + 52784, + 52790, + 52804, + 52807, + 52808, + 52819, + 52826, + 52828, + 52832, + 52835, + 52849, + 52859, + 52877, + 52880, + 52896, + 52899, + 52905, + 52913, + 52933, + 52934, + 52938, + 52957, + 52979, + 52981, + 52986, + 53005, + 53008, + 53024, + 53029, + 53054, + 53073, + 53083, + 53086, + 53095, + 53102, + 53107, + 53126, + 53130, + 53138, + 53144, + 53156, + 53163, + 53165, + 53173, + 53177, + 53183, + 53192, + 53195, + 53200, + 53212, + 53219, + 53221, + 53245, + 53254, + 53257, + 53265, + 53266, + 53268, + 53275, + 53277, + 53284, + 53294, + 53308, + 53314, + 53319, + 53326, + 53328, + 53340, + 53364, + 53367, + 53377, + 53395, + 53398, + 53407, + 53413, + 53414, + 53417, + 53443, + 53473, + 53476, + 53480, + 53486, + 53506, + 53542, + 53546, + 53554, + 53563, + 53580, + 53591, + 53598, + 53611, + 53621, + 53625, + 53628, + 53632, + 53650, + 53655, + 53675, + 53677, + 53680, + 53683, + 53700, + 53709, + 53724, + 53731, + 53733, + 53738, + 53762, + 53767, + 53785, + 53786, + 53795, + 53802, + 53812, + 53821, + 53827, + 53833, + 53841, + 53848, + 53869, + 53897, + 53905, + 53912, + 53921, + 53928, + 53948, + 53954, + 53968, + 53977, + 53983, + 53984, + 54002, + 54007, + 54013, + 54014, + 54021, + 54026, + 54028, + 54031, + 54036, + 54067, + 54069, + 54074, + 54076, + 54105, + 54111, + 54118, + 54129, + 54145, + 54157, + 54158, + 54163, + 54166, + 54172, + 54185, + 54186, + 54188, + 54208, + 54223, + 54237, + 54241, + 54244, + 54259, + 54273, + 54276, + 54280, + 54294, + 54298, + 54303, + 54304, + 54309, + 54310, + 54316, + 54336, + 54354, + 54359, + 54375, + 54376, + 54381, + 54390, + 54396, + 54399, + 54409, + 54424, + 54434, + 54436, + 54439, + 54445, + 54448, + 54457, + 54465, + 54471, + 54472, + 54485, + 54508, + 54513, + 54528, + 54534, + 54537, + 54540, + 54551, + 54561, + 54573, + 54579, + 54586, + 54591, + 54596, + 54599, + 54605, + 54613, + 54623, + 54654, + 54667, + 54681, + 54684, + 54687, + 54694, + 54706, + 54712, + 54715, + 54723, + 54725, + 54726, + 54740, + 54750, + 54760, + 54768, + 54771, + 54773, + 54796, + 54801, + 54808, + 54814, + 54837, + 54847, + 54849, + 54864, + 54867, + 54889, + 54895, + 54907, + 54919, + 54923, + 54926, + 54940, + 54950, + 54954, + 54961, + 54973, + 54974, + 54976, + 54986, + 54993, + 55000, + 55010, + 55019, + 55021, + 55030, + 55033, + 55039, + 55047, + 55048, + 55054, + 55059, + 55068, + 55071, + 55075, + 55077, + 55081, + 55095, + 55099, + 55110, + 55116, + 55122, + 55134, + 55144, + 55147, + 55158, + 55162, + 55171, + 55185, + 55192, + 55197, + 55207, + 55228, + 55246, + 55253, + 55254, + 55281, + 55300, + 55303, + 55307, + 55312, + 55328, + 55331, + 55337, + 55348, + 55352, + 55357, + 55372, + 55375, + 55377, + 55394, + 55406, + 55424, + 55429, + 55430, + 55436, + 55439, + 55447, + 55453, + 55458, + 55460, + 55478, + 55489, + 55501, + 55502, + 55519, + 55525, + 55530, + 55544, + 55550, + 55558, + 55561, + 55569, + 55586, + 55591, + 55598, + 55605, + 55609, + 55618, + 55630, + 55642, + 55644, + 55653, + 55654, + 55660, + 55671, + 55693, + 55706, + 55712, + 55718, + 55739, + 55747, + 55754, + 55771, + 55774, + 55780, + 55783, + 55784, + 55789, + 55798, + 55802, + 55823, + 55828, + 55837, + 55838, + 55847, + 55848, + 55885, + 55897, + 55904, + 55910, + 55919, + 55922, + 55931, + 55933, + 55937, + 55943, + 55955, + 55957, + 55968, + 55980, + 55986, + 55992, + 56005, + 56034, + 56051, + 56054, + 56065, + 56080, + 56101, + 56113, + 56126, + 56131, + 56134, + 56143, + 56148, + 56152, + 56174, + 56181, + 56182, + 56185, + 56192, + 56201, + 56215, + 56219, + 56222, + 56258, + 56264, + 56269, + 56272, + 56278, + 56282, + 56306, + 56308, + 56318, + 56329, + 56356, + 56360, + 56383, + 56388, + 56391, + 56405, + 56406, + 56416, + 56426, + 56439, + 56446, + 56450, + 56459, + 56461, + 56464, + 56469, + 56489, + 56490, + 56497, + 56509, + 56515, + 56518, + 56524, + 56535, + 56542, + 56545, + 56551, + 56555, + 56560, + 56569, + 56580, + 56584, + 56598, + 56601, + 56602, + 56623, + 56637, + 56638, + 56643, + 56650, + 56673, + 56676, + 56686, + 56704, + 56710, + 56721, + 56731, + 56738, + 56747, + 56750, + 56752, + 56757, + 56787, + 56796, + 56803, + 56812, + 56815, + 56824, + 56829, + 56833, + 56839, + 56840, + 56845, + 56853, + 56854, + 56858, + 56863, + 56864, + 56881, + 56882, + 56896, + 56901, + 56902, + 56908, + 56923, + 56925, + 56926, + 56932, + 56939, + 56947, + 56954, + 56970, + 56972, + 56977, + 56980, + 56993, + 57013, + 57017, + 57018, + 57031, + 57059, + 57062, + 57065, + 57071, + 57083, + 57093, + 57097, + 57106, + 57118, + 57133, + 57134, + 57141, + 57146, + 57156, + 57174, + 57183, + 57189, + 57190, + 57193, + 57196, + 57207, + 57211, + 57214, + 57218, + 57230, + 57235, + 57241, + 57251, + 57260, + 57263, + 57265, + 57271, + 57272, + 57290, + 57295, + 57298, + 57325, + 57328, + 57340, + 57344, + 57353, + 57368, + 57371, + 57383, + 57402, + 57407, + 57419, + 57424, + 57433, + 57452, + 57458, + 57467, + 57470, + 57473, + 57479, + 57480, + 57486, + 57491, + 57493, + 57524, + 57528, + 57534, + 57542, + 57560, + 57565, + 57570, + 57579, + 57590, + 57601, + 57604, + 57607, + 57621, + 57635, + 57642, + 57650, + 57655, + 57670, + 57676, + 57682, + 57687, + 57691, + 57700, + 57704, + 57707, + 57721, + 57731, + 57733, + 57738, + 57745, + 57748, + 57751, + 57757, + 57761, + 57774, + 57779, + 57786, + 57808, + 57814, + 57817, + 57824, + 57827, + 57848, + 57853, + 57857, + 57858, + 57867, + 57872, + 57887, + 57894, + 57915, + 57920, + 57923, + 57932, + 57937, + 57943, + 57950, + 57960, + 57971, + 57974, + 57983, + 57987, + 57994, + 58001, + 58002, + 58013, + 58023, + 58027, + 58029, + 58032, + 58041, + 58047, + 58062, + 58086, + 58092, + 58095, + 58097, + 58100, + 58117, + 58121, + 58132, + 58142, + 58145, + 58152, + 58155, + 58163, + 58166, + 58170, + 58175, + 58184, + 58197, + 58202, + 58204, + 58208, + 58213, + 58220, + 58226, + 58231, + 58235, + 58254, + 58261, + 58271, + 58278, + 58287, + 58327, + 58333, + 58337, + 58357, + 58362, + 58364, + 58375, + 58384, + 58387, + 58405, + 58406, + 58417, + 58424, + 58435, + 58450, + 58452, + 58459, + 58461, + 58466, + 58468, + 58485, + 58489, + 58492, + 58495, + 58505, + 58523, + 58535, + 58536, + 58549, + 58550, + 58561, + 58562, + 58573, + 58576, + 58592, + 58601, + 58622, + 58627, + 58629, + 58634, + 58639, + 58641, + 58644, + 58654, + 58663, + 58667, + 58677, + 58682, + 58690, + 58692, + 58695, + 58710, + 58713, + 58723, + 58740, + 58749, + 58760, + 58766, + 58773, + 58780, + 58787, + 58796, + 58816, + 58822, + 58831, + 58839, + 58849, + 58859, + 58870, + 58879, + 58889, + 58904, + 58914, + 58923, + 58940, + 58945, + 58952, + 58960, + 58965, + 58986, + 59000, + 59006, + 59027, + 59034, + 59052, + 59058, + 59081, + 59082, + 59089, + 59096, + 59118, + 59123, + 59126, + 59132, + 59135, + 59150, + 59174, + 59177, + 59185, + 59195, + 59203, + 59206, + 59234, + 59248, + 59258, + 59260, + 59270, + 59284, + 59291, + 59293, + 59297, + 59312, + 59315, + 59327, + 59332, + 59347, + 59354, + 59363, + 59369, + 59377, + 59406, + 59413, + 59423, + 59434, + 59441, + 59442, + 59456, + 59465, + 59479, + 59501, + 59504, + 59507, + 59514, + 59523, + 59525, + 59526, + 59537, + 59543, + 59560, + 59563, + 59566, + 59577, + 59580, + 59586, + 59597, + 59612, + 59615, + 59622, + 59631, + 59657, + 59660, + 59665, + 59671, + 59675, + 59688, + 59706, + 59708, + 59713, + 59714, + 59720, + 59737, + 59743, + 59744, + 59749, + 59756, + 59783, + 59784, + 59787, + 59795, + 59804, + 59811, + 59814, + 59823, + 59838, + 59840, + 59846, + 59849, + 59855, + 59860, + 59867, + 59869, + 59885, + 59888, + 59893, + 59904, + 59919, + 59922, + 59927, + 59937, + 59940, + 59944, + 59947, + 59949, + 59961, + 59975, + 59981, + 59994, + 59999, + 60018, + 60023, + 60024, + 60039, + 60043, + 60048, + 60054, + 60073, + 60079, + 60082, + 60102, + 60108, + 60111, + 60120, + 60149, + 60153, + 60161, + 60168, + 60176, + 60182, + 60185, + 60204, + 60212, + 60215, + 60219, + 60222, + 60229, + 60234, + 60241, + 60248, + 60277, + 60282, + 60287, + 60303, + 60306, + 60327, + 60333, + 60334, + 60336, + 60345, + 60359, + 60368, + 60380, + 60389, + 60390, + 60394, + 60407, + 60414, + 60419, + 60426, + 60428, + 60431, + 60440, + 60450, + 60469, + 60473, + 60474, + 60484, + 60496, + 60502, + 60508, + 60511, + 60522, + 60529, + 60530, + 60536, + 60551, + 60557, + 60566, + 60576, + 60579, + 60585, + 60588, + 60600, + 60613, + 60628, + 60631, + 60648, + 60651, + 60653, + 60671, + 60673, + 60691, + 60697, + 60700, + 60714, + 60724, + 60728, + 60733, + 60736, + 60745, + 60746, + 60753, + 60754, + 60782, + 60784, + 60790, + 60793, + 60805, + 60830, + 60836, + 60846, + 60851, + 60880, + 60896, + 60905, + 60923, + 60925, + 60932, + 60939, + 60942, + 60953, + 60956, + 60959, + 60963, + 60969, + 60978, + 60980, + 60987, + 61007, + 61012, + 61015, + 61025, + 61026, + 61038, + 61040, + 61052, + 61061, + 61074, + 61083, + 61085, + 61086, + 61096, + 61119, + 61124, + 61127, + 61128, + 61133, + 61134, + 61146, + 61155, + 61161, + 61162, + 61169, + 61179, + 61182, + 61190, + 61201, + 61208, + 61238, + 61241, + 61247, + 61259, + 61267, + 61269, + 61295, + 61304, + 61309, + 61310, + 61313, + 61320, + 61325, + 61334, + 61337, + 61386, + 61399, + 61422, + 61429, + 61436, + 61439, + 61466, + 61477, + 61478, + 61490, + 61495, + 61504, + 61514, + 61516, + 61521, + 61527, + 61531, + 61540, + 61550, + 61557, + 61562, + 61577, + 61583, + 61597, + 61602, + 61604, + 61607, + 61622, + 61625, + 61633, + 61640, + 61643, + 61651, + 61658, + 61670, + 61674, + 61676, + 61679, + 61688, + 61693, + 61701, + 61711, + 61714, + 61723, + 61725, + 61726, + 61729, + 61741, + 61761, + 61779, + 61781, + 61782, + 61797, + 61809, + 61810, + 61816, + 61822, + 61849, + 61876, + 61893, + 61905, + 61908, + 61911, + 61912, + 61928, + 61934, + 61957, + 61961, + 61969, + 61979, + 61982, + 62003, + 62006, + 62010, + 62015, + 62020, + 62024, + 62029, + 62032, + 62035, + 62038, + 62047, + 62068, + 62071, + 62082, + 62088, + 62096, + 62108, + 62124, + 62142, + 62147, + 62153, + 62159, + 62161, + 62171, + 62189, + 62207, + 62227, + 62230, + 62234, + 62236, + 62239, + 62257, + 62270, + 62278, + 62287, + 62295, + 62301, + 62306, + 62312, + 62317, + 62330, + 62342, + 62359, + 62365, + 62366, + 62370, + 62375, + 62376, + 62387, + 62404, + 62411, + 62435, + 62441, + 62442, + 62452, + 62459, + 62461, + 62473, + 62474, + 62493, + 62510, + 62518, + 62524, + 62549, + 62556, + 62565, + 62566, + 62580, + 62584, + 62589, + 62596, + 62608, + 62636, + 62642, + 62651, + 62654, + 62659, + 62666, + 62680, + 62692, + 62701, + 62702, + 62714, + 62716, + 62733, + 62762, + 62769, + 62770, + 62787, + 62794, + 62801, + 62807, + 62808, + 62813, + 62817, + 62818, + 62832, + 62841, + 62857, + 62860, + 62871, + 62882, + 62888, + 62913, + 62919, + 62920, + 62925, + 62933, + 62938, + 62940, + 62949, + 62956, + 62971, + 62978, + 62990, + 62995, + 62997, + 63004, + 63011, + 63032, + 63038, + 63067, + 63069, + 63076, + 63083, + 63088, + 63094, + 63097, + 63100, + 63104, + 63114, + 63116, + 63122, + 63128, + 63149, + 63150, + 63157, + 63167, + 63187, + 63200, + 63220, + 63223, + 63229, + 63235, + 63247, + 63252, + 63255, + 63289, + 63298, + 63303, + 63327, + 63328, + 63348, + 63355, + 63357, + 63368, + 63391, + 63402, + 63409, + 63416, + 63419, + 63430, + 63442, + 63457, + 63458, + 63482, + 63487, + 63488, + 63500, + 63511, + 63517, + 63528, + 63531, + 63559, + 63566, + 63578, + 63580, + 63584, + 63587, + 63594, + 63607, + 63611, + 63630, + 63632, + 63641, + 63647, + 63651, + 63666, + 63668, + 63695, + 63697, + 63709, + 63723, + 63737, + 63746, + 63752, + 63755, + 63775, + 63781, + 63794, + 63796, + 63808, + 63817, + 63820, + 63826, + 63838, + 63848, + 63861, + 63862, + 63866, + 63878, + 63889, + 63892, + 63901, + 63915, + 63917, + 63926, + 63932, + 63937, + 63938, + 63943, + 63944, + 63950, + 63952, + 63955, + 63957, + 63961, + 63962, + 63978, + 63983, + 63988, + 64008, + 64013, + 64019, + 64026, + 64028, + 64032, + 64042, + 64044, + 64055, + 64070, + 64079, + 64084, + 64087, + 64093, + 64100, + 64104, + 64109, + 64140, + 64148, + 64151, + 64152, + 64171, + 64179, + 64186, + 64203, + 64206, + 64213, + 64214, + 64220, + 64233, + 64239, + 64248, + 64251, + 64259, + 64268, + 64273, + 64279, + 64283, + 64292, + 64296, + 64301, + 64302, + 64324, + 64331, + 64346, + 64364, + 64382, + 64386, + 64400, + 64409, + 64419, + 64433, + 64454, + 64458, + 64482, + 64494, + 64496, + 64505, + 64514, + 64519, + 64525, + 64528, + 64534, + 64561, + 64571, + 64579, + 64591, + 64606, + 64616, + 64619, + 64640, + 64645, + 64649, + 64652, + 64670, + 64673, + 64674, + 64683, + 64697, + 64703, + 64711, + 64723, + 64736, + 64739, + 64741, + 64748, + 64759, + 64768, + 64771, + 64778, + 64792, + 64821, + 64831, + 64839, + 64848, + 64860, + 64867, + 64870, + 64874, + 64879, + 64887, + 64894, + 64897, + 64898, + 64921, + 64933, + 64940, + 64957, + 64969, + 64972, + 64978, + 64984, + 64993, + 64999, + 65000, + 65006, + 65011, + 65014, + 65036, + 65044, + 65063, + 65067, + 65075, + 65077, + 65082, + 65095, + 65101, + 65104, + 65109, + 65110, + 65116, + 65126, + 65129, + 65138, + 65160, + 65171, + 65173, + 65180, + 65189, + 65193, + 65208, + 65214, + 65216, + 65225, + 65236, + 65239, + 65273, + 65274, + 65281, + 65294, + 65324, + 65335, + 65354, + 65359, + 65373, + 65383, + 65387, + 65397, + 65411, + 65413, + 65418, + 65441, + 65444, + 65447, + 65448, + 65473, + 65476, + 65480, + 65494, + 65509, + 65519, + 65527, + -1 + }; + //#endif + + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_17 + static long[] PrimitivePolynomialDegree18 = + { + 19, + 31, + 38, + 61, + 64, + 109, + 115, + 118, + 131, + 167, + 200, + 241, + 244, + 247, + 261, + 265, + 304, + 314, + 341, + 376, + 395, + 405, + 406, + 443, + 451, + 458, + 460, + 468, + 472, + 482, + 491, + 496, + 524, + 536, + 542, + 557, + 572, + 580, + 592, + 656, + 713, + 719, + 738, + 749, + 752, + 767, + 772, + 782, + 789, + 830, + 838, + 916, + 920, + 936, + 991, + 998, + 1016, + 1024, + 1053, + 1081, + 1090, + 1125, + 1135, + 1143, + 1150, + 1154, + 1171, + 1174, + 1202, + 1213, + 1225, + 1233, + 1234, + 1252, + 1255, + 1294, + 1349, + 1354, + 1378, + 1383, + 1387, + 1392, + 1402, + 1420, + 1428, + 1437, + 1448, + 1459, + 1473, + 1507, + 1516, + 1528, + 1573, + 1592, + 1597, + 1654, + 1663, + 1730, + 1739, + 1741, + 1753, + 1783, + 1804, + 1807, + 1832, + 1850, + 1852, + 1881, + 1894, + 1927, + 1952, + 1969, + 1999, + 2018, + 2047, + 2066, + 2068, + 2093, + 2105, + 2116, + 2149, + 2201, + 2228, + 2245, + 2246, + 2283, + 2288, + 2320, + 2326, + 2386, + 2392, + 2395, + 2413, + 2419, + 2441, + 2466, + 2477, + 2485, + 2492, + 2495, + 2498, + 2504, + 2515, + 2521, + 2561, + 2579, + 2604, + 2657, + 2681, + 2691, + 2731, + 2739, + 2765, + 2790, + 2802, + 2819, + 2891, + 2905, + 2911, + 2912, + 2921, + 2924, + 2945, + 2952, + 2972, + 2986, + 3000, + 3008, + 3011, + 3018, + 3047, + 3071, + 3079, + 3083, + 3086, + 3148, + 3156, + 3194, + 3230, + 3233, + 3254, + 3268, + 3305, + 3323, + 3326, + 3343, + 3345, + 3382, + 3413, + 3420, + 3434, + 3453, + 3472, + 3488, + 3503, + 3506, + 3518, + 3532, + 3543, + 3547, + 3573, + 3574, + 3587, + 3632, + 3664, + 3713, + 3726, + 3768, + 3771, + 3810, + 3848, + 3868, + 3896, + 3910, + 3921, + 3928, + 3940, + 3947, + 3949, + 4001, + 4004, + 4022, + 4026, + 4036, + 4073, + 4093, + 4099, + 4120, + 4136, + 4156, + 4176, + 4182, + 4191, + 4198, + 4252, + 4259, + 4261, + 4294, + 4341, + 4348, + 4356, + 4384, + 4389, + 4401, + 4428, + 4431, + 4445, + 4470, + 4473, + 4474, + 4490, + 4509, + 4510, + 4533, + 4548, + 4558, + 4594, + 4596, + 4603, + 4610, + 4619, + 4630, + 4652, + 4658, + 4682, + 4708, + 4736, + 4753, + 4760, + 4781, + 4784, + 4799, + 4807, + 4808, + 4842, + 4882, + 4897, + 4900, + 4922, + 4936, + 4960, + 4970, + 4978, + 4994, + 5003, + 5044, + 5061, + 5107, + 5127, + 5131, + 5136, + 5145, + 5146, + 5175, + 5218, + 5223, + 5248, + 5294, + 5299, + 5301, + 5311, + 5343, + 5344, + 5396, + 5406, + 5410, + 5424, + 5447, + 5461, + 5468, + 5475, + 5478, + 5523, + 5530, + 5535, + 5548, + 5559, + 5580, + 5604, + 5622, + 5641, + 5649, + 5656, + 5671, + 5689, + 5721, + 5731, + 5734, + 5738, + 5740, + 5748, + 5791, + 5801, + 5807, + 5822, + 5829, + 5834, + 5847, + 5854, + 5878, + 5882, + 5919, + 5947, + 5981, + 5982, + 6025, + 6028, + 6039, + 6056, + 6064, + 6073, + 6081, + 6088, + 6101, + 6139, + 6142, + 6194, + 6199, + 6200, + 6203, + 6214, + 6238, + 6241, + 6244, + 6248, + 6256, + 6266, + 6271, + 6275, + 6295, + 6315, + 6364, + 6368, + 6377, + 6400, + 6430, + 6477, + 6480, + 6490, + 6526, + 6539, + 6556, + 6584, + 6598, + 6601, + 6609, + 6612, + 6645, + 6655, + 6679, + 6683, + 6719, + 6727, + 6734, + 6770, + 6776, + 6791, + 6798, + 6800, + 6826, + 6833, + 6836, + 6858, + 6882, + 6901, + 6923, + 6967, + 6979, + 7022, + 7060, + 7064, + 7083, + 7093, + 7094, + 7120, + 7125, + 7142, + 7151, + 7165, + 7173, + 7188, + 7191, + 7202, + 7216, + 7219, + 7267, + 7358, + 7383, + 7387, + 7396, + 7408, + 7432, + 7462, + 7480, + 7488, + 7497, + 7531, + 7561, + 7582, + 7591, + 7612, + 7677, + 7687, + 7701, + 7705, + 7712, + 7721, + 7736, + 7756, + 7777, + 7783, + 7792, + 7797, + 7802, + 7808, + 7866, + 7885, + 7891, + 7913, + 7936, + 7946, + 7963, + 7996, + 7999, + 8011, + 8014, + 8028, + 8047, + 8077, + 8101, + 8119, + 8125, + 8140, + 8152, + 8209, + 8212, + 8231, + 8258, + 8275, + 8303, + 8308, + 8312, + 8345, + 8346, + 8370, + 8402, + 8411, + 8414, + 8424, + 8435, + 8452, + 8462, + 8479, + 8509, + 8515, + 8522, + 8541, + 8560, + 8563, + 8585, + 8594, + 8596, + 8603, + 8610, + 8647, + 8661, + 8662, + 8672, + 8690, + 8696, + 8739, + 8783, + 8811, + 8813, + 8821, + 8856, + 8877, + 8885, + 8897, + 8898, + 8934, + 8955, + 8972, + 8977, + 9038, + 9045, + 9071, + 9085, + 9110, + 9120, + 9157, + 9164, + 9185, + 9203, + 9235, + 9278, + 9290, + 9292, + 9319, + 9334, + 9362, + 9387, + 9404, + 9407, + 9410, + 9422, + 9478, + 9512, + 9535, + 9604, + 9616, + 9622, + 9631, + 9656, + 9710, + 9721, + 9728, + 9733, + 9738, + 9774, + 9791, + 9803, + 9805, + 9817, + 9823, + 9839, + 9847, + 9854, + 9863, + 9872, + 9884, + 9935, + 9937, + 9974, + 9980, + 10003, + 10015, + 10016, + 10066, + 10093, + 10118, + 10132, + 10135, + 10151, + 10158, + 10169, + 10172, + 10180, + 10187, + 10189, + 10192, + 10197, + 10211, + 10214, + 10256, + 10278, + 10290, + 10301, + 10310, + 10344, + 10473, + 10474, + 10482, + 10499, + 10525, + 10532, + 10535, + 10556, + 10568, + 10579, + 10586, + 10609, + 10612, + 10650, + 10665, + 10685, + 10686, + 10688, + 10711, + 10728, + 10748, + 10751, + 10781, + 10805, + 10823, + 10838, + 10857, + 10865, + 10872, + 10893, + 10899, + 10917, + 10935, + 11001, + 11072, + 11089, + 11090, + 11108, + 11117, + 11136, + 11148, + 11153, + 11181, + 11190, + 11201, + 11204, + 11216, + 11237, + 11259, + 11279, + 11282, + 11304, + 11312, + 11332, + 11341, + 11354, + 11356, + 11365, + 11377, + 11417, + 11427, + 11433, + 11434, + 11439, + 11444, + 11448, + 11461, + 11466, + 11468, + 11473, + 11489, + 11499, + 11516, + 11531, + 11533, + 11557, + 11572, + 11608, + 11635, + 11638, + 11644, + 11684, + 11702, + 11740, + 11749, + 11754, + 11764, + 11767, + 11784, + 11789, + 11795, + 11798, + 11804, + 11818, + 11820, + 11860, + 11869, + 11874, + 11903, + 11916, + 11927, + 11933, + 11962, + 12009, + 12020, + 12035, + 12041, + 12049, + 12065, + 12072, + 12098, + 12100, + 12107, + 12167, + 12202, + 12207, + 12233, + 12269, + 12290, + 12304, + 12314, + 12340, + 12416, + 12425, + 12428, + 12446, + 12462, + 12476, + 12496, + 12511, + 12518, + 12530, + 12532, + 12539, + 12567, + 12597, + 12601, + 12602, + 12622, + 12693, + 12707, + 12713, + 12716, + 12734, + 12763, + 12765, + 12799, + 12843, + 12853, + 12865, + 12866, + 12919, + 12926, + 12936, + 12944, + 12959, + 12965, + 12980, + 13004, + 13016, + 13019, + 13037, + 13055, + 13063, + 13098, + 13103, + 13106, + 13115, + 13143, + 13144, + 13153, + 13171, + 13184, + 13193, + 13199, + 13207, + 13217, + 13227, + 13232, + 13276, + 13283, + 13307, + 13317, + 13330, + 13345, + 13363, + 13387, + 13426, + 13428, + 13431, + 13489, + 13501, + 13533, + 13589, + 13600, + 13603, + 13623, + 13665, + 13672, + 13675, + 13708, + 13713, + 13720, + 13730, + 13735, + 13767, + 13773, + 13792, + 13843, + 13891, + 13946, + 13967, + 13976, + 14017, + 14030, + 14041, + 14054, + 14058, + 14060, + 14063, + 14078, + 14080, + 14089, + 14131, + 14134, + 14137, + 14188, + 14215, + 14222, + 14249, + 14292, + 14320, + 14339, + 14346, + 14353, + 14365, + 14384, + 14414, + 14428, + 14435, + 14483, + 14486, + 14506, + 14513, + 14520, + 14526, + 14528, + 14533, + 14576, + 14599, + 14613, + 14639, + 14644, + 14653, + 14662, + 14695, + 14704, + 14713, + 14725, + 14783, + 14810, + 14816, + 14822, + 14828, + 14883, + 14889, + 14904, + 14917, + 14927, + 14941, + 14946, + 14952, + 15010, + 15012, + 15033, + 15041, + 15047, + 15066, + 15068, + 15072, + 15095, + 15150, + 15152, + 15175, + 15176, + 15210, + 15245, + 15258, + 15263, + 15264, + 15279, + 15301, + 15306, + 15313, + 15329, + 15341, + 15367, + 15368, + 15386, + 15404, + 15422, + 15436, + 15444, + 15467, + 15498, + 15503, + 15528, + 15534, + 15536, + 15559, + 15565, + 15583, + 15599, + 15602, + 15616, + 15626, + 15667, + 15684, + 15711, + 15745, + 15763, + 15779, + 15811, + 15814, + 15817, + 15853, + 15881, + 15890, + 15899, + 15905, + 15915, + 15937, + 15950, + 16002, + 16041, + 16042, + 16052, + 16121, + 16132, + 16136, + 16150, + 16153, + 16180, + 16190, + 16192, + 16195, + 16210, + 16225, + 16256, + 16266, + 16274, + 16302, + 16310, + 16322, + 16339, + 16345, + 16348, + 16357, + 16382, + 16402, + 16461, + 16469, + 16474, + 16483, + 16497, + 16523, + 16534, + 16550, + 16564, + 16582, + 16591, + 16609, + 16642, + 16648, + 16656, + 16662, + 16665, + 16678, + 16701, + 16713, + 16716, + 16758, + 16768, + 16797, + 16804, + 16811, + 16813, + 16881, + 16888, + 16893, + 16922, + 16937, + 16958, + 16965, + 16978, + 16980, + 16989, + 17011, + 17014, + 17023, + 17063, + 17081, + 17084, + 17099, + 17126, + 17129, + 17138, + 17164, + 17170, + 17203, + 17206, + 17224, + 17305, + 17322, + 17327, + 17332, + 17342, + 17387, + 17410, + 17419, + 17429, + 17439, + 17440, + 17457, + 17458, + 17469, + 17477, + 17512, + 17518, + 17532, + 17536, + 17559, + 17569, + 17641, + 17667, + 17674, + 17693, + 17710, + 17729, + 17754, + 17763, + 17780, + 17784, + 17790, + 17830, + 17851, + 17868, + 17879, + 17896, + 17901, + 17916, + 17935, + 17953, + 17991, + 18009, + 18016, + 18034, + 18061, + 18070, + 18079, + 18132, + 18145, + 18169, + 18170, + 18190, + 18192, + 18201, + 18228, + 18243, + 18260, + 18279, + 18285, + 18297, + 18300, + 18321, + 18344, + 18358, + 18364, + 18376, + 18390, + 18399, + 18400, + 18427, + 18443, + 18487, + 18493, + 18508, + 18532, + 18535, + 18580, + 18587, + 18606, + 18659, + 18662, + 18679, + 18694, + 18697, + 18706, + 18708, + 18728, + 18731, + 18733, + 18751, + 18766, + 18773, + 18796, + 18811, + 18823, + 18832, + 18854, + 18858, + 18883, + 18900, + 18967, + 18974, + 18990, + 19009, + 19055, + 19058, + 19074, + 19079, + 19086, + 19128, + 19145, + 19163, + 19175, + 19189, + 19196, + 19204, + 19213, + 19237, + 19276, + 19287, + 19291, + 19293, + 19304, + 19371, + 19379, + 19381, + 19405, + 19417, + 19420, + 19424, + 19462, + 19474, + 19492, + 19501, + 19504, + 19516, + 19519, + 19534, + 19555, + 19597, + 19600, + 19615, + 19621, + 19646, + 19651, + 19693, + 19702, + 19726, + 19754, + 19759, + 19764, + 19788, + 19793, + 19836, + 19855, + 19858, + 19880, + 19883, + 19917, + 19918, + 19936, + 19946, + 19954, + 19979, + 19993, + 19994, + 20006, + 20017, + 20032, + 20038, + 20050, + 20080, + 20135, + 20142, + 20159, + 20173, + 20186, + 20229, + 20234, + 20263, + 20270, + 20299, + 20304, + 20319, + 20329, + 20337, + 20353, + 20401, + 20434, + 20436, + 20473, + 20488, + 20512, + 20515, + 20517, + 20530, + 20571, + 20574, + 20589, + 20592, + 20611, + 20613, + 20628, + 20637, + 20638, + 20719, + 20724, + 20772, + 20796, + 20799, + 20816, + 20841, + 20844, + 20862, + 20865, + 20902, + 20938, + 20957, + 20971, + 20973, + 20981, + 20982, + 20985, + 20991, + 21012, + 21022, + 21026, + 21028, + 21050, + 21075, + 21077, + 21078, + 21106, + 21122, + 21127, + 21155, + 21167, + 21169, + 21204, + 21230, + 21256, + 21285, + 21312, + 21329, + 21351, + 21372, + 21376, + 21424, + 21448, + 21465, + 21495, + 21509, + 21550, + 21562, + 21575, + 21579, + 21582, + 21600, + 21615, + 21617, + 21624, + 21633, + 21636, + 21645, + 21654, + 21660, + 21667, + 21702, + 21714, + 21719, + 21736, + 21767, + 21781, + 21795, + 21841, + 21853, + 21867, + 21878, + 21891, + 21897, + 21954, + 21956, + 21965, + 21977, + 21978, + 21983, + 22002, + 22013, + 22014, + 22054, + 22058, + 22066, + 22085, + 22103, + 22138, + 22140, + 22153, + 22164, + 22167, + 22189, + 22202, + 22212, + 22234, + 22239, + 22245, + 22272, + 22308, + 22318, + 22320, + 22338, + 22350, + 22374, + 22388, + 22391, + 22422, + 22426, + 22441, + 22481, + 22488, + 22500, + 22517, + 22531, + 22552, + 22574, + 22579, + 22582, + 22586, + 22594, + 22611, + 22614, + 22700, + 22711, + 22749, + 22759, + 22774, + 22777, + 22780, + 22783, + 22785, + 22840, + 22878, + 22884, + 22888, + 22927, + 22941, + 22951, + 22958, + 22980, + 23007, + 23032, + 23041, + 23044, + 23059, + 23065, + 23072, + 23137, + 23144, + 23155, + 23162, + 23167, + 23183, + 23192, + 23197, + 23216, + 23221, + 23228, + 23233, + 23234, + 23251, + 23257, + 23258, + 23288, + 23302, + 23341, + 23373, + 23402, + 23409, + 23428, + 23435, + 23440, + 23449, + 23459, + 23473, + 23500, + 23511, + 23548, + 23560, + 23563, + 23594, + 23601, + 23625, + 23640, + 23650, + 23662, + 23692, + 23726, + 23738, + 23743, + 23755, + 23760, + 23799, + 23848, + 23859, + 23876, + 23897, + 23907, + 23919, + 23921, + 23931, + 23933, + 23943, + 23957, + 23986, + 24020, + 24043, + 24064, + 24082, + 24084, + 24088, + 24117, + 24149, + 24165, + 24223, + 24247, + 24259, + 24283, + 24296, + 24336, + 24342, + 24389, + 24394, + 24414, + 24424, + 24441, + 24491, + 24502, + 24534, + 24540, + 24543, + 24549, + 24567, + 24583, + 24693, + 24704, + 24719, + 24749, + 24799, + 24830, + 24835, + 24907, + 24917, + 24940, + 24943, + 24958, + 24962, + 24964, + 24968, + 25015, + 25024, + 25027, + 25033, + 25041, + 25047, + 25057, + 25082, + 25093, + 25105, + 25112, + 25117, + 25131, + 25139, + 25194, + 25204, + 25244, + 25247, + 25253, + 25258, + 25275, + 25320, + 25338, + 25343, + 25351, + 25358, + 25372, + 25399, + 25408, + 25432, + 25442, + 25462, + 25465, + 25468, + 25482, + 25489, + 25490, + 25505, + 25511, + 25512, + 25552, + 25555, + 25595, + 25636, + 25672, + 25685, + 25696, + 25720, + 25730, + 25735, + 25753, + 25756, + 25769, + 25821, + 25825, + 25840, + 25860, + 25869, + 25872, + 25956, + 25973, + 25994, + 26002, + 26020, + 26023, + 26041, + 26044, + 26069, + 26097, + 26113, + 26138, + 26167, + 26216, + 26230, + 26243, + 26245, + 26263, + 26264, + 26269, + 26311, + 26346, + 26354, + 26365, + 26368, + 26398, + 26401, + 26426, + 26436, + 26443, + 26448, + 26458, + 26464, + 26476, + 26503, + 26504, + 26515, + 26531, + 26548, + 26570, + 26589, + 26594, + 26608, + 26623, + 26678, + 26690, + 26709, + 26725, + 26744, + 26763, + 26765, + 26768, + 26784, + 26802, + 26814, + 26856, + 26861, + 26862, + 26894, + 26908, + 26915, + 26929, + 26930, + 26939, + 26941, + 26987, + 27023, + 27066, + 27079, + 27086, + 27091, + 27113, + 27157, + 27174, + 27188, + 27191, + 27197, + 27206, + 27210, + 27245, + 27254, + 27383, + 27387, + 27416, + 27422, + 27472, + 27478, + 27548, + 27579, + 27582, + 27589, + 27593, + 27613, + 27649, + 27717, + 27729, + 27751, + 27757, + 27766, + 27791, + 27794, + 27854, + 27856, + 27866, + 27875, + 27902, + 27916, + 27924, + 27933, + 27940, + 27947, + 27969, + 27981, + 27996, + 28005, + 28030, + 28064, + 28102, + 28108, + 28120, + 28125, + 28130, + 28142, + 28149, + 28165, + 28169, + 28177, + 28211, + 28213, + 28220, + 28261, + 28271, + 28299, + 28326, + 28330, + 28350, + 28355, + 28367, + 28376, + 28379, + 28381, + 28447, + 28465, + 28471, + 28472, + 28478, + 28480, + 28489, + 28514, + 28525, + 28537, + 28550, + 28559, + 28595, + 28601, + 28629, + 28657, + 28667, + 28711, + 28718, + 28730, + 28732, + 28777, + 28801, + 28822, + 28855, + 28859, + 28869, + 28893, + 28904, + 28922, + 28930, + 28949, + 28972, + 29002, + 29009, + 29061, + 29068, + 29107, + 29119, + 29142, + 29146, + 29152, + 29200, + 29206, + 29245, + 29254, + 29258, + 29260, + 29268, + 29281, + 29306, + 29317, + 29324, + 29342, + 29375, + 29384, + 29389, + 29411, + 29413, + 29446, + 29457, + 29458, + 29483, + 29488, + 29494, + 29506, + 29553, + 29569, + 29587, + 29590, + 29600, + 29612, + 29665, + 29722, + 29745, + 29746, + 29752, + 29775, + 29778, + 29800, + 29829, + 29830, + 29877, + 29881, + 29884, + 29895, + 29899, + 29916, + 29923, + 29935, + 29955, + 29962, + 29969, + 29997, + 30032, + 30041, + 30048, + 30060, + 30063, + 30105, + 30122, + 30141, + 30142, + 30153, + 30171, + 30192, + 30197, + 30223, + 30235, + 30241, + 30256, + 30291, + 30293, + 30300, + 30331, + 30349, + 30361, + 30367, + 30392, + 30405, + 30410, + 30415, + 30439, + 30446, + 30501, + 30526, + 30531, + 30537, + 30546, + 30568, + 30581, + 30588, + 30598, + 30607, + 30609, + 30616, + 30626, + 30628, + 30638, + 30658, + 30663, + 30675, + 30698, + 30708, + 30712, + 30727, + 30736, + 30748, + 30758, + 30775, + 30793, + 30802, + 30820, + 30823, + 30827, + 30848, + 30893, + 30906, + 30950, + 30956, + 30996, + 31015, + 31016, + 31034, + 31099, + 31123, + 31145, + 31166, + 31168, + 31174, + 31216, + 31219, + 31238, + 31256, + 31304, + 31315, + 31324, + 31364, + 31379, + 31382, + 31412, + 31451, + 31487, + 31509, + 31510, + 31520, + 31535, + 31564, + 31585, + 31586, + 31600, + 31643, + 31646, + 31649, + 31650, + 31674, + 31679, + 31684, + 31688, + 31706, + 31735, + 31754, + 31761, + 31774, + 31807, + 31812, + 31821, + 31855, + 31919, + 31934, + 31956, + 31965, + 31975, + 31981, + 31999, + 32014, + 32022, + 32049, + 32055, + 32082, + 32087, + 32100, + 32104, + 32109, + 32138, + 32140, + 32148, + 32161, + 32162, + 32174, + 32196, + 32220, + 32223, + 32267, + 32272, + 32308, + 32315, + 32317, + 32347, + 32360, + 32394, + 32411, + 32420, + 32423, + 32455, + 32456, + 32510, + 32517, + 32541, + 32552, + 32555, + 32580, + 32598, + 32654, + 32662, + 32665, + 32678, + 32682, + 32687, + 32692, + 32710, + 32791, + 32792, + 32813, + 32826, + 32831, + 32836, + 32843, + 32854, + 32893, + 32897, + 32912, + 32951, + 32963, + 32970, + 32975, + 33028, + 33052, + 33061, + 33083, + 33103, + 33117, + 33139, + 33151, + 33162, + 33209, + 33210, + 33223, + 33227, + 33241, + 33263, + 33341, + 33344, + 33356, + 33390, + 33398, + 33423, + 33428, + 33444, + 33454, + 33479, + 33510, + 33514, + 33528, + 33548, + 33566, + 33570, + 33593, + 33599, + 33619, + 33635, + 33659, + 33680, + 33699, + 33713, + 33758, + 33771, + 33779, + 33800, + 33829, + 33836, + 33844, + 33856, + 33859, + 33873, + 33874, + 33929, + 33944, + 33965, + 33978, + 33986, + 34006, + 34025, + 34106, + 34126, + 34171, + 34189, + 34204, + 34260, + 34270, + 34280, + 34298, + 34313, + 34321, + 34333, + 34370, + 34376, + 34387, + 34389, + 34417, + 34429, + 34440, + 34443, + 34451, + 34470, + 34484, + 34493, + 34496, + 34514, + 34526, + 34535, + 34585, + 34591, + 34592, + 34602, + 34607, + 34644, + 34657, + 34675, + 34681, + 34693, + 34706, + 34745, + 34759, + 34765, + 34774, + 34780, + 34794, + 34807, + 34808, + 34835, + 34842, + 34865, + 34907, + 34928, + 34949, + 34961, + 34964, + 34987, + 34990, + 35019, + 35069, + 35077, + 35090, + 35152, + 35173, + 35174, + 35202, + 35214, + 35219, + 35226, + 35235, + 35255, + 35310, + 35318, + 35321, + 35333, + 35337, + 35346, + 35373, + 35414, + 35478, + 35497, + 35503, + 35512, + 35515, + 35526, + 35577, + 35585, + 35592, + 35615, + 35616, + 35622, + 35634, + 35657, + 35672, + 35708, + 35772, + 35790, + 35804, + 35811, + 35814, + 35837, + 35846, + 35873, + 35883, + 35918, + 35920, + 35925, + 35926, + 35945, + 35956, + 36003, + 36023, + 36024, + 36059, + 36061, + 36072, + 36075, + 36103, + 36110, + 36131, + 36151, + 36160, + 36199, + 36223, + 36227, + 36234, + 36236, + 36284, + 36319, + 36332, + 36343, + 36373, + 36401, + 36413, + 36433, + 36459, + 36480, + 36485, + 36510, + 36513, + 36523, + 36528, + 36537, + 36558, + 36563, + 36576, + 36608, + 36611, + 36617, + 36653, + 36716, + 36721, + 36733, + 36761, + 36783, + 36786, + 36795, + 36800, + 36810, + 36812, + 36817, + 36818, + 36851, + 36853, + 36868, + 36889, + 36890, + 36896, + 36905, + 36919, + 36938, + 36946, + 36951, + 36952, + 36964, + 36968, + 36979, + 36981, + 37021, + 37026, + 37075, + 37077, + 37108, + 37112, + 37150, + 37154, + 37156, + 37163, + 37178, + 37183, + 37185, + 37191, + 37198, + 37203, + 37225, + 37243, + 37252, + 37262, + 37264, + 37276, + 37327, + 37355, + 37403, + 37415, + 37422, + 37448, + 37451, + 37478, + 37484, + 37525, + 37553, + 37640, + 37645, + 37658, + 37667, + 37708, + 37723, + 37732, + 37747, + 37753, + 37772, + 37789, + 37817, + 37826, + 37831, + 37845, + 37855, + 37859, + 37866, + 37880, + 37885, + 37897, + 37906, + 37948, + 37954, + 37978, + 37980, + 37990, + 38001, + 38020, + 38029, + 38047, + 38063, + 38077, + 38110, + 38116, + 38119, + 38176, + 38186, + 38194, + 38218, + 38241, + 38247, + 38261, + 38268, + 38277, + 38287, + 38295, + 38299, + 38301, + 38305, + 38312, + 38315, + 38317, + 38343, + 38344, + 38350, + 38358, + 38364, + 38371, + 38373, + 38377, + 38392, + 38407, + 38408, + 38421, + 38438, + 38442, + 38464, + 38473, + 38484, + 38491, + 38510, + 38518, + 38531, + 38537, + 38538, + 38567, + 38594, + 38647, + 38651, + 38654, + 38686, + 38702, + 38751, + 38821, + 38825, + 38853, + 38863, + 38882, + 38884, + 38932, + 38941, + 38952, + 38960, + 38980, + 38995, + 39004, + 39013, + 39017, + 39026, + 39056, + 39121, + 39124, + 39133, + 39157, + 39181, + 39187, + 39212, + 39223, + 39250, + 39265, + 39320, + 39330, + 39335, + 39353, + 39371, + 39385, + 39421, + 39432, + 39443, + 39450, + 39455, + 39468, + 39473, + 39488, + 39497, + 39521, + 39531, + 39542, + 39585, + 39605, + 39658, + 39677, + 39703, + 39726, + 39731, + 39745, + 39776, + 39796, + 39809, + 39833, + 39850, + 39869, + 39882, + 39906, + 39918, + 39929, + 39947, + 39985, + 39986, + 40023, + 40024, + 40039, + 40053, + 40079, + 40084, + 40087, + 40094, + 40100, + 40112, + 40129, + 40132, + 40142, + 40154, + 40177, + 40178, + 40202, + 40219, + 40303, + 40305, + 40311, + 40336, + 40342, + 40358, + 40381, + 40417, + 40438, + 40463, + 40471, + 40472, + 40488, + 40491, + 40525, + 40526, + 40550, + 40553, + 40562, + 40568, + 40580, + 40608, + 40613, + 40652, + 40703, + 40712, + 40720, + 40723, + 40746, + 40759, + 40765, + 40771, + 40778, + 40788, + 40804, + 40835, + 40841, + 40907, + 40934, + 40955, + 40986, + 41007, + 41016, + 41034, + 41041, + 41063, + 41084, + 41093, + 41097, + 41111, + 41118, + 41121, + 41141, + 41160, + 41207, + 41214, + 41255, + 41284, + 41287, + 41308, + 41330, + 41336, + 41437, + 41444, + 41456, + 41481, + 41489, + 41499, + 41555, + 41561, + 41562, + 41571, + 41592, + 41631, + 41661, + 41682, + 41710, + 41724, + 41727, + 41730, + 41744, + 41769, + 41795, + 41798, + 41804, + 41826, + 41852, + 41868, + 41910, + 41914, + 41942, + 41969, + 41975, + 41976, + 41994, + 42002, + 42037, + 42056, + 42079, + 42085, + 42089, + 42123, + 42128, + 42140, + 42149, + 42156, + 42186, + 42191, + 42205, + 42221, + 42222, + 42230, + 42233, + 42241, + 42247, + 42248, + 42254, + 42259, + 42268, + 42295, + 42304, + 42322, + 42334, + 42355, + 42361, + 42373, + 42374, + 42398, + 42411, + 42443, + 42446, + 42463, + 42479, + 42482, + 42484, + 42498, + 42534, + 42537, + 42557, + 42570, + 42599, + 42600, + 42633, + 42639, + 42672, + 42681, + 42687, + 42704, + 42713, + 42714, + 42716, + 42726, + 42730, + 42737, + 42752, + 42757, + 42772, + 42809, + 42853, + 42857, + 42902, + 42912, + 42930, + 42936, + 42956, + 42959, + 42978, + 43001, + 43011, + 43047, + 43059, + 43094, + 43124, + 43218, + 43220, + 43240, + 43258, + 43263, + 43265, + 43290, + 43346, + 43364, + 43373, + 43401, + 43416, + 43443, + 43458, + 43497, + 43506, + 43545, + 43558, + 43576, + 43579, + 43624, + 43630, + 43637, + 43654, + 43660, + 43696, + 43706, + 43725, + 43733, + 43753, + 43756, + 43761, + 43768, + 43812, + 43822, + 43841, + 43861, + 43868, + 43877, + 43878, + 43908, + 43917, + 43936, + 43954, + 43963, + 43977, + 44008, + 44013, + 44026, + 44028, + 44045, + 44046, + 44053, + 44091, + 44101, + 44129, + 44139, + 44172, + 44203, + 44211, + 44240, + 44259, + 44305, + 44383, + 44384, + 44389, + 44390, + 44432, + 44435, + 44468, + 44472, + 44483, + 44497, + 44550, + 44577, + 44584, + 44601, + 44674, + 44683, + 44688, + 44694, + 44703, + 44713, + 44721, + 44722, + 44733, + 44746, + 44748, + 44760, + 44765, + 44766, + 44775, + 44794, + 44822, + 44841, + 44859, + 44894, + 44900, + 44904, + 44946, + 44967, + 44994, + 44999, + 45013, + 45017, + 45020, + 45027, + 45029, + 45066, + 45074, + 45080, + 45090, + 45101, + 45110, + 45113, + 45134, + 45136, + 45148, + 45158, + 45176, + 45181, + 45185, + 45188, + 45203, + 45209, + 45231, + 45234, + 45239, + 45246, + 45260, + 45284, + 45301, + 45333, + 45350, + 45354, + 45446, + 45458, + 45518, + 45566, + 45569, + 45575, + 45576, + 45587, + 45615, + 45661, + 45798, + 45829, + 45847, + 45858, + 45864, + 45899, + 45904, + 45919, + 45974, + 45987, + 45989, + 46008, + 46036, + 46039, + 46043, + 46045, + 46079, + 46084, + 46091, + 46105, + 46117, + 46141, + 46147, + 46162, + 46184, + 46197, + 46207, + 46214, + 46218, + 46237, + 46247, + 46251, + 46327, + 46333, + 46342, + 46366, + 46376, + 46384, + 46404, + 46478, + 46511, + 46540, + 46638, + 46700, + 46706, + 46745, + 46757, + 46772, + 46776, + 46790, + 46794, + 46804, + 46820, + 46849, + 46870, + 46876, + 46903, + 46904, + 46907, + 46932, + 46955, + 46963, + 46991, + 47029, + 47036, + 47054, + 47099, + 47106, + 47132, + 47145, + 47151, + 47156, + 47171, + 47188, + 47201, + 47219, + 47226, + 47241, + 47252, + 47261, + 47295, + 47297, + 47333, + 47337, + 47360, + 47377, + 47378, + 47384, + 47389, + 47417, + 47420, + 47426, + 47443, + 47504, + 47507, + 47510, + 47526, + 47550, + 47552, + 47557, + 47564, + 47591, + 47610, + 47621, + 47639, + 47646, + 47676, + 47682, + 47732, + 47741, + 47751, + 47757, + 47786, + 47803, + 47828, + 47848, + 47853, + 47856, + 47862, + 47874, + 47883, + 47916, + 47934, + 47951, + 47979, + 48010, + 48027, + 48046, + 48060, + 48065, + 48075, + 48096, + 48119, + 48173, + 48176, + 48186, + 48213, + 48223, + 48224, + 48229, + 48241, + 48281, + 48284, + 48291, + 48308, + 48340, + 48344, + 48368, + 48400, + 48406, + 48409, + 48421, + 48448, + 48453, + 48457, + 48478, + 48493, + 48527, + 48583, + 48597, + 48641, + 48668, + 48671, + 48682, + 48709, + 48719, + 48731, + 48780, + 48791, + 48797, + 48807, + 48811, + 48814, + 48821, + 48836, + 48846, + 48848, + 48854, + 48874, + 48908, + 48929, + 48941, + 48954, + 48961, + 48962, + 48985, + 49001, + 49007, + 49015, + 49035, + 49062, + 49066, + 49085, + 49091, + 49094, + 49127, + 49134, + 49183, + 49221, + 49231, + 49250, + 49252, + 49270, + 49297, + 49313, + 49340, + 49365, + 49379, + 49386, + 49391, + 49417, + 49438, + 49444, + 49453, + 49454, + 49480, + 49485, + 49498, + 49513, + 49527, + 49531, + 49564, + 49588, + 49609, + 49617, + 49645, + 49646, + 49654, + 49697, + 49718, + 49741, + 49754, + 49756, + 49833, + 49834, + 49879, + 49942, + 49946, + 49982, + 49994, + 50001, + 50023, + 50047, + 50120, + 50133, + 50137, + 50140, + 50156, + 50199, + 50205, + 50215, + 50216, + 50224, + 50229, + 50233, + 50251, + 50281, + 50326, + 50332, + 50348, + 50359, + 50374, + 50404, + 50443, + 50488, + 50493, + 50505, + 50511, + 50525, + 50542, + 50550, + 50560, + 50570, + 50587, + 50593, + 50611, + 50649, + 50656, + 50685, + 50686, + 50692, + 50702, + 50704, + 50709, + 50720, + 50726, + 50729, + 50737, + 50758, + 50772, + 50849, + 50850, + 50881, + 50901, + 50906, + 50915, + 50961, + 50992, + 50997, + 51001, + 51004, + 51033, + 51045, + 51052, + 51064, + 51085, + 51127, + 51139, + 51153, + 51181, + 51182, + 51194, + 51196, + 51200, + 51239, + 51240, + 51254, + 51260, + 51342, + 51370, + 51372, + 51377, + 51398, + 51402, + 51407, + 51410, + 51412, + 51419, + 51428, + 51431, + 51460, + 51475, + 51477, + 51478, + 51482, + 51511, + 51518, + 51568, + 51607, + 51618, + 51630, + 51655, + 51673, + 51683, + 51709, + 51716, + 51774, + 51829, + 51830, + 51839, + 51849, + 51869, + 51886, + 51905, + 51906, + 51915, + 51948, + 51988, + 51998, + 52004, + 52026, + 52036, + 52082, + 52127, + 52145, + 52157, + 52165, + 52193, + 52211, + 52213, + 52218, + 52220, + 52238, + 52240, + 52243, + 52250, + 52279, + 52285, + 52306, + 52370, + 52432, + 52457, + 52466, + 52514, + 52557, + 52560, + 52585, + 52586, + 52603, + 52650, + 52672, + 52681, + 52692, + 52735, + 52760, + 52772, + 52781, + 52793, + 52796, + 52807, + 52821, + 52849, + 52866, + 52868, + 52872, + 52875, + 52886, + 52890, + 52896, + 52925, + 52931, + 52937, + 52938, + 52952, + 52979, + 53013, + 53023, + 53027, + 53033, + 53039, + 53041, + 53048, + 53073, + 53095, + 53099, + 53120, + 53154, + 53168, + 53192, + 53205, + 53206, + 53234, + 53246, + 53253, + 53263, + 53275, + 53313, + 53331, + 53349, + 53367, + 53383, + 53392, + 53404, + 53407, + 53411, + 53417, + 53425, + 53443, + 53469, + 53480, + 53508, + 53535, + 53536, + 53542, + 53563, + 53577, + 53591, + 53607, + 53626, + 53628, + 53638, + 53675, + 53685, + 53692, + 53703, + 53722, + 53738, + 53748, + 53752, + 53764, + 53781, + 53788, + 53791, + 53816, + 53824, + 53830, + 53839, + 53844, + 53875, + 53921, + 53922, + 53927, + 53948, + 53956, + 53990, + 53994, + 54001, + 54016, + 54019, + 54070, + 54074, + 54088, + 54102, + 54111, + 54130, + 54152, + 54170, + 54172, + 54211, + 54218, + 54228, + 54251, + 54253, + 54268, + 54271, + 54274, + 54288, + 54314, + 54319, + 54321, + 54324, + 54341, + 54353, + 54366, + 54370, + 54420, + 54423, + 54434, + 54440, + 54454, + 54495, + 54501, + 54526, + 54639, + 54653, + 54667, + 54678, + 54700, + 54717, + 54780, + 54801, + 54813, + 54814, + 54850, + 54883, + 54907, + 54919, + 54931, + 54933, + 54991, + 55003, + 55009, + 55030, + 55034, + 55039, + 55048, + 55059, + 55061, + 55068, + 55077, + 55122, + 55149, + 55157, + 55158, + 55178, + 55222, + 55234, + 55236, + 55251, + 55269, + 55270, + 55284, + 55309, + 55322, + 55334, + 55340, + 55348, + 55377, + 55430, + 55433, + 55441, + 55470, + 55535, + 55561, + 55567, + 55597, + 55630, + 55648, + 55653, + 55657, + 55665, + 55678, + 55684, + 55691, + 55693, + 55702, + 55708, + 55715, + 55739, + 55761, + 55767, + 55768, + 55774, + 55787, + 55811, + 55835, + 55894, + 55897, + 55904, + 55931, + 55950, + 55961, + 55973, + 56078, + 56099, + 56105, + 56119, + 56133, + 56168, + 56191, + 56202, + 56209, + 56215, + 56232, + 56240, + 56260, + 56270, + 56278, + 56281, + 56288, + 56303, + 56308, + 56312, + 56320, + 56326, + 56392, + 56395, + 56403, + 56419, + 56428, + 56450, + 56452, + 56485, + 56486, + 56492, + 56498, + 56510, + 56512, + 56524, + 56530, + 56545, + 56551, + 56565, + 56580, + 56587, + 56589, + 56592, + 56611, + 56623, + 56635, + 56646, + 56660, + 56680, + 56686, + 56716, + 56749, + 56790, + 56809, + 56869, + 56884, + 56887, + 56893, + 56906, + 56932, + 56959, + 56965, + 56983, + 57018, + 57023, + 57025, + 57032, + 57040, + 57046, + 57071, + 57091, + 57094, + 57108, + 57122, + 57127, + 57168, + 57183, + 57184, + 57193, + 57202, + 57235, + 57237, + 57251, + 57289, + 57349, + 57359, + 57374, + 57377, + 57387, + 57415, + 57440, + 57446, + 57450, + 57469, + 57491, + 57503, + 57507, + 57542, + 57569, + 57599, + 57601, + 57607, + 57608, + 57625, + 57644, + 57662, + 57664, + 57674, + 57698, + 57700, + 57709, + 57724, + 57728, + 57740, + 57745, + 57751, + 57774, + 57782, + 57796, + 57803, + 57823, + 57863, + 57894, + 57925, + 57971, + 58013, + 58020, + 58032, + 58038, + 58061, + 58069, + 58080, + 58089, + 58107, + 58121, + 58130, + 58146, + 58190, + 58195, + 58202, + 58237, + 58253, + 58299, + 58302, + 58327, + 58328, + 58364, + 58367, + 58375, + 58394, + 58405, + 58417, + 58424, + 58430, + 58452, + 58466, + 58468, + 58495, + 58501, + 58544, + 58571, + 58609, + 58610, + 58616, + 58619, + 58641, + 58642, + 58648, + 58660, + 58675, + 58678, + 58690, + 58735, + 58760, + 58766, + 58799, + 58825, + 58836, + 58855, + 58864, + 58910, + 58937, + 58943, + 58952, + 58965, + 58988, + 58994, + 58999, + 59006, + 59029, + 59033, + 59069, + 59096, + 59106, + 59123, + 59130, + 59152, + 59162, + 59180, + 59183, + 59195, + 59205, + 59210, + 59217, + 59218, + 59236, + 59267, + 59298, + 59318, + 59321, + 59327, + 59354, + 59363, + 59377, + 59389, + 59403, + 59420, + 59444, + 59471, + 59476, + 59483, + 59502, + 59509, + 59538, + 59556, + 59571, + 59592, + 59610, + 59654, + 59677, + 59699, + 59716, + 59719, + 59737, + 59747, + 59789, + 59807, + 59811, + 59818, + 59825, + 59826, + 59832, + 59858, + 59860, + 59873, + 59876, + 59907, + 59928, + 59933, + 59938, + 59940, + 59958, + 59984, + 60020, + 60024, + 60033, + 60034, + 60063, + 60070, + 60087, + 60091, + 60105, + 60126, + 60132, + 60154, + 60174, + 60181, + 60198, + 60212, + 60247, + 60254, + 60275, + 60284, + 60317, + 60318, + 60346, + 60360, + 60380, + 60389, + 60393, + 60401, + 60407, + 60408, + 60462, + 60484, + 60505, + 60521, + 60527, + 60532, + 60545, + 60546, + 60555, + 60563, + 60586, + 60626, + 60637, + 60665, + 60673, + 60685, + 60703, + 60734, + 60742, + 60790, + 60830, + 60848, + 60857, + 60871, + 60875, + 60913, + 60923, + 60972, + 60989, + 61001, + 61002, + 61019, + 61022, + 61059, + 61065, + 61066, + 61071, + 61076, + 61141, + 61148, + 61167, + 61190, + 61218, + 61247, + 61256, + 61289, + 61292, + 61307, + 61319, + 61353, + 61362, + 61379, + 61382, + 61433, + 61434, + 61454, + 61461, + 61475, + 61481, + 61534, + 61547, + 61564, + 61568, + 61588, + 61604, + 61626, + 61645, + 61646, + 61654, + 61663, + 61669, + 61702, + 61705, + 61714, + 61739, + 61744, + 61749, + 61776, + 61786, + 61822, + 61826, + 61862, + 61865, + 61868, + 61879, + 61885, + 61900, + 61905, + 61906, + 61962, + 61967, + 61972, + 61976, + 62027, + 62048, + 62051, + 62066, + 62081, + 62108, + 62178, + 62189, + 62224, + 62229, + 62282, + 62318, + 62320, + 62329, + 62341, + 62353, + 62359, + 62382, + 62389, + 62396, + 62425, + 62455, + 62484, + 62494, + 62507, + 62512, + 62550, + 62577, + 62590, + 62599, + 62617, + 62679, + 62702, + 62745, + 62772, + 62794, + 62835, + 62842, + 62847, + 62857, + 62894, + 62911, + 62928, + 62954, + 62964, + 62977, + 62984, + 63007, + 63017, + 63058, + 63067, + 63085, + 63150, + 63170, + 63184, + 63210, + 63215, + 63217, + 63229, + 63237, + 63259, + 63265, + 63271, + 63286, + 63298, + 63343, + 63355, + 63361, + 63362, + 63379, + 63397, + 63415, + 63421, + 63463, + 63491, + 63527, + 63545, + 63553, + 63560, + 63563, + 63566, + 63589, + 63599, + 63601, + 63608, + 63620, + 63654, + 63703, + 63719, + 63758, + 63769, + 63782, + 63803, + 63811, + 63851, + 63854, + 63872, + 63878, + 63895, + 63917, + 63930, + 63935, + 63955, + 63964, + 63967, + 63980, + 63985, + 63992, + 64021, + 64026, + 64044, + 64055, + 64056, + 64061, + 64067, + 64081, + 64100, + 64109, + 64112, + 64118, + 64124, + 64145, + 64151, + 64203, + 64208, + 64236, + 64254, + 64261, + 64280, + 64296, + 64313, + 64314, + 64316, + 64348, + 64352, + 64355, + 64361, + 64388, + 64398, + 64403, + 64419, + 64421, + 64428, + 64453, + 64463, + 64475, + 64511, + 64537, + 64576, + 64579, + 64581, + 64606, + 64615, + 64649, + 64655, + 64664, + 64667, + 64712, + 64715, + 64718, + 64741, + 64766, + 64780, + 64788, + 64791, + 64795, + 64798, + 64816, + 64819, + 64822, + 64833, + 64836, + 64876, + 64891, + 64907, + 64943, + 64965, + 64977, + 64999, + 65034, + 65036, + 65089, + 65107, + 65110, + 65120, + 65132, + 65143, + 65150, + 65177, + 65201, + 65214, + 65234, + 65240, + 65243, + 65259, + 65276, + 65287, + 65306, + 65311, + 65321, + 65350, + 65364, + 65451, + 65488, + 65510, + 65528, + 65533, + 65553, + 65563, + 65579, + 65621, + 65625, + 65635, + 65644, + 65690, + 65696, + 65705, + 65716, + 65725, + 65733, + 65740, + 65758, + 65786, + 65806, + 65834, + 65844, + 65866, + 65895, + 65902, + 65953, + 65954, + 65983, + 65985, + 66003, + 66010, + 66025, + 66050, + 66074, + 66076, + 66097, + 66132, + 66158, + 66175, + 66185, + 66199, + 66206, + 66222, + 66227, + 66241, + 66272, + 66324, + 66424, + 66460, + 66464, + 66481, + 66482, + 66523, + 66526, + 66532, + 66539, + 66541, + 66573, + 66582, + 66591, + 66615, + 66622, + 66629, + 66641, + 66712, + 66724, + 66731, + 66745, + 66759, + 66808, + 66814, + 66821, + 66831, + 66834, + 66879, + 66884, + 66899, + 66901, + 66924, + 66929, + 66942, + 66985, + 66986, + 66994, + 67066, + 67075, + 67099, + 67130, + 67173, + 67183, + 67186, + 67197, + 67201, + 67208, + 67221, + 67238, + 67252, + 67256, + 67270, + 67288, + 67318, + 67329, + 67349, + 67369, + 67392, + 67435, + 67473, + 67496, + 67507, + 67514, + 67536, + 67555, + 67598, + 67615, + 67625, + 67645, + 67651, + 67663, + 67672, + 67682, + 67699, + 67718, + 67780, + 67795, + 67804, + 67818, + 67832, + 67941, + 67984, + 68044, + 68059, + 68062, + 68065, + 68071, + 68072, + 68085, + 68090, + 68101, + 68102, + 68106, + 68164, + 68191, + 68192, + 68195, + 68209, + 68245, + 68246, + 68274, + 68293, + 68294, + 68322, + 68353, + 68359, + 68377, + 68401, + 68422, + 68434, + 68443, + 68445, + 68476, + 68492, + 68504, + 68525, + 68540, + 68543, + 68555, + 68563, + 68576, + 68581, + 68617, + 68631, + 68656, + 68666, + 68714, + 68743, + 68761, + 68764, + 68767, + 68768, + 68786, + 68788, + 68848, + 68851, + 68914, + 68946, + 68952, + 68973, + 69001, + 69016, + 69035, + 69037, + 69049, + 69052, + 69058, + 69063, + 69075, + 69112, + 69117, + 69124, + 69127, + 69134, + 69139, + 69161, + 69196, + 69224, + 69238, + 69301, + 69316, + 69325, + 69334, + 69347, + 69359, + 69381, + 69388, + 69393, + 69409, + 69422, + 69453, + 69459, + 69481, + 69487, + 69490, + 69495, + 69501, + 69511, + 69512, + 69532, + 69542, + 69560, + 69565, + 69571, + 69611, + 69633, + 69640, + 69667, + 69669, + 69679, + 69688, + 69699, + 69756, + 69759, + 69770, + 69772, + 69826, + 69840, + 69846, + 69868, + 69885, + 69946, + 69966, + 69973, + 69977, + 69980, + 69984, + 69994, + 70024, + 70044, + 70053, + 70086, + 70113, + 70120, + 70131, + 70150, + 70178, + 70198, + 70227, + 70285, + 70288, + 70291, + 70309, + 70334, + 70339, + 70381, + 70413, + 70414, + 70481, + 70488, + 70493, + 70515, + 70540, + 70543, + 70558, + 70568, + 70582, + 70593, + 70596, + 70613, + 70620, + 70647, + 70666, + 70710, + 70719, + 70721, + 70722, + 70742, + 70757, + 70764, + 70781, + 70795, + 70803, + 70809, + 70821, + 70846, + 70882, + 70887, + 70940, + 70961, + 70996, + 71012, + 71046, + 71057, + 71060, + 71063, + 71079, + 71080, + 71111, + 71118, + 71129, + 71136, + 71142, + 71145, + 71151, + 71163, + 71218, + 71223, + 71232, + 71237, + 71272, + 71323, + 71339, + 71341, + 71349, + 71368, + 71379, + 71395, + 71407, + 71421, + 71430, + 71436, + 71454, + 71467, + 71472, + 71478, + 71481, + 71501, + 71519, + 71530, + 71550, + 71573, + 71593, + 71608, + 71619, + 71622, + 71636, + 71650, + 71655, + 71685, + 71703, + 71714, + 71748, + 71758, + 71766, + 71772, + 71785, + 71794, + 71796, + 71803, + 71809, + 71858, + 71863, + 71878, + 71895, + 71899, + 71906, + 71908, + 71917, + 71952, + 71957, + 71961, + 71973, + 71980, + 71997, + 72017, + 72060, + 72091, + 72097, + 72166, + 72172, + 72183, + 72203, + 72205, + 72213, + 72214, + 72230, + 72239, + 72248, + 72251, + 72280, + 72313, + 72338, + 72340, + 72343, + 72368, + 72371, + 72426, + 72439, + 72446, + 72494, + 72519, + 72573, + 72577, + 72578, + 72614, + 72628, + 72640, + 72676, + 72708, + 72717, + 72766, + 72786, + 72788, + 72795, + 72797, + 72798, + 72808, + 72826, + 72835, + 72837, + 72865, + 72871, + 72872, + 72898, + 72907, + 72909, + 72917, + 72934, + 72987, + 73000, + 73005, + 73014, + 73023, + 73025, + 73074, + 73076, + 73113, + 73116, + 73140, + 73149, + 73186, + 73188, + 73191, + 73205, + 73215, + 73216, + 73239, + 73294, + 73311, + 73330, + 73366, + 73379, + 73386, + 73391, + 73418, + 73438, + 73476, + 73503, + 73509, + 73534, + 73545, + 73548, + 73563, + 73575, + 73582, + 73603, + 73609, + 73610, + 73645, + 73646, + 73678, + 73685, + 73708, + 73747, + 73765, + 73797, + 73810, + 73819, + 73825, + 73845, + 73855, + 73866, + 73890, + 73919, + 73922, + 73936, + 73939, + 73964, + 73976, + 73984, + 73990, + 74013, + 74014, + 74020, + 74035, + 74038, + 74069, + 74119, + 74123, + 74126, + 74153, + 74179, + 74200, + 74210, + 74216, + 74250, + 74263, + 74264, + 74279, + 74285, + 74294, + 74298, + 74303, + 74306, + 74366, + 74369, + 74403, + 74406, + 74442, + 74450, + 74452, + 74459, + 74461, + 74477, + 74478, + 74489, + 74504, + 74528, + 74533, + 74538, + 74551, + 74580, + 74589, + 74590, + 74593, + 74608, + 74611, + 74617, + 74623, + 74648, + 74704, + 74735, + 74737, + 74738, + 74779, + 74781, + 74809, + 74812, + 74827, + 74868, + 74871, + 74905, + 74930, + 74962, + 74990, + 74995, + 75007, + 75012, + 75030, + 75033, + 75039, + 75055, + 75078, + 75120, + 75130, + 75159, + 75163, + 75170, + 75193, + 75228, + 75244, + 75249, + 75328, + 75357, + 75373, + 75392, + 75428, + 75438, + 75469, + 75487, + 75494, + 75515, + 75526, + 75532, + 75543, + 75549, + 75559, + 75563, + 75568, + 75598, + 75612, + 75622, + 75640, + 75683, + 75689, + 75690, + 75692, + 75752, + 75766, + 75769, + 75791, + 75794, + 75806, + 75809, + 75819, + 75834, + 75895, + 75908, + 75951, + 75960, + 75965, + 75974, + 75978, + 75998, + 76001, + 76007, + 76016, + 76091, + 76119, + 76135, + 76170, + 76189, + 76214, + 76225, + 76235, + 76259, + 76261, + 76262, + 76266, + 76286, + 76289, + 76310, + 76319, + 76364, + 76375, + 76392, + 76422, + 76450, + 76496, + 76521, + 76522, + 76527, + 76536, + 76541, + 76553, + 76568, + 76574, + 76584, + 76604, + 76607, + 76609, + 76669, + 76683, + 76745, + 76753, + 76754, + 76756, + 76760, + 76782, + 76821, + 76828, + 76849, + 76850, + 76870, + 76874, + 76898, + 76903, + 76910, + 76921, + 76968, + 77013, + 77027, + 77042, + 77059, + 77062, + 77074, + 77076, + 77110, + 77113, + 77131, + 77157, + 77158, + 77216, + 77246, + 77258, + 77281, + 77284, + 77294, + 77302, + 77306, + 77315, + 77352, + 77360, + 77365, + 77370, + 77378, + 77380, + 77407, + 77408, + 77414, + 77444, + 77454, + 77481, + 77482, + 77531, + 77544, + 77552, + 77569, + 77579, + 77610, + 77612, + 77623, + 77649, + 77650, + 77661, + 77675, + 77686, + 77742, + 77791, + 77792, + 77807, + 77815, + 77842, + 77847, + 77899, + 77901, + 77904, + 77914, + 77925, + 77950, + 77959, + 77994, + 78004, + 78043, + 78052, + 78061, + 78064, + 78084, + 78094, + 78099, + 78129, + 78142, + 78149, + 78153, + 78171, + 78173, + 78174, + 78195, + 78201, + 78202, + 78241, + 78247, + 78274, + 78276, + 78303, + 78307, + 78328, + 78344, + 78362, + 78367, + 78368, + 78409, + 78412, + 78417, + 78430, + 78433, + 78440, + 78451, + 78453, + 78458, + 78467, + 78479, + 78507, + 78518, + 78535, + 78542, + 78549, + 78554, + 78556, + 78583, + 78590, + 78615, + 78635, + 78649, + 78684, + 78691, + 78705, + 78724, + 78755, + 78770, + 78772, + 78818, + 78837, + 78844, + 78849, + 78909, + 78915, + 78941, + 78958, + 78975, + 78979, + 78986, + 79029, + 79030, + 79044, + 79048, + 79056, + 79095, + 79099, + 79121, + 79150, + 79196, + 79199, + 79220, + 79229, + 79263, + 79264, + 79296, + 79302, + 79354, + 79387, + 79399, + 79435, + 79525, + 79540, + 79552, + 79562, + 79576, + 79579, + 79605, + 79618, + 79648, + 79654, + 79666, + 79686, + 79697, + 79700, + 79723, + 79749, + 79750, + 79764, + 79771, + 79774, + 79780, + 79789, + 79798, + 79821, + 79850, + 79864, + 79898, + 79904, + 79934, + 79936, + 79942, + 79945, + 79963, + 79987, + 80057, + 80077, + 80078, + 80080, + 80102, + 80106, + 80111, + 80152, + 80155, + 80173, + 80186, + 80203, + 80223, + 80233, + 80258, + 80281, + 80318, + 80326, + 80330, + 80337, + 80344, + 80365, + 80383, + 80389, + 80413, + 80441, + 80449, + 80461, + 80467, + 80476, + 80507, + 80516, + 80519, + 80568, + 80571, + 80579, + 80586, + 80599, + 80610, + 80629, + 80642, + 80690, + 80713, + 80716, + 80737, + 80743, + 80750, + 80786, + 80811, + 80834, + 80839, + 80840, + 80846, + 80848, + 80876, + 80911, + 80947, + 81001, + 81031, + 81045, + 81056, + 81073, + 81083, + 81145, + 81168, + 81177, + 81207, + 81208, + 81226, + 81245, + 81269, + 81285, + 81289, + 81292, + 81298, + 81310, + 81346, + 81348, + 81355, + 81388, + 81396, + 81415, + 81460, + 81482, + 81518, + 81523, + 81529, + 81545, + 81570, + 81576, + 81604, + 81613, + 81631, + 81656, + 81679, + 81684, + 81698, + 81736, + 81747, + 81765, + 81775, + 81805, + 81842, + 81859, + 81865, + 81866, + 81892, + 81902, + 81933, + 81934, + 81942, + 81969, + 81981, + 81999, + 82004, + 82008, + 82032, + 82035, + 82060, + 82063, + 82071, + 82081, + 82082, + 82105, + 82106, + 82120, + 82125, + 82156, + 82176, + 82203, + 82210, + 82241, + 82287, + 82323, + 82330, + 82366, + 82378, + 82395, + 82398, + 82401, + 82404, + 82419, + 82421, + 82428, + 82442, + 82452, + 82455, + 82466, + 82510, + 82524, + 82545, + 82555, + 82581, + 82588, + 82591, + 82636, + 82658, + 82675, + 82678, + 82716, + 82725, + 82743, + 82744, + 82762, + 82770, + 82809, + 82846, + 82855, + 82882, + 82899, + 82905, + 82950, + 82953, + 82967, + 82971, + 82987, + 83007, + 83009, + 83012, + 83030, + 83045, + 83050, + 83052, + 83070, + 83076, + 83086, + 83128, + 83141, + 83153, + 83156, + 83194, + 83225, + 83261, + 83264, + 83322, + 83382, + 83391, + 83399, + 83406, + 83427, + 83439, + 83444, + 83453, + 83457, + 83475, + 83484, + 83488, + 83493, + 83512, + 83525, + 83535, + 83560, + 83617, + 83664, + 83676, + 83757, + 83770, + 83775, + 83835, + 83838, + 83848, + 83856, + 83878, + 83884, + 83896, + 83902, + 83922, + 83977, + 83985, + 83988, + 84034, + 84046, + 84058, + 84069, + 84107, + 84155, + 84157, + 84160, + 84165, + 84187, + 84214, + 84226, + 84235, + 84240, + 84255, + 84273, + 84291, + 84311, + 84317, + 84328, + 84346, + 84357, + 84361, + 84372, + 84388, + 84415, + 84438, + 84444, + 84447, + 84451, + 84465, + 84471, + 84496, + 84554, + 84561, + 84571, + 84580, + 84598, + 84611, + 84620, + 84625, + 84632, + 84648, + 84659, + 84662, + 84683, + 84697, + 84698, + 84709, + 84722, + 84753, + 84775, + 84789, + 84885, + 84890, + 84899, + 84926, + 84946, + 84958, + 84976, + 84979, + 85003, + 85014, + 85017, + 85024, + 85029, + 85036, + 85042, + 85054, + 85056, + 85061, + 85066, + 85073, + 85096, + 85101, + 85109, + 85114, + 85119, + 85123, + 85149, + 85185, + 85228, + 85236, + 85281, + 85282, + 85293, + 85302, + 85319, + 85353, + 85354, + 85356, + 85389, + 85418, + 85446, + 85450, + 85463, + 85497, + 85534, + 85543, + 85549, + 85562, + 85587, + 85590, + 85599, + 85630, + 85660, + 85669, + 85693, + 85711, + 85716, + 85773, + 85801, + 85815, + 85839, + 85842, + 85864, + 85867, + 85903, + 85917, + 85921, + 85928, + 85934, + 85974, + 85994, + 85999, + 86004, + 86008, + 86046, + 86067, + 86084, + 86087, + 86093, + 86121, + 86122, + 86127, + 86151, + 86166, + 86179, + 86188, + 86193, + 86206, + 86214, + 86226, + 86242, + 86256, + 86259, + 86298, + 86300, + 86307, + 86310, + 86319, + 86321, + 86328, + 86356, + 86360, + 86375, + 86399, + 86400, + 86403, + 86430, + 86446, + 86460, + 86465, + 86486, + 86502, + 86563, + 86595, + 86635, + 86649, + 86661, + 86674, + 86689, + 86721, + 86734, + 86741, + 86742, + 86784, + 86799, + 86808, + 86837, + 86869, + 86900, + 86949, + 86993, + 86999, + 87030, + 87041, + 87044, + 87084, + 87116, + 87138, + 87162, + 87188, + 87211, + 87234, + 87245, + 87246, + 87260, + 87270, + 87284, + 87293, + 87296, + 87299, + 87305, + 87308, + 87313, + 87323, + 87332, + 87361, + 87376, + 87392, + 87419, + 87432, + 87435, + 87445, + 87466, + 87491, + 87503, + 87558, + 87570, + 87581, + 87603, + 87615, + 87623, + 87635, + 87647, + 87651, + 87657, + 87665, + 87694, + 87701, + 87705, + 87722, + 87739, + 87750, + 87790, + 87795, + 87797, + 87816, + 87884, + 87917, + 87930, + 87942, + 87953, + 87954, + 87984, + 87989, + 88008, + 88016, + 88038, + 88042, + 88044, + 88049, + 88083, + 88119, + 88134, + 88138, + 88143, + 88191, + 88216, + 88231, + 88232, + 88297, + 88300, + 88308, + 88317, + 88344, + 88350, + 88371, + 88469, + 88483, + 88485, + 88518, + 88586, + 88605, + 88621, + 88651, + 88656, + 88665, + 88668, + 88712, + 88717, + 88751, + 88754, + 88756, + 88785, + 88801, + 88807, + 88826, + 88848, + 88854, + 88864, + 88879, + 88939, + 88947, + 88987, + 88990, + 88996, + 89008, + 89011, + 89043, + 89045, + 89050, + 89097, + 89100, + 89106, + 89134, + 89178, + 89189, + 89202, + 89211, + 89224, + 89241, + 89251, + 89254, + 89258, + 89295, + 89328, + 89357, + 89403, + 89420, + 89426, + 89465, + 89471, + 89475, + 89547, + 89549, + 89558, + 89564, + 89611, + 89616, + 89626, + 89650, + 89691, + 89718, + 89764, + 89776, + 89785, + 89813, + 89817, + 89861, + 89876, + 89889, + 89904, + 89939, + 89948, + 89952, + 89964, + 89969, + 89979, + 90009, + 90022, + 90031, + 90043, + 90045, + 90068, + 90071, + 90082, + 90087, + 90117, + 90127, + 90163, + 90166, + 90177, + 90211, + 90218, + 90225, + 90231, + 90235, + 90289, + 90344, + 90347, + 90379, + 90387, + 90418, + 90435, + 90444, + 90472, + 90478, + 90485, + 90486, + 90513, + 90514, + 90532, + 90567, + 90595, + 90597, + 90621, + 90631, + 90668, + 90706, + 90708, + 90715, + 90724, + 90769, + 90791, + 90792, + 90805, + 90810, + 90820, + 90844, + 90907, + 90925, + 90926, + 90934, + 90946, + 90981, + 90999, + 91003, + 91019, + 91022, + 91050, + 91055, + 91064, + 91078, + 91117, + 91120, + 91129, + 91140, + 91157, + 91161, + 91240, + 91260, + 91270, + 91287, + 91321, + 91336, + 91341, + 91378, + 91398, + 91437, + 91440, + 91475, + 91494, + 91500, + 91511, + 91567, + 91572, + 91601, + 91617, + 91653, + 91678, + 91705, + 91723, + 91725, + 91733, + 91761, + 91768, + 91790, + 91804, + 91807, + 91808, + 91818, + 91840, + 91849, + 91869, + 91873, + 91876, + 91888, + 91891, + 91897, + 91911, + 91965, + 91971, + 91988, + 91992, + 92004, + 92021, + 92035, + 92068, + 92098, + 92104, + 92121, + 92127, + 92151, + 92162, + 92186, + 92191, + 92192, + 92207, + 92260, + 92282, + 92288, + 92297, + 92303, + 92315, + 92322, + 92327, + 92341, + 92389, + 92390, + 92422, + 92439, + 92452, + 92470, + 92473, + 92493, + 92508, + 92517, + 92529, + 92551, + 92557, + 92596, + 92611, + 92613, + 92642, + 92666, + 92684, + 92723, + 92732, + 92738, + 92783, + 92808, + 92816, + 92835, + 92847, + 92879, + 92881, + 92884, + 92932, + 92935, + 92960, + 92990, + 93010, + 93025, + 93046, + 93085, + 93089, + 93096, + 93145, + 93155, + 93169, + 93179, + 93184, + 93204, + 93211, + 93213, + 93227, + 93285, + 93292, + 93320, + 93356, + 93371, + 93374, + 93385, + 93403, + 93406, + 93427, + 93451, + 93454, + 93472, + 93482, + 93507, + 93537, + 93562, + 93564, + 93608, + 93636, + 93640, + 93653, + 93654, + 93664, + 93676, + 93721, + 93740, + 93743, + 93745, + 93751, + 93770, + 93796, + 93820, + 93824, + 93833, + 93841, + 93847, + 93848, + 93854, + 93882, + 93943, + 93958, + 93972, + 93975, + 94003, + 94009, + 94020, + 94072, + 94081, + 94093, + 94102, + 94122, + 94135, + 94136, + 94150, + 94184, + 94187, + 94258, + 94264, + 94272, + 94278, + 94281, + 94317, + 94348, + 94376, + 94382, + 94387, + 94389, + 94393, + 94402, + 94421, + 94422, + 94431, + 94473, + 94487, + 94504, + 94510, + 94522, + 94532, + 94572, + 94589, + 94599, + 94603, + 94647, + 94665, + 94695, + 94716, + 94738, + 94740, + 94778, + 94803, + 94810, + 94815, + 94821, + 94862, + 94886, + 94900, + 94924, + 94952, + 94963, + 94970, + 94980, + 94992, + 95017, + 95028, + 95031, + 95035, + 95040, + 95058, + 95079, + 95122, + 95149, + 95150, + 95167, + 95175, + 95205, + 95229, + 95321, + 95345, + 95364, + 95379, + 95386, + 95395, + 95416, + 95419, + 95433, + 95464, + 95490, + 95496, + 95504, + 95513, + 95523, + 95525, + 95558, + 95572, + 95591, + 95609, + 95619, + 95625, + 95633, + 95649, + 95652, + 95655, + 95696, + 95721, + 95766, + 95772, + 95775, + 95794, + 95796, + 95818, + 95820, + 95832, + 95842, + 95851, + 95854, + 95859, + 95868, + 95881, + 95895, + 95943, + 95949, + 95978, + 95980, + 96010, + 96020, + 96024, + 96063, + 96108, + 96125, + 96154, + 96172, + 96189, + 96204, + 96219, + 96256, + 96261, + 96289, + 96292, + 96296, + 96324, + 96345, + 96346, + 96358, + 96386, + 96412, + 96428, + 96445, + 96446, + 96448, + 96458, + 96475, + 96482, + 96494, + 96502, + 96508, + 96511, + 96516, + 96520, + 96547, + 96556, + 96561, + 96568, + 96581, + 96582, + 96679, + 96683, + 96717, + 96754, + 96769, + 96799, + 96805, + 96809, + 96823, + 96829, + 96832, + 96850, + 96856, + 96906, + 96962, + 96974, + 96979, + 96997, + 96998, + 97002, + 97054, + 97064, + 97067, + 97110, + 97116, + 97137, + 97138, + 97143, + 97183, + 97187, + 97190, + 97202, + 97219, + 97239, + 97245, + 97246, + 97249, + 97264, + 97267, + 97269, + 97274, + 97282, + 97287, + 97294, + 97299, + 97306, + 97347, + 97361, + 97371, + 97435, + 97466, + 97473, + 97474, + 97559, + 97565, + 97587, + 97611, + 97622, + 97625, + 97632, + 97635, + 97652, + 97672, + 97678, + 97683, + 97695, + 97705, + 97713, + 97719, + 97757, + 97761, + 97762, + 97771, + 97795, + 97809, + 97826, + 97845, + 97877, + 97882, + 97891, + 97903, + 97961, + 97970, + 97975, + 97996, + 98001, + 98014, + 98023, + 98035, + 98052, + 98059, + 98061, + 98086, + 98098, + 98117, + 98118, + 98132, + 98135, + 98145, + 98160, + 98194, + 98205, + 98210, + 98224, + 98227, + 98254, + 98271, + 98272, + 98302, + 98320, + 98346, + 98356, + 98360, + 98366, + 98478, + 98483, + 98486, + 98497, + 98528, + 98537, + 98551, + 98557, + 98572, + 98575, + 98600, + 98628, + 98635, + 98645, + 98652, + 98655, + 98665, + 98710, + 98719, + 98720, + 98786, + 98792, + 98806, + 98816, + 98836, + 98859, + 98864, + 98879, + 98905, + 98917, + 98929, + 98969, + 98975, + 98976, + 98981, + 98999, + 99020, + 99026, + 99054, + 99083, + 99093, + 99103, + 99131, + 99156, + 99159, + 99165, + 99170, + 99189, + 99223, + 99227, + 99271, + 99277, + 99278, + 99313, + 99314, + 99345, + 99361, + 99367, + 99386, + 99394, + 99417, + 99418, + 99453, + 99454, + 99477, + 99518, + 99544, + 99559, + 99592, + 99597, + 99603, + 99621, + 99646, + 99693, + 99722, + 99760, + 99780, + 99789, + 99804, + 99823, + 99826, + 99832, + 99842, + 99851, + 99862, + 99871, + 99899, + 99940, + 99983, + 99985, + 100025, + 100043, + 100070, + 100076, + 100084, + 100096, + 100105, + 100108, + 100123, + 100132, + 100141, + 100181, + 100191, + 100202, + 100216, + 100246, + 100256, + 100271, + 100285, + 100294, + 100305, + 100321, + 100331, + 100334, + 100345, + 100346, + 100369, + 100372, + 100382, + 100403, + 100451, + 100488, + 100499, + 100501, + 100511, + 100536, + 100629, + 100652, + 100655, + 100669, + 100687, + 100692, + 100696, + 100701, + 100706, + 100711, + 100726, + 100754, + 100759, + 100790, + 100838, + 100878, + 100880, + 100885, + 100886, + 100943, + 100948, + 100957, + 100962, + 100968, + 100981, + 100986, + 101001, + 101012, + 101015, + 101019, + 101037, + 101063, + 101105, + 101144, + 101147, + 101154, + 101163, + 101166, + 101173, + 101174, + 101219, + 101240, + 101250, + 101259, + 101273, + 101274, + 101285, + 101300, + 101309, + 101310, + 101321, + 101324, + 101363, + 101366, + 101377, + 101380, + 101389, + 101407, + 101411, + 101432, + 101476, + 101488, + 101494, + 101514, + 101534, + 101537, + 101543, + 101547, + 101584, + 101589, + 101590, + 101629, + 101678, + 101683, + 101700, + 101712, + 101748, + 101757, + 101762, + 101771, + 101785, + 101795, + 101822, + 101851, + 101863, + 101894, + 101903, + 101924, + 101939, + 101980, + 101993, + 101994, + 101996, + 102007, + 102044, + 102086, + 102097, + 102113, + 102123, + 102155, + 102157, + 102169, + 102181, + 102182, + 102185, + 102199, + 102208, + 102213, + 102226, + 102290, + 102296, + 102306, + 102317, + 102337, + 102344, + 102350, + 102378, + 102383, + 102391, + 102400, + 102409, + 102427, + 102434, + 102453, + 102472, + 102502, + 102525, + 102547, + 102554, + 102560, + 102578, + 102580, + 102597, + 102616, + 102625, + 102632, + 102663, + 102669, + 102681, + 102694, + 102706, + 102715, + 102723, + 102730, + 102743, + 102856, + 102870, + 102898, + 102926, + 102931, + 102938, + 102947, + 102968, + 102976, + 102993, + 103005, + 103019, + 103022, + 103057, + 103080, + 103100, + 103106, + 103126, + 103173, + 103202, + 103207, + 103219, + 103226, + 103228, + 103248, + 103274, + 103288, + 103291, + 103293, + 103324, + 103358, + 103372, + 103375, + 103390, + 103414, + 103432, + 103446, + 103455, + 103471, + 103474, + 103476, + 103515, + 103527, + 103542, + 103562, + 103569, + 103572, + 103581, + 103609, + 103612, + 103618, + 103637, + 103644, + 103653, + 103663, + 103671, + 103678, + 103695, + 103698, + 103720, + 103723, + 103738, + 103743, + 103745, + 103757, + 103810, + 103822, + 103855, + 103887, + 103905, + 103915, + 103925, + 103929, + 103945, + 103954, + 103969, + 104011, + 104055, + 104111, + 104116, + 104125, + 104145, + 104162, + 104176, + 104193, + 104199, + 104224, + 104236, + 104247, + 104254, + 104289, + 104325, + 104332, + 104335, + 104353, + 104363, + 104371, + 104373, + 104406, + 104412, + 104440, + 104459, + 104461, + 104469, + 104479, + 104483, + 104490, + 104500, + 104536, + 104560, + 104569, + 104588, + 104591, + 104621, + 104661, + 104675, + 104684, + 104713, + 104747, + 104750, + 104757, + 104775, + 104782, + 104803, + 104820, + 104824, + 104829, + 104830, + 104836, + 104851, + 104882, + 104920, + 104941, + 104963, + 104989, + 104999, + 105006, + 105040, + 105066, + 105089, + 105120, + 105125, + 105137, + 105179, + 105215, + 105244, + 105258, + 105263, + 105280, + 105286, + 105380, + 105397, + 105409, + 105427, + 105452, + 105469, + 105472, + 105477, + 105490, + 105505, + 105529, + 105530, + 105604, + 105614, + 105622, + 105625, + 105652, + 105687, + 105693, + 105707, + 105721, + 105730, + 105736, + 105753, + 105759, + 105760, + 105802, + 105822, + 105832, + 105865, + 105873, + 105874, + 105880, + 105899, + 105902, + 105909, + 105919, + 105922, + 105946, + 105975, + 105992, + 106005, + 106057, + 106081, + 106093, + 106117, + 106127, + 106135, + 106141, + 106189, + 106190, + 106197, + 106214, + 106237, + 106245, + 106257, + 106300, + 106335, + 106351, + 106370, + 106375, + 106376, + 106384, + 106403, + 106405, + 106406, + 106429, + 106447, + 106466, + 106495, + 106532, + 106542, + 106547, + 106564, + 106576, + 106586, + 106592, + 106597, + 106610, + 106612, + 106635, + 106640, + 106673, + 106691, + 106724, + 106731, + 106741, + 106748, + 106765, + 106789, + 106822, + 106856, + 106861, + 106870, + 106883, + 106895, + 106928, + 106938, + 106979, + 106985, + 107005, + 107012, + 107019, + 107045, + 107052, + 107082, + 107089, + 107118, + 107163, + 107202, + 107238, + 107242, + 107244, + 107264, + 107273, + 107291, + 107293, + 107312, + 107318, + 107335, + 107349, + 107350, + 107363, + 107390, + 107405, + 107408, + 107427, + 107433, + 107444, + 107514, + 107522, + 107545, + 107582, + 107590, + 107593, + 107599, + 107604, + 107608, + 107627, + 107638, + 107666, + 107678, + 107701, + 107720, + 107723, + 107725, + 107731, + 107737, + 107767, + 107779, + 107788, + 107799, + 107819, + 107833, + 107881, + 107901, + 107911, + 107930, + 107936, + 107980, + 108004, + 108008, + 108016, + 108066, + 108071, + 108107, + 108110, + 108124, + 108145, + 108148, + 108158, + 108164, + 108197, + 108198, + 108219, + 108222, + 108224, + 108227, + 108290, + 108302, + 108329, + 108335, + 108338, + 108362, + 108398, + 108405, + 108409, + 108431, + 108449, + 108474, + 108488, + 108530, + 108545, + 108551, + 108558, + 108585, + 108613, + 108638, + 108642, + 108653, + 108671, + 108675, + 108684, + 108687, + 108696, + 108786, + 108792, + 108795, + 108818, + 108830, + 108836, + 108839, + 108851, + 108875, + 108883, + 108895, + 108908, + 108953, + 108956, + 108963, + 108989, + 109001, + 109009, + 109052, + 109083, + 109090, + 109104, + 109121, + 109128, + 109141, + 109146, + 109155, + 109162, + 109209, + 109216, + 109243, + 109265, + 109282, + 109306, + 109316, + 109334, + 109359, + 109373, + 109386, + 109394, + 109403, + 109409, + 109412, + 109427, + 109439, + 109464, + 109467, + 109476, + 109488, + 109497, + 109523, + 109551, + 109556, + 109566, + 109598, + 109628, + 109643, + 109663, + 109674, + 109688, + 109691, + 109704, + 109715, + 109717, + 109746, + 109789, + 109794, + 109868, + 109886, + 109888, + 109903, + 109908, + 109912, + 109927, + 109936, + 109979, + 110005, + 110010, + 110017, + 110041, + 110042, + 110047, + 110048, + 110053, + 110054, + 110057, + 110091, + 110093, + 110112, + 110127, + 110178, + 110183, + 110184, + 110195, + 110307, + 110334, + 110336, + 110354, + 110356, + 110390, + 110419, + 110452, + 110461, + 110465, + 110466, + 110468, + 110486, + 110511, + 110531, + 110561, + 110573, + 110593, + 110611, + 110614, + 110651, + 110661, + 110665, + 110701, + 110730, + 110735, + 110738, + 110759, + 110763, + 110768, + 110774, + 110783, + 110785, + 110809, + 110812, + 110840, + 110853, + 110905, + 110933, + 110961, + 110962, + 110974, + 110987, + 110989, + 111007, + 111011, + 111043, + 111070, + 111088, + 111127, + 111140, + 111149, + 111229, + 111230, + 111243, + 111267, + 111287, + 111313, + 111356, + 111368, + 111409, + 111419, + 111430, + 111433, + 111442, + 111467, + 111491, + 111503, + 111527, + 111531, + 111541, + 111546, + 111548, + 111577, + 111625, + 111636, + 111650, + 111655, + 111662, + 111673, + 111699, + 111727, + 111729, + 111741, + 111757, + 111781, + 111791, + 111826, + 111838, + 111854, + 111861, + 111866, + 111868, + 111897, + 111903, + 111904, + 111959, + 111975, + 112018, + 112023, + 112033, + 112036, + 112043, + 112095, + 112113, + 112136, + 112153, + 112165, + 112166, + 112177, + 112189, + 112226, + 112237, + 112240, + 112255, + 112265, + 112280, + 112292, + 112307, + 112316, + 112342, + 112345, + 112351, + 112361, + 112364, + 112372, + 112382, + 112389, + 112408, + 112417, + 112423, + 112476, + 112480, + 112483, + 112513, + 112538, + 112543, + 112574, + 112599, + 112605, + 112667, + 112688, + 112735, + 112746, + 112810, + 112817, + 112827, + 112835, + 112892, + 112898, + 112915, + 112918, + 112937, + 112940, + 112958, + 113013, + 113014, + 113027, + 113048, + 113051, + 113053, + 113102, + 113104, + 113114, + 113130, + 113159, + 113180, + 113189, + 113211, + 113245, + 113261, + 113273, + 113292, + 113314, + 113319, + 113323, + 113326, + 113337, + 113338, + 113355, + 113365, + 113376, + 113408, + 113462, + 113476, + 113503, + 113550, + 113578, + 113580, + 113634, + 113653, + 113677, + 113713, + 113751, + 113771, + 113781, + 113797, + 113846, + 113849, + 113855, + 113878, + 113884, + 113926, + 113938, + 113956, + 113980, + 113986, + 113991, + 114005, + 114022, + 114036, + 114046, + 114050, + 114061, + 114067, + 114117, + 114142, + 114158, + 114165, + 114200, + 114219, + 114254, + 114265, + 114272, + 114312, + 114318, + 114348, + 114377, + 114383, + 114386, + 114431, + 114448, + 114479, + 114487, + 114513, + 114542, + 114572, + 114584, + 114600, + 114605, + 114623, + 114628, + 114640, + 114650, + 114668, + 114671, + 114674, + 114700, + 114731, + 114748, + 114759, + 114766, + 114768, + 114784, + 114808, + 114813, + 114829, + 114830, + 114842, + 114875, + 114898, + 114903, + 114913, + 114928, + 114937, + 114958, + 114963, + 115000, + 115018, + 115023, + 115028, + 115042, + 115084, + 115096, + 115105, + 115117, + 115149, + 115155, + 115198, + 115221, + 115222, + 115225, + 115276, + 115294, + 115297, + 115321, + 115348, + 115364, + 115376, + 115385, + 115386, + 115400, + 115414, + 115465, + 115485, + 115492, + 115501, + 115519, + 115527, + 115531, + 115567, + 115572, + 115631, + 115648, + 115660, + 115672, + 115681, + 115688, + 115694, + 115699, + 115719, + 115726, + 115733, + 115796, + 115879, + 115880, + 115888, + 115908, + 115925, + 115942, + 115978, + 115986, + 116014, + 116019, + 116031, + 116048, + 116069, + 116091, + 116103, + 116107, + 116145, + 116152, + 116247, + 116289, + 116316, + 116344, + 116354, + 116368, + 116377, + 116383, + 116387, + 116408, + 116428, + 116445, + 116476, + 116482, + 116488, + 116493, + 116502, + 116518, + 116524, + 116527, + 116549, + 116561, + 116562, + 116568, + 116577, + 116590, + 116602, + 116607, + 116611, + 116626, + 116637, + 116647, + 116665, + 116674, + 116700, + 116714, + 116719, + 116744, + 116764, + 116774, + 116778, + 116798, + 116803, + 116806, + 116827, + 116839, + 116863, + 116873, + 116882, + 116887, + 116915, + 116939, + 116944, + 116953, + 116965, + 117002, + 117007, + 117015, + 117032, + 117035, + 117052, + 117087, + 117139, + 117157, + 117193, + 117211, + 117214, + 117220, + 117238, + 117248, + 117275, + 117293, + 117301, + 117319, + 117338, + 117347, + 117361, + 117380, + 117389, + 117398, + 117435, + 117458, + 117476, + 117498, + 117500, + 117529, + 117554, + 117556, + 117565, + 117580, + 117585, + 117592, + 117597, + 117616, + 117637, + 117644, + 117659, + 117703, + 117704, + 117727, + 117738, + 117770, + 117796, + 117799, + 117820, + 117832, + 117840, + 117843, + 117865, + 117868, + 117874, + 117886, + 117962, + 117967, + 117995, + 118000, + 118017, + 118037, + 118038, + 118051, + 118057, + 118072, + 118080, + 118098, + 118107, + 118109, + 118114, + 118123, + 118150, + 118159, + 118164, + 118173, + 118201, + 118212, + 118246, + 118257, + 118303, + 118310, + 118313, + 118324, + 118334, + 118336, + 118339, + 118353, + 118354, + 118390, + 118396, + 118436, + 118453, + 118466, + 118492, + 118506, + 118525, + 118557, + 118561, + 118586, + 118606, + 118627, + 118641, + 118654, + 118687, + 118688, + 118735, + 118737, + 118750, + 118773, + 118778, + 118786, + 118809, + 118833, + 118853, + 118854, + 118863, + 118881, + 118896, + 118917, + 118921, + 118939, + 118948, + 118960, + 118970, + 118983, + 119025, + 119026, + 119064, + 119069, + 119079, + 119085, + 119115, + 119165, + 119166, + 119193, + 119194, + 119199, + 119215, + 119218, + 119241, + 119277, + 119301, + 119306, + 119335, + 119344, + 119364, + 119373, + 119382, + 119410, + 119425, + 119459, + 119473, + 119486, + 119500, + 119508, + 119511, + 119517, + 119528, + 119533, + 119539, + 119542, + 119546, + 119566, + 119587, + 119590, + 119607, + 119614, + 119625, + 119633, + 119634, + 119643, + 119683, + 119704, + 119710, + 119734, + 119752, + 119760, + 119826, + 119922, + 119931, + 119977, + 120015, + 120020, + 120083, + 120086, + 120101, + 120105, + 120155, + 120188, + 120195, + 120216, + 120228, + 120238, + 120255, + 120317, + 120327, + 120369, + 120382, + 120404, + 120414, + 120432, + 120435, + 120454, + 120463, + 120471, + 120505, + 120528, + 120588, + 120616, + 120630, + 120644, + 120672, + 120677, + 120718, + 120725, + 120730, + 120756, + 120759, + 120765, + 120795, + 120821, + 120850, + 120868, + 120880, + 120885, + 120892, + 120897, + 120912, + 120934, + 120991, + 121004, + 121021, + 121022, + 121036, + 121041, + 121069, + 121078, + 121126, + 121135, + 121138, + 121162, + 121176, + 121186, + 121209, + 121212, + 121221, + 121225, + 121228, + 121239, + 121245, + 121264, + 121270, + 121299, + 121306, + 121315, + 121317, + 121321, + 121324, + 121330, + 121339, + 121346, + 121370, + 121372, + 121393, + 121396, + 121414, + 121442, + 121475, + 121499, + 121512, + 121518, + 121588, + 121597, + 121612, + 121629, + 121630, + 121634, + 121680, + 121725, + 121798, + 121815, + 121822, + 121837, + 121840, + 121869, + 121878, + 121897, + 121920, + 121929, + 121944, + 121999, + 122008, + 122056, + 122062, + 122067, + 122083, + 122095, + 122110, + 122118, + 122127, + 122189, + 122207, + 122226, + 122253, + 122301, + 122324, + 122337, + 122362, + 122368, + 122371, + 122378, + 122404, + 122443, + 122451, + 122457, + 122458, + 122479, + 122484, + 122521, + 122540, + 122545, + 122552, + 122560, + 122575, + 122578, + 122605, + 122661, + 122673, + 122722, + 122728, + 122739, + 122751, + 122762, + 122769, + 122772, + 122782, + 122798, + 122810, + 122812, + 122818, + 122829, + 122851, + 122857, + 122868, + 122893, + 122894, + 122902, + 122921, + 122959, + 122984, + 123001, + 123038, + 123076, + 123100, + 123107, + 123122, + 123139, + 123175, + 123190, + 123201, + 123219, + 123232, + 123255, + 123285, + 123328, + 123385, + 123397, + 123404, + 123419, + 123435, + 123437, + 123443, + 123500, + 123506, + 123511, + 123512, + 123518, + 123522, + 123545, + 123572, + 123587, + 123594, + 123607, + 123608, + 123630, + 123635, + 123659, + 123692, + 123695, + 123700, + 123730, + 123748, + 123751, + 123770, + 123793, + 123800, + 123803, + 123851, + 123859, + 123866, + 123868, + 123877, + 123884, + 123909, + 123910, + 123919, + 123927, + 123937, + 123950, + 123957, + 123979, + 123996, + 124040, + 124054, + 124063, + 124067, + 124088, + 124101, + 124154, + 124162, + 124167, + 124176, + 124195, + 124230, + 124267, + 124346, + 124389, + 124418, + 124420, + 124454, + 124490, + 124503, + 124519, + 124533, + 124544, + 124589, + 124616, + 124630, + 124636, + 124645, + 124652, + 124663, + 124667, + 124690, + 124755, + 124757, + 124819, + 124862, + 124864, + 124874, + 124882, + 124903, + 124915, + 124938, + 124945, + 124973, + 124986, + 124991, + 125011, + 125014, + 125082, + 125105, + 125163, + 125165, + 125205, + 125219, + 125239, + 125240, + 125257, + 125284, + 125302, + 125327, + 125336, + 125355, + 125363, + 125365, + 125372, + 125378, + 125383, + 125387, + 125390, + 125414, + 125435, + 125466, + 125481, + 125522, + 125531, + 125544, + 125564, + 125588, + 125602, + 125613, + 125621, + 125648, + 125651, + 125681, + 125719, + 125773, + 125774, + 125779, + 125786, + 125792, + 125822, + 125828, + 125831, + 125837, + 125880, + 125891, + 125922, + 125928, + 125931, + 125941, + 125948, + 125960, + 125973, + 126014, + 126016, + 126036, + 126043, + 126062, + 126076, + 126116, + 126125, + 126145, + 126152, + 126175, + 126188, + 126199, + 126205, + 126213, + 126220, + 126286, + 126294, + 126300, + 126322, + 126324, + 126343, + 126344, + 126430, + 126433, + 126448, + 126451, + 126457, + 126458, + 126463, + 126470, + 126484, + 126518, + 126521, + 126547, + 126556, + 126583, + 126584, + 126633, + 126673, + 126680, + 126686, + 126689, + 126702, + 126710, + 126722, + 126787, + 126789, + 126794, + 126801, + 126857, + 126891, + 126896, + 126902, + 126911, + 126919, + 126943, + 126947, + 126949, + 126953, + 126971, + 126976, + 126982, + 127009, + 127021, + 127027, + 127039, + 127041, + 127044, + 127059, + 127071, + 127075, + 127126, + 127129, + 127145, + 127154, + 127165, + 127171, + 127197, + 127198, + 127207, + 127226, + 127240, + 127254, + 127269, + 127305, + 127323, + 127342, + 127347, + 127363, + 127394, + 127426, + 127432, + 127440, + 127462, + 127468, + 127473, + 127486, + 127502, + 127510, + 127523, + 127543, + 127567, + 127570, + 127585, + 127588, + 127619, + 127621, + 127626, + 127628, + 127640, + 127662, + 127684, + 127687, + 127693, + 127696, + 127708, + 127711, + 127722, + 127732, + 127747, + 127767, + 127771, + 127790, + 127816, + 127824, + 127833, + 127869, + 127910, + 127928, + 127933, + 127963, + 127975, + 128016, + 128031, + 128059, + 128074, + 128107, + 128122, + 128157, + 128161, + 128200, + 128213, + 128229, + 128233, + 128241, + 128259, + 128295, + 128299, + 128313, + 128345, + 128362, + 128375, + 128376, + 128406, + 128410, + 128416, + 128443, + 128451, + 128465, + 128466, + 128484, + 128499, + 128502, + 128524, + 128536, + 128541, + 128542, + 128592, + 128598, + 128623, + 128632, + 128671, + 128713, + 128724, + 128731, + 128761, + 128767, + 128782, + 128793, + 128805, + 128820, + 128830, + 128842, + 128852, + 128859, + 128866, + 128875, + 128892, + 128896, + 128914, + 128935, + 128964, + 128973, + 129001, + 129007, + 129012, + 129021, + 129026, + 129055, + 129071, + 129093, + 129105, + 129124, + 129148, + 129151, + 129155, + 129161, + 129200, + 129224, + 129230, + 129237, + 129298, + 129300, + 129316, + 129345, + 129351, + 129352, + 129363, + 129393, + 129410, + 129415, + 129449, + 129477, + 129501, + 129518, + 129520, + 129545, + 129563, + 129594, + 129608, + 129616, + 129652, + 129659, + 129680, + 129692, + 129738, + 129764, + 129782, + 129793, + 129820, + 129824, + 129829, + 129848, + 129854, + 129861, + 129879, + 129886, + 129907, + 129949, + 129953, + 129980, + 129998, + 130031, + 130043, + 130057, + 130065, + 130087, + 130091, + 130096, + 130101, + 130111, + 130126, + 130137, + 130138, + 130149, + 130177, + 130180, + 130214, + 130228, + 130240, + 130267, + 130280, + 130294, + 130306, + 130325, + 130398, + 130402, + 130421, + 130438, + 130441, + 130475, + 130486, + 130503, + 130551, + 130574, + 130602, + 130612, + 130621, + 130633, + 130684, + 130688, + 130698, + 130700, + 130712, + 130739, + 130748, + 130774, + 130783, + 130802, + 130811, + 130836, + 130840, + 130856, + 130864, + 130873, + 130918, + 130927, + 130929, + 130958, + 130966, + 130970, + 130976, + 131006, + 131008, + 131020, + 131059, + -1 + }; + //#endif + + /*! You can access the following array as in PrimitivePolynomials[i][j] + with i and j counting from 0 in C convention. PrimitivePolynomials[i][j] + will get you the j-th (counting from zero) primitive polynomial of degree + i+1. Each one-dimensional array of primitive polynomials of a given + degree is terminated with an entry of -1. Accessing beyond this entry + will result in a memory violation and must be avoided. */ + public static long[][] PrimitivePolynomials { get { return PrimitivePolynomials_; } } + private static long[][] PrimitivePolynomials_ = new long[N_MAX_DEGREE][] + { + PrimitivePolynomialDegree01 + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_01 + , PrimitivePolynomialDegree02 + //#endif + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_02 + , PrimitivePolynomialDegree03 + //#endif + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_03 + , PrimitivePolynomialDegree04 + //#endif + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_04 + , PrimitivePolynomialDegree05 + //#endif + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_05 + , PrimitivePolynomialDegree06 + //#endif + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_06 + , PrimitivePolynomialDegree07 + //#endif + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_07 + , PrimitivePolynomialDegree08 + //#endif + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_08 + , PrimitivePolynomialDegree09 + //#endif + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_09 + , PrimitivePolynomialDegree10 + //#endif + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_10 + , PrimitivePolynomialDegree11 + //#endif + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_11 + , PrimitivePolynomialDegree12 + //#endif + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_12 + , PrimitivePolynomialDegree13 + //#endif + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_13 + , PrimitivePolynomialDegree14 + //#endif + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_14 + , PrimitivePolynomialDegree15 + //#endif + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_15 + , PrimitivePolynomialDegree16 + //#endif + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_16 + , PrimitivePolynomialDegree17 + //#endif + //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_17 + , PrimitivePolynomialDegree18 + //#endif + }; + + } + +#endif + + +} diff --git a/src/QLNet/Math/randomnumbers/RNGTraits.cs b/src/QLNet/Math/randomnumbers/RNGTraits.cs new file mode 100644 index 000000000..3df27a4e4 --- /dev/null +++ b/src/QLNet/Math/randomnumbers/RNGTraits.cs @@ -0,0 +1,115 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +namespace QLNet +{ + public interface IRNGTraits + { + ulong nextInt32(); + Sample next(); + + IRNGTraits factory(ulong seed); + } + + public interface IRSG + { + int allowsErrorEstimate { get; } + object make_sequence_generator(int dimension, ulong seed); + } + + // random number traits + public class GenericPseudoRandom : IRSG where URNG : IRNGTraits, new () where IC : IValue, new () + { + // data + private static IC icInstance_ = FastActivator.Create(); + + // more traits + public int allowsErrorEstimate + { + get + { + return 1; + } + } + + public static IC icInstance + { + get + { + return icInstance_; + } + set + { + icInstance_ = value; + } + } + + // factory + public object make_sequence_generator(int dimension, ulong seed) + { + RandomSequenceGenerator g = new RandomSequenceGenerator(dimension, seed); + return (icInstance_ != null + ? new InverseCumulativeRsg, IC>(g, icInstance_) + : new InverseCumulativeRsg, IC>(g)); + } + } + + //! default traits for pseudo-random number generation + /*! \test a sequence generator is generated and tested by comparing samples against known good values. */ + public class PseudoRandom : GenericPseudoRandom { } + + //! traits for Poisson-distributed pseudo-random number generation + /*! \test sequence generators are generated and tested by comparing + samples against known good values. + */ + public class PoissonPseudoRandom : GenericPseudoRandom { } + + + public class GenericLowDiscrepancy : IRSG where URSG : IRNG, new () where IC : IValue, new () + { + // data + private static IC icInstance_ = FastActivator.Create(); + public static IC icInstance + { + get + { + return icInstance_; + } + set + { + icInstance_ = value; + } + } + + + // more traits + public int allowsErrorEstimate { get { return 0; } } + + // factory + public object make_sequence_generator(int dimension, ulong seed) + { + URSG g = (URSG)FastActivator.Create().factory(dimension, seed); + return (icInstance != null ? new InverseCumulativeRsg(g, icInstance) + : new InverseCumulativeRsg(g)); + } + } + + //! default traits for low-discrepancy sequence generation + public class LowDiscrepancy : GenericLowDiscrepancy { } +} diff --git a/src/QLNet/Math/randomnumbers/RandomSequenceGenerator.cs b/src/QLNet/Math/randomnumbers/RandomSequenceGenerator.cs new file mode 100644 index 000000000..01f5a3e9c --- /dev/null +++ b/src/QLNet/Math/randomnumbers/RandomSequenceGenerator.cs @@ -0,0 +1,98 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + public interface IRNG + { + int dimension(); + Sample> nextSequence(); + Sample> lastSequence(); + + IRNG factory(int dimensionality, ulong seed); + } + + /*! Random sequence generator based on a pseudo-random number generator RNG. + Do not use with low-discrepancy sequence generator. + */ + public class RandomSequenceGenerator : IRNG where RNG : IRNGTraits, new () + { + private int dimensionality_; + + private RNG rng_; + private Sample> sequence_; + private List int32Sequence_; + + public RandomSequenceGenerator(int dimensionality, RNG rng) + { + dimensionality_ = dimensionality; + rng_ = rng; + + List ls = new List(); + for (int i = 0; i < dimensionality; i++) + ls.Add(0.0); + sequence_ = new Sample>(ls, 1.0); + int32Sequence_ = new InitializedList(dimensionality); + + Utils.QL_REQUIRE(dimensionality > 0, () => "dimensionality must be greater than 0"); + } + + public RandomSequenceGenerator(int dimensionality, ulong seed) + { + dimensionality_ = dimensionality; + rng_ = (RNG)FastActivator.Create().factory(seed); + sequence_ = new Sample>(new InitializedList(dimensionality), 1.0); + int32Sequence_ = new InitializedList(dimensionality); + } + + public List nextInt32Sequence() + { + for (int i = 0; i < dimensionality_; i++) + { + int32Sequence_[i] = rng_.nextInt32(); + } + return int32Sequence_; + } + + #region IRGN interface + public Sample> nextSequence() + { + sequence_.weight = 1.0; + for (int i = 0; i < dimensionality_; i++) + { + Sample x = rng_.next(); + sequence_.value[i] = x.value; + sequence_.weight *= x.weight; + } + return sequence_; + } + + public Sample> lastSequence() { return sequence_; } + + public int dimension() { return dimensionality_; } + + public IRNG factory(int dimensionality, ulong seed) + { + return new RandomSequenceGenerator(dimensionality, seed); + } + #endregion + } +} diff --git a/src/QLNet/Math/randomnumbers/SeedGenerator.cs b/src/QLNet/Math/randomnumbers/SeedGenerator.cs new file mode 100644 index 000000000..84ec26bb3 --- /dev/null +++ b/src/QLNet/Math/randomnumbers/SeedGenerator.cs @@ -0,0 +1,70 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + //! Random seed generator + /*! Random number generator used for automatic generation of initialization seeds. */ + public class SeedGenerator + { + private MersenneTwisterUniformRng rng_; + + private static readonly SeedGenerator instance_ = new SeedGenerator(); + private SeedGenerator() + { + rng_ = new MersenneTwisterUniformRng(42UL); + initialize(); + } + + public ulong get() + { + return rng_.nextInt32(); + } + + public static SeedGenerator instance() { return instance_; } + + private void initialize() + { + // firstSeed is chosen based on clock() and used for the first rng + ulong firstSeed = (ulong)DateTime.Now.Ticks; + MersenneTwisterUniformRng first = new MersenneTwisterUniformRng(firstSeed); + + // secondSeed is as random as it could be + // feel free to suggest improvements + ulong secondSeed = first.nextInt32(); + + MersenneTwisterUniformRng second = new MersenneTwisterUniformRng(secondSeed); + + // use the second rng to initialize the final one + ulong skip = second.nextInt32() % 1000; + List init = new InitializedList(4); + init[0] = second.nextInt32(); + init[1] = second.nextInt32(); + init[2] = second.nextInt32(); + init[3] = second.nextInt32(); + + rng_ = new MersenneTwisterUniformRng(init); + + for (ulong i = 0; i < skip ; i++) + rng_.nextInt32(); + } + } +} diff --git a/src/QLNet/Math/randomnumbers/SobolBrownianBridgeRsg.cs b/src/QLNet/Math/randomnumbers/SobolBrownianBridgeRsg.cs index 580b7ada1..fb786a75e 100644 --- a/src/QLNet/Math/randomnumbers/SobolBrownianBridgeRsg.cs +++ b/src/QLNet/Math/randomnumbers/SobolBrownianBridgeRsg.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,8 +29,8 @@ public SobolBrownianBridgeRsg(int factors, int steps, { factors_ = factors; steps_ = steps; - dim_ = factors*steps; - seq_ = new Sample>(new InitializedList(factors*steps), 1.0) ; + dim_ = factors * steps; + seq_ = new Sample>(new InitializedList(factors * steps), 1.0) ; gen_ = new SobolBrownianGenerator(factors, steps, ordering, seed, directionIntegers); } @@ -38,16 +38,16 @@ public Sample> nextSequence() { gen_.nextPath(); List output = new InitializedList(factors_); - for (int i=0; i < steps_; ++i) + for (int i = 0; i < steps_; ++i) { gen_.nextStep(output); - for ( int j = 0; j < output.Count ; j++) + for (int j = 0; j < output.Count ; j++) { - seq_.value[j + i*factors_] = output[j]; + seq_.value[j + i * factors_] = output[j]; } - } + } - return seq_; + return seq_; } public Sample> lastSequence() {return seq_;} public IRNG factory(int dimensionality, ulong seed) diff --git a/src/QLNet/Math/randomnumbers/sobolrsg.cs b/src/QLNet/Math/randomnumbers/SobolRsg.cs similarity index 73% rename from src/QLNet/Math/randomnumbers/sobolrsg.cs rename to src/QLNet/Math/randomnumbers/SobolRsg.cs index ce838190a..3fce7f7cf 100644 --- a/src/QLNet/Math/randomnumbers/sobolrsg.cs +++ b/src/QLNet/Math/randomnumbers/SobolRsg.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -96,9 +96,9 @@ their discrepancy against known good values. */ public partial class SobolRsg : IRNG { - const int bits_ = 8 * sizeof( int ); + const int bits_ = 8 * sizeof(int); // 1/(2^bits_) (written as (1/2)/(2^(bits_-1)) to avoid long overflow) - const double normalizationFactor_ = 0.5 / ( 1UL << ( bits_ - 1 ) ); + const double normalizationFactor_ = 0.5 / (1UL << (bits_ - 1)); private int dimensionality_; private ulong sequenceCounter_; @@ -112,42 +112,42 @@ public enum DirectionIntegers Unit, Jaeckel, SobolLevitan, SobolLevitanLemieux, JoeKuoD5, JoeKuoD6, JoeKuoD7, Kuo, Kuo2, Kuo3 - }; + } // required for generics public SobolRsg() { } /*! \pre dimensionality must be <= PPMT_MAX_DIM */ - public SobolRsg( int dimensionality ) : this( dimensionality, 0, DirectionIntegers.Jaeckel ) { } - public SobolRsg( int dimensionality, ulong seed ) : this( dimensionality, seed, DirectionIntegers.Jaeckel ) { } - public SobolRsg( int dimensionality, ulong seed, DirectionIntegers directionIntegers ) + public SobolRsg(int dimensionality) : this(dimensionality, 0, DirectionIntegers.Jaeckel) { } + public SobolRsg(int dimensionality, ulong seed) : this(dimensionality, seed, DirectionIntegers.Jaeckel) { } + public SobolRsg(int dimensionality, ulong seed, DirectionIntegers directionIntegers) { dimensionality_ = dimensionality; sequenceCounter_ = 0; firstDraw_ = true; - sequence_ = new Sample>( new InitializedList( dimensionality ), 1.0 ); - integerSequence_ = new InitializedList( dimensionality ); + sequence_ = new Sample>(new InitializedList(dimensionality), 1.0); + integerSequence_ = new InitializedList(dimensionality); - directionIntegers_ = new InitializedList>( dimensionality ); - for ( int i = 0; i < dimensionality; i++ ) - directionIntegers_[i] = new InitializedList( bits_ ); + directionIntegers_ = new InitializedList>(dimensionality); + for (int i = 0; i < dimensionality; i++) + directionIntegers_[i] = new InitializedList(bits_); - Utils.QL_REQUIRE( dimensionality > 0 ,()=> "dimensionality must be greater than 0" ); - Utils.QL_REQUIRE( dimensionality <= PPMT_MAX_DIM,()=> - "dimensionality " + dimensionality + " exceeds the number of available " + - "primitive polynomials modulo two (" + PPMT_MAX_DIM + ")" ); + Utils.QL_REQUIRE(dimensionality > 0, () => "dimensionality must be greater than 0"); + Utils.QL_REQUIRE(dimensionality <= PPMT_MAX_DIM, () => + "dimensionality " + dimensionality + " exceeds the number of available " + + "primitive polynomials modulo two (" + PPMT_MAX_DIM + ")"); // initializes coefficient array of the k-th primitive polynomial // and degree of the k-th primitive polynomial - List degree = new InitializedList( dimensionality_ ); - List ppmt = new InitializedList( dimensionality_ ); + List degree = new InitializedList(dimensionality_); + List ppmt = new InitializedList(dimensionality_); bool useAltPolynomials = false; - if ( directionIntegers == DirectionIntegers.Kuo || directionIntegers == DirectionIntegers.Kuo2 + if (directionIntegers == DirectionIntegers.Kuo || directionIntegers == DirectionIntegers.Kuo2 || directionIntegers == DirectionIntegers.Kuo3 || directionIntegers == DirectionIntegers.SobolLevitan - || directionIntegers == DirectionIntegers.SobolLevitanLemieux ) + || directionIntegers == DirectionIntegers.SobolLevitanLemieux) useAltPolynomials = true; // degree 0 is not used @@ -160,10 +160,10 @@ public SobolRsg( int dimensionality, ulong seed, DirectionIntegers directionInte uint altDegree = useAltPolynomials ? maxAltDegree : 0; - for ( ; k < Math.Min( dimensionality_, altDegree ); k++, index++ ) + for (; k < Math.Min(dimensionality_, altDegree); k++, index++) { ppmt[k] = AltPrimitivePolynomials[currentDegree - 1][index]; - if ( ppmt[k] == -1 ) + if (ppmt[k] == -1) { ++currentDegree; index = 0; @@ -173,10 +173,10 @@ public SobolRsg( int dimensionality, ulong seed, DirectionIntegers directionInte degree[k] = currentDegree; } - for ( ; k < dimensionality_; k++, index++ ) + for (; k < dimensionality_; k++, index++) { ppmt[k] = PrimitivePolynomials[currentDegree - 1][index]; - if ( ppmt[k] == -1 ) + if (ppmt[k] == -1) { ++currentDegree; index = 0; @@ -196,36 +196,36 @@ public SobolRsg( int dimensionality, ulong seed, DirectionIntegers directionInte // degenerate (no free direction integers) first dimension int j; - for ( j = 0; j < bits_; j++ ) - directionIntegers_[0][j] = ( 1UL << ( bits_ - j - 1 ) ); + for (j = 0; j < bits_; j++) + directionIntegers_[0][j] = (1UL << (bits_ - j - 1)); int maxTabulated = 0; // dimensions from 2 (k=1) to maxTabulated (k=maxTabulated-1) included // are initialized from tabulated coefficients - switch ( directionIntegers ) + switch (directionIntegers) { case DirectionIntegers.Unit: maxTabulated = dimensionality_; - for ( k = 1; k < maxTabulated; k++ ) + for (k = 1; k < maxTabulated; k++) { - for ( int l = 1; l <= degree[k]; l++ ) + for (int l = 1; l <= degree[k]; l++) { directionIntegers_[k][l - 1] = 1UL; - directionIntegers_[k][l - 1] <<= ( bits_ - l ); + directionIntegers_[k][l - 1] <<= (bits_ - l); } } break; case DirectionIntegers.Jaeckel: // maxTabulated=32 maxTabulated = initializers.Length + 1; - for ( k = 1; k < Math.Min( dimensionality_, maxTabulated ); k++ ) + for (k = 1; k < Math.Min(dimensionality_, maxTabulated); k++) { j = 0; // 0UL marks coefficients' end for a given dimension - while ( initializers[k - 1][j] != 0UL ) + while (initializers[k - 1][j] != 0UL) { directionIntegers_[k][j] = initializers[k - 1][j]; - directionIntegers_[k][j] <<= ( bits_ - j - 1 ); + directionIntegers_[k][j] <<= (bits_ - j - 1); j++; } } @@ -233,14 +233,14 @@ public SobolRsg( int dimensionality, ulong seed, DirectionIntegers directionInte case DirectionIntegers.SobolLevitan: // maxTabulated=40 maxTabulated = SLinitializers.Length + 1; - for ( k = 1; k < Math.Min( dimensionality_, maxTabulated ); k++ ) + for (k = 1; k < Math.Min(dimensionality_, maxTabulated); k++) { j = 0; // 0UL marks coefficients' end for a given dimension - while ( SLinitializers[k - 1][j] != 0UL ) + while (SLinitializers[k - 1][j] != 0UL) { directionIntegers_[k][j] = SLinitializers[k - 1][j]; - directionIntegers_[k][j] <<= ( bits_ - j - 1 ); + directionIntegers_[k][j] <<= (bits_ - j - 1); j++; } } @@ -248,14 +248,14 @@ public SobolRsg( int dimensionality, ulong seed, DirectionIntegers directionInte case DirectionIntegers.SobolLevitanLemieux: // maxTabulated=360 maxTabulated = Linitializers.Length + 1; - for ( k = 1; k < Math.Min( dimensionality_, maxTabulated ); k++ ) + for (k = 1; k < Math.Min(dimensionality_, maxTabulated); k++) { j = 0; // 0UL marks coefficients' end for a given dimension - while ( Linitializers[k - 1][j] != 0UL ) + while (Linitializers[k - 1][j] != 0UL) { directionIntegers_[k][j] = Linitializers[k - 1][j]; - directionIntegers_[k][j] <<= ( bits_ - j - 1 ); + directionIntegers_[k][j] <<= (bits_ - j - 1); j++; } } @@ -263,14 +263,14 @@ public SobolRsg( int dimensionality, ulong seed, DirectionIntegers directionInte case DirectionIntegers.JoeKuoD5: // maxTabulated=1898 maxTabulated = JoeKuoD5initializers.Length + 1; - for ( k = 1; k < Math.Min( dimensionality_, maxTabulated ); k++ ) + for (k = 1; k < Math.Min(dimensionality_, maxTabulated); k++) { j = 0; // 0UL marks coefficients' end for a given dimension - while ( JoeKuoD5initializers[k - 1][j] != 0UL ) + while (JoeKuoD5initializers[k - 1][j] != 0UL) { directionIntegers_[k][j] = JoeKuoD5initializers[k - 1][j]; - directionIntegers_[k][j] <<= ( bits_ - j - 1 ); + directionIntegers_[k][j] <<= (bits_ - j - 1); j++; } } @@ -278,14 +278,14 @@ public SobolRsg( int dimensionality, ulong seed, DirectionIntegers directionInte case DirectionIntegers.JoeKuoD6: // maxTabulated=1799 maxTabulated = JoeKuoD6initializers.Length + 1; - for ( k = 1; k < Math.Min( dimensionality_, maxTabulated ); k++ ) + for (k = 1; k < Math.Min(dimensionality_, maxTabulated); k++) { j = 0; // 0UL marks coefficients' end for a given dimension - while ( JoeKuoD6initializers[k - 1][j] != 0UL ) + while (JoeKuoD6initializers[k - 1][j] != 0UL) { directionIntegers_[k][j] = JoeKuoD6initializers[k - 1][j]; - directionIntegers_[k][j] <<= ( bits_ - j - 1 ); + directionIntegers_[k][j] <<= (bits_ - j - 1); j++; } } @@ -293,14 +293,14 @@ public SobolRsg( int dimensionality, ulong seed, DirectionIntegers directionInte case DirectionIntegers.JoeKuoD7: // maxTabulated=1898 maxTabulated = JoeKuoD7initializers.Length + 1; - for ( k = 1; k < Math.Min( dimensionality_, maxTabulated ); k++ ) + for (k = 1; k < Math.Min(dimensionality_, maxTabulated); k++) { j = 0; // 0UL marks coefficients' end for a given dimension - while ( JoeKuoD7initializers[k - 1][j] != 0UL ) + while (JoeKuoD7initializers[k - 1][j] != 0UL) { directionIntegers_[k][j] = JoeKuoD7initializers[k - 1][j]; - directionIntegers_[k][j] <<= ( bits_ - j - 1 ); + directionIntegers_[k][j] <<= (bits_ - j - 1); j++; } } @@ -311,14 +311,14 @@ public SobolRsg( int dimensionality, ulong seed, DirectionIntegers directionInte case DirectionIntegers.Kuo: // maxTabulated=4925 maxTabulated = Kuoinitializers.Length + 1; - for ( k = 1; k < Math.Min( dimensionality_, maxTabulated ); k++ ) + for (k = 1; k < Math.Min(dimensionality_, maxTabulated); k++) { j = 0; // 0UL marks coefficients' end for a given dimension - while ( Kuoinitializers[k - 1][j] != 0UL ) + while (Kuoinitializers[k - 1][j] != 0UL) { directionIntegers_[k][j] = Kuoinitializers[k - 1][j]; - directionIntegers_[k][j] <<= ( bits_ - j - 1 ); + directionIntegers_[k][j] <<= (bits_ - j - 1); j++; } } @@ -326,14 +326,14 @@ public SobolRsg( int dimensionality, ulong seed, DirectionIntegers directionInte case DirectionIntegers.Kuo2: // maxTabulated=3946 maxTabulated = Kuo2initializers.Length + 1; - for ( k = 1; k < Math.Min( dimensionality_, maxTabulated ); k++ ) + for (k = 1; k < Math.Min(dimensionality_, maxTabulated); k++) { j = 0; // 0UL marks coefficients' end for a given dimension - while ( Kuo2initializers[k - 1][j] != 0UL ) + while (Kuo2initializers[k - 1][j] != 0UL) { directionIntegers_[k][j] = Kuo2initializers[k - 1][j]; - directionIntegers_[k][j] <<= ( bits_ - j - 1 ); + directionIntegers_[k][j] <<= (bits_ - j - 1); j++; } } @@ -342,14 +342,14 @@ public SobolRsg( int dimensionality, ulong seed, DirectionIntegers directionInte case DirectionIntegers.Kuo3: // maxTabulated=4585 maxTabulated = Kuo3initializers.Length + 1; - for ( k = 1; k < Math.Min( dimensionality_, maxTabulated ); k++ ) + for (k = 1; k < Math.Min(dimensionality_, maxTabulated); k++) { j = 0; // 0UL marks coefficients' end for a given dimension - while ( Kuo3initializers[k - 1][j] != 0UL ) + while (Kuo3initializers[k - 1][j] != 0UL) { directionIntegers_[k][j] = Kuo3initializers[k - 1][j]; - directionIntegers_[k][j] <<= ( bits_ - j - 1 ); + directionIntegers_[k][j] <<= (bits_ - j - 1); j++; } } @@ -360,12 +360,12 @@ public SobolRsg( int dimensionality, ulong seed, DirectionIntegers directionInte } // random initialization for higher dimensions - if ( dimensionality_ > maxTabulated ) + if (dimensionality_ > maxTabulated) { - MersenneTwisterUniformRng uniformRng = new MersenneTwisterUniformRng( seed ); - for ( k = maxTabulated; k < dimensionality_; k++ ) + MersenneTwisterUniformRng uniformRng = new MersenneTwisterUniformRng(seed); + for (k = maxTabulated; k < dimensionality_; k++) { - for ( int l = 1; l <= degree[k]; l++ ) + for (int l = 1; l <= degree[k]; l++) { do { @@ -373,8 +373,9 @@ public SobolRsg( int dimensionality, ulong seed, DirectionIntegers directionInte double u = uniformRng.next().value; // the direction integer has at most the // rightmost l bits non-zero - directionIntegers_[k][l - 1] = (ulong)( u * ( 1UL << l ) ); - } while ( ( directionIntegers_[k][l - 1] & 1UL ) == 0 ); + directionIntegers_[k][l - 1] = (ulong)(u * (1UL << l)); + } + while ((directionIntegers_[k][l - 1] & 1UL) == 0); // iterate until the direction integer is odd // that is it has the rightmost bit set @@ -382,20 +383,20 @@ public SobolRsg( int dimensionality, ulong seed, DirectionIntegers directionInte // we are guaranteed that the l-th leftmost bit // is set, and only the first l leftmost bit // can be non-zero - directionIntegers_[k][l - 1] <<= ( bits_ - l ); + directionIntegers_[k][l - 1] <<= (bits_ - l); } } } // computation of directionIntegers_[k][l] for l>=degree_[k] // by recurrence relation - for ( k = 1; k < dimensionality_; k++ ) + for (k = 1; k < dimensionality_; k++) { uint gk = degree[k]; - for ( int l = (int)gk; l < bits_; l++ ) + for (int l = (int)gk; l < bits_; l++) { // eq. 8.19 "Monte Carlo Methods in Finance" by P. Jдckel - ulong n = ( directionIntegers_[k][(int)( l - gk )] >> (int)gk ); + ulong n = (directionIntegers_[k][(int)(l - gk)] >> (int)gk); // a[k][j] are the coefficients of the monomials in ppmt[k] // The highest order coefficient a[k][0] is not actually // used in the recurrence relation, and the lowest order @@ -404,42 +405,42 @@ public SobolRsg( int dimensionality, ulong seed, DirectionIntegers directionInte // the polynomial ppmt[k] are not included in its encoding, // provided that its degree is known. // That is: a[k][j] = ppmt[k] >> (gk-j-1) - for ( uint z = 1; z < gk; z++ ) + for (uint z = 1; z < gk; z++) { // XORed with a selection of (unshifted) direction // integers controlled by which of the a[k][j] are set - if ( ( ( (ulong)ppmt[k] >> (int)( gk - z - 1 ) ) & 1UL ) != 0 ) - n ^= directionIntegers_[k][(int)( l - z )]; + if ((((ulong)ppmt[k] >> (int)(gk - z - 1)) & 1UL) != 0) + n ^= directionIntegers_[k][(int)(l - z)]; } // a[k][gk] is always set, so directionIntegers_[k][l-gk] // will always enter - n ^= directionIntegers_[k][(int)( l - gk )]; + n ^= directionIntegers_[k][(int)(l - gk)]; directionIntegers_[k][l] = n; } } // initialize the Sobol integer/double vectors // first draw - for ( k = 0; k < dimensionality_; k++ ) + for (k = 0; k < dimensionality_; k++) { integerSequence_[k] = directionIntegers_[k][0]; } } /*! skip to the n-th sample in the low-discrepancy sequence */ - public void skipTo( ulong skip ) + public void skipTo(ulong skip) { ulong N = skip + 1; - uint ops = (uint)( Math.Log( (double)N ) / Const.M_LN2 ) + 1; + uint ops = (uint)(Math.Log((double)N) / Const.M_LN2) + 1; // Convert to Gray code - ulong G = N ^ ( N >> 1 ); - for ( int k = 0; k < dimensionality_; k++ ) + ulong G = N ^ (N >> 1); + for (int k = 0; k < dimensionality_; k++) { integerSequence_[k] = 0; - for ( int index = 0; index < ops; index++ ) + for (int index = 0; index < ops; index++) { - if ( ( G >> index & 1 ) != 0 ) + if ((G >> index & 1) != 0) integerSequence_[k] ^= directionIntegers_[k][index]; } } @@ -448,7 +449,7 @@ public void skipTo( ulong skip ) public List nextInt32Sequence() { - if ( firstDraw_ ) + if (firstDraw_) { // it was precomputed in the constructor firstDraw_ = false; @@ -457,7 +458,7 @@ public List nextInt32Sequence() // increment the counter sequenceCounter_++; // did we overflow? - Utils.QL_REQUIRE( sequenceCounter_ != 0,()=> "period exceeded" ); + Utils.QL_REQUIRE(sequenceCounter_ != 0, () => "period exceeded"); // instead of using the counter n as new unique generating integer // for the n-th draw use the Gray code G(n) as proposed @@ -465,8 +466,12 @@ public List nextInt32Sequence() ulong n = sequenceCounter_; // Find rightmost zero bit of n int j = 0; - while ( ( n & 1 ) != 0 ) { n >>= 1; j++; } - for ( int k = 0; k < dimensionality_; k++ ) + while ((n & 1) != 0) + { + n >>= 1; + j++; + } + for (int k = 0; k < dimensionality_; k++) { // XOR the appropriate direction number into each component of // the integer sequence to obtain a new Sobol integer for that @@ -481,7 +486,7 @@ public Sample> nextSequence() { List v = nextInt32Sequence(); // normalize to get a double in (0,1) - for ( int k = 0; k < dimensionality_; ++k ) + for (int k = 0; k < dimensionality_; ++k) sequence_.value[k] = v[k] * normalizationFactor_; return sequence_; } @@ -490,9 +495,9 @@ public Sample> nextSequence() public int dimension() { return dimensionality_; } - public IRNG factory( int dimensionality, ulong seed ) + public IRNG factory(int dimensionality, ulong seed) { - return new SobolRsg( dimensionality, seed ); + return new SobolRsg(dimensionality, seed); } #endregion } diff --git a/src/QLNet/Math/randomnumbers/SobolRsg2.cs b/src/QLNet/Math/randomnumbers/SobolRsg2.cs new file mode 100644 index 000000000..6b508775d --- /dev/null +++ b/src/QLNet/Math/randomnumbers/SobolRsg2.cs @@ -0,0 +1,39328 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICAR PURPOSE. See the license for more details. +*/ + +namespace QLNet +{ + +#if NOPOLY + public partial class SobolRsg + { + const uint maxAltDegree = 0; + static long[][] AltPrimitivePolynomials; + static ulong[][] initializers; + static ulong[][] SLinitializers; + static ulong[][] Linitializers; + static ulong[][] JoeKuoD5initializers; + static ulong[][] JoeKuoD6initializers; + static ulong[][] JoeKuoD7initializers; + static ulong[][] Kuoinitializers; + static ulong[][] Kuo2initializers; + static ulong[][] Kuo3initializers; + } + +#else + + + public partial class SobolRsg + { + // number of dimensions in the alternative primitive polynomials + const uint maxAltDegree = 52; + + static long[] AltPrimitivePolynomialDegree01 = + { + 0, /* x+1 (1)(1) */ + -1 + }; + + static long[] AltPrimitivePolynomialDegree02 = + { + 1, /* x^2+x+1 (1)1(1) */ + -1 + }; + + static long[] AltPrimitivePolynomialDegree03 = + { + 1, /* x^3 +x+1 (1)01(1) */ + 2, /* x^3+x^2 +1 (1)10(1) */ + -1 + }; + + static long[] AltPrimitivePolynomialDegree04 = + { + 1, /* x^4+ +x+1 (1)001(1) */ + 4, /* x^4+x^3+ +1 (1)100(1) */ + -1 + }; + + + static long[] AltPrimitivePolynomialDegree05 = + { + 2, /* x^5 +x^2 +1 (1)0010(1) */ + 13, /* x^5+x^4+x^3 +x+1 (1)1101(1) */ + 7, /* x^5 +x^3+x^2+x+1 (1)0111(1) */ + 14, /* x^5+x^4+x^3+x^2 +1 (1)1110(1) */ + 11, /* x^5+x^4 +x^2+x+1 (1)1011(1) */ + 4, /* x^5 +x^3 +1 (1)0100(1) */ + -1 + }; + + static long[] AltPrimitivePolynomialDegree06 = + { + 1, /* x^6 +x+1 (1)00001(1) */ + 16, /* x^6+x^5 +1 (1)10000(1) */ + 13, /* x^6 +x^4+x^3 +x+1 (1)01101(1) */ + 22, /* x^6+x^5 +x^3+x^2 +1 (1)10110(1) */ + 19, /* x^6 +x^2+x+1 (1)10011(1) */ + 25, /* x^6+x^5+x^4 +x+1 (1)11001(1) */ + -1 + }; + + + static long[] AltPrimitivePolynomialDegree07 = + { + 1, /* x^7 +x+1 (1)000001(1) */ + 32, /* x^7+x^6 +1 (1)100000(1) */ + 4, /* x^7 +x^3 +1 (1)000100(1) */ + 8, /* x^7 +x^4 +1 (1)001000(1) */ + 7, /* x^7 +x^3+x^2+x+1 (1)000111(1) */ + 56, /* x^7+x^6+x^5+x^4 +1 (1)111000(1) */ + 14, /* x^7 +x^4+x^3+x^2 +1 (1)001110(1) */ + 28, /* x^7 +x^5+x^4+x^3 +1 (1)011100(1) */ + 19, /* x^7 +x^5 +x^2+x+1 (1)010011(1) */ + 50, /* x^7+x^6+x^5 +x^2 +1 (1)110010(1) */ + 21, /* x^7 +x^5 +x^3 +x+1 (1)010101(1) */ + 42, /* x^7+x^6 +x^4 +x^2 +1 (1)101010(1) */ + 31, /* x^7 +x^5+x^4+x^3+x^2+x+1 (1)011111(1) */ + 62, /* x^7+x^6+x^5+x^4+x^3+x^2 +1 (1)111110(1) */ + 37, /* x^7+x^6 +x^3 +x+1 (1)100101(1) */ + 41, /* x^7+x^6 +x^4 +x+1 (1)101001(1) */ + 55, /* x^7+x^6+x^5 +x^3+x^2+x+1 (1)110111(1) */ + 59, /* x^7+x^6+x^5+x^4 +x^2+x+1 (1)111011(1) */ + -1 + }; + + static long[] AltPrimitivePolynomialDegree08 = + { + 14, + 56, + 21, + 22, + 38, + 47, + 49, + 50, + 52, + 67, + 70, + 84, + 97, + 103, + 115, + 122, + -1 + }; + + static long[][] AltPrimitivePolynomials = + { + AltPrimitivePolynomialDegree01, + AltPrimitivePolynomialDegree02, + AltPrimitivePolynomialDegree03, + AltPrimitivePolynomialDegree04, + AltPrimitivePolynomialDegree05, + AltPrimitivePolynomialDegree06, + AltPrimitivePolynomialDegree07, + AltPrimitivePolynomialDegree08 + }; + + /* Sobol' Levitan coefficients of the free direction integers as given by Bratley, P., Fox, B.L. (1988) */ + static ulong[] dim02SLinitializers = { 1, 0 }; + static ulong[] dim03SLinitializers = { 1, 1, 0 }; + static ulong[] dim04SLinitializers = { 1, 3, 7, 0 }; + static ulong[] dim05SLinitializers = { 1, 1, 5, 0 }; + static ulong[] dim06SLinitializers = { 1, 3, 1, 1, 0 }; + static ulong[] dim07SLinitializers = { 1, 1, 3, 7, 0 }; + static ulong[] dim08SLinitializers = { 1, 3, 3, 9, 9, 0 }; + static ulong[] dim09SLinitializers = { 1, 3, 7, 13, 3, 0 }; + static ulong[] dim10SLinitializers = { 1, 1, 5, 11, 27, 0 }; + static ulong[] dim11SLinitializers = { 1, 3, 5, 1, 15, 0 }; + static ulong[] dim12SLinitializers = { 1, 1, 7, 3, 29, 0 }; + static ulong[] dim13SLinitializers = { 1, 3, 7, 7, 21, 0 }; + static ulong[] dim14SLinitializers = { 1, 1, 1, 9, 23, 37, 0 }; + static ulong[] dim15SLinitializers = { 1, 3, 3, 5, 19, 33, 0 }; + static ulong[] dim16SLinitializers = { 1, 1, 3, 13, 11, 7, 0 }; + static ulong[] dim17SLinitializers = { 1, 1, 7, 13, 25, 5, 0 }; + static ulong[] dim18SLinitializers = { 1, 3, 5, 11, 7, 11, 0 }; + static ulong[] dim19SLinitializers = { 1, 1, 1, 3, 13, 39, 0 }; + static ulong[] dim20SLinitializers = { 1, 3, 1, 15, 17, 63, 13, 0 }; + static ulong[] dim21SLinitializers = { 1, 1, 5, 5, 1, 27, 33, 0 }; + static ulong[] dim22SLinitializers = { 1, 3, 3, 3, 25, 17, 115, 0 }; + static ulong[] dim23SLinitializers = { 1, 1, 3, 15, 29, 15, 41, 0 }; + static ulong[] dim24SLinitializers = { 1, 3, 1, 7, 3, 23, 79, 0 }; + static ulong[] dim25SLinitializers = { 1, 3, 7, 9, 31, 29, 17, 0 }; + static ulong[] dim26SLinitializers = { 1, 1, 5, 13, 11, 3, 29, 0 }; + static ulong[] dim27SLinitializers = { 1, 3, 1, 9, 5, 21, 119, 0 }; + static ulong[] dim28SLinitializers = { 1, 1, 3, 1, 23, 13, 75, 0 }; + static ulong[] dim29SLinitializers = { 1, 3, 3, 11, 27, 31, 73, 0 }; + static ulong[] dim30SLinitializers = { 1, 1, 7, 7, 19, 25, 105, 0 }; + static ulong[] dim31SLinitializers = { 1, 3, 5, 5, 21, 9, 7, 0 }; + static ulong[] dim32SLinitializers = { 1, 1, 1, 15, 5, 49, 59, 0 }; + static ulong[] dim33SLinitializers = { 1, 1, 1, 1, 1, 33, 65, 0 }; + static ulong[] dim34SLinitializers = { 1, 3, 5, 15, 17, 19, 21, 0 }; + static ulong[] dim35SLinitializers = { 1, 1, 7, 11, 13, 29, 3, 0 }; + static ulong[] dim36SLinitializers = { 1, 3, 7, 5, 7, 11, 113, 0 }; + static ulong[] dim37SLinitializers = { 1, 1, 5, 3, 15, 19, 61, 0 }; + static ulong[] dim38SLinitializers = { 1, 3, 1, 1, 9, 27, 89, 7, 0 }; + static ulong[] dim39SLinitializers = { 1, 1, 3, 7, 31, 15, 45, 23, 0 }; + static ulong[] dim40SLinitializers = { 1, 3, 3, 9, 9, 25, 107, 39, 0 }; + + static ulong[][] SLinitializers = + { + dim02SLinitializers, + dim03SLinitializers, + dim04SLinitializers, + dim05SLinitializers, + dim06SLinitializers, + dim07SLinitializers, + dim08SLinitializers, + dim09SLinitializers, + dim10SLinitializers, + dim11SLinitializers, + dim12SLinitializers, + dim13SLinitializers, + dim14SLinitializers, + dim15SLinitializers, + dim16SLinitializers, + dim17SLinitializers, + dim18SLinitializers, + dim19SLinitializers, + dim20SLinitializers, + dim21SLinitializers, + dim22SLinitializers, + dim23SLinitializers, + dim24SLinitializers, + dim25SLinitializers, + dim26SLinitializers, + dim27SLinitializers, + dim28SLinitializers, + dim29SLinitializers, + dim30SLinitializers, + dim31SLinitializers, + dim32SLinitializers, + dim33SLinitializers, + dim34SLinitializers, + dim35SLinitializers, + dim36SLinitializers, + dim37SLinitializers, + dim38SLinitializers, + dim39SLinitializers, + dim40SLinitializers + }; + + /* coefficients of the free direction integers as given in + "Monte Carlo Methods in Finance", by Peter Jдckel, section 8.3 + */ + static ulong[] dim09initializers = { 1, 3, 7, 7, 21, 0 }; + static ulong[] dim10initializers = { 1, 1, 5, 11, 27, 0 }; + static ulong[] dim11initializers = { 1, 1, 7, 3, 29, 0 }; + static ulong[] dim12initializers = { 1, 3, 7, 13, 3, 0 }; + static ulong[] dim13initializers = { 1, 3, 5, 1, 15, 0 }; + static ulong[] dim14initializers = { 1, 1, 1, 9, 23, 37, 0 }; + static ulong[] dim15initializers = { 1, 1, 3, 13, 11, 7, 0 }; + static ulong[] dim16initializers = { 1, 3, 3, 5, 19, 33, 0 }; + static ulong[] dim17initializers = { 1, 1, 7, 13, 25, 5, 0 }; + static ulong[] dim18initializers = { 1, 1, 1, 3, 13, 39, 0 }; + static ulong[] dim19initializers = { 1, 3, 5, 11, 7, 11, 0 }; + static ulong[] dim20initializers = { 1, 3, 1, 7, 3, 23, 79, 0 }; + static ulong[] dim21initializers = { 1, 3, 1, 15, 17, 63, 13, 0 }; + static ulong[] dim22initializers = { 1, 3, 3, 3, 25, 17, 115, 0 }; + static ulong[] dim23initializers = { 1, 3, 7, 9, 31, 29, 17, 0 }; + static ulong[] dim24initializers = { 1, 1, 3, 15, 29, 15, 41, 0 }; + static ulong[] dim25initializers = { 1, 3, 1, 9, 5, 21, 119, 0 }; + static ulong[] dim26initializers = { 1, 1, 5, 5, 1, 27, 33, 0 }; + static ulong[] dim27initializers = { 1, 1, 3, 1, 23, 13, 75, 0 }; + static ulong[] dim28initializers = { 1, 1, 7, 7, 19, 25, 105, 0 }; + static ulong[] dim29initializers = { 1, 3, 5, 5, 21, 9, 7, 0 }; + static ulong[] dim30initializers = { 1, 1, 1, 15, 5, 49, 59, 0 }; + static ulong[] dim31initializers = { 1, 3, 5, 15, 17, 19, 21, 0 }; + static ulong[] dim32initializers = { 1, 1, 7, 11, 13, 29, 3, 0 }; + + static ulong[][] initializers = + { + dim02SLinitializers, + dim03SLinitializers, + dim04SLinitializers, + dim05SLinitializers, + dim06SLinitializers, + dim07SLinitializers, + dim08SLinitializers, + dim09initializers, + dim10initializers, + dim11initializers, + dim12initializers, + dim13initializers, + dim14initializers, + dim15initializers, + dim16initializers, + dim17initializers, + dim18initializers, + dim19initializers, + dim20initializers, + dim21initializers, + dim22initializers, + dim23initializers, + dim24initializers, + dim25initializers, + dim26initializers, + dim27initializers, + dim28initializers, + dim29initializers, + dim30initializers, + dim31initializers, + dim32initializers + }; + + /* Lemieux coefficients of the free direction integers as given + in Christiane Lemieux, private communication, September 2004 + */ + static ulong[] dim041Linitializers = { 1, 1, 3, 13, 7, 35, 61, 91, 0}; + static ulong[] dim042Linitializers = { 1, 1, 7, 11, 5, 35, 55, 75, 0}; + static ulong[] dim043Linitializers = { 1, 3, 5, 5, 11, 23, 29, 139, 0}; + static ulong[] dim044Linitializers = { 1, 1, 1, 7, 11, 15, 17, 81, 0}; + static ulong[] dim045Linitializers = { 1, 1, 7, 9, 5, 57, 79, 103, 0}; + static ulong[] dim046Linitializers = { 1, 1, 7, 13, 19, 5, 5, 185, 0}; + static ulong[] dim047Linitializers = { 1, 3, 1, 3, 13, 57, 97, 131, 0}; + static ulong[] dim048Linitializers = { 1, 1, 5, 5, 21, 25, 125, 197, 0}; + static ulong[] dim049Linitializers = { 1, 3, 3, 9, 31, 11, 103, 201, 0}; + static ulong[] dim050Linitializers = { 1, 1, 5, 3, 7, 25, 51, 121, 0}; + static ulong[] dim051Linitializers = { 1, 3, 7, 15, 19, 53, 73, 189, 0}; + static ulong[] dim052Linitializers = { 1, 1, 1, 15, 19, 55, 27, 183, 0}; + static ulong[] dim053Linitializers = { 1, 1, 7, 13, 3, 29, 109, 69, 0}; + static ulong[] dim054Linitializers = { 1, 1, 5, 15, 15, 23, 15, 1, 57, 0}; + static ulong[] dim055Linitializers = { 1, 3, 1, 3, 23, 55, 43, 143, 397, 0}; + static ulong[] dim056Linitializers = { 1, 1, 3, 11, 29, 9, 35, 131, 411, 0}; + static ulong[] dim057Linitializers = { 1, 3, 1, 7, 27, 39, 103, 199, 277, 0}; + static ulong[] dim058Linitializers = { 1, 3, 7, 3, 19, 55, 127, 67, 449, 0}; + static ulong[] dim059Linitializers = { 1, 3, 7, 3, 5, 29, 45, 85, 3, 0}; + static ulong[] dim060Linitializers = { 1, 3, 5, 5, 13, 23, 75, 245, 453, 0}; + static ulong[] dim061Linitializers = { 1, 3, 1, 15, 21, 47, 3, 77, 165, 0}; + static ulong[] dim062Linitializers = { 1, 1, 7, 9, 15, 5, 117, 73, 473, 0}; + static ulong[] dim063Linitializers = { 1, 3, 1, 9, 1, 21, 13, 173, 313, 0}; + static ulong[] dim064Linitializers = { 1, 1, 7, 3, 11, 45, 63, 77, 49, 0}; + static ulong[] dim065Linitializers = { 1, 1, 1, 1, 1, 25, 123, 39, 259, 0}; + static ulong[] dim066Linitializers = { 1, 1, 1, 5, 23, 11, 59, 11, 203, 0}; + static ulong[] dim067Linitializers = { 1, 3, 3, 15, 21, 1, 73, 71, 421, 0}; + static ulong[] dim068Linitializers = { 1, 1, 5, 11, 15, 31, 115, 95, 217, 0}; + static ulong[] dim069Linitializers = { 1, 1, 3, 3, 7, 53, 37, 43, 439, 0}; + static ulong[] dim070Linitializers = { 1, 1, 1, 1, 27, 53, 69, 159, 321, 0}; + static ulong[] dim071Linitializers = { 1, 1, 5, 15, 29, 17, 19, 43, 449, 0}; + static ulong[] dim072Linitializers = { 1, 1, 3, 9, 1, 55, 121, 205, 255, 0}; + static ulong[] dim073Linitializers = { 1, 1, 3, 11, 9, 47, 107, 11, 417, 0}; + static ulong[] dim074Linitializers = { 1, 1, 1, 5, 17, 25, 21, 83, 95, 0}; + static ulong[] dim075Linitializers = { 1, 3, 5, 13, 31, 25, 61, 157, 407, 0}; + static ulong[] dim076Linitializers = { 1, 1, 7, 9, 25, 33, 41, 35, 17, 0}; + static ulong[] dim077Linitializers = { 1, 3, 7, 15, 13, 39, 61, 187, 461, 0}; + static ulong[] dim078Linitializers = { 1, 3, 7, 13, 5, 57, 23, 177, 435, 0}; + static ulong[] dim079Linitializers = { 1, 1, 3, 15, 11, 27, 115, 5, 337, 0}; + static ulong[] dim080Linitializers = { 1, 3, 7, 3, 15, 63, 61, 171, 339, 0}; + static ulong[] dim081Linitializers = { 1, 3, 3, 13, 15, 61, 59, 47, 1, 0}; + static ulong[] dim082Linitializers = { 1, 1, 5, 15, 13, 5, 39, 83, 329, 0}; + static ulong[] dim083Linitializers = { 1, 1, 5, 5, 5, 27, 25, 39, 301, 0}; + static ulong[] dim084Linitializers = { 1, 1, 5, 11, 31, 41, 35, 233, 27, 0}; + static ulong[] dim085Linitializers = { 1, 3, 5, 15, 7, 37, 119, 171, 419, 0}; + static ulong[] dim086Linitializers = { 1, 3, 5, 5, 3, 29, 21, 189, 417, 0}; + static ulong[] dim087Linitializers = { 1, 1, 1, 1, 21, 41, 117, 119, 351, 0}; + static ulong[] dim088Linitializers = { 1, 1, 3, 1, 7, 27, 87, 19, 213, 0}; + static ulong[] dim089Linitializers = { 1, 1, 1, 1, 17, 7, 97, 217, 477, 0}; + static ulong[] dim090Linitializers = { 1, 1, 7, 1, 29, 61, 103, 231, 269, 0}; + static ulong[] dim091Linitializers = { 1, 1, 7, 13, 9, 27, 107, 207, 311, 0}; + static ulong[] dim092Linitializers = { 1, 1, 7, 5, 25, 21, 107, 179, 423, 0}; + static ulong[] dim093Linitializers = { 1, 3, 5, 11, 7, 1, 17, 245, 281, 0}; + static ulong[] dim094Linitializers = { 1, 3, 5, 9, 1, 5, 53, 59, 125, 0}; + static ulong[] dim095Linitializers = { 1, 1, 7, 1, 31, 57, 71, 245, 125, 0}; + static ulong[] dim096Linitializers = { 1, 1, 7, 5, 5, 57, 53, 253, 441, 0}; + static ulong[] dim097Linitializers = { 1, 3, 1, 13, 19, 35, 119, 235, 381, 0}; + static ulong[] dim098Linitializers = { 1, 3, 1, 7, 19, 59, 115, 33, 361, 0}; + static ulong[] dim099Linitializers = { 1, 1, 3, 5, 13, 1, 49, 143, 501, 0}; + static ulong[] dim100Linitializers = { 1, 1, 3, 5, 1, 63, 101, 85, 189, 0}; + static ulong[] dim101Linitializers = { 1, 1, 5, 11, 27, 63, 13, 131, 5, 0}; + static ulong[] dim102Linitializers = { 1, 1, 5, 7, 15, 45, 75, 59, 455, 585, 0}; + static ulong[] dim103Linitializers = { 1, 3, 1, 3, 7, 7, 111, 23, 119, 959, 0}; + static ulong[] dim104Linitializers = { 1, 3, 3, 9, 11, 41, 109, 163, 161, 879, 0}; + static ulong[] dim105Linitializers = { 1, 3, 5, 1, 21, 41, 121, 183, 315, 219, 0}; + static ulong[] dim106Linitializers = { 1, 1, 3, 9, 15, 3, 9, 223, 441, 929, 0}; + static ulong[] dim107Linitializers = { 1, 1, 7, 9, 3, 5, 93, 57, 253, 457, 0}; + static ulong[] dim108Linitializers = { 1, 1, 7, 13, 15, 29, 83, 21, 35, 45, 0}; + static ulong[] dim109Linitializers = { 1, 1, 3, 7, 13, 61, 119, 219, 85, 505, 0}; + static ulong[] dim110Linitializers = { 1, 1, 3, 3, 17, 13, 35, 197, 291, 109, 0}; + static ulong[] dim111Linitializers = { 1, 1, 3, 3, 5, 1, 113, 103, 217, 253, 0}; + static ulong[] dim112Linitializers = { 1, 1, 7, 1, 15, 39, 63, 223, 17, 9, 0}; + static ulong[] dim113Linitializers = { 1, 3, 7, 1, 17, 29, 67, 103, 495, 383, 0}; + static ulong[] dim114Linitializers = { 1, 3, 3, 15, 31, 59, 75, 165, 51, 913, 0}; + static ulong[] dim115Linitializers = { 1, 3, 7, 9, 5, 27, 79, 219, 233, 37, 0}; + static ulong[] dim116Linitializers = { 1, 3, 5, 15, 1, 11, 15, 211, 417, 811, 0}; + static ulong[] dim117Linitializers = { 1, 3, 5, 3, 29, 27, 39, 137, 407, 231, 0}; + static ulong[] dim118Linitializers = { 1, 1, 3, 5, 29, 43, 125, 135, 109, 67, 0}; + static ulong[] dim119Linitializers = { 1, 1, 1, 5, 11, 39, 107, 159, 323, 381, 0}; + static ulong[] dim120Linitializers = { 1, 1, 1, 1, 9, 11, 33, 55, 169, 253, 0}; + static ulong[] dim121Linitializers = { 1, 3, 5, 5, 11, 53, 63, 101, 251, 897, 0}; + static ulong[] dim122Linitializers = { 1, 3, 7, 1, 25, 15, 83, 119, 53, 157, 0}; + static ulong[] dim123Linitializers = { 1, 3, 5, 13, 5, 5, 3, 195, 111, 451, 0}; + static ulong[] dim124Linitializers = { 1, 3, 1, 15, 11, 1, 19, 11, 307, 777, 0}; + static ulong[] dim125Linitializers = { 1, 3, 7, 11, 5, 5, 17, 231, 345, 981, 0}; + static ulong[] dim126Linitializers = { 1, 1, 3, 3, 1, 33, 83, 201, 57, 475, 0}; + static ulong[] dim127Linitializers = { 1, 3, 7, 7, 17, 13, 35, 175, 499, 809, 0}; + static ulong[] dim128Linitializers = { 1, 1, 5, 3, 3, 17, 103, 119, 499, 865, 0}; + static ulong[] dim129Linitializers = { 1, 1, 1, 11, 27, 25, 37, 121, 401, 11, 0}; + static ulong[] dim130Linitializers = { 1, 1, 1, 11, 9, 25, 25, 241, 403, 3, 0}; + static ulong[] dim131Linitializers = { 1, 1, 1, 1, 11, 1, 39, 163, 231, 573, 0}; + static ulong[] dim132Linitializers = { 1, 1, 1, 13, 13, 21, 75, 185, 99, 545, 0}; + static ulong[] dim133Linitializers = { 1, 1, 1, 15, 3, 63, 69, 11, 173, 315, 0}; + static ulong[] dim134Linitializers = { 1, 3, 5, 15, 11, 3, 95, 49, 123, 765, 0}; + static ulong[] dim135Linitializers = { 1, 1, 1, 15, 3, 63, 77, 31, 425, 711, 0}; + static ulong[] dim136Linitializers = { 1, 1, 7, 15, 1, 37, 119, 145, 489, 583, 0}; + static ulong[] dim137Linitializers = { 1, 3, 5, 15, 3, 49, 117, 211, 165, 323, 0}; + static ulong[] dim138Linitializers = { 1, 3, 7, 1, 27, 63, 77, 201, 225, 803, 0}; + static ulong[] dim139Linitializers = { 1, 1, 1, 11, 23, 35, 67, 21, 469, 357, 0}; + static ulong[] dim140Linitializers = { 1, 1, 7, 7, 9, 7, 25, 237, 237, 571, 0}; + static ulong[] dim141Linitializers = { 1, 1, 3, 15, 29, 5, 107, 109, 241, 47, 0}; + static ulong[] dim142Linitializers = { 1, 3, 5, 11, 27, 63, 29, 13, 203, 675, 0}; + static ulong[] dim143Linitializers = { 1, 1, 3, 9, 9, 11, 103, 179, 449, 263, 0}; + static ulong[] dim144Linitializers = { 1, 3, 5, 11, 29, 63, 53, 151, 259, 223, 0}; + static ulong[] dim145Linitializers = { 1, 1, 3, 7, 9, 25, 5, 197, 237, 163, 0}; + static ulong[] dim146Linitializers = { 1, 3, 7, 13, 5, 57, 67, 193, 147, 241, 0}; + static ulong[] dim147Linitializers = { 1, 1, 5, 15, 15, 33, 17, 67, 161, 341, 0}; + static ulong[] dim148Linitializers = { 1, 1, 3, 13, 17, 43, 21, 197, 441, 985, 0}; + static ulong[] dim149Linitializers = { 1, 3, 1, 5, 15, 33, 33, 193, 305, 829, 0}; + static ulong[] dim150Linitializers = { 1, 1, 1, 13, 19, 27, 71, 187, 477, 239, 0}; + static ulong[] dim151Linitializers = { 1, 1, 1, 9, 9, 17, 41, 177, 229, 983, 0}; + static ulong[] dim152Linitializers = { 1, 3, 5, 9, 15, 45, 97, 205, 43, 767, 0}; + static ulong[] dim153Linitializers = { 1, 1, 1, 9, 31, 31, 77, 159, 395, 809, 0}; + static ulong[] dim154Linitializers = { 1, 3, 3, 3, 29, 19, 73, 123, 165, 307, 0}; + static ulong[] dim155Linitializers = { 1, 3, 1, 7, 5, 11, 77, 227, 355, 403, 0}; + static ulong[] dim156Linitializers = { 1, 3, 5, 5, 25, 31, 1, 215, 451, 195, 0}; + static ulong[] dim157Linitializers = { 1, 3, 7, 15, 29, 37, 101, 241, 17, 633, 0}; + static ulong[] dim158Linitializers = { 1, 1, 5, 1, 11, 3, 107, 137, 489, 5, 0}; + static ulong[] dim159Linitializers = { 1, 1, 1, 7, 19, 19, 75, 85, 471, 355, 0}; + static ulong[] dim160Linitializers = { 1, 1, 3, 3, 9, 13, 113, 167, 13, 27, 0}; + static ulong[] dim161Linitializers = { 1, 3, 5, 11, 21, 3, 89, 205, 377, 307, 0}; + static ulong[] dim162Linitializers = { 1, 1, 1, 9, 31, 61, 65, 9, 391, 141, 867, 0}; + static ulong[] dim163Linitializers = { 1, 1, 1, 9, 19, 19, 61, 227, 241, 55, 161, 0}; + static ulong[] dim164Linitializers = { 1, 1, 1, 11, 1, 19, 7, 233, 463, 171, 1941, 0}; + static ulong[] dim165Linitializers = { 1, 1, 5, 7, 25, 13, 103, 75, 19, 1021, 1063, 0}; + static ulong[] dim166Linitializers = { 1, 1, 1, 15, 17, 17, 79, 63, 391, 403, 1221, 0}; + static ulong[] dim167Linitializers = { 1, 3, 3, 11, 29, 25, 29, 107, 335, 475, 963, 0}; + static ulong[] dim168Linitializers = { 1, 3, 5, 1, 31, 33, 49, 43, 155, 9, 1285, 0}; + static ulong[] dim169Linitializers = { 1, 1, 5, 5, 15, 47, 39, 161, 357, 863, 1039, 0}; + static ulong[] dim170Linitializers = { 1, 3, 7, 15, 1, 39, 47, 109, 427, 393, 1103, 0}; + static ulong[] dim171Linitializers = { 1, 1, 1, 9, 9, 29, 121, 233, 157, 99, 701, 0}; + static ulong[] dim172Linitializers = { 1, 1, 1, 7, 1, 29, 75, 121, 439, 109, 993, 0}; + static ulong[] dim173Linitializers = { 1, 1, 1, 9, 5, 1, 39, 59, 89, 157, 1865, 0}; + static ulong[] dim174Linitializers = { 1, 1, 5, 1, 3, 37, 89, 93, 143, 533, 175, 0}; + static ulong[] dim175Linitializers = { 1, 1, 3, 5, 7, 33, 35, 173, 159, 135, 241, 0}; + static ulong[] dim176Linitializers = { 1, 1, 1, 15, 17, 37, 79, 131, 43, 891, 229, 0}; + static ulong[] dim177Linitializers = { 1, 1, 1, 1, 1, 35, 121, 177, 397, 1017, 583, 0}; + static ulong[] dim178Linitializers = { 1, 1, 3, 15, 31, 21, 43, 67, 467, 923, 1473, 0}; + static ulong[] dim179Linitializers = { 1, 1, 1, 7, 1, 33, 77, 111, 125, 771, 1975, 0}; + static ulong[] dim180Linitializers = { 1, 3, 7, 13, 1, 51, 113, 139, 245, 573, 503, 0}; + static ulong[] dim181Linitializers = { 1, 3, 1, 9, 21, 49, 15, 157, 49, 483, 291, 0}; + static ulong[] dim182Linitializers = { 1, 1, 1, 1, 29, 35, 17, 65, 403, 485, 1603, 0}; + static ulong[] dim183Linitializers = { 1, 1, 1, 7, 19, 1, 37, 129, 203, 321, 1809, 0}; + static ulong[] dim184Linitializers = { 1, 3, 7, 15, 15, 9, 5, 77, 29, 485, 581, 0}; + static ulong[] dim185Linitializers = { 1, 1, 3, 5, 15, 49, 97, 105, 309, 875, 1581, 0}; + static ulong[] dim186Linitializers = { 1, 3, 5, 1, 5, 19, 63, 35, 165, 399, 1489, 0}; + static ulong[] dim187Linitializers = { 1, 3, 5, 3, 23, 5, 79, 137, 115, 599, 1127, 0}; + static ulong[] dim188Linitializers = { 1, 1, 7, 5, 3, 61, 27, 177, 257, 91, 841, 0}; + static ulong[] dim189Linitializers = { 1, 1, 3, 5, 9, 31, 91, 209, 409, 661, 159, 0}; + static ulong[] dim190Linitializers = { 1, 3, 1, 15, 23, 39, 23, 195, 245, 203, 947, 0}; + static ulong[] dim191Linitializers = { 1, 1, 3, 1, 15, 59, 67, 95, 155, 461, 147, 0}; + static ulong[] dim192Linitializers = { 1, 3, 7, 5, 23, 25, 87, 11, 51, 449, 1631, 0}; + static ulong[] dim193Linitializers = { 1, 1, 1, 1, 17, 57, 7, 197, 409, 609, 135, 0}; + static ulong[] dim194Linitializers = { 1, 1, 1, 9, 1, 61, 115, 113, 495, 895, 1595, 0}; + static ulong[] dim195Linitializers = { 1, 3, 7, 15, 9, 47, 121, 211, 379, 985, 1755, 0}; + static ulong[] dim196Linitializers = { 1, 3, 1, 3, 7, 57, 27, 231, 339, 325, 1023, 0}; + static ulong[] dim197Linitializers = { 1, 1, 1, 1, 19, 63, 63, 239, 31, 643, 373, 0}; + static ulong[] dim198Linitializers = { 1, 3, 1, 11, 19, 9, 7, 171, 21, 691, 215, 0}; + static ulong[] dim199Linitializers = { 1, 1, 5, 13, 11, 57, 39, 211, 241, 893, 555, 0}; + static ulong[] dim200Linitializers = { 1, 1, 7, 5, 29, 21, 45, 59, 509, 223, 491, 0}; + static ulong[] dim201Linitializers = { 1, 1, 7, 9, 15, 61, 97, 75, 127, 779, 839, 0}; + static ulong[] dim202Linitializers = { 1, 1, 7, 15, 17, 33, 75, 237, 191, 925, 681, 0}; + static ulong[] dim203Linitializers = { 1, 3, 5, 7, 27, 57, 123, 111, 101, 371, 1129, 0}; + static ulong[] dim204Linitializers = { 1, 3, 5, 5, 29, 45, 59, 127, 229, 967, 2027, 0}; + static ulong[] dim205Linitializers = { 1, 1, 1, 1, 17, 7, 23, 199, 241, 455, 135, 0}; + static ulong[] dim206Linitializers = { 1, 1, 7, 15, 27, 29, 105, 171, 337, 503, 1817, 0}; + static ulong[] dim207Linitializers = { 1, 1, 3, 7, 21, 35, 61, 71, 405, 647, 2045, 0}; + static ulong[] dim208Linitializers = { 1, 1, 1, 1, 1, 15, 65, 167, 501, 79, 737, 0}; + static ulong[] dim209Linitializers = { 1, 1, 5, 1, 3, 49, 27, 189, 341, 615, 1287, 0}; + static ulong[] dim210Linitializers = { 1, 1, 1, 9, 1, 7, 31, 159, 503, 327, 1613, 0}; + static ulong[] dim211Linitializers = { 1, 3, 3, 3, 3, 23, 99, 115, 323, 997, 987, 0}; + static ulong[] dim212Linitializers = { 1, 1, 1, 9, 19, 33, 93, 247, 509, 453, 891, 0}; + static ulong[] dim213Linitializers = { 1, 1, 3, 1, 13, 19, 35, 153, 161, 633, 445, 0}; + static ulong[] dim214Linitializers = { 1, 3, 5, 15, 31, 5, 87, 197, 183, 783, 1823, 0}; + static ulong[] dim215Linitializers = { 1, 1, 7, 5, 19, 63, 69, 221, 129, 231, 1195, 0}; + static ulong[] dim216Linitializers = { 1, 1, 5, 5, 13, 23, 19, 231, 245, 917, 379, 0}; + static ulong[] dim217Linitializers = { 1, 3, 1, 15, 19, 43, 27, 223, 171, 413, 125, 0}; + static ulong[] dim218Linitializers = { 1, 1, 1, 9, 1, 59, 21, 15, 509, 207, 589, 0}; + static ulong[] dim219Linitializers = { 1, 3, 5, 3, 19, 31, 113, 19, 23, 733, 499, 0}; + static ulong[] dim220Linitializers = { 1, 1, 7, 1, 19, 51, 101, 165, 47, 925, 1093, 0}; + static ulong[] dim221Linitializers = { 1, 3, 3, 9, 15, 21, 43, 243, 237, 461, 1361, 0}; + static ulong[] dim222Linitializers = { 1, 1, 1, 9, 17, 15, 75, 75, 113, 715, 1419, 0}; + static ulong[] dim223Linitializers = { 1, 1, 7, 13, 17, 1, 99, 15, 347, 721, 1405, 0}; + static ulong[] dim224Linitializers = { 1, 1, 7, 15, 7, 27, 23, 183, 39, 59, 571, 0}; + static ulong[] dim225Linitializers = { 1, 3, 5, 9, 7, 43, 35, 165, 463, 567, 859, 0}; + static ulong[] dim226Linitializers = { 1, 3, 3, 11, 15, 19, 17, 129, 311, 343, 15, 0}; + static ulong[] dim227Linitializers = { 1, 1, 1, 15, 31, 59, 63, 39, 347, 359, 105, 0}; + static ulong[] dim228Linitializers = { 1, 1, 1, 15, 5, 43, 87, 241, 109, 61, 685, 0}; + static ulong[] dim229Linitializers = { 1, 1, 7, 7, 9, 39, 121, 127, 369, 579, 853, 0}; + static ulong[] dim230Linitializers = { 1, 1, 1, 1, 17, 15, 15, 95, 325, 627, 299, 0}; + static ulong[] dim231Linitializers = { 1, 1, 3, 13, 31, 53, 85, 111, 289, 811, 1635, 0}; + static ulong[] dim232Linitializers = { 1, 3, 7, 1, 19, 29, 75, 185, 153, 573, 653, 0}; + static ulong[] dim233Linitializers = { 1, 3, 7, 1, 29, 31, 55, 91, 249, 247, 1015, 0}; + static ulong[] dim234Linitializers = { 1, 3, 5, 7, 1, 49, 113, 139, 257, 127, 307, 0}; + static ulong[] dim235Linitializers = { 1, 3, 5, 9, 15, 15, 123, 105, 105, 225, 1893, 0}; + static ulong[] dim236Linitializers = { 1, 3, 3, 1, 15, 5, 105, 249, 73, 709, 1557, 0}; + static ulong[] dim237Linitializers = { 1, 1, 1, 9, 17, 31, 113, 73, 65, 701, 1439, 0}; + static ulong[] dim238Linitializers = { 1, 3, 5, 15, 13, 21, 117, 131, 243, 859, 323, 0}; + static ulong[] dim239Linitializers = { 1, 1, 1, 9, 19, 15, 69, 149, 89, 681, 515, 0}; + static ulong[] dim240Linitializers = { 1, 1, 1, 5, 29, 13, 21, 97, 301, 27, 967, 0}; + static ulong[] dim241Linitializers = { 1, 1, 3, 3, 15, 45, 107, 227, 495, 769, 1935, 0}; + static ulong[] dim242Linitializers = { 1, 1, 1, 11, 5, 27, 41, 173, 261, 703, 1349, 0}; + static ulong[] dim243Linitializers = { 1, 3, 3, 3, 11, 35, 97, 43, 501, 563, 1331, 0}; + static ulong[] dim244Linitializers = { 1, 1, 1, 7, 1, 17, 87, 17, 429, 245, 1941, 0}; + static ulong[] dim245Linitializers = { 1, 1, 7, 15, 29, 13, 1, 175, 425, 233, 797, 0}; + static ulong[] dim246Linitializers = { 1, 1, 3, 11, 21, 57, 49, 49, 163, 685, 701, 0}; + static ulong[] dim247Linitializers = { 1, 3, 3, 7, 11, 45, 107, 111, 379, 703, 1403, 0}; + static ulong[] dim248Linitializers = { 1, 1, 7, 3, 21, 7, 117, 49, 469, 37, 775, 0}; + static ulong[] dim249Linitializers = { 1, 1, 5, 15, 31, 63, 101, 77, 507, 489, 1955, 0}; + static ulong[] dim250Linitializers = { 1, 3, 3, 11, 19, 21, 101, 255, 203, 673, 665, 0}; + static ulong[] dim251Linitializers = { 1, 3, 3, 15, 17, 47, 125, 187, 271, 899, 2003, 0}; + static ulong[] dim252Linitializers = { 1, 1, 7, 7, 1, 35, 13, 235, 5, 337, 905, 0}; + static ulong[] dim253Linitializers = { 1, 3, 1, 15, 1, 43, 1, 27, 37, 695, 1429, 0}; + static ulong[] dim254Linitializers = { 1, 3, 1, 11, 21, 27, 93, 161, 299, 665, 495, 0}; + static ulong[] dim255Linitializers = { 1, 3, 3, 15, 3, 1, 81, 111, 105, 547, 897, 0}; + static ulong[] dim256Linitializers = { 1, 3, 5, 1, 3, 53, 97, 253, 401, 827, 1467, 0}; + static ulong[] dim257Linitializers = {1, 1, 1, 5, 19, 59, 105, 125, 271, 351, 719, 0}; + static ulong[] dim258Linitializers = {1, 3, 5, 13, 7, 11, 91, 41, 441, 759, 1827, 0}; + static ulong[] dim259Linitializers = {1, 3, 7, 11, 29, 61, 61, 23, 307, 863, 363, 0}; + static ulong[] dim260Linitializers = {1, 1, 7, 1, 15, 35, 29, 133, 415, 473, 1737, 0}; + static ulong[] dim261Linitializers = {1, 1, 1, 13, 7, 33, 35, 225, 117, 681, 1545, 0}; + static ulong[] dim262Linitializers = {1, 1, 1, 3, 5, 41, 83, 247, 13, 373, 1091, 0}; + static ulong[] dim263Linitializers = {1, 3, 1, 13, 25, 61, 71, 217, 233, 313, 547, 0}; + static ulong[] dim264Linitializers = {1, 3, 1, 7, 3, 29, 3, 49, 93, 465, 15, 0}; + static ulong[] dim265Linitializers = {1, 1, 1, 9, 17, 61, 99, 163, 129, 485, 1087, 0}; + static ulong[] dim266Linitializers = {1, 1, 1, 9, 9, 33, 31, 163, 145, 649, 253, 0}; + static ulong[] dim267Linitializers = {1, 1, 1, 1, 17, 63, 43, 235, 287, 111, 567, 0}; + static ulong[] dim268Linitializers = {1, 3, 5, 13, 29, 7, 11, 69, 153, 127, 449, 0}; + static ulong[] dim269Linitializers = {1, 1, 5, 9, 11, 21, 15, 189, 431, 493, 1219, 0}; + static ulong[] dim270Linitializers = {1, 1, 1, 15, 19, 5, 47, 91, 399, 293, 1743, 0}; + static ulong[] dim271Linitializers = {1, 3, 3, 11, 29, 53, 53, 225, 409, 303, 333, 0}; + static ulong[] dim272Linitializers = {1, 1, 1, 15, 31, 31, 21, 81, 147, 287, 1753, 0}; + static ulong[] dim273Linitializers = {1, 3, 5, 5, 5, 63, 35, 125, 41, 687, 1793, 0}; + static ulong[] dim274Linitializers = {1, 1, 1, 9, 19, 59, 107, 219, 455, 971, 297, 0}; + static ulong[] dim275Linitializers = {1, 1, 3, 5, 3, 51, 121, 31, 245, 105, 1311, 0}; + static ulong[] dim276Linitializers = {1, 3, 1, 5, 5, 57, 75, 107, 161, 431, 1693, 0}; + static ulong[] dim277Linitializers = {1, 3, 1, 3, 19, 53, 27, 31, 191, 565, 1015, 0}; + static ulong[] dim278Linitializers = {1, 3, 5, 13, 9, 41, 35, 249, 287, 49, 123, 0}; + static ulong[] dim279Linitializers = {1, 1, 5, 7, 27, 17, 21, 3, 151, 885, 1165, 0}; + static ulong[] dim280Linitializers = {1, 1, 7, 1, 15, 17, 65, 139, 427, 339, 1171, 0}; + static ulong[] dim281Linitializers = {1, 1, 1, 5, 23, 5, 9, 89, 321, 907, 391, 0}; + static ulong[] dim282Linitializers = {1, 1, 7, 9, 15, 1, 77, 71, 87, 701, 917, 0}; + static ulong[] dim283Linitializers = {1, 1, 7, 1, 17, 37, 115, 127, 469, 779, 1543, 0}; + static ulong[] dim284Linitializers = {1, 3, 7, 3, 5, 61, 15, 37, 301, 951, 1437, 0}; + static ulong[] dim285Linitializers = {1, 1, 1, 13, 9, 51, 127, 145, 229, 55, 1567, 0}; + static ulong[] dim286Linitializers = {1, 3, 7, 15, 19, 47, 53, 153, 295, 47, 1337, 0}; + static ulong[] dim287Linitializers = {1, 3, 3, 5, 11, 31, 29, 133, 327, 287, 507, 0}; + static ulong[] dim288Linitializers = {1, 1, 7, 7, 25, 31, 37, 199, 25, 927, 1317, 0}; + static ulong[] dim289Linitializers = {1, 1, 7, 9, 3, 39, 127, 167, 345, 467, 759, 0}; + static ulong[] dim290Linitializers = {1, 1, 1, 1, 31, 21, 15, 101, 293, 787, 1025, 0}; + static ulong[] dim291Linitializers = {1, 1, 5, 3, 11, 41, 105, 109, 149, 837, 1813, 0}; + static ulong[] dim292Linitializers = {1, 1, 3, 5, 29, 13, 19, 97, 309, 901, 753, 0}; + static ulong[] dim293Linitializers = {1, 1, 7, 1, 19, 17, 31, 39, 173, 361, 1177, 0}; + static ulong[] dim294Linitializers = {1, 3, 3, 3, 3, 41, 81, 7, 341, 491, 43, 0}; + static ulong[] dim295Linitializers = {1, 1, 7, 7, 31, 35, 29, 77, 11, 335, 1275, 0}; + static ulong[] dim296Linitializers = {1, 3, 3, 15, 17, 45, 19, 63, 151, 849, 129, 0}; + static ulong[] dim297Linitializers = {1, 1, 7, 5, 7, 13, 47, 73, 79, 31, 499, 0}; + static ulong[] dim298Linitializers = {1, 3, 1, 11, 1, 41, 59, 151, 247, 115, 1295, 0}; + static ulong[] dim299Linitializers = {1, 1, 1, 9, 31, 37, 73, 23, 295, 483, 179, 0}; + static ulong[] dim300Linitializers = {1, 3, 1, 15, 13, 63, 81, 27, 169, 825, 2037, 0}; + static ulong[] dim301Linitializers = {1, 3, 5, 15, 7, 11, 73, 1, 451, 101, 2039, 0}; + static ulong[] dim302Linitializers = {1, 3, 5, 3, 13, 53, 31, 137, 173, 319, 1521, 0}; + static ulong[] dim303Linitializers = {1, 3, 1, 3, 29, 1, 73, 227, 377, 337, 1189, 0}; + static ulong[] dim304Linitializers = {1, 3, 3, 13, 27, 9, 31, 101, 229, 165, 1983, 0}; + static ulong[] dim305Linitializers = {1, 3, 1, 13, 13, 19, 19, 111, 319, 421, 223, 0}; + static ulong[] dim306Linitializers = {1, 1, 7, 15, 25, 37, 61, 55, 359, 255, 1955, 0}; + static ulong[] dim307Linitializers = {1, 1, 5, 13, 17, 43, 49, 215, 383, 915, 51, 0}; + static ulong[] dim308Linitializers = {1, 1, 3, 1, 3, 7, 13, 119, 155, 585, 967, 0}; + static ulong[] dim309Linitializers = {1, 3, 1, 13, 1, 63, 125, 21, 103, 287, 457, 0}; + static ulong[] dim310Linitializers = {1, 1, 7, 1, 31, 17, 125, 137, 345, 379, 1925, 0}; + static ulong[] dim311Linitializers = {1, 1, 3, 5, 5, 25, 119, 153, 455, 271, 2023, 0}; + static ulong[] dim312Linitializers = {1, 1, 7, 9, 9, 37, 115, 47, 5, 255, 917, 0}; + static ulong[] dim313Linitializers = {1, 3, 5, 3, 31, 21, 75, 203, 489, 593, 1, 0}; + static ulong[] dim314Linitializers = {1, 3, 7, 15, 19, 63, 123, 153, 135, 977, 1875, 0}; + static ulong[] dim315Linitializers = {1, 1, 1, 1, 5, 59, 31, 25, 127, 209, 745, 0}; + static ulong[] dim316Linitializers = {1, 1, 1, 1, 19, 45, 67, 159, 301, 199, 535, 0}; + static ulong[] dim317Linitializers = {1, 1, 7, 1, 31, 17, 19, 225, 369, 125, 421, 0}; + static ulong[] dim318Linitializers = {1, 3, 3, 11, 7, 59, 115, 197, 459, 469, 1055, 0}; + static ulong[] dim319Linitializers = {1, 3, 1, 3, 27, 45, 35, 131, 349, 101, 411, 0}; + static ulong[] dim320Linitializers = {1, 3, 7, 11, 9, 3, 67, 145, 299, 253, 1339, 0}; + static ulong[] dim321Linitializers = {1, 3, 3, 11, 9, 37, 123, 229, 273, 269, 515, 0}; + static ulong[] dim322Linitializers = {1, 3, 7, 15, 11, 25, 75, 5, 367, 217, 951, 0}; + static ulong[] dim323Linitializers = {1, 1, 3, 7, 9, 23, 63, 237, 385, 159, 1273, 0}; + static ulong[] dim324Linitializers = {1, 1, 5, 11, 23, 5, 55, 193, 109, 865, 663, 0}; + static ulong[] dim325Linitializers = {1, 1, 7, 15, 1, 57, 17, 141, 51, 217, 1259, 0}; + static ulong[] dim326Linitializers = {1, 1, 3, 3, 15, 7, 89, 233, 71, 329, 203, 0}; + static ulong[] dim327Linitializers = {1, 3, 7, 11, 11, 1, 19, 155, 89, 437, 573, 0}; + static ulong[] dim328Linitializers = {1, 3, 1, 9, 27, 61, 47, 109, 161, 913, 1681, 0}; + static ulong[] dim329Linitializers = {1, 1, 7, 15, 1, 33, 19, 15, 23, 913, 989, 0}; + static ulong[] dim330Linitializers = {1, 3, 1, 1, 25, 39, 119, 193, 13, 571, 157, 0}; + static ulong[] dim331Linitializers = {1, 1, 7, 13, 9, 55, 59, 147, 361, 935, 515, 0}; + static ulong[] dim332Linitializers = {1, 1, 1, 9, 7, 59, 67, 117, 71, 855, 1493, 0}; + static ulong[] dim333Linitializers = {1, 3, 1, 3, 13, 19, 57, 141, 305, 275, 1079, 0}; + static ulong[] dim334Linitializers = {1, 1, 1, 9, 17, 61, 33, 7, 43, 931, 781, 0}; + static ulong[] dim335Linitializers = {1, 1, 3, 1, 11, 17, 21, 97, 295, 277, 1721, 0}; + static ulong[] dim336Linitializers = {1, 3, 1, 13, 15, 43, 11, 241, 147, 391, 1641, 0}; + static ulong[] dim337Linitializers = {1, 1, 1, 1, 1, 19, 37, 21, 255, 263, 1571, 0}; + static ulong[] dim338Linitializers = {1, 1, 3, 3, 23, 59, 89, 17, 475, 303, 757, 543, 0}; + static ulong[] dim339Linitializers = {1, 3, 3, 9, 11, 55, 35, 159, 139, 203, 1531, 1825, 0}; + static ulong[] dim340Linitializers = {1, 1, 5, 3, 17, 53, 51, 241, 269, 949, 1373, 325, 0}; + static ulong[] dim341Linitializers = {1, 3, 7, 7, 5, 29, 91, 149, 239, 193, 1951, 2675, 0}; + static ulong[] dim342Linitializers = {1, 3, 5, 1, 27, 33, 69, 11, 51, 371, 833, 2685, 0}; + static ulong[] dim343Linitializers = {1, 1, 1, 15, 1, 17, 35, 57, 171, 1007, 449, 367, 0}; + static ulong[] dim344Linitializers = {1, 1, 1, 7, 25, 61, 73, 219, 379, 53, 589, 4065, 0}; + static ulong[] dim345Linitializers = {1, 3, 5, 13, 21, 29, 45, 19, 163, 169, 147, 597, 0}; + static ulong[] dim346Linitializers = {1, 1, 5, 11, 21, 27, 7, 17, 237, 591, 255, 1235, 0}; + static ulong[] dim347Linitializers = {1, 1, 7, 7, 17, 41, 69, 237, 397, 173, 1229, 2341, 0}; + static ulong[] dim348Linitializers = {1, 1, 3, 1, 1, 33, 125, 47, 11, 783, 1323, 2469, 0}; + static ulong[] dim349Linitializers = {1, 3, 1, 11, 3, 39, 35, 133, 153, 55, 1171, 3165, 0}; + static ulong[] dim350Linitializers = {1, 1, 5, 11, 27, 23, 103, 245, 375, 753, 477, 2165, 0}; + static ulong[] dim351Linitializers = {1, 3, 1, 15, 15, 49, 127, 223, 387, 771, 1719, 1465, 0}; + static ulong[] dim352Linitializers = {1, 1, 1, 9, 11, 9, 17, 185, 239, 899, 1273, 3961, 0}; + static ulong[] dim353Linitializers = {1, 1, 3, 13, 11, 51, 73, 81, 389, 647, 1767, 1215, 0}; + static ulong[] dim354Linitializers = {1, 3, 5, 15, 19, 9, 69, 35, 349, 977, 1603, 1435, 0}; + static ulong[] dim355Linitializers = {1, 1, 1, 1, 19, 59, 123, 37, 41, 961, 181, 1275, 0}; + static ulong[] dim356Linitializers = {1, 1, 1, 1, 31, 29, 37, 71, 205, 947, 115, 3017, 0}; + static ulong[] dim357Linitializers = {1, 1, 7, 15, 5, 37, 101, 169, 221, 245, 687, 195, 0}; + static ulong[] dim358Linitializers = {1, 1, 1, 1, 19, 9, 125, 157, 119, 283, 1721, 743, 0}; + static ulong[] dim359Linitializers = {1, 1, 7, 3, 1, 7, 61, 71, 119, 257, 1227, 2893, 0}; + static ulong[] dim360Linitializers = {1, 3, 3, 3, 25, 41, 25, 225, 31, 57, 925, 2139, 0}; + + static ulong[][] Linitializers = + { + dim02SLinitializers, + dim03SLinitializers, + dim04SLinitializers, + dim05SLinitializers, + dim06SLinitializers, + dim07SLinitializers, + dim08SLinitializers, + dim09SLinitializers, + dim10SLinitializers, + dim11SLinitializers, + dim12SLinitializers, + dim13SLinitializers, + dim14SLinitializers, + dim15SLinitializers, + dim16SLinitializers, + dim17SLinitializers, + dim18SLinitializers, + dim19SLinitializers, + dim20SLinitializers, + dim21SLinitializers, + dim22SLinitializers, + dim23SLinitializers, + dim24SLinitializers, + dim25SLinitializers, + dim26SLinitializers, + dim27SLinitializers, + dim28SLinitializers, + dim29SLinitializers, + dim30SLinitializers, + dim31SLinitializers, + dim32SLinitializers, + dim33SLinitializers, + dim34SLinitializers, + dim35SLinitializers, + dim36SLinitializers, + dim37SLinitializers, + dim38SLinitializers, + dim39SLinitializers, + dim40SLinitializers, + dim041Linitializers, + dim042Linitializers, + dim043Linitializers, + dim044Linitializers, + dim045Linitializers, + dim046Linitializers, + dim047Linitializers, + dim048Linitializers, + dim049Linitializers, + dim050Linitializers, + dim051Linitializers, + dim052Linitializers, + dim053Linitializers, + dim054Linitializers, + dim055Linitializers, + dim056Linitializers, + dim057Linitializers, + dim058Linitializers, + dim059Linitializers, + dim060Linitializers, + dim061Linitializers, + dim062Linitializers, + dim063Linitializers, + dim064Linitializers, + dim065Linitializers, + dim066Linitializers, + dim067Linitializers, + dim068Linitializers, + dim069Linitializers, + dim070Linitializers, + dim071Linitializers, + dim072Linitializers, + dim073Linitializers, + dim074Linitializers, + dim075Linitializers, + dim076Linitializers, + dim077Linitializers, + dim078Linitializers, + dim079Linitializers, + dim080Linitializers, + dim081Linitializers, + dim082Linitializers, + dim083Linitializers, + dim084Linitializers, + dim085Linitializers, + dim086Linitializers, + dim087Linitializers, + dim088Linitializers, + dim089Linitializers, + dim090Linitializers, + dim091Linitializers, + dim092Linitializers, + dim093Linitializers, + dim094Linitializers, + dim095Linitializers, + dim096Linitializers, + dim097Linitializers, + dim098Linitializers, + dim099Linitializers, + dim100Linitializers, + dim101Linitializers, + dim102Linitializers, + dim103Linitializers, + dim104Linitializers, + dim105Linitializers, + dim106Linitializers, + dim107Linitializers, + dim108Linitializers, + dim109Linitializers, + dim110Linitializers, + dim111Linitializers, + dim112Linitializers, + dim113Linitializers, + dim114Linitializers, + dim115Linitializers, + dim116Linitializers, + dim117Linitializers, + dim118Linitializers, + dim119Linitializers, + dim120Linitializers, + dim121Linitializers, + dim122Linitializers, + dim123Linitializers, + dim124Linitializers, + dim125Linitializers, + dim126Linitializers, + dim127Linitializers, + dim128Linitializers, + dim129Linitializers, + dim130Linitializers, + dim131Linitializers, + dim132Linitializers, + dim133Linitializers, + dim134Linitializers, + dim135Linitializers, + dim136Linitializers, + dim137Linitializers, + dim138Linitializers, + dim139Linitializers, + dim140Linitializers, + dim141Linitializers, + dim142Linitializers, + dim143Linitializers, + dim144Linitializers, + dim145Linitializers, + dim146Linitializers, + dim147Linitializers, + dim148Linitializers, + dim149Linitializers, + dim150Linitializers, + dim151Linitializers, + dim152Linitializers, + dim153Linitializers, + dim154Linitializers, + dim155Linitializers, + dim156Linitializers, + dim157Linitializers, + dim158Linitializers, + dim159Linitializers, + dim160Linitializers, + dim161Linitializers, + dim162Linitializers, + dim163Linitializers, + dim164Linitializers, + dim165Linitializers, + dim166Linitializers, + dim167Linitializers, + dim168Linitializers, + dim169Linitializers, + dim170Linitializers, + dim171Linitializers, + dim172Linitializers, + dim173Linitializers, + dim174Linitializers, + dim175Linitializers, + dim176Linitializers, + dim177Linitializers, + dim178Linitializers, + dim179Linitializers, + dim180Linitializers, + dim181Linitializers, + dim182Linitializers, + dim183Linitializers, + dim184Linitializers, + dim185Linitializers, + dim186Linitializers, + dim187Linitializers, + dim188Linitializers, + dim189Linitializers, + dim190Linitializers, + dim191Linitializers, + dim192Linitializers, + dim193Linitializers, + dim194Linitializers, + dim195Linitializers, + dim196Linitializers, + dim197Linitializers, + dim198Linitializers, + dim199Linitializers, + dim200Linitializers, + dim201Linitializers, + dim202Linitializers, + dim203Linitializers, + dim204Linitializers, + dim205Linitializers, + dim206Linitializers, + dim207Linitializers, + dim208Linitializers, + dim209Linitializers, + dim210Linitializers, + dim211Linitializers, + dim212Linitializers, + dim213Linitializers, + dim214Linitializers, + dim215Linitializers, + dim216Linitializers, + dim217Linitializers, + dim218Linitializers, + dim219Linitializers, + dim220Linitializers, + dim221Linitializers, + dim222Linitializers, + dim223Linitializers, + dim224Linitializers, + dim225Linitializers, + dim226Linitializers, + dim227Linitializers, + dim228Linitializers, + dim229Linitializers, + dim230Linitializers, + dim231Linitializers, + dim232Linitializers, + dim233Linitializers, + dim234Linitializers, + dim235Linitializers, + dim236Linitializers, + dim237Linitializers, + dim238Linitializers, + dim239Linitializers, + dim240Linitializers, + dim241Linitializers, + dim242Linitializers, + dim243Linitializers, + dim244Linitializers, + dim245Linitializers, + dim246Linitializers, + dim247Linitializers, + dim248Linitializers, + dim249Linitializers, + dim250Linitializers, + dim251Linitializers, + dim252Linitializers, + dim253Linitializers, + dim254Linitializers, + dim255Linitializers, + dim256Linitializers, + dim257Linitializers, + dim258Linitializers, + dim259Linitializers, + dim260Linitializers, + dim261Linitializers, + dim262Linitializers, + dim263Linitializers, + dim264Linitializers, + dim265Linitializers, + dim266Linitializers, + dim267Linitializers, + dim268Linitializers, + dim269Linitializers, + dim270Linitializers, + dim271Linitializers, + dim272Linitializers, + dim273Linitializers, + dim274Linitializers, + dim275Linitializers, + dim276Linitializers, + dim277Linitializers, + dim278Linitializers, + dim279Linitializers, + dim280Linitializers, + dim281Linitializers, + dim282Linitializers, + dim283Linitializers, + dim284Linitializers, + dim285Linitializers, + dim286Linitializers, + dim287Linitializers, + dim288Linitializers, + dim289Linitializers, + dim290Linitializers, + dim291Linitializers, + dim292Linitializers, + dim293Linitializers, + dim294Linitializers, + dim295Linitializers, + dim296Linitializers, + dim297Linitializers, + dim298Linitializers, + dim299Linitializers, + dim300Linitializers, + dim301Linitializers, + dim302Linitializers, + dim303Linitializers, + dim304Linitializers, + dim305Linitializers, + dim306Linitializers, + dim307Linitializers, + dim308Linitializers, + dim309Linitializers, + dim310Linitializers, + dim311Linitializers, + dim312Linitializers, + dim313Linitializers, + dim314Linitializers, + dim315Linitializers, + dim316Linitializers, + dim317Linitializers, + dim318Linitializers, + dim319Linitializers, + dim320Linitializers, + dim321Linitializers, + dim322Linitializers, + dim323Linitializers, + dim324Linitializers, + dim325Linitializers, + dim326Linitializers, + dim327Linitializers, + dim328Linitializers, + dim329Linitializers, + dim330Linitializers, + dim331Linitializers, + dim332Linitializers, + dim333Linitializers, + dim334Linitializers, + dim335Linitializers, + dim336Linitializers, + dim337Linitializers, + dim338Linitializers, + dim339Linitializers, + dim340Linitializers, + dim341Linitializers, + dim342Linitializers, + dim343Linitializers, + dim344Linitializers, + dim345Linitializers, + dim346Linitializers, + dim347Linitializers, + dim348Linitializers, + dim349Linitializers, + dim350Linitializers, + dim351Linitializers, + dim352Linitializers, + dim353Linitializers, + dim354Linitializers, + dim355Linitializers, + dim356Linitializers, + dim357Linitializers, + dim358Linitializers, + dim359Linitializers, + dim360Linitializers + }; + + static ulong[] dim1KuoInit = { 1, 0 }; + static ulong[] dim2KuoInit = { 1, 1, 0 }; + static ulong[] dim3KuoInit = { 1, 1, 1, 0 }; + static ulong[] dim4KuoInit = { 1, 3, 1, 0 }; + static ulong[] dim5KuoInit = { 1, 1, 7, 13, 0 }; + static ulong[] dim6KuoInit = { 1, 1, 3, 7, 0 }; + static ulong[] dim7KuoInit = { 1, 3, 1, 7, 21, 0 }; + static ulong[] dim8KuoInit = { 1, 3, 1, 3, 9, 0 }; + static ulong[] dim9KuoInit = { 1, 1, 5, 9, 13, 0 }; + static ulong[] dim10KuoInit = { 1, 1, 3, 9, 13, 0 }; + static ulong[] dim11KuoInit = { 1, 1, 5, 3, 7, 0 }; + static ulong[] dim12KuoInit = { 1, 1, 5, 7, 11, 0 }; + static ulong[] dim13KuoInit = { 1, 3, 3, 13, 15, 43, 0 }; + static ulong[] dim14KuoInit = { 1, 3, 5, 11, 25, 45, 0 }; + static ulong[] dim15KuoInit = { 1, 1, 3, 11, 3, 45, 0 }; + static ulong[] dim16KuoInit = { 1, 3, 5, 1, 9, 21, 0 }; + static ulong[] dim17KuoInit = { 1, 1, 3, 13, 9, 9, 0 }; + static ulong[] dim18KuoInit = { 1, 3, 5, 7, 17, 53, 0 }; + static ulong[] dim19KuoInit = { 1, 3, 1, 7, 11, 51, 115, 0 }; + static ulong[] dim20KuoInit = { 1, 1, 7, 9, 25, 35, 11, 0 }; + static ulong[] dim21KuoInit = { 1, 3, 1, 1, 31, 5, 1, 0 }; + static ulong[] dim22KuoInit = { 1, 1, 5, 9, 11, 1, 121, 0 }; + static ulong[] dim23KuoInit = { 1, 1, 1, 15, 11, 59, 21, 0 }; + static ulong[] dim24KuoInit = { 1, 3, 1, 3, 17, 49, 51, 0 }; + static ulong[] dim25KuoInit = { 1, 1, 5, 7, 15, 25, 13, 0 }; + static ulong[] dim26KuoInit = { 1, 3, 7, 7, 1, 45, 7, 0 }; + static ulong[] dim27KuoInit = { 1, 1, 5, 7, 21, 21, 37, 0 }; + static ulong[] dim28KuoInit = { 1, 3, 1, 13, 9, 49, 23, 0 }; + static ulong[] dim29KuoInit = { 1, 1, 1, 3, 3, 35, 123, 0 }; + static ulong[] dim30KuoInit = { 1, 1, 7, 5, 15, 47, 117, 0 }; + static ulong[] dim31KuoInit = { 1, 1, 3, 13, 9, 23, 33, 0 }; + static ulong[] dim32KuoInit = { 1, 1, 1, 13, 25, 23, 63, 0 }; + static ulong[] dim33KuoInit = { 1, 1, 5, 3, 5, 13, 91, 0 }; + static ulong[] dim34KuoInit = { 1, 1, 5, 5, 23, 7, 101, 0 }; + static ulong[] dim35KuoInit = { 1, 3, 1, 11, 9, 61, 127, 0 }; + static ulong[] dim36KuoInit = { 1, 3, 1, 9, 1, 57, 93, 0 }; + static ulong[] dim37KuoInit = { 1, 1, 1, 1, 31, 31, 25, 231, 0 }; + static ulong[] dim38KuoInit = { 1, 3, 7, 7, 29, 17, 59, 215, 0 }; + static ulong[] dim39KuoInit = { 1, 1, 3, 15, 5, 63, 117, 217, 0 }; + static ulong[] dim40KuoInit = { 1, 3, 1, 1, 29, 5, 111, 51, 0 }; + static ulong[] dim41KuoInit = { 1, 1, 7, 1, 17, 37, 11, 53, 0 }; + static ulong[] dim42KuoInit = { 1, 3, 7, 15, 29, 5, 3, 67, 0 }; + static ulong[] dim43KuoInit = { 1, 3, 7, 11, 23, 27, 35, 143, 0 }; + static ulong[] dim44KuoInit = { 1, 1, 5, 11, 11, 33, 103, 179, 0 }; + static ulong[] dim45KuoInit = { 1, 3, 5, 7, 13, 45, 87, 143, 0 }; + static ulong[] dim46KuoInit = { 1, 3, 1, 13, 17, 17, 49, 249, 0 }; + static ulong[] dim47KuoInit = { 1, 1, 1, 3, 17, 29, 75, 143, 0 }; + static ulong[] dim48KuoInit = { 1, 1, 1, 3, 19, 55, 65, 109, 0 }; + static ulong[] dim49KuoInit = { 1, 1, 7, 3, 21, 29, 13, 191, 0 }; + static ulong[] dim50KuoInit = { 1, 1, 3, 7, 7, 5, 97, 179, 0 }; + static ulong[] dim51KuoInit = { 1, 3, 5, 13, 1, 17, 113, 149, 0 }; + static ulong[] dim52KuoInit = { 1, 3, 3, 11, 25, 13, 105, 75, 0 }; + static ulong[] dim53KuoInit = { 1, 3, 1, 13, 29, 33, 71, 117, 77, 0 }; + static ulong[] dim54KuoInit = { 1, 1, 1, 1, 31, 41, 9, 245, 205, 0 }; + static ulong[] dim55KuoInit = { 1, 1, 1, 15, 25, 23, 111, 105, 95, 0 }; + static ulong[] dim56KuoInit = { 1, 1, 3, 5, 3, 5, 81, 251, 221, 0 }; + static ulong[] dim57KuoInit = { 1, 3, 5, 5, 9, 53, 37, 41, 509, 0 }; + static ulong[] dim58KuoInit = { 1, 1, 5, 15, 21, 25, 77, 225, 333, 0 }; + static ulong[] dim59KuoInit = { 1, 3, 5, 13, 3, 17, 1, 101, 397, 0 }; + static ulong[] dim60KuoInit = { 1, 3, 5, 11, 27, 53, 115, 87, 47, 0 }; + static ulong[] dim61KuoInit = { 1, 1, 3, 11, 31, 39, 21, 233, 9, 0 }; + static ulong[] dim62KuoInit = { 1, 1, 3, 15, 17, 19, 73, 147, 351, 0 }; + static ulong[] dim63KuoInit = { 1, 1, 3, 3, 29, 17, 1, 105, 293, 0 }; + static ulong[] dim64KuoInit = { 1, 1, 3, 15, 9, 21, 103, 239, 433, 0 }; + static ulong[] dim65KuoInit = { 1, 1, 1, 15, 17, 35, 49, 7, 435, 0 }; + static ulong[] dim66KuoInit = { 1, 3, 7, 3, 9, 51, 91, 177, 255, 0 }; + static ulong[] dim67KuoInit = { 1, 1, 5, 5, 31, 9, 39, 209, 511, 0 }; + static ulong[] dim68KuoInit = { 1, 1, 7, 3, 11, 11, 19, 227, 343, 0 }; + static ulong[] dim69KuoInit = { 1, 3, 7, 3, 17, 13, 105, 151, 225, 0 }; + static ulong[] dim70KuoInit = { 1, 1, 7, 11, 29, 35, 105, 11, 497, 0 }; + static ulong[] dim71KuoInit = { 1, 3, 7, 15, 5, 13, 31, 201, 63, 0 }; + static ulong[] dim72KuoInit = { 1, 1, 5, 7, 17, 31, 9, 63, 167, 0 }; + static ulong[] dim73KuoInit = { 1, 1, 1, 13, 1, 51, 9, 115, 217, 0 }; + static ulong[] dim74KuoInit = { 1, 1, 7, 15, 23, 49, 125, 163, 39, 0 }; + static ulong[] dim75KuoInit = { 1, 1, 3, 13, 11, 45, 77, 149, 173, 0 }; + static ulong[] dim76KuoInit = { 1, 3, 3, 3, 7, 27, 43, 27, 361, 0 }; + static ulong[] dim77KuoInit = { 1, 3, 3, 5, 5, 37, 9, 51, 149, 0 }; + static ulong[] dim78KuoInit = { 1, 1, 1, 15, 13, 13, 49, 251, 385, 0 }; + static ulong[] dim79KuoInit = { 1, 1, 3, 7, 1, 57, 27, 25, 335, 0 }; + static ulong[] dim80KuoInit = { 1, 3, 3, 9, 31, 55, 41, 143, 97, 0 }; + static ulong[] dim81KuoInit = { 1, 3, 3, 11, 31, 33, 65, 57, 113, 0 }; + static ulong[] dim82KuoInit = { 1, 1, 5, 13, 19, 63, 5, 71, 317, 0 }; + static ulong[] dim83KuoInit = { 1, 1, 1, 5, 29, 45, 35, 107, 113, 0 }; + static ulong[] dim84KuoInit = { 1, 1, 3, 7, 3, 31, 81, 57, 439, 0 }; + static ulong[] dim85KuoInit = { 1, 3, 5, 5, 1, 7, 3, 21, 319, 0 }; + static ulong[] dim86KuoInit = { 1, 3, 1, 15, 27, 49, 25, 247, 455, 0 }; + static ulong[] dim87KuoInit = { 1, 1, 3, 5, 5, 43, 105, 207, 271, 0 }; + static ulong[] dim88KuoInit = { 1, 3, 3, 7, 29, 63, 25, 239, 165, 0 }; + static ulong[] dim89KuoInit = { 1, 3, 7, 1, 19, 23, 87, 23, 161, 0 }; + static ulong[] dim90KuoInit = { 1, 3, 7, 5, 27, 1, 15, 113, 85, 0 }; + static ulong[] dim91KuoInit = { 1, 1, 1, 13, 23, 39, 103, 59, 105, 0 }; + static ulong[] dim92KuoInit = { 1, 3, 1, 15, 9, 35, 65, 225, 385, 0 }; + static ulong[] dim93KuoInit = { 1, 1, 5, 9, 5, 63, 109, 153, 25, 0 }; + static ulong[] dim94KuoInit = { 1, 3, 7, 11, 5, 41, 103, 103, 245, 0 }; + static ulong[] dim95KuoInit = { 1, 1, 1, 3, 25, 5, 71, 203, 351, 0 }; + static ulong[] dim96KuoInit = { 1, 1, 5, 5, 27, 49, 111, 253, 265, 0 }; + static ulong[] dim97KuoInit = { 1, 1, 1, 11, 31, 63, 91, 179, 359, 0 }; + static ulong[] dim98KuoInit = { 1, 3, 7, 1, 9, 41, 117, 69, 141, 0 }; + static ulong[] dim99KuoInit = { 1, 3, 1, 5, 11, 25, 7, 73, 477, 0 }; + static ulong[] dim100KuoInit = { 1, 1, 3, 1, 31, 7, 51, 67, 97, 0 }; + static ulong[] dim101KuoInit = { 1, 3, 3, 15, 31, 61, 27, 137, 319, 605, 0 }; + static ulong[] dim102KuoInit = { 1, 3, 5, 7, 29, 45, 31, 211, 287, 13, 0 }; + static ulong[] dim103KuoInit = { 1, 3, 1, 7, 25, 61, 121, 91, 215, 439, 0 }; + static ulong[] dim104KuoInit = { 1, 1, 3, 11, 31, 51, 31, 151, 421, 195, 0 }; + static ulong[] dim105KuoInit = { 1, 1, 5, 13, 17, 23, 47, 9, 33, 1003, 0 }; + static ulong[] dim106KuoInit = { 1, 1, 1, 3, 23, 5, 109, 23, 125, 773, 0 }; + static ulong[] dim107KuoInit = { 1, 3, 5, 9, 7, 41, 33, 81, 277, 623, 0 }; + static ulong[] dim108KuoInit = { 1, 1, 1, 11, 9, 33, 51, 31, 181, 985, 0 }; + static ulong[] dim109KuoInit = { 1, 1, 7, 11, 3, 37, 3, 107, 405, 639, 0 }; + static ulong[] dim110KuoInit = { 1, 1, 5, 15, 17, 7, 35, 221, 255, 753, 0 }; + static ulong[] dim111KuoInit = { 1, 1, 7, 3, 31, 11, 113, 105, 275, 683, 0 }; + static ulong[] dim112KuoInit = { 1, 1, 3, 11, 3, 39, 57, 237, 189, 561, 0 }; + static ulong[] dim113KuoInit = { 1, 3, 3, 7, 17, 37, 55, 97, 499, 511, 0 }; + static ulong[] dim114KuoInit = { 1, 1, 7, 11, 31, 27, 21, 241, 127, 279, 0 }; + static ulong[] dim115KuoInit = { 1, 3, 1, 7, 1, 19, 95, 3, 511, 143, 0 }; + static ulong[] dim116KuoInit = { 1, 3, 5, 3, 21, 39, 115, 155, 67, 607, 0 }; + static ulong[] dim117KuoInit = { 1, 1, 7, 7, 25, 37, 33, 149, 89, 997, 0 }; + static ulong[] dim118KuoInit = { 1, 3, 1, 7, 3, 7, 113, 165, 235, 943, 0 }; + static ulong[] dim119KuoInit = { 1, 3, 7, 9, 29, 5, 93, 255, 323, 555, 0 }; + static ulong[] dim120KuoInit = { 1, 1, 1, 3, 13, 45, 89, 87, 29, 23, 0 }; + static ulong[] dim121KuoInit = { 1, 3, 3, 11, 11, 29, 75, 91, 211, 459, 0 }; + static ulong[] dim122KuoInit = { 1, 3, 5, 15, 11, 43, 105, 1, 227, 711, 0 }; + static ulong[] dim123KuoInit = { 1, 1, 5, 5, 13, 33, 29, 217, 511, 241, 0 }; + static ulong[] dim124KuoInit = { 1, 3, 7, 9, 1, 47, 125, 151, 375, 815, 0 }; + static ulong[] dim125KuoInit = { 1, 1, 1, 3, 25, 29, 5, 39, 133, 585, 0 }; + static ulong[] dim126KuoInit = { 1, 1, 5, 9, 9, 31, 79, 227, 395, 517, 0 }; + static ulong[] dim127KuoInit = { 1, 3, 3, 3, 15, 3, 47, 159, 233, 339, 0 }; + static ulong[] dim128KuoInit = { 1, 3, 5, 3, 15, 13, 79, 109, 187, 249, 0 }; + static ulong[] dim129KuoInit = { 1, 3, 1, 15, 23, 39, 85, 157, 323, 535, 0 }; + static ulong[] dim130KuoInit = { 1, 1, 1, 5, 11, 25, 5, 153, 19, 779, 0 }; + static ulong[] dim131KuoInit = { 1, 3, 5, 1, 9, 43, 27, 179, 407, 167, 0 }; + static ulong[] dim132KuoInit = { 1, 3, 5, 5, 25, 47, 21, 23, 57, 415, 0 }; + static ulong[] dim133KuoInit = { 1, 1, 1, 7, 3, 29, 45, 195, 349, 267, 0 }; + static ulong[] dim134KuoInit = { 1, 3, 5, 3, 19, 13, 61, 243, 125, 961, 0 }; + static ulong[] dim135KuoInit = { 1, 3, 7, 3, 29, 49, 7, 197, 387, 747, 0 }; + static ulong[] dim136KuoInit = { 1, 3, 7, 11, 31, 31, 109, 87, 345, 807, 0 }; + static ulong[] dim137KuoInit = { 1, 3, 1, 3, 21, 57, 43, 207, 221, 85, 0 }; + static ulong[] dim138KuoInit = { 1, 1, 3, 13, 19, 19, 41, 19, 509, 419, 0 }; + static ulong[] dim139KuoInit = { 1, 1, 3, 3, 23, 17, 85, 99, 421, 875, 0 }; + static ulong[] dim140KuoInit = { 1, 3, 1, 15, 27, 43, 89, 151, 39, 643, 0 }; + static ulong[] dim141KuoInit = { 1, 1, 1, 5, 3, 59, 25, 79, 319, 959, 0 }; + static ulong[] dim142KuoInit = { 1, 3, 5, 9, 3, 27, 71, 209, 195, 569, 0 }; + static ulong[] dim143KuoInit = { 1, 3, 3, 3, 11, 47, 67, 1, 221, 119, 0 }; + static ulong[] dim144KuoInit = { 1, 1, 5, 11, 11, 39, 95, 29, 7, 957, 0 }; + static ulong[] dim145KuoInit = { 1, 1, 7, 13, 13, 57, 47, 71, 165, 393, 0 }; + static ulong[] dim146KuoInit = { 1, 3, 5, 3, 5, 47, 127, 209, 377, 53, 0 }; + static ulong[] dim147KuoInit = { 1, 3, 1, 5, 13, 51, 69, 165, 477, 961, 0 }; + static ulong[] dim148KuoInit = { 1, 3, 5, 9, 25, 37, 5, 133, 117, 29, 0 }; + static ulong[] dim149KuoInit = { 1, 1, 1, 9, 7, 21, 95, 53, 205, 805, 0 }; + static ulong[] dim150KuoInit = { 1, 1, 5, 11, 25, 39, 25, 15, 497, 525, 0 }; + static ulong[] dim151KuoInit = { 1, 3, 5, 5, 15, 37, 33, 255, 97, 341, 0 }; + static ulong[] dim152KuoInit = { 1, 3, 1, 13, 31, 63, 35, 203, 415, 903, 0 }; + static ulong[] dim153KuoInit = { 1, 1, 5, 7, 13, 59, 55, 17, 103, 221, 0 }; + static ulong[] dim154KuoInit = { 1, 1, 5, 3, 7, 37, 113, 139, 269, 987, 0 }; + static ulong[] dim155KuoInit = { 1, 3, 3, 7, 21, 3, 47, 175, 327, 633, 0 }; + static ulong[] dim156KuoInit = { 1, 1, 1, 3, 13, 61, 19, 209, 39, 695, 0 }; + static ulong[] dim157KuoInit = { 1, 1, 1, 9, 31, 61, 21, 75, 445, 647, 0 }; + static ulong[] dim158KuoInit = { 1, 1, 5, 3, 21, 1, 65, 211, 405, 629, 0 }; + static ulong[] dim159KuoInit = { 1, 3, 7, 15, 9, 25, 119, 13, 465, 865, 0 }; + static ulong[] dim160KuoInit = { 1, 3, 1, 15, 29, 19, 103, 39, 37, 289, 0 }; + static ulong[] dim161KuoInit = { 1, 1, 1, 5, 25, 23, 21, 111, 455, 665, 1609, 0 }; + static ulong[] dim162KuoInit = { 1, 3, 3, 13, 27, 29, 45, 191, 385, 413, 1875, 0 }; + static ulong[] dim163KuoInit = { 1, 3, 7, 7, 19, 17, 47, 231, 337, 781, 1235, 0 }; + static ulong[] dim164KuoInit = { 1, 1, 5, 7, 7, 25, 99, 239, 501, 29, 159, 0 }; + static ulong[] dim165KuoInit = { 1, 1, 1, 3, 5, 19, 101, 147, 225, 353, 1117, 0 }; + static ulong[] dim166KuoInit = { 1, 3, 7, 11, 17, 57, 45, 73, 219, 853, 1379, 0 }; + static ulong[] dim167KuoInit = { 1, 3, 3, 7, 11, 47, 23, 67, 157, 283, 867, 0 }; + static ulong[] dim168KuoInit = { 1, 1, 7, 7, 23, 55, 71, 155, 237, 927, 929, 0 }; + static ulong[] dim169KuoInit = { 1, 3, 3, 15, 11, 19, 59, 147, 373, 619, 53, 0 }; + static ulong[] dim170KuoInit = { 1, 1, 3, 15, 13, 23, 11, 33, 45, 121, 241, 0 }; + static ulong[] dim171KuoInit = { 1, 1, 1, 9, 13, 29, 3, 131, 373, 91, 1207, 0 }; + static ulong[] dim172KuoInit = { 1, 1, 1, 15, 21, 29, 59, 197, 375, 637, 1275, 0 }; + static ulong[] dim173KuoInit = { 1, 1, 3, 11, 27, 31, 87, 95, 119, 249, 1913, 0 }; + static ulong[] dim174KuoInit = { 1, 3, 1, 5, 25, 51, 1, 241, 53, 883, 61, 0 }; + static ulong[] dim175KuoInit = { 1, 3, 1, 5, 23, 37, 83, 45, 287, 911, 717, 0 }; + static ulong[] dim176KuoInit = { 1, 3, 1, 3, 9, 39, 105, 129, 475, 399, 1783, 0 }; + static ulong[] dim177KuoInit = { 1, 3, 5, 5, 23, 11, 119, 205, 317, 797, 605, 0 }; + static ulong[] dim178KuoInit = { 1, 1, 7, 5, 13, 57, 19, 225, 53, 987, 1463, 0 }; + static ulong[] dim179KuoInit = { 1, 3, 5, 11, 3, 59, 1, 201, 97, 1011, 1059, 0 }; + static ulong[] dim180KuoInit = { 1, 3, 3, 9, 29, 51, 39, 199, 243, 877, 883, 0 }; + static ulong[] dim181KuoInit = { 1, 1, 3, 5, 29, 13, 97, 15, 387, 435, 701, 0 }; + static ulong[] dim182KuoInit = { 1, 3, 3, 11, 21, 41, 3, 119, 385, 503, 2015, 0 }; + static ulong[] dim183KuoInit = { 1, 3, 3, 1, 17, 9, 49, 13, 309, 29, 1501, 0 }; + static ulong[] dim184KuoInit = { 1, 3, 1, 3, 13, 29, 91, 51, 225, 989, 1701, 0 }; + static ulong[] dim185KuoInit = { 1, 1, 7, 13, 1, 55, 59, 243, 399, 65, 1725, 0 }; + static ulong[] dim186KuoInit = { 1, 3, 7, 7, 19, 29, 97, 161, 195, 257, 1595, 0 }; + static ulong[] dim187KuoInit = { 1, 3, 7, 15, 29, 49, 49, 23, 157, 363, 1355, 0 }; + static ulong[] dim188KuoInit = { 1, 3, 1, 13, 23, 39, 45, 73, 147, 323, 1965, 0 }; + static ulong[] dim189KuoInit = { 1, 3, 1, 15, 17, 27, 17, 19, 371, 387, 395, 0 }; + static ulong[] dim190KuoInit = { 1, 1, 1, 9, 19, 39, 31, 3, 291, 379, 605, 0 }; + static ulong[] dim191KuoInit = { 1, 1, 7, 1, 15, 17, 47, 133, 485, 145, 629, 0 }; + static ulong[] dim192KuoInit = { 1, 1, 1, 13, 11, 11, 117, 233, 85, 1, 1357, 0 }; + static ulong[] dim193KuoInit = { 1, 1, 7, 15, 19, 51, 115, 19, 333, 683, 917, 0 }; + static ulong[] dim194KuoInit = { 1, 3, 7, 9, 27, 47, 17, 209, 461, 261, 761, 0 }; + static ulong[] dim195KuoInit = { 1, 1, 3, 1, 27, 15, 43, 141, 291, 363, 605, 0 }; + static ulong[] dim196KuoInit = { 1, 3, 7, 5, 1, 3, 43, 75, 115, 653, 847, 0 }; + static ulong[] dim197KuoInit = { 1, 1, 3, 1, 11, 51, 69, 119, 195, 979, 1543, 0 }; + static ulong[] dim198KuoInit = { 1, 1, 7, 3, 11, 29, 29, 59, 339, 273, 855, 0 }; + static ulong[] dim199KuoInit = { 1, 1, 1, 1, 11, 15, 59, 97, 267, 647, 2037, 0 }; + static ulong[] dim200KuoInit = { 1, 1, 5, 3, 25, 43, 41, 195, 457, 155, 1707, 0 }; + static ulong[] dim201KuoInit = { 1, 3, 3, 15, 11, 47, 43, 15, 505, 761, 1259, 0 }; + static ulong[] dim202KuoInit = { 1, 3, 5, 15, 27, 29, 55, 109, 187, 545, 1177, 0 }; + static ulong[] dim203KuoInit = { 1, 3, 1, 5, 29, 25, 89, 11, 75, 771, 1437, 0 }; + static ulong[] dim204KuoInit = { 1, 3, 5, 11, 19, 17, 27, 59, 231, 35, 391, 0 }; + static ulong[] dim205KuoInit = { 1, 1, 7, 9, 3, 17, 31, 81, 317, 973, 1913, 0 }; + static ulong[] dim206KuoInit = { 1, 1, 1, 7, 3, 21, 113, 41, 335, 789, 1195, 0 }; + static ulong[] dim207KuoInit = { 1, 1, 7, 1, 13, 61, 41, 117, 301, 707, 693, 0 }; + static ulong[] dim208KuoInit = { 1, 1, 1, 7, 3, 1, 79, 145, 137, 307, 205, 0 }; + static ulong[] dim209KuoInit = { 1, 3, 7, 1, 27, 49, 83, 127, 265, 669, 87, 0 }; + static ulong[] dim210KuoInit = { 1, 1, 3, 15, 21, 31, 115, 115, 343, 55, 1049, 0 }; + static ulong[] dim211KuoInit = { 1, 1, 5, 9, 7, 25, 43, 255, 363, 123, 299, 0 }; + static ulong[] dim212KuoInit = { 1, 3, 5, 13, 1, 9, 79, 245, 91, 233, 1703, 0 }; + static ulong[] dim213KuoInit = { 1, 3, 5, 1, 17, 39, 81, 147, 147, 335, 819, 0 }; + static ulong[] dim214KuoInit = { 1, 3, 7, 3, 31, 63, 55, 53, 389, 307, 451, 0 }; + static ulong[] dim215KuoInit = { 1, 1, 7, 7, 23, 41, 125, 147, 323, 7, 1211, 0 }; + static ulong[] dim216KuoInit = { 1, 1, 1, 13, 23, 9, 35, 177, 165, 315, 1885, 0 }; + static ulong[] dim217KuoInit = { 1, 3, 3, 7, 11, 39, 99, 197, 405, 377, 555, 0 }; + static ulong[] dim218KuoInit = { 1, 3, 3, 11, 15, 39, 125, 59, 323, 377, 325, 0 }; + static ulong[] dim219KuoInit = { 1, 3, 5, 9, 7, 45, 75, 143, 265, 161, 1701, 0 }; + static ulong[] dim220KuoInit = { 1, 1, 7, 5, 31, 21, 35, 1, 511, 585, 923, 0 }; + static ulong[] dim221KuoInit = { 1, 3, 1, 5, 3, 31, 65, 33, 199, 205, 1673, 0 }; + static ulong[] dim222KuoInit = { 1, 3, 7, 9, 17, 61, 123, 33, 405, 235, 645, 0 }; + static ulong[] dim223KuoInit = { 1, 3, 3, 15, 27, 1, 35, 165, 509, 681, 621, 0 }; + static ulong[] dim224KuoInit = { 1, 3, 5, 15, 19, 13, 49, 85, 5, 661, 805, 0 }; + static ulong[] dim225KuoInit = { 1, 3, 7, 3, 3, 51, 77, 167, 461, 731, 1681, 0 }; + static ulong[] dim226KuoInit = { 1, 1, 3, 5, 21, 51, 125, 65, 41, 613, 1009, 0 }; + static ulong[] dim227KuoInit = { 1, 3, 7, 11, 17, 39, 127, 31, 423, 87, 1413, 0 }; + static ulong[] dim228KuoInit = { 1, 3, 1, 5, 11, 41, 25, 49, 169, 637, 1599, 0 }; + static ulong[] dim229KuoInit = { 1, 3, 5, 13, 31, 27, 75, 65, 391, 857, 1491, 0 }; + static ulong[] dim230KuoInit = { 1, 1, 1, 13, 5, 61, 65, 183, 373, 161, 235, 0 }; + static ulong[] dim231KuoInit = { 1, 3, 1, 1, 27, 49, 47, 55, 503, 683, 301, 0 }; + static ulong[] dim232KuoInit = { 1, 1, 7, 11, 17, 31, 113, 255, 281, 341, 2033, 0 }; + static ulong[] dim233KuoInit = { 1, 3, 3, 13, 27, 27, 27, 225, 161, 187, 485, 0 }; + static ulong[] dim234KuoInit = { 1, 1, 1, 3, 21, 27, 105, 215, 241, 211, 899, 0 }; + static ulong[] dim235KuoInit = { 1, 3, 5, 5, 11, 37, 1, 7, 335, 221, 757, 0 }; + static ulong[] dim236KuoInit = { 1, 1, 5, 7, 21, 55, 61, 99, 23, 957, 35, 0 }; + static ulong[] dim237KuoInit = { 1, 3, 5, 5, 13, 53, 31, 121, 111, 47, 1491, 0 }; + static ulong[] dim238KuoInit = { 1, 1, 5, 13, 17, 5, 11, 179, 357, 1003, 1179, 0 }; + static ulong[] dim239KuoInit = { 1, 1, 5, 13, 29, 9, 3, 91, 471, 369, 323, 0 }; + static ulong[] dim240KuoInit = { 1, 3, 7, 5, 7, 25, 109, 43, 133, 261, 1623, 0 }; + static ulong[] dim241KuoInit = { 1, 3, 7, 15, 13, 33, 125, 81, 491, 331, 1243, 0 }; + static ulong[] dim242KuoInit = { 1, 3, 3, 11, 15, 21, 57, 63, 55, 341, 1717, 0 }; + static ulong[] dim243KuoInit = { 1, 3, 1, 1, 31, 13, 67, 89, 459, 879, 863, 0 }; + static ulong[] dim244KuoInit = { 1, 3, 7, 15, 7, 21, 117, 229, 467, 227, 1463, 0 }; + static ulong[] dim245KuoInit = { 1, 1, 1, 7, 23, 43, 53, 79, 3, 905, 1049, 0 }; + static ulong[] dim246KuoInit = { 1, 3, 7, 1, 19, 1, 61, 15, 377, 579, 145, 0 }; + static ulong[] dim247KuoInit = { 1, 3, 1, 15, 27, 25, 61, 171, 425, 631, 1343, 0 }; + static ulong[] dim248KuoInit = { 1, 3, 7, 5, 15, 31, 69, 5, 217, 809, 647, 0 }; + static ulong[] dim249KuoInit = { 1, 1, 5, 3, 5, 35, 101, 21, 33, 757, 559, 0 }; + static ulong[] dim250KuoInit = { 1, 3, 5, 13, 3, 7, 101, 93, 31, 315, 1897, 0 }; + static ulong[] dim251KuoInit = { 1, 1, 3, 1, 21, 31, 37, 127, 211, 429, 1019, 0 }; + static ulong[] dim252KuoInit = { 1, 1, 3, 9, 11, 27, 113, 203, 115, 765, 759, 0 }; + static ulong[] dim253KuoInit = { 1, 1, 3, 13, 7, 21, 89, 99, 469, 729, 683, 0 }; + static ulong[] dim254KuoInit = { 1, 1, 1, 5, 27, 17, 43, 177, 225, 405, 1929, 0 }; + static ulong[] dim255KuoInit = { 1, 3, 1, 7, 21, 55, 69, 41, 309, 487, 681, 0 }; + static ulong[] dim256KuoInit = { 1, 3, 5, 11, 19, 21, 61, 163, 337, 61, 301, 0 }; + static ulong[] dim257KuoInit = { 1, 3, 1, 7, 21, 61, 67, 219, 281, 21, 1271, 0 }; + static ulong[] dim258KuoInit = { 1, 1, 5, 11, 5, 25, 51, 207, 235, 289, 395, 0 }; + static ulong[] dim259KuoInit = { 1, 1, 3, 3, 17, 61, 5, 179, 457, 941, 1577, 0 }; + static ulong[] dim260KuoInit = { 1, 1, 7, 7, 17, 23, 127, 35, 407, 545, 169, 0 }; + static ulong[] dim261KuoInit = { 1, 3, 7, 15, 21, 19, 123, 145, 97, 263, 1881, 0 }; + static ulong[] dim262KuoInit = { 1, 3, 7, 11, 25, 49, 117, 165, 79, 137, 1311, 0 }; + static ulong[] dim263KuoInit = { 1, 3, 1, 11, 3, 17, 9, 177, 367, 863, 1255, 0 }; + static ulong[] dim264KuoInit = { 1, 1, 5, 13, 9, 1, 31, 3, 69, 1009, 1091, 0 }; + static ulong[] dim265KuoInit = { 1, 3, 7, 15, 25, 41, 13, 3, 319, 131, 493, 0 }; + static ulong[] dim266KuoInit = { 1, 1, 1, 15, 9, 45, 25, 21, 405, 61, 1167, 0 }; + static ulong[] dim267KuoInit = { 1, 1, 1, 1, 31, 3, 95, 113, 475, 209, 1473, 0 }; + static ulong[] dim268KuoInit = { 1, 1, 5, 5, 27, 9, 95, 121, 193, 481, 1785, 0 }; + static ulong[] dim269KuoInit = { 1, 1, 3, 13, 1, 13, 57, 167, 273, 491, 867, 0 }; + static ulong[] dim270KuoInit = { 1, 1, 7, 1, 9, 27, 123, 65, 407, 609, 1979, 0 }; + static ulong[] dim271KuoInit = { 1, 3, 1, 15, 5, 5, 89, 17, 207, 249, 1725, 0 }; + static ulong[] dim272KuoInit = { 1, 3, 5, 11, 11, 15, 91, 33, 113, 531, 831, 0 }; + static ulong[] dim273KuoInit = { 1, 1, 5, 9, 27, 51, 17, 141, 215, 171, 455, 0 }; + static ulong[] dim274KuoInit = { 1, 1, 5, 9, 11, 25, 115, 5, 173, 209, 1455, 0 }; + static ulong[] dim275KuoInit = { 1, 1, 7, 7, 13, 51, 21, 79, 357, 423, 1855, 0 }; + static ulong[] dim276KuoInit = { 1, 1, 7, 1, 13, 37, 123, 27, 477, 1023, 1235, 0 }; + static ulong[] dim277KuoInit = { 1, 1, 7, 13, 25, 43, 123, 41, 199, 779, 1691, 0 }; + static ulong[] dim278KuoInit = { 1, 3, 3, 9, 7, 27, 81, 147, 465, 135, 829, 0 }; + static ulong[] dim279KuoInit = { 1, 1, 7, 11, 17, 5, 25, 177, 377, 629, 915, 0 }; + static ulong[] dim280KuoInit = { 1, 1, 3, 15, 11, 19, 45, 229, 409, 187, 507, 0 }; + static ulong[] dim281KuoInit = { 1, 1, 7, 5, 7, 49, 21, 49, 395, 185, 391, 0 }; + static ulong[] dim282KuoInit = { 1, 3, 1, 1, 1, 37, 123, 255, 223, 473, 1011, 0 }; + static ulong[] dim283KuoInit = { 1, 3, 3, 13, 3, 7, 113, 183, 457, 561, 1427, 0 }; + static ulong[] dim284KuoInit = { 1, 1, 1, 11, 27, 39, 125, 241, 279, 905, 1907, 0 }; + static ulong[] dim285KuoInit = { 1, 3, 1, 15, 19, 19, 9, 233, 39, 701, 939, 0 }; + static ulong[] dim286KuoInit = { 1, 3, 5, 11, 15, 51, 1, 25, 461, 671, 611, 0 }; + static ulong[] dim287KuoInit = { 1, 3, 1, 3, 23, 39, 23, 191, 219, 911, 1247, 0 }; + static ulong[] dim288KuoInit = { 1, 3, 1, 3, 1, 27, 91, 97, 55, 863, 805, 0 }; + static ulong[] dim289KuoInit = { 1, 3, 7, 7, 5, 63, 81, 33, 383, 645, 841, 0 }; + static ulong[] dim290KuoInit = { 1, 3, 7, 5, 27, 39, 33, 25, 185, 799, 1109, 0 }; + static ulong[] dim291KuoInit = { 1, 3, 1, 11, 11, 61, 109, 209, 345, 465, 935, 0 }; + static ulong[] dim292KuoInit = { 1, 3, 5, 13, 19, 55, 117, 237, 455, 953, 905, 0 }; + static ulong[] dim293KuoInit = { 1, 3, 7, 9, 9, 25, 77, 37, 111, 357, 131, 0 }; + static ulong[] dim294KuoInit = { 1, 1, 3, 13, 1, 51, 27, 235, 349, 517, 653, 0 }; + static ulong[] dim295KuoInit = { 1, 3, 7, 3, 27, 43, 23, 129, 455, 431, 1999, 0 }; + static ulong[] dim296KuoInit = { 1, 3, 7, 13, 11, 3, 19, 55, 261, 217, 535, 0 }; + static ulong[] dim297KuoInit = { 1, 3, 7, 7, 23, 53, 33, 237, 73, 421, 1439, 0 }; + static ulong[] dim298KuoInit = { 1, 1, 5, 5, 19, 7, 9, 201, 339, 33, 2019, 0 }; + static ulong[] dim299KuoInit = { 1, 3, 5, 7, 1, 3, 9, 79, 265, 125, 1063, 0 }; + static ulong[] dim300KuoInit = { 1, 1, 7, 11, 31, 61, 83, 71, 93, 393, 851, 0 }; + static ulong[] dim301KuoInit = { 1, 3, 1, 13, 13, 45, 65, 89, 87, 657, 1635, 0 }; + static ulong[] dim302KuoInit = { 1, 3, 5, 7, 21, 3, 27, 251, 287, 305, 1143, 0 }; + static ulong[] dim303KuoInit = { 1, 1, 3, 13, 5, 45, 35, 89, 61, 347, 1349, 0 }; + static ulong[] dim304KuoInit = { 1, 1, 7, 1, 7, 61, 19, 33, 11, 845, 839, 0 }; + static ulong[] dim305KuoInit = { 1, 3, 5, 15, 3, 1, 127, 245, 423, 57, 865, 0 }; + static ulong[] dim306KuoInit = { 1, 3, 5, 7, 31, 33, 53, 109, 397, 705, 307, 0 }; + static ulong[] dim307KuoInit = { 1, 3, 7, 7, 11, 51, 53, 75, 325, 61, 2035, 0 }; + static ulong[] dim308KuoInit = { 1, 3, 3, 9, 23, 37, 63, 115, 377, 741, 1181, 0 }; + static ulong[] dim309KuoInit = { 1, 1, 1, 13, 13, 7, 77, 171, 129, 615, 157, 0 }; + static ulong[] dim310KuoInit = { 1, 1, 5, 5, 9, 41, 59, 215, 275, 969, 31, 0 }; + static ulong[] dim311KuoInit = { 1, 1, 3, 1, 27, 1, 33, 111, 459, 503, 1703, 0 }; + static ulong[] dim312KuoInit = { 1, 3, 3, 9, 11, 41, 27, 213, 67, 203, 497, 0 }; + static ulong[] dim313KuoInit = { 1, 3, 3, 3, 1, 35, 39, 69, 457, 765, 903, 0 }; + static ulong[] dim314KuoInit = { 1, 3, 5, 11, 11, 31, 31, 195, 481, 831, 1727, 0 }; + static ulong[] dim315KuoInit = { 1, 3, 1, 1, 9, 39, 11, 179, 241, 945, 439, 0 }; + static ulong[] dim316KuoInit = { 1, 1, 5, 13, 1, 29, 37, 113, 193, 229, 1639, 0 }; + static ulong[] dim317KuoInit = { 1, 3, 5, 7, 9, 27, 75, 105, 449, 631, 2025, 0 }; + static ulong[] dim318KuoInit = { 1, 3, 7, 11, 7, 9, 73, 201, 273, 915, 729, 0 }; + static ulong[] dim319KuoInit = { 1, 3, 3, 15, 3, 41, 61, 5, 475, 193, 699, 0 }; + static ulong[] dim320KuoInit = { 1, 1, 3, 3, 13, 57, 51, 201, 313, 877, 507, 0 }; + static ulong[] dim321KuoInit = { 1, 1, 7, 9, 7, 3, 73, 103, 113, 719, 1747, 0 }; + static ulong[] dim322KuoInit = { 1, 1, 7, 1, 1, 25, 77, 249, 185, 583, 123, 0 }; + static ulong[] dim323KuoInit = { 1, 1, 5, 11, 25, 49, 17, 45, 161, 647, 1685, 0 }; + static ulong[] dim324KuoInit = { 1, 3, 1, 15, 15, 49, 35, 59, 47, 523, 1961, 0 }; + static ulong[] dim325KuoInit = { 1, 1, 5, 5, 19, 11, 105, 33, 333, 451, 45, 0 }; + static ulong[] dim326KuoInit = { 1, 3, 1, 7, 21, 1, 1, 15, 465, 731, 447, 0 }; + static ulong[] dim327KuoInit = { 1, 3, 5, 7, 3, 9, 31, 205, 479, 921, 1705, 0 }; + static ulong[] dim328KuoInit = { 1, 1, 7, 13, 7, 29, 55, 1, 293, 135, 1459, 0 }; + static ulong[] dim329KuoInit = { 1, 1, 7, 5, 19, 17, 7, 217, 133, 959, 811, 0 }; + static ulong[] dim330KuoInit = { 1, 1, 1, 15, 3, 37, 55, 223, 253, 535, 1039, 0 }; + static ulong[] dim331KuoInit = { 1, 3, 7, 3, 19, 47, 125, 117, 473, 257, 1215, 0 }; + static ulong[] dim332KuoInit = { 1, 1, 3, 5, 5, 1, 87, 95, 189, 431, 1355, 0 }; + static ulong[] dim333KuoInit = { 1, 1, 5, 11, 17, 5, 63, 15, 153, 325, 259, 0 }; + static ulong[] dim334KuoInit = { 1, 1, 3, 11, 9, 41, 101, 21, 161, 653, 1091, 0 }; + static ulong[] dim335KuoInit = { 1, 3, 3, 13, 5, 19, 37, 223, 469, 953, 15, 0 }; + static ulong[] dim336KuoInit = { 1, 1, 1, 5, 3, 33, 7, 63, 111, 685, 381, 0 }; + static ulong[] dim337KuoInit = { 1, 1, 3, 11, 31, 27, 49, 119, 277, 303, 1719, 909, 0 }; + static ulong[] dim338KuoInit = { 1, 3, 1, 11, 27, 13, 9, 107, 251, 759, 1641, 2177, 0 }; + static ulong[] dim339KuoInit = { 1, 3, 3, 3, 3, 57, 33, 169, 239, 357, 1519, 997, 0 }; + static ulong[] dim340KuoInit = { 1, 3, 3, 3, 11, 29, 53, 109, 411, 775, 1647, 819, 0 }; + static ulong[] dim341KuoInit = { 1, 1, 5, 13, 9, 3, 15, 219, 483, 513, 1319, 965, 0 }; + static ulong[] dim342KuoInit = { 1, 1, 1, 5, 3, 41, 9, 53, 303, 349, 1071, 681, 0 }; + static ulong[] dim343KuoInit = { 1, 3, 5, 15, 27, 15, 107, 211, 317, 283, 1317, 2661, 0 }; + static ulong[] dim344KuoInit = { 1, 3, 3, 1, 13, 41, 29, 17, 91, 985, 327, 1637, 0 }; + static ulong[] dim345KuoInit = { 1, 1, 3, 15, 27, 3, 127, 233, 177, 877, 1467, 3951, 0 }; + static ulong[] dim346KuoInit = { 1, 3, 1, 5, 1, 51, 5, 195, 501, 859, 905, 3163, 0 }; + static ulong[] dim347KuoInit = { 1, 1, 1, 5, 1, 25, 5, 205, 65, 435, 1645, 4013, 0 }; + static ulong[] dim348KuoInit = { 1, 3, 5, 13, 29, 57, 101, 59, 289, 701, 1363, 961, 0 }; + static ulong[] dim349KuoInit = { 1, 3, 7, 5, 1, 61, 33, 117, 311, 395, 1531, 2491, 0 }; + static ulong[] dim350KuoInit = { 1, 1, 1, 1, 5, 35, 15, 59, 201, 195, 1423, 2195, 0 }; + static ulong[] dim351KuoInit = { 1, 1, 7, 7, 13, 29, 37, 109, 481, 573, 1347, 3335, 0 }; + static ulong[] dim352KuoInit = { 1, 1, 5, 5, 25, 1, 63, 53, 419, 475, 1527, 3327, 0 }; + static ulong[] dim353KuoInit = { 1, 1, 3, 1, 27, 55, 75, 225, 379, 471, 211, 1655, 0 }; + static ulong[] dim354KuoInit = { 1, 1, 7, 15, 13, 61, 111, 95, 457, 801, 1865, 2529, 0 }; + static ulong[] dim355KuoInit = { 1, 3, 5, 5, 21, 3, 31, 97, 3, 495, 1953, 145, 0 }; + static ulong[] dim356KuoInit = { 1, 3, 3, 5, 13, 27, 31, 143, 133, 357, 1975, 1077, 0 }; + static ulong[] dim357KuoInit = { 1, 3, 3, 15, 19, 19, 23, 221, 9, 783, 1403, 4003, 0 }; + static ulong[] dim358KuoInit = { 1, 3, 7, 3, 5, 53, 63, 35, 209, 221, 1517, 1915, 0 }; + static ulong[] dim359KuoInit = { 1, 3, 3, 11, 27, 21, 53, 95, 359, 925, 1035, 3093, 0 }; + static ulong[] dim360KuoInit = { 1, 1, 3, 9, 9, 13, 25, 125, 101, 119, 1361, 3503, 0 }; + static ulong[] dim361KuoInit = { 1, 3, 7, 11, 19, 43, 125, 95, 113, 373, 655, 1001, 0 }; + static ulong[] dim362KuoInit = { 1, 1, 3, 15, 3, 29, 125, 5, 287, 859, 567, 3451, 0 }; + static ulong[] dim363KuoInit = { 1, 3, 1, 1, 7, 21, 67, 249, 487, 663, 2041, 799, 0 }; + static ulong[] dim364KuoInit = { 1, 1, 3, 9, 9, 29, 11, 229, 303, 821, 1187, 287, 0 }; + static ulong[] dim365KuoInit = { 1, 1, 5, 11, 25, 19, 77, 93, 209, 155, 1717, 4085, 0 }; + static ulong[] dim366KuoInit = { 1, 1, 3, 3, 23, 39, 5, 29, 295, 757, 1185, 817, 0 }; + static ulong[] dim367KuoInit = { 1, 3, 7, 7, 27, 25, 33, 73, 489, 543, 2011, 447, 0 }; + static ulong[] dim368KuoInit = { 1, 3, 1, 5, 21, 59, 107, 109, 415, 599, 325, 1457, 0 }; + static ulong[] dim369KuoInit = { 1, 3, 1, 5, 27, 61, 45, 129, 37, 923, 285, 2077, 0 }; + static ulong[] dim370KuoInit = { 1, 1, 1, 3, 11, 11, 17, 157, 289, 575, 749, 2463, 0 }; + static ulong[] dim371KuoInit = { 1, 1, 3, 7, 25, 1, 19, 177, 361, 831, 911, 1833, 0 }; + static ulong[] dim372KuoInit = { 1, 3, 7, 7, 25, 27, 11, 105, 489, 399, 483, 1287, 0 }; + static ulong[] dim373KuoInit = { 1, 3, 7, 11, 3, 49, 27, 63, 33, 991, 341, 2239, 0 }; + static ulong[] dim374KuoInit = { 1, 3, 1, 5, 3, 49, 23, 23, 157, 145, 1709, 1459, 0 }; + static ulong[] dim375KuoInit = { 1, 1, 5, 9, 29, 29, 5, 239, 201, 503, 229, 1943, 0 }; + static ulong[] dim376KuoInit = { 1, 3, 7, 3, 5, 39, 43, 127, 239, 679, 1225, 2123, 0 }; + static ulong[] dim377KuoInit = { 1, 1, 7, 11, 13, 17, 125, 253, 223, 67, 1319, 4019, 0 }; + static ulong[] dim378KuoInit = { 1, 3, 3, 3, 7, 57, 71, 131, 205, 953, 915, 1349, 0 }; + static ulong[] dim379KuoInit = { 1, 1, 1, 7, 1, 59, 77, 221, 227, 67, 1853, 2577, 0 }; + static ulong[] dim380KuoInit = { 1, 1, 7, 11, 31, 15, 103, 51, 505, 403, 1947, 1915, 0 }; + static ulong[] dim381KuoInit = { 1, 3, 3, 3, 15, 7, 41, 179, 265, 787, 1249, 3663, 0 }; + static ulong[] dim382KuoInit = { 1, 3, 1, 11, 27, 53, 123, 95, 427, 877, 471, 2167, 0 }; + static ulong[] dim383KuoInit = { 1, 1, 1, 9, 25, 7, 31, 47, 21, 299, 1397, 1119, 0 }; + static ulong[] dim384KuoInit = { 1, 3, 3, 9, 15, 49, 9, 255, 19, 995, 837, 2323, 0 }; + static ulong[] dim385KuoInit = { 1, 1, 7, 3, 31, 45, 35, 93, 179, 561, 1737, 3969, 0 }; + static ulong[] dim386KuoInit = { 1, 1, 1, 5, 7, 59, 27, 71, 9, 411, 59, 1783, 0 }; + static ulong[] dim387KuoInit = { 1, 3, 3, 7, 27, 17, 43, 37, 505, 893, 709, 3163, 0 }; + static ulong[] dim388KuoInit = { 1, 1, 5, 7, 7, 59, 47, 119, 39, 153, 259, 1409, 0 }; + static ulong[] dim389KuoInit = { 1, 3, 5, 1, 21, 29, 23, 153, 309, 137, 1015, 1527, 0 }; + static ulong[] dim390KuoInit = { 1, 1, 5, 15, 15, 27, 41, 15, 135, 707, 481, 2429, 0 }; + static ulong[] dim391KuoInit = { 1, 1, 7, 13, 1, 17, 95, 131, 497, 873, 193, 1683, 0 }; + static ulong[] dim392KuoInit = { 1, 1, 1, 13, 29, 39, 55, 51, 163, 581, 1867, 2219, 0 }; + static ulong[] dim393KuoInit = { 1, 1, 7, 3, 21, 29, 9, 111, 503, 7, 89, 3431, 0 }; + static ulong[] dim394KuoInit = { 1, 3, 7, 9, 13, 45, 61, 239, 61, 969, 77, 4053, 0 }; + static ulong[] dim395KuoInit = { 1, 1, 7, 11, 13, 29, 79, 39, 361, 635, 1867, 3051, 0 }; + static ulong[] dim396KuoInit = { 1, 3, 7, 3, 29, 11, 81, 193, 469, 365, 17, 3657, 0 }; + static ulong[] dim397KuoInit = { 1, 3, 3, 15, 13, 45, 69, 181, 95, 315, 1025, 1935, 0 }; + static ulong[] dim398KuoInit = { 1, 1, 5, 15, 31, 61, 97, 117, 207, 409, 69, 187, 0 }; + static ulong[] dim399KuoInit = { 1, 1, 5, 9, 27, 59, 123, 157, 409, 999, 905, 1097, 0 }; + static ulong[] dim400KuoInit = { 1, 1, 7, 1, 1, 51, 99, 143, 255, 817, 179, 3317, 0 }; + static ulong[] dim401KuoInit = { 1, 1, 1, 1, 23, 15, 117, 139, 245, 865, 1723, 3501, 0 }; + static ulong[] dim402KuoInit = { 1, 1, 5, 15, 25, 53, 9, 207, 291, 137, 291, 653, 0 }; + static ulong[] dim403KuoInit = { 1, 1, 3, 9, 9, 63, 55, 147, 199, 455, 2047, 2903, 0 }; + static ulong[] dim404KuoInit = { 1, 1, 5, 15, 29, 55, 85, 13, 117, 479, 1371, 2939, 0 }; + static ulong[] dim405KuoInit = { 1, 3, 3, 5, 17, 15, 33, 83, 359, 469, 463, 491, 0 }; + static ulong[] dim406KuoInit = { 1, 1, 3, 5, 23, 39, 35, 83, 387, 891, 789, 1469, 0 }; + static ulong[] dim407KuoInit = { 1, 3, 7, 9, 27, 49, 41, 49, 207, 39, 25, 2355, 0 }; + static ulong[] dim408KuoInit = { 1, 3, 5, 1, 5, 7, 29, 233, 169, 827, 1631, 2263, 0 }; + static ulong[] dim409KuoInit = { 1, 1, 1, 1, 1, 13, 97, 109, 255, 449, 345, 2533, 0 }; + static ulong[] dim410KuoInit = { 1, 3, 1, 5, 3, 15, 77, 217, 237, 57, 1711, 725, 0 }; + static ulong[] dim411KuoInit = { 1, 3, 3, 7, 9, 49, 93, 213, 487, 811, 1659, 3019, 0 }; + static ulong[] dim412KuoInit = { 1, 1, 1, 7, 7, 9, 57, 223, 263, 9, 443, 1103, 0 }; + static ulong[] dim413KuoInit = { 1, 1, 5, 11, 21, 11, 83, 239, 347, 489, 983, 677, 0 }; + static ulong[] dim414KuoInit = { 1, 1, 1, 11, 9, 29, 25, 105, 391, 1001, 1807, 1041, 0 }; + static ulong[] dim415KuoInit = { 1, 3, 3, 1, 11, 21, 89, 85, 259, 237, 1489, 3825, 0 }; + static ulong[] dim416KuoInit = { 1, 3, 5, 5, 1, 21, 53, 127, 269, 741, 529, 1649, 0 }; + static ulong[] dim417KuoInit = { 1, 3, 1, 7, 3, 35, 71, 65, 21, 985, 111, 2199, 0 }; + static ulong[] dim418KuoInit = { 1, 1, 5, 13, 3, 39, 33, 151, 95, 655, 1805, 1545, 0 }; + static ulong[] dim419KuoInit = { 1, 3, 1, 11, 17, 53, 63, 171, 275, 649, 1791, 3309, 0 }; + static ulong[] dim420KuoInit = { 1, 1, 7, 1, 3, 5, 63, 241, 77, 677, 1713, 1643, 0 }; + static ulong[] dim421KuoInit = { 1, 3, 3, 3, 9, 25, 7, 33, 277, 837, 1235, 3289, 0 }; + static ulong[] dim422KuoInit = { 1, 3, 3, 1, 27, 13, 97, 79, 145, 197, 1237, 1689, 0 }; + static ulong[] dim423KuoInit = { 1, 3, 5, 7, 27, 45, 71, 165, 405, 251, 383, 737, 0 }; + static ulong[] dim424KuoInit = { 1, 3, 7, 1, 13, 21, 107, 7, 207, 329, 1671, 2053, 0 }; + static ulong[] dim425KuoInit = { 1, 3, 7, 1, 31, 33, 25, 223, 37, 693, 1831, 2249, 0 }; + static ulong[] dim426KuoInit = { 1, 3, 3, 15, 5, 53, 111, 11, 317, 819, 1345, 401, 0 }; + static ulong[] dim427KuoInit = { 1, 3, 1, 9, 7, 61, 35, 127, 453, 565, 37, 17, 0 }; + static ulong[] dim428KuoInit = { 1, 3, 1, 1, 15, 3, 37, 133, 339, 181, 377, 2339, 0 }; + static ulong[] dim429KuoInit = { 1, 3, 7, 3, 27, 57, 27, 23, 45, 219, 455, 2821, 0 }; + static ulong[] dim430KuoInit = { 1, 3, 7, 9, 3, 43, 79, 67, 15, 797, 129, 1233, 0 }; + static ulong[] dim431KuoInit = { 1, 3, 5, 11, 5, 45, 123, 161, 355, 447, 1165, 2437, 0 }; + static ulong[] dim432KuoInit = { 1, 3, 7, 1, 3, 59, 65, 109, 253, 447, 649, 379, 0 }; + static ulong[] dim433KuoInit = { 1, 3, 1, 5, 21, 23, 45, 47, 213, 813, 1475, 1271, 0 }; + static ulong[] dim434KuoInit = { 1, 1, 1, 7, 9, 31, 91, 47, 161, 535, 1529, 881, 0 }; + static ulong[] dim435KuoInit = { 1, 1, 5, 13, 1, 25, 85, 107, 59, 487, 221, 51, 0 }; + static ulong[] dim436KuoInit = { 1, 1, 1, 1, 1, 55, 93, 95, 267, 157, 1255, 2115, 0 }; + static ulong[] dim437KuoInit = { 1, 3, 1, 11, 23, 55, 29, 187, 261, 139, 515, 2627, 0 }; + static ulong[] dim438KuoInit = { 1, 3, 3, 13, 31, 3, 121, 245, 475, 67, 195, 979, 0 }; + static ulong[] dim439KuoInit = { 1, 1, 3, 7, 25, 13, 79, 129, 475, 177, 1519, 1069, 0 }; + static ulong[] dim440KuoInit = { 1, 3, 3, 9, 17, 23, 83, 191, 133, 901, 1161, 1657, 0 }; + static ulong[] dim441KuoInit = { 1, 3, 7, 15, 23, 61, 111, 135, 107, 27, 583, 225, 0 }; + static ulong[] dim442KuoInit = { 1, 1, 5, 1, 17, 11, 31, 197, 111, 953, 1227, 3737, 0 }; + static ulong[] dim443KuoInit = { 1, 1, 3, 9, 19, 25, 83, 97, 489, 781, 1591, 2061, 0 }; + static ulong[] dim444KuoInit = { 1, 1, 1, 1, 9, 61, 31, 93, 39, 53, 1613, 3371, 0 }; + static ulong[] dim445KuoInit = { 1, 1, 1, 7, 3, 5, 103, 247, 255, 333, 31, 3087, 0 }; + static ulong[] dim446KuoInit = { 1, 1, 7, 7, 17, 35, 51, 153, 363, 897, 395, 1153, 0 }; + static ulong[] dim447KuoInit = { 1, 3, 7, 9, 3, 59, 127, 177, 191, 255, 1543, 503, 0 }; + static ulong[] dim448KuoInit = { 1, 1, 7, 3, 1, 7, 81, 199, 411, 565, 1717, 615, 0 }; + static ulong[] dim449KuoInit = { 1, 1, 1, 11, 17, 35, 35, 245, 507, 439, 523, 2343, 0 }; + static ulong[] dim450KuoInit = { 1, 1, 7, 15, 13, 61, 31, 99, 241, 605, 1575, 1321, 0 }; + static ulong[] dim451KuoInit = { 1, 3, 1, 5, 15, 31, 45, 89, 193, 905, 691, 3917, 0 }; + static ulong[] dim452KuoInit = { 1, 3, 3, 9, 29, 31, 101, 151, 187, 199, 1543, 3951, 0 }; + static ulong[] dim453KuoInit = { 1, 1, 7, 9, 21, 45, 71, 19, 395, 175, 503, 3759, 0 }; + static ulong[] dim454KuoInit = { 1, 3, 7, 7, 17, 31, 47, 7, 135, 719, 567, 1447, 0 }; + static ulong[] dim455KuoInit = { 1, 3, 3, 9, 1, 39, 1, 53, 5, 553, 371, 3833, 0 }; + static ulong[] dim456KuoInit = { 1, 1, 1, 11, 1, 33, 97, 209, 377, 187, 1683, 143, 0 }; + static ulong[] dim457KuoInit = { 1, 1, 1, 3, 29, 33, 111, 35, 343, 511, 273, 445, 0 }; + static ulong[] dim458KuoInit = { 1, 1, 1, 15, 15, 63, 73, 1, 111, 775, 665, 2737, 0 }; + static ulong[] dim459KuoInit = { 1, 1, 1, 9, 29, 23, 127, 77, 33, 131, 1055, 2351, 0 }; + static ulong[] dim460KuoInit = { 1, 3, 5, 7, 31, 53, 117, 57, 287, 221, 1099, 1147, 0 }; + static ulong[] dim461KuoInit = { 1, 3, 7, 15, 3, 17, 15, 177, 189, 379, 179, 1095, 0 }; + static ulong[] dim462KuoInit = { 1, 3, 1, 15, 25, 19, 43, 113, 123, 123, 877, 1869, 0 }; + static ulong[] dim463KuoInit = { 1, 3, 1, 1, 13, 63, 1, 83, 197, 215, 1005, 3531, 0 }; + static ulong[] dim464KuoInit = { 1, 3, 7, 1, 27, 25, 111, 199, 239, 909, 485, 3399, 0 }; + static ulong[] dim465KuoInit = { 1, 1, 7, 3, 19, 57, 43, 75, 163, 111, 359, 1987, 0 }; + static ulong[] dim466KuoInit = { 1, 1, 3, 7, 11, 63, 79, 235, 197, 757, 293, 3795, 0 }; + static ulong[] dim467KuoInit = { 1, 3, 5, 9, 13, 55, 49, 29, 133, 949, 1185, 905, 0 }; + static ulong[] dim468KuoInit = { 1, 1, 7, 1, 15, 51, 13, 223, 243, 831, 845, 2663, 0 }; + static ulong[] dim469KuoInit = { 1, 1, 3, 11, 25, 21, 65, 57, 483, 665, 741, 2713, 0 }; + static ulong[] dim470KuoInit = { 1, 3, 5, 3, 21, 3, 81, 57, 133, 553, 683, 425, 0 }; + static ulong[] dim471KuoInit = { 1, 1, 5, 11, 31, 29, 59, 189, 399, 751, 651, 4093, 0 }; + static ulong[] dim472KuoInit = { 1, 3, 3, 7, 13, 59, 19, 217, 267, 355, 173, 4051, 0 }; + static ulong[] dim473KuoInit = { 1, 1, 5, 9, 23, 49, 57, 145, 77, 591, 1913, 779, 0 }; + static ulong[] dim474KuoInit = { 1, 3, 7, 3, 25, 1, 83, 103, 393, 121, 1415, 1503, 0 }; + static ulong[] dim475KuoInit = { 1, 1, 7, 9, 23, 41, 35, 157, 63, 293, 1911, 2303, 0 }; + static ulong[] dim476KuoInit = { 1, 3, 5, 15, 7, 3, 9, 1, 201, 913, 1275, 3495, 0 }; + static ulong[] dim477KuoInit = { 1, 1, 7, 11, 15, 5, 107, 57, 53, 451, 351, 2621, 0 }; + static ulong[] dim478KuoInit = { 1, 3, 7, 15, 23, 25, 97, 29, 111, 531, 1979, 2115, 0 }; + static ulong[] dim479KuoInit = { 1, 1, 1, 1, 19, 11, 49, 229, 355, 195, 2033, 1701, 0 }; + static ulong[] dim480KuoInit = { 1, 3, 3, 3, 15, 35, 17, 13, 425, 285, 965, 159, 0 }; + static ulong[] dim481KuoInit = { 1, 3, 1, 11, 11, 11, 1, 145, 365, 471, 1527, 2309, 5863, 0 }; + static ulong[] dim482KuoInit = { 1, 1, 3, 9, 21, 59, 35, 123, 91, 741, 527, 2061, 5505, 0 }; + static ulong[] dim483KuoInit = { 1, 3, 7, 9, 9, 37, 75, 171, 75, 943, 443, 201, 4861, 0 }; + static ulong[] dim484KuoInit = { 1, 1, 7, 13, 23, 49, 67, 103, 453, 643, 1117, 1621, 7135, 0 }; + static ulong[] dim485KuoInit = { 1, 3, 1, 7, 15, 43, 113, 17, 277, 301, 349, 1155, 5285, 0 }; + static ulong[] dim486KuoInit = { 1, 3, 5, 1, 25, 61, 103, 81, 141, 347, 1467, 1535, 421, 0 }; + static ulong[] dim487KuoInit = { 1, 3, 5, 13, 29, 45, 43, 31, 403, 711, 455, 3387, 3521, 0 }; + static ulong[] dim488KuoInit = { 1, 3, 3, 7, 7, 41, 71, 251, 147, 241, 1129, 2093, 7683, 0 }; + static ulong[] dim489KuoInit = { 1, 1, 1, 5, 23, 61, 57, 97, 177, 387, 1557, 3587, 751, 0 }; + static ulong[] dim490KuoInit = { 1, 3, 1, 13, 11, 33, 47, 147, 321, 661, 53, 2437, 3087, 0 }; + static ulong[] dim491KuoInit = { 1, 3, 1, 3, 17, 21, 79, 91, 77, 1011, 745, 3551, 1857, 0 }; + static ulong[] dim492KuoInit = { 1, 1, 3, 15, 19, 27, 63, 231, 267, 879, 1959, 3019, 1655, 0 }; + static ulong[] dim493KuoInit = { 1, 1, 7, 15, 27, 55, 21, 37, 417, 69, 327, 2709, 6335, 0 }; + static ulong[] dim494KuoInit = { 1, 3, 1, 15, 1, 9, 27, 89, 205, 355, 373, 2191, 311, 0 }; + static ulong[] dim495KuoInit = { 1, 1, 3, 5, 15, 51, 85, 233, 21, 971, 1823, 1843, 1417, 0 }; + static ulong[] dim496KuoInit = { 1, 3, 5, 13, 31, 57, 3, 199, 211, 401, 1559, 3601, 4569, 0 }; + static ulong[] dim497KuoInit = { 1, 3, 3, 1, 27, 63, 93, 123, 223, 601, 1023, 2501, 7105, 0 }; + static ulong[] dim498KuoInit = { 1, 1, 1, 7, 3, 31, 5, 51, 453, 535, 255, 735, 749, 0 }; + static ulong[] dim499KuoInit = { 1, 3, 5, 9, 23, 63, 109, 163, 221, 845, 911, 933, 361, 0 }; + static ulong[] dim500KuoInit = { 1, 1, 1, 13, 13, 17, 19, 191, 227, 711, 1523, 1635, 6397, 0 }; + static ulong[] dim501KuoInit = { 1, 3, 7, 7, 21, 21, 23, 91, 439, 227, 1831, 1475, 705, 0 }; + static ulong[] dim502KuoInit = { 1, 3, 7, 7, 13, 39, 99, 199, 149, 1005, 149, 445, 3367, 0 }; + static ulong[] dim503KuoInit = { 1, 3, 1, 5, 25, 61, 99, 187, 33, 619, 1833, 2177, 7631, 0 }; + static ulong[] dim504KuoInit = { 1, 1, 1, 13, 15, 45, 1, 225, 129, 113, 2009, 1223, 49, 0 }; + static ulong[] dim505KuoInit = { 1, 3, 1, 9, 7, 43, 57, 193, 409, 265, 1151, 2635, 6005, 0 }; + static ulong[] dim506KuoInit = { 1, 3, 5, 5, 13, 13, 99, 163, 1, 629, 87, 925, 137, 0 }; + static ulong[] dim507KuoInit = { 1, 3, 7, 9, 23, 43, 43, 1, 505, 179, 335, 2033, 8065, 0 }; + static ulong[] dim508KuoInit = { 1, 3, 5, 1, 7, 55, 99, 159, 19, 883, 1503, 801, 1433, 0 }; + static ulong[] dim509KuoInit = { 1, 3, 7, 1, 1, 55, 53, 241, 95, 315, 723, 3571, 4685, 0 }; + static ulong[] dim510KuoInit = { 1, 3, 5, 15, 29, 43, 97, 159, 427, 87, 1995, 1849, 6771, 0 }; + static ulong[] dim511KuoInit = { 1, 1, 1, 7, 5, 55, 55, 203, 119, 185, 1333, 2107, 4271, 0 }; + static ulong[] dim512KuoInit = { 1, 1, 3, 15, 5, 7, 19, 185, 75, 601, 2015, 2175, 4259, 0 }; + static ulong[] dim513KuoInit = { 1, 3, 3, 15, 3, 49, 33, 115, 413, 321, 1787, 469, 3721, 0 }; + static ulong[] dim514KuoInit = { 1, 3, 1, 9, 25, 63, 123, 17, 355, 903, 1269, 3737, 5333, 0 }; + static ulong[] dim515KuoInit = { 1, 1, 3, 7, 25, 41, 113, 239, 373, 533, 1823, 3513, 7745, 0 }; + static ulong[] dim516KuoInit = { 1, 1, 1, 11, 13, 7, 7, 43, 145, 607, 2043, 2397, 4051, 0 }; + static ulong[] dim517KuoInit = { 1, 1, 3, 3, 9, 49, 5, 173, 63, 157, 637, 2307, 6603, 0 }; + static ulong[] dim518KuoInit = { 1, 3, 1, 3, 23, 33, 89, 139, 207, 389, 1389, 3385, 2169, 0 }; + static ulong[] dim519KuoInit = { 1, 1, 7, 3, 7, 7, 19, 7, 217, 189, 739, 2475, 7925, 0 }; + static ulong[] dim520KuoInit = { 1, 1, 7, 5, 23, 37, 71, 31, 145, 29, 537, 959, 2227, 0 }; + static ulong[] dim521KuoInit = { 1, 1, 7, 11, 7, 55, 39, 167, 347, 293, 577, 3077, 531, 0 }; + static ulong[] dim522KuoInit = { 1, 3, 1, 5, 19, 1, 119, 133, 487, 867, 1331, 1759, 3683, 0 }; + static ulong[] dim523KuoInit = { 1, 3, 5, 13, 27, 31, 77, 71, 465, 133, 105, 477, 6301, 0 }; + static ulong[] dim524KuoInit = { 1, 3, 5, 15, 25, 49, 35, 75, 57, 663, 195, 1041, 5697, 0 }; + static ulong[] dim525KuoInit = { 1, 3, 7, 9, 9, 7, 47, 233, 397, 155, 439, 2487, 4697, 0 }; + static ulong[] dim526KuoInit = { 1, 1, 5, 9, 5, 41, 125, 9, 477, 567, 2033, 769, 1553, 0 }; + static ulong[] dim527KuoInit = { 1, 1, 3, 7, 7, 25, 95, 45, 211, 453, 483, 3965, 1865, 0 }; + static ulong[] dim528KuoInit = { 1, 3, 7, 5, 17, 41, 109, 59, 385, 1023, 1527, 2445, 6303, 0 }; + static ulong[] dim529KuoInit = { 1, 3, 3, 9, 7, 29, 91, 245, 189, 251, 1237, 2825, 7919, 0 }; + static ulong[] dim530KuoInit = { 1, 3, 7, 1, 25, 43, 27, 11, 63, 641, 1765, 1683, 2445, 0 }; + static ulong[] dim531KuoInit = { 1, 1, 1, 7, 3, 59, 19, 81, 387, 207, 31, 1583, 607, 0 }; + static ulong[] dim532KuoInit = { 1, 1, 3, 1, 3, 33, 99, 135, 267, 355, 585, 4017, 2385, 0 }; + static ulong[] dim533KuoInit = { 1, 1, 7, 15, 1, 49, 35, 211, 359, 379, 1173, 2709, 3945, 0 }; + static ulong[] dim534KuoInit = { 1, 1, 5, 7, 29, 23, 99, 219, 269, 977, 1175, 2305, 5633, 0 }; + static ulong[] dim535KuoInit = { 1, 3, 3, 15, 17, 9, 115, 21, 503, 329, 1725, 289, 4667, 0 }; + static ulong[] dim536KuoInit = { 1, 1, 7, 1, 9, 1, 31, 145, 209, 833, 1527, 4021, 2177, 0 }; + static ulong[] dim537KuoInit = { 1, 3, 3, 1, 25, 13, 37, 143, 217, 891, 1289, 3635, 6931, 0 }; + static ulong[] dim538KuoInit = { 1, 1, 3, 9, 9, 49, 33, 123, 435, 993, 389, 2491, 2097, 0 }; + static ulong[] dim539KuoInit = { 1, 3, 5, 9, 11, 53, 121, 25, 31, 589, 1939, 3981, 621, 0 }; + static ulong[] dim540KuoInit = { 1, 1, 1, 1, 27, 53, 9, 217, 135, 605, 1779, 3053, 2865, 0 }; + static ulong[] dim541KuoInit = { 1, 1, 7, 5, 3, 53, 9, 15, 275, 613, 1395, 2287, 1111, 0 }; + static ulong[] dim542KuoInit = { 1, 1, 3, 1, 13, 17, 3, 103, 195, 509, 493, 2395, 4669, 0 }; + static ulong[] dim543KuoInit = { 1, 3, 5, 1, 13, 17, 59, 3, 117, 39, 1699, 2339, 5203, 0 }; + static ulong[] dim544KuoInit = { 1, 3, 5, 3, 29, 23, 59, 251, 139, 625, 935, 785, 7547, 0 }; + static ulong[] dim545KuoInit = { 1, 3, 1, 13, 23, 47, 5, 91, 283, 59, 919, 2427, 1631, 0 }; + static ulong[] dim546KuoInit = { 1, 1, 3, 9, 15, 35, 67, 131, 183, 891, 345, 3741, 3175, 0 }; + static ulong[] dim547KuoInit = { 1, 3, 1, 3, 23, 11, 85, 135, 269, 347, 713, 2947, 1617, 0 }; + static ulong[] dim548KuoInit = { 1, 3, 1, 3, 27, 33, 77, 189, 243, 893, 283, 885, 1999, 0 }; + static ulong[] dim549KuoInit = { 1, 1, 5, 1, 31, 39, 99, 21, 437, 979, 919, 3663, 6689, 0 }; + static ulong[] dim550KuoInit = { 1, 1, 1, 1, 17, 27, 55, 161, 205, 583, 383, 1681, 6445, 0 }; + static ulong[] dim551KuoInit = { 1, 3, 7, 1, 31, 59, 111, 129, 121, 555, 653, 2787, 3899, 0 }; + static ulong[] dim552KuoInit = { 1, 3, 1, 9, 11, 59, 51, 115, 349, 809, 513, 1585, 31, 0 }; + static ulong[] dim553KuoInit = { 1, 1, 1, 3, 29, 17, 3, 173, 111, 671, 1289, 397, 799, 0 }; + static ulong[] dim554KuoInit = { 1, 3, 1, 7, 17, 55, 85, 49, 23, 915, 1929, 685, 7021, 0 }; + static ulong[] dim555KuoInit = { 1, 3, 7, 11, 3, 41, 123, 227, 111, 805, 1567, 751, 7927, 0 }; + static ulong[] dim556KuoInit = { 1, 1, 7, 3, 15, 45, 117, 39, 491, 401, 1775, 2197, 4303, 0 }; + static ulong[] dim557KuoInit = { 1, 1, 7, 9, 13, 23, 63, 245, 163, 595, 1271, 2143, 8105, 0 }; + static ulong[] dim558KuoInit = { 1, 1, 3, 1, 31, 57, 45, 35, 327, 89, 1845, 1075, 4649, 0 }; + static ulong[] dim559KuoInit = { 1, 3, 7, 7, 11, 31, 51, 209, 103, 215, 1693, 3427, 677, 0 }; + static ulong[] dim560KuoInit = { 1, 1, 5, 13, 3, 7, 83, 199, 325, 461, 1185, 1997, 2327, 0 }; + static ulong[] dim561KuoInit = { 1, 1, 3, 15, 23, 13, 23, 39, 209, 267, 1995, 3999, 6277, 0 }; + static ulong[] dim562KuoInit = { 1, 1, 7, 1, 5, 37, 99, 117, 509, 303, 655, 935, 6321, 0 }; + static ulong[] dim563KuoInit = { 1, 1, 1, 15, 23, 39, 123, 11, 445, 897, 1327, 2819, 1899, 0 }; + static ulong[] dim564KuoInit = { 1, 1, 5, 5, 7, 7, 7, 61, 349, 865, 707, 2097, 1217, 0 }; + static ulong[] dim565KuoInit = { 1, 1, 5, 9, 1, 63, 35, 187, 207, 53, 1917, 621, 2113, 0 }; + static ulong[] dim566KuoInit = { 1, 1, 1, 15, 21, 61, 101, 169, 129, 813, 453, 323, 7283, 0 }; + static ulong[] dim567KuoInit = { 1, 1, 7, 7, 27, 1, 27, 141, 33, 307, 2023, 2561, 8111, 0 }; + static ulong[] dim568KuoInit = { 1, 1, 5, 13, 3, 9, 3, 87, 451, 691, 973, 539, 4393, 0 }; + static ulong[] dim569KuoInit = { 1, 1, 5, 1, 23, 23, 9, 101, 349, 299, 583, 2037, 5247, 0 }; + static ulong[] dim570KuoInit = { 1, 1, 5, 11, 15, 39, 99, 163, 395, 123, 1067, 2735, 4407, 0 }; + static ulong[] dim571KuoInit = { 1, 3, 5, 11, 9, 61, 51, 237, 483, 501, 1767, 1419, 5047, 0 }; + static ulong[] dim572KuoInit = { 1, 1, 7, 9, 27, 31, 57, 103, 291, 537, 1759, 1861, 3815, 0 }; + static ulong[] dim573KuoInit = { 1, 1, 5, 15, 31, 5, 107, 103, 159, 939, 1331, 1219, 2045, 0 }; + static ulong[] dim574KuoInit = { 1, 3, 5, 15, 7, 45, 99, 175, 131, 967, 593, 3191, 5403, 0 }; + static ulong[] dim575KuoInit = { 1, 3, 7, 11, 19, 43, 57, 129, 285, 943, 1507, 3979, 2807, 0 }; + static ulong[] dim576KuoInit = { 1, 1, 5, 3, 11, 7, 117, 241, 393, 1023, 95, 535, 7235, 0 }; + static ulong[] dim577KuoInit = { 1, 3, 1, 5, 17, 5, 111, 165, 343, 65, 1393, 2855, 3801, 0 }; + static ulong[] dim578KuoInit = { 1, 1, 5, 5, 27, 1, 87, 9, 177, 455, 1915, 1557, 7175, 0 }; + static ulong[] dim579KuoInit = { 1, 1, 5, 11, 31, 33, 105, 255, 281, 303, 1831, 1575, 1179, 0 }; + static ulong[] dim580KuoInit = { 1, 3, 3, 9, 7, 37, 3, 85, 161, 491, 299, 4003, 7429, 0 }; + static ulong[] dim581KuoInit = { 1, 1, 5, 9, 1, 19, 23, 175, 497, 613, 2043, 1467, 2379, 0 }; + static ulong[] dim582KuoInit = { 1, 3, 7, 13, 5, 57, 93, 17, 383, 801, 1465, 3151, 4717, 0 }; + static ulong[] dim583KuoInit = { 1, 3, 7, 5, 3, 19, 87, 25, 95, 643, 79, 123, 7175, 0 }; + static ulong[] dim584KuoInit = { 1, 1, 1, 5, 3, 27, 49, 155, 45, 655, 1079, 3243, 8147, 0 }; + static ulong[] dim585KuoInit = { 1, 3, 1, 11, 13, 57, 107, 37, 147, 119, 887, 1317, 6687, 0 }; + static ulong[] dim586KuoInit = { 1, 3, 3, 13, 29, 23, 105, 137, 339, 509, 1543, 2339, 2167, 0 }; + static ulong[] dim587KuoInit = { 1, 1, 5, 3, 29, 5, 89, 65, 191, 33, 755, 737, 3495, 0 }; + static ulong[] dim588KuoInit = { 1, 1, 5, 1, 19, 27, 123, 67, 323, 731, 1753, 1773, 1731, 0 }; + static ulong[] dim589KuoInit = { 1, 1, 5, 11, 23, 35, 21, 1, 107, 509, 1617, 1565, 1617, 0 }; + static ulong[] dim590KuoInit = { 1, 1, 7, 15, 31, 7, 31, 241, 479, 457, 1353, 1531, 5939, 0 }; + static ulong[] dim591KuoInit = { 1, 3, 1, 1, 31, 19, 71, 127, 379, 151, 739, 893, 7857, 0 }; + static ulong[] dim592KuoInit = { 1, 1, 1, 3, 31, 41, 99, 55, 229, 585, 1881, 2267, 3555, 0 }; + static ulong[] dim593KuoInit = { 1, 3, 3, 1, 25, 3, 55, 95, 409, 429, 527, 611, 6551, 0 }; + static ulong[] dim594KuoInit = { 1, 3, 5, 3, 3, 59, 81, 83, 131, 981, 67, 295, 3313, 0 }; + static ulong[] dim595KuoInit = { 1, 1, 1, 13, 23, 57, 47, 127, 307, 621, 865, 2589, 4033, 0 }; + static ulong[] dim596KuoInit = { 1, 1, 7, 11, 7, 17, 15, 207, 89, 77, 1923, 3649, 119, 0 }; + static ulong[] dim597KuoInit = { 1, 3, 5, 3, 23, 5, 87, 247, 233, 43, 475, 999, 6999, 0 }; + static ulong[] dim598KuoInit = { 1, 1, 7, 13, 19, 49, 53, 21, 105, 181, 1569, 3151, 5089, 0 }; + static ulong[] dim599KuoInit = { 1, 1, 5, 7, 11, 53, 119, 11, 301, 647, 759, 2849, 4541, 0 }; + static ulong[] dim600KuoInit = { 1, 1, 7, 11, 31, 31, 83, 107, 373, 41, 921, 3935, 2859, 0 }; + static ulong[] dim601KuoInit = { 1, 3, 5, 13, 13, 57, 121, 133, 355, 153, 607, 3199, 8097, 0 }; + static ulong[] dim602KuoInit = { 1, 1, 5, 9, 5, 25, 113, 21, 17, 643, 415, 2705, 903, 0 }; + static ulong[] dim603KuoInit = { 1, 1, 5, 1, 19, 3, 119, 199, 241, 957, 1203, 1291, 6355, 0 }; + static ulong[] dim604KuoInit = { 1, 1, 3, 13, 19, 1, 11, 73, 387, 97, 783, 3875, 4573, 0 }; + static ulong[] dim605KuoInit = { 1, 1, 7, 3, 27, 11, 99, 193, 311, 889, 535, 801, 4467, 0 }; + static ulong[] dim606KuoInit = { 1, 1, 1, 1, 3, 53, 61, 245, 497, 127, 1213, 1147, 2225, 0 }; + static ulong[] dim607KuoInit = { 1, 3, 5, 1, 9, 49, 21, 229, 481, 23, 47, 3959, 2991, 0 }; + static ulong[] dim608KuoInit = { 1, 1, 5, 1, 9, 21, 123, 107, 359, 759, 993, 695, 5609, 0 }; + static ulong[] dim609KuoInit = { 1, 3, 5, 11, 25, 55, 73, 245, 373, 525, 1399, 1727, 1763, 0 }; + static ulong[] dim610KuoInit = { 1, 1, 5, 3, 21, 41, 83, 161, 43, 563, 1655, 3539, 7941, 0 }; + static ulong[] dim611KuoInit = { 1, 3, 1, 13, 29, 59, 25, 119, 199, 375, 1507, 2095, 3281, 0 }; + static ulong[] dim612KuoInit = { 1, 3, 3, 5, 21, 23, 63, 85, 115, 77, 745, 771, 3319, 0 }; + static ulong[] dim613KuoInit = { 1, 1, 7, 3, 3, 37, 11, 233, 173, 51, 1723, 1441, 6529, 0 }; + static ulong[] dim614KuoInit = { 1, 1, 1, 11, 1, 55, 113, 25, 369, 1023, 1691, 1797, 159, 0 }; + static ulong[] dim615KuoInit = { 1, 3, 1, 15, 13, 43, 63, 113, 55, 351, 1459, 3117, 3499, 0 }; + static ulong[] dim616KuoInit = { 1, 3, 7, 1, 19, 61, 17, 243, 203, 349, 1069, 105, 6015, 0 }; + static ulong[] dim617KuoInit = { 1, 1, 5, 1, 23, 49, 7, 129, 99, 377, 1989, 531, 6315, 0 }; + static ulong[] dim618KuoInit = { 1, 1, 7, 7, 11, 23, 107, 63, 163, 351, 1385, 127, 7439, 0 }; + static ulong[] dim619KuoInit = { 1, 3, 5, 15, 15, 43, 81, 229, 21, 179, 1357, 3813, 7345, 0 }; + static ulong[] dim620KuoInit = { 1, 1, 1, 15, 23, 19, 89, 251, 161, 443, 983, 1059, 1241, 0 }; + static ulong[] dim621KuoInit = { 1, 3, 3, 9, 7, 17, 11, 239, 325, 117, 893, 917, 6327, 0 }; + static ulong[] dim622KuoInit = { 1, 1, 7, 1, 31, 33, 23, 241, 255, 991, 903, 3973, 3935, 0 }; + static ulong[] dim623KuoInit = { 1, 3, 7, 3, 11, 17, 61, 219, 461, 437, 1843, 1845, 771, 0 }; + static ulong[] dim624KuoInit = { 1, 3, 7, 5, 7, 61, 79, 225, 215, 411, 885, 3949, 2757, 0 }; + static ulong[] dim625KuoInit = { 1, 3, 7, 3, 3, 15, 25, 49, 351, 671, 1573, 3643, 2383, 0 }; + static ulong[] dim626KuoInit = { 1, 1, 7, 1, 29, 1, 121, 61, 49, 833, 1363, 427, 3237, 0 }; + static ulong[] dim627KuoInit = { 1, 3, 3, 5, 11, 9, 79, 113, 341, 25, 1797, 1641, 6899, 0 }; + static ulong[] dim628KuoInit = { 1, 1, 5, 9, 11, 15, 71, 169, 269, 359, 1991, 3673, 601, 0 }; + static ulong[] dim629KuoInit = { 1, 1, 1, 11, 31, 7, 5, 165, 23, 917, 617, 4059, 2599, 0 }; + static ulong[] dim630KuoInit = { 1, 1, 7, 9, 19, 25, 119, 103, 115, 247, 1265, 859, 5543, 0 }; + static ulong[] dim631KuoInit = { 1, 1, 7, 7, 15, 27, 45, 29, 67, 989, 753, 3215, 6281, 0 }; + static ulong[] dim632KuoInit = { 1, 3, 1, 7, 11, 15, 35, 39, 61, 483, 1427, 193, 3469, 0 }; + static ulong[] dim633KuoInit = { 1, 3, 5, 9, 21, 41, 21, 223, 233, 341, 177, 1167, 3101, 0 }; + static ulong[] dim634KuoInit = { 1, 3, 3, 5, 19, 25, 53, 247, 29, 909, 2047, 1683, 4433, 0 }; + static ulong[] dim635KuoInit = { 1, 3, 3, 9, 31, 7, 71, 85, 501, 447, 113, 3465, 3445, 0 }; + static ulong[] dim636KuoInit = { 1, 1, 3, 15, 19, 9, 127, 69, 429, 451, 531, 1319, 507, 0 }; + static ulong[] dim637KuoInit = { 1, 3, 1, 3, 29, 1, 53, 63, 267, 293, 333, 2749, 1785, 0 }; + static ulong[] dim638KuoInit = { 1, 3, 1, 7, 5, 43, 71, 165, 325, 309, 921, 2277, 6423, 0 }; + static ulong[] dim639KuoInit = { 1, 1, 7, 5, 23, 31, 63, 35, 221, 733, 1901, 153, 3577, 0 }; + static ulong[] dim640KuoInit = { 1, 3, 7, 11, 7, 5, 39, 141, 293, 237, 501, 1759, 7763, 0 }; + static ulong[] dim641KuoInit = { 1, 1, 3, 15, 1, 49, 5, 7, 239, 1021, 1215, 3857, 4637, 0 }; + static ulong[] dim642KuoInit = { 1, 1, 5, 1, 1, 31, 77, 243, 155, 505, 855, 3117, 815, 0 }; + static ulong[] dim643KuoInit = { 1, 1, 7, 3, 3, 33, 55, 249, 185, 443, 543, 1333, 5041, 0 }; + static ulong[] dim644KuoInit = { 1, 3, 5, 11, 13, 13, 83, 55, 443, 723, 135, 3073, 4215, 0 }; + static ulong[] dim645KuoInit = { 1, 3, 5, 9, 15, 5, 13, 209, 313, 891, 431, 4009, 7531, 0 }; + static ulong[] dim646KuoInit = { 1, 1, 5, 15, 13, 37, 91, 117, 321, 791, 2045, 4073, 6787, 0 }; + static ulong[] dim647KuoInit = { 1, 1, 3, 7, 1, 43, 61, 121, 393, 797, 1347, 491, 341, 0 }; + static ulong[] dim648KuoInit = { 1, 1, 7, 3, 1, 31, 63, 205, 43, 359, 325, 3329, 4961, 0 }; + static ulong[] dim649KuoInit = { 1, 1, 7, 11, 27, 21, 83, 151, 97, 45, 1839, 3221, 2575, 0 }; + static ulong[] dim650KuoInit = { 1, 3, 7, 3, 13, 7, 97, 89, 277, 351, 1493, 1161, 6629, 0 }; + static ulong[] dim651KuoInit = { 1, 3, 7, 11, 27, 17, 19, 211, 373, 73, 1325, 183, 1073, 0 }; + static ulong[] dim652KuoInit = { 1, 3, 3, 13, 9, 23, 111, 235, 153, 857, 1669, 3423, 3817, 0 }; + static ulong[] dim653KuoInit = { 1, 1, 1, 5, 25, 63, 99, 11, 283, 755, 999, 2795, 7795, 0 }; + static ulong[] dim654KuoInit = { 1, 1, 5, 11, 3, 53, 127, 73, 61, 91, 1099, 921, 1787, 0 }; + static ulong[] dim655KuoInit = { 1, 3, 5, 1, 9, 39, 9, 181, 287, 545, 1343, 2587, 961, 0 }; + static ulong[] dim656KuoInit = { 1, 3, 7, 5, 9, 47, 7, 113, 69, 531, 753, 2225, 5705, 0 }; + static ulong[] dim657KuoInit = { 1, 1, 3, 13, 29, 39, 71, 223, 179, 871, 1743, 2645, 7355, 0 }; + static ulong[] dim658KuoInit = { 1, 1, 7, 5, 1, 41, 87, 251, 303, 271, 791, 2825, 2723, 0 }; + static ulong[] dim659KuoInit = { 1, 3, 1, 11, 31, 15, 119, 127, 451, 161, 1909, 3591, 2811, 0 }; + static ulong[] dim660KuoInit = { 1, 1, 3, 13, 31, 27, 111, 119, 423, 419, 1659, 941, 6123, 0 }; + static ulong[] dim661KuoInit = { 1, 1, 1, 7, 27, 39, 27, 61, 417, 629, 1411, 1489, 5915, 0 }; + static ulong[] dim662KuoInit = { 1, 3, 3, 1, 29, 37, 111, 13, 129, 831, 1423, 3859, 7009, 0 }; + static ulong[] dim663KuoInit = { 1, 1, 1, 3, 3, 51, 67, 45, 289, 715, 183, 357, 3661, 0 }; + static ulong[] dim664KuoInit = { 1, 3, 3, 1, 23, 49, 55, 99, 77, 795, 429, 1815, 1867, 0 }; + static ulong[] dim665KuoInit = { 1, 1, 5, 7, 1, 37, 45, 27, 57, 937, 1583, 899, 819, 0 }; + static ulong[] dim666KuoInit = { 1, 3, 5, 7, 7, 37, 1, 109, 217, 203, 207, 2243, 2337, 0 }; + static ulong[] dim667KuoInit = { 1, 1, 3, 15, 27, 51, 119, 45, 289, 395, 95, 2425, 7421, 0 }; + static ulong[] dim668KuoInit = { 1, 3, 1, 9, 27, 61, 41, 227, 279, 31, 1105, 153, 5045, 0 }; + static ulong[] dim669KuoInit = { 1, 1, 7, 15, 31, 43, 109, 67, 347, 611, 1811, 2969, 3545, 0 }; + static ulong[] dim670KuoInit = { 1, 3, 1, 7, 17, 15, 103, 35, 407, 935, 1159, 2357, 6559, 0 }; + static ulong[] dim671KuoInit = { 1, 1, 1, 7, 5, 7, 101, 43, 301, 189, 641, 3015, 6955, 0 }; + static ulong[] dim672KuoInit = { 1, 3, 1, 1, 3, 41, 61, 43, 213, 595, 955, 377, 7527, 0 }; + static ulong[] dim673KuoInit = { 1, 3, 3, 15, 19, 45, 59, 57, 425, 683, 1187, 221, 4265, 0 }; + static ulong[] dim674KuoInit = { 1, 3, 5, 3, 27, 47, 85, 73, 67, 509, 555, 3887, 1883, 0 }; + static ulong[] dim675KuoInit = { 1, 3, 5, 13, 19, 45, 83, 191, 117, 723, 701, 2783, 389, 0 }; + static ulong[] dim676KuoInit = { 1, 1, 1, 3, 17, 21, 125, 13, 387, 613, 1647, 2555, 2435, 0 }; + static ulong[] dim677KuoInit = { 1, 3, 3, 11, 21, 53, 105, 5, 493, 167, 1195, 2815, 5761, 0 }; + static ulong[] dim678KuoInit = { 1, 1, 1, 7, 27, 17, 107, 83, 31, 787, 1541, 3761, 4083, 0 }; + static ulong[] dim679KuoInit = { 1, 3, 5, 11, 5, 15, 17, 219, 273, 207, 119, 1693, 373, 0 }; + static ulong[] dim680KuoInit = { 1, 1, 5, 15, 7, 11, 9, 103, 253, 377, 1667, 1159, 5669, 0 }; + static ulong[] dim681KuoInit = { 1, 3, 7, 5, 17, 55, 23, 77, 341, 419, 1165, 1625, 6609, 0 }; + static ulong[] dim682KuoInit = { 1, 3, 1, 15, 29, 7, 101, 183, 181, 111, 751, 247, 4205, 0 }; + static ulong[] dim683KuoInit = { 1, 1, 1, 11, 3, 5, 91, 43, 247, 661, 621, 2791, 4245, 0 }; + static ulong[] dim684KuoInit = { 1, 1, 1, 11, 11, 63, 25, 239, 39, 311, 1603, 1179, 4959, 0 }; + static ulong[] dim685KuoInit = { 1, 3, 1, 7, 23, 61, 49, 99, 287, 251, 1053, 3819, 5575, 0 }; + static ulong[] dim686KuoInit = { 1, 1, 1, 7, 21, 17, 33, 163, 503, 537, 1159, 2473, 8113, 0 }; + static ulong[] dim687KuoInit = { 1, 1, 5, 13, 23, 57, 57, 89, 503, 299, 1319, 2177, 8155, 0 }; + static ulong[] dim688KuoInit = { 1, 3, 3, 5, 5, 5, 61, 103, 247, 339, 1137, 3717, 747, 0 }; + static ulong[] dim689KuoInit = { 1, 3, 1, 7, 17, 55, 41, 155, 363, 873, 59, 2093, 4255, 0 }; + static ulong[] dim690KuoInit = { 1, 3, 3, 7, 9, 25, 93, 87, 479, 477, 2047, 321, 2277, 0 }; + static ulong[] dim691KuoInit = { 1, 1, 3, 11, 7, 37, 41, 237, 121, 187, 929, 1823, 313, 0 }; + static ulong[] dim692KuoInit = { 1, 1, 1, 11, 29, 41, 79, 11, 295, 715, 979, 2649, 915, 0 }; + static ulong[] dim693KuoInit = { 1, 1, 3, 13, 5, 9, 55, 159, 343, 887, 235, 53, 593, 0 }; + static ulong[] dim694KuoInit = { 1, 1, 1, 3, 13, 23, 105, 125, 405, 521, 897, 559, 1561, 0 }; + static ulong[] dim695KuoInit = { 1, 1, 3, 9, 23, 33, 121, 183, 181, 141, 1103, 821, 7193, 0 }; + static ulong[] dim696KuoInit = { 1, 1, 3, 9, 23, 1, 113, 63, 59, 783, 1525, 115, 3193, 0 }; + static ulong[] dim697KuoInit = { 1, 3, 1, 9, 23, 29, 83, 237, 83, 477, 1163, 2951, 3523, 0 }; + static ulong[] dim698KuoInit = { 1, 3, 5, 1, 21, 25, 55, 79, 39, 45, 1509, 2127, 5259, 0 }; + static ulong[] dim699KuoInit = { 1, 1, 7, 9, 31, 61, 83, 145, 89, 723, 393, 1543, 7765, 0 }; + static ulong[] dim700KuoInit = { 1, 1, 5, 15, 21, 17, 73, 189, 473, 1023, 1627, 2305, 7127, 0 }; + static ulong[] dim701KuoInit = { 1, 3, 1, 7, 7, 23, 61, 203, 373, 941, 975, 3225, 7659, 0 }; + static ulong[] dim702KuoInit = { 1, 3, 1, 15, 31, 19, 99, 197, 113, 131, 263, 2427, 2085, 0 }; + static ulong[] dim703KuoInit = { 1, 1, 1, 13, 25, 27, 3, 139, 351, 267, 1583, 913, 5497, 0 }; + static ulong[] dim704KuoInit = { 1, 3, 5, 11, 7, 1, 65, 85, 271, 151, 1003, 889, 6127, 0 }; + static ulong[] dim705KuoInit = { 1, 3, 7, 5, 21, 27, 39, 147, 139, 81, 1377, 1969, 6171, 0 }; + static ulong[] dim706KuoInit = { 1, 3, 5, 13, 1, 11, 101, 27, 285, 939, 1055, 3237, 7063, 0 }; + static ulong[] dim707KuoInit = { 1, 3, 3, 7, 23, 43, 67, 89, 201, 393, 277, 3531, 4003, 0 }; + static ulong[] dim708KuoInit = { 1, 3, 7, 9, 3, 13, 103, 241, 161, 111, 61, 4001, 6291, 0 }; + static ulong[] dim709KuoInit = { 1, 1, 5, 7, 5, 27, 57, 87, 313, 471, 227, 1395, 2821, 0 }; + static ulong[] dim710KuoInit = { 1, 3, 1, 5, 11, 35, 11, 157, 257, 679, 245, 329, 2423, 0 }; + static ulong[] dim711KuoInit = { 1, 1, 7, 11, 15, 5, 29, 229, 365, 911, 477, 219, 4851, 0 }; + static ulong[] dim712KuoInit = { 1, 3, 1, 9, 5, 57, 87, 19, 93, 403, 1729, 1843, 7301, 0 }; + static ulong[] dim713KuoInit = { 1, 1, 3, 3, 27, 29, 11, 99, 149, 917, 709, 3761, 6947, 0 }; + static ulong[] dim714KuoInit = { 1, 1, 5, 1, 19, 63, 69, 71, 209, 423, 2015, 3905, 2077, 0 }; + static ulong[] dim715KuoInit = { 1, 3, 7, 7, 7, 3, 9, 63, 137, 781, 1825, 1331, 2987, 0 }; + static ulong[] dim716KuoInit = { 1, 3, 7, 11, 15, 23, 7, 205, 27, 619, 225, 297, 8179, 0 }; + static ulong[] dim717KuoInit = { 1, 3, 3, 13, 11, 15, 11, 185, 343, 269, 1415, 843, 4001, 0 }; + static ulong[] dim718KuoInit = { 1, 3, 3, 1, 15, 47, 101, 49, 25, 933, 903, 1927, 6641, 0 }; + static ulong[] dim719KuoInit = { 1, 3, 3, 13, 7, 45, 29, 51, 143, 549, 119, 235, 7345, 0 }; + static ulong[] dim720KuoInit = { 1, 1, 3, 9, 29, 45, 53, 133, 173, 543, 545, 2015, 149, 0 }; + static ulong[] dim721KuoInit = { 1, 1, 3, 11, 3, 3, 109, 193, 349, 243, 1381, 3547, 4387, 0 }; + static ulong[] dim722KuoInit = { 1, 3, 7, 9, 7, 3, 37, 121, 79, 59, 1453, 3273, 477, 0 }; + static ulong[] dim723KuoInit = { 1, 3, 5, 15, 19, 15, 83, 5, 203, 603, 373, 955, 1587, 0 }; + static ulong[] dim724KuoInit = { 1, 1, 5, 11, 25, 41, 89, 47, 313, 443, 1799, 1827, 5881, 0 }; + static ulong[] dim725KuoInit = { 1, 1, 3, 5, 9, 7, 15, 87, 285, 509, 289, 855, 3131, 0 }; + static ulong[] dim726KuoInit = { 1, 1, 3, 11, 13, 57, 41, 235, 357, 213, 1867, 1961, 2759, 0 }; + static ulong[] dim727KuoInit = { 1, 3, 5, 9, 25, 15, 111, 197, 479, 539, 1833, 105, 7245, 0 }; + static ulong[] dim728KuoInit = { 1, 1, 5, 5, 23, 47, 101, 97, 97, 261, 1301, 3895, 5425, 0 }; + static ulong[] dim729KuoInit = { 1, 1, 7, 11, 13, 49, 39, 233, 7, 965, 2015, 1341, 941, 0 }; + static ulong[] dim730KuoInit = { 1, 1, 5, 7, 19, 63, 91, 77, 469, 367, 1849, 1213, 7611, 0 }; + static ulong[] dim731KuoInit = { 1, 3, 3, 15, 17, 57, 27, 107, 133, 431, 445, 2885, 5963, 0 }; + static ulong[] dim732KuoInit = { 1, 1, 3, 1, 27, 37, 119, 241, 403, 239, 833, 3057, 5557, 0 }; + static ulong[] dim733KuoInit = { 1, 3, 3, 13, 11, 47, 35, 41, 243, 143, 1923, 1883, 2543, 0 }; + static ulong[] dim734KuoInit = { 1, 1, 5, 5, 3, 15, 45, 205, 179, 515, 161, 895, 3679, 0 }; + static ulong[] dim735KuoInit = { 1, 3, 1, 1, 5, 39, 99, 221, 115, 983, 1913, 665, 7835, 0 }; + static ulong[] dim736KuoInit = { 1, 3, 5, 15, 5, 5, 111, 45, 373, 143, 1107, 1413, 2935, 0 }; + static ulong[] dim737KuoInit = { 1, 3, 7, 11, 17, 53, 77, 159, 319, 279, 835, 139, 3633, 0 }; + static ulong[] dim738KuoInit = { 1, 1, 7, 15, 5, 57, 105, 139, 491, 409, 51, 2875, 427, 0 }; + static ulong[] dim739KuoInit = { 1, 1, 1, 9, 9, 9, 93, 45, 265, 307, 589, 557, 3971, 0 }; + static ulong[] dim740KuoInit = { 1, 3, 5, 3, 23, 45, 5, 9, 123, 841, 679, 2213, 4507, 0 }; + static ulong[] dim741KuoInit = { 1, 3, 5, 3, 27, 55, 55, 19, 405, 43, 1897, 3515, 683, 0 }; + static ulong[] dim742KuoInit = { 1, 1, 7, 15, 23, 47, 121, 105, 341, 707, 799, 1843, 7011, 0 }; + static ulong[] dim743KuoInit = { 1, 1, 3, 13, 23, 51, 71, 161, 415, 819, 729, 297, 4461, 0 }; + static ulong[] dim744KuoInit = { 1, 3, 5, 15, 13, 39, 43, 103, 251, 583, 775, 877, 4947, 0 }; + static ulong[] dim745KuoInit = { 1, 3, 7, 5, 19, 61, 121, 49, 75, 963, 297, 3751, 911, 0 }; + static ulong[] dim746KuoInit = { 1, 3, 5, 7, 15, 51, 23, 23, 453, 675, 1575, 473, 3763, 0 }; + static ulong[] dim747KuoInit = { 1, 1, 7, 11, 9, 37, 69, 137, 251, 89, 1823, 1289, 2983, 0 }; + static ulong[] dim748KuoInit = { 1, 3, 3, 5, 11, 39, 39, 231, 427, 633, 1453, 579, 5823, 0 }; + static ulong[] dim749KuoInit = { 1, 3, 7, 11, 31, 57, 87, 81, 161, 929, 1293, 3215, 4803, 0 }; + static ulong[] dim750KuoInit = { 1, 3, 5, 5, 27, 33, 11, 151, 25, 1017, 41, 61, 4381, 0 }; + static ulong[] dim751KuoInit = { 1, 3, 1, 15, 23, 25, 7, 21, 231, 407, 817, 2089, 839, 0 }; + static ulong[] dim752KuoInit = { 1, 1, 7, 1, 5, 51, 117, 59, 251, 861, 727, 481, 2207, 0 }; + static ulong[] dim753KuoInit = { 1, 1, 5, 3, 21, 19, 97, 199, 135, 203, 1177, 2751, 2863, 0 }; + static ulong[] dim754KuoInit = { 1, 3, 7, 3, 27, 3, 5, 109, 17, 933, 911, 921, 1173, 0 }; + static ulong[] dim755KuoInit = { 1, 3, 7, 1, 7, 1, 121, 205, 381, 971, 255, 3313, 5479, 0 }; + static ulong[] dim756KuoInit = { 1, 3, 1, 1, 17, 59, 3, 5, 271, 149, 111, 3707, 7893, 0 }; + static ulong[] dim757KuoInit = { 1, 1, 1, 1, 17, 61, 47, 117, 187, 839, 435, 399, 3173, 0 }; + static ulong[] dim758KuoInit = { 1, 3, 3, 7, 5, 9, 119, 191, 197, 791, 375, 3361, 6677, 0 }; + static ulong[] dim759KuoInit = { 1, 1, 5, 3, 21, 49, 69, 249, 39, 69, 673, 109, 7051, 0 }; + static ulong[] dim760KuoInit = { 1, 1, 3, 11, 21, 37, 121, 93, 261, 5, 1269, 767, 2801, 0 }; + static ulong[] dim761KuoInit = { 1, 1, 5, 9, 31, 49, 9, 87, 375, 773, 1517, 3057, 2169, 0 }; + static ulong[] dim762KuoInit = { 1, 1, 5, 3, 13, 33, 31, 87, 353, 991, 1809, 859, 6117, 0 }; + static ulong[] dim763KuoInit = { 1, 1, 5, 11, 3, 21, 103, 41, 129, 137, 1567, 3483, 5317, 0 }; + static ulong[] dim764KuoInit = { 1, 3, 5, 1, 3, 31, 5, 15, 109, 723, 1439, 2543, 2377, 0 }; + static ulong[] dim765KuoInit = { 1, 3, 3, 13, 11, 17, 9, 243, 233, 543, 903, 2775, 6877, 0 }; + static ulong[] dim766KuoInit = { 1, 1, 7, 1, 23, 45, 61, 137, 207, 457, 245, 3833, 6533, 0 }; + static ulong[] dim767KuoInit = { 1, 3, 1, 1, 31, 7, 71, 153, 501, 749, 1477, 621, 6577, 0 }; + static ulong[] dim768KuoInit = { 1, 3, 1, 13, 3, 45, 3, 233, 85, 847, 1031, 141, 5029, 0 }; + static ulong[] dim769KuoInit = { 1, 3, 1, 13, 17, 35, 49, 157, 243, 175, 905, 539, 8059, 0 }; + static ulong[] dim770KuoInit = { 1, 3, 1, 11, 19, 45, 31, 49, 399, 341, 2047, 1527, 5993, 0 }; + static ulong[] dim771KuoInit = { 1, 3, 1, 3, 5, 5, 33, 163, 239, 607, 1367, 2747, 1513, 0 }; + static ulong[] dim772KuoInit = { 1, 3, 3, 11, 9, 29, 33, 255, 29, 955, 367, 1709, 4993, 0 }; + static ulong[] dim773KuoInit = { 1, 3, 7, 5, 19, 35, 11, 47, 109, 235, 1125, 4019, 5395, 0 }; + static ulong[] dim774KuoInit = { 1, 1, 7, 1, 19, 29, 43, 1, 199, 479, 1025, 1065, 2203, 0 }; + static ulong[] dim775KuoInit = { 1, 3, 1, 9, 17, 13, 45, 167, 125, 869, 1667, 1083, 4015, 0 }; + static ulong[] dim776KuoInit = { 1, 1, 5, 11, 27, 45, 115, 199, 375, 761, 1641, 3761, 5509, 0 }; + static ulong[] dim777KuoInit = { 1, 1, 7, 15, 9, 47, 47, 133, 401, 555, 1077, 1381, 1903, 0 }; + static ulong[] dim778KuoInit = { 1, 3, 3, 15, 3, 45, 19, 49, 377, 135, 239, 3605, 1053, 0 }; + static ulong[] dim779KuoInit = { 1, 3, 1, 11, 17, 5, 83, 101, 247, 267, 1337, 2649, 513, 0 }; + static ulong[] dim780KuoInit = { 1, 3, 1, 11, 13, 41, 41, 113, 243, 463, 1077, 565, 2871, 0 }; + static ulong[] dim781KuoInit = { 1, 3, 5, 11, 19, 63, 81, 51, 139, 921, 2021, 417, 1305, 0 }; + static ulong[] dim782KuoInit = { 1, 3, 3, 1, 23, 61, 13, 123, 135, 521, 1963, 3085, 4395, 0 }; + static ulong[] dim783KuoInit = { 1, 3, 1, 1, 15, 61, 17, 245, 479, 77, 287, 3043, 2647, 0 }; + static ulong[] dim784KuoInit = { 1, 1, 7, 15, 29, 5, 125, 123, 149, 919, 1779, 3763, 1479, 0 }; + static ulong[] dim785KuoInit = { 1, 1, 3, 1, 19, 49, 27, 127, 253, 279, 739, 147, 6835, 0 }; + static ulong[] dim786KuoInit = { 1, 3, 5, 11, 21, 27, 33, 85, 419, 441, 1341, 289, 2759, 0 }; + static ulong[] dim787KuoInit = { 1, 3, 1, 3, 3, 9, 17, 99, 375, 251, 1823, 2433, 1525, 0 }; + static ulong[] dim788KuoInit = { 1, 3, 1, 3, 5, 55, 25, 225, 473, 825, 1061, 2987, 4397, 0 }; + static ulong[] dim789KuoInit = { 1, 1, 7, 15, 23, 59, 9, 163, 105, 911, 905, 3715, 4917, 0 }; + static ulong[] dim790KuoInit = { 1, 3, 1, 11, 21, 53, 127, 3, 507, 467, 547, 3003, 6939, 0 }; + static ulong[] dim791KuoInit = { 1, 1, 1, 13, 15, 7, 1, 7, 101, 645, 1469, 843, 2843, 0 }; + static ulong[] dim792KuoInit = { 1, 3, 3, 9, 11, 35, 95, 53, 291, 459, 669, 1163, 4893, 0 }; + static ulong[] dim793KuoInit = { 1, 1, 3, 3, 25, 29, 29, 223, 21, 553, 177, 3347, 3575, 0 }; + static ulong[] dim794KuoInit = { 1, 1, 5, 1, 23, 17, 21, 57, 383, 427, 397, 1947, 2627, 0 }; + static ulong[] dim795KuoInit = { 1, 3, 7, 1, 21, 53, 79, 59, 133, 461, 1703, 3071, 4679, 0 }; + static ulong[] dim796KuoInit = { 1, 3, 5, 1, 27, 31, 83, 159, 505, 121, 1969, 1073, 2117, 0 }; + static ulong[] dim797KuoInit = { 1, 1, 3, 1, 19, 25, 43, 115, 191, 845, 1923, 903, 2319, 0 }; + static ulong[] dim798KuoInit = { 1, 1, 3, 9, 27, 37, 31, 111, 437, 925, 501, 883, 3485, 0 }; + static ulong[] dim799KuoInit = { 1, 3, 5, 5, 15, 25, 51, 131, 149, 811, 1827, 1519, 1435, 0 }; + static ulong[] dim800KuoInit = { 1, 1, 7, 13, 3, 39, 103, 107, 473, 553, 1763, 399, 2137, 0 }; + static ulong[] dim801KuoInit = { 1, 3, 7, 13, 27, 25, 49, 29, 497, 863, 1715, 99, 1521, 0 }; + static ulong[] dim802KuoInit = { 1, 1, 1, 9, 27, 37, 67, 59, 11, 369, 893, 2249, 5303, 0 }; + static ulong[] dim803KuoInit = { 1, 3, 3, 13, 19, 9, 93, 29, 247, 35, 833, 1037, 7137, 0 }; + static ulong[] dim804KuoInit = { 1, 3, 7, 3, 25, 17, 63, 239, 395, 367, 1935, 2095, 5191, 0 }; + static ulong[] dim805KuoInit = { 1, 3, 5, 15, 23, 51, 13, 101, 477, 511, 1951, 2505, 4155, 0 }; + static ulong[] dim806KuoInit = { 1, 3, 3, 15, 3, 55, 15, 173, 21, 699, 1617, 1573, 2645, 0 }; + static ulong[] dim807KuoInit = { 1, 1, 3, 11, 7, 55, 69, 165, 255, 397, 2033, 9, 843, 0 }; + static ulong[] dim808KuoInit = { 1, 3, 1, 13, 5, 3, 37, 99, 165, 971, 555, 2379, 7879, 0 }; + static ulong[] dim809KuoInit = { 1, 1, 5, 3, 19, 37, 23, 197, 145, 315, 981, 161, 323, 0 }; + static ulong[] dim810KuoInit = { 1, 1, 7, 7, 17, 37, 27, 189, 371, 145, 1097, 2801, 5469, 0 }; + static ulong[] dim811KuoInit = { 1, 1, 3, 9, 23, 15, 39, 7, 25, 221, 757, 1393, 4629, 0 }; + static ulong[] dim812KuoInit = { 1, 1, 1, 1, 13, 31, 29, 197, 237, 173, 337, 743, 1459, 0 }; + static ulong[] dim813KuoInit = { 1, 1, 5, 15, 17, 7, 127, 29, 307, 965, 1567, 2771, 6053, 0 }; + static ulong[] dim814KuoInit = { 1, 3, 1, 1, 13, 57, 41, 59, 77, 67, 1985, 3443, 7495, 0 }; + static ulong[] dim815KuoInit = { 1, 3, 7, 15, 17, 21, 57, 143, 179, 99, 217, 1763, 873, 0 }; + static ulong[] dim816KuoInit = { 1, 1, 7, 1, 21, 17, 123, 39, 95, 775, 1865, 341, 6167, 0 }; + static ulong[] dim817KuoInit = { 1, 3, 7, 3, 31, 33, 33, 163, 281, 765, 1809, 1469, 7011, 0 }; + static ulong[] dim818KuoInit = { 1, 3, 7, 7, 25, 35, 45, 109, 221, 25, 757, 597, 3057, 0 }; + static ulong[] dim819KuoInit = { 1, 3, 5, 3, 27, 25, 97, 21, 351, 841, 1339, 565, 7181, 0 }; + static ulong[] dim820KuoInit = { 1, 1, 1, 15, 23, 61, 97, 57, 503, 379, 25, 1197, 6957, 0 }; + static ulong[] dim821KuoInit = { 1, 3, 3, 3, 13, 49, 127, 89, 329, 503, 1957, 3569, 7013, 0 }; + static ulong[] dim822KuoInit = { 1, 1, 7, 7, 7, 15, 43, 61, 227, 859, 279, 3309, 1941, 0 }; + static ulong[] dim823KuoInit = { 1, 3, 1, 9, 19, 1, 111, 45, 315, 339, 1049, 121, 2711, 0 }; + static ulong[] dim824KuoInit = { 1, 1, 3, 11, 7, 33, 121, 253, 267, 845, 1677, 569, 3743, 0 }; + static ulong[] dim825KuoInit = { 1, 3, 7, 9, 9, 53, 113, 11, 177, 165, 1707, 2027, 2099, 0 }; + static ulong[] dim826KuoInit = { 1, 1, 5, 7, 19, 41, 33, 129, 389, 249, 1945, 1393, 5941, 0 }; + static ulong[] dim827KuoInit = { 1, 1, 1, 1, 27, 37, 63, 171, 301, 179, 223, 3775, 1189, 0 }; + static ulong[] dim828KuoInit = { 1, 3, 3, 5, 5, 33, 101, 37, 505, 561, 1681, 567, 2197, 0 }; + static ulong[] dim829KuoInit = { 1, 3, 7, 13, 25, 23, 29, 27, 325, 757, 5, 487, 3241, 0 }; + static ulong[] dim830KuoInit = { 1, 3, 3, 7, 27, 13, 85, 35, 171, 565, 969, 773, 7173, 0 }; + static ulong[] dim831KuoInit = { 1, 3, 5, 5, 11, 55, 33, 243, 401, 939, 73, 775, 1159, 0 }; + static ulong[] dim832KuoInit = { 1, 1, 3, 13, 13, 63, 9, 161, 343, 547, 1659, 1005, 8041, 0 }; + static ulong[] dim833KuoInit = { 1, 3, 5, 7, 15, 27, 27, 51, 475, 957, 445, 3745, 5113, 0 }; + static ulong[] dim834KuoInit = { 1, 1, 3, 7, 15, 49, 63, 181, 15, 1, 1915, 633, 1039, 0 }; + static ulong[] dim835KuoInit = { 1, 3, 7, 1, 1, 11, 15, 221, 375, 59, 1471, 113, 5661, 0 }; + static ulong[] dim836KuoInit = { 1, 3, 5, 5, 11, 41, 115, 87, 263, 173, 1249, 2235, 6863, 0 }; + static ulong[] dim837KuoInit = { 1, 1, 5, 11, 19, 1, 61, 25, 239, 5, 1869, 2269, 3911, 0 }; + static ulong[] dim838KuoInit = { 1, 3, 5, 7, 23, 59, 99, 47, 439, 105, 455, 547, 2447, 0 }; + static ulong[] dim839KuoInit = { 1, 1, 7, 15, 25, 15, 117, 185, 83, 243, 1099, 2613, 7721, 0 }; + static ulong[] dim840KuoInit = { 1, 3, 1, 9, 5, 49, 27, 237, 239, 177, 1507, 2059, 1731, 0 }; + static ulong[] dim841KuoInit = { 1, 3, 3, 11, 29, 47, 119, 243, 475, 443, 111, 787, 2597, 0 }; + static ulong[] dim842KuoInit = { 1, 1, 7, 1, 25, 39, 95, 107, 391, 149, 397, 3755, 2735, 0 }; + static ulong[] dim843KuoInit = { 1, 3, 7, 11, 13, 49, 37, 135, 99, 473, 1961, 1233, 7359, 0 }; + static ulong[] dim844KuoInit = { 1, 3, 5, 11, 29, 59, 123, 53, 371, 573, 1099, 3035, 3217, 0 }; + static ulong[] dim845KuoInit = { 1, 1, 1, 11, 25, 47, 105, 147, 317, 69, 1201, 3781, 2457, 0 }; + static ulong[] dim846KuoInit = { 1, 1, 5, 9, 3, 31, 25, 127, 153, 303, 1367, 3583, 5229, 0 }; + static ulong[] dim847KuoInit = { 1, 1, 3, 13, 25, 33, 11, 101, 85, 741, 1191, 1769, 4119, 0 }; + static ulong[] dim848KuoInit = { 1, 1, 3, 13, 19, 59, 81, 71, 255, 277, 991, 2183, 3257, 0 }; + static ulong[] dim849KuoInit = { 1, 3, 1, 3, 23, 27, 89, 237, 249, 837, 759, 43, 5571, 0 }; + static ulong[] dim850KuoInit = { 1, 1, 1, 9, 15, 35, 45, 213, 423, 159, 353, 3123, 6399, 0 }; + static ulong[] dim851KuoInit = { 1, 1, 5, 9, 15, 45, 83, 65, 115, 513, 361, 1877, 4307, 0 }; + static ulong[] dim852KuoInit = { 1, 1, 7, 11, 17, 61, 15, 143, 491, 253, 443, 3521, 7611, 0 }; + static ulong[] dim853KuoInit = { 1, 1, 3, 11, 11, 49, 117, 117, 279, 715, 1365, 689, 4339, 0 }; + static ulong[] dim854KuoInit = { 1, 1, 3, 13, 3, 53, 123, 89, 91, 471, 1723, 1811, 1285, 0 }; + static ulong[] dim855KuoInit = { 1, 3, 7, 13, 7, 5, 99, 235, 465, 915, 1813, 3137, 7645, 0 }; + static ulong[] dim856KuoInit = { 1, 3, 3, 13, 5, 45, 37, 99, 459, 541, 225, 2417, 6385, 0 }; + static ulong[] dim857KuoInit = { 1, 1, 1, 15, 19, 39, 109, 21, 117, 589, 1261, 3695, 4251, 0 }; + static ulong[] dim858KuoInit = { 1, 1, 7, 11, 23, 43, 35, 43, 135, 509, 1331, 1567, 7085, 0 }; + static ulong[] dim859KuoInit = { 1, 1, 5, 5, 23, 3, 61, 151, 171, 295, 1377, 2165, 2125, 0 }; + static ulong[] dim860KuoInit = { 1, 3, 3, 5, 3, 57, 17, 73, 71, 55, 1373, 2067, 3249, 0 }; + static ulong[] dim861KuoInit = { 1, 1, 5, 9, 25, 39, 65, 75, 141, 849, 237, 3719, 6705, 0 }; + static ulong[] dim862KuoInit = { 1, 1, 7, 1, 17, 17, 23, 91, 333, 749, 657, 3267, 3343, 0 }; + static ulong[] dim863KuoInit = { 1, 3, 1, 5, 5, 27, 15, 107, 345, 405, 111, 345, 5505, 0 }; + static ulong[] dim864KuoInit = { 1, 3, 3, 13, 1, 9, 19, 63, 427, 995, 1257, 923, 267, 0 }; + static ulong[] dim865KuoInit = { 1, 1, 1, 7, 21, 19, 65, 249, 401, 729, 1403, 1579, 3443, 0 }; + static ulong[] dim866KuoInit = { 1, 3, 5, 1, 3, 43, 81, 11, 473, 1011, 1755, 117, 2881, 0 }; + static ulong[] dim867KuoInit = { 1, 1, 7, 13, 3, 63, 95, 11, 23, 895, 1591, 2623, 6887, 0 }; + static ulong[] dim868KuoInit = { 1, 3, 1, 3, 17, 11, 39, 165, 367, 363, 1207, 2555, 5437, 0 }; + static ulong[] dim869KuoInit = { 1, 1, 1, 7, 17, 9, 19, 175, 7, 535, 1779, 3341, 4825, 0 }; + static ulong[] dim870KuoInit = { 1, 1, 7, 3, 27, 7, 19, 217, 479, 143, 1189, 2809, 339, 0 }; + static ulong[] dim871KuoInit = { 1, 3, 7, 9, 25, 41, 9, 39, 391, 331, 1427, 2321, 1673, 0 }; + static ulong[] dim872KuoInit = { 1, 3, 1, 13, 7, 17, 11, 27, 125, 799, 1325, 517, 1043, 0 }; + static ulong[] dim873KuoInit = { 1, 1, 3, 15, 29, 11, 73, 11, 289, 1, 839, 3311, 7535, 0 }; + static ulong[] dim874KuoInit = { 1, 1, 1, 11, 11, 59, 25, 47, 153, 297, 679, 1441, 7105, 0 }; + static ulong[] dim875KuoInit = { 1, 3, 5, 7, 25, 29, 13, 227, 379, 247, 449, 679, 6581, 0 }; + static ulong[] dim876KuoInit = { 1, 1, 1, 5, 9, 59, 81, 195, 289, 705, 183, 1, 3703, 0 }; + static ulong[] dim877KuoInit = { 1, 3, 3, 9, 31, 1, 71, 155, 307, 467, 1699, 269, 6077, 0 }; + static ulong[] dim878KuoInit = { 1, 3, 1, 11, 31, 21, 59, 225, 385, 623, 117, 1435, 3195, 0 }; + static ulong[] dim879KuoInit = { 1, 1, 7, 9, 3, 43, 97, 15, 145, 279, 1785, 545, 3977, 0 }; + static ulong[] dim880KuoInit = { 1, 1, 5, 9, 25, 27, 113, 193, 31, 255, 691, 3315, 7005, 0 }; + static ulong[] dim881KuoInit = { 1, 3, 7, 5, 9, 19, 69, 87, 379, 931, 1567, 1391, 4765, 0 }; + static ulong[] dim882KuoInit = { 1, 1, 1, 15, 15, 23, 127, 69, 113, 801, 1923, 2847, 1073, 0 }; + static ulong[] dim883KuoInit = { 1, 1, 1, 1, 21, 51, 65, 133, 465, 739, 2029, 2243, 4023, 0 }; + static ulong[] dim884KuoInit = { 1, 1, 5, 11, 9, 41, 71, 217, 317, 855, 275, 1965, 3151, 0 }; + static ulong[] dim885KuoInit = { 1, 1, 7, 5, 19, 3, 81, 127, 423, 415, 565, 1941, 5079, 0 }; + static ulong[] dim886KuoInit = { 1, 1, 3, 1, 19, 19, 117, 169, 353, 159, 1235, 845, 2381, 0 }; + static ulong[] dim887KuoInit = { 1, 3, 1, 15, 21, 27, 77, 5, 113, 201, 311, 2263, 7855, 0 }; + static ulong[] dim888KuoInit = { 1, 3, 5, 9, 5, 21, 41, 119, 447, 983, 1703, 2707, 2789, 0 }; + static ulong[] dim889KuoInit = { 1, 1, 5, 3, 5, 19, 9, 131, 269, 999, 1259, 3843, 7753, 0 }; + static ulong[] dim890KuoInit = { 1, 3, 7, 11, 25, 27, 91, 187, 177, 921, 163, 1141, 4903, 0 }; + static ulong[] dim891KuoInit = { 1, 3, 1, 7, 15, 21, 67, 155, 335, 149, 2011, 2483, 7015, 0 }; + static ulong[] dim892KuoInit = { 1, 1, 1, 7, 3, 53, 29, 119, 21, 933, 595, 3141, 7925, 0 }; + static ulong[] dim893KuoInit = { 1, 1, 1, 9, 21, 33, 55, 87, 451, 297, 1615, 697, 2299, 0 }; + static ulong[] dim894KuoInit = { 1, 3, 1, 9, 9, 5, 3, 113, 197, 137, 1105, 1949, 4651, 0 }; + static ulong[] dim895KuoInit = { 1, 1, 7, 3, 7, 27, 109, 99, 121, 463, 621, 887, 5847, 0 }; + static ulong[] dim896KuoInit = { 1, 3, 7, 7, 31, 61, 21, 69, 443, 81, 151, 3601, 699, 0 }; + static ulong[] dim897KuoInit = { 1, 1, 7, 11, 7, 63, 97, 241, 87, 961, 1279, 1715, 3183, 0 }; + static ulong[] dim898KuoInit = { 1, 1, 3, 5, 7, 41, 5, 123, 189, 283, 1775, 49, 6107, 0 }; + static ulong[] dim899KuoInit = { 1, 1, 7, 15, 7, 19, 71, 117, 195, 67, 1583, 3371, 777, 0 }; + static ulong[] dim900KuoInit = { 1, 1, 1, 15, 19, 43, 81, 103, 173, 209, 447, 1735, 5023, 0 }; + static ulong[] dim901KuoInit = { 1, 1, 5, 15, 15, 9, 99, 185, 451, 605, 1429, 1257, 6825, 0 }; + static ulong[] dim902KuoInit = { 1, 3, 1, 11, 11, 21, 79, 13, 23, 607, 1601, 3603, 147, 0 }; + static ulong[] dim903KuoInit = { 1, 1, 3, 1, 27, 51, 83, 191, 59, 281, 1853, 1441, 5359, 0 }; + static ulong[] dim904KuoInit = { 1, 1, 1, 11, 31, 17, 117, 239, 385, 465, 1787, 2645, 6047, 0 }; + static ulong[] dim905KuoInit = { 1, 1, 7, 5, 17, 59, 111, 143, 419, 163, 763, 2327, 1741, 0 }; + static ulong[] dim906KuoInit = { 1, 1, 1, 3, 3, 43, 3, 203, 1, 373, 1829, 3493, 2347, 0 }; + static ulong[] dim907KuoInit = { 1, 3, 7, 13, 21, 17, 89, 147, 51, 665, 397, 2475, 3393, 0 }; + static ulong[] dim908KuoInit = { 1, 3, 7, 15, 19, 33, 1, 211, 155, 355, 1137, 1633, 5025, 0 }; + static ulong[] dim909KuoInit = { 1, 3, 3, 9, 7, 63, 127, 59, 205, 645, 2047, 1187, 2711, 0 }; + static ulong[] dim910KuoInit = { 1, 3, 3, 5, 7, 59, 125, 35, 285, 811, 1489, 3269, 2737, 0 }; + static ulong[] dim911KuoInit = { 1, 1, 7, 3, 15, 39, 75, 229, 213, 23, 1825, 2269, 6739, 0 }; + static ulong[] dim912KuoInit = { 1, 1, 3, 7, 1, 5, 73, 173, 305, 681, 1225, 2475, 6981, 0 }; + static ulong[] dim913KuoInit = { 1, 1, 5, 3, 21, 3, 27, 241, 475, 543, 1065, 2731, 1739, 0 }; + static ulong[] dim914KuoInit = { 1, 3, 7, 13, 19, 35, 57, 19, 307, 113, 451, 1897, 2135, 0 }; + static ulong[] dim915KuoInit = { 1, 1, 3, 11, 31, 13, 63, 15, 477, 389, 829, 2167, 3317, 0 }; + static ulong[] dim916KuoInit = { 1, 1, 7, 11, 9, 39, 1, 41, 99, 295, 1009, 1411, 3423, 0 }; + static ulong[] dim917KuoInit = { 1, 1, 5, 9, 15, 17, 93, 171, 361, 51, 455, 2413, 7295, 0 }; + static ulong[] dim918KuoInit = { 1, 1, 5, 13, 7, 27, 127, 153, 163, 635, 1065, 2243, 3813, 0 }; + static ulong[] dim919KuoInit = { 1, 1, 7, 9, 15, 45, 7, 241, 365, 447, 1435, 3473, 715, 0 }; + static ulong[] dim920KuoInit = { 1, 1, 5, 9, 9, 11, 21, 21, 255, 717, 1579, 217, 6921, 0 }; + static ulong[] dim921KuoInit = { 1, 1, 5, 15, 25, 21, 31, 47, 455, 631, 971, 3105, 2219, 0 }; + static ulong[] dim922KuoInit = { 1, 3, 1, 7, 9, 1, 75, 85, 351, 555, 1379, 1361, 6163, 0 }; + static ulong[] dim923KuoInit = { 1, 3, 5, 7, 9, 63, 19, 99, 335, 173, 1385, 3011, 5787, 0 }; + static ulong[] dim924KuoInit = { 1, 3, 5, 1, 23, 35, 79, 163, 97, 213, 1281, 1739, 477, 0 }; + static ulong[] dim925KuoInit = { 1, 1, 5, 5, 9, 13, 41, 167, 349, 959, 925, 1383, 883, 0 }; + static ulong[] dim926KuoInit = { 1, 3, 7, 7, 17, 23, 69, 241, 447, 31, 767, 2981, 253, 0 }; + static ulong[] dim927KuoInit = { 1, 3, 7, 15, 31, 15, 3, 107, 225, 207, 429, 959, 2627, 0 }; + static ulong[] dim928KuoInit = { 1, 3, 3, 11, 29, 25, 109, 41, 261, 585, 1049, 3013, 4361, 0 }; + static ulong[] dim929KuoInit = { 1, 1, 7, 11, 29, 63, 117, 147, 149, 427, 1371, 2171, 7797, 0 }; + static ulong[] dim930KuoInit = { 1, 3, 5, 3, 13, 33, 103, 33, 227, 785, 1277, 27, 6713, 0 }; + static ulong[] dim931KuoInit = { 1, 3, 1, 3, 19, 3, 121, 123, 313, 283, 1231, 3331, 7271, 0 }; + static ulong[] dim932KuoInit = { 1, 1, 7, 3, 21, 57, 53, 9, 275, 661, 1665, 1557, 3813, 0 }; + static ulong[] dim933KuoInit = { 1, 3, 5, 1, 19, 63, 69, 149, 373, 667, 975, 3483, 7605, 0 }; + static ulong[] dim934KuoInit = { 1, 3, 5, 3, 3, 53, 37, 247, 293, 491, 657, 3123, 1165, 0 }; + static ulong[] dim935KuoInit = { 1, 1, 1, 13, 27, 41, 23, 185, 405, 215, 455, 433, 7775, 0 }; + static ulong[] dim936KuoInit = { 1, 1, 3, 13, 23, 61, 63, 61, 195, 83, 33, 1903, 269, 0 }; + static ulong[] dim937KuoInit = { 1, 1, 3, 7, 5, 7, 1, 161, 295, 539, 1371, 3911, 4095, 0 }; + static ulong[] dim938KuoInit = { 1, 1, 7, 9, 7, 7, 63, 115, 323, 95, 1965, 137, 7147, 0 }; + static ulong[] dim939KuoInit = { 1, 3, 7, 11, 19, 55, 107, 71, 169, 937, 939, 113, 6187, 0 }; + static ulong[] dim940KuoInit = { 1, 1, 3, 7, 13, 17, 55, 5, 167, 337, 2043, 1485, 5069, 0 }; + static ulong[] dim941KuoInit = { 1, 1, 7, 9, 21, 3, 107, 125, 253, 363, 49, 469, 2873, 0 }; + static ulong[] dim942KuoInit = { 1, 1, 7, 9, 9, 31, 91, 65, 315, 973, 653, 1023, 6479, 0 }; + static ulong[] dim943KuoInit = { 1, 3, 5, 11, 1, 5, 19, 109, 143, 335, 1035, 3893, 4573, 0 }; + static ulong[] dim944KuoInit = { 1, 3, 3, 13, 27, 53, 37, 177, 407, 315, 1943, 3111, 1385, 0 }; + static ulong[] dim945KuoInit = { 1, 3, 5, 15, 27, 47, 57, 105, 131, 31, 551, 3733, 5157, 0 }; + static ulong[] dim946KuoInit = { 1, 3, 5, 9, 15, 31, 41, 11, 93, 895, 587, 421, 885, 0 }; + static ulong[] dim947KuoInit = { 1, 3, 7, 1, 5, 35, 107, 189, 287, 457, 645, 519, 7459, 0 }; + static ulong[] dim948KuoInit = { 1, 1, 7, 5, 23, 7, 79, 45, 73, 711, 575, 3571, 1453, 0 }; + static ulong[] dim949KuoInit = { 1, 1, 3, 9, 9, 7, 89, 197, 215, 111, 1099, 3915, 3709, 0 }; + static ulong[] dim950KuoInit = { 1, 3, 1, 7, 25, 1, 83, 55, 449, 227, 1563, 1103, 4129, 0 }; + static ulong[] dim951KuoInit = { 1, 1, 1, 9, 23, 25, 103, 183, 379, 541, 673, 2711, 7409, 0 }; + static ulong[] dim952KuoInit = { 1, 3, 1, 11, 27, 21, 83, 61, 65, 867, 1755, 3815, 7235, 0 }; + static ulong[] dim953KuoInit = { 1, 1, 3, 15, 15, 55, 13, 185, 145, 955, 785, 189, 6653, 0 }; + static ulong[] dim954KuoInit = { 1, 3, 5, 15, 5, 19, 83, 157, 429, 57, 1293, 1551, 581, 0 }; + static ulong[] dim955KuoInit = { 1, 3, 3, 11, 25, 19, 117, 73, 503, 1015, 203, 2689, 6697, 0 }; + static ulong[] dim956KuoInit = { 1, 1, 7, 1, 27, 31, 111, 193, 403, 267, 233, 3031, 5451, 0 }; + static ulong[] dim957KuoInit = { 1, 3, 7, 5, 9, 7, 73, 221, 27, 483, 185, 1805, 1813, 0 }; + static ulong[] dim958KuoInit = { 1, 3, 3, 5, 19, 27, 103, 197, 245, 191, 301, 531, 3677, 0 }; + static ulong[] dim959KuoInit = { 1, 1, 5, 1, 9, 49, 5, 55, 81, 907, 313, 3379, 2573, 0 }; + static ulong[] dim960KuoInit = { 1, 3, 5, 3, 13, 11, 75, 145, 143, 991, 201, 3769, 5041, 0 }; + static ulong[] dim961KuoInit = { 1, 3, 1, 5, 15, 45, 89, 17, 209, 91, 1635, 3025, 3885, 0 }; + static ulong[] dim962KuoInit = { 1, 3, 3, 5, 15, 37, 79, 163, 455, 477, 69, 3617, 1263, 0 }; + static ulong[] dim963KuoInit = { 1, 1, 3, 11, 15, 47, 77, 73, 199, 493, 207, 2109, 4991, 0 }; + static ulong[] dim964KuoInit = { 1, 1, 5, 15, 29, 23, 35, 177, 483, 151, 1497, 631, 1647, 0 }; + static ulong[] dim965KuoInit = { 1, 3, 7, 5, 29, 45, 127, 199, 491, 965, 371, 3549, 2757, 0 }; + static ulong[] dim966KuoInit = { 1, 1, 7, 5, 21, 11, 27, 217, 407, 493, 1979, 359, 6187, 0 }; + static ulong[] dim967KuoInit = { 1, 3, 5, 7, 31, 61, 113, 197, 109, 781, 1859, 991, 3617, 0 }; + static ulong[] dim968KuoInit = { 1, 3, 1, 5, 17, 43, 75, 169, 413, 257, 1751, 4047, 1951, 0 }; + static ulong[] dim969KuoInit = { 1, 3, 1, 13, 17, 49, 95, 223, 439, 587, 427, 89, 7723, 0 }; + static ulong[] dim970KuoInit = { 1, 3, 5, 1, 7, 53, 1, 79, 111, 721, 169, 4087, 5255, 0 }; + static ulong[] dim971KuoInit = { 1, 1, 7, 15, 31, 7, 111, 163, 491, 559, 259, 3057, 5669, 0 }; + static ulong[] dim972KuoInit = { 1, 3, 3, 9, 25, 41, 45, 101, 145, 769, 1313, 3101, 405, 0 }; + static ulong[] dim973KuoInit = { 1, 3, 3, 11, 3, 39, 67, 201, 171, 79, 1727, 2331, 8161, 0 }; + static ulong[] dim974KuoInit = { 1, 3, 5, 5, 31, 29, 13, 111, 449, 579, 1133, 1321, 2447, 0 }; + static ulong[] dim975KuoInit = { 1, 3, 3, 15, 21, 39, 57, 203, 39, 733, 1773, 2867, 6751, 0 }; + static ulong[] dim976KuoInit = { 1, 3, 5, 3, 19, 33, 73, 219, 159, 901, 919, 1445, 1387, 0 }; + static ulong[] dim977KuoInit = { 1, 3, 1, 7, 9, 33, 113, 221, 315, 503, 1795, 577, 1605, 0 }; + static ulong[] dim978KuoInit = { 1, 1, 7, 11, 31, 47, 51, 53, 159, 731, 1101, 1895, 2061, 0 }; + static ulong[] dim979KuoInit = { 1, 3, 5, 7, 29, 11, 107, 39, 89, 357, 13, 805, 5527, 0 }; + static ulong[] dim980KuoInit = { 1, 3, 1, 9, 13, 15, 59, 95, 467, 875, 217, 3345, 1579, 0 }; + static ulong[] dim981KuoInit = { 1, 3, 1, 15, 29, 33, 11, 121, 243, 429, 1017, 1511, 6289, 0 }; + static ulong[] dim982KuoInit = { 1, 3, 7, 1, 27, 41, 125, 121, 265, 695, 155, 3933, 661, 0 }; + static ulong[] dim983KuoInit = { 1, 1, 3, 7, 5, 3, 95, 213, 385, 183, 1693, 2685, 5647, 0 }; + static ulong[] dim984KuoInit = { 1, 1, 5, 5, 23, 29, 21, 193, 327, 965, 49, 2157, 1539, 0 }; + static ulong[] dim985KuoInit = { 1, 3, 1, 7, 15, 15, 103, 191, 249, 347, 283, 2459, 5957, 0 }; + static ulong[] dim986KuoInit = { 1, 1, 7, 5, 21, 43, 29, 205, 125, 63, 1645, 3357, 3333, 0 }; + static ulong[] dim987KuoInit = { 1, 3, 1, 5, 11, 21, 109, 213, 123, 587, 2047, 343, 6669, 0 }; + static ulong[] dim988KuoInit = { 1, 1, 5, 5, 25, 63, 75, 237, 421, 883, 801, 2403, 4723, 0 }; + static ulong[] dim989KuoInit = { 1, 3, 5, 11, 13, 63, 87, 107, 411, 3, 139, 3097, 6109, 0 }; + static ulong[] dim990KuoInit = { 1, 3, 7, 9, 19, 31, 33, 23, 499, 105, 471, 2311, 439, 0 }; + static ulong[] dim991KuoInit = { 1, 3, 3, 13, 13, 39, 19, 253, 53, 315, 1381, 3875, 5741, 0 }; + static ulong[] dim992KuoInit = { 1, 1, 1, 7, 19, 9, 47, 169, 265, 1005, 159, 2957, 2987, 0 }; + static ulong[] dim993KuoInit = { 1, 3, 3, 3, 1, 35, 107, 77, 47, 89, 1901, 1719, 2873, 0 }; + static ulong[] dim994KuoInit = { 1, 1, 5, 7, 7, 51, 87, 91, 45, 991, 1369, 3759, 3511, 0 }; + static ulong[] dim995KuoInit = { 1, 3, 7, 15, 17, 51, 93, 43, 71, 213, 1637, 2617, 1767, 0 }; + static ulong[] dim996KuoInit = { 1, 1, 5, 15, 29, 63, 81, 15, 409, 779, 1419, 497, 463, 0 }; + static ulong[] dim997KuoInit = { 1, 1, 7, 1, 1, 31, 21, 167, 445, 893, 1687, 603, 3211, 0 }; + static ulong[] dim998KuoInit = { 1, 3, 7, 15, 19, 3, 41, 53, 175, 971, 1873, 43, 4795, 0 }; + static ulong[] dim999KuoInit = { 1, 3, 5, 15, 21, 59, 77, 67, 495, 547, 411, 2373, 5187, 0 }; + static ulong[] dim1000KuoInit = { 1, 1, 5, 1, 27, 45, 119, 201, 237, 499, 261, 3331, 3973, 0 }; + static ulong[] dim1001KuoInit = { 1, 3, 5, 9, 17, 31, 33, 15, 237, 135, 1751, 297, 6331, 0 }; + static ulong[] dim1002KuoInit = { 1, 3, 7, 9, 15, 1, 11, 135, 355, 617, 805, 1201, 457, 0 }; + static ulong[] dim1003KuoInit = { 1, 1, 7, 5, 19, 55, 21, 121, 205, 999, 1719, 2815, 6753, 0 }; + static ulong[] dim1004KuoInit = { 1, 1, 5, 3, 9, 5, 7, 231, 323, 953, 1811, 2847, 2059, 0 }; + static ulong[] dim1005KuoInit = { 1, 3, 3, 9, 17, 15, 85, 3, 259, 989, 287, 3995, 2677, 0 }; + static ulong[] dim1006KuoInit = { 1, 1, 3, 11, 13, 61, 69, 143, 167, 187, 481, 2359, 1913, 0 }; + static ulong[] dim1007KuoInit = { 1, 1, 5, 13, 29, 3, 29, 247, 407, 733, 677, 99, 1625, 0 }; + static ulong[] dim1008KuoInit = { 1, 1, 7, 13, 7, 17, 67, 115, 299, 765, 1885, 2769, 1619, 0 }; + static ulong[] dim1009KuoInit = { 1, 1, 3, 3, 17, 7, 27, 61, 433, 323, 1091, 1309, 7239, 0 }; + static ulong[] dim1010KuoInit = { 1, 1, 7, 3, 19, 63, 41, 157, 43, 743, 675, 2149, 6729, 0 }; + static ulong[] dim1011KuoInit = { 1, 1, 5, 1, 21, 35, 45, 145, 235, 185, 1563, 1117, 3669, 0 }; + static ulong[] dim1012KuoInit = { 1, 3, 1, 9, 9, 37, 105, 61, 259, 935, 793, 823, 1765, 0 }; + static ulong[] dim1013KuoInit = { 1, 3, 3, 11, 25, 41, 35, 11, 389, 399, 339, 859, 4299, 0 }; + static ulong[] dim1014KuoInit = { 1, 3, 5, 13, 7, 29, 53, 91, 185, 163, 1689, 983, 4545, 0 }; + static ulong[] dim1015KuoInit = { 1, 3, 7, 11, 19, 35, 45, 141, 445, 469, 1827, 3523, 377, 0 }; + static ulong[] dim1016KuoInit = { 1, 3, 5, 13, 27, 29, 35, 199, 73, 163, 1591, 1021, 2867, 0 }; + static ulong[] dim1017KuoInit = { 1, 1, 1, 15, 7, 61, 95, 95, 147, 959, 971, 649, 5047, 0 }; + static ulong[] dim1018KuoInit = { 1, 1, 1, 15, 11, 23, 49, 231, 359, 677, 1401, 2889, 3799, 0 }; + static ulong[] dim1019KuoInit = { 1, 3, 7, 11, 11, 15, 119, 103, 403, 983, 399, 321, 437, 0 }; + static ulong[] dim1020KuoInit = { 1, 3, 7, 1, 29, 13, 83, 55, 175, 835, 1637, 209, 1923, 0 }; + static ulong[] dim1021KuoInit = { 1, 1, 5, 13, 25, 37, 5, 239, 227, 229, 243, 1837, 4821, 0 }; + static ulong[] dim1022KuoInit = { 1, 1, 7, 9, 9, 59, 29, 135, 227, 473, 1759, 3711, 4113, 0 }; + static ulong[] dim1023KuoInit = { 1, 3, 3, 3, 15, 3, 53, 225, 165, 375, 537, 331, 5085, 0 }; + static ulong[] dim1024KuoInit = { 1, 1, 1, 5, 15, 41, 57, 165, 45, 137, 931, 1015, 6451, 0 }; + static ulong[] dim1025KuoInit = { 1, 3, 5, 7, 5, 47, 35, 249, 89, 111, 1275, 529, 3297, 0 }; + static ulong[] dim1026KuoInit = { 1, 3, 1, 1, 27, 21, 65, 193, 381, 861, 59, 1457, 2447, 0 }; + static ulong[] dim1027KuoInit = { 1, 1, 7, 15, 17, 25, 75, 171, 263, 401, 1369, 2609, 6265, 0 }; + static ulong[] dim1028KuoInit = { 1, 1, 3, 7, 17, 61, 75, 77, 487, 7, 1565, 527, 7213, 0 }; + static ulong[] dim1029KuoInit = { 1, 3, 5, 9, 5, 45, 47, 27, 163, 43, 219, 2119, 1793, 0 }; + static ulong[] dim1030KuoInit = { 1, 1, 3, 3, 27, 9, 89, 151, 487, 925, 1257, 1065, 3413, 0 }; + static ulong[] dim1031KuoInit = { 1, 1, 5, 3, 11, 27, 9, 161, 303, 457, 1367, 2319, 6145, 0 }; + static ulong[] dim1032KuoInit = { 1, 3, 1, 13, 23, 43, 115, 227, 319, 469, 1651, 1693, 2095, 0 }; + static ulong[] dim1033KuoInit = { 1, 1, 1, 11, 23, 5, 91, 103, 393, 787, 1557, 925, 7189, 0 }; + static ulong[] dim1034KuoInit = { 1, 3, 5, 7, 31, 5, 51, 171, 375, 309, 199, 1833, 2741, 0 }; + static ulong[] dim1035KuoInit = { 1, 1, 5, 13, 27, 59, 15, 255, 205, 807, 1407, 161, 6955, 0 }; + static ulong[] dim1036KuoInit = { 1, 3, 5, 5, 5, 35, 7, 167, 265, 67, 1133, 699, 6225, 0 }; + static ulong[] dim1037KuoInit = { 1, 1, 1, 7, 19, 31, 5, 243, 279, 505, 303, 2303, 5367, 0 }; + static ulong[] dim1038KuoInit = { 1, 3, 1, 3, 19, 47, 105, 159, 309, 783, 1845, 2603, 4663, 0 }; + static ulong[] dim1039KuoInit = { 1, 1, 7, 13, 13, 35, 101, 123, 99, 559, 1681, 2751, 1965, 0 }; + static ulong[] dim1040KuoInit = { 1, 3, 7, 5, 1, 63, 29, 245, 105, 469, 939, 721, 6213, 0 }; + static ulong[] dim1041KuoInit = { 1, 3, 7, 15, 11, 45, 13, 121, 81, 15, 1503, 2203, 7467, 0 }; + static ulong[] dim1042KuoInit = { 1, 1, 7, 11, 29, 25, 59, 93, 5, 551, 1799, 2251, 115, 0 }; + static ulong[] dim1043KuoInit = { 1, 1, 1, 7, 17, 37, 81, 117, 183, 301, 1085, 3925, 697, 0 }; + static ulong[] dim1044KuoInit = { 1, 3, 7, 7, 13, 13, 5, 207, 443, 723, 897, 3481, 3377, 0 }; + static ulong[] dim1045KuoInit = { 1, 3, 7, 13, 9, 41, 25, 161, 283, 3, 1515, 2445, 2179, 0 }; + static ulong[] dim1046KuoInit = { 1, 1, 1, 1, 29, 17, 73, 129, 499, 457, 103, 2287, 525, 0 }; + static ulong[] dim1047KuoInit = { 1, 3, 7, 11, 9, 13, 95, 31, 411, 185, 931, 119, 711, 0 }; + static ulong[] dim1048KuoInit = { 1, 1, 3, 13, 19, 53, 49, 209, 217, 593, 733, 4057, 2853, 0 }; + static ulong[] dim1049KuoInit = { 1, 3, 5, 1, 7, 63, 95, 45, 209, 641, 1767, 3001, 4089, 0 }; + static ulong[] dim1050KuoInit = { 1, 1, 5, 9, 9, 25, 69, 85, 345, 475, 613, 3975, 2179, 0 }; + static ulong[] dim1051KuoInit = { 1, 1, 1, 9, 19, 9, 47, 51, 111, 7, 627, 1635, 3857, 0 }; + static ulong[] dim1052KuoInit = { 1, 3, 7, 1, 25, 37, 27, 253, 111, 369, 235, 2887, 5649, 0 }; + static ulong[] dim1053KuoInit = { 1, 1, 7, 3, 15, 5, 13, 181, 471, 825, 121, 3007, 777, 0 }; + static ulong[] dim1054KuoInit = { 1, 1, 1, 9, 27, 41, 59, 9, 391, 779, 915, 3965, 4431, 0 }; + static ulong[] dim1055KuoInit = { 1, 3, 1, 1, 25, 27, 75, 123, 385, 923, 141, 3771, 2227, 0 }; + static ulong[] dim1056KuoInit = { 1, 3, 3, 15, 17, 29, 85, 253, 261, 517, 87, 621, 7947, 0 }; + static ulong[] dim1057KuoInit = { 1, 3, 7, 5, 13, 15, 83, 49, 399, 875, 845, 1731, 7071, 0 }; + static ulong[] dim1058KuoInit = { 1, 1, 3, 5, 21, 49, 93, 121, 271, 921, 183, 1533, 1609, 0 }; + static ulong[] dim1059KuoInit = { 1, 3, 7, 7, 9, 51, 89, 135, 389, 151, 1813, 3673, 2099, 0 }; + static ulong[] dim1060KuoInit = { 1, 1, 1, 11, 25, 63, 127, 239, 329, 455, 403, 363, 2689, 0 }; + static ulong[] dim1061KuoInit = { 1, 3, 5, 13, 1, 45, 65, 93, 371, 577, 669, 2433, 3507, 0 }; + static ulong[] dim1062KuoInit = { 1, 3, 5, 9, 9, 15, 13, 85, 67, 809, 1133, 129, 3869, 0 }; + static ulong[] dim1063KuoInit = { 1, 3, 7, 15, 3, 47, 31, 79, 395, 227, 677, 3399, 8173, 0 }; + static ulong[] dim1064KuoInit = { 1, 3, 1, 11, 7, 19, 81, 27, 393, 49, 299, 879, 5401, 0 }; + static ulong[] dim1065KuoInit = { 1, 1, 1, 1, 3, 25, 105, 67, 147, 23, 749, 2677, 2799, 0 }; + static ulong[] dim1066KuoInit = { 1, 1, 3, 15, 3, 49, 55, 131, 249, 183, 399, 4065, 4575, 0 }; + static ulong[] dim1067KuoInit = { 1, 3, 7, 13, 21, 1, 105, 167, 379, 567, 1843, 3019, 7479, 0 }; + static ulong[] dim1068KuoInit = { 1, 1, 7, 3, 7, 15, 65, 213, 191, 735, 1087, 1223, 7827, 0 }; + static ulong[] dim1069KuoInit = { 1, 1, 3, 3, 13, 35, 79, 55, 169, 513, 639, 1153, 1129, 0 }; + static ulong[] dim1070KuoInit = { 1, 3, 5, 15, 1, 37, 49, 209, 355, 533, 1073, 3249, 4309, 0 }; + static ulong[] dim1071KuoInit = { 1, 1, 3, 15, 23, 45, 69, 195, 155, 267, 291, 1773, 3575, 0 }; + static ulong[] dim1072KuoInit = { 1, 3, 1, 13, 25, 3, 51, 175, 505, 467, 1909, 1929, 4909, 0 }; + static ulong[] dim1073KuoInit = { 1, 3, 3, 1, 31, 51, 99, 119, 505, 57, 1987, 1303, 4273, 0 }; + static ulong[] dim1074KuoInit = { 1, 3, 7, 9, 19, 49, 61, 147, 29, 1001, 633, 963, 5601, 0 }; + static ulong[] dim1075KuoInit = { 1, 3, 5, 7, 1, 13, 101, 133, 31, 263, 2033, 575, 983, 0 }; + static ulong[] dim1076KuoInit = { 1, 1, 1, 15, 21, 29, 101, 143, 263, 601, 1239, 1187, 3045, 0 }; + static ulong[] dim1077KuoInit = { 1, 3, 3, 15, 5, 49, 7, 165, 411, 517, 619, 1517, 1839, 0 }; + static ulong[] dim1078KuoInit = { 1, 3, 5, 15, 29, 45, 71, 245, 67, 469, 1793, 3353, 7799, 0 }; + static ulong[] dim1079KuoInit = { 1, 1, 5, 7, 15, 49, 5, 183, 345, 585, 1877, 2205, 7963, 0 }; + static ulong[] dim1080KuoInit = { 1, 3, 1, 1, 7, 39, 85, 183, 131, 527, 1731, 1899, 3813, 0 }; + static ulong[] dim1081KuoInit = { 1, 1, 7, 9, 29, 23, 77, 233, 77, 699, 1963, 171, 6557, 0 }; + static ulong[] dim1082KuoInit = { 1, 3, 5, 15, 5, 3, 79, 199, 279, 279, 399, 769, 1661, 0 }; + static ulong[] dim1083KuoInit = { 1, 3, 7, 1, 17, 61, 61, 227, 289, 541, 379, 3155, 5791, 0 }; + static ulong[] dim1084KuoInit = { 1, 3, 3, 7, 31, 37, 73, 215, 47, 895, 1511, 305, 5247, 0 }; + static ulong[] dim1085KuoInit = { 1, 1, 7, 5, 31, 47, 123, 191, 175, 875, 501, 2203, 1781, 0 }; + static ulong[] dim1086KuoInit = { 1, 3, 3, 3, 13, 5, 43, 145, 183, 705, 1143, 3113, 1959, 0 }; + static ulong[] dim1087KuoInit = { 1, 3, 7, 1, 23, 53, 93, 133, 13, 987, 1711, 2241, 7721, 0 }; + static ulong[] dim1088KuoInit = { 1, 3, 1, 7, 3, 19, 123, 65, 421, 891, 159, 1633, 733, 0 }; + static ulong[] dim1089KuoInit = { 1, 3, 3, 3, 23, 59, 127, 109, 315, 939, 1177, 1237, 1805, 0 }; + static ulong[] dim1090KuoInit = { 1, 3, 5, 15, 13, 19, 39, 97, 437, 949, 539, 1171, 151, 0 }; + static ulong[] dim1091KuoInit = { 1, 3, 5, 9, 13, 45, 107, 159, 363, 727, 509, 3051, 4071, 0 }; + static ulong[] dim1092KuoInit = { 1, 3, 3, 1, 15, 11, 93, 199, 137, 947, 479, 2127, 1377, 0 }; + static ulong[] dim1093KuoInit = { 1, 3, 7, 15, 13, 5, 67, 227, 69, 795, 299, 1845, 4765, 0 }; + static ulong[] dim1094KuoInit = { 1, 1, 5, 7, 31, 15, 11, 255, 361, 599, 1235, 1785, 1611, 0 }; + static ulong[] dim1095KuoInit = { 1, 3, 5, 15, 29, 21, 85, 49, 101, 785, 1071, 1333, 1691, 0 }; + static ulong[] dim1096KuoInit = { 1, 3, 1, 1, 19, 11, 23, 157, 201, 67, 789, 999, 4281, 0 }; + static ulong[] dim1097KuoInit = { 1, 1, 7, 3, 7, 61, 109, 253, 455, 863, 81, 3185, 7105, 0 }; + static ulong[] dim1098KuoInit = { 1, 1, 1, 1, 11, 29, 51, 43, 211, 103, 1333, 3425, 6669, 0 }; + static ulong[] dim1099KuoInit = { 1, 3, 3, 3, 19, 15, 25, 21, 9, 563, 1737, 159, 1827, 0 }; + static ulong[] dim1100KuoInit = { 1, 3, 5, 11, 9, 35, 19, 145, 159, 345, 475, 1453, 7807, 0 }; + static ulong[] dim1101KuoInit = { 1, 3, 7, 9, 19, 41, 61, 63, 77, 3, 997, 223, 5493, 0 }; + static ulong[] dim1102KuoInit = { 1, 3, 7, 15, 25, 17, 87, 99, 441, 973, 713, 631, 4039, 0 }; + static ulong[] dim1103KuoInit = { 1, 3, 5, 15, 17, 19, 89, 11, 321, 143, 11, 915, 3359, 0 }; + static ulong[] dim1104KuoInit = { 1, 3, 7, 1, 11, 55, 43, 3, 1, 893, 1845, 1237, 693, 0 }; + static ulong[] dim1105KuoInit = { 1, 3, 7, 13, 25, 21, 93, 43, 127, 197, 1349, 1727, 1133, 0 }; + static ulong[] dim1106KuoInit = { 1, 3, 7, 15, 29, 57, 19, 35, 37, 81, 1599, 3469, 4327, 0 }; + static ulong[] dim1107KuoInit = { 1, 1, 7, 9, 15, 47, 119, 203, 301, 835, 1221, 2771, 2023, 0 }; + static ulong[] dim1108KuoInit = { 1, 3, 5, 9, 25, 43, 109, 51, 431, 189, 255, 2595, 2447, 0 }; + static ulong[] dim1109KuoInit = { 1, 1, 5, 5, 13, 3, 113, 109, 321, 837, 159, 2617, 2277, 0 }; + static ulong[] dim1110KuoInit = { 1, 1, 1, 11, 29, 43, 33, 173, 47, 395, 1113, 1711, 7909, 0 }; + static ulong[] dim1111KuoInit = { 1, 1, 3, 15, 31, 45, 37, 95, 13, 449, 1377, 2117, 6607, 11053, 0 }; + static ulong[] dim1112KuoInit = { 1, 1, 1, 9, 21, 7, 127, 71, 11, 271, 65, 3681, 4209, 3183, 0 }; + static ulong[] dim1113KuoInit = { 1, 3, 3, 15, 19, 27, 99, 243, 371, 77, 629, 3989, 3105, 6287, 0 }; + static ulong[] dim1114KuoInit = { 1, 3, 1, 15, 7, 35, 115, 237, 403, 273, 697, 117, 6887, 3243, 0 }; + static ulong[] dim1115KuoInit = { 1, 1, 5, 9, 29, 1, 117, 101, 483, 909, 867, 2051, 7081, 14905, 0 }; + static ulong[] dim1116KuoInit = { 1, 1, 7, 13, 21, 49, 107, 101, 121, 979, 309, 1871, 7339, 4213, 0 }; + static ulong[] dim1117KuoInit = { 1, 1, 7, 13, 9, 25, 13, 61, 409, 469, 411, 2041, 7685, 15501, 0 }; + static ulong[] dim1118KuoInit = { 1, 1, 7, 5, 1, 29, 109, 125, 63, 829, 175, 957, 4781, 12473, 0 }; + static ulong[] dim1119KuoInit = { 1, 3, 3, 1, 11, 53, 17, 171, 393, 165, 51, 737, 1697, 4137, 0 }; + static ulong[] dim1120KuoInit = { 1, 3, 7, 9, 15, 45, 49, 219, 105, 121, 549, 991, 1337, 11311, 0 }; + static ulong[] dim1121KuoInit = { 1, 3, 3, 5, 27, 9, 39, 207, 85, 185, 901, 3077, 5295, 3933, 0 }; + static ulong[] dim1122KuoInit = { 1, 1, 5, 7, 23, 29, 95, 63, 125, 447, 573, 2053, 4621, 10135, 0 }; + static ulong[] dim1123KuoInit = { 1, 1, 1, 7, 23, 45, 3, 109, 335, 339, 1453, 3121, 37, 9155, 0 }; + static ulong[] dim1124KuoInit = { 1, 3, 1, 13, 9, 25, 27, 67, 35, 573, 215, 1969, 7083, 15729, 0 }; + static ulong[] dim1125KuoInit = { 1, 3, 1, 9, 21, 3, 21, 143, 131, 613, 299, 1127, 5647, 15007, 0 }; + static ulong[] dim1126KuoInit = { 1, 3, 7, 9, 29, 47, 53, 223, 409, 633, 535, 2423, 5763, 11633, 0 }; + static ulong[] dim1127KuoInit = { 1, 3, 1, 9, 1, 21, 5, 1, 359, 547, 285, 779, 2091, 11785, 0 }; + static ulong[] dim1128KuoInit = { 1, 3, 7, 7, 1, 31, 61, 245, 331, 45, 1559, 3223, 7577, 2157, 0 }; + static ulong[] dim1129KuoInit = { 1, 1, 1, 7, 3, 27, 37, 191, 229, 205, 1535, 887, 701, 10867, 0 }; + static ulong[] dim1130KuoInit = { 1, 3, 3, 15, 21, 53, 61, 177, 485, 575, 681, 1447, 1427, 11279, 0 }; + static ulong[] dim1131KuoInit = { 1, 1, 1, 3, 17, 3, 5, 49, 311, 507, 995, 3971, 471, 3045, 0 }; + static ulong[] dim1132KuoInit = { 1, 1, 3, 9, 7, 45, 73, 183, 419, 635, 523, 1793, 7549, 9727, 0 }; + static ulong[] dim1133KuoInit = { 1, 1, 7, 3, 19, 33, 109, 91, 19, 825, 1629, 2111, 2673, 6677, 0 }; + static ulong[] dim1134KuoInit = { 1, 1, 3, 9, 31, 13, 71, 199, 113, 77, 371, 3117, 7799, 15919, 0 }; + static ulong[] dim1135KuoInit = { 1, 1, 7, 5, 27, 41, 91, 183, 75, 159, 911, 2081, 7065, 16313, 0 }; + static ulong[] dim1136KuoInit = { 1, 3, 1, 15, 17, 29, 65, 9, 399, 259, 671, 525, 1393, 13367, 0 }; + static ulong[] dim1137KuoInit = { 1, 3, 3, 13, 1, 29, 101, 187, 231, 413, 1245, 269, 201, 1673, 0 }; + static ulong[] dim1138KuoInit = { 1, 1, 7, 3, 27, 47, 11, 149, 49, 309, 1923, 1187, 3165, 7927, 0 }; + static ulong[] dim1139KuoInit = { 1, 1, 1, 5, 31, 57, 29, 203, 11, 305, 1771, 2997, 377, 5777, 0 }; + static ulong[] dim1140KuoInit = { 1, 1, 7, 5, 1, 29, 29, 205, 93, 821, 1583, 2991, 4137, 14967, 0 }; + static ulong[] dim1141KuoInit = { 1, 1, 3, 3, 7, 57, 13, 179, 261, 547, 219, 1979, 4951, 2529, 0 }; + static ulong[] dim1142KuoInit = { 1, 3, 1, 5, 3, 51, 89, 7, 121, 611, 1655, 3639, 1991, 9911, 0 }; + static ulong[] dim1143KuoInit = { 1, 3, 3, 15, 1, 21, 9, 173, 93, 579, 1685, 767, 5183, 3965, 0 }; + static ulong[] dim1144KuoInit = { 1, 1, 3, 7, 15, 47, 55, 113, 27, 941, 1633, 3791, 1705, 16293, 0 }; + static ulong[] dim1145KuoInit = { 1, 3, 3, 1, 7, 41, 11, 229, 367, 997, 543, 933, 4249, 7049, 0 }; + static ulong[] dim1146KuoInit = { 1, 1, 1, 13, 7, 7, 25, 87, 213, 277, 627, 721, 6161, 14877, 0 }; + static ulong[] dim1147KuoInit = { 1, 3, 5, 7, 25, 61, 47, 103, 199, 983, 543, 1935, 4663, 3597, 0 }; + static ulong[] dim1148KuoInit = { 1, 3, 1, 15, 15, 49, 125, 27, 153, 521, 351, 1129, 5897, 11325, 0 }; + static ulong[] dim1149KuoInit = { 1, 3, 1, 13, 13, 35, 81, 53, 217, 739, 963, 3441, 6843, 3505, 0 }; + static ulong[] dim1150KuoInit = { 1, 3, 7, 1, 17, 35, 119, 187, 475, 919, 1325, 3269, 677, 617, 0 }; + static ulong[] dim1151KuoInit = { 1, 1, 7, 15, 7, 15, 91, 99, 259, 37, 1461, 1145, 6973, 15643, 0 }; + static ulong[] dim1152KuoInit = { 1, 1, 5, 15, 13, 11, 27, 75, 9, 611, 1331, 2057, 863, 6245, 0 }; + static ulong[] dim1153KuoInit = { 1, 1, 1, 15, 3, 25, 117, 45, 141, 839, 1201, 629, 6289, 12231, 0 }; + static ulong[] dim1154KuoInit = { 1, 1, 3, 13, 17, 61, 23, 243, 349, 153, 1747, 3107, 7763, 10067, 0 }; + static ulong[] dim1155KuoInit = { 1, 1, 1, 1, 21, 25, 53, 67, 97, 851, 1921, 2247, 5769, 5779, 0 }; + static ulong[] dim1156KuoInit = { 1, 3, 3, 3, 9, 37, 93, 247, 287, 609, 1643, 427, 4269, 15923, 0 }; + static ulong[] dim1157KuoInit = { 1, 3, 3, 15, 7, 35, 111, 105, 357, 539, 319, 993, 6155, 6587, 0 }; + static ulong[] dim1158KuoInit = { 1, 1, 3, 1, 13, 33, 99, 73, 89, 231, 1537, 309, 3837, 6669, 0 }; + static ulong[] dim1159KuoInit = { 1, 3, 1, 1, 9, 25, 105, 197, 399, 259, 1381, 1631, 3551, 4593, 0 }; + static ulong[] dim1160KuoInit = { 1, 3, 1, 3, 7, 63, 113, 65, 109, 529, 1451, 1169, 3321, 6811, 0 }; + static ulong[] dim1161KuoInit = { 1, 1, 1, 5, 11, 55, 109, 27, 65, 199, 199, 2745, 2009, 14853, 0 }; + static ulong[] dim1162KuoInit = { 1, 3, 1, 9, 13, 31, 109, 119, 431, 363, 1191, 703, 2617, 6817, 0 }; + static ulong[] dim1163KuoInit = { 1, 1, 3, 11, 27, 1, 107, 11, 457, 495, 215, 1459, 4137, 13007, 0 }; + static ulong[] dim1164KuoInit = { 1, 1, 7, 3, 7, 29, 11, 19, 159, 821, 1881, 3277, 1303, 7145, 0 }; + static ulong[] dim1165KuoInit = { 1, 3, 3, 11, 25, 11, 125, 241, 197, 863, 423, 2107, 5885, 14279, 0 }; + static ulong[] dim1166KuoInit = { 1, 3, 3, 1, 7, 29, 97, 249, 333, 945, 1081, 2405, 109, 2869, 0 }; + static ulong[] dim1167KuoInit = { 1, 3, 3, 3, 27, 57, 89, 243, 481, 431, 269, 3371, 3667, 13293, 0 }; + static ulong[] dim1168KuoInit = { 1, 3, 7, 7, 23, 3, 91, 57, 79, 165, 629, 2771, 7927, 2689, 0 }; + static ulong[] dim1169KuoInit = { 1, 1, 1, 11, 17, 51, 81, 147, 19, 501, 861, 159, 2117, 6777, 0 }; + static ulong[] dim1170KuoInit = { 1, 3, 3, 15, 7, 9, 51, 197, 97, 983, 133, 1819, 4449, 7821, 0 }; + static ulong[] dim1171KuoInit = { 1, 3, 3, 7, 21, 55, 61, 171, 461, 741, 1901, 2195, 5477, 1681, 0 }; + static ulong[] dim1172KuoInit = { 1, 1, 3, 1, 13, 37, 73, 151, 479, 561, 1483, 2679, 295, 7325, 0 }; + static ulong[] dim1173KuoInit = { 1, 3, 3, 9, 11, 17, 127, 115, 371, 979, 1391, 2189, 2805, 7471, 0 }; + static ulong[] dim1174KuoInit = { 1, 1, 3, 13, 31, 25, 65, 249, 91, 649, 1103, 493, 6341, 10313, 0 }; + static ulong[] dim1175KuoInit = { 1, 1, 1, 3, 7, 31, 85, 201, 277, 771, 1007, 69, 3357, 15059, 0 }; + static ulong[] dim1176KuoInit = { 1, 1, 1, 7, 17, 17, 9, 229, 269, 591, 945, 3003, 6723, 16101, 0 }; + static ulong[] dim1177KuoInit = { 1, 1, 3, 5, 1, 29, 119, 181, 269, 269, 1781, 2935, 6265, 13989, 0 }; + static ulong[] dim1178KuoInit = { 1, 3, 1, 11, 13, 51, 117, 141, 467, 521, 449, 797, 3447, 11693, 0 }; + static ulong[] dim1179KuoInit = { 1, 1, 5, 15, 3, 57, 61, 209, 423, 213, 1663, 3735, 5229, 11809, 0 }; + static ulong[] dim1180KuoInit = { 1, 3, 7, 9, 13, 51, 113, 127, 229, 793, 905, 3271, 7501, 10801, 0 }; + static ulong[] dim1181KuoInit = { 1, 3, 7, 7, 5, 19, 43, 87, 9, 981, 221, 3925, 2095, 7185, 0 }; + static ulong[] dim1182KuoInit = { 1, 1, 7, 15, 23, 35, 113, 175, 383, 699, 1617, 3771, 5847, 9097, 0 }; + static ulong[] dim1183KuoInit = { 1, 3, 1, 7, 25, 23, 27, 77, 491, 211, 1785, 199, 4865, 10147, 0 }; + static ulong[] dim1184KuoInit = { 1, 3, 1, 11, 25, 39, 15, 15, 191, 889, 457, 2647, 4555, 4799, 0 }; + static ulong[] dim1185KuoInit = { 1, 1, 7, 5, 15, 1, 117, 169, 245, 917, 1025, 3805, 1455, 3051, 0 }; + static ulong[] dim1186KuoInit = { 1, 3, 7, 5, 7, 15, 43, 13, 359, 685, 75, 271, 555, 3595, 0 }; + static ulong[] dim1187KuoInit = { 1, 3, 7, 5, 19, 9, 29, 15, 139, 13, 753, 205, 677, 5945, 0 }; + static ulong[] dim1188KuoInit = { 1, 3, 1, 9, 5, 21, 99, 77, 287, 663, 589, 229, 5255, 4177, 0 }; + static ulong[] dim1189KuoInit = { 1, 1, 1, 9, 15, 47, 21, 149, 461, 871, 577, 3393, 6879, 6353, 0 }; + static ulong[] dim1190KuoInit = { 1, 3, 3, 3, 21, 33, 29, 25, 195, 1, 1817, 3437, 4265, 16121, 0 }; + static ulong[] dim1191KuoInit = { 1, 3, 1, 7, 27, 31, 93, 141, 471, 735, 1737, 2997, 3529, 12285, 0 }; + static ulong[] dim1192KuoInit = { 1, 1, 3, 15, 15, 49, 105, 157, 165, 593, 651, 3331, 4333, 8607, 0 }; + static ulong[] dim1193KuoInit = { 1, 3, 7, 1, 5, 35, 73, 53, 461, 41, 1407, 357, 3537, 1123, 0 }; + static ulong[] dim1194KuoInit = { 1, 1, 7, 9, 15, 39, 83, 23, 501, 3, 743, 3819, 5491, 15317, 0 }; + static ulong[] dim1195KuoInit = { 1, 1, 7, 15, 31, 29, 125, 173, 465, 347, 1515, 2871, 3861, 9353, 0 }; + static ulong[] dim1196KuoInit = { 1, 1, 7, 5, 9, 31, 121, 221, 491, 579, 313, 3549, 711, 12501, 0 }; + static ulong[] dim1197KuoInit = { 1, 1, 7, 15, 7, 47, 15, 175, 201, 399, 609, 749, 3587, 10091, 0 }; + static ulong[] dim1198KuoInit = { 1, 1, 5, 11, 1, 39, 43, 69, 429, 87, 2017, 1961, 5679, 3179, 0 }; + static ulong[] dim1199KuoInit = { 1, 1, 3, 3, 29, 51, 27, 13, 377, 99, 1291, 247, 2657, 4793, 0 }; + static ulong[] dim1200KuoInit = { 1, 1, 1, 1, 23, 63, 119, 33, 405, 689, 517, 1331, 1047, 403, 0 }; + static ulong[] dim1201KuoInit = { 1, 1, 1, 5, 9, 27, 121, 49, 317, 181, 623, 1789, 5867, 11009, 0 }; + static ulong[] dim1202KuoInit = { 1, 1, 7, 15, 15, 63, 113, 129, 299, 889, 361, 2339, 3893, 3953, 0 }; + static ulong[] dim1203KuoInit = { 1, 1, 1, 15, 9, 51, 73, 77, 511, 745, 639, 1261, 439, 13409, 0 }; + static ulong[] dim1204KuoInit = { 1, 3, 5, 3, 29, 15, 37, 31, 47, 901, 1383, 1979, 7341, 13411, 0 }; + static ulong[] dim1205KuoInit = { 1, 3, 7, 5, 31, 59, 87, 35, 123, 943, 1181, 3877, 4821, 9231, 0 }; + static ulong[] dim1206KuoInit = { 1, 3, 5, 13, 3, 47, 123, 89, 41, 883, 241, 2055, 1723, 6747, 0 }; + static ulong[] dim1207KuoInit = { 1, 1, 7, 5, 21, 29, 89, 101, 423, 279, 29, 2089, 6233, 7343, 0 }; + static ulong[] dim1208KuoInit = { 1, 1, 7, 5, 29, 25, 23, 179, 13, 707, 1603, 585, 4159, 10767, 0 }; + static ulong[] dim1209KuoInit = { 1, 1, 1, 1, 15, 11, 55, 159, 279, 613, 1445, 613, 499, 7095, 0 }; + static ulong[] dim1210KuoInit = { 1, 1, 1, 5, 15, 61, 75, 171, 173, 765, 1763, 2193, 7897, 4559, 0 }; + static ulong[] dim1211KuoInit = { 1, 1, 1, 9, 9, 57, 127, 113, 7, 269, 791, 619, 2923, 6309, 0 }; + static ulong[] dim1212KuoInit = { 1, 1, 3, 13, 21, 9, 99, 1, 263, 69, 1879, 4079, 33, 7313, 0 }; + static ulong[] dim1213KuoInit = { 1, 1, 7, 9, 17, 1, 69, 93, 147, 461, 1777, 3375, 4067, 15307, 0 }; + static ulong[] dim1214KuoInit = { 1, 3, 7, 11, 11, 7, 77, 159, 125, 159, 625, 1339, 2301, 11525, 0 }; + static ulong[] dim1215KuoInit = { 1, 1, 7, 9, 1, 5, 23, 115, 25, 755, 1523, 2767, 7667, 7129, 0 }; + static ulong[] dim1216KuoInit = { 1, 1, 5, 5, 23, 31, 41, 3, 249, 69, 1821, 155, 585, 7905, 0 }; + static ulong[] dim1217KuoInit = { 1, 3, 7, 11, 21, 35, 7, 161, 409, 771, 967, 2429, 1, 5391, 0 }; + static ulong[] dim1218KuoInit = { 1, 1, 1, 9, 9, 3, 13, 125, 87, 115, 1013, 2103, 4769, 7389, 0 }; + static ulong[] dim1219KuoInit = { 1, 3, 3, 7, 27, 25, 85, 119, 115, 775, 189, 3577, 5369, 5213, 0 }; + static ulong[] dim1220KuoInit = { 1, 3, 7, 3, 27, 49, 81, 23, 223, 523, 1939, 431, 6247, 10509, 0 }; + static ulong[] dim1221KuoInit = { 1, 3, 3, 3, 31, 7, 119, 235, 315, 431, 1669, 1223, 5785, 6507, 0 }; + static ulong[] dim1222KuoInit = { 1, 1, 5, 9, 27, 23, 35, 141, 327, 395, 869, 177, 3997, 11191, 0 }; + static ulong[] dim1223KuoInit = { 1, 1, 7, 9, 21, 15, 35, 163, 273, 93, 835, 3339, 6109, 2617, 0 }; + static ulong[] dim1224KuoInit = { 1, 3, 5, 9, 1, 29, 107, 161, 301, 27, 1391, 211, 5263, 10899, 0 }; + static ulong[] dim1225KuoInit = { 1, 3, 7, 7, 13, 61, 91, 179, 227, 193, 1909, 3759, 5875, 6799, 0 }; + static ulong[] dim1226KuoInit = { 1, 3, 1, 9, 17, 23, 57, 117, 201, 459, 1841, 2371, 2641, 13927, 0 }; + static ulong[] dim1227KuoInit = { 1, 3, 7, 11, 1, 1, 13, 139, 313, 1, 1551, 2693, 2785, 6959, 0 }; + static ulong[] dim1228KuoInit = { 1, 3, 3, 13, 1, 29, 117, 67, 147, 821, 1935, 2913, 7911, 4829, 0 }; + static ulong[] dim1229KuoInit = { 1, 1, 7, 7, 19, 17, 57, 33, 93, 819, 1035, 3493, 1831, 5345, 0 }; + static ulong[] dim1230KuoInit = { 1, 3, 5, 13, 9, 13, 117, 219, 415, 743, 381, 2343, 3865, 3915, 0 }; + static ulong[] dim1231KuoInit = { 1, 1, 5, 15, 3, 25, 67, 197, 59, 419, 461, 1951, 4657, 9263, 0 }; + static ulong[] dim1232KuoInit = { 1, 1, 7, 15, 31, 53, 33, 213, 169, 231, 615, 441, 7055, 16079, 0 }; + static ulong[] dim1233KuoInit = { 1, 1, 1, 15, 5, 27, 57, 79, 373, 713, 583, 3773, 4239, 14231, 0 }; + static ulong[] dim1234KuoInit = { 1, 1, 7, 15, 21, 55, 119, 219, 371, 321, 185, 1103, 7783, 8705, 0 }; + static ulong[] dim1235KuoInit = { 1, 3, 5, 15, 3, 11, 69, 127, 27, 223, 867, 2249, 597, 10051, 0 }; + static ulong[] dim1236KuoInit = { 1, 3, 5, 7, 5, 13, 99, 115, 21, 659, 1287, 1941, 6505, 1091, 0 }; + static ulong[] dim1237KuoInit = { 1, 1, 7, 1, 17, 57, 57, 155, 373, 729, 1521, 3741, 4935, 13867, 0 }; + static ulong[] dim1238KuoInit = { 1, 1, 7, 1, 19, 21, 39, 47, 451, 67, 463, 1849, 5311, 5831, 0 }; + static ulong[] dim1239KuoInit = { 1, 3, 7, 7, 29, 11, 59, 161, 29, 107, 1413, 3915, 6863, 5095, 0 }; + static ulong[] dim1240KuoInit = { 1, 1, 7, 15, 13, 37, 29, 91, 83, 663, 1629, 3005, 655, 7601, 0 }; + static ulong[] dim1241KuoInit = { 1, 1, 3, 3, 31, 47, 29, 31, 509, 319, 929, 1481, 6255, 14003, 0 }; + static ulong[] dim1242KuoInit = { 1, 3, 3, 3, 5, 7, 97, 253, 163, 801, 283, 813, 6277, 3201, 0 }; + static ulong[] dim1243KuoInit = { 1, 3, 3, 15, 5, 59, 49, 47, 259, 837, 2003, 1489, 3425, 6863, 0 }; + static ulong[] dim1244KuoInit = { 1, 3, 5, 13, 25, 55, 37, 139, 347, 95, 259, 3175, 1043, 1395, 0 }; + static ulong[] dim1245KuoInit = { 1, 3, 7, 5, 31, 37, 73, 7, 1, 883, 1641, 1941, 6885, 23, 0 }; + static ulong[] dim1246KuoInit = { 1, 1, 3, 9, 13, 45, 85, 67, 55, 11, 1717, 3461, 3189, 15989, 0 }; + static ulong[] dim1247KuoInit = { 1, 1, 1, 13, 27, 15, 93, 39, 329, 43, 175, 2253, 1193, 13257, 0 }; + static ulong[] dim1248KuoInit = { 1, 3, 3, 1, 25, 41, 111, 211, 99, 267, 965, 1311, 2661, 1981, 0 }; + static ulong[] dim1249KuoInit = { 1, 3, 7, 15, 31, 15, 37, 73, 239, 505, 983, 3299, 2891, 8247, 0 }; + static ulong[] dim1250KuoInit = { 1, 1, 5, 3, 19, 5, 45, 55, 251, 125, 977, 955, 1169, 8495, 0 }; + static ulong[] dim1251KuoInit = { 1, 3, 1, 3, 19, 31, 121, 119, 185, 43, 847, 3939, 2511, 10889, 0 }; + static ulong[] dim1252KuoInit = { 1, 3, 1, 7, 7, 17, 81, 37, 425, 663, 1715, 789, 661, 9089, 0 }; + static ulong[] dim1253KuoInit = { 1, 3, 3, 11, 1, 3, 17, 247, 311, 369, 211, 97, 6355, 16297, 0 }; + static ulong[] dim1254KuoInit = { 1, 3, 7, 13, 21, 53, 33, 71, 73, 629, 1321, 3181, 6627, 161, 0 }; + static ulong[] dim1255KuoInit = { 1, 1, 3, 5, 21, 25, 21, 231, 291, 585, 111, 1651, 1031, 13705, 0 }; + static ulong[] dim1256KuoInit = { 1, 3, 3, 9, 5, 31, 59, 51, 245, 465, 37, 3425, 4251, 1121, 0 }; + static ulong[] dim1257KuoInit = { 1, 3, 7, 11, 31, 45, 125, 245, 335, 973, 49, 1557, 4847, 10739, 0 }; + static ulong[] dim1258KuoInit = { 1, 1, 1, 3, 21, 39, 127, 67, 101, 9, 1099, 1159, 2483, 4283, 0 }; + static ulong[] dim1259KuoInit = { 1, 1, 7, 13, 29, 53, 49, 65, 5, 775, 433, 351, 493, 7233, 0 }; + static ulong[] dim1260KuoInit = { 1, 3, 5, 5, 27, 13, 73, 83, 417, 31, 1891, 1809, 1103, 4555, 0 }; + static ulong[] dim1261KuoInit = { 1, 1, 5, 9, 15, 1, 25, 63, 191, 251, 1759, 429, 2477, 12577, 0 }; + static ulong[] dim1262KuoInit = { 1, 1, 3, 5, 3, 21, 61, 245, 191, 217, 845, 2121, 2133, 6045, 0 }; + static ulong[] dim1263KuoInit = { 1, 3, 3, 5, 23, 33, 85, 15, 57, 645, 1109, 3411, 2895, 6885, 0 }; + static ulong[] dim1264KuoInit = { 1, 3, 3, 11, 13, 41, 13, 59, 45, 199, 1145, 2637, 6741, 1273, 0 }; + static ulong[] dim1265KuoInit = { 1, 3, 3, 5, 27, 33, 121, 21, 75, 687, 349, 2097, 1195, 4227, 0 }; + static ulong[] dim1266KuoInit = { 1, 1, 7, 9, 25, 51, 71, 85, 281, 825, 1335, 277, 797, 407, 0 }; + static ulong[] dim1267KuoInit = { 1, 3, 3, 15, 21, 31, 19, 11, 39, 821, 1623, 97, 1573, 13297, 0 }; + static ulong[] dim1268KuoInit = { 1, 1, 3, 1, 25, 39, 67, 113, 109, 719, 1427, 2539, 5885, 13537, 0 }; + static ulong[] dim1269KuoInit = { 1, 1, 5, 3, 15, 53, 11, 139, 393, 365, 709, 1603, 4929, 2651, 0 }; + static ulong[] dim1270KuoInit = { 1, 3, 7, 5, 3, 11, 19, 41, 123, 7, 993, 3627, 2027, 4009, 0 }; + static ulong[] dim1271KuoInit = { 1, 1, 3, 7, 3, 17, 63, 129, 323, 303, 1669, 1023, 1259, 289, 0 }; + static ulong[] dim1272KuoInit = { 1, 3, 7, 15, 15, 33, 69, 229, 291, 939, 969, 2497, 4323, 16299, 0 }; + static ulong[] dim1273KuoInit = { 1, 3, 5, 5, 17, 35, 79, 33, 471, 857, 975, 297, 7219, 12903, 0 }; + static ulong[] dim1274KuoInit = { 1, 1, 7, 7, 21, 5, 65, 53, 11, 265, 1447, 1405, 3351, 2661, 0 }; + static ulong[] dim1275KuoInit = { 1, 3, 3, 3, 1, 21, 123, 123, 361, 71, 1233, 2673, 7643, 9519, 0 }; + static ulong[] dim1276KuoInit = { 1, 1, 5, 7, 27, 41, 117, 239, 125, 183, 1375, 649, 5267, 1735, 0 }; + static ulong[] dim1277KuoInit = { 1, 1, 1, 11, 7, 33, 59, 7, 37, 705, 1055, 1661, 6213, 2083, 0 }; + static ulong[] dim1278KuoInit = { 1, 3, 1, 9, 11, 61, 91, 143, 113, 229, 809, 431, 1971, 12453, 0 }; + static ulong[] dim1279KuoInit = { 1, 1, 3, 9, 17, 23, 97, 249, 109, 669, 1643, 3305, 6141, 1793, 0 }; + static ulong[] dim1280KuoInit = { 1, 1, 5, 13, 3, 39, 37, 107, 123, 637, 869, 1969, 4195, 9431, 0 }; + static ulong[] dim1281KuoInit = { 1, 1, 7, 13, 7, 25, 97, 63, 395, 1011, 161, 827, 4001, 15159, 0 }; + static ulong[] dim1282KuoInit = { 1, 1, 3, 7, 11, 59, 11, 49, 25, 691, 73, 1171, 2937, 13877, 0 }; + static ulong[] dim1283KuoInit = { 1, 3, 7, 15, 1, 19, 119, 129, 63, 451, 1593, 1207, 67, 3621, 0 }; + static ulong[] dim1284KuoInit = { 1, 1, 1, 1, 25, 27, 45, 23, 111, 191, 1205, 4079, 1821, 5571, 0 }; + static ulong[] dim1285KuoInit = { 1, 1, 7, 5, 17, 37, 37, 249, 81, 909, 153, 209, 7919, 10763, 0 }; + static ulong[] dim1286KuoInit = { 1, 3, 5, 5, 19, 9, 101, 193, 431, 63, 1309, 2693, 2413, 14513, 0 }; + static ulong[] dim1287KuoInit = { 1, 3, 5, 7, 13, 5, 5, 203, 313, 723, 1637, 2725, 4197, 3767, 0 }; + static ulong[] dim1288KuoInit = { 1, 3, 3, 11, 1, 53, 33, 245, 181, 1001, 1057, 2701, 5861, 4199, 0 }; + static ulong[] dim1289KuoInit = { 1, 1, 5, 3, 31, 35, 19, 253, 403, 429, 1667, 1671, 7491, 1023, 0 }; + static ulong[] dim1290KuoInit = { 1, 3, 5, 7, 15, 51, 41, 253, 247, 883, 1887, 1067, 3227, 13259, 0 }; + static ulong[] dim1291KuoInit = { 1, 3, 7, 15, 5, 63, 9, 97, 87, 11, 1873, 2529, 833, 5583, 0 }; + static ulong[] dim1292KuoInit = { 1, 1, 5, 7, 17, 59, 23, 225, 91, 189, 923, 3177, 599, 4315, 0 }; + static ulong[] dim1293KuoInit = { 1, 3, 3, 11, 15, 59, 85, 75, 281, 935, 1219, 3121, 231, 13839, 0 }; + static ulong[] dim1294KuoInit = { 1, 1, 5, 9, 15, 61, 105, 27, 179, 145, 827, 2985, 6907, 14961, 0 }; + static ulong[] dim1295KuoInit = { 1, 1, 1, 1, 1, 63, 7, 3, 449, 387, 483, 603, 6607, 13241, 0 }; + static ulong[] dim1296KuoInit = { 1, 1, 7, 1, 9, 37, 73, 255, 331, 797, 679, 579, 3015, 2517, 0 }; + static ulong[] dim1297KuoInit = { 1, 1, 3, 5, 23, 15, 97, 159, 9, 469, 881, 1935, 1871, 7943, 0 }; + static ulong[] dim1298KuoInit = { 1, 1, 7, 15, 31, 33, 103, 247, 7, 217, 397, 3761, 3071, 15357, 0 }; + static ulong[] dim1299KuoInit = { 1, 3, 3, 9, 23, 25, 61, 61, 495, 195, 1615, 923, 6583, 11169, 0 }; + static ulong[] dim1300KuoInit = { 1, 1, 3, 9, 25, 7, 67, 105, 423, 519, 327, 2789, 7527, 13465, 0 }; + static ulong[] dim1301KuoInit = { 1, 1, 3, 11, 29, 57, 21, 47, 71, 771, 1255, 1469, 737, 11533, 0 }; + static ulong[] dim1302KuoInit = { 1, 1, 5, 11, 23, 31, 103, 145, 19, 931, 963, 2627, 1419, 14451, 0 }; + static ulong[] dim1303KuoInit = { 1, 3, 7, 1, 15, 45, 37, 57, 223, 151, 979, 2569, 2487, 2877, 0 }; + static ulong[] dim1304KuoInit = { 1, 1, 3, 7, 13, 39, 83, 127, 341, 687, 1575, 3193, 2845, 725, 0 }; + static ulong[] dim1305KuoInit = { 1, 1, 1, 5, 23, 39, 71, 205, 53, 477, 1961, 3967, 7169, 5443, 0 }; + static ulong[] dim1306KuoInit = { 1, 1, 5, 5, 23, 17, 107, 151, 291, 101, 1917, 3429, 6279, 1781, 0 }; + static ulong[] dim1307KuoInit = { 1, 3, 3, 11, 23, 45, 11, 137, 243, 257, 495, 3267, 1373, 15477, 0 }; + static ulong[] dim1308KuoInit = { 1, 1, 7, 5, 23, 13, 37, 139, 473, 215, 1281, 989, 2187, 1551, 0 }; + static ulong[] dim1309KuoInit = { 1, 1, 7, 7, 5, 21, 113, 195, 247, 493, 513, 1775, 1885, 5131, 0 }; + static ulong[] dim1310KuoInit = { 1, 1, 7, 15, 29, 31, 9, 59, 329, 11, 1739, 1657, 1745, 8969, 0 }; + static ulong[] dim1311KuoInit = { 1, 1, 3, 7, 19, 29, 121, 171, 33, 393, 1463, 1817, 393, 2509, 0 }; + static ulong[] dim1312KuoInit = { 1, 1, 5, 11, 23, 55, 103, 169, 313, 293, 1791, 2727, 2311, 14519, 0 }; + static ulong[] dim1313KuoInit = { 1, 3, 7, 11, 13, 21, 95, 205, 87, 431, 667, 367, 6879, 9843, 0 }; + static ulong[] dim1314KuoInit = { 1, 3, 1, 3, 3, 53, 75, 43, 115, 561, 795, 613, 4491, 913, 0 }; + static ulong[] dim1315KuoInit = { 1, 1, 5, 5, 25, 37, 71, 13, 499, 105, 9, 3759, 4997, 14747, 0 }; + static ulong[] dim1316KuoInit = { 1, 3, 3, 13, 25, 63, 27, 163, 359, 431, 5, 3371, 6051, 1099, 0 }; + static ulong[] dim1317KuoInit = { 1, 1, 3, 7, 5, 45, 19, 217, 423, 171, 933, 3441, 7451, 11831, 0 }; + static ulong[] dim1318KuoInit = { 1, 3, 7, 7, 7, 53, 81, 67, 465, 713, 1761, 3945, 3051, 8139, 0 }; + static ulong[] dim1319KuoInit = { 1, 1, 5, 7, 23, 55, 85, 205, 265, 99, 353, 4061, 3385, 4273, 0 }; + static ulong[] dim1320KuoInit = { 1, 3, 7, 7, 9, 19, 7, 81, 9, 373, 837, 1397, 3945, 14325, 0 }; + static ulong[] dim1321KuoInit = { 1, 1, 5, 7, 7, 47, 61, 195, 101, 931, 1667, 3277, 7701, 14697, 0 }; + static ulong[] dim1322KuoInit = { 1, 3, 7, 7, 11, 57, 43, 55, 399, 783, 1647, 269, 6055, 9935, 0 }; + static ulong[] dim1323KuoInit = { 1, 1, 5, 3, 5, 57, 87, 193, 15, 515, 1663, 495, 4725, 7221, 0 }; + static ulong[] dim1324KuoInit = { 1, 1, 5, 3, 23, 23, 87, 231, 133, 123, 1477, 1811, 7383, 16339, 0 }; + static ulong[] dim1325KuoInit = { 1, 3, 5, 13, 31, 57, 105, 237, 375, 129, 193, 1293, 2445, 13383, 0 }; + static ulong[] dim1326KuoInit = { 1, 3, 7, 13, 19, 51, 91, 27, 309, 421, 647, 3777, 6779, 2807, 0 }; + static ulong[] dim1327KuoInit = { 1, 3, 5, 15, 5, 43, 125, 37, 269, 155, 1733, 447, 7883, 6085, 0 }; + static ulong[] dim1328KuoInit = { 1, 3, 7, 7, 27, 63, 91, 7, 117, 369, 1019, 847, 6747, 5057, 0 }; + static ulong[] dim1329KuoInit = { 1, 3, 5, 3, 31, 19, 87, 125, 259, 355, 161, 1421, 2295, 9683, 0 }; + static ulong[] dim1330KuoInit = { 1, 3, 3, 13, 25, 37, 63, 169, 477, 633, 231, 2039, 3469, 2531, 0 }; + static ulong[] dim1331KuoInit = { 1, 3, 1, 1, 25, 1, 81, 211, 237, 233, 1743, 961, 645, 2605, 0 }; + static ulong[] dim1332KuoInit = { 1, 3, 1, 11, 3, 25, 3, 111, 123, 417, 1799, 1419, 2501, 5765, 0 }; + static ulong[] dim1333KuoInit = { 1, 1, 3, 15, 11, 17, 27, 95, 295, 315, 987, 481, 6627, 16171, 0 }; + static ulong[] dim1334KuoInit = { 1, 3, 5, 15, 15, 61, 123, 5, 369, 161, 897, 855, 625, 9975, 0 }; + static ulong[] dim1335KuoInit = { 1, 1, 5, 3, 9, 45, 59, 53, 43, 117, 789, 21, 7799, 11061, 0 }; + static ulong[] dim1336KuoInit = { 1, 1, 3, 7, 3, 17, 113, 159, 115, 965, 1541, 1037, 4723, 10151, 0 }; + static ulong[] dim1337KuoInit = { 1, 3, 1, 9, 7, 15, 19, 161, 123, 421, 109, 433, 7387, 6047, 0 }; + static ulong[] dim1338KuoInit = { 1, 3, 1, 13, 19, 49, 31, 215, 25, 289, 1995, 1135, 3719, 8453, 0 }; + static ulong[] dim1339KuoInit = { 1, 3, 3, 9, 3, 33, 15, 191, 83, 963, 199, 2199, 3273, 16165, 0 }; + static ulong[] dim1340KuoInit = { 1, 3, 3, 11, 17, 63, 71, 49, 427, 633, 735, 2009, 5049, 13649, 0 }; + static ulong[] dim1341KuoInit = { 1, 1, 3, 7, 25, 41, 79, 161, 293, 967, 969, 3253, 269, 6971, 0 }; + static ulong[] dim1342KuoInit = { 1, 1, 5, 7, 25, 9, 43, 237, 283, 135, 669, 2193, 4193, 4787, 0 }; + static ulong[] dim1343KuoInit = { 1, 3, 3, 7, 5, 19, 83, 89, 443, 443, 1511, 2309, 5483, 7583, 0 }; + static ulong[] dim1344KuoInit = { 1, 3, 3, 15, 21, 29, 113, 127, 405, 465, 1135, 2401, 7715, 13061, 0 }; + static ulong[] dim1345KuoInit = { 1, 3, 7, 7, 23, 19, 17, 59, 483, 519, 1439, 3839, 1691, 5, 0 }; + static ulong[] dim1346KuoInit = { 1, 1, 1, 13, 23, 43, 115, 103, 155, 769, 455, 17, 7791, 3333, 0 }; + static ulong[] dim1347KuoInit = { 1, 1, 7, 9, 3, 25, 31, 7, 125, 357, 759, 1203, 2107, 5361, 0 }; + static ulong[] dim1348KuoInit = { 1, 1, 5, 11, 27, 31, 23, 73, 77, 449, 661, 2337, 941, 9421, 0 }; + static ulong[] dim1349KuoInit = { 1, 1, 7, 15, 27, 17, 35, 15, 405, 317, 1977, 2449, 237, 7741, 0 }; + static ulong[] dim1350KuoInit = { 1, 1, 7, 3, 1, 15, 63, 251, 61, 123, 855, 773, 4291, 15581, 0 }; + static ulong[] dim1351KuoInit = { 1, 1, 5, 9, 15, 49, 101, 215, 239, 31, 1193, 3839, 1913, 15471, 0 }; + static ulong[] dim1352KuoInit = { 1, 3, 3, 5, 29, 1, 109, 211, 97, 1017, 1477, 2131, 6539, 4891, 0 }; + static ulong[] dim1353KuoInit = { 1, 1, 3, 11, 15, 63, 67, 175, 209, 105, 1427, 769, 7021, 287, 0 }; + static ulong[] dim1354KuoInit = { 1, 3, 3, 7, 19, 41, 109, 165, 307, 935, 379, 395, 2533, 6291, 0 }; + static ulong[] dim1355KuoInit = { 1, 3, 5, 13, 17, 3, 69, 79, 437, 861, 1115, 1351, 4951, 1753, 0 }; + static ulong[] dim1356KuoInit = { 1, 3, 1, 7, 19, 15, 83, 85, 431, 207, 481, 711, 6715, 13439, 0 }; + static ulong[] dim1357KuoInit = { 1, 1, 1, 5, 3, 13, 127, 27, 223, 297, 985, 227, 6665, 13587, 0 }; + static ulong[] dim1358KuoInit = { 1, 3, 7, 7, 7, 61, 113, 73, 443, 397, 717, 1151, 3047, 3247, 0 }; + static ulong[] dim1359KuoInit = { 1, 1, 1, 9, 1, 1, 103, 239, 351, 305, 1345, 3543, 4321, 9147, 0 }; + static ulong[] dim1360KuoInit = { 1, 1, 3, 1, 11, 53, 57, 85, 95, 707, 1817, 249, 357, 11769, 0 }; + static ulong[] dim1361KuoInit = { 1, 3, 1, 15, 15, 25, 7, 169, 499, 717, 915, 365, 3131, 12487, 0 }; + static ulong[] dim1362KuoInit = { 1, 1, 3, 11, 15, 47, 109, 9, 171, 67, 1473, 1779, 5567, 3799, 0 }; + static ulong[] dim1363KuoInit = { 1, 3, 5, 15, 23, 21, 31, 59, 1, 505, 1157, 1209, 7661, 11903, 0 }; + static ulong[] dim1364KuoInit = { 1, 3, 1, 13, 11, 5, 75, 53, 481, 433, 915, 2881, 5299, 2835, 0 }; + static ulong[] dim1365KuoInit = { 1, 3, 7, 5, 23, 13, 127, 229, 157, 643, 847, 3613, 1999, 3807, 0 }; + static ulong[] dim1366KuoInit = { 1, 3, 5, 11, 13, 39, 79, 11, 131, 603, 1013, 1197, 7583, 8195, 0 }; + static ulong[] dim1367KuoInit = { 1, 3, 3, 7, 27, 29, 99, 19, 503, 455, 1453, 2233, 2479, 8489, 0 }; + static ulong[] dim1368KuoInit = { 1, 3, 5, 1, 21, 37, 27, 207, 405, 87, 319, 3323, 4809, 12599, 0 }; + static ulong[] dim1369KuoInit = { 1, 3, 7, 15, 29, 3, 121, 249, 31, 601, 865, 2819, 2633, 15541, 0 }; + static ulong[] dim1370KuoInit = { 1, 3, 5, 1, 25, 53, 121, 57, 75, 327, 2047, 253, 7945, 14209, 0 }; + static ulong[] dim1371KuoInit = { 1, 1, 7, 11, 21, 3, 13, 91, 417, 825, 1381, 3653, 4187, 4685, 0 }; + static ulong[] dim1372KuoInit = { 1, 3, 3, 9, 11, 17, 87, 75, 333, 871, 1679, 2943, 4803, 8147, 0 }; + static ulong[] dim1373KuoInit = { 1, 1, 1, 9, 13, 1, 105, 95, 347, 543, 1435, 2337, 5971, 7605, 0 }; + static ulong[] dim1374KuoInit = { 1, 3, 5, 15, 19, 51, 35, 91, 187, 833, 1921, 573, 3605, 8627, 0 }; + static ulong[] dim1375KuoInit = { 1, 3, 5, 7, 25, 7, 115, 93, 87, 13, 1323, 3821, 587, 5079, 0 }; + static ulong[] dim1376KuoInit = { 1, 3, 5, 3, 25, 25, 89, 185, 473, 909, 1245, 1589, 63, 10765, 0 }; + static ulong[] dim1377KuoInit = { 1, 3, 5, 5, 15, 3, 9, 149, 237, 107, 879, 2487, 7995, 12713, 0 }; + static ulong[] dim1378KuoInit = { 1, 3, 3, 3, 19, 55, 43, 221, 289, 129, 1123, 3411, 703, 9585, 0 }; + static ulong[] dim1379KuoInit = { 1, 1, 5, 3, 7, 63, 13, 243, 235, 253, 357, 563, 519, 3471, 0 }; + static ulong[] dim1380KuoInit = { 1, 1, 3, 13, 9, 59, 67, 61, 321, 149, 365, 2645, 2309, 3303, 0 }; + static ulong[] dim1381KuoInit = { 1, 1, 5, 5, 13, 7, 53, 175, 207, 507, 1159, 3869, 8139, 13899, 0 }; + static ulong[] dim1382KuoInit = { 1, 3, 5, 3, 23, 9, 123, 37, 325, 41, 679, 513, 4379, 3493, 0 }; + static ulong[] dim1383KuoInit = { 1, 1, 7, 3, 29, 9, 117, 203, 461, 831, 1757, 2815, 1215, 1725, 0 }; + static ulong[] dim1384KuoInit = { 1, 1, 7, 7, 23, 45, 75, 159, 395, 315, 709, 887, 6935, 2307, 0 }; + static ulong[] dim1385KuoInit = { 1, 1, 7, 7, 5, 51, 29, 141, 215, 783, 1161, 3887, 8103, 7461, 0 }; + static ulong[] dim1386KuoInit = { 1, 1, 7, 3, 21, 5, 59, 123, 283, 921, 225, 453, 2125, 559, 0 }; + static ulong[] dim1387KuoInit = { 1, 3, 7, 13, 21, 19, 121, 201, 367, 215, 1727, 1743, 4875, 2819, 0 }; + static ulong[] dim1388KuoInit = { 1, 3, 3, 13, 15, 53, 57, 35, 419, 595, 1581, 2881, 3473, 7201, 0 }; + static ulong[] dim1389KuoInit = { 1, 3, 5, 5, 19, 17, 113, 175, 195, 829, 115, 491, 6439, 4085, 0 }; + static ulong[] dim1390KuoInit = { 1, 1, 5, 9, 7, 9, 111, 23, 459, 335, 1529, 1519, 2855, 11923, 0 }; + static ulong[] dim1391KuoInit = { 1, 3, 7, 9, 13, 41, 19, 229, 73, 865, 1379, 1315, 1403, 10489, 0 }; + static ulong[] dim1392KuoInit = { 1, 1, 1, 7, 17, 35, 71, 199, 195, 89, 855, 355, 5087, 13173, 0 }; + static ulong[] dim1393KuoInit = { 1, 3, 5, 7, 3, 45, 77, 109, 105, 919, 21, 2749, 5401, 11701, 0 }; + static ulong[] dim1394KuoInit = { 1, 3, 1, 15, 5, 9, 29, 213, 489, 455, 791, 215, 1011, 2501, 0 }; + static ulong[] dim1395KuoInit = { 1, 3, 1, 9, 17, 7, 61, 99, 381, 669, 1787, 1443, 6135, 3273, 0 }; + static ulong[] dim1396KuoInit = { 1, 3, 1, 3, 27, 47, 31, 153, 365, 271, 1499, 1229, 5791, 2251, 0 }; + static ulong[] dim1397KuoInit = { 1, 1, 1, 3, 9, 31, 109, 53, 293, 135, 1329, 2795, 4335, 14817, 0 }; + static ulong[] dim1398KuoInit = { 1, 3, 1, 15, 19, 7, 43, 223, 483, 237, 803, 1713, 7969, 9681, 0 }; + static ulong[] dim1399KuoInit = { 1, 1, 7, 1, 23, 45, 67, 87, 57, 261, 955, 2917, 549, 4725, 0 }; + static ulong[] dim1400KuoInit = { 1, 1, 1, 7, 13, 43, 63, 153, 395, 313, 1219, 655, 6489, 2129, 0 }; + static ulong[] dim1401KuoInit = { 1, 3, 3, 3, 7, 51, 35, 233, 289, 715, 1227, 2041, 3639, 1465, 0 }; + static ulong[] dim1402KuoInit = { 1, 3, 1, 7, 3, 37, 97, 149, 51, 313, 1883, 1411, 3319, 2599, 0 }; + static ulong[] dim1403KuoInit = { 1, 1, 7, 13, 25, 13, 89, 245, 251, 841, 1367, 4039, 4389, 7129, 0 }; + static ulong[] dim1404KuoInit = { 1, 3, 5, 15, 3, 55, 113, 97, 159, 621, 251, 2539, 7017, 1039, 0 }; + static ulong[] dim1405KuoInit = { 1, 3, 3, 9, 27, 31, 53, 61, 165, 753, 1733, 671, 665, 4893, 0 }; + static ulong[] dim1406KuoInit = { 1, 1, 7, 5, 25, 11, 7, 189, 457, 5, 97, 2399, 3089, 4811, 0 }; + static ulong[] dim1407KuoInit = { 1, 1, 3, 13, 29, 19, 73, 105, 187, 871, 499, 443, 6807, 3753, 0 }; + static ulong[] dim1408KuoInit = { 1, 3, 1, 5, 9, 15, 53, 83, 91, 763, 1585, 1675, 5137, 10483, 0 }; + static ulong[] dim1409KuoInit = { 1, 1, 7, 5, 25, 51, 43, 47, 151, 13, 1117, 1465, 2497, 7677, 0 }; + static ulong[] dim1410KuoInit = { 1, 1, 1, 3, 15, 15, 43, 53, 161, 689, 2027, 437, 3599, 6837, 0 }; + static ulong[] dim1411KuoInit = { 1, 3, 3, 9, 21, 5, 81, 99, 249, 785, 763, 1203, 1541, 6497, 0 }; + static ulong[] dim1412KuoInit = { 1, 1, 5, 7, 27, 7, 121, 91, 271, 461, 1531, 3255, 847, 14503, 0 }; + static ulong[] dim1413KuoInit = { 1, 1, 3, 15, 9, 53, 125, 107, 321, 579, 813, 2295, 2521, 6773, 0 }; + static ulong[] dim1414KuoInit = { 1, 3, 3, 1, 15, 55, 71, 61, 307, 917, 217, 1133, 7255, 16083, 0 }; + static ulong[] dim1415KuoInit = { 1, 3, 1, 1, 3, 7, 57, 27, 243, 989, 223, 3857, 2357, 11315, 0 }; + static ulong[] dim1416KuoInit = { 1, 3, 5, 5, 23, 41, 55, 75, 241, 829, 1865, 909, 4509, 5163, 0 }; + static ulong[] dim1417KuoInit = { 1, 1, 1, 13, 27, 5, 117, 79, 171, 135, 623, 2515, 3661, 941, 0 }; + static ulong[] dim1418KuoInit = { 1, 3, 5, 13, 17, 29, 9, 147, 73, 321, 895, 3263, 6897, 8551, 0 }; + static ulong[] dim1419KuoInit = { 1, 1, 5, 11, 21, 45, 57, 153, 83, 971, 403, 617, 545, 6489, 0 }; + static ulong[] dim1420KuoInit = { 1, 1, 5, 9, 31, 37, 19, 241, 89, 583, 1365, 2649, 7011, 6183, 0 }; + static ulong[] dim1421KuoInit = { 1, 3, 5, 9, 3, 5, 45, 237, 351, 811, 445, 557, 4103, 11185, 0 }; + static ulong[] dim1422KuoInit = { 1, 3, 3, 13, 25, 23, 21, 249, 209, 775, 1397, 2501, 4535, 4957, 0 }; + static ulong[] dim1423KuoInit = { 1, 1, 1, 13, 7, 43, 55, 179, 239, 43, 225, 2827, 955, 665, 0 }; + static ulong[] dim1424KuoInit = { 1, 1, 3, 5, 15, 35, 77, 153, 429, 35, 539, 3543, 1971, 2865, 0 }; + static ulong[] dim1425KuoInit = { 1, 3, 7, 3, 27, 35, 87, 51, 281, 247, 547, 2185, 2593, 1301, 0 }; + static ulong[] dim1426KuoInit = { 1, 3, 5, 11, 19, 11, 79, 241, 467, 515, 531, 3285, 1575, 7869, 0 }; + static ulong[] dim1427KuoInit = { 1, 3, 1, 13, 25, 15, 109, 231, 349, 955, 2019, 3475, 2927, 14383, 0 }; + static ulong[] dim1428KuoInit = { 1, 1, 7, 1, 17, 43, 43, 131, 485, 179, 901, 483, 4879, 15189, 0 }; + static ulong[] dim1429KuoInit = { 1, 1, 5, 11, 7, 39, 111, 27, 29, 79, 261, 77, 231, 8577, 0 }; + static ulong[] dim1430KuoInit = { 1, 3, 1, 11, 25, 15, 25, 41, 457, 677, 1033, 161, 3215, 105, 0 }; + static ulong[] dim1431KuoInit = { 1, 3, 1, 15, 3, 57, 125, 41, 325, 467, 1325, 1287, 51, 9463, 0 }; + static ulong[] dim1432KuoInit = { 1, 1, 1, 9, 1, 33, 39, 47, 313, 305, 2023, 1131, 4167, 4519, 0 }; + static ulong[] dim1433KuoInit = { 1, 1, 5, 15, 1, 47, 123, 151, 263, 143, 91, 1673, 4175, 4575, 0 }; + static ulong[] dim1434KuoInit = { 1, 1, 7, 3, 7, 41, 95, 27, 183, 437, 587, 3821, 8035, 7627, 0 }; + static ulong[] dim1435KuoInit = { 1, 1, 3, 5, 17, 53, 95, 73, 335, 497, 643, 3309, 7139, 10811, 0 }; + static ulong[] dim1436KuoInit = { 1, 3, 1, 13, 7, 29, 83, 15, 29, 881, 881, 1253, 7267, 4221, 0 }; + static ulong[] dim1437KuoInit = { 1, 3, 7, 13, 15, 47, 71, 63, 493, 365, 1209, 2503, 3963, 5069, 0 }; + static ulong[] dim1438KuoInit = { 1, 1, 5, 5, 23, 55, 107, 255, 17, 561, 1131, 497, 5731, 13287, 0 }; + static ulong[] dim1439KuoInit = { 1, 3, 5, 11, 5, 59, 25, 131, 375, 165, 1051, 3129, 6517, 6317, 0 }; + static ulong[] dim1440KuoInit = { 1, 3, 5, 9, 17, 29, 57, 215, 77, 197, 1775, 3959, 185, 11431, 0 }; + static ulong[] dim1441KuoInit = { 1, 1, 1, 11, 11, 45, 29, 245, 193, 747, 1449, 2185, 7751, 10009, 0 }; + static ulong[] dim1442KuoInit = { 1, 1, 1, 5, 27, 19, 39, 161, 355, 455, 1625, 1283, 1547, 8707, 0 }; + static ulong[] dim1443KuoInit = { 1, 1, 1, 11, 7, 15, 35, 193, 489, 619, 515, 199, 5439, 15711, 0 }; + static ulong[] dim1444KuoInit = { 1, 1, 7, 1, 29, 21, 69, 13, 343, 581, 495, 3963, 911, 3995, 0 }; + static ulong[] dim1445KuoInit = { 1, 1, 1, 7, 21, 5, 9, 31, 291, 825, 7, 2621, 1149, 2709, 0 }; + static ulong[] dim1446KuoInit = { 1, 3, 3, 13, 7, 35, 69, 43, 397, 641, 89, 3325, 5567, 3487, 0 }; + static ulong[] dim1447KuoInit = { 1, 3, 5, 5, 1, 17, 11, 97, 309, 371, 145, 3255, 5161, 7787, 0 }; + static ulong[] dim1448KuoInit = { 1, 3, 7, 7, 27, 1, 1, 235, 47, 251, 1525, 2661, 3971, 11319, 0 }; + static ulong[] dim1449KuoInit = { 1, 3, 5, 3, 11, 21, 69, 97, 13, 931, 1955, 3497, 3963, 519, 0 }; + static ulong[] dim1450KuoInit = { 1, 1, 5, 9, 21, 15, 11, 201, 175, 855, 1867, 3941, 6505, 3451, 0 }; + static ulong[] dim1451KuoInit = { 1, 1, 7, 13, 25, 45, 27, 91, 149, 827, 1791, 139, 6721, 9, 0 }; + static ulong[] dim1452KuoInit = { 1, 3, 3, 7, 19, 13, 95, 161, 91, 333, 203, 3195, 517, 3911, 0 }; + static ulong[] dim1453KuoInit = { 1, 1, 5, 1, 3, 7, 113, 195, 501, 203, 193, 3585, 3217, 2009, 0 }; + static ulong[] dim1454KuoInit = { 1, 1, 5, 13, 21, 29, 9, 209, 381, 245, 1317, 3577, 3327, 9253, 0 }; + static ulong[] dim1455KuoInit = { 1, 3, 3, 15, 1, 5, 75, 215, 349, 143, 1607, 2817, 8185, 13991, 0 }; + static ulong[] dim1456KuoInit = { 1, 3, 3, 11, 23, 29, 73, 15, 159, 425, 1169, 2989, 5835, 12687, 0 }; + static ulong[] dim1457KuoInit = { 1, 1, 1, 11, 13, 13, 79, 97, 351, 455, 1465, 2013, 5133, 1747, 0 }; + static ulong[] dim1458KuoInit = { 1, 3, 3, 13, 3, 29, 53, 37, 357, 55, 195, 43, 3903, 7013, 0 }; + static ulong[] dim1459KuoInit = { 1, 3, 5, 13, 25, 43, 19, 233, 17, 31, 1727, 557, 2581, 847, 0 }; + static ulong[] dim1460KuoInit = { 1, 1, 7, 5, 21, 27, 7, 27, 487, 961, 1095, 3813, 7967, 15283, 0 }; + static ulong[] dim1461KuoInit = { 1, 3, 7, 7, 27, 49, 15, 199, 413, 295, 441, 2023, 2453, 2243, 0 }; + static ulong[] dim1462KuoInit = { 1, 3, 7, 9, 19, 13, 99, 85, 227, 61, 933, 3897, 2399, 455, 0 }; + static ulong[] dim1463KuoInit = { 1, 3, 1, 15, 13, 45, 123, 13, 39, 431, 1573, 2771, 2273, 12613, 0 }; + static ulong[] dim1464KuoInit = { 1, 1, 3, 13, 1, 29, 127, 59, 159, 1005, 483, 3031, 5029, 1763, 0 }; + static ulong[] dim1465KuoInit = { 1, 1, 7, 9, 17, 27, 87, 25, 313, 305, 1611, 693, 3701, 573, 0 }; + static ulong[] dim1466KuoInit = { 1, 3, 7, 13, 5, 61, 93, 69, 357, 681, 291, 1251, 3889, 3687, 0 }; + static ulong[] dim1467KuoInit = { 1, 1, 3, 15, 9, 31, 121, 213, 115, 231, 349, 2141, 4443, 12319, 0 }; + static ulong[] dim1468KuoInit = { 1, 1, 1, 5, 1, 37, 59, 21, 399, 751, 841, 33, 7195, 8403, 0 }; + static ulong[] dim1469KuoInit = { 1, 3, 3, 13, 5, 41, 111, 21, 135, 945, 1915, 2351, 6429, 10993, 0 }; + static ulong[] dim1470KuoInit = { 1, 1, 1, 1, 29, 43, 45, 13, 395, 407, 47, 1007, 7525, 6707, 0 }; + static ulong[] dim1471KuoInit = { 1, 3, 5, 15, 23, 3, 49, 149, 391, 689, 147, 1173, 3793, 4249, 0 }; + static ulong[] dim1472KuoInit = { 1, 3, 1, 13, 25, 35, 109, 147, 323, 161, 257, 2023, 5693, 16199, 0 }; + static ulong[] dim1473KuoInit = { 1, 3, 3, 9, 17, 3, 9, 191, 19, 405, 1841, 1669, 4691, 11907, 0 }; + static ulong[] dim1474KuoInit = { 1, 1, 3, 5, 13, 35, 45, 27, 127, 329, 931, 1, 2521, 15307, 0 }; + static ulong[] dim1475KuoInit = { 1, 1, 5, 3, 11, 25, 31, 233, 1, 769, 433, 3785, 3631, 8573, 0 }; + static ulong[] dim1476KuoInit = { 1, 1, 3, 1, 23, 57, 67, 227, 393, 469, 1579, 2235, 493, 2477, 0 }; + static ulong[] dim1477KuoInit = { 1, 3, 7, 3, 9, 19, 69, 123, 205, 553, 1871, 3807, 1563, 2771, 0 }; + static ulong[] dim1478KuoInit = { 1, 3, 3, 11, 11, 33, 55, 27, 51, 903, 1681, 2613, 2519, 9529, 0 }; + static ulong[] dim1479KuoInit = { 1, 1, 7, 11, 29, 55, 31, 185, 85, 929, 233, 2619, 2989, 191, 0 }; + static ulong[] dim1480KuoInit = { 1, 1, 1, 3, 1, 47, 47, 225, 387, 717, 815, 853, 819, 5645, 0 }; + static ulong[] dim1481KuoInit = { 1, 1, 5, 3, 1, 55, 89, 59, 39, 687, 1395, 535, 4977, 8155, 0 }; + static ulong[] dim1482KuoInit = { 1, 3, 7, 1, 11, 57, 107, 137, 407, 155, 313, 2205, 3095, 15179, 0 }; + static ulong[] dim1483KuoInit = { 1, 1, 7, 13, 29, 5, 121, 173, 21, 247, 1663, 1937, 5113, 7439, 0 }; + static ulong[] dim1484KuoInit = { 1, 3, 1, 7, 1, 39, 31, 129, 109, 447, 1269, 3133, 4933, 11893, 0 }; + static ulong[] dim1485KuoInit = { 1, 3, 3, 15, 9, 7, 21, 157, 397, 465, 1057, 2355, 4663, 13955, 0 }; + static ulong[] dim1486KuoInit = { 1, 1, 7, 3, 1, 35, 71, 175, 439, 1019, 1479, 2519, 5119, 15245, 0 }; + static ulong[] dim1487KuoInit = { 1, 1, 7, 3, 23, 49, 55, 91, 269, 407, 393, 1495, 6153, 15703, 0 }; + static ulong[] dim1488KuoInit = { 1, 1, 3, 7, 25, 3, 45, 87, 141, 693, 555, 3629, 2723, 4357, 0 }; + static ulong[] dim1489KuoInit = { 1, 3, 3, 7, 15, 27, 103, 161, 423, 785, 1171, 2335, 1845, 14373, 0 }; + static ulong[] dim1490KuoInit = { 1, 3, 5, 5, 1, 31, 117, 35, 181, 263, 1337, 3239, 617, 11499, 0 }; + static ulong[] dim1491KuoInit = { 1, 1, 1, 9, 15, 17, 103, 201, 79, 211, 2043, 3733, 7593, 6523, 0 }; + static ulong[] dim1492KuoInit = { 1, 3, 5, 5, 3, 59, 11, 163, 155, 215, 1621, 2615, 2915, 2459, 0 }; + static ulong[] dim1493KuoInit = { 1, 3, 7, 11, 11, 11, 93, 239, 367, 553, 1341, 129, 7651, 2841, 0 }; + static ulong[] dim1494KuoInit = { 1, 3, 7, 7, 7, 21, 45, 99, 63, 601, 1877, 765, 5831, 1825, 0 }; + static ulong[] dim1495KuoInit = { 1, 1, 7, 3, 21, 27, 71, 53, 185, 675, 891, 657, 5343, 3583, 0 }; + static ulong[] dim1496KuoInit = { 1, 3, 5, 9, 17, 57, 95, 57, 427, 329, 681, 2663, 3183, 7429, 0 }; + static ulong[] dim1497KuoInit = { 1, 3, 7, 3, 17, 9, 93, 105, 409, 975, 205, 429, 4473, 10269, 0 }; + static ulong[] dim1498KuoInit = { 1, 3, 1, 1, 11, 51, 25, 97, 333, 71, 1513, 1273, 1235, 5023, 0 }; + static ulong[] dim1499KuoInit = { 1, 1, 7, 9, 17, 59, 75, 51, 277, 377, 3, 3357, 2595, 7939, 0 }; + static ulong[] dim1500KuoInit = { 1, 3, 3, 1, 7, 47, 11, 241, 235, 761, 283, 3277, 2121, 69, 0 }; + static ulong[] dim1501KuoInit = { 1, 3, 1, 3, 5, 5, 57, 5, 99, 869, 707, 2379, 5439, 4981, 0 }; + static ulong[] dim1502KuoInit = { 1, 3, 7, 9, 5, 9, 115, 155, 191, 905, 1173, 975, 6825, 8257, 0 }; + static ulong[] dim1503KuoInit = { 1, 1, 3, 13, 17, 13, 63, 143, 305, 577, 1895, 1943, 2335, 8957, 0 }; + static ulong[] dim1504KuoInit = { 1, 3, 7, 3, 15, 19, 89, 91, 497, 145, 1419, 1449, 5305, 1379, 0 }; + static ulong[] dim1505KuoInit = { 1, 3, 1, 13, 9, 51, 103, 169, 265, 347, 697, 3735, 6987, 2565, 0 }; + static ulong[] dim1506KuoInit = { 1, 3, 3, 5, 1, 19, 83, 211, 247, 81, 131, 2243, 7563, 14221, 0 }; + static ulong[] dim1507KuoInit = { 1, 3, 3, 11, 27, 1, 97, 85, 265, 423, 173, 1873, 3889, 1845, 0 }; + static ulong[] dim1508KuoInit = { 1, 1, 1, 11, 15, 25, 25, 155, 111, 327, 1089, 335, 7635, 6467, 0 }; + static ulong[] dim1509KuoInit = { 1, 3, 5, 7, 15, 33, 103, 231, 455, 681, 547, 3389, 4279, 6037, 0 }; + static ulong[] dim1510KuoInit = { 1, 3, 3, 7, 3, 11, 11, 165, 113, 499, 977, 3805, 2733, 15643, 0 }; + static ulong[] dim1511KuoInit = { 1, 1, 3, 7, 23, 49, 39, 165, 323, 313, 1731, 2977, 4795, 12387, 0 }; + static ulong[] dim1512KuoInit = { 1, 1, 5, 15, 27, 15, 43, 149, 71, 19, 1025, 2585, 5975, 12473, 0 }; + static ulong[] dim1513KuoInit = { 1, 3, 7, 15, 15, 21, 33, 29, 351, 909, 813, 3901, 3235, 3719, 0 }; + static ulong[] dim1514KuoInit = { 1, 3, 3, 1, 29, 63, 55, 173, 405, 841, 871, 213, 4747, 11611, 0 }; + static ulong[] dim1515KuoInit = { 1, 1, 1, 7, 15, 11, 83, 21, 123, 929, 1137, 3843, 5919, 151, 0 }; + static ulong[] dim1516KuoInit = { 1, 1, 3, 1, 29, 53, 111, 133, 285, 499, 2011, 121, 2853, 7587, 0 }; + static ulong[] dim1517KuoInit = { 1, 3, 7, 1, 15, 33, 87, 139, 429, 97, 375, 1273, 2745, 12045, 0 }; + static ulong[] dim1518KuoInit = { 1, 1, 5, 13, 17, 55, 43, 3, 465, 1, 1065, 647, 2497, 14775, 0 }; + static ulong[] dim1519KuoInit = { 1, 1, 5, 5, 15, 41, 39, 37, 397, 621, 1735, 1009, 1289, 2375, 0 }; + static ulong[] dim1520KuoInit = { 1, 3, 5, 11, 1, 45, 73, 207, 375, 825, 697, 3765, 7181, 4953, 0 }; + static ulong[] dim1521KuoInit = { 1, 3, 7, 7, 23, 15, 75, 11, 137, 1017, 203, 1325, 6661, 8569, 0 }; + static ulong[] dim1522KuoInit = { 1, 1, 1, 15, 23, 9, 15, 157, 179, 699, 1493, 2161, 3159, 2709, 0 }; + static ulong[] dim1523KuoInit = { 1, 3, 7, 3, 15, 51, 95, 101, 467, 303, 1867, 3819, 7593, 6133, 0 }; + static ulong[] dim1524KuoInit = { 1, 3, 7, 13, 25, 27, 87, 11, 113, 861, 1393, 1521, 2109, 11899, 0 }; + static ulong[] dim1525KuoInit = { 1, 3, 5, 11, 25, 53, 27, 249, 193, 783, 609, 3069, 3901, 391, 0 }; + static ulong[] dim1526KuoInit = { 1, 3, 5, 11, 19, 13, 55, 147, 325, 131, 659, 1277, 6127, 1033, 0 }; + static ulong[] dim1527KuoInit = { 1, 3, 1, 7, 31, 13, 1, 141, 377, 159, 1945, 2031, 8039, 13851, 0 }; + static ulong[] dim1528KuoInit = { 1, 3, 5, 7, 27, 17, 79, 47, 421, 517, 751, 3049, 6109, 11027, 0 }; + static ulong[] dim1529KuoInit = { 1, 3, 3, 11, 23, 41, 89, 225, 367, 109, 1295, 2691, 4677, 9207, 0 }; + static ulong[] dim1530KuoInit = { 1, 1, 7, 7, 7, 27, 89, 221, 267, 537, 2003, 3357, 8113, 8173, 0 }; + static ulong[] dim1531KuoInit = { 1, 1, 7, 15, 19, 23, 21, 173, 159, 535, 1685, 2259, 6515, 15853, 0 }; + static ulong[] dim1532KuoInit = { 1, 3, 3, 15, 13, 21, 105, 173, 173, 13, 423, 2259, 4145, 6543, 0 }; + static ulong[] dim1533KuoInit = { 1, 1, 3, 11, 13, 41, 35, 239, 307, 893, 73, 1325, 7975, 8395, 0 }; + static ulong[] dim1534KuoInit = { 1, 1, 7, 11, 11, 11, 115, 195, 407, 543, 801, 1449, 8121, 9627, 0 }; + static ulong[] dim1535KuoInit = { 1, 1, 1, 1, 13, 33, 41, 207, 347, 49, 897, 557, 5917, 13163, 0 }; + static ulong[] dim1536KuoInit = { 1, 1, 7, 13, 7, 9, 51, 241, 47, 479, 1399, 3229, 5201, 537, 0 }; + static ulong[] dim1537KuoInit = { 1, 3, 7, 3, 9, 63, 31, 109, 381, 631, 521, 139, 4229, 1639, 0 }; + static ulong[] dim1538KuoInit = { 1, 3, 3, 7, 1, 23, 15, 99, 395, 991, 627, 571, 833, 6631, 0 }; + static ulong[] dim1539KuoInit = { 1, 1, 7, 3, 31, 9, 99, 145, 237, 181, 1911, 2985, 2415, 5363, 0 }; + static ulong[] dim1540KuoInit = { 1, 3, 5, 3, 27, 1, 111, 133, 307, 211, 1119, 2289, 5333, 14747, 0 }; + static ulong[] dim1541KuoInit = { 1, 3, 7, 5, 9, 27, 5, 101, 113, 505, 931, 677, 6225, 16279, 0 }; + static ulong[] dim1542KuoInit = { 1, 1, 5, 9, 19, 47, 57, 3, 281, 207, 621, 939, 839, 4089, 0 }; + static ulong[] dim1543KuoInit = { 1, 1, 5, 11, 25, 61, 117, 139, 5, 325, 745, 3423, 31, 1451, 0 }; + static ulong[] dim1544KuoInit = { 1, 3, 5, 5, 3, 9, 121, 185, 497, 203, 367, 3049, 4827, 3363, 0 }; + static ulong[] dim1545KuoInit = { 1, 3, 7, 5, 1, 45, 91, 199, 183, 577, 625, 3641, 963, 9379, 0 }; + static ulong[] dim1546KuoInit = { 1, 3, 5, 9, 5, 53, 17, 205, 331, 329, 669, 2403, 3027, 297, 0 }; + static ulong[] dim1547KuoInit = { 1, 3, 5, 9, 19, 31, 43, 249, 361, 923, 635, 3461, 3901, 439, 0 }; + static ulong[] dim1548KuoInit = { 1, 3, 7, 15, 21, 25, 115, 115, 457, 607, 699, 2649, 3003, 1599, 0 }; + static ulong[] dim1549KuoInit = { 1, 1, 5, 15, 21, 35, 61, 97, 131, 521, 1045, 2401, 2885, 11795, 0 }; + static ulong[] dim1550KuoInit = { 1, 1, 1, 11, 19, 13, 119, 117, 31, 575, 427, 3689, 3801, 12267, 0 }; + static ulong[] dim1551KuoInit = { 1, 1, 3, 7, 27, 45, 15, 235, 281, 777, 1181, 2445, 7947, 2081, 0 }; + static ulong[] dim1552KuoInit = { 1, 1, 5, 3, 31, 57, 57, 219, 135, 717, 1369, 2221, 4397, 16195, 0 }; + static ulong[] dim1553KuoInit = { 1, 3, 5, 13, 11, 17, 7, 189, 97, 7, 397, 1557, 7181, 16205, 0 }; + static ulong[] dim1554KuoInit = { 1, 1, 7, 15, 13, 25, 79, 241, 143, 959, 529, 3899, 5411, 8769, 0 }; + static ulong[] dim1555KuoInit = { 1, 1, 7, 1, 3, 17, 109, 25, 389, 463, 1675, 627, 6383, 5007, 0 }; + static ulong[] dim1556KuoInit = { 1, 3, 1, 13, 19, 3, 13, 3, 293, 755, 1827, 755, 3325, 13447, 0 }; + static ulong[] dim1557KuoInit = { 1, 1, 7, 15, 17, 5, 87, 17, 423, 901, 777, 919, 2655, 1423, 0 }; + static ulong[] dim1558KuoInit = { 1, 1, 3, 13, 19, 41, 89, 9, 475, 479, 981, 1031, 7207, 3605, 0 }; + static ulong[] dim1559KuoInit = { 1, 3, 5, 7, 9, 41, 111, 201, 389, 139, 1853, 1773, 233, 3695, 0 }; + static ulong[] dim1560KuoInit = { 1, 1, 3, 1, 3, 47, 83, 15, 49, 867, 1513, 3203, 3081, 8429, 0 }; + static ulong[] dim1561KuoInit = { 1, 1, 5, 11, 11, 33, 67, 225, 303, 825, 1711, 1521, 1569, 5233, 0 }; + static ulong[] dim1562KuoInit = { 1, 3, 3, 11, 27, 41, 37, 247, 211, 143, 855, 3755, 569, 10155, 0 }; + static ulong[] dim1563KuoInit = { 1, 1, 7, 3, 21, 57, 7, 83, 133, 791, 565, 2217, 7621, 14141, 0 }; + static ulong[] dim1564KuoInit = { 1, 1, 5, 13, 3, 57, 7, 29, 131, 935, 1555, 1103, 7395, 4079, 0 }; + static ulong[] dim1565KuoInit = { 1, 1, 7, 3, 13, 9, 13, 71, 345, 1003, 1519, 1757, 539, 9207, 0 }; + static ulong[] dim1566KuoInit = { 1, 3, 1, 3, 1, 11, 13, 143, 365, 981, 1691, 2501, 7155, 4189, 0 }; + static ulong[] dim1567KuoInit = { 1, 3, 3, 1, 23, 37, 33, 229, 411, 329, 915, 2373, 2525, 12319, 0 }; + static ulong[] dim1568KuoInit = { 1, 1, 3, 3, 5, 45, 77, 23, 317, 311, 425, 1329, 3619, 11941, 0 }; + static ulong[] dim1569KuoInit = { 1, 3, 1, 1, 19, 17, 39, 37, 405, 275, 983, 995, 4925, 1005, 0 }; + static ulong[] dim1570KuoInit = { 1, 1, 1, 5, 31, 1, 71, 137, 481, 489, 1381, 3919, 7841, 14843, 0 }; + static ulong[] dim1571KuoInit = { 1, 1, 7, 15, 13, 37, 11, 201, 43, 311, 921, 2755, 2997, 4753, 0 }; + static ulong[] dim1572KuoInit = { 1, 1, 3, 7, 27, 35, 87, 203, 197, 27, 1839, 2847, 3261, 3139, 0 }; + static ulong[] dim1573KuoInit = { 1, 1, 7, 1, 25, 5, 9, 9, 497, 125, 1451, 1381, 1975, 10493, 0 }; + static ulong[] dim1574KuoInit = { 1, 1, 1, 11, 11, 25, 3, 9, 39, 989, 975, 1825, 7089, 10475, 0 }; + static ulong[] dim1575KuoInit = { 1, 1, 5, 13, 25, 33, 69, 55, 179, 163, 1233, 1601, 1893, 8225, 0 }; + static ulong[] dim1576KuoInit = { 1, 1, 3, 15, 23, 11, 117, 71, 151, 437, 371, 1543, 2417, 13195, 0 }; + static ulong[] dim1577KuoInit = { 1, 3, 7, 9, 25, 33, 63, 215, 193, 415, 1771, 715, 4011, 11739, 0 }; + static ulong[] dim1578KuoInit = { 1, 3, 3, 13, 17, 1, 105, 169, 5, 259, 169, 1207, 5425, 6091, 0 }; + static ulong[] dim1579KuoInit = { 1, 1, 5, 11, 29, 43, 25, 245, 33, 995, 1797, 279, 6443, 14507, 0 }; + static ulong[] dim1580KuoInit = { 1, 3, 7, 7, 5, 29, 117, 141, 409, 367, 1223, 1499, 5651, 3337, 0 }; + static ulong[] dim1581KuoInit = { 1, 1, 3, 9, 15, 21, 21, 27, 23, 693, 1431, 2055, 2959, 1347, 0 }; + static ulong[] dim1582KuoInit = { 1, 1, 1, 9, 7, 27, 67, 127, 63, 213, 763, 1221, 2319, 5313, 0 }; + static ulong[] dim1583KuoInit = { 1, 1, 3, 11, 21, 33, 43, 243, 113, 223, 1095, 2433, 1253, 16303, 0 }; + static ulong[] dim1584KuoInit = { 1, 1, 5, 15, 21, 61, 39, 147, 263, 943, 321, 2599, 3513, 6595, 0 }; + static ulong[] dim1585KuoInit = { 1, 1, 7, 3, 9, 25, 19, 73, 253, 889, 1699, 1709, 6451, 2939, 0 }; + static ulong[] dim1586KuoInit = { 1, 3, 3, 15, 29, 29, 53, 133, 349, 553, 1677, 3949, 1701, 1187, 0 }; + static ulong[] dim1587KuoInit = { 1, 3, 7, 9, 27, 5, 17, 15, 185, 583, 1117, 2869, 6929, 8117, 0 }; + static ulong[] dim1588KuoInit = { 1, 1, 5, 1, 3, 15, 117, 73, 321, 245, 537, 2689, 4883, 5993, 0 }; + static ulong[] dim1589KuoInit = { 1, 3, 7, 15, 31, 57, 103, 65, 89, 323, 1341, 1951, 4999, 12663, 0 }; + static ulong[] dim1590KuoInit = { 1, 3, 5, 5, 7, 23, 77, 133, 413, 157, 1281, 3779, 2081, 12201, 0 }; + static ulong[] dim1591KuoInit = { 1, 3, 7, 13, 15, 49, 119, 45, 27, 621, 2017, 1351, 7647, 8845, 0 }; + static ulong[] dim1592KuoInit = { 1, 1, 7, 15, 7, 51, 77, 181, 25, 769, 1159, 1505, 5219, 647, 0 }; + static ulong[] dim1593KuoInit = { 1, 1, 3, 5, 3, 35, 69, 43, 327, 383, 755, 253, 1137, 16133, 0 }; + static ulong[] dim1594KuoInit = { 1, 1, 7, 9, 13, 63, 69, 215, 357, 873, 477, 1243, 5475, 5335, 0 }; + static ulong[] dim1595KuoInit = { 1, 3, 1, 9, 27, 13, 115, 197, 131, 651, 741, 2539, 265, 15757, 0 }; + static ulong[] dim1596KuoInit = { 1, 1, 5, 11, 13, 47, 45, 235, 103, 597, 523, 3129, 5113, 7031, 0 }; + static ulong[] dim1597KuoInit = { 1, 1, 1, 13, 31, 63, 25, 75, 343, 537, 83, 3165, 3247, 2589, 0 }; + static ulong[] dim1598KuoInit = { 1, 3, 5, 5, 11, 13, 29, 79, 233, 901, 627, 1691, 2659, 10251, 0 }; + static ulong[] dim1599KuoInit = { 1, 3, 7, 1, 11, 63, 123, 63, 441, 931, 573, 4083, 4483, 5685, 0 }; + static ulong[] dim1600KuoInit = { 1, 3, 7, 1, 23, 51, 107, 113, 233, 921, 1761, 207, 5083, 9165, 0 }; + static ulong[] dim1601KuoInit = { 1, 3, 3, 15, 13, 23, 5, 151, 487, 157, 23, 3967, 6241, 487, 0 }; + static ulong[] dim1602KuoInit = { 1, 1, 7, 1, 7, 39, 95, 185, 379, 225, 1685, 513, 2463, 11033, 0 }; + static ulong[] dim1603KuoInit = { 1, 1, 5, 11, 19, 43, 55, 69, 433, 933, 811, 3717, 5555, 15391, 0 }; + static ulong[] dim1604KuoInit = { 1, 1, 7, 7, 21, 17, 19, 149, 185, 475, 1817, 913, 4463, 12837, 0 }; + static ulong[] dim1605KuoInit = { 1, 1, 7, 5, 27, 63, 5, 131, 217, 271, 889, 3905, 2881, 419, 0 }; + static ulong[] dim1606KuoInit = { 1, 3, 7, 11, 5, 55, 103, 135, 59, 775, 1105, 2017, 493, 12747, 0 }; + static ulong[] dim1607KuoInit = { 1, 1, 3, 5, 9, 25, 65, 9, 61, 709, 1925, 1769, 3273, 1627, 0 }; + static ulong[] dim1608KuoInit = { 1, 3, 1, 11, 7, 35, 37, 223, 105, 55, 293, 2103, 7531, 2795, 0 }; + static ulong[] dim1609KuoInit = { 1, 3, 7, 13, 17, 23, 35, 163, 177, 797, 1539, 3843, 6761, 11817, 0 }; + static ulong[] dim1610KuoInit = { 1, 1, 3, 15, 11, 19, 55, 161, 33, 701, 601, 1055, 4949, 10741, 0 }; + static ulong[] dim1611KuoInit = { 1, 1, 7, 3, 11, 45, 71, 199, 233, 917, 1447, 3651, 6021, 4745, 0 }; + static ulong[] dim1612KuoInit = { 1, 1, 3, 11, 21, 17, 39, 141, 17, 827, 355, 3337, 6897, 9005, 0 }; + static ulong[] dim1613KuoInit = { 1, 3, 3, 1, 11, 61, 67, 103, 377, 351, 1863, 207, 7333, 4481, 0 }; + static ulong[] dim1614KuoInit = { 1, 1, 1, 1, 7, 33, 103, 121, 361, 233, 195, 985, 4743, 8715, 0 }; + static ulong[] dim1615KuoInit = { 1, 3, 1, 9, 17, 47, 127, 129, 93, 217, 1049, 689, 5595, 13625, 0 }; + static ulong[] dim1616KuoInit = { 1, 1, 5, 11, 13, 33, 59, 29, 439, 447, 21, 621, 3731, 9371, 0 }; + static ulong[] dim1617KuoInit = { 1, 3, 1, 7, 15, 31, 41, 217, 275, 97, 143, 3779, 5453, 13167, 0 }; + static ulong[] dim1618KuoInit = { 1, 3, 7, 1, 11, 31, 7, 249, 193, 907, 1275, 691, 5701, 6215, 0 }; + static ulong[] dim1619KuoInit = { 1, 3, 5, 1, 11, 63, 7, 209, 227, 959, 1313, 1107, 2281, 5567, 0 }; + static ulong[] dim1620KuoInit = { 1, 3, 7, 9, 25, 5, 103, 193, 137, 345, 1953, 369, 2201, 9435, 0 }; + static ulong[] dim1621KuoInit = { 1, 1, 3, 1, 5, 19, 11, 191, 101, 861, 1665, 1439, 6889, 2467, 0 }; + static ulong[] dim1622KuoInit = { 1, 1, 7, 5, 19, 47, 13, 123, 363, 659, 1011, 2961, 2231, 11523, 0 }; + static ulong[] dim1623KuoInit = { 1, 3, 1, 1, 9, 19, 7, 1, 351, 461, 1323, 1125, 3063, 9589, 0 }; + static ulong[] dim1624KuoInit = { 1, 1, 5, 11, 1, 25, 79, 171, 503, 319, 729, 2133, 1979, 13769, 0 }; + static ulong[] dim1625KuoInit = { 1, 3, 1, 3, 17, 45, 55, 109, 143, 541, 65, 431, 2949, 11501, 0 }; + static ulong[] dim1626KuoInit = { 1, 3, 7, 7, 7, 7, 85, 81, 317, 245, 1683, 1009, 3853, 12597, 0 }; + static ulong[] dim1627KuoInit = { 1, 1, 1, 7, 9, 25, 85, 19, 59, 5, 1919, 577, 7723, 9365, 0 }; + static ulong[] dim1628KuoInit = { 1, 1, 7, 11, 13, 27, 35, 163, 209, 491, 1759, 383, 5697, 13131, 0 }; + static ulong[] dim1629KuoInit = { 1, 1, 7, 13, 19, 57, 121, 61, 143, 735, 721, 3405, 6939, 4691, 0 }; + static ulong[] dim1630KuoInit = { 1, 1, 7, 15, 21, 23, 55, 203, 145, 673, 419, 3023, 6439, 6361, 0 }; + static ulong[] dim1631KuoInit = { 1, 1, 5, 15, 5, 21, 11, 153, 223, 229, 721, 715, 7981, 15459, 0 }; + static ulong[] dim1632KuoInit = { 1, 3, 5, 7, 21, 59, 47, 15, 213, 549, 465, 1353, 2611, 11989, 0 }; + static ulong[] dim1633KuoInit = { 1, 3, 5, 7, 13, 51, 65, 11, 295, 63, 1887, 3347, 3061, 2219, 0 }; + static ulong[] dim1634KuoInit = { 1, 1, 5, 3, 29, 29, 83, 175, 507, 341, 2031, 3737, 1741, 7615, 0 }; + static ulong[] dim1635KuoInit = { 1, 3, 7, 13, 11, 55, 59, 213, 197, 851, 1723, 2805, 2461, 8071, 0 }; + static ulong[] dim1636KuoInit = { 1, 1, 3, 15, 5, 37, 55, 237, 319, 345, 1677, 1791, 5063, 4301, 0 }; + static ulong[] dim1637KuoInit = { 1, 3, 1, 11, 25, 13, 87, 85, 293, 97, 557, 3583, 7077, 6433, 0 }; + static ulong[] dim1638KuoInit = { 1, 3, 3, 1, 31, 9, 63, 29, 193, 351, 1071, 3587, 4695, 1771, 0 }; + static ulong[] dim1639KuoInit = { 1, 3, 7, 11, 11, 3, 45, 119, 215, 367, 677, 3405, 7177, 14607, 0 }; + static ulong[] dim1640KuoInit = { 1, 3, 7, 3, 3, 23, 33, 33, 223, 209, 1033, 3167, 4189, 2195, 0 }; + static ulong[] dim1641KuoInit = { 1, 1, 5, 1, 3, 53, 21, 151, 475, 987, 1671, 393, 7783, 2561, 0 }; + static ulong[] dim1642KuoInit = { 1, 3, 7, 13, 15, 5, 21, 247, 225, 861, 1707, 3237, 5793, 14557, 0 }; + static ulong[] dim1643KuoInit = { 1, 3, 5, 9, 13, 3, 37, 49, 119, 33, 805, 681, 7591, 1707, 0 }; + static ulong[] dim1644KuoInit = { 1, 1, 3, 15, 27, 55, 99, 17, 361, 773, 1415, 3547, 5427, 4579, 0 }; + static ulong[] dim1645KuoInit = { 1, 3, 5, 9, 17, 55, 89, 111, 189, 719, 1691, 1565, 941, 15481, 0 }; + static ulong[] dim1646KuoInit = { 1, 1, 1, 11, 17, 3, 77, 57, 71, 739, 869, 165, 6411, 1565, 0 }; + static ulong[] dim1647KuoInit = { 1, 3, 3, 11, 31, 47, 87, 105, 241, 999, 245, 3695, 5151, 9087, 0 }; + static ulong[] dim1648KuoInit = { 1, 3, 1, 15, 27, 59, 15, 45, 413, 291, 87, 1735, 779, 5977, 0 }; + static ulong[] dim1649KuoInit = { 1, 3, 7, 1, 9, 19, 7, 183, 133, 833, 1347, 3559, 7745, 11071, 0 }; + static ulong[] dim1650KuoInit = { 1, 1, 3, 13, 23, 59, 13, 227, 407, 661, 217, 299, 6033, 14519, 0 }; + static ulong[] dim1651KuoInit = { 1, 1, 5, 5, 27, 33, 105, 15, 141, 555, 397, 3287, 5859, 9553, 0 }; + static ulong[] dim1652KuoInit = { 1, 3, 3, 9, 27, 59, 11, 47, 379, 275, 889, 3069, 4135, 15735, 0 }; + static ulong[] dim1653KuoInit = { 1, 1, 5, 13, 27, 47, 107, 165, 487, 463, 425, 3949, 3213, 4161, 0 }; + static ulong[] dim1654KuoInit = { 1, 3, 5, 7, 27, 55, 17, 3, 159, 181, 393, 2441, 2531, 895, 0 }; + static ulong[] dim1655KuoInit = { 1, 3, 7, 7, 31, 3, 95, 81, 181, 367, 1689, 2351, 193, 7165, 0 }; + static ulong[] dim1656KuoInit = { 1, 3, 7, 15, 1, 17, 103, 181, 29, 851, 15, 1447, 435, 14059, 0 }; + static ulong[] dim1657KuoInit = { 1, 1, 1, 15, 21, 31, 83, 41, 237, 437, 509, 3757, 5609, 15859, 0 }; + static ulong[] dim1658KuoInit = { 1, 1, 7, 15, 5, 35, 101, 37, 245, 487, 449, 2089, 27, 13667, 0 }; + static ulong[] dim1659KuoInit = { 1, 1, 7, 15, 29, 49, 89, 161, 271, 455, 1599, 3843, 1673, 3683, 0 }; + static ulong[] dim1660KuoInit = { 1, 1, 7, 1, 1, 25, 37, 211, 369, 207, 243, 2113, 2707, 7951, 0 }; + static ulong[] dim1661KuoInit = { 1, 1, 7, 5, 19, 21, 25, 161, 97, 505, 273, 1443, 4461, 1407, 0 }; + static ulong[] dim1662KuoInit = { 1, 1, 5, 15, 17, 57, 115, 175, 511, 389, 1333, 2459, 5561, 4409, 0 }; + static ulong[] dim1663KuoInit = { 1, 1, 5, 9, 29, 45, 45, 121, 159, 51, 865, 531, 1387, 3517, 0 }; + static ulong[] dim1664KuoInit = { 1, 3, 5, 15, 25, 17, 59, 161, 193, 495, 611, 1009, 5035, 15325, 0 }; + static ulong[] dim1665KuoInit = { 1, 1, 1, 7, 7, 53, 99, 241, 305, 989, 175, 2841, 2891, 4975, 0 }; + static ulong[] dim1666KuoInit = { 1, 1, 7, 1, 31, 45, 85, 251, 339, 731, 513, 2557, 3119, 15961, 0 }; + static ulong[] dim1667KuoInit = { 1, 3, 7, 15, 11, 37, 73, 93, 83, 931, 1561, 791, 3263, 10789, 0 }; + static ulong[] dim1668KuoInit = { 1, 3, 1, 11, 27, 25, 29, 71, 199, 673, 173, 2267, 1277, 4373, 0 }; + static ulong[] dim1669KuoInit = { 1, 1, 5, 5, 7, 19, 79, 143, 63, 139, 977, 845, 5125, 5635, 0 }; + static ulong[] dim1670KuoInit = { 1, 1, 3, 15, 3, 27, 117, 219, 393, 457, 1001, 1235, 6409, 10883, 0 }; + static ulong[] dim1671KuoInit = { 1, 1, 3, 3, 19, 31, 61, 225, 391, 719, 1919, 1843, 4883, 10499, 0 }; + static ulong[] dim1672KuoInit = { 1, 3, 1, 3, 13, 63, 73, 103, 15, 777, 1019, 2677, 7317, 4349, 0 }; + static ulong[] dim1673KuoInit = { 1, 3, 5, 15, 5, 7, 31, 33, 237, 1021, 2045, 2283, 7045, 13829, 0 }; + static ulong[] dim1674KuoInit = { 1, 1, 3, 13, 11, 43, 47, 239, 5, 293, 2015, 3613, 1551, 3203, 0 }; + static ulong[] dim1675KuoInit = { 1, 3, 1, 11, 11, 11, 67, 201, 287, 161, 193, 1815, 1493, 2863, 0 }; + static ulong[] dim1676KuoInit = { 1, 3, 5, 13, 11, 31, 119, 57, 305, 1009, 915, 2855, 3595, 11653, 0 }; + static ulong[] dim1677KuoInit = { 1, 1, 1, 9, 17, 7, 59, 27, 189, 227, 763, 2843, 7335, 13559, 0 }; + static ulong[] dim1678KuoInit = { 1, 1, 5, 13, 3, 1, 17, 129, 83, 763, 443, 895, 1573, 7343, 0 }; + static ulong[] dim1679KuoInit = { 1, 3, 7, 3, 5, 43, 31, 95, 503, 815, 1725, 2319, 2323, 12543, 0 }; + static ulong[] dim1680KuoInit = { 1, 1, 1, 9, 29, 27, 103, 43, 39, 289, 277, 453, 4297, 1009, 0 }; + static ulong[] dim1681KuoInit = { 1, 1, 7, 5, 31, 61, 105, 79, 259, 141, 49, 925, 2793, 13247, 0 }; + static ulong[] dim1682KuoInit = { 1, 1, 1, 5, 15, 23, 59, 55, 497, 561, 343, 3633, 2097, 2035, 0 }; + static ulong[] dim1683KuoInit = { 1, 1, 3, 13, 17, 23, 13, 23, 15, 519, 105, 3719, 3639, 6387, 0 }; + static ulong[] dim1684KuoInit = { 1, 1, 1, 11, 1, 43, 97, 73, 295, 841, 1033, 11, 3027, 4073, 0 }; + static ulong[] dim1685KuoInit = { 1, 3, 1, 3, 21, 15, 67, 95, 425, 979, 1641, 3059, 4195, 14291, 0 }; + static ulong[] dim1686KuoInit = { 1, 3, 5, 3, 9, 23, 83, 203, 479, 999, 1469, 2227, 7995, 4053, 0 }; + static ulong[] dim1687KuoInit = { 1, 1, 5, 7, 1, 13, 17, 191, 297, 397, 329, 1551, 6885, 2413, 0 }; + static ulong[] dim1688KuoInit = { 1, 1, 7, 13, 31, 21, 123, 59, 79, 647, 475, 347, 667, 9871, 0 }; + static ulong[] dim1689KuoInit = { 1, 1, 7, 15, 25, 43, 35, 117, 323, 805, 1543, 2631, 2919, 1377, 0 }; + static ulong[] dim1690KuoInit = { 1, 1, 3, 11, 17, 55, 45, 213, 507, 641, 1947, 2439, 4749, 6865, 0 }; + static ulong[] dim1691KuoInit = { 1, 3, 7, 5, 13, 31, 51, 31, 167, 431, 1999, 1041, 3613, 16289, 0 }; + static ulong[] dim1692KuoInit = { 1, 3, 7, 9, 1, 15, 19, 191, 181, 247, 11, 2305, 5451, 1719, 0 }; + static ulong[] dim1693KuoInit = { 1, 3, 1, 11, 25, 39, 13, 123, 93, 527, 1359, 1985, 6789, 2045, 0 }; + static ulong[] dim1694KuoInit = { 1, 1, 1, 7, 25, 57, 113, 91, 311, 661, 1461, 2801, 5281, 13423, 0 }; + static ulong[] dim1695KuoInit = { 1, 1, 1, 11, 31, 9, 119, 55, 91, 965, 1973, 2901, 1147, 9341, 0 }; + static ulong[] dim1696KuoInit = { 1, 1, 7, 15, 9, 59, 83, 21, 49, 921, 749, 1249, 3577, 14341, 0 }; + static ulong[] dim1697KuoInit = { 1, 3, 5, 13, 25, 63, 65, 135, 337, 743, 1669, 2519, 341, 16285, 0 }; + static ulong[] dim1698KuoInit = { 1, 3, 3, 7, 23, 9, 97, 205, 87, 289, 1195, 2843, 7419, 4183, 0 }; + static ulong[] dim1699KuoInit = { 1, 3, 1, 9, 3, 33, 117, 243, 161, 977, 109, 3333, 4639, 2299, 0 }; + static ulong[] dim1700KuoInit = { 1, 1, 3, 7, 1, 53, 79, 73, 71, 953, 349, 2517, 6281, 2625, 0 }; + static ulong[] dim1701KuoInit = { 1, 1, 5, 9, 21, 59, 31, 253, 265, 403, 603, 2185, 7277, 6057, 0 }; + static ulong[] dim1702KuoInit = { 1, 1, 1, 13, 27, 35, 63, 109, 483, 205, 1245, 2599, 1697, 11381, 0 }; + static ulong[] dim1703KuoInit = { 1, 1, 7, 15, 25, 29, 107, 205, 411, 627, 745, 1585, 1175, 3077, 0 }; + static ulong[] dim1704KuoInit = { 1, 3, 5, 3, 25, 15, 121, 97, 283, 809, 753, 2577, 1099, 12155, 0 }; + static ulong[] dim1705KuoInit = { 1, 1, 7, 15, 29, 21, 55, 53, 101, 69, 657, 2727, 931, 4873, 0 }; + static ulong[] dim1706KuoInit = { 1, 3, 7, 15, 5, 57, 9, 11, 269, 261, 1681, 1025, 4001, 16111, 0 }; + static ulong[] dim1707KuoInit = { 1, 1, 3, 7, 9, 51, 29, 77, 313, 199, 1305, 2665, 5971, 7525, 0 }; + static ulong[] dim1708KuoInit = { 1, 1, 3, 15, 3, 29, 99, 255, 331, 925, 1973, 3825, 3549, 8537, 0 }; + static ulong[] dim1709KuoInit = { 1, 1, 3, 1, 27, 33, 19, 225, 209, 895, 47, 4063, 1873, 15631, 0 }; + static ulong[] dim1710KuoInit = { 1, 3, 1, 9, 11, 57, 121, 205, 89, 565, 1387, 1119, 7375, 6153, 0 }; + static ulong[] dim1711KuoInit = { 1, 1, 3, 15, 1, 27, 9, 177, 443, 437, 1487, 2119, 5299, 16251, 0 }; + static ulong[] dim1712KuoInit = { 1, 3, 7, 5, 17, 33, 79, 153, 327, 719, 1587, 407, 1137, 9607, 0 }; + static ulong[] dim1713KuoInit = { 1, 1, 3, 15, 7, 31, 109, 251, 501, 553, 785, 3047, 8141, 6305, 0 }; + static ulong[] dim1714KuoInit = { 1, 1, 3, 9, 11, 63, 65, 135, 257, 313, 191, 1073, 6821, 10629, 0 }; + static ulong[] dim1715KuoInit = { 1, 1, 7, 1, 19, 55, 7, 69, 503, 131, 1133, 3325, 347, 9255, 0 }; + static ulong[] dim1716KuoInit = { 1, 3, 5, 3, 11, 55, 115, 171, 261, 581, 1169, 3609, 307, 14055, 0 }; + static ulong[] dim1717KuoInit = { 1, 3, 7, 15, 29, 3, 33, 229, 431, 969, 281, 1617, 3685, 13583, 0 }; + static ulong[] dim1718KuoInit = { 1, 1, 7, 11, 9, 23, 5, 147, 305, 651, 1419, 3225, 7029, 15331, 0 }; + static ulong[] dim1719KuoInit = { 1, 3, 7, 15, 23, 61, 111, 221, 145, 809, 1127, 2287, 6023, 6103, 0 }; + static ulong[] dim1720KuoInit = { 1, 3, 1, 7, 1, 49, 93, 251, 239, 617, 401, 3419, 8123, 4855, 0 }; + static ulong[] dim1721KuoInit = { 1, 3, 5, 5, 15, 9, 69, 5, 509, 83, 405, 3451, 4401, 3321, 0 }; + static ulong[] dim1722KuoInit = { 1, 1, 3, 9, 29, 39, 53, 155, 73, 207, 499, 3179, 6099, 1377, 0 }; + static ulong[] dim1723KuoInit = { 1, 1, 1, 11, 9, 43, 101, 211, 439, 865, 621, 3271, 4699, 5329, 0 }; + static ulong[] dim1724KuoInit = { 1, 3, 5, 9, 21, 59, 105, 89, 5, 493, 227, 1177, 6829, 8659, 0 }; + static ulong[] dim1725KuoInit = { 1, 1, 1, 3, 27, 19, 49, 209, 337, 961, 93, 81, 4607, 13579, 0 }; + static ulong[] dim1726KuoInit = { 1, 3, 7, 1, 31, 53, 77, 213, 3, 555, 1409, 3917, 23, 7837, 0 }; + static ulong[] dim1727KuoInit = { 1, 3, 1, 1, 21, 37, 121, 17, 295, 367, 1105, 3053, 1453, 8869, 0 }; + static ulong[] dim1728KuoInit = { 1, 3, 5, 5, 31, 23, 13, 145, 459, 609, 77, 197, 4457, 5145, 0 }; + static ulong[] dim1729KuoInit = { 1, 1, 3, 7, 27, 23, 83, 165, 25, 491, 1487, 2335, 7019, 499, 0 }; + static ulong[] dim1730KuoInit = { 1, 1, 7, 15, 29, 53, 87, 47, 21, 233, 253, 2529, 1651, 16091, 0 }; + static ulong[] dim1731KuoInit = { 1, 3, 5, 11, 7, 55, 99, 193, 395, 63, 817, 2109, 1167, 5739, 0 }; + static ulong[] dim1732KuoInit = { 1, 1, 7, 15, 13, 21, 61, 31, 45, 723, 103, 1347, 4259, 13185, 0 }; + static ulong[] dim1733KuoInit = { 1, 1, 5, 9, 7, 51, 43, 21, 411, 887, 1303, 3389, 6653, 9265, 0 }; + static ulong[] dim1734KuoInit = { 1, 1, 3, 7, 3, 7, 43, 197, 151, 977, 717, 2293, 3135, 5223, 0 }; + static ulong[] dim1735KuoInit = { 1, 1, 1, 1, 23, 49, 23, 105, 279, 401, 1309, 3485, 4305, 13181, 0 }; + static ulong[] dim1736KuoInit = { 1, 3, 1, 15, 23, 15, 89, 171, 237, 513, 369, 3731, 4753, 4655, 0 }; + static ulong[] dim1737KuoInit = { 1, 1, 7, 11, 3, 35, 49, 211, 353, 843, 705, 2237, 7843, 9009, 0 }; + static ulong[] dim1738KuoInit = { 1, 3, 3, 9, 29, 25, 63, 29, 369, 777, 477, 547, 6575, 13769, 0 }; + static ulong[] dim1739KuoInit = { 1, 1, 3, 1, 3, 5, 101, 107, 11, 817, 413, 3241, 6275, 4035, 0 }; + static ulong[] dim1740KuoInit = { 1, 1, 1, 3, 21, 17, 25, 113, 183, 159, 307, 447, 7881, 7399, 0 }; + static ulong[] dim1741KuoInit = { 1, 1, 7, 15, 7, 45, 39, 39, 111, 191, 151, 267, 7133, 5557, 0 }; + static ulong[] dim1742KuoInit = { 1, 3, 7, 5, 27, 39, 29, 59, 141, 835, 1307, 1007, 2101, 7675, 0 }; + static ulong[] dim1743KuoInit = { 1, 3, 1, 11, 9, 15, 65, 47, 371, 385, 683, 3495, 711, 3963, 0 }; + static ulong[] dim1744KuoInit = { 1, 1, 7, 3, 5, 59, 81, 9, 23, 885, 291, 2349, 5495, 12985, 0 }; + static ulong[] dim1745KuoInit = { 1, 3, 5, 1, 21, 49, 99, 101, 447, 289, 659, 1061, 5771, 7591, 0 }; + static ulong[] dim1746KuoInit = { 1, 3, 5, 7, 5, 11, 13, 255, 7, 775, 1919, 1965, 7069, 10379, 0 }; + static ulong[] dim1747KuoInit = { 1, 1, 7, 15, 29, 23, 61, 183, 117, 817, 113, 1665, 2349, 305, 0 }; + static ulong[] dim1748KuoInit = { 1, 3, 7, 13, 25, 9, 97, 161, 361, 33, 1781, 3717, 6319, 13199, 0 }; + static ulong[] dim1749KuoInit = { 1, 3, 5, 13, 21, 63, 85, 225, 447, 169, 1601, 2359, 8087, 2609, 0 }; + static ulong[] dim1750KuoInit = { 1, 1, 3, 9, 1, 11, 1, 173, 345, 217, 1131, 493, 4613, 9223, 0 }; + static ulong[] dim1751KuoInit = { 1, 3, 7, 3, 5, 51, 55, 235, 129, 451, 1191, 2065, 6781, 9135, 0 }; + static ulong[] dim1752KuoInit = { 1, 3, 7, 1, 27, 41, 123, 49, 495, 999, 1731, 1597, 7471, 1129, 0 }; + static ulong[] dim1753KuoInit = { 1, 1, 5, 3, 13, 3, 123, 83, 199, 325, 1521, 1023, 2703, 10915, 0 }; + static ulong[] dim1754KuoInit = { 1, 1, 3, 1, 15, 19, 45, 223, 17, 643, 661, 633, 6475, 10153, 0 }; + static ulong[] dim1755KuoInit = { 1, 1, 7, 9, 17, 21, 101, 137, 39, 975, 1003, 1419, 353, 11971, 0 }; + static ulong[] dim1756KuoInit = { 1, 3, 5, 3, 11, 37, 75, 87, 49, 535, 801, 1689, 8125, 12419, 0 }; + static ulong[] dim1757KuoInit = { 1, 3, 3, 3, 19, 11, 99, 97, 285, 641, 1485, 257, 5417, 8669, 0 }; + static ulong[] dim1758KuoInit = { 1, 1, 1, 1, 21, 53, 19, 61, 223, 917, 931, 1779, 5859, 3111, 0 }; + static ulong[] dim1759KuoInit = { 1, 3, 1, 13, 25, 17, 55, 227, 61, 953, 255, 3939, 2523, 2119, 0 }; + static ulong[] dim1760KuoInit = { 1, 1, 7, 11, 23, 43, 111, 21, 263, 399, 723, 1067, 3633, 4165, 0 }; + static ulong[] dim1761KuoInit = { 1, 3, 7, 3, 31, 29, 69, 135, 105, 839, 1077, 1479, 643, 1063, 0 }; + static ulong[] dim1762KuoInit = { 1, 3, 1, 11, 23, 29, 51, 235, 287, 941, 393, 2241, 1601, 4629, 0 }; + static ulong[] dim1763KuoInit = { 1, 3, 3, 1, 1, 7, 47, 119, 369, 789, 1943, 3417, 4073, 7495, 0 }; + static ulong[] dim1764KuoInit = { 1, 1, 7, 7, 21, 37, 25, 217, 267, 275, 903, 865, 6251, 1323, 0 }; + static ulong[] dim1765KuoInit = { 1, 3, 7, 15, 13, 61, 77, 181, 479, 1003, 335, 2917, 1133, 14321, 0 }; + static ulong[] dim1766KuoInit = { 1, 1, 7, 7, 9, 53, 47, 197, 257, 823, 421, 2465, 4333, 3841, 0 }; + static ulong[] dim1767KuoInit = { 1, 3, 3, 9, 23, 17, 83, 131, 427, 25, 319, 517, 4109, 15841, 0 }; + static ulong[] dim1768KuoInit = { 1, 1, 7, 7, 7, 25, 105, 63, 117, 173, 909, 2731, 877, 1095, 0 }; + static ulong[] dim1769KuoInit = { 1, 1, 3, 9, 29, 17, 125, 45, 269, 681, 1389, 283, 7217, 15315, 0 }; + static ulong[] dim1770KuoInit = { 1, 1, 7, 3, 3, 59, 29, 177, 191, 803, 809, 131, 857, 16213, 0 }; + static ulong[] dim1771KuoInit = { 1, 1, 1, 15, 15, 21, 41, 177, 245, 543, 761, 2423, 1381, 1125, 0 }; + static ulong[] dim1772KuoInit = { 1, 3, 5, 13, 31, 5, 121, 183, 477, 143, 559, 765, 703, 12255, 0 }; + static ulong[] dim1773KuoInit = { 1, 1, 1, 15, 21, 23, 127, 227, 331, 963, 333, 2101, 2215, 10107, 0 }; + static ulong[] dim1774KuoInit = { 1, 3, 7, 3, 1, 47, 53, 189, 331, 587, 1417, 731, 4317, 11629, 0 }; + static ulong[] dim1775KuoInit = { 1, 3, 7, 13, 11, 21, 45, 109, 455, 347, 1483, 2589, 6933, 8343, 0 }; + static ulong[] dim1776KuoInit = { 1, 1, 1, 11, 5, 31, 45, 85, 253, 729, 111, 3315, 3183, 12847, 0 }; + static ulong[] dim1777KuoInit = { 1, 3, 1, 1, 25, 5, 3, 219, 263, 517, 247, 2303, 2709, 11973, 0 }; + static ulong[] dim1778KuoInit = { 1, 1, 5, 11, 21, 39, 115, 231, 5, 451, 1503, 1527, 4071, 5879, 0 }; + static ulong[] dim1779KuoInit = { 1, 3, 5, 15, 23, 31, 15, 61, 313, 83, 49, 1377, 7029, 14187, 0 }; + static ulong[] dim1780KuoInit = { 1, 3, 7, 9, 29, 7, 117, 111, 493, 159, 513, 3841, 7011, 14723, 0 }; + static ulong[] dim1781KuoInit = { 1, 1, 5, 13, 21, 15, 3, 139, 463, 1023, 1301, 243, 5105, 2259, 0 }; + static ulong[] dim1782KuoInit = { 1, 1, 7, 13, 5, 3, 119, 111, 447, 75, 1161, 1917, 345, 557, 0 }; + static ulong[] dim1783KuoInit = { 1, 1, 5, 5, 25, 21, 87, 93, 237, 921, 475, 2555, 4105, 5691, 0 }; + static ulong[] dim1784KuoInit = { 1, 1, 3, 15, 29, 51, 5, 73, 471, 421, 861, 3833, 2531, 1059, 0 }; + static ulong[] dim1785KuoInit = { 1, 3, 7, 9, 3, 11, 101, 35, 271, 981, 1661, 1629, 7321, 1335, 0 }; + static ulong[] dim1786KuoInit = { 1, 1, 5, 9, 9, 37, 9, 127, 45, 215, 611, 1193, 659, 5975, 0 }; + static ulong[] dim1787KuoInit = { 1, 1, 3, 9, 31, 31, 21, 167, 415, 513, 1917, 829, 1161, 3585, 0 }; + static ulong[] dim1788KuoInit = { 1, 1, 7, 1, 19, 23, 49, 55, 169, 351, 1389, 3251, 5001, 13445, 0 }; + static ulong[] dim1789KuoInit = { 1, 3, 1, 15, 3, 3, 113, 193, 391, 851, 681, 2961, 7239, 12837, 0 }; + static ulong[] dim1790KuoInit = { 1, 3, 5, 15, 5, 43, 71, 1, 347, 635, 1123, 3399, 2087, 8209, 0 }; + static ulong[] dim1791KuoInit = { 1, 1, 3, 15, 23, 7, 59, 115, 139, 311, 893, 2421, 405, 6541, 0 }; + static ulong[] dim1792KuoInit = { 1, 3, 3, 3, 25, 23, 127, 135, 199, 661, 7, 3279, 91, 11879, 0 }; + static ulong[] dim1793KuoInit = { 1, 1, 3, 3, 19, 37, 33, 159, 3, 425, 379, 1321, 369, 13125, 0 }; + static ulong[] dim1794KuoInit = { 1, 3, 5, 15, 7, 17, 47, 47, 167, 909, 403, 95, 7861, 231, 0 }; + static ulong[] dim1795KuoInit = { 1, 1, 5, 1, 15, 5, 69, 179, 229, 597, 1743, 467, 1859, 2059, 0 }; + static ulong[] dim1796KuoInit = { 1, 1, 7, 15, 5, 63, 109, 191, 271, 281, 907, 489, 5863, 12697, 0 }; + static ulong[] dim1797KuoInit = { 1, 1, 3, 3, 31, 1, 67, 81, 3, 755, 1839, 1481, 4691, 14549, 0 }; + static ulong[] dim1798KuoInit = { 1, 3, 3, 15, 17, 13, 59, 23, 85, 951, 1259, 363, 5479, 10705, 0 }; + static ulong[] dim1799KuoInit = { 1, 1, 3, 15, 11, 61, 111, 109, 361, 483, 1691, 1039, 3777, 14613, 0 }; + static ulong[] dim1800KuoInit = { 1, 1, 3, 5, 29, 55, 101, 55, 407, 61, 607, 829, 8011, 14021, 0 }; + static ulong[] dim1801KuoInit = { 1, 1, 1, 13, 1, 39, 29, 19, 389, 85, 313, 1123, 1303, 11535, 0 }; + static ulong[] dim1802KuoInit = { 1, 1, 1, 5, 5, 45, 47, 139, 165, 937, 1677, 2973, 501, 4387, 0 }; + static ulong[] dim1803KuoInit = { 1, 3, 5, 9, 5, 55, 89, 235, 29, 75, 1839, 801, 5753, 4409, 0 }; + static ulong[] dim1804KuoInit = { 1, 1, 3, 5, 7, 41, 7, 185, 297, 661, 1955, 2193, 6001, 12349, 0 }; + static ulong[] dim1805KuoInit = { 1, 1, 7, 15, 27, 47, 7, 7, 183, 725, 1511, 3021, 6091, 10567, 0 }; + static ulong[] dim1806KuoInit = { 1, 3, 3, 13, 21, 7, 79, 133, 307, 759, 369, 2779, 7629, 16191, 0 }; + static ulong[] dim1807KuoInit = { 1, 1, 5, 9, 5, 47, 15, 141, 293, 339, 1471, 127, 5805, 5543, 0 }; + static ulong[] dim1808KuoInit = { 1, 3, 1, 9, 31, 7, 125, 27, 511, 549, 619, 743, 3471, 8595, 0 }; + static ulong[] dim1809KuoInit = { 1, 1, 7, 5, 15, 9, 25, 35, 161, 691, 659, 909, 969, 9285, 0 }; + static ulong[] dim1810KuoInit = { 1, 1, 7, 11, 31, 17, 59, 255, 281, 7, 1075, 2561, 6883, 8193, 0 }; + static ulong[] dim1811KuoInit = { 1, 1, 7, 1, 9, 15, 83, 253, 415, 601, 417, 3999, 7513, 3663, 0 }; + static ulong[] dim1812KuoInit = { 1, 3, 5, 7, 11, 25, 109, 135, 41, 5, 697, 1703, 8175, 11369, 0 }; + static ulong[] dim1813KuoInit = { 1, 1, 7, 15, 7, 39, 1, 253, 373, 273, 857, 401, 1609, 2391, 0 }; + static ulong[] dim1814KuoInit = { 1, 1, 5, 1, 1, 61, 85, 213, 183, 695, 523, 1237, 5485, 6843, 0 }; + static ulong[] dim1815KuoInit = { 1, 1, 7, 9, 17, 41, 125, 209, 285, 823, 857, 31, 839, 10847, 0 }; + static ulong[] dim1816KuoInit = { 1, 3, 5, 9, 31, 23, 65, 75, 243, 471, 669, 539, 3949, 14913, 0 }; + static ulong[] dim1817KuoInit = { 1, 1, 7, 3, 25, 23, 109, 19, 89, 983, 193, 1433, 6401, 663, 0 }; + static ulong[] dim1818KuoInit = { 1, 3, 1, 15, 25, 9, 93, 13, 133, 561, 1343, 4049, 6221, 3137, 0 }; + static ulong[] dim1819KuoInit = { 1, 1, 3, 3, 31, 47, 105, 225, 231, 75, 187, 963, 3339, 9705, 0 }; + static ulong[] dim1820KuoInit = { 1, 3, 7, 1, 9, 31, 21, 221, 309, 791, 2011, 241, 5507, 11579, 0 }; + static ulong[] dim1821KuoInit = { 1, 3, 7, 9, 1, 19, 53, 239, 305, 151, 53, 873, 5235, 13357, 0 }; + static ulong[] dim1822KuoInit = { 1, 1, 5, 15, 13, 27, 23, 255, 75, 435, 209, 2001, 2529, 5363, 0 }; + static ulong[] dim1823KuoInit = { 1, 1, 7, 5, 25, 53, 71, 203, 259, 403, 1535, 3381, 6791, 16061, 0 }; + static ulong[] dim1824KuoInit = { 1, 3, 5, 3, 29, 5, 93, 5, 179, 813, 1569, 2875, 7855, 13863, 0 }; + static ulong[] dim1825KuoInit = { 1, 1, 3, 7, 1, 13, 97, 125, 479, 209, 1659, 2997, 3405, 9707, 0 }; + static ulong[] dim1826KuoInit = { 1, 3, 1, 9, 5, 43, 15, 29, 317, 317, 1317, 3177, 519, 8115, 0 }; + static ulong[] dim1827KuoInit = { 1, 1, 1, 5, 1, 55, 49, 145, 415, 785, 1489, 1217, 3829, 10207, 0 }; + static ulong[] dim1828KuoInit = { 1, 3, 3, 9, 17, 5, 99, 235, 277, 921, 71, 343, 2935, 12495, 0 }; + static ulong[] dim1829KuoInit = { 1, 1, 3, 15, 25, 11, 11, 69, 209, 543, 17, 1489, 8119, 3557, 0 }; + static ulong[] dim1830KuoInit = { 1, 1, 7, 9, 29, 43, 125, 87, 11, 947, 1709, 17, 3467, 3339, 0 }; + static ulong[] dim1831KuoInit = { 1, 3, 5, 15, 23, 47, 113, 185, 75, 523, 1253, 859, 6359, 15563, 0 }; + static ulong[] dim1832KuoInit = { 1, 1, 7, 11, 1, 25, 25, 23, 267, 275, 1751, 3237, 3967, 9943, 0 }; + static ulong[] dim1833KuoInit = { 1, 1, 1, 13, 7, 35, 43, 151, 489, 97, 143, 257, 771, 8181, 0 }; + static ulong[] dim1834KuoInit = { 1, 1, 3, 7, 19, 11, 17, 23, 425, 869, 525, 95, 2217, 3931, 0 }; + static ulong[] dim1835KuoInit = { 1, 3, 7, 11, 3, 19, 77, 219, 501, 23, 773, 2421, 3713, 6209, 0 }; + static ulong[] dim1836KuoInit = { 1, 1, 3, 1, 7, 1, 33, 35, 229, 329, 201, 291, 4165, 16059, 0 }; + static ulong[] dim1837KuoInit = { 1, 3, 5, 9, 17, 23, 107, 23, 3, 673, 609, 2931, 5989, 3133, 0 }; + static ulong[] dim1838KuoInit = { 1, 3, 3, 3, 17, 59, 31, 63, 111, 287, 407, 769, 2381, 2203, 0 }; + static ulong[] dim1839KuoInit = { 1, 1, 1, 15, 3, 51, 105, 57, 313, 847, 261, 2697, 749, 15419, 0 }; + static ulong[] dim1840KuoInit = { 1, 3, 1, 11, 3, 21, 65, 139, 363, 21, 1889, 1007, 6969, 3609, 0 }; + static ulong[] dim1841KuoInit = { 1, 3, 7, 15, 17, 51, 73, 121, 481, 339, 1409, 131, 2005, 11847, 0 }; + static ulong[] dim1842KuoInit = { 1, 3, 5, 3, 31, 13, 107, 253, 125, 973, 1027, 3473, 6883, 15061, 0 }; + static ulong[] dim1843KuoInit = { 1, 3, 1, 5, 25, 17, 11, 255, 209, 35, 1987, 2275, 2327, 16079, 0 }; + static ulong[] dim1844KuoInit = { 1, 3, 7, 5, 3, 1, 25, 93, 397, 467, 1895, 3199, 1861, 10943, 0 }; + static ulong[] dim1845KuoInit = { 1, 3, 7, 1, 23, 27, 13, 211, 299, 117, 1689, 457, 6335, 11921, 0 }; + static ulong[] dim1846KuoInit = { 1, 1, 5, 5, 9, 59, 49, 177, 81, 913, 429, 2705, 339, 9347, 0 }; + static ulong[] dim1847KuoInit = { 1, 3, 1, 15, 1, 61, 81, 143, 455, 311, 381, 235, 2537, 12511, 0 }; + static ulong[] dim1848KuoInit = { 1, 3, 5, 11, 7, 33, 103, 137, 377, 717, 851, 2939, 303, 11175, 0 }; + static ulong[] dim1849KuoInit = { 1, 3, 3, 13, 25, 59, 15, 43, 71, 767, 47, 3425, 7015, 14431, 0 }; + static ulong[] dim1850KuoInit = { 1, 3, 3, 9, 25, 37, 37, 39, 279, 491, 1483, 2633, 3791, 14311, 0 }; + static ulong[] dim1851KuoInit = { 1, 1, 1, 13, 29, 63, 83, 89, 339, 923, 455, 965, 7339, 16383, 0 }; + static ulong[] dim1852KuoInit = { 1, 1, 3, 1, 9, 33, 7, 63, 385, 717, 1449, 2705, 6233, 10753, 0 }; + static ulong[] dim1853KuoInit = { 1, 3, 1, 11, 15, 13, 11, 181, 271, 749, 1825, 875, 2497, 12999, 0 }; + static ulong[] dim1854KuoInit = { 1, 3, 3, 7, 13, 49, 35, 65, 467, 259, 429, 549, 5481, 11343, 0 }; + static ulong[] dim1855KuoInit = { 1, 3, 7, 15, 17, 55, 125, 217, 91, 495, 133, 1985, 4871, 3415, 0 }; + static ulong[] dim1856KuoInit = { 1, 3, 3, 13, 11, 33, 29, 53, 253, 935, 1919, 2607, 3205, 819, 0 }; + static ulong[] dim1857KuoInit = { 1, 1, 1, 3, 25, 23, 127, 151, 39, 583, 985, 715, 765, 16343, 0 }; + static ulong[] dim1858KuoInit = { 1, 3, 5, 3, 7, 21, 127, 179, 239, 353, 221, 531, 5147, 6699, 0 }; + static ulong[] dim1859KuoInit = { 1, 1, 7, 9, 7, 63, 91, 99, 495, 111, 1295, 2609, 6389, 7719, 0 }; + static ulong[] dim1860KuoInit = { 1, 3, 5, 7, 9, 27, 123, 171, 155, 683, 1209, 2081, 2823, 1007, 0 }; + static ulong[] dim1861KuoInit = { 1, 3, 3, 15, 25, 45, 91, 93, 329, 961, 1843, 2637, 4333, 8359, 0 }; + static ulong[] dim1862KuoInit = { 1, 3, 1, 5, 9, 5, 73, 221, 71, 951, 1175, 2489, 4565, 7221, 0 }; + static ulong[] dim1863KuoInit = { 1, 3, 1, 3, 31, 33, 67, 127, 427, 487, 239, 787, 1731, 11867, 0 }; + static ulong[] dim1864KuoInit = { 1, 1, 1, 9, 17, 23, 5, 201, 175, 661, 1381, 3017, 4237, 14403, 0 }; + static ulong[] dim1865KuoInit = { 1, 3, 7, 7, 31, 7, 39, 141, 299, 237, 281, 3057, 5553, 11339, 0 }; + static ulong[] dim1866KuoInit = { 1, 1, 1, 15, 25, 49, 51, 135, 363, 377, 1767, 4069, 3001, 7111, 0 }; + static ulong[] dim1867KuoInit = { 1, 3, 7, 11, 29, 7, 91, 145, 263, 581, 35, 3101, 6227, 12007, 30807, 0 }; + static ulong[] dim1868KuoInit = { 1, 1, 1, 13, 11, 41, 61, 135, 61, 501, 189, 1923, 129, 14563, 12247, 0 }; + static ulong[] dim1869KuoInit = { 1, 1, 3, 5, 17, 45, 53, 5, 199, 165, 859, 771, 4553, 14723, 17293, 0 }; + static ulong[] dim1870KuoInit = { 1, 1, 3, 15, 27, 57, 41, 3, 437, 543, 1291, 1083, 1311, 4407, 9107, 0 }; + static ulong[] dim1871KuoInit = { 1, 1, 3, 11, 19, 23, 17, 251, 267, 575, 1675, 775, 1281, 12389, 11781, 0 }; + static ulong[] dim1872KuoInit = { 1, 3, 3, 9, 19, 41, 69, 45, 113, 683, 1843, 1217, 1075, 7141, 11259, 0 }; + static ulong[] dim1873KuoInit = { 1, 3, 5, 5, 21, 45, 75, 199, 227, 717, 267, 3211, 5893, 6559, 16445, 0 }; + static ulong[] dim1874KuoInit = { 1, 1, 3, 15, 25, 19, 13, 3, 477, 511, 1607, 61, 5937, 6471, 4561, 0 }; + static ulong[] dim1875KuoInit = { 1, 1, 7, 9, 25, 9, 59, 209, 181, 671, 1473, 1863, 6835, 5915, 21573, 0 }; + static ulong[] dim1876KuoInit = { 1, 1, 7, 5, 31, 43, 91, 191, 505, 979, 1431, 1347, 1445, 9759, 31653, 0 }; + static ulong[] dim1877KuoInit = { 1, 1, 5, 3, 11, 63, 35, 1, 313, 863, 577, 3039, 5205, 5089, 20009, 0 }; + static ulong[] dim1878KuoInit = { 1, 3, 3, 7, 1, 27, 79, 21, 179, 187, 917, 1831, 1737, 2879, 5801, 0 }; + static ulong[] dim1879KuoInit = { 1, 1, 1, 3, 19, 51, 77, 201, 499, 345, 617, 33, 543, 6925, 5945, 0 }; + static ulong[] dim1880KuoInit = { 1, 3, 1, 1, 19, 49, 67, 51, 181, 1015, 1159, 2109, 879, 10257, 23207, 0 }; + static ulong[] dim1881KuoInit = { 1, 1, 7, 7, 19, 29, 7, 111, 365, 373, 1309, 3633, 5951, 2597, 27947, 0 }; + static ulong[] dim1882KuoInit = { 1, 3, 5, 13, 21, 27, 85, 71, 149, 665, 1499, 4025, 3939, 8947, 15811, 0 }; + static ulong[] dim1883KuoInit = { 1, 3, 7, 5, 25, 47, 77, 99, 105, 739, 1077, 3145, 7859, 1925, 16765, 0 }; + static ulong[] dim1884KuoInit = { 1, 1, 3, 11, 25, 9, 113, 105, 309, 397, 1687, 1171, 455, 3183, 12487, 0 }; + static ulong[] dim1885KuoInit = { 1, 1, 7, 15, 7, 9, 51, 239, 469, 415, 1895, 89, 4243, 967, 7113, 0 }; + static ulong[] dim1886KuoInit = { 1, 1, 5, 1, 23, 41, 39, 247, 115, 541, 1461, 2907, 2175, 3133, 3171, 0 }; + static ulong[] dim1887KuoInit = { 1, 3, 7, 11, 7, 53, 43, 187, 213, 549, 947, 3695, 3931, 699, 21299, 0 }; + static ulong[] dim1888KuoInit = { 1, 1, 1, 7, 15, 9, 9, 3, 175, 231, 1529, 337, 5333, 6945, 1359, 0 }; + static ulong[] dim1889KuoInit = { 1, 1, 3, 3, 13, 25, 123, 231, 389, 351, 1695, 2959, 1037, 2103, 327, 0 }; + static ulong[] dim1890KuoInit = { 1, 3, 5, 11, 9, 31, 19, 149, 1, 477, 1819, 3487, 3299, 8835, 10351, 0 }; + static ulong[] dim1891KuoInit = { 1, 1, 5, 7, 9, 37, 123, 93, 267, 481, 901, 3927, 7295, 13251, 22551, 0 }; + static ulong[] dim1892KuoInit = { 1, 1, 7, 11, 21, 13, 127, 173, 459, 169, 1511, 1649, 5431, 8637, 3601, 0 }; + static ulong[] dim1893KuoInit = { 1, 1, 1, 9, 29, 3, 101, 135, 159, 295, 1767, 3089, 3753, 4969, 21523, 0 }; + static ulong[] dim1894KuoInit = { 1, 3, 5, 3, 3, 9, 45, 143, 301, 307, 191, 3337, 6721, 12095, 7017, 0 }; + static ulong[] dim1895KuoInit = { 1, 3, 7, 13, 17, 25, 55, 37, 379, 725, 1079, 311, 2853, 15097, 31857, 0 }; + static ulong[] dim1896KuoInit = { 1, 3, 1, 13, 19, 57, 39, 99, 39, 283, 425, 2447, 2077, 815, 7639, 0 }; + static ulong[] dim1897KuoInit = { 1, 3, 3, 15, 11, 5, 17, 83, 231, 535, 35, 2773, 4127, 9951, 5773, 0 }; + static ulong[] dim1898KuoInit = { 1, 3, 3, 15, 7, 47, 87, 119, 291, 523, 1325, 1757, 2377, 6481, 7901, 0 }; + static ulong[] dim1899KuoInit = { 1, 3, 7, 15, 25, 21, 29, 87, 241, 241, 1273, 2813, 2011, 8549, 7253, 0 }; + static ulong[] dim1900KuoInit = { 1, 1, 1, 7, 19, 35, 119, 227, 483, 1015, 685, 1149, 4823, 4113, 7169, 0 }; + static ulong[] dim1901KuoInit = { 1, 3, 3, 5, 11, 59, 125, 99, 255, 149, 829, 2869, 7927, 6779, 31949, 0 }; + static ulong[] dim1902KuoInit = { 1, 3, 7, 3, 3, 49, 21, 111, 219, 33, 91, 1585, 303, 14931, 11777, 0 }; + static ulong[] dim1903KuoInit = { 1, 3, 3, 11, 3, 47, 27, 227, 477, 891, 1281, 1927, 7325, 14075, 26633, 0 }; + static ulong[] dim1904KuoInit = { 1, 1, 5, 5, 5, 29, 25, 23, 223, 65, 1511, 2563, 7825, 7339, 32095, 0 }; + static ulong[] dim1905KuoInit = { 1, 1, 5, 7, 3, 29, 49, 83, 317, 513, 755, 1339, 4829, 6213, 29055, 0 }; + static ulong[] dim1906KuoInit = { 1, 1, 3, 5, 23, 23, 97, 27, 379, 183, 933, 3431, 797, 9655, 32061, 0 }; + static ulong[] dim1907KuoInit = { 1, 1, 7, 1, 29, 61, 31, 75, 331, 487, 229, 2319, 1385, 14697, 17081, 0 }; + static ulong[] dim1908KuoInit = { 1, 1, 1, 5, 19, 1, 43, 27, 433, 751, 1283, 559, 7941, 7385, 13809, 0 }; + static ulong[] dim1909KuoInit = { 1, 1, 3, 15, 19, 37, 97, 219, 217, 39, 1969, 1909, 2895, 749, 27607, 0 }; + static ulong[] dim1910KuoInit = { 1, 3, 5, 9, 25, 17, 79, 213, 321, 73, 533, 3773, 6989, 10183, 20179, 0 }; + static ulong[] dim1911KuoInit = { 1, 1, 5, 7, 15, 51, 71, 161, 107, 531, 461, 15, 2887, 13271, 24273, 0 }; + static ulong[] dim1912KuoInit = { 1, 3, 5, 7, 29, 21, 119, 53, 207, 471, 987, 1771, 7259, 4377, 15405, 0 }; + static ulong[] dim1913KuoInit = { 1, 1, 3, 11, 3, 5, 7, 189, 231, 181, 751, 1, 225, 12575, 4853, 0 }; + static ulong[] dim1914KuoInit = { 1, 1, 1, 13, 1, 51, 35, 239, 145, 827, 1169, 3671, 7585, 4593, 4433, 0 }; + static ulong[] dim1915KuoInit = { 1, 1, 3, 13, 15, 55, 43, 157, 13, 517, 1669, 25, 1175, 3971, 11165, 0 }; + static ulong[] dim1916KuoInit = { 1, 3, 7, 15, 15, 37, 33, 155, 243, 375, 947, 1869, 2693, 5191, 9865, 0 }; + static ulong[] dim1917KuoInit = { 1, 3, 7, 1, 15, 57, 73, 15, 389, 341, 207, 3249, 439, 5975, 23461, 0 }; + static ulong[] dim1918KuoInit = { 1, 3, 3, 11, 17, 3, 35, 245, 349, 915, 1221, 1495, 5525, 10223, 29109, 0 }; + static ulong[] dim1919KuoInit = { 1, 1, 7, 9, 19, 17, 39, 49, 159, 163, 419, 1117, 7947, 7177, 10945, 0 }; + static ulong[] dim1920KuoInit = { 1, 3, 7, 5, 23, 35, 31, 33, 325, 565, 1951, 745, 6867, 13121, 25831, 0 }; + static ulong[] dim1921KuoInit = { 1, 3, 7, 7, 27, 11, 89, 191, 233, 57, 1621, 2167, 7155, 15613, 14111, 0 }; + static ulong[] dim1922KuoInit = { 1, 1, 7, 15, 31, 49, 3, 245, 51, 173, 1809, 379, 8085, 5125, 10279, 0 }; + static ulong[] dim1923KuoInit = { 1, 1, 7, 7, 29, 59, 37, 197, 377, 5, 1851, 3685, 3537, 1897, 24257, 0 }; + static ulong[] dim1924KuoInit = { 1, 1, 1, 11, 13, 9, 11, 19, 377, 435, 869, 497, 8181, 3411, 4415, 0 }; + static ulong[] dim1925KuoInit = { 1, 1, 5, 7, 7, 21, 51, 115, 435, 9, 1099, 987, 1633, 7689, 19131, 0 }; + static ulong[] dim1926KuoInit = { 1, 3, 3, 5, 17, 59, 93, 131, 17, 637, 211, 2759, 3059, 4691, 10225, 0 }; + static ulong[] dim1927KuoInit = { 1, 3, 3, 13, 5, 35, 55, 49, 425, 395, 615, 1505, 1477, 6689, 28435, 0 }; + static ulong[] dim1928KuoInit = { 1, 1, 3, 5, 27, 1, 43, 53, 375, 657, 1307, 1869, 415, 1143, 16961, 0 }; + static ulong[] dim1929KuoInit = { 1, 1, 7, 5, 13, 27, 111, 113, 459, 149, 139, 79, 5031, 15165, 443, 0 }; + static ulong[] dim1930KuoInit = { 1, 3, 1, 11, 9, 45, 35, 217, 259, 523, 601, 499, 7683, 1447, 5267, 0 }; + static ulong[] dim1931KuoInit = { 1, 3, 1, 7, 3, 51, 101, 191, 469, 435, 883, 343, 1897, 5245, 1037, 0 }; + static ulong[] dim1932KuoInit = { 1, 3, 5, 1, 19, 21, 109, 105, 363, 409, 1651, 3739, 339, 12915, 31603, 0 }; + static ulong[] dim1933KuoInit = { 1, 3, 5, 13, 9, 7, 65, 193, 447, 829, 1123, 2431, 3357, 6687, 26903, 0 }; + static ulong[] dim1934KuoInit = { 1, 3, 5, 5, 11, 9, 69, 147, 331, 657, 1589, 3417, 5805, 8673, 2517, 0 }; + static ulong[] dim1935KuoInit = { 1, 3, 1, 5, 23, 45, 59, 53, 285, 711, 1447, 927, 8005, 3513, 18147, 0 }; + static ulong[] dim1936KuoInit = { 1, 3, 5, 9, 9, 15, 17, 85, 165, 923, 915, 3263, 1103, 9445, 15371, 0 }; + static ulong[] dim1937KuoInit = { 1, 1, 5, 13, 13, 13, 33, 249, 501, 495, 1771, 1305, 2821, 9405, 7193, 0 }; + static ulong[] dim1938KuoInit = { 1, 1, 3, 5, 9, 11, 23, 5, 359, 977, 613, 2163, 4511, 7901, 1609, 0 }; + static ulong[] dim1939KuoInit = { 1, 1, 3, 5, 29, 29, 73, 69, 155, 863, 243, 2705, 4005, 11249, 13983, 0 }; + static ulong[] dim1940KuoInit = { 1, 3, 7, 9, 9, 15, 75, 171, 213, 931, 1613, 3801, 4617, 3929, 24787, 0 }; + static ulong[] dim1941KuoInit = { 1, 3, 5, 11, 19, 35, 107, 251, 121, 455, 2027, 2323, 4297, 7949, 12043, 0 }; + static ulong[] dim1942KuoInit = { 1, 3, 3, 7, 3, 59, 13, 151, 161, 615, 1427, 2469, 3211, 6601, 26829, 0 }; + static ulong[] dim1943KuoInit = { 1, 1, 1, 9, 31, 1, 41, 247, 225, 65, 1751, 3557, 935, 16115, 3009, 0 }; + static ulong[] dim1944KuoInit = { 1, 1, 7, 1, 31, 3, 31, 39, 279, 213, 1141, 371, 7529, 12485, 6585, 0 }; + static ulong[] dim1945KuoInit = { 1, 3, 3, 3, 13, 31, 121, 185, 171, 991, 147, 1913, 475, 15155, 2427, 0 }; + static ulong[] dim1946KuoInit = { 1, 3, 5, 5, 7, 13, 59, 127, 175, 717, 759, 3949, 4229, 2091, 20267, 0 }; + static ulong[] dim1947KuoInit = { 1, 3, 1, 15, 21, 33, 45, 57, 1, 463, 1217, 1499, 269, 11159, 17175, 0 }; + static ulong[] dim1948KuoInit = { 1, 1, 1, 9, 21, 29, 51, 63, 299, 775, 239, 575, 1033, 3627, 12017, 0 }; + static ulong[] dim1949KuoInit = { 1, 3, 3, 3, 23, 35, 63, 197, 341, 775, 675, 1835, 4155, 7439, 1797, 0 }; + static ulong[] dim1950KuoInit = { 1, 3, 7, 5, 23, 57, 71, 181, 1, 95, 337, 1971, 5721, 15013, 3387, 0 }; + static ulong[] dim1951KuoInit = { 1, 3, 1, 5, 31, 21, 33, 203, 463, 3, 1261, 555, 3847, 5653, 18155, 0 }; + static ulong[] dim1952KuoInit = { 1, 1, 3, 9, 27, 57, 57, 119, 213, 723, 1695, 2233, 1605, 8169, 28485, 0 }; + static ulong[] dim1953KuoInit = { 1, 1, 7, 11, 17, 35, 119, 167, 391, 111, 229, 695, 4209, 5457, 6729, 0 }; + static ulong[] dim1954KuoInit = { 1, 1, 7, 11, 5, 23, 5, 223, 89, 447, 2015, 3403, 1335, 15235, 20897, 0 }; + static ulong[] dim1955KuoInit = { 1, 1, 1, 7, 1, 63, 55, 233, 351, 323, 497, 1247, 2455, 2337, 17523, 0 }; + static ulong[] dim1956KuoInit = { 1, 3, 1, 11, 7, 21, 127, 207, 197, 479, 611, 3525, 2093, 2591, 21085, 0 }; + static ulong[] dim1957KuoInit = { 1, 3, 5, 5, 1, 37, 107, 199, 29, 995, 1857, 133, 1423, 9967, 11367, 0 }; + static ulong[] dim1958KuoInit = { 1, 1, 7, 11, 25, 25, 17, 155, 221, 539, 1895, 1909, 2921, 13107, 21681, 0 }; + static ulong[] dim1959KuoInit = { 1, 1, 1, 13, 25, 59, 45, 41, 401, 657, 2043, 1317, 8065, 11897, 4767, 0 }; + static ulong[] dim1960KuoInit = { 1, 1, 7, 15, 21, 29, 43, 125, 407, 851, 1421, 1101, 811, 9577, 27, 0 }; + static ulong[] dim1961KuoInit = { 1, 3, 5, 7, 25, 49, 65, 175, 319, 807, 1691, 357, 4015, 1059, 599, 0 }; + static ulong[] dim1962KuoInit = { 1, 1, 7, 13, 23, 5, 65, 79, 43, 665, 1931, 2143, 4577, 5905, 14917, 0 }; + static ulong[] dim1963KuoInit = { 1, 3, 1, 7, 5, 41, 121, 251, 395, 951, 795, 1589, 4027, 13671, 18787, 0 }; + static ulong[] dim1964KuoInit = { 1, 3, 7, 11, 3, 51, 57, 177, 63, 33, 1085, 1357, 5039, 2583, 2805, 0 }; + static ulong[] dim1965KuoInit = { 1, 1, 1, 1, 29, 53, 117, 225, 373, 1, 901, 3871, 2815, 9871, 7737, 0 }; + static ulong[] dim1966KuoInit = { 1, 3, 7, 7, 31, 61, 89, 253, 291, 829, 9, 1131, 4951, 14509, 23491, 0 }; + static ulong[] dim1967KuoInit = { 1, 1, 7, 5, 25, 43, 35, 63, 425, 757, 217, 821, 1453, 8413, 7745, 0 }; + static ulong[] dim1968KuoInit = { 1, 1, 5, 5, 7, 1, 41, 233, 235, 599, 833, 3637, 7005, 789, 27709, 0 }; + static ulong[] dim1969KuoInit = { 1, 1, 3, 13, 7, 57, 69, 115, 417, 99, 1435, 3119, 1655, 3515, 7273, 0 }; + static ulong[] dim1970KuoInit = { 1, 1, 3, 15, 9, 13, 33, 57, 179, 847, 289, 2213, 4635, 2349, 20203, 0 }; + static ulong[] dim1971KuoInit = { 1, 1, 3, 9, 1, 39, 63, 147, 277, 389, 575, 423, 4943, 4327, 29067, 0 }; + static ulong[] dim1972KuoInit = { 1, 1, 3, 13, 9, 9, 69, 167, 119, 591, 1679, 3543, 4517, 9263, 17957, 0 }; + static ulong[] dim1973KuoInit = { 1, 3, 5, 13, 25, 37, 127, 159, 391, 29, 329, 3477, 6513, 11971, 18791, 0 }; + static ulong[] dim1974KuoInit = { 1, 1, 7, 5, 25, 29, 49, 135, 387, 921, 391, 665, 6315, 16183, 553, 0 }; + static ulong[] dim1975KuoInit = { 1, 1, 7, 3, 27, 43, 43, 253, 9, 285, 1073, 2627, 7417, 3223, 2649, 0 }; + static ulong[] dim1976KuoInit = { 1, 1, 5, 3, 13, 57, 119, 37, 475, 471, 1145, 2709, 2115, 6507, 12393, 0 }; + static ulong[] dim1977KuoInit = { 1, 1, 3, 1, 17, 29, 117, 189, 319, 533, 1299, 1987, 4971, 15719, 19395, 0 }; + static ulong[] dim1978KuoInit = { 1, 1, 1, 15, 11, 63, 77, 245, 57, 9, 1285, 2069, 579, 5105, 13797, 0 }; + static ulong[] dim1979KuoInit = { 1, 3, 1, 11, 19, 49, 1, 241, 89, 519, 591, 3875, 1585, 7239, 25867, 0 }; + static ulong[] dim1980KuoInit = { 1, 1, 5, 11, 27, 47, 1, 143, 209, 695, 539, 3781, 6317, 14075, 27849, 0 }; + static ulong[] dim1981KuoInit = { 1, 1, 3, 5, 17, 3, 17, 201, 105, 771, 497, 735, 3517, 5207, 20897, 0 }; + static ulong[] dim1982KuoInit = { 1, 1, 3, 15, 3, 3, 103, 35, 421, 235, 1527, 3139, 2693, 9739, 63, 0 }; + static ulong[] dim1983KuoInit = { 1, 3, 1, 13, 21, 39, 101, 213, 205, 853, 1455, 39, 7917, 7893, 4627, 0 }; + static ulong[] dim1984KuoInit = { 1, 3, 7, 5, 13, 5, 9, 239, 129, 355, 809, 3413, 7535, 7063, 29149, 0 }; + static ulong[] dim1985KuoInit = { 1, 1, 5, 3, 19, 37, 125, 55, 495, 597, 735, 1729, 619, 12881, 22913, 0 }; + static ulong[] dim1986KuoInit = { 1, 1, 5, 11, 27, 31, 87, 65, 413, 421, 575, 2185, 4217, 12223, 22487, 0 }; + static ulong[] dim1987KuoInit = { 1, 3, 3, 7, 23, 51, 115, 221, 369, 27, 229, 613, 3739, 1425, 10927, 0 }; + static ulong[] dim1988KuoInit = { 1, 1, 1, 13, 23, 49, 73, 223, 139, 511, 899, 483, 7747, 7947, 32357, 0 }; + static ulong[] dim1989KuoInit = { 1, 3, 5, 3, 7, 31, 9, 119, 417, 723, 2033, 663, 5927, 1787, 12841, 0 }; + static ulong[] dim1990KuoInit = { 1, 1, 5, 9, 7, 5, 55, 201, 245, 221, 1447, 405, 447, 2447, 24331, 0 }; + static ulong[] dim1991KuoInit = { 1, 3, 5, 11, 9, 47, 33, 175, 187, 513, 1613, 2413, 4207, 6941, 2341, 0 }; + static ulong[] dim1992KuoInit = { 1, 1, 5, 9, 19, 33, 33, 181, 505, 923, 1923, 2471, 6499, 11243, 29653, 0 }; + static ulong[] dim1993KuoInit = { 1, 1, 5, 15, 1, 49, 21, 15, 443, 565, 1955, 3299, 139, 14389, 28011, 0 }; + static ulong[] dim1994KuoInit = { 1, 1, 3, 9, 17, 27, 29, 65, 509, 867, 707, 2425, 7279, 15271, 18239, 0 }; + static ulong[] dim1995KuoInit = { 1, 1, 7, 15, 3, 1, 103, 79, 49, 909, 529, 1207, 231, 11181, 23319, 0 }; + static ulong[] dim1996KuoInit = { 1, 1, 5, 1, 13, 23, 33, 29, 189, 491, 129, 501, 2635, 2071, 18057, 0 }; + static ulong[] dim1997KuoInit = { 1, 1, 7, 7, 19, 1, 95, 185, 67, 251, 1017, 105, 3683, 9797, 24413, 0 }; + static ulong[] dim1998KuoInit = { 1, 3, 5, 9, 13, 35, 79, 213, 223, 1013, 1205, 1777, 1415, 5023, 15901, 0 }; + static ulong[] dim1999KuoInit = { 1, 1, 1, 5, 15, 13, 91, 57, 447, 897, 935, 1543, 5461, 5091, 12697, 0 }; + static ulong[] dim2000KuoInit = { 1, 1, 1, 11, 9, 61, 81, 147, 55, 121, 449, 2833, 2383, 12065, 19435, 0 }; + static ulong[] dim2001KuoInit = { 1, 3, 1, 3, 17, 27, 77, 203, 415, 489, 665, 21, 6453, 5069, 29629, 0 }; + static ulong[] dim2002KuoInit = { 1, 1, 1, 9, 7, 3, 33, 209, 85, 851, 367, 783, 309, 14821, 1217, 0 }; + static ulong[] dim2003KuoInit = { 1, 1, 1, 15, 5, 39, 15, 225, 241, 477, 999, 841, 4637, 5383, 18081, 0 }; + static ulong[] dim2004KuoInit = { 1, 1, 5, 5, 19, 49, 101, 115, 87, 781, 815, 2405, 2579, 15043, 31067, 0 }; + static ulong[] dim2005KuoInit = { 1, 1, 3, 5, 3, 57, 123, 191, 305, 999, 1091, 733, 3219, 891, 30495, 0 }; + static ulong[] dim2006KuoInit = { 1, 1, 5, 3, 27, 17, 95, 121, 39, 41, 171, 97, 7363, 11279, 28039, 0 }; + static ulong[] dim2007KuoInit = { 1, 3, 7, 5, 21, 9, 21, 147, 269, 475, 1825, 1459, 6337, 3259, 27731, 0 }; + static ulong[] dim2008KuoInit = { 1, 1, 3, 5, 9, 17, 107, 171, 253, 71, 629, 1671, 2587, 11429, 8985, 0 }; + static ulong[] dim2009KuoInit = { 1, 3, 3, 9, 25, 1, 63, 15, 173, 79, 1465, 2647, 6885, 13043, 24703, 0 }; + static ulong[] dim2010KuoInit = { 1, 3, 1, 9, 1, 13, 3, 217, 49, 77, 1635, 3767, 173, 12697, 11837, 0 }; + static ulong[] dim2011KuoInit = { 1, 3, 5, 13, 31, 7, 11, 181, 509, 601, 1267, 1857, 7871, 1703, 6091, 0 }; + static ulong[] dim2012KuoInit = { 1, 1, 1, 11, 29, 61, 117, 151, 487, 185, 1899, 575, 7341, 3055, 26513, 0 }; + static ulong[] dim2013KuoInit = { 1, 3, 7, 15, 1, 49, 87, 23, 483, 603, 1197, 2589, 1705, 5759, 19791, 0 }; + static ulong[] dim2014KuoInit = { 1, 3, 3, 11, 1, 37, 71, 115, 59, 167, 1907, 2225, 5673, 14571, 19389, 0 }; + static ulong[] dim2015KuoInit = { 1, 1, 3, 7, 15, 57, 33, 143, 45, 321, 779, 543, 3465, 4769, 19753, 0 }; + static ulong[] dim2016KuoInit = { 1, 3, 5, 5, 31, 21, 21, 141, 197, 397, 1041, 317, 109, 9395, 7141, 0 }; + static ulong[] dim2017KuoInit = { 1, 3, 7, 11, 1, 61, 45, 215, 405, 365, 1801, 2767, 6381, 12975, 41, 0 }; + static ulong[] dim2018KuoInit = { 1, 3, 7, 7, 23, 13, 37, 193, 305, 883, 1427, 3859, 2049, 16065, 2471, 0 }; + static ulong[] dim2019KuoInit = { 1, 3, 3, 3, 31, 3, 9, 169, 433, 187, 545, 985, 7699, 1183, 27773, 0 }; + static ulong[] dim2020KuoInit = { 1, 3, 5, 15, 11, 15, 9, 171, 89, 711, 163, 3637, 5725, 5079, 13373, 0 }; + static ulong[] dim2021KuoInit = { 1, 1, 7, 1, 1, 29, 123, 235, 229, 667, 1155, 3387, 129, 13889, 24547, 0 }; + static ulong[] dim2022KuoInit = { 1, 3, 3, 7, 27, 15, 75, 117, 335, 821, 609, 3843, 79, 6787, 5605, 0 }; + static ulong[] dim2023KuoInit = { 1, 1, 3, 15, 27, 47, 13, 163, 205, 773, 541, 1155, 4341, 14155, 6643, 0 }; + static ulong[] dim2024KuoInit = { 1, 3, 3, 11, 31, 1, 67, 35, 443, 723, 1089, 2605, 4193, 6133, 31127, 0 }; + static ulong[] dim2025KuoInit = { 1, 1, 1, 15, 27, 57, 11, 153, 199, 219, 1987, 2517, 1455, 6051, 9615, 0 }; + static ulong[] dim2026KuoInit = { 1, 3, 5, 9, 5, 7, 79, 187, 93, 679, 1607, 799, 2753, 6513, 11371, 0 }; + static ulong[] dim2027KuoInit = { 1, 3, 1, 15, 31, 55, 5, 175, 261, 545, 995, 2225, 2217, 2037, 14785, 0 }; + static ulong[] dim2028KuoInit = { 1, 3, 5, 9, 29, 5, 101, 223, 241, 829, 1625, 3417, 1335, 10705, 531, 0 }; + static ulong[] dim2029KuoInit = { 1, 3, 3, 1, 19, 15, 5, 203, 97, 165, 99, 2371, 3267, 13169, 22229, 0 }; + static ulong[] dim2030KuoInit = { 1, 1, 1, 7, 11, 63, 113, 255, 145, 589, 1149, 683, 2619, 5569, 5933, 0 }; + static ulong[] dim2031KuoInit = { 1, 1, 5, 9, 23, 41, 21, 217, 503, 975, 329, 3433, 6299, 5337, 199, 0 }; + static ulong[] dim2032KuoInit = { 1, 1, 7, 13, 3, 39, 109, 223, 241, 521, 1071, 589, 1199, 13059, 24921, 0 }; + static ulong[] dim2033KuoInit = { 1, 1, 3, 7, 11, 23, 27, 15, 107, 679, 87, 3259, 4369, 7365, 16293, 0 }; + static ulong[] dim2034KuoInit = { 1, 3, 3, 11, 11, 5, 75, 111, 21, 587, 1707, 1915, 6617, 11143, 24389, 0 }; + static ulong[] dim2035KuoInit = { 1, 1, 5, 9, 5, 59, 77, 3, 43, 583, 1601, 2183, 6209, 5409, 18175, 0 }; + static ulong[] dim2036KuoInit = { 1, 1, 1, 1, 15, 1, 55, 95, 437, 731, 1559, 2421, 7441, 6567, 1549, 0 }; + static ulong[] dim2037KuoInit = { 1, 3, 3, 11, 17, 21, 13, 61, 153, 81, 141, 3095, 5485, 14461, 8495, 0 }; + static ulong[] dim2038KuoInit = { 1, 1, 1, 13, 25, 61, 87, 195, 243, 47, 103, 3451, 5583, 1611, 11939, 0 }; + static ulong[] dim2039KuoInit = { 1, 1, 5, 7, 31, 53, 93, 101, 145, 917, 1669, 867, 6949, 16333, 12577, 0 }; + static ulong[] dim2040KuoInit = { 1, 1, 5, 1, 5, 41, 35, 75, 331, 671, 1623, 1573, 4275, 9031, 9047, 0 }; + static ulong[] dim2041KuoInit = { 1, 3, 5, 13, 15, 39, 29, 183, 477, 787, 1333, 2499, 2189, 8387, 2783, 0 }; + static ulong[] dim2042KuoInit = { 1, 1, 3, 7, 19, 33, 117, 201, 177, 595, 69, 3341, 1841, 11091, 16745, 0 }; + static ulong[] dim2043KuoInit = { 1, 3, 7, 11, 29, 59, 69, 119, 433, 595, 221, 1245, 7805, 1761, 27657, 0 }; + static ulong[] dim2044KuoInit = { 1, 3, 5, 3, 23, 19, 75, 189, 279, 867, 113, 3817, 6093, 12237, 20297, 0 }; + static ulong[] dim2045KuoInit = { 1, 1, 1, 15, 21, 39, 15, 249, 9, 997, 51, 1317, 1083, 13683, 5759, 0 }; + static ulong[] dim2046KuoInit = { 1, 1, 5, 15, 29, 29, 25, 93, 465, 549, 283, 1673, 1745, 3913, 7931, 0 }; + static ulong[] dim2047KuoInit = { 1, 3, 5, 1, 5, 23, 123, 217, 211, 215, 1999, 1229, 6969, 13481, 14795, 0 }; + static ulong[] dim2048KuoInit = { 1, 1, 3, 5, 17, 35, 107, 163, 103, 807, 463, 2999, 4889, 12863, 24619, 0 }; + static ulong[] dim2049KuoInit = { 1, 3, 1, 15, 5, 17, 121, 209, 49, 871, 1931, 345, 6887, 1357, 14693, 0 }; + static ulong[] dim2050KuoInit = { 1, 1, 1, 1, 23, 63, 53, 35, 511, 261, 11, 283, 3283, 1963, 11703, 0 }; + static ulong[] dim2051KuoInit = { 1, 3, 3, 13, 15, 41, 19, 39, 445, 21, 513, 2957, 2307, 11451, 6539, 0 }; + static ulong[] dim2052KuoInit = { 1, 1, 3, 11, 19, 45, 7, 155, 387, 287, 347, 1557, 7407, 10885, 31829, 0 }; + static ulong[] dim2053KuoInit = { 1, 3, 5, 13, 9, 53, 61, 99, 355, 449, 1353, 3135, 2329, 733, 22443, 0 }; + static ulong[] dim2054KuoInit = { 1, 1, 3, 5, 27, 47, 43, 217, 113, 385, 903, 3015, 4169, 10705, 11351, 0 }; + static ulong[] dim2055KuoInit = { 1, 3, 7, 11, 9, 33, 7, 167, 473, 465, 357, 2387, 2901, 12995, 16871, 0 }; + static ulong[] dim2056KuoInit = { 1, 3, 7, 3, 29, 35, 85, 201, 311, 581, 491, 2977, 7433, 14615, 29995, 0 }; + static ulong[] dim2057KuoInit = { 1, 3, 1, 15, 5, 5, 121, 17, 93, 847, 835, 3885, 2437, 2237, 15669, 0 }; + static ulong[] dim2058KuoInit = { 1, 3, 7, 5, 29, 39, 57, 241, 247, 847, 311, 3115, 7605, 3117, 30677, 0 }; + static ulong[] dim2059KuoInit = { 1, 3, 1, 13, 21, 27, 123, 77, 511, 319, 1699, 709, 7021, 14377, 9601, 0 }; + static ulong[] dim2060KuoInit = { 1, 3, 3, 5, 31, 1, 49, 249, 271, 595, 1069, 2307, 567, 13145, 8779, 0 }; + static ulong[] dim2061KuoInit = { 1, 3, 3, 3, 29, 25, 55, 63, 289, 617, 1209, 3949, 481, 13495, 16659, 0 }; + static ulong[] dim2062KuoInit = { 1, 3, 3, 3, 5, 19, 47, 125, 323, 917, 1875, 1683, 7451, 16145, 3029, 0 }; + static ulong[] dim2063KuoInit = { 1, 1, 7, 5, 27, 33, 3, 133, 477, 457, 803, 1141, 3965, 9127, 21173, 0 }; + static ulong[] dim2064KuoInit = { 1, 3, 5, 7, 19, 61, 17, 27, 297, 995, 1119, 2555, 6741, 3233, 13735, 0 }; + static ulong[] dim2065KuoInit = { 1, 3, 7, 11, 11, 21, 21, 143, 319, 143, 675, 187, 6909, 7145, 27029, 0 }; + static ulong[] dim2066KuoInit = { 1, 3, 3, 1, 29, 5, 1, 65, 123, 801, 933, 3105, 1163, 15703, 9567, 0 }; + static ulong[] dim2067KuoInit = { 1, 1, 3, 11, 3, 15, 11, 109, 117, 1011, 1407, 3287, 5799, 147, 32641, 0 }; + static ulong[] dim2068KuoInit = { 1, 1, 1, 5, 29, 25, 63, 39, 139, 379, 1887, 417, 2965, 4409, 19149, 0 }; + static ulong[] dim2069KuoInit = { 1, 1, 1, 13, 31, 25, 123, 187, 311, 397, 1467, 15, 4253, 14565, 32609, 0 }; + static ulong[] dim2070KuoInit = { 1, 3, 5, 7, 25, 5, 13, 25, 489, 837, 865, 527, 4965, 2567, 13505, 0 }; + static ulong[] dim2071KuoInit = { 1, 1, 3, 9, 3, 15, 59, 115, 339, 459, 2011, 3311, 4067, 3437, 21435, 0 }; + static ulong[] dim2072KuoInit = { 1, 1, 5, 3, 17, 35, 49, 11, 217, 401, 385, 569, 1727, 9927, 27229, 0 }; + static ulong[] dim2073KuoInit = { 1, 3, 1, 5, 27, 43, 21, 11, 459, 555, 237, 87, 7531, 16117, 23625, 0 }; + static ulong[] dim2074KuoInit = { 1, 3, 3, 5, 15, 57, 93, 35, 31, 257, 77, 3437, 3665, 3137, 2477, 0 }; + static ulong[] dim2075KuoInit = { 1, 3, 5, 9, 1, 43, 91, 55, 53, 265, 1495, 551, 4729, 7839, 23475, 0 }; + static ulong[] dim2076KuoInit = { 1, 1, 7, 11, 11, 45, 9, 27, 485, 397, 925, 3601, 4419, 4563, 6443, 0 }; + static ulong[] dim2077KuoInit = { 1, 3, 5, 3, 15, 35, 103, 239, 193, 831, 559, 1299, 4939, 8051, 6899, 0 }; + static ulong[] dim2078KuoInit = { 1, 3, 3, 11, 17, 47, 77, 13, 227, 935, 1973, 1789, 4357, 5135, 27643, 0 }; + static ulong[] dim2079KuoInit = { 1, 1, 3, 7, 11, 51, 109, 143, 101, 131, 565, 3503, 5649, 10007, 6283, 0 }; + static ulong[] dim2080KuoInit = { 1, 1, 3, 15, 19, 5, 15, 241, 399, 341, 943, 587, 4757, 13941, 7571, 0 }; + static ulong[] dim2081KuoInit = { 1, 3, 3, 3, 21, 9, 119, 119, 445, 349, 1517, 17, 3593, 11983, 9713, 0 }; + static ulong[] dim2082KuoInit = { 1, 1, 3, 3, 23, 55, 21, 251, 191, 585, 1619, 431, 4161, 5667, 17703, 0 }; + static ulong[] dim2083KuoInit = { 1, 3, 3, 3, 1, 57, 65, 231, 67, 531, 1403, 3883, 4463, 12795, 4427, 0 }; + static ulong[] dim2084KuoInit = { 1, 1, 5, 15, 19, 7, 9, 163, 487, 455, 1663, 3141, 5975, 11001, 24781, 0 }; + static ulong[] dim2085KuoInit = { 1, 1, 5, 1, 29, 19, 45, 235, 371, 935, 1757, 187, 7729, 6241, 27171, 0 }; + static ulong[] dim2086KuoInit = { 1, 1, 1, 1, 15, 39, 39, 171, 145, 413, 1545, 3733, 1815, 9443, 32705, 0 }; + static ulong[] dim2087KuoInit = { 1, 1, 3, 9, 31, 1, 87, 11, 219, 913, 131, 3625, 7927, 9945, 2595, 0 }; + static ulong[] dim2088KuoInit = { 1, 3, 3, 13, 21, 15, 39, 29, 267, 275, 973, 701, 1057, 13641, 22149, 0 }; + static ulong[] dim2089KuoInit = { 1, 3, 3, 5, 3, 33, 81, 29, 85, 515, 1719, 3967, 5145, 12921, 8303, 0 }; + static ulong[] dim2090KuoInit = { 1, 3, 7, 11, 17, 23, 113, 129, 395, 153, 427, 1113, 8157, 9087, 20471, 0 }; + static ulong[] dim2091KuoInit = { 1, 1, 5, 9, 23, 5, 119, 67, 215, 581, 1249, 3949, 731, 10387, 27979, 0 }; + static ulong[] dim2092KuoInit = { 1, 1, 5, 5, 5, 53, 7, 39, 51, 519, 225, 119, 4335, 11723, 27971, 0 }; + static ulong[] dim2093KuoInit = { 1, 3, 5, 3, 5, 49, 105, 29, 443, 457, 191, 2679, 5803, 12017, 2205, 0 }; + static ulong[] dim2094KuoInit = { 1, 1, 3, 1, 23, 31, 11, 199, 479, 231, 431, 1989, 705, 6557, 27763, 0 }; + static ulong[] dim2095KuoInit = { 1, 1, 3, 1, 27, 9, 39, 105, 149, 1017, 79, 1575, 6365, 839, 27601, 0 }; + static ulong[] dim2096KuoInit = { 1, 1, 3, 7, 1, 29, 61, 129, 253, 541, 1953, 351, 2895, 14385, 23685, 0 }; + static ulong[] dim2097KuoInit = { 1, 3, 1, 7, 19, 15, 55, 133, 195, 881, 311, 2021, 7935, 4513, 31065, 0 }; + static ulong[] dim2098KuoInit = { 1, 1, 5, 13, 23, 55, 53, 169, 79, 707, 1415, 3999, 299, 6689, 10219, 0 }; + static ulong[] dim2099KuoInit = { 1, 3, 3, 7, 7, 47, 77, 209, 467, 39, 291, 3769, 1295, 12407, 2205, 0 }; + static ulong[] dim2100KuoInit = { 1, 1, 3, 9, 13, 3, 63, 241, 251, 939, 1391, 2053, 719, 13739, 12167, 0 }; + static ulong[] dim2101KuoInit = { 1, 1, 7, 9, 21, 31, 37, 11, 187, 201, 1425, 249, 2475, 12421, 14443, 0 }; + static ulong[] dim2102KuoInit = { 1, 1, 3, 9, 31, 51, 53, 119, 19, 13, 1513, 1115, 1265, 15707, 22795, 0 }; + static ulong[] dim2103KuoInit = { 1, 3, 5, 9, 23, 13, 69, 247, 103, 773, 997, 703, 2921, 3165, 3027, 0 }; + static ulong[] dim2104KuoInit = { 1, 3, 7, 7, 15, 27, 81, 221, 259, 405, 391, 2635, 1747, 7743, 28833, 0 }; + static ulong[] dim2105KuoInit = { 1, 1, 3, 9, 29, 47, 23, 127, 49, 81, 543, 919, 5517, 9573, 1523, 0 }; + static ulong[] dim2106KuoInit = { 1, 3, 3, 9, 11, 37, 123, 199, 343, 697, 293, 3123, 4601, 14209, 30425, 0 }; + static ulong[] dim2107KuoInit = { 1, 1, 5, 7, 3, 31, 127, 13, 191, 509, 1999, 3379, 2365, 10307, 26693, 0 }; + static ulong[] dim2108KuoInit = { 1, 3, 7, 3, 3, 41, 71, 153, 119, 9, 1601, 3839, 369, 16241, 19115, 0 }; + static ulong[] dim2109KuoInit = { 1, 1, 5, 5, 3, 17, 7, 65, 191, 143, 127, 1973, 6885, 13615, 26289, 0 }; + static ulong[] dim2110KuoInit = { 1, 1, 3, 5, 13, 5, 87, 17, 445, 975, 1527, 253, 5983, 7095, 21271, 0 }; + static ulong[] dim2111KuoInit = { 1, 3, 1, 3, 7, 49, 29, 19, 37, 695, 603, 3153, 4065, 5421, 3285, 0 }; + static ulong[] dim2112KuoInit = { 1, 1, 5, 13, 25, 47, 43, 35, 205, 629, 1255, 2843, 7533, 751, 10119, 0 }; + static ulong[] dim2113KuoInit = { 1, 3, 1, 11, 13, 27, 127, 221, 67, 523, 217, 1493, 1793, 10871, 14289, 0 }; + static ulong[] dim2114KuoInit = { 1, 1, 1, 5, 21, 47, 45, 73, 479, 653, 1553, 695, 3131, 8773, 20303, 0 }; + static ulong[] dim2115KuoInit = { 1, 3, 1, 1, 19, 31, 25, 207, 361, 961, 1595, 1807, 3649, 1029, 31579, 0 }; + static ulong[] dim2116KuoInit = { 1, 1, 1, 1, 27, 23, 109, 111, 477, 233, 1305, 51, 4517, 14867, 4075, 0 }; + static ulong[] dim2117KuoInit = { 1, 1, 7, 11, 21, 5, 51, 9, 131, 671, 191, 4045, 7773, 5037, 23229, 0 }; + static ulong[] dim2118KuoInit = { 1, 1, 5, 7, 3, 57, 75, 141, 439, 269, 99, 1595, 3597, 10183, 19849, 0 }; + static ulong[] dim2119KuoInit = { 1, 1, 3, 3, 17, 61, 81, 75, 471, 1023, 1045, 849, 3741, 12803, 10735, 0 }; + static ulong[] dim2120KuoInit = { 1, 1, 7, 11, 3, 33, 79, 113, 335, 245, 1807, 1927, 7381, 6405, 20035, 0 }; + static ulong[] dim2121KuoInit = { 1, 3, 1, 11, 5, 37, 31, 177, 233, 937, 1655, 511, 1109, 5083, 31325, 0 }; + static ulong[] dim2122KuoInit = { 1, 3, 5, 15, 15, 35, 125, 105, 313, 553, 259, 1433, 327, 2079, 5279, 0 }; + static ulong[] dim2123KuoInit = { 1, 3, 1, 1, 25, 57, 121, 189, 409, 459, 749, 3159, 6389, 4141, 16463, 0 }; + static ulong[] dim2124KuoInit = { 1, 1, 7, 15, 7, 21, 113, 139, 241, 617, 1385, 1387, 145, 6605, 2057, 0 }; + static ulong[] dim2125KuoInit = { 1, 3, 3, 11, 17, 33, 89, 17, 341, 369, 719, 2481, 7589, 16283, 28157, 0 }; + static ulong[] dim2126KuoInit = { 1, 3, 7, 1, 11, 17, 31, 135, 333, 335, 197, 2401, 7637, 703, 3001, 0 }; + static ulong[] dim2127KuoInit = { 1, 3, 5, 11, 17, 31, 33, 249, 315, 475, 1743, 2429, 4923, 2779, 25677, 0 }; + static ulong[] dim2128KuoInit = { 1, 1, 5, 5, 11, 29, 111, 103, 143, 779, 1437, 3759, 5827, 3129, 26961, 0 }; + static ulong[] dim2129KuoInit = { 1, 3, 5, 3, 25, 1, 109, 117, 159, 53, 1291, 1787, 7851, 14363, 15271, 0 }; + static ulong[] dim2130KuoInit = { 1, 1, 1, 9, 9, 1, 31, 131, 163, 723, 1023, 27, 853, 2623, 16859, 0 }; + static ulong[] dim2131KuoInit = { 1, 1, 3, 11, 23, 13, 91, 87, 141, 111, 1677, 1483, 1461, 15981, 29417, 0 }; + static ulong[] dim2132KuoInit = { 1, 3, 7, 9, 17, 17, 115, 43, 397, 683, 2017, 985, 3703, 16135, 3661, 0 }; + static ulong[] dim2133KuoInit = { 1, 1, 7, 13, 17, 45, 71, 149, 317, 559, 279, 2441, 2323, 16071, 29709, 0 }; + static ulong[] dim2134KuoInit = { 1, 3, 5, 11, 31, 33, 105, 127, 375, 1001, 115, 1429, 7003, 13369, 23281, 0 }; + static ulong[] dim2135KuoInit = { 1, 1, 5, 7, 21, 7, 27, 105, 99, 479, 849, 1361, 4935, 14831, 29, 0 }; + static ulong[] dim2136KuoInit = { 1, 3, 7, 9, 15, 53, 63, 109, 171, 323, 289, 2937, 3177, 4615, 10711, 0 }; + static ulong[] dim2137KuoInit = { 1, 1, 1, 1, 27, 41, 29, 101, 209, 673, 1597, 3743, 827, 4025, 27267, 0 }; + static ulong[] dim2138KuoInit = { 1, 3, 7, 13, 25, 17, 19, 219, 233, 769, 909, 3585, 55, 13349, 13685, 0 }; + static ulong[] dim2139KuoInit = { 1, 1, 1, 15, 17, 57, 63, 181, 339, 319, 655, 699, 1633, 8181, 23039, 0 }; + static ulong[] dim2140KuoInit = { 1, 1, 3, 1, 25, 11, 61, 195, 311, 723, 365, 2791, 1281, 9113, 26741, 0 }; + static ulong[] dim2141KuoInit = { 1, 1, 7, 11, 19, 43, 65, 37, 89, 847, 951, 851, 4441, 6681, 917, 0 }; + static ulong[] dim2142KuoInit = { 1, 3, 5, 13, 1, 11, 55, 29, 419, 769, 815, 1487, 2151, 7981, 19509, 0 }; + static ulong[] dim2143KuoInit = { 1, 1, 5, 13, 11, 55, 127, 19, 419, 679, 119, 1417, 1717, 5849, 6365, 0 }; + static ulong[] dim2144KuoInit = { 1, 1, 7, 5, 29, 5, 9, 241, 405, 253, 1015, 2027, 7695, 12003, 659, 0 }; + static ulong[] dim2145KuoInit = { 1, 3, 7, 5, 27, 63, 87, 221, 219, 355, 941, 3901, 6535, 4715, 3571, 0 }; + static ulong[] dim2146KuoInit = { 1, 3, 3, 9, 13, 1, 113, 21, 71, 353, 1063, 1447, 2157, 5195, 21311, 0 }; + static ulong[] dim2147KuoInit = { 1, 1, 3, 15, 29, 1, 7, 223, 43, 605, 1063, 67, 2529, 1125, 16933, 0 }; + static ulong[] dim2148KuoInit = { 1, 3, 1, 15, 29, 37, 51, 239, 117, 351, 1953, 1933, 6371, 13467, 8265, 0 }; + static ulong[] dim2149KuoInit = { 1, 1, 3, 5, 7, 25, 19, 221, 409, 121, 89, 219, 105, 4213, 1903, 0 }; + static ulong[] dim2150KuoInit = { 1, 3, 7, 1, 13, 3, 79, 123, 423, 589, 1085, 3387, 6117, 8749, 8947, 0 }; + static ulong[] dim2151KuoInit = { 1, 3, 7, 9, 21, 49, 1, 39, 461, 115, 1131, 719, 3709, 1495, 23871, 0 }; + static ulong[] dim2152KuoInit = { 1, 1, 7, 5, 23, 41, 107, 225, 499, 721, 1977, 2063, 1825, 9589, 22137, 0 }; + static ulong[] dim2153KuoInit = { 1, 1, 5, 7, 15, 53, 33, 145, 179, 109, 425, 2729, 7637, 6805, 26223, 0 }; + static ulong[] dim2154KuoInit = { 1, 1, 5, 13, 1, 1, 31, 117, 25, 427, 681, 2991, 7681, 15927, 20913, 0 }; + static ulong[] dim2155KuoInit = { 1, 1, 5, 13, 31, 53, 23, 71, 397, 661, 131, 2815, 2351, 15881, 10321, 0 }; + static ulong[] dim2156KuoInit = { 1, 3, 1, 15, 19, 41, 39, 57, 349, 761, 1999, 1151, 201, 1025, 18821, 0 }; + static ulong[] dim2157KuoInit = { 1, 1, 3, 3, 17, 43, 73, 163, 187, 913, 31, 81, 4829, 6993, 32175, 0 }; + static ulong[] dim2158KuoInit = { 1, 3, 1, 15, 19, 41, 79, 13, 343, 415, 863, 1943, 2231, 11353, 15631, 0 }; + static ulong[] dim2159KuoInit = { 1, 3, 1, 15, 29, 35, 101, 23, 111, 937, 833, 2369, 3503, 6605, 14279, 0 }; + static ulong[] dim2160KuoInit = { 1, 3, 7, 15, 27, 61, 43, 211, 259, 583, 1529, 1013, 8005, 7717, 1085, 0 }; + static ulong[] dim2161KuoInit = { 1, 1, 7, 15, 23, 39, 17, 201, 465, 289, 1051, 33, 7403, 7971, 24905, 0 }; + static ulong[] dim2162KuoInit = { 1, 1, 5, 13, 23, 41, 5, 239, 9, 23, 1353, 2005, 2513, 8707, 3893, 0 }; + static ulong[] dim2163KuoInit = { 1, 3, 1, 7, 7, 41, 73, 177, 351, 297, 1057, 3867, 2481, 15751, 25231, 0 }; + static ulong[] dim2164KuoInit = { 1, 1, 3, 1, 17, 59, 45, 171, 367, 575, 1085, 953, 3467, 8435, 6345, 0 }; + static ulong[] dim2165KuoInit = { 1, 3, 1, 9, 5, 21, 125, 137, 415, 101, 121, 3499, 6671, 15541, 14081, 0 }; + static ulong[] dim2166KuoInit = { 1, 3, 5, 15, 15, 19, 111, 235, 53, 119, 1307, 583, 1695, 211, 5567, 0 }; + static ulong[] dim2167KuoInit = { 1, 1, 5, 9, 7, 13, 119, 109, 273, 677, 2001, 3307, 7999, 11769, 10069, 0 }; + static ulong[] dim2168KuoInit = { 1, 1, 1, 15, 11, 15, 57, 233, 77, 815, 31, 669, 6365, 5085, 13583, 0 }; + static ulong[] dim2169KuoInit = { 1, 3, 7, 1, 31, 9, 101, 33, 13, 699, 637, 1159, 5101, 13805, 32651, 0 }; + static ulong[] dim2170KuoInit = { 1, 1, 7, 13, 15, 9, 125, 71, 241, 147, 529, 1863, 1551, 4981, 30389, 0 }; + static ulong[] dim2171KuoInit = { 1, 1, 7, 13, 11, 35, 11, 5, 473, 55, 1589, 2835, 3771, 11433, 11099, 0 }; + static ulong[] dim2172KuoInit = { 1, 1, 7, 15, 11, 11, 35, 207, 267, 289, 999, 3183, 3827, 6617, 29015, 0 }; + static ulong[] dim2173KuoInit = { 1, 1, 3, 1, 3, 11, 119, 223, 255, 319, 1823, 1301, 4401, 12827, 889, 0 }; + static ulong[] dim2174KuoInit = { 1, 3, 5, 1, 1, 5, 5, 109, 27, 963, 727, 335, 6295, 9775, 32681, 0 }; + static ulong[] dim2175KuoInit = { 1, 3, 7, 15, 29, 47, 55, 253, 281, 303, 857, 903, 2977, 14777, 31689, 0 }; + static ulong[] dim2176KuoInit = { 1, 3, 1, 7, 17, 49, 105, 155, 467, 467, 1287, 1281, 3429, 3195, 15297, 0 }; + static ulong[] dim2177KuoInit = { 1, 3, 1, 1, 27, 31, 17, 201, 23, 897, 1991, 2661, 645, 16127, 30857, 0 }; + static ulong[] dim2178KuoInit = { 1, 3, 3, 11, 9, 15, 85, 183, 31, 179, 779, 171, 5989, 7253, 15077, 0 }; + static ulong[] dim2179KuoInit = { 1, 1, 1, 5, 19, 23, 37, 39, 281, 707, 17, 2707, 289, 12081, 4381, 0 }; + static ulong[] dim2180KuoInit = { 1, 1, 7, 9, 21, 27, 115, 179, 99, 277, 331, 3407, 2057, 13893, 11501, 0 }; + static ulong[] dim2181KuoInit = { 1, 3, 1, 9, 31, 51, 51, 25, 319, 319, 27, 2161, 89, 3421, 18273, 0 }; + static ulong[] dim2182KuoInit = { 1, 1, 7, 15, 13, 21, 11, 189, 63, 15, 363, 1951, 5751, 5797, 22123, 0 }; + static ulong[] dim2183KuoInit = { 1, 1, 3, 1, 25, 47, 99, 77, 77, 595, 1473, 1653, 6751, 5005, 29051, 0 }; + static ulong[] dim2184KuoInit = { 1, 1, 3, 7, 25, 47, 31, 13, 311, 269, 1095, 1359, 305, 6811, 16455, 0 }; + static ulong[] dim2185KuoInit = { 1, 1, 5, 3, 13, 63, 87, 13, 221, 459, 1177, 891, 5781, 13803, 18795, 0 }; + static ulong[] dim2186KuoInit = { 1, 1, 7, 3, 23, 13, 25, 115, 47, 903, 1551, 2887, 229, 16067, 9511, 0 }; + static ulong[] dim2187KuoInit = { 1, 1, 7, 15, 23, 15, 7, 65, 27, 677, 1503, 125, 7739, 14655, 29577, 0 }; + static ulong[] dim2188KuoInit = { 1, 1, 1, 5, 9, 23, 93, 187, 205, 915, 599, 2105, 7767, 2411, 15045, 0 }; + static ulong[] dim2189KuoInit = { 1, 3, 5, 1, 21, 45, 17, 57, 171, 491, 1465, 2013, 3253, 5517, 19113, 0 }; + static ulong[] dim2190KuoInit = { 1, 1, 7, 5, 5, 25, 87, 247, 301, 385, 1655, 1351, 6307, 14695, 29745, 0 }; + static ulong[] dim2191KuoInit = { 1, 3, 7, 3, 31, 25, 113, 155, 123, 755, 649, 1809, 1703, 875, 5235, 0 }; + static ulong[] dim2192KuoInit = { 1, 1, 1, 7, 7, 43, 121, 47, 499, 63, 449, 2039, 835, 2883, 2287, 0 }; + static ulong[] dim2193KuoInit = { 1, 3, 7, 1, 9, 11, 99, 169, 305, 469, 157, 2043, 4851, 3367, 8689, 0 }; + static ulong[] dim2194KuoInit = { 1, 1, 1, 11, 17, 15, 41, 209, 377, 81, 335, 1685, 143, 1513, 28465, 0 }; + static ulong[] dim2195KuoInit = { 1, 3, 1, 15, 9, 45, 83, 123, 347, 437, 783, 3561, 6003, 9329, 4729, 0 }; + static ulong[] dim2196KuoInit = { 1, 1, 1, 1, 13, 33, 109, 217, 403, 539, 1393, 1069, 235, 11261, 13423, 0 }; + static ulong[] dim2197KuoInit = { 1, 1, 5, 13, 27, 1, 81, 139, 421, 301, 55, 1883, 1525, 6029, 1879, 0 }; + static ulong[] dim2198KuoInit = { 1, 1, 1, 15, 15, 55, 49, 249, 487, 373, 737, 2133, 6883, 1603, 27607, 0 }; + static ulong[] dim2199KuoInit = { 1, 1, 1, 13, 25, 17, 17, 15, 119, 571, 1053, 2153, 5221, 2681, 24595, 0 }; + static ulong[] dim2200KuoInit = { 1, 3, 1, 5, 3, 63, 31, 9, 263, 977, 575, 1225, 4127, 15649, 1281, 0 }; + static ulong[] dim2201KuoInit = { 1, 1, 7, 9, 19, 1, 37, 109, 13, 191, 1483, 465, 1321, 13697, 26065, 0 }; + static ulong[] dim2202KuoInit = { 1, 1, 3, 9, 17, 15, 103, 97, 237, 861, 1251, 2069, 4459, 9999, 7369, 0 }; + static ulong[] dim2203KuoInit = { 1, 3, 7, 9, 15, 33, 55, 5, 355, 519, 445, 4033, 627, 2375, 31013, 0 }; + static ulong[] dim2204KuoInit = { 1, 1, 1, 3, 23, 51, 65, 177, 225, 63, 987, 2921, 823, 1781, 22923, 0 }; + static ulong[] dim2205KuoInit = { 1, 3, 5, 7, 27, 33, 111, 47, 465, 379, 1575, 1793, 513, 14033, 27409, 0 }; + static ulong[] dim2206KuoInit = { 1, 3, 5, 7, 1, 57, 31, 195, 393, 257, 1489, 2589, 5339, 7487, 29023, 0 }; + static ulong[] dim2207KuoInit = { 1, 3, 5, 11, 15, 27, 39, 89, 387, 753, 1213, 2417, 6287, 129, 12295, 0 }; + static ulong[] dim2208KuoInit = { 1, 1, 3, 11, 11, 37, 117, 55, 55, 677, 1057, 3971, 5017, 12941, 3001, 0 }; + static ulong[] dim2209KuoInit = { 1, 3, 1, 7, 21, 33, 103, 19, 427, 637, 393, 2245, 2853, 15927, 14633, 0 }; + static ulong[] dim2210KuoInit = { 1, 1, 5, 7, 31, 11, 75, 191, 367, 659, 121, 2947, 515, 10625, 19753, 0 }; + static ulong[] dim2211KuoInit = { 1, 1, 5, 5, 15, 63, 115, 119, 85, 527, 875, 67, 475, 2207, 4101, 0 }; + static ulong[] dim2212KuoInit = { 1, 3, 3, 9, 23, 37, 53, 187, 37, 535, 509, 1765, 6577, 13249, 3875, 0 }; + static ulong[] dim2213KuoInit = { 1, 3, 3, 5, 13, 49, 23, 193, 109, 295, 309, 2457, 4193, 9927, 16313, 0 }; + static ulong[] dim2214KuoInit = { 1, 3, 3, 5, 5, 15, 33, 69, 225, 231, 131, 3135, 3597, 2989, 12365, 0 }; + static ulong[] dim2215KuoInit = { 1, 3, 7, 1, 27, 33, 9, 139, 507, 789, 663, 1693, 949, 9149, 29529, 0 }; + static ulong[] dim2216KuoInit = { 1, 1, 7, 7, 11, 1, 57, 159, 511, 929, 1337, 2181, 5573, 425, 26935, 0 }; + static ulong[] dim2217KuoInit = { 1, 1, 5, 9, 15, 53, 57, 81, 105, 389, 1563, 1, 669, 8403, 15747, 0 }; + static ulong[] dim2218KuoInit = { 1, 3, 3, 5, 19, 21, 29, 133, 203, 689, 2011, 1825, 3365, 1957, 21393, 0 }; + static ulong[] dim2219KuoInit = { 1, 1, 3, 15, 7, 11, 73, 189, 63, 81, 1429, 3403, 4249, 16265, 22423, 0 }; + static ulong[] dim2220KuoInit = { 1, 1, 5, 1, 31, 47, 75, 199, 343, 957, 691, 939, 2165, 10523, 3577, 0 }; + static ulong[] dim2221KuoInit = { 1, 1, 7, 13, 3, 27, 5, 131, 437, 405, 1809, 2637, 5735, 12897, 22905, 0 }; + static ulong[] dim2222KuoInit = { 1, 1, 5, 1, 17, 17, 85, 161, 205, 81, 1125, 1783, 2241, 6321, 10891, 0 }; + static ulong[] dim2223KuoInit = { 1, 3, 7, 15, 27, 7, 119, 61, 383, 171, 1495, 1237, 729, 1977, 11779, 0 }; + static ulong[] dim2224KuoInit = { 1, 1, 5, 7, 21, 3, 63, 167, 493, 117, 855, 143, 2579, 7527, 7395, 0 }; + static ulong[] dim2225KuoInit = { 1, 1, 1, 9, 31, 61, 15, 31, 445, 397, 1369, 1047, 4751, 10375, 30319, 0 }; + static ulong[] dim2226KuoInit = { 1, 3, 1, 15, 7, 13, 87, 99, 333, 433, 287, 2861, 2085, 14691, 14801, 0 }; + static ulong[] dim2227KuoInit = { 1, 3, 3, 7, 27, 45, 41, 69, 391, 259, 899, 1019, 2999, 6487, 19831, 0 }; + static ulong[] dim2228KuoInit = { 1, 3, 5, 11, 19, 33, 49, 87, 89, 649, 1209, 43, 8035, 12687, 24783, 0 }; + static ulong[] dim2229KuoInit = { 1, 3, 1, 9, 13, 11, 55, 5, 315, 347, 1361, 41, 807, 11551, 499, 0 }; + static ulong[] dim2230KuoInit = { 1, 1, 7, 1, 25, 15, 11, 19, 233, 269, 135, 2577, 4385, 8109, 13161, 0 }; + static ulong[] dim2231KuoInit = { 1, 3, 1, 9, 19, 13, 127, 79, 49, 525, 1499, 1209, 3747, 8311, 15061, 0 }; + static ulong[] dim2232KuoInit = { 1, 3, 1, 15, 9, 47, 59, 81, 491, 401, 1691, 543, 7129, 13617, 17031, 0 }; + static ulong[] dim2233KuoInit = { 1, 3, 3, 5, 15, 51, 41, 85, 245, 91, 1293, 2041, 7205, 12709, 17421, 0 }; + static ulong[] dim2234KuoInit = { 1, 3, 1, 5, 3, 19, 29, 149, 51, 133, 953, 2385, 7471, 14829, 8197, 0 }; + static ulong[] dim2235KuoInit = { 1, 3, 1, 11, 31, 15, 5, 139, 299, 595, 1585, 2115, 5647, 12125, 1265, 0 }; + static ulong[] dim2236KuoInit = { 1, 3, 7, 9, 7, 5, 93, 187, 307, 329, 671, 3983, 817, 3965, 21561, 0 }; + static ulong[] dim2237KuoInit = { 1, 3, 7, 1, 21, 57, 67, 159, 467, 65, 1365, 2797, 7051, 12603, 10429, 0 }; + static ulong[] dim2238KuoInit = { 1, 3, 1, 7, 27, 59, 113, 199, 13, 393, 1605, 3215, 5233, 12749, 32365, 0 }; + static ulong[] dim2239KuoInit = { 1, 3, 1, 1, 1, 13, 15, 217, 317, 945, 1713, 1951, 5585, 1529, 4969, 0 }; + static ulong[] dim2240KuoInit = { 1, 1, 7, 15, 3, 59, 23, 255, 71, 539, 21, 2603, 5145, 295, 2681, 0 }; + static ulong[] dim2241KuoInit = { 1, 1, 1, 13, 11, 41, 85, 145, 209, 1001, 659, 951, 4039, 1409, 4059, 0 }; + static ulong[] dim2242KuoInit = { 1, 1, 7, 13, 15, 41, 15, 121, 485, 515, 325, 3673, 2883, 8119, 29183, 0 }; + static ulong[] dim2243KuoInit = { 1, 3, 3, 13, 21, 39, 31, 163, 13, 219, 411, 2061, 1999, 2999, 24835, 0 }; + static ulong[] dim2244KuoInit = { 1, 3, 7, 7, 21, 49, 9, 75, 401, 339, 191, 2679, 7483, 1361, 21399, 0 }; + static ulong[] dim2245KuoInit = { 1, 3, 1, 13, 5, 29, 9, 77, 459, 247, 1777, 3873, 6747, 7541, 12015, 0 }; + static ulong[] dim2246KuoInit = { 1, 1, 5, 9, 23, 27, 55, 51, 389, 63, 1163, 255, 6049, 1737, 12403, 0 }; + static ulong[] dim2247KuoInit = { 1, 1, 7, 3, 23, 25, 81, 247, 261, 445, 1297, 1945, 2769, 1287, 24403, 0 }; + static ulong[] dim2248KuoInit = { 1, 1, 5, 15, 19, 13, 127, 105, 475, 859, 683, 941, 2911, 14571, 22769, 0 }; + static ulong[] dim2249KuoInit = { 1, 1, 1, 13, 31, 25, 55, 63, 355, 525, 397, 3213, 2267, 2731, 32145, 0 }; + static ulong[] dim2250KuoInit = { 1, 1, 5, 15, 3, 21, 45, 229, 83, 661, 149, 1615, 5309, 12233, 23101, 0 }; + static ulong[] dim2251KuoInit = { 1, 1, 7, 1, 15, 41, 91, 17, 119, 65, 1921, 97, 6521, 8969, 5419, 0 }; + static ulong[] dim2252KuoInit = { 1, 1, 7, 11, 31, 35, 73, 123, 331, 83, 125, 3001, 5485, 1693, 24327, 0 }; + static ulong[] dim2253KuoInit = { 1, 3, 5, 15, 29, 37, 63, 229, 143, 529, 961, 2845, 8003, 7741, 23393, 0 }; + static ulong[] dim2254KuoInit = { 1, 3, 1, 15, 25, 27, 91, 171, 361, 575, 1977, 2141, 89, 7097, 8115, 0 }; + static ulong[] dim2255KuoInit = { 1, 3, 7, 15, 13, 7, 51, 253, 17, 991, 595, 1819, 7091, 8619, 1147, 0 }; + static ulong[] dim2256KuoInit = { 1, 3, 3, 7, 13, 31, 41, 11, 57, 185, 1353, 907, 6585, 8597, 10239, 0 }; + static ulong[] dim2257KuoInit = { 1, 3, 1, 11, 31, 1, 119, 165, 105, 725, 493, 3279, 7117, 15141, 5957, 0 }; + static ulong[] dim2258KuoInit = { 1, 3, 3, 13, 29, 1, 35, 95, 477, 847, 733, 2599, 581, 6487, 10879, 0 }; + static ulong[] dim2259KuoInit = { 1, 3, 7, 3, 15, 23, 115, 177, 409, 711, 1179, 685, 4071, 15129, 2951, 0 }; + static ulong[] dim2260KuoInit = { 1, 1, 3, 11, 19, 5, 69, 33, 41, 501, 135, 1063, 4857, 15537, 29247, 0 }; + static ulong[] dim2261KuoInit = { 1, 3, 5, 13, 1, 25, 123, 1, 431, 399, 483, 3159, 7359, 6169, 22525, 0 }; + static ulong[] dim2262KuoInit = { 1, 3, 5, 7, 1, 9, 125, 131, 99, 911, 421, 1403, 993, 14155, 20863, 0 }; + static ulong[] dim2263KuoInit = { 1, 3, 1, 3, 1, 43, 93, 9, 345, 483, 1809, 2379, 653, 14851, 20619, 0 }; + static ulong[] dim2264KuoInit = { 1, 3, 7, 5, 15, 37, 33, 185, 173, 397, 2021, 613, 37, 7185, 15399, 0 }; + static ulong[] dim2265KuoInit = { 1, 3, 5, 5, 17, 55, 119, 207, 301, 461, 1853, 2471, 3611, 1149, 3321, 0 }; + static ulong[] dim2266KuoInit = { 1, 3, 3, 3, 25, 57, 51, 135, 337, 935, 619, 1165, 1613, 8711, 2329, 0 }; + static ulong[] dim2267KuoInit = { 1, 3, 1, 15, 27, 25, 63, 127, 169, 221, 1103, 1087, 1729, 3967, 6323, 0 }; + static ulong[] dim2268KuoInit = { 1, 1, 3, 11, 13, 29, 105, 189, 321, 103, 2047, 923, 4443, 2175, 12411, 0 }; + static ulong[] dim2269KuoInit = { 1, 1, 7, 9, 7, 3, 3, 61, 479, 533, 227, 3137, 6065, 3621, 3583, 0 }; + static ulong[] dim2270KuoInit = { 1, 1, 5, 13, 11, 31, 23, 147, 67, 823, 663, 3717, 6747, 10935, 21931, 0 }; + static ulong[] dim2271KuoInit = { 1, 1, 5, 13, 29, 9, 75, 31, 349, 603, 1071, 1767, 1811, 15921, 25681, 0 }; + static ulong[] dim2272KuoInit = { 1, 3, 7, 13, 29, 31, 57, 15, 405, 263, 715, 445, 1825, 15057, 3449, 0 }; + static ulong[] dim2273KuoInit = { 1, 3, 5, 5, 5, 21, 61, 137, 15, 935, 897, 125, 6651, 6813, 27863, 0 }; + static ulong[] dim2274KuoInit = { 1, 1, 3, 13, 9, 53, 5, 91, 93, 179, 489, 3615, 5911, 7501, 14205, 0 }; + static ulong[] dim2275KuoInit = { 1, 1, 5, 13, 27, 49, 35, 93, 371, 519, 589, 1563, 2609, 14055, 28071, 0 }; + static ulong[] dim2276KuoInit = { 1, 1, 5, 7, 29, 41, 23, 135, 491, 745, 1327, 4065, 6327, 6375, 24901, 0 }; + static ulong[] dim2277KuoInit = { 1, 3, 3, 5, 23, 47, 113, 85, 453, 321, 597, 1817, 7579, 11633, 25569, 0 }; + static ulong[] dim2278KuoInit = { 1, 3, 1, 13, 13, 55, 127, 47, 159, 885, 235, 199, 3133, 9793, 25877, 0 }; + static ulong[] dim2279KuoInit = { 1, 1, 3, 9, 17, 21, 27, 237, 413, 999, 451, 3279, 1607, 9625, 16943, 0 }; + static ulong[] dim2280KuoInit = { 1, 3, 1, 1, 21, 61, 29, 143, 33, 235, 1591, 2379, 3573, 1399, 16215, 0 }; + static ulong[] dim2281KuoInit = { 1, 1, 7, 1, 29, 23, 95, 207, 87, 199, 1389, 3587, 71, 14401, 28431, 0 }; + static ulong[] dim2282KuoInit = { 1, 1, 5, 13, 23, 43, 109, 119, 151, 451, 23, 2709, 3125, 11541, 3923, 0 }; + static ulong[] dim2283KuoInit = { 1, 3, 7, 3, 11, 55, 5, 227, 171, 465, 1685, 333, 2605, 15055, 8333, 0 }; + static ulong[] dim2284KuoInit = { 1, 3, 5, 3, 21, 11, 57, 37, 67, 667, 521, 2961, 6145, 12527, 17433, 0 }; + static ulong[] dim2285KuoInit = { 1, 1, 7, 11, 9, 39, 103, 83, 313, 827, 721, 2965, 3231, 10121, 19991, 0 }; + static ulong[] dim2286KuoInit = { 1, 1, 5, 7, 23, 9, 31, 39, 7, 767, 153, 2969, 5539, 6581, 30515, 0 }; + static ulong[] dim2287KuoInit = { 1, 1, 3, 13, 3, 43, 49, 143, 3, 227, 99, 597, 7207, 4737, 2259, 0 }; + static ulong[] dim2288KuoInit = { 1, 3, 3, 3, 3, 57, 69, 243, 199, 803, 657, 1209, 1343, 11673, 21543, 0 }; + static ulong[] dim2289KuoInit = { 1, 1, 1, 1, 17, 27, 127, 107, 171, 391, 1737, 1247, 1389, 14387, 1671, 0 }; + static ulong[] dim2290KuoInit = { 1, 3, 3, 9, 23, 47, 97, 139, 435, 943, 1111, 2723, 1021, 1155, 10241, 0 }; + static ulong[] dim2291KuoInit = { 1, 3, 3, 13, 15, 15, 101, 205, 229, 639, 1077, 1613, 3035, 12897, 14303, 0 }; + static ulong[] dim2292KuoInit = { 1, 1, 1, 9, 17, 43, 3, 81, 149, 931, 731, 4005, 7397, 8707, 27927, 0 }; + static ulong[] dim2293KuoInit = { 1, 3, 7, 15, 19, 59, 97, 97, 347, 489, 1577, 3927, 3431, 4051, 8489, 0 }; + static ulong[] dim2294KuoInit = { 1, 1, 5, 3, 29, 49, 19, 151, 27, 701, 541, 481, 101, 10701, 31909, 0 }; + static ulong[] dim2295KuoInit = { 1, 1, 1, 9, 11, 47, 59, 45, 439, 757, 1579, 1681, 6701, 11707, 10715, 0 }; + static ulong[] dim2296KuoInit = { 1, 3, 3, 11, 27, 55, 1, 35, 491, 767, 1247, 1143, 5079, 8029, 10267, 0 }; + static ulong[] dim2297KuoInit = { 1, 3, 3, 1, 15, 5, 53, 215, 249, 659, 329, 1959, 249, 11775, 4815, 0 }; + static ulong[] dim2298KuoInit = { 1, 3, 7, 15, 19, 17, 41, 29, 157, 995, 235, 1397, 3983, 11739, 7523, 0 }; + static ulong[] dim2299KuoInit = { 1, 3, 5, 5, 13, 3, 55, 211, 59, 717, 1389, 3219, 2279, 9583, 16981, 0 }; + static ulong[] dim2300KuoInit = { 1, 3, 5, 11, 31, 41, 95, 217, 375, 255, 1433, 1595, 5795, 11893, 16665, 0 }; + static ulong[] dim2301KuoInit = { 1, 3, 1, 13, 15, 45, 19, 125, 387, 1017, 1075, 3469, 7873, 9135, 28215, 0 }; + static ulong[] dim2302KuoInit = { 1, 3, 7, 5, 23, 41, 35, 171, 159, 545, 2043, 887, 8167, 8977, 30985, 0 }; + static ulong[] dim2303KuoInit = { 1, 3, 1, 3, 21, 17, 31, 171, 45, 979, 757, 3839, 4221, 8659, 7005, 0 }; + static ulong[] dim2304KuoInit = { 1, 3, 3, 1, 3, 23, 81, 157, 385, 233, 527, 2357, 7299, 10977, 16285, 0 }; + static ulong[] dim2305KuoInit = { 1, 1, 7, 13, 23, 27, 31, 211, 451, 211, 45, 2239, 981, 14279, 14515, 0 }; + static ulong[] dim2306KuoInit = { 1, 3, 1, 5, 13, 61, 17, 197, 455, 457, 2023, 1809, 4243, 3269, 7159, 0 }; + static ulong[] dim2307KuoInit = { 1, 1, 5, 5, 9, 61, 49, 111, 281, 827, 1155, 3107, 5761, 12043, 3061, 0 }; + static ulong[] dim2308KuoInit = { 1, 1, 1, 5, 19, 29, 63, 209, 207, 503, 1563, 2539, 5115, 12939, 22977, 0 }; + static ulong[] dim2309KuoInit = { 1, 3, 7, 5, 31, 33, 91, 45, 399, 263, 53, 2723, 7909, 7125, 14795, 0 }; + static ulong[] dim2310KuoInit = { 1, 1, 7, 11, 9, 5, 119, 91, 87, 847, 85, 4025, 1891, 791, 30447, 0 }; + static ulong[] dim2311KuoInit = { 1, 1, 1, 1, 25, 59, 101, 85, 159, 491, 635, 1047, 6221, 11579, 13943, 0 }; + static ulong[] dim2312KuoInit = { 1, 3, 7, 3, 27, 55, 19, 29, 479, 299, 1705, 3505, 6811, 14851, 6827, 0 }; + static ulong[] dim2313KuoInit = { 1, 1, 1, 9, 23, 19, 47, 235, 81, 35, 1297, 2029, 1303, 6877, 30813, 0 }; + static ulong[] dim2314KuoInit = { 1, 3, 1, 11, 21, 37, 49, 209, 93, 439, 2023, 437, 6405, 2407, 10475, 0 }; + static ulong[] dim2315KuoInit = { 1, 1, 3, 3, 5, 51, 11, 127, 339, 419, 1495, 43, 5707, 3905, 331, 0 }; + static ulong[] dim2316KuoInit = { 1, 1, 5, 15, 27, 7, 73, 137, 111, 283, 1017, 1487, 7359, 4921, 3285, 0 }; + static ulong[] dim2317KuoInit = { 1, 1, 1, 9, 3, 23, 123, 75, 317, 517, 109, 2307, 1095, 10309, 27651, 0 }; + static ulong[] dim2318KuoInit = { 1, 3, 1, 1, 21, 55, 5, 115, 483, 379, 1935, 3483, 2485, 1991, 2403, 0 }; + static ulong[] dim2319KuoInit = { 1, 3, 5, 9, 27, 57, 1, 227, 235, 373, 241, 1115, 3037, 6841, 28711, 0 }; + static ulong[] dim2320KuoInit = { 1, 3, 1, 13, 21, 27, 19, 217, 449, 727, 475, 515, 7933, 4401, 5455, 0 }; + static ulong[] dim2321KuoInit = { 1, 3, 5, 13, 27, 3, 117, 67, 293, 625, 1463, 3713, 1271, 11873, 24239, 0 }; + static ulong[] dim2322KuoInit = { 1, 1, 3, 1, 7, 25, 5, 187, 377, 15, 1973, 597, 725, 8809, 2419, 0 }; + static ulong[] dim2323KuoInit = { 1, 1, 7, 13, 7, 9, 89, 41, 443, 921, 17, 3675, 715, 7147, 25345, 0 }; + static ulong[] dim2324KuoInit = { 1, 1, 5, 1, 31, 27, 127, 139, 101, 349, 1551, 1703, 5981, 3259, 31203, 0 }; + static ulong[] dim2325KuoInit = { 1, 1, 1, 5, 31, 59, 1, 149, 111, 947, 1919, 2841, 5383, 6973, 19565, 0 }; + static ulong[] dim2326KuoInit = { 1, 3, 3, 11, 5, 57, 65, 197, 413, 741, 1737, 1333, 5101, 14375, 28969, 0 }; + static ulong[] dim2327KuoInit = { 1, 1, 1, 3, 5, 21, 31, 187, 51, 267, 539, 1305, 4085, 14735, 9441, 0 }; + static ulong[] dim2328KuoInit = { 1, 1, 7, 1, 9, 27, 123, 13, 383, 739, 649, 1253, 4697, 9571, 16983, 0 }; + static ulong[] dim2329KuoInit = { 1, 3, 1, 11, 23, 3, 31, 153, 185, 969, 329, 3919, 3905, 14321, 16535, 0 }; + static ulong[] dim2330KuoInit = { 1, 1, 1, 5, 15, 31, 97, 243, 117, 269, 1545, 1495, 167, 14281, 1369, 0 }; + static ulong[] dim2331KuoInit = { 1, 1, 1, 1, 7, 47, 9, 187, 233, 629, 1981, 2327, 7473, 14641, 31829, 0 }; + static ulong[] dim2332KuoInit = { 1, 1, 1, 11, 11, 43, 117, 193, 395, 501, 1213, 3499, 3369, 817, 22069, 0 }; + static ulong[] dim2333KuoInit = { 1, 3, 7, 1, 13, 63, 67, 67, 119, 371, 1887, 1281, 129, 14277, 5213, 0 }; + static ulong[] dim2334KuoInit = { 1, 3, 1, 11, 11, 57, 47, 149, 119, 547, 389, 1977, 1709, 2335, 7023, 0 }; + static ulong[] dim2335KuoInit = { 1, 1, 7, 7, 15, 41, 19, 57, 279, 737, 29, 2015, 1103, 4933, 26145, 0 }; + static ulong[] dim2336KuoInit = { 1, 3, 1, 1, 23, 61, 17, 1, 309, 637, 809, 3443, 135, 6851, 27321, 0 }; + static ulong[] dim2337KuoInit = { 1, 3, 1, 3, 21, 63, 81, 131, 495, 209, 1901, 2921, 1021, 7207, 22053, 0 }; + static ulong[] dim2338KuoInit = { 1, 1, 7, 9, 7, 63, 1, 119, 329, 553, 1405, 97, 4751, 6955, 20049, 0 }; + static ulong[] dim2339KuoInit = { 1, 3, 7, 15, 1, 59, 99, 201, 487, 271, 2035, 3261, 4953, 15257, 11835, 0 }; + static ulong[] dim2340KuoInit = { 1, 1, 5, 11, 27, 21, 27, 227, 331, 779, 1003, 2291, 7139, 14125, 14371, 0 }; + static ulong[] dim2341KuoInit = { 1, 1, 3, 13, 15, 43, 23, 183, 463, 273, 1707, 2001, 3219, 14481, 751, 0 }; + static ulong[] dim2342KuoInit = { 1, 1, 5, 5, 23, 31, 51, 39, 221, 687, 2003, 1251, 3541, 6347, 551, 0 }; + static ulong[] dim2343KuoInit = { 1, 1, 7, 3, 17, 51, 3, 57, 131, 13, 2027, 3301, 4223, 6499, 30913, 0 }; + static ulong[] dim2344KuoInit = { 1, 1, 7, 13, 11, 47, 53, 205, 59, 315, 1595, 3747, 2623, 7317, 8309, 0 }; + static ulong[] dim2345KuoInit = { 1, 3, 1, 11, 13, 45, 83, 131, 193, 739, 61, 1657, 3789, 9859, 3755, 0 }; + static ulong[] dim2346KuoInit = { 1, 3, 7, 11, 25, 7, 123, 103, 307, 463, 1113, 2245, 2819, 12983, 18077, 0 }; + static ulong[] dim2347KuoInit = { 1, 1, 1, 1, 7, 23, 103, 183, 409, 657, 583, 583, 5449, 7397, 13085, 0 }; + static ulong[] dim2348KuoInit = { 1, 3, 3, 5, 3, 61, 31, 147, 31, 449, 1579, 4021, 1163, 9719, 27079, 0 }; + static ulong[] dim2349KuoInit = { 1, 3, 1, 3, 9, 53, 125, 77, 99, 863, 1719, 51, 4183, 13009, 791, 0 }; + static ulong[] dim2350KuoInit = { 1, 3, 3, 11, 27, 33, 43, 5, 173, 775, 593, 3701, 3323, 6481, 25765, 0 }; + static ulong[] dim2351KuoInit = { 1, 1, 7, 15, 11, 3, 109, 221, 375, 883, 903, 2361, 255, 12851, 16697, 0 }; + static ulong[] dim2352KuoInit = { 1, 1, 5, 9, 3, 61, 127, 89, 213, 71, 303, 2525, 3691, 2945, 12359, 0 }; + static ulong[] dim2353KuoInit = { 1, 3, 1, 13, 19, 15, 7, 231, 159, 275, 1161, 819, 3003, 12707, 20699, 0 }; + static ulong[] dim2354KuoInit = { 1, 1, 3, 1, 31, 51, 125, 21, 27, 427, 941, 237, 4343, 9555, 30511, 0 }; + static ulong[] dim2355KuoInit = { 1, 3, 3, 9, 17, 23, 105, 21, 471, 357, 773, 1185, 2655, 2317, 9969, 0 }; + static ulong[] dim2356KuoInit = { 1, 1, 5, 7, 15, 55, 87, 249, 111, 319, 985, 2305, 1641, 12655, 7321, 0 }; + static ulong[] dim2357KuoInit = { 1, 3, 5, 3, 23, 49, 85, 31, 299, 391, 549, 3831, 1413, 13803, 30599, 0 }; + static ulong[] dim2358KuoInit = { 1, 1, 3, 3, 31, 39, 43, 253, 67, 321, 463, 2327, 6831, 10461, 18077, 0 }; + static ulong[] dim2359KuoInit = { 1, 3, 1, 9, 13, 13, 127, 175, 425, 567, 1663, 195, 1763, 13271, 1739, 0 }; + static ulong[] dim2360KuoInit = { 1, 1, 7, 9, 9, 33, 11, 167, 87, 901, 1625, 2055, 2475, 7241, 29717, 0 }; + static ulong[] dim2361KuoInit = { 1, 1, 1, 1, 15, 63, 127, 29, 227, 817, 637, 1873, 4885, 16299, 31243, 0 }; + static ulong[] dim2362KuoInit = { 1, 3, 7, 3, 17, 27, 81, 237, 283, 161, 1905, 1551, 6171, 4519, 11047, 0 }; + static ulong[] dim2363KuoInit = { 1, 1, 7, 9, 25, 23, 25, 1, 461, 623, 493, 827, 5795, 16065, 8401, 0 }; + static ulong[] dim2364KuoInit = { 1, 3, 5, 11, 29, 29, 91, 133, 91, 565, 1821, 269, 1731, 1499, 7975, 0 }; + static ulong[] dim2365KuoInit = { 1, 1, 1, 13, 3, 41, 99, 23, 239, 945, 219, 1127, 4919, 9713, 3321, 0 }; + static ulong[] dim2366KuoInit = { 1, 3, 1, 11, 25, 59, 59, 127, 83, 643, 881, 1671, 3521, 459, 15479, 0 }; + static ulong[] dim2367KuoInit = { 1, 1, 5, 11, 15, 23, 111, 225, 145, 703, 1643, 419, 4853, 7195, 20879, 0 }; + static ulong[] dim2368KuoInit = { 1, 3, 7, 15, 5, 31, 111, 151, 489, 629, 473, 1507, 117, 15305, 11011, 0 }; + static ulong[] dim2369KuoInit = { 1, 1, 3, 3, 1, 55, 55, 223, 489, 911, 1721, 3533, 5893, 2891, 8929, 0 }; + static ulong[] dim2370KuoInit = { 1, 1, 5, 13, 7, 43, 113, 99, 19, 681, 1765, 1983, 5477, 7531, 26507, 0 }; + static ulong[] dim2371KuoInit = { 1, 1, 3, 1, 9, 7, 77, 231, 345, 745, 285, 3213, 2611, 4449, 24621, 0 }; + static ulong[] dim2372KuoInit = { 1, 1, 5, 1, 21, 21, 3, 11, 131, 327, 1893, 33, 6947, 337, 8877, 0 }; + static ulong[] dim2373KuoInit = { 1, 1, 5, 13, 5, 11, 41, 7, 447, 625, 1231, 3621, 3785, 12351, 13829, 0 }; + static ulong[] dim2374KuoInit = { 1, 3, 1, 13, 29, 41, 11, 63, 357, 723, 1657, 91, 1373, 6383, 8327, 0 }; + static ulong[] dim2375KuoInit = { 1, 3, 3, 15, 23, 51, 85, 113, 103, 499, 1669, 3685, 63, 2853, 20859, 0 }; + static ulong[] dim2376KuoInit = { 1, 1, 5, 11, 31, 39, 15, 103, 365, 231, 443, 3213, 6951, 1715, 32301, 0 }; + static ulong[] dim2377KuoInit = { 1, 3, 7, 5, 19, 23, 13, 127, 475, 281, 1095, 473, 4955, 2217, 10427, 0 }; + static ulong[] dim2378KuoInit = { 1, 1, 5, 13, 17, 41, 47, 121, 131, 69, 1747, 3679, 2765, 4349, 32041, 0 }; + static ulong[] dim2379KuoInit = { 1, 1, 7, 9, 3, 47, 11, 127, 321, 669, 1283, 797, 6393, 12351, 5161, 0 }; + static ulong[] dim2380KuoInit = { 1, 3, 7, 15, 21, 37, 73, 15, 393, 173, 1461, 1437, 2367, 7171, 15123, 0 }; + static ulong[] dim2381KuoInit = { 1, 3, 5, 15, 7, 57, 29, 83, 241, 221, 1607, 1291, 4839, 11293, 1837, 0 }; + static ulong[] dim2382KuoInit = { 1, 3, 5, 7, 1, 31, 59, 143, 487, 317, 535, 1505, 3705, 9947, 6149, 0 }; + static ulong[] dim2383KuoInit = { 1, 3, 1, 3, 29, 31, 69, 63, 183, 173, 1965, 3331, 4473, 993, 4937, 0 }; + static ulong[] dim2384KuoInit = { 1, 1, 1, 15, 13, 13, 55, 43, 283, 897, 1019, 2761, 3237, 14661, 12309, 0 }; + static ulong[] dim2385KuoInit = { 1, 3, 1, 15, 9, 15, 1, 19, 227, 777, 1713, 3471, 2917, 1117, 16397, 0 }; + static ulong[] dim2386KuoInit = { 1, 1, 1, 1, 21, 19, 49, 3, 477, 659, 61, 2373, 6363, 13771, 5675, 0 }; + static ulong[] dim2387KuoInit = { 1, 3, 3, 3, 13, 23, 43, 253, 483, 975, 1629, 19, 6339, 13963, 6065, 0 }; + static ulong[] dim2388KuoInit = { 1, 3, 7, 3, 9, 31, 65, 1, 311, 67, 293, 667, 3685, 3589, 25251, 0 }; + static ulong[] dim2389KuoInit = { 1, 1, 3, 1, 29, 31, 47, 85, 431, 131, 1495, 1271, 6121, 7183, 20477, 0 }; + static ulong[] dim2390KuoInit = { 1, 1, 7, 5, 13, 37, 83, 201, 277, 643, 19, 2519, 2589, 2471, 19727, 0 }; + static ulong[] dim2391KuoInit = { 1, 3, 5, 13, 27, 13, 97, 183, 463, 639, 87, 181, 747, 3715, 16207, 0 }; + static ulong[] dim2392KuoInit = { 1, 1, 7, 3, 9, 29, 21, 191, 485, 211, 541, 69, 511, 9923, 24543, 0 }; + static ulong[] dim2393KuoInit = { 1, 3, 5, 9, 19, 43, 85, 189, 47, 723, 1211, 1259, 1645, 2983, 27195, 0 }; + static ulong[] dim2394KuoInit = { 1, 1, 7, 15, 17, 25, 103, 83, 389, 229, 1457, 4045, 161, 15471, 19929, 0 }; + static ulong[] dim2395KuoInit = { 1, 1, 3, 9, 5, 27, 55, 231, 245, 723, 479, 3761, 787, 12939, 30227, 0 }; + static ulong[] dim2396KuoInit = { 1, 3, 3, 1, 19, 39, 63, 27, 137, 399, 1353, 1143, 5835, 2013, 4107, 0 }; + static ulong[] dim2397KuoInit = { 1, 3, 5, 7, 5, 39, 45, 207, 7, 131, 961, 1715, 3761, 11501, 9803, 0 }; + static ulong[] dim2398KuoInit = { 1, 3, 1, 7, 17, 11, 23, 45, 417, 289, 1545, 2585, 1345, 15529, 8365, 0 }; + static ulong[] dim2399KuoInit = { 1, 1, 1, 7, 21, 27, 97, 23, 461, 983, 997, 1321, 2551, 5485, 23565, 0 }; + static ulong[] dim2400KuoInit = { 1, 1, 5, 5, 23, 19, 77, 103, 171, 553, 1767, 3255, 7955, 249, 32681, 0 }; + static ulong[] dim2401KuoInit = { 1, 1, 7, 1, 23, 43, 73, 15, 381, 245, 1389, 3693, 1975, 13629, 2079, 0 }; + static ulong[] dim2402KuoInit = { 1, 1, 7, 11, 23, 61, 79, 39, 345, 541, 875, 1375, 123, 15305, 13731, 0 }; + static ulong[] dim2403KuoInit = { 1, 1, 3, 15, 3, 17, 19, 11, 79, 415, 1791, 447, 6529, 11243, 10427, 0 }; + static ulong[] dim2404KuoInit = { 1, 1, 7, 15, 9, 31, 121, 247, 403, 935, 705, 2921, 3769, 625, 22905, 0 }; + static ulong[] dim2405KuoInit = { 1, 3, 5, 15, 19, 9, 5, 47, 135, 585, 1155, 1517, 4961, 15725, 7585, 0 }; + static ulong[] dim2406KuoInit = { 1, 3, 3, 7, 19, 57, 37, 69, 117, 485, 115, 2709, 1909, 12781, 19323, 0 }; + static ulong[] dim2407KuoInit = { 1, 1, 1, 5, 7, 1, 37, 39, 141, 1017, 993, 191, 6173, 8083, 9733, 0 }; + static ulong[] dim2408KuoInit = { 1, 1, 7, 3, 3, 21, 17, 55, 129, 353, 673, 3233, 6289, 10955, 19357, 0 }; + static ulong[] dim2409KuoInit = { 1, 3, 7, 11, 31, 31, 31, 105, 187, 839, 733, 1795, 5075, 1053, 613, 0 }; + static ulong[] dim2410KuoInit = { 1, 3, 3, 1, 9, 9, 23, 139, 417, 431, 1943, 3067, 267, 4401, 9847, 0 }; + static ulong[] dim2411KuoInit = { 1, 3, 5, 11, 23, 61, 61, 119, 383, 869, 503, 195, 1935, 4617, 21393, 0 }; + static ulong[] dim2412KuoInit = { 1, 1, 1, 5, 7, 15, 51, 53, 427, 499, 1829, 2533, 3029, 12485, 28425, 0 }; + static ulong[] dim2413KuoInit = { 1, 3, 3, 7, 9, 11, 55, 205, 255, 619, 1323, 1983, 15, 4237, 20983, 0 }; + static ulong[] dim2414KuoInit = { 1, 1, 3, 15, 15, 37, 109, 247, 179, 1005, 1111, 77, 4533, 12849, 25601, 0 }; + static ulong[] dim2415KuoInit = { 1, 1, 5, 3, 15, 25, 59, 117, 55, 755, 681, 649, 6041, 1695, 13719, 0 }; + static ulong[] dim2416KuoInit = { 1, 3, 1, 3, 15, 17, 117, 113, 197, 701, 773, 1097, 1267, 16093, 21555, 0 }; + static ulong[] dim2417KuoInit = { 1, 3, 1, 5, 9, 57, 39, 171, 449, 507, 29, 3581, 1929, 12715, 24575, 0 }; + static ulong[] dim2418KuoInit = { 1, 3, 5, 5, 23, 1, 67, 153, 375, 333, 379, 3163, 8121, 13465, 27641, 0 }; + static ulong[] dim2419KuoInit = { 1, 3, 5, 5, 31, 27, 83, 243, 415, 997, 1787, 4021, 5955, 1861, 10511, 0 }; + static ulong[] dim2420KuoInit = { 1, 3, 1, 3, 13, 47, 69, 169, 185, 645, 1857, 3487, 1557, 9589, 7971, 0 }; + static ulong[] dim2421KuoInit = { 1, 3, 3, 15, 3, 1, 93, 97, 71, 433, 1371, 2495, 8171, 9101, 32435, 0 }; + static ulong[] dim2422KuoInit = { 1, 3, 7, 11, 3, 29, 37, 167, 169, 15, 1575, 1331, 7163, 1555, 32439, 0 }; + static ulong[] dim2423KuoInit = { 1, 1, 5, 1, 29, 11, 83, 135, 367, 37, 1455, 3939, 3383, 5291, 14269, 0 }; + static ulong[] dim2424KuoInit = { 1, 1, 5, 15, 7, 63, 17, 45, 259, 57, 1933, 3101, 7871, 12633, 15789, 0 }; + static ulong[] dim2425KuoInit = { 1, 1, 1, 7, 19, 37, 89, 159, 487, 101, 1551, 3703, 4323, 9153, 6155, 0 }; + static ulong[] dim2426KuoInit = { 1, 3, 3, 13, 15, 49, 81, 51, 267, 761, 863, 2239, 7683, 15491, 28655, 0 }; + static ulong[] dim2427KuoInit = { 1, 3, 1, 1, 25, 53, 113, 117, 11, 1003, 539, 3603, 1007, 11329, 15099, 0 }; + static ulong[] dim2428KuoInit = { 1, 3, 5, 7, 9, 27, 125, 231, 301, 461, 2031, 183, 6361, 10811, 29425, 0 }; + static ulong[] dim2429KuoInit = { 1, 1, 3, 1, 3, 37, 65, 127, 487, 611, 867, 2361, 5243, 11829, 31297, 0 }; + static ulong[] dim2430KuoInit = { 1, 3, 3, 15, 9, 39, 31, 219, 77, 97, 1061, 435, 2449, 14751, 20273, 0 }; + static ulong[] dim2431KuoInit = { 1, 1, 5, 11, 1, 23, 41, 239, 183, 287, 969, 1325, 3553, 6751, 14679, 0 }; + static ulong[] dim2432KuoInit = { 1, 3, 7, 1, 17, 61, 47, 207, 509, 601, 1539, 345, 3723, 5415, 11667, 0 }; + static ulong[] dim2433KuoInit = { 1, 1, 7, 7, 23, 33, 25, 165, 345, 569, 983, 2857, 1563, 1737, 19285, 0 }; + static ulong[] dim2434KuoInit = { 1, 1, 1, 7, 3, 43, 107, 229, 223, 583, 1495, 3487, 7497, 10367, 20575, 0 }; + static ulong[] dim2435KuoInit = { 1, 3, 3, 13, 21, 49, 17, 195, 115, 797, 1489, 1587, 7847, 11013, 14547, 0 }; + static ulong[] dim2436KuoInit = { 1, 3, 5, 11, 9, 29, 19, 245, 153, 779, 1311, 425, 5809, 4457, 6905, 0 }; + static ulong[] dim2437KuoInit = { 1, 1, 5, 3, 21, 33, 13, 193, 343, 971, 1315, 1989, 1969, 9227, 8881, 0 }; + static ulong[] dim2438KuoInit = { 1, 3, 7, 15, 3, 59, 87, 205, 261, 567, 557, 1143, 6923, 9451, 20239, 0 }; + static ulong[] dim2439KuoInit = { 1, 1, 1, 15, 29, 35, 127, 123, 173, 807, 1279, 2413, 1899, 11657, 22257, 0 }; + static ulong[] dim2440KuoInit = { 1, 3, 5, 3, 23, 35, 125, 129, 239, 951, 499, 1609, 4643, 339, 26701, 0 }; + static ulong[] dim2441KuoInit = { 1, 3, 3, 13, 9, 15, 23, 55, 105, 81, 591, 947, 3761, 7351, 25697, 0 }; + static ulong[] dim2442KuoInit = { 1, 1, 7, 13, 23, 17, 127, 149, 227, 1005, 839, 3391, 5761, 10431, 31899, 0 }; + static ulong[] dim2443KuoInit = { 1, 3, 1, 1, 23, 7, 11, 3, 77, 457, 375, 3823, 5447, 8339, 18847, 0 }; + static ulong[] dim2444KuoInit = { 1, 3, 7, 3, 29, 1, 19, 39, 23, 285, 569, 2979, 7029, 11311, 18269, 0 }; + static ulong[] dim2445KuoInit = { 1, 1, 5, 9, 21, 19, 85, 211, 437, 185, 597, 787, 4555, 2853, 18493, 0 }; + static ulong[] dim2446KuoInit = { 1, 3, 3, 9, 11, 27, 25, 245, 55, 869, 323, 3999, 2639, 9385, 26823, 0 }; + static ulong[] dim2447KuoInit = { 1, 3, 1, 7, 19, 61, 51, 111, 115, 721, 893, 23, 6375, 5101, 25567, 0 }; + static ulong[] dim2448KuoInit = { 1, 3, 5, 9, 9, 13, 9, 241, 297, 391, 1529, 3843, 737, 5897, 23469, 0 }; + static ulong[] dim2449KuoInit = { 1, 3, 7, 3, 31, 53, 43, 219, 81, 507, 1627, 3503, 817, 6533, 31633, 0 }; + static ulong[] dim2450KuoInit = { 1, 1, 7, 1, 13, 59, 13, 185, 387, 869, 1013, 2291, 4945, 11493, 7785, 0 }; + static ulong[] dim2451KuoInit = { 1, 3, 5, 9, 31, 35, 11, 225, 235, 893, 1749, 2393, 5317, 10069, 8569, 0 }; + static ulong[] dim2452KuoInit = { 1, 1, 1, 3, 5, 15, 93, 25, 503, 205, 65, 2563, 7971, 2917, 19687, 0 }; + static ulong[] dim2453KuoInit = { 1, 3, 3, 13, 1, 37, 127, 63, 339, 121, 1895, 1943, 7527, 15869, 20533, 0 }; + static ulong[] dim2454KuoInit = { 1, 1, 5, 7, 19, 25, 87, 27, 279, 419, 1261, 613, 7687, 5301, 6761, 0 }; + static ulong[] dim2455KuoInit = { 1, 1, 1, 1, 13, 33, 59, 235, 471, 811, 695, 2727, 5615, 6269, 13469, 0 }; + static ulong[] dim2456KuoInit = { 1, 3, 1, 15, 17, 23, 123, 71, 15, 1005, 973, 411, 2627, 1967, 25597, 0 }; + static ulong[] dim2457KuoInit = { 1, 3, 5, 1, 3, 61, 71, 217, 377, 613, 1819, 141, 6265, 9223, 20635, 0 }; + static ulong[] dim2458KuoInit = { 1, 1, 5, 11, 15, 1, 39, 121, 83, 57, 1133, 3165, 7675, 13715, 11383, 0 }; + static ulong[] dim2459KuoInit = { 1, 3, 7, 15, 9, 3, 97, 223, 493, 77, 159, 2921, 5475, 9289, 20925, 0 }; + static ulong[] dim2460KuoInit = { 1, 1, 3, 7, 29, 13, 87, 219, 327, 879, 883, 1637, 3451, 13939, 8203, 0 }; + static ulong[] dim2461KuoInit = { 1, 3, 7, 15, 25, 21, 95, 129, 343, 9, 1415, 2965, 747, 7297, 24293, 0 }; + static ulong[] dim2462KuoInit = { 1, 1, 1, 3, 23, 47, 57, 31, 359, 1017, 769, 2761, 1933, 6091, 6475, 0 }; + static ulong[] dim2463KuoInit = { 1, 1, 5, 9, 27, 45, 125, 67, 145, 581, 157, 2153, 2727, 8025, 28165, 0 }; + static ulong[] dim2464KuoInit = { 1, 3, 5, 9, 7, 53, 27, 161, 343, 139, 1651, 1275, 2981, 9027, 31175, 0 }; + static ulong[] dim2465KuoInit = { 1, 3, 3, 11, 7, 15, 81, 229, 115, 849, 459, 1651, 3867, 7029, 6741, 0 }; + static ulong[] dim2466KuoInit = { 1, 1, 3, 5, 31, 45, 17, 107, 467, 401, 1473, 1953, 3779, 11237, 31257, 0 }; + static ulong[] dim2467KuoInit = { 1, 3, 3, 11, 3, 27, 45, 217, 133, 515, 1487, 1427, 1999, 12979, 3543, 0 }; + static ulong[] dim2468KuoInit = { 1, 3, 7, 3, 17, 31, 123, 205, 263, 963, 1697, 2453, 1249, 603, 8581, 0 }; + static ulong[] dim2469KuoInit = { 1, 3, 1, 15, 23, 9, 23, 251, 489, 393, 1103, 3273, 5703, 3033, 22631, 0 }; + static ulong[] dim2470KuoInit = { 1, 3, 3, 13, 23, 29, 49, 233, 461, 795, 991, 3695, 4715, 7211, 3695, 0 }; + static ulong[] dim2471KuoInit = { 1, 3, 3, 15, 21, 11, 33, 69, 347, 535, 25, 3465, 2825, 9345, 4485, 0 }; + static ulong[] dim2472KuoInit = { 1, 3, 7, 3, 23, 47, 65, 209, 357, 363, 1979, 289, 35, 4459, 17929, 0 }; + static ulong[] dim2473KuoInit = { 1, 3, 1, 11, 19, 17, 125, 231, 221, 953, 2041, 2359, 5925, 15693, 30859, 0 }; + static ulong[] dim2474KuoInit = { 1, 1, 3, 13, 31, 11, 11, 215, 335, 153, 1459, 2303, 3471, 7415, 3783, 0 }; + static ulong[] dim2475KuoInit = { 1, 1, 7, 5, 11, 55, 47, 43, 355, 469, 963, 383, 667, 2233, 27759, 0 }; + static ulong[] dim2476KuoInit = { 1, 3, 1, 9, 23, 29, 27, 135, 359, 111, 387, 3021, 817, 4211, 17243, 0 }; + static ulong[] dim2477KuoInit = { 1, 1, 3, 9, 25, 27, 63, 89, 195, 359, 413, 3509, 3831, 4785, 30097, 0 }; + static ulong[] dim2478KuoInit = { 1, 1, 5, 5, 11, 29, 29, 25, 445, 643, 261, 3901, 3019, 14213, 16115, 0 }; + static ulong[] dim2479KuoInit = { 1, 3, 3, 15, 21, 31, 7, 255, 207, 535, 1033, 1017, 3791, 11455, 31701, 0 }; + static ulong[] dim2480KuoInit = { 1, 3, 5, 13, 15, 37, 79, 205, 439, 609, 1433, 3333, 6583, 9689, 14979, 0 }; + static ulong[] dim2481KuoInit = { 1, 1, 7, 3, 31, 27, 53, 101, 427, 773, 1877, 1715, 6177, 11851, 17989, 0 }; + static ulong[] dim2482KuoInit = { 1, 3, 1, 3, 21, 11, 101, 203, 49, 543, 1979, 1469, 6701, 9963, 7793, 0 }; + static ulong[] dim2483KuoInit = { 1, 1, 3, 1, 15, 47, 123, 141, 433, 783, 211, 1489, 4983, 6417, 29767, 0 }; + static ulong[] dim2484KuoInit = { 1, 1, 5, 3, 1, 41, 109, 13, 465, 959, 431, 543, 4681, 8573, 7889, 0 }; + static ulong[] dim2485KuoInit = { 1, 1, 1, 3, 15, 43, 15, 63, 145, 859, 939, 629, 7077, 5617, 16779, 0 }; + static ulong[] dim2486KuoInit = { 1, 3, 3, 1, 23, 63, 67, 139, 219, 257, 943, 1501, 827, 10855, 10035, 0 }; + static ulong[] dim2487KuoInit = { 1, 3, 1, 15, 9, 47, 27, 119, 231, 767, 999, 3553, 7683, 5399, 11553, 0 }; + static ulong[] dim2488KuoInit = { 1, 3, 3, 11, 15, 13, 35, 139, 463, 985, 553, 3997, 2935, 7707, 2511, 0 }; + static ulong[] dim2489KuoInit = { 1, 1, 3, 11, 23, 53, 103, 1, 409, 853, 737, 2077, 523, 1839, 32145, 0 }; + static ulong[] dim2490KuoInit = { 1, 3, 1, 15, 23, 7, 77, 185, 371, 447, 499, 569, 6647, 501, 27649, 0 }; + static ulong[] dim2491KuoInit = { 1, 1, 3, 5, 19, 31, 119, 157, 385, 427, 1411, 4031, 4199, 14567, 8133, 0 }; + static ulong[] dim2492KuoInit = { 1, 3, 7, 5, 31, 3, 123, 149, 209, 467, 1619, 879, 5949, 7295, 25165, 0 }; + static ulong[] dim2493KuoInit = { 1, 3, 1, 15, 31, 47, 111, 129, 359, 385, 463, 3363, 6823, 10751, 4473, 0 }; + static ulong[] dim2494KuoInit = { 1, 3, 3, 7, 5, 39, 71, 45, 439, 161, 597, 2093, 1725, 11285, 18149, 0 }; + static ulong[] dim2495KuoInit = { 1, 3, 3, 7, 21, 55, 115, 199, 339, 425, 71, 305, 1161, 3359, 16835, 0 }; + static ulong[] dim2496KuoInit = { 1, 1, 7, 7, 1, 53, 51, 31, 57, 581, 147, 903, 7269, 1461, 7417, 0 }; + static ulong[] dim2497KuoInit = { 1, 3, 7, 3, 17, 31, 65, 195, 47, 575, 1877, 1603, 3043, 5385, 15177, 0 }; + static ulong[] dim2498KuoInit = { 1, 1, 3, 11, 15, 7, 121, 51, 67, 391, 1553, 1817, 6503, 2907, 3611, 0 }; + static ulong[] dim2499KuoInit = { 1, 1, 1, 9, 13, 51, 95, 19, 315, 549, 1417, 2073, 485, 5257, 32419, 0 }; + static ulong[] dim2500KuoInit = { 1, 3, 1, 9, 31, 63, 107, 103, 173, 681, 211, 3283, 2413, 2073, 24497, 0 }; + static ulong[] dim2501KuoInit = { 1, 3, 1, 7, 3, 41, 49, 81, 289, 177, 699, 1305, 7867, 4699, 27669, 0 }; + static ulong[] dim2502KuoInit = { 1, 1, 5, 3, 7, 15, 73, 57, 319, 959, 701, 2071, 1587, 4701, 2595, 0 }; + static ulong[] dim2503KuoInit = { 1, 1, 5, 7, 7, 1, 29, 129, 361, 619, 1405, 2185, 6631, 3505, 391, 0 }; + static ulong[] dim2504KuoInit = { 1, 3, 3, 5, 19, 9, 31, 63, 149, 181, 299, 2755, 1511, 5745, 20323, 0 }; + static ulong[] dim2505KuoInit = { 1, 1, 3, 11, 23, 5, 29, 175, 119, 25, 319, 835, 1339, 5429, 7175, 0 }; + static ulong[] dim2506KuoInit = { 1, 1, 3, 3, 31, 57, 55, 181, 473, 229, 309, 1567, 5063, 9745, 3713, 0 }; + static ulong[] dim2507KuoInit = { 1, 3, 3, 13, 1, 15, 23, 175, 71, 53, 1749, 743, 285, 49, 7389, 0 }; + static ulong[] dim2508KuoInit = { 1, 3, 1, 5, 7, 39, 75, 177, 259, 975, 257, 1497, 1565, 6973, 3827, 0 }; + static ulong[] dim2509KuoInit = { 1, 3, 7, 13, 1, 39, 43, 213, 291, 941, 613, 3041, 1859, 10755, 29831, 0 }; + static ulong[] dim2510KuoInit = { 1, 3, 3, 9, 17, 43, 15, 135, 473, 989, 429, 3287, 3699, 14349, 16311, 0 }; + static ulong[] dim2511KuoInit = { 1, 3, 1, 15, 1, 51, 59, 203, 383, 731, 171, 1259, 5833, 12029, 18099, 0 }; + static ulong[] dim2512KuoInit = { 1, 3, 1, 3, 19, 63, 125, 57, 429, 93, 1179, 2707, 449, 2213, 4759, 0 }; + static ulong[] dim2513KuoInit = { 1, 1, 7, 3, 19, 11, 107, 127, 359, 759, 503, 761, 6817, 15343, 13777, 0 }; + static ulong[] dim2514KuoInit = { 1, 1, 1, 7, 21, 49, 67, 179, 241, 403, 769, 3341, 1845, 2855, 3825, 0 }; + static ulong[] dim2515KuoInit = { 1, 3, 3, 3, 7, 29, 71, 35, 389, 297, 673, 1353, 6781, 5633, 12459, 0 }; + static ulong[] dim2516KuoInit = { 1, 1, 1, 15, 13, 15, 11, 57, 143, 35, 809, 2295, 6497, 455, 23689, 0 }; + static ulong[] dim2517KuoInit = { 1, 3, 7, 15, 23, 39, 39, 211, 335, 537, 1569, 3989, 5777, 12951, 22841, 0 }; + static ulong[] dim2518KuoInit = { 1, 1, 7, 3, 23, 17, 107, 237, 241, 533, 57, 3421, 263, 889, 28841, 0 }; + static ulong[] dim2519KuoInit = { 1, 1, 5, 1, 11, 29, 17, 141, 431, 809, 1227, 2835, 2955, 11823, 23061, 0 }; + static ulong[] dim2520KuoInit = { 1, 1, 3, 9, 5, 51, 73, 43, 75, 985, 1665, 1369, 519, 6379, 8665, 0 }; + static ulong[] dim2521KuoInit = { 1, 3, 3, 13, 17, 21, 9, 173, 333, 689, 277, 1755, 5173, 7651, 30597, 0 }; + static ulong[] dim2522KuoInit = { 1, 3, 5, 9, 3, 59, 59, 221, 177, 819, 1483, 1945, 4725, 4821, 3709, 0 }; + static ulong[] dim2523KuoInit = { 1, 1, 7, 7, 19, 35, 93, 47, 49, 861, 561, 753, 8047, 419, 4335, 0 }; + static ulong[] dim2524KuoInit = { 1, 3, 3, 15, 31, 3, 97, 177, 443, 55, 1541, 2627, 6129, 4165, 3079, 0 }; + static ulong[] dim2525KuoInit = { 1, 1, 1, 9, 13, 13, 13, 29, 309, 679, 1893, 3629, 513, 16333, 25371, 0 }; + static ulong[] dim2526KuoInit = { 1, 3, 1, 5, 3, 23, 85, 169, 143, 537, 1387, 3997, 3659, 12107, 11689, 0 }; + static ulong[] dim2527KuoInit = { 1, 1, 1, 5, 9, 7, 11, 59, 325, 855, 1853, 855, 5743, 7625, 10381, 0 }; + static ulong[] dim2528KuoInit = { 1, 3, 3, 3, 5, 37, 109, 101, 243, 301, 1849, 1633, 4451, 8859, 22017, 0 }; + static ulong[] dim2529KuoInit = { 1, 3, 5, 1, 7, 1, 9, 1, 411, 941, 153, 2709, 389, 9403, 24103, 0 }; + static ulong[] dim2530KuoInit = { 1, 1, 1, 15, 17, 19, 105, 127, 271, 543, 449, 1385, 7387, 8335, 741, 0 }; + static ulong[] dim2531KuoInit = { 1, 3, 7, 5, 23, 21, 43, 17, 357, 499, 649, 1121, 7655, 15623, 12975, 0 }; + static ulong[] dim2532KuoInit = { 1, 1, 5, 5, 1, 57, 37, 91, 159, 1013, 653, 3371, 4857, 441, 17729, 0 }; + static ulong[] dim2533KuoInit = { 1, 3, 7, 15, 15, 31, 71, 77, 113, 47, 1597, 43, 1139, 3191, 31775, 0 }; + static ulong[] dim2534KuoInit = { 1, 1, 1, 13, 19, 39, 93, 15, 433, 867, 1091, 2333, 6113, 13005, 13309, 0 }; + static ulong[] dim2535KuoInit = { 1, 1, 1, 9, 5, 57, 21, 7, 267, 79, 1829, 43, 211, 2795, 18739, 0 }; + static ulong[] dim2536KuoInit = { 1, 1, 5, 13, 25, 59, 93, 213, 23, 281, 625, 439, 1449, 2259, 31713, 0 }; + static ulong[] dim2537KuoInit = { 1, 1, 1, 3, 9, 13, 41, 171, 365, 907, 395, 3465, 6433, 33, 17191, 0 }; + static ulong[] dim2538KuoInit = { 1, 1, 1, 5, 3, 41, 45, 55, 413, 579, 1215, 3983, 1201, 3019, 16401, 0 }; + static ulong[] dim2539KuoInit = { 1, 1, 3, 3, 9, 25, 111, 33, 359, 427, 63, 4005, 2753, 15063, 1925, 0 }; + static ulong[] dim2540KuoInit = { 1, 1, 5, 3, 21, 55, 15, 5, 121, 867, 1645, 2387, 1167, 13865, 15899, 0 }; + static ulong[] dim2541KuoInit = { 1, 3, 5, 15, 13, 49, 9, 173, 291, 517, 143, 399, 7545, 7225, 29753, 0 }; + static ulong[] dim2542KuoInit = { 1, 1, 3, 5, 29, 23, 105, 165, 35, 325, 983, 215, 2537, 8661, 1715, 0 }; + static ulong[] dim2543KuoInit = { 1, 3, 7, 7, 19, 1, 91, 77, 311, 715, 347, 1705, 1045, 15003, 10961, 0 }; + static ulong[] dim2544KuoInit = { 1, 1, 1, 15, 5, 3, 73, 159, 113, 201, 257, 181, 551, 1189, 30719, 0 }; + static ulong[] dim2545KuoInit = { 1, 1, 1, 3, 15, 57, 69, 85, 133, 735, 429, 2087, 1453, 14277, 15245, 0 }; + static ulong[] dim2546KuoInit = { 1, 3, 1, 1, 27, 5, 27, 247, 401, 841, 1723, 3717, 3545, 3123, 27441, 0 }; + static ulong[] dim2547KuoInit = { 1, 3, 1, 15, 5, 11, 97, 117, 331, 843, 1101, 2977, 5123, 5761, 2019, 0 }; + static ulong[] dim2548KuoInit = { 1, 3, 1, 5, 31, 25, 53, 191, 265, 961, 1695, 1847, 6377, 13261, 8853, 0 }; + static ulong[] dim2549KuoInit = { 1, 3, 1, 5, 5, 29, 85, 3, 127, 407, 1511, 549, 4015, 15327, 9167, 0 }; + static ulong[] dim2550KuoInit = { 1, 3, 5, 3, 9, 11, 1, 217, 53, 201, 1237, 2663, 7429, 7349, 5619, 0 }; + static ulong[] dim2551KuoInit = { 1, 3, 3, 15, 13, 63, 21, 173, 59, 881, 351, 1285, 7155, 6665, 25117, 0 }; + static ulong[] dim2552KuoInit = { 1, 1, 3, 3, 3, 43, 103, 227, 397, 75, 1211, 2959, 3507, 3105, 21739, 0 }; + static ulong[] dim2553KuoInit = { 1, 1, 3, 11, 1, 1, 5, 3, 41, 243, 1317, 2205, 4079, 7447, 22493, 0 }; + static ulong[] dim2554KuoInit = { 1, 3, 1, 3, 7, 39, 23, 171, 263, 375, 805, 2309, 7123, 4935, 4517, 0 }; + static ulong[] dim2555KuoInit = { 1, 1, 5, 15, 5, 47, 35, 15, 131, 875, 1771, 3001, 951, 14269, 6395, 0 }; + static ulong[] dim2556KuoInit = { 1, 1, 3, 9, 27, 1, 59, 247, 295, 229, 309, 213, 6661, 10415, 17855, 0 }; + static ulong[] dim2557KuoInit = { 1, 3, 5, 1, 15, 61, 47, 175, 279, 221, 1665, 3475, 4171, 15515, 30835, 0 }; + static ulong[] dim2558KuoInit = { 1, 3, 3, 15, 29, 21, 61, 123, 57, 839, 399, 3069, 4617, 7051, 3245, 0 }; + static ulong[] dim2559KuoInit = { 1, 3, 7, 11, 27, 57, 83, 163, 499, 901, 855, 2049, 2993, 10323, 3391, 0 }; + static ulong[] dim2560KuoInit = { 1, 1, 7, 5, 17, 5, 23, 51, 445, 639, 811, 139, 2863, 9447, 25971, 0 }; + static ulong[] dim2561KuoInit = { 1, 3, 3, 13, 31, 43, 75, 251, 9, 239, 1573, 871, 2211, 15057, 879, 0 }; + static ulong[] dim2562KuoInit = { 1, 1, 5, 11, 23, 39, 69, 79, 335, 729, 1807, 1497, 2363, 8713, 3987, 0 }; + static ulong[] dim2563KuoInit = { 1, 3, 5, 11, 27, 9, 1, 5, 207, 217, 1097, 2737, 6815, 9969, 21731, 0 }; + static ulong[] dim2564KuoInit = { 1, 3, 3, 15, 9, 33, 71, 85, 15, 323, 1955, 1299, 4439, 6413, 23055, 0 }; + static ulong[] dim2565KuoInit = { 1, 3, 5, 13, 15, 11, 75, 201, 5, 69, 1067, 2287, 8099, 11293, 22547, 0 }; + static ulong[] dim2566KuoInit = { 1, 3, 1, 7, 19, 1, 63, 195, 463, 463, 1741, 915, 1289, 11275, 16383, 0 }; + static ulong[] dim2567KuoInit = { 1, 1, 7, 3, 3, 53, 51, 95, 389, 385, 1621, 955, 137, 8523, 24087, 0 }; + static ulong[] dim2568KuoInit = { 1, 3, 5, 11, 25, 27, 49, 27, 459, 979, 277, 2917, 6639, 3471, 20407, 0 }; + static ulong[] dim2569KuoInit = { 1, 1, 5, 3, 19, 25, 75, 47, 395, 269, 1445, 287, 4563, 8817, 10645, 0 }; + static ulong[] dim2570KuoInit = { 1, 1, 1, 15, 5, 9, 59, 177, 463, 683, 1917, 1189, 2423, 6967, 433, 0 }; + static ulong[] dim2571KuoInit = { 1, 3, 5, 7, 11, 53, 101, 81, 89, 419, 1605, 3719, 5449, 4303, 11235, 0 }; + static ulong[] dim2572KuoInit = { 1, 1, 7, 15, 7, 55, 5, 133, 273, 757, 313, 3451, 7837, 14543, 1607, 0 }; + static ulong[] dim2573KuoInit = { 1, 3, 7, 11, 9, 13, 103, 95, 301, 637, 1951, 2577, 2571, 7881, 27057, 0 }; + static ulong[] dim2574KuoInit = { 1, 3, 3, 9, 25, 17, 119, 11, 7, 141, 1219, 3091, 1737, 16355, 2807, 0 }; + static ulong[] dim2575KuoInit = { 1, 1, 1, 1, 3, 55, 59, 193, 23, 643, 159, 3393, 2671, 14737, 21193, 0 }; + static ulong[] dim2576KuoInit = { 1, 3, 5, 9, 9, 11, 109, 227, 333, 861, 915, 3239, 6199, 9555, 28563, 0 }; + static ulong[] dim2577KuoInit = { 1, 3, 3, 9, 1, 33, 51, 169, 291, 159, 1983, 173, 4133, 11477, 31525, 0 }; + static ulong[] dim2578KuoInit = { 1, 3, 5, 5, 31, 39, 47, 195, 421, 949, 311, 1537, 8009, 6273, 10893, 0 }; + static ulong[] dim2579KuoInit = { 1, 1, 1, 1, 17, 19, 37, 211, 245, 553, 769, 2131, 2819, 16119, 25851, 0 }; + static ulong[] dim2580KuoInit = { 1, 3, 3, 13, 7, 3, 63, 141, 465, 367, 949, 3997, 5217, 3425, 31161, 0 }; + static ulong[] dim2581KuoInit = { 1, 3, 3, 5, 19, 35, 91, 115, 153, 127, 231, 3723, 7911, 4421, 2271, 0 }; + static ulong[] dim2582KuoInit = { 1, 3, 5, 9, 17, 57, 49, 151, 263, 89, 1635, 2991, 7011, 13243, 1473, 0 }; + static ulong[] dim2583KuoInit = { 1, 1, 1, 15, 21, 59, 53, 179, 113, 839, 649, 2083, 7015, 5507, 9539, 0 }; + static ulong[] dim2584KuoInit = { 1, 1, 1, 1, 13, 49, 97, 81, 255, 973, 275, 2005, 5493, 11019, 14427, 0 }; + static ulong[] dim2585KuoInit = { 1, 1, 7, 5, 5, 53, 27, 197, 269, 699, 285, 3725, 7681, 3767, 11881, 0 }; + static ulong[] dim2586KuoInit = { 1, 1, 1, 13, 15, 15, 11, 245, 419, 559, 727, 1545, 1821, 5655, 26971, 0 }; + static ulong[] dim2587KuoInit = { 1, 1, 3, 3, 5, 1, 77, 211, 139, 949, 1945, 3327, 6699, 6227, 9769, 0 }; + static ulong[] dim2588KuoInit = { 1, 3, 1, 1, 3, 9, 113, 17, 283, 939, 1941, 19, 7431, 14503, 24541, 0 }; + static ulong[] dim2589KuoInit = { 1, 1, 1, 3, 1, 57, 17, 85, 371, 491, 775, 2093, 5615, 4977, 30995, 0 }; + static ulong[] dim2590KuoInit = { 1, 1, 3, 3, 1, 61, 75, 163, 307, 527, 1821, 1291, 5761, 9983, 4647, 0 }; + static ulong[] dim2591KuoInit = { 1, 1, 1, 13, 7, 61, 9, 203, 255, 293, 1683, 1081, 3179, 13283, 13759, 0 }; + static ulong[] dim2592KuoInit = { 1, 1, 5, 5, 5, 25, 23, 97, 37, 277, 1787, 2709, 6201, 8041, 2301, 0 }; + static ulong[] dim2593KuoInit = { 1, 3, 1, 1, 21, 57, 33, 13, 307, 427, 1577, 2043, 8131, 11723, 14353, 0 }; + static ulong[] dim2594KuoInit = { 1, 1, 3, 5, 19, 39, 63, 11, 139, 173, 517, 1597, 3871, 15533, 4123, 0 }; + static ulong[] dim2595KuoInit = { 1, 3, 1, 11, 19, 43, 123, 127, 237, 599, 893, 3645, 947, 12565, 9367, 0 }; + static ulong[] dim2596KuoInit = { 1, 1, 7, 11, 27, 9, 119, 251, 499, 777, 1667, 1699, 3431, 2727, 7097, 0 }; + static ulong[] dim2597KuoInit = { 1, 1, 1, 11, 7, 25, 95, 143, 319, 659, 1567, 1391, 5149, 15177, 6583, 0 }; + static ulong[] dim2598KuoInit = { 1, 3, 1, 13, 7, 39, 125, 219, 405, 739, 1267, 3065, 7529, 3195, 21889, 0 }; + static ulong[] dim2599KuoInit = { 1, 3, 3, 9, 27, 13, 87, 129, 451, 997, 103, 1667, 545, 6341, 3105, 0 }; + static ulong[] dim2600KuoInit = { 1, 1, 5, 3, 11, 43, 95, 205, 445, 919, 1353, 2435, 269, 3221, 8983, 0 }; + static ulong[] dim2601KuoInit = { 1, 1, 3, 1, 5, 47, 15, 127, 47, 89, 1409, 1935, 2047, 10629, 4867, 0 }; + static ulong[] dim2602KuoInit = { 1, 1, 5, 9, 21, 51, 31, 175, 337, 643, 1233, 1049, 569, 3383, 18771, 0 }; + static ulong[] dim2603KuoInit = { 1, 1, 7, 11, 7, 7, 29, 139, 65, 621, 363, 513, 4149, 5225, 11595, 0 }; + static ulong[] dim2604KuoInit = { 1, 1, 7, 7, 11, 31, 43, 223, 249, 661, 123, 2725, 5179, 13237, 10483, 0 }; + static ulong[] dim2605KuoInit = { 1, 1, 5, 3, 5, 35, 121, 193, 33, 343, 413, 1879, 8013, 11161, 7945, 0 }; + static ulong[] dim2606KuoInit = { 1, 3, 7, 5, 27, 43, 123, 25, 45, 279, 979, 1121, 1041, 3757, 22217, 0 }; + static ulong[] dim2607KuoInit = { 1, 3, 5, 1, 29, 45, 29, 215, 39, 679, 799, 1491, 885, 15475, 29269, 0 }; + static ulong[] dim2608KuoInit = { 1, 1, 3, 1, 1, 5, 49, 181, 441, 691, 639, 859, 2785, 3237, 1703, 0 }; + static ulong[] dim2609KuoInit = { 1, 1, 1, 9, 19, 1, 41, 131, 469, 999, 1665, 2309, 4447, 13851, 7063, 0 }; + static ulong[] dim2610KuoInit = { 1, 3, 5, 3, 21, 53, 51, 155, 41, 43, 127, 1653, 6237, 10481, 22557, 0 }; + static ulong[] dim2611KuoInit = { 1, 3, 5, 7, 31, 21, 39, 177, 283, 535, 771, 3783, 3033, 10971, 8691, 0 }; + static ulong[] dim2612KuoInit = { 1, 1, 3, 1, 25, 57, 13, 139, 169, 717, 795, 2337, 7347, 6951, 20509, 0 }; + static ulong[] dim2613KuoInit = { 1, 1, 5, 11, 1, 29, 27, 21, 259, 889, 83, 3295, 3699, 1523, 6227, 0 }; + static ulong[] dim2614KuoInit = { 1, 3, 5, 3, 9, 37, 35, 95, 217, 335, 865, 3093, 3077, 9831, 12173, 0 }; + static ulong[] dim2615KuoInit = { 1, 1, 7, 13, 31, 7, 69, 193, 459, 967, 481, 3271, 677, 13131, 22665, 0 }; + static ulong[] dim2616KuoInit = { 1, 3, 3, 9, 13, 31, 43, 155, 465, 303, 1153, 1591, 7793, 921, 12805, 0 }; + static ulong[] dim2617KuoInit = { 1, 1, 5, 5, 23, 59, 3, 151, 391, 729, 913, 899, 1793, 10173, 19681, 0 }; + static ulong[] dim2618KuoInit = { 1, 3, 1, 5, 31, 21, 19, 219, 311, 1013, 227, 1813, 3103, 14191, 22995, 0 }; + static ulong[] dim2619KuoInit = { 1, 1, 3, 5, 3, 59, 11, 191, 433, 63, 465, 3505, 6801, 3047, 16913, 0 }; + static ulong[] dim2620KuoInit = { 1, 1, 7, 9, 19, 3, 95, 203, 1, 679, 1719, 269, 1747, 9465, 24445, 0 }; + static ulong[] dim2621KuoInit = { 1, 1, 7, 9, 9, 17, 79, 45, 179, 863, 801, 2825, 5345, 637, 9729, 0 }; + static ulong[] dim2622KuoInit = { 1, 3, 7, 11, 11, 59, 45, 107, 45, 891, 629, 443, 805, 15277, 1961, 0 }; + static ulong[] dim2623KuoInit = { 1, 1, 3, 5, 9, 49, 123, 183, 13, 867, 261, 3883, 2479, 8221, 3327, 0 }; + static ulong[] dim2624KuoInit = { 1, 1, 5, 11, 19, 19, 95, 85, 351, 861, 1499, 3697, 7369, 10757, 16445, 0 }; + static ulong[] dim2625KuoInit = { 1, 3, 5, 5, 27, 13, 119, 243, 437, 655, 955, 1919, 3643, 12389, 6865, 0 }; + static ulong[] dim2626KuoInit = { 1, 3, 3, 1, 23, 15, 43, 65, 87, 833, 503, 999, 703, 4411, 3343, 0 }; + static ulong[] dim2627KuoInit = { 1, 3, 7, 1, 31, 13, 67, 199, 261, 257, 1767, 3983, 823, 149, 32353, 0 }; + static ulong[] dim2628KuoInit = { 1, 3, 1, 15, 15, 17, 69, 237, 441, 657, 1125, 3377, 5971, 15477, 31363, 0 }; + static ulong[] dim2629KuoInit = { 1, 3, 1, 13, 3, 55, 67, 93, 315, 1015, 61, 35, 3059, 15503, 16811, 0 }; + static ulong[] dim2630KuoInit = { 1, 1, 3, 9, 1, 51, 91, 213, 3, 37, 849, 2329, 2237, 6189, 625, 0 }; + static ulong[] dim2631KuoInit = { 1, 1, 5, 7, 25, 3, 57, 103, 401, 357, 461, 2677, 6059, 291, 11461, 0 }; + static ulong[] dim2632KuoInit = { 1, 1, 5, 7, 23, 29, 119, 61, 121, 535, 251, 565, 7307, 1085, 8429, 0 }; + static ulong[] dim2633KuoInit = { 1, 1, 3, 13, 23, 19, 63, 155, 5, 617, 9, 715, 5399, 1747, 17633, 0 }; + static ulong[] dim2634KuoInit = { 1, 1, 1, 13, 3, 57, 13, 161, 123, 389, 1695, 4083, 1957, 11359, 18961, 0 }; + static ulong[] dim2635KuoInit = { 1, 1, 3, 15, 27, 25, 65, 15, 205, 695, 995, 1471, 1131, 11435, 22107, 0 }; + static ulong[] dim2636KuoInit = { 1, 3, 3, 11, 31, 29, 109, 121, 81, 15, 1087, 299, 3495, 14137, 19073, 0 }; + static ulong[] dim2637KuoInit = { 1, 3, 3, 15, 23, 23, 117, 55, 215, 287, 1421, 731, 279, 15497, 15545, 0 }; + static ulong[] dim2638KuoInit = { 1, 3, 5, 15, 1, 31, 95, 249, 403, 239, 771, 1279, 1863, 12893, 21043, 0 }; + static ulong[] dim2639KuoInit = { 1, 3, 1, 9, 21, 23, 123, 169, 69, 591, 621, 1697, 5867, 5193, 16573, 0 }; + static ulong[] dim2640KuoInit = { 1, 3, 3, 5, 29, 19, 105, 177, 143, 141, 1455, 3119, 347, 8797, 3925, 0 }; + static ulong[] dim2641KuoInit = { 1, 3, 3, 15, 9, 11, 41, 169, 141, 555, 1761, 3441, 2245, 14205, 9769, 0 }; + static ulong[] dim2642KuoInit = { 1, 1, 1, 5, 9, 33, 125, 203, 333, 461, 551, 569, 1305, 10213, 24549, 0 }; + static ulong[] dim2643KuoInit = { 1, 1, 7, 13, 21, 9, 99, 43, 395, 667, 121, 1225, 7835, 8327, 17717, 0 }; + static ulong[] dim2644KuoInit = { 1, 3, 3, 7, 21, 9, 31, 59, 321, 505, 1357, 3213, 4219, 10637, 11127, 0 }; + static ulong[] dim2645KuoInit = { 1, 1, 1, 7, 17, 49, 77, 243, 189, 115, 1339, 2023, 7431, 5087, 24495, 0 }; + static ulong[] dim2646KuoInit = { 1, 1, 1, 11, 1, 39, 41, 51, 315, 383, 237, 3877, 5731, 11, 21307, 0 }; + static ulong[] dim2647KuoInit = { 1, 1, 7, 5, 5, 3, 17, 227, 483, 395, 1251, 1265, 3965, 15203, 17163, 0 }; + static ulong[] dim2648KuoInit = { 1, 3, 7, 7, 23, 41, 53, 45, 43, 989, 629, 1557, 2891, 4613, 3647, 0 }; + static ulong[] dim2649KuoInit = { 1, 3, 3, 5, 15, 39, 35, 127, 267, 45, 1299, 2251, 7363, 13595, 31061, 0 }; + static ulong[] dim2650KuoInit = { 1, 3, 7, 15, 23, 45, 99, 153, 419, 727, 1077, 3407, 4861, 3697, 14479, 0 }; + static ulong[] dim2651KuoInit = { 1, 3, 5, 15, 19, 21, 123, 173, 295, 47, 1977, 1185, 7403, 11901, 29753, 0 }; + static ulong[] dim2652KuoInit = { 1, 1, 3, 13, 21, 53, 83, 151, 309, 293, 439, 2381, 7965, 3449, 8861, 0 }; + static ulong[] dim2653KuoInit = { 1, 1, 1, 3, 31, 49, 61, 81, 327, 173, 111, 3893, 2621, 1409, 13255, 0 }; + static ulong[] dim2654KuoInit = { 1, 3, 5, 5, 3, 13, 75, 71, 271, 689, 369, 2719, 759, 8691, 24611, 0 }; + static ulong[] dim2655KuoInit = { 1, 1, 1, 5, 21, 7, 69, 17, 347, 699, 1581, 1095, 1727, 8213, 5033, 0 }; + static ulong[] dim2656KuoInit = { 1, 1, 1, 1, 23, 41, 85, 233, 43, 863, 553, 2625, 2323, 7471, 12457, 0 }; + static ulong[] dim2657KuoInit = { 1, 1, 3, 15, 3, 7, 99, 27, 173, 539, 113, 2309, 1771, 11709, 29703, 0 }; + static ulong[] dim2658KuoInit = { 1, 3, 1, 1, 7, 43, 73, 91, 151, 961, 251, 2089, 4475, 2745, 6077, 0 }; + static ulong[] dim2659KuoInit = { 1, 1, 3, 7, 15, 61, 91, 139, 161, 613, 603, 1587, 3995, 9241, 24467, 0 }; + static ulong[] dim2660KuoInit = { 1, 1, 1, 3, 1, 21, 7, 157, 311, 451, 137, 3289, 5583, 5107, 24471, 0 }; + static ulong[] dim2661KuoInit = { 1, 1, 7, 9, 15, 3, 7, 19, 375, 265, 1781, 335, 233, 3569, 21407, 0 }; + static ulong[] dim2662KuoInit = { 1, 1, 5, 13, 7, 53, 81, 79, 355, 89, 1233, 267, 6523, 8819, 30595, 0 }; + static ulong[] dim2663KuoInit = { 1, 1, 7, 7, 1, 59, 65, 93, 251, 565, 1575, 2709, 7845, 13355, 6043, 0 }; + static ulong[] dim2664KuoInit = { 1, 1, 5, 7, 9, 21, 71, 97, 383, 189, 3, 1841, 1403, 9649, 25053, 0 }; + static ulong[] dim2665KuoInit = { 1, 3, 5, 9, 25, 47, 41, 63, 177, 551, 1389, 1639, 4209, 15787, 26499, 0 }; + static ulong[] dim2666KuoInit = { 1, 1, 3, 15, 29, 53, 119, 3, 33, 677, 207, 1239, 453, 6281, 26701, 0 }; + static ulong[] dim2667KuoInit = { 1, 3, 5, 13, 7, 37, 87, 241, 477, 765, 1511, 2659, 1043, 313, 27957, 0 }; + static ulong[] dim2668KuoInit = { 1, 3, 5, 3, 1, 31, 101, 27, 401, 547, 617, 3605, 4899, 5093, 19933, 0 }; + static ulong[] dim2669KuoInit = { 1, 1, 7, 13, 7, 45, 127, 191, 439, 383, 745, 3143, 2083, 2941, 31981, 0 }; + static ulong[] dim2670KuoInit = { 1, 3, 3, 13, 7, 15, 31, 203, 75, 297, 603, 2945, 1823, 12359, 29245, 0 }; + static ulong[] dim2671KuoInit = { 1, 3, 7, 15, 1, 57, 35, 255, 77, 483, 1051, 1999, 4975, 16211, 22903, 0 }; + static ulong[] dim2672KuoInit = { 1, 1, 5, 5, 23, 53, 13, 251, 181, 1011, 983, 3735, 4221, 5557, 25777, 0 }; + static ulong[] dim2673KuoInit = { 1, 1, 1, 11, 13, 51, 21, 155, 293, 79, 1015, 2653, 2959, 9913, 17751, 0 }; + static ulong[] dim2674KuoInit = { 1, 1, 5, 3, 17, 33, 27, 125, 437, 663, 343, 1799, 2129, 7993, 1373, 0 }; + static ulong[] dim2675KuoInit = { 1, 3, 3, 3, 9, 17, 31, 123, 453, 853, 1221, 2863, 4637, 8239, 27233, 0 }; + static ulong[] dim2676KuoInit = { 1, 1, 5, 1, 7, 19, 43, 77, 19, 559, 1397, 1631, 3187, 1445, 25437, 0 }; + static ulong[] dim2677KuoInit = { 1, 1, 3, 5, 31, 21, 71, 127, 223, 127, 717, 3163, 2079, 2399, 16415, 0 }; + static ulong[] dim2678KuoInit = { 1, 1, 1, 13, 17, 13, 99, 227, 127, 625, 1065, 1779, 7275, 11865, 17397, 0 }; + static ulong[] dim2679KuoInit = { 1, 3, 3, 11, 31, 43, 27, 231, 103, 873, 949, 1179, 3149, 2251, 22993, 0 }; + static ulong[] dim2680KuoInit = { 1, 3, 1, 11, 25, 11, 89, 149, 71, 171, 1985, 3779, 901, 16307, 5663, 0 }; + static ulong[] dim2681KuoInit = { 1, 1, 3, 5, 1, 25, 125, 241, 167, 381, 407, 2801, 635, 313, 10199, 0 }; + static ulong[] dim2682KuoInit = { 1, 1, 3, 15, 29, 31, 101, 121, 251, 685, 677, 1683, 3499, 16193, 7139, 0 }; + static ulong[] dim2683KuoInit = { 1, 3, 5, 3, 7, 13, 27, 101, 7, 159, 2005, 3297, 2775, 11193, 17385, 0 }; + static ulong[] dim2684KuoInit = { 1, 1, 5, 5, 25, 31, 119, 43, 317, 371, 1505, 2631, 1021, 1297, 22791, 0 }; + static ulong[] dim2685KuoInit = { 1, 3, 5, 7, 17, 57, 63, 229, 97, 599, 1485, 1113, 403, 77, 25541, 0 }; + static ulong[] dim2686KuoInit = { 1, 1, 7, 13, 11, 43, 29, 85, 335, 943, 1605, 1757, 2787, 3313, 14991, 0 }; + static ulong[] dim2687KuoInit = { 1, 3, 7, 13, 17, 43, 5, 231, 441, 883, 465, 841, 2785, 8193, 7951, 0 }; + static ulong[] dim2688KuoInit = { 1, 3, 1, 3, 27, 33, 1, 215, 295, 381, 283, 219, 3419, 3343, 17629, 0 }; + static ulong[] dim2689KuoInit = { 1, 1, 5, 9, 5, 49, 107, 179, 281, 223, 1845, 2505, 2281, 12051, 12609, 0 }; + static ulong[] dim2690KuoInit = { 1, 1, 7, 13, 21, 13, 109, 183, 385, 293, 773, 3975, 4737, 8143, 1335, 0 }; + static ulong[] dim2691KuoInit = { 1, 1, 1, 13, 13, 47, 23, 27, 271, 957, 1937, 4091, 3563, 4055, 17595, 0 }; + static ulong[] dim2692KuoInit = { 1, 3, 3, 15, 31, 45, 43, 7, 125, 549, 169, 1567, 5405, 3919, 21795, 0 }; + static ulong[] dim2693KuoInit = { 1, 3, 5, 7, 5, 53, 121, 107, 217, 745, 861, 481, 5503, 3723, 12215, 0 }; + static ulong[] dim2694KuoInit = { 1, 3, 7, 3, 23, 27, 91, 175, 477, 289, 817, 2483, 6071, 5429, 12923, 0 }; + static ulong[] dim2695KuoInit = { 1, 1, 3, 15, 7, 63, 29, 157, 323, 851, 1941, 1927, 5165, 9875, 11809, 0 }; + static ulong[] dim2696KuoInit = { 1, 3, 3, 1, 13, 17, 93, 187, 329, 187, 1417, 1477, 7891, 11093, 24705, 0 }; + static ulong[] dim2697KuoInit = { 1, 3, 3, 13, 5, 41, 119, 135, 255, 47, 803, 3941, 1647, 7777, 17515, 0 }; + static ulong[] dim2698KuoInit = { 1, 1, 5, 9, 25, 11, 15, 231, 81, 267, 1633, 407, 3319, 12033, 9651, 0 }; + static ulong[] dim2699KuoInit = { 1, 3, 1, 1, 31, 43, 3, 101, 435, 869, 159, 441, 613, 10283, 6873, 0 }; + static ulong[] dim2700KuoInit = { 1, 1, 5, 1, 11, 55, 7, 65, 357, 595, 1543, 3957, 6075, 7265, 27063, 0 }; + static ulong[] dim2701KuoInit = { 1, 3, 3, 11, 23, 23, 41, 205, 197, 863, 695, 971, 39, 12389, 2983, 0 }; + static ulong[] dim2702KuoInit = { 1, 1, 3, 15, 7, 39, 39, 25, 173, 277, 999, 3797, 3051, 189, 13559, 0 }; + static ulong[] dim2703KuoInit = { 1, 1, 7, 5, 3, 7, 47, 79, 411, 109, 55, 3803, 6617, 14317, 9533, 0 }; + static ulong[] dim2704KuoInit = { 1, 1, 3, 9, 31, 17, 53, 97, 495, 995, 1735, 1055, 6805, 6865, 23321, 0 }; + static ulong[] dim2705KuoInit = { 1, 3, 7, 13, 3, 63, 37, 185, 311, 995, 1819, 2633, 2593, 2107, 15755, 0 }; + static ulong[] dim2706KuoInit = { 1, 3, 7, 11, 25, 37, 79, 179, 435, 167, 147, 2159, 5909, 10427, 12487, 0 }; + static ulong[] dim2707KuoInit = { 1, 3, 5, 7, 31, 9, 69, 93, 477, 283, 479, 1895, 5693, 4809, 3157, 0 }; + static ulong[] dim2708KuoInit = { 1, 1, 3, 11, 27, 21, 11, 3, 157, 1011, 1473, 2393, 259, 4155, 28375, 0 }; + static ulong[] dim2709KuoInit = { 1, 3, 1, 9, 7, 11, 73, 215, 289, 933, 1369, 2911, 3251, 727, 19237, 0 }; + static ulong[] dim2710KuoInit = { 1, 1, 1, 15, 29, 19, 77, 59, 213, 1005, 2009, 1899, 5987, 7429, 5607, 0 }; + static ulong[] dim2711KuoInit = { 1, 1, 1, 13, 7, 53, 79, 151, 443, 911, 1777, 1223, 663, 2099, 17297, 0 }; + static ulong[] dim2712KuoInit = { 1, 1, 1, 9, 11, 7, 81, 175, 265, 879, 1867, 539, 2353, 5667, 4973, 0 }; + static ulong[] dim2713KuoInit = { 1, 1, 1, 9, 23, 63, 35, 57, 139, 653, 1837, 681, 6993, 643, 21771, 0 }; + static ulong[] dim2714KuoInit = { 1, 3, 7, 9, 11, 13, 123, 199, 405, 373, 1817, 3331, 5585, 11721, 9355, 0 }; + static ulong[] dim2715KuoInit = { 1, 1, 7, 7, 27, 29, 79, 121, 399, 85, 531, 507, 4361, 6167, 29317, 0 }; + static ulong[] dim2716KuoInit = { 1, 1, 7, 11, 13, 19, 75, 245, 197, 731, 233, 487, 2245, 11413, 31865, 0 }; + static ulong[] dim2717KuoInit = { 1, 1, 7, 5, 27, 43, 109, 135, 91, 475, 209, 865, 2239, 8065, 23295, 0 }; + static ulong[] dim2718KuoInit = { 1, 1, 1, 9, 13, 27, 101, 121, 23, 319, 873, 251, 299, 7145, 26225, 0 }; + static ulong[] dim2719KuoInit = { 1, 1, 7, 1, 31, 51, 85, 91, 299, 545, 1557, 2447, 4055, 3911, 12805, 0 }; + static ulong[] dim2720KuoInit = { 1, 3, 1, 9, 31, 63, 123, 191, 241, 7, 347, 23, 5135, 7353, 30865, 0 }; + static ulong[] dim2721KuoInit = { 1, 1, 5, 1, 3, 13, 81, 249, 65, 853, 893, 219, 6555, 4941, 21669, 0 }; + static ulong[] dim2722KuoInit = { 1, 3, 5, 13, 13, 27, 13, 203, 205, 459, 883, 1723, 2721, 9173, 9643, 0 }; + static ulong[] dim2723KuoInit = { 1, 1, 5, 5, 11, 59, 109, 25, 107, 1007, 357, 2877, 5075, 3251, 29541, 0 }; + static ulong[] dim2724KuoInit = { 1, 1, 1, 15, 19, 37, 99, 183, 267, 571, 49, 975, 2441, 4459, 15481, 0 }; + static ulong[] dim2725KuoInit = { 1, 3, 1, 1, 21, 7, 89, 233, 209, 151, 1919, 31, 4363, 9781, 4683, 0 }; + static ulong[] dim2726KuoInit = { 1, 1, 3, 9, 15, 35, 101, 29, 27, 737, 1577, 2611, 3727, 2245, 31889, 0 }; + static ulong[] dim2727KuoInit = { 1, 3, 5, 9, 19, 19, 125, 229, 313, 239, 67, 1373, 6459, 1339, 19909, 0 }; + static ulong[] dim2728KuoInit = { 1, 3, 3, 13, 19, 35, 17, 31, 183, 391, 1515, 2357, 2673, 10055, 943, 0 }; + static ulong[] dim2729KuoInit = { 1, 1, 3, 11, 31, 17, 37, 239, 79, 869, 629, 2755, 7431, 127, 19155, 0 }; + static ulong[] dim2730KuoInit = { 1, 3, 5, 3, 9, 13, 91, 27, 163, 455, 2007, 2479, 2387, 1557, 437, 0 }; + static ulong[] dim2731KuoInit = { 1, 1, 1, 13, 15, 63, 11, 105, 51, 673, 997, 2487, 35, 8655, 21481, 0 }; + static ulong[] dim2732KuoInit = { 1, 3, 5, 11, 1, 3, 27, 117, 195, 233, 269, 2163, 2083, 8907, 28005, 0 }; + static ulong[] dim2733KuoInit = { 1, 1, 1, 9, 9, 17, 63, 211, 87, 107, 1183, 2705, 6811, 9959, 13937, 0 }; + static ulong[] dim2734KuoInit = { 1, 1, 1, 1, 1, 3, 57, 231, 209, 949, 895, 2773, 237, 8943, 22453, 0 }; + static ulong[] dim2735KuoInit = { 1, 3, 7, 11, 7, 53, 1, 247, 279, 411, 1247, 2121, 3127, 16279, 277, 0 }; + static ulong[] dim2736KuoInit = { 1, 3, 5, 5, 15, 35, 15, 15, 485, 763, 1631, 1717, 191, 6609, 32383, 0 }; + static ulong[] dim2737KuoInit = { 1, 1, 5, 11, 27, 5, 73, 143, 127, 477, 535, 3815, 3135, 9865, 5375, 0 }; + static ulong[] dim2738KuoInit = { 1, 1, 7, 9, 21, 31, 83, 63, 313, 775, 875, 4053, 905, 14255, 31537, 0 }; + static ulong[] dim2739KuoInit = { 1, 1, 1, 3, 7, 3, 107, 231, 333, 935, 1625, 2527, 2293, 10407, 4795, 0 }; + static ulong[] dim2740KuoInit = { 1, 3, 5, 7, 25, 19, 123, 193, 353, 353, 1403, 3007, 677, 15333, 1263, 0 }; + static ulong[] dim2741KuoInit = { 1, 1, 3, 9, 1, 39, 79, 251, 59, 973, 1707, 2153, 7445, 9083, 6675, 0 }; + static ulong[] dim2742KuoInit = { 1, 1, 7, 3, 7, 55, 21, 101, 203, 735, 1789, 3119, 6633, 3643, 1947, 0 }; + static ulong[] dim2743KuoInit = { 1, 1, 5, 9, 13, 49, 103, 141, 181, 893, 385, 1541, 5887, 10687, 16183, 0 }; + static ulong[] dim2744KuoInit = { 1, 3, 3, 7, 17, 59, 35, 119, 467, 77, 1591, 469, 4991, 8113, 20231, 0 }; + static ulong[] dim2745KuoInit = { 1, 3, 1, 15, 19, 41, 5, 71, 247, 955, 565, 1931, 2895, 13189, 28461, 0 }; + static ulong[] dim2746KuoInit = { 1, 3, 5, 9, 19, 21, 123, 39, 175, 35, 673, 107, 3157, 1495, 16341, 0 }; + static ulong[] dim2747KuoInit = { 1, 1, 3, 9, 31, 25, 9, 17, 463, 585, 1701, 3325, 6071, 2719, 4479, 0 }; + static ulong[] dim2748KuoInit = { 1, 3, 3, 15, 25, 51, 63, 241, 289, 787, 1109, 453, 5119, 139, 377, 0 }; + static ulong[] dim2749KuoInit = { 1, 3, 5, 7, 29, 3, 53, 119, 219, 367, 1785, 777, 5255, 10013, 27979, 0 }; + static ulong[] dim2750KuoInit = { 1, 1, 1, 3, 1, 45, 3, 239, 429, 595, 1591, 3111, 2373, 4121, 12671, 0 }; + static ulong[] dim2751KuoInit = { 1, 3, 3, 9, 5, 49, 11, 145, 167, 19, 155, 2017, 3593, 15275, 22319, 0 }; + static ulong[] dim2752KuoInit = { 1, 3, 1, 3, 11, 15, 17, 241, 293, 345, 1663, 301, 627, 12161, 19939, 0 }; + static ulong[] dim2753KuoInit = { 1, 3, 5, 1, 3, 19, 41, 75, 121, 611, 1741, 4055, 5567, 773, 767, 0 }; + static ulong[] dim2754KuoInit = { 1, 1, 1, 3, 5, 49, 127, 49, 93, 819, 1391, 2173, 4021, 11953, 28465, 0 }; + static ulong[] dim2755KuoInit = { 1, 1, 3, 5, 9, 59, 63, 85, 249, 239, 521, 3333, 6301, 15283, 10645, 0 }; + static ulong[] dim2756KuoInit = { 1, 1, 1, 7, 9, 53, 107, 201, 151, 79, 1561, 3497, 4473, 4369, 6231, 0 }; + static ulong[] dim2757KuoInit = { 1, 1, 1, 9, 11, 61, 57, 69, 215, 637, 1087, 2827, 2495, 7471, 19127, 0 }; + static ulong[] dim2758KuoInit = { 1, 1, 1, 13, 3, 25, 87, 131, 171, 577, 957, 989, 3391, 3803, 27229, 0 }; + static ulong[] dim2759KuoInit = { 1, 1, 5, 5, 1, 25, 83, 71, 161, 477, 573, 3709, 4393, 4607, 32373, 0 }; + static ulong[] dim2760KuoInit = { 1, 1, 7, 5, 13, 21, 19, 71, 207, 433, 849, 2685, 4455, 463, 25163, 0 }; + static ulong[] dim2761KuoInit = { 1, 1, 7, 3, 5, 19, 35, 41, 487, 3, 865, 25, 7925, 9015, 29397, 0 }; + static ulong[] dim2762KuoInit = { 1, 1, 7, 3, 7, 41, 83, 27, 79, 501, 267, 2015, 8109, 8877, 4029, 0 }; + static ulong[] dim2763KuoInit = { 1, 3, 5, 1, 1, 31, 71, 233, 167, 185, 33, 1249, 3755, 2805, 29559, 0 }; + static ulong[] dim2764KuoInit = { 1, 1, 1, 7, 11, 21, 111, 105, 469, 527, 711, 3551, 521, 10593, 22701, 0 }; + static ulong[] dim2765KuoInit = { 1, 1, 1, 1, 29, 1, 79, 109, 279, 643, 1263, 2405, 3717, 11395, 4325, 0 }; + static ulong[] dim2766KuoInit = { 1, 1, 1, 1, 29, 47, 59, 1, 195, 399, 1963, 265, 317, 15117, 9935, 0 }; + static ulong[] dim2767KuoInit = { 1, 1, 7, 5, 21, 43, 93, 113, 273, 67, 281, 477, 6309, 3649, 20147, 0 }; + static ulong[] dim2768KuoInit = { 1, 1, 3, 15, 29, 61, 69, 151, 185, 809, 993, 2383, 7263, 901, 18607, 0 }; + static ulong[] dim2769KuoInit = { 1, 1, 3, 9, 27, 33, 25, 103, 387, 131, 1555, 301, 1471, 11331, 15091, 0 }; + static ulong[] dim2770KuoInit = { 1, 1, 7, 7, 19, 55, 115, 121, 99, 371, 1563, 895, 6207, 93, 8549, 0 }; + static ulong[] dim2771KuoInit = { 1, 1, 1, 9, 19, 23, 13, 181, 281, 479, 1, 1515, 3853, 8601, 19241, 0 }; + static ulong[] dim2772KuoInit = { 1, 3, 1, 15, 29, 63, 113, 253, 105, 421, 1679, 2113, 4671, 7923, 7671, 0 }; + static ulong[] dim2773KuoInit = { 1, 3, 1, 3, 17, 9, 15, 241, 339, 619, 417, 3257, 5917, 9981, 19033, 0 }; + static ulong[] dim2774KuoInit = { 1, 3, 3, 13, 21, 11, 97, 201, 257, 307, 133, 1793, 193, 8609, 27771, 0 }; + static ulong[] dim2775KuoInit = { 1, 1, 7, 3, 25, 55, 51, 97, 453, 37, 639, 3451, 6587, 3835, 13229, 0 }; + static ulong[] dim2776KuoInit = { 1, 3, 1, 1, 3, 21, 123, 81, 447, 963, 449, 1329, 4887, 1141, 3213, 0 }; + static ulong[] dim2777KuoInit = { 1, 1, 3, 1, 5, 33, 107, 89, 67, 229, 2025, 1925, 5369, 14049, 10461, 0 }; + static ulong[] dim2778KuoInit = { 1, 1, 7, 3, 23, 17, 75, 79, 51, 25, 1541, 3475, 6129, 13391, 31091, 0 }; + static ulong[] dim2779KuoInit = { 1, 3, 3, 13, 17, 27, 5, 57, 147, 549, 721, 2477, 893, 6413, 24053, 0 }; + static ulong[] dim2780KuoInit = { 1, 3, 1, 15, 11, 29, 119, 149, 185, 713, 1603, 3671, 3409, 2689, 7933, 0 }; + static ulong[] dim2781KuoInit = { 1, 1, 7, 15, 9, 33, 97, 85, 185, 225, 1747, 1677, 4133, 11421, 26591, 0 }; + static ulong[] dim2782KuoInit = { 1, 1, 5, 15, 29, 43, 75, 251, 157, 861, 517, 3341, 4447, 14803, 18465, 0 }; + static ulong[] dim2783KuoInit = { 1, 3, 5, 15, 11, 37, 57, 189, 423, 881, 1199, 1263, 2691, 6969, 21803, 0 }; + static ulong[] dim2784KuoInit = { 1, 1, 3, 3, 25, 47, 15, 107, 119, 885, 1149, 673, 4459, 9997, 4519, 0 }; + static ulong[] dim2785KuoInit = { 1, 3, 7, 13, 23, 7, 37, 161, 17, 499, 1675, 2309, 4159, 13771, 17741, 0 }; + static ulong[] dim2786KuoInit = { 1, 3, 1, 13, 7, 51, 111, 163, 313, 835, 1903, 2201, 321, 14655, 16845, 0 }; + static ulong[] dim2787KuoInit = { 1, 1, 3, 3, 7, 41, 23, 87, 101, 371, 257, 1679, 7449, 12967, 31, 0 }; + static ulong[] dim2788KuoInit = { 1, 3, 3, 7, 29, 37, 57, 163, 507, 1, 691, 2933, 4687, 10621, 32351, 0 }; + static ulong[] dim2789KuoInit = { 1, 3, 7, 3, 31, 63, 73, 67, 503, 289, 1533, 1203, 7931, 11399, 23463, 0 }; + static ulong[] dim2790KuoInit = { 1, 1, 5, 7, 23, 39, 19, 73, 467, 65, 791, 2017, 1763, 11921, 31643, 0 }; + static ulong[] dim2791KuoInit = { 1, 3, 3, 1, 19, 21, 53, 61, 401, 429, 1095, 297, 7931, 13085, 2013, 0 }; + static ulong[] dim2792KuoInit = { 1, 1, 5, 11, 27, 41, 23, 225, 299, 943, 823, 3507, 4333, 817, 26137, 0 }; + static ulong[] dim2793KuoInit = { 1, 1, 1, 7, 27, 29, 31, 251, 499, 151, 295, 1731, 7661, 11825, 29587, 0 }; + static ulong[] dim2794KuoInit = { 1, 1, 3, 7, 17, 43, 17, 5, 25, 813, 1875, 2941, 1407, 11669, 16753, 0 }; + static ulong[] dim2795KuoInit = { 1, 3, 1, 1, 17, 59, 93, 173, 335, 933, 369, 3421, 2769, 16361, 11891, 0 }; + static ulong[] dim2796KuoInit = { 1, 1, 1, 3, 27, 5, 63, 7, 415, 533, 179, 851, 1623, 16375, 1271, 0 }; + static ulong[] dim2797KuoInit = { 1, 1, 5, 1, 17, 45, 125, 93, 43, 311, 153, 1225, 4891, 5621, 14355, 0 }; + static ulong[] dim2798KuoInit = { 1, 3, 7, 5, 13, 63, 103, 205, 119, 953, 1087, 703, 3729, 10249, 19085, 0 }; + static ulong[] dim2799KuoInit = { 1, 3, 5, 3, 11, 51, 17, 97, 323, 657, 269, 467, 2747, 13603, 22803, 0 }; + static ulong[] dim2800KuoInit = { 1, 3, 3, 15, 3, 5, 35, 23, 433, 259, 1857, 2313, 7709, 2297, 31109, 0 }; + static ulong[] dim2801KuoInit = { 1, 3, 1, 15, 19, 11, 51, 251, 167, 741, 1705, 3763, 967, 2593, 28229, 0 }; + static ulong[] dim2802KuoInit = { 1, 3, 3, 13, 29, 47, 47, 183, 305, 223, 381, 1753, 2285, 9113, 21685, 0 }; + static ulong[] dim2803KuoInit = { 1, 3, 7, 13, 31, 17, 105, 25, 49, 679, 1501, 3887, 5007, 4275, 31161, 0 }; + static ulong[] dim2804KuoInit = { 1, 3, 7, 5, 27, 59, 17, 183, 477, 191, 1111, 383, 5519, 7435, 20341, 0 }; + static ulong[] dim2805KuoInit = { 1, 1, 7, 13, 25, 15, 67, 57, 5, 955, 731, 3785, 2055, 13017, 27843, 0 }; + static ulong[] dim2806KuoInit = { 1, 1, 5, 1, 27, 45, 67, 93, 311, 635, 1893, 1753, 7307, 2765, 6263, 0 }; + static ulong[] dim2807KuoInit = { 1, 1, 3, 1, 13, 53, 109, 5, 3, 705, 1745, 2233, 3425, 6125, 28839, 0 }; + static ulong[] dim2808KuoInit = { 1, 3, 5, 5, 5, 39, 5, 251, 431, 85, 599, 3459, 3211, 15611, 28739, 0 }; + static ulong[] dim2809KuoInit = { 1, 1, 7, 7, 25, 5, 25, 31, 283, 909, 399, 1335, 6973, 15791, 28351, 0 }; + static ulong[] dim2810KuoInit = { 1, 1, 5, 5, 3, 29, 47, 227, 463, 815, 1089, 2217, 4911, 14743, 17843, 0 }; + static ulong[] dim2811KuoInit = { 1, 1, 7, 3, 29, 39, 125, 165, 367, 461, 569, 3441, 1293, 1577, 10567, 0 }; + static ulong[] dim2812KuoInit = { 1, 1, 1, 11, 5, 11, 19, 129, 401, 111, 2019, 899, 2079, 7363, 32675, 0 }; + static ulong[] dim2813KuoInit = { 1, 3, 1, 7, 13, 27, 47, 183, 465, 421, 665, 1279, 5629, 7559, 21265, 0 }; + static ulong[] dim2814KuoInit = { 1, 1, 7, 1, 11, 19, 75, 1, 137, 893, 1709, 385, 2221, 15185, 10923, 0 }; + static ulong[] dim2815KuoInit = { 1, 3, 5, 5, 9, 1, 115, 203, 133, 259, 915, 2477, 3615, 1749, 7643, 0 }; + static ulong[] dim2816KuoInit = { 1, 3, 3, 5, 9, 57, 21, 113, 453, 739, 1857, 685, 5727, 10625, 23469, 0 }; + static ulong[] dim2817KuoInit = { 1, 1, 5, 5, 13, 45, 37, 25, 495, 723, 1805, 1631, 4889, 12885, 16895, 0 }; + static ulong[] dim2818KuoInit = { 1, 1, 5, 7, 17, 59, 111, 29, 143, 863, 1757, 1621, 3995, 7315, 30271, 0 }; + static ulong[] dim2819KuoInit = { 1, 1, 1, 1, 5, 31, 81, 161, 275, 623, 2017, 967, 2395, 14923, 23931, 0 }; + static ulong[] dim2820KuoInit = { 1, 3, 5, 11, 31, 33, 95, 135, 477, 221, 1603, 231, 5957, 12461, 2623, 0 }; + static ulong[] dim2821KuoInit = { 1, 3, 5, 11, 7, 3, 53, 43, 351, 557, 1981, 2127, 909, 8943, 21035, 0 }; + static ulong[] dim2822KuoInit = { 1, 3, 5, 9, 31, 11, 13, 231, 145, 321, 567, 1919, 7101, 12089, 8331, 0 }; + static ulong[] dim2823KuoInit = { 1, 1, 7, 1, 13, 27, 101, 229, 89, 395, 349, 1785, 6441, 8241, 30735, 0 }; + static ulong[] dim2824KuoInit = { 1, 1, 7, 9, 21, 57, 123, 77, 251, 347, 1367, 2205, 4017, 16057, 9247, 0 }; + static ulong[] dim2825KuoInit = { 1, 3, 3, 11, 5, 1, 47, 57, 69, 381, 1613, 1525, 5715, 3677, 13015, 0 }; + static ulong[] dim2826KuoInit = { 1, 3, 7, 9, 31, 33, 15, 255, 149, 1021, 1149, 3609, 1739, 11867, 3093, 0 }; + static ulong[] dim2827KuoInit = { 1, 1, 7, 15, 27, 25, 57, 5, 137, 1005, 343, 2567, 1025, 8615, 6357, 0 }; + static ulong[] dim2828KuoInit = { 1, 3, 5, 1, 29, 57, 85, 65, 85, 789, 1179, 2523, 7589, 14657, 23637, 0 }; + static ulong[] dim2829KuoInit = { 1, 3, 1, 11, 3, 3, 107, 37, 125, 423, 225, 2991, 4515, 5057, 31181, 0 }; + static ulong[] dim2830KuoInit = { 1, 1, 5, 9, 31, 5, 111, 241, 301, 37, 943, 555, 7051, 11627, 7125, 0 }; + static ulong[] dim2831KuoInit = { 1, 3, 3, 15, 17, 31, 119, 185, 187, 621, 395, 3595, 1055, 7993, 28441, 0 }; + static ulong[] dim2832KuoInit = { 1, 1, 5, 1, 31, 25, 113, 223, 493, 919, 1455, 31, 4743, 14435, 31627, 0 }; + static ulong[] dim2833KuoInit = { 1, 1, 1, 1, 27, 59, 45, 75, 343, 701, 1737, 161, 6919, 13537, 26835, 0 }; + static ulong[] dim2834KuoInit = { 1, 3, 1, 9, 31, 45, 89, 215, 137, 237, 1135, 3239, 3345, 12063, 14599, 0 }; + static ulong[] dim2835KuoInit = { 1, 3, 5, 15, 5, 51, 85, 73, 353, 943, 1981, 127, 2605, 5673, 10037, 0 }; + static ulong[] dim2836KuoInit = { 1, 1, 7, 1, 3, 49, 109, 105, 483, 499, 1581, 793, 5857, 5509, 4651, 0 }; + static ulong[] dim2837KuoInit = { 1, 3, 5, 9, 23, 5, 109, 83, 7, 155, 187, 2205, 4199, 5487, 31925, 0 }; + static ulong[] dim2838KuoInit = { 1, 1, 7, 5, 13, 11, 75, 53, 125, 139, 1241, 203, 7361, 13783, 4317, 0 }; + static ulong[] dim2839KuoInit = { 1, 3, 7, 5, 25, 57, 105, 197, 207, 261, 1251, 4057, 3877, 13613, 7829, 0 }; + static ulong[] dim2840KuoInit = { 1, 1, 5, 13, 31, 21, 89, 73, 163, 941, 1683, 2239, 1893, 16067, 609, 0 }; + static ulong[] dim2841KuoInit = { 1, 1, 1, 3, 5, 9, 41, 149, 43, 333, 1459, 277, 5687, 14201, 26879, 0 }; + static ulong[] dim2842KuoInit = { 1, 1, 3, 15, 21, 37, 67, 227, 443, 767, 1109, 2151, 7875, 15519, 13741, 0 }; + static ulong[] dim2843KuoInit = { 1, 3, 1, 5, 31, 15, 107, 43, 343, 27, 1321, 3009, 5751, 2931, 9733, 0 }; + static ulong[] dim2844KuoInit = { 1, 1, 1, 11, 5, 27, 49, 33, 439, 555, 97, 59, 4043, 12063, 27227, 0 }; + static ulong[] dim2845KuoInit = { 1, 3, 7, 7, 27, 9, 55, 69, 485, 75, 1255, 101, 7193, 9427, 31125, 0 }; + static ulong[] dim2846KuoInit = { 1, 3, 7, 3, 15, 23, 51, 145, 501, 875, 1611, 1321, 6809, 5051, 17135, 0 }; + static ulong[] dim2847KuoInit = { 1, 3, 3, 13, 5, 45, 35, 115, 3, 639, 1705, 207, 4235, 3329, 14481, 0 }; + static ulong[] dim2848KuoInit = { 1, 3, 3, 1, 5, 15, 17, 115, 175, 583, 1649, 2195, 3827, 16227, 21401, 0 }; + static ulong[] dim2849KuoInit = { 1, 3, 3, 7, 1, 3, 107, 167, 195, 953, 743, 1375, 701, 1155, 1027, 0 }; + static ulong[] dim2850KuoInit = { 1, 1, 7, 1, 31, 31, 67, 133, 219, 307, 1031, 3321, 4855, 11285, 16987, 0 }; + static ulong[] dim2851KuoInit = { 1, 1, 7, 1, 25, 9, 41, 105, 89, 289, 1851, 2245, 1647, 2925, 8637, 0 }; + static ulong[] dim2852KuoInit = { 1, 3, 7, 15, 29, 29, 107, 21, 101, 419, 1207, 3301, 1217, 14157, 17373, 0 }; + static ulong[] dim2853KuoInit = { 1, 1, 5, 11, 9, 41, 49, 165, 353, 215, 883, 2031, 7363, 13221, 8329, 0 }; + static ulong[] dim2854KuoInit = { 1, 1, 5, 15, 17, 7, 67, 217, 87, 217, 2013, 3809, 4983, 5341, 30353, 0 }; + static ulong[] dim2855KuoInit = { 1, 1, 7, 9, 1, 37, 97, 109, 485, 777, 171, 1391, 781, 5019, 19883, 0 }; + static ulong[] dim2856KuoInit = { 1, 3, 3, 13, 7, 17, 27, 69, 265, 663, 569, 2909, 7409, 14813, 5849, 0 }; + static ulong[] dim2857KuoInit = { 1, 3, 5, 13, 11, 29, 27, 105, 215, 59, 1251, 2003, 2201, 7221, 7549, 0 }; + static ulong[] dim2858KuoInit = { 1, 1, 1, 3, 15, 7, 79, 237, 327, 839, 1167, 3211, 275, 16031, 25691, 0 }; + static ulong[] dim2859KuoInit = { 1, 1, 5, 3, 3, 33, 117, 113, 361, 381, 1093, 1791, 2399, 1245, 23275, 0 }; + static ulong[] dim2860KuoInit = { 1, 1, 1, 3, 7, 49, 77, 5, 217, 995, 1127, 3891, 81, 13331, 12479, 0 }; + static ulong[] dim2861KuoInit = { 1, 1, 7, 9, 9, 57, 119, 227, 41, 337, 183, 3201, 3627, 16263, 28153, 0 }; + static ulong[] dim2862KuoInit = { 1, 3, 1, 13, 11, 9, 81, 99, 247, 157, 1421, 1087, 151, 6529, 13537, 0 }; + static ulong[] dim2863KuoInit = { 1, 3, 3, 5, 31, 43, 113, 143, 163, 583, 2031, 3087, 7565, 4987, 17131, 0 }; + static ulong[] dim2864KuoInit = { 1, 1, 3, 1, 9, 1, 121, 93, 113, 849, 679, 1403, 6815, 15605, 29785, 0 }; + static ulong[] dim2865KuoInit = { 1, 3, 7, 11, 27, 63, 53, 83, 397, 935, 23, 125, 5813, 15765, 2869, 0 }; + static ulong[] dim2866KuoInit = { 1, 1, 3, 3, 9, 11, 65, 77, 387, 129, 1039, 1583, 2235, 3851, 30603, 0 }; + static ulong[] dim2867KuoInit = { 1, 1, 7, 3, 5, 27, 45, 233, 351, 827, 215, 1209, 409, 2185, 3827, 0 }; + static ulong[] dim2868KuoInit = { 1, 1, 3, 3, 31, 23, 35, 83, 271, 65, 553, 3189, 2435, 12865, 28271, 0 }; + static ulong[] dim2869KuoInit = { 1, 1, 5, 1, 29, 51, 35, 105, 477, 1001, 1859, 2063, 6895, 1855, 13931, 0 }; + static ulong[] dim2870KuoInit = { 1, 3, 3, 11, 17, 63, 125, 165, 37, 671, 2001, 1237, 7355, 339, 24771, 0 }; + static ulong[] dim2871KuoInit = { 1, 3, 3, 5, 13, 5, 9, 201, 183, 39, 119, 3889, 949, 7889, 25951, 0 }; + static ulong[] dim2872KuoInit = { 1, 1, 3, 5, 13, 63, 71, 117, 209, 955, 1175, 317, 4261, 2341, 29819, 0 }; + static ulong[] dim2873KuoInit = { 1, 3, 5, 5, 9, 59, 109, 137, 353, 355, 1227, 3183, 1553, 15039, 27979, 0 }; + static ulong[] dim2874KuoInit = { 1, 3, 1, 5, 25, 57, 87, 231, 259, 333, 975, 3413, 6035, 14783, 22309, 0 }; + static ulong[] dim2875KuoInit = { 1, 3, 5, 11, 19, 37, 55, 229, 423, 761, 1669, 3023, 2517, 2961, 12043, 0 }; + static ulong[] dim2876KuoInit = { 1, 1, 3, 13, 23, 5, 87, 193, 113, 577, 269, 983, 5453, 7827, 28197, 0 }; + static ulong[] dim2877KuoInit = { 1, 1, 7, 13, 1, 49, 89, 107, 155, 767, 1547, 2139, 5951, 3143, 12735, 0 }; + static ulong[] dim2878KuoInit = { 1, 3, 1, 13, 13, 57, 53, 243, 231, 131, 1505, 1255, 7831, 15615, 28755, 0 }; + static ulong[] dim2879KuoInit = { 1, 1, 5, 11, 21, 21, 37, 65, 327, 353, 1625, 543, 669, 1139, 20745, 0 }; + static ulong[] dim2880KuoInit = { 1, 3, 1, 1, 5, 33, 87, 211, 21, 581, 397, 2691, 1069, 10449, 17727, 0 }; + static ulong[] dim2881KuoInit = { 1, 1, 7, 7, 1, 5, 115, 143, 99, 523, 51, 939, 4635, 11491, 32731, 0 }; + static ulong[] dim2882KuoInit = { 1, 3, 3, 15, 1, 19, 119, 193, 127, 897, 1337, 3977, 5027, 5913, 9329, 0 }; + static ulong[] dim2883KuoInit = { 1, 1, 5, 15, 15, 1, 93, 209, 427, 625, 1581, 2639, 1291, 11177, 26943, 0 }; + static ulong[] dim2884KuoInit = { 1, 1, 3, 13, 27, 9, 47, 243, 211, 21, 1159, 3157, 6729, 219, 19671, 0 }; + static ulong[] dim2885KuoInit = { 1, 3, 1, 15, 19, 27, 39, 237, 39, 389, 1201, 2237, 7623, 12041, 18491, 0 }; + static ulong[] dim2886KuoInit = { 1, 1, 3, 5, 25, 43, 47, 101, 319, 749, 659, 2319, 1221, 3887, 29927, 0 }; + static ulong[] dim2887KuoInit = { 1, 3, 3, 9, 1, 55, 57, 179, 163, 695, 611, 2511, 1261, 15561, 29535, 0 }; + static ulong[] dim2888KuoInit = { 1, 1, 1, 13, 7, 31, 79, 21, 143, 993, 377, 791, 187, 6485, 6827, 0 }; + static ulong[] dim2889KuoInit = { 1, 3, 5, 1, 11, 57, 39, 159, 373, 179, 1907, 2475, 1355, 9885, 18683, 0 }; + static ulong[] dim2890KuoInit = { 1, 1, 1, 3, 7, 5, 83, 151, 267, 377, 1463, 365, 4725, 2319, 18957, 0 }; + static ulong[] dim2891KuoInit = { 1, 3, 7, 3, 21, 51, 115, 119, 73, 561, 1513, 403, 4889, 2329, 20141, 0 }; + static ulong[] dim2892KuoInit = { 1, 1, 1, 15, 21, 47, 31, 61, 171, 529, 185, 717, 7065, 4273, 16643, 0 }; + static ulong[] dim2893KuoInit = { 1, 3, 5, 9, 3, 55, 41, 213, 489, 379, 1951, 1957, 7721, 6415, 27049, 0 }; + static ulong[] dim2894KuoInit = { 1, 3, 1, 13, 19, 43, 29, 203, 139, 137, 463, 1447, 2585, 14381, 29073, 0 }; + static ulong[] dim2895KuoInit = { 1, 1, 1, 1, 19, 37, 111, 119, 411, 671, 1135, 2891, 7929, 7465, 21699, 0 }; + static ulong[] dim2896KuoInit = { 1, 1, 5, 13, 21, 31, 83, 227, 435, 61, 969, 2171, 789, 3415, 18293, 0 }; + static ulong[] dim2897KuoInit = { 1, 3, 3, 15, 31, 33, 87, 227, 369, 341, 1515, 25, 2891, 16199, 22179, 0 }; + static ulong[] dim2898KuoInit = { 1, 3, 3, 1, 25, 49, 111, 167, 59, 355, 1687, 1799, 5963, 6161, 32157, 0 }; + static ulong[] dim2899KuoInit = { 1, 1, 1, 5, 7, 57, 95, 171, 417, 277, 47, 847, 3889, 8645, 3367, 0 }; + static ulong[] dim2900KuoInit = { 1, 1, 7, 3, 25, 51, 99, 251, 463, 833, 491, 3595, 2883, 8183, 28937, 0 }; + static ulong[] dim2901KuoInit = { 1, 1, 3, 7, 1, 5, 73, 151, 397, 521, 905, 603, 2315, 15231, 17955, 0 }; + static ulong[] dim2902KuoInit = { 1, 1, 1, 13, 23, 59, 9, 187, 163, 727, 1909, 1135, 6135, 11563, 2047, 0 }; + static ulong[] dim2903KuoInit = { 1, 1, 3, 3, 9, 1, 121, 207, 55, 947, 873, 419, 2799, 3285, 10237, 0 }; + static ulong[] dim2904KuoInit = { 1, 1, 1, 3, 21, 27, 27, 241, 509, 295, 1509, 3527, 4269, 13579, 29125, 0 }; + static ulong[] dim2905KuoInit = { 1, 3, 1, 5, 7, 21, 35, 67, 251, 883, 1117, 1311, 1251, 10401, 10615, 0 }; + static ulong[] dim2906KuoInit = { 1, 3, 7, 3, 21, 13, 23, 75, 401, 279, 1557, 1419, 7067, 2563, 22285, 0 }; + static ulong[] dim2907KuoInit = { 1, 3, 1, 7, 23, 15, 11, 189, 315, 353, 1377, 3551, 4939, 14529, 12459, 0 }; + static ulong[] dim2908KuoInit = { 1, 3, 1, 3, 21, 41, 111, 67, 311, 95, 1919, 165, 2097, 12965, 12517, 0 }; + static ulong[] dim2909KuoInit = { 1, 3, 3, 11, 29, 61, 33, 35, 209, 541, 149, 3073, 8187, 15087, 17617, 0 }; + static ulong[] dim2910KuoInit = { 1, 1, 7, 5, 9, 53, 73, 145, 205, 157, 1737, 1737, 6471, 12327, 11605, 0 }; + static ulong[] dim2911KuoInit = { 1, 1, 5, 5, 15, 35, 105, 99, 467, 421, 483, 3191, 2321, 8953, 22045, 0 }; + static ulong[] dim2912KuoInit = { 1, 3, 3, 9, 1, 35, 65, 249, 37, 535, 1301, 2141, 1629, 9709, 995, 0 }; + static ulong[] dim2913KuoInit = { 1, 3, 1, 13, 9, 27, 75, 115, 121, 731, 1567, 2341, 6657, 14959, 6781, 0 }; + static ulong[] dim2914KuoInit = { 1, 1, 1, 5, 13, 33, 89, 215, 189, 693, 357, 3383, 6345, 14263, 23973, 0 }; + static ulong[] dim2915KuoInit = { 1, 3, 1, 9, 21, 5, 59, 11, 21, 703, 1217, 2623, 6429, 479, 28659, 0 }; + static ulong[] dim2916KuoInit = { 1, 3, 3, 9, 11, 15, 113, 89, 453, 233, 1323, 3859, 1841, 2753, 2839, 0 }; + static ulong[] dim2917KuoInit = { 1, 1, 5, 15, 19, 1, 119, 83, 205, 861, 787, 1039, 5257, 8945, 27271, 0 }; + static ulong[] dim2918KuoInit = { 1, 3, 1, 15, 9, 37, 7, 83, 51, 611, 1121, 3185, 1603, 5821, 14533, 0 }; + static ulong[] dim2919KuoInit = { 1, 1, 7, 7, 27, 61, 115, 191, 357, 93, 1647, 3249, 2479, 2423, 649, 0 }; + static ulong[] dim2920KuoInit = { 1, 1, 7, 11, 25, 17, 13, 213, 37, 571, 1179, 3897, 3817, 7597, 26239, 0 }; + static ulong[] dim2921KuoInit = { 1, 1, 5, 5, 27, 57, 73, 209, 433, 779, 75, 2135, 8183, 7343, 23751, 0 }; + static ulong[] dim2922KuoInit = { 1, 1, 7, 13, 27, 51, 31, 33, 195, 443, 1639, 1415, 6203, 4373, 31271, 0 }; + static ulong[] dim2923KuoInit = { 1, 1, 7, 11, 9, 9, 75, 103, 237, 521, 1653, 1209, 5981, 5961, 15229, 0 }; + static ulong[] dim2924KuoInit = { 1, 3, 3, 11, 15, 29, 1, 201, 171, 81, 729, 589, 441, 2453, 25209, 0 }; + static ulong[] dim2925KuoInit = { 1, 3, 1, 1, 21, 11, 95, 225, 213, 981, 1479, 3259, 4415, 8393, 17647, 0 }; + static ulong[] dim2926KuoInit = { 1, 1, 7, 1, 7, 11, 95, 135, 329, 483, 1711, 3223, 4841, 11083, 4033, 0 }; + static ulong[] dim2927KuoInit = { 1, 1, 3, 5, 23, 37, 77, 39, 363, 555, 1451, 99, 6963, 13279, 24155, 0 }; + static ulong[] dim2928KuoInit = { 1, 3, 7, 11, 11, 17, 31, 29, 357, 177, 411, 1439, 815, 7017, 25527, 0 }; + static ulong[] dim2929KuoInit = { 1, 3, 3, 15, 25, 7, 105, 9, 301, 209, 917, 1369, 2941, 11599, 25847, 0 }; + static ulong[] dim2930KuoInit = { 1, 1, 7, 7, 11, 33, 121, 9, 465, 945, 201, 3929, 5521, 4787, 10713, 0 }; + static ulong[] dim2931KuoInit = { 1, 1, 7, 9, 27, 3, 77, 11, 103, 181, 1199, 2833, 6259, 3879, 13217, 0 }; + static ulong[] dim2932KuoInit = { 1, 3, 3, 11, 11, 9, 5, 217, 471, 973, 293, 3693, 5457, 11359, 30043, 0 }; + static ulong[] dim2933KuoInit = { 1, 1, 3, 15, 27, 25, 7, 65, 95, 883, 277, 3147, 6203, 12201, 23203, 0 }; + static ulong[] dim2934KuoInit = { 1, 1, 3, 9, 3, 19, 51, 55, 381, 879, 845, 1605, 2433, 4781, 5075, 0 }; + static ulong[] dim2935KuoInit = { 1, 1, 3, 15, 17, 49, 21, 81, 209, 285, 1483, 1897, 5591, 131, 30459, 0 }; + static ulong[] dim2936KuoInit = { 1, 3, 1, 9, 17, 19, 47, 97, 325, 963, 1665, 3361, 369, 11023, 23701, 0 }; + static ulong[] dim2937KuoInit = { 1, 3, 1, 13, 3, 19, 57, 7, 57, 383, 1945, 3357, 2553, 5161, 22363, 0 }; + static ulong[] dim2938KuoInit = { 1, 1, 3, 15, 15, 37, 41, 123, 453, 879, 337, 251, 7137, 4117, 30879, 0 }; + static ulong[] dim2939KuoInit = { 1, 3, 5, 3, 13, 45, 55, 151, 357, 429, 671, 1183, 3047, 4991, 15273, 0 }; + static ulong[] dim2940KuoInit = { 1, 1, 3, 3, 15, 15, 65, 131, 505, 339, 869, 2983, 4451, 2375, 26745, 0 }; + static ulong[] dim2941KuoInit = { 1, 3, 5, 9, 15, 55, 23, 83, 255, 395, 15, 1175, 849, 5959, 17355, 0 }; + static ulong[] dim2942KuoInit = { 1, 1, 3, 7, 9, 3, 57, 95, 7, 267, 801, 3843, 3139, 12565, 20737, 0 }; + static ulong[] dim2943KuoInit = { 1, 3, 7, 7, 9, 41, 121, 77, 489, 975, 215, 325, 7505, 15517, 8833, 0 }; + static ulong[] dim2944KuoInit = { 1, 3, 3, 1, 9, 43, 105, 199, 339, 335, 1719, 1999, 4153, 9665, 15457, 0 }; + static ulong[] dim2945KuoInit = { 1, 3, 1, 13, 1, 35, 47, 157, 3, 93, 1399, 471, 6337, 2789, 32727, 0 }; + static ulong[] dim2946KuoInit = { 1, 3, 5, 1, 29, 9, 101, 195, 371, 573, 1361, 521, 5737, 4845, 4871, 0 }; + static ulong[] dim2947KuoInit = { 1, 1, 7, 9, 9, 11, 43, 129, 295, 1015, 665, 451, 1249, 7733, 8861, 0 }; + static ulong[] dim2948KuoInit = { 1, 1, 1, 11, 19, 31, 127, 171, 341, 865, 1391, 955, 5585, 1481, 1311, 0 }; + static ulong[] dim2949KuoInit = { 1, 3, 1, 11, 19, 43, 113, 83, 285, 865, 815, 807, 779, 6685, 22315, 0 }; + static ulong[] dim2950KuoInit = { 1, 1, 1, 11, 1, 19, 99, 19, 455, 155, 637, 2153, 3013, 4791, 20619, 0 }; + static ulong[] dim2951KuoInit = { 1, 1, 1, 1, 13, 39, 95, 229, 35, 515, 1945, 3631, 3359, 7913, 8081, 0 }; + static ulong[] dim2952KuoInit = { 1, 3, 7, 13, 1, 5, 25, 227, 487, 269, 1213, 303, 4041, 15847, 1125, 0 }; + static ulong[] dim2953KuoInit = { 1, 1, 3, 7, 27, 53, 121, 143, 1, 977, 1963, 807, 253, 7649, 16047, 0 }; + static ulong[] dim2954KuoInit = { 1, 3, 5, 9, 29, 17, 97, 93, 83, 739, 1221, 963, 6849, 4307, 17277, 0 }; + static ulong[] dim2955KuoInit = { 1, 1, 7, 1, 27, 55, 71, 177, 63, 11, 1781, 3341, 2797, 8035, 6135, 0 }; + static ulong[] dim2956KuoInit = { 1, 1, 1, 11, 15, 43, 59, 107, 485, 995, 1571, 1527, 2195, 4883, 32563, 0 }; + static ulong[] dim2957KuoInit = { 1, 3, 5, 15, 7, 45, 55, 211, 425, 771, 621, 1141, 5277, 13575, 203, 0 }; + static ulong[] dim2958KuoInit = { 1, 1, 7, 1, 21, 51, 81, 41, 71, 551, 839, 3315, 5075, 3651, 6649, 0 }; + static ulong[] dim2959KuoInit = { 1, 1, 1, 9, 17, 45, 51, 211, 349, 329, 987, 3153, 7121, 16101, 1475, 0 }; + static ulong[] dim2960KuoInit = { 1, 3, 3, 9, 5, 5, 99, 17, 245, 827, 231, 949, 2577, 12925, 2055, 0 }; + static ulong[] dim2961KuoInit = { 1, 1, 5, 1, 19, 59, 75, 97, 303, 649, 901, 3987, 1209, 14483, 25855, 0 }; + static ulong[] dim2962KuoInit = { 1, 3, 7, 15, 25, 51, 5, 69, 199, 845, 1847, 1491, 6183, 3359, 11809, 0 }; + static ulong[] dim2963KuoInit = { 1, 1, 5, 5, 19, 43, 17, 113, 215, 337, 583, 2199, 6375, 499, 11283, 0 }; + static ulong[] dim2964KuoInit = { 1, 1, 5, 15, 5, 3, 45, 219, 375, 269, 1251, 2711, 7897, 3379, 11887, 0 }; + static ulong[] dim2965KuoInit = { 1, 1, 7, 13, 3, 59, 17, 41, 275, 1007, 711, 1689, 3727, 14237, 32057, 0 }; + static ulong[] dim2966KuoInit = { 1, 3, 5, 7, 5, 27, 73, 167, 295, 581, 233, 585, 7207, 12709, 3847, 0 }; + static ulong[] dim2967KuoInit = { 1, 1, 7, 5, 9, 17, 65, 15, 439, 385, 455, 1073, 5727, 2679, 3689, 0 }; + static ulong[] dim2968KuoInit = { 1, 1, 7, 5, 7, 63, 111, 161, 85, 295, 755, 2805, 3031, 4833, 11149, 0 }; + static ulong[] dim2969KuoInit = { 1, 1, 5, 7, 13, 53, 63, 47, 163, 275, 289, 1377, 639, 15367, 32517, 0 }; + static ulong[] dim2970KuoInit = { 1, 1, 7, 9, 21, 43, 123, 221, 451, 901, 1339, 3367, 2531, 9319, 4461, 0 }; + static ulong[] dim2971KuoInit = { 1, 3, 3, 9, 3, 53, 87, 117, 471, 349, 1487, 2375, 7399, 8561, 19611, 0 }; + static ulong[] dim2972KuoInit = { 1, 3, 1, 7, 29, 55, 53, 197, 301, 701, 357, 3651, 2233, 6365, 705, 0 }; + static ulong[] dim2973KuoInit = { 1, 3, 5, 3, 17, 19, 23, 17, 433, 979, 1377, 213, 3993, 3773, 24369, 0 }; + static ulong[] dim2974KuoInit = { 1, 3, 5, 5, 17, 9, 105, 149, 145, 751, 1173, 1831, 7005, 3559, 10913, 0 }; + static ulong[] dim2975KuoInit = { 1, 3, 1, 9, 23, 47, 83, 213, 135, 223, 937, 3607, 7375, 4731, 14307, 0 }; + static ulong[] dim2976KuoInit = { 1, 1, 7, 3, 23, 21, 71, 241, 399, 199, 289, 2049, 7959, 14897, 18661, 0 }; + static ulong[] dim2977KuoInit = { 1, 3, 3, 9, 13, 45, 125, 217, 325, 893, 1523, 2477, 7829, 15737, 2127, 0 }; + static ulong[] dim2978KuoInit = { 1, 1, 5, 1, 21, 51, 117, 203, 253, 713, 545, 191, 729, 8403, 8381, 0 }; + static ulong[] dim2979KuoInit = { 1, 3, 7, 7, 11, 23, 3, 193, 421, 341, 1309, 2457, 5805, 7457, 26857, 0 }; + static ulong[] dim2980KuoInit = { 1, 3, 7, 15, 1, 17, 27, 159, 127, 713, 1465, 3551, 7409, 7957, 2317, 0 }; + static ulong[] dim2981KuoInit = { 1, 3, 1, 15, 7, 33, 17, 1, 237, 199, 527, 3361, 3785, 13111, 19119, 0 }; + static ulong[] dim2982KuoInit = { 1, 3, 3, 1, 23, 37, 91, 31, 35, 969, 661, 85, 5917, 10895, 11049, 0 }; + static ulong[] dim2983KuoInit = { 1, 3, 1, 7, 23, 53, 101, 181, 381, 159, 1967, 3427, 4499, 6877, 12155, 0 }; + static ulong[] dim2984KuoInit = { 1, 3, 3, 13, 9, 57, 77, 27, 223, 101, 1709, 3023, 6655, 6221, 1027, 0 }; + static ulong[] dim2985KuoInit = { 1, 3, 5, 7, 19, 47, 73, 175, 103, 35, 1039, 343, 6757, 11521, 24495, 0 }; + static ulong[] dim2986KuoInit = { 1, 3, 1, 9, 17, 19, 9, 205, 279, 373, 173, 3641, 3945, 10831, 15621, 0 }; + static ulong[] dim2987KuoInit = { 1, 1, 3, 13, 29, 63, 71, 217, 367, 381, 647, 9, 5521, 5209, 24275, 0 }; + static ulong[] dim2988KuoInit = { 1, 3, 7, 7, 23, 15, 7, 203, 153, 655, 2047, 287, 973, 6757, 29207, 0 }; + static ulong[] dim2989KuoInit = { 1, 1, 1, 9, 17, 33, 63, 97, 49, 31, 1989, 569, 3321, 4017, 6437, 0 }; + static ulong[] dim2990KuoInit = { 1, 1, 7, 11, 15, 15, 57, 255, 381, 115, 573, 3903, 7141, 1569, 11789, 0 }; + static ulong[] dim2991KuoInit = { 1, 1, 5, 13, 9, 45, 69, 111, 91, 389, 1347, 3351, 3023, 517, 28373, 0 }; + static ulong[] dim2992KuoInit = { 1, 3, 3, 15, 9, 11, 81, 205, 299, 903, 661, 3377, 5355, 9151, 17597, 0 }; + static ulong[] dim2993KuoInit = { 1, 1, 3, 9, 19, 55, 45, 123, 285, 161, 1591, 1971, 5471, 8221, 2855, 0 }; + static ulong[] dim2994KuoInit = { 1, 3, 5, 13, 23, 25, 87, 197, 303, 487, 395, 3137, 4395, 5861, 5847, 0 }; + static ulong[] dim2995KuoInit = { 1, 3, 7, 5, 23, 9, 107, 13, 127, 971, 1701, 2387, 6195, 5041, 24857, 0 }; + static ulong[] dim2996KuoInit = { 1, 1, 3, 3, 19, 63, 91, 205, 207, 897, 295, 2093, 1223, 14599, 13803, 0 }; + static ulong[] dim2997KuoInit = { 1, 1, 5, 1, 1, 25, 93, 33, 393, 221, 1845, 2517, 1723, 13881, 15777, 0 }; + static ulong[] dim2998KuoInit = { 1, 3, 5, 3, 1, 21, 115, 103, 377, 789, 541, 3423, 3111, 8077, 25089, 0 }; + static ulong[] dim2999KuoInit = { 1, 1, 1, 11, 31, 55, 95, 53, 141, 697, 1085, 3031, 653, 4145, 28121, 0 }; + static ulong[] dim3000KuoInit = { 1, 3, 1, 1, 7, 39, 55, 57, 447, 257, 101, 2307, 5623, 8505, 995, 0 }; + static ulong[] dim3001KuoInit = { 1, 3, 5, 11, 25, 37, 11, 203, 361, 281, 701, 3643, 957, 14541, 8109, 0 }; + static ulong[] dim3002KuoInit = { 1, 3, 1, 3, 21, 49, 57, 225, 21, 523, 1275, 3743, 6259, 13625, 26721, 0 }; + static ulong[] dim3003KuoInit = { 1, 1, 1, 1, 13, 53, 9, 167, 117, 971, 875, 2659, 7589, 13575, 11659, 0 }; + static ulong[] dim3004KuoInit = { 1, 1, 7, 13, 21, 1, 35, 201, 261, 533, 1069, 1459, 5433, 7211, 3535, 0 }; + static ulong[] dim3005KuoInit = { 1, 1, 3, 13, 23, 7, 41, 137, 341, 767, 1823, 3745, 1415, 4811, 21669, 0 }; + static ulong[] dim3006KuoInit = { 1, 3, 3, 5, 5, 11, 71, 117, 451, 1, 381, 967, 7977, 10741, 20141, 0 }; + static ulong[] dim3007KuoInit = { 1, 3, 1, 3, 21, 1, 65, 37, 451, 29, 327, 2471, 7573, 5051, 23925, 0 }; + static ulong[] dim3008KuoInit = { 1, 3, 3, 11, 17, 61, 97, 121, 327, 929, 1165, 185, 2343, 1479, 3817, 0 }; + static ulong[] dim3009KuoInit = { 1, 1, 3, 7, 27, 55, 87, 53, 389, 577, 1051, 2413, 609, 12651, 15695, 0 }; + static ulong[] dim3010KuoInit = { 1, 3, 5, 13, 1, 41, 25, 149, 175, 667, 1219, 2297, 6599, 1667, 19647, 0 }; + static ulong[] dim3011KuoInit = { 1, 1, 3, 11, 17, 63, 83, 37, 425, 675, 1111, 499, 7727, 7491, 9759, 0 }; + static ulong[] dim3012KuoInit = { 1, 1, 3, 1, 21, 23, 17, 125, 485, 643, 341, 1159, 7073, 14405, 22409, 0 }; + static ulong[] dim3013KuoInit = { 1, 3, 7, 15, 15, 53, 23, 17, 365, 101, 685, 1391, 5123, 14961, 31179, 0 }; + static ulong[] dim3014KuoInit = { 1, 3, 3, 3, 23, 11, 101, 139, 401, 779, 1723, 3421, 623, 3443, 17179, 0 }; + static ulong[] dim3015KuoInit = { 1, 1, 1, 7, 13, 19, 93, 129, 127, 389, 1361, 2341, 6491, 15063, 8199, 0 }; + static ulong[] dim3016KuoInit = { 1, 1, 7, 1, 31, 1, 55, 169, 373, 69, 539, 513, 6329, 393, 21963, 0 }; + static ulong[] dim3017KuoInit = { 1, 1, 7, 1, 5, 39, 73, 87, 401, 923, 1747, 565, 2227, 14509, 7601, 0 }; + static ulong[] dim3018KuoInit = { 1, 3, 3, 1, 25, 3, 77, 207, 149, 591, 1165, 3235, 7615, 12237, 20849, 0 }; + static ulong[] dim3019KuoInit = { 1, 3, 1, 11, 21, 41, 83, 109, 265, 349, 485, 1411, 2705, 13017, 25205, 0 }; + static ulong[] dim3020KuoInit = { 1, 1, 7, 7, 31, 27, 55, 23, 129, 369, 1785, 2031, 1993, 123, 20063, 0 }; + static ulong[] dim3021KuoInit = { 1, 3, 5, 9, 9, 45, 75, 37, 69, 957, 2047, 2515, 5327, 15345, 2147, 0 }; + static ulong[] dim3022KuoInit = { 1, 3, 1, 7, 5, 57, 91, 19, 499, 173, 765, 3653, 6397, 1509, 11223, 0 }; + static ulong[] dim3023KuoInit = { 1, 3, 5, 15, 1, 15, 69, 107, 225, 233, 1015, 807, 4265, 8823, 22047, 0 }; + static ulong[] dim3024KuoInit = { 1, 1, 7, 13, 15, 55, 15, 83, 49, 711, 935, 1865, 29, 607, 8113, 0 }; + static ulong[] dim3025KuoInit = { 1, 3, 1, 15, 13, 15, 127, 193, 219, 653, 1787, 905, 3311, 11595, 21193, 0 }; + static ulong[] dim3026KuoInit = { 1, 3, 5, 11, 21, 51, 67, 97, 371, 367, 1763, 2953, 3701, 15983, 18631, 0 }; + static ulong[] dim3027KuoInit = { 1, 1, 5, 9, 13, 1, 83, 15, 305, 939, 1073, 1577, 2073, 5335, 17173, 0 }; + static ulong[] dim3028KuoInit = { 1, 3, 5, 7, 19, 7, 27, 213, 357, 681, 1969, 4007, 7887, 11191, 19395, 0 }; + static ulong[] dim3029KuoInit = { 1, 1, 5, 3, 19, 29, 119, 239, 123, 559, 1613, 1563, 8047, 5753, 26719, 0 }; + static ulong[] dim3030KuoInit = { 1, 3, 7, 5, 3, 3, 127, 241, 333, 453, 1407, 2687, 4603, 3637, 23041, 0 }; + static ulong[] dim3031KuoInit = { 1, 1, 1, 15, 17, 9, 7, 31, 145, 613, 1851, 1981, 3921, 6469, 32397, 0 }; + static ulong[] dim3032KuoInit = { 1, 1, 5, 3, 9, 39, 113, 79, 165, 359, 1573, 2311, 651, 7047, 15961, 0 }; + static ulong[] dim3033KuoInit = { 1, 3, 7, 7, 11, 57, 59, 153, 363, 279, 77, 3085, 5971, 29, 22087, 0 }; + static ulong[] dim3034KuoInit = { 1, 1, 7, 11, 25, 47, 49, 229, 147, 777, 1177, 1117, 3783, 3681, 1465, 0 }; + static ulong[] dim3035KuoInit = { 1, 3, 5, 11, 3, 45, 11, 139, 393, 9, 471, 1643, 4963, 5837, 17023, 0 }; + static ulong[] dim3036KuoInit = { 1, 3, 1, 7, 5, 41, 123, 113, 223, 237, 239, 1099, 6065, 11105, 10259, 0 }; + static ulong[] dim3037KuoInit = { 1, 1, 3, 11, 15, 57, 41, 173, 169, 585, 201, 2133, 2629, 12861, 16559, 0 }; + static ulong[] dim3038KuoInit = { 1, 1, 7, 5, 9, 27, 3, 157, 279, 393, 1849, 437, 5549, 10009, 11783, 0 }; + static ulong[] dim3039KuoInit = { 1, 1, 7, 9, 17, 23, 67, 143, 1, 203, 153, 1699, 1333, 16001, 11755, 0 }; + static ulong[] dim3040KuoInit = { 1, 3, 5, 15, 17, 61, 59, 235, 67, 393, 1597, 3523, 2049, 11887, 7737, 0 }; + static ulong[] dim3041KuoInit = { 1, 3, 5, 13, 21, 45, 5, 221, 299, 887, 699, 959, 1143, 4879, 8767, 0 }; + static ulong[] dim3042KuoInit = { 1, 3, 7, 15, 11, 35, 83, 237, 167, 1, 1429, 2877, 4611, 14881, 4453, 0 }; + static ulong[] dim3043KuoInit = { 1, 3, 5, 3, 7, 55, 21, 237, 9, 743, 1707, 1229, 6827, 407, 777, 0 }; + static ulong[] dim3044KuoInit = { 1, 3, 7, 3, 15, 39, 3, 127, 163, 747, 1773, 1569, 2377, 15023, 32249, 0 }; + static ulong[] dim3045KuoInit = { 1, 1, 7, 7, 19, 33, 1, 55, 319, 585, 413, 1241, 95, 7163, 29935, 0 }; + static ulong[] dim3046KuoInit = { 1, 3, 1, 1, 7, 51, 77, 197, 481, 517, 1441, 1779, 1405, 3633, 32545, 0 }; + static ulong[] dim3047KuoInit = { 1, 3, 7, 5, 13, 51, 69, 35, 131, 115, 1759, 3991, 8065, 10311, 12749, 0 }; + static ulong[] dim3048KuoInit = { 1, 3, 3, 5, 5, 35, 37, 181, 371, 543, 1389, 815, 3261, 11997, 29665, 0 }; + static ulong[] dim3049KuoInit = { 1, 3, 7, 11, 31, 47, 33, 147, 445, 663, 63, 1033, 6081, 15523, 28477, 0 }; + static ulong[] dim3050KuoInit = { 1, 1, 7, 11, 11, 9, 1, 39, 357, 873, 1829, 3245, 3219, 601, 1335, 0 }; + static ulong[] dim3051KuoInit = { 1, 1, 5, 7, 5, 5, 33, 145, 465, 5, 1959, 3573, 3791, 8689, 14513, 0 }; + static ulong[] dim3052KuoInit = { 1, 1, 1, 13, 31, 37, 103, 255, 87, 903, 1325, 1423, 8031, 14845, 12261, 0 }; + static ulong[] dim3053KuoInit = { 1, 3, 3, 13, 31, 25, 41, 45, 261, 225, 1711, 641, 2331, 10825, 21539, 0 }; + static ulong[] dim3054KuoInit = { 1, 3, 1, 9, 9, 33, 23, 135, 165, 363, 1435, 3019, 4907, 9791, 1337, 0 }; + static ulong[] dim3055KuoInit = { 1, 3, 3, 3, 13, 23, 109, 161, 107, 829, 1635, 791, 2757, 15265, 8771, 0 }; + static ulong[] dim3056KuoInit = { 1, 1, 1, 11, 7, 17, 45, 167, 69, 437, 1051, 1443, 875, 2461, 28471, 0 }; + static ulong[] dim3057KuoInit = { 1, 3, 5, 11, 23, 43, 55, 69, 365, 497, 1529, 1101, 211, 8145, 10579, 0 }; + static ulong[] dim3058KuoInit = { 1, 1, 5, 3, 19, 9, 91, 91, 453, 875, 1815, 1455, 7969, 5621, 4773, 0 }; + static ulong[] dim3059KuoInit = { 1, 1, 5, 1, 17, 63, 19, 193, 335, 571, 703, 919, 773, 1789, 17839, 0 }; + static ulong[] dim3060KuoInit = { 1, 1, 5, 7, 1, 57, 11, 171, 11, 833, 191, 1719, 7649, 11005, 20171, 0 }; + static ulong[] dim3061KuoInit = { 1, 1, 7, 15, 25, 55, 63, 71, 127, 445, 1151, 2709, 6633, 4959, 13511, 0 }; + static ulong[] dim3062KuoInit = { 1, 1, 3, 1, 3, 41, 43, 59, 211, 123, 987, 3701, 6391, 6755, 3069, 0 }; + static ulong[] dim3063KuoInit = { 1, 1, 3, 11, 5, 3, 93, 29, 233, 365, 117, 1483, 4917, 1949, 23697, 0 }; + static ulong[] dim3064KuoInit = { 1, 3, 5, 1, 15, 53, 21, 9, 23, 701, 1337, 2591, 7719, 14063, 28453, 0 }; + static ulong[] dim3065KuoInit = { 1, 1, 1, 11, 21, 3, 127, 179, 409, 261, 1683, 3197, 1999, 10009, 25031, 0 }; + static ulong[] dim3066KuoInit = { 1, 3, 5, 13, 31, 57, 9, 91, 31, 125, 1831, 1943, 5931, 15015, 22269, 0 }; + static ulong[] dim3067KuoInit = { 1, 3, 5, 9, 7, 7, 83, 113, 203, 679, 1279, 3403, 7069, 8617, 27827, 0 }; + static ulong[] dim3068KuoInit = { 1, 3, 7, 5, 29, 47, 93, 59, 315, 107, 807, 2861, 2345, 11787, 6543, 0 }; + static ulong[] dim3069KuoInit = { 1, 3, 1, 7, 21, 25, 3, 35, 345, 833, 2029, 281, 2389, 11529, 20647, 0 }; + static ulong[] dim3070KuoInit = { 1, 1, 1, 13, 19, 47, 109, 21, 251, 625, 1699, 2169, 7293, 14035, 24277, 0 }; + static ulong[] dim3071KuoInit = { 1, 3, 5, 13, 15, 7, 51, 125, 423, 981, 437, 1021, 5209, 11447, 26181, 0 }; + static ulong[] dim3072KuoInit = { 1, 3, 1, 1, 15, 41, 75, 227, 13, 85, 675, 3993, 8163, 8095, 23801, 0 }; + static ulong[] dim3073KuoInit = { 1, 3, 3, 9, 25, 1, 85, 143, 309, 815, 1271, 1331, 6565, 369, 7975, 0 }; + static ulong[] dim3074KuoInit = { 1, 1, 7, 1, 21, 45, 113, 153, 283, 117, 1481, 3527, 3371, 15801, 22337, 0 }; + static ulong[] dim3075KuoInit = { 1, 3, 5, 1, 17, 47, 107, 25, 373, 549, 1387, 1247, 2307, 6469, 24327, 0 }; + static ulong[] dim3076KuoInit = { 1, 1, 5, 15, 9, 57, 43, 179, 157, 119, 547, 3665, 1495, 13405, 2391, 0 }; + static ulong[] dim3077KuoInit = { 1, 3, 1, 1, 7, 57, 123, 189, 281, 87, 1559, 2863, 8017, 10279, 32005, 0 }; + static ulong[] dim3078KuoInit = { 1, 1, 5, 1, 29, 21, 51, 123, 351, 683, 1505, 681, 49, 2929, 7591, 0 }; + static ulong[] dim3079KuoInit = { 1, 1, 3, 7, 17, 63, 119, 209, 441, 717, 567, 1283, 1007, 14661, 32383, 0 }; + static ulong[] dim3080KuoInit = { 1, 3, 1, 7, 27, 41, 41, 157, 487, 257, 1267, 165, 1023, 16065, 16431, 0 }; + static ulong[] dim3081KuoInit = { 1, 1, 3, 9, 17, 53, 51, 175, 367, 453, 1445, 1889, 4567, 1781, 6543, 0 }; + static ulong[] dim3082KuoInit = { 1, 1, 7, 1, 27, 47, 95, 51, 483, 581, 1617, 685, 3017, 4889, 6185, 0 }; + static ulong[] dim3083KuoInit = { 1, 3, 3, 9, 29, 23, 9, 23, 165, 3, 279, 861, 1007, 9607, 24999, 0 }; + static ulong[] dim3084KuoInit = { 1, 1, 1, 5, 11, 59, 55, 135, 399, 729, 683, 2119, 3781, 15525, 1125, 0 }; + static ulong[] dim3085KuoInit = { 1, 3, 3, 15, 25, 61, 123, 153, 267, 823, 951, 4069, 8017, 4899, 6535, 0 }; + static ulong[] dim3086KuoInit = { 1, 1, 7, 11, 5, 43, 5, 123, 57, 229, 129, 131, 7491, 2105, 16411, 0 }; + static ulong[] dim3087KuoInit = { 1, 1, 5, 11, 9, 37, 123, 211, 331, 623, 1469, 1155, 6327, 12591, 18971, 0 }; + static ulong[] dim3088KuoInit = { 1, 1, 1, 11, 17, 35, 59, 137, 451, 829, 365, 305, 5857, 2095, 14597, 0 }; + static ulong[] dim3089KuoInit = { 1, 3, 7, 7, 15, 11, 23, 201, 247, 883, 1103, 4035, 5915, 4275, 12511, 0 }; + static ulong[] dim3090KuoInit = { 1, 3, 7, 1, 27, 19, 87, 189, 91, 113, 237, 2073, 419, 1339, 16705, 0 }; + static ulong[] dim3091KuoInit = { 1, 3, 7, 7, 15, 59, 99, 237, 167, 327, 1507, 771, 3743, 1723, 28873, 0 }; + static ulong[] dim3092KuoInit = { 1, 3, 5, 15, 27, 19, 35, 175, 403, 1, 617, 2425, 2021, 12547, 23655, 0 }; + static ulong[] dim3093KuoInit = { 1, 1, 7, 1, 7, 1, 45, 169, 43, 501, 1653, 593, 7219, 5501, 3671, 0 }; + static ulong[] dim3094KuoInit = { 1, 1, 5, 3, 23, 53, 117, 165, 329, 177, 89, 2269, 7897, 11225, 25807, 0 }; + static ulong[] dim3095KuoInit = { 1, 1, 5, 11, 25, 41, 91, 43, 107, 699, 1745, 3117, 7497, 6579, 21803, 0 }; + static ulong[] dim3096KuoInit = { 1, 3, 3, 13, 19, 9, 103, 65, 413, 459, 1751, 4025, 6695, 9589, 1443, 0 }; + static ulong[] dim3097KuoInit = { 1, 3, 5, 15, 31, 31, 23, 251, 343, 809, 283, 1501, 445, 7945, 26993, 0 }; + static ulong[] dim3098KuoInit = { 1, 3, 7, 11, 1, 11, 113, 235, 127, 45, 109, 2421, 3955, 1017, 21497, 0 }; + static ulong[] dim3099KuoInit = { 1, 3, 1, 13, 5, 57, 47, 227, 447, 499, 1755, 3527, 1625, 13341, 22301, 0 }; + static ulong[] dim3100KuoInit = { 1, 3, 1, 9, 13, 9, 113, 101, 377, 39, 991, 3791, 7351, 12841, 2911, 0 }; + static ulong[] dim3101KuoInit = { 1, 1, 3, 1, 1, 31, 111, 85, 247, 387, 1907, 3061, 569, 5845, 6729, 0 }; + static ulong[] dim3102KuoInit = { 1, 3, 7, 15, 31, 17, 77, 33, 109, 661, 67, 3725, 955, 9475, 14345, 0 }; + static ulong[] dim3103KuoInit = { 1, 1, 7, 15, 11, 23, 63, 23, 67, 843, 1747, 2441, 2063, 8575, 11921, 0 }; + static ulong[] dim3104KuoInit = { 1, 3, 5, 13, 25, 19, 43, 177, 67, 57, 1127, 3817, 3097, 6143, 27757, 0 }; + static ulong[] dim3105KuoInit = { 1, 1, 3, 1, 19, 25, 65, 135, 143, 863, 1013, 1285, 6133, 13491, 5093, 0 }; + static ulong[] dim3106KuoInit = { 1, 3, 5, 15, 7, 17, 61, 199, 39, 767, 295, 127, 335, 10789, 20473, 0 }; + static ulong[] dim3107KuoInit = { 1, 3, 3, 15, 15, 51, 87, 75, 439, 71, 1371, 1911, 1145, 4201, 26883, 0 }; + static ulong[] dim3108KuoInit = { 1, 1, 3, 11, 3, 15, 79, 237, 43, 375, 1925, 1517, 6415, 303, 2217, 0 }; + static ulong[] dim3109KuoInit = { 1, 3, 1, 3, 21, 23, 19, 83, 159, 249, 1297, 1853, 2609, 13635, 29119, 0 }; + static ulong[] dim3110KuoInit = { 1, 1, 3, 9, 29, 53, 125, 73, 299, 45, 557, 3641, 1593, 10585, 22545, 0 }; + static ulong[] dim3111KuoInit = { 1, 1, 3, 9, 13, 45, 53, 245, 401, 635, 785, 2841, 3033, 12377, 1235, 0 }; + static ulong[] dim3112KuoInit = { 1, 1, 3, 11, 23, 35, 71, 207, 211, 901, 351, 1473, 6683, 981, 17449, 0 }; + static ulong[] dim3113KuoInit = { 1, 1, 3, 9, 17, 13, 125, 213, 109, 631, 677, 2141, 1037, 6119, 25945, 0 }; + static ulong[] dim3114KuoInit = { 1, 3, 7, 1, 29, 3, 53, 23, 45, 347, 27, 1537, 7833, 16315, 12337, 0 }; + static ulong[] dim3115KuoInit = { 1, 3, 1, 1, 31, 23, 15, 241, 315, 977, 99, 3067, 3227, 6153, 9751, 0 }; + static ulong[] dim3116KuoInit = { 1, 1, 7, 7, 13, 33, 5, 5, 29, 547, 1105, 1135, 7263, 7421, 9545, 0 }; + static ulong[] dim3117KuoInit = { 1, 3, 7, 13, 19, 25, 53, 239, 65, 417, 1681, 659, 133, 4113, 16735, 0 }; + static ulong[] dim3118KuoInit = { 1, 3, 7, 5, 3, 55, 57, 33, 357, 885, 941, 3471, 6863, 777, 19111, 0 }; + static ulong[] dim3119KuoInit = { 1, 1, 1, 9, 27, 47, 65, 161, 115, 577, 1951, 363, 2045, 2497, 6931, 0 }; + static ulong[] dim3120KuoInit = { 1, 3, 3, 11, 29, 37, 21, 235, 233, 833, 81, 2875, 4759, 8435, 16017, 0 }; + static ulong[] dim3121KuoInit = { 1, 1, 3, 7, 9, 57, 89, 21, 291, 445, 1833, 735, 3935, 14943, 30987, 0 }; + static ulong[] dim3122KuoInit = { 1, 1, 5, 13, 23, 9, 37, 71, 175, 899, 1897, 707, 6201, 15543, 13801, 0 }; + static ulong[] dim3123KuoInit = { 1, 3, 7, 1, 13, 25, 17, 209, 455, 969, 755, 397, 4103, 3159, 28665, 0 }; + static ulong[] dim3124KuoInit = { 1, 1, 1, 5, 15, 7, 17, 249, 299, 423, 83, 1203, 7397, 15657, 15661, 0 }; + static ulong[] dim3125KuoInit = { 1, 1, 7, 7, 19, 19, 21, 231, 443, 729, 947, 1451, 3399, 5691, 11943, 0 }; + static ulong[] dim3126KuoInit = { 1, 1, 5, 7, 15, 11, 89, 211, 459, 3, 741, 105, 1147, 927, 31805, 0 }; + static ulong[] dim3127KuoInit = { 1, 1, 7, 9, 7, 1, 61, 145, 291, 1021, 221, 821, 4999, 3165, 22549, 0 }; + static ulong[] dim3128KuoInit = { 1, 1, 1, 7, 5, 41, 101, 137, 143, 249, 87, 4045, 2301, 3833, 9841, 0 }; + static ulong[] dim3129KuoInit = { 1, 1, 5, 5, 19, 61, 111, 109, 87, 65, 971, 3943, 6559, 9647, 3049, 0 }; + static ulong[] dim3130KuoInit = { 1, 1, 1, 13, 9, 11, 41, 61, 145, 27, 1287, 3537, 1943, 10635, 32557, 0 }; + static ulong[] dim3131KuoInit = { 1, 3, 5, 7, 17, 35, 29, 177, 5, 131, 465, 1235, 1383, 14253, 17595, 0 }; + static ulong[] dim3132KuoInit = { 1, 1, 3, 7, 15, 63, 21, 119, 195, 627, 1635, 2369, 5549, 7641, 29481, 0 }; + static ulong[] dim3133KuoInit = { 1, 1, 7, 13, 25, 3, 73, 233, 115, 749, 707, 1939, 3667, 1899, 22345, 0 }; + static ulong[] dim3134KuoInit = { 1, 1, 5, 9, 15, 33, 17, 91, 507, 289, 1929, 2001, 629, 15559, 12725, 0 }; + static ulong[] dim3135KuoInit = { 1, 1, 1, 13, 7, 7, 91, 171, 95, 257, 1611, 3527, 2769, 5779, 7783, 0 }; + static ulong[] dim3136KuoInit = { 1, 1, 1, 13, 27, 27, 55, 113, 171, 61, 1229, 3681, 4487, 9815, 20357, 0 }; + static ulong[] dim3137KuoInit = { 1, 3, 7, 15, 1, 21, 57, 67, 185, 189, 1673, 3637, 2987, 4619, 6339, 0 }; + static ulong[] dim3138KuoInit = { 1, 3, 7, 3, 9, 45, 71, 183, 107, 145, 821, 1115, 6067, 8301, 7565, 0 }; + static ulong[] dim3139KuoInit = { 1, 3, 5, 1, 21, 29, 85, 9, 427, 553, 887, 2463, 4023, 9107, 25405, 0 }; + static ulong[] dim3140KuoInit = { 1, 1, 5, 13, 25, 45, 89, 235, 349, 671, 1667, 2023, 2385, 1831, 515, 0 }; + static ulong[] dim3141KuoInit = { 1, 1, 1, 11, 17, 37, 95, 77, 445, 169, 829, 9, 2589, 12809, 32469, 0 }; + static ulong[] dim3142KuoInit = { 1, 1, 5, 5, 23, 31, 117, 81, 275, 861, 1439, 4041, 3337, 14945, 15921, 0 }; + static ulong[] dim3143KuoInit = { 1, 1, 3, 13, 9, 21, 121, 23, 133, 563, 1889, 1939, 4427, 5501, 4609, 0 }; + static ulong[] dim3144KuoInit = { 1, 1, 7, 7, 17, 25, 7, 245, 319, 697, 1561, 3209, 2369, 16045, 31799, 0 }; + static ulong[] dim3145KuoInit = { 1, 1, 7, 5, 13, 19, 83, 165, 457, 1005, 743, 4049, 2563, 14487, 23699, 0 }; + static ulong[] dim3146KuoInit = { 1, 1, 7, 1, 5, 25, 65, 185, 27, 235, 1771, 3505, 6807, 14715, 19841, 0 }; + static ulong[] dim3147KuoInit = { 1, 1, 7, 11, 15, 15, 19, 111, 99, 397, 315, 2587, 7335, 4371, 11753, 0 }; + static ulong[] dim3148KuoInit = { 1, 1, 7, 9, 1, 21, 55, 255, 105, 865, 179, 2127, 4485, 1803, 19503, 0 }; + static ulong[] dim3149KuoInit = { 1, 3, 7, 13, 27, 23, 9, 9, 323, 421, 671, 3323, 5263, 2963, 16065, 0 }; + static ulong[] dim3150KuoInit = { 1, 1, 5, 7, 17, 47, 79, 255, 259, 913, 1691, 1553, 2443, 14167, 24499, 0 }; + static ulong[] dim3151KuoInit = { 1, 3, 3, 3, 21, 7, 17, 71, 57, 715, 2023, 2133, 5439, 12483, 32547, 0 }; + static ulong[] dim3152KuoInit = { 1, 3, 3, 15, 1, 37, 23, 235, 35, 739, 1767, 3531, 597, 13259, 7869, 0 }; + static ulong[] dim3153KuoInit = { 1, 3, 3, 9, 7, 5, 29, 129, 223, 991, 31, 375, 1917, 1157, 9723, 0 }; + static ulong[] dim3154KuoInit = { 1, 3, 5, 5, 29, 33, 33, 73, 339, 21, 2037, 1127, 6385, 16335, 25825, 0 }; + static ulong[] dim3155KuoInit = { 1, 3, 7, 7, 7, 49, 103, 235, 503, 687, 277, 2639, 5997, 11797, 27141, 0 }; + static ulong[] dim3156KuoInit = { 1, 1, 1, 13, 27, 31, 103, 145, 245, 493, 867, 2075, 5369, 12551, 4907, 0 }; + static ulong[] dim3157KuoInit = { 1, 3, 1, 5, 19, 57, 101, 165, 61, 201, 1299, 3081, 8173, 12835, 7915, 0 }; + static ulong[] dim3158KuoInit = { 1, 3, 5, 3, 29, 23, 49, 41, 473, 273, 1493, 1915, 6669, 14263, 13385, 0 }; + static ulong[] dim3159KuoInit = { 1, 1, 5, 9, 21, 27, 49, 73, 281, 1017, 1905, 1005, 631, 5963, 5729, 0 }; + static ulong[] dim3160KuoInit = { 1, 3, 3, 5, 9, 25, 1, 155, 275, 675, 831, 109, 5349, 9607, 22431, 0 }; + static ulong[] dim3161KuoInit = { 1, 1, 1, 3, 11, 33, 43, 63, 293, 425, 1525, 4091, 1865, 13187, 25191, 0 }; + static ulong[] dim3162KuoInit = { 1, 1, 1, 7, 27, 25, 89, 39, 11, 961, 1601, 785, 3317, 13121, 13647, 0 }; + static ulong[] dim3163KuoInit = { 1, 1, 7, 1, 31, 59, 25, 75, 317, 305, 1585, 3649, 7099, 1819, 10977, 0 }; + static ulong[] dim3164KuoInit = { 1, 3, 7, 5, 7, 29, 85, 189, 137, 783, 395, 1887, 6253, 4043, 32279, 0 }; + static ulong[] dim3165KuoInit = { 1, 1, 3, 7, 15, 47, 53, 125, 325, 579, 1783, 3393, 485, 13923, 4947, 0 }; + static ulong[] dim3166KuoInit = { 1, 3, 5, 1, 19, 53, 67, 47, 503, 875, 1717, 857, 5151, 12279, 21249, 0 }; + static ulong[] dim3167KuoInit = { 1, 1, 5, 11, 1, 53, 49, 211, 139, 955, 1129, 1967, 6833, 2923, 13251, 0 }; + static ulong[] dim3168KuoInit = { 1, 3, 3, 9, 15, 53, 103, 71, 51, 379, 1565, 2017, 6013, 13147, 1227, 0 }; + static ulong[] dim3169KuoInit = { 1, 3, 3, 1, 17, 25, 105, 177, 275, 969, 1373, 2471, 6959, 11107, 23657, 0 }; + static ulong[] dim3170KuoInit = { 1, 3, 1, 13, 15, 3, 19, 145, 309, 1021, 985, 2385, 5727, 10357, 4915, 0 }; + static ulong[] dim3171KuoInit = { 1, 3, 1, 9, 27, 33, 63, 115, 369, 613, 277, 751, 1959, 5709, 1851, 0 }; + static ulong[] dim3172KuoInit = { 1, 1, 7, 7, 11, 31, 95, 131, 383, 821, 725, 1381, 3953, 14945, 29101, 0 }; + static ulong[] dim3173KuoInit = { 1, 1, 1, 11, 1, 59, 81, 89, 325, 27, 1865, 987, 3877, 12509, 4129, 0 }; + static ulong[] dim3174KuoInit = { 1, 3, 5, 7, 3, 33, 63, 141, 429, 847, 1355, 1451, 4741, 5427, 16907, 0 }; + static ulong[] dim3175KuoInit = { 1, 3, 5, 9, 25, 45, 27, 249, 453, 673, 1519, 905, 5235, 10057, 24965, 0 }; + static ulong[] dim3176KuoInit = { 1, 1, 5, 3, 27, 43, 91, 61, 121, 485, 1047, 405, 8159, 8363, 19695, 0 }; + static ulong[] dim3177KuoInit = { 1, 1, 3, 9, 17, 5, 107, 139, 293, 685, 521, 253, 3309, 15335, 4967, 0 }; + static ulong[] dim3178KuoInit = { 1, 1, 7, 13, 7, 43, 63, 119, 225, 269, 1489, 2983, 1041, 15149, 21039, 0 }; + static ulong[] dim3179KuoInit = { 1, 3, 1, 5, 5, 1, 123, 255, 469, 139, 1861, 385, 3123, 14739, 23049, 0 }; + static ulong[] dim3180KuoInit = { 1, 3, 5, 9, 25, 47, 107, 55, 435, 935, 1751, 555, 973, 10123, 31869, 0 }; + static ulong[] dim3181KuoInit = { 1, 3, 7, 5, 21, 25, 113, 169, 313, 607, 631, 3409, 6539, 5781, 12681, 0 }; + static ulong[] dim3182KuoInit = { 1, 1, 3, 15, 7, 13, 1, 245, 57, 495, 905, 1627, 7107, 13939, 22091, 0 }; + static ulong[] dim3183KuoInit = { 1, 1, 1, 5, 7, 55, 121, 137, 93, 265, 1263, 2251, 7101, 3095, 13779, 0 }; + static ulong[] dim3184KuoInit = { 1, 1, 5, 13, 21, 11, 37, 193, 481, 551, 1659, 563, 4405, 9541, 8495, 0 }; + static ulong[] dim3185KuoInit = { 1, 1, 3, 15, 5, 7, 23, 19, 147, 779, 1089, 723, 3837, 16291, 23911, 0 }; + static ulong[] dim3186KuoInit = { 1, 1, 1, 11, 27, 17, 57, 191, 337, 361, 1261, 3605, 8051, 8909, 14951, 0 }; + static ulong[] dim3187KuoInit = { 1, 3, 3, 9, 25, 23, 39, 109, 107, 605, 373, 649, 5747, 2037, 24933, 0 }; + static ulong[] dim3188KuoInit = { 1, 3, 5, 7, 9, 27, 91, 53, 153, 497, 941, 2999, 3721, 11115, 17589, 0 }; + static ulong[] dim3189KuoInit = { 1, 3, 1, 7, 31, 7, 101, 115, 419, 479, 1097, 2253, 4365, 14285, 26469, 0 }; + static ulong[] dim3190KuoInit = { 1, 1, 1, 15, 13, 37, 31, 231, 195, 539, 941, 3723, 2483, 2603, 18897, 0 }; + static ulong[] dim3191KuoInit = { 1, 3, 5, 13, 7, 31, 19, 99, 197, 833, 79, 3899, 7045, 6913, 17959, 0 }; + static ulong[] dim3192KuoInit = { 1, 1, 3, 5, 1, 51, 83, 135, 307, 121, 187, 2135, 2927, 6183, 20327, 0 }; + static ulong[] dim3193KuoInit = { 1, 3, 5, 11, 7, 31, 47, 123, 409, 239, 1787, 3063, 6685, 7487, 31243, 0 }; + static ulong[] dim3194KuoInit = { 1, 3, 7, 9, 9, 31, 57, 5, 493, 771, 1941, 199, 6389, 681, 19379, 0 }; + static ulong[] dim3195KuoInit = { 1, 1, 5, 3, 1, 57, 63, 35, 369, 267, 923, 2019, 6487, 15555, 6993, 0 }; + static ulong[] dim3196KuoInit = { 1, 3, 7, 15, 15, 59, 123, 179, 5, 35, 1061, 125, 1025, 5907, 29671, 0 }; + static ulong[] dim3197KuoInit = { 1, 3, 1, 11, 21, 63, 71, 237, 333, 893, 1139, 1969, 2007, 10017, 27597, 0 }; + static ulong[] dim3198KuoInit = { 1, 1, 1, 13, 15, 29, 103, 241, 25, 135, 1147, 1263, 4793, 16109, 22447, 0 }; + static ulong[] dim3199KuoInit = { 1, 1, 3, 7, 11, 21, 85, 7, 123, 69, 1379, 3243, 7907, 15859, 19993, 0 }; + static ulong[] dim3200KuoInit = { 1, 3, 5, 3, 17, 49, 125, 211, 165, 307, 1331, 2287, 1127, 4031, 13719, 0 }; + static ulong[] dim3201KuoInit = { 1, 1, 7, 1, 23, 23, 21, 159, 387, 443, 291, 2843, 4413, 9035, 28887, 0 }; + static ulong[] dim3202KuoInit = { 1, 1, 7, 15, 9, 25, 113, 185, 285, 211, 317, 3721, 6921, 4921, 2353, 0 }; + static ulong[] dim3203KuoInit = { 1, 1, 3, 5, 21, 9, 53, 21, 337, 51, 429, 4035, 4697, 3695, 22589, 0 }; + static ulong[] dim3204KuoInit = { 1, 1, 5, 5, 21, 63, 79, 213, 471, 183, 299, 409, 6125, 3653, 9785, 0 }; + static ulong[] dim3205KuoInit = { 1, 3, 3, 3, 27, 27, 9, 73, 129, 391, 1877, 4023, 1631, 7101, 1491, 0 }; + static ulong[] dim3206KuoInit = { 1, 3, 5, 3, 21, 7, 93, 51, 469, 3, 1343, 3827, 6623, 10149, 29233, 0 }; + static ulong[] dim3207KuoInit = { 1, 1, 1, 9, 31, 25, 35, 249, 469, 393, 1315, 1247, 275, 15841, 23877, 0 }; + static ulong[] dim3208KuoInit = { 1, 3, 5, 11, 25, 47, 105, 45, 79, 131, 499, 1411, 2077, 9809, 14917, 0 }; + static ulong[] dim3209KuoInit = { 1, 3, 3, 3, 13, 15, 117, 27, 499, 885, 301, 935, 3443, 3845, 26873, 0 }; + static ulong[] dim3210KuoInit = { 1, 3, 3, 1, 1, 47, 21, 97, 245, 95, 899, 993, 2493, 5249, 32695, 0 }; + static ulong[] dim3211KuoInit = { 1, 3, 3, 11, 21, 39, 53, 15, 53, 687, 1269, 1673, 2015, 3205, 21447, 0 }; + static ulong[] dim3212KuoInit = { 1, 1, 5, 11, 1, 39, 117, 85, 277, 635, 1459, 3977, 2449, 13341, 30607, 0 }; + static ulong[] dim3213KuoInit = { 1, 1, 1, 13, 27, 45, 7, 255, 281, 807, 533, 2173, 4561, 2501, 5767, 0 }; + static ulong[] dim3214KuoInit = { 1, 3, 5, 1, 21, 17, 65, 123, 239, 431, 1003, 241, 8115, 11633, 27709, 0 }; + static ulong[] dim3215KuoInit = { 1, 3, 1, 1, 23, 39, 81, 35, 33, 905, 2019, 3327, 1197, 6891, 5521, 0 }; + static ulong[] dim3216KuoInit = { 1, 3, 3, 11, 1, 51, 51, 153, 23, 685, 1663, 3167, 5803, 11111, 3371, 0 }; + static ulong[] dim3217KuoInit = { 1, 3, 3, 11, 31, 29, 7, 173, 27, 129, 341, 2971, 4907, 13481, 19619, 0 }; + static ulong[] dim3218KuoInit = { 1, 3, 3, 9, 29, 29, 115, 3, 45, 765, 385, 3775, 5349, 8809, 11019, 0 }; + static ulong[] dim3219KuoInit = { 1, 1, 5, 7, 15, 19, 21, 29, 377, 915, 1835, 517, 3763, 5439, 7649, 0 }; + static ulong[] dim3220KuoInit = { 1, 3, 7, 13, 25, 27, 33, 225, 135, 869, 1383, 3817, 2981, 8185, 5689, 0 }; + static ulong[] dim3221KuoInit = { 1, 1, 5, 9, 1, 27, 19, 55, 39, 451, 365, 2905, 4311, 16005, 4537, 0 }; + static ulong[] dim3222KuoInit = { 1, 1, 7, 15, 19, 1, 99, 177, 163, 877, 511, 1977, 3291, 7739, 6383, 0 }; + static ulong[] dim3223KuoInit = { 1, 1, 7, 15, 1, 29, 27, 1, 411, 425, 2027, 1739, 5137, 107, 3515, 0 }; + static ulong[] dim3224KuoInit = { 1, 3, 7, 5, 5, 29, 15, 55, 423, 671, 1145, 2403, 5429, 11507, 24747, 0 }; + static ulong[] dim3225KuoInit = { 1, 1, 1, 13, 9, 61, 93, 215, 447, 969, 853, 487, 5735, 2153, 27857, 0 }; + static ulong[] dim3226KuoInit = { 1, 3, 1, 3, 29, 41, 47, 245, 197, 261, 77, 805, 965, 14089, 29199, 0 }; + static ulong[] dim3227KuoInit = { 1, 1, 5, 11, 3, 49, 53, 7, 91, 123, 413, 123, 7611, 11493, 16417, 0 }; + static ulong[] dim3228KuoInit = { 1, 3, 7, 9, 23, 59, 105, 191, 13, 421, 1541, 2045, 2821, 9769, 19893, 0 }; + static ulong[] dim3229KuoInit = { 1, 3, 5, 13, 3, 19, 37, 229, 465, 1015, 1871, 1101, 7515, 8547, 7853, 0 }; + static ulong[] dim3230KuoInit = { 1, 3, 5, 13, 9, 61, 113, 209, 503, 441, 905, 2693, 1827, 9551, 26081, 0 }; + static ulong[] dim3231KuoInit = { 1, 1, 1, 7, 31, 27, 123, 37, 415, 729, 921, 453, 673, 14393, 9139, 0 }; + static ulong[] dim3232KuoInit = { 1, 1, 5, 3, 13, 9, 79, 243, 211, 89, 295, 3663, 8165, 12099, 1413, 0 }; + static ulong[] dim3233KuoInit = { 1, 1, 5, 7, 23, 33, 33, 129, 51, 965, 1145, 713, 8143, 10045, 5291, 0 }; + static ulong[] dim3234KuoInit = { 1, 1, 3, 3, 11, 45, 77, 223, 423, 1021, 343, 3103, 119, 3371, 24053, 0 }; + static ulong[] dim3235KuoInit = { 1, 1, 7, 7, 7, 3, 65, 31, 433, 277, 1541, 2001, 121, 13543, 6723, 0 }; + static ulong[] dim3236KuoInit = { 1, 1, 7, 1, 1, 15, 83, 85, 351, 351, 1063, 3989, 5739, 11939, 28009, 0 }; + static ulong[] dim3237KuoInit = { 1, 1, 5, 11, 25, 57, 73, 127, 25, 67, 1789, 199, 6373, 10945, 17839, 0 }; + static ulong[] dim3238KuoInit = { 1, 3, 5, 11, 17, 15, 5, 191, 209, 455, 89, 2611, 7557, 16167, 25993, 0 }; + static ulong[] dim3239KuoInit = { 1, 1, 7, 7, 29, 21, 79, 81, 257, 373, 557, 2363, 5497, 8343, 2011, 0 }; + static ulong[] dim3240KuoInit = { 1, 1, 5, 11, 25, 63, 83, 31, 477, 201, 2013, 3349, 3517, 9527, 14883, 0 }; + static ulong[] dim3241KuoInit = { 1, 3, 7, 13, 21, 13, 41, 151, 359, 829, 661, 1959, 6109, 13757, 17677, 0 }; + static ulong[] dim3242KuoInit = { 1, 3, 7, 1, 11, 15, 119, 25, 351, 135, 515, 3727, 5701, 5283, 18771, 0 }; + static ulong[] dim3243KuoInit = { 1, 1, 1, 3, 3, 59, 55, 117, 269, 161, 645, 3459, 8173, 7193, 10275, 0 }; + static ulong[] dim3244KuoInit = { 1, 3, 5, 7, 21, 25, 53, 211, 237, 775, 43, 3613, 5555, 1689, 1781, 0 }; + static ulong[] dim3245KuoInit = { 1, 1, 1, 7, 31, 43, 71, 201, 371, 457, 1757, 2529, 7067, 2987, 3945, 0 }; + static ulong[] dim3246KuoInit = { 1, 1, 5, 7, 15, 47, 29, 83, 259, 813, 881, 1901, 6635, 8515, 20385, 0 }; + static ulong[] dim3247KuoInit = { 1, 1, 5, 5, 3, 45, 55, 43, 17, 179, 1801, 49, 8121, 9333, 12701, 0 }; + static ulong[] dim3248KuoInit = { 1, 1, 3, 9, 21, 9, 55, 59, 275, 775, 1567, 1557, 3465, 5727, 12881, 0 }; + static ulong[] dim3249KuoInit = { 1, 1, 1, 5, 21, 63, 81, 27, 139, 859, 1211, 3787, 1179, 4045, 26225, 0 }; + static ulong[] dim3250KuoInit = { 1, 3, 7, 3, 7, 5, 99, 125, 499, 437, 1141, 3557, 5349, 2701, 25741, 0 }; + static ulong[] dim3251KuoInit = { 1, 1, 5, 1, 7, 59, 65, 117, 201, 351, 1063, 3083, 6637, 5969, 23037, 0 }; + static ulong[] dim3252KuoInit = { 1, 3, 7, 7, 25, 45, 115, 31, 351, 203, 1791, 2931, 7127, 12117, 10781, 0 }; + static ulong[] dim3253KuoInit = { 1, 1, 3, 3, 29, 59, 85, 101, 147, 219, 1293, 1645, 7653, 649, 32221, 0 }; + static ulong[] dim3254KuoInit = { 1, 1, 7, 5, 29, 51, 127, 139, 205, 77, 859, 2277, 2333, 105, 9053, 0 }; + static ulong[] dim3255KuoInit = { 1, 3, 5, 3, 29, 23, 119, 71, 263, 551, 1095, 359, 6223, 7665, 1095, 0 }; + static ulong[] dim3256KuoInit = { 1, 3, 1, 11, 13, 47, 11, 207, 507, 139, 1383, 1339, 4111, 11685, 12607, 0 }; + static ulong[] dim3257KuoInit = { 1, 3, 7, 3, 25, 9, 87, 117, 21, 289, 351, 225, 4045, 5275, 531, 0 }; + static ulong[] dim3258KuoInit = { 1, 3, 7, 3, 29, 55, 31, 57, 83, 423, 201, 4055, 1977, 8891, 17961, 0 }; + static ulong[] dim3259KuoInit = { 1, 1, 1, 3, 9, 7, 45, 237, 413, 53, 1063, 23, 6615, 16359, 4743, 0 }; + static ulong[] dim3260KuoInit = { 1, 3, 1, 3, 21, 57, 63, 221, 111, 95, 647, 3419, 1919, 923, 8357, 0 }; + static ulong[] dim3261KuoInit = { 1, 1, 1, 3, 27, 25, 119, 237, 397, 73, 41, 17, 6839, 15695, 30365, 0 }; + static ulong[] dim3262KuoInit = { 1, 3, 1, 1, 23, 59, 107, 121, 267, 163, 181, 2289, 167, 7077, 12895, 0 }; + static ulong[] dim3263KuoInit = { 1, 1, 5, 5, 15, 45, 45, 179, 195, 95, 43, 377, 629, 11983, 23439, 0 }; + static ulong[] dim3264KuoInit = { 1, 3, 3, 9, 17, 43, 67, 143, 223, 243, 209, 3, 7651, 12607, 3927, 0 }; + static ulong[] dim3265KuoInit = { 1, 3, 1, 11, 19, 21, 59, 75, 353, 509, 1215, 3223, 2373, 3873, 20391, 0 }; + static ulong[] dim3266KuoInit = { 1, 1, 7, 3, 7, 9, 53, 89, 407, 987, 1165, 2473, 4295, 2531, 5615, 0 }; + static ulong[] dim3267KuoInit = { 1, 1, 3, 11, 23, 7, 111, 147, 49, 627, 1769, 3497, 2807, 4743, 26491, 0 }; + static ulong[] dim3268KuoInit = { 1, 3, 3, 13, 29, 29, 83, 57, 377, 581, 1699, 1689, 2297, 1377, 24551, 0 }; + static ulong[] dim3269KuoInit = { 1, 3, 5, 15, 25, 33, 41, 187, 195, 647, 73, 619, 5585, 8379, 26079, 0 }; + static ulong[] dim3270KuoInit = { 1, 1, 3, 9, 3, 47, 105, 83, 501, 843, 1867, 1855, 6347, 3269, 26155, 0 }; + static ulong[] dim3271KuoInit = { 1, 3, 3, 15, 29, 33, 117, 141, 171, 801, 1489, 1, 4081, 15529, 4081, 0 }; + static ulong[] dim3272KuoInit = { 1, 1, 3, 13, 21, 43, 13, 75, 75, 443, 1443, 3227, 907, 11821, 24209, 0 }; + static ulong[] dim3273KuoInit = { 1, 1, 3, 3, 31, 31, 111, 193, 275, 545, 371, 3071, 3491, 6661, 1113, 0 }; + static ulong[] dim3274KuoInit = { 1, 1, 7, 3, 11, 39, 17, 107, 303, 201, 321, 3083, 6839, 4381, 3449, 0 }; + static ulong[] dim3275KuoInit = { 1, 1, 7, 15, 31, 21, 7, 143, 211, 369, 369, 323, 3811, 5131, 11425, 0 }; + static ulong[] dim3276KuoInit = { 1, 1, 1, 3, 9, 27, 23, 21, 349, 607, 529, 1161, 5753, 6015, 20489, 0 }; + static ulong[] dim3277KuoInit = { 1, 3, 7, 11, 23, 17, 103, 97, 227, 933, 2011, 1705, 5185, 299, 5673, 0 }; + static ulong[] dim3278KuoInit = { 1, 3, 5, 9, 7, 45, 63, 43, 339, 299, 1617, 1393, 4507, 13513, 29039, 0 }; + static ulong[] dim3279KuoInit = { 1, 1, 5, 5, 17, 11, 49, 159, 51, 449, 497, 2627, 1541, 15711, 16591, 0 }; + static ulong[] dim3280KuoInit = { 1, 1, 7, 3, 23, 19, 53, 79, 133, 279, 327, 2847, 5825, 14429, 26491, 0 }; + static ulong[] dim3281KuoInit = { 1, 3, 1, 3, 17, 3, 33, 55, 263, 663, 1253, 1509, 4487, 1811, 32123, 0 }; + static ulong[] dim3282KuoInit = { 1, 3, 7, 9, 17, 7, 23, 87, 221, 183, 1577, 1373, 2717, 3323, 24573, 0 }; + static ulong[] dim3283KuoInit = { 1, 3, 3, 9, 5, 51, 45, 11, 11, 135, 505, 221, 3847, 13487, 23843, 0 }; + static ulong[] dim3284KuoInit = { 1, 1, 5, 13, 15, 61, 85, 53, 321, 433, 61, 3377, 3993, 15325, 8641, 0 }; + static ulong[] dim3285KuoInit = { 1, 3, 7, 13, 27, 35, 57, 43, 509, 595, 2033, 77, 7533, 5027, 15567, 0 }; + static ulong[] dim3286KuoInit = { 1, 1, 1, 1, 31, 51, 69, 157, 105, 797, 249, 2033, 2457, 10773, 31537, 0 }; + static ulong[] dim3287KuoInit = { 1, 3, 3, 13, 23, 25, 75, 11, 145, 361, 819, 3689, 5751, 6395, 30685, 0 }; + static ulong[] dim3288KuoInit = { 1, 1, 7, 11, 13, 25, 13, 175, 11, 685, 835, 2641, 2037, 2037, 2807, 0 }; + static ulong[] dim3289KuoInit = { 1, 1, 7, 11, 21, 27, 115, 91, 21, 105, 1817, 2057, 2797, 3825, 23761, 0 }; + static ulong[] dim3290KuoInit = { 1, 3, 3, 5, 5, 49, 51, 57, 425, 959, 473, 575, 6851, 3683, 27429, 0 }; + static ulong[] dim3291KuoInit = { 1, 1, 7, 5, 29, 1, 65, 13, 447, 467, 1193, 4021, 275, 13453, 29749, 0 }; + static ulong[] dim3292KuoInit = { 1, 3, 5, 11, 27, 53, 71, 63, 125, 545, 1673, 3917, 6625, 12805, 2905, 0 }; + static ulong[] dim3293KuoInit = { 1, 3, 3, 1, 7, 1, 45, 65, 23, 237, 1573, 3445, 6307, 5015, 11263, 0 }; + static ulong[] dim3294KuoInit = { 1, 1, 5, 1, 7, 29, 67, 35, 307, 675, 727, 2789, 2353, 13241, 16621, 0 }; + static ulong[] dim3295KuoInit = { 1, 3, 1, 15, 13, 5, 115, 75, 21, 745, 2027, 265, 3583, 1365, 397, 0 }; + static ulong[] dim3296KuoInit = { 1, 1, 5, 7, 9, 31, 115, 25, 441, 433, 1665, 2499, 5765, 4001, 22105, 0 }; + static ulong[] dim3297KuoInit = { 1, 3, 7, 9, 23, 21, 71, 165, 353, 101, 1335, 3411, 1415, 12641, 21961, 0 }; + static ulong[] dim3298KuoInit = { 1, 3, 7, 1, 3, 3, 21, 157, 85, 117, 469, 1573, 2475, 6471, 15975, 0 }; + static ulong[] dim3299KuoInit = { 1, 1, 7, 9, 31, 35, 127, 221, 447, 697, 1393, 701, 7291, 4279, 2897, 0 }; + static ulong[] dim3300KuoInit = { 1, 3, 5, 5, 21, 13, 15, 15, 395, 519, 1985, 2331, 5483, 13905, 31549, 0 }; + static ulong[] dim3301KuoInit = { 1, 1, 7, 5, 1, 43, 57, 131, 7, 893, 1631, 1581, 6691, 6249, 4975, 0 }; + static ulong[] dim3302KuoInit = { 1, 3, 3, 9, 29, 33, 51, 177, 423, 459, 1293, 2467, 3877, 15653, 2727, 0 }; + static ulong[] dim3303KuoInit = { 1, 3, 5, 1, 5, 45, 11, 27, 311, 645, 283, 65, 5913, 12811, 20041, 0 }; + static ulong[] dim3304KuoInit = { 1, 3, 7, 5, 19, 3, 39, 99, 269, 429, 1901, 2213, 6755, 1205, 16073, 0 }; + static ulong[] dim3305KuoInit = { 1, 3, 5, 13, 7, 37, 109, 113, 395, 981, 1991, 845, 2473, 3801, 24405, 0 }; + static ulong[] dim3306KuoInit = { 1, 1, 1, 15, 9, 31, 117, 213, 141, 867, 387, 1985, 1985, 12683, 20501, 0 }; + static ulong[] dim3307KuoInit = { 1, 1, 1, 15, 11, 3, 25, 31, 375, 437, 645, 335, 207, 14915, 2577, 0 }; + static ulong[] dim3308KuoInit = { 1, 1, 7, 7, 19, 61, 87, 107, 53, 777, 31, 3335, 157, 2927, 25905, 0 }; + static ulong[] dim3309KuoInit = { 1, 1, 7, 9, 13, 13, 21, 151, 51, 501, 213, 2177, 2821, 3081, 5955, 0 }; + static ulong[] dim3310KuoInit = { 1, 1, 5, 13, 19, 33, 5, 209, 283, 613, 281, 715, 297, 15033, 20489, 0 }; + static ulong[] dim3311KuoInit = { 1, 3, 5, 5, 31, 7, 31, 49, 5, 41, 939, 2359, 3663, 10151, 20457, 0 }; + static ulong[] dim3312KuoInit = { 1, 1, 7, 1, 7, 61, 69, 255, 17, 637, 863, 3351, 6033, 5005, 23107, 0 }; + static ulong[] dim3313KuoInit = { 1, 1, 5, 3, 5, 61, 15, 87, 111, 383, 1577, 3515, 789, 4219, 2527, 0 }; + static ulong[] dim3314KuoInit = { 1, 1, 5, 11, 19, 9, 37, 61, 329, 811, 1829, 3109, 397, 2065, 32001, 0 }; + static ulong[] dim3315KuoInit = { 1, 3, 1, 9, 7, 13, 55, 7, 463, 307, 1551, 3161, 649, 14073, 20839, 0 }; + static ulong[] dim3316KuoInit = { 1, 3, 1, 9, 1, 43, 71, 87, 149, 557, 857, 2739, 6269, 3297, 26067, 0 }; + static ulong[] dim3317KuoInit = { 1, 3, 1, 5, 5, 29, 45, 159, 125, 389, 627, 983, 755, 15585, 12555, 0 }; + static ulong[] dim3318KuoInit = { 1, 1, 3, 7, 9, 53, 79, 29, 423, 423, 1493, 61, 1631, 5157, 29845, 0 }; + static ulong[] dim3319KuoInit = { 1, 3, 5, 9, 23, 27, 57, 235, 57, 833, 371, 1797, 4541, 12491, 23127, 0 }; + static ulong[] dim3320KuoInit = { 1, 3, 3, 1, 17, 1, 79, 87, 247, 987, 651, 3167, 4423, 831, 16811, 0 }; + static ulong[] dim3321KuoInit = { 1, 3, 3, 5, 15, 23, 51, 167, 421, 493, 1877, 1079, 4147, 13485, 28619, 0 }; + static ulong[] dim3322KuoInit = { 1, 1, 7, 13, 19, 15, 69, 31, 225, 597, 1477, 2363, 6969, 13221, 2561, 0 }; + static ulong[] dim3323KuoInit = { 1, 3, 1, 7, 19, 61, 75, 199, 103, 823, 375, 1301, 4349, 135, 5701, 0 }; + static ulong[] dim3324KuoInit = { 1, 3, 7, 11, 21, 25, 85, 249, 91, 885, 469, 1809, 4351, 14393, 19607, 0 }; + static ulong[] dim3325KuoInit = { 1, 3, 5, 1, 25, 19, 71, 111, 427, 523, 1691, 4085, 7587, 1949, 10471, 0 }; + static ulong[] dim3326KuoInit = { 1, 3, 1, 11, 27, 59, 13, 117, 155, 369, 1767, 2951, 6109, 13867, 13887, 0 }; + static ulong[] dim3327KuoInit = { 1, 3, 3, 3, 31, 53, 35, 101, 295, 653, 337, 2281, 7563, 8847, 15235, 0 }; + static ulong[] dim3328KuoInit = { 1, 1, 7, 13, 3, 17, 63, 251, 293, 861, 1539, 2409, 663, 1637, 22309, 0 }; + static ulong[] dim3329KuoInit = { 1, 3, 7, 9, 13, 27, 41, 81, 483, 901, 1963, 1855, 799, 10933, 14395, 0 }; + static ulong[] dim3330KuoInit = { 1, 1, 3, 5, 19, 23, 97, 179, 93, 657, 1361, 4019, 7577, 355, 4881, 0 }; + static ulong[] dim3331KuoInit = { 1, 3, 3, 15, 23, 25, 101, 141, 91, 37, 1165, 3509, 2445, 7675, 30803, 0 }; + static ulong[] dim3332KuoInit = { 1, 1, 1, 5, 13, 53, 87, 197, 321, 297, 277, 2159, 5457, 6463, 1797, 0 }; + static ulong[] dim3333KuoInit = { 1, 3, 3, 7, 3, 3, 117, 5, 95, 527, 755, 2865, 6359, 4859, 11395, 0 }; + static ulong[] dim3334KuoInit = { 1, 3, 3, 13, 1, 49, 43, 247, 369, 351, 1277, 1639, 3133, 4193, 26645, 0 }; + static ulong[] dim3335KuoInit = { 1, 1, 1, 9, 27, 21, 59, 191, 365, 95, 337, 3279, 4455, 8235, 12457, 0 }; + static ulong[] dim3336KuoInit = { 1, 1, 7, 5, 9, 1, 7, 23, 117, 711, 1027, 613, 4729, 14415, 15705, 0 }; + static ulong[] dim3337KuoInit = { 1, 3, 1, 3, 29, 13, 43, 3, 117, 763, 1787, 2109, 4949, 7579, 24083, 0 }; + static ulong[] dim3338KuoInit = { 1, 1, 5, 11, 7, 61, 107, 113, 127, 495, 1167, 2871, 7187, 13235, 2037, 0 }; + static ulong[] dim3339KuoInit = { 1, 1, 5, 5, 13, 33, 23, 69, 5, 137, 157, 1107, 1025, 1907, 2279, 0 }; + static ulong[] dim3340KuoInit = { 1, 1, 1, 9, 11, 63, 27, 13, 295, 951, 2027, 3625, 1447, 8939, 3965, 0 }; + static ulong[] dim3341KuoInit = { 1, 3, 3, 13, 29, 31, 67, 221, 413, 13, 1643, 2847, 4889, 3733, 25713, 0 }; + static ulong[] dim3342KuoInit = { 1, 3, 5, 11, 11, 17, 37, 37, 159, 835, 1775, 2059, 2995, 6141, 12277, 0 }; + static ulong[] dim3343KuoInit = { 1, 3, 3, 7, 11, 25, 107, 239, 361, 835, 1943, 1375, 7077, 13843, 5685, 0 }; + static ulong[] dim3344KuoInit = { 1, 1, 3, 11, 23, 27, 3, 191, 339, 675, 1181, 2005, 245, 7305, 5831, 0 }; + static ulong[] dim3345KuoInit = { 1, 3, 5, 9, 15, 17, 91, 15, 255, 201, 535, 3063, 4351, 12527, 15981, 0 }; + static ulong[] dim3346KuoInit = { 1, 3, 5, 9, 7, 47, 111, 245, 223, 781, 367, 559, 1433, 9631, 7207, 0 }; + static ulong[] dim3347KuoInit = { 1, 3, 7, 5, 23, 5, 111, 237, 371, 541, 663, 693, 6591, 13089, 11381, 0 }; + static ulong[] dim3348KuoInit = { 1, 1, 3, 9, 25, 5, 99, 17, 401, 787, 971, 1035, 1143, 12041, 22455, 0 }; + static ulong[] dim3349KuoInit = { 1, 1, 5, 1, 3, 5, 125, 193, 69, 939, 37, 2843, 3139, 7967, 15099, 0 }; + static ulong[] dim3350KuoInit = { 1, 1, 5, 3, 11, 39, 35, 103, 203, 255, 727, 2513, 1981, 12855, 20887, 0 }; + static ulong[] dim3351KuoInit = { 1, 3, 3, 15, 27, 41, 41, 57, 275, 497, 727, 901, 5653, 12917, 20783, 0 }; + static ulong[] dim3352KuoInit = { 1, 3, 1, 5, 17, 13, 101, 95, 465, 155, 973, 1911, 2719, 157, 19475, 0 }; + static ulong[] dim3353KuoInit = { 1, 3, 3, 5, 3, 61, 31, 225, 351, 931, 855, 3871, 1835, 11133, 25203, 0 }; + static ulong[] dim3354KuoInit = { 1, 3, 7, 7, 25, 1, 91, 193, 455, 873, 1255, 1657, 4143, 433, 22789, 0 }; + static ulong[] dim3355KuoInit = { 1, 3, 7, 9, 31, 19, 35, 81, 175, 885, 1007, 3443, 2063, 3179, 28563, 0 }; + static ulong[] dim3356KuoInit = { 1, 1, 3, 9, 1, 25, 109, 249, 341, 393, 497, 1181, 2943, 9021, 9985, 0 }; + static ulong[] dim3357KuoInit = { 1, 1, 7, 13, 15, 49, 27, 145, 351, 119, 257, 151, 4287, 1709, 2585, 0 }; + static ulong[] dim3358KuoInit = { 1, 1, 7, 7, 3, 19, 105, 51, 443, 693, 29, 2657, 6967, 4797, 14565, 0 }; + static ulong[] dim3359KuoInit = { 1, 3, 3, 1, 25, 53, 65, 169, 461, 275, 1191, 731, 6295, 15083, 28445, 0 }; + static ulong[] dim3360KuoInit = { 1, 3, 1, 1, 11, 39, 21, 3, 411, 45, 1325, 3279, 3153, 289, 30973, 0 }; + static ulong[] dim3361KuoInit = { 1, 1, 1, 11, 29, 57, 107, 245, 279, 677, 599, 1145, 5135, 6131, 12667, 0 }; + static ulong[] dim3362KuoInit = { 1, 3, 1, 15, 27, 7, 99, 215, 17, 171, 977, 2065, 1357, 8705, 29641, 0 }; + static ulong[] dim3363KuoInit = { 1, 1, 3, 9, 31, 23, 53, 9, 177, 645, 99, 3175, 3543, 13637, 9923, 0 }; + static ulong[] dim3364KuoInit = { 1, 1, 1, 13, 5, 45, 69, 39, 207, 651, 1507, 2969, 2743, 4025, 9983, 0 }; + static ulong[] dim3365KuoInit = { 1, 1, 5, 13, 13, 57, 27, 215, 51, 927, 1973, 3127, 3655, 10653, 5649, 0 }; + static ulong[] dim3366KuoInit = { 1, 3, 3, 7, 21, 7, 119, 163, 461, 859, 253, 2817, 8001, 393, 20171, 0 }; + static ulong[] dim3367KuoInit = { 1, 3, 3, 3, 25, 7, 101, 109, 57, 185, 2005, 3167, 3539, 2465, 783, 0 }; + static ulong[] dim3368KuoInit = { 1, 3, 1, 3, 31, 43, 69, 189, 471, 669, 339, 1125, 4273, 10417, 20129, 0 }; + static ulong[] dim3369KuoInit = { 1, 1, 3, 7, 19, 37, 115, 111, 439, 19, 425, 995, 3983, 15523, 25679, 0 }; + static ulong[] dim3370KuoInit = { 1, 3, 5, 9, 5, 1, 37, 105, 359, 423, 545, 1099, 6809, 8531, 25155, 0 }; + static ulong[] dim3371KuoInit = { 1, 1, 3, 3, 9, 37, 37, 149, 457, 1017, 25, 3641, 2673, 1501, 28811, 0 }; + static ulong[] dim3372KuoInit = { 1, 3, 5, 11, 25, 31, 57, 233, 125, 755, 1807, 337, 81, 14709, 4061, 0 }; + static ulong[] dim3373KuoInit = { 1, 1, 1, 7, 25, 7, 37, 35, 437, 889, 965, 3997, 4493, 1357, 26383, 0 }; + static ulong[] dim3374KuoInit = { 1, 1, 1, 3, 9, 37, 105, 127, 283, 141, 1451, 2275, 3261, 8135, 429, 0 }; + static ulong[] dim3375KuoInit = { 1, 1, 1, 5, 3, 19, 9, 233, 293, 827, 103, 1963, 2877, 7701, 17431, 0 }; + static ulong[] dim3376KuoInit = { 1, 3, 7, 11, 15, 17, 87, 243, 141, 721, 829, 3569, 4081, 6039, 21523, 0 }; + static ulong[] dim3377KuoInit = { 1, 3, 3, 11, 17, 21, 31, 169, 425, 755, 1391, 3433, 3275, 15657, 9085, 0 }; + static ulong[] dim3378KuoInit = { 1, 3, 1, 7, 25, 23, 49, 227, 103, 5, 1995, 3803, 1109, 6015, 2433, 0 }; + static ulong[] dim3379KuoInit = { 1, 1, 7, 7, 19, 39, 91, 219, 403, 475, 1629, 117, 2317, 3991, 23467, 0 }; + static ulong[] dim3380KuoInit = { 1, 1, 7, 5, 19, 63, 79, 9, 19, 747, 1045, 875, 5809, 949, 10943, 0 }; + static ulong[] dim3381KuoInit = { 1, 1, 3, 11, 3, 29, 83, 103, 481, 565, 451, 1353, 5417, 2747, 141, 0 }; + static ulong[] dim3382KuoInit = { 1, 1, 1, 11, 17, 43, 75, 51, 335, 257, 1077, 517, 4029, 13761, 8653, 0 }; + static ulong[] dim3383KuoInit = { 1, 1, 1, 1, 13, 51, 41, 195, 331, 155, 1711, 2787, 6163, 12641, 20731, 0 }; + static ulong[] dim3384KuoInit = { 1, 1, 1, 11, 5, 37, 117, 97, 133, 793, 491, 2185, 3671, 12257, 6239, 0 }; + static ulong[] dim3385KuoInit = { 1, 1, 1, 5, 9, 33, 69, 153, 29, 443, 921, 3679, 7385, 7229, 16443, 0 }; + static ulong[] dim3386KuoInit = { 1, 3, 3, 9, 19, 19, 87, 147, 113, 577, 505, 343, 7385, 3247, 6411, 0 }; + static ulong[] dim3387KuoInit = { 1, 1, 7, 9, 15, 33, 83, 69, 27, 519, 115, 4059, 5281, 7995, 25537, 0 }; + static ulong[] dim3388KuoInit = { 1, 1, 5, 15, 21, 25, 37, 35, 263, 531, 197, 27, 7871, 7383, 28467, 0 }; + static ulong[] dim3389KuoInit = { 1, 3, 5, 1, 1, 49, 87, 173, 37, 633, 65, 2449, 149, 7145, 6461, 0 }; + static ulong[] dim3390KuoInit = { 1, 1, 3, 7, 17, 35, 91, 45, 257, 351, 1569, 3757, 5203, 8071, 32211, 0 }; + static ulong[] dim3391KuoInit = { 1, 1, 3, 9, 9, 39, 51, 33, 77, 663, 287, 1127, 4549, 6321, 16199, 0 }; + static ulong[] dim3392KuoInit = { 1, 1, 5, 9, 3, 3, 123, 35, 75, 253, 1661, 3191, 1749, 14421, 15767, 0 }; + static ulong[] dim3393KuoInit = { 1, 1, 1, 15, 21, 27, 69, 233, 425, 89, 1069, 603, 5439, 5597, 24183, 0 }; + static ulong[] dim3394KuoInit = { 1, 1, 7, 15, 19, 57, 127, 83, 445, 619, 1541, 2695, 1657, 10787, 27703, 0 }; + static ulong[] dim3395KuoInit = { 1, 3, 1, 3, 31, 31, 29, 61, 245, 449, 145, 3619, 5267, 9403, 9637, 0 }; + static ulong[] dim3396KuoInit = { 1, 1, 5, 9, 29, 61, 33, 245, 341, 991, 639, 3391, 2971, 857, 26191, 0 }; + static ulong[] dim3397KuoInit = { 1, 1, 1, 5, 9, 7, 57, 33, 79, 489, 379, 3907, 3759, 4243, 9811, 0 }; + static ulong[] dim3398KuoInit = { 1, 3, 5, 15, 7, 61, 7, 119, 51, 927, 1505, 2997, 723, 8987, 29007, 0 }; + static ulong[] dim3399KuoInit = { 1, 1, 3, 1, 31, 55, 63, 15, 421, 423, 1041, 3967, 2471, 13273, 18587, 0 }; + static ulong[] dim3400KuoInit = { 1, 3, 3, 13, 9, 49, 111, 211, 87, 887, 1867, 19, 5329, 12411, 18537, 0 }; + static ulong[] dim3401KuoInit = { 1, 3, 1, 1, 27, 35, 89, 81, 119, 635, 63, 2185, 7001, 11283, 11883, 0 }; + static ulong[] dim3402KuoInit = { 1, 1, 3, 9, 31, 61, 55, 237, 327, 537, 123, 3589, 3019, 705, 16701, 0 }; + static ulong[] dim3403KuoInit = { 1, 1, 7, 1, 7, 13, 103, 101, 473, 7, 381, 3643, 1227, 11335, 615, 0 }; + static ulong[] dim3404KuoInit = { 1, 3, 5, 13, 1, 9, 127, 65, 479, 623, 469, 3403, 2423, 4269, 15195, 0 }; + static ulong[] dim3405KuoInit = { 1, 1, 7, 15, 3, 23, 125, 195, 267, 923, 961, 799, 783, 893, 22403, 0 }; + static ulong[] dim3406KuoInit = { 1, 3, 1, 3, 21, 7, 21, 151, 373, 377, 1685, 3731, 6019, 1059, 32457, 0 }; + static ulong[] dim3407KuoInit = { 1, 3, 3, 11, 9, 31, 55, 207, 109, 945, 1073, 3545, 4191, 12965, 20863, 0 }; + static ulong[] dim3408KuoInit = { 1, 1, 1, 5, 27, 45, 15, 67, 101, 207, 77, 3309, 747, 13857, 25737, 0 }; + static ulong[] dim3409KuoInit = { 1, 1, 1, 5, 1, 31, 15, 235, 57, 449, 411, 3739, 5093, 12963, 30649, 0 }; + static ulong[] dim3410KuoInit = { 1, 3, 7, 5, 5, 33, 87, 13, 57, 727, 1041, 3369, 6047, 1007, 4587, 0 }; + static ulong[] dim3411KuoInit = { 1, 1, 3, 9, 29, 43, 11, 251, 99, 413, 1943, 3461, 993, 13983, 8157, 0 }; + static ulong[] dim3412KuoInit = { 1, 1, 5, 15, 7, 27, 105, 9, 69, 949, 245, 2537, 5941, 10961, 17115, 0 }; + static ulong[] dim3413KuoInit = { 1, 1, 7, 5, 17, 41, 63, 167, 45, 391, 895, 2565, 2681, 10855, 6919, 0 }; + static ulong[] dim3414KuoInit = { 1, 3, 7, 3, 7, 53, 15, 207, 467, 131, 761, 189, 4977, 4345, 7539, 0 }; + static ulong[] dim3415KuoInit = { 1, 1, 5, 5, 23, 17, 127, 3, 455, 787, 383, 2381, 6407, 3253, 1787, 0 }; + static ulong[] dim3416KuoInit = { 1, 3, 5, 15, 5, 7, 37, 75, 351, 141, 93, 2631, 609, 11455, 20603, 0 }; + static ulong[] dim3417KuoInit = { 1, 3, 7, 9, 5, 33, 19, 15, 101, 1005, 7, 1341, 4577, 11627, 17061, 0 }; + static ulong[] dim3418KuoInit = { 1, 3, 3, 9, 5, 7, 87, 181, 197, 423, 361, 545, 2459, 7419, 14457, 0 }; + static ulong[] dim3419KuoInit = { 1, 1, 7, 7, 25, 37, 93, 85, 345, 459, 465, 3377, 795, 13439, 4765, 0 }; + static ulong[] dim3420KuoInit = { 1, 1, 7, 9, 25, 55, 109, 63, 381, 329, 1787, 3163, 279, 4647, 8723, 0 }; + static ulong[] dim3421KuoInit = { 1, 3, 3, 13, 23, 33, 85, 41, 151, 319, 265, 259, 29, 4217, 21025, 0 }; + static ulong[] dim3422KuoInit = { 1, 1, 5, 9, 31, 17, 93, 27, 455, 1015, 81, 621, 6511, 7617, 6775, 0 }; + static ulong[] dim3423KuoInit = { 1, 1, 1, 11, 25, 21, 73, 161, 267, 911, 25, 1385, 4073, 14423, 31473, 0 }; + static ulong[] dim3424KuoInit = { 1, 3, 5, 11, 13, 33, 95, 113, 371, 291, 1055, 3779, 991, 9699, 9495, 0 }; + static ulong[] dim3425KuoInit = { 1, 1, 1, 7, 31, 55, 111, 215, 399, 721, 1443, 763, 3119, 11075, 15489, 0 }; + static ulong[] dim3426KuoInit = { 1, 1, 1, 3, 17, 57, 119, 171, 299, 299, 1919, 3103, 5691, 7927, 18875, 0 }; + static ulong[] dim3427KuoInit = { 1, 1, 5, 7, 13, 41, 35, 209, 383, 381, 901, 3341, 3421, 11501, 2187, 0 }; + static ulong[] dim3428KuoInit = { 1, 3, 1, 7, 1, 3, 83, 105, 495, 297, 413, 2941, 4309, 9829, 32115, 0 }; + static ulong[] dim3429KuoInit = { 1, 3, 5, 3, 3, 7, 81, 9, 55, 19, 225, 2915, 6255, 10967, 8767, 0 }; + static ulong[] dim3430KuoInit = { 1, 3, 1, 1, 23, 59, 21, 127, 7, 703, 1189, 2375, 6273, 1655, 10115, 0 }; + static ulong[] dim3431KuoInit = { 1, 1, 1, 15, 19, 35, 39, 185, 143, 163, 1491, 201, 2473, 661, 12827, 0 }; + static ulong[] dim3432KuoInit = { 1, 1, 1, 5, 29, 49, 5, 27, 131, 1005, 991, 1159, 5437, 5039, 4037, 0 }; + static ulong[] dim3433KuoInit = { 1, 3, 7, 3, 11, 41, 123, 43, 11, 443, 109, 3995, 5377, 2907, 30035, 0 }; + static ulong[] dim3434KuoInit = { 1, 3, 1, 1, 31, 59, 53, 219, 185, 31, 641, 1695, 5817, 9001, 28827, 0 }; + static ulong[] dim3435KuoInit = { 1, 1, 1, 3, 13, 37, 37, 119, 123, 57, 1241, 551, 5825, 11551, 23521, 0 }; + static ulong[] dim3436KuoInit = { 1, 1, 3, 15, 13, 37, 33, 61, 209, 375, 335, 1223, 4023, 12743, 8375, 0 }; + static ulong[] dim3437KuoInit = { 1, 3, 3, 3, 31, 7, 103, 43, 451, 517, 1025, 2853, 5943, 13655, 21409, 0 }; + static ulong[] dim3438KuoInit = { 1, 1, 1, 13, 11, 37, 11, 167, 271, 763, 85, 3727, 641, 2841, 23803, 0 }; + static ulong[] dim3439KuoInit = { 1, 1, 7, 5, 3, 19, 117, 225, 275, 327, 1263, 1597, 1439, 8531, 18063, 0 }; + static ulong[] dim3440KuoInit = { 1, 3, 5, 3, 9, 45, 57, 169, 453, 949, 585, 1365, 4263, 3461, 7191, 0 }; + static ulong[] dim3441KuoInit = { 1, 3, 7, 9, 25, 51, 97, 255, 457, 293, 1027, 1291, 6685, 2617, 3055, 0 }; + static ulong[] dim3442KuoInit = { 1, 3, 7, 5, 27, 33, 47, 65, 43, 545, 123, 1093, 5563, 3013, 18451, 0 }; + static ulong[] dim3443KuoInit = { 1, 1, 3, 11, 9, 25, 71, 241, 495, 561, 1565, 703, 809, 10961, 3001, 0 }; + static ulong[] dim3444KuoInit = { 1, 3, 5, 1, 1, 47, 97, 233, 259, 39, 543, 303, 2705, 3683, 32123, 0 }; + static ulong[] dim3445KuoInit = { 1, 1, 5, 7, 1, 35, 91, 43, 417, 299, 1635, 2163, 7959, 9015, 5661, 0 }; + static ulong[] dim3446KuoInit = { 1, 1, 3, 11, 1, 63, 49, 209, 125, 241, 987, 3173, 631, 9767, 8467, 0 }; + static ulong[] dim3447KuoInit = { 1, 1, 1, 5, 25, 49, 43, 117, 65, 81, 313, 1917, 6087, 1503, 3383, 0 }; + static ulong[] dim3448KuoInit = { 1, 3, 5, 1, 23, 53, 43, 29, 91, 727, 1157, 2985, 3851, 15897, 17577, 0 }; + static ulong[] dim3449KuoInit = { 1, 1, 3, 15, 15, 27, 35, 129, 161, 679, 1001, 2681, 5287, 10367, 21017, 0 }; + static ulong[] dim3450KuoInit = { 1, 3, 3, 1, 23, 51, 127, 119, 467, 161, 1229, 2969, 6321, 1141, 7827, 0 }; + static ulong[] dim3451KuoInit = { 1, 3, 5, 15, 19, 45, 33, 173, 205, 815, 783, 1323, 69, 5191, 23795, 0 }; + static ulong[] dim3452KuoInit = { 1, 3, 5, 9, 19, 1, 111, 253, 463, 247, 1877, 1831, 8037, 12769, 8111, 0 }; + static ulong[] dim3453KuoInit = { 1, 3, 1, 1, 21, 7, 19, 241, 297, 953, 1759, 2187, 1587, 14857, 13245, 0 }; + static ulong[] dim3454KuoInit = { 1, 1, 1, 15, 27, 21, 111, 37, 333, 485, 127, 1781, 545, 251, 2757, 0 }; + static ulong[] dim3455KuoInit = { 1, 3, 1, 1, 3, 7, 21, 69, 171, 225, 1505, 2725, 923, 9451, 29443, 0 }; + static ulong[] dim3456KuoInit = { 1, 3, 7, 7, 13, 57, 97, 175, 429, 529, 677, 1501, 4717, 12705, 31473, 0 }; + static ulong[] dim3457KuoInit = { 1, 3, 7, 11, 29, 7, 57, 115, 55, 167, 903, 3855, 8051, 15567, 31733, 0 }; + static ulong[] dim3458KuoInit = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }; + static ulong[] dim3459KuoInit = { 1, 1, 1, 13, 11, 17, 73, 193, 151, 927, 1375, 4037, 6855, 10481, 8973, 0 }; + static ulong[] dim3460KuoInit = { 1, 3, 7, 1, 25, 7, 115, 39, 469, 903, 655, 299, 6007, 6629, 11871, 0 }; + static ulong[] dim3461KuoInit = { 1, 3, 7, 5, 15, 49, 79, 115, 55, 841, 1091, 1641, 5693, 3607, 13699, 0 }; + static ulong[] dim3462KuoInit = { 1, 1, 1, 15, 5, 33, 99, 239, 157, 133, 2023, 683, 3419, 10993, 32187, 0 }; + static ulong[] dim3463KuoInit = { 1, 1, 7, 1, 3, 13, 95, 233, 341, 243, 2043, 653, 4673, 1441, 19087, 0 }; + static ulong[] dim3464KuoInit = { 1, 3, 3, 3, 29, 51, 117, 199, 49, 467, 461, 2465, 7541, 6815, 28711, 0 }; + static ulong[] dim3465KuoInit = { 1, 3, 1, 1, 25, 47, 31, 79, 9, 39, 733, 3567, 5965, 6627, 1109, 0 }; + static ulong[] dim3466KuoInit = { 1, 3, 1, 13, 9, 53, 27, 101, 341, 369, 1659, 1645, 4465, 10175, 4565, 0 }; + static ulong[] dim3467KuoInit = { 1, 3, 5, 7, 13, 61, 67, 125, 427, 105, 133, 2303, 5595, 4527, 23151, 0 }; + static ulong[] dim3468KuoInit = { 1, 1, 5, 7, 19, 29, 87, 167, 141, 657, 947, 367, 2617, 9287, 629, 0 }; + static ulong[] dim3469KuoInit = { 1, 3, 7, 5, 21, 25, 35, 21, 391, 1019, 991, 3343, 1221, 1591, 18095, 0 }; + static ulong[] dim3470KuoInit = { 1, 3, 7, 9, 31, 49, 99, 185, 405, 261, 935, 3447, 4081, 5537, 26329, 0 }; + static ulong[] dim3471KuoInit = { 1, 1, 3, 7, 25, 51, 107, 83, 449, 733, 597, 1023, 7457, 14343, 7119, 0 }; + static ulong[] dim3472KuoInit = { 1, 1, 1, 5, 23, 21, 35, 83, 185, 531, 1283, 2235, 7775, 15895, 32651, 0 }; + static ulong[] dim3473KuoInit = { 1, 1, 5, 15, 27, 13, 23, 227, 491, 701, 341, 2109, 8045, 1529, 10589, 0 }; + static ulong[] dim3474KuoInit = { 1, 1, 5, 5, 21, 51, 31, 101, 31, 861, 401, 1519, 5349, 2623, 22667, 0 }; + static ulong[] dim3475KuoInit = { 1, 3, 5, 5, 1, 41, 43, 25, 491, 329, 537, 1357, 5567, 3951, 15293, 0 }; + static ulong[] dim3476KuoInit = { 1, 3, 7, 3, 15, 39, 113, 105, 51, 483, 1417, 2971, 3, 9673, 4331, 0 }; + static ulong[] dim3477KuoInit = { 1, 3, 5, 13, 17, 3, 19, 55, 443, 967, 327, 3463, 5427, 195, 7495, 0 }; + static ulong[] dim3478KuoInit = { 1, 1, 3, 3, 15, 15, 11, 157, 311, 967, 89, 3691, 7307, 12309, 1915, 0 }; + static ulong[] dim3479KuoInit = { 1, 3, 5, 7, 25, 7, 125, 163, 231, 177, 1497, 3119, 3281, 15033, 9457, 0 }; + static ulong[] dim3480KuoInit = { 1, 3, 3, 9, 25, 51, 51, 243, 427, 831, 709, 3741, 445, 14275, 32323, 0 }; + static ulong[] dim3481KuoInit = { 1, 3, 3, 13, 1, 41, 123, 237, 401, 19, 1161, 985, 5119, 14879, 5785, 0 }; + static ulong[] dim3482KuoInit = { 1, 3, 1, 3, 3, 11, 121, 209, 507, 271, 1045, 2547, 1019, 7107, 31823, 0 }; + static ulong[] dim3483KuoInit = { 1, 1, 5, 3, 21, 3, 33, 73, 79, 607, 47, 3045, 2471, 2023, 8115, 0 }; + static ulong[] dim3484KuoInit = { 1, 3, 7, 13, 19, 49, 111, 185, 209, 683, 1459, 3827, 6591, 13139, 2057, 0 }; + static ulong[] dim3485KuoInit = { 1, 3, 7, 9, 17, 63, 77, 217, 161, 287, 335, 3947, 5255, 12297, 16829, 0 }; + static ulong[] dim3486KuoInit = { 1, 3, 1, 11, 17, 17, 31, 231, 483, 437, 431, 957, 6499, 12947, 29751, 0 }; + static ulong[] dim3487KuoInit = { 1, 3, 7, 15, 5, 57, 119, 43, 385, 743, 249, 3479, 7751, 6321, 31747, 0 }; + static ulong[] dim3488KuoInit = { 1, 1, 5, 3, 5, 1, 113, 87, 439, 507, 1517, 2081, 5947, 10967, 10219, 0 }; + static ulong[] dim3489KuoInit = { 1, 3, 1, 13, 23, 29, 39, 33, 129, 493, 1119, 2177, 4135, 5051, 20241, 0 }; + static ulong[] dim3490KuoInit = { 1, 3, 7, 13, 19, 13, 71, 163, 107, 285, 1999, 3371, 3555, 16265, 2825, 0 }; + static ulong[] dim3491KuoInit = { 1, 3, 7, 11, 5, 19, 67, 201, 203, 619, 927, 1769, 5655, 4539, 1719, 0 }; + static ulong[] dim3492KuoInit = { 1, 3, 5, 7, 15, 43, 107, 91, 315, 281, 525, 3243, 7751, 8991, 29195, 0 }; + static ulong[] dim3493KuoInit = { 1, 1, 7, 7, 21, 43, 35, 81, 199, 51, 935, 357, 1723, 8183, 6209, 0 }; + static ulong[] dim3494KuoInit = { 1, 3, 5, 5, 9, 31, 75, 71, 375, 181, 1503, 3479, 2255, 1371, 16127, 0 }; + static ulong[] dim3495KuoInit = { 1, 1, 7, 11, 29, 61, 57, 145, 149, 673, 1953, 2111, 3525, 1007, 15927, 0 }; + static ulong[] dim3496KuoInit = { 1, 1, 7, 15, 25, 25, 103, 175, 273, 193, 1215, 3059, 7805, 1455, 1627, 0 }; + static ulong[] dim3497KuoInit = { 1, 3, 1, 1, 23, 45, 61, 227, 487, 89, 739, 1867, 3643, 9879, 17307, 0 }; + static ulong[] dim3498KuoInit = { 1, 1, 5, 1, 23, 5, 117, 25, 325, 725, 1999, 3453, 2353, 5467, 2065, 0 }; + static ulong[] dim3499KuoInit = { 1, 1, 5, 5, 25, 3, 95, 243, 175, 291, 821, 3531, 4873, 9975, 30437, 0 }; + static ulong[] dim3500KuoInit = { 1, 3, 3, 11, 5, 41, 121, 23, 15, 195, 1141, 171, 2245, 8043, 2201, 0 }; + static ulong[] dim3501KuoInit = { 1, 3, 7, 1, 29, 1, 41, 233, 217, 501, 913, 3589, 1153, 4601, 23147, 0 }; + static ulong[] dim3502KuoInit = { 1, 1, 5, 15, 1, 41, 71, 255, 283, 125, 845, 1261, 7519, 15623, 13301, 0 }; + static ulong[] dim3503KuoInit = { 1, 3, 3, 15, 11, 3, 73, 161, 203, 775, 905, 411, 4139, 8289, 8581, 0 }; + static ulong[] dim3504KuoInit = { 1, 1, 7, 13, 7, 57, 17, 115, 273, 949, 913, 3267, 6949, 6785, 30449, 0 }; + static ulong[] dim3505KuoInit = { 1, 1, 7, 5, 3, 49, 55, 191, 505, 807, 287, 3595, 2261, 13751, 15339, 0 }; + static ulong[] dim3506KuoInit = { 1, 1, 5, 11, 23, 13, 83, 145, 387, 37, 341, 111, 3309, 4481, 21679, 0 }; + static ulong[] dim3507KuoInit = { 1, 1, 7, 15, 3, 51, 13, 247, 419, 555, 431, 187, 2753, 9071, 25189, 0 }; + static ulong[] dim3508KuoInit = { 1, 3, 7, 3, 29, 33, 119, 63, 363, 197, 1901, 2231, 1453, 3901, 13713, 0 }; + static ulong[] dim3509KuoInit = { 1, 1, 5, 7, 9, 15, 91, 107, 397, 739, 1419, 481, 5713, 14089, 11699, 0 }; + static ulong[] dim3510KuoInit = { 1, 3, 3, 7, 9, 37, 47, 183, 45, 135, 903, 2769, 5929, 8175, 8661, 0 }; + static ulong[] dim3511KuoInit = { 1, 1, 3, 9, 7, 63, 117, 81, 385, 459, 1455, 4089, 395, 7569, 18089, 0 }; + static ulong[] dim3512KuoInit = { 1, 1, 1, 3, 15, 29, 71, 47, 423, 177, 1481, 1087, 3703, 5857, 9631, 0 }; + static ulong[] dim3513KuoInit = { 1, 3, 1, 7, 23, 45, 127, 91, 457, 81, 681, 257, 361, 11739, 1503, 0 }; + static ulong[] dim3514KuoInit = { 1, 3, 3, 9, 29, 29, 107, 125, 55, 759, 1287, 1937, 353, 1275, 14349, 0 }; + static ulong[] dim3515KuoInit = { 1, 3, 5, 11, 15, 53, 35, 1, 419, 255, 1891, 7, 3005, 1493, 165, 0 }; + static ulong[] dim3516KuoInit = { 1, 3, 5, 1, 5, 19, 45, 109, 479, 309, 277, 2749, 4859, 4301, 17799, 0 }; + static ulong[] dim3517KuoInit = { 1, 3, 7, 15, 21, 57, 39, 19, 433, 77, 1999, 3467, 2097, 6853, 1763, 0 }; + static ulong[] dim3518KuoInit = { 1, 1, 5, 5, 7, 39, 109, 53, 1, 543, 623, 573, 4039, 1367, 23177, 0 }; + static ulong[] dim3519KuoInit = { 1, 3, 1, 11, 1, 31, 3, 203, 409, 409, 1471, 1245, 3881, 14467, 22731, 0 }; + static ulong[] dim3520KuoInit = { 1, 3, 1, 11, 19, 41, 39, 95, 187, 823, 973, 3055, 3803, 4229, 29363, 0 }; + static ulong[] dim3521KuoInit = { 1, 1, 5, 15, 29, 41, 69, 121, 385, 717, 1601, 3061, 6523, 13423, 12559, 0 }; + static ulong[] dim3522KuoInit = { 1, 3, 7, 1, 5, 45, 85, 153, 337, 587, 595, 1183, 3799, 12775, 19537, 0 }; + static ulong[] dim3523KuoInit = { 1, 3, 7, 15, 11, 45, 97, 37, 167, 227, 1003, 2991, 2291, 15865, 6645, 0 }; + static ulong[] dim3524KuoInit = { 1, 3, 3, 7, 31, 41, 123, 225, 275, 733, 1611, 1599, 7345, 297, 22551, 0 }; + static ulong[] dim3525KuoInit = { 1, 1, 5, 3, 7, 45, 45, 155, 41, 581, 635, 4065, 3993, 7233, 27097, 0 }; + static ulong[] dim3526KuoInit = { 1, 1, 7, 11, 9, 39, 17, 19, 335, 819, 1845, 1199, 591, 7743, 26797, 0 }; + static ulong[] dim3527KuoInit = { 1, 3, 7, 9, 29, 33, 35, 19, 287, 935, 1463, 3639, 5537, 2751, 20073, 0 }; + static ulong[] dim3528KuoInit = { 1, 3, 5, 5, 3, 45, 59, 117, 431, 419, 1325, 983, 6065, 3501, 15765, 0 }; + static ulong[] dim3529KuoInit = { 1, 1, 1, 9, 27, 7, 123, 205, 155, 59, 1139, 1147, 4845, 15131, 10155, 0 }; + static ulong[] dim3530KuoInit = { 1, 3, 7, 5, 23, 37, 97, 33, 337, 837, 1379, 2459, 469, 10615, 16475, 0 }; + static ulong[] dim3531KuoInit = { 1, 3, 1, 7, 1, 23, 27, 63, 503, 635, 935, 1767, 6887, 6675, 10973, 0 }; + static ulong[] dim3532KuoInit = { 1, 3, 1, 9, 13, 29, 15, 109, 185, 33, 1039, 959, 1745, 10587, 9269, 0 }; + static ulong[] dim3533KuoInit = { 1, 3, 3, 1, 5, 29, 89, 63, 341, 773, 1851, 775, 1717, 6041, 11901, 0 }; + static ulong[] dim3534KuoInit = { 1, 1, 7, 9, 23, 47, 21, 111, 289, 997, 1559, 501, 5913, 4737, 4623, 0 }; + static ulong[] dim3535KuoInit = { 1, 1, 1, 15, 3, 3, 87, 197, 391, 121, 627, 3705, 4093, 3933, 13787, 0 }; + static ulong[] dim3536KuoInit = { 1, 3, 3, 15, 31, 9, 117, 47, 373, 697, 131, 3933, 3135, 9155, 3937, 0 }; + static ulong[] dim3537KuoInit = { 1, 1, 7, 3, 11, 39, 5, 27, 253, 301, 1151, 3771, 1581, 9811, 17617, 0 }; + static ulong[] dim3538KuoInit = { 1, 3, 7, 15, 25, 59, 97, 229, 291, 349, 1153, 1859, 3357, 7919, 2733, 0 }; + static ulong[] dim3539KuoInit = { 1, 1, 5, 13, 5, 7, 37, 177, 177, 969, 29, 4017, 6791, 2823, 10607, 0 }; + static ulong[] dim3540KuoInit = { 1, 1, 7, 13, 27, 17, 25, 137, 325, 949, 1519, 3711, 4399, 9501, 2989, 0 }; + static ulong[] dim3541KuoInit = { 1, 1, 5, 5, 29, 27, 75, 195, 417, 945, 1851, 2887, 2379, 15229, 4805, 0 }; + static ulong[] dim3542KuoInit = { 1, 1, 3, 11, 31, 45, 105, 87, 241, 153, 1941, 3459, 4809, 9823, 19419, 0 }; + static ulong[] dim3543KuoInit = { 1, 1, 1, 1, 1, 59, 75, 51, 309, 671, 1039, 2999, 1025, 15823, 4835, 0 }; + static ulong[] dim3544KuoInit = { 1, 3, 7, 13, 19, 37, 41, 85, 11, 713, 1047, 989, 2941, 6423, 7983, 0 }; + static ulong[] dim3545KuoInit = { 1, 3, 5, 13, 1, 55, 103, 207, 275, 431, 563, 101, 691, 1997, 17227, 0 }; + static ulong[] dim3546KuoInit = { 1, 3, 1, 3, 19, 15, 67, 197, 125, 377, 367, 601, 4983, 1699, 29315, 0 }; + static ulong[] dim3547KuoInit = { 1, 1, 5, 3, 23, 19, 19, 133, 83, 625, 757, 1349, 5821, 2483, 26653, 0 }; + static ulong[] dim3548KuoInit = { 1, 1, 3, 3, 19, 17, 19, 83, 235, 657, 733, 1773, 7011, 3893, 8495, 0 }; + static ulong[] dim3549KuoInit = { 1, 1, 3, 15, 19, 33, 37, 69, 385, 835, 1025, 1585, 6685, 10627, 19203, 0 }; + static ulong[] dim3550KuoInit = { 1, 1, 5, 11, 9, 31, 65, 177, 153, 781, 1183, 1215, 6271, 13099, 12449, 0 }; + static ulong[] dim3551KuoInit = { 1, 1, 7, 9, 13, 49, 41, 57, 443, 633, 1953, 2423, 789, 5591, 20891, 0 }; + static ulong[] dim3552KuoInit = { 1, 1, 1, 15, 17, 21, 69, 177, 57, 797, 13, 3987, 6597, 9935, 26559, 0 }; + static ulong[] dim3553KuoInit = { 1, 3, 3, 1, 21, 27, 17, 207, 139, 43, 1935, 3285, 4251, 4411, 24469, 0 }; + static ulong[] dim3554KuoInit = { 1, 3, 3, 11, 11, 47, 63, 243, 19, 801, 971, 1925, 5981, 13055, 12185, 0 }; + static ulong[] dim3555KuoInit = { 1, 3, 5, 5, 9, 13, 49, 251, 315, 889, 1613, 1007, 7849, 3121, 4279, 0 }; + static ulong[] dim3556KuoInit = { 1, 3, 1, 15, 7, 37, 95, 253, 65, 177, 1551, 2307, 2325, 9975, 18277, 0 }; + static ulong[] dim3557KuoInit = { 1, 3, 1, 15, 7, 53, 45, 5, 447, 1005, 279, 2141, 4271, 4707, 11225, 0 }; + static ulong[] dim3558KuoInit = { 1, 1, 3, 13, 31, 11, 15, 133, 313, 249, 1971, 2905, 819, 11603, 25679, 0 }; + static ulong[] dim3559KuoInit = { 1, 3, 3, 15, 21, 49, 107, 229, 101, 449, 245, 1401, 391, 3749, 14555, 0 }; + static ulong[] dim3560KuoInit = { 1, 1, 1, 15, 7, 39, 69, 223, 37, 771, 1469, 2085, 1075, 14485, 10019, 0 }; + static ulong[] dim3561KuoInit = { 1, 3, 1, 13, 3, 27, 37, 59, 69, 675, 807, 2711, 3867, 9737, 21913, 0 }; + static ulong[] dim3562KuoInit = { 1, 1, 3, 9, 25, 45, 109, 113, 267, 867, 771, 1647, 2063, 14063, 27737, 0 }; + static ulong[] dim3563KuoInit = { 1, 1, 7, 15, 23, 51, 71, 33, 103, 71, 1177, 2353, 4741, 6907, 11121, 0 }; + static ulong[] dim3564KuoInit = { 1, 3, 3, 7, 21, 31, 77, 255, 341, 249, 1263, 505, 1845, 12867, 11393, 0 }; + static ulong[] dim3565KuoInit = { 1, 3, 1, 1, 3, 1, 5, 215, 155, 107, 1283, 3501, 8079, 13921, 22415, 0 }; + static ulong[] dim3566KuoInit = { 1, 1, 7, 9, 31, 21, 21, 29, 341, 13, 155, 2161, 517, 13135, 15893, 0 }; + static ulong[] dim3567KuoInit = { 1, 1, 7, 5, 21, 33, 23, 131, 367, 939, 1139, 865, 6015, 6945, 2301, 0 }; + static ulong[] dim3568KuoInit = { 1, 3, 7, 3, 1, 25, 109, 183, 267, 757, 371, 1459, 3671, 2925, 10345, 0 }; + static ulong[] dim3569KuoInit = { 1, 1, 5, 15, 29, 57, 95, 169, 301, 645, 5, 225, 5711, 305, 16515, 0 }; + static ulong[] dim3570KuoInit = { 1, 3, 7, 9, 27, 47, 95, 121, 203, 341, 657, 2467, 7619, 9587, 7981, 0 }; + static ulong[] dim3571KuoInit = { 1, 3, 1, 5, 27, 11, 103, 67, 19, 289, 187, 3857, 8117, 12931, 11279, 0 }; + static ulong[] dim3572KuoInit = { 1, 1, 5, 1, 31, 9, 57, 67, 507, 405, 181, 2301, 715, 12165, 18415, 0 }; + static ulong[] dim3573KuoInit = { 1, 1, 7, 1, 11, 3, 35, 215, 177, 679, 735, 1569, 6231, 5141, 28291, 0 }; + static ulong[] dim3574KuoInit = { 1, 3, 1, 9, 7, 7, 101, 247, 103, 373, 1485, 2515, 3981, 12029, 5845, 0 }; + static ulong[] dim3575KuoInit = { 1, 1, 1, 9, 29, 27, 117, 111, 107, 737, 629, 1331, 7495, 9813, 24925, 0 }; + static ulong[] dim3576KuoInit = { 1, 1, 1, 13, 17, 11, 95, 11, 1, 525, 1677, 2673, 2353, 7211, 1075, 0 }; + static ulong[] dim3577KuoInit = { 1, 3, 3, 7, 9, 29, 9, 125, 249, 815, 105, 1649, 2789, 6041, 15287, 0 }; + static ulong[] dim3578KuoInit = { 1, 3, 3, 3, 25, 53, 87, 99, 427, 255, 285, 2339, 5003, 10395, 20969, 0 }; + static ulong[] dim3579KuoInit = { 1, 3, 1, 5, 25, 33, 97, 149, 207, 925, 645, 1867, 4591, 10823, 16603, 0 }; + static ulong[] dim3580KuoInit = { 1, 3, 3, 13, 1, 33, 71, 49, 417, 535, 923, 525, 811, 7443, 12971, 0 }; + static ulong[] dim3581KuoInit = { 1, 3, 5, 3, 5, 9, 39, 121, 87, 883, 1957, 1375, 4109, 12691, 15557, 0 }; + static ulong[] dim3582KuoInit = { 1, 1, 7, 9, 23, 11, 59, 41, 117, 243, 1953, 3967, 7303, 10767, 1345, 0 }; + static ulong[] dim3583KuoInit = { 1, 3, 1, 7, 29, 59, 19, 177, 405, 197, 59, 855, 5009, 11887, 6361, 0 }; + static ulong[] dim3584KuoInit = { 1, 3, 7, 7, 19, 59, 71, 199, 207, 757, 1147, 1857, 3787, 16081, 29557, 0 }; + static ulong[] dim3585KuoInit = { 1, 1, 5, 9, 25, 13, 37, 27, 511, 983, 1087, 371, 4953, 8987, 3155, 0 }; + static ulong[] dim3586KuoInit = { 1, 3, 7, 15, 21, 43, 75, 227, 441, 523, 551, 3517, 77, 5869, 24607, 0 }; + static ulong[] dim3587KuoInit = { 1, 1, 5, 15, 1, 33, 25, 217, 277, 73, 105, 1697, 1545, 10205, 4275, 0 }; + static ulong[] dim3588KuoInit = { 1, 1, 5, 7, 3, 53, 99, 19, 121, 427, 585, 2471, 103, 3771, 23525, 0 }; + static ulong[] dim3589KuoInit = { 1, 3, 5, 3, 15, 17, 35, 205, 9, 941, 1281, 1339, 7421, 3341, 4393, 0 }; + static ulong[] dim3590KuoInit = { 1, 1, 1, 13, 27, 13, 35, 99, 87, 157, 951, 2739, 1993, 6107, 29023, 0 }; + static ulong[] dim3591KuoInit = { 1, 3, 5, 15, 15, 5, 83, 5, 283, 393, 1273, 2251, 4181, 3851, 6845, 0 }; + static ulong[] dim3592KuoInit = { 1, 1, 5, 3, 1, 9, 63, 97, 83, 93, 293, 2087, 2259, 10313, 1037, 0 }; + static ulong[] dim3593KuoInit = { 1, 1, 1, 5, 11, 19, 39, 19, 327, 329, 189, 3851, 4839, 1669, 25805, 0 }; + static ulong[] dim3594KuoInit = { 1, 3, 3, 7, 21, 1, 41, 233, 497, 265, 1041, 4003, 8029, 15, 14437, 0 }; + static ulong[] dim3595KuoInit = { 1, 3, 7, 5, 7, 15, 123, 215, 403, 931, 277, 3501, 3667, 13313, 23977, 0 }; + static ulong[] dim3596KuoInit = { 1, 1, 3, 9, 5, 23, 99, 161, 25, 403, 1695, 2493, 199, 15745, 9167, 0 }; + static ulong[] dim3597KuoInit = { 1, 1, 1, 15, 1, 25, 93, 31, 227, 833, 1891, 1171, 4551, 3329, 30593, 0 }; + static ulong[] dim3598KuoInit = { 1, 3, 1, 11, 29, 51, 109, 27, 475, 511, 1763, 2285, 3191, 7943, 8373, 0 }; + static ulong[] dim3599KuoInit = { 1, 1, 5, 3, 21, 63, 89, 9, 429, 613, 141, 4011, 6563, 5871, 30701, 0 }; + static ulong[] dim3600KuoInit = { 1, 1, 5, 1, 31, 49, 87, 15, 481, 237, 133, 3267, 7385, 4733, 16853, 0 }; + static ulong[] dim3601KuoInit = { 1, 3, 7, 9, 1, 63, 95, 17, 311, 29, 1543, 2971, 695, 3641, 28155, 0 }; + static ulong[] dim3602KuoInit = { 1, 3, 3, 7, 27, 1, 59, 181, 321, 431, 143, 213, 1471, 4707, 22897, 0 }; + static ulong[] dim3603KuoInit = { 1, 1, 3, 11, 19, 3, 95, 1, 407, 755, 1581, 3435, 2025, 7781, 5573, 0 }; + static ulong[] dim3604KuoInit = { 1, 1, 1, 1, 19, 15, 119, 169, 109, 1003, 403, 1633, 4963, 9785, 18483, 0 }; + static ulong[] dim3605KuoInit = { 1, 3, 7, 1, 23, 5, 77, 79, 429, 921, 1913, 2075, 7923, 5515, 19257, 0 }; + static ulong[] dim3606KuoInit = { 1, 3, 1, 11, 1, 45, 99, 249, 385, 427, 1201, 1363, 335, 12561, 18753, 0 }; + static ulong[] dim3607KuoInit = { 1, 1, 1, 11, 27, 41, 9, 13, 267, 987, 1023, 2723, 3873, 15911, 3165, 0 }; + static ulong[] dim3608KuoInit = { 1, 3, 5, 1, 17, 7, 117, 241, 509, 757, 1301, 3935, 3361, 13745, 27239, 0 }; + static ulong[] dim3609KuoInit = { 1, 1, 5, 15, 21, 33, 55, 245, 1, 263, 437, 2279, 1201, 2043, 20473, 0 }; + static ulong[] dim3610KuoInit = { 1, 3, 7, 5, 29, 9, 31, 165, 299, 923, 847, 769, 5683, 1805, 13433, 0 }; + static ulong[] dim3611KuoInit = { 1, 1, 1, 11, 29, 13, 49, 173, 269, 35, 1057, 973, 1853, 12677, 13565, 0 }; + static ulong[] dim3612KuoInit = { 1, 3, 1, 11, 11, 21, 19, 3, 127, 133, 193, 2665, 7187, 15425, 23805, 0 }; + static ulong[] dim3613KuoInit = { 1, 3, 5, 7, 13, 61, 95, 17, 197, 381, 865, 1241, 685, 9525, 2503, 0 }; + static ulong[] dim3614KuoInit = { 1, 1, 5, 7, 13, 19, 83, 141, 179, 201, 463, 2083, 3617, 1945, 20371, 0 }; + static ulong[] dim3615KuoInit = { 1, 3, 5, 13, 9, 39, 47, 3, 13, 739, 1501, 1007, 6963, 15819, 29739, 0 }; + static ulong[] dim3616KuoInit = { 1, 1, 5, 7, 3, 17, 105, 27, 165, 515, 949, 81, 947, 9615, 24403, 0 }; + static ulong[] dim3617KuoInit = { 1, 3, 7, 5, 23, 43, 81, 141, 181, 1007, 1343, 1919, 5971, 8563, 17091, 0 }; + static ulong[] dim3618KuoInit = { 1, 3, 3, 11, 1, 25, 19, 117, 225, 347, 785, 791, 7321, 15647, 25491, 0 }; + static ulong[] dim3619KuoInit = { 1, 1, 5, 5, 11, 61, 25, 205, 145, 695, 713, 1787, 8087, 5935, 5105, 0 }; + static ulong[] dim3620KuoInit = { 1, 1, 7, 1, 15, 17, 25, 141, 75, 657, 1641, 575, 3387, 6093, 15565, 0 }; + static ulong[] dim3621KuoInit = { 1, 3, 7, 11, 31, 49, 113, 37, 321, 547, 819, 2079, 7231, 7497, 29877, 0 }; + static ulong[] dim3622KuoInit = { 1, 1, 3, 11, 31, 19, 39, 99, 271, 527, 1551, 2491, 5515, 5541, 6131, 0 }; + static ulong[] dim3623KuoInit = { 1, 1, 1, 7, 23, 35, 31, 35, 315, 911, 1133, 3509, 1381, 15869, 23211, 0 }; + static ulong[] dim3624KuoInit = { 1, 3, 3, 5, 1, 33, 127, 175, 311, 497, 187, 2983, 6553, 9653, 5711, 0 }; + static ulong[] dim3625KuoInit = { 1, 1, 3, 13, 19, 3, 65, 91, 265, 199, 2035, 1277, 4575, 5517, 15247, 0 }; + static ulong[] dim3626KuoInit = { 1, 1, 5, 15, 31, 39, 71, 167, 337, 245, 399, 2681, 1257, 15117, 24145, 0 }; + static ulong[] dim3627KuoInit = { 1, 1, 1, 11, 7, 19, 113, 133, 83, 851, 1543, 1699, 4527, 3167, 10793, 0 }; + static ulong[] dim3628KuoInit = { 1, 3, 3, 3, 31, 55, 35, 161, 133, 83, 469, 3011, 4513, 4677, 2363, 0 }; + static ulong[] dim3629KuoInit = { 1, 1, 3, 1, 29, 51, 29, 163, 95, 221, 973, 2819, 3103, 9969, 10347, 0 }; + static ulong[] dim3630KuoInit = { 1, 1, 5, 7, 31, 5, 73, 159, 339, 523, 399, 4041, 4341, 11527, 505, 0 }; + static ulong[] dim3631KuoInit = { 1, 1, 3, 7, 15, 55, 91, 117, 233, 497, 485, 1187, 5185, 13127, 14393, 0 }; + static ulong[] dim3632KuoInit = { 1, 3, 7, 9, 27, 19, 23, 197, 99, 779, 423, 2735, 3513, 8227, 31127, 0 }; + static ulong[] dim3633KuoInit = { 1, 3, 3, 1, 3, 61, 89, 137, 189, 325, 1797, 2287, 5033, 7351, 1131, 0 }; + static ulong[] dim3634KuoInit = { 1, 3, 3, 15, 19, 9, 83, 87, 451, 317, 667, 3379, 2225, 6437, 31515, 0 }; + static ulong[] dim3635KuoInit = { 1, 1, 1, 15, 13, 31, 121, 131, 473, 717, 1507, 1483, 4819, 14375, 24667, 0 }; + static ulong[] dim3636KuoInit = { 1, 1, 1, 5, 5, 55, 101, 111, 89, 481, 2031, 3043, 5727, 1253, 11951, 0 }; + static ulong[] dim3637KuoInit = { 1, 3, 1, 1, 3, 13, 67, 129, 311, 125, 121, 2833, 3555, 7761, 27343, 0 }; + static ulong[] dim3638KuoInit = { 1, 3, 7, 7, 29, 37, 63, 59, 5, 691, 1625, 97, 6113, 14795, 31471, 0 }; + static ulong[] dim3639KuoInit = { 1, 3, 3, 3, 25, 7, 65, 207, 371, 29, 1627, 1785, 5203, 5153, 1461, 0 }; + static ulong[] dim3640KuoInit = { 1, 3, 3, 11, 1, 37, 121, 249, 381, 309, 1545, 4039, 5657, 6783, 1889, 0 }; + static ulong[] dim3641KuoInit = { 1, 1, 1, 9, 29, 19, 51, 213, 185, 481, 1929, 2475, 567, 10045, 32619, 0 }; + static ulong[] dim3642KuoInit = { 1, 1, 3, 7, 13, 13, 17, 47, 55, 521, 473, 495, 7807, 1645, 17713, 0 }; + static ulong[] dim3643KuoInit = { 1, 1, 1, 3, 5, 63, 119, 167, 357, 231, 1915, 3605, 3579, 3041, 603, 0 }; + static ulong[] dim3644KuoInit = { 1, 3, 3, 7, 31, 5, 93, 193, 175, 801, 1963, 1413, 1641, 4073, 16017, 0 }; + static ulong[] dim3645KuoInit = { 1, 3, 3, 11, 11, 49, 53, 57, 1, 799, 301, 2611, 2975, 7595, 25891, 0 }; + static ulong[] dim3646KuoInit = { 1, 3, 1, 3, 19, 41, 63, 173, 257, 903, 1977, 3799, 3985, 14807, 24903, 0 }; + static ulong[] dim3647KuoInit = { 1, 3, 3, 11, 17, 53, 61, 115, 453, 395, 993, 3365, 4071, 4737, 29469, 0 }; + static ulong[] dim3648KuoInit = { 1, 3, 1, 13, 3, 55, 109, 149, 313, 621, 345, 4037, 677, 3787, 6701, 0 }; + static ulong[] dim3649KuoInit = { 1, 3, 3, 9, 23, 11, 63, 21, 47, 949, 47, 3055, 3403, 7581, 12853, 0 }; + static ulong[] dim3650KuoInit = { 1, 1, 1, 9, 7, 21, 15, 203, 167, 677, 49, 2777, 7817, 13207, 31485, 0 }; + static ulong[] dim3651KuoInit = { 1, 1, 1, 3, 29, 41, 37, 61, 343, 279, 127, 925, 7091, 14477, 24149, 0 }; + static ulong[] dim3652KuoInit = { 1, 1, 1, 11, 3, 33, 35, 237, 133, 653, 1491, 2183, 3565, 14773, 4521, 0 }; + static ulong[] dim3653KuoInit = { 1, 1, 5, 3, 31, 43, 13, 79, 465, 785, 1913, 1133, 2701, 9007, 15695, 0 }; + static ulong[] dim3654KuoInit = { 1, 3, 3, 1, 23, 43, 5, 155, 369, 131, 671, 1109, 7951, 1929, 23965, 0 }; + static ulong[] dim3655KuoInit = { 1, 1, 5, 7, 9, 15, 23, 59, 511, 931, 259, 1953, 1197, 9441, 25545, 0 }; + static ulong[] dim3656KuoInit = { 1, 1, 7, 7, 27, 25, 51, 81, 479, 491, 203, 4009, 4621, 11153, 12049, 0 }; + static ulong[] dim3657KuoInit = { 1, 3, 5, 15, 25, 11, 77, 253, 249, 761, 707, 161, 7519, 5381, 1549, 0 }; + static ulong[] dim3658KuoInit = { 1, 1, 1, 13, 11, 39, 59, 191, 443, 471, 53, 1639, 505, 1281, 1919, 0 }; + static ulong[] dim3659KuoInit = { 1, 1, 3, 7, 29, 47, 121, 135, 411, 95, 1255, 635, 835, 7905, 18435, 0 }; + static ulong[] dim3660KuoInit = { 1, 1, 3, 15, 21, 57, 65, 75, 333, 61, 1861, 3903, 6051, 8311, 2791, 0 }; + static ulong[] dim3661KuoInit = { 1, 3, 3, 7, 7, 49, 121, 233, 305, 697, 525, 3921, 5747, 2951, 24321, 0 }; + static ulong[] dim3662KuoInit = { 1, 1, 3, 3, 9, 23, 53, 121, 187, 35, 1973, 829, 575, 4003, 32159, 0 }; + static ulong[] dim3663KuoInit = { 1, 1, 3, 1, 3, 57, 25, 99, 383, 97, 1751, 1799, 2001, 8335, 20349, 0 }; + static ulong[] dim3664KuoInit = { 1, 1, 7, 9, 11, 17, 25, 107, 483, 183, 559, 2531, 6509, 9449, 1793, 0 }; + static ulong[] dim3665KuoInit = { 1, 3, 3, 1, 3, 43, 89, 57, 15, 269, 521, 1119, 3573, 9801, 30943, 0 }; + static ulong[] dim3666KuoInit = { 1, 3, 7, 3, 7, 41, 101, 177, 47, 47, 2009, 2127, 5113, 13541, 4133, 0 }; + static ulong[] dim3667KuoInit = { 1, 1, 3, 7, 23, 63, 67, 73, 335, 471, 1137, 3101, 5539, 16203, 15395, 12455, 0 }; + static ulong[] dim3668KuoInit = { 1, 3, 1, 11, 5, 9, 43, 123, 91, 23, 1199, 287, 5343, 1937, 12115, 4749, 0 }; + static ulong[] dim3669KuoInit = { 1, 1, 7, 11, 27, 3, 29, 251, 413, 147, 403, 2065, 2695, 11657, 15519, 49391, 0 }; + static ulong[] dim3670KuoInit = { 1, 3, 7, 11, 25, 7, 125, 137, 479, 753, 309, 1075, 7991, 2629, 4039, 6749, 0 }; + static ulong[] dim3671KuoInit = { 1, 1, 7, 1, 3, 27, 69, 227, 503, 915, 569, 115, 4299, 10799, 13745, 7973, 0 }; + static ulong[] dim3672KuoInit = { 1, 3, 1, 11, 17, 49, 33, 161, 429, 153, 1179, 4005, 6507, 10507, 1779, 5331, 0 }; + static ulong[] dim3673KuoInit = { 1, 3, 1, 13, 25, 45, 117, 47, 253, 851, 627, 593, 7555, 3677, 30695, 38851, 0 }; + static ulong[] dim3674KuoInit = { 1, 3, 1, 11, 25, 19, 95, 191, 505, 683, 67, 2375, 995, 8647, 4853, 17483, 0 }; + static ulong[] dim3675KuoInit = { 1, 3, 3, 15, 7, 57, 101, 151, 477, 343, 879, 2161, 1585, 1903, 6459, 45285, 0 }; + static ulong[] dim3676KuoInit = { 1, 1, 5, 3, 7, 7, 31, 219, 137, 107, 119, 2959, 7453, 9215, 20463, 61165, 0 }; + static ulong[] dim3677KuoInit = { 1, 1, 3, 15, 25, 39, 41, 165, 421, 567, 1095, 4055, 7321, 831, 81, 50377, 0 }; + static ulong[] dim3678KuoInit = { 1, 1, 3, 1, 21, 23, 65, 31, 331, 875, 1449, 653, 1975, 783, 29021, 47225, 0 }; + static ulong[] dim3679KuoInit = { 1, 1, 7, 1, 21, 21, 39, 39, 289, 129, 345, 2983, 2419, 133, 2519, 33307, 0 }; + static ulong[] dim3680KuoInit = { 1, 3, 5, 1, 27, 23, 53, 63, 315, 93, 335, 3239, 6749, 12985, 5863, 49565, 0 }; + static ulong[] dim3681KuoInit = { 1, 3, 7, 11, 17, 23, 89, 253, 329, 837, 589, 1135, 4099, 3123, 25567, 21017, 0 }; + static ulong[] dim3682KuoInit = { 1, 3, 7, 3, 21, 17, 111, 21, 73, 901, 2017, 3711, 159, 6703, 32209, 34411, 0 }; + static ulong[] dim3683KuoInit = { 1, 1, 1, 9, 19, 59, 1, 31, 273, 683, 1155, 2543, 477, 8479, 25235, 61595, 0 }; + static ulong[] dim3684KuoInit = { 1, 1, 7, 1, 13, 17, 97, 49, 221, 63, 197, 465, 1801, 5389, 10395, 54157, 0 }; + static ulong[] dim3685KuoInit = { 1, 1, 5, 9, 11, 59, 79, 139, 249, 185, 1131, 507, 3325, 2713, 27293, 21539, 0 }; + static ulong[] dim3686KuoInit = { 1, 1, 3, 5, 9, 45, 103, 145, 327, 675, 1609, 1703, 761, 4947, 187, 53903, 0 }; + static ulong[] dim3687KuoInit = { 1, 1, 1, 9, 19, 13, 77, 143, 303, 119, 1985, 1347, 6661, 6081, 9723, 52129, 0 }; + static ulong[] dim3688KuoInit = { 1, 3, 3, 3, 27, 27, 15, 163, 139, 159, 1921, 3549, 6477, 11423, 16055, 32399, 0 }; + static ulong[] dim3689KuoInit = { 1, 3, 1, 13, 19, 59, 5, 73, 481, 945, 187, 1223, 1771, 12961, 13853, 14513, 0 }; + static ulong[] dim3690KuoInit = { 1, 1, 7, 11, 5, 63, 33, 185, 477, 857, 1057, 2509, 7341, 7669, 13829, 51965, 0 }; + static ulong[] dim3691KuoInit = { 1, 1, 3, 5, 23, 17, 7, 87, 101, 817, 241, 853, 4067, 6409, 28217, 54395, 0 }; + static ulong[] dim3692KuoInit = { 1, 3, 3, 3, 21, 55, 47, 159, 407, 675, 1805, 2079, 1113, 149, 26071, 30829, 0 }; + static ulong[] dim3693KuoInit = { 1, 1, 3, 13, 7, 3, 89, 161, 95, 333, 525, 3979, 6831, 8007, 7063, 45299, 0 }; + static ulong[] dim3694KuoInit = { 1, 1, 7, 5, 17, 37, 95, 129, 215, 313, 1395, 2415, 6191, 6409, 29717, 4199, 0 }; + static ulong[] dim3695KuoInit = { 1, 1, 1, 7, 7, 45, 75, 175, 407, 763, 1037, 2477, 3167, 6991, 23905, 14707, 0 }; + static ulong[] dim3696KuoInit = { 1, 3, 7, 7, 23, 23, 103, 217, 479, 779, 941, 3173, 3639, 12833, 7133, 39269, 0 }; + static ulong[] dim3697KuoInit = { 1, 1, 1, 5, 9, 55, 19, 147, 287, 291, 1751, 2475, 6639, 5933, 27837, 33713, 0 }; + static ulong[] dim3698KuoInit = { 1, 1, 5, 5, 11, 39, 65, 109, 95, 637, 1897, 2395, 6975, 12431, 25097, 15649, 0 }; + static ulong[] dim3699KuoInit = { 1, 1, 3, 7, 25, 37, 27, 53, 373, 881, 1221, 2127, 1775, 2025, 10249, 55325, 0 }; + static ulong[] dim3700KuoInit = { 1, 1, 7, 15, 5, 37, 1, 99, 249, 209, 1177, 2953, 4455, 12125, 7679, 25543, 0 }; + static ulong[] dim3701KuoInit = { 1, 3, 3, 13, 9, 19, 97, 11, 331, 107, 1475, 769, 1749, 9375, 19477, 47559, 0 }; + static ulong[] dim3702KuoInit = { 1, 3, 7, 15, 25, 57, 69, 45, 21, 455, 1841, 1101, 2931, 2845, 21925, 43731, 0 }; + static ulong[] dim3703KuoInit = { 1, 1, 3, 11, 27, 33, 31, 33, 9, 825, 883, 2259, 7317, 5507, 3931, 61075, 0 }; + static ulong[] dim3704KuoInit = { 1, 3, 7, 5, 7, 21, 97, 203, 449, 671, 1037, 3985, 5655, 11099, 21981, 50149, 0 }; + static ulong[] dim3705KuoInit = { 1, 1, 1, 1, 5, 19, 109, 247, 73, 981, 1981, 3613, 6575, 3493, 9553, 259, 0 }; + static ulong[] dim3706KuoInit = { 1, 1, 7, 9, 3, 55, 13, 175, 285, 865, 1817, 911, 6393, 4843, 31569, 30115, 0 }; + static ulong[] dim3707KuoInit = { 1, 1, 3, 15, 21, 51, 85, 239, 171, 741, 881, 749, 4021, 2049, 25495, 62913, 0 }; + static ulong[] dim3708KuoInit = { 1, 3, 1, 1, 19, 9, 111, 119, 171, 903, 567, 1513, 8179, 10553, 5315, 63291, 0 }; + static ulong[] dim3709KuoInit = { 1, 3, 5, 1, 1, 61, 21, 197, 165, 371, 3, 2085, 669, 4497, 27467, 52995, 0 }; + static ulong[] dim3710KuoInit = { 1, 3, 5, 13, 29, 37, 95, 247, 161, 621, 83, 2597, 6779, 13747, 18873, 6173, 0 }; + static ulong[] dim3711KuoInit = { 1, 1, 3, 5, 21, 5, 41, 137, 77, 829, 689, 563, 5331, 8061, 21371, 58565, 0 }; + static ulong[] dim3712KuoInit = { 1, 3, 7, 13, 1, 19, 11, 111, 35, 39, 1513, 1241, 3739, 16191, 25097, 25947, 0 }; + static ulong[] dim3713KuoInit = { 1, 1, 5, 1, 27, 45, 11, 29, 153, 321, 1657, 1419, 6983, 11935, 8295, 24313, 0 }; + static ulong[] dim3714KuoInit = { 1, 3, 3, 11, 1, 57, 109, 139, 53, 883, 81, 333, 5133, 13891, 7775, 13401, 0 }; + static ulong[] dim3715KuoInit = { 1, 3, 5, 15, 5, 35, 121, 15, 73, 313, 1903, 437, 1567, 11905, 7679, 14265, 0 }; + static ulong[] dim3716KuoInit = { 1, 3, 7, 3, 31, 63, 69, 135, 75, 489, 1271, 585, 7361, 15965, 3099, 37309, 0 }; + static ulong[] dim3717KuoInit = { 1, 1, 7, 11, 15, 21, 97, 73, 115, 795, 421, 69, 7795, 9895, 1755, 44375, 0 }; + static ulong[] dim3718KuoInit = { 1, 3, 5, 9, 17, 13, 49, 61, 395, 637, 1737, 3103, 5197, 7799, 25425, 56313, 0 }; + static ulong[] dim3719KuoInit = { 1, 3, 1, 9, 17, 19, 87, 131, 315, 865, 813, 163, 1045, 12573, 12657, 43715, 0 }; + static ulong[] dim3720KuoInit = { 1, 3, 7, 3, 27, 23, 9, 185, 291, 421, 603, 1339, 1085, 15449, 1543, 5815, 0 }; + static ulong[] dim3721KuoInit = { 1, 3, 1, 5, 29, 35, 15, 75, 135, 911, 1153, 3067, 3475, 11653, 27485, 8459, 0 }; + static ulong[] dim3722KuoInit = { 1, 3, 5, 7, 3, 9, 43, 29, 77, 551, 973, 2165, 1499, 9185, 27025, 31605, 0 }; + static ulong[] dim3723KuoInit = { 1, 1, 1, 9, 23, 49, 13, 229, 295, 497, 187, 1995, 1883, 9109, 2689, 37275, 0 }; + static ulong[] dim3724KuoInit = { 1, 1, 7, 15, 11, 1, 61, 183, 129, 869, 1271, 3439, 7743, 5831, 12829, 1341, 0 }; + static ulong[] dim3725KuoInit = { 1, 3, 7, 1, 17, 45, 31, 29, 441, 533, 1479, 3519, 2083, 149, 22119, 37615, 0 }; + static ulong[] dim3726KuoInit = { 1, 1, 3, 7, 31, 39, 101, 209, 237, 211, 1015, 1339, 857, 3833, 16875, 38147, 0 }; + static ulong[] dim3727KuoInit = { 1, 3, 7, 13, 29, 23, 9, 79, 71, 363, 487, 595, 259, 12425, 28181, 20717, 0 }; + static ulong[] dim3728KuoInit = { 1, 3, 3, 11, 1, 21, 97, 39, 101, 1, 121, 3083, 109, 7889, 29005, 57081, 0 }; + static ulong[] dim3729KuoInit = { 1, 3, 3, 15, 19, 19, 91, 17, 281, 121, 1653, 3099, 181, 15911, 29553, 10047, 0 }; + static ulong[] dim3730KuoInit = { 1, 1, 3, 9, 27, 39, 69, 57, 25, 595, 723, 1779, 7537, 9397, 5563, 8197, 0 }; + static ulong[] dim3731KuoInit = { 1, 1, 1, 1, 11, 61, 127, 81, 439, 723, 1147, 3639, 1207, 5127, 10209, 33629, 0 }; + static ulong[] dim3732KuoInit = { 1, 3, 1, 9, 27, 55, 69, 147, 477, 663, 833, 3113, 2585, 9497, 679, 62759, 0 }; + static ulong[] dim3733KuoInit = { 1, 3, 1, 15, 9, 51, 67, 191, 105, 3, 1439, 1915, 3059, 3001, 4035, 551, 0 }; + static ulong[] dim3734KuoInit = { 1, 1, 3, 15, 1, 3, 11, 171, 189, 659, 1279, 3995, 6729, 6187, 22213, 22709, 0 }; + static ulong[] dim3735KuoInit = { 1, 1, 7, 11, 27, 31, 3, 183, 209, 931, 99, 1901, 113, 15779, 11525, 29949, 0 }; + static ulong[] dim3736KuoInit = { 1, 3, 7, 13, 11, 51, 1, 173, 271, 785, 1875, 2115, 1977, 189, 7819, 8133, 0 }; + static ulong[] dim3737KuoInit = { 1, 3, 7, 7, 21, 9, 5, 253, 495, 415, 3, 1979, 2331, 12229, 29901, 7115, 0 }; + static ulong[] dim3738KuoInit = { 1, 3, 1, 15, 21, 11, 105, 81, 269, 347, 901, 81, 7077, 11813, 18739, 57959, 0 }; + static ulong[] dim3739KuoInit = { 1, 1, 1, 1, 19, 57, 17, 87, 325, 129, 1907, 1641, 6247, 12073, 31629, 28503, 0 }; + static ulong[] dim3740KuoInit = { 1, 1, 5, 15, 29, 27, 81, 11, 383, 881, 1385, 3787, 503, 1369, 25031, 42049, 0 }; + static ulong[] dim3741KuoInit = { 1, 3, 7, 15, 27, 15, 13, 13, 279, 785, 163, 1907, 4523, 12133, 1497, 18845, 0 }; + static ulong[] dim3742KuoInit = { 1, 3, 7, 9, 13, 37, 51, 83, 309, 645, 383, 1607, 2087, 14287, 14375, 39619, 0 }; + static ulong[] dim3743KuoInit = { 1, 3, 7, 5, 11, 13, 21, 45, 95, 667, 1597, 1823, 5887, 10909, 26279, 29845, 0 }; + static ulong[] dim3744KuoInit = { 1, 3, 1, 1, 25, 61, 21, 91, 81, 173, 1271, 339, 2185, 16033, 3687, 53797, 0 }; + static ulong[] dim3745KuoInit = { 1, 3, 3, 15, 19, 27, 59, 153, 453, 523, 85, 3367, 4439, 13605, 6219, 25593, 0 }; + static ulong[] dim3746KuoInit = { 1, 3, 5, 3, 27, 57, 127, 225, 199, 823, 431, 2911, 4421, 14063, 1467, 46787, 0 }; + static ulong[] dim3747KuoInit = { 1, 3, 5, 1, 31, 33, 17, 73, 357, 199, 677, 2015, 1213, 8503, 4785, 54835, 0 }; + static ulong[] dim3748KuoInit = { 1, 1, 1, 11, 15, 13, 65, 1, 311, 469, 1307, 2605, 5281, 15665, 6349, 61753, 0 }; + static ulong[] dim3749KuoInit = { 1, 1, 1, 3, 19, 33, 49, 141, 229, 925, 1059, 1295, 3093, 6207, 7607, 63987, 0 }; + static ulong[] dim3750KuoInit = { 1, 1, 3, 1, 21, 63, 17, 131, 27, 295, 1969, 3259, 2011, 11005, 32249, 57641, 0 }; + static ulong[] dim3751KuoInit = { 1, 3, 7, 15, 25, 27, 11, 105, 99, 923, 1003, 2765, 49, 10367, 22119, 27199, 0 }; + static ulong[] dim3752KuoInit = { 1, 1, 1, 3, 31, 11, 57, 253, 31, 259, 1687, 1135, 1675, 12051, 3543, 19087, 0 }; + static ulong[] dim3753KuoInit = { 1, 3, 5, 9, 9, 53, 119, 215, 213, 67, 343, 2743, 7303, 14225, 13379, 51001, 0 }; + static ulong[] dim3754KuoInit = { 1, 3, 7, 9, 1, 45, 11, 125, 209, 459, 1037, 673, 2497, 669, 11251, 19387, 0 }; + static ulong[] dim3755KuoInit = { 1, 1, 1, 15, 21, 47, 63, 45, 349, 561, 1823, 2005, 4173, 5595, 3789, 34133, 0 }; + static ulong[] dim3756KuoInit = { 1, 1, 3, 3, 5, 7, 83, 63, 305, 679, 879, 3613, 7627, 9849, 3987, 28795, 0 }; + static ulong[] dim3757KuoInit = { 1, 3, 7, 11, 7, 51, 119, 1, 21, 213, 1399, 3715, 7775, 1003, 6749, 5547, 0 }; + static ulong[] dim3758KuoInit = { 1, 1, 7, 9, 21, 53, 51, 137, 379, 439, 1497, 3455, 2509, 2539, 3583, 5107, 0 }; + static ulong[] dim3759KuoInit = { 1, 3, 5, 3, 9, 13, 73, 237, 65, 53, 663, 3895, 7579, 10027, 23969, 34767, 0 }; + static ulong[] dim3760KuoInit = { 1, 3, 7, 3, 13, 57, 125, 245, 243, 561, 91, 863, 1925, 13553, 4113, 31077, 0 }; + static ulong[] dim3761KuoInit = { 1, 1, 5, 7, 9, 31, 9, 83, 355, 249, 1741, 3593, 425, 6377, 10607, 48275, 0 }; + static ulong[] dim3762KuoInit = { 1, 3, 7, 3, 19, 17, 123, 75, 413, 981, 877, 3489, 5907, 6141, 2729, 49219, 0 }; + static ulong[] dim3763KuoInit = { 1, 3, 1, 3, 31, 39, 97, 233, 99, 17, 105, 2911, 347, 4069, 32535, 47179, 0 }; + static ulong[] dim3764KuoInit = { 1, 1, 5, 7, 1, 51, 1, 59, 197, 487, 1763, 2449, 4249, 55, 11885, 57597, 0 }; + static ulong[] dim3765KuoInit = { 1, 3, 5, 3, 25, 49, 43, 101, 353, 759, 1295, 3441, 1521, 2879, 9815, 27091, 0 }; + static ulong[] dim3766KuoInit = { 1, 3, 5, 11, 1, 7, 69, 205, 271, 511, 1157, 3597, 2857, 10997, 15525, 6807, 0 }; + static ulong[] dim3767KuoInit = { 1, 1, 1, 15, 11, 1, 45, 213, 463, 389, 1761, 3005, 3359, 12829, 18211, 2107, 0 }; + static ulong[] dim3768KuoInit = { 1, 1, 7, 13, 27, 59, 115, 203, 321, 711, 1489, 2893, 1427, 4599, 17105, 10063, 0 }; + static ulong[] dim3769KuoInit = { 1, 3, 1, 13, 5, 5, 53, 221, 97, 535, 1967, 1951, 4077, 327, 18243, 43285, 0 }; + static ulong[] dim3770KuoInit = { 1, 3, 5, 13, 9, 61, 59, 255, 143, 21, 1859, 3509, 4295, 5107, 11117, 29431, 0 }; + static ulong[] dim3771KuoInit = { 1, 3, 3, 13, 19, 13, 33, 169, 17, 773, 1693, 147, 5143, 2357, 2295, 50187, 0 }; + static ulong[] dim3772KuoInit = { 1, 1, 5, 11, 11, 19, 79, 151, 441, 825, 665, 2947, 5391, 8695, 155, 26751, 0 }; + static ulong[] dim3773KuoInit = { 1, 1, 7, 15, 13, 31, 77, 61, 249, 341, 1737, 3567, 6337, 14457, 3799, 20283, 0 }; + static ulong[] dim3774KuoInit = { 1, 1, 7, 11, 13, 5, 83, 59, 185, 325, 2029, 1329, 1125, 10799, 27107, 2817, 0 }; + static ulong[] dim3775KuoInit = { 1, 3, 5, 7, 17, 43, 21, 113, 57, 503, 1647, 393, 4525, 8385, 27153, 37175, 0 }; + static ulong[] dim3776KuoInit = { 1, 3, 1, 15, 23, 57, 3, 177, 419, 65, 1895, 1107, 7705, 7915, 20677, 27931, 0 }; + static ulong[] dim3777KuoInit = { 1, 3, 7, 13, 13, 63, 53, 237, 237, 161, 265, 1053, 161, 11635, 1455, 55551, 0 }; + static ulong[] dim3778KuoInit = { 1, 3, 7, 5, 15, 41, 7, 77, 93, 737, 1195, 1381, 399, 7829, 6251, 34883, 0 }; + static ulong[] dim3779KuoInit = { 1, 1, 5, 7, 23, 63, 119, 35, 115, 829, 441, 4059, 4755, 11331, 18071, 6911, 0 }; + static ulong[] dim3780KuoInit = { 1, 3, 3, 7, 21, 33, 49, 47, 329, 341, 45, 3093, 5937, 6803, 31681, 9575, 0 }; + static ulong[] dim3781KuoInit = { 1, 1, 1, 13, 13, 19, 121, 71, 231, 915, 981, 93, 5879, 15645, 8555, 58411, 0 }; + static ulong[] dim3782KuoInit = { 1, 3, 7, 5, 31, 45, 71, 189, 337, 955, 1263, 2271, 1615, 15137, 29933, 16585, 0 }; + static ulong[] dim3783KuoInit = { 1, 1, 7, 15, 29, 49, 85, 255, 143, 585, 1099, 1159, 1519, 15593, 6177, 16083, 0 }; + static ulong[] dim3784KuoInit = { 1, 3, 5, 1, 13, 59, 79, 67, 341, 815, 703, 3857, 4711, 15155, 15997, 31699, 0 }; + static ulong[] dim3785KuoInit = { 1, 3, 3, 7, 11, 51, 77, 231, 241, 261, 1607, 4031, 3779, 4289, 22039, 47177, 0 }; + static ulong[] dim3786KuoInit = { 1, 3, 7, 1, 21, 23, 31, 233, 225, 883, 715, 777, 2433, 3665, 26695, 60997, 0 }; + static ulong[] dim3787KuoInit = { 1, 3, 1, 1, 27, 17, 55, 33, 133, 899, 1443, 283, 6839, 9497, 22399, 60527, 0 }; + static ulong[] dim3788KuoInit = { 1, 1, 3, 3, 5, 63, 91, 5, 275, 219, 1679, 2385, 4727, 9995, 14079, 24695, 0 }; + static ulong[] dim3789KuoInit = { 1, 3, 7, 15, 9, 3, 77, 215, 265, 317, 1655, 1027, 5029, 6867, 9465, 64257, 0 }; + static ulong[] dim3790KuoInit = { 1, 3, 1, 3, 23, 7, 67, 63, 503, 269, 85, 3669, 5941, 13833, 25857, 34221, 0 }; + static ulong[] dim3791KuoInit = { 1, 1, 1, 7, 13, 31, 83, 113, 389, 923, 1173, 2457, 997, 9761, 17033, 50521, 0 }; + static ulong[] dim3792KuoInit = { 1, 3, 1, 1, 15, 31, 93, 243, 221, 331, 1961, 3251, 6459, 3341, 28535, 27909, 0 }; + static ulong[] dim3793KuoInit = { 1, 3, 1, 15, 27, 1, 75, 169, 277, 921, 5, 1391, 5665, 14659, 6895, 37927, 0 }; + static ulong[] dim3794KuoInit = { 1, 3, 1, 9, 17, 63, 93, 35, 225, 109, 977, 2623, 3779, 8011, 11643, 57789, 0 }; + static ulong[] dim3795KuoInit = { 1, 1, 5, 3, 17, 5, 63, 109, 449, 695, 1021, 2749, 3981, 2073, 24537, 43643, 0 }; + static ulong[] dim3796KuoInit = { 1, 1, 5, 1, 1, 19, 15, 249, 3, 431, 743, 3813, 4013, 4027, 1943, 23569, 0 }; + static ulong[] dim3797KuoInit = { 1, 3, 7, 1, 9, 49, 93, 59, 425, 325, 1925, 495, 6611, 2425, 19847, 58683, 0 }; + static ulong[] dim3798KuoInit = { 1, 3, 5, 5, 7, 21, 71, 51, 335, 67, 373, 1805, 1805, 4069, 6585, 56579, 0 }; + static ulong[] dim3799KuoInit = { 1, 3, 1, 7, 25, 27, 49, 131, 491, 105, 1467, 665, 6777, 15467, 13597, 49141, 0 }; + static ulong[] dim3800KuoInit = { 1, 3, 5, 13, 9, 9, 37, 159, 19, 91, 1963, 3133, 5147, 8655, 11153, 44491, 0 }; + static ulong[] dim3801KuoInit = { 1, 3, 5, 7, 13, 55, 41, 67, 155, 853, 1651, 3511, 4391, 6359, 9129, 32359, 0 }; + static ulong[] dim3802KuoInit = { 1, 3, 5, 5, 9, 3, 27, 101, 467, 185, 1071, 1477, 1523, 9535, 15433, 7493, 0 }; + static ulong[] dim3803KuoInit = { 1, 1, 1, 3, 15, 19, 3, 97, 241, 995, 451, 1651, 241, 1063, 2521, 65531, 0 }; + static ulong[] dim3804KuoInit = { 1, 3, 3, 5, 23, 13, 117, 65, 119, 871, 1245, 3577, 7303, 9433, 13701, 21321, 0 }; + static ulong[] dim3805KuoInit = { 1, 1, 1, 11, 25, 33, 121, 203, 325, 775, 1835, 1385, 2541, 3399, 275, 54311, 0 }; + static ulong[] dim3806KuoInit = { 1, 1, 3, 3, 13, 41, 5, 63, 415, 771, 375, 3933, 5239, 1731, 7675, 11855, 0 }; + static ulong[] dim3807KuoInit = { 1, 1, 5, 7, 23, 49, 27, 119, 231, 897, 1995, 3847, 25, 7505, 2823, 10115, 0 }; + static ulong[] dim3808KuoInit = { 1, 3, 5, 1, 5, 41, 41, 129, 339, 861, 147, 3299, 1123, 2175, 27111, 2067, 0 }; + static ulong[] dim3809KuoInit = { 1, 1, 3, 5, 5, 39, 71, 53, 483, 585, 1167, 2037, 3125, 499, 29491, 43467, 0 }; + static ulong[] dim3810KuoInit = { 1, 1, 1, 3, 25, 9, 85, 197, 271, 457, 1159, 3805, 2423, 11777, 4383, 57495, 0 }; + static ulong[] dim3811KuoInit = { 1, 3, 7, 9, 25, 5, 33, 255, 325, 643, 499, 3233, 4477, 14189, 12183, 7667, 0 }; + static ulong[] dim3812KuoInit = { 1, 3, 3, 5, 1, 63, 3, 51, 173, 1011, 1423, 3453, 2471, 7801, 29989, 8347, 0 }; + static ulong[] dim3813KuoInit = { 1, 1, 7, 11, 17, 39, 23, 13, 413, 503, 321, 3699, 6441, 11953, 24253, 2561, 0 }; + static ulong[] dim3814KuoInit = { 1, 1, 1, 3, 31, 45, 21, 215, 55, 555, 771, 2703, 8113, 3279, 6053, 48617, 0 }; + static ulong[] dim3815KuoInit = { 1, 1, 7, 9, 25, 25, 33, 101, 111, 643, 1277, 3833, 7431, 14395, 20849, 14455, 0 }; + static ulong[] dim3816KuoInit = { 1, 3, 7, 11, 21, 15, 95, 179, 437, 747, 1131, 83, 415, 12605, 29245, 28021, 0 }; + static ulong[] dim3817KuoInit = { 1, 3, 7, 5, 13, 59, 9, 217, 287, 929, 691, 3201, 4915, 3301, 15371, 17063, 0 }; + static ulong[] dim3818KuoInit = { 1, 1, 1, 7, 31, 3, 27, 229, 151, 321, 801, 1271, 1195, 11221, 16903, 27919, 0 }; + static ulong[] dim3819KuoInit = { 1, 1, 5, 9, 5, 41, 105, 133, 265, 167, 505, 3939, 771, 1291, 1109, 52601, 0 }; + static ulong[] dim3820KuoInit = { 1, 3, 5, 11, 21, 23, 23, 229, 197, 623, 1973, 901, 147, 15751, 29429, 13159, 0 }; + static ulong[] dim3821KuoInit = { 1, 1, 5, 11, 25, 53, 79, 123, 245, 939, 1889, 4073, 417, 13625, 14691, 56965, 0 }; + static ulong[] dim3822KuoInit = { 1, 1, 1, 11, 1, 39, 51, 231, 367, 233, 1453, 3095, 6071, 7521, 469, 8407, 0 }; + static ulong[] dim3823KuoInit = { 1, 3, 5, 1, 9, 17, 109, 135, 85, 151, 1217, 1643, 4455, 3923, 11681, 32807, 0 }; + static ulong[] dim3824KuoInit = { 1, 1, 1, 13, 11, 39, 27, 205, 85, 1019, 1759, 1705, 4585, 8311, 29123, 44045, 0 }; + static ulong[] dim3825KuoInit = { 1, 3, 1, 3, 9, 33, 65, 253, 319, 65, 851, 3357, 2827, 10107, 10197, 19111, 0 }; + static ulong[] dim3826KuoInit = { 1, 3, 7, 3, 3, 53, 67, 99, 501, 603, 1409, 359, 7395, 12827, 10867, 17473, 0 }; + static ulong[] dim3827KuoInit = { 1, 1, 7, 5, 5, 35, 97, 49, 365, 971, 1707, 1305, 6801, 14451, 32473, 57269, 0 }; + static ulong[] dim3828KuoInit = { 1, 1, 5, 11, 25, 57, 115, 195, 47, 923, 1515, 2043, 803, 6371, 25341, 63263, 0 }; + static ulong[] dim3829KuoInit = { 1, 1, 5, 3, 27, 53, 83, 91, 367, 695, 1809, 927, 6815, 1229, 27359, 28937, 0 }; + static ulong[] dim3830KuoInit = { 1, 1, 3, 7, 3, 3, 17, 203, 95, 577, 1531, 1645, 7271, 5541, 30905, 38825, 0 }; + static ulong[] dim3831KuoInit = { 1, 1, 7, 9, 7, 57, 97, 185, 75, 681, 1197, 3713, 6429, 4723, 26275, 23495, 0 }; + static ulong[] dim3832KuoInit = { 1, 3, 1, 3, 5, 25, 71, 171, 143, 603, 1349, 1723, 7493, 8417, 24171, 13421, 0 }; + static ulong[] dim3833KuoInit = { 1, 3, 1, 15, 23, 57, 33, 247, 409, 511, 29, 1403, 5831, 1749, 28441, 4117, 0 }; + static ulong[] dim3834KuoInit = { 1, 1, 3, 15, 31, 11, 105, 239, 431, 127, 343, 961, 6449, 1677, 24937, 15859, 0 }; + static ulong[] dim3835KuoInit = { 1, 1, 5, 3, 27, 57, 61, 245, 425, 417, 301, 521, 2425, 2547, 11349, 47931, 0 }; + static ulong[] dim3836KuoInit = { 1, 3, 5, 3, 15, 19, 19, 127, 151, 913, 1061, 1795, 2519, 6297, 2519, 56677, 0 }; + static ulong[] dim3837KuoInit = { 1, 1, 3, 9, 25, 3, 67, 53, 305, 609, 1067, 1003, 6933, 14009, 24475, 23183, 0 }; + static ulong[] dim3838KuoInit = { 1, 1, 5, 7, 21, 35, 89, 95, 399, 341, 1337, 2815, 3605, 3209, 9881, 6399, 0 }; + static ulong[] dim3839KuoInit = { 1, 1, 7, 1, 29, 63, 23, 219, 145, 583, 985, 2577, 3951, 15199, 26981, 2755, 0 }; + static ulong[] dim3840KuoInit = { 1, 3, 7, 1, 13, 45, 105, 139, 103, 83, 819, 2655, 39, 11661, 11057, 38189, 0 }; + static ulong[] dim3841KuoInit = { 1, 3, 1, 15, 23, 41, 79, 237, 353, 67, 1551, 2345, 1169, 4623, 1391, 18607, 0 }; + static ulong[] dim3842KuoInit = { 1, 1, 1, 13, 29, 31, 43, 65, 25, 387, 1109, 2515, 3967, 2221, 27321, 20511, 0 }; + static ulong[] dim3843KuoInit = { 1, 1, 1, 3, 17, 45, 35, 211, 31, 45, 1791, 2225, 6995, 15241, 24555, 45993, 0 }; + static ulong[] dim3844KuoInit = { 1, 1, 5, 5, 31, 25, 71, 57, 87, 531, 117, 267, 2415, 2213, 603, 23369, 0 }; + static ulong[] dim3845KuoInit = { 1, 1, 1, 5, 23, 53, 39, 3, 93, 697, 25, 465, 1517, 6061, 11759, 34863, 0 }; + static ulong[] dim3846KuoInit = { 1, 1, 1, 13, 29, 29, 41, 27, 499, 285, 355, 3915, 1683, 11933, 24685, 59013, 0 }; + static ulong[] dim3847KuoInit = { 1, 3, 1, 3, 21, 21, 25, 251, 109, 469, 1841, 889, 6541, 12961, 9449, 48755, 0 }; + static ulong[] dim3848KuoInit = { 1, 3, 1, 1, 21, 59, 41, 159, 159, 105, 999, 2535, 3251, 12213, 24005, 17145, 0 }; + static ulong[] dim3849KuoInit = { 1, 1, 7, 9, 1, 39, 43, 235, 447, 767, 871, 453, 7285, 3387, 14625, 40099, 0 }; + static ulong[] dim3850KuoInit = { 1, 1, 3, 3, 5, 11, 15, 205, 183, 309, 1747, 1089, 3141, 9129, 25149, 63109, 0 }; + static ulong[] dim3851KuoInit = { 1, 3, 7, 15, 23, 15, 7, 157, 45, 263, 1383, 735, 205, 16021, 13233, 23425, 0 }; + static ulong[] dim3852KuoInit = { 1, 1, 7, 13, 11, 31, 53, 23, 357, 953, 611, 2579, 475, 15183, 12755, 10347, 0 }; + static ulong[] dim3853KuoInit = { 1, 1, 1, 5, 7, 27, 41, 215, 247, 1001, 1369, 3105, 3195, 13417, 6967, 52501, 0 }; + static ulong[] dim3854KuoInit = { 1, 3, 7, 3, 3, 61, 35, 175, 415, 835, 1381, 3951, 6857, 10273, 26657, 5239, 0 }; + static ulong[] dim3855KuoInit = { 1, 3, 7, 5, 1, 27, 3, 251, 499, 637, 1101, 3817, 4823, 3065, 29919, 4151, 0 }; + static ulong[] dim3856KuoInit = { 1, 3, 7, 13, 19, 39, 1, 141, 353, 853, 295, 1201, 6895, 3965, 6417, 47379, 0 }; + static ulong[] dim3857KuoInit = { 1, 1, 7, 13, 11, 9, 99, 225, 161, 349, 421, 2803, 4461, 2319, 2495, 62429, 0 }; + static ulong[] dim3858KuoInit = { 1, 3, 1, 13, 31, 1, 47, 115, 299, 331, 1917, 2547, 969, 4841, 8237, 2405, 0 }; + static ulong[] dim3859KuoInit = { 1, 1, 1, 9, 9, 19, 77, 35, 225, 211, 1875, 3531, 2753, 12679, 6863, 42143, 0 }; + static ulong[] dim3860KuoInit = { 1, 1, 1, 3, 29, 25, 105, 19, 269, 863, 811, 2741, 143, 6353, 25109, 62251, 0 }; + static ulong[] dim3861KuoInit = { 1, 3, 5, 3, 27, 51, 11, 61, 245, 517, 891, 2081, 4523, 11703, 31477, 12113, 0 }; + static ulong[] dim3862KuoInit = { 1, 1, 1, 1, 27, 29, 25, 47, 143, 489, 1475, 1139, 1855, 8031, 21341, 23619, 0 }; + static ulong[] dim3863KuoInit = { 1, 1, 5, 1, 3, 45, 103, 59, 123, 831, 1883, 149, 5843, 10275, 3121, 21411, 0 }; + static ulong[] dim3864KuoInit = { 1, 1, 7, 1, 21, 11, 1, 35, 285, 501, 1407, 1307, 1371, 15057, 14091, 52279, 0 }; + static ulong[] dim3865KuoInit = { 1, 1, 3, 13, 3, 5, 9, 167, 139, 255, 1561, 2183, 1079, 2055, 24779, 19737, 0 }; + static ulong[] dim3866KuoInit = { 1, 1, 7, 13, 31, 29, 59, 157, 311, 447, 21, 2177, 3679, 7519, 987, 44221, 0 }; + static ulong[] dim3867KuoInit = { 1, 3, 3, 1, 11, 31, 95, 23, 457, 733, 1413, 273, 333, 14391, 16557, 35227, 0 }; + static ulong[] dim3868KuoInit = { 1, 1, 3, 9, 5, 3, 103, 59, 21, 475, 1455, 2995, 7651, 4893, 21739, 21379, 0 }; + static ulong[] dim3869KuoInit = { 1, 3, 5, 1, 9, 63, 55, 127, 283, 603, 1477, 331, 2115, 15965, 22433, 17311, 0 }; + static ulong[] dim3870KuoInit = { 1, 1, 3, 3, 5, 61, 105, 175, 245, 431, 479, 821, 3835, 3585, 16533, 63233, 0 }; + static ulong[] dim3871KuoInit = { 1, 1, 7, 1, 31, 57, 9, 11, 145, 519, 1915, 2809, 2943, 13885, 31223, 32897, 0 }; + static ulong[] dim3872KuoInit = { 1, 3, 1, 15, 5, 39, 67, 179, 285, 91, 1429, 3571, 1925, 9737, 28647, 8189, 0 }; + static ulong[] dim3873KuoInit = { 1, 3, 7, 11, 21, 25, 51, 173, 151, 283, 765, 2717, 3541, 10317, 9827, 24445, 0 }; + static ulong[] dim3874KuoInit = { 1, 3, 1, 13, 31, 25, 121, 71, 347, 129, 159, 1845, 475, 12777, 19607, 7163, 0 }; + static ulong[] dim3875KuoInit = { 1, 3, 1, 9, 29, 37, 59, 117, 375, 411, 1031, 3781, 3119, 6851, 30759, 46181, 0 }; + static ulong[] dim3876KuoInit = { 1, 3, 1, 7, 5, 41, 81, 141, 377, 817, 1007, 2211, 7303, 5833, 6117, 52265, 0 }; + static ulong[] dim3877KuoInit = { 1, 3, 5, 3, 7, 63, 83, 181, 169, 19, 1589, 3793, 7003, 12145, 25625, 35731, 0 }; + static ulong[] dim3878KuoInit = { 1, 1, 1, 5, 21, 39, 15, 225, 231, 497, 917, 559, 6515, 13637, 17721, 4725, 0 }; + static ulong[] dim3879KuoInit = { 1, 3, 1, 15, 17, 19, 93, 65, 281, 775, 613, 2453, 1969, 2499, 5373, 28207, 0 }; + static ulong[] dim3880KuoInit = { 1, 1, 5, 11, 9, 37, 103, 211, 357, 409, 457, 1527, 3289, 14293, 7681, 58069, 0 }; + static ulong[] dim3881KuoInit = { 1, 3, 5, 9, 1, 29, 83, 1, 35, 655, 491, 1447, 725, 7807, 13311, 345, 0 }; + static ulong[] dim3882KuoInit = { 1, 3, 1, 7, 19, 59, 103, 243, 157, 209, 399, 1113, 1595, 15075, 22475, 42835, 0 }; + static ulong[] dim3883KuoInit = { 1, 3, 5, 5, 27, 53, 69, 73, 413, 443, 559, 427, 2841, 13107, 8909, 35265, 0 }; + static ulong[] dim3884KuoInit = { 1, 3, 3, 7, 21, 39, 99, 75, 341, 917, 11, 1247, 247, 14285, 24531, 58523, 0 }; + static ulong[] dim3885KuoInit = { 1, 1, 7, 9, 29, 1, 55, 143, 363, 527, 103, 3735, 6373, 7837, 24451, 36999, 0 }; + static ulong[] dim3886KuoInit = { 1, 1, 3, 3, 3, 51, 71, 103, 173, 397, 1683, 489, 6515, 2531, 12517, 63165, 0 }; + static ulong[] dim3887KuoInit = { 1, 3, 7, 3, 27, 15, 31, 63, 323, 903, 1025, 2761, 1813, 2839, 2065, 20013, 0 }; + static ulong[] dim3888KuoInit = { 1, 1, 1, 13, 19, 37, 49, 207, 57, 45, 1517, 2715, 6315, 10499, 27195, 56175, 0 }; + static ulong[] dim3889KuoInit = { 1, 3, 5, 11, 13, 47, 91, 81, 459, 801, 1111, 3023, 5901, 12735, 14233, 24383, 0 }; + static ulong[] dim3890KuoInit = { 1, 3, 1, 5, 19, 39, 11, 69, 333, 17, 1339, 2991, 4411, 2749, 15423, 13805, 0 }; + static ulong[] dim3891KuoInit = { 1, 3, 5, 9, 19, 3, 109, 45, 461, 103, 811, 3089, 893, 16121, 1337, 31929, 0 }; + static ulong[] dim3892KuoInit = { 1, 3, 7, 11, 3, 21, 125, 241, 355, 519, 1551, 3273, 2413, 3371, 11435, 2277, 0 }; + static ulong[] dim3893KuoInit = { 1, 1, 5, 9, 7, 21, 93, 79, 25, 265, 1045, 2011, 4883, 8631, 22461, 31117, 0 }; + static ulong[] dim3894KuoInit = { 1, 1, 3, 9, 13, 35, 61, 203, 371, 185, 1445, 2017, 363, 13603, 23097, 22617, 0 }; + static ulong[] dim3895KuoInit = { 1, 1, 1, 1, 29, 33, 9, 139, 73, 119, 755, 2117, 3949, 3403, 30007, 58147, 0 }; + static ulong[] dim3896KuoInit = { 1, 1, 3, 5, 9, 29, 85, 1, 349, 573, 1191, 133, 235, 1557, 18147, 5839, 0 }; + static ulong[] dim3897KuoInit = { 1, 3, 3, 5, 15, 45, 5, 95, 359, 223, 37, 547, 3407, 4927, 32417, 49205, 0 }; + static ulong[] dim3898KuoInit = { 1, 1, 7, 11, 21, 57, 127, 95, 355, 903, 1555, 9, 1249, 2463, 7921, 20633, 0 }; + static ulong[] dim3899KuoInit = { 1, 3, 3, 11, 29, 35, 95, 237, 43, 289, 1547, 3951, 5489, 2699, 347, 14405, 0 }; + static ulong[] dim3900KuoInit = { 1, 3, 3, 11, 11, 23, 33, 171, 37, 989, 917, 139, 5497, 617, 25555, 27031, 0 }; + static ulong[] dim3901KuoInit = { 1, 1, 5, 1, 21, 55, 63, 191, 93, 207, 1799, 2143, 4147, 6853, 18129, 18287, 0 }; + static ulong[] dim3902KuoInit = { 1, 3, 7, 15, 23, 39, 59, 131, 51, 113, 941, 2599, 5593, 11311, 30561, 22307, 0 }; + static ulong[] dim3903KuoInit = { 1, 3, 7, 5, 21, 49, 93, 5, 399, 173, 1017, 3551, 937, 13653, 21411, 56835, 0 }; + static ulong[] dim3904KuoInit = { 1, 3, 1, 1, 15, 47, 57, 19, 93, 931, 1803, 2947, 1291, 10979, 22069, 47485, 0 }; + static ulong[] dim3905KuoInit = { 1, 3, 7, 11, 31, 19, 75, 195, 23, 235, 137, 2521, 4109, 233, 26961, 19185, 0 }; + static ulong[] dim3906KuoInit = { 1, 3, 3, 15, 9, 17, 87, 239, 233, 939, 1643, 1189, 7875, 5199, 26603, 52223, 0 }; + static ulong[] dim3907KuoInit = { 1, 3, 5, 7, 3, 31, 21, 255, 41, 95, 1267, 1873, 5535, 8419, 19791, 14811, 0 }; + static ulong[] dim3908KuoInit = { 1, 1, 7, 15, 7, 51, 27, 35, 17, 1015, 661, 2679, 1269, 15729, 17329, 33555, 0 }; + static ulong[] dim3909KuoInit = { 1, 1, 5, 1, 13, 19, 39, 105, 173, 255, 1873, 1527, 253, 3517, 19867, 56765, 0 }; + static ulong[] dim3910KuoInit = { 1, 1, 7, 1, 15, 13, 85, 27, 491, 827, 1151, 3591, 7819, 10085, 11307, 45059, 0 }; + static ulong[] dim3911KuoInit = { 1, 3, 5, 15, 21, 17, 23, 207, 223, 721, 655, 243, 4289, 4973, 29709, 9203, 0 }; + static ulong[] dim3912KuoInit = { 1, 1, 5, 11, 27, 51, 3, 199, 277, 121, 1637, 3973, 861, 7215, 32577, 4391, 0 }; + static ulong[] dim3913KuoInit = { 1, 1, 7, 9, 21, 27, 33, 199, 29, 917, 99, 2755, 821, 16003, 8325, 55587, 0 }; + static ulong[] dim3914KuoInit = { 1, 1, 7, 1, 19, 17, 61, 39, 377, 739, 13, 3435, 5081, 10591, 11957, 30049, 0 }; + static ulong[] dim3915KuoInit = { 1, 1, 5, 1, 25, 13, 117, 5, 479, 579, 907, 3135, 1011, 3389, 135, 41711, 0 }; + static ulong[] dim3916KuoInit = { 1, 3, 5, 5, 19, 15, 89, 169, 321, 981, 365, 333, 4913, 9577, 13835, 23439, 0 }; + static ulong[] dim3917KuoInit = { 1, 1, 5, 11, 31, 27, 103, 25, 129, 207, 259, 2033, 7931, 8357, 17451, 60583, 0 }; + static ulong[] dim3918KuoInit = { 1, 1, 7, 11, 15, 47, 59, 151, 291, 669, 663, 111, 4809, 14179, 22313, 51969, 0 }; + static ulong[] dim3919KuoInit = { 1, 3, 3, 5, 1, 5, 87, 25, 179, 641, 1133, 629, 2281, 6213, 14281, 54147, 0 }; + static ulong[] dim3920KuoInit = { 1, 1, 5, 15, 29, 33, 89, 63, 331, 379, 453, 1903, 7319, 15063, 31383, 23099, 0 }; + static ulong[] dim3921KuoInit = { 1, 3, 1, 15, 23, 7, 13, 71, 367, 53, 983, 3615, 5601, 2569, 18173, 40563, 0 }; + static ulong[] dim3922KuoInit = { 1, 3, 1, 15, 23, 41, 35, 215, 401, 807, 1809, 3919, 5651, 1249, 9699, 14275, 0 }; + static ulong[] dim3923KuoInit = { 1, 1, 3, 1, 15, 55, 7, 235, 171, 911, 1351, 2863, 5735, 8577, 7489, 42047, 0 }; + static ulong[] dim3924KuoInit = { 1, 3, 1, 5, 29, 35, 11, 211, 133, 507, 1127, 2443, 7895, 10519, 13035, 26165, 0 }; + static ulong[] dim3925KuoInit = { 1, 1, 1, 9, 21, 39, 107, 55, 235, 409, 39, 1681, 2699, 3143, 847, 35635, 0 }; + static ulong[] dim3926KuoInit = { 1, 3, 7, 3, 27, 57, 79, 173, 273, 919, 1917, 4005, 1299, 14743, 24093, 64047, 0 }; + static ulong[] dim3927KuoInit = { 1, 1, 7, 11, 13, 53, 45, 195, 39, 379, 1699, 2401, 7131, 7205, 24419, 32161, 0 }; + static ulong[] dim3928KuoInit = { 1, 3, 3, 15, 31, 31, 35, 199, 421, 367, 1517, 1559, 3627, 10281, 27963, 31115, 0 }; + static ulong[] dim3929KuoInit = { 1, 1, 5, 15, 5, 59, 89, 195, 263, 853, 1043, 3699, 2543, 9893, 727, 62533, 0 }; + static ulong[] dim3930KuoInit = { 1, 1, 7, 5, 29, 49, 101, 219, 135, 643, 321, 83, 1651, 2347, 1519, 21683, 0 }; + static ulong[] dim3931KuoInit = { 1, 1, 3, 5, 11, 17, 3, 75, 255, 359, 1231, 2333, 6745, 2393, 4213, 7689, 0 }; + static ulong[] dim3932KuoInit = { 1, 1, 5, 13, 23, 27, 53, 51, 307, 87, 1409, 3555, 8139, 8597, 27357, 28489, 0 }; + static ulong[] dim3933KuoInit = { 1, 3, 3, 1, 29, 31, 53, 175, 245, 815, 461, 1681, 2255, 761, 18061, 13273, 0 }; + static ulong[] dim3934KuoInit = { 1, 3, 3, 7, 21, 41, 81, 243, 9, 973, 1411, 2327, 4575, 2659, 22903, 27605, 0 }; + static ulong[] dim3935KuoInit = { 1, 1, 3, 7, 1, 3, 91, 203, 149, 101, 1745, 1427, 4107, 11967, 13545, 19249, 0 }; + static ulong[] dim3936KuoInit = { 1, 3, 1, 1, 3, 13, 47, 13, 291, 813, 97, 2741, 2847, 2845, 6437, 1497, 0 }; + static ulong[] dim3937KuoInit = { 1, 3, 3, 1, 15, 7, 121, 173, 333, 977, 357, 3439, 8023, 8741, 205, 11447, 0 }; + static ulong[] dim3938KuoInit = { 1, 1, 3, 13, 17, 57, 79, 3, 455, 673, 1877, 2019, 4809, 10635, 19927, 38703, 0 }; + static ulong[] dim3939KuoInit = { 1, 1, 1, 15, 17, 23, 65, 157, 265, 177, 697, 3281, 409, 471, 113, 16349, 0 }; + static ulong[] dim3940KuoInit = { 1, 3, 3, 11, 19, 57, 125, 55, 343, 177, 621, 1827, 983, 2491, 10389, 49879, 0 }; + static ulong[] dim3941KuoInit = { 1, 1, 5, 1, 23, 21, 125, 13, 155, 459, 1677, 2585, 6703, 945, 5341, 54821, 0 }; + static ulong[] dim3942KuoInit = { 1, 3, 3, 1, 1, 59, 75, 137, 261, 563, 1145, 759, 2363, 12949, 16677, 43535, 0 }; + static ulong[] dim3943KuoInit = { 1, 3, 1, 1, 31, 13, 29, 59, 263, 879, 49, 1365, 4977, 6981, 32683, 25063, 0 }; + static ulong[] dim3944KuoInit = { 1, 3, 3, 11, 27, 63, 41, 101, 353, 611, 349, 1947, 6473, 3099, 28855, 27945, 0 }; + static ulong[] dim3945KuoInit = { 1, 1, 5, 3, 13, 49, 59, 5, 401, 679, 2045, 2267, 5879, 12809, 23767, 47855, 0 }; + static ulong[] dim3946KuoInit = { 1, 1, 5, 11, 17, 1, 25, 235, 67, 155, 629, 25, 2565, 12261, 28847, 19987, 0 }; + static ulong[] dim3947KuoInit = { 1, 3, 1, 1, 23, 39, 117, 147, 155, 797, 1487, 921, 1205, 9947, 14603, 21335, 0 }; + static ulong[] dim3948KuoInit = { 1, 1, 3, 13, 21, 45, 49, 175, 447, 303, 531, 2923, 3887, 16273, 5121, 38965, 0 }; + static ulong[] dim3949KuoInit = { 1, 1, 7, 11, 5, 21, 53, 201, 1, 207, 181, 1263, 833, 5435, 28363, 62913, 0 }; + static ulong[] dim3950KuoInit = { 1, 1, 3, 5, 11, 31, 1, 63, 343, 221, 23, 1315, 7639, 9983, 9167, 63489, 0 }; + static ulong[] dim3951KuoInit = { 1, 3, 3, 1, 21, 43, 7, 161, 471, 749, 1547, 1645, 1557, 9719, 14017, 43281, 0 }; + static ulong[] dim3952KuoInit = { 1, 1, 1, 7, 3, 23, 49, 29, 259, 367, 1929, 3925, 4197, 8353, 28995, 41225, 0 }; + static ulong[] dim3953KuoInit = { 1, 3, 1, 9, 5, 31, 33, 195, 33, 171, 1021, 127, 5275, 10751, 12483, 7097, 0 }; + static ulong[] dim3954KuoInit = { 1, 3, 5, 3, 19, 21, 3, 113, 217, 953, 419, 1689, 8011, 805, 20691, 39159, 0 }; + static ulong[] dim3955KuoInit = { 1, 1, 5, 1, 27, 35, 83, 173, 299, 687, 493, 3965, 5963, 1307, 16379, 34297, 0 }; + static ulong[] dim3956KuoInit = { 1, 3, 7, 3, 11, 63, 103, 199, 207, 25, 1471, 2047, 7271, 7735, 4313, 45205, 0 }; + static ulong[] dim3957KuoInit = { 1, 3, 1, 7, 9, 23, 33, 207, 213, 125, 1871, 2073, 53, 9953, 1327, 41943, 0 }; + static ulong[] dim3958KuoInit = { 1, 3, 7, 3, 19, 55, 3, 159, 147, 649, 1161, 2245, 4303, 9971, 29633, 56535, 0 }; + static ulong[] dim3959KuoInit = { 1, 3, 3, 5, 1, 1, 57, 101, 265, 859, 137, 763, 6657, 8659, 21037, 22757, 0 }; + static ulong[] dim3960KuoInit = { 1, 1, 1, 7, 11, 23, 39, 129, 49, 987, 2013, 4071, 1289, 6471, 6231, 23987, 0 }; + static ulong[] dim3961KuoInit = { 1, 3, 7, 3, 29, 7, 87, 253, 111, 55, 1719, 321, 3579, 4489, 28323, 35091, 0 }; + static ulong[] dim3962KuoInit = { 1, 1, 5, 13, 17, 1, 39, 73, 455, 31, 1215, 2683, 6193, 15725, 2737, 24927, 0 }; + static ulong[] dim3963KuoInit = { 1, 3, 1, 7, 15, 63, 69, 125, 127, 337, 129, 2667, 4723, 8489, 6129, 14973, 0 }; + static ulong[] dim3964KuoInit = { 1, 3, 1, 9, 21, 37, 109, 91, 499, 767, 1095, 2731, 6129, 2167, 21311, 43503, 0 }; + static ulong[] dim3965KuoInit = { 1, 3, 7, 7, 29, 11, 87, 101, 19, 699, 1601, 2341, 3623, 1799, 2253, 40705, 0 }; + static ulong[] dim3966KuoInit = { 1, 1, 7, 1, 27, 25, 111, 91, 49, 3, 13, 3851, 3735, 13387, 4501, 64303, 0 }; + static ulong[] dim3967KuoInit = { 1, 1, 3, 13, 21, 63, 7, 65, 241, 925, 705, 3745, 827, 7227, 1869, 60375, 0 }; + static ulong[] dim3968KuoInit = { 1, 3, 1, 7, 31, 45, 5, 51, 45, 595, 1069, 3139, 5843, 2581, 22573, 53297, 0 }; + static ulong[] dim3969KuoInit = { 1, 1, 5, 3, 5, 9, 89, 91, 349, 241, 369, 279, 617, 4479, 12761, 14473, 0 }; + static ulong[] dim3970KuoInit = { 1, 3, 1, 1, 13, 45, 91, 29, 219, 341, 1831, 1993, 3661, 1855, 7243, 3477, 0 }; + static ulong[] dim3971KuoInit = { 1, 3, 3, 13, 15, 17, 27, 123, 223, 127, 111, 2375, 3919, 7569, 4419, 24957, 0 }; + static ulong[] dim3972KuoInit = { 1, 3, 7, 1, 17, 1, 49, 111, 103, 67, 75, 3109, 1783, 13291, 5409, 33123, 0 }; + static ulong[] dim3973KuoInit = { 1, 3, 5, 3, 1, 51, 107, 89, 233, 51, 745, 2005, 5485, 7537, 13353, 34579, 0 }; + static ulong[] dim3974KuoInit = { 1, 1, 7, 3, 9, 3, 25, 95, 413, 461, 1597, 767, 3183, 10285, 10579, 26581, 0 }; + static ulong[] dim3975KuoInit = { 1, 1, 5, 7, 25, 3, 27, 93, 433, 59, 701, 1825, 6375, 6477, 6743, 42101, 0 }; + static ulong[] dim3976KuoInit = { 1, 3, 1, 3, 19, 45, 95, 207, 267, 623, 1523, 1541, 3955, 4681, 2365, 16661, 0 }; + static ulong[] dim3977KuoInit = { 1, 1, 3, 13, 19, 35, 83, 151, 159, 825, 205, 2215, 4767, 797, 12821, 14951, 0 }; + static ulong[] dim3978KuoInit = { 1, 1, 5, 13, 15, 5, 99, 141, 21, 537, 657, 2055, 1571, 12725, 4227, 21061, 0 }; + static ulong[] dim3979KuoInit = { 1, 1, 1, 13, 1, 39, 85, 229, 9, 721, 1117, 519, 1763, 13211, 32533, 41393, 0 }; + static ulong[] dim3980KuoInit = { 1, 1, 3, 15, 23, 11, 125, 59, 439, 887, 1273, 3707, 7737, 4115, 7013, 47453, 0 }; + static ulong[] dim3981KuoInit = { 1, 1, 1, 5, 9, 25, 53, 203, 9, 189, 471, 637, 5983, 1693, 8425, 52181, 0 }; + static ulong[] dim3982KuoInit = { 1, 1, 1, 1, 29, 61, 33, 87, 153, 625, 539, 3595, 3161, 3929, 22825, 50113, 0 }; + static ulong[] dim3983KuoInit = { 1, 3, 7, 7, 1, 31, 105, 169, 475, 631, 1511, 3687, 5321, 3859, 19329, 9571, 0 }; + static ulong[] dim3984KuoInit = { 1, 3, 7, 1, 9, 13, 111, 79, 245, 351, 69, 59, 5561, 4713, 22789, 14929, 0 }; + static ulong[] dim3985KuoInit = { 1, 1, 3, 1, 1, 55, 87, 147, 37, 587, 479, 3175, 5437, 12267, 7057, 57899, 0 }; + static ulong[] dim3986KuoInit = { 1, 1, 5, 11, 15, 55, 87, 53, 359, 491, 343, 621, 1055, 8697, 28993, 20473, 0 }; + static ulong[] dim3987KuoInit = { 1, 3, 3, 15, 13, 11, 63, 179, 293, 639, 809, 1365, 7043, 13269, 5423, 36465, 0 }; + static ulong[] dim3988KuoInit = { 1, 1, 5, 11, 31, 49, 27, 71, 187, 377, 283, 2407, 2987, 8565, 15159, 44501, 0 }; + static ulong[] dim3989KuoInit = { 1, 3, 1, 1, 27, 5, 79, 211, 315, 645, 951, 4025, 1647, 2893, 23829, 23941, 0 }; + static ulong[] dim3990KuoInit = { 1, 1, 7, 15, 15, 29, 81, 133, 345, 573, 1605, 2693, 5293, 13579, 21793, 30981, 0 }; + static ulong[] dim3991KuoInit = { 1, 3, 7, 5, 31, 19, 109, 141, 389, 473, 1359, 1695, 6761, 3701, 27583, 47907, 0 }; + static ulong[] dim3992KuoInit = { 1, 1, 3, 5, 7, 43, 51, 139, 81, 111, 417, 2627, 2297, 12493, 24401, 42525, 0 }; + static ulong[] dim3993KuoInit = { 1, 3, 7, 3, 21, 9, 65, 141, 119, 971, 589, 2635, 6365, 1925, 15853, 47123, 0 }; + static ulong[] dim3994KuoInit = { 1, 1, 3, 1, 25, 15, 93, 151, 443, 325, 457, 3779, 7669, 2063, 20005, 6513, 0 }; + static ulong[] dim3995KuoInit = { 1, 1, 5, 11, 7, 13, 127, 55, 183, 663, 437, 3475, 6391, 8423, 8473, 41971, 0 }; + static ulong[] dim3996KuoInit = { 1, 1, 5, 9, 7, 15, 113, 225, 259, 85, 945, 645, 5129, 3657, 931, 30429, 0 }; + static ulong[] dim3997KuoInit = { 1, 3, 3, 15, 9, 63, 23, 117, 205, 295, 1325, 1349, 5521, 9399, 7907, 26373, 0 }; + static ulong[] dim3998KuoInit = { 1, 3, 7, 5, 17, 23, 47, 75, 97, 35, 1363, 793, 2811, 3491, 18173, 8353, 0 }; + static ulong[] dim3999KuoInit = { 1, 3, 3, 11, 25, 27, 107, 9, 331, 1017, 615, 1123, 1303, 5705, 14013, 39207, 0 }; + static ulong[] dim4000KuoInit = { 1, 3, 1, 7, 3, 17, 101, 17, 461, 781, 345, 2687, 5867, 1367, 17245, 18929, 0 }; + static ulong[] dim4001KuoInit = { 1, 1, 1, 13, 3, 53, 55, 37, 257, 101, 195, 1193, 5419, 4243, 6079, 32461, 0 }; + static ulong[] dim4002KuoInit = { 1, 1, 1, 13, 29, 21, 51, 123, 145, 105, 639, 2389, 6985, 2519, 12351, 45859, 0 }; + static ulong[] dim4003KuoInit = { 1, 1, 3, 13, 31, 17, 75, 121, 11, 945, 1917, 601, 3765, 14215, 19075, 26317, 0 }; + static ulong[] dim4004KuoInit = { 1, 3, 7, 13, 21, 3, 57, 17, 97, 567, 839, 135, 2441, 4613, 10511, 21927, 0 }; + static ulong[] dim4005KuoInit = { 1, 3, 5, 1, 21, 27, 1, 109, 381, 241, 1701, 1255, 1469, 8415, 18789, 1769, 0 }; + static ulong[] dim4006KuoInit = { 1, 3, 1, 11, 11, 45, 77, 209, 55, 371, 1323, 2899, 7387, 10317, 32695, 52199, 0 }; + static ulong[] dim4007KuoInit = { 1, 3, 5, 9, 15, 59, 45, 97, 369, 247, 1621, 2037, 4569, 16043, 2225, 39055, 0 }; + static ulong[] dim4008KuoInit = { 1, 1, 7, 1, 21, 43, 85, 195, 99, 85, 1759, 547, 4371, 14467, 17551, 52185, 0 }; + static ulong[] dim4009KuoInit = { 1, 1, 3, 1, 17, 53, 79, 203, 49, 289, 1547, 1173, 1445, 11593, 29927, 63479, 0 }; + static ulong[] dim4010KuoInit = { 1, 3, 3, 5, 3, 61, 31, 71, 321, 923, 1337, 3465, 3305, 10841, 31921, 3057, 0 }; + static ulong[] dim4011KuoInit = { 1, 3, 5, 11, 31, 1, 39, 201, 57, 913, 1953, 193, 4185, 5895, 27027, 10889, 0 }; + static ulong[] dim4012KuoInit = { 1, 3, 1, 9, 7, 9, 89, 145, 445, 643, 279, 1983, 491, 11825, 1857, 11201, 0 }; + static ulong[] dim4013KuoInit = { 1, 3, 1, 5, 9, 39, 21, 245, 403, 393, 779, 1419, 967, 14309, 6789, 54477, 0 }; + static ulong[] dim4014KuoInit = { 1, 3, 5, 7, 31, 21, 65, 211, 447, 263, 665, 3311, 405, 1775, 31121, 54025, 0 }; + static ulong[] dim4015KuoInit = { 1, 3, 5, 11, 13, 9, 95, 243, 139, 733, 813, 3855, 2731, 11651, 2175, 9655, 0 }; + static ulong[] dim4016KuoInit = { 1, 1, 1, 1, 21, 5, 5, 241, 415, 241, 1223, 3237, 2265, 3761, 26883, 37875, 0 }; + static ulong[] dim4017KuoInit = { 1, 1, 1, 13, 25, 45, 97, 73, 353, 393, 1217, 563, 5813, 2791, 16477, 4401, 0 }; + static ulong[] dim4018KuoInit = { 1, 3, 5, 13, 17, 61, 1, 247, 439, 1013, 501, 881, 353, 4689, 18733, 46731, 0 }; + static ulong[] dim4019KuoInit = { 1, 3, 1, 11, 11, 29, 87, 53, 461, 751, 1503, 2851, 2891, 15231, 1513, 12573, 0 }; + static ulong[] dim4020KuoInit = { 1, 3, 1, 3, 1, 13, 95, 239, 151, 159, 55, 1203, 1331, 10429, 19159, 18431, 0 }; + static ulong[] dim4021KuoInit = { 1, 3, 3, 15, 11, 43, 81, 133, 449, 523, 667, 2759, 6829, 15129, 19829, 31745, 0 }; + static ulong[] dim4022KuoInit = { 1, 1, 1, 13, 25, 43, 115, 171, 475, 553, 1615, 1421, 2363, 13091, 27505, 21247, 0 }; + static ulong[] dim4023KuoInit = { 1, 3, 5, 13, 1, 23, 15, 25, 205, 797, 1013, 1903, 1595, 16373, 29983, 23009, 0 }; + static ulong[] dim4024KuoInit = { 1, 1, 1, 11, 3, 27, 79, 179, 147, 905, 1893, 2459, 3063, 7447, 16293, 14331, 0 }; + static ulong[] dim4025KuoInit = { 1, 3, 7, 1, 19, 49, 41, 19, 97, 559, 1213, 847, 3715, 13963, 20273, 25565, 0 }; + static ulong[] dim4026KuoInit = { 1, 3, 7, 3, 27, 21, 75, 1, 157, 715, 41, 2383, 4609, 9875, 21509, 57199, 0 }; + static ulong[] dim4027KuoInit = { 1, 1, 1, 9, 5, 51, 93, 115, 495, 687, 1805, 1369, 1525, 15841, 8897, 21023, 0 }; + static ulong[] dim4028KuoInit = { 1, 1, 3, 11, 21, 41, 93, 107, 391, 567, 223, 2331, 6009, 9405, 13137, 54727, 0 }; + static ulong[] dim4029KuoInit = { 1, 3, 1, 15, 5, 59, 119, 165, 485, 765, 243, 2589, 4631, 4045, 26867, 55329, 0 }; + static ulong[] dim4030KuoInit = { 1, 1, 7, 9, 17, 45, 35, 219, 137, 315, 293, 1137, 6675, 10693, 17455, 35603, 0 }; + static ulong[] dim4031KuoInit = { 1, 3, 7, 13, 11, 43, 65, 205, 351, 155, 1371, 3069, 1345, 859, 21385, 25923, 0 }; + static ulong[] dim4032KuoInit = { 1, 1, 3, 3, 11, 21, 39, 195, 349, 333, 687, 1155, 1491, 10453, 17615, 64801, 0 }; + static ulong[] dim4033KuoInit = { 1, 3, 1, 9, 17, 45, 39, 137, 25, 105, 441, 2437, 7715, 8501, 3999, 15913, 0 }; + static ulong[] dim4034KuoInit = { 1, 1, 1, 9, 31, 21, 93, 31, 63, 635, 331, 149, 1683, 6183, 19333, 34947, 0 }; + static ulong[] dim4035KuoInit = { 1, 3, 3, 5, 23, 11, 15, 239, 365, 983, 389, 945, 1765, 6417, 4471, 41431, 0 }; + static ulong[] dim4036KuoInit = { 1, 3, 1, 5, 5, 49, 49, 27, 417, 605, 1495, 4021, 1775, 3691, 21803, 60999, 0 }; + static ulong[] dim4037KuoInit = { 1, 3, 3, 5, 23, 21, 33, 205, 481, 105, 359, 1407, 4007, 35, 10789, 27721, 0 }; + static ulong[] dim4038KuoInit = { 1, 1, 5, 3, 5, 33, 51, 61, 29, 337, 1523, 955, 4923, 1977, 16505, 21249, 0 }; + static ulong[] dim4039KuoInit = { 1, 3, 1, 11, 17, 19, 39, 7, 443, 557, 611, 4037, 5873, 15161, 449, 41747, 0 }; + static ulong[] dim4040KuoInit = { 1, 1, 7, 11, 5, 53, 91, 227, 217, 689, 7, 775, 8139, 10997, 29539, 60185, 0 }; + static ulong[] dim4041KuoInit = { 1, 1, 5, 1, 7, 59, 117, 101, 145, 779, 1359, 3375, 2493, 13075, 11475, 49507, 0 }; + static ulong[] dim4042KuoInit = { 1, 1, 1, 3, 13, 31, 39, 219, 181, 203, 19, 659, 533, 2541, 7285, 29353, 0 }; + static ulong[] dim4043KuoInit = { 1, 3, 3, 1, 29, 33, 1, 125, 283, 61, 303, 1613, 4309, 1891, 7107, 25977, 0 }; + static ulong[] dim4044KuoInit = { 1, 3, 5, 9, 21, 59, 41, 63, 123, 715, 893, 3509, 6785, 11009, 17749, 18349, 0 }; + static ulong[] dim4045KuoInit = { 1, 3, 1, 1, 25, 23, 15, 1, 147, 709, 957, 1101, 2733, 14069, 18905, 12467, 0 }; + static ulong[] dim4046KuoInit = { 1, 3, 3, 13, 9, 63, 109, 39, 123, 919, 427, 435, 5241, 14169, 31179, 15887, 0 }; + static ulong[] dim4047KuoInit = { 1, 1, 7, 15, 13, 25, 29, 187, 433, 633, 1203, 113, 4577, 13349, 18407, 62825, 0 }; + static ulong[] dim4048KuoInit = { 1, 1, 5, 1, 15, 33, 53, 209, 415, 711, 1543, 1529, 4991, 9545, 19655, 40427, 0 }; + static ulong[] dim4049KuoInit = { 1, 1, 5, 5, 23, 59, 27, 23, 7, 841, 1715, 43, 4987, 2073, 13765, 36105, 0 }; + static ulong[] dim4050KuoInit = { 1, 3, 3, 15, 31, 5, 51, 183, 319, 443, 621, 349, 2835, 10847, 19059, 51689, 0 }; + static ulong[] dim4051KuoInit = { 1, 3, 1, 9, 5, 3, 21, 81, 357, 609, 2019, 2613, 333, 5699, 2485, 52105, 0 }; + static ulong[] dim4052KuoInit = { 1, 1, 3, 15, 3, 11, 73, 121, 263, 833, 65, 347, 4821, 4631, 29929, 42157, 0 }; + static ulong[] dim4053KuoInit = { 1, 1, 7, 3, 1, 63, 7, 191, 47, 405, 43, 1499, 5539, 12607, 26095, 20759, 0 }; + static ulong[] dim4054KuoInit = { 1, 3, 3, 5, 15, 21, 109, 3, 15, 57, 1669, 4033, 5251, 4465, 28057, 64943, 0 }; + static ulong[] dim4055KuoInit = { 1, 1, 3, 9, 7, 61, 31, 17, 331, 671, 1955, 1035, 7183, 6559, 19299, 10225, 0 }; + static ulong[] dim4056KuoInit = { 1, 1, 5, 11, 31, 15, 97, 3, 361, 541, 323, 1463, 6867, 12717, 9593, 15407, 0 }; + static ulong[] dim4057KuoInit = { 1, 1, 1, 5, 29, 39, 71, 27, 305, 589, 1441, 2349, 185, 447, 24223, 53591, 0 }; + static ulong[] dim4058KuoInit = { 1, 1, 7, 15, 15, 59, 81, 77, 371, 891, 31, 457, 3073, 8427, 8225, 53157, 0 }; + static ulong[] dim4059KuoInit = { 1, 3, 3, 11, 23, 61, 71, 85, 39, 77, 1583, 933, 6147, 2271, 24761, 15835, 0 }; + static ulong[] dim4060KuoInit = { 1, 3, 7, 11, 25, 55, 41, 131, 275, 603, 43, 761, 5071, 14149, 4001, 6545, 0 }; + static ulong[] dim4061KuoInit = { 1, 1, 5, 3, 5, 1, 25, 217, 445, 197, 863, 3557, 585, 13599, 12329, 17331, 0 }; + static ulong[] dim4062KuoInit = { 1, 3, 3, 13, 9, 21, 21, 89, 121, 1017, 1559, 83, 5225, 13247, 12003, 10049, 0 }; + static ulong[] dim4063KuoInit = { 1, 3, 3, 9, 31, 15, 71, 45, 161, 895, 1431, 1277, 2547, 1943, 17631, 59133, 0 }; + static ulong[] dim4064KuoInit = { 1, 1, 1, 9, 11, 17, 29, 157, 355, 89, 401, 983, 8175, 11687, 20087, 7541, 0 }; + static ulong[] dim4065KuoInit = { 1, 3, 7, 5, 15, 45, 23, 141, 365, 593, 1137, 873, 2903, 8861, 25805, 22601, 0 }; + static ulong[] dim4066KuoInit = { 1, 1, 3, 11, 27, 17, 97, 3, 359, 531, 329, 437, 3483, 8653, 15953, 48333, 0 }; + static ulong[] dim4067KuoInit = { 1, 3, 5, 3, 9, 43, 79, 223, 149, 177, 1075, 545, 7235, 4271, 20153, 65481, 0 }; + static ulong[] dim4068KuoInit = { 1, 3, 1, 13, 5, 55, 29, 51, 497, 677, 167, 391, 1371, 8753, 23771, 48167, 0 }; + static ulong[] dim4069KuoInit = { 1, 1, 5, 3, 7, 17, 7, 227, 21, 521, 221, 3529, 5641, 4139, 14839, 49863, 0 }; + static ulong[] dim4070KuoInit = { 1, 1, 3, 9, 7, 41, 17, 151, 401, 407, 689, 507, 6683, 12515, 26895, 60863, 0 }; + static ulong[] dim4071KuoInit = { 1, 1, 3, 7, 3, 53, 27, 185, 119, 891, 2025, 607, 6961, 4263, 7795, 34157, 0 }; + static ulong[] dim4072KuoInit = { 1, 1, 3, 3, 25, 19, 15, 131, 323, 27, 1749, 2429, 2207, 9207, 18333, 25857, 0 }; + static ulong[] dim4073KuoInit = { 1, 1, 5, 5, 21, 57, 61, 93, 305, 497, 1465, 3639, 7695, 3903, 31201, 45699, 0 }; + static ulong[] dim4074KuoInit = { 1, 1, 5, 11, 25, 35, 93, 55, 415, 397, 1375, 809, 6205, 9761, 23129, 28757, 0 }; + static ulong[] dim4075KuoInit = { 1, 3, 5, 9, 13, 21, 1, 167, 65, 689, 525, 2839, 4069, 10123, 24403, 4121, 0 }; + static ulong[] dim4076KuoInit = { 1, 1, 3, 13, 11, 21, 67, 159, 131, 579, 1397, 251, 3933, 14737, 22047, 4173, 0 }; + static ulong[] dim4077KuoInit = { 1, 1, 3, 13, 9, 47, 71, 81, 141, 607, 1879, 3057, 6493, 1177, 27261, 59313, 0 }; + static ulong[] dim4078KuoInit = { 1, 1, 3, 11, 25, 45, 35, 193, 251, 223, 1725, 1533, 5799, 12417, 29765, 50203, 0 }; + static ulong[] dim4079KuoInit = { 1, 3, 1, 13, 27, 1, 41, 171, 293, 65, 607, 2843, 2955, 8783, 21249, 41695, 0 }; + static ulong[] dim4080KuoInit = { 1, 3, 1, 3, 3, 57, 39, 31, 507, 687, 2009, 2881, 4595, 9275, 9773, 31489, 0 }; + static ulong[] dim4081KuoInit = { 1, 3, 1, 7, 17, 11, 47, 233, 193, 395, 1879, 1983, 4811, 1221, 27279, 52089, 0 }; + static ulong[] dim4082KuoInit = { 1, 3, 1, 1, 13, 57, 51, 253, 381, 779, 897, 2893, 4373, 6599, 7533, 30359, 0 }; + static ulong[] dim4083KuoInit = { 1, 3, 3, 3, 5, 35, 1, 117, 81, 35, 2005, 2133, 4493, 9773, 24265, 45945, 0 }; + static ulong[] dim4084KuoInit = { 1, 1, 3, 1, 21, 57, 67, 157, 111, 857, 899, 2081, 2097, 16005, 20535, 2955, 0 }; + static ulong[] dim4085KuoInit = { 1, 1, 1, 11, 19, 45, 109, 83, 375, 1003, 79, 3801, 3433, 4429, 32385, 31551, 0 }; + static ulong[] dim4086KuoInit = { 1, 1, 3, 3, 1, 15, 115, 47, 511, 533, 1711, 2433, 3027, 13511, 23743, 23805, 0 }; + static ulong[] dim4087KuoInit = { 1, 1, 7, 15, 31, 11, 107, 215, 431, 935, 1033, 213, 7913, 557, 22063, 7947, 0 }; + static ulong[] dim4088KuoInit = { 1, 3, 3, 1, 23, 25, 109, 183, 445, 477, 1297, 2269, 3593, 5657, 995, 19821, 0 }; + static ulong[] dim4089KuoInit = { 1, 3, 3, 9, 5, 19, 93, 137, 155, 5, 1905, 1551, 6321, 11213, 6305, 5063, 0 }; + static ulong[] dim4090KuoInit = { 1, 1, 3, 15, 9, 5, 123, 203, 379, 159, 1871, 2377, 665, 4877, 17663, 60371, 0 }; + static ulong[] dim4091KuoInit = { 1, 1, 1, 15, 3, 7, 109, 15, 109, 117, 79, 3061, 667, 6963, 30565, 25745, 0 }; + static ulong[] dim4092KuoInit = { 1, 3, 5, 1, 15, 7, 105, 139, 29, 923, 1449, 1349, 2951, 7443, 10243, 51739, 0 }; + static ulong[] dim4093KuoInit = { 1, 1, 7, 5, 5, 47, 91, 77, 437, 483, 1309, 1559, 6491, 13469, 9461, 40993, 0 }; + static ulong[] dim4094KuoInit = { 1, 1, 7, 5, 5, 35, 57, 139, 207, 267, 707, 1887, 3447, 3959, 8169, 14511, 0 }; + static ulong[] dim4095KuoInit = { 1, 1, 7, 15, 23, 9, 57, 183, 437, 595, 1317, 3847, 2515, 13415, 26651, 41885, 0 }; + static ulong[] dim4096KuoInit = { 1, 3, 3, 3, 21, 49, 71, 129, 15, 183, 315, 57, 1739, 15119, 15293, 8489, 0 }; + static ulong[] dim4097KuoInit = { 1, 3, 1, 3, 7, 63, 91, 241, 355, 921, 1827, 1, 5713, 3233, 21901, 48009, 0 }; + static ulong[] dim4098KuoInit = { 1, 3, 7, 13, 31, 9, 103, 209, 289, 575, 1543, 653, 7189, 1843, 5205, 27325, 0 }; + static ulong[] dim4099KuoInit = { 1, 1, 7, 7, 15, 63, 7, 71, 95, 861, 857, 701, 6843, 10609, 11177, 21043, 0 }; + static ulong[] dim4100KuoInit = { 1, 3, 3, 9, 25, 31, 85, 255, 247, 773, 1503, 2379, 7231, 6013, 16193, 33855, 0 }; + static ulong[] dim4101KuoInit = { 1, 1, 3, 11, 5, 27, 125, 159, 381, 665, 1059, 2527, 1423, 3055, 8363, 57053, 0 }; + static ulong[] dim4102KuoInit = { 1, 1, 5, 3, 25, 57, 107, 89, 499, 761, 909, 1487, 1569, 9353, 27477, 39373, 0 }; + static ulong[] dim4103KuoInit = { 1, 3, 5, 9, 1, 57, 81, 27, 41, 371, 1111, 2437, 3669, 6033, 28601, 38985, 0 }; + static ulong[] dim4104KuoInit = { 1, 3, 5, 5, 25, 63, 85, 171, 187, 387, 1971, 579, 2779, 7667, 25423, 61005, 0 }; + static ulong[] dim4105KuoInit = { 1, 1, 5, 1, 25, 37, 87, 93, 387, 95, 65, 3345, 6581, 13325, 9683, 25399, 0 }; + static ulong[] dim4106KuoInit = { 1, 3, 5, 11, 9, 33, 81, 69, 483, 79, 123, 3241, 2599, 7545, 17775, 34933, 0 }; + static ulong[] dim4107KuoInit = { 1, 1, 7, 1, 9, 41, 27, 191, 385, 439, 347, 1279, 4491, 8883, 31599, 27167, 0 }; + static ulong[] dim4108KuoInit = { 1, 3, 5, 13, 1, 57, 51, 81, 161, 15, 7, 3695, 1777, 14947, 27853, 22383, 0 }; + static ulong[] dim4109KuoInit = { 1, 1, 5, 5, 15, 21, 79, 159, 85, 677, 401, 665, 3547, 13659, 18035, 38181, 0 }; + static ulong[] dim4110KuoInit = { 1, 3, 3, 15, 11, 55, 29, 219, 45, 683, 673, 2653, 6841, 7809, 8969, 17773, 0 }; + static ulong[] dim4111KuoInit = { 1, 3, 5, 13, 25, 61, 19, 67, 469, 265, 1835, 2733, 4537, 8113, 27089, 59191, 0 }; + static ulong[] dim4112KuoInit = { 1, 1, 5, 11, 9, 37, 99, 31, 229, 635, 1615, 3073, 2161, 13917, 22197, 4331, 0 }; + static ulong[] dim4113KuoInit = { 1, 3, 1, 11, 13, 59, 119, 65, 55, 113, 189, 57, 903, 11119, 3835, 30549, 0 }; + static ulong[] dim4114KuoInit = { 1, 1, 1, 5, 23, 25, 29, 167, 199, 669, 691, 3047, 7433, 15043, 22471, 39473, 0 }; + static ulong[] dim4115KuoInit = { 1, 1, 5, 13, 13, 15, 121, 127, 343, 293, 511, 1873, 4535, 6395, 10161, 52113, 0 }; + static ulong[] dim4116KuoInit = { 1, 3, 1, 11, 13, 7, 95, 151, 187, 221, 843, 2433, 5083, 15319, 5763, 46801, 0 }; + static ulong[] dim4117KuoInit = { 1, 3, 5, 3, 3, 57, 109, 65, 203, 583, 209, 2395, 5615, 14949, 10819, 5109, 0 }; + static ulong[] dim4118KuoInit = { 1, 3, 7, 15, 23, 41, 65, 17, 351, 89, 1451, 219, 5863, 15197, 22741, 16599, 0 }; + static ulong[] dim4119KuoInit = { 1, 1, 3, 13, 23, 49, 51, 9, 365, 595, 1619, 933, 2231, 15219, 105, 1657, 0 }; + static ulong[] dim4120KuoInit = { 1, 3, 5, 7, 27, 33, 39, 243, 257, 299, 479, 1999, 1781, 9267, 3631, 21449, 0 }; + static ulong[] dim4121KuoInit = { 1, 3, 1, 3, 13, 1, 83, 9, 373, 99, 1873, 3959, 1009, 31, 29329, 1489, 0 }; + static ulong[] dim4122KuoInit = { 1, 1, 7, 3, 15, 21, 99, 25, 265, 461, 467, 2475, 8149, 5685, 22679, 9787, 0 }; + static ulong[] dim4123KuoInit = { 1, 1, 3, 1, 5, 43, 109, 55, 451, 11, 1631, 999, 1181, 3377, 4807, 14675, 0 }; + static ulong[] dim4124KuoInit = { 1, 3, 7, 11, 5, 43, 27, 253, 73, 697, 81, 3739, 4267, 3801, 2913, 33117, 0 }; + static ulong[] dim4125KuoInit = { 1, 3, 1, 5, 11, 55, 97, 3, 3, 949, 155, 3575, 941, 3727, 4047, 26071, 0 }; + static ulong[] dim4126KuoInit = { 1, 1, 5, 3, 17, 35, 3, 9, 185, 1, 421, 2831, 957, 4505, 6421, 16279, 0 }; + static ulong[] dim4127KuoInit = { 1, 1, 3, 9, 21, 43, 115, 183, 231, 13, 1711, 3403, 5447, 2761, 27591, 431, 0 }; + static ulong[] dim4128KuoInit = { 1, 3, 3, 15, 1, 25, 111, 157, 429, 981, 1117, 2767, 3107, 2203, 15335, 62597, 0 }; + static ulong[] dim4129KuoInit = { 1, 1, 1, 9, 5, 11, 59, 163, 37, 101, 63, 2829, 5583, 12695, 21683, 62563, 0 }; + static ulong[] dim4130KuoInit = { 1, 3, 3, 15, 7, 29, 39, 241, 333, 321, 931, 3811, 1981, 229, 18877, 6597, 0 }; + static ulong[] dim4131KuoInit = { 1, 3, 3, 13, 31, 3, 83, 21, 253, 117, 757, 2335, 291, 3723, 24961, 41985, 0 }; + static ulong[] dim4132KuoInit = { 1, 1, 1, 1, 23, 37, 71, 227, 211, 671, 757, 597, 4015, 7297, 26275, 46051, 0 }; + static ulong[] dim4133KuoInit = { 1, 3, 3, 11, 9, 15, 23, 143, 207, 235, 1215, 1401, 7487, 13397, 30443, 43735, 0 }; + static ulong[] dim4134KuoInit = { 1, 1, 7, 7, 23, 5, 57, 169, 3, 609, 1077, 109, 6029, 14891, 6641, 26525, 0 }; + static ulong[] dim4135KuoInit = { 1, 3, 7, 13, 7, 45, 99, 187, 43, 751, 1189, 1787, 4903, 10605, 15799, 61769, 0 }; + static ulong[] dim4136KuoInit = { 1, 3, 1, 5, 31, 51, 95, 127, 149, 557, 1027, 3377, 1461, 15217, 16955, 27339, 0 }; + static ulong[] dim4137KuoInit = { 1, 3, 5, 11, 31, 29, 11, 143, 47, 709, 1413, 343, 5421, 3567, 5383, 62347, 0 }; + static ulong[] dim4138KuoInit = { 1, 3, 3, 11, 13, 3, 33, 19, 79, 751, 1979, 785, 6339, 4133, 31633, 1963, 0 }; + static ulong[] dim4139KuoInit = { 1, 3, 3, 9, 15, 21, 117, 13, 105, 519, 1575, 3041, 5465, 7167, 17443, 15781, 0 }; + static ulong[] dim4140KuoInit = { 1, 1, 1, 7, 29, 25, 51, 237, 11, 431, 1597, 751, 4115, 12345, 9451, 1417, 0 }; + static ulong[] dim4141KuoInit = { 1, 3, 5, 13, 1, 43, 61, 141, 279, 541, 149, 3783, 1503, 7597, 25469, 21143, 0 }; + static ulong[] dim4142KuoInit = { 1, 1, 3, 13, 23, 13, 21, 53, 49, 491, 135, 3079, 2593, 10611, 24467, 18627, 0 }; + static ulong[] dim4143KuoInit = { 1, 3, 3, 5, 19, 31, 59, 139, 137, 839, 799, 1081, 251, 2685, 15993, 15909, 0 }; + static ulong[] dim4144KuoInit = { 1, 3, 5, 1, 3, 1, 33, 131, 259, 137, 651, 3879, 3089, 6957, 24589, 8945, 0 }; + static ulong[] dim4145KuoInit = { 1, 1, 3, 1, 23, 13, 127, 255, 325, 451, 275, 1425, 3649, 8149, 28913, 16481, 0 }; + static ulong[] dim4146KuoInit = { 1, 1, 5, 3, 19, 35, 55, 183, 383, 419, 551, 961, 5413, 3779, 10935, 30523, 0 }; + static ulong[] dim4147KuoInit = { 1, 1, 7, 3, 19, 35, 125, 165, 21, 23, 1119, 4061, 8057, 5129, 6035, 29907, 0 }; + static ulong[] dim4148KuoInit = { 1, 1, 1, 11, 31, 5, 9, 165, 189, 117, 1371, 3171, 3723, 9051, 11071, 1669, 0 }; + static ulong[] dim4149KuoInit = { 1, 1, 1, 7, 23, 37, 61, 241, 253, 79, 241, 2629, 6791, 2305, 17085, 17163, 0 }; + static ulong[] dim4150KuoInit = { 1, 1, 7, 11, 25, 49, 109, 139, 271, 325, 1673, 1827, 319, 10729, 15739, 19971, 0 }; + static ulong[] dim4151KuoInit = { 1, 3, 3, 9, 15, 3, 21, 153, 229, 781, 2029, 3169, 2191, 7861, 26817, 44695, 0 }; + static ulong[] dim4152KuoInit = { 1, 1, 1, 11, 9, 45, 93, 117, 361, 319, 1747, 2379, 259, 15451, 2431, 29633, 0 }; + static ulong[] dim4153KuoInit = { 1, 1, 3, 1, 21, 3, 87, 157, 389, 373, 1235, 1347, 6573, 3447, 1569, 42287, 0 }; + static ulong[] dim4154KuoInit = { 1, 3, 5, 1, 3, 35, 27, 49, 283, 281, 733, 1557, 3589, 4047, 4589, 981, 0 }; + static ulong[] dim4155KuoInit = { 1, 3, 5, 5, 11, 15, 69, 209, 319, 601, 1559, 35, 185, 8659, 26943, 10885, 0 }; + static ulong[] dim4156KuoInit = { 1, 3, 3, 15, 15, 25, 105, 241, 153, 813, 481, 2269, 5677, 11121, 21781, 29427, 0 }; + static ulong[] dim4157KuoInit = { 1, 1, 1, 13, 1, 41, 123, 235, 487, 339, 1815, 241, 5673, 9319, 6031, 3785, 0 }; + static ulong[] dim4158KuoInit = { 1, 1, 3, 9, 3, 15, 111, 207, 281, 7, 1089, 709, 8001, 14277, 27351, 21503, 0 }; + static ulong[] dim4159KuoInit = { 1, 3, 1, 11, 29, 11, 69, 111, 471, 549, 1731, 115, 1067, 8417, 19377, 18729, 0 }; + static ulong[] dim4160KuoInit = { 1, 1, 7, 1, 29, 11, 31, 251, 437, 217, 1815, 1229, 5735, 11813, 20831, 27237, 0 }; + static ulong[] dim4161KuoInit = { 1, 1, 3, 9, 25, 63, 115, 45, 71, 359, 1313, 543, 1837, 5359, 13635, 47057, 0 }; + static ulong[] dim4162KuoInit = { 1, 3, 1, 13, 5, 21, 73, 47, 13, 553, 471, 465, 591, 1943, 12549, 20245, 0 }; + static ulong[] dim4163KuoInit = { 1, 3, 5, 1, 5, 35, 1, 5, 403, 797, 987, 1227, 2847, 931, 7417, 7551, 0 }; + static ulong[] dim4164KuoInit = { 1, 3, 3, 11, 15, 13, 7, 201, 145, 475, 1557, 2871, 3161, 3489, 7893, 1745, 0 }; + static ulong[] dim4165KuoInit = { 1, 1, 1, 7, 15, 27, 9, 129, 83, 31, 1351, 647, 6217, 15201, 21019, 39925, 0 }; + static ulong[] dim4166KuoInit = { 1, 1, 7, 3, 19, 39, 99, 253, 491, 455, 405, 131, 4755, 8395, 26647, 65287, 0 }; + static ulong[] dim4167KuoInit = { 1, 3, 5, 13, 13, 13, 15, 49, 397, 237, 1491, 1881, 4233, 15801, 25591, 47061, 0 }; + static ulong[] dim4168KuoInit = { 1, 1, 1, 15, 11, 11, 11, 161, 225, 257, 231, 3303, 5145, 5217, 21527, 50231, 0 }; + static ulong[] dim4169KuoInit = { 1, 3, 1, 13, 21, 51, 11, 161, 55, 945, 1835, 1493, 5069, 9443, 31181, 2157, 0 }; + static ulong[] dim4170KuoInit = { 1, 3, 1, 15, 29, 45, 75, 141, 475, 43, 219, 2689, 7579, 523, 27125, 48615, 0 }; + static ulong[] dim4171KuoInit = { 1, 3, 7, 13, 5, 7, 125, 13, 73, 231, 1397, 295, 3197, 4023, 2167, 42101, 0 }; + static ulong[] dim4172KuoInit = { 1, 1, 5, 11, 5, 15, 99, 241, 1, 49, 1635, 2467, 4939, 9411, 145, 62117, 0 }; + static ulong[] dim4173KuoInit = { 1, 3, 7, 1, 3, 43, 91, 179, 379, 997, 1839, 3463, 4967, 12773, 26273, 52999, 0 }; + static ulong[] dim4174KuoInit = { 1, 1, 1, 5, 7, 45, 127, 213, 63, 93, 1735, 623, 153, 7039, 4233, 49775, 0 }; + static ulong[] dim4175KuoInit = { 1, 3, 1, 9, 19, 57, 27, 225, 225, 361, 1349, 829, 1441, 3557, 7595, 48405, 0 }; + static ulong[] dim4176KuoInit = { 1, 1, 7, 13, 27, 19, 119, 115, 15, 929, 345, 2199, 8101, 5787, 3105, 58313, 0 }; + static ulong[] dim4177KuoInit = { 1, 3, 3, 9, 23, 41, 81, 19, 445, 11, 771, 3767, 6781, 6969, 28385, 8473, 0 }; + static ulong[] dim4178KuoInit = { 1, 1, 1, 3, 1, 49, 5, 149, 383, 567, 1663, 1277, 733, 7651, 4835, 56429, 0 }; + static ulong[] dim4179KuoInit = { 1, 1, 7, 1, 29, 53, 33, 135, 491, 957, 1215, 687, 1025, 607, 459, 58433, 0 }; + static ulong[] dim4180KuoInit = { 1, 1, 1, 5, 17, 29, 67, 149, 93, 169, 851, 2311, 4971, 13403, 15023, 31645, 0 }; + static ulong[] dim4181KuoInit = { 1, 1, 7, 15, 25, 61, 127, 73, 379, 279, 1407, 285, 5697, 11141, 28961, 35551, 0 }; + static ulong[] dim4182KuoInit = { 1, 3, 1, 3, 17, 17, 123, 113, 349, 203, 685, 687, 6957, 13033, 25147, 61541, 0 }; + static ulong[] dim4183KuoInit = { 1, 3, 7, 3, 29, 47, 67, 161, 163, 427, 241, 2767, 6855, 4975, 19081, 4613, 0 }; + static ulong[] dim4184KuoInit = { 1, 1, 1, 3, 7, 51, 81, 57, 107, 171, 1671, 2373, 341, 4071, 12877, 55775, 0 }; + static ulong[] dim4185KuoInit = { 1, 1, 7, 15, 29, 63, 111, 255, 189, 33, 1613, 113, 4347, 549, 9793, 52611, 0 }; + static ulong[] dim4186KuoInit = { 1, 3, 3, 3, 17, 11, 41, 103, 509, 387, 1341, 663, 611, 12977, 6435, 40351, 0 }; + static ulong[] dim4187KuoInit = { 1, 1, 1, 5, 5, 39, 13, 229, 473, 159, 585, 2905, 3467, 8331, 11539, 57525, 0 }; + static ulong[] dim4188KuoInit = { 1, 3, 1, 7, 13, 25, 87, 115, 199, 611, 635, 2653, 5559, 7959, 9545, 14829, 0 }; + static ulong[] dim4189KuoInit = { 1, 1, 3, 7, 5, 57, 53, 155, 57, 301, 263, 1597, 7805, 8327, 20457, 6761, 0 }; + static ulong[] dim4190KuoInit = { 1, 3, 3, 5, 17, 39, 105, 177, 317, 681, 679, 691, 7751, 959, 2989, 31533, 0 }; + static ulong[] dim4191KuoInit = { 1, 1, 3, 1, 23, 15, 65, 223, 379, 523, 1285, 3175, 1821, 15655, 25183, 9415, 0 }; + static ulong[] dim4192KuoInit = { 1, 3, 3, 1, 11, 15, 49, 33, 243, 755, 2027, 3115, 4665, 12511, 8653, 35519, 0 }; + static ulong[] dim4193KuoInit = { 1, 3, 3, 7, 5, 45, 45, 183, 409, 107, 1277, 2975, 2291, 13839, 18513, 62993, 0 }; + static ulong[] dim4194KuoInit = { 1, 3, 5, 3, 21, 39, 47, 175, 197, 737, 707, 2769, 171, 12341, 22361, 16647, 0 }; + static ulong[] dim4195KuoInit = { 1, 3, 3, 1, 3, 35, 127, 23, 349, 477, 1347, 1939, 1199, 14441, 9795, 48051, 0 }; + static ulong[] dim4196KuoInit = { 1, 3, 1, 15, 23, 59, 69, 227, 429, 359, 507, 3615, 2331, 5741, 23905, 977, 0 }; + static ulong[] dim4197KuoInit = { 1, 3, 3, 1, 7, 5, 111, 17, 425, 697, 1957, 1771, 3495, 14373, 8385, 59295, 0 }; + static ulong[] dim4198KuoInit = { 1, 3, 3, 1, 1, 25, 113, 237, 393, 23, 575, 1117, 665, 3803, 28291, 60053, 0 }; + static ulong[] dim4199KuoInit = { 1, 1, 7, 7, 5, 33, 43, 121, 109, 201, 877, 3203, 7967, 11671, 13397, 9063, 0 }; + static ulong[] dim4200KuoInit = { 1, 1, 1, 9, 31, 57, 31, 75, 429, 471, 683, 3593, 4277, 10315, 1913, 54527, 0 }; + static ulong[] dim4201KuoInit = { 1, 1, 1, 3, 29, 17, 69, 75, 251, 595, 1127, 3015, 5621, 389, 2245, 43007, 0 }; + static ulong[] dim4202KuoInit = { 1, 1, 1, 5, 7, 41, 127, 57, 321, 971, 1217, 3731, 4667, 5919, 29871, 60487, 0 }; + static ulong[] dim4203KuoInit = { 1, 3, 3, 7, 21, 9, 83, 109, 489, 689, 1601, 2979, 405, 3131, 19409, 20739, 0 }; + static ulong[] dim4204KuoInit = { 1, 3, 7, 15, 31, 45, 77, 129, 269, 473, 427, 2751, 6841, 5957, 25297, 2301, 0 }; + static ulong[] dim4205KuoInit = { 1, 3, 7, 3, 27, 3, 107, 99, 37, 421, 1853, 2683, 7305, 467, 32481, 1085, 0 }; + static ulong[] dim4206KuoInit = { 1, 3, 7, 15, 25, 3, 79, 7, 47, 299, 731, 1321, 1917, 4315, 17177, 26499, 0 }; + static ulong[] dim4207KuoInit = { 1, 3, 7, 15, 5, 1, 19, 163, 335, 13, 1855, 3805, 6707, 2133, 19671, 53653, 0 }; + static ulong[] dim4208KuoInit = { 1, 1, 3, 7, 3, 5, 77, 69, 31, 959, 1815, 669, 5965, 2925, 16285, 42043, 0 }; + static ulong[] dim4209KuoInit = { 1, 3, 5, 15, 25, 5, 35, 175, 55, 765, 597, 703, 3141, 9825, 29067, 32817, 0 }; + static ulong[] dim4210KuoInit = { 1, 1, 3, 5, 1, 57, 119, 85, 167, 299, 561, 1045, 4255, 14663, 27787, 38785, 0 }; + static ulong[] dim4211KuoInit = { 1, 3, 5, 13, 5, 41, 97, 31, 55, 773, 707, 1083, 359, 15955, 11203, 50129, 0 }; + static ulong[] dim4212KuoInit = { 1, 3, 7, 5, 9, 35, 101, 231, 23, 301, 683, 3075, 3221, 7763, 5585, 35205, 0 }; + static ulong[] dim4213KuoInit = { 1, 3, 1, 13, 23, 29, 83, 227, 111, 307, 837, 465, 5933, 5265, 4507, 8719, 0 }; + static ulong[] dim4214KuoInit = { 1, 3, 3, 11, 21, 9, 49, 157, 271, 809, 1467, 1337, 5893, 13681, 11261, 56709, 0 }; + static ulong[] dim4215KuoInit = { 1, 3, 7, 1, 29, 33, 89, 39, 131, 339, 359, 3087, 5167, 5659, 629, 53865, 0 }; + static ulong[] dim4216KuoInit = { 1, 3, 1, 15, 11, 23, 59, 105, 201, 17, 923, 613, 1665, 8931, 28457, 63933, 0 }; + static ulong[] dim4217KuoInit = { 1, 1, 5, 13, 17, 33, 67, 73, 367, 263, 1377, 393, 1561, 3409, 24453, 61637, 0 }; + static ulong[] dim4218KuoInit = { 1, 1, 5, 1, 29, 9, 31, 51, 485, 775, 741, 1427, 1857, 10243, 18101, 29795, 0 }; + static ulong[] dim4219KuoInit = { 1, 1, 1, 5, 5, 39, 29, 137, 171, 837, 347, 1271, 7365, 3783, 22731, 18131, 0 }; + static ulong[] dim4220KuoInit = { 1, 1, 5, 11, 1, 45, 89, 175, 11, 859, 355, 1033, 4767, 11495, 28761, 11335, 0 }; + static ulong[] dim4221KuoInit = { 1, 1, 7, 1, 25, 7, 85, 229, 243, 259, 383, 1163, 4833, 11283, 31573, 30891, 0 }; + static ulong[] dim4222KuoInit = { 1, 3, 7, 5, 11, 41, 111, 87, 203, 177, 1113, 415, 3613, 1327, 20103, 61295, 0 }; + static ulong[] dim4223KuoInit = { 1, 3, 3, 9, 15, 53, 25, 245, 335, 31, 1335, 3339, 2337, 5719, 3333, 51325, 0 }; + static ulong[] dim4224KuoInit = { 1, 1, 5, 3, 5, 29, 117, 11, 239, 135, 1501, 2707, 2775, 2135, 11477, 44363, 0 }; + static ulong[] dim4225KuoInit = { 1, 1, 3, 1, 23, 33, 3, 219, 301, 643, 1555, 1, 709, 11, 30649, 19729, 0 }; + static ulong[] dim4226KuoInit = { 1, 1, 5, 7, 31, 9, 45, 185, 203, 741, 1851, 981, 6437, 1559, 27245, 36797, 0 }; + static ulong[] dim4227KuoInit = { 1, 1, 3, 7, 1, 41, 11, 141, 53, 533, 927, 2733, 1049, 16191, 1241, 49695, 0 }; + static ulong[] dim4228KuoInit = { 1, 3, 7, 1, 31, 21, 105, 181, 487, 1009, 135, 3649, 6459, 3397, 1805, 29793, 0 }; + static ulong[] dim4229KuoInit = { 1, 1, 3, 1, 1, 29, 65, 127, 461, 297, 1151, 2403, 4875, 343, 24293, 47203, 0 }; + static ulong[] dim4230KuoInit = { 1, 1, 7, 3, 9, 1, 23, 139, 337, 591, 1557, 1993, 6927, 5791, 29199, 2991, 0 }; + static ulong[] dim4231KuoInit = { 1, 1, 7, 9, 7, 1, 81, 129, 469, 215, 695, 2691, 6165, 14741, 24339, 58681, 0 }; + static ulong[] dim4232KuoInit = { 1, 3, 5, 13, 29, 59, 113, 143, 15, 399, 1141, 975, 1285, 12773, 593, 15481, 0 }; + static ulong[] dim4233KuoInit = { 1, 1, 3, 11, 19, 41, 85, 95, 479, 311, 1721, 1089, 7199, 15683, 15909, 40911, 0 }; + static ulong[] dim4234KuoInit = { 1, 1, 1, 3, 25, 55, 23, 195, 413, 623, 411, 279, 3381, 15313, 19323, 22829, 0 }; + static ulong[] dim4235KuoInit = { 1, 3, 5, 15, 13, 1, 55, 91, 493, 967, 1571, 2887, 2791, 1331, 20565, 61267, 0 }; + static ulong[] dim4236KuoInit = { 1, 3, 5, 1, 1, 17, 127, 253, 249, 559, 739, 2921, 1315, 13699, 22501, 9699, 0 }; + static ulong[] dim4237KuoInit = { 1, 3, 7, 13, 19, 53, 31, 103, 307, 821, 661, 591, 5379, 6401, 10109, 7325, 0 }; + static ulong[] dim4238KuoInit = { 1, 1, 1, 5, 15, 35, 59, 149, 443, 413, 139, 1851, 3679, 10721, 31393, 37329, 0 }; + static ulong[] dim4239KuoInit = { 1, 1, 3, 3, 15, 47, 43, 241, 323, 357, 1567, 3183, 6869, 4615, 5617, 28691, 0 }; + static ulong[] dim4240KuoInit = { 1, 3, 3, 1, 25, 11, 55, 55, 105, 277, 1317, 3631, 5351, 12747, 1685, 61239, 0 }; + static ulong[] dim4241KuoInit = { 1, 1, 7, 7, 31, 19, 87, 119, 409, 817, 97, 3549, 3517, 13901, 11707, 9501, 0 }; + static ulong[] dim4242KuoInit = { 1, 1, 7, 11, 13, 17, 55, 195, 457, 223, 837, 453, 2953, 2269, 10149, 48941, 0 }; + static ulong[] dim4243KuoInit = { 1, 3, 3, 13, 5, 31, 63, 117, 419, 329, 1759, 1167, 7967, 8975, 11247, 37159, 0 }; + static ulong[] dim4244KuoInit = { 1, 1, 7, 1, 17, 19, 41, 61, 349, 299, 1449, 2329, 471, 5119, 29595, 43335, 0 }; + static ulong[] dim4245KuoInit = { 1, 1, 1, 13, 13, 63, 99, 239, 239, 903, 55, 1347, 969, 9409, 11603, 28553, 0 }; + static ulong[] dim4246KuoInit = { 1, 3, 1, 7, 25, 59, 23, 241, 361, 1005, 771, 923, 3315, 4201, 32695, 54151, 0 }; + static ulong[] dim4247KuoInit = { 1, 3, 3, 5, 19, 1, 113, 103, 469, 591, 319, 2297, 1033, 9273, 20529, 58301, 0 }; + static ulong[] dim4248KuoInit = { 1, 3, 7, 11, 23, 1, 77, 161, 321, 855, 1987, 3735, 4533, 12061, 19305, 31679, 0 }; + static ulong[] dim4249KuoInit = { 1, 1, 3, 7, 27, 15, 73, 83, 113, 455, 1855, 2677, 3243, 14961, 27147, 21865, 0 }; + static ulong[] dim4250KuoInit = { 1, 3, 5, 11, 15, 33, 61, 87, 237, 775, 1765, 2783, 3051, 3617, 32519, 43991, 0 }; + static ulong[] dim4251KuoInit = { 1, 3, 5, 1, 9, 57, 21, 177, 499, 605, 391, 381, 2027, 9221, 11213, 10365, 0 }; + static ulong[] dim4252KuoInit = { 1, 1, 7, 5, 31, 29, 57, 159, 413, 321, 245, 2007, 2817, 5173, 23227, 19885, 0 }; + static ulong[] dim4253KuoInit = { 1, 1, 7, 7, 29, 43, 113, 173, 505, 449, 409, 981, 2257, 13261, 85, 6477, 0 }; + static ulong[] dim4254KuoInit = { 1, 1, 5, 13, 9, 51, 1, 127, 65, 963, 1541, 1321, 7849, 6481, 1583, 14737, 0 }; + static ulong[] dim4255KuoInit = { 1, 1, 3, 3, 1, 45, 11, 157, 375, 439, 1673, 271, 3853, 8795, 23287, 45365, 0 }; + static ulong[] dim4256KuoInit = { 1, 1, 3, 11, 17, 7, 43, 3, 3, 1005, 523, 2553, 2457, 259, 20999, 23611, 0 }; + static ulong[] dim4257KuoInit = { 1, 3, 3, 11, 17, 33, 97, 227, 19, 19, 2039, 3181, 1393, 1427, 215, 49915, 0 }; + static ulong[] dim4258KuoInit = { 1, 1, 5, 9, 19, 1, 83, 95, 7, 571, 655, 1281, 3841, 3925, 24603, 38413, 0 }; + static ulong[] dim4259KuoInit = { 1, 3, 1, 3, 19, 47, 43, 105, 431, 921, 927, 3713, 8181, 4177, 9411, 1481, 0 }; + static ulong[] dim4260KuoInit = { 1, 3, 1, 9, 3, 29, 11, 121, 505, 629, 959, 523, 257, 3089, 15075, 14087, 0 }; + static ulong[] dim4261KuoInit = { 1, 3, 5, 13, 9, 3, 5, 167, 7, 705, 1737, 583, 2297, 13073, 27617, 22083, 0 }; + static ulong[] dim4262KuoInit = { 1, 3, 3, 13, 9, 51, 33, 191, 263, 961, 1019, 2771, 3487, 7471, 10939, 23831, 0 }; + static ulong[] dim4263KuoInit = { 1, 1, 5, 5, 25, 19, 75, 115, 221, 93, 1135, 257, 5597, 14715, 2385, 46659, 0 }; + static ulong[] dim4264KuoInit = { 1, 1, 3, 5, 31, 13, 63, 231, 463, 501, 1437, 1777, 6161, 9885, 10543, 26031, 0 }; + static ulong[] dim4265KuoInit = { 1, 1, 5, 5, 5, 1, 51, 141, 311, 929, 261, 2959, 59, 4163, 9855, 54825, 0 }; + static ulong[] dim4266KuoInit = { 1, 3, 1, 9, 1, 57, 31, 21, 395, 211, 89, 3703, 7565, 2095, 16273, 52105, 0 }; + static ulong[] dim4267KuoInit = { 1, 1, 3, 11, 25, 57, 27, 163, 459, 849, 955, 2437, 7115, 8029, 165, 12007, 0 }; + static ulong[] dim4268KuoInit = { 1, 1, 3, 7, 29, 57, 49, 71, 389, 483, 991, 629, 1517, 2481, 4881, 39431, 0 }; + static ulong[] dim4269KuoInit = { 1, 3, 5, 1, 1, 11, 29, 81, 323, 581, 1515, 905, 2813, 12221, 20181, 9855, 0 }; + static ulong[] dim4270KuoInit = { 1, 3, 1, 5, 27, 3, 41, 65, 369, 925, 1449, 2711, 3333, 6263, 10639, 43537, 0 }; + static ulong[] dim4271KuoInit = { 1, 1, 1, 15, 17, 5, 31, 181, 77, 999, 1011, 2631, 1761, 10139, 24369, 39093, 0 }; + static ulong[] dim4272KuoInit = { 1, 3, 3, 11, 11, 23, 65, 165, 41, 591, 1045, 263, 1707, 4419, 24005, 47489, 0 }; + static ulong[] dim4273KuoInit = { 1, 1, 7, 13, 11, 43, 65, 161, 229, 35, 637, 3693, 721, 6863, 12001, 48067, 0 }; + static ulong[] dim4274KuoInit = { 1, 3, 3, 15, 9, 39, 27, 65, 407, 103, 1437, 3403, 7355, 2009, 5979, 37959, 0 }; + static ulong[] dim4275KuoInit = { 1, 1, 5, 5, 13, 23, 65, 145, 395, 603, 1711, 1529, 6309, 14631, 4615, 24459, 0 }; + static ulong[] dim4276KuoInit = { 1, 3, 7, 13, 25, 27, 109, 91, 205, 53, 199, 1215, 4371, 4821, 11793, 20719, 0 }; + static ulong[] dim4277KuoInit = { 1, 1, 5, 5, 9, 9, 115, 77, 223, 381, 1035, 1961, 5285, 12465, 20531, 51677, 0 }; + static ulong[] dim4278KuoInit = { 1, 3, 3, 9, 13, 31, 123, 123, 325, 719, 1683, 1253, 4241, 1443, 7507, 8253, 0 }; + static ulong[] dim4279KuoInit = { 1, 3, 3, 7, 5, 1, 71, 145, 299, 1021, 677, 1733, 2791, 12337, 24395, 64145, 0 }; + static ulong[] dim4280KuoInit = { 1, 1, 7, 11, 21, 31, 113, 79, 1, 29, 1171, 4081, 7599, 11661, 4305, 11383, 0 }; + static ulong[] dim4281KuoInit = { 1, 3, 3, 7, 27, 9, 97, 117, 205, 391, 1571, 1801, 6085, 15867, 8987, 29925, 0 }; + static ulong[] dim4282KuoInit = { 1, 3, 3, 3, 5, 35, 27, 143, 503, 533, 1293, 3737, 3011, 4457, 18381, 45513, 0 }; + static ulong[] dim4283KuoInit = { 1, 3, 1, 1, 21, 55, 113, 127, 365, 265, 1211, 841, 807, 3901, 28993, 28467, 0 }; + static ulong[] dim4284KuoInit = { 1, 1, 1, 7, 21, 17, 101, 217, 413, 273, 53, 2415, 655, 9939, 11233, 31631, 0 }; + static ulong[] dim4285KuoInit = { 1, 3, 7, 13, 11, 11, 111, 63, 301, 343, 1757, 2615, 1683, 11143, 16405, 16671, 0 }; + static ulong[] dim4286KuoInit = { 1, 1, 5, 15, 17, 19, 83, 195, 475, 189, 1881, 699, 4853, 7849, 15063, 5517, 0 }; + static ulong[] dim4287KuoInit = { 1, 1, 5, 5, 27, 25, 19, 239, 153, 725, 709, 3717, 4801, 1433, 17789, 34549, 0 }; + static ulong[] dim4288KuoInit = { 1, 3, 1, 9, 9, 5, 47, 215, 123, 161, 583, 917, 5373, 6839, 20747, 47179, 0 }; + static ulong[] dim4289KuoInit = { 1, 1, 1, 15, 1, 25, 31, 217, 185, 331, 261, 3877, 2339, 11557, 22779, 58509, 0 }; + static ulong[] dim4290KuoInit = { 1, 1, 7, 15, 11, 1, 13, 53, 319, 237, 763, 2411, 7953, 2117, 24947, 26643, 0 }; + static ulong[] dim4291KuoInit = { 1, 3, 5, 5, 17, 53, 9, 253, 219, 715, 1923, 823, 1495, 1975, 3739, 61343, 0 }; + static ulong[] dim4292KuoInit = { 1, 1, 1, 11, 27, 31, 121, 253, 319, 1001, 125, 567, 215, 6879, 22581, 38495, 0 }; + static ulong[] dim4293KuoInit = { 1, 1, 1, 11, 23, 17, 83, 65, 279, 725, 1611, 3911, 509, 1729, 30025, 10791, 0 }; + static ulong[] dim4294KuoInit = { 1, 3, 1, 11, 19, 17, 67, 101, 129, 607, 557, 3475, 1445, 8789, 1815, 18171, 0 }; + static ulong[] dim4295KuoInit = { 1, 3, 7, 7, 23, 57, 69, 127, 147, 743, 549, 3269, 6193, 12667, 17081, 6899, 0 }; + static ulong[] dim4296KuoInit = { 1, 3, 1, 9, 9, 29, 83, 175, 389, 289, 367, 1259, 6631, 15675, 20975, 54067, 0 }; + static ulong[] dim4297KuoInit = { 1, 1, 7, 1, 27, 11, 31, 209, 159, 615, 1813, 3235, 7487, 7103, 5857, 19435, 0 }; + static ulong[] dim4298KuoInit = { 1, 3, 7, 7, 17, 3, 13, 255, 405, 925, 55, 3539, 3351, 359, 7633, 38209, 0 }; + static ulong[] dim4299KuoInit = { 1, 3, 5, 5, 5, 51, 123, 61, 485, 785, 1975, 121, 7841, 7253, 11769, 7389, 0 }; + static ulong[] dim4300KuoInit = { 1, 1, 1, 9, 1, 3, 51, 169, 163, 875, 35, 1573, 7931, 13611, 14697, 64843, 0 }; + static ulong[] dim4301KuoInit = { 1, 1, 5, 13, 11, 35, 47, 135, 475, 893, 39, 2763, 2671, 7417, 22905, 60593, 0 }; + static ulong[] dim4302KuoInit = { 1, 3, 5, 3, 27, 27, 85, 219, 341, 509, 1131, 3607, 1307, 15265, 28589, 61113, 0 }; + static ulong[] dim4303KuoInit = { 1, 1, 5, 11, 11, 37, 53, 67, 177, 951, 237, 3865, 2233, 1405, 28373, 47767, 0 }; + static ulong[] dim4304KuoInit = { 1, 3, 7, 9, 17, 49, 35, 167, 67, 397, 927, 3305, 2791, 3609, 3111, 4555, 0 }; + static ulong[] dim4305KuoInit = { 1, 1, 5, 13, 13, 41, 123, 89, 65, 931, 1959, 1751, 2765, 8361, 23653, 45677, 0 }; + static ulong[] dim4306KuoInit = { 1, 1, 1, 3, 25, 37, 91, 225, 181, 275, 1515, 1355, 7971, 16081, 13715, 63963, 0 }; + static ulong[] dim4307KuoInit = { 1, 3, 3, 3, 7, 11, 125, 181, 127, 855, 1277, 3587, 1351, 4907, 16985, 357, 0 }; + static ulong[] dim4308KuoInit = { 1, 3, 5, 13, 13, 57, 23, 99, 115, 923, 1395, 3083, 3939, 475, 12385, 30113, 0 }; + static ulong[] dim4309KuoInit = { 1, 3, 1, 1, 1, 19, 27, 73, 91, 155, 1145, 467, 5655, 341, 8875, 61583, 0 }; + static ulong[] dim4310KuoInit = { 1, 3, 1, 1, 17, 33, 113, 219, 99, 817, 1731, 3379, 5729, 13615, 19047, 14143, 0 }; + static ulong[] dim4311KuoInit = { 1, 1, 3, 5, 29, 7, 35, 111, 405, 207, 1811, 3701, 6101, 7147, 13825, 52081, 0 }; + static ulong[] dim4312KuoInit = { 1, 1, 7, 9, 19, 23, 89, 95, 503, 311, 1615, 371, 5853, 4635, 31911, 65345, 0 }; + static ulong[] dim4313KuoInit = { 1, 1, 7, 5, 17, 41, 49, 143, 445, 855, 1311, 3961, 3559, 5483, 31609, 34147, 0 }; + static ulong[] dim4314KuoInit = { 1, 3, 1, 15, 19, 49, 67, 141, 293, 757, 1905, 2513, 4405, 41, 1191, 15259, 0 }; + static ulong[] dim4315KuoInit = { 1, 1, 3, 11, 11, 39, 113, 73, 23, 117, 1315, 725, 7429, 5483, 26213, 9331, 0 }; + static ulong[] dim4316KuoInit = { 1, 1, 3, 3, 3, 9, 119, 35, 309, 515, 751, 323, 2521, 12093, 1123, 43651, 0 }; + static ulong[] dim4317KuoInit = { 1, 1, 3, 3, 29, 43, 49, 53, 481, 269, 915, 1845, 3341, 511, 23845, 34623, 0 }; + static ulong[] dim4318KuoInit = { 1, 1, 3, 1, 23, 23, 71, 225, 269, 713, 21, 1051, 7635, 14245, 3947, 41757, 0 }; + static ulong[] dim4319KuoInit = { 1, 3, 5, 11, 5, 19, 39, 99, 309, 531, 1645, 787, 6913, 8159, 1359, 61973, 0 }; + static ulong[] dim4320KuoInit = { 1, 1, 5, 5, 5, 61, 107, 91, 197, 109, 369, 1053, 1995, 11551, 4751, 4981, 0 }; + static ulong[] dim4321KuoInit = { 1, 3, 5, 11, 29, 31, 103, 21, 393, 63, 1465, 2813, 995, 67, 11997, 34887, 0 }; + static ulong[] dim4322KuoInit = { 1, 3, 1, 7, 9, 49, 111, 135, 83, 79, 353, 2703, 5027, 10287, 3753, 60785, 0 }; + static ulong[] dim4323KuoInit = { 1, 1, 7, 15, 17, 17, 51, 69, 465, 25, 1231, 995, 4643, 3405, 2237, 54357, 0 }; + static ulong[] dim4324KuoInit = { 1, 1, 1, 1, 5, 39, 31, 187, 459, 197, 905, 279, 2279, 6585, 7073, 1897, 0 }; + static ulong[] dim4325KuoInit = { 1, 3, 3, 15, 13, 17, 105, 29, 183, 193, 541, 977, 2247, 5173, 10511, 59969, 0 }; + static ulong[] dim4326KuoInit = { 1, 1, 1, 15, 3, 11, 89, 1, 411, 503, 267, 2875, 2585, 9391, 19395, 30107, 0 }; + static ulong[] dim4327KuoInit = { 1, 1, 7, 9, 7, 19, 45, 251, 143, 729, 1825, 2571, 6277, 12759, 5057, 58455, 0 }; + static ulong[] dim4328KuoInit = { 1, 3, 3, 9, 7, 49, 119, 3, 127, 1015, 937, 2585, 1229, 16289, 30087, 45069, 0 }; + static ulong[] dim4329KuoInit = { 1, 3, 5, 13, 15, 39, 39, 13, 315, 533, 143, 2107, 805, 1487, 8049, 3643, 0 }; + static ulong[] dim4330KuoInit = { 1, 3, 1, 15, 23, 35, 127, 143, 247, 491, 837, 2263, 1375, 8283, 24527, 37967, 0 }; + static ulong[] dim4331KuoInit = { 1, 3, 7, 11, 13, 9, 51, 171, 421, 161, 1777, 3679, 4821, 10113, 28459, 55339, 0 }; + static ulong[] dim4332KuoInit = { 1, 3, 3, 1, 25, 61, 53, 145, 81, 509, 2001, 315, 7775, 7741, 9239, 10041, 0 }; + static ulong[] dim4333KuoInit = { 1, 1, 3, 3, 11, 31, 21, 91, 425, 415, 523, 3649, 6595, 9409, 26631, 8761, 0 }; + static ulong[] dim4334KuoInit = { 1, 3, 7, 7, 13, 1, 51, 53, 123, 125, 1055, 3951, 6621, 9207, 25991, 36435, 0 }; + static ulong[] dim4335KuoInit = { 1, 3, 5, 3, 21, 63, 57, 35, 197, 601, 665, 3223, 817, 3467, 2667, 2811, 0 }; + static ulong[] dim4336KuoInit = { 1, 3, 1, 11, 7, 29, 51, 29, 383, 969, 557, 795, 7535, 513, 1329, 57567, 0 }; + static ulong[] dim4337KuoInit = { 1, 1, 1, 13, 11, 59, 85, 183, 163, 445, 1595, 133, 4277, 3323, 6833, 50359, 0 }; + static ulong[] dim4338KuoInit = { 1, 3, 1, 13, 9, 11, 65, 209, 509, 65, 1299, 2225, 7727, 3851, 17661, 39777, 0 }; + static ulong[] dim4339KuoInit = { 1, 1, 5, 5, 13, 31, 15, 189, 43, 435, 707, 83, 6713, 13721, 24013, 47037, 0 }; + static ulong[] dim4340KuoInit = { 1, 1, 1, 9, 29, 49, 101, 205, 7, 539, 1809, 4095, 7581, 8187, 16475, 10923, 0 }; + static ulong[] dim4341KuoInit = { 1, 3, 3, 7, 27, 39, 65, 117, 183, 439, 997, 1389, 2945, 13303, 10621, 63085, 0 }; + static ulong[] dim4342KuoInit = { 1, 1, 3, 15, 11, 21, 121, 179, 37, 993, 1299, 2741, 5797, 10677, 32519, 45061, 0 }; + static ulong[] dim4343KuoInit = { 1, 1, 7, 1, 23, 47, 107, 131, 145, 679, 1519, 1147, 887, 2017, 31191, 4047, 0 }; + static ulong[] dim4344KuoInit = { 1, 1, 3, 11, 1, 51, 1, 105, 245, 269, 1067, 3551, 6323, 3729, 16351, 62965, 0 }; + static ulong[] dim4345KuoInit = { 1, 1, 3, 3, 17, 11, 53, 163, 387, 601, 75, 3219, 5683, 783, 28143, 20695, 0 }; + static ulong[] dim4346KuoInit = { 1, 1, 5, 15, 21, 21, 33, 171, 73, 157, 49, 3443, 4057, 8631, 17555, 8959, 0 }; + static ulong[] dim4347KuoInit = { 1, 1, 5, 9, 3, 35, 13, 211, 181, 425, 1367, 2217, 5949, 2741, 8141, 45769, 0 }; + static ulong[] dim4348KuoInit = { 1, 3, 1, 11, 27, 43, 117, 3, 331, 553, 1847, 2085, 7125, 10827, 10583, 60169, 0 }; + static ulong[] dim4349KuoInit = { 1, 1, 3, 1, 15, 35, 81, 15, 259, 89, 1071, 3807, 3149, 3309, 17791, 63869, 0 }; + static ulong[] dim4350KuoInit = { 1, 3, 3, 5, 19, 7, 113, 131, 399, 691, 57, 1837, 3613, 1755, 521, 64867, 0 }; + static ulong[] dim4351KuoInit = { 1, 3, 1, 11, 25, 53, 11, 241, 187, 237, 1591, 4059, 6021, 8451, 14305, 30965, 0 }; + static ulong[] dim4352KuoInit = { 1, 1, 7, 11, 27, 15, 9, 209, 43, 137, 1351, 2553, 2841, 6375, 20291, 2523, 0 }; + static ulong[] dim4353KuoInit = { 1, 3, 3, 5, 27, 37, 83, 61, 365, 739, 69, 725, 6745, 7353, 2621, 57747, 0 }; + static ulong[] dim4354KuoInit = { 1, 1, 1, 1, 17, 9, 53, 93, 103, 467, 1543, 2353, 4901, 13269, 21635, 63425, 0 }; + static ulong[] dim4355KuoInit = { 1, 3, 1, 9, 15, 19, 61, 127, 423, 749, 809, 515, 7819, 1209, 22879, 54069, 0 }; + static ulong[] dim4356KuoInit = { 1, 1, 3, 7, 11, 23, 93, 5, 91, 613, 1529, 2621, 2689, 2251, 16049, 60773, 0 }; + static ulong[] dim4357KuoInit = { 1, 1, 5, 5, 15, 27, 57, 177, 477, 585, 249, 3673, 2651, 10137, 30395, 57475, 0 }; + static ulong[] dim4358KuoInit = { 1, 3, 1, 5, 31, 39, 25, 185, 233, 915, 1335, 2889, 1135, 12515, 27385, 54785, 0 }; + static ulong[] dim4359KuoInit = { 1, 3, 5, 15, 3, 19, 13, 105, 465, 11, 799, 1699, 6495, 14307, 18071, 55405, 0 }; + static ulong[] dim4360KuoInit = { 1, 1, 1, 15, 31, 49, 27, 209, 503, 979, 877, 3121, 3545, 12875, 799, 44427, 0 }; + static ulong[] dim4361KuoInit = { 1, 1, 5, 3, 23, 17, 113, 109, 301, 587, 1865, 1623, 453, 14449, 26901, 34687, 0 }; + static ulong[] dim4362KuoInit = { 1, 3, 7, 11, 1, 29, 25, 113, 147, 53, 27, 2971, 5663, 12013, 1281, 65173, 0 }; + static ulong[] dim4363KuoInit = { 1, 3, 1, 11, 13, 47, 13, 209, 339, 393, 1389, 2205, 537, 10911, 20093, 61499, 0 }; + static ulong[] dim4364KuoInit = { 1, 1, 7, 9, 21, 45, 75, 43, 425, 89, 1319, 2245, 6519, 12819, 30653, 18927, 0 }; + static ulong[] dim4365KuoInit = { 1, 1, 3, 11, 1, 31, 55, 29, 337, 733, 1303, 1721, 7163, 13807, 5865, 20009, 0 }; + static ulong[] dim4366KuoInit = { 1, 1, 3, 15, 1, 5, 101, 211, 263, 865, 59, 2473, 3857, 9909, 21353, 8807, 0 }; + static ulong[] dim4367KuoInit = { 1, 1, 3, 9, 25, 29, 5, 157, 17, 985, 369, 1903, 2431, 15395, 20245, 51253, 0 }; + static ulong[] dim4368KuoInit = { 1, 3, 3, 11, 7, 31, 45, 209, 287, 13, 591, 3907, 7501, 10003, 21815, 43213, 0 }; + static ulong[] dim4369KuoInit = { 1, 3, 7, 5, 27, 25, 73, 191, 361, 731, 757, 1907, 9, 16357, 4241, 40187, 0 }; + static ulong[] dim4370KuoInit = { 1, 1, 7, 1, 5, 55, 121, 89, 39, 531, 493, 3453, 5709, 8215, 21831, 5661, 0 }; + static ulong[] dim4371KuoInit = { 1, 3, 7, 11, 27, 59, 49, 251, 17, 223, 875, 1133, 3161, 10273, 26463, 45987, 0 }; + static ulong[] dim4372KuoInit = { 1, 3, 5, 9, 17, 39, 117, 153, 243, 449, 1261, 3917, 1359, 4525, 22119, 1781, 0 }; + static ulong[] dim4373KuoInit = { 1, 1, 3, 7, 15, 15, 19, 151, 411, 693, 445, 2525, 2867, 12809, 1487, 7019, 0 }; + static ulong[] dim4374KuoInit = { 1, 1, 7, 7, 15, 57, 61, 243, 427, 529, 1051, 3391, 6259, 8791, 3405, 54757, 0 }; + static ulong[] dim4375KuoInit = { 1, 3, 1, 5, 13, 41, 105, 73, 485, 881, 1943, 1419, 5761, 11807, 16497, 12763, 0 }; + static ulong[] dim4376KuoInit = { 1, 3, 3, 15, 7, 47, 61, 99, 473, 487, 1973, 1675, 3163, 4033, 5323, 31313, 0 }; + static ulong[] dim4377KuoInit = { 1, 1, 1, 3, 21, 33, 23, 129, 469, 743, 769, 1561, 235, 13713, 6827, 61273, 0 }; + static ulong[] dim4378KuoInit = { 1, 3, 1, 13, 11, 19, 59, 37, 431, 5, 1333, 2381, 5707, 2499, 9339, 35803, 0 }; + static ulong[] dim4379KuoInit = { 1, 1, 5, 1, 17, 11, 77, 137, 111, 567, 1469, 543, 5633, 1927, 26491, 37955, 0 }; + static ulong[] dim4380KuoInit = { 1, 3, 5, 15, 21, 9, 57, 35, 291, 371, 65, 2891, 841, 11859, 16685, 5641, 0 }; + static ulong[] dim4381KuoInit = { 1, 3, 7, 1, 3, 35, 121, 153, 353, 633, 995, 121, 7317, 273, 23329, 32591, 0 }; + static ulong[] dim4382KuoInit = { 1, 3, 5, 1, 25, 19, 35, 221, 295, 543, 1269, 3901, 2109, 4463, 4275, 89, 0 }; + static ulong[] dim4383KuoInit = { 1, 3, 7, 13, 1, 13, 85, 97, 155, 731, 1017, 3713, 1613, 805, 8927, 32165, 0 }; + static ulong[] dim4384KuoInit = { 1, 3, 3, 13, 17, 1, 21, 235, 103, 875, 1849, 2669, 3193, 9053, 16123, 29481, 0 }; + static ulong[] dim4385KuoInit = { 1, 3, 7, 9, 23, 21, 37, 251, 441, 437, 629, 1009, 5663, 14447, 23437, 32521, 0 }; + static ulong[] dim4386KuoInit = { 1, 1, 7, 5, 9, 5, 7, 123, 483, 433, 867, 149, 1975, 5497, 7887, 25779, 0 }; + static ulong[] dim4387KuoInit = { 1, 3, 3, 3, 31, 17, 81, 167, 399, 1, 1777, 833, 8035, 8597, 28371, 19293, 0 }; + static ulong[] dim4388KuoInit = { 1, 3, 3, 11, 9, 45, 125, 121, 147, 613, 599, 111, 7583, 3189, 13185, 35603, 0 }; + static ulong[] dim4389KuoInit = { 1, 1, 1, 15, 31, 51, 9, 191, 55, 837, 1773, 2781, 6351, 1909, 5407, 7533, 0 }; + static ulong[] dim4390KuoInit = { 1, 1, 3, 13, 13, 35, 71, 25, 465, 377, 613, 2487, 6297, 8299, 27541, 17779, 0 }; + static ulong[] dim4391KuoInit = { 1, 1, 3, 15, 21, 59, 43, 115, 369, 315, 315, 3451, 5785, 6353, 22609, 42793, 0 }; + static ulong[] dim4392KuoInit = { 1, 1, 5, 15, 13, 3, 127, 87, 211, 981, 629, 2683, 5683, 15475, 20431, 32977, 0 }; + static ulong[] dim4393KuoInit = { 1, 1, 3, 7, 31, 3, 23, 7, 117, 1001, 431, 2215, 5817, 16283, 12781, 63883, 0 }; + static ulong[] dim4394KuoInit = { 1, 1, 3, 1, 27, 11, 43, 195, 329, 375, 655, 3815, 5699, 11259, 6733, 26015, 0 }; + static ulong[] dim4395KuoInit = { 1, 3, 3, 11, 19, 3, 63, 187, 47, 891, 1463, 3259, 1479, 15109, 25387, 43753, 0 }; + static ulong[] dim4396KuoInit = { 1, 1, 5, 11, 31, 43, 59, 149, 205, 447, 1787, 627, 6227, 9951, 19069, 50193, 0 }; + static ulong[] dim4397KuoInit = { 1, 3, 3, 7, 7, 1, 41, 33, 395, 139, 689, 1597, 529, 6861, 2025, 19569, 0 }; + static ulong[] dim4398KuoInit = { 1, 1, 1, 7, 17, 63, 17, 73, 459, 1007, 1563, 879, 1441, 525, 32679, 56409, 0 }; + static ulong[] dim4399KuoInit = { 1, 3, 3, 13, 3, 5, 23, 239, 7, 807, 1999, 1427, 6647, 2249, 17687, 5519, 0 }; + static ulong[] dim4400KuoInit = { 1, 3, 5, 1, 7, 15, 7, 243, 347, 415, 1519, 2267, 3119, 3145, 27799, 24453, 0 }; + static ulong[] dim4401KuoInit = { 1, 3, 3, 3, 5, 1, 93, 215, 475, 209, 361, 951, 147, 1401, 6851, 59257, 0 }; + static ulong[] dim4402KuoInit = { 1, 1, 7, 3, 29, 39, 67, 195, 287, 587, 315, 1747, 7169, 11967, 4893, 797, 0 }; + static ulong[] dim4403KuoInit = { 1, 3, 5, 5, 13, 49, 47, 97, 105, 203, 1237, 805, 3595, 9225, 23105, 52679, 0 }; + static ulong[] dim4404KuoInit = { 1, 1, 5, 1, 23, 41, 39, 85, 7, 237, 1545, 2591, 1771, 2291, 20185, 46995, 0 }; + static ulong[] dim4405KuoInit = { 1, 1, 1, 3, 15, 5, 43, 211, 109, 599, 77, 703, 5749, 15909, 12619, 41635, 0 }; + static ulong[] dim4406KuoInit = { 1, 3, 1, 9, 19, 9, 49, 211, 149, 883, 1617, 497, 7689, 4253, 18737, 25293, 0 }; + static ulong[] dim4407KuoInit = { 1, 1, 7, 11, 25, 3, 57, 83, 181, 801, 1515, 3821, 5287, 15243, 2347, 42333, 0 }; + static ulong[] dim4408KuoInit = { 1, 3, 7, 15, 15, 25, 107, 79, 249, 721, 1237, 1587, 3469, 10319, 6421, 59103, 0 }; + static ulong[] dim4409KuoInit = { 1, 1, 3, 3, 17, 21, 81, 35, 173, 101, 1879, 3301, 4409, 8563, 27981, 64269, 0 }; + static ulong[] dim4410KuoInit = { 1, 1, 7, 3, 29, 17, 103, 17, 443, 821, 1133, 73, 2587, 16119, 17385, 2293, 0 }; + static ulong[] dim4411KuoInit = { 1, 3, 7, 13, 9, 3, 41, 125, 149, 403, 537, 695, 3885, 15769, 11315, 53979, 0 }; + static ulong[] dim4412KuoInit = { 1, 3, 5, 7, 11, 47, 57, 105, 433, 1009, 1749, 2453, 2083, 1543, 25941, 58037, 0 }; + static ulong[] dim4413KuoInit = { 1, 1, 1, 3, 19, 63, 45, 251, 265, 591, 1235, 1349, 6069, 14139, 4299, 32719, 0 }; + static ulong[] dim4414KuoInit = { 1, 3, 5, 9, 1, 49, 125, 217, 247, 915, 1289, 3589, 7, 5285, 32443, 56439, 0 }; + static ulong[] dim4415KuoInit = { 1, 3, 5, 3, 31, 31, 67, 55, 203, 487, 983, 1841, 1587, 14881, 29187, 59293, 0 }; + static ulong[] dim4416KuoInit = { 1, 1, 1, 13, 1, 59, 121, 57, 99, 857, 1085, 3505, 3615, 13725, 10363, 16841, 0 }; + static ulong[] dim4417KuoInit = { 1, 1, 5, 3, 19, 55, 43, 95, 141, 217, 1087, 1129, 3417, 515, 23815, 13135, 0 }; + static ulong[] dim4418KuoInit = { 1, 1, 1, 15, 9, 63, 5, 139, 327, 743, 1321, 4055, 4337, 15115, 8635, 53571, 0 }; + static ulong[] dim4419KuoInit = { 1, 1, 5, 11, 31, 47, 105, 91, 493, 77, 1767, 1647, 4287, 5455, 1875, 6669, 0 }; + static ulong[] dim4420KuoInit = { 1, 3, 1, 1, 25, 47, 19, 243, 131, 387, 69, 2057, 7151, 8497, 10975, 64383, 0 }; + static ulong[] dim4421KuoInit = { 1, 3, 3, 1, 13, 19, 93, 35, 63, 881, 1787, 331, 57, 12875, 5689, 56411, 0 }; + static ulong[] dim4422KuoInit = { 1, 3, 5, 1, 1, 33, 39, 193, 17, 291, 1507, 1719, 3507, 12683, 16467, 21453, 0 }; + static ulong[] dim4423KuoInit = { 1, 1, 7, 7, 15, 41, 113, 23, 499, 641, 937, 2505, 4093, 4897, 2493, 28043, 0 }; + static ulong[] dim4424KuoInit = { 1, 3, 1, 15, 13, 11, 59, 175, 299, 233, 189, 675, 2623, 15695, 2895, 29213, 0 }; + static ulong[] dim4425KuoInit = { 1, 1, 3, 3, 25, 33, 113, 81, 485, 615, 1451, 1331, 607, 13451, 5853, 5051, 0 }; + static ulong[] dim4426KuoInit = { 1, 1, 7, 15, 13, 55, 107, 43, 343, 383, 63, 2761, 5543, 10249, 2903, 28567, 0 }; + static ulong[] dim4427KuoInit = { 1, 1, 7, 13, 7, 23, 13, 199, 109, 87, 389, 561, 2403, 12411, 18247, 40239, 0 }; + static ulong[] dim4428KuoInit = { 1, 1, 1, 13, 21, 31, 3, 109, 97, 803, 991, 847, 6517, 3389, 15347, 18295, 0 }; + static ulong[] dim4429KuoInit = { 1, 1, 1, 1, 27, 41, 115, 59, 189, 105, 63, 3169, 2293, 6051, 26017, 49947, 0 }; + static ulong[] dim4430KuoInit = { 1, 3, 5, 13, 19, 27, 47, 13, 9, 135, 637, 2167, 2865, 13353, 1725, 41671, 0 }; + static ulong[] dim4431KuoInit = { 1, 1, 5, 7, 17, 61, 37, 247, 447, 633, 1761, 2075, 6385, 12393, 31483, 1857, 0 }; + static ulong[] dim4432KuoInit = { 1, 3, 5, 13, 17, 17, 103, 47, 391, 725, 1379, 3939, 6467, 6723, 4229, 50221, 0 }; + static ulong[] dim4433KuoInit = { 1, 1, 5, 5, 1, 61, 13, 157, 379, 935, 105, 419, 147, 6369, 15413, 38553, 0 }; + static ulong[] dim4434KuoInit = { 1, 1, 5, 1, 13, 49, 63, 165, 207, 741, 1285, 3247, 4053, 1647, 6571, 61075, 0 }; + static ulong[] dim4435KuoInit = { 1, 1, 5, 15, 29, 41, 51, 5, 123, 45, 537, 2887, 1329, 9447, 22285, 45247, 0 }; + static ulong[] dim4436KuoInit = { 1, 3, 1, 3, 29, 51, 65, 91, 153, 673, 1759, 401, 2969, 6631, 16965, 49027, 0 }; + static ulong[] dim4437KuoInit = { 1, 3, 3, 15, 29, 61, 31, 85, 13, 427, 1833, 2145, 4229, 14543, 22741, 24913, 0 }; + static ulong[] dim4438KuoInit = { 1, 3, 5, 3, 21, 9, 45, 253, 89, 397, 965, 685, 4013, 11731, 2947, 11995, 0 }; + static ulong[] dim4439KuoInit = { 1, 3, 3, 11, 27, 45, 101, 151, 21, 563, 203, 445, 6863, 2151, 4999, 8839, 0 }; + static ulong[] dim4440KuoInit = { 1, 3, 5, 9, 25, 57, 15, 29, 3, 127, 871, 1851, 7825, 1593, 11143, 24507, 0 }; + static ulong[] dim4441KuoInit = { 1, 1, 1, 7, 17, 27, 49, 159, 425, 773, 1841, 1693, 7829, 2905, 16347, 5581, 0 }; + static ulong[] dim4442KuoInit = { 1, 3, 5, 7, 13, 29, 81, 77, 349, 747, 119, 1195, 5, 8481, 1543, 50033, 0 }; + static ulong[] dim4443KuoInit = { 1, 1, 7, 15, 1, 25, 33, 13, 9, 565, 555, 699, 4691, 1749, 9531, 30133, 0 }; + static ulong[] dim4444KuoInit = { 1, 1, 5, 5, 13, 43, 17, 31, 199, 381, 393, 3511, 6331, 10377, 31467, 25305, 0 }; + static ulong[] dim4445KuoInit = { 1, 3, 3, 13, 1, 49, 23, 241, 499, 791, 1851, 321, 6057, 2141, 8825, 1829, 0 }; + static ulong[] dim4446KuoInit = { 1, 1, 1, 1, 13, 23, 77, 103, 123, 247, 1655, 1403, 6059, 14505, 1579, 48169, 0 }; + static ulong[] dim4447KuoInit = { 1, 1, 7, 13, 9, 23, 125, 15, 479, 447, 327, 3743, 1199, 5015, 19009, 50929, 0 }; + static ulong[] dim4448KuoInit = { 1, 1, 7, 5, 5, 55, 39, 131, 229, 607, 1591, 769, 2899, 9681, 11789, 62135, 0 }; + static ulong[] dim4449KuoInit = { 1, 3, 3, 13, 17, 59, 65, 117, 299, 85, 1187, 3249, 295, 15603, 28909, 60317, 0 }; + static ulong[] dim4450KuoInit = { 1, 1, 5, 13, 13, 31, 7, 5, 65, 785, 985, 1637, 3015, 14261, 15089, 37337, 0 }; + static ulong[] dim4451KuoInit = { 1, 3, 3, 3, 17, 49, 123, 151, 41, 419, 391, 1265, 6225, 2037, 8409, 13437, 0 }; + static ulong[] dim4452KuoInit = { 1, 1, 5, 13, 1, 23, 111, 21, 381, 343, 519, 1071, 3889, 14897, 9611, 10657, 0 }; + static ulong[] dim4453KuoInit = { 1, 3, 5, 13, 25, 15, 79, 215, 99, 783, 107, 3845, 443, 1115, 24657, 54263, 0 }; + static ulong[] dim4454KuoInit = { 1, 3, 3, 7, 7, 29, 15, 213, 165, 911, 351, 4025, 7657, 2079, 21525, 60751, 0 }; + static ulong[] dim4455KuoInit = { 1, 1, 3, 3, 15, 19, 107, 181, 177, 279, 803, 2825, 4609, 9955, 7725, 44161, 0 }; + static ulong[] dim4456KuoInit = { 1, 1, 3, 7, 21, 9, 69, 107, 43, 239, 397, 2567, 1375, 12483, 19783, 27889, 0 }; + static ulong[] dim4457KuoInit = { 1, 3, 7, 5, 7, 39, 39, 71, 397, 829, 373, 1869, 6229, 2299, 19737, 58479, 0 }; + static ulong[] dim4458KuoInit = { 1, 1, 3, 7, 13, 53, 39, 41, 105, 547, 1687, 153, 4067, 16317, 15, 52949, 0 }; + static ulong[] dim4459KuoInit = { 1, 3, 7, 11, 9, 19, 97, 45, 225, 977, 545, 3691, 5315, 6239, 26833, 28115, 0 }; + static ulong[] dim4460KuoInit = { 1, 3, 7, 3, 23, 11, 17, 13, 437, 145, 1153, 1193, 835, 5095, 5535, 17033, 0 }; + static ulong[] dim4461KuoInit = { 1, 3, 1, 3, 7, 13, 17, 197, 289, 875, 97, 1721, 2369, 8351, 10813, 10129, 0 }; + static ulong[] dim4462KuoInit = { 1, 3, 7, 13, 7, 59, 11, 37, 77, 541, 837, 2943, 423, 6093, 32495, 59203, 0 }; + static ulong[] dim4463KuoInit = { 1, 1, 5, 9, 13, 17, 117, 239, 499, 819, 1585, 1755, 219, 4681, 10771, 14713, 0 }; + static ulong[] dim4464KuoInit = { 1, 3, 1, 9, 15, 21, 3, 123, 303, 223, 1579, 1959, 7767, 6079, 2085, 7683, 0 }; + static ulong[] dim4465KuoInit = { 1, 1, 7, 15, 13, 37, 35, 37, 479, 341, 1315, 3339, 3059, 251, 31629, 32757, 0 }; + static ulong[] dim4466KuoInit = { 1, 1, 5, 11, 19, 23, 55, 109, 443, 77, 577, 1963, 3769, 1783, 5059, 35905, 0 }; + static ulong[] dim4467KuoInit = { 1, 1, 5, 15, 17, 45, 53, 139, 261, 147, 1117, 2255, 1389, 6505, 21785, 52763, 0 }; + static ulong[] dim4468KuoInit = { 1, 1, 7, 15, 21, 61, 97, 147, 397, 231, 775, 3297, 4883, 7059, 16769, 22765, 0 }; + static ulong[] dim4469KuoInit = { 1, 3, 7, 13, 13, 29, 67, 117, 381, 505, 1437, 939, 4551, 8767, 7355, 10507, 0 }; + static ulong[] dim4470KuoInit = { 1, 3, 3, 7, 5, 57, 115, 205, 159, 587, 169, 3787, 1271, 9583, 12205, 63993, 0 }; + static ulong[] dim4471KuoInit = { 1, 3, 3, 13, 9, 59, 51, 165, 159, 391, 421, 2179, 2943, 505, 19315, 16175, 0 }; + static ulong[] dim4472KuoInit = { 1, 3, 5, 13, 21, 53, 95, 131, 275, 421, 435, 2655, 4999, 14225, 26417, 57465, 0 }; + static ulong[] dim4473KuoInit = { 1, 1, 1, 5, 29, 39, 115, 183, 507, 849, 1935, 2849, 6301, 11937, 19519, 37019, 0 }; + static ulong[] dim4474KuoInit = { 1, 1, 5, 1, 13, 15, 37, 25, 113, 885, 1265, 2287, 4535, 12265, 10433, 56641, 0 }; + static ulong[] dim4475KuoInit = { 1, 3, 1, 9, 29, 11, 67, 19, 11, 347, 1659, 3251, 3179, 2583, 10127, 21549, 0 }; + static ulong[] dim4476KuoInit = { 1, 3, 7, 7, 13, 27, 101, 101, 197, 381, 987, 1699, 2913, 5179, 3423, 30389, 0 }; + static ulong[] dim4477KuoInit = { 1, 1, 7, 13, 29, 39, 87, 65, 265, 891, 973, 1487, 6687, 7875, 13389, 39141, 0 }; + static ulong[] dim4478KuoInit = { 1, 1, 1, 3, 7, 13, 101, 223, 181, 143, 1291, 2803, 251, 12541, 20713, 18137, 0 }; + static ulong[] dim4479KuoInit = { 1, 1, 1, 15, 3, 9, 103, 137, 121, 563, 1079, 3119, 5619, 2175, 27223, 25289, 0 }; + static ulong[] dim4480KuoInit = { 1, 3, 3, 15, 7, 13, 109, 201, 385, 347, 319, 883, 13, 3683, 19615, 9781, 0 }; + static ulong[] dim4481KuoInit = { 1, 1, 1, 5, 13, 15, 127, 161, 353, 567, 555, 2287, 1791, 9535, 26227, 15335, 0 }; + static ulong[] dim4482KuoInit = { 1, 1, 5, 9, 3, 63, 11, 83, 235, 741, 977, 2265, 449, 10293, 20451, 25143, 0 }; + static ulong[] dim4483KuoInit = { 1, 1, 3, 3, 23, 25, 119, 1, 381, 463, 67, 257, 7087, 10553, 10781, 60003, 0 }; + static ulong[] dim4484KuoInit = { 1, 3, 7, 15, 17, 11, 81, 17, 363, 163, 1765, 285, 4239, 14777, 15081, 54151, 0 }; + static ulong[] dim4485KuoInit = { 1, 3, 3, 13, 17, 9, 73, 237, 273, 439, 1419, 1539, 667, 13833, 31783, 49459, 0 }; + static ulong[] dim4486KuoInit = { 1, 1, 3, 3, 15, 11, 85, 3, 481, 169, 1443, 3403, 1157, 595, 6851, 59343, 0 }; + static ulong[] dim4487KuoInit = { 1, 3, 7, 1, 23, 21, 13, 251, 403, 859, 175, 1373, 3711, 1233, 16879, 4659, 0 }; + static ulong[] dim4488KuoInit = { 1, 1, 5, 7, 21, 7, 15, 165, 265, 117, 385, 2661, 1481, 1709, 19843, 29639, 0 }; + static ulong[] dim4489KuoInit = { 1, 1, 1, 11, 3, 7, 81, 3, 429, 997, 1759, 285, 375, 3487, 5257, 14203, 0 }; + static ulong[] dim4490KuoInit = { 1, 3, 7, 1, 15, 17, 93, 69, 303, 809, 929, 3025, 6333, 4525, 6441, 32265, 0 }; + static ulong[] dim4491KuoInit = { 1, 3, 1, 5, 27, 41, 119, 25, 461, 347, 369, 489, 377, 3899, 12711, 24475, 0 }; + static ulong[] dim4492KuoInit = { 1, 3, 7, 5, 29, 59, 101, 159, 305, 337, 1371, 891, 6013, 2987, 27201, 61055, 0 }; + static ulong[] dim4493KuoInit = { 1, 1, 1, 3, 19, 5, 3, 219, 71, 213, 137, 1925, 2365, 583, 11591, 9495, 0 }; + static ulong[] dim4494KuoInit = { 1, 3, 7, 3, 31, 31, 85, 115, 169, 499, 1669, 499, 1987, 2505, 435, 6377, 0 }; + static ulong[] dim4495KuoInit = { 1, 1, 3, 5, 3, 33, 33, 41, 199, 187, 1023, 771, 3447, 4355, 29353, 42293, 0 }; + static ulong[] dim4496KuoInit = { 1, 1, 5, 7, 1, 41, 17, 231, 305, 975, 975, 1697, 7267, 9567, 9975, 51313, 0 }; + static ulong[] dim4497KuoInit = { 1, 3, 5, 3, 9, 41, 27, 29, 285, 469, 1845, 665, 3007, 4199, 3367, 50849, 0 }; + static ulong[] dim4498KuoInit = { 1, 1, 5, 9, 29, 5, 93, 63, 227, 751, 1591, 649, 6219, 13371, 3473, 34033, 0 }; + static ulong[] dim4499KuoInit = { 1, 3, 3, 1, 13, 5, 27, 239, 89, 893, 1869, 3789, 7569, 525, 32019, 17501, 0 }; + static ulong[] dim4500KuoInit = { 1, 1, 5, 11, 9, 5, 51, 149, 351, 81, 1895, 3011, 2521, 4185, 1277, 65397, 0 }; + static ulong[] dim4501KuoInit = { 1, 3, 5, 3, 21, 13, 121, 213, 67, 825, 1493, 2933, 6189, 14135, 7021, 47435, 0 }; + static ulong[] dim4502KuoInit = { 1, 3, 7, 15, 11, 51, 63, 163, 371, 363, 1885, 1535, 629, 2939, 12547, 24779, 0 }; + static ulong[] dim4503KuoInit = { 1, 3, 7, 3, 3, 3, 49, 47, 409, 963, 1499, 1107, 8063, 11137, 21251, 4695, 0 }; + static ulong[] dim4504KuoInit = { 1, 1, 3, 1, 31, 17, 61, 149, 263, 503, 219, 3419, 4525, 14689, 30841, 60799, 0 }; + static ulong[] dim4505KuoInit = { 1, 3, 3, 5, 31, 25, 5, 247, 219, 79, 1605, 3523, 4815, 12907, 22017, 16145, 0 }; + static ulong[] dim4506KuoInit = { 1, 1, 7, 11, 21, 51, 47, 85, 37, 461, 1299, 2007, 2093, 10707, 17997, 4221, 0 }; + static ulong[] dim4507KuoInit = { 1, 3, 3, 11, 11, 59, 63, 191, 359, 859, 1265, 853, 6733, 4605, 27559, 32557, 0 }; + static ulong[] dim4508KuoInit = { 1, 3, 7, 11, 29, 61, 119, 73, 73, 259, 1939, 59, 5177, 12375, 22143, 28073, 0 }; + static ulong[] dim4509KuoInit = { 1, 3, 7, 7, 21, 29, 19, 33, 59, 539, 281, 2989, 2239, 6671, 31629, 16065, 0 }; + static ulong[] dim4510KuoInit = { 1, 3, 5, 7, 17, 27, 39, 57, 483, 463, 51, 3771, 5641, 5875, 2369, 21619, 0 }; + static ulong[] dim4511KuoInit = { 1, 3, 1, 1, 15, 9, 121, 217, 107, 615, 1413, 2083, 231, 9177, 12275, 20069, 0 }; + static ulong[] dim4512KuoInit = { 1, 3, 5, 15, 17, 55, 85, 27, 477, 687, 1295, 3471, 6951, 2645, 30051, 36149, 0 }; + static ulong[] dim4513KuoInit = { 1, 3, 3, 1, 1, 27, 9, 183, 39, 559, 1639, 5, 1177, 16011, 1447, 42897, 0 }; + static ulong[] dim4514KuoInit = { 1, 1, 1, 5, 21, 9, 75, 217, 311, 679, 1913, 2623, 3853, 10889, 22501, 40089, 0 }; + static ulong[] dim4515KuoInit = { 1, 3, 5, 7, 17, 59, 23, 199, 147, 339, 1027, 1471, 6539, 7963, 30713, 1939, 0 }; + static ulong[] dim4516KuoInit = { 1, 1, 3, 11, 23, 51, 111, 175, 433, 803, 1577, 4091, 2197, 10003, 2597, 53553, 0 }; + static ulong[] dim4517KuoInit = { 1, 3, 5, 1, 3, 11, 125, 11, 281, 969, 1943, 1003, 2189, 3551, 25831, 64261, 0 }; + static ulong[] dim4518KuoInit = { 1, 3, 7, 1, 17, 19, 111, 235, 511, 723, 1779, 1041, 4067, 3827, 17285, 63075, 0 }; + static ulong[] dim4519KuoInit = { 1, 1, 3, 15, 3, 63, 7, 165, 153, 829, 221, 1485, 4319, 9865, 937, 65171, 0 }; + static ulong[] dim4520KuoInit = { 1, 1, 7, 1, 21, 21, 89, 233, 417, 15, 367, 311, 3575, 11285, 5245, 3947, 0 }; + static ulong[] dim4521KuoInit = { 1, 3, 7, 9, 27, 55, 3, 71, 227, 397, 561, 4075, 5495, 16071, 11495, 48733, 0 }; + static ulong[] dim4522KuoInit = { 1, 3, 3, 3, 3, 39, 57, 219, 237, 151, 1305, 2485, 5045, 5065, 21041, 20055, 0 }; + static ulong[] dim4523KuoInit = { 1, 1, 3, 11, 15, 33, 75, 241, 335, 207, 1695, 119, 839, 12449, 28467, 7445, 0 }; + static ulong[] dim4524KuoInit = { 1, 1, 7, 3, 21, 3, 43, 137, 321, 763, 575, 2317, 8073, 1225, 8257, 11639, 0 }; + static ulong[] dim4525KuoInit = { 1, 3, 5, 11, 27, 21, 17, 115, 265, 1023, 1403, 853, 757, 1799, 25505, 49207, 0 }; + static ulong[] dim4526KuoInit = { 1, 1, 7, 5, 9, 45, 57, 77, 127, 447, 1097, 1729, 2361, 1599, 15727, 49413, 0 }; + static ulong[] dim4527KuoInit = { 1, 1, 1, 15, 21, 41, 13, 41, 183, 151, 441, 3077, 4205, 125, 23767, 44667, 0 }; + static ulong[] dim4528KuoInit = { 1, 3, 3, 9, 3, 37, 5, 203, 39, 49, 1793, 3523, 7541, 23, 22527, 35999, 0 }; + static ulong[] dim4529KuoInit = { 1, 3, 7, 13, 13, 5, 127, 169, 465, 759, 393, 1543, 3327, 6223, 18675, 36075, 0 }; + static ulong[] dim4530KuoInit = { 1, 3, 5, 15, 17, 57, 83, 237, 307, 495, 135, 1461, 4353, 15251, 10005, 12769, 0 }; + static ulong[] dim4531KuoInit = { 1, 1, 7, 13, 27, 49, 57, 19, 463, 97, 217, 2825, 7729, 2375, 8339, 17563, 0 }; + static ulong[] dim4532KuoInit = { 1, 3, 7, 1, 31, 13, 17, 245, 329, 1021, 619, 3149, 7089, 4381, 14079, 35659, 0 }; + static ulong[] dim4533KuoInit = { 1, 3, 5, 15, 31, 19, 15, 217, 115, 159, 281, 2233, 4315, 7429, 25527, 44671, 0 }; + static ulong[] dim4534KuoInit = { 1, 1, 7, 1, 11, 23, 7, 181, 43, 271, 607, 389, 357, 3003, 15899, 50849, 0 }; + static ulong[] dim4535KuoInit = { 1, 1, 7, 15, 11, 15, 41, 247, 37, 163, 665, 3059, 5151, 15335, 13167, 18541, 0 }; + static ulong[] dim4536KuoInit = { 1, 1, 7, 15, 25, 33, 33, 135, 425, 785, 1557, 793, 7153, 13473, 8833, 21335, 0 }; + static ulong[] dim4537KuoInit = { 1, 3, 3, 1, 17, 27, 7, 75, 205, 71, 581, 733, 5009, 1029, 27537, 41905, 0 }; + static ulong[] dim4538KuoInit = { 1, 3, 3, 3, 5, 63, 121, 3, 381, 607, 1099, 1571, 1077, 15491, 13785, 31537, 0 }; + static ulong[] dim4539KuoInit = { 1, 1, 5, 7, 17, 15, 87, 81, 313, 683, 31, 3301, 1683, 12667, 17867, 38405, 0 }; + static ulong[] dim4540KuoInit = { 1, 1, 1, 13, 3, 23, 51, 95, 409, 711, 381, 245, 7, 15679, 14281, 39789, 0 }; + static ulong[] dim4541KuoInit = { 1, 3, 1, 1, 31, 35, 97, 35, 121, 45, 1397, 4009, 2829, 3273, 2725, 913, 0 }; + static ulong[] dim4542KuoInit = { 1, 3, 1, 11, 29, 29, 111, 153, 499, 371, 1767, 3063, 6175, 8205, 3485, 8951, 0 }; + static ulong[] dim4543KuoInit = { 1, 3, 5, 5, 27, 9, 113, 141, 295, 901, 1367, 791, 1645, 5993, 6139, 12853, 0 }; + static ulong[] dim4544KuoInit = { 1, 1, 1, 7, 27, 17, 113, 187, 293, 517, 1327, 579, 1191, 12039, 13973, 51129, 0 }; + static ulong[] dim4545KuoInit = { 1, 1, 7, 3, 11, 9, 55, 71, 47, 787, 1311, 2567, 7555, 2825, 11485, 16787, 0 }; + static ulong[] dim4546KuoInit = { 1, 3, 1, 7, 29, 33, 115, 115, 69, 155, 1185, 2653, 7127, 1449, 8875, 34819, 0 }; + static ulong[] dim4547KuoInit = { 1, 3, 5, 15, 9, 61, 61, 161, 29, 33, 1155, 613, 7233, 2811, 4837, 27781, 0 }; + static ulong[] dim4548KuoInit = { 1, 1, 5, 3, 25, 57, 85, 121, 505, 45, 1143, 3237, 6403, 2377, 30791, 26637, 0 }; + static ulong[] dim4549KuoInit = { 1, 3, 3, 5, 31, 39, 63, 255, 153, 417, 865, 441, 7649, 16321, 29147, 11089, 0 }; + static ulong[] dim4550KuoInit = { 1, 1, 7, 5, 25, 19, 43, 45, 457, 353, 25, 1135, 4663, 11419, 25373, 8411, 0 }; + static ulong[] dim4551KuoInit = { 1, 3, 7, 11, 11, 47, 101, 255, 437, 937, 263, 1171, 7893, 277, 4413, 20197, 0 }; + static ulong[] dim4552KuoInit = { 1, 1, 5, 13, 21, 61, 1, 31, 227, 345, 1535, 1597, 7061, 11595, 12055, 29611, 0 }; + static ulong[] dim4553KuoInit = { 1, 1, 3, 1, 19, 49, 83, 61, 305, 611, 399, 1397, 4753, 2309, 15097, 13439, 0 }; + static ulong[] dim4554KuoInit = { 1, 1, 3, 9, 27, 37, 77, 165, 273, 85, 483, 299, 5073, 1255, 4073, 56333, 0 }; + static ulong[] dim4555KuoInit = { 1, 1, 7, 3, 5, 11, 127, 157, 489, 653, 165, 2071, 4819, 121, 32755, 21623, 0 }; + static ulong[] dim4556KuoInit = { 1, 3, 5, 11, 23, 5, 111, 25, 173, 661, 353, 1167, 2625, 8021, 18731, 42705, 0 }; + static ulong[] dim4557KuoInit = { 1, 3, 5, 15, 9, 33, 31, 137, 283, 925, 1641, 115, 7047, 11365, 13097, 4711, 0 }; + static ulong[] dim4558KuoInit = { 1, 3, 7, 13, 13, 13, 29, 135, 273, 325, 1085, 1683, 1365, 9931, 8557, 3855, 0 }; + static ulong[] dim4559KuoInit = { 1, 3, 5, 13, 17, 27, 103, 183, 237, 343, 907, 2945, 3039, 12873, 28635, 14791, 0 }; + static ulong[] dim4560KuoInit = { 1, 3, 3, 13, 5, 51, 13, 57, 131, 1021, 1995, 921, 6911, 14381, 17113, 56783, 0 }; + static ulong[] dim4561KuoInit = { 1, 3, 5, 5, 5, 55, 89, 29, 409, 687, 1151, 3423, 1893, 12153, 8167, 14849, 0 }; + static ulong[] dim4562KuoInit = { 1, 3, 5, 1, 1, 53, 41, 53, 81, 797, 1665, 85, 8131, 3853, 17815, 7771, 0 }; + static ulong[] dim4563KuoInit = { 1, 1, 7, 3, 31, 41, 37, 107, 319, 421, 279, 2061, 1981, 6917, 25545, 46053, 0 }; + static ulong[] dim4564KuoInit = { 1, 3, 3, 11, 13, 25, 85, 203, 399, 863, 1577, 1445, 8093, 1845, 16307, 61075, 0 }; + static ulong[] dim4565KuoInit = { 1, 1, 5, 5, 1, 35, 117, 201, 271, 901, 1939, 2291, 343, 13591, 28371, 61429, 0 }; + static ulong[] dim4566KuoInit = { 1, 3, 3, 7, 21, 55, 85, 123, 183, 787, 1121, 447, 5761, 6925, 22407, 53149, 0 }; + static ulong[] dim4567KuoInit = { 1, 3, 1, 13, 31, 25, 63, 247, 109, 741, 231, 2621, 4939, 11155, 21625, 30433, 0 }; + static ulong[] dim4568KuoInit = { 1, 1, 5, 15, 3, 49, 63, 147, 117, 703, 1317, 2803, 4655, 5981, 14473, 52739, 0 }; + static ulong[] dim4569KuoInit = { 1, 1, 7, 1, 27, 45, 117, 55, 391, 275, 1793, 1279, 4799, 15509, 17173, 25103, 0 }; + static ulong[] dim4570KuoInit = { 1, 3, 3, 1, 27, 15, 35, 43, 209, 869, 1833, 3625, 5973, 8965, 1443, 59053, 0 }; + static ulong[] dim4571KuoInit = { 1, 1, 1, 1, 1, 19, 93, 63, 407, 735, 1821, 2875, 1263, 1461, 7811, 17257, 0 }; + static ulong[] dim4572KuoInit = { 1, 1, 7, 5, 15, 35, 3, 89, 355, 983, 1183, 2709, 127, 10671, 31223, 26689, 0 }; + static ulong[] dim4573KuoInit = { 1, 3, 3, 3, 15, 29, 105, 239, 293, 57, 515, 363, 5227, 14693, 18437, 13107, 0 }; + static ulong[] dim4574KuoInit = { 1, 1, 5, 1, 29, 61, 65, 77, 23, 311, 1581, 215, 1409, 2575, 13915, 63179, 0 }; + static ulong[] dim4575KuoInit = { 1, 3, 1, 5, 27, 17, 113, 255, 347, 493, 1795, 817, 7483, 10611, 9941, 56425, 0 }; + static ulong[] dim4576KuoInit = { 1, 3, 1, 11, 1, 29, 79, 153, 183, 975, 1127, 881, 1319, 11481, 16807, 23167, 0 }; + static ulong[] dim4577KuoInit = { 1, 1, 5, 15, 7, 31, 107, 245, 59, 579, 423, 2165, 5137, 14735, 13187, 28781, 0 }; + static ulong[] dim4578KuoInit = { 1, 3, 1, 13, 13, 55, 63, 155, 63, 581, 1083, 2249, 7397, 2081, 23727, 23981, 0 }; + static ulong[] dim4579KuoInit = { 1, 3, 7, 9, 23, 29, 93, 215, 361, 71, 119, 3215, 3529, 14249, 29593, 27305, 0 }; + static ulong[] dim4580KuoInit = { 1, 1, 7, 9, 5, 63, 45, 181, 463, 21, 229, 4069, 4889, 2141, 25623, 6191, 0 }; + static ulong[] dim4581KuoInit = { 1, 3, 1, 1, 17, 31, 105, 153, 301, 433, 517, 585, 285, 12805, 30173, 21363, 0 }; + static ulong[] dim4582KuoInit = { 1, 3, 3, 15, 29, 23, 117, 19, 415, 389, 881, 2067, 583, 11383, 24951, 34745, 0 }; + static ulong[] dim4583KuoInit = { 1, 1, 3, 13, 27, 55, 37, 5, 337, 943, 1851, 3227, 3881, 7365, 10853, 23325, 0 }; + static ulong[] dim4584KuoInit = { 1, 3, 1, 11, 25, 5, 39, 189, 503, 745, 1349, 3881, 5037, 13855, 19537, 22329, 0 }; + static ulong[] dim4585KuoInit = { 1, 3, 7, 9, 7, 33, 63, 61, 39, 825, 53, 1471, 3589, 13473, 29241, 40829, 0 }; + static ulong[] dim4586KuoInit = { 1, 1, 7, 1, 1, 37, 111, 251, 427, 427, 937, 3921, 8033, 269, 14261, 37345, 0 }; + static ulong[] dim4587KuoInit = { 1, 1, 7, 7, 31, 59, 111, 205, 285, 113, 951, 2867, 3769, 5237, 693, 42097, 0 }; + static ulong[] dim4588KuoInit = { 1, 1, 1, 15, 29, 43, 15, 253, 383, 783, 1407, 3851, 4333, 11607, 12777, 55499, 0 }; + static ulong[] dim4589KuoInit = { 1, 1, 3, 15, 15, 27, 75, 57, 87, 185, 1079, 2721, 915, 13633, 26439, 10697, 0 }; + static ulong[] dim4590KuoInit = { 1, 1, 7, 13, 17, 63, 43, 65, 5, 699, 1157, 2271, 837, 687, 29551, 22109, 0 }; + static ulong[] dim4591KuoInit = { 1, 3, 7, 3, 5, 47, 103, 143, 281, 81, 283, 3073, 3741, 11525, 4499, 41325, 0 }; + static ulong[] dim4592KuoInit = { 1, 3, 7, 11, 13, 19, 63, 215, 215, 21, 1443, 2485, 2661, 8123, 11739, 48729, 0 }; + static ulong[] dim4593KuoInit = { 1, 3, 3, 3, 27, 13, 111, 153, 17, 715, 1453, 1827, 5201, 1139, 19531, 18853, 0 }; + static ulong[] dim4594KuoInit = { 1, 3, 7, 15, 7, 61, 109, 213, 383, 483, 301, 1791, 559, 14205, 28441, 13179, 0 }; + static ulong[] dim4595KuoInit = { 1, 1, 7, 7, 23, 55, 119, 45, 467, 775, 951, 2533, 6703, 15791, 12891, 54513, 0 }; + static ulong[] dim4596KuoInit = { 1, 1, 7, 15, 19, 49, 71, 127, 455, 881, 329, 663, 4997, 8755, 17517, 31507, 0 }; + static ulong[] dim4597KuoInit = { 1, 1, 5, 9, 9, 13, 75, 161, 109, 631, 153, 15, 1181, 14299, 11815, 32017, 0 }; + static ulong[] dim4598KuoInit = { 1, 3, 5, 15, 9, 63, 101, 85, 487, 213, 1743, 2575, 6979, 14421, 18051, 14505, 0 }; + static ulong[] dim4599KuoInit = { 1, 1, 5, 7, 5, 5, 109, 245, 427, 765, 2013, 2929, 6737, 14561, 32227, 60605, 0 }; + static ulong[] dim4600KuoInit = { 1, 3, 1, 3, 1, 7, 17, 169, 27, 925, 1711, 101, 2065, 4857, 863, 38371, 0 }; + static ulong[] dim4601KuoInit = { 1, 1, 7, 5, 5, 25, 119, 145, 27, 377, 1535, 441, 5181, 9789, 26757, 46977, 0 }; + static ulong[] dim4602KuoInit = { 1, 1, 7, 5, 31, 1, 79, 223, 199, 409, 2033, 1781, 5269, 2631, 10627, 41785, 0 }; + static ulong[] dim4603KuoInit = { 1, 3, 5, 3, 29, 7, 91, 123, 407, 19, 847, 4019, 1029, 15763, 30265, 49287, 0 }; + static ulong[] dim4604KuoInit = { 1, 1, 3, 9, 1, 37, 33, 53, 49, 949, 1737, 229, 3419, 5125, 16365, 48867, 0 }; + static ulong[] dim4605KuoInit = { 1, 3, 7, 9, 25, 17, 13, 31, 27, 53, 287, 4021, 7687, 14511, 12627, 54409, 0 }; + static ulong[] dim4606KuoInit = { 1, 1, 3, 9, 21, 29, 1, 193, 479, 895, 605, 2013, 6571, 14073, 28185, 58845, 0 }; + static ulong[] dim4607KuoInit = { 1, 3, 5, 11, 3, 21, 111, 215, 259, 941, 1729, 645, 695, 3295, 23825, 1009, 0 }; + static ulong[] dim4608KuoInit = { 1, 3, 3, 9, 25, 17, 103, 187, 153, 287, 911, 1265, 41, 1687, 22443, 21117, 0 }; + static ulong[] dim4609KuoInit = { 1, 3, 5, 5, 31, 25, 3, 107, 271, 531, 1413, 2813, 5075, 2127, 18647, 5257, 0 }; + static ulong[] dim4610KuoInit = { 1, 1, 1, 7, 5, 25, 71, 225, 391, 877, 1713, 1841, 3239, 9063, 11445, 48693, 0 }; + static ulong[] dim4611KuoInit = { 1, 1, 1, 13, 21, 25, 15, 157, 59, 37, 1349, 413, 6401, 3533, 6019, 40373, 0 }; + static ulong[] dim4612KuoInit = { 1, 1, 5, 5, 5, 3, 31, 185, 59, 933, 1415, 901, 6075, 4839, 32477, 43085, 0 }; + static ulong[] dim4613KuoInit = { 1, 3, 1, 5, 11, 7, 81, 109, 167, 277, 1803, 39, 7421, 15573, 2233, 8193, 0 }; + static ulong[] dim4614KuoInit = { 1, 3, 1, 1, 13, 15, 47, 109, 279, 515, 1393, 1785, 4297, 813, 19177, 5951, 0 }; + static ulong[] dim4615KuoInit = { 1, 3, 3, 1, 21, 23, 3, 27, 317, 677, 1775, 1109, 93, 9007, 8767, 42181, 0 }; + static ulong[] dim4616KuoInit = { 1, 3, 5, 13, 23, 15, 49, 9, 369, 293, 529, 2115, 4781, 1955, 21897, 22871, 0 }; + static ulong[] dim4617KuoInit = { 1, 1, 7, 9, 5, 39, 85, 85, 405, 837, 1891, 27, 509, 14643, 10497, 34021, 0 }; + static ulong[] dim4618KuoInit = { 1, 1, 7, 9, 7, 47, 49, 87, 481, 1003, 741, 329, 2951, 5317, 21601, 20485, 0 }; + static ulong[] dim4619KuoInit = { 1, 3, 5, 11, 27, 61, 45, 251, 489, 623, 1673, 891, 5429, 4457, 23147, 5201, 0 }; + static ulong[] dim4620KuoInit = { 1, 3, 3, 7, 25, 27, 3, 233, 193, 253, 483, 1881, 6753, 7843, 3975, 23413, 0 }; + static ulong[] dim4621KuoInit = { 1, 3, 1, 15, 27, 31, 51, 213, 463, 995, 1127, 3589, 1409, 15743, 22755, 39913, 0 }; + static ulong[] dim4622KuoInit = { 1, 3, 1, 13, 21, 17, 35, 157, 233, 899, 1003, 201, 3425, 6703, 26585, 18389, 0 }; + static ulong[] dim4623KuoInit = { 1, 3, 1, 9, 11, 23, 69, 93, 361, 177, 1071, 3523, 4117, 6107, 3701, 64213, 0 }; + static ulong[] dim4624KuoInit = { 1, 3, 5, 1, 19, 1, 35, 95, 385, 853, 1635, 1815, 5307, 3155, 11347, 39289, 0 }; + static ulong[] dim4625KuoInit = { 1, 1, 7, 9, 3, 41, 37, 161, 293, 1005, 1915, 2867, 841, 195, 4247, 8621, 0 }; + static ulong[] dim4626KuoInit = { 1, 3, 7, 11, 19, 43, 69, 95, 455, 669, 217, 129, 1275, 8431, 22519, 39261, 0 }; + static ulong[] dim4627KuoInit = { 1, 3, 7, 13, 31, 49, 105, 61, 437, 923, 1579, 1695, 7129, 10555, 3177, 6667, 0 }; + static ulong[] dim4628KuoInit = { 1, 1, 5, 7, 3, 47, 29, 159, 207, 969, 433, 3541, 689, 1255, 1359, 38349, 0 }; + static ulong[] dim4629KuoInit = { 1, 1, 3, 9, 9, 31, 23, 37, 435, 729, 121, 2483, 8009, 14229, 6961, 40681, 0 }; + static ulong[] dim4630KuoInit = { 1, 3, 1, 7, 19, 33, 111, 131, 155, 641, 795, 3753, 4381, 11135, 8381, 62553, 0 }; + static ulong[] dim4631KuoInit = { 1, 3, 7, 13, 29, 37, 15, 245, 341, 1023, 1123, 3317, 2409, 8957, 4607, 53947, 0 }; + static ulong[] dim4632KuoInit = { 1, 1, 7, 15, 7, 19, 105, 187, 407, 339, 607, 11, 1679, 13701, 2385, 6203, 0 }; + static ulong[] dim4633KuoInit = { 1, 3, 3, 9, 7, 63, 7, 173, 475, 87, 807, 1467, 791, 1949, 20839, 54179, 0 }; + static ulong[] dim4634KuoInit = { 1, 3, 3, 3, 25, 25, 111, 155, 249, 55, 1455, 2503, 6869, 14463, 10519, 56761, 0 }; + static ulong[] dim4635KuoInit = { 1, 3, 1, 9, 9, 31, 89, 235, 499, 61, 747, 487, 6767, 4777, 12513, 43677, 0 }; + static ulong[] dim4636KuoInit = { 1, 3, 3, 5, 25, 47, 13, 3, 313, 541, 1323, 3551, 7971, 1453, 1531, 38915, 0 }; + static ulong[] dim4637KuoInit = { 1, 1, 1, 5, 7, 63, 125, 243, 199, 875, 791, 103, 3997, 16199, 20615, 18359, 0 }; + static ulong[] dim4638KuoInit = { 1, 1, 7, 1, 21, 19, 13, 9, 117, 625, 1333, 561, 889, 10961, 11313, 48139, 0 }; + static ulong[] dim4639KuoInit = { 1, 3, 5, 9, 19, 57, 121, 163, 333, 681, 1065, 885, 5961, 6385, 20135, 19733, 0 }; + static ulong[] dim4640KuoInit = { 1, 1, 7, 13, 27, 11, 113, 187, 91, 83, 591, 517, 7379, 12823, 31815, 14721, 0 }; + static ulong[] dim4641KuoInit = { 1, 3, 5, 7, 27, 21, 47, 203, 411, 191, 881, 2597, 6107, 135, 14525, 4059, 0 }; + static ulong[] dim4642KuoInit = { 1, 3, 5, 7, 29, 3, 61, 231, 259, 425, 1953, 803, 7921, 2321, 28919, 41349, 0 }; + static ulong[] dim4643KuoInit = { 1, 3, 1, 1, 27, 7, 87, 197, 287, 345, 457, 1813, 2701, 2095, 32705, 52579, 0 }; + static ulong[] dim4644KuoInit = { 1, 3, 3, 9, 13, 59, 87, 105, 49, 387, 73, 2983, 6453, 10977, 8851, 61031, 0 }; + static ulong[] dim4645KuoInit = { 1, 3, 5, 7, 1, 53, 121, 129, 307, 251, 1405, 3093, 4487, 1953, 2681, 4391, 0 }; + static ulong[] dim4646KuoInit = { 1, 1, 3, 1, 1, 29, 119, 125, 95, 425, 385, 1577, 3387, 14709, 25143, 4317, 0 }; + static ulong[] dim4647KuoInit = { 1, 3, 1, 3, 27, 59, 53, 203, 75, 731, 1019, 3179, 4533, 3217, 30801, 53439, 0 }; + static ulong[] dim4648KuoInit = { 1, 1, 3, 11, 29, 53, 93, 251, 441, 75, 363, 2405, 6263, 12121, 11963, 13219, 0 }; + static ulong[] dim4649KuoInit = { 1, 3, 1, 13, 3, 7, 57, 169, 387, 543, 1027, 1169, 5089, 5077, 17933, 8131, 0 }; + static ulong[] dim4650KuoInit = { 1, 1, 3, 5, 17, 17, 123, 161, 21, 641, 795, 2415, 2743, 1489, 25137, 19393, 0 }; + static ulong[] dim4651KuoInit = { 1, 3, 3, 1, 1, 47, 37, 95, 315, 37, 1481, 2189, 687, 2859, 5339, 26907, 0 }; + static ulong[] dim4652KuoInit = { 1, 3, 7, 15, 23, 51, 71, 203, 237, 777, 417, 2767, 5243, 1453, 17269, 27679, 0 }; + static ulong[] dim4653KuoInit = { 1, 3, 1, 15, 17, 41, 29, 45, 363, 77, 1071, 3419, 6453, 13897, 25275, 26379, 0 }; + static ulong[] dim4654KuoInit = { 1, 3, 7, 11, 21, 5, 89, 133, 339, 971, 1581, 377, 6563, 13073, 24521, 41107, 0 }; + static ulong[] dim4655KuoInit = { 1, 1, 7, 15, 1, 27, 57, 249, 511, 833, 269, 2771, 4127, 12567, 27359, 22105, 0 }; + static ulong[] dim4656KuoInit = { 1, 1, 3, 5, 31, 47, 63, 221, 25, 869, 1947, 3075, 6857, 13507, 16601, 29621, 0 }; + static ulong[] dim4657KuoInit = { 1, 1, 3, 7, 17, 23, 109, 169, 211, 407, 1147, 2453, 2281, 10763, 11539, 49127, 0 }; + static ulong[] dim4658KuoInit = { 1, 1, 3, 11, 27, 25, 111, 75, 465, 67, 1641, 3623, 7957, 14307, 17469, 52229, 0 }; + static ulong[] dim4659KuoInit = { 1, 3, 1, 5, 23, 31, 49, 131, 351, 311, 1937, 2181, 7485, 10883, 20843, 33447, 0 }; + static ulong[] dim4660KuoInit = { 1, 3, 1, 3, 5, 47, 81, 47, 305, 567, 219, 2495, 1207, 14359, 4683, 53717, 0 }; + static ulong[] dim4661KuoInit = { 1, 1, 3, 3, 29, 43, 107, 81, 227, 795, 1261, 3887, 6177, 6219, 2557, 53203, 0 }; + static ulong[] dim4662KuoInit = { 1, 3, 1, 9, 25, 47, 87, 177, 511, 899, 1967, 601, 3659, 3961, 27301, 9497, 0 }; + static ulong[] dim4663KuoInit = { 1, 1, 5, 11, 7, 19, 69, 95, 319, 811, 1539, 931, 6609, 4325, 4639, 60125, 0 }; + static ulong[] dim4664KuoInit = { 1, 3, 3, 13, 31, 25, 65, 137, 67, 903, 1519, 3, 81, 9991, 24985, 12571, 0 }; + static ulong[] dim4665KuoInit = { 1, 3, 1, 15, 13, 45, 87, 95, 185, 531, 591, 3649, 2289, 6353, 4305, 12801, 0 }; + static ulong[] dim4666KuoInit = { 1, 3, 7, 11, 13, 49, 79, 205, 9, 457, 151, 3363, 1865, 12337, 3601, 23781, 0 }; + static ulong[] dim4667KuoInit = { 1, 3, 3, 7, 21, 7, 117, 177, 327, 547, 385, 301, 5595, 14389, 8243, 3133, 0 }; + static ulong[] dim4668KuoInit = { 1, 3, 1, 3, 17, 39, 61, 45, 489, 769, 1893, 1633, 2645, 10849, 3827, 41365, 0 }; + static ulong[] dim4669KuoInit = { 1, 1, 1, 11, 11, 43, 93, 81, 497, 731, 1049, 91, 7979, 4707, 8757, 54837, 0 }; + static ulong[] dim4670KuoInit = { 1, 1, 3, 7, 1, 63, 127, 173, 137, 291, 473, 3095, 6291, 14415, 20763, 45687, 0 }; + static ulong[] dim4671KuoInit = { 1, 1, 5, 13, 29, 59, 73, 47, 171, 1001, 537, 2009, 5057, 15013, 22195, 56067, 0 }; + static ulong[] dim4672KuoInit = { 1, 1, 3, 5, 21, 35, 121, 169, 377, 389, 1209, 415, 2641, 10423, 11327, 64157, 0 }; + static ulong[] dim4673KuoInit = { 1, 1, 7, 1, 23, 43, 59, 205, 39, 455, 633, 1965, 7955, 305, 12245, 45229, 0 }; + static ulong[] dim4674KuoInit = { 1, 3, 1, 15, 15, 27, 49, 77, 407, 549, 1159, 1701, 7331, 6421, 1799, 43539, 0 }; + static ulong[] dim4675KuoInit = { 1, 3, 5, 3, 5, 33, 41, 127, 141, 149, 1957, 2823, 1303, 7339, 25253, 32329, 0 }; + static ulong[] dim4676KuoInit = { 1, 1, 5, 15, 5, 37, 119, 111, 329, 781, 983, 2021, 1191, 1579, 4191, 24065, 0 }; + static ulong[] dim4677KuoInit = { 1, 3, 7, 9, 7, 11, 25, 111, 301, 819, 1073, 2311, 2357, 6385, 17015, 8051, 0 }; + static ulong[] dim4678KuoInit = { 1, 1, 1, 9, 29, 63, 91, 101, 71, 679, 267, 2909, 5359, 2305, 2523, 32423, 0 }; + static ulong[] dim4679KuoInit = { 1, 3, 1, 5, 11, 45, 107, 95, 487, 605, 1647, 1977, 5305, 8855, 9057, 7809, 0 }; + static ulong[] dim4680KuoInit = { 1, 1, 1, 1, 5, 45, 51, 51, 97, 775, 1559, 935, 7421, 2823, 11415, 49193, 0 }; + static ulong[] dim4681KuoInit = { 1, 3, 3, 5, 23, 63, 99, 189, 175, 77, 675, 4021, 899, 11315, 18627, 46175, 0 }; + static ulong[] dim4682KuoInit = { 1, 1, 3, 13, 9, 31, 67, 235, 409, 541, 2013, 2715, 2121, 3695, 11953, 5745, 0 }; + static ulong[] dim4683KuoInit = { 1, 3, 5, 1, 13, 3, 15, 111, 455, 849, 231, 2711, 6831, 7813, 17173, 26019, 0 }; + static ulong[] dim4684KuoInit = { 1, 1, 1, 15, 19, 3, 21, 135, 275, 891, 61, 5, 2901, 15727, 18015, 55741, 0 }; + static ulong[] dim4685KuoInit = { 1, 3, 1, 5, 5, 31, 5, 147, 353, 199, 229, 3821, 537, 11667, 649, 33923, 0 }; + static ulong[] dim4686KuoInit = { 1, 1, 7, 13, 3, 9, 75, 217, 423, 487, 723, 4091, 7075, 819, 2755, 13593, 0 }; + static ulong[] dim4687KuoInit = { 1, 1, 1, 9, 25, 45, 69, 41, 183, 547, 69, 3591, 1331, 5701, 25891, 26553, 0 }; + static ulong[] dim4688KuoInit = { 1, 3, 3, 13, 29, 51, 79, 153, 145, 923, 1345, 3113, 93, 10617, 12865, 27341, 0 }; + static ulong[] dim4689KuoInit = { 1, 3, 3, 13, 13, 61, 67, 115, 295, 767, 1077, 3959, 7741, 16145, 3571, 38941, 0 }; + static ulong[] dim4690KuoInit = { 1, 1, 3, 3, 1, 11, 25, 33, 481, 901, 135, 2093, 3531, 12137, 4521, 42301, 0 }; + static ulong[] dim4691KuoInit = { 1, 1, 3, 1, 9, 59, 105, 71, 57, 131, 1491, 3259, 4125, 10279, 7537, 38827, 0 }; + static ulong[] dim4692KuoInit = { 1, 3, 7, 13, 7, 53, 83, 43, 243, 423, 43, 2021, 4269, 1793, 9969, 55429, 0 }; + static ulong[] dim4693KuoInit = { 1, 1, 3, 11, 17, 57, 73, 55, 369, 975, 603, 1893, 3299, 12177, 8965, 17159, 0 }; + static ulong[] dim4694KuoInit = { 1, 3, 5, 11, 23, 11, 61, 11, 119, 905, 1841, 2597, 691, 6237, 2285, 33503, 0 }; + static ulong[] dim4695KuoInit = { 1, 3, 5, 3, 21, 17, 35, 169, 511, 1009, 1287, 3967, 1543, 6983, 6895, 24959, 0 }; + static ulong[] dim4696KuoInit = { 1, 1, 1, 13, 23, 9, 21, 47, 119, 323, 1255, 3601, 3157, 14041, 32065, 4759, 0 }; + static ulong[] dim4697KuoInit = { 1, 1, 7, 15, 9, 1, 103, 43, 485, 281, 1651, 1957, 4215, 2105, 24455, 51001, 0 }; + static ulong[] dim4698KuoInit = { 1, 1, 5, 7, 11, 11, 59, 31, 351, 275, 573, 2481, 2545, 15767, 4319, 63375, 0 }; + static ulong[] dim4699KuoInit = { 1, 3, 1, 1, 1, 41, 41, 13, 33, 693, 1035, 905, 6129, 11131, 23571, 28789, 0 }; + static ulong[] dim4700KuoInit = { 1, 1, 7, 11, 9, 39, 119, 31, 109, 837, 1905, 763, 3737, 16031, 8751, 17307, 0 }; + static ulong[] dim4701KuoInit = { 1, 3, 3, 7, 17, 49, 77, 199, 33, 185, 1489, 445, 5495, 13693, 21453, 21039, 0 }; + static ulong[] dim4702KuoInit = { 1, 3, 5, 15, 5, 9, 113, 179, 315, 85, 1559, 1505, 593, 259, 10393, 39025, 0 }; + static ulong[] dim4703KuoInit = { 1, 1, 1, 5, 31, 33, 41, 45, 313, 513, 861, 2697, 4767, 10737, 25019, 12715, 0 }; + static ulong[] dim4704KuoInit = { 1, 3, 3, 1, 19, 21, 19, 19, 127, 1009, 859, 829, 6887, 5407, 28491, 61079, 0 }; + static ulong[] dim4705KuoInit = { 1, 1, 3, 15, 15, 35, 69, 255, 367, 889, 49, 3237, 3269, 1559, 26337, 16967, 0 }; + static ulong[] dim4706KuoInit = { 1, 1, 5, 3, 17, 5, 125, 171, 505, 981, 773, 2973, 2905, 1537, 17729, 52289, 0 }; + static ulong[] dim4707KuoInit = { 1, 1, 3, 3, 29, 5, 57, 247, 149, 707, 673, 429, 7583, 12135, 5405, 313, 0 }; + static ulong[] dim4708KuoInit = { 1, 1, 3, 13, 31, 35, 117, 69, 413, 723, 645, 3989, 6461, 77, 29713, 32381, 0 }; + static ulong[] dim4709KuoInit = { 1, 3, 3, 13, 11, 59, 5, 53, 507, 355, 335, 4027, 3111, 8385, 22369, 42907, 0 }; + static ulong[] dim4710KuoInit = { 1, 1, 5, 9, 1, 47, 87, 13, 397, 693, 1745, 2907, 3919, 14843, 869, 24161, 0 }; + static ulong[] dim4711KuoInit = { 1, 3, 7, 13, 11, 25, 25, 153, 501, 305, 941, 2379, 2587, 8225, 27951, 14809, 0 }; + static ulong[] dim4712KuoInit = { 1, 1, 7, 3, 31, 7, 9, 47, 129, 611, 1367, 1575, 4421, 2277, 8113, 34229, 0 }; + static ulong[] dim4713KuoInit = { 1, 1, 5, 11, 7, 41, 65, 5, 289, 799, 1143, 291, 243, 12957, 2729, 14589, 0 }; + static ulong[] dim4714KuoInit = { 1, 3, 3, 7, 15, 29, 49, 243, 191, 565, 271, 2485, 1507, 13479, 3541, 10039, 0 }; + static ulong[] dim4715KuoInit = { 1, 3, 5, 3, 25, 29, 113, 157, 357, 891, 199, 3113, 7133, 11047, 27517, 26795, 0 }; + static ulong[] dim4716KuoInit = { 1, 1, 3, 15, 27, 23, 5, 207, 183, 85, 247, 15, 5559, 8005, 32485, 26403, 0 }; + static ulong[] dim4717KuoInit = { 1, 1, 3, 9, 13, 9, 87, 9, 237, 875, 1621, 2955, 4105, 9645, 9613, 31235, 0 }; + static ulong[] dim4718KuoInit = { 1, 1, 7, 11, 17, 3, 77, 241, 75, 433, 1481, 1901, 6249, 12411, 18975, 18911, 0 }; + static ulong[] dim4719KuoInit = { 1, 3, 5, 15, 3, 43, 99, 197, 407, 161, 1103, 587, 6695, 255, 15571, 7523, 0 }; + static ulong[] dim4720KuoInit = { 1, 1, 1, 13, 1, 21, 9, 155, 447, 785, 1573, 2497, 1515, 6031, 23509, 38199, 0 }; + static ulong[] dim4721KuoInit = { 1, 1, 5, 15, 23, 43, 125, 187, 57, 259, 941, 1213, 2303, 1127, 31819, 53539, 0 }; + static ulong[] dim4722KuoInit = { 1, 3, 3, 9, 23, 19, 29, 83, 431, 79, 781, 1887, 4857, 2079, 11521, 64925, 0 }; + static ulong[] dim4723KuoInit = { 1, 3, 5, 5, 23, 11, 33, 107, 127, 173, 223, 491, 1529, 14655, 18857, 25247, 0 }; + static ulong[] dim4724KuoInit = { 1, 3, 3, 9, 17, 53, 119, 159, 503, 153, 697, 657, 6207, 7659, 23899, 10347, 0 }; + static ulong[] dim4725KuoInit = { 1, 3, 1, 15, 13, 37, 117, 219, 341, 983, 193, 1641, 7811, 11961, 12553, 9467, 0 }; + static ulong[] dim4726KuoInit = { 1, 1, 7, 5, 27, 11, 35, 45, 89, 535, 965, 1269, 1243, 3987, 4629, 45335, 0 }; + static ulong[] dim4727KuoInit = { 1, 1, 7, 1, 17, 25, 79, 133, 287, 7, 269, 697, 2537, 241, 15747, 49429, 0 }; + static ulong[] dim4728KuoInit = { 1, 3, 3, 3, 27, 63, 23, 229, 3, 625, 453, 3037, 5747, 13525, 28835, 13411, 0 }; + static ulong[] dim4729KuoInit = { 1, 3, 5, 5, 25, 57, 101, 13, 81, 917, 1849, 3931, 3319, 1353, 8253, 28897, 0 }; + static ulong[] dim4730KuoInit = { 1, 1, 3, 15, 3, 41, 89, 165, 1, 935, 1859, 2881, 4351, 6737, 12361, 27821, 0 }; + static ulong[] dim4731KuoInit = { 1, 3, 5, 3, 9, 45, 89, 251, 77, 899, 777, 4063, 8111, 5953, 26645, 62567, 0 }; + static ulong[] dim4732KuoInit = { 1, 3, 5, 1, 25, 7, 15, 189, 157, 751, 627, 629, 2875, 11143, 23841, 58751, 0 }; + static ulong[] dim4733KuoInit = { 1, 1, 1, 9, 7, 43, 95, 171, 311, 809, 971, 1317, 3521, 15227, 18155, 11409, 0 }; + static ulong[] dim4734KuoInit = { 1, 3, 3, 7, 29, 7, 69, 1, 235, 699, 971, 3149, 71, 3609, 859, 17059, 0 }; + static ulong[] dim4735KuoInit = { 1, 3, 1, 1, 3, 43, 3, 181, 465, 843, 1391, 3313, 8115, 1835, 32365, 31303, 0 }; + static ulong[] dim4736KuoInit = { 1, 1, 5, 1, 27, 49, 15, 37, 257, 365, 1577, 3037, 2767, 8183, 173, 43089, 0 }; + static ulong[] dim4737KuoInit = { 1, 1, 1, 7, 7, 29, 81, 33, 299, 827, 221, 2049, 1163, 13023, 6755, 53987, 0 }; + static ulong[] dim4738KuoInit = { 1, 3, 1, 11, 19, 17, 63, 19, 469, 925, 37, 3291, 2699, 10083, 32197, 53749, 0 }; + static ulong[] dim4739KuoInit = { 1, 3, 5, 15, 1, 23, 71, 173, 441, 109, 391, 3611, 7515, 5095, 26379, 55999, 0 }; + static ulong[] dim4740KuoInit = { 1, 3, 3, 13, 29, 13, 23, 57, 329, 285, 1595, 2681, 5427, 3251, 7025, 3921, 0 }; + static ulong[] dim4741KuoInit = { 1, 1, 1, 13, 7, 45, 121, 19, 19, 317, 1619, 2245, 7151, 5797, 31369, 7765, 0 }; + static ulong[] dim4742KuoInit = { 1, 3, 7, 13, 9, 17, 11, 127, 337, 271, 2005, 787, 1017, 3075, 29453, 62275, 0 }; + static ulong[] dim4743KuoInit = { 1, 3, 3, 13, 9, 51, 77, 31, 395, 175, 247, 1021, 4343, 3829, 959, 12069, 0 }; + static ulong[] dim4744KuoInit = { 1, 3, 1, 9, 21, 33, 3, 129, 327, 13, 1943, 3305, 6173, 6903, 32539, 9525, 0 }; + static ulong[] dim4745KuoInit = { 1, 1, 3, 15, 23, 5, 49, 125, 445, 849, 547, 2911, 7611, 8137, 28701, 6883, 0 }; + static ulong[] dim4746KuoInit = { 1, 1, 3, 13, 11, 15, 21, 35, 303, 401, 187, 1981, 7919, 6179, 15643, 10327, 0 }; + static ulong[] dim4747KuoInit = { 1, 1, 5, 7, 9, 45, 95, 205, 137, 425, 353, 673, 1337, 4357, 12521, 55229, 0 }; + static ulong[] dim4748KuoInit = { 1, 3, 5, 5, 29, 47, 93, 213, 357, 821, 467, 395, 5079, 10341, 24117, 59757, 0 }; + static ulong[] dim4749KuoInit = { 1, 3, 7, 5, 29, 39, 25, 85, 437, 873, 795, 91, 1979, 15503, 12157, 6803, 0 }; + static ulong[] dim4750KuoInit = { 1, 3, 7, 1, 31, 21, 31, 245, 79, 661, 323, 1843, 2225, 15383, 17507, 30667, 0 }; + static ulong[] dim4751KuoInit = { 1, 3, 5, 11, 1, 11, 119, 151, 489, 303, 835, 319, 2071, 1497, 10343, 40641, 0 }; + static ulong[] dim4752KuoInit = { 1, 1, 1, 13, 7, 7, 125, 237, 103, 65, 1917, 2203, 5895, 8651, 7331, 27591, 0 }; + static ulong[] dim4753KuoInit = { 1, 3, 3, 15, 21, 17, 73, 21, 485, 985, 253, 1877, 7423, 6569, 25971, 57821, 0 }; + static ulong[] dim4754KuoInit = { 1, 3, 5, 13, 3, 59, 9, 77, 99, 851, 343, 2655, 367, 7253, 16357, 61563, 0 }; + static ulong[] dim4755KuoInit = { 1, 3, 7, 13, 11, 1, 15, 227, 223, 317, 1111, 2287, 4035, 6803, 16787, 27797, 0 }; + static ulong[] dim4756KuoInit = { 1, 3, 3, 5, 17, 49, 103, 191, 245, 473, 2007, 3297, 6487, 7371, 30497, 40255, 0 }; + static ulong[] dim4757KuoInit = { 1, 3, 5, 13, 1, 61, 39, 1, 501, 665, 1085, 3933, 855, 883, 26949, 48761, 0 }; + static ulong[] dim4758KuoInit = { 1, 3, 3, 13, 29, 39, 5, 43, 39, 529, 1605, 2235, 5081, 7467, 20727, 48611, 0 }; + static ulong[] dim4759KuoInit = { 1, 1, 3, 11, 19, 61, 89, 15, 149, 639, 337, 2953, 2229, 11161, 21981, 26003, 0 }; + static ulong[] dim4760KuoInit = { 1, 1, 3, 5, 29, 47, 71, 65, 107, 485, 57, 2255, 4383, 12383, 18161, 40233, 0 }; + static ulong[] dim4761KuoInit = { 1, 1, 7, 3, 21, 41, 75, 133, 141, 343, 633, 2043, 2441, 5479, 2493, 45707, 0 }; + static ulong[] dim4762KuoInit = { 1, 1, 7, 15, 21, 37, 19, 73, 361, 195, 1007, 1265, 4075, 1383, 11809, 64265, 0 }; + static ulong[] dim4763KuoInit = { 1, 1, 5, 11, 19, 63, 21, 163, 349, 961, 1221, 2265, 4801, 14049, 8655, 32823, 0 }; + static ulong[] dim4764KuoInit = { 1, 1, 5, 1, 9, 1, 101, 37, 473, 293, 1191, 791, 5327, 13739, 21761, 5755, 0 }; + static ulong[] dim4765KuoInit = { 1, 1, 1, 15, 23, 57, 63, 195, 451, 627, 1725, 2405, 6943, 6855, 31563, 44699, 0 }; + static ulong[] dim4766KuoInit = { 1, 3, 7, 1, 31, 41, 51, 177, 95, 961, 1407, 2847, 7, 8975, 4017, 46229, 0 }; + static ulong[] dim4767KuoInit = { 1, 1, 3, 13, 19, 9, 67, 183, 255, 1, 1769, 2585, 2157, 9747, 32047, 13063, 0 }; + static ulong[] dim4768KuoInit = { 1, 3, 3, 1, 21, 39, 31, 117, 397, 441, 1443, 3849, 5993, 13981, 23579, 40637, 0 }; + static ulong[] dim4769KuoInit = { 1, 1, 7, 1, 31, 23, 61, 203, 111, 273, 1693, 3031, 4125, 1527, 30525, 17465, 0 }; + static ulong[] dim4770KuoInit = { 1, 3, 5, 9, 19, 39, 127, 51, 419, 205, 425, 1939, 3703, 12009, 6291, 48639, 0 }; + static ulong[] dim4771KuoInit = { 1, 3, 5, 13, 15, 27, 63, 239, 483, 181, 1621, 3789, 1929, 11115, 29385, 53075, 0 }; + static ulong[] dim4772KuoInit = { 1, 1, 1, 9, 13, 9, 61, 15, 221, 163, 1645, 419, 639, 15081, 2097, 42133, 0 }; + static ulong[] dim4773KuoInit = { 1, 3, 1, 7, 7, 31, 27, 141, 215, 645, 1293, 2237, 7129, 12619, 14563, 46081, 0 }; + static ulong[] dim4774KuoInit = { 1, 3, 1, 13, 3, 41, 85, 37, 295, 815, 1417, 3083, 5873, 2037, 29909, 3817, 0 }; + static ulong[] dim4775KuoInit = { 1, 3, 3, 9, 11, 49, 77, 103, 189, 319, 439, 3547, 173, 1105, 12125, 49989, 0 }; + static ulong[] dim4776KuoInit = { 1, 3, 1, 15, 21, 9, 5, 37, 87, 905, 145, 1151, 2213, 4157, 16171, 56121, 0 }; + static ulong[] dim4777KuoInit = { 1, 3, 5, 3, 15, 21, 91, 103, 367, 423, 101, 327, 3819, 3141, 3515, 11433, 0 }; + static ulong[] dim4778KuoInit = { 1, 3, 1, 13, 13, 11, 61, 175, 265, 1011, 1825, 937, 983, 9575, 6053, 19633, 0 }; + static ulong[] dim4779KuoInit = { 1, 3, 3, 9, 25, 47, 55, 233, 397, 325, 1217, 1691, 2751, 5339, 14269, 28791, 0 }; + static ulong[] dim4780KuoInit = { 1, 1, 7, 15, 15, 51, 29, 215, 47, 713, 1879, 1981, 3087, 9945, 8959, 59367, 0 }; + static ulong[] dim4781KuoInit = { 1, 1, 1, 9, 1, 33, 97, 7, 247, 893, 655, 3137, 6593, 7261, 11829, 22101, 0 }; + static ulong[] dim4782KuoInit = { 1, 1, 1, 7, 11, 23, 75, 55, 313, 533, 529, 1929, 3647, 3317, 2987, 11917, 0 }; + static ulong[] dim4783KuoInit = { 1, 1, 1, 11, 17, 35, 105, 221, 211, 545, 1595, 1949, 1895, 39, 7163, 33303, 0 }; + static ulong[] dim4784KuoInit = { 1, 1, 1, 9, 21, 29, 73, 235, 189, 11, 1747, 1023, 3987, 10337, 1689, 64043, 0 }; + static ulong[] dim4785KuoInit = { 1, 3, 1, 5, 11, 17, 115, 57, 465, 899, 1421, 1329, 6099, 8081, 11297, 13217, 0 }; + static ulong[] dim4786KuoInit = { 1, 3, 3, 9, 5, 23, 53, 23, 11, 177, 817, 3003, 5073, 12071, 11263, 43159, 0 }; + static ulong[] dim4787KuoInit = { 1, 1, 3, 13, 1, 63, 127, 41, 303, 681, 1559, 2385, 6265, 2417, 7063, 57965, 0 }; + static ulong[] dim4788KuoInit = { 1, 3, 1, 1, 3, 21, 21, 37, 485, 771, 2043, 2065, 7047, 8867, 7019, 31437, 0 }; + static ulong[] dim4789KuoInit = { 1, 3, 1, 11, 27, 49, 77, 89, 391, 623, 1675, 1919, 3575, 2187, 22801, 11059, 0 }; + static ulong[] dim4790KuoInit = { 1, 1, 3, 5, 9, 57, 51, 255, 287, 851, 1999, 811, 7769, 11185, 19279, 65491, 0 }; + static ulong[] dim4791KuoInit = { 1, 3, 1, 15, 31, 43, 113, 11, 461, 95, 841, 2937, 3969, 5901, 32681, 9231, 0 }; + static ulong[] dim4792KuoInit = { 1, 3, 3, 5, 31, 47, 21, 187, 171, 249, 787, 459, 6897, 12131, 14843, 11805, 0 }; + static ulong[] dim4793KuoInit = { 1, 1, 7, 13, 27, 61, 91, 77, 9, 393, 1231, 1901, 291, 1487, 22139, 30569, 0 }; + static ulong[] dim4794KuoInit = { 1, 1, 1, 1, 27, 33, 55, 151, 89, 603, 551, 3767, 695, 15225, 9665, 60459, 0 }; + static ulong[] dim4795KuoInit = { 1, 1, 7, 13, 31, 19, 83, 27, 381, 105, 481, 3095, 137, 10433, 12967, 19555, 0 }; + static ulong[] dim4796KuoInit = { 1, 1, 1, 11, 15, 1, 3, 121, 107, 435, 1571, 3205, 5213, 3689, 31365, 14353, 0 }; + static ulong[] dim4797KuoInit = { 1, 3, 7, 11, 23, 61, 93, 59, 179, 361, 965, 413, 7757, 15779, 1119, 34673, 0 }; + static ulong[] dim4798KuoInit = { 1, 1, 3, 13, 29, 63, 79, 135, 431, 723, 727, 2685, 1775, 9027, 27051, 42581, 0 }; + static ulong[] dim4799KuoInit = { 1, 3, 5, 9, 27, 19, 17, 141, 367, 1021, 651, 2549, 4003, 15737, 22063, 12443, 0 }; + static ulong[] dim4800KuoInit = { 1, 1, 1, 11, 23, 27, 35, 225, 399, 173, 451, 1701, 1093, 5639, 1855, 1817, 0 }; + static ulong[] dim4801KuoInit = { 1, 3, 7, 11, 23, 63, 119, 13, 147, 997, 53, 3127, 101, 6633, 14377, 61843, 0 }; + static ulong[] dim4802KuoInit = { 1, 1, 1, 15, 23, 21, 65, 213, 311, 789, 1395, 1239, 241, 15041, 14683, 27805, 0 }; + static ulong[] dim4803KuoInit = { 1, 3, 3, 9, 7, 29, 83, 153, 231, 337, 153, 3097, 6137, 11003, 31091, 57005, 0 }; + static ulong[] dim4804KuoInit = { 1, 3, 7, 9, 19, 33, 91, 235, 123, 747, 1331, 2307, 3791, 2063, 23613, 3589, 0 }; + static ulong[] dim4805KuoInit = { 1, 3, 3, 15, 9, 25, 95, 237, 381, 349, 1339, 3187, 2387, 3487, 4149, 39343, 0 }; + static ulong[] dim4806KuoInit = { 1, 1, 1, 13, 5, 3, 43, 193, 431, 853, 1419, 905, 2395, 11459, 26109, 31277, 0 }; + static ulong[] dim4807KuoInit = { 1, 3, 1, 15, 13, 29, 13, 253, 475, 81, 1199, 841, 7385, 2609, 10445, 11151, 0 }; + static ulong[] dim4808KuoInit = { 1, 1, 7, 15, 29, 11, 81, 91, 287, 615, 949, 2541, 5059, 12567, 9547, 45647, 0 }; + static ulong[] dim4809KuoInit = { 1, 3, 7, 13, 9, 27, 123, 165, 249, 457, 607, 1203, 987, 4477, 21205, 44547, 0 }; + static ulong[] dim4810KuoInit = { 1, 1, 3, 15, 3, 1, 37, 43, 445, 205, 1849, 3461, 7667, 209, 8773, 1507, 0 }; + static ulong[] dim4811KuoInit = { 1, 3, 1, 3, 27, 43, 75, 199, 185, 249, 725, 301, 2181, 6859, 16825, 3471, 0 }; + static ulong[] dim4812KuoInit = { 1, 3, 1, 9, 29, 5, 55, 5, 345, 325, 1853, 3925, 1739, 14991, 27845, 6931, 0 }; + static ulong[] dim4813KuoInit = { 1, 1, 3, 5, 31, 15, 33, 47, 201, 649, 415, 639, 391, 12065, 17343, 3063, 0 }; + static ulong[] dim4814KuoInit = { 1, 1, 7, 11, 19, 37, 39, 77, 367, 29, 1251, 2637, 5601, 10661, 17647, 22131, 0 }; + static ulong[] dim4815KuoInit = { 1, 1, 7, 15, 29, 51, 13, 129, 279, 427, 1535, 2185, 2651, 8251, 14857, 61467, 0 }; + static ulong[] dim4816KuoInit = { 1, 1, 7, 5, 25, 55, 45, 105, 213, 31, 735, 3795, 6627, 14299, 3155, 3659, 0 }; + static ulong[] dim4817KuoInit = { 1, 1, 1, 9, 21, 27, 21, 85, 315, 793, 1663, 437, 4113, 4639, 11321, 13633, 0 }; + static ulong[] dim4818KuoInit = { 1, 3, 5, 9, 23, 17, 49, 35, 451, 799, 1451, 539, 4549, 43, 1901, 21155, 0 }; + static ulong[] dim4819KuoInit = { 1, 3, 7, 9, 23, 53, 25, 71, 371, 1005, 129, 157, 2977, 15823, 30393, 55629, 0 }; + static ulong[] dim4820KuoInit = { 1, 1, 7, 7, 9, 27, 79, 101, 147, 511, 199, 2843, 101, 14975, 3455, 843, 0 }; + static ulong[] dim4821KuoInit = { 1, 3, 1, 7, 11, 33, 43, 7, 445, 501, 1071, 1851, 5763, 5233, 16121, 23357, 0 }; + static ulong[] dim4822KuoInit = { 1, 1, 1, 13, 11, 21, 75, 153, 421, 311, 1709, 3745, 2971, 11219, 23107, 40057, 0 }; + static ulong[] dim4823KuoInit = { 1, 1, 3, 15, 17, 39, 17, 165, 103, 31, 575, 3945, 1921, 11305, 13417, 20603, 0 }; + static ulong[] dim4824KuoInit = { 1, 3, 3, 3, 5, 49, 37, 61, 177, 595, 1133, 1883, 819, 5137, 10423, 42009, 0 }; + static ulong[] dim4825KuoInit = { 1, 1, 3, 5, 5, 15, 89, 191, 97, 1017, 205, 4037, 3431, 13877, 29867, 26041, 0 }; + static ulong[] dim4826KuoInit = { 1, 3, 3, 7, 9, 9, 109, 157, 357, 815, 1539, 3507, 1379, 1105, 14387, 46689, 0 }; + static ulong[] dim4827KuoInit = { 1, 3, 3, 9, 3, 11, 77, 161, 473, 619, 741, 2945, 5123, 3325, 8679, 36167, 0 }; + static ulong[] dim4828KuoInit = { 1, 1, 1, 9, 9, 53, 3, 77, 319, 223, 875, 425, 1369, 509, 25895, 32803, 0 }; + static ulong[] dim4829KuoInit = { 1, 1, 3, 13, 31, 15, 113, 133, 473, 29, 1009, 1385, 871, 15785, 1015, 42627, 0 }; + static ulong[] dim4830KuoInit = { 1, 3, 7, 13, 5, 53, 123, 7, 465, 485, 1413, 1663, 6541, 13051, 12251, 36151, 0 }; + static ulong[] dim4831KuoInit = { 1, 1, 1, 13, 9, 21, 123, 223, 483, 849, 489, 3905, 4697, 7583, 5373, 62397, 0 }; + static ulong[] dim4832KuoInit = { 1, 1, 7, 9, 29, 53, 85, 151, 511, 917, 1719, 937, 2035, 6385, 23529, 62213, 0 }; + static ulong[] dim4833KuoInit = { 1, 1, 3, 15, 11, 47, 111, 79, 377, 585, 475, 3201, 7025, 1483, 8815, 47235, 0 }; + static ulong[] dim4834KuoInit = { 1, 1, 3, 13, 13, 5, 39, 31, 71, 39, 941, 2215, 2195, 2827, 24353, 18435, 0 }; + static ulong[] dim4835KuoInit = { 1, 1, 7, 15, 13, 31, 31, 15, 421, 81, 895, 1345, 7049, 4373, 28005, 41781, 0 }; + static ulong[] dim4836KuoInit = { 1, 1, 3, 15, 17, 57, 21, 175, 453, 755, 1295, 353, 5257, 15901, 15643, 31725, 0 }; + static ulong[] dim4837KuoInit = { 1, 1, 1, 9, 17, 17, 71, 209, 155, 511, 1461, 3313, 7515, 8407, 9561, 48169, 0 }; + static ulong[] dim4838KuoInit = { 1, 3, 7, 15, 23, 59, 89, 39, 85, 857, 1285, 3099, 6497, 5501, 21321, 34319, 0 }; + static ulong[] dim4839KuoInit = { 1, 3, 5, 5, 27, 13, 41, 1, 191, 275, 1567, 895, 13, 673, 10079, 55075, 0 }; + static ulong[] dim4840KuoInit = { 1, 1, 7, 15, 9, 33, 33, 35, 55, 597, 365, 3205, 6427, 837, 16011, 23279, 0 }; + static ulong[] dim4841KuoInit = { 1, 3, 5, 11, 23, 23, 9, 79, 383, 303, 1715, 1651, 7507, 14553, 30715, 56659, 0 }; + static ulong[] dim4842KuoInit = { 1, 3, 1, 11, 1, 61, 31, 85, 181, 593, 1783, 901, 6069, 1521, 13275, 18057, 0 }; + static ulong[] dim4843KuoInit = { 1, 3, 1, 13, 23, 59, 111, 221, 47, 599, 193, 1547, 4077, 15271, 19315, 1115, 0 }; + static ulong[] dim4844KuoInit = { 1, 3, 7, 7, 23, 53, 115, 69, 19, 409, 1041, 3395, 6429, 9263, 21637, 35533, 0 }; + static ulong[] dim4845KuoInit = { 1, 1, 7, 1, 31, 45, 43, 251, 163, 907, 761, 2009, 3807, 1529, 12001, 38823, 0 }; + static ulong[] dim4846KuoInit = { 1, 3, 5, 3, 3, 59, 87, 247, 179, 931, 709, 53, 6283, 13723, 15407, 22417, 0 }; + static ulong[] dim4847KuoInit = { 1, 1, 1, 5, 27, 17, 21, 183, 393, 177, 1187, 19, 5409, 2539, 17401, 29287, 0 }; + static ulong[] dim4848KuoInit = { 1, 1, 5, 15, 3, 51, 91, 95, 389, 855, 1453, 2815, 7507, 5449, 12459, 59111, 0 }; + static ulong[] dim4849KuoInit = { 1, 1, 5, 3, 7, 53, 101, 255, 395, 345, 915, 1649, 6641, 7771, 20747, 17067, 0 }; + static ulong[] dim4850KuoInit = { 1, 3, 1, 7, 5, 35, 69, 63, 249, 189, 1937, 965, 3463, 13615, 12449, 11891, 0 }; + static ulong[] dim4851KuoInit = { 1, 3, 3, 9, 5, 59, 57, 187, 403, 825, 1291, 2995, 6365, 15995, 6871, 25785, 0 }; + static ulong[] dim4852KuoInit = { 1, 3, 5, 15, 17, 23, 117, 103, 131, 601, 1259, 1331, 3039, 4761, 8105, 14521, 0 }; + static ulong[] dim4853KuoInit = { 1, 1, 3, 15, 27, 51, 97, 221, 345, 615, 487, 2535, 139, 16233, 16271, 713, 0 }; + static ulong[] dim4854KuoInit = { 1, 3, 7, 13, 25, 49, 99, 71, 353, 1015, 1889, 689, 1925, 6523, 30995, 23057, 0 }; + static ulong[] dim4855KuoInit = { 1, 3, 5, 9, 21, 55, 11, 29, 477, 581, 1719, 2603, 1757, 3995, 27025, 62833, 0 }; + static ulong[] dim4856KuoInit = { 1, 3, 1, 9, 9, 39, 9, 121, 459, 991, 2021, 1469, 2399, 4441, 11829, 36865, 0 }; + static ulong[] dim4857KuoInit = { 1, 3, 1, 5, 9, 13, 115, 27, 487, 307, 453, 351, 885, 12539, 39, 33887, 0 }; + static ulong[] dim4858KuoInit = { 1, 3, 1, 7, 23, 35, 87, 131, 129, 1, 2015, 3921, 1309, 7915, 16661, 45945, 0 }; + static ulong[] dim4859KuoInit = { 1, 3, 1, 3, 1, 15, 93, 255, 285, 915, 563, 527, 7763, 4581, 11161, 64619, 0 }; + static ulong[] dim4860KuoInit = { 1, 3, 3, 9, 31, 37, 87, 81, 313, 647, 1065, 863, 6121, 1385, 26171, 56323, 0 }; + static ulong[] dim4861KuoInit = { 1, 1, 3, 7, 25, 49, 23, 107, 507, 511, 951, 669, 67, 14319, 17669, 32497, 0 }; + static ulong[] dim4862KuoInit = { 1, 3, 1, 13, 9, 33, 93, 171, 457, 687, 703, 1073, 3699, 7029, 28983, 14501, 0 }; + static ulong[] dim4863KuoInit = { 1, 1, 7, 13, 29, 3, 19, 173, 131, 285, 469, 1223, 7779, 15367, 643, 63715, 0 }; + static ulong[] dim4864KuoInit = { 1, 3, 7, 5, 5, 37, 21, 223, 227, 939, 1205, 3167, 5535, 11543, 7411, 30841, 0 }; + static ulong[] dim4865KuoInit = { 1, 3, 5, 11, 31, 37, 75, 39, 171, 135, 1487, 3503, 7939, 77, 19745, 2551, 0 }; + static ulong[] dim4866KuoInit = { 1, 3, 5, 13, 25, 33, 79, 213, 289, 27, 1435, 1839, 3089, 8173, 27555, 20599, 0 }; + static ulong[] dim4867KuoInit = { 1, 1, 3, 13, 19, 31, 67, 9, 229, 591, 561, 3797, 1833, 3311, 16053, 61183, 0 }; + static ulong[] dim4868KuoInit = { 1, 1, 3, 3, 27, 27, 79, 95, 7, 1023, 517, 3627, 4117, 8165, 17961, 39011, 0 }; + static ulong[] dim4869KuoInit = { 1, 3, 5, 3, 3, 43, 37, 231, 389, 367, 517, 3117, 2643, 2103, 127, 42669, 0 }; + static ulong[] dim4870KuoInit = { 1, 1, 1, 11, 11, 49, 35, 71, 295, 87, 1653, 1899, 1177, 16071, 8429, 54751, 0 }; + static ulong[] dim4871KuoInit = { 1, 1, 7, 13, 5, 47, 7, 229, 261, 837, 645, 1581, 159, 73, 10233, 18557, 0 }; + static ulong[] dim4872KuoInit = { 1, 3, 1, 9, 11, 45, 25, 3, 271, 1005, 1193, 507, 269, 14689, 7601, 56781, 0 }; + static ulong[] dim4873KuoInit = { 1, 1, 5, 11, 13, 61, 107, 29, 155, 415, 1435, 1979, 7339, 1839, 21097, 5851, 0 }; + static ulong[] dim4874KuoInit = { 1, 1, 5, 9, 9, 27, 83, 163, 15, 539, 765, 463, 7493, 1413, 15597, 42819, 0 }; + static ulong[] dim4875KuoInit = { 1, 3, 1, 9, 21, 7, 91, 213, 463, 827, 1847, 2825, 2115, 14549, 29923, 61355, 0 }; + static ulong[] dim4876KuoInit = { 1, 1, 3, 15, 1, 55, 69, 85, 7, 847, 1935, 3225, 693, 12069, 26303, 19143, 0 }; + static ulong[] dim4877KuoInit = { 1, 3, 1, 11, 15, 47, 53, 181, 327, 493, 483, 999, 4421, 6707, 27933, 11533, 0 }; + static ulong[] dim4878KuoInit = { 1, 3, 3, 3, 23, 7, 7, 63, 235, 493, 937, 2935, 2869, 14243, 30975, 12881, 0 }; + static ulong[] dim4879KuoInit = { 1, 1, 3, 9, 9, 7, 113, 203, 297, 183, 1687, 3211, 8131, 7033, 15007, 1307, 0 }; + static ulong[] dim4880KuoInit = { 1, 3, 1, 9, 9, 39, 99, 5, 61, 435, 427, 2719, 7741, 4267, 2423, 37573, 0 }; + static ulong[] dim4881KuoInit = { 1, 3, 7, 3, 17, 1, 105, 13, 89, 693, 1835, 2455, 1135, 15545, 2447, 25673, 0 }; + static ulong[] dim4882KuoInit = { 1, 3, 5, 5, 15, 47, 103, 167, 21, 791, 1297, 3523, 4427, 7013, 1845, 44461, 0 }; + static ulong[] dim4883KuoInit = { 1, 1, 5, 7, 11, 17, 55, 247, 317, 229, 1465, 3781, 2397, 10541, 8943, 29155, 0 }; + static ulong[] dim4884KuoInit = { 1, 1, 5, 3, 17, 17, 97, 141, 153, 883, 449, 1163, 3165, 125, 4689, 44461, 0 }; + static ulong[] dim4885KuoInit = { 1, 3, 7, 1, 17, 13, 9, 235, 87, 251, 57, 2769, 4845, 5733, 4305, 49489, 0 }; + static ulong[] dim4886KuoInit = { 1, 1, 7, 1, 9, 41, 79, 97, 201, 789, 37, 2593, 8023, 139, 30623, 7667, 0 }; + static ulong[] dim4887KuoInit = { 1, 1, 7, 7, 7, 27, 9, 99, 199, 163, 1175, 729, 2731, 4391, 27597, 23087, 0 }; + static ulong[] dim4888KuoInit = { 1, 3, 5, 5, 29, 39, 5, 129, 395, 1007, 1751, 3951, 5879, 13105, 26223, 31361, 0 }; + static ulong[] dim4889KuoInit = { 1, 3, 5, 3, 3, 55, 89, 253, 207, 553, 1407, 2277, 6879, 16027, 23477, 43633, 0 }; + static ulong[] dim4890KuoInit = { 1, 1, 1, 3, 13, 21, 9, 149, 31, 359, 1631, 2199, 2937, 15663, 5899, 59959, 0 }; + static ulong[] dim4891KuoInit = { 1, 1, 1, 7, 25, 63, 87, 13, 179, 237, 359, 3841, 6467, 5621, 29459, 31339, 0 }; + static ulong[] dim4892KuoInit = { 1, 1, 1, 15, 25, 45, 77, 17, 419, 759, 1045, 1285, 6739, 11035, 11401, 44821, 0 }; + static ulong[] dim4893KuoInit = { 1, 3, 7, 1, 31, 47, 17, 237, 69, 389, 1251, 1205, 833, 2313, 17005, 32683, 0 }; + static ulong[] dim4894KuoInit = { 1, 1, 7, 9, 13, 19, 51, 69, 261, 85, 215, 2215, 1643, 12985, 10363, 17123, 0 }; + static ulong[] dim4895KuoInit = { 1, 3, 1, 3, 3, 51, 41, 173, 161, 633, 1727, 3089, 7791, 7367, 32641, 14361, 0 }; + static ulong[] dim4896KuoInit = { 1, 3, 5, 3, 21, 49, 19, 243, 427, 589, 1699, 2187, 4177, 927, 6201, 46319, 0 }; + static ulong[] dim4897KuoInit = { 1, 1, 3, 11, 1, 59, 49, 235, 345, 731, 793, 1893, 4735, 10647, 31169, 12051, 0 }; + static ulong[] dim4898KuoInit = { 1, 1, 7, 15, 23, 51, 67, 151, 253, 793, 1673, 3255, 4919, 11309, 24903, 9083, 0 }; + static ulong[] dim4899KuoInit = { 1, 3, 3, 9, 7, 59, 41, 225, 397, 671, 513, 1351, 2835, 15789, 17679, 28641, 0 }; + static ulong[] dim4900KuoInit = { 1, 3, 1, 7, 17, 39, 49, 103, 181, 375, 1843, 1183, 4219, 2931, 18385, 1203, 0 }; + static ulong[] dim4901KuoInit = { 1, 1, 1, 3, 29, 19, 113, 55, 81, 69, 1541, 3249, 643, 841, 6053, 63571, 0 }; + static ulong[] dim4902KuoInit = { 1, 1, 7, 5, 1, 3, 39, 237, 283, 283, 813, 3539, 5899, 8489, 18393, 22371, 0 }; + static ulong[] dim4903KuoInit = { 1, 3, 7, 13, 5, 53, 15, 129, 95, 181, 657, 3735, 7517, 2435, 17245, 4075, 0 }; + static ulong[] dim4904KuoInit = { 1, 1, 5, 3, 9, 37, 73, 95, 175, 989, 1443, 1745, 8117, 5867, 29729, 28441, 0 }; + static ulong[] dim4905KuoInit = { 1, 3, 3, 11, 5, 41, 25, 3, 177, 735, 187, 357, 5365, 8161, 2071, 41651, 0 }; + static ulong[] dim4906KuoInit = { 1, 1, 1, 15, 29, 47, 27, 233, 177, 339, 1839, 1761, 5483, 7203, 32411, 59859, 0 }; + static ulong[] dim4907KuoInit = { 1, 3, 7, 9, 13, 59, 25, 17, 157, 247, 697, 4011, 4539, 4253, 1381, 63009, 0 }; + static ulong[] dim4908KuoInit = { 1, 1, 5, 13, 19, 21, 19, 161, 325, 389, 1067, 525, 529, 277, 13775, 52265, 0 }; + static ulong[] dim4909KuoInit = { 1, 1, 5, 13, 21, 17, 77, 191, 329, 627, 1857, 1705, 2207, 5329, 29833, 1523, 0 }; + static ulong[] dim4910KuoInit = { 1, 3, 3, 1, 21, 3, 107, 85, 29, 887, 793, 1089, 1361, 10361, 15869, 1659, 0 }; + static ulong[] dim4911KuoInit = { 1, 1, 1, 15, 11, 47, 85, 137, 373, 777, 875, 2735, 4381, 8831, 5891, 44809, 0 }; + static ulong[] dim4912KuoInit = { 1, 1, 1, 11, 19, 9, 77, 59, 497, 643, 51, 3115, 7267, 11927, 28119, 28151, 0 }; + static ulong[] dim4913KuoInit = { 1, 3, 1, 3, 13, 27, 55, 201, 319, 167, 1435, 2197, 5049, 5923, 12759, 62383, 0 }; + static ulong[] dim4914KuoInit = { 1, 3, 1, 3, 23, 43, 45, 193, 221, 647, 1933, 2915, 6461, 4927, 22105, 54557, 0 }; + static ulong[] dim4915KuoInit = { 1, 1, 5, 11, 5, 23, 67, 59, 79, 507, 925, 3015, 317, 3887, 29967, 17205, 0 }; + static ulong[] dim4916KuoInit = { 1, 3, 7, 7, 19, 39, 51, 159, 485, 315, 1739, 2617, 8017, 11655, 1141, 26055, 0 }; + static ulong[] dim4917KuoInit = { 1, 1, 3, 1, 27, 53, 119, 113, 135, 85, 2023, 1659, 307, 8189, 28339, 53297, 0 }; + static ulong[] dim4918KuoInit = { 1, 3, 3, 5, 9, 61, 57, 225, 137, 381, 1045, 1253, 1185, 9885, 30153, 29355, 0 }; + static ulong[] dim4919KuoInit = { 1, 1, 3, 5, 19, 9, 87, 87, 393, 421, 1941, 57, 2483, 10855, 26741, 28091, 0 }; + static ulong[] dim4920KuoInit = { 1, 1, 7, 5, 3, 35, 35, 137, 123, 327, 933, 3429, 281, 1705, 17123, 29337, 0 }; + static ulong[] dim4921KuoInit = { 1, 3, 7, 13, 9, 61, 111, 207, 45, 57, 1093, 2223, 575, 11959, 21147, 30273, 0 }; + static ulong[] dim4922KuoInit = { 1, 1, 5, 5, 31, 37, 123, 5, 277, 273, 525, 1773, 2685, 11607, 32079, 25199, 0 }; + static ulong[] dim4923KuoInit = { 1, 1, 7, 11, 5, 29, 121, 193, 437, 417, 1521, 3057, 4681, 2773, 5391, 59747, 0 }; + static ulong[] dim4924KuoInit = { 1, 3, 7, 11, 27, 3, 103, 17, 395, 695, 1731, 4055, 2727, 2171, 26893, 7047, 0 }; + static ulong[] dim4925KuoInit = { 1, 3, 7, 5, 23, 9, 25, 167, 241, 755, 1789, 1977, 6325, 5425, 23247, 64181, 0 }; + + static ulong[][] Kuoinitializers = + { + dim1KuoInit, + dim2KuoInit, + dim3KuoInit, + dim4KuoInit, + dim5KuoInit, + dim6KuoInit, + dim7KuoInit, + dim8KuoInit, + dim9KuoInit, + dim10KuoInit, + dim11KuoInit, + dim12KuoInit, + dim13KuoInit, + dim14KuoInit, + dim15KuoInit, + dim16KuoInit, + dim17KuoInit, + dim18KuoInit, + dim19KuoInit, + dim20KuoInit, + dim21KuoInit, + dim22KuoInit, + dim23KuoInit, + dim24KuoInit, + dim25KuoInit, + dim26KuoInit, + dim27KuoInit, + dim28KuoInit, + dim29KuoInit, + dim30KuoInit, + dim31KuoInit, + dim32KuoInit, + dim33KuoInit, + dim34KuoInit, + dim35KuoInit, + dim36KuoInit, + dim37KuoInit, + dim38KuoInit, + dim39KuoInit, + dim40KuoInit, + dim41KuoInit, + dim42KuoInit, + dim43KuoInit, + dim44KuoInit, + dim45KuoInit, + dim46KuoInit, + dim47KuoInit, + dim48KuoInit, + dim49KuoInit, + dim50KuoInit, + dim51KuoInit, + dim52KuoInit, + dim53KuoInit, + dim54KuoInit, + dim55KuoInit, + dim56KuoInit, + dim57KuoInit, + dim58KuoInit, + dim59KuoInit, + dim60KuoInit, + dim61KuoInit, + dim62KuoInit, + dim63KuoInit, + dim64KuoInit, + dim65KuoInit, + dim66KuoInit, + dim67KuoInit, + dim68KuoInit, + dim69KuoInit, + dim70KuoInit, + dim71KuoInit, + dim72KuoInit, + dim73KuoInit, + dim74KuoInit, + dim75KuoInit, + dim76KuoInit, + dim77KuoInit, + dim78KuoInit, + dim79KuoInit, + dim80KuoInit, + dim81KuoInit, + dim82KuoInit, + dim83KuoInit, + dim84KuoInit, + dim85KuoInit, + dim86KuoInit, + dim87KuoInit, + dim88KuoInit, + dim89KuoInit, + dim90KuoInit, + dim91KuoInit, + dim92KuoInit, + dim93KuoInit, + dim94KuoInit, + dim95KuoInit, + dim96KuoInit, + dim97KuoInit, + dim98KuoInit, + dim99KuoInit, + dim100KuoInit, + dim101KuoInit, + dim102KuoInit, + dim103KuoInit, + dim104KuoInit, + dim105KuoInit, + dim106KuoInit, + dim107KuoInit, + dim108KuoInit, + dim109KuoInit, + dim110KuoInit, + dim111KuoInit, + dim112KuoInit, + dim113KuoInit, + dim114KuoInit, + dim115KuoInit, + dim116KuoInit, + dim117KuoInit, + dim118KuoInit, + dim119KuoInit, + dim120KuoInit, + dim121KuoInit, + dim122KuoInit, + dim123KuoInit, + dim124KuoInit, + dim125KuoInit, + dim126KuoInit, + dim127KuoInit, + dim128KuoInit, + dim129KuoInit, + dim130KuoInit, + dim131KuoInit, + dim132KuoInit, + dim133KuoInit, + dim134KuoInit, + dim135KuoInit, + dim136KuoInit, + dim137KuoInit, + dim138KuoInit, + dim139KuoInit, + dim140KuoInit, + dim141KuoInit, + dim142KuoInit, + dim143KuoInit, + dim144KuoInit, + dim145KuoInit, + dim146KuoInit, + dim147KuoInit, + dim148KuoInit, + dim149KuoInit, + dim150KuoInit, + dim151KuoInit, + dim152KuoInit, + dim153KuoInit, + dim154KuoInit, + dim155KuoInit, + dim156KuoInit, + dim157KuoInit, + dim158KuoInit, + dim159KuoInit, + dim160KuoInit, + dim161KuoInit, + dim162KuoInit, + dim163KuoInit, + dim164KuoInit, + dim165KuoInit, + dim166KuoInit, + dim167KuoInit, + dim168KuoInit, + dim169KuoInit, + dim170KuoInit, + dim171KuoInit, + dim172KuoInit, + dim173KuoInit, + dim174KuoInit, + dim175KuoInit, + dim176KuoInit, + dim177KuoInit, + dim178KuoInit, + dim179KuoInit, + dim180KuoInit, + dim181KuoInit, + dim182KuoInit, + dim183KuoInit, + dim184KuoInit, + dim185KuoInit, + dim186KuoInit, + dim187KuoInit, + dim188KuoInit, + dim189KuoInit, + dim190KuoInit, + dim191KuoInit, + dim192KuoInit, + dim193KuoInit, + dim194KuoInit, + dim195KuoInit, + dim196KuoInit, + dim197KuoInit, + dim198KuoInit, + dim199KuoInit, + dim200KuoInit, + dim201KuoInit, + dim202KuoInit, + dim203KuoInit, + dim204KuoInit, + dim205KuoInit, + dim206KuoInit, + dim207KuoInit, + dim208KuoInit, + dim209KuoInit, + dim210KuoInit, + dim211KuoInit, + dim212KuoInit, + dim213KuoInit, + dim214KuoInit, + dim215KuoInit, + dim216KuoInit, + dim217KuoInit, + dim218KuoInit, + dim219KuoInit, + dim220KuoInit, + dim221KuoInit, + dim222KuoInit, + dim223KuoInit, + dim224KuoInit, + dim225KuoInit, + dim226KuoInit, + dim227KuoInit, + dim228KuoInit, + dim229KuoInit, + dim230KuoInit, + dim231KuoInit, + dim232KuoInit, + dim233KuoInit, + dim234KuoInit, + dim235KuoInit, + dim236KuoInit, + dim237KuoInit, + dim238KuoInit, + dim239KuoInit, + dim240KuoInit, + dim241KuoInit, + dim242KuoInit, + dim243KuoInit, + dim244KuoInit, + dim245KuoInit, + dim246KuoInit, + dim247KuoInit, + dim248KuoInit, + dim249KuoInit, + dim250KuoInit, + dim251KuoInit, + dim252KuoInit, + dim253KuoInit, + dim254KuoInit, + dim255KuoInit, + dim256KuoInit, + dim257KuoInit, + dim258KuoInit, + dim259KuoInit, + dim260KuoInit, + dim261KuoInit, + dim262KuoInit, + dim263KuoInit, + dim264KuoInit, + dim265KuoInit, + dim266KuoInit, + dim267KuoInit, + dim268KuoInit, + dim269KuoInit, + dim270KuoInit, + dim271KuoInit, + dim272KuoInit, + dim273KuoInit, + dim274KuoInit, + dim275KuoInit, + dim276KuoInit, + dim277KuoInit, + dim278KuoInit, + dim279KuoInit, + dim280KuoInit, + dim281KuoInit, + dim282KuoInit, + dim283KuoInit, + dim284KuoInit, + dim285KuoInit, + dim286KuoInit, + dim287KuoInit, + dim288KuoInit, + dim289KuoInit, + dim290KuoInit, + dim291KuoInit, + dim292KuoInit, + dim293KuoInit, + dim294KuoInit, + dim295KuoInit, + dim296KuoInit, + dim297KuoInit, + dim298KuoInit, + dim299KuoInit, + dim300KuoInit, + dim301KuoInit, + dim302KuoInit, + dim303KuoInit, + dim304KuoInit, + dim305KuoInit, + dim306KuoInit, + dim307KuoInit, + dim308KuoInit, + dim309KuoInit, + dim310KuoInit, + dim311KuoInit, + dim312KuoInit, + dim313KuoInit, + dim314KuoInit, + dim315KuoInit, + dim316KuoInit, + dim317KuoInit, + dim318KuoInit, + dim319KuoInit, + dim320KuoInit, + dim321KuoInit, + dim322KuoInit, + dim323KuoInit, + dim324KuoInit, + dim325KuoInit, + dim326KuoInit, + dim327KuoInit, + dim328KuoInit, + dim329KuoInit, + dim330KuoInit, + dim331KuoInit, + dim332KuoInit, + dim333KuoInit, + dim334KuoInit, + dim335KuoInit, + dim336KuoInit, + dim337KuoInit, + dim338KuoInit, + dim339KuoInit, + dim340KuoInit, + dim341KuoInit, + dim342KuoInit, + dim343KuoInit, + dim344KuoInit, + dim345KuoInit, + dim346KuoInit, + dim347KuoInit, + dim348KuoInit, + dim349KuoInit, + dim350KuoInit, + dim351KuoInit, + dim352KuoInit, + dim353KuoInit, + dim354KuoInit, + dim355KuoInit, + dim356KuoInit, + dim357KuoInit, + dim358KuoInit, + dim359KuoInit, + dim360KuoInit, + dim361KuoInit, + dim362KuoInit, + dim363KuoInit, + dim364KuoInit, + dim365KuoInit, + dim366KuoInit, + dim367KuoInit, + dim368KuoInit, + dim369KuoInit, + dim370KuoInit, + dim371KuoInit, + dim372KuoInit, + dim373KuoInit, + dim374KuoInit, + dim375KuoInit, + dim376KuoInit, + dim377KuoInit, + dim378KuoInit, + dim379KuoInit, + dim380KuoInit, + dim381KuoInit, + dim382KuoInit, + dim383KuoInit, + dim384KuoInit, + dim385KuoInit, + dim386KuoInit, + dim387KuoInit, + dim388KuoInit, + dim389KuoInit, + dim390KuoInit, + dim391KuoInit, + dim392KuoInit, + dim393KuoInit, + dim394KuoInit, + dim395KuoInit, + dim396KuoInit, + dim397KuoInit, + dim398KuoInit, + dim399KuoInit, + dim400KuoInit, + dim401KuoInit, + dim402KuoInit, + dim403KuoInit, + dim404KuoInit, + dim405KuoInit, + dim406KuoInit, + dim407KuoInit, + dim408KuoInit, + dim409KuoInit, + dim410KuoInit, + dim411KuoInit, + dim412KuoInit, + dim413KuoInit, + dim414KuoInit, + dim415KuoInit, + dim416KuoInit, + dim417KuoInit, + dim418KuoInit, + dim419KuoInit, + dim420KuoInit, + dim421KuoInit, + dim422KuoInit, + dim423KuoInit, + dim424KuoInit, + dim425KuoInit, + dim426KuoInit, + dim427KuoInit, + dim428KuoInit, + dim429KuoInit, + dim430KuoInit, + dim431KuoInit, + dim432KuoInit, + dim433KuoInit, + dim434KuoInit, + dim435KuoInit, + dim436KuoInit, + dim437KuoInit, + dim438KuoInit, + dim439KuoInit, + dim440KuoInit, + dim441KuoInit, + dim442KuoInit, + dim443KuoInit, + dim444KuoInit, + dim445KuoInit, + dim446KuoInit, + dim447KuoInit, + dim448KuoInit, + dim449KuoInit, + dim450KuoInit, + dim451KuoInit, + dim452KuoInit, + dim453KuoInit, + dim454KuoInit, + dim455KuoInit, + dim456KuoInit, + dim457KuoInit, + dim458KuoInit, + dim459KuoInit, + dim460KuoInit, + dim461KuoInit, + dim462KuoInit, + dim463KuoInit, + dim464KuoInit, + dim465KuoInit, + dim466KuoInit, + dim467KuoInit, + dim468KuoInit, + dim469KuoInit, + dim470KuoInit, + dim471KuoInit, + dim472KuoInit, + dim473KuoInit, + dim474KuoInit, + dim475KuoInit, + dim476KuoInit, + dim477KuoInit, + dim478KuoInit, + dim479KuoInit, + dim480KuoInit, + dim481KuoInit, + dim482KuoInit, + dim483KuoInit, + dim484KuoInit, + dim485KuoInit, + dim486KuoInit, + dim487KuoInit, + dim488KuoInit, + dim489KuoInit, + dim490KuoInit, + dim491KuoInit, + dim492KuoInit, + dim493KuoInit, + dim494KuoInit, + dim495KuoInit, + dim496KuoInit, + dim497KuoInit, + dim498KuoInit, + dim499KuoInit, + dim500KuoInit, + dim501KuoInit, + dim502KuoInit, + dim503KuoInit, + dim504KuoInit, + dim505KuoInit, + dim506KuoInit, + dim507KuoInit, + dim508KuoInit, + dim509KuoInit, + dim510KuoInit, + dim511KuoInit, + dim512KuoInit, + dim513KuoInit, + dim514KuoInit, + dim515KuoInit, + dim516KuoInit, + dim517KuoInit, + dim518KuoInit, + dim519KuoInit, + dim520KuoInit, + dim521KuoInit, + dim522KuoInit, + dim523KuoInit, + dim524KuoInit, + dim525KuoInit, + dim526KuoInit, + dim527KuoInit, + dim528KuoInit, + dim529KuoInit, + dim530KuoInit, + dim531KuoInit, + dim532KuoInit, + dim533KuoInit, + dim534KuoInit, + dim535KuoInit, + dim536KuoInit, + dim537KuoInit, + dim538KuoInit, + dim539KuoInit, + dim540KuoInit, + dim541KuoInit, + dim542KuoInit, + dim543KuoInit, + dim544KuoInit, + dim545KuoInit, + dim546KuoInit, + dim547KuoInit, + dim548KuoInit, + dim549KuoInit, + dim550KuoInit, + dim551KuoInit, + dim552KuoInit, + dim553KuoInit, + dim554KuoInit, + dim555KuoInit, + dim556KuoInit, + dim557KuoInit, + dim558KuoInit, + dim559KuoInit, + dim560KuoInit, + dim561KuoInit, + dim562KuoInit, + dim563KuoInit, + dim564KuoInit, + dim565KuoInit, + dim566KuoInit, + dim567KuoInit, + dim568KuoInit, + dim569KuoInit, + dim570KuoInit, + dim571KuoInit, + dim572KuoInit, + dim573KuoInit, + dim574KuoInit, + dim575KuoInit, + dim576KuoInit, + dim577KuoInit, + dim578KuoInit, + dim579KuoInit, + dim580KuoInit, + dim581KuoInit, + dim582KuoInit, + dim583KuoInit, + dim584KuoInit, + dim585KuoInit, + dim586KuoInit, + dim587KuoInit, + dim588KuoInit, + dim589KuoInit, + dim590KuoInit, + dim591KuoInit, + dim592KuoInit, + dim593KuoInit, + dim594KuoInit, + dim595KuoInit, + dim596KuoInit, + dim597KuoInit, + dim598KuoInit, + dim599KuoInit, + dim600KuoInit, + dim601KuoInit, + dim602KuoInit, + dim603KuoInit, + dim604KuoInit, + dim605KuoInit, + dim606KuoInit, + dim607KuoInit, + dim608KuoInit, + dim609KuoInit, + dim610KuoInit, + dim611KuoInit, + dim612KuoInit, + dim613KuoInit, + dim614KuoInit, + dim615KuoInit, + dim616KuoInit, + dim617KuoInit, + dim618KuoInit, + dim619KuoInit, + dim620KuoInit, + dim621KuoInit, + dim622KuoInit, + dim623KuoInit, + dim624KuoInit, + dim625KuoInit, + dim626KuoInit, + dim627KuoInit, + dim628KuoInit, + dim629KuoInit, + dim630KuoInit, + dim631KuoInit, + dim632KuoInit, + dim633KuoInit, + dim634KuoInit, + dim635KuoInit, + dim636KuoInit, + dim637KuoInit, + dim638KuoInit, + dim639KuoInit, + dim640KuoInit, + dim641KuoInit, + dim642KuoInit, + dim643KuoInit, + dim644KuoInit, + dim645KuoInit, + dim646KuoInit, + dim647KuoInit, + dim648KuoInit, + dim649KuoInit, + dim650KuoInit, + dim651KuoInit, + dim652KuoInit, + dim653KuoInit, + dim654KuoInit, + dim655KuoInit, + dim656KuoInit, + dim657KuoInit, + dim658KuoInit, + dim659KuoInit, + dim660KuoInit, + dim661KuoInit, + dim662KuoInit, + dim663KuoInit, + dim664KuoInit, + dim665KuoInit, + dim666KuoInit, + dim667KuoInit, + dim668KuoInit, + dim669KuoInit, + dim670KuoInit, + dim671KuoInit, + dim672KuoInit, + dim673KuoInit, + dim674KuoInit, + dim675KuoInit, + dim676KuoInit, + dim677KuoInit, + dim678KuoInit, + dim679KuoInit, + dim680KuoInit, + dim681KuoInit, + dim682KuoInit, + dim683KuoInit, + dim684KuoInit, + dim685KuoInit, + dim686KuoInit, + dim687KuoInit, + dim688KuoInit, + dim689KuoInit, + dim690KuoInit, + dim691KuoInit, + dim692KuoInit, + dim693KuoInit, + dim694KuoInit, + dim695KuoInit, + dim696KuoInit, + dim697KuoInit, + dim698KuoInit, + dim699KuoInit, + dim700KuoInit, + dim701KuoInit, + dim702KuoInit, + dim703KuoInit, + dim704KuoInit, + dim705KuoInit, + dim706KuoInit, + dim707KuoInit, + dim708KuoInit, + dim709KuoInit, + dim710KuoInit, + dim711KuoInit, + dim712KuoInit, + dim713KuoInit, + dim714KuoInit, + dim715KuoInit, + dim716KuoInit, + dim717KuoInit, + dim718KuoInit, + dim719KuoInit, + dim720KuoInit, + dim721KuoInit, + dim722KuoInit, + dim723KuoInit, + dim724KuoInit, + dim725KuoInit, + dim726KuoInit, + dim727KuoInit, + dim728KuoInit, + dim729KuoInit, + dim730KuoInit, + dim731KuoInit, + dim732KuoInit, + dim733KuoInit, + dim734KuoInit, + dim735KuoInit, + dim736KuoInit, + dim737KuoInit, + dim738KuoInit, + dim739KuoInit, + dim740KuoInit, + dim741KuoInit, + dim742KuoInit, + dim743KuoInit, + dim744KuoInit, + dim745KuoInit, + dim746KuoInit, + dim747KuoInit, + dim748KuoInit, + dim749KuoInit, + dim750KuoInit, + dim751KuoInit, + dim752KuoInit, + dim753KuoInit, + dim754KuoInit, + dim755KuoInit, + dim756KuoInit, + dim757KuoInit, + dim758KuoInit, + dim759KuoInit, + dim760KuoInit, + dim761KuoInit, + dim762KuoInit, + dim763KuoInit, + dim764KuoInit, + dim765KuoInit, + dim766KuoInit, + dim767KuoInit, + dim768KuoInit, + dim769KuoInit, + dim770KuoInit, + dim771KuoInit, + dim772KuoInit, + dim773KuoInit, + dim774KuoInit, + dim775KuoInit, + dim776KuoInit, + dim777KuoInit, + dim778KuoInit, + dim779KuoInit, + dim780KuoInit, + dim781KuoInit, + dim782KuoInit, + dim783KuoInit, + dim784KuoInit, + dim785KuoInit, + dim786KuoInit, + dim787KuoInit, + dim788KuoInit, + dim789KuoInit, + dim790KuoInit, + dim791KuoInit, + dim792KuoInit, + dim793KuoInit, + dim794KuoInit, + dim795KuoInit, + dim796KuoInit, + dim797KuoInit, + dim798KuoInit, + dim799KuoInit, + dim800KuoInit, + dim801KuoInit, + dim802KuoInit, + dim803KuoInit, + dim804KuoInit, + dim805KuoInit, + dim806KuoInit, + dim807KuoInit, + dim808KuoInit, + dim809KuoInit, + dim810KuoInit, + dim811KuoInit, + dim812KuoInit, + dim813KuoInit, + dim814KuoInit, + dim815KuoInit, + dim816KuoInit, + dim817KuoInit, + dim818KuoInit, + dim819KuoInit, + dim820KuoInit, + dim821KuoInit, + dim822KuoInit, + dim823KuoInit, + dim824KuoInit, + dim825KuoInit, + dim826KuoInit, + dim827KuoInit, + dim828KuoInit, + dim829KuoInit, + dim830KuoInit, + dim831KuoInit, + dim832KuoInit, + dim833KuoInit, + dim834KuoInit, + dim835KuoInit, + dim836KuoInit, + dim837KuoInit, + dim838KuoInit, + dim839KuoInit, + dim840KuoInit, + dim841KuoInit, + dim842KuoInit, + dim843KuoInit, + dim844KuoInit, + dim845KuoInit, + dim846KuoInit, + dim847KuoInit, + dim848KuoInit, + dim849KuoInit, + dim850KuoInit, + dim851KuoInit, + dim852KuoInit, + dim853KuoInit, + dim854KuoInit, + dim855KuoInit, + dim856KuoInit, + dim857KuoInit, + dim858KuoInit, + dim859KuoInit, + dim860KuoInit, + dim861KuoInit, + dim862KuoInit, + dim863KuoInit, + dim864KuoInit, + dim865KuoInit, + dim866KuoInit, + dim867KuoInit, + dim868KuoInit, + dim869KuoInit, + dim870KuoInit, + dim871KuoInit, + dim872KuoInit, + dim873KuoInit, + dim874KuoInit, + dim875KuoInit, + dim876KuoInit, + dim877KuoInit, + dim878KuoInit, + dim879KuoInit, + dim880KuoInit, + dim881KuoInit, + dim882KuoInit, + dim883KuoInit, + dim884KuoInit, + dim885KuoInit, + dim886KuoInit, + dim887KuoInit, + dim888KuoInit, + dim889KuoInit, + dim890KuoInit, + dim891KuoInit, + dim892KuoInit, + dim893KuoInit, + dim894KuoInit, + dim895KuoInit, + dim896KuoInit, + dim897KuoInit, + dim898KuoInit, + dim899KuoInit, + dim900KuoInit, + dim901KuoInit, + dim902KuoInit, + dim903KuoInit, + dim904KuoInit, + dim905KuoInit, + dim906KuoInit, + dim907KuoInit, + dim908KuoInit, + dim909KuoInit, + dim910KuoInit, + dim911KuoInit, + dim912KuoInit, + dim913KuoInit, + dim914KuoInit, + dim915KuoInit, + dim916KuoInit, + dim917KuoInit, + dim918KuoInit, + dim919KuoInit, + dim920KuoInit, + dim921KuoInit, + dim922KuoInit, + dim923KuoInit, + dim924KuoInit, + dim925KuoInit, + dim926KuoInit, + dim927KuoInit, + dim928KuoInit, + dim929KuoInit, + dim930KuoInit, + dim931KuoInit, + dim932KuoInit, + dim933KuoInit, + dim934KuoInit, + dim935KuoInit, + dim936KuoInit, + dim937KuoInit, + dim938KuoInit, + dim939KuoInit, + dim940KuoInit, + dim941KuoInit, + dim942KuoInit, + dim943KuoInit, + dim944KuoInit, + dim945KuoInit, + dim946KuoInit, + dim947KuoInit, + dim948KuoInit, + dim949KuoInit, + dim950KuoInit, + dim951KuoInit, + dim952KuoInit, + dim953KuoInit, + dim954KuoInit, + dim955KuoInit, + dim956KuoInit, + dim957KuoInit, + dim958KuoInit, + dim959KuoInit, + dim960KuoInit, + dim961KuoInit, + dim962KuoInit, + dim963KuoInit, + dim964KuoInit, + dim965KuoInit, + dim966KuoInit, + dim967KuoInit, + dim968KuoInit, + dim969KuoInit, + dim970KuoInit, + dim971KuoInit, + dim972KuoInit, + dim973KuoInit, + dim974KuoInit, + dim975KuoInit, + dim976KuoInit, + dim977KuoInit, + dim978KuoInit, + dim979KuoInit, + dim980KuoInit, + dim981KuoInit, + dim982KuoInit, + dim983KuoInit, + dim984KuoInit, + dim985KuoInit, + dim986KuoInit, + dim987KuoInit, + dim988KuoInit, + dim989KuoInit, + dim990KuoInit, + dim991KuoInit, + dim992KuoInit, + dim993KuoInit, + dim994KuoInit, + dim995KuoInit, + dim996KuoInit, + dim997KuoInit, + dim998KuoInit, + dim999KuoInit, + dim1000KuoInit, + dim1001KuoInit, + dim1002KuoInit, + dim1003KuoInit, + dim1004KuoInit, + dim1005KuoInit, + dim1006KuoInit, + dim1007KuoInit, + dim1008KuoInit, + dim1009KuoInit, + dim1010KuoInit, + dim1011KuoInit, + dim1012KuoInit, + dim1013KuoInit, + dim1014KuoInit, + dim1015KuoInit, + dim1016KuoInit, + dim1017KuoInit, + dim1018KuoInit, + dim1019KuoInit, + dim1020KuoInit, + dim1021KuoInit, + dim1022KuoInit, + dim1023KuoInit, + dim1024KuoInit, + dim1025KuoInit, + dim1026KuoInit, + dim1027KuoInit, + dim1028KuoInit, + dim1029KuoInit, + dim1030KuoInit, + dim1031KuoInit, + dim1032KuoInit, + dim1033KuoInit, + dim1034KuoInit, + dim1035KuoInit, + dim1036KuoInit, + dim1037KuoInit, + dim1038KuoInit, + dim1039KuoInit, + dim1040KuoInit, + dim1041KuoInit, + dim1042KuoInit, + dim1043KuoInit, + dim1044KuoInit, + dim1045KuoInit, + dim1046KuoInit, + dim1047KuoInit, + dim1048KuoInit, + dim1049KuoInit, + dim1050KuoInit, + dim1051KuoInit, + dim1052KuoInit, + dim1053KuoInit, + dim1054KuoInit, + dim1055KuoInit, + dim1056KuoInit, + dim1057KuoInit, + dim1058KuoInit, + dim1059KuoInit, + dim1060KuoInit, + dim1061KuoInit, + dim1062KuoInit, + dim1063KuoInit, + dim1064KuoInit, + dim1065KuoInit, + dim1066KuoInit, + dim1067KuoInit, + dim1068KuoInit, + dim1069KuoInit, + dim1070KuoInit, + dim1071KuoInit, + dim1072KuoInit, + dim1073KuoInit, + dim1074KuoInit, + dim1075KuoInit, + dim1076KuoInit, + dim1077KuoInit, + dim1078KuoInit, + dim1079KuoInit, + dim1080KuoInit, + dim1081KuoInit, + dim1082KuoInit, + dim1083KuoInit, + dim1084KuoInit, + dim1085KuoInit, + dim1086KuoInit, + dim1087KuoInit, + dim1088KuoInit, + dim1089KuoInit, + dim1090KuoInit, + dim1091KuoInit, + dim1092KuoInit, + dim1093KuoInit, + dim1094KuoInit, + dim1095KuoInit, + dim1096KuoInit, + dim1097KuoInit, + dim1098KuoInit, + dim1099KuoInit, + dim1100KuoInit, + dim1101KuoInit, + dim1102KuoInit, + dim1103KuoInit, + dim1104KuoInit, + dim1105KuoInit, + dim1106KuoInit, + dim1107KuoInit, + dim1108KuoInit, + dim1109KuoInit, + dim1110KuoInit, + dim1111KuoInit, + dim1112KuoInit, + dim1113KuoInit, + dim1114KuoInit, + dim1115KuoInit, + dim1116KuoInit, + dim1117KuoInit, + dim1118KuoInit, + dim1119KuoInit, + dim1120KuoInit, + dim1121KuoInit, + dim1122KuoInit, + dim1123KuoInit, + dim1124KuoInit, + dim1125KuoInit, + dim1126KuoInit, + dim1127KuoInit, + dim1128KuoInit, + dim1129KuoInit, + dim1130KuoInit, + dim1131KuoInit, + dim1132KuoInit, + dim1133KuoInit, + dim1134KuoInit, + dim1135KuoInit, + dim1136KuoInit, + dim1137KuoInit, + dim1138KuoInit, + dim1139KuoInit, + dim1140KuoInit, + dim1141KuoInit, + dim1142KuoInit, + dim1143KuoInit, + dim1144KuoInit, + dim1145KuoInit, + dim1146KuoInit, + dim1147KuoInit, + dim1148KuoInit, + dim1149KuoInit, + dim1150KuoInit, + dim1151KuoInit, + dim1152KuoInit, + dim1153KuoInit, + dim1154KuoInit, + dim1155KuoInit, + dim1156KuoInit, + dim1157KuoInit, + dim1158KuoInit, + dim1159KuoInit, + dim1160KuoInit, + dim1161KuoInit, + dim1162KuoInit, + dim1163KuoInit, + dim1164KuoInit, + dim1165KuoInit, + dim1166KuoInit, + dim1167KuoInit, + dim1168KuoInit, + dim1169KuoInit, + dim1170KuoInit, + dim1171KuoInit, + dim1172KuoInit, + dim1173KuoInit, + dim1174KuoInit, + dim1175KuoInit, + dim1176KuoInit, + dim1177KuoInit, + dim1178KuoInit, + dim1179KuoInit, + dim1180KuoInit, + dim1181KuoInit, + dim1182KuoInit, + dim1183KuoInit, + dim1184KuoInit, + dim1185KuoInit, + dim1186KuoInit, + dim1187KuoInit, + dim1188KuoInit, + dim1189KuoInit, + dim1190KuoInit, + dim1191KuoInit, + dim1192KuoInit, + dim1193KuoInit, + dim1194KuoInit, + dim1195KuoInit, + dim1196KuoInit, + dim1197KuoInit, + dim1198KuoInit, + dim1199KuoInit, + dim1200KuoInit, + dim1201KuoInit, + dim1202KuoInit, + dim1203KuoInit, + dim1204KuoInit, + dim1205KuoInit, + dim1206KuoInit, + dim1207KuoInit, + dim1208KuoInit, + dim1209KuoInit, + dim1210KuoInit, + dim1211KuoInit, + dim1212KuoInit, + dim1213KuoInit, + dim1214KuoInit, + dim1215KuoInit, + dim1216KuoInit, + dim1217KuoInit, + dim1218KuoInit, + dim1219KuoInit, + dim1220KuoInit, + dim1221KuoInit, + dim1222KuoInit, + dim1223KuoInit, + dim1224KuoInit, + dim1225KuoInit, + dim1226KuoInit, + dim1227KuoInit, + dim1228KuoInit, + dim1229KuoInit, + dim1230KuoInit, + dim1231KuoInit, + dim1232KuoInit, + dim1233KuoInit, + dim1234KuoInit, + dim1235KuoInit, + dim1236KuoInit, + dim1237KuoInit, + dim1238KuoInit, + dim1239KuoInit, + dim1240KuoInit, + dim1241KuoInit, + dim1242KuoInit, + dim1243KuoInit, + dim1244KuoInit, + dim1245KuoInit, + dim1246KuoInit, + dim1247KuoInit, + dim1248KuoInit, + dim1249KuoInit, + dim1250KuoInit, + dim1251KuoInit, + dim1252KuoInit, + dim1253KuoInit, + dim1254KuoInit, + dim1255KuoInit, + dim1256KuoInit, + dim1257KuoInit, + dim1258KuoInit, + dim1259KuoInit, + dim1260KuoInit, + dim1261KuoInit, + dim1262KuoInit, + dim1263KuoInit, + dim1264KuoInit, + dim1265KuoInit, + dim1266KuoInit, + dim1267KuoInit, + dim1268KuoInit, + dim1269KuoInit, + dim1270KuoInit, + dim1271KuoInit, + dim1272KuoInit, + dim1273KuoInit, + dim1274KuoInit, + dim1275KuoInit, + dim1276KuoInit, + dim1277KuoInit, + dim1278KuoInit, + dim1279KuoInit, + dim1280KuoInit, + dim1281KuoInit, + dim1282KuoInit, + dim1283KuoInit, + dim1284KuoInit, + dim1285KuoInit, + dim1286KuoInit, + dim1287KuoInit, + dim1288KuoInit, + dim1289KuoInit, + dim1290KuoInit, + dim1291KuoInit, + dim1292KuoInit, + dim1293KuoInit, + dim1294KuoInit, + dim1295KuoInit, + dim1296KuoInit, + dim1297KuoInit, + dim1298KuoInit, + dim1299KuoInit, + dim1300KuoInit, + dim1301KuoInit, + dim1302KuoInit, + dim1303KuoInit, + dim1304KuoInit, + dim1305KuoInit, + dim1306KuoInit, + dim1307KuoInit, + dim1308KuoInit, + dim1309KuoInit, + dim1310KuoInit, + dim1311KuoInit, + dim1312KuoInit, + dim1313KuoInit, + dim1314KuoInit, + dim1315KuoInit, + dim1316KuoInit, + dim1317KuoInit, + dim1318KuoInit, + dim1319KuoInit, + dim1320KuoInit, + dim1321KuoInit, + dim1322KuoInit, + dim1323KuoInit, + dim1324KuoInit, + dim1325KuoInit, + dim1326KuoInit, + dim1327KuoInit, + dim1328KuoInit, + dim1329KuoInit, + dim1330KuoInit, + dim1331KuoInit, + dim1332KuoInit, + dim1333KuoInit, + dim1334KuoInit, + dim1335KuoInit, + dim1336KuoInit, + dim1337KuoInit, + dim1338KuoInit, + dim1339KuoInit, + dim1340KuoInit, + dim1341KuoInit, + dim1342KuoInit, + dim1343KuoInit, + dim1344KuoInit, + dim1345KuoInit, + dim1346KuoInit, + dim1347KuoInit, + dim1348KuoInit, + dim1349KuoInit, + dim1350KuoInit, + dim1351KuoInit, + dim1352KuoInit, + dim1353KuoInit, + dim1354KuoInit, + dim1355KuoInit, + dim1356KuoInit, + dim1357KuoInit, + dim1358KuoInit, + dim1359KuoInit, + dim1360KuoInit, + dim1361KuoInit, + dim1362KuoInit, + dim1363KuoInit, + dim1364KuoInit, + dim1365KuoInit, + dim1366KuoInit, + dim1367KuoInit, + dim1368KuoInit, + dim1369KuoInit, + dim1370KuoInit, + dim1371KuoInit, + dim1372KuoInit, + dim1373KuoInit, + dim1374KuoInit, + dim1375KuoInit, + dim1376KuoInit, + dim1377KuoInit, + dim1378KuoInit, + dim1379KuoInit, + dim1380KuoInit, + dim1381KuoInit, + dim1382KuoInit, + dim1383KuoInit, + dim1384KuoInit, + dim1385KuoInit, + dim1386KuoInit, + dim1387KuoInit, + dim1388KuoInit, + dim1389KuoInit, + dim1390KuoInit, + dim1391KuoInit, + dim1392KuoInit, + dim1393KuoInit, + dim1394KuoInit, + dim1395KuoInit, + dim1396KuoInit, + dim1397KuoInit, + dim1398KuoInit, + dim1399KuoInit, + dim1400KuoInit, + dim1401KuoInit, + dim1402KuoInit, + dim1403KuoInit, + dim1404KuoInit, + dim1405KuoInit, + dim1406KuoInit, + dim1407KuoInit, + dim1408KuoInit, + dim1409KuoInit, + dim1410KuoInit, + dim1411KuoInit, + dim1412KuoInit, + dim1413KuoInit, + dim1414KuoInit, + dim1415KuoInit, + dim1416KuoInit, + dim1417KuoInit, + dim1418KuoInit, + dim1419KuoInit, + dim1420KuoInit, + dim1421KuoInit, + dim1422KuoInit, + dim1423KuoInit, + dim1424KuoInit, + dim1425KuoInit, + dim1426KuoInit, + dim1427KuoInit, + dim1428KuoInit, + dim1429KuoInit, + dim1430KuoInit, + dim1431KuoInit, + dim1432KuoInit, + dim1433KuoInit, + dim1434KuoInit, + dim1435KuoInit, + dim1436KuoInit, + dim1437KuoInit, + dim1438KuoInit, + dim1439KuoInit, + dim1440KuoInit, + dim1441KuoInit, + dim1442KuoInit, + dim1443KuoInit, + dim1444KuoInit, + dim1445KuoInit, + dim1446KuoInit, + dim1447KuoInit, + dim1448KuoInit, + dim1449KuoInit, + dim1450KuoInit, + dim1451KuoInit, + dim1452KuoInit, + dim1453KuoInit, + dim1454KuoInit, + dim1455KuoInit, + dim1456KuoInit, + dim1457KuoInit, + dim1458KuoInit, + dim1459KuoInit, + dim1460KuoInit, + dim1461KuoInit, + dim1462KuoInit, + dim1463KuoInit, + dim1464KuoInit, + dim1465KuoInit, + dim1466KuoInit, + dim1467KuoInit, + dim1468KuoInit, + dim1469KuoInit, + dim1470KuoInit, + dim1471KuoInit, + dim1472KuoInit, + dim1473KuoInit, + dim1474KuoInit, + dim1475KuoInit, + dim1476KuoInit, + dim1477KuoInit, + dim1478KuoInit, + dim1479KuoInit, + dim1480KuoInit, + dim1481KuoInit, + dim1482KuoInit, + dim1483KuoInit, + dim1484KuoInit, + dim1485KuoInit, + dim1486KuoInit, + dim1487KuoInit, + dim1488KuoInit, + dim1489KuoInit, + dim1490KuoInit, + dim1491KuoInit, + dim1492KuoInit, + dim1493KuoInit, + dim1494KuoInit, + dim1495KuoInit, + dim1496KuoInit, + dim1497KuoInit, + dim1498KuoInit, + dim1499KuoInit, + dim1500KuoInit, + dim1501KuoInit, + dim1502KuoInit, + dim1503KuoInit, + dim1504KuoInit, + dim1505KuoInit, + dim1506KuoInit, + dim1507KuoInit, + dim1508KuoInit, + dim1509KuoInit, + dim1510KuoInit, + dim1511KuoInit, + dim1512KuoInit, + dim1513KuoInit, + dim1514KuoInit, + dim1515KuoInit, + dim1516KuoInit, + dim1517KuoInit, + dim1518KuoInit, + dim1519KuoInit, + dim1520KuoInit, + dim1521KuoInit, + dim1522KuoInit, + dim1523KuoInit, + dim1524KuoInit, + dim1525KuoInit, + dim1526KuoInit, + dim1527KuoInit, + dim1528KuoInit, + dim1529KuoInit, + dim1530KuoInit, + dim1531KuoInit, + dim1532KuoInit, + dim1533KuoInit, + dim1534KuoInit, + dim1535KuoInit, + dim1536KuoInit, + dim1537KuoInit, + dim1538KuoInit, + dim1539KuoInit, + dim1540KuoInit, + dim1541KuoInit, + dim1542KuoInit, + dim1543KuoInit, + dim1544KuoInit, + dim1545KuoInit, + dim1546KuoInit, + dim1547KuoInit, + dim1548KuoInit, + dim1549KuoInit, + dim1550KuoInit, + dim1551KuoInit, + dim1552KuoInit, + dim1553KuoInit, + dim1554KuoInit, + dim1555KuoInit, + dim1556KuoInit, + dim1557KuoInit, + dim1558KuoInit, + dim1559KuoInit, + dim1560KuoInit, + dim1561KuoInit, + dim1562KuoInit, + dim1563KuoInit, + dim1564KuoInit, + dim1565KuoInit, + dim1566KuoInit, + dim1567KuoInit, + dim1568KuoInit, + dim1569KuoInit, + dim1570KuoInit, + dim1571KuoInit, + dim1572KuoInit, + dim1573KuoInit, + dim1574KuoInit, + dim1575KuoInit, + dim1576KuoInit, + dim1577KuoInit, + dim1578KuoInit, + dim1579KuoInit, + dim1580KuoInit, + dim1581KuoInit, + dim1582KuoInit, + dim1583KuoInit, + dim1584KuoInit, + dim1585KuoInit, + dim1586KuoInit, + dim1587KuoInit, + dim1588KuoInit, + dim1589KuoInit, + dim1590KuoInit, + dim1591KuoInit, + dim1592KuoInit, + dim1593KuoInit, + dim1594KuoInit, + dim1595KuoInit, + dim1596KuoInit, + dim1597KuoInit, + dim1598KuoInit, + dim1599KuoInit, + dim1600KuoInit, + dim1601KuoInit, + dim1602KuoInit, + dim1603KuoInit, + dim1604KuoInit, + dim1605KuoInit, + dim1606KuoInit, + dim1607KuoInit, + dim1608KuoInit, + dim1609KuoInit, + dim1610KuoInit, + dim1611KuoInit, + dim1612KuoInit, + dim1613KuoInit, + dim1614KuoInit, + dim1615KuoInit, + dim1616KuoInit, + dim1617KuoInit, + dim1618KuoInit, + dim1619KuoInit, + dim1620KuoInit, + dim1621KuoInit, + dim1622KuoInit, + dim1623KuoInit, + dim1624KuoInit, + dim1625KuoInit, + dim1626KuoInit, + dim1627KuoInit, + dim1628KuoInit, + dim1629KuoInit, + dim1630KuoInit, + dim1631KuoInit, + dim1632KuoInit, + dim1633KuoInit, + dim1634KuoInit, + dim1635KuoInit, + dim1636KuoInit, + dim1637KuoInit, + dim1638KuoInit, + dim1639KuoInit, + dim1640KuoInit, + dim1641KuoInit, + dim1642KuoInit, + dim1643KuoInit, + dim1644KuoInit, + dim1645KuoInit, + dim1646KuoInit, + dim1647KuoInit, + dim1648KuoInit, + dim1649KuoInit, + dim1650KuoInit, + dim1651KuoInit, + dim1652KuoInit, + dim1653KuoInit, + dim1654KuoInit, + dim1655KuoInit, + dim1656KuoInit, + dim1657KuoInit, + dim1658KuoInit, + dim1659KuoInit, + dim1660KuoInit, + dim1661KuoInit, + dim1662KuoInit, + dim1663KuoInit, + dim1664KuoInit, + dim1665KuoInit, + dim1666KuoInit, + dim1667KuoInit, + dim1668KuoInit, + dim1669KuoInit, + dim1670KuoInit, + dim1671KuoInit, + dim1672KuoInit, + dim1673KuoInit, + dim1674KuoInit, + dim1675KuoInit, + dim1676KuoInit, + dim1677KuoInit, + dim1678KuoInit, + dim1679KuoInit, + dim1680KuoInit, + dim1681KuoInit, + dim1682KuoInit, + dim1683KuoInit, + dim1684KuoInit, + dim1685KuoInit, + dim1686KuoInit, + dim1687KuoInit, + dim1688KuoInit, + dim1689KuoInit, + dim1690KuoInit, + dim1691KuoInit, + dim1692KuoInit, + dim1693KuoInit, + dim1694KuoInit, + dim1695KuoInit, + dim1696KuoInit, + dim1697KuoInit, + dim1698KuoInit, + dim1699KuoInit, + dim1700KuoInit, + dim1701KuoInit, + dim1702KuoInit, + dim1703KuoInit, + dim1704KuoInit, + dim1705KuoInit, + dim1706KuoInit, + dim1707KuoInit, + dim1708KuoInit, + dim1709KuoInit, + dim1710KuoInit, + dim1711KuoInit, + dim1712KuoInit, + dim1713KuoInit, + dim1714KuoInit, + dim1715KuoInit, + dim1716KuoInit, + dim1717KuoInit, + dim1718KuoInit, + dim1719KuoInit, + dim1720KuoInit, + dim1721KuoInit, + dim1722KuoInit, + dim1723KuoInit, + dim1724KuoInit, + dim1725KuoInit, + dim1726KuoInit, + dim1727KuoInit, + dim1728KuoInit, + dim1729KuoInit, + dim1730KuoInit, + dim1731KuoInit, + dim1732KuoInit, + dim1733KuoInit, + dim1734KuoInit, + dim1735KuoInit, + dim1736KuoInit, + dim1737KuoInit, + dim1738KuoInit, + dim1739KuoInit, + dim1740KuoInit, + dim1741KuoInit, + dim1742KuoInit, + dim1743KuoInit, + dim1744KuoInit, + dim1745KuoInit, + dim1746KuoInit, + dim1747KuoInit, + dim1748KuoInit, + dim1749KuoInit, + dim1750KuoInit, + dim1751KuoInit, + dim1752KuoInit, + dim1753KuoInit, + dim1754KuoInit, + dim1755KuoInit, + dim1756KuoInit, + dim1757KuoInit, + dim1758KuoInit, + dim1759KuoInit, + dim1760KuoInit, + dim1761KuoInit, + dim1762KuoInit, + dim1763KuoInit, + dim1764KuoInit, + dim1765KuoInit, + dim1766KuoInit, + dim1767KuoInit, + dim1768KuoInit, + dim1769KuoInit, + dim1770KuoInit, + dim1771KuoInit, + dim1772KuoInit, + dim1773KuoInit, + dim1774KuoInit, + dim1775KuoInit, + dim1776KuoInit, + dim1777KuoInit, + dim1778KuoInit, + dim1779KuoInit, + dim1780KuoInit, + dim1781KuoInit, + dim1782KuoInit, + dim1783KuoInit, + dim1784KuoInit, + dim1785KuoInit, + dim1786KuoInit, + dim1787KuoInit, + dim1788KuoInit, + dim1789KuoInit, + dim1790KuoInit, + dim1791KuoInit, + dim1792KuoInit, + dim1793KuoInit, + dim1794KuoInit, + dim1795KuoInit, + dim1796KuoInit, + dim1797KuoInit, + dim1798KuoInit, + dim1799KuoInit, + dim1800KuoInit, + dim1801KuoInit, + dim1802KuoInit, + dim1803KuoInit, + dim1804KuoInit, + dim1805KuoInit, + dim1806KuoInit, + dim1807KuoInit, + dim1808KuoInit, + dim1809KuoInit, + dim1810KuoInit, + dim1811KuoInit, + dim1812KuoInit, + dim1813KuoInit, + dim1814KuoInit, + dim1815KuoInit, + dim1816KuoInit, + dim1817KuoInit, + dim1818KuoInit, + dim1819KuoInit, + dim1820KuoInit, + dim1821KuoInit, + dim1822KuoInit, + dim1823KuoInit, + dim1824KuoInit, + dim1825KuoInit, + dim1826KuoInit, + dim1827KuoInit, + dim1828KuoInit, + dim1829KuoInit, + dim1830KuoInit, + dim1831KuoInit, + dim1832KuoInit, + dim1833KuoInit, + dim1834KuoInit, + dim1835KuoInit, + dim1836KuoInit, + dim1837KuoInit, + dim1838KuoInit, + dim1839KuoInit, + dim1840KuoInit, + dim1841KuoInit, + dim1842KuoInit, + dim1843KuoInit, + dim1844KuoInit, + dim1845KuoInit, + dim1846KuoInit, + dim1847KuoInit, + dim1848KuoInit, + dim1849KuoInit, + dim1850KuoInit, + dim1851KuoInit, + dim1852KuoInit, + dim1853KuoInit, + dim1854KuoInit, + dim1855KuoInit, + dim1856KuoInit, + dim1857KuoInit, + dim1858KuoInit, + dim1859KuoInit, + dim1860KuoInit, + dim1861KuoInit, + dim1862KuoInit, + dim1863KuoInit, + dim1864KuoInit, + dim1865KuoInit, + dim1866KuoInit, + dim1867KuoInit, + dim1868KuoInit, + dim1869KuoInit, + dim1870KuoInit, + dim1871KuoInit, + dim1872KuoInit, + dim1873KuoInit, + dim1874KuoInit, + dim1875KuoInit, + dim1876KuoInit, + dim1877KuoInit, + dim1878KuoInit, + dim1879KuoInit, + dim1880KuoInit, + dim1881KuoInit, + dim1882KuoInit, + dim1883KuoInit, + dim1884KuoInit, + dim1885KuoInit, + dim1886KuoInit, + dim1887KuoInit, + dim1888KuoInit, + dim1889KuoInit, + dim1890KuoInit, + dim1891KuoInit, + dim1892KuoInit, + dim1893KuoInit, + dim1894KuoInit, + dim1895KuoInit, + dim1896KuoInit, + dim1897KuoInit, + dim1898KuoInit, + dim1899KuoInit, + dim1900KuoInit, + dim1901KuoInit, + dim1902KuoInit, + dim1903KuoInit, + dim1904KuoInit, + dim1905KuoInit, + dim1906KuoInit, + dim1907KuoInit, + dim1908KuoInit, + dim1909KuoInit, + dim1910KuoInit, + dim1911KuoInit, + dim1912KuoInit, + dim1913KuoInit, + dim1914KuoInit, + dim1915KuoInit, + dim1916KuoInit, + dim1917KuoInit, + dim1918KuoInit, + dim1919KuoInit, + dim1920KuoInit, + dim1921KuoInit, + dim1922KuoInit, + dim1923KuoInit, + dim1924KuoInit, + dim1925KuoInit, + dim1926KuoInit, + dim1927KuoInit, + dim1928KuoInit, + dim1929KuoInit, + dim1930KuoInit, + dim1931KuoInit, + dim1932KuoInit, + dim1933KuoInit, + dim1934KuoInit, + dim1935KuoInit, + dim1936KuoInit, + dim1937KuoInit, + dim1938KuoInit, + dim1939KuoInit, + dim1940KuoInit, + dim1941KuoInit, + dim1942KuoInit, + dim1943KuoInit, + dim1944KuoInit, + dim1945KuoInit, + dim1946KuoInit, + dim1947KuoInit, + dim1948KuoInit, + dim1949KuoInit, + dim1950KuoInit, + dim1951KuoInit, + dim1952KuoInit, + dim1953KuoInit, + dim1954KuoInit, + dim1955KuoInit, + dim1956KuoInit, + dim1957KuoInit, + dim1958KuoInit, + dim1959KuoInit, + dim1960KuoInit, + dim1961KuoInit, + dim1962KuoInit, + dim1963KuoInit, + dim1964KuoInit, + dim1965KuoInit, + dim1966KuoInit, + dim1967KuoInit, + dim1968KuoInit, + dim1969KuoInit, + dim1970KuoInit, + dim1971KuoInit, + dim1972KuoInit, + dim1973KuoInit, + dim1974KuoInit, + dim1975KuoInit, + dim1976KuoInit, + dim1977KuoInit, + dim1978KuoInit, + dim1979KuoInit, + dim1980KuoInit, + dim1981KuoInit, + dim1982KuoInit, + dim1983KuoInit, + dim1984KuoInit, + dim1985KuoInit, + dim1986KuoInit, + dim1987KuoInit, + dim1988KuoInit, + dim1989KuoInit, + dim1990KuoInit, + dim1991KuoInit, + dim1992KuoInit, + dim1993KuoInit, + dim1994KuoInit, + dim1995KuoInit, + dim1996KuoInit, + dim1997KuoInit, + dim1998KuoInit, + dim1999KuoInit, + dim2000KuoInit, + dim2001KuoInit, + dim2002KuoInit, + dim2003KuoInit, + dim2004KuoInit, + dim2005KuoInit, + dim2006KuoInit, + dim2007KuoInit, + dim2008KuoInit, + dim2009KuoInit, + dim2010KuoInit, + dim2011KuoInit, + dim2012KuoInit, + dim2013KuoInit, + dim2014KuoInit, + dim2015KuoInit, + dim2016KuoInit, + dim2017KuoInit, + dim2018KuoInit, + dim2019KuoInit, + dim2020KuoInit, + dim2021KuoInit, + dim2022KuoInit, + dim2023KuoInit, + dim2024KuoInit, + dim2025KuoInit, + dim2026KuoInit, + dim2027KuoInit, + dim2028KuoInit, + dim2029KuoInit, + dim2030KuoInit, + dim2031KuoInit, + dim2032KuoInit, + dim2033KuoInit, + dim2034KuoInit, + dim2035KuoInit, + dim2036KuoInit, + dim2037KuoInit, + dim2038KuoInit, + dim2039KuoInit, + dim2040KuoInit, + dim2041KuoInit, + dim2042KuoInit, + dim2043KuoInit, + dim2044KuoInit, + dim2045KuoInit, + dim2046KuoInit, + dim2047KuoInit, + dim2048KuoInit, + dim2049KuoInit, + dim2050KuoInit, + dim2051KuoInit, + dim2052KuoInit, + dim2053KuoInit, + dim2054KuoInit, + dim2055KuoInit, + dim2056KuoInit, + dim2057KuoInit, + dim2058KuoInit, + dim2059KuoInit, + dim2060KuoInit, + dim2061KuoInit, + dim2062KuoInit, + dim2063KuoInit, + dim2064KuoInit, + dim2065KuoInit, + dim2066KuoInit, + dim2067KuoInit, + dim2068KuoInit, + dim2069KuoInit, + dim2070KuoInit, + dim2071KuoInit, + dim2072KuoInit, + dim2073KuoInit, + dim2074KuoInit, + dim2075KuoInit, + dim2076KuoInit, + dim2077KuoInit, + dim2078KuoInit, + dim2079KuoInit, + dim2080KuoInit, + dim2081KuoInit, + dim2082KuoInit, + dim2083KuoInit, + dim2084KuoInit, + dim2085KuoInit, + dim2086KuoInit, + dim2087KuoInit, + dim2088KuoInit, + dim2089KuoInit, + dim2090KuoInit, + dim2091KuoInit, + dim2092KuoInit, + dim2093KuoInit, + dim2094KuoInit, + dim2095KuoInit, + dim2096KuoInit, + dim2097KuoInit, + dim2098KuoInit, + dim2099KuoInit, + dim2100KuoInit, + dim2101KuoInit, + dim2102KuoInit, + dim2103KuoInit, + dim2104KuoInit, + dim2105KuoInit, + dim2106KuoInit, + dim2107KuoInit, + dim2108KuoInit, + dim2109KuoInit, + dim2110KuoInit, + dim2111KuoInit, + dim2112KuoInit, + dim2113KuoInit, + dim2114KuoInit, + dim2115KuoInit, + dim2116KuoInit, + dim2117KuoInit, + dim2118KuoInit, + dim2119KuoInit, + dim2120KuoInit, + dim2121KuoInit, + dim2122KuoInit, + dim2123KuoInit, + dim2124KuoInit, + dim2125KuoInit, + dim2126KuoInit, + dim2127KuoInit, + dim2128KuoInit, + dim2129KuoInit, + dim2130KuoInit, + dim2131KuoInit, + dim2132KuoInit, + dim2133KuoInit, + dim2134KuoInit, + dim2135KuoInit, + dim2136KuoInit, + dim2137KuoInit, + dim2138KuoInit, + dim2139KuoInit, + dim2140KuoInit, + dim2141KuoInit, + dim2142KuoInit, + dim2143KuoInit, + dim2144KuoInit, + dim2145KuoInit, + dim2146KuoInit, + dim2147KuoInit, + dim2148KuoInit, + dim2149KuoInit, + dim2150KuoInit, + dim2151KuoInit, + dim2152KuoInit, + dim2153KuoInit, + dim2154KuoInit, + dim2155KuoInit, + dim2156KuoInit, + dim2157KuoInit, + dim2158KuoInit, + dim2159KuoInit, + dim2160KuoInit, + dim2161KuoInit, + dim2162KuoInit, + dim2163KuoInit, + dim2164KuoInit, + dim2165KuoInit, + dim2166KuoInit, + dim2167KuoInit, + dim2168KuoInit, + dim2169KuoInit, + dim2170KuoInit, + dim2171KuoInit, + dim2172KuoInit, + dim2173KuoInit, + dim2174KuoInit, + dim2175KuoInit, + dim2176KuoInit, + dim2177KuoInit, + dim2178KuoInit, + dim2179KuoInit, + dim2180KuoInit, + dim2181KuoInit, + dim2182KuoInit, + dim2183KuoInit, + dim2184KuoInit, + dim2185KuoInit, + dim2186KuoInit, + dim2187KuoInit, + dim2188KuoInit, + dim2189KuoInit, + dim2190KuoInit, + dim2191KuoInit, + dim2192KuoInit, + dim2193KuoInit, + dim2194KuoInit, + dim2195KuoInit, + dim2196KuoInit, + dim2197KuoInit, + dim2198KuoInit, + dim2199KuoInit, + dim2200KuoInit, + dim2201KuoInit, + dim2202KuoInit, + dim2203KuoInit, + dim2204KuoInit, + dim2205KuoInit, + dim2206KuoInit, + dim2207KuoInit, + dim2208KuoInit, + dim2209KuoInit, + dim2210KuoInit, + dim2211KuoInit, + dim2212KuoInit, + dim2213KuoInit, + dim2214KuoInit, + dim2215KuoInit, + dim2216KuoInit, + dim2217KuoInit, + dim2218KuoInit, + dim2219KuoInit, + dim2220KuoInit, + dim2221KuoInit, + dim2222KuoInit, + dim2223KuoInit, + dim2224KuoInit, + dim2225KuoInit, + dim2226KuoInit, + dim2227KuoInit, + dim2228KuoInit, + dim2229KuoInit, + dim2230KuoInit, + dim2231KuoInit, + dim2232KuoInit, + dim2233KuoInit, + dim2234KuoInit, + dim2235KuoInit, + dim2236KuoInit, + dim2237KuoInit, + dim2238KuoInit, + dim2239KuoInit, + dim2240KuoInit, + dim2241KuoInit, + dim2242KuoInit, + dim2243KuoInit, + dim2244KuoInit, + dim2245KuoInit, + dim2246KuoInit, + dim2247KuoInit, + dim2248KuoInit, + dim2249KuoInit, + dim2250KuoInit, + dim2251KuoInit, + dim2252KuoInit, + dim2253KuoInit, + dim2254KuoInit, + dim2255KuoInit, + dim2256KuoInit, + dim2257KuoInit, + dim2258KuoInit, + dim2259KuoInit, + dim2260KuoInit, + dim2261KuoInit, + dim2262KuoInit, + dim2263KuoInit, + dim2264KuoInit, + dim2265KuoInit, + dim2266KuoInit, + dim2267KuoInit, + dim2268KuoInit, + dim2269KuoInit, + dim2270KuoInit, + dim2271KuoInit, + dim2272KuoInit, + dim2273KuoInit, + dim2274KuoInit, + dim2275KuoInit, + dim2276KuoInit, + dim2277KuoInit, + dim2278KuoInit, + dim2279KuoInit, + dim2280KuoInit, + dim2281KuoInit, + dim2282KuoInit, + dim2283KuoInit, + dim2284KuoInit, + dim2285KuoInit, + dim2286KuoInit, + dim2287KuoInit, + dim2288KuoInit, + dim2289KuoInit, + dim2290KuoInit, + dim2291KuoInit, + dim2292KuoInit, + dim2293KuoInit, + dim2294KuoInit, + dim2295KuoInit, + dim2296KuoInit, + dim2297KuoInit, + dim2298KuoInit, + dim2299KuoInit, + dim2300KuoInit, + dim2301KuoInit, + dim2302KuoInit, + dim2303KuoInit, + dim2304KuoInit, + dim2305KuoInit, + dim2306KuoInit, + dim2307KuoInit, + dim2308KuoInit, + dim2309KuoInit, + dim2310KuoInit, + dim2311KuoInit, + dim2312KuoInit, + dim2313KuoInit, + dim2314KuoInit, + dim2315KuoInit, + dim2316KuoInit, + dim2317KuoInit, + dim2318KuoInit, + dim2319KuoInit, + dim2320KuoInit, + dim2321KuoInit, + dim2322KuoInit, + dim2323KuoInit, + dim2324KuoInit, + dim2325KuoInit, + dim2326KuoInit, + dim2327KuoInit, + dim2328KuoInit, + dim2329KuoInit, + dim2330KuoInit, + dim2331KuoInit, + dim2332KuoInit, + dim2333KuoInit, + dim2334KuoInit, + dim2335KuoInit, + dim2336KuoInit, + dim2337KuoInit, + dim2338KuoInit, + dim2339KuoInit, + dim2340KuoInit, + dim2341KuoInit, + dim2342KuoInit, + dim2343KuoInit, + dim2344KuoInit, + dim2345KuoInit, + dim2346KuoInit, + dim2347KuoInit, + dim2348KuoInit, + dim2349KuoInit, + dim2350KuoInit, + dim2351KuoInit, + dim2352KuoInit, + dim2353KuoInit, + dim2354KuoInit, + dim2355KuoInit, + dim2356KuoInit, + dim2357KuoInit, + dim2358KuoInit, + dim2359KuoInit, + dim2360KuoInit, + dim2361KuoInit, + dim2362KuoInit, + dim2363KuoInit, + dim2364KuoInit, + dim2365KuoInit, + dim2366KuoInit, + dim2367KuoInit, + dim2368KuoInit, + dim2369KuoInit, + dim2370KuoInit, + dim2371KuoInit, + dim2372KuoInit, + dim2373KuoInit, + dim2374KuoInit, + dim2375KuoInit, + dim2376KuoInit, + dim2377KuoInit, + dim2378KuoInit, + dim2379KuoInit, + dim2380KuoInit, + dim2381KuoInit, + dim2382KuoInit, + dim2383KuoInit, + dim2384KuoInit, + dim2385KuoInit, + dim2386KuoInit, + dim2387KuoInit, + dim2388KuoInit, + dim2389KuoInit, + dim2390KuoInit, + dim2391KuoInit, + dim2392KuoInit, + dim2393KuoInit, + dim2394KuoInit, + dim2395KuoInit, + dim2396KuoInit, + dim2397KuoInit, + dim2398KuoInit, + dim2399KuoInit, + dim2400KuoInit, + dim2401KuoInit, + dim2402KuoInit, + dim2403KuoInit, + dim2404KuoInit, + dim2405KuoInit, + dim2406KuoInit, + dim2407KuoInit, + dim2408KuoInit, + dim2409KuoInit, + dim2410KuoInit, + dim2411KuoInit, + dim2412KuoInit, + dim2413KuoInit, + dim2414KuoInit, + dim2415KuoInit, + dim2416KuoInit, + dim2417KuoInit, + dim2418KuoInit, + dim2419KuoInit, + dim2420KuoInit, + dim2421KuoInit, + dim2422KuoInit, + dim2423KuoInit, + dim2424KuoInit, + dim2425KuoInit, + dim2426KuoInit, + dim2427KuoInit, + dim2428KuoInit, + dim2429KuoInit, + dim2430KuoInit, + dim2431KuoInit, + dim2432KuoInit, + dim2433KuoInit, + dim2434KuoInit, + dim2435KuoInit, + dim2436KuoInit, + dim2437KuoInit, + dim2438KuoInit, + dim2439KuoInit, + dim2440KuoInit, + dim2441KuoInit, + dim2442KuoInit, + dim2443KuoInit, + dim2444KuoInit, + dim2445KuoInit, + dim2446KuoInit, + dim2447KuoInit, + dim2448KuoInit, + dim2449KuoInit, + dim2450KuoInit, + dim2451KuoInit, + dim2452KuoInit, + dim2453KuoInit, + dim2454KuoInit, + dim2455KuoInit, + dim2456KuoInit, + dim2457KuoInit, + dim2458KuoInit, + dim2459KuoInit, + dim2460KuoInit, + dim2461KuoInit, + dim2462KuoInit, + dim2463KuoInit, + dim2464KuoInit, + dim2465KuoInit, + dim2466KuoInit, + dim2467KuoInit, + dim2468KuoInit, + dim2469KuoInit, + dim2470KuoInit, + dim2471KuoInit, + dim2472KuoInit, + dim2473KuoInit, + dim2474KuoInit, + dim2475KuoInit, + dim2476KuoInit, + dim2477KuoInit, + dim2478KuoInit, + dim2479KuoInit, + dim2480KuoInit, + dim2481KuoInit, + dim2482KuoInit, + dim2483KuoInit, + dim2484KuoInit, + dim2485KuoInit, + dim2486KuoInit, + dim2487KuoInit, + dim2488KuoInit, + dim2489KuoInit, + dim2490KuoInit, + dim2491KuoInit, + dim2492KuoInit, + dim2493KuoInit, + dim2494KuoInit, + dim2495KuoInit, + dim2496KuoInit, + dim2497KuoInit, + dim2498KuoInit, + dim2499KuoInit, + dim2500KuoInit, + dim2501KuoInit, + dim2502KuoInit, + dim2503KuoInit, + dim2504KuoInit, + dim2505KuoInit, + dim2506KuoInit, + dim2507KuoInit, + dim2508KuoInit, + dim2509KuoInit, + dim2510KuoInit, + dim2511KuoInit, + dim2512KuoInit, + dim2513KuoInit, + dim2514KuoInit, + dim2515KuoInit, + dim2516KuoInit, + dim2517KuoInit, + dim2518KuoInit, + dim2519KuoInit, + dim2520KuoInit, + dim2521KuoInit, + dim2522KuoInit, + dim2523KuoInit, + dim2524KuoInit, + dim2525KuoInit, + dim2526KuoInit, + dim2527KuoInit, + dim2528KuoInit, + dim2529KuoInit, + dim2530KuoInit, + dim2531KuoInit, + dim2532KuoInit, + dim2533KuoInit, + dim2534KuoInit, + dim2535KuoInit, + dim2536KuoInit, + dim2537KuoInit, + dim2538KuoInit, + dim2539KuoInit, + dim2540KuoInit, + dim2541KuoInit, + dim2542KuoInit, + dim2543KuoInit, + dim2544KuoInit, + dim2545KuoInit, + dim2546KuoInit, + dim2547KuoInit, + dim2548KuoInit, + dim2549KuoInit, + dim2550KuoInit, + dim2551KuoInit, + dim2552KuoInit, + dim2553KuoInit, + dim2554KuoInit, + dim2555KuoInit, + dim2556KuoInit, + dim2557KuoInit, + dim2558KuoInit, + dim2559KuoInit, + dim2560KuoInit, + dim2561KuoInit, + dim2562KuoInit, + dim2563KuoInit, + dim2564KuoInit, + dim2565KuoInit, + dim2566KuoInit, + dim2567KuoInit, + dim2568KuoInit, + dim2569KuoInit, + dim2570KuoInit, + dim2571KuoInit, + dim2572KuoInit, + dim2573KuoInit, + dim2574KuoInit, + dim2575KuoInit, + dim2576KuoInit, + dim2577KuoInit, + dim2578KuoInit, + dim2579KuoInit, + dim2580KuoInit, + dim2581KuoInit, + dim2582KuoInit, + dim2583KuoInit, + dim2584KuoInit, + dim2585KuoInit, + dim2586KuoInit, + dim2587KuoInit, + dim2588KuoInit, + dim2589KuoInit, + dim2590KuoInit, + dim2591KuoInit, + dim2592KuoInit, + dim2593KuoInit, + dim2594KuoInit, + dim2595KuoInit, + dim2596KuoInit, + dim2597KuoInit, + dim2598KuoInit, + dim2599KuoInit, + dim2600KuoInit, + dim2601KuoInit, + dim2602KuoInit, + dim2603KuoInit, + dim2604KuoInit, + dim2605KuoInit, + dim2606KuoInit, + dim2607KuoInit, + dim2608KuoInit, + dim2609KuoInit, + dim2610KuoInit, + dim2611KuoInit, + dim2612KuoInit, + dim2613KuoInit, + dim2614KuoInit, + dim2615KuoInit, + dim2616KuoInit, + dim2617KuoInit, + dim2618KuoInit, + dim2619KuoInit, + dim2620KuoInit, + dim2621KuoInit, + dim2622KuoInit, + dim2623KuoInit, + dim2624KuoInit, + dim2625KuoInit, + dim2626KuoInit, + dim2627KuoInit, + dim2628KuoInit, + dim2629KuoInit, + dim2630KuoInit, + dim2631KuoInit, + dim2632KuoInit, + dim2633KuoInit, + dim2634KuoInit, + dim2635KuoInit, + dim2636KuoInit, + dim2637KuoInit, + dim2638KuoInit, + dim2639KuoInit, + dim2640KuoInit, + dim2641KuoInit, + dim2642KuoInit, + dim2643KuoInit, + dim2644KuoInit, + dim2645KuoInit, + dim2646KuoInit, + dim2647KuoInit, + dim2648KuoInit, + dim2649KuoInit, + dim2650KuoInit, + dim2651KuoInit, + dim2652KuoInit, + dim2653KuoInit, + dim2654KuoInit, + dim2655KuoInit, + dim2656KuoInit, + dim2657KuoInit, + dim2658KuoInit, + dim2659KuoInit, + dim2660KuoInit, + dim2661KuoInit, + dim2662KuoInit, + dim2663KuoInit, + dim2664KuoInit, + dim2665KuoInit, + dim2666KuoInit, + dim2667KuoInit, + dim2668KuoInit, + dim2669KuoInit, + dim2670KuoInit, + dim2671KuoInit, + dim2672KuoInit, + dim2673KuoInit, + dim2674KuoInit, + dim2675KuoInit, + dim2676KuoInit, + dim2677KuoInit, + dim2678KuoInit, + dim2679KuoInit, + dim2680KuoInit, + dim2681KuoInit, + dim2682KuoInit, + dim2683KuoInit, + dim2684KuoInit, + dim2685KuoInit, + dim2686KuoInit, + dim2687KuoInit, + dim2688KuoInit, + dim2689KuoInit, + dim2690KuoInit, + dim2691KuoInit, + dim2692KuoInit, + dim2693KuoInit, + dim2694KuoInit, + dim2695KuoInit, + dim2696KuoInit, + dim2697KuoInit, + dim2698KuoInit, + dim2699KuoInit, + dim2700KuoInit, + dim2701KuoInit, + dim2702KuoInit, + dim2703KuoInit, + dim2704KuoInit, + dim2705KuoInit, + dim2706KuoInit, + dim2707KuoInit, + dim2708KuoInit, + dim2709KuoInit, + dim2710KuoInit, + dim2711KuoInit, + dim2712KuoInit, + dim2713KuoInit, + dim2714KuoInit, + dim2715KuoInit, + dim2716KuoInit, + dim2717KuoInit, + dim2718KuoInit, + dim2719KuoInit, + dim2720KuoInit, + dim2721KuoInit, + dim2722KuoInit, + dim2723KuoInit, + dim2724KuoInit, + dim2725KuoInit, + dim2726KuoInit, + dim2727KuoInit, + dim2728KuoInit, + dim2729KuoInit, + dim2730KuoInit, + dim2731KuoInit, + dim2732KuoInit, + dim2733KuoInit, + dim2734KuoInit, + dim2735KuoInit, + dim2736KuoInit, + dim2737KuoInit, + dim2738KuoInit, + dim2739KuoInit, + dim2740KuoInit, + dim2741KuoInit, + dim2742KuoInit, + dim2743KuoInit, + dim2744KuoInit, + dim2745KuoInit, + dim2746KuoInit, + dim2747KuoInit, + dim2748KuoInit, + dim2749KuoInit, + dim2750KuoInit, + dim2751KuoInit, + dim2752KuoInit, + dim2753KuoInit, + dim2754KuoInit, + dim2755KuoInit, + dim2756KuoInit, + dim2757KuoInit, + dim2758KuoInit, + dim2759KuoInit, + dim2760KuoInit, + dim2761KuoInit, + dim2762KuoInit, + dim2763KuoInit, + dim2764KuoInit, + dim2765KuoInit, + dim2766KuoInit, + dim2767KuoInit, + dim2768KuoInit, + dim2769KuoInit, + dim2770KuoInit, + dim2771KuoInit, + dim2772KuoInit, + dim2773KuoInit, + dim2774KuoInit, + dim2775KuoInit, + dim2776KuoInit, + dim2777KuoInit, + dim2778KuoInit, + dim2779KuoInit, + dim2780KuoInit, + dim2781KuoInit, + dim2782KuoInit, + dim2783KuoInit, + dim2784KuoInit, + dim2785KuoInit, + dim2786KuoInit, + dim2787KuoInit, + dim2788KuoInit, + dim2789KuoInit, + dim2790KuoInit, + dim2791KuoInit, + dim2792KuoInit, + dim2793KuoInit, + dim2794KuoInit, + dim2795KuoInit, + dim2796KuoInit, + dim2797KuoInit, + dim2798KuoInit, + dim2799KuoInit, + dim2800KuoInit, + dim2801KuoInit, + dim2802KuoInit, + dim2803KuoInit, + dim2804KuoInit, + dim2805KuoInit, + dim2806KuoInit, + dim2807KuoInit, + dim2808KuoInit, + dim2809KuoInit, + dim2810KuoInit, + dim2811KuoInit, + dim2812KuoInit, + dim2813KuoInit, + dim2814KuoInit, + dim2815KuoInit, + dim2816KuoInit, + dim2817KuoInit, + dim2818KuoInit, + dim2819KuoInit, + dim2820KuoInit, + dim2821KuoInit, + dim2822KuoInit, + dim2823KuoInit, + dim2824KuoInit, + dim2825KuoInit, + dim2826KuoInit, + dim2827KuoInit, + dim2828KuoInit, + dim2829KuoInit, + dim2830KuoInit, + dim2831KuoInit, + dim2832KuoInit, + dim2833KuoInit, + dim2834KuoInit, + dim2835KuoInit, + dim2836KuoInit, + dim2837KuoInit, + dim2838KuoInit, + dim2839KuoInit, + dim2840KuoInit, + dim2841KuoInit, + dim2842KuoInit, + dim2843KuoInit, + dim2844KuoInit, + dim2845KuoInit, + dim2846KuoInit, + dim2847KuoInit, + dim2848KuoInit, + dim2849KuoInit, + dim2850KuoInit, + dim2851KuoInit, + dim2852KuoInit, + dim2853KuoInit, + dim2854KuoInit, + dim2855KuoInit, + dim2856KuoInit, + dim2857KuoInit, + dim2858KuoInit, + dim2859KuoInit, + dim2860KuoInit, + dim2861KuoInit, + dim2862KuoInit, + dim2863KuoInit, + dim2864KuoInit, + dim2865KuoInit, + dim2866KuoInit, + dim2867KuoInit, + dim2868KuoInit, + dim2869KuoInit, + dim2870KuoInit, + dim2871KuoInit, + dim2872KuoInit, + dim2873KuoInit, + dim2874KuoInit, + dim2875KuoInit, + dim2876KuoInit, + dim2877KuoInit, + dim2878KuoInit, + dim2879KuoInit, + dim2880KuoInit, + dim2881KuoInit, + dim2882KuoInit, + dim2883KuoInit, + dim2884KuoInit, + dim2885KuoInit, + dim2886KuoInit, + dim2887KuoInit, + dim2888KuoInit, + dim2889KuoInit, + dim2890KuoInit, + dim2891KuoInit, + dim2892KuoInit, + dim2893KuoInit, + dim2894KuoInit, + dim2895KuoInit, + dim2896KuoInit, + dim2897KuoInit, + dim2898KuoInit, + dim2899KuoInit, + dim2900KuoInit, + dim2901KuoInit, + dim2902KuoInit, + dim2903KuoInit, + dim2904KuoInit, + dim2905KuoInit, + dim2906KuoInit, + dim2907KuoInit, + dim2908KuoInit, + dim2909KuoInit, + dim2910KuoInit, + dim2911KuoInit, + dim2912KuoInit, + dim2913KuoInit, + dim2914KuoInit, + dim2915KuoInit, + dim2916KuoInit, + dim2917KuoInit, + dim2918KuoInit, + dim2919KuoInit, + dim2920KuoInit, + dim2921KuoInit, + dim2922KuoInit, + dim2923KuoInit, + dim2924KuoInit, + dim2925KuoInit, + dim2926KuoInit, + dim2927KuoInit, + dim2928KuoInit, + dim2929KuoInit, + dim2930KuoInit, + dim2931KuoInit, + dim2932KuoInit, + dim2933KuoInit, + dim2934KuoInit, + dim2935KuoInit, + dim2936KuoInit, + dim2937KuoInit, + dim2938KuoInit, + dim2939KuoInit, + dim2940KuoInit, + dim2941KuoInit, + dim2942KuoInit, + dim2943KuoInit, + dim2944KuoInit, + dim2945KuoInit, + dim2946KuoInit, + dim2947KuoInit, + dim2948KuoInit, + dim2949KuoInit, + dim2950KuoInit, + dim2951KuoInit, + dim2952KuoInit, + dim2953KuoInit, + dim2954KuoInit, + dim2955KuoInit, + dim2956KuoInit, + dim2957KuoInit, + dim2958KuoInit, + dim2959KuoInit, + dim2960KuoInit, + dim2961KuoInit, + dim2962KuoInit, + dim2963KuoInit, + dim2964KuoInit, + dim2965KuoInit, + dim2966KuoInit, + dim2967KuoInit, + dim2968KuoInit, + dim2969KuoInit, + dim2970KuoInit, + dim2971KuoInit, + dim2972KuoInit, + dim2973KuoInit, + dim2974KuoInit, + dim2975KuoInit, + dim2976KuoInit, + dim2977KuoInit, + dim2978KuoInit, + dim2979KuoInit, + dim2980KuoInit, + dim2981KuoInit, + dim2982KuoInit, + dim2983KuoInit, + dim2984KuoInit, + dim2985KuoInit, + dim2986KuoInit, + dim2987KuoInit, + dim2988KuoInit, + dim2989KuoInit, + dim2990KuoInit, + dim2991KuoInit, + dim2992KuoInit, + dim2993KuoInit, + dim2994KuoInit, + dim2995KuoInit, + dim2996KuoInit, + dim2997KuoInit, + dim2998KuoInit, + dim2999KuoInit, + dim3000KuoInit, + dim3001KuoInit, + dim3002KuoInit, + dim3003KuoInit, + dim3004KuoInit, + dim3005KuoInit, + dim3006KuoInit, + dim3007KuoInit, + dim3008KuoInit, + dim3009KuoInit, + dim3010KuoInit, + dim3011KuoInit, + dim3012KuoInit, + dim3013KuoInit, + dim3014KuoInit, + dim3015KuoInit, + dim3016KuoInit, + dim3017KuoInit, + dim3018KuoInit, + dim3019KuoInit, + dim3020KuoInit, + dim3021KuoInit, + dim3022KuoInit, + dim3023KuoInit, + dim3024KuoInit, + dim3025KuoInit, + dim3026KuoInit, + dim3027KuoInit, + dim3028KuoInit, + dim3029KuoInit, + dim3030KuoInit, + dim3031KuoInit, + dim3032KuoInit, + dim3033KuoInit, + dim3034KuoInit, + dim3035KuoInit, + dim3036KuoInit, + dim3037KuoInit, + dim3038KuoInit, + dim3039KuoInit, + dim3040KuoInit, + dim3041KuoInit, + dim3042KuoInit, + dim3043KuoInit, + dim3044KuoInit, + dim3045KuoInit, + dim3046KuoInit, + dim3047KuoInit, + dim3048KuoInit, + dim3049KuoInit, + dim3050KuoInit, + dim3051KuoInit, + dim3052KuoInit, + dim3053KuoInit, + dim3054KuoInit, + dim3055KuoInit, + dim3056KuoInit, + dim3057KuoInit, + dim3058KuoInit, + dim3059KuoInit, + dim3060KuoInit, + dim3061KuoInit, + dim3062KuoInit, + dim3063KuoInit, + dim3064KuoInit, + dim3065KuoInit, + dim3066KuoInit, + dim3067KuoInit, + dim3068KuoInit, + dim3069KuoInit, + dim3070KuoInit, + dim3071KuoInit, + dim3072KuoInit, + dim3073KuoInit, + dim3074KuoInit, + dim3075KuoInit, + dim3076KuoInit, + dim3077KuoInit, + dim3078KuoInit, + dim3079KuoInit, + dim3080KuoInit, + dim3081KuoInit, + dim3082KuoInit, + dim3083KuoInit, + dim3084KuoInit, + dim3085KuoInit, + dim3086KuoInit, + dim3087KuoInit, + dim3088KuoInit, + dim3089KuoInit, + dim3090KuoInit, + dim3091KuoInit, + dim3092KuoInit, + dim3093KuoInit, + dim3094KuoInit, + dim3095KuoInit, + dim3096KuoInit, + dim3097KuoInit, + dim3098KuoInit, + dim3099KuoInit, + dim3100KuoInit, + dim3101KuoInit, + dim3102KuoInit, + dim3103KuoInit, + dim3104KuoInit, + dim3105KuoInit, + dim3106KuoInit, + dim3107KuoInit, + dim3108KuoInit, + dim3109KuoInit, + dim3110KuoInit, + dim3111KuoInit, + dim3112KuoInit, + dim3113KuoInit, + dim3114KuoInit, + dim3115KuoInit, + dim3116KuoInit, + dim3117KuoInit, + dim3118KuoInit, + dim3119KuoInit, + dim3120KuoInit, + dim3121KuoInit, + dim3122KuoInit, + dim3123KuoInit, + dim3124KuoInit, + dim3125KuoInit, + dim3126KuoInit, + dim3127KuoInit, + dim3128KuoInit, + dim3129KuoInit, + dim3130KuoInit, + dim3131KuoInit, + dim3132KuoInit, + dim3133KuoInit, + dim3134KuoInit, + dim3135KuoInit, + dim3136KuoInit, + dim3137KuoInit, + dim3138KuoInit, + dim3139KuoInit, + dim3140KuoInit, + dim3141KuoInit, + dim3142KuoInit, + dim3143KuoInit, + dim3144KuoInit, + dim3145KuoInit, + dim3146KuoInit, + dim3147KuoInit, + dim3148KuoInit, + dim3149KuoInit, + dim3150KuoInit, + dim3151KuoInit, + dim3152KuoInit, + dim3153KuoInit, + dim3154KuoInit, + dim3155KuoInit, + dim3156KuoInit, + dim3157KuoInit, + dim3158KuoInit, + dim3159KuoInit, + dim3160KuoInit, + dim3161KuoInit, + dim3162KuoInit, + dim3163KuoInit, + dim3164KuoInit, + dim3165KuoInit, + dim3166KuoInit, + dim3167KuoInit, + dim3168KuoInit, + dim3169KuoInit, + dim3170KuoInit, + dim3171KuoInit, + dim3172KuoInit, + dim3173KuoInit, + dim3174KuoInit, + dim3175KuoInit, + dim3176KuoInit, + dim3177KuoInit, + dim3178KuoInit, + dim3179KuoInit, + dim3180KuoInit, + dim3181KuoInit, + dim3182KuoInit, + dim3183KuoInit, + dim3184KuoInit, + dim3185KuoInit, + dim3186KuoInit, + dim3187KuoInit, + dim3188KuoInit, + dim3189KuoInit, + dim3190KuoInit, + dim3191KuoInit, + dim3192KuoInit, + dim3193KuoInit, + dim3194KuoInit, + dim3195KuoInit, + dim3196KuoInit, + dim3197KuoInit, + dim3198KuoInit, + dim3199KuoInit, + dim3200KuoInit, + dim3201KuoInit, + dim3202KuoInit, + dim3203KuoInit, + dim3204KuoInit, + dim3205KuoInit, + dim3206KuoInit, + dim3207KuoInit, + dim3208KuoInit, + dim3209KuoInit, + dim3210KuoInit, + dim3211KuoInit, + dim3212KuoInit, + dim3213KuoInit, + dim3214KuoInit, + dim3215KuoInit, + dim3216KuoInit, + dim3217KuoInit, + dim3218KuoInit, + dim3219KuoInit, + dim3220KuoInit, + dim3221KuoInit, + dim3222KuoInit, + dim3223KuoInit, + dim3224KuoInit, + dim3225KuoInit, + dim3226KuoInit, + dim3227KuoInit, + dim3228KuoInit, + dim3229KuoInit, + dim3230KuoInit, + dim3231KuoInit, + dim3232KuoInit, + dim3233KuoInit, + dim3234KuoInit, + dim3235KuoInit, + dim3236KuoInit, + dim3237KuoInit, + dim3238KuoInit, + dim3239KuoInit, + dim3240KuoInit, + dim3241KuoInit, + dim3242KuoInit, + dim3243KuoInit, + dim3244KuoInit, + dim3245KuoInit, + dim3246KuoInit, + dim3247KuoInit, + dim3248KuoInit, + dim3249KuoInit, + dim3250KuoInit, + dim3251KuoInit, + dim3252KuoInit, + dim3253KuoInit, + dim3254KuoInit, + dim3255KuoInit, + dim3256KuoInit, + dim3257KuoInit, + dim3258KuoInit, + dim3259KuoInit, + dim3260KuoInit, + dim3261KuoInit, + dim3262KuoInit, + dim3263KuoInit, + dim3264KuoInit, + dim3265KuoInit, + dim3266KuoInit, + dim3267KuoInit, + dim3268KuoInit, + dim3269KuoInit, + dim3270KuoInit, + dim3271KuoInit, + dim3272KuoInit, + dim3273KuoInit, + dim3274KuoInit, + dim3275KuoInit, + dim3276KuoInit, + dim3277KuoInit, + dim3278KuoInit, + dim3279KuoInit, + dim3280KuoInit, + dim3281KuoInit, + dim3282KuoInit, + dim3283KuoInit, + dim3284KuoInit, + dim3285KuoInit, + dim3286KuoInit, + dim3287KuoInit, + dim3288KuoInit, + dim3289KuoInit, + dim3290KuoInit, + dim3291KuoInit, + dim3292KuoInit, + dim3293KuoInit, + dim3294KuoInit, + dim3295KuoInit, + dim3296KuoInit, + dim3297KuoInit, + dim3298KuoInit, + dim3299KuoInit, + dim3300KuoInit, + dim3301KuoInit, + dim3302KuoInit, + dim3303KuoInit, + dim3304KuoInit, + dim3305KuoInit, + dim3306KuoInit, + dim3307KuoInit, + dim3308KuoInit, + dim3309KuoInit, + dim3310KuoInit, + dim3311KuoInit, + dim3312KuoInit, + dim3313KuoInit, + dim3314KuoInit, + dim3315KuoInit, + dim3316KuoInit, + dim3317KuoInit, + dim3318KuoInit, + dim3319KuoInit, + dim3320KuoInit, + dim3321KuoInit, + dim3322KuoInit, + dim3323KuoInit, + dim3324KuoInit, + dim3325KuoInit, + dim3326KuoInit, + dim3327KuoInit, + dim3328KuoInit, + dim3329KuoInit, + dim3330KuoInit, + dim3331KuoInit, + dim3332KuoInit, + dim3333KuoInit, + dim3334KuoInit, + dim3335KuoInit, + dim3336KuoInit, + dim3337KuoInit, + dim3338KuoInit, + dim3339KuoInit, + dim3340KuoInit, + dim3341KuoInit, + dim3342KuoInit, + dim3343KuoInit, + dim3344KuoInit, + dim3345KuoInit, + dim3346KuoInit, + dim3347KuoInit, + dim3348KuoInit, + dim3349KuoInit, + dim3350KuoInit, + dim3351KuoInit, + dim3352KuoInit, + dim3353KuoInit, + dim3354KuoInit, + dim3355KuoInit, + dim3356KuoInit, + dim3357KuoInit, + dim3358KuoInit, + dim3359KuoInit, + dim3360KuoInit, + dim3361KuoInit, + dim3362KuoInit, + dim3363KuoInit, + dim3364KuoInit, + dim3365KuoInit, + dim3366KuoInit, + dim3367KuoInit, + dim3368KuoInit, + dim3369KuoInit, + dim3370KuoInit, + dim3371KuoInit, + dim3372KuoInit, + dim3373KuoInit, + dim3374KuoInit, + dim3375KuoInit, + dim3376KuoInit, + dim3377KuoInit, + dim3378KuoInit, + dim3379KuoInit, + dim3380KuoInit, + dim3381KuoInit, + dim3382KuoInit, + dim3383KuoInit, + dim3384KuoInit, + dim3385KuoInit, + dim3386KuoInit, + dim3387KuoInit, + dim3388KuoInit, + dim3389KuoInit, + dim3390KuoInit, + dim3391KuoInit, + dim3392KuoInit, + dim3393KuoInit, + dim3394KuoInit, + dim3395KuoInit, + dim3396KuoInit, + dim3397KuoInit, + dim3398KuoInit, + dim3399KuoInit, + dim3400KuoInit, + dim3401KuoInit, + dim3402KuoInit, + dim3403KuoInit, + dim3404KuoInit, + dim3405KuoInit, + dim3406KuoInit, + dim3407KuoInit, + dim3408KuoInit, + dim3409KuoInit, + dim3410KuoInit, + dim3411KuoInit, + dim3412KuoInit, + dim3413KuoInit, + dim3414KuoInit, + dim3415KuoInit, + dim3416KuoInit, + dim3417KuoInit, + dim3418KuoInit, + dim3419KuoInit, + dim3420KuoInit, + dim3421KuoInit, + dim3422KuoInit, + dim3423KuoInit, + dim3424KuoInit, + dim3425KuoInit, + dim3426KuoInit, + dim3427KuoInit, + dim3428KuoInit, + dim3429KuoInit, + dim3430KuoInit, + dim3431KuoInit, + dim3432KuoInit, + dim3433KuoInit, + dim3434KuoInit, + dim3435KuoInit, + dim3436KuoInit, + dim3437KuoInit, + dim3438KuoInit, + dim3439KuoInit, + dim3440KuoInit, + dim3441KuoInit, + dim3442KuoInit, + dim3443KuoInit, + dim3444KuoInit, + dim3445KuoInit, + dim3446KuoInit, + dim3447KuoInit, + dim3448KuoInit, + dim3449KuoInit, + dim3450KuoInit, + dim3451KuoInit, + dim3452KuoInit, + dim3453KuoInit, + dim3454KuoInit, + dim3455KuoInit, + dim3456KuoInit, + dim3457KuoInit, + dim3458KuoInit, + dim3459KuoInit, + dim3460KuoInit, + dim3461KuoInit, + dim3462KuoInit, + dim3463KuoInit, + dim3464KuoInit, + dim3465KuoInit, + dim3466KuoInit, + dim3467KuoInit, + dim3468KuoInit, + dim3469KuoInit, + dim3470KuoInit, + dim3471KuoInit, + dim3472KuoInit, + dim3473KuoInit, + dim3474KuoInit, + dim3475KuoInit, + dim3476KuoInit, + dim3477KuoInit, + dim3478KuoInit, + dim3479KuoInit, + dim3480KuoInit, + dim3481KuoInit, + dim3482KuoInit, + dim3483KuoInit, + dim3484KuoInit, + dim3485KuoInit, + dim3486KuoInit, + dim3487KuoInit, + dim3488KuoInit, + dim3489KuoInit, + dim3490KuoInit, + dim3491KuoInit, + dim3492KuoInit, + dim3493KuoInit, + dim3494KuoInit, + dim3495KuoInit, + dim3496KuoInit, + dim3497KuoInit, + dim3498KuoInit, + dim3499KuoInit, + dim3500KuoInit, + dim3501KuoInit, + dim3502KuoInit, + dim3503KuoInit, + dim3504KuoInit, + dim3505KuoInit, + dim3506KuoInit, + dim3507KuoInit, + dim3508KuoInit, + dim3509KuoInit, + dim3510KuoInit, + dim3511KuoInit, + dim3512KuoInit, + dim3513KuoInit, + dim3514KuoInit, + dim3515KuoInit, + dim3516KuoInit, + dim3517KuoInit, + dim3518KuoInit, + dim3519KuoInit, + dim3520KuoInit, + dim3521KuoInit, + dim3522KuoInit, + dim3523KuoInit, + dim3524KuoInit, + dim3525KuoInit, + dim3526KuoInit, + dim3527KuoInit, + dim3528KuoInit, + dim3529KuoInit, + dim3530KuoInit, + dim3531KuoInit, + dim3532KuoInit, + dim3533KuoInit, + dim3534KuoInit, + dim3535KuoInit, + dim3536KuoInit, + dim3537KuoInit, + dim3538KuoInit, + dim3539KuoInit, + dim3540KuoInit, + dim3541KuoInit, + dim3542KuoInit, + dim3543KuoInit, + dim3544KuoInit, + dim3545KuoInit, + dim3546KuoInit, + dim3547KuoInit, + dim3548KuoInit, + dim3549KuoInit, + dim3550KuoInit, + dim3551KuoInit, + dim3552KuoInit, + dim3553KuoInit, + dim3554KuoInit, + dim3555KuoInit, + dim3556KuoInit, + dim3557KuoInit, + dim3558KuoInit, + dim3559KuoInit, + dim3560KuoInit, + dim3561KuoInit, + dim3562KuoInit, + dim3563KuoInit, + dim3564KuoInit, + dim3565KuoInit, + dim3566KuoInit, + dim3567KuoInit, + dim3568KuoInit, + dim3569KuoInit, + dim3570KuoInit, + dim3571KuoInit, + dim3572KuoInit, + dim3573KuoInit, + dim3574KuoInit, + dim3575KuoInit, + dim3576KuoInit, + dim3577KuoInit, + dim3578KuoInit, + dim3579KuoInit, + dim3580KuoInit, + dim3581KuoInit, + dim3582KuoInit, + dim3583KuoInit, + dim3584KuoInit, + dim3585KuoInit, + dim3586KuoInit, + dim3587KuoInit, + dim3588KuoInit, + dim3589KuoInit, + dim3590KuoInit, + dim3591KuoInit, + dim3592KuoInit, + dim3593KuoInit, + dim3594KuoInit, + dim3595KuoInit, + dim3596KuoInit, + dim3597KuoInit, + dim3598KuoInit, + dim3599KuoInit, + dim3600KuoInit, + dim3601KuoInit, + dim3602KuoInit, + dim3603KuoInit, + dim3604KuoInit, + dim3605KuoInit, + dim3606KuoInit, + dim3607KuoInit, + dim3608KuoInit, + dim3609KuoInit, + dim3610KuoInit, + dim3611KuoInit, + dim3612KuoInit, + dim3613KuoInit, + dim3614KuoInit, + dim3615KuoInit, + dim3616KuoInit, + dim3617KuoInit, + dim3618KuoInit, + dim3619KuoInit, + dim3620KuoInit, + dim3621KuoInit, + dim3622KuoInit, + dim3623KuoInit, + dim3624KuoInit, + dim3625KuoInit, + dim3626KuoInit, + dim3627KuoInit, + dim3628KuoInit, + dim3629KuoInit, + dim3630KuoInit, + dim3631KuoInit, + dim3632KuoInit, + dim3633KuoInit, + dim3634KuoInit, + dim3635KuoInit, + dim3636KuoInit, + dim3637KuoInit, + dim3638KuoInit, + dim3639KuoInit, + dim3640KuoInit, + dim3641KuoInit, + dim3642KuoInit, + dim3643KuoInit, + dim3644KuoInit, + dim3645KuoInit, + dim3646KuoInit, + dim3647KuoInit, + dim3648KuoInit, + dim3649KuoInit, + dim3650KuoInit, + dim3651KuoInit, + dim3652KuoInit, + dim3653KuoInit, + dim3654KuoInit, + dim3655KuoInit, + dim3656KuoInit, + dim3657KuoInit, + dim3658KuoInit, + dim3659KuoInit, + dim3660KuoInit, + dim3661KuoInit, + dim3662KuoInit, + dim3663KuoInit, + dim3664KuoInit, + dim3665KuoInit, + dim3666KuoInit, + dim3667KuoInit, + dim3668KuoInit, + dim3669KuoInit, + dim3670KuoInit, + dim3671KuoInit, + dim3672KuoInit, + dim3673KuoInit, + dim3674KuoInit, + dim3675KuoInit, + dim3676KuoInit, + dim3677KuoInit, + dim3678KuoInit, + dim3679KuoInit, + dim3680KuoInit, + dim3681KuoInit, + dim3682KuoInit, + dim3683KuoInit, + dim3684KuoInit, + dim3685KuoInit, + dim3686KuoInit, + dim3687KuoInit, + dim3688KuoInit, + dim3689KuoInit, + dim3690KuoInit, + dim3691KuoInit, + dim3692KuoInit, + dim3693KuoInit, + dim3694KuoInit, + dim3695KuoInit, + dim3696KuoInit, + dim3697KuoInit, + dim3698KuoInit, + dim3699KuoInit, + dim3700KuoInit, + dim3701KuoInit, + dim3702KuoInit, + dim3703KuoInit, + dim3704KuoInit, + dim3705KuoInit, + dim3706KuoInit, + dim3707KuoInit, + dim3708KuoInit, + dim3709KuoInit, + dim3710KuoInit, + dim3711KuoInit, + dim3712KuoInit, + dim3713KuoInit, + dim3714KuoInit, + dim3715KuoInit, + dim3716KuoInit, + dim3717KuoInit, + dim3718KuoInit, + dim3719KuoInit, + dim3720KuoInit, + dim3721KuoInit, + dim3722KuoInit, + dim3723KuoInit, + dim3724KuoInit, + dim3725KuoInit, + dim3726KuoInit, + dim3727KuoInit, + dim3728KuoInit, + dim3729KuoInit, + dim3730KuoInit, + dim3731KuoInit, + dim3732KuoInit, + dim3733KuoInit, + dim3734KuoInit, + dim3735KuoInit, + dim3736KuoInit, + dim3737KuoInit, + dim3738KuoInit, + dim3739KuoInit, + dim3740KuoInit, + dim3741KuoInit, + dim3742KuoInit, + dim3743KuoInit, + dim3744KuoInit, + dim3745KuoInit, + dim3746KuoInit, + dim3747KuoInit, + dim3748KuoInit, + dim3749KuoInit, + dim3750KuoInit, + dim3751KuoInit, + dim3752KuoInit, + dim3753KuoInit, + dim3754KuoInit, + dim3755KuoInit, + dim3756KuoInit, + dim3757KuoInit, + dim3758KuoInit, + dim3759KuoInit, + dim3760KuoInit, + dim3761KuoInit, + dim3762KuoInit, + dim3763KuoInit, + dim3764KuoInit, + dim3765KuoInit, + dim3766KuoInit, + dim3767KuoInit, + dim3768KuoInit, + dim3769KuoInit, + dim3770KuoInit, + dim3771KuoInit, + dim3772KuoInit, + dim3773KuoInit, + dim3774KuoInit, + dim3775KuoInit, + dim3776KuoInit, + dim3777KuoInit, + dim3778KuoInit, + dim3779KuoInit, + dim3780KuoInit, + dim3781KuoInit, + dim3782KuoInit, + dim3783KuoInit, + dim3784KuoInit, + dim3785KuoInit, + dim3786KuoInit, + dim3787KuoInit, + dim3788KuoInit, + dim3789KuoInit, + dim3790KuoInit, + dim3791KuoInit, + dim3792KuoInit, + dim3793KuoInit, + dim3794KuoInit, + dim3795KuoInit, + dim3796KuoInit, + dim3797KuoInit, + dim3798KuoInit, + dim3799KuoInit, + dim3800KuoInit, + dim3801KuoInit, + dim3802KuoInit, + dim3803KuoInit, + dim3804KuoInit, + dim3805KuoInit, + dim3806KuoInit, + dim3807KuoInit, + dim3808KuoInit, + dim3809KuoInit, + dim3810KuoInit, + dim3811KuoInit, + dim3812KuoInit, + dim3813KuoInit, + dim3814KuoInit, + dim3815KuoInit, + dim3816KuoInit, + dim3817KuoInit, + dim3818KuoInit, + dim3819KuoInit, + dim3820KuoInit, + dim3821KuoInit, + dim3822KuoInit, + dim3823KuoInit, + dim3824KuoInit, + dim3825KuoInit, + dim3826KuoInit, + dim3827KuoInit, + dim3828KuoInit, + dim3829KuoInit, + dim3830KuoInit, + dim3831KuoInit, + dim3832KuoInit, + dim3833KuoInit, + dim3834KuoInit, + dim3835KuoInit, + dim3836KuoInit, + dim3837KuoInit, + dim3838KuoInit, + dim3839KuoInit, + dim3840KuoInit, + dim3841KuoInit, + dim3842KuoInit, + dim3843KuoInit, + dim3844KuoInit, + dim3845KuoInit, + dim3846KuoInit, + dim3847KuoInit, + dim3848KuoInit, + dim3849KuoInit, + dim3850KuoInit, + dim3851KuoInit, + dim3852KuoInit, + dim3853KuoInit, + dim3854KuoInit, + dim3855KuoInit, + dim3856KuoInit, + dim3857KuoInit, + dim3858KuoInit, + dim3859KuoInit, + dim3860KuoInit, + dim3861KuoInit, + dim3862KuoInit, + dim3863KuoInit, + dim3864KuoInit, + dim3865KuoInit, + dim3866KuoInit, + dim3867KuoInit, + dim3868KuoInit, + dim3869KuoInit, + dim3870KuoInit, + dim3871KuoInit, + dim3872KuoInit, + dim3873KuoInit, + dim3874KuoInit, + dim3875KuoInit, + dim3876KuoInit, + dim3877KuoInit, + dim3878KuoInit, + dim3879KuoInit, + dim3880KuoInit, + dim3881KuoInit, + dim3882KuoInit, + dim3883KuoInit, + dim3884KuoInit, + dim3885KuoInit, + dim3886KuoInit, + dim3887KuoInit, + dim3888KuoInit, + dim3889KuoInit, + dim3890KuoInit, + dim3891KuoInit, + dim3892KuoInit, + dim3893KuoInit, + dim3894KuoInit, + dim3895KuoInit, + dim3896KuoInit, + dim3897KuoInit, + dim3898KuoInit, + dim3899KuoInit, + dim3900KuoInit, + dim3901KuoInit, + dim3902KuoInit, + dim3903KuoInit, + dim3904KuoInit, + dim3905KuoInit, + dim3906KuoInit, + dim3907KuoInit, + dim3908KuoInit, + dim3909KuoInit, + dim3910KuoInit, + dim3911KuoInit, + dim3912KuoInit, + dim3913KuoInit, + dim3914KuoInit, + dim3915KuoInit, + dim3916KuoInit, + dim3917KuoInit, + dim3918KuoInit, + dim3919KuoInit, + dim3920KuoInit, + dim3921KuoInit, + dim3922KuoInit, + dim3923KuoInit, + dim3924KuoInit, + dim3925KuoInit, + dim3926KuoInit, + dim3927KuoInit, + dim3928KuoInit, + dim3929KuoInit, + dim3930KuoInit, + dim3931KuoInit, + dim3932KuoInit, + dim3933KuoInit, + dim3934KuoInit, + dim3935KuoInit, + dim3936KuoInit, + dim3937KuoInit, + dim3938KuoInit, + dim3939KuoInit, + dim3940KuoInit, + dim3941KuoInit, + dim3942KuoInit, + dim3943KuoInit, + dim3944KuoInit, + dim3945KuoInit, + dim3946KuoInit, + dim3947KuoInit, + dim3948KuoInit, + dim3949KuoInit, + dim3950KuoInit, + dim3951KuoInit, + dim3952KuoInit, + dim3953KuoInit, + dim3954KuoInit, + dim3955KuoInit, + dim3956KuoInit, + dim3957KuoInit, + dim3958KuoInit, + dim3959KuoInit, + dim3960KuoInit, + dim3961KuoInit, + dim3962KuoInit, + dim3963KuoInit, + dim3964KuoInit, + dim3965KuoInit, + dim3966KuoInit, + dim3967KuoInit, + dim3968KuoInit, + dim3969KuoInit, + dim3970KuoInit, + dim3971KuoInit, + dim3972KuoInit, + dim3973KuoInit, + dim3974KuoInit, + dim3975KuoInit, + dim3976KuoInit, + dim3977KuoInit, + dim3978KuoInit, + dim3979KuoInit, + dim3980KuoInit, + dim3981KuoInit, + dim3982KuoInit, + dim3983KuoInit, + dim3984KuoInit, + dim3985KuoInit, + dim3986KuoInit, + dim3987KuoInit, + dim3988KuoInit, + dim3989KuoInit, + dim3990KuoInit, + dim3991KuoInit, + dim3992KuoInit, + dim3993KuoInit, + dim3994KuoInit, + dim3995KuoInit, + dim3996KuoInit, + dim3997KuoInit, + dim3998KuoInit, + dim3999KuoInit, + dim4000KuoInit, + dim4001KuoInit, + dim4002KuoInit, + dim4003KuoInit, + dim4004KuoInit, + dim4005KuoInit, + dim4006KuoInit, + dim4007KuoInit, + dim4008KuoInit, + dim4009KuoInit, + dim4010KuoInit, + dim4011KuoInit, + dim4012KuoInit, + dim4013KuoInit, + dim4014KuoInit, + dim4015KuoInit, + dim4016KuoInit, + dim4017KuoInit, + dim4018KuoInit, + dim4019KuoInit, + dim4020KuoInit, + dim4021KuoInit, + dim4022KuoInit, + dim4023KuoInit, + dim4024KuoInit, + dim4025KuoInit, + dim4026KuoInit, + dim4027KuoInit, + dim4028KuoInit, + dim4029KuoInit, + dim4030KuoInit, + dim4031KuoInit, + dim4032KuoInit, + dim4033KuoInit, + dim4034KuoInit, + dim4035KuoInit, + dim4036KuoInit, + dim4037KuoInit, + dim4038KuoInit, + dim4039KuoInit, + dim4040KuoInit, + dim4041KuoInit, + dim4042KuoInit, + dim4043KuoInit, + dim4044KuoInit, + dim4045KuoInit, + dim4046KuoInit, + dim4047KuoInit, + dim4048KuoInit, + dim4049KuoInit, + dim4050KuoInit, + dim4051KuoInit, + dim4052KuoInit, + dim4053KuoInit, + dim4054KuoInit, + dim4055KuoInit, + dim4056KuoInit, + dim4057KuoInit, + dim4058KuoInit, + dim4059KuoInit, + dim4060KuoInit, + dim4061KuoInit, + dim4062KuoInit, + dim4063KuoInit, + dim4064KuoInit, + dim4065KuoInit, + dim4066KuoInit, + dim4067KuoInit, + dim4068KuoInit, + dim4069KuoInit, + dim4070KuoInit, + dim4071KuoInit, + dim4072KuoInit, + dim4073KuoInit, + dim4074KuoInit, + dim4075KuoInit, + dim4076KuoInit, + dim4077KuoInit, + dim4078KuoInit, + dim4079KuoInit, + dim4080KuoInit, + dim4081KuoInit, + dim4082KuoInit, + dim4083KuoInit, + dim4084KuoInit, + dim4085KuoInit, + dim4086KuoInit, + dim4087KuoInit, + dim4088KuoInit, + dim4089KuoInit, + dim4090KuoInit, + dim4091KuoInit, + dim4092KuoInit, + dim4093KuoInit, + dim4094KuoInit, + dim4095KuoInit, + dim4096KuoInit, + dim4097KuoInit, + dim4098KuoInit, + dim4099KuoInit, + dim4100KuoInit, + dim4101KuoInit, + dim4102KuoInit, + dim4103KuoInit, + dim4104KuoInit, + dim4105KuoInit, + dim4106KuoInit, + dim4107KuoInit, + dim4108KuoInit, + dim4109KuoInit, + dim4110KuoInit, + dim4111KuoInit, + dim4112KuoInit, + dim4113KuoInit, + dim4114KuoInit, + dim4115KuoInit, + dim4116KuoInit, + dim4117KuoInit, + dim4118KuoInit, + dim4119KuoInit, + dim4120KuoInit, + dim4121KuoInit, + dim4122KuoInit, + dim4123KuoInit, + dim4124KuoInit, + dim4125KuoInit, + dim4126KuoInit, + dim4127KuoInit, + dim4128KuoInit, + dim4129KuoInit, + dim4130KuoInit, + dim4131KuoInit, + dim4132KuoInit, + dim4133KuoInit, + dim4134KuoInit, + dim4135KuoInit, + dim4136KuoInit, + dim4137KuoInit, + dim4138KuoInit, + dim4139KuoInit, + dim4140KuoInit, + dim4141KuoInit, + dim4142KuoInit, + dim4143KuoInit, + dim4144KuoInit, + dim4145KuoInit, + dim4146KuoInit, + dim4147KuoInit, + dim4148KuoInit, + dim4149KuoInit, + dim4150KuoInit, + dim4151KuoInit, + dim4152KuoInit, + dim4153KuoInit, + dim4154KuoInit, + dim4155KuoInit, + dim4156KuoInit, + dim4157KuoInit, + dim4158KuoInit, + dim4159KuoInit, + dim4160KuoInit, + dim4161KuoInit, + dim4162KuoInit, + dim4163KuoInit, + dim4164KuoInit, + dim4165KuoInit, + dim4166KuoInit, + dim4167KuoInit, + dim4168KuoInit, + dim4169KuoInit, + dim4170KuoInit, + dim4171KuoInit, + dim4172KuoInit, + dim4173KuoInit, + dim4174KuoInit, + dim4175KuoInit, + dim4176KuoInit, + dim4177KuoInit, + dim4178KuoInit, + dim4179KuoInit, + dim4180KuoInit, + dim4181KuoInit, + dim4182KuoInit, + dim4183KuoInit, + dim4184KuoInit, + dim4185KuoInit, + dim4186KuoInit, + dim4187KuoInit, + dim4188KuoInit, + dim4189KuoInit, + dim4190KuoInit, + dim4191KuoInit, + dim4192KuoInit, + dim4193KuoInit, + dim4194KuoInit, + dim4195KuoInit, + dim4196KuoInit, + dim4197KuoInit, + dim4198KuoInit, + dim4199KuoInit, + dim4200KuoInit, + dim4201KuoInit, + dim4202KuoInit, + dim4203KuoInit, + dim4204KuoInit, + dim4205KuoInit, + dim4206KuoInit, + dim4207KuoInit, + dim4208KuoInit, + dim4209KuoInit, + dim4210KuoInit, + dim4211KuoInit, + dim4212KuoInit, + dim4213KuoInit, + dim4214KuoInit, + dim4215KuoInit, + dim4216KuoInit, + dim4217KuoInit, + dim4218KuoInit, + dim4219KuoInit, + dim4220KuoInit, + dim4221KuoInit, + dim4222KuoInit, + dim4223KuoInit, + dim4224KuoInit, + dim4225KuoInit, + dim4226KuoInit, + dim4227KuoInit, + dim4228KuoInit, + dim4229KuoInit, + dim4230KuoInit, + dim4231KuoInit, + dim4232KuoInit, + dim4233KuoInit, + dim4234KuoInit, + dim4235KuoInit, + dim4236KuoInit, + dim4237KuoInit, + dim4238KuoInit, + dim4239KuoInit, + dim4240KuoInit, + dim4241KuoInit, + dim4242KuoInit, + dim4243KuoInit, + dim4244KuoInit, + dim4245KuoInit, + dim4246KuoInit, + dim4247KuoInit, + dim4248KuoInit, + dim4249KuoInit, + dim4250KuoInit, + dim4251KuoInit, + dim4252KuoInit, + dim4253KuoInit, + dim4254KuoInit, + dim4255KuoInit, + dim4256KuoInit, + dim4257KuoInit, + dim4258KuoInit, + dim4259KuoInit, + dim4260KuoInit, + dim4261KuoInit, + dim4262KuoInit, + dim4263KuoInit, + dim4264KuoInit, + dim4265KuoInit, + dim4266KuoInit, + dim4267KuoInit, + dim4268KuoInit, + dim4269KuoInit, + dim4270KuoInit, + dim4271KuoInit, + dim4272KuoInit, + dim4273KuoInit, + dim4274KuoInit, + dim4275KuoInit, + dim4276KuoInit, + dim4277KuoInit, + dim4278KuoInit, + dim4279KuoInit, + dim4280KuoInit, + dim4281KuoInit, + dim4282KuoInit, + dim4283KuoInit, + dim4284KuoInit, + dim4285KuoInit, + dim4286KuoInit, + dim4287KuoInit, + dim4288KuoInit, + dim4289KuoInit, + dim4290KuoInit, + dim4291KuoInit, + dim4292KuoInit, + dim4293KuoInit, + dim4294KuoInit, + dim4295KuoInit, + dim4296KuoInit, + dim4297KuoInit, + dim4298KuoInit, + dim4299KuoInit, + dim4300KuoInit, + dim4301KuoInit, + dim4302KuoInit, + dim4303KuoInit, + dim4304KuoInit, + dim4305KuoInit, + dim4306KuoInit, + dim4307KuoInit, + dim4308KuoInit, + dim4309KuoInit, + dim4310KuoInit, + dim4311KuoInit, + dim4312KuoInit, + dim4313KuoInit, + dim4314KuoInit, + dim4315KuoInit, + dim4316KuoInit, + dim4317KuoInit, + dim4318KuoInit, + dim4319KuoInit, + dim4320KuoInit, + dim4321KuoInit, + dim4322KuoInit, + dim4323KuoInit, + dim4324KuoInit, + dim4325KuoInit, + dim4326KuoInit, + dim4327KuoInit, + dim4328KuoInit, + dim4329KuoInit, + dim4330KuoInit, + dim4331KuoInit, + dim4332KuoInit, + dim4333KuoInit, + dim4334KuoInit, + dim4335KuoInit, + dim4336KuoInit, + dim4337KuoInit, + dim4338KuoInit, + dim4339KuoInit, + dim4340KuoInit, + dim4341KuoInit, + dim4342KuoInit, + dim4343KuoInit, + dim4344KuoInit, + dim4345KuoInit, + dim4346KuoInit, + dim4347KuoInit, + dim4348KuoInit, + dim4349KuoInit, + dim4350KuoInit, + dim4351KuoInit, + dim4352KuoInit, + dim4353KuoInit, + dim4354KuoInit, + dim4355KuoInit, + dim4356KuoInit, + dim4357KuoInit, + dim4358KuoInit, + dim4359KuoInit, + dim4360KuoInit, + dim4361KuoInit, + dim4362KuoInit, + dim4363KuoInit, + dim4364KuoInit, + dim4365KuoInit, + dim4366KuoInit, + dim4367KuoInit, + dim4368KuoInit, + dim4369KuoInit, + dim4370KuoInit, + dim4371KuoInit, + dim4372KuoInit, + dim4373KuoInit, + dim4374KuoInit, + dim4375KuoInit, + dim4376KuoInit, + dim4377KuoInit, + dim4378KuoInit, + dim4379KuoInit, + dim4380KuoInit, + dim4381KuoInit, + dim4382KuoInit, + dim4383KuoInit, + dim4384KuoInit, + dim4385KuoInit, + dim4386KuoInit, + dim4387KuoInit, + dim4388KuoInit, + dim4389KuoInit, + dim4390KuoInit, + dim4391KuoInit, + dim4392KuoInit, + dim4393KuoInit, + dim4394KuoInit, + dim4395KuoInit, + dim4396KuoInit, + dim4397KuoInit, + dim4398KuoInit, + dim4399KuoInit, + dim4400KuoInit, + dim4401KuoInit, + dim4402KuoInit, + dim4403KuoInit, + dim4404KuoInit, + dim4405KuoInit, + dim4406KuoInit, + dim4407KuoInit, + dim4408KuoInit, + dim4409KuoInit, + dim4410KuoInit, + dim4411KuoInit, + dim4412KuoInit, + dim4413KuoInit, + dim4414KuoInit, + dim4415KuoInit, + dim4416KuoInit, + dim4417KuoInit, + dim4418KuoInit, + dim4419KuoInit, + dim4420KuoInit, + dim4421KuoInit, + dim4422KuoInit, + dim4423KuoInit, + dim4424KuoInit, + dim4425KuoInit, + dim4426KuoInit, + dim4427KuoInit, + dim4428KuoInit, + dim4429KuoInit, + dim4430KuoInit, + dim4431KuoInit, + dim4432KuoInit, + dim4433KuoInit, + dim4434KuoInit, + dim4435KuoInit, + dim4436KuoInit, + dim4437KuoInit, + dim4438KuoInit, + dim4439KuoInit, + dim4440KuoInit, + dim4441KuoInit, + dim4442KuoInit, + dim4443KuoInit, + dim4444KuoInit, + dim4445KuoInit, + dim4446KuoInit, + dim4447KuoInit, + dim4448KuoInit, + dim4449KuoInit, + dim4450KuoInit, + dim4451KuoInit, + dim4452KuoInit, + dim4453KuoInit, + dim4454KuoInit, + dim4455KuoInit, + dim4456KuoInit, + dim4457KuoInit, + dim4458KuoInit, + dim4459KuoInit, + dim4460KuoInit, + dim4461KuoInit, + dim4462KuoInit, + dim4463KuoInit, + dim4464KuoInit, + dim4465KuoInit, + dim4466KuoInit, + dim4467KuoInit, + dim4468KuoInit, + dim4469KuoInit, + dim4470KuoInit, + dim4471KuoInit, + dim4472KuoInit, + dim4473KuoInit, + dim4474KuoInit, + dim4475KuoInit, + dim4476KuoInit, + dim4477KuoInit, + dim4478KuoInit, + dim4479KuoInit, + dim4480KuoInit, + dim4481KuoInit, + dim4482KuoInit, + dim4483KuoInit, + dim4484KuoInit, + dim4485KuoInit, + dim4486KuoInit, + dim4487KuoInit, + dim4488KuoInit, + dim4489KuoInit, + dim4490KuoInit, + dim4491KuoInit, + dim4492KuoInit, + dim4493KuoInit, + dim4494KuoInit, + dim4495KuoInit, + dim4496KuoInit, + dim4497KuoInit, + dim4498KuoInit, + dim4499KuoInit, + dim4500KuoInit, + dim4501KuoInit, + dim4502KuoInit, + dim4503KuoInit, + dim4504KuoInit, + dim4505KuoInit, + dim4506KuoInit, + dim4507KuoInit, + dim4508KuoInit, + dim4509KuoInit, + dim4510KuoInit, + dim4511KuoInit, + dim4512KuoInit, + dim4513KuoInit, + dim4514KuoInit, + dim4515KuoInit, + dim4516KuoInit, + dim4517KuoInit, + dim4518KuoInit, + dim4519KuoInit, + dim4520KuoInit, + dim4521KuoInit, + dim4522KuoInit, + dim4523KuoInit, + dim4524KuoInit, + dim4525KuoInit, + dim4526KuoInit, + dim4527KuoInit, + dim4528KuoInit, + dim4529KuoInit, + dim4530KuoInit, + dim4531KuoInit, + dim4532KuoInit, + dim4533KuoInit, + dim4534KuoInit, + dim4535KuoInit, + dim4536KuoInit, + dim4537KuoInit, + dim4538KuoInit, + dim4539KuoInit, + dim4540KuoInit, + dim4541KuoInit, + dim4542KuoInit, + dim4543KuoInit, + dim4544KuoInit, + dim4545KuoInit, + dim4546KuoInit, + dim4547KuoInit, + dim4548KuoInit, + dim4549KuoInit, + dim4550KuoInit, + dim4551KuoInit, + dim4552KuoInit, + dim4553KuoInit, + dim4554KuoInit, + dim4555KuoInit, + dim4556KuoInit, + dim4557KuoInit, + dim4558KuoInit, + dim4559KuoInit, + dim4560KuoInit, + dim4561KuoInit, + dim4562KuoInit, + dim4563KuoInit, + dim4564KuoInit, + dim4565KuoInit, + dim4566KuoInit, + dim4567KuoInit, + dim4568KuoInit, + dim4569KuoInit, + dim4570KuoInit, + dim4571KuoInit, + dim4572KuoInit, + dim4573KuoInit, + dim4574KuoInit, + dim4575KuoInit, + dim4576KuoInit, + dim4577KuoInit, + dim4578KuoInit, + dim4579KuoInit, + dim4580KuoInit, + dim4581KuoInit, + dim4582KuoInit, + dim4583KuoInit, + dim4584KuoInit, + dim4585KuoInit, + dim4586KuoInit, + dim4587KuoInit, + dim4588KuoInit, + dim4589KuoInit, + dim4590KuoInit, + dim4591KuoInit, + dim4592KuoInit, + dim4593KuoInit, + dim4594KuoInit, + dim4595KuoInit, + dim4596KuoInit, + dim4597KuoInit, + dim4598KuoInit, + dim4599KuoInit, + dim4600KuoInit, + dim4601KuoInit, + dim4602KuoInit, + dim4603KuoInit, + dim4604KuoInit, + dim4605KuoInit, + dim4606KuoInit, + dim4607KuoInit, + dim4608KuoInit, + dim4609KuoInit, + dim4610KuoInit, + dim4611KuoInit, + dim4612KuoInit, + dim4613KuoInit, + dim4614KuoInit, + dim4615KuoInit, + dim4616KuoInit, + dim4617KuoInit, + dim4618KuoInit, + dim4619KuoInit, + dim4620KuoInit, + dim4621KuoInit, + dim4622KuoInit, + dim4623KuoInit, + dim4624KuoInit, + dim4625KuoInit, + dim4626KuoInit, + dim4627KuoInit, + dim4628KuoInit, + dim4629KuoInit, + dim4630KuoInit, + dim4631KuoInit, + dim4632KuoInit, + dim4633KuoInit, + dim4634KuoInit, + dim4635KuoInit, + dim4636KuoInit, + dim4637KuoInit, + dim4638KuoInit, + dim4639KuoInit, + dim4640KuoInit, + dim4641KuoInit, + dim4642KuoInit, + dim4643KuoInit, + dim4644KuoInit, + dim4645KuoInit, + dim4646KuoInit, + dim4647KuoInit, + dim4648KuoInit, + dim4649KuoInit, + dim4650KuoInit, + dim4651KuoInit, + dim4652KuoInit, + dim4653KuoInit, + dim4654KuoInit, + dim4655KuoInit, + dim4656KuoInit, + dim4657KuoInit, + dim4658KuoInit, + dim4659KuoInit, + dim4660KuoInit, + dim4661KuoInit, + dim4662KuoInit, + dim4663KuoInit, + dim4664KuoInit, + dim4665KuoInit, + dim4666KuoInit, + dim4667KuoInit, + dim4668KuoInit, + dim4669KuoInit, + dim4670KuoInit, + dim4671KuoInit, + dim4672KuoInit, + dim4673KuoInit, + dim4674KuoInit, + dim4675KuoInit, + dim4676KuoInit, + dim4677KuoInit, + dim4678KuoInit, + dim4679KuoInit, + dim4680KuoInit, + dim4681KuoInit, + dim4682KuoInit, + dim4683KuoInit, + dim4684KuoInit, + dim4685KuoInit, + dim4686KuoInit, + dim4687KuoInit, + dim4688KuoInit, + dim4689KuoInit, + dim4690KuoInit, + dim4691KuoInit, + dim4692KuoInit, + dim4693KuoInit, + dim4694KuoInit, + dim4695KuoInit, + dim4696KuoInit, + dim4697KuoInit, + dim4698KuoInit, + dim4699KuoInit, + dim4700KuoInit, + dim4701KuoInit, + dim4702KuoInit, + dim4703KuoInit, + dim4704KuoInit, + dim4705KuoInit, + dim4706KuoInit, + dim4707KuoInit, + dim4708KuoInit, + dim4709KuoInit, + dim4710KuoInit, + dim4711KuoInit, + dim4712KuoInit, + dim4713KuoInit, + dim4714KuoInit, + dim4715KuoInit, + dim4716KuoInit, + dim4717KuoInit, + dim4718KuoInit, + dim4719KuoInit, + dim4720KuoInit, + dim4721KuoInit, + dim4722KuoInit, + dim4723KuoInit, + dim4724KuoInit, + dim4725KuoInit, + dim4726KuoInit, + dim4727KuoInit, + dim4728KuoInit, + dim4729KuoInit, + dim4730KuoInit, + dim4731KuoInit, + dim4732KuoInit, + dim4733KuoInit, + dim4734KuoInit, + dim4735KuoInit, + dim4736KuoInit, + dim4737KuoInit, + dim4738KuoInit, + dim4739KuoInit, + dim4740KuoInit, + dim4741KuoInit, + dim4742KuoInit, + dim4743KuoInit, + dim4744KuoInit, + dim4745KuoInit, + dim4746KuoInit, + dim4747KuoInit, + dim4748KuoInit, + dim4749KuoInit, + dim4750KuoInit, + dim4751KuoInit, + dim4752KuoInit, + dim4753KuoInit, + dim4754KuoInit, + dim4755KuoInit, + dim4756KuoInit, + dim4757KuoInit, + dim4758KuoInit, + dim4759KuoInit, + dim4760KuoInit, + dim4761KuoInit, + dim4762KuoInit, + dim4763KuoInit, + dim4764KuoInit, + dim4765KuoInit, + dim4766KuoInit, + dim4767KuoInit, + dim4768KuoInit, + dim4769KuoInit, + dim4770KuoInit, + dim4771KuoInit, + dim4772KuoInit, + dim4773KuoInit, + dim4774KuoInit, + dim4775KuoInit, + dim4776KuoInit, + dim4777KuoInit, + dim4778KuoInit, + dim4779KuoInit, + dim4780KuoInit, + dim4781KuoInit, + dim4782KuoInit, + dim4783KuoInit, + dim4784KuoInit, + dim4785KuoInit, + dim4786KuoInit, + dim4787KuoInit, + dim4788KuoInit, + dim4789KuoInit, + dim4790KuoInit, + dim4791KuoInit, + dim4792KuoInit, + dim4793KuoInit, + dim4794KuoInit, + dim4795KuoInit, + dim4796KuoInit, + dim4797KuoInit, + dim4798KuoInit, + dim4799KuoInit, + dim4800KuoInit, + dim4801KuoInit, + dim4802KuoInit, + dim4803KuoInit, + dim4804KuoInit, + dim4805KuoInit, + dim4806KuoInit, + dim4807KuoInit, + dim4808KuoInit, + dim4809KuoInit, + dim4810KuoInit, + dim4811KuoInit, + dim4812KuoInit, + dim4813KuoInit, + dim4814KuoInit, + dim4815KuoInit, + dim4816KuoInit, + dim4817KuoInit, + dim4818KuoInit, + dim4819KuoInit, + dim4820KuoInit, + dim4821KuoInit, + dim4822KuoInit, + dim4823KuoInit, + dim4824KuoInit, + dim4825KuoInit, + dim4826KuoInit, + dim4827KuoInit, + dim4828KuoInit, + dim4829KuoInit, + dim4830KuoInit, + dim4831KuoInit, + dim4832KuoInit, + dim4833KuoInit, + dim4834KuoInit, + dim4835KuoInit, + dim4836KuoInit, + dim4837KuoInit, + dim4838KuoInit, + dim4839KuoInit, + dim4840KuoInit, + dim4841KuoInit, + dim4842KuoInit, + dim4843KuoInit, + dim4844KuoInit, + dim4845KuoInit, + dim4846KuoInit, + dim4847KuoInit, + dim4848KuoInit, + dim4849KuoInit, + dim4850KuoInit, + dim4851KuoInit, + dim4852KuoInit, + dim4853KuoInit, + dim4854KuoInit, + dim4855KuoInit, + dim4856KuoInit, + dim4857KuoInit, + dim4858KuoInit, + dim4859KuoInit, + dim4860KuoInit, + dim4861KuoInit, + dim4862KuoInit, + dim4863KuoInit, + dim4864KuoInit, + dim4865KuoInit, + dim4866KuoInit, + dim4867KuoInit, + dim4868KuoInit, + dim4869KuoInit, + dim4870KuoInit, + dim4871KuoInit, + dim4872KuoInit, + dim4873KuoInit, + dim4874KuoInit, + dim4875KuoInit, + dim4876KuoInit, + dim4877KuoInit, + dim4878KuoInit, + dim4879KuoInit, + dim4880KuoInit, + dim4881KuoInit, + dim4882KuoInit, + dim4883KuoInit, + dim4884KuoInit, + dim4885KuoInit, + dim4886KuoInit, + dim4887KuoInit, + dim4888KuoInit, + dim4889KuoInit, + dim4890KuoInit, + dim4891KuoInit, + dim4892KuoInit, + dim4893KuoInit, + dim4894KuoInit, + dim4895KuoInit, + dim4896KuoInit, + dim4897KuoInit, + dim4898KuoInit, + dim4899KuoInit, + dim4900KuoInit, + dim4901KuoInit, + dim4902KuoInit, + dim4903KuoInit, + dim4904KuoInit, + dim4905KuoInit, + dim4906KuoInit, + dim4907KuoInit, + dim4908KuoInit, + dim4909KuoInit, + dim4910KuoInit, + dim4911KuoInit, + dim4912KuoInit, + dim4913KuoInit, + dim4914KuoInit, + dim4915KuoInit, + dim4916KuoInit, + dim4917KuoInit, + dim4918KuoInit, + dim4919KuoInit, + dim4920KuoInit, + dim4921KuoInit, + dim4922KuoInit, + dim4923KuoInit, + dim4924KuoInit, + dim4925KuoInit, + }; + + static ulong[] dim1Kuo3Init = { 1, 0 }; + static ulong[] dim2Kuo3Init = { 1, 1, 0 }; + static ulong[] dim3Kuo3Init = { 1, 1, 1, 0 }; + static ulong[] dim4Kuo3Init = { 1, 3, 1, 0 }; + static ulong[] dim5Kuo3Init = { 1, 3, 7, 1, 0 }; + static ulong[] dim6Kuo3Init = { 1, 1, 3, 7, 0 }; + static ulong[] dim7Kuo3Init = { 1, 3, 1, 7, 23, 0 }; + static ulong[] dim8Kuo3Init = { 1, 3, 1, 1, 13, 0 }; + static ulong[] dim9Kuo3Init = { 1, 1, 7, 7, 9, 0 }; + static ulong[] dim10Kuo3Init = { 1, 1, 5, 15, 21, 0 }; + static ulong[] dim11Kuo3Init = { 1, 3, 5, 3, 23, 0 }; + static ulong[] dim12Kuo3Init = { 1, 1, 1, 15, 27, 0 }; + static ulong[] dim13Kuo3Init = { 1, 3, 7, 9, 1, 9, 0 }; + static ulong[] dim14Kuo3Init = { 1, 1, 7, 15, 31, 37, 0 }; + static ulong[] dim15Kuo3Init = { 1, 1, 5, 5, 31, 9, 0 }; + static ulong[] dim16Kuo3Init = { 1, 3, 1, 13, 3, 49, 0 }; + static ulong[] dim17Kuo3Init = { 1, 1, 7, 15, 1, 13, 0 }; + static ulong[] dim18Kuo3Init = { 1, 3, 3, 13, 29, 37, 0 }; + static ulong[] dim19Kuo3Init = { 1, 1, 1, 5, 13, 51, 45, 0 }; + static ulong[] dim20Kuo3Init = { 1, 3, 1, 7, 19, 23, 51, 0 }; + static ulong[] dim21Kuo3Init = { 1, 3, 7, 1, 27, 45, 61, 0 }; + static ulong[] dim22Kuo3Init = { 1, 3, 7, 3, 9, 51, 1, 0 }; + static ulong[] dim23Kuo3Init = { 1, 3, 1, 11, 27, 3, 23, 0 }; + static ulong[] dim24Kuo3Init = { 1, 3, 7, 9, 5, 35, 105, 0 }; + static ulong[] dim25Kuo3Init = { 1, 1, 1, 1, 19, 21, 69, 0 }; + static ulong[] dim26Kuo3Init = { 1, 3, 3, 5, 11, 61, 41, 0 }; + static ulong[] dim27Kuo3Init = { 1, 1, 3, 13, 15, 17, 25, 0 }; + static ulong[] dim28Kuo3Init = { 1, 1, 1, 13, 19, 47, 19, 0 }; + static ulong[] dim29Kuo3Init = { 1, 1, 7, 1, 31, 23, 127, 0 }; + static ulong[] dim30Kuo3Init = { 1, 1, 7, 1, 31, 59, 123, 0 }; + static ulong[] dim31Kuo3Init = { 1, 1, 5, 5, 13, 39, 109, 0 }; + static ulong[] dim32Kuo3Init = { 1, 3, 7, 15, 23, 19, 127, 0 }; + static ulong[] dim33Kuo3Init = { 1, 1, 5, 3, 1, 47, 15, 0 }; + static ulong[] dim34Kuo3Init = { 1, 1, 3, 13, 23, 1, 61, 0 }; + static ulong[] dim35Kuo3Init = { 1, 3, 3, 3, 3, 35, 83, 0 }; + static ulong[] dim36Kuo3Init = { 1, 1, 5, 5, 13, 5, 19, 0 }; + static ulong[] dim37Kuo3Init = { 1, 1, 5, 9, 13, 51, 25, 117, 0 }; + static ulong[] dim38Kuo3Init = { 1, 1, 5, 11, 19, 33, 111, 71, 0 }; + static ulong[] dim39Kuo3Init = { 1, 3, 1, 9, 5, 63, 33, 27, 0 }; + static ulong[] dim40Kuo3Init = { 1, 3, 1, 5, 19, 57, 15, 181, 0 }; + static ulong[] dim41Kuo3Init = { 1, 3, 7, 5, 5, 41, 115, 15, 0 }; + static ulong[] dim42Kuo3Init = { 1, 3, 1, 9, 9, 23, 45, 43, 0 }; + static ulong[] dim43Kuo3Init = { 1, 1, 1, 1, 13, 1, 109, 29, 0 }; + static ulong[] dim44Kuo3Init = { 1, 1, 5, 13, 31, 29, 95, 111, 0 }; + static ulong[] dim45Kuo3Init = { 1, 1, 1, 3, 9, 39, 109, 17, 0 }; + static ulong[] dim46Kuo3Init = { 1, 1, 1, 5, 17, 17, 47, 153, 0 }; + static ulong[] dim47Kuo3Init = { 1, 1, 1, 3, 31, 57, 43, 17, 0 }; + static ulong[] dim48Kuo3Init = { 1, 3, 7, 3, 29, 17, 91, 153, 0 }; + static ulong[] dim49Kuo3Init = { 1, 3, 3, 5, 21, 7, 73, 91, 0 }; + static ulong[] dim50Kuo3Init = { 1, 1, 7, 11, 13, 9, 83, 213, 0 }; + static ulong[] dim51Kuo3Init = { 1, 1, 7, 3, 17, 55, 37, 189, 0 }; + static ulong[] dim52Kuo3Init = { 1, 3, 7, 5, 7, 15, 39, 247, 0 }; + static ulong[] dim53Kuo3Init = { 1, 3, 1, 9, 27, 41, 83, 63, 89, 0 }; + static ulong[] dim54Kuo3Init = { 1, 3, 7, 11, 9, 51, 59, 89, 11, 0 }; + static ulong[] dim55Kuo3Init = { 1, 3, 5, 13, 29, 21, 55, 65, 45, 0 }; + static ulong[] dim56Kuo3Init = { 1, 3, 7, 5, 29, 33, 83, 229, 287, 0 }; + static ulong[] dim57Kuo3Init = { 1, 3, 5, 15, 13, 7, 89, 151, 391, 0 }; + static ulong[] dim58Kuo3Init = { 1, 3, 3, 9, 29, 3, 111, 177, 475, 0 }; + static ulong[] dim59Kuo3Init = { 1, 3, 1, 1, 5, 11, 23, 33, 337, 0 }; + static ulong[] dim60Kuo3Init = { 1, 1, 1, 15, 1, 23, 111, 175, 125, 0 }; + static ulong[] dim61Kuo3Init = { 1, 3, 7, 15, 27, 47, 31, 103, 245, 0 }; + static ulong[] dim62Kuo3Init = { 1, 3, 5, 7, 7, 3, 127, 187, 245, 0 }; + static ulong[] dim63Kuo3Init = { 1, 1, 1, 13, 13, 33, 33, 249, 381, 0 }; + static ulong[] dim64Kuo3Init = { 1, 1, 3, 11, 27, 45, 95, 31, 419, 0 }; + static ulong[] dim65Kuo3Init = { 1, 1, 1, 13, 17, 53, 35, 197, 455, 0 }; + static ulong[] dim66Kuo3Init = { 1, 1, 5, 7, 21, 43, 93, 237, 467, 0 }; + static ulong[] dim67Kuo3Init = { 1, 3, 5, 15, 1, 19, 43, 245, 193, 0 }; + static ulong[] dim68Kuo3Init = { 1, 1, 7, 11, 21, 21, 23, 147, 429, 0 }; + static ulong[] dim69Kuo3Init = { 1, 3, 3, 7, 27, 33, 99, 127, 97, 0 }; + static ulong[] dim70Kuo3Init = { 1, 1, 5, 11, 13, 21, 101, 73, 17, 0 }; + static ulong[] dim71Kuo3Init = { 1, 3, 1, 13, 3, 41, 7, 237, 311, 0 }; + static ulong[] dim72Kuo3Init = { 1, 3, 7, 1, 1, 43, 115, 215, 499, 0 }; + static ulong[] dim73Kuo3Init = { 1, 3, 1, 13, 1, 9, 113, 121, 473, 0 }; + static ulong[] dim74Kuo3Init = { 1, 1, 5, 5, 21, 7, 5, 171, 41, 0 }; + static ulong[] dim75Kuo3Init = { 1, 3, 7, 15, 31, 11, 87, 89, 495, 0 }; + static ulong[] dim76Kuo3Init = { 1, 1, 5, 1, 9, 9, 19, 161, 325, 0 }; + static ulong[] dim77Kuo3Init = { 1, 3, 3, 11, 15, 35, 75, 99, 331, 0 }; + static ulong[] dim78Kuo3Init = { 1, 3, 1, 1, 9, 27, 103, 93, 187, 0 }; + static ulong[] dim79Kuo3Init = { 1, 1, 3, 11, 19, 43, 123, 169, 325, 0 }; + static ulong[] dim80Kuo3Init = { 1, 1, 7, 9, 17, 59, 65, 139, 89, 0 }; + static ulong[] dim81Kuo3Init = { 1, 1, 5, 15, 19, 57, 29, 151, 131, 0 }; + static ulong[] dim82Kuo3Init = { 1, 1, 1, 1, 23, 49, 75, 85, 365, 0 }; + static ulong[] dim83Kuo3Init = { 1, 1, 5, 13, 11, 45, 31, 245, 311, 0 }; + static ulong[] dim84Kuo3Init = { 1, 3, 7, 5, 5, 13, 23, 1, 461, 0 }; + static ulong[] dim85Kuo3Init = { 1, 3, 1, 11, 17, 23, 19, 43, 393, 0 }; + static ulong[] dim86Kuo3Init = { 1, 1, 3, 5, 27, 9, 37, 105, 491, 0 }; + static ulong[] dim87Kuo3Init = { 1, 3, 3, 1, 15, 51, 107, 231, 39, 0 }; + static ulong[] dim88Kuo3Init = { 1, 1, 1, 5, 21, 57, 59, 143, 47, 0 }; + static ulong[] dim89Kuo3Init = { 1, 1, 7, 7, 23, 45, 29, 33, 403, 0 }; + static ulong[] dim90Kuo3Init = { 1, 3, 7, 5, 31, 7, 91, 5, 355, 0 }; + static ulong[] dim91Kuo3Init = { 1, 3, 5, 1, 25, 7, 15, 191, 45, 0 }; + static ulong[] dim92Kuo3Init = { 1, 1, 7, 5, 9, 33, 63, 75, 45, 0 }; + static ulong[] dim93Kuo3Init = { 1, 3, 5, 7, 27, 39, 83, 121, 495, 0 }; + static ulong[] dim94Kuo3Init = { 1, 1, 7, 5, 1, 25, 71, 31, 33, 0 }; + static ulong[] dim95Kuo3Init = { 1, 1, 7, 13, 13, 63, 85, 203, 491, 0 }; + static ulong[] dim96Kuo3Init = { 1, 3, 3, 11, 21, 39, 25, 213, 423, 0 }; + static ulong[] dim97Kuo3Init = { 1, 3, 5, 11, 3, 7, 115, 3, 191, 0 }; + static ulong[] dim98Kuo3Init = { 1, 1, 1, 9, 19, 1, 51, 247, 301, 0 }; + static ulong[] dim99Kuo3Init = { 1, 1, 1, 7, 13, 15, 45, 243, 453, 0 }; + static ulong[] dim100Kuo3Init = { 1, 1, 1, 7, 25, 1, 113, 153, 105, 0 }; + static ulong[] dim101Kuo3Init = { 1, 3, 5, 11, 19, 15, 3, 245, 443, 651, 0 }; + static ulong[] dim102Kuo3Init = { 1, 3, 7, 15, 13, 35, 5, 167, 233, 9, 0 }; + static ulong[] dim103Kuo3Init = { 1, 3, 5, 11, 21, 63, 95, 45, 411, 189, 0 }; + static ulong[] dim104Kuo3Init = { 1, 1, 7, 7, 31, 11, 81, 87, 15, 677, 0 }; + static ulong[] dim105Kuo3Init = { 1, 3, 3, 9, 13, 21, 27, 215, 459, 923, 0 }; + static ulong[] dim106Kuo3Init = { 1, 1, 1, 9, 13, 49, 23, 7, 441, 31, 0 }; + static ulong[] dim107Kuo3Init = { 1, 3, 1, 7, 27, 19, 5, 71, 391, 159, 0 }; + static ulong[] dim108Kuo3Init = { 1, 3, 7, 9, 9, 55, 77, 95, 353, 519, 0 }; + static ulong[] dim109Kuo3Init = { 1, 3, 1, 1, 23, 51, 51, 113, 33, 725, 0 }; + static ulong[] dim110Kuo3Init = { 1, 3, 3, 1, 21, 3, 107, 223, 261, 913, 0 }; + static ulong[] dim111Kuo3Init = { 1, 1, 1, 7, 9, 31, 83, 219, 285, 695, 0 }; + static ulong[] dim112Kuo3Init = { 1, 1, 3, 15, 1, 1, 23, 49, 39, 485, 0 }; + static ulong[] dim113Kuo3Init = { 1, 1, 1, 9, 5, 61, 71, 121, 427, 83, 0 }; + static ulong[] dim114Kuo3Init = { 1, 1, 3, 3, 5, 45, 111, 227, 261, 957, 0 }; + static ulong[] dim115Kuo3Init = { 1, 3, 7, 7, 17, 51, 61, 85, 183, 831, 0 }; + static ulong[] dim116Kuo3Init = { 1, 3, 3, 5, 13, 35, 27, 135, 189, 743, 0 }; + static ulong[] dim117Kuo3Init = { 1, 3, 1, 5, 7, 5, 7, 149, 333, 287, 0 }; + static ulong[] dim118Kuo3Init = { 1, 3, 1, 13, 19, 57, 127, 201, 365, 359, 0 }; + static ulong[] dim119Kuo3Init = { 1, 1, 5, 9, 27, 23, 79, 173, 227, 299, 0 }; + static ulong[] dim120Kuo3Init = { 1, 1, 7, 7, 9, 35, 123, 1, 289, 43, 0 }; + static ulong[] dim121Kuo3Init = { 1, 1, 5, 15, 15, 17, 57, 175, 97, 585, 0 }; + static ulong[] dim122Kuo3Init = { 1, 1, 3, 13, 9, 23, 123, 45, 463, 137, 0 }; + static ulong[] dim123Kuo3Init = { 1, 3, 1, 9, 19, 3, 81, 35, 221, 75, 0 }; + static ulong[] dim124Kuo3Init = { 1, 3, 7, 13, 31, 41, 53, 207, 253, 957, 0 }; + static ulong[] dim125Kuo3Init = { 1, 1, 1, 5, 1, 35, 51, 67, 289, 417, 0 }; + static ulong[] dim126Kuo3Init = { 1, 1, 1, 11, 27, 21, 121, 235, 49, 3, 0 }; + static ulong[] dim127Kuo3Init = { 1, 3, 7, 5, 15, 59, 25, 43, 141, 965, 0 }; + static ulong[] dim128Kuo3Init = { 1, 1, 5, 3, 7, 23, 121, 161, 223, 245, 0 }; + static ulong[] dim129Kuo3Init = { 1, 3, 7, 15, 5, 5, 49, 235, 329, 777, 0 }; + static ulong[] dim130Kuo3Init = { 1, 3, 1, 11, 7, 49, 41, 187, 221, 639, 0 }; + static ulong[] dim131Kuo3Init = { 1, 1, 5, 9, 1, 11, 41, 39, 319, 203, 0 }; + static ulong[] dim132Kuo3Init = { 1, 3, 3, 3, 21, 61, 23, 233, 397, 251, 0 }; + static ulong[] dim133Kuo3Init = { 1, 1, 1, 1, 27, 49, 87, 251, 371, 973, 0 }; + static ulong[] dim134Kuo3Init = { 1, 1, 5, 11, 11, 43, 57, 59, 153, 695, 0 }; + static ulong[] dim135Kuo3Init = { 1, 1, 3, 7, 29, 57, 87, 17, 129, 511, 0 }; + static ulong[] dim136Kuo3Init = { 1, 3, 7, 7, 5, 39, 71, 27, 59, 49, 0 }; + static ulong[] dim137Kuo3Init = { 1, 3, 3, 5, 1, 49, 65, 87, 453, 515, 0 }; + static ulong[] dim138Kuo3Init = { 1, 3, 3, 9, 19, 3, 3, 167, 85, 653, 0 }; + static ulong[] dim139Kuo3Init = { 1, 1, 7, 15, 7, 51, 67, 37, 245, 943, 0 }; + static ulong[] dim140Kuo3Init = { 1, 1, 5, 7, 1, 7, 21, 5, 135, 999, 0 }; + static ulong[] dim141Kuo3Init = { 1, 3, 3, 5, 19, 1, 7, 179, 405, 589, 0 }; + static ulong[] dim142Kuo3Init = { 1, 1, 3, 15, 3, 3, 43, 79, 501, 287, 0 }; + static ulong[] dim143Kuo3Init = { 1, 1, 3, 9, 21, 39, 59, 181, 99, 737, 0 }; + static ulong[] dim144Kuo3Init = { 1, 3, 7, 1, 3, 11, 91, 33, 273, 651, 0 }; + static ulong[] dim145Kuo3Init = { 1, 1, 5, 11, 23, 47, 97, 253, 465, 741, 0 }; + static ulong[] dim146Kuo3Init = { 1, 1, 5, 1, 7, 45, 33, 203, 297, 193, 0 }; + static ulong[] dim147Kuo3Init = { 1, 1, 5, 3, 31, 55, 63, 41, 243, 953, 0 }; + static ulong[] dim148Kuo3Init = { 1, 3, 5, 9, 9, 53, 51, 71, 281, 447, 0 }; + static ulong[] dim149Kuo3Init = { 1, 3, 3, 9, 5, 63, 77, 89, 213, 527, 0 }; + static ulong[] dim150Kuo3Init = { 1, 1, 3, 11, 31, 15, 3, 91, 321, 997, 0 }; + static ulong[] dim151Kuo3Init = { 1, 3, 5, 7, 31, 27, 117, 179, 389, 645, 0 }; + static ulong[] dim152Kuo3Init = { 1, 3, 3, 9, 21, 37, 41, 49, 143, 401, 0 }; + static ulong[] dim153Kuo3Init = { 1, 3, 1, 3, 31, 57, 77, 129, 49, 245, 0 }; + static ulong[] dim154Kuo3Init = { 1, 3, 1, 15, 27, 7, 23, 69, 177, 1009, 0 }; + static ulong[] dim155Kuo3Init = { 1, 3, 3, 3, 11, 9, 101, 141, 313, 739, 0 }; + static ulong[] dim156Kuo3Init = { 1, 1, 3, 13, 27, 31, 27, 129, 139, 645, 0 }; + static ulong[] dim157Kuo3Init = { 1, 3, 7, 5, 7, 11, 99, 145, 313, 641, 0 }; + static ulong[] dim158Kuo3Init = { 1, 3, 1, 13, 15, 3, 55, 183, 153, 743, 0 }; + static ulong[] dim159Kuo3Init = { 1, 3, 5, 1, 23, 63, 53, 237, 267, 333, 0 }; + static ulong[] dim160Kuo3Init = { 1, 3, 1, 9, 5, 27, 45, 49, 9, 911, 0 }; + static ulong[] dim161Kuo3Init = { 1, 1, 3, 9, 11, 51, 97, 231, 295, 877, 353, 0 }; + static ulong[] dim162Kuo3Init = { 1, 3, 7, 3, 15, 55, 125, 241, 149, 417, 449, 0 }; + static ulong[] dim163Kuo3Init = { 1, 1, 7, 1, 7, 31, 89, 91, 259, 819, 849, 0 }; + static ulong[] dim164Kuo3Init = { 1, 3, 1, 11, 3, 9, 79, 77, 195, 39, 937, 0 }; + static ulong[] dim165Kuo3Init = { 1, 1, 3, 15, 27, 37, 123, 233, 221, 661, 323, 0 }; + static ulong[] dim166Kuo3Init = { 1, 3, 7, 7, 31, 59, 121, 71, 19, 723, 1713, 0 }; + static ulong[] dim167Kuo3Init = { 1, 1, 5, 5, 23, 43, 75, 201, 7, 565, 293, 0 }; + static ulong[] dim168Kuo3Init = { 1, 1, 1, 3, 13, 39, 115, 209, 239, 439, 1623, 0 }; + static ulong[] dim169Kuo3Init = { 1, 3, 7, 5, 29, 39, 69, 241, 71, 465, 77, 0 }; + static ulong[] dim170Kuo3Init = { 1, 1, 1, 13, 17, 1, 91, 67, 491, 969, 1709, 0 }; + static ulong[] dim171Kuo3Init = { 1, 3, 1, 3, 7, 37, 17, 185, 365, 571, 757, 0 }; + static ulong[] dim172Kuo3Init = { 1, 1, 5, 1, 29, 47, 87, 65, 171, 893, 1659, 0 }; + static ulong[] dim173Kuo3Init = { 1, 3, 5, 5, 13, 5, 21, 151, 91, 801, 1415, 0 }; + static ulong[] dim174Kuo3Init = { 1, 3, 3, 13, 27, 35, 81, 49, 417, 315, 1039, 0 }; + static ulong[] dim175Kuo3Init = { 1, 3, 3, 7, 13, 11, 63, 19, 35, 659, 83, 0 }; + static ulong[] dim176Kuo3Init = { 1, 1, 1, 15, 11, 55, 43, 181, 45, 657, 681, 0 }; + static ulong[] dim177Kuo3Init = { 1, 3, 7, 1, 23, 9, 73, 55, 143, 731, 401, 0 }; + static ulong[] dim178Kuo3Init = { 1, 1, 3, 1, 5, 49, 125, 1, 113, 41, 1733, 0 }; + static ulong[] dim179Kuo3Init = { 1, 1, 3, 5, 21, 63, 45, 119, 67, 499, 141, 0 }; + static ulong[] dim180Kuo3Init = { 1, 3, 5, 11, 29, 39, 45, 93, 415, 515, 413, 0 }; + static ulong[] dim181Kuo3Init = { 1, 1, 7, 15, 5, 3, 79, 201, 5, 473, 55, 0 }; + static ulong[] dim182Kuo3Init = { 1, 1, 3, 7, 25, 31, 55, 61, 175, 919, 2047, 0 }; + static ulong[] dim183Kuo3Init = { 1, 1, 7, 3, 31, 61, 15, 147, 409, 249, 1677, 0 }; + static ulong[] dim184Kuo3Init = { 1, 3, 3, 9, 11, 37, 9, 65, 383, 689, 111, 0 }; + static ulong[] dim185Kuo3Init = { 1, 1, 5, 1, 31, 23, 93, 15, 327, 973, 765, 0 }; + static ulong[] dim186Kuo3Init = { 1, 3, 7, 15, 25, 17, 115, 245, 205, 169, 13, 0 }; + static ulong[] dim187Kuo3Init = { 1, 1, 5, 15, 15, 27, 109, 39, 289, 135, 693, 0 }; + static ulong[] dim188Kuo3Init = { 1, 1, 7, 3, 23, 1, 119, 199, 1, 661, 1741, 0 }; + static ulong[] dim189Kuo3Init = { 1, 3, 5, 13, 7, 29, 3, 55, 369, 903, 715, 0 }; + static ulong[] dim190Kuo3Init = { 1, 1, 5, 1, 29, 19, 31, 7, 165, 1019, 467, 0 }; + static ulong[] dim191Kuo3Init = { 1, 1, 7, 11, 27, 33, 105, 27, 271, 55, 475, 0 }; + static ulong[] dim192Kuo3Init = { 1, 1, 5, 1, 27, 9, 63, 157, 507, 491, 1525, 0 }; + static ulong[] dim193Kuo3Init = { 1, 3, 3, 9, 1, 41, 71, 239, 471, 147, 505, 0 }; + static ulong[] dim194Kuo3Init = { 1, 3, 3, 1, 25, 11, 1, 35, 127, 583, 2043, 0 }; + static ulong[] dim195Kuo3Init = { 1, 3, 7, 15, 1, 13, 119, 183, 89, 555, 1739, 0 }; + static ulong[] dim196Kuo3Init = { 1, 1, 1, 3, 3, 45, 61, 163, 357, 679, 641, 0 }; + static ulong[] dim197Kuo3Init = { 1, 3, 5, 13, 23, 27, 57, 125, 393, 917, 939, 0 }; + static ulong[] dim198Kuo3Init = { 1, 1, 3, 9, 9, 21, 85, 105, 111, 537, 733, 0 }; + static ulong[] dim199Kuo3Init = { 1, 1, 3, 15, 9, 61, 43, 103, 65, 227, 315, 0 }; + static ulong[] dim200Kuo3Init = { 1, 1, 7, 9, 9, 7, 31, 219, 293, 441, 559, 0 }; + static ulong[] dim201Kuo3Init = { 1, 1, 3, 1, 23, 21, 25, 229, 303, 537, 1655, 0 }; + static ulong[] dim202Kuo3Init = { 1, 3, 7, 7, 31, 5, 21, 177, 435, 899, 1939, 0 }; + static ulong[] dim203Kuo3Init = { 1, 3, 3, 3, 11, 43, 77, 131, 353, 11, 157, 0 }; + static ulong[] dim204Kuo3Init = { 1, 3, 3, 3, 5, 45, 13, 39, 459, 261, 237, 0 }; + static ulong[] dim205Kuo3Init = { 1, 3, 5, 7, 23, 1, 55, 63, 9, 755, 589, 0 }; + static ulong[] dim206Kuo3Init = { 1, 1, 7, 5, 3, 11, 59, 167, 145, 459, 617, 0 }; + static ulong[] dim207Kuo3Init = { 1, 3, 1, 13, 31, 49, 53, 235, 1, 37, 1373, 0 }; + static ulong[] dim208Kuo3Init = { 1, 1, 7, 11, 27, 63, 21, 59, 183, 297, 15, 0 }; + static ulong[] dim209Kuo3Init = { 1, 3, 7, 15, 3, 61, 57, 205, 359, 799, 1591, 0 }; + static ulong[] dim210Kuo3Init = { 1, 1, 1, 3, 29, 29, 121, 193, 405, 161, 909, 0 }; + static ulong[] dim211Kuo3Init = { 1, 1, 5, 5, 15, 43, 19, 87, 337, 595, 551, 0 }; + static ulong[] dim212Kuo3Init = { 1, 3, 3, 7, 27, 23, 109, 127, 107, 793, 787, 0 }; + static ulong[] dim213Kuo3Init = { 1, 1, 3, 5, 9, 11, 63, 21, 363, 403, 981, 0 }; + static ulong[] dim214Kuo3Init = { 1, 1, 3, 5, 1, 39, 43, 71, 5, 151, 1535, 0 }; + static ulong[] dim215Kuo3Init = { 1, 1, 7, 3, 1, 33, 65, 249, 81, 889, 1591, 0 }; + static ulong[] dim216Kuo3Init = { 1, 3, 5, 11, 15, 53, 117, 47, 13, 215, 1953, 0 }; + static ulong[] dim217Kuo3Init = { 1, 1, 3, 13, 15, 13, 49, 209, 137, 403, 1373, 0 }; + static ulong[] dim218Kuo3Init = { 1, 1, 3, 15, 25, 13, 123, 193, 275, 235, 1975, 0 }; + static ulong[] dim219Kuo3Init = { 1, 3, 1, 3, 21, 55, 109, 115, 411, 413, 2023, 0 }; + static ulong[] dim220Kuo3Init = { 1, 3, 3, 1, 5, 7, 53, 161, 221, 529, 489, 0 }; + static ulong[] dim221Kuo3Init = { 1, 1, 3, 5, 25, 27, 103, 31, 7, 103, 343, 0 }; + static ulong[] dim222Kuo3Init = { 1, 1, 7, 11, 19, 47, 45, 201, 499, 255, 1501, 0 }; + static ulong[] dim223Kuo3Init = { 1, 3, 1, 1, 5, 7, 79, 113, 445, 515, 287, 0 }; + static ulong[] dim224Kuo3Init = { 1, 1, 7, 11, 7, 35, 87, 145, 115, 773, 1415, 0 }; + static ulong[] dim225Kuo3Init = { 1, 1, 1, 13, 15, 25, 83, 143, 347, 473, 415, 0 }; + static ulong[] dim226Kuo3Init = { 1, 3, 1, 11, 23, 45, 79, 245, 81, 835, 589, 0 }; + static ulong[] dim227Kuo3Init = { 1, 1, 1, 13, 25, 49, 17, 15, 255, 421, 1195, 0 }; + static ulong[] dim228Kuo3Init = { 1, 1, 3, 1, 13, 31, 103, 189, 43, 389, 1497, 0 }; + static ulong[] dim229Kuo3Init = { 1, 3, 5, 7, 3, 63, 21, 151, 339, 525, 455, 0 }; + static ulong[] dim230Kuo3Init = { 1, 3, 3, 13, 23, 29, 101, 25, 461, 631, 2017, 0 }; + static ulong[] dim231Kuo3Init = { 1, 1, 5, 13, 7, 57, 11, 181, 215, 911, 463, 0 }; + static ulong[] dim232Kuo3Init = { 1, 3, 7, 1, 1, 45, 41, 101, 263, 835, 1985, 0 }; + static ulong[] dim233Kuo3Init = { 1, 3, 3, 3, 25, 13, 127, 245, 137, 709, 993, 0 }; + static ulong[] dim234Kuo3Init = { 1, 3, 7, 3, 5, 19, 23, 55, 51, 367, 1513, 0 }; + static ulong[] dim235Kuo3Init = { 1, 1, 5, 3, 13, 39, 101, 119, 119, 835, 875, 0 }; + static ulong[] dim236Kuo3Init = { 1, 1, 7, 13, 17, 27, 103, 31, 223, 461, 1267, 0 }; + static ulong[] dim237Kuo3Init = { 1, 3, 5, 13, 29, 29, 29, 189, 13, 647, 1931, 0 }; + static ulong[] dim238Kuo3Init = { 1, 3, 5, 15, 9, 27, 127, 43, 341, 939, 1981, 0 }; + static ulong[] dim239Kuo3Init = { 1, 1, 7, 11, 27, 27, 25, 163, 83, 709, 141, 0 }; + static ulong[] dim240Kuo3Init = { 1, 3, 7, 15, 31, 45, 119, 141, 181, 231, 411, 0 }; + static ulong[] dim241Kuo3Init = { 1, 1, 5, 9, 31, 25, 113, 243, 435, 55, 765, 0 }; + static ulong[] dim242Kuo3Init = { 1, 1, 7, 9, 27, 5, 63, 23, 133, 767, 1963, 0 }; + static ulong[] dim243Kuo3Init = { 1, 3, 7, 9, 9, 55, 97, 159, 371, 1013, 2013, 0 }; + static ulong[] dim244Kuo3Init = { 1, 1, 3, 7, 3, 17, 13, 215, 15, 281, 291, 0 }; + static ulong[] dim245Kuo3Init = { 1, 3, 5, 9, 29, 7, 71, 9, 181, 763, 1111, 0 }; + static ulong[] dim246Kuo3Init = { 1, 3, 7, 13, 23, 55, 79, 99, 165, 447, 1947, 0 }; + static ulong[] dim247Kuo3Init = { 1, 3, 7, 7, 29, 59, 25, 41, 313, 665, 1245, 0 }; + static ulong[] dim248Kuo3Init = { 1, 1, 3, 3, 5, 29, 71, 71, 475, 781, 567, 0 }; + static ulong[] dim249Kuo3Init = { 1, 1, 1, 3, 19, 53, 61, 215, 475, 885, 459, 0 }; + static ulong[] dim250Kuo3Init = { 1, 3, 3, 13, 5, 31, 95, 137, 119, 249, 975, 0 }; + static ulong[] dim251Kuo3Init = { 1, 1, 1, 15, 21, 51, 71, 21, 193, 709, 1167, 0 }; + static ulong[] dim252Kuo3Init = { 1, 3, 7, 9, 29, 61, 45, 153, 351, 867, 995, 0 }; + static ulong[] dim253Kuo3Init = { 1, 1, 1, 15, 7, 37, 65, 51, 45, 497, 1825, 0 }; + static ulong[] dim254Kuo3Init = { 1, 3, 3, 1, 23, 59, 11, 127, 501, 351, 1525, 0 }; + static ulong[] dim255Kuo3Init = { 1, 1, 3, 15, 31, 29, 47, 105, 179, 159, 991, 0 }; + static ulong[] dim256Kuo3Init = { 1, 3, 3, 15, 27, 23, 93, 163, 169, 1003, 1369, 0 }; + static ulong[] dim257Kuo3Init = { 1, 3, 1, 5, 31, 51, 85, 221, 87, 941, 317, 0 }; + static ulong[] dim258Kuo3Init = { 1, 3, 7, 15, 21, 19, 71, 205, 385, 371, 1401, 0 }; + static ulong[] dim259Kuo3Init = { 1, 1, 5, 11, 1, 51, 31, 185, 407, 233, 1171, 0 }; + static ulong[] dim260Kuo3Init = { 1, 3, 3, 9, 19, 11, 93, 253, 373, 679, 69, 0 }; + static ulong[] dim261Kuo3Init = { 1, 1, 7, 15, 23, 45, 87, 61, 113, 541, 1701, 0 }; + static ulong[] dim262Kuo3Init = { 1, 1, 5, 7, 7, 61, 55, 167, 345, 633, 1699, 0 }; + static ulong[] dim263Kuo3Init = { 1, 3, 7, 7, 1, 23, 121, 33, 507, 361, 1945, 0 }; + static ulong[] dim264Kuo3Init = { 1, 3, 7, 1, 19, 47, 43, 101, 67, 57, 1685, 0 }; + static ulong[] dim265Kuo3Init = { 1, 3, 3, 3, 25, 63, 53, 149, 483, 551, 1519, 0 }; + static ulong[] dim266Kuo3Init = { 1, 3, 1, 3, 27, 1, 41, 213, 57, 897, 121, 0 }; + static ulong[] dim267Kuo3Init = { 1, 3, 1, 5, 19, 13, 49, 81, 239, 455, 957, 0 }; + static ulong[] dim268Kuo3Init = { 1, 1, 3, 7, 15, 23, 89, 171, 319, 117, 2041, 0 }; + static ulong[] dim269Kuo3Init = { 1, 1, 3, 13, 3, 13, 41, 15, 145, 659, 973, 0 }; + static ulong[] dim270Kuo3Init = { 1, 3, 7, 1, 15, 17, 69, 53, 245, 179, 159, 0 }; + static ulong[] dim271Kuo3Init = { 1, 3, 3, 5, 5, 3, 113, 183, 219, 469, 1169, 0 }; + static ulong[] dim272Kuo3Init = { 1, 1, 5, 15, 13, 45, 89, 87, 371, 267, 1643, 0 }; + static ulong[] dim273Kuo3Init = { 1, 3, 5, 5, 1, 25, 3, 247, 309, 401, 2027, 0 }; + static ulong[] dim274Kuo3Init = { 1, 3, 1, 11, 13, 7, 79, 17, 297, 679, 1699, 0 }; + static ulong[] dim275Kuo3Init = { 1, 3, 1, 5, 13, 19, 123, 255, 343, 393, 1635, 0 }; + static ulong[] dim276Kuo3Init = { 1, 3, 3, 15, 13, 13, 37, 229, 483, 283, 1423, 0 }; + static ulong[] dim277Kuo3Init = { 1, 3, 1, 1, 7, 37, 65, 67, 77, 247, 1539, 0 }; + static ulong[] dim278Kuo3Init = { 1, 1, 3, 5, 25, 39, 37, 19, 231, 835, 797, 0 }; + static ulong[] dim279Kuo3Init = { 1, 1, 1, 11, 27, 53, 1, 217, 211, 7, 801, 0 }; + static ulong[] dim280Kuo3Init = { 1, 3, 7, 1, 15, 55, 69, 77, 491, 61, 55, 0 }; + static ulong[] dim281Kuo3Init = { 1, 1, 1, 1, 29, 21, 47, 167, 281, 105, 1363, 0 }; + static ulong[] dim282Kuo3Init = { 1, 3, 1, 15, 15, 55, 57, 207, 479, 709, 867, 0 }; + static ulong[] dim283Kuo3Init = { 1, 1, 1, 9, 7, 13, 115, 237, 47, 127, 1849, 0 }; + static ulong[] dim284Kuo3Init = { 1, 1, 7, 9, 7, 35, 83, 63, 155, 441, 1105, 0 }; + static ulong[] dim285Kuo3Init = { 1, 3, 3, 9, 17, 39, 19, 231, 491, 593, 1997, 0 }; + static ulong[] dim286Kuo3Init = { 1, 3, 3, 13, 17, 19, 65, 21, 389, 391, 483, 0 }; + static ulong[] dim287Kuo3Init = { 1, 1, 5, 7, 17, 7, 97, 173, 413, 917, 1691, 0 }; + static ulong[] dim288Kuo3Init = { 1, 1, 3, 3, 29, 49, 3, 127, 337, 713, 1057, 0 }; + static ulong[] dim289Kuo3Init = { 1, 3, 7, 5, 31, 23, 31, 119, 161, 51, 537, 0 }; + static ulong[] dim290Kuo3Init = { 1, 1, 5, 1, 29, 25, 15, 187, 143, 927, 715, 0 }; + static ulong[] dim291Kuo3Init = { 1, 1, 7, 11, 15, 47, 55, 103, 109, 465, 1439, 0 }; + static ulong[] dim292Kuo3Init = { 1, 1, 3, 13, 31, 47, 115, 177, 355, 163, 833, 0 }; + static ulong[] dim293Kuo3Init = { 1, 3, 5, 5, 31, 13, 15, 163, 57, 937, 1553, 0 }; + static ulong[] dim294Kuo3Init = { 1, 3, 5, 15, 7, 29, 47, 139, 231, 507, 595, 0 }; + static ulong[] dim295Kuo3Init = { 1, 3, 1, 15, 31, 13, 49, 253, 29, 109, 727, 0 }; + static ulong[] dim296Kuo3Init = { 1, 1, 5, 15, 21, 1, 107, 89, 367, 825, 1297, 0 }; + static ulong[] dim297Kuo3Init = { 1, 3, 3, 9, 31, 21, 31, 247, 375, 767, 1761, 0 }; + static ulong[] dim298Kuo3Init = { 1, 1, 7, 3, 31, 33, 119, 119, 409, 955, 1411, 0 }; + static ulong[] dim299Kuo3Init = { 1, 1, 7, 1, 17, 57, 101, 37, 147, 367, 265, 0 }; + static ulong[] dim300Kuo3Init = { 1, 3, 3, 3, 25, 53, 91, 43, 351, 1021, 1243, 0 }; + static ulong[] dim301Kuo3Init = { 1, 3, 3, 5, 11, 47, 107, 209, 251, 765, 1089, 0 }; + static ulong[] dim302Kuo3Init = { 1, 1, 7, 5, 9, 13, 23, 153, 367, 585, 315, 0 }; + static ulong[] dim303Kuo3Init = { 1, 3, 3, 15, 23, 57, 83, 173, 413, 555, 159, 0 }; + static ulong[] dim304Kuo3Init = { 1, 3, 7, 15, 7, 59, 31, 233, 67, 767, 75, 0 }; + static ulong[] dim305Kuo3Init = { 1, 3, 5, 3, 17, 1, 35, 37, 445, 847, 1853, 0 }; + static ulong[] dim306Kuo3Init = { 1, 3, 5, 13, 3, 1, 75, 113, 83, 467, 1057, 0 }; + static ulong[] dim307Kuo3Init = { 1, 1, 7, 1, 7, 15, 125, 31, 341, 133, 285, 0 }; + static ulong[] dim308Kuo3Init = { 1, 1, 5, 5, 15, 11, 97, 3, 59, 777, 1125, 0 }; + static ulong[] dim309Kuo3Init = { 1, 3, 7, 9, 17, 55, 117, 255, 429, 239, 1071, 0 }; + static ulong[] dim310Kuo3Init = { 1, 1, 7, 3, 27, 37, 31, 221, 385, 877, 1767, 0 }; + static ulong[] dim311Kuo3Init = { 1, 1, 5, 1, 5, 31, 43, 23, 77, 497, 1605, 0 }; + static ulong[] dim312Kuo3Init = { 1, 3, 5, 15, 15, 37, 103, 227, 33, 185, 481, 0 }; + static ulong[] dim313Kuo3Init = { 1, 3, 3, 11, 29, 61, 67, 53, 257, 609, 1581, 0 }; + static ulong[] dim314Kuo3Init = { 1, 1, 3, 15, 31, 25, 123, 59, 395, 107, 587, 0 }; + static ulong[] dim315Kuo3Init = { 1, 3, 1, 7, 29, 19, 51, 135, 503, 71, 33, 0 }; + static ulong[] dim316Kuo3Init = { 1, 3, 1, 15, 21, 31, 23, 85, 17, 227, 657, 0 }; + static ulong[] dim317Kuo3Init = { 1, 1, 1, 3, 9, 63, 61, 205, 61, 699, 599, 0 }; + static ulong[] dim318Kuo3Init = { 1, 3, 1, 15, 1, 39, 45, 133, 1, 391, 255, 0 }; + static ulong[] dim319Kuo3Init = { 1, 3, 5, 13, 17, 13, 107, 245, 55, 619, 1085, 0 }; + static ulong[] dim320Kuo3Init = { 1, 3, 3, 9, 5, 25, 5, 49, 509, 661, 1225, 0 }; + static ulong[] dim321Kuo3Init = { 1, 3, 7, 9, 29, 61, 13, 247, 341, 257, 1551, 0 }; + static ulong[] dim322Kuo3Init = { 1, 3, 7, 9, 5, 39, 123, 221, 391, 501, 527, 0 }; + static ulong[] dim323Kuo3Init = { 1, 3, 1, 7, 21, 23, 65, 233, 181, 405, 1297, 0 }; + static ulong[] dim324Kuo3Init = { 1, 1, 1, 3, 23, 23, 15, 253, 37, 679, 1455, 0 }; + static ulong[] dim325Kuo3Init = { 1, 3, 3, 3, 3, 31, 89, 105, 11, 1015, 1837, 0 }; + static ulong[] dim326Kuo3Init = { 1, 3, 1, 7, 15, 59, 105, 179, 477, 923, 1189, 0 }; + static ulong[] dim327Kuo3Init = { 1, 3, 5, 9, 1, 9, 21, 71, 145, 409, 1235, 0 }; + static ulong[] dim328Kuo3Init = { 1, 1, 7, 13, 9, 43, 85, 241, 497, 683, 1169, 0 }; + static ulong[] dim329Kuo3Init = { 1, 3, 3, 13, 29, 41, 23, 51, 1, 563, 905, 0 }; + static ulong[] dim330Kuo3Init = { 1, 3, 5, 9, 25, 51, 1, 71, 25, 195, 363, 0 }; + static ulong[] dim331Kuo3Init = { 1, 3, 7, 7, 31, 49, 13, 255, 471, 653, 1127, 0 }; + static ulong[] dim332Kuo3Init = { 1, 3, 3, 7, 7, 61, 63, 21, 413, 817, 1369, 0 }; + static ulong[] dim333Kuo3Init = { 1, 3, 5, 1, 7, 53, 43, 167, 173, 261, 633, 0 }; + static ulong[] dim334Kuo3Init = { 1, 1, 1, 13, 21, 59, 49, 135, 351, 187, 447, 0 }; + static ulong[] dim335Kuo3Init = { 1, 1, 3, 7, 5, 35, 103, 5, 247, 555, 1439, 0 }; + static ulong[] dim336Kuo3Init = { 1, 1, 3, 1, 3, 11, 5, 153, 507, 21, 1331, 0 }; + static ulong[] dim337Kuo3Init = { 1, 3, 7, 15, 25, 11, 29, 51, 353, 447, 337, 3621, 0 }; + static ulong[] dim338Kuo3Init = { 1, 3, 5, 13, 31, 51, 103, 69, 311, 645, 1373, 1155, 0 }; + static ulong[] dim339Kuo3Init = { 1, 1, 7, 7, 1, 55, 101, 203, 503, 711, 131, 937, 0 }; + static ulong[] dim340Kuo3Init = { 1, 3, 3, 11, 7, 5, 75, 63, 217, 643, 871, 3511, 0 }; + static ulong[] dim341Kuo3Init = { 1, 1, 3, 15, 21, 23, 75, 3, 113, 203, 13, 2727, 0 }; + static ulong[] dim342Kuo3Init = { 1, 3, 5, 11, 7, 1, 27, 39, 411, 195, 607, 1705, 0 }; + static ulong[] dim343Kuo3Init = { 1, 1, 7, 11, 23, 21, 11, 113, 437, 947, 1897, 1249, 0 }; + static ulong[] dim344Kuo3Init = { 1, 1, 7, 5, 23, 45, 41, 169, 33, 981, 1331, 2013, 0 }; + static ulong[] dim345Kuo3Init = { 1, 3, 1, 7, 11, 5, 11, 121, 239, 269, 1759, 829, 0 }; + static ulong[] dim346Kuo3Init = { 1, 1, 1, 9, 31, 51, 77, 61, 19, 121, 969, 3627, 0 }; + static ulong[] dim347Kuo3Init = { 1, 3, 1, 13, 23, 45, 39, 183, 21, 787, 967, 1911, 0 }; + static ulong[] dim348Kuo3Init = { 1, 1, 1, 15, 21, 19, 91, 231, 325, 531, 473, 2543, 0 }; + static ulong[] dim349Kuo3Init = { 1, 3, 5, 3, 7, 25, 91, 193, 387, 181, 493, 1225, 0 }; + static ulong[] dim350Kuo3Init = { 1, 1, 7, 7, 23, 21, 55, 221, 283, 995, 793, 485, 0 }; + static ulong[] dim351Kuo3Init = { 1, 1, 1, 15, 29, 61, 1, 33, 59, 725, 1053, 55, 0 }; + static ulong[] dim352Kuo3Init = { 1, 3, 3, 5, 15, 43, 85, 87, 425, 39, 1559, 1403, 0 }; + static ulong[] dim353Kuo3Init = { 1, 1, 5, 9, 3, 7, 65, 3, 177, 491, 121, 2755, 0 }; + static ulong[] dim354Kuo3Init = { 1, 1, 3, 3, 15, 37, 67, 145, 295, 421, 1849, 2151, 0 }; + static ulong[] dim355Kuo3Init = { 1, 1, 3, 15, 17, 41, 109, 125, 509, 407, 1927, 2401, 0 }; + static ulong[] dim356Kuo3Init = { 1, 1, 7, 5, 9, 39, 69, 1, 259, 821, 1837, 947, 0 }; + static ulong[] dim357Kuo3Init = { 1, 1, 7, 9, 25, 55, 127, 185, 143, 211, 1615, 1949, 0 }; + static ulong[] dim358Kuo3Init = { 1, 3, 3, 13, 15, 25, 25, 231, 197, 329, 1319, 853, 0 }; + static ulong[] dim359Kuo3Init = { 1, 3, 7, 11, 29, 1, 23, 131, 473, 497, 1147, 3779, 0 }; + static ulong[] dim360Kuo3Init = { 1, 3, 1, 15, 21, 23, 67, 243, 191, 353, 1091, 2121, 0 }; + static ulong[] dim361Kuo3Init = { 1, 1, 7, 11, 27, 15, 41, 183, 235, 219, 303, 795, 0 }; + static ulong[] dim362Kuo3Init = { 1, 3, 7, 15, 3, 21, 19, 187, 365, 453, 1069, 1983, 0 }; + static ulong[] dim363Kuo3Init = { 1, 1, 7, 1, 27, 11, 95, 117, 433, 453, 1839, 3863, 0 }; + static ulong[] dim364Kuo3Init = { 1, 3, 3, 5, 29, 63, 17, 243, 247, 609, 1999, 785, 0 }; + static ulong[] dim365Kuo3Init = { 1, 1, 1, 7, 21, 17, 57, 99, 227, 217, 585, 397, 0 }; + static ulong[] dim366Kuo3Init = { 1, 1, 1, 13, 13, 41, 75, 153, 355, 175, 313, 2237, 0 }; + static ulong[] dim367Kuo3Init = { 1, 3, 7, 9, 27, 63, 1, 33, 383, 507, 1315, 1691, 0 }; + static ulong[] dim368Kuo3Init = { 1, 1, 3, 3, 17, 33, 65, 235, 395, 317, 1769, 2937, 0 }; + static ulong[] dim369Kuo3Init = { 1, 3, 1, 5, 31, 19, 25, 15, 373, 823, 2003, 1309, 0 }; + static ulong[] dim370Kuo3Init = { 1, 3, 3, 5, 3, 33, 43, 225, 445, 181, 325, 797, 0 }; + static ulong[] dim371Kuo3Init = { 1, 1, 3, 1, 11, 19, 49, 129, 73, 983, 621, 2381, 0 }; + static ulong[] dim372Kuo3Init = { 1, 3, 3, 15, 1, 33, 109, 33, 363, 925, 589, 3955, 0 }; + static ulong[] dim373Kuo3Init = { 1, 1, 3, 3, 11, 21, 23, 99, 159, 949, 977, 3103, 0 }; + static ulong[] dim374Kuo3Init = { 1, 1, 5, 3, 3, 15, 41, 45, 325, 703, 907, 2467, 0 }; + static ulong[] dim375Kuo3Init = { 1, 1, 7, 15, 31, 11, 71, 225, 199, 521, 933, 2777, 0 }; + static ulong[] dim376Kuo3Init = { 1, 3, 5, 9, 13, 55, 23, 199, 293, 297, 2031, 3815, 0 }; + static ulong[] dim377Kuo3Init = { 1, 1, 3, 13, 25, 5, 25, 229, 301, 301, 1165, 2229, 0 }; + static ulong[] dim378Kuo3Init = { 1, 1, 1, 11, 1, 39, 25, 211, 233, 233, 355, 3131, 0 }; + static ulong[] dim379Kuo3Init = { 1, 3, 3, 9, 31, 37, 113, 17, 163, 547, 877, 333, 0 }; + static ulong[] dim380Kuo3Init = { 1, 1, 7, 1, 31, 7, 117, 175, 191, 191, 1185, 2637, 0 }; + static ulong[] dim381Kuo3Init = { 1, 1, 3, 11, 27, 59, 33, 79, 293, 657, 1899, 1547, 0 }; + static ulong[] dim382Kuo3Init = { 1, 3, 1, 7, 29, 43, 89, 227, 315, 971, 1175, 693, 0 }; + static ulong[] dim383Kuo3Init = { 1, 1, 1, 5, 9, 43, 17, 37, 321, 907, 441, 21, 0 }; + static ulong[] dim384Kuo3Init = { 1, 3, 1, 15, 25, 47, 21, 11, 385, 353, 1103, 3445, 0 }; + static ulong[] dim385Kuo3Init = { 1, 1, 7, 9, 21, 63, 9, 147, 79, 627, 471, 1683, 0 }; + static ulong[] dim386Kuo3Init = { 1, 3, 7, 7, 1, 13, 29, 127, 3, 629, 1213, 2981, 0 }; + static ulong[] dim387Kuo3Init = { 1, 1, 5, 9, 7, 41, 41, 235, 131, 379, 23, 1251, 0 }; + static ulong[] dim388Kuo3Init = { 1, 3, 5, 3, 17, 31, 101, 193, 271, 189, 1923, 1849, 0 }; + static ulong[] dim389Kuo3Init = { 1, 1, 1, 5, 21, 43, 35, 209, 359, 185, 1921, 2773, 0 }; + static ulong[] dim390Kuo3Init = { 1, 1, 7, 5, 31, 5, 41, 127, 415, 151, 1027, 2171, 0 }; + static ulong[] dim391Kuo3Init = { 1, 1, 1, 3, 31, 53, 127, 37, 273, 415, 1657, 467, 0 }; + static ulong[] dim392Kuo3Init = { 1, 3, 7, 3, 29, 43, 77, 35, 347, 37, 1265, 1211, 0 }; + static ulong[] dim393Kuo3Init = { 1, 1, 1, 1, 3, 31, 89, 57, 405, 491, 1685, 2727, 0 }; + static ulong[] dim394Kuo3Init = { 1, 3, 5, 15, 29, 9, 23, 79, 253, 161, 273, 4001, 0 }; + static ulong[] dim395Kuo3Init = { 1, 3, 3, 13, 29, 49, 73, 145, 203, 215, 423, 3293, 0 }; + static ulong[] dim396Kuo3Init = { 1, 1, 5, 15, 29, 43, 49, 99, 335, 1017, 315, 2761, 0 }; + static ulong[] dim397Kuo3Init = { 1, 3, 1, 9, 15, 39, 87, 243, 331, 1015, 1771, 1303, 0 }; + static ulong[] dim398Kuo3Init = { 1, 1, 1, 5, 5, 1, 15, 19, 277, 699, 1957, 373, 0 }; + static ulong[] dim399Kuo3Init = { 1, 1, 7, 1, 7, 13, 41, 211, 167, 705, 1011, 2097, 0 }; + static ulong[] dim400Kuo3Init = { 1, 1, 7, 9, 3, 25, 127, 75, 271, 817, 629, 2027, 0 }; + static ulong[] dim401Kuo3Init = { 1, 3, 1, 5, 31, 49, 17, 113, 71, 233, 443, 3005, 0 }; + static ulong[] dim402Kuo3Init = { 1, 1, 1, 1, 1, 23, 87, 29, 121, 485, 227, 2981, 0 }; + static ulong[] dim403Kuo3Init = { 1, 1, 1, 1, 19, 3, 127, 31, 57, 567, 375, 1121, 0 }; + static ulong[] dim404Kuo3Init = { 1, 1, 1, 9, 15, 49, 67, 49, 473, 957, 1955, 29, 0 }; + static ulong[] dim405Kuo3Init = { 1, 1, 1, 1, 15, 49, 71, 241, 43, 611, 953, 4013, 0 }; + static ulong[] dim406Kuo3Init = { 1, 3, 3, 3, 13, 57, 45, 65, 5, 101, 511, 3317, 0 }; + static ulong[] dim407Kuo3Init = { 1, 3, 3, 7, 25, 9, 97, 35, 495, 791, 223, 1555, 0 }; + static ulong[] dim408Kuo3Init = { 1, 1, 3, 1, 25, 37, 73, 61, 31, 525, 855, 695, 0 }; + static ulong[] dim409Kuo3Init = { 1, 3, 5, 11, 15, 45, 11, 53, 393, 557, 349, 2507, 0 }; + static ulong[] dim410Kuo3Init = { 1, 1, 5, 11, 1, 43, 77, 215, 149, 81, 1663, 987, 0 }; + static ulong[] dim411Kuo3Init = { 1, 3, 5, 5, 13, 55, 45, 79, 305, 65, 1721, 605, 0 }; + static ulong[] dim412Kuo3Init = { 1, 1, 1, 3, 15, 19, 103, 249, 253, 935, 1933, 3809, 0 }; + static ulong[] dim413Kuo3Init = { 1, 1, 1, 11, 1, 43, 119, 233, 79, 539, 1397, 1669, 0 }; + static ulong[] dim414Kuo3Init = { 1, 1, 7, 15, 9, 27, 29, 125, 335, 573, 1721, 551, 0 }; + static ulong[] dim415Kuo3Init = { 1, 1, 5, 11, 29, 33, 121, 47, 351, 857, 1155, 2939, 0 }; + static ulong[] dim416Kuo3Init = { 1, 1, 1, 13, 21, 13, 107, 179, 135, 597, 39, 2129, 0 }; + static ulong[] dim417Kuo3Init = { 1, 3, 5, 15, 11, 5, 101, 227, 457, 773, 1369, 2229, 0 }; + static ulong[] dim418Kuo3Init = { 1, 1, 7, 3, 9, 47, 53, 47, 315, 221, 369, 2991, 0 }; + static ulong[] dim419Kuo3Init = { 1, 3, 7, 9, 7, 1, 117, 229, 193, 105, 1591, 875, 0 }; + static ulong[] dim420Kuo3Init = { 1, 3, 1, 13, 5, 49, 47, 95, 431, 37, 2037, 3793, 0 }; + static ulong[] dim421Kuo3Init = { 1, 1, 3, 11, 17, 39, 91, 225, 109, 375, 1431, 3689, 0 }; + static ulong[] dim422Kuo3Init = { 1, 3, 5, 7, 27, 39, 23, 215, 55, 573, 965, 321, 0 }; + static ulong[] dim423Kuo3Init = { 1, 1, 3, 13, 1, 51, 23, 181, 399, 471, 429, 2409, 0 }; + static ulong[] dim424Kuo3Init = { 1, 1, 7, 9, 17, 21, 43, 177, 327, 789, 1581, 3505, 0 }; + static ulong[] dim425Kuo3Init = { 1, 1, 7, 7, 9, 39, 59, 187, 203, 655, 545, 2107, 0 }; + static ulong[] dim426Kuo3Init = { 1, 1, 7, 3, 15, 13, 83, 189, 213, 575, 255, 1475, 0 }; + static ulong[] dim427Kuo3Init = { 1, 1, 1, 3, 23, 27, 101, 67, 299, 1003, 1351, 1799, 0 }; + static ulong[] dim428Kuo3Init = { 1, 3, 3, 9, 13, 29, 83, 251, 151, 607, 2047, 447, 0 }; + static ulong[] dim429Kuo3Init = { 1, 3, 1, 5, 5, 7, 23, 145, 241, 437, 1215, 489, 0 }; + static ulong[] dim430Kuo3Init = { 1, 3, 1, 11, 3, 63, 55, 53, 187, 179, 1137, 3923, 0 }; + static ulong[] dim431Kuo3Init = { 1, 3, 7, 11, 31, 29, 127, 37, 509, 835, 1693, 965, 0 }; + static ulong[] dim432Kuo3Init = { 1, 1, 1, 9, 29, 1, 11, 61, 459, 415, 317, 2981, 0 }; + static ulong[] dim433Kuo3Init = { 1, 3, 7, 3, 1, 61, 31, 77, 55, 301, 1333, 2803, 0 }; + static ulong[] dim434Kuo3Init = { 1, 1, 7, 13, 3, 1, 117, 185, 385, 771, 409, 3667, 0 }; + static ulong[] dim435Kuo3Init = { 1, 1, 5, 13, 19, 3, 43, 53, 41, 111, 1617, 95, 0 }; + static ulong[] dim436Kuo3Init = { 1, 3, 7, 13, 25, 25, 125, 91, 85, 99, 461, 3999, 0 }; + static ulong[] dim437Kuo3Init = { 1, 3, 5, 7, 7, 29, 15, 155, 237, 443, 1187, 623, 0 }; + static ulong[] dim438Kuo3Init = { 1, 3, 3, 1, 11, 3, 35, 169, 449, 917, 141, 1525, 0 }; + static ulong[] dim439Kuo3Init = { 1, 1, 5, 7, 17, 11, 85, 31, 165, 35, 1069, 3395, 0 }; + static ulong[] dim440Kuo3Init = { 1, 3, 7, 15, 11, 21, 89, 61, 459, 211, 959, 2411, 0 }; + static ulong[] dim441Kuo3Init = { 1, 1, 5, 11, 25, 35, 1, 137, 491, 955, 1287, 3955, 0 }; + static ulong[] dim442Kuo3Init = { 1, 3, 3, 11, 13, 47, 105, 69, 119, 455, 769, 1665, 0 }; + static ulong[] dim443Kuo3Init = { 1, 3, 3, 13, 17, 9, 27, 25, 445, 611, 855, 1273, 0 }; + static ulong[] dim444Kuo3Init = { 1, 1, 3, 9, 3, 5, 107, 89, 443, 991, 727, 871, 0 }; + static ulong[] dim445Kuo3Init = { 1, 1, 5, 3, 19, 43, 93, 163, 193, 395, 99, 1717, 0 }; + static ulong[] dim446Kuo3Init = { 1, 1, 1, 7, 23, 43, 121, 205, 249, 255, 1763, 1867, 0 }; + static ulong[] dim447Kuo3Init = { 1, 1, 3, 3, 1, 45, 33, 191, 475, 503, 761, 1845, 0 }; + static ulong[] dim448Kuo3Init = { 1, 1, 3, 3, 31, 39, 11, 203, 9, 183, 407, 3787, 0 }; + static ulong[] dim449Kuo3Init = { 1, 1, 5, 11, 11, 3, 65, 175, 131, 757, 1717, 1003, 0 }; + static ulong[] dim450Kuo3Init = { 1, 1, 1, 15, 13, 61, 29, 123, 269, 531, 257, 1399, 0 }; + static ulong[] dim451Kuo3Init = { 1, 3, 5, 5, 13, 23, 23, 1, 293, 921, 79, 479, 0 }; + static ulong[] dim452Kuo3Init = { 1, 1, 3, 13, 9, 55, 21, 15, 47, 685, 829, 2679, 0 }; + static ulong[] dim453Kuo3Init = { 1, 3, 5, 11, 1, 39, 97, 59, 37, 787, 991, 263, 0 }; + static ulong[] dim454Kuo3Init = { 1, 3, 5, 15, 31, 3, 45, 159, 219, 161, 1025, 665, 0 }; + static ulong[] dim455Kuo3Init = { 1, 3, 7, 15, 11, 51, 51, 19, 181, 125, 1677, 2125, 0 }; + static ulong[] dim456Kuo3Init = { 1, 1, 3, 5, 27, 23, 79, 161, 97, 581, 405, 2239, 0 }; + static ulong[] dim457Kuo3Init = { 1, 3, 1, 11, 17, 1, 97, 33, 31, 771, 707, 1053, 0 }; + static ulong[] dim458Kuo3Init = { 1, 1, 1, 11, 11, 51, 113, 47, 51, 827, 385, 3211, 0 }; + static ulong[] dim459Kuo3Init = { 1, 3, 3, 7, 17, 3, 99, 57, 59, 199, 1359, 2459, 0 }; + static ulong[] dim460Kuo3Init = { 1, 1, 5, 11, 1, 7, 19, 37, 53, 435, 1095, 495, 0 }; + static ulong[] dim461Kuo3Init = { 1, 1, 5, 13, 19, 5, 95, 109, 245, 737, 1163, 33, 0 }; + static ulong[] dim462Kuo3Init = { 1, 3, 5, 3, 1, 17, 79, 195, 153, 857, 603, 2905, 0 }; + static ulong[] dim463Kuo3Init = { 1, 3, 5, 5, 31, 51, 71, 103, 121, 5, 931, 217, 0 }; + static ulong[] dim464Kuo3Init = { 1, 1, 5, 7, 31, 39, 11, 9, 223, 365, 1317, 449, 0 }; + static ulong[] dim465Kuo3Init = { 1, 3, 5, 3, 17, 19, 85, 121, 161, 75, 527, 3941, 0 }; + static ulong[] dim466Kuo3Init = { 1, 3, 5, 9, 17, 53, 41, 255, 207, 251, 925, 2395, 0 }; + static ulong[] dim467Kuo3Init = { 1, 3, 3, 3, 13, 5, 109, 125, 293, 165, 1715, 1017, 0 }; + static ulong[] dim468Kuo3Init = { 1, 3, 7, 1, 23, 27, 45, 141, 267, 187, 611, 59, 0 }; + static ulong[] dim469Kuo3Init = { 1, 3, 1, 9, 11, 9, 81, 239, 469, 905, 525, 1549, 0 }; + static ulong[] dim470Kuo3Init = { 1, 1, 1, 15, 13, 21, 71, 87, 199, 389, 139, 3499, 0 }; + static ulong[] dim471Kuo3Init = { 1, 3, 7, 5, 21, 41, 107, 195, 369, 391, 271, 3351, 0 }; + static ulong[] dim472Kuo3Init = { 1, 3, 3, 1, 17, 19, 75, 219, 415, 241, 1441, 967, 0 }; + static ulong[] dim473Kuo3Init = { 1, 1, 1, 15, 7, 7, 79, 213, 391, 831, 1649, 3741, 0 }; + static ulong[] dim474Kuo3Init = { 1, 3, 5, 3, 29, 57, 99, 207, 243, 915, 1969, 2499, 0 }; + static ulong[] dim475Kuo3Init = { 1, 1, 3, 13, 1, 3, 27, 211, 271, 657, 1251, 3333, 0 }; + static ulong[] dim476Kuo3Init = { 1, 3, 3, 1, 3, 31, 49, 53, 273, 837, 1771, 1405, 0 }; + static ulong[] dim477Kuo3Init = { 1, 3, 7, 7, 1, 33, 125, 221, 179, 601, 565, 2709, 0 }; + static ulong[] dim478Kuo3Init = { 1, 1, 1, 7, 31, 19, 81, 173, 413, 849, 579, 2487, 0 }; + static ulong[] dim479Kuo3Init = { 1, 1, 7, 11, 17, 23, 97, 145, 383, 1015, 547, 483, 0 }; + static ulong[] dim480Kuo3Init = { 1, 3, 1, 3, 11, 63, 41, 175, 43, 283, 1441, 2695, 0 }; + static ulong[] dim481Kuo3Init = { 1, 1, 7, 9, 5, 23, 61, 161, 149, 49, 1851, 1281, 4615, 0 }; + static ulong[] dim482Kuo3Init = { 1, 1, 5, 7, 23, 47, 111, 213, 317, 107, 849, 1563, 6863, 0 }; + static ulong[] dim483Kuo3Init = { 1, 1, 7, 9, 31, 53, 115, 233, 497, 23, 1395, 327, 551, 0 }; + static ulong[] dim484Kuo3Init = { 1, 1, 7, 13, 21, 51, 17, 109, 29, 1003, 1221, 2175, 4645, 0 }; + static ulong[] dim485Kuo3Init = { 1, 3, 3, 15, 7, 57, 103, 131, 63, 217, 607, 2311, 1237, 0 }; + static ulong[] dim486Kuo3Init = { 1, 3, 5, 3, 19, 27, 107, 223, 15, 149, 1777, 2211, 2241, 0 }; + static ulong[] dim487Kuo3Init = { 1, 1, 1, 1, 5, 37, 87, 59, 435, 37, 1771, 1675, 6241, 0 }; + static ulong[] dim488Kuo3Init = { 1, 3, 1, 7, 29, 51, 83, 41, 11, 545, 995, 1625, 4883, 0 }; + static ulong[] dim489Kuo3Init = { 1, 1, 1, 5, 15, 43, 57, 111, 55, 921, 567, 1767, 1849, 0 }; + static ulong[] dim490Kuo3Init = { 1, 1, 5, 15, 5, 49, 3, 23, 307, 691, 1727, 2297, 6705, 0 }; + static ulong[] dim491Kuo3Init = { 1, 3, 7, 5, 31, 1, 111, 53, 499, 1017, 1889, 1955, 1327, 0 }; + static ulong[] dim492Kuo3Init = { 1, 3, 7, 11, 17, 35, 71, 223, 149, 743, 319, 3157, 5961, 0 }; + static ulong[] dim493Kuo3Init = { 1, 1, 1, 3, 21, 31, 27, 79, 353, 753, 341, 2121, 5455, 0 }; + static ulong[] dim494Kuo3Init = { 1, 1, 5, 3, 21, 29, 27, 91, 111, 359, 27, 2383, 7149, 0 }; + static ulong[] dim495Kuo3Init = { 1, 3, 7, 9, 5, 51, 115, 65, 275, 211, 1519, 2247, 2065, 0 }; + static ulong[] dim496Kuo3Init = { 1, 1, 1, 15, 27, 7, 21, 173, 79, 357, 693, 873, 879, 0 }; + static ulong[] dim497Kuo3Init = { 1, 3, 1, 7, 25, 47, 53, 123, 491, 707, 1723, 1139, 3757, 0 }; + static ulong[] dim498Kuo3Init = { 1, 1, 7, 5, 15, 55, 103, 17, 17, 345, 1477, 3423, 7527, 0 }; + static ulong[] dim499Kuo3Init = { 1, 3, 1, 13, 1, 3, 55, 85, 251, 389, 631, 117, 4879, 0 }; + static ulong[] dim500Kuo3Init = { 1, 1, 7, 1, 29, 33, 17, 3, 303, 299, 465, 1709, 1111, 0 }; + static ulong[] dim501Kuo3Init = { 1, 1, 7, 5, 3, 29, 111, 249, 383, 611, 859, 1555, 7387, 0 }; + static ulong[] dim502Kuo3Init = { 1, 3, 5, 5, 29, 41, 33, 63, 395, 53, 351, 247, 5317, 0 }; + static ulong[] dim503Kuo3Init = { 1, 1, 5, 7, 11, 63, 121, 131, 249, 451, 619, 2395, 4575, 0 }; + static ulong[] dim504Kuo3Init = { 1, 3, 7, 3, 3, 43, 37, 211, 385, 289, 791, 735, 4683, 0 }; + static ulong[] dim505Kuo3Init = { 1, 1, 3, 11, 7, 13, 53, 7, 497, 771, 903, 119, 6601, 0 }; + static ulong[] dim506Kuo3Init = { 1, 3, 7, 1, 3, 61, 117, 237, 427, 335, 1749, 3105, 6493, 0 }; + static ulong[] dim507Kuo3Init = { 1, 3, 5, 7, 11, 55, 121, 93, 3, 953, 433, 2663, 1633, 0 }; + static ulong[] dim508Kuo3Init = { 1, 1, 7, 1, 7, 51, 43, 31, 31, 819, 791, 1071, 569, 0 }; + static ulong[] dim509Kuo3Init = { 1, 3, 5, 11, 17, 37, 71, 97, 69, 681, 1133, 2425, 3217, 0 }; + static ulong[] dim510Kuo3Init = { 1, 1, 1, 15, 9, 15, 31, 131, 113, 567, 593, 1781, 6715, 0 }; + static ulong[] dim511Kuo3Init = { 1, 1, 7, 9, 29, 25, 39, 159, 495, 507, 1253, 409, 6723, 0 }; + static ulong[] dim512Kuo3Init = { 1, 1, 1, 5, 13, 29, 25, 197, 489, 853, 87, 3173, 6389, 0 }; + static ulong[] dim513Kuo3Init = { 1, 1, 7, 11, 11, 7, 27, 227, 347, 777, 893, 1007, 1953, 0 }; + static ulong[] dim514Kuo3Init = { 1, 1, 3, 7, 31, 9, 61, 39, 251, 1, 1297, 2861, 2593, 0 }; + static ulong[] dim515Kuo3Init = { 1, 1, 5, 1, 15, 45, 3, 147, 143, 279, 2045, 649, 5579, 0 }; + static ulong[] dim516Kuo3Init = { 1, 1, 5, 5, 9, 51, 3, 249, 253, 533, 1305, 1749, 1287, 0 }; + static ulong[] dim517Kuo3Init = { 1, 3, 7, 9, 13, 15, 85, 165, 183, 943, 41, 4061, 5845, 0 }; + static ulong[] dim518Kuo3Init = { 1, 3, 3, 1, 23, 31, 49, 247, 287, 83, 1833, 1249, 2789, 0 }; + static ulong[] dim519Kuo3Init = { 1, 3, 3, 7, 7, 53, 125, 211, 145, 837, 515, 1971, 6201, 0 }; + static ulong[] dim520Kuo3Init = { 1, 3, 3, 11, 13, 11, 87, 11, 33, 355, 1049, 3053, 4801, 0 }; + static ulong[] dim521Kuo3Init = { 1, 3, 5, 13, 23, 25, 63, 221, 385, 217, 687, 455, 4083, 0 }; + static ulong[] dim522Kuo3Init = { 1, 1, 5, 1, 3, 21, 119, 79, 207, 693, 925, 1519, 3981, 0 }; + static ulong[] dim523Kuo3Init = { 1, 1, 3, 11, 21, 35, 21, 21, 297, 461, 793, 1679, 1285, 0 }; + static ulong[] dim524Kuo3Init = { 1, 3, 5, 13, 31, 23, 11, 129, 189, 933, 283, 3435, 4593, 0 }; + static ulong[] dim525Kuo3Init = { 1, 3, 1, 1, 13, 11, 113, 35, 199, 149, 181, 3183, 6205, 0 }; + static ulong[] dim526Kuo3Init = { 1, 3, 1, 9, 7, 59, 105, 161, 63, 821, 13, 2561, 755, 0 }; + static ulong[] dim527Kuo3Init = { 1, 1, 1, 7, 27, 3, 87, 243, 279, 13, 1341, 2383, 6005, 0 }; + static ulong[] dim528Kuo3Init = { 1, 3, 3, 13, 27, 25, 91, 205, 275, 663, 1875, 2399, 4179, 0 }; + static ulong[] dim529Kuo3Init = { 1, 1, 7, 15, 27, 25, 51, 235, 391, 951, 759, 285, 3443, 0 }; + static ulong[] dim530Kuo3Init = { 1, 3, 3, 5, 1, 33, 57, 107, 137, 851, 1937, 1003, 2427, 0 }; + static ulong[] dim531Kuo3Init = { 1, 1, 5, 11, 27, 3, 27, 81, 303, 151, 433, 1893, 587, 0 }; + static ulong[] dim532Kuo3Init = { 1, 1, 1, 9, 25, 45, 113, 173, 471, 191, 1031, 2119, 4853, 0 }; + static ulong[] dim533Kuo3Init = { 1, 1, 7, 11, 27, 23, 107, 229, 485, 197, 1925, 1809, 7775, 0 }; + static ulong[] dim534Kuo3Init = { 1, 1, 1, 3, 31, 61, 91, 47, 3, 643, 1487, 2563, 3893, 0 }; + static ulong[] dim535Kuo3Init = { 1, 1, 7, 15, 19, 27, 97, 109, 283, 67, 335, 3707, 1909, 0 }; + static ulong[] dim536Kuo3Init = { 1, 1, 1, 11, 23, 59, 101, 249, 121, 919, 1385, 2119, 7389, 0 }; + static ulong[] dim537Kuo3Init = { 1, 1, 7, 11, 7, 29, 33, 111, 243, 617, 125, 3887, 727, 0 }; + static ulong[] dim538Kuo3Init = { 1, 1, 3, 1, 7, 41, 91, 177, 315, 555, 1653, 1725, 8069, 0 }; + static ulong[] dim539Kuo3Init = { 1, 1, 5, 15, 3, 63, 53, 31, 177, 451, 141, 3727, 1695, 0 }; + static ulong[] dim540Kuo3Init = { 1, 1, 3, 15, 25, 37, 17, 229, 75, 705, 327, 1367, 807, 0 }; + static ulong[] dim541Kuo3Init = { 1, 3, 5, 5, 27, 1, 35, 97, 171, 167, 1077, 25, 5497, 0 }; + static ulong[] dim542Kuo3Init = { 1, 1, 7, 7, 11, 17, 105, 41, 53, 389, 941, 3273, 967, 0 }; + static ulong[] dim543Kuo3Init = { 1, 3, 3, 15, 11, 61, 125, 155, 361, 229, 1981, 1647, 5077, 0 }; + static ulong[] dim544Kuo3Init = { 1, 3, 1, 15, 5, 11, 35, 203, 425, 509, 993, 1861, 1977, 0 }; + static ulong[] dim545Kuo3Init = { 1, 3, 5, 15, 25, 7, 55, 89, 101, 939, 7, 3535, 7543, 0 }; + static ulong[] dim546Kuo3Init = { 1, 1, 3, 1, 19, 45, 117, 249, 261, 529, 1299, 597, 7207, 0 }; + static ulong[] dim547Kuo3Init = { 1, 3, 5, 13, 17, 47, 73, 231, 353, 941, 325, 115, 4005, 0 }; + static ulong[] dim548Kuo3Init = { 1, 3, 1, 9, 5, 29, 11, 161, 461, 793, 813, 3755, 7017, 0 }; + static ulong[] dim549Kuo3Init = { 1, 3, 3, 15, 23, 21, 83, 47, 143, 279, 1009, 3315, 3801, 0 }; + static ulong[] dim550Kuo3Init = { 1, 1, 7, 9, 21, 55, 31, 129, 325, 59, 701, 2227, 1491, 0 }; + static ulong[] dim551Kuo3Init = { 1, 1, 7, 1, 21, 41, 87, 151, 269, 885, 795, 4087, 2919, 0 }; + static ulong[] dim552Kuo3Init = { 1, 1, 3, 11, 7, 19, 103, 45, 461, 109, 1921, 2497, 4969, 0 }; + static ulong[] dim553Kuo3Init = { 1, 1, 3, 7, 7, 49, 9, 185, 95, 277, 1325, 2393, 7585, 0 }; + static ulong[] dim554Kuo3Init = { 1, 3, 3, 13, 13, 1, 71, 77, 245, 865, 1693, 2187, 2589, 0 }; + static ulong[] dim555Kuo3Init = { 1, 3, 1, 15, 19, 59, 17, 189, 101, 511, 23, 677, 4091, 0 }; + static ulong[] dim556Kuo3Init = { 1, 3, 5, 7, 9, 45, 45, 233, 47, 973, 795, 2339, 595, 0 }; + static ulong[] dim557Kuo3Init = { 1, 3, 1, 7, 15, 35, 79, 53, 429, 299, 389, 237, 2261, 0 }; + static ulong[] dim558Kuo3Init = { 1, 3, 1, 1, 9, 35, 27, 169, 85, 755, 145, 91, 257, 0 }; + static ulong[] dim559Kuo3Init = { 1, 3, 7, 11, 25, 33, 41, 151, 11, 401, 1335, 2111, 3309, 0 }; + static ulong[] dim560Kuo3Init = { 1, 1, 7, 3, 17, 1, 61, 253, 289, 917, 1157, 1513, 4783, 0 }; + static ulong[] dim561Kuo3Init = { 1, 1, 5, 7, 23, 51, 59, 171, 161, 815, 969, 1199, 4137, 0 }; + static ulong[] dim562Kuo3Init = { 1, 3, 3, 7, 7, 27, 81, 175, 89, 145, 19, 1469, 3775, 0 }; + static ulong[] dim563Kuo3Init = { 1, 3, 1, 7, 7, 33, 95, 179, 177, 375, 1077, 3711, 2903, 0 }; + static ulong[] dim564Kuo3Init = { 1, 3, 1, 15, 15, 27, 127, 245, 307, 949, 1037, 3753, 4993, 0 }; + static ulong[] dim565Kuo3Init = { 1, 3, 3, 7, 29, 15, 59, 39, 9, 331, 1877, 3565, 6483, 0 }; + static ulong[] dim566Kuo3Init = { 1, 1, 5, 3, 1, 41, 29, 185, 351, 837, 747, 3263, 749, 0 }; + static ulong[] dim567Kuo3Init = { 1, 1, 7, 1, 19, 47, 1, 239, 489, 79, 767, 1123, 8145, 0 }; + static ulong[] dim568Kuo3Init = { 1, 3, 7, 15, 7, 39, 23, 239, 465, 981, 185, 837, 7837, 0 }; + static ulong[] dim569Kuo3Init = { 1, 3, 5, 5, 23, 15, 21, 221, 259, 663, 185, 1203, 2857, 0 }; + static ulong[] dim570Kuo3Init = { 1, 1, 3, 5, 31, 43, 107, 199, 117, 161, 403, 2227, 7969, 0 }; + static ulong[] dim571Kuo3Init = { 1, 1, 3, 5, 5, 5, 105, 153, 349, 601, 815, 939, 3547, 0 }; + static ulong[] dim572Kuo3Init = { 1, 1, 7, 15, 23, 33, 85, 51, 309, 63, 1799, 1599, 1711, 0 }; + static ulong[] dim573Kuo3Init = { 1, 1, 7, 3, 15, 41, 71, 169, 87, 381, 1695, 3189, 3343, 0 }; + static ulong[] dim574Kuo3Init = { 1, 1, 7, 11, 15, 57, 81, 107, 57, 773, 111, 2741, 6399, 0 }; + static ulong[] dim575Kuo3Init = { 1, 1, 5, 15, 5, 55, 65, 35, 387, 797, 1093, 4039, 3041, 0 }; + static ulong[] dim576Kuo3Init = { 1, 1, 5, 3, 29, 5, 87, 235, 503, 539, 483, 2785, 4211, 0 }; + static ulong[] dim577Kuo3Init = { 1, 1, 3, 5, 11, 53, 101, 83, 61, 97, 411, 2063, 2951, 0 }; + static ulong[] dim578Kuo3Init = { 1, 1, 1, 5, 25, 33, 45, 253, 183, 251, 1323, 1891, 5143, 0 }; + static ulong[] dim579Kuo3Init = { 1, 1, 5, 11, 7, 61, 67, 201, 465, 851, 1, 1533, 2839, 0 }; + static ulong[] dim580Kuo3Init = { 1, 3, 3, 7, 15, 3, 51, 9, 425, 671, 223, 2203, 481, 0 }; + static ulong[] dim581Kuo3Init = { 1, 1, 1, 7, 25, 5, 45, 153, 479, 437, 221, 1085, 455, 0 }; + static ulong[] dim582Kuo3Init = { 1, 3, 7, 1, 7, 53, 65, 35, 153, 423, 989, 2779, 4787, 0 }; + static ulong[] dim583Kuo3Init = { 1, 3, 1, 3, 29, 43, 7, 219, 47, 431, 627, 3735, 383, 0 }; + static ulong[] dim584Kuo3Init = { 1, 1, 5, 13, 31, 49, 121, 29, 235, 325, 1247, 1765, 7173, 0 }; + static ulong[] dim585Kuo3Init = { 1, 1, 1, 9, 25, 15, 73, 167, 191, 215, 259, 111, 2289, 0 }; + static ulong[] dim586Kuo3Init = { 1, 3, 7, 9, 23, 1, 119, 15, 155, 153, 1419, 667, 6309, 0 }; + static ulong[] dim587Kuo3Init = { 1, 1, 5, 13, 7, 53, 91, 161, 445, 283, 571, 3623, 5737, 0 }; + static ulong[] dim588Kuo3Init = { 1, 3, 3, 5, 3, 39, 29, 47, 393, 871, 345, 805, 8167, 0 }; + static ulong[] dim589Kuo3Init = { 1, 3, 1, 5, 21, 9, 1, 169, 471, 693, 53, 967, 4145, 0 }; + static ulong[] dim590Kuo3Init = { 1, 3, 7, 11, 17, 19, 123, 133, 511, 15, 675, 3935, 5465, 0 }; + static ulong[] dim591Kuo3Init = { 1, 3, 5, 13, 25, 51, 63, 87, 503, 61, 907, 105, 7599, 0 }; + static ulong[] dim592Kuo3Init = { 1, 3, 5, 13, 27, 3, 67, 189, 193, 131, 1227, 227, 1975, 0 }; + static ulong[] dim593Kuo3Init = { 1, 3, 5, 5, 31, 17, 89, 187, 391, 575, 1715, 2551, 5371, 0 }; + static ulong[] dim594Kuo3Init = { 1, 3, 1, 9, 11, 63, 9, 251, 399, 703, 1557, 107, 675, 0 }; + static ulong[] dim595Kuo3Init = { 1, 3, 5, 15, 29, 55, 15, 65, 51, 811, 1387, 3815, 7973, 0 }; + static ulong[] dim596Kuo3Init = { 1, 3, 1, 13, 19, 33, 87, 7, 183, 97, 2011, 3849, 3015, 0 }; + static ulong[] dim597Kuo3Init = { 1, 1, 3, 11, 29, 57, 27, 185, 457, 181, 1341, 2033, 2181, 0 }; + static ulong[] dim598Kuo3Init = { 1, 3, 7, 5, 25, 19, 19, 147, 101, 73, 499, 897, 3053, 0 }; + static ulong[] dim599Kuo3Init = { 1, 3, 5, 5, 29, 29, 109, 5, 197, 581, 1829, 3679, 283, 0 }; + static ulong[] dim600Kuo3Init = { 1, 3, 5, 1, 27, 63, 71, 131, 309, 193, 1663, 3009, 1041, 0 }; + static ulong[] dim601Kuo3Init = { 1, 3, 3, 5, 19, 29, 95, 173, 195, 205, 207, 3597, 2223, 0 }; + static ulong[] dim602Kuo3Init = { 1, 1, 5, 1, 3, 45, 127, 251, 175, 663, 415, 1789, 6577, 0 }; + static ulong[] dim603Kuo3Init = { 1, 3, 1, 9, 1, 51, 73, 165, 377, 525, 381, 2829, 4619, 0 }; + static ulong[] dim604Kuo3Init = { 1, 3, 1, 15, 23, 19, 79, 115, 297, 75, 1505, 1407, 5865, 0 }; + static ulong[] dim605Kuo3Init = { 1, 1, 1, 5, 27, 33, 93, 123, 449, 747, 2027, 51, 4507, 0 }; + static ulong[] dim606Kuo3Init = { 1, 3, 1, 7, 13, 39, 49, 111, 101, 247, 1375, 3577, 6769, 0 }; + static ulong[] dim607Kuo3Init = { 1, 1, 7, 9, 19, 49, 35, 139, 57, 527, 1943, 1781, 1839, 0 }; + static ulong[] dim608Kuo3Init = { 1, 3, 7, 7, 3, 7, 67, 163, 289, 139, 1415, 2149, 7501, 0 }; + static ulong[] dim609Kuo3Init = { 1, 3, 5, 5, 13, 47, 21, 47, 3, 105, 473, 2013, 2443, 0 }; + static ulong[] dim610Kuo3Init = { 1, 1, 3, 13, 31, 25, 21, 75, 505, 795, 1311, 2467, 5541, 0 }; + static ulong[] dim611Kuo3Init = { 1, 1, 5, 1, 25, 15, 21, 113, 427, 249, 293, 1089, 1589, 0 }; + static ulong[] dim612Kuo3Init = { 1, 1, 7, 5, 17, 11, 3, 211, 219, 37, 781, 1299, 3669, 0 }; + static ulong[] dim613Kuo3Init = { 1, 3, 1, 15, 23, 3, 55, 59, 273, 947, 1647, 3111, 2615, 0 }; + static ulong[] dim614Kuo3Init = { 1, 1, 3, 7, 21, 33, 81, 253, 267, 499, 299, 4015, 1669, 0 }; + static ulong[] dim615Kuo3Init = { 1, 3, 7, 5, 5, 17, 75, 205, 53, 237, 1791, 3671, 4205, 0 }; + static ulong[] dim616Kuo3Init = { 1, 3, 1, 5, 3, 59, 77, 39, 295, 649, 1219, 3971, 7675, 0 }; + static ulong[] dim617Kuo3Init = { 1, 3, 5, 15, 1, 1, 13, 207, 445, 91, 571, 869, 359, 0 }; + static ulong[] dim618Kuo3Init = { 1, 3, 5, 5, 15, 35, 79, 175, 313, 745, 1689, 1499, 5899, 0 }; + static ulong[] dim619Kuo3Init = { 1, 3, 7, 7, 19, 51, 57, 131, 491, 301, 1405, 3789, 6081, 0 }; + static ulong[] dim620Kuo3Init = { 1, 1, 3, 9, 27, 53, 55, 193, 413, 535, 715, 2823, 2063, 0 }; + static ulong[] dim621Kuo3Init = { 1, 1, 7, 13, 31, 47, 47, 99, 441, 125, 999, 3575, 8007, 0 }; + static ulong[] dim622Kuo3Init = { 1, 1, 1, 11, 17, 45, 67, 27, 329, 267, 773, 565, 5559, 0 }; + static ulong[] dim623Kuo3Init = { 1, 1, 7, 11, 31, 23, 125, 117, 373, 523, 571, 1385, 3841, 0 }; + static ulong[] dim624Kuo3Init = { 1, 3, 7, 15, 3, 15, 63, 91, 23, 97, 311, 3045, 2025, 0 }; + static ulong[] dim625Kuo3Init = { 1, 3, 7, 5, 29, 37, 105, 63, 511, 35, 537, 4047, 7449, 0 }; + static ulong[] dim626Kuo3Init = { 1, 3, 1, 13, 5, 9, 29, 51, 269, 395, 1737, 2097, 199, 0 }; + static ulong[] dim627Kuo3Init = { 1, 3, 7, 15, 23, 33, 71, 111, 497, 369, 1265, 2937, 1883, 0 }; + static ulong[] dim628Kuo3Init = { 1, 1, 3, 3, 3, 49, 117, 243, 57, 83, 3, 3319, 5711, 0 }; + static ulong[] dim629Kuo3Init = { 1, 1, 5, 11, 25, 41, 29, 123, 405, 623, 1537, 3467, 699, 0 }; + static ulong[] dim630Kuo3Init = { 1, 3, 7, 13, 17, 5, 87, 103, 501, 581, 713, 1535, 4637, 0 }; + static ulong[] dim631Kuo3Init = { 1, 3, 3, 3, 25, 59, 91, 241, 163, 537, 1249, 3427, 6647, 0 }; + static ulong[] dim632Kuo3Init = { 1, 3, 7, 1, 27, 7, 49, 219, 51, 989, 599, 2593, 6051, 0 }; + static ulong[] dim633Kuo3Init = { 1, 1, 7, 9, 17, 19, 31, 23, 199, 729, 819, 287, 4689, 0 }; + static ulong[] dim634Kuo3Init = { 1, 1, 1, 11, 13, 49, 97, 229, 411, 29, 1815, 3761, 3849, 0 }; + static ulong[] dim635Kuo3Init = { 1, 3, 1, 1, 23, 35, 15, 33, 3, 865, 995, 1263, 3779, 0 }; + static ulong[] dim636Kuo3Init = { 1, 1, 7, 7, 17, 1, 103, 117, 455, 93, 599, 1075, 4389, 0 }; + static ulong[] dim637Kuo3Init = { 1, 3, 7, 5, 27, 3, 67, 117, 101, 443, 1773, 3731, 629, 0 }; + static ulong[] dim638Kuo3Init = { 1, 3, 1, 11, 9, 51, 63, 217, 273, 425, 1889, 1113, 3799, 0 }; + static ulong[] dim639Kuo3Init = { 1, 1, 3, 3, 25, 13, 37, 89, 429, 493, 637, 3287, 6733, 0 }; + static ulong[] dim640Kuo3Init = { 1, 1, 1, 9, 17, 29, 45, 89, 141, 633, 243, 4035, 1835, 0 }; + static ulong[] dim641Kuo3Init = { 1, 1, 1, 9, 15, 41, 61, 239, 349, 3, 1669, 1767, 6257, 0 }; + static ulong[] dim642Kuo3Init = { 1, 3, 5, 11, 21, 41, 17, 65, 495, 879, 1891, 667, 3807, 0 }; + static ulong[] dim643Kuo3Init = { 1, 1, 5, 11, 7, 25, 101, 231, 159, 287, 1125, 3859, 4331, 0 }; + static ulong[] dim644Kuo3Init = { 1, 1, 1, 9, 13, 59, 23, 85, 393, 611, 1213, 7, 5707, 0 }; + static ulong[] dim645Kuo3Init = { 1, 3, 5, 15, 13, 33, 61, 255, 163, 465, 641, 703, 6391, 0 }; + static ulong[] dim646Kuo3Init = { 1, 1, 3, 3, 29, 41, 25, 19, 247, 973, 1815, 235, 7215, 0 }; + static ulong[] dim647Kuo3Init = { 1, 1, 3, 11, 17, 43, 83, 105, 493, 663, 1395, 1079, 745, 0 }; + static ulong[] dim648Kuo3Init = { 1, 1, 3, 13, 17, 53, 5, 55, 31, 459, 673, 1253, 5601, 0 }; + static ulong[] dim649Kuo3Init = { 1, 3, 7, 7, 1, 49, 85, 73, 265, 555, 43, 2235, 6787, 0 }; + static ulong[] dim650Kuo3Init = { 1, 1, 7, 5, 15, 3, 43, 201, 289, 755, 1605, 1927, 6179, 0 }; + static ulong[] dim651Kuo3Init = { 1, 1, 7, 9, 15, 5, 101, 19, 17, 879, 1155, 3845, 3225, 0 }; + static ulong[] dim652Kuo3Init = { 1, 3, 5, 15, 15, 63, 103, 133, 209, 121, 1865, 4039, 3335, 0 }; + static ulong[] dim653Kuo3Init = { 1, 3, 7, 11, 15, 51, 87, 241, 455, 431, 1111, 1319, 1959, 0 }; + static ulong[] dim654Kuo3Init = { 1, 3, 7, 5, 21, 47, 67, 251, 91, 575, 481, 3269, 1473, 0 }; + static ulong[] dim655Kuo3Init = { 1, 3, 1, 1, 23, 5, 37, 169, 105, 803, 1765, 1823, 5081, 0 }; + static ulong[] dim656Kuo3Init = { 1, 1, 7, 9, 1, 37, 55, 175, 431, 77, 171, 3759, 1227, 0 }; + static ulong[] dim657Kuo3Init = { 1, 3, 7, 9, 3, 61, 111, 139, 87, 649, 243, 1109, 1303, 0 }; + static ulong[] dim658Kuo3Init = { 1, 3, 1, 11, 17, 25, 9, 117, 227, 821, 1219, 2567, 5851, 0 }; + static ulong[] dim659Kuo3Init = { 1, 1, 7, 1, 19, 53, 89, 57, 29, 885, 275, 2289, 4341, 0 }; + static ulong[] dim660Kuo3Init = { 1, 3, 1, 5, 5, 1, 43, 237, 235, 667, 1433, 2497, 5535, 0 }; + static ulong[] dim661Kuo3Init = { 1, 1, 1, 11, 21, 9, 29, 165, 153, 157, 1209, 817, 7819, 0 }; + static ulong[] dim662Kuo3Init = { 1, 3, 1, 5, 1, 37, 33, 9, 493, 497, 1469, 357, 5929, 0 }; + static ulong[] dim663Kuo3Init = { 1, 3, 3, 9, 25, 55, 5, 157, 397, 461, 537, 1085, 6737, 0 }; + static ulong[] dim664Kuo3Init = { 1, 3, 3, 13, 3, 61, 83, 5, 5, 243, 1745, 845, 1965, 0 }; + static ulong[] dim665Kuo3Init = { 1, 3, 1, 3, 31, 63, 3, 75, 355, 799, 417, 791, 2763, 0 }; + static ulong[] dim666Kuo3Init = { 1, 3, 3, 11, 5, 31, 99, 163, 69, 699, 809, 1651, 7249, 0 }; + static ulong[] dim667Kuo3Init = { 1, 1, 7, 3, 29, 53, 51, 185, 379, 743, 611, 963, 5631, 0 }; + static ulong[] dim668Kuo3Init = { 1, 1, 5, 11, 21, 15, 59, 75, 121, 247, 307, 2483, 2861, 0 }; + static ulong[] dim669Kuo3Init = { 1, 1, 1, 5, 21, 5, 33, 43, 225, 675, 213, 3081, 5047, 0 }; + static ulong[] dim670Kuo3Init = { 1, 3, 3, 15, 29, 45, 19, 19, 15, 605, 1531, 1305, 7725, 0 }; + static ulong[] dim671Kuo3Init = { 1, 3, 1, 5, 19, 21, 73, 131, 37, 667, 1953, 1211, 7499, 0 }; + static ulong[] dim672Kuo3Init = { 1, 3, 1, 5, 13, 3, 105, 151, 131, 965, 1953, 335, 4991, 0 }; + static ulong[] dim673Kuo3Init = { 1, 3, 1, 13, 23, 37, 81, 147, 353, 125, 141, 4017, 7543, 0 }; + static ulong[] dim674Kuo3Init = { 1, 1, 1, 7, 15, 13, 25, 107, 431, 327, 1069, 155, 1729, 0 }; + static ulong[] dim675Kuo3Init = { 1, 1, 5, 1, 19, 3, 51, 113, 349, 845, 1157, 1771, 4923, 0 }; + static ulong[] dim676Kuo3Init = { 1, 1, 3, 7, 17, 19, 47, 249, 215, 959, 659, 3989, 3719, 0 }; + static ulong[] dim677Kuo3Init = { 1, 3, 5, 5, 27, 57, 41, 29, 153, 1007, 1209, 1373, 2847, 0 }; + static ulong[] dim678Kuo3Init = { 1, 3, 5, 7, 5, 21, 23, 67, 127, 755, 211, 2517, 8161, 0 }; + static ulong[] dim679Kuo3Init = { 1, 1, 7, 15, 1, 5, 65, 197, 435, 275, 473, 1333, 3669, 0 }; + static ulong[] dim680Kuo3Init = { 1, 3, 7, 1, 17, 19, 61, 11, 425, 717, 351, 2323, 6575, 0 }; + static ulong[] dim681Kuo3Init = { 1, 1, 7, 3, 29, 13, 115, 19, 235, 371, 81, 3107, 3103, 0 }; + static ulong[] dim682Kuo3Init = { 1, 1, 3, 1, 23, 19, 57, 179, 7, 405, 217, 3159, 6675, 0 }; + static ulong[] dim683Kuo3Init = { 1, 3, 3, 3, 19, 39, 121, 195, 205, 489, 1959, 3617, 799, 0 }; + static ulong[] dim684Kuo3Init = { 1, 3, 5, 9, 19, 35, 115, 3, 17, 201, 671, 1847, 597, 0 }; + static ulong[] dim685Kuo3Init = { 1, 3, 1, 3, 7, 1, 121, 77, 163, 769, 977, 1223, 4215, 0 }; + static ulong[] dim686Kuo3Init = { 1, 1, 1, 15, 9, 13, 33, 57, 271, 733, 1699, 3083, 813, 0 }; + static ulong[] dim687Kuo3Init = { 1, 1, 7, 7, 15, 49, 101, 183, 339, 129, 1865, 2697, 3131, 0 }; + static ulong[] dim688Kuo3Init = { 1, 3, 1, 3, 9, 39, 33, 141, 459, 971, 1621, 3893, 4393, 0 }; + static ulong[] dim689Kuo3Init = { 1, 1, 3, 3, 27, 61, 53, 79, 375, 613, 663, 2325, 4707, 0 }; + static ulong[] dim690Kuo3Init = { 1, 1, 7, 1, 27, 59, 59, 179, 173, 333, 649, 1053, 555, 0 }; + static ulong[] dim691Kuo3Init = { 1, 3, 3, 13, 15, 55, 25, 91, 45, 739, 1769, 1341, 2007, 0 }; + static ulong[] dim692Kuo3Init = { 1, 1, 3, 15, 9, 59, 27, 45, 133, 941, 1037, 1559, 7145, 0 }; + static ulong[] dim693Kuo3Init = { 1, 3, 5, 1, 13, 5, 3, 167, 235, 609, 1023, 1967, 771, 0 }; + static ulong[] dim694Kuo3Init = { 1, 1, 1, 15, 19, 15, 45, 143, 309, 697, 337, 3399, 3599, 0 }; + static ulong[] dim695Kuo3Init = { 1, 1, 5, 3, 9, 1, 19, 41, 39, 1003, 997, 1357, 5849, 0 }; + static ulong[] dim696Kuo3Init = { 1, 3, 3, 7, 29, 37, 9, 165, 9, 855, 337, 2363, 2633, 0 }; + static ulong[] dim697Kuo3Init = { 1, 3, 5, 1, 23, 19, 97, 55, 411, 623, 287, 3365, 7675, 0 }; + static ulong[] dim698Kuo3Init = { 1, 3, 3, 3, 11, 1, 47, 81, 377, 85, 859, 3717, 1979, 0 }; + static ulong[] dim699Kuo3Init = { 1, 1, 3, 1, 11, 3, 125, 43, 471, 127, 341, 2943, 231, 0 }; + static ulong[] dim700Kuo3Init = { 1, 1, 5, 15, 29, 21, 101, 193, 389, 727, 1397, 2799, 4387, 0 }; + static ulong[] dim701Kuo3Init = { 1, 3, 5, 15, 27, 19, 13, 195, 105, 5, 985, 767, 4573, 0 }; + static ulong[] dim702Kuo3Init = { 1, 1, 5, 3, 13, 29, 33, 123, 107, 353, 723, 3821, 5425, 0 }; + static ulong[] dim703Kuo3Init = { 1, 3, 5, 11, 23, 11, 69, 219, 15, 735, 1015, 431, 6511, 0 }; + static ulong[] dim704Kuo3Init = { 1, 3, 1, 1, 27, 49, 79, 91, 201, 365, 255, 1309, 7165, 0 }; + static ulong[] dim705Kuo3Init = { 1, 3, 1, 13, 21, 61, 39, 111, 71, 137, 551, 3237, 6681, 0 }; + static ulong[] dim706Kuo3Init = { 1, 3, 5, 13, 19, 21, 121, 227, 381, 677, 421, 449, 5375, 0 }; + static ulong[] dim707Kuo3Init = { 1, 1, 7, 5, 1, 23, 95, 199, 509, 197, 829, 941, 2269, 0 }; + static ulong[] dim708Kuo3Init = { 1, 3, 7, 5, 21, 61, 119, 59, 97, 841, 453, 2439, 7345, 0 }; + static ulong[] dim709Kuo3Init = { 1, 1, 1, 3, 23, 21, 19, 245, 281, 841, 273, 1967, 2129, 0 }; + static ulong[] dim710Kuo3Init = { 1, 3, 3, 5, 7, 43, 19, 253, 239, 421, 461, 4023, 6981, 0 }; + static ulong[] dim711Kuo3Init = { 1, 3, 1, 11, 25, 3, 109, 107, 55, 781, 1109, 101, 889, 0 }; + static ulong[] dim712Kuo3Init = { 1, 3, 7, 13, 1, 21, 27, 3, 303, 557, 1381, 407, 1849, 0 }; + static ulong[] dim713Kuo3Init = { 1, 1, 3, 13, 3, 61, 121, 119, 453, 137, 2039, 3333, 333, 0 }; + static ulong[] dim714Kuo3Init = { 1, 3, 5, 1, 21, 9, 113, 9, 413, 301, 1795, 2827, 1837, 0 }; + static ulong[] dim715Kuo3Init = { 1, 3, 5, 15, 13, 31, 119, 107, 445, 277, 1555, 2121, 2173, 0 }; + static ulong[] dim716Kuo3Init = { 1, 1, 1, 5, 9, 5, 5, 97, 191, 949, 1603, 2181, 6879, 0 }; + static ulong[] dim717Kuo3Init = { 1, 3, 3, 9, 5, 47, 77, 43, 483, 137, 61, 1811, 5309, 0 }; + static ulong[] dim718Kuo3Init = { 1, 3, 7, 11, 25, 63, 107, 207, 23, 231, 1685, 4009, 391, 0 }; + static ulong[] dim719Kuo3Init = { 1, 3, 7, 9, 3, 35, 119, 83, 193, 269, 289, 3051, 8137, 0 }; + static ulong[] dim720Kuo3Init = { 1, 3, 3, 11, 25, 25, 17, 243, 195, 503, 1797, 1913, 749, 0 }; + static ulong[] dim721Kuo3Init = { 1, 3, 1, 13, 5, 35, 101, 57, 185, 881, 2005, 3493, 2715, 0 }; + static ulong[] dim722Kuo3Init = { 1, 3, 1, 11, 25, 51, 113, 177, 175, 855, 1727, 1901, 8181, 0 }; + static ulong[] dim723Kuo3Init = { 1, 1, 3, 9, 9, 63, 109, 233, 205, 357, 499, 3367, 1189, 0 }; + static ulong[] dim724Kuo3Init = { 1, 3, 1, 15, 17, 11, 35, 135, 501, 319, 1465, 2095, 5269, 0 }; + static ulong[] dim725Kuo3Init = { 1, 1, 3, 9, 1, 27, 99, 201, 67, 269, 135, 3891, 4067, 0 }; + static ulong[] dim726Kuo3Init = { 1, 1, 1, 9, 15, 37, 83, 135, 3, 645, 499, 2597, 2705, 0 }; + static ulong[] dim727Kuo3Init = { 1, 3, 1, 7, 17, 33, 89, 51, 295, 809, 743, 27, 2599, 0 }; + static ulong[] dim728Kuo3Init = { 1, 1, 7, 1, 5, 55, 11, 97, 177, 515, 1651, 1183, 5803, 0 }; + static ulong[] dim729Kuo3Init = { 1, 1, 3, 11, 21, 3, 39, 249, 55, 891, 1681, 709, 7833, 0 }; + static ulong[] dim730Kuo3Init = { 1, 3, 5, 13, 11, 21, 81, 21, 99, 223, 355, 2015, 7195, 0 }; + static ulong[] dim731Kuo3Init = { 1, 3, 7, 11, 25, 23, 9, 131, 417, 583, 1927, 277, 2923, 0 }; + static ulong[] dim732Kuo3Init = { 1, 1, 5, 5, 1, 43, 35, 87, 471, 499, 1411, 2867, 2477, 0 }; + static ulong[] dim733Kuo3Init = { 1, 1, 5, 9, 25, 43, 83, 103, 183, 527, 483, 935, 7097, 0 }; + static ulong[] dim734Kuo3Init = { 1, 1, 5, 7, 31, 13, 49, 169, 135, 885, 1367, 2627, 5917, 0 }; + static ulong[] dim735Kuo3Init = { 1, 3, 7, 5, 1, 39, 97, 167, 95, 745, 1067, 805, 2885, 0 }; + static ulong[] dim736Kuo3Init = { 1, 3, 7, 15, 31, 41, 1, 147, 15, 795, 323, 309, 5075, 0 }; + static ulong[] dim737Kuo3Init = { 1, 3, 7, 5, 23, 3, 65, 143, 183, 671, 993, 547, 5971, 0 }; + static ulong[] dim738Kuo3Init = { 1, 3, 7, 1, 21, 59, 29, 45, 367, 363, 1707, 541, 7045, 0 }; + static ulong[] dim739Kuo3Init = { 1, 1, 7, 15, 11, 25, 77, 33, 409, 495, 1713, 1479, 2857, 0 }; + static ulong[] dim740Kuo3Init = { 1, 1, 3, 1, 11, 59, 113, 217, 313, 79, 379, 627, 3917, 0 }; + static ulong[] dim741Kuo3Init = { 1, 1, 1, 15, 31, 61, 73, 211, 419, 965, 1817, 3965, 1425, 0 }; + static ulong[] dim742Kuo3Init = { 1, 1, 7, 13, 9, 9, 61, 119, 223, 387, 595, 191, 1723, 0 }; + static ulong[] dim743Kuo3Init = { 1, 3, 5, 3, 25, 49, 83, 175, 329, 1003, 729, 1399, 6553, 0 }; + static ulong[] dim744Kuo3Init = { 1, 1, 5, 9, 5, 37, 31, 43, 365, 403, 1485, 1621, 3753, 0 }; + static ulong[] dim745Kuo3Init = { 1, 3, 5, 7, 17, 5, 125, 219, 311, 1, 639, 1939, 4367, 0 }; + static ulong[] dim746Kuo3Init = { 1, 3, 5, 3, 21, 63, 119, 31, 151, 325, 1063, 2477, 1223, 0 }; + static ulong[] dim747Kuo3Init = { 1, 1, 5, 13, 15, 23, 1, 141, 105, 21, 747, 161, 3555, 0 }; + static ulong[] dim748Kuo3Init = { 1, 3, 7, 1, 31, 21, 11, 27, 267, 205, 1569, 765, 1357, 0 }; + static ulong[] dim749Kuo3Init = { 1, 1, 3, 9, 23, 59, 93, 51, 81, 367, 1545, 1161, 3481, 0 }; + static ulong[] dim750Kuo3Init = { 1, 3, 7, 11, 15, 51, 43, 205, 237, 617, 1075, 1051, 5285, 0 }; + static ulong[] dim751Kuo3Init = { 1, 3, 7, 3, 11, 5, 95, 203, 495, 661, 1119, 1095, 3391, 0 }; + static ulong[] dim752Kuo3Init = { 1, 3, 3, 1, 25, 39, 59, 159, 273, 101, 1887, 417, 3423, 0 }; + static ulong[] dim753Kuo3Init = { 1, 3, 5, 13, 23, 45, 13, 87, 139, 313, 1527, 3739, 7009, 0 }; + static ulong[] dim754Kuo3Init = { 1, 1, 5, 1, 23, 43, 127, 149, 63, 823, 1075, 3123, 3079, 0 }; + static ulong[] dim755Kuo3Init = { 1, 1, 7, 3, 11, 1, 29, 127, 313, 971, 1363, 1765, 6439, 0 }; + static ulong[] dim756Kuo3Init = { 1, 1, 3, 13, 1, 19, 61, 125, 345, 51, 273, 2783, 5255, 0 }; + static ulong[] dim757Kuo3Init = { 1, 1, 1, 7, 29, 33, 21, 239, 351, 481, 795, 2865, 2235, 0 }; + static ulong[] dim758Kuo3Init = { 1, 3, 3, 3, 19, 31, 41, 125, 327, 169, 837, 753, 191, 0 }; + static ulong[] dim759Kuo3Init = { 1, 3, 7, 15, 5, 15, 5, 109, 333, 127, 2021, 441, 6307, 0 }; + static ulong[] dim760Kuo3Init = { 1, 3, 7, 9, 23, 39, 79, 235, 27, 573, 1989, 1401, 7597, 0 }; + static ulong[] dim761Kuo3Init = { 1, 1, 7, 3, 23, 29, 119, 53, 105, 609, 1139, 321, 1111, 0 }; + static ulong[] dim762Kuo3Init = { 1, 1, 7, 13, 13, 43, 3, 211, 389, 563, 1047, 1373, 4669, 0 }; + static ulong[] dim763Kuo3Init = { 1, 3, 3, 1, 9, 7, 1, 135, 455, 539, 1681, 1851, 4585, 0 }; + static ulong[] dim764Kuo3Init = { 1, 3, 1, 13, 19, 45, 65, 109, 391, 563, 753, 2405, 2623, 0 }; + static ulong[] dim765Kuo3Init = { 1, 3, 1, 13, 31, 41, 29, 153, 507, 559, 877, 125, 4827, 0 }; + static ulong[] dim766Kuo3Init = { 1, 1, 7, 3, 15, 53, 39, 1, 143, 351, 505, 1213, 4829, 0 }; + static ulong[] dim767Kuo3Init = { 1, 1, 5, 5, 27, 49, 39, 101, 501, 239, 1233, 1695, 6929, 0 }; + static ulong[] dim768Kuo3Init = { 1, 1, 5, 9, 13, 29, 103, 185, 343, 943, 1709, 801, 1227, 0 }; + static ulong[] dim769Kuo3Init = { 1, 1, 1, 3, 3, 1, 63, 23, 199, 53, 1629, 325, 7609, 0 }; + static ulong[] dim770Kuo3Init = { 1, 3, 7, 1, 11, 47, 61, 171, 71, 493, 2035, 869, 5925, 0 }; + static ulong[] dim771Kuo3Init = { 1, 1, 7, 7, 5, 3, 95, 163, 89, 395, 1033, 2051, 5589, 0 }; + static ulong[] dim772Kuo3Init = { 1, 3, 5, 9, 3, 21, 29, 143, 333, 805, 267, 4077, 383, 0 }; + static ulong[] dim773Kuo3Init = { 1, 1, 3, 13, 9, 17, 87, 163, 107, 1011, 1099, 3395, 987, 0 }; + static ulong[] dim774Kuo3Init = { 1, 3, 1, 1, 5, 51, 71, 249, 441, 513, 791, 1831, 2757, 0 }; + static ulong[] dim775Kuo3Init = { 1, 1, 3, 13, 23, 7, 101, 211, 289, 1001, 1623, 3239, 1685, 0 }; + static ulong[] dim776Kuo3Init = { 1, 1, 5, 15, 31, 53, 91, 245, 143, 237, 557, 3099, 3737, 0 }; + static ulong[] dim777Kuo3Init = { 1, 3, 1, 1, 5, 27, 51, 173, 321, 85, 1385, 9, 1887, 0 }; + static ulong[] dim778Kuo3Init = { 1, 3, 1, 15, 11, 17, 49, 97, 121, 189, 2031, 565, 7513, 0 }; + static ulong[] dim779Kuo3Init = { 1, 1, 5, 5, 1, 3, 55, 157, 27, 783, 1543, 2645, 1079, 0 }; + static ulong[] dim780Kuo3Init = { 1, 1, 5, 11, 27, 9, 83, 155, 17, 147, 1561, 3213, 4483, 0 }; + static ulong[] dim781Kuo3Init = { 1, 3, 5, 15, 23, 63, 127, 97, 459, 869, 671, 3287, 995, 0 }; + static ulong[] dim782Kuo3Init = { 1, 3, 3, 1, 5, 1, 89, 229, 269, 493, 709, 2719, 4803, 0 }; + static ulong[] dim783Kuo3Init = { 1, 1, 3, 3, 27, 5, 85, 55, 491, 781, 711, 3193, 2051, 0 }; + static ulong[] dim784Kuo3Init = { 1, 1, 5, 13, 21, 9, 31, 107, 381, 613, 991, 2289, 325, 0 }; + static ulong[] dim785Kuo3Init = { 1, 3, 7, 11, 11, 47, 115, 103, 101, 945, 1993, 1345, 2031, 0 }; + static ulong[] dim786Kuo3Init = { 1, 3, 7, 11, 27, 59, 123, 73, 85, 975, 397, 2619, 2095, 0 }; + static ulong[] dim787Kuo3Init = { 1, 1, 1, 13, 19, 31, 87, 45, 39, 43, 1041, 2015, 5859, 0 }; + static ulong[] dim788Kuo3Init = { 1, 1, 3, 15, 5, 19, 47, 193, 293, 961, 113, 3013, 889, 0 }; + static ulong[] dim789Kuo3Init = { 1, 1, 1, 3, 31, 61, 61, 209, 493, 785, 1825, 3779, 8095, 0 }; + static ulong[] dim790Kuo3Init = { 1, 1, 3, 9, 17, 51, 103, 255, 133, 165, 281, 3945, 2779, 0 }; + static ulong[] dim791Kuo3Init = { 1, 1, 7, 3, 9, 33, 105, 29, 449, 231, 1393, 1071, 5043, 0 }; + static ulong[] dim792Kuo3Init = { 1, 1, 7, 5, 29, 35, 115, 1, 467, 969, 343, 2291, 5099, 0 }; + static ulong[] dim793Kuo3Init = { 1, 1, 3, 5, 13, 21, 99, 151, 13, 861, 189, 1709, 4943, 0 }; + static ulong[] dim794Kuo3Init = { 1, 1, 7, 15, 5, 41, 53, 89, 235, 515, 1819, 3907, 4861, 0 }; + static ulong[] dim795Kuo3Init = { 1, 3, 5, 1, 7, 15, 75, 65, 247, 581, 853, 445, 7623, 0 }; + static ulong[] dim796Kuo3Init = { 1, 1, 3, 5, 25, 29, 27, 73, 359, 729, 1991, 1075, 8107, 0 }; + static ulong[] dim797Kuo3Init = { 1, 1, 3, 1, 5, 35, 83, 119, 385, 657, 1085, 2707, 4403, 0 }; + static ulong[] dim798Kuo3Init = { 1, 3, 5, 5, 25, 55, 51, 205, 257, 887, 827, 2795, 925, 0 }; + static ulong[] dim799Kuo3Init = { 1, 1, 3, 1, 5, 29, 113, 195, 439, 241, 127, 2783, 2577, 0 }; + static ulong[] dim800Kuo3Init = { 1, 3, 1, 11, 15, 47, 7, 149, 81, 897, 235, 3935, 6981, 0 }; + static ulong[] dim801Kuo3Init = { 1, 3, 3, 1, 27, 5, 69, 125, 377, 829, 1549, 3025, 2319, 0 }; + static ulong[] dim802Kuo3Init = { 1, 1, 7, 15, 15, 19, 3, 205, 291, 209, 1817, 2439, 1001, 0 }; + static ulong[] dim803Kuo3Init = { 1, 1, 7, 9, 21, 7, 101, 17, 13, 615, 137, 1821, 1387, 0 }; + static ulong[] dim804Kuo3Init = { 1, 3, 3, 11, 21, 27, 61, 133, 183, 699, 245, 527, 471, 0 }; + static ulong[] dim805Kuo3Init = { 1, 3, 3, 13, 5, 25, 111, 69, 417, 271, 1545, 2729, 475, 0 }; + static ulong[] dim806Kuo3Init = { 1, 3, 5, 15, 11, 47, 93, 93, 311, 775, 789, 1163, 1563, 0 }; + static ulong[] dim807Kuo3Init = { 1, 3, 5, 1, 13, 63, 27, 113, 449, 971, 1021, 73, 1229, 0 }; + static ulong[] dim808Kuo3Init = { 1, 3, 3, 15, 17, 37, 103, 13, 91, 823, 1767, 1295, 6941, 0 }; + static ulong[] dim809Kuo3Init = { 1, 1, 3, 9, 15, 59, 125, 91, 195, 409, 65, 2873, 1921, 0 }; + static ulong[] dim810Kuo3Init = { 1, 3, 1, 7, 17, 31, 21, 251, 145, 385, 1385, 1505, 5735, 0 }; + static ulong[] dim811Kuo3Init = { 1, 3, 7, 11, 17, 19, 85, 85, 81, 583, 889, 669, 5187, 0 }; + static ulong[] dim812Kuo3Init = { 1, 1, 5, 9, 23, 53, 97, 217, 129, 517, 271, 2967, 3937, 0 }; + static ulong[] dim813Kuo3Init = { 1, 1, 1, 13, 3, 45, 49, 193, 35, 671, 1039, 2841, 4547, 0 }; + static ulong[] dim814Kuo3Init = { 1, 3, 1, 15, 21, 29, 5, 91, 23, 247, 1701, 1585, 1493, 0 }; + static ulong[] dim815Kuo3Init = { 1, 3, 3, 11, 15, 31, 21, 165, 153, 607, 221, 2781, 6159, 0 }; + static ulong[] dim816Kuo3Init = { 1, 3, 7, 15, 15, 27, 107, 25, 457, 995, 849, 877, 407, 0 }; + static ulong[] dim817Kuo3Init = { 1, 3, 1, 15, 7, 17, 37, 31, 203, 585, 369, 609, 2509, 0 }; + static ulong[] dim818Kuo3Init = { 1, 3, 1, 11, 17, 5, 17, 71, 453, 171, 1317, 1985, 5817, 0 }; + static ulong[] dim819Kuo3Init = { 1, 1, 5, 5, 23, 39, 123, 179, 49, 19, 1337, 1051, 5289, 0 }; + static ulong[] dim820Kuo3Init = { 1, 3, 1, 13, 17, 43, 47, 139, 21, 851, 1253, 1939, 299, 0 }; + static ulong[] dim821Kuo3Init = { 1, 1, 7, 1, 3, 35, 57, 115, 481, 653, 1975, 1319, 5225, 0 }; + static ulong[] dim822Kuo3Init = { 1, 3, 7, 15, 5, 13, 3, 249, 21, 791, 1349, 1961, 6975, 0 }; + static ulong[] dim823Kuo3Init = { 1, 1, 5, 11, 17, 3, 97, 103, 201, 313, 939, 693, 5397, 0 }; + static ulong[] dim824Kuo3Init = { 1, 1, 7, 9, 29, 59, 35, 91, 135, 19, 1505, 1715, 3335, 0 }; + static ulong[] dim825Kuo3Init = { 1, 3, 5, 1, 17, 53, 59, 217, 1, 305, 1257, 3773, 3509, 0 }; + static ulong[] dim826Kuo3Init = { 1, 3, 7, 7, 5, 29, 47, 245, 487, 525, 1409, 245, 6427, 0 }; + static ulong[] dim827Kuo3Init = { 1, 3, 5, 15, 25, 39, 49, 153, 461, 1003, 1527, 2883, 3499, 0 }; + static ulong[] dim828Kuo3Init = { 1, 1, 7, 13, 23, 11, 15, 163, 9, 77, 1853, 1679, 1023, 0 }; + static ulong[] dim829Kuo3Init = { 1, 3, 7, 13, 3, 55, 101, 229, 327, 537, 79, 3947, 6259, 0 }; + static ulong[] dim830Kuo3Init = { 1, 3, 7, 5, 9, 39, 3, 151, 439, 181, 1473, 3613, 7425, 0 }; + static ulong[] dim831Kuo3Init = { 1, 3, 7, 11, 21, 5, 53, 11, 39, 455, 1131, 393, 1525, 0 }; + static ulong[] dim832Kuo3Init = { 1, 1, 1, 7, 5, 45, 49, 229, 173, 567, 1285, 2317, 2207, 0 }; + static ulong[] dim833Kuo3Init = { 1, 1, 1, 7, 5, 33, 53, 241, 477, 161, 1607, 1253, 4497, 0 }; + static ulong[] dim834Kuo3Init = { 1, 1, 7, 15, 11, 3, 107, 187, 249, 529, 905, 2883, 7777, 0 }; + static ulong[] dim835Kuo3Init = { 1, 1, 5, 7, 17, 13, 123, 7, 449, 627, 1679, 569, 4145, 0 }; + static ulong[] dim836Kuo3Init = { 1, 1, 1, 1, 3, 29, 57, 219, 209, 51, 1475, 2989, 7373, 0 }; + static ulong[] dim837Kuo3Init = { 1, 3, 3, 5, 19, 33, 95, 241, 257, 465, 1305, 189, 269, 0 }; + static ulong[] dim838Kuo3Init = { 1, 1, 3, 1, 13, 11, 67, 53, 157, 693, 1583, 739, 3827, 0 }; + static ulong[] dim839Kuo3Init = { 1, 1, 3, 9, 17, 9, 5, 7, 421, 425, 1851, 3847, 5147, 0 }; + static ulong[] dim840Kuo3Init = { 1, 1, 3, 3, 23, 47, 123, 215, 11, 643, 1543, 1859, 4073, 0 }; + static ulong[] dim841Kuo3Init = { 1, 1, 1, 11, 5, 35, 79, 55, 225, 773, 1717, 2891, 563, 0 }; + static ulong[] dim842Kuo3Init = { 1, 1, 1, 15, 5, 17, 115, 3, 107, 33, 1897, 3677, 4313, 0 }; + static ulong[] dim843Kuo3Init = { 1, 1, 5, 7, 5, 57, 75, 65, 177, 269, 733, 3837, 1211, 0 }; + static ulong[] dim844Kuo3Init = { 1, 1, 5, 15, 25, 45, 125, 159, 501, 17, 693, 1083, 1801, 0 }; + static ulong[] dim845Kuo3Init = { 1, 3, 5, 3, 15, 17, 17, 159, 421, 449, 83, 1367, 7719, 0 }; + static ulong[] dim846Kuo3Init = { 1, 3, 7, 3, 7, 31, 121, 43, 491, 501, 335, 2731, 1959, 0 }; + static ulong[] dim847Kuo3Init = { 1, 1, 1, 11, 7, 1, 43, 187, 437, 113, 1205, 1255, 1319, 0 }; + static ulong[] dim848Kuo3Init = { 1, 1, 5, 15, 15, 49, 103, 139, 187, 697, 907, 1229, 3205, 0 }; + static ulong[] dim849Kuo3Init = { 1, 1, 5, 13, 9, 19, 25, 89, 345, 229, 1325, 859, 527, 0 }; + static ulong[] dim850Kuo3Init = { 1, 1, 1, 3, 3, 63, 105, 11, 407, 131, 679, 3069, 4153, 0 }; + static ulong[] dim851Kuo3Init = { 1, 1, 3, 11, 21, 27, 113, 59, 409, 845, 309, 2639, 129, 0 }; + static ulong[] dim852Kuo3Init = { 1, 1, 5, 15, 21, 47, 55, 237, 201, 103, 331, 3531, 4965, 0 }; + static ulong[] dim853Kuo3Init = { 1, 1, 5, 11, 9, 11, 85, 49, 209, 333, 1993, 511, 7347, 0 }; + static ulong[] dim854Kuo3Init = { 1, 1, 5, 13, 25, 49, 109, 241, 297, 677, 313, 657, 4503, 0 }; + static ulong[] dim855Kuo3Init = { 1, 1, 1, 15, 23, 57, 61, 117, 461, 559, 837, 2781, 709, 0 }; + static ulong[] dim856Kuo3Init = { 1, 1, 3, 3, 31, 13, 109, 167, 389, 1021, 1437, 31, 811, 0 }; + static ulong[] dim857Kuo3Init = { 1, 1, 1, 9, 21, 17, 19, 61, 241, 445, 1935, 3161, 4061, 0 }; + static ulong[] dim858Kuo3Init = { 1, 3, 5, 5, 17, 5, 59, 117, 241, 913, 1315, 1597, 713, 0 }; + static ulong[] dim859Kuo3Init = { 1, 3, 1, 15, 5, 41, 91, 191, 43, 49, 1491, 4051, 2317, 0 }; + static ulong[] dim860Kuo3Init = { 1, 1, 1, 3, 13, 33, 53, 39, 341, 341, 617, 2627, 421, 0 }; + static ulong[] dim861Kuo3Init = { 1, 3, 3, 15, 23, 25, 47, 251, 405, 659, 721, 229, 2269, 0 }; + static ulong[] dim862Kuo3Init = { 1, 1, 3, 3, 25, 19, 123, 53, 59, 805, 2033, 1693, 6223, 0 }; + static ulong[] dim863Kuo3Init = { 1, 1, 1, 3, 13, 45, 67, 67, 199, 925, 145, 775, 7923, 0 }; + static ulong[] dim864Kuo3Init = { 1, 1, 5, 7, 17, 23, 49, 37, 185, 253, 1743, 2771, 6899, 0 }; + static ulong[] dim865Kuo3Init = { 1, 3, 5, 5, 15, 53, 75, 185, 17, 379, 1091, 4029, 5399, 0 }; + static ulong[] dim866Kuo3Init = { 1, 1, 1, 9, 13, 37, 101, 33, 499, 723, 57, 467, 7227, 0 }; + static ulong[] dim867Kuo3Init = { 1, 1, 7, 1, 21, 49, 17, 49, 417, 895, 1099, 3199, 7059, 0 }; + static ulong[] dim868Kuo3Init = { 1, 1, 5, 13, 27, 35, 49, 35, 213, 799, 197, 3599, 4135, 0 }; + static ulong[] dim869Kuo3Init = { 1, 3, 5, 3, 31, 33, 61, 127, 87, 343, 845, 1699, 3897, 0 }; + static ulong[] dim870Kuo3Init = { 1, 3, 1, 11, 7, 59, 19, 161, 119, 377, 1637, 2025, 849, 0 }; + static ulong[] dim871Kuo3Init = { 1, 1, 3, 3, 3, 51, 3, 67, 77, 357, 295, 2383, 7423, 0 }; + static ulong[] dim872Kuo3Init = { 1, 3, 1, 3, 23, 25, 67, 29, 433, 49, 901, 1641, 3021, 0 }; + static ulong[] dim873Kuo3Init = { 1, 3, 7, 3, 25, 59, 15, 181, 193, 809, 1089, 423, 1629, 0 }; + static ulong[] dim874Kuo3Init = { 1, 3, 5, 1, 3, 19, 53, 45, 277, 411, 455, 9, 3651, 0 }; + static ulong[] dim875Kuo3Init = { 1, 3, 7, 15, 13, 33, 37, 15, 489, 275, 1113, 3371, 3915, 0 }; + static ulong[] dim876Kuo3Init = { 1, 1, 5, 11, 3, 3, 97, 47, 471, 713, 1975, 1679, 7901, 0 }; + static ulong[] dim877Kuo3Init = { 1, 1, 3, 15, 31, 47, 13, 33, 111, 607, 85, 4049, 2937, 0 }; + static ulong[] dim878Kuo3Init = { 1, 1, 5, 1, 7, 61, 17, 179, 301, 245, 67, 2823, 4121, 0 }; + static ulong[] dim879Kuo3Init = { 1, 3, 7, 15, 7, 25, 97, 73, 19, 899, 1357, 2041, 6493, 0 }; + static ulong[] dim880Kuo3Init = { 1, 1, 1, 3, 3, 63, 117, 231, 125, 527, 1795, 1807, 7331, 0 }; + static ulong[] dim881Kuo3Init = { 1, 1, 5, 11, 17, 35, 61, 161, 415, 687, 1015, 1239, 6925, 0 }; + static ulong[] dim882Kuo3Init = { 1, 3, 3, 5, 15, 19, 1, 5, 209, 545, 1341, 4019, 6177, 0 }; + static ulong[] dim883Kuo3Init = { 1, 3, 5, 15, 13, 3, 7, 39, 63, 727, 1033, 2551, 449, 0 }; + static ulong[] dim884Kuo3Init = { 1, 1, 1, 5, 11, 35, 39, 143, 361, 659, 1407, 2399, 6421, 0 }; + static ulong[] dim885Kuo3Init = { 1, 1, 7, 13, 3, 23, 21, 161, 153, 595, 1847, 1339, 1887, 0 }; + static ulong[] dim886Kuo3Init = { 1, 3, 3, 9, 3, 43, 75, 45, 433, 811, 1045, 2773, 2415, 0 }; + static ulong[] dim887Kuo3Init = { 1, 1, 3, 5, 23, 29, 73, 167, 211, 403, 539, 13, 4433, 0 }; + static ulong[] dim888Kuo3Init = { 1, 3, 3, 13, 19, 25, 113, 181, 343, 349, 931, 115, 5687, 0 }; + static ulong[] dim889Kuo3Init = { 1, 3, 1, 11, 25, 39, 23, 91, 359, 221, 37, 575, 3035, 0 }; + static ulong[] dim890Kuo3Init = { 1, 1, 7, 1, 19, 61, 99, 81, 167, 53, 1493, 2623, 5797, 0 }; + static ulong[] dim891Kuo3Init = { 1, 1, 3, 5, 13, 13, 105, 53, 449, 1003, 1405, 1403, 2557, 0 }; + static ulong[] dim892Kuo3Init = { 1, 1, 3, 15, 1, 37, 51, 69, 13, 5, 1865, 3585, 3409, 0 }; + static ulong[] dim893Kuo3Init = { 1, 1, 7, 13, 15, 31, 61, 53, 439, 665, 57, 445, 435, 0 }; + static ulong[] dim894Kuo3Init = { 1, 3, 1, 3, 1, 27, 1, 155, 65, 191, 449, 2185, 1787, 0 }; + static ulong[] dim895Kuo3Init = { 1, 1, 3, 11, 13, 59, 15, 43, 435, 477, 823, 717, 299, 0 }; + static ulong[] dim896Kuo3Init = { 1, 1, 3, 1, 23, 9, 85, 155, 127, 543, 1081, 221, 7357, 0 }; + static ulong[] dim897Kuo3Init = { 1, 3, 3, 1, 7, 35, 77, 9, 79, 283, 449, 2729, 4193, 0 }; + static ulong[] dim898Kuo3Init = { 1, 1, 7, 1, 9, 15, 97, 99, 363, 513, 1063, 3051, 1529, 0 }; + static ulong[] dim899Kuo3Init = { 1, 1, 5, 3, 1, 17, 101, 19, 425, 377, 1369, 3071, 6877, 0 }; + static ulong[] dim900Kuo3Init = { 1, 1, 5, 1, 23, 63, 11, 7, 29, 717, 963, 2205, 7487, 0 }; + static ulong[] dim901Kuo3Init = { 1, 3, 1, 13, 1, 15, 43, 151, 59, 315, 691, 2765, 7723, 0 }; + static ulong[] dim902Kuo3Init = { 1, 3, 1, 5, 5, 31, 17, 81, 235, 419, 123, 2983, 1797, 0 }; + static ulong[] dim903Kuo3Init = { 1, 1, 1, 11, 29, 17, 123, 115, 91, 531, 1393, 3537, 6387, 0 }; + static ulong[] dim904Kuo3Init = { 1, 3, 5, 11, 31, 5, 107, 61, 463, 507, 1937, 4075, 4727, 0 }; + static ulong[] dim905Kuo3Init = { 1, 3, 7, 1, 9, 27, 23, 97, 125, 511, 239, 1031, 153, 0 }; + static ulong[] dim906Kuo3Init = { 1, 3, 5, 9, 13, 55, 53, 195, 265, 217, 357, 567, 1613, 0 }; + static ulong[] dim907Kuo3Init = { 1, 1, 5, 15, 5, 51, 51, 235, 63, 393, 1915, 2495, 7067, 0 }; + static ulong[] dim908Kuo3Init = { 1, 1, 7, 1, 15, 35, 97, 65, 115, 819, 1419, 2313, 6029, 0 }; + static ulong[] dim909Kuo3Init = { 1, 1, 5, 13, 11, 35, 45, 149, 45, 617, 2001, 1629, 5611, 0 }; + static ulong[] dim910Kuo3Init = { 1, 3, 5, 11, 15, 17, 39, 155, 143, 473, 1269, 2537, 2571, 0 }; + static ulong[] dim911Kuo3Init = { 1, 1, 3, 3, 1, 7, 57, 227, 151, 731, 1871, 245, 7605, 0 }; + static ulong[] dim912Kuo3Init = { 1, 1, 1, 13, 21, 1, 19, 189, 299, 483, 513, 2235, 3079, 0 }; + static ulong[] dim913Kuo3Init = { 1, 1, 5, 15, 13, 53, 91, 55, 339, 161, 273, 2759, 7251, 0 }; + static ulong[] dim914Kuo3Init = { 1, 3, 1, 1, 17, 47, 29, 107, 371, 437, 715, 739, 2195, 0 }; + static ulong[] dim915Kuo3Init = { 1, 3, 5, 11, 27, 1, 35, 105, 443, 623, 1401, 2683, 4327, 0 }; + static ulong[] dim916Kuo3Init = { 1, 1, 5, 7, 13, 23, 101, 235, 369, 951, 1983, 1021, 7835, 0 }; + static ulong[] dim917Kuo3Init = { 1, 1, 1, 5, 21, 57, 45, 67, 89, 209, 1105, 2161, 2245, 0 }; + static ulong[] dim918Kuo3Init = { 1, 1, 7, 15, 7, 33, 69, 129, 181, 231, 961, 1621, 7763, 0 }; + static ulong[] dim919Kuo3Init = { 1, 3, 1, 5, 1, 31, 105, 123, 413, 989, 1311, 199, 5175, 0 }; + static ulong[] dim920Kuo3Init = { 1, 3, 5, 13, 15, 9, 123, 215, 463, 197, 537, 531, 2331, 0 }; + static ulong[] dim921Kuo3Init = { 1, 1, 3, 13, 13, 45, 61, 189, 91, 445, 1719, 3335, 5269, 0 }; + static ulong[] dim922Kuo3Init = { 1, 3, 1, 11, 19, 41, 65, 143, 199, 177, 1695, 3647, 7169, 0 }; + static ulong[] dim923Kuo3Init = { 1, 1, 3, 13, 13, 25, 37, 89, 175, 551, 1535, 1401, 1823, 0 }; + static ulong[] dim924Kuo3Init = { 1, 3, 3, 1, 21, 15, 31, 101, 329, 907, 731, 1493, 451, 0 }; + static ulong[] dim925Kuo3Init = { 1, 1, 3, 9, 5, 61, 85, 247, 289, 547, 1031, 3567, 1769, 0 }; + static ulong[] dim926Kuo3Init = { 1, 3, 1, 7, 25, 35, 99, 43, 25, 855, 1451, 617, 2615, 0 }; + static ulong[] dim927Kuo3Init = { 1, 1, 1, 7, 25, 9, 77, 39, 127, 327, 1501, 57, 1485, 0 }; + static ulong[] dim928Kuo3Init = { 1, 3, 5, 5, 9, 13, 13, 239, 125, 473, 785, 2853, 5165, 0 }; + static ulong[] dim929Kuo3Init = { 1, 1, 1, 3, 27, 43, 117, 63, 175, 487, 1505, 157, 6043, 0 }; + static ulong[] dim930Kuo3Init = { 1, 1, 5, 5, 25, 43, 97, 231, 389, 191, 1795, 2659, 7409, 0 }; + static ulong[] dim931Kuo3Init = { 1, 1, 7, 7, 11, 25, 47, 131, 363, 311, 523, 2773, 8015, 0 }; + static ulong[] dim932Kuo3Init = { 1, 1, 5, 11, 25, 61, 123, 83, 265, 995, 613, 1893, 6341, 0 }; + static ulong[] dim933Kuo3Init = { 1, 1, 3, 3, 27, 45, 41, 143, 173, 1009, 1963, 4009, 3675, 0 }; + static ulong[] dim934Kuo3Init = { 1, 3, 3, 9, 5, 11, 95, 253, 415, 307, 501, 3117, 4621, 0 }; + static ulong[] dim935Kuo3Init = { 1, 3, 5, 1, 31, 41, 95, 39, 473, 565, 1389, 4049, 5673, 0 }; + static ulong[] dim936Kuo3Init = { 1, 1, 3, 11, 3, 13, 87, 101, 413, 769, 1223, 549, 4967, 0 }; + static ulong[] dim937Kuo3Init = { 1, 3, 1, 3, 13, 41, 29, 187, 491, 197, 1685, 3859, 3799, 0 }; + static ulong[] dim938Kuo3Init = { 1, 3, 1, 3, 17, 55, 91, 131, 429, 899, 29, 1193, 7323, 0 }; + static ulong[] dim939Kuo3Init = { 1, 1, 3, 1, 11, 17, 107, 113, 71, 185, 1057, 897, 249, 0 }; + static ulong[] dim940Kuo3Init = { 1, 1, 3, 5, 29, 27, 87, 33, 273, 405, 547, 763, 2195, 0 }; + static ulong[] dim941Kuo3Init = { 1, 3, 1, 11, 7, 43, 39, 103, 475, 515, 1105, 767, 3881, 0 }; + static ulong[] dim942Kuo3Init = { 1, 3, 3, 1, 13, 21, 93, 141, 407, 1001, 1939, 2747, 6479, 0 }; + static ulong[] dim943Kuo3Init = { 1, 3, 1, 15, 1, 31, 15, 69, 313, 547, 987, 3569, 2795, 0 }; + static ulong[] dim944Kuo3Init = { 1, 3, 5, 7, 1, 17, 105, 113, 253, 453, 1219, 2769, 197, 0 }; + static ulong[] dim945Kuo3Init = { 1, 3, 7, 7, 29, 55, 77, 169, 227, 471, 1385, 2689, 7995, 0 }; + static ulong[] dim946Kuo3Init = { 1, 3, 7, 15, 7, 15, 113, 133, 205, 271, 263, 3141, 5007, 0 }; + static ulong[] dim947Kuo3Init = { 1, 1, 5, 7, 7, 57, 121, 209, 319, 733, 1689, 2817, 6621, 0 }; + static ulong[] dim948Kuo3Init = { 1, 3, 7, 9, 23, 37, 101, 229, 269, 429, 157, 515, 6975, 0 }; + static ulong[] dim949Kuo3Init = { 1, 1, 7, 7, 23, 31, 83, 237, 299, 333, 959, 1467, 419, 0 }; + static ulong[] dim950Kuo3Init = { 1, 3, 7, 3, 23, 45, 17, 33, 293, 679, 625, 3651, 4205, 0 }; + static ulong[] dim951Kuo3Init = { 1, 3, 1, 13, 17, 19, 87, 237, 219, 119, 841, 1923, 8141, 0 }; + static ulong[] dim952Kuo3Init = { 1, 1, 1, 15, 15, 49, 21, 189, 287, 759, 695, 913, 5167, 0 }; + static ulong[] dim953Kuo3Init = { 1, 1, 3, 15, 1, 9, 125, 5, 67, 603, 1691, 2863, 1299, 0 }; + static ulong[] dim954Kuo3Init = { 1, 3, 7, 3, 5, 35, 105, 27, 51, 889, 1469, 3203, 6997, 0 }; + static ulong[] dim955Kuo3Init = { 1, 3, 5, 7, 1, 53, 77, 1, 313, 475, 1515, 2233, 399, 0 }; + static ulong[] dim956Kuo3Init = { 1, 3, 5, 7, 3, 31, 43, 17, 425, 673, 1817, 1939, 8027, 0 }; + static ulong[] dim957Kuo3Init = { 1, 1, 5, 5, 31, 31, 119, 179, 157, 635, 1, 315, 1179, 0 }; + static ulong[] dim958Kuo3Init = { 1, 1, 5, 5, 1, 7, 25, 15, 311, 489, 829, 1929, 623, 0 }; + static ulong[] dim959Kuo3Init = { 1, 1, 5, 11, 1, 17, 43, 205, 347, 713, 2029, 977, 4345, 0 }; + static ulong[] dim960Kuo3Init = { 1, 1, 3, 9, 17, 3, 109, 253, 427, 333, 203, 1609, 1851, 0 }; + static ulong[] dim961Kuo3Init = { 1, 3, 1, 9, 21, 55, 107, 203, 483, 869, 1417, 587, 3965, 0 }; + static ulong[] dim962Kuo3Init = { 1, 3, 3, 13, 27, 21, 103, 109, 313, 797, 723, 683, 349, 0 }; + static ulong[] dim963Kuo3Init = { 1, 3, 5, 3, 1, 35, 43, 19, 367, 487, 703, 2211, 1199, 0 }; + static ulong[] dim964Kuo3Init = { 1, 3, 1, 3, 19, 33, 13, 135, 329, 621, 843, 407, 6523, 0 }; + static ulong[] dim965Kuo3Init = { 1, 1, 7, 5, 13, 1, 45, 133, 27, 267, 1975, 2761, 5061, 0 }; + static ulong[] dim966Kuo3Init = { 1, 1, 3, 3, 19, 59, 13, 35, 489, 391, 1595, 2983, 3203, 0 }; + static ulong[] dim967Kuo3Init = { 1, 3, 3, 7, 19, 27, 125, 55, 121, 733, 1437, 51, 4029, 0 }; + static ulong[] dim968Kuo3Init = { 1, 3, 1, 15, 11, 7, 73, 187, 209, 127, 1259, 1733, 1897, 0 }; + static ulong[] dim969Kuo3Init = { 1, 3, 7, 1, 27, 19, 87, 189, 91, 113, 237, 2073, 419, 0 }; + static ulong[] dim970Kuo3Init = { 1, 3, 5, 3, 15, 27, 107, 77, 467, 953, 1317, 877, 6911, 0 }; + static ulong[] dim971Kuo3Init = { 1, 3, 7, 13, 7, 17, 107, 157, 439, 871, 651, 797, 2095, 0 }; + static ulong[] dim972Kuo3Init = { 1, 1, 3, 9, 13, 19, 19, 75, 13, 267, 435, 1067, 6603, 0 }; + static ulong[] dim973Kuo3Init = { 1, 1, 7, 13, 25, 7, 81, 207, 149, 587, 1561, 2025, 2355, 0 }; + static ulong[] dim974Kuo3Init = { 1, 3, 3, 5, 25, 25, 79, 249, 371, 305, 305, 53, 1051, 0 }; + static ulong[] dim975Kuo3Init = { 1, 1, 3, 9, 19, 63, 57, 237, 39, 349, 1163, 2443, 1739, 0 }; + static ulong[] dim976Kuo3Init = { 1, 1, 5, 5, 23, 57, 61, 21, 115, 107, 303, 1451, 2955, 0 }; + static ulong[] dim977Kuo3Init = { 1, 3, 1, 3, 17, 19, 121, 123, 25, 367, 963, 545, 2885, 0 }; + static ulong[] dim978Kuo3Init = { 1, 3, 3, 5, 15, 57, 123, 1, 193, 861, 1001, 1457, 4977, 0 }; + static ulong[] dim979Kuo3Init = { 1, 3, 5, 9, 21, 31, 37, 83, 361, 491, 1933, 407, 1923, 0 }; + static ulong[] dim980Kuo3Init = { 1, 3, 7, 5, 9, 47, 33, 43, 239, 837, 799, 3731, 5883, 0 }; + static ulong[] dim981Kuo3Init = { 1, 3, 5, 5, 7, 39, 49, 201, 339, 783, 1937, 1473, 391, 0 }; + static ulong[] dim982Kuo3Init = { 1, 3, 5, 13, 3, 63, 39, 91, 63, 645, 929, 1543, 577, 0 }; + static ulong[] dim983Kuo3Init = { 1, 3, 3, 3, 9, 59, 107, 129, 455, 259, 1523, 107, 285, 0 }; + static ulong[] dim984Kuo3Init = { 1, 1, 3, 9, 23, 21, 89, 13, 413, 87, 1703, 1611, 5667, 0 }; + static ulong[] dim985Kuo3Init = { 1, 1, 3, 9, 21, 9, 83, 187, 159, 757, 1111, 3619, 3907, 0 }; + static ulong[] dim986Kuo3Init = { 1, 3, 3, 9, 21, 35, 27, 57, 357, 659, 1243, 2725, 5769, 0 }; + static ulong[] dim987Kuo3Init = { 1, 1, 7, 1, 3, 7, 75, 145, 119, 1019, 1169, 953, 2343, 0 }; + static ulong[] dim988Kuo3Init = { 1, 3, 3, 11, 19, 15, 121, 135, 187, 569, 671, 131, 479, 0 }; + static ulong[] dim989Kuo3Init = { 1, 3, 5, 1, 21, 27, 63, 187, 367, 181, 1885, 2513, 4499, 0 }; + static ulong[] dim990Kuo3Init = { 1, 3, 3, 5, 27, 13, 107, 183, 345, 855, 123, 1491, 867, 0 }; + static ulong[] dim991Kuo3Init = { 1, 3, 7, 9, 5, 41, 43, 47, 277, 657, 1227, 2265, 1777, 0 }; + static ulong[] dim992Kuo3Init = { 1, 1, 5, 5, 31, 37, 119, 5, 395, 399, 787, 2869, 829, 0 }; + static ulong[] dim993Kuo3Init = { 1, 1, 1, 5, 3, 55, 43, 117, 191, 577, 1185, 3407, 4673, 0 }; + static ulong[] dim994Kuo3Init = { 1, 3, 5, 11, 15, 63, 103, 127, 505, 53, 297, 3411, 3919, 0 }; + static ulong[] dim995Kuo3Init = { 1, 3, 7, 13, 15, 57, 45, 17, 253, 261, 767, 1951, 6599, 0 }; + static ulong[] dim996Kuo3Init = { 1, 3, 1, 13, 3, 55, 11, 113, 223, 403, 249, 633, 3265, 0 }; + static ulong[] dim997Kuo3Init = { 1, 1, 1, 5, 7, 49, 47, 47, 467, 633, 1991, 361, 8099, 0 }; + static ulong[] dim998Kuo3Init = { 1, 1, 3, 5, 31, 45, 87, 117, 483, 331, 687, 3393, 7377, 0 }; + static ulong[] dim999Kuo3Init = { 1, 1, 7, 9, 29, 3, 11, 147, 147, 631, 1131, 2651, 3141, 0 }; + static ulong[] dim1000Kuo3Init = { 1, 3, 7, 9, 27, 49, 41, 207, 305, 403, 889, 2947, 5775, 0 }; + static ulong[] dim1001Kuo3Init = { 1, 3, 1, 13, 1, 63, 25, 127, 401, 375, 727, 2375, 2945, 0 }; + static ulong[] dim1002Kuo3Init = { 1, 3, 3, 15, 7, 19, 65, 29, 383, 809, 279, 2081, 1993, 0 }; + static ulong[] dim1003Kuo3Init = { 1, 1, 7, 7, 29, 9, 39, 159, 457, 435, 947, 2309, 2219, 0 }; + static ulong[] dim1004Kuo3Init = { 1, 1, 1, 11, 15, 31, 51, 147, 167, 113, 145, 125, 6997, 0 }; + static ulong[] dim1005Kuo3Init = { 1, 1, 5, 1, 27, 21, 123, 249, 21, 487, 331, 35, 3101, 0 }; + static ulong[] dim1006Kuo3Init = { 1, 3, 7, 3, 5, 7, 127, 173, 115, 607, 1061, 2923, 6869, 0 }; + static ulong[] dim1007Kuo3Init = { 1, 3, 1, 5, 17, 55, 13, 15, 95, 365, 1419, 1111, 7561, 0 }; + static ulong[] dim1008Kuo3Init = { 1, 3, 3, 15, 23, 45, 115, 123, 477, 335, 85, 431, 6893, 0 }; + static ulong[] dim1009Kuo3Init = { 1, 1, 5, 1, 5, 49, 95, 19, 429, 549, 713, 661, 167, 0 }; + static ulong[] dim1010Kuo3Init = { 1, 1, 3, 15, 3, 13, 127, 189, 385, 649, 67, 499, 5355, 0 }; + static ulong[] dim1011Kuo3Init = { 1, 1, 1, 5, 9, 31, 17, 21, 419, 655, 287, 1173, 1023, 0 }; + static ulong[] dim1012Kuo3Init = { 1, 1, 5, 1, 17, 11, 19, 17, 195, 1015, 1621, 1197, 3497, 0 }; + static ulong[] dim1013Kuo3Init = { 1, 3, 1, 5, 29, 55, 85, 43, 381, 59, 149, 391, 2109, 0 }; + static ulong[] dim1014Kuo3Init = { 1, 1, 7, 9, 11, 43, 115, 57, 211, 463, 787, 3665, 5619, 0 }; + static ulong[] dim1015Kuo3Init = { 1, 3, 1, 7, 23, 5, 55, 93, 117, 925, 941, 91, 6221, 0 }; + static ulong[] dim1016Kuo3Init = { 1, 1, 1, 13, 29, 35, 89, 7, 75, 759, 735, 3011, 1279, 0 }; + static ulong[] dim1017Kuo3Init = { 1, 1, 1, 15, 13, 17, 13, 175, 167, 965, 1069, 2215, 6065, 0 }; + static ulong[] dim1018Kuo3Init = { 1, 1, 3, 15, 1, 11, 109, 205, 501, 419, 1071, 543, 5377, 0 }; + static ulong[] dim1019Kuo3Init = { 1, 1, 3, 5, 11, 1, 123, 147, 87, 289, 325, 3693, 4939, 0 }; + static ulong[] dim1020Kuo3Init = { 1, 1, 3, 1, 9, 21, 29, 215, 365, 995, 1727, 2515, 5741, 0 }; + static ulong[] dim1021Kuo3Init = { 1, 1, 3, 5, 3, 7, 5, 147, 413, 505, 661, 3071, 2521, 0 }; + static ulong[] dim1022Kuo3Init = { 1, 3, 7, 5, 5, 41, 117, 145, 455, 379, 601, 455, 5377, 0 }; + static ulong[] dim1023Kuo3Init = { 1, 1, 7, 15, 11, 45, 27, 37, 457, 935, 595, 3883, 1491, 0 }; + static ulong[] dim1024Kuo3Init = { 1, 3, 5, 9, 15, 7, 49, 95, 225, 837, 805, 2553, 4891, 0 }; + static ulong[] dim1025Kuo3Init = { 1, 3, 3, 5, 1, 29, 109, 99, 349, 221, 749, 3499, 4201, 0 }; + static ulong[] dim1026Kuo3Init = { 1, 1, 1, 11, 27, 35, 47, 253, 151, 129, 927, 4039, 6133, 0 }; + static ulong[] dim1027Kuo3Init = { 1, 3, 1, 3, 17, 59, 1, 63, 61, 927, 933, 3645, 3707, 0 }; + static ulong[] dim1028Kuo3Init = { 1, 3, 1, 3, 29, 33, 45, 59, 183, 459, 903, 747, 1895, 0 }; + static ulong[] dim1029Kuo3Init = { 1, 1, 5, 3, 19, 53, 71, 199, 91, 807, 507, 3821, 1815, 0 }; + static ulong[] dim1030Kuo3Init = { 1, 1, 1, 7, 23, 43, 39, 17, 139, 751, 467, 617, 5237, 0 }; + static ulong[] dim1031Kuo3Init = { 1, 1, 7, 13, 5, 53, 43, 181, 337, 731, 497, 3189, 4063, 0 }; + static ulong[] dim1032Kuo3Init = { 1, 1, 7, 9, 1, 45, 103, 151, 265, 897, 1821, 2957, 5591, 0 }; + static ulong[] dim1033Kuo3Init = { 1, 3, 7, 5, 13, 43, 65, 49, 233, 1, 1709, 2641, 5633, 0 }; + static ulong[] dim1034Kuo3Init = { 1, 1, 1, 7, 15, 15, 95, 223, 447, 967, 1533, 1969, 6497, 0 }; + static ulong[] dim1035Kuo3Init = { 1, 1, 7, 9, 29, 5, 55, 57, 377, 487, 443, 2589, 4735, 0 }; + static ulong[] dim1036Kuo3Init = { 1, 1, 5, 1, 23, 49, 5, 47, 203, 727, 1955, 3465, 6691, 0 }; + static ulong[] dim1037Kuo3Init = { 1, 1, 3, 7, 25, 13, 31, 153, 411, 79, 121, 3815, 2123, 0 }; + static ulong[] dim1038Kuo3Init = { 1, 1, 3, 1, 3, 57, 11, 141, 465, 713, 659, 2849, 487, 0 }; + static ulong[] dim1039Kuo3Init = { 1, 3, 7, 5, 29, 49, 91, 249, 353, 247, 1793, 1617, 3321, 0 }; + static ulong[] dim1040Kuo3Init = { 1, 1, 7, 13, 31, 3, 59, 213, 265, 3, 543, 2237, 6617, 0 }; + static ulong[] dim1041Kuo3Init = { 1, 1, 7, 13, 9, 23, 57, 89, 365, 11, 871, 1343, 7375, 0 }; + static ulong[] dim1042Kuo3Init = { 1, 3, 7, 11, 7, 19, 15, 101, 239, 341, 1259, 3607, 3879, 0 }; + static ulong[] dim1043Kuo3Init = { 1, 1, 5, 7, 29, 25, 117, 183, 131, 705, 1497, 3537, 1007, 0 }; + static ulong[] dim1044Kuo3Init = { 1, 1, 1, 3, 11, 41, 113, 127, 95, 417, 1177, 1939, 1317, 0 }; + static ulong[] dim1045Kuo3Init = { 1, 1, 5, 11, 1, 37, 1, 141, 417, 157, 993, 671, 4993, 0 }; + static ulong[] dim1046Kuo3Init = { 1, 1, 7, 11, 23, 15, 41, 171, 389, 261, 1967, 3009, 2237, 0 }; + static ulong[] dim1047Kuo3Init = { 1, 3, 5, 15, 31, 41, 49, 39, 73, 201, 495, 3121, 4247, 0 }; + static ulong[] dim1048Kuo3Init = { 1, 1, 3, 1, 17, 21, 95, 219, 343, 103, 93, 2907, 1279, 0 }; + static ulong[] dim1049Kuo3Init = { 1, 3, 3, 1, 7, 31, 79, 139, 347, 437, 1261, 3425, 6981, 0 }; + static ulong[] dim1050Kuo3Init = { 1, 1, 5, 7, 9, 19, 55, 185, 425, 145, 1627, 3045, 8113, 0 }; + static ulong[] dim1051Kuo3Init = { 1, 1, 5, 1, 15, 33, 99, 185, 485, 859, 481, 3063, 3209, 0 }; + static ulong[] dim1052Kuo3Init = { 1, 1, 3, 13, 23, 7, 7, 81, 405, 705, 1933, 315, 5819, 0 }; + static ulong[] dim1053Kuo3Init = { 1, 3, 1, 3, 9, 55, 95, 101, 391, 299, 185, 3687, 2833, 0 }; + static ulong[] dim1054Kuo3Init = { 1, 3, 7, 13, 15, 5, 119, 29, 29, 893, 207, 1789, 3395, 0 }; + static ulong[] dim1055Kuo3Init = { 1, 3, 3, 5, 1, 59, 49, 81, 391, 95, 289, 3167, 5417, 0 }; + static ulong[] dim1056Kuo3Init = { 1, 3, 5, 15, 31, 21, 5, 189, 63, 567, 1515, 297, 5415, 0 }; + static ulong[] dim1057Kuo3Init = { 1, 3, 3, 15, 3, 23, 105, 113, 403, 799, 591, 1977, 1117, 0 }; + static ulong[] dim1058Kuo3Init = { 1, 3, 1, 13, 23, 55, 59, 229, 319, 357, 1703, 585, 3785, 0 }; + static ulong[] dim1059Kuo3Init = { 1, 3, 7, 13, 7, 1, 97, 247, 451, 897, 137, 3289, 3621, 0 }; + static ulong[] dim1060Kuo3Init = { 1, 3, 1, 5, 13, 43, 89, 75, 243, 489, 1999, 1179, 13, 0 }; + static ulong[] dim1061Kuo3Init = { 1, 3, 7, 9, 11, 21, 51, 199, 15, 859, 83, 613, 5027, 0 }; + static ulong[] dim1062Kuo3Init = { 1, 3, 1, 13, 15, 15, 81, 87, 311, 681, 1391, 2123, 6747, 0 }; + static ulong[] dim1063Kuo3Init = { 1, 3, 1, 1, 5, 45, 5, 123, 19, 831, 1345, 3313, 7945, 0 }; + static ulong[] dim1064Kuo3Init = { 1, 1, 7, 3, 5, 9, 93, 39, 221, 601, 315, 2179, 6573, 0 }; + static ulong[] dim1065Kuo3Init = { 1, 3, 5, 13, 17, 17, 117, 145, 471, 893, 305, 3065, 7519, 0 }; + static ulong[] dim1066Kuo3Init = { 1, 3, 1, 9, 1, 55, 119, 235, 417, 167, 467, 2947, 3235, 0 }; + static ulong[] dim1067Kuo3Init = { 1, 3, 3, 13, 25, 51, 71, 101, 255, 671, 1929, 2911, 2837, 0 }; + static ulong[] dim1068Kuo3Init = { 1, 1, 5, 15, 17, 1, 79, 241, 25, 635, 379, 1701, 7139, 0 }; + static ulong[] dim1069Kuo3Init = { 1, 1, 7, 13, 1, 1, 119, 121, 469, 51, 939, 2161, 4247, 0 }; + static ulong[] dim1070Kuo3Init = { 1, 3, 3, 15, 3, 35, 95, 107, 143, 701, 1843, 301, 6345, 0 }; + static ulong[] dim1071Kuo3Init = { 1, 3, 5, 3, 27, 13, 117, 143, 49, 875, 1705, 3005, 3671, 0 }; + static ulong[] dim1072Kuo3Init = { 1, 1, 7, 7, 5, 49, 111, 33, 169, 189, 1109, 805, 2753, 0 }; + static ulong[] dim1073Kuo3Init = { 1, 3, 7, 9, 19, 49, 59, 3, 71, 859, 435, 3417, 1883, 0 }; + static ulong[] dim1074Kuo3Init = { 1, 3, 5, 9, 9, 51, 35, 79, 385, 83, 1121, 1421, 7317, 0 }; + static ulong[] dim1075Kuo3Init = { 1, 3, 7, 5, 13, 29, 49, 41, 219, 23, 1025, 849, 499, 0 }; + static ulong[] dim1076Kuo3Init = { 1, 3, 3, 11, 3, 15, 13, 167, 441, 753, 1731, 527, 8099, 0 }; + static ulong[] dim1077Kuo3Init = { 1, 3, 5, 3, 1, 57, 17, 193, 29, 849, 15, 539, 1713, 0 }; + static ulong[] dim1078Kuo3Init = { 1, 1, 1, 11, 27, 47, 59, 249, 363, 175, 3, 2485, 3551, 0 }; + static ulong[] dim1079Kuo3Init = { 1, 1, 3, 3, 25, 45, 79, 45, 141, 13, 1007, 1235, 5359, 0 }; + static ulong[] dim1080Kuo3Init = { 1, 3, 1, 7, 29, 31, 111, 173, 281, 287, 173, 2627, 4125, 0 }; + static ulong[] dim1081Kuo3Init = { 1, 3, 5, 5, 3, 13, 37, 157, 509, 323, 1695, 765, 6533, 0 }; + static ulong[] dim1082Kuo3Init = { 1, 3, 5, 11, 7, 33, 77, 237, 377, 351, 205, 183, 5273, 0 }; + static ulong[] dim1083Kuo3Init = { 1, 3, 7, 5, 11, 1, 123, 251, 3, 207, 1319, 553, 8143, 0 }; + static ulong[] dim1084Kuo3Init = { 1, 1, 7, 15, 23, 25, 105, 43, 271, 633, 1331, 2197, 7229, 0 }; + static ulong[] dim1085Kuo3Init = { 1, 3, 3, 1, 13, 37, 119, 195, 21, 751, 1809, 4025, 3037, 0 }; + static ulong[] dim1086Kuo3Init = { 1, 1, 7, 13, 19, 1, 3, 33, 79, 477, 1203, 3657, 5573, 0 }; + static ulong[] dim1087Kuo3Init = { 1, 1, 1, 1, 21, 21, 121, 183, 355, 259, 1033, 1621, 2843, 0 }; + static ulong[] dim1088Kuo3Init = { 1, 3, 7, 15, 19, 37, 121, 233, 397, 27, 279, 2891, 4191, 0 }; + static ulong[] dim1089Kuo3Init = { 1, 3, 1, 3, 13, 5, 31, 237, 453, 913, 1073, 3573, 7883, 0 }; + static ulong[] dim1090Kuo3Init = { 1, 1, 1, 1, 1, 11, 57, 103, 453, 605, 1041, 2975, 4735, 0 }; + static ulong[] dim1091Kuo3Init = { 1, 1, 5, 9, 29, 33, 119, 241, 27, 491, 341, 1945, 6599, 0 }; + static ulong[] dim1092Kuo3Init = { 1, 1, 7, 1, 25, 41, 83, 191, 481, 995, 1819, 1577, 3837, 0 }; + static ulong[] dim1093Kuo3Init = { 1, 3, 5, 5, 15, 21, 81, 111, 143, 281, 509, 2905, 177, 0 }; + static ulong[] dim1094Kuo3Init = { 1, 1, 1, 3, 19, 19, 31, 107, 451, 1007, 2027, 3947, 3903, 0 }; + static ulong[] dim1095Kuo3Init = { 1, 3, 3, 1, 27, 41, 23, 147, 299, 315, 895, 407, 4761, 0 }; + static ulong[] dim1096Kuo3Init = { 1, 3, 7, 15, 27, 1, 105, 103, 507, 897, 1309, 3979, 5123, 0 }; + static ulong[] dim1097Kuo3Init = { 1, 3, 1, 11, 7, 41, 99, 67, 183, 495, 1509, 2733, 6995, 0 }; + static ulong[] dim1098Kuo3Init = { 1, 1, 1, 11, 13, 5, 69, 239, 95, 211, 691, 323, 7485, 0 }; + static ulong[] dim1099Kuo3Init = { 1, 3, 5, 11, 23, 57, 5, 113, 417, 893, 1229, 2109, 7657, 0 }; + static ulong[] dim1100Kuo3Init = { 1, 1, 5, 15, 19, 59, 111, 181, 61, 743, 227, 831, 3035, 0 }; + static ulong[] dim1101Kuo3Init = { 1, 1, 5, 7, 19, 13, 107, 63, 127, 17, 1753, 337, 3403, 0 }; + static ulong[] dim1102Kuo3Init = { 1, 3, 7, 7, 7, 21, 85, 219, 77, 311, 685, 145, 3451, 0 }; + static ulong[] dim1103Kuo3Init = { 1, 3, 5, 5, 3, 55, 123, 187, 407, 539, 1167, 2741, 6885, 0 }; + static ulong[] dim1104Kuo3Init = { 1, 3, 1, 13, 23, 57, 109, 93, 93, 483, 857, 1895, 7145, 0 }; + static ulong[] dim1105Kuo3Init = { 1, 1, 1, 15, 19, 43, 37, 129, 487, 523, 1959, 2053, 6281, 0 }; + static ulong[] dim1106Kuo3Init = { 1, 3, 1, 11, 9, 1, 105, 123, 483, 511, 1661, 1065, 7539, 0 }; + static ulong[] dim1107Kuo3Init = { 1, 3, 3, 1, 27, 33, 87, 191, 89, 697, 1195, 1699, 2699, 0 }; + static ulong[] dim1108Kuo3Init = { 1, 3, 7, 5, 21, 57, 5, 109, 343, 721, 1355, 1155, 4515, 0 }; + static ulong[] dim1109Kuo3Init = { 1, 3, 3, 15, 27, 43, 47, 167, 457, 93, 221, 3693, 383, 0 }; + static ulong[] dim1110Kuo3Init = { 1, 3, 1, 7, 13, 13, 55, 75, 113, 577, 397, 2491, 6871, 0 }; + static ulong[] dim1111Kuo3Init = { 1, 1, 3, 13, 31, 31, 71, 189, 39, 397, 977, 2645, 1683, 5081, 0 }; + static ulong[] dim1112Kuo3Init = { 1, 3, 5, 15, 27, 41, 125, 69, 269, 157, 1827, 41, 3105, 10615, 0 }; + static ulong[] dim1113Kuo3Init = { 1, 1, 3, 9, 5, 45, 33, 169, 317, 371, 389, 595, 1071, 5323, 0 }; + static ulong[] dim1114Kuo3Init = { 1, 1, 5, 5, 25, 25, 69, 45, 313, 105, 795, 3987, 5181, 155, 0 }; + static ulong[] dim1115Kuo3Init = { 1, 3, 7, 5, 19, 17, 13, 119, 213, 289, 269, 1561, 6069, 15631, 0 }; + static ulong[] dim1116Kuo3Init = { 1, 3, 7, 1, 15, 7, 17, 173, 491, 907, 315, 101, 6205, 4631, 0 }; + static ulong[] dim1117Kuo3Init = { 1, 1, 5, 11, 17, 13, 9, 67, 267, 719, 1565, 2157, 5773, 5167, 0 }; + static ulong[] dim1118Kuo3Init = { 1, 1, 5, 5, 11, 45, 65, 207, 403, 231, 1019, 3345, 2779, 3621, 0 }; + static ulong[] dim1119Kuo3Init = { 1, 3, 5, 13, 13, 59, 65, 225, 307, 581, 1159, 2041, 3535, 16381, 0 }; + static ulong[] dim1120Kuo3Init = { 1, 3, 1, 15, 9, 45, 17, 99, 285, 797, 477, 3041, 3123, 397, 0 }; + static ulong[] dim1121Kuo3Init = { 1, 3, 1, 15, 3, 57, 99, 115, 105, 877, 9, 1185, 3147, 6285, 0 }; + static ulong[] dim1122Kuo3Init = { 1, 1, 1, 1, 25, 31, 37, 13, 119, 935, 1339, 2147, 2371, 16107, 0 }; + static ulong[] dim1123Kuo3Init = { 1, 1, 5, 15, 17, 31, 123, 131, 135, 977, 1943, 3643, 4457, 15405, 0 }; + static ulong[] dim1124Kuo3Init = { 1, 3, 3, 1, 3, 57, 29, 33, 1, 519, 535, 681, 6255, 16263, 0 }; + static ulong[] dim1125Kuo3Init = { 1, 1, 5, 3, 9, 45, 39, 215, 329, 457, 1341, 3037, 1631, 15335, 0 }; + static ulong[] dim1126Kuo3Init = { 1, 1, 7, 13, 3, 27, 23, 73, 465, 771, 1453, 3821, 3099, 10075, 0 }; + static ulong[] dim1127Kuo3Init = { 1, 1, 3, 3, 21, 45, 119, 233, 507, 959, 1743, 2711, 2465, 4257, 0 }; + static ulong[] dim1128Kuo3Init = { 1, 1, 7, 5, 31, 37, 113, 207, 239, 305, 1085, 2447, 743, 15747, 0 }; + static ulong[] dim1129Kuo3Init = { 1, 3, 5, 5, 27, 25, 83, 255, 93, 149, 627, 1887, 6913, 5793, 0 }; + static ulong[] dim1130Kuo3Init = { 1, 1, 5, 11, 17, 61, 91, 75, 469, 503, 1405, 3609, 421, 10819, 0 }; + static ulong[] dim1131Kuo3Init = { 1, 1, 5, 1, 13, 47, 53, 221, 351, 621, 1025, 3729, 367, 16091, 0 }; + static ulong[] dim1132Kuo3Init = { 1, 1, 1, 5, 7, 41, 3, 177, 127, 71, 753, 1581, 2227, 257, 0 }; + static ulong[] dim1133Kuo3Init = { 1, 1, 3, 3, 3, 17, 69, 31, 143, 825, 291, 257, 2147, 4199, 0 }; + static ulong[] dim1134Kuo3Init = { 1, 1, 5, 9, 29, 21, 49, 1, 35, 321, 383, 1495, 4201, 7143, 0 }; + static ulong[] dim1135Kuo3Init = { 1, 3, 7, 13, 5, 27, 31, 143, 117, 487, 585, 809, 2425, 15681, 0 }; + static ulong[] dim1136Kuo3Init = { 1, 3, 3, 13, 23, 3, 33, 213, 209, 185, 603, 431, 5519, 5017, 0 }; + static ulong[] dim1137Kuo3Init = { 1, 3, 7, 9, 21, 61, 3, 53, 303, 793, 759, 3869, 391, 8395, 0 }; + static ulong[] dim1138Kuo3Init = { 1, 3, 5, 13, 25, 13, 119, 37, 419, 399, 825, 709, 5351, 1299, 0 }; + static ulong[] dim1139Kuo3Init = { 1, 3, 7, 11, 17, 11, 93, 205, 33, 493, 1353, 3777, 2521, 13405, 0 }; + static ulong[] dim1140Kuo3Init = { 1, 3, 3, 5, 5, 3, 25, 215, 209, 559, 465, 1809, 6621, 8733, 0 }; + static ulong[] dim1141Kuo3Init = { 1, 3, 5, 11, 23, 17, 75, 11, 299, 613, 565, 3487, 5017, 6187, 0 }; + static ulong[] dim1142Kuo3Init = { 1, 3, 5, 15, 15, 41, 121, 225, 259, 283, 1119, 3509, 6663, 241, 0 }; + static ulong[] dim1143Kuo3Init = { 1, 3, 3, 5, 17, 49, 5, 227, 493, 677, 1365, 3681, 1651, 5079, 0 }; + static ulong[] dim1144Kuo3Init = { 1, 3, 5, 11, 3, 13, 43, 219, 247, 223, 1451, 1449, 605, 5877, 0 }; + static ulong[] dim1145Kuo3Init = { 1, 1, 7, 7, 21, 47, 7, 197, 387, 59, 7, 3209, 5623, 1221, 0 }; + static ulong[] dim1146Kuo3Init = { 1, 3, 3, 5, 25, 5, 97, 1, 105, 801, 815, 1635, 3567, 5231, 0 }; + static ulong[] dim1147Kuo3Init = { 1, 3, 7, 15, 17, 21, 101, 167, 265, 407, 1859, 3359, 1245, 4153, 0 }; + static ulong[] dim1148Kuo3Init = { 1, 1, 1, 11, 31, 61, 21, 101, 77, 325, 645, 2059, 3201, 527, 0 }; + static ulong[] dim1149Kuo3Init = { 1, 3, 7, 15, 29, 55, 107, 135, 55, 433, 1519, 1049, 6119, 15877, 0 }; + static ulong[] dim1150Kuo3Init = { 1, 1, 7, 7, 19, 29, 1, 167, 13, 67, 1703, 1159, 7145, 4243, 0 }; + static ulong[] dim1151Kuo3Init = { 1, 3, 5, 11, 1, 33, 7, 21, 407, 695, 345, 425, 7399, 3847, 0 }; + static ulong[] dim1152Kuo3Init = { 1, 1, 7, 11, 15, 59, 121, 175, 21, 859, 1311, 1365, 3823, 3983, 0 }; + static ulong[] dim1153Kuo3Init = { 1, 1, 7, 5, 29, 21, 111, 221, 429, 739, 985, 1989, 4947, 8311, 0 }; + static ulong[] dim1154Kuo3Init = { 1, 3, 3, 15, 29, 17, 103, 39, 475, 193, 253, 1903, 4073, 15039, 0 }; + static ulong[] dim1155Kuo3Init = { 1, 3, 7, 11, 1, 57, 35, 197, 89, 475, 283, 2291, 7129, 14357, 0 }; + static ulong[] dim1156Kuo3Init = { 1, 1, 3, 11, 15, 63, 29, 157, 211, 517, 1643, 199, 285, 8621, 0 }; + static ulong[] dim1157Kuo3Init = { 1, 3, 3, 15, 9, 47, 43, 215, 407, 979, 51, 635, 467, 6365, 0 }; + static ulong[] dim1158Kuo3Init = { 1, 3, 3, 1, 23, 27, 97, 111, 51, 407, 1037, 1337, 1475, 1151, 0 }; + static ulong[] dim1159Kuo3Init = { 1, 3, 3, 15, 13, 45, 67, 51, 331, 691, 1137, 1967, 5715, 3125, 0 }; + static ulong[] dim1160Kuo3Init = { 1, 3, 3, 15, 31, 19, 85, 221, 449, 689, 1817, 1575, 7429, 12125, 0 }; + static ulong[] dim1161Kuo3Init = { 1, 3, 1, 9, 21, 61, 77, 55, 65, 591, 9, 2477, 4081, 4631, 0 }; + static ulong[] dim1162Kuo3Init = { 1, 3, 5, 9, 27, 45, 29, 159, 21, 931, 1939, 1297, 5589, 12635, 0 }; + static ulong[] dim1163Kuo3Init = { 1, 1, 7, 9, 21, 41, 7, 171, 461, 373, 1655, 3475, 4073, 4859, 0 }; + static ulong[] dim1164Kuo3Init = { 1, 3, 1, 13, 17, 35, 3, 41, 45, 37, 1409, 3939, 5497, 3501, 0 }; + static ulong[] dim1165Kuo3Init = { 1, 1, 3, 15, 11, 57, 121, 177, 177, 515, 675, 1943, 2645, 2469, 0 }; + static ulong[] dim1166Kuo3Init = { 1, 1, 7, 1, 23, 63, 29, 157, 157, 397, 1131, 1479, 4683, 10011, 0 }; + static ulong[] dim1167Kuo3Init = { 1, 3, 7, 9, 15, 35, 75, 99, 195, 589, 19, 3427, 1623, 12843, 0 }; + static ulong[] dim1168Kuo3Init = { 1, 3, 7, 3, 21, 19, 101, 135, 351, 549, 223, 517, 4023, 1863, 0 }; + static ulong[] dim1169Kuo3Init = { 1, 1, 7, 7, 7, 23, 67, 15, 217, 915, 1617, 1527, 877, 15061, 0 }; + static ulong[] dim1170Kuo3Init = { 1, 3, 5, 3, 11, 35, 95, 5, 399, 669, 1185, 167, 7405, 11169, 0 }; + static ulong[] dim1171Kuo3Init = { 1, 3, 5, 5, 1, 49, 91, 125, 185, 73, 263, 1139, 3171, 5427, 0 }; + static ulong[] dim1172Kuo3Init = { 1, 1, 5, 1, 27, 51, 89, 81, 179, 593, 67, 1495, 3669, 15981, 0 }; + static ulong[] dim1173Kuo3Init = { 1, 3, 1, 11, 29, 63, 47, 105, 327, 747, 953, 2399, 6711, 16313, 0 }; + static ulong[] dim1174Kuo3Init = { 1, 1, 5, 5, 21, 21, 117, 179, 427, 981, 2029, 1, 495, 4005, 0 }; + static ulong[] dim1175Kuo3Init = { 1, 1, 3, 5, 23, 21, 59, 99, 459, 217, 1131, 1853, 3049, 2247, 0 }; + static ulong[] dim1176Kuo3Init = { 1, 3, 1, 5, 29, 9, 71, 167, 55, 775, 627, 3967, 45, 11199, 0 }; + static ulong[] dim1177Kuo3Init = { 1, 3, 5, 3, 29, 25, 1, 69, 317, 649, 1567, 2587, 2277, 15675, 0 }; + static ulong[] dim1178Kuo3Init = { 1, 3, 3, 9, 21, 3, 39, 147, 279, 953, 1207, 333, 2747, 1717, 0 }; + static ulong[] dim1179Kuo3Init = { 1, 3, 3, 3, 31, 63, 113, 149, 431, 699, 335, 2475, 6375, 13061, 0 }; + static ulong[] dim1180Kuo3Init = { 1, 1, 7, 11, 11, 19, 51, 175, 377, 971, 35, 2749, 6309, 4755, 0 }; + static ulong[] dim1181Kuo3Init = { 1, 1, 3, 15, 27, 53, 105, 221, 15, 495, 799, 1717, 6997, 15949, 0 }; + static ulong[] dim1182Kuo3Init = { 1, 1, 1, 15, 31, 29, 69, 137, 421, 231, 2021, 1869, 4533, 1121, 0 }; + static ulong[] dim1183Kuo3Init = { 1, 1, 7, 11, 15, 49, 17, 121, 285, 303, 1085, 2463, 357, 2519, 0 }; + static ulong[] dim1184Kuo3Init = { 1, 1, 1, 5, 29, 47, 109, 95, 339, 15, 1195, 2171, 4649, 6517, 0 }; + static ulong[] dim1185Kuo3Init = { 1, 3, 3, 3, 29, 19, 45, 93, 47, 827, 1113, 4055, 601, 10807, 0 }; + static ulong[] dim1186Kuo3Init = { 1, 1, 7, 5, 15, 47, 11, 79, 137, 267, 1443, 1003, 2475, 147, 0 }; + static ulong[] dim1187Kuo3Init = { 1, 3, 7, 15, 11, 39, 95, 191, 205, 967, 333, 3371, 4913, 15231, 0 }; + static ulong[] dim1188Kuo3Init = { 1, 3, 7, 9, 25, 9, 47, 75, 77, 539, 487, 361, 2293, 7285, 0 }; + static ulong[] dim1189Kuo3Init = { 1, 3, 7, 7, 27, 11, 93, 181, 455, 277, 1001, 3313, 7335, 4593, 0 }; + static ulong[] dim1190Kuo3Init = { 1, 1, 5, 5, 15, 35, 107, 51, 223, 447, 371, 1739, 1937, 3589, 0 }; + static ulong[] dim1191Kuo3Init = { 1, 1, 3, 11, 15, 51, 23, 129, 285, 895, 2015, 1389, 2043, 1989, 0 }; + static ulong[] dim1192Kuo3Init = { 1, 1, 5, 7, 21, 57, 107, 149, 285, 825, 959, 827, 2931, 3207, 0 }; + static ulong[] dim1193Kuo3Init = { 1, 1, 1, 13, 23, 19, 91, 15, 261, 785, 1031, 2245, 505, 14891, 0 }; + static ulong[] dim1194Kuo3Init = { 1, 1, 3, 15, 23, 21, 33, 153, 71, 757, 1131, 3251, 877, 4533, 0 }; + static ulong[] dim1195Kuo3Init = { 1, 1, 3, 11, 25, 39, 33, 231, 451, 587, 781, 1145, 4743, 467, 0 }; + static ulong[] dim1196Kuo3Init = { 1, 1, 7, 11, 23, 7, 35, 45, 397, 41, 1443, 2087, 587, 14139, 0 }; + static ulong[] dim1197Kuo3Init = { 1, 3, 3, 3, 19, 57, 61, 225, 197, 263, 1447, 1929, 2833, 5325, 0 }; + static ulong[] dim1198Kuo3Init = { 1, 1, 5, 7, 25, 51, 45, 221, 403, 843, 727, 3099, 3883, 9151, 0 }; + static ulong[] dim1199Kuo3Init = { 1, 1, 5, 13, 9, 23, 33, 119, 81, 525, 1527, 567, 2867, 12907, 0 }; + static ulong[] dim1200Kuo3Init = { 1, 1, 5, 5, 11, 19, 125, 135, 427, 949, 643, 3403, 6531, 12607, 0 }; + static ulong[] dim1201Kuo3Init = { 1, 3, 3, 7, 27, 23, 89, 83, 381, 333, 361, 2773, 4247, 10233, 0 }; + static ulong[] dim1202Kuo3Init = { 1, 3, 7, 11, 25, 61, 105, 141, 473, 993, 379, 2949, 5757, 4003, 0 }; + static ulong[] dim1203Kuo3Init = { 1, 1, 3, 11, 27, 29, 75, 175, 391, 567, 1017, 1575, 5287, 16289, 0 }; + static ulong[] dim1204Kuo3Init = { 1, 3, 7, 15, 7, 33, 23, 137, 299, 19, 599, 2649, 6141, 3321, 0 }; + static ulong[] dim1205Kuo3Init = { 1, 1, 3, 1, 3, 19, 101, 95, 499, 261, 51, 43, 5457, 313, 0 }; + static ulong[] dim1206Kuo3Init = { 1, 3, 5, 11, 27, 5, 7, 85, 419, 983, 1965, 1639, 6397, 15823, 0 }; + static ulong[] dim1207Kuo3Init = { 1, 1, 1, 11, 13, 55, 121, 13, 289, 791, 437, 3279, 7125, 10473, 0 }; + static ulong[] dim1208Kuo3Init = { 1, 1, 7, 1, 13, 15, 25, 9, 21, 205, 61, 749, 8005, 9453, 0 }; + static ulong[] dim1209Kuo3Init = { 1, 1, 3, 9, 19, 47, 55, 113, 325, 165, 771, 3655, 6265, 11157, 0 }; + static ulong[] dim1210Kuo3Init = { 1, 1, 5, 13, 19, 45, 107, 37, 205, 677, 1273, 3817, 559, 11321, 0 }; + static ulong[] dim1211Kuo3Init = { 1, 3, 7, 15, 31, 57, 87, 31, 431, 383, 327, 2703, 4197, 7861, 0 }; + static ulong[] dim1212Kuo3Init = { 1, 1, 3, 9, 3, 33, 39, 253, 215, 903, 447, 2175, 5249, 3203, 0 }; + static ulong[] dim1213Kuo3Init = { 1, 3, 7, 5, 15, 5, 27, 145, 391, 869, 1641, 2497, 4683, 3111, 0 }; + static ulong[] dim1214Kuo3Init = { 1, 3, 1, 5, 3, 33, 39, 223, 379, 803, 1833, 1799, 2617, 2113, 0 }; + static ulong[] dim1215Kuo3Init = { 1, 3, 1, 15, 29, 37, 57, 227, 425, 943, 311, 2883, 2973, 1831, 0 }; + static ulong[] dim1216Kuo3Init = { 1, 3, 3, 5, 17, 63, 113, 139, 453, 871, 1029, 2705, 3379, 4503, 0 }; + static ulong[] dim1217Kuo3Init = { 1, 3, 7, 5, 19, 35, 43, 151, 511, 657, 1885, 1425, 387, 2165, 0 }; + static ulong[] dim1218Kuo3Init = { 1, 1, 3, 15, 9, 61, 123, 241, 485, 485, 955, 1215, 87, 3195, 0 }; + static ulong[] dim1219Kuo3Init = { 1, 3, 5, 9, 23, 45, 51, 15, 23, 49, 2025, 853, 6609, 12099, 0 }; + static ulong[] dim1220Kuo3Init = { 1, 3, 7, 7, 23, 35, 95, 67, 131, 281, 1821, 1951, 1363, 7477, 0 }; + static ulong[] dim1221Kuo3Init = { 1, 3, 1, 7, 9, 53, 79, 255, 453, 77, 629, 1207, 4171, 4415, 0 }; + static ulong[] dim1222Kuo3Init = { 1, 3, 5, 3, 23, 5, 11, 153, 57, 217, 1177, 2297, 3515, 15121, 0 }; + static ulong[] dim1223Kuo3Init = { 1, 1, 1, 9, 31, 57, 93, 35, 177, 449, 1505, 2715, 1315, 8953, 0 }; + static ulong[] dim1224Kuo3Init = { 1, 1, 3, 11, 7, 7, 109, 255, 317, 325, 267, 2573, 1511, 3371, 0 }; + static ulong[] dim1225Kuo3Init = { 1, 3, 7, 11, 13, 51, 29, 203, 13, 889, 679, 1981, 5553, 671, 0 }; + static ulong[] dim1226Kuo3Init = { 1, 1, 3, 5, 29, 11, 29, 249, 289, 817, 1983, 1865, 6705, 9667, 0 }; + static ulong[] dim1227Kuo3Init = { 1, 1, 3, 13, 15, 19, 23, 59, 143, 815, 643, 763, 1437, 2909, 0 }; + static ulong[] dim1228Kuo3Init = { 1, 3, 7, 5, 15, 61, 121, 73, 367, 13, 1455, 561, 7475, 8479, 0 }; + static ulong[] dim1229Kuo3Init = { 1, 3, 1, 15, 17, 19, 105, 223, 481, 49, 217, 2935, 2731, 9857, 0 }; + static ulong[] dim1230Kuo3Init = { 1, 3, 1, 7, 3, 41, 3, 195, 245, 969, 139, 2727, 6957, 2049, 0 }; + static ulong[] dim1231Kuo3Init = { 1, 1, 5, 1, 13, 39, 55, 247, 279, 991, 875, 1393, 2649, 14477, 0 }; + static ulong[] dim1232Kuo3Init = { 1, 1, 7, 3, 19, 1, 83, 87, 277, 939, 105, 681, 5377, 16067, 0 }; + static ulong[] dim1233Kuo3Init = { 1, 3, 3, 3, 29, 9, 63, 67, 97, 457, 179, 1137, 5067, 14541, 0 }; + static ulong[] dim1234Kuo3Init = { 1, 1, 7, 5, 25, 23, 17, 175, 33, 523, 2023, 649, 6889, 3481, 0 }; + static ulong[] dim1235Kuo3Init = { 1, 1, 7, 7, 13, 7, 7, 145, 81, 69, 1029, 1351, 285, 13007, 0 }; + static ulong[] dim1236Kuo3Init = { 1, 1, 5, 3, 3, 23, 107, 67, 327, 463, 1123, 1981, 1189, 6921, 0 }; + static ulong[] dim1237Kuo3Init = { 1, 1, 7, 3, 15, 31, 15, 51, 421, 191, 1663, 2257, 2633, 4685, 0 }; + static ulong[] dim1238Kuo3Init = { 1, 3, 7, 11, 9, 41, 101, 43, 23, 453, 1399, 2349, 8013, 15791, 0 }; + static ulong[] dim1239Kuo3Init = { 1, 3, 3, 11, 27, 47, 15, 193, 99, 355, 1873, 1541, 5957, 13079, 0 }; + static ulong[] dim1240Kuo3Init = { 1, 3, 1, 9, 11, 45, 43, 171, 355, 17, 955, 1153, 1437, 5477, 0 }; + static ulong[] dim1241Kuo3Init = { 1, 3, 7, 7, 29, 25, 11, 231, 79, 951, 1619, 69, 2279, 7249, 0 }; + static ulong[] dim1242Kuo3Init = { 1, 1, 5, 1, 5, 41, 47, 229, 353, 261, 443, 1181, 1813, 7929, 0 }; + static ulong[] dim1243Kuo3Init = { 1, 3, 7, 13, 19, 45, 69, 11, 209, 477, 1623, 429, 1853, 13571, 0 }; + static ulong[] dim1244Kuo3Init = { 1, 3, 3, 5, 19, 55, 49, 243, 357, 675, 129, 2801, 2511, 12965, 0 }; + static ulong[] dim1245Kuo3Init = { 1, 1, 3, 15, 11, 47, 11, 11, 291, 943, 573, 2257, 1767, 2547, 0 }; + static ulong[] dim1246Kuo3Init = { 1, 1, 7, 11, 1, 11, 103, 65, 395, 623, 697, 3375, 7977, 13449, 0 }; + static ulong[] dim1247Kuo3Init = { 1, 1, 3, 3, 3, 35, 69, 59, 85, 379, 835, 557, 873, 16281, 0 }; + static ulong[] dim1248Kuo3Init = { 1, 1, 7, 3, 31, 41, 59, 137, 297, 43, 1111, 2119, 3109, 1551, 0 }; + static ulong[] dim1249Kuo3Init = { 1, 3, 7, 13, 11, 11, 87, 199, 283, 461, 951, 2429, 6739, 11499, 0 }; + static ulong[] dim1250Kuo3Init = { 1, 3, 7, 7, 31, 13, 89, 75, 117, 755, 1761, 581, 7233, 8395, 0 }; + static ulong[] dim1251Kuo3Init = { 1, 3, 7, 7, 1, 29, 117, 213, 81, 901, 357, 27, 127, 10541, 0 }; + static ulong[] dim1252Kuo3Init = { 1, 1, 7, 5, 31, 1, 11, 243, 321, 973, 1753, 2363, 6717, 14861, 0 }; + static ulong[] dim1253Kuo3Init = { 1, 1, 1, 1, 17, 25, 35, 211, 197, 697, 1389, 1371, 3687, 11941, 0 }; + static ulong[] dim1254Kuo3Init = { 1, 3, 5, 11, 15, 35, 27, 179, 367, 891, 483, 3581, 4343, 9581, 0 }; + static ulong[] dim1255Kuo3Init = { 1, 3, 5, 1, 13, 41, 67, 75, 309, 601, 247, 1609, 4365, 3003, 0 }; + static ulong[] dim1256Kuo3Init = { 1, 1, 7, 11, 1, 59, 55, 213, 415, 445, 1763, 3615, 6847, 11931, 0 }; + static ulong[] dim1257Kuo3Init = { 1, 1, 7, 13, 25, 53, 9, 63, 501, 95, 1745, 3273, 3551, 12733, 0 }; + static ulong[] dim1258Kuo3Init = { 1, 3, 7, 7, 13, 23, 117, 75, 169, 11, 1401, 125, 2127, 15609, 0 }; + static ulong[] dim1259Kuo3Init = { 1, 3, 3, 9, 21, 53, 113, 247, 495, 39, 1491, 985, 4943, 3683, 0 }; + static ulong[] dim1260Kuo3Init = { 1, 1, 1, 7, 5, 49, 23, 207, 43, 863, 749, 3363, 1191, 1305, 0 }; + static ulong[] dim1261Kuo3Init = { 1, 1, 5, 15, 3, 13, 19, 123, 377, 803, 319, 2617, 7781, 5113, 0 }; + static ulong[] dim1262Kuo3Init = { 1, 3, 3, 13, 23, 53, 19, 223, 63, 729, 599, 2437, 1023, 13659, 0 }; + static ulong[] dim1263Kuo3Init = { 1, 3, 7, 13, 7, 31, 101, 227, 53, 933, 405, 1077, 1341, 12049, 0 }; + static ulong[] dim1264Kuo3Init = { 1, 1, 3, 11, 21, 31, 65, 191, 175, 735, 593, 805, 4405, 7893, 0 }; + static ulong[] dim1265Kuo3Init = { 1, 3, 3, 11, 11, 23, 57, 71, 367, 275, 715, 81, 6455, 9509, 0 }; + static ulong[] dim1266Kuo3Init = { 1, 1, 5, 9, 7, 5, 99, 19, 193, 501, 243, 1971, 4685, 455, 0 }; + static ulong[] dim1267Kuo3Init = { 1, 3, 3, 1, 11, 59, 45, 241, 257, 107, 605, 3885, 813, 15667, 0 }; + static ulong[] dim1268Kuo3Init = { 1, 3, 7, 9, 17, 63, 93, 129, 191, 839, 535, 271, 1087, 10393, 0 }; + static ulong[] dim1269Kuo3Init = { 1, 1, 3, 9, 19, 15, 11, 85, 377, 653, 891, 1909, 5561, 1289, 0 }; + static ulong[] dim1270Kuo3Init = { 1, 3, 1, 15, 7, 25, 25, 67, 55, 749, 1541, 1183, 1563, 5377, 0 }; + static ulong[] dim1271Kuo3Init = { 1, 3, 1, 5, 11, 57, 121, 173, 317, 777, 749, 4037, 123, 10707, 0 }; + static ulong[] dim1272Kuo3Init = { 1, 3, 3, 5, 29, 45, 99, 215, 103, 447, 1743, 991, 7649, 11773, 0 }; + static ulong[] dim1273Kuo3Init = { 1, 1, 5, 7, 3, 33, 39, 169, 255, 383, 559, 3635, 5669, 4267, 0 }; + static ulong[] dim1274Kuo3Init = { 1, 3, 1, 5, 15, 41, 51, 69, 373, 815, 293, 2125, 4903, 12429, 0 }; + static ulong[] dim1275Kuo3Init = { 1, 3, 3, 1, 17, 53, 101, 153, 271, 491, 801, 2811, 619, 2021, 0 }; + static ulong[] dim1276Kuo3Init = { 1, 1, 3, 5, 25, 37, 33, 139, 385, 323, 601, 1077, 753, 3925, 0 }; + static ulong[] dim1277Kuo3Init = { 1, 1, 3, 1, 25, 21, 127, 67, 463, 121, 1765, 1561, 5, 5161, 0 }; + static ulong[] dim1278Kuo3Init = { 1, 1, 7, 7, 25, 27, 37, 159, 453, 847, 353, 3051, 4269, 13981, 0 }; + static ulong[] dim1279Kuo3Init = { 1, 3, 5, 11, 13, 1, 11, 123, 459, 989, 1459, 3793, 5915, 8411, 0 }; + static ulong[] dim1280Kuo3Init = { 1, 3, 1, 15, 5, 21, 37, 41, 399, 471, 1147, 143, 2737, 9447, 0 }; + static ulong[] dim1281Kuo3Init = { 1, 3, 1, 5, 27, 5, 121, 77, 183, 209, 49, 3737, 4317, 11225, 0 }; + static ulong[] dim1282Kuo3Init = { 1, 1, 3, 7, 5, 9, 65, 25, 237, 21, 139, 1729, 965, 15419, 0 }; + static ulong[] dim1283Kuo3Init = { 1, 1, 3, 11, 5, 47, 115, 211, 495, 97, 1439, 127, 4823, 11643, 0 }; + static ulong[] dim1284Kuo3Init = { 1, 1, 5, 1, 11, 37, 19, 129, 35, 1017, 1057, 3501, 4293, 15271, 0 }; + static ulong[] dim1285Kuo3Init = { 1, 3, 5, 5, 3, 31, 45, 25, 441, 729, 909, 3519, 5579, 10341, 0 }; + static ulong[] dim1286Kuo3Init = { 1, 1, 5, 13, 23, 55, 13, 47, 25, 319, 697, 2839, 209, 5007, 0 }; + static ulong[] dim1287Kuo3Init = { 1, 3, 1, 13, 31, 7, 81, 239, 305, 667, 233, 3555, 7385, 10113, 0 }; + static ulong[] dim1288Kuo3Init = { 1, 3, 3, 13, 23, 7, 101, 193, 343, 435, 1065, 3399, 1855, 15231, 0 }; + static ulong[] dim1289Kuo3Init = { 1, 3, 7, 7, 3, 31, 13, 51, 141, 523, 1545, 31, 3827, 13871, 0 }; + static ulong[] dim1290Kuo3Init = { 1, 1, 1, 3, 29, 37, 117, 187, 337, 799, 923, 3919, 5861, 3167, 0 }; + static ulong[] dim1291Kuo3Init = { 1, 3, 7, 1, 21, 17, 59, 73, 223, 455, 2025, 2701, 673, 8333, 0 }; + static ulong[] dim1292Kuo3Init = { 1, 1, 1, 3, 9, 53, 99, 87, 35, 637, 1553, 1417, 1233, 855, 0 }; + static ulong[] dim1293Kuo3Init = { 1, 1, 3, 11, 25, 21, 3, 227, 345, 711, 1347, 437, 7513, 7731, 0 }; + static ulong[] dim1294Kuo3Init = { 1, 1, 1, 3, 5, 51, 125, 133, 241, 327, 589, 1895, 1627, 6945, 0 }; + static ulong[] dim1295Kuo3Init = { 1, 1, 1, 3, 21, 19, 101, 95, 143, 353, 1783, 2815, 3691, 11209, 0 }; + static ulong[] dim1296Kuo3Init = { 1, 1, 3, 1, 31, 29, 95, 121, 253, 925, 277, 2857, 963, 7701, 0 }; + static ulong[] dim1297Kuo3Init = { 1, 3, 7, 5, 3, 23, 31, 63, 467, 91, 1235, 1927, 4347, 9281, 0 }; + static ulong[] dim1298Kuo3Init = { 1, 1, 5, 15, 21, 23, 113, 219, 69, 13, 1165, 1043, 6335, 3499, 0 }; + static ulong[] dim1299Kuo3Init = { 1, 1, 7, 15, 25, 35, 67, 67, 273, 421, 521, 1169, 1557, 1523, 0 }; + static ulong[] dim1300Kuo3Init = { 1, 3, 5, 7, 25, 5, 19, 157, 385, 35, 1701, 1697, 1425, 12549, 0 }; + static ulong[] dim1301Kuo3Init = { 1, 1, 3, 1, 15, 13, 31, 219, 159, 831, 909, 1907, 4251, 4231, 0 }; + static ulong[] dim1302Kuo3Init = { 1, 3, 5, 7, 27, 51, 19, 205, 177, 769, 1881, 3961, 7715, 13351, 0 }; + static ulong[] dim1303Kuo3Init = { 1, 1, 3, 5, 13, 19, 1, 91, 257, 201, 459, 525, 5093, 7259, 0 }; + static ulong[] dim1304Kuo3Init = { 1, 3, 7, 9, 3, 37, 87, 117, 209, 9, 1019, 195, 1531, 14445, 0 }; + static ulong[] dim1305Kuo3Init = { 1, 1, 1, 5, 23, 35, 21, 27, 455, 665, 455, 1009, 2315, 11465, 0 }; + static ulong[] dim1306Kuo3Init = { 1, 3, 7, 1, 17, 55, 3, 71, 239, 183, 889, 2091, 2853, 12541, 0 }; + static ulong[] dim1307Kuo3Init = { 1, 1, 3, 15, 5, 7, 67, 127, 411, 719, 835, 2299, 1339, 12149, 0 }; + static ulong[] dim1308Kuo3Init = { 1, 1, 3, 3, 7, 21, 113, 199, 17, 161, 1945, 1141, 4879, 1579, 0 }; + static ulong[] dim1309Kuo3Init = { 1, 3, 1, 7, 5, 9, 35, 169, 317, 355, 193, 599, 7653, 7689, 0 }; + static ulong[] dim1310Kuo3Init = { 1, 1, 1, 13, 29, 35, 59, 85, 139, 199, 1075, 2799, 6263, 11133, 0 }; + static ulong[] dim1311Kuo3Init = { 1, 1, 5, 3, 19, 63, 13, 41, 289, 845, 1455, 633, 4995, 2037, 0 }; + static ulong[] dim1312Kuo3Init = { 1, 1, 3, 11, 19, 25, 65, 213, 27, 257, 1151, 4063, 5587, 2205, 0 }; + static ulong[] dim1313Kuo3Init = { 1, 1, 7, 7, 9, 53, 103, 49, 187, 579, 801, 263, 2975, 12013, 0 }; + static ulong[] dim1314Kuo3Init = { 1, 3, 1, 13, 7, 13, 85, 11, 365, 63, 595, 747, 1565, 1817, 0 }; + static ulong[] dim1315Kuo3Init = { 1, 3, 7, 15, 11, 1, 45, 3, 181, 357, 447, 821, 6471, 10121, 0 }; + static ulong[] dim1316Kuo3Init = { 1, 1, 7, 11, 7, 25, 75, 139, 463, 679, 1327, 2863, 2373, 10681, 0 }; + static ulong[] dim1317Kuo3Init = { 1, 3, 5, 5, 17, 7, 103, 157, 241, 781, 399, 3951, 6587, 35, 0 }; + static ulong[] dim1318Kuo3Init = { 1, 3, 5, 5, 17, 29, 71, 115, 415, 91, 729, 3055, 5219, 15271, 0 }; + static ulong[] dim1319Kuo3Init = { 1, 3, 1, 9, 7, 5, 123, 235, 33, 103, 257, 1151, 3931, 16257, 0 }; + static ulong[] dim1320Kuo3Init = { 1, 1, 3, 11, 27, 29, 29, 31, 463, 187, 103, 209, 747, 14311, 0 }; + static ulong[] dim1321Kuo3Init = { 1, 3, 5, 1, 11, 61, 79, 103, 233, 733, 779, 705, 2377, 12689, 0 }; + static ulong[] dim1322Kuo3Init = { 1, 3, 1, 9, 31, 11, 123, 239, 227, 81, 525, 2099, 8149, 5851, 0 }; + static ulong[] dim1323Kuo3Init = { 1, 3, 7, 5, 1, 37, 9, 199, 313, 875, 975, 777, 5449, 3075, 0 }; + static ulong[] dim1324Kuo3Init = { 1, 3, 5, 11, 7, 29, 5, 133, 419, 691, 859, 1089, 4331, 11079, 0 }; + static ulong[] dim1325Kuo3Init = { 1, 1, 1, 1, 5, 57, 113, 17, 481, 989, 233, 1523, 3291, 1665, 0 }; + static ulong[] dim1326Kuo3Init = { 1, 3, 7, 15, 27, 31, 43, 247, 403, 395, 69, 2561, 7281, 7291, 0 }; + static ulong[] dim1327Kuo3Init = { 1, 3, 3, 11, 31, 43, 105, 237, 21, 719, 861, 199, 1045, 7689, 0 }; + static ulong[] dim1328Kuo3Init = { 1, 3, 1, 13, 1, 15, 3, 35, 219, 993, 891, 3649, 3795, 11599, 0 }; + static ulong[] dim1329Kuo3Init = { 1, 3, 7, 7, 7, 15, 125, 243, 449, 173, 1041, 1433, 6559, 14285, 0 }; + static ulong[] dim1330Kuo3Init = { 1, 1, 7, 7, 1, 5, 75, 189, 439, 745, 1361, 3525, 2913, 10513, 0 }; + static ulong[] dim1331Kuo3Init = { 1, 1, 5, 1, 31, 7, 49, 41, 413, 347, 881, 2953, 2173, 8667, 0 }; + static ulong[] dim1332Kuo3Init = { 1, 3, 3, 1, 27, 33, 75, 99, 451, 207, 1847, 1285, 3217, 7899, 0 }; + static ulong[] dim1333Kuo3Init = { 1, 3, 7, 11, 21, 63, 87, 11, 429, 591, 1471, 3221, 2441, 2889, 0 }; + static ulong[] dim1334Kuo3Init = { 1, 3, 1, 15, 3, 47, 103, 219, 317, 605, 1709, 2473, 3511, 10035, 0 }; + static ulong[] dim1335Kuo3Init = { 1, 1, 5, 3, 13, 21, 117, 113, 443, 863, 201, 1293, 1291, 5537, 0 }; + static ulong[] dim1336Kuo3Init = { 1, 1, 7, 7, 3, 15, 59, 45, 135, 465, 1033, 605, 2783, 1001, 0 }; + static ulong[] dim1337Kuo3Init = { 1, 3, 1, 13, 25, 49, 125, 171, 231, 691, 1759, 3493, 1703, 4405, 0 }; + static ulong[] dim1338Kuo3Init = { 1, 1, 5, 11, 3, 31, 73, 31, 189, 533, 1191, 487, 6233, 5607, 0 }; + static ulong[] dim1339Kuo3Init = { 1, 3, 7, 5, 11, 23, 91, 207, 337, 225, 339, 2085, 6223, 16299, 0 }; + static ulong[] dim1340Kuo3Init = { 1, 1, 5, 13, 21, 35, 47, 81, 229, 815, 767, 1939, 1335, 1865, 0 }; + static ulong[] dim1341Kuo3Init = { 1, 1, 5, 9, 3, 11, 19, 253, 499, 13, 1771, 1461, 2339, 1217, 0 }; + static ulong[] dim1342Kuo3Init = { 1, 1, 1, 7, 15, 51, 91, 213, 435, 137, 551, 3483, 1485, 4061, 0 }; + static ulong[] dim1343Kuo3Init = { 1, 3, 3, 9, 23, 25, 57, 1, 147, 705, 399, 3061, 5921, 4201, 0 }; + static ulong[] dim1344Kuo3Init = { 1, 3, 3, 9, 9, 15, 53, 105, 175, 147, 1077, 2323, 6041, 9591, 0 }; + static ulong[] dim1345Kuo3Init = { 1, 1, 5, 9, 5, 17, 125, 243, 5, 329, 161, 795, 8105, 8385, 0 }; + static ulong[] dim1346Kuo3Init = { 1, 3, 1, 13, 9, 7, 83, 49, 83, 109, 759, 2197, 2587, 10715, 0 }; + static ulong[] dim1347Kuo3Init = { 1, 3, 3, 9, 17, 11, 33, 173, 133, 853, 1005, 3027, 2137, 14471, 0 }; + static ulong[] dim1348Kuo3Init = { 1, 3, 7, 9, 23, 19, 29, 169, 73, 405, 1175, 3179, 2449, 13447, 0 }; + static ulong[] dim1349Kuo3Init = { 1, 1, 7, 1, 21, 43, 1, 85, 387, 979, 571, 1849, 3287, 1201, 0 }; + static ulong[] dim1350Kuo3Init = { 1, 1, 5, 13, 15, 43, 125, 49, 365, 689, 1569, 719, 3925, 3781, 0 }; + static ulong[] dim1351Kuo3Init = { 1, 1, 7, 1, 11, 5, 39, 181, 39, 729, 641, 1983, 7321, 14747, 0 }; + static ulong[] dim1352Kuo3Init = { 1, 3, 7, 11, 11, 9, 115, 125, 305, 371, 1647, 463, 2473, 9029, 0 }; + static ulong[] dim1353Kuo3Init = { 1, 1, 7, 15, 5, 11, 69, 177, 249, 235, 1843, 695, 7931, 10891, 0 }; + static ulong[] dim1354Kuo3Init = { 1, 1, 5, 11, 17, 57, 127, 135, 357, 315, 55, 2867, 4187, 15803, 0 }; + static ulong[] dim1355Kuo3Init = { 1, 3, 1, 13, 29, 23, 69, 179, 151, 813, 1317, 1943, 3995, 13023, 0 }; + static ulong[] dim1356Kuo3Init = { 1, 1, 7, 11, 9, 55, 39, 65, 3, 127, 1781, 117, 2651, 16111, 0 }; + static ulong[] dim1357Kuo3Init = { 1, 3, 5, 15, 31, 19, 89, 185, 351, 623, 1301, 3123, 5905, 7231, 0 }; + static ulong[] dim1358Kuo3Init = { 1, 3, 3, 3, 31, 25, 31, 163, 81, 927, 1171, 2667, 5699, 7555, 0 }; + static ulong[] dim1359Kuo3Init = { 1, 1, 3, 13, 17, 55, 83, 217, 97, 795, 1745, 875, 483, 3271, 0 }; + static ulong[] dim1360Kuo3Init = { 1, 1, 1, 1, 9, 13, 19, 207, 325, 277, 1393, 2619, 3055, 8499, 0 }; + static ulong[] dim1361Kuo3Init = { 1, 1, 7, 5, 1, 11, 113, 181, 411, 55, 505, 3125, 619, 1749, 0 }; + static ulong[] dim1362Kuo3Init = { 1, 3, 3, 15, 11, 47, 25, 123, 143, 51, 1075, 715, 4647, 13995, 0 }; + static ulong[] dim1363Kuo3Init = { 1, 1, 1, 1, 21, 23, 121, 217, 325, 589, 2017, 3027, 6175, 1293, 0 }; + static ulong[] dim1364Kuo3Init = { 1, 3, 1, 9, 3, 47, 35, 233, 381, 905, 1031, 2229, 2575, 6891, 0 }; + static ulong[] dim1365Kuo3Init = { 1, 1, 1, 5, 3, 33, 17, 39, 377, 635, 1281, 2673, 2101, 2921, 0 }; + static ulong[] dim1366Kuo3Init = { 1, 1, 7, 7, 13, 21, 43, 55, 353, 643, 533, 57, 5583, 2189, 0 }; + static ulong[] dim1367Kuo3Init = { 1, 3, 5, 3, 27, 15, 79, 47, 463, 327, 1231, 171, 4931, 7549, 0 }; + static ulong[] dim1368Kuo3Init = { 1, 1, 5, 9, 11, 27, 109, 15, 57, 35, 1347, 3061, 8179, 5461, 0 }; + static ulong[] dim1369Kuo3Init = { 1, 3, 3, 7, 29, 57, 103, 221, 409, 437, 1541, 2591, 4757, 13735, 0 }; + static ulong[] dim1370Kuo3Init = { 1, 1, 7, 1, 3, 23, 115, 35, 165, 389, 1399, 2081, 3169, 1493, 0 }; + static ulong[] dim1371Kuo3Init = { 1, 1, 3, 3, 25, 27, 93, 253, 83, 557, 957, 2017, 2005, 10005, 0 }; + static ulong[] dim1372Kuo3Init = { 1, 3, 7, 7, 1, 33, 55, 227, 427, 595, 1235, 3815, 5397, 4827, 0 }; + static ulong[] dim1373Kuo3Init = { 1, 3, 1, 7, 31, 23, 53, 155, 177, 851, 531, 2441, 2049, 12209, 0 }; + static ulong[] dim1374Kuo3Init = { 1, 1, 7, 3, 21, 27, 13, 67, 467, 607, 611, 2565, 5907, 8441, 0 }; + static ulong[] dim1375Kuo3Init = { 1, 1, 7, 5, 31, 59, 99, 65, 403, 439, 1407, 2587, 3111, 8715, 0 }; + static ulong[] dim1376Kuo3Init = { 1, 1, 5, 13, 7, 3, 35, 69, 177, 591, 449, 369, 5047, 3435, 0 }; + static ulong[] dim1377Kuo3Init = { 1, 3, 5, 5, 17, 27, 9, 49, 161, 925, 603, 2555, 3349, 4913, 0 }; + static ulong[] dim1378Kuo3Init = { 1, 1, 1, 9, 11, 43, 89, 139, 163, 851, 1991, 3439, 227, 5875, 0 }; + static ulong[] dim1379Kuo3Init = { 1, 3, 3, 9, 15, 7, 63, 133, 437, 447, 1227, 3945, 3467, 14919, 0 }; + static ulong[] dim1380Kuo3Init = { 1, 1, 1, 7, 13, 49, 113, 39, 77, 773, 127, 3361, 2325, 987, 0 }; + static ulong[] dim1381Kuo3Init = { 1, 1, 5, 9, 31, 23, 69, 203, 189, 35, 647, 3507, 6679, 2097, 0 }; + static ulong[] dim1382Kuo3Init = { 1, 3, 7, 5, 23, 9, 99, 253, 203, 167, 1073, 435, 1745, 2155, 0 }; + static ulong[] dim1383Kuo3Init = { 1, 1, 5, 11, 11, 27, 15, 125, 291, 261, 1953, 3695, 6345, 8519, 0 }; + static ulong[] dim1384Kuo3Init = { 1, 1, 7, 11, 3, 39, 23, 143, 401, 587, 1729, 3083, 4255, 7427, 0 }; + static ulong[] dim1385Kuo3Init = { 1, 1, 7, 9, 27, 7, 63, 153, 349, 1003, 1315, 841, 5991, 15647, 0 }; + static ulong[] dim1386Kuo3Init = { 1, 3, 5, 1, 27, 45, 91, 245, 297, 485, 647, 91, 231, 5231, 0 }; + static ulong[] dim1387Kuo3Init = { 1, 1, 5, 15, 29, 43, 53, 79, 387, 977, 247, 371, 5823, 8335, 0 }; + static ulong[] dim1388Kuo3Init = { 1, 3, 3, 5, 5, 17, 29, 71, 417, 201, 1495, 277, 2087, 15421, 0 }; + static ulong[] dim1389Kuo3Init = { 1, 3, 5, 11, 7, 47, 37, 171, 167, 355, 1845, 1747, 839, 7213, 0 }; + static ulong[] dim1390Kuo3Init = { 1, 1, 3, 15, 15, 29, 107, 35, 183, 735, 183, 2993, 6495, 981, 0 }; + static ulong[] dim1391Kuo3Init = { 1, 3, 1, 3, 3, 25, 25, 195, 461, 739, 861, 3027, 2007, 7771, 0 }; + static ulong[] dim1392Kuo3Init = { 1, 3, 7, 5, 29, 55, 115, 57, 67, 913, 1603, 2397, 949, 14671, 0 }; + static ulong[] dim1393Kuo3Init = { 1, 1, 1, 7, 27, 15, 51, 201, 127, 459, 1545, 3415, 1823, 1673, 0 }; + static ulong[] dim1394Kuo3Init = { 1, 3, 1, 13, 21, 43, 75, 59, 379, 1007, 1697, 763, 741, 3801, 0 }; + static ulong[] dim1395Kuo3Init = { 1, 1, 5, 13, 13, 41, 105, 235, 381, 465, 665, 877, 1025, 9041, 0 }; + static ulong[] dim1396Kuo3Init = { 1, 3, 3, 3, 3, 63, 65, 151, 167, 683, 327, 3545, 2531, 13479, 0 }; + static ulong[] dim1397Kuo3Init = { 1, 3, 5, 1, 7, 25, 61, 137, 155, 5, 623, 649, 7235, 13495, 0 }; + static ulong[] dim1398Kuo3Init = { 1, 3, 5, 1, 23, 33, 3, 45, 235, 909, 1619, 2843, 5307, 14345, 0 }; + static ulong[] dim1399Kuo3Init = { 1, 3, 3, 3, 29, 1, 67, 161, 237, 229, 1403, 3289, 399, 237, 0 }; + static ulong[] dim1400Kuo3Init = { 1, 3, 1, 7, 5, 27, 83, 133, 189, 277, 1975, 1399, 65, 13645, 0 }; + static ulong[] dim1401Kuo3Init = { 1, 3, 3, 9, 1, 41, 11, 121, 413, 413, 1817, 1533, 5299, 9089, 0 }; + static ulong[] dim1402Kuo3Init = { 1, 1, 1, 7, 15, 59, 75, 255, 419, 441, 1993, 573, 6025, 16375, 0 }; + static ulong[] dim1403Kuo3Init = { 1, 1, 1, 9, 3, 35, 117, 69, 473, 53, 1007, 2229, 1749, 14795, 0 }; + static ulong[] dim1404Kuo3Init = { 1, 1, 3, 11, 23, 27, 117, 183, 69, 689, 1903, 1851, 1143, 11959, 0 }; + static ulong[] dim1405Kuo3Init = { 1, 3, 7, 13, 3, 9, 125, 173, 365, 393, 1313, 3937, 1699, 15667, 0 }; + static ulong[] dim1406Kuo3Init = { 1, 3, 5, 11, 19, 3, 45, 181, 439, 61, 1139, 149, 1929, 15617, 0 }; + static ulong[] dim1407Kuo3Init = { 1, 3, 7, 1, 13, 41, 43, 131, 79, 947, 1579, 2055, 451, 10875, 0 }; + static ulong[] dim1408Kuo3Init = { 1, 1, 1, 11, 27, 11, 105, 109, 503, 361, 27, 133, 801, 853, 0 }; + static ulong[] dim1409Kuo3Init = { 1, 3, 5, 11, 11, 43, 3, 233, 449, 557, 2003, 467, 5617, 7431, 0 }; + static ulong[] dim1410Kuo3Init = { 1, 1, 3, 9, 5, 31, 121, 13, 301, 433, 1719, 821, 8107, 13313, 0 }; + static ulong[] dim1411Kuo3Init = { 1, 1, 5, 15, 25, 17, 117, 81, 239, 219, 195, 2653, 1287, 11595, 0 }; + static ulong[] dim1412Kuo3Init = { 1, 1, 3, 9, 31, 37, 123, 35, 507, 91, 1345, 279, 2369, 1613, 0 }; + static ulong[] dim1413Kuo3Init = { 1, 3, 3, 11, 23, 9, 83, 91, 257, 977, 697, 3813, 6839, 2755, 0 }; + static ulong[] dim1414Kuo3Init = { 1, 3, 5, 5, 21, 23, 65, 63, 407, 515, 1817, 2893, 7539, 11803, 0 }; + static ulong[] dim1415Kuo3Init = { 1, 3, 1, 15, 5, 1, 7, 195, 15, 319, 1177, 3191, 3489, 6213, 0 }; + static ulong[] dim1416Kuo3Init = { 1, 1, 7, 5, 29, 11, 97, 125, 89, 1005, 455, 3397, 7345, 14481, 0 }; + static ulong[] dim1417Kuo3Init = { 1, 1, 5, 11, 31, 37, 15, 35, 405, 181, 601, 543, 6639, 16103, 0 }; + static ulong[] dim1418Kuo3Init = { 1, 3, 3, 1, 1, 33, 127, 177, 277, 681, 2039, 3109, 4657, 1303, 0 }; + static ulong[] dim1419Kuo3Init = { 1, 1, 5, 7, 3, 61, 107, 215, 175, 973, 899, 3655, 823, 7125, 0 }; + static ulong[] dim1420Kuo3Init = { 1, 1, 3, 1, 3, 47, 87, 179, 387, 987, 1171, 2767, 6329, 609, 0 }; + static ulong[] dim1421Kuo3Init = { 1, 3, 3, 11, 7, 25, 33, 109, 485, 789, 979, 659, 2555, 10175, 0 }; + static ulong[] dim1422Kuo3Init = { 1, 1, 5, 7, 15, 41, 77, 69, 487, 601, 753, 2785, 1075, 35, 0 }; + static ulong[] dim1423Kuo3Init = { 1, 1, 1, 7, 23, 3, 125, 143, 463, 981, 499, 1249, 5461, 43, 0 }; + static ulong[] dim1424Kuo3Init = { 1, 1, 5, 11, 9, 1, 55, 147, 85, 857, 1995, 3471, 6115, 5511, 0 }; + static ulong[] dim1425Kuo3Init = { 1, 3, 3, 11, 11, 25, 27, 201, 497, 533, 643, 2015, 205, 13535, 0 }; + static ulong[] dim1426Kuo3Init = { 1, 3, 3, 3, 23, 53, 77, 143, 231, 335, 471, 1821, 739, 4727, 0 }; + static ulong[] dim1427Kuo3Init = { 1, 3, 1, 3, 13, 25, 53, 61, 155, 1013, 1439, 1745, 6393, 13329, 0 }; + static ulong[] dim1428Kuo3Init = { 1, 3, 7, 1, 5, 11, 111, 21, 357, 599, 1213, 3581, 1221, 75, 0 }; + static ulong[] dim1429Kuo3Init = { 1, 3, 7, 7, 23, 45, 79, 83, 97, 191, 53, 2157, 7737, 1533, 0 }; + static ulong[] dim1430Kuo3Init = { 1, 3, 1, 9, 25, 17, 123, 179, 151, 77, 1903, 1457, 1403, 13557, 0 }; + static ulong[] dim1431Kuo3Init = { 1, 3, 3, 1, 23, 59, 65, 47, 119, 113, 133, 3601, 7543, 16289, 0 }; + static ulong[] dim1432Kuo3Init = { 1, 3, 5, 13, 17, 51, 33, 39, 257, 409, 659, 3907, 7301, 8893, 0 }; + static ulong[] dim1433Kuo3Init = { 1, 1, 7, 11, 31, 25, 79, 245, 465, 809, 1317, 1109, 5983, 4359, 0 }; + static ulong[] dim1434Kuo3Init = { 1, 1, 7, 7, 5, 25, 83, 239, 199, 497, 521, 1527, 4509, 12627, 0 }; + static ulong[] dim1435Kuo3Init = { 1, 1, 1, 11, 25, 33, 97, 171, 443, 75, 1681, 407, 7669, 14893, 0 }; + static ulong[] dim1436Kuo3Init = { 1, 1, 3, 13, 17, 31, 53, 113, 97, 653, 917, 11, 5697, 8083, 0 }; + static ulong[] dim1437Kuo3Init = { 1, 1, 3, 9, 19, 27, 1, 155, 89, 579, 951, 1779, 343, 12053, 0 }; + static ulong[] dim1438Kuo3Init = { 1, 3, 7, 7, 23, 29, 33, 143, 181, 25, 109, 3407, 3255, 15363, 0 }; + static ulong[] dim1439Kuo3Init = { 1, 3, 3, 7, 5, 47, 119, 111, 315, 225, 1655, 3019, 4835, 11641, 0 }; + static ulong[] dim1440Kuo3Init = { 1, 1, 7, 1, 19, 51, 103, 219, 233, 633, 1923, 1523, 467, 15363, 0 }; + static ulong[] dim1441Kuo3Init = { 1, 1, 3, 3, 11, 5, 125, 143, 277, 5, 1597, 2445, 4261, 12449, 0 }; + static ulong[] dim1442Kuo3Init = { 1, 3, 1, 1, 7, 1, 103, 63, 23, 65, 1449, 3097, 601, 12563, 0 }; + static ulong[] dim1443Kuo3Init = { 1, 1, 7, 13, 31, 51, 23, 251, 193, 227, 1569, 439, 1037, 8013, 0 }; + static ulong[] dim1444Kuo3Init = { 1, 3, 5, 5, 17, 9, 45, 241, 197, 787, 555, 1951, 2697, 725, 0 }; + static ulong[] dim1445Kuo3Init = { 1, 3, 5, 15, 9, 43, 1, 211, 51, 645, 1977, 3085, 4003, 10331, 0 }; + static ulong[] dim1446Kuo3Init = { 1, 1, 3, 11, 7, 31, 89, 209, 505, 753, 641, 3177, 2791, 10727, 0 }; + static ulong[] dim1447Kuo3Init = { 1, 3, 1, 1, 31, 13, 53, 223, 435, 51, 571, 2033, 1689, 67, 0 }; + static ulong[] dim1448Kuo3Init = { 1, 3, 1, 3, 21, 55, 19, 31, 273, 175, 1657, 3399, 3031, 10271, 0 }; + static ulong[] dim1449Kuo3Init = { 1, 1, 7, 9, 27, 51, 87, 157, 395, 57, 1501, 2547, 5061, 11325, 0 }; + static ulong[] dim1450Kuo3Init = { 1, 1, 1, 9, 19, 43, 55, 147, 193, 531, 511, 4019, 2317, 3727, 0 }; + static ulong[] dim1451Kuo3Init = { 1, 1, 1, 15, 1, 15, 5, 157, 335, 183, 619, 2483, 5817, 3247, 0 }; + static ulong[] dim1452Kuo3Init = { 1, 1, 1, 3, 29, 59, 27, 27, 355, 315, 193, 707, 5897, 4623, 0 }; + static ulong[] dim1453Kuo3Init = { 1, 1, 7, 1, 23, 29, 33, 123, 413, 317, 1099, 1633, 1619, 9141, 0 }; + static ulong[] dim1454Kuo3Init = { 1, 1, 5, 11, 11, 49, 85, 95, 73, 829, 929, 2013, 4653, 3045, 0 }; + static ulong[] dim1455Kuo3Init = { 1, 1, 1, 13, 5, 63, 81, 177, 23, 455, 1527, 2271, 2523, 3711, 0 }; + static ulong[] dim1456Kuo3Init = { 1, 3, 3, 13, 9, 13, 1, 241, 225, 191, 933, 657, 4557, 6903, 0 }; + static ulong[] dim1457Kuo3Init = { 1, 3, 3, 15, 19, 29, 121, 3, 235, 729, 1705, 4035, 5429, 15339, 0 }; + static ulong[] dim1458Kuo3Init = { 1, 1, 7, 5, 3, 63, 79, 89, 363, 407, 325, 3045, 7761, 8855, 0 }; + static ulong[] dim1459Kuo3Init = { 1, 3, 3, 1, 13, 39, 69, 119, 45, 259, 577, 269, 2977, 2093, 0 }; + static ulong[] dim1460Kuo3Init = { 1, 3, 3, 3, 5, 9, 115, 161, 319, 799, 777, 459, 1823, 10971, 0 }; + static ulong[] dim1461Kuo3Init = { 1, 3, 7, 9, 1, 45, 31, 223, 421, 389, 1535, 1701, 3739, 9301, 0 }; + static ulong[] dim1462Kuo3Init = { 1, 3, 5, 5, 5, 49, 53, 189, 101, 475, 453, 1921, 7161, 4529, 0 }; + static ulong[] dim1463Kuo3Init = { 1, 3, 5, 11, 29, 37, 53, 213, 371, 985, 647, 765, 6303, 10947, 0 }; + static ulong[] dim1464Kuo3Init = { 1, 3, 3, 15, 5, 23, 51, 199, 463, 11, 709, 2083, 6337, 1115, 0 }; + static ulong[] dim1465Kuo3Init = { 1, 1, 1, 1, 17, 57, 1, 91, 159, 1013, 1229, 2147, 571, 335, 0 }; + static ulong[] dim1466Kuo3Init = { 1, 3, 1, 11, 21, 53, 119, 221, 203, 467, 845, 645, 7939, 7257, 0 }; + static ulong[] dim1467Kuo3Init = { 1, 1, 5, 1, 9, 45, 87, 213, 483, 247, 1423, 1855, 583, 13339, 0 }; + static ulong[] dim1468Kuo3Init = { 1, 1, 3, 7, 13, 39, 89, 87, 467, 107, 185, 1507, 755, 12069, 0 }; + static ulong[] dim1469Kuo3Init = { 1, 1, 5, 5, 5, 49, 17, 61, 483, 877, 1887, 2973, 6733, 3241, 0 }; + static ulong[] dim1470Kuo3Init = { 1, 1, 7, 15, 31, 25, 105, 215, 449, 723, 973, 4011, 1079, 9713, 0 }; + static ulong[] dim1471Kuo3Init = { 1, 3, 3, 5, 23, 61, 9, 85, 323, 675, 101, 2451, 5441, 14371, 0 }; + static ulong[] dim1472Kuo3Init = { 1, 1, 5, 9, 1, 47, 109, 177, 279, 675, 867, 2053, 6975, 4829, 0 }; + static ulong[] dim1473Kuo3Init = { 1, 3, 5, 15, 23, 15, 17, 49, 273, 839, 779, 3899, 3775, 4289, 0 }; + static ulong[] dim1474Kuo3Init = { 1, 3, 3, 13, 3, 5, 9, 83, 291, 727, 2041, 2221, 979, 761, 0 }; + static ulong[] dim1475Kuo3Init = { 1, 1, 5, 5, 7, 5, 23, 187, 293, 159, 847, 697, 7227, 9549, 0 }; + static ulong[] dim1476Kuo3Init = { 1, 3, 5, 7, 19, 7, 77, 57, 225, 443, 539, 1531, 857, 12997, 0 }; + static ulong[] dim1477Kuo3Init = { 1, 3, 3, 9, 9, 33, 79, 137, 15, 927, 1621, 1241, 5741, 13507, 0 }; + static ulong[] dim1478Kuo3Init = { 1, 3, 7, 7, 11, 37, 87, 255, 293, 649, 393, 2549, 8083, 13417, 0 }; + static ulong[] dim1479Kuo3Init = { 1, 1, 3, 5, 19, 31, 47, 243, 423, 663, 359, 3293, 7915, 16351, 0 }; + static ulong[] dim1480Kuo3Init = { 1, 1, 1, 11, 19, 63, 87, 245, 445, 975, 1047, 935, 4221, 851, 0 }; + static ulong[] dim1481Kuo3Init = { 1, 3, 5, 1, 19, 43, 11, 85, 257, 875, 369, 1075, 1343, 8487, 0 }; + static ulong[] dim1482Kuo3Init = { 1, 1, 7, 13, 29, 35, 37, 201, 473, 853, 185, 3157, 6135, 7631, 0 }; + static ulong[] dim1483Kuo3Init = { 1, 1, 1, 13, 13, 53, 43, 55, 65, 999, 729, 857, 3645, 9793, 0 }; + static ulong[] dim1484Kuo3Init = { 1, 1, 3, 13, 21, 47, 85, 19, 1, 333, 989, 327, 4693, 3521, 0 }; + static ulong[] dim1485Kuo3Init = { 1, 3, 1, 13, 11, 39, 101, 209, 51, 53, 631, 1439, 5909, 9599, 0 }; + static ulong[] dim1486Kuo3Init = { 1, 1, 7, 15, 29, 57, 21, 181, 293, 807, 1299, 1001, 4265, 1811, 0 }; + static ulong[] dim1487Kuo3Init = { 1, 1, 5, 13, 15, 1, 17, 63, 213, 85, 1025, 3955, 2371, 9065, 0 }; + static ulong[] dim1488Kuo3Init = { 1, 1, 5, 15, 13, 57, 23, 169, 93, 501, 7, 2481, 123, 8985, 0 }; + static ulong[] dim1489Kuo3Init = { 1, 3, 3, 3, 11, 61, 19, 133, 175, 833, 1753, 3871, 8169, 2771, 0 }; + static ulong[] dim1490Kuo3Init = { 1, 3, 5, 1, 11, 13, 57, 55, 385, 463, 785, 2339, 7117, 12519, 0 }; + static ulong[] dim1491Kuo3Init = { 1, 1, 1, 13, 15, 35, 27, 179, 375, 477, 1157, 2067, 6971, 8269, 0 }; + static ulong[] dim1492Kuo3Init = { 1, 1, 3, 11, 27, 21, 57, 125, 219, 433, 67, 307, 7327, 2915, 0 }; + static ulong[] dim1493Kuo3Init = { 1, 3, 5, 7, 21, 7, 111, 21, 85, 295, 1751, 821, 1175, 3109, 0 }; + static ulong[] dim1494Kuo3Init = { 1, 1, 7, 1, 7, 51, 43, 119, 89, 751, 835, 3969, 861, 5775, 0 }; + static ulong[] dim1495Kuo3Init = { 1, 3, 1, 13, 5, 37, 93, 185, 435, 283, 1221, 2965, 2845, 6025, 0 }; + static ulong[] dim1496Kuo3Init = { 1, 1, 7, 7, 31, 27, 99, 143, 507, 461, 1999, 3743, 4277, 13729, 0 }; + static ulong[] dim1497Kuo3Init = { 1, 3, 1, 13, 15, 43, 99, 121, 245, 73, 829, 3887, 3093, 16183, 0 }; + static ulong[] dim1498Kuo3Init = { 1, 3, 3, 7, 15, 35, 29, 79, 457, 695, 1469, 1505, 3891, 14677, 0 }; + static ulong[] dim1499Kuo3Init = { 1, 3, 7, 7, 5, 59, 71, 179, 305, 9, 2043, 245, 1291, 14409, 0 }; + static ulong[] dim1500Kuo3Init = { 1, 1, 3, 1, 13, 7, 17, 43, 367, 163, 1649, 3671, 2663, 2277, 0 }; + static ulong[] dim1501Kuo3Init = { 1, 1, 1, 5, 9, 57, 115, 177, 271, 735, 263, 1137, 2127, 15367, 0 }; + static ulong[] dim1502Kuo3Init = { 1, 3, 5, 7, 17, 11, 37, 197, 459, 647, 307, 3617, 3201, 10293, 0 }; + static ulong[] dim1503Kuo3Init = { 1, 1, 1, 7, 31, 37, 61, 59, 331, 483, 1849, 1737, 2617, 5053, 0 }; + static ulong[] dim1504Kuo3Init = { 1, 3, 5, 13, 31, 43, 31, 185, 261, 249, 1137, 1285, 2885, 4289, 0 }; + static ulong[] dim1505Kuo3Init = { 1, 1, 7, 3, 21, 53, 113, 163, 209, 25, 329, 2963, 7849, 10933, 0 }; + static ulong[] dim1506Kuo3Init = { 1, 1, 5, 1, 31, 23, 101, 151, 173, 193, 1267, 487, 4701, 8543, 0 }; + static ulong[] dim1507Kuo3Init = { 1, 1, 1, 1, 25, 33, 85, 31, 433, 537, 613, 1675, 6997, 11975, 0 }; + static ulong[] dim1508Kuo3Init = { 1, 3, 7, 1, 7, 59, 57, 249, 511, 371, 121, 3435, 8029, 11785, 0 }; + static ulong[] dim1509Kuo3Init = { 1, 1, 7, 3, 19, 61, 105, 27, 217, 47, 861, 2571, 6203, 805, 0 }; + static ulong[] dim1510Kuo3Init = { 1, 1, 7, 13, 27, 33, 41, 217, 39, 917, 355, 3083, 2803, 747, 0 }; + static ulong[] dim1511Kuo3Init = { 1, 3, 7, 3, 23, 33, 43, 27, 151, 399, 1307, 3269, 7941, 195, 0 }; + static ulong[] dim1512Kuo3Init = { 1, 1, 3, 3, 3, 37, 71, 111, 389, 13, 1147, 3649, 1497, 10459, 0 }; + static ulong[] dim1513Kuo3Init = { 1, 1, 5, 5, 25, 23, 19, 251, 87, 347, 711, 3379, 4677, 5651, 0 }; + static ulong[] dim1514Kuo3Init = { 1, 1, 5, 3, 9, 21, 51, 85, 491, 67, 485, 2099, 3081, 11751, 0 }; + static ulong[] dim1515Kuo3Init = { 1, 1, 3, 15, 27, 37, 75, 71, 41, 823, 1035, 133, 7537, 129, 0 }; + static ulong[] dim1516Kuo3Init = { 1, 1, 1, 7, 31, 35, 75, 223, 379, 395, 2011, 1403, 4923, 391, 0 }; + static ulong[] dim1517Kuo3Init = { 1, 1, 5, 1, 19, 37, 87, 109, 291, 73, 355, 1427, 741, 7393, 0 }; + static ulong[] dim1518Kuo3Init = { 1, 3, 3, 11, 23, 1, 109, 81, 319, 1001, 1173, 2529, 5859, 3167, 0 }; + static ulong[] dim1519Kuo3Init = { 1, 1, 1, 7, 17, 23, 121, 223, 49, 203, 1653, 1567, 7795, 1631, 0 }; + static ulong[] dim1520Kuo3Init = { 1, 3, 1, 15, 15, 61, 123, 141, 127, 871, 897, 533, 231, 13767, 0 }; + static ulong[] dim1521Kuo3Init = { 1, 3, 5, 15, 5, 17, 31, 5, 505, 65, 587, 3721, 5755, 3865, 0 }; + static ulong[] dim1522Kuo3Init = { 1, 1, 7, 11, 27, 59, 17, 17, 33, 399, 1963, 3135, 5807, 2427, 0 }; + static ulong[] dim1523Kuo3Init = { 1, 3, 1, 3, 29, 19, 77, 55, 511, 569, 729, 2893, 373, 643, 0 }; + static ulong[] dim1524Kuo3Init = { 1, 1, 5, 13, 17, 17, 101, 107, 449, 581, 905, 3281, 4487, 9397, 0 }; + static ulong[] dim1525Kuo3Init = { 1, 1, 7, 9, 23, 3, 103, 29, 291, 437, 1417, 2289, 3705, 14439, 0 }; + static ulong[] dim1526Kuo3Init = { 1, 3, 1, 13, 11, 61, 7, 87, 471, 707, 1823, 3971, 7255, 14395, 0 }; + static ulong[] dim1527Kuo3Init = { 1, 3, 7, 13, 21, 25, 125, 19, 221, 885, 1787, 3825, 7661, 8839, 0 }; + static ulong[] dim1528Kuo3Init = { 1, 3, 5, 3, 29, 39, 21, 47, 475, 447, 405, 3365, 5545, 11759, 0 }; + static ulong[] dim1529Kuo3Init = { 1, 1, 7, 1, 13, 11, 113, 123, 411, 385, 533, 4091, 6451, 6021, 0 }; + static ulong[] dim1530Kuo3Init = { 1, 1, 3, 11, 7, 7, 25, 65, 105, 409, 1837, 2609, 6417, 16111, 0 }; + static ulong[] dim1531Kuo3Init = { 1, 3, 7, 15, 25, 11, 101, 151, 91, 305, 865, 2653, 3031, 2295, 0 }; + static ulong[] dim1532Kuo3Init = { 1, 1, 1, 15, 11, 53, 87, 203, 275, 915, 281, 687, 5857, 393, 0 }; + static ulong[] dim1533Kuo3Init = { 1, 3, 3, 5, 15, 11, 97, 169, 175, 325, 285, 2287, 7095, 5245, 0 }; + static ulong[] dim1534Kuo3Init = { 1, 1, 5, 13, 25, 3, 31, 79, 49, 637, 1927, 2361, 2233, 7935, 0 }; + static ulong[] dim1535Kuo3Init = { 1, 1, 3, 11, 17, 41, 69, 9, 441, 719, 765, 689, 475, 8613, 0 }; + static ulong[] dim1536Kuo3Init = { 1, 1, 7, 1, 9, 11, 51, 175, 231, 975, 1983, 1389, 205, 5051, 0 }; + static ulong[] dim1537Kuo3Init = { 1, 1, 3, 7, 17, 37, 9, 193, 243, 331, 1545, 3905, 4601, 7731, 0 }; + static ulong[] dim1538Kuo3Init = { 1, 1, 5, 9, 9, 41, 27, 29, 231, 775, 1753, 1915, 7247, 6821, 0 }; + static ulong[] dim1539Kuo3Init = { 1, 3, 7, 13, 21, 9, 51, 165, 313, 951, 1897, 2123, 2999, 3171, 0 }; + static ulong[] dim1540Kuo3Init = { 1, 1, 1, 11, 25, 43, 81, 249, 309, 523, 373, 3293, 6607, 9495, 0 }; + static ulong[] dim1541Kuo3Init = { 1, 1, 3, 1, 15, 63, 11, 139, 319, 665, 1703, 1669, 4817, 3645, 0 }; + static ulong[] dim1542Kuo3Init = { 1, 1, 7, 1, 11, 47, 117, 245, 251, 341, 415, 815, 7335, 14297, 0 }; + static ulong[] dim1543Kuo3Init = { 1, 1, 5, 13, 19, 33, 109, 191, 253, 867, 1505, 2629, 6619, 7913, 0 }; + static ulong[] dim1544Kuo3Init = { 1, 3, 5, 1, 7, 49, 53, 51, 285, 25, 1783, 2201, 7603, 11365, 0 }; + static ulong[] dim1545Kuo3Init = { 1, 1, 3, 11, 1, 49, 9, 89, 365, 909, 1563, 2719, 6859, 14135, 0 }; + static ulong[] dim1546Kuo3Init = { 1, 1, 1, 11, 17, 57, 21, 165, 419, 443, 1207, 3821, 1151, 14037, 0 }; + static ulong[] dim1547Kuo3Init = { 1, 1, 1, 3, 1, 31, 97, 133, 423, 993, 745, 3559, 7725, 2069, 0 }; + static ulong[] dim1548Kuo3Init = { 1, 1, 1, 7, 31, 1, 65, 3, 63, 255, 313, 515, 455, 4957, 0 }; + static ulong[] dim1549Kuo3Init = { 1, 1, 1, 5, 5, 31, 37, 121, 201, 493, 55, 3735, 5019, 5665, 0 }; + static ulong[] dim1550Kuo3Init = { 1, 3, 3, 9, 9, 57, 55, 155, 171, 687, 1415, 2017, 7021, 7409, 0 }; + static ulong[] dim1551Kuo3Init = { 1, 3, 5, 3, 15, 23, 83, 79, 367, 485, 1933, 315, 2591, 7609, 0 }; + static ulong[] dim1552Kuo3Init = { 1, 3, 7, 3, 25, 49, 79, 15, 435, 809, 265, 2215, 7207, 563, 0 }; + static ulong[] dim1553Kuo3Init = { 1, 3, 7, 1, 19, 61, 103, 101, 51, 637, 639, 55, 4323, 179, 0 }; + static ulong[] dim1554Kuo3Init = { 1, 3, 1, 3, 23, 27, 33, 79, 215, 849, 331, 2881, 2109, 10309, 0 }; + static ulong[] dim1555Kuo3Init = { 1, 3, 5, 7, 21, 63, 113, 237, 63, 769, 63, 391, 1433, 6913, 0 }; + static ulong[] dim1556Kuo3Init = { 1, 3, 3, 15, 3, 53, 25, 187, 313, 93, 1499, 3281, 557, 12441, 0 }; + static ulong[] dim1557Kuo3Init = { 1, 1, 1, 5, 7, 27, 97, 211, 5, 31, 497, 1659, 7061, 807, 0 }; + static ulong[] dim1558Kuo3Init = { 1, 3, 1, 9, 23, 3, 39, 55, 369, 197, 299, 2529, 2703, 247, 0 }; + static ulong[] dim1559Kuo3Init = { 1, 3, 3, 3, 15, 49, 119, 241, 45, 303, 1741, 1077, 6735, 8079, 0 }; + static ulong[] dim1560Kuo3Init = { 1, 3, 5, 5, 21, 55, 91, 17, 341, 123, 1389, 2557, 3667, 4891, 0 }; + static ulong[] dim1561Kuo3Init = { 1, 1, 7, 5, 27, 21, 107, 111, 85, 39, 863, 1965, 5173, 49, 0 }; + static ulong[] dim1562Kuo3Init = { 1, 1, 1, 5, 11, 5, 15, 185, 269, 711, 557, 2021, 7481, 4977, 0 }; + static ulong[] dim1563Kuo3Init = { 1, 1, 5, 9, 5, 1, 93, 139, 323, 915, 549, 1345, 6031, 3979, 0 }; + static ulong[] dim1564Kuo3Init = { 1, 3, 3, 7, 19, 9, 57, 177, 135, 65, 27, 795, 4637, 11977, 0 }; + static ulong[] dim1565Kuo3Init = { 1, 3, 5, 13, 7, 17, 117, 35, 257, 671, 1741, 1993, 1887, 8149, 0 }; + static ulong[] dim1566Kuo3Init = { 1, 1, 7, 13, 3, 45, 5, 199, 29, 227, 1613, 835, 2451, 13079, 0 }; + static ulong[] dim1567Kuo3Init = { 1, 1, 5, 15, 23, 45, 87, 15, 349, 843, 159, 3283, 1017, 15813, 0 }; + static ulong[] dim1568Kuo3Init = { 1, 3, 3, 3, 21, 21, 31, 51, 481, 49, 1561, 2171, 6025, 9955, 0 }; + static ulong[] dim1569Kuo3Init = { 1, 1, 1, 3, 7, 51, 97, 195, 5, 251, 1509, 1479, 1165, 16375, 0 }; + static ulong[] dim1570Kuo3Init = { 1, 3, 5, 7, 7, 17, 43, 101, 281, 807, 2003, 2821, 6877, 2457, 0 }; + static ulong[] dim1571Kuo3Init = { 1, 1, 1, 1, 15, 23, 59, 91, 19, 933, 145, 673, 4729, 10369, 0 }; + static ulong[] dim1572Kuo3Init = { 1, 3, 5, 13, 31, 37, 9, 219, 343, 907, 1401, 213, 5149, 14171, 0 }; + static ulong[] dim1573Kuo3Init = { 1, 3, 1, 3, 17, 17, 61, 181, 281, 707, 113, 3595, 67, 15423, 0 }; + static ulong[] dim1574Kuo3Init = { 1, 1, 5, 9, 3, 51, 69, 93, 375, 451, 1181, 1353, 939, 629, 0 }; + static ulong[] dim1575Kuo3Init = { 1, 3, 5, 11, 13, 33, 113, 85, 397, 823, 1513, 283, 7167, 4627, 0 }; + static ulong[] dim1576Kuo3Init = { 1, 3, 7, 9, 25, 31, 5, 17, 377, 429, 1841, 3915, 6023, 11791, 0 }; + static ulong[] dim1577Kuo3Init = { 1, 1, 1, 7, 15, 35, 45, 31, 427, 509, 1827, 1171, 7001, 6419, 0 }; + static ulong[] dim1578Kuo3Init = { 1, 1, 5, 5, 7, 37, 41, 35, 349, 73, 171, 35, 2333, 659, 0 }; + static ulong[] dim1579Kuo3Init = { 1, 1, 5, 15, 13, 61, 53, 87, 463, 143, 257, 3151, 6149, 10155, 0 }; + static ulong[] dim1580Kuo3Init = { 1, 1, 3, 9, 3, 17, 29, 151, 259, 881, 2003, 1057, 1867, 7773, 0 }; + static ulong[] dim1581Kuo3Init = { 1, 3, 3, 1, 5, 55, 97, 49, 473, 795, 1545, 1169, 187, 10475, 0 }; + static ulong[] dim1582Kuo3Init = { 1, 1, 3, 7, 9, 11, 61, 205, 71, 183, 1551, 621, 5715, 3401, 0 }; + static ulong[] dim1583Kuo3Init = { 1, 3, 7, 13, 25, 41, 109, 211, 189, 859, 1681, 3281, 8153, 13303, 0 }; + static ulong[] dim1584Kuo3Init = { 1, 1, 5, 3, 13, 17, 81, 151, 189, 419, 1707, 235, 355, 8295, 0 }; + static ulong[] dim1585Kuo3Init = { 1, 3, 3, 13, 19, 33, 49, 249, 347, 617, 2037, 537, 755, 5131, 0 }; + static ulong[] dim1586Kuo3Init = { 1, 1, 1, 13, 23, 17, 93, 35, 357, 523, 355, 1159, 1329, 7663, 0 }; + static ulong[] dim1587Kuo3Init = { 1, 1, 5, 15, 15, 17, 81, 197, 479, 405, 55, 4095, 4931, 7663, 0 }; + static ulong[] dim1588Kuo3Init = { 1, 3, 5, 13, 1, 1, 17, 173, 259, 191, 1929, 2063, 6623, 5065, 0 }; + static ulong[] dim1589Kuo3Init = { 1, 3, 5, 15, 31, 21, 25, 33, 233, 663, 1687, 495, 5223, 439, 0 }; + static ulong[] dim1590Kuo3Init = { 1, 3, 3, 5, 31, 47, 43, 119, 491, 893, 1513, 2453, 6131, 8675, 0 }; + static ulong[] dim1591Kuo3Init = { 1, 3, 5, 1, 21, 51, 21, 27, 35, 613, 849, 3679, 4089, 9671, 0 }; + static ulong[] dim1592Kuo3Init = { 1, 1, 3, 5, 29, 53, 125, 223, 415, 315, 811, 513, 4833, 10667, 0 }; + static ulong[] dim1593Kuo3Init = { 1, 1, 7, 11, 5, 49, 87, 47, 85, 115, 757, 567, 3655, 4009, 0 }; + static ulong[] dim1594Kuo3Init = { 1, 3, 1, 3, 9, 1, 65, 179, 55, 545, 467, 1615, 4349, 14745, 0 }; + static ulong[] dim1595Kuo3Init = { 1, 3, 3, 13, 7, 49, 91, 133, 151, 113, 1373, 203, 2711, 8045, 0 }; + static ulong[] dim1596Kuo3Init = { 1, 1, 3, 13, 13, 5, 53, 181, 397, 309, 1653, 2987, 175, 13419, 0 }; + static ulong[] dim1597Kuo3Init = { 1, 1, 7, 13, 19, 35, 17, 177, 77, 1011, 1667, 3083, 7977, 14925, 0 }; + static ulong[] dim1598Kuo3Init = { 1, 1, 3, 15, 25, 33, 59, 21, 345, 395, 1575, 2173, 159, 11799, 0 }; + static ulong[] dim1599Kuo3Init = { 1, 3, 1, 13, 3, 19, 87, 135, 227, 995, 1965, 3469, 3801, 1979, 0 }; + static ulong[] dim1600Kuo3Init = { 1, 1, 1, 15, 11, 1, 51, 235, 37, 695, 1761, 275, 5793, 4897, 0 }; + static ulong[] dim1601Kuo3Init = { 1, 1, 7, 5, 13, 37, 123, 23, 363, 377, 2009, 2897, 207, 15103, 0 }; + static ulong[] dim1602Kuo3Init = { 1, 1, 1, 15, 3, 43, 49, 23, 351, 429, 1181, 2003, 1397, 9489, 0 }; + static ulong[] dim1603Kuo3Init = { 1, 3, 7, 7, 23, 61, 105, 149, 183, 83, 69, 121, 6719, 4729, 0 }; + static ulong[] dim1604Kuo3Init = { 1, 1, 5, 11, 27, 9, 119, 59, 115, 207, 1865, 3953, 45, 9739, 0 }; + static ulong[] dim1605Kuo3Init = { 1, 1, 5, 5, 7, 29, 81, 75, 361, 589, 1689, 49, 7125, 10563, 0 }; + static ulong[] dim1606Kuo3Init = { 1, 1, 7, 7, 11, 21, 43, 31, 43, 991, 357, 3707, 7679, 4305, 0 }; + static ulong[] dim1607Kuo3Init = { 1, 1, 1, 3, 23, 41, 33, 167, 207, 1015, 517, 1039, 4831, 753, 0 }; + static ulong[] dim1608Kuo3Init = { 1, 3, 7, 9, 1, 29, 25, 227, 5, 935, 1201, 2781, 6947, 1597, 0 }; + static ulong[] dim1609Kuo3Init = { 1, 1, 1, 11, 13, 27, 79, 175, 25, 681, 1805, 1435, 7325, 10439, 0 }; + static ulong[] dim1610Kuo3Init = { 1, 3, 5, 15, 25, 21, 105, 175, 501, 43, 19, 965, 255, 4177, 0 }; + static ulong[] dim1611Kuo3Init = { 1, 3, 7, 9, 1, 27, 115, 105, 43, 181, 181, 3747, 3827, 13451, 0 }; + static ulong[] dim1612Kuo3Init = { 1, 1, 5, 1, 15, 27, 49, 57, 361, 911, 1735, 3815, 5935, 11793, 0 }; + static ulong[] dim1613Kuo3Init = { 1, 3, 7, 11, 23, 7, 103, 83, 343, 59, 1383, 945, 4839, 1475, 0 }; + static ulong[] dim1614Kuo3Init = { 1, 1, 3, 9, 13, 17, 15, 129, 449, 645, 719, 283, 7911, 14961, 0 }; + static ulong[] dim1615Kuo3Init = { 1, 3, 1, 13, 1, 35, 27, 15, 177, 983, 1537, 2439, 7459, 7107, 0 }; + static ulong[] dim1616Kuo3Init = { 1, 1, 7, 3, 25, 45, 3, 163, 149, 285, 917, 2233, 7463, 15869, 0 }; + static ulong[] dim1617Kuo3Init = { 1, 1, 5, 9, 3, 3, 45, 175, 367, 261, 723, 3273, 5611, 3323, 0 }; + static ulong[] dim1618Kuo3Init = { 1, 1, 5, 15, 25, 25, 9, 189, 437, 807, 801, 3655, 5759, 9099, 0 }; + static ulong[] dim1619Kuo3Init = { 1, 3, 5, 3, 27, 37, 37, 177, 313, 179, 1897, 1299, 8041, 10523, 0 }; + static ulong[] dim1620Kuo3Init = { 1, 1, 3, 13, 7, 61, 105, 125, 343, 201, 1089, 43, 5645, 7547, 0 }; + static ulong[] dim1621Kuo3Init = { 1, 1, 3, 9, 17, 9, 69, 199, 333, 791, 1611, 1273, 7193, 6575, 0 }; + static ulong[] dim1622Kuo3Init = { 1, 3, 1, 7, 7, 63, 79, 225, 89, 391, 503, 3199, 1409, 4669, 0 }; + static ulong[] dim1623Kuo3Init = { 1, 1, 1, 3, 29, 7, 3, 119, 361, 269, 205, 1253, 113, 9665, 0 }; + static ulong[] dim1624Kuo3Init = { 1, 3, 7, 13, 13, 59, 53, 75, 467, 317, 815, 3401, 7223, 8237, 0 }; + static ulong[] dim1625Kuo3Init = { 1, 1, 7, 1, 7, 15, 49, 191, 333, 1017, 399, 55, 931, 14979, 0 }; + static ulong[] dim1626Kuo3Init = { 1, 3, 1, 11, 23, 5, 113, 47, 105, 341, 615, 81, 7393, 1037, 0 }; + static ulong[] dim1627Kuo3Init = { 1, 3, 5, 11, 3, 29, 95, 3, 275, 257, 613, 1627, 695, 5929, 0 }; + static ulong[] dim1628Kuo3Init = { 1, 3, 5, 5, 11, 31, 57, 83, 77, 573, 969, 1237, 7449, 13959, 0 }; + static ulong[] dim1629Kuo3Init = { 1, 3, 3, 5, 31, 47, 51, 37, 123, 817, 1293, 771, 4241, 3007, 0 }; + static ulong[] dim1630Kuo3Init = { 1, 1, 1, 13, 9, 13, 23, 111, 311, 213, 1217, 2187, 5709, 6891, 0 }; + static ulong[] dim1631Kuo3Init = { 1, 1, 3, 1, 7, 37, 29, 67, 109, 747, 723, 2631, 649, 13007, 0 }; + static ulong[] dim1632Kuo3Init = { 1, 3, 5, 3, 5, 55, 121, 203, 69, 515, 767, 861, 7189, 3327, 0 }; + static ulong[] dim1633Kuo3Init = { 1, 3, 7, 13, 27, 53, 91, 65, 247, 257, 799, 3115, 6301, 15527, 0 }; + static ulong[] dim1634Kuo3Init = { 1, 3, 1, 7, 27, 29, 19, 95, 343, 265, 53, 3227, 8011, 10223, 0 }; + static ulong[] dim1635Kuo3Init = { 1, 3, 1, 7, 23, 31, 89, 43, 455, 581, 2023, 845, 7765, 4811, 0 }; + static ulong[] dim1636Kuo3Init = { 1, 3, 3, 15, 31, 37, 117, 173, 343, 971, 491, 1447, 1547, 6737, 0 }; + static ulong[] dim1637Kuo3Init = { 1, 3, 1, 1, 7, 43, 75, 67, 407, 697, 51, 207, 2499, 9681, 0 }; + static ulong[] dim1638Kuo3Init = { 1, 1, 3, 7, 17, 27, 55, 3, 237, 983, 1, 1227, 2605, 8441, 0 }; + static ulong[] dim1639Kuo3Init = { 1, 1, 1, 7, 3, 31, 47, 65, 119, 823, 1055, 1047, 6067, 4267, 0 }; + static ulong[] dim1640Kuo3Init = { 1, 3, 1, 15, 9, 11, 41, 211, 249, 739, 953, 1365, 4749, 3723, 0 }; + static ulong[] dim1641Kuo3Init = { 1, 1, 5, 5, 25, 29, 31, 75, 207, 395, 1843, 1737, 387, 11871, 0 }; + static ulong[] dim1642Kuo3Init = { 1, 1, 5, 15, 21, 5, 3, 221, 223, 975, 743, 2217, 7743, 4667, 0 }; + static ulong[] dim1643Kuo3Init = { 1, 1, 5, 1, 23, 63, 113, 149, 427, 499, 1259, 735, 2839, 503, 0 }; + static ulong[] dim1644Kuo3Init = { 1, 3, 5, 5, 19, 47, 53, 205, 385, 409, 475, 265, 8183, 11709, 0 }; + static ulong[] dim1645Kuo3Init = { 1, 3, 7, 7, 21, 25, 91, 143, 373, 967, 1735, 1149, 3077, 8809, 0 }; + static ulong[] dim1646Kuo3Init = { 1, 3, 1, 1, 23, 39, 39, 89, 241, 181, 1819, 3431, 1605, 2143, 0 }; + static ulong[] dim1647Kuo3Init = { 1, 1, 7, 13, 27, 21, 69, 35, 327, 233, 495, 157, 5961, 15785, 0 }; + static ulong[] dim1648Kuo3Init = { 1, 1, 5, 15, 1, 29, 77, 249, 471, 31, 1805, 1431, 1703, 3593, 0 }; + static ulong[] dim1649Kuo3Init = { 1, 3, 1, 13, 13, 31, 15, 89, 35, 143, 487, 4047, 7681, 1557, 0 }; + static ulong[] dim1650Kuo3Init = { 1, 1, 5, 3, 21, 3, 81, 1, 15, 531, 1443, 2421, 4465, 4431, 0 }; + static ulong[] dim1651Kuo3Init = { 1, 1, 1, 13, 5, 25, 83, 1, 47, 723, 1427, 1013, 1525, 8877, 0 }; + static ulong[] dim1652Kuo3Init = { 1, 1, 5, 15, 25, 23, 71, 87, 13, 543, 1715, 2449, 4639, 8339, 0 }; + static ulong[] dim1653Kuo3Init = { 1, 1, 7, 9, 1, 27, 101, 129, 81, 747, 1745, 2545, 455, 14103, 0 }; + static ulong[] dim1654Kuo3Init = { 1, 1, 1, 11, 23, 59, 125, 49, 323, 989, 1959, 2349, 2835, 115, 0 }; + static ulong[] dim1655Kuo3Init = { 1, 3, 1, 11, 29, 23, 31, 185, 273, 43, 1093, 323, 751, 7473, 0 }; + static ulong[] dim1656Kuo3Init = { 1, 1, 5, 7, 3, 51, 65, 231, 147, 69, 1635, 1593, 7385, 1251, 0 }; + static ulong[] dim1657Kuo3Init = { 1, 1, 3, 7, 21, 7, 109, 61, 387, 819, 417, 1393, 5535, 12201, 0 }; + static ulong[] dim1658Kuo3Init = { 1, 3, 1, 1, 11, 17, 41, 61, 361, 891, 69, 935, 2793, 1631, 0 }; + static ulong[] dim1659Kuo3Init = { 1, 3, 3, 13, 25, 31, 43, 47, 247, 723, 1703, 1499, 139, 8809, 0 }; + static ulong[] dim1660Kuo3Init = { 1, 3, 5, 1, 9, 47, 45, 117, 95, 345, 1431, 975, 6575, 1213, 0 }; + static ulong[] dim1661Kuo3Init = { 1, 3, 1, 13, 29, 37, 45, 91, 443, 471, 1363, 1839, 6263, 3289, 0 }; + static ulong[] dim1662Kuo3Init = { 1, 1, 3, 5, 17, 17, 57, 193, 477, 283, 1307, 967, 1793, 12551, 0 }; + static ulong[] dim1663Kuo3Init = { 1, 1, 1, 7, 17, 1, 103, 67, 113, 805, 1993, 3019, 1911, 11961, 0 }; + static ulong[] dim1664Kuo3Init = { 1, 1, 3, 1, 23, 47, 19, 137, 511, 685, 1525, 1703, 2513, 12541, 0 }; + static ulong[] dim1665Kuo3Init = { 1, 3, 3, 3, 3, 7, 29, 45, 279, 855, 1931, 2261, 2097, 2373, 0 }; + static ulong[] dim1666Kuo3Init = { 1, 3, 7, 13, 13, 23, 105, 119, 473, 809, 925, 3295, 7547, 4229, 0 }; + static ulong[] dim1667Kuo3Init = { 1, 1, 1, 9, 27, 37, 3, 109, 257, 743, 1233, 2973, 3313, 2949, 0 }; + static ulong[] dim1668Kuo3Init = { 1, 3, 7, 13, 25, 37, 103, 157, 333, 127, 1893, 649, 7773, 15639, 0 }; + static ulong[] dim1669Kuo3Init = { 1, 1, 1, 11, 13, 53, 21, 67, 161, 859, 1715, 3303, 2527, 9487, 0 }; + static ulong[] dim1670Kuo3Init = { 1, 1, 7, 3, 7, 27, 47, 173, 103, 413, 719, 2865, 2337, 2963, 0 }; + static ulong[] dim1671Kuo3Init = { 1, 1, 5, 11, 25, 17, 3, 105, 85, 731, 933, 3967, 279, 14649, 0 }; + static ulong[] dim1672Kuo3Init = { 1, 1, 7, 5, 11, 15, 37, 197, 443, 667, 1373, 2961, 615, 6011, 0 }; + static ulong[] dim1673Kuo3Init = { 1, 1, 3, 9, 11, 45, 9, 43, 339, 203, 27, 3047, 6531, 1071, 0 }; + static ulong[] dim1674Kuo3Init = { 1, 1, 3, 9, 1, 23, 111, 185, 485, 425, 2043, 3375, 4037, 8751, 0 }; + static ulong[] dim1675Kuo3Init = { 1, 1, 7, 7, 21, 35, 37, 87, 393, 149, 1475, 4027, 8125, 16021, 0 }; + static ulong[] dim1676Kuo3Init = { 1, 1, 3, 11, 21, 51, 125, 229, 49, 611, 919, 3103, 7239, 3553, 0 }; + static ulong[] dim1677Kuo3Init = { 1, 3, 7, 5, 5, 27, 77, 99, 313, 667, 413, 1933, 7977, 8903, 0 }; + static ulong[] dim1678Kuo3Init = { 1, 3, 3, 9, 5, 47, 47, 99, 181, 253, 433, 3385, 5789, 9043, 0 }; + static ulong[] dim1679Kuo3Init = { 1, 3, 3, 13, 9, 9, 117, 51, 93, 615, 1159, 251, 3345, 925, 0 }; + static ulong[] dim1680Kuo3Init = { 1, 3, 1, 7, 21, 27, 75, 201, 489, 901, 643, 2511, 3803, 11525, 0 }; + static ulong[] dim1681Kuo3Init = { 1, 3, 3, 1, 15, 27, 117, 1, 69, 1019, 1853, 3745, 3549, 5721, 0 }; + static ulong[] dim1682Kuo3Init = { 1, 3, 7, 7, 23, 63, 113, 235, 315, 613, 1691, 2725, 2941, 11339, 0 }; + static ulong[] dim1683Kuo3Init = { 1, 1, 3, 15, 19, 1, 3, 157, 251, 443, 217, 2229, 6723, 15045, 0 }; + static ulong[] dim1684Kuo3Init = { 1, 1, 1, 3, 1, 1, 93, 133, 69, 897, 197, 2241, 1727, 3645, 0 }; + static ulong[] dim1685Kuo3Init = { 1, 3, 3, 15, 31, 33, 83, 21, 3, 243, 1857, 1343, 1359, 2631, 0 }; + static ulong[] dim1686Kuo3Init = { 1, 1, 5, 13, 27, 17, 1, 147, 113, 849, 1899, 1037, 5029, 6829, 0 }; + static ulong[] dim1687Kuo3Init = { 1, 3, 1, 1, 21, 3, 95, 69, 425, 185, 1983, 3887, 843, 14881, 0 }; + static ulong[] dim1688Kuo3Init = { 1, 3, 5, 13, 11, 31, 49, 35, 349, 429, 1173, 3783, 7979, 13651, 0 }; + static ulong[] dim1689Kuo3Init = { 1, 1, 5, 11, 25, 13, 49, 97, 293, 661, 387, 79, 5863, 9315, 0 }; + static ulong[] dim1690Kuo3Init = { 1, 1, 5, 3, 27, 25, 9, 51, 185, 569, 1129, 2657, 6609, 8383, 0 }; + static ulong[] dim1691Kuo3Init = { 1, 1, 1, 11, 29, 7, 67, 77, 77, 661, 259, 2365, 3649, 9989, 0 }; + static ulong[] dim1692Kuo3Init = { 1, 1, 5, 9, 29, 59, 43, 241, 279, 177, 721, 1329, 3709, 8987, 0 }; + static ulong[] dim1693Kuo3Init = { 1, 3, 5, 7, 25, 35, 51, 213, 367, 735, 11, 1061, 497, 13593, 0 }; + static ulong[] dim1694Kuo3Init = { 1, 1, 1, 9, 1, 39, 79, 31, 497, 799, 1575, 2627, 2821, 4815, 0 }; + static ulong[] dim1695Kuo3Init = { 1, 3, 7, 7, 15, 31, 99, 199, 369, 829, 721, 3509, 3973, 9491, 0 }; + static ulong[] dim1696Kuo3Init = { 1, 1, 1, 15, 7, 49, 125, 249, 295, 907, 1243, 155, 2519, 2295, 0 }; + static ulong[] dim1697Kuo3Init = { 1, 3, 7, 9, 7, 1, 63, 141, 505, 865, 1389, 1041, 191, 4109, 0 }; + static ulong[] dim1698Kuo3Init = { 1, 3, 5, 13, 5, 45, 5, 53, 77, 525, 579, 3077, 6737, 6839, 0 }; + static ulong[] dim1699Kuo3Init = { 1, 1, 3, 5, 23, 5, 127, 61, 421, 353, 589, 4095, 2841, 8095, 0 }; + static ulong[] dim1700Kuo3Init = { 1, 1, 7, 9, 3, 11, 49, 103, 75, 403, 441, 3513, 6535, 7811, 0 }; + static ulong[] dim1701Kuo3Init = { 1, 3, 7, 13, 21, 57, 115, 59, 341, 673, 759, 81, 6585, 9727, 0 }; + static ulong[] dim1702Kuo3Init = { 1, 1, 3, 7, 29, 33, 35, 201, 149, 41, 175, 1355, 5311, 85, 0 }; + static ulong[] dim1703Kuo3Init = { 1, 3, 1, 1, 31, 5, 51, 83, 225, 123, 1347, 2017, 6259, 1553, 0 }; + static ulong[] dim1704Kuo3Init = { 1, 1, 5, 1, 17, 57, 77, 1, 393, 875, 887, 1, 4007, 6391, 0 }; + static ulong[] dim1705Kuo3Init = { 1, 1, 3, 5, 3, 31, 83, 167, 511, 19, 525, 323, 6991, 10411, 0 }; + static ulong[] dim1706Kuo3Init = { 1, 1, 7, 9, 15, 61, 77, 189, 43, 651, 305, 3107, 6433, 3035, 0 }; + static ulong[] dim1707Kuo3Init = { 1, 3, 1, 11, 25, 15, 51, 233, 395, 867, 145, 2215, 917, 13815, 0 }; + static ulong[] dim1708Kuo3Init = { 1, 3, 1, 13, 23, 15, 3, 103, 439, 691, 283, 3917, 5525, 11007, 0 }; + static ulong[] dim1709Kuo3Init = { 1, 3, 7, 11, 11, 49, 39, 31, 127, 521, 1327, 43, 1509, 679, 0 }; + static ulong[] dim1710Kuo3Init = { 1, 1, 7, 5, 17, 27, 17, 181, 337, 85, 1687, 3245, 5315, 5653, 0 }; + static ulong[] dim1711Kuo3Init = { 1, 3, 5, 15, 31, 33, 3, 229, 103, 337, 1337, 1961, 6053, 8661, 0 }; + static ulong[] dim1712Kuo3Init = { 1, 3, 1, 7, 31, 63, 15, 135, 77, 583, 697, 1353, 6543, 291, 0 }; + static ulong[] dim1713Kuo3Init = { 1, 3, 7, 9, 17, 53, 55, 59, 149, 995, 1059, 1829, 7759, 10901, 0 }; + static ulong[] dim1714Kuo3Init = { 1, 3, 5, 7, 5, 63, 51, 123, 369, 861, 1835, 3369, 4555, 1623, 0 }; + static ulong[] dim1715Kuo3Init = { 1, 1, 3, 11, 23, 31, 21, 247, 417, 565, 689, 1401, 405, 6657, 0 }; + static ulong[] dim1716Kuo3Init = { 1, 3, 7, 7, 21, 21, 37, 123, 359, 133, 397, 173, 2135, 12407, 0 }; + static ulong[] dim1717Kuo3Init = { 1, 1, 1, 3, 1, 23, 91, 97, 421, 531, 975, 2647, 4337, 7775, 0 }; + static ulong[] dim1718Kuo3Init = { 1, 1, 3, 13, 5, 9, 57, 149, 243, 225, 79, 2745, 523, 16133, 0 }; + static ulong[] dim1719Kuo3Init = { 1, 1, 1, 11, 7, 5, 97, 91, 15, 217, 991, 1465, 3975, 8467, 0 }; + static ulong[] dim1720Kuo3Init = { 1, 3, 7, 13, 9, 61, 97, 153, 411, 801, 59, 603, 5919, 9509, 0 }; + static ulong[] dim1721Kuo3Init = { 1, 3, 5, 7, 29, 11, 71, 111, 473, 985, 931, 1211, 653, 13933, 0 }; + static ulong[] dim1722Kuo3Init = { 1, 1, 3, 3, 29, 49, 71, 105, 29, 333, 1261, 3791, 5349, 15675, 0 }; + static ulong[] dim1723Kuo3Init = { 1, 1, 7, 13, 3, 53, 73, 77, 451, 547, 51, 669, 7355, 8325, 0 }; + static ulong[] dim1724Kuo3Init = { 1, 1, 1, 13, 7, 9, 37, 87, 273, 275, 191, 469, 7529, 1955, 0 }; + static ulong[] dim1725Kuo3Init = { 1, 3, 5, 3, 21, 5, 121, 195, 327, 477, 1661, 3499, 7903, 9053, 0 }; + static ulong[] dim1726Kuo3Init = { 1, 3, 3, 11, 29, 41, 25, 13, 429, 351, 723, 3901, 5841, 9783, 0 }; + static ulong[] dim1727Kuo3Init = { 1, 3, 1, 5, 1, 25, 15, 203, 47, 289, 67, 847, 5547, 15845, 0 }; + static ulong[] dim1728Kuo3Init = { 1, 3, 3, 11, 21, 7, 53, 39, 461, 153, 1739, 4021, 307, 1435, 0 }; + static ulong[] dim1729Kuo3Init = { 1, 3, 5, 5, 7, 17, 87, 23, 47, 839, 1841, 3877, 2401, 853, 0 }; + static ulong[] dim1730Kuo3Init = { 1, 3, 3, 9, 31, 37, 15, 49, 171, 757, 499, 1455, 2151, 6169, 0 }; + static ulong[] dim1731Kuo3Init = { 1, 1, 5, 1, 31, 19, 33, 87, 507, 685, 1765, 3109, 7221, 8047, 0 }; + static ulong[] dim1732Kuo3Init = { 1, 1, 7, 7, 23, 7, 25, 45, 167, 865, 465, 3377, 7203, 7825, 0 }; + static ulong[] dim1733Kuo3Init = { 1, 3, 3, 13, 15, 53, 79, 111, 391, 777, 367, 1445, 5243, 1929, 0 }; + static ulong[] dim1734Kuo3Init = { 1, 1, 3, 15, 11, 11, 57, 115, 239, 77, 797, 2073, 831, 11879, 0 }; + static ulong[] dim1735Kuo3Init = { 1, 1, 7, 5, 23, 11, 91, 153, 29, 729, 241, 2627, 6447, 13239, 0 }; + static ulong[] dim1736Kuo3Init = { 1, 1, 7, 9, 31, 11, 59, 243, 105, 83, 363, 3473, 315, 2371, 0 }; + static ulong[] dim1737Kuo3Init = { 1, 3, 5, 1, 19, 31, 111, 91, 215, 697, 103, 3323, 7259, 13625, 0 }; + static ulong[] dim1738Kuo3Init = { 1, 1, 1, 11, 5, 59, 83, 129, 45, 223, 835, 1965, 3975, 15233, 0 }; + static ulong[] dim1739Kuo3Init = { 1, 3, 7, 11, 19, 11, 31, 225, 175, 209, 619, 3127, 4943, 9701, 0 }; + static ulong[] dim1740Kuo3Init = { 1, 1, 1, 3, 3, 19, 21, 133, 7, 151, 1017, 3867, 3699, 13051, 0 }; + static ulong[] dim1741Kuo3Init = { 1, 1, 5, 9, 27, 17, 81, 139, 439, 11, 265, 659, 1329, 4259, 0 }; + static ulong[] dim1742Kuo3Init = { 1, 3, 5, 1, 1, 59, 105, 251, 131, 817, 1215, 3005, 3417, 5637, 0 }; + static ulong[] dim1743Kuo3Init = { 1, 3, 3, 15, 31, 37, 27, 243, 225, 631, 2023, 2509, 249, 593, 0 }; + static ulong[] dim1744Kuo3Init = { 1, 1, 3, 11, 27, 51, 89, 33, 423, 423, 789, 3627, 2995, 8477, 0 }; + static ulong[] dim1745Kuo3Init = { 1, 3, 5, 5, 5, 31, 69, 65, 381, 375, 221, 477, 3311, 12103, 0 }; + static ulong[] dim1746Kuo3Init = { 1, 3, 1, 15, 31, 1, 75, 97, 143, 749, 581, 4019, 4655, 15571, 0 }; + static ulong[] dim1747Kuo3Init = { 1, 3, 7, 3, 1, 31, 51, 151, 127, 917, 975, 2839, 3815, 7405, 0 }; + static ulong[] dim1748Kuo3Init = { 1, 3, 1, 3, 9, 61, 93, 49, 41, 881, 1205, 2425, 7727, 2687, 0 }; + static ulong[] dim1749Kuo3Init = { 1, 3, 3, 3, 27, 11, 99, 51, 51, 937, 1511, 3891, 3955, 6055, 0 }; + static ulong[] dim1750Kuo3Init = { 1, 3, 3, 3, 3, 27, 81, 107, 409, 895, 1869, 2721, 1505, 9877, 0 }; + static ulong[] dim1751Kuo3Init = { 1, 1, 1, 5, 11, 43, 101, 7, 263, 881, 1029, 1491, 4147, 10339, 0 }; + static ulong[] dim1752Kuo3Init = { 1, 1, 3, 11, 25, 21, 85, 145, 489, 335, 643, 4019, 951, 5885, 0 }; + static ulong[] dim1753Kuo3Init = { 1, 1, 1, 15, 3, 55, 113, 87, 53, 839, 381, 1961, 3865, 2841, 0 }; + static ulong[] dim1754Kuo3Init = { 1, 1, 3, 13, 11, 33, 25, 95, 47, 321, 649, 1641, 1715, 3815, 0 }; + static ulong[] dim1755Kuo3Init = { 1, 1, 1, 15, 23, 59, 5, 3, 451, 781, 867, 747, 793, 6147, 0 }; + static ulong[] dim1756Kuo3Init = { 1, 1, 1, 15, 3, 27, 31, 125, 355, 837, 689, 3599, 1451, 2167, 0 }; + static ulong[] dim1757Kuo3Init = { 1, 1, 3, 9, 21, 5, 101, 37, 465, 115, 1607, 2999, 631, 1435, 0 }; + static ulong[] dim1758Kuo3Init = { 1, 3, 5, 9, 19, 41, 91, 241, 375, 707, 1573, 105, 863, 11273, 0 }; + static ulong[] dim1759Kuo3Init = { 1, 1, 5, 15, 17, 63, 95, 83, 273, 617, 1299, 1259, 7997, 5225, 0 }; + static ulong[] dim1760Kuo3Init = { 1, 3, 5, 9, 11, 5, 127, 67, 189, 733, 1175, 3099, 6561, 7771, 0 }; + static ulong[] dim1761Kuo3Init = { 1, 1, 7, 11, 13, 45, 75, 101, 279, 147, 177, 225, 557, 9413, 0 }; + static ulong[] dim1762Kuo3Init = { 1, 3, 1, 13, 11, 53, 49, 71, 451, 327, 567, 531, 589, 15395, 0 }; + static ulong[] dim1763Kuo3Init = { 1, 1, 7, 13, 29, 51, 95, 227, 87, 171, 1769, 2799, 2589, 7255, 0 }; + static ulong[] dim1764Kuo3Init = { 1, 1, 5, 7, 1, 51, 109, 135, 99, 957, 1681, 2217, 2247, 6567, 0 }; + static ulong[] dim1765Kuo3Init = { 1, 1, 3, 7, 27, 57, 101, 51, 237, 835, 1339, 955, 5969, 12511, 0 }; + static ulong[] dim1766Kuo3Init = { 1, 1, 5, 1, 21, 9, 95, 247, 309, 413, 17, 3473, 3961, 8555, 0 }; + static ulong[] dim1767Kuo3Init = { 1, 1, 1, 1, 21, 47, 29, 33, 135, 447, 1387, 107, 4781, 10987, 0 }; + static ulong[] dim1768Kuo3Init = { 1, 1, 3, 11, 5, 17, 41, 103, 83, 829, 1449, 4047, 4807, 7277, 0 }; + static ulong[] dim1769Kuo3Init = { 1, 3, 7, 15, 5, 1, 75, 241, 235, 701, 1529, 1621, 7995, 6243, 0 }; + static ulong[] dim1770Kuo3Init = { 1, 1, 3, 5, 23, 49, 31, 173, 83, 961, 1293, 1279, 2495, 10805, 0 }; + static ulong[] dim1771Kuo3Init = { 1, 1, 1, 1, 15, 39, 17, 81, 167, 209, 685, 1089, 7197, 15773, 0 }; + static ulong[] dim1772Kuo3Init = { 1, 1, 1, 15, 29, 1, 73, 113, 21, 301, 1087, 2529, 6835, 8089, 0 }; + static ulong[] dim1773Kuo3Init = { 1, 1, 5, 15, 1, 7, 99, 87, 177, 537, 283, 205, 6241, 12489, 0 }; + static ulong[] dim1774Kuo3Init = { 1, 3, 7, 3, 11, 13, 89, 43, 37, 859, 263, 2623, 6941, 7433, 0 }; + static ulong[] dim1775Kuo3Init = { 1, 3, 3, 13, 9, 47, 13, 155, 109, 507, 343, 1049, 4915, 14873, 0 }; + static ulong[] dim1776Kuo3Init = { 1, 1, 5, 1, 5, 37, 5, 71, 1, 17, 417, 3137, 3045, 5835, 0 }; + static ulong[] dim1777Kuo3Init = { 1, 3, 3, 5, 15, 43, 31, 235, 379, 807, 89, 3375, 123, 9783, 0 }; + static ulong[] dim1778Kuo3Init = { 1, 3, 5, 3, 19, 23, 53, 129, 493, 393, 91, 2345, 1959, 745, 0 }; + static ulong[] dim1779Kuo3Init = { 1, 3, 3, 13, 21, 33, 31, 125, 99, 167, 685, 733, 6479, 10391, 0 }; + static ulong[] dim1780Kuo3Init = { 1, 1, 1, 11, 1, 17, 9, 245, 75, 281, 1427, 675, 5393, 8841, 0 }; + static ulong[] dim1781Kuo3Init = { 1, 1, 3, 7, 15, 63, 31, 83, 359, 643, 77, 3941, 5477, 3435, 0 }; + static ulong[] dim1782Kuo3Init = { 1, 1, 3, 9, 31, 21, 3, 111, 233, 745, 1819, 2617, 5735, 15237, 0 }; + static ulong[] dim1783Kuo3Init = { 1, 3, 1, 9, 29, 23, 99, 25, 119, 69, 1063, 651, 4983, 14079, 0 }; + static ulong[] dim1784Kuo3Init = { 1, 3, 3, 3, 9, 53, 47, 127, 443, 113, 1651, 2967, 6633, 10025, 0 }; + static ulong[] dim1785Kuo3Init = { 1, 3, 7, 7, 19, 11, 5, 49, 23, 567, 1095, 3815, 4187, 5305, 0 }; + static ulong[] dim1786Kuo3Init = { 1, 1, 1, 11, 29, 63, 85, 147, 105, 307, 1829, 27, 7499, 15661, 0 }; + static ulong[] dim1787Kuo3Init = { 1, 3, 3, 9, 15, 19, 97, 65, 71, 597, 551, 947, 8047, 8513, 0 }; + static ulong[] dim1788Kuo3Init = { 1, 1, 5, 1, 29, 31, 1, 135, 159, 769, 997, 3027, 1485, 12627, 0 }; + static ulong[] dim1789Kuo3Init = { 1, 1, 3, 15, 29, 47, 37, 43, 45, 649, 719, 1757, 4619, 11571, 0 }; + static ulong[] dim1790Kuo3Init = { 1, 1, 1, 5, 9, 9, 117, 207, 107, 651, 1155, 2047, 7489, 5959, 0 }; + static ulong[] dim1791Kuo3Init = { 1, 3, 1, 13, 29, 37, 69, 243, 347, 849, 1503, 3985, 6081, 1471, 0 }; + static ulong[] dim1792Kuo3Init = { 1, 1, 1, 11, 1, 21, 107, 9, 377, 147, 925, 3055, 397, 11337, 0 }; + static ulong[] dim1793Kuo3Init = { 1, 3, 5, 9, 27, 45, 57, 177, 229, 925, 855, 2203, 8065, 299, 0 }; + static ulong[] dim1794Kuo3Init = { 1, 3, 1, 11, 5, 1, 77, 149, 339, 1023, 89, 3509, 4315, 6571, 0 }; + static ulong[] dim1795Kuo3Init = { 1, 1, 3, 11, 19, 51, 49, 191, 179, 941, 1409, 1789, 3363, 11507, 0 }; + static ulong[] dim1796Kuo3Init = { 1, 3, 3, 13, 29, 25, 47, 61, 121, 243, 1155, 3915, 5397, 6289, 0 }; + static ulong[] dim1797Kuo3Init = { 1, 1, 1, 3, 31, 55, 25, 125, 239, 277, 165, 3631, 3609, 13607, 0 }; + static ulong[] dim1798Kuo3Init = { 1, 3, 1, 15, 11, 23, 41, 199, 239, 805, 2021, 3377, 3103, 10657, 0 }; + static ulong[] dim1799Kuo3Init = { 1, 1, 7, 1, 27, 49, 9, 219, 383, 523, 1357, 501, 733, 631, 0 }; + static ulong[] dim1800Kuo3Init = { 1, 3, 5, 13, 1, 51, 125, 185, 205, 231, 247, 2579, 1283, 3383, 0 }; + static ulong[] dim1801Kuo3Init = { 1, 1, 7, 13, 13, 49, 81, 243, 111, 219, 409, 3755, 3783, 8159, 0 }; + static ulong[] dim1802Kuo3Init = { 1, 3, 7, 5, 13, 33, 109, 245, 141, 391, 101, 2043, 4091, 379, 0 }; + static ulong[] dim1803Kuo3Init = { 1, 1, 7, 3, 27, 39, 7, 223, 107, 969, 1117, 3599, 8063, 7737, 0 }; + static ulong[] dim1804Kuo3Init = { 1, 1, 5, 5, 11, 19, 9, 47, 41, 571, 1831, 3, 5721, 14897, 0 }; + static ulong[] dim1805Kuo3Init = { 1, 1, 7, 5, 11, 25, 75, 159, 77, 843, 61, 2283, 4033, 15099, 0 }; + static ulong[] dim1806Kuo3Init = { 1, 3, 7, 1, 5, 23, 57, 117, 45, 373, 831, 3047, 5829, 3205, 0 }; + static ulong[] dim1807Kuo3Init = { 1, 3, 5, 11, 31, 29, 45, 129, 25, 519, 661, 2033, 3003, 12469, 0 }; + static ulong[] dim1808Kuo3Init = { 1, 3, 1, 15, 5, 37, 55, 247, 129, 299, 1317, 3543, 421, 12299, 0 }; + static ulong[] dim1809Kuo3Init = { 1, 3, 1, 9, 23, 63, 5, 117, 425, 883, 1997, 1701, 415, 3279, 0 }; + static ulong[] dim1810Kuo3Init = { 1, 3, 3, 5, 1, 21, 23, 109, 55, 377, 1565, 2821, 4995, 3151, 0 }; + static ulong[] dim1811Kuo3Init = { 1, 3, 7, 7, 19, 39, 43, 169, 141, 353, 459, 2509, 1503, 3597, 0 }; + static ulong[] dim1812Kuo3Init = { 1, 1, 1, 3, 17, 55, 121, 49, 229, 589, 579, 2935, 4647, 12887, 0 }; + static ulong[] dim1813Kuo3Init = { 1, 3, 3, 11, 11, 47, 11, 119, 83, 701, 197, 583, 7997, 11635, 0 }; + static ulong[] dim1814Kuo3Init = { 1, 1, 3, 5, 25, 47, 85, 21, 317, 887, 1551, 2309, 4227, 8115, 0 }; + static ulong[] dim1815Kuo3Init = { 1, 1, 3, 5, 13, 23, 71, 7, 419, 873, 1423, 2213, 7485, 13237, 0 }; + static ulong[] dim1816Kuo3Init = { 1, 3, 7, 7, 25, 55, 43, 141, 125, 583, 451, 3897, 4059, 7409, 0 }; + static ulong[] dim1817Kuo3Init = { 1, 1, 7, 5, 19, 55, 13, 61, 461, 353, 981, 2271, 4881, 12761, 0 }; + static ulong[] dim1818Kuo3Init = { 1, 3, 3, 9, 31, 61, 105, 105, 497, 173, 1111, 873, 1869, 9027, 0 }; + static ulong[] dim1819Kuo3Init = { 1, 1, 1, 3, 31, 31, 93, 119, 399, 617, 1977, 3913, 8061, 13017, 0 }; + static ulong[] dim1820Kuo3Init = { 1, 3, 7, 9, 17, 7, 89, 149, 119, 791, 839, 3643, 7545, 13329, 0 }; + static ulong[] dim1821Kuo3Init = { 1, 1, 5, 1, 13, 59, 35, 231, 3, 703, 881, 45, 5979, 3249, 0 }; + static ulong[] dim1822Kuo3Init = { 1, 1, 1, 7, 1, 21, 117, 105, 3, 791, 1563, 2303, 3533, 7853, 0 }; + static ulong[] dim1823Kuo3Init = { 1, 3, 3, 5, 11, 11, 109, 115, 233, 471, 509, 821, 7209, 15463, 0 }; + static ulong[] dim1824Kuo3Init = { 1, 1, 5, 5, 13, 1, 83, 99, 21, 369, 751, 277, 881, 8963, 0 }; + static ulong[] dim1825Kuo3Init = { 1, 3, 1, 1, 27, 57, 3, 219, 509, 337, 1469, 2881, 7911, 1983, 0 }; + static ulong[] dim1826Kuo3Init = { 1, 1, 7, 15, 1, 25, 35, 243, 243, 491, 1031, 2905, 4293, 8387, 0 }; + static ulong[] dim1827Kuo3Init = { 1, 1, 1, 15, 5, 1, 121, 71, 129, 333, 1121, 917, 6627, 3291, 0 }; + static ulong[] dim1828Kuo3Init = { 1, 3, 5, 3, 7, 37, 13, 7, 115, 863, 345, 603, 1471, 15843, 0 }; + static ulong[] dim1829Kuo3Init = { 1, 3, 7, 3, 3, 49, 29, 79, 185, 685, 1691, 3469, 7111, 915, 0 }; + static ulong[] dim1830Kuo3Init = { 1, 1, 3, 1, 19, 61, 67, 143, 133, 457, 1865, 3403, 2557, 2603, 0 }; + static ulong[] dim1831Kuo3Init = { 1, 1, 1, 15, 27, 25, 9, 87, 489, 23, 1251, 1995, 4737, 3099, 0 }; + static ulong[] dim1832Kuo3Init = { 1, 1, 7, 11, 5, 43, 55, 85, 43, 621, 145, 1507, 4895, 687, 0 }; + static ulong[] dim1833Kuo3Init = { 1, 3, 7, 15, 7, 35, 101, 19, 35, 609, 1433, 3877, 3661, 2517, 0 }; + static ulong[] dim1834Kuo3Init = { 1, 3, 1, 5, 31, 47, 89, 225, 95, 941, 287, 1163, 6537, 10907, 0 }; + static ulong[] dim1835Kuo3Init = { 1, 3, 7, 1, 15, 61, 65, 205, 413, 147, 833, 2097, 5465, 6309, 0 }; + static ulong[] dim1836Kuo3Init = { 1, 3, 5, 11, 27, 55, 37, 185, 265, 343, 805, 325, 283, 1935, 0 }; + static ulong[] dim1837Kuo3Init = { 1, 1, 3, 13, 29, 7, 55, 243, 101, 87, 2015, 2897, 2087, 47, 0 }; + static ulong[] dim1838Kuo3Init = { 1, 3, 5, 11, 27, 1, 125, 65, 205, 525, 655, 3881, 993, 3967, 0 }; + static ulong[] dim1839Kuo3Init = { 1, 3, 3, 9, 3, 61, 85, 31, 257, 257, 1227, 3329, 731, 7223, 0 }; + static ulong[] dim1840Kuo3Init = { 1, 1, 7, 15, 29, 49, 49, 171, 95, 475, 601, 1325, 3995, 14421, 0 }; + static ulong[] dim1841Kuo3Init = { 1, 1, 1, 11, 21, 23, 97, 65, 53, 417, 181, 551, 6583, 12835, 0 }; + static ulong[] dim1842Kuo3Init = { 1, 3, 3, 1, 27, 37, 37, 143, 181, 59, 1011, 97, 2757, 15537, 0 }; + static ulong[] dim1843Kuo3Init = { 1, 3, 5, 9, 5, 47, 121, 91, 297, 897, 813, 2563, 1779, 12675, 0 }; + static ulong[] dim1844Kuo3Init = { 1, 3, 7, 9, 17, 61, 31, 47, 509, 55, 1401, 2251, 4327, 10409, 0 }; + static ulong[] dim1845Kuo3Init = { 1, 3, 1, 3, 15, 29, 97, 37, 295, 271, 893, 1135, 1651, 9271, 0 }; + static ulong[] dim1846Kuo3Init = { 1, 3, 5, 15, 29, 37, 65, 247, 247, 341, 865, 2163, 6827, 1849, 0 }; + static ulong[] dim1847Kuo3Init = { 1, 3, 3, 11, 27, 27, 105, 67, 283, 221, 1445, 3283, 865, 3747, 0 }; + static ulong[] dim1848Kuo3Init = { 1, 3, 5, 7, 7, 33, 63, 193, 219, 357, 1755, 2521, 5375, 10049, 0 }; + static ulong[] dim1849Kuo3Init = { 1, 3, 5, 7, 17, 43, 113, 171, 237, 75, 1257, 251, 4681, 14793, 0 }; + static ulong[] dim1850Kuo3Init = { 1, 3, 5, 11, 15, 15, 103, 163, 61, 263, 1165, 4021, 6833, 2675, 0 }; + static ulong[] dim1851Kuo3Init = { 1, 3, 1, 5, 21, 63, 69, 29, 237, 473, 1457, 3545, 1457, 7595, 0 }; + static ulong[] dim1852Kuo3Init = { 1, 3, 3, 1, 29, 33, 85, 103, 469, 579, 387, 2113, 5365, 7955, 0 }; + static ulong[] dim1853Kuo3Init = { 1, 1, 3, 13, 7, 37, 99, 87, 147, 401, 125, 1233, 1463, 15067, 0 }; + static ulong[] dim1854Kuo3Init = { 1, 1, 1, 3, 29, 11, 17, 89, 55, 273, 1069, 203, 941, 13667, 0 }; + static ulong[] dim1855Kuo3Init = { 1, 3, 7, 3, 3, 53, 75, 163, 79, 63, 1851, 1495, 6537, 6329, 0 }; + static ulong[] dim1856Kuo3Init = { 1, 3, 3, 3, 7, 53, 39, 35, 211, 275, 553, 1247, 3137, 11513, 0 }; + static ulong[] dim1857Kuo3Init = { 1, 1, 3, 15, 25, 37, 15, 249, 79, 227, 1297, 277, 7693, 2431, 0 }; + static ulong[] dim1858Kuo3Init = { 1, 3, 7, 3, 15, 53, 61, 27, 313, 817, 699, 3743, 6683, 11909, 0 }; + static ulong[] dim1859Kuo3Init = { 1, 1, 3, 7, 9, 3, 77, 25, 421, 403, 1729, 1349, 5995, 7579, 0 }; + static ulong[] dim1860Kuo3Init = { 1, 1, 7, 5, 29, 25, 1, 3, 69, 479, 699, 1317, 6729, 7701, 0 }; + static ulong[] dim1861Kuo3Init = { 1, 1, 1, 9, 15, 51, 41, 227, 195, 101, 1783, 485, 1157, 1849, 0 }; + static ulong[] dim1862Kuo3Init = { 1, 3, 3, 11, 1, 31, 111, 149, 361, 291, 1353, 3531, 473, 8545, 0 }; + static ulong[] dim1863Kuo3Init = { 1, 1, 1, 3, 9, 35, 31, 165, 175, 617, 1063, 179, 957, 1395, 0 }; + static ulong[] dim1864Kuo3Init = { 1, 1, 3, 1, 1, 5, 21, 191, 379, 293, 439, 1575, 243, 5013, 0 }; + static ulong[] dim1865Kuo3Init = { 1, 3, 3, 1, 1, 21, 107, 91, 473, 809, 993, 2599, 8151, 10927, 0 }; + static ulong[] dim1866Kuo3Init = { 1, 1, 1, 13, 13, 35, 71, 37, 173, 545, 1279, 225, 3275, 8823, 0 }; + static ulong[] dim1867Kuo3Init = { 1, 3, 1, 7, 3, 21, 97, 23, 197, 535, 741, 3481, 919, 14675, 14019, 0 }; + static ulong[] dim1868Kuo3Init = { 1, 3, 1, 3, 23, 25, 73, 203, 405, 287, 1167, 2313, 3065, 6385, 16509, 0 }; + static ulong[] dim1869Kuo3Init = { 1, 1, 7, 15, 9, 23, 59, 241, 245, 865, 97, 931, 3317, 747, 14415, 0 }; + static ulong[] dim1870Kuo3Init = { 1, 3, 7, 13, 7, 13, 73, 213, 345, 707, 1223, 517, 4427, 9539, 2669, 0 }; + static ulong[] dim1871Kuo3Init = { 1, 1, 5, 15, 29, 41, 75, 149, 445, 933, 1727, 1967, 1927, 1205, 30051, 0 }; + static ulong[] dim1872Kuo3Init = { 1, 1, 7, 9, 17, 57, 119, 115, 39, 957, 309, 3197, 6849, 7151, 1771, 0 }; + static ulong[] dim1873Kuo3Init = { 1, 1, 3, 11, 19, 57, 25, 89, 223, 921, 1741, 2695, 3571, 11933, 4973, 0 }; + static ulong[] dim1874Kuo3Init = { 1, 1, 3, 3, 29, 37, 77, 239, 63, 231, 639, 1311, 725, 5699, 15709, 0 }; + static ulong[] dim1875Kuo3Init = { 1, 3, 5, 5, 31, 23, 53, 27, 353, 851, 685, 169, 5325, 13675, 21493, 0 }; + static ulong[] dim1876Kuo3Init = { 1, 3, 5, 9, 31, 13, 37, 7, 51, 211, 1807, 3107, 6485, 12595, 1097, 0 }; + static ulong[] dim1877Kuo3Init = { 1, 1, 7, 15, 9, 3, 33, 197, 357, 841, 1233, 2065, 5009, 5863, 11287, 0 }; + static ulong[] dim1878Kuo3Init = { 1, 3, 7, 9, 27, 15, 75, 195, 223, 689, 1181, 1597, 2553, 7985, 13593, 0 }; + static ulong[] dim1879Kuo3Init = { 1, 1, 5, 5, 21, 41, 97, 121, 293, 639, 1799, 689, 6941, 14179, 11007, 0 }; + static ulong[] dim1880Kuo3Init = { 1, 1, 3, 7, 21, 61, 91, 177, 213, 757, 123, 2021, 1493, 2365, 9713, 0 }; + static ulong[] dim1881Kuo3Init = { 1, 1, 1, 7, 3, 57, 33, 229, 45, 351, 1671, 2047, 7685, 14375, 5773, 0 }; + static ulong[] dim1882Kuo3Init = { 1, 1, 7, 7, 23, 55, 19, 83, 11, 463, 83, 3071, 5257, 2741, 31137, 0 }; + static ulong[] dim1883Kuo3Init = { 1, 3, 3, 5, 5, 31, 53, 135, 255, 711, 1873, 609, 3395, 16137, 19947, 0 }; + static ulong[] dim1884Kuo3Init = { 1, 3, 7, 7, 13, 29, 117, 203, 387, 529, 1301, 3199, 1843, 5381, 12491, 0 }; + static ulong[] dim1885Kuo3Init = { 1, 3, 1, 15, 25, 61, 21, 75, 111, 757, 1611, 2911, 5805, 5787, 5099, 0 }; + static ulong[] dim1886Kuo3Init = { 1, 3, 3, 5, 1, 33, 51, 45, 115, 45, 1155, 951, 6471, 10233, 8053, 0 }; + static ulong[] dim1887Kuo3Init = { 1, 3, 7, 1, 11, 13, 17, 167, 391, 219, 277, 3311, 1761, 6741, 6253, 0 }; + static ulong[] dim1888Kuo3Init = { 1, 1, 3, 7, 3, 9, 43, 187, 113, 747, 1207, 3513, 1055, 15145, 3793, 0 }; + static ulong[] dim1889Kuo3Init = { 1, 1, 7, 13, 3, 33, 127, 95, 47, 663, 1581, 489, 2303, 15183, 21671, 0 }; + static ulong[] dim1890Kuo3Init = { 1, 3, 7, 9, 15, 7, 53, 143, 313, 167, 425, 3153, 7241, 3019, 27323, 0 }; + static ulong[] dim1891Kuo3Init = { 1, 1, 5, 1, 1, 47, 47, 211, 79, 495, 1383, 2373, 141, 2933, 11535, 0 }; + static ulong[] dim1892Kuo3Init = { 1, 3, 1, 11, 13, 35, 79, 105, 329, 235, 667, 2431, 6427, 15335, 15013, 0 }; + static ulong[] dim1893Kuo3Init = { 1, 3, 3, 9, 25, 33, 27, 241, 153, 197, 221, 3149, 2357, 4485, 17877, 0 }; + static ulong[] dim1894Kuo3Init = { 1, 1, 1, 7, 31, 29, 43, 39, 439, 799, 293, 727, 6387, 12257, 15701, 0 }; + static ulong[] dim1895Kuo3Init = { 1, 3, 1, 1, 17, 47, 105, 33, 275, 269, 259, 2293, 1829, 13141, 3015, 0 }; + static ulong[] dim1896Kuo3Init = { 1, 1, 3, 3, 29, 27, 43, 161, 131, 95, 851, 1269, 491, 4073, 3481, 0 }; + static ulong[] dim1897Kuo3Init = { 1, 3, 7, 3, 23, 13, 35, 137, 405, 899, 1521, 2193, 725, 11967, 16937, 0 }; + static ulong[] dim1898Kuo3Init = { 1, 3, 1, 15, 5, 15, 113, 139, 307, 125, 635, 477, 493, 9879, 21125, 0 }; + static ulong[] dim1899Kuo3Init = { 1, 1, 7, 11, 19, 9, 117, 173, 447, 485, 1073, 2893, 1767, 10299, 31449, 0 }; + static ulong[] dim1900Kuo3Init = { 1, 3, 7, 3, 11, 53, 99, 109, 393, 281, 187, 1557, 3597, 5215, 4033, 0 }; + static ulong[] dim1901Kuo3Init = { 1, 1, 1, 3, 5, 15, 33, 33, 37, 445, 1415, 2885, 2625, 465, 2745, 0 }; + static ulong[] dim1902Kuo3Init = { 1, 3, 1, 13, 7, 13, 93, 141, 427, 663, 1863, 991, 2001, 701, 18287, 0 }; + static ulong[] dim1903Kuo3Init = { 1, 3, 1, 7, 19, 47, 65, 49, 425, 691, 1487, 2725, 6145, 4983, 11871, 0 }; + static ulong[] dim1904Kuo3Init = { 1, 1, 7, 11, 27, 35, 89, 147, 413, 1007, 755, 3883, 4737, 10399, 19073, 0 }; + static ulong[] dim1905Kuo3Init = { 1, 3, 3, 1, 11, 41, 27, 225, 237, 407, 461, 1881, 3761, 6587, 28923, 0 }; + static ulong[] dim1906Kuo3Init = { 1, 3, 5, 9, 1, 3, 93, 179, 157, 227, 571, 1901, 1407, 12059, 15281, 0 }; + static ulong[] dim1907Kuo3Init = { 1, 3, 1, 15, 27, 29, 55, 169, 65, 517, 1801, 177, 5687, 9597, 5167, 0 }; + static ulong[] dim1908Kuo3Init = { 1, 1, 3, 5, 25, 47, 57, 15, 491, 631, 1567, 25, 2087, 7513, 15107, 0 }; + static ulong[] dim1909Kuo3Init = { 1, 1, 1, 11, 15, 55, 13, 39, 203, 487, 1235, 389, 281, 499, 20119, 0 }; + static ulong[] dim1910Kuo3Init = { 1, 3, 3, 15, 29, 53, 127, 211, 301, 509, 611, 1293, 6495, 10211, 4905, 0 }; + static ulong[] dim1911Kuo3Init = { 1, 3, 5, 3, 13, 15, 31, 205, 237, 429, 1721, 3953, 8153, 16275, 30421, 0 }; + static ulong[] dim1912Kuo3Init = { 1, 3, 7, 11, 27, 17, 43, 123, 503, 507, 257, 447, 6315, 5023, 6995, 0 }; + static ulong[] dim1913Kuo3Init = { 1, 3, 5, 15, 27, 33, 127, 33, 241, 1001, 1009, 1263, 4627, 9329, 29191, 0 }; + static ulong[] dim1914Kuo3Init = { 1, 1, 1, 13, 13, 45, 125, 77, 247, 123, 1581, 537, 799, 15417, 30457, 0 }; + static ulong[] dim1915Kuo3Init = { 1, 3, 5, 5, 9, 29, 39, 211, 243, 871, 1581, 4029, 4791, 13393, 25341, 0 }; + static ulong[] dim1916Kuo3Init = { 1, 3, 1, 5, 15, 17, 123, 123, 303, 207, 1551, 3633, 5591, 2725, 5707, 0 }; + static ulong[] dim1917Kuo3Init = { 1, 1, 7, 11, 29, 41, 111, 73, 163, 511, 1305, 3235, 4725, 13589, 9611, 0 }; + static ulong[] dim1918Kuo3Init = { 1, 1, 1, 1, 19, 51, 17, 225, 499, 1013, 7, 1793, 7073, 10115, 18195, 0 }; + static ulong[] dim1919Kuo3Init = { 1, 1, 7, 9, 17, 35, 107, 87, 251, 19, 959, 1389, 6725, 8555, 14571, 0 }; + static ulong[] dim1920Kuo3Init = { 1, 1, 1, 9, 1, 13, 79, 163, 17, 87, 1121, 1813, 1213, 3325, 18083, 0 }; + static ulong[] dim1921Kuo3Init = { 1, 3, 1, 3, 27, 5, 107, 143, 211, 459, 257, 957, 1183, 2367, 24687, 0 }; + static ulong[] dim1922Kuo3Init = { 1, 1, 7, 15, 1, 33, 51, 25, 379, 829, 1657, 273, 4507, 9609, 879, 0 }; + static ulong[] dim1923Kuo3Init = { 1, 1, 7, 15, 1, 31, 43, 181, 147, 373, 83, 2179, 6363, 1871, 10209, 0 }; + static ulong[] dim1924Kuo3Init = { 1, 1, 1, 15, 9, 29, 105, 255, 483, 573, 1841, 1101, 2987, 1619, 18837, 0 }; + static ulong[] dim1925Kuo3Init = { 1, 3, 5, 11, 17, 19, 67, 109, 13, 247, 1365, 2153, 5597, 5785, 25877, 0 }; + static ulong[] dim1926Kuo3Init = { 1, 1, 3, 7, 17, 49, 121, 163, 49, 689, 1917, 2161, 7979, 8153, 12889, 0 }; + static ulong[] dim1927Kuo3Init = { 1, 1, 3, 7, 5, 49, 39, 251, 311, 69, 553, 2789, 2415, 6521, 26847, 0 }; + static ulong[] dim1928Kuo3Init = { 1, 1, 3, 5, 15, 51, 67, 227, 245, 893, 493, 1191, 3061, 249, 16603, 0 }; + static ulong[] dim1929Kuo3Init = { 1, 3, 1, 3, 17, 63, 35, 41, 269, 75, 147, 3229, 7985, 5789, 6365, 0 }; + static ulong[] dim1930Kuo3Init = { 1, 3, 1, 13, 21, 33, 125, 39, 343, 133, 389, 2467, 4079, 14315, 17047, 0 }; + static ulong[] dim1931Kuo3Init = { 1, 3, 1, 7, 27, 61, 73, 107, 143, 665, 155, 2865, 3017, 7307, 8771, 0 }; + static ulong[] dim1932Kuo3Init = { 1, 1, 5, 7, 25, 57, 57, 39, 195, 405, 1863, 2985, 5775, 9609, 24409, 0 }; + static ulong[] dim1933Kuo3Init = { 1, 3, 3, 5, 11, 27, 91, 169, 343, 673, 1317, 1763, 1603, 527, 18945, 0 }; + static ulong[] dim1934Kuo3Init = { 1, 3, 7, 7, 17, 39, 113, 47, 483, 793, 1295, 1305, 7025, 14849, 17703, 0 }; + static ulong[] dim1935Kuo3Init = { 1, 1, 5, 9, 5, 43, 119, 149, 103, 63, 1369, 3791, 3081, 10587, 12711, 0 }; + static ulong[] dim1936Kuo3Init = { 1, 3, 5, 15, 9, 55, 105, 171, 199, 883, 1113, 3559, 1979, 8823, 12407, 0 }; + static ulong[] dim1937Kuo3Init = { 1, 3, 3, 9, 27, 51, 105, 163, 203, 25, 1579, 351, 8071, 5921, 28935, 0 }; + static ulong[] dim1938Kuo3Init = { 1, 1, 5, 15, 15, 43, 115, 115, 5, 283, 1935, 2619, 2543, 7603, 2877, 0 }; + static ulong[] dim1939Kuo3Init = { 1, 3, 7, 9, 31, 29, 17, 67, 121, 187, 563, 377, 3947, 7699, 8677, 0 }; + static ulong[] dim1940Kuo3Init = { 1, 1, 5, 1, 5, 1, 121, 211, 109, 955, 1605, 3681, 5395, 797, 19243, 0 }; + static ulong[] dim1941Kuo3Init = { 1, 1, 7, 13, 7, 63, 73, 215, 403, 465, 1317, 3141, 4511, 12579, 20839, 0 }; + static ulong[] dim1942Kuo3Init = { 1, 3, 5, 7, 9, 63, 39, 55, 353, 395, 233, 1189, 1781, 9167, 887, 0 }; + static ulong[] dim1943Kuo3Init = { 1, 1, 7, 1, 1, 55, 93, 63, 211, 635, 1767, 827, 7257, 119, 26333, 0 }; + static ulong[] dim1944Kuo3Init = { 1, 1, 3, 11, 9, 33, 17, 205, 303, 713, 65, 3539, 5069, 8895, 3843, 0 }; + static ulong[] dim1945Kuo3Init = { 1, 1, 3, 15, 3, 59, 45, 135, 103, 293, 731, 359, 3631, 7967, 30043, 0 }; + static ulong[] dim1946Kuo3Init = { 1, 3, 3, 7, 25, 7, 27, 161, 9, 509, 1345, 3759, 7957, 5975, 17981, 0 }; + static ulong[] dim1947Kuo3Init = { 1, 3, 1, 7, 13, 41, 105, 241, 331, 437, 2027, 2589, 5201, 11373, 22581, 0 }; + static ulong[] dim1948Kuo3Init = { 1, 3, 7, 13, 5, 3, 37, 43, 125, 521, 1059, 291, 4421, 5215, 16835, 0 }; + static ulong[] dim1949Kuo3Init = { 1, 1, 5, 15, 13, 15, 85, 175, 221, 527, 173, 1333, 7505, 883, 2215, 0 }; + static ulong[] dim1950Kuo3Init = { 1, 3, 5, 11, 27, 63, 5, 215, 85, 229, 165, 525, 2693, 15089, 4907, 0 }; + static ulong[] dim1951Kuo3Init = { 1, 3, 7, 15, 25, 13, 91, 81, 81, 189, 671, 539, 2393, 9627, 17667, 0 }; + static ulong[] dim1952Kuo3Init = { 1, 1, 1, 5, 5, 9, 45, 43, 337, 841, 853, 3969, 5917, 5837, 17265, 0 }; + static ulong[] dim1953Kuo3Init = { 1, 1, 7, 9, 1, 57, 33, 29, 235, 69, 815, 147, 7251, 2933, 32405, 0 }; + static ulong[] dim1954Kuo3Init = { 1, 3, 1, 3, 29, 1, 3, 13, 483, 825, 31, 2289, 185, 9075, 15495, 0 }; + static ulong[] dim1955Kuo3Init = { 1, 3, 3, 3, 1, 33, 127, 53, 229, 975, 91, 3259, 7969, 4193, 18433, 0 }; + static ulong[] dim1956Kuo3Init = { 1, 1, 3, 7, 7, 43, 89, 193, 51, 563, 1961, 3959, 1901, 10393, 679, 0 }; + static ulong[] dim1957Kuo3Init = { 1, 1, 5, 9, 29, 11, 57, 227, 163, 169, 1969, 3087, 3221, 15499, 12255, 0 }; + static ulong[] dim1958Kuo3Init = { 1, 3, 7, 5, 31, 47, 45, 37, 257, 383, 1347, 3923, 7963, 13459, 8755, 0 }; + static ulong[] dim1959Kuo3Init = { 1, 1, 1, 3, 5, 53, 19, 219, 261, 313, 1889, 3185, 5309, 14049, 5231, 0 }; + static ulong[] dim1960Kuo3Init = { 1, 3, 3, 13, 29, 19, 49, 221, 443, 125, 929, 2445, 6713, 5639, 2657, 0 }; + static ulong[] dim1961Kuo3Init = { 1, 1, 7, 3, 17, 59, 87, 227, 305, 67, 311, 3473, 4785, 10761, 2871, 0 }; + static ulong[] dim1962Kuo3Init = { 1, 1, 5, 7, 31, 63, 103, 127, 49, 839, 1991, 41, 5019, 12779, 25489, 0 }; + static ulong[] dim1963Kuo3Init = { 1, 3, 5, 9, 9, 45, 127, 29, 441, 481, 49, 1975, 1523, 759, 847, 0 }; + static ulong[] dim1964Kuo3Init = { 1, 3, 5, 13, 1, 25, 89, 19, 53, 17, 1449, 603, 473, 9965, 14455, 0 }; + static ulong[] dim1965Kuo3Init = { 1, 3, 1, 7, 19, 9, 27, 97, 321, 1007, 1283, 3805, 539, 2979, 4631, 0 }; + static ulong[] dim1966Kuo3Init = { 1, 3, 1, 5, 9, 3, 9, 237, 349, 277, 1791, 3325, 865, 4305, 29293, 0 }; + static ulong[] dim1967Kuo3Init = { 1, 1, 1, 9, 13, 23, 63, 33, 381, 711, 1921, 1385, 5949, 8837, 3589, 0 }; + static ulong[] dim1968Kuo3Init = { 1, 3, 1, 7, 15, 5, 7, 175, 15, 343, 1587, 2917, 4189, 14973, 1691, 0 }; + static ulong[] dim1969Kuo3Init = { 1, 1, 3, 15, 17, 59, 123, 195, 377, 35, 917, 1045, 721, 9759, 15287, 0 }; + static ulong[] dim1970Kuo3Init = { 1, 1, 3, 15, 29, 3, 15, 147, 283, 449, 175, 1771, 2359, 7541, 11657, 0 }; + static ulong[] dim1971Kuo3Init = { 1, 3, 1, 3, 1, 11, 45, 117, 235, 75, 247, 917, 6135, 13817, 27365, 0 }; + static ulong[] dim1972Kuo3Init = { 1, 1, 7, 3, 1, 45, 31, 97, 281, 739, 829, 1837, 1709, 877, 25275, 0 }; + static ulong[] dim1973Kuo3Init = { 1, 3, 7, 11, 3, 35, 11, 55, 233, 471, 1239, 1345, 2475, 13391, 25447, 0 }; + static ulong[] dim1974Kuo3Init = { 1, 1, 5, 7, 27, 33, 111, 89, 173, 361, 1641, 381, 1629, 5663, 17715, 0 }; + static ulong[] dim1975Kuo3Init = { 1, 3, 1, 1, 31, 59, 11, 165, 129, 513, 1729, 2707, 4665, 3381, 7915, 0 }; + static ulong[] dim1976Kuo3Init = { 1, 3, 1, 11, 19, 15, 3, 99, 21, 255, 515, 1619, 1819, 4143, 24317, 0 }; + static ulong[] dim1977Kuo3Init = { 1, 3, 1, 9, 11, 33, 13, 143, 39, 557, 901, 187, 2963, 13413, 5641, 0 }; + static ulong[] dim1978Kuo3Init = { 1, 3, 3, 13, 5, 27, 87, 63, 41, 57, 2009, 493, 2565, 14931, 24071, 0 }; + static ulong[] dim1979Kuo3Init = { 1, 3, 1, 1, 7, 11, 31, 107, 343, 395, 841, 467, 1019, 3861, 19595, 0 }; + static ulong[] dim1980Kuo3Init = { 1, 1, 7, 13, 5, 15, 113, 23, 421, 693, 1421, 2213, 3589, 3713, 1353, 0 }; + static ulong[] dim1981Kuo3Init = { 1, 3, 1, 7, 17, 1, 87, 217, 333, 797, 1971, 917, 3527, 10061, 19353, 0 }; + static ulong[] dim1982Kuo3Init = { 1, 3, 1, 5, 5, 51, 17, 239, 275, 221, 1621, 215, 319, 12041, 15669, 0 }; + static ulong[] dim1983Kuo3Init = { 1, 1, 7, 11, 27, 33, 31, 19, 365, 951, 1453, 141, 1249, 16313, 30607, 0 }; + static ulong[] dim1984Kuo3Init = { 1, 3, 1, 9, 15, 19, 127, 247, 161, 921, 195, 2857, 1573, 11077, 15997, 0 }; + static ulong[] dim1985Kuo3Init = { 1, 1, 1, 1, 9, 43, 57, 103, 215, 337, 1705, 961, 6895, 2671, 7157, 0 }; + static ulong[] dim1986Kuo3Init = { 1, 1, 7, 3, 13, 55, 123, 19, 279, 571, 1039, 2545, 5961, 12373, 11479, 0 }; + static ulong[] dim1987Kuo3Init = { 1, 3, 7, 11, 7, 35, 85, 89, 407, 359, 1897, 231, 7653, 9215, 9957, 0 }; + static ulong[] dim1988Kuo3Init = { 1, 3, 7, 5, 23, 53, 13, 153, 221, 363, 1481, 1069, 1023, 8573, 29385, 0 }; + static ulong[] dim1989Kuo3Init = { 1, 1, 1, 3, 15, 63, 1, 57, 373, 35, 725, 135, 5593, 5593, 8365, 0 }; + static ulong[] dim1990Kuo3Init = { 1, 1, 5, 3, 7, 35, 25, 69, 441, 451, 1109, 1723, 1617, 3947, 22349, 0 }; + static ulong[] dim1991Kuo3Init = { 1, 3, 5, 3, 27, 55, 75, 231, 245, 831, 1641, 1475, 51, 2683, 12489, 0 }; + static ulong[] dim1992Kuo3Init = { 1, 1, 5, 5, 17, 5, 61, 167, 389, 149, 43, 825, 6079, 12955, 20121, 0 }; + static ulong[] dim1993Kuo3Init = { 1, 1, 5, 7, 15, 43, 63, 83, 187, 1005, 1675, 2907, 2357, 5459, 18621, 0 }; + static ulong[] dim1994Kuo3Init = { 1, 1, 5, 13, 27, 53, 49, 93, 9, 629, 1507, 357, 3207, 9209, 13697, 0 }; + static ulong[] dim1995Kuo3Init = { 1, 3, 5, 3, 19, 49, 65, 31, 359, 13, 617, 815, 4673, 2475, 27491, 0 }; + static ulong[] dim1996Kuo3Init = { 1, 3, 3, 13, 21, 39, 79, 107, 485, 905, 51, 987, 6579, 3899, 28785, 0 }; + static ulong[] dim1997Kuo3Init = { 1, 1, 1, 11, 7, 11, 111, 223, 249, 767, 141, 691, 4711, 583, 7917, 0 }; + static ulong[] dim1998Kuo3Init = { 1, 1, 5, 1, 9, 43, 115, 179, 313, 783, 2047, 1773, 2307, 5011, 7215, 0 }; + static ulong[] dim1999Kuo3Init = { 1, 3, 3, 5, 23, 23, 85, 193, 83, 809, 1827, 3375, 5177, 2041, 19271, 0 }; + static ulong[] dim2000Kuo3Init = { 1, 1, 1, 9, 23, 17, 31, 111, 75, 265, 1171, 219, 6309, 2263, 3807, 0 }; + static ulong[] dim2001Kuo3Init = { 1, 1, 5, 1, 27, 7, 65, 117, 291, 811, 1797, 3395, 3495, 829, 23911, 0 }; + static ulong[] dim2002Kuo3Init = { 1, 1, 3, 11, 19, 31, 43, 229, 361, 219, 1029, 1407, 5855, 12411, 16117, 0 }; + static ulong[] dim2003Kuo3Init = { 1, 3, 3, 3, 5, 1, 99, 245, 21, 925, 1807, 2529, 627, 3363, 853, 0 }; + static ulong[] dim2004Kuo3Init = { 1, 1, 3, 15, 17, 41, 83, 31, 207, 615, 851, 1631, 6789, 12061, 12327, 0 }; + static ulong[] dim2005Kuo3Init = { 1, 1, 7, 15, 27, 19, 75, 3, 51, 655, 73, 2433, 7973, 1425, 31309, 0 }; + static ulong[] dim2006Kuo3Init = { 1, 3, 1, 7, 25, 47, 73, 119, 91, 981, 1671, 2145, 3101, 3765, 8719, 0 }; + static ulong[] dim2007Kuo3Init = { 1, 1, 1, 7, 31, 37, 51, 181, 289, 273, 1889, 1017, 2793, 9513, 32549, 0 }; + static ulong[] dim2008Kuo3Init = { 1, 1, 3, 5, 5, 39, 57, 51, 135, 689, 1913, 709, 4759, 12223, 17377, 0 }; + static ulong[] dim2009Kuo3Init = { 1, 3, 3, 15, 31, 9, 57, 245, 159, 97, 1485, 2229, 1393, 9699, 5807, 0 }; + static ulong[] dim2010Kuo3Init = { 1, 1, 3, 9, 11, 3, 11, 169, 81, 667, 357, 2307, 7305, 8631, 2555, 0 }; + static ulong[] dim2011Kuo3Init = { 1, 3, 7, 7, 15, 17, 119, 143, 15, 567, 1879, 1363, 1617, 8231, 23071, 0 }; + static ulong[] dim2012Kuo3Init = { 1, 1, 5, 9, 5, 39, 49, 45, 371, 641, 943, 1231, 8139, 14423, 11057, 0 }; + static ulong[] dim2013Kuo3Init = { 1, 1, 5, 1, 27, 51, 25, 111, 205, 655, 317, 1381, 2359, 8785, 31503, 0 }; + static ulong[] dim2014Kuo3Init = { 1, 3, 3, 3, 9, 13, 127, 211, 423, 147, 735, 1323, 5801, 9291, 10059, 0 }; + static ulong[] dim2015Kuo3Init = { 1, 3, 3, 13, 19, 1, 11, 85, 343, 781, 1661, 1803, 4541, 2271, 20541, 0 }; + static ulong[] dim2016Kuo3Init = { 1, 1, 5, 9, 11, 15, 77, 63, 345, 71, 1311, 3809, 7535, 1269, 13949, 0 }; + static ulong[] dim2017Kuo3Init = { 1, 3, 7, 7, 19, 27, 3, 107, 439, 195, 2007, 4009, 305, 3111, 17775, 0 }; + static ulong[] dim2018Kuo3Init = { 1, 1, 3, 7, 27, 31, 25, 123, 177, 161, 287, 3389, 3013, 11427, 9165, 0 }; + static ulong[] dim2019Kuo3Init = { 1, 1, 3, 7, 27, 15, 83, 131, 201, 277, 267, 3557, 1337, 4427, 2389, 0 }; + static ulong[] dim2020Kuo3Init = { 1, 1, 5, 7, 25, 27, 75, 211, 147, 37, 491, 3467, 4525, 13073, 15289, 0 }; + static ulong[] dim2021Kuo3Init = { 1, 3, 5, 9, 13, 37, 117, 159, 145, 453, 1451, 667, 1861, 6855, 25389, 0 }; + static ulong[] dim2022Kuo3Init = { 1, 1, 5, 7, 19, 37, 3, 157, 251, 901, 433, 3289, 2723, 11941, 10103, 0 }; + static ulong[] dim2023Kuo3Init = { 1, 3, 7, 3, 31, 51, 125, 211, 317, 775, 801, 3887, 2257, 13947, 2421, 0 }; + static ulong[] dim2024Kuo3Init = { 1, 3, 3, 13, 11, 21, 67, 223, 203, 409, 1927, 3565, 679, 14197, 24987, 0 }; + static ulong[] dim2025Kuo3Init = { 1, 3, 1, 1, 23, 29, 37, 203, 311, 825, 1957, 3069, 5295, 4073, 4407, 0 }; + static ulong[] dim2026Kuo3Init = { 1, 3, 1, 15, 1, 49, 111, 205, 441, 907, 481, 225, 6589, 7523, 19807, 0 }; + static ulong[] dim2027Kuo3Init = { 1, 3, 5, 15, 1, 55, 43, 121, 9, 239, 723, 3109, 5639, 9547, 20455, 0 }; + static ulong[] dim2028Kuo3Init = { 1, 1, 1, 15, 29, 17, 121, 61, 233, 873, 1447, 1313, 5073, 12259, 32305, 0 }; + static ulong[] dim2029Kuo3Init = { 1, 1, 5, 7, 25, 57, 15, 45, 243, 297, 219, 2307, 1459, 16005, 10041, 0 }; + static ulong[] dim2030Kuo3Init = { 1, 3, 7, 3, 5, 53, 57, 187, 287, 243, 1223, 1625, 669, 5165, 8395, 0 }; + static ulong[] dim2031Kuo3Init = { 1, 3, 7, 15, 23, 23, 25, 225, 471, 661, 905, 2293, 1131, 8469, 7929, 0 }; + static ulong[] dim2032Kuo3Init = { 1, 1, 5, 11, 11, 33, 11, 129, 237, 855, 1417, 3661, 1561, 9635, 31905, 0 }; + static ulong[] dim2033Kuo3Init = { 1, 3, 1, 3, 15, 45, 3, 253, 125, 449, 1675, 1707, 3917, 11829, 27439, 0 }; + static ulong[] dim2034Kuo3Init = { 1, 3, 7, 1, 1, 55, 83, 69, 83, 745, 1225, 977, 7117, 15045, 28067, 0 }; + static ulong[] dim2035Kuo3Init = { 1, 1, 7, 9, 3, 51, 23, 205, 5, 625, 531, 3557, 4101, 5709, 29487, 0 }; + static ulong[] dim2036Kuo3Init = { 1, 1, 1, 5, 9, 23, 69, 99, 203, 355, 1935, 3165, 5701, 15491, 18151, 0 }; + static ulong[] dim2037Kuo3Init = { 1, 1, 1, 7, 31, 41, 89, 85, 273, 227, 785, 1057, 4409, 9155, 11573, 0 }; + static ulong[] dim2038Kuo3Init = { 1, 3, 7, 15, 17, 49, 117, 31, 181, 799, 417, 3931, 6069, 1253, 25793, 0 }; + static ulong[] dim2039Kuo3Init = { 1, 1, 3, 7, 27, 23, 33, 189, 5, 841, 901, 2023, 331, 10015, 3781, 0 }; + static ulong[] dim2040Kuo3Init = { 1, 3, 3, 5, 19, 47, 73, 103, 373, 1011, 1015, 1657, 6181, 69, 16243, 0 }; + static ulong[] dim2041Kuo3Init = { 1, 1, 7, 9, 13, 9, 95, 161, 413, 155, 367, 3519, 1557, 14897, 31331, 0 }; + static ulong[] dim2042Kuo3Init = { 1, 1, 7, 3, 15, 25, 105, 145, 157, 525, 1541, 3361, 1531, 7473, 28187, 0 }; + static ulong[] dim2043Kuo3Init = { 1, 1, 7, 7, 15, 7, 119, 135, 395, 441, 1443, 537, 5185, 793, 13205, 0 }; + static ulong[] dim2044Kuo3Init = { 1, 1, 1, 9, 15, 7, 101, 43, 437, 761, 1471, 3843, 6765, 4135, 7883, 0 }; + static ulong[] dim2045Kuo3Init = { 1, 1, 5, 5, 23, 31, 125, 119, 361, 65, 1907, 1335, 1309, 10591, 11167, 0 }; + static ulong[] dim2046Kuo3Init = { 1, 3, 1, 7, 21, 9, 29, 149, 371, 201, 1531, 2955, 1755, 14047, 5867, 0 }; + static ulong[] dim2047Kuo3Init = { 1, 1, 5, 1, 19, 9, 13, 13, 313, 621, 595, 2765, 2963, 13081, 21795, 0 }; + static ulong[] dim2048Kuo3Init = { 1, 1, 3, 11, 21, 61, 7, 113, 295, 995, 1649, 1715, 4737, 4769, 13945, 0 }; + static ulong[] dim2049Kuo3Init = { 1, 3, 5, 15, 17, 53, 73, 15, 83, 813, 1757, 471, 6031, 7871, 32569, 0 }; + static ulong[] dim2050Kuo3Init = { 1, 3, 1, 13, 29, 55, 45, 173, 231, 167, 415, 1487, 6403, 13823, 10121, 0 }; + static ulong[] dim2051Kuo3Init = { 1, 1, 1, 5, 19, 25, 107, 177, 97, 703, 1349, 2217, 3863, 11211, 28875, 0 }; + static ulong[] dim2052Kuo3Init = { 1, 3, 7, 9, 1, 9, 37, 127, 435, 917, 709, 2227, 7449, 13927, 1187, 0 }; + static ulong[] dim2053Kuo3Init = { 1, 1, 3, 15, 19, 17, 19, 127, 343, 235, 931, 589, 6439, 8839, 18027, 0 }; + static ulong[] dim2054Kuo3Init = { 1, 3, 5, 7, 25, 25, 71, 141, 343, 35, 15, 1439, 3163, 8063, 15337, 0 }; + static ulong[] dim2055Kuo3Init = { 1, 3, 3, 13, 27, 31, 91, 215, 67, 835, 673, 3355, 7633, 11711, 31479, 0 }; + static ulong[] dim2056Kuo3Init = { 1, 3, 5, 3, 5, 9, 35, 23, 415, 341, 1813, 3761, 5053, 9497, 10147, 0 }; + static ulong[] dim2057Kuo3Init = { 1, 1, 3, 5, 25, 59, 107, 57, 43, 955, 1049, 2613, 7003, 5749, 28211, 0 }; + static ulong[] dim2058Kuo3Init = { 1, 3, 5, 5, 5, 61, 25, 17, 41, 477, 131, 3331, 1193, 14291, 1467, 0 }; + static ulong[] dim2059Kuo3Init = { 1, 3, 3, 3, 5, 7, 37, 41, 215, 723, 1735, 3735, 3981, 13405, 5837, 0 }; + static ulong[] dim2060Kuo3Init = { 1, 3, 1, 7, 17, 9, 21, 51, 451, 691, 1853, 779, 635, 15461, 14789, 0 }; + static ulong[] dim2061Kuo3Init = { 1, 1, 7, 13, 9, 51, 21, 183, 33, 565, 529, 393, 6847, 10149, 23807, 0 }; + static ulong[] dim2062Kuo3Init = { 1, 3, 1, 15, 9, 27, 1, 245, 459, 935, 1219, 2277, 6309, 13511, 31255, 0 }; + static ulong[] dim2063Kuo3Init = { 1, 1, 3, 3, 21, 63, 121, 95, 5, 545, 995, 1011, 2073, 6145, 4635, 0 }; + static ulong[] dim2064Kuo3Init = { 1, 1, 3, 15, 11, 1, 61, 53, 445, 33, 153, 2179, 2899, 7633, 20417, 0 }; + static ulong[] dim2065Kuo3Init = { 1, 1, 5, 3, 29, 47, 65, 55, 509, 175, 1875, 2669, 4583, 775, 27621, 0 }; + static ulong[] dim2066Kuo3Init = { 1, 3, 1, 1, 5, 21, 43, 37, 349, 89, 1581, 2105, 6753, 14577, 14339, 0 }; + static ulong[] dim2067Kuo3Init = { 1, 1, 1, 11, 21, 17, 55, 11, 87, 323, 647, 955, 1343, 10799, 15375, 0 }; + static ulong[] dim2068Kuo3Init = { 1, 3, 7, 13, 11, 43, 23, 25, 327, 797, 1111, 231, 4423, 5907, 16191, 0 }; + static ulong[] dim2069Kuo3Init = { 1, 3, 5, 15, 1, 15, 109, 43, 217, 905, 1295, 2373, 497, 11643, 14371, 0 }; + static ulong[] dim2070Kuo3Init = { 1, 1, 3, 5, 3, 43, 125, 249, 343, 947, 1523, 2393, 3073, 11301, 18751, 0 }; + static ulong[] dim2071Kuo3Init = { 1, 3, 1, 13, 31, 27, 23, 241, 103, 503, 1715, 877, 5269, 10665, 23927, 0 }; + static ulong[] dim2072Kuo3Init = { 1, 3, 1, 9, 21, 1, 91, 55, 297, 941, 1419, 3391, 811, 8399, 8513, 0 }; + static ulong[] dim2073Kuo3Init = { 1, 1, 5, 1, 7, 3, 17, 139, 461, 1007, 1835, 165, 1575, 15075, 18673, 0 }; + static ulong[] dim2074Kuo3Init = { 1, 3, 7, 11, 21, 63, 11, 123, 229, 767, 201, 3415, 4997, 14791, 27193, 0 }; + static ulong[] dim2075Kuo3Init = { 1, 3, 3, 9, 5, 13, 71, 163, 499, 933, 1829, 2321, 1773, 5255, 18219, 0 }; + static ulong[] dim2076Kuo3Init = { 1, 1, 5, 15, 15, 5, 47, 81, 167, 27, 773, 3607, 25, 12437, 11525, 0 }; + static ulong[] dim2077Kuo3Init = { 1, 3, 3, 11, 3, 21, 41, 1, 441, 1013, 1409, 3097, 5671, 3953, 51, 0 }; + static ulong[] dim2078Kuo3Init = { 1, 1, 3, 15, 15, 13, 93, 111, 355, 207, 1653, 2711, 81, 7801, 14105, 0 }; + static ulong[] dim2079Kuo3Init = { 1, 1, 5, 9, 15, 57, 47, 53, 79, 255, 517, 4015, 8123, 5557, 4245, 0 }; + static ulong[] dim2080Kuo3Init = { 1, 3, 1, 9, 25, 45, 97, 107, 107, 365, 1647, 3831, 5567, 167, 26977, 0 }; + static ulong[] dim2081Kuo3Init = { 1, 1, 1, 7, 31, 21, 79, 155, 391, 347, 1295, 255, 6439, 8201, 31975, 0 }; + static ulong[] dim2082Kuo3Init = { 1, 1, 1, 13, 19, 57, 9, 167, 359, 833, 709, 3437, 5031, 16221, 18491, 0 }; + static ulong[] dim2083Kuo3Init = { 1, 3, 3, 11, 17, 37, 39, 167, 271, 801, 601, 461, 3949, 5237, 3425, 0 }; + static ulong[] dim2084Kuo3Init = { 1, 3, 3, 13, 29, 47, 51, 161, 427, 421, 671, 2545, 4793, 10083, 3499, 0 }; + static ulong[] dim2085Kuo3Init = { 1, 3, 5, 7, 27, 25, 59, 75, 431, 891, 1557, 3615, 4759, 11267, 8473, 0 }; + static ulong[] dim2086Kuo3Init = { 1, 3, 1, 7, 7, 31, 63, 89, 353, 761, 1333, 1367, 5963, 12311, 20717, 0 }; + static ulong[] dim2087Kuo3Init = { 1, 3, 3, 1, 27, 19, 93, 209, 291, 119, 513, 3757, 3477, 2541, 4919, 0 }; + static ulong[] dim2088Kuo3Init = { 1, 3, 7, 1, 15, 9, 109, 41, 401, 365, 907, 3603, 6401, 12115, 28691, 0 }; + static ulong[] dim2089Kuo3Init = { 1, 1, 5, 9, 3, 21, 121, 27, 355, 571, 133, 1073, 4875, 13351, 13197, 0 }; + static ulong[] dim2090Kuo3Init = { 1, 3, 1, 3, 1, 31, 35, 171, 201, 617, 1181, 3621, 823, 8599, 4407, 0 }; + static ulong[] dim2091Kuo3Init = { 1, 3, 3, 3, 31, 61, 45, 19, 191, 843, 909, 391, 5899, 14059, 7879, 0 }; + static ulong[] dim2092Kuo3Init = { 1, 1, 7, 9, 19, 51, 123, 201, 163, 737, 153, 161, 7949, 2865, 17357, 0 }; + static ulong[] dim2093Kuo3Init = { 1, 3, 7, 11, 23, 51, 121, 165, 459, 959, 647, 535, 7903, 2935, 24895, 0 }; + static ulong[] dim2094Kuo3Init = { 1, 3, 5, 3, 1, 63, 73, 179, 485, 661, 255, 1423, 7277, 2109, 25113, 0 }; + static ulong[] dim2095Kuo3Init = { 1, 3, 5, 11, 27, 51, 79, 151, 389, 251, 277, 1785, 4073, 1729, 22705, 0 }; + static ulong[] dim2096Kuo3Init = { 1, 3, 3, 11, 23, 15, 105, 205, 413, 253, 1181, 2605, 6181, 1771, 17869, 0 }; + static ulong[] dim2097Kuo3Init = { 1, 3, 7, 13, 29, 45, 95, 37, 319, 609, 369, 3311, 5717, 7219, 25157, 0 }; + static ulong[] dim2098Kuo3Init = { 1, 1, 7, 15, 23, 3, 61, 125, 429, 29, 479, 1151, 4479, 8909, 9763, 0 }; + static ulong[] dim2099Kuo3Init = { 1, 3, 1, 13, 25, 21, 11, 147, 61, 903, 1719, 3065, 7089, 15041, 6387, 0 }; + static ulong[] dim2100Kuo3Init = { 1, 1, 5, 11, 17, 33, 43, 1, 271, 223, 363, 2799, 1043, 3929, 25991, 0 }; + static ulong[] dim2101Kuo3Init = { 1, 1, 7, 11, 3, 15, 115, 245, 383, 881, 221, 2045, 621, 14543, 1027, 0 }; + static ulong[] dim2102Kuo3Init = { 1, 3, 1, 7, 1, 45, 19, 133, 339, 883, 1643, 853, 7141, 6259, 6373, 0 }; + static ulong[] dim2103Kuo3Init = { 1, 1, 3, 11, 27, 23, 123, 159, 185, 693, 577, 473, 313, 13579, 19317, 0 }; + static ulong[] dim2104Kuo3Init = { 1, 3, 3, 15, 27, 19, 43, 23, 183, 925, 1987, 1945, 6341, 10771, 9669, 0 }; + static ulong[] dim2105Kuo3Init = { 1, 1, 1, 3, 15, 27, 49, 117, 347, 149, 23, 103, 3613, 3123, 32759, 0 }; + static ulong[] dim2106Kuo3Init = { 1, 3, 7, 13, 1, 37, 13, 111, 407, 319, 563, 1499, 6551, 13333, 659, 0 }; + static ulong[] dim2107Kuo3Init = { 1, 3, 3, 3, 23, 21, 9, 109, 393, 115, 415, 351, 6113, 2417, 14151, 0 }; + static ulong[] dim2108Kuo3Init = { 1, 3, 5, 7, 25, 7, 35, 41, 43, 663, 1809, 535, 7437, 12487, 1059, 0 }; + static ulong[] dim2109Kuo3Init = { 1, 3, 3, 11, 13, 13, 123, 111, 391, 199, 69, 2357, 4779, 7461, 5003, 0 }; + static ulong[] dim2110Kuo3Init = { 1, 1, 1, 13, 17, 63, 5, 163, 107, 609, 1979, 3389, 499, 13111, 219, 0 }; + static ulong[] dim2111Kuo3Init = { 1, 3, 7, 1, 19, 41, 43, 29, 35, 371, 1773, 3563, 2005, 8217, 5131, 0 }; + static ulong[] dim2112Kuo3Init = { 1, 3, 7, 15, 13, 53, 43, 167, 201, 259, 1855, 3971, 1179, 8591, 21425, 0 }; + static ulong[] dim2113Kuo3Init = { 1, 1, 1, 11, 27, 21, 45, 47, 185, 753, 531, 2553, 5515, 11501, 4623, 0 }; + static ulong[] dim2114Kuo3Init = { 1, 1, 7, 9, 9, 49, 29, 207, 441, 265, 1059, 1703, 1625, 9371, 23045, 0 }; + static ulong[] dim2115Kuo3Init = { 1, 3, 5, 9, 13, 29, 33, 185, 233, 11, 381, 3917, 4931, 3497, 24713, 0 }; + static ulong[] dim2116Kuo3Init = { 1, 3, 1, 11, 13, 61, 43, 147, 505, 251, 1875, 3009, 4695, 6793, 3083, 0 }; + static ulong[] dim2117Kuo3Init = { 1, 3, 3, 3, 31, 17, 119, 35, 111, 767, 211, 3227, 2539, 10755, 26177, 0 }; + static ulong[] dim2118Kuo3Init = { 1, 3, 1, 7, 9, 63, 3, 45, 195, 515, 103, 2327, 5967, 8087, 9849, 0 }; + static ulong[] dim2119Kuo3Init = { 1, 3, 7, 13, 31, 51, 55, 231, 451, 259, 1025, 2671, 5317, 7087, 7365, 0 }; + static ulong[] dim2120Kuo3Init = { 1, 3, 5, 3, 5, 41, 33, 255, 305, 831, 1279, 4013, 3899, 171, 8543, 0 }; + static ulong[] dim2121Kuo3Init = { 1, 1, 5, 9, 7, 9, 97, 125, 123, 3, 121, 4041, 3941, 1655, 25583, 0 }; + static ulong[] dim2122Kuo3Init = { 1, 1, 3, 3, 9, 63, 99, 53, 85, 57, 1117, 969, 7067, 1393, 17497, 0 }; + static ulong[] dim2123Kuo3Init = { 1, 1, 3, 7, 9, 51, 1, 207, 443, 967, 1387, 2515, 1789, 1493, 20941, 0 }; + static ulong[] dim2124Kuo3Init = { 1, 1, 5, 9, 15, 37, 11, 191, 503, 823, 1789, 4071, 3355, 9177, 27281, 0 }; + static ulong[] dim2125Kuo3Init = { 1, 3, 7, 5, 3, 61, 83, 19, 325, 543, 19, 239, 3513, 16147, 32395, 0 }; + static ulong[] dim2126Kuo3Init = { 1, 3, 5, 7, 1, 17, 101, 23, 379, 649, 853, 3045, 1301, 7215, 18851, 0 }; + static ulong[] dim2127Kuo3Init = { 1, 3, 5, 13, 25, 11, 41, 213, 137, 705, 1829, 1055, 3061, 9335, 5797, 0 }; + static ulong[] dim2128Kuo3Init = { 1, 3, 1, 13, 11, 21, 17, 117, 473, 687, 125, 4007, 5283, 11961, 15365, 0 }; + static ulong[] dim2129Kuo3Init = { 1, 3, 1, 13, 11, 19, 3, 189, 393, 219, 1229, 1521, 7137, 1811, 6745, 0 }; + static ulong[] dim2130Kuo3Init = { 1, 1, 7, 9, 21, 59, 23, 193, 321, 691, 735, 3731, 593, 9351, 6571, 0 }; + static ulong[] dim2131Kuo3Init = { 1, 3, 5, 5, 23, 55, 43, 107, 217, 111, 921, 1017, 7055, 16059, 8181, 0 }; + static ulong[] dim2132Kuo3Init = { 1, 3, 3, 3, 29, 57, 93, 91, 9, 453, 1245, 691, 1571, 5755, 13387, 0 }; + static ulong[] dim2133Kuo3Init = { 1, 1, 3, 1, 1, 23, 87, 239, 373, 433, 553, 2205, 4495, 3975, 25819, 0 }; + static ulong[] dim2134Kuo3Init = { 1, 1, 3, 1, 23, 7, 9, 227, 503, 87, 819, 3167, 4135, 9281, 8443, 0 }; + static ulong[] dim2135Kuo3Init = { 1, 1, 3, 5, 7, 27, 17, 81, 295, 131, 955, 4065, 797, 16165, 2385, 0 }; + static ulong[] dim2136Kuo3Init = { 1, 3, 3, 1, 9, 47, 113, 105, 277, 187, 1983, 2833, 2749, 4473, 31275, 0 }; + static ulong[] dim2137Kuo3Init = { 1, 3, 3, 3, 19, 61, 41, 51, 435, 933, 961, 459, 4187, 6619, 777, 0 }; + static ulong[] dim2138Kuo3Init = { 1, 3, 3, 9, 11, 25, 51, 219, 203, 897, 777, 3047, 2601, 4387, 14185, 0 }; + static ulong[] dim2139Kuo3Init = { 1, 3, 7, 15, 23, 17, 103, 55, 387, 127, 197, 1045, 3973, 10503, 23443, 0 }; + static ulong[] dim2140Kuo3Init = { 1, 1, 5, 9, 13, 59, 87, 253, 7, 879, 1335, 1349, 6353, 5897, 10021, 0 }; + static ulong[] dim2141Kuo3Init = { 1, 1, 3, 5, 19, 49, 107, 65, 229, 317, 169, 509, 1819, 2267, 13269, 0 }; + static ulong[] dim2142Kuo3Init = { 1, 3, 5, 13, 21, 25, 11, 143, 511, 107, 637, 3237, 3985, 15197, 23343, 0 }; + static ulong[] dim2143Kuo3Init = { 1, 1, 5, 15, 1, 15, 67, 91, 131, 501, 1803, 699, 2031, 11015, 17989, 0 }; + static ulong[] dim2144Kuo3Init = { 1, 1, 7, 13, 3, 55, 103, 245, 229, 121, 245, 1299, 3357, 3283, 26181, 0 }; + static ulong[] dim2145Kuo3Init = { 1, 1, 7, 1, 19, 53, 101, 125, 35, 963, 887, 3119, 1407, 723, 29169, 0 }; + static ulong[] dim2146Kuo3Init = { 1, 3, 7, 3, 27, 39, 29, 71, 7, 529, 329, 2811, 4627, 2865, 26837, 0 }; + static ulong[] dim2147Kuo3Init = { 1, 3, 5, 7, 29, 55, 71, 129, 455, 465, 1949, 3895, 6971, 15621, 26819, 0 }; + static ulong[] dim2148Kuo3Init = { 1, 1, 3, 15, 5, 63, 95, 15, 425, 347, 835, 1973, 5171, 3963, 23691, 0 }; + static ulong[] dim2149Kuo3Init = { 1, 3, 1, 9, 27, 23, 87, 237, 261, 349, 1777, 287, 3543, 35, 31891, 0 }; + static ulong[] dim2150Kuo3Init = { 1, 1, 7, 7, 17, 59, 7, 65, 45, 733, 239, 221, 6419, 9161, 17499, 0 }; + static ulong[] dim2151Kuo3Init = { 1, 3, 3, 15, 7, 53, 121, 97, 127, 583, 501, 1667, 6265, 3233, 19187, 0 }; + static ulong[] dim2152Kuo3Init = { 1, 1, 3, 1, 29, 17, 121, 89, 107, 787, 1699, 3389, 6191, 11503, 2461, 0 }; + static ulong[] dim2153Kuo3Init = { 1, 1, 1, 9, 13, 27, 97, 49, 447, 851, 147, 439, 277, 11129, 2201, 0 }; + static ulong[] dim2154Kuo3Init = { 1, 3, 3, 11, 29, 47, 93, 243, 101, 627, 1607, 459, 27, 10635, 1345, 0 }; + static ulong[] dim2155Kuo3Init = { 1, 1, 7, 3, 19, 11, 61, 253, 345, 523, 317, 1599, 5625, 14385, 3461, 0 }; + static ulong[] dim2156Kuo3Init = { 1, 1, 5, 13, 27, 59, 33, 251, 29, 787, 1655, 3383, 2451, 2499, 10719, 0 }; + static ulong[] dim2157Kuo3Init = { 1, 3, 7, 7, 1, 29, 97, 233, 193, 459, 1667, 47, 3059, 8713, 13259, 0 }; + static ulong[] dim2158Kuo3Init = { 1, 1, 3, 9, 29, 63, 127, 35, 105, 95, 887, 2337, 5999, 13553, 30225, 0 }; + static ulong[] dim2159Kuo3Init = { 1, 1, 7, 7, 17, 43, 47, 205, 497, 835, 1565, 3863, 785, 6149, 17595, 0 }; + static ulong[] dim2160Kuo3Init = { 1, 1, 1, 13, 29, 17, 47, 37, 339, 131, 1219, 3545, 3499, 2223, 3107, 0 }; + static ulong[] dim2161Kuo3Init = { 1, 1, 1, 15, 7, 17, 39, 25, 97, 691, 1645, 3333, 95, 15593, 11667, 0 }; + static ulong[] dim2162Kuo3Init = { 1, 3, 5, 7, 13, 21, 61, 147, 115, 249, 981, 665, 1245, 14397, 9571, 0 }; + static ulong[] dim2163Kuo3Init = { 1, 1, 3, 13, 15, 5, 7, 129, 151, 947, 375, 1631, 3247, 1321, 19495, 0 }; + static ulong[] dim2164Kuo3Init = { 1, 1, 5, 11, 5, 5, 69, 247, 53, 37, 683, 1581, 2997, 5897, 4797, 0 }; + static ulong[] dim2165Kuo3Init = { 1, 1, 5, 15, 5, 45, 115, 65, 509, 557, 1749, 2167, 4795, 629, 10749, 0 }; + static ulong[] dim2166Kuo3Init = { 1, 1, 3, 1, 25, 23, 99, 93, 99, 721, 1235, 1259, 2739, 11797, 15985, 0 }; + static ulong[] dim2167Kuo3Init = { 1, 3, 5, 11, 15, 29, 97, 103, 21, 981, 1717, 1483, 711, 12419, 14401, 0 }; + static ulong[] dim2168Kuo3Init = { 1, 3, 1, 1, 5, 5, 125, 159, 301, 733, 1987, 1679, 7459, 3493, 29377, 0 }; + static ulong[] dim2169Kuo3Init = { 1, 1, 7, 7, 29, 45, 53, 197, 303, 303, 931, 1171, 1771, 14895, 21525, 0 }; + static ulong[] dim2170Kuo3Init = { 1, 3, 7, 13, 11, 59, 93, 113, 219, 557, 397, 2639, 5089, 6833, 20455, 0 }; + static ulong[] dim2171Kuo3Init = { 1, 3, 1, 3, 11, 33, 117, 163, 359, 431, 915, 3285, 2443, 8225, 16341, 0 }; + static ulong[] dim2172Kuo3Init = { 1, 3, 1, 9, 19, 1, 105, 65, 3, 71, 705, 2047, 2169, 13129, 8575, 0 }; + static ulong[] dim2173Kuo3Init = { 1, 1, 1, 9, 23, 63, 67, 203, 429, 897, 1453, 101, 1445, 8553, 16355, 0 }; + static ulong[] dim2174Kuo3Init = { 1, 1, 7, 5, 13, 61, 79, 217, 83, 339, 529, 3573, 4075, 5929, 2687, 0 }; + static ulong[] dim2175Kuo3Init = { 1, 1, 7, 11, 27, 9, 93, 105, 179, 479, 1093, 3551, 5697, 8989, 1099, 0 }; + static ulong[] dim2176Kuo3Init = { 1, 1, 1, 11, 15, 9, 21, 59, 193, 231, 1817, 463, 1945, 13795, 28655, 0 }; + static ulong[] dim2177Kuo3Init = { 1, 1, 1, 5, 3, 27, 49, 179, 205, 49, 355, 667, 6573, 4317, 26599, 0 }; + static ulong[] dim2178Kuo3Init = { 1, 3, 7, 5, 9, 45, 121, 219, 309, 371, 1119, 1991, 5889, 14257, 1105, 0 }; + static ulong[] dim2179Kuo3Init = { 1, 1, 3, 3, 7, 19, 111, 191, 321, 77, 39, 1921, 563, 1049, 26623, 0 }; + static ulong[] dim2180Kuo3Init = { 1, 3, 3, 13, 13, 43, 21, 121, 181, 185, 629, 211, 7897, 9445, 12679, 0 }; + static ulong[] dim2181Kuo3Init = { 1, 1, 7, 15, 3, 19, 61, 159, 337, 711, 155, 2099, 2201, 14337, 21633, 0 }; + static ulong[] dim2182Kuo3Init = { 1, 1, 3, 9, 27, 63, 43, 209, 17, 565, 225, 2381, 4577, 15793, 4861, 0 }; + static ulong[] dim2183Kuo3Init = { 1, 3, 7, 3, 25, 51, 65, 187, 235, 479, 293, 789, 2453, 4367, 15835, 0 }; + static ulong[] dim2184Kuo3Init = { 1, 1, 5, 11, 17, 7, 115, 165, 3, 457, 455, 969, 5859, 2663, 15337, 0 }; + static ulong[] dim2185Kuo3Init = { 1, 3, 1, 13, 19, 1, 55, 177, 365, 395, 1043, 1095, 6531, 8599, 12867, 0 }; + static ulong[] dim2186Kuo3Init = { 1, 3, 7, 1, 29, 57, 55, 139, 187, 649, 1899, 355, 6447, 4521, 31497, 0 }; + static ulong[] dim2187Kuo3Init = { 1, 3, 5, 1, 19, 55, 73, 163, 127, 893, 1189, 2425, 5145, 15965, 5937, 0 }; + static ulong[] dim2188Kuo3Init = { 1, 3, 1, 1, 21, 33, 91, 81, 75, 39, 1, 397, 2799, 11987, 27829, 0 }; + static ulong[] dim2189Kuo3Init = { 1, 3, 7, 5, 25, 15, 95, 61, 351, 377, 1949, 3141, 6259, 135, 19307, 0 }; + static ulong[] dim2190Kuo3Init = { 1, 3, 3, 7, 7, 45, 1, 197, 235, 747, 1333, 3293, 1439, 7447, 26119, 0 }; + static ulong[] dim2191Kuo3Init = { 1, 3, 3, 3, 25, 31, 113, 159, 335, 587, 733, 1045, 5015, 9677, 21777, 0 }; + static ulong[] dim2192Kuo3Init = { 1, 1, 5, 3, 15, 55, 91, 181, 465, 409, 995, 3243, 6165, 1547, 31785, 0 }; + static ulong[] dim2193Kuo3Init = { 1, 3, 7, 3, 7, 47, 27, 87, 399, 265, 945, 1675, 5383, 4847, 27859, 0 }; + static ulong[] dim2194Kuo3Init = { 1, 1, 7, 3, 21, 53, 69, 107, 121, 855, 629, 1947, 8149, 10707, 2981, 0 }; + static ulong[] dim2195Kuo3Init = { 1, 3, 1, 11, 3, 25, 53, 87, 349, 237, 1745, 3705, 4273, 4109, 26059, 0 }; + static ulong[] dim2196Kuo3Init = { 1, 1, 5, 11, 25, 19, 11, 179, 301, 27, 1343, 79, 2475, 5581, 27225, 0 }; + static ulong[] dim2197Kuo3Init = { 1, 3, 7, 9, 29, 55, 119, 107, 431, 943, 1567, 3727, 7415, 2565, 24957, 0 }; + static ulong[] dim2198Kuo3Init = { 1, 3, 3, 1, 15, 27, 91, 159, 285, 781, 357, 643, 7445, 9931, 11881, 0 }; + static ulong[] dim2199Kuo3Init = { 1, 3, 7, 9, 5, 53, 65, 195, 273, 37, 1785, 467, 5211, 25, 1749, 0 }; + static ulong[] dim2200Kuo3Init = { 1, 1, 1, 11, 7, 11, 43, 143, 305, 825, 1055, 2995, 3907, 7581, 9679, 0 }; + static ulong[] dim2201Kuo3Init = { 1, 3, 1, 9, 31, 29, 93, 3, 299, 1, 1851, 395, 239, 8323, 18201, 0 }; + static ulong[] dim2202Kuo3Init = { 1, 1, 1, 5, 29, 29, 75, 3, 273, 759, 801, 2841, 5789, 6651, 19351, 0 }; + static ulong[] dim2203Kuo3Init = { 1, 3, 7, 1, 1, 11, 11, 215, 27, 955, 1397, 3483, 1317, 223, 20559, 0 }; + static ulong[] dim2204Kuo3Init = { 1, 3, 5, 13, 21, 23, 39, 189, 295, 255, 1457, 2821, 3145, 15437, 26997, 0 }; + static ulong[] dim2205Kuo3Init = { 1, 1, 3, 5, 9, 43, 13, 97, 259, 23, 933, 3867, 5921, 4199, 24721, 0 }; + static ulong[] dim2206Kuo3Init = { 1, 1, 3, 11, 1, 19, 89, 87, 17, 247, 1535, 2629, 2893, 12209, 23739, 0 }; + static ulong[] dim2207Kuo3Init = { 1, 1, 1, 1, 31, 15, 81, 37, 235, 249, 1437, 1485, 5889, 10017, 18593, 0 }; + static ulong[] dim2208Kuo3Init = { 1, 3, 7, 5, 17, 33, 117, 5, 31, 63, 2015, 3063, 5139, 14771, 29107, 0 }; + static ulong[] dim2209Kuo3Init = { 1, 1, 7, 15, 13, 3, 25, 127, 419, 945, 1739, 175, 1591, 4443, 27289, 0 }; + static ulong[] dim2210Kuo3Init = { 1, 1, 1, 7, 11, 59, 99, 119, 307, 857, 1711, 1201, 1623, 11429, 5663, 0 }; + static ulong[] dim2211Kuo3Init = { 1, 3, 1, 13, 17, 45, 65, 225, 131, 279, 587, 3487, 1123, 2753, 30789, 0 }; + static ulong[] dim2212Kuo3Init = { 1, 3, 3, 15, 21, 55, 17, 141, 109, 1021, 1387, 1407, 8163, 1983, 25971, 0 }; + static ulong[] dim2213Kuo3Init = { 1, 3, 3, 9, 21, 51, 103, 243, 435, 481, 857, 3353, 2717, 2295, 7999, 0 }; + static ulong[] dim2214Kuo3Init = { 1, 1, 1, 7, 7, 27, 83, 45, 359, 191, 259, 3229, 7869, 10729, 28587, 0 }; + static ulong[] dim2215Kuo3Init = { 1, 3, 7, 5, 19, 25, 51, 103, 37, 429, 995, 415, 2879, 2283, 29981, 0 }; + static ulong[] dim2216Kuo3Init = { 1, 1, 3, 3, 21, 19, 29, 35, 401, 19, 1761, 3735, 7775, 3365, 31767, 0 }; + static ulong[] dim2217Kuo3Init = { 1, 1, 7, 1, 29, 1, 9, 195, 279, 1003, 999, 4043, 3761, 11341, 7117, 0 }; + static ulong[] dim2218Kuo3Init = { 1, 1, 5, 11, 19, 7, 97, 181, 37, 929, 667, 993, 2517, 12683, 24487, 0 }; + static ulong[] dim2219Kuo3Init = { 1, 1, 3, 1, 31, 15, 47, 143, 511, 525, 1799, 1743, 3237, 12839, 2287, 0 }; + static ulong[] dim2220Kuo3Init = { 1, 3, 3, 15, 31, 59, 59, 205, 99, 233, 1857, 2469, 2661, 3675, 391, 0 }; + static ulong[] dim2221Kuo3Init = { 1, 3, 5, 15, 31, 23, 23, 1, 313, 401, 605, 3771, 2703, 6037, 7943, 0 }; + static ulong[] dim2222Kuo3Init = { 1, 1, 3, 13, 21, 19, 55, 139, 273, 725, 1239, 595, 549, 15279, 20887, 0 }; + static ulong[] dim2223Kuo3Init = { 1, 1, 5, 3, 13, 9, 39, 83, 257, 323, 1801, 167, 3747, 2867, 30151, 0 }; + static ulong[] dim2224Kuo3Init = { 1, 3, 3, 3, 17, 3, 67, 163, 325, 569, 1099, 4037, 5003, 6985, 7445, 0 }; + static ulong[] dim2225Kuo3Init = { 1, 3, 7, 13, 31, 37, 13, 91, 21, 763, 785, 1461, 5257, 15307, 16389, 0 }; + static ulong[] dim2226Kuo3Init = { 1, 3, 5, 13, 1, 35, 27, 179, 429, 21, 865, 775, 4993, 335, 12479, 0 }; + static ulong[] dim2227Kuo3Init = { 1, 3, 1, 1, 19, 1, 111, 201, 219, 709, 1539, 1905, 647, 8605, 14129, 0 }; + static ulong[] dim2228Kuo3Init = { 1, 3, 5, 7, 21, 7, 117, 251, 311, 689, 1125, 1931, 6363, 7409, 4189, 0 }; + static ulong[] dim2229Kuo3Init = { 1, 1, 3, 7, 1, 27, 93, 5, 395, 117, 113, 1297, 501, 13073, 30483, 0 }; + static ulong[] dim2230Kuo3Init = { 1, 1, 3, 11, 19, 57, 65, 67, 13, 893, 551, 539, 2861, 10635, 16057, 0 }; + static ulong[] dim2231Kuo3Init = { 1, 3, 3, 11, 19, 5, 41, 43, 161, 1015, 33, 471, 229, 13315, 10791, 0 }; + static ulong[] dim2232Kuo3Init = { 1, 3, 1, 7, 1, 13, 97, 149, 321, 131, 1389, 715, 5421, 343, 4129, 0 }; + static ulong[] dim2233Kuo3Init = { 1, 1, 3, 11, 15, 51, 91, 57, 229, 1007, 709, 2745, 147, 10427, 21151, 0 }; + static ulong[] dim2234Kuo3Init = { 1, 3, 7, 15, 1, 31, 65, 251, 75, 553, 133, 1027, 4857, 7139, 10591, 0 }; + static ulong[] dim2235Kuo3Init = { 1, 3, 5, 15, 13, 11, 49, 183, 263, 121, 981, 1421, 7781, 5313, 3245, 0 }; + static ulong[] dim2236Kuo3Init = { 1, 3, 5, 15, 31, 27, 109, 85, 327, 999, 1063, 705, 6047, 13227, 5817, 0 }; + static ulong[] dim2237Kuo3Init = { 1, 1, 5, 15, 9, 5, 99, 69, 91, 637, 1353, 2471, 7003, 9429, 25235, 0 }; + static ulong[] dim2238Kuo3Init = { 1, 3, 3, 11, 1, 25, 77, 67, 173, 929, 1919, 4021, 5587, 3333, 12769, 0 }; + static ulong[] dim2239Kuo3Init = { 1, 1, 5, 15, 15, 9, 11, 71, 465, 831, 1127, 3439, 6793, 1269, 1699, 0 }; + static ulong[] dim2240Kuo3Init = { 1, 3, 1, 1, 17, 43, 45, 181, 147, 501, 283, 3875, 7221, 14487, 2549, 0 }; + static ulong[] dim2241Kuo3Init = { 1, 3, 7, 11, 1, 21, 125, 179, 479, 367, 1961, 607, 255, 913, 16143, 0 }; + static ulong[] dim2242Kuo3Init = { 1, 3, 3, 15, 7, 49, 117, 97, 45, 729, 1331, 1373, 2147, 11673, 9779, 0 }; + static ulong[] dim2243Kuo3Init = { 1, 3, 5, 11, 1, 11, 105, 231, 237, 449, 1195, 33, 4531, 11591, 29539, 0 }; + static ulong[] dim2244Kuo3Init = { 1, 3, 3, 3, 27, 47, 105, 85, 25, 663, 47, 3213, 6777, 11947, 28993, 0 }; + static ulong[] dim2245Kuo3Init = { 1, 1, 5, 15, 11, 57, 121, 107, 327, 631, 285, 921, 3721, 7983, 9199, 0 }; + static ulong[] dim2246Kuo3Init = { 1, 1, 1, 13, 3, 61, 49, 101, 415, 187, 1645, 2139, 143, 12033, 11409, 0 }; + static ulong[] dim2247Kuo3Init = { 1, 1, 5, 13, 7, 15, 27, 143, 17, 977, 495, 2479, 1507, 10621, 2119, 0 }; + static ulong[] dim2248Kuo3Init = { 1, 1, 5, 13, 11, 9, 53, 159, 479, 333, 1423, 2559, 5497, 12611, 22627, 0 }; + static ulong[] dim2249Kuo3Init = { 1, 1, 5, 9, 7, 55, 3, 137, 421, 661, 113, 925, 1649, 12405, 30035, 0 }; + static ulong[] dim2250Kuo3Init = { 1, 3, 1, 13, 9, 31, 25, 233, 241, 239, 505, 2685, 223, 4389, 28191, 0 }; + static ulong[] dim2251Kuo3Init = { 1, 1, 3, 3, 23, 59, 5, 181, 491, 111, 1289, 3717, 4429, 15091, 25375, 0 }; + static ulong[] dim2252Kuo3Init = { 1, 3, 1, 3, 25, 3, 3, 7, 163, 247, 1673, 3061, 2355, 12779, 20039, 0 }; + static ulong[] dim2253Kuo3Init = { 1, 1, 1, 5, 3, 35, 5, 107, 387, 99, 1841, 3607, 2027, 6353, 15929, 0 }; + static ulong[] dim2254Kuo3Init = { 1, 1, 7, 7, 29, 45, 43, 207, 383, 681, 769, 3939, 8161, 10235, 24209, 0 }; + static ulong[] dim2255Kuo3Init = { 1, 3, 1, 5, 5, 13, 73, 99, 233, 327, 1429, 487, 3925, 5169, 5477, 0 }; + static ulong[] dim2256Kuo3Init = { 1, 1, 1, 5, 21, 63, 39, 17, 227, 455, 1559, 113, 3993, 7935, 8995, 0 }; + static ulong[] dim2257Kuo3Init = { 1, 1, 3, 11, 17, 51, 43, 231, 69, 475, 761, 4011, 4007, 14829, 29961, 0 }; + static ulong[] dim2258Kuo3Init = { 1, 3, 1, 5, 19, 37, 49, 197, 277, 391, 583, 2711, 4041, 6029, 29559, 0 }; + static ulong[] dim2259Kuo3Init = { 1, 3, 3, 1, 7, 53, 33, 33, 325, 171, 63, 2929, 641, 7143, 12585, 0 }; + static ulong[] dim2260Kuo3Init = { 1, 1, 1, 9, 1, 31, 23, 157, 437, 355, 595, 239, 1275, 4917, 31055, 0 }; + static ulong[] dim2261Kuo3Init = { 1, 3, 7, 15, 15, 43, 39, 51, 431, 131, 741, 3473, 1947, 4223, 27943, 0 }; + static ulong[] dim2262Kuo3Init = { 1, 1, 7, 1, 27, 49, 5, 197, 33, 611, 1131, 429, 4931, 1243, 5787, 0 }; + static ulong[] dim2263Kuo3Init = { 1, 1, 7, 9, 29, 19, 89, 139, 239, 421, 951, 3749, 1557, 3803, 7155, 0 }; + static ulong[] dim2264Kuo3Init = { 1, 1, 7, 13, 15, 53, 121, 123, 99, 677, 1519, 3051, 5235, 8061, 21353, 0 }; + static ulong[] dim2265Kuo3Init = { 1, 1, 3, 7, 21, 53, 65, 35, 389, 141, 253, 2867, 803, 11525, 9901, 0 }; + static ulong[] dim2266Kuo3Init = { 1, 1, 7, 7, 21, 37, 81, 53, 121, 15, 1741, 2225, 183, 7155, 7597, 0 }; + static ulong[] dim2267Kuo3Init = { 1, 1, 7, 15, 29, 29, 13, 197, 291, 765, 1479, 2211, 5949, 5045, 32519, 0 }; + static ulong[] dim2268Kuo3Init = { 1, 3, 3, 5, 5, 19, 121, 219, 121, 17, 1223, 2685, 8179, 391, 31257, 0 }; + static ulong[] dim2269Kuo3Init = { 1, 1, 5, 7, 13, 27, 29, 71, 7, 95, 255, 9, 2375, 3325, 29915, 0 }; + static ulong[] dim2270Kuo3Init = { 1, 3, 3, 1, 1, 3, 11, 43, 233, 663, 715, 585, 3701, 13559, 3197, 0 }; + static ulong[] dim2271Kuo3Init = { 1, 1, 7, 5, 17, 45, 103, 209, 61, 923, 517, 249, 5775, 14537, 15371, 0 }; + static ulong[] dim2272Kuo3Init = { 1, 1, 5, 1, 7, 5, 123, 99, 137, 277, 1071, 3371, 7095, 2765, 28945, 0 }; + static ulong[] dim2273Kuo3Init = { 1, 1, 3, 15, 1, 59, 85, 5, 475, 855, 1793, 2479, 4989, 7155, 6403, 0 }; + static ulong[] dim2274Kuo3Init = { 1, 1, 5, 5, 3, 29, 41, 129, 373, 839, 1031, 2845, 6911, 4793, 25609, 0 }; + static ulong[] dim2275Kuo3Init = { 1, 1, 3, 5, 23, 55, 79, 209, 131, 893, 1933, 1391, 6873, 407, 28823, 0 }; + static ulong[] dim2276Kuo3Init = { 1, 1, 3, 15, 15, 57, 37, 153, 415, 947, 1959, 1513, 7961, 4931, 749, 0 }; + static ulong[] dim2277Kuo3Init = { 1, 1, 3, 3, 21, 5, 27, 169, 349, 541, 533, 3411, 945, 5275, 665, 0 }; + static ulong[] dim2278Kuo3Init = { 1, 1, 7, 15, 15, 17, 97, 225, 85, 887, 1251, 1485, 3987, 10753, 18013, 0 }; + static ulong[] dim2279Kuo3Init = { 1, 3, 1, 15, 19, 53, 117, 153, 279, 397, 1929, 3621, 3887, 7753, 22075, 0 }; + static ulong[] dim2280Kuo3Init = { 1, 3, 1, 5, 7, 21, 97, 63, 403, 715, 579, 1645, 2069, 9279, 14291, 0 }; + static ulong[] dim2281Kuo3Init = { 1, 1, 1, 3, 21, 17, 63, 61, 207, 795, 737, 4047, 3559, 6971, 14903, 0 }; + static ulong[] dim2282Kuo3Init = { 1, 3, 7, 5, 29, 1, 103, 109, 57, 485, 1373, 3399, 6351, 13037, 17193, 0 }; + static ulong[] dim2283Kuo3Init = { 1, 1, 7, 7, 5, 15, 105, 225, 215, 53, 1125, 3255, 3277, 2125, 23359, 0 }; + static ulong[] dim2284Kuo3Init = { 1, 3, 1, 7, 31, 39, 19, 163, 197, 831, 1959, 1227, 6515, 8839, 20105, 0 }; + static ulong[] dim2285Kuo3Init = { 1, 3, 3, 1, 27, 31, 89, 133, 451, 371, 1513, 1595, 771, 7637, 32403, 0 }; + static ulong[] dim2286Kuo3Init = { 1, 3, 3, 13, 29, 45, 29, 157, 117, 461, 913, 3907, 4225, 5617, 28917, 0 }; + static ulong[] dim2287Kuo3Init = { 1, 3, 7, 3, 13, 63, 113, 49, 137, 641, 275, 1179, 8139, 519, 5851, 0 }; + static ulong[] dim2288Kuo3Init = { 1, 1, 1, 1, 31, 43, 61, 193, 173, 651, 1491, 1005, 7559, 1963, 8323, 0 }; + static ulong[] dim2289Kuo3Init = { 1, 3, 5, 5, 23, 23, 11, 111, 95, 487, 1091, 175, 25, 10557, 24493, 0 }; + static ulong[] dim2290Kuo3Init = { 1, 1, 1, 9, 1, 31, 97, 175, 249, 309, 1005, 3777, 5551, 2605, 28071, 0 }; + static ulong[] dim2291Kuo3Init = { 1, 3, 3, 7, 13, 1, 113, 103, 169, 853, 35, 3645, 6907, 13713, 12811, 0 }; + static ulong[] dim2292Kuo3Init = { 1, 1, 7, 3, 25, 49, 53, 23, 33, 967, 2039, 2057, 799, 1527, 3427, 0 }; + static ulong[] dim2293Kuo3Init = { 1, 1, 5, 7, 29, 43, 81, 155, 59, 201, 1571, 1719, 3343, 3231, 27929, 0 }; + static ulong[] dim2294Kuo3Init = { 1, 1, 5, 1, 27, 17, 1, 159, 209, 749, 1883, 1885, 2511, 15957, 3471, 0 }; + static ulong[] dim2295Kuo3Init = { 1, 3, 1, 5, 7, 51, 15, 245, 57, 627, 1315, 673, 5329, 1043, 555, 0 }; + static ulong[] dim2296Kuo3Init = { 1, 1, 5, 11, 13, 55, 103, 157, 329, 171, 393, 3967, 373, 7225, 25133, 0 }; + static ulong[] dim2297Kuo3Init = { 1, 1, 5, 7, 5, 51, 109, 11, 111, 859, 165, 3991, 7187, 697, 28035, 0 }; + static ulong[] dim2298Kuo3Init = { 1, 3, 1, 9, 23, 55, 59, 173, 55, 105, 1103, 1569, 3099, 10483, 18821, 0 }; + static ulong[] dim2299Kuo3Init = { 1, 3, 7, 5, 21, 3, 23, 247, 13, 59, 1327, 2393, 5023, 11163, 21443, 0 }; + static ulong[] dim2300Kuo3Init = { 1, 3, 3, 15, 19, 47, 79, 45, 127, 313, 1609, 273, 4729, 7363, 13541, 0 }; + static ulong[] dim2301Kuo3Init = { 1, 3, 7, 15, 21, 61, 91, 247, 477, 539, 1969, 3541, 3983, 8339, 32499, 0 }; + static ulong[] dim2302Kuo3Init = { 1, 3, 7, 11, 13, 7, 47, 57, 299, 907, 701, 2039, 5509, 7489, 30175, 0 }; + static ulong[] dim2303Kuo3Init = { 1, 3, 7, 7, 9, 21, 125, 241, 69, 405, 1989, 3777, 613, 9827, 19447, 0 }; + static ulong[] dim2304Kuo3Init = { 1, 3, 7, 3, 19, 39, 19, 43, 1, 1007, 1829, 3099, 4001, 2181, 5849, 0 }; + static ulong[] dim2305Kuo3Init = { 1, 1, 7, 1, 9, 49, 21, 103, 107, 473, 1913, 2983, 5669, 977, 21281, 0 }; + static ulong[] dim2306Kuo3Init = { 1, 3, 5, 3, 3, 37, 79, 239, 425, 949, 1953, 3867, 2537, 16117, 945, 0 }; + static ulong[] dim2307Kuo3Init = { 1, 3, 5, 13, 23, 7, 119, 221, 321, 881, 1505, 3993, 3677, 4095, 10501, 0 }; + static ulong[] dim2308Kuo3Init = { 1, 1, 1, 3, 7, 17, 5, 223, 3, 891, 1699, 823, 3839, 4113, 16039, 0 }; + static ulong[] dim2309Kuo3Init = { 1, 1, 7, 5, 27, 35, 67, 89, 291, 521, 411, 3025, 1427, 12131, 4449, 0 }; + static ulong[] dim2310Kuo3Init = { 1, 1, 3, 7, 13, 61, 103, 113, 195, 269, 75, 3879, 7669, 9403, 13341, 0 }; + static ulong[] dim2311Kuo3Init = { 1, 3, 7, 13, 21, 17, 101, 135, 153, 615, 755, 2589, 653, 11187, 2997, 0 }; + static ulong[] dim2312Kuo3Init = { 1, 3, 1, 9, 11, 53, 61, 171, 423, 857, 465, 819, 4341, 6377, 21305, 0 }; + static ulong[] dim2313Kuo3Init = { 1, 3, 5, 3, 17, 37, 63, 91, 157, 877, 1801, 587, 6183, 12923, 15991, 0 }; + static ulong[] dim2314Kuo3Init = { 1, 3, 7, 5, 27, 63, 123, 27, 243, 375, 191, 3333, 965, 889, 15771, 0 }; + static ulong[] dim2315Kuo3Init = { 1, 3, 7, 15, 23, 51, 49, 187, 201, 861, 1581, 1045, 493, 9939, 30893, 0 }; + static ulong[] dim2316Kuo3Init = { 1, 3, 3, 15, 1, 31, 93, 125, 57, 147, 663, 2733, 4601, 16043, 6875, 0 }; + static ulong[] dim2317Kuo3Init = { 1, 3, 7, 11, 15, 1, 45, 251, 173, 807, 1301, 507, 645, 10383, 14737, 0 }; + static ulong[] dim2318Kuo3Init = { 1, 3, 7, 7, 27, 3, 3, 127, 153, 151, 1987, 2255, 5201, 11095, 20757, 0 }; + static ulong[] dim2319Kuo3Init = { 1, 1, 5, 1, 13, 49, 69, 55, 205, 547, 701, 1449, 6689, 3047, 12025, 0 }; + static ulong[] dim2320Kuo3Init = { 1, 1, 7, 9, 13, 27, 31, 87, 263, 499, 1573, 619, 6697, 9797, 7673, 0 }; + static ulong[] dim2321Kuo3Init = { 1, 1, 3, 3, 1, 43, 45, 81, 241, 143, 2045, 2847, 7361, 12253, 27815, 0 }; + static ulong[] dim2322Kuo3Init = { 1, 1, 3, 11, 27, 13, 71, 119, 365, 245, 113, 2635, 7157, 4951, 3381, 0 }; + static ulong[] dim2323Kuo3Init = { 1, 1, 7, 7, 25, 23, 101, 21, 247, 149, 431, 3165, 4109, 14305, 22549, 0 }; + static ulong[] dim2324Kuo3Init = { 1, 1, 5, 1, 3, 51, 79, 7, 473, 337, 709, 127, 555, 12147, 19843, 0 }; + static ulong[] dim2325Kuo3Init = { 1, 1, 3, 5, 21, 35, 125, 51, 373, 859, 1429, 2623, 787, 9669, 14933, 0 }; + static ulong[] dim2326Kuo3Init = { 1, 1, 1, 9, 25, 45, 47, 251, 475, 823, 1361, 1393, 6787, 14571, 11311, 0 }; + static ulong[] dim2327Kuo3Init = { 1, 3, 3, 13, 1, 27, 75, 153, 19, 373, 209, 3083, 8071, 15401, 14619, 0 }; + static ulong[] dim2328Kuo3Init = { 1, 1, 1, 13, 25, 39, 73, 235, 251, 245, 247, 1909, 2057, 14937, 16509, 0 }; + static ulong[] dim2329Kuo3Init = { 1, 1, 5, 11, 31, 15, 117, 167, 79, 911, 403, 3595, 4633, 11017, 5021, 0 }; + static ulong[] dim2330Kuo3Init = { 1, 1, 1, 9, 9, 37, 19, 179, 417, 285, 1237, 2667, 2131, 5943, 21265, 0 }; + static ulong[] dim2331Kuo3Init = { 1, 3, 7, 13, 29, 53, 89, 223, 37, 101, 1255, 97, 3813, 8543, 17949, 0 }; + static ulong[] dim2332Kuo3Init = { 1, 1, 1, 13, 25, 61, 33, 145, 271, 639, 1539, 2967, 1043, 10259, 27997, 0 }; + static ulong[] dim2333Kuo3Init = { 1, 1, 3, 7, 11, 17, 21, 21, 159, 485, 1855, 3139, 6605, 9567, 21401, 0 }; + static ulong[] dim2334Kuo3Init = { 1, 3, 7, 9, 27, 23, 23, 121, 17, 45, 537, 3155, 2409, 15359, 16105, 0 }; + static ulong[] dim2335Kuo3Init = { 1, 1, 3, 13, 11, 51, 87, 251, 297, 227, 411, 3737, 3649, 14697, 665, 0 }; + static ulong[] dim2336Kuo3Init = { 1, 3, 5, 11, 23, 23, 3, 75, 99, 149, 1505, 1137, 6495, 12629, 29339, 0 }; + static ulong[] dim2337Kuo3Init = { 1, 3, 1, 9, 29, 1, 83, 233, 387, 801, 1387, 2721, 1399, 2275, 19865, 0 }; + static ulong[] dim2338Kuo3Init = { 1, 3, 7, 7, 31, 33, 1, 253, 71, 435, 781, 2991, 6881, 13183, 10419, 0 }; + static ulong[] dim2339Kuo3Init = { 1, 1, 5, 11, 19, 61, 25, 167, 79, 173, 447, 911, 6509, 5531, 9387, 0 }; + static ulong[] dim2340Kuo3Init = { 1, 1, 1, 15, 31, 23, 117, 1, 119, 939, 1277, 2517, 2019, 4979, 4065, 0 }; + static ulong[] dim2341Kuo3Init = { 1, 3, 3, 9, 5, 49, 87, 187, 159, 941, 303, 217, 5931, 9065, 20043, 0 }; + static ulong[] dim2342Kuo3Init = { 1, 3, 1, 11, 31, 43, 25, 45, 61, 361, 2043, 817, 8023, 14309, 6781, 0 }; + static ulong[] dim2343Kuo3Init = { 1, 3, 7, 9, 27, 45, 97, 189, 387, 379, 621, 2449, 39, 10313, 14603, 0 }; + static ulong[] dim2344Kuo3Init = { 1, 3, 1, 5, 5, 45, 89, 251, 103, 33, 1141, 2957, 6511, 8497, 16609, 0 }; + static ulong[] dim2345Kuo3Init = { 1, 3, 5, 15, 19, 11, 115, 255, 277, 419, 15, 999, 7509, 14191, 2749, 0 }; + static ulong[] dim2346Kuo3Init = { 1, 1, 1, 7, 7, 51, 127, 225, 295, 389, 1039, 2775, 5531, 10645, 13391, 0 }; + static ulong[] dim2347Kuo3Init = { 1, 3, 3, 11, 13, 63, 37, 5, 3, 737, 123, 777, 1469, 4009, 17037, 0 }; + static ulong[] dim2348Kuo3Init = { 1, 1, 3, 5, 31, 43, 59, 119, 287, 973, 541, 751, 5697, 7909, 28673, 0 }; + static ulong[] dim2349Kuo3Init = { 1, 1, 5, 7, 15, 61, 71, 213, 465, 961, 1399, 3227, 571, 10759, 13947, 0 }; + static ulong[] dim2350Kuo3Init = { 1, 1, 5, 9, 17, 53, 85, 11, 185, 397, 567, 3763, 483, 6243, 31191, 0 }; + static ulong[] dim2351Kuo3Init = { 1, 3, 7, 1, 31, 57, 13, 255, 495, 315, 763, 3153, 5543, 5719, 2235, 0 }; + static ulong[] dim2352Kuo3Init = { 1, 1, 1, 1, 13, 25, 43, 125, 391, 483, 1029, 3739, 4991, 891, 24935, 0 }; + static ulong[] dim2353Kuo3Init = { 1, 3, 7, 3, 21, 3, 79, 205, 87, 3, 1859, 1467, 6129, 14431, 18881, 0 }; + static ulong[] dim2354Kuo3Init = { 1, 1, 1, 11, 15, 21, 79, 145, 253, 595, 1939, 2195, 5735, 5383, 5311, 0 }; + static ulong[] dim2355Kuo3Init = { 1, 1, 7, 3, 13, 61, 89, 3, 231, 867, 1385, 183, 957, 791, 2879, 0 }; + static ulong[] dim2356Kuo3Init = { 1, 3, 5, 7, 1, 39, 47, 107, 217, 725, 1707, 2241, 2813, 5373, 23191, 0 }; + static ulong[] dim2357Kuo3Init = { 1, 1, 1, 5, 27, 29, 119, 159, 287, 343, 693, 519, 2127, 6083, 2991, 0 }; + static ulong[] dim2358Kuo3Init = { 1, 3, 3, 11, 3, 51, 11, 119, 337, 567, 1175, 235, 6801, 1643, 26593, 0 }; + static ulong[] dim2359Kuo3Init = { 1, 1, 5, 3, 27, 49, 91, 249, 489, 257, 1735, 3227, 1419, 4401, 12263, 0 }; + static ulong[] dim2360Kuo3Init = { 1, 1, 3, 13, 27, 37, 101, 43, 289, 313, 1031, 2921, 3655, 6781, 29593, 0 }; + static ulong[] dim2361Kuo3Init = { 1, 1, 5, 5, 17, 23, 117, 129, 261, 919, 265, 1561, 1297, 815, 4315, 0 }; + static ulong[] dim2362Kuo3Init = { 1, 1, 3, 13, 23, 31, 95, 231, 99, 909, 1477, 3385, 5679, 15319, 28849, 0 }; + static ulong[] dim2363Kuo3Init = { 1, 1, 5, 11, 25, 27, 69, 83, 15, 31, 1469, 751, 2339, 3251, 17343, 0 }; + static ulong[] dim2364Kuo3Init = { 1, 1, 1, 9, 5, 19, 49, 25, 145, 763, 667, 2003, 6905, 15623, 3533, 0 }; + static ulong[] dim2365Kuo3Init = { 1, 1, 1, 5, 5, 17, 65, 151, 333, 639, 1885, 3561, 1083, 7875, 22647, 0 }; + static ulong[] dim2366Kuo3Init = { 1, 3, 5, 7, 25, 45, 79, 175, 87, 305, 1447, 1935, 3627, 6007, 27877, 0 }; + static ulong[] dim2367Kuo3Init = { 1, 3, 7, 1, 11, 37, 63, 37, 323, 405, 1851, 435, 1501, 1345, 13729, 0 }; + static ulong[] dim2368Kuo3Init = { 1, 3, 7, 13, 9, 37, 115, 151, 255, 795, 811, 681, 5631, 489, 21813, 0 }; + static ulong[] dim2369Kuo3Init = { 1, 1, 1, 11, 13, 25, 61, 91, 367, 289, 1093, 41, 5073, 1105, 28059, 0 }; + static ulong[] dim2370Kuo3Init = { 1, 1, 3, 13, 29, 53, 13, 173, 83, 313, 1223, 719, 517, 11689, 28719, 0 }; + static ulong[] dim2371Kuo3Init = { 1, 1, 5, 3, 5, 21, 71, 229, 95, 187, 739, 2607, 601, 2359, 10603, 0 }; + static ulong[] dim2372Kuo3Init = { 1, 1, 1, 5, 25, 35, 55, 131, 173, 677, 1887, 3293, 7641, 13535, 25561, 0 }; + static ulong[] dim2373Kuo3Init = { 1, 3, 5, 13, 29, 47, 27, 1, 131, 345, 1751, 1807, 235, 1891, 5909, 0 }; + static ulong[] dim2374Kuo3Init = { 1, 1, 3, 3, 15, 41, 55, 201, 263, 831, 401, 2685, 7403, 11827, 15353, 0 }; + static ulong[] dim2375Kuo3Init = { 1, 3, 1, 7, 5, 3, 99, 61, 433, 641, 1817, 891, 1937, 7179, 14391, 0 }; + static ulong[] dim2376Kuo3Init = { 1, 1, 5, 15, 19, 33, 37, 223, 329, 5, 1897, 2737, 4339, 9325, 12199, 0 }; + static ulong[] dim2377Kuo3Init = { 1, 1, 5, 3, 3, 23, 47, 125, 85, 61, 1133, 2467, 1991, 8059, 153, 0 }; + static ulong[] dim2378Kuo3Init = { 1, 1, 1, 15, 29, 45, 117, 133, 447, 627, 525, 173, 1165, 11939, 21807, 0 }; + static ulong[] dim2379Kuo3Init = { 1, 1, 1, 3, 1, 15, 5, 49, 237, 675, 717, 2783, 4287, 11485, 3797, 0 }; + static ulong[] dim2380Kuo3Init = { 1, 3, 5, 15, 19, 63, 23, 79, 313, 1007, 1321, 229, 7537, 825, 29127, 0 }; + static ulong[] dim2381Kuo3Init = { 1, 1, 3, 15, 15, 55, 1, 229, 221, 359, 1021, 3307, 4993, 8781, 29275, 0 }; + static ulong[] dim2382Kuo3Init = { 1, 3, 3, 11, 17, 57, 37, 207, 283, 599, 1867, 31, 6631, 10605, 29671, 0 }; + static ulong[] dim2383Kuo3Init = { 1, 3, 3, 9, 25, 9, 111, 87, 325, 515, 1249, 2027, 7783, 6473, 23737, 0 }; + static ulong[] dim2384Kuo3Init = { 1, 3, 3, 3, 31, 11, 39, 161, 65, 259, 1747, 597, 913, 12397, 25611, 0 }; + static ulong[] dim2385Kuo3Init = { 1, 3, 5, 11, 31, 37, 27, 157, 411, 785, 1699, 467, 3993, 6357, 11039, 0 }; + static ulong[] dim2386Kuo3Init = { 1, 3, 3, 7, 5, 41, 61, 103, 33, 789, 1861, 319, 7667, 10169, 10823, 0 }; + static ulong[] dim2387Kuo3Init = { 1, 1, 7, 5, 31, 37, 45, 175, 453, 423, 291, 3989, 2215, 11379, 28713, 0 }; + static ulong[] dim2388Kuo3Init = { 1, 3, 3, 1, 23, 39, 75, 103, 341, 961, 2039, 1539, 7831, 1665, 18579, 0 }; + static ulong[] dim2389Kuo3Init = { 1, 1, 5, 13, 19, 25, 27, 183, 241, 539, 257, 3, 3709, 8133, 31081, 0 }; + static ulong[] dim2390Kuo3Init = { 1, 1, 3, 15, 1, 53, 27, 229, 299, 913, 1277, 2687, 831, 1065, 4409, 0 }; + static ulong[] dim2391Kuo3Init = { 1, 1, 7, 9, 13, 47, 127, 145, 481, 751, 1745, 3645, 2853, 5601, 14991, 0 }; + static ulong[] dim2392Kuo3Init = { 1, 3, 7, 3, 3, 39, 31, 191, 69, 707, 1757, 223, 5055, 14777, 4433, 0 }; + static ulong[] dim2393Kuo3Init = { 1, 1, 7, 15, 27, 33, 77, 75, 357, 1007, 1373, 3445, 2597, 6085, 19441, 0 }; + static ulong[] dim2394Kuo3Init = { 1, 1, 1, 9, 13, 53, 77, 61, 425, 245, 1149, 1239, 1989, 1293, 12971, 0 }; + static ulong[] dim2395Kuo3Init = { 1, 1, 1, 7, 23, 43, 29, 89, 349, 411, 2021, 2075, 4917, 11387, 27045, 0 }; + static ulong[] dim2396Kuo3Init = { 1, 1, 5, 11, 27, 63, 71, 19, 363, 289, 1147, 2541, 4427, 591, 21287, 0 }; + static ulong[] dim2397Kuo3Init = { 1, 1, 1, 3, 27, 3, 1, 159, 85, 651, 1109, 1885, 5639, 11725, 1527, 0 }; + static ulong[] dim2398Kuo3Init = { 1, 1, 3, 1, 11, 63, 77, 185, 233, 129, 1721, 2419, 2043, 3121, 2159, 0 }; + static ulong[] dim2399Kuo3Init = { 1, 1, 1, 3, 11, 27, 83, 193, 143, 89, 1927, 3753, 4041, 10397, 1973, 0 }; + static ulong[] dim2400Kuo3Init = { 1, 1, 5, 1, 9, 61, 49, 29, 333, 621, 1555, 4051, 3011, 12075, 4699, 0 }; + static ulong[] dim2401Kuo3Init = { 1, 3, 1, 5, 25, 37, 69, 81, 271, 827, 763, 2973, 3729, 2339, 4783, 0 }; + static ulong[] dim2402Kuo3Init = { 1, 3, 1, 7, 23, 1, 95, 143, 417, 517, 1991, 1423, 7511, 125, 18675, 0 }; + static ulong[] dim2403Kuo3Init = { 1, 3, 5, 9, 3, 43, 71, 73, 443, 335, 737, 1121, 8001, 13165, 11155, 0 }; + static ulong[] dim2404Kuo3Init = { 1, 3, 1, 11, 1, 21, 39, 149, 261, 963, 117, 3421, 2603, 4035, 4801, 0 }; + static ulong[] dim2405Kuo3Init = { 1, 3, 5, 7, 23, 63, 101, 71, 495, 649, 469, 2559, 541, 4499, 20357, 0 }; + static ulong[] dim2406Kuo3Init = { 1, 1, 5, 7, 31, 37, 107, 239, 197, 695, 1403, 2193, 5583, 16019, 11599, 0 }; + static ulong[] dim2407Kuo3Init = { 1, 1, 5, 3, 21, 25, 127, 255, 259, 209, 1491, 349, 737, 9781, 3697, 0 }; + static ulong[] dim2408Kuo3Init = { 1, 1, 5, 9, 3, 47, 43, 123, 315, 983, 349, 2139, 6233, 731, 745, 0 }; + static ulong[] dim2409Kuo3Init = { 1, 1, 1, 1, 25, 63, 95, 101, 483, 439, 1073, 1813, 3809, 11987, 4607, 0 }; + static ulong[] dim2410Kuo3Init = { 1, 1, 3, 5, 23, 11, 11, 101, 9, 599, 931, 39, 6593, 14875, 13557, 0 }; + static ulong[] dim2411Kuo3Init = { 1, 3, 3, 3, 21, 59, 107, 131, 221, 351, 1057, 3689, 7471, 4659, 27303, 0 }; + static ulong[] dim2412Kuo3Init = { 1, 1, 5, 5, 19, 59, 79, 81, 169, 927, 1439, 2305, 2413, 2935, 28571, 0 }; + static ulong[] dim2413Kuo3Init = { 1, 3, 7, 5, 17, 37, 81, 125, 347, 81, 1029, 705, 7321, 4877, 28743, 0 }; + static ulong[] dim2414Kuo3Init = { 1, 3, 5, 5, 21, 27, 113, 161, 177, 49, 1655, 4035, 4987, 5545, 13137, 0 }; + static ulong[] dim2415Kuo3Init = { 1, 1, 5, 13, 5, 19, 117, 13, 379, 449, 765, 1395, 1051, 14783, 22283, 0 }; + static ulong[] dim2416Kuo3Init = { 1, 1, 7, 13, 25, 57, 59, 47, 15, 425, 1359, 1019, 4933, 6289, 2943, 0 }; + static ulong[] dim2417Kuo3Init = { 1, 3, 7, 15, 7, 31, 95, 245, 243, 515, 893, 2451, 83, 6561, 20993, 0 }; + static ulong[] dim2418Kuo3Init = { 1, 3, 1, 13, 7, 45, 39, 227, 245, 793, 1103, 3279, 6967, 14771, 23199, 0 }; + static ulong[] dim2419Kuo3Init = { 1, 3, 5, 9, 21, 5, 103, 27, 509, 187, 1727, 1281, 923, 8305, 29315, 0 }; + static ulong[] dim2420Kuo3Init = { 1, 3, 1, 13, 13, 3, 3, 57, 231, 609, 695, 3461, 6565, 16003, 12719, 0 }; + static ulong[] dim2421Kuo3Init = { 1, 1, 5, 7, 13, 55, 49, 111, 111, 947, 1047, 3745, 8141, 13181, 25703, 0 }; + static ulong[] dim2422Kuo3Init = { 1, 3, 7, 15, 17, 51, 37, 253, 97, 363, 1617, 1201, 3199, 11871, 29389, 0 }; + static ulong[] dim2423Kuo3Init = { 1, 3, 3, 5, 23, 13, 73, 85, 53, 699, 1707, 2137, 4537, 15375, 28251, 0 }; + static ulong[] dim2424Kuo3Init = { 1, 3, 3, 7, 17, 35, 29, 251, 455, 153, 1703, 1535, 4801, 12889, 5959, 0 }; + static ulong[] dim2425Kuo3Init = { 1, 3, 1, 1, 15, 61, 75, 21, 211, 425, 1459, 1347, 7525, 15465, 28191, 0 }; + static ulong[] dim2426Kuo3Init = { 1, 1, 5, 15, 3, 1, 7, 163, 317, 85, 385, 3183, 1901, 6265, 13773, 0 }; + static ulong[] dim2427Kuo3Init = { 1, 1, 5, 1, 31, 43, 63, 15, 157, 711, 617, 2283, 1269, 15661, 28559, 0 }; + static ulong[] dim2428Kuo3Init = { 1, 3, 5, 1, 19, 57, 1, 149, 183, 9, 1587, 2711, 6563, 9291, 287, 0 }; + static ulong[] dim2429Kuo3Init = { 1, 3, 1, 7, 3, 47, 11, 85, 97, 245, 1673, 1147, 2187, 2361, 4417, 0 }; + static ulong[] dim2430Kuo3Init = { 1, 3, 5, 7, 9, 17, 75, 3, 449, 145, 1695, 597, 6931, 2281, 27291, 0 }; + static ulong[] dim2431Kuo3Init = { 1, 1, 1, 7, 7, 51, 53, 53, 463, 669, 677, 3579, 2609, 4147, 27567, 0 }; + static ulong[] dim2432Kuo3Init = { 1, 1, 5, 13, 29, 63, 3, 195, 507, 43, 425, 2121, 8147, 1287, 15137, 0 }; + static ulong[] dim2433Kuo3Init = { 1, 1, 7, 9, 17, 7, 3, 139, 301, 647, 817, 3657, 3217, 4651, 21497, 0 }; + static ulong[] dim2434Kuo3Init = { 1, 1, 3, 13, 11, 43, 87, 139, 441, 13, 1555, 2855, 4891, 3835, 17465, 0 }; + static ulong[] dim2435Kuo3Init = { 1, 3, 1, 3, 15, 47, 29, 99, 481, 377, 455, 929, 1977, 7221, 2517, 0 }; + static ulong[] dim2436Kuo3Init = { 1, 3, 1, 9, 7, 41, 65, 19, 17, 573, 1007, 2097, 4251, 4067, 17217, 0 }; + static ulong[] dim2437Kuo3Init = { 1, 3, 3, 13, 27, 53, 41, 223, 67, 747, 163, 1483, 1827, 11977, 17451, 0 }; + static ulong[] dim2438Kuo3Init = { 1, 3, 5, 13, 17, 51, 109, 11, 105, 481, 239, 787, 5337, 14103, 10499, 0 }; + static ulong[] dim2439Kuo3Init = { 1, 1, 3, 11, 31, 25, 13, 139, 37, 307, 331, 633, 7907, 4705, 26019, 0 }; + static ulong[] dim2440Kuo3Init = { 1, 1, 7, 5, 25, 27, 11, 33, 463, 141, 1409, 2449, 2211, 10729, 28935, 0 }; + static ulong[] dim2441Kuo3Init = { 1, 3, 3, 13, 1, 39, 53, 81, 117, 79, 563, 3735, 253, 10483, 28129, 0 }; + static ulong[] dim2442Kuo3Init = { 1, 1, 3, 3, 7, 7, 103, 233, 341, 765, 11, 3735, 4011, 8075, 10239, 0 }; + static ulong[] dim2443Kuo3Init = { 1, 3, 7, 7, 25, 23, 83, 139, 255, 441, 611, 1583, 733, 673, 21145, 0 }; + static ulong[] dim2444Kuo3Init = { 1, 1, 3, 5, 29, 7, 49, 31, 417, 41, 133, 2119, 3871, 16029, 25649, 0 }; + static ulong[] dim2445Kuo3Init = { 1, 3, 5, 5, 13, 17, 99, 213, 149, 1015, 987, 2497, 7419, 183, 27645, 0 }; + static ulong[] dim2446Kuo3Init = { 1, 3, 3, 1, 25, 13, 107, 211, 113, 909, 1625, 2893, 3957, 10657, 16739, 0 }; + static ulong[] dim2447Kuo3Init = { 1, 1, 5, 11, 5, 3, 97, 61, 189, 779, 1633, 71, 3751, 4589, 30795, 0 }; + static ulong[] dim2448Kuo3Init = { 1, 3, 3, 15, 3, 15, 33, 175, 307, 937, 1713, 833, 2141, 1019, 26093, 0 }; + static ulong[] dim2449Kuo3Init = { 1, 1, 7, 9, 15, 31, 9, 45, 197, 905, 1343, 27, 6835, 4353, 7229, 0 }; + static ulong[] dim2450Kuo3Init = { 1, 1, 7, 15, 23, 15, 73, 217, 283, 853, 987, 389, 3875, 4353, 26667, 0 }; + static ulong[] dim2451Kuo3Init = { 1, 3, 1, 7, 9, 1, 121, 39, 343, 225, 143, 343, 5573, 14997, 15723, 0 }; + static ulong[] dim2452Kuo3Init = { 1, 1, 5, 5, 19, 35, 73, 177, 15, 697, 885, 3917, 6267, 14557, 30395, 0 }; + static ulong[] dim2453Kuo3Init = { 1, 1, 3, 5, 3, 47, 59, 253, 107, 251, 1081, 3115, 1295, 9261, 22389, 0 }; + static ulong[] dim2454Kuo3Init = { 1, 1, 5, 15, 29, 47, 113, 153, 205, 5, 507, 1313, 3329, 3043, 10135, 0 }; + static ulong[] dim2455Kuo3Init = { 1, 1, 1, 3, 29, 39, 15, 147, 439, 975, 415, 3385, 5379, 8957, 3441, 0 }; + static ulong[] dim2456Kuo3Init = { 1, 1, 1, 11, 23, 35, 97, 251, 399, 653, 1327, 3805, 6475, 1729, 29557, 0 }; + static ulong[] dim2457Kuo3Init = { 1, 1, 3, 13, 1, 5, 63, 67, 209, 1005, 383, 2279, 509, 7039, 24973, 0 }; + static ulong[] dim2458Kuo3Init = { 1, 1, 7, 7, 17, 59, 1, 5, 325, 703, 1937, 2699, 163, 10115, 8407, 0 }; + static ulong[] dim2459Kuo3Init = { 1, 3, 1, 3, 25, 27, 73, 183, 41, 373, 909, 3957, 7135, 2401, 24963, 0 }; + static ulong[] dim2460Kuo3Init = { 1, 1, 5, 7, 21, 3, 113, 19, 279, 729, 669, 1403, 881, 3581, 29297, 0 }; + static ulong[] dim2461Kuo3Init = { 1, 3, 3, 1, 29, 9, 39, 97, 133, 369, 515, 1279, 2061, 5785, 29799, 0 }; + static ulong[] dim2462Kuo3Init = { 1, 1, 1, 7, 15, 9, 33, 227, 13, 117, 1903, 2437, 451, 10029, 27469, 0 }; + static ulong[] dim2463Kuo3Init = { 1, 1, 1, 5, 25, 3, 17, 11, 439, 701, 1319, 3357, 5487, 11165, 14077, 0 }; + static ulong[] dim2464Kuo3Init = { 1, 3, 1, 9, 19, 61, 115, 83, 381, 261, 1025, 3215, 6889, 6123, 3761, 0 }; + static ulong[] dim2465Kuo3Init = { 1, 3, 3, 11, 21, 17, 37, 151, 447, 683, 811, 2551, 6735, 16189, 13109, 0 }; + static ulong[] dim2466Kuo3Init = { 1, 1, 1, 5, 5, 61, 11, 223, 221, 755, 65, 913, 6285, 13337, 27473, 0 }; + static ulong[] dim2467Kuo3Init = { 1, 1, 1, 13, 15, 37, 93, 7, 249, 809, 1819, 3297, 4555, 9013, 16243, 0 }; + static ulong[] dim2468Kuo3Init = { 1, 1, 1, 9, 3, 1, 13, 45, 407, 203, 963, 1055, 727, 2269, 18663, 0 }; + static ulong[] dim2469Kuo3Init = { 1, 3, 7, 13, 3, 19, 95, 87, 341, 337, 557, 307, 7827, 15479, 24617, 0 }; + static ulong[] dim2470Kuo3Init = { 1, 1, 1, 3, 31, 3, 125, 163, 439, 971, 815, 1785, 2637, 2973, 15405, 0 }; + static ulong[] dim2471Kuo3Init = { 1, 3, 1, 15, 13, 61, 25, 151, 227, 173, 215, 3151, 4201, 6011, 13655, 0 }; + static ulong[] dim2472Kuo3Init = { 1, 3, 1, 9, 27, 7, 13, 95, 511, 373, 2023, 1019, 3229, 2513, 20929, 0 }; + static ulong[] dim2473Kuo3Init = { 1, 3, 7, 13, 11, 19, 93, 159, 461, 209, 549, 119, 7419, 6969, 29707, 0 }; + static ulong[] dim2474Kuo3Init = { 1, 3, 1, 7, 17, 41, 53, 239, 121, 529, 27, 2129, 4675, 5159, 5767, 0 }; + static ulong[] dim2475Kuo3Init = { 1, 1, 1, 15, 23, 45, 31, 189, 427, 583, 191, 1123, 3183, 5499, 25925, 0 }; + static ulong[] dim2476Kuo3Init = { 1, 3, 7, 1, 3, 17, 39, 15, 257, 567, 459, 3731, 1315, 10975, 23725, 0 }; + static ulong[] dim2477Kuo3Init = { 1, 3, 1, 11, 27, 43, 31, 101, 285, 249, 1467, 3937, 6413, 611, 10287, 0 }; + static ulong[] dim2478Kuo3Init = { 1, 1, 5, 7, 19, 35, 5, 225, 211, 57, 1849, 3915, 5275, 13909, 18885, 0 }; + static ulong[] dim2479Kuo3Init = { 1, 1, 5, 3, 17, 45, 45, 197, 311, 777, 2013, 927, 6209, 15495, 30027, 0 }; + static ulong[] dim2480Kuo3Init = { 1, 1, 7, 11, 9, 13, 37, 81, 389, 459, 671, 2567, 7357, 5339, 13729, 0 }; + static ulong[] dim2481Kuo3Init = { 1, 3, 1, 3, 29, 31, 63, 189, 271, 543, 229, 1385, 2031, 8993, 5665, 0 }; + static ulong[] dim2482Kuo3Init = { 1, 3, 5, 11, 5, 25, 39, 225, 121, 207, 1161, 1739, 6627, 11129, 475, 0 }; + static ulong[] dim2483Kuo3Init = { 1, 1, 7, 7, 19, 7, 29, 83, 25, 707, 197, 335, 2613, 10035, 20157, 0 }; + static ulong[] dim2484Kuo3Init = { 1, 3, 3, 7, 7, 63, 99, 169, 221, 125, 563, 1351, 3867, 14903, 27469, 0 }; + static ulong[] dim2485Kuo3Init = { 1, 3, 3, 7, 25, 5, 31, 151, 213, 555, 481, 3955, 4347, 8811, 30687, 0 }; + static ulong[] dim2486Kuo3Init = { 1, 1, 5, 13, 23, 9, 59, 149, 351, 819, 311, 233, 4409, 3539, 6509, 0 }; + static ulong[] dim2487Kuo3Init = { 1, 3, 3, 7, 1, 11, 3, 161, 473, 65, 1793, 367, 5115, 15743, 27175, 0 }; + static ulong[] dim2488Kuo3Init = { 1, 3, 3, 9, 15, 61, 5, 125, 53, 523, 1365, 1909, 7689, 10799, 29199, 0 }; + static ulong[] dim2489Kuo3Init = { 1, 1, 3, 7, 13, 43, 31, 179, 73, 611, 293, 2349, 4873, 11271, 29827, 0 }; + static ulong[] dim2490Kuo3Init = { 1, 1, 5, 5, 27, 31, 107, 197, 409, 405, 789, 1529, 7793, 5679, 25127, 0 }; + static ulong[] dim2491Kuo3Init = { 1, 3, 5, 1, 23, 35, 37, 119, 99, 891, 877, 1799, 5647, 13983, 22321, 0 }; + static ulong[] dim2492Kuo3Init = { 1, 3, 3, 13, 9, 49, 29, 245, 447, 963, 211, 3233, 2883, 5467, 24057, 0 }; + static ulong[] dim2493Kuo3Init = { 1, 1, 3, 5, 7, 29, 77, 7, 47, 141, 799, 2009, 7731, 4371, 24529, 0 }; + static ulong[] dim2494Kuo3Init = { 1, 1, 7, 7, 19, 31, 65, 21, 417, 395, 653, 1751, 2989, 6721, 28155, 0 }; + static ulong[] dim2495Kuo3Init = { 1, 1, 3, 9, 1, 5, 117, 119, 39, 949, 1081, 1919, 5689, 8367, 19043, 0 }; + static ulong[] dim2496Kuo3Init = { 1, 3, 3, 13, 29, 45, 73, 49, 393, 545, 581, 689, 2597, 5757, 26953, 0 }; + static ulong[] dim2497Kuo3Init = { 1, 1, 7, 13, 3, 13, 1, 97, 73, 517, 795, 2755, 5109, 15771, 19297, 0 }; + static ulong[] dim2498Kuo3Init = { 1, 3, 1, 7, 11, 5, 117, 179, 507, 483, 143, 1441, 3247, 7557, 10939, 0 }; + static ulong[] dim2499Kuo3Init = { 1, 1, 7, 1, 7, 9, 1, 1, 465, 1019, 37, 2011, 4065, 725, 10133, 0 }; + static ulong[] dim2500Kuo3Init = { 1, 1, 7, 13, 15, 39, 69, 167, 399, 571, 1089, 1787, 8097, 3209, 25689, 0 }; + static ulong[] dim2501Kuo3Init = { 1, 1, 7, 3, 7, 23, 17, 197, 43, 727, 543, 1307, 2701, 4121, 29165, 0 }; + static ulong[] dim2502Kuo3Init = { 1, 1, 7, 3, 3, 29, 57, 89, 269, 667, 705, 2427, 47, 5535, 21861, 0 }; + static ulong[] dim2503Kuo3Init = { 1, 1, 1, 13, 3, 43, 55, 55, 337, 567, 63, 3061, 5191, 16365, 24415, 0 }; + static ulong[] dim2504Kuo3Init = { 1, 1, 5, 9, 3, 31, 123, 101, 149, 131, 1037, 3925, 861, 12811, 23787, 0 }; + static ulong[] dim2505Kuo3Init = { 1, 3, 1, 5, 1, 5, 71, 7, 113, 797, 863, 1199, 1911, 2551, 12423, 0 }; + static ulong[] dim2506Kuo3Init = { 1, 3, 1, 11, 19, 17, 25, 231, 7, 137, 127, 2297, 3345, 729, 909, 0 }; + static ulong[] dim2507Kuo3Init = { 1, 1, 5, 9, 17, 13, 5, 227, 327, 335, 1463, 2685, 6301, 15547, 13151, 0 }; + static ulong[] dim2508Kuo3Init = { 1, 3, 5, 9, 9, 25, 87, 53, 107, 219, 861, 1615, 371, 4983, 6445, 0 }; + static ulong[] dim2509Kuo3Init = { 1, 3, 3, 13, 21, 59, 109, 53, 365, 293, 1373, 147, 4215, 1007, 20401, 0 }; + static ulong[] dim2510Kuo3Init = { 1, 3, 3, 5, 5, 25, 113, 233, 317, 121, 427, 3561, 701, 10169, 23449, 0 }; + static ulong[] dim2511Kuo3Init = { 1, 3, 5, 9, 9, 41, 123, 199, 305, 639, 1131, 3635, 8125, 4007, 6883, 0 }; + static ulong[] dim2512Kuo3Init = { 1, 3, 1, 13, 23, 5, 105, 25, 281, 301, 1011, 3647, 263, 3389, 5527, 0 }; + static ulong[] dim2513Kuo3Init = { 1, 1, 5, 15, 17, 59, 33, 175, 115, 625, 975, 3189, 6973, 8291, 14201, 0 }; + static ulong[] dim2514Kuo3Init = { 1, 3, 3, 5, 1, 41, 39, 231, 57, 95, 623, 2199, 3821, 1627, 4035, 0 }; + static ulong[] dim2515Kuo3Init = { 1, 3, 5, 11, 25, 5, 1, 21, 457, 875, 355, 389, 1623, 9575, 1283, 0 }; + static ulong[] dim2516Kuo3Init = { 1, 3, 1, 1, 21, 29, 83, 45, 315, 735, 1253, 3743, 7163, 5163, 10833, 0 }; + static ulong[] dim2517Kuo3Init = { 1, 3, 5, 13, 1, 5, 47, 21, 231, 1019, 1851, 21, 1699, 851, 11857, 0 }; + static ulong[] dim2518Kuo3Init = { 1, 3, 5, 7, 19, 9, 61, 241, 175, 191, 415, 1197, 5643, 9765, 17375, 0 }; + static ulong[] dim2519Kuo3Init = { 1, 3, 5, 1, 3, 5, 35, 231, 471, 175, 1715, 487, 2299, 12355, 5113, 0 }; + static ulong[] dim2520Kuo3Init = { 1, 1, 3, 9, 15, 45, 33, 93, 289, 371, 275, 1703, 6925, 5511, 3203, 0 }; + static ulong[] dim2521Kuo3Init = { 1, 3, 5, 7, 21, 55, 105, 199, 435, 955, 731, 719, 1571, 7341, 5255, 0 }; + static ulong[] dim2522Kuo3Init = { 1, 3, 7, 7, 1, 3, 127, 85, 11, 165, 1423, 3889, 7509, 14687, 23383, 0 }; + static ulong[] dim2523Kuo3Init = { 1, 1, 7, 11, 31, 61, 9, 141, 357, 801, 1785, 3813, 3437, 10853, 17191, 0 }; + static ulong[] dim2524Kuo3Init = { 1, 1, 7, 5, 23, 59, 17, 205, 449, 107, 1123, 1089, 5499, 12251, 653, 0 }; + static ulong[] dim2525Kuo3Init = { 1, 3, 1, 5, 3, 25, 71, 229, 263, 423, 1357, 3709, 1719, 2799, 10943, 0 }; + static ulong[] dim2526Kuo3Init = { 1, 1, 5, 13, 1, 23, 97, 209, 401, 809, 783, 2455, 1137, 13941, 12751, 0 }; + static ulong[] dim2527Kuo3Init = { 1, 3, 3, 11, 21, 47, 25, 29, 471, 677, 1129, 2689, 929, 5635, 26509, 0 }; + static ulong[] dim2528Kuo3Init = { 1, 3, 1, 5, 7, 27, 5, 195, 435, 255, 395, 2775, 297, 6909, 2289, 0 }; + static ulong[] dim2529Kuo3Init = { 1, 1, 1, 9, 7, 53, 109, 85, 141, 243, 1433, 1531, 5461, 1111, 7889, 0 }; + static ulong[] dim2530Kuo3Init = { 1, 3, 7, 11, 13, 47, 91, 51, 489, 433, 1667, 2955, 5135, 11949, 14123, 0 }; + static ulong[] dim2531Kuo3Init = { 1, 1, 7, 15, 5, 57, 57, 147, 97, 709, 1757, 1493, 2715, 12583, 18991, 0 }; + static ulong[] dim2532Kuo3Init = { 1, 3, 1, 15, 7, 17, 79, 75, 397, 555, 787, 1405, 4749, 6723, 3749, 0 }; + static ulong[] dim2533Kuo3Init = { 1, 1, 3, 11, 21, 59, 5, 211, 215, 393, 1445, 4057, 5115, 821, 7783, 0 }; + static ulong[] dim2534Kuo3Init = { 1, 1, 3, 5, 29, 1, 97, 201, 21, 287, 1735, 2397, 3401, 2017, 32229, 0 }; + static ulong[] dim2535Kuo3Init = { 1, 1, 3, 13, 17, 43, 71, 25, 243, 423, 733, 1917, 1235, 3527, 22695, 0 }; + static ulong[] dim2536Kuo3Init = { 1, 1, 3, 15, 27, 7, 25, 239, 493, 945, 397, 3837, 5465, 12273, 26025, 0 }; + static ulong[] dim2537Kuo3Init = { 1, 3, 1, 7, 17, 17, 61, 7, 487, 439, 1433, 1761, 6507, 487, 32633, 0 }; + static ulong[] dim2538Kuo3Init = { 1, 3, 3, 9, 21, 29, 83, 27, 321, 73, 1247, 2593, 6935, 7009, 31617, 0 }; + static ulong[] dim2539Kuo3Init = { 1, 3, 3, 1, 25, 37, 99, 177, 357, 527, 1259, 3625, 4277, 15243, 28615, 0 }; + static ulong[] dim2540Kuo3Init = { 1, 1, 3, 13, 29, 31, 59, 177, 73, 1007, 1809, 2143, 7375, 4321, 3771, 0 }; + static ulong[] dim2541Kuo3Init = { 1, 3, 3, 3, 21, 7, 123, 253, 87, 995, 103, 561, 7639, 10087, 4149, 0 }; + static ulong[] dim2542Kuo3Init = { 1, 1, 5, 13, 11, 31, 53, 249, 435, 361, 367, 783, 7525, 5361, 21535, 0 }; + static ulong[] dim2543Kuo3Init = { 1, 3, 7, 5, 15, 25, 31, 9, 29, 907, 77, 2585, 2929, 12153, 19401, 0 }; + static ulong[] dim2544Kuo3Init = { 1, 3, 5, 5, 15, 1, 101, 99, 209, 583, 679, 1005, 2271, 269, 29527, 0 }; + static ulong[] dim2545Kuo3Init = { 1, 1, 3, 1, 13, 35, 85, 83, 77, 999, 1485, 2817, 7001, 13659, 25061, 0 }; + static ulong[] dim2546Kuo3Init = { 1, 3, 7, 13, 19, 15, 19, 65, 195, 693, 1399, 2875, 255, 6617, 7907, 0 }; + static ulong[] dim2547Kuo3Init = { 1, 1, 5, 5, 13, 25, 67, 195, 131, 481, 1831, 873, 6281, 4935, 2311, 0 }; + static ulong[] dim2548Kuo3Init = { 1, 1, 1, 15, 27, 47, 85, 209, 323, 809, 605, 2087, 1917, 8061, 13659, 0 }; + static ulong[] dim2549Kuo3Init = { 1, 3, 1, 13, 5, 63, 69, 197, 241, 349, 813, 3943, 6267, 16197, 1417, 0 }; + static ulong[] dim2550Kuo3Init = { 1, 1, 1, 5, 13, 21, 85, 55, 21, 791, 795, 4087, 2697, 6545, 30253, 0 }; + static ulong[] dim2551Kuo3Init = { 1, 3, 5, 15, 31, 13, 117, 237, 99, 803, 1367, 251, 5143, 12153, 27565, 0 }; + static ulong[] dim2552Kuo3Init = { 1, 1, 7, 7, 11, 7, 17, 47, 305, 9, 941, 3529, 6131, 11027, 20319, 0 }; + static ulong[] dim2553Kuo3Init = { 1, 3, 1, 5, 19, 51, 1, 113, 277, 573, 1717, 1757, 4541, 943, 349, 0 }; + static ulong[] dim2554Kuo3Init = { 1, 3, 1, 1, 21, 23, 11, 143, 413, 171, 355, 2801, 2431, 11597, 16833, 0 }; + static ulong[] dim2555Kuo3Init = { 1, 3, 1, 1, 13, 31, 111, 109, 73, 125, 1011, 2249, 4039, 8757, 2765, 0 }; + static ulong[] dim2556Kuo3Init = { 1, 1, 1, 7, 15, 53, 33, 133, 511, 595, 139, 815, 6093, 10215, 9507, 0 }; + static ulong[] dim2557Kuo3Init = { 1, 3, 7, 7, 29, 1, 93, 13, 169, 435, 527, 3861, 3867, 9337, 26855, 0 }; + static ulong[] dim2558Kuo3Init = { 1, 1, 5, 3, 13, 29, 91, 73, 257, 645, 679, 3245, 6467, 5917, 17891, 0 }; + static ulong[] dim2559Kuo3Init = { 1, 1, 7, 15, 27, 1, 45, 17, 429, 571, 1127, 3843, 3801, 4773, 16577, 0 }; + static ulong[] dim2560Kuo3Init = { 1, 1, 7, 11, 29, 29, 65, 111, 415, 941, 1411, 3003, 3945, 15281, 16851, 0 }; + static ulong[] dim2561Kuo3Init = { 1, 3, 1, 3, 3, 29, 39, 121, 165, 285, 1895, 283, 4393, 13281, 3349, 0 }; + static ulong[] dim2562Kuo3Init = { 1, 3, 1, 9, 27, 1, 35, 119, 91, 445, 1045, 1427, 6271, 955, 509, 0 }; + static ulong[] dim2563Kuo3Init = { 1, 1, 7, 1, 11, 15, 3, 181, 17, 3, 1865, 2465, 357, 12149, 7359, 0 }; + static ulong[] dim2564Kuo3Init = { 1, 3, 5, 5, 11, 47, 5, 65, 105, 53, 1341, 3729, 4883, 5179, 29353, 0 }; + static ulong[] dim2565Kuo3Init = { 1, 1, 7, 5, 15, 53, 23, 181, 125, 441, 511, 3933, 2327, 1305, 14629, 0 }; + static ulong[] dim2566Kuo3Init = { 1, 1, 3, 5, 3, 11, 91, 187, 177, 649, 1849, 2545, 3349, 6563, 8139, 0 }; + static ulong[] dim2567Kuo3Init = { 1, 3, 1, 11, 31, 35, 71, 51, 235, 295, 521, 3869, 3083, 1327, 3277, 0 }; + static ulong[] dim2568Kuo3Init = { 1, 1, 3, 15, 11, 11, 125, 163, 71, 721, 449, 3443, 1347, 6221, 19489, 0 }; + static ulong[] dim2569Kuo3Init = { 1, 1, 7, 3, 25, 13, 13, 149, 115, 563, 311, 1823, 2687, 5997, 23063, 0 }; + static ulong[] dim2570Kuo3Init = { 1, 1, 1, 13, 7, 47, 115, 19, 419, 395, 591, 2413, 7143, 11235, 25795, 0 }; + static ulong[] dim2571Kuo3Init = { 1, 1, 1, 7, 17, 37, 63, 57, 175, 301, 493, 1849, 1903, 13149, 21429, 0 }; + static ulong[] dim2572Kuo3Init = { 1, 1, 3, 3, 1, 53, 15, 91, 315, 687, 473, 1639, 7769, 11621, 24245, 0 }; + static ulong[] dim2573Kuo3Init = { 1, 1, 5, 11, 13, 35, 13, 235, 365, 677, 611, 3175, 6349, 445, 13739, 0 }; + static ulong[] dim2574Kuo3Init = { 1, 1, 1, 15, 17, 49, 49, 15, 205, 755, 665, 3865, 6499, 6521, 31925, 0 }; + static ulong[] dim2575Kuo3Init = { 1, 1, 3, 5, 9, 49, 57, 119, 489, 633, 1407, 957, 4005, 14503, 2783, 0 }; + static ulong[] dim2576Kuo3Init = { 1, 1, 3, 13, 17, 41, 73, 137, 195, 457, 1361, 3209, 3701, 9675, 26499, 0 }; + static ulong[] dim2577Kuo3Init = { 1, 3, 7, 3, 31, 49, 71, 83, 141, 1009, 1503, 3393, 4653, 8051, 25861, 0 }; + static ulong[] dim2578Kuo3Init = { 1, 3, 7, 9, 31, 17, 83, 211, 3, 81, 1579, 387, 4471, 5407, 28849, 0 }; + static ulong[] dim2579Kuo3Init = { 1, 1, 5, 9, 3, 51, 45, 157, 197, 195, 1121, 2451, 3885, 9317, 29157, 0 }; + static ulong[] dim2580Kuo3Init = { 1, 3, 7, 5, 23, 19, 49, 89, 107, 369, 129, 2381, 383, 8279, 29277, 0 }; + static ulong[] dim2581Kuo3Init = { 1, 3, 3, 13, 21, 7, 123, 221, 85, 819, 1857, 1211, 7495, 2921, 9529, 0 }; + static ulong[] dim2582Kuo3Init = { 1, 3, 3, 13, 19, 13, 63, 47, 465, 739, 1961, 2779, 7989, 8419, 19249, 0 }; + static ulong[] dim2583Kuo3Init = { 1, 3, 5, 15, 25, 49, 65, 39, 333, 193, 443, 1221, 245, 523, 31885, 0 }; + static ulong[] dim2584Kuo3Init = { 1, 3, 5, 7, 31, 3, 69, 173, 19, 593, 61, 1545, 415, 14489, 9723, 0 }; + static ulong[] dim2585Kuo3Init = { 1, 3, 3, 1, 5, 9, 121, 87, 431, 893, 1031, 3589, 4263, 11355, 22725, 0 }; + static ulong[] dim2586Kuo3Init = { 1, 1, 5, 3, 21, 9, 47, 151, 165, 941, 1369, 3991, 989, 1515, 12725, 0 }; + static ulong[] dim2587Kuo3Init = { 1, 3, 7, 1, 7, 47, 57, 153, 239, 397, 1723, 1681, 521, 8173, 14567, 0 }; + static ulong[] dim2588Kuo3Init = { 1, 3, 3, 5, 23, 9, 77, 201, 61, 969, 345, 2817, 4391, 2193, 18739, 0 }; + static ulong[] dim2589Kuo3Init = { 1, 1, 5, 13, 15, 45, 83, 165, 421, 967, 449, 3419, 2475, 7283, 18199, 0 }; + static ulong[] dim2590Kuo3Init = { 1, 3, 7, 11, 25, 37, 3, 175, 327, 35, 1179, 927, 5263, 1723, 32015, 0 }; + static ulong[] dim2591Kuo3Init = { 1, 1, 5, 15, 29, 17, 63, 45, 495, 107, 459, 2223, 989, 11823, 6547, 0 }; + static ulong[] dim2592Kuo3Init = { 1, 3, 1, 13, 17, 15, 127, 223, 369, 409, 303, 2229, 7349, 10165, 28327, 0 }; + static ulong[] dim2593Kuo3Init = { 1, 3, 5, 15, 15, 17, 119, 185, 55, 299, 113, 3585, 2289, 7793, 26217, 0 }; + static ulong[] dim2594Kuo3Init = { 1, 3, 7, 13, 21, 33, 3, 5, 169, 615, 1607, 1069, 1827, 6165, 16245, 0 }; + static ulong[] dim2595Kuo3Init = { 1, 1, 5, 13, 21, 59, 119, 253, 181, 1001, 2001, 887, 4129, 3953, 29979, 0 }; + static ulong[] dim2596Kuo3Init = { 1, 3, 3, 9, 29, 17, 33, 3, 375, 973, 989, 1725, 731, 12845, 21133, 0 }; + static ulong[] dim2597Kuo3Init = { 1, 1, 3, 13, 21, 25, 65, 41, 379, 693, 1507, 1601, 2087, 8181, 12723, 0 }; + static ulong[] dim2598Kuo3Init = { 1, 1, 7, 1, 21, 37, 117, 187, 483, 779, 1279, 685, 5479, 12039, 12559, 0 }; + static ulong[] dim2599Kuo3Init = { 1, 1, 3, 5, 7, 39, 49, 79, 361, 191, 1749, 507, 19, 10671, 4745, 0 }; + static ulong[] dim2600Kuo3Init = { 1, 1, 1, 15, 15, 45, 37, 49, 85, 311, 577, 2417, 4061, 1409, 19187, 0 }; + static ulong[] dim2601Kuo3Init = { 1, 3, 5, 11, 5, 1, 41, 73, 313, 741, 1081, 3325, 977, 1693, 15249, 0 }; + static ulong[] dim2602Kuo3Init = { 1, 1, 1, 9, 19, 49, 29, 169, 153, 665, 413, 907, 6129, 4961, 21295, 0 }; + static ulong[] dim2603Kuo3Init = { 1, 3, 3, 3, 23, 17, 91, 27, 375, 231, 513, 1459, 7245, 8117, 19583, 0 }; + static ulong[] dim2604Kuo3Init = { 1, 1, 7, 13, 19, 57, 111, 195, 491, 771, 1841, 1339, 5045, 12901, 17307, 0 }; + static ulong[] dim2605Kuo3Init = { 1, 1, 1, 7, 1, 61, 61, 11, 151, 403, 173, 3629, 2157, 6125, 29233, 0 }; + static ulong[] dim2606Kuo3Init = { 1, 3, 1, 13, 29, 63, 55, 9, 465, 439, 9, 1527, 4635, 4533, 13633, 0 }; + static ulong[] dim2607Kuo3Init = { 1, 3, 5, 1, 15, 57, 113, 137, 483, 753, 1971, 1141, 2765, 7865, 32733, 0 }; + static ulong[] dim2608Kuo3Init = { 1, 3, 5, 15, 9, 23, 125, 81, 471, 457, 1475, 3419, 6089, 4899, 19805, 0 }; + static ulong[] dim2609Kuo3Init = { 1, 1, 5, 3, 25, 29, 1, 115, 273, 281, 899, 3129, 4877, 15459, 24615, 0 }; + static ulong[] dim2610Kuo3Init = { 1, 1, 7, 11, 19, 41, 59, 165, 115, 369, 1173, 2545, 4285, 10899, 3823, 0 }; + static ulong[] dim2611Kuo3Init = { 1, 3, 5, 13, 17, 47, 107, 191, 53, 1003, 747, 583, 6457, 12141, 2541, 0 }; + static ulong[] dim2612Kuo3Init = { 1, 3, 7, 1, 9, 51, 33, 201, 399, 209, 271, 679, 2401, 10521, 9949, 0 }; + static ulong[] dim2613Kuo3Init = { 1, 1, 5, 9, 5, 53, 117, 157, 137, 757, 257, 1407, 4831, 11205, 25075, 0 }; + static ulong[] dim2614Kuo3Init = { 1, 1, 7, 13, 29, 63, 25, 11, 255, 251, 1393, 2089, 1701, 11773, 24011, 0 }; + static ulong[] dim2615Kuo3Init = { 1, 3, 3, 11, 17, 5, 69, 119, 287, 607, 779, 2369, 55, 12381, 26051, 0 }; + static ulong[] dim2616Kuo3Init = { 1, 3, 3, 13, 25, 1, 97, 109, 79, 453, 795, 2821, 4113, 3085, 30667, 0 }; + static ulong[] dim2617Kuo3Init = { 1, 1, 1, 9, 25, 17, 87, 163, 483, 803, 315, 2755, 7147, 12537, 7707, 0 }; + static ulong[] dim2618Kuo3Init = { 1, 3, 1, 5, 23, 29, 93, 129, 47, 181, 1577, 2645, 4103, 10753, 27119, 0 }; + static ulong[] dim2619Kuo3Init = { 1, 1, 1, 1, 17, 61, 37, 175, 451, 5, 879, 1625, 7981, 11249, 12573, 0 }; + static ulong[] dim2620Kuo3Init = { 1, 1, 3, 5, 9, 17, 85, 131, 111, 621, 903, 3143, 5951, 6567, 32227, 0 }; + static ulong[] dim2621Kuo3Init = { 1, 3, 5, 3, 1, 49, 53, 255, 435, 845, 225, 2535, 7925, 8043, 17519, 0 }; + static ulong[] dim2622Kuo3Init = { 1, 3, 3, 5, 23, 7, 63, 117, 79, 637, 1265, 2747, 6531, 7327, 17329, 0 }; + static ulong[] dim2623Kuo3Init = { 1, 3, 7, 3, 27, 35, 69, 253, 489, 495, 561, 3615, 917, 6595, 10673, 0 }; + static ulong[] dim2624Kuo3Init = { 1, 1, 1, 5, 25, 7, 99, 99, 499, 251, 1651, 3603, 689, 5837, 347, 0 }; + static ulong[] dim2625Kuo3Init = { 1, 1, 3, 5, 1, 27, 55, 91, 137, 291, 517, 2149, 1097, 2187, 16191, 0 }; + static ulong[] dim2626Kuo3Init = { 1, 1, 1, 11, 29, 3, 103, 81, 335, 85, 549, 1667, 5319, 5929, 15885, 0 }; + static ulong[] dim2627Kuo3Init = { 1, 1, 3, 9, 7, 41, 103, 141, 103, 655, 179, 1513, 7105, 1919, 2245, 0 }; + static ulong[] dim2628Kuo3Init = { 1, 3, 5, 11, 11, 13, 127, 65, 493, 233, 859, 3179, 5449, 13255, 14495, 0 }; + static ulong[] dim2629Kuo3Init = { 1, 3, 1, 5, 27, 49, 119, 29, 55, 717, 1293, 1193, 7883, 4475, 13745, 0 }; + static ulong[] dim2630Kuo3Init = { 1, 3, 7, 3, 21, 9, 1, 43, 425, 385, 447, 3135, 7671, 12317, 5649, 0 }; + static ulong[] dim2631Kuo3Init = { 1, 1, 7, 5, 21, 51, 103, 199, 119, 875, 1457, 461, 6521, 7849, 7725, 0 }; + static ulong[] dim2632Kuo3Init = { 1, 1, 1, 15, 9, 25, 89, 125, 395, 269, 1533, 1545, 2613, 11175, 17167, 0 }; + static ulong[] dim2633Kuo3Init = { 1, 3, 5, 9, 17, 41, 113, 37, 253, 407, 795, 2117, 3041, 9269, 30097, 0 }; + static ulong[] dim2634Kuo3Init = { 1, 1, 3, 11, 31, 13, 23, 29, 385, 603, 1721, 3817, 3453, 2021, 8829, 0 }; + static ulong[] dim2635Kuo3Init = { 1, 1, 7, 9, 21, 3, 107, 121, 267, 385, 261, 3967, 5607, 13991, 8639, 0 }; + static ulong[] dim2636Kuo3Init = { 1, 3, 5, 15, 17, 19, 99, 195, 415, 19, 865, 4049, 3819, 7581, 10779, 0 }; + static ulong[] dim2637Kuo3Init = { 1, 1, 5, 15, 25, 29, 125, 105, 337, 153, 2023, 1475, 2741, 7779, 16929, 0 }; + static ulong[] dim2638Kuo3Init = { 1, 3, 3, 5, 11, 1, 111, 157, 441, 751, 865, 3499, 6425, 9567, 6659, 0 }; + static ulong[] dim2639Kuo3Init = { 1, 1, 5, 3, 23, 41, 57, 91, 413, 81, 1977, 2227, 2289, 1291, 19339, 0 }; + static ulong[] dim2640Kuo3Init = { 1, 1, 3, 15, 15, 49, 47, 115, 153, 593, 1243, 2029, 1177, 8121, 14893, 0 }; + static ulong[] dim2641Kuo3Init = { 1, 1, 5, 15, 29, 11, 55, 23, 173, 145, 143, 2275, 4537, 13221, 32575, 0 }; + static ulong[] dim2642Kuo3Init = { 1, 1, 1, 9, 29, 53, 103, 37, 327, 543, 1327, 899, 6343, 6707, 1247, 0 }; + static ulong[] dim2643Kuo3Init = { 1, 3, 1, 13, 21, 49, 113, 205, 349, 451, 1277, 989, 3387, 9275, 6629, 0 }; + static ulong[] dim2644Kuo3Init = { 1, 3, 5, 5, 31, 59, 79, 65, 285, 841, 287, 1453, 1507, 14813, 14705, 0 }; + static ulong[] dim2645Kuo3Init = { 1, 1, 3, 5, 9, 11, 79, 109, 313, 339, 1939, 2399, 5127, 8747, 11989, 0 }; + static ulong[] dim2646Kuo3Init = { 1, 3, 3, 9, 9, 27, 83, 135, 249, 101, 1181, 451, 6063, 609, 15371, 0 }; + static ulong[] dim2647Kuo3Init = { 1, 1, 5, 5, 15, 61, 77, 221, 19, 643, 1535, 1223, 7165, 10969, 10367, 0 }; + static ulong[] dim2648Kuo3Init = { 1, 1, 7, 13, 5, 9, 61, 95, 493, 709, 71, 1571, 6805, 9687, 12217, 0 }; + static ulong[] dim2649Kuo3Init = { 1, 3, 5, 7, 17, 55, 57, 179, 217, 699, 943, 127, 1603, 6851, 8579, 0 }; + static ulong[] dim2650Kuo3Init = { 1, 3, 1, 11, 25, 51, 127, 13, 429, 15, 949, 2337, 5743, 14255, 15137, 0 }; + static ulong[] dim2651Kuo3Init = { 1, 3, 7, 15, 5, 39, 39, 105, 119, 355, 1655, 3819, 1313, 5173, 7791, 0 }; + static ulong[] dim2652Kuo3Init = { 1, 3, 7, 5, 3, 47, 93, 85, 19, 399, 303, 1333, 5435, 9425, 6503, 0 }; + static ulong[] dim2653Kuo3Init = { 1, 3, 1, 7, 21, 33, 71, 253, 489, 149, 227, 797, 955, 6839, 23037, 0 }; + static ulong[] dim2654Kuo3Init = { 1, 1, 7, 1, 27, 59, 15, 47, 249, 557, 1477, 1837, 4409, 14723, 14933, 0 }; + static ulong[] dim2655Kuo3Init = { 1, 3, 5, 13, 1, 47, 11, 205, 131, 17, 373, 2039, 1873, 3041, 22869, 0 }; + static ulong[] dim2656Kuo3Init = { 1, 1, 3, 1, 11, 27, 99, 135, 195, 419, 561, 1027, 1849, 13533, 7701, 0 }; + static ulong[] dim2657Kuo3Init = { 1, 1, 7, 15, 27, 23, 77, 111, 157, 417, 591, 3435, 5999, 9481, 17073, 0 }; + static ulong[] dim2658Kuo3Init = { 1, 3, 5, 3, 9, 61, 57, 43, 85, 585, 1861, 703, 2337, 8565, 16233, 0 }; + static ulong[] dim2659Kuo3Init = { 1, 1, 3, 11, 7, 17, 41, 213, 145, 325, 1847, 3205, 3515, 1117, 285, 0 }; + static ulong[] dim2660Kuo3Init = { 1, 3, 5, 11, 7, 35, 95, 127, 57, 123, 759, 129, 4335, 15183, 2107, 0 }; + static ulong[] dim2661Kuo3Init = { 1, 3, 7, 7, 13, 1, 87, 193, 63, 201, 741, 2087, 1625, 1677, 31603, 0 }; + static ulong[] dim2662Kuo3Init = { 1, 1, 7, 11, 13, 53, 127, 235, 489, 173, 1551, 1897, 5877, 15559, 24445, 0 }; + static ulong[] dim2663Kuo3Init = { 1, 1, 7, 7, 9, 53, 59, 247, 83, 521, 2029, 3677, 2083, 11635, 30517, 0 }; + static ulong[] dim2664Kuo3Init = { 1, 1, 1, 5, 9, 19, 71, 99, 213, 663, 947, 1929, 5275, 9715, 10033, 0 }; + static ulong[] dim2665Kuo3Init = { 1, 1, 5, 11, 25, 31, 33, 239, 137, 445, 1227, 1051, 7405, 7983, 10079, 0 }; + static ulong[] dim2666Kuo3Init = { 1, 3, 3, 15, 27, 35, 51, 207, 167, 519, 303, 3399, 4393, 1623, 21225, 0 }; + static ulong[] dim2667Kuo3Init = { 1, 3, 1, 11, 17, 13, 41, 229, 441, 879, 1695, 1351, 5745, 1907, 15517, 0 }; + static ulong[] dim2668Kuo3Init = { 1, 3, 7, 1, 3, 1, 95, 105, 333, 11, 1709, 2783, 3011, 5579, 14939, 0 }; + static ulong[] dim2669Kuo3Init = { 1, 3, 1, 1, 5, 33, 67, 103, 71, 707, 325, 315, 567, 11969, 23071, 0 }; + static ulong[] dim2670Kuo3Init = { 1, 1, 7, 11, 5, 61, 47, 131, 413, 507, 991, 27, 3873, 13151, 4115, 0 }; + static ulong[] dim2671Kuo3Init = { 1, 1, 5, 11, 9, 31, 103, 91, 297, 419, 1251, 1155, 5539, 10347, 26811, 0 }; + static ulong[] dim2672Kuo3Init = { 1, 3, 3, 3, 15, 37, 37, 167, 307, 397, 561, 2431, 6219, 3401, 23551, 0 }; + static ulong[] dim2673Kuo3Init = { 1, 3, 7, 7, 29, 11, 33, 7, 177, 625, 853, 2317, 7371, 7435, 18135, 0 }; + static ulong[] dim2674Kuo3Init = { 1, 1, 5, 1, 29, 7, 107, 97, 3, 97, 901, 717, 1911, 3877, 29583, 0 }; + static ulong[] dim2675Kuo3Init = { 1, 1, 7, 3, 27, 33, 33, 105, 285, 3, 1427, 13, 3941, 299, 12025, 0 }; + static ulong[] dim2676Kuo3Init = { 1, 1, 3, 7, 13, 57, 81, 131, 327, 587, 445, 1313, 4797, 8587, 5915, 0 }; + static ulong[] dim2677Kuo3Init = { 1, 1, 3, 13, 21, 29, 43, 89, 499, 893, 501, 2409, 3145, 9435, 10831, 0 }; + static ulong[] dim2678Kuo3Init = { 1, 1, 7, 11, 25, 21, 23, 211, 37, 993, 199, 3791, 291, 465, 32513, 0 }; + static ulong[] dim2679Kuo3Init = { 1, 1, 5, 11, 15, 53, 123, 91, 407, 925, 1125, 927, 6793, 1905, 27477, 0 }; + static ulong[] dim2680Kuo3Init = { 1, 1, 1, 11, 27, 51, 1, 77, 5, 273, 1363, 3835, 1627, 14925, 9431, 0 }; + static ulong[] dim2681Kuo3Init = { 1, 1, 7, 3, 29, 47, 47, 79, 305, 655, 1171, 899, 95, 9413, 14371, 0 }; + static ulong[] dim2682Kuo3Init = { 1, 1, 7, 13, 31, 45, 5, 211, 331, 677, 1045, 929, 975, 2377, 15407, 0 }; + static ulong[] dim2683Kuo3Init = { 1, 3, 5, 13, 21, 59, 61, 111, 449, 641, 597, 4023, 6333, 4439, 605, 0 }; + static ulong[] dim2684Kuo3Init = { 1, 1, 3, 5, 29, 7, 89, 21, 373, 311, 433, 1091, 4871, 8951, 22591, 0 }; + static ulong[] dim2685Kuo3Init = { 1, 1, 1, 7, 27, 17, 81, 77, 119, 1005, 873, 2299, 6919, 657, 12479, 0 }; + static ulong[] dim2686Kuo3Init = { 1, 3, 3, 5, 29, 41, 31, 133, 411, 655, 1753, 1365, 1807, 15975, 23783, 0 }; + static ulong[] dim2687Kuo3Init = { 1, 1, 3, 9, 21, 11, 79, 65, 149, 121, 1393, 983, 885, 6991, 14943, 0 }; + static ulong[] dim2688Kuo3Init = { 1, 1, 1, 3, 17, 39, 123, 35, 101, 363, 1991, 3309, 2117, 16229, 3017, 0 }; + static ulong[] dim2689Kuo3Init = { 1, 3, 3, 15, 19, 61, 41, 201, 267, 985, 1635, 2681, 883, 13343, 22061, 0 }; + static ulong[] dim2690Kuo3Init = { 1, 1, 7, 7, 9, 13, 15, 139, 25, 989, 1817, 867, 5913, 16197, 7521, 0 }; + static ulong[] dim2691Kuo3Init = { 1, 1, 5, 5, 11, 29, 49, 75, 135, 705, 315, 2769, 3539, 13655, 11443, 0 }; + static ulong[] dim2692Kuo3Init = { 1, 1, 7, 1, 25, 9, 53, 81, 217, 391, 1789, 3837, 1191, 12359, 21831, 0 }; + static ulong[] dim2693Kuo3Init = { 1, 1, 5, 9, 3, 39, 1, 81, 367, 893, 1661, 3693, 9, 4061, 15321, 0 }; + static ulong[] dim2694Kuo3Init = { 1, 1, 5, 5, 27, 21, 11, 23, 287, 901, 1695, 469, 1993, 11435, 12637, 0 }; + static ulong[] dim2695Kuo3Init = { 1, 1, 3, 7, 21, 25, 113, 161, 361, 583, 2023, 831, 7161, 5125, 21097, 0 }; + static ulong[] dim2696Kuo3Init = { 1, 1, 1, 13, 11, 29, 21, 221, 255, 255, 693, 701, 989, 10323, 3165, 0 }; + static ulong[] dim2697Kuo3Init = { 1, 1, 5, 15, 5, 27, 107, 213, 85, 325, 1359, 735, 161, 11505, 24007, 0 }; + static ulong[] dim2698Kuo3Init = { 1, 3, 1, 9, 1, 47, 17, 241, 53, 563, 635, 3159, 3231, 12167, 221, 0 }; + static ulong[] dim2699Kuo3Init = { 1, 1, 1, 9, 21, 51, 15, 1, 491, 283, 1933, 1455, 6921, 10547, 29725, 0 }; + static ulong[] dim2700Kuo3Init = { 1, 3, 3, 3, 31, 43, 123, 103, 291, 479, 1207, 1703, 5591, 6555, 37, 0 }; + static ulong[] dim2701Kuo3Init = { 1, 3, 7, 7, 13, 53, 29, 155, 101, 651, 423, 2705, 6469, 13795, 9903, 0 }; + static ulong[] dim2702Kuo3Init = { 1, 1, 7, 3, 23, 27, 39, 181, 47, 297, 353, 327, 6723, 5981, 8333, 0 }; + static ulong[] dim2703Kuo3Init = { 1, 1, 1, 1, 29, 41, 55, 177, 459, 933, 675, 177, 1459, 6371, 8301, 0 }; + static ulong[] dim2704Kuo3Init = { 1, 3, 5, 1, 11, 29, 45, 119, 145, 793, 1771, 2295, 2349, 13825, 10389, 0 }; + static ulong[] dim2705Kuo3Init = { 1, 3, 7, 7, 13, 9, 85, 201, 509, 285, 1613, 2571, 3925, 4303, 14625, 0 }; + static ulong[] dim2706Kuo3Init = { 1, 3, 5, 1, 17, 53, 89, 93, 401, 429, 865, 679, 1995, 13567, 32275, 0 }; + static ulong[] dim2707Kuo3Init = { 1, 1, 1, 3, 17, 23, 97, 39, 309, 67, 1445, 101, 4305, 12195, 18559, 0 }; + static ulong[] dim2708Kuo3Init = { 1, 1, 5, 11, 27, 35, 119, 67, 411, 461, 1149, 1651, 6149, 1543, 19747, 0 }; + static ulong[] dim2709Kuo3Init = { 1, 1, 5, 9, 23, 51, 25, 109, 283, 331, 1651, 691, 7953, 1979, 7425, 0 }; + static ulong[] dim2710Kuo3Init = { 1, 3, 3, 1, 31, 63, 113, 191, 481, 467, 589, 2375, 4619, 3745, 4343, 0 }; + static ulong[] dim2711Kuo3Init = { 1, 1, 3, 1, 27, 35, 61, 29, 115, 909, 107, 815, 1579, 8373, 32657, 0 }; + static ulong[] dim2712Kuo3Init = { 1, 3, 3, 11, 21, 45, 101, 27, 229, 1011, 497, 841, 7653, 5429, 17329, 0 }; + static ulong[] dim2713Kuo3Init = { 1, 3, 7, 9, 27, 5, 105, 171, 75, 45, 865, 4061, 7947, 4979, 20577, 0 }; + static ulong[] dim2714Kuo3Init = { 1, 3, 7, 15, 9, 45, 67, 221, 27, 31, 187, 2063, 4733, 10087, 23091, 0 }; + static ulong[] dim2715Kuo3Init = { 1, 3, 5, 15, 3, 51, 79, 117, 379, 687, 721, 3645, 6639, 14161, 16187, 0 }; + static ulong[] dim2716Kuo3Init = { 1, 3, 1, 1, 5, 15, 117, 177, 163, 577, 279, 1549, 2397, 8099, 2125, 0 }; + static ulong[] dim2717Kuo3Init = { 1, 3, 3, 5, 17, 11, 121, 89, 313, 541, 47, 1993, 3313, 159, 3761, 0 }; + static ulong[] dim2718Kuo3Init = { 1, 3, 5, 7, 11, 43, 7, 165, 283, 7, 1275, 3391, 417, 11697, 22357, 0 }; + static ulong[] dim2719Kuo3Init = { 1, 1, 3, 13, 27, 47, 65, 51, 83, 223, 2015, 2939, 6121, 3873, 27573, 0 }; + static ulong[] dim2720Kuo3Init = { 1, 3, 1, 3, 19, 55, 115, 105, 345, 393, 1609, 3131, 109, 11443, 23475, 0 }; + static ulong[] dim2721Kuo3Init = { 1, 3, 3, 15, 21, 61, 39, 69, 381, 279, 1473, 1239, 661, 781, 21603, 0 }; + static ulong[] dim2722Kuo3Init = { 1, 1, 7, 1, 3, 7, 7, 129, 229, 233, 77, 845, 7871, 3013, 14469, 0 }; + static ulong[] dim2723Kuo3Init = { 1, 1, 7, 1, 17, 9, 3, 17, 375, 27, 473, 945, 4111, 7645, 7899, 0 }; + static ulong[] dim2724Kuo3Init = { 1, 1, 7, 3, 25, 31, 71, 157, 269, 1003, 1875, 3573, 8121, 14073, 26019, 0 }; + static ulong[] dim2725Kuo3Init = { 1, 3, 3, 13, 17, 25, 57, 1, 63, 425, 507, 2341, 4891, 12643, 32083, 0 }; + static ulong[] dim2726Kuo3Init = { 1, 1, 3, 13, 23, 47, 55, 145, 269, 417, 559, 2065, 5801, 13751, 15617, 0 }; + static ulong[] dim2727Kuo3Init = { 1, 3, 7, 9, 3, 39, 45, 143, 131, 713, 1549, 779, 1427, 10819, 10629, 0 }; + static ulong[] dim2728Kuo3Init = { 1, 1, 5, 3, 13, 61, 99, 145, 293, 393, 1181, 4011, 6843, 12667, 21301, 0 }; + static ulong[] dim2729Kuo3Init = { 1, 3, 7, 1, 19, 29, 105, 109, 391, 569, 1933, 1799, 8045, 509, 13251, 0 }; + static ulong[] dim2730Kuo3Init = { 1, 1, 3, 3, 21, 55, 123, 239, 65, 891, 635, 3107, 2701, 9041, 28249, 0 }; + static ulong[] dim2731Kuo3Init = { 1, 1, 3, 7, 1, 11, 9, 49, 51, 243, 51, 3, 6813, 14995, 27065, 0 }; + static ulong[] dim2732Kuo3Init = { 1, 1, 3, 11, 29, 35, 107, 19, 415, 273, 881, 49, 3267, 4791, 9609, 0 }; + static ulong[] dim2733Kuo3Init = { 1, 1, 5, 3, 5, 39, 59, 127, 267, 215, 375, 133, 8057, 8497, 23595, 0 }; + static ulong[] dim2734Kuo3Init = { 1, 3, 7, 9, 1, 41, 81, 199, 287, 907, 743, 2875, 3873, 2851, 7385, 0 }; + static ulong[] dim2735Kuo3Init = { 1, 3, 1, 13, 13, 49, 25, 43, 105, 511, 1483, 3277, 7561, 7211, 20671, 0 }; + static ulong[] dim2736Kuo3Init = { 1, 3, 5, 13, 19, 21, 37, 87, 439, 69, 1145, 141, 6187, 6329, 26923, 0 }; + static ulong[] dim2737Kuo3Init = { 1, 3, 1, 13, 13, 59, 123, 155, 189, 803, 1807, 363, 2239, 547, 30801, 0 }; + static ulong[] dim2738Kuo3Init = { 1, 3, 7, 7, 1, 61, 93, 25, 205, 275, 1591, 1575, 3951, 12313, 9399, 0 }; + static ulong[] dim2739Kuo3Init = { 1, 1, 1, 9, 11, 49, 43, 241, 435, 515, 283, 3667, 2089, 4755, 19427, 0 }; + static ulong[] dim2740Kuo3Init = { 1, 1, 1, 5, 19, 57, 5, 23, 271, 113, 481, 2619, 4507, 15191, 2227, 0 }; + static ulong[] dim2741Kuo3Init = { 1, 1, 1, 11, 11, 15, 49, 51, 121, 463, 1015, 791, 3993, 14311, 8723, 0 }; + static ulong[] dim2742Kuo3Init = { 1, 1, 1, 7, 17, 19, 55, 137, 211, 307, 1647, 2719, 5231, 13005, 17527, 0 }; + static ulong[] dim2743Kuo3Init = { 1, 1, 3, 3, 1, 25, 5, 119, 271, 611, 1799, 3149, 2159, 9147, 30765, 0 }; + static ulong[] dim2744Kuo3Init = { 1, 1, 1, 15, 5, 19, 75, 137, 483, 457, 1913, 31, 9, 8333, 3315, 0 }; + static ulong[] dim2745Kuo3Init = { 1, 3, 7, 7, 5, 11, 95, 83, 269, 105, 67, 2021, 6423, 10315, 28017, 0 }; + static ulong[] dim2746Kuo3Init = { 1, 3, 1, 7, 27, 49, 7, 45, 297, 899, 665, 2473, 2863, 2171, 10693, 0 }; + static ulong[] dim2747Kuo3Init = { 1, 1, 5, 5, 25, 17, 41, 155, 101, 355, 197, 3853, 2381, 9663, 25187, 0 }; + static ulong[] dim2748Kuo3Init = { 1, 3, 7, 15, 15, 53, 119, 233, 79, 545, 1203, 1535, 3563, 2469, 29449, 0 }; + static ulong[] dim2749Kuo3Init = { 1, 1, 5, 5, 27, 57, 113, 189, 3, 253, 1743, 3735, 5257, 10521, 18679, 0 }; + static ulong[] dim2750Kuo3Init = { 1, 3, 7, 1, 5, 29, 117, 207, 101, 293, 615, 401, 7201, 11451, 13705, 0 }; + static ulong[] dim2751Kuo3Init = { 1, 1, 5, 11, 13, 59, 55, 101, 253, 801, 1947, 3509, 655, 5555, 15517, 0 }; + static ulong[] dim2752Kuo3Init = { 1, 3, 3, 5, 3, 19, 31, 93, 3, 1009, 1535, 261, 2259, 9835, 5797, 0 }; + static ulong[] dim2753Kuo3Init = { 1, 3, 3, 9, 9, 53, 1, 213, 123, 271, 1137, 11, 6331, 9907, 13219, 0 }; + static ulong[] dim2754Kuo3Init = { 1, 1, 7, 5, 17, 9, 83, 153, 231, 3, 1179, 735, 553, 10627, 4643, 0 }; + static ulong[] dim2755Kuo3Init = { 1, 1, 1, 11, 25, 21, 127, 85, 17, 541, 535, 1041, 5071, 15451, 909, 0 }; + static ulong[] dim2756Kuo3Init = { 1, 3, 1, 7, 29, 31, 75, 91, 67, 253, 971, 327, 7491, 7627, 31857, 0 }; + static ulong[] dim2757Kuo3Init = { 1, 3, 1, 5, 23, 19, 79, 197, 25, 83, 1427, 2023, 1861, 1617, 10129, 0 }; + static ulong[] dim2758Kuo3Init = { 1, 1, 5, 13, 27, 55, 113, 191, 119, 301, 1243, 333, 7609, 4875, 19035, 0 }; + static ulong[] dim2759Kuo3Init = { 1, 1, 5, 5, 7, 51, 59, 157, 21, 697, 171, 2857, 3875, 15413, 28749, 0 }; + static ulong[] dim2760Kuo3Init = { 1, 1, 1, 11, 13, 45, 49, 161, 389, 715, 991, 839, 2655, 11399, 5261, 0 }; + static ulong[] dim2761Kuo3Init = { 1, 1, 7, 5, 17, 51, 87, 75, 65, 67, 1283, 1991, 7735, 9063, 313, 0 }; + static ulong[] dim2762Kuo3Init = { 1, 3, 3, 13, 29, 39, 109, 159, 63, 103, 587, 1941, 3883, 1119, 4303, 0 }; + static ulong[] dim2763Kuo3Init = { 1, 3, 3, 1, 15, 27, 69, 49, 417, 281, 1207, 289, 1873, 12287, 19321, 0 }; + static ulong[] dim2764Kuo3Init = { 1, 1, 1, 3, 9, 57, 77, 81, 267, 45, 835, 671, 4569, 12713, 32657, 0 }; + static ulong[] dim2765Kuo3Init = { 1, 1, 7, 5, 25, 25, 73, 165, 413, 845, 529, 2987, 2051, 6155, 29133, 0 }; + static ulong[] dim2766Kuo3Init = { 1, 3, 1, 13, 3, 41, 107, 85, 429, 323, 1509, 649, 5897, 10309, 30927, 0 }; + static ulong[] dim2767Kuo3Init = { 1, 1, 7, 9, 1, 1, 105, 213, 479, 755, 1863, 1429, 5927, 9923, 18531, 0 }; + static ulong[] dim2768Kuo3Init = { 1, 3, 1, 5, 9, 13, 45, 105, 133, 117, 1837, 3019, 3809, 8713, 19865, 0 }; + static ulong[] dim2769Kuo3Init = { 1, 1, 3, 7, 13, 7, 31, 175, 209, 313, 1095, 1093, 2707, 11955, 11137, 0 }; + static ulong[] dim2770Kuo3Init = { 1, 3, 7, 13, 9, 31, 79, 25, 205, 309, 1977, 1207, 5629, 6869, 24269, 0 }; + static ulong[] dim2771Kuo3Init = { 1, 1, 5, 3, 5, 43, 31, 81, 251, 569, 2033, 299, 345, 7437, 2183, 0 }; + static ulong[] dim2772Kuo3Init = { 1, 1, 5, 1, 23, 17, 107, 143, 31, 349, 1501, 2487, 6911, 12591, 17599, 0 }; + static ulong[] dim2773Kuo3Init = { 1, 1, 7, 9, 5, 13, 99, 145, 141, 947, 1587, 3691, 6029, 13153, 13971, 0 }; + static ulong[] dim2774Kuo3Init = { 1, 3, 1, 1, 21, 37, 87, 19, 195, 263, 85, 3285, 1733, 11057, 6293, 0 }; + static ulong[] dim2775Kuo3Init = { 1, 1, 3, 3, 31, 29, 97, 81, 479, 879, 2011, 1041, 8141, 14891, 175, 0 }; + static ulong[] dim2776Kuo3Init = { 1, 3, 5, 7, 13, 35, 61, 219, 103, 161, 1187, 3925, 2041, 2609, 30195, 0 }; + static ulong[] dim2777Kuo3Init = { 1, 3, 1, 13, 15, 43, 31, 163, 401, 451, 1881, 1307, 4201, 6821, 3717, 0 }; + static ulong[] dim2778Kuo3Init = { 1, 3, 7, 3, 5, 3, 85, 149, 47, 1003, 405, 1801, 6695, 897, 28005, 0 }; + static ulong[] dim2779Kuo3Init = { 1, 1, 3, 11, 19, 37, 81, 41, 315, 729, 303, 501, 7483, 10841, 12649, 0 }; + static ulong[] dim2780Kuo3Init = { 1, 1, 1, 1, 1, 51, 121, 129, 49, 511, 719, 2235, 827, 9331, 22551, 0 }; + static ulong[] dim2781Kuo3Init = { 1, 3, 3, 9, 21, 41, 47, 17, 157, 771, 867, 3685, 2387, 7409, 13889, 0 }; + static ulong[] dim2782Kuo3Init = { 1, 3, 7, 7, 11, 53, 119, 19, 289, 337, 551, 2529, 321, 2599, 11153, 0 }; + static ulong[] dim2783Kuo3Init = { 1, 3, 1, 9, 7, 33, 19, 7, 459, 729, 281, 947, 5469, 7497, 22893, 0 }; + static ulong[] dim2784Kuo3Init = { 1, 1, 7, 13, 11, 41, 91, 217, 195, 483, 1659, 1619, 4201, 15825, 3357, 0 }; + static ulong[] dim2785Kuo3Init = { 1, 1, 5, 9, 9, 29, 87, 153, 175, 967, 75, 385, 719, 12269, 28729, 0 }; + static ulong[] dim2786Kuo3Init = { 1, 3, 3, 9, 13, 21, 115, 55, 303, 853, 1735, 3763, 31, 2547, 9735, 0 }; + static ulong[] dim2787Kuo3Init = { 1, 3, 3, 9, 17, 25, 109, 207, 465, 627, 1171, 557, 2577, 13873, 30945, 0 }; + static ulong[] dim2788Kuo3Init = { 1, 1, 1, 1, 27, 25, 65, 131, 373, 297, 1561, 2481, 3491, 3175, 12527, 0 }; + static ulong[] dim2789Kuo3Init = { 1, 1, 7, 11, 13, 33, 81, 81, 337, 249, 739, 1451, 4479, 10253, 3585, 0 }; + static ulong[] dim2790Kuo3Init = { 1, 1, 1, 13, 3, 9, 11, 109, 261, 663, 507, 897, 4081, 12393, 21621, 0 }; + static ulong[] dim2791Kuo3Init = { 1, 1, 1, 9, 27, 35, 13, 191, 433, 111, 1567, 851, 6303, 2411, 25985, 0 }; + static ulong[] dim2792Kuo3Init = { 1, 3, 3, 1, 7, 41, 91, 217, 203, 821, 883, 1549, 37, 1837, 19549, 0 }; + static ulong[] dim2793Kuo3Init = { 1, 3, 3, 11, 23, 49, 27, 81, 475, 251, 985, 2527, 3857, 4579, 30231, 0 }; + static ulong[] dim2794Kuo3Init = { 1, 1, 3, 11, 7, 33, 71, 207, 179, 77, 743, 375, 5649, 3165, 25063, 0 }; + static ulong[] dim2795Kuo3Init = { 1, 1, 3, 9, 25, 47, 21, 109, 375, 525, 671, 1117, 5663, 9835, 19675, 0 }; + static ulong[] dim2796Kuo3Init = { 1, 3, 7, 11, 19, 31, 9, 167, 501, 477, 1015, 109, 6233, 14131, 30015, 0 }; + static ulong[] dim2797Kuo3Init = { 1, 3, 1, 3, 25, 9, 91, 121, 373, 511, 1925, 3609, 7681, 7321, 19931, 0 }; + static ulong[] dim2798Kuo3Init = { 1, 1, 3, 7, 23, 23, 63, 225, 511, 407, 573, 587, 6877, 4747, 31503, 0 }; + static ulong[] dim2799Kuo3Init = { 1, 3, 7, 3, 7, 11, 61, 119, 149, 119, 1497, 165, 5833, 14727, 21075, 0 }; + static ulong[] dim2800Kuo3Init = { 1, 3, 7, 5, 23, 27, 113, 99, 97, 385, 563, 1745, 4321, 2201, 5707, 0 }; + static ulong[] dim2801Kuo3Init = { 1, 1, 3, 15, 5, 51, 49, 213, 111, 587, 1433, 1473, 4673, 369, 31405, 0 }; + static ulong[] dim2802Kuo3Init = { 1, 1, 5, 11, 25, 49, 67, 163, 109, 679, 975, 3711, 6627, 2273, 13451, 0 }; + static ulong[] dim2803Kuo3Init = { 1, 3, 5, 3, 9, 3, 75, 123, 71, 181, 1007, 2459, 5671, 2805, 15839, 0 }; + static ulong[] dim2804Kuo3Init = { 1, 3, 5, 3, 7, 51, 49, 19, 89, 209, 1097, 359, 2487, 12969, 24243, 0 }; + static ulong[] dim2805Kuo3Init = { 1, 1, 7, 11, 1, 47, 61, 65, 161, 801, 511, 3711, 237, 14741, 14239, 0 }; + static ulong[] dim2806Kuo3Init = { 1, 3, 7, 13, 31, 25, 11, 175, 151, 79, 1749, 751, 6129, 12139, 30837, 0 }; + static ulong[] dim2807Kuo3Init = { 1, 3, 3, 11, 19, 13, 71, 75, 479, 211, 395, 1935, 7949, 12049, 31539, 0 }; + static ulong[] dim2808Kuo3Init = { 1, 3, 5, 3, 19, 9, 93, 79, 69, 1001, 673, 1963, 8047, 8023, 8199, 0 }; + static ulong[] dim2809Kuo3Init = { 1, 3, 7, 3, 11, 9, 107, 39, 319, 835, 1297, 1667, 393, 5619, 15019, 0 }; + static ulong[] dim2810Kuo3Init = { 1, 3, 1, 3, 17, 25, 71, 227, 219, 455, 29, 1503, 4207, 11523, 13077, 0 }; + static ulong[] dim2811Kuo3Init = { 1, 3, 7, 1, 11, 11, 91, 203, 483, 959, 911, 979, 4327, 15113, 23415, 0 }; + static ulong[] dim2812Kuo3Init = { 1, 3, 7, 15, 5, 63, 57, 253, 369, 609, 1831, 2895, 1025, 2567, 14017, 0 }; + static ulong[] dim2813Kuo3Init = { 1, 3, 5, 1, 19, 39, 107, 169, 107, 863, 591, 4077, 7441, 3201, 269, 0 }; + static ulong[] dim2814Kuo3Init = { 1, 1, 3, 1, 7, 45, 19, 103, 119, 539, 9, 2909, 8135, 7913, 1403, 0 }; + static ulong[] dim2815Kuo3Init = { 1, 3, 1, 13, 17, 39, 125, 57, 417, 543, 1067, 3807, 397, 11947, 7655, 0 }; + static ulong[] dim2816Kuo3Init = { 1, 3, 5, 7, 31, 49, 65, 23, 197, 777, 1669, 1373, 773, 6947, 2835, 0 }; + static ulong[] dim2817Kuo3Init = { 1, 3, 7, 7, 25, 45, 115, 31, 351, 203, 1791, 2931, 7127, 12117, 10781, 0 }; + static ulong[] dim2818Kuo3Init = { 1, 1, 5, 9, 21, 61, 47, 59, 393, 621, 811, 2321, 7801, 2255, 13513, 0 }; + static ulong[] dim2819Kuo3Init = { 1, 1, 5, 9, 27, 15, 85, 53, 379, 597, 19, 267, 5511, 8167, 14843, 0 }; + static ulong[] dim2820Kuo3Init = { 1, 1, 7, 9, 19, 11, 43, 101, 309, 125, 2023, 689, 589, 3621, 10593, 0 }; + static ulong[] dim2821Kuo3Init = { 1, 3, 1, 1, 25, 57, 55, 57, 111, 743, 1773, 2223, 6567, 7401, 14843, 0 }; + static ulong[] dim2822Kuo3Init = { 1, 3, 1, 11, 17, 43, 1, 11, 155, 287, 519, 4051, 311, 10079, 29753, 0 }; + static ulong[] dim2823Kuo3Init = { 1, 3, 7, 1, 15, 33, 47, 117, 343, 667, 1489, 1985, 5105, 11887, 29117, 0 }; + static ulong[] dim2824Kuo3Init = { 1, 3, 3, 13, 9, 33, 115, 211, 7, 391, 475, 1843, 3277, 11067, 12857, 0 }; + static ulong[] dim2825Kuo3Init = { 1, 1, 7, 7, 31, 11, 17, 147, 129, 875, 845, 2999, 6395, 361, 7395, 0 }; + static ulong[] dim2826Kuo3Init = { 1, 3, 5, 1, 27, 17, 55, 115, 35, 989, 153, 77, 5713, 14653, 587, 0 }; + static ulong[] dim2827Kuo3Init = { 1, 3, 3, 5, 3, 37, 107, 57, 201, 631, 1549, 3709, 3615, 12567, 21729, 0 }; + static ulong[] dim2828Kuo3Init = { 1, 3, 3, 1, 15, 19, 21, 205, 253, 431, 915, 1057, 359, 431, 31417, 0 }; + static ulong[] dim2829Kuo3Init = { 1, 3, 7, 3, 11, 47, 107, 101, 461, 805, 1569, 1215, 765, 1547, 32531, 0 }; + static ulong[] dim2830Kuo3Init = { 1, 3, 3, 3, 21, 55, 61, 171, 75, 337, 231, 1925, 7415, 1073, 17519, 0 }; + static ulong[] dim2831Kuo3Init = { 1, 3, 5, 7, 5, 23, 39, 119, 399, 265, 601, 3487, 1129, 10731, 14795, 0 }; + static ulong[] dim2832Kuo3Init = { 1, 1, 5, 3, 11, 57, 33, 99, 283, 581, 1791, 1723, 411, 5779, 8989, 0 }; + static ulong[] dim2833Kuo3Init = { 1, 3, 3, 13, 19, 33, 81, 245, 375, 763, 77, 175, 5417, 12525, 18197, 0 }; + static ulong[] dim2834Kuo3Init = { 1, 3, 7, 5, 29, 31, 59, 207, 19, 369, 1449, 165, 6115, 15417, 14227, 0 }; + static ulong[] dim2835Kuo3Init = { 1, 3, 5, 11, 7, 15, 109, 171, 179, 541, 1907, 2545, 5633, 8039, 23495, 0 }; + static ulong[] dim2836Kuo3Init = { 1, 3, 5, 7, 5, 5, 51, 5, 347, 351, 177, 965, 6583, 3631, 26493, 0 }; + static ulong[] dim2837Kuo3Init = { 1, 1, 1, 15, 21, 55, 101, 137, 165, 947, 1149, 2615, 3709, 8231, 2033, 0 }; + static ulong[] dim2838Kuo3Init = { 1, 3, 5, 1, 1, 11, 29, 5, 353, 675, 2045, 2111, 2477, 7803, 18925, 0 }; + static ulong[] dim2839Kuo3Init = { 1, 3, 3, 7, 11, 5, 43, 241, 103, 87, 1841, 841, 277, 7647, 6953, 0 }; + static ulong[] dim2840Kuo3Init = { 1, 1, 3, 9, 23, 15, 77, 199, 457, 183, 1719, 4077, 2751, 6285, 2741, 0 }; + static ulong[] dim2841Kuo3Init = { 1, 3, 5, 13, 11, 7, 119, 207, 89, 415, 1501, 2333, 2155, 13559, 9701, 0 }; + static ulong[] dim2842Kuo3Init = { 1, 1, 7, 1, 9, 29, 119, 171, 259, 849, 493, 3103, 2559, 4323, 8993, 0 }; + static ulong[] dim2843Kuo3Init = { 1, 3, 7, 15, 5, 3, 35, 29, 177, 19, 565, 2111, 4781, 13603, 10759, 0 }; + static ulong[] dim2844Kuo3Init = { 1, 1, 3, 13, 7, 41, 45, 181, 55, 575, 685, 2407, 3499, 10073, 5717, 0 }; + static ulong[] dim2845Kuo3Init = { 1, 3, 5, 11, 25, 31, 97, 247, 411, 663, 413, 771, 2325, 4849, 18605, 0 }; + static ulong[] dim2846Kuo3Init = { 1, 1, 1, 1, 11, 55, 77, 183, 131, 873, 315, 3403, 7219, 5419, 9943, 0 }; + static ulong[] dim2847Kuo3Init = { 1, 1, 5, 11, 17, 49, 125, 1, 379, 995, 1911, 9, 1201, 14599, 3237, 0 }; + static ulong[] dim2848Kuo3Init = { 1, 1, 5, 7, 5, 47, 25, 47, 93, 1009, 361, 3111, 6221, 15799, 11049, 0 }; + static ulong[] dim2849Kuo3Init = { 1, 1, 1, 13, 31, 41, 27, 119, 463, 357, 1399, 3023, 8145, 7233, 10461, 0 }; + static ulong[] dim2850Kuo3Init = { 1, 3, 1, 13, 25, 1, 89, 167, 13, 477, 989, 1109, 3279, 1893, 22091, 0 }; + static ulong[] dim2851Kuo3Init = { 1, 1, 3, 11, 27, 27, 127, 85, 135, 975, 557, 2247, 5675, 7397, 28829, 0 }; + static ulong[] dim2852Kuo3Init = { 1, 1, 3, 3, 5, 57, 87, 115, 399, 189, 497, 2525, 323, 2849, 1539, 0 }; + static ulong[] dim2853Kuo3Init = { 1, 3, 5, 15, 31, 57, 49, 13, 151, 483, 1117, 2177, 4011, 2467, 5465, 0 }; + static ulong[] dim2854Kuo3Init = { 1, 3, 1, 13, 17, 49, 31, 167, 385, 183, 225, 465, 2099, 475, 28001, 0 }; + static ulong[] dim2855Kuo3Init = { 1, 1, 3, 3, 23, 39, 37, 63, 419, 95, 1217, 1147, 7599, 985, 23455, 0 }; + static ulong[] dim2856Kuo3Init = { 1, 3, 1, 5, 15, 53, 17, 221, 441, 303, 1595, 3731, 7833, 14649, 30843, 0 }; + static ulong[] dim2857Kuo3Init = { 1, 3, 3, 15, 13, 63, 29, 137, 263, 79, 591, 679, 4681, 4121, 22733, 0 }; + static ulong[] dim2858Kuo3Init = { 1, 1, 3, 3, 27, 31, 97, 191, 295, 601, 1353, 3817, 2305, 427, 5985, 0 }; + static ulong[] dim2859Kuo3Init = { 1, 3, 5, 7, 29, 27, 27, 249, 441, 415, 489, 779, 5927, 10569, 7539, 0 }; + static ulong[] dim2860Kuo3Init = { 1, 3, 7, 1, 1, 59, 21, 115, 25, 715, 697, 3585, 383, 8043, 21457, 0 }; + static ulong[] dim2861Kuo3Init = { 1, 1, 7, 1, 3, 37, 25, 239, 25, 213, 1449, 1975, 1805, 11867, 24163, 0 }; + static ulong[] dim2862Kuo3Init = { 1, 3, 5, 7, 9, 37, 95, 19, 105, 787, 249, 2501, 5073, 2677, 2871, 0 }; + static ulong[] dim2863Kuo3Init = { 1, 1, 1, 7, 25, 17, 59, 79, 467, 489, 1981, 169, 7713, 3035, 6135, 0 }; + static ulong[] dim2864Kuo3Init = { 1, 1, 1, 11, 21, 41, 75, 59, 495, 475, 803, 3117, 4999, 5153, 20541, 0 }; + static ulong[] dim2865Kuo3Init = { 1, 3, 5, 5, 21, 5, 43, 69, 167, 743, 1395, 3701, 1329, 12039, 26595, 0 }; + static ulong[] dim2866Kuo3Init = { 1, 3, 5, 5, 7, 51, 7, 191, 341, 561, 617, 803, 965, 7995, 7605, 0 }; + static ulong[] dim2867Kuo3Init = { 1, 3, 5, 1, 25, 21, 21, 141, 461, 353, 1909, 1089, 4603, 7285, 30359, 0 }; + static ulong[] dim2868Kuo3Init = { 1, 3, 1, 7, 13, 17, 47, 173, 151, 1003, 1823, 1463, 6441, 8647, 8671, 0 }; + static ulong[] dim2869Kuo3Init = { 1, 1, 3, 13, 29, 29, 111, 237, 341, 693, 773, 637, 741, 7737, 12077, 0 }; + static ulong[] dim2870Kuo3Init = { 1, 1, 5, 9, 1, 27, 71, 177, 379, 289, 1659, 697, 4765, 15945, 24463, 0 }; + static ulong[] dim2871Kuo3Init = { 1, 1, 7, 7, 15, 13, 77, 59, 5, 483, 581, 2193, 7765, 14443, 21545, 0 }; + static ulong[] dim2872Kuo3Init = { 1, 3, 5, 11, 9, 17, 111, 13, 427, 405, 1765, 2029, 4989, 1995, 18581, 0 }; + static ulong[] dim2873Kuo3Init = { 1, 1, 1, 1, 17, 15, 9, 43, 177, 277, 217, 1869, 2847, 11839, 5483, 0 }; + static ulong[] dim2874Kuo3Init = { 1, 3, 5, 13, 1, 61, 87, 211, 367, 317, 1681, 3913, 2635, 5095, 2993, 0 }; + static ulong[] dim2875Kuo3Init = { 1, 3, 5, 11, 13, 47, 123, 111, 139, 193, 1575, 3549, 2113, 2997, 2319, 0 }; + static ulong[] dim2876Kuo3Init = { 1, 3, 7, 9, 17, 29, 67, 195, 455, 137, 1159, 367, 469, 4663, 13811, 0 }; + static ulong[] dim2877Kuo3Init = { 1, 3, 1, 9, 21, 55, 27, 165, 483, 487, 1199, 2989, 3195, 8847, 12465, 0 }; + static ulong[] dim2878Kuo3Init = { 1, 3, 3, 5, 13, 31, 5, 77, 283, 837, 827, 3477, 5555, 15411, 803, 0 }; + static ulong[] dim2879Kuo3Init = { 1, 3, 5, 1, 5, 47, 23, 21, 255, 193, 67, 1489, 5785, 3247, 18425, 0 }; + static ulong[] dim2880Kuo3Init = { 1, 1, 5, 11, 3, 41, 1, 37, 281, 767, 419, 1067, 749, 4985, 18525, 0 }; + static ulong[] dim2881Kuo3Init = { 1, 1, 3, 7, 29, 47, 37, 195, 359, 517, 1809, 2111, 419, 1895, 17813, 0 }; + static ulong[] dim2882Kuo3Init = { 1, 3, 1, 13, 13, 61, 99, 183, 311, 515, 1359, 1077, 835, 12945, 27707, 0 }; + static ulong[] dim2883Kuo3Init = { 1, 3, 7, 15, 5, 25, 77, 7, 249, 325, 929, 3121, 4183, 9347, 1209, 0 }; + static ulong[] dim2884Kuo3Init = { 1, 1, 1, 7, 13, 59, 9, 251, 323, 479, 1791, 555, 2591, 417, 23821, 0 }; + static ulong[] dim2885Kuo3Init = { 1, 3, 7, 1, 31, 25, 43, 167, 337, 321, 1223, 3693, 1945, 4937, 15613, 0 }; + static ulong[] dim2886Kuo3Init = { 1, 3, 1, 13, 23, 27, 71, 3, 249, 427, 1259, 2493, 3463, 8339, 2361, 0 }; + static ulong[] dim2887Kuo3Init = { 1, 3, 3, 3, 25, 49, 19, 167, 189, 211, 1247, 2883, 6983, 14573, 1021, 0 }; + static ulong[] dim2888Kuo3Init = { 1, 1, 7, 11, 5, 53, 119, 115, 497, 57, 1255, 2771, 6055, 865, 2735, 0 }; + static ulong[] dim2889Kuo3Init = { 1, 1, 7, 11, 25, 63, 83, 115, 185, 615, 1135, 1577, 3097, 2955, 7667, 0 }; + static ulong[] dim2890Kuo3Init = { 1, 3, 7, 7, 19, 33, 61, 121, 339, 153, 89, 1841, 3219, 10177, 13655, 0 }; + static ulong[] dim2891Kuo3Init = { 1, 3, 5, 3, 23, 51, 111, 149, 283, 863, 1687, 813, 951, 10593, 2491, 0 }; + static ulong[] dim2892Kuo3Init = { 1, 1, 5, 7, 19, 63, 47, 73, 91, 501, 1837, 4079, 313, 14141, 7843, 0 }; + static ulong[] dim2893Kuo3Init = { 1, 3, 1, 9, 9, 15, 49, 195, 433, 289, 1109, 3929, 5589, 8943, 6325, 0 }; + static ulong[] dim2894Kuo3Init = { 1, 3, 5, 13, 13, 1, 97, 111, 379, 963, 837, 3681, 3281, 153, 9133, 0 }; + static ulong[] dim2895Kuo3Init = { 1, 3, 5, 1, 19, 37, 7, 81, 443, 555, 1885, 3123, 7667, 2579, 3521, 0 }; + static ulong[] dim2896Kuo3Init = { 1, 3, 1, 1, 21, 17, 77, 121, 157, 993, 627, 893, 7633, 6421, 7315, 0 }; + static ulong[] dim2897Kuo3Init = { 1, 1, 3, 15, 25, 21, 105, 187, 17, 239, 1745, 13, 1021, 13319, 8511, 0 }; + static ulong[] dim2898Kuo3Init = { 1, 3, 1, 5, 5, 19, 67, 79, 79, 361, 1189, 3967, 6643, 2367, 18247, 0 }; + static ulong[] dim2899Kuo3Init = { 1, 3, 5, 15, 5, 15, 17, 139, 405, 229, 1819, 369, 4011, 11369, 5271, 0 }; + static ulong[] dim2900Kuo3Init = { 1, 3, 1, 3, 19, 3, 97, 121, 345, 917, 1473, 1439, 1007, 2535, 17107, 0 }; + static ulong[] dim2901Kuo3Init = { 1, 3, 7, 3, 3, 55, 117, 183, 65, 589, 107, 3933, 6911, 6425, 28363, 0 }; + static ulong[] dim2902Kuo3Init = { 1, 1, 7, 11, 25, 55, 57, 45, 217, 213, 281, 2211, 6851, 11553, 30021, 0 }; + static ulong[] dim2903Kuo3Init = { 1, 3, 7, 11, 29, 5, 1, 15, 477, 233, 677, 311, 3207, 10527, 5543, 0 }; + static ulong[] dim2904Kuo3Init = { 1, 3, 3, 15, 21, 57, 43, 9, 145, 369, 1367, 3241, 2821, 8753, 18579, 0 }; + static ulong[] dim2905Kuo3Init = { 1, 1, 3, 1, 13, 15, 99, 237, 101, 983, 657, 1169, 617, 12859, 32279, 0 }; + static ulong[] dim2906Kuo3Init = { 1, 3, 3, 3, 11, 61, 53, 39, 487, 967, 1239, 1899, 7063, 7943, 6739, 0 }; + static ulong[] dim2907Kuo3Init = { 1, 1, 7, 15, 1, 17, 27, 121, 13, 519, 1049, 3613, 2777, 11077, 28601, 0 }; + static ulong[] dim2908Kuo3Init = { 1, 3, 7, 13, 27, 47, 39, 71, 179, 899, 1871, 3783, 2029, 2653, 5711, 0 }; + static ulong[] dim2909Kuo3Init = { 1, 3, 3, 13, 15, 13, 67, 113, 321, 1017, 1615, 1575, 3879, 6113, 31893, 0 }; + static ulong[] dim2910Kuo3Init = { 1, 1, 7, 3, 25, 45, 3, 121, 275, 313, 205, 1743, 5349, 4535, 22849, 0 }; + static ulong[] dim2911Kuo3Init = { 1, 1, 3, 1, 3, 19, 21, 97, 455, 1021, 773, 1825, 6985, 9389, 21107, 0 }; + static ulong[] dim2912Kuo3Init = { 1, 3, 5, 9, 5, 3, 29, 9, 261, 575, 1111, 1983, 7629, 15743, 11009, 0 }; + static ulong[] dim2913Kuo3Init = { 1, 3, 1, 3, 25, 25, 79, 181, 417, 109, 29, 777, 4753, 6131, 4939, 0 }; + static ulong[] dim2914Kuo3Init = { 1, 1, 3, 1, 1, 1, 73, 175, 377, 531, 1829, 37, 497, 12055, 24991, 0 }; + static ulong[] dim2915Kuo3Init = { 1, 1, 5, 9, 27, 7, 63, 115, 381, 525, 1183, 1035, 5115, 2943, 2947, 0 }; + static ulong[] dim2916Kuo3Init = { 1, 3, 7, 11, 13, 17, 25, 203, 479, 887, 1465, 249, 4347, 12201, 10365, 0 }; + static ulong[] dim2917Kuo3Init = { 1, 3, 5, 13, 7, 19, 11, 173, 505, 509, 1311, 3535, 403, 13245, 25357, 0 }; + static ulong[] dim2918Kuo3Init = { 1, 1, 5, 1, 11, 53, 111, 243, 509, 17, 1281, 1149, 4561, 4705, 5783, 0 }; + static ulong[] dim2919Kuo3Init = { 1, 3, 7, 5, 29, 7, 39, 75, 385, 921, 147, 3419, 237, 12609, 10103, 0 }; + static ulong[] dim2920Kuo3Init = { 1, 1, 5, 3, 5, 21, 75, 109, 451, 371, 743, 3, 5277, 10917, 2677, 0 }; + static ulong[] dim2921Kuo3Init = { 1, 3, 5, 5, 21, 29, 85, 79, 359, 607, 191, 2481, 2089, 13441, 23575, 0 }; + static ulong[] dim2922Kuo3Init = { 1, 3, 1, 11, 1, 43, 35, 119, 363, 477, 159, 3999, 7731, 15279, 20611, 0 }; + static ulong[] dim2923Kuo3Init = { 1, 1, 5, 5, 1, 9, 111, 19, 191, 899, 2039, 1153, 7893, 1627, 32325, 0 }; + static ulong[] dim2924Kuo3Init = { 1, 1, 1, 11, 1, 1, 43, 199, 329, 245, 1643, 2869, 5563, 3911, 21837, 0 }; + static ulong[] dim2925Kuo3Init = { 1, 1, 5, 15, 11, 15, 35, 153, 489, 383, 1313, 1881, 5895, 10085, 2489, 0 }; + static ulong[] dim2926Kuo3Init = { 1, 3, 1, 5, 27, 29, 15, 209, 27, 291, 77, 1759, 1565, 5477, 18701, 0 }; + static ulong[] dim2927Kuo3Init = { 1, 3, 5, 5, 19, 39, 35, 207, 345, 625, 1797, 2563, 8043, 1559, 18415, 0 }; + static ulong[] dim2928Kuo3Init = { 1, 3, 1, 1, 21, 43, 101, 89, 229, 435, 1445, 2789, 6903, 11629, 29933, 0 }; + static ulong[] dim2929Kuo3Init = { 1, 1, 7, 7, 21, 23, 107, 21, 377, 67, 1007, 2323, 2957, 6553, 3225, 0 }; + static ulong[] dim2930Kuo3Init = { 1, 1, 3, 13, 3, 13, 121, 119, 253, 391, 215, 851, 5047, 4577, 17691, 0 }; + static ulong[] dim2931Kuo3Init = { 1, 3, 3, 3, 3, 37, 65, 103, 395, 745, 1897, 3031, 2321, 5731, 4657, 0 }; + static ulong[] dim2932Kuo3Init = { 1, 3, 1, 7, 17, 19, 61, 159, 459, 207, 397, 1101, 5835, 1947, 28479, 0 }; + static ulong[] dim2933Kuo3Init = { 1, 1, 7, 7, 23, 13, 63, 7, 231, 15, 855, 375, 673, 12523, 20981, 0 }; + static ulong[] dim2934Kuo3Init = { 1, 1, 7, 3, 21, 13, 109, 93, 7, 767, 477, 2301, 3587, 6053, 427, 0 }; + static ulong[] dim2935Kuo3Init = { 1, 1, 5, 5, 23, 9, 97, 175, 139, 983, 993, 2447, 2183, 16143, 10059, 0 }; + static ulong[] dim2936Kuo3Init = { 1, 1, 1, 1, 17, 61, 9, 13, 241, 825, 707, 3385, 6551, 7321, 1825, 0 }; + static ulong[] dim2937Kuo3Init = { 1, 1, 5, 1, 9, 63, 101, 33, 151, 629, 1903, 3159, 1083, 11109, 27679, 0 }; + static ulong[] dim2938Kuo3Init = { 1, 3, 1, 13, 11, 57, 123, 191, 41, 765, 1039, 2639, 3793, 1403, 20745, 0 }; + static ulong[] dim2939Kuo3Init = { 1, 3, 7, 13, 23, 45, 21, 39, 259, 531, 1205, 3537, 1927, 4357, 16185, 0 }; + static ulong[] dim2940Kuo3Init = { 1, 1, 3, 1, 5, 59, 127, 187, 67, 377, 1577, 401, 4523, 8433, 20965, 0 }; + static ulong[] dim2941Kuo3Init = { 1, 3, 3, 7, 9, 37, 9, 221, 459, 301, 1937, 283, 6973, 3545, 203, 0 }; + static ulong[] dim2942Kuo3Init = { 1, 1, 3, 5, 27, 29, 59, 47, 11, 791, 1863, 1725, 2797, 2673, 9551, 0 }; + static ulong[] dim2943Kuo3Init = { 1, 1, 5, 3, 9, 17, 75, 167, 31, 879, 1841, 801, 5659, 10199, 8639, 0 }; + static ulong[] dim2944Kuo3Init = { 1, 3, 3, 13, 27, 35, 99, 97, 153, 987, 1847, 2209, 8139, 647, 30087, 0 }; + static ulong[] dim2945Kuo3Init = { 1, 1, 5, 5, 3, 9, 85, 105, 503, 279, 1919, 1407, 8161, 3601, 26729, 0 }; + static ulong[] dim2946Kuo3Init = { 1, 3, 7, 1, 23, 37, 71, 131, 315, 401, 389, 547, 7305, 581, 14619, 0 }; + static ulong[] dim2947Kuo3Init = { 1, 1, 7, 5, 3, 47, 125, 87, 255, 397, 1561, 433, 7057, 4595, 17785, 0 }; + static ulong[] dim2948Kuo3Init = { 1, 1, 5, 7, 17, 59, 107, 141, 437, 335, 397, 3913, 3777, 8625, 25539, 0 }; + static ulong[] dim2949Kuo3Init = { 1, 1, 5, 1, 9, 21, 43, 13, 75, 667, 287, 347, 1503, 15905, 17281, 0 }; + static ulong[] dim2950Kuo3Init = { 1, 1, 1, 5, 7, 1, 25, 91, 337, 909, 1555, 1719, 1169, 8537, 8859, 0 }; + static ulong[] dim2951Kuo3Init = { 1, 1, 3, 15, 11, 17, 3, 67, 305, 565, 2023, 1175, 1135, 4453, 21431, 0 }; + static ulong[] dim2952Kuo3Init = { 1, 3, 1, 9, 5, 17, 23, 41, 317, 63, 775, 3699, 3141, 12917, 1847, 0 }; + static ulong[] dim2953Kuo3Init = { 1, 1, 5, 5, 13, 41, 27, 229, 113, 223, 1411, 2733, 7769, 831, 20447, 0 }; + static ulong[] dim2954Kuo3Init = { 1, 1, 3, 13, 9, 15, 9, 235, 501, 709, 643, 79, 2163, 10511, 8763, 0 }; + static ulong[] dim2955Kuo3Init = { 1, 3, 3, 7, 13, 3, 61, 173, 507, 619, 1169, 3133, 533, 7989, 14071, 0 }; + static ulong[] dim2956Kuo3Init = { 1, 1, 5, 11, 9, 11, 63, 147, 73, 501, 371, 489, 5689, 3289, 23459, 0 }; + static ulong[] dim2957Kuo3Init = { 1, 1, 1, 1, 23, 21, 83, 127, 507, 395, 445, 4021, 7401, 14939, 781, 0 }; + static ulong[] dim2958Kuo3Init = { 1, 1, 5, 11, 21, 15, 57, 9, 223, 603, 271, 2277, 7509, 5183, 9645, 0 }; + static ulong[] dim2959Kuo3Init = { 1, 3, 1, 5, 3, 37, 59, 75, 325, 481, 1503, 2891, 3333, 5251, 24987, 0 }; + static ulong[] dim2960Kuo3Init = { 1, 1, 7, 5, 25, 3, 95, 55, 437, 809, 1459, 957, 4037, 4139, 22307, 0 }; + static ulong[] dim2961Kuo3Init = { 1, 3, 5, 5, 7, 43, 111, 183, 321, 475, 633, 3183, 2885, 2083, 2515, 0 }; + static ulong[] dim2962Kuo3Init = { 1, 1, 3, 3, 1, 1, 9, 159, 257, 257, 431, 3433, 6191, 15379, 29129, 0 }; + static ulong[] dim2963Kuo3Init = { 1, 1, 3, 9, 19, 7, 69, 119, 391, 381, 1355, 877, 245, 5287, 451, 0 }; + static ulong[] dim2964Kuo3Init = { 1, 3, 7, 3, 15, 27, 47, 19, 213, 213, 1435, 3835, 3639, 16037, 32613, 0 }; + static ulong[] dim2965Kuo3Init = { 1, 3, 5, 15, 19, 9, 115, 1, 319, 893, 29, 3363, 2491, 8091, 29797, 0 }; + static ulong[] dim2966Kuo3Init = { 1, 3, 3, 11, 19, 9, 111, 181, 37, 819, 843, 3591, 3617, 11209, 1731, 0 }; + static ulong[] dim2967Kuo3Init = { 1, 3, 5, 7, 17, 31, 107, 147, 469, 409, 1391, 927, 4483, 15859, 11231, 0 }; + static ulong[] dim2968Kuo3Init = { 1, 3, 7, 15, 17, 37, 37, 165, 289, 857, 243, 3803, 8131, 7409, 12197, 0 }; + static ulong[] dim2969Kuo3Init = { 1, 1, 1, 9, 17, 61, 75, 177, 63, 835, 731, 2015, 7287, 11803, 11595, 0 }; + static ulong[] dim2970Kuo3Init = { 1, 3, 1, 15, 17, 43, 33, 151, 259, 951, 73, 2229, 4851, 7875, 21497, 0 }; + static ulong[] dim2971Kuo3Init = { 1, 3, 7, 11, 25, 5, 91, 15, 231, 729, 865, 545, 3043, 8925, 9111, 0 }; + static ulong[] dim2972Kuo3Init = { 1, 3, 5, 3, 27, 13, 67, 175, 135, 999, 997, 2237, 617, 14805, 31347, 0 }; + static ulong[] dim2973Kuo3Init = { 1, 3, 1, 7, 5, 37, 59, 155, 11, 401, 421, 305, 4727, 7087, 27231, 0 }; + static ulong[] dim2974Kuo3Init = { 1, 3, 1, 7, 7, 39, 105, 215, 241, 959, 1065, 2045, 5807, 1219, 12545, 0 }; + static ulong[] dim2975Kuo3Init = { 1, 1, 3, 5, 3, 61, 3, 141, 363, 677, 1149, 1143, 1697, 11339, 10503, 0 }; + static ulong[] dim2976Kuo3Init = { 1, 1, 5, 5, 15, 1, 37, 183, 279, 885, 571, 1537, 5489, 12111, 4867, 0 }; + static ulong[] dim2977Kuo3Init = { 1, 1, 3, 15, 7, 49, 49, 37, 323, 407, 1555, 1209, 8159, 12171, 4457, 0 }; + static ulong[] dim2978Kuo3Init = { 1, 3, 3, 9, 9, 17, 111, 19, 353, 273, 1271, 975, 3935, 9689, 18355, 0 }; + static ulong[] dim2979Kuo3Init = { 1, 3, 1, 7, 17, 37, 21, 127, 115, 19, 771, 667, 4219, 1829, 18899, 0 }; + static ulong[] dim2980Kuo3Init = { 1, 3, 3, 7, 3, 43, 67, 43, 119, 319, 1165, 2759, 5389, 10891, 16529, 0 }; + static ulong[] dim2981Kuo3Init = { 1, 3, 3, 11, 29, 17, 53, 137, 329, 71, 1499, 3381, 3533, 15551, 30561, 0 }; + static ulong[] dim2982Kuo3Init = { 1, 3, 3, 3, 5, 61, 45, 109, 389, 505, 1803, 1845, 2165, 267, 14573, 0 }; + static ulong[] dim2983Kuo3Init = { 1, 3, 7, 5, 25, 55, 47, 17, 421, 711, 613, 1537, 5255, 13437, 3425, 0 }; + static ulong[] dim2984Kuo3Init = { 1, 1, 3, 7, 25, 51, 25, 67, 409, 309, 951, 131, 2781, 7445, 1487, 0 }; + static ulong[] dim2985Kuo3Init = { 1, 3, 7, 9, 27, 21, 45, 73, 465, 977, 1327, 837, 1311, 11167, 21265, 0 }; + static ulong[] dim2986Kuo3Init = { 1, 1, 3, 11, 17, 61, 27, 83, 271, 245, 187, 1947, 7989, 13633, 27023, 0 }; + static ulong[] dim2987Kuo3Init = { 1, 3, 1, 9, 17, 7, 35, 195, 465, 745, 1833, 3231, 3061, 1631, 9081, 0 }; + static ulong[] dim2988Kuo3Init = { 1, 3, 3, 1, 5, 39, 83, 13, 199, 821, 839, 3509, 3857, 12389, 28771, 0 }; + static ulong[] dim2989Kuo3Init = { 1, 3, 3, 3, 5, 15, 91, 199, 239, 97, 1699, 549, 4735, 15127, 7407, 0 }; + static ulong[] dim2990Kuo3Init = { 1, 3, 7, 9, 13, 1, 7, 109, 93, 733, 1221, 3361, 7765, 11317, 431, 0 }; + static ulong[] dim2991Kuo3Init = { 1, 3, 7, 15, 31, 23, 17, 97, 477, 497, 1123, 2731, 3157, 5217, 23901, 0 }; + static ulong[] dim2992Kuo3Init = { 1, 1, 5, 1, 1, 41, 63, 11, 507, 55, 1927, 2193, 6177, 3013, 24095, 0 }; + static ulong[] dim2993Kuo3Init = { 1, 1, 7, 3, 25, 57, 113, 99, 383, 831, 1455, 2603, 4619, 9495, 5073, 0 }; + static ulong[] dim2994Kuo3Init = { 1, 1, 5, 11, 25, 35, 67, 83, 125, 909, 227, 1337, 3729, 7623, 27899, 0 }; + static ulong[] dim2995Kuo3Init = { 1, 1, 1, 13, 15, 23, 117, 73, 285, 341, 241, 3569, 7401, 16185, 18571, 0 }; + static ulong[] dim2996Kuo3Init = { 1, 1, 7, 11, 23, 9, 123, 93, 287, 881, 1857, 195, 3999, 81, 26173, 0 }; + static ulong[] dim2997Kuo3Init = { 1, 1, 3, 9, 21, 27, 57, 251, 321, 109, 811, 3665, 4575, 15971, 24111, 0 }; + static ulong[] dim2998Kuo3Init = { 1, 1, 7, 11, 11, 53, 71, 11, 67, 433, 549, 3121, 193, 13099, 6635, 0 }; + static ulong[] dim2999Kuo3Init = { 1, 3, 1, 9, 1, 39, 75, 163, 259, 523, 941, 3025, 3757, 2589, 15403, 0 }; + static ulong[] dim3000Kuo3Init = { 1, 3, 5, 1, 1, 15, 47, 83, 33, 881, 215, 1717, 2255, 7349, 27345, 0 }; + static ulong[] dim3001Kuo3Init = { 1, 1, 3, 11, 15, 55, 95, 125, 511, 829, 1021, 2095, 1107, 13071, 29279, 0 }; + static ulong[] dim3002Kuo3Init = { 1, 1, 5, 11, 15, 63, 15, 123, 233, 351, 1687, 3383, 287, 2721, 20109, 0 }; + static ulong[] dim3003Kuo3Init = { 1, 1, 1, 7, 7, 19, 103, 29, 349, 875, 1631, 119, 6095, 7623, 4063, 0 }; + static ulong[] dim3004Kuo3Init = { 1, 3, 5, 5, 21, 41, 45, 91, 445, 193, 1077, 3849, 163, 15123, 9677, 0 }; + static ulong[] dim3005Kuo3Init = { 1, 1, 3, 1, 7, 39, 127, 75, 53, 233, 531, 635, 8055, 8789, 6205, 0 }; + static ulong[] dim3006Kuo3Init = { 1, 3, 7, 5, 21, 19, 53, 197, 207, 791, 1193, 365, 5747, 12155, 30361, 0 }; + static ulong[] dim3007Kuo3Init = { 1, 1, 1, 15, 23, 39, 95, 75, 239, 639, 253, 3329, 6017, 6647, 16381, 0 }; + static ulong[] dim3008Kuo3Init = { 1, 3, 3, 7, 5, 37, 85, 45, 473, 299, 767, 3795, 6895, 16255, 20411, 0 }; + static ulong[] dim3009Kuo3Init = { 1, 1, 5, 15, 31, 33, 83, 79, 341, 11, 561, 2051, 485, 8653, 7751, 0 }; + static ulong[] dim3010Kuo3Init = { 1, 1, 1, 1, 9, 39, 127, 115, 55, 281, 1439, 2527, 3975, 9037, 32221, 0 }; + static ulong[] dim3011Kuo3Init = { 1, 1, 7, 5, 27, 45, 117, 67, 471, 101, 927, 2391, 4935, 14477, 17515, 0 }; + static ulong[] dim3012Kuo3Init = { 1, 3, 1, 1, 5, 1, 45, 93, 169, 181, 609, 3489, 4779, 11641, 16535, 0 }; + static ulong[] dim3013Kuo3Init = { 1, 3, 3, 5, 1, 53, 21, 169, 199, 769, 813, 1799, 5199, 13499, 25677, 0 }; + static ulong[] dim3014Kuo3Init = { 1, 1, 3, 7, 13, 43, 127, 169, 503, 935, 1315, 1449, 1497, 6173, 20437, 0 }; + static ulong[] dim3015Kuo3Init = { 1, 1, 5, 3, 19, 31, 83, 167, 23, 1019, 1223, 2705, 6471, 11619, 10589, 0 }; + static ulong[] dim3016Kuo3Init = { 1, 1, 5, 3, 7, 39, 117, 67, 159, 301, 553, 2005, 5455, 10049, 3441, 0 }; + static ulong[] dim3017Kuo3Init = { 1, 3, 5, 5, 7, 45, 59, 73, 105, 507, 387, 2697, 5679, 9825, 7689, 0 }; + static ulong[] dim3018Kuo3Init = { 1, 1, 7, 13, 3, 35, 93, 129, 273, 165, 1615, 3631, 1391, 10631, 27157, 0 }; + static ulong[] dim3019Kuo3Init = { 1, 1, 5, 5, 9, 25, 23, 101, 1, 741, 1539, 1893, 1573, 10037, 3079, 0 }; + static ulong[] dim3020Kuo3Init = { 1, 1, 1, 13, 29, 63, 119, 83, 239, 993, 1663, 391, 1583, 11393, 8361, 0 }; + static ulong[] dim3021Kuo3Init = { 1, 1, 5, 5, 11, 55, 41, 155, 439, 631, 1949, 1529, 5249, 883, 25125, 0 }; + static ulong[] dim3022Kuo3Init = { 1, 3, 1, 1, 19, 15, 35, 175, 33, 199, 1979, 4025, 1543, 6451, 11485, 0 }; + static ulong[] dim3023Kuo3Init = { 1, 3, 1, 1, 17, 63, 127, 191, 463, 973, 1509, 1925, 3469, 15967, 10661, 0 }; + static ulong[] dim3024Kuo3Init = { 1, 1, 1, 11, 7, 57, 111, 127, 475, 625, 553, 1941, 2923, 5203, 16915, 0 }; + static ulong[] dim3025Kuo3Init = { 1, 1, 1, 5, 15, 23, 61, 93, 251, 865, 2011, 2607, 1691, 10359, 4667, 0 }; + static ulong[] dim3026Kuo3Init = { 1, 3, 1, 13, 29, 19, 5, 101, 205, 515, 1953, 3543, 929, 8745, 1773, 0 }; + static ulong[] dim3027Kuo3Init = { 1, 1, 7, 15, 19, 29, 127, 153, 383, 799, 639, 3271, 6487, 2989, 8965, 0 }; + static ulong[] dim3028Kuo3Init = { 1, 1, 5, 15, 7, 7, 73, 239, 117, 261, 1147, 3761, 1531, 15613, 13545, 0 }; + static ulong[] dim3029Kuo3Init = { 1, 3, 1, 11, 17, 29, 53, 161, 47, 933, 1763, 1543, 3661, 9369, 14239, 0 }; + static ulong[] dim3030Kuo3Init = { 1, 1, 5, 9, 13, 47, 19, 139, 115, 239, 799, 2211, 6205, 5273, 31205, 0 }; + static ulong[] dim3031Kuo3Init = { 1, 1, 5, 9, 29, 53, 121, 3, 89, 253, 1201, 89, 297, 11561, 9655, 0 }; + static ulong[] dim3032Kuo3Init = { 1, 1, 7, 5, 25, 43, 25, 165, 135, 789, 891, 1711, 711, 269, 17895, 0 }; + static ulong[] dim3033Kuo3Init = { 1, 3, 1, 3, 27, 57, 63, 89, 33, 897, 691, 3129, 7253, 2041, 14341, 0 }; + static ulong[] dim3034Kuo3Init = { 1, 1, 1, 1, 5, 25, 21, 65, 383, 687, 57, 2267, 1837, 7091, 5941, 0 }; + static ulong[] dim3035Kuo3Init = { 1, 3, 7, 13, 9, 37, 75, 113, 243, 419, 387, 3479, 3295, 3659, 29215, 0 }; + static ulong[] dim3036Kuo3Init = { 1, 1, 1, 13, 1, 39, 97, 237, 509, 51, 1239, 1889, 915, 15313, 3487, 0 }; + static ulong[] dim3037Kuo3Init = { 1, 1, 3, 1, 1, 5, 81, 153, 83, 977, 1667, 571, 1161, 9347, 32353, 0 }; + static ulong[] dim3038Kuo3Init = { 1, 1, 7, 5, 11, 13, 45, 91, 265, 815, 1141, 1187, 41, 15723, 5573, 0 }; + static ulong[] dim3039Kuo3Init = { 1, 1, 7, 13, 31, 29, 27, 23, 163, 605, 1457, 37, 2075, 4581, 10571, 0 }; + static ulong[] dim3040Kuo3Init = { 1, 1, 1, 11, 13, 31, 119, 241, 379, 427, 333, 1299, 3303, 13049, 15233, 0 }; + static ulong[] dim3041Kuo3Init = { 1, 3, 7, 13, 23, 35, 69, 195, 149, 273, 41, 289, 3173, 13177, 10865, 0 }; + static ulong[] dim3042Kuo3Init = { 1, 3, 3, 7, 1, 5, 85, 245, 417, 887, 1821, 3623, 1591, 15871, 10837, 0 }; + static ulong[] dim3043Kuo3Init = { 1, 1, 3, 13, 19, 55, 11, 65, 227, 273, 1065, 1937, 5197, 7695, 24827, 0 }; + static ulong[] dim3044Kuo3Init = { 1, 1, 3, 15, 11, 55, 11, 49, 141, 607, 509, 3785, 8009, 4127, 4757, 0 }; + static ulong[] dim3045Kuo3Init = { 1, 1, 3, 11, 31, 23, 33, 241, 347, 261, 1609, 3177, 4065, 13767, 24607, 0 }; + static ulong[] dim3046Kuo3Init = { 1, 3, 7, 13, 13, 7, 73, 63, 493, 607, 869, 1599, 7725, 2405, 12945, 0 }; + static ulong[] dim3047Kuo3Init = { 1, 3, 1, 9, 9, 57, 85, 173, 259, 749, 1661, 2911, 7833, 7577, 21209, 0 }; + static ulong[] dim3048Kuo3Init = { 1, 3, 5, 7, 7, 27, 61, 91, 417, 369, 1181, 1385, 2991, 12503, 13073, 0 }; + static ulong[] dim3049Kuo3Init = { 1, 3, 5, 13, 17, 11, 51, 101, 45, 45, 1247, 4069, 3079, 9081, 12443, 0 }; + static ulong[] dim3050Kuo3Init = { 1, 1, 3, 7, 13, 57, 63, 43, 451, 743, 1045, 2967, 6437, 93, 4589, 0 }; + static ulong[] dim3051Kuo3Init = { 1, 3, 7, 3, 25, 17, 113, 89, 457, 261, 827, 197, 7177, 4135, 19733, 0 }; + static ulong[] dim3052Kuo3Init = { 1, 3, 5, 9, 23, 59, 29, 207, 19, 623, 101, 1675, 579, 3255, 16259, 0 }; + static ulong[] dim3053Kuo3Init = { 1, 1, 1, 1, 21, 23, 103, 123, 61, 233, 71, 897, 6147, 3335, 1027, 0 }; + static ulong[] dim3054Kuo3Init = { 1, 3, 5, 13, 9, 11, 101, 55, 247, 285, 1387, 2063, 6853, 409, 10715, 0 }; + static ulong[] dim3055Kuo3Init = { 1, 1, 7, 7, 11, 41, 5, 157, 325, 975, 1403, 3187, 4107, 4093, 18165, 0 }; + static ulong[] dim3056Kuo3Init = { 1, 3, 1, 3, 25, 15, 69, 93, 87, 711, 1699, 733, 7703, 2191, 12293, 0 }; + static ulong[] dim3057Kuo3Init = { 1, 3, 3, 1, 21, 41, 31, 229, 325, 507, 2019, 2225, 1733, 4447, 32477, 0 }; + static ulong[] dim3058Kuo3Init = { 1, 3, 1, 5, 23, 41, 19, 1, 467, 315, 1513, 1671, 4159, 12477, 6199, 0 }; + static ulong[] dim3059Kuo3Init = { 1, 1, 1, 11, 27, 61, 35, 115, 215, 979, 1887, 1913, 689, 3847, 11451, 0 }; + static ulong[] dim3060Kuo3Init = { 1, 3, 3, 7, 25, 29, 65, 233, 433, 113, 1031, 2455, 6743, 5227, 7207, 0 }; + static ulong[] dim3061Kuo3Init = { 1, 1, 3, 9, 5, 9, 85, 103, 185, 699, 663, 441, 8013, 1227, 12875, 0 }; + static ulong[] dim3062Kuo3Init = { 1, 3, 5, 11, 9, 59, 35, 223, 131, 409, 125, 3437, 2015, 217, 16351, 0 }; + static ulong[] dim3063Kuo3Init = { 1, 3, 7, 3, 9, 27, 43, 211, 365, 855, 1249, 3127, 3611, 9339, 16083, 0 }; + static ulong[] dim3064Kuo3Init = { 1, 1, 1, 9, 29, 11, 61, 27, 195, 963, 1905, 1679, 1811, 7, 27243, 0 }; + static ulong[] dim3065Kuo3Init = { 1, 3, 7, 15, 3, 41, 21, 31, 461, 3, 1033, 459, 1831, 12289, 19645, 0 }; + static ulong[] dim3066Kuo3Init = { 1, 1, 7, 7, 15, 7, 25, 207, 37, 177, 973, 3207, 5329, 8541, 7929, 0 }; + static ulong[] dim3067Kuo3Init = { 1, 1, 5, 1, 29, 35, 77, 251, 429, 681, 391, 3789, 5953, 13339, 16991, 0 }; + static ulong[] dim3068Kuo3Init = { 1, 1, 5, 5, 5, 39, 21, 131, 511, 11, 921, 3073, 3239, 561, 28595, 0 }; + static ulong[] dim3069Kuo3Init = { 1, 3, 1, 11, 3, 11, 71, 231, 439, 523, 209, 3213, 211, 13449, 23311, 0 }; + static ulong[] dim3070Kuo3Init = { 1, 1, 1, 5, 31, 27, 59, 161, 71, 619, 1643, 3687, 753, 7443, 25743, 0 }; + static ulong[] dim3071Kuo3Init = { 1, 3, 7, 11, 13, 49, 33, 223, 443, 463, 1833, 3757, 299, 9633, 16339, 0 }; + static ulong[] dim3072Kuo3Init = { 1, 3, 7, 1, 21, 57, 63, 31, 491, 53, 75, 3059, 3013, 965, 6209, 0 }; + static ulong[] dim3073Kuo3Init = { 1, 1, 5, 9, 3, 45, 63, 25, 511, 501, 1003, 1499, 887, 5583, 6329, 0 }; + static ulong[] dim3074Kuo3Init = { 1, 3, 1, 1, 9, 11, 49, 225, 511, 563, 495, 1697, 7943, 13561, 16159, 0 }; + static ulong[] dim3075Kuo3Init = { 1, 3, 7, 9, 11, 1, 95, 255, 437, 979, 1669, 179, 2189, 14431, 23919, 0 }; + static ulong[] dim3076Kuo3Init = { 1, 3, 1, 13, 13, 5, 23, 233, 327, 903, 167, 797, 5205, 2203, 22137, 0 }; + static ulong[] dim3077Kuo3Init = { 1, 1, 7, 11, 25, 63, 43, 113, 251, 39, 163, 1631, 2731, 12241, 32567, 0 }; + static ulong[] dim3078Kuo3Init = { 1, 1, 5, 11, 3, 35, 9, 21, 477, 139, 1107, 1975, 6883, 6651, 20847, 0 }; + static ulong[] dim3079Kuo3Init = { 1, 3, 5, 13, 25, 39, 89, 217, 95, 457, 1741, 2725, 5391, 13381, 2411, 0 }; + static ulong[] dim3080Kuo3Init = { 1, 3, 5, 5, 1, 27, 9, 51, 3, 915, 1803, 931, 7651, 6497, 6635, 0 }; + static ulong[] dim3081Kuo3Init = { 1, 3, 7, 9, 21, 53, 9, 151, 155, 827, 453, 4071, 3153, 2711, 25143, 0 }; + static ulong[] dim3082Kuo3Init = { 1, 1, 3, 7, 21, 15, 5, 169, 27, 479, 911, 3949, 2819, 387, 2919, 0 }; + static ulong[] dim3083Kuo3Init = { 1, 1, 3, 3, 27, 59, 27, 225, 507, 403, 1333, 747, 7731, 13007, 16283, 0 }; + static ulong[] dim3084Kuo3Init = { 1, 1, 3, 13, 29, 11, 65, 169, 197, 209, 1703, 3503, 2661, 14703, 28529, 0 }; + static ulong[] dim3085Kuo3Init = { 1, 1, 3, 13, 17, 63, 73, 11, 495, 603, 687, 2773, 3955, 12761, 13899, 0 }; + static ulong[] dim3086Kuo3Init = { 1, 1, 1, 11, 7, 31, 55, 133, 197, 619, 1747, 3531, 1157, 7143, 19347, 0 }; + static ulong[] dim3087Kuo3Init = { 1, 3, 1, 13, 15, 47, 5, 117, 329, 169, 2023, 901, 397, 15681, 8931, 0 }; + static ulong[] dim3088Kuo3Init = { 1, 1, 5, 1, 29, 5, 79, 73, 463, 125, 1539, 2149, 4353, 15123, 27853, 0 }; + static ulong[] dim3089Kuo3Init = { 1, 1, 5, 7, 13, 55, 59, 151, 105, 79, 1023, 1839, 3889, 3843, 6129, 0 }; + static ulong[] dim3090Kuo3Init = { 1, 1, 3, 15, 9, 15, 109, 63, 95, 573, 385, 3773, 535, 11307, 4719, 0 }; + static ulong[] dim3091Kuo3Init = { 1, 3, 7, 11, 9, 9, 91, 245, 403, 841, 1771, 2121, 6927, 1029, 26767, 0 }; + static ulong[] dim3092Kuo3Init = { 1, 3, 1, 11, 25, 55, 21, 173, 327, 327, 1747, 1771, 6829, 12155, 29375, 0 }; + static ulong[] dim3093Kuo3Init = { 1, 3, 7, 11, 17, 15, 31, 189, 179, 849, 1895, 3333, 7385, 4473, 18003, 0 }; + static ulong[] dim3094Kuo3Init = { 1, 1, 7, 3, 29, 37, 11, 81, 181, 197, 1231, 167, 6611, 3437, 8857, 0 }; + static ulong[] dim3095Kuo3Init = { 1, 3, 3, 15, 17, 53, 63, 51, 497, 725, 917, 2661, 2013, 10887, 29145, 0 }; + static ulong[] dim3096Kuo3Init = { 1, 1, 3, 11, 15, 53, 75, 209, 429, 927, 1867, 677, 5305, 15901, 5079, 0 }; + static ulong[] dim3097Kuo3Init = { 1, 1, 1, 5, 19, 57, 105, 169, 113, 701, 1123, 2203, 285, 12447, 18301, 0 }; + static ulong[] dim3098Kuo3Init = { 1, 3, 1, 7, 25, 53, 51, 35, 245, 173, 1047, 1905, 1773, 10699, 32057, 0 }; + static ulong[] dim3099Kuo3Init = { 1, 1, 1, 7, 31, 33, 15, 233, 105, 943, 201, 2681, 3121, 14145, 23741, 0 }; + static ulong[] dim3100Kuo3Init = { 1, 1, 1, 1, 27, 61, 121, 199, 437, 717, 1481, 2421, 6681, 2457, 4411, 0 }; + static ulong[] dim3101Kuo3Init = { 1, 1, 1, 13, 31, 9, 93, 149, 379, 639, 1889, 1385, 3513, 10105, 13933, 0 }; + static ulong[] dim3102Kuo3Init = { 1, 1, 7, 7, 9, 37, 41, 221, 323, 989, 445, 3083, 6855, 11577, 29849, 0 }; + static ulong[] dim3103Kuo3Init = { 1, 1, 7, 7, 27, 55, 53, 171, 87, 529, 1555, 2065, 1685, 1953, 20561, 0 }; + static ulong[] dim3104Kuo3Init = { 1, 3, 7, 13, 1, 15, 11, 91, 81, 217, 7, 1687, 493, 13345, 14009, 0 }; + static ulong[] dim3105Kuo3Init = { 1, 3, 1, 9, 5, 31, 89, 33, 39, 747, 753, 2193, 1937, 9685, 17689, 0 }; + static ulong[] dim3106Kuo3Init = { 1, 1, 3, 7, 13, 61, 101, 89, 305, 123, 1773, 411, 595, 10113, 4725, 0 }; + static ulong[] dim3107Kuo3Init = { 1, 1, 3, 15, 3, 13, 25, 205, 343, 869, 115, 2413, 4531, 13185, 15699, 0 }; + static ulong[] dim3108Kuo3Init = { 1, 3, 5, 3, 25, 37, 71, 125, 85, 995, 769, 2737, 2495, 7571, 26825, 0 }; + static ulong[] dim3109Kuo3Init = { 1, 3, 3, 11, 21, 3, 109, 175, 479, 605, 569, 2753, 2927, 10529, 28345, 0 }; + static ulong[] dim3110Kuo3Init = { 1, 3, 7, 1, 5, 57, 75, 79, 383, 637, 1411, 3955, 5535, 9403, 10463, 0 }; + static ulong[] dim3111Kuo3Init = { 1, 1, 7, 5, 27, 25, 67, 35, 95, 25, 1585, 1725, 7003, 2261, 3575, 0 }; + static ulong[] dim3112Kuo3Init = { 1, 3, 7, 13, 11, 11, 85, 141, 389, 903, 995, 2625, 7163, 7229, 18205, 0 }; + static ulong[] dim3113Kuo3Init = { 1, 1, 3, 5, 3, 53, 69, 141, 213, 675, 1799, 235, 3433, 2305, 29607, 0 }; + static ulong[] dim3114Kuo3Init = { 1, 1, 7, 5, 21, 45, 119, 229, 493, 691, 1551, 3801, 663, 9693, 5255, 0 }; + static ulong[] dim3115Kuo3Init = { 1, 3, 7, 11, 11, 37, 69, 65, 163, 61, 1567, 1879, 1853, 11099, 4523, 0 }; + static ulong[] dim3116Kuo3Init = { 1, 1, 3, 9, 5, 43, 75, 93, 81, 555, 803, 129, 4391, 3025, 1013, 0 }; + static ulong[] dim3117Kuo3Init = { 1, 1, 5, 5, 9, 49, 69, 185, 441, 567, 203, 2641, 4169, 15585, 10963, 0 }; + static ulong[] dim3118Kuo3Init = { 1, 3, 7, 9, 9, 35, 121, 117, 509, 93, 1381, 1329, 751, 2351, 11079, 0 }; + static ulong[] dim3119Kuo3Init = { 1, 3, 5, 15, 5, 61, 117, 83, 383, 961, 779, 1499, 4695, 3679, 20383, 0 }; + static ulong[] dim3120Kuo3Init = { 1, 3, 5, 5, 21, 63, 105, 15, 297, 923, 1867, 1667, 3523, 12387, 14977, 0 }; + static ulong[] dim3121Kuo3Init = { 1, 1, 5, 5, 7, 37, 123, 161, 343, 959, 1807, 1695, 6121, 8415, 5373, 0 }; + static ulong[] dim3122Kuo3Init = { 1, 3, 5, 15, 29, 51, 107, 151, 5, 715, 3, 3005, 1917, 12243, 13903, 0 }; + static ulong[] dim3123Kuo3Init = { 1, 3, 5, 11, 25, 29, 125, 165, 57, 729, 1187, 2273, 2869, 13149, 2831, 0 }; + static ulong[] dim3124Kuo3Init = { 1, 1, 7, 15, 1, 15, 37, 15, 489, 879, 89, 2399, 547, 1959, 20073, 0 }; + static ulong[] dim3125Kuo3Init = { 1, 3, 5, 13, 5, 43, 101, 27, 425, 531, 1681, 3301, 5741, 7005, 6607, 0 }; + static ulong[] dim3126Kuo3Init = { 1, 1, 3, 13, 17, 53, 61, 165, 375, 7, 761, 1891, 1253, 2431, 15273, 0 }; + static ulong[] dim3127Kuo3Init = { 1, 1, 1, 5, 13, 23, 27, 229, 215, 729, 9, 779, 3583, 9109, 19059, 0 }; + static ulong[] dim3128Kuo3Init = { 1, 1, 3, 9, 3, 45, 99, 193, 203, 57, 147, 3953, 5263, 14641, 24729, 0 }; + static ulong[] dim3129Kuo3Init = { 1, 3, 7, 3, 11, 49, 57, 121, 413, 293, 1251, 3791, 1803, 12549, 3743, 0 }; + static ulong[] dim3130Kuo3Init = { 1, 3, 7, 13, 19, 55, 85, 1, 169, 539, 1565, 2157, 4493, 9169, 27583, 0 }; + static ulong[] dim3131Kuo3Init = { 1, 1, 7, 7, 19, 59, 95, 171, 471, 881, 663, 1489, 8013, 8981, 11443, 0 }; + static ulong[] dim3132Kuo3Init = { 1, 1, 3, 7, 17, 59, 25, 115, 439, 967, 1939, 905, 4141, 4177, 24827, 0 }; + static ulong[] dim3133Kuo3Init = { 1, 3, 5, 3, 29, 17, 23, 241, 49, 815, 1409, 3997, 1073, 2331, 455, 0 }; + static ulong[] dim3134Kuo3Init = { 1, 1, 5, 13, 27, 53, 51, 67, 405, 853, 1229, 2647, 4817, 521, 14343, 0 }; + static ulong[] dim3135Kuo3Init = { 1, 3, 3, 13, 1, 55, 83, 15, 41, 327, 1501, 1967, 5787, 3557, 7461, 0 }; + static ulong[] dim3136Kuo3Init = { 1, 3, 5, 1, 23, 43, 93, 179, 373, 173, 1625, 487, 6973, 12479, 24659, 0 }; + static ulong[] dim3137Kuo3Init = { 1, 3, 7, 15, 3, 27, 9, 69, 501, 287, 945, 681, 3667, 7499, 24259, 0 }; + static ulong[] dim3138Kuo3Init = { 1, 3, 7, 3, 21, 55, 55, 13, 191, 25, 1339, 185, 4345, 13649, 17793, 0 }; + static ulong[] dim3139Kuo3Init = { 1, 3, 3, 1, 9, 13, 95, 127, 305, 961, 141, 3071, 683, 2141, 13757, 0 }; + static ulong[] dim3140Kuo3Init = { 1, 1, 5, 5, 21, 59, 83, 39, 137, 259, 689, 339, 105, 147, 26143, 0 }; + static ulong[] dim3141Kuo3Init = { 1, 1, 5, 7, 31, 21, 121, 45, 103, 507, 1243, 3325, 441, 6743, 31937, 0 }; + static ulong[] dim3142Kuo3Init = { 1, 1, 5, 3, 7, 35, 5, 117, 433, 47, 261, 2405, 3361, 4361, 14397, 0 }; + static ulong[] dim3143Kuo3Init = { 1, 3, 7, 9, 19, 7, 19, 129, 79, 247, 35, 1483, 285, 4923, 14255, 0 }; + static ulong[] dim3144Kuo3Init = { 1, 3, 3, 11, 13, 3, 117, 169, 3, 527, 1295, 295, 2317, 5391, 27073, 0 }; + static ulong[] dim3145Kuo3Init = { 1, 1, 7, 3, 3, 53, 9, 175, 157, 917, 1297, 1917, 5575, 16183, 20165, 0 }; + static ulong[] dim3146Kuo3Init = { 1, 3, 3, 9, 25, 47, 61, 71, 129, 923, 367, 1623, 4281, 11241, 14759, 0 }; + static ulong[] dim3147Kuo3Init = { 1, 3, 7, 11, 23, 29, 53, 135, 381, 943, 1611, 1609, 5897, 393, 24647, 0 }; + static ulong[] dim3148Kuo3Init = { 1, 1, 7, 1, 3, 55, 5, 191, 305, 385, 1383, 913, 1017, 6463, 32323, 0 }; + static ulong[] dim3149Kuo3Init = { 1, 1, 5, 9, 3, 57, 113, 189, 41, 413, 1685, 2145, 6071, 7229, 11413, 0 }; + static ulong[] dim3150Kuo3Init = { 1, 3, 3, 9, 21, 5, 95, 87, 247, 175, 1265, 83, 511, 2821, 9881, 0 }; + static ulong[] dim3151Kuo3Init = { 1, 3, 1, 3, 31, 41, 127, 115, 457, 809, 2017, 3979, 3425, 159, 15903, 0 }; + static ulong[] dim3152Kuo3Init = { 1, 1, 7, 7, 29, 9, 85, 109, 299, 607, 1991, 3717, 4593, 8529, 10759, 0 }; + static ulong[] dim3153Kuo3Init = { 1, 3, 1, 9, 15, 49, 123, 61, 49, 413, 1599, 3697, 2481, 739, 1641, 0 }; + static ulong[] dim3154Kuo3Init = { 1, 3, 3, 1, 13, 55, 35, 217, 79, 167, 1215, 2687, 7303, 10331, 29985, 0 }; + static ulong[] dim3155Kuo3Init = { 1, 1, 1, 9, 29, 29, 37, 177, 63, 515, 1551, 1053, 893, 6831, 18039, 0 }; + static ulong[] dim3156Kuo3Init = { 1, 1, 7, 5, 25, 47, 57, 209, 345, 805, 999, 307, 3465, 13411, 17721, 0 }; + static ulong[] dim3157Kuo3Init = { 1, 1, 5, 11, 3, 63, 95, 243, 163, 923, 1181, 3319, 5903, 8195, 21217, 0 }; + static ulong[] dim3158Kuo3Init = { 1, 3, 7, 11, 15, 51, 75, 237, 25, 907, 395, 3721, 3371, 12425, 3795, 0 }; + static ulong[] dim3159Kuo3Init = { 1, 1, 1, 11, 15, 61, 127, 39, 359, 381, 1879, 2605, 7511, 4329, 28251, 0 }; + static ulong[] dim3160Kuo3Init = { 1, 3, 5, 9, 11, 61, 1, 215, 503, 939, 419, 3353, 3013, 5391, 12567, 0 }; + static ulong[] dim3161Kuo3Init = { 1, 3, 1, 9, 7, 57, 123, 5, 473, 931, 759, 571, 2407, 13057, 7443, 0 }; + static ulong[] dim3162Kuo3Init = { 1, 1, 3, 7, 31, 17, 55, 181, 359, 913, 271, 935, 5911, 9767, 23, 0 }; + static ulong[] dim3163Kuo3Init = { 1, 1, 1, 15, 1, 35, 93, 233, 109, 135, 1793, 2453, 6547, 15435, 16227, 0 }; + static ulong[] dim3164Kuo3Init = { 1, 3, 1, 13, 5, 37, 87, 51, 165, 455, 621, 881, 2377, 7977, 29763, 0 }; + static ulong[] dim3165Kuo3Init = { 1, 1, 3, 13, 31, 3, 119, 113, 141, 179, 621, 677, 1047, 2405, 28777, 0 }; + static ulong[] dim3166Kuo3Init = { 1, 3, 1, 1, 11, 25, 37, 15, 117, 509, 853, 747, 3065, 11569, 11731, 0 }; + static ulong[] dim3167Kuo3Init = { 1, 1, 5, 11, 31, 9, 27, 219, 71, 919, 1553, 3067, 6315, 17, 18511, 0 }; + static ulong[] dim3168Kuo3Init = { 1, 1, 7, 1, 27, 39, 111, 127, 315, 671, 845, 179, 8129, 15409, 21565, 0 }; + static ulong[] dim3169Kuo3Init = { 1, 1, 5, 13, 31, 37, 105, 67, 37, 725, 1947, 2743, 6241, 5465, 15025, 0 }; + static ulong[] dim3170Kuo3Init = { 1, 1, 7, 13, 7, 63, 63, 209, 431, 171, 845, 2067, 4829, 5627, 32333, 0 }; + static ulong[] dim3171Kuo3Init = { 1, 3, 7, 15, 7, 61, 105, 35, 113, 551, 1227, 867, 5907, 4389, 13281, 0 }; + static ulong[] dim3172Kuo3Init = { 1, 1, 1, 13, 31, 13, 123, 255, 497, 365, 921, 2009, 5365, 15443, 23455, 0 }; + static ulong[] dim3173Kuo3Init = { 1, 1, 5, 15, 5, 45, 91, 199, 417, 557, 827, 1911, 4173, 8705, 19437, 0 }; + static ulong[] dim3174Kuo3Init = { 1, 3, 3, 9, 31, 51, 69, 247, 407, 791, 1811, 1127, 6775, 8343, 19723, 0 }; + static ulong[] dim3175Kuo3Init = { 1, 3, 3, 3, 21, 43, 71, 191, 339, 219, 1809, 3735, 151, 3743, 11803, 0 }; + static ulong[] dim3176Kuo3Init = { 1, 1, 7, 3, 13, 21, 1, 233, 395, 335, 1929, 547, 2939, 9205, 22309, 0 }; + static ulong[] dim3177Kuo3Init = { 1, 1, 1, 13, 7, 5, 97, 189, 195, 191, 833, 269, 3255, 15301, 11593, 0 }; + static ulong[] dim3178Kuo3Init = { 1, 1, 3, 1, 31, 35, 53, 193, 143, 241, 763, 3221, 3217, 14915, 5603, 0 }; + static ulong[] dim3179Kuo3Init = { 1, 3, 5, 15, 3, 15, 47, 171, 349, 995, 1803, 2123, 8009, 10339, 1827, 0 }; + static ulong[] dim3180Kuo3Init = { 1, 1, 1, 3, 11, 37, 125, 149, 261, 507, 1603, 683, 137, 353, 26313, 0 }; + static ulong[] dim3181Kuo3Init = { 1, 3, 3, 11, 5, 19, 7, 97, 257, 439, 825, 265, 2493, 5567, 8575, 0 }; + static ulong[] dim3182Kuo3Init = { 1, 1, 5, 5, 9, 25, 101, 207, 345, 823, 1787, 2449, 4377, 10581, 19169, 0 }; + static ulong[] dim3183Kuo3Init = { 1, 3, 1, 9, 19, 5, 15, 19, 405, 665, 715, 3743, 23, 5061, 21145, 0 }; + static ulong[] dim3184Kuo3Init = { 1, 1, 3, 9, 11, 7, 73, 39, 77, 763, 1251, 3533, 6379, 16101, 8719, 0 }; + static ulong[] dim3185Kuo3Init = { 1, 3, 3, 1, 15, 55, 89, 249, 475, 641, 511, 111, 5797, 5627, 2187, 0 }; + static ulong[] dim3186Kuo3Init = { 1, 1, 5, 5, 7, 27, 117, 153, 387, 295, 309, 3293, 5197, 8359, 16643, 0 }; + static ulong[] dim3187Kuo3Init = { 1, 3, 3, 3, 5, 35, 45, 159, 495, 311, 463, 1249, 5163, 7939, 21405, 0 }; + static ulong[] dim3188Kuo3Init = { 1, 3, 3, 7, 31, 39, 125, 167, 43, 41, 589, 3329, 5511, 7983, 17329, 0 }; + static ulong[] dim3189Kuo3Init = { 1, 1, 3, 13, 1, 17, 43, 95, 465, 587, 1189, 2629, 7613, 15115, 22299, 0 }; + static ulong[] dim3190Kuo3Init = { 1, 3, 1, 9, 21, 57, 73, 241, 149, 531, 827, 731, 7431, 14375, 16307, 0 }; + static ulong[] dim3191Kuo3Init = { 1, 1, 1, 7, 7, 25, 113, 115, 381, 951, 811, 305, 935, 2927, 18755, 0 }; + static ulong[] dim3192Kuo3Init = { 1, 3, 5, 13, 11, 53, 91, 197, 497, 9, 1009, 25, 2473, 2467, 8827, 0 }; + static ulong[] dim3193Kuo3Init = { 1, 3, 3, 7, 23, 23, 15, 3, 131, 591, 379, 1227, 3479, 8409, 20177, 0 }; + static ulong[] dim3194Kuo3Init = { 1, 3, 5, 9, 17, 47, 91, 107, 17, 175, 1181, 2097, 457, 10253, 24291, 0 }; + static ulong[] dim3195Kuo3Init = { 1, 1, 3, 5, 31, 57, 25, 117, 97, 707, 1875, 4059, 6997, 3533, 27781, 0 }; + static ulong[] dim3196Kuo3Init = { 1, 1, 7, 11, 7, 7, 53, 137, 255, 1017, 501, 847, 4569, 3665, 21377, 0 }; + static ulong[] dim3197Kuo3Init = { 1, 1, 3, 9, 19, 57, 39, 213, 67, 221, 149, 357, 1137, 12625, 13945, 0 }; + static ulong[] dim3198Kuo3Init = { 1, 1, 7, 11, 19, 53, 75, 67, 71, 811, 837, 3399, 3993, 3119, 13459, 0 }; + static ulong[] dim3199Kuo3Init = { 1, 1, 1, 3, 29, 7, 77, 249, 97, 159, 1097, 161, 1649, 4663, 8635, 0 }; + static ulong[] dim3200Kuo3Init = { 1, 1, 5, 9, 9, 11, 69, 151, 419, 11, 1457, 2357, 7259, 4059, 6189, 0 }; + static ulong[] dim3201Kuo3Init = { 1, 3, 5, 7, 29, 1, 109, 103, 129, 561, 1629, 237, 643, 14519, 22839, 0 }; + static ulong[] dim3202Kuo3Init = { 1, 3, 3, 15, 17, 25, 109, 213, 253, 427, 849, 4053, 3845, 8935, 21233, 0 }; + static ulong[] dim3203Kuo3Init = { 1, 3, 1, 3, 15, 53, 81, 127, 131, 523, 1303, 451, 3363, 14105, 28881, 0 }; + static ulong[] dim3204Kuo3Init = { 1, 1, 1, 13, 1, 29, 105, 75, 235, 407, 1555, 1247, 2329, 1259, 8653, 0 }; + static ulong[] dim3205Kuo3Init = { 1, 1, 1, 3, 31, 45, 9, 199, 315, 375, 205, 3157, 4247, 11961, 4039, 0 }; + static ulong[] dim3206Kuo3Init = { 1, 3, 3, 5, 3, 39, 13, 125, 103, 359, 287, 3529, 2015, 3187, 26261, 0 }; + static ulong[] dim3207Kuo3Init = { 1, 3, 3, 7, 3, 63, 81, 157, 169, 1005, 889, 2271, 7773, 8739, 11171, 0 }; + static ulong[] dim3208Kuo3Init = { 1, 1, 1, 3, 11, 63, 61, 67, 1, 919, 349, 1645, 8155, 219, 357, 0 }; + static ulong[] dim3209Kuo3Init = { 1, 3, 7, 9, 17, 39, 1, 253, 497, 409, 631, 1425, 7763, 3239, 5405, 0 }; + static ulong[] dim3210Kuo3Init = { 1, 3, 3, 3, 21, 57, 97, 231, 445, 417, 1567, 739, 6413, 13499, 16947, 0 }; + static ulong[] dim3211Kuo3Init = { 1, 1, 1, 3, 13, 59, 17, 15, 75, 197, 267, 1295, 3867, 6607, 31623, 0 }; + static ulong[] dim3212Kuo3Init = { 1, 1, 3, 5, 27, 1, 83, 97, 381, 931, 1133, 4091, 341, 7105, 28761, 0 }; + static ulong[] dim3213Kuo3Init = { 1, 3, 3, 11, 3, 39, 49, 237, 437, 353, 321, 3609, 4555, 8987, 28727, 0 }; + static ulong[] dim3214Kuo3Init = { 1, 3, 1, 13, 15, 49, 101, 255, 409, 231, 355, 2333, 7277, 2549, 1613, 0 }; + static ulong[] dim3215Kuo3Init = { 1, 3, 3, 13, 11, 49, 99, 201, 57, 705, 413, 2791, 5947, 8533, 22155, 0 }; + static ulong[] dim3216Kuo3Init = { 1, 3, 1, 15, 13, 51, 91, 47, 165, 995, 1293, 3601, 5841, 4671, 27379, 0 }; + static ulong[] dim3217Kuo3Init = { 1, 1, 3, 11, 15, 47, 43, 97, 151, 75, 1229, 2525, 5085, 10969, 5195, 0 }; + static ulong[] dim3218Kuo3Init = { 1, 1, 5, 3, 7, 15, 65, 161, 423, 773, 291, 1081, 2127, 15861, 16051, 0 }; + static ulong[] dim3219Kuo3Init = { 1, 3, 1, 1, 11, 47, 47, 157, 369, 889, 221, 83, 3165, 12911, 20687, 0 }; + static ulong[] dim3220Kuo3Init = { 1, 1, 1, 9, 23, 63, 97, 191, 185, 863, 1611, 241, 4177, 14965, 22205, 0 }; + static ulong[] dim3221Kuo3Init = { 1, 3, 3, 15, 13, 11, 85, 109, 13, 401, 1365, 2637, 2119, 14673, 28813, 0 }; + static ulong[] dim3222Kuo3Init = { 1, 1, 5, 7, 23, 13, 11, 9, 105, 891, 1511, 3969, 2097, 2089, 18535, 0 }; + static ulong[] dim3223Kuo3Init = { 1, 1, 3, 15, 3, 23, 67, 197, 309, 883, 1635, 359, 5023, 10693, 28537, 0 }; + static ulong[] dim3224Kuo3Init = { 1, 1, 3, 1, 1, 25, 63, 233, 445, 665, 1971, 1713, 1827, 14269, 19539, 0 }; + static ulong[] dim3225Kuo3Init = { 1, 3, 3, 13, 25, 27, 79, 131, 441, 465, 613, 2027, 2521, 11109, 14443, 0 }; + static ulong[] dim3226Kuo3Init = { 1, 3, 5, 13, 27, 1, 27, 123, 405, 567, 159, 2319, 5625, 4643, 1185, 0 }; + static ulong[] dim3227Kuo3Init = { 1, 1, 7, 15, 15, 55, 21, 105, 353, 431, 955, 3341, 2891, 13667, 17787, 0 }; + static ulong[] dim3228Kuo3Init = { 1, 1, 1, 5, 25, 61, 11, 251, 459, 985, 1285, 811, 4279, 4579, 14313, 0 }; + static ulong[] dim3229Kuo3Init = { 1, 1, 3, 15, 13, 1, 63, 103, 113, 91, 1241, 2513, 767, 9037, 29591, 0 }; + static ulong[] dim3230Kuo3Init = { 1, 3, 7, 15, 31, 39, 87, 215, 421, 875, 913, 3593, 2215, 4889, 14595, 0 }; + static ulong[] dim3231Kuo3Init = { 1, 3, 3, 3, 17, 61, 99, 13, 475, 331, 541, 2363, 5697, 14867, 11483, 0 }; + static ulong[] dim3232Kuo3Init = { 1, 1, 5, 3, 17, 15, 7, 217, 219, 327, 1775, 939, 3953, 2393, 28241, 0 }; + static ulong[] dim3233Kuo3Init = { 1, 1, 3, 3, 11, 57, 75, 139, 123, 607, 87, 539, 4955, 6533, 31827, 0 }; + static ulong[] dim3234Kuo3Init = { 1, 3, 3, 15, 15, 15, 43, 127, 485, 1009, 1201, 919, 761, 385, 29889, 0 }; + static ulong[] dim3235Kuo3Init = { 1, 3, 1, 3, 3, 53, 47, 101, 463, 899, 523, 1009, 3541, 11191, 2257, 0 }; + static ulong[] dim3236Kuo3Init = { 1, 1, 1, 3, 31, 43, 9, 39, 201, 469, 839, 2509, 5645, 2861, 25533, 0 }; + static ulong[] dim3237Kuo3Init = { 1, 3, 5, 7, 19, 27, 69, 45, 367, 267, 953, 3711, 603, 3511, 13419, 0 }; + static ulong[] dim3238Kuo3Init = { 1, 1, 3, 1, 25, 39, 33, 89, 459, 573, 1643, 3291, 2371, 1749, 20693, 0 }; + static ulong[] dim3239Kuo3Init = { 1, 1, 1, 13, 11, 29, 103, 213, 13, 219, 2023, 1327, 4315, 13933, 19559, 0 }; + static ulong[] dim3240Kuo3Init = { 1, 1, 5, 3, 17, 49, 11, 241, 227, 157, 745, 1377, 5739, 14285, 26107, 0 }; + static ulong[] dim3241Kuo3Init = { 1, 1, 7, 3, 23, 11, 5, 213, 405, 415, 1911, 3763, 3403, 16079, 10957, 0 }; + static ulong[] dim3242Kuo3Init = { 1, 3, 5, 15, 31, 27, 79, 153, 403, 747, 269, 4039, 2791, 4711, 501, 0 }; + static ulong[] dim3243Kuo3Init = { 1, 1, 7, 15, 1, 29, 105, 29, 131, 913, 265, 871, 2899, 11547, 20351, 0 }; + static ulong[] dim3244Kuo3Init = { 1, 1, 1, 3, 9, 47, 55, 121, 487, 349, 233, 1657, 3015, 12345, 2213, 0 }; + static ulong[] dim3245Kuo3Init = { 1, 1, 7, 9, 1, 45, 49, 241, 81, 673, 1933, 3203, 7433, 14745, 5811, 0 }; + static ulong[] dim3246Kuo3Init = { 1, 1, 7, 5, 31, 31, 97, 97, 377, 795, 417, 3851, 4725, 9803, 16785, 0 }; + static ulong[] dim3247Kuo3Init = { 1, 3, 1, 1, 9, 5, 45, 141, 361, 523, 297, 2535, 4433, 16353, 28191, 0 }; + static ulong[] dim3248Kuo3Init = { 1, 3, 3, 7, 9, 29, 47, 19, 419, 49, 825, 1771, 5439, 8611, 12659, 0 }; + static ulong[] dim3249Kuo3Init = { 1, 1, 1, 9, 19, 3, 89, 107, 407, 567, 807, 623, 7915, 8083, 6761, 0 }; + static ulong[] dim3250Kuo3Init = { 1, 1, 5, 3, 23, 35, 109, 23, 461, 401, 713, 965, 7687, 9729, 17287, 0 }; + static ulong[] dim3251Kuo3Init = { 1, 3, 5, 11, 11, 43, 79, 197, 249, 423, 953, 1621, 4045, 3913, 11143, 0 }; + static ulong[] dim3252Kuo3Init = { 1, 1, 3, 7, 19, 59, 91, 217, 481, 861, 1915, 1689, 2061, 5377, 8535, 0 }; + static ulong[] dim3253Kuo3Init = { 1, 3, 3, 9, 15, 57, 5, 81, 133, 833, 49, 3231, 6315, 9771, 5667, 0 }; + static ulong[] dim3254Kuo3Init = { 1, 1, 1, 11, 27, 15, 83, 11, 483, 799, 1423, 2121, 5385, 4541, 597, 0 }; + static ulong[] dim3255Kuo3Init = { 1, 3, 7, 3, 19, 25, 5, 111, 493, 531, 317, 5, 2601, 6909, 11515, 0 }; + static ulong[] dim3256Kuo3Init = { 1, 3, 3, 7, 15, 33, 63, 89, 425, 913, 831, 3881, 2055, 4285, 13015, 0 }; + static ulong[] dim3257Kuo3Init = { 1, 3, 1, 1, 11, 5, 87, 255, 17, 731, 1149, 115, 1223, 413, 579, 0 }; + static ulong[] dim3258Kuo3Init = { 1, 1, 5, 15, 11, 27, 125, 97, 73, 221, 687, 623, 1617, 13347, 1369, 0 }; + static ulong[] dim3259Kuo3Init = { 1, 1, 5, 9, 19, 19, 39, 9, 273, 687, 805, 1105, 267, 8321, 17899, 0 }; + static ulong[] dim3260Kuo3Init = { 1, 1, 7, 7, 31, 25, 5, 209, 3, 503, 1757, 2071, 6251, 12821, 28241, 0 }; + static ulong[] dim3261Kuo3Init = { 1, 1, 5, 3, 7, 51, 25, 37, 197, 143, 1261, 1069, 6559, 5625, 30631, 0 }; + static ulong[] dim3262Kuo3Init = { 1, 3, 1, 5, 17, 15, 53, 71, 433, 133, 867, 3883, 3281, 3785, 11523, 0 }; + static ulong[] dim3263Kuo3Init = { 1, 3, 1, 7, 1, 31, 89, 165, 239, 525, 507, 3637, 4423, 1295, 9441, 0 }; + static ulong[] dim3264Kuo3Init = { 1, 1, 3, 13, 7, 11, 127, 151, 151, 821, 381, 23, 173, 14027, 8391, 0 }; + static ulong[] dim3265Kuo3Init = { 1, 3, 5, 15, 1, 51, 85, 67, 321, 797, 1625, 475, 313, 8189, 13315, 0 }; + static ulong[] dim3266Kuo3Init = { 1, 3, 5, 7, 25, 49, 1, 155, 497, 771, 457, 2097, 5997, 11363, 14715, 0 }; + static ulong[] dim3267Kuo3Init = { 1, 1, 3, 5, 15, 5, 89, 219, 441, 997, 127, 699, 5245, 3941, 14083, 0 }; + static ulong[] dim3268Kuo3Init = { 1, 3, 5, 15, 21, 13, 35, 239, 115, 57, 1479, 2813, 5249, 7733, 3135, 0 }; + static ulong[] dim3269Kuo3Init = { 1, 3, 7, 3, 11, 59, 49, 55, 183, 631, 365, 323, 6891, 3727, 24231, 0 }; + static ulong[] dim3270Kuo3Init = { 1, 1, 1, 13, 9, 29, 101, 59, 257, 995, 145, 3037, 7291, 16021, 31971, 0 }; + static ulong[] dim3271Kuo3Init = { 1, 1, 1, 1, 19, 5, 51, 21, 207, 767, 1301, 3111, 7133, 9555, 24043, 0 }; + static ulong[] dim3272Kuo3Init = { 1, 1, 3, 5, 23, 45, 25, 149, 225, 141, 827, 37, 3767, 16305, 30229, 0 }; + static ulong[] dim3273Kuo3Init = { 1, 1, 3, 9, 21, 15, 51, 155, 185, 551, 243, 2493, 653, 10615, 28137, 0 }; + static ulong[] dim3274Kuo3Init = { 1, 1, 1, 5, 13, 55, 77, 71, 383, 605, 957, 1605, 6905, 12193, 26729, 0 }; + static ulong[] dim3275Kuo3Init = { 1, 3, 1, 15, 13, 19, 95, 219, 435, 165, 1531, 2733, 4213, 3739, 10943, 0 }; + static ulong[] dim3276Kuo3Init = { 1, 3, 1, 7, 31, 35, 3, 85, 331, 161, 1167, 3627, 7075, 16189, 385, 0 }; + static ulong[] dim3277Kuo3Init = { 1, 1, 3, 11, 3, 17, 103, 205, 299, 917, 105, 1675, 3461, 895, 3279, 0 }; + static ulong[] dim3278Kuo3Init = { 1, 1, 1, 7, 25, 11, 47, 77, 91, 263, 1575, 1337, 5603, 6561, 4941, 0 }; + static ulong[] dim3279Kuo3Init = { 1, 1, 1, 5, 15, 17, 77, 69, 413, 343, 1923, 2013, 269, 12245, 14611, 0 }; + static ulong[] dim3280Kuo3Init = { 1, 3, 7, 13, 1, 29, 99, 83, 69, 871, 945, 1271, 5741, 2505, 4743, 0 }; + static ulong[] dim3281Kuo3Init = { 1, 3, 5, 13, 23, 55, 95, 17, 321, 929, 1499, 205, 5529, 3819, 29763, 0 }; + static ulong[] dim3282Kuo3Init = { 1, 3, 3, 1, 1, 47, 15, 151, 273, 991, 1993, 2325, 3633, 9033, 795, 0 }; + static ulong[] dim3283Kuo3Init = { 1, 3, 1, 5, 19, 59, 115, 79, 51, 585, 253, 1545, 2871, 2303, 23189, 0 }; + static ulong[] dim3284Kuo3Init = { 1, 1, 7, 11, 5, 49, 77, 79, 103, 719, 965, 2115, 2431, 7761, 7267, 0 }; + static ulong[] dim3285Kuo3Init = { 1, 1, 7, 13, 1, 33, 13, 121, 297, 217, 1143, 2185, 6007, 13233, 4529, 0 }; + static ulong[] dim3286Kuo3Init = { 1, 3, 7, 3, 1, 15, 17, 155, 321, 19, 1071, 3195, 3589, 12159, 30323, 0 }; + static ulong[] dim3287Kuo3Init = { 1, 3, 5, 7, 3, 57, 35, 197, 247, 449, 557, 809, 909, 9141, 26613, 0 }; + static ulong[] dim3288Kuo3Init = { 1, 3, 1, 5, 13, 43, 61, 177, 21, 161, 1823, 1077, 6523, 10765, 17427, 0 }; + static ulong[] dim3289Kuo3Init = { 1, 1, 3, 3, 13, 27, 77, 77, 315, 763, 853, 3801, 1505, 13801, 28217, 0 }; + static ulong[] dim3290Kuo3Init = { 1, 1, 1, 9, 15, 27, 45, 131, 271, 703, 1509, 443, 7739, 3011, 32463, 0 }; + static ulong[] dim3291Kuo3Init = { 1, 1, 7, 11, 17, 3, 93, 55, 331, 785, 585, 3451, 283, 2623, 21459, 0 }; + static ulong[] dim3292Kuo3Init = { 1, 3, 5, 15, 3, 3, 101, 25, 235, 721, 257, 3961, 7049, 9861, 21259, 0 }; + static ulong[] dim3293Kuo3Init = { 1, 1, 7, 7, 9, 31, 17, 17, 473, 155, 677, 603, 7503, 2845, 21089, 0 }; + static ulong[] dim3294Kuo3Init = { 1, 3, 3, 9, 11, 29, 5, 135, 141, 587, 1073, 461, 883, 16191, 16139, 0 }; + static ulong[] dim3295Kuo3Init = { 1, 3, 1, 15, 25, 17, 87, 231, 63, 563, 1061, 3207, 2291, 913, 11871, 0 }; + static ulong[] dim3296Kuo3Init = { 1, 1, 7, 11, 7, 45, 53, 79, 247, 21, 1203, 1857, 5095, 7533, 4427, 0 }; + static ulong[] dim3297Kuo3Init = { 1, 3, 5, 9, 17, 57, 29, 181, 345, 709, 1889, 2625, 8157, 4681, 21681, 0 }; + static ulong[] dim3298Kuo3Init = { 1, 3, 5, 13, 9, 63, 63, 183, 123, 957, 27, 3113, 1873, 8917, 8669, 0 }; + static ulong[] dim3299Kuo3Init = { 1, 3, 5, 9, 29, 59, 31, 211, 459, 679, 259, 1885, 1895, 12815, 2437, 0 }; + static ulong[] dim3300Kuo3Init = { 1, 1, 5, 11, 13, 51, 125, 5, 15, 865, 901, 1803, 3277, 2879, 13057, 0 }; + static ulong[] dim3301Kuo3Init = { 1, 1, 7, 9, 27, 39, 115, 67, 389, 1, 649, 639, 7183, 15929, 12953, 0 }; + static ulong[] dim3302Kuo3Init = { 1, 1, 5, 13, 3, 7, 21, 219, 241, 977, 1233, 1717, 7077, 8657, 1389, 0 }; + static ulong[] dim3303Kuo3Init = { 1, 1, 5, 15, 9, 51, 101, 127, 383, 801, 657, 2793, 1037, 11525, 7195, 0 }; + static ulong[] dim3304Kuo3Init = { 1, 3, 3, 7, 1, 29, 71, 227, 19, 371, 363, 809, 4241, 5739, 26497, 0 }; + static ulong[] dim3305Kuo3Init = { 1, 3, 5, 11, 25, 23, 65, 161, 259, 135, 1047, 3943, 5749, 2931, 20647, 0 }; + static ulong[] dim3306Kuo3Init = { 1, 1, 7, 3, 1, 55, 1, 85, 271, 67, 1813, 77, 5435, 11867, 28375, 0 }; + static ulong[] dim3307Kuo3Init = { 1, 1, 7, 11, 31, 53, 43, 47, 285, 901, 901, 977, 733, 5291, 7043, 0 }; + static ulong[] dim3308Kuo3Init = { 1, 3, 3, 7, 1, 59, 79, 123, 355, 721, 365, 2871, 6253, 14511, 4209, 0 }; + static ulong[] dim3309Kuo3Init = { 1, 1, 5, 15, 5, 49, 77, 107, 237, 257, 703, 1013, 4563, 8603, 10469, 0 }; + static ulong[] dim3310Kuo3Init = { 1, 3, 7, 11, 27, 59, 9, 129, 21, 991, 1283, 2871, 759, 5435, 30419, 0 }; + static ulong[] dim3311Kuo3Init = { 1, 3, 5, 1, 19, 5, 5, 215, 91, 117, 939, 3595, 4331, 16083, 23279, 0 }; + static ulong[] dim3312Kuo3Init = { 1, 1, 7, 7, 7, 45, 45, 71, 75, 261, 685, 63, 3553, 16349, 6803, 0 }; + static ulong[] dim3313Kuo3Init = { 1, 3, 1, 9, 1, 23, 101, 11, 331, 407, 547, 1553, 7471, 6125, 3965, 0 }; + static ulong[] dim3314Kuo3Init = { 1, 3, 7, 11, 19, 29, 1, 53, 125, 775, 1381, 1885, 2655, 7199, 24073, 0 }; + static ulong[] dim3315Kuo3Init = { 1, 3, 5, 7, 27, 21, 79, 211, 433, 993, 143, 2241, 2607, 15447, 6121, 0 }; + static ulong[] dim3316Kuo3Init = { 1, 3, 3, 7, 29, 39, 93, 65, 39, 577, 1471, 3491, 4413, 10553, 1339, 0 }; + static ulong[] dim3317Kuo3Init = { 1, 1, 5, 11, 21, 23, 75, 237, 439, 171, 361, 3283, 4145, 15267, 19917, 0 }; + static ulong[] dim3318Kuo3Init = { 1, 1, 1, 5, 9, 55, 39, 171, 423, 211, 43, 2597, 7135, 2437, 28965, 0 }; + static ulong[] dim3319Kuo3Init = { 1, 3, 1, 9, 11, 15, 71, 109, 337, 907, 135, 3557, 7359, 3539, 26953, 0 }; + static ulong[] dim3320Kuo3Init = { 1, 1, 1, 15, 15, 63, 9, 47, 153, 157, 457, 857, 6985, 3559, 23285, 0 }; + static ulong[] dim3321Kuo3Init = { 1, 3, 3, 9, 21, 21, 3, 223, 67, 429, 497, 1303, 869, 3909, 17491, 0 }; + static ulong[] dim3322Kuo3Init = { 1, 1, 1, 3, 23, 37, 7, 197, 223, 597, 421, 845, 1397, 927, 20621, 0 }; + static ulong[] dim3323Kuo3Init = { 1, 3, 1, 13, 5, 37, 41, 83, 241, 301, 1157, 1087, 2365, 10905, 25195, 0 }; + static ulong[] dim3324Kuo3Init = { 1, 3, 7, 11, 25, 11, 75, 9, 31, 5, 1909, 681, 2891, 867, 4661, 0 }; + static ulong[] dim3325Kuo3Init = { 1, 1, 1, 13, 21, 33, 127, 233, 369, 381, 711, 133, 4463, 14119, 8877, 0 }; + static ulong[] dim3326Kuo3Init = { 1, 1, 7, 7, 21, 13, 5, 61, 29, 247, 923, 3533, 2831, 9645, 1537, 0 }; + static ulong[] dim3327Kuo3Init = { 1, 1, 1, 9, 29, 13, 29, 177, 195, 299, 445, 3753, 3699, 9383, 3249, 0 }; + static ulong[] dim3328Kuo3Init = { 1, 3, 1, 3, 17, 55, 21, 245, 11, 93, 1097, 1601, 4431, 5847, 21521, 0 }; + static ulong[] dim3329Kuo3Init = { 1, 1, 3, 9, 3, 37, 9, 179, 465, 123, 333, 3765, 1599, 8709, 11007, 0 }; + static ulong[] dim3330Kuo3Init = { 1, 3, 3, 11, 15, 25, 23, 217, 193, 767, 1433, 3435, 4891, 4109, 32061, 0 }; + static ulong[] dim3331Kuo3Init = { 1, 3, 7, 11, 21, 25, 123, 111, 377, 951, 1791, 2173, 569, 12831, 30045, 0 }; + static ulong[] dim3332Kuo3Init = { 1, 1, 7, 11, 11, 19, 75, 63, 497, 1005, 1215, 3957, 4137, 4851, 23547, 0 }; + static ulong[] dim3333Kuo3Init = { 1, 1, 1, 15, 15, 9, 59, 143, 27, 941, 117, 3035, 1201, 4373, 19291, 0 }; + static ulong[] dim3334Kuo3Init = { 1, 3, 3, 5, 1, 3, 37, 187, 115, 901, 617, 1959, 2243, 6563, 3087, 0 }; + static ulong[] dim3335Kuo3Init = { 1, 1, 1, 9, 17, 31, 67, 243, 35, 667, 1863, 1017, 6501, 9279, 18089, 0 }; + static ulong[] dim3336Kuo3Init = { 1, 1, 5, 11, 25, 19, 25, 255, 371, 27, 763, 2575, 695, 6155, 27761, 0 }; + static ulong[] dim3337Kuo3Init = { 1, 3, 1, 1, 5, 49, 79, 149, 331, 601, 199, 2927, 6293, 12449, 16397, 0 }; + static ulong[] dim3338Kuo3Init = { 1, 1, 7, 11, 29, 41, 29, 161, 191, 519, 445, 1159, 3009, 3413, 21757, 0 }; + static ulong[] dim3339Kuo3Init = { 1, 3, 7, 5, 23, 57, 93, 211, 57, 269, 1627, 3393, 873, 8189, 26059, 0 }; + static ulong[] dim3340Kuo3Init = { 1, 1, 7, 11, 27, 59, 125, 251, 259, 251, 79, 2693, 1815, 8759, 15667, 0 }; + static ulong[] dim3341Kuo3Init = { 1, 1, 3, 15, 31, 47, 15, 51, 17, 761, 589, 537, 3991, 2883, 6899, 0 }; + static ulong[] dim3342Kuo3Init = { 1, 1, 3, 7, 19, 39, 95, 143, 37, 183, 1719, 1819, 1659, 1043, 31929, 0 }; + static ulong[] dim3343Kuo3Init = { 1, 1, 3, 7, 15, 47, 105, 45, 67, 665, 1273, 221, 5423, 679, 8375, 0 }; + static ulong[] dim3344Kuo3Init = { 1, 3, 1, 15, 23, 37, 123, 233, 117, 743, 785, 3871, 6031, 14379, 3339, 0 }; + static ulong[] dim3345Kuo3Init = { 1, 3, 1, 13, 1, 47, 33, 63, 309, 961, 83, 2539, 5935, 3121, 27671, 0 }; + static ulong[] dim3346Kuo3Init = { 1, 3, 7, 13, 21, 11, 103, 87, 433, 39, 293, 3217, 1533, 4511, 24493, 0 }; + static ulong[] dim3347Kuo3Init = { 1, 1, 5, 7, 9, 51, 41, 133, 443, 605, 913, 377, 5969, 8401, 25427, 0 }; + static ulong[] dim3348Kuo3Init = { 1, 1, 1, 3, 21, 27, 59, 41, 155, 35, 897, 2317, 6557, 679, 7863, 0 }; + static ulong[] dim3349Kuo3Init = { 1, 1, 7, 11, 19, 47, 39, 53, 401, 199, 271, 1385, 3505, 719, 12963, 0 }; + static ulong[] dim3350Kuo3Init = { 1, 1, 7, 7, 13, 7, 11, 131, 455, 605, 523, 3435, 2313, 9861, 22437, 0 }; + static ulong[] dim3351Kuo3Init = { 1, 3, 7, 3, 19, 5, 125, 71, 425, 321, 1151, 231, 2585, 12899, 4789, 0 }; + static ulong[] dim3352Kuo3Init = { 1, 3, 5, 11, 15, 27, 35, 13, 187, 863, 795, 1005, 6443, 3011, 5275, 0 }; + static ulong[] dim3353Kuo3Init = { 1, 3, 7, 5, 25, 61, 33, 201, 343, 337, 1441, 2647, 3469, 5537, 30595, 0 }; + static ulong[] dim3354Kuo3Init = { 1, 1, 7, 11, 17, 13, 73, 209, 121, 411, 1027, 1879, 845, 14019, 4269, 0 }; + static ulong[] dim3355Kuo3Init = { 1, 3, 5, 9, 11, 51, 69, 103, 245, 677, 409, 135, 3775, 15781, 24159, 0 }; + static ulong[] dim3356Kuo3Init = { 1, 1, 7, 3, 11, 9, 117, 101, 205, 745, 941, 125, 5915, 16305, 12547, 0 }; + static ulong[] dim3357Kuo3Init = { 1, 1, 1, 9, 9, 51, 37, 135, 79, 327, 1695, 2517, 2685, 1103, 6035, 0 }; + static ulong[] dim3358Kuo3Init = { 1, 1, 3, 13, 21, 33, 33, 229, 201, 939, 1625, 2043, 6661, 11821, 22881, 0 }; + static ulong[] dim3359Kuo3Init = { 1, 1, 1, 11, 23, 3, 23, 5, 329, 467, 963, 3833, 7345, 3225, 3709, 0 }; + static ulong[] dim3360Kuo3Init = { 1, 3, 1, 11, 27, 21, 35, 159, 255, 707, 353, 3095, 6701, 14311, 839, 0 }; + static ulong[] dim3361Kuo3Init = { 1, 1, 5, 7, 7, 63, 107, 227, 233, 303, 1523, 2019, 227, 14695, 20253, 0 }; + static ulong[] dim3362Kuo3Init = { 1, 3, 1, 1, 17, 29, 1, 167, 331, 795, 2027, 2333, 361, 1841, 4053, 0 }; + static ulong[] dim3363Kuo3Init = { 1, 1, 7, 9, 1, 41, 71, 173, 103, 43, 635, 3311, 5883, 6517, 467, 0 }; + static ulong[] dim3364Kuo3Init = { 1, 3, 7, 1, 3, 15, 101, 197, 449, 393, 889, 1189, 2665, 3647, 21977, 0 }; + static ulong[] dim3365Kuo3Init = { 1, 3, 1, 11, 23, 5, 103, 199, 417, 729, 137, 1667, 5, 4769, 11981, 0 }; + static ulong[] dim3366Kuo3Init = { 1, 3, 1, 1, 17, 37, 73, 231, 195, 497, 1835, 1597, 403, 12569, 24761, 0 }; + static ulong[] dim3367Kuo3Init = { 1, 3, 3, 7, 31, 37, 33, 39, 359, 961, 1745, 2353, 827, 6439, 27419, 0 }; + static ulong[] dim3368Kuo3Init = { 1, 1, 3, 1, 25, 25, 97, 111, 149, 799, 593, 1011, 5439, 2613, 3669, 0 }; + static ulong[] dim3369Kuo3Init = { 1, 1, 3, 5, 5, 21, 55, 37, 483, 407, 1059, 905, 5225, 9441, 17461, 0 }; + static ulong[] dim3370Kuo3Init = { 1, 1, 1, 11, 27, 15, 93, 87, 423, 625, 285, 4051, 7931, 9005, 4033, 0 }; + static ulong[] dim3371Kuo3Init = { 1, 1, 1, 7, 13, 17, 13, 221, 29, 179, 645, 2721, 4781, 6151, 6435, 0 }; + static ulong[] dim3372Kuo3Init = { 1, 1, 5, 9, 11, 59, 53, 249, 13, 295, 467, 1781, 2381, 2897, 11175, 0 }; + static ulong[] dim3373Kuo3Init = { 1, 3, 5, 3, 5, 41, 111, 129, 159, 363, 1109, 1547, 1209, 15035, 17367, 0 }; + static ulong[] dim3374Kuo3Init = { 1, 1, 7, 13, 23, 51, 55, 129, 435, 671, 947, 349, 1741, 15317, 28069, 0 }; + static ulong[] dim3375Kuo3Init = { 1, 3, 5, 7, 13, 9, 17, 111, 309, 987, 1521, 1243, 1815, 10055, 4883, 0 }; + static ulong[] dim3376Kuo3Init = { 1, 1, 5, 5, 21, 9, 19, 179, 315, 547, 1899, 1421, 589, 2563, 27523, 0 }; + static ulong[] dim3377Kuo3Init = { 1, 1, 5, 11, 25, 23, 115, 229, 439, 225, 1957, 3251, 4377, 12751, 2983, 0 }; + static ulong[] dim3378Kuo3Init = { 1, 3, 1, 3, 21, 23, 57, 187, 469, 575, 1587, 1983, 4353, 8605, 27269, 0 }; + static ulong[] dim3379Kuo3Init = { 1, 3, 5, 15, 11, 17, 51, 131, 93, 599, 487, 3397, 761, 11503, 13405, 0 }; + static ulong[] dim3380Kuo3Init = { 1, 3, 1, 15, 27, 7, 13, 105, 189, 141, 715, 1571, 8103, 3233, 10481, 0 }; + static ulong[] dim3381Kuo3Init = { 1, 1, 7, 3, 21, 17, 103, 121, 229, 865, 1819, 171, 7281, 14085, 4483, 0 }; + static ulong[] dim3382Kuo3Init = { 1, 3, 7, 13, 21, 47, 105, 233, 325, 49, 1305, 2269, 7717, 2771, 27583, 0 }; + static ulong[] dim3383Kuo3Init = { 1, 3, 3, 5, 17, 11, 101, 55, 191, 115, 1749, 3015, 1493, 15301, 1629, 0 }; + static ulong[] dim3384Kuo3Init = { 1, 1, 7, 1, 3, 39, 111, 51, 269, 451, 1327, 3389, 6461, 7361, 1311, 0 }; + static ulong[] dim3385Kuo3Init = { 1, 1, 7, 7, 23, 21, 103, 241, 3, 295, 981, 3969, 1631, 6301, 9481, 0 }; + static ulong[] dim3386Kuo3Init = { 1, 3, 7, 3, 17, 63, 49, 163, 89, 183, 555, 597, 3099, 8057, 28653, 0 }; + static ulong[] dim3387Kuo3Init = { 1, 1, 7, 15, 9, 29, 35, 255, 173, 295, 2015, 283, 1179, 1677, 26417, 0 }; + static ulong[] dim3388Kuo3Init = { 1, 3, 1, 5, 11, 29, 73, 67, 5, 995, 1563, 2611, 7605, 13831, 7405, 0 }; + static ulong[] dim3389Kuo3Init = { 1, 3, 3, 1, 1, 27, 7, 251, 175, 683, 603, 2895, 6033, 4133, 2753, 0 }; + static ulong[] dim3390Kuo3Init = { 1, 1, 7, 15, 23, 47, 45, 179, 289, 317, 1111, 1241, 7221, 8661, 31853, 0 }; + static ulong[] dim3391Kuo3Init = { 1, 1, 3, 15, 19, 19, 35, 139, 145, 469, 1455, 2335, 8009, 6609, 14847, 0 }; + static ulong[] dim3392Kuo3Init = { 1, 1, 7, 11, 17, 59, 115, 71, 197, 143, 1791, 3515, 3443, 5065, 22885, 0 }; + static ulong[] dim3393Kuo3Init = { 1, 3, 7, 11, 25, 19, 47, 223, 469, 745, 107, 2801, 6279, 16311, 15699, 0 }; + static ulong[] dim3394Kuo3Init = { 1, 1, 1, 5, 29, 47, 21, 227, 219, 331, 1179, 3409, 1787, 9113, 8359, 0 }; + static ulong[] dim3395Kuo3Init = { 1, 3, 7, 3, 7, 29, 43, 135, 137, 203, 241, 2421, 3125, 3883, 23519, 0 }; + static ulong[] dim3396Kuo3Init = { 1, 3, 5, 3, 3, 63, 5, 5, 425, 863, 1483, 4049, 2505, 3173, 3021, 0 }; + static ulong[] dim3397Kuo3Init = { 1, 1, 1, 1, 31, 11, 37, 133, 349, 33, 1617, 7, 4945, 8143, 22027, 0 }; + static ulong[] dim3398Kuo3Init = { 1, 3, 7, 9, 13, 61, 61, 111, 203, 255, 1107, 425, 4571, 1537, 2547, 0 }; + static ulong[] dim3399Kuo3Init = { 1, 3, 1, 13, 19, 35, 5, 99, 33, 271, 203, 545, 1917, 8645, 30737, 0 }; + static ulong[] dim3400Kuo3Init = { 1, 1, 5, 1, 31, 33, 125, 119, 475, 497, 1341, 593, 3497, 2191, 28715, 0 }; + static ulong[] dim3401Kuo3Init = { 1, 1, 7, 15, 17, 57, 87, 101, 487, 659, 497, 1243, 3353, 4803, 11445, 0 }; + static ulong[] dim3402Kuo3Init = { 1, 3, 1, 3, 31, 13, 55, 79, 233, 327, 1825, 245, 2693, 11761, 21155, 0 }; + static ulong[] dim3403Kuo3Init = { 1, 3, 7, 7, 21, 1, 15, 183, 113, 871, 251, 3573, 517, 9973, 28567, 0 }; + static ulong[] dim3404Kuo3Init = { 1, 1, 1, 11, 23, 53, 47, 143, 435, 107, 1091, 2139, 5985, 12541, 9857, 0 }; + static ulong[] dim3405Kuo3Init = { 1, 3, 3, 13, 23, 47, 125, 95, 333, 13, 285, 1691, 1899, 5625, 29883, 0 }; + static ulong[] dim3406Kuo3Init = { 1, 1, 7, 1, 1, 3, 21, 69, 425, 179, 1815, 2231, 6257, 1387, 26423, 0 }; + static ulong[] dim3407Kuo3Init = { 1, 1, 1, 13, 23, 11, 37, 223, 259, 767, 1521, 2445, 7725, 2013, 8365, 0 }; + static ulong[] dim3408Kuo3Init = { 1, 1, 7, 7, 13, 25, 125, 167, 423, 457, 1793, 4043, 913, 14917, 4577, 0 }; + static ulong[] dim3409Kuo3Init = { 1, 3, 5, 11, 13, 49, 95, 145, 251, 305, 1883, 3717, 7927, 6635, 9647, 0 }; + static ulong[] dim3410Kuo3Init = { 1, 3, 1, 1, 31, 33, 87, 189, 499, 933, 115, 3407, 1517, 157, 11815, 0 }; + static ulong[] dim3411Kuo3Init = { 1, 1, 7, 7, 15, 1, 7, 155, 493, 413, 231, 69, 3433, 13471, 26705, 0 }; + static ulong[] dim3412Kuo3Init = { 1, 3, 7, 15, 3, 59, 21, 81, 309, 445, 1467, 2655, 4871, 1667, 24557, 0 }; + static ulong[] dim3413Kuo3Init = { 1, 3, 3, 15, 11, 25, 73, 181, 355, 887, 967, 1131, 5137, 12695, 8561, 0 }; + static ulong[] dim3414Kuo3Init = { 1, 3, 3, 11, 27, 51, 19, 95, 165, 991, 2039, 3269, 2839, 12065, 26791, 0 }; + static ulong[] dim3415Kuo3Init = { 1, 1, 5, 15, 29, 15, 47, 89, 251, 149, 7, 447, 1945, 157, 3865, 0 }; + static ulong[] dim3416Kuo3Init = { 1, 1, 5, 15, 27, 33, 99, 211, 481, 95, 1361, 2933, 509, 16383, 11581, 0 }; + static ulong[] dim3417Kuo3Init = { 1, 1, 3, 1, 29, 43, 103, 141, 117, 505, 733, 2719, 2281, 4753, 27511, 0 }; + static ulong[] dim3418Kuo3Init = { 1, 3, 1, 15, 5, 15, 25, 87, 255, 819, 1589, 2623, 2043, 7735, 7813, 0 }; + static ulong[] dim3419Kuo3Init = { 1, 1, 5, 15, 23, 57, 125, 145, 387, 729, 1845, 2809, 8067, 3487, 19919, 0 }; + static ulong[] dim3420Kuo3Init = { 1, 3, 3, 5, 17, 59, 45, 11, 15, 505, 1859, 2193, 4581, 15553, 767, 0 }; + static ulong[] dim3421Kuo3Init = { 1, 1, 1, 3, 27, 47, 95, 147, 493, 259, 759, 4013, 5611, 1379, 13017, 0 }; + static ulong[] dim3422Kuo3Init = { 1, 3, 3, 9, 13, 3, 7, 193, 203, 379, 1445, 1599, 5915, 6025, 8037, 0 }; + static ulong[] dim3423Kuo3Init = { 1, 3, 7, 5, 7, 33, 77, 5, 449, 509, 1409, 2711, 5603, 9343, 10613, 0 }; + static ulong[] dim3424Kuo3Init = { 1, 3, 5, 1, 31, 19, 65, 169, 429, 951, 1659, 3045, 735, 5089, 27215, 0 }; + static ulong[] dim3425Kuo3Init = { 1, 1, 7, 1, 13, 43, 73, 67, 449, 357, 285, 2291, 3493, 1575, 9281, 0 }; + static ulong[] dim3426Kuo3Init = { 1, 3, 7, 13, 7, 59, 15, 119, 479, 523, 201, 1381, 3245, 15591, 18785, 0 }; + static ulong[] dim3427Kuo3Init = { 1, 3, 1, 13, 13, 13, 29, 105, 65, 231, 161, 375, 3725, 5097, 23183, 0 }; + static ulong[] dim3428Kuo3Init = { 1, 3, 5, 7, 7, 21, 103, 155, 357, 661, 1035, 2421, 5989, 14613, 11499, 0 }; + static ulong[] dim3429Kuo3Init = { 1, 3, 3, 3, 13, 7, 45, 221, 189, 405, 1845, 3791, 2989, 495, 13899, 0 }; + static ulong[] dim3430Kuo3Init = { 1, 3, 7, 15, 27, 23, 91, 39, 385, 59, 1367, 3177, 1945, 15335, 7543, 0 }; + static ulong[] dim3431Kuo3Init = { 1, 3, 1, 5, 25, 49, 43, 215, 7, 1003, 831, 611, 183, 4627, 29423, 0 }; + static ulong[] dim3432Kuo3Init = { 1, 1, 3, 9, 29, 15, 57, 7, 259, 543, 1313, 449, 2497, 4337, 20879, 0 }; + static ulong[] dim3433Kuo3Init = { 1, 3, 1, 3, 17, 23, 111, 99, 185, 183, 1215, 1775, 8129, 4487, 7927, 0 }; + static ulong[] dim3434Kuo3Init = { 1, 1, 1, 1, 21, 23, 55, 195, 219, 595, 703, 97, 7599, 15673, 25677, 0 }; + static ulong[] dim3435Kuo3Init = { 1, 3, 1, 11, 19, 11, 121, 145, 237, 719, 201, 1335, 5147, 2195, 22909, 0 }; + static ulong[] dim3436Kuo3Init = { 1, 1, 3, 11, 27, 27, 45, 185, 251, 329, 1253, 1071, 2097, 9669, 2999, 0 }; + static ulong[] dim3437Kuo3Init = { 1, 3, 3, 11, 27, 35, 91, 183, 161, 393, 1269, 1945, 727, 9985, 9275, 0 }; + static ulong[] dim3438Kuo3Init = { 1, 1, 1, 9, 15, 43, 109, 25, 431, 641, 1291, 1169, 649, 16145, 27663, 0 }; + static ulong[] dim3439Kuo3Init = { 1, 3, 5, 5, 11, 59, 77, 193, 59, 325, 531, 365, 7285, 5111, 26647, 0 }; + static ulong[] dim3440Kuo3Init = { 1, 1, 3, 9, 15, 1, 33, 51, 427, 513, 575, 3739, 4593, 6669, 25369, 0 }; + static ulong[] dim3441Kuo3Init = { 1, 3, 1, 13, 5, 31, 109, 155, 83, 405, 657, 1095, 5087, 13835, 30395, 0 }; + static ulong[] dim3442Kuo3Init = { 1, 3, 7, 9, 11, 21, 115, 129, 389, 25, 657, 3455, 1357, 1501, 10589, 0 }; + static ulong[] dim3443Kuo3Init = { 1, 3, 5, 9, 29, 21, 67, 153, 197, 703, 123, 1645, 2175, 5581, 26465, 0 }; + static ulong[] dim3444Kuo3Init = { 1, 1, 7, 11, 1, 21, 79, 71, 49, 719, 909, 3783, 5081, 13235, 19387, 0 }; + static ulong[] dim3445Kuo3Init = { 1, 1, 1, 5, 11, 47, 93, 213, 305, 673, 191, 2787, 3293, 6721, 19105, 0 }; + static ulong[] dim3446Kuo3Init = { 1, 1, 5, 15, 19, 1, 127, 189, 25, 201, 1867, 3541, 3215, 14025, 15823, 0 }; + static ulong[] dim3447Kuo3Init = { 1, 1, 7, 5, 9, 43, 75, 129, 335, 73, 995, 15, 4423, 6817, 14311, 0 }; + static ulong[] dim3448Kuo3Init = { 1, 3, 3, 7, 13, 53, 97, 29, 311, 749, 1025, 5, 6001, 6831, 24699, 0 }; + static ulong[] dim3449Kuo3Init = { 1, 3, 7, 3, 29, 21, 117, 245, 389, 785, 405, 1455, 4249, 9663, 30027, 0 }; + static ulong[] dim3450Kuo3Init = { 1, 1, 5, 13, 13, 27, 113, 221, 293, 583, 1329, 3387, 4233, 11511, 30005, 0 }; + static ulong[] dim3451Kuo3Init = { 1, 3, 1, 11, 11, 59, 85, 23, 435, 769, 889, 2993, 8075, 10831, 23109, 0 }; + static ulong[] dim3452Kuo3Init = { 1, 1, 7, 13, 31, 9, 59, 247, 387, 27, 791, 1381, 1881, 15223, 29481, 0 }; + static ulong[] dim3453Kuo3Init = { 1, 1, 7, 7, 1, 39, 93, 67, 293, 777, 1463, 1363, 3159, 6569, 18361, 0 }; + static ulong[] dim3454Kuo3Init = { 1, 3, 1, 11, 25, 31, 49, 133, 459, 399, 593, 3907, 701, 9321, 28589, 0 }; + static ulong[] dim3455Kuo3Init = { 1, 1, 7, 5, 7, 35, 85, 247, 247, 577, 245, 1615, 337, 11289, 32149, 0 }; + static ulong[] dim3456Kuo3Init = { 1, 3, 5, 7, 21, 35, 67, 37, 77, 395, 907, 595, 883, 14931, 21875, 0 }; + static ulong[] dim3457Kuo3Init = { 1, 1, 1, 9, 5, 25, 1, 69, 307, 419, 1875, 3075, 15, 5853, 3177, 0 }; + static ulong[] dim3458Kuo3Init = { 1, 1, 3, 1, 15, 7, 15, 17, 67, 577, 1525, 1847, 481, 15451, 21229, 0 }; + static ulong[] dim3459Kuo3Init = { 1, 1, 1, 11, 23, 35, 79, 179, 397, 403, 1935, 3371, 3511, 13593, 30241, 0 }; + static ulong[] dim3460Kuo3Init = { 1, 3, 5, 3, 13, 11, 79, 215, 409, 577, 1301, 451, 5171, 1555, 18445, 0 }; + static ulong[] dim3461Kuo3Init = { 1, 3, 3, 13, 25, 35, 71, 65, 371, 667, 247, 3815, 4383, 6429, 4667, 0 }; + static ulong[] dim3462Kuo3Init = { 1, 1, 3, 1, 17, 45, 115, 217, 353, 501, 1087, 1521, 2621, 4847, 12647, 0 }; + static ulong[] dim3463Kuo3Init = { 1, 1, 7, 7, 5, 25, 75, 33, 421, 39, 1857, 2189, 2383, 4401, 11737, 0 }; + static ulong[] dim3464Kuo3Init = { 1, 1, 7, 7, 7, 23, 123, 155, 343, 85, 879, 595, 6419, 3789, 31233, 0 }; + static ulong[] dim3465Kuo3Init = { 1, 1, 7, 5, 29, 55, 75, 203, 319, 465, 1903, 595, 8127, 9773, 4083, 0 }; + static ulong[] dim3466Kuo3Init = { 1, 3, 7, 11, 27, 31, 55, 147, 17, 893, 33, 3239, 1773, 2111, 19833, 0 }; + static ulong[] dim3467Kuo3Init = { 1, 3, 7, 5, 27, 39, 3, 131, 401, 843, 1229, 227, 5221, 5845, 29029, 0 }; + static ulong[] dim3468Kuo3Init = { 1, 1, 5, 13, 15, 47, 113, 11, 361, 95, 1303, 333, 5139, 8393, 2225, 0 }; + static ulong[] dim3469Kuo3Init = { 1, 3, 5, 11, 27, 53, 45, 111, 377, 41, 985, 931, 3901, 13921, 25305, 0 }; + static ulong[] dim3470Kuo3Init = { 1, 3, 7, 3, 23, 23, 95, 227, 207, 71, 525, 3843, 6025, 16335, 30519, 0 }; + static ulong[] dim3471Kuo3Init = { 1, 3, 5, 1, 9, 55, 95, 69, 457, 823, 479, 4073, 3227, 1355, 12937, 0 }; + static ulong[] dim3472Kuo3Init = { 1, 1, 1, 5, 7, 17, 67, 143, 189, 79, 653, 2791, 1193, 9409, 3561, 0 }; + static ulong[] dim3473Kuo3Init = { 1, 1, 1, 5, 29, 53, 67, 253, 471, 649, 669, 1621, 1199, 12889, 27943, 0 }; + static ulong[] dim3474Kuo3Init = { 1, 1, 3, 11, 15, 3, 93, 33, 335, 899, 1897, 1689, 2753, 473, 21935, 0 }; + static ulong[] dim3475Kuo3Init = { 1, 1, 7, 7, 27, 29, 17, 167, 467, 261, 671, 2449, 7433, 5669, 77, 0 }; + static ulong[] dim3476Kuo3Init = { 1, 1, 7, 9, 5, 37, 85, 103, 19, 971, 1851, 231, 7897, 1783, 12659, 0 }; + static ulong[] dim3477Kuo3Init = { 1, 3, 7, 7, 17, 57, 1, 7, 491, 887, 341, 3859, 2783, 9547, 26867, 0 }; + static ulong[] dim3478Kuo3Init = { 1, 1, 1, 3, 29, 45, 77, 219, 131, 573, 1015, 765, 6211, 3243, 32547, 0 }; + static ulong[] dim3479Kuo3Init = { 1, 3, 1, 5, 19, 51, 61, 27, 415, 125, 69, 2151, 3385, 1405, 25509, 0 }; + static ulong[] dim3480Kuo3Init = { 1, 3, 1, 3, 23, 17, 19, 35, 489, 869, 687, 1047, 6031, 589, 3611, 0 }; + static ulong[] dim3481Kuo3Init = { 1, 3, 5, 15, 19, 27, 47, 175, 23, 427, 137, 2733, 1795, 483, 11083, 0 }; + static ulong[] dim3482Kuo3Init = { 1, 1, 1, 1, 23, 41, 93, 229, 407, 751, 635, 3125, 831, 2121, 8463, 0 }; + static ulong[] dim3483Kuo3Init = { 1, 3, 5, 11, 27, 61, 27, 21, 337, 33, 1373, 37, 89, 7527, 21165, 0 }; + static ulong[] dim3484Kuo3Init = { 1, 1, 5, 9, 25, 55, 51, 111, 497, 737, 1097, 165, 7879, 1509, 5025, 0 }; + static ulong[] dim3485Kuo3Init = { 1, 3, 5, 11, 3, 51, 61, 19, 75, 1001, 1535, 2689, 2903, 9675, 22209, 0 }; + static ulong[] dim3486Kuo3Init = { 1, 1, 3, 13, 27, 7, 89, 219, 459, 403, 1963, 979, 3987, 4165, 5027, 0 }; + static ulong[] dim3487Kuo3Init = { 1, 1, 1, 13, 15, 51, 113, 37, 105, 57, 589, 3583, 7205, 107, 29687, 0 }; + static ulong[] dim3488Kuo3Init = { 1, 1, 7, 7, 1, 57, 125, 131, 265, 957, 461, 1413, 3961, 10543, 14951, 0 }; + static ulong[] dim3489Kuo3Init = { 1, 1, 7, 13, 19, 53, 125, 41, 417, 629, 153, 2531, 5655, 1919, 14615, 0 }; + static ulong[] dim3490Kuo3Init = { 1, 1, 7, 1, 1, 21, 19, 123, 3, 601, 1781, 2237, 705, 14229, 6739, 0 }; + static ulong[] dim3491Kuo3Init = { 1, 3, 5, 5, 3, 3, 23, 71, 225, 507, 619, 493, 5917, 1145, 7303, 0 }; + static ulong[] dim3492Kuo3Init = { 1, 1, 1, 13, 3, 19, 89, 237, 497, 3, 91, 2559, 6347, 8925, 9845, 0 }; + static ulong[] dim3493Kuo3Init = { 1, 3, 5, 7, 11, 47, 85, 147, 339, 499, 511, 731, 3063, 5363, 19841, 0 }; + static ulong[] dim3494Kuo3Init = { 1, 3, 7, 7, 19, 41, 105, 225, 37, 181, 127, 2167, 4247, 915, 14507, 0 }; + static ulong[] dim3495Kuo3Init = { 1, 1, 5, 11, 31, 7, 23, 229, 165, 485, 693, 3279, 7407, 9883, 31803, 0 }; + static ulong[] dim3496Kuo3Init = { 1, 3, 5, 9, 15, 33, 1, 99, 79, 589, 411, 2783, 3437, 2151, 11585, 0 }; + static ulong[] dim3497Kuo3Init = { 1, 3, 1, 5, 25, 15, 95, 221, 399, 793, 617, 2431, 6859, 2893, 8919, 0 }; + static ulong[] dim3498Kuo3Init = { 1, 3, 1, 11, 21, 57, 127, 1, 81, 657, 1935, 1937, 1635, 4079, 6677, 0 }; + static ulong[] dim3499Kuo3Init = { 1, 1, 5, 1, 17, 7, 19, 167, 483, 53, 49, 1187, 789, 1787, 4103, 0 }; + static ulong[] dim3500Kuo3Init = { 1, 3, 5, 15, 11, 1, 83, 223, 289, 119, 1263, 2995, 5697, 5835, 7127, 0 }; + static ulong[] dim3501Kuo3Init = { 1, 3, 7, 13, 1, 25, 59, 59, 223, 309, 1133, 773, 8171, 12881, 21959, 0 }; + static ulong[] dim3502Kuo3Init = { 1, 3, 7, 15, 7, 43, 63, 99, 503, 527, 1915, 1147, 2729, 8311, 13451, 0 }; + static ulong[] dim3503Kuo3Init = { 1, 1, 1, 7, 25, 37, 61, 41, 25, 681, 1029, 1715, 63, 6913, 31299, 0 }; + static ulong[] dim3504Kuo3Init = { 1, 3, 5, 13, 29, 41, 25, 135, 241, 331, 51, 2305, 5149, 12295, 8891, 0 }; + static ulong[] dim3505Kuo3Init = { 1, 1, 3, 7, 7, 53, 25, 127, 227, 711, 1165, 2563, 2681, 1331, 8435, 0 }; + static ulong[] dim3506Kuo3Init = { 1, 3, 3, 15, 29, 43, 27, 105, 371, 691, 77, 1847, 6097, 1253, 1163, 0 }; + static ulong[] dim3507Kuo3Init = { 1, 3, 5, 1, 23, 43, 23, 185, 287, 407, 1523, 1923, 2121, 3297, 21549, 0 }; + static ulong[] dim3508Kuo3Init = { 1, 3, 7, 15, 31, 45, 19, 85, 323, 837, 99, 581, 6607, 3685, 21853, 0 }; + static ulong[] dim3509Kuo3Init = { 1, 1, 3, 3, 31, 27, 107, 55, 79, 339, 1739, 2373, 6393, 6557, 20651, 0 }; + static ulong[] dim3510Kuo3Init = { 1, 3, 1, 11, 7, 23, 63, 43, 237, 753, 1347, 1775, 6663, 2907, 2905, 0 }; + static ulong[] dim3511Kuo3Init = { 1, 1, 5, 5, 1, 3, 99, 135, 247, 249, 757, 619, 3497, 2421, 6601, 0 }; + static ulong[] dim3512Kuo3Init = { 1, 3, 1, 7, 5, 61, 91, 151, 283, 723, 1931, 3799, 2737, 14833, 2363, 0 }; + static ulong[] dim3513Kuo3Init = { 1, 1, 3, 1, 9, 15, 53, 233, 365, 323, 1141, 3523, 7771, 707, 1837, 0 }; + static ulong[] dim3514Kuo3Init = { 1, 1, 1, 7, 11, 43, 87, 63, 425, 149, 1121, 4051, 5391, 591, 19849, 0 }; + static ulong[] dim3515Kuo3Init = { 1, 1, 1, 5, 15, 39, 55, 233, 401, 337, 289, 693, 3659, 10381, 25723, 0 }; + static ulong[] dim3516Kuo3Init = { 1, 1, 7, 11, 3, 11, 55, 89, 293, 235, 893, 853, 1281, 13845, 7123, 0 }; + static ulong[] dim3517Kuo3Init = { 1, 1, 7, 15, 11, 1, 41, 187, 297, 557, 1951, 4007, 2429, 493, 31645, 0 }; + static ulong[] dim3518Kuo3Init = { 1, 1, 1, 1, 31, 39, 113, 3, 11, 217, 1841, 545, 1953, 1667, 28317, 0 }; + static ulong[] dim3519Kuo3Init = { 1, 1, 3, 7, 31, 31, 125, 217, 127, 561, 983, 3651, 6649, 11859, 3887, 0 }; + static ulong[] dim3520Kuo3Init = { 1, 1, 1, 3, 17, 51, 107, 25, 511, 777, 771, 2359, 275, 16351, 15639, 0 }; + static ulong[] dim3521Kuo3Init = { 1, 3, 5, 1, 11, 13, 9, 167, 505, 667, 155, 2857, 4043, 12145, 3369, 0 }; + static ulong[] dim3522Kuo3Init = { 1, 3, 7, 1, 15, 33, 83, 217, 333, 847, 679, 3981, 925, 3465, 1217, 0 }; + static ulong[] dim3523Kuo3Init = { 1, 1, 3, 7, 13, 55, 111, 101, 455, 929, 1755, 2177, 931, 8083, 1207, 0 }; + static ulong[] dim3524Kuo3Init = { 1, 1, 1, 3, 21, 29, 25, 213, 113, 51, 1913, 1131, 1981, 16221, 32569, 0 }; + static ulong[] dim3525Kuo3Init = { 1, 1, 3, 13, 13, 9, 105, 153, 317, 755, 363, 2833, 4463, 2607, 17587, 0 }; + static ulong[] dim3526Kuo3Init = { 1, 1, 5, 1, 7, 15, 71, 133, 141, 639, 273, 1445, 4571, 13313, 319, 0 }; + static ulong[] dim3527Kuo3Init = { 1, 1, 5, 9, 23, 17, 55, 49, 159, 713, 1127, 2537, 4927, 4389, 8361, 0 }; + static ulong[] dim3528Kuo3Init = { 1, 3, 3, 1, 31, 23, 35, 237, 7, 801, 1939, 2243, 3891, 12379, 251, 0 }; + static ulong[] dim3529Kuo3Init = { 1, 1, 7, 15, 17, 11, 33, 89, 39, 87, 1963, 1591, 7775, 5091, 23503, 0 }; + static ulong[] dim3530Kuo3Init = { 1, 1, 7, 1, 31, 63, 93, 55, 197, 627, 1887, 899, 2491, 7713, 9921, 0 }; + static ulong[] dim3531Kuo3Init = { 1, 1, 3, 11, 27, 17, 27, 33, 413, 131, 1713, 615, 1775, 237, 2775, 0 }; + static ulong[] dim3532Kuo3Init = { 1, 3, 5, 9, 23, 3, 83, 69, 113, 311, 1199, 2593, 3745, 14473, 727, 0 }; + static ulong[] dim3533Kuo3Init = { 1, 3, 3, 3, 3, 57, 111, 195, 303, 713, 1305, 955, 7415, 15625, 6491, 0 }; + static ulong[] dim3534Kuo3Init = { 1, 3, 1, 15, 25, 37, 3, 149, 7, 923, 1367, 3743, 5887, 5683, 17437, 0 }; + static ulong[] dim3535Kuo3Init = { 1, 3, 3, 7, 5, 33, 85, 149, 339, 223, 1359, 1881, 4383, 8949, 1331, 0 }; + static ulong[] dim3536Kuo3Init = { 1, 1, 3, 15, 21, 27, 85, 209, 205, 597, 655, 2759, 109, 4963, 13055, 0 }; + static ulong[] dim3537Kuo3Init = { 1, 3, 1, 1, 3, 29, 99, 15, 399, 233, 1697, 2613, 1819, 9059, 10329, 0 }; + static ulong[] dim3538Kuo3Init = { 1, 1, 5, 1, 19, 13, 69, 87, 451, 389, 1065, 665, 7217, 12907, 32423, 0 }; + static ulong[] dim3539Kuo3Init = { 1, 1, 3, 11, 23, 57, 127, 107, 181, 231, 1233, 1593, 6365, 13919, 29379, 0 }; + static ulong[] dim3540Kuo3Init = { 1, 1, 7, 13, 29, 43, 11, 119, 165, 835, 323, 3051, 3641, 13841, 26399, 0 }; + static ulong[] dim3541Kuo3Init = { 1, 1, 7, 5, 15, 27, 41, 97, 317, 565, 1589, 2091, 1213, 12143, 26777, 0 }; + static ulong[] dim3542Kuo3Init = { 1, 3, 7, 13, 3, 17, 65, 221, 183, 265, 363, 1013, 7269, 13731, 25029, 0 }; + static ulong[] dim3543Kuo3Init = { 1, 1, 3, 3, 13, 13, 123, 59, 193, 95, 1909, 1701, 6123, 5599, 17805, 0 }; + static ulong[] dim3544Kuo3Init = { 1, 1, 1, 1, 3, 51, 1, 155, 59, 199, 1751, 813, 441, 5615, 28115, 0 }; + static ulong[] dim3545Kuo3Init = { 1, 1, 5, 3, 13, 33, 37, 245, 343, 21, 1083, 2177, 4593, 13995, 12465, 0 }; + static ulong[] dim3546Kuo3Init = { 1, 1, 7, 3, 21, 57, 31, 65, 15, 427, 981, 1047, 7731, 763, 26335, 0 }; + static ulong[] dim3547Kuo3Init = { 1, 3, 3, 11, 1, 15, 19, 207, 127, 623, 949, 663, 2691, 505, 10667, 0 }; + static ulong[] dim3548Kuo3Init = { 1, 1, 3, 9, 3, 7, 31, 175, 225, 707, 1393, 1661, 2761, 4675, 16195, 0 }; + static ulong[] dim3549Kuo3Init = { 1, 3, 1, 5, 21, 35, 17, 61, 337, 307, 191, 1077, 7331, 8965, 18963, 0 }; + static ulong[] dim3550Kuo3Init = { 1, 3, 3, 7, 23, 53, 37, 95, 229, 125, 813, 2279, 4915, 10637, 15533, 0 }; + static ulong[] dim3551Kuo3Init = { 1, 3, 3, 1, 21, 9, 61, 183, 457, 997, 929, 2245, 6213, 11179, 1803, 0 }; + static ulong[] dim3552Kuo3Init = { 1, 1, 5, 15, 11, 63, 21, 235, 259, 161, 1347, 2807, 3991, 14205, 26369, 0 }; + static ulong[] dim3553Kuo3Init = { 1, 1, 7, 5, 13, 3, 33, 237, 473, 167, 1341, 3617, 3671, 15041, 29603, 0 }; + static ulong[] dim3554Kuo3Init = { 1, 1, 5, 9, 17, 1, 105, 169, 25, 825, 1703, 751, 5461, 13121, 30917, 0 }; + static ulong[] dim3555Kuo3Init = { 1, 3, 7, 5, 9, 31, 19, 231, 137, 601, 1177, 327, 3811, 7553, 13453, 0 }; + static ulong[] dim3556Kuo3Init = { 1, 1, 7, 7, 7, 43, 7, 231, 171, 695, 331, 1493, 2437, 12487, 25451, 0 }; + static ulong[] dim3557Kuo3Init = { 1, 3, 5, 13, 27, 19, 103, 157, 145, 267, 1417, 3867, 7477, 15399, 31311, 0 }; + static ulong[] dim3558Kuo3Init = { 1, 1, 7, 1, 5, 11, 111, 89, 45, 685, 1283, 2581, 819, 3675, 25143, 0 }; + static ulong[] dim3559Kuo3Init = { 1, 1, 1, 5, 31, 5, 85, 143, 113, 693, 529, 321, 5407, 14411, 27513, 0 }; + static ulong[] dim3560Kuo3Init = { 1, 1, 1, 9, 19, 5, 103, 79, 439, 327, 1769, 3371, 7191, 5827, 10145, 0 }; + static ulong[] dim3561Kuo3Init = { 1, 3, 1, 15, 1, 3, 63, 57, 331, 525, 239, 307, 4927, 13525, 26383, 0 }; + static ulong[] dim3562Kuo3Init = { 1, 1, 1, 11, 11, 31, 49, 137, 407, 335, 905, 3441, 623, 11301, 8933, 0 }; + static ulong[] dim3563Kuo3Init = { 1, 3, 7, 13, 29, 59, 41, 143, 103, 255, 1195, 3033, 6785, 12717, 5789, 0 }; + static ulong[] dim3564Kuo3Init = { 1, 3, 7, 5, 11, 3, 107, 121, 173, 481, 3, 1485, 4557, 11095, 24611, 0 }; + static ulong[] dim3565Kuo3Init = { 1, 3, 3, 1, 3, 47, 17, 107, 77, 323, 1349, 2285, 871, 7301, 27811, 0 }; + static ulong[] dim3566Kuo3Init = { 1, 3, 3, 13, 9, 49, 95, 53, 337, 323, 1231, 3825, 7403, 12851, 31133, 0 }; + static ulong[] dim3567Kuo3Init = { 1, 3, 1, 1, 29, 59, 123, 239, 251, 513, 259, 529, 1267, 13323, 15509, 0 }; + static ulong[] dim3568Kuo3Init = { 1, 1, 1, 7, 25, 61, 91, 75, 83, 575, 671, 2575, 2871, 11909, 31371, 0 }; + static ulong[] dim3569Kuo3Init = { 1, 3, 7, 3, 15, 63, 99, 161, 77, 539, 1069, 1263, 4173, 12691, 18091, 0 }; + static ulong[] dim3570Kuo3Init = { 1, 3, 7, 1, 15, 55, 39, 33, 257, 925, 839, 4091, 2621, 315, 28153, 0 }; + static ulong[] dim3571Kuo3Init = { 1, 1, 3, 3, 9, 9, 17, 207, 369, 773, 1661, 3175, 2367, 6363, 5363, 0 }; + static ulong[] dim3572Kuo3Init = { 1, 1, 3, 15, 31, 11, 41, 145, 381, 969, 327, 487, 5545, 16163, 13891, 0 }; + static ulong[] dim3573Kuo3Init = { 1, 1, 3, 5, 19, 15, 125, 183, 445, 771, 829, 3653, 7487, 14429, 14535, 0 }; + static ulong[] dim3574Kuo3Init = { 1, 1, 1, 13, 5, 55, 41, 171, 163, 677, 1549, 2769, 3961, 4051, 25883, 0 }; + static ulong[] dim3575Kuo3Init = { 1, 3, 5, 5, 15, 5, 121, 113, 423, 607, 1623, 2899, 7839, 8107, 13963, 0 }; + static ulong[] dim3576Kuo3Init = { 1, 1, 7, 11, 17, 55, 85, 139, 93, 453, 75, 2405, 7601, 15647, 25349, 0 }; + static ulong[] dim3577Kuo3Init = { 1, 3, 3, 3, 11, 27, 1, 11, 361, 811, 599, 405, 6981, 5705, 16427, 0 }; + static ulong[] dim3578Kuo3Init = { 1, 3, 5, 9, 23, 61, 27, 7, 99, 495, 473, 477, 1733, 8043, 24843, 0 }; + static ulong[] dim3579Kuo3Init = { 1, 3, 7, 3, 21, 27, 71, 157, 357, 175, 829, 2411, 2305, 4669, 24933, 0 }; + static ulong[] dim3580Kuo3Init = { 1, 3, 5, 9, 21, 13, 121, 123, 119, 59, 429, 3757, 5833, 11263, 16013, 0 }; + static ulong[] dim3581Kuo3Init = { 1, 3, 7, 15, 11, 49, 7, 31, 375, 647, 413, 2979, 7731, 15953, 13637, 0 }; + static ulong[] dim3582Kuo3Init = { 1, 1, 1, 7, 9, 59, 121, 115, 239, 739, 121, 791, 769, 14223, 15127, 0 }; + static ulong[] dim3583Kuo3Init = { 1, 3, 7, 15, 17, 31, 69, 9, 189, 503, 565, 1373, 6467, 15291, 20621, 0 }; + static ulong[] dim3584Kuo3Init = { 1, 1, 5, 13, 31, 13, 71, 15, 197, 855, 1923, 2923, 2375, 7201, 29767, 0 }; + static ulong[] dim3585Kuo3Init = { 1, 1, 7, 7, 17, 13, 53, 131, 447, 337, 1059, 1365, 1269, 6035, 32075, 0 }; + static ulong[] dim3586Kuo3Init = { 1, 3, 5, 1, 15, 13, 43, 151, 207, 591, 717, 971, 5801, 10975, 3889, 0 }; + static ulong[] dim3587Kuo3Init = { 1, 3, 5, 7, 15, 45, 125, 193, 17, 605, 651, 1987, 577, 2835, 6801, 0 }; + static ulong[] dim3588Kuo3Init = { 1, 3, 5, 7, 31, 53, 83, 137, 399, 781, 135, 2863, 4901, 2861, 14025, 0 }; + static ulong[] dim3589Kuo3Init = { 1, 3, 3, 13, 29, 45, 99, 43, 121, 141, 753, 11, 4033, 2011, 7493, 0 }; + static ulong[] dim3590Kuo3Init = { 1, 3, 7, 11, 7, 39, 95, 199, 365, 9, 381, 3923, 3803, 6607, 30777, 0 }; + static ulong[] dim3591Kuo3Init = { 1, 3, 5, 13, 13, 49, 17, 25, 195, 269, 83, 2115, 4013, 8817, 28017, 0 }; + static ulong[] dim3592Kuo3Init = { 1, 1, 5, 15, 23, 49, 51, 49, 303, 439, 1353, 2385, 4547, 14405, 24115, 0 }; + static ulong[] dim3593Kuo3Init = { 1, 3, 1, 9, 9, 3, 87, 159, 449, 139, 461, 465, 5585, 9313, 6337, 0 }; + static ulong[] dim3594Kuo3Init = { 1, 1, 1, 9, 23, 17, 103, 167, 209, 179, 137, 57, 4265, 1743, 27575, 0 }; + static ulong[] dim3595Kuo3Init = { 1, 3, 1, 15, 15, 17, 7, 93, 173, 277, 497, 4047, 2205, 10403, 6319, 0 }; + static ulong[] dim3596Kuo3Init = { 1, 3, 1, 9, 13, 55, 37, 153, 69, 989, 1609, 1939, 1153, 5671, 16563, 0 }; + static ulong[] dim3597Kuo3Init = { 1, 1, 3, 15, 3, 41, 67, 41, 253, 293, 1495, 3935, 271, 12067, 3891, 0 }; + static ulong[] dim3598Kuo3Init = { 1, 3, 7, 15, 27, 21, 39, 41, 43, 713, 747, 995, 5389, 9811, 20489, 0 }; + static ulong[] dim3599Kuo3Init = { 1, 3, 7, 15, 11, 47, 41, 155, 301, 867, 1467, 1503, 893, 6819, 6923, 0 }; + static ulong[] dim3600Kuo3Init = { 1, 1, 1, 11, 29, 15, 57, 25, 219, 65, 997, 2109, 1921, 1771, 5997, 0 }; + static ulong[] dim3601Kuo3Init = { 1, 1, 7, 5, 11, 59, 89, 59, 319, 841, 1, 1339, 5635, 3141, 8735, 0 }; + static ulong[] dim3602Kuo3Init = { 1, 3, 3, 3, 17, 25, 13, 201, 37, 561, 1101, 1407, 3003, 99, 20189, 0 }; + static ulong[] dim3603Kuo3Init = { 1, 1, 3, 3, 9, 7, 65, 27, 203, 399, 555, 2605, 7951, 833, 6103, 0 }; + static ulong[] dim3604Kuo3Init = { 1, 3, 7, 15, 15, 25, 87, 215, 499, 935, 563, 1091, 6601, 12097, 22935, 0 }; + static ulong[] dim3605Kuo3Init = { 1, 3, 5, 9, 3, 21, 63, 51, 353, 187, 1609, 2321, 1743, 12665, 9313, 0 }; + static ulong[] dim3606Kuo3Init = { 1, 1, 3, 13, 21, 7, 101, 27, 15, 467, 833, 2439, 3559, 10509, 16327, 0 }; + static ulong[] dim3607Kuo3Init = { 1, 3, 5, 1, 21, 37, 107, 77, 147, 107, 1493, 969, 7895, 14293, 14557, 0 }; + static ulong[] dim3608Kuo3Init = { 1, 1, 3, 13, 1, 13, 57, 183, 303, 93, 1755, 845, 6857, 11061, 13661, 0 }; + static ulong[] dim3609Kuo3Init = { 1, 1, 7, 13, 11, 23, 25, 77, 75, 279, 1375, 1235, 3225, 8143, 4055, 0 }; + static ulong[] dim3610Kuo3Init = { 1, 3, 1, 11, 5, 1, 85, 1, 221, 831, 1673, 633, 4837, 14409, 28993, 0 }; + static ulong[] dim3611Kuo3Init = { 1, 1, 7, 7, 23, 33, 51, 181, 201, 947, 697, 3417, 6169, 757, 9343, 0 }; + static ulong[] dim3612Kuo3Init = { 1, 1, 3, 11, 21, 51, 45, 81, 447, 17, 789, 3773, 3647, 5913, 25419, 0 }; + static ulong[] dim3613Kuo3Init = { 1, 1, 5, 11, 29, 39, 33, 67, 157, 583, 653, 43, 4441, 9571, 9895, 0 }; + static ulong[] dim3614Kuo3Init = { 1, 3, 3, 13, 21, 13, 53, 3, 135, 61, 1975, 2107, 1395, 11395, 1741, 0 }; + static ulong[] dim3615Kuo3Init = { 1, 1, 5, 3, 21, 29, 35, 25, 495, 783, 407, 1765, 1959, 3975, 23157, 0 }; + static ulong[] dim3616Kuo3Init = { 1, 1, 7, 7, 1, 57, 107, 73, 483, 945, 73, 2757, 7211, 1053, 7625, 0 }; + static ulong[] dim3617Kuo3Init = { 1, 1, 3, 13, 25, 53, 61, 117, 231, 261, 901, 1823, 3401, 8399, 17953, 0 }; + static ulong[] dim3618Kuo3Init = { 1, 1, 7, 15, 29, 13, 55, 51, 469, 457, 1529, 2381, 6017, 10953, 18639, 0 }; + static ulong[] dim3619Kuo3Init = { 1, 1, 1, 9, 21, 17, 45, 1, 457, 821, 367, 453, 1015, 1017, 21745, 0 }; + static ulong[] dim3620Kuo3Init = { 1, 3, 1, 9, 15, 21, 121, 149, 417, 287, 897, 2595, 327, 16157, 11971, 0 }; + static ulong[] dim3621Kuo3Init = { 1, 3, 7, 15, 17, 29, 41, 191, 475, 457, 1487, 1885, 6959, 10869, 7435, 0 }; + static ulong[] dim3622Kuo3Init = { 1, 1, 5, 3, 9, 57, 29, 41, 81, 179, 1023, 3683, 4313, 4849, 14211, 0 }; + static ulong[] dim3623Kuo3Init = { 1, 3, 1, 15, 15, 3, 123, 5, 201, 387, 1175, 1285, 4367, 459, 7771, 0 }; + static ulong[] dim3624Kuo3Init = { 1, 1, 1, 3, 25, 47, 113, 41, 299, 217, 495, 565, 2337, 9877, 28731, 0 }; + static ulong[] dim3625Kuo3Init = { 1, 1, 5, 5, 17, 11, 119, 187, 389, 19, 1947, 2607, 1119, 7677, 1561, 0 }; + static ulong[] dim3626Kuo3Init = { 1, 1, 7, 9, 23, 59, 63, 175, 103, 211, 125, 3465, 2535, 14899, 1239, 0 }; + static ulong[] dim3627Kuo3Init = { 1, 1, 3, 11, 17, 37, 111, 225, 51, 455, 1911, 1579, 841, 11451, 31521, 0 }; + static ulong[] dim3628Kuo3Init = { 1, 1, 3, 15, 13, 1, 63, 33, 113, 83, 513, 3903, 5399, 5855, 11151, 0 }; + static ulong[] dim3629Kuo3Init = { 1, 3, 7, 7, 1, 15, 55, 181, 453, 15, 333, 185, 2031, 14809, 6187, 0 }; + static ulong[] dim3630Kuo3Init = { 1, 1, 5, 13, 27, 37, 41, 197, 191, 365, 1863, 559, 7731, 821, 8477, 0 }; + static ulong[] dim3631Kuo3Init = { 1, 1, 1, 15, 19, 53, 91, 119, 185, 515, 1041, 3933, 601, 2971, 25445, 0 }; + static ulong[] dim3632Kuo3Init = { 1, 3, 5, 15, 25, 57, 11, 79, 299, 5, 1433, 2811, 1807, 4057, 3283, 0 }; + static ulong[] dim3633Kuo3Init = { 1, 1, 5, 13, 17, 17, 41, 157, 357, 981, 1323, 1189, 1249, 2857, 10163, 0 }; + static ulong[] dim3634Kuo3Init = { 1, 3, 3, 3, 15, 47, 109, 249, 37, 403, 1611, 281, 2521, 14179, 3095, 0 }; + static ulong[] dim3635Kuo3Init = { 1, 3, 5, 7, 23, 25, 5, 83, 503, 203, 1961, 1915, 5111, 4265, 27243, 0 }; + static ulong[] dim3636Kuo3Init = { 1, 1, 3, 1, 7, 29, 43, 19, 139, 487, 1847, 1569, 643, 15999, 21539, 0 }; + static ulong[] dim3637Kuo3Init = { 1, 1, 7, 3, 3, 7, 31, 217, 103, 127, 1389, 87, 7911, 12751, 11907, 0 }; + static ulong[] dim3638Kuo3Init = { 1, 3, 1, 9, 31, 25, 27, 69, 477, 471, 1375, 2485, 4221, 175, 16841, 0 }; + static ulong[] dim3639Kuo3Init = { 1, 3, 1, 15, 9, 31, 125, 233, 175, 649, 641, 3751, 7857, 3849, 8859, 0 }; + static ulong[] dim3640Kuo3Init = { 1, 1, 1, 3, 25, 7, 31, 197, 435, 453, 1715, 3187, 6131, 12375, 29367, 0 }; + static ulong[] dim3641Kuo3Init = { 1, 3, 5, 15, 9, 41, 75, 107, 205, 919, 1709, 2515, 7143, 10433, 6179, 0 }; + static ulong[] dim3642Kuo3Init = { 1, 1, 5, 1, 27, 11, 107, 177, 17, 675, 677, 547, 7101, 7789, 29465, 0 }; + static ulong[] dim3643Kuo3Init = { 1, 3, 5, 3, 9, 7, 123, 209, 443, 221, 35, 4045, 2871, 16167, 31745, 0 }; + static ulong[] dim3644Kuo3Init = { 1, 1, 7, 1, 15, 59, 127, 173, 163, 151, 813, 967, 1165, 4147, 29355, 0 }; + static ulong[] dim3645Kuo3Init = { 1, 3, 7, 13, 21, 17, 33, 35, 87, 897, 393, 2205, 2885, 7327, 28521, 0 }; + static ulong[] dim3646Kuo3Init = { 1, 1, 5, 1, 1, 47, 67, 87, 371, 217, 1943, 1277, 27, 7205, 9751, 0 }; + static ulong[] dim3647Kuo3Init = { 1, 1, 5, 13, 1, 25, 51, 103, 61, 279, 1151, 3745, 4159, 1895, 15869, 0 }; + static ulong[] dim3648Kuo3Init = { 1, 3, 7, 9, 5, 59, 29, 83, 415, 851, 1415, 3719, 4345, 13897, 22409, 0 }; + static ulong[] dim3649Kuo3Init = { 1, 1, 1, 7, 29, 19, 7, 23, 87, 1, 2035, 2287, 4985, 1371, 9323, 0 }; + static ulong[] dim3650Kuo3Init = { 1, 1, 3, 1, 17, 33, 55, 49, 285, 953, 131, 3679, 3811, 6125, 18827, 0 }; + static ulong[] dim3651Kuo3Init = { 1, 1, 3, 3, 9, 51, 61, 119, 163, 829, 1579, 2047, 909, 3499, 26535, 0 }; + static ulong[] dim3652Kuo3Init = { 1, 3, 3, 3, 27, 49, 127, 239, 193, 359, 695, 1471, 6481, 3549, 22337, 0 }; + static ulong[] dim3653Kuo3Init = { 1, 3, 1, 5, 29, 7, 83, 57, 509, 15, 391, 2287, 1023, 13993, 6073, 0 }; + static ulong[] dim3654Kuo3Init = { 1, 1, 5, 15, 3, 21, 23, 217, 147, 511, 1817, 2425, 2347, 1433, 10625, 0 }; + static ulong[] dim3655Kuo3Init = { 1, 1, 7, 13, 23, 21, 29, 197, 189, 367, 619, 1305, 5463, 7099, 3307, 0 }; + static ulong[] dim3656Kuo3Init = { 1, 3, 1, 1, 27, 7, 33, 221, 107, 85, 633, 3325, 3109, 16377, 25633, 0 }; + static ulong[] dim3657Kuo3Init = { 1, 1, 3, 11, 13, 59, 57, 251, 321, 45, 451, 237, 4499, 10549, 16473, 0 }; + static ulong[] dim3658Kuo3Init = { 1, 1, 7, 15, 11, 39, 17, 85, 233, 865, 1285, 1771, 2913, 7729, 3815, 0 }; + static ulong[] dim3659Kuo3Init = { 1, 1, 5, 15, 9, 1, 51, 47, 113, 917, 1007, 1883, 4087, 4061, 27965, 0 }; + static ulong[] dim3660Kuo3Init = { 1, 1, 5, 15, 29, 33, 123, 183, 347, 99, 1215, 893, 7555, 6835, 1729, 0 }; + static ulong[] dim3661Kuo3Init = { 1, 1, 5, 13, 5, 25, 7, 255, 315, 559, 51, 899, 7165, 2021, 17413, 0 }; + static ulong[] dim3662Kuo3Init = { 1, 3, 3, 7, 3, 19, 7, 89, 77, 599, 1021, 3269, 3615, 10023, 31043, 0 }; + static ulong[] dim3663Kuo3Init = { 1, 1, 7, 3, 9, 7, 119, 199, 315, 835, 1401, 1547, 609, 9015, 27589, 0 }; + static ulong[] dim3664Kuo3Init = { 1, 3, 3, 15, 7, 33, 109, 239, 329, 213, 215, 1989, 1495, 7765, 3123, 0 }; + static ulong[] dim3665Kuo3Init = { 1, 1, 1, 13, 31, 23, 79, 181, 211, 189, 1, 2103, 4247, 7209, 3733, 0 }; + static ulong[] dim3666Kuo3Init = { 1, 3, 3, 7, 19, 31, 59, 103, 291, 877, 459, 3893, 4303, 10033, 31859, 0 }; + static ulong[] dim3667Kuo3Init = { 1, 3, 5, 11, 11, 1, 11, 163, 477, 925, 659, 143, 3705, 11335, 23667, 53273, 0 }; + static ulong[] dim3668Kuo3Init = { 1, 1, 7, 11, 21, 29, 119, 195, 303, 185, 1353, 1285, 2525, 11801, 10663, 49201, 0 }; + static ulong[] dim3669Kuo3Init = { 1, 1, 7, 3, 29, 41, 115, 115, 389, 763, 1625, 691, 3425, 6451, 3355, 26967, 0 }; + static ulong[] dim3670Kuo3Init = { 1, 1, 1, 9, 1, 3, 71, 129, 25, 231, 1849, 2087, 3253, 13151, 17039, 21893, 0 }; + static ulong[] dim3671Kuo3Init = { 1, 3, 5, 9, 11, 57, 99, 187, 245, 965, 1437, 3431, 4657, 12581, 14883, 54985, 0 }; + static ulong[] dim3672Kuo3Init = { 1, 3, 5, 3, 27, 55, 41, 203, 261, 271, 327, 71, 3659, 4517, 24071, 56297, 0 }; + static ulong[] dim3673Kuo3Init = { 1, 1, 5, 1, 13, 63, 37, 109, 437, 611, 649, 1123, 4365, 10259, 26507, 60715, 0 }; + static ulong[] dim3674Kuo3Init = { 1, 1, 5, 9, 21, 51, 113, 95, 221, 157, 843, 1429, 781, 13193, 16453, 26883, 0 }; + static ulong[] dim3675Kuo3Init = { 1, 3, 3, 9, 29, 15, 13, 5, 441, 7, 139, 773, 1495, 2283, 31549, 4105, 0 }; + static ulong[] dim3676Kuo3Init = { 1, 1, 5, 9, 27, 59, 51, 51, 211, 871, 1971, 1213, 7459, 14001, 32175, 53975, 0 }; + static ulong[] dim3677Kuo3Init = { 1, 3, 5, 3, 3, 29, 47, 131, 263, 879, 731, 1063, 3647, 8729, 5407, 4001, 0 }; + static ulong[] dim3678Kuo3Init = { 1, 1, 3, 5, 21, 45, 93, 143, 443, 295, 1683, 2335, 4213, 6297, 26611, 56661, 0 }; + static ulong[] dim3679Kuo3Init = { 1, 1, 5, 3, 9, 63, 97, 143, 101, 579, 435, 3339, 7333, 6267, 1589, 30997, 0 }; + static ulong[] dim3680Kuo3Init = { 1, 1, 3, 3, 31, 51, 81, 125, 285, 879, 1377, 107, 827, 7185, 27265, 54517, 0 }; + static ulong[] dim3681Kuo3Init = { 1, 1, 3, 11, 9, 9, 121, 167, 195, 625, 1167, 1533, 3697, 7545, 27799, 11613, 0 }; + static ulong[] dim3682Kuo3Init = { 1, 3, 7, 7, 21, 55, 65, 63, 355, 525, 1441, 3057, 1779, 1613, 6277, 37655, 0 }; + static ulong[] dim3683Kuo3Init = { 1, 1, 7, 15, 9, 61, 7, 211, 11, 955, 499, 2795, 4017, 1459, 4323, 1453, 0 }; + static ulong[] dim3684Kuo3Init = { 1, 1, 1, 9, 25, 17, 75, 219, 383, 721, 1661, 3325, 5917, 11423, 19265, 41063, 0 }; + static ulong[] dim3685Kuo3Init = { 1, 3, 1, 7, 15, 39, 93, 9, 463, 611, 547, 173, 4179, 4641, 28201, 32139, 0 }; + static ulong[] dim3686Kuo3Init = { 1, 1, 5, 7, 29, 51, 41, 157, 93, 289, 935, 3299, 2103, 4371, 15485, 62685, 0 }; + static ulong[] dim3687Kuo3Init = { 1, 3, 3, 15, 31, 49, 93, 205, 13, 551, 1809, 4051, 5481, 2693, 6615, 18123, 0 }; + static ulong[] dim3688Kuo3Init = { 1, 3, 7, 3, 1, 41, 27, 105, 469, 759, 625, 1579, 4253, 7435, 20545, 4365, 0 }; + static ulong[] dim3689Kuo3Init = { 1, 3, 7, 11, 17, 45, 111, 91, 357, 651, 5, 937, 3199, 6485, 21145, 35085, 0 }; + static ulong[] dim3690Kuo3Init = { 1, 3, 5, 1, 7, 21, 33, 213, 399, 735, 1923, 1047, 2765, 11057, 19007, 58345, 0 }; + static ulong[] dim3691Kuo3Init = { 1, 3, 7, 13, 31, 57, 113, 81, 75, 985, 479, 1353, 1041, 13489, 12011, 52749, 0 }; + static ulong[] dim3692Kuo3Init = { 1, 1, 1, 9, 23, 23, 83, 167, 473, 471, 171, 3303, 7167, 1109, 29263, 30047, 0 }; + static ulong[] dim3693Kuo3Init = { 1, 3, 7, 15, 11, 63, 57, 73, 49, 921, 457, 1683, 4447, 14549, 5819, 18291, 0 }; + static ulong[] dim3694Kuo3Init = { 1, 3, 5, 5, 27, 1, 127, 233, 509, 229, 1553, 3875, 2243, 16005, 17985, 28437, 0 }; + static ulong[] dim3695Kuo3Init = { 1, 1, 1, 15, 7, 27, 75, 191, 433, 585, 1659, 3373, 4067, 55, 11095, 37179, 0 }; + static ulong[] dim3696Kuo3Init = { 1, 1, 7, 15, 27, 31, 21, 105, 95, 357, 2019, 2193, 741, 8509, 349, 24797, 0 }; + static ulong[] dim3697Kuo3Init = { 1, 1, 1, 15, 1, 51, 77, 139, 205, 81, 1849, 1687, 1597, 1531, 115, 50163, 0 }; + static ulong[] dim3698Kuo3Init = { 1, 3, 5, 5, 7, 61, 113, 111, 69, 443, 179, 2955, 7, 13237, 26787, 33917, 0 }; + static ulong[] dim3699Kuo3Init = { 1, 3, 5, 5, 21, 37, 11, 209, 177, 433, 1423, 1629, 5807, 4655, 19377, 58963, 0 }; + static ulong[] dim3700Kuo3Init = { 1, 3, 5, 1, 11, 29, 107, 17, 135, 801, 1441, 3119, 4573, 8903, 11267, 2845, 0 }; + static ulong[] dim3701Kuo3Init = { 1, 1, 3, 3, 21, 41, 115, 19, 473, 447, 1879, 4095, 2743, 10007, 5751, 36845, 0 }; + static ulong[] dim3702Kuo3Init = { 1, 1, 3, 5, 19, 13, 85, 131, 85, 849, 1179, 1919, 3631, 13807, 10467, 24081, 0 }; + static ulong[] dim3703Kuo3Init = { 1, 1, 5, 13, 5, 17, 21, 125, 169, 369, 761, 1419, 7795, 9041, 7613, 6125, 0 }; + static ulong[] dim3704Kuo3Init = { 1, 3, 7, 9, 21, 53, 119, 55, 97, 563, 1531, 847, 3709, 10573, 18469, 29625, 0 }; + static ulong[] dim3705Kuo3Init = { 1, 1, 5, 7, 23, 15, 99, 251, 415, 55, 563, 3535, 8017, 7771, 23601, 52955, 0 }; + static ulong[] dim3706Kuo3Init = { 1, 3, 5, 15, 29, 11, 73, 251, 139, 215, 825, 1735, 7859, 10171, 17351, 24971, 0 }; + static ulong[] dim3707Kuo3Init = { 1, 3, 1, 1, 21, 21, 21, 21, 107, 901, 1321, 647, 7521, 5505, 965, 36217, 0 }; + static ulong[] dim3708Kuo3Init = { 1, 1, 5, 15, 9, 39, 87, 173, 201, 705, 563, 3479, 437, 1733, 18001, 39161, 0 }; + static ulong[] dim3709Kuo3Init = { 1, 3, 7, 15, 31, 31, 89, 119, 471, 633, 249, 187, 3735, 4045, 1611, 10045, 0 }; + static ulong[] dim3710Kuo3Init = { 1, 3, 5, 1, 7, 31, 117, 249, 175, 515, 1825, 3417, 307, 10909, 4453, 43833, 0 }; + static ulong[] dim3711Kuo3Init = { 1, 3, 1, 9, 1, 21, 59, 103, 243, 105, 2037, 1759, 689, 15389, 16981, 35545, 0 }; + static ulong[] dim3712Kuo3Init = { 1, 1, 7, 1, 13, 15, 105, 89, 463, 513, 191, 1489, 5239, 3723, 20511, 52139, 0 }; + static ulong[] dim3713Kuo3Init = { 1, 3, 5, 1, 1, 25, 71, 89, 167, 1009, 829, 2267, 375, 10217, 31677, 58309, 0 }; + static ulong[] dim3714Kuo3Init = { 1, 3, 5, 1, 31, 19, 21, 225, 331, 621, 1047, 3385, 5247, 1763, 19985, 9013, 0 }; + static ulong[] dim3715Kuo3Init = { 1, 3, 1, 1, 5, 19, 69, 11, 15, 361, 617, 823, 2645, 207, 18775, 60509, 0 }; + static ulong[] dim3716Kuo3Init = { 1, 3, 3, 13, 15, 1, 37, 3, 249, 277, 1729, 3599, 115, 9557, 12865, 6257, 0 }; + static ulong[] dim3717Kuo3Init = { 1, 3, 7, 11, 15, 51, 21, 147, 23, 527, 167, 1673, 2299, 923, 22755, 48627, 0 }; + static ulong[] dim3718Kuo3Init = { 1, 3, 7, 1, 17, 55, 23, 1, 213, 479, 287, 2741, 7255, 4571, 6581, 57509, 0 }; + static ulong[] dim3719Kuo3Init = { 1, 3, 5, 7, 15, 49, 13, 149, 103, 513, 1977, 2275, 5535, 7867, 16305, 24713, 0 }; + static ulong[] dim3720Kuo3Init = { 1, 1, 7, 1, 29, 41, 69, 211, 131, 87, 859, 3631, 611, 11463, 18029, 38771, 0 }; + static ulong[] dim3721Kuo3Init = { 1, 3, 5, 11, 17, 23, 37, 149, 271, 547, 1129, 3615, 6647, 7023, 103, 29257, 0 }; + static ulong[] dim3722Kuo3Init = { 1, 1, 7, 13, 1, 55, 71, 51, 249, 141, 1937, 3869, 5897, 13227, 22279, 11733, 0 }; + static ulong[] dim3723Kuo3Init = { 1, 1, 5, 13, 1, 29, 85, 255, 93, 741, 687, 2195, 519, 8235, 21305, 19681, 0 }; + static ulong[] dim3724Kuo3Init = { 1, 1, 7, 5, 13, 17, 103, 65, 211, 603, 543, 3629, 235, 7337, 27477, 2735, 0 }; + static ulong[] dim3725Kuo3Init = { 1, 3, 1, 1, 17, 63, 75, 183, 107, 583, 1849, 545, 7987, 13679, 22797, 40095, 0 }; + static ulong[] dim3726Kuo3Init = { 1, 1, 5, 1, 31, 13, 33, 21, 479, 879, 1223, 3925, 3003, 9975, 23465, 27775, 0 }; + static ulong[] dim3727Kuo3Init = { 1, 1, 3, 1, 7, 23, 65, 107, 239, 867, 1245, 1549, 5981, 4677, 3761, 61449, 0 }; + static ulong[] dim3728Kuo3Init = { 1, 3, 7, 9, 5, 31, 25, 53, 59, 79, 1545, 3721, 6979, 16351, 7305, 41653, 0 }; + static ulong[] dim3729Kuo3Init = { 1, 1, 1, 13, 27, 53, 9, 7, 159, 353, 121, 2525, 8049, 12997, 3933, 19835, 0 }; + static ulong[] dim3730Kuo3Init = { 1, 3, 3, 15, 1, 33, 127, 163, 399, 125, 1869, 569, 3853, 4819, 4403, 34367, 0 }; + static ulong[] dim3731Kuo3Init = { 1, 3, 5, 15, 11, 23, 21, 95, 329, 937, 689, 3731, 1157, 9613, 12593, 58609, 0 }; + static ulong[] dim3732Kuo3Init = { 1, 3, 5, 7, 13, 23, 7, 237, 413, 139, 523, 3517, 6829, 17, 17673, 57889, 0 }; + static ulong[] dim3733Kuo3Init = { 1, 1, 3, 3, 3, 49, 63, 87, 147, 359, 2027, 1513, 3933, 13911, 25459, 11391, 0 }; + static ulong[] dim3734Kuo3Init = { 1, 1, 1, 5, 23, 17, 81, 249, 487, 71, 395, 3635, 4773, 14909, 13523, 32617, 0 }; + static ulong[] dim3735Kuo3Init = { 1, 1, 7, 5, 19, 39, 13, 91, 475, 899, 353, 3275, 4161, 2203, 20375, 14795, 0 }; + static ulong[] dim3736Kuo3Init = { 1, 3, 3, 11, 17, 15, 117, 145, 223, 393, 1267, 1089, 6745, 10485, 20385, 25991, 0 }; + static ulong[] dim3737Kuo3Init = { 1, 1, 7, 7, 27, 21, 57, 237, 405, 513, 1411, 2791, 1685, 11529, 2115, 36631, 0 }; + static ulong[] dim3738Kuo3Init = { 1, 1, 1, 13, 5, 17, 111, 55, 277, 639, 1541, 2347, 1119, 10101, 8533, 15383, 0 }; + static ulong[] dim3739Kuo3Init = { 1, 3, 5, 9, 1, 47, 123, 39, 473, 471, 299, 3785, 6589, 9415, 29193, 24367, 0 }; + static ulong[] dim3740Kuo3Init = { 1, 3, 3, 9, 13, 17, 9, 131, 9, 309, 1529, 3721, 5927, 6699, 17439, 60313, 0 }; + static ulong[] dim3741Kuo3Init = { 1, 3, 3, 7, 17, 3, 93, 33, 287, 47, 1295, 1021, 4267, 403, 31111, 5399, 0 }; + static ulong[] dim3742Kuo3Init = { 1, 3, 5, 3, 29, 27, 73, 117, 123, 1007, 2003, 2921, 4875, 2043, 12221, 57865, 0 }; + static ulong[] dim3743Kuo3Init = { 1, 3, 1, 15, 15, 51, 31, 217, 429, 1009, 1761, 389, 4859, 13667, 17955, 29493, 0 }; + static ulong[] dim3744Kuo3Init = { 1, 3, 3, 7, 25, 11, 65, 109, 241, 421, 363, 2641, 781, 711, 5363, 9603, 0 }; + static ulong[] dim3745Kuo3Init = { 1, 3, 1, 11, 1, 41, 99, 181, 103, 503, 1887, 1917, 4791, 6405, 27701, 62353, 0 }; + static ulong[] dim3746Kuo3Init = { 1, 1, 5, 7, 25, 43, 23, 49, 333, 205, 903, 3915, 2899, 2719, 7887, 17313, 0 }; + static ulong[] dim3747Kuo3Init = { 1, 3, 5, 3, 27, 19, 59, 125, 409, 979, 1203, 1737, 5269, 14755, 32173, 2127, 0 }; + static ulong[] dim3748Kuo3Init = { 1, 1, 7, 11, 29, 19, 73, 63, 81, 717, 933, 2939, 2863, 5993, 25953, 31733, 0 }; + static ulong[] dim3749Kuo3Init = { 1, 3, 7, 5, 11, 19, 55, 223, 51, 661, 547, 4055, 4849, 3009, 22303, 25, 0 }; + static ulong[] dim3750Kuo3Init = { 1, 1, 7, 5, 7, 3, 55, 167, 207, 819, 791, 3813, 2455, 1305, 4661, 51189, 0 }; + static ulong[] dim3751Kuo3Init = { 1, 3, 7, 5, 29, 1, 31, 191, 267, 705, 181, 3091, 4725, 12351, 31521, 56163, 0 }; + static ulong[] dim3752Kuo3Init = { 1, 3, 3, 1, 19, 11, 27, 215, 249, 713, 723, 143, 2179, 11075, 22059, 62629, 0 }; + static ulong[] dim3753Kuo3Init = { 1, 1, 3, 3, 23, 45, 101, 25, 115, 353, 565, 3491, 285, 2133, 27117, 42699, 0 }; + static ulong[] dim3754Kuo3Init = { 1, 1, 5, 7, 1, 51, 113, 165, 157, 431, 1043, 3003, 5971, 15699, 20799, 13989, 0 }; + static ulong[] dim3755Kuo3Init = { 1, 3, 7, 5, 23, 21, 121, 85, 69, 169, 1761, 1023, 5501, 1255, 25683, 48699, 0 }; + static ulong[] dim3756Kuo3Init = { 1, 3, 5, 13, 21, 31, 95, 5, 237, 607, 1525, 763, 4725, 4221, 22769, 40899, 0 }; + static ulong[] dim3757Kuo3Init = { 1, 1, 5, 1, 1, 9, 105, 225, 171, 999, 547, 2331, 4389, 12847, 18107, 11939, 0 }; + static ulong[] dim3758Kuo3Init = { 1, 3, 5, 5, 15, 47, 73, 237, 463, 501, 1611, 2259, 1679, 1709, 24527, 53529, 0 }; + static ulong[] dim3759Kuo3Init = { 1, 3, 1, 7, 21, 27, 27, 25, 463, 73, 2021, 3899, 487, 667, 5063, 5017, 0 }; + static ulong[] dim3760Kuo3Init = { 1, 1, 3, 3, 15, 3, 87, 145, 45, 473, 1455, 1857, 2379, 4805, 10557, 27485, 0 }; + static ulong[] dim3761Kuo3Init = { 1, 1, 3, 13, 17, 15, 13, 237, 177, 835, 1019, 975, 7085, 2871, 16473, 23693, 0 }; + static ulong[] dim3762Kuo3Init = { 1, 1, 1, 1, 13, 61, 31, 197, 127, 213, 173, 3751, 3819, 2899, 22675, 23095, 0 }; + static ulong[] dim3763Kuo3Init = { 1, 3, 1, 15, 7, 63, 89, 95, 497, 1021, 1751, 1379, 3809, 9493, 7941, 35217, 0 }; + static ulong[] dim3764Kuo3Init = { 1, 3, 7, 3, 7, 63, 33, 155, 171, 651, 773, 1861, 4225, 1081, 29141, 53413, 0 }; + static ulong[] dim3765Kuo3Init = { 1, 1, 3, 7, 15, 27, 31, 183, 377, 341, 205, 1817, 6185, 13047, 19585, 1533, 0 }; + static ulong[] dim3766Kuo3Init = { 1, 1, 1, 7, 27, 23, 23, 117, 463, 73, 529, 1727, 6989, 15911, 11783, 1011, 0 }; + static ulong[] dim3767Kuo3Init = { 1, 1, 3, 7, 9, 43, 55, 191, 203, 471, 515, 1315, 7911, 14281, 4767, 15725, 0 }; + static ulong[] dim3768Kuo3Init = { 1, 1, 1, 15, 23, 13, 61, 231, 423, 79, 421, 1619, 7951, 15541, 20985, 42181, 0 }; + static ulong[] dim3769Kuo3Init = { 1, 1, 7, 3, 31, 29, 81, 125, 217, 643, 449, 477, 4521, 2973, 13295, 943, 0 }; + static ulong[] dim3770Kuo3Init = { 1, 3, 5, 3, 15, 37, 81, 167, 11, 53, 1455, 3719, 1777, 7253, 16365, 17021, 0 }; + static ulong[] dim3771Kuo3Init = { 1, 3, 7, 5, 25, 39, 95, 189, 453, 697, 1761, 3837, 4697, 8429, 10455, 17239, 0 }; + static ulong[] dim3772Kuo3Init = { 1, 1, 3, 5, 13, 43, 127, 251, 497, 475, 105, 3137, 5927, 7569, 5645, 25315, 0 }; + static ulong[] dim3773Kuo3Init = { 1, 3, 7, 9, 1, 23, 15, 129, 165, 887, 1719, 2343, 1663, 1153, 25889, 10961, 0 }; + static ulong[] dim3774Kuo3Init = { 1, 3, 1, 13, 29, 7, 37, 147, 369, 697, 481, 1845, 4499, 4885, 3201, 6773, 0 }; + static ulong[] dim3775Kuo3Init = { 1, 1, 1, 3, 25, 23, 49, 149, 435, 561, 1233, 2821, 3121, 2825, 21237, 47491, 0 }; + static ulong[] dim3776Kuo3Init = { 1, 1, 3, 3, 3, 59, 85, 205, 89, 423, 701, 1179, 4875, 3351, 17863, 35111, 0 }; + static ulong[] dim3777Kuo3Init = { 1, 1, 3, 1, 5, 51, 105, 85, 411, 561, 155, 2809, 63, 8711, 12523, 28827, 0 }; + static ulong[] dim3778Kuo3Init = { 1, 3, 7, 15, 29, 43, 103, 153, 105, 819, 1861, 1725, 2225, 1821, 25551, 65399, 0 }; + static ulong[] dim3779Kuo3Init = { 1, 1, 1, 13, 7, 51, 71, 177, 49, 605, 1375, 737, 7325, 9597, 10239, 64761, 0 }; + static ulong[] dim3780Kuo3Init = { 1, 3, 1, 3, 5, 15, 117, 187, 19, 149, 119, 3375, 3203, 6827, 22073, 35757, 0 }; + static ulong[] dim3781Kuo3Init = { 1, 1, 1, 5, 13, 25, 7, 157, 23, 741, 465, 2225, 6697, 14371, 25115, 29699, 0 }; + static ulong[] dim3782Kuo3Init = { 1, 3, 7, 13, 5, 29, 95, 209, 123, 947, 1631, 423, 1217, 12353, 7561, 1415, 0 }; + static ulong[] dim3783Kuo3Init = { 1, 3, 7, 11, 3, 17, 63, 65, 371, 355, 1793, 1197, 2375, 3629, 13283, 41727, 0 }; + static ulong[] dim3784Kuo3Init = { 1, 3, 1, 13, 5, 19, 103, 85, 271, 123, 1939, 2741, 5105, 8693, 4291, 49389, 0 }; + static ulong[] dim3785Kuo3Init = { 1, 3, 3, 1, 31, 1, 57, 13, 265, 941, 1169, 3639, 5317, 10565, 30263, 64329, 0 }; + static ulong[] dim3786Kuo3Init = { 1, 1, 7, 13, 7, 9, 115, 111, 301, 365, 1, 3093, 3209, 2607, 5749, 17047, 0 }; + static ulong[] dim3787Kuo3Init = { 1, 3, 1, 1, 5, 41, 113, 73, 407, 427, 1271, 1361, 4869, 14845, 29515, 38769, 0 }; + static ulong[] dim3788Kuo3Init = { 1, 3, 5, 13, 19, 47, 77, 27, 57, 43, 1633, 197, 5465, 14735, 25187, 38621, 0 }; + static ulong[] dim3789Kuo3Init = { 1, 3, 1, 5, 11, 55, 23, 213, 495, 929, 697, 2829, 4185, 8321, 12673, 22759, 0 }; + static ulong[] dim3790Kuo3Init = { 1, 1, 3, 9, 17, 29, 7, 41, 75, 139, 1165, 3387, 6015, 3679, 8353, 29981, 0 }; + static ulong[] dim3791Kuo3Init = { 1, 3, 3, 1, 21, 47, 95, 163, 121, 877, 245, 3947, 3839, 15097, 4695, 26037, 0 }; + static ulong[] dim3792Kuo3Init = { 1, 1, 7, 11, 19, 19, 7, 93, 77, 887, 153, 237, 543, 2631, 22023, 17207, 0 }; + static ulong[] dim3793Kuo3Init = { 1, 1, 7, 13, 7, 23, 39, 181, 107, 313, 131, 3799, 981, 11145, 10969, 28733, 0 }; + static ulong[] dim3794Kuo3Init = { 1, 3, 1, 11, 15, 45, 105, 187, 457, 41, 1739, 3229, 4289, 107, 2685, 15601, 0 }; + static ulong[] dim3795Kuo3Init = { 1, 1, 1, 9, 15, 53, 11, 87, 421, 733, 1031, 121, 2413, 3383, 6525, 35781, 0 }; + static ulong[] dim3796Kuo3Init = { 1, 3, 3, 11, 23, 15, 81, 13, 215, 573, 1953, 379, 6857, 2137, 2599, 29589, 0 }; + static ulong[] dim3797Kuo3Init = { 1, 3, 3, 9, 29, 17, 25, 121, 291, 317, 81, 4073, 7111, 5045, 32685, 21527, 0 }; + static ulong[] dim3798Kuo3Init = { 1, 1, 3, 11, 31, 53, 115, 179, 81, 919, 955, 2301, 647, 11433, 17761, 8187, 0 }; + static ulong[] dim3799Kuo3Init = { 1, 1, 5, 9, 17, 15, 105, 55, 303, 505, 223, 1757, 3567, 9079, 29415, 37845, 0 }; + static ulong[] dim3800Kuo3Init = { 1, 3, 7, 1, 23, 33, 33, 199, 119, 911, 349, 3641, 5339, 12803, 27979, 17951, 0 }; + static ulong[] dim3801Kuo3Init = { 1, 1, 3, 13, 15, 53, 43, 25, 31, 609, 49, 1307, 6477, 2173, 32245, 34123, 0 }; + static ulong[] dim3802Kuo3Init = { 1, 3, 1, 13, 11, 35, 55, 85, 381, 733, 1407, 2821, 1547, 9843, 13861, 13529, 0 }; + static ulong[] dim3803Kuo3Init = { 1, 1, 1, 5, 13, 11, 35, 255, 421, 673, 387, 3429, 3137, 13619, 28689, 11145, 0 }; + static ulong[] dim3804Kuo3Init = { 1, 3, 3, 9, 23, 61, 81, 25, 163, 595, 769, 3455, 5371, 9711, 14937, 34383, 0 }; + static ulong[] dim3805Kuo3Init = { 1, 3, 7, 13, 11, 11, 115, 93, 307, 807, 1667, 483, 4815, 6305, 5197, 281, 0 }; + static ulong[] dim3806Kuo3Init = { 1, 1, 7, 15, 29, 31, 113, 129, 483, 369, 855, 643, 7503, 1699, 20681, 51497, 0 }; + static ulong[] dim3807Kuo3Init = { 1, 1, 3, 9, 3, 41, 7, 255, 171, 1003, 559, 775, 5333, 11563, 22473, 44299, 0 }; + static ulong[] dim3808Kuo3Init = { 1, 1, 5, 15, 23, 51, 101, 161, 433, 757, 713, 403, 1789, 5353, 28901, 14249, 0 }; + static ulong[] dim3809Kuo3Init = { 1, 3, 7, 9, 27, 5, 9, 71, 47, 287, 369, 653, 7595, 10127, 12547, 34119, 0 }; + static ulong[] dim3810Kuo3Init = { 1, 1, 3, 7, 5, 33, 19, 183, 497, 209, 1999, 2897, 2553, 633, 7413, 7847, 0 }; + static ulong[] dim3811Kuo3Init = { 1, 3, 3, 13, 27, 19, 73, 181, 15, 297, 1485, 2167, 5033, 11191, 24999, 30177, 0 }; + static ulong[] dim3812Kuo3Init = { 1, 1, 1, 13, 5, 47, 111, 239, 259, 1019, 241, 2521, 1599, 4655, 5725, 56623, 0 }; + static ulong[] dim3813Kuo3Init = { 1, 3, 1, 7, 29, 37, 29, 223, 413, 307, 939, 2009, 3961, 9481, 9121, 23927, 0 }; + static ulong[] dim3814Kuo3Init = { 1, 1, 3, 13, 17, 37, 7, 121, 387, 573, 1751, 3431, 7199, 15041, 14453, 45757, 0 }; + static ulong[] dim3815Kuo3Init = { 1, 3, 3, 7, 31, 53, 29, 247, 23, 579, 1919, 2925, 321, 653, 25925, 49439, 0 }; + static ulong[] dim3816Kuo3Init = { 1, 3, 5, 5, 5, 55, 109, 193, 125, 823, 1707, 2389, 4135, 5197, 12563, 5977, 0 }; + static ulong[] dim3817Kuo3Init = { 1, 3, 3, 7, 25, 47, 1, 145, 491, 661, 1125, 2567, 6783, 15009, 31871, 46645, 0 }; + static ulong[] dim3818Kuo3Init = { 1, 3, 3, 7, 13, 43, 105, 69, 25, 157, 923, 1997, 4383, 14935, 8821, 6383, 0 }; + static ulong[] dim3819Kuo3Init = { 1, 1, 7, 1, 23, 41, 51, 215, 509, 117, 1871, 3025, 4295, 8327, 23887, 53039, 0 }; + static ulong[] dim3820Kuo3Init = { 1, 1, 7, 1, 17, 9, 41, 89, 227, 909, 523, 3755, 3527, 12117, 12455, 18087, 0 }; + static ulong[] dim3821Kuo3Init = { 1, 3, 1, 11, 19, 1, 77, 73, 139, 707, 163, 2715, 819, 8401, 24751, 24619, 0 }; + static ulong[] dim3822Kuo3Init = { 1, 3, 3, 15, 11, 55, 31, 89, 383, 429, 269, 1593, 4929, 12037, 17279, 6489, 0 }; + static ulong[] dim3823Kuo3Init = { 1, 1, 7, 13, 5, 19, 65, 43, 257, 711, 349, 3231, 3169, 11759, 19069, 29043, 0 }; + static ulong[] dim3824Kuo3Init = { 1, 3, 7, 15, 5, 51, 31, 245, 197, 685, 1527, 3409, 4925, 8923, 10927, 62873, 0 }; + static ulong[] dim3825Kuo3Init = { 1, 1, 7, 15, 31, 31, 61, 111, 327, 785, 97, 2659, 4777, 14187, 19731, 5195, 0 }; + static ulong[] dim3826Kuo3Init = { 1, 3, 5, 13, 7, 53, 3, 97, 109, 537, 1395, 1919, 4447, 4067, 30137, 60659, 0 }; + static ulong[] dim3827Kuo3Init = { 1, 3, 7, 11, 19, 45, 51, 107, 161, 269, 1003, 2363, 311, 7051, 25943, 20881, 0 }; + static ulong[] dim3828Kuo3Init = { 1, 3, 7, 11, 27, 49, 79, 187, 265, 903, 1547, 1147, 8049, 10451, 15371, 43705, 0 }; + static ulong[] dim3829Kuo3Init = { 1, 3, 5, 1, 9, 25, 29, 229, 229, 337, 1821, 2377, 1325, 15079, 28661, 46107, 0 }; + static ulong[] dim3830Kuo3Init = { 1, 3, 7, 9, 29, 13, 121, 121, 229, 523, 707, 2577, 7637, 9257, 31031, 56527, 0 }; + static ulong[] dim3831Kuo3Init = { 1, 1, 5, 9, 11, 41, 111, 59, 347, 295, 895, 3477, 149, 6747, 14671, 3405, 0 }; + static ulong[] dim3832Kuo3Init = { 1, 1, 3, 11, 17, 17, 77, 105, 65, 831, 1969, 41, 1001, 2753, 4427, 25655, 0 }; + static ulong[] dim3833Kuo3Init = { 1, 1, 5, 9, 7, 37, 55, 121, 51, 155, 443, 321, 1845, 11587, 28855, 13905, 0 }; + static ulong[] dim3834Kuo3Init = { 1, 3, 3, 15, 9, 51, 1, 1, 453, 193, 1615, 2085, 3685, 15933, 18913, 46073, 0 }; + static ulong[] dim3835Kuo3Init = { 1, 1, 1, 9, 31, 29, 59, 55, 33, 413, 1261, 1367, 1895, 10291, 575, 12241, 0 }; + static ulong[] dim3836Kuo3Init = { 1, 3, 3, 9, 7, 11, 1, 207, 351, 357, 77, 4059, 3951, 4589, 11861, 43855, 0 }; + static ulong[] dim3837Kuo3Init = { 1, 1, 1, 9, 15, 1, 77, 227, 377, 25, 1665, 3693, 8129, 10059, 19517, 51103, 0 }; + static ulong[] dim3838Kuo3Init = { 1, 3, 5, 15, 25, 43, 103, 3, 477, 87, 1943, 1163, 7619, 8345, 25321, 36191, 0 }; + static ulong[] dim3839Kuo3Init = { 1, 1, 1, 5, 13, 5, 99, 11, 33, 113, 1905, 2559, 2679, 15005, 12859, 19233, 0 }; + static ulong[] dim3840Kuo3Init = { 1, 3, 5, 3, 9, 61, 79, 95, 71, 963, 1367, 1843, 3179, 10633, 5451, 64379, 0 }; + static ulong[] dim3841Kuo3Init = { 1, 1, 1, 5, 11, 11, 67, 11, 133, 759, 1823, 3281, 6741, 4995, 21753, 17093, 0 }; + static ulong[] dim3842Kuo3Init = { 1, 1, 7, 5, 29, 41, 31, 17, 381, 741, 567, 1009, 4781, 8953, 12397, 51833, 0 }; + static ulong[] dim3843Kuo3Init = { 1, 3, 3, 7, 9, 61, 35, 203, 69, 633, 477, 2839, 1917, 12097, 28693, 42999, 0 }; + static ulong[] dim3844Kuo3Init = { 1, 1, 3, 11, 29, 25, 1, 219, 343, 249, 1077, 125, 3197, 5877, 28407, 59627, 0 }; + static ulong[] dim3845Kuo3Init = { 1, 1, 3, 1, 25, 37, 113, 125, 253, 947, 1103, 1283, 3493, 7129, 17881, 21279, 0 }; + static ulong[] dim3846Kuo3Init = { 1, 3, 7, 15, 29, 43, 125, 203, 495, 421, 1725, 1673, 3635, 8161, 3753, 46323, 0 }; + static ulong[] dim3847Kuo3Init = { 1, 1, 5, 1, 9, 7, 73, 117, 397, 521, 1699, 2715, 6149, 2337, 30623, 3943, 0 }; + static ulong[] dim3848Kuo3Init = { 1, 3, 5, 7, 13, 17, 121, 163, 491, 111, 1589, 351, 303, 7395, 5731, 65513, 0 }; + static ulong[] dim3849Kuo3Init = { 1, 1, 1, 3, 11, 1, 19, 179, 295, 595, 897, 1929, 1379, 13651, 19067, 43507, 0 }; + static ulong[] dim3850Kuo3Init = { 1, 3, 5, 15, 29, 51, 19, 221, 67, 507, 213, 1873, 6051, 11191, 31475, 23447, 0 }; + static ulong[] dim3851Kuo3Init = { 1, 3, 5, 3, 13, 35, 97, 75, 195, 569, 1047, 2607, 1549, 9495, 5945, 7581, 0 }; + static ulong[] dim3852Kuo3Init = { 1, 3, 3, 15, 23, 41, 125, 101, 415, 927, 1421, 2043, 8035, 4077, 11133, 17333, 0 }; + static ulong[] dim3853Kuo3Init = { 1, 3, 7, 3, 5, 51, 111, 129, 29, 469, 991, 2595, 165, 13987, 30077, 63491, 0 }; + static ulong[] dim3854Kuo3Init = { 1, 3, 1, 3, 1, 17, 93, 7, 511, 3, 861, 3979, 2173, 6571, 30099, 12907, 0 }; + static ulong[] dim3855Kuo3Init = { 1, 1, 7, 5, 9, 29, 43, 153, 83, 961, 1585, 3615, 4409, 1937, 24107, 45235, 0 }; + static ulong[] dim3856Kuo3Init = { 1, 1, 3, 1, 19, 29, 81, 183, 197, 565, 1455, 2993, 6731, 2749, 1013, 27777, 0 }; + static ulong[] dim3857Kuo3Init = { 1, 3, 7, 1, 17, 11, 121, 245, 103, 851, 1367, 141, 1257, 719, 25581, 48999, 0 }; + static ulong[] dim3858Kuo3Init = { 1, 1, 5, 15, 15, 17, 33, 255, 113, 715, 1497, 3137, 1415, 7791, 28563, 28415, 0 }; + static ulong[] dim3859Kuo3Init = { 1, 1, 3, 9, 7, 45, 19, 143, 73, 95, 317, 1777, 7263, 11833, 25181, 27137, 0 }; + static ulong[] dim3860Kuo3Init = { 1, 1, 5, 3, 15, 49, 71, 57, 101, 95, 667, 2745, 6387, 14167, 661, 31809, 0 }; + static ulong[] dim3861Kuo3Init = { 1, 1, 7, 3, 7, 11, 119, 5, 3, 383, 933, 293, 5507, 3025, 18865, 26577, 0 }; + static ulong[] dim3862Kuo3Init = { 1, 1, 7, 9, 21, 57, 113, 173, 103, 743, 1573, 2165, 2909, 14253, 2303, 51939, 0 }; + static ulong[] dim3863Kuo3Init = { 1, 3, 3, 9, 11, 29, 85, 239, 501, 123, 1149, 165, 6341, 10205, 18829, 32327, 0 }; + static ulong[] dim3864Kuo3Init = { 1, 3, 1, 15, 21, 15, 63, 117, 217, 701, 299, 2887, 1341, 1617, 15163, 45899, 0 }; + static ulong[] dim3865Kuo3Init = { 1, 3, 3, 13, 25, 63, 91, 225, 399, 765, 1719, 3169, 1645, 10445, 1109, 13021, 0 }; + static ulong[] dim3866Kuo3Init = { 1, 1, 3, 13, 3, 9, 115, 35, 59, 145, 551, 2601, 1737, 9753, 7665, 30995, 0 }; + static ulong[] dim3867Kuo3Init = { 1, 1, 5, 9, 1, 33, 37, 173, 385, 635, 1419, 1377, 3161, 1915, 30933, 46117, 0 }; + static ulong[] dim3868Kuo3Init = { 1, 1, 7, 9, 21, 35, 65, 227, 329, 797, 61, 3409, 3911, 751, 21951, 11969, 0 }; + static ulong[] dim3869Kuo3Init = { 1, 3, 1, 13, 13, 33, 29, 197, 183, 979, 979, 1629, 6017, 8645, 4007, 52377, 0 }; + static ulong[] dim3870Kuo3Init = { 1, 1, 5, 7, 5, 17, 29, 117, 197, 163, 685, 2561, 2849, 5441, 32031, 25761, 0 }; + static ulong[] dim3871Kuo3Init = { 1, 3, 1, 5, 9, 17, 59, 237, 33, 11, 399, 3543, 7273, 8239, 15191, 57529, 0 }; + static ulong[] dim3872Kuo3Init = { 1, 1, 3, 7, 1, 45, 75, 107, 123, 909, 389, 3549, 4961, 15671, 14139, 29273, 0 }; + static ulong[] dim3873Kuo3Init = { 1, 3, 7, 3, 23, 3, 93, 73, 265, 889, 27, 805, 6021, 5851, 7181, 35309, 0 }; + static ulong[] dim3874Kuo3Init = { 1, 3, 1, 9, 23, 61, 17, 89, 495, 813, 1189, 1137, 7363, 6075, 3053, 28313, 0 }; + static ulong[] dim3875Kuo3Init = { 1, 1, 3, 13, 3, 1, 9, 133, 63, 417, 843, 2481, 5703, 11095, 867, 28097, 0 }; + static ulong[] dim3876Kuo3Init = { 1, 1, 5, 9, 23, 15, 113, 23, 199, 863, 1751, 765, 1917, 2145, 5391, 4629, 0 }; + static ulong[] dim3877Kuo3Init = { 1, 3, 3, 11, 13, 59, 127, 115, 341, 311, 677, 2305, 19, 13871, 9297, 4023, 0 }; + static ulong[] dim3878Kuo3Init = { 1, 1, 5, 7, 13, 3, 25, 195, 403, 323, 515, 2809, 983, 8699, 10205, 14719, 0 }; + static ulong[] dim3879Kuo3Init = { 1, 1, 1, 13, 5, 33, 123, 213, 99, 889, 1151, 3339, 4855, 3677, 30627, 23225, 0 }; + static ulong[] dim3880Kuo3Init = { 1, 1, 7, 9, 21, 19, 77, 85, 155, 379, 119, 81, 1937, 3589, 22645, 51585, 0 }; + static ulong[] dim3881Kuo3Init = { 1, 1, 3, 1, 5, 11, 121, 111, 423, 927, 1551, 2207, 3589, 691, 8519, 61261, 0 }; + static ulong[] dim3882Kuo3Init = { 1, 3, 5, 3, 1, 59, 25, 111, 415, 41, 623, 2505, 6075, 973, 10419, 26877, 0 }; + static ulong[] dim3883Kuo3Init = { 1, 3, 3, 11, 15, 57, 43, 27, 177, 733, 1521, 3629, 3003, 15351, 26327, 32921, 0 }; + static ulong[] dim3884Kuo3Init = { 1, 3, 3, 13, 1, 37, 3, 183, 349, 731, 1583, 2787, 6233, 14787, 16299, 4663, 0 }; + static ulong[] dim3885Kuo3Init = { 1, 3, 7, 15, 29, 47, 59, 79, 265, 193, 503, 2393, 643, 14341, 21055, 43803, 0 }; + static ulong[] dim3886Kuo3Init = { 1, 3, 1, 9, 11, 43, 75, 77, 493, 411, 145, 227, 3045, 363, 19879, 41017, 0 }; + static ulong[] dim3887Kuo3Init = { 1, 1, 5, 3, 1, 49, 87, 3, 377, 795, 1905, 2959, 3743, 1459, 32493, 6283, 0 }; + static ulong[] dim3888Kuo3Init = { 1, 3, 1, 13, 13, 13, 39, 83, 131, 935, 599, 1871, 7293, 11749, 6627, 58295, 0 }; + static ulong[] dim3889Kuo3Init = { 1, 1, 5, 3, 15, 9, 107, 239, 453, 53, 1825, 1493, 3611, 9993, 12535, 38879, 0 }; + static ulong[] dim3890Kuo3Init = { 1, 3, 5, 7, 1, 21, 93, 189, 477, 923, 13, 3797, 8147, 8417, 21473, 62305, 0 }; + static ulong[] dim3891Kuo3Init = { 1, 3, 3, 15, 21, 47, 75, 183, 425, 281, 813, 571, 1017, 565, 8541, 52977, 0 }; + static ulong[] dim3892Kuo3Init = { 1, 1, 5, 13, 29, 53, 25, 217, 111, 605, 1771, 1827, 7245, 16063, 10769, 57483, 0 }; + static ulong[] dim3893Kuo3Init = { 1, 3, 5, 7, 9, 27, 99, 75, 171, 299, 1751, 841, 4717, 7373, 14241, 7435, 0 }; + static ulong[] dim3894Kuo3Init = { 1, 3, 7, 3, 27, 13, 121, 69, 453, 1009, 1353, 3289, 3221, 9127, 29967, 60919, 0 }; + static ulong[] dim3895Kuo3Init = { 1, 1, 1, 11, 5, 41, 81, 151, 479, 599, 1751, 2841, 5721, 1725, 3465, 23385, 0 }; + static ulong[] dim3896Kuo3Init = { 1, 1, 3, 11, 7, 7, 35, 169, 35, 255, 1657, 297, 3855, 2071, 10929, 15907, 0 }; + static ulong[] dim3897Kuo3Init = { 1, 1, 1, 3, 25, 1, 43, 139, 165, 535, 95, 2769, 8105, 6865, 20297, 64539, 0 }; + static ulong[] dim3898Kuo3Init = { 1, 3, 7, 7, 21, 27, 11, 209, 279, 769, 1961, 101, 2103, 4529, 4987, 29097, 0 }; + static ulong[] dim3899Kuo3Init = { 1, 1, 1, 11, 29, 37, 45, 65, 75, 729, 1773, 4023, 7671, 6259, 22339, 45735, 0 }; + static ulong[] dim3900Kuo3Init = { 1, 3, 7, 5, 25, 3, 41, 139, 365, 915, 111, 611, 7609, 6259, 12247, 58671, 0 }; + static ulong[] dim3901Kuo3Init = { 1, 1, 7, 15, 11, 45, 95, 121, 3, 491, 1779, 1055, 7051, 15499, 17301, 13081, 0 }; + static ulong[] dim3902Kuo3Init = { 1, 1, 1, 13, 5, 43, 105, 173, 267, 263, 873, 953, 5945, 11417, 23799, 54591, 0 }; + static ulong[] dim3903Kuo3Init = { 1, 1, 1, 9, 1, 55, 15, 73, 87, 49, 1651, 775, 6485, 9543, 26199, 30419, 0 }; + static ulong[] dim3904Kuo3Init = { 1, 3, 1, 3, 11, 5, 35, 37, 451, 85, 943, 4017, 6795, 8915, 28551, 45097, 0 }; + static ulong[] dim3905Kuo3Init = { 1, 3, 7, 11, 11, 51, 93, 237, 487, 515, 1511, 383, 7571, 4673, 29395, 21659, 0 }; + static ulong[] dim3906Kuo3Init = { 1, 1, 3, 1, 11, 63, 113, 253, 99, 733, 2001, 3767, 7431, 12131, 25203, 22251, 0 }; + static ulong[] dim3907Kuo3Init = { 1, 3, 3, 1, 11, 29, 37, 181, 299, 9, 11, 317, 1079, 13441, 8925, 15847, 0 }; + static ulong[] dim3908Kuo3Init = { 1, 1, 5, 5, 5, 9, 77, 67, 165, 273, 1161, 65, 7157, 13531, 2987, 1169, 0 }; + static ulong[] dim3909Kuo3Init = { 1, 3, 5, 7, 9, 57, 17, 209, 357, 901, 1113, 61, 5751, 2255, 29677, 56397, 0 }; + static ulong[] dim3910Kuo3Init = { 1, 1, 5, 11, 7, 5, 7, 53, 397, 279, 1387, 2447, 115, 2043, 19287, 45753, 0 }; + static ulong[] dim3911Kuo3Init = { 1, 3, 3, 15, 25, 41, 45, 33, 167, 801, 1929, 1173, 1525, 3725, 22407, 37077, 0 }; + static ulong[] dim3912Kuo3Init = { 1, 3, 1, 11, 13, 61, 107, 181, 179, 51, 1379, 3573, 7319, 4843, 10023, 28725, 0 }; + static ulong[] dim3913Kuo3Init = { 1, 1, 5, 3, 11, 61, 61, 1, 211, 557, 417, 899, 4651, 3375, 19423, 11719, 0 }; + static ulong[] dim3914Kuo3Init = { 1, 3, 1, 13, 9, 5, 117, 217, 193, 911, 991, 155, 3011, 4759, 30953, 63939, 0 }; + static ulong[] dim3915Kuo3Init = { 1, 3, 1, 13, 21, 7, 77, 29, 457, 923, 871, 147, 5177, 13949, 1977, 27515, 0 }; + static ulong[] dim3916Kuo3Init = { 1, 3, 1, 3, 5, 39, 83, 133, 471, 355, 615, 1627, 2471, 59, 21449, 52293, 0 }; + static ulong[] dim3917Kuo3Init = { 1, 3, 7, 13, 23, 57, 97, 3, 385, 255, 1565, 3479, 5587, 15101, 27153, 9239, 0 }; + static ulong[] dim3918Kuo3Init = { 1, 3, 5, 5, 13, 25, 99, 19, 49, 655, 1823, 641, 619, 5913, 11379, 23781, 0 }; + static ulong[] dim3919Kuo3Init = { 1, 1, 1, 5, 21, 1, 91, 3, 31, 19, 19, 3627, 1575, 1439, 7473, 36215, 0 }; + static ulong[] dim3920Kuo3Init = { 1, 3, 5, 13, 29, 61, 1, 151, 291, 315, 965, 3435, 1849, 13069, 9785, 41345, 0 }; + static ulong[] dim3921Kuo3Init = { 1, 3, 3, 15, 17, 9, 97, 69, 233, 925, 1933, 3861, 89, 7889, 28853, 64959, 0 }; + static ulong[] dim3922Kuo3Init = { 1, 3, 3, 3, 5, 51, 67, 175, 341, 191, 1643, 3327, 763, 327, 28069, 15317, 0 }; + static ulong[] dim3923Kuo3Init = { 1, 3, 5, 3, 3, 37, 109, 43, 465, 57, 489, 915, 6943, 7947, 9229, 5647, 0 }; + static ulong[] dim3924Kuo3Init = { 1, 1, 7, 7, 27, 1, 85, 171, 185, 615, 1451, 237, 1597, 4255, 24429, 34357, 0 }; + static ulong[] dim3925Kuo3Init = { 1, 3, 1, 7, 29, 35, 69, 237, 117, 841, 1549, 2093, 105, 10197, 5229, 59299, 0 }; + static ulong[] dim3926Kuo3Init = { 1, 3, 5, 3, 7, 33, 73, 81, 385, 177, 1849, 773, 1085, 5539, 29213, 30635, 0 }; + static ulong[] dim3927Kuo3Init = { 1, 3, 7, 15, 15, 47, 53, 207, 337, 479, 775, 2851, 725, 14779, 29653, 35949, 0 }; + static ulong[] dim3928Kuo3Init = { 1, 1, 3, 9, 15, 53, 53, 87, 315, 929, 919, 907, 6893, 4647, 2019, 57879, 0 }; + static ulong[] dim3929Kuo3Init = { 1, 3, 5, 11, 5, 31, 21, 9, 215, 599, 617, 3737, 787, 10513, 17907, 22221, 0 }; + static ulong[] dim3930Kuo3Init = { 1, 3, 3, 3, 27, 5, 27, 157, 423, 197, 1757, 2451, 6317, 1557, 6641, 12621, 0 }; + static ulong[] dim3931Kuo3Init = { 1, 1, 5, 9, 19, 17, 109, 37, 329, 217, 1265, 3073, 6243, 6179, 25921, 9001, 0 }; + static ulong[] dim3932Kuo3Init = { 1, 3, 5, 15, 13, 13, 103, 79, 399, 897, 1241, 2847, 5913, 2267, 5367, 26337, 0 }; + static ulong[] dim3933Kuo3Init = { 1, 1, 3, 1, 17, 41, 19, 213, 123, 123, 1103, 1125, 2819, 7643, 26391, 20935, 0 }; + static ulong[] dim3934Kuo3Init = { 1, 1, 1, 5, 29, 27, 79, 143, 93, 311, 433, 1945, 2783, 13787, 4473, 23279, 0 }; + static ulong[] dim3935Kuo3Init = { 1, 3, 1, 1, 13, 49, 39, 21, 117, 933, 169, 551, 2871, 9879, 3715, 25143, 0 }; + static ulong[] dim3936Kuo3Init = { 1, 3, 1, 3, 29, 15, 5, 89, 255, 779, 495, 2335, 6029, 8733, 5687, 40189, 0 }; + static ulong[] dim3937Kuo3Init = { 1, 1, 5, 3, 5, 61, 37, 231, 395, 175, 711, 1149, 4819, 10119, 24929, 37155, 0 }; + static ulong[] dim3938Kuo3Init = { 1, 1, 7, 3, 7, 49, 81, 221, 193, 685, 2029, 3979, 5071, 2965, 18951, 21497, 0 }; + static ulong[] dim3939Kuo3Init = { 1, 1, 3, 5, 11, 17, 29, 153, 379, 387, 1271, 1261, 817, 5913, 22395, 885, 0 }; + static ulong[] dim3940Kuo3Init = { 1, 1, 1, 1, 3, 37, 89, 255, 337, 135, 535, 1087, 7987, 8107, 22953, 18709, 0 }; + static ulong[] dim3941Kuo3Init = { 1, 1, 5, 11, 25, 29, 15, 223, 181, 879, 1661, 1605, 3777, 5221, 7253, 22951, 0 }; + static ulong[] dim3942Kuo3Init = { 1, 3, 1, 1, 3, 9, 57, 239, 439, 669, 1069, 2001, 2689, 9569, 24151, 54337, 0 }; + static ulong[] dim3943Kuo3Init = { 1, 1, 1, 11, 7, 47, 21, 31, 35, 739, 1229, 2929, 5221, 6715, 32275, 42743, 0 }; + static ulong[] dim3944Kuo3Init = { 1, 3, 1, 7, 19, 3, 85, 55, 397, 875, 949, 2835, 6077, 1069, 13307, 5897, 0 }; + static ulong[] dim3945Kuo3Init = { 1, 3, 7, 15, 11, 57, 113, 193, 191, 53, 1319, 1585, 4797, 13903, 24875, 50229, 0 }; + static ulong[] dim3946Kuo3Init = { 1, 3, 7, 7, 15, 17, 29, 125, 387, 775, 411, 1283, 6069, 10909, 14221, 52811, 0 }; + static ulong[] dim3947Kuo3Init = { 1, 3, 7, 15, 17, 47, 73, 143, 133, 1009, 1671, 2307, 2991, 10319, 3161, 665, 0 }; + static ulong[] dim3948Kuo3Init = { 1, 3, 7, 11, 23, 29, 115, 77, 167, 667, 1983, 3985, 1449, 10055, 27947, 63501, 0 }; + static ulong[] dim3949Kuo3Init = { 1, 1, 3, 11, 27, 61, 83, 173, 427, 161, 1349, 297, 1579, 9929, 32663, 44385, 0 }; + static ulong[] dim3950Kuo3Init = { 1, 1, 7, 9, 19, 31, 73, 233, 109, 991, 1381, 3223, 4033, 4447, 4773, 61631, 0 }; + static ulong[] dim3951Kuo3Init = { 1, 1, 3, 5, 17, 53, 71, 201, 181, 395, 1305, 2049, 4317, 12689, 23133, 13401, 0 }; + static ulong[] dim3952Kuo3Init = { 1, 3, 1, 1, 13, 63, 17, 107, 149, 739, 1829, 2441, 3491, 1649, 15839, 13021, 0 }; + static ulong[] dim3953Kuo3Init = { 1, 1, 1, 3, 3, 15, 35, 247, 95, 973, 1625, 3097, 6075, 14331, 8345, 12225, 0 }; + static ulong[] dim3954Kuo3Init = { 1, 3, 3, 7, 9, 21, 5, 85, 431, 317, 1313, 1981, 7761, 2857, 18659, 58677, 0 }; + static ulong[] dim3955Kuo3Init = { 1, 3, 3, 1, 25, 23, 5, 213, 345, 119, 1979, 1023, 6849, 9587, 2519, 57219, 0 }; + static ulong[] dim3956Kuo3Init = { 1, 1, 5, 11, 17, 1, 15, 213, 21, 435, 1719, 3065, 6197, 8993, 8479, 17383, 0 }; + static ulong[] dim3957Kuo3Init = { 1, 1, 3, 5, 17, 35, 97, 167, 411, 57, 145, 663, 1319, 16029, 1649, 13097, 0 }; + static ulong[] dim3958Kuo3Init = { 1, 3, 3, 9, 13, 1, 89, 179, 355, 655, 1217, 1421, 4303, 2705, 30107, 45801, 0 }; + static ulong[] dim3959Kuo3Init = { 1, 1, 7, 1, 23, 49, 67, 119, 139, 397, 983, 3537, 1463, 10395, 4717, 50885, 0 }; + static ulong[] dim3960Kuo3Init = { 1, 1, 1, 9, 9, 9, 95, 75, 489, 459, 951, 1829, 5017, 8703, 6229, 18921, 0 }; + static ulong[] dim3961Kuo3Init = { 1, 3, 7, 5, 7, 55, 89, 75, 231, 141, 1611, 2275, 1953, 6389, 12899, 45117, 0 }; + static ulong[] dim3962Kuo3Init = { 1, 3, 1, 1, 25, 53, 91, 25, 425, 275, 189, 863, 5777, 6179, 12273, 3473, 0 }; + static ulong[] dim3963Kuo3Init = { 1, 1, 7, 15, 5, 17, 75, 83, 357, 523, 1075, 1981, 3993, 13133, 16441, 53935, 0 }; + static ulong[] dim3964Kuo3Init = { 1, 3, 7, 5, 15, 13, 103, 89, 309, 961, 771, 1441, 1449, 15867, 20019, 22303, 0 }; + static ulong[] dim3965Kuo3Init = { 1, 3, 5, 9, 7, 47, 33, 117, 151, 77, 893, 867, 2523, 13975, 20649, 15673, 0 }; + static ulong[] dim3966Kuo3Init = { 1, 3, 5, 15, 5, 15, 57, 149, 405, 523, 763, 4071, 5915, 3255, 22243, 46779, 0 }; + static ulong[] dim3967Kuo3Init = { 1, 3, 7, 5, 17, 39, 53, 181, 65, 541, 1995, 3213, 3837, 3527, 2433, 23527, 0 }; + static ulong[] dim3968Kuo3Init = { 1, 3, 5, 3, 17, 9, 5, 79, 299, 441, 1891, 3607, 5087, 14629, 31767, 21443, 0 }; + static ulong[] dim3969Kuo3Init = { 1, 1, 5, 11, 1, 47, 25, 13, 201, 691, 507, 2041, 3169, 2909, 5341, 7643, 0 }; + static ulong[] dim3970Kuo3Init = { 1, 1, 1, 1, 31, 55, 109, 97, 335, 835, 933, 839, 3271, 14323, 25319, 18807, 0 }; + static ulong[] dim3971Kuo3Init = { 1, 3, 7, 9, 19, 21, 19, 79, 449, 1007, 1559, 3143, 2633, 11691, 3273, 17381, 0 }; + static ulong[] dim3972Kuo3Init = { 1, 1, 3, 9, 3, 61, 105, 255, 327, 649, 11, 715, 2629, 8425, 165, 6235, 0 }; + static ulong[] dim3973Kuo3Init = { 1, 3, 5, 11, 9, 39, 45, 161, 421, 243, 1589, 157, 5309, 9769, 28229, 12947, 0 }; + static ulong[] dim3974Kuo3Init = { 1, 3, 3, 13, 15, 17, 75, 23, 189, 601, 737, 687, 3387, 11913, 17245, 16073, 0 }; + static ulong[] dim3975Kuo3Init = { 1, 1, 1, 3, 25, 45, 73, 243, 171, 179, 617, 2039, 4937, 963, 10791, 48989, 0 }; + static ulong[] dim3976Kuo3Init = { 1, 1, 7, 3, 3, 61, 123, 27, 3, 385, 1357, 3773, 1639, 353, 21277, 52013, 0 }; + static ulong[] dim3977Kuo3Init = { 1, 3, 5, 9, 27, 19, 49, 255, 213, 753, 297, 601, 4905, 15889, 18055, 31511, 0 }; + static ulong[] dim3978Kuo3Init = { 1, 1, 7, 9, 1, 19, 93, 251, 279, 21, 891, 859, 4637, 2587, 17659, 19485, 0 }; + static ulong[] dim3979Kuo3Init = { 1, 3, 3, 11, 29, 55, 69, 151, 445, 947, 719, 3935, 4625, 9321, 25645, 39153, 0 }; + static ulong[] dim3980Kuo3Init = { 1, 3, 7, 5, 23, 57, 79, 21, 353, 7, 295, 3379, 3505, 15409, 9117, 19745, 0 }; + static ulong[] dim3981Kuo3Init = { 1, 1, 5, 13, 7, 5, 41, 249, 429, 999, 1945, 1097, 795, 8647, 23297, 60707, 0 }; + static ulong[] dim3982Kuo3Init = { 1, 1, 5, 13, 3, 57, 105, 175, 345, 53, 455, 1549, 5291, 6757, 12637, 45159, 0 }; + static ulong[] dim3983Kuo3Init = { 1, 3, 3, 11, 5, 31, 5, 69, 373, 453, 1861, 1061, 6339, 3857, 13979, 24015, 0 }; + static ulong[] dim3984Kuo3Init = { 1, 1, 5, 11, 19, 41, 113, 183, 299, 197, 397, 1597, 6471, 14855, 26067, 2705, 0 }; + static ulong[] dim3985Kuo3Init = { 1, 1, 1, 13, 15, 59, 89, 73, 45, 891, 1285, 1565, 4675, 10669, 3067, 40585, 0 }; + static ulong[] dim3986Kuo3Init = { 1, 1, 5, 7, 1, 51, 59, 27, 275, 961, 765, 3003, 1677, 2093, 15083, 51929, 0 }; + static ulong[] dim3987Kuo3Init = { 1, 1, 5, 15, 19, 37, 101, 247, 223, 39, 2009, 3155, 6357, 13513, 30965, 36485, 0 }; + static ulong[] dim3988Kuo3Init = { 1, 1, 5, 1, 27, 9, 71, 231, 115, 1, 719, 873, 4895, 4031, 23581, 17529, 0 }; + static ulong[] dim3989Kuo3Init = { 1, 1, 3, 9, 1, 63, 13, 187, 325, 199, 1165, 491, 1361, 15377, 9463, 5077, 0 }; + static ulong[] dim3990Kuo3Init = { 1, 3, 3, 7, 9, 13, 71, 17, 213, 915, 1779, 401, 5315, 2161, 14765, 11301, 0 }; + static ulong[] dim3991Kuo3Init = { 1, 3, 7, 15, 5, 5, 3, 137, 17, 197, 1559, 3077, 4615, 923, 2143, 16743, 0 }; + static ulong[] dim3992Kuo3Init = { 1, 1, 3, 5, 13, 19, 77, 155, 285, 209, 1089, 2213, 3131, 11685, 13287, 10439, 0 }; + static ulong[] dim3993Kuo3Init = { 1, 1, 1, 9, 7, 11, 35, 113, 165, 795, 1657, 483, 4937, 5209, 19801, 13831, 0 }; + static ulong[] dim3994Kuo3Init = { 1, 1, 7, 9, 29, 1, 67, 131, 277, 919, 1267, 3907, 2561, 2469, 25321, 17769, 0 }; + static ulong[] dim3995Kuo3Init = { 1, 3, 5, 3, 25, 39, 93, 5, 151, 905, 201, 1499, 4069, 4691, 8293, 945, 0 }; + static ulong[] dim3996Kuo3Init = { 1, 3, 3, 3, 3, 59, 47, 13, 79, 157, 231, 1105, 5449, 10889, 2625, 53303, 0 }; + static ulong[] dim3997Kuo3Init = { 1, 3, 7, 15, 13, 23, 25, 171, 391, 497, 57, 4089, 3849, 6121, 1561, 29977, 0 }; + static ulong[] dim3998Kuo3Init = { 1, 3, 7, 5, 17, 19, 33, 193, 351, 189, 619, 2091, 7881, 12689, 3799, 1199, 0 }; + static ulong[] dim3999Kuo3Init = { 1, 3, 7, 7, 5, 35, 23, 219, 247, 377, 439, 3421, 2729, 7169, 24373, 48533, 0 }; + static ulong[] dim4000Kuo3Init = { 1, 1, 1, 13, 23, 33, 77, 37, 347, 831, 1525, 2383, 6483, 15377, 22761, 51647, 0 }; + static ulong[] dim4001Kuo3Init = { 1, 1, 3, 9, 5, 51, 89, 207, 131, 969, 463, 3917, 5985, 10797, 25183, 35637, 0 }; + static ulong[] dim4002Kuo3Init = { 1, 1, 1, 15, 9, 45, 99, 25, 7, 279, 541, 879, 6681, 2591, 31667, 51957, 0 }; + static ulong[] dim4003Kuo3Init = { 1, 1, 5, 1, 19, 13, 59, 119, 195, 385, 1715, 823, 7631, 9547, 27099, 30967, 0 }; + static ulong[] dim4004Kuo3Init = { 1, 1, 3, 13, 21, 29, 9, 17, 51, 819, 365, 1855, 1505, 13923, 27397, 25347, 0 }; + static ulong[] dim4005Kuo3Init = { 1, 3, 1, 9, 21, 1, 17, 109, 435, 887, 1951, 923, 181, 8365, 1531, 5533, 0 }; + static ulong[] dim4006Kuo3Init = { 1, 3, 1, 15, 7, 29, 101, 221, 151, 49, 1655, 2889, 7179, 1019, 10765, 49489, 0 }; + static ulong[] dim4007Kuo3Init = { 1, 3, 1, 13, 27, 15, 25, 249, 31, 187, 1875, 2937, 5831, 13499, 27997, 8003, 0 }; + static ulong[] dim4008Kuo3Init = { 1, 3, 1, 5, 13, 55, 111, 231, 71, 245, 479, 2487, 7967, 10911, 12853, 56217, 0 }; + static ulong[] dim4009Kuo3Init = { 1, 1, 7, 7, 15, 13, 77, 37, 497, 899, 1527, 275, 517, 10323, 2329, 19267, 0 }; + static ulong[] dim4010Kuo3Init = { 1, 3, 5, 5, 13, 1, 17, 201, 211, 153, 1377, 347, 3481, 6785, 23745, 54849, 0 }; + static ulong[] dim4011Kuo3Init = { 1, 1, 1, 13, 23, 29, 55, 91, 249, 815, 1375, 3081, 1445, 13763, 29983, 24581, 0 }; + static ulong[] dim4012Kuo3Init = { 1, 1, 5, 15, 23, 19, 65, 31, 105, 797, 957, 1741, 4189, 3313, 17183, 34345, 0 }; + static ulong[] dim4013Kuo3Init = { 1, 1, 7, 13, 23, 51, 13, 119, 19, 901, 1985, 3269, 3753, 5365, 3871, 30099, 0 }; + static ulong[] dim4014Kuo3Init = { 1, 1, 1, 1, 13, 11, 3, 59, 45, 1007, 121, 1433, 1559, 15593, 187, 55939, 0 }; + static ulong[] dim4015Kuo3Init = { 1, 3, 7, 13, 7, 15, 17, 227, 143, 889, 1011, 1195, 3849, 12643, 27303, 10473, 0 }; + static ulong[] dim4016Kuo3Init = { 1, 3, 7, 11, 9, 63, 35, 181, 301, 945, 853, 877, 2983, 9945, 31237, 12011, 0 }; + static ulong[] dim4017Kuo3Init = { 1, 1, 1, 5, 23, 17, 111, 15, 429, 925, 299, 173, 3379, 2407, 11999, 44485, 0 }; + static ulong[] dim4018Kuo3Init = { 1, 1, 5, 5, 31, 55, 103, 227, 93, 15, 399, 1559, 3107, 5729, 24069, 55711, 0 }; + static ulong[] dim4019Kuo3Init = { 1, 3, 7, 7, 25, 5, 107, 57, 23, 1005, 27, 2881, 2591, 10939, 8613, 50351, 0 }; + static ulong[] dim4020Kuo3Init = { 1, 1, 5, 1, 19, 23, 107, 65, 11, 643, 1337, 3197, 1583, 8797, 6047, 55749, 0 }; + static ulong[] dim4021Kuo3Init = { 1, 1, 1, 9, 3, 61, 31, 67, 369, 755, 1263, 2711, 1341, 15465, 25337, 20607, 0 }; + static ulong[] dim4022Kuo3Init = { 1, 3, 7, 7, 23, 53, 95, 223, 225, 627, 471, 1203, 7689, 3211, 24697, 21153, 0 }; + static ulong[] dim4023Kuo3Init = { 1, 3, 7, 1, 3, 29, 45, 15, 247, 45, 345, 4063, 3819, 263, 9705, 27991, 0 }; + static ulong[] dim4024Kuo3Init = { 1, 3, 3, 1, 3, 55, 127, 247, 87, 969, 1409, 2105, 4133, 1213, 2719, 37043, 0 }; + static ulong[] dim4025Kuo3Init = { 1, 1, 5, 15, 9, 15, 71, 9, 421, 1, 1367, 2557, 2121, 2919, 29167, 7035, 0 }; + static ulong[] dim4026Kuo3Init = { 1, 3, 7, 5, 21, 35, 7, 1, 429, 491, 1077, 499, 2915, 13217, 25153, 327, 0 }; + static ulong[] dim4027Kuo3Init = { 1, 1, 3, 9, 7, 57, 37, 235, 97, 357, 1171, 705, 7111, 5217, 13167, 38395, 0 }; + static ulong[] dim4028Kuo3Init = { 1, 3, 7, 7, 9, 55, 43, 173, 429, 287, 355, 3009, 1667, 1845, 11477, 25437, 0 }; + static ulong[] dim4029Kuo3Init = { 1, 3, 7, 3, 13, 41, 41, 239, 421, 347, 1423, 797, 7435, 16195, 3501, 56213, 0 }; + static ulong[] dim4030Kuo3Init = { 1, 3, 7, 13, 25, 59, 67, 49, 363, 125, 365, 2517, 915, 2865, 25361, 24823, 0 }; + static ulong[] dim4031Kuo3Init = { 1, 3, 7, 1, 31, 55, 109, 213, 19, 843, 1457, 851, 7245, 13587, 30111, 58737, 0 }; + static ulong[] dim4032Kuo3Init = { 1, 1, 5, 5, 7, 29, 111, 121, 511, 401, 411, 3073, 3617, 4447, 12443, 49051, 0 }; + static ulong[] dim4033Kuo3Init = { 1, 3, 3, 9, 5, 55, 89, 231, 343, 869, 465, 1421, 701, 13565, 12469, 62381, 0 }; + static ulong[] dim4034Kuo3Init = { 1, 3, 3, 13, 7, 9, 91, 147, 37, 917, 1717, 2221, 5795, 7127, 21599, 28335, 0 }; + static ulong[] dim4035Kuo3Init = { 1, 3, 1, 3, 9, 51, 109, 43, 411, 477, 549, 1901, 4295, 2915, 5701, 29005, 0 }; + static ulong[] dim4036Kuo3Init = { 1, 1, 3, 9, 11, 51, 5, 81, 413, 461, 143, 2695, 2091, 8435, 14217, 60831, 0 }; + static ulong[] dim4037Kuo3Init = { 1, 3, 5, 13, 1, 15, 17, 239, 219, 75, 339, 1565, 5029, 6351, 19429, 21483, 0 }; + static ulong[] dim4038Kuo3Init = { 1, 1, 3, 5, 13, 7, 101, 215, 395, 387, 1215, 1967, 4141, 643, 14623, 58609, 0 }; + static ulong[] dim4039Kuo3Init = { 1, 3, 5, 13, 17, 29, 85, 201, 327, 855, 1971, 335, 6201, 5933, 6131, 3179, 0 }; + static ulong[] dim4040Kuo3Init = { 1, 3, 3, 13, 3, 49, 25, 223, 207, 477, 671, 1881, 3639, 10867, 22953, 58725, 0 }; + static ulong[] dim4041Kuo3Init = { 1, 1, 1, 5, 21, 23, 31, 57, 387, 881, 343, 1781, 3241, 10939, 5569, 37555, 0 }; + static ulong[] dim4042Kuo3Init = { 1, 1, 3, 1, 25, 3, 117, 153, 155, 61, 127, 3871, 7883, 11791, 18529, 55395, 0 }; + static ulong[] dim4043Kuo3Init = { 1, 1, 7, 9, 15, 15, 89, 197, 109, 221, 317, 2827, 2159, 847, 2527, 9463, 0 }; + static ulong[] dim4044Kuo3Init = { 1, 3, 5, 9, 25, 11, 39, 185, 457, 831, 637, 527, 2829, 4411, 4713, 53597, 0 }; + static ulong[] dim4045Kuo3Init = { 1, 3, 7, 15, 5, 27, 45, 123, 385, 217, 907, 2877, 2703, 15987, 24963, 41659, 0 }; + static ulong[] dim4046Kuo3Init = { 1, 3, 1, 13, 9, 31, 7, 225, 77, 227, 175, 1471, 3305, 4521, 6345, 55509, 0 }; + static ulong[] dim4047Kuo3Init = { 1, 3, 1, 5, 21, 33, 37, 3, 121, 605, 1121, 537, 1771, 14415, 8323, 21795, 0 }; + static ulong[] dim4048Kuo3Init = { 1, 3, 7, 5, 23, 23, 45, 231, 97, 535, 861, 1349, 6611, 7445, 25231, 50737, 0 }; + static ulong[] dim4049Kuo3Init = { 1, 3, 1, 9, 11, 13, 61, 155, 483, 391, 615, 899, 5099, 4895, 2919, 60239, 0 }; + static ulong[] dim4050Kuo3Init = { 1, 3, 3, 1, 31, 9, 47, 209, 405, 493, 103, 59, 3609, 12889, 6501, 32869, 0 }; + static ulong[] dim4051Kuo3Init = { 1, 1, 7, 13, 15, 57, 23, 153, 57, 369, 1833, 1287, 4487, 3195, 19587, 24373, 0 }; + static ulong[] dim4052Kuo3Init = { 1, 3, 7, 3, 25, 45, 51, 117, 293, 701, 1909, 659, 637, 3375, 23223, 29707, 0 }; + static ulong[] dim4053Kuo3Init = { 1, 3, 7, 15, 1, 27, 13, 227, 369, 143, 1167, 1787, 4815, 1143, 7789, 16467, 0 }; + static ulong[] dim4054Kuo3Init = { 1, 1, 5, 1, 13, 5, 63, 75, 13, 411, 1123, 459, 6323, 10445, 1303, 43103, 0 }; + static ulong[] dim4055Kuo3Init = { 1, 3, 1, 9, 29, 21, 93, 49, 135, 525, 121, 1299, 5931, 13115, 32567, 60605, 0 }; + static ulong[] dim4056Kuo3Init = { 1, 3, 3, 11, 25, 59, 77, 181, 39, 345, 1375, 2067, 3909, 8023, 6409, 12571, 0 }; + static ulong[] dim4057Kuo3Init = { 1, 3, 5, 15, 15, 55, 95, 183, 269, 931, 285, 1945, 2105, 10589, 19787, 64461, 0 }; + static ulong[] dim4058Kuo3Init = { 1, 1, 1, 5, 31, 19, 51, 109, 455, 877, 905, 2403, 2021, 573, 29837, 46871, 0 }; + static ulong[] dim4059Kuo3Init = { 1, 3, 1, 9, 21, 23, 9, 201, 143, 661, 289, 621, 6729, 9573, 6359, 14981, 0 }; + static ulong[] dim4060Kuo3Init = { 1, 3, 5, 5, 15, 53, 41, 57, 201, 37, 2047, 4045, 6501, 15641, 22031, 25851, 0 }; + static ulong[] dim4061Kuo3Init = { 1, 1, 7, 7, 17, 3, 31, 31, 165, 765, 1101, 1161, 7247, 16383, 27715, 20835, 0 }; + static ulong[] dim4062Kuo3Init = { 1, 3, 3, 13, 7, 41, 81, 55, 345, 913, 1457, 3801, 6937, 3781, 21125, 36899, 0 }; + static ulong[] dim4063Kuo3Init = { 1, 1, 3, 11, 21, 61, 57, 89, 341, 877, 639, 3051, 6541, 2133, 11187, 9613, 0 }; + static ulong[] dim4064Kuo3Init = { 1, 3, 3, 5, 3, 29, 3, 193, 331, 333, 1613, 3755, 6489, 4851, 10421, 11257, 0 }; + static ulong[] dim4065Kuo3Init = { 1, 3, 3, 13, 15, 29, 115, 135, 283, 363, 905, 3199, 733, 7785, 5237, 20657, 0 }; + static ulong[] dim4066Kuo3Init = { 1, 3, 5, 7, 3, 31, 89, 219, 61, 573, 1773, 677, 7447, 4625, 17011, 57851, 0 }; + static ulong[] dim4067Kuo3Init = { 1, 3, 1, 7, 9, 31, 121, 219, 27, 583, 1769, 3667, 4415, 6789, 28069, 11833, 0 }; + static ulong[] dim4068Kuo3Init = { 1, 1, 3, 1, 29, 11, 63, 201, 33, 153, 1075, 641, 5923, 10485, 24573, 29423, 0 }; + static ulong[] dim4069Kuo3Init = { 1, 1, 3, 13, 17, 5, 87, 237, 243, 231, 915, 1755, 4021, 2127, 26147, 28397, 0 }; + static ulong[] dim4070Kuo3Init = { 1, 3, 3, 3, 21, 49, 53, 163, 415, 553, 505, 3309, 4987, 16163, 14439, 30921, 0 }; + static ulong[] dim4071Kuo3Init = { 1, 3, 1, 13, 9, 59, 89, 113, 203, 485, 177, 2243, 5267, 7105, 5297, 23333, 0 }; + static ulong[] dim4072Kuo3Init = { 1, 3, 1, 1, 13, 21, 107, 183, 243, 985, 499, 385, 2409, 9317, 17393, 1913, 0 }; + static ulong[] dim4073Kuo3Init = { 1, 3, 3, 13, 21, 47, 59, 21, 71, 523, 1843, 3131, 5907, 15401, 7957, 51365, 0 }; + static ulong[] dim4074Kuo3Init = { 1, 3, 1, 3, 17, 19, 75, 195, 171, 11, 57, 303, 6801, 1825, 25027, 28587, 0 }; + static ulong[] dim4075Kuo3Init = { 1, 3, 5, 15, 13, 47, 19, 161, 47, 385, 1227, 261, 5855, 1439, 18605, 55645, 0 }; + static ulong[] dim4076Kuo3Init = { 1, 1, 5, 11, 23, 13, 87, 197, 507, 921, 1813, 579, 3585, 5117, 30913, 5739, 0 }; + static ulong[] dim4077Kuo3Init = { 1, 1, 1, 5, 21, 7, 3, 103, 475, 929, 1189, 1005, 2933, 1377, 30183, 58513, 0 }; + static ulong[] dim4078Kuo3Init = { 1, 1, 3, 11, 27, 51, 25, 139, 431, 275, 1541, 1459, 5787, 9865, 15077, 25965, 0 }; + static ulong[] dim4079Kuo3Init = { 1, 3, 7, 15, 19, 33, 85, 5, 119, 523, 11, 1459, 3807, 3959, 31321, 1905, 0 }; + static ulong[] dim4080Kuo3Init = { 1, 3, 1, 15, 9, 25, 107, 51, 149, 437, 995, 397, 753, 12421, 30637, 22865, 0 }; + static ulong[] dim4081Kuo3Init = { 1, 3, 1, 9, 25, 13, 11, 129, 371, 497, 597, 1257, 7291, 4021, 16223, 21489, 0 }; + static ulong[] dim4082Kuo3Init = { 1, 3, 5, 1, 5, 17, 119, 107, 267, 27, 87, 3641, 593, 4671, 16129, 25645, 0 }; + static ulong[] dim4083Kuo3Init = { 1, 3, 1, 7, 19, 55, 39, 159, 283, 551, 321, 1979, 1259, 10049, 15195, 62799, 0 }; + static ulong[] dim4084Kuo3Init = { 1, 3, 7, 3, 23, 43, 63, 187, 399, 725, 419, 1759, 5477, 4743, 13397, 21347, 0 }; + static ulong[] dim4085Kuo3Init = { 1, 1, 1, 7, 3, 45, 55, 207, 33, 695, 1109, 1427, 5425, 4743, 28949, 54665, 0 }; + static ulong[] dim4086Kuo3Init = { 1, 1, 5, 5, 19, 1, 97, 151, 465, 767, 1931, 1097, 7001, 5761, 30323, 17501, 0 }; + static ulong[] dim4087Kuo3Init = { 1, 3, 1, 9, 9, 11, 9, 165, 181, 711, 45, 1163, 11, 9127, 31361, 11259, 0 }; + static ulong[] dim4088Kuo3Init = { 1, 3, 3, 1, 23, 23, 7, 115, 243, 281, 847, 3091, 6383, 4593, 13507, 58001, 0 }; + static ulong[] dim4089Kuo3Init = { 1, 1, 3, 13, 27, 3, 123, 91, 47, 483, 1913, 2139, 3877, 16373, 31969, 42977, 0 }; + static ulong[] dim4090Kuo3Init = { 1, 1, 1, 3, 11, 9, 35, 3, 155, 585, 1193, 1887, 1657, 2479, 18803, 47309, 0 }; + static ulong[] dim4091Kuo3Init = { 1, 3, 3, 5, 5, 57, 79, 77, 205, 361, 505, 2505, 2959, 1345, 8165, 46001, 0 }; + static ulong[] dim4092Kuo3Init = { 1, 1, 1, 5, 29, 25, 35, 209, 193, 177, 291, 1095, 7137, 4323, 673, 37571, 0 }; + static ulong[] dim4093Kuo3Init = { 1, 3, 5, 5, 27, 29, 107, 161, 93, 585, 1061, 3281, 5565, 5093, 4511, 45327, 0 }; + static ulong[] dim4094Kuo3Init = { 1, 3, 7, 7, 15, 43, 41, 61, 425, 451, 1775, 345, 7851, 12907, 9467, 25705, 0 }; + static ulong[] dim4095Kuo3Init = { 1, 1, 1, 15, 31, 37, 105, 227, 155, 201, 653, 2343, 4601, 1331, 9193, 28423, 0 }; + static ulong[] dim4096Kuo3Init = { 1, 1, 5, 9, 31, 61, 19, 165, 491, 121, 159, 485, 7847, 4993, 30405, 22889, 0 }; + static ulong[] dim4097Kuo3Init = { 1, 3, 1, 5, 27, 35, 81, 231, 345, 519, 849, 539, 627, 16141, 26509, 8965, 0 }; + static ulong[] dim4098Kuo3Init = { 1, 1, 3, 3, 7, 33, 81, 51, 415, 785, 1617, 669, 4749, 737, 15557, 61779, 0 }; + static ulong[] dim4099Kuo3Init = { 1, 3, 5, 15, 5, 39, 47, 199, 313, 193, 1797, 2425, 327, 5111, 275, 45933, 0 }; + static ulong[] dim4100Kuo3Init = { 1, 3, 1, 5, 1, 27, 61, 1, 435, 1005, 665, 3099, 1153, 12721, 25537, 62559, 0 }; + static ulong[] dim4101Kuo3Init = { 1, 3, 7, 9, 29, 43, 97, 213, 43, 333, 25, 3085, 2709, 5917, 5887, 3847, 0 }; + static ulong[] dim4102Kuo3Init = { 1, 1, 7, 5, 17, 27, 93, 45, 205, 29, 2035, 4053, 6525, 12321, 26175, 43979, 0 }; + static ulong[] dim4103Kuo3Init = { 1, 1, 3, 3, 9, 41, 23, 215, 163, 531, 1753, 2377, 5533, 8681, 12213, 36789, 0 }; + static ulong[] dim4104Kuo3Init = { 1, 3, 1, 3, 7, 13, 25, 111, 439, 695, 1855, 2437, 4477, 10207, 4089, 43521, 0 }; + static ulong[] dim4105Kuo3Init = { 1, 1, 3, 9, 23, 7, 85, 123, 361, 913, 1817, 1547, 7969, 9731, 10553, 53879, 0 }; + static ulong[] dim4106Kuo3Init = { 1, 1, 7, 13, 29, 25, 5, 129, 211, 511, 45, 907, 1997, 15657, 9003, 47267, 0 }; + static ulong[] dim4107Kuo3Init = { 1, 3, 1, 9, 15, 49, 13, 131, 43, 295, 1569, 2675, 7857, 15515, 9189, 33061, 0 }; + static ulong[] dim4108Kuo3Init = { 1, 3, 7, 9, 29, 3, 85, 125, 403, 583, 1507, 73, 4701, 1117, 12271, 11387, 0 }; + static ulong[] dim4109Kuo3Init = { 1, 1, 3, 5, 3, 15, 1, 63, 319, 43, 913, 3029, 557, 3087, 18605, 39477, 0 }; + static ulong[] dim4110Kuo3Init = { 1, 1, 7, 13, 31, 51, 99, 103, 343, 835, 313, 2025, 7109, 5373, 20821, 55649, 0 }; + static ulong[] dim4111Kuo3Init = { 1, 1, 3, 7, 7, 21, 53, 123, 189, 1013, 427, 2773, 6567, 5241, 29647, 41591, 0 }; + static ulong[] dim4112Kuo3Init = { 1, 1, 1, 3, 29, 53, 127, 159, 327, 999, 1357, 989, 4401, 10949, 32555, 5097, 0 }; + static ulong[] dim4113Kuo3Init = { 1, 3, 1, 9, 31, 11, 75, 47, 307, 251, 1845, 1543, 6901, 3959, 18371, 40149, 0 }; + static ulong[] dim4114Kuo3Init = { 1, 1, 7, 11, 31, 47, 81, 17, 17, 21, 807, 3115, 5447, 11191, 2357, 2263, 0 }; + static ulong[] dim4115Kuo3Init = { 1, 1, 5, 13, 25, 41, 93, 135, 251, 165, 805, 1805, 2895, 11725, 6389, 21875, 0 }; + static ulong[] dim4116Kuo3Init = { 1, 1, 5, 5, 19, 37, 19, 247, 25, 241, 767, 2883, 5951, 531, 22893, 47493, 0 }; + static ulong[] dim4117Kuo3Init = { 1, 3, 1, 11, 31, 49, 23, 199, 337, 311, 1929, 2703, 4339, 6477, 1821, 4729, 0 }; + static ulong[] dim4118Kuo3Init = { 1, 1, 3, 11, 7, 59, 119, 3, 289, 951, 1387, 2999, 6617, 14551, 22081, 14187, 0 }; + static ulong[] dim4119Kuo3Init = { 1, 1, 5, 5, 13, 33, 37, 97, 501, 247, 651, 209, 7517, 2847, 3549, 16479, 0 }; + static ulong[] dim4120Kuo3Init = { 1, 1, 3, 1, 25, 45, 83, 207, 115, 1023, 543, 2851, 3383, 4177, 25567, 2797, 0 }; + static ulong[] dim4121Kuo3Init = { 1, 3, 3, 5, 7, 9, 127, 243, 501, 653, 1071, 2547, 6995, 10811, 4791, 50157, 0 }; + static ulong[] dim4122Kuo3Init = { 1, 1, 1, 11, 27, 61, 65, 117, 373, 191, 1643, 1057, 6013, 15167, 18815, 4225, 0 }; + static ulong[] dim4123Kuo3Init = { 1, 1, 1, 11, 9, 25, 105, 225, 247, 609, 325, 2761, 515, 9985, 6977, 57207, 0 }; + static ulong[] dim4124Kuo3Init = { 1, 1, 7, 15, 5, 43, 33, 45, 301, 1017, 1881, 83, 95, 10417, 2307, 6915, 0 }; + static ulong[] dim4125Kuo3Init = { 1, 3, 1, 3, 25, 43, 27, 81, 249, 239, 1671, 1215, 3139, 7961, 28509, 27099, 0 }; + static ulong[] dim4126Kuo3Init = { 1, 1, 3, 1, 17, 29, 49, 81, 503, 429, 2037, 2243, 7509, 12359, 14681, 21661, 0 }; + static ulong[] dim4127Kuo3Init = { 1, 3, 5, 3, 3, 63, 71, 71, 375, 999, 11, 2475, 4491, 7439, 5915, 63169, 0 }; + static ulong[] dim4128Kuo3Init = { 1, 1, 7, 13, 31, 35, 91, 27, 151, 893, 525, 1913, 2795, 10377, 1173, 44175, 0 }; + static ulong[] dim4129Kuo3Init = { 1, 1, 7, 15, 23, 11, 69, 77, 133, 307, 1589, 2795, 1183, 1491, 4661, 51315, 0 }; + static ulong[] dim4130Kuo3Init = { 1, 1, 7, 3, 27, 37, 9, 67, 481, 113, 7, 1679, 217, 6195, 18147, 50839, 0 }; + static ulong[] dim4131Kuo3Init = { 1, 1, 5, 1, 3, 37, 53, 127, 19, 177, 1851, 921, 1009, 9577, 24637, 2491, 0 }; + static ulong[] dim4132Kuo3Init = { 1, 3, 7, 5, 19, 33, 65, 25, 333, 749, 1577, 143, 6731, 2411, 25579, 57987, 0 }; + static ulong[] dim4133Kuo3Init = { 1, 1, 5, 3, 29, 45, 89, 179, 147, 411, 1831, 2209, 499, 3141, 17357, 23229, 0 }; + static ulong[] dim4134Kuo3Init = { 1, 1, 5, 1, 25, 41, 105, 165, 369, 241, 299, 875, 1231, 469, 4203, 27117, 0 }; + static ulong[] dim4135Kuo3Init = { 1, 3, 1, 5, 29, 35, 95, 235, 229, 797, 411, 71, 4571, 2341, 4095, 28185, 0 }; + static ulong[] dim4136Kuo3Init = { 1, 1, 1, 7, 21, 33, 23, 59, 195, 539, 1131, 3799, 8093, 8247, 6283, 44143, 0 }; + static ulong[] dim4137Kuo3Init = { 1, 1, 5, 15, 11, 15, 45, 99, 73, 983, 1047, 361, 2925, 1985, 20379, 63235, 0 }; + static ulong[] dim4138Kuo3Init = { 1, 3, 7, 5, 25, 7, 29, 129, 257, 1015, 1823, 23, 5031, 12153, 13511, 57897, 0 }; + static ulong[] dim4139Kuo3Init = { 1, 1, 1, 7, 15, 39, 57, 173, 391, 979, 569, 2051, 3221, 9561, 24331, 39791, 0 }; + static ulong[] dim4140Kuo3Init = { 1, 1, 3, 15, 1, 51, 25, 79, 373, 639, 5, 3237, 2983, 12491, 15991, 12467, 0 }; + static ulong[] dim4141Kuo3Init = { 1, 1, 7, 15, 17, 21, 103, 55, 233, 605, 597, 1867, 2147, 11047, 1173, 27237, 0 }; + static ulong[] dim4142Kuo3Init = { 1, 1, 7, 11, 11, 25, 43, 63, 143, 829, 1357, 2199, 5219, 15981, 15615, 22207, 0 }; + static ulong[] dim4143Kuo3Init = { 1, 1, 3, 13, 17, 53, 121, 131, 501, 355, 533, 2343, 6515, 9115, 29065, 64569, 0 }; + static ulong[] dim4144Kuo3Init = { 1, 3, 5, 15, 27, 57, 5, 105, 327, 861, 931, 3085, 5051, 12687, 22409, 57487, 0 }; + static ulong[] dim4145Kuo3Init = { 1, 1, 5, 15, 1, 53, 65, 97, 315, 413, 37, 2563, 4805, 2327, 10261, 7281, 0 }; + static ulong[] dim4146Kuo3Init = { 1, 3, 5, 9, 19, 57, 15, 75, 161, 245, 1215, 1735, 4567, 109, 8467, 43139, 0 }; + static ulong[] dim4147Kuo3Init = { 1, 3, 1, 11, 21, 55, 95, 11, 193, 959, 793, 3321, 5865, 301, 7887, 7389, 0 }; + static ulong[] dim4148Kuo3Init = { 1, 1, 1, 7, 31, 35, 27, 89, 247, 491, 1087, 3955, 6317, 1337, 21619, 11739, 0 }; + static ulong[] dim4149Kuo3Init = { 1, 1, 7, 13, 21, 59, 53, 211, 403, 851, 887, 1457, 539, 4493, 16571, 55429, 0 }; + static ulong[] dim4150Kuo3Init = { 1, 1, 1, 7, 23, 33, 69, 129, 33, 203, 267, 3261, 4179, 9653, 22523, 18779, 0 }; + static ulong[] dim4151Kuo3Init = { 1, 1, 3, 9, 31, 35, 7, 189, 253, 583, 1475, 939, 2977, 5573, 20047, 38915, 0 }; + static ulong[] dim4152Kuo3Init = { 1, 3, 3, 13, 19, 25, 61, 237, 479, 821, 1173, 599, 7035, 12695, 433, 26499, 0 }; + static ulong[] dim4153Kuo3Init = { 1, 3, 7, 3, 27, 47, 29, 31, 327, 687, 495, 987, 1655, 951, 29265, 28641, 0 }; + static ulong[] dim4154Kuo3Init = { 1, 1, 3, 1, 25, 29, 15, 139, 417, 837, 2011, 3703, 7809, 421, 207, 18961, 0 }; + static ulong[] dim4155Kuo3Init = { 1, 3, 3, 13, 7, 29, 19, 63, 257, 695, 161, 3023, 149, 10707, 20873, 61881, 0 }; + static ulong[] dim4156Kuo3Init = { 1, 3, 3, 7, 5, 9, 69, 31, 487, 525, 1441, 5, 3891, 14473, 22123, 40041, 0 }; + static ulong[] dim4157Kuo3Init = { 1, 3, 7, 15, 13, 37, 75, 181, 431, 753, 1587, 595, 2567, 8155, 23199, 50647, 0 }; + static ulong[] dim4158Kuo3Init = { 1, 1, 5, 1, 21, 63, 39, 245, 171, 217, 1643, 887, 2349, 2415, 31673, 51007, 0 }; + static ulong[] dim4159Kuo3Init = { 1, 3, 5, 9, 19, 33, 107, 227, 187, 163, 1071, 2385, 2701, 15969, 18665, 62089, 0 }; + static ulong[] dim4160Kuo3Init = { 1, 1, 1, 15, 27, 47, 25, 219, 139, 879, 459, 1521, 2153, 3429, 28293, 57703, 0 }; + static ulong[] dim4161Kuo3Init = { 1, 3, 3, 15, 15, 63, 23, 237, 137, 271, 117, 3047, 3973, 3379, 11527, 52555, 0 }; + static ulong[] dim4162Kuo3Init = { 1, 3, 7, 1, 19, 27, 19, 111, 441, 279, 321, 2015, 4451, 11841, 17223, 51691, 0 }; + static ulong[] dim4163Kuo3Init = { 1, 3, 3, 1, 15, 35, 19, 31, 277, 977, 1125, 2435, 5171, 81, 31729, 18883, 0 }; + static ulong[] dim4164Kuo3Init = { 1, 3, 1, 15, 19, 31, 105, 13, 117, 533, 191, 3651, 6915, 2423, 31819, 47709, 0 }; + static ulong[] dim4165Kuo3Init = { 1, 1, 5, 11, 29, 45, 17, 51, 283, 297, 1605, 3009, 3137, 2665, 27799, 2293, 0 }; + static ulong[] dim4166Kuo3Init = { 1, 3, 5, 13, 29, 61, 91, 7, 23, 835, 1809, 3283, 1091, 10443, 26547, 10685, 0 }; + static ulong[] dim4167Kuo3Init = { 1, 3, 5, 1, 1, 29, 121, 181, 43, 827, 871, 3547, 4285, 12551, 2079, 19385, 0 }; + static ulong[] dim4168Kuo3Init = { 1, 1, 1, 7, 3, 53, 73, 39, 1, 499, 1905, 3785, 1597, 1529, 9423, 11555, 0 }; + static ulong[] dim4169Kuo3Init = { 1, 1, 5, 5, 27, 25, 33, 59, 327, 419, 1527, 255, 6877, 3927, 11877, 21747, 0 }; + static ulong[] dim4170Kuo3Init = { 1, 1, 3, 11, 27, 37, 99, 161, 213, 321, 1127, 523, 5327, 7885, 17403, 2097, 0 }; + static ulong[] dim4171Kuo3Init = { 1, 1, 1, 3, 5, 11, 119, 153, 503, 1007, 187, 1705, 7499, 12739, 16185, 11121, 0 }; + static ulong[] dim4172Kuo3Init = { 1, 1, 3, 1, 27, 63, 29, 239, 5, 377, 831, 2883, 2167, 2551, 29891, 6165, 0 }; + static ulong[] dim4173Kuo3Init = { 1, 3, 7, 11, 5, 57, 33, 15, 425, 93, 1435, 1449, 1629, 999, 27037, 51171, 0 }; + static ulong[] dim4174Kuo3Init = { 1, 1, 5, 13, 1, 31, 83, 19, 373, 497, 1173, 775, 439, 5757, 32143, 52487, 0 }; + static ulong[] dim4175Kuo3Init = { 1, 1, 5, 11, 15, 43, 73, 19, 259, 145, 1771, 2133, 6969, 8571, 29821, 19581, 0 }; + static ulong[] dim4176Kuo3Init = { 1, 3, 3, 5, 25, 63, 43, 95, 215, 853, 127, 3737, 4803, 10089, 3537, 14671, 0 }; + static ulong[] dim4177Kuo3Init = { 1, 1, 3, 1, 31, 17, 1, 139, 199, 841, 1859, 1767, 1545, 4869, 14501, 11729, 0 }; + static ulong[] dim4178Kuo3Init = { 1, 3, 5, 13, 29, 57, 43, 143, 55, 893, 1219, 2415, 7605, 11091, 3441, 45749, 0 }; + static ulong[] dim4179Kuo3Init = { 1, 3, 7, 13, 27, 11, 27, 15, 67, 49, 967, 1919, 1773, 9135, 4607, 65495, 0 }; + static ulong[] dim4180Kuo3Init = { 1, 1, 1, 5, 7, 11, 63, 39, 209, 41, 951, 63, 1537, 9971, 9659, 17825, 0 }; + static ulong[] dim4181Kuo3Init = { 1, 3, 7, 7, 27, 25, 57, 53, 91, 1013, 591, 261, 721, 2061, 629, 37817, 0 }; + static ulong[] dim4182Kuo3Init = { 1, 1, 5, 15, 23, 35, 71, 43, 343, 329, 295, 3523, 275, 2119, 15165, 2809, 0 }; + static ulong[] dim4183Kuo3Init = { 1, 1, 5, 13, 19, 3, 121, 67, 165, 909, 1731, 437, 8055, 11683, 12735, 29129, 0 }; + static ulong[] dim4184Kuo3Init = { 1, 3, 5, 7, 21, 47, 113, 55, 169, 133, 2029, 825, 4079, 14651, 22373, 15009, 0 }; + static ulong[] dim4185Kuo3Init = { 1, 1, 5, 7, 25, 23, 61, 147, 211, 665, 395, 505, 3757, 14545, 10683, 53211, 0 }; + static ulong[] dim4186Kuo3Init = { 1, 1, 1, 3, 17, 25, 111, 171, 493, 815, 847, 2109, 8013, 751, 26793, 62903, 0 }; + static ulong[] dim4187Kuo3Init = { 1, 3, 7, 11, 7, 27, 91, 61, 385, 3, 577, 3515, 4335, 4261, 6053, 62513, 0 }; + static ulong[] dim4188Kuo3Init = { 1, 3, 7, 5, 17, 5, 21, 217, 227, 443, 1479, 2855, 2581, 6255, 23363, 37437, 0 }; + static ulong[] dim4189Kuo3Init = { 1, 1, 5, 5, 5, 51, 5, 213, 233, 787, 719, 463, 2595, 4019, 16839, 14671, 0 }; + static ulong[] dim4190Kuo3Init = { 1, 1, 1, 15, 11, 5, 49, 135, 85, 773, 1719, 2187, 449, 14913, 19721, 59583, 0 }; + static ulong[] dim4191Kuo3Init = { 1, 1, 1, 13, 3, 49, 77, 217, 289, 889, 63, 2547, 5547, 14005, 18657, 65109, 0 }; + static ulong[] dim4192Kuo3Init = { 1, 3, 5, 9, 11, 47, 19, 251, 77, 623, 1253, 635, 1047, 525, 8573, 25951, 0 }; + static ulong[] dim4193Kuo3Init = { 1, 1, 1, 13, 5, 21, 35, 187, 395, 547, 2003, 3189, 4107, 567, 29239, 32647, 0 }; + static ulong[] dim4194Kuo3Init = { 1, 1, 3, 13, 13, 61, 59, 57, 91, 881, 1665, 453, 6313, 2291, 19523, 60439, 0 }; + static ulong[] dim4195Kuo3Init = { 1, 1, 3, 3, 7, 7, 7, 127, 411, 643, 1415, 2933, 6649, 4219, 31781, 8733, 0 }; + static ulong[] dim4196Kuo3Init = { 1, 3, 1, 1, 25, 29, 127, 235, 271, 831, 1909, 2347, 7085, 8339, 22459, 48791, 0 }; + static ulong[] dim4197Kuo3Init = { 1, 3, 7, 11, 21, 19, 31, 5, 509, 713, 767, 1801, 6937, 1763, 20703, 10153, 0 }; + static ulong[] dim4198Kuo3Init = { 1, 3, 5, 3, 9, 35, 55, 215, 75, 733, 1773, 1373, 43, 5045, 17675, 29615, 0 }; + static ulong[] dim4199Kuo3Init = { 1, 3, 5, 13, 25, 27, 33, 167, 277, 231, 449, 1055, 6227, 1441, 29535, 30421, 0 }; + static ulong[] dim4200Kuo3Init = { 1, 1, 5, 15, 31, 63, 69, 137, 41, 67, 965, 3737, 3191, 2613, 8229, 47453, 0 }; + static ulong[] dim4201Kuo3Init = { 1, 1, 3, 7, 9, 13, 97, 31, 279, 525, 185, 1673, 1269, 8305, 29745, 5799, 0 }; + static ulong[] dim4202Kuo3Init = { 1, 3, 3, 13, 27, 47, 97, 185, 483, 787, 1049, 4073, 1985, 2129, 15099, 33307, 0 }; + static ulong[] dim4203Kuo3Init = { 1, 1, 7, 13, 21, 25, 97, 49, 377, 75, 1875, 2389, 1381, 6691, 30447, 23969, 0 }; + static ulong[] dim4204Kuo3Init = { 1, 1, 7, 1, 3, 55, 111, 185, 371, 331, 1471, 1211, 1523, 5393, 21763, 44333, 0 }; + static ulong[] dim4205Kuo3Init = { 1, 3, 1, 3, 19, 39, 35, 49, 433, 937, 869, 239, 7775, 9591, 16969, 43455, 0 }; + static ulong[] dim4206Kuo3Init = { 1, 3, 3, 11, 21, 11, 11, 201, 187, 409, 1603, 3471, 1473, 5283, 7109, 53219, 0 }; + static ulong[] dim4207Kuo3Init = { 1, 3, 1, 1, 13, 55, 91, 37, 71, 837, 1779, 1097, 7433, 5969, 22781, 28547, 0 }; + static ulong[] dim4208Kuo3Init = { 1, 3, 3, 11, 9, 41, 29, 125, 151, 51, 667, 1387, 6695, 7957, 20469, 20987, 0 }; + static ulong[] dim4209Kuo3Init = { 1, 3, 1, 7, 23, 17, 91, 79, 249, 123, 1141, 2201, 7139, 5749, 20655, 18111, 0 }; + static ulong[] dim4210Kuo3Init = { 1, 3, 5, 11, 1, 35, 5, 219, 255, 549, 1159, 1641, 5063, 457, 24023, 61667, 0 }; + static ulong[] dim4211Kuo3Init = { 1, 1, 5, 9, 23, 45, 85, 81, 41, 327, 1923, 2043, 6737, 13609, 1833, 30563, 0 }; + static ulong[] dim4212Kuo3Init = { 1, 3, 3, 1, 9, 15, 81, 137, 353, 509, 799, 787, 5371, 4863, 29781, 40405, 0 }; + static ulong[] dim4213Kuo3Init = { 1, 3, 7, 5, 31, 17, 109, 123, 455, 155, 253, 1541, 2265, 16015, 32309, 40837, 0 }; + static ulong[] dim4214Kuo3Init = { 1, 1, 5, 15, 21, 59, 109, 3, 367, 411, 1601, 3577, 3155, 1659, 15193, 32453, 0 }; + static ulong[] dim4215Kuo3Init = { 1, 3, 5, 3, 3, 21, 123, 125, 163, 233, 125, 947, 1023, 7435, 30777, 14615, 0 }; + static ulong[] dim4216Kuo3Init = { 1, 3, 5, 9, 15, 29, 31, 101, 427, 379, 379, 1123, 1411, 10523, 24017, 43629, 0 }; + static ulong[] dim4217Kuo3Init = { 1, 1, 5, 15, 1, 27, 43, 239, 91, 967, 991, 2827, 6135, 1035, 25925, 42605, 0 }; + static ulong[] dim4218Kuo3Init = { 1, 3, 7, 9, 11, 53, 83, 127, 51, 1021, 2017, 593, 1445, 14597, 6517, 19667, 0 }; + static ulong[] dim4219Kuo3Init = { 1, 3, 7, 15, 9, 1, 17, 235, 321, 571, 1315, 3993, 5825, 8065, 13885, 48815, 0 }; + static ulong[] dim4220Kuo3Init = { 1, 1, 1, 15, 3, 7, 5, 197, 89, 23, 711, 1601, 3577, 737, 27565, 43365, 0 }; + static ulong[] dim4221Kuo3Init = { 1, 1, 5, 3, 19, 35, 15, 99, 177, 1013, 905, 755, 667, 21, 27039, 56601, 0 }; + static ulong[] dim4222Kuo3Init = { 1, 1, 3, 9, 13, 37, 37, 73, 75, 827, 169, 2417, 5457, 13851, 5443, 15731, 0 }; + static ulong[] dim4223Kuo3Init = { 1, 1, 3, 11, 11, 23, 21, 159, 59, 633, 1719, 203, 5655, 15887, 9067, 33597, 0 }; + static ulong[] dim4224Kuo3Init = { 1, 1, 7, 7, 27, 11, 55, 139, 309, 721, 99, 3371, 1411, 4531, 12751, 37745, 0 }; + static ulong[] dim4225Kuo3Init = { 1, 1, 1, 13, 31, 33, 37, 43, 125, 11, 1441, 3947, 7455, 6097, 15333, 32601, 0 }; + static ulong[] dim4226Kuo3Init = { 1, 1, 3, 15, 9, 43, 79, 217, 247, 229, 171, 3607, 4155, 1675, 3945, 41499, 0 }; + static ulong[] dim4227Kuo3Init = { 1, 1, 1, 9, 5, 59, 25, 175, 209, 291, 1419, 2339, 7039, 1327, 19653, 11563, 0 }; + static ulong[] dim4228Kuo3Init = { 1, 1, 3, 11, 5, 1, 103, 197, 111, 891, 163, 361, 2885, 3443, 25481, 47399, 0 }; + static ulong[] dim4229Kuo3Init = { 1, 3, 7, 1, 21, 49, 35, 179, 339, 505, 1121, 2393, 1181, 11389, 5851, 30553, 0 }; + static ulong[] dim4230Kuo3Init = { 1, 3, 7, 15, 31, 3, 23, 205, 3, 861, 1767, 1971, 2279, 4901, 22077, 54183, 0 }; + static ulong[] dim4231Kuo3Init = { 1, 3, 7, 11, 11, 1, 3, 165, 129, 767, 2007, 1913, 3701, 5761, 1985, 42383, 0 }; + static ulong[] dim4232Kuo3Init = { 1, 3, 3, 5, 3, 39, 31, 73, 55, 805, 545, 1577, 1409, 5693, 31995, 58057, 0 }; + static ulong[] dim4233Kuo3Init = { 1, 3, 1, 15, 21, 9, 69, 17, 497, 1003, 1123, 4023, 1921, 723, 19815, 11583, 0 }; + static ulong[] dim4234Kuo3Init = { 1, 1, 7, 1, 13, 31, 61, 189, 1, 805, 1321, 1973, 4133, 7789, 9735, 50237, 0 }; + static ulong[] dim4235Kuo3Init = { 1, 3, 7, 5, 1, 39, 67, 189, 139, 891, 171, 693, 5639, 12841, 12223, 64009, 0 }; + static ulong[] dim4236Kuo3Init = { 1, 1, 3, 1, 7, 1, 115, 41, 283, 463, 53, 1349, 3233, 7247, 28515, 23931, 0 }; + static ulong[] dim4237Kuo3Init = { 1, 3, 3, 1, 25, 31, 49, 177, 339, 103, 701, 3059, 6557, 8669, 13923, 46913, 0 }; + static ulong[] dim4238Kuo3Init = { 1, 1, 5, 5, 7, 47, 7, 153, 481, 1005, 615, 2483, 3519, 5297, 21749, 55945, 0 }; + static ulong[] dim4239Kuo3Init = { 1, 3, 5, 15, 15, 43, 105, 121, 419, 181, 1945, 3501, 3443, 5555, 27925, 18357, 0 }; + static ulong[] dim4240Kuo3Init = { 1, 3, 3, 5, 5, 63, 107, 225, 17, 503, 2033, 2059, 2621, 12675, 25015, 15115, 0 }; + static ulong[] dim4241Kuo3Init = { 1, 3, 5, 13, 5, 33, 39, 143, 293, 793, 159, 1349, 5483, 9303, 8269, 58221, 0 }; + static ulong[] dim4242Kuo3Init = { 1, 1, 1, 3, 13, 21, 15, 11, 489, 921, 47, 7, 7677, 3281, 1339, 1447, 0 }; + static ulong[] dim4243Kuo3Init = { 1, 1, 3, 11, 19, 61, 29, 45, 355, 671, 1029, 455, 5611, 14655, 22871, 17303, 0 }; + static ulong[] dim4244Kuo3Init = { 1, 1, 1, 11, 3, 29, 93, 83, 425, 689, 437, 1943, 457, 2497, 2573, 56827, 0 }; + static ulong[] dim4245Kuo3Init = { 1, 3, 7, 1, 3, 39, 17, 243, 475, 13, 199, 413, 5503, 1559, 8615, 5339, 0 }; + static ulong[] dim4246Kuo3Init = { 1, 1, 5, 13, 7, 17, 55, 243, 465, 957, 1347, 3247, 4613, 10821, 17377, 21765, 0 }; + static ulong[] dim4247Kuo3Init = { 1, 1, 3, 5, 15, 49, 109, 113, 19, 1007, 967, 685, 3195, 467, 1269, 27705, 0 }; + static ulong[] dim4248Kuo3Init = { 1, 3, 3, 15, 31, 25, 73, 73, 483, 565, 1739, 641, 4085, 10481, 30053, 52773, 0 }; + static ulong[] dim4249Kuo3Init = { 1, 1, 1, 1, 31, 17, 35, 85, 339, 93, 479, 2833, 681, 3123, 3753, 63989, 0 }; + static ulong[] dim4250Kuo3Init = { 1, 3, 7, 5, 25, 17, 23, 47, 83, 59, 1525, 2445, 4831, 2605, 20711, 34129, 0 }; + static ulong[] dim4251Kuo3Init = { 1, 3, 7, 9, 11, 29, 111, 239, 81, 855, 2039, 4051, 4619, 14095, 15765, 17195, 0 }; + static ulong[] dim4252Kuo3Init = { 1, 1, 5, 9, 17, 29, 105, 175, 497, 741, 1151, 767, 7211, 14699, 9351, 22163, 0 }; + static ulong[] dim4253Kuo3Init = { 1, 1, 3, 9, 23, 17, 23, 193, 25, 883, 347, 2429, 4023, 5477, 9365, 30625, 0 }; + static ulong[] dim4254Kuo3Init = { 1, 1, 7, 13, 31, 57, 115, 119, 413, 733, 1095, 3877, 4021, 8415, 16129, 49425, 0 }; + static ulong[] dim4255Kuo3Init = { 1, 3, 1, 3, 13, 39, 127, 97, 389, 993, 1941, 847, 5109, 8499, 18653, 20615, 0 }; + static ulong[] dim4256Kuo3Init = { 1, 1, 3, 7, 9, 33, 21, 11, 357, 653, 1423, 3525, 277, 13085, 2525, 16547, 0 }; + static ulong[] dim4257Kuo3Init = { 1, 3, 3, 1, 3, 63, 55, 137, 229, 359, 703, 2555, 3117, 9323, 3483, 52999, 0 }; + static ulong[] dim4258Kuo3Init = { 1, 3, 7, 1, 23, 7, 67, 119, 239, 951, 495, 645, 3047, 12393, 14837, 33015, 0 }; + static ulong[] dim4259Kuo3Init = { 1, 1, 5, 15, 23, 33, 19, 75, 365, 419, 905, 3485, 1097, 10639, 8627, 57441, 0 }; + static ulong[] dim4260Kuo3Init = { 1, 1, 3, 3, 5, 37, 83, 163, 483, 403, 1467, 309, 5113, 3567, 28425, 63963, 0 }; + static ulong[] dim4261Kuo3Init = { 1, 3, 3, 15, 21, 63, 59, 103, 261, 355, 1779, 1589, 7447, 10909, 23197, 31539, 0 }; + static ulong[] dim4262Kuo3Init = { 1, 1, 3, 11, 9, 39, 121, 7, 383, 975, 179, 505, 1551, 15397, 28277, 53023, 0 }; + static ulong[] dim4263Kuo3Init = { 1, 1, 5, 3, 31, 15, 29, 81, 291, 843, 507, 1291, 4533, 5333, 18841, 58999, 0 }; + static ulong[] dim4264Kuo3Init = { 1, 3, 1, 3, 3, 15, 107, 93, 15, 349, 1359, 151, 4859, 10435, 3669, 31713, 0 }; + static ulong[] dim4265Kuo3Init = { 1, 3, 5, 1, 21, 1, 45, 167, 25, 123, 905, 115, 2953, 15029, 31475, 37235, 0 }; + static ulong[] dim4266Kuo3Init = { 1, 3, 5, 11, 9, 35, 115, 49, 61, 29, 1529, 1311, 6293, 13505, 15033, 31879, 0 }; + static ulong[] dim4267Kuo3Init = { 1, 3, 1, 1, 1, 19, 21, 199, 489, 463, 1761, 2295, 2011, 14179, 22955, 22451, 0 }; + static ulong[] dim4268Kuo3Init = { 1, 3, 1, 3, 21, 59, 71, 27, 425, 459, 177, 2301, 4703, 5589, 12799, 44729, 0 }; + static ulong[] dim4269Kuo3Init = { 1, 3, 7, 15, 11, 43, 103, 207, 315, 805, 469, 4009, 4589, 9627, 13309, 929, 0 }; + static ulong[] dim4270Kuo3Init = { 1, 3, 5, 15, 3, 45, 49, 59, 25, 371, 859, 2687, 3767, 7395, 24579, 2657, 0 }; + static ulong[] dim4271Kuo3Init = { 1, 3, 3, 1, 13, 1, 39, 115, 497, 291, 1187, 3109, 6731, 7591, 2551, 49121, 0 }; + static ulong[] dim4272Kuo3Init = { 1, 3, 1, 1, 11, 37, 75, 39, 377, 67, 291, 1275, 7893, 16261, 27093, 30007, 0 }; + static ulong[] dim4273Kuo3Init = { 1, 1, 5, 15, 27, 31, 117, 145, 435, 739, 1855, 2703, 6125, 16333, 16209, 11649, 0 }; + static ulong[] dim4274Kuo3Init = { 1, 3, 5, 7, 5, 37, 3, 173, 461, 535, 295, 3097, 6275, 15703, 20079, 45413, 0 }; + static ulong[] dim4275Kuo3Init = { 1, 1, 5, 13, 9, 39, 39, 113, 113, 315, 697, 2433, 7637, 9895, 17979, 13837, 0 }; + static ulong[] dim4276Kuo3Init = { 1, 1, 7, 11, 7, 35, 113, 255, 309, 389, 757, 1649, 1871, 311, 3531, 15617, 0 }; + static ulong[] dim4277Kuo3Init = { 1, 1, 7, 5, 25, 7, 87, 99, 249, 687, 57, 2291, 3315, 14677, 15225, 16859, 0 }; + static ulong[] dim4278Kuo3Init = { 1, 1, 7, 1, 11, 23, 91, 25, 209, 227, 567, 183, 7419, 9873, 10653, 41705, 0 }; + static ulong[] dim4279Kuo3Init = { 1, 1, 1, 13, 19, 17, 47, 79, 187, 185, 187, 3959, 4221, 389, 1733, 62413, 0 }; + static ulong[] dim4280Kuo3Init = { 1, 3, 7, 9, 1, 27, 109, 59, 223, 451, 865, 3623, 2545, 6531, 14837, 40749, 0 }; + static ulong[] dim4281Kuo3Init = { 1, 1, 3, 7, 5, 9, 69, 201, 145, 445, 1787, 1995, 691, 11387, 21391, 19185, 0 }; + static ulong[] dim4282Kuo3Init = { 1, 3, 7, 3, 15, 31, 61, 121, 295, 93, 1157, 2821, 2907, 6995, 17563, 4613, 0 }; + static ulong[] dim4283Kuo3Init = { 1, 3, 5, 3, 3, 41, 43, 199, 319, 903, 1699, 3599, 6567, 12851, 21253, 49715, 0 }; + static ulong[] dim4284Kuo3Init = { 1, 1, 5, 1, 25, 59, 7, 107, 405, 365, 1159, 2357, 1645, 16353, 31521, 13587, 0 }; + static ulong[] dim4285Kuo3Init = { 1, 3, 3, 1, 29, 25, 109, 181, 475, 117, 809, 2741, 5113, 9973, 31763, 20201, 0 }; + static ulong[] dim4286Kuo3Init = { 1, 3, 3, 9, 29, 43, 51, 239, 359, 137, 419, 43, 4091, 11107, 2121, 5057, 0 }; + static ulong[] dim4287Kuo3Init = { 1, 3, 1, 7, 13, 17, 65, 151, 289, 37, 1321, 3853, 7513, 3161, 6517, 27777, 0 }; + static ulong[] dim4288Kuo3Init = { 1, 1, 3, 13, 13, 31, 125, 13, 507, 491, 669, 2913, 8067, 4257, 11413, 8003, 0 }; + static ulong[] dim4289Kuo3Init = { 1, 1, 7, 1, 23, 57, 125, 227, 341, 647, 907, 1503, 1541, 14311, 10591, 49967, 0 }; + static ulong[] dim4290Kuo3Init = { 1, 3, 1, 15, 25, 29, 83, 39, 141, 545, 1213, 2001, 6627, 8701, 19205, 2859, 0 }; + static ulong[] dim4291Kuo3Init = { 1, 1, 7, 13, 11, 25, 93, 91, 471, 907, 793, 3045, 8137, 5095, 12445, 41967, 0 }; + static ulong[] dim4292Kuo3Init = { 1, 1, 5, 1, 25, 45, 13, 191, 373, 371, 1321, 3381, 3945, 9097, 7785, 44469, 0 }; + static ulong[] dim4293Kuo3Init = { 1, 3, 3, 13, 13, 19, 53, 189, 183, 115, 1957, 91, 113, 5839, 23783, 63959, 0 }; + static ulong[] dim4294Kuo3Init = { 1, 3, 1, 7, 3, 19, 71, 219, 393, 369, 107, 3729, 7457, 12379, 28647, 54159, 0 }; + static ulong[] dim4295Kuo3Init = { 1, 1, 1, 9, 5, 43, 15, 125, 297, 145, 1837, 2143, 305, 793, 14663, 313, 0 }; + static ulong[] dim4296Kuo3Init = { 1, 3, 1, 5, 17, 57, 67, 51, 211, 817, 2023, 1615, 4379, 12165, 30433, 44479, 0 }; + static ulong[] dim4297Kuo3Init = { 1, 1, 7, 1, 9, 49, 71, 231, 159, 179, 2027, 4043, 1053, 3679, 9035, 4173, 0 }; + static ulong[] dim4298Kuo3Init = { 1, 3, 7, 3, 17, 5, 33, 151, 223, 331, 1777, 2467, 7949, 2571, 9099, 58751, 0 }; + static ulong[] dim4299Kuo3Init = { 1, 3, 1, 15, 5, 23, 85, 113, 369, 607, 505, 1791, 1597, 12933, 28853, 13207, 0 }; + static ulong[] dim4300Kuo3Init = { 1, 1, 5, 15, 11, 39, 107, 81, 345, 815, 2025, 803, 1779, 15499, 26197, 6045, 0 }; + static ulong[] dim4301Kuo3Init = { 1, 3, 1, 9, 1, 3, 41, 29, 213, 295, 1561, 2631, 6231, 3255, 11309, 22853, 0 }; + static ulong[] dim4302Kuo3Init = { 1, 3, 7, 9, 19, 21, 127, 57, 425, 551, 171, 903, 7747, 5251, 11457, 57735, 0 }; + static ulong[] dim4303Kuo3Init = { 1, 1, 1, 11, 29, 5, 33, 221, 91, 435, 1341, 1627, 4269, 8689, 19, 9609, 0 }; + static ulong[] dim4304Kuo3Init = { 1, 3, 1, 9, 11, 1, 101, 219, 45, 317, 793, 823, 2449, 7911, 3739, 2441, 0 }; + static ulong[] dim4305Kuo3Init = { 1, 3, 5, 7, 25, 51, 103, 179, 481, 999, 675, 1693, 193, 9987, 18519, 16777, 0 }; + static ulong[] dim4306Kuo3Init = { 1, 3, 5, 5, 15, 59, 83, 61, 329, 537, 1293, 459, 5059, 7943, 3569, 34727, 0 }; + static ulong[] dim4307Kuo3Init = { 1, 3, 3, 9, 29, 17, 41, 171, 303, 123, 1945, 1383, 5823, 1569, 10699, 14585, 0 }; + static ulong[] dim4308Kuo3Init = { 1, 1, 1, 11, 7, 11, 35, 193, 69, 487, 879, 693, 6367, 7381, 11463, 50741, 0 }; + static ulong[] dim4309Kuo3Init = { 1, 3, 1, 11, 9, 17, 5, 155, 443, 543, 643, 1595, 319, 2877, 27849, 8365, 0 }; + static ulong[] dim4310Kuo3Init = { 1, 3, 7, 15, 3, 43, 111, 219, 35, 595, 541, 3299, 4117, 265, 2817, 60825, 0 }; + static ulong[] dim4311Kuo3Init = { 1, 3, 5, 5, 13, 15, 45, 211, 21, 1019, 1015, 1051, 2879, 15077, 19851, 6615, 0 }; + static ulong[] dim4312Kuo3Init = { 1, 1, 7, 13, 15, 59, 7, 201, 215, 217, 967, 2013, 907, 12073, 9105, 44873, 0 }; + static ulong[] dim4313Kuo3Init = { 1, 1, 1, 13, 1, 3, 117, 253, 493, 727, 1997, 3325, 2757, 11313, 7439, 18863, 0 }; + static ulong[] dim4314Kuo3Init = { 1, 1, 7, 11, 5, 23, 97, 169, 63, 243, 419, 3259, 2521, 13055, 3223, 36055, 0 }; + static ulong[] dim4315Kuo3Init = { 1, 1, 5, 9, 9, 9, 63, 69, 305, 391, 1901, 2785, 7877, 7219, 10727, 13115, 0 }; + static ulong[] dim4316Kuo3Init = { 1, 1, 3, 7, 1, 63, 83, 27, 417, 537, 1969, 3083, 4267, 11153, 11205, 61249, 0 }; + static ulong[] dim4317Kuo3Init = { 1, 3, 3, 1, 11, 47, 79, 201, 449, 569, 809, 1575, 271, 651, 5459, 24805, 0 }; + static ulong[] dim4318Kuo3Init = { 1, 3, 7, 15, 29, 25, 103, 95, 57, 209, 1175, 2579, 3735, 1969, 29903, 65397, 0 }; + static ulong[] dim4319Kuo3Init = { 1, 3, 5, 1, 25, 41, 7, 239, 175, 395, 1261, 2567, 4875, 279, 25905, 43603, 0 }; + static ulong[] dim4320Kuo3Init = { 1, 3, 7, 1, 27, 7, 89, 111, 467, 691, 39, 1213, 5377, 13247, 31513, 58015, 0 }; + static ulong[] dim4321Kuo3Init = { 1, 1, 1, 15, 25, 1, 55, 131, 259, 923, 1623, 125, 2273, 4221, 21857, 49621, 0 }; + static ulong[] dim4322Kuo3Init = { 1, 1, 5, 3, 27, 1, 99, 95, 199, 773, 87, 2981, 8127, 6493, 27507, 52789, 0 }; + static ulong[] dim4323Kuo3Init = { 1, 1, 5, 9, 11, 39, 7, 7, 145, 933, 1301, 2975, 5237, 11619, 1423, 46351, 0 }; + static ulong[] dim4324Kuo3Init = { 1, 1, 7, 5, 17, 3, 29, 233, 195, 727, 1893, 3709, 1285, 12877, 30821, 30383, 0 }; + static ulong[] dim4325Kuo3Init = { 1, 3, 7, 15, 1, 7, 115, 55, 231, 769, 849, 1043, 3041, 5187, 14613, 58821, 0 }; + static ulong[] dim4326Kuo3Init = { 1, 3, 7, 3, 13, 41, 5, 245, 109, 785, 187, 391, 3333, 8193, 823, 27985, 0 }; + static ulong[] dim4327Kuo3Init = { 1, 1, 5, 11, 9, 33, 25, 231, 347, 313, 31, 59, 6189, 4249, 26963, 56975, 0 }; + static ulong[] dim4328Kuo3Init = { 1, 1, 5, 5, 27, 57, 87, 77, 209, 231, 173, 3691, 8095, 10353, 14217, 3263, 0 }; + static ulong[] dim4329Kuo3Init = { 1, 3, 1, 7, 1, 55, 115, 63, 13, 705, 865, 1901, 4209, 8195, 25245, 2313, 0 }; + static ulong[] dim4330Kuo3Init = { 1, 3, 5, 1, 13, 3, 53, 215, 345, 635, 1601, 241, 6491, 911, 5825, 34247, 0 }; + static ulong[] dim4331Kuo3Init = { 1, 1, 5, 5, 27, 21, 69, 83, 451, 33, 773, 2663, 5325, 16207, 15073, 32259, 0 }; + static ulong[] dim4332Kuo3Init = { 1, 1, 3, 9, 25, 33, 1, 35, 335, 355, 2005, 3087, 4577, 10533, 23641, 45297, 0 }; + static ulong[] dim4333Kuo3Init = { 1, 3, 3, 7, 21, 43, 103, 223, 269, 781, 1445, 461, 6777, 5251, 6483, 14425, 0 }; + static ulong[] dim4334Kuo3Init = { 1, 3, 7, 7, 21, 55, 113, 227, 227, 173, 575, 3187, 3965, 13569, 4809, 16217, 0 }; + static ulong[] dim4335Kuo3Init = { 1, 1, 5, 5, 23, 23, 67, 99, 257, 651, 495, 3427, 7653, 505, 2549, 9283, 0 }; + static ulong[] dim4336Kuo3Init = { 1, 1, 5, 5, 15, 39, 123, 27, 1, 5, 107, 4055, 7347, 6411, 28857, 45591, 0 }; + static ulong[] dim4337Kuo3Init = { 1, 3, 1, 5, 29, 57, 77, 67, 365, 25, 1475, 3583, 4315, 6725, 22635, 62003, 0 }; + static ulong[] dim4338Kuo3Init = { 1, 3, 1, 1, 11, 9, 19, 25, 399, 467, 501, 2081, 977, 7695, 12997, 11841, 0 }; + static ulong[] dim4339Kuo3Init = { 1, 1, 5, 15, 19, 37, 39, 69, 75, 343, 525, 433, 6771, 8697, 6041, 49701, 0 }; + static ulong[] dim4340Kuo3Init = { 1, 1, 3, 1, 21, 31, 5, 193, 467, 161, 929, 3967, 2629, 3031, 30715, 45539, 0 }; + static ulong[] dim4341Kuo3Init = { 1, 3, 3, 9, 25, 17, 87, 179, 385, 491, 965, 2809, 6937, 2669, 20963, 13333, 0 }; + static ulong[] dim4342Kuo3Init = { 1, 3, 1, 7, 25, 1, 83, 47, 99, 425, 1007, 2903, 2959, 12403, 19707, 60863, 0 }; + static ulong[] dim4343Kuo3Init = { 1, 1, 1, 15, 5, 19, 3, 181, 255, 135, 791, 3473, 3123, 5247, 28349, 5581, 0 }; + static ulong[] dim4344Kuo3Init = { 1, 1, 5, 13, 27, 13, 93, 215, 333, 667, 251, 2027, 6345, 8985, 22669, 46509, 0 }; + static ulong[] dim4345Kuo3Init = { 1, 1, 5, 9, 1, 27, 83, 107, 339, 699, 1197, 635, 2367, 6791, 9743, 9685, 0 }; + static ulong[] dim4346Kuo3Init = { 1, 3, 1, 7, 11, 43, 9, 37, 511, 177, 1957, 2697, 1879, 8219, 27525, 17737, 0 }; + static ulong[] dim4347Kuo3Init = { 1, 3, 1, 5, 3, 35, 81, 137, 193, 439, 35, 3743, 2973, 10245, 17111, 12025, 0 }; + static ulong[] dim4348Kuo3Init = { 1, 3, 3, 9, 3, 51, 7, 103, 65, 787, 1859, 1217, 8189, 2917, 2161, 64559, 0 }; + static ulong[] dim4349Kuo3Init = { 1, 3, 5, 5, 31, 9, 53, 45, 167, 877, 1169, 2375, 6631, 9699, 8345, 27223, 0 }; + static ulong[] dim4350Kuo3Init = { 1, 3, 5, 9, 1, 33, 113, 205, 153, 255, 63, 1517, 5225, 14485, 22053, 53333, 0 }; + static ulong[] dim4351Kuo3Init = { 1, 1, 1, 1, 7, 45, 95, 211, 13, 769, 1909, 1049, 2465, 11581, 2983, 55267, 0 }; + static ulong[] dim4352Kuo3Init = { 1, 1, 5, 3, 7, 27, 3, 47, 503, 7, 1223, 1979, 815, 12593, 4229, 30539, 0 }; + static ulong[] dim4353Kuo3Init = { 1, 3, 7, 15, 9, 3, 103, 217, 199, 567, 943, 1527, 7191, 15243, 26311, 44263, 0 }; + static ulong[] dim4354Kuo3Init = { 1, 3, 5, 11, 29, 13, 107, 107, 35, 367, 849, 4047, 6027, 8155, 10963, 9941, 0 }; + static ulong[] dim4355Kuo3Init = { 1, 1, 7, 1, 27, 49, 89, 59, 479, 477, 1351, 2165, 7611, 9745, 7023, 22153, 0 }; + static ulong[] dim4356Kuo3Init = { 1, 1, 3, 1, 5, 7, 21, 91, 13, 547, 493, 813, 4325, 751, 14753, 52131, 0 }; + static ulong[] dim4357Kuo3Init = { 1, 3, 1, 3, 23, 7, 55, 69, 335, 127, 1669, 2171, 6033, 3713, 16855, 36479, 0 }; + static ulong[] dim4358Kuo3Init = { 1, 3, 3, 9, 17, 35, 117, 85, 415, 1019, 15, 3033, 2933, 2113, 10909, 107, 0 }; + static ulong[] dim4359Kuo3Init = { 1, 1, 7, 3, 13, 45, 61, 31, 115, 569, 21, 375, 1955, 10699, 17307, 20119, 0 }; + static ulong[] dim4360Kuo3Init = { 1, 1, 1, 13, 29, 29, 101, 137, 457, 845, 39, 461, 5113, 1429, 25443, 60127, 0 }; + static ulong[] dim4361Kuo3Init = { 1, 1, 1, 3, 29, 39, 35, 45, 269, 327, 2023, 2799, 4893, 3751, 7579, 56975, 0 }; + static ulong[] dim4362Kuo3Init = { 1, 1, 3, 3, 3, 49, 45, 219, 133, 279, 2003, 4007, 409, 3697, 11629, 19359, 0 }; + static ulong[] dim4363Kuo3Init = { 1, 3, 5, 9, 25, 21, 85, 61, 131, 69, 1277, 249, 6265, 10245, 32575, 59735, 0 }; + static ulong[] dim4364Kuo3Init = { 1, 3, 5, 7, 1, 11, 63, 125, 57, 17, 111, 3521, 7397, 10985, 10193, 45493, 0 }; + static ulong[] dim4365Kuo3Init = { 1, 3, 5, 13, 31, 37, 115, 139, 203, 199, 559, 67, 7187, 5825, 6755, 43, 0 }; + static ulong[] dim4366Kuo3Init = { 1, 3, 3, 15, 7, 33, 41, 59, 487, 711, 247, 1095, 4113, 11349, 26331, 33159, 0 }; + static ulong[] dim4367Kuo3Init = { 1, 3, 7, 15, 25, 61, 57, 129, 409, 589, 1913, 1293, 7981, 8027, 789, 19655, 0 }; + static ulong[] dim4368Kuo3Init = { 1, 1, 5, 11, 29, 33, 55, 165, 315, 757, 1213, 2071, 4827, 6905, 7087, 22317, 0 }; + static ulong[] dim4369Kuo3Init = { 1, 3, 3, 1, 5, 7, 115, 161, 247, 91, 397, 1889, 2445, 13407, 20077, 50953, 0 }; + static ulong[] dim4370Kuo3Init = { 1, 1, 5, 1, 31, 43, 53, 67, 183, 85, 285, 475, 3345, 7783, 25383, 26213, 0 }; + static ulong[] dim4371Kuo3Init = { 1, 1, 1, 3, 21, 27, 127, 229, 135, 795, 287, 937, 5645, 2271, 26095, 18407, 0 }; + static ulong[] dim4372Kuo3Init = { 1, 3, 5, 13, 27, 39, 109, 183, 1, 343, 695, 3825, 4347, 8399, 30219, 41839, 0 }; + static ulong[] dim4373Kuo3Init = { 1, 1, 1, 3, 31, 3, 93, 139, 145, 107, 1311, 1919, 6631, 16363, 17473, 38661, 0 }; + static ulong[] dim4374Kuo3Init = { 1, 3, 3, 1, 23, 7, 17, 131, 505, 335, 19, 1037, 6985, 15181, 24857, 37363, 0 }; + static ulong[] dim4375Kuo3Init = { 1, 3, 7, 13, 5, 17, 51, 243, 221, 149, 801, 3179, 1929, 14145, 16541, 36911, 0 }; + static ulong[] dim4376Kuo3Init = { 1, 3, 1, 7, 15, 5, 19, 93, 117, 21, 1517, 2041, 5281, 7579, 23087, 37619, 0 }; + static ulong[] dim4377Kuo3Init = { 1, 3, 5, 1, 21, 33, 5, 187, 471, 483, 249, 1075, 4831, 5467, 2921, 60803, 0 }; + static ulong[] dim4378Kuo3Init = { 1, 1, 1, 1, 27, 57, 23, 185, 397, 945, 495, 2097, 7561, 1111, 30773, 61855, 0 }; + static ulong[] dim4379Kuo3Init = { 1, 1, 5, 5, 31, 53, 71, 125, 365, 947, 1685, 2871, 313, 5199, 11179, 18717, 0 }; + static ulong[] dim4380Kuo3Init = { 1, 3, 7, 13, 23, 41, 83, 79, 427, 877, 281, 3205, 865, 8021, 3423, 28111, 0 }; + static ulong[] dim4381Kuo3Init = { 1, 1, 3, 1, 29, 39, 11, 247, 45, 339, 1153, 1179, 6495, 6861, 15247, 44515, 0 }; + static ulong[] dim4382Kuo3Init = { 1, 3, 1, 1, 1, 21, 41, 211, 379, 99, 887, 2035, 847, 4679, 9941, 49585, 0 }; + static ulong[] dim4383Kuo3Init = { 1, 3, 1, 11, 17, 59, 29, 23, 355, 393, 323, 1843, 1373, 1995, 28417, 12167, 0 }; + static ulong[] dim4384Kuo3Init = { 1, 3, 7, 1, 31, 55, 105, 239, 509, 709, 415, 4015, 4597, 13861, 11553, 87, 0 }; + static ulong[] dim4385Kuo3Init = { 1, 3, 7, 15, 25, 55, 13, 19, 333, 371, 1829, 3879, 7199, 2849, 16885, 52575, 0 }; + static ulong[] dim4386Kuo3Init = { 1, 3, 5, 9, 27, 23, 55, 109, 465, 923, 905, 197, 4017, 2079, 10775, 55543, 0 }; + static ulong[] dim4387Kuo3Init = { 1, 1, 3, 7, 31, 49, 69, 181, 261, 71, 1727, 2717, 317, 13397, 26641, 37783, 0 }; + static ulong[] dim4388Kuo3Init = { 1, 3, 3, 15, 17, 55, 107, 201, 21, 279, 437, 3267, 999, 14787, 23727, 2563, 0 }; + static ulong[] dim4389Kuo3Init = { 1, 3, 1, 13, 27, 41, 19, 153, 435, 577, 327, 965, 7899, 11799, 4683, 49651, 0 }; + static ulong[] dim4390Kuo3Init = { 1, 3, 5, 15, 25, 47, 13, 243, 281, 201, 1455, 2369, 7947, 10993, 14715, 30099, 0 }; + static ulong[] dim4391Kuo3Init = { 1, 1, 3, 11, 17, 1, 49, 205, 303, 85, 823, 3721, 3155, 5473, 6019, 24837, 0 }; + static ulong[] dim4392Kuo3Init = { 1, 3, 1, 7, 5, 27, 65, 177, 405, 841, 1523, 43, 2309, 14041, 6705, 18145, 0 }; + static ulong[] dim4393Kuo3Init = { 1, 1, 7, 3, 25, 35, 53, 177, 233, 287, 1265, 3305, 4961, 2751, 8715, 56605, 0 }; + static ulong[] dim4394Kuo3Init = { 1, 3, 5, 3, 7, 9, 45, 179, 65, 153, 1861, 111, 5501, 3671, 25663, 46493, 0 }; + static ulong[] dim4395Kuo3Init = { 1, 3, 5, 11, 11, 37, 25, 199, 339, 313, 1823, 2933, 6459, 3359, 8577, 64109, 0 }; + static ulong[] dim4396Kuo3Init = { 1, 3, 1, 11, 5, 3, 127, 53, 77, 431, 931, 3159, 2267, 8123, 7581, 52237, 0 }; + static ulong[] dim4397Kuo3Init = { 1, 1, 5, 3, 1, 51, 41, 147, 481, 243, 2045, 3239, 8191, 7533, 25021, 46359, 0 }; + static ulong[] dim4398Kuo3Init = { 1, 1, 1, 7, 17, 1, 57, 141, 239, 375, 23, 3695, 827, 10783, 18109, 54029, 0 }; + static ulong[] dim4399Kuo3Init = { 1, 3, 1, 1, 13, 39, 35, 251, 271, 461, 313, 2807, 2927, 4639, 17175, 65325, 0 }; + static ulong[] dim4400Kuo3Init = { 1, 1, 7, 15, 1, 9, 123, 243, 451, 433, 1339, 1223, 3399, 12669, 20663, 27505, 0 }; + static ulong[] dim4401Kuo3Init = { 1, 1, 1, 5, 31, 25, 41, 225, 61, 525, 527, 1559, 5469, 2299, 3169, 12435, 0 }; + static ulong[] dim4402Kuo3Init = { 1, 1, 7, 1, 3, 45, 21, 99, 89, 97, 379, 1815, 5883, 9437, 32597, 14795, 0 }; + static ulong[] dim4403Kuo3Init = { 1, 3, 3, 3, 5, 17, 109, 185, 389, 291, 1041, 847, 957, 13413, 29763, 39789, 0 }; + static ulong[] dim4404Kuo3Init = { 1, 3, 5, 7, 31, 39, 63, 181, 297, 71, 199, 1655, 1497, 8981, 23785, 40839, 0 }; + static ulong[] dim4405Kuo3Init = { 1, 3, 5, 13, 23, 15, 25, 9, 361, 151, 1191, 943, 17, 715, 28593, 22609, 0 }; + static ulong[] dim4406Kuo3Init = { 1, 3, 7, 3, 27, 13, 99, 109, 97, 415, 1515, 701, 7153, 14207, 24417, 52673, 0 }; + static ulong[] dim4407Kuo3Init = { 1, 1, 1, 9, 15, 15, 15, 251, 23, 717, 219, 1783, 3657, 10141, 6525, 37683, 0 }; + static ulong[] dim4408Kuo3Init = { 1, 1, 1, 1, 5, 55, 19, 213, 99, 73, 227, 2029, 1225, 14849, 17073, 30409, 0 }; + static ulong[] dim4409Kuo3Init = { 1, 1, 3, 3, 15, 49, 49, 11, 289, 287, 999, 743, 1081, 3185, 30613, 25163, 0 }; + static ulong[] dim4410Kuo3Init = { 1, 1, 3, 11, 15, 21, 33, 53, 465, 45, 113, 2865, 2641, 13797, 27785, 63159, 0 }; + static ulong[] dim4411Kuo3Init = { 1, 1, 7, 13, 27, 5, 41, 21, 53, 675, 1217, 239, 7925, 6659, 15025, 56589, 0 }; + static ulong[] dim4412Kuo3Init = { 1, 1, 3, 15, 15, 1, 7, 129, 377, 1017, 1015, 329, 3153, 5815, 7929, 62579, 0 }; + static ulong[] dim4413Kuo3Init = { 1, 1, 7, 7, 19, 37, 23, 115, 29, 813, 1761, 751, 3461, 13027, 30853, 51399, 0 }; + static ulong[] dim4414Kuo3Init = { 1, 3, 1, 15, 1, 37, 125, 143, 117, 33, 321, 1917, 741, 1281, 4811, 30907, 0 }; + static ulong[] dim4415Kuo3Init = { 1, 1, 5, 9, 25, 55, 43, 69, 479, 37, 1891, 325, 7165, 11707, 11663, 9, 0 }; + static ulong[] dim4416Kuo3Init = { 1, 1, 1, 7, 13, 1, 37, 5, 195, 959, 1707, 3099, 2295, 1363, 14463, 37013, 0 }; + static ulong[] dim4417Kuo3Init = { 1, 1, 3, 1, 17, 45, 63, 189, 471, 273, 633, 977, 3377, 15191, 25127, 38949, 0 }; + static ulong[] dim4418Kuo3Init = { 1, 3, 7, 11, 11, 49, 107, 237, 365, 813, 841, 215, 5087, 4661, 8045, 39713, 0 }; + static ulong[] dim4419Kuo3Init = { 1, 1, 7, 7, 11, 39, 47, 23, 267, 929, 709, 2593, 3773, 8435, 15947, 43873, 0 }; + static ulong[] dim4420Kuo3Init = { 1, 3, 3, 1, 7, 45, 109, 121, 389, 15, 599, 2887, 4009, 13557, 6845, 10149, 0 }; + static ulong[] dim4421Kuo3Init = { 1, 1, 7, 11, 11, 45, 5, 39, 401, 467, 291, 1807, 3711, 13831, 11777, 28543, 0 }; + static ulong[] dim4422Kuo3Init = { 1, 3, 1, 5, 29, 29, 121, 33, 185, 135, 479, 3681, 4763, 6915, 6689, 45981, 0 }; + static ulong[] dim4423Kuo3Init = { 1, 1, 1, 13, 7, 57, 53, 39, 429, 985, 523, 2245, 8003, 3385, 31869, 30589, 0 }; + static ulong[] dim4424Kuo3Init = { 1, 1, 5, 3, 23, 21, 71, 229, 83, 327, 399, 1413, 5321, 10593, 19219, 32837, 0 }; + static ulong[] dim4425Kuo3Init = { 1, 3, 7, 7, 31, 37, 15, 119, 13, 949, 1589, 3247, 5671, 2141, 21189, 6353, 0 }; + static ulong[] dim4426Kuo3Init = { 1, 1, 1, 11, 13, 25, 77, 19, 261, 237, 1651, 1165, 4317, 3265, 13471, 34163, 0 }; + static ulong[] dim4427Kuo3Init = { 1, 3, 3, 3, 17, 53, 97, 245, 3, 177, 873, 2273, 3577, 10233, 3615, 38189, 0 }; + static ulong[] dim4428Kuo3Init = { 1, 1, 7, 9, 23, 63, 5, 115, 55, 825, 877, 101, 1167, 10583, 14171, 42343, 0 }; + static ulong[] dim4429Kuo3Init = { 1, 3, 7, 5, 3, 25, 119, 185, 295, 349, 587, 2497, 6103, 5755, 25191, 50015, 0 }; + static ulong[] dim4430Kuo3Init = { 1, 1, 7, 13, 11, 55, 55, 37, 229, 803, 911, 3081, 1543, 297, 187, 51775, 0 }; + static ulong[] dim4431Kuo3Init = { 1, 3, 1, 3, 31, 53, 105, 17, 219, 145, 1129, 431, 5651, 1963, 693, 18177, 0 }; + static ulong[] dim4432Kuo3Init = { 1, 1, 7, 3, 7, 29, 61, 199, 101, 553, 1765, 1657, 1843, 12557, 27261, 4877, 0 }; + static ulong[] dim4433Kuo3Init = { 1, 3, 1, 13, 19, 57, 33, 233, 179, 437, 1835, 3081, 7241, 4227, 18707, 27027, 0 }; + static ulong[] dim4434Kuo3Init = { 1, 1, 3, 15, 7, 61, 45, 55, 153, 97, 1081, 2937, 2911, 3927, 17915, 275, 0 }; + static ulong[] dim4435Kuo3Init = { 1, 3, 7, 15, 19, 25, 95, 85, 27, 589, 121, 2003, 4891, 6737, 4835, 10443, 0 }; + static ulong[] dim4436Kuo3Init = { 1, 1, 5, 7, 5, 61, 21, 7, 439, 351, 1119, 937, 5517, 5001, 18859, 12427, 0 }; + static ulong[] dim4437Kuo3Init = { 1, 1, 1, 1, 13, 21, 87, 73, 61, 71, 885, 4029, 2893, 833, 18813, 18617, 0 }; + static ulong[] dim4438Kuo3Init = { 1, 1, 5, 7, 23, 63, 111, 159, 39, 937, 719, 1641, 7901, 7349, 31397, 38111, 0 }; + static ulong[] dim4439Kuo3Init = { 1, 1, 5, 9, 9, 9, 105, 33, 205, 829, 1929, 1925, 1735, 10217, 1747, 38351, 0 }; + static ulong[] dim4440Kuo3Init = { 1, 3, 1, 13, 9, 13, 111, 39, 465, 635, 989, 2079, 7781, 13229, 1039, 21061, 0 }; + static ulong[] dim4441Kuo3Init = { 1, 3, 3, 1, 29, 15, 123, 137, 75, 561, 1699, 57, 8179, 5693, 6333, 25581, 0 }; + static ulong[] dim4442Kuo3Init = { 1, 1, 7, 9, 3, 17, 27, 117, 95, 287, 1313, 1863, 7119, 16253, 27931, 42341, 0 }; + static ulong[] dim4443Kuo3Init = { 1, 1, 1, 11, 21, 47, 83, 79, 451, 535, 1249, 1125, 5387, 11309, 12115, 45877, 0 }; + static ulong[] dim4444Kuo3Init = { 1, 1, 3, 7, 21, 17, 93, 125, 467, 465, 619, 1899, 5501, 233, 28371, 7199, 0 }; + static ulong[] dim4445Kuo3Init = { 1, 3, 7, 9, 3, 5, 5, 111, 107, 95, 2023, 3529, 5135, 3377, 22025, 41931, 0 }; + static ulong[] dim4446Kuo3Init = { 1, 1, 3, 13, 31, 19, 115, 155, 349, 911, 1893, 3617, 689, 16323, 13523, 20373, 0 }; + static ulong[] dim4447Kuo3Init = { 1, 1, 3, 5, 25, 7, 57, 117, 65, 469, 1669, 407, 3693, 1743, 16697, 30749, 0 }; + static ulong[] dim4448Kuo3Init = { 1, 1, 1, 5, 29, 11, 117, 187, 13, 77, 45, 39, 6237, 9899, 28805, 9389, 0 }; + static ulong[] dim4449Kuo3Init = { 1, 3, 1, 5, 5, 33, 43, 45, 331, 615, 961, 2143, 4403, 543, 22783, 47063, 0 }; + static ulong[] dim4450Kuo3Init = { 1, 3, 1, 11, 7, 1, 93, 153, 417, 859, 451, 1211, 6439, 8043, 5759, 60265, 0 }; + static ulong[] dim4451Kuo3Init = { 1, 3, 1, 9, 19, 53, 57, 93, 295, 773, 533, 2685, 7429, 2855, 7665, 46257, 0 }; + static ulong[] dim4452Kuo3Init = { 1, 3, 5, 15, 29, 5, 93, 159, 7, 845, 337, 881, 2529, 15677, 9795, 31347, 0 }; + static ulong[] dim4453Kuo3Init = { 1, 1, 3, 3, 11, 49, 97, 59, 157, 695, 65, 1865, 4107, 15283, 2309, 13841, 0 }; + static ulong[] dim4454Kuo3Init = { 1, 3, 3, 15, 21, 31, 61, 85, 361, 893, 1223, 259, 2771, 4973, 18661, 16653, 0 }; + static ulong[] dim4455Kuo3Init = { 1, 1, 1, 7, 19, 31, 3, 223, 151, 785, 447, 2123, 3377, 14159, 933, 23357, 0 }; + static ulong[] dim4456Kuo3Init = { 1, 3, 5, 11, 1, 55, 77, 107, 245, 193, 583, 2729, 831, 11019, 25433, 6541, 0 }; + static ulong[] dim4457Kuo3Init = { 1, 3, 3, 9, 3, 35, 19, 127, 419, 203, 1869, 1477, 5239, 6113, 4835, 21131, 0 }; + static ulong[] dim4458Kuo3Init = { 1, 3, 3, 7, 17, 49, 17, 23, 111, 65, 1603, 157, 6433, 2965, 19845, 59041, 0 }; + static ulong[] dim4459Kuo3Init = { 1, 3, 1, 3, 17, 1, 17, 207, 245, 129, 1309, 413, 6933, 7575, 17179, 24075, 0 }; + static ulong[] dim4460Kuo3Init = { 1, 1, 5, 5, 29, 23, 65, 43, 157, 569, 645, 1821, 605, 3925, 2863, 55361, 0 }; + static ulong[] dim4461Kuo3Init = { 1, 3, 3, 5, 15, 43, 1, 149, 253, 529, 37, 2589, 2851, 2529, 32689, 49303, 0 }; + static ulong[] dim4462Kuo3Init = { 1, 3, 1, 15, 3, 29, 19, 241, 153, 189, 161, 797, 5419, 11269, 2159, 57893, 0 }; + static ulong[] dim4463Kuo3Init = { 1, 1, 3, 13, 19, 23, 49, 179, 459, 701, 1003, 2673, 1729, 1901, 26003, 51441, 0 }; + static ulong[] dim4464Kuo3Init = { 1, 1, 3, 9, 23, 19, 47, 85, 281, 371, 773, 2263, 3235, 647, 23085, 10053, 0 }; + static ulong[] dim4465Kuo3Init = { 1, 3, 3, 13, 13, 23, 13, 95, 41, 963, 213, 2317, 3889, 3981, 4749, 55409, 0 }; + static ulong[] dim4466Kuo3Init = { 1, 1, 7, 13, 9, 39, 33, 21, 17, 201, 1789, 2593, 1373, 14601, 17025, 31861, 0 }; + static ulong[] dim4467Kuo3Init = { 1, 1, 5, 9, 5, 43, 107, 169, 247, 361, 1245, 2371, 119, 4987, 32661, 19363, 0 }; + static ulong[] dim4468Kuo3Init = { 1, 3, 7, 5, 29, 35, 81, 13, 419, 1003, 701, 759, 4415, 11441, 28985, 46869, 0 }; + static ulong[] dim4469Kuo3Init = { 1, 3, 7, 7, 9, 57, 3, 39, 457, 455, 29, 2983, 4879, 14359, 12913, 64711, 0 }; + static ulong[] dim4470Kuo3Init = { 1, 1, 7, 3, 9, 31, 57, 47, 55, 525, 2015, 2053, 7101, 8487, 26865, 29149, 0 }; + static ulong[] dim4471Kuo3Init = { 1, 1, 7, 11, 11, 37, 67, 241, 509, 711, 263, 1565, 6803, 2095, 3055, 28847, 0 }; + static ulong[] dim4472Kuo3Init = { 1, 3, 1, 9, 25, 23, 53, 135, 391, 625, 673, 2807, 6511, 7465, 21959, 17561, 0 }; + static ulong[] dim4473Kuo3Init = { 1, 1, 7, 3, 23, 23, 47, 247, 297, 191, 1137, 3921, 3669, 4439, 707, 33529, 0 }; + static ulong[] dim4474Kuo3Init = { 1, 1, 7, 15, 19, 35, 91, 75, 237, 585, 1047, 1389, 7147, 9043, 22363, 14287, 0 }; + static ulong[] dim4475Kuo3Init = { 1, 3, 1, 15, 17, 35, 45, 181, 439, 307, 709, 2925, 3397, 4577, 30645, 25167, 0 }; + static ulong[] dim4476Kuo3Init = { 1, 1, 5, 9, 25, 1, 127, 173, 397, 477, 821, 2017, 1363, 8615, 8833, 12771, 0 }; + static ulong[] dim4477Kuo3Init = { 1, 1, 5, 9, 9, 1, 33, 137, 383, 465, 1211, 3563, 5035, 6609, 31667, 10853, 0 }; + static ulong[] dim4478Kuo3Init = { 1, 3, 7, 9, 11, 49, 61, 51, 31, 811, 623, 2213, 7131, 15679, 5335, 53001, 0 }; + static ulong[] dim4479Kuo3Init = { 1, 1, 5, 7, 27, 55, 11, 229, 331, 109, 109, 877, 6087, 10023, 22627, 64253, 0 }; + static ulong[] dim4480Kuo3Init = { 1, 1, 5, 3, 11, 13, 105, 31, 357, 589, 869, 1583, 3441, 15783, 25579, 25335, 0 }; + static ulong[] dim4481Kuo3Init = { 1, 3, 7, 7, 7, 9, 35, 29, 153, 425, 1145, 2021, 115, 15865, 4305, 62417, 0 }; + static ulong[] dim4482Kuo3Init = { 1, 3, 5, 3, 27, 17, 3, 57, 111, 393, 711, 2519, 7223, 10117, 5509, 63361, 0 }; + static ulong[] dim4483Kuo3Init = { 1, 1, 5, 7, 9, 55, 101, 199, 441, 141, 1349, 3017, 7625, 1457, 27947, 13269, 0 }; + static ulong[] dim4484Kuo3Init = { 1, 1, 5, 15, 5, 23, 3, 87, 61, 19, 1449, 2317, 4049, 3397, 6271, 53317, 0 }; + static ulong[] dim4485Kuo3Init = { 1, 3, 5, 3, 11, 35, 95, 141, 355, 749, 1247, 3495, 5719, 16201, 9649, 12395, 0 }; + static ulong[] dim4486Kuo3Init = { 1, 3, 7, 11, 23, 29, 79, 171, 259, 923, 2035, 783, 3571, 14987, 30025, 19185, 0 }; + static ulong[] dim4487Kuo3Init = { 1, 1, 7, 13, 17, 31, 75, 141, 131, 391, 303, 2641, 5527, 12629, 1097, 47589, 0 }; + static ulong[] dim4488Kuo3Init = { 1, 3, 3, 15, 9, 55, 23, 207, 211, 633, 805, 3079, 5495, 4651, 26483, 59323, 0 }; + static ulong[] dim4489Kuo3Init = { 1, 1, 1, 9, 9, 17, 97, 173, 123, 139, 595, 3859, 4615, 15565, 9243, 19933, 0 }; + static ulong[] dim4490Kuo3Init = { 1, 3, 5, 9, 31, 51, 1, 133, 213, 877, 23, 3661, 3451, 11705, 27943, 10995, 0 }; + static ulong[] dim4491Kuo3Init = { 1, 3, 3, 11, 5, 1, 91, 113, 147, 825, 795, 2871, 5175, 6843, 17829, 25375, 0 }; + static ulong[] dim4492Kuo3Init = { 1, 3, 3, 3, 7, 15, 105, 227, 97, 985, 347, 2833, 1237, 9419, 17853, 43467, 0 }; + static ulong[] dim4493Kuo3Init = { 1, 3, 7, 7, 17, 47, 3, 237, 97, 915, 1463, 477, 2237, 7755, 11779, 35897, 0 }; + static ulong[] dim4494Kuo3Init = { 1, 3, 1, 9, 17, 17, 97, 163, 181, 411, 1145, 623, 3017, 1335, 6999, 57149, 0 }; + static ulong[] dim4495Kuo3Init = { 1, 1, 1, 7, 27, 49, 57, 49, 217, 635, 973, 1153, 8097, 4669, 30691, 1949, 0 }; + static ulong[] dim4496Kuo3Init = { 1, 1, 1, 7, 13, 47, 107, 247, 269, 803, 1919, 3047, 2967, 63, 12287, 39925, 0 }; + static ulong[] dim4497Kuo3Init = { 1, 1, 5, 3, 27, 15, 27, 255, 27, 463, 621, 2443, 5615, 14589, 10869, 5013, 0 }; + static ulong[] dim4498Kuo3Init = { 1, 3, 5, 15, 25, 15, 75, 223, 17, 227, 911, 3069, 2583, 8811, 14191, 2819, 0 }; + static ulong[] dim4499Kuo3Init = { 1, 3, 5, 15, 25, 13, 19, 157, 495, 997, 1997, 3175, 1515, 15693, 15585, 2753, 0 }; + static ulong[] dim4500Kuo3Init = { 1, 1, 7, 7, 7, 5, 67, 95, 337, 539, 2019, 2009, 7171, 1089, 7955, 17557, 0 }; + static ulong[] dim4501Kuo3Init = { 1, 3, 3, 3, 7, 63, 61, 31, 61, 483, 365, 1153, 495, 7357, 2831, 23191, 0 }; + static ulong[] dim4502Kuo3Init = { 1, 1, 7, 1, 17, 35, 121, 143, 411, 895, 1859, 2205, 6565, 11611, 20941, 47151, 0 }; + static ulong[] dim4503Kuo3Init = { 1, 3, 7, 9, 27, 21, 53, 51, 77, 251, 1355, 175, 3949, 2903, 26991, 41571, 0 }; + static ulong[] dim4504Kuo3Init = { 1, 1, 1, 15, 17, 1, 15, 253, 99, 611, 1949, 1917, 4363, 2887, 30421, 42197, 0 }; + static ulong[] dim4505Kuo3Init = { 1, 3, 3, 11, 29, 45, 111, 49, 389, 171, 1069, 3061, 6657, 12097, 533, 9459, 0 }; + static ulong[] dim4506Kuo3Init = { 1, 1, 3, 1, 5, 27, 39, 15, 381, 119, 137, 3641, 8047, 1391, 13093, 50659, 0 }; + static ulong[] dim4507Kuo3Init = { 1, 1, 7, 9, 27, 59, 123, 235, 301, 933, 335, 3927, 2811, 16133, 5999, 19933, 0 }; + static ulong[] dim4508Kuo3Init = { 1, 3, 3, 13, 15, 55, 69, 199, 353, 131, 753, 2765, 4005, 13575, 16607, 51253, 0 }; + static ulong[] dim4509Kuo3Init = { 1, 1, 7, 1, 19, 53, 31, 233, 289, 939, 31, 1741, 5467, 1987, 13923, 49857, 0 }; + static ulong[] dim4510Kuo3Init = { 1, 1, 7, 7, 31, 45, 45, 237, 427, 305, 1753, 1237, 3573, 10813, 10609, 24187, 0 }; + static ulong[] dim4511Kuo3Init = { 1, 1, 1, 13, 21, 41, 81, 219, 185, 107, 71, 2017, 6587, 3351, 10207, 10545, 0 }; + static ulong[] dim4512Kuo3Init = { 1, 1, 1, 5, 5, 21, 127, 129, 209, 313, 1273, 3229, 6733, 4431, 7297, 41569, 0 }; + static ulong[] dim4513Kuo3Init = { 1, 1, 3, 15, 17, 61, 55, 127, 85, 913, 1173, 3837, 5579, 10309, 24659, 22697, 0 }; + static ulong[] dim4514Kuo3Init = { 1, 1, 3, 3, 11, 11, 91, 165, 367, 79, 43, 679, 3285, 15469, 21511, 57755, 0 }; + static ulong[] dim4515Kuo3Init = { 1, 1, 1, 13, 15, 1, 125, 47, 101, 999, 521, 543, 5535, 10191, 7497, 15677, 0 }; + static ulong[] dim4516Kuo3Init = { 1, 3, 3, 9, 9, 15, 63, 239, 471, 903, 1473, 717, 6547, 8445, 20737, 41457, 0 }; + static ulong[] dim4517Kuo3Init = { 1, 1, 5, 15, 13, 31, 43, 93, 325, 393, 373, 971, 6045, 14981, 28011, 35997, 0 }; + static ulong[] dim4518Kuo3Init = { 1, 3, 1, 15, 11, 45, 41, 35, 381, 779, 443, 3395, 2495, 14795, 4695, 22745, 0 }; + static ulong[] dim4519Kuo3Init = { 1, 3, 3, 7, 21, 9, 89, 173, 233, 935, 683, 1533, 953, 2627, 30975, 43449, 0 }; + static ulong[] dim4520Kuo3Init = { 1, 1, 5, 3, 25, 55, 107, 105, 99, 959, 1935, 3489, 3671, 14999, 11707, 10285, 0 }; + static ulong[] dim4521Kuo3Init = { 1, 3, 5, 3, 31, 17, 123, 119, 63, 169, 1283, 3691, 1411, 3437, 27941, 57089, 0 }; + static ulong[] dim4522Kuo3Init = { 1, 3, 3, 1, 17, 9, 115, 69, 481, 689, 2007, 3815, 4419, 11249, 31469, 55783, 0 }; + static ulong[] dim4523Kuo3Init = { 1, 3, 7, 15, 9, 39, 65, 125, 253, 413, 1283, 2073, 6563, 2111, 22865, 59393, 0 }; + static ulong[] dim4524Kuo3Init = { 1, 3, 3, 15, 19, 1, 67, 253, 489, 185, 297, 261, 5203, 8685, 10515, 58595, 0 }; + static ulong[] dim4525Kuo3Init = { 1, 1, 1, 13, 23, 39, 95, 233, 171, 653, 2025, 2285, 4477, 9275, 9717, 43321, 0 }; + static ulong[] dim4526Kuo3Init = { 1, 1, 7, 3, 23, 35, 77, 119, 193, 41, 1057, 4017, 235, 13819, 7911, 3981, 0 }; + static ulong[] dim4527Kuo3Init = { 1, 3, 5, 9, 15, 33, 41, 221, 1, 307, 1325, 2899, 399, 801, 24611, 31941, 0 }; + static ulong[] dim4528Kuo3Init = { 1, 1, 1, 15, 1, 7, 91, 27, 247, 667, 483, 573, 481, 11771, 31139, 31979, 0 }; + static ulong[] dim4529Kuo3Init = { 1, 3, 5, 1, 3, 23, 39, 73, 101, 367, 1259, 4053, 3055, 1231, 27981, 54287, 0 }; + static ulong[] dim4530Kuo3Init = { 1, 3, 3, 7, 3, 31, 9, 71, 339, 33, 1255, 1353, 5575, 12481, 27881, 17293, 0 }; + static ulong[] dim4531Kuo3Init = { 1, 3, 5, 13, 5, 57, 123, 193, 443, 185, 851, 539, 4217, 915, 1247, 20163, 0 }; + static ulong[] dim4532Kuo3Init = { 1, 3, 7, 5, 11, 13, 99, 141, 439, 259, 1177, 453, 6037, 5813, 25147, 20381, 0 }; + static ulong[] dim4533Kuo3Init = { 1, 1, 1, 5, 25, 17, 105, 91, 33, 15, 2035, 3693, 2249, 5825, 29037, 12529, 0 }; + static ulong[] dim4534Kuo3Init = { 1, 3, 1, 13, 1, 33, 113, 237, 13, 845, 1127, 4067, 825, 8391, 1269, 51473, 0 }; + static ulong[] dim4535Kuo3Init = { 1, 3, 5, 3, 27, 5, 77, 97, 33, 569, 1327, 751, 2817, 775, 32275, 55757, 0 }; + static ulong[] dim4536Kuo3Init = { 1, 1, 1, 7, 25, 1, 73, 105, 19, 1007, 371, 269, 4833, 13881, 21503, 35303, 0 }; + static ulong[] dim4537Kuo3Init = { 1, 3, 1, 3, 23, 39, 27, 203, 351, 433, 399, 405, 39, 7773, 27345, 57109, 0 }; + static ulong[] dim4538Kuo3Init = { 1, 1, 5, 13, 7, 7, 21, 33, 481, 201, 7, 2377, 1009, 7593, 19381, 10325, 0 }; + static ulong[] dim4539Kuo3Init = { 1, 1, 1, 13, 15, 61, 29, 59, 255, 213, 1207, 3783, 4375, 8137, 6733, 10809, 0 }; + static ulong[] dim4540Kuo3Init = { 1, 1, 1, 9, 25, 37, 83, 169, 267, 21, 1211, 3099, 239, 2489, 12843, 4395, 0 }; + static ulong[] dim4541Kuo3Init = { 1, 1, 1, 13, 17, 47, 77, 63, 361, 567, 245, 3569, 7707, 15463, 29579, 55017, 0 }; + static ulong[] dim4542Kuo3Init = { 1, 1, 7, 13, 23, 3, 111, 21, 417, 609, 547, 3297, 7487, 3285, 16913, 34005, 0 }; + static ulong[] dim4543Kuo3Init = { 1, 3, 7, 5, 9, 37, 39, 173, 129, 215, 1939, 2745, 319, 12707, 4665, 32065, 0 }; + static ulong[] dim4544Kuo3Init = { 1, 1, 3, 3, 21, 39, 67, 85, 223, 591, 681, 1655, 6651, 3547, 22459, 291, 0 }; + static ulong[] dim4545Kuo3Init = { 1, 1, 7, 11, 17, 9, 61, 121, 489, 129, 489, 1261, 2377, 9243, 15123, 59249, 0 }; + static ulong[] dim4546Kuo3Init = { 1, 1, 5, 9, 1, 31, 1, 171, 331, 233, 1033, 1975, 1515, 13295, 9383, 52107, 0 }; + static ulong[] dim4547Kuo3Init = { 1, 1, 1, 13, 17, 45, 75, 209, 187, 441, 1227, 4063, 5699, 3397, 25793, 58187, 0 }; + static ulong[] dim4548Kuo3Init = { 1, 3, 1, 3, 17, 13, 67, 73, 141, 451, 1307, 3115, 1273, 5275, 32383, 4663, 0 }; + static ulong[] dim4549Kuo3Init = { 1, 1, 5, 15, 5, 37, 77, 159, 339, 443, 1663, 345, 1513, 3195, 15131, 32473, 0 }; + static ulong[] dim4550Kuo3Init = { 1, 1, 3, 11, 29, 19, 13, 47, 409, 141, 1907, 3473, 4799, 213, 341, 45091, 0 }; + static ulong[] dim4551Kuo3Init = { 1, 3, 1, 1, 15, 29, 27, 179, 367, 439, 1073, 1783, 735, 11731, 20101, 7889, 0 }; + static ulong[] dim4552Kuo3Init = { 1, 1, 3, 15, 23, 35, 107, 53, 325, 51, 831, 1693, 5161, 13655, 31957, 60089, 0 }; + static ulong[] dim4553Kuo3Init = { 1, 1, 5, 11, 31, 13, 103, 109, 71, 237, 1271, 629, 6813, 10253, 17161, 58597, 0 }; + static ulong[] dim4554Kuo3Init = { 1, 3, 3, 1, 29, 37, 47, 173, 131, 787, 39, 879, 215, 13625, 4031, 56677, 0 }; + static ulong[] dim4555Kuo3Init = { 1, 1, 7, 5, 29, 3, 61, 227, 23, 699, 1291, 3909, 6995, 4085, 8961, 40275, 0 }; + static ulong[] dim4556Kuo3Init = { 1, 1, 5, 7, 27, 21, 25, 213, 359, 701, 1453, 3753, 5493, 5971, 30375, 54707, 0 }; + static ulong[] dim4557Kuo3Init = { 1, 3, 7, 7, 7, 63, 67, 47, 341, 451, 1205, 3125, 1575, 6229, 13951, 4539, 0 }; + static ulong[] dim4558Kuo3Init = { 1, 1, 3, 13, 25, 3, 93, 91, 507, 843, 623, 865, 5873, 10397, 4135, 11313, 0 }; + static ulong[] dim4559Kuo3Init = { 1, 3, 7, 15, 11, 39, 111, 149, 439, 519, 1015, 2777, 1643, 9703, 13767, 7351, 0 }; + static ulong[] dim4560Kuo3Init = { 1, 1, 5, 5, 27, 55, 79, 39, 23, 451, 1507, 2117, 6881, 4623, 26289, 23435, 0 }; + static ulong[] dim4561Kuo3Init = { 1, 3, 3, 11, 27, 29, 21, 63, 229, 173, 1777, 2163, 5185, 15487, 19661, 49185, 0 }; + static ulong[] dim4562Kuo3Init = { 1, 3, 1, 9, 3, 29, 59, 63, 477, 51, 1257, 2301, 3495, 9475, 32201, 47511, 0 }; + static ulong[] dim4563Kuo3Init = { 1, 1, 1, 7, 29, 45, 115, 235, 201, 847, 57, 1783, 2203, 13077, 4917, 6773, 0 }; + static ulong[] dim4564Kuo3Init = { 1, 1, 5, 9, 13, 49, 77, 1, 105, 747, 1389, 2461, 3823, 3315, 25295, 24761, 0 }; + static ulong[] dim4565Kuo3Init = { 1, 3, 7, 7, 19, 5, 83, 157, 37, 499, 1893, 2787, 6427, 8575, 26547, 28871, 0 }; + static ulong[] dim4566Kuo3Init = { 1, 1, 3, 9, 29, 47, 109, 151, 125, 1005, 751, 2059, 7045, 15483, 5227, 58193, 0 }; + static ulong[] dim4567Kuo3Init = { 1, 1, 3, 1, 11, 41, 63, 155, 175, 943, 161, 889, 6001, 3537, 23609, 23595, 0 }; + static ulong[] dim4568Kuo3Init = { 1, 3, 1, 11, 5, 51, 121, 11, 81, 175, 1953, 451, 4723, 11083, 26527, 41887, 0 }; + static ulong[] dim4569Kuo3Init = { 1, 1, 3, 7, 13, 59, 47, 205, 503, 249, 1263, 1767, 2553, 9755, 909, 27129, 0 }; + static ulong[] dim4570Kuo3Init = { 1, 1, 5, 13, 11, 19, 123, 1, 429, 455, 85, 1021, 7119, 8563, 11115, 24741, 0 }; + static ulong[] dim4571Kuo3Init = { 1, 1, 1, 1, 5, 55, 1, 1, 17, 221, 1633, 4065, 9, 4091, 29557, 33855, 0 }; + static ulong[] dim4572Kuo3Init = { 1, 3, 3, 11, 9, 3, 15, 159, 243, 245, 1845, 3841, 3321, 8631, 1131, 7327, 0 }; + static ulong[] dim4573Kuo3Init = { 1, 1, 5, 5, 3, 9, 119, 99, 337, 969, 1313, 4083, 2053, 10277, 15941, 16969, 0 }; + static ulong[] dim4574Kuo3Init = { 1, 1, 7, 13, 15, 35, 25, 239, 345, 785, 747, 233, 7175, 10319, 23783, 55803, 0 }; + static ulong[] dim4575Kuo3Init = { 1, 1, 7, 1, 7, 5, 91, 119, 317, 831, 351, 2149, 7531, 16373, 23461, 19863, 0 }; + static ulong[] dim4576Kuo3Init = { 1, 1, 7, 1, 29, 7, 5, 43, 7, 717, 1459, 713, 5453, 7471, 12909, 36941, 0 }; + static ulong[] dim4577Kuo3Init = { 1, 3, 5, 15, 9, 53, 59, 201, 333, 603, 629, 1819, 3397, 2823, 6459, 16213, 0 }; + static ulong[] dim4578Kuo3Init = { 1, 3, 1, 13, 27, 47, 67, 119, 145, 81, 507, 53, 7407, 6327, 11387, 45391, 0 }; + static ulong[] dim4579Kuo3Init = { 1, 1, 7, 13, 7, 63, 53, 171, 381, 523, 825, 2785, 7077, 13601, 329, 26677, 0 }; + static ulong[] dim4580Kuo3Init = { 1, 1, 5, 13, 7, 25, 91, 67, 267, 463, 1869, 2041, 5949, 1635, 21551, 37331, 0 }; + static ulong[] dim4581Kuo3Init = { 1, 1, 1, 5, 25, 1, 17, 113, 445, 685, 1201, 3299, 8139, 1463, 26067, 14613, 0 }; + static ulong[] dim4582Kuo3Init = { 1, 3, 1, 13, 3, 19, 103, 159, 337, 999, 755, 3935, 5161, 8681, 17375, 20163, 0 }; + static ulong[] dim4583Kuo3Init = { 1, 3, 5, 9, 1, 13, 117, 209, 93, 613, 271, 1321, 2265, 2739, 5055, 27581, 0 }; + static ulong[] dim4584Kuo3Init = { 1, 1, 1, 1, 7, 21, 111, 45, 361, 665, 1243, 1485, 7833, 15515, 26437, 55983, 0 }; + static ulong[] dim4585Kuo3Init = { 1, 1, 5, 7, 1, 31, 123, 199, 347, 235, 1367, 2451, 7211, 6095, 19245, 55993, 0 }; + static ulong[] dim4586Kuo3Init = { 1, 3, 7, 3, 25, 9, 25, 117, 315, 497, 1235, 1969, 7981, 9743, 20951, 30635, 0 }; + + static ulong[][] Kuo3initializers = + { + dim1Kuo3Init, + dim2Kuo3Init, + dim3Kuo3Init, + dim4Kuo3Init, + dim5Kuo3Init, + dim6Kuo3Init, + dim7Kuo3Init, + dim8Kuo3Init, + dim9Kuo3Init, + dim10Kuo3Init, + dim11Kuo3Init, + dim12Kuo3Init, + dim13Kuo3Init, + dim14Kuo3Init, + dim15Kuo3Init, + dim16Kuo3Init, + dim17Kuo3Init, + dim18Kuo3Init, + dim19Kuo3Init, + dim20Kuo3Init, + dim21Kuo3Init, + dim22Kuo3Init, + dim23Kuo3Init, + dim24Kuo3Init, + dim25Kuo3Init, + dim26Kuo3Init, + dim27Kuo3Init, + dim28Kuo3Init, + dim29Kuo3Init, + dim30Kuo3Init, + dim31Kuo3Init, + dim32Kuo3Init, + dim33Kuo3Init, + dim34Kuo3Init, + dim35Kuo3Init, + dim36Kuo3Init, + dim37Kuo3Init, + dim38Kuo3Init, + dim39Kuo3Init, + dim40Kuo3Init, + dim41Kuo3Init, + dim42Kuo3Init, + dim43Kuo3Init, + dim44Kuo3Init, + dim45Kuo3Init, + dim46Kuo3Init, + dim47Kuo3Init, + dim48Kuo3Init, + dim49Kuo3Init, + dim50Kuo3Init, + dim51Kuo3Init, + dim52Kuo3Init, + dim53Kuo3Init, + dim54Kuo3Init, + dim55Kuo3Init, + dim56Kuo3Init, + dim57Kuo3Init, + dim58Kuo3Init, + dim59Kuo3Init, + dim60Kuo3Init, + dim61Kuo3Init, + dim62Kuo3Init, + dim63Kuo3Init, + dim64Kuo3Init, + dim65Kuo3Init, + dim66Kuo3Init, + dim67Kuo3Init, + dim68Kuo3Init, + dim69Kuo3Init, + dim70Kuo3Init, + dim71Kuo3Init, + dim72Kuo3Init, + dim73Kuo3Init, + dim74Kuo3Init, + dim75Kuo3Init, + dim76Kuo3Init, + dim77Kuo3Init, + dim78Kuo3Init, + dim79Kuo3Init, + dim80Kuo3Init, + dim81Kuo3Init, + dim82Kuo3Init, + dim83Kuo3Init, + dim84Kuo3Init, + dim85Kuo3Init, + dim86Kuo3Init, + dim87Kuo3Init, + dim88Kuo3Init, + dim89Kuo3Init, + dim90Kuo3Init, + dim91Kuo3Init, + dim92Kuo3Init, + dim93Kuo3Init, + dim94Kuo3Init, + dim95Kuo3Init, + dim96Kuo3Init, + dim97Kuo3Init, + dim98Kuo3Init, + dim99Kuo3Init, + dim100Kuo3Init, + dim101Kuo3Init, + dim102Kuo3Init, + dim103Kuo3Init, + dim104Kuo3Init, + dim105Kuo3Init, + dim106Kuo3Init, + dim107Kuo3Init, + dim108Kuo3Init, + dim109Kuo3Init, + dim110Kuo3Init, + dim111Kuo3Init, + dim112Kuo3Init, + dim113Kuo3Init, + dim114Kuo3Init, + dim115Kuo3Init, + dim116Kuo3Init, + dim117Kuo3Init, + dim118Kuo3Init, + dim119Kuo3Init, + dim120Kuo3Init, + dim121Kuo3Init, + dim122Kuo3Init, + dim123Kuo3Init, + dim124Kuo3Init, + dim125Kuo3Init, + dim126Kuo3Init, + dim127Kuo3Init, + dim128Kuo3Init, + dim129Kuo3Init, + dim130Kuo3Init, + dim131Kuo3Init, + dim132Kuo3Init, + dim133Kuo3Init, + dim134Kuo3Init, + dim135Kuo3Init, + dim136Kuo3Init, + dim137Kuo3Init, + dim138Kuo3Init, + dim139Kuo3Init, + dim140Kuo3Init, + dim141Kuo3Init, + dim142Kuo3Init, + dim143Kuo3Init, + dim144Kuo3Init, + dim145Kuo3Init, + dim146Kuo3Init, + dim147Kuo3Init, + dim148Kuo3Init, + dim149Kuo3Init, + dim150Kuo3Init, + dim151Kuo3Init, + dim152Kuo3Init, + dim153Kuo3Init, + dim154Kuo3Init, + dim155Kuo3Init, + dim156Kuo3Init, + dim157Kuo3Init, + dim158Kuo3Init, + dim159Kuo3Init, + dim160Kuo3Init, + dim161Kuo3Init, + dim162Kuo3Init, + dim163Kuo3Init, + dim164Kuo3Init, + dim165Kuo3Init, + dim166Kuo3Init, + dim167Kuo3Init, + dim168Kuo3Init, + dim169Kuo3Init, + dim170Kuo3Init, + dim171Kuo3Init, + dim172Kuo3Init, + dim173Kuo3Init, + dim174Kuo3Init, + dim175Kuo3Init, + dim176Kuo3Init, + dim177Kuo3Init, + dim178Kuo3Init, + dim179Kuo3Init, + dim180Kuo3Init, + dim181Kuo3Init, + dim182Kuo3Init, + dim183Kuo3Init, + dim184Kuo3Init, + dim185Kuo3Init, + dim186Kuo3Init, + dim187Kuo3Init, + dim188Kuo3Init, + dim189Kuo3Init, + dim190Kuo3Init, + dim191Kuo3Init, + dim192Kuo3Init, + dim193Kuo3Init, + dim194Kuo3Init, + dim195Kuo3Init, + dim196Kuo3Init, + dim197Kuo3Init, + dim198Kuo3Init, + dim199Kuo3Init, + dim200Kuo3Init, + dim201Kuo3Init, + dim202Kuo3Init, + dim203Kuo3Init, + dim204Kuo3Init, + dim205Kuo3Init, + dim206Kuo3Init, + dim207Kuo3Init, + dim208Kuo3Init, + dim209Kuo3Init, + dim210Kuo3Init, + dim211Kuo3Init, + dim212Kuo3Init, + dim213Kuo3Init, + dim214Kuo3Init, + dim215Kuo3Init, + dim216Kuo3Init, + dim217Kuo3Init, + dim218Kuo3Init, + dim219Kuo3Init, + dim220Kuo3Init, + dim221Kuo3Init, + dim222Kuo3Init, + dim223Kuo3Init, + dim224Kuo3Init, + dim225Kuo3Init, + dim226Kuo3Init, + dim227Kuo3Init, + dim228Kuo3Init, + dim229Kuo3Init, + dim230Kuo3Init, + dim231Kuo3Init, + dim232Kuo3Init, + dim233Kuo3Init, + dim234Kuo3Init, + dim235Kuo3Init, + dim236Kuo3Init, + dim237Kuo3Init, + dim238Kuo3Init, + dim239Kuo3Init, + dim240Kuo3Init, + dim241Kuo3Init, + dim242Kuo3Init, + dim243Kuo3Init, + dim244Kuo3Init, + dim245Kuo3Init, + dim246Kuo3Init, + dim247Kuo3Init, + dim248Kuo3Init, + dim249Kuo3Init, + dim250Kuo3Init, + dim251Kuo3Init, + dim252Kuo3Init, + dim253Kuo3Init, + dim254Kuo3Init, + dim255Kuo3Init, + dim256Kuo3Init, + dim257Kuo3Init, + dim258Kuo3Init, + dim259Kuo3Init, + dim260Kuo3Init, + dim261Kuo3Init, + dim262Kuo3Init, + dim263Kuo3Init, + dim264Kuo3Init, + dim265Kuo3Init, + dim266Kuo3Init, + dim267Kuo3Init, + dim268Kuo3Init, + dim269Kuo3Init, + dim270Kuo3Init, + dim271Kuo3Init, + dim272Kuo3Init, + dim273Kuo3Init, + dim274Kuo3Init, + dim275Kuo3Init, + dim276Kuo3Init, + dim277Kuo3Init, + dim278Kuo3Init, + dim279Kuo3Init, + dim280Kuo3Init, + dim281Kuo3Init, + dim282Kuo3Init, + dim283Kuo3Init, + dim284Kuo3Init, + dim285Kuo3Init, + dim286Kuo3Init, + dim287Kuo3Init, + dim288Kuo3Init, + dim289Kuo3Init, + dim290Kuo3Init, + dim291Kuo3Init, + dim292Kuo3Init, + dim293Kuo3Init, + dim294Kuo3Init, + dim295Kuo3Init, + dim296Kuo3Init, + dim297Kuo3Init, + dim298Kuo3Init, + dim299Kuo3Init, + dim300Kuo3Init, + dim301Kuo3Init, + dim302Kuo3Init, + dim303Kuo3Init, + dim304Kuo3Init, + dim305Kuo3Init, + dim306Kuo3Init, + dim307Kuo3Init, + dim308Kuo3Init, + dim309Kuo3Init, + dim310Kuo3Init, + dim311Kuo3Init, + dim312Kuo3Init, + dim313Kuo3Init, + dim314Kuo3Init, + dim315Kuo3Init, + dim316Kuo3Init, + dim317Kuo3Init, + dim318Kuo3Init, + dim319Kuo3Init, + dim320Kuo3Init, + dim321Kuo3Init, + dim322Kuo3Init, + dim323Kuo3Init, + dim324Kuo3Init, + dim325Kuo3Init, + dim326Kuo3Init, + dim327Kuo3Init, + dim328Kuo3Init, + dim329Kuo3Init, + dim330Kuo3Init, + dim331Kuo3Init, + dim332Kuo3Init, + dim333Kuo3Init, + dim334Kuo3Init, + dim335Kuo3Init, + dim336Kuo3Init, + dim337Kuo3Init, + dim338Kuo3Init, + dim339Kuo3Init, + dim340Kuo3Init, + dim341Kuo3Init, + dim342Kuo3Init, + dim343Kuo3Init, + dim344Kuo3Init, + dim345Kuo3Init, + dim346Kuo3Init, + dim347Kuo3Init, + dim348Kuo3Init, + dim349Kuo3Init, + dim350Kuo3Init, + dim351Kuo3Init, + dim352Kuo3Init, + dim353Kuo3Init, + dim354Kuo3Init, + dim355Kuo3Init, + dim356Kuo3Init, + dim357Kuo3Init, + dim358Kuo3Init, + dim359Kuo3Init, + dim360Kuo3Init, + dim361Kuo3Init, + dim362Kuo3Init, + dim363Kuo3Init, + dim364Kuo3Init, + dim365Kuo3Init, + dim366Kuo3Init, + dim367Kuo3Init, + dim368Kuo3Init, + dim369Kuo3Init, + dim370Kuo3Init, + dim371Kuo3Init, + dim372Kuo3Init, + dim373Kuo3Init, + dim374Kuo3Init, + dim375Kuo3Init, + dim376Kuo3Init, + dim377Kuo3Init, + dim378Kuo3Init, + dim379Kuo3Init, + dim380Kuo3Init, + dim381Kuo3Init, + dim382Kuo3Init, + dim383Kuo3Init, + dim384Kuo3Init, + dim385Kuo3Init, + dim386Kuo3Init, + dim387Kuo3Init, + dim388Kuo3Init, + dim389Kuo3Init, + dim390Kuo3Init, + dim391Kuo3Init, + dim392Kuo3Init, + dim393Kuo3Init, + dim394Kuo3Init, + dim395Kuo3Init, + dim396Kuo3Init, + dim397Kuo3Init, + dim398Kuo3Init, + dim399Kuo3Init, + dim400Kuo3Init, + dim401Kuo3Init, + dim402Kuo3Init, + dim403Kuo3Init, + dim404Kuo3Init, + dim405Kuo3Init, + dim406Kuo3Init, + dim407Kuo3Init, + dim408Kuo3Init, + dim409Kuo3Init, + dim410Kuo3Init, + dim411Kuo3Init, + dim412Kuo3Init, + dim413Kuo3Init, + dim414Kuo3Init, + dim415Kuo3Init, + dim416Kuo3Init, + dim417Kuo3Init, + dim418Kuo3Init, + dim419Kuo3Init, + dim420Kuo3Init, + dim421Kuo3Init, + dim422Kuo3Init, + dim423Kuo3Init, + dim424Kuo3Init, + dim425Kuo3Init, + dim426Kuo3Init, + dim427Kuo3Init, + dim428Kuo3Init, + dim429Kuo3Init, + dim430Kuo3Init, + dim431Kuo3Init, + dim432Kuo3Init, + dim433Kuo3Init, + dim434Kuo3Init, + dim435Kuo3Init, + dim436Kuo3Init, + dim437Kuo3Init, + dim438Kuo3Init, + dim439Kuo3Init, + dim440Kuo3Init, + dim441Kuo3Init, + dim442Kuo3Init, + dim443Kuo3Init, + dim444Kuo3Init, + dim445Kuo3Init, + dim446Kuo3Init, + dim447Kuo3Init, + dim448Kuo3Init, + dim449Kuo3Init, + dim450Kuo3Init, + dim451Kuo3Init, + dim452Kuo3Init, + dim453Kuo3Init, + dim454Kuo3Init, + dim455Kuo3Init, + dim456Kuo3Init, + dim457Kuo3Init, + dim458Kuo3Init, + dim459Kuo3Init, + dim460Kuo3Init, + dim461Kuo3Init, + dim462Kuo3Init, + dim463Kuo3Init, + dim464Kuo3Init, + dim465Kuo3Init, + dim466Kuo3Init, + dim467Kuo3Init, + dim468Kuo3Init, + dim469Kuo3Init, + dim470Kuo3Init, + dim471Kuo3Init, + dim472Kuo3Init, + dim473Kuo3Init, + dim474Kuo3Init, + dim475Kuo3Init, + dim476Kuo3Init, + dim477Kuo3Init, + dim478Kuo3Init, + dim479Kuo3Init, + dim480Kuo3Init, + dim481Kuo3Init, + dim482Kuo3Init, + dim483Kuo3Init, + dim484Kuo3Init, + dim485Kuo3Init, + dim486Kuo3Init, + dim487Kuo3Init, + dim488Kuo3Init, + dim489Kuo3Init, + dim490Kuo3Init, + dim491Kuo3Init, + dim492Kuo3Init, + dim493Kuo3Init, + dim494Kuo3Init, + dim495Kuo3Init, + dim496Kuo3Init, + dim497Kuo3Init, + dim498Kuo3Init, + dim499Kuo3Init, + dim500Kuo3Init, + dim501Kuo3Init, + dim502Kuo3Init, + dim503Kuo3Init, + dim504Kuo3Init, + dim505Kuo3Init, + dim506Kuo3Init, + dim507Kuo3Init, + dim508Kuo3Init, + dim509Kuo3Init, + dim510Kuo3Init, + dim511Kuo3Init, + dim512Kuo3Init, + dim513Kuo3Init, + dim514Kuo3Init, + dim515Kuo3Init, + dim516Kuo3Init, + dim517Kuo3Init, + dim518Kuo3Init, + dim519Kuo3Init, + dim520Kuo3Init, + dim521Kuo3Init, + dim522Kuo3Init, + dim523Kuo3Init, + dim524Kuo3Init, + dim525Kuo3Init, + dim526Kuo3Init, + dim527Kuo3Init, + dim528Kuo3Init, + dim529Kuo3Init, + dim530Kuo3Init, + dim531Kuo3Init, + dim532Kuo3Init, + dim533Kuo3Init, + dim534Kuo3Init, + dim535Kuo3Init, + dim536Kuo3Init, + dim537Kuo3Init, + dim538Kuo3Init, + dim539Kuo3Init, + dim540Kuo3Init, + dim541Kuo3Init, + dim542Kuo3Init, + dim543Kuo3Init, + dim544Kuo3Init, + dim545Kuo3Init, + dim546Kuo3Init, + dim547Kuo3Init, + dim548Kuo3Init, + dim549Kuo3Init, + dim550Kuo3Init, + dim551Kuo3Init, + dim552Kuo3Init, + dim553Kuo3Init, + dim554Kuo3Init, + dim555Kuo3Init, + dim556Kuo3Init, + dim557Kuo3Init, + dim558Kuo3Init, + dim559Kuo3Init, + dim560Kuo3Init, + dim561Kuo3Init, + dim562Kuo3Init, + dim563Kuo3Init, + dim564Kuo3Init, + dim565Kuo3Init, + dim566Kuo3Init, + dim567Kuo3Init, + dim568Kuo3Init, + dim569Kuo3Init, + dim570Kuo3Init, + dim571Kuo3Init, + dim572Kuo3Init, + dim573Kuo3Init, + dim574Kuo3Init, + dim575Kuo3Init, + dim576Kuo3Init, + dim577Kuo3Init, + dim578Kuo3Init, + dim579Kuo3Init, + dim580Kuo3Init, + dim581Kuo3Init, + dim582Kuo3Init, + dim583Kuo3Init, + dim584Kuo3Init, + dim585Kuo3Init, + dim586Kuo3Init, + dim587Kuo3Init, + dim588Kuo3Init, + dim589Kuo3Init, + dim590Kuo3Init, + dim591Kuo3Init, + dim592Kuo3Init, + dim593Kuo3Init, + dim594Kuo3Init, + dim595Kuo3Init, + dim596Kuo3Init, + dim597Kuo3Init, + dim598Kuo3Init, + dim599Kuo3Init, + dim600Kuo3Init, + dim601Kuo3Init, + dim602Kuo3Init, + dim603Kuo3Init, + dim604Kuo3Init, + dim605Kuo3Init, + dim606Kuo3Init, + dim607Kuo3Init, + dim608Kuo3Init, + dim609Kuo3Init, + dim610Kuo3Init, + dim611Kuo3Init, + dim612Kuo3Init, + dim613Kuo3Init, + dim614Kuo3Init, + dim615Kuo3Init, + dim616Kuo3Init, + dim617Kuo3Init, + dim618Kuo3Init, + dim619Kuo3Init, + dim620Kuo3Init, + dim621Kuo3Init, + dim622Kuo3Init, + dim623Kuo3Init, + dim624Kuo3Init, + dim625Kuo3Init, + dim626Kuo3Init, + dim627Kuo3Init, + dim628Kuo3Init, + dim629Kuo3Init, + dim630Kuo3Init, + dim631Kuo3Init, + dim632Kuo3Init, + dim633Kuo3Init, + dim634Kuo3Init, + dim635Kuo3Init, + dim636Kuo3Init, + dim637Kuo3Init, + dim638Kuo3Init, + dim639Kuo3Init, + dim640Kuo3Init, + dim641Kuo3Init, + dim642Kuo3Init, + dim643Kuo3Init, + dim644Kuo3Init, + dim645Kuo3Init, + dim646Kuo3Init, + dim647Kuo3Init, + dim648Kuo3Init, + dim649Kuo3Init, + dim650Kuo3Init, + dim651Kuo3Init, + dim652Kuo3Init, + dim653Kuo3Init, + dim654Kuo3Init, + dim655Kuo3Init, + dim656Kuo3Init, + dim657Kuo3Init, + dim658Kuo3Init, + dim659Kuo3Init, + dim660Kuo3Init, + dim661Kuo3Init, + dim662Kuo3Init, + dim663Kuo3Init, + dim664Kuo3Init, + dim665Kuo3Init, + dim666Kuo3Init, + dim667Kuo3Init, + dim668Kuo3Init, + dim669Kuo3Init, + dim670Kuo3Init, + dim671Kuo3Init, + dim672Kuo3Init, + dim673Kuo3Init, + dim674Kuo3Init, + dim675Kuo3Init, + dim676Kuo3Init, + dim677Kuo3Init, + dim678Kuo3Init, + dim679Kuo3Init, + dim680Kuo3Init, + dim681Kuo3Init, + dim682Kuo3Init, + dim683Kuo3Init, + dim684Kuo3Init, + dim685Kuo3Init, + dim686Kuo3Init, + dim687Kuo3Init, + dim688Kuo3Init, + dim689Kuo3Init, + dim690Kuo3Init, + dim691Kuo3Init, + dim692Kuo3Init, + dim693Kuo3Init, + dim694Kuo3Init, + dim695Kuo3Init, + dim696Kuo3Init, + dim697Kuo3Init, + dim698Kuo3Init, + dim699Kuo3Init, + dim700Kuo3Init, + dim701Kuo3Init, + dim702Kuo3Init, + dim703Kuo3Init, + dim704Kuo3Init, + dim705Kuo3Init, + dim706Kuo3Init, + dim707Kuo3Init, + dim708Kuo3Init, + dim709Kuo3Init, + dim710Kuo3Init, + dim711Kuo3Init, + dim712Kuo3Init, + dim713Kuo3Init, + dim714Kuo3Init, + dim715Kuo3Init, + dim716Kuo3Init, + dim717Kuo3Init, + dim718Kuo3Init, + dim719Kuo3Init, + dim720Kuo3Init, + dim721Kuo3Init, + dim722Kuo3Init, + dim723Kuo3Init, + dim724Kuo3Init, + dim725Kuo3Init, + dim726Kuo3Init, + dim727Kuo3Init, + dim728Kuo3Init, + dim729Kuo3Init, + dim730Kuo3Init, + dim731Kuo3Init, + dim732Kuo3Init, + dim733Kuo3Init, + dim734Kuo3Init, + dim735Kuo3Init, + dim736Kuo3Init, + dim737Kuo3Init, + dim738Kuo3Init, + dim739Kuo3Init, + dim740Kuo3Init, + dim741Kuo3Init, + dim742Kuo3Init, + dim743Kuo3Init, + dim744Kuo3Init, + dim745Kuo3Init, + dim746Kuo3Init, + dim747Kuo3Init, + dim748Kuo3Init, + dim749Kuo3Init, + dim750Kuo3Init, + dim751Kuo3Init, + dim752Kuo3Init, + dim753Kuo3Init, + dim754Kuo3Init, + dim755Kuo3Init, + dim756Kuo3Init, + dim757Kuo3Init, + dim758Kuo3Init, + dim759Kuo3Init, + dim760Kuo3Init, + dim761Kuo3Init, + dim762Kuo3Init, + dim763Kuo3Init, + dim764Kuo3Init, + dim765Kuo3Init, + dim766Kuo3Init, + dim767Kuo3Init, + dim768Kuo3Init, + dim769Kuo3Init, + dim770Kuo3Init, + dim771Kuo3Init, + dim772Kuo3Init, + dim773Kuo3Init, + dim774Kuo3Init, + dim775Kuo3Init, + dim776Kuo3Init, + dim777Kuo3Init, + dim778Kuo3Init, + dim779Kuo3Init, + dim780Kuo3Init, + dim781Kuo3Init, + dim782Kuo3Init, + dim783Kuo3Init, + dim784Kuo3Init, + dim785Kuo3Init, + dim786Kuo3Init, + dim787Kuo3Init, + dim788Kuo3Init, + dim789Kuo3Init, + dim790Kuo3Init, + dim791Kuo3Init, + dim792Kuo3Init, + dim793Kuo3Init, + dim794Kuo3Init, + dim795Kuo3Init, + dim796Kuo3Init, + dim797Kuo3Init, + dim798Kuo3Init, + dim799Kuo3Init, + dim800Kuo3Init, + dim801Kuo3Init, + dim802Kuo3Init, + dim803Kuo3Init, + dim804Kuo3Init, + dim805Kuo3Init, + dim806Kuo3Init, + dim807Kuo3Init, + dim808Kuo3Init, + dim809Kuo3Init, + dim810Kuo3Init, + dim811Kuo3Init, + dim812Kuo3Init, + dim813Kuo3Init, + dim814Kuo3Init, + dim815Kuo3Init, + dim816Kuo3Init, + dim817Kuo3Init, + dim818Kuo3Init, + dim819Kuo3Init, + dim820Kuo3Init, + dim821Kuo3Init, + dim822Kuo3Init, + dim823Kuo3Init, + dim824Kuo3Init, + dim825Kuo3Init, + dim826Kuo3Init, + dim827Kuo3Init, + dim828Kuo3Init, + dim829Kuo3Init, + dim830Kuo3Init, + dim831Kuo3Init, + dim832Kuo3Init, + dim833Kuo3Init, + dim834Kuo3Init, + dim835Kuo3Init, + dim836Kuo3Init, + dim837Kuo3Init, + dim838Kuo3Init, + dim839Kuo3Init, + dim840Kuo3Init, + dim841Kuo3Init, + dim842Kuo3Init, + dim843Kuo3Init, + dim844Kuo3Init, + dim845Kuo3Init, + dim846Kuo3Init, + dim847Kuo3Init, + dim848Kuo3Init, + dim849Kuo3Init, + dim850Kuo3Init, + dim851Kuo3Init, + dim852Kuo3Init, + dim853Kuo3Init, + dim854Kuo3Init, + dim855Kuo3Init, + dim856Kuo3Init, + dim857Kuo3Init, + dim858Kuo3Init, + dim859Kuo3Init, + dim860Kuo3Init, + dim861Kuo3Init, + dim862Kuo3Init, + dim863Kuo3Init, + dim864Kuo3Init, + dim865Kuo3Init, + dim866Kuo3Init, + dim867Kuo3Init, + dim868Kuo3Init, + dim869Kuo3Init, + dim870Kuo3Init, + dim871Kuo3Init, + dim872Kuo3Init, + dim873Kuo3Init, + dim874Kuo3Init, + dim875Kuo3Init, + dim876Kuo3Init, + dim877Kuo3Init, + dim878Kuo3Init, + dim879Kuo3Init, + dim880Kuo3Init, + dim881Kuo3Init, + dim882Kuo3Init, + dim883Kuo3Init, + dim884Kuo3Init, + dim885Kuo3Init, + dim886Kuo3Init, + dim887Kuo3Init, + dim888Kuo3Init, + dim889Kuo3Init, + dim890Kuo3Init, + dim891Kuo3Init, + dim892Kuo3Init, + dim893Kuo3Init, + dim894Kuo3Init, + dim895Kuo3Init, + dim896Kuo3Init, + dim897Kuo3Init, + dim898Kuo3Init, + dim899Kuo3Init, + dim900Kuo3Init, + dim901Kuo3Init, + dim902Kuo3Init, + dim903Kuo3Init, + dim904Kuo3Init, + dim905Kuo3Init, + dim906Kuo3Init, + dim907Kuo3Init, + dim908Kuo3Init, + dim909Kuo3Init, + dim910Kuo3Init, + dim911Kuo3Init, + dim912Kuo3Init, + dim913Kuo3Init, + dim914Kuo3Init, + dim915Kuo3Init, + dim916Kuo3Init, + dim917Kuo3Init, + dim918Kuo3Init, + dim919Kuo3Init, + dim920Kuo3Init, + dim921Kuo3Init, + dim922Kuo3Init, + dim923Kuo3Init, + dim924Kuo3Init, + dim925Kuo3Init, + dim926Kuo3Init, + dim927Kuo3Init, + dim928Kuo3Init, + dim929Kuo3Init, + dim930Kuo3Init, + dim931Kuo3Init, + dim932Kuo3Init, + dim933Kuo3Init, + dim934Kuo3Init, + dim935Kuo3Init, + dim936Kuo3Init, + dim937Kuo3Init, + dim938Kuo3Init, + dim939Kuo3Init, + dim940Kuo3Init, + dim941Kuo3Init, + dim942Kuo3Init, + dim943Kuo3Init, + dim944Kuo3Init, + dim945Kuo3Init, + dim946Kuo3Init, + dim947Kuo3Init, + dim948Kuo3Init, + dim949Kuo3Init, + dim950Kuo3Init, + dim951Kuo3Init, + dim952Kuo3Init, + dim953Kuo3Init, + dim954Kuo3Init, + dim955Kuo3Init, + dim956Kuo3Init, + dim957Kuo3Init, + dim958Kuo3Init, + dim959Kuo3Init, + dim960Kuo3Init, + dim961Kuo3Init, + dim962Kuo3Init, + dim963Kuo3Init, + dim964Kuo3Init, + dim965Kuo3Init, + dim966Kuo3Init, + dim967Kuo3Init, + dim968Kuo3Init, + dim969Kuo3Init, + dim970Kuo3Init, + dim971Kuo3Init, + dim972Kuo3Init, + dim973Kuo3Init, + dim974Kuo3Init, + dim975Kuo3Init, + dim976Kuo3Init, + dim977Kuo3Init, + dim978Kuo3Init, + dim979Kuo3Init, + dim980Kuo3Init, + dim981Kuo3Init, + dim982Kuo3Init, + dim983Kuo3Init, + dim984Kuo3Init, + dim985Kuo3Init, + dim986Kuo3Init, + dim987Kuo3Init, + dim988Kuo3Init, + dim989Kuo3Init, + dim990Kuo3Init, + dim991Kuo3Init, + dim992Kuo3Init, + dim993Kuo3Init, + dim994Kuo3Init, + dim995Kuo3Init, + dim996Kuo3Init, + dim997Kuo3Init, + dim998Kuo3Init, + dim999Kuo3Init, + dim1000Kuo3Init, + dim1001Kuo3Init, + dim1002Kuo3Init, + dim1003Kuo3Init, + dim1004Kuo3Init, + dim1005Kuo3Init, + dim1006Kuo3Init, + dim1007Kuo3Init, + dim1008Kuo3Init, + dim1009Kuo3Init, + dim1010Kuo3Init, + dim1011Kuo3Init, + dim1012Kuo3Init, + dim1013Kuo3Init, + dim1014Kuo3Init, + dim1015Kuo3Init, + dim1016Kuo3Init, + dim1017Kuo3Init, + dim1018Kuo3Init, + dim1019Kuo3Init, + dim1020Kuo3Init, + dim1021Kuo3Init, + dim1022Kuo3Init, + dim1023Kuo3Init, + dim1024Kuo3Init, + dim1025Kuo3Init, + dim1026Kuo3Init, + dim1027Kuo3Init, + dim1028Kuo3Init, + dim1029Kuo3Init, + dim1030Kuo3Init, + dim1031Kuo3Init, + dim1032Kuo3Init, + dim1033Kuo3Init, + dim1034Kuo3Init, + dim1035Kuo3Init, + dim1036Kuo3Init, + dim1037Kuo3Init, + dim1038Kuo3Init, + dim1039Kuo3Init, + dim1040Kuo3Init, + dim1041Kuo3Init, + dim1042Kuo3Init, + dim1043Kuo3Init, + dim1044Kuo3Init, + dim1045Kuo3Init, + dim1046Kuo3Init, + dim1047Kuo3Init, + dim1048Kuo3Init, + dim1049Kuo3Init, + dim1050Kuo3Init, + dim1051Kuo3Init, + dim1052Kuo3Init, + dim1053Kuo3Init, + dim1054Kuo3Init, + dim1055Kuo3Init, + dim1056Kuo3Init, + dim1057Kuo3Init, + dim1058Kuo3Init, + dim1059Kuo3Init, + dim1060Kuo3Init, + dim1061Kuo3Init, + dim1062Kuo3Init, + dim1063Kuo3Init, + dim1064Kuo3Init, + dim1065Kuo3Init, + dim1066Kuo3Init, + dim1067Kuo3Init, + dim1068Kuo3Init, + dim1069Kuo3Init, + dim1070Kuo3Init, + dim1071Kuo3Init, + dim1072Kuo3Init, + dim1073Kuo3Init, + dim1074Kuo3Init, + dim1075Kuo3Init, + dim1076Kuo3Init, + dim1077Kuo3Init, + dim1078Kuo3Init, + dim1079Kuo3Init, + dim1080Kuo3Init, + dim1081Kuo3Init, + dim1082Kuo3Init, + dim1083Kuo3Init, + dim1084Kuo3Init, + dim1085Kuo3Init, + dim1086Kuo3Init, + dim1087Kuo3Init, + dim1088Kuo3Init, + dim1089Kuo3Init, + dim1090Kuo3Init, + dim1091Kuo3Init, + dim1092Kuo3Init, + dim1093Kuo3Init, + dim1094Kuo3Init, + dim1095Kuo3Init, + dim1096Kuo3Init, + dim1097Kuo3Init, + dim1098Kuo3Init, + dim1099Kuo3Init, + dim1100Kuo3Init, + dim1101Kuo3Init, + dim1102Kuo3Init, + dim1103Kuo3Init, + dim1104Kuo3Init, + dim1105Kuo3Init, + dim1106Kuo3Init, + dim1107Kuo3Init, + dim1108Kuo3Init, + dim1109Kuo3Init, + dim1110Kuo3Init, + dim1111Kuo3Init, + dim1112Kuo3Init, + dim1113Kuo3Init, + dim1114Kuo3Init, + dim1115Kuo3Init, + dim1116Kuo3Init, + dim1117Kuo3Init, + dim1118Kuo3Init, + dim1119Kuo3Init, + dim1120Kuo3Init, + dim1121Kuo3Init, + dim1122Kuo3Init, + dim1123Kuo3Init, + dim1124Kuo3Init, + dim1125Kuo3Init, + dim1126Kuo3Init, + dim1127Kuo3Init, + dim1128Kuo3Init, + dim1129Kuo3Init, + dim1130Kuo3Init, + dim1131Kuo3Init, + dim1132Kuo3Init, + dim1133Kuo3Init, + dim1134Kuo3Init, + dim1135Kuo3Init, + dim1136Kuo3Init, + dim1137Kuo3Init, + dim1138Kuo3Init, + dim1139Kuo3Init, + dim1140Kuo3Init, + dim1141Kuo3Init, + dim1142Kuo3Init, + dim1143Kuo3Init, + dim1144Kuo3Init, + dim1145Kuo3Init, + dim1146Kuo3Init, + dim1147Kuo3Init, + dim1148Kuo3Init, + dim1149Kuo3Init, + dim1150Kuo3Init, + dim1151Kuo3Init, + dim1152Kuo3Init, + dim1153Kuo3Init, + dim1154Kuo3Init, + dim1155Kuo3Init, + dim1156Kuo3Init, + dim1157Kuo3Init, + dim1158Kuo3Init, + dim1159Kuo3Init, + dim1160Kuo3Init, + dim1161Kuo3Init, + dim1162Kuo3Init, + dim1163Kuo3Init, + dim1164Kuo3Init, + dim1165Kuo3Init, + dim1166Kuo3Init, + dim1167Kuo3Init, + dim1168Kuo3Init, + dim1169Kuo3Init, + dim1170Kuo3Init, + dim1171Kuo3Init, + dim1172Kuo3Init, + dim1173Kuo3Init, + dim1174Kuo3Init, + dim1175Kuo3Init, + dim1176Kuo3Init, + dim1177Kuo3Init, + dim1178Kuo3Init, + dim1179Kuo3Init, + dim1180Kuo3Init, + dim1181Kuo3Init, + dim1182Kuo3Init, + dim1183Kuo3Init, + dim1184Kuo3Init, + dim1185Kuo3Init, + dim1186Kuo3Init, + dim1187Kuo3Init, + dim1188Kuo3Init, + dim1189Kuo3Init, + dim1190Kuo3Init, + dim1191Kuo3Init, + dim1192Kuo3Init, + dim1193Kuo3Init, + dim1194Kuo3Init, + dim1195Kuo3Init, + dim1196Kuo3Init, + dim1197Kuo3Init, + dim1198Kuo3Init, + dim1199Kuo3Init, + dim1200Kuo3Init, + dim1201Kuo3Init, + dim1202Kuo3Init, + dim1203Kuo3Init, + dim1204Kuo3Init, + dim1205Kuo3Init, + dim1206Kuo3Init, + dim1207Kuo3Init, + dim1208Kuo3Init, + dim1209Kuo3Init, + dim1210Kuo3Init, + dim1211Kuo3Init, + dim1212Kuo3Init, + dim1213Kuo3Init, + dim1214Kuo3Init, + dim1215Kuo3Init, + dim1216Kuo3Init, + dim1217Kuo3Init, + dim1218Kuo3Init, + dim1219Kuo3Init, + dim1220Kuo3Init, + dim1221Kuo3Init, + dim1222Kuo3Init, + dim1223Kuo3Init, + dim1224Kuo3Init, + dim1225Kuo3Init, + dim1226Kuo3Init, + dim1227Kuo3Init, + dim1228Kuo3Init, + dim1229Kuo3Init, + dim1230Kuo3Init, + dim1231Kuo3Init, + dim1232Kuo3Init, + dim1233Kuo3Init, + dim1234Kuo3Init, + dim1235Kuo3Init, + dim1236Kuo3Init, + dim1237Kuo3Init, + dim1238Kuo3Init, + dim1239Kuo3Init, + dim1240Kuo3Init, + dim1241Kuo3Init, + dim1242Kuo3Init, + dim1243Kuo3Init, + dim1244Kuo3Init, + dim1245Kuo3Init, + dim1246Kuo3Init, + dim1247Kuo3Init, + dim1248Kuo3Init, + dim1249Kuo3Init, + dim1250Kuo3Init, + dim1251Kuo3Init, + dim1252Kuo3Init, + dim1253Kuo3Init, + dim1254Kuo3Init, + dim1255Kuo3Init, + dim1256Kuo3Init, + dim1257Kuo3Init, + dim1258Kuo3Init, + dim1259Kuo3Init, + dim1260Kuo3Init, + dim1261Kuo3Init, + dim1262Kuo3Init, + dim1263Kuo3Init, + dim1264Kuo3Init, + dim1265Kuo3Init, + dim1266Kuo3Init, + dim1267Kuo3Init, + dim1268Kuo3Init, + dim1269Kuo3Init, + dim1270Kuo3Init, + dim1271Kuo3Init, + dim1272Kuo3Init, + dim1273Kuo3Init, + dim1274Kuo3Init, + dim1275Kuo3Init, + dim1276Kuo3Init, + dim1277Kuo3Init, + dim1278Kuo3Init, + dim1279Kuo3Init, + dim1280Kuo3Init, + dim1281Kuo3Init, + dim1282Kuo3Init, + dim1283Kuo3Init, + dim1284Kuo3Init, + dim1285Kuo3Init, + dim1286Kuo3Init, + dim1287Kuo3Init, + dim1288Kuo3Init, + dim1289Kuo3Init, + dim1290Kuo3Init, + dim1291Kuo3Init, + dim1292Kuo3Init, + dim1293Kuo3Init, + dim1294Kuo3Init, + dim1295Kuo3Init, + dim1296Kuo3Init, + dim1297Kuo3Init, + dim1298Kuo3Init, + dim1299Kuo3Init, + dim1300Kuo3Init, + dim1301Kuo3Init, + dim1302Kuo3Init, + dim1303Kuo3Init, + dim1304Kuo3Init, + dim1305Kuo3Init, + dim1306Kuo3Init, + dim1307Kuo3Init, + dim1308Kuo3Init, + dim1309Kuo3Init, + dim1310Kuo3Init, + dim1311Kuo3Init, + dim1312Kuo3Init, + dim1313Kuo3Init, + dim1314Kuo3Init, + dim1315Kuo3Init, + dim1316Kuo3Init, + dim1317Kuo3Init, + dim1318Kuo3Init, + dim1319Kuo3Init, + dim1320Kuo3Init, + dim1321Kuo3Init, + dim1322Kuo3Init, + dim1323Kuo3Init, + dim1324Kuo3Init, + dim1325Kuo3Init, + dim1326Kuo3Init, + dim1327Kuo3Init, + dim1328Kuo3Init, + dim1329Kuo3Init, + dim1330Kuo3Init, + dim1331Kuo3Init, + dim1332Kuo3Init, + dim1333Kuo3Init, + dim1334Kuo3Init, + dim1335Kuo3Init, + dim1336Kuo3Init, + dim1337Kuo3Init, + dim1338Kuo3Init, + dim1339Kuo3Init, + dim1340Kuo3Init, + dim1341Kuo3Init, + dim1342Kuo3Init, + dim1343Kuo3Init, + dim1344Kuo3Init, + dim1345Kuo3Init, + dim1346Kuo3Init, + dim1347Kuo3Init, + dim1348Kuo3Init, + dim1349Kuo3Init, + dim1350Kuo3Init, + dim1351Kuo3Init, + dim1352Kuo3Init, + dim1353Kuo3Init, + dim1354Kuo3Init, + dim1355Kuo3Init, + dim1356Kuo3Init, + dim1357Kuo3Init, + dim1358Kuo3Init, + dim1359Kuo3Init, + dim1360Kuo3Init, + dim1361Kuo3Init, + dim1362Kuo3Init, + dim1363Kuo3Init, + dim1364Kuo3Init, + dim1365Kuo3Init, + dim1366Kuo3Init, + dim1367Kuo3Init, + dim1368Kuo3Init, + dim1369Kuo3Init, + dim1370Kuo3Init, + dim1371Kuo3Init, + dim1372Kuo3Init, + dim1373Kuo3Init, + dim1374Kuo3Init, + dim1375Kuo3Init, + dim1376Kuo3Init, + dim1377Kuo3Init, + dim1378Kuo3Init, + dim1379Kuo3Init, + dim1380Kuo3Init, + dim1381Kuo3Init, + dim1382Kuo3Init, + dim1383Kuo3Init, + dim1384Kuo3Init, + dim1385Kuo3Init, + dim1386Kuo3Init, + dim1387Kuo3Init, + dim1388Kuo3Init, + dim1389Kuo3Init, + dim1390Kuo3Init, + dim1391Kuo3Init, + dim1392Kuo3Init, + dim1393Kuo3Init, + dim1394Kuo3Init, + dim1395Kuo3Init, + dim1396Kuo3Init, + dim1397Kuo3Init, + dim1398Kuo3Init, + dim1399Kuo3Init, + dim1400Kuo3Init, + dim1401Kuo3Init, + dim1402Kuo3Init, + dim1403Kuo3Init, + dim1404Kuo3Init, + dim1405Kuo3Init, + dim1406Kuo3Init, + dim1407Kuo3Init, + dim1408Kuo3Init, + dim1409Kuo3Init, + dim1410Kuo3Init, + dim1411Kuo3Init, + dim1412Kuo3Init, + dim1413Kuo3Init, + dim1414Kuo3Init, + dim1415Kuo3Init, + dim1416Kuo3Init, + dim1417Kuo3Init, + dim1418Kuo3Init, + dim1419Kuo3Init, + dim1420Kuo3Init, + dim1421Kuo3Init, + dim1422Kuo3Init, + dim1423Kuo3Init, + dim1424Kuo3Init, + dim1425Kuo3Init, + dim1426Kuo3Init, + dim1427Kuo3Init, + dim1428Kuo3Init, + dim1429Kuo3Init, + dim1430Kuo3Init, + dim1431Kuo3Init, + dim1432Kuo3Init, + dim1433Kuo3Init, + dim1434Kuo3Init, + dim1435Kuo3Init, + dim1436Kuo3Init, + dim1437Kuo3Init, + dim1438Kuo3Init, + dim1439Kuo3Init, + dim1440Kuo3Init, + dim1441Kuo3Init, + dim1442Kuo3Init, + dim1443Kuo3Init, + dim1444Kuo3Init, + dim1445Kuo3Init, + dim1446Kuo3Init, + dim1447Kuo3Init, + dim1448Kuo3Init, + dim1449Kuo3Init, + dim1450Kuo3Init, + dim1451Kuo3Init, + dim1452Kuo3Init, + dim1453Kuo3Init, + dim1454Kuo3Init, + dim1455Kuo3Init, + dim1456Kuo3Init, + dim1457Kuo3Init, + dim1458Kuo3Init, + dim1459Kuo3Init, + dim1460Kuo3Init, + dim1461Kuo3Init, + dim1462Kuo3Init, + dim1463Kuo3Init, + dim1464Kuo3Init, + dim1465Kuo3Init, + dim1466Kuo3Init, + dim1467Kuo3Init, + dim1468Kuo3Init, + dim1469Kuo3Init, + dim1470Kuo3Init, + dim1471Kuo3Init, + dim1472Kuo3Init, + dim1473Kuo3Init, + dim1474Kuo3Init, + dim1475Kuo3Init, + dim1476Kuo3Init, + dim1477Kuo3Init, + dim1478Kuo3Init, + dim1479Kuo3Init, + dim1480Kuo3Init, + dim1481Kuo3Init, + dim1482Kuo3Init, + dim1483Kuo3Init, + dim1484Kuo3Init, + dim1485Kuo3Init, + dim1486Kuo3Init, + dim1487Kuo3Init, + dim1488Kuo3Init, + dim1489Kuo3Init, + dim1490Kuo3Init, + dim1491Kuo3Init, + dim1492Kuo3Init, + dim1493Kuo3Init, + dim1494Kuo3Init, + dim1495Kuo3Init, + dim1496Kuo3Init, + dim1497Kuo3Init, + dim1498Kuo3Init, + dim1499Kuo3Init, + dim1500Kuo3Init, + dim1501Kuo3Init, + dim1502Kuo3Init, + dim1503Kuo3Init, + dim1504Kuo3Init, + dim1505Kuo3Init, + dim1506Kuo3Init, + dim1507Kuo3Init, + dim1508Kuo3Init, + dim1509Kuo3Init, + dim1510Kuo3Init, + dim1511Kuo3Init, + dim1512Kuo3Init, + dim1513Kuo3Init, + dim1514Kuo3Init, + dim1515Kuo3Init, + dim1516Kuo3Init, + dim1517Kuo3Init, + dim1518Kuo3Init, + dim1519Kuo3Init, + dim1520Kuo3Init, + dim1521Kuo3Init, + dim1522Kuo3Init, + dim1523Kuo3Init, + dim1524Kuo3Init, + dim1525Kuo3Init, + dim1526Kuo3Init, + dim1527Kuo3Init, + dim1528Kuo3Init, + dim1529Kuo3Init, + dim1530Kuo3Init, + dim1531Kuo3Init, + dim1532Kuo3Init, + dim1533Kuo3Init, + dim1534Kuo3Init, + dim1535Kuo3Init, + dim1536Kuo3Init, + dim1537Kuo3Init, + dim1538Kuo3Init, + dim1539Kuo3Init, + dim1540Kuo3Init, + dim1541Kuo3Init, + dim1542Kuo3Init, + dim1543Kuo3Init, + dim1544Kuo3Init, + dim1545Kuo3Init, + dim1546Kuo3Init, + dim1547Kuo3Init, + dim1548Kuo3Init, + dim1549Kuo3Init, + dim1550Kuo3Init, + dim1551Kuo3Init, + dim1552Kuo3Init, + dim1553Kuo3Init, + dim1554Kuo3Init, + dim1555Kuo3Init, + dim1556Kuo3Init, + dim1557Kuo3Init, + dim1558Kuo3Init, + dim1559Kuo3Init, + dim1560Kuo3Init, + dim1561Kuo3Init, + dim1562Kuo3Init, + dim1563Kuo3Init, + dim1564Kuo3Init, + dim1565Kuo3Init, + dim1566Kuo3Init, + dim1567Kuo3Init, + dim1568Kuo3Init, + dim1569Kuo3Init, + dim1570Kuo3Init, + dim1571Kuo3Init, + dim1572Kuo3Init, + dim1573Kuo3Init, + dim1574Kuo3Init, + dim1575Kuo3Init, + dim1576Kuo3Init, + dim1577Kuo3Init, + dim1578Kuo3Init, + dim1579Kuo3Init, + dim1580Kuo3Init, + dim1581Kuo3Init, + dim1582Kuo3Init, + dim1583Kuo3Init, + dim1584Kuo3Init, + dim1585Kuo3Init, + dim1586Kuo3Init, + dim1587Kuo3Init, + dim1588Kuo3Init, + dim1589Kuo3Init, + dim1590Kuo3Init, + dim1591Kuo3Init, + dim1592Kuo3Init, + dim1593Kuo3Init, + dim1594Kuo3Init, + dim1595Kuo3Init, + dim1596Kuo3Init, + dim1597Kuo3Init, + dim1598Kuo3Init, + dim1599Kuo3Init, + dim1600Kuo3Init, + dim1601Kuo3Init, + dim1602Kuo3Init, + dim1603Kuo3Init, + dim1604Kuo3Init, + dim1605Kuo3Init, + dim1606Kuo3Init, + dim1607Kuo3Init, + dim1608Kuo3Init, + dim1609Kuo3Init, + dim1610Kuo3Init, + dim1611Kuo3Init, + dim1612Kuo3Init, + dim1613Kuo3Init, + dim1614Kuo3Init, + dim1615Kuo3Init, + dim1616Kuo3Init, + dim1617Kuo3Init, + dim1618Kuo3Init, + dim1619Kuo3Init, + dim1620Kuo3Init, + dim1621Kuo3Init, + dim1622Kuo3Init, + dim1623Kuo3Init, + dim1624Kuo3Init, + dim1625Kuo3Init, + dim1626Kuo3Init, + dim1627Kuo3Init, + dim1628Kuo3Init, + dim1629Kuo3Init, + dim1630Kuo3Init, + dim1631Kuo3Init, + dim1632Kuo3Init, + dim1633Kuo3Init, + dim1634Kuo3Init, + dim1635Kuo3Init, + dim1636Kuo3Init, + dim1637Kuo3Init, + dim1638Kuo3Init, + dim1639Kuo3Init, + dim1640Kuo3Init, + dim1641Kuo3Init, + dim1642Kuo3Init, + dim1643Kuo3Init, + dim1644Kuo3Init, + dim1645Kuo3Init, + dim1646Kuo3Init, + dim1647Kuo3Init, + dim1648Kuo3Init, + dim1649Kuo3Init, + dim1650Kuo3Init, + dim1651Kuo3Init, + dim1652Kuo3Init, + dim1653Kuo3Init, + dim1654Kuo3Init, + dim1655Kuo3Init, + dim1656Kuo3Init, + dim1657Kuo3Init, + dim1658Kuo3Init, + dim1659Kuo3Init, + dim1660Kuo3Init, + dim1661Kuo3Init, + dim1662Kuo3Init, + dim1663Kuo3Init, + dim1664Kuo3Init, + dim1665Kuo3Init, + dim1666Kuo3Init, + dim1667Kuo3Init, + dim1668Kuo3Init, + dim1669Kuo3Init, + dim1670Kuo3Init, + dim1671Kuo3Init, + dim1672Kuo3Init, + dim1673Kuo3Init, + dim1674Kuo3Init, + dim1675Kuo3Init, + dim1676Kuo3Init, + dim1677Kuo3Init, + dim1678Kuo3Init, + dim1679Kuo3Init, + dim1680Kuo3Init, + dim1681Kuo3Init, + dim1682Kuo3Init, + dim1683Kuo3Init, + dim1684Kuo3Init, + dim1685Kuo3Init, + dim1686Kuo3Init, + dim1687Kuo3Init, + dim1688Kuo3Init, + dim1689Kuo3Init, + dim1690Kuo3Init, + dim1691Kuo3Init, + dim1692Kuo3Init, + dim1693Kuo3Init, + dim1694Kuo3Init, + dim1695Kuo3Init, + dim1696Kuo3Init, + dim1697Kuo3Init, + dim1698Kuo3Init, + dim1699Kuo3Init, + dim1700Kuo3Init, + dim1701Kuo3Init, + dim1702Kuo3Init, + dim1703Kuo3Init, + dim1704Kuo3Init, + dim1705Kuo3Init, + dim1706Kuo3Init, + dim1707Kuo3Init, + dim1708Kuo3Init, + dim1709Kuo3Init, + dim1710Kuo3Init, + dim1711Kuo3Init, + dim1712Kuo3Init, + dim1713Kuo3Init, + dim1714Kuo3Init, + dim1715Kuo3Init, + dim1716Kuo3Init, + dim1717Kuo3Init, + dim1718Kuo3Init, + dim1719Kuo3Init, + dim1720Kuo3Init, + dim1721Kuo3Init, + dim1722Kuo3Init, + dim1723Kuo3Init, + dim1724Kuo3Init, + dim1725Kuo3Init, + dim1726Kuo3Init, + dim1727Kuo3Init, + dim1728Kuo3Init, + dim1729Kuo3Init, + dim1730Kuo3Init, + dim1731Kuo3Init, + dim1732Kuo3Init, + dim1733Kuo3Init, + dim1734Kuo3Init, + dim1735Kuo3Init, + dim1736Kuo3Init, + dim1737Kuo3Init, + dim1738Kuo3Init, + dim1739Kuo3Init, + dim1740Kuo3Init, + dim1741Kuo3Init, + dim1742Kuo3Init, + dim1743Kuo3Init, + dim1744Kuo3Init, + dim1745Kuo3Init, + dim1746Kuo3Init, + dim1747Kuo3Init, + dim1748Kuo3Init, + dim1749Kuo3Init, + dim1750Kuo3Init, + dim1751Kuo3Init, + dim1752Kuo3Init, + dim1753Kuo3Init, + dim1754Kuo3Init, + dim1755Kuo3Init, + dim1756Kuo3Init, + dim1757Kuo3Init, + dim1758Kuo3Init, + dim1759Kuo3Init, + dim1760Kuo3Init, + dim1761Kuo3Init, + dim1762Kuo3Init, + dim1763Kuo3Init, + dim1764Kuo3Init, + dim1765Kuo3Init, + dim1766Kuo3Init, + dim1767Kuo3Init, + dim1768Kuo3Init, + dim1769Kuo3Init, + dim1770Kuo3Init, + dim1771Kuo3Init, + dim1772Kuo3Init, + dim1773Kuo3Init, + dim1774Kuo3Init, + dim1775Kuo3Init, + dim1776Kuo3Init, + dim1777Kuo3Init, + dim1778Kuo3Init, + dim1779Kuo3Init, + dim1780Kuo3Init, + dim1781Kuo3Init, + dim1782Kuo3Init, + dim1783Kuo3Init, + dim1784Kuo3Init, + dim1785Kuo3Init, + dim1786Kuo3Init, + dim1787Kuo3Init, + dim1788Kuo3Init, + dim1789Kuo3Init, + dim1790Kuo3Init, + dim1791Kuo3Init, + dim1792Kuo3Init, + dim1793Kuo3Init, + dim1794Kuo3Init, + dim1795Kuo3Init, + dim1796Kuo3Init, + dim1797Kuo3Init, + dim1798Kuo3Init, + dim1799Kuo3Init, + dim1800Kuo3Init, + dim1801Kuo3Init, + dim1802Kuo3Init, + dim1803Kuo3Init, + dim1804Kuo3Init, + dim1805Kuo3Init, + dim1806Kuo3Init, + dim1807Kuo3Init, + dim1808Kuo3Init, + dim1809Kuo3Init, + dim1810Kuo3Init, + dim1811Kuo3Init, + dim1812Kuo3Init, + dim1813Kuo3Init, + dim1814Kuo3Init, + dim1815Kuo3Init, + dim1816Kuo3Init, + dim1817Kuo3Init, + dim1818Kuo3Init, + dim1819Kuo3Init, + dim1820Kuo3Init, + dim1821Kuo3Init, + dim1822Kuo3Init, + dim1823Kuo3Init, + dim1824Kuo3Init, + dim1825Kuo3Init, + dim1826Kuo3Init, + dim1827Kuo3Init, + dim1828Kuo3Init, + dim1829Kuo3Init, + dim1830Kuo3Init, + dim1831Kuo3Init, + dim1832Kuo3Init, + dim1833Kuo3Init, + dim1834Kuo3Init, + dim1835Kuo3Init, + dim1836Kuo3Init, + dim1837Kuo3Init, + dim1838Kuo3Init, + dim1839Kuo3Init, + dim1840Kuo3Init, + dim1841Kuo3Init, + dim1842Kuo3Init, + dim1843Kuo3Init, + dim1844Kuo3Init, + dim1845Kuo3Init, + dim1846Kuo3Init, + dim1847Kuo3Init, + dim1848Kuo3Init, + dim1849Kuo3Init, + dim1850Kuo3Init, + dim1851Kuo3Init, + dim1852Kuo3Init, + dim1853Kuo3Init, + dim1854Kuo3Init, + dim1855Kuo3Init, + dim1856Kuo3Init, + dim1857Kuo3Init, + dim1858Kuo3Init, + dim1859Kuo3Init, + dim1860Kuo3Init, + dim1861Kuo3Init, + dim1862Kuo3Init, + dim1863Kuo3Init, + dim1864Kuo3Init, + dim1865Kuo3Init, + dim1866Kuo3Init, + dim1867Kuo3Init, + dim1868Kuo3Init, + dim1869Kuo3Init, + dim1870Kuo3Init, + dim1871Kuo3Init, + dim1872Kuo3Init, + dim1873Kuo3Init, + dim1874Kuo3Init, + dim1875Kuo3Init, + dim1876Kuo3Init, + dim1877Kuo3Init, + dim1878Kuo3Init, + dim1879Kuo3Init, + dim1880Kuo3Init, + dim1881Kuo3Init, + dim1882Kuo3Init, + dim1883Kuo3Init, + dim1884Kuo3Init, + dim1885Kuo3Init, + dim1886Kuo3Init, + dim1887Kuo3Init, + dim1888Kuo3Init, + dim1889Kuo3Init, + dim1890Kuo3Init, + dim1891Kuo3Init, + dim1892Kuo3Init, + dim1893Kuo3Init, + dim1894Kuo3Init, + dim1895Kuo3Init, + dim1896Kuo3Init, + dim1897Kuo3Init, + dim1898Kuo3Init, + dim1899Kuo3Init, + dim1900Kuo3Init, + dim1901Kuo3Init, + dim1902Kuo3Init, + dim1903Kuo3Init, + dim1904Kuo3Init, + dim1905Kuo3Init, + dim1906Kuo3Init, + dim1907Kuo3Init, + dim1908Kuo3Init, + dim1909Kuo3Init, + dim1910Kuo3Init, + dim1911Kuo3Init, + dim1912Kuo3Init, + dim1913Kuo3Init, + dim1914Kuo3Init, + dim1915Kuo3Init, + dim1916Kuo3Init, + dim1917Kuo3Init, + dim1918Kuo3Init, + dim1919Kuo3Init, + dim1920Kuo3Init, + dim1921Kuo3Init, + dim1922Kuo3Init, + dim1923Kuo3Init, + dim1924Kuo3Init, + dim1925Kuo3Init, + dim1926Kuo3Init, + dim1927Kuo3Init, + dim1928Kuo3Init, + dim1929Kuo3Init, + dim1930Kuo3Init, + dim1931Kuo3Init, + dim1932Kuo3Init, + dim1933Kuo3Init, + dim1934Kuo3Init, + dim1935Kuo3Init, + dim1936Kuo3Init, + dim1937Kuo3Init, + dim1938Kuo3Init, + dim1939Kuo3Init, + dim1940Kuo3Init, + dim1941Kuo3Init, + dim1942Kuo3Init, + dim1943Kuo3Init, + dim1944Kuo3Init, + dim1945Kuo3Init, + dim1946Kuo3Init, + dim1947Kuo3Init, + dim1948Kuo3Init, + dim1949Kuo3Init, + dim1950Kuo3Init, + dim1951Kuo3Init, + dim1952Kuo3Init, + dim1953Kuo3Init, + dim1954Kuo3Init, + dim1955Kuo3Init, + dim1956Kuo3Init, + dim1957Kuo3Init, + dim1958Kuo3Init, + dim1959Kuo3Init, + dim1960Kuo3Init, + dim1961Kuo3Init, + dim1962Kuo3Init, + dim1963Kuo3Init, + dim1964Kuo3Init, + dim1965Kuo3Init, + dim1966Kuo3Init, + dim1967Kuo3Init, + dim1968Kuo3Init, + dim1969Kuo3Init, + dim1970Kuo3Init, + dim1971Kuo3Init, + dim1972Kuo3Init, + dim1973Kuo3Init, + dim1974Kuo3Init, + dim1975Kuo3Init, + dim1976Kuo3Init, + dim1977Kuo3Init, + dim1978Kuo3Init, + dim1979Kuo3Init, + dim1980Kuo3Init, + dim1981Kuo3Init, + dim1982Kuo3Init, + dim1983Kuo3Init, + dim1984Kuo3Init, + dim1985Kuo3Init, + dim1986Kuo3Init, + dim1987Kuo3Init, + dim1988Kuo3Init, + dim1989Kuo3Init, + dim1990Kuo3Init, + dim1991Kuo3Init, + dim1992Kuo3Init, + dim1993Kuo3Init, + dim1994Kuo3Init, + dim1995Kuo3Init, + dim1996Kuo3Init, + dim1997Kuo3Init, + dim1998Kuo3Init, + dim1999Kuo3Init, + dim2000Kuo3Init, + dim2001Kuo3Init, + dim2002Kuo3Init, + dim2003Kuo3Init, + dim2004Kuo3Init, + dim2005Kuo3Init, + dim2006Kuo3Init, + dim2007Kuo3Init, + dim2008Kuo3Init, + dim2009Kuo3Init, + dim2010Kuo3Init, + dim2011Kuo3Init, + dim2012Kuo3Init, + dim2013Kuo3Init, + dim2014Kuo3Init, + dim2015Kuo3Init, + dim2016Kuo3Init, + dim2017Kuo3Init, + dim2018Kuo3Init, + dim2019Kuo3Init, + dim2020Kuo3Init, + dim2021Kuo3Init, + dim2022Kuo3Init, + dim2023Kuo3Init, + dim2024Kuo3Init, + dim2025Kuo3Init, + dim2026Kuo3Init, + dim2027Kuo3Init, + dim2028Kuo3Init, + dim2029Kuo3Init, + dim2030Kuo3Init, + dim2031Kuo3Init, + dim2032Kuo3Init, + dim2033Kuo3Init, + dim2034Kuo3Init, + dim2035Kuo3Init, + dim2036Kuo3Init, + dim2037Kuo3Init, + dim2038Kuo3Init, + dim2039Kuo3Init, + dim2040Kuo3Init, + dim2041Kuo3Init, + dim2042Kuo3Init, + dim2043Kuo3Init, + dim2044Kuo3Init, + dim2045Kuo3Init, + dim2046Kuo3Init, + dim2047Kuo3Init, + dim2048Kuo3Init, + dim2049Kuo3Init, + dim2050Kuo3Init, + dim2051Kuo3Init, + dim2052Kuo3Init, + dim2053Kuo3Init, + dim2054Kuo3Init, + dim2055Kuo3Init, + dim2056Kuo3Init, + dim2057Kuo3Init, + dim2058Kuo3Init, + dim2059Kuo3Init, + dim2060Kuo3Init, + dim2061Kuo3Init, + dim2062Kuo3Init, + dim2063Kuo3Init, + dim2064Kuo3Init, + dim2065Kuo3Init, + dim2066Kuo3Init, + dim2067Kuo3Init, + dim2068Kuo3Init, + dim2069Kuo3Init, + dim2070Kuo3Init, + dim2071Kuo3Init, + dim2072Kuo3Init, + dim2073Kuo3Init, + dim2074Kuo3Init, + dim2075Kuo3Init, + dim2076Kuo3Init, + dim2077Kuo3Init, + dim2078Kuo3Init, + dim2079Kuo3Init, + dim2080Kuo3Init, + dim2081Kuo3Init, + dim2082Kuo3Init, + dim2083Kuo3Init, + dim2084Kuo3Init, + dim2085Kuo3Init, + dim2086Kuo3Init, + dim2087Kuo3Init, + dim2088Kuo3Init, + dim2089Kuo3Init, + dim2090Kuo3Init, + dim2091Kuo3Init, + dim2092Kuo3Init, + dim2093Kuo3Init, + dim2094Kuo3Init, + dim2095Kuo3Init, + dim2096Kuo3Init, + dim2097Kuo3Init, + dim2098Kuo3Init, + dim2099Kuo3Init, + dim2100Kuo3Init, + dim2101Kuo3Init, + dim2102Kuo3Init, + dim2103Kuo3Init, + dim2104Kuo3Init, + dim2105Kuo3Init, + dim2106Kuo3Init, + dim2107Kuo3Init, + dim2108Kuo3Init, + dim2109Kuo3Init, + dim2110Kuo3Init, + dim2111Kuo3Init, + dim2112Kuo3Init, + dim2113Kuo3Init, + dim2114Kuo3Init, + dim2115Kuo3Init, + dim2116Kuo3Init, + dim2117Kuo3Init, + dim2118Kuo3Init, + dim2119Kuo3Init, + dim2120Kuo3Init, + dim2121Kuo3Init, + dim2122Kuo3Init, + dim2123Kuo3Init, + dim2124Kuo3Init, + dim2125Kuo3Init, + dim2126Kuo3Init, + dim2127Kuo3Init, + dim2128Kuo3Init, + dim2129Kuo3Init, + dim2130Kuo3Init, + dim2131Kuo3Init, + dim2132Kuo3Init, + dim2133Kuo3Init, + dim2134Kuo3Init, + dim2135Kuo3Init, + dim2136Kuo3Init, + dim2137Kuo3Init, + dim2138Kuo3Init, + dim2139Kuo3Init, + dim2140Kuo3Init, + dim2141Kuo3Init, + dim2142Kuo3Init, + dim2143Kuo3Init, + dim2144Kuo3Init, + dim2145Kuo3Init, + dim2146Kuo3Init, + dim2147Kuo3Init, + dim2148Kuo3Init, + dim2149Kuo3Init, + dim2150Kuo3Init, + dim2151Kuo3Init, + dim2152Kuo3Init, + dim2153Kuo3Init, + dim2154Kuo3Init, + dim2155Kuo3Init, + dim2156Kuo3Init, + dim2157Kuo3Init, + dim2158Kuo3Init, + dim2159Kuo3Init, + dim2160Kuo3Init, + dim2161Kuo3Init, + dim2162Kuo3Init, + dim2163Kuo3Init, + dim2164Kuo3Init, + dim2165Kuo3Init, + dim2166Kuo3Init, + dim2167Kuo3Init, + dim2168Kuo3Init, + dim2169Kuo3Init, + dim2170Kuo3Init, + dim2171Kuo3Init, + dim2172Kuo3Init, + dim2173Kuo3Init, + dim2174Kuo3Init, + dim2175Kuo3Init, + dim2176Kuo3Init, + dim2177Kuo3Init, + dim2178Kuo3Init, + dim2179Kuo3Init, + dim2180Kuo3Init, + dim2181Kuo3Init, + dim2182Kuo3Init, + dim2183Kuo3Init, + dim2184Kuo3Init, + dim2185Kuo3Init, + dim2186Kuo3Init, + dim2187Kuo3Init, + dim2188Kuo3Init, + dim2189Kuo3Init, + dim2190Kuo3Init, + dim2191Kuo3Init, + dim2192Kuo3Init, + dim2193Kuo3Init, + dim2194Kuo3Init, + dim2195Kuo3Init, + dim2196Kuo3Init, + dim2197Kuo3Init, + dim2198Kuo3Init, + dim2199Kuo3Init, + dim2200Kuo3Init, + dim2201Kuo3Init, + dim2202Kuo3Init, + dim2203Kuo3Init, + dim2204Kuo3Init, + dim2205Kuo3Init, + dim2206Kuo3Init, + dim2207Kuo3Init, + dim2208Kuo3Init, + dim2209Kuo3Init, + dim2210Kuo3Init, + dim2211Kuo3Init, + dim2212Kuo3Init, + dim2213Kuo3Init, + dim2214Kuo3Init, + dim2215Kuo3Init, + dim2216Kuo3Init, + dim2217Kuo3Init, + dim2218Kuo3Init, + dim2219Kuo3Init, + dim2220Kuo3Init, + dim2221Kuo3Init, + dim2222Kuo3Init, + dim2223Kuo3Init, + dim2224Kuo3Init, + dim2225Kuo3Init, + dim2226Kuo3Init, + dim2227Kuo3Init, + dim2228Kuo3Init, + dim2229Kuo3Init, + dim2230Kuo3Init, + dim2231Kuo3Init, + dim2232Kuo3Init, + dim2233Kuo3Init, + dim2234Kuo3Init, + dim2235Kuo3Init, + dim2236Kuo3Init, + dim2237Kuo3Init, + dim2238Kuo3Init, + dim2239Kuo3Init, + dim2240Kuo3Init, + dim2241Kuo3Init, + dim2242Kuo3Init, + dim2243Kuo3Init, + dim2244Kuo3Init, + dim2245Kuo3Init, + dim2246Kuo3Init, + dim2247Kuo3Init, + dim2248Kuo3Init, + dim2249Kuo3Init, + dim2250Kuo3Init, + dim2251Kuo3Init, + dim2252Kuo3Init, + dim2253Kuo3Init, + dim2254Kuo3Init, + dim2255Kuo3Init, + dim2256Kuo3Init, + dim2257Kuo3Init, + dim2258Kuo3Init, + dim2259Kuo3Init, + dim2260Kuo3Init, + dim2261Kuo3Init, + dim2262Kuo3Init, + dim2263Kuo3Init, + dim2264Kuo3Init, + dim2265Kuo3Init, + dim2266Kuo3Init, + dim2267Kuo3Init, + dim2268Kuo3Init, + dim2269Kuo3Init, + dim2270Kuo3Init, + dim2271Kuo3Init, + dim2272Kuo3Init, + dim2273Kuo3Init, + dim2274Kuo3Init, + dim2275Kuo3Init, + dim2276Kuo3Init, + dim2277Kuo3Init, + dim2278Kuo3Init, + dim2279Kuo3Init, + dim2280Kuo3Init, + dim2281Kuo3Init, + dim2282Kuo3Init, + dim2283Kuo3Init, + dim2284Kuo3Init, + dim2285Kuo3Init, + dim2286Kuo3Init, + dim2287Kuo3Init, + dim2288Kuo3Init, + dim2289Kuo3Init, + dim2290Kuo3Init, + dim2291Kuo3Init, + dim2292Kuo3Init, + dim2293Kuo3Init, + dim2294Kuo3Init, + dim2295Kuo3Init, + dim2296Kuo3Init, + dim2297Kuo3Init, + dim2298Kuo3Init, + dim2299Kuo3Init, + dim2300Kuo3Init, + dim2301Kuo3Init, + dim2302Kuo3Init, + dim2303Kuo3Init, + dim2304Kuo3Init, + dim2305Kuo3Init, + dim2306Kuo3Init, + dim2307Kuo3Init, + dim2308Kuo3Init, + dim2309Kuo3Init, + dim2310Kuo3Init, + dim2311Kuo3Init, + dim2312Kuo3Init, + dim2313Kuo3Init, + dim2314Kuo3Init, + dim2315Kuo3Init, + dim2316Kuo3Init, + dim2317Kuo3Init, + dim2318Kuo3Init, + dim2319Kuo3Init, + dim2320Kuo3Init, + dim2321Kuo3Init, + dim2322Kuo3Init, + dim2323Kuo3Init, + dim2324Kuo3Init, + dim2325Kuo3Init, + dim2326Kuo3Init, + dim2327Kuo3Init, + dim2328Kuo3Init, + dim2329Kuo3Init, + dim2330Kuo3Init, + dim2331Kuo3Init, + dim2332Kuo3Init, + dim2333Kuo3Init, + dim2334Kuo3Init, + dim2335Kuo3Init, + dim2336Kuo3Init, + dim2337Kuo3Init, + dim2338Kuo3Init, + dim2339Kuo3Init, + dim2340Kuo3Init, + dim2341Kuo3Init, + dim2342Kuo3Init, + dim2343Kuo3Init, + dim2344Kuo3Init, + dim2345Kuo3Init, + dim2346Kuo3Init, + dim2347Kuo3Init, + dim2348Kuo3Init, + dim2349Kuo3Init, + dim2350Kuo3Init, + dim2351Kuo3Init, + dim2352Kuo3Init, + dim2353Kuo3Init, + dim2354Kuo3Init, + dim2355Kuo3Init, + dim2356Kuo3Init, + dim2357Kuo3Init, + dim2358Kuo3Init, + dim2359Kuo3Init, + dim2360Kuo3Init, + dim2361Kuo3Init, + dim2362Kuo3Init, + dim2363Kuo3Init, + dim2364Kuo3Init, + dim2365Kuo3Init, + dim2366Kuo3Init, + dim2367Kuo3Init, + dim2368Kuo3Init, + dim2369Kuo3Init, + dim2370Kuo3Init, + dim2371Kuo3Init, + dim2372Kuo3Init, + dim2373Kuo3Init, + dim2374Kuo3Init, + dim2375Kuo3Init, + dim2376Kuo3Init, + dim2377Kuo3Init, + dim2378Kuo3Init, + dim2379Kuo3Init, + dim2380Kuo3Init, + dim2381Kuo3Init, + dim2382Kuo3Init, + dim2383Kuo3Init, + dim2384Kuo3Init, + dim2385Kuo3Init, + dim2386Kuo3Init, + dim2387Kuo3Init, + dim2388Kuo3Init, + dim2389Kuo3Init, + dim2390Kuo3Init, + dim2391Kuo3Init, + dim2392Kuo3Init, + dim2393Kuo3Init, + dim2394Kuo3Init, + dim2395Kuo3Init, + dim2396Kuo3Init, + dim2397Kuo3Init, + dim2398Kuo3Init, + dim2399Kuo3Init, + dim2400Kuo3Init, + dim2401Kuo3Init, + dim2402Kuo3Init, + dim2403Kuo3Init, + dim2404Kuo3Init, + dim2405Kuo3Init, + dim2406Kuo3Init, + dim2407Kuo3Init, + dim2408Kuo3Init, + dim2409Kuo3Init, + dim2410Kuo3Init, + dim2411Kuo3Init, + dim2412Kuo3Init, + dim2413Kuo3Init, + dim2414Kuo3Init, + dim2415Kuo3Init, + dim2416Kuo3Init, + dim2417Kuo3Init, + dim2418Kuo3Init, + dim2419Kuo3Init, + dim2420Kuo3Init, + dim2421Kuo3Init, + dim2422Kuo3Init, + dim2423Kuo3Init, + dim2424Kuo3Init, + dim2425Kuo3Init, + dim2426Kuo3Init, + dim2427Kuo3Init, + dim2428Kuo3Init, + dim2429Kuo3Init, + dim2430Kuo3Init, + dim2431Kuo3Init, + dim2432Kuo3Init, + dim2433Kuo3Init, + dim2434Kuo3Init, + dim2435Kuo3Init, + dim2436Kuo3Init, + dim2437Kuo3Init, + dim2438Kuo3Init, + dim2439Kuo3Init, + dim2440Kuo3Init, + dim2441Kuo3Init, + dim2442Kuo3Init, + dim2443Kuo3Init, + dim2444Kuo3Init, + dim2445Kuo3Init, + dim2446Kuo3Init, + dim2447Kuo3Init, + dim2448Kuo3Init, + dim2449Kuo3Init, + dim2450Kuo3Init, + dim2451Kuo3Init, + dim2452Kuo3Init, + dim2453Kuo3Init, + dim2454Kuo3Init, + dim2455Kuo3Init, + dim2456Kuo3Init, + dim2457Kuo3Init, + dim2458Kuo3Init, + dim2459Kuo3Init, + dim2460Kuo3Init, + dim2461Kuo3Init, + dim2462Kuo3Init, + dim2463Kuo3Init, + dim2464Kuo3Init, + dim2465Kuo3Init, + dim2466Kuo3Init, + dim2467Kuo3Init, + dim2468Kuo3Init, + dim2469Kuo3Init, + dim2470Kuo3Init, + dim2471Kuo3Init, + dim2472Kuo3Init, + dim2473Kuo3Init, + dim2474Kuo3Init, + dim2475Kuo3Init, + dim2476Kuo3Init, + dim2477Kuo3Init, + dim2478Kuo3Init, + dim2479Kuo3Init, + dim2480Kuo3Init, + dim2481Kuo3Init, + dim2482Kuo3Init, + dim2483Kuo3Init, + dim2484Kuo3Init, + dim2485Kuo3Init, + dim2486Kuo3Init, + dim2487Kuo3Init, + dim2488Kuo3Init, + dim2489Kuo3Init, + dim2490Kuo3Init, + dim2491Kuo3Init, + dim2492Kuo3Init, + dim2493Kuo3Init, + dim2494Kuo3Init, + dim2495Kuo3Init, + dim2496Kuo3Init, + dim2497Kuo3Init, + dim2498Kuo3Init, + dim2499Kuo3Init, + dim2500Kuo3Init, + dim2501Kuo3Init, + dim2502Kuo3Init, + dim2503Kuo3Init, + dim2504Kuo3Init, + dim2505Kuo3Init, + dim2506Kuo3Init, + dim2507Kuo3Init, + dim2508Kuo3Init, + dim2509Kuo3Init, + dim2510Kuo3Init, + dim2511Kuo3Init, + dim2512Kuo3Init, + dim2513Kuo3Init, + dim2514Kuo3Init, + dim2515Kuo3Init, + dim2516Kuo3Init, + dim2517Kuo3Init, + dim2518Kuo3Init, + dim2519Kuo3Init, + dim2520Kuo3Init, + dim2521Kuo3Init, + dim2522Kuo3Init, + dim2523Kuo3Init, + dim2524Kuo3Init, + dim2525Kuo3Init, + dim2526Kuo3Init, + dim2527Kuo3Init, + dim2528Kuo3Init, + dim2529Kuo3Init, + dim2530Kuo3Init, + dim2531Kuo3Init, + dim2532Kuo3Init, + dim2533Kuo3Init, + dim2534Kuo3Init, + dim2535Kuo3Init, + dim2536Kuo3Init, + dim2537Kuo3Init, + dim2538Kuo3Init, + dim2539Kuo3Init, + dim2540Kuo3Init, + dim2541Kuo3Init, + dim2542Kuo3Init, + dim2543Kuo3Init, + dim2544Kuo3Init, + dim2545Kuo3Init, + dim2546Kuo3Init, + dim2547Kuo3Init, + dim2548Kuo3Init, + dim2549Kuo3Init, + dim2550Kuo3Init, + dim2551Kuo3Init, + dim2552Kuo3Init, + dim2553Kuo3Init, + dim2554Kuo3Init, + dim2555Kuo3Init, + dim2556Kuo3Init, + dim2557Kuo3Init, + dim2558Kuo3Init, + dim2559Kuo3Init, + dim2560Kuo3Init, + dim2561Kuo3Init, + dim2562Kuo3Init, + dim2563Kuo3Init, + dim2564Kuo3Init, + dim2565Kuo3Init, + dim2566Kuo3Init, + dim2567Kuo3Init, + dim2568Kuo3Init, + dim2569Kuo3Init, + dim2570Kuo3Init, + dim2571Kuo3Init, + dim2572Kuo3Init, + dim2573Kuo3Init, + dim2574Kuo3Init, + dim2575Kuo3Init, + dim2576Kuo3Init, + dim2577Kuo3Init, + dim2578Kuo3Init, + dim2579Kuo3Init, + dim2580Kuo3Init, + dim2581Kuo3Init, + dim2582Kuo3Init, + dim2583Kuo3Init, + dim2584Kuo3Init, + dim2585Kuo3Init, + dim2586Kuo3Init, + dim2587Kuo3Init, + dim2588Kuo3Init, + dim2589Kuo3Init, + dim2590Kuo3Init, + dim2591Kuo3Init, + dim2592Kuo3Init, + dim2593Kuo3Init, + dim2594Kuo3Init, + dim2595Kuo3Init, + dim2596Kuo3Init, + dim2597Kuo3Init, + dim2598Kuo3Init, + dim2599Kuo3Init, + dim2600Kuo3Init, + dim2601Kuo3Init, + dim2602Kuo3Init, + dim2603Kuo3Init, + dim2604Kuo3Init, + dim2605Kuo3Init, + dim2606Kuo3Init, + dim2607Kuo3Init, + dim2608Kuo3Init, + dim2609Kuo3Init, + dim2610Kuo3Init, + dim2611Kuo3Init, + dim2612Kuo3Init, + dim2613Kuo3Init, + dim2614Kuo3Init, + dim2615Kuo3Init, + dim2616Kuo3Init, + dim2617Kuo3Init, + dim2618Kuo3Init, + dim2619Kuo3Init, + dim2620Kuo3Init, + dim2621Kuo3Init, + dim2622Kuo3Init, + dim2623Kuo3Init, + dim2624Kuo3Init, + dim2625Kuo3Init, + dim2626Kuo3Init, + dim2627Kuo3Init, + dim2628Kuo3Init, + dim2629Kuo3Init, + dim2630Kuo3Init, + dim2631Kuo3Init, + dim2632Kuo3Init, + dim2633Kuo3Init, + dim2634Kuo3Init, + dim2635Kuo3Init, + dim2636Kuo3Init, + dim2637Kuo3Init, + dim2638Kuo3Init, + dim2639Kuo3Init, + dim2640Kuo3Init, + dim2641Kuo3Init, + dim2642Kuo3Init, + dim2643Kuo3Init, + dim2644Kuo3Init, + dim2645Kuo3Init, + dim2646Kuo3Init, + dim2647Kuo3Init, + dim2648Kuo3Init, + dim2649Kuo3Init, + dim2650Kuo3Init, + dim2651Kuo3Init, + dim2652Kuo3Init, + dim2653Kuo3Init, + dim2654Kuo3Init, + dim2655Kuo3Init, + dim2656Kuo3Init, + dim2657Kuo3Init, + dim2658Kuo3Init, + dim2659Kuo3Init, + dim2660Kuo3Init, + dim2661Kuo3Init, + dim2662Kuo3Init, + dim2663Kuo3Init, + dim2664Kuo3Init, + dim2665Kuo3Init, + dim2666Kuo3Init, + dim2667Kuo3Init, + dim2668Kuo3Init, + dim2669Kuo3Init, + dim2670Kuo3Init, + dim2671Kuo3Init, + dim2672Kuo3Init, + dim2673Kuo3Init, + dim2674Kuo3Init, + dim2675Kuo3Init, + dim2676Kuo3Init, + dim2677Kuo3Init, + dim2678Kuo3Init, + dim2679Kuo3Init, + dim2680Kuo3Init, + dim2681Kuo3Init, + dim2682Kuo3Init, + dim2683Kuo3Init, + dim2684Kuo3Init, + dim2685Kuo3Init, + dim2686Kuo3Init, + dim2687Kuo3Init, + dim2688Kuo3Init, + dim2689Kuo3Init, + dim2690Kuo3Init, + dim2691Kuo3Init, + dim2692Kuo3Init, + dim2693Kuo3Init, + dim2694Kuo3Init, + dim2695Kuo3Init, + dim2696Kuo3Init, + dim2697Kuo3Init, + dim2698Kuo3Init, + dim2699Kuo3Init, + dim2700Kuo3Init, + dim2701Kuo3Init, + dim2702Kuo3Init, + dim2703Kuo3Init, + dim2704Kuo3Init, + dim2705Kuo3Init, + dim2706Kuo3Init, + dim2707Kuo3Init, + dim2708Kuo3Init, + dim2709Kuo3Init, + dim2710Kuo3Init, + dim2711Kuo3Init, + dim2712Kuo3Init, + dim2713Kuo3Init, + dim2714Kuo3Init, + dim2715Kuo3Init, + dim2716Kuo3Init, + dim2717Kuo3Init, + dim2718Kuo3Init, + dim2719Kuo3Init, + dim2720Kuo3Init, + dim2721Kuo3Init, + dim2722Kuo3Init, + dim2723Kuo3Init, + dim2724Kuo3Init, + dim2725Kuo3Init, + dim2726Kuo3Init, + dim2727Kuo3Init, + dim2728Kuo3Init, + dim2729Kuo3Init, + dim2730Kuo3Init, + dim2731Kuo3Init, + dim2732Kuo3Init, + dim2733Kuo3Init, + dim2734Kuo3Init, + dim2735Kuo3Init, + dim2736Kuo3Init, + dim2737Kuo3Init, + dim2738Kuo3Init, + dim2739Kuo3Init, + dim2740Kuo3Init, + dim2741Kuo3Init, + dim2742Kuo3Init, + dim2743Kuo3Init, + dim2744Kuo3Init, + dim2745Kuo3Init, + dim2746Kuo3Init, + dim2747Kuo3Init, + dim2748Kuo3Init, + dim2749Kuo3Init, + dim2750Kuo3Init, + dim2751Kuo3Init, + dim2752Kuo3Init, + dim2753Kuo3Init, + dim2754Kuo3Init, + dim2755Kuo3Init, + dim2756Kuo3Init, + dim2757Kuo3Init, + dim2758Kuo3Init, + dim2759Kuo3Init, + dim2760Kuo3Init, + dim2761Kuo3Init, + dim2762Kuo3Init, + dim2763Kuo3Init, + dim2764Kuo3Init, + dim2765Kuo3Init, + dim2766Kuo3Init, + dim2767Kuo3Init, + dim2768Kuo3Init, + dim2769Kuo3Init, + dim2770Kuo3Init, + dim2771Kuo3Init, + dim2772Kuo3Init, + dim2773Kuo3Init, + dim2774Kuo3Init, + dim2775Kuo3Init, + dim2776Kuo3Init, + dim2777Kuo3Init, + dim2778Kuo3Init, + dim2779Kuo3Init, + dim2780Kuo3Init, + dim2781Kuo3Init, + dim2782Kuo3Init, + dim2783Kuo3Init, + dim2784Kuo3Init, + dim2785Kuo3Init, + dim2786Kuo3Init, + dim2787Kuo3Init, + dim2788Kuo3Init, + dim2789Kuo3Init, + dim2790Kuo3Init, + dim2791Kuo3Init, + dim2792Kuo3Init, + dim2793Kuo3Init, + dim2794Kuo3Init, + dim2795Kuo3Init, + dim2796Kuo3Init, + dim2797Kuo3Init, + dim2798Kuo3Init, + dim2799Kuo3Init, + dim2800Kuo3Init, + dim2801Kuo3Init, + dim2802Kuo3Init, + dim2803Kuo3Init, + dim2804Kuo3Init, + dim2805Kuo3Init, + dim2806Kuo3Init, + dim2807Kuo3Init, + dim2808Kuo3Init, + dim2809Kuo3Init, + dim2810Kuo3Init, + dim2811Kuo3Init, + dim2812Kuo3Init, + dim2813Kuo3Init, + dim2814Kuo3Init, + dim2815Kuo3Init, + dim2816Kuo3Init, + dim2817Kuo3Init, + dim2818Kuo3Init, + dim2819Kuo3Init, + dim2820Kuo3Init, + dim2821Kuo3Init, + dim2822Kuo3Init, + dim2823Kuo3Init, + dim2824Kuo3Init, + dim2825Kuo3Init, + dim2826Kuo3Init, + dim2827Kuo3Init, + dim2828Kuo3Init, + dim2829Kuo3Init, + dim2830Kuo3Init, + dim2831Kuo3Init, + dim2832Kuo3Init, + dim2833Kuo3Init, + dim2834Kuo3Init, + dim2835Kuo3Init, + dim2836Kuo3Init, + dim2837Kuo3Init, + dim2838Kuo3Init, + dim2839Kuo3Init, + dim2840Kuo3Init, + dim2841Kuo3Init, + dim2842Kuo3Init, + dim2843Kuo3Init, + dim2844Kuo3Init, + dim2845Kuo3Init, + dim2846Kuo3Init, + dim2847Kuo3Init, + dim2848Kuo3Init, + dim2849Kuo3Init, + dim2850Kuo3Init, + dim2851Kuo3Init, + dim2852Kuo3Init, + dim2853Kuo3Init, + dim2854Kuo3Init, + dim2855Kuo3Init, + dim2856Kuo3Init, + dim2857Kuo3Init, + dim2858Kuo3Init, + dim2859Kuo3Init, + dim2860Kuo3Init, + dim2861Kuo3Init, + dim2862Kuo3Init, + dim2863Kuo3Init, + dim2864Kuo3Init, + dim2865Kuo3Init, + dim2866Kuo3Init, + dim2867Kuo3Init, + dim2868Kuo3Init, + dim2869Kuo3Init, + dim2870Kuo3Init, + dim2871Kuo3Init, + dim2872Kuo3Init, + dim2873Kuo3Init, + dim2874Kuo3Init, + dim2875Kuo3Init, + dim2876Kuo3Init, + dim2877Kuo3Init, + dim2878Kuo3Init, + dim2879Kuo3Init, + dim2880Kuo3Init, + dim2881Kuo3Init, + dim2882Kuo3Init, + dim2883Kuo3Init, + dim2884Kuo3Init, + dim2885Kuo3Init, + dim2886Kuo3Init, + dim2887Kuo3Init, + dim2888Kuo3Init, + dim2889Kuo3Init, + dim2890Kuo3Init, + dim2891Kuo3Init, + dim2892Kuo3Init, + dim2893Kuo3Init, + dim2894Kuo3Init, + dim2895Kuo3Init, + dim2896Kuo3Init, + dim2897Kuo3Init, + dim2898Kuo3Init, + dim2899Kuo3Init, + dim2900Kuo3Init, + dim2901Kuo3Init, + dim2902Kuo3Init, + dim2903Kuo3Init, + dim2904Kuo3Init, + dim2905Kuo3Init, + dim2906Kuo3Init, + dim2907Kuo3Init, + dim2908Kuo3Init, + dim2909Kuo3Init, + dim2910Kuo3Init, + dim2911Kuo3Init, + dim2912Kuo3Init, + dim2913Kuo3Init, + dim2914Kuo3Init, + dim2915Kuo3Init, + dim2916Kuo3Init, + dim2917Kuo3Init, + dim2918Kuo3Init, + dim2919Kuo3Init, + dim2920Kuo3Init, + dim2921Kuo3Init, + dim2922Kuo3Init, + dim2923Kuo3Init, + dim2924Kuo3Init, + dim2925Kuo3Init, + dim2926Kuo3Init, + dim2927Kuo3Init, + dim2928Kuo3Init, + dim2929Kuo3Init, + dim2930Kuo3Init, + dim2931Kuo3Init, + dim2932Kuo3Init, + dim2933Kuo3Init, + dim2934Kuo3Init, + dim2935Kuo3Init, + dim2936Kuo3Init, + dim2937Kuo3Init, + dim2938Kuo3Init, + dim2939Kuo3Init, + dim2940Kuo3Init, + dim2941Kuo3Init, + dim2942Kuo3Init, + dim2943Kuo3Init, + dim2944Kuo3Init, + dim2945Kuo3Init, + dim2946Kuo3Init, + dim2947Kuo3Init, + dim2948Kuo3Init, + dim2949Kuo3Init, + dim2950Kuo3Init, + dim2951Kuo3Init, + dim2952Kuo3Init, + dim2953Kuo3Init, + dim2954Kuo3Init, + dim2955Kuo3Init, + dim2956Kuo3Init, + dim2957Kuo3Init, + dim2958Kuo3Init, + dim2959Kuo3Init, + dim2960Kuo3Init, + dim2961Kuo3Init, + dim2962Kuo3Init, + dim2963Kuo3Init, + dim2964Kuo3Init, + dim2965Kuo3Init, + dim2966Kuo3Init, + dim2967Kuo3Init, + dim2968Kuo3Init, + dim2969Kuo3Init, + dim2970Kuo3Init, + dim2971Kuo3Init, + dim2972Kuo3Init, + dim2973Kuo3Init, + dim2974Kuo3Init, + dim2975Kuo3Init, + dim2976Kuo3Init, + dim2977Kuo3Init, + dim2978Kuo3Init, + dim2979Kuo3Init, + dim2980Kuo3Init, + dim2981Kuo3Init, + dim2982Kuo3Init, + dim2983Kuo3Init, + dim2984Kuo3Init, + dim2985Kuo3Init, + dim2986Kuo3Init, + dim2987Kuo3Init, + dim2988Kuo3Init, + dim2989Kuo3Init, + dim2990Kuo3Init, + dim2991Kuo3Init, + dim2992Kuo3Init, + dim2993Kuo3Init, + dim2994Kuo3Init, + dim2995Kuo3Init, + dim2996Kuo3Init, + dim2997Kuo3Init, + dim2998Kuo3Init, + dim2999Kuo3Init, + dim3000Kuo3Init, + dim3001Kuo3Init, + dim3002Kuo3Init, + dim3003Kuo3Init, + dim3004Kuo3Init, + dim3005Kuo3Init, + dim3006Kuo3Init, + dim3007Kuo3Init, + dim3008Kuo3Init, + dim3009Kuo3Init, + dim3010Kuo3Init, + dim3011Kuo3Init, + dim3012Kuo3Init, + dim3013Kuo3Init, + dim3014Kuo3Init, + dim3015Kuo3Init, + dim3016Kuo3Init, + dim3017Kuo3Init, + dim3018Kuo3Init, + dim3019Kuo3Init, + dim3020Kuo3Init, + dim3021Kuo3Init, + dim3022Kuo3Init, + dim3023Kuo3Init, + dim3024Kuo3Init, + dim3025Kuo3Init, + dim3026Kuo3Init, + dim3027Kuo3Init, + dim3028Kuo3Init, + dim3029Kuo3Init, + dim3030Kuo3Init, + dim3031Kuo3Init, + dim3032Kuo3Init, + dim3033Kuo3Init, + dim3034Kuo3Init, + dim3035Kuo3Init, + dim3036Kuo3Init, + dim3037Kuo3Init, + dim3038Kuo3Init, + dim3039Kuo3Init, + dim3040Kuo3Init, + dim3041Kuo3Init, + dim3042Kuo3Init, + dim3043Kuo3Init, + dim3044Kuo3Init, + dim3045Kuo3Init, + dim3046Kuo3Init, + dim3047Kuo3Init, + dim3048Kuo3Init, + dim3049Kuo3Init, + dim3050Kuo3Init, + dim3051Kuo3Init, + dim3052Kuo3Init, + dim3053Kuo3Init, + dim3054Kuo3Init, + dim3055Kuo3Init, + dim3056Kuo3Init, + dim3057Kuo3Init, + dim3058Kuo3Init, + dim3059Kuo3Init, + dim3060Kuo3Init, + dim3061Kuo3Init, + dim3062Kuo3Init, + dim3063Kuo3Init, + dim3064Kuo3Init, + dim3065Kuo3Init, + dim3066Kuo3Init, + dim3067Kuo3Init, + dim3068Kuo3Init, + dim3069Kuo3Init, + dim3070Kuo3Init, + dim3071Kuo3Init, + dim3072Kuo3Init, + dim3073Kuo3Init, + dim3074Kuo3Init, + dim3075Kuo3Init, + dim3076Kuo3Init, + dim3077Kuo3Init, + dim3078Kuo3Init, + dim3079Kuo3Init, + dim3080Kuo3Init, + dim3081Kuo3Init, + dim3082Kuo3Init, + dim3083Kuo3Init, + dim3084Kuo3Init, + dim3085Kuo3Init, + dim3086Kuo3Init, + dim3087Kuo3Init, + dim3088Kuo3Init, + dim3089Kuo3Init, + dim3090Kuo3Init, + dim3091Kuo3Init, + dim3092Kuo3Init, + dim3093Kuo3Init, + dim3094Kuo3Init, + dim3095Kuo3Init, + dim3096Kuo3Init, + dim3097Kuo3Init, + dim3098Kuo3Init, + dim3099Kuo3Init, + dim3100Kuo3Init, + dim3101Kuo3Init, + dim3102Kuo3Init, + dim3103Kuo3Init, + dim3104Kuo3Init, + dim3105Kuo3Init, + dim3106Kuo3Init, + dim3107Kuo3Init, + dim3108Kuo3Init, + dim3109Kuo3Init, + dim3110Kuo3Init, + dim3111Kuo3Init, + dim3112Kuo3Init, + dim3113Kuo3Init, + dim3114Kuo3Init, + dim3115Kuo3Init, + dim3116Kuo3Init, + dim3117Kuo3Init, + dim3118Kuo3Init, + dim3119Kuo3Init, + dim3120Kuo3Init, + dim3121Kuo3Init, + dim3122Kuo3Init, + dim3123Kuo3Init, + dim3124Kuo3Init, + dim3125Kuo3Init, + dim3126Kuo3Init, + dim3127Kuo3Init, + dim3128Kuo3Init, + dim3129Kuo3Init, + dim3130Kuo3Init, + dim3131Kuo3Init, + dim3132Kuo3Init, + dim3133Kuo3Init, + dim3134Kuo3Init, + dim3135Kuo3Init, + dim3136Kuo3Init, + dim3137Kuo3Init, + dim3138Kuo3Init, + dim3139Kuo3Init, + dim3140Kuo3Init, + dim3141Kuo3Init, + dim3142Kuo3Init, + dim3143Kuo3Init, + dim3144Kuo3Init, + dim3145Kuo3Init, + dim3146Kuo3Init, + dim3147Kuo3Init, + dim3148Kuo3Init, + dim3149Kuo3Init, + dim3150Kuo3Init, + dim3151Kuo3Init, + dim3152Kuo3Init, + dim3153Kuo3Init, + dim3154Kuo3Init, + dim3155Kuo3Init, + dim3156Kuo3Init, + dim3157Kuo3Init, + dim3158Kuo3Init, + dim3159Kuo3Init, + dim3160Kuo3Init, + dim3161Kuo3Init, + dim3162Kuo3Init, + dim3163Kuo3Init, + dim3164Kuo3Init, + dim3165Kuo3Init, + dim3166Kuo3Init, + dim3167Kuo3Init, + dim3168Kuo3Init, + dim3169Kuo3Init, + dim3170Kuo3Init, + dim3171Kuo3Init, + dim3172Kuo3Init, + dim3173Kuo3Init, + dim3174Kuo3Init, + dim3175Kuo3Init, + dim3176Kuo3Init, + dim3177Kuo3Init, + dim3178Kuo3Init, + dim3179Kuo3Init, + dim3180Kuo3Init, + dim3181Kuo3Init, + dim3182Kuo3Init, + dim3183Kuo3Init, + dim3184Kuo3Init, + dim3185Kuo3Init, + dim3186Kuo3Init, + dim3187Kuo3Init, + dim3188Kuo3Init, + dim3189Kuo3Init, + dim3190Kuo3Init, + dim3191Kuo3Init, + dim3192Kuo3Init, + dim3193Kuo3Init, + dim3194Kuo3Init, + dim3195Kuo3Init, + dim3196Kuo3Init, + dim3197Kuo3Init, + dim3198Kuo3Init, + dim3199Kuo3Init, + dim3200Kuo3Init, + dim3201Kuo3Init, + dim3202Kuo3Init, + dim3203Kuo3Init, + dim3204Kuo3Init, + dim3205Kuo3Init, + dim3206Kuo3Init, + dim3207Kuo3Init, + dim3208Kuo3Init, + dim3209Kuo3Init, + dim3210Kuo3Init, + dim3211Kuo3Init, + dim3212Kuo3Init, + dim3213Kuo3Init, + dim3214Kuo3Init, + dim3215Kuo3Init, + dim3216Kuo3Init, + dim3217Kuo3Init, + dim3218Kuo3Init, + dim3219Kuo3Init, + dim3220Kuo3Init, + dim3221Kuo3Init, + dim3222Kuo3Init, + dim3223Kuo3Init, + dim3224Kuo3Init, + dim3225Kuo3Init, + dim3226Kuo3Init, + dim3227Kuo3Init, + dim3228Kuo3Init, + dim3229Kuo3Init, + dim3230Kuo3Init, + dim3231Kuo3Init, + dim3232Kuo3Init, + dim3233Kuo3Init, + dim3234Kuo3Init, + dim3235Kuo3Init, + dim3236Kuo3Init, + dim3237Kuo3Init, + dim3238Kuo3Init, + dim3239Kuo3Init, + dim3240Kuo3Init, + dim3241Kuo3Init, + dim3242Kuo3Init, + dim3243Kuo3Init, + dim3244Kuo3Init, + dim3245Kuo3Init, + dim3246Kuo3Init, + dim3247Kuo3Init, + dim3248Kuo3Init, + dim3249Kuo3Init, + dim3250Kuo3Init, + dim3251Kuo3Init, + dim3252Kuo3Init, + dim3253Kuo3Init, + dim3254Kuo3Init, + dim3255Kuo3Init, + dim3256Kuo3Init, + dim3257Kuo3Init, + dim3258Kuo3Init, + dim3259Kuo3Init, + dim3260Kuo3Init, + dim3261Kuo3Init, + dim3262Kuo3Init, + dim3263Kuo3Init, + dim3264Kuo3Init, + dim3265Kuo3Init, + dim3266Kuo3Init, + dim3267Kuo3Init, + dim3268Kuo3Init, + dim3269Kuo3Init, + dim3270Kuo3Init, + dim3271Kuo3Init, + dim3272Kuo3Init, + dim3273Kuo3Init, + dim3274Kuo3Init, + dim3275Kuo3Init, + dim3276Kuo3Init, + dim3277Kuo3Init, + dim3278Kuo3Init, + dim3279Kuo3Init, + dim3280Kuo3Init, + dim3281Kuo3Init, + dim3282Kuo3Init, + dim3283Kuo3Init, + dim3284Kuo3Init, + dim3285Kuo3Init, + dim3286Kuo3Init, + dim3287Kuo3Init, + dim3288Kuo3Init, + dim3289Kuo3Init, + dim3290Kuo3Init, + dim3291Kuo3Init, + dim3292Kuo3Init, + dim3293Kuo3Init, + dim3294Kuo3Init, + dim3295Kuo3Init, + dim3296Kuo3Init, + dim3297Kuo3Init, + dim3298Kuo3Init, + dim3299Kuo3Init, + dim3300Kuo3Init, + dim3301Kuo3Init, + dim3302Kuo3Init, + dim3303Kuo3Init, + dim3304Kuo3Init, + dim3305Kuo3Init, + dim3306Kuo3Init, + dim3307Kuo3Init, + dim3308Kuo3Init, + dim3309Kuo3Init, + dim3310Kuo3Init, + dim3311Kuo3Init, + dim3312Kuo3Init, + dim3313Kuo3Init, + dim3314Kuo3Init, + dim3315Kuo3Init, + dim3316Kuo3Init, + dim3317Kuo3Init, + dim3318Kuo3Init, + dim3319Kuo3Init, + dim3320Kuo3Init, + dim3321Kuo3Init, + dim3322Kuo3Init, + dim3323Kuo3Init, + dim3324Kuo3Init, + dim3325Kuo3Init, + dim3326Kuo3Init, + dim3327Kuo3Init, + dim3328Kuo3Init, + dim3329Kuo3Init, + dim3330Kuo3Init, + dim3331Kuo3Init, + dim3332Kuo3Init, + dim3333Kuo3Init, + dim3334Kuo3Init, + dim3335Kuo3Init, + dim3336Kuo3Init, + dim3337Kuo3Init, + dim3338Kuo3Init, + dim3339Kuo3Init, + dim3340Kuo3Init, + dim3341Kuo3Init, + dim3342Kuo3Init, + dim3343Kuo3Init, + dim3344Kuo3Init, + dim3345Kuo3Init, + dim3346Kuo3Init, + dim3347Kuo3Init, + dim3348Kuo3Init, + dim3349Kuo3Init, + dim3350Kuo3Init, + dim3351Kuo3Init, + dim3352Kuo3Init, + dim3353Kuo3Init, + dim3354Kuo3Init, + dim3355Kuo3Init, + dim3356Kuo3Init, + dim3357Kuo3Init, + dim3358Kuo3Init, + dim3359Kuo3Init, + dim3360Kuo3Init, + dim3361Kuo3Init, + dim3362Kuo3Init, + dim3363Kuo3Init, + dim3364Kuo3Init, + dim3365Kuo3Init, + dim3366Kuo3Init, + dim3367Kuo3Init, + dim3368Kuo3Init, + dim3369Kuo3Init, + dim3370Kuo3Init, + dim3371Kuo3Init, + dim3372Kuo3Init, + dim3373Kuo3Init, + dim3374Kuo3Init, + dim3375Kuo3Init, + dim3376Kuo3Init, + dim3377Kuo3Init, + dim3378Kuo3Init, + dim3379Kuo3Init, + dim3380Kuo3Init, + dim3381Kuo3Init, + dim3382Kuo3Init, + dim3383Kuo3Init, + dim3384Kuo3Init, + dim3385Kuo3Init, + dim3386Kuo3Init, + dim3387Kuo3Init, + dim3388Kuo3Init, + dim3389Kuo3Init, + dim3390Kuo3Init, + dim3391Kuo3Init, + dim3392Kuo3Init, + dim3393Kuo3Init, + dim3394Kuo3Init, + dim3395Kuo3Init, + dim3396Kuo3Init, + dim3397Kuo3Init, + dim3398Kuo3Init, + dim3399Kuo3Init, + dim3400Kuo3Init, + dim3401Kuo3Init, + dim3402Kuo3Init, + dim3403Kuo3Init, + dim3404Kuo3Init, + dim3405Kuo3Init, + dim3406Kuo3Init, + dim3407Kuo3Init, + dim3408Kuo3Init, + dim3409Kuo3Init, + dim3410Kuo3Init, + dim3411Kuo3Init, + dim3412Kuo3Init, + dim3413Kuo3Init, + dim3414Kuo3Init, + dim3415Kuo3Init, + dim3416Kuo3Init, + dim3417Kuo3Init, + dim3418Kuo3Init, + dim3419Kuo3Init, + dim3420Kuo3Init, + dim3421Kuo3Init, + dim3422Kuo3Init, + dim3423Kuo3Init, + dim3424Kuo3Init, + dim3425Kuo3Init, + dim3426Kuo3Init, + dim3427Kuo3Init, + dim3428Kuo3Init, + dim3429Kuo3Init, + dim3430Kuo3Init, + dim3431Kuo3Init, + dim3432Kuo3Init, + dim3433Kuo3Init, + dim3434Kuo3Init, + dim3435Kuo3Init, + dim3436Kuo3Init, + dim3437Kuo3Init, + dim3438Kuo3Init, + dim3439Kuo3Init, + dim3440Kuo3Init, + dim3441Kuo3Init, + dim3442Kuo3Init, + dim3443Kuo3Init, + dim3444Kuo3Init, + dim3445Kuo3Init, + dim3446Kuo3Init, + dim3447Kuo3Init, + dim3448Kuo3Init, + dim3449Kuo3Init, + dim3450Kuo3Init, + dim3451Kuo3Init, + dim3452Kuo3Init, + dim3453Kuo3Init, + dim3454Kuo3Init, + dim3455Kuo3Init, + dim3456Kuo3Init, + dim3457Kuo3Init, + dim3458Kuo3Init, + dim3459Kuo3Init, + dim3460Kuo3Init, + dim3461Kuo3Init, + dim3462Kuo3Init, + dim3463Kuo3Init, + dim3464Kuo3Init, + dim3465Kuo3Init, + dim3466Kuo3Init, + dim3467Kuo3Init, + dim3468Kuo3Init, + dim3469Kuo3Init, + dim3470Kuo3Init, + dim3471Kuo3Init, + dim3472Kuo3Init, + dim3473Kuo3Init, + dim3474Kuo3Init, + dim3475Kuo3Init, + dim3476Kuo3Init, + dim3477Kuo3Init, + dim3478Kuo3Init, + dim3479Kuo3Init, + dim3480Kuo3Init, + dim3481Kuo3Init, + dim3482Kuo3Init, + dim3483Kuo3Init, + dim3484Kuo3Init, + dim3485Kuo3Init, + dim3486Kuo3Init, + dim3487Kuo3Init, + dim3488Kuo3Init, + dim3489Kuo3Init, + dim3490Kuo3Init, + dim3491Kuo3Init, + dim3492Kuo3Init, + dim3493Kuo3Init, + dim3494Kuo3Init, + dim3495Kuo3Init, + dim3496Kuo3Init, + dim3497Kuo3Init, + dim3498Kuo3Init, + dim3499Kuo3Init, + dim3500Kuo3Init, + dim3501Kuo3Init, + dim3502Kuo3Init, + dim3503Kuo3Init, + dim3504Kuo3Init, + dim3505Kuo3Init, + dim3506Kuo3Init, + dim3507Kuo3Init, + dim3508Kuo3Init, + dim3509Kuo3Init, + dim3510Kuo3Init, + dim3511Kuo3Init, + dim3512Kuo3Init, + dim3513Kuo3Init, + dim3514Kuo3Init, + dim3515Kuo3Init, + dim3516Kuo3Init, + dim3517Kuo3Init, + dim3518Kuo3Init, + dim3519Kuo3Init, + dim3520Kuo3Init, + dim3521Kuo3Init, + dim3522Kuo3Init, + dim3523Kuo3Init, + dim3524Kuo3Init, + dim3525Kuo3Init, + dim3526Kuo3Init, + dim3527Kuo3Init, + dim3528Kuo3Init, + dim3529Kuo3Init, + dim3530Kuo3Init, + dim3531Kuo3Init, + dim3532Kuo3Init, + dim3533Kuo3Init, + dim3534Kuo3Init, + dim3535Kuo3Init, + dim3536Kuo3Init, + dim3537Kuo3Init, + dim3538Kuo3Init, + dim3539Kuo3Init, + dim3540Kuo3Init, + dim3541Kuo3Init, + dim3542Kuo3Init, + dim3543Kuo3Init, + dim3544Kuo3Init, + dim3545Kuo3Init, + dim3546Kuo3Init, + dim3547Kuo3Init, + dim3548Kuo3Init, + dim3549Kuo3Init, + dim3550Kuo3Init, + dim3551Kuo3Init, + dim3552Kuo3Init, + dim3553Kuo3Init, + dim3554Kuo3Init, + dim3555Kuo3Init, + dim3556Kuo3Init, + dim3557Kuo3Init, + dim3558Kuo3Init, + dim3559Kuo3Init, + dim3560Kuo3Init, + dim3561Kuo3Init, + dim3562Kuo3Init, + dim3563Kuo3Init, + dim3564Kuo3Init, + dim3565Kuo3Init, + dim3566Kuo3Init, + dim3567Kuo3Init, + dim3568Kuo3Init, + dim3569Kuo3Init, + dim3570Kuo3Init, + dim3571Kuo3Init, + dim3572Kuo3Init, + dim3573Kuo3Init, + dim3574Kuo3Init, + dim3575Kuo3Init, + dim3576Kuo3Init, + dim3577Kuo3Init, + dim3578Kuo3Init, + dim3579Kuo3Init, + dim3580Kuo3Init, + dim3581Kuo3Init, + dim3582Kuo3Init, + dim3583Kuo3Init, + dim3584Kuo3Init, + dim3585Kuo3Init, + dim3586Kuo3Init, + dim3587Kuo3Init, + dim3588Kuo3Init, + dim3589Kuo3Init, + dim3590Kuo3Init, + dim3591Kuo3Init, + dim3592Kuo3Init, + dim3593Kuo3Init, + dim3594Kuo3Init, + dim3595Kuo3Init, + dim3596Kuo3Init, + dim3597Kuo3Init, + dim3598Kuo3Init, + dim3599Kuo3Init, + dim3600Kuo3Init, + dim3601Kuo3Init, + dim3602Kuo3Init, + dim3603Kuo3Init, + dim3604Kuo3Init, + dim3605Kuo3Init, + dim3606Kuo3Init, + dim3607Kuo3Init, + dim3608Kuo3Init, + dim3609Kuo3Init, + dim3610Kuo3Init, + dim3611Kuo3Init, + dim3612Kuo3Init, + dim3613Kuo3Init, + dim3614Kuo3Init, + dim3615Kuo3Init, + dim3616Kuo3Init, + dim3617Kuo3Init, + dim3618Kuo3Init, + dim3619Kuo3Init, + dim3620Kuo3Init, + dim3621Kuo3Init, + dim3622Kuo3Init, + dim3623Kuo3Init, + dim3624Kuo3Init, + dim3625Kuo3Init, + dim3626Kuo3Init, + dim3627Kuo3Init, + dim3628Kuo3Init, + dim3629Kuo3Init, + dim3630Kuo3Init, + dim3631Kuo3Init, + dim3632Kuo3Init, + dim3633Kuo3Init, + dim3634Kuo3Init, + dim3635Kuo3Init, + dim3636Kuo3Init, + dim3637Kuo3Init, + dim3638Kuo3Init, + dim3639Kuo3Init, + dim3640Kuo3Init, + dim3641Kuo3Init, + dim3642Kuo3Init, + dim3643Kuo3Init, + dim3644Kuo3Init, + dim3645Kuo3Init, + dim3646Kuo3Init, + dim3647Kuo3Init, + dim3648Kuo3Init, + dim3649Kuo3Init, + dim3650Kuo3Init, + dim3651Kuo3Init, + dim3652Kuo3Init, + dim3653Kuo3Init, + dim3654Kuo3Init, + dim3655Kuo3Init, + dim3656Kuo3Init, + dim3657Kuo3Init, + dim3658Kuo3Init, + dim3659Kuo3Init, + dim3660Kuo3Init, + dim3661Kuo3Init, + dim3662Kuo3Init, + dim3663Kuo3Init, + dim3664Kuo3Init, + dim3665Kuo3Init, + dim3666Kuo3Init, + dim3667Kuo3Init, + dim3668Kuo3Init, + dim3669Kuo3Init, + dim3670Kuo3Init, + dim3671Kuo3Init, + dim3672Kuo3Init, + dim3673Kuo3Init, + dim3674Kuo3Init, + dim3675Kuo3Init, + dim3676Kuo3Init, + dim3677Kuo3Init, + dim3678Kuo3Init, + dim3679Kuo3Init, + dim3680Kuo3Init, + dim3681Kuo3Init, + dim3682Kuo3Init, + dim3683Kuo3Init, + dim3684Kuo3Init, + dim3685Kuo3Init, + dim3686Kuo3Init, + dim3687Kuo3Init, + dim3688Kuo3Init, + dim3689Kuo3Init, + dim3690Kuo3Init, + dim3691Kuo3Init, + dim3692Kuo3Init, + dim3693Kuo3Init, + dim3694Kuo3Init, + dim3695Kuo3Init, + dim3696Kuo3Init, + dim3697Kuo3Init, + dim3698Kuo3Init, + dim3699Kuo3Init, + dim3700Kuo3Init, + dim3701Kuo3Init, + dim3702Kuo3Init, + dim3703Kuo3Init, + dim3704Kuo3Init, + dim3705Kuo3Init, + dim3706Kuo3Init, + dim3707Kuo3Init, + dim3708Kuo3Init, + dim3709Kuo3Init, + dim3710Kuo3Init, + dim3711Kuo3Init, + dim3712Kuo3Init, + dim3713Kuo3Init, + dim3714Kuo3Init, + dim3715Kuo3Init, + dim3716Kuo3Init, + dim3717Kuo3Init, + dim3718Kuo3Init, + dim3719Kuo3Init, + dim3720Kuo3Init, + dim3721Kuo3Init, + dim3722Kuo3Init, + dim3723Kuo3Init, + dim3724Kuo3Init, + dim3725Kuo3Init, + dim3726Kuo3Init, + dim3727Kuo3Init, + dim3728Kuo3Init, + dim3729Kuo3Init, + dim3730Kuo3Init, + dim3731Kuo3Init, + dim3732Kuo3Init, + dim3733Kuo3Init, + dim3734Kuo3Init, + dim3735Kuo3Init, + dim3736Kuo3Init, + dim3737Kuo3Init, + dim3738Kuo3Init, + dim3739Kuo3Init, + dim3740Kuo3Init, + dim3741Kuo3Init, + dim3742Kuo3Init, + dim3743Kuo3Init, + dim3744Kuo3Init, + dim3745Kuo3Init, + dim3746Kuo3Init, + dim3747Kuo3Init, + dim3748Kuo3Init, + dim3749Kuo3Init, + dim3750Kuo3Init, + dim3751Kuo3Init, + dim3752Kuo3Init, + dim3753Kuo3Init, + dim3754Kuo3Init, + dim3755Kuo3Init, + dim3756Kuo3Init, + dim3757Kuo3Init, + dim3758Kuo3Init, + dim3759Kuo3Init, + dim3760Kuo3Init, + dim3761Kuo3Init, + dim3762Kuo3Init, + dim3763Kuo3Init, + dim3764Kuo3Init, + dim3765Kuo3Init, + dim3766Kuo3Init, + dim3767Kuo3Init, + dim3768Kuo3Init, + dim3769Kuo3Init, + dim3770Kuo3Init, + dim3771Kuo3Init, + dim3772Kuo3Init, + dim3773Kuo3Init, + dim3774Kuo3Init, + dim3775Kuo3Init, + dim3776Kuo3Init, + dim3777Kuo3Init, + dim3778Kuo3Init, + dim3779Kuo3Init, + dim3780Kuo3Init, + dim3781Kuo3Init, + dim3782Kuo3Init, + dim3783Kuo3Init, + dim3784Kuo3Init, + dim3785Kuo3Init, + dim3786Kuo3Init, + dim3787Kuo3Init, + dim3788Kuo3Init, + dim3789Kuo3Init, + dim3790Kuo3Init, + dim3791Kuo3Init, + dim3792Kuo3Init, + dim3793Kuo3Init, + dim3794Kuo3Init, + dim3795Kuo3Init, + dim3796Kuo3Init, + dim3797Kuo3Init, + dim3798Kuo3Init, + dim3799Kuo3Init, + dim3800Kuo3Init, + dim3801Kuo3Init, + dim3802Kuo3Init, + dim3803Kuo3Init, + dim3804Kuo3Init, + dim3805Kuo3Init, + dim3806Kuo3Init, + dim3807Kuo3Init, + dim3808Kuo3Init, + dim3809Kuo3Init, + dim3810Kuo3Init, + dim3811Kuo3Init, + dim3812Kuo3Init, + dim3813Kuo3Init, + dim3814Kuo3Init, + dim3815Kuo3Init, + dim3816Kuo3Init, + dim3817Kuo3Init, + dim3818Kuo3Init, + dim3819Kuo3Init, + dim3820Kuo3Init, + dim3821Kuo3Init, + dim3822Kuo3Init, + dim3823Kuo3Init, + dim3824Kuo3Init, + dim3825Kuo3Init, + dim3826Kuo3Init, + dim3827Kuo3Init, + dim3828Kuo3Init, + dim3829Kuo3Init, + dim3830Kuo3Init, + dim3831Kuo3Init, + dim3832Kuo3Init, + dim3833Kuo3Init, + dim3834Kuo3Init, + dim3835Kuo3Init, + dim3836Kuo3Init, + dim3837Kuo3Init, + dim3838Kuo3Init, + dim3839Kuo3Init, + dim3840Kuo3Init, + dim3841Kuo3Init, + dim3842Kuo3Init, + dim3843Kuo3Init, + dim3844Kuo3Init, + dim3845Kuo3Init, + dim3846Kuo3Init, + dim3847Kuo3Init, + dim3848Kuo3Init, + dim3849Kuo3Init, + dim3850Kuo3Init, + dim3851Kuo3Init, + dim3852Kuo3Init, + dim3853Kuo3Init, + dim3854Kuo3Init, + dim3855Kuo3Init, + dim3856Kuo3Init, + dim3857Kuo3Init, + dim3858Kuo3Init, + dim3859Kuo3Init, + dim3860Kuo3Init, + dim3861Kuo3Init, + dim3862Kuo3Init, + dim3863Kuo3Init, + dim3864Kuo3Init, + dim3865Kuo3Init, + dim3866Kuo3Init, + dim3867Kuo3Init, + dim3868Kuo3Init, + dim3869Kuo3Init, + dim3870Kuo3Init, + dim3871Kuo3Init, + dim3872Kuo3Init, + dim3873Kuo3Init, + dim3874Kuo3Init, + dim3875Kuo3Init, + dim3876Kuo3Init, + dim3877Kuo3Init, + dim3878Kuo3Init, + dim3879Kuo3Init, + dim3880Kuo3Init, + dim3881Kuo3Init, + dim3882Kuo3Init, + dim3883Kuo3Init, + dim3884Kuo3Init, + dim3885Kuo3Init, + dim3886Kuo3Init, + dim3887Kuo3Init, + dim3888Kuo3Init, + dim3889Kuo3Init, + dim3890Kuo3Init, + dim3891Kuo3Init, + dim3892Kuo3Init, + dim3893Kuo3Init, + dim3894Kuo3Init, + dim3895Kuo3Init, + dim3896Kuo3Init, + dim3897Kuo3Init, + dim3898Kuo3Init, + dim3899Kuo3Init, + dim3900Kuo3Init, + dim3901Kuo3Init, + dim3902Kuo3Init, + dim3903Kuo3Init, + dim3904Kuo3Init, + dim3905Kuo3Init, + dim3906Kuo3Init, + dim3907Kuo3Init, + dim3908Kuo3Init, + dim3909Kuo3Init, + dim3910Kuo3Init, + dim3911Kuo3Init, + dim3912Kuo3Init, + dim3913Kuo3Init, + dim3914Kuo3Init, + dim3915Kuo3Init, + dim3916Kuo3Init, + dim3917Kuo3Init, + dim3918Kuo3Init, + dim3919Kuo3Init, + dim3920Kuo3Init, + dim3921Kuo3Init, + dim3922Kuo3Init, + dim3923Kuo3Init, + dim3924Kuo3Init, + dim3925Kuo3Init, + dim3926Kuo3Init, + dim3927Kuo3Init, + dim3928Kuo3Init, + dim3929Kuo3Init, + dim3930Kuo3Init, + dim3931Kuo3Init, + dim3932Kuo3Init, + dim3933Kuo3Init, + dim3934Kuo3Init, + dim3935Kuo3Init, + dim3936Kuo3Init, + dim3937Kuo3Init, + dim3938Kuo3Init, + dim3939Kuo3Init, + dim3940Kuo3Init, + dim3941Kuo3Init, + dim3942Kuo3Init, + dim3943Kuo3Init, + dim3944Kuo3Init, + dim3945Kuo3Init, + dim3946Kuo3Init, + dim3947Kuo3Init, + dim3948Kuo3Init, + dim3949Kuo3Init, + dim3950Kuo3Init, + dim3951Kuo3Init, + dim3952Kuo3Init, + dim3953Kuo3Init, + dim3954Kuo3Init, + dim3955Kuo3Init, + dim3956Kuo3Init, + dim3957Kuo3Init, + dim3958Kuo3Init, + dim3959Kuo3Init, + dim3960Kuo3Init, + dim3961Kuo3Init, + dim3962Kuo3Init, + dim3963Kuo3Init, + dim3964Kuo3Init, + dim3965Kuo3Init, + dim3966Kuo3Init, + dim3967Kuo3Init, + dim3968Kuo3Init, + dim3969Kuo3Init, + dim3970Kuo3Init, + dim3971Kuo3Init, + dim3972Kuo3Init, + dim3973Kuo3Init, + dim3974Kuo3Init, + dim3975Kuo3Init, + dim3976Kuo3Init, + dim3977Kuo3Init, + dim3978Kuo3Init, + dim3979Kuo3Init, + dim3980Kuo3Init, + dim3981Kuo3Init, + dim3982Kuo3Init, + dim3983Kuo3Init, + dim3984Kuo3Init, + dim3985Kuo3Init, + dim3986Kuo3Init, + dim3987Kuo3Init, + dim3988Kuo3Init, + dim3989Kuo3Init, + dim3990Kuo3Init, + dim3991Kuo3Init, + dim3992Kuo3Init, + dim3993Kuo3Init, + dim3994Kuo3Init, + dim3995Kuo3Init, + dim3996Kuo3Init, + dim3997Kuo3Init, + dim3998Kuo3Init, + dim3999Kuo3Init, + dim4000Kuo3Init, + dim4001Kuo3Init, + dim4002Kuo3Init, + dim4003Kuo3Init, + dim4004Kuo3Init, + dim4005Kuo3Init, + dim4006Kuo3Init, + dim4007Kuo3Init, + dim4008Kuo3Init, + dim4009Kuo3Init, + dim4010Kuo3Init, + dim4011Kuo3Init, + dim4012Kuo3Init, + dim4013Kuo3Init, + dim4014Kuo3Init, + dim4015Kuo3Init, + dim4016Kuo3Init, + dim4017Kuo3Init, + dim4018Kuo3Init, + dim4019Kuo3Init, + dim4020Kuo3Init, + dim4021Kuo3Init, + dim4022Kuo3Init, + dim4023Kuo3Init, + dim4024Kuo3Init, + dim4025Kuo3Init, + dim4026Kuo3Init, + dim4027Kuo3Init, + dim4028Kuo3Init, + dim4029Kuo3Init, + dim4030Kuo3Init, + dim4031Kuo3Init, + dim4032Kuo3Init, + dim4033Kuo3Init, + dim4034Kuo3Init, + dim4035Kuo3Init, + dim4036Kuo3Init, + dim4037Kuo3Init, + dim4038Kuo3Init, + dim4039Kuo3Init, + dim4040Kuo3Init, + dim4041Kuo3Init, + dim4042Kuo3Init, + dim4043Kuo3Init, + dim4044Kuo3Init, + dim4045Kuo3Init, + dim4046Kuo3Init, + dim4047Kuo3Init, + dim4048Kuo3Init, + dim4049Kuo3Init, + dim4050Kuo3Init, + dim4051Kuo3Init, + dim4052Kuo3Init, + dim4053Kuo3Init, + dim4054Kuo3Init, + dim4055Kuo3Init, + dim4056Kuo3Init, + dim4057Kuo3Init, + dim4058Kuo3Init, + dim4059Kuo3Init, + dim4060Kuo3Init, + dim4061Kuo3Init, + dim4062Kuo3Init, + dim4063Kuo3Init, + dim4064Kuo3Init, + dim4065Kuo3Init, + dim4066Kuo3Init, + dim4067Kuo3Init, + dim4068Kuo3Init, + dim4069Kuo3Init, + dim4070Kuo3Init, + dim4071Kuo3Init, + dim4072Kuo3Init, + dim4073Kuo3Init, + dim4074Kuo3Init, + dim4075Kuo3Init, + dim4076Kuo3Init, + dim4077Kuo3Init, + dim4078Kuo3Init, + dim4079Kuo3Init, + dim4080Kuo3Init, + dim4081Kuo3Init, + dim4082Kuo3Init, + dim4083Kuo3Init, + dim4084Kuo3Init, + dim4085Kuo3Init, + dim4086Kuo3Init, + dim4087Kuo3Init, + dim4088Kuo3Init, + dim4089Kuo3Init, + dim4090Kuo3Init, + dim4091Kuo3Init, + dim4092Kuo3Init, + dim4093Kuo3Init, + dim4094Kuo3Init, + dim4095Kuo3Init, + dim4096Kuo3Init, + dim4097Kuo3Init, + dim4098Kuo3Init, + dim4099Kuo3Init, + dim4100Kuo3Init, + dim4101Kuo3Init, + dim4102Kuo3Init, + dim4103Kuo3Init, + dim4104Kuo3Init, + dim4105Kuo3Init, + dim4106Kuo3Init, + dim4107Kuo3Init, + dim4108Kuo3Init, + dim4109Kuo3Init, + dim4110Kuo3Init, + dim4111Kuo3Init, + dim4112Kuo3Init, + dim4113Kuo3Init, + dim4114Kuo3Init, + dim4115Kuo3Init, + dim4116Kuo3Init, + dim4117Kuo3Init, + dim4118Kuo3Init, + dim4119Kuo3Init, + dim4120Kuo3Init, + dim4121Kuo3Init, + dim4122Kuo3Init, + dim4123Kuo3Init, + dim4124Kuo3Init, + dim4125Kuo3Init, + dim4126Kuo3Init, + dim4127Kuo3Init, + dim4128Kuo3Init, + dim4129Kuo3Init, + dim4130Kuo3Init, + dim4131Kuo3Init, + dim4132Kuo3Init, + dim4133Kuo3Init, + dim4134Kuo3Init, + dim4135Kuo3Init, + dim4136Kuo3Init, + dim4137Kuo3Init, + dim4138Kuo3Init, + dim4139Kuo3Init, + dim4140Kuo3Init, + dim4141Kuo3Init, + dim4142Kuo3Init, + dim4143Kuo3Init, + dim4144Kuo3Init, + dim4145Kuo3Init, + dim4146Kuo3Init, + dim4147Kuo3Init, + dim4148Kuo3Init, + dim4149Kuo3Init, + dim4150Kuo3Init, + dim4151Kuo3Init, + dim4152Kuo3Init, + dim4153Kuo3Init, + dim4154Kuo3Init, + dim4155Kuo3Init, + dim4156Kuo3Init, + dim4157Kuo3Init, + dim4158Kuo3Init, + dim4159Kuo3Init, + dim4160Kuo3Init, + dim4161Kuo3Init, + dim4162Kuo3Init, + dim4163Kuo3Init, + dim4164Kuo3Init, + dim4165Kuo3Init, + dim4166Kuo3Init, + dim4167Kuo3Init, + dim4168Kuo3Init, + dim4169Kuo3Init, + dim4170Kuo3Init, + dim4171Kuo3Init, + dim4172Kuo3Init, + dim4173Kuo3Init, + dim4174Kuo3Init, + dim4175Kuo3Init, + dim4176Kuo3Init, + dim4177Kuo3Init, + dim4178Kuo3Init, + dim4179Kuo3Init, + dim4180Kuo3Init, + dim4181Kuo3Init, + dim4182Kuo3Init, + dim4183Kuo3Init, + dim4184Kuo3Init, + dim4185Kuo3Init, + dim4186Kuo3Init, + dim4187Kuo3Init, + dim4188Kuo3Init, + dim4189Kuo3Init, + dim4190Kuo3Init, + dim4191Kuo3Init, + dim4192Kuo3Init, + dim4193Kuo3Init, + dim4194Kuo3Init, + dim4195Kuo3Init, + dim4196Kuo3Init, + dim4197Kuo3Init, + dim4198Kuo3Init, + dim4199Kuo3Init, + dim4200Kuo3Init, + dim4201Kuo3Init, + dim4202Kuo3Init, + dim4203Kuo3Init, + dim4204Kuo3Init, + dim4205Kuo3Init, + dim4206Kuo3Init, + dim4207Kuo3Init, + dim4208Kuo3Init, + dim4209Kuo3Init, + dim4210Kuo3Init, + dim4211Kuo3Init, + dim4212Kuo3Init, + dim4213Kuo3Init, + dim4214Kuo3Init, + dim4215Kuo3Init, + dim4216Kuo3Init, + dim4217Kuo3Init, + dim4218Kuo3Init, + dim4219Kuo3Init, + dim4220Kuo3Init, + dim4221Kuo3Init, + dim4222Kuo3Init, + dim4223Kuo3Init, + dim4224Kuo3Init, + dim4225Kuo3Init, + dim4226Kuo3Init, + dim4227Kuo3Init, + dim4228Kuo3Init, + dim4229Kuo3Init, + dim4230Kuo3Init, + dim4231Kuo3Init, + dim4232Kuo3Init, + dim4233Kuo3Init, + dim4234Kuo3Init, + dim4235Kuo3Init, + dim4236Kuo3Init, + dim4237Kuo3Init, + dim4238Kuo3Init, + dim4239Kuo3Init, + dim4240Kuo3Init, + dim4241Kuo3Init, + dim4242Kuo3Init, + dim4243Kuo3Init, + dim4244Kuo3Init, + dim4245Kuo3Init, + dim4246Kuo3Init, + dim4247Kuo3Init, + dim4248Kuo3Init, + dim4249Kuo3Init, + dim4250Kuo3Init, + dim4251Kuo3Init, + dim4252Kuo3Init, + dim4253Kuo3Init, + dim4254Kuo3Init, + dim4255Kuo3Init, + dim4256Kuo3Init, + dim4257Kuo3Init, + dim4258Kuo3Init, + dim4259Kuo3Init, + dim4260Kuo3Init, + dim4261Kuo3Init, + dim4262Kuo3Init, + dim4263Kuo3Init, + dim4264Kuo3Init, + dim4265Kuo3Init, + dim4266Kuo3Init, + dim4267Kuo3Init, + dim4268Kuo3Init, + dim4269Kuo3Init, + dim4270Kuo3Init, + dim4271Kuo3Init, + dim4272Kuo3Init, + dim4273Kuo3Init, + dim4274Kuo3Init, + dim4275Kuo3Init, + dim4276Kuo3Init, + dim4277Kuo3Init, + dim4278Kuo3Init, + dim4279Kuo3Init, + dim4280Kuo3Init, + dim4281Kuo3Init, + dim4282Kuo3Init, + dim4283Kuo3Init, + dim4284Kuo3Init, + dim4285Kuo3Init, + dim4286Kuo3Init, + dim4287Kuo3Init, + dim4288Kuo3Init, + dim4289Kuo3Init, + dim4290Kuo3Init, + dim4291Kuo3Init, + dim4292Kuo3Init, + dim4293Kuo3Init, + dim4294Kuo3Init, + dim4295Kuo3Init, + dim4296Kuo3Init, + dim4297Kuo3Init, + dim4298Kuo3Init, + dim4299Kuo3Init, + dim4300Kuo3Init, + dim4301Kuo3Init, + dim4302Kuo3Init, + dim4303Kuo3Init, + dim4304Kuo3Init, + dim4305Kuo3Init, + dim4306Kuo3Init, + dim4307Kuo3Init, + dim4308Kuo3Init, + dim4309Kuo3Init, + dim4310Kuo3Init, + dim4311Kuo3Init, + dim4312Kuo3Init, + dim4313Kuo3Init, + dim4314Kuo3Init, + dim4315Kuo3Init, + dim4316Kuo3Init, + dim4317Kuo3Init, + dim4318Kuo3Init, + dim4319Kuo3Init, + dim4320Kuo3Init, + dim4321Kuo3Init, + dim4322Kuo3Init, + dim4323Kuo3Init, + dim4324Kuo3Init, + dim4325Kuo3Init, + dim4326Kuo3Init, + dim4327Kuo3Init, + dim4328Kuo3Init, + dim4329Kuo3Init, + dim4330Kuo3Init, + dim4331Kuo3Init, + dim4332Kuo3Init, + dim4333Kuo3Init, + dim4334Kuo3Init, + dim4335Kuo3Init, + dim4336Kuo3Init, + dim4337Kuo3Init, + dim4338Kuo3Init, + dim4339Kuo3Init, + dim4340Kuo3Init, + dim4341Kuo3Init, + dim4342Kuo3Init, + dim4343Kuo3Init, + dim4344Kuo3Init, + dim4345Kuo3Init, + dim4346Kuo3Init, + dim4347Kuo3Init, + dim4348Kuo3Init, + dim4349Kuo3Init, + dim4350Kuo3Init, + dim4351Kuo3Init, + dim4352Kuo3Init, + dim4353Kuo3Init, + dim4354Kuo3Init, + dim4355Kuo3Init, + dim4356Kuo3Init, + dim4357Kuo3Init, + dim4358Kuo3Init, + dim4359Kuo3Init, + dim4360Kuo3Init, + dim4361Kuo3Init, + dim4362Kuo3Init, + dim4363Kuo3Init, + dim4364Kuo3Init, + dim4365Kuo3Init, + dim4366Kuo3Init, + dim4367Kuo3Init, + dim4368Kuo3Init, + dim4369Kuo3Init, + dim4370Kuo3Init, + dim4371Kuo3Init, + dim4372Kuo3Init, + dim4373Kuo3Init, + dim4374Kuo3Init, + dim4375Kuo3Init, + dim4376Kuo3Init, + dim4377Kuo3Init, + dim4378Kuo3Init, + dim4379Kuo3Init, + dim4380Kuo3Init, + dim4381Kuo3Init, + dim4382Kuo3Init, + dim4383Kuo3Init, + dim4384Kuo3Init, + dim4385Kuo3Init, + dim4386Kuo3Init, + dim4387Kuo3Init, + dim4388Kuo3Init, + dim4389Kuo3Init, + dim4390Kuo3Init, + dim4391Kuo3Init, + dim4392Kuo3Init, + dim4393Kuo3Init, + dim4394Kuo3Init, + dim4395Kuo3Init, + dim4396Kuo3Init, + dim4397Kuo3Init, + dim4398Kuo3Init, + dim4399Kuo3Init, + dim4400Kuo3Init, + dim4401Kuo3Init, + dim4402Kuo3Init, + dim4403Kuo3Init, + dim4404Kuo3Init, + dim4405Kuo3Init, + dim4406Kuo3Init, + dim4407Kuo3Init, + dim4408Kuo3Init, + dim4409Kuo3Init, + dim4410Kuo3Init, + dim4411Kuo3Init, + dim4412Kuo3Init, + dim4413Kuo3Init, + dim4414Kuo3Init, + dim4415Kuo3Init, + dim4416Kuo3Init, + dim4417Kuo3Init, + dim4418Kuo3Init, + dim4419Kuo3Init, + dim4420Kuo3Init, + dim4421Kuo3Init, + dim4422Kuo3Init, + dim4423Kuo3Init, + dim4424Kuo3Init, + dim4425Kuo3Init, + dim4426Kuo3Init, + dim4427Kuo3Init, + dim4428Kuo3Init, + dim4429Kuo3Init, + dim4430Kuo3Init, + dim4431Kuo3Init, + dim4432Kuo3Init, + dim4433Kuo3Init, + dim4434Kuo3Init, + dim4435Kuo3Init, + dim4436Kuo3Init, + dim4437Kuo3Init, + dim4438Kuo3Init, + dim4439Kuo3Init, + dim4440Kuo3Init, + dim4441Kuo3Init, + dim4442Kuo3Init, + dim4443Kuo3Init, + dim4444Kuo3Init, + dim4445Kuo3Init, + dim4446Kuo3Init, + dim4447Kuo3Init, + dim4448Kuo3Init, + dim4449Kuo3Init, + dim4450Kuo3Init, + dim4451Kuo3Init, + dim4452Kuo3Init, + dim4453Kuo3Init, + dim4454Kuo3Init, + dim4455Kuo3Init, + dim4456Kuo3Init, + dim4457Kuo3Init, + dim4458Kuo3Init, + dim4459Kuo3Init, + dim4460Kuo3Init, + dim4461Kuo3Init, + dim4462Kuo3Init, + dim4463Kuo3Init, + dim4464Kuo3Init, + dim4465Kuo3Init, + dim4466Kuo3Init, + dim4467Kuo3Init, + dim4468Kuo3Init, + dim4469Kuo3Init, + dim4470Kuo3Init, + dim4471Kuo3Init, + dim4472Kuo3Init, + dim4473Kuo3Init, + dim4474Kuo3Init, + dim4475Kuo3Init, + dim4476Kuo3Init, + dim4477Kuo3Init, + dim4478Kuo3Init, + dim4479Kuo3Init, + dim4480Kuo3Init, + dim4481Kuo3Init, + dim4482Kuo3Init, + dim4483Kuo3Init, + dim4484Kuo3Init, + dim4485Kuo3Init, + dim4486Kuo3Init, + dim4487Kuo3Init, + dim4488Kuo3Init, + dim4489Kuo3Init, + dim4490Kuo3Init, + dim4491Kuo3Init, + dim4492Kuo3Init, + dim4493Kuo3Init, + dim4494Kuo3Init, + dim4495Kuo3Init, + dim4496Kuo3Init, + dim4497Kuo3Init, + dim4498Kuo3Init, + dim4499Kuo3Init, + dim4500Kuo3Init, + dim4501Kuo3Init, + dim4502Kuo3Init, + dim4503Kuo3Init, + dim4504Kuo3Init, + dim4505Kuo3Init, + dim4506Kuo3Init, + dim4507Kuo3Init, + dim4508Kuo3Init, + dim4509Kuo3Init, + dim4510Kuo3Init, + dim4511Kuo3Init, + dim4512Kuo3Init, + dim4513Kuo3Init, + dim4514Kuo3Init, + dim4515Kuo3Init, + dim4516Kuo3Init, + dim4517Kuo3Init, + dim4518Kuo3Init, + dim4519Kuo3Init, + dim4520Kuo3Init, + dim4521Kuo3Init, + dim4522Kuo3Init, + dim4523Kuo3Init, + dim4524Kuo3Init, + dim4525Kuo3Init, + dim4526Kuo3Init, + dim4527Kuo3Init, + dim4528Kuo3Init, + dim4529Kuo3Init, + dim4530Kuo3Init, + dim4531Kuo3Init, + dim4532Kuo3Init, + dim4533Kuo3Init, + dim4534Kuo3Init, + dim4535Kuo3Init, + dim4536Kuo3Init, + dim4537Kuo3Init, + dim4538Kuo3Init, + dim4539Kuo3Init, + dim4540Kuo3Init, + dim4541Kuo3Init, + dim4542Kuo3Init, + dim4543Kuo3Init, + dim4544Kuo3Init, + dim4545Kuo3Init, + dim4546Kuo3Init, + dim4547Kuo3Init, + dim4548Kuo3Init, + dim4549Kuo3Init, + dim4550Kuo3Init, + dim4551Kuo3Init, + dim4552Kuo3Init, + dim4553Kuo3Init, + dim4554Kuo3Init, + dim4555Kuo3Init, + dim4556Kuo3Init, + dim4557Kuo3Init, + dim4558Kuo3Init, + dim4559Kuo3Init, + dim4560Kuo3Init, + dim4561Kuo3Init, + dim4562Kuo3Init, + dim4563Kuo3Init, + dim4564Kuo3Init, + dim4565Kuo3Init, + dim4566Kuo3Init, + dim4567Kuo3Init, + dim4568Kuo3Init, + dim4569Kuo3Init, + dim4570Kuo3Init, + dim4571Kuo3Init, + dim4572Kuo3Init, + dim4573Kuo3Init, + dim4574Kuo3Init, + dim4575Kuo3Init, + dim4576Kuo3Init, + dim4577Kuo3Init, + dim4578Kuo3Init, + dim4579Kuo3Init, + dim4580Kuo3Init, + dim4581Kuo3Init, + dim4582Kuo3Init, + dim4583Kuo3Init, + dim4584Kuo3Init, + dim4585Kuo3Init, + dim4586Kuo3Init + }; + + static ulong[] dim1JoeKuoD6Init = { 1, 0 }; + static ulong[] dim2JoeKuoD6Init = { 1, 3, 0 }; + static ulong[] dim3JoeKuoD6Init = { 1, 3, 1, 0 }; + static ulong[] dim4JoeKuoD6Init = { 1, 1, 1, 0 }; + static ulong[] dim5JoeKuoD6Init = { 1, 1, 3, 3, 0 }; + static ulong[] dim6JoeKuoD6Init = { 1, 3, 5, 13, 0 }; + static ulong[] dim7JoeKuoD6Init = { 1, 1, 5, 5, 17, 0 }; + static ulong[] dim8JoeKuoD6Init = { 1, 1, 5, 5, 5, 0 }; + static ulong[] dim9JoeKuoD6Init = { 1, 1, 7, 11, 19, 0 }; + static ulong[] dim10JoeKuoD6Init = { 1, 1, 5, 1, 1, 0 }; + static ulong[] dim11JoeKuoD6Init = { 1, 1, 1, 3, 11, 0 }; + static ulong[] dim12JoeKuoD6Init = { 1, 3, 5, 5, 31, 0 }; + static ulong[] dim13JoeKuoD6Init = { 1, 3, 3, 9, 7, 49, 0 }; + static ulong[] dim14JoeKuoD6Init = { 1, 1, 1, 15, 21, 21, 0 }; + static ulong[] dim15JoeKuoD6Init = { 1, 3, 1, 13, 27, 49, 0 }; + static ulong[] dim16JoeKuoD6Init = { 1, 1, 1, 15, 7, 5, 0 }; + static ulong[] dim17JoeKuoD6Init = { 1, 3, 1, 15, 13, 25, 0 }; + static ulong[] dim18JoeKuoD6Init = { 1, 1, 5, 5, 19, 61, 0 }; + static ulong[] dim19JoeKuoD6Init = { 1, 3, 7, 11, 23, 15, 103, 0 }; + static ulong[] dim20JoeKuoD6Init = { 1, 3, 7, 13, 13, 15, 69, 0 }; + static ulong[] dim21JoeKuoD6Init = { 1, 1, 3, 13, 7, 35, 63, 0 }; + static ulong[] dim22JoeKuoD6Init = { 1, 3, 5, 9, 1, 25, 53, 0 }; + static ulong[] dim23JoeKuoD6Init = { 1, 3, 1, 13, 9, 35, 107, 0 }; + static ulong[] dim24JoeKuoD6Init = { 1, 3, 1, 5, 27, 61, 31, 0 }; + static ulong[] dim25JoeKuoD6Init = { 1, 1, 5, 11, 19, 41, 61, 0 }; + static ulong[] dim26JoeKuoD6Init = { 1, 3, 5, 3, 3, 13, 69, 0 }; + static ulong[] dim27JoeKuoD6Init = { 1, 1, 7, 13, 1, 19, 1, 0 }; + static ulong[] dim28JoeKuoD6Init = { 1, 3, 7, 5, 13, 19, 59, 0 }; + static ulong[] dim29JoeKuoD6Init = { 1, 1, 3, 9, 25, 29, 41, 0 }; + static ulong[] dim30JoeKuoD6Init = { 1, 3, 5, 13, 23, 1, 55, 0 }; + static ulong[] dim31JoeKuoD6Init = { 1, 3, 7, 3, 13, 59, 17, 0 }; + static ulong[] dim32JoeKuoD6Init = { 1, 3, 1, 3, 5, 53, 69, 0 }; + static ulong[] dim33JoeKuoD6Init = { 1, 1, 5, 5, 23, 33, 13, 0 }; + static ulong[] dim34JoeKuoD6Init = { 1, 1, 7, 7, 1, 61, 123, 0 }; + static ulong[] dim35JoeKuoD6Init = { 1, 1, 7, 9, 13, 61, 49, 0 }; + static ulong[] dim36JoeKuoD6Init = { 1, 3, 3, 5, 3, 55, 33, 0 }; + static ulong[] dim37JoeKuoD6Init = { 1, 3, 1, 15, 31, 13, 49, 245, 0 }; + static ulong[] dim38JoeKuoD6Init = { 1, 3, 5, 15, 31, 59, 63, 97, 0 }; + static ulong[] dim39JoeKuoD6Init = { 1, 3, 1, 11, 11, 11, 77, 249, 0 }; + static ulong[] dim40JoeKuoD6Init = { 1, 3, 1, 11, 27, 43, 71, 9, 0 }; + static ulong[] dim41JoeKuoD6Init = { 1, 1, 7, 15, 21, 11, 81, 45, 0 }; + static ulong[] dim42JoeKuoD6Init = { 1, 3, 7, 3, 25, 31, 65, 79, 0 }; + static ulong[] dim43JoeKuoD6Init = { 1, 3, 1, 1, 19, 11, 3, 205, 0 }; + static ulong[] dim44JoeKuoD6Init = { 1, 1, 5, 9, 19, 21, 29, 157, 0 }; + static ulong[] dim45JoeKuoD6Init = { 1, 3, 7, 11, 1, 33, 89, 185, 0 }; + static ulong[] dim46JoeKuoD6Init = { 1, 3, 3, 3, 15, 9, 79, 71, 0 }; + static ulong[] dim47JoeKuoD6Init = { 1, 3, 7, 11, 15, 39, 119, 27, 0 }; + static ulong[] dim48JoeKuoD6Init = { 1, 1, 3, 1, 11, 31, 97, 225, 0 }; + static ulong[] dim49JoeKuoD6Init = { 1, 1, 1, 3, 23, 43, 57, 177, 0 }; + static ulong[] dim50JoeKuoD6Init = { 1, 3, 7, 7, 17, 17, 37, 71, 0 }; + static ulong[] dim51JoeKuoD6Init = { 1, 3, 1, 5, 27, 63, 123, 213, 0 }; + static ulong[] dim52JoeKuoD6Init = { 1, 1, 3, 5, 11, 43, 53, 133, 0 }; + static ulong[] dim53JoeKuoD6Init = { 1, 3, 5, 5, 29, 17, 47, 173, 479, 0 }; + static ulong[] dim54JoeKuoD6Init = { 1, 3, 3, 11, 3, 1, 109, 9, 69, 0 }; + static ulong[] dim55JoeKuoD6Init = { 1, 1, 1, 5, 17, 39, 23, 5, 343, 0 }; + static ulong[] dim56JoeKuoD6Init = { 1, 3, 1, 5, 25, 15, 31, 103, 499, 0 }; + static ulong[] dim57JoeKuoD6Init = { 1, 1, 1, 11, 11, 17, 63, 105, 183, 0 }; + static ulong[] dim58JoeKuoD6Init = { 1, 1, 5, 11, 9, 29, 97, 231, 363, 0 }; + static ulong[] dim59JoeKuoD6Init = { 1, 1, 5, 15, 19, 45, 41, 7, 383, 0 }; + static ulong[] dim60JoeKuoD6Init = { 1, 3, 7, 7, 31, 19, 83, 137, 221, 0 }; + static ulong[] dim61JoeKuoD6Init = { 1, 1, 1, 3, 23, 15, 111, 223, 83, 0 }; + static ulong[] dim62JoeKuoD6Init = { 1, 1, 5, 13, 31, 15, 55, 25, 161, 0 }; + static ulong[] dim63JoeKuoD6Init = { 1, 1, 3, 13, 25, 47, 39, 87, 257, 0 }; + static ulong[] dim64JoeKuoD6Init = { 1, 1, 1, 11, 21, 53, 125, 249, 293, 0 }; + static ulong[] dim65JoeKuoD6Init = { 1, 1, 7, 11, 11, 7, 57, 79, 323, 0 }; + static ulong[] dim66JoeKuoD6Init = { 1, 1, 5, 5, 17, 13, 81, 3, 131, 0 }; + static ulong[] dim67JoeKuoD6Init = { 1, 1, 7, 13, 23, 7, 65, 251, 475, 0 }; + static ulong[] dim68JoeKuoD6Init = { 1, 3, 5, 1, 9, 43, 3, 149, 11, 0 }; + static ulong[] dim69JoeKuoD6Init = { 1, 1, 3, 13, 31, 13, 13, 255, 487, 0 }; + static ulong[] dim70JoeKuoD6Init = { 1, 3, 3, 1, 5, 63, 89, 91, 127, 0 }; + static ulong[] dim71JoeKuoD6Init = { 1, 1, 3, 3, 1, 19, 123, 127, 237, 0 }; + static ulong[] dim72JoeKuoD6Init = { 1, 1, 5, 7, 23, 31, 37, 243, 289, 0 }; + static ulong[] dim73JoeKuoD6Init = { 1, 1, 5, 11, 17, 53, 117, 183, 491, 0 }; + static ulong[] dim74JoeKuoD6Init = { 1, 1, 1, 5, 1, 13, 13, 209, 345, 0 }; + static ulong[] dim75JoeKuoD6Init = { 1, 1, 3, 15, 1, 57, 115, 7, 33, 0 }; + static ulong[] dim76JoeKuoD6Init = { 1, 3, 1, 11, 7, 43, 81, 207, 175, 0 }; + static ulong[] dim77JoeKuoD6Init = { 1, 3, 1, 1, 15, 27, 63, 255, 49, 0 }; + static ulong[] dim78JoeKuoD6Init = { 1, 3, 5, 3, 27, 61, 105, 171, 305, 0 }; + static ulong[] dim79JoeKuoD6Init = { 1, 1, 5, 3, 1, 3, 57, 249, 149, 0 }; + static ulong[] dim80JoeKuoD6Init = { 1, 1, 3, 5, 5, 57, 15, 13, 159, 0 }; + static ulong[] dim81JoeKuoD6Init = { 1, 1, 1, 11, 7, 11, 105, 141, 225, 0 }; + static ulong[] dim82JoeKuoD6Init = { 1, 3, 3, 5, 27, 59, 121, 101, 271, 0 }; + static ulong[] dim83JoeKuoD6Init = { 1, 3, 5, 9, 11, 49, 51, 59, 115, 0 }; + static ulong[] dim84JoeKuoD6Init = { 1, 1, 7, 1, 23, 45, 125, 71, 419, 0 }; + static ulong[] dim85JoeKuoD6Init = { 1, 1, 3, 5, 23, 5, 105, 109, 75, 0 }; + static ulong[] dim86JoeKuoD6Init = { 1, 1, 7, 15, 7, 11, 67, 121, 453, 0 }; + static ulong[] dim87JoeKuoD6Init = { 1, 3, 7, 3, 9, 13, 31, 27, 449, 0 }; + static ulong[] dim88JoeKuoD6Init = { 1, 3, 1, 15, 19, 39, 39, 89, 15, 0 }; + static ulong[] dim89JoeKuoD6Init = { 1, 1, 1, 1, 1, 33, 73, 145, 379, 0 }; + static ulong[] dim90JoeKuoD6Init = { 1, 3, 1, 15, 15, 43, 29, 13, 483, 0 }; + static ulong[] dim91JoeKuoD6Init = { 1, 1, 7, 3, 19, 27, 85, 131, 431, 0 }; + static ulong[] dim92JoeKuoD6Init = { 1, 3, 3, 3, 5, 35, 23, 195, 349, 0 }; + static ulong[] dim93JoeKuoD6Init = { 1, 3, 3, 7, 9, 27, 39, 59, 297, 0 }; + static ulong[] dim94JoeKuoD6Init = { 1, 1, 3, 9, 11, 17, 13, 241, 157, 0 }; + static ulong[] dim95JoeKuoD6Init = { 1, 3, 7, 15, 25, 57, 33, 189, 213, 0 }; + static ulong[] dim96JoeKuoD6Init = { 1, 1, 7, 1, 9, 55, 73, 83, 217, 0 }; + static ulong[] dim97JoeKuoD6Init = { 1, 3, 3, 13, 19, 27, 23, 113, 249, 0 }; + static ulong[] dim98JoeKuoD6Init = { 1, 3, 5, 3, 23, 43, 3, 253, 479, 0 }; + static ulong[] dim99JoeKuoD6Init = { 1, 1, 5, 5, 11, 5, 45, 117, 217, 0 }; + static ulong[] dim100JoeKuoD6Init = { 1, 3, 3, 7, 29, 37, 33, 123, 147, 0 }; + static ulong[] dim101JoeKuoD6Init = { 1, 3, 1, 15, 5, 5, 37, 227, 223, 459, 0 }; + static ulong[] dim102JoeKuoD6Init = { 1, 1, 7, 5, 5, 39, 63, 255, 135, 487, 0 }; + static ulong[] dim103JoeKuoD6Init = { 1, 3, 1, 7, 9, 7, 87, 249, 217, 599, 0 }; + static ulong[] dim104JoeKuoD6Init = { 1, 1, 3, 13, 9, 47, 7, 225, 363, 247, 0 }; + static ulong[] dim105JoeKuoD6Init = { 1, 3, 7, 13, 19, 13, 9, 67, 9, 737, 0 }; + static ulong[] dim106JoeKuoD6Init = { 1, 3, 5, 5, 19, 59, 7, 41, 319, 677, 0 }; + static ulong[] dim107JoeKuoD6Init = { 1, 1, 5, 3, 31, 63, 15, 43, 207, 789, 0 }; + static ulong[] dim108JoeKuoD6Init = { 1, 1, 7, 9, 13, 39, 3, 47, 497, 169, 0 }; + static ulong[] dim109JoeKuoD6Init = { 1, 3, 1, 7, 21, 17, 97, 19, 415, 905, 0 }; + static ulong[] dim110JoeKuoD6Init = { 1, 3, 7, 1, 3, 31, 71, 111, 165, 127, 0 }; + static ulong[] dim111JoeKuoD6Init = { 1, 1, 5, 11, 1, 61, 83, 119, 203, 847, 0 }; + static ulong[] dim112JoeKuoD6Init = { 1, 3, 3, 13, 9, 61, 19, 97, 47, 35, 0 }; + static ulong[] dim113JoeKuoD6Init = { 1, 1, 7, 7, 15, 29, 63, 95, 417, 469, 0 }; + static ulong[] dim114JoeKuoD6Init = { 1, 3, 1, 9, 25, 9, 71, 57, 213, 385, 0 }; + static ulong[] dim115JoeKuoD6Init = { 1, 3, 5, 13, 31, 47, 101, 57, 39, 341, 0 }; + static ulong[] dim116JoeKuoD6Init = { 1, 1, 3, 3, 31, 57, 125, 173, 365, 551, 0 }; + static ulong[] dim117JoeKuoD6Init = { 1, 3, 7, 1, 13, 57, 67, 157, 451, 707, 0 }; + static ulong[] dim118JoeKuoD6Init = { 1, 1, 1, 7, 21, 13, 105, 89, 429, 965, 0 }; + static ulong[] dim119JoeKuoD6Init = { 1, 1, 5, 9, 17, 51, 45, 119, 157, 141, 0 }; + static ulong[] dim120JoeKuoD6Init = { 1, 3, 7, 7, 13, 45, 91, 9, 129, 741, 0 }; + static ulong[] dim121JoeKuoD6Init = { 1, 3, 7, 1, 23, 57, 67, 141, 151, 571, 0 }; + static ulong[] dim122JoeKuoD6Init = { 1, 1, 3, 11, 17, 47, 93, 107, 375, 157, 0 }; + static ulong[] dim123JoeKuoD6Init = { 1, 3, 3, 5, 11, 21, 43, 51, 169, 915, 0 }; + static ulong[] dim124JoeKuoD6Init = { 1, 1, 5, 3, 15, 55, 101, 67, 455, 625, 0 }; + static ulong[] dim125JoeKuoD6Init = { 1, 3, 5, 9, 1, 23, 29, 47, 345, 595, 0 }; + static ulong[] dim126JoeKuoD6Init = { 1, 3, 7, 7, 5, 49, 29, 155, 323, 589, 0 }; + static ulong[] dim127JoeKuoD6Init = { 1, 3, 3, 7, 5, 41, 127, 61, 261, 717, 0 }; + static ulong[] dim128JoeKuoD6Init = { 1, 3, 7, 7, 17, 23, 117, 67, 129, 1009, 0 }; + static ulong[] dim129JoeKuoD6Init = { 1, 1, 3, 13, 11, 39, 21, 207, 123, 305, 0 }; + static ulong[] dim130JoeKuoD6Init = { 1, 1, 3, 9, 29, 3, 95, 47, 231, 73, 0 }; + static ulong[] dim131JoeKuoD6Init = { 1, 3, 1, 9, 1, 29, 117, 21, 441, 259, 0 }; + static ulong[] dim132JoeKuoD6Init = { 1, 3, 1, 13, 21, 39, 125, 211, 439, 723, 0 }; + static ulong[] dim133JoeKuoD6Init = { 1, 1, 7, 3, 17, 63, 115, 89, 49, 773, 0 }; + static ulong[] dim134JoeKuoD6Init = { 1, 3, 7, 13, 11, 33, 101, 107, 63, 73, 0 }; + static ulong[] dim135JoeKuoD6Init = { 1, 1, 5, 5, 13, 57, 63, 135, 437, 177, 0 }; + static ulong[] dim136JoeKuoD6Init = { 1, 1, 3, 7, 27, 63, 93, 47, 417, 483, 0 }; + static ulong[] dim137JoeKuoD6Init = { 1, 1, 3, 1, 23, 29, 1, 191, 49, 23, 0 }; + static ulong[] dim138JoeKuoD6Init = { 1, 1, 3, 15, 25, 55, 9, 101, 219, 607, 0 }; + static ulong[] dim139JoeKuoD6Init = { 1, 3, 1, 7, 7, 19, 51, 251, 393, 307, 0 }; + static ulong[] dim140JoeKuoD6Init = { 1, 3, 3, 3, 25, 55, 17, 75, 337, 3, 0 }; + static ulong[] dim141JoeKuoD6Init = { 1, 1, 1, 13, 25, 17, 65, 45, 479, 413, 0 }; + static ulong[] dim142JoeKuoD6Init = { 1, 1, 7, 7, 27, 49, 99, 161, 213, 727, 0 }; + static ulong[] dim143JoeKuoD6Init = { 1, 3, 5, 1, 23, 5, 43, 41, 251, 857, 0 }; + static ulong[] dim144JoeKuoD6Init = { 1, 3, 3, 7, 11, 61, 39, 87, 383, 835, 0 }; + static ulong[] dim145JoeKuoD6Init = { 1, 1, 3, 15, 13, 7, 29, 7, 505, 923, 0 }; + static ulong[] dim146JoeKuoD6Init = { 1, 3, 7, 1, 5, 31, 47, 157, 445, 501, 0 }; + static ulong[] dim147JoeKuoD6Init = { 1, 1, 3, 7, 1, 43, 9, 147, 115, 605, 0 }; + static ulong[] dim148JoeKuoD6Init = { 1, 3, 3, 13, 5, 1, 119, 211, 455, 1001, 0 }; + static ulong[] dim149JoeKuoD6Init = { 1, 1, 3, 5, 13, 19, 3, 243, 75, 843, 0 }; + static ulong[] dim150JoeKuoD6Init = { 1, 3, 7, 7, 1, 19, 91, 249, 357, 589, 0 }; + static ulong[] dim151JoeKuoD6Init = { 1, 1, 1, 9, 1, 25, 109, 197, 279, 411, 0 }; + static ulong[] dim152JoeKuoD6Init = { 1, 3, 1, 15, 23, 57, 59, 135, 191, 75, 0 }; + static ulong[] dim153JoeKuoD6Init = { 1, 1, 5, 15, 29, 21, 39, 253, 383, 349, 0 }; + static ulong[] dim154JoeKuoD6Init = { 1, 3, 3, 5, 19, 45, 61, 151, 199, 981, 0 }; + static ulong[] dim155JoeKuoD6Init = { 1, 3, 5, 13, 9, 61, 107, 141, 141, 1, 0 }; + static ulong[] dim156JoeKuoD6Init = { 1, 3, 1, 11, 27, 25, 85, 105, 309, 979, 0 }; + static ulong[] dim157JoeKuoD6Init = { 1, 3, 3, 11, 19, 7, 115, 223, 349, 43, 0 }; + static ulong[] dim158JoeKuoD6Init = { 1, 1, 7, 9, 21, 39, 123, 21, 275, 927, 0 }; + static ulong[] dim159JoeKuoD6Init = { 1, 1, 7, 13, 15, 41, 47, 243, 303, 437, 0 }; + static ulong[] dim160JoeKuoD6Init = { 1, 1, 1, 7, 7, 3, 15, 99, 409, 719, 0 }; + static ulong[] dim161JoeKuoD6Init = { 1, 3, 3, 15, 27, 49, 113, 123, 113, 67, 469, 0 }; + static ulong[] dim162JoeKuoD6Init = { 1, 3, 7, 11, 3, 23, 87, 169, 119, 483, 199, 0 }; + static ulong[] dim163JoeKuoD6Init = { 1, 1, 5, 15, 7, 17, 109, 229, 179, 213, 741, 0 }; + static ulong[] dim164JoeKuoD6Init = { 1, 1, 5, 13, 11, 17, 25, 135, 403, 557, 1433, 0 }; + static ulong[] dim165JoeKuoD6Init = { 1, 3, 1, 1, 1, 61, 67, 215, 189, 945, 1243, 0 }; + static ulong[] dim166JoeKuoD6Init = { 1, 1, 7, 13, 17, 33, 9, 221, 429, 217, 1679, 0 }; + static ulong[] dim167JoeKuoD6Init = { 1, 1, 3, 11, 27, 3, 15, 93, 93, 865, 1049, 0 }; + static ulong[] dim168JoeKuoD6Init = { 1, 3, 7, 7, 25, 41, 121, 35, 373, 379, 1547, 0 }; + static ulong[] dim169JoeKuoD6Init = { 1, 3, 3, 9, 11, 35, 45, 205, 241, 9, 59, 0 }; + static ulong[] dim170JoeKuoD6Init = { 1, 3, 1, 7, 3, 51, 7, 177, 53, 975, 89, 0 }; + static ulong[] dim171JoeKuoD6Init = { 1, 1, 3, 5, 27, 1, 113, 231, 299, 759, 861, 0 }; + static ulong[] dim172JoeKuoD6Init = { 1, 3, 3, 15, 25, 29, 5, 255, 139, 891, 2031, 0 }; + static ulong[] dim173JoeKuoD6Init = { 1, 3, 1, 1, 13, 9, 109, 193, 419, 95, 17, 0 }; + static ulong[] dim174JoeKuoD6Init = { 1, 1, 7, 9, 3, 7, 29, 41, 135, 839, 867, 0 }; + static ulong[] dim175JoeKuoD6Init = { 1, 1, 7, 9, 25, 49, 123, 217, 113, 909, 215, 0 }; + static ulong[] dim176JoeKuoD6Init = { 1, 1, 7, 3, 23, 15, 43, 133, 217, 327, 901, 0 }; + static ulong[] dim177JoeKuoD6Init = { 1, 1, 3, 3, 13, 53, 63, 123, 477, 711, 1387, 0 }; + static ulong[] dim178JoeKuoD6Init = { 1, 1, 3, 15, 7, 29, 75, 119, 181, 957, 247, 0 }; + static ulong[] dim179JoeKuoD6Init = { 1, 1, 1, 11, 27, 25, 109, 151, 267, 99, 1461, 0 }; + static ulong[] dim180JoeKuoD6Init = { 1, 3, 7, 15, 5, 5, 53, 145, 11, 725, 1501, 0 }; + static ulong[] dim181JoeKuoD6Init = { 1, 3, 7, 1, 9, 43, 71, 229, 157, 607, 1835, 0 }; + static ulong[] dim182JoeKuoD6Init = { 1, 3, 3, 13, 25, 1, 5, 27, 471, 349, 127, 0 }; + static ulong[] dim183JoeKuoD6Init = { 1, 1, 1, 1, 23, 37, 9, 221, 269, 897, 1685, 0 }; + static ulong[] dim184JoeKuoD6Init = { 1, 1, 3, 3, 31, 29, 51, 19, 311, 553, 1969, 0 }; + static ulong[] dim185JoeKuoD6Init = { 1, 3, 7, 5, 5, 55, 17, 39, 475, 671, 1529, 0 }; + static ulong[] dim186JoeKuoD6Init = { 1, 1, 7, 1, 1, 35, 47, 27, 437, 395, 1635, 0 }; + static ulong[] dim187JoeKuoD6Init = { 1, 1, 7, 3, 13, 23, 43, 135, 327, 139, 389, 0 }; + static ulong[] dim188JoeKuoD6Init = { 1, 3, 7, 3, 9, 25, 91, 25, 429, 219, 513, 0 }; + static ulong[] dim189JoeKuoD6Init = { 1, 1, 3, 5, 13, 29, 119, 201, 277, 157, 2043, 0 }; + static ulong[] dim190JoeKuoD6Init = { 1, 3, 5, 3, 29, 57, 13, 17, 167, 739, 1031, 0 }; + static ulong[] dim191JoeKuoD6Init = { 1, 3, 3, 5, 29, 21, 95, 27, 255, 679, 1531, 0 }; + static ulong[] dim192JoeKuoD6Init = { 1, 3, 7, 15, 9, 5, 21, 71, 61, 961, 1201, 0 }; + static ulong[] dim193JoeKuoD6Init = { 1, 3, 5, 13, 15, 57, 33, 93, 459, 867, 223, 0 }; + static ulong[] dim194JoeKuoD6Init = { 1, 1, 1, 15, 17, 43, 127, 191, 67, 177, 1073, 0 }; + static ulong[] dim195JoeKuoD6Init = { 1, 1, 1, 15, 23, 7, 21, 199, 75, 293, 1611, 0 }; + static ulong[] dim196JoeKuoD6Init = { 1, 3, 7, 13, 15, 39, 21, 149, 65, 741, 319, 0 }; + static ulong[] dim197JoeKuoD6Init = { 1, 3, 7, 11, 23, 13, 101, 89, 277, 519, 711, 0 }; + static ulong[] dim198JoeKuoD6Init = { 1, 3, 7, 15, 19, 27, 85, 203, 441, 97, 1895, 0 }; + static ulong[] dim199JoeKuoD6Init = { 1, 3, 1, 3, 29, 25, 21, 155, 11, 191, 197, 0 }; + static ulong[] dim200JoeKuoD6Init = { 1, 1, 7, 5, 27, 11, 81, 101, 457, 675, 1687, 0 }; + static ulong[] dim201JoeKuoD6Init = { 1, 3, 1, 5, 25, 5, 65, 193, 41, 567, 781, 0 }; + static ulong[] dim202JoeKuoD6Init = { 1, 3, 1, 5, 11, 15, 113, 77, 411, 695, 1111, 0 }; + static ulong[] dim203JoeKuoD6Init = { 1, 1, 3, 9, 11, 53, 119, 171, 55, 297, 509, 0 }; + static ulong[] dim204JoeKuoD6Init = { 1, 1, 1, 1, 11, 39, 113, 139, 165, 347, 595, 0 }; + static ulong[] dim205JoeKuoD6Init = { 1, 3, 7, 11, 9, 17, 101, 13, 81, 325, 1733, 0 }; + static ulong[] dim206JoeKuoD6Init = { 1, 3, 1, 1, 21, 43, 115, 9, 113, 907, 645, 0 }; + static ulong[] dim207JoeKuoD6Init = { 1, 1, 7, 3, 9, 25, 117, 197, 159, 471, 475, 0 }; + static ulong[] dim208JoeKuoD6Init = { 1, 3, 1, 9, 11, 21, 57, 207, 485, 613, 1661, 0 }; + static ulong[] dim209JoeKuoD6Init = { 1, 1, 7, 7, 27, 55, 49, 223, 89, 85, 1523, 0 }; + static ulong[] dim210JoeKuoD6Init = { 1, 1, 5, 3, 19, 41, 45, 51, 447, 299, 1355, 0 }; + static ulong[] dim211JoeKuoD6Init = { 1, 3, 1, 15, 1, 35, 119, 135, 427, 93, 1311, 0 }; + static ulong[] dim212JoeKuoD6Init = { 1, 3, 1, 15, 31, 39, 121, 145, 129, 903, 333, 0 }; + static ulong[] dim213JoeKuoD6Init = { 1, 1, 5, 3, 29, 7, 9, 11, 395, 119, 873, 0 }; + static ulong[] dim214JoeKuoD6Init = { 1, 3, 5, 11, 27, 29, 5, 117, 469, 31, 1811, 0 }; + static ulong[] dim215JoeKuoD6Init = { 1, 1, 7, 15, 21, 25, 71, 15, 89, 1021, 679, 0 }; + static ulong[] dim216JoeKuoD6Init = { 1, 3, 7, 9, 21, 39, 51, 111, 327, 809, 845, 0 }; + static ulong[] dim217JoeKuoD6Init = { 1, 3, 3, 13, 3, 33, 79, 17, 183, 599, 1859, 0 }; + static ulong[] dim218JoeKuoD6Init = { 1, 1, 7, 9, 31, 9, 1, 5, 353, 395, 833, 0 }; + static ulong[] dim219JoeKuoD6Init = { 1, 3, 5, 7, 3, 53, 81, 133, 155, 355, 1559, 0 }; + static ulong[] dim220JoeKuoD6Init = { 1, 3, 5, 5, 31, 13, 89, 195, 357, 769, 889, 0 }; + static ulong[] dim221JoeKuoD6Init = { 1, 1, 7, 1, 9, 21, 77, 31, 269, 857, 923, 0 }; + static ulong[] dim222JoeKuoD6Init = { 1, 1, 1, 11, 11, 27, 61, 185, 329, 685, 325, 0 }; + static ulong[] dim223JoeKuoD6Init = { 1, 1, 1, 5, 11, 31, 71, 79, 293, 29, 17, 0 }; + static ulong[] dim224JoeKuoD6Init = { 1, 1, 7, 7, 7, 41, 65, 167, 67, 153, 1305, 0 }; + static ulong[] dim225JoeKuoD6Init = { 1, 3, 3, 5, 23, 45, 109, 205, 191, 649, 749, 0 }; + static ulong[] dim226JoeKuoD6Init = { 1, 1, 7, 7, 17, 1, 73, 211, 19, 797, 1009, 0 }; + static ulong[] dim227JoeKuoD6Init = { 1, 1, 5, 9, 23, 15, 117, 213, 183, 477, 1301, 0 }; + static ulong[] dim228JoeKuoD6Init = { 1, 1, 5, 13, 23, 35, 55, 151, 267, 883, 1479, 0 }; + static ulong[] dim229JoeKuoD6Init = { 1, 1, 1, 7, 5, 43, 77, 11, 149, 297, 329, 0 }; + static ulong[] dim230JoeKuoD6Init = { 1, 1, 7, 15, 3, 41, 55, 123, 219, 499, 377, 0 }; + static ulong[] dim231JoeKuoD6Init = { 1, 3, 3, 1, 27, 7, 113, 141, 173, 379, 1087, 0 }; + static ulong[] dim232JoeKuoD6Init = { 1, 3, 1, 9, 7, 25, 45, 49, 415, 329, 483, 0 }; + static ulong[] dim233JoeKuoD6Init = { 1, 1, 7, 7, 7, 15, 75, 191, 305, 757, 813, 0 }; + static ulong[] dim234JoeKuoD6Init = { 1, 3, 7, 5, 31, 15, 21, 247, 29, 297, 1015, 0 }; + static ulong[] dim235JoeKuoD6Init = { 1, 3, 1, 13, 3, 41, 69, 235, 431, 515, 1889, 0 }; + static ulong[] dim236JoeKuoD6Init = { 1, 1, 5, 7, 31, 5, 69, 193, 229, 439, 1043, 0 }; + static ulong[] dim237JoeKuoD6Init = { 1, 3, 5, 13, 31, 33, 45, 159, 477, 707, 1605, 0 }; + static ulong[] dim238JoeKuoD6Init = { 1, 1, 1, 7, 23, 49, 107, 223, 7, 429, 2047, 0 }; + static ulong[] dim239JoeKuoD6Init = { 1, 3, 5, 1, 31, 17, 117, 133, 331, 97, 833, 0 }; + static ulong[] dim240JoeKuoD6Init = { 1, 3, 1, 11, 7, 31, 103, 5, 299, 601, 981, 0 }; + static ulong[] dim241JoeKuoD6Init = { 1, 3, 5, 5, 15, 57, 87, 39, 217, 155, 361, 0 }; + static ulong[] dim242JoeKuoD6Init = { 1, 1, 7, 15, 29, 19, 125, 131, 37, 635, 1429, 0 }; + static ulong[] dim243JoeKuoD6Init = { 1, 3, 1, 9, 29, 3, 59, 107, 341, 809, 101, 0 }; + static ulong[] dim244JoeKuoD6Init = { 1, 1, 5, 15, 9, 37, 113, 225, 139, 165, 393, 0 }; + static ulong[] dim245JoeKuoD6Init = { 1, 3, 3, 13, 27, 21, 35, 255, 189, 45, 103, 0 }; + static ulong[] dim246JoeKuoD6Init = { 1, 1, 7, 5, 7, 59, 39, 87, 319, 723, 955, 0 }; + static ulong[] dim247JoeKuoD6Init = { 1, 3, 1, 1, 9, 23, 83, 47, 413, 445, 787, 0 }; + static ulong[] dim248JoeKuoD6Init = { 1, 3, 3, 3, 9, 27, 113, 135, 279, 915, 1221, 0 }; + static ulong[] dim249JoeKuoD6Init = { 1, 3, 7, 15, 3, 49, 99, 67, 11, 1017, 891, 0 }; + static ulong[] dim250JoeKuoD6Init = { 1, 3, 1, 9, 31, 41, 9, 205, 39, 993, 105, 0 }; + static ulong[] dim251JoeKuoD6Init = { 1, 3, 3, 7, 11, 45, 67, 123, 303, 87, 1943, 0 }; + static ulong[] dim252JoeKuoD6Init = { 1, 1, 1, 9, 1, 51, 101, 253, 499, 879, 833, 0 }; + static ulong[] dim253JoeKuoD6Init = { 1, 3, 7, 15, 19, 51, 97, 13, 499, 231, 829, 0 }; + static ulong[] dim254JoeKuoD6Init = { 1, 3, 5, 3, 25, 49, 29, 165, 43, 95, 779, 0 }; + static ulong[] dim255JoeKuoD6Init = { 1, 3, 5, 11, 13, 63, 1, 133, 207, 349, 221, 0 }; + static ulong[] dim256JoeKuoD6Init = { 1, 3, 7, 11, 23, 37, 51, 123, 399, 295, 1057, 0 }; + static ulong[] dim257JoeKuoD6Init = { 1, 1, 5, 11, 11, 43, 97, 163, 477, 777, 1217, 0 }; + static ulong[] dim258JoeKuoD6Init = { 1, 1, 7, 13, 3, 33, 65, 191, 25, 993, 291, 0 }; + static ulong[] dim259JoeKuoD6Init = { 1, 3, 5, 9, 25, 55, 101, 231, 219, 215, 517, 0 }; + static ulong[] dim260JoeKuoD6Init = { 1, 3, 1, 7, 17, 31, 87, 1, 475, 371, 771, 0 }; + static ulong[] dim261JoeKuoD6Init = { 1, 1, 1, 7, 3, 25, 35, 255, 211, 67, 447, 0 }; + static ulong[] dim262JoeKuoD6Init = { 1, 1, 1, 13, 9, 33, 103, 17, 369, 455, 265, 0 }; + static ulong[] dim263JoeKuoD6Init = { 1, 3, 5, 5, 29, 61, 61, 207, 345, 87, 1035, 0 }; + static ulong[] dim264JoeKuoD6Init = { 1, 3, 1, 7, 19, 21, 117, 49, 191, 133, 1889, 0 }; + static ulong[] dim265JoeKuoD6Init = { 1, 3, 3, 13, 5, 37, 63, 229, 53, 891, 1939, 0 }; + static ulong[] dim266JoeKuoD6Init = { 1, 1, 3, 5, 1, 43, 7, 1, 427, 155, 1587, 0 }; + static ulong[] dim267JoeKuoD6Init = { 1, 1, 7, 15, 15, 33, 33, 233, 481, 709, 905, 0 }; + static ulong[] dim268JoeKuoD6Init = { 1, 1, 7, 13, 7, 11, 125, 77, 39, 55, 1745, 0 }; + static ulong[] dim269JoeKuoD6Init = { 1, 3, 3, 3, 7, 49, 35, 123, 267, 229, 1873, 0 }; + static ulong[] dim270JoeKuoD6Init = { 1, 1, 7, 3, 17, 11, 35, 217, 215, 577, 1467, 0 }; + static ulong[] dim271JoeKuoD6Init = { 1, 3, 3, 5, 7, 11, 51, 27, 277, 113, 767, 0 }; + static ulong[] dim272JoeKuoD6Init = { 1, 3, 3, 3, 17, 1, 61, 151, 227, 841, 1421, 0 }; + static ulong[] dim273JoeKuoD6Init = { 1, 3, 7, 7, 7, 29, 95, 219, 407, 257, 417, 0 }; + static ulong[] dim274JoeKuoD6Init = { 1, 3, 5, 13, 5, 39, 63, 67, 467, 99, 457, 0 }; + static ulong[] dim275JoeKuoD6Init = { 1, 3, 3, 9, 15, 19, 107, 217, 371, 411, 867, 0 }; + static ulong[] dim276JoeKuoD6Init = { 1, 3, 3, 13, 13, 1, 101, 81, 69, 371, 415, 0 }; + static ulong[] dim277JoeKuoD6Init = { 1, 3, 1, 1, 5, 31, 103, 125, 147, 85, 1357, 0 }; + static ulong[] dim278JoeKuoD6Init = { 1, 3, 1, 5, 25, 61, 9, 83, 371, 691, 1189, 0 }; + static ulong[] dim279JoeKuoD6Init = { 1, 1, 5, 3, 3, 9, 1, 123, 333, 741, 961, 0 }; + static ulong[] dim280JoeKuoD6Init = { 1, 1, 3, 1, 7, 37, 73, 39, 101, 1005, 1361, 0 }; + static ulong[] dim281JoeKuoD6Init = { 1, 1, 3, 15, 11, 51, 29, 159, 361, 685, 1643, 0 }; + static ulong[] dim282JoeKuoD6Init = { 1, 1, 3, 3, 17, 51, 79, 143, 373, 425, 703, 0 }; + static ulong[] dim283JoeKuoD6Init = { 1, 1, 3, 15, 17, 21, 63, 97, 335, 591, 1697, 0 }; + static ulong[] dim284JoeKuoD6Init = { 1, 1, 7, 7, 1, 57, 21, 253, 199, 661, 77, 0 }; + static ulong[] dim285JoeKuoD6Init = { 1, 1, 3, 13, 27, 13, 101, 247, 497, 535, 273, 0 }; + static ulong[] dim286JoeKuoD6Init = { 1, 1, 1, 7, 25, 5, 83, 27, 107, 549, 1885, 0 }; + static ulong[] dim287JoeKuoD6Init = { 1, 1, 7, 5, 29, 45, 107, 159, 59, 303, 1941, 0 }; + static ulong[] dim288JoeKuoD6Init = { 1, 1, 7, 9, 5, 43, 85, 89, 151, 39, 221, 0 }; + static ulong[] dim289JoeKuoD6Init = { 1, 1, 3, 5, 5, 47, 65, 205, 141, 777, 1873, 0 }; + static ulong[] dim290JoeKuoD6Init = { 1, 1, 5, 15, 25, 41, 121, 133, 41, 171, 521, 0 }; + static ulong[] dim291JoeKuoD6Init = { 1, 3, 3, 9, 19, 25, 15, 161, 339, 155, 413, 0 }; + static ulong[] dim292JoeKuoD6Init = { 1, 3, 7, 1, 7, 1, 67, 23, 453, 625, 1375, 0 }; + static ulong[] dim293JoeKuoD6Init = { 1, 1, 1, 15, 5, 9, 87, 89, 209, 361, 1711, 0 }; + static ulong[] dim294JoeKuoD6Init = { 1, 3, 7, 11, 21, 39, 87, 21, 23, 727, 15, 0 }; + static ulong[] dim295JoeKuoD6Init = { 1, 3, 5, 13, 15, 15, 9, 247, 73, 9, 319, 0 }; + static ulong[] dim296JoeKuoD6Init = { 1, 1, 5, 7, 29, 21, 13, 121, 359, 679, 1659, 0 }; + static ulong[] dim297JoeKuoD6Init = { 1, 1, 7, 13, 19, 63, 79, 99, 107, 13, 137, 0 }; + static ulong[] dim298JoeKuoD6Init = { 1, 1, 7, 15, 1, 43, 117, 79, 305, 285, 1151, 0 }; + static ulong[] dim299JoeKuoD6Init = { 1, 1, 7, 9, 23, 9, 53, 105, 205, 121, 1451, 0 }; + static ulong[] dim300JoeKuoD6Init = { 1, 1, 7, 3, 3, 63, 99, 71, 495, 233, 1633, 0 }; + static ulong[] dim301JoeKuoD6Init = { 1, 3, 7, 11, 17, 5, 99, 211, 409, 911, 1743, 0 }; + static ulong[] dim302JoeKuoD6Init = { 1, 1, 3, 3, 1, 61, 81, 107, 493, 625, 847, 0 }; + static ulong[] dim303JoeKuoD6Init = { 1, 1, 3, 13, 15, 29, 13, 57, 305, 409, 1267, 0 }; + static ulong[] dim304JoeKuoD6Init = { 1, 3, 5, 13, 11, 3, 121, 253, 161, 891, 1463, 0 }; + static ulong[] dim305JoeKuoD6Init = { 1, 1, 7, 13, 23, 1, 125, 7, 273, 221, 2001, 0 }; + static ulong[] dim306JoeKuoD6Init = { 1, 3, 3, 5, 3, 49, 115, 205, 11, 45, 1563, 0 }; + static ulong[] dim307JoeKuoD6Init = { 1, 3, 7, 5, 21, 59, 81, 191, 31, 485, 743, 0 }; + static ulong[] dim308JoeKuoD6Init = { 1, 1, 5, 13, 9, 9, 21, 77, 487, 615, 423, 0 }; + static ulong[] dim309JoeKuoD6Init = { 1, 1, 1, 3, 27, 43, 53, 53, 345, 605, 949, 0 }; + static ulong[] dim310JoeKuoD6Init = { 1, 3, 1, 7, 31, 49, 97, 39, 279, 597, 189, 0 }; + static ulong[] dim311JoeKuoD6Init = { 1, 3, 5, 3, 17, 23, 87, 89, 457, 103, 1969, 0 }; + static ulong[] dim312JoeKuoD6Init = { 1, 1, 7, 3, 21, 45, 19, 127, 49, 231, 273, 0 }; + static ulong[] dim313JoeKuoD6Init = { 1, 3, 5, 11, 13, 15, 127, 83, 185, 553, 537, 0 }; + static ulong[] dim314JoeKuoD6Init = { 1, 3, 7, 11, 19, 45, 77, 123, 471, 731, 605, 0 }; + static ulong[] dim315JoeKuoD6Init = { 1, 1, 7, 5, 11, 25, 123, 25, 51, 501, 2025, 0 }; + static ulong[] dim316JoeKuoD6Init = { 1, 3, 3, 9, 15, 17, 67, 173, 93, 217, 1507, 0 }; + static ulong[] dim317JoeKuoD6Init = { 1, 3, 5, 1, 29, 7, 29, 211, 369, 983, 1331, 0 }; + static ulong[] dim318JoeKuoD6Init = { 1, 1, 5, 7, 17, 63, 1, 9, 493, 1009, 1275, 0 }; + static ulong[] dim319JoeKuoD6Init = { 1, 1, 1, 7, 31, 37, 51, 255, 253, 387, 591, 0 }; + static ulong[] dim320JoeKuoD6Init = { 1, 1, 7, 1, 11, 25, 41, 245, 215, 329, 1877, 0 }; + static ulong[] dim321JoeKuoD6Init = { 1, 1, 5, 7, 17, 21, 115, 63, 31, 435, 39, 0 }; + static ulong[] dim322JoeKuoD6Init = { 1, 1, 7, 9, 1, 17, 95, 139, 505, 365, 825, 0 }; + static ulong[] dim323JoeKuoD6Init = { 1, 3, 7, 7, 13, 31, 105, 167, 203, 337, 813, 0 }; + static ulong[] dim324JoeKuoD6Init = { 1, 3, 5, 11, 3, 7, 111, 91, 491, 93, 1473, 0 }; + static ulong[] dim325JoeKuoD6Init = { 1, 1, 3, 7, 29, 55, 103, 193, 219, 693, 1241, 0 }; + static ulong[] dim326JoeKuoD6Init = { 1, 3, 7, 9, 27, 7, 37, 135, 455, 87, 257, 0 }; + static ulong[] dim327JoeKuoD6Init = { 1, 1, 3, 5, 23, 19, 23, 33, 417, 263, 1693, 0 }; + static ulong[] dim328JoeKuoD6Init = { 1, 3, 3, 7, 29, 39, 127, 221, 305, 717, 989, 0 }; + static ulong[] dim329JoeKuoD6Init = { 1, 3, 3, 1, 27, 21, 49, 51, 355, 241, 1853, 0 }; + static ulong[] dim330JoeKuoD6Init = { 1, 1, 1, 15, 21, 3, 51, 137, 257, 431, 1641, 0 }; + static ulong[] dim331JoeKuoD6Init = { 1, 3, 7, 13, 25, 3, 69, 111, 163, 955, 459, 0 }; + static ulong[] dim332JoeKuoD6Init = { 1, 3, 7, 5, 5, 43, 111, 53, 463, 177, 605, 0 }; + static ulong[] dim333JoeKuoD6Init = { 1, 1, 3, 11, 23, 11, 79, 105, 419, 645, 423, 0 }; + static ulong[] dim334JoeKuoD6Init = { 1, 1, 3, 3, 15, 5, 105, 31, 117, 961, 325, 0 }; + static ulong[] dim335JoeKuoD6Init = { 1, 3, 5, 15, 21, 55, 81, 199, 231, 973, 373, 0 }; + static ulong[] dim336JoeKuoD6Init = { 1, 3, 3, 15, 23, 17, 71, 63, 59, 719, 405, 0 }; + static ulong[] dim337JoeKuoD6Init = { 1, 3, 5, 3, 9, 37, 45, 205, 267, 261, 1173, 3681, 0 }; + static ulong[] dim338JoeKuoD6Init = { 1, 3, 7, 11, 1, 53, 91, 207, 487, 593, 1397, 1255, 0 }; + static ulong[] dim339JoeKuoD6Init = { 1, 1, 3, 7, 17, 3, 111, 145, 237, 667, 1199, 3793, 0 }; + static ulong[] dim340JoeKuoD6Init = { 1, 3, 7, 3, 15, 59, 69, 223, 509, 211, 1431, 2455, 0 }; + static ulong[] dim341JoeKuoD6Init = { 1, 3, 7, 1, 27, 47, 75, 123, 455, 553, 1153, 1675, 0 }; + static ulong[] dim342JoeKuoD6Init = { 1, 1, 7, 13, 17, 3, 85, 103, 205, 443, 1093, 4083, 0 }; + static ulong[] dim343JoeKuoD6Init = { 1, 3, 7, 13, 13, 63, 13, 103, 223, 473, 1125, 1565, 0 }; + static ulong[] dim344JoeKuoD6Init = { 1, 1, 1, 13, 21, 55, 21, 39, 385, 809, 457, 1991, 0 }; + static ulong[] dim345JoeKuoD6Init = { 1, 1, 3, 5, 29, 57, 81, 1, 165, 181, 57, 1463, 0 }; + static ulong[] dim346JoeKuoD6Init = { 1, 3, 7, 7, 21, 29, 59, 127, 393, 981, 577, 2707, 0 }; + static ulong[] dim347JoeKuoD6Init = { 1, 1, 3, 11, 17, 47, 123, 149, 273, 825, 1843, 479, 0 }; + static ulong[] dim348JoeKuoD6Init = { 1, 1, 5, 7, 1, 33, 91, 251, 371, 655, 383, 3123, 0 }; + static ulong[] dim349JoeKuoD6Init = { 1, 3, 1, 7, 3, 55, 15, 195, 345, 1017, 385, 1869, 0 }; + static ulong[] dim350JoeKuoD6Init = { 1, 1, 3, 7, 15, 25, 25, 67, 223, 935, 905, 923, 0 }; + static ulong[] dim351JoeKuoD6Init = { 1, 1, 1, 13, 29, 5, 23, 81, 227, 175, 1025, 355, 0 }; + static ulong[] dim352JoeKuoD6Init = { 1, 1, 7, 9, 25, 27, 43, 85, 401, 955, 989, 3117, 0 }; + static ulong[] dim353JoeKuoD6Init = { 1, 1, 7, 13, 27, 31, 27, 235, 99, 539, 1093, 2821, 0 }; + static ulong[] dim354JoeKuoD6Init = { 1, 3, 5, 7, 13, 19, 45, 231, 203, 489, 1929, 3615, 0 }; + static ulong[] dim355JoeKuoD6Init = { 1, 3, 1, 3, 3, 15, 3, 191, 181, 463, 1247, 2229, 0 }; + static ulong[] dim356JoeKuoD6Init = { 1, 3, 7, 3, 1, 37, 1, 59, 29, 283, 679, 429, 0 }; + static ulong[] dim357JoeKuoD6Init = { 1, 3, 1, 15, 17, 25, 5, 113, 191, 505, 365, 3943, 0 }; + static ulong[] dim358JoeKuoD6Init = { 1, 1, 3, 3, 13, 31, 95, 141, 29, 353, 661, 3637, 0 }; + static ulong[] dim359JoeKuoD6Init = { 1, 3, 1, 1, 5, 53, 19, 9, 81, 497, 1915, 2997, 0 }; + static ulong[] dim360JoeKuoD6Init = { 1, 3, 7, 15, 5, 13, 35, 163, 293, 309, 503, 2387, 0 }; + static ulong[] dim361JoeKuoD6Init = { 1, 1, 5, 3, 11, 25, 127, 27, 435, 247, 1485, 3917, 0 }; + static ulong[] dim362JoeKuoD6Init = { 1, 1, 7, 5, 21, 7, 15, 213, 355, 209, 1107, 1317, 0 }; + static ulong[] dim363JoeKuoD6Init = { 1, 3, 3, 11, 25, 29, 73, 203, 445, 849, 291, 1567, 0 }; + static ulong[] dim364JoeKuoD6Init = { 1, 3, 3, 15, 15, 31, 5, 15, 19, 345, 635, 1815, 0 }; + static ulong[] dim365JoeKuoD6Init = { 1, 1, 3, 3, 19, 21, 15, 95, 111, 167, 1051, 479, 0 }; + static ulong[] dim366JoeKuoD6Init = { 1, 3, 1, 13, 15, 61, 125, 237, 11, 789, 1681, 437, 0 }; + static ulong[] dim367JoeKuoD6Init = { 1, 3, 3, 15, 21, 23, 105, 145, 145, 453, 917, 1727, 0 }; + static ulong[] dim368JoeKuoD6Init = { 1, 1, 7, 11, 9, 37, 27, 91, 199, 561, 1705, 3849, 0 }; + static ulong[] dim369JoeKuoD6Init = { 1, 1, 3, 5, 11, 53, 1, 21, 63, 879, 629, 3219, 0 }; + static ulong[] dim370JoeKuoD6Init = { 1, 1, 3, 13, 3, 5, 121, 17, 511, 809, 627, 2627, 0 }; + static ulong[] dim371JoeKuoD6Init = { 1, 3, 5, 3, 27, 21, 115, 117, 193, 185, 1855, 2473, 0 }; + static ulong[] dim372JoeKuoD6Init = { 1, 3, 1, 9, 11, 37, 79, 123, 391, 715, 573, 699, 0 }; + static ulong[] dim373JoeKuoD6Init = { 1, 3, 1, 9, 5, 35, 105, 5, 55, 347, 1217, 3483, 0 }; + static ulong[] dim374JoeKuoD6Init = { 1, 3, 1, 11, 19, 59, 21, 221, 329, 873, 943, 3679, 0 }; + static ulong[] dim375JoeKuoD6Init = { 1, 3, 1, 13, 21, 57, 119, 33, 111, 581, 1133, 131, 0 }; + static ulong[] dim376JoeKuoD6Init = { 1, 3, 3, 7, 13, 31, 67, 205, 211, 143, 1117, 4067, 0 }; + static ulong[] dim377JoeKuoD6Init = { 1, 3, 7, 9, 9, 53, 71, 251, 41, 875, 691, 3681, 0 }; + static ulong[] dim378JoeKuoD6Init = { 1, 3, 1, 9, 23, 55, 57, 29, 123, 453, 523, 3237, 0 }; + static ulong[] dim379JoeKuoD6Init = { 1, 1, 5, 11, 15, 19, 91, 105, 221, 1005, 169, 461, 0 }; + static ulong[] dim380JoeKuoD6Init = { 1, 1, 1, 11, 7, 61, 49, 41, 337, 739, 699, 2379, 0 }; + static ulong[] dim381JoeKuoD6Init = { 1, 1, 3, 13, 21, 31, 103, 247, 87, 537, 757, 785, 0 }; + static ulong[] dim382JoeKuoD6Init = { 1, 1, 5, 9, 7, 49, 127, 149, 277, 87, 475, 127, 0 }; + static ulong[] dim383JoeKuoD6Init = { 1, 3, 5, 15, 5, 25, 95, 229, 389, 121, 95, 2787, 0 }; + static ulong[] dim384JoeKuoD6Init = { 1, 1, 1, 5, 9, 27, 29, 23, 419, 371, 127, 961, 0 }; + static ulong[] dim385JoeKuoD6Init = { 1, 1, 1, 15, 25, 19, 123, 35, 41, 785, 605, 711, 0 }; + static ulong[] dim386JoeKuoD6Init = { 1, 1, 7, 3, 1, 13, 69, 161, 449, 225, 1795, 2083, 0 }; + static ulong[] dim387JoeKuoD6Init = { 1, 1, 3, 5, 21, 1, 19, 211, 191, 697, 89, 177, 0 }; + static ulong[] dim388JoeKuoD6Init = { 1, 1, 3, 3, 19, 29, 49, 151, 365, 541, 1681, 1943, 0 }; + static ulong[] dim389JoeKuoD6Init = { 1, 3, 7, 7, 9, 5, 75, 109, 243, 769, 755, 2733, 0 }; + static ulong[] dim390JoeKuoD6Init = { 1, 3, 1, 11, 11, 41, 7, 87, 363, 893, 1799, 1303, 0 }; + static ulong[] dim391JoeKuoD6Init = { 1, 1, 1, 9, 11, 5, 19, 101, 41, 401, 1863, 965, 0 }; + static ulong[] dim392JoeKuoD6Init = { 1, 1, 3, 11, 13, 15, 71, 249, 511, 625, 1101, 2615, 0 }; + static ulong[] dim393JoeKuoD6Init = { 1, 3, 3, 9, 31, 35, 85, 107, 383, 201, 1163, 981, 0 }; + static ulong[] dim394JoeKuoD6Init = { 1, 3, 5, 9, 21, 13, 33, 9, 243, 93, 461, 741, 0 }; + static ulong[] dim395JoeKuoD6Init = { 1, 1, 1, 9, 1, 55, 85, 179, 321, 163, 1807, 339, 0 }; + static ulong[] dim396JoeKuoD6Init = { 1, 3, 7, 11, 29, 7, 57, 133, 245, 87, 917, 109, 0 }; + static ulong[] dim397JoeKuoD6Init = { 1, 1, 7, 9, 11, 13, 93, 81, 361, 343, 647, 1113, 0 }; + static ulong[] dim398JoeKuoD6Init = { 1, 3, 7, 5, 23, 57, 117, 105, 221, 697, 1159, 1307, 0 }; + static ulong[] dim399JoeKuoD6Init = { 1, 3, 1, 7, 27, 55, 15, 235, 279, 941, 655, 3975, 0 }; + static ulong[] dim400JoeKuoD6Init = { 1, 3, 1, 9, 27, 47, 45, 41, 361, 135, 379, 2121, 0 }; + static ulong[] dim401JoeKuoD6Init = { 1, 1, 7, 15, 19, 51, 31, 39, 187, 573, 273, 383, 0 }; + static ulong[] dim402JoeKuoD6Init = { 1, 1, 7, 11, 9, 47, 107, 29, 435, 989, 1315, 2815, 0 }; + static ulong[] dim403JoeKuoD6Init = { 1, 3, 1, 3, 21, 31, 7, 41, 45, 115, 1639, 1861, 0 }; + static ulong[] dim404JoeKuoD6Init = { 1, 1, 1, 15, 1, 21, 57, 233, 51, 149, 1251, 1809, 0 }; + static ulong[] dim405JoeKuoD6Init = { 1, 1, 3, 11, 1, 53, 111, 35, 447, 657, 1557, 349, 0 }; + static ulong[] dim406JoeKuoD6Init = { 1, 1, 7, 11, 25, 33, 39, 209, 127, 913, 659, 177, 0 }; + static ulong[] dim407JoeKuoD6Init = { 1, 3, 5, 9, 13, 53, 25, 191, 373, 997, 1413, 2859, 0 }; + static ulong[] dim408JoeKuoD6Init = { 1, 1, 7, 3, 31, 51, 17, 253, 149, 719, 1681, 2713, 0 }; + static ulong[] dim409JoeKuoD6Init = { 1, 1, 7, 1, 23, 49, 9, 211, 381, 321, 2033, 361, 0 }; + static ulong[] dim410JoeKuoD6Init = { 1, 3, 1, 15, 31, 3, 121, 21, 465, 417, 1023, 3921, 0 }; + static ulong[] dim411JoeKuoD6Init = { 1, 1, 7, 1, 17, 49, 101, 37, 429, 877, 505, 821, 0 }; + static ulong[] dim412JoeKuoD6Init = { 1, 3, 1, 7, 23, 59, 33, 127, 43, 987, 1065, 2675, 0 }; + static ulong[] dim413JoeKuoD6Init = { 1, 3, 1, 9, 7, 19, 45, 157, 475, 53, 1223, 523, 0 }; + static ulong[] dim414JoeKuoD6Init = { 1, 3, 7, 9, 23, 61, 31, 133, 85, 623, 871, 965, 0 }; + static ulong[] dim415JoeKuoD6Init = { 1, 3, 1, 7, 3, 17, 21, 197, 377, 819, 661, 1803, 0 }; + static ulong[] dim416JoeKuoD6Init = { 1, 1, 7, 3, 11, 37, 1, 135, 509, 927, 23, 1657, 0 }; + static ulong[] dim417JoeKuoD6Init = { 1, 1, 3, 5, 15, 57, 55, 179, 317, 31, 611, 4057, 0 }; + static ulong[] dim418JoeKuoD6Init = { 1, 1, 5, 5, 29, 57, 93, 105, 103, 157, 701, 249, 0 }; + static ulong[] dim419JoeKuoD6Init = { 1, 1, 3, 13, 27, 41, 23, 213, 363, 911, 85, 2733, 0 }; + static ulong[] dim420JoeKuoD6Init = { 1, 1, 5, 15, 15, 15, 93, 203, 61, 759, 1735, 459, 0 }; + static ulong[] dim421JoeKuoD6Init = { 1, 1, 5, 13, 1, 59, 27, 203, 165, 87, 835, 3647, 0 }; + static ulong[] dim422JoeKuoD6Init = { 1, 3, 3, 5, 25, 57, 43, 209, 71, 35, 1985, 1521, 0 }; + static ulong[] dim423JoeKuoD6Init = { 1, 1, 7, 5, 15, 19, 49, 103, 195, 17, 2041, 1267, 0 }; + static ulong[] dim424JoeKuoD6Init = { 1, 1, 5, 5, 5, 19, 91, 131, 157, 625, 1851, 3691, 0 }; + static ulong[] dim425JoeKuoD6Init = { 1, 1, 1, 9, 9, 47, 3, 195, 25, 1003, 533, 833, 0 }; + static ulong[] dim426JoeKuoD6Init = { 1, 1, 1, 15, 21, 33, 27, 193, 65, 545, 261, 3095, 0 }; + static ulong[] dim427JoeKuoD6Init = { 1, 3, 7, 5, 7, 39, 35, 9, 387, 241, 1015, 1557, 0 }; + static ulong[] dim428JoeKuoD6Init = { 1, 3, 7, 7, 13, 29, 43, 101, 457, 363, 115, 915, 0 }; + static ulong[] dim429JoeKuoD6Init = { 1, 1, 3, 13, 17, 57, 79, 11, 155, 39, 215, 157, 0 }; + static ulong[] dim430JoeKuoD6Init = { 1, 3, 7, 9, 23, 33, 69, 189, 59, 823, 1941, 423, 0 }; + static ulong[] dim431JoeKuoD6Init = { 1, 3, 5, 11, 9, 39, 79, 43, 431, 227, 163, 2653, 0 }; + static ulong[] dim432JoeKuoD6Init = { 1, 3, 1, 3, 5, 63, 55, 141, 207, 349, 1873, 773, 0 }; + static ulong[] dim433JoeKuoD6Init = { 1, 1, 5, 7, 21, 59, 89, 111, 53, 217, 1897, 1619, 0 }; + static ulong[] dim434JoeKuoD6Init = { 1, 1, 5, 9, 7, 27, 127, 247, 183, 925, 989, 1059, 0 }; + static ulong[] dim435JoeKuoD6Init = { 1, 3, 5, 3, 21, 47, 39, 71, 343, 285, 1053, 3007, 0 }; + static ulong[] dim436JoeKuoD6Init = { 1, 1, 3, 11, 1, 7, 27, 109, 19, 325, 157, 2779, 0 }; + static ulong[] dim437JoeKuoD6Init = { 1, 3, 5, 9, 23, 27, 63, 115, 415, 1005, 1159, 3699, 0 }; + static ulong[] dim438JoeKuoD6Init = { 1, 1, 5, 13, 27, 27, 5, 245, 95, 1021, 641, 3875, 0 }; + static ulong[] dim439JoeKuoD6Init = { 1, 3, 5, 9, 5, 9, 53, 183, 379, 251, 1747, 969, 0 }; + static ulong[] dim440JoeKuoD6Init = { 1, 1, 5, 13, 7, 23, 53, 195, 353, 225, 1871, 2131, 0 }; + static ulong[] dim441JoeKuoD6Init = { 1, 3, 7, 3, 21, 5, 25, 253, 59, 821, 1699, 1911, 0 }; + static ulong[] dim442JoeKuoD6Init = { 1, 3, 3, 7, 9, 53, 121, 155, 281, 969, 1943, 2291, 0 }; + static ulong[] dim443JoeKuoD6Init = { 1, 1, 1, 1, 27, 25, 65, 111, 295, 213, 81, 415, 0 }; + static ulong[] dim444JoeKuoD6Init = { 1, 1, 7, 7, 29, 51, 39, 201, 133, 987, 243, 3369, 0 }; + static ulong[] dim445JoeKuoD6Init = { 1, 1, 1, 7, 27, 5, 57, 205, 395, 813, 125, 1293, 0 }; + static ulong[] dim446JoeKuoD6Init = { 1, 1, 7, 13, 15, 19, 57, 11, 151, 405, 2013, 2607, 0 }; + static ulong[] dim447JoeKuoD6Init = { 1, 3, 1, 1, 9, 53, 17, 25, 7, 483, 525, 967, 0 }; + static ulong[] dim448JoeKuoD6Init = { 1, 3, 7, 13, 11, 31, 111, 253, 439, 689, 919, 3563, 0 }; + static ulong[] dim449JoeKuoD6Init = { 1, 1, 5, 9, 13, 59, 123, 69, 339, 17, 297, 2511, 0 }; + static ulong[] dim450JoeKuoD6Init = { 1, 1, 7, 5, 13, 1, 85, 113, 45, 107, 565, 795, 0 }; + static ulong[] dim451JoeKuoD6Init = { 1, 3, 1, 11, 15, 5, 109, 163, 73, 103, 195, 639, 0 }; + static ulong[] dim452JoeKuoD6Init = { 1, 1, 5, 9, 21, 11, 93, 23, 217, 275, 139, 1159, 0 }; + static ulong[] dim453JoeKuoD6Init = { 1, 1, 1, 3, 31, 63, 73, 61, 63, 923, 1237, 3887, 0 }; + static ulong[] dim454JoeKuoD6Init = { 1, 3, 5, 9, 27, 45, 5, 93, 3, 303, 357, 2973, 0 }; + static ulong[] dim455JoeKuoD6Init = { 1, 1, 1, 11, 7, 51, 41, 27, 83, 357, 1679, 2015, 0 }; + static ulong[] dim456JoeKuoD6Init = { 1, 3, 3, 13, 9, 53, 1, 193, 343, 59, 451, 1579, 0 }; + static ulong[] dim457JoeKuoD6Init = { 1, 3, 5, 3, 9, 37, 37, 131, 207, 29, 2027, 733, 0 }; + static ulong[] dim458JoeKuoD6Init = { 1, 1, 5, 7, 3, 61, 51, 221, 71, 659, 1955, 1289, 0 }; + static ulong[] dim459JoeKuoD6Init = { 1, 3, 1, 15, 5, 19, 3, 205, 319, 155, 325, 2643, 0 }; + static ulong[] dim460JoeKuoD6Init = { 1, 1, 5, 9, 3, 15, 1, 247, 323, 143, 37, 2069, 0 }; + static ulong[] dim461JoeKuoD6Init = { 1, 1, 5, 15, 23, 43, 35, 59, 285, 779, 605, 1739, 0 }; + static ulong[] dim462JoeKuoD6Init = { 1, 3, 3, 5, 29, 31, 57, 225, 417, 521, 1337, 3051, 0 }; + static ulong[] dim463JoeKuoD6Init = { 1, 3, 1, 7, 23, 57, 41, 165, 437, 669, 1087, 1275, 0 }; + static ulong[] dim464JoeKuoD6Init = { 1, 1, 3, 5, 1, 51, 25, 233, 449, 503, 1237, 1303, 0 }; + static ulong[] dim465JoeKuoD6Init = { 1, 1, 1, 11, 9, 45, 79, 149, 229, 991, 1725, 395, 0 }; + static ulong[] dim466JoeKuoD6Init = { 1, 1, 5, 11, 31, 37, 13, 117, 19, 939, 1347, 2251, 0 }; + static ulong[] dim467JoeKuoD6Init = { 1, 1, 5, 5, 1, 29, 25, 251, 493, 793, 649, 1197, 0 }; + static ulong[] dim468JoeKuoD6Init = { 1, 3, 3, 11, 5, 53, 49, 33, 37, 937, 497, 361, 0 }; + static ulong[] dim469JoeKuoD6Init = { 1, 1, 1, 1, 5, 57, 19, 141, 115, 371, 1341, 3335, 0 }; + static ulong[] dim470JoeKuoD6Init = { 1, 3, 5, 5, 23, 47, 77, 31, 225, 589, 551, 2625, 0 }; + static ulong[] dim471JoeKuoD6Init = { 1, 1, 3, 1, 25, 37, 29, 213, 283, 207, 385, 2019, 0 }; + static ulong[] dim472JoeKuoD6Init = { 1, 3, 5, 11, 5, 17, 21, 37, 167, 49, 1595, 1647, 0 }; + static ulong[] dim473JoeKuoD6Init = { 1, 1, 3, 15, 29, 15, 79, 203, 329, 627, 1799, 895, 0 }; + static ulong[] dim474JoeKuoD6Init = { 1, 1, 5, 7, 23, 53, 69, 45, 271, 661, 1437, 2429, 0 }; + static ulong[] dim475JoeKuoD6Init = { 1, 3, 1, 1, 21, 7, 115, 233, 267, 873, 2023, 3431, 0 }; + static ulong[] dim476JoeKuoD6Init = { 1, 1, 5, 5, 7, 63, 7, 125, 129, 815, 771, 1233, 0 }; + static ulong[] dim477JoeKuoD6Init = { 1, 3, 5, 9, 5, 29, 121, 203, 373, 137, 1181, 3773, 0 }; + static ulong[] dim478JoeKuoD6Init = { 1, 1, 5, 1, 15, 47, 25, 137, 329, 531, 1957, 1933, 0 }; + static ulong[] dim479JoeKuoD6Init = { 1, 3, 1, 11, 23, 37, 67, 123, 181, 567, 893, 2307, 0 }; + static ulong[] dim480JoeKuoD6Init = { 1, 3, 5, 3, 5, 23, 41, 227, 9, 213, 821, 1689, 0 }; + static ulong[] dim481JoeKuoD6Init = { 1, 1, 1, 13, 29, 33, 23, 241, 199, 753, 1759, 833, 5261, 0 }; + static ulong[] dim482JoeKuoD6Init = { 1, 3, 5, 15, 31, 7, 61, 225, 209, 117, 1983, 395, 3583, 0 }; + static ulong[] dim483JoeKuoD6Init = { 1, 1, 7, 5, 27, 49, 7, 125, 365, 513, 1001, 283, 627, 0 }; + static ulong[] dim484JoeKuoD6Init = { 1, 3, 1, 3, 7, 53, 99, 123, 493, 481, 173, 1483, 805, 0 }; + static ulong[] dim485JoeKuoD6Init = { 1, 1, 5, 7, 15, 1, 57, 19, 391, 847, 1641, 3497, 2807, 0 }; + static ulong[] dim486JoeKuoD6Init = { 1, 1, 7, 11, 19, 49, 77, 139, 275, 115, 1401, 2541, 7239, 0 }; + static ulong[] dim487JoeKuoD6Init = { 1, 1, 1, 15, 11, 13, 13, 211, 119, 317, 271, 1867, 4299, 0 }; + static ulong[] dim488JoeKuoD6Init = { 1, 1, 1, 13, 15, 37, 121, 197, 485, 605, 1025, 3235, 6205, 0 }; + static ulong[] dim489JoeKuoD6Init = { 1, 3, 5, 7, 25, 39, 31, 3, 465, 33, 625, 1069, 6043, 0 }; + static ulong[] dim490JoeKuoD6Init = { 1, 1, 3, 9, 7, 37, 115, 169, 27, 967, 505, 1493, 4333, 0 }; + static ulong[] dim491JoeKuoD6Init = { 1, 1, 3, 13, 1, 51, 19, 117, 365, 587, 1597, 279, 99, 0 }; + static ulong[] dim492JoeKuoD6Init = { 1, 3, 5, 9, 15, 57, 89, 153, 495, 535, 775, 4063, 6049, 0 }; + static ulong[] dim493JoeKuoD6Init = { 1, 1, 3, 1, 9, 7, 111, 43, 225, 677, 1379, 481, 5003, 0 }; + static ulong[] dim494JoeKuoD6Init = { 1, 1, 1, 15, 11, 47, 63, 37, 41, 833, 467, 3795, 5643, 0 }; + static ulong[] dim495JoeKuoD6Init = { 1, 3, 3, 7, 25, 49, 21, 91, 191, 579, 507, 3001, 6549, 0 }; + static ulong[] dim496JoeKuoD6Init = { 1, 3, 5, 9, 25, 17, 17, 153, 467, 359, 1523, 3175, 7307, 0 }; + static ulong[] dim497JoeKuoD6Init = { 1, 3, 7, 7, 29, 57, 51, 145, 71, 515, 495, 1091, 7911, 0 }; + static ulong[] dim498JoeKuoD6Init = { 1, 3, 1, 7, 31, 31, 53, 149, 303, 969, 383, 939, 2659, 0 }; + static ulong[] dim499JoeKuoD6Init = { 1, 1, 7, 9, 1, 21, 15, 145, 9, 199, 695, 2967, 1179, 0 }; + static ulong[] dim500JoeKuoD6Init = { 1, 3, 1, 3, 23, 33, 89, 23, 387, 591, 1543, 3941, 7021, 0 }; + static ulong[] dim501JoeKuoD6Init = { 1, 1, 3, 7, 27, 17, 25, 71, 43, 761, 803, 833, 1023, 0 }; + static ulong[] dim502JoeKuoD6Init = { 1, 1, 1, 3, 11, 25, 3, 171, 377, 843, 1147, 1469, 1773, 0 }; + static ulong[] dim503JoeKuoD6Init = { 1, 1, 3, 15, 1, 13, 65, 197, 381, 683, 895, 2181, 1973, 0 }; + static ulong[] dim504JoeKuoD6Init = { 1, 1, 5, 7, 19, 25, 109, 49, 451, 277, 1417, 2965, 7677, 0 }; + static ulong[] dim505JoeKuoD6Init = { 1, 3, 3, 7, 25, 51, 115, 43, 175, 317, 953, 81, 2533, 0 }; + static ulong[] dim506JoeKuoD6Init = { 1, 3, 7, 15, 27, 57, 5, 181, 489, 369, 1339, 3643, 7911, 0 }; + static ulong[] dim507JoeKuoD6Init = { 1, 3, 1, 5, 21, 11, 87, 81, 85, 5, 867, 3541, 3071, 0 }; + static ulong[] dim508JoeKuoD6Init = { 1, 1, 3, 3, 19, 37, 111, 43, 27, 549, 367, 3021, 6563, 0 }; + static ulong[] dim509JoeKuoD6Init = { 1, 1, 1, 13, 3, 63, 83, 107, 327, 599, 425, 3941, 4319, 0 }; + static ulong[] dim510JoeKuoD6Init = { 1, 3, 7, 15, 5, 37, 127, 169, 117, 987, 1821, 997, 63, 0 }; + static ulong[] dim511JoeKuoD6Init = { 1, 1, 7, 15, 17, 41, 103, 129, 449, 373, 733, 55, 5987, 0 }; + static ulong[] dim512JoeKuoD6Init = { 1, 1, 1, 15, 13, 61, 15, 117, 249, 149, 885, 3723, 5525, 0 }; + static ulong[] dim513JoeKuoD6Init = { 1, 1, 1, 1, 7, 3, 39, 47, 367, 355, 1943, 1035, 2367, 0 }; + static ulong[] dim514JoeKuoD6Init = { 1, 1, 7, 11, 19, 49, 21, 239, 403, 921, 693, 2123, 7387, 0 }; + static ulong[] dim515JoeKuoD6Init = { 1, 3, 5, 5, 23, 45, 13, 81, 105, 91, 1173, 3059, 5969, 0 }; + static ulong[] dim516JoeKuoD6Init = { 1, 1, 1, 5, 1, 31, 73, 253, 395, 941, 1949, 455, 453, 0 }; + static ulong[] dim517JoeKuoD6Init = { 1, 1, 3, 15, 27, 57, 115, 17, 269, 819, 145, 1219, 6471, 0 }; + static ulong[] dim518JoeKuoD6Init = { 1, 3, 3, 7, 29, 19, 9, 67, 501, 87, 883, 1985, 4859, 0 }; + static ulong[] dim519JoeKuoD6Init = { 1, 1, 1, 3, 29, 3, 55, 107, 79, 941, 1437, 3607, 6221, 0 }; + static ulong[] dim520JoeKuoD6Init = { 1, 3, 3, 15, 9, 63, 59, 113, 319, 825, 641, 491, 4015, 0 }; + static ulong[] dim521JoeKuoD6Init = { 1, 1, 1, 3, 21, 59, 55, 107, 215, 167, 315, 81, 3491, 0 }; + static ulong[] dim522JoeKuoD6Init = { 1, 3, 7, 11, 15, 7, 71, 145, 481, 843, 1437, 3809, 7729, 0 }; + static ulong[] dim523JoeKuoD6Init = { 1, 3, 1, 11, 23, 59, 65, 45, 397, 117, 325, 2933, 541, 0 }; + static ulong[] dim524JoeKuoD6Init = { 1, 3, 3, 15, 15, 47, 77, 35, 143, 327, 965, 3409, 1817, 0 }; + static ulong[] dim525JoeKuoD6Init = { 1, 1, 1, 9, 31, 7, 31, 57, 331, 615, 645, 605, 2185, 0 }; + static ulong[] dim526JoeKuoD6Init = { 1, 1, 5, 1, 15, 53, 109, 135, 259, 591, 1419, 3349, 5541, 0 }; + static ulong[] dim527JoeKuoD6Init = { 1, 1, 5, 13, 21, 23, 87, 115, 211, 737, 1433, 3247, 6899, 0 }; + static ulong[] dim528JoeKuoD6Init = { 1, 3, 3, 7, 23, 5, 43, 43, 253, 753, 1305, 2179, 1375, 0 }; + static ulong[] dim529JoeKuoD6Init = { 1, 3, 3, 7, 21, 49, 127, 129, 229, 415, 1593, 2315, 3273, 0 }; + static ulong[] dim530JoeKuoD6Init = { 1, 3, 5, 9, 15, 61, 97, 101, 199, 651, 1421, 2471, 6109, 0 }; + static ulong[] dim531JoeKuoD6Init = { 1, 3, 1, 11, 13, 27, 19, 243, 185, 707, 559, 1687, 981, 0 }; + static ulong[] dim532JoeKuoD6Init = { 1, 3, 7, 3, 5, 9, 101, 55, 39, 811, 1491, 3725, 6691, 0 }; + static ulong[] dim533JoeKuoD6Init = { 1, 1, 5, 9, 27, 33, 41, 61, 271, 695, 1563, 547, 1569, 0 }; + static ulong[] dim534JoeKuoD6Init = { 1, 3, 5, 1, 29, 21, 9, 83, 131, 287, 1505, 2711, 1617, 0 }; + static ulong[] dim535JoeKuoD6Init = { 1, 1, 1, 7, 29, 57, 19, 99, 303, 609, 1397, 3241, 3463, 0 }; + static ulong[] dim536JoeKuoD6Init = { 1, 3, 1, 9, 13, 33, 45, 101, 195, 615, 2017, 2473, 1251, 0 }; + static ulong[] dim537JoeKuoD6Init = { 1, 1, 3, 7, 31, 7, 121, 67, 275, 153, 1189, 2343, 5593, 0 }; + static ulong[] dim538JoeKuoD6Init = { 1, 1, 3, 15, 19, 37, 79, 207, 473, 927, 915, 1971, 8033, 0 }; + static ulong[] dim539JoeKuoD6Init = { 1, 3, 3, 13, 7, 55, 123, 163, 47, 599, 209, 2235, 7643, 0 }; + static ulong[] dim540JoeKuoD6Init = { 1, 1, 3, 11, 31, 3, 31, 69, 61, 257, 11, 845, 2659, 0 }; + static ulong[] dim541JoeKuoD6Init = { 1, 3, 5, 9, 27, 15, 73, 237, 79, 517, 1905, 1595, 6337, 0 }; + static ulong[] dim542JoeKuoD6Init = { 1, 1, 5, 15, 11, 19, 95, 213, 321, 303, 1957, 2291, 5991, 0 }; + static ulong[] dim543JoeKuoD6Init = { 1, 1, 1, 11, 15, 17, 85, 45, 143, 425, 55, 3595, 685, 0 }; + static ulong[] dim544JoeKuoD6Init = { 1, 1, 7, 3, 25, 5, 25, 203, 353, 537, 1921, 1885, 1157, 0 }; + static ulong[] dim545JoeKuoD6Init = { 1, 1, 1, 7, 29, 23, 117, 141, 257, 81, 25, 3237, 7223, 0 }; + static ulong[] dim546JoeKuoD6Init = { 1, 3, 5, 11, 27, 23, 47, 29, 143, 341, 1855, 3973, 5977, 0 }; + static ulong[] dim547JoeKuoD6Init = { 1, 3, 5, 7, 7, 45, 11, 95, 135, 261, 1475, 3723, 6999, 0 }; + static ulong[] dim548JoeKuoD6Init = { 1, 1, 3, 13, 19, 39, 89, 93, 187, 1011, 1319, 67, 399, 0 }; + static ulong[] dim549JoeKuoD6Init = { 1, 1, 5, 5, 17, 1, 91, 69, 405, 815, 225, 2469, 6287, 0 }; + static ulong[] dim550JoeKuoD6Init = { 1, 1, 7, 7, 3, 19, 41, 37, 125, 221, 1011, 3603, 4881, 0 }; + static ulong[] dim551JoeKuoD6Init = { 1, 3, 5, 11, 15, 13, 45, 235, 141, 17, 1991, 2581, 4965, 0 }; + static ulong[] dim552JoeKuoD6Init = { 1, 3, 3, 13, 5, 41, 117, 143, 261, 717, 111, 395, 4381, 0 }; + static ulong[] dim553JoeKuoD6Init = { 1, 3, 7, 5, 15, 47, 117, 197, 147, 117, 295, 2005, 4081, 0 }; + static ulong[] dim554JoeKuoD6Init = { 1, 3, 5, 3, 29, 61, 93, 245, 59, 119, 1121, 2549, 6471, 0 }; + static ulong[] dim555JoeKuoD6Init = { 1, 3, 1, 5, 13, 43, 93, 133, 313, 923, 295, 1239, 6355, 0 }; + static ulong[] dim556JoeKuoD6Init = { 1, 3, 3, 11, 5, 47, 99, 115, 107, 585, 671, 2077, 7005, 0 }; + static ulong[] dim557JoeKuoD6Init = { 1, 1, 1, 9, 13, 31, 79, 253, 245, 597, 1071, 2273, 2481, 0 }; + static ulong[] dim558JoeKuoD6Init = { 1, 1, 7, 1, 25, 3, 39, 47, 201, 187, 419, 3881, 4031, 0 }; + static ulong[] dim559JoeKuoD6Init = { 1, 3, 1, 11, 17, 47, 119, 243, 217, 321, 727, 3227, 6041, 0 }; + static ulong[] dim560JoeKuoD6Init = { 1, 1, 5, 11, 9, 3, 85, 121, 161, 663, 2035, 4073, 7401, 0 }; + static ulong[] dim561JoeKuoD6Init = { 1, 1, 3, 5, 11, 45, 51, 99, 431, 307, 157, 2941, 1645, 0 }; + static ulong[] dim562JoeKuoD6Init = { 1, 3, 3, 7, 7, 43, 77, 19, 169, 535, 1797, 2907, 531, 0 }; + static ulong[] dim563JoeKuoD6Init = { 1, 1, 7, 9, 19, 11, 45, 51, 169, 175, 995, 2231, 147, 0 }; + static ulong[] dim564JoeKuoD6Init = { 1, 1, 5, 1, 3, 25, 123, 11, 387, 757, 1067, 1359, 2227, 0 }; + static ulong[] dim565JoeKuoD6Init = { 1, 1, 5, 15, 13, 41, 45, 135, 49, 391, 1551, 1729, 4799, 0 }; + static ulong[] dim566JoeKuoD6Init = { 1, 1, 7, 9, 3, 11, 109, 59, 217, 507, 47, 1609, 7145, 0 }; + static ulong[] dim567JoeKuoD6Init = { 1, 1, 5, 15, 13, 35, 7, 213, 495, 811, 1403, 3423, 8139, 0 }; + static ulong[] dim568JoeKuoD6Init = { 1, 3, 5, 15, 3, 55, 107, 47, 337, 305, 1869, 943, 7533, 0 }; + static ulong[] dim569JoeKuoD6Init = { 1, 1, 7, 15, 15, 51, 9, 209, 477, 173, 1921, 3295, 4283, 0 }; + static ulong[] dim570JoeKuoD6Init = { 1, 3, 7, 13, 17, 31, 111, 73, 143, 773, 1499, 651, 6659, 0 }; + static ulong[] dim571JoeKuoD6Init = { 1, 1, 1, 1, 17, 5, 1, 95, 347, 613, 49, 7, 2373, 0 }; + static ulong[] dim572JoeKuoD6Init = { 1, 1, 7, 13, 5, 21, 33, 227, 375, 635, 149, 1585, 6159, 0 }; + static ulong[] dim573JoeKuoD6Init = { 1, 3, 7, 5, 25, 7, 121, 185, 129, 1021, 167, 873, 949, 0 }; + static ulong[] dim574JoeKuoD6Init = { 1, 1, 3, 11, 29, 23, 25, 219, 203, 651, 629, 155, 5385, 0 }; + static ulong[] dim575JoeKuoD6Init = { 1, 3, 5, 9, 25, 1, 91, 213, 87, 807, 599, 2527, 6971, 0 }; + static ulong[] dim576JoeKuoD6Init = { 1, 3, 1, 11, 19, 13, 91, 11, 73, 617, 1721, 1803, 3005, 0 }; + static ulong[] dim577JoeKuoD6Init = { 1, 1, 5, 9, 25, 33, 19, 167, 195, 861, 1209, 1887, 3165, 0 }; + static ulong[] dim578JoeKuoD6Init = { 1, 1, 5, 1, 5, 21, 57, 253, 325, 907, 1237, 1037, 3639, 0 }; + static ulong[] dim579JoeKuoD6Init = { 1, 3, 1, 1, 5, 17, 35, 65, 193, 57, 1045, 2117, 7433, 0 }; + static ulong[] dim580JoeKuoD6Init = { 1, 3, 5, 1, 3, 23, 89, 157, 379, 831, 479, 3285, 5107, 0 }; + static ulong[] dim581JoeKuoD6Init = { 1, 3, 3, 1, 5, 35, 57, 107, 465, 81, 387, 1035, 7231, 0 }; + static ulong[] dim582JoeKuoD6Init = { 1, 3, 3, 9, 13, 25, 23, 39, 439, 89, 1651, 781, 6167, 0 }; + static ulong[] dim583JoeKuoD6Init = { 1, 1, 3, 1, 19, 33, 103, 139, 259, 201, 1569, 3453, 5143, 0 }; + static ulong[] dim584JoeKuoD6Init = { 1, 3, 1, 1, 5, 51, 33, 199, 509, 593, 1671, 243, 3455, 0 }; + static ulong[] dim585JoeKuoD6Init = { 1, 1, 5, 15, 31, 15, 81, 173, 357, 447, 595, 1177, 2435, 0 }; + static ulong[] dim586JoeKuoD6Init = { 1, 3, 5, 1, 9, 35, 53, 111, 277, 143, 1837, 385, 7057, 0 }; + static ulong[] dim587JoeKuoD6Init = { 1, 3, 3, 1, 7, 25, 115, 117, 1, 97, 51, 3459, 3057, 0 }; + static ulong[] dim588JoeKuoD6Init = { 1, 1, 3, 5, 11, 63, 85, 69, 1, 943, 279, 4091, 7753, 0 }; + static ulong[] dim589JoeKuoD6Init = { 1, 3, 7, 9, 7, 59, 19, 17, 435, 779, 1049, 2125, 3295, 0 }; + static ulong[] dim590JoeKuoD6Init = { 1, 1, 7, 13, 29, 45, 95, 37, 179, 463, 1503, 417, 1959, 0 }; + static ulong[] dim591JoeKuoD6Init = { 1, 3, 1, 9, 21, 27, 27, 53, 359, 781, 1387, 997, 2123, 0 }; + static ulong[] dim592JoeKuoD6Init = { 1, 3, 3, 13, 17, 39, 103, 175, 131, 973, 1055, 2935, 5671, 0 }; + static ulong[] dim593JoeKuoD6Init = { 1, 1, 3, 9, 7, 41, 55, 133, 223, 1019, 1341, 2559, 4225, 0 }; + static ulong[] dim594JoeKuoD6Init = { 1, 3, 5, 9, 13, 7, 85, 101, 161, 461, 227, 2073, 6483, 0 }; + static ulong[] dim595JoeKuoD6Init = { 1, 3, 3, 1, 11, 27, 67, 125, 287, 229, 1945, 2461, 7111, 0 }; + static ulong[] dim596JoeKuoD6Init = { 1, 1, 7, 3, 23, 59, 39, 137, 421, 245, 955, 1941, 3743, 0 }; + static ulong[] dim597JoeKuoD6Init = { 1, 1, 1, 9, 19, 55, 45, 93, 101, 777, 729, 867, 7123, 0 }; + static ulong[] dim598JoeKuoD6Init = { 1, 1, 5, 5, 21, 27, 49, 125, 245, 271, 1643, 3995, 1845, 0 }; + static ulong[] dim599JoeKuoD6Init = { 1, 1, 3, 15, 21, 63, 113, 157, 123, 347, 333, 2445, 3401, 0 }; + static ulong[] dim600JoeKuoD6Init = { 1, 3, 5, 5, 25, 7, 113, 13, 167, 935, 329, 3483, 4237, 0 }; + static ulong[] dim601JoeKuoD6Init = { 1, 1, 3, 9, 25, 43, 101, 115, 439, 633, 2001, 283, 4415, 0 }; + static ulong[] dim602JoeKuoD6Init = { 1, 3, 1, 7, 7, 39, 41, 201, 423, 351, 563, 653, 6769, 0 }; + static ulong[] dim603JoeKuoD6Init = { 1, 3, 7, 11, 3, 55, 29, 75, 17, 283, 837, 1303, 7917, 0 }; + static ulong[] dim604JoeKuoD6Init = { 1, 3, 1, 11, 9, 17, 47, 39, 399, 645, 575, 805, 5751, 0 }; + static ulong[] dim605JoeKuoD6Init = { 1, 3, 1, 11, 7, 9, 99, 239, 503, 995, 1265, 1651, 2095, 0 }; + static ulong[] dim606JoeKuoD6Init = { 1, 1, 3, 15, 17, 13, 107, 165, 341, 337, 51, 1619, 7801, 0 }; + static ulong[] dim607JoeKuoD6Init = { 1, 3, 1, 3, 19, 55, 73, 105, 97, 557, 1701, 799, 5591, 0 }; + static ulong[] dim608JoeKuoD6Init = { 1, 1, 5, 13, 15, 21, 35, 39, 215, 357, 171, 161, 4527, 0 }; + static ulong[] dim609JoeKuoD6Init = { 1, 3, 3, 15, 19, 7, 27, 153, 399, 415, 2031, 627, 8169, 0 }; + static ulong[] dim610JoeKuoD6Init = { 1, 3, 1, 11, 27, 37, 21, 217, 413, 787, 1637, 1199, 1735, 0 }; + static ulong[] dim611JoeKuoD6Init = { 1, 1, 7, 7, 25, 21, 95, 13, 159, 195, 1493, 1395, 7453, 0 }; + static ulong[] dim612JoeKuoD6Init = { 1, 3, 5, 1, 3, 17, 47, 95, 327, 493, 1501, 2857, 7215, 0 }; + static ulong[] dim613JoeKuoD6Init = { 1, 3, 1, 3, 19, 25, 67, 89, 243, 913, 815, 2471, 6537, 0 }; + static ulong[] dim614JoeKuoD6Init = { 1, 1, 3, 1, 29, 53, 13, 21, 131, 893, 1113, 525, 6723, 0 }; + static ulong[] dim615JoeKuoD6Init = { 1, 1, 5, 1, 25, 45, 97, 167, 465, 65, 1923, 3971, 6365, 0 }; + static ulong[] dim616JoeKuoD6Init = { 1, 1, 7, 7, 3, 7, 113, 85, 371, 143, 201, 1023, 2827, 0 }; + static ulong[] dim617JoeKuoD6Init = { 1, 3, 3, 1, 5, 31, 5, 37, 57, 203, 241, 2473, 593, 0 }; + static ulong[] dim618JoeKuoD6Init = { 1, 3, 1, 5, 25, 59, 87, 207, 227, 103, 491, 1299, 4173, 0 }; + static ulong[] dim619JoeKuoD6Init = { 1, 1, 7, 9, 15, 61, 75, 171, 421, 651, 375, 511, 2723, 0 }; + static ulong[] dim620JoeKuoD6Init = { 1, 3, 7, 11, 9, 19, 55, 5, 365, 7, 1401, 3049, 6669, 0 }; + static ulong[] dim621JoeKuoD6Init = { 1, 1, 1, 5, 31, 37, 97, 105, 343, 999, 1641, 1951, 1395, 0 }; + static ulong[] dim622JoeKuoD6Init = { 1, 3, 5, 1, 5, 13, 83, 189, 395, 335, 1767, 887, 3431, 0 }; + static ulong[] dim623JoeKuoD6Init = { 1, 1, 1, 13, 17, 45, 71, 227, 171, 831, 617, 1203, 6477, 0 }; + static ulong[] dim624JoeKuoD6Init = { 1, 1, 7, 13, 15, 49, 91, 61, 155, 951, 1031, 1153, 5201, 0 }; + static ulong[] dim625JoeKuoD6Init = { 1, 1, 1, 13, 23, 51, 75, 89, 359, 257, 1695, 1739, 5439, 0 }; + static ulong[] dim626JoeKuoD6Init = { 1, 3, 3, 13, 9, 47, 31, 225, 191, 787, 355, 2013, 5897, 0 }; + static ulong[] dim627JoeKuoD6Init = { 1, 1, 7, 3, 7, 41, 91, 83, 9, 643, 1589, 3491, 135, 0 }; + static ulong[] dim628JoeKuoD6Init = { 1, 3, 5, 9, 5, 29, 29, 249, 181, 641, 17, 3187, 6767, 0 }; + static ulong[] dim629JoeKuoD6Init = { 1, 1, 7, 13, 25, 17, 91, 187, 61, 305, 199, 2397, 2287, 0 }; + static ulong[] dim630JoeKuoD6Init = { 1, 1, 7, 1, 25, 45, 85, 35, 361, 353, 631, 1113, 135, 0 }; + static ulong[] dim631JoeKuoD6Init = { 1, 3, 7, 9, 13, 11, 107, 67, 127, 523, 1129, 81, 7627, 0 }; + static ulong[] dim632JoeKuoD6Init = { 1, 3, 1, 7, 17, 43, 89, 225, 45, 597, 1683, 943, 3801, 0 }; + static ulong[] dim633JoeKuoD6Init = { 1, 3, 7, 1, 31, 47, 37, 31, 269, 731, 1817, 3977, 7107, 0 }; + static ulong[] dim634JoeKuoD6Init = { 1, 1, 5, 5, 21, 37, 93, 219, 117, 369, 561, 4031, 365, 0 }; + static ulong[] dim635JoeKuoD6Init = { 1, 1, 5, 13, 31, 21, 65, 237, 157, 775, 843, 1725, 583, 0 }; + static ulong[] dim636JoeKuoD6Init = { 1, 1, 1, 11, 11, 31, 15, 217, 377, 395, 1633, 3841, 4417, 0 }; + static ulong[] dim637JoeKuoD6Init = { 1, 3, 7, 9, 23, 23, 93, 109, 265, 379, 1341, 1857, 5567, 0 }; + static ulong[] dim638JoeKuoD6Init = { 1, 1, 7, 1, 13, 37, 109, 121, 7, 157, 1639, 483, 1433, 0 }; + static ulong[] dim639JoeKuoD6Init = { 1, 1, 1, 3, 5, 37, 29, 107, 77, 771, 1631, 3051, 8097, 0 }; + static ulong[] dim640JoeKuoD6Init = { 1, 3, 7, 13, 27, 5, 59, 89, 401, 223, 1013, 1089, 3407, 0 }; + static ulong[] dim641JoeKuoD6Init = { 1, 1, 5, 5, 11, 47, 113, 237, 69, 833, 845, 179, 3687, 0 }; + static ulong[] dim642JoeKuoD6Init = { 1, 3, 7, 3, 19, 43, 117, 223, 373, 145, 463, 1719, 3621, 0 }; + static ulong[] dim643JoeKuoD6Init = { 1, 1, 3, 7, 5, 53, 5, 53, 385, 723, 809, 1785, 6495, 0 }; + static ulong[] dim644JoeKuoD6Init = { 1, 3, 7, 5, 3, 63, 125, 63, 275, 575, 1461, 821, 5607, 0 }; + static ulong[] dim645JoeKuoD6Init = { 1, 1, 5, 9, 17, 33, 71, 145, 215, 741, 1843, 1987, 4263, 0 }; + static ulong[] dim646JoeKuoD6Init = { 1, 3, 5, 3, 31, 63, 29, 233, 441, 447, 853, 3937, 4747, 0 }; + static ulong[] dim647JoeKuoD6Init = { 1, 3, 3, 15, 21, 35, 15, 221, 63, 481, 403, 2795, 5533, 0 }; + static ulong[] dim648JoeKuoD6Init = { 1, 3, 7, 9, 1, 47, 123, 129, 365, 23, 1975, 1179, 7957, 0 }; + static ulong[] dim649JoeKuoD6Init = { 1, 3, 1, 3, 11, 23, 119, 229, 141, 687, 1639, 2105, 319, 0 }; + static ulong[] dim650JoeKuoD6Init = { 1, 3, 1, 11, 17, 49, 3, 113, 297, 727, 1135, 2657, 187, 0 }; + static ulong[] dim651JoeKuoD6Init = { 1, 3, 7, 5, 5, 31, 83, 173, 159, 389, 1373, 3049, 827, 0 }; + static ulong[] dim652JoeKuoD6Init = { 1, 1, 1, 15, 27, 51, 107, 97, 119, 831, 247, 2613, 7125, 0 }; + static ulong[] dim653JoeKuoD6Init = { 1, 1, 3, 7, 23, 53, 35, 181, 81, 213, 1135, 2901, 1555, 0 }; + static ulong[] dim654JoeKuoD6Init = { 1, 3, 5, 7, 9, 45, 25, 137, 399, 345, 339, 1869, 3469, 0 }; + static ulong[] dim655JoeKuoD6Init = { 1, 1, 3, 5, 25, 49, 71, 139, 473, 883, 677, 1229, 6661, 0 }; + static ulong[] dim656JoeKuoD6Init = { 1, 3, 5, 13, 1, 55, 31, 67, 321, 221, 1425, 1335, 3805, 0 }; + static ulong[] dim657JoeKuoD6Init = { 1, 1, 5, 9, 7, 31, 53, 169, 67, 509, 1155, 1739, 615, 0 }; + static ulong[] dim658JoeKuoD6Init = { 1, 3, 7, 9, 1, 13, 49, 39, 263, 215, 767, 2881, 1517, 0 }; + static ulong[] dim659JoeKuoD6Init = { 1, 1, 5, 5, 27, 41, 15, 5, 203, 539, 463, 1983, 1949, 0 }; + static ulong[] dim660JoeKuoD6Init = { 1, 3, 3, 1, 21, 3, 101, 225, 255, 805, 1035, 813, 8125, 0 }; + static ulong[] dim661JoeKuoD6Init = { 1, 3, 1, 1, 17, 59, 55, 107, 117, 489, 541, 689, 581, 0 }; + static ulong[] dim662JoeKuoD6Init = { 1, 3, 7, 15, 17, 57, 75, 135, 295, 11, 1415, 1843, 7079, 0 }; + static ulong[] dim663JoeKuoD6Init = { 1, 1, 5, 5, 17, 49, 49, 91, 227, 295, 1501, 3723, 5879, 0 }; + static ulong[] dim664JoeKuoD6Init = { 1, 3, 5, 9, 27, 17, 63, 127, 503, 869, 53, 627, 5085, 0 }; + static ulong[] dim665JoeKuoD6Init = { 1, 3, 7, 3, 25, 25, 1, 83, 461, 1019, 1737, 1901, 2611, 0 }; + static ulong[] dim666JoeKuoD6Init = { 1, 3, 1, 11, 23, 59, 59, 235, 33, 747, 1141, 2429, 3833, 0 }; + static ulong[] dim667JoeKuoD6Init = { 1, 1, 7, 9, 29, 55, 85, 179, 385, 645, 1009, 1193, 5643, 0 }; + static ulong[] dim668JoeKuoD6Init = { 1, 1, 5, 15, 29, 11, 77, 147, 453, 655, 469, 2727, 6205, 0 }; + static ulong[] dim669JoeKuoD6Init = { 1, 3, 5, 3, 5, 13, 103, 115, 445, 87, 1803, 601, 5159, 0 }; + static ulong[] dim670JoeKuoD6Init = { 1, 1, 7, 5, 1, 37, 55, 129, 5, 387, 51, 3585, 6771, 0 }; + static ulong[] dim671JoeKuoD6Init = { 1, 3, 3, 15, 15, 15, 21, 13, 67, 391, 1745, 1137, 7039, 0 }; + static ulong[] dim672JoeKuoD6Init = { 1, 3, 7, 9, 25, 1, 83, 135, 275, 11, 339, 269, 6121, 0 }; + static ulong[] dim673JoeKuoD6Init = { 1, 1, 5, 3, 27, 11, 109, 15, 499, 489, 615, 1713, 7713, 0 }; + static ulong[] dim674JoeKuoD6Init = { 1, 3, 7, 15, 25, 53, 1, 169, 275, 623, 411, 195, 6331, 0 }; + static ulong[] dim675JoeKuoD6Init = { 1, 1, 3, 7, 3, 5, 73, 97, 407, 687, 311, 2141, 6687, 0 }; + static ulong[] dim676JoeKuoD6Init = { 1, 3, 5, 3, 27, 43, 123, 143, 99, 963, 2029, 3759, 1483, 0 }; + static ulong[] dim677JoeKuoD6Init = { 1, 1, 5, 3, 5, 43, 11, 51, 423, 111, 875, 3605, 4023, 0 }; + static ulong[] dim678JoeKuoD6Init = { 1, 1, 1, 15, 25, 11, 89, 21, 425, 585, 1983, 3481, 7329, 0 }; + static ulong[] dim679JoeKuoD6Init = { 1, 3, 7, 3, 1, 5, 107, 29, 285, 929, 663, 319, 3139, 0 }; + static ulong[] dim680JoeKuoD6Init = { 1, 3, 3, 7, 7, 37, 21, 51, 385, 539, 59, 1595, 9, 0 }; + static ulong[] dim681JoeKuoD6Init = { 1, 3, 3, 1, 9, 21, 87, 149, 21, 211, 787, 351, 5597, 0 }; + static ulong[] dim682JoeKuoD6Init = { 1, 3, 1, 11, 1, 41, 21, 65, 7, 83, 693, 1905, 5935, 0 }; + static ulong[] dim683JoeKuoD6Init = { 1, 3, 3, 11, 17, 3, 55, 205, 461, 897, 273, 2849, 1685, 0 }; + static ulong[] dim684JoeKuoD6Init = { 1, 3, 7, 5, 23, 15, 121, 129, 387, 967, 1131, 3451, 3545, 0 }; + static ulong[] dim685JoeKuoD6Init = { 1, 1, 7, 11, 5, 29, 59, 69, 27, 699, 1639, 2137, 6305, 0 }; + static ulong[] dim686JoeKuoD6Init = { 1, 3, 7, 7, 23, 23, 69, 205, 399, 661, 1187, 1639, 5099, 0 }; + static ulong[] dim687JoeKuoD6Init = { 1, 3, 5, 5, 31, 17, 37, 173, 371, 649, 449, 243, 3665, 0 }; + static ulong[] dim688JoeKuoD6Init = { 1, 3, 5, 1, 21, 5, 51, 105, 173, 699, 475, 3489, 7411, 0 }; + static ulong[] dim689JoeKuoD6Init = { 1, 1, 3, 13, 17, 41, 55, 131, 359, 461, 1885, 4045, 3615, 0 }; + static ulong[] dim690JoeKuoD6Init = { 1, 3, 7, 11, 27, 33, 79, 127, 227, 293, 607, 1713, 167, 0 }; + static ulong[] dim691JoeKuoD6Init = { 1, 3, 3, 1, 5, 9, 13, 59, 425, 319, 1813, 2905, 4647, 0 }; + static ulong[] dim692JoeKuoD6Init = { 1, 3, 5, 5, 13, 59, 69, 95, 379, 119, 1175, 1853, 7573, 0 }; + static ulong[] dim693JoeKuoD6Init = { 1, 3, 5, 3, 3, 47, 51, 203, 395, 623, 13, 3369, 663, 0 }; + static ulong[] dim694JoeKuoD6Init = { 1, 1, 5, 3, 3, 39, 107, 203, 125, 627, 1817, 1101, 935, 0 }; + static ulong[] dim695JoeKuoD6Init = { 1, 1, 1, 5, 7, 31, 71, 141, 507, 101, 913, 567, 753, 0 }; + static ulong[] dim696JoeKuoD6Init = { 1, 3, 5, 11, 1, 25, 81, 211, 79, 277, 1445, 783, 5, 0 }; + static ulong[] dim697JoeKuoD6Init = { 1, 1, 7, 3, 7, 9, 63, 87, 335, 413, 1595, 2313, 5883, 0 }; + static ulong[] dim698JoeKuoD6Init = { 1, 1, 1, 11, 21, 61, 87, 119, 155, 259, 1629, 2565, 5975, 0 }; + static ulong[] dim699JoeKuoD6Init = { 1, 3, 1, 3, 29, 59, 57, 205, 65, 779, 1433, 2845, 1311, 0 }; + static ulong[] dim700JoeKuoD6Init = { 1, 3, 3, 3, 29, 59, 1, 125, 493, 25, 315, 1171, 4837, 0 }; + static ulong[] dim701JoeKuoD6Init = { 1, 1, 1, 11, 1, 47, 119, 141, 95, 87, 1497, 3613, 5009, 0 }; + static ulong[] dim702JoeKuoD6Init = { 1, 3, 5, 5, 7, 19, 61, 233, 321, 585, 547, 179, 6787, 0 }; + static ulong[] dim703JoeKuoD6Init = { 1, 3, 1, 7, 15, 29, 51, 177, 189, 435, 89, 2507, 4975, 0 }; + static ulong[] dim704JoeKuoD6Init = { 1, 3, 7, 5, 19, 49, 125, 145, 329, 975, 717, 161, 1099, 0 }; + static ulong[] dim705JoeKuoD6Init = { 1, 3, 3, 13, 1, 21, 81, 63, 263, 597, 1713, 1759, 1745, 0 }; + static ulong[] dim706JoeKuoD6Init = { 1, 1, 3, 9, 17, 61, 19, 119, 229, 25, 1759, 343, 7925, 0 }; + static ulong[] dim707JoeKuoD6Init = { 1, 1, 1, 9, 27, 49, 51, 149, 453, 717, 1791, 2529, 331, 0 }; + static ulong[] dim708JoeKuoD6Init = { 1, 3, 1, 7, 11, 15, 125, 237, 291, 111, 1051, 3739, 3805, 0 }; + static ulong[] dim709JoeKuoD6Init = { 1, 1, 7, 9, 7, 63, 49, 73, 53, 429, 1167, 2019, 911, 0 }; + static ulong[] dim710JoeKuoD6Init = { 1, 3, 5, 5, 29, 17, 3, 193, 243, 29, 2007, 1881, 7143, 0 }; + static ulong[] dim711JoeKuoD6Init = { 1, 3, 3, 3, 5, 19, 127, 149, 57, 601, 1263, 1909, 3835, 0 }; + static ulong[] dim712JoeKuoD6Init = { 1, 1, 1, 5, 25, 43, 21, 115, 193, 735, 571, 401, 1573, 0 }; + static ulong[] dim713JoeKuoD6Init = { 1, 3, 5, 9, 25, 41, 53, 165, 5, 575, 1381, 995, 5851, 0 }; + static ulong[] dim714JoeKuoD6Init = { 1, 1, 5, 15, 21, 43, 25, 125, 49, 207, 345, 2981, 709, 0 }; + static ulong[] dim715JoeKuoD6Init = { 1, 1, 3, 5, 29, 37, 89, 145, 123, 771, 631, 3259, 1431, 0 }; + static ulong[] dim716JoeKuoD6Init = { 1, 1, 3, 3, 1, 37, 67, 243, 335, 913, 1927, 3027, 6059, 0 }; + static ulong[] dim717JoeKuoD6Init = { 1, 1, 5, 15, 11, 31, 61, 59, 511, 543, 1747, 3329, 599, 0 }; + static ulong[] dim718JoeKuoD6Init = { 1, 1, 7, 13, 17, 31, 9, 143, 381, 713, 135, 1037, 5981, 0 }; + static ulong[] dim719JoeKuoD6Init = { 1, 1, 7, 11, 25, 7, 79, 3, 403, 979, 1021, 457, 999, 0 }; + static ulong[] dim720JoeKuoD6Init = { 1, 3, 3, 11, 3, 19, 127, 135, 255, 645, 437, 3793, 5809, 0 }; + static ulong[] dim721JoeKuoD6Init = { 1, 3, 7, 1, 5, 59, 69, 135, 307, 769, 307, 3225, 2869, 0 }; + static ulong[] dim722JoeKuoD6Init = { 1, 3, 5, 3, 9, 33, 121, 41, 245, 1009, 2039, 925, 3341, 0 }; + static ulong[] dim723JoeKuoD6Init = { 1, 3, 3, 15, 19, 23, 55, 155, 389, 817, 475, 1005, 1971, 0 }; + static ulong[] dim724JoeKuoD6Init = { 1, 3, 5, 7, 11, 17, 7, 113, 249, 241, 1149, 2359, 8037, 0 }; + static ulong[] dim725JoeKuoD6Init = { 1, 3, 5, 5, 23, 59, 115, 5, 503, 221, 485, 3857, 4399, 0 }; + static ulong[] dim726JoeKuoD6Init = { 1, 3, 7, 3, 5, 53, 119, 107, 103, 99, 1313, 623, 3073, 0 }; + static ulong[] dim727JoeKuoD6Init = { 1, 3, 1, 13, 7, 21, 85, 47, 345, 355, 607, 2213, 2489, 0 }; + static ulong[] dim728JoeKuoD6Init = { 1, 1, 5, 11, 7, 51, 43, 53, 281, 311, 1221, 3919, 4821, 0 }; + static ulong[] dim729JoeKuoD6Init = { 1, 1, 7, 9, 21, 15, 105, 251, 367, 311, 1247, 2357, 5411, 0 }; + static ulong[] dim730JoeKuoD6Init = { 1, 3, 5, 5, 17, 21, 1, 213, 505, 97, 603, 4057, 6853, 0 }; + static ulong[] dim731JoeKuoD6Init = { 1, 3, 7, 5, 21, 3, 105, 61, 5, 39, 461, 351, 4379, 0 }; + static ulong[] dim732JoeKuoD6Init = { 1, 3, 3, 9, 15, 39, 87, 21, 393, 525, 1699, 2427, 211, 0 }; + static ulong[] dim733JoeKuoD6Init = { 1, 1, 5, 9, 21, 25, 53, 175, 387, 83, 1155, 1225, 5681, 0 }; + static ulong[] dim734JoeKuoD6Init = { 1, 3, 1, 15, 7, 49, 43, 127, 257, 499, 79, 33, 2843, 0 }; + static ulong[] dim735JoeKuoD6Init = { 1, 3, 7, 15, 21, 17, 89, 175, 161, 371, 389, 2289, 7751, 0 }; + static ulong[] dim736JoeKuoD6Init = { 1, 1, 7, 3, 19, 23, 65, 5, 149, 563, 1237, 3445, 6817, 0 }; + static ulong[] dim737JoeKuoD6Init = { 1, 3, 5, 11, 23, 21, 65, 11, 329, 323, 551, 3859, 749, 0 }; + static ulong[] dim738JoeKuoD6Init = { 1, 3, 1, 9, 13, 23, 11, 169, 203, 349, 1733, 2537, 3777, 0 }; + static ulong[] dim739JoeKuoD6Init = { 1, 3, 7, 7, 5, 19, 47, 81, 215, 677, 1861, 2703, 6373, 0 }; + static ulong[] dim740JoeKuoD6Init = { 1, 1, 5, 5, 11, 5, 19, 151, 215, 695, 1347, 1359, 1979, 0 }; + static ulong[] dim741JoeKuoD6Init = { 1, 1, 7, 3, 1, 59, 11, 185, 379, 247, 1885, 1819, 637, 0 }; + static ulong[] dim742JoeKuoD6Init = { 1, 3, 7, 3, 21, 3, 53, 161, 49, 697, 113, 3561, 95, 0 }; + static ulong[] dim743JoeKuoD6Init = { 1, 3, 7, 7, 29, 15, 85, 123, 415, 41, 703, 1501, 6939, 0 }; + static ulong[] dim744JoeKuoD6Init = { 1, 1, 7, 5, 7, 37, 75, 185, 115, 423, 625, 3557, 7851, 0 }; + static ulong[] dim745JoeKuoD6Init = { 1, 1, 1, 7, 11, 35, 119, 131, 331, 197, 1939, 1951, 7957, 0 }; + static ulong[] dim746JoeKuoD6Init = { 1, 1, 5, 3, 9, 43, 93, 11, 97, 483, 131, 1095, 601, 0 }; + static ulong[] dim747JoeKuoD6Init = { 1, 1, 1, 15, 11, 43, 49, 205, 393, 921, 625, 359, 3997, 0 }; + static ulong[] dim748JoeKuoD6Init = { 1, 1, 3, 7, 31, 21, 27, 231, 159, 67, 1127, 2153, 6291, 0 }; + static ulong[] dim749JoeKuoD6Init = { 1, 3, 1, 1, 13, 15, 45, 85, 155, 763, 1341, 9, 6229, 0 }; + static ulong[] dim750JoeKuoD6Init = { 1, 3, 7, 15, 9, 21, 47, 67, 207, 385, 401, 1665, 7849, 0 }; + static ulong[] dim751JoeKuoD6Init = { 1, 1, 5, 9, 13, 59, 89, 163, 19, 997, 2021, 3301, 2945, 0 }; + static ulong[] dim752JoeKuoD6Init = { 1, 1, 3, 15, 17, 9, 33, 117, 33, 701, 73, 2955, 1781, 0 }; + static ulong[] dim753JoeKuoD6Init = { 1, 1, 3, 7, 3, 11, 81, 209, 131, 247, 1927, 3997, 1709, 0 }; + static ulong[] dim754JoeKuoD6Init = { 1, 1, 3, 5, 21, 47, 85, 163, 247, 273, 545, 3477, 4565, 0 }; + static ulong[] dim755JoeKuoD6Init = { 1, 1, 1, 15, 3, 5, 55, 171, 501, 149, 121, 2317, 2023, 0 }; + static ulong[] dim756JoeKuoD6Init = { 1, 1, 5, 1, 25, 31, 25, 171, 471, 149, 49, 3059, 7871, 0 }; + static ulong[] dim757JoeKuoD6Init = { 1, 3, 3, 1, 3, 39, 91, 75, 183, 115, 869, 4005, 1443, 0 }; + static ulong[] dim758JoeKuoD6Init = { 1, 1, 1, 13, 31, 37, 3, 23, 443, 177, 219, 1683, 7063, 0 }; + static ulong[] dim759JoeKuoD6Init = { 1, 1, 1, 11, 17, 51, 111, 157, 455, 415, 1171, 531, 7289, 0 }; + static ulong[] dim760JoeKuoD6Init = { 1, 1, 7, 13, 3, 45, 103, 185, 63, 299, 1471, 3579, 3751, 0 }; + static ulong[] dim761JoeKuoD6Init = { 1, 1, 7, 7, 25, 45, 91, 145, 285, 525, 1675, 665, 883, 0 }; + static ulong[] dim762JoeKuoD6Init = { 1, 3, 7, 5, 23, 23, 33, 47, 271, 65, 1009, 2363, 7231, 0 }; + static ulong[] dim763JoeKuoD6Init = { 1, 3, 1, 11, 25, 3, 13, 105, 105, 649, 531, 535, 6019, 0 }; + static ulong[] dim764JoeKuoD6Init = { 1, 3, 3, 5, 9, 1, 9, 15, 131, 793, 1841, 2249, 5775, 0 }; + static ulong[] dim765JoeKuoD6Init = { 1, 1, 7, 7, 27, 35, 125, 249, 125, 973, 233, 229, 8165, 0 }; + static ulong[] dim766JoeKuoD6Init = { 1, 3, 1, 7, 19, 1, 39, 239, 159, 627, 601, 1537, 7473, 0 }; + static ulong[] dim767JoeKuoD6Init = { 1, 1, 3, 3, 1, 45, 99, 149, 205, 277, 1701, 121, 1577, 0 }; + static ulong[] dim768JoeKuoD6Init = { 1, 3, 7, 15, 9, 43, 7, 139, 331, 995, 647, 2707, 4493, 0 }; + static ulong[] dim769JoeKuoD6Init = { 1, 3, 3, 13, 19, 31, 67, 213, 355, 85, 1829, 2897, 6799, 0 }; + static ulong[] dim770JoeKuoD6Init = { 1, 3, 7, 1, 29, 51, 49, 209, 257, 913, 811, 895, 8051, 0 }; + static ulong[] dim771JoeKuoD6Init = { 1, 1, 3, 3, 31, 33, 19, 37, 297, 473, 1987, 3433, 1981, 0 }; + static ulong[] dim772JoeKuoD6Init = { 1, 1, 1, 13, 1, 3, 127, 183, 241, 941, 973, 577, 6891, 0 }; + static ulong[] dim773JoeKuoD6Init = { 1, 1, 7, 15, 31, 21, 125, 193, 23, 731, 493, 3173, 4381, 0 }; + static ulong[] dim774JoeKuoD6Init = { 1, 3, 3, 13, 23, 31, 65, 59, 63, 285, 1191, 3005, 2211, 0 }; + static ulong[] dim775JoeKuoD6Init = { 1, 1, 3, 3, 13, 11, 121, 153, 199, 359, 1159, 363, 3477, 0 }; + static ulong[] dim776JoeKuoD6Init = { 1, 1, 3, 3, 29, 27, 105, 215, 143, 365, 369, 3341, 5017, 0 }; + static ulong[] dim777JoeKuoD6Init = { 1, 1, 5, 9, 23, 43, 119, 89, 307, 607, 1087, 287, 7305, 0 }; + static ulong[] dim778JoeKuoD6Init = { 1, 1, 7, 3, 19, 9, 115, 133, 387, 717, 687, 3447, 201, 0 }; + static ulong[] dim779JoeKuoD6Init = { 1, 3, 1, 1, 23, 7, 81, 77, 483, 725, 1499, 1565, 8073, 0 }; + static ulong[] dim780JoeKuoD6Init = { 1, 3, 1, 9, 23, 25, 119, 247, 195, 205, 1851, 2463, 6827, 0 }; + static ulong[] dim781JoeKuoD6Init = { 1, 3, 5, 9, 17, 51, 11, 233, 115, 719, 1333, 3829, 4941, 0 }; + static ulong[] dim782JoeKuoD6Init = { 1, 1, 3, 13, 25, 17, 103, 241, 133, 237, 1375, 4005, 7853, 0 }; + static ulong[] dim783JoeKuoD6Init = { 1, 3, 7, 1, 19, 31, 115, 193, 305, 1, 1167, 325, 985, 0 }; + static ulong[] dim784JoeKuoD6Init = { 1, 1, 3, 15, 13, 11, 33, 27, 453, 941, 293, 2819, 3247, 0 }; + static ulong[] dim785JoeKuoD6Init = { 1, 3, 3, 3, 11, 27, 37, 95, 371, 441, 1347, 13, 4219, 0 }; + static ulong[] dim786JoeKuoD6Init = { 1, 3, 1, 11, 31, 39, 17, 63, 323, 1013, 479, 4077, 313, 0 }; + static ulong[] dim787JoeKuoD6Init = { 1, 3, 7, 15, 3, 59, 121, 19, 43, 351, 285, 2239, 8117, 0 }; + static ulong[] dim788JoeKuoD6Init = { 1, 1, 3, 3, 7, 7, 13, 31, 403, 925, 789, 275, 6959, 0 }; + static ulong[] dim789JoeKuoD6Init = { 1, 1, 1, 9, 3, 11, 89, 195, 393, 301, 517, 1675, 963, 0 }; + static ulong[] dim790JoeKuoD6Init = { 1, 3, 1, 13, 17, 63, 79, 17, 127, 119, 1127, 2121, 7545, 0 }; + static ulong[] dim791JoeKuoD6Init = { 1, 3, 5, 5, 29, 15, 97, 183, 157, 319, 1047, 895, 7297, 0 }; + static ulong[] dim792JoeKuoD6Init = { 1, 3, 1, 3, 25, 37, 101, 233, 275, 705, 1147, 1511, 231, 0 }; + static ulong[] dim793JoeKuoD6Init = { 1, 3, 1, 11, 3, 63, 45, 219, 315, 905, 9, 3105, 785, 0 }; + static ulong[] dim794JoeKuoD6Init = { 1, 1, 3, 1, 17, 27, 89, 15, 337, 981, 403, 1609, 349, 0 }; + static ulong[] dim795JoeKuoD6Init = { 1, 3, 1, 5, 27, 21, 39, 209, 461, 211, 71, 1413, 1185, 0 }; + static ulong[] dim796JoeKuoD6Init = { 1, 1, 3, 1, 11, 9, 19, 229, 403, 323, 1651, 475, 1207, 0 }; + static ulong[] dim797JoeKuoD6Init = { 1, 3, 7, 5, 31, 13, 39, 9, 365, 857, 1715, 3831, 2467, 0 }; + static ulong[] dim798JoeKuoD6Init = { 1, 1, 7, 1, 31, 41, 25, 101, 297, 143, 345, 2097, 1679, 0 }; + static ulong[] dim799JoeKuoD6Init = { 1, 3, 5, 7, 27, 61, 77, 107, 291, 265, 759, 933, 2529, 0 }; + static ulong[] dim800JoeKuoD6Init = { 1, 3, 7, 11, 15, 51, 31, 191, 39, 469, 1711, 1215, 7603, 0 }; + static ulong[] dim801JoeKuoD6Init = { 1, 1, 5, 13, 19, 27, 121, 235, 475, 11, 1193, 543, 5689, 0 }; + static ulong[] dim802JoeKuoD6Init = { 1, 3, 5, 11, 19, 1, 97, 85, 393, 971, 1915, 3487, 7569, 0 }; + static ulong[] dim803JoeKuoD6Init = { 1, 3, 7, 9, 21, 25, 81, 197, 9, 403, 1305, 2977, 6261, 0 }; + static ulong[] dim804JoeKuoD6Init = { 1, 3, 3, 15, 5, 3, 5, 91, 133, 957, 437, 3821, 4395, 0 }; + static ulong[] dim805JoeKuoD6Init = { 1, 3, 7, 7, 23, 47, 85, 139, 511, 389, 461, 2967, 7305, 0 }; + static ulong[] dim806JoeKuoD6Init = { 1, 3, 5, 5, 13, 3, 33, 171, 391, 109, 197, 2097, 5357, 0 }; + static ulong[] dim807JoeKuoD6Init = { 1, 3, 7, 15, 31, 61, 7, 61, 175, 455, 1867, 2829, 197, 0 }; + static ulong[] dim808JoeKuoD6Init = { 1, 3, 7, 13, 21, 33, 119, 97, 297, 69, 1503, 2887, 3785, 0 }; + static ulong[] dim809JoeKuoD6Init = { 1, 3, 3, 7, 1, 63, 105, 53, 443, 775, 1855, 2635, 4453, 0 }; + static ulong[] dim810JoeKuoD6Init = { 1, 1, 7, 11, 1, 13, 99, 227, 421, 739, 583, 4011, 2095, 0 }; + static ulong[] dim811JoeKuoD6Init = { 1, 1, 7, 11, 7, 21, 125, 45, 411, 621, 137, 259, 3401, 0 }; + static ulong[] dim812JoeKuoD6Init = { 1, 3, 3, 7, 9, 15, 47, 213, 71, 725, 2015, 3119, 3295, 0 }; + static ulong[] dim813JoeKuoD6Init = { 1, 1, 7, 7, 21, 63, 83, 63, 29, 969, 119, 3535, 989, 0 }; + static ulong[] dim814JoeKuoD6Init = { 1, 3, 3, 9, 13, 15, 71, 83, 209, 191, 1049, 3423, 5829, 0 }; + static ulong[] dim815JoeKuoD6Init = { 1, 3, 1, 11, 27, 7, 65, 107, 387, 853, 919, 1257, 719, 0 }; + static ulong[] dim816JoeKuoD6Init = { 1, 3, 1, 9, 29, 63, 115, 91, 181, 217, 1097, 1023, 3641, 0 }; + static ulong[] dim817JoeKuoD6Init = { 1, 1, 3, 7, 7, 57, 37, 209, 99, 959, 693, 1573, 3407, 0 }; + static ulong[] dim818JoeKuoD6Init = { 1, 3, 7, 7, 9, 51, 51, 127, 153, 977, 1565, 1329, 4603, 0 }; + static ulong[] dim819JoeKuoD6Init = { 1, 3, 5, 3, 9, 57, 7, 225, 139, 515, 1355, 191, 659, 0 }; + static ulong[] dim820JoeKuoD6Init = { 1, 3, 3, 3, 7, 45, 85, 231, 153, 93, 371, 2753, 5331, 0 }; + static ulong[] dim821JoeKuoD6Init = { 1, 1, 5, 5, 1, 9, 45, 29, 131, 203, 31, 1219, 1635, 0 }; + static ulong[] dim822JoeKuoD6Init = { 1, 1, 1, 11, 5, 13, 115, 51, 471, 987, 1937, 3921, 7885, 0 }; + static ulong[] dim823JoeKuoD6Init = { 1, 1, 7, 3, 1, 23, 49, 183, 495, 427, 1397, 3383, 3459, 0 }; + static ulong[] dim824JoeKuoD6Init = { 1, 1, 7, 1, 23, 39, 3, 205, 447, 603, 1213, 667, 1039, 0 }; + static ulong[] dim825JoeKuoD6Init = { 1, 1, 1, 5, 7, 63, 27, 169, 403, 775, 241, 3951, 3411, 0 }; + static ulong[] dim826JoeKuoD6Init = { 1, 1, 3, 1, 7, 1, 63, 185, 197, 813, 1757, 2687, 7289, 0 }; + static ulong[] dim827JoeKuoD6Init = { 1, 1, 7, 3, 21, 21, 97, 73, 73, 147, 1905, 2391, 3743, 0 }; + static ulong[] dim828JoeKuoD6Init = { 1, 3, 7, 1, 29, 45, 27, 93, 71, 749, 337, 7, 3959, 0 }; + static ulong[] dim829JoeKuoD6Init = { 1, 3, 3, 9, 25, 13, 61, 131, 183, 409, 1547, 1261, 5541, 0 }; + static ulong[] dim830JoeKuoD6Init = { 1, 1, 7, 9, 9, 13, 13, 115, 87, 587, 1561, 1845, 2383, 0 }; + static ulong[] dim831JoeKuoD6Init = { 1, 3, 3, 3, 13, 19, 99, 75, 435, 815, 251, 1639, 2157, 0 }; + static ulong[] dim832JoeKuoD6Init = { 1, 1, 7, 9, 19, 61, 49, 237, 325, 429, 1019, 2649, 6671, 0 }; + static ulong[] dim833JoeKuoD6Init = { 1, 3, 3, 11, 1, 59, 71, 143, 37, 445, 1289, 2089, 5693, 0 }; + static ulong[] dim834JoeKuoD6Init = { 1, 3, 3, 7, 13, 13, 119, 83, 111, 497, 739, 863, 2009, 0 }; + static ulong[] dim835JoeKuoD6Init = { 1, 3, 5, 1, 3, 21, 89, 27, 171, 121, 1453, 3273, 2891, 0 }; + static ulong[] dim836JoeKuoD6Init = { 1, 3, 5, 5, 29, 19, 79, 77, 343, 969, 1759, 1921, 4189, 0 }; + static ulong[] dim837JoeKuoD6Init = { 1, 1, 1, 3, 21, 55, 99, 49, 435, 697, 559, 3475, 6905, 0 }; + static ulong[] dim838JoeKuoD6Init = { 1, 3, 1, 5, 9, 37, 83, 79, 171, 935, 751, 3293, 299, 0 }; + static ulong[] dim839JoeKuoD6Init = { 1, 1, 3, 13, 13, 45, 35, 159, 283, 451, 495, 3239, 4429, 0 }; + static ulong[] dim840JoeKuoD6Init = { 1, 1, 3, 1, 13, 43, 107, 189, 475, 679, 1843, 33, 6895, 0 }; + static ulong[] dim841JoeKuoD6Init = { 1, 3, 5, 9, 17, 13, 107, 245, 415, 531, 265, 3165, 3189, 0 }; + static ulong[] dim842JoeKuoD6Init = { 1, 3, 1, 3, 31, 29, 103, 233, 31, 445, 649, 3377, 3207, 0 }; + static ulong[] dim843JoeKuoD6Init = { 1, 1, 3, 9, 19, 3, 1, 75, 423, 445, 1351, 2889, 5785, 0 }; + static ulong[] dim844JoeKuoD6Init = { 1, 1, 3, 3, 21, 19, 113, 35, 173, 871, 275, 1901, 6725, 0 }; + static ulong[] dim845JoeKuoD6Init = { 1, 1, 3, 7, 27, 45, 41, 93, 463, 209, 1721, 1863, 7893, 0 }; + static ulong[] dim846JoeKuoD6Init = { 1, 1, 1, 13, 25, 63, 17, 171, 403, 645, 1669, 1663, 4335, 0 }; + static ulong[] dim847JoeKuoD6Init = { 1, 3, 3, 7, 17, 15, 103, 5, 375, 7, 1117, 3851, 651, 0 }; + static ulong[] dim848JoeKuoD6Init = { 1, 1, 1, 15, 29, 43, 13, 241, 403, 349, 685, 987, 4177, 0 }; + static ulong[] dim849JoeKuoD6Init = { 1, 3, 5, 15, 31, 37, 111, 91, 391, 513, 1701, 2861, 4713, 0 }; + static ulong[] dim850JoeKuoD6Init = { 1, 1, 5, 9, 23, 59, 125, 117, 375, 461, 1697, 1283, 7395, 0 }; + static ulong[] dim851JoeKuoD6Init = { 1, 1, 3, 7, 21, 35, 101, 131, 129, 757, 199, 1881, 737, 0 }; + static ulong[] dim852JoeKuoD6Init = { 1, 1, 7, 3, 31, 15, 121, 143, 67, 593, 1143, 3761, 3441, 0 }; + static ulong[] dim853JoeKuoD6Init = { 1, 1, 3, 9, 11, 43, 7, 159, 25, 725, 1169, 1757, 3499, 0 }; + static ulong[] dim854JoeKuoD6Init = { 1, 1, 3, 9, 5, 55, 77, 85, 309, 113, 1419, 1255, 4777, 0 }; + static ulong[] dim855JoeKuoD6Init = { 1, 3, 3, 15, 19, 41, 75, 163, 51, 511, 1785, 4033, 7791, 0 }; + static ulong[] dim856JoeKuoD6Init = { 1, 3, 7, 15, 29, 45, 81, 189, 401, 71, 1597, 3671, 2133, 0 }; + static ulong[] dim857JoeKuoD6Init = { 1, 1, 3, 1, 3, 17, 119, 55, 217, 485, 1217, 1475, 5791, 0 }; + static ulong[] dim858JoeKuoD6Init = { 1, 1, 7, 9, 21, 61, 71, 175, 205, 413, 1645, 2375, 89, 0 }; + static ulong[] dim859JoeKuoD6Init = { 1, 3, 3, 7, 25, 35, 23, 49, 395, 675, 341, 959, 4665, 0 }; + static ulong[] dim860JoeKuoD6Init = { 1, 3, 5, 15, 21, 37, 99, 151, 197, 145, 2043, 755, 2523, 0 }; + static ulong[] dim861JoeKuoD6Init = { 1, 1, 1, 7, 1, 61, 75, 131, 65, 891, 349, 2767, 3855, 0 }; + static ulong[] dim862JoeKuoD6Init = { 1, 3, 5, 9, 29, 57, 61, 79, 303, 997, 1053, 1973, 1547, 0 }; + static ulong[] dim863JoeKuoD6Init = { 1, 1, 3, 7, 19, 9, 57, 197, 253, 597, 1971, 1831, 8097, 0 }; + static ulong[] dim864JoeKuoD6Init = { 1, 3, 1, 9, 3, 13, 29, 169, 25, 957, 1575, 2955, 3549, 0 }; + static ulong[] dim865JoeKuoD6Init = { 1, 1, 5, 11, 17, 37, 79, 91, 11, 687, 1511, 1065, 1539, 0 }; + static ulong[] dim866JoeKuoD6Init = { 1, 1, 1, 7, 1, 59, 1, 49, 23, 73, 881, 1661, 3841, 0 }; + static ulong[] dim867JoeKuoD6Init = { 1, 1, 1, 1, 13, 57, 111, 67, 511, 833, 1095, 15, 569, 0 }; + static ulong[] dim868JoeKuoD6Init = { 1, 3, 1, 5, 17, 33, 1, 161, 311, 29, 685, 729, 5981, 0 }; + static ulong[] dim869JoeKuoD6Init = { 1, 1, 7, 1, 7, 13, 49, 55, 251, 825, 709, 445, 7439, 0 }; + static ulong[] dim870JoeKuoD6Init = { 1, 3, 1, 5, 13, 55, 101, 89, 239, 907, 1559, 1421, 87, 0 }; + static ulong[] dim871JoeKuoD6Init = { 1, 1, 3, 9, 23, 27, 41, 189, 35, 155, 683, 2491, 7495, 0 }; + static ulong[] dim872JoeKuoD6Init = { 1, 3, 5, 3, 5, 47, 39, 161, 279, 945, 365, 15, 4643, 0 }; + static ulong[] dim873JoeKuoD6Init = { 1, 1, 1, 11, 21, 7, 125, 195, 23, 635, 1949, 2237, 1885, 0 }; + static ulong[] dim874JoeKuoD6Init = { 1, 1, 3, 7, 13, 25, 105, 145, 203, 701, 1525, 1391, 1637, 0 }; + static ulong[] dim875JoeKuoD6Init = { 1, 3, 3, 13, 7, 43, 13, 39, 301, 507, 405, 2333, 2405, 0 }; + static ulong[] dim876JoeKuoD6Init = { 1, 1, 5, 15, 25, 19, 31, 67, 81, 781, 1541, 3743, 2787, 0 }; + static ulong[] dim877JoeKuoD6Init = { 1, 1, 1, 11, 15, 7, 87, 129, 151, 225, 655, 1569, 5299, 0 }; + static ulong[] dim878JoeKuoD6Init = { 1, 1, 5, 3, 3, 33, 97, 255, 9, 667, 787, 3557, 5273, 0 }; + static ulong[] dim879JoeKuoD6Init = { 1, 1, 3, 3, 1, 7, 13, 31, 31, 1021, 1863, 2897, 6389, 0 }; + static ulong[] dim880JoeKuoD6Init = { 1, 3, 1, 15, 13, 29, 93, 27, 229, 599, 521, 1631, 3683, 0 }; + static ulong[] dim881JoeKuoD6Init = { 1, 1, 7, 9, 11, 27, 43, 95, 149, 159, 495, 2711, 2189, 0 }; + static ulong[] dim882JoeKuoD6Init = { 1, 1, 7, 9, 11, 51, 43, 121, 299, 73, 1991, 561, 6781, 0 }; + static ulong[] dim883JoeKuoD6Init = { 1, 1, 3, 3, 7, 61, 125, 13, 415, 11, 15, 2463, 385, 0 }; + static ulong[] dim884JoeKuoD6Init = { 1, 3, 5, 1, 27, 23, 1, 47, 149, 371, 1599, 341, 1595, 0 }; + static ulong[] dim885JoeKuoD6Init = { 1, 1, 1, 15, 3, 39, 65, 5, 33, 713, 399, 2935, 3825, 0 }; + static ulong[] dim886JoeKuoD6Init = { 1, 1, 7, 7, 17, 39, 3, 235, 227, 231, 323, 2869, 4747, 0 }; + static ulong[] dim887JoeKuoD6Init = { 1, 1, 5, 9, 13, 11, 41, 155, 393, 701, 909, 2999, 5053, 0 }; + static ulong[] dim888JoeKuoD6Init = { 1, 1, 3, 7, 5, 41, 105, 13, 123, 429, 1455, 2501, 1065, 0 }; + static ulong[] dim889JoeKuoD6Init = { 1, 1, 1, 7, 17, 21, 95, 141, 305, 951, 1305, 3639, 3797, 0 }; + static ulong[] dim890JoeKuoD6Init = { 1, 3, 5, 9, 7, 59, 29, 129, 265, 889, 993, 1411, 2069, 0 }; + static ulong[] dim891JoeKuoD6Init = { 1, 1, 1, 11, 3, 51, 9, 35, 355, 131, 1307, 1547, 701, 0 }; + static ulong[] dim892JoeKuoD6Init = { 1, 1, 7, 3, 17, 57, 113, 197, 483, 831, 1741, 3897, 3649, 0 }; + static ulong[] dim893JoeKuoD6Init = { 1, 1, 5, 11, 1, 33, 7, 243, 95, 905, 1933, 2123, 7381, 0 }; + static ulong[] dim894JoeKuoD6Init = { 1, 3, 3, 15, 5, 37, 1, 235, 77, 375, 1231, 1029, 1839, 0 }; + static ulong[] dim895JoeKuoD6Init = { 1, 1, 5, 3, 31, 11, 103, 245, 373, 103, 25, 1283, 6155, 0 }; + static ulong[] dim896JoeKuoD6Init = { 1, 3, 5, 1, 25, 25, 51, 159, 381, 97, 799, 565, 5165, 0 }; + static ulong[] dim897JoeKuoD6Init = { 1, 1, 7, 13, 25, 21, 109, 3, 253, 459, 623, 2817, 7815, 0 }; + static ulong[] dim898JoeKuoD6Init = { 1, 3, 5, 1, 23, 5, 127, 157, 187, 187, 1383, 2777, 2413, 0 }; + static ulong[] dim899JoeKuoD6Init = { 1, 1, 5, 3, 29, 47, 97, 197, 215, 725, 445, 2111, 1701, 0 }; + static ulong[] dim900JoeKuoD6Init = { 1, 3, 1, 9, 27, 25, 105, 59, 333, 79, 1099, 3695, 5725, 0 }; + static ulong[] dim901JoeKuoD6Init = { 1, 1, 7, 3, 11, 15, 127, 151, 163, 967, 665, 733, 509, 0 }; + static ulong[] dim902JoeKuoD6Init = { 1, 3, 3, 3, 15, 5, 51, 17, 409, 679, 229, 1037, 353, 0 }; + static ulong[] dim903JoeKuoD6Init = { 1, 3, 7, 15, 7, 9, 17, 115, 205, 105, 597, 2913, 1941, 0 }; + static ulong[] dim904JoeKuoD6Init = { 1, 1, 5, 11, 31, 1, 99, 213, 33, 319, 617, 1493, 7287, 0 }; + static ulong[] dim905JoeKuoD6Init = { 1, 3, 5, 5, 21, 31, 115, 43, 309, 217, 1, 3363, 6673, 0 }; + static ulong[] dim906JoeKuoD6Init = { 1, 3, 7, 7, 11, 29, 125, 75, 209, 217, 1749, 1565, 4431, 0 }; + static ulong[] dim907JoeKuoD6Init = { 1, 3, 5, 1, 5, 37, 103, 237, 19, 763, 915, 753, 7479, 0 }; + static ulong[] dim908JoeKuoD6Init = { 1, 3, 3, 9, 11, 59, 9, 133, 455, 683, 251, 963, 3743, 0 }; + static ulong[] dim909JoeKuoD6Init = { 1, 3, 5, 9, 7, 41, 97, 185, 117, 367, 2045, 3013, 6249, 0 }; + static ulong[] dim910JoeKuoD6Init = { 1, 1, 1, 5, 29, 51, 53, 147, 379, 769, 865, 2273, 1755, 0 }; + static ulong[] dim911JoeKuoD6Init = { 1, 3, 1, 7, 13, 61, 125, 153, 297, 385, 1981, 2221, 4209, 0 }; + static ulong[] dim912JoeKuoD6Init = { 1, 1, 7, 15, 7, 33, 41, 43, 201, 819, 129, 757, 4087, 0 }; + static ulong[] dim913JoeKuoD6Init = { 1, 1, 5, 7, 31, 15, 19, 15, 197, 921, 1967, 491, 4911, 0 }; + static ulong[] dim914JoeKuoD6Init = { 1, 1, 1, 13, 21, 25, 119, 123, 255, 155, 1765, 2895, 4201, 0 }; + static ulong[] dim915JoeKuoD6Init = { 1, 3, 5, 9, 1, 63, 57, 193, 327, 455, 1729, 1259, 7483, 0 }; + static ulong[] dim916JoeKuoD6Init = { 1, 3, 5, 1, 5, 19, 71, 255, 257, 477, 1799, 3855, 955, 0 }; + static ulong[] dim917JoeKuoD6Init = { 1, 1, 3, 1, 29, 27, 7, 151, 327, 311, 235, 3599, 6165, 0 }; + static ulong[] dim918JoeKuoD6Init = { 1, 3, 3, 3, 7, 29, 113, 87, 339, 271, 1141, 1111, 7971, 0 }; + static ulong[] dim919JoeKuoD6Init = { 1, 3, 5, 15, 23, 51, 57, 233, 179, 397, 1059, 123, 697, 0 }; + static ulong[] dim920JoeKuoD6Init = { 1, 3, 3, 13, 17, 11, 15, 189, 437, 449, 1533, 2209, 1849, 0 }; + static ulong[] dim921JoeKuoD6Init = { 1, 3, 5, 9, 9, 19, 53, 165, 279, 875, 1223, 1585, 6647, 0 }; + static ulong[] dim922JoeKuoD6Init = { 1, 1, 7, 5, 5, 49, 119, 31, 273, 919, 413, 1531, 6233, 0 }; + static ulong[] dim923JoeKuoD6Init = { 1, 3, 5, 5, 1, 19, 27, 213, 413, 271, 223, 299, 5635, 0 }; + static ulong[] dim924JoeKuoD6Init = { 1, 1, 7, 3, 11, 55, 25, 43, 147, 53, 95, 1849, 7701, 0 }; + static ulong[] dim925JoeKuoD6Init = { 1, 3, 5, 11, 17, 35, 9, 3, 117, 729, 21, 3379, 5963, 0 }; + static ulong[] dim926JoeKuoD6Init = { 1, 3, 1, 7, 23, 25, 45, 103, 181, 677, 1155, 205, 1967, 0 }; + static ulong[] dim927JoeKuoD6Init = { 1, 1, 3, 9, 19, 53, 41, 243, 97, 199, 407, 3299, 5309, 0 }; + static ulong[] dim928JoeKuoD6Init = { 1, 3, 5, 11, 27, 27, 59, 153, 501, 855, 1235, 2295, 5535, 0 }; + static ulong[] dim929JoeKuoD6Init = { 1, 1, 3, 7, 11, 37, 1, 179, 289, 895, 511, 697, 5067, 0 }; + static ulong[] dim930JoeKuoD6Init = { 1, 3, 7, 15, 25, 27, 33, 37, 351, 351, 813, 2239, 1561, 0 }; + static ulong[] dim931JoeKuoD6Init = { 1, 3, 1, 7, 25, 51, 79, 65, 427, 293, 1031, 685, 533, 0 }; + static ulong[] dim932JoeKuoD6Init = { 1, 3, 3, 15, 21, 21, 77, 31, 299, 643, 161, 2991, 7911, 0 }; + static ulong[] dim933JoeKuoD6Init = { 1, 3, 3, 7, 7, 61, 99, 19, 43, 35, 687, 1449, 5211, 0 }; + static ulong[] dim934JoeKuoD6Init = { 1, 3, 1, 5, 5, 59, 101, 175, 149, 799, 439, 19, 7565, 0 }; + static ulong[] dim935JoeKuoD6Init = { 1, 3, 7, 9, 31, 13, 75, 227, 337, 207, 609, 2119, 3539, 0 }; + static ulong[] dim936JoeKuoD6Init = { 1, 1, 1, 11, 3, 59, 1, 139, 425, 583, 263, 2687, 4445, 0 }; + static ulong[] dim937JoeKuoD6Init = { 1, 1, 5, 7, 21, 31, 55, 117, 377, 469, 1907, 3091, 3221, 0 }; + static ulong[] dim938JoeKuoD6Init = { 1, 1, 5, 1, 7, 63, 89, 197, 271, 425, 1493, 2337, 6397, 0 }; + static ulong[] dim939JoeKuoD6Init = { 1, 1, 1, 7, 9, 35, 17, 237, 215, 211, 523, 3095, 1771, 0 }; + static ulong[] dim940JoeKuoD6Init = { 1, 1, 5, 5, 19, 23, 119, 31, 331, 533, 71, 319, 7567, 0 }; + static ulong[] dim941JoeKuoD6Init = { 1, 1, 5, 7, 1, 33, 41, 9, 421, 789, 1305, 3775, 6545, 0 }; + static ulong[] dim942JoeKuoD6Init = { 1, 3, 1, 11, 17, 9, 47, 237, 227, 859, 113, 429, 5399, 0 }; + static ulong[] dim943JoeKuoD6Init = { 1, 3, 5, 11, 25, 29, 15, 1, 73, 1015, 2023, 367, 1523, 0 }; + static ulong[] dim944JoeKuoD6Init = { 1, 1, 5, 11, 19, 31, 121, 243, 411, 717, 671, 1329, 2669, 0 }; + static ulong[] dim945JoeKuoD6Init = { 1, 1, 1, 11, 27, 41, 23, 13, 353, 533, 1627, 1625, 3705, 0 }; + static ulong[] dim946JoeKuoD6Init = { 1, 1, 7, 11, 31, 41, 17, 3, 163, 207, 407, 1475, 5911, 0 }; + static ulong[] dim947JoeKuoD6Init = { 1, 1, 7, 3, 3, 19, 87, 199, 77, 207, 1957, 1691, 5045, 0 }; + static ulong[] dim948JoeKuoD6Init = { 1, 1, 1, 3, 19, 57, 107, 37, 419, 943, 133, 519, 4391, 0 }; + static ulong[] dim949JoeKuoD6Init = { 1, 3, 5, 11, 7, 5, 85, 1, 265, 801, 2025, 2655, 4635, 0 }; + static ulong[] dim950JoeKuoD6Init = { 1, 3, 3, 3, 7, 13, 15, 155, 283, 97, 1311, 607, 2879, 0 }; + static ulong[] dim951JoeKuoD6Init = { 1, 1, 5, 9, 21, 31, 3, 237, 323, 749, 1879, 611, 6763, 0 }; + static ulong[] dim952JoeKuoD6Init = { 1, 3, 5, 9, 19, 51, 25, 39, 7, 973, 837, 105, 1987, 0 }; + static ulong[] dim953JoeKuoD6Init = { 1, 1, 5, 13, 9, 63, 39, 233, 391, 93, 1741, 425, 901, 0 }; + static ulong[] dim954JoeKuoD6Init = { 1, 3, 7, 13, 13, 23, 95, 195, 263, 71, 255, 1839, 4301, 0 }; + static ulong[] dim955JoeKuoD6Init = { 1, 3, 1, 3, 29, 35, 123, 145, 377, 1021, 1361, 2319, 1487, 0 }; + static ulong[] dim956JoeKuoD6Init = { 1, 3, 7, 15, 9, 27, 61, 85, 81, 371, 1803, 3683, 4771, 0 }; + static ulong[] dim957JoeKuoD6Init = { 1, 3, 7, 15, 9, 35, 51, 137, 3, 721, 1269, 2667, 7293, 0 }; + static ulong[] dim958JoeKuoD6Init = { 1, 1, 3, 15, 3, 53, 121, 227, 55, 937, 1623, 2691, 2353, 0 }; + static ulong[] dim959JoeKuoD6Init = { 1, 3, 1, 5, 7, 53, 53, 121, 299, 633, 263, 3651, 3187, 0 }; + static ulong[] dim960JoeKuoD6Init = { 1, 3, 1, 9, 31, 59, 73, 5, 475, 763, 115, 2263, 2475, 0 }; + static ulong[] dim961JoeKuoD6Init = { 1, 3, 3, 7, 13, 15, 49, 227, 285, 41, 1817, 2573, 4991, 0 }; + static ulong[] dim962JoeKuoD6Init = { 1, 3, 5, 3, 17, 7, 29, 93, 253, 527, 657, 1859, 763, 0 }; + static ulong[] dim963JoeKuoD6Init = { 1, 1, 5, 11, 9, 11, 75, 47, 469, 119, 1505, 3807, 2769, 0 }; + static ulong[] dim964JoeKuoD6Init = { 1, 1, 3, 11, 1, 37, 65, 135, 345, 307, 305, 1167, 1767, 0 }; + static ulong[] dim965JoeKuoD6Init = { 1, 3, 3, 13, 5, 33, 9, 245, 271, 123, 1865, 2215, 2791, 0 }; + static ulong[] dim966JoeKuoD6Init = { 1, 1, 3, 1, 9, 23, 3, 21, 149, 923, 1335, 1015, 45, 0 }; + static ulong[] dim967JoeKuoD6Init = { 1, 3, 1, 15, 11, 3, 65, 219, 233, 353, 771, 3961, 1515, 0 }; + static ulong[] dim968JoeKuoD6Init = { 1, 3, 1, 5, 15, 41, 87, 141, 19, 905, 449, 3727, 1875, 0 }; + static ulong[] dim969JoeKuoD6Init = { 1, 1, 7, 9, 11, 15, 53, 151, 243, 279, 1695, 2317, 6661, 0 }; + static ulong[] dim970JoeKuoD6Init = { 1, 3, 3, 7, 19, 51, 31, 157, 79, 399, 465, 661, 1029, 0 }; + static ulong[] dim971JoeKuoD6Init = { 1, 3, 5, 1, 5, 41, 3, 33, 157, 385, 1943, 1851, 3121, 0 }; + static ulong[] dim972JoeKuoD6Init = { 1, 3, 1, 11, 25, 59, 105, 191, 151, 285, 801, 201, 6871, 0 }; + static ulong[] dim973JoeKuoD6Init = { 1, 3, 1, 15, 27, 35, 17, 195, 387, 907, 1905, 2177, 2597, 0 }; + static ulong[] dim974JoeKuoD6Init = { 1, 3, 1, 9, 31, 43, 71, 185, 469, 809, 541, 571, 107, 0 }; + static ulong[] dim975JoeKuoD6Init = { 1, 3, 7, 13, 5, 15, 55, 211, 305, 645, 1317, 2751, 603, 0 }; + static ulong[] dim976JoeKuoD6Init = { 1, 1, 3, 15, 19, 59, 45, 147, 165, 223, 259, 1205, 431, 0 }; + static ulong[] dim977JoeKuoD6Init = { 1, 1, 5, 13, 5, 53, 115, 57, 203, 151, 1039, 871, 3881, 0 }; + static ulong[] dim978JoeKuoD6Init = { 1, 3, 5, 15, 1, 29, 115, 249, 79, 957, 143, 3425, 5769, 0 }; + static ulong[] dim979JoeKuoD6Init = { 1, 1, 7, 15, 15, 15, 117, 181, 363, 17, 1871, 1049, 2997, 0 }; + static ulong[] dim980JoeKuoD6Init = { 1, 1, 3, 7, 23, 11, 77, 123, 149, 1019, 93, 3637, 6975, 0 }; + static ulong[] dim981JoeKuoD6Init = { 1, 1, 1, 7, 5, 51, 77, 89, 121, 155, 1839, 1301, 2771, 0 }; + static ulong[] dim982JoeKuoD6Init = { 1, 3, 7, 7, 7, 39, 33, 69, 169, 535, 1699, 2117, 3233, 0 }; + static ulong[] dim983JoeKuoD6Init = { 1, 3, 5, 7, 3, 59, 81, 113, 261, 627, 79, 227, 7623, 0 }; + static ulong[] dim984JoeKuoD6Init = { 1, 3, 5, 5, 13, 57, 121, 41, 11, 111, 1055, 3313, 3371, 0 }; + static ulong[] dim985JoeKuoD6Init = { 1, 1, 3, 13, 13, 9, 47, 197, 303, 987, 1125, 2461, 5007, 0 }; + static ulong[] dim986JoeKuoD6Init = { 1, 3, 1, 5, 1, 59, 109, 49, 453, 673, 2017, 205, 4673, 0 }; + static ulong[] dim987JoeKuoD6Init = { 1, 3, 1, 13, 19, 43, 95, 247, 475, 193, 1513, 885, 5391, 0 }; + static ulong[] dim988JoeKuoD6Init = { 1, 1, 1, 11, 29, 57, 77, 101, 433, 537, 1681, 2463, 6623, 0 }; + static ulong[] dim989JoeKuoD6Init = { 1, 3, 7, 13, 3, 61, 29, 53, 29, 673, 1037, 3877, 7421, 0 }; + static ulong[] dim990JoeKuoD6Init = { 1, 3, 3, 11, 5, 59, 61, 91, 13, 949, 1093, 1291, 7395, 0 }; + static ulong[] dim991JoeKuoD6Init = { 1, 3, 3, 13, 21, 27, 49, 37, 429, 877, 1247, 2375, 737, 0 }; + static ulong[] dim992JoeKuoD6Init = { 1, 3, 5, 3, 25, 19, 75, 187, 239, 971, 859, 2519, 7323, 0 }; + static ulong[] dim993JoeKuoD6Init = { 1, 3, 3, 7, 25, 19, 11, 223, 75, 801, 313, 2875, 6857, 0 }; + static ulong[] dim994JoeKuoD6Init = { 1, 1, 7, 3, 13, 63, 49, 125, 65, 1005, 1757, 3685, 4385, 0 }; + static ulong[] dim995JoeKuoD6Init = { 1, 3, 1, 15, 5, 41, 95, 231, 505, 907, 751, 3207, 4115, 0 }; + static ulong[] dim996JoeKuoD6Init = { 1, 1, 7, 11, 31, 7, 29, 51, 449, 151, 1821, 3317, 931, 0 }; + static ulong[] dim997JoeKuoD6Init = { 1, 3, 1, 11, 19, 11, 19, 47, 111, 637, 37, 3707, 2599, 0 }; + static ulong[] dim998JoeKuoD6Init = { 1, 3, 7, 5, 23, 27, 65, 217, 491, 129, 1715, 2479, 2015, 0 }; + static ulong[] dim999JoeKuoD6Init = { 1, 1, 5, 3, 5, 51, 43, 253, 495, 105, 1183, 3409, 1469, 0 }; + static ulong[] dim1000JoeKuoD6Init = { 1, 3, 7, 9, 21, 5, 87, 67, 481, 405, 1967, 2837, 5161, 0 }; + static ulong[] dim1001JoeKuoD6Init = { 1, 1, 7, 3, 29, 25, 15, 211, 233, 301, 1037, 3853, 7115, 0 }; + static ulong[] dim1002JoeKuoD6Init = { 1, 3, 5, 9, 3, 15, 85, 81, 141, 395, 845, 17, 7485, 0 }; + static ulong[] dim1003JoeKuoD6Init = { 1, 3, 5, 3, 21, 37, 39, 93, 461, 615, 1725, 1745, 5137, 0 }; + static ulong[] dim1004JoeKuoD6Init = { 1, 1, 3, 1, 1, 21, 21, 207, 271, 447, 1415, 2507, 3291, 0 }; + static ulong[] dim1005JoeKuoD6Init = { 1, 3, 7, 11, 23, 3, 115, 191, 257, 1015, 463, 1501, 7439, 0 }; + static ulong[] dim1006JoeKuoD6Init = { 1, 1, 7, 11, 3, 53, 101, 221, 9, 225, 1799, 1701, 5669, 0 }; + static ulong[] dim1007JoeKuoD6Init = { 1, 1, 7, 13, 17, 27, 7, 115, 67, 645, 1283, 75, 1881, 0 }; + static ulong[] dim1008JoeKuoD6Init = { 1, 1, 3, 15, 7, 39, 75, 85, 127, 379, 1509, 2215, 5697, 0 }; + static ulong[] dim1009JoeKuoD6Init = { 1, 1, 7, 1, 19, 31, 11, 67, 263, 877, 337, 1655, 1855, 0 }; + static ulong[] dim1010JoeKuoD6Init = { 1, 3, 5, 9, 11, 47, 125, 89, 235, 331, 159, 685, 999, 0 }; + static ulong[] dim1011JoeKuoD6Init = { 1, 3, 7, 3, 23, 39, 59, 69, 221, 291, 725, 2831, 4743, 0 }; + static ulong[] dim1012JoeKuoD6Init = { 1, 3, 7, 11, 1, 43, 127, 235, 143, 329, 1823, 21, 73, 0 }; + static ulong[] dim1013JoeKuoD6Init = { 1, 3, 1, 3, 27, 23, 33, 29, 493, 775, 1873, 1005, 2869, 0 }; + static ulong[] dim1014JoeKuoD6Init = { 1, 3, 3, 9, 3, 31, 63, 249, 353, 849, 5, 2787, 4759, 0 }; + static ulong[] dim1015JoeKuoD6Init = { 1, 3, 3, 11, 15, 15, 73, 159, 433, 35, 1203, 2541, 6713, 0 }; + static ulong[] dim1016JoeKuoD6Init = { 1, 1, 5, 1, 13, 17, 107, 101, 411, 861, 1075, 2161, 3923, 0 }; + static ulong[] dim1017JoeKuoD6Init = { 1, 1, 3, 5, 29, 29, 55, 205, 235, 685, 1445, 2413, 6837, 0 }; + static ulong[] dim1018JoeKuoD6Init = { 1, 1, 1, 13, 13, 1, 125, 37, 331, 33, 47, 2761, 3449, 0 }; + static ulong[] dim1019JoeKuoD6Init = { 1, 1, 7, 3, 17, 21, 21, 93, 145, 423, 1057, 997, 6117, 0 }; + static ulong[] dim1020JoeKuoD6Init = { 1, 3, 3, 13, 25, 47, 13, 159, 41, 907, 1543, 1919, 5547, 0 }; + static ulong[] dim1021JoeKuoD6Init = { 1, 1, 3, 9, 29, 53, 83, 45, 133, 453, 183, 2939, 4945, 0 }; + static ulong[] dim1022JoeKuoD6Init = { 1, 1, 1, 7, 9, 7, 89, 71, 315, 983, 1471, 2475, 7077, 0 }; + static ulong[] dim1023JoeKuoD6Init = { 1, 1, 3, 3, 31, 21, 55, 37, 337, 63, 299, 2415, 153, 0 }; + static ulong[] dim1024JoeKuoD6Init = { 1, 1, 7, 3, 27, 59, 85, 109, 405, 337, 393, 2291, 5423, 0 }; + static ulong[] dim1025JoeKuoD6Init = { 1, 1, 1, 1, 5, 31, 33, 43, 141, 9, 1271, 1749, 6281, 0 }; + static ulong[] dim1026JoeKuoD6Init = { 1, 1, 3, 9, 23, 35, 25, 17, 49, 119, 883, 2907, 3573, 0 }; + static ulong[] dim1027JoeKuoD6Init = { 1, 3, 1, 15, 25, 61, 89, 15, 315, 1015, 563, 1895, 4123, 0 }; + static ulong[] dim1028JoeKuoD6Init = { 1, 3, 3, 7, 15, 53, 61, 225, 381, 217, 163, 4005, 7269, 0 }; + static ulong[] dim1029JoeKuoD6Init = { 1, 3, 7, 5, 1, 59, 13, 201, 53, 629, 1917, 3105, 3047, 0 }; + static ulong[] dim1030JoeKuoD6Init = { 1, 3, 1, 1, 19, 45, 71, 11, 15, 365, 1223, 3861, 5005, 0 }; + static ulong[] dim1031JoeKuoD6Init = { 1, 1, 5, 11, 15, 15, 31, 245, 105, 609, 1051, 1911, 7531, 0 }; + static ulong[] dim1032JoeKuoD6Init = { 1, 3, 7, 11, 27, 5, 79, 31, 201, 347, 1295, 2589, 5179, 0 }; + static ulong[] dim1033JoeKuoD6Init = { 1, 1, 3, 1, 31, 23, 65, 203, 359, 591, 1459, 1941, 2307, 0 }; + static ulong[] dim1034JoeKuoD6Init = { 1, 1, 5, 5, 3, 55, 79, 179, 147, 223, 1011, 1437, 3715, 0 }; + static ulong[] dim1035JoeKuoD6Init = { 1, 1, 5, 11, 23, 19, 57, 241, 363, 729, 1647, 2395, 3237, 0 }; + static ulong[] dim1036JoeKuoD6Init = { 1, 3, 7, 7, 7, 63, 115, 53, 485, 965, 551, 3945, 1535, 0 }; + static ulong[] dim1037JoeKuoD6Init = { 1, 1, 1, 15, 5, 61, 33, 213, 451, 363, 95, 1185, 3633, 0 }; + static ulong[] dim1038JoeKuoD6Init = { 1, 3, 5, 1, 17, 49, 39, 159, 327, 1021, 289, 3375, 8055, 0 }; + static ulong[] dim1039JoeKuoD6Init = { 1, 3, 3, 5, 11, 1, 73, 3, 121, 561, 209, 1913, 4549, 0 }; + static ulong[] dim1040JoeKuoD6Init = { 1, 3, 1, 3, 23, 39, 101, 231, 317, 397, 693, 1579, 3585, 0 }; + static ulong[] dim1041JoeKuoD6Init = { 1, 1, 1, 1, 1, 5, 81, 209, 373, 689, 259, 3167, 1665, 0 }; + static ulong[] dim1042JoeKuoD6Init = { 1, 1, 1, 11, 21, 19, 83, 201, 7, 573, 1563, 1649, 5827, 0 }; + static ulong[] dim1043JoeKuoD6Init = { 1, 3, 5, 1, 31, 35, 53, 149, 185, 925, 701, 3727, 4425, 0 }; + static ulong[] dim1044JoeKuoD6Init = { 1, 1, 5, 7, 19, 11, 67, 47, 19, 789, 1855, 293, 7569, 0 }; + static ulong[] dim1045JoeKuoD6Init = { 1, 1, 5, 13, 25, 55, 25, 187, 405, 1013, 493, 1645, 6753, 0 }; + static ulong[] dim1046JoeKuoD6Init = { 1, 1, 3, 11, 13, 23, 35, 219, 247, 723, 1079, 1523, 7383, 0 }; + static ulong[] dim1047JoeKuoD6Init = { 1, 1, 3, 13, 5, 1, 27, 151, 61, 889, 1911, 3859, 4661, 0 }; + static ulong[] dim1048JoeKuoD6Init = { 1, 3, 1, 7, 15, 59, 57, 157, 333, 367, 245, 3043, 1683, 0 }; + static ulong[] dim1049JoeKuoD6Init = { 1, 3, 7, 11, 15, 53, 107, 81, 287, 637, 557, 315, 4361, 0 }; + static ulong[] dim1050JoeKuoD6Init = { 1, 1, 5, 11, 11, 21, 35, 59, 429, 459, 1439, 639, 6907, 0 }; + static ulong[] dim1051JoeKuoD6Init = { 1, 3, 3, 11, 13, 51, 101, 121, 437, 9, 889, 1907, 5217, 0 }; + static ulong[] dim1052JoeKuoD6Init = { 1, 1, 7, 13, 7, 5, 99, 161, 207, 237, 1547, 403, 2269, 0 }; + static ulong[] dim1053JoeKuoD6Init = { 1, 1, 5, 9, 23, 17, 43, 113, 119, 213, 977, 1197, 1039, 0 }; + static ulong[] dim1054JoeKuoD6Init = { 1, 3, 3, 9, 25, 51, 79, 5, 355, 279, 875, 1947, 1261, 0 }; + static ulong[] dim1055JoeKuoD6Init = { 1, 1, 7, 3, 5, 15, 85, 137, 361, 509, 959, 3227, 3755, 0 }; + static ulong[] dim1056JoeKuoD6Init = { 1, 1, 7, 3, 29, 31, 45, 139, 143, 891, 877, 2195, 4405, 0 }; + static ulong[] dim1057JoeKuoD6Init = { 1, 1, 1, 7, 17, 7, 81, 19, 469, 713, 57, 3559, 4925, 0 }; + static ulong[] dim1058JoeKuoD6Init = { 1, 1, 1, 9, 13, 43, 69, 77, 225, 497, 1263, 1153, 7375, 0 }; + static ulong[] dim1059JoeKuoD6Init = { 1, 1, 5, 7, 15, 19, 67, 75, 207, 851, 1827, 3523, 2159, 0 }; + static ulong[] dim1060JoeKuoD6Init = { 1, 3, 7, 3, 25, 63, 71, 157, 509, 219, 1529, 2513, 1697, 0 }; + static ulong[] dim1061JoeKuoD6Init = { 1, 3, 1, 5, 9, 9, 13, 147, 363, 561, 1707, 2991, 1671, 0 }; + static ulong[] dim1062JoeKuoD6Init = { 1, 3, 1, 15, 13, 55, 77, 27, 427, 277, 725, 2861, 4841, 0 }; + static ulong[] dim1063JoeKuoD6Init = { 1, 1, 5, 15, 25, 55, 21, 135, 221, 965, 1723, 2097, 1277, 0 }; + static ulong[] dim1064JoeKuoD6Init = { 1, 1, 5, 3, 1, 11, 45, 179, 503, 283, 1075, 1283, 7603, 0 }; + static ulong[] dim1065JoeKuoD6Init = { 1, 3, 1, 1, 1, 39, 61, 107, 183, 817, 1577, 1143, 783, 0 }; + static ulong[] dim1066JoeKuoD6Init = { 1, 1, 5, 13, 9, 59, 51, 89, 397, 705, 1081, 3053, 4001, 0 }; + static ulong[] dim1067JoeKuoD6Init = { 1, 3, 3, 11, 25, 53, 3, 125, 419, 827, 1907, 903, 3169, 0 }; + static ulong[] dim1068JoeKuoD6Init = { 1, 3, 5, 9, 1, 3, 119, 153, 353, 315, 1555, 1273, 6605, 0 }; + static ulong[] dim1069JoeKuoD6Init = { 1, 1, 3, 13, 13, 39, 117, 59, 225, 735, 1297, 1281, 8049, 0 }; + static ulong[] dim1070JoeKuoD6Init = { 1, 3, 1, 3, 27, 53, 57, 95, 303, 803, 343, 4021, 5047, 0 }; + static ulong[] dim1071JoeKuoD6Init = { 1, 3, 1, 11, 25, 1, 91, 107, 181, 839, 1691, 3859, 2363, 0 }; + static ulong[] dim1072JoeKuoD6Init = { 1, 1, 7, 1, 19, 45, 23, 37, 345, 675, 5, 3731, 2961, 0 }; + static ulong[] dim1073JoeKuoD6Init = { 1, 3, 1, 11, 13, 47, 19, 43, 221, 1007, 1021, 2967, 6931, 0 }; + static ulong[] dim1074JoeKuoD6Init = { 1, 3, 7, 5, 27, 21, 19, 57, 59, 485, 967, 983, 4989, 0 }; + static ulong[] dim1075JoeKuoD6Init = { 1, 3, 7, 3, 11, 23, 1, 221, 223, 535, 155, 2805, 661, 0 }; + static ulong[] dim1076JoeKuoD6Init = { 1, 1, 7, 5, 3, 49, 127, 75, 215, 517, 1391, 589, 493, 0 }; + static ulong[] dim1077JoeKuoD6Init = { 1, 1, 7, 5, 23, 29, 79, 171, 319, 811, 191, 1131, 7689, 0 }; + static ulong[] dim1078JoeKuoD6Init = { 1, 1, 1, 7, 21, 9, 23, 21, 171, 631, 299, 2295, 5691, 0 }; + static ulong[] dim1079JoeKuoD6Init = { 1, 1, 3, 7, 17, 59, 47, 205, 39, 407, 1107, 1323, 6769, 0 }; + static ulong[] dim1080JoeKuoD6Init = { 1, 3, 7, 1, 9, 33, 117, 249, 167, 631, 717, 3901, 6125, 0 }; + static ulong[] dim1081JoeKuoD6Init = { 1, 3, 7, 9, 31, 11, 75, 125, 417, 803, 1117, 1609, 3263, 0 }; + static ulong[] dim1082JoeKuoD6Init = { 1, 3, 1, 3, 15, 33, 35, 205, 477, 939, 1891, 2579, 2035, 0 }; + static ulong[] dim1083JoeKuoD6Init = { 1, 3, 5, 1, 5, 21, 5, 221, 105, 103, 587, 2111, 5891, 0 }; + static ulong[] dim1084JoeKuoD6Init = { 1, 3, 1, 11, 3, 45, 91, 113, 311, 617, 1629, 1677, 2349, 0 }; + static ulong[] dim1085JoeKuoD6Init = { 1, 1, 7, 13, 27, 17, 69, 11, 75, 545, 1245, 785, 645, 0 }; + static ulong[] dim1086JoeKuoD6Init = { 1, 3, 3, 5, 23, 13, 87, 193, 407, 445, 1299, 81, 2679, 0 }; + static ulong[] dim1087JoeKuoD6Init = { 1, 1, 7, 15, 17, 43, 13, 233, 255, 51, 1277, 965, 1615, 0 }; + static ulong[] dim1088JoeKuoD6Init = { 1, 3, 7, 1, 31, 49, 21, 61, 269, 265, 25, 3141, 7687, 0 }; + static ulong[] dim1089JoeKuoD6Init = { 1, 3, 3, 13, 27, 39, 65, 69, 453, 203, 461, 1585, 5681, 0 }; + static ulong[] dim1090JoeKuoD6Init = { 1, 1, 3, 3, 23, 19, 63, 97, 339, 83, 671, 433, 5285, 0 }; + static ulong[] dim1091JoeKuoD6Init = { 1, 3, 7, 11, 9, 3, 119, 157, 385, 847, 1159, 1389, 5833, 0 }; + static ulong[] dim1092JoeKuoD6Init = { 1, 1, 5, 5, 31, 51, 39, 247, 71, 815, 1807, 1973, 1841, 0 }; + static ulong[] dim1093JoeKuoD6Init = { 1, 1, 3, 3, 31, 39, 121, 75, 343, 25, 59, 575, 3503, 0 }; + static ulong[] dim1094JoeKuoD6Init = { 1, 1, 5, 11, 23, 17, 35, 33, 437, 1001, 1941, 351, 2949, 0 }; + static ulong[] dim1095JoeKuoD6Init = { 1, 1, 3, 7, 9, 51, 125, 3, 279, 373, 157, 1537, 5547, 0 }; + static ulong[] dim1096JoeKuoD6Init = { 1, 3, 1, 11, 11, 23, 63, 91, 139, 911, 463, 1831, 7325, 0 }; + static ulong[] dim1097JoeKuoD6Init = { 1, 3, 7, 1, 9, 11, 33, 125, 471, 583, 881, 2533, 7173, 0 }; + static ulong[] dim1098JoeKuoD6Init = { 1, 1, 5, 1, 15, 41, 53, 77, 43, 237, 787, 3299, 5131, 0 }; + static ulong[] dim1099JoeKuoD6Init = { 1, 1, 7, 7, 17, 19, 115, 145, 231, 555, 1279, 605, 2977, 0 }; + static ulong[] dim1100JoeKuoD6Init = { 1, 1, 3, 7, 21, 47, 61, 171, 337, 441, 1961, 2815, 4565, 0 }; + static ulong[] dim1101JoeKuoD6Init = { 1, 1, 7, 9, 25, 25, 3, 199, 85, 129, 1853, 3293, 71, 0 }; + static ulong[] dim1102JoeKuoD6Init = { 1, 1, 3, 1, 25, 25, 113, 9, 453, 353, 1955, 1443, 7027, 0 }; + static ulong[] dim1103JoeKuoD6Init = { 1, 3, 3, 11, 9, 35, 89, 149, 335, 485, 37, 1519, 7341, 0 }; + static ulong[] dim1104JoeKuoD6Init = { 1, 3, 7, 15, 27, 1, 119, 175, 181, 353, 1667, 2023, 3239, 0 }; + static ulong[] dim1105JoeKuoD6Init = { 1, 1, 1, 5, 27, 11, 39, 255, 283, 101, 603, 541, 2429, 0 }; + static ulong[] dim1106JoeKuoD6Init = { 1, 1, 7, 11, 27, 51, 87, 187, 183, 1013, 1207, 3431, 3321, 0 }; + static ulong[] dim1107JoeKuoD6Init = { 1, 1, 5, 3, 5, 15, 107, 171, 139, 919, 235, 3047, 3401, 0 }; + static ulong[] dim1108JoeKuoD6Init = { 1, 3, 3, 1, 17, 49, 35, 37, 59, 61, 227, 3175, 4093, 0 }; + static ulong[] dim1109JoeKuoD6Init = { 1, 1, 3, 1, 23, 51, 43, 143, 389, 559, 349, 1933, 6149, 0 }; + static ulong[] dim1110JoeKuoD6Init = { 1, 3, 5, 13, 9, 19, 111, 233, 373, 883, 1653, 1591, 2971, 0 }; + static ulong[] dim1111JoeKuoD6Init = { 1, 3, 3, 13, 7, 63, 95, 29, 173, 175, 355, 877, 5819, 15873, 0 }; + static ulong[] dim1112JoeKuoD6Init = { 1, 1, 1, 7, 1, 63, 23, 73, 469, 893, 773, 3647, 1191, 8731, 0 }; + static ulong[] dim1113JoeKuoD6Init = { 1, 3, 3, 9, 17, 9, 85, 137, 53, 793, 439, 2097, 4257, 8439, 0 }; + static ulong[] dim1114JoeKuoD6Init = { 1, 1, 7, 15, 3, 57, 83, 83, 123, 399, 1659, 2621, 3355, 255, 0 }; + static ulong[] dim1115JoeKuoD6Init = { 1, 1, 5, 13, 9, 55, 21, 55, 391, 765, 2023, 1211, 1265, 5391, 0 }; + static ulong[] dim1116JoeKuoD6Init = { 1, 1, 1, 11, 31, 63, 43, 153, 423, 969, 931, 531, 1635, 4695, 0 }; + static ulong[] dim1117JoeKuoD6Init = { 1, 1, 5, 11, 19, 11, 115, 213, 473, 13, 853, 3771, 7841, 1249, 0 }; + static ulong[] dim1118JoeKuoD6Init = { 1, 1, 1, 5, 31, 51, 121, 97, 483, 511, 299, 3307, 3363, 12639, 0 }; + static ulong[] dim1119JoeKuoD6Init = { 1, 3, 3, 1, 31, 31, 89, 221, 451, 253, 1371, 2457, 573, 4359, 0 }; + static ulong[] dim1120JoeKuoD6Init = { 1, 1, 7, 5, 5, 21, 59, 151, 275, 937, 1603, 3337, 3157, 15289, 0 }; + static ulong[] dim1121JoeKuoD6Init = { 1, 3, 1, 3, 19, 11, 27, 5, 405, 899, 1315, 3299, 945, 1421, 0 }; + static ulong[] dim1122JoeKuoD6Init = { 1, 3, 7, 3, 31, 55, 85, 49, 303, 859, 469, 723, 2221, 4099, 0 }; + static ulong[] dim1123JoeKuoD6Init = { 1, 1, 5, 13, 31, 27, 57, 37, 493, 883, 1781, 2915, 6435, 6905, 0 }; + static ulong[] dim1124JoeKuoD6Init = { 1, 1, 1, 7, 21, 49, 111, 69, 221, 845, 219, 1257, 7909, 15225, 0 }; + static ulong[] dim1125JoeKuoD6Init = { 1, 3, 1, 3, 3, 1, 89, 143, 359, 717, 327, 1063, 3845, 8963, 0 }; + static ulong[] dim1126JoeKuoD6Init = { 1, 1, 3, 7, 31, 3, 5, 79, 241, 877, 309, 3735, 1409, 11947, 0 }; + static ulong[] dim1127JoeKuoD6Init = { 1, 1, 1, 7, 13, 63, 89, 69, 417, 809, 1251, 3213, 1107, 9143, 0 }; + static ulong[] dim1128JoeKuoD6Init = { 1, 3, 7, 9, 21, 3, 17, 231, 273, 545, 1385, 1367, 5491, 7497, 0 }; + static ulong[] dim1129JoeKuoD6Init = { 1, 1, 7, 1, 31, 35, 117, 31, 173, 711, 555, 1551, 443, 10469, 0 }; + static ulong[] dim1130JoeKuoD6Init = { 1, 1, 5, 9, 3, 61, 55, 31, 321, 517, 47, 1379, 4329, 2305, 0 }; + static ulong[] dim1131JoeKuoD6Init = { 1, 1, 5, 15, 15, 13, 23, 153, 209, 115, 913, 2013, 841, 2015, 0 }; + static ulong[] dim1132JoeKuoD6Init = { 1, 3, 1, 5, 15, 43, 31, 103, 55, 489, 1003, 2723, 2613, 15743, 0 }; + static ulong[] dim1133JoeKuoD6Init = { 1, 3, 5, 3, 31, 45, 21, 37, 453, 99, 1047, 235, 1133, 11199, 0 }; + static ulong[] dim1134JoeKuoD6Init = { 1, 1, 1, 9, 13, 25, 109, 129, 25, 291, 445, 2775, 1011, 4645, 0 }; + static ulong[] dim1135JoeKuoD6Init = { 1, 1, 3, 9, 9, 45, 7, 161, 217, 645, 421, 3429, 2941, 5319, 0 }; + static ulong[] dim1136JoeKuoD6Init = { 1, 1, 3, 15, 13, 57, 13, 63, 89, 739, 1989, 1679, 2031, 265, 0 }; + static ulong[] dim1137JoeKuoD6Init = { 1, 3, 7, 9, 21, 63, 117, 21, 345, 19, 1357, 611, 6591, 8075, 0 }; + static ulong[] dim1138JoeKuoD6Init = { 1, 1, 7, 13, 29, 37, 37, 219, 81, 143, 1505, 2921, 1497, 4359, 0 }; + static ulong[] dim1139JoeKuoD6Init = { 1, 3, 5, 9, 25, 23, 39, 145, 121, 877, 1491, 2687, 865, 3417, 0 }; + static ulong[] dim1140JoeKuoD6Init = { 1, 1, 1, 13, 25, 7, 45, 143, 61, 591, 455, 3039, 4147, 1695, 0 }; + static ulong[] dim1141JoeKuoD6Init = { 1, 1, 1, 9, 27, 7, 61, 139, 509, 843, 1175, 3787, 4695, 13851, 0 }; + static ulong[] dim1142JoeKuoD6Init = { 1, 3, 1, 5, 15, 19, 73, 109, 263, 791, 455, 3503, 1203, 4993, 0 }; + static ulong[] dim1143JoeKuoD6Init = { 1, 1, 1, 11, 21, 59, 51, 101, 407, 25, 355, 2817, 3323, 14641, 0 }; + static ulong[] dim1144JoeKuoD6Init = { 1, 3, 1, 13, 3, 45, 73, 241, 511, 763, 189, 2913, 489, 10441, 0 }; + static ulong[] dim1145JoeKuoD6Init = { 1, 1, 7, 9, 15, 9, 113, 103, 375, 773, 621, 3035, 4359, 13259, 0 }; + static ulong[] dim1146JoeKuoD6Init = { 1, 3, 1, 1, 17, 13, 81, 207, 493, 737, 427, 2895, 539, 4125, 0 }; + static ulong[] dim1147JoeKuoD6Init = { 1, 1, 1, 11, 9, 5, 89, 209, 175, 105, 293, 3337, 7235, 6481, 0 }; + static ulong[] dim1148JoeKuoD6Init = { 1, 3, 1, 13, 5, 19, 3, 245, 25, 733, 885, 3747, 3997, 7945, 0 }; + static ulong[] dim1149JoeKuoD6Init = { 1, 3, 3, 11, 13, 7, 29, 169, 239, 205, 1399, 1447, 5211, 11789, 0 }; + static ulong[] dim1150JoeKuoD6Init = { 1, 3, 1, 15, 7, 19, 65, 23, 183, 547, 671, 2873, 5101, 4187, 0 }; + static ulong[] dim1151JoeKuoD6Init = { 1, 3, 5, 13, 15, 35, 119, 75, 53, 773, 1769, 1945, 7781, 11349, 0 }; + static ulong[] dim1152JoeKuoD6Init = { 1, 3, 7, 9, 31, 37, 39, 55, 333, 567, 1095, 3707, 4265, 117, 0 }; + static ulong[] dim1153JoeKuoD6Init = { 1, 3, 1, 3, 1, 61, 9, 7, 253, 737, 1441, 2591, 2807, 13685, 0 }; + static ulong[] dim1154JoeKuoD6Init = { 1, 1, 3, 11, 21, 41, 81, 61, 497, 827, 783, 3799, 4803, 141, 0 }; + static ulong[] dim1155JoeKuoD6Init = { 1, 3, 7, 13, 11, 15, 3, 165, 401, 747, 1961, 3265, 8123, 2151, 0 }; + static ulong[] dim1156JoeKuoD6Init = { 1, 3, 3, 15, 21, 39, 47, 135, 61, 803, 1447, 1763, 2033, 12907, 0 }; + static ulong[] dim1157JoeKuoD6Init = { 1, 1, 1, 9, 25, 21, 15, 233, 493, 115, 921, 2047, 3715, 9089, 0 }; + static ulong[] dim1158JoeKuoD6Init = { 1, 3, 5, 5, 11, 17, 43, 49, 249, 873, 771, 47, 5357, 12459, 0 }; + static ulong[] dim1159JoeKuoD6Init = { 1, 3, 3, 13, 31, 39, 85, 97, 241, 529, 65, 1995, 2411, 761, 0 }; + static ulong[] dim1160JoeKuoD6Init = { 1, 3, 5, 15, 3, 1, 63, 229, 11, 733, 901, 63, 3585, 10273, 0 }; + static ulong[] dim1161JoeKuoD6Init = { 1, 1, 1, 13, 23, 39, 123, 187, 27, 893, 1127, 2781, 5977, 13797, 0 }; + static ulong[] dim1162JoeKuoD6Init = { 1, 1, 5, 13, 15, 35, 97, 29, 345, 447, 897, 793, 5155, 15939, 0 }; + static ulong[] dim1163JoeKuoD6Init = { 1, 1, 3, 3, 1, 15, 19, 189, 183, 137, 1059, 2135, 6891, 10319, 0 }; + static ulong[] dim1164JoeKuoD6Init = { 1, 1, 1, 11, 29, 27, 83, 111, 113, 225, 1527, 1071, 635, 3471, 0 }; + static ulong[] dim1165JoeKuoD6Init = { 1, 3, 1, 3, 27, 9, 43, 19, 409, 579, 1983, 811, 5477, 559, 0 }; + static ulong[] dim1166JoeKuoD6Init = { 1, 3, 7, 9, 1, 39, 121, 249, 355, 677, 899, 729, 2611, 9463, 0 }; + static ulong[] dim1167JoeKuoD6Init = { 1, 1, 1, 11, 31, 43, 47, 157, 309, 529, 787, 1935, 5679, 1553, 0 }; + static ulong[] dim1168JoeKuoD6Init = { 1, 1, 5, 15, 19, 53, 63, 71, 371, 455, 1943, 477, 6227, 1033, 0 }; + static ulong[] dim1169JoeKuoD6Init = { 1, 1, 3, 15, 9, 55, 45, 247, 189, 57, 1573, 591, 2831, 14273, 0 }; + static ulong[] dim1170JoeKuoD6Init = { 1, 3, 5, 7, 3, 37, 33, 219, 13, 163, 763, 3921, 7617, 15439, 0 }; + static ulong[] dim1171JoeKuoD6Init = { 1, 3, 1, 13, 21, 41, 85, 151, 117, 587, 1513, 17, 7695, 4135, 0 }; + static ulong[] dim1172JoeKuoD6Init = { 1, 3, 1, 5, 21, 51, 107, 209, 107, 459, 243, 3043, 473, 1357, 0 }; + static ulong[] dim1173JoeKuoD6Init = { 1, 3, 1, 1, 5, 49, 87, 203, 261, 935, 765, 2879, 7677, 607, 0 }; + static ulong[] dim1174JoeKuoD6Init = { 1, 3, 7, 15, 25, 31, 7, 53, 391, 569, 187, 2761, 1369, 8871, 0 }; + static ulong[] dim1175JoeKuoD6Init = { 1, 1, 1, 15, 9, 25, 31, 59, 485, 253, 381, 1239, 4797, 4691, 0 }; + static ulong[] dim1176JoeKuoD6Init = { 1, 3, 5, 9, 13, 17, 35, 97, 339, 47, 1053, 293, 8103, 8489, 0 }; + static ulong[] dim1177JoeKuoD6Init = { 1, 1, 1, 11, 13, 7, 43, 33, 187, 135, 277, 1011, 297, 8443, 0 }; + static ulong[] dim1178JoeKuoD6Init = { 1, 3, 5, 1, 13, 45, 125, 185, 369, 643, 791, 119, 7205, 6785, 0 }; + static ulong[] dim1179JoeKuoD6Init = { 1, 1, 3, 15, 15, 39, 89, 33, 47, 801, 1451, 2583, 445, 14029, 0 }; + static ulong[] dim1180JoeKuoD6Init = { 1, 3, 1, 13, 27, 53, 113, 159, 395, 835, 655, 3503, 3733, 1547, 0 }; + static ulong[] dim1181JoeKuoD6Init = { 1, 1, 7, 5, 29, 61, 43, 181, 127, 839, 755, 579, 6805, 4591, 0 }; + static ulong[] dim1182JoeKuoD6Init = { 1, 3, 1, 1, 29, 63, 71, 145, 149, 571, 1129, 2503, 5761, 6251, 0 }; + static ulong[] dim1183JoeKuoD6Init = { 1, 3, 5, 7, 7, 21, 73, 101, 29, 517, 235, 195, 3561, 15347, 0 }; + static ulong[] dim1184JoeKuoD6Init = { 1, 3, 5, 9, 11, 11, 109, 81, 483, 183, 753, 1635, 3763, 8141, 0 }; + static ulong[] dim1185JoeKuoD6Init = { 1, 3, 5, 1, 21, 35, 111, 251, 255, 605, 1613, 283, 3035, 11681, 0 }; + static ulong[] dim1186JoeKuoD6Init = { 1, 3, 7, 3, 29, 49, 43, 255, 217, 791, 1281, 2327, 5115, 10261, 0 }; + static ulong[] dim1187JoeKuoD6Init = { 1, 3, 7, 9, 19, 23, 93, 105, 69, 429, 1729, 3547, 217, 15075, 0 }; + static ulong[] dim1188JoeKuoD6Init = { 1, 3, 1, 9, 7, 21, 13, 81, 395, 997, 399, 3925, 7277, 1733, 0 }; + static ulong[] dim1189JoeKuoD6Init = { 1, 3, 7, 13, 11, 51, 65, 29, 489, 489, 1639, 3949, 6271, 2015, 0 }; + static ulong[] dim1190JoeKuoD6Init = { 1, 1, 7, 1, 15, 39, 23, 67, 121, 617, 1689, 1887, 3485, 7913, 0 }; + static ulong[] dim1191JoeKuoD6Init = { 1, 3, 7, 3, 25, 23, 81, 59, 87, 457, 937, 3229, 2731, 5003, 0 }; + static ulong[] dim1192JoeKuoD6Init = { 1, 1, 5, 11, 29, 41, 21, 67, 475, 127, 1113, 1693, 3705, 1051, 0 }; + static ulong[] dim1193JoeKuoD6Init = { 1, 3, 7, 3, 13, 7, 33, 95, 123, 65, 2039, 1011, 5175, 10459, 0 }; + static ulong[] dim1194JoeKuoD6Init = { 1, 1, 7, 9, 29, 53, 113, 57, 323, 309, 501, 3971, 5999, 16335, 0 }; + static ulong[] dim1195JoeKuoD6Init = { 1, 1, 1, 13, 29, 9, 17, 49, 173, 473, 555, 3753, 7471, 10099, 0 }; + static ulong[] dim1196JoeKuoD6Init = { 1, 3, 3, 3, 23, 3, 101, 199, 351, 435, 1919, 1175, 8037, 2259, 0 }; + static ulong[] dim1197JoeKuoD6Init = { 1, 3, 1, 7, 29, 27, 23, 61, 197, 883, 153, 683, 2109, 14991, 0 }; + static ulong[] dim1198JoeKuoD6Init = { 1, 1, 5, 11, 15, 21, 23, 9, 341, 391, 1537, 3483, 4641, 12489, 0 }; + static ulong[] dim1199JoeKuoD6Init = { 1, 3, 7, 1, 1, 9, 3, 7, 485, 377, 597, 2277, 7811, 1303, 0 }; + static ulong[] dim1200JoeKuoD6Init = { 1, 3, 3, 9, 13, 23, 13, 1, 353, 517, 1787, 2095, 3095, 4999, 0 }; + static ulong[] dim1201JoeKuoD6Init = { 1, 3, 5, 13, 17, 13, 55, 165, 487, 387, 839, 2867, 3939, 7945, 0 }; + static ulong[] dim1202JoeKuoD6Init = { 1, 3, 5, 3, 15, 25, 103, 225, 275, 571, 441, 567, 4759, 12965, 0 }; + static ulong[] dim1203JoeKuoD6Init = { 1, 1, 3, 5, 19, 31, 121, 109, 89, 315, 1517, 187, 1645, 2331, 0 }; + static ulong[] dim1204JoeKuoD6Init = { 1, 1, 7, 3, 17, 49, 87, 241, 491, 99, 1559, 843, 5627, 2383, 0 }; + static ulong[] dim1205JoeKuoD6Init = { 1, 3, 7, 7, 21, 55, 69, 27, 461, 663, 1609, 4059, 4097, 2299, 0 }; + static ulong[] dim1206JoeKuoD6Init = { 1, 1, 1, 13, 1, 27, 35, 63, 125, 293, 721, 1433, 4813, 15439, 0 }; + static ulong[] dim1207JoeKuoD6Init = { 1, 1, 1, 15, 19, 13, 65, 55, 101, 981, 989, 3501, 8125, 8849, 0 }; + static ulong[] dim1208JoeKuoD6Init = { 1, 1, 5, 13, 25, 45, 23, 157, 165, 581, 1613, 3721, 7569, 9347, 0 }; + static ulong[] dim1209JoeKuoD6Init = { 1, 1, 1, 5, 29, 47, 51, 43, 221, 809, 469, 2089, 2721, 3799, 0 }; + static ulong[] dim1210JoeKuoD6Init = { 1, 3, 7, 9, 11, 63, 107, 33, 433, 381, 819, 739, 7861, 12219, 0 }; + static ulong[] dim1211JoeKuoD6Init = { 1, 3, 5, 7, 29, 27, 105, 219, 227, 851, 1287, 1825, 1861, 8171, 0 }; + static ulong[] dim1212JoeKuoD6Init = { 1, 3, 1, 11, 1, 31, 77, 183, 81, 781, 541, 1663, 3, 12533, 0 }; + static ulong[] dim1213JoeKuoD6Init = { 1, 3, 3, 1, 7, 59, 107, 49, 147, 625, 593, 729, 4335, 12651, 0 }; + static ulong[] dim1214JoeKuoD6Init = { 1, 3, 1, 11, 25, 45, 55, 117, 247, 499, 1403, 3321, 6769, 15183, 0 }; + static ulong[] dim1215JoeKuoD6Init = { 1, 1, 3, 13, 15, 51, 41, 111, 297, 283, 1943, 2741, 5087, 12203, 0 }; + static ulong[] dim1216JoeKuoD6Init = { 1, 3, 1, 13, 19, 37, 59, 149, 481, 211, 69, 1253, 8019, 10607, 0 }; + static ulong[] dim1217JoeKuoD6Init = { 1, 3, 1, 1, 21, 61, 103, 93, 75, 91, 1695, 3683, 679, 14789, 0 }; + static ulong[] dim1218JoeKuoD6Init = { 1, 3, 1, 3, 27, 19, 101, 215, 165, 887, 1647, 4033, 7709, 15581, 0 }; + static ulong[] dim1219JoeKuoD6Init = { 1, 1, 1, 9, 17, 9, 15, 231, 335, 227, 661, 2505, 6525, 15019, 0 }; + static ulong[] dim1220JoeKuoD6Init = { 1, 3, 3, 13, 15, 63, 81, 221, 117, 893, 875, 485, 7323, 11105, 0 }; + static ulong[] dim1221JoeKuoD6Init = { 1, 3, 1, 3, 7, 57, 115, 159, 457, 235, 1245, 973, 7801, 4753, 0 }; + static ulong[] dim1222JoeKuoD6Init = { 1, 3, 5, 7, 7, 21, 3, 49, 455, 733, 323, 261, 7809, 4699, 0 }; + static ulong[] dim1223JoeKuoD6Init = { 1, 1, 7, 3, 17, 31, 15, 105, 81, 901, 1107, 2161, 6631, 14523, 0 }; + static ulong[] dim1224JoeKuoD6Init = { 1, 1, 7, 15, 21, 51, 125, 227, 321, 665, 13, 3203, 6117, 15401, 0 }; + static ulong[] dim1225JoeKuoD6Init = { 1, 1, 5, 11, 23, 23, 27, 31, 489, 625, 1973, 2005, 7097, 11557, 0 }; + static ulong[] dim1226JoeKuoD6Init = { 1, 1, 7, 11, 27, 37, 41, 79, 373, 207, 1399, 2629, 953, 8649, 0 }; + static ulong[] dim1227JoeKuoD6Init = { 1, 1, 5, 5, 27, 15, 73, 37, 277, 301, 207, 2283, 2787, 8475, 0 }; + static ulong[] dim1228JoeKuoD6Init = { 1, 3, 5, 11, 7, 47, 3, 169, 201, 573, 1953, 915, 4509, 7767, 0 }; + static ulong[] dim1229JoeKuoD6Init = { 1, 3, 3, 7, 21, 21, 97, 69, 501, 491, 1471, 657, 5661, 2315, 0 }; + static ulong[] dim1230JoeKuoD6Init = { 1, 1, 1, 1, 21, 17, 127, 207, 255, 357, 59, 1035, 4497, 7397, 0 }; + static ulong[] dim1231JoeKuoD6Init = { 1, 3, 7, 1, 17, 55, 71, 35, 85, 5, 507, 1445, 2201, 14137, 0 }; + static ulong[] dim1232JoeKuoD6Init = { 1, 1, 1, 9, 23, 11, 21, 67, 347, 845, 443, 2461, 2767, 1603, 0 }; + static ulong[] dim1233JoeKuoD6Init = { 1, 3, 3, 11, 25, 11, 97, 225, 301, 111, 1163, 1783, 7879, 15191, 0 }; + static ulong[] dim1234JoeKuoD6Init = { 1, 3, 5, 11, 29, 55, 9, 137, 233, 51, 1957, 3807, 2631, 2255, 0 }; + static ulong[] dim1235JoeKuoD6Init = { 1, 1, 7, 1, 19, 41, 83, 121, 283, 839, 179, 3307, 4679, 1163, 0 }; + static ulong[] dim1236JoeKuoD6Init = { 1, 1, 3, 9, 17, 1, 11, 47, 295, 189, 1863, 1145, 367, 41, 0 }; + static ulong[] dim1237JoeKuoD6Init = { 1, 3, 1, 5, 7, 29, 85, 169, 479, 27, 1681, 917, 3983, 5041, 0 }; + static ulong[] dim1238JoeKuoD6Init = { 1, 1, 7, 15, 13, 29, 39, 131, 491, 361, 565, 271, 6255, 10815, 0 }; + static ulong[] dim1239JoeKuoD6Init = { 1, 1, 3, 3, 5, 63, 23, 201, 377, 593, 825, 339, 1065, 8989, 0 }; + static ulong[] dim1240JoeKuoD6Init = { 1, 3, 1, 1, 19, 33, 103, 187, 327, 85, 55, 2561, 6833, 3889, 0 }; + static ulong[] dim1241JoeKuoD6Init = { 1, 1, 5, 5, 5, 7, 85, 103, 463, 279, 47, 2479, 2149, 1421, 0 }; + static ulong[] dim1242JoeKuoD6Init = { 1, 1, 3, 13, 17, 31, 61, 247, 59, 869, 1513, 2405, 2129, 15647, 0 }; + static ulong[] dim1243JoeKuoD6Init = { 1, 1, 3, 13, 7, 31, 99, 63, 289, 123, 617, 3263, 6445, 14101, 0 }; + static ulong[] dim1244JoeKuoD6Init = { 1, 3, 7, 5, 13, 23, 107, 73, 19, 595, 1623, 1583, 15, 10907, 0 }; + static ulong[] dim1245JoeKuoD6Init = { 1, 1, 5, 15, 19, 33, 113, 45, 435, 99, 1909, 3317, 1733, 3629, 0 }; + static ulong[] dim1246JoeKuoD6Init = { 1, 1, 7, 13, 3, 9, 107, 59, 69, 781, 1861, 393, 7143, 4465, 0 }; + static ulong[] dim1247JoeKuoD6Init = { 1, 3, 5, 3, 23, 49, 3, 173, 483, 353, 783, 717, 2903, 11101, 0 }; + static ulong[] dim1248JoeKuoD6Init = { 1, 3, 7, 15, 27, 25, 105, 47, 387, 103, 323, 455, 1607, 3673, 0 }; + static ulong[] dim1249JoeKuoD6Init = { 1, 1, 7, 5, 19, 49, 59, 159, 5, 595, 75, 1963, 313, 5593, 0 }; + static ulong[] dim1250JoeKuoD6Init = { 1, 3, 3, 15, 27, 35, 51, 135, 347, 375, 493, 589, 507, 4661, 0 }; + static ulong[] dim1251JoeKuoD6Init = { 1, 1, 1, 5, 5, 59, 103, 249, 473, 503, 1401, 3219, 4337, 3607, 0 }; + static ulong[] dim1252JoeKuoD6Init = { 1, 3, 1, 15, 29, 15, 123, 165, 55, 515, 1009, 3231, 3567, 7871, 0 }; + static ulong[] dim1253JoeKuoD6Init = { 1, 3, 5, 7, 5, 11, 45, 87, 67, 359, 43, 457, 6483, 5165, 0 }; + static ulong[] dim1254JoeKuoD6Init = { 1, 1, 1, 15, 13, 55, 85, 51, 127, 937, 1505, 1445, 889, 789, 0 }; + static ulong[] dim1255JoeKuoD6Init = { 1, 1, 5, 1, 31, 27, 5, 225, 209, 291, 1047, 3417, 2899, 9691, 0 }; + static ulong[] dim1256JoeKuoD6Init = { 1, 1, 1, 5, 23, 9, 83, 201, 511, 805, 1341, 2791, 4803, 13523, 0 }; + static ulong[] dim1257JoeKuoD6Init = { 1, 3, 5, 7, 29, 29, 31, 239, 175, 1005, 1443, 2543, 6235, 15409, 0 }; + static ulong[] dim1258JoeKuoD6Init = { 1, 3, 5, 5, 31, 7, 17, 195, 15, 65, 1297, 2707, 3097, 2281, 0 }; + static ulong[] dim1259JoeKuoD6Init = { 1, 1, 3, 1, 25, 43, 57, 219, 419, 9, 1121, 593, 4403, 147, 0 }; + static ulong[] dim1260JoeKuoD6Init = { 1, 1, 3, 7, 5, 31, 27, 43, 343, 95, 1917, 2425, 4939, 2937, 0 }; + static ulong[] dim1261JoeKuoD6Init = { 1, 3, 1, 1, 31, 35, 19, 151, 339, 411, 77, 3881, 7401, 927, 0 }; + static ulong[] dim1262JoeKuoD6Init = { 1, 3, 1, 7, 3, 61, 37, 135, 159, 81, 157, 2945, 6371, 3583, 0 }; + static ulong[] dim1263JoeKuoD6Init = { 1, 1, 7, 1, 15, 27, 113, 213, 127, 141, 1431, 2163, 2527, 4027, 0 }; + static ulong[] dim1264JoeKuoD6Init = { 1, 3, 1, 13, 1, 39, 103, 187, 395, 283, 907, 3977, 5901, 6043, 0 }; + static ulong[] dim1265JoeKuoD6Init = { 1, 3, 7, 1, 31, 47, 45, 95, 53, 165, 357, 3893, 1555, 2263, 0 }; + static ulong[] dim1266JoeKuoD6Init = { 1, 1, 1, 7, 1, 57, 39, 39, 365, 193, 887, 815, 7309, 15089, 0 }; + static ulong[] dim1267JoeKuoD6Init = { 1, 1, 3, 11, 25, 61, 21, 139, 241, 167, 843, 299, 7737, 4625, 0 }; + static ulong[] dim1268JoeKuoD6Init = { 1, 3, 5, 3, 29, 49, 115, 55, 185, 157, 515, 1985, 5891, 11189, 0 }; + static ulong[] dim1269JoeKuoD6Init = { 1, 1, 1, 1, 1, 9, 41, 227, 267, 581, 5, 2677, 1231, 6989, 0 }; + static ulong[] dim1270JoeKuoD6Init = { 1, 1, 3, 5, 13, 57, 33, 211, 333, 277, 1387, 2673, 5923, 15623, 0 }; + static ulong[] dim1271JoeKuoD6Init = { 1, 1, 1, 9, 5, 57, 123, 93, 387, 975, 251, 677, 2843, 2237, 0 }; + static ulong[] dim1272JoeKuoD6Init = { 1, 1, 7, 1, 5, 15, 19, 241, 171, 713, 1761, 3363, 2707, 7629, 0 }; + static ulong[] dim1273JoeKuoD6Init = { 1, 1, 1, 13, 13, 25, 125, 233, 377, 1005, 1591, 1327, 7661, 15701, 0 }; + static ulong[] dim1274JoeKuoD6Init = { 1, 1, 5, 15, 23, 39, 77, 121, 255, 105, 1739, 3511, 2369, 2209, 0 }; + static ulong[] dim1275JoeKuoD6Init = { 1, 3, 5, 11, 5, 23, 11, 29, 501, 753, 1317, 1927, 2127, 7753, 0 }; + static ulong[] dim1276JoeKuoD6Init = { 1, 3, 1, 1, 31, 25, 45, 197, 483, 787, 721, 2227, 4237, 1985, 0 }; + static ulong[] dim1277JoeKuoD6Init = { 1, 3, 7, 7, 1, 53, 51, 235, 255, 517, 1389, 2381, 7845, 8707, 0 }; + static ulong[] dim1278JoeKuoD6Init = { 1, 1, 1, 5, 27, 9, 19, 251, 29, 211, 1665, 1181, 983, 16139, 0 }; + static ulong[] dim1279JoeKuoD6Init = { 1, 1, 5, 11, 21, 35, 39, 47, 445, 685, 773, 3563, 3339, 14855, 0 }; + static ulong[] dim1280JoeKuoD6Init = { 1, 3, 7, 7, 29, 61, 89, 203, 239, 11, 1407, 1529, 3581, 11443, 0 }; + static ulong[] dim1281JoeKuoD6Init = { 1, 3, 3, 5, 19, 21, 3, 253, 437, 755, 1409, 1449, 623, 10533, 0 }; + static ulong[] dim1282JoeKuoD6Init = { 1, 3, 3, 15, 13, 25, 65, 123, 273, 611, 1305, 2751, 5123, 1515, 0 }; + static ulong[] dim1283JoeKuoD6Init = { 1, 1, 3, 5, 13, 63, 79, 139, 253, 917, 19, 1129, 7801, 14215, 0 }; + static ulong[] dim1284JoeKuoD6Init = { 1, 1, 5, 9, 5, 21, 29, 179, 79, 803, 1163, 2481, 3537, 11015, 0 }; + static ulong[] dim1285JoeKuoD6Init = { 1, 3, 5, 1, 9, 51, 35, 241, 473, 291, 147, 3021, 2147, 4437, 0 }; + static ulong[] dim1286JoeKuoD6Init = { 1, 1, 7, 15, 7, 19, 81, 215, 205, 19, 1713, 1347, 7519, 9851, 0 }; + static ulong[] dim1287JoeKuoD6Init = { 1, 1, 7, 1, 9, 49, 35, 219, 73, 479, 559, 1619, 7891, 1221, 0 }; + static ulong[] dim1288JoeKuoD6Init = { 1, 1, 3, 1, 9, 39, 17, 67, 139, 287, 703, 3797, 4263, 10847, 0 }; + static ulong[] dim1289JoeKuoD6Init = { 1, 3, 7, 9, 23, 23, 17, 221, 185, 209, 1827, 3117, 8183, 15405, 0 }; + static ulong[] dim1290JoeKuoD6Init = { 1, 3, 5, 9, 9, 9, 95, 1, 225, 727, 1577, 3947, 7995, 2587, 0 }; + static ulong[] dim1291JoeKuoD6Init = { 1, 1, 5, 7, 5, 29, 89, 193, 427, 1009, 1123, 717, 3191, 14381, 0 }; + static ulong[] dim1292JoeKuoD6Init = { 1, 3, 1, 9, 7, 53, 57, 147, 511, 887, 501, 431, 7537, 363, 0 }; + static ulong[] dim1293JoeKuoD6Init = { 1, 1, 3, 7, 3, 21, 127, 157, 45, 773, 1973, 2577, 6057, 8153, 0 }; + static ulong[] dim1294JoeKuoD6Init = { 1, 3, 3, 9, 31, 63, 23, 47, 365, 369, 97, 1627, 831, 12769, 0 }; + static ulong[] dim1295JoeKuoD6Init = { 1, 3, 5, 9, 5, 61, 53, 131, 447, 281, 1115, 2523, 3789, 11581, 0 }; + static ulong[] dim1296JoeKuoD6Init = { 1, 1, 3, 5, 19, 39, 95, 243, 95, 601, 1385, 2523, 2973, 2759, 0 }; + static ulong[] dim1297JoeKuoD6Init = { 1, 3, 1, 15, 25, 15, 19, 133, 1, 197, 1259, 2501, 2513, 9417, 0 }; + static ulong[] dim1298JoeKuoD6Init = { 1, 1, 7, 1, 13, 49, 47, 61, 167, 971, 835, 2259, 3747, 13077, 0 }; + static ulong[] dim1299JoeKuoD6Init = { 1, 1, 5, 9, 17, 35, 33, 223, 173, 691, 855, 2743, 5383, 2017, 0 }; + static ulong[] dim1300JoeKuoD6Init = { 1, 3, 1, 5, 11, 35, 19, 255, 201, 801, 1921, 2511, 2497, 13317, 0 }; + static ulong[] dim1301JoeKuoD6Init = { 1, 1, 7, 9, 17, 1, 47, 187, 63, 641, 1395, 1591, 6145, 4549, 0 }; + static ulong[] dim1302JoeKuoD6Init = { 1, 1, 1, 1, 11, 35, 55, 167, 75, 801, 257, 2531, 1821, 11325, 0 }; + static ulong[] dim1303JoeKuoD6Init = { 1, 1, 1, 11, 21, 27, 117, 131, 167, 461, 1459, 1, 4847, 4347, 0 }; + static ulong[] dim1304JoeKuoD6Init = { 1, 1, 5, 15, 7, 19, 103, 233, 509, 397, 1147, 1325, 6173, 9643, 0 }; + static ulong[] dim1305JoeKuoD6Init = { 1, 3, 1, 11, 31, 37, 51, 43, 173, 575, 7, 3595, 5865, 7539, 0 }; + static ulong[] dim1306JoeKuoD6Init = { 1, 1, 5, 15, 17, 63, 109, 29, 325, 57, 889, 1197, 7839, 13931, 0 }; + static ulong[] dim1307JoeKuoD6Init = { 1, 1, 5, 15, 3, 19, 105, 251, 447, 451, 925, 1857, 4343, 14273, 0 }; + static ulong[] dim1308JoeKuoD6Init = { 1, 3, 1, 9, 27, 29, 97, 113, 155, 591, 1435, 2175, 4197, 10661, 0 }; + static ulong[] dim1309JoeKuoD6Init = { 1, 3, 1, 3, 9, 11, 33, 107, 187, 463, 1479, 1127, 6699, 2183, 0 }; + static ulong[] dim1310JoeKuoD6Init = { 1, 3, 3, 1, 5, 15, 73, 231, 73, 161, 525, 2265, 619, 8085, 0 }; + static ulong[] dim1311JoeKuoD6Init = { 1, 1, 1, 1, 1, 43, 7, 137, 163, 953, 775, 3839, 7377, 12321, 0 }; + static ulong[] dim1312JoeKuoD6Init = { 1, 1, 3, 3, 27, 57, 11, 131, 407, 41, 173, 2595, 5179, 1455, 0 }; + static ulong[] dim1313JoeKuoD6Init = { 1, 3, 5, 3, 31, 9, 93, 233, 61, 149, 1973, 3493, 5535, 9595, 0 }; + static ulong[] dim1314JoeKuoD6Init = { 1, 1, 5, 9, 1, 37, 13, 71, 451, 645, 51, 3663, 1917, 10641, 0 }; + static ulong[] dim1315JoeKuoD6Init = { 1, 3, 1, 11, 13, 53, 111, 71, 61, 539, 319, 1951, 6763, 751, 0 }; + static ulong[] dim1316JoeKuoD6Init = { 1, 1, 7, 1, 27, 27, 53, 189, 39, 29, 1645, 235, 7643, 15621, 0 }; + static ulong[] dim1317JoeKuoD6Init = { 1, 1, 7, 1, 13, 13, 115, 125, 109, 377, 463, 3819, 7397, 5205, 0 }; + static ulong[] dim1318JoeKuoD6Init = { 1, 1, 3, 9, 29, 59, 61, 145, 187, 875, 1571, 4035, 2861, 10897, 0 }; + static ulong[] dim1319JoeKuoD6Init = { 1, 1, 7, 1, 11, 5, 9, 19, 477, 201, 1061, 1483, 7597, 7161, 0 }; + static ulong[] dim1320JoeKuoD6Init = { 1, 3, 1, 13, 17, 35, 55, 211, 285, 161, 385, 4093, 3685, 3635, 0 }; + static ulong[] dim1321JoeKuoD6Init = { 1, 3, 1, 9, 19, 43, 95, 253, 453, 829, 857, 3913, 4949, 9057, 0 }; + static ulong[] dim1322JoeKuoD6Init = { 1, 1, 1, 13, 3, 45, 57, 185, 7, 457, 1805, 3947, 1515, 4863, 0 }; + static ulong[] dim1323JoeKuoD6Init = { 1, 1, 5, 1, 9, 27, 75, 243, 401, 593, 1669, 3315, 3023, 14677, 0 }; + static ulong[] dim1324JoeKuoD6Init = { 1, 1, 3, 13, 29, 57, 37, 11, 153, 255, 1039, 2067, 2033, 7927, 0 }; + static ulong[] dim1325JoeKuoD6Init = { 1, 3, 3, 13, 27, 63, 23, 73, 355, 913, 327, 43, 2095, 433, 0 }; + static ulong[] dim1326JoeKuoD6Init = { 1, 3, 3, 7, 13, 1, 61, 193, 73, 465, 1483, 1359, 7459, 6855, 0 }; + static ulong[] dim1327JoeKuoD6Init = { 1, 1, 7, 3, 15, 39, 85, 165, 285, 713, 1455, 403, 7723, 6595, 0 }; + static ulong[] dim1328JoeKuoD6Init = { 1, 1, 3, 9, 11, 39, 67, 43, 47, 85, 1831, 1387, 1423, 12473, 0 }; + static ulong[] dim1329JoeKuoD6Init = { 1, 3, 5, 3, 23, 11, 49, 195, 207, 403, 1761, 3633, 8069, 12455, 0 }; + static ulong[] dim1330JoeKuoD6Init = { 1, 1, 3, 7, 19, 11, 27, 131, 123, 685, 931, 2433, 7133, 1997, 0 }; + static ulong[] dim1331JoeKuoD6Init = { 1, 3, 3, 7, 27, 3, 69, 77, 227, 227, 213, 1277, 6597, 8343, 0 }; + static ulong[] dim1332JoeKuoD6Init = { 1, 3, 7, 5, 13, 61, 69, 63, 59, 949, 2019, 2723, 451, 9641, 0 }; + static ulong[] dim1333JoeKuoD6Init = { 1, 1, 7, 11, 19, 29, 75, 149, 481, 583, 861, 1353, 7525, 115, 0 }; + static ulong[] dim1334JoeKuoD6Init = { 1, 3, 5, 13, 19, 3, 27, 155, 81, 907, 683, 1997, 189, 12139, 0 }; + static ulong[] dim1335JoeKuoD6Init = { 1, 1, 5, 9, 19, 1, 61, 97, 433, 289, 1191, 2347, 5533, 14327, 0 }; + static ulong[] dim1336JoeKuoD6Init = { 1, 3, 1, 5, 13, 9, 7, 91, 49, 75, 1839, 415, 795, 9127, 0 }; + static ulong[] dim1337JoeKuoD6Init = { 1, 1, 1, 11, 13, 11, 123, 31, 261, 159, 681, 231, 117, 14923, 0 }; + static ulong[] dim1338JoeKuoD6Init = { 1, 1, 7, 1, 21, 35, 93, 17, 251, 229, 553, 3413, 7717, 891, 0 }; + static ulong[] dim1339JoeKuoD6Init = { 1, 3, 5, 3, 7, 47, 85, 155, 63, 785, 939, 3135, 3319, 1997, 0 }; + static ulong[] dim1340JoeKuoD6Init = { 1, 3, 7, 1, 21, 19, 7, 69, 505, 327, 1015, 1821, 2583, 15031, 0 }; + static ulong[] dim1341JoeKuoD6Init = { 1, 3, 5, 15, 3, 55, 87, 111, 499, 845, 375, 2735, 6895, 291, 0 }; + static ulong[] dim1342JoeKuoD6Init = { 1, 1, 3, 3, 15, 5, 51, 105, 369, 91, 945, 3633, 7847, 13811, 0 }; + static ulong[] dim1343JoeKuoD6Init = { 1, 1, 1, 5, 21, 57, 79, 213, 225, 71, 881, 391, 4329, 2481, 0 }; + static ulong[] dim1344JoeKuoD6Init = { 1, 1, 7, 11, 19, 49, 39, 193, 271, 463, 1009, 137, 3751, 8439, 0 }; + static ulong[] dim1345JoeKuoD6Init = { 1, 3, 1, 3, 17, 37, 51, 211, 103, 929, 1323, 1175, 5465, 12229, 0 }; + static ulong[] dim1346JoeKuoD6Init = { 1, 1, 3, 9, 21, 9, 123, 221, 201, 769, 723, 2627, 2367, 13169, 0 }; + static ulong[] dim1347JoeKuoD6Init = { 1, 1, 1, 11, 31, 23, 93, 103, 257, 263, 1771, 801, 4735, 13557, 0 }; + static ulong[] dim1348JoeKuoD6Init = { 1, 3, 1, 9, 21, 29, 67, 225, 367, 909, 1333, 655, 7691, 1251, 0 }; + static ulong[] dim1349JoeKuoD6Init = { 1, 1, 3, 7, 19, 11, 75, 175, 383, 121, 1917, 2371, 4191, 16111, 0 }; + static ulong[] dim1350JoeKuoD6Init = { 1, 1, 3, 13, 17, 5, 103, 53, 173, 981, 1185, 3071, 179, 9197, 0 }; + static ulong[] dim1351JoeKuoD6Init = { 1, 1, 3, 9, 5, 41, 25, 219, 211, 291, 1735, 397, 6317, 11209, 0 }; + static ulong[] dim1352JoeKuoD6Init = { 1, 3, 7, 5, 5, 1, 11, 125, 405, 583, 773, 1711, 757, 5187, 0 }; + static ulong[] dim1353JoeKuoD6Init = { 1, 1, 1, 7, 1, 45, 127, 11, 157, 255, 1167, 3315, 5059, 8219, 0 }; + static ulong[] dim1354JoeKuoD6Init = { 1, 1, 1, 5, 15, 55, 49, 81, 451, 887, 309, 2321, 5759, 4673, 0 }; + static ulong[] dim1355JoeKuoD6Init = { 1, 1, 3, 3, 29, 51, 15, 113, 245, 77, 109, 2813, 225, 5479, 0 }; + static ulong[] dim1356JoeKuoD6Init = { 1, 1, 3, 13, 13, 43, 5, 99, 89, 559, 903, 1003, 5401, 1839, 0 }; + static ulong[] dim1357JoeKuoD6Init = { 1, 1, 1, 5, 25, 11, 3, 225, 341, 439, 521, 545, 5529, 5365, 0 }; + static ulong[] dim1358JoeKuoD6Init = { 1, 1, 7, 7, 13, 41, 41, 183, 319, 593, 1961, 2211, 7155, 1683, 0 }; + static ulong[] dim1359JoeKuoD6Init = { 1, 1, 3, 1, 9, 27, 115, 119, 289, 935, 1173, 1783, 7151, 7157, 0 }; + static ulong[] dim1360JoeKuoD6Init = { 1, 3, 3, 7, 17, 33, 31, 109, 245, 785, 1563, 999, 7989, 3493, 0 }; + static ulong[] dim1361JoeKuoD6Init = { 1, 1, 7, 7, 9, 3, 85, 91, 21, 831, 1669, 1857, 1737, 12513, 0 }; + static ulong[] dim1362JoeKuoD6Init = { 1, 3, 3, 5, 17, 51, 37, 175, 325, 581, 1809, 2669, 6179, 2187, 0 }; + static ulong[] dim1363JoeKuoD6Init = { 1, 3, 5, 9, 9, 39, 53, 87, 47, 677, 1081, 171, 4885, 2311, 0 }; + static ulong[] dim1364JoeKuoD6Init = { 1, 1, 5, 9, 29, 3, 79, 13, 433, 891, 131, 3559, 797, 3405, 0 }; + static ulong[] dim1365JoeKuoD6Init = { 1, 3, 7, 11, 25, 5, 73, 189, 251, 927, 2001, 3179, 859, 15931, 0 }; + static ulong[] dim1366JoeKuoD6Init = { 1, 1, 1, 7, 15, 61, 67, 149, 99, 795, 53, 2417, 4943, 7367, 0 }; + static ulong[] dim1367JoeKuoD6Init = { 1, 3, 1, 3, 25, 61, 79, 145, 283, 161, 887, 137, 6027, 12585, 0 }; + static ulong[] dim1368JoeKuoD6Init = { 1, 3, 3, 3, 31, 5, 117, 33, 21, 883, 117, 1609, 7219, 2511, 0 }; + static ulong[] dim1369JoeKuoD6Init = { 1, 3, 3, 13, 1, 59, 29, 177, 419, 287, 973, 3649, 3333, 9779, 0 }; + static ulong[] dim1370JoeKuoD6Init = { 1, 3, 5, 5, 11, 51, 11, 125, 237, 305, 37, 3137, 7645, 6317, 0 }; + static ulong[] dim1371JoeKuoD6Init = { 1, 1, 3, 3, 29, 39, 127, 43, 113, 437, 1501, 13, 1915, 7561, 0 }; + static ulong[] dim1372JoeKuoD6Init = { 1, 3, 5, 13, 9, 55, 7, 209, 381, 725, 1867, 637, 6335, 6057, 0 }; + static ulong[] dim1373JoeKuoD6Init = { 1, 3, 3, 5, 1, 57, 57, 45, 247, 23, 1663, 489, 2503, 9033, 0 }; + static ulong[] dim1374JoeKuoD6Init = { 1, 3, 1, 3, 23, 7, 57, 157, 291, 523, 313, 2501, 1197, 3353, 0 }; + static ulong[] dim1375JoeKuoD6Init = { 1, 3, 5, 11, 31, 13, 35, 253, 349, 393, 1531, 159, 5311, 9225, 0 }; + static ulong[] dim1376JoeKuoD6Init = { 1, 1, 7, 1, 1, 47, 75, 187, 41, 713, 1933, 2139, 2211, 7425, 0 }; + static ulong[] dim1377JoeKuoD6Init = { 1, 1, 3, 5, 7, 21, 67, 27, 303, 617, 1943, 3173, 3081, 10977, 0 }; + static ulong[] dim1378JoeKuoD6Init = { 1, 1, 7, 7, 27, 57, 103, 65, 195, 267, 1347, 3831, 5335, 435, 0 }; + static ulong[] dim1379JoeKuoD6Init = { 1, 1, 7, 13, 11, 35, 83, 21, 273, 227, 1523, 3565, 7221, 3105, 0 }; + static ulong[] dim1380JoeKuoD6Init = { 1, 1, 5, 15, 7, 29, 123, 207, 63, 535, 1355, 2751, 4791, 10285, 0 }; + static ulong[] dim1381JoeKuoD6Init = { 1, 1, 3, 5, 3, 19, 79, 91, 481, 205, 1741, 319, 4651, 12631, 0 }; + static ulong[] dim1382JoeKuoD6Init = { 1, 3, 3, 7, 25, 61, 39, 181, 377, 243, 593, 1383, 1427, 11865, 0 }; + static ulong[] dim1383JoeKuoD6Init = { 1, 1, 3, 9, 13, 13, 97, 27, 335, 973, 1857, 425, 2729, 12013, 0 }; + static ulong[] dim1384JoeKuoD6Init = { 1, 1, 5, 7, 23, 57, 99, 37, 117, 337, 751, 2471, 1105, 1415, 0 }; + static ulong[] dim1385JoeKuoD6Init = { 1, 3, 5, 1, 17, 33, 117, 87, 211, 899, 825, 1043, 4273, 9093, 0 }; + static ulong[] dim1386JoeKuoD6Init = { 1, 1, 3, 13, 11, 7, 81, 251, 421, 643, 1931, 1205, 1033, 8741, 0 }; + static ulong[] dim1387JoeKuoD6Init = { 1, 3, 7, 5, 17, 27, 113, 43, 63, 819, 503, 1427, 5787, 1133, 0 }; + static ulong[] dim1388JoeKuoD6Init = { 1, 1, 1, 13, 7, 31, 85, 123, 17, 243, 749, 1447, 6045, 729, 0 }; + static ulong[] dim1389JoeKuoD6Init = { 1, 1, 1, 3, 19, 15, 97, 49, 101, 37, 1123, 1565, 6957, 1209, 0 }; + static ulong[] dim1390JoeKuoD6Init = { 1, 3, 1, 5, 1, 39, 23, 47, 387, 727, 81, 4023, 7635, 8691, 0 }; + static ulong[] dim1391JoeKuoD6Init = { 1, 3, 7, 11, 19, 27, 71, 37, 281, 981, 1777, 1751, 7387, 8391, 0 }; + static ulong[] dim1392JoeKuoD6Init = { 1, 3, 7, 11, 21, 55, 55, 35, 205, 277, 1573, 327, 7643, 4901, 0 }; + static ulong[] dim1393JoeKuoD6Init = { 1, 1, 5, 11, 15, 45, 91, 157, 339, 489, 1871, 2841, 6839, 4067, 0 }; + static ulong[] dim1394JoeKuoD6Init = { 1, 1, 7, 3, 11, 13, 57, 193, 499, 729, 603, 2235, 6323, 16307, 0 }; + static ulong[] dim1395JoeKuoD6Init = { 1, 1, 5, 9, 13, 41, 127, 117, 115, 159, 1335, 1473, 6509, 8165, 0 }; + static ulong[] dim1396JoeKuoD6Init = { 1, 3, 7, 15, 29, 39, 57, 161, 71, 97, 1201, 649, 5863, 4765, 0 }; + static ulong[] dim1397JoeKuoD6Init = { 1, 3, 1, 1, 21, 3, 3, 129, 421, 575, 1693, 337, 7313, 4801, 0 }; + static ulong[] dim1398JoeKuoD6Init = { 1, 3, 3, 15, 27, 51, 105, 91, 51, 683, 795, 603, 7759, 251, 0 }; + static ulong[] dim1399JoeKuoD6Init = { 1, 1, 5, 7, 9, 45, 55, 199, 83, 575, 521, 2169, 5741, 1579, 0 }; + static ulong[] dim1400JoeKuoD6Init = { 1, 3, 1, 7, 13, 47, 125, 227, 45, 355, 127, 1841, 727, 8555, 0 }; + static ulong[] dim1401JoeKuoD6Init = { 1, 3, 7, 11, 27, 9, 57, 133, 393, 315, 1411, 453, 3787, 7651, 0 }; + static ulong[] dim1402JoeKuoD6Init = { 1, 1, 1, 15, 11, 35, 77, 15, 223, 1009, 291, 2645, 4585, 5839, 0 }; + static ulong[] dim1403JoeKuoD6Init = { 1, 3, 1, 7, 7, 61, 89, 55, 399, 651, 1847, 1901, 1887, 5841, 0 }; + static ulong[] dim1404JoeKuoD6Init = { 1, 3, 3, 3, 17, 29, 41, 19, 353, 475, 1193, 949, 3351, 5073, 0 }; + static ulong[] dim1405JoeKuoD6Init = { 1, 1, 1, 5, 29, 45, 37, 39, 343, 661, 1405, 229, 493, 471, 0 }; + static ulong[] dim1406JoeKuoD6Init = { 1, 3, 5, 5, 25, 27, 37, 33, 33, 139, 1537, 1125, 4331, 253, 0 }; + static ulong[] dim1407JoeKuoD6Init = { 1, 3, 3, 7, 19, 31, 111, 243, 201, 563, 1913, 2153, 749, 3521, 0 }; + static ulong[] dim1408JoeKuoD6Init = { 1, 3, 5, 1, 9, 41, 19, 163, 185, 435, 1997, 3383, 1721, 11137, 0 }; + static ulong[] dim1409JoeKuoD6Init = { 1, 3, 3, 15, 25, 1, 67, 231, 11, 197, 1431, 1697, 3337, 8791, 0 }; + static ulong[] dim1410JoeKuoD6Init = { 1, 1, 1, 1, 13, 59, 11, 199, 243, 105, 751, 811, 345, 8183, 0 }; + static ulong[] dim1411JoeKuoD6Init = { 1, 1, 3, 1, 29, 35, 123, 187, 411, 523, 989, 2545, 4969, 14489, 0 }; + static ulong[] dim1412JoeKuoD6Init = { 1, 3, 7, 5, 29, 23, 51, 83, 335, 769, 171, 1631, 1651, 10549, 0 }; + static ulong[] dim1413JoeKuoD6Init = { 1, 1, 3, 9, 13, 29, 57, 167, 113, 703, 1027, 163, 1327, 5649, 0 }; + static ulong[] dim1414JoeKuoD6Init = { 1, 3, 5, 11, 1, 47, 101, 251, 377, 421, 1825, 3153, 3425, 10447, 0 }; + static ulong[] dim1415JoeKuoD6Init = { 1, 3, 1, 1, 11, 49, 17, 215, 261, 899, 811, 3451, 3955, 791, 0 }; + static ulong[] dim1416JoeKuoD6Init = { 1, 1, 1, 11, 19, 23, 41, 239, 203, 321, 993, 1201, 5073, 8329, 0 }; + static ulong[] dim1417JoeKuoD6Init = { 1, 3, 3, 7, 23, 55, 81, 227, 379, 571, 1869, 2159, 8181, 12901, 0 }; + static ulong[] dim1418JoeKuoD6Init = { 1, 1, 7, 3, 31, 55, 13, 57, 413, 927, 873, 3649, 7167, 3985, 0 }; + static ulong[] dim1419JoeKuoD6Init = { 1, 1, 7, 1, 9, 49, 7, 41, 461, 959, 1477, 4037, 1119, 3525, 0 }; + static ulong[] dim1420JoeKuoD6Init = { 1, 3, 5, 9, 9, 31, 67, 245, 57, 395, 1035, 3005, 4211, 7155, 0 }; + static ulong[] dim1421JoeKuoD6Init = { 1, 1, 7, 9, 5, 59, 55, 7, 97, 707, 1755, 1921, 6239, 233, 0 }; + static ulong[] dim1422JoeKuoD6Init = { 1, 1, 7, 5, 11, 11, 47, 195, 197, 37, 501, 2013, 6579, 15115, 0 }; + static ulong[] dim1423JoeKuoD6Init = { 1, 1, 3, 15, 23, 61, 27, 199, 41, 479, 871, 2365, 1589, 13, 0 }; + static ulong[] dim1424JoeKuoD6Init = { 1, 1, 3, 3, 11, 9, 1, 225, 295, 403, 1065, 3039, 6025, 963, 0 }; + static ulong[] dim1425JoeKuoD6Init = { 1, 3, 7, 13, 9, 61, 29, 253, 371, 527, 1697, 571, 2865, 15967, 0 }; + static ulong[] dim1426JoeKuoD6Init = { 1, 1, 3, 1, 13, 33, 55, 67, 441, 451, 379, 1365, 2111, 6169, 0 }; + static ulong[] dim1427JoeKuoD6Init = { 1, 1, 7, 1, 23, 39, 127, 43, 205, 391, 1463, 2227, 6877, 11483, 0 }; + static ulong[] dim1428JoeKuoD6Init = { 1, 3, 3, 9, 31, 41, 5, 65, 245, 405, 633, 1379, 4111, 13129, 0 }; + static ulong[] dim1429JoeKuoD6Init = { 1, 3, 5, 1, 1, 3, 57, 179, 23, 615, 761, 2339, 8191, 1995, 0 }; + static ulong[] dim1430JoeKuoD6Init = { 1, 3, 3, 5, 11, 53, 67, 119, 169, 313, 873, 531, 63, 10827, 0 }; + static ulong[] dim1431JoeKuoD6Init = { 1, 1, 5, 7, 31, 3, 53, 139, 33, 639, 855, 43, 7895, 495, 0 }; + static ulong[] dim1432JoeKuoD6Init = { 1, 3, 3, 15, 15, 15, 13, 237, 427, 257, 1973, 2287, 7597, 13397, 0 }; + static ulong[] dim1433JoeKuoD6Init = { 1, 1, 3, 11, 31, 5, 29, 97, 99, 1003, 333, 773, 4457, 8629, 0 }; + static ulong[] dim1434JoeKuoD6Init = { 1, 1, 5, 9, 11, 55, 59, 201, 25, 559, 1647, 485, 7041, 4965, 0 }; + static ulong[] dim1435JoeKuoD6Init = { 1, 1, 3, 5, 7, 37, 117, 159, 319, 431, 341, 2497, 755, 5363, 0 }; + static ulong[] dim1436JoeKuoD6Init = { 1, 3, 5, 15, 25, 29, 99, 61, 5, 643, 1605, 2273, 3189, 5505, 0 }; + static ulong[] dim1437JoeKuoD6Init = { 1, 1, 1, 1, 29, 47, 79, 177, 473, 361, 1337, 1199, 2395, 1079, 0 }; + static ulong[] dim1438JoeKuoD6Init = { 1, 3, 5, 3, 7, 31, 101, 189, 223, 719, 1815, 1383, 7233, 11693, 0 }; + static ulong[] dim1439JoeKuoD6Init = { 1, 1, 1, 5, 29, 39, 109, 211, 485, 659, 683, 3331, 4277, 809, 0 }; + static ulong[] dim1440JoeKuoD6Init = { 1, 1, 3, 7, 23, 49, 37, 163, 127, 389, 367, 2223, 1175, 12717, 0 }; + static ulong[] dim1441JoeKuoD6Init = { 1, 3, 3, 7, 27, 27, 51, 57, 115, 941, 243, 2741, 245, 341, 0 }; + static ulong[] dim1442JoeKuoD6Init = { 1, 1, 5, 5, 15, 33, 113, 3, 267, 343, 563, 1769, 4095, 11557, 0 }; + static ulong[] dim1443JoeKuoD6Init = { 1, 3, 3, 13, 13, 11, 105, 161, 145, 125, 1509, 1459, 843, 4553, 0 }; + static ulong[] dim1444JoeKuoD6Init = { 1, 1, 1, 3, 11, 7, 67, 205, 335, 595, 1553, 2319, 6565, 14473, 0 }; + static ulong[] dim1445JoeKuoD6Init = { 1, 3, 5, 15, 23, 13, 119, 117, 263, 463, 1919, 2089, 2809, 9957, 0 }; + static ulong[] dim1446JoeKuoD6Init = { 1, 3, 7, 1, 27, 41, 5, 155, 31, 261, 1383, 1271, 2557, 6041, 0 }; + static ulong[] dim1447JoeKuoD6Init = { 1, 3, 3, 13, 13, 43, 89, 45, 443, 13, 465, 703, 3405, 6471, 0 }; + static ulong[] dim1448JoeKuoD6Init = { 1, 3, 1, 7, 31, 49, 49, 57, 97, 987, 187, 141, 7537, 11021, 0 }; + static ulong[] dim1449JoeKuoD6Init = { 1, 1, 5, 15, 29, 43, 103, 89, 113, 729, 1523, 2893, 1143, 9049, 0 }; + static ulong[] dim1450JoeKuoD6Init = { 1, 1, 3, 3, 29, 49, 43, 255, 371, 903, 661, 3355, 5981, 861, 0 }; + static ulong[] dim1451JoeKuoD6Init = { 1, 3, 7, 11, 29, 13, 75, 5, 239, 983, 733, 2949, 4635, 6789, 0 }; + static ulong[] dim1452JoeKuoD6Init = { 1, 1, 5, 3, 17, 51, 17, 49, 349, 73, 111, 897, 2757, 9817, 0 }; + static ulong[] dim1453JoeKuoD6Init = { 1, 1, 1, 9, 17, 31, 73, 125, 207, 951, 681, 3685, 893, 13725, 0 }; + static ulong[] dim1454JoeKuoD6Init = { 1, 1, 3, 1, 29, 13, 51, 181, 27, 807, 59, 3781, 263, 13865, 0 }; + static ulong[] dim1455JoeKuoD6Init = { 1, 1, 7, 5, 15, 29, 55, 159, 341, 365, 1101, 3139, 4795, 4305, 0 }; + static ulong[] dim1456JoeKuoD6Init = { 1, 3, 7, 15, 19, 35, 99, 251, 241, 115, 1197, 1167, 4663, 5523, 0 }; + static ulong[] dim1457JoeKuoD6Init = { 1, 1, 7, 5, 13, 43, 59, 251, 455, 601, 891, 2279, 3447, 7787, 0 }; + static ulong[] dim1458JoeKuoD6Init = { 1, 3, 3, 9, 31, 17, 97, 27, 373, 183, 7, 1729, 4513, 9763, 0 }; + static ulong[] dim1459JoeKuoD6Init = { 1, 1, 3, 15, 29, 15, 57, 75, 211, 551, 141, 811, 27, 15107, 0 }; + static ulong[] dim1460JoeKuoD6Init = { 1, 3, 1, 15, 31, 9, 57, 73, 431, 375, 1269, 2589, 1567, 9293, 0 }; + static ulong[] dim1461JoeKuoD6Init = { 1, 1, 3, 13, 21, 13, 41, 211, 301, 177, 1667, 3957, 6261, 3275, 0 }; + static ulong[] dim1462JoeKuoD6Init = { 1, 1, 5, 5, 15, 3, 33, 101, 119, 345, 1853, 2807, 337, 10163, 0 }; + static ulong[] dim1463JoeKuoD6Init = { 1, 3, 3, 5, 27, 61, 11, 161, 25, 159, 1775, 3039, 3807, 9373, 0 }; + static ulong[] dim1464JoeKuoD6Init = { 1, 1, 1, 15, 19, 35, 15, 191, 87, 735, 1079, 2373, 7087, 7505, 0 }; + static ulong[] dim1465JoeKuoD6Init = { 1, 1, 5, 15, 29, 37, 43, 25, 161, 925, 259, 3281, 2643, 2359, 0 }; + static ulong[] dim1466JoeKuoD6Init = { 1, 3, 1, 11, 3, 21, 13, 169, 17, 637, 1711, 1877, 6081, 5115, 0 }; + static ulong[] dim1467JoeKuoD6Init = { 1, 3, 5, 1, 25, 5, 125, 103, 277, 533, 1485, 3263, 4899, 11851, 0 }; + static ulong[] dim1468JoeKuoD6Init = { 1, 3, 7, 9, 23, 13, 61, 59, 405, 73, 817, 3831, 5059, 7671, 0 }; + static ulong[] dim1469JoeKuoD6Init = { 1, 1, 7, 3, 1, 53, 113, 135, 481, 861, 1041, 931, 2973, 7957, 0 }; + static ulong[] dim1470JoeKuoD6Init = { 1, 1, 7, 11, 9, 9, 123, 175, 65, 447, 1709, 4083, 6089, 7869, 0 }; + static ulong[] dim1471JoeKuoD6Init = { 1, 3, 7, 7, 5, 11, 43, 59, 439, 539, 283, 3221, 2631, 13025, 0 }; + static ulong[] dim1472JoeKuoD6Init = { 1, 3, 7, 7, 27, 1, 93, 51, 361, 441, 2005, 127, 6763, 12699, 0 }; + static ulong[] dim1473JoeKuoD6Init = { 1, 3, 5, 15, 27, 29, 49, 49, 115, 167, 445, 2811, 1809, 11141, 0 }; + static ulong[] dim1474JoeKuoD6Init = { 1, 1, 7, 5, 1, 57, 69, 49, 197, 459, 1613, 2891, 4437, 1621, 0 }; + static ulong[] dim1475JoeKuoD6Init = { 1, 1, 1, 5, 25, 51, 33, 47, 115, 349, 1373, 1985, 5339, 4331, 0 }; + static ulong[] dim1476JoeKuoD6Init = { 1, 3, 7, 11, 21, 55, 113, 183, 91, 955, 835, 2277, 5989, 1383, 0 }; + static ulong[] dim1477JoeKuoD6Init = { 1, 3, 5, 1, 1, 11, 113, 121, 207, 897, 125, 393, 6281, 15003, 0 }; + static ulong[] dim1478JoeKuoD6Init = { 1, 3, 7, 15, 13, 37, 89, 169, 437, 787, 1253, 2835, 4923, 15271, 0 }; + static ulong[] dim1479JoeKuoD6Init = { 1, 3, 5, 9, 23, 37, 65, 135, 271, 381, 551, 3819, 5683, 3689, 0 }; + static ulong[] dim1480JoeKuoD6Init = { 1, 1, 1, 9, 27, 29, 61, 147, 347, 745, 1793, 611, 7415, 4927, 0 }; + static ulong[] dim1481JoeKuoD6Init = { 1, 1, 3, 5, 23, 59, 35, 5, 179, 247, 1265, 2503, 1705, 10011, 0 }; + static ulong[] dim1482JoeKuoD6Init = { 1, 3, 5, 7, 11, 19, 57, 175, 93, 777, 353, 371, 6655, 10271, 0 }; + static ulong[] dim1483JoeKuoD6Init = { 1, 3, 7, 13, 15, 51, 29, 213, 113, 143, 2011, 2223, 2099, 4103, 0 }; + static ulong[] dim1484JoeKuoD6Init = { 1, 1, 7, 13, 19, 31, 75, 99, 89, 219, 2019, 1739, 3813, 5619, 0 }; + static ulong[] dim1485JoeKuoD6Init = { 1, 1, 3, 7, 27, 53, 69, 215, 299, 401, 719, 3123, 3463, 13967, 0 }; + static ulong[] dim1486JoeKuoD6Init = { 1, 3, 5, 3, 29, 63, 5, 247, 21, 651, 879, 3033, 117, 11511, 0 }; + static ulong[] dim1487JoeKuoD6Init = { 1, 1, 5, 1, 5, 47, 63, 45, 145, 905, 885, 2367, 6721, 3869, 0 }; + static ulong[] dim1488JoeKuoD6Init = { 1, 1, 3, 3, 25, 13, 117, 17, 367, 425, 367, 2863, 3087, 9115, 0 }; + static ulong[] dim1489JoeKuoD6Init = { 1, 3, 5, 1, 1, 31, 13, 65, 255, 873, 831, 3439, 7459, 7713, 0 }; + static ulong[] dim1490JoeKuoD6Init = { 1, 1, 7, 11, 19, 53, 93, 33, 505, 1007, 1331, 2317, 2817, 2549, 0 }; + static ulong[] dim1491JoeKuoD6Init = { 1, 1, 1, 11, 9, 1, 67, 109, 397, 831, 1371, 3277, 151, 6523, 0 }; + static ulong[] dim1492JoeKuoD6Init = { 1, 3, 1, 3, 25, 11, 35, 233, 231, 89, 1029, 1053, 6579, 455, 0 }; + static ulong[] dim1493JoeKuoD6Init = { 1, 1, 5, 13, 11, 7, 117, 203, 125, 863, 1927, 2081, 1229, 6373, 0 }; + static ulong[] dim1494JoeKuoD6Init = { 1, 1, 1, 7, 23, 53, 27, 207, 189, 287, 635, 3483, 4551, 15085, 0 }; + static ulong[] dim1495JoeKuoD6Init = { 1, 1, 3, 3, 23, 45, 99, 177, 59, 835, 1123, 3397, 4237, 11895, 0 }; + static ulong[] dim1496JoeKuoD6Init = { 1, 1, 7, 3, 31, 59, 37, 7, 387, 849, 1857, 3469, 3663, 1465, 0 }; + static ulong[] dim1497JoeKuoD6Init = { 1, 1, 5, 9, 13, 7, 73, 211, 83, 831, 1069, 3103, 2355, 8817, 0 }; + static ulong[] dim1498JoeKuoD6Init = { 1, 3, 7, 1, 1, 7, 63, 195, 69, 945, 39, 1417, 879, 9223, 0 }; + static ulong[] dim1499JoeKuoD6Init = { 1, 1, 7, 9, 3, 53, 111, 41, 29, 597, 1667, 3903, 7401, 6939, 0 }; + static ulong[] dim1500JoeKuoD6Init = { 1, 3, 5, 7, 9, 35, 55, 61, 509, 729, 25, 2357, 3607, 2215, 0 }; + static ulong[] dim1501JoeKuoD6Init = { 1, 3, 7, 7, 19, 49, 47, 241, 79, 363, 1987, 3269, 5161, 1379, 0 }; + static ulong[] dim1502JoeKuoD6Init = { 1, 3, 5, 5, 1, 33, 21, 249, 321, 281, 2025, 425, 4955, 5799, 0 }; + static ulong[] dim1503JoeKuoD6Init = { 1, 1, 7, 5, 19, 21, 93, 69, 487, 619, 839, 1359, 3219, 8303, 0 }; + static ulong[] dim1504JoeKuoD6Init = { 1, 3, 5, 15, 27, 33, 3, 55, 149, 361, 887, 1341, 1219, 4769, 0 }; + static ulong[] dim1505JoeKuoD6Init = { 1, 1, 1, 15, 5, 13, 65, 53, 181, 923, 1643, 3853, 3067, 4281, 0 }; + static ulong[] dim1506JoeKuoD6Init = { 1, 1, 1, 1, 13, 5, 23, 27, 211, 377, 1421, 3085, 509, 509, 0 }; + static ulong[] dim1507JoeKuoD6Init = { 1, 1, 7, 9, 21, 13, 3, 193, 19, 497, 1989, 885, 1157, 7213, 0 }; + static ulong[] dim1508JoeKuoD6Init = { 1, 3, 7, 11, 1, 5, 105, 57, 245, 25, 153, 795, 3781, 11735, 0 }; + static ulong[] dim1509JoeKuoD6Init = { 1, 1, 1, 13, 5, 7, 87, 63, 81, 491, 971, 805, 2349, 15627, 0 }; + static ulong[] dim1510JoeKuoD6Init = { 1, 1, 5, 1, 27, 41, 31, 165, 383, 85, 1713, 2427, 5329, 15169, 0 }; + static ulong[] dim1511JoeKuoD6Init = { 1, 1, 5, 7, 9, 47, 75, 51, 329, 651, 481, 2469, 1761, 1367, 0 }; + static ulong[] dim1512JoeKuoD6Init = { 1, 1, 1, 11, 13, 51, 89, 163, 431, 117, 1909, 2685, 7197, 1537, 0 }; + static ulong[] dim1513JoeKuoD6Init = { 1, 1, 1, 15, 29, 47, 19, 231, 35, 597, 997, 105, 7701, 899, 0 }; + static ulong[] dim1514JoeKuoD6Init = { 1, 3, 7, 15, 5, 19, 63, 87, 49, 685, 525, 3709, 4461, 15697, 0 }; + static ulong[] dim1515JoeKuoD6Init = { 1, 3, 1, 13, 31, 63, 65, 91, 169, 857, 1143, 2831, 7307, 11755, 0 }; + static ulong[] dim1516JoeKuoD6Init = { 1, 3, 1, 13, 27, 61, 105, 191, 325, 71, 1155, 2291, 8023, 1281, 0 }; + static ulong[] dim1517JoeKuoD6Init = { 1, 1, 3, 11, 21, 45, 45, 19, 453, 527, 75, 3489, 3011, 12687, 0 }; + static ulong[] dim1518JoeKuoD6Init = { 1, 1, 5, 7, 23, 15, 27, 105, 335, 549, 737, 3671, 5071, 10957, 0 }; + static ulong[] dim1519JoeKuoD6Init = { 1, 1, 7, 9, 9, 13, 121, 169, 87, 871, 917, 3071, 7817, 14493, 0 }; + static ulong[] dim1520JoeKuoD6Init = { 1, 1, 3, 9, 3, 1, 63, 195, 67, 123, 175, 3779, 2681, 15967, 0 }; + static ulong[] dim1521JoeKuoD6Init = { 1, 3, 7, 9, 11, 31, 111, 147, 203, 205, 1591, 3003, 631, 15567, 0 }; + static ulong[] dim1522JoeKuoD6Init = { 1, 1, 3, 5, 23, 11, 43, 117, 37, 413, 1657, 4061, 5491, 10329, 0 }; + static ulong[] dim1523JoeKuoD6Init = { 1, 1, 1, 11, 31, 35, 107, 105, 107, 117, 2041, 1415, 2153, 9063, 0 }; + static ulong[] dim1524JoeKuoD6Init = { 1, 3, 5, 13, 9, 35, 77, 1, 343, 341, 1841, 2963, 1105, 4103, 0 }; + static ulong[] dim1525JoeKuoD6Init = { 1, 1, 7, 3, 25, 21, 45, 63, 429, 843, 585, 741, 6641, 6327, 0 }; + static ulong[] dim1526JoeKuoD6Init = { 1, 1, 1, 5, 19, 23, 3, 63, 273, 1009, 131, 3541, 3769, 13045, 0 }; + static ulong[] dim1527JoeKuoD6Init = { 1, 3, 5, 15, 11, 41, 127, 139, 105, 15, 1311, 2995, 3151, 12913, 0 }; + static ulong[] dim1528JoeKuoD6Init = { 1, 3, 1, 3, 1, 37, 71, 55, 17, 155, 397, 121, 2917, 3943, 0 }; + static ulong[] dim1529JoeKuoD6Init = { 1, 3, 7, 11, 5, 1, 23, 29, 233, 947, 893, 269, 6487, 13831, 0 }; + static ulong[] dim1530JoeKuoD6Init = { 1, 3, 1, 5, 7, 17, 63, 177, 153, 595, 1217, 2225, 5973, 15853, 0 }; + static ulong[] dim1531JoeKuoD6Init = { 1, 3, 7, 9, 19, 9, 45, 197, 285, 85, 1533, 673, 5969, 501, 0 }; + static ulong[] dim1532JoeKuoD6Init = { 1, 3, 5, 15, 15, 23, 123, 151, 49, 583, 385, 3671, 3617, 16285, 0 }; + static ulong[] dim1533JoeKuoD6Init = { 1, 3, 7, 13, 11, 55, 111, 57, 51, 249, 13, 1929, 4711, 9847, 0 }; + static ulong[] dim1534JoeKuoD6Init = { 1, 1, 1, 3, 17, 13, 101, 117, 433, 327, 151, 2137, 4885, 12775, 0 }; + static ulong[] dim1535JoeKuoD6Init = { 1, 3, 3, 11, 13, 39, 113, 35, 99, 985, 765, 1239, 1311, 4591, 0 }; + static ulong[] dim1536JoeKuoD6Init = { 1, 1, 1, 11, 11, 31, 41, 205, 339, 773, 1291, 1665, 4345, 4139, 0 }; + static ulong[] dim1537JoeKuoD6Init = { 1, 1, 1, 1, 27, 41, 27, 139, 109, 555, 691, 2263, 5321, 12865, 0 }; + static ulong[] dim1538JoeKuoD6Init = { 1, 1, 3, 11, 23, 13, 41, 73, 253, 481, 1345, 3339, 1121, 665, 0 }; + static ulong[] dim1539JoeKuoD6Init = { 1, 1, 7, 7, 23, 57, 109, 161, 35, 911, 411, 3117, 5997, 6843, 0 }; + static ulong[] dim1540JoeKuoD6Init = { 1, 3, 7, 13, 3, 39, 97, 85, 399, 733, 43, 2437, 2755, 10693, 0 }; + static ulong[] dim1541JoeKuoD6Init = { 1, 3, 5, 15, 15, 47, 121, 157, 379, 805, 1483, 4013, 79, 10943, 0 }; + static ulong[] dim1542JoeKuoD6Init = { 1, 1, 3, 3, 23, 51, 39, 61, 157, 139, 273, 2385, 2451, 12437, 0 }; + static ulong[] dim1543JoeKuoD6Init = { 1, 1, 5, 1, 21, 7, 77, 197, 469, 391, 1665, 1241, 1847, 14129, 0 }; + static ulong[] dim1544JoeKuoD6Init = { 1, 1, 5, 5, 27, 23, 83, 245, 319, 247, 1345, 1229, 1119, 5749, 0 }; + static ulong[] dim1545JoeKuoD6Init = { 1, 1, 5, 3, 31, 63, 121, 245, 371, 359, 1929, 817, 2603, 5135, 0 }; + static ulong[] dim1546JoeKuoD6Init = { 1, 3, 1, 15, 21, 17, 15, 11, 425, 115, 1773, 1491, 2295, 11883, 0 }; + static ulong[] dim1547JoeKuoD6Init = { 1, 1, 5, 1, 7, 21, 91, 203, 435, 119, 819, 707, 3567, 517, 0 }; + static ulong[] dim1548JoeKuoD6Init = { 1, 1, 5, 3, 7, 7, 101, 41, 475, 539, 1059, 2245, 6731, 6635, 0 }; + static ulong[] dim1549JoeKuoD6Init = { 1, 3, 5, 1, 11, 25, 91, 89, 193, 463, 1667, 661, 801, 7087, 0 }; + static ulong[] dim1550JoeKuoD6Init = { 1, 3, 7, 15, 1, 43, 17, 97, 129, 843, 1319, 723, 2725, 10743, 0 }; + static ulong[] dim1551JoeKuoD6Init = { 1, 1, 3, 11, 19, 27, 119, 113, 85, 385, 1841, 2821, 2867, 6199, 0 }; + static ulong[] dim1552JoeKuoD6Init = { 1, 1, 7, 1, 23, 27, 95, 175, 99, 839, 1039, 735, 6355, 1651, 0 }; + static ulong[] dim1553JoeKuoD6Init = { 1, 3, 3, 1, 11, 13, 71, 91, 7, 959, 979, 2571, 117, 11479, 0 }; + static ulong[] dim1554JoeKuoD6Init = { 1, 1, 7, 11, 21, 45, 113, 205, 107, 881, 2039, 3181, 4125, 13801, 0 }; + static ulong[] dim1555JoeKuoD6Init = { 1, 1, 1, 13, 3, 63, 123, 53, 427, 469, 685, 3685, 1019, 7069, 0 }; + static ulong[] dim1556JoeKuoD6Init = { 1, 1, 1, 13, 31, 33, 39, 155, 19, 975, 659, 11, 6873, 10105, 0 }; + static ulong[] dim1557JoeKuoD6Init = { 1, 3, 5, 3, 31, 33, 91, 3, 207, 63, 559, 3745, 637, 6869, 0 }; + static ulong[] dim1558JoeKuoD6Init = { 1, 3, 1, 11, 1, 11, 41, 51, 439, 273, 1977, 2987, 5265, 11779, 0 }; + static ulong[] dim1559JoeKuoD6Init = { 1, 1, 5, 7, 13, 63, 111, 125, 65, 1003, 2045, 1823, 6799, 2847, 0 }; + static ulong[] dim1560JoeKuoD6Init = { 1, 1, 1, 1, 11, 9, 59, 187, 431, 773, 1817, 2891, 2927, 1145, 0 }; + static ulong[] dim1561JoeKuoD6Init = { 1, 1, 1, 15, 25, 19, 101, 231, 371, 857, 261, 1901, 2165, 7275, 0 }; + static ulong[] dim1562JoeKuoD6Init = { 1, 3, 1, 15, 31, 57, 125, 77, 447, 417, 1503, 3003, 7229, 14275, 0 }; + static ulong[] dim1563JoeKuoD6Init = { 1, 1, 1, 11, 23, 63, 17, 251, 237, 755, 641, 1875, 1537, 2465, 0 }; + static ulong[] dim1564JoeKuoD6Init = { 1, 3, 7, 3, 25, 59, 45, 97, 173, 179, 421, 1269, 2933, 337, 0 }; + static ulong[] dim1565JoeKuoD6Init = { 1, 3, 5, 5, 15, 25, 81, 191, 475, 723, 107, 277, 681, 15147, 0 }; + static ulong[] dim1566JoeKuoD6Init = { 1, 1, 5, 15, 3, 17, 65, 39, 281, 831, 85, 1445, 4779, 5559, 0 }; + static ulong[] dim1567JoeKuoD6Init = { 1, 3, 1, 13, 21, 1, 7, 5, 141, 65, 745, 1389, 1935, 9317, 0 }; + static ulong[] dim1568JoeKuoD6Init = { 1, 1, 5, 11, 27, 31, 33, 27, 185, 625, 1723, 3499, 6225, 7993, 0 }; + static ulong[] dim1569JoeKuoD6Init = { 1, 1, 5, 7, 5, 51, 19, 27, 301, 845, 949, 1963, 7201, 5399, 0 }; + static ulong[] dim1570JoeKuoD6Init = { 1, 3, 3, 9, 1, 59, 113, 87, 237, 83, 815, 161, 1685, 1155, 0 }; + static ulong[] dim1571JoeKuoD6Init = { 1, 3, 3, 15, 3, 47, 105, 77, 343, 997, 647, 3051, 4877, 11519, 0 }; + static ulong[] dim1572JoeKuoD6Init = { 1, 1, 5, 7, 15, 13, 123, 253, 343, 701, 1231, 3997, 3203, 7411, 0 }; + static ulong[] dim1573JoeKuoD6Init = { 1, 3, 3, 7, 21, 53, 103, 49, 511, 535, 1159, 747, 4859, 2733, 0 }; + static ulong[] dim1574JoeKuoD6Init = { 1, 3, 3, 13, 19, 13, 113, 93, 61, 1007, 219, 3817, 4819, 9959, 0 }; + static ulong[] dim1575JoeKuoD6Init = { 1, 3, 1, 7, 1, 57, 45, 167, 209, 757, 1861, 1863, 3495, 4295, 0 }; + static ulong[] dim1576JoeKuoD6Init = { 1, 1, 3, 13, 25, 53, 63, 187, 27, 663, 1697, 2477, 1685, 6609, 0 }; + static ulong[] dim1577JoeKuoD6Init = { 1, 3, 7, 1, 19, 51, 91, 125, 275, 737, 61, 685, 5739, 12795, 0 }; + static ulong[] dim1578JoeKuoD6Init = { 1, 1, 7, 15, 1, 63, 21, 253, 247, 399, 1207, 3357, 1029, 4719, 0 }; + static ulong[] dim1579JoeKuoD6Init = { 1, 1, 5, 13, 21, 1, 45, 223, 511, 963, 1099, 2913, 7385, 13903, 0 }; + static ulong[] dim1580JoeKuoD6Init = { 1, 3, 7, 7, 1, 33, 123, 81, 431, 947, 1821, 3763, 1679, 2391, 0 }; + static ulong[] dim1581JoeKuoD6Init = { 1, 1, 5, 1, 9, 9, 9, 55, 425, 539, 221, 409, 4967, 8239, 0 }; + static ulong[] dim1582JoeKuoD6Init = { 1, 3, 7, 11, 19, 5, 97, 77, 95, 955, 705, 3627, 3743, 8687, 0 }; + static ulong[] dim1583JoeKuoD6Init = { 1, 3, 1, 11, 27, 51, 37, 177, 109, 343, 35, 1361, 1557, 13487, 0 }; + static ulong[] dim1584JoeKuoD6Init = { 1, 1, 1, 11, 19, 25, 93, 155, 421, 765, 1529, 2685, 2729, 4763, 0 }; + static ulong[] dim1585JoeKuoD6Init = { 1, 3, 3, 11, 7, 21, 99, 179, 205, 473, 1435, 711, 6975, 10497, 0 }; + static ulong[] dim1586JoeKuoD6Init = { 1, 1, 5, 3, 1, 55, 29, 113, 201, 123, 201, 2749, 75, 5839, 0 }; + static ulong[] dim1587JoeKuoD6Init = { 1, 3, 1, 9, 13, 9, 19, 55, 57, 99, 811, 3143, 5143, 5149, 0 }; + static ulong[] dim1588JoeKuoD6Init = { 1, 3, 5, 1, 5, 49, 89, 229, 351, 93, 951, 3587, 6819, 119, 0 }; + static ulong[] dim1589JoeKuoD6Init = { 1, 1, 5, 5, 17, 1, 95, 129, 79, 165, 209, 2859, 4269, 7613, 0 }; + static ulong[] dim1590JoeKuoD6Init = { 1, 3, 5, 11, 3, 1, 115, 215, 215, 449, 1365, 3429, 5711, 10053, 0 }; + static ulong[] dim1591JoeKuoD6Init = { 1, 1, 1, 9, 17, 59, 11, 121, 229, 37, 781, 421, 145, 1359, 0 }; + static ulong[] dim1592JoeKuoD6Init = { 1, 1, 3, 9, 31, 31, 73, 255, 451, 337, 617, 3169, 7275, 4783, 0 }; + static ulong[] dim1593JoeKuoD6Init = { 1, 1, 7, 15, 3, 31, 17, 163, 243, 695, 1073, 2625, 6237, 4011, 0 }; + static ulong[] dim1594JoeKuoD6Init = { 1, 1, 5, 5, 27, 17, 45, 167, 363, 741, 1873, 3699, 7577, 7389, 0 }; + static ulong[] dim1595JoeKuoD6Init = { 1, 1, 7, 9, 5, 61, 43, 99, 175, 645, 1351, 1405, 2443, 15481, 0 }; + static ulong[] dim1596JoeKuoD6Init = { 1, 3, 7, 11, 7, 19, 11, 27, 481, 271, 881, 143, 1087, 7443, 0 }; + static ulong[] dim1597JoeKuoD6Init = { 1, 1, 3, 15, 11, 59, 47, 165, 421, 211, 451, 3957, 1715, 5045, 0 }; + static ulong[] dim1598JoeKuoD6Init = { 1, 1, 1, 3, 1, 55, 121, 71, 483, 79, 61, 3107, 6367, 8787, 0 }; + static ulong[] dim1599JoeKuoD6Init = { 1, 1, 5, 11, 5, 35, 7, 197, 269, 437, 1529, 1757, 8165, 10897, 0 }; + static ulong[] dim1600JoeKuoD6Init = { 1, 1, 3, 13, 25, 41, 121, 115, 177, 435, 839, 2701, 2813, 5055, 0 }; + static ulong[] dim1601JoeKuoD6Init = { 1, 1, 3, 15, 5, 57, 17, 99, 31, 415, 1391, 3077, 4317, 12963, 0 }; + static ulong[] dim1602JoeKuoD6Init = { 1, 3, 1, 7, 31, 45, 95, 97, 43, 601, 2033, 2967, 3985, 10845, 0 }; + static ulong[] dim1603JoeKuoD6Init = { 1, 3, 1, 15, 19, 55, 99, 125, 391, 339, 1277, 2669, 359, 3983, 0 }; + static ulong[] dim1604JoeKuoD6Init = { 1, 3, 7, 11, 11, 47, 79, 197, 157, 959, 777, 133, 337, 14891, 0 }; + static ulong[] dim1605JoeKuoD6Init = { 1, 1, 5, 7, 9, 3, 95, 77, 217, 399, 1269, 2505, 1055, 5483, 0 }; + static ulong[] dim1606JoeKuoD6Init = { 1, 1, 5, 3, 27, 5, 3, 109, 481, 169, 1787, 725, 2827, 13599, 0 }; + static ulong[] dim1607JoeKuoD6Init = { 1, 3, 1, 5, 7, 11, 127, 119, 141, 999, 295, 2727, 7329, 11371, 0 }; + static ulong[] dim1608JoeKuoD6Init = { 1, 3, 3, 7, 31, 17, 105, 139, 287, 333, 1149, 3373, 5165, 9555, 0 }; + static ulong[] dim1609JoeKuoD6Init = { 1, 3, 5, 5, 5, 13, 53, 25, 125, 953, 511, 3695, 7935, 10901, 0 }; + static ulong[] dim1610JoeKuoD6Init = { 1, 1, 5, 15, 5, 37, 73, 29, 471, 423, 2025, 3759, 4271, 9589, 0 }; + static ulong[] dim1611JoeKuoD6Init = { 1, 1, 1, 5, 9, 35, 105, 207, 245, 935, 801, 2115, 7935, 11439, 0 }; + static ulong[] dim1612JoeKuoD6Init = { 1, 3, 7, 15, 23, 39, 67, 187, 333, 823, 1015, 1463, 6445, 5079, 0 }; + static ulong[] dim1613JoeKuoD6Init = { 1, 1, 7, 7, 15, 43, 41, 243, 493, 703, 3, 3585, 6775, 2169, 0 }; + static ulong[] dim1614JoeKuoD6Init = { 1, 3, 7, 9, 7, 53, 29, 225, 399, 885, 1051, 665, 1447, 5913, 0 }; + static ulong[] dim1615JoeKuoD6Init = { 1, 1, 1, 7, 3, 19, 47, 219, 203, 903, 1399, 1793, 5949, 4311, 0 }; + static ulong[] dim1616JoeKuoD6Init = { 1, 1, 1, 5, 9, 9, 117, 207, 107, 651, 1155, 2047, 7489, 5959, 0 }; + static ulong[] dim1617JoeKuoD6Init = { 1, 3, 7, 9, 31, 59, 105, 73, 251, 209, 515, 3467, 721, 13423, 0 }; + static ulong[] dim1618JoeKuoD6Init = { 1, 1, 7, 13, 13, 45, 75, 171, 61, 249, 1641, 289, 201, 6185, 0 }; + static ulong[] dim1619JoeKuoD6Init = { 1, 1, 1, 11, 13, 37, 91, 225, 241, 899, 1471, 3553, 6741, 11623, 0 }; + static ulong[] dim1620JoeKuoD6Init = { 1, 3, 7, 15, 19, 61, 79, 81, 75, 343, 145, 3975, 4807, 4887, 0 }; + static ulong[] dim1621JoeKuoD6Init = { 1, 1, 3, 9, 17, 15, 29, 1, 331, 649, 1455, 2365, 6309, 6701, 0 }; + static ulong[] dim1622JoeKuoD6Init = { 1, 1, 1, 1, 15, 19, 37, 5, 417, 933, 269, 2391, 8063, 14231, 0 }; + static ulong[] dim1623JoeKuoD6Init = { 1, 1, 7, 3, 17, 49, 21, 41, 127, 507, 1927, 1971, 7057, 12047, 0 }; + static ulong[] dim1624JoeKuoD6Init = { 1, 1, 7, 15, 31, 53, 33, 225, 105, 907, 775, 3699, 439, 10087, 0 }; + static ulong[] dim1625JoeKuoD6Init = { 1, 1, 5, 3, 23, 5, 3, 19, 387, 811, 865, 2817, 3757, 12849, 0 }; + static ulong[] dim1626JoeKuoD6Init = { 1, 3, 5, 3, 3, 23, 51, 239, 489, 667, 301, 3879, 4141, 1131, 0 }; + static ulong[] dim1627JoeKuoD6Init = { 1, 3, 3, 1, 21, 59, 115, 89, 235, 1009, 1371, 2141, 2489, 763, 0 }; + static ulong[] dim1628JoeKuoD6Init = { 1, 1, 7, 1, 5, 7, 75, 83, 491, 233, 1027, 1421, 5111, 445, 0 }; + static ulong[] dim1629JoeKuoD6Init = { 1, 3, 3, 3, 19, 27, 1, 181, 193, 949, 69, 2689, 3421, 13921, 0 }; + static ulong[] dim1630JoeKuoD6Init = { 1, 3, 7, 3, 9, 35, 109, 203, 123, 217, 225, 3355, 2331, 11853, 0 }; + static ulong[] dim1631JoeKuoD6Init = { 1, 1, 5, 13, 1, 55, 41, 225, 425, 801, 353, 2851, 4403, 7885, 0 }; + static ulong[] dim1632JoeKuoD6Init = { 1, 3, 5, 11, 19, 47, 83, 17, 91, 875, 1739, 971, 8157, 11047, 0 }; + static ulong[] dim1633JoeKuoD6Init = { 1, 3, 1, 15, 29, 47, 123, 209, 183, 473, 1019, 537, 1035, 4473, 0 }; + static ulong[] dim1634JoeKuoD6Init = { 1, 3, 7, 7, 25, 9, 5, 115, 297, 411, 563, 883, 3509, 1637, 0 }; + static ulong[] dim1635JoeKuoD6Init = { 1, 1, 1, 15, 3, 17, 55, 31, 123, 931, 1239, 2137, 3673, 10325, 0 }; + static ulong[] dim1636JoeKuoD6Init = { 1, 1, 5, 1, 31, 49, 35, 51, 223, 65, 925, 2133, 3849, 2243, 0 }; + static ulong[] dim1637JoeKuoD6Init = { 1, 1, 5, 15, 1, 27, 73, 111, 237, 877, 13, 3147, 7115, 13467, 0 }; + static ulong[] dim1638JoeKuoD6Init = { 1, 3, 5, 7, 9, 53, 123, 189, 459, 383, 1259, 297, 3307, 3305, 0 }; + static ulong[] dim1639JoeKuoD6Init = { 1, 3, 5, 15, 27, 45, 65, 175, 417, 377, 195, 1419, 1013, 8419, 0 }; + static ulong[] dim1640JoeKuoD6Init = { 1, 3, 7, 3, 29, 13, 19, 37, 339, 515, 981, 335, 3965, 7577, 0 }; + static ulong[] dim1641JoeKuoD6Init = { 1, 1, 1, 5, 27, 37, 85, 217, 463, 173, 1723, 493, 6847, 12253, 0 }; + static ulong[] dim1642JoeKuoD6Init = { 1, 1, 3, 9, 19, 35, 53, 123, 365, 771, 961, 2545, 3191, 7891, 0 }; + static ulong[] dim1643JoeKuoD6Init = { 1, 3, 7, 3, 27, 47, 81, 243, 89, 79, 13, 1733, 965, 39, 0 }; + static ulong[] dim1644JoeKuoD6Init = { 1, 3, 1, 7, 21, 1, 57, 137, 211, 491, 1071, 2425, 5225, 16141, 0 }; + static ulong[] dim1645JoeKuoD6Init = { 1, 3, 7, 1, 5, 23, 57, 117, 45, 373, 831, 3047, 5829, 3205, 0 }; + static ulong[] dim1646JoeKuoD6Init = { 1, 3, 1, 7, 3, 59, 17, 171, 263, 723, 535, 3791, 4969, 4325, 0 }; + static ulong[] dim1647JoeKuoD6Init = { 1, 1, 5, 7, 19, 5, 75, 169, 231, 25, 1925, 161, 8051, 13051, 0 }; + static ulong[] dim1648JoeKuoD6Init = { 1, 1, 1, 9, 29, 5, 5, 197, 135, 713, 1895, 533, 6703, 9307, 0 }; + static ulong[] dim1649JoeKuoD6Init = { 1, 3, 7, 3, 1, 47, 69, 247, 49, 15, 1533, 3051, 8097, 4881, 0 }; + static ulong[] dim1650JoeKuoD6Init = { 1, 3, 1, 3, 21, 29, 81, 147, 123, 983, 1925, 3959, 3803, 13461, 0 }; + static ulong[] dim1651JoeKuoD6Init = { 1, 1, 5, 11, 25, 59, 99, 253, 85, 37, 1821, 93, 1813, 6001, 0 }; + static ulong[] dim1652JoeKuoD6Init = { 1, 1, 1, 15, 7, 53, 69, 129, 273, 5, 837, 441, 7573, 1803, 0 }; + static ulong[] dim1653JoeKuoD6Init = { 1, 1, 5, 15, 25, 13, 125, 113, 405, 41, 1151, 3659, 3947, 12983, 0 }; + static ulong[] dim1654JoeKuoD6Init = { 1, 1, 3, 15, 19, 1, 63, 223, 343, 523, 1857, 1273, 5251, 13665, 0 }; + static ulong[] dim1655JoeKuoD6Init = { 1, 3, 1, 9, 3, 39, 45, 161, 483, 421, 159, 3257, 7749, 4481, 0 }; + static ulong[] dim1656JoeKuoD6Init = { 1, 1, 5, 15, 13, 53, 25, 213, 179, 753, 1195, 343, 5803, 15289, 0 }; + static ulong[] dim1657JoeKuoD6Init = { 1, 1, 3, 3, 21, 41, 67, 149, 225, 103, 1567, 2681, 3731, 9779, 0 }; + static ulong[] dim1658JoeKuoD6Init = { 1, 3, 7, 3, 1, 25, 9, 185, 373, 851, 1245, 1635, 2255, 8411, 0 }; + static ulong[] dim1659JoeKuoD6Init = { 1, 1, 7, 9, 1, 39, 99, 193, 115, 763, 1079, 1923, 6111, 2327, 0 }; + static ulong[] dim1660JoeKuoD6Init = { 1, 1, 5, 13, 29, 51, 73, 91, 427, 959, 1321, 3105, 5093, 8935, 0 }; + static ulong[] dim1661JoeKuoD6Init = { 1, 3, 3, 7, 3, 37, 19, 187, 341, 907, 119, 2177, 7459, 14047, 0 }; + static ulong[] dim1662JoeKuoD6Init = { 1, 1, 7, 11, 29, 39, 95, 29, 17, 833, 1657, 2867, 4945, 6435, 0 }; + static ulong[] dim1663JoeKuoD6Init = { 1, 3, 7, 9, 15, 51, 123, 201, 161, 239, 1937, 627, 7529, 15029, 0 }; + static ulong[] dim1664JoeKuoD6Init = { 1, 1, 1, 1, 11, 57, 95, 155, 459, 157, 477, 1751, 4569, 13395, 0 }; + static ulong[] dim1665JoeKuoD6Init = { 1, 1, 1, 13, 13, 51, 1, 33, 47, 781, 1527, 2471, 7245, 8565, 0 }; + static ulong[] dim1666JoeKuoD6Init = { 1, 1, 3, 15, 1, 51, 81, 113, 317, 323, 1255, 2387, 6913, 2587, 0 }; + static ulong[] dim1667JoeKuoD6Init = { 1, 1, 5, 3, 25, 9, 73, 163, 31, 367, 477, 3427, 7957, 12235, 0 }; + static ulong[] dim1668JoeKuoD6Init = { 1, 1, 5, 15, 19, 31, 31, 93, 307, 371, 961, 3967, 4205, 12459, 0 }; + static ulong[] dim1669JoeKuoD6Init = { 1, 1, 7, 3, 7, 13, 29, 75, 31, 583, 923, 2993, 5707, 715, 0 }; + static ulong[] dim1670JoeKuoD6Init = { 1, 1, 1, 13, 21, 1, 103, 171, 469, 373, 415, 3031, 1411, 14589, 0 }; + static ulong[] dim1671JoeKuoD6Init = { 1, 1, 7, 3, 17, 11, 57, 89, 441, 709, 1339, 47, 759, 8273, 0 }; + static ulong[] dim1672JoeKuoD6Init = { 1, 3, 1, 11, 13, 61, 73, 31, 503, 619, 371, 3533, 4173, 5011, 0 }; + static ulong[] dim1673JoeKuoD6Init = { 1, 1, 3, 11, 23, 1, 79, 7, 363, 919, 495, 15, 2595, 2691, 0 }; + static ulong[] dim1674JoeKuoD6Init = { 1, 3, 1, 11, 25, 5, 57, 241, 23, 907, 43, 2895, 3697, 11003, 0 }; + static ulong[] dim1675JoeKuoD6Init = { 1, 3, 3, 1, 3, 7, 57, 133, 491, 365, 1793, 3765, 3623, 11377, 0 }; + static ulong[] dim1676JoeKuoD6Init = { 1, 3, 1, 13, 7, 37, 101, 133, 29, 689, 1997, 3011, 2321, 3139, 0 }; + static ulong[] dim1677JoeKuoD6Init = { 1, 1, 5, 13, 17, 21, 119, 253, 323, 469, 1959, 537, 675, 4933, 0 }; + static ulong[] dim1678JoeKuoD6Init = { 1, 1, 7, 11, 19, 19, 29, 7, 451, 111, 1743, 379, 5223, 3477, 0 }; + static ulong[] dim1679JoeKuoD6Init = { 1, 1, 5, 15, 31, 35, 71, 217, 185, 599, 1233, 2079, 7127, 4785, 0 }; + static ulong[] dim1680JoeKuoD6Init = { 1, 1, 7, 11, 1, 33, 41, 239, 429, 987, 1453, 81, 705, 6347, 0 }; + static ulong[] dim1681JoeKuoD6Init = { 1, 3, 7, 13, 29, 49, 107, 217, 295, 797, 563, 1917, 537, 4355, 0 }; + static ulong[] dim1682JoeKuoD6Init = { 1, 3, 1, 13, 17, 49, 27, 67, 5, 239, 53, 1759, 3235, 1321, 0 }; + static ulong[] dim1683JoeKuoD6Init = { 1, 1, 7, 13, 11, 33, 85, 47, 285, 669, 341, 3011, 287, 9693, 0 }; + static ulong[] dim1684JoeKuoD6Init = { 1, 3, 7, 7, 19, 57, 99, 97, 249, 567, 1709, 2053, 7603, 4011, 0 }; + static ulong[] dim1685JoeKuoD6Init = { 1, 1, 3, 1, 3, 55, 105, 245, 167, 785, 1409, 3395, 6503, 14809, 0 }; + static ulong[] dim1686JoeKuoD6Init = { 1, 3, 5, 13, 9, 63, 91, 49, 125, 123, 861, 1327, 5517, 3319, 0 }; + static ulong[] dim1687JoeKuoD6Init = { 1, 3, 5, 7, 3, 63, 101, 167, 403, 43, 1767, 1365, 4577, 15423, 0 }; + static ulong[] dim1688JoeKuoD6Init = { 1, 3, 3, 1, 3, 31, 81, 189, 273, 935, 1195, 3075, 4703, 7855, 0 }; + static ulong[] dim1689JoeKuoD6Init = { 1, 1, 7, 9, 11, 21, 57, 69, 405, 865, 281, 3813, 2543, 4281, 0 }; + static ulong[] dim1690JoeKuoD6Init = { 1, 3, 7, 11, 19, 49, 117, 21, 507, 481, 1961, 2893, 6627, 13545, 0 }; + static ulong[] dim1691JoeKuoD6Init = { 1, 1, 1, 5, 7, 41, 57, 39, 233, 85, 35, 539, 8009, 7223, 0 }; + static ulong[] dim1692JoeKuoD6Init = { 1, 1, 3, 11, 17, 51, 47, 219, 319, 141, 1993, 1473, 2403, 13697, 0 }; + static ulong[] dim1693JoeKuoD6Init = { 1, 1, 5, 1, 5, 61, 69, 251, 499, 813, 123, 925, 2093, 3253, 0 }; + static ulong[] dim1694JoeKuoD6Init = { 1, 1, 3, 11, 23, 19, 97, 19, 345, 127, 1571, 27, 2915, 1497, 0 }; + static ulong[] dim1695JoeKuoD6Init = { 1, 3, 5, 7, 25, 23, 41, 41, 75, 571, 527, 517, 7057, 2737, 0 }; + static ulong[] dim1696JoeKuoD6Init = { 1, 3, 7, 3, 1, 59, 27, 177, 253, 21, 2023, 3393, 3195, 879, 0 }; + static ulong[] dim1697JoeKuoD6Init = { 1, 3, 3, 9, 7, 37, 1, 185, 381, 211, 2033, 1415, 3275, 15281, 0 }; + static ulong[] dim1698JoeKuoD6Init = { 1, 1, 1, 15, 3, 49, 101, 89, 495, 683, 1945, 3017, 5209, 9879, 0 }; + static ulong[] dim1699JoeKuoD6Init = { 1, 3, 3, 7, 17, 63, 55, 243, 215, 289, 1119, 4087, 3513, 2961, 0 }; + static ulong[] dim1700JoeKuoD6Init = { 1, 1, 7, 13, 11, 49, 17, 103, 151, 725, 1433, 967, 4127, 14955, 0 }; + static ulong[] dim1701JoeKuoD6Init = { 1, 3, 5, 9, 11, 5, 69, 179, 163, 565, 245, 2013, 699, 7109, 0 }; + static ulong[] dim1702JoeKuoD6Init = { 1, 3, 7, 15, 29, 23, 39, 93, 211, 1017, 1677, 3883, 6157, 11339, 0 }; + static ulong[] dim1703JoeKuoD6Init = { 1, 1, 7, 9, 7, 15, 27, 109, 449, 165, 1785, 1945, 2095, 14831, 0 }; + static ulong[] dim1704JoeKuoD6Init = { 1, 1, 5, 13, 17, 43, 71, 49, 9, 305, 561, 2309, 6409, 2097, 0 }; + static ulong[] dim1705JoeKuoD6Init = { 1, 1, 7, 5, 9, 63, 77, 149, 119, 727, 1781, 3429, 141, 13329, 0 }; + static ulong[] dim1706JoeKuoD6Init = { 1, 1, 1, 7, 23, 27, 111, 193, 97, 727, 425, 2665, 2217, 7463, 0 }; + static ulong[] dim1707JoeKuoD6Init = { 1, 3, 3, 5, 15, 45, 85, 237, 207, 759, 1007, 2545, 7897, 10953, 0 }; + static ulong[] dim1708JoeKuoD6Init = { 1, 1, 1, 3, 7, 47, 81, 57, 369, 777, 155, 1341, 6679, 5877, 0 }; + static ulong[] dim1709JoeKuoD6Init = { 1, 1, 3, 9, 9, 31, 47, 135, 31, 275, 1779, 2537, 2157, 7347, 0 }; + static ulong[] dim1710JoeKuoD6Init = { 1, 1, 5, 9, 23, 51, 59, 107, 43, 639, 1893, 1713, 2409, 6301, 0 }; + static ulong[] dim1711JoeKuoD6Init = { 1, 3, 5, 13, 9, 13, 13, 231, 419, 373, 1071, 2903, 3565, 15075, 0 }; + static ulong[] dim1712JoeKuoD6Init = { 1, 3, 5, 5, 1, 3, 33, 123, 53, 273, 731, 2049, 4617, 12341, 0 }; + static ulong[] dim1713JoeKuoD6Init = { 1, 3, 1, 1, 17, 49, 75, 141, 499, 863, 635, 2967, 3483, 5087, 0 }; + static ulong[] dim1714JoeKuoD6Init = { 1, 3, 1, 9, 17, 7, 33, 247, 143, 73, 551, 65, 1261, 10177, 0 }; + static ulong[] dim1715JoeKuoD6Init = { 1, 3, 7, 3, 11, 13, 123, 137, 29, 175, 1353, 627, 1223, 191, 0 }; + static ulong[] dim1716JoeKuoD6Init = { 1, 3, 5, 15, 29, 23, 89, 183, 427, 629, 1747, 141, 95, 8319, 0 }; + static ulong[] dim1717JoeKuoD6Init = { 1, 1, 1, 5, 17, 45, 53, 95, 433, 523, 1175, 1227, 6893, 2081, 0 }; + static ulong[] dim1718JoeKuoD6Init = { 1, 3, 3, 15, 29, 21, 107, 117, 407, 937, 301, 1443, 6841, 5673, 0 }; + static ulong[] dim1719JoeKuoD6Init = { 1, 3, 5, 11, 15, 13, 81, 213, 259, 619, 375, 1777, 455, 8185, 0 }; + static ulong[] dim1720JoeKuoD6Init = { 1, 1, 5, 7, 13, 25, 113, 175, 31, 265, 1901, 1779, 1787, 14551, 0 }; + static ulong[] dim1721JoeKuoD6Init = { 1, 3, 1, 9, 17, 59, 41, 183, 405, 477, 133, 3993, 7217, 9373, 0 }; + static ulong[] dim1722JoeKuoD6Init = { 1, 1, 1, 13, 7, 27, 85, 133, 165, 1023, 443, 2549, 1923, 6561, 0 }; + static ulong[] dim1723JoeKuoD6Init = { 1, 3, 7, 3, 15, 51, 11, 167, 321, 37, 1299, 1953, 5365, 8423, 0 }; + static ulong[] dim1724JoeKuoD6Init = { 1, 1, 3, 1, 7, 45, 41, 219, 149, 355, 1975, 1711, 1643, 13669, 0 }; + static ulong[] dim1725JoeKuoD6Init = { 1, 1, 7, 7, 11, 9, 105, 221, 275, 845, 1651, 483, 7463, 7729, 0 }; + static ulong[] dim1726JoeKuoD6Init = { 1, 3, 3, 9, 7, 29, 81, 141, 503, 321, 2039, 405, 7503, 3751, 0 }; + static ulong[] dim1727JoeKuoD6Init = { 1, 1, 1, 7, 21, 31, 19, 71, 299, 301, 1101, 2821, 6005, 5361, 0 }; + static ulong[] dim1728JoeKuoD6Init = { 1, 1, 7, 15, 11, 61, 37, 67, 151, 175, 1815, 2779, 5507, 153, 0 }; + static ulong[] dim1729JoeKuoD6Init = { 1, 1, 5, 11, 9, 41, 83, 225, 109, 23, 563, 1021, 3523, 14027, 0 }; + static ulong[] dim1730JoeKuoD6Init = { 1, 3, 3, 7, 3, 19, 33, 251, 337, 925, 1309, 1895, 4113, 14017, 0 }; + static ulong[] dim1731JoeKuoD6Init = { 1, 3, 7, 9, 15, 57, 15, 121, 311, 929, 1697, 1877, 803, 3361, 0 }; + static ulong[] dim1732JoeKuoD6Init = { 1, 3, 5, 1, 11, 29, 19, 173, 497, 879, 249, 3111, 4227, 14681, 0 }; + static ulong[] dim1733JoeKuoD6Init = { 1, 3, 7, 13, 13, 41, 51, 99, 137, 867, 1207, 3343, 613, 15047, 0 }; + static ulong[] dim1734JoeKuoD6Init = { 1, 3, 3, 15, 11, 41, 57, 7, 203, 569, 669, 3185, 1233, 527, 0 }; + static ulong[] dim1735JoeKuoD6Init = { 1, 3, 5, 5, 27, 45, 83, 49, 335, 747, 1075, 2639, 3057, 4137, 0 }; + static ulong[] dim1736JoeKuoD6Init = { 1, 3, 7, 15, 3, 11, 9, 177, 153, 401, 61, 3689, 3853, 15605, 0 }; + static ulong[] dim1737JoeKuoD6Init = { 1, 3, 3, 7, 27, 13, 79, 51, 213, 465, 1917, 3353, 3553, 14853, 0 }; + static ulong[] dim1738JoeKuoD6Init = { 1, 3, 1, 9, 25, 27, 67, 253, 29, 635, 239, 679, 3653, 15435, 0 }; + static ulong[] dim1739JoeKuoD6Init = { 1, 1, 1, 7, 23, 9, 77, 167, 373, 295, 1423, 1895, 1541, 14563, 0 }; + static ulong[] dim1740JoeKuoD6Init = { 1, 3, 3, 1, 9, 37, 117, 223, 109, 969, 149, 1611, 3511, 11357, 0 }; + static ulong[] dim1741JoeKuoD6Init = { 1, 3, 5, 11, 19, 61, 105, 137, 113, 443, 359, 1705, 6893, 11371, 0 }; + static ulong[] dim1742JoeKuoD6Init = { 1, 3, 1, 13, 21, 11, 65, 3, 275, 311, 1157, 87, 4841, 2995, 0 }; + static ulong[] dim1743JoeKuoD6Init = { 1, 1, 7, 3, 17, 41, 15, 203, 249, 353, 861, 2519, 537, 15203, 0 }; + static ulong[] dim1744JoeKuoD6Init = { 1, 3, 3, 13, 29, 7, 87, 121, 69, 733, 1035, 2731, 8079, 7243, 0 }; + static ulong[] dim1745JoeKuoD6Init = { 1, 1, 1, 3, 13, 3, 109, 47, 161, 313, 1641, 2621, 7629, 13713, 0 }; + static ulong[] dim1746JoeKuoD6Init = { 1, 1, 3, 1, 5, 5, 85, 99, 463, 1005, 89, 1209, 8013, 14393, 0 }; + static ulong[] dim1747JoeKuoD6Init = { 1, 1, 3, 1, 27, 1, 127, 185, 193, 275, 891, 763, 3775, 2569, 0 }; + static ulong[] dim1748JoeKuoD6Init = { 1, 3, 7, 1, 7, 43, 123, 3, 131, 441, 771, 3413, 6641, 2363, 0 }; + static ulong[] dim1749JoeKuoD6Init = { 1, 3, 3, 9, 21, 39, 81, 243, 179, 765, 181, 417, 8027, 1025, 0 }; + static ulong[] dim1750JoeKuoD6Init = { 1, 1, 3, 11, 11, 37, 23, 167, 257, 103, 305, 1097, 6099, 11321, 0 }; + static ulong[] dim1751JoeKuoD6Init = { 1, 3, 1, 7, 27, 29, 71, 207, 83, 367, 1575, 3171, 759, 10981, 0 }; + static ulong[] dim1752JoeKuoD6Init = { 1, 1, 7, 1, 23, 29, 93, 89, 41, 577, 1657, 415, 655, 2501, 0 }; + static ulong[] dim1753JoeKuoD6Init = { 1, 1, 1, 11, 27, 39, 111, 139, 425, 513, 1341, 2059, 2187, 6047, 0 }; + static ulong[] dim1754JoeKuoD6Init = { 1, 1, 1, 13, 25, 55, 63, 193, 183, 429, 611, 2119, 2495, 15361, 0 }; + static ulong[] dim1755JoeKuoD6Init = { 1, 1, 1, 3, 9, 31, 15, 185, 139, 603, 1159, 2065, 1159, 14869, 0 }; + static ulong[] dim1756JoeKuoD6Init = { 1, 1, 3, 5, 21, 5, 117, 191, 357, 61, 1517, 2075, 2041, 14485, 0 }; + static ulong[] dim1757JoeKuoD6Init = { 1, 1, 3, 15, 21, 59, 13, 67, 393, 809, 1539, 3631, 5437, 7787, 0 }; + static ulong[] dim1758JoeKuoD6Init = { 1, 3, 1, 5, 23, 19, 53, 237, 123, 123, 351, 1797, 3415, 4721, 0 }; + static ulong[] dim1759JoeKuoD6Init = { 1, 1, 3, 1, 13, 39, 75, 41, 425, 557, 985, 1485, 7613, 11109, 0 }; + static ulong[] dim1760JoeKuoD6Init = { 1, 3, 1, 11, 25, 29, 23, 117, 411, 721, 21, 1707, 7685, 11979, 0 }; + static ulong[] dim1761JoeKuoD6Init = { 1, 3, 1, 5, 25, 55, 1, 221, 339, 705, 641, 515, 5883, 10709, 0 }; + static ulong[] dim1762JoeKuoD6Init = { 1, 1, 3, 9, 13, 63, 69, 121, 371, 643, 597, 1977, 1295, 10941, 0 }; + static ulong[] dim1763JoeKuoD6Init = { 1, 3, 5, 5, 21, 49, 91, 37, 53, 549, 905, 1707, 7371, 7539, 0 }; + static ulong[] dim1764JoeKuoD6Init = { 1, 1, 5, 9, 9, 43, 45, 205, 49, 1001, 1617, 2307, 3359, 5871, 0 }; + static ulong[] dim1765JoeKuoD6Init = { 1, 3, 5, 7, 7, 43, 73, 129, 381, 97, 529, 607, 2505, 5171, 0 }; + static ulong[] dim1766JoeKuoD6Init = { 1, 1, 5, 9, 3, 31, 81, 63, 185, 443, 1215, 3123, 7973, 8457, 0 }; + static ulong[] dim1767JoeKuoD6Init = { 1, 1, 5, 5, 13, 31, 59, 141, 93, 509, 149, 3039, 6011, 11489, 0 }; + static ulong[] dim1768JoeKuoD6Init = { 1, 1, 5, 5, 17, 13, 93, 221, 23, 325, 415, 829, 7611, 2183, 0 }; + static ulong[] dim1769JoeKuoD6Init = { 1, 3, 3, 3, 13, 55, 47, 77, 375, 41, 1821, 2599, 843, 13411, 0 }; + static ulong[] dim1770JoeKuoD6Init = { 1, 3, 1, 15, 17, 15, 101, 225, 47, 217, 137, 2637, 895, 10679, 0 }; + static ulong[] dim1771JoeKuoD6Init = { 1, 1, 7, 3, 27, 37, 123, 173, 83, 119, 599, 17, 89, 15621, 0 }; + static ulong[] dim1772JoeKuoD6Init = { 1, 3, 7, 11, 25, 41, 105, 43, 247, 841, 1331, 2323, 3499, 5443, 0 }; + static ulong[] dim1773JoeKuoD6Init = { 1, 1, 1, 7, 23, 49, 101, 179, 233, 463, 443, 2825, 3431, 12585, 0 }; + static ulong[] dim1774JoeKuoD6Init = { 1, 3, 7, 13, 31, 49, 115, 173, 193, 615, 663, 2167, 5655, 15331, 0 }; + static ulong[] dim1775JoeKuoD6Init = { 1, 3, 7, 1, 1, 55, 73, 145, 345, 475, 871, 3809, 5329, 15785, 0 }; + static ulong[] dim1776JoeKuoD6Init = { 1, 1, 1, 3, 7, 7, 45, 3, 9, 753, 703, 3381, 4831, 5145, 0 }; + static ulong[] dim1777JoeKuoD6Init = { 1, 3, 1, 15, 21, 51, 93, 181, 275, 127, 1743, 509, 2231, 13423, 0 }; + static ulong[] dim1778JoeKuoD6Init = { 1, 1, 3, 11, 31, 29, 33, 49, 495, 645, 49, 3139, 5281, 12193, 0 }; + static ulong[] dim1779JoeKuoD6Init = { 1, 3, 3, 3, 3, 49, 41, 31, 101, 681, 1331, 1001, 6679, 4525, 0 }; + static ulong[] dim1780JoeKuoD6Init = { 1, 3, 5, 11, 7, 51, 49, 197, 43, 419, 965, 3105, 1325, 3137, 0 }; + static ulong[] dim1781JoeKuoD6Init = { 1, 1, 5, 3, 15, 31, 73, 147, 1, 471, 1569, 3647, 7251, 6261, 0 }; + static ulong[] dim1782JoeKuoD6Init = { 1, 3, 3, 1, 5, 43, 41, 215, 161, 521, 1349, 1627, 1177, 11719, 0 }; + static ulong[] dim1783JoeKuoD6Init = { 1, 1, 3, 11, 31, 5, 125, 79, 199, 581, 1153, 2937, 7875, 16361, 0 }; + static ulong[] dim1784JoeKuoD6Init = { 1, 1, 5, 1, 1, 31, 7, 7, 475, 807, 1249, 811, 6865, 13897, 0 }; + static ulong[] dim1785JoeKuoD6Init = { 1, 3, 1, 9, 5, 7, 11, 203, 215, 669, 1963, 1255, 4785, 11215, 0 }; + static ulong[] dim1786JoeKuoD6Init = { 1, 1, 5, 13, 19, 57, 89, 133, 287, 469, 191, 3177, 1425, 14149, 0 }; + static ulong[] dim1787JoeKuoD6Init = { 1, 3, 5, 15, 9, 9, 13, 229, 477, 261, 1015, 1669, 7685, 3337, 0 }; + static ulong[] dim1788JoeKuoD6Init = { 1, 1, 1, 13, 21, 7, 117, 35, 233, 347, 1347, 2171, 2419, 11555, 0 }; + static ulong[] dim1789JoeKuoD6Init = { 1, 3, 7, 5, 17, 55, 37, 243, 159, 605, 1079, 111, 3149, 3973, 0 }; + static ulong[] dim1790JoeKuoD6Init = { 1, 3, 5, 7, 29, 29, 111, 49, 445, 241, 875, 3895, 3915, 6337, 0 }; + static ulong[] dim1791JoeKuoD6Init = { 1, 3, 1, 3, 13, 7, 21, 185, 121, 319, 1391, 1303, 3123, 7699, 0 }; + static ulong[] dim1792JoeKuoD6Init = { 1, 1, 5, 5, 3, 9, 69, 205, 423, 189, 687, 1453, 2427, 11231, 0 }; + static ulong[] dim1793JoeKuoD6Init = { 1, 3, 3, 7, 5, 31, 91, 235, 287, 185, 1439, 2011, 7429, 4313, 0 }; + static ulong[] dim1794JoeKuoD6Init = { 1, 1, 7, 1, 3, 57, 11, 11, 377, 699, 883, 221, 4849, 11373, 0 }; + static ulong[] dim1795JoeKuoD6Init = { 1, 1, 1, 11, 3, 15, 51, 79, 83, 915, 1429, 811, 2651, 829, 0 }; + static ulong[] dim1796JoeKuoD6Init = { 1, 1, 1, 5, 21, 17, 5, 227, 379, 383, 745, 2761, 323, 753, 0 }; + static ulong[] dim1797JoeKuoD6Init = { 1, 1, 3, 9, 11, 33, 123, 59, 241, 829, 879, 3339, 5315, 10777, 0 }; + static ulong[] dim1798JoeKuoD6Init = { 1, 3, 7, 13, 25, 27, 117, 5, 11, 793, 243, 2571, 369, 1371, 0 }; + static ulong[] dim1799JoeKuoD6Init = { 1, 1, 1, 3, 21, 31, 95, 217, 175, 837, 583, 1149, 8073, 12751, 0 }; + + static ulong[][] JoeKuoD6initializers = + { + dim1JoeKuoD6Init, + dim2JoeKuoD6Init, + dim3JoeKuoD6Init, + dim4JoeKuoD6Init, + dim5JoeKuoD6Init, + dim6JoeKuoD6Init, + dim7JoeKuoD6Init, + dim8JoeKuoD6Init, + dim9JoeKuoD6Init, + dim10JoeKuoD6Init, + dim11JoeKuoD6Init, + dim12JoeKuoD6Init, + dim13JoeKuoD6Init, + dim14JoeKuoD6Init, + dim15JoeKuoD6Init, + dim16JoeKuoD6Init, + dim17JoeKuoD6Init, + dim18JoeKuoD6Init, + dim19JoeKuoD6Init, + dim20JoeKuoD6Init, + dim21JoeKuoD6Init, + dim22JoeKuoD6Init, + dim23JoeKuoD6Init, + dim24JoeKuoD6Init, + dim25JoeKuoD6Init, + dim26JoeKuoD6Init, + dim27JoeKuoD6Init, + dim28JoeKuoD6Init, + dim29JoeKuoD6Init, + dim30JoeKuoD6Init, + dim31JoeKuoD6Init, + dim32JoeKuoD6Init, + dim33JoeKuoD6Init, + dim34JoeKuoD6Init, + dim35JoeKuoD6Init, + dim36JoeKuoD6Init, + dim37JoeKuoD6Init, + dim38JoeKuoD6Init, + dim39JoeKuoD6Init, + dim40JoeKuoD6Init, + dim41JoeKuoD6Init, + dim42JoeKuoD6Init, + dim43JoeKuoD6Init, + dim44JoeKuoD6Init, + dim45JoeKuoD6Init, + dim46JoeKuoD6Init, + dim47JoeKuoD6Init, + dim48JoeKuoD6Init, + dim49JoeKuoD6Init, + dim50JoeKuoD6Init, + dim51JoeKuoD6Init, + dim52JoeKuoD6Init, + dim53JoeKuoD6Init, + dim54JoeKuoD6Init, + dim55JoeKuoD6Init, + dim56JoeKuoD6Init, + dim57JoeKuoD6Init, + dim58JoeKuoD6Init, + dim59JoeKuoD6Init, + dim60JoeKuoD6Init, + dim61JoeKuoD6Init, + dim62JoeKuoD6Init, + dim63JoeKuoD6Init, + dim64JoeKuoD6Init, + dim65JoeKuoD6Init, + dim66JoeKuoD6Init, + dim67JoeKuoD6Init, + dim68JoeKuoD6Init, + dim69JoeKuoD6Init, + dim70JoeKuoD6Init, + dim71JoeKuoD6Init, + dim72JoeKuoD6Init, + dim73JoeKuoD6Init, + dim74JoeKuoD6Init, + dim75JoeKuoD6Init, + dim76JoeKuoD6Init, + dim77JoeKuoD6Init, + dim78JoeKuoD6Init, + dim79JoeKuoD6Init, + dim80JoeKuoD6Init, + dim81JoeKuoD6Init, + dim82JoeKuoD6Init, + dim83JoeKuoD6Init, + dim84JoeKuoD6Init, + dim85JoeKuoD6Init, + dim86JoeKuoD6Init, + dim87JoeKuoD6Init, + dim88JoeKuoD6Init, + dim89JoeKuoD6Init, + dim90JoeKuoD6Init, + dim91JoeKuoD6Init, + dim92JoeKuoD6Init, + dim93JoeKuoD6Init, + dim94JoeKuoD6Init, + dim95JoeKuoD6Init, + dim96JoeKuoD6Init, + dim97JoeKuoD6Init, + dim98JoeKuoD6Init, + dim99JoeKuoD6Init, + dim100JoeKuoD6Init, + dim101JoeKuoD6Init, + dim102JoeKuoD6Init, + dim103JoeKuoD6Init, + dim104JoeKuoD6Init, + dim105JoeKuoD6Init, + dim106JoeKuoD6Init, + dim107JoeKuoD6Init, + dim108JoeKuoD6Init, + dim109JoeKuoD6Init, + dim110JoeKuoD6Init, + dim111JoeKuoD6Init, + dim112JoeKuoD6Init, + dim113JoeKuoD6Init, + dim114JoeKuoD6Init, + dim115JoeKuoD6Init, + dim116JoeKuoD6Init, + dim117JoeKuoD6Init, + dim118JoeKuoD6Init, + dim119JoeKuoD6Init, + dim120JoeKuoD6Init, + dim121JoeKuoD6Init, + dim122JoeKuoD6Init, + dim123JoeKuoD6Init, + dim124JoeKuoD6Init, + dim125JoeKuoD6Init, + dim126JoeKuoD6Init, + dim127JoeKuoD6Init, + dim128JoeKuoD6Init, + dim129JoeKuoD6Init, + dim130JoeKuoD6Init, + dim131JoeKuoD6Init, + dim132JoeKuoD6Init, + dim133JoeKuoD6Init, + dim134JoeKuoD6Init, + dim135JoeKuoD6Init, + dim136JoeKuoD6Init, + dim137JoeKuoD6Init, + dim138JoeKuoD6Init, + dim139JoeKuoD6Init, + dim140JoeKuoD6Init, + dim141JoeKuoD6Init, + dim142JoeKuoD6Init, + dim143JoeKuoD6Init, + dim144JoeKuoD6Init, + dim145JoeKuoD6Init, + dim146JoeKuoD6Init, + dim147JoeKuoD6Init, + dim148JoeKuoD6Init, + dim149JoeKuoD6Init, + dim150JoeKuoD6Init, + dim151JoeKuoD6Init, + dim152JoeKuoD6Init, + dim153JoeKuoD6Init, + dim154JoeKuoD6Init, + dim155JoeKuoD6Init, + dim156JoeKuoD6Init, + dim157JoeKuoD6Init, + dim158JoeKuoD6Init, + dim159JoeKuoD6Init, + dim160JoeKuoD6Init, + dim161JoeKuoD6Init, + dim162JoeKuoD6Init, + dim163JoeKuoD6Init, + dim164JoeKuoD6Init, + dim165JoeKuoD6Init, + dim166JoeKuoD6Init, + dim167JoeKuoD6Init, + dim168JoeKuoD6Init, + dim169JoeKuoD6Init, + dim170JoeKuoD6Init, + dim171JoeKuoD6Init, + dim172JoeKuoD6Init, + dim173JoeKuoD6Init, + dim174JoeKuoD6Init, + dim175JoeKuoD6Init, + dim176JoeKuoD6Init, + dim177JoeKuoD6Init, + dim178JoeKuoD6Init, + dim179JoeKuoD6Init, + dim180JoeKuoD6Init, + dim181JoeKuoD6Init, + dim182JoeKuoD6Init, + dim183JoeKuoD6Init, + dim184JoeKuoD6Init, + dim185JoeKuoD6Init, + dim186JoeKuoD6Init, + dim187JoeKuoD6Init, + dim188JoeKuoD6Init, + dim189JoeKuoD6Init, + dim190JoeKuoD6Init, + dim191JoeKuoD6Init, + dim192JoeKuoD6Init, + dim193JoeKuoD6Init, + dim194JoeKuoD6Init, + dim195JoeKuoD6Init, + dim196JoeKuoD6Init, + dim197JoeKuoD6Init, + dim198JoeKuoD6Init, + dim199JoeKuoD6Init, + dim200JoeKuoD6Init, + dim201JoeKuoD6Init, + dim202JoeKuoD6Init, + dim203JoeKuoD6Init, + dim204JoeKuoD6Init, + dim205JoeKuoD6Init, + dim206JoeKuoD6Init, + dim207JoeKuoD6Init, + dim208JoeKuoD6Init, + dim209JoeKuoD6Init, + dim210JoeKuoD6Init, + dim211JoeKuoD6Init, + dim212JoeKuoD6Init, + dim213JoeKuoD6Init, + dim214JoeKuoD6Init, + dim215JoeKuoD6Init, + dim216JoeKuoD6Init, + dim217JoeKuoD6Init, + dim218JoeKuoD6Init, + dim219JoeKuoD6Init, + dim220JoeKuoD6Init, + dim221JoeKuoD6Init, + dim222JoeKuoD6Init, + dim223JoeKuoD6Init, + dim224JoeKuoD6Init, + dim225JoeKuoD6Init, + dim226JoeKuoD6Init, + dim227JoeKuoD6Init, + dim228JoeKuoD6Init, + dim229JoeKuoD6Init, + dim230JoeKuoD6Init, + dim231JoeKuoD6Init, + dim232JoeKuoD6Init, + dim233JoeKuoD6Init, + dim234JoeKuoD6Init, + dim235JoeKuoD6Init, + dim236JoeKuoD6Init, + dim237JoeKuoD6Init, + dim238JoeKuoD6Init, + dim239JoeKuoD6Init, + dim240JoeKuoD6Init, + dim241JoeKuoD6Init, + dim242JoeKuoD6Init, + dim243JoeKuoD6Init, + dim244JoeKuoD6Init, + dim245JoeKuoD6Init, + dim246JoeKuoD6Init, + dim247JoeKuoD6Init, + dim248JoeKuoD6Init, + dim249JoeKuoD6Init, + dim250JoeKuoD6Init, + dim251JoeKuoD6Init, + dim252JoeKuoD6Init, + dim253JoeKuoD6Init, + dim254JoeKuoD6Init, + dim255JoeKuoD6Init, + dim256JoeKuoD6Init, + dim257JoeKuoD6Init, + dim258JoeKuoD6Init, + dim259JoeKuoD6Init, + dim260JoeKuoD6Init, + dim261JoeKuoD6Init, + dim262JoeKuoD6Init, + dim263JoeKuoD6Init, + dim264JoeKuoD6Init, + dim265JoeKuoD6Init, + dim266JoeKuoD6Init, + dim267JoeKuoD6Init, + dim268JoeKuoD6Init, + dim269JoeKuoD6Init, + dim270JoeKuoD6Init, + dim271JoeKuoD6Init, + dim272JoeKuoD6Init, + dim273JoeKuoD6Init, + dim274JoeKuoD6Init, + dim275JoeKuoD6Init, + dim276JoeKuoD6Init, + dim277JoeKuoD6Init, + dim278JoeKuoD6Init, + dim279JoeKuoD6Init, + dim280JoeKuoD6Init, + dim281JoeKuoD6Init, + dim282JoeKuoD6Init, + dim283JoeKuoD6Init, + dim284JoeKuoD6Init, + dim285JoeKuoD6Init, + dim286JoeKuoD6Init, + dim287JoeKuoD6Init, + dim288JoeKuoD6Init, + dim289JoeKuoD6Init, + dim290JoeKuoD6Init, + dim291JoeKuoD6Init, + dim292JoeKuoD6Init, + dim293JoeKuoD6Init, + dim294JoeKuoD6Init, + dim295JoeKuoD6Init, + dim296JoeKuoD6Init, + dim297JoeKuoD6Init, + dim298JoeKuoD6Init, + dim299JoeKuoD6Init, + dim300JoeKuoD6Init, + dim301JoeKuoD6Init, + dim302JoeKuoD6Init, + dim303JoeKuoD6Init, + dim304JoeKuoD6Init, + dim305JoeKuoD6Init, + dim306JoeKuoD6Init, + dim307JoeKuoD6Init, + dim308JoeKuoD6Init, + dim309JoeKuoD6Init, + dim310JoeKuoD6Init, + dim311JoeKuoD6Init, + dim312JoeKuoD6Init, + dim313JoeKuoD6Init, + dim314JoeKuoD6Init, + dim315JoeKuoD6Init, + dim316JoeKuoD6Init, + dim317JoeKuoD6Init, + dim318JoeKuoD6Init, + dim319JoeKuoD6Init, + dim320JoeKuoD6Init, + dim321JoeKuoD6Init, + dim322JoeKuoD6Init, + dim323JoeKuoD6Init, + dim324JoeKuoD6Init, + dim325JoeKuoD6Init, + dim326JoeKuoD6Init, + dim327JoeKuoD6Init, + dim328JoeKuoD6Init, + dim329JoeKuoD6Init, + dim330JoeKuoD6Init, + dim331JoeKuoD6Init, + dim332JoeKuoD6Init, + dim333JoeKuoD6Init, + dim334JoeKuoD6Init, + dim335JoeKuoD6Init, + dim336JoeKuoD6Init, + dim337JoeKuoD6Init, + dim338JoeKuoD6Init, + dim339JoeKuoD6Init, + dim340JoeKuoD6Init, + dim341JoeKuoD6Init, + dim342JoeKuoD6Init, + dim343JoeKuoD6Init, + dim344JoeKuoD6Init, + dim345JoeKuoD6Init, + dim346JoeKuoD6Init, + dim347JoeKuoD6Init, + dim348JoeKuoD6Init, + dim349JoeKuoD6Init, + dim350JoeKuoD6Init, + dim351JoeKuoD6Init, + dim352JoeKuoD6Init, + dim353JoeKuoD6Init, + dim354JoeKuoD6Init, + dim355JoeKuoD6Init, + dim356JoeKuoD6Init, + dim357JoeKuoD6Init, + dim358JoeKuoD6Init, + dim359JoeKuoD6Init, + dim360JoeKuoD6Init, + dim361JoeKuoD6Init, + dim362JoeKuoD6Init, + dim363JoeKuoD6Init, + dim364JoeKuoD6Init, + dim365JoeKuoD6Init, + dim366JoeKuoD6Init, + dim367JoeKuoD6Init, + dim368JoeKuoD6Init, + dim369JoeKuoD6Init, + dim370JoeKuoD6Init, + dim371JoeKuoD6Init, + dim372JoeKuoD6Init, + dim373JoeKuoD6Init, + dim374JoeKuoD6Init, + dim375JoeKuoD6Init, + dim376JoeKuoD6Init, + dim377JoeKuoD6Init, + dim378JoeKuoD6Init, + dim379JoeKuoD6Init, + dim380JoeKuoD6Init, + dim381JoeKuoD6Init, + dim382JoeKuoD6Init, + dim383JoeKuoD6Init, + dim384JoeKuoD6Init, + dim385JoeKuoD6Init, + dim386JoeKuoD6Init, + dim387JoeKuoD6Init, + dim388JoeKuoD6Init, + dim389JoeKuoD6Init, + dim390JoeKuoD6Init, + dim391JoeKuoD6Init, + dim392JoeKuoD6Init, + dim393JoeKuoD6Init, + dim394JoeKuoD6Init, + dim395JoeKuoD6Init, + dim396JoeKuoD6Init, + dim397JoeKuoD6Init, + dim398JoeKuoD6Init, + dim399JoeKuoD6Init, + dim400JoeKuoD6Init, + dim401JoeKuoD6Init, + dim402JoeKuoD6Init, + dim403JoeKuoD6Init, + dim404JoeKuoD6Init, + dim405JoeKuoD6Init, + dim406JoeKuoD6Init, + dim407JoeKuoD6Init, + dim408JoeKuoD6Init, + dim409JoeKuoD6Init, + dim410JoeKuoD6Init, + dim411JoeKuoD6Init, + dim412JoeKuoD6Init, + dim413JoeKuoD6Init, + dim414JoeKuoD6Init, + dim415JoeKuoD6Init, + dim416JoeKuoD6Init, + dim417JoeKuoD6Init, + dim418JoeKuoD6Init, + dim419JoeKuoD6Init, + dim420JoeKuoD6Init, + dim421JoeKuoD6Init, + dim422JoeKuoD6Init, + dim423JoeKuoD6Init, + dim424JoeKuoD6Init, + dim425JoeKuoD6Init, + dim426JoeKuoD6Init, + dim427JoeKuoD6Init, + dim428JoeKuoD6Init, + dim429JoeKuoD6Init, + dim430JoeKuoD6Init, + dim431JoeKuoD6Init, + dim432JoeKuoD6Init, + dim433JoeKuoD6Init, + dim434JoeKuoD6Init, + dim435JoeKuoD6Init, + dim436JoeKuoD6Init, + dim437JoeKuoD6Init, + dim438JoeKuoD6Init, + dim439JoeKuoD6Init, + dim440JoeKuoD6Init, + dim441JoeKuoD6Init, + dim442JoeKuoD6Init, + dim443JoeKuoD6Init, + dim444JoeKuoD6Init, + dim445JoeKuoD6Init, + dim446JoeKuoD6Init, + dim447JoeKuoD6Init, + dim448JoeKuoD6Init, + dim449JoeKuoD6Init, + dim450JoeKuoD6Init, + dim451JoeKuoD6Init, + dim452JoeKuoD6Init, + dim453JoeKuoD6Init, + dim454JoeKuoD6Init, + dim455JoeKuoD6Init, + dim456JoeKuoD6Init, + dim457JoeKuoD6Init, + dim458JoeKuoD6Init, + dim459JoeKuoD6Init, + dim460JoeKuoD6Init, + dim461JoeKuoD6Init, + dim462JoeKuoD6Init, + dim463JoeKuoD6Init, + dim464JoeKuoD6Init, + dim465JoeKuoD6Init, + dim466JoeKuoD6Init, + dim467JoeKuoD6Init, + dim468JoeKuoD6Init, + dim469JoeKuoD6Init, + dim470JoeKuoD6Init, + dim471JoeKuoD6Init, + dim472JoeKuoD6Init, + dim473JoeKuoD6Init, + dim474JoeKuoD6Init, + dim475JoeKuoD6Init, + dim476JoeKuoD6Init, + dim477JoeKuoD6Init, + dim478JoeKuoD6Init, + dim479JoeKuoD6Init, + dim480JoeKuoD6Init, + dim481JoeKuoD6Init, + dim482JoeKuoD6Init, + dim483JoeKuoD6Init, + dim484JoeKuoD6Init, + dim485JoeKuoD6Init, + dim486JoeKuoD6Init, + dim487JoeKuoD6Init, + dim488JoeKuoD6Init, + dim489JoeKuoD6Init, + dim490JoeKuoD6Init, + dim491JoeKuoD6Init, + dim492JoeKuoD6Init, + dim493JoeKuoD6Init, + dim494JoeKuoD6Init, + dim495JoeKuoD6Init, + dim496JoeKuoD6Init, + dim497JoeKuoD6Init, + dim498JoeKuoD6Init, + dim499JoeKuoD6Init, + dim500JoeKuoD6Init, + dim501JoeKuoD6Init, + dim502JoeKuoD6Init, + dim503JoeKuoD6Init, + dim504JoeKuoD6Init, + dim505JoeKuoD6Init, + dim506JoeKuoD6Init, + dim507JoeKuoD6Init, + dim508JoeKuoD6Init, + dim509JoeKuoD6Init, + dim510JoeKuoD6Init, + dim511JoeKuoD6Init, + dim512JoeKuoD6Init, + dim513JoeKuoD6Init, + dim514JoeKuoD6Init, + dim515JoeKuoD6Init, + dim516JoeKuoD6Init, + dim517JoeKuoD6Init, + dim518JoeKuoD6Init, + dim519JoeKuoD6Init, + dim520JoeKuoD6Init, + dim521JoeKuoD6Init, + dim522JoeKuoD6Init, + dim523JoeKuoD6Init, + dim524JoeKuoD6Init, + dim525JoeKuoD6Init, + dim526JoeKuoD6Init, + dim527JoeKuoD6Init, + dim528JoeKuoD6Init, + dim529JoeKuoD6Init, + dim530JoeKuoD6Init, + dim531JoeKuoD6Init, + dim532JoeKuoD6Init, + dim533JoeKuoD6Init, + dim534JoeKuoD6Init, + dim535JoeKuoD6Init, + dim536JoeKuoD6Init, + dim537JoeKuoD6Init, + dim538JoeKuoD6Init, + dim539JoeKuoD6Init, + dim540JoeKuoD6Init, + dim541JoeKuoD6Init, + dim542JoeKuoD6Init, + dim543JoeKuoD6Init, + dim544JoeKuoD6Init, + dim545JoeKuoD6Init, + dim546JoeKuoD6Init, + dim547JoeKuoD6Init, + dim548JoeKuoD6Init, + dim549JoeKuoD6Init, + dim550JoeKuoD6Init, + dim551JoeKuoD6Init, + dim552JoeKuoD6Init, + dim553JoeKuoD6Init, + dim554JoeKuoD6Init, + dim555JoeKuoD6Init, + dim556JoeKuoD6Init, + dim557JoeKuoD6Init, + dim558JoeKuoD6Init, + dim559JoeKuoD6Init, + dim560JoeKuoD6Init, + dim561JoeKuoD6Init, + dim562JoeKuoD6Init, + dim563JoeKuoD6Init, + dim564JoeKuoD6Init, + dim565JoeKuoD6Init, + dim566JoeKuoD6Init, + dim567JoeKuoD6Init, + dim568JoeKuoD6Init, + dim569JoeKuoD6Init, + dim570JoeKuoD6Init, + dim571JoeKuoD6Init, + dim572JoeKuoD6Init, + dim573JoeKuoD6Init, + dim574JoeKuoD6Init, + dim575JoeKuoD6Init, + dim576JoeKuoD6Init, + dim577JoeKuoD6Init, + dim578JoeKuoD6Init, + dim579JoeKuoD6Init, + dim580JoeKuoD6Init, + dim581JoeKuoD6Init, + dim582JoeKuoD6Init, + dim583JoeKuoD6Init, + dim584JoeKuoD6Init, + dim585JoeKuoD6Init, + dim586JoeKuoD6Init, + dim587JoeKuoD6Init, + dim588JoeKuoD6Init, + dim589JoeKuoD6Init, + dim590JoeKuoD6Init, + dim591JoeKuoD6Init, + dim592JoeKuoD6Init, + dim593JoeKuoD6Init, + dim594JoeKuoD6Init, + dim595JoeKuoD6Init, + dim596JoeKuoD6Init, + dim597JoeKuoD6Init, + dim598JoeKuoD6Init, + dim599JoeKuoD6Init, + dim600JoeKuoD6Init, + dim601JoeKuoD6Init, + dim602JoeKuoD6Init, + dim603JoeKuoD6Init, + dim604JoeKuoD6Init, + dim605JoeKuoD6Init, + dim606JoeKuoD6Init, + dim607JoeKuoD6Init, + dim608JoeKuoD6Init, + dim609JoeKuoD6Init, + dim610JoeKuoD6Init, + dim611JoeKuoD6Init, + dim612JoeKuoD6Init, + dim613JoeKuoD6Init, + dim614JoeKuoD6Init, + dim615JoeKuoD6Init, + dim616JoeKuoD6Init, + dim617JoeKuoD6Init, + dim618JoeKuoD6Init, + dim619JoeKuoD6Init, + dim620JoeKuoD6Init, + dim621JoeKuoD6Init, + dim622JoeKuoD6Init, + dim623JoeKuoD6Init, + dim624JoeKuoD6Init, + dim625JoeKuoD6Init, + dim626JoeKuoD6Init, + dim627JoeKuoD6Init, + dim628JoeKuoD6Init, + dim629JoeKuoD6Init, + dim630JoeKuoD6Init, + dim631JoeKuoD6Init, + dim632JoeKuoD6Init, + dim633JoeKuoD6Init, + dim634JoeKuoD6Init, + dim635JoeKuoD6Init, + dim636JoeKuoD6Init, + dim637JoeKuoD6Init, + dim638JoeKuoD6Init, + dim639JoeKuoD6Init, + dim640JoeKuoD6Init, + dim641JoeKuoD6Init, + dim642JoeKuoD6Init, + dim643JoeKuoD6Init, + dim644JoeKuoD6Init, + dim645JoeKuoD6Init, + dim646JoeKuoD6Init, + dim647JoeKuoD6Init, + dim648JoeKuoD6Init, + dim649JoeKuoD6Init, + dim650JoeKuoD6Init, + dim651JoeKuoD6Init, + dim652JoeKuoD6Init, + dim653JoeKuoD6Init, + dim654JoeKuoD6Init, + dim655JoeKuoD6Init, + dim656JoeKuoD6Init, + dim657JoeKuoD6Init, + dim658JoeKuoD6Init, + dim659JoeKuoD6Init, + dim660JoeKuoD6Init, + dim661JoeKuoD6Init, + dim662JoeKuoD6Init, + dim663JoeKuoD6Init, + dim664JoeKuoD6Init, + dim665JoeKuoD6Init, + dim666JoeKuoD6Init, + dim667JoeKuoD6Init, + dim668JoeKuoD6Init, + dim669JoeKuoD6Init, + dim670JoeKuoD6Init, + dim671JoeKuoD6Init, + dim672JoeKuoD6Init, + dim673JoeKuoD6Init, + dim674JoeKuoD6Init, + dim675JoeKuoD6Init, + dim676JoeKuoD6Init, + dim677JoeKuoD6Init, + dim678JoeKuoD6Init, + dim679JoeKuoD6Init, + dim680JoeKuoD6Init, + dim681JoeKuoD6Init, + dim682JoeKuoD6Init, + dim683JoeKuoD6Init, + dim684JoeKuoD6Init, + dim685JoeKuoD6Init, + dim686JoeKuoD6Init, + dim687JoeKuoD6Init, + dim688JoeKuoD6Init, + dim689JoeKuoD6Init, + dim690JoeKuoD6Init, + dim691JoeKuoD6Init, + dim692JoeKuoD6Init, + dim693JoeKuoD6Init, + dim694JoeKuoD6Init, + dim695JoeKuoD6Init, + dim696JoeKuoD6Init, + dim697JoeKuoD6Init, + dim698JoeKuoD6Init, + dim699JoeKuoD6Init, + dim700JoeKuoD6Init, + dim701JoeKuoD6Init, + dim702JoeKuoD6Init, + dim703JoeKuoD6Init, + dim704JoeKuoD6Init, + dim705JoeKuoD6Init, + dim706JoeKuoD6Init, + dim707JoeKuoD6Init, + dim708JoeKuoD6Init, + dim709JoeKuoD6Init, + dim710JoeKuoD6Init, + dim711JoeKuoD6Init, + dim712JoeKuoD6Init, + dim713JoeKuoD6Init, + dim714JoeKuoD6Init, + dim715JoeKuoD6Init, + dim716JoeKuoD6Init, + dim717JoeKuoD6Init, + dim718JoeKuoD6Init, + dim719JoeKuoD6Init, + dim720JoeKuoD6Init, + dim721JoeKuoD6Init, + dim722JoeKuoD6Init, + dim723JoeKuoD6Init, + dim724JoeKuoD6Init, + dim725JoeKuoD6Init, + dim726JoeKuoD6Init, + dim727JoeKuoD6Init, + dim728JoeKuoD6Init, + dim729JoeKuoD6Init, + dim730JoeKuoD6Init, + dim731JoeKuoD6Init, + dim732JoeKuoD6Init, + dim733JoeKuoD6Init, + dim734JoeKuoD6Init, + dim735JoeKuoD6Init, + dim736JoeKuoD6Init, + dim737JoeKuoD6Init, + dim738JoeKuoD6Init, + dim739JoeKuoD6Init, + dim740JoeKuoD6Init, + dim741JoeKuoD6Init, + dim742JoeKuoD6Init, + dim743JoeKuoD6Init, + dim744JoeKuoD6Init, + dim745JoeKuoD6Init, + dim746JoeKuoD6Init, + dim747JoeKuoD6Init, + dim748JoeKuoD6Init, + dim749JoeKuoD6Init, + dim750JoeKuoD6Init, + dim751JoeKuoD6Init, + dim752JoeKuoD6Init, + dim753JoeKuoD6Init, + dim754JoeKuoD6Init, + dim755JoeKuoD6Init, + dim756JoeKuoD6Init, + dim757JoeKuoD6Init, + dim758JoeKuoD6Init, + dim759JoeKuoD6Init, + dim760JoeKuoD6Init, + dim761JoeKuoD6Init, + dim762JoeKuoD6Init, + dim763JoeKuoD6Init, + dim764JoeKuoD6Init, + dim765JoeKuoD6Init, + dim766JoeKuoD6Init, + dim767JoeKuoD6Init, + dim768JoeKuoD6Init, + dim769JoeKuoD6Init, + dim770JoeKuoD6Init, + dim771JoeKuoD6Init, + dim772JoeKuoD6Init, + dim773JoeKuoD6Init, + dim774JoeKuoD6Init, + dim775JoeKuoD6Init, + dim776JoeKuoD6Init, + dim777JoeKuoD6Init, + dim778JoeKuoD6Init, + dim779JoeKuoD6Init, + dim780JoeKuoD6Init, + dim781JoeKuoD6Init, + dim782JoeKuoD6Init, + dim783JoeKuoD6Init, + dim784JoeKuoD6Init, + dim785JoeKuoD6Init, + dim786JoeKuoD6Init, + dim787JoeKuoD6Init, + dim788JoeKuoD6Init, + dim789JoeKuoD6Init, + dim790JoeKuoD6Init, + dim791JoeKuoD6Init, + dim792JoeKuoD6Init, + dim793JoeKuoD6Init, + dim794JoeKuoD6Init, + dim795JoeKuoD6Init, + dim796JoeKuoD6Init, + dim797JoeKuoD6Init, + dim798JoeKuoD6Init, + dim799JoeKuoD6Init, + dim800JoeKuoD6Init, + dim801JoeKuoD6Init, + dim802JoeKuoD6Init, + dim803JoeKuoD6Init, + dim804JoeKuoD6Init, + dim805JoeKuoD6Init, + dim806JoeKuoD6Init, + dim807JoeKuoD6Init, + dim808JoeKuoD6Init, + dim809JoeKuoD6Init, + dim810JoeKuoD6Init, + dim811JoeKuoD6Init, + dim812JoeKuoD6Init, + dim813JoeKuoD6Init, + dim814JoeKuoD6Init, + dim815JoeKuoD6Init, + dim816JoeKuoD6Init, + dim817JoeKuoD6Init, + dim818JoeKuoD6Init, + dim819JoeKuoD6Init, + dim820JoeKuoD6Init, + dim821JoeKuoD6Init, + dim822JoeKuoD6Init, + dim823JoeKuoD6Init, + dim824JoeKuoD6Init, + dim825JoeKuoD6Init, + dim826JoeKuoD6Init, + dim827JoeKuoD6Init, + dim828JoeKuoD6Init, + dim829JoeKuoD6Init, + dim830JoeKuoD6Init, + dim831JoeKuoD6Init, + dim832JoeKuoD6Init, + dim833JoeKuoD6Init, + dim834JoeKuoD6Init, + dim835JoeKuoD6Init, + dim836JoeKuoD6Init, + dim837JoeKuoD6Init, + dim838JoeKuoD6Init, + dim839JoeKuoD6Init, + dim840JoeKuoD6Init, + dim841JoeKuoD6Init, + dim842JoeKuoD6Init, + dim843JoeKuoD6Init, + dim844JoeKuoD6Init, + dim845JoeKuoD6Init, + dim846JoeKuoD6Init, + dim847JoeKuoD6Init, + dim848JoeKuoD6Init, + dim849JoeKuoD6Init, + dim850JoeKuoD6Init, + dim851JoeKuoD6Init, + dim852JoeKuoD6Init, + dim853JoeKuoD6Init, + dim854JoeKuoD6Init, + dim855JoeKuoD6Init, + dim856JoeKuoD6Init, + dim857JoeKuoD6Init, + dim858JoeKuoD6Init, + dim859JoeKuoD6Init, + dim860JoeKuoD6Init, + dim861JoeKuoD6Init, + dim862JoeKuoD6Init, + dim863JoeKuoD6Init, + dim864JoeKuoD6Init, + dim865JoeKuoD6Init, + dim866JoeKuoD6Init, + dim867JoeKuoD6Init, + dim868JoeKuoD6Init, + dim869JoeKuoD6Init, + dim870JoeKuoD6Init, + dim871JoeKuoD6Init, + dim872JoeKuoD6Init, + dim873JoeKuoD6Init, + dim874JoeKuoD6Init, + dim875JoeKuoD6Init, + dim876JoeKuoD6Init, + dim877JoeKuoD6Init, + dim878JoeKuoD6Init, + dim879JoeKuoD6Init, + dim880JoeKuoD6Init, + dim881JoeKuoD6Init, + dim882JoeKuoD6Init, + dim883JoeKuoD6Init, + dim884JoeKuoD6Init, + dim885JoeKuoD6Init, + dim886JoeKuoD6Init, + dim887JoeKuoD6Init, + dim888JoeKuoD6Init, + dim889JoeKuoD6Init, + dim890JoeKuoD6Init, + dim891JoeKuoD6Init, + dim892JoeKuoD6Init, + dim893JoeKuoD6Init, + dim894JoeKuoD6Init, + dim895JoeKuoD6Init, + dim896JoeKuoD6Init, + dim897JoeKuoD6Init, + dim898JoeKuoD6Init, + dim899JoeKuoD6Init, + dim900JoeKuoD6Init, + dim901JoeKuoD6Init, + dim902JoeKuoD6Init, + dim903JoeKuoD6Init, + dim904JoeKuoD6Init, + dim905JoeKuoD6Init, + dim906JoeKuoD6Init, + dim907JoeKuoD6Init, + dim908JoeKuoD6Init, + dim909JoeKuoD6Init, + dim910JoeKuoD6Init, + dim911JoeKuoD6Init, + dim912JoeKuoD6Init, + dim913JoeKuoD6Init, + dim914JoeKuoD6Init, + dim915JoeKuoD6Init, + dim916JoeKuoD6Init, + dim917JoeKuoD6Init, + dim918JoeKuoD6Init, + dim919JoeKuoD6Init, + dim920JoeKuoD6Init, + dim921JoeKuoD6Init, + dim922JoeKuoD6Init, + dim923JoeKuoD6Init, + dim924JoeKuoD6Init, + dim925JoeKuoD6Init, + dim926JoeKuoD6Init, + dim927JoeKuoD6Init, + dim928JoeKuoD6Init, + dim929JoeKuoD6Init, + dim930JoeKuoD6Init, + dim931JoeKuoD6Init, + dim932JoeKuoD6Init, + dim933JoeKuoD6Init, + dim934JoeKuoD6Init, + dim935JoeKuoD6Init, + dim936JoeKuoD6Init, + dim937JoeKuoD6Init, + dim938JoeKuoD6Init, + dim939JoeKuoD6Init, + dim940JoeKuoD6Init, + dim941JoeKuoD6Init, + dim942JoeKuoD6Init, + dim943JoeKuoD6Init, + dim944JoeKuoD6Init, + dim945JoeKuoD6Init, + dim946JoeKuoD6Init, + dim947JoeKuoD6Init, + dim948JoeKuoD6Init, + dim949JoeKuoD6Init, + dim950JoeKuoD6Init, + dim951JoeKuoD6Init, + dim952JoeKuoD6Init, + dim953JoeKuoD6Init, + dim954JoeKuoD6Init, + dim955JoeKuoD6Init, + dim956JoeKuoD6Init, + dim957JoeKuoD6Init, + dim958JoeKuoD6Init, + dim959JoeKuoD6Init, + dim960JoeKuoD6Init, + dim961JoeKuoD6Init, + dim962JoeKuoD6Init, + dim963JoeKuoD6Init, + dim964JoeKuoD6Init, + dim965JoeKuoD6Init, + dim966JoeKuoD6Init, + dim967JoeKuoD6Init, + dim968JoeKuoD6Init, + dim969JoeKuoD6Init, + dim970JoeKuoD6Init, + dim971JoeKuoD6Init, + dim972JoeKuoD6Init, + dim973JoeKuoD6Init, + dim974JoeKuoD6Init, + dim975JoeKuoD6Init, + dim976JoeKuoD6Init, + dim977JoeKuoD6Init, + dim978JoeKuoD6Init, + dim979JoeKuoD6Init, + dim980JoeKuoD6Init, + dim981JoeKuoD6Init, + dim982JoeKuoD6Init, + dim983JoeKuoD6Init, + dim984JoeKuoD6Init, + dim985JoeKuoD6Init, + dim986JoeKuoD6Init, + dim987JoeKuoD6Init, + dim988JoeKuoD6Init, + dim989JoeKuoD6Init, + dim990JoeKuoD6Init, + dim991JoeKuoD6Init, + dim992JoeKuoD6Init, + dim993JoeKuoD6Init, + dim994JoeKuoD6Init, + dim995JoeKuoD6Init, + dim996JoeKuoD6Init, + dim997JoeKuoD6Init, + dim998JoeKuoD6Init, + dim999JoeKuoD6Init, + dim1000JoeKuoD6Init, + dim1001JoeKuoD6Init, + dim1002JoeKuoD6Init, + dim1003JoeKuoD6Init, + dim1004JoeKuoD6Init, + dim1005JoeKuoD6Init, + dim1006JoeKuoD6Init, + dim1007JoeKuoD6Init, + dim1008JoeKuoD6Init, + dim1009JoeKuoD6Init, + dim1010JoeKuoD6Init, + dim1011JoeKuoD6Init, + dim1012JoeKuoD6Init, + dim1013JoeKuoD6Init, + dim1014JoeKuoD6Init, + dim1015JoeKuoD6Init, + dim1016JoeKuoD6Init, + dim1017JoeKuoD6Init, + dim1018JoeKuoD6Init, + dim1019JoeKuoD6Init, + dim1020JoeKuoD6Init, + dim1021JoeKuoD6Init, + dim1022JoeKuoD6Init, + dim1023JoeKuoD6Init, + dim1024JoeKuoD6Init, + dim1025JoeKuoD6Init, + dim1026JoeKuoD6Init, + dim1027JoeKuoD6Init, + dim1028JoeKuoD6Init, + dim1029JoeKuoD6Init, + dim1030JoeKuoD6Init, + dim1031JoeKuoD6Init, + dim1032JoeKuoD6Init, + dim1033JoeKuoD6Init, + dim1034JoeKuoD6Init, + dim1035JoeKuoD6Init, + dim1036JoeKuoD6Init, + dim1037JoeKuoD6Init, + dim1038JoeKuoD6Init, + dim1039JoeKuoD6Init, + dim1040JoeKuoD6Init, + dim1041JoeKuoD6Init, + dim1042JoeKuoD6Init, + dim1043JoeKuoD6Init, + dim1044JoeKuoD6Init, + dim1045JoeKuoD6Init, + dim1046JoeKuoD6Init, + dim1047JoeKuoD6Init, + dim1048JoeKuoD6Init, + dim1049JoeKuoD6Init, + dim1050JoeKuoD6Init, + dim1051JoeKuoD6Init, + dim1052JoeKuoD6Init, + dim1053JoeKuoD6Init, + dim1054JoeKuoD6Init, + dim1055JoeKuoD6Init, + dim1056JoeKuoD6Init, + dim1057JoeKuoD6Init, + dim1058JoeKuoD6Init, + dim1059JoeKuoD6Init, + dim1060JoeKuoD6Init, + dim1061JoeKuoD6Init, + dim1062JoeKuoD6Init, + dim1063JoeKuoD6Init, + dim1064JoeKuoD6Init, + dim1065JoeKuoD6Init, + dim1066JoeKuoD6Init, + dim1067JoeKuoD6Init, + dim1068JoeKuoD6Init, + dim1069JoeKuoD6Init, + dim1070JoeKuoD6Init, + dim1071JoeKuoD6Init, + dim1072JoeKuoD6Init, + dim1073JoeKuoD6Init, + dim1074JoeKuoD6Init, + dim1075JoeKuoD6Init, + dim1076JoeKuoD6Init, + dim1077JoeKuoD6Init, + dim1078JoeKuoD6Init, + dim1079JoeKuoD6Init, + dim1080JoeKuoD6Init, + dim1081JoeKuoD6Init, + dim1082JoeKuoD6Init, + dim1083JoeKuoD6Init, + dim1084JoeKuoD6Init, + dim1085JoeKuoD6Init, + dim1086JoeKuoD6Init, + dim1087JoeKuoD6Init, + dim1088JoeKuoD6Init, + dim1089JoeKuoD6Init, + dim1090JoeKuoD6Init, + dim1091JoeKuoD6Init, + dim1092JoeKuoD6Init, + dim1093JoeKuoD6Init, + dim1094JoeKuoD6Init, + dim1095JoeKuoD6Init, + dim1096JoeKuoD6Init, + dim1097JoeKuoD6Init, + dim1098JoeKuoD6Init, + dim1099JoeKuoD6Init, + dim1100JoeKuoD6Init, + dim1101JoeKuoD6Init, + dim1102JoeKuoD6Init, + dim1103JoeKuoD6Init, + dim1104JoeKuoD6Init, + dim1105JoeKuoD6Init, + dim1106JoeKuoD6Init, + dim1107JoeKuoD6Init, + dim1108JoeKuoD6Init, + dim1109JoeKuoD6Init, + dim1110JoeKuoD6Init, + dim1111JoeKuoD6Init, + dim1112JoeKuoD6Init, + dim1113JoeKuoD6Init, + dim1114JoeKuoD6Init, + dim1115JoeKuoD6Init, + dim1116JoeKuoD6Init, + dim1117JoeKuoD6Init, + dim1118JoeKuoD6Init, + dim1119JoeKuoD6Init, + dim1120JoeKuoD6Init, + dim1121JoeKuoD6Init, + dim1122JoeKuoD6Init, + dim1123JoeKuoD6Init, + dim1124JoeKuoD6Init, + dim1125JoeKuoD6Init, + dim1126JoeKuoD6Init, + dim1127JoeKuoD6Init, + dim1128JoeKuoD6Init, + dim1129JoeKuoD6Init, + dim1130JoeKuoD6Init, + dim1131JoeKuoD6Init, + dim1132JoeKuoD6Init, + dim1133JoeKuoD6Init, + dim1134JoeKuoD6Init, + dim1135JoeKuoD6Init, + dim1136JoeKuoD6Init, + dim1137JoeKuoD6Init, + dim1138JoeKuoD6Init, + dim1139JoeKuoD6Init, + dim1140JoeKuoD6Init, + dim1141JoeKuoD6Init, + dim1142JoeKuoD6Init, + dim1143JoeKuoD6Init, + dim1144JoeKuoD6Init, + dim1145JoeKuoD6Init, + dim1146JoeKuoD6Init, + dim1147JoeKuoD6Init, + dim1148JoeKuoD6Init, + dim1149JoeKuoD6Init, + dim1150JoeKuoD6Init, + dim1151JoeKuoD6Init, + dim1152JoeKuoD6Init, + dim1153JoeKuoD6Init, + dim1154JoeKuoD6Init, + dim1155JoeKuoD6Init, + dim1156JoeKuoD6Init, + dim1157JoeKuoD6Init, + dim1158JoeKuoD6Init, + dim1159JoeKuoD6Init, + dim1160JoeKuoD6Init, + dim1161JoeKuoD6Init, + dim1162JoeKuoD6Init, + dim1163JoeKuoD6Init, + dim1164JoeKuoD6Init, + dim1165JoeKuoD6Init, + dim1166JoeKuoD6Init, + dim1167JoeKuoD6Init, + dim1168JoeKuoD6Init, + dim1169JoeKuoD6Init, + dim1170JoeKuoD6Init, + dim1171JoeKuoD6Init, + dim1172JoeKuoD6Init, + dim1173JoeKuoD6Init, + dim1174JoeKuoD6Init, + dim1175JoeKuoD6Init, + dim1176JoeKuoD6Init, + dim1177JoeKuoD6Init, + dim1178JoeKuoD6Init, + dim1179JoeKuoD6Init, + dim1180JoeKuoD6Init, + dim1181JoeKuoD6Init, + dim1182JoeKuoD6Init, + dim1183JoeKuoD6Init, + dim1184JoeKuoD6Init, + dim1185JoeKuoD6Init, + dim1186JoeKuoD6Init, + dim1187JoeKuoD6Init, + dim1188JoeKuoD6Init, + dim1189JoeKuoD6Init, + dim1190JoeKuoD6Init, + dim1191JoeKuoD6Init, + dim1192JoeKuoD6Init, + dim1193JoeKuoD6Init, + dim1194JoeKuoD6Init, + dim1195JoeKuoD6Init, + dim1196JoeKuoD6Init, + dim1197JoeKuoD6Init, + dim1198JoeKuoD6Init, + dim1199JoeKuoD6Init, + dim1200JoeKuoD6Init, + dim1201JoeKuoD6Init, + dim1202JoeKuoD6Init, + dim1203JoeKuoD6Init, + dim1204JoeKuoD6Init, + dim1205JoeKuoD6Init, + dim1206JoeKuoD6Init, + dim1207JoeKuoD6Init, + dim1208JoeKuoD6Init, + dim1209JoeKuoD6Init, + dim1210JoeKuoD6Init, + dim1211JoeKuoD6Init, + dim1212JoeKuoD6Init, + dim1213JoeKuoD6Init, + dim1214JoeKuoD6Init, + dim1215JoeKuoD6Init, + dim1216JoeKuoD6Init, + dim1217JoeKuoD6Init, + dim1218JoeKuoD6Init, + dim1219JoeKuoD6Init, + dim1220JoeKuoD6Init, + dim1221JoeKuoD6Init, + dim1222JoeKuoD6Init, + dim1223JoeKuoD6Init, + dim1224JoeKuoD6Init, + dim1225JoeKuoD6Init, + dim1226JoeKuoD6Init, + dim1227JoeKuoD6Init, + dim1228JoeKuoD6Init, + dim1229JoeKuoD6Init, + dim1230JoeKuoD6Init, + dim1231JoeKuoD6Init, + dim1232JoeKuoD6Init, + dim1233JoeKuoD6Init, + dim1234JoeKuoD6Init, + dim1235JoeKuoD6Init, + dim1236JoeKuoD6Init, + dim1237JoeKuoD6Init, + dim1238JoeKuoD6Init, + dim1239JoeKuoD6Init, + dim1240JoeKuoD6Init, + dim1241JoeKuoD6Init, + dim1242JoeKuoD6Init, + dim1243JoeKuoD6Init, + dim1244JoeKuoD6Init, + dim1245JoeKuoD6Init, + dim1246JoeKuoD6Init, + dim1247JoeKuoD6Init, + dim1248JoeKuoD6Init, + dim1249JoeKuoD6Init, + dim1250JoeKuoD6Init, + dim1251JoeKuoD6Init, + dim1252JoeKuoD6Init, + dim1253JoeKuoD6Init, + dim1254JoeKuoD6Init, + dim1255JoeKuoD6Init, + dim1256JoeKuoD6Init, + dim1257JoeKuoD6Init, + dim1258JoeKuoD6Init, + dim1259JoeKuoD6Init, + dim1260JoeKuoD6Init, + dim1261JoeKuoD6Init, + dim1262JoeKuoD6Init, + dim1263JoeKuoD6Init, + dim1264JoeKuoD6Init, + dim1265JoeKuoD6Init, + dim1266JoeKuoD6Init, + dim1267JoeKuoD6Init, + dim1268JoeKuoD6Init, + dim1269JoeKuoD6Init, + dim1270JoeKuoD6Init, + dim1271JoeKuoD6Init, + dim1272JoeKuoD6Init, + dim1273JoeKuoD6Init, + dim1274JoeKuoD6Init, + dim1275JoeKuoD6Init, + dim1276JoeKuoD6Init, + dim1277JoeKuoD6Init, + dim1278JoeKuoD6Init, + dim1279JoeKuoD6Init, + dim1280JoeKuoD6Init, + dim1281JoeKuoD6Init, + dim1282JoeKuoD6Init, + dim1283JoeKuoD6Init, + dim1284JoeKuoD6Init, + dim1285JoeKuoD6Init, + dim1286JoeKuoD6Init, + dim1287JoeKuoD6Init, + dim1288JoeKuoD6Init, + dim1289JoeKuoD6Init, + dim1290JoeKuoD6Init, + dim1291JoeKuoD6Init, + dim1292JoeKuoD6Init, + dim1293JoeKuoD6Init, + dim1294JoeKuoD6Init, + dim1295JoeKuoD6Init, + dim1296JoeKuoD6Init, + dim1297JoeKuoD6Init, + dim1298JoeKuoD6Init, + dim1299JoeKuoD6Init, + dim1300JoeKuoD6Init, + dim1301JoeKuoD6Init, + dim1302JoeKuoD6Init, + dim1303JoeKuoD6Init, + dim1304JoeKuoD6Init, + dim1305JoeKuoD6Init, + dim1306JoeKuoD6Init, + dim1307JoeKuoD6Init, + dim1308JoeKuoD6Init, + dim1309JoeKuoD6Init, + dim1310JoeKuoD6Init, + dim1311JoeKuoD6Init, + dim1312JoeKuoD6Init, + dim1313JoeKuoD6Init, + dim1314JoeKuoD6Init, + dim1315JoeKuoD6Init, + dim1316JoeKuoD6Init, + dim1317JoeKuoD6Init, + dim1318JoeKuoD6Init, + dim1319JoeKuoD6Init, + dim1320JoeKuoD6Init, + dim1321JoeKuoD6Init, + dim1322JoeKuoD6Init, + dim1323JoeKuoD6Init, + dim1324JoeKuoD6Init, + dim1325JoeKuoD6Init, + dim1326JoeKuoD6Init, + dim1327JoeKuoD6Init, + dim1328JoeKuoD6Init, + dim1329JoeKuoD6Init, + dim1330JoeKuoD6Init, + dim1331JoeKuoD6Init, + dim1332JoeKuoD6Init, + dim1333JoeKuoD6Init, + dim1334JoeKuoD6Init, + dim1335JoeKuoD6Init, + dim1336JoeKuoD6Init, + dim1337JoeKuoD6Init, + dim1338JoeKuoD6Init, + dim1339JoeKuoD6Init, + dim1340JoeKuoD6Init, + dim1341JoeKuoD6Init, + dim1342JoeKuoD6Init, + dim1343JoeKuoD6Init, + dim1344JoeKuoD6Init, + dim1345JoeKuoD6Init, + dim1346JoeKuoD6Init, + dim1347JoeKuoD6Init, + dim1348JoeKuoD6Init, + dim1349JoeKuoD6Init, + dim1350JoeKuoD6Init, + dim1351JoeKuoD6Init, + dim1352JoeKuoD6Init, + dim1353JoeKuoD6Init, + dim1354JoeKuoD6Init, + dim1355JoeKuoD6Init, + dim1356JoeKuoD6Init, + dim1357JoeKuoD6Init, + dim1358JoeKuoD6Init, + dim1359JoeKuoD6Init, + dim1360JoeKuoD6Init, + dim1361JoeKuoD6Init, + dim1362JoeKuoD6Init, + dim1363JoeKuoD6Init, + dim1364JoeKuoD6Init, + dim1365JoeKuoD6Init, + dim1366JoeKuoD6Init, + dim1367JoeKuoD6Init, + dim1368JoeKuoD6Init, + dim1369JoeKuoD6Init, + dim1370JoeKuoD6Init, + dim1371JoeKuoD6Init, + dim1372JoeKuoD6Init, + dim1373JoeKuoD6Init, + dim1374JoeKuoD6Init, + dim1375JoeKuoD6Init, + dim1376JoeKuoD6Init, + dim1377JoeKuoD6Init, + dim1378JoeKuoD6Init, + dim1379JoeKuoD6Init, + dim1380JoeKuoD6Init, + dim1381JoeKuoD6Init, + dim1382JoeKuoD6Init, + dim1383JoeKuoD6Init, + dim1384JoeKuoD6Init, + dim1385JoeKuoD6Init, + dim1386JoeKuoD6Init, + dim1387JoeKuoD6Init, + dim1388JoeKuoD6Init, + dim1389JoeKuoD6Init, + dim1390JoeKuoD6Init, + dim1391JoeKuoD6Init, + dim1392JoeKuoD6Init, + dim1393JoeKuoD6Init, + dim1394JoeKuoD6Init, + dim1395JoeKuoD6Init, + dim1396JoeKuoD6Init, + dim1397JoeKuoD6Init, + dim1398JoeKuoD6Init, + dim1399JoeKuoD6Init, + dim1400JoeKuoD6Init, + dim1401JoeKuoD6Init, + dim1402JoeKuoD6Init, + dim1403JoeKuoD6Init, + dim1404JoeKuoD6Init, + dim1405JoeKuoD6Init, + dim1406JoeKuoD6Init, + dim1407JoeKuoD6Init, + dim1408JoeKuoD6Init, + dim1409JoeKuoD6Init, + dim1410JoeKuoD6Init, + dim1411JoeKuoD6Init, + dim1412JoeKuoD6Init, + dim1413JoeKuoD6Init, + dim1414JoeKuoD6Init, + dim1415JoeKuoD6Init, + dim1416JoeKuoD6Init, + dim1417JoeKuoD6Init, + dim1418JoeKuoD6Init, + dim1419JoeKuoD6Init, + dim1420JoeKuoD6Init, + dim1421JoeKuoD6Init, + dim1422JoeKuoD6Init, + dim1423JoeKuoD6Init, + dim1424JoeKuoD6Init, + dim1425JoeKuoD6Init, + dim1426JoeKuoD6Init, + dim1427JoeKuoD6Init, + dim1428JoeKuoD6Init, + dim1429JoeKuoD6Init, + dim1430JoeKuoD6Init, + dim1431JoeKuoD6Init, + dim1432JoeKuoD6Init, + dim1433JoeKuoD6Init, + dim1434JoeKuoD6Init, + dim1435JoeKuoD6Init, + dim1436JoeKuoD6Init, + dim1437JoeKuoD6Init, + dim1438JoeKuoD6Init, + dim1439JoeKuoD6Init, + dim1440JoeKuoD6Init, + dim1441JoeKuoD6Init, + dim1442JoeKuoD6Init, + dim1443JoeKuoD6Init, + dim1444JoeKuoD6Init, + dim1445JoeKuoD6Init, + dim1446JoeKuoD6Init, + dim1447JoeKuoD6Init, + dim1448JoeKuoD6Init, + dim1449JoeKuoD6Init, + dim1450JoeKuoD6Init, + dim1451JoeKuoD6Init, + dim1452JoeKuoD6Init, + dim1453JoeKuoD6Init, + dim1454JoeKuoD6Init, + dim1455JoeKuoD6Init, + dim1456JoeKuoD6Init, + dim1457JoeKuoD6Init, + dim1458JoeKuoD6Init, + dim1459JoeKuoD6Init, + dim1460JoeKuoD6Init, + dim1461JoeKuoD6Init, + dim1462JoeKuoD6Init, + dim1463JoeKuoD6Init, + dim1464JoeKuoD6Init, + dim1465JoeKuoD6Init, + dim1466JoeKuoD6Init, + dim1467JoeKuoD6Init, + dim1468JoeKuoD6Init, + dim1469JoeKuoD6Init, + dim1470JoeKuoD6Init, + dim1471JoeKuoD6Init, + dim1472JoeKuoD6Init, + dim1473JoeKuoD6Init, + dim1474JoeKuoD6Init, + dim1475JoeKuoD6Init, + dim1476JoeKuoD6Init, + dim1477JoeKuoD6Init, + dim1478JoeKuoD6Init, + dim1479JoeKuoD6Init, + dim1480JoeKuoD6Init, + dim1481JoeKuoD6Init, + dim1482JoeKuoD6Init, + dim1483JoeKuoD6Init, + dim1484JoeKuoD6Init, + dim1485JoeKuoD6Init, + dim1486JoeKuoD6Init, + dim1487JoeKuoD6Init, + dim1488JoeKuoD6Init, + dim1489JoeKuoD6Init, + dim1490JoeKuoD6Init, + dim1491JoeKuoD6Init, + dim1492JoeKuoD6Init, + dim1493JoeKuoD6Init, + dim1494JoeKuoD6Init, + dim1495JoeKuoD6Init, + dim1496JoeKuoD6Init, + dim1497JoeKuoD6Init, + dim1498JoeKuoD6Init, + dim1499JoeKuoD6Init, + dim1500JoeKuoD6Init, + dim1501JoeKuoD6Init, + dim1502JoeKuoD6Init, + dim1503JoeKuoD6Init, + dim1504JoeKuoD6Init, + dim1505JoeKuoD6Init, + dim1506JoeKuoD6Init, + dim1507JoeKuoD6Init, + dim1508JoeKuoD6Init, + dim1509JoeKuoD6Init, + dim1510JoeKuoD6Init, + dim1511JoeKuoD6Init, + dim1512JoeKuoD6Init, + dim1513JoeKuoD6Init, + dim1514JoeKuoD6Init, + dim1515JoeKuoD6Init, + dim1516JoeKuoD6Init, + dim1517JoeKuoD6Init, + dim1518JoeKuoD6Init, + dim1519JoeKuoD6Init, + dim1520JoeKuoD6Init, + dim1521JoeKuoD6Init, + dim1522JoeKuoD6Init, + dim1523JoeKuoD6Init, + dim1524JoeKuoD6Init, + dim1525JoeKuoD6Init, + dim1526JoeKuoD6Init, + dim1527JoeKuoD6Init, + dim1528JoeKuoD6Init, + dim1529JoeKuoD6Init, + dim1530JoeKuoD6Init, + dim1531JoeKuoD6Init, + dim1532JoeKuoD6Init, + dim1533JoeKuoD6Init, + dim1534JoeKuoD6Init, + dim1535JoeKuoD6Init, + dim1536JoeKuoD6Init, + dim1537JoeKuoD6Init, + dim1538JoeKuoD6Init, + dim1539JoeKuoD6Init, + dim1540JoeKuoD6Init, + dim1541JoeKuoD6Init, + dim1542JoeKuoD6Init, + dim1543JoeKuoD6Init, + dim1544JoeKuoD6Init, + dim1545JoeKuoD6Init, + dim1546JoeKuoD6Init, + dim1547JoeKuoD6Init, + dim1548JoeKuoD6Init, + dim1549JoeKuoD6Init, + dim1550JoeKuoD6Init, + dim1551JoeKuoD6Init, + dim1552JoeKuoD6Init, + dim1553JoeKuoD6Init, + dim1554JoeKuoD6Init, + dim1555JoeKuoD6Init, + dim1556JoeKuoD6Init, + dim1557JoeKuoD6Init, + dim1558JoeKuoD6Init, + dim1559JoeKuoD6Init, + dim1560JoeKuoD6Init, + dim1561JoeKuoD6Init, + dim1562JoeKuoD6Init, + dim1563JoeKuoD6Init, + dim1564JoeKuoD6Init, + dim1565JoeKuoD6Init, + dim1566JoeKuoD6Init, + dim1567JoeKuoD6Init, + dim1568JoeKuoD6Init, + dim1569JoeKuoD6Init, + dim1570JoeKuoD6Init, + dim1571JoeKuoD6Init, + dim1572JoeKuoD6Init, + dim1573JoeKuoD6Init, + dim1574JoeKuoD6Init, + dim1575JoeKuoD6Init, + dim1576JoeKuoD6Init, + dim1577JoeKuoD6Init, + dim1578JoeKuoD6Init, + dim1579JoeKuoD6Init, + dim1580JoeKuoD6Init, + dim1581JoeKuoD6Init, + dim1582JoeKuoD6Init, + dim1583JoeKuoD6Init, + dim1584JoeKuoD6Init, + dim1585JoeKuoD6Init, + dim1586JoeKuoD6Init, + dim1587JoeKuoD6Init, + dim1588JoeKuoD6Init, + dim1589JoeKuoD6Init, + dim1590JoeKuoD6Init, + dim1591JoeKuoD6Init, + dim1592JoeKuoD6Init, + dim1593JoeKuoD6Init, + dim1594JoeKuoD6Init, + dim1595JoeKuoD6Init, + dim1596JoeKuoD6Init, + dim1597JoeKuoD6Init, + dim1598JoeKuoD6Init, + dim1599JoeKuoD6Init, + dim1600JoeKuoD6Init, + dim1601JoeKuoD6Init, + dim1602JoeKuoD6Init, + dim1603JoeKuoD6Init, + dim1604JoeKuoD6Init, + dim1605JoeKuoD6Init, + dim1606JoeKuoD6Init, + dim1607JoeKuoD6Init, + dim1608JoeKuoD6Init, + dim1609JoeKuoD6Init, + dim1610JoeKuoD6Init, + dim1611JoeKuoD6Init, + dim1612JoeKuoD6Init, + dim1613JoeKuoD6Init, + dim1614JoeKuoD6Init, + dim1615JoeKuoD6Init, + dim1616JoeKuoD6Init, + dim1617JoeKuoD6Init, + dim1618JoeKuoD6Init, + dim1619JoeKuoD6Init, + dim1620JoeKuoD6Init, + dim1621JoeKuoD6Init, + dim1622JoeKuoD6Init, + dim1623JoeKuoD6Init, + dim1624JoeKuoD6Init, + dim1625JoeKuoD6Init, + dim1626JoeKuoD6Init, + dim1627JoeKuoD6Init, + dim1628JoeKuoD6Init, + dim1629JoeKuoD6Init, + dim1630JoeKuoD6Init, + dim1631JoeKuoD6Init, + dim1632JoeKuoD6Init, + dim1633JoeKuoD6Init, + dim1634JoeKuoD6Init, + dim1635JoeKuoD6Init, + dim1636JoeKuoD6Init, + dim1637JoeKuoD6Init, + dim1638JoeKuoD6Init, + dim1639JoeKuoD6Init, + dim1640JoeKuoD6Init, + dim1641JoeKuoD6Init, + dim1642JoeKuoD6Init, + dim1643JoeKuoD6Init, + dim1644JoeKuoD6Init, + dim1645JoeKuoD6Init, + dim1646JoeKuoD6Init, + dim1647JoeKuoD6Init, + dim1648JoeKuoD6Init, + dim1649JoeKuoD6Init, + dim1650JoeKuoD6Init, + dim1651JoeKuoD6Init, + dim1652JoeKuoD6Init, + dim1653JoeKuoD6Init, + dim1654JoeKuoD6Init, + dim1655JoeKuoD6Init, + dim1656JoeKuoD6Init, + dim1657JoeKuoD6Init, + dim1658JoeKuoD6Init, + dim1659JoeKuoD6Init, + dim1660JoeKuoD6Init, + dim1661JoeKuoD6Init, + dim1662JoeKuoD6Init, + dim1663JoeKuoD6Init, + dim1664JoeKuoD6Init, + dim1665JoeKuoD6Init, + dim1666JoeKuoD6Init, + dim1667JoeKuoD6Init, + dim1668JoeKuoD6Init, + dim1669JoeKuoD6Init, + dim1670JoeKuoD6Init, + dim1671JoeKuoD6Init, + dim1672JoeKuoD6Init, + dim1673JoeKuoD6Init, + dim1674JoeKuoD6Init, + dim1675JoeKuoD6Init, + dim1676JoeKuoD6Init, + dim1677JoeKuoD6Init, + dim1678JoeKuoD6Init, + dim1679JoeKuoD6Init, + dim1680JoeKuoD6Init, + dim1681JoeKuoD6Init, + dim1682JoeKuoD6Init, + dim1683JoeKuoD6Init, + dim1684JoeKuoD6Init, + dim1685JoeKuoD6Init, + dim1686JoeKuoD6Init, + dim1687JoeKuoD6Init, + dim1688JoeKuoD6Init, + dim1689JoeKuoD6Init, + dim1690JoeKuoD6Init, + dim1691JoeKuoD6Init, + dim1692JoeKuoD6Init, + dim1693JoeKuoD6Init, + dim1694JoeKuoD6Init, + dim1695JoeKuoD6Init, + dim1696JoeKuoD6Init, + dim1697JoeKuoD6Init, + dim1698JoeKuoD6Init, + dim1699JoeKuoD6Init, + dim1700JoeKuoD6Init, + dim1701JoeKuoD6Init, + dim1702JoeKuoD6Init, + dim1703JoeKuoD6Init, + dim1704JoeKuoD6Init, + dim1705JoeKuoD6Init, + dim1706JoeKuoD6Init, + dim1707JoeKuoD6Init, + dim1708JoeKuoD6Init, + dim1709JoeKuoD6Init, + dim1710JoeKuoD6Init, + dim1711JoeKuoD6Init, + dim1712JoeKuoD6Init, + dim1713JoeKuoD6Init, + dim1714JoeKuoD6Init, + dim1715JoeKuoD6Init, + dim1716JoeKuoD6Init, + dim1717JoeKuoD6Init, + dim1718JoeKuoD6Init, + dim1719JoeKuoD6Init, + dim1720JoeKuoD6Init, + dim1721JoeKuoD6Init, + dim1722JoeKuoD6Init, + dim1723JoeKuoD6Init, + dim1724JoeKuoD6Init, + dim1725JoeKuoD6Init, + dim1726JoeKuoD6Init, + dim1727JoeKuoD6Init, + dim1728JoeKuoD6Init, + dim1729JoeKuoD6Init, + dim1730JoeKuoD6Init, + dim1731JoeKuoD6Init, + dim1732JoeKuoD6Init, + dim1733JoeKuoD6Init, + dim1734JoeKuoD6Init, + dim1735JoeKuoD6Init, + dim1736JoeKuoD6Init, + dim1737JoeKuoD6Init, + dim1738JoeKuoD6Init, + dim1739JoeKuoD6Init, + dim1740JoeKuoD6Init, + dim1741JoeKuoD6Init, + dim1742JoeKuoD6Init, + dim1743JoeKuoD6Init, + dim1744JoeKuoD6Init, + dim1745JoeKuoD6Init, + dim1746JoeKuoD6Init, + dim1747JoeKuoD6Init, + dim1748JoeKuoD6Init, + dim1749JoeKuoD6Init, + dim1750JoeKuoD6Init, + dim1751JoeKuoD6Init, + dim1752JoeKuoD6Init, + dim1753JoeKuoD6Init, + dim1754JoeKuoD6Init, + dim1755JoeKuoD6Init, + dim1756JoeKuoD6Init, + dim1757JoeKuoD6Init, + dim1758JoeKuoD6Init, + dim1759JoeKuoD6Init, + dim1760JoeKuoD6Init, + dim1761JoeKuoD6Init, + dim1762JoeKuoD6Init, + dim1763JoeKuoD6Init, + dim1764JoeKuoD6Init, + dim1765JoeKuoD6Init, + dim1766JoeKuoD6Init, + dim1767JoeKuoD6Init, + dim1768JoeKuoD6Init, + dim1769JoeKuoD6Init, + dim1770JoeKuoD6Init, + dim1771JoeKuoD6Init, + dim1772JoeKuoD6Init, + dim1773JoeKuoD6Init, + dim1774JoeKuoD6Init, + dim1775JoeKuoD6Init, + dim1776JoeKuoD6Init, + dim1777JoeKuoD6Init, + dim1778JoeKuoD6Init, + dim1779JoeKuoD6Init, + dim1780JoeKuoD6Init, + dim1781JoeKuoD6Init, + dim1782JoeKuoD6Init, + dim1783JoeKuoD6Init, + dim1784JoeKuoD6Init, + dim1785JoeKuoD6Init, + dim1786JoeKuoD6Init, + dim1787JoeKuoD6Init, + dim1788JoeKuoD6Init, + dim1789JoeKuoD6Init, + dim1790JoeKuoD6Init, + dim1791JoeKuoD6Init, + dim1792JoeKuoD6Init, + dim1793JoeKuoD6Init, + dim1794JoeKuoD6Init, + dim1795JoeKuoD6Init, + dim1796JoeKuoD6Init, + dim1797JoeKuoD6Init, + dim1798JoeKuoD6Init, + dim1799JoeKuoD6Init + }; + + static ulong[] dim1JoeKuoD7Init = { 1, 0 }; + static ulong[] dim2JoeKuoD7Init = { 1, 3, 0 }; + static ulong[] dim3JoeKuoD7Init = { 1, 3, 1, 0 }; + static ulong[] dim4JoeKuoD7Init = { 1, 1, 1, 0 }; + static ulong[] dim5JoeKuoD7Init = { 1, 1, 3, 3, 0 }; + static ulong[] dim6JoeKuoD7Init = { 1, 3, 5, 13, 0 }; + static ulong[] dim7JoeKuoD7Init = { 1, 1, 5, 5, 17, 0 }; + static ulong[] dim8JoeKuoD7Init = { 1, 1, 5, 5, 5, 0 }; + static ulong[] dim9JoeKuoD7Init = { 1, 1, 7, 11, 19, 0 }; + static ulong[] dim10JoeKuoD7Init = { 1, 1, 5, 1, 1, 0 }; + static ulong[] dim11JoeKuoD7Init = { 1, 1, 1, 3, 11, 0 }; + static ulong[] dim12JoeKuoD7Init = { 1, 3, 5, 5, 31, 0 }; + static ulong[] dim13JoeKuoD7Init = { 1, 3, 3, 9, 7, 49, 0 }; + static ulong[] dim14JoeKuoD7Init = { 1, 1, 1, 15, 23, 17, 0 }; + static ulong[] dim15JoeKuoD7Init = { 1, 3, 1, 13, 27, 49, 0 }; + static ulong[] dim16JoeKuoD7Init = { 1, 1, 1, 15, 7, 5, 0 }; + static ulong[] dim17JoeKuoD7Init = { 1, 3, 7, 7, 19, 13, 0 }; + static ulong[] dim18JoeKuoD7Init = { 1, 1, 5, 5, 19, 59, 0 }; + static ulong[] dim19JoeKuoD7Init = { 1, 3, 7, 11, 23, 7, 121, 0 }; + static ulong[] dim20JoeKuoD7Init = { 1, 3, 5, 13, 9, 19, 113, 0 }; + static ulong[] dim21JoeKuoD7Init = { 1, 1, 7, 15, 3, 53, 87, 0 }; + static ulong[] dim22JoeKuoD7Init = { 1, 3, 7, 7, 25, 33, 41, 0 }; + static ulong[] dim23JoeKuoD7Init = { 1, 3, 1, 9, 15, 47, 85, 0 }; + static ulong[] dim24JoeKuoD7Init = { 1, 1, 7, 3, 5, 25, 37, 0 }; + static ulong[] dim25JoeKuoD7Init = { 1, 3, 7, 9, 31, 11, 27, 0 }; + static ulong[] dim26JoeKuoD7Init = { 1, 1, 7, 15, 1, 17, 121, 0 }; + static ulong[] dim27JoeKuoD7Init = { 1, 3, 7, 13, 17, 49, 5, 0 }; + static ulong[] dim28JoeKuoD7Init = { 1, 3, 5, 9, 7, 9, 31, 0 }; + static ulong[] dim29JoeKuoD7Init = { 1, 3, 1, 9, 7, 29, 15, 0 }; + static ulong[] dim30JoeKuoD7Init = { 1, 3, 1, 1, 23, 43, 37, 0 }; + static ulong[] dim31JoeKuoD7Init = { 1, 3, 7, 5, 3, 43, 95, 0 }; + static ulong[] dim32JoeKuoD7Init = { 1, 1, 7, 9, 31, 25, 91, 0 }; + static ulong[] dim33JoeKuoD7Init = { 1, 3, 1, 11, 15, 17, 91, 0 }; + static ulong[] dim34JoeKuoD7Init = { 1, 1, 1, 1, 21, 29, 71, 0 }; + static ulong[] dim35JoeKuoD7Init = { 1, 1, 5, 13, 27, 3, 27, 0 }; + static ulong[] dim36JoeKuoD7Init = { 1, 3, 1, 9, 31, 25, 3, 0 }; + static ulong[] dim37JoeKuoD7Init = { 1, 3, 3, 1, 25, 23, 51, 45, 0 }; + static ulong[] dim38JoeKuoD7Init = { 1, 1, 5, 13, 9, 25, 17, 227, 0 }; + static ulong[] dim39JoeKuoD7Init = { 1, 1, 1, 1, 15, 9, 91, 45, 0 }; + static ulong[] dim40JoeKuoD7Init = { 1, 1, 7, 7, 9, 35, 87, 31, 0 }; + static ulong[] dim41JoeKuoD7Init = { 1, 1, 5, 13, 29, 33, 13, 119, 0 }; + static ulong[] dim42JoeKuoD7Init = { 1, 3, 5, 3, 17, 9, 73, 85, 0 }; + static ulong[] dim43JoeKuoD7Init = { 1, 3, 7, 5, 13, 33, 11, 17, 0 }; + static ulong[] dim44JoeKuoD7Init = { 1, 1, 3, 13, 29, 25, 15, 75, 0 }; + static ulong[] dim45JoeKuoD7Init = { 1, 3, 7, 9, 3, 11, 11, 59, 0 }; + static ulong[] dim46JoeKuoD7Init = { 1, 3, 1, 13, 5, 27, 19, 71, 0 }; + static ulong[] dim47JoeKuoD7Init = { 1, 1, 7, 3, 13, 41, 79, 137, 0 }; + static ulong[] dim48JoeKuoD7Init = { 1, 3, 3, 7, 9, 41, 89, 63, 0 }; + static ulong[] dim49JoeKuoD7Init = { 1, 1, 1, 5, 29, 57, 53, 103, 0 }; + static ulong[] dim50JoeKuoD7Init = { 1, 1, 3, 9, 3, 41, 71, 119, 0 }; + static ulong[] dim51JoeKuoD7Init = { 1, 3, 5, 5, 3, 1, 39, 185, 0 }; + static ulong[] dim52JoeKuoD7Init = { 1, 3, 3, 15, 23, 3, 43, 95, 0 }; + static ulong[] dim53JoeKuoD7Init = { 1, 1, 3, 7, 1, 35, 19, 19, 127, 0 }; + static ulong[] dim54JoeKuoD7Init = { 1, 1, 3, 9, 9, 31, 9, 157, 105, 0 }; + static ulong[] dim55JoeKuoD7Init = { 1, 3, 1, 1, 7, 49, 13, 125, 471, 0 }; + static ulong[] dim56JoeKuoD7Init = { 1, 3, 3, 1, 17, 25, 111, 73, 41, 0 }; + static ulong[] dim57JoeKuoD7Init = { 1, 3, 5, 11, 3, 61, 117, 93, 325, 0 }; + static ulong[] dim58JoeKuoD7Init = { 1, 1, 7, 15, 21, 63, 103, 145, 61, 0 }; + static ulong[] dim59JoeKuoD7Init = { 1, 3, 7, 7, 27, 49, 101, 227, 55, 0 }; + static ulong[] dim60JoeKuoD7Init = { 1, 1, 7, 5, 1, 1, 33, 225, 501, 0 }; + static ulong[] dim61JoeKuoD7Init = { 1, 3, 5, 5, 1, 17, 113, 149, 71, 0 }; + static ulong[] dim62JoeKuoD7Init = { 1, 1, 5, 9, 27, 9, 97, 7, 35, 0 }; + static ulong[] dim63JoeKuoD7Init = { 1, 3, 1, 7, 13, 39, 49, 213, 483, 0 }; + static ulong[] dim64JoeKuoD7Init = { 1, 3, 3, 11, 13, 47, 43, 89, 329, 0 }; + static ulong[] dim65JoeKuoD7Init = { 1, 3, 1, 1, 19, 61, 97, 205, 285, 0 }; + static ulong[] dim66JoeKuoD7Init = { 1, 1, 3, 11, 11, 3, 105, 151, 469, 0 }; + static ulong[] dim67JoeKuoD7Init = { 1, 1, 1, 1, 5, 39, 89, 137, 409, 0 }; + static ulong[] dim68JoeKuoD7Init = { 1, 1, 3, 11, 23, 39, 85, 251, 141, 0 }; + static ulong[] dim69JoeKuoD7Init = { 1, 1, 3, 5, 23, 23, 59, 111, 19, 0 }; + static ulong[] dim70JoeKuoD7Init = { 1, 3, 5, 9, 19, 63, 1, 251, 305, 0 }; + static ulong[] dim71JoeKuoD7Init = { 1, 3, 1, 1, 3, 35, 65, 153, 387, 0 }; + static ulong[] dim72JoeKuoD7Init = { 1, 1, 5, 13, 21, 45, 37, 255, 295, 0 }; + static ulong[] dim73JoeKuoD7Init = { 1, 1, 5, 1, 21, 5, 39, 143, 293, 0 }; + static ulong[] dim74JoeKuoD7Init = { 1, 1, 1, 5, 21, 45, 91, 211, 347, 0 }; + static ulong[] dim75JoeKuoD7Init = { 1, 3, 5, 11, 17, 21, 73, 185, 259, 0 }; + static ulong[] dim76JoeKuoD7Init = { 1, 3, 1, 11, 29, 25, 85, 103, 97, 0 }; + static ulong[] dim77JoeKuoD7Init = { 1, 3, 5, 5, 27, 37, 43, 243, 257, 0 }; + static ulong[] dim78JoeKuoD7Init = { 1, 3, 5, 11, 31, 63, 105, 41, 229, 0 }; + static ulong[] dim79JoeKuoD7Init = { 1, 3, 3, 15, 21, 55, 29, 39, 279, 0 }; + static ulong[] dim80JoeKuoD7Init = { 1, 3, 5, 7, 1, 47, 97, 15, 173, 0 }; + static ulong[] dim81JoeKuoD7Init = { 1, 1, 5, 7, 21, 55, 29, 93, 97, 0 }; + static ulong[] dim82JoeKuoD7Init = { 1, 3, 3, 3, 7, 29, 27, 179, 105, 0 }; + static ulong[] dim83JoeKuoD7Init = { 1, 1, 3, 3, 1, 43, 37, 221, 259, 0 }; + static ulong[] dim84JoeKuoD7Init = { 1, 1, 7, 9, 31, 25, 1, 47, 71, 0 }; + static ulong[] dim85JoeKuoD7Init = { 1, 3, 7, 7, 7, 25, 37, 1, 487, 0 }; + static ulong[] dim86JoeKuoD7Init = { 1, 3, 1, 1, 31, 43, 25, 117, 147, 0 }; + static ulong[] dim87JoeKuoD7Init = { 1, 3, 7, 3, 27, 7, 103, 241, 173, 0 }; + static ulong[] dim88JoeKuoD7Init = { 1, 1, 5, 1, 27, 25, 91, 189, 53, 0 }; + static ulong[] dim89JoeKuoD7Init = { 1, 1, 3, 3, 29, 39, 79, 125, 281, 0 }; + static ulong[] dim90JoeKuoD7Init = { 1, 1, 5, 11, 13, 57, 15, 219, 407, 0 }; + static ulong[] dim91JoeKuoD7Init = { 1, 3, 3, 5, 15, 9, 65, 111, 1, 0 }; + static ulong[] dim92JoeKuoD7Init = { 1, 1, 5, 3, 31, 45, 17, 227, 67, 0 }; + static ulong[] dim93JoeKuoD7Init = { 1, 1, 3, 1, 31, 59, 63, 205, 27, 0 }; + static ulong[] dim94JoeKuoD7Init = { 1, 1, 1, 9, 27, 9, 49, 187, 451, 0 }; + static ulong[] dim95JoeKuoD7Init = { 1, 1, 5, 15, 11, 43, 93, 49, 129, 0 }; + static ulong[] dim96JoeKuoD7Init = { 1, 3, 7, 7, 5, 63, 31, 239, 11, 0 }; + static ulong[] dim97JoeKuoD7Init = { 1, 1, 1, 11, 7, 59, 37, 157, 505, 0 }; + static ulong[] dim98JoeKuoD7Init = { 1, 3, 5, 9, 3, 41, 87, 229, 269, 0 }; + static ulong[] dim99JoeKuoD7Init = { 1, 1, 5, 3, 25, 11, 69, 125, 35, 0 }; + static ulong[] dim100JoeKuoD7Init = { 1, 3, 5, 13, 11, 53, 47, 21, 79, 0 }; + static ulong[] dim101JoeKuoD7Init = { 1, 3, 3, 7, 11, 23, 1, 99, 417, 35, 0 }; + static ulong[] dim102JoeKuoD7Init = { 1, 1, 7, 7, 7, 53, 57, 229, 473, 533, 0 }; + static ulong[] dim103JoeKuoD7Init = { 1, 1, 3, 9, 23, 31, 87, 27, 313, 853, 0 }; + static ulong[] dim104JoeKuoD7Init = { 1, 3, 3, 1, 13, 43, 27, 227, 231, 91, 0 }; + static ulong[] dim105JoeKuoD7Init = { 1, 3, 7, 5, 11, 17, 109, 29, 417, 597, 0 }; + static ulong[] dim106JoeKuoD7Init = { 1, 3, 7, 7, 31, 5, 23, 137, 35, 583, 0 }; + static ulong[] dim107JoeKuoD7Init = { 1, 3, 1, 5, 15, 23, 87, 171, 171, 889, 0 }; + static ulong[] dim108JoeKuoD7Init = { 1, 3, 3, 7, 17, 21, 19, 233, 275, 651, 0 }; + static ulong[] dim109JoeKuoD7Init = { 1, 1, 3, 5, 31, 19, 127, 115, 211, 715, 0 }; + static ulong[] dim110JoeKuoD7Init = { 1, 1, 5, 3, 13, 5, 37, 83, 123, 567, 0 }; + static ulong[] dim111JoeKuoD7Init = { 1, 3, 1, 7, 3, 41, 123, 61, 311, 45, 0 }; + static ulong[] dim112JoeKuoD7Init = { 1, 1, 5, 5, 19, 27, 1, 159, 87, 155, 0 }; + static ulong[] dim113JoeKuoD7Init = { 1, 3, 3, 15, 31, 17, 29, 105, 293, 205, 0 }; + static ulong[] dim114JoeKuoD7Init = { 1, 1, 1, 13, 15, 11, 125, 241, 1, 755, 0 }; + static ulong[] dim115JoeKuoD7Init = { 1, 1, 7, 7, 27, 47, 59, 143, 451, 1005, 0 }; + static ulong[] dim116JoeKuoD7Init = { 1, 3, 1, 11, 19, 37, 49, 105, 127, 683, 0 }; + static ulong[] dim117JoeKuoD7Init = { 1, 1, 1, 1, 11, 31, 9, 15, 355, 951, 0 }; + static ulong[] dim118JoeKuoD7Init = { 1, 1, 7, 15, 5, 19, 69, 51, 121, 695, 0 }; + static ulong[] dim119JoeKuoD7Init = { 1, 3, 1, 9, 15, 33, 125, 63, 191, 773, 0 }; + static ulong[] dim120JoeKuoD7Init = { 1, 1, 3, 1, 11, 13, 67, 123, 143, 427, 0 }; + static ulong[] dim121JoeKuoD7Init = { 1, 3, 7, 7, 17, 45, 73, 209, 501, 781, 0 }; + static ulong[] dim122JoeKuoD7Init = { 1, 1, 3, 5, 21, 25, 31, 229, 107, 447, 0 }; + static ulong[] dim123JoeKuoD7Init = { 1, 3, 3, 5, 15, 39, 19, 111, 221, 35, 0 }; + static ulong[] dim124JoeKuoD7Init = { 1, 3, 5, 7, 7, 23, 111, 201, 469, 859, 0 }; + static ulong[] dim125JoeKuoD7Init = { 1, 3, 1, 9, 7, 55, 1, 57, 245, 865, 0 }; + static ulong[] dim126JoeKuoD7Init = { 1, 1, 5, 11, 19, 17, 63, 107, 423, 977, 0 }; + static ulong[] dim127JoeKuoD7Init = { 1, 1, 3, 5, 23, 35, 59, 143, 403, 469, 0 }; + static ulong[] dim128JoeKuoD7Init = { 1, 3, 3, 9, 29, 11, 11, 137, 341, 669, 0 }; + static ulong[] dim129JoeKuoD7Init = { 1, 3, 5, 5, 31, 29, 73, 25, 21, 543, 0 }; + static ulong[] dim130JoeKuoD7Init = { 1, 1, 5, 3, 17, 47, 69, 103, 49, 869, 0 }; + static ulong[] dim131JoeKuoD7Init = { 1, 1, 3, 9, 1, 5, 69, 45, 73, 533, 0 }; + static ulong[] dim132JoeKuoD7Init = { 1, 1, 1, 11, 13, 11, 61, 71, 397, 919, 0 }; + static ulong[] dim133JoeKuoD7Init = { 1, 1, 7, 11, 1, 3, 21, 127, 263, 597, 0 }; + static ulong[] dim134JoeKuoD7Init = { 1, 3, 1, 9, 3, 31, 41, 179, 499, 313, 0 }; + static ulong[] dim135JoeKuoD7Init = { 1, 1, 7, 11, 5, 43, 33, 41, 53, 917, 0 }; + static ulong[] dim136JoeKuoD7Init = { 1, 3, 3, 9, 1, 63, 35, 139, 169, 945, 0 }; + static ulong[] dim137JoeKuoD7Init = { 1, 1, 7, 3, 31, 13, 51, 105, 333, 703, 0 }; + static ulong[] dim138JoeKuoD7Init = { 1, 1, 5, 3, 5, 5, 127, 103, 465, 989, 0 }; + static ulong[] dim139JoeKuoD7Init = { 1, 1, 3, 1, 31, 3, 87, 41, 511, 713, 0 }; + static ulong[] dim140JoeKuoD7Init = { 1, 1, 7, 1, 7, 29, 19, 237, 235, 531, 0 }; + static ulong[] dim141JoeKuoD7Init = { 1, 1, 7, 13, 21, 11, 111, 51, 461, 525, 0 }; + static ulong[] dim142JoeKuoD7Init = { 1, 3, 3, 13, 27, 49, 123, 241, 365, 137, 0 }; + static ulong[] dim143JoeKuoD7Init = { 1, 1, 7, 13, 17, 43, 43, 115, 483, 291, 0 }; + static ulong[] dim144JoeKuoD7Init = { 1, 1, 3, 7, 5, 17, 127, 167, 371, 417, 0 }; + static ulong[] dim145JoeKuoD7Init = { 1, 3, 7, 9, 11, 21, 123, 29, 133, 9, 0 }; + static ulong[] dim146JoeKuoD7Init = { 1, 3, 1, 7, 13, 35, 99, 161, 45, 347, 0 }; + static ulong[] dim147JoeKuoD7Init = { 1, 1, 1, 7, 15, 21, 31, 131, 441, 635, 0 }; + static ulong[] dim148JoeKuoD7Init = { 1, 1, 3, 7, 21, 63, 119, 175, 183, 189, 0 }; + static ulong[] dim149JoeKuoD7Init = { 1, 3, 7, 3, 17, 39, 21, 201, 31, 747, 0 }; + static ulong[] dim150JoeKuoD7Init = { 1, 1, 5, 15, 7, 23, 127, 169, 341, 975, 0 }; + static ulong[] dim151JoeKuoD7Init = { 1, 3, 3, 15, 27, 39, 67, 111, 501, 343, 0 }; + static ulong[] dim152JoeKuoD7Init = { 1, 3, 7, 15, 13, 3, 99, 145, 259, 579, 0 }; + static ulong[] dim153JoeKuoD7Init = { 1, 1, 5, 13, 27, 45, 9, 229, 139, 1015, 0 }; + static ulong[] dim154JoeKuoD7Init = { 1, 1, 3, 11, 1, 61, 35, 77, 423, 987, 0 }; + static ulong[] dim155JoeKuoD7Init = { 1, 1, 7, 11, 13, 53, 99, 165, 329, 191, 0 }; + static ulong[] dim156JoeKuoD7Init = { 1, 1, 1, 11, 13, 31, 15, 237, 359, 337, 0 }; + static ulong[] dim157JoeKuoD7Init = { 1, 3, 1, 1, 1, 15, 35, 175, 347, 485, 0 }; + static ulong[] dim158JoeKuoD7Init = { 1, 1, 5, 9, 3, 15, 63, 19, 123, 633, 0 }; + static ulong[] dim159JoeKuoD7Init = { 1, 3, 5, 3, 9, 5, 51, 123, 239, 829, 0 }; + static ulong[] dim160JoeKuoD7Init = { 1, 1, 3, 15, 27, 49, 1, 177, 433, 237, 0 }; + static ulong[] dim161JoeKuoD7Init = { 1, 3, 3, 1, 25, 1, 71, 187, 3, 455, 1559, 0 }; + static ulong[] dim162JoeKuoD7Init = { 1, 1, 1, 5, 17, 53, 71, 115, 87, 811, 1559, 0 }; + static ulong[] dim163JoeKuoD7Init = { 1, 3, 3, 9, 3, 5, 93, 233, 413, 105, 335, 0 }; + static ulong[] dim164JoeKuoD7Init = { 1, 3, 7, 5, 13, 33, 45, 45, 255, 691, 1827, 0 }; + static ulong[] dim165JoeKuoD7Init = { 1, 1, 5, 7, 3, 51, 57, 119, 355, 151, 297, 0 }; + static ulong[] dim166JoeKuoD7Init = { 1, 1, 1, 13, 17, 11, 19, 5, 369, 661, 877, 0 }; + static ulong[] dim167JoeKuoD7Init = { 1, 1, 7, 3, 3, 61, 15, 207, 161, 811, 1585, 0 }; + static ulong[] dim168JoeKuoD7Init = { 1, 3, 7, 9, 11, 63, 105, 45, 209, 605, 835, 0 }; + static ulong[] dim169JoeKuoD7Init = { 1, 1, 1, 7, 11, 47, 35, 73, 303, 809, 1813, 0 }; + static ulong[] dim170JoeKuoD7Init = { 1, 1, 1, 1, 9, 35, 69, 219, 5, 281, 1263, 0 }; + static ulong[] dim171JoeKuoD7Init = { 1, 1, 5, 1, 9, 25, 85, 159, 415, 471, 345, 0 }; + static ulong[] dim172JoeKuoD7Init = { 1, 3, 7, 11, 11, 61, 43, 109, 327, 865, 1635, 0 }; + static ulong[] dim173JoeKuoD7Init = { 1, 1, 3, 13, 21, 39, 123, 211, 355, 91, 1481, 0 }; + static ulong[] dim174JoeKuoD7Init = { 1, 3, 1, 15, 17, 39, 69, 149, 133, 779, 575, 0 }; + static ulong[] dim175JoeKuoD7Init = { 1, 3, 5, 9, 15, 49, 7, 183, 25, 823, 971, 0 }; + static ulong[] dim176JoeKuoD7Init = { 1, 3, 1, 7, 31, 63, 9, 187, 211, 473, 485, 0 }; + static ulong[] dim177JoeKuoD7Init = { 1, 3, 7, 11, 9, 1, 35, 177, 435, 307, 1493, 0 }; + static ulong[] dim178JoeKuoD7Init = { 1, 1, 7, 3, 27, 51, 91, 63, 511, 179, 251, 0 }; + static ulong[] dim179JoeKuoD7Init = { 1, 1, 5, 11, 27, 49, 125, 111, 283, 577, 397, 0 }; + static ulong[] dim180JoeKuoD7Init = { 1, 3, 7, 15, 11, 7, 19, 85, 111, 629, 435, 0 }; + static ulong[] dim181JoeKuoD7Init = { 1, 3, 3, 9, 7, 11, 127, 25, 139, 271, 263, 0 }; + static ulong[] dim182JoeKuoD7Init = { 1, 1, 1, 15, 21, 25, 55, 129, 211, 755, 1695, 0 }; + static ulong[] dim183JoeKuoD7Init = { 1, 1, 7, 15, 13, 23, 107, 241, 231, 319, 385, 0 }; + static ulong[] dim184JoeKuoD7Init = { 1, 1, 5, 11, 31, 31, 97, 141, 93, 759, 1199, 0 }; + static ulong[] dim185JoeKuoD7Init = { 1, 3, 5, 9, 25, 15, 63, 79, 321, 53, 1877, 0 }; + static ulong[] dim186JoeKuoD7Init = { 1, 1, 7, 5, 11, 59, 113, 77, 75, 453, 1617, 0 }; + static ulong[] dim187JoeKuoD7Init = { 1, 3, 1, 15, 19, 33, 65, 141, 109, 211, 213, 0 }; + static ulong[] dim188JoeKuoD7Init = { 1, 3, 3, 13, 17, 1, 123, 1, 305, 271, 1835, 0 }; + static ulong[] dim189JoeKuoD7Init = { 1, 3, 7, 7, 9, 61, 83, 75, 355, 595, 773, 0 }; + static ulong[] dim190JoeKuoD7Init = { 1, 3, 5, 13, 31, 53, 97, 193, 95, 933, 535, 0 }; + static ulong[] dim191JoeKuoD7Init = { 1, 1, 3, 11, 21, 47, 95, 31, 399, 115, 265, 0 }; + static ulong[] dim192JoeKuoD7Init = { 1, 3, 3, 3, 19, 43, 97, 29, 259, 671, 1789, 0 }; + static ulong[] dim193JoeKuoD7Init = { 1, 1, 1, 7, 11, 3, 1, 167, 73, 21, 587, 0 }; + static ulong[] dim194JoeKuoD7Init = { 1, 1, 7, 1, 7, 29, 113, 243, 389, 605, 1267, 0 }; + static ulong[] dim195JoeKuoD7Init = { 1, 3, 3, 1, 19, 17, 43, 89, 467, 501, 137, 0 }; + static ulong[] dim196JoeKuoD7Init = { 1, 1, 1, 7, 13, 41, 97, 123, 153, 603, 1469, 0 }; + static ulong[] dim197JoeKuoD7Init = { 1, 3, 5, 3, 25, 29, 45, 231, 489, 305, 1071, 0 }; + static ulong[] dim198JoeKuoD7Init = { 1, 1, 7, 3, 31, 51, 59, 113, 309, 923, 1171, 0 }; + static ulong[] dim199JoeKuoD7Init = { 1, 1, 5, 11, 7, 41, 55, 207, 181, 565, 913, 0 }; + static ulong[] dim200JoeKuoD7Init = { 1, 1, 3, 9, 9, 45, 25, 49, 135, 777, 593, 0 }; + static ulong[] dim201JoeKuoD7Init = { 1, 3, 5, 3, 31, 3, 51, 253, 369, 853, 1985, 0 }; + static ulong[] dim202JoeKuoD7Init = { 1, 3, 1, 3, 25, 7, 89, 193, 153, 835, 341, 0 }; + static ulong[] dim203JoeKuoD7Init = { 1, 3, 1, 15, 29, 51, 1, 159, 77, 423, 1319, 0 }; + static ulong[] dim204JoeKuoD7Init = { 1, 1, 5, 11, 31, 51, 93, 249, 321, 841, 619, 0 }; + static ulong[] dim205JoeKuoD7Init = { 1, 3, 1, 7, 17, 11, 99, 45, 407, 123, 1363, 0 }; + static ulong[] dim206JoeKuoD7Init = { 1, 3, 5, 5, 13, 39, 65, 195, 55, 991, 1105, 0 }; + static ulong[] dim207JoeKuoD7Init = { 1, 1, 5, 11, 13, 11, 79, 239, 93, 683, 1459, 0 }; + static ulong[] dim208JoeKuoD7Init = { 1, 1, 5, 11, 23, 5, 29, 73, 197, 17, 953, 0 }; + static ulong[] dim209JoeKuoD7Init = { 1, 1, 5, 3, 27, 13, 109, 193, 447, 271, 429, 0 }; + static ulong[] dim210JoeKuoD7Init = { 1, 3, 5, 15, 17, 41, 45, 205, 235, 1015, 1129, 0 }; + static ulong[] dim211JoeKuoD7Init = { 1, 3, 7, 7, 5, 33, 121, 23, 265, 199, 525, 0 }; + static ulong[] dim212JoeKuoD7Init = { 1, 1, 3, 5, 19, 35, 17, 177, 351, 935, 1769, 0 }; + static ulong[] dim213JoeKuoD7Init = { 1, 1, 5, 5, 1, 39, 71, 89, 27, 695, 289, 0 }; + static ulong[] dim214JoeKuoD7Init = { 1, 3, 5, 5, 27, 9, 27, 239, 83, 349, 1989, 0 }; + static ulong[] dim215JoeKuoD7Init = { 1, 3, 1, 11, 13, 63, 99, 177, 91, 899, 987, 0 }; + static ulong[] dim216JoeKuoD7Init = { 1, 3, 1, 1, 5, 23, 85, 61, 307, 491, 663, 0 }; + static ulong[] dim217JoeKuoD7Init = { 1, 1, 7, 7, 19, 27, 127, 205, 489, 857, 1077, 0 }; + static ulong[] dim218JoeKuoD7Init = { 1, 1, 3, 1, 1, 45, 43, 93, 445, 391, 1703, 0 }; + static ulong[] dim219JoeKuoD7Init = { 1, 1, 7, 9, 31, 55, 85, 103, 439, 123, 3, 0 }; + static ulong[] dim220JoeKuoD7Init = { 1, 1, 5, 15, 9, 51, 51, 213, 119, 245, 417, 0 }; + static ulong[] dim221JoeKuoD7Init = { 1, 3, 7, 1, 31, 49, 49, 227, 279, 891, 69, 0 }; + static ulong[] dim222JoeKuoD7Init = { 1, 3, 1, 13, 7, 49, 19, 147, 69, 451, 669, 0 }; + static ulong[] dim223JoeKuoD7Init = { 1, 3, 7, 9, 27, 27, 67, 131, 191, 497, 1189, 0 }; + static ulong[] dim224JoeKuoD7Init = { 1, 3, 5, 1, 13, 49, 93, 1, 161, 725, 709, 0 }; + static ulong[] dim225JoeKuoD7Init = { 1, 1, 1, 1, 13, 49, 67, 37, 153, 31, 409, 0 }; + static ulong[] dim226JoeKuoD7Init = { 1, 3, 1, 7, 19, 55, 103, 111, 381, 209, 271, 0 }; + static ulong[] dim227JoeKuoD7Init = { 1, 1, 5, 13, 17, 29, 15, 155, 81, 737, 565, 0 }; + static ulong[] dim228JoeKuoD7Init = { 1, 3, 7, 11, 29, 17, 119, 247, 189, 897, 1385, 0 }; + static ulong[] dim229JoeKuoD7Init = { 1, 1, 7, 13, 15, 51, 71, 85, 211, 839, 1085, 0 }; + static ulong[] dim230JoeKuoD7Init = { 1, 1, 3, 9, 15, 37, 93, 155, 357, 475, 175, 0 }; + static ulong[] dim231JoeKuoD7Init = { 1, 3, 7, 7, 1, 31, 125, 181, 339, 275, 301, 0 }; + static ulong[] dim232JoeKuoD7Init = { 1, 1, 3, 7, 27, 33, 3, 125, 153, 343, 577, 0 }; + static ulong[] dim233JoeKuoD7Init = { 1, 1, 3, 1, 17, 17, 51, 87, 409, 845, 1857, 0 }; + static ulong[] dim234JoeKuoD7Init = { 1, 1, 3, 11, 5, 47, 101, 45, 425, 721, 1303, 0 }; + static ulong[] dim235JoeKuoD7Init = { 1, 3, 1, 15, 9, 57, 15, 7, 479, 611, 1837, 0 }; + static ulong[] dim236JoeKuoD7Init = { 1, 3, 3, 13, 21, 57, 89, 145, 401, 1007, 753, 0 }; + static ulong[] dim237JoeKuoD7Init = { 1, 3, 3, 15, 19, 63, 5, 243, 111, 999, 435, 0 }; + static ulong[] dim238JoeKuoD7Init = { 1, 3, 7, 13, 31, 27, 27, 217, 71, 145, 695, 0 }; + static ulong[] dim239JoeKuoD7Init = { 1, 3, 7, 7, 11, 61, 113, 145, 481, 487, 1609, 0 }; + static ulong[] dim240JoeKuoD7Init = { 1, 1, 5, 13, 7, 51, 55, 1, 307, 219, 475, 0 }; + static ulong[] dim241JoeKuoD7Init = { 1, 3, 5, 5, 21, 27, 77, 193, 263, 37, 1421, 0 }; + static ulong[] dim242JoeKuoD7Init = { 1, 1, 5, 11, 5, 23, 101, 85, 41, 179, 1311, 0 }; + static ulong[] dim243JoeKuoD7Init = { 1, 1, 3, 9, 27, 5, 49, 227, 317, 695, 581, 0 }; + static ulong[] dim244JoeKuoD7Init = { 1, 1, 1, 15, 9, 23, 119, 145, 231, 15, 1349, 0 }; + static ulong[] dim245JoeKuoD7Init = { 1, 3, 1, 5, 1, 17, 37, 247, 261, 993, 173, 0 }; + static ulong[] dim246JoeKuoD7Init = { 1, 3, 1, 15, 31, 19, 23, 189, 353, 445, 1145, 0 }; + static ulong[] dim247JoeKuoD7Init = { 1, 3, 7, 11, 9, 1, 65, 211, 119, 531, 1389, 0 }; + static ulong[] dim248JoeKuoD7Init = { 1, 3, 7, 1, 31, 49, 31, 239, 131, 159, 55, 0 }; + static ulong[] dim249JoeKuoD7Init = { 1, 1, 7, 7, 3, 13, 85, 89, 459, 293, 1621, 0 }; + static ulong[] dim250JoeKuoD7Init = { 1, 1, 7, 7, 23, 55, 79, 61, 499, 915, 1641, 0 }; + static ulong[] dim251JoeKuoD7Init = { 1, 3, 1, 7, 17, 47, 69, 91, 157, 171, 1827, 0 }; + static ulong[] dim252JoeKuoD7Init = { 1, 3, 5, 5, 29, 55, 105, 31, 467, 3, 241, 0 }; + static ulong[] dim253JoeKuoD7Init = { 1, 1, 5, 11, 19, 27, 87, 199, 295, 949, 323, 0 }; + static ulong[] dim254JoeKuoD7Init = { 1, 1, 1, 1, 25, 59, 125, 33, 35, 75, 603, 0 }; + static ulong[] dim255JoeKuoD7Init = { 1, 3, 5, 5, 25, 63, 19, 87, 475, 711, 1549, 0 }; + static ulong[] dim256JoeKuoD7Init = { 1, 3, 3, 7, 11, 35, 29, 193, 27, 757, 133, 0 }; + static ulong[] dim257JoeKuoD7Init = { 1, 1, 5, 13, 9, 29, 21, 229, 137, 111, 1827, 0 }; + static ulong[] dim258JoeKuoD7Init = { 1, 3, 5, 7, 7, 5, 35, 217, 511, 309, 2013, 0 }; + static ulong[] dim259JoeKuoD7Init = { 1, 1, 1, 1, 3, 25, 99, 187, 141, 599, 223, 0 }; + static ulong[] dim260JoeKuoD7Init = { 1, 1, 7, 9, 23, 9, 3, 223, 357, 261, 393, 0 }; + static ulong[] dim261JoeKuoD7Init = { 1, 3, 5, 9, 3, 47, 73, 75, 153, 249, 149, 0 }; + static ulong[] dim262JoeKuoD7Init = { 1, 3, 7, 13, 5, 31, 25, 77, 501, 221, 941, 0 }; + static ulong[] dim263JoeKuoD7Init = { 1, 1, 7, 1, 21, 41, 107, 95, 245, 35, 1843, 0 }; + static ulong[] dim264JoeKuoD7Init = { 1, 3, 3, 3, 19, 59, 95, 51, 211, 647, 61, 0 }; + static ulong[] dim265JoeKuoD7Init = { 1, 3, 3, 15, 31, 9, 91, 191, 395, 161, 601, 0 }; + static ulong[] dim266JoeKuoD7Init = { 1, 3, 1, 7, 25, 11, 45, 147, 457, 457, 1331, 0 }; + static ulong[] dim267JoeKuoD7Init = { 1, 1, 5, 15, 31, 13, 49, 87, 481, 155, 745, 0 }; + static ulong[] dim268JoeKuoD7Init = { 1, 1, 5, 11, 17, 31, 93, 39, 195, 957, 877, 0 }; + static ulong[] dim269JoeKuoD7Init = { 1, 3, 3, 1, 1, 9, 1, 175, 63, 715, 887, 0 }; + static ulong[] dim270JoeKuoD7Init = { 1, 1, 7, 3, 11, 55, 15, 221, 103, 169, 1961, 0 }; + static ulong[] dim271JoeKuoD7Init = { 1, 1, 5, 15, 21, 41, 87, 141, 233, 879, 1869, 0 }; + static ulong[] dim272JoeKuoD7Init = { 1, 3, 5, 13, 13, 15, 127, 29, 103, 533, 925, 0 }; + static ulong[] dim273JoeKuoD7Init = { 1, 3, 1, 5, 23, 59, 1, 93, 97, 979, 1123, 0 }; + static ulong[] dim274JoeKuoD7Init = { 1, 3, 1, 7, 31, 29, 55, 185, 27, 759, 1037, 0 }; + static ulong[] dim275JoeKuoD7Init = { 1, 3, 7, 9, 9, 21, 95, 111, 291, 331, 889, 0 }; + static ulong[] dim276JoeKuoD7Init = { 1, 1, 3, 3, 15, 17, 113, 21, 97, 653, 769, 0 }; + static ulong[] dim277JoeKuoD7Init = { 1, 3, 1, 9, 19, 9, 67, 43, 9, 7, 1751, 0 }; + static ulong[] dim278JoeKuoD7Init = { 1, 1, 3, 9, 29, 15, 103, 69, 249, 465, 1747, 0 }; + static ulong[] dim279JoeKuoD7Init = { 1, 1, 3, 15, 17, 13, 81, 149, 253, 993, 25, 0 }; + static ulong[] dim280JoeKuoD7Init = { 1, 1, 3, 7, 27, 19, 63, 95, 165, 641, 1141, 0 }; + static ulong[] dim281JoeKuoD7Init = { 1, 3, 3, 1, 13, 39, 101, 131, 359, 825, 41, 0 }; + static ulong[] dim282JoeKuoD7Init = { 1, 1, 5, 7, 31, 31, 43, 83, 147, 427, 2031, 0 }; + static ulong[] dim283JoeKuoD7Init = { 1, 3, 5, 9, 27, 33, 109, 45, 123, 121, 485, 0 }; + static ulong[] dim284JoeKuoD7Init = { 1, 1, 3, 9, 27, 35, 13, 161, 363, 651, 1865, 0 }; + static ulong[] dim285JoeKuoD7Init = { 1, 1, 1, 11, 11, 45, 11, 127, 19, 459, 605, 0 }; + static ulong[] dim286JoeKuoD7Init = { 1, 3, 7, 15, 13, 37, 105, 159, 61, 157, 157, 0 }; + static ulong[] dim287JoeKuoD7Init = { 1, 3, 1, 15, 5, 39, 121, 85, 383, 579, 2001, 0 }; + static ulong[] dim288JoeKuoD7Init = { 1, 3, 1, 13, 13, 7, 101, 213, 455, 961, 1327, 0 }; + static ulong[] dim289JoeKuoD7Init = { 1, 3, 5, 13, 31, 39, 49, 33, 267, 783, 67, 0 }; + static ulong[] dim290JoeKuoD7Init = { 1, 1, 3, 9, 31, 43, 45, 85, 1, 187, 899, 0 }; + static ulong[] dim291JoeKuoD7Init = { 1, 1, 7, 1, 23, 11, 93, 227, 41, 1013, 1689, 0 }; + static ulong[] dim292JoeKuoD7Init = { 1, 1, 1, 15, 17, 31, 33, 67, 79, 113, 803, 0 }; + static ulong[] dim293JoeKuoD7Init = { 1, 1, 1, 9, 13, 53, 27, 203, 143, 469, 1435, 0 }; + static ulong[] dim294JoeKuoD7Init = { 1, 1, 5, 1, 19, 1, 119, 37, 135, 797, 1935, 0 }; + static ulong[] dim295JoeKuoD7Init = { 1, 1, 3, 11, 29, 29, 111, 79, 81, 973, 899, 0 }; + static ulong[] dim296JoeKuoD7Init = { 1, 3, 7, 1, 21, 3, 83, 43, 95, 445, 1529, 0 }; + static ulong[] dim297JoeKuoD7Init = { 1, 1, 3, 9, 11, 5, 27, 67, 101, 395, 195, 0 }; + static ulong[] dim298JoeKuoD7Init = { 1, 3, 1, 3, 29, 13, 41, 219, 157, 325, 955, 0 }; + static ulong[] dim299JoeKuoD7Init = { 1, 3, 3, 13, 27, 29, 113, 209, 323, 747, 759, 0 }; + static ulong[] dim300JoeKuoD7Init = { 1, 3, 1, 13, 1, 57, 113, 133, 363, 57, 715, 0 }; + static ulong[] dim301JoeKuoD7Init = { 1, 1, 3, 3, 25, 43, 123, 27, 483, 1023, 739, 0 }; + static ulong[] dim302JoeKuoD7Init = { 1, 1, 3, 13, 27, 43, 117, 217, 55, 977, 487, 0 }; + static ulong[] dim303JoeKuoD7Init = { 1, 1, 1, 3, 25, 31, 95, 67, 7, 19, 321, 0 }; + static ulong[] dim304JoeKuoD7Init = { 1, 3, 1, 3, 25, 7, 17, 123, 487, 709, 971, 0 }; + static ulong[] dim305JoeKuoD7Init = { 1, 3, 5, 11, 15, 9, 127, 129, 35, 123, 1217, 0 }; + static ulong[] dim306JoeKuoD7Init = { 1, 1, 3, 5, 17, 63, 67, 137, 253, 691, 447, 0 }; + static ulong[] dim307JoeKuoD7Init = { 1, 3, 3, 1, 27, 53, 25, 205, 75, 827, 1609, 0 }; + static ulong[] dim308JoeKuoD7Init = { 1, 1, 7, 13, 3, 49, 59, 207, 357, 269, 309, 0 }; + static ulong[] dim309JoeKuoD7Init = { 1, 3, 1, 5, 25, 57, 9, 117, 359, 9, 405, 0 }; + static ulong[] dim310JoeKuoD7Init = { 1, 3, 7, 15, 15, 21, 53, 163, 91, 35, 277, 0 }; + static ulong[] dim311JoeKuoD7Init = { 1, 3, 1, 1, 23, 5, 69, 83, 11, 161, 141, 0 }; + static ulong[] dim312JoeKuoD7Init = { 1, 1, 5, 13, 13, 25, 15, 209, 385, 389, 817, 0 }; + static ulong[] dim313JoeKuoD7Init = { 1, 3, 1, 13, 11, 11, 17, 191, 327, 731, 973, 0 }; + static ulong[] dim314JoeKuoD7Init = { 1, 3, 7, 15, 1, 63, 55, 51, 379, 359, 305, 0 }; + static ulong[] dim315JoeKuoD7Init = { 1, 3, 7, 11, 17, 19, 81, 123, 335, 391, 647, 0 }; + static ulong[] dim316JoeKuoD7Init = { 1, 3, 3, 13, 27, 15, 53, 243, 115, 733, 1095, 0 }; + static ulong[] dim317JoeKuoD7Init = { 1, 1, 1, 3, 5, 47, 111, 153, 479, 133, 723, 0 }; + static ulong[] dim318JoeKuoD7Init = { 1, 1, 3, 1, 15, 47, 85, 27, 449, 673, 931, 0 }; + static ulong[] dim319JoeKuoD7Init = { 1, 3, 1, 5, 23, 23, 15, 21, 113, 1003, 1077, 0 }; + static ulong[] dim320JoeKuoD7Init = { 1, 3, 7, 9, 27, 55, 29, 95, 21, 29, 1409, 0 }; + static ulong[] dim321JoeKuoD7Init = { 1, 1, 5, 5, 19, 53, 5, 135, 219, 607, 151, 0 }; + static ulong[] dim322JoeKuoD7Init = { 1, 1, 5, 1, 29, 31, 83, 103, 493, 227, 423, 0 }; + static ulong[] dim323JoeKuoD7Init = { 1, 3, 5, 13, 23, 3, 111, 147, 333, 159, 983, 0 }; + static ulong[] dim324JoeKuoD7Init = { 1, 3, 5, 7, 13, 1, 45, 57, 111, 459, 1503, 0 }; + static ulong[] dim325JoeKuoD7Init = { 1, 3, 7, 9, 9, 21, 27, 155, 377, 617, 1429, 0 }; + static ulong[] dim326JoeKuoD7Init = { 1, 3, 1, 15, 3, 7, 113, 11, 349, 961, 749, 0 }; + static ulong[] dim327JoeKuoD7Init = { 1, 3, 5, 15, 31, 13, 51, 63, 315, 691, 1351, 0 }; + static ulong[] dim328JoeKuoD7Init = { 1, 1, 5, 1, 21, 51, 5, 53, 215, 199, 891, 0 }; + static ulong[] dim329JoeKuoD7Init = { 1, 1, 3, 1, 23, 19, 37, 29, 263, 341, 453, 0 }; + static ulong[] dim330JoeKuoD7Init = { 1, 3, 3, 1, 13, 37, 113, 121, 483, 879, 1749, 0 }; + static ulong[] dim331JoeKuoD7Init = { 1, 3, 3, 7, 13, 41, 19, 69, 323, 547, 297, 0 }; + static ulong[] dim332JoeKuoD7Init = { 1, 3, 5, 9, 23, 13, 21, 179, 377, 217, 559, 0 }; + static ulong[] dim333JoeKuoD7Init = { 1, 3, 5, 15, 15, 5, 17, 41, 3, 391, 1241, 0 }; + static ulong[] dim334JoeKuoD7Init = { 1, 1, 1, 15, 31, 57, 97, 57, 183, 415, 917, 0 }; + static ulong[] dim335JoeKuoD7Init = { 1, 1, 7, 9, 17, 31, 121, 15, 425, 9, 655, 0 }; + static ulong[] dim336JoeKuoD7Init = { 1, 1, 7, 15, 3, 55, 53, 73, 463, 887, 1999, 0 }; + static ulong[] dim337JoeKuoD7Init = { 1, 1, 1, 7, 3, 25, 17, 5, 55, 833, 1899, 4077, 0 }; + static ulong[] dim338JoeKuoD7Init = { 1, 1, 5, 11, 23, 47, 67, 45, 9, 41, 835, 373, 0 }; + static ulong[] dim339JoeKuoD7Init = { 1, 3, 7, 11, 5, 55, 25, 137, 11, 119, 967, 3969, 0 }; + static ulong[] dim340JoeKuoD7Init = { 1, 3, 3, 13, 3, 5, 17, 11, 259, 7, 1587, 3919, 0 }; + static ulong[] dim341JoeKuoD7Init = { 1, 1, 7, 3, 29, 57, 113, 207, 187, 173, 575, 935, 0 }; + static ulong[] dim342JoeKuoD7Init = { 1, 3, 1, 9, 25, 31, 89, 29, 345, 753, 1675, 85, 0 }; + static ulong[] dim343JoeKuoD7Init = { 1, 1, 3, 1, 9, 41, 91, 245, 63, 995, 1751, 2881, 0 }; + static ulong[] dim344JoeKuoD7Init = { 1, 1, 7, 3, 21, 63, 121, 237, 243, 815, 1507, 265, 0 }; + static ulong[] dim345JoeKuoD7Init = { 1, 1, 1, 1, 23, 27, 121, 215, 381, 317, 669, 357, 0 }; + static ulong[] dim346JoeKuoD7Init = { 1, 3, 1, 3, 1, 45, 87, 19, 43, 915, 1083, 3259, 0 }; + static ulong[] dim347JoeKuoD7Init = { 1, 3, 7, 5, 15, 31, 15, 229, 489, 897, 791, 3019, 0 }; + static ulong[] dim348JoeKuoD7Init = { 1, 3, 3, 5, 25, 19, 89, 211, 413, 839, 2029, 1785, 0 }; + static ulong[] dim349JoeKuoD7Init = { 1, 3, 7, 1, 19, 29, 67, 11, 483, 303, 469, 795, 0 }; + static ulong[] dim350JoeKuoD7Init = { 1, 3, 5, 5, 19, 15, 81, 147, 337, 641, 1863, 2497, 0 }; + static ulong[] dim351JoeKuoD7Init = { 1, 1, 7, 5, 17, 43, 83, 173, 307, 397, 1231, 2275, 0 }; + static ulong[] dim352JoeKuoD7Init = { 1, 1, 1, 9, 27, 49, 61, 29, 169, 811, 171, 1373, 0 }; + static ulong[] dim353JoeKuoD7Init = { 1, 1, 1, 1, 13, 63, 11, 197, 145, 987, 1709, 895, 0 }; + static ulong[] dim354JoeKuoD7Init = { 1, 1, 7, 3, 15, 3, 5, 213, 155, 271, 867, 1665, 0 }; + static ulong[] dim355JoeKuoD7Init = { 1, 1, 3, 1, 23, 51, 99, 49, 83, 159, 1589, 3961, 0 }; + static ulong[] dim356JoeKuoD7Init = { 1, 3, 3, 9, 21, 13, 1, 91, 187, 615, 293, 3791, 0 }; + static ulong[] dim357JoeKuoD7Init = { 1, 3, 1, 5, 19, 43, 107, 235, 339, 65, 579, 2529, 0 }; + static ulong[] dim358JoeKuoD7Init = { 1, 3, 1, 1, 17, 39, 63, 67, 289, 593, 959, 1503, 0 }; + static ulong[] dim359JoeKuoD7Init = { 1, 1, 1, 11, 3, 15, 87, 153, 487, 537, 849, 385, 0 }; + static ulong[] dim360JoeKuoD7Init = { 1, 1, 3, 3, 5, 11, 99, 239, 241, 251, 793, 3677, 0 }; + static ulong[] dim361JoeKuoD7Init = { 1, 3, 7, 7, 13, 21, 111, 113, 69, 861, 1455, 3655, 0 }; + static ulong[] dim362JoeKuoD7Init = { 1, 1, 7, 11, 9, 21, 33, 29, 505, 81, 713, 2545, 0 }; + static ulong[] dim363JoeKuoD7Init = { 1, 3, 1, 11, 5, 29, 83, 73, 377, 611, 1099, 3225, 0 }; + static ulong[] dim364JoeKuoD7Init = { 1, 3, 7, 3, 25, 53, 75, 75, 235, 877, 609, 1535, 0 }; + static ulong[] dim365JoeKuoD7Init = { 1, 1, 1, 1, 29, 45, 27, 13, 437, 317, 581, 1179, 0 }; + static ulong[] dim366JoeKuoD7Init = { 1, 3, 3, 1, 3, 25, 127, 157, 443, 229, 277, 4059, 0 }; + static ulong[] dim367JoeKuoD7Init = { 1, 1, 1, 13, 17, 61, 31, 1, 483, 915, 1085, 1497, 0 }; + static ulong[] dim368JoeKuoD7Init = { 1, 3, 7, 11, 13, 57, 5, 49, 181, 881, 765, 1767, 0 }; + static ulong[] dim369JoeKuoD7Init = { 1, 1, 3, 1, 29, 17, 91, 95, 319, 339, 187, 2427, 0 }; + static ulong[] dim370JoeKuoD7Init = { 1, 3, 7, 5, 1, 17, 33, 181, 165, 237, 815, 3387, 0 }; + static ulong[] dim371JoeKuoD7Init = { 1, 1, 7, 1, 5, 17, 81, 193, 61, 411, 457, 2367, 0 }; + static ulong[] dim372JoeKuoD7Init = { 1, 1, 1, 7, 23, 17, 73, 185, 269, 1017, 299, 1879, 0 }; + static ulong[] dim373JoeKuoD7Init = { 1, 3, 5, 11, 7, 33, 75, 57, 275, 355, 1157, 2297, 0 }; + static ulong[] dim374JoeKuoD7Init = { 1, 3, 5, 7, 13, 7, 69, 25, 411, 319, 1385, 2081, 0 }; + static ulong[] dim375JoeKuoD7Init = { 1, 1, 7, 15, 27, 55, 35, 51, 71, 759, 1071, 51, 0 }; + static ulong[] dim376JoeKuoD7Init = { 1, 3, 5, 7, 29, 3, 25, 19, 123, 717, 1071, 257, 0 }; + static ulong[] dim377JoeKuoD7Init = { 1, 3, 7, 1, 7, 37, 51, 175, 19, 511, 469, 3757, 0 }; + static ulong[] dim378JoeKuoD7Init = { 1, 1, 5, 5, 19, 45, 107, 207, 369, 479, 853, 195, 0 }; + static ulong[] dim379JoeKuoD7Init = { 1, 3, 1, 9, 11, 11, 89, 115, 149, 789, 523, 2949, 0 }; + static ulong[] dim380JoeKuoD7Init = { 1, 3, 1, 11, 15, 53, 123, 167, 471, 355, 1515, 2291, 0 }; + static ulong[] dim381JoeKuoD7Init = { 1, 3, 7, 1, 23, 1, 5, 21, 315, 45, 1901, 3351, 0 }; + static ulong[] dim382JoeKuoD7Init = { 1, 1, 7, 5, 3, 49, 31, 89, 11, 777, 1003, 389, 0 }; + static ulong[] dim383JoeKuoD7Init = { 1, 1, 5, 3, 23, 3, 55, 213, 333, 257, 309, 4079, 0 }; + static ulong[] dim384JoeKuoD7Init = { 1, 3, 3, 7, 9, 29, 103, 41, 161, 253, 681, 1971, 0 }; + static ulong[] dim385JoeKuoD7Init = { 1, 1, 7, 13, 13, 33, 71, 121, 325, 423, 1485, 3205, 0 }; + static ulong[] dim386JoeKuoD7Init = { 1, 3, 1, 7, 9, 55, 69, 201, 111, 561, 1733, 1881, 0 }; + static ulong[] dim387JoeKuoD7Init = { 1, 1, 1, 7, 9, 41, 31, 113, 79, 193, 757, 329, 0 }; + static ulong[] dim388JoeKuoD7Init = { 1, 1, 7, 5, 3, 23, 27, 99, 179, 7, 1087, 27, 0 }; + static ulong[] dim389JoeKuoD7Init = { 1, 3, 3, 7, 13, 23, 9, 61, 157, 641, 299, 2077, 0 }; + static ulong[] dim390JoeKuoD7Init = { 1, 1, 5, 5, 29, 59, 63, 67, 493, 119, 959, 2683, 0 }; + static ulong[] dim391JoeKuoD7Init = { 1, 1, 3, 1, 19, 25, 117, 161, 249, 545, 997, 17, 0 }; + static ulong[] dim392JoeKuoD7Init = { 1, 3, 5, 5, 5, 31, 107, 181, 191, 913, 1911, 2329, 0 }; + static ulong[] dim393JoeKuoD7Init = { 1, 3, 1, 13, 31, 11, 109, 229, 159, 235, 975, 717, 0 }; + static ulong[] dim394JoeKuoD7Init = { 1, 1, 5, 3, 5, 7, 117, 233, 83, 31, 1641, 251, 0 }; + static ulong[] dim395JoeKuoD7Init = { 1, 1, 1, 1, 3, 45, 53, 179, 113, 353, 1805, 1097, 0 }; + static ulong[] dim396JoeKuoD7Init = { 1, 3, 3, 5, 17, 15, 83, 177, 399, 831, 231, 2307, 0 }; + static ulong[] dim397JoeKuoD7Init = { 1, 3, 7, 15, 19, 37, 19, 119, 243, 703, 1813, 2415, 0 }; + static ulong[] dim398JoeKuoD7Init = { 1, 3, 7, 9, 19, 25, 119, 123, 235, 817, 871, 763, 0 }; + static ulong[] dim399JoeKuoD7Init = { 1, 1, 5, 3, 7, 49, 97, 207, 297, 283, 467, 1843, 0 }; + static ulong[] dim400JoeKuoD7Init = { 1, 3, 5, 1, 21, 25, 103, 227, 239, 683, 797, 1763, 0 }; + static ulong[] dim401JoeKuoD7Init = { 1, 1, 5, 11, 27, 27, 127, 185, 137, 449, 1549, 3561, 0 }; + static ulong[] dim402JoeKuoD7Init = { 1, 1, 5, 5, 3, 45, 113, 35, 427, 847, 1761, 1721, 0 }; + static ulong[] dim403JoeKuoD7Init = { 1, 1, 3, 7, 25, 63, 33, 197, 183, 803, 963, 2179, 0 }; + static ulong[] dim404JoeKuoD7Init = { 1, 1, 3, 9, 19, 1, 3, 229, 225, 479, 593, 597, 0 }; + static ulong[] dim405JoeKuoD7Init = { 1, 3, 1, 5, 19, 35, 105, 245, 1, 249, 217, 2917, 0 }; + static ulong[] dim406JoeKuoD7Init = { 1, 3, 1, 1, 11, 3, 59, 51, 249, 135, 419, 3411, 0 }; + static ulong[] dim407JoeKuoD7Init = { 1, 3, 3, 15, 27, 45, 51, 15, 17, 473, 557, 2679, 0 }; + static ulong[] dim408JoeKuoD7Init = { 1, 3, 7, 11, 31, 43, 45, 163, 289, 723, 337, 2817, 0 }; + static ulong[] dim409JoeKuoD7Init = { 1, 1, 3, 11, 11, 51, 73, 101, 217, 255, 1547, 925, 0 }; + static ulong[] dim410JoeKuoD7Init = { 1, 3, 7, 5, 7, 53, 5, 163, 323, 757, 1443, 2703, 0 }; + static ulong[] dim411JoeKuoD7Init = { 1, 1, 5, 15, 19, 35, 23, 129, 199, 303, 1801, 1999, 0 }; + static ulong[] dim412JoeKuoD7Init = { 1, 1, 5, 15, 23, 37, 25, 61, 307, 901, 1117, 1301, 0 }; + static ulong[] dim413JoeKuoD7Init = { 1, 1, 5, 11, 15, 59, 71, 163, 93, 471, 341, 1825, 0 }; + static ulong[] dim414JoeKuoD7Init = { 1, 3, 7, 11, 27, 63, 73, 209, 453, 49, 1161, 1399, 0 }; + static ulong[] dim415JoeKuoD7Init = { 1, 3, 5, 3, 9, 5, 101, 47, 225, 451, 2005, 223, 0 }; + static ulong[] dim416JoeKuoD7Init = { 1, 3, 3, 3, 25, 43, 33, 171, 413, 371, 1133, 1057, 0 }; + static ulong[] dim417JoeKuoD7Init = { 1, 3, 3, 9, 5, 35, 39, 219, 319, 301, 1475, 3155, 0 }; + static ulong[] dim418JoeKuoD7Init = { 1, 3, 5, 15, 17, 39, 123, 165, 337, 17, 679, 3155, 0 }; + static ulong[] dim419JoeKuoD7Init = { 1, 1, 5, 3, 29, 33, 13, 165, 57, 723, 1201, 3523, 0 }; + static ulong[] dim420JoeKuoD7Init = { 1, 1, 1, 9, 25, 23, 67, 139, 321, 555, 723, 1017, 0 }; + static ulong[] dim421JoeKuoD7Init = { 1, 1, 3, 9, 17, 59, 25, 29, 473, 473, 1425, 965, 0 }; + static ulong[] dim422JoeKuoD7Init = { 1, 1, 5, 3, 13, 53, 29, 239, 321, 455, 1539, 1279, 0 }; + static ulong[] dim423JoeKuoD7Init = { 1, 3, 7, 3, 3, 37, 127, 149, 205, 313, 827, 1713, 0 }; + static ulong[] dim424JoeKuoD7Init = { 1, 1, 7, 5, 11, 41, 25, 73, 279, 539, 1761, 2565, 0 }; + static ulong[] dim425JoeKuoD7Init = { 1, 1, 5, 9, 21, 7, 75, 209, 83, 885, 821, 3887, 0 }; + static ulong[] dim426JoeKuoD7Init = { 1, 1, 3, 1, 21, 1, 13, 245, 291, 615, 1747, 1477, 0 }; + static ulong[] dim427JoeKuoD7Init = { 1, 1, 5, 1, 1, 11, 107, 105, 19, 263, 1497, 2311, 0 }; + static ulong[] dim428JoeKuoD7Init = { 1, 1, 5, 5, 15, 15, 105, 171, 143, 879, 1611, 277, 0 }; + static ulong[] dim429JoeKuoD7Init = { 1, 3, 1, 15, 15, 51, 15, 15, 25, 309, 1531, 977, 0 }; + static ulong[] dim430JoeKuoD7Init = { 1, 1, 7, 11, 29, 63, 65, 209, 155, 975, 107, 611, 0 }; + static ulong[] dim431JoeKuoD7Init = { 1, 3, 3, 15, 11, 55, 21, 149, 291, 221, 449, 133, 0 }; + static ulong[] dim432JoeKuoD7Init = { 1, 1, 3, 13, 3, 59, 41, 167, 37, 951, 1561, 2087, 0 }; + static ulong[] dim433JoeKuoD7Init = { 1, 3, 3, 15, 31, 59, 97, 49, 319, 935, 1419, 3215, 0 }; + static ulong[] dim434JoeKuoD7Init = { 1, 1, 3, 1, 27, 17, 91, 91, 327, 395, 1553, 201, 0 }; + static ulong[] dim435JoeKuoD7Init = { 1, 3, 1, 7, 5, 59, 51, 77, 207, 697, 521, 635, 0 }; + static ulong[] dim436JoeKuoD7Init = { 1, 3, 7, 5, 5, 37, 95, 91, 399, 151, 1795, 905, 0 }; + static ulong[] dim437JoeKuoD7Init = { 1, 3, 5, 5, 19, 29, 49, 55, 377, 793, 1429, 3393, 0 }; + static ulong[] dim438JoeKuoD7Init = { 1, 1, 5, 9, 9, 43, 127, 203, 355, 951, 711, 563, 0 }; + static ulong[] dim439JoeKuoD7Init = { 1, 1, 1, 13, 23, 21, 123, 41, 465, 33, 855, 1685, 0 }; + static ulong[] dim440JoeKuoD7Init = { 1, 1, 5, 7, 7, 11, 65, 195, 235, 823, 23, 2723, 0 }; + static ulong[] dim441JoeKuoD7Init = { 1, 1, 7, 7, 9, 41, 93, 109, 475, 587, 27, 1061, 0 }; + static ulong[] dim442JoeKuoD7Init = { 1, 3, 7, 13, 5, 45, 29, 87, 75, 853, 2023, 795, 0 }; + static ulong[] dim443JoeKuoD7Init = { 1, 1, 1, 3, 3, 7, 59, 235, 139, 457, 1855, 3739, 0 }; + static ulong[] dim444JoeKuoD7Init = { 1, 1, 7, 11, 23, 57, 25, 11, 473, 699, 887, 805, 0 }; + static ulong[] dim445JoeKuoD7Init = { 1, 1, 5, 1, 27, 3, 23, 115, 499, 287, 531, 1115, 0 }; + static ulong[] dim446JoeKuoD7Init = { 1, 3, 7, 15, 7, 7, 33, 83, 29, 477, 727, 3037, 0 }; + static ulong[] dim447JoeKuoD7Init = { 1, 1, 1, 9, 27, 43, 113, 203, 413, 649, 869, 3351, 0 }; + static ulong[] dim448JoeKuoD7Init = { 1, 1, 3, 9, 27, 15, 105, 167, 431, 87, 931, 4017, 0 }; + static ulong[] dim449JoeKuoD7Init = { 1, 3, 3, 1, 15, 23, 85, 145, 349, 291, 1137, 605, 0 }; + static ulong[] dim450JoeKuoD7Init = { 1, 3, 3, 15, 31, 53, 127, 25, 15, 277, 575, 1327, 0 }; + static ulong[] dim451JoeKuoD7Init = { 1, 3, 1, 15, 17, 29, 125, 251, 469, 15, 1803, 237, 0 }; + static ulong[] dim452JoeKuoD7Init = { 1, 3, 5, 13, 9, 21, 23, 111, 103, 861, 1137, 3843, 0 }; + static ulong[] dim453JoeKuoD7Init = { 1, 1, 5, 5, 29, 49, 101, 237, 187, 825, 137, 957, 0 }; + static ulong[] dim454JoeKuoD7Init = { 1, 1, 3, 13, 13, 9, 101, 171, 15, 245, 107, 2179, 0 }; + static ulong[] dim455JoeKuoD7Init = { 1, 1, 3, 11, 21, 33, 51, 211, 113, 569, 295, 3593, 0 }; + static ulong[] dim456JoeKuoD7Init = { 1, 3, 1, 5, 9, 5, 119, 159, 211, 121, 1547, 2267, 0 }; + static ulong[] dim457JoeKuoD7Init = { 1, 1, 3, 9, 7, 19, 53, 39, 271, 437, 765, 1511, 0 }; + static ulong[] dim458JoeKuoD7Init = { 1, 1, 1, 9, 3, 5, 119, 83, 161, 275, 1443, 465, 0 }; + static ulong[] dim459JoeKuoD7Init = { 1, 3, 7, 1, 27, 61, 103, 207, 249, 479, 651, 1793, 0 }; + static ulong[] dim460JoeKuoD7Init = { 1, 3, 5, 9, 11, 53, 43, 41, 271, 859, 25, 1401, 0 }; + static ulong[] dim461JoeKuoD7Init = { 1, 3, 1, 5, 9, 39, 87, 21, 425, 561, 861, 2801, 0 }; + static ulong[] dim462JoeKuoD7Init = { 1, 3, 7, 1, 1, 25, 21, 199, 315, 355, 429, 3093, 0 }; + static ulong[] dim463JoeKuoD7Init = { 1, 1, 7, 9, 11, 63, 123, 253, 483, 781, 1685, 977, 0 }; + static ulong[] dim464JoeKuoD7Init = { 1, 1, 1, 15, 17, 57, 19, 251, 173, 519, 1523, 749, 0 }; + static ulong[] dim465JoeKuoD7Init = { 1, 1, 1, 11, 23, 5, 119, 7, 327, 507, 1777, 951, 0 }; + static ulong[] dim466JoeKuoD7Init = { 1, 3, 7, 5, 1, 37, 41, 99, 273, 241, 293, 2289, 0 }; + static ulong[] dim467JoeKuoD7Init = { 1, 3, 3, 9, 3, 51, 65, 115, 159, 341, 1603, 3769, 0 }; + static ulong[] dim468JoeKuoD7Init = { 1, 3, 7, 3, 15, 61, 105, 103, 113, 435, 415, 161, 0 }; + static ulong[] dim469JoeKuoD7Init = { 1, 1, 1, 7, 9, 9, 17, 13, 135, 923, 951, 3603, 0 }; + static ulong[] dim470JoeKuoD7Init = { 1, 1, 3, 13, 9, 31, 25, 175, 449, 541, 745, 2771, 0 }; + static ulong[] dim471JoeKuoD7Init = { 1, 3, 3, 9, 5, 5, 61, 17, 357, 623, 873, 975, 0 }; + static ulong[] dim472JoeKuoD7Init = { 1, 1, 3, 9, 9, 31, 11, 225, 81, 965, 1837, 1975, 0 }; + static ulong[] dim473JoeKuoD7Init = { 1, 1, 7, 1, 3, 57, 69, 169, 11, 633, 885, 535, 0 }; + static ulong[] dim474JoeKuoD7Init = { 1, 1, 1, 9, 21, 63, 73, 233, 151, 519, 1319, 1485, 0 }; + static ulong[] dim475JoeKuoD7Init = { 1, 1, 3, 11, 23, 5, 51, 115, 501, 627, 1875, 3003, 0 }; + static ulong[] dim476JoeKuoD7Init = { 1, 1, 5, 1, 9, 3, 91, 177, 305, 897, 317, 3231, 0 }; + static ulong[] dim477JoeKuoD7Init = { 1, 3, 3, 3, 9, 13, 121, 93, 303, 551, 1087, 905, 0 }; + static ulong[] dim478JoeKuoD7Init = { 1, 1, 5, 7, 1, 63, 123, 177, 87, 489, 1247, 1831, 0 }; + static ulong[] dim479JoeKuoD7Init = { 1, 3, 3, 5, 25, 61, 1, 225, 247, 991, 231, 657, 0 }; + static ulong[] dim480JoeKuoD7Init = { 1, 3, 5, 5, 19, 23, 113, 101, 427, 327, 1859, 3115, 0 }; + static ulong[] dim481JoeKuoD7Init = { 1, 1, 5, 13, 11, 5, 125, 133, 131, 441, 1277, 2583, 7133, 0 }; + static ulong[] dim482JoeKuoD7Init = { 1, 3, 7, 3, 29, 45, 21, 45, 477, 135, 13, 2531, 7657, 0 }; + static ulong[] dim483JoeKuoD7Init = { 1, 1, 7, 9, 19, 3, 47, 37, 491, 237, 1493, 4053, 6025, 0 }; + static ulong[] dim484JoeKuoD7Init = { 1, 1, 5, 7, 15, 51, 23, 181, 63, 755, 761, 3215, 3547, 0 }; + static ulong[] dim485JoeKuoD7Init = { 1, 1, 7, 5, 11, 3, 27, 187, 221, 305, 1941, 1443, 5161, 0 }; + static ulong[] dim486JoeKuoD7Init = { 1, 1, 7, 13, 13, 53, 63, 19, 5, 273, 1305, 919, 3335, 0 }; + static ulong[] dim487JoeKuoD7Init = { 1, 3, 1, 5, 15, 19, 85, 35, 41, 117, 1269, 289, 7433, 0 }; + static ulong[] dim488JoeKuoD7Init = { 1, 3, 7, 9, 27, 49, 119, 101, 57, 267, 1225, 3779, 3357, 0 }; + static ulong[] dim489JoeKuoD7Init = { 1, 3, 5, 11, 5, 1, 9, 251, 411, 19, 763, 1297, 5309, 0 }; + static ulong[] dim490JoeKuoD7Init = { 1, 3, 3, 13, 31, 55, 67, 63, 23, 1021, 199, 2885, 1777, 0 }; + static ulong[] dim491JoeKuoD7Init = { 1, 3, 7, 9, 29, 27, 123, 191, 125, 295, 891, 3507, 2895, 0 }; + static ulong[] dim492JoeKuoD7Init = { 1, 1, 5, 7, 15, 41, 35, 119, 343, 603, 819, 41, 8131, 0 }; + static ulong[] dim493JoeKuoD7Init = { 1, 3, 3, 9, 21, 61, 43, 199, 359, 607, 623, 1579, 7899, 0 }; + static ulong[] dim494JoeKuoD7Init = { 1, 1, 1, 15, 25, 59, 47, 47, 365, 125, 921, 3081, 2081, 0 }; + static ulong[] dim495JoeKuoD7Init = { 1, 3, 3, 1, 23, 23, 111, 53, 395, 945, 59, 3345, 1671, 0 }; + static ulong[] dim496JoeKuoD7Init = { 1, 1, 1, 15, 15, 57, 31, 15, 235, 247, 1645, 3085, 4381, 0 }; + static ulong[] dim497JoeKuoD7Init = { 1, 1, 3, 11, 23, 21, 9, 89, 61, 347, 1423, 3613, 697, 0 }; + static ulong[] dim498JoeKuoD7Init = { 1, 1, 5, 13, 21, 37, 5, 159, 409, 131, 559, 3505, 6631, 0 }; + static ulong[] dim499JoeKuoD7Init = { 1, 3, 3, 11, 23, 51, 97, 247, 137, 183, 1775, 2169, 2869, 0 }; + static ulong[] dim500JoeKuoD7Init = { 1, 1, 7, 7, 29, 53, 109, 75, 327, 755, 825, 329, 5795, 0 }; + static ulong[] dim501JoeKuoD7Init = { 1, 3, 1, 5, 17, 63, 109, 199, 215, 869, 2009, 1153, 1233, 0 }; + static ulong[] dim502JoeKuoD7Init = { 1, 1, 7, 15, 15, 37, 63, 93, 151, 621, 1749, 2211, 5437, 0 }; + static ulong[] dim503JoeKuoD7Init = { 1, 3, 5, 15, 13, 63, 57, 17, 323, 271, 1451, 459, 1187, 0 }; + static ulong[] dim504JoeKuoD7Init = { 1, 1, 5, 5, 31, 47, 15, 83, 389, 857, 505, 635, 7341, 0 }; + static ulong[] dim505JoeKuoD7Init = { 1, 3, 5, 3, 19, 7, 83, 17, 51, 947, 1193, 163, 3895, 0 }; + static ulong[] dim506JoeKuoD7Init = { 1, 1, 7, 1, 23, 5, 115, 113, 445, 703, 747, 963, 7483, 0 }; + static ulong[] dim507JoeKuoD7Init = { 1, 3, 7, 5, 27, 31, 41, 221, 313, 317, 517, 3901, 3937, 0 }; + static ulong[] dim508JoeKuoD7Init = { 1, 3, 5, 11, 29, 41, 23, 249, 169, 51, 1783, 2493, 6109, 0 }; + static ulong[] dim509JoeKuoD7Init = { 1, 1, 5, 13, 23, 23, 85, 71, 321, 623, 207, 3027, 319, 0 }; + static ulong[] dim510JoeKuoD7Init = { 1, 1, 7, 3, 3, 19, 63, 233, 377, 509, 1969, 67, 5059, 0 }; + static ulong[] dim511JoeKuoD7Init = { 1, 1, 3, 7, 13, 27, 39, 67, 483, 587, 1581, 177, 5213, 0 }; + static ulong[] dim512JoeKuoD7Init = { 1, 1, 3, 1, 23, 55, 3, 177, 97, 551, 1733, 1943, 6607, 0 }; + static ulong[] dim513JoeKuoD7Init = { 1, 3, 3, 5, 5, 9, 39, 189, 473, 5, 19, 2793, 6937, 0 }; + static ulong[] dim514JoeKuoD7Init = { 1, 1, 3, 13, 31, 35, 105, 19, 279, 749, 523, 1503, 6231, 0 }; + static ulong[] dim515JoeKuoD7Init = { 1, 3, 1, 9, 11, 59, 89, 153, 155, 219, 549, 2263, 8101, 0 }; + static ulong[] dim516JoeKuoD7Init = { 1, 1, 7, 13, 29, 9, 9, 61, 43, 165, 1395, 91, 2871, 0 }; + static ulong[] dim517JoeKuoD7Init = { 1, 1, 1, 1, 27, 63, 63, 97, 47, 969, 991, 111, 2267, 0 }; + static ulong[] dim518JoeKuoD7Init = { 1, 1, 3, 7, 5, 13, 51, 195, 369, 551, 961, 1123, 7001, 0 }; + static ulong[] dim519JoeKuoD7Init = { 1, 1, 5, 7, 27, 57, 49, 51, 321, 187, 1869, 1181, 6333, 0 }; + static ulong[] dim520JoeKuoD7Init = { 1, 3, 1, 3, 25, 63, 15, 165, 175, 401, 1659, 2345, 683, 0 }; + static ulong[] dim521JoeKuoD7Init = { 1, 1, 7, 1, 9, 41, 121, 123, 49, 303, 229, 2799, 3247, 0 }; + static ulong[] dim522JoeKuoD7Init = { 1, 1, 1, 15, 29, 11, 113, 137, 221, 859, 1601, 215, 6257, 0 }; + static ulong[] dim523JoeKuoD7Init = { 1, 1, 5, 9, 9, 21, 91, 179, 369, 389, 1737, 1235, 3033, 0 }; + static ulong[] dim524JoeKuoD7Init = { 1, 3, 7, 7, 21, 53, 85, 217, 505, 299, 1505, 3289, 3811, 0 }; + static ulong[] dim525JoeKuoD7Init = { 1, 1, 3, 15, 25, 25, 109, 229, 511, 733, 1047, 3295, 307, 0 }; + static ulong[] dim526JoeKuoD7Init = { 1, 1, 3, 15, 29, 25, 21, 201, 353, 97, 231, 3791, 3019, 0 }; + static ulong[] dim527JoeKuoD7Init = { 1, 3, 1, 5, 1, 7, 75, 57, 501, 217, 1647, 1539, 2961, 0 }; + static ulong[] dim528JoeKuoD7Init = { 1, 3, 3, 5, 21, 13, 123, 153, 83, 253, 19, 2469, 5239, 0 }; + static ulong[] dim529JoeKuoD7Init = { 1, 3, 1, 3, 31, 13, 103, 107, 91, 3, 1795, 3587, 3345, 0 }; + static ulong[] dim530JoeKuoD7Init = { 1, 3, 7, 13, 1, 47, 71, 61, 335, 347, 753, 3685, 3895, 0 }; + static ulong[] dim531JoeKuoD7Init = { 1, 1, 1, 11, 25, 53, 73, 65, 203, 923, 661, 1349, 8089, 0 }; + static ulong[] dim532JoeKuoD7Init = { 1, 1, 1, 5, 11, 23, 93, 149, 367, 577, 1095, 993, 5279, 0 }; + static ulong[] dim533JoeKuoD7Init = { 1, 3, 3, 7, 11, 33, 23, 117, 457, 1023, 1789, 3103, 2979, 0 }; + static ulong[] dim534JoeKuoD7Init = { 1, 3, 3, 11, 3, 3, 3, 177, 9, 11, 1753, 3291, 7617, 0 }; + static ulong[] dim535JoeKuoD7Init = { 1, 1, 1, 7, 1, 27, 105, 199, 465, 505, 427, 2605, 7215, 0 }; + static ulong[] dim536JoeKuoD7Init = { 1, 3, 7, 1, 19, 23, 21, 167, 205, 561, 175, 677, 117, 0 }; + static ulong[] dim537JoeKuoD7Init = { 1, 1, 1, 7, 31, 23, 83, 219, 391, 101, 1433, 3973, 4217, 0 }; + static ulong[] dim538JoeKuoD7Init = { 1, 1, 1, 3, 9, 41, 21, 189, 437, 187, 1973, 445, 7439, 0 }; + static ulong[] dim539JoeKuoD7Init = { 1, 1, 5, 7, 21, 3, 53, 9, 295, 331, 2029, 3063, 6095, 0 }; + static ulong[] dim540JoeKuoD7Init = { 1, 1, 1, 7, 19, 9, 119, 247, 371, 635, 1411, 419, 3297, 0 }; + static ulong[] dim541JoeKuoD7Init = { 1, 1, 3, 1, 3, 31, 113, 235, 57, 923, 2033, 1523, 6381, 0 }; + static ulong[] dim542JoeKuoD7Init = { 1, 1, 1, 3, 17, 51, 115, 215, 271, 411, 573, 1761, 1793, 0 }; + static ulong[] dim543JoeKuoD7Init = { 1, 3, 1, 11, 5, 15, 69, 193, 107, 577, 909, 1997, 4503, 0 }; + static ulong[] dim544JoeKuoD7Init = { 1, 3, 5, 3, 1, 3, 17, 227, 381, 931, 1933, 807, 3295, 0 }; + static ulong[] dim545JoeKuoD7Init = { 1, 1, 7, 15, 15, 23, 15, 183, 247, 167, 193, 1643, 4139, 0 }; + static ulong[] dim546JoeKuoD7Init = { 1, 3, 7, 13, 31, 39, 13, 213, 45, 643, 515, 1167, 6991, 0 }; + static ulong[] dim547JoeKuoD7Init = { 1, 3, 1, 9, 15, 7, 5, 223, 53, 413, 403, 3003, 4135, 0 }; + static ulong[] dim548JoeKuoD7Init = { 1, 3, 3, 5, 25, 25, 31, 209, 113, 971, 629, 189, 2309, 0 }; + static ulong[] dim549JoeKuoD7Init = { 1, 3, 3, 3, 23, 29, 37, 39, 73, 797, 589, 1351, 4495, 0 }; + static ulong[] dim550JoeKuoD7Init = { 1, 3, 1, 13, 31, 25, 15, 147, 351, 541, 493, 1361, 3151, 0 }; + static ulong[] dim551JoeKuoD7Init = { 1, 3, 5, 9, 31, 45, 43, 125, 503, 987, 1485, 521, 957, 0 }; + static ulong[] dim552JoeKuoD7Init = { 1, 1, 1, 5, 1, 51, 7, 189, 111, 735, 993, 2313, 7027, 0 }; + static ulong[] dim553JoeKuoD7Init = { 1, 1, 7, 1, 5, 11, 123, 241, 325, 337, 1369, 3515, 8077, 0 }; + static ulong[] dim554JoeKuoD7Init = { 1, 3, 3, 13, 9, 57, 89, 89, 439, 803, 545, 1097, 2443, 0 }; + static ulong[] dim555JoeKuoD7Init = { 1, 3, 5, 7, 1, 31, 23, 121, 19, 469, 887, 3925, 6591, 0 }; + static ulong[] dim556JoeKuoD7Init = { 1, 1, 3, 7, 11, 39, 95, 65, 39, 407, 1187, 2803, 643, 0 }; + static ulong[] dim557JoeKuoD7Init = { 1, 3, 7, 3, 23, 43, 97, 39, 463, 929, 469, 255, 7219, 0 }; + static ulong[] dim558JoeKuoD7Init = { 1, 1, 5, 5, 21, 47, 99, 117, 233, 921, 801, 1105, 2993, 0 }; + static ulong[] dim559JoeKuoD7Init = { 1, 3, 7, 5, 7, 1, 33, 61, 389, 969, 389, 2081, 4215, 0 }; + static ulong[] dim560JoeKuoD7Init = { 1, 1, 1, 7, 15, 5, 103, 115, 59, 699, 1287, 3023, 7599, 0 }; + static ulong[] dim561JoeKuoD7Init = { 1, 3, 7, 15, 23, 49, 19, 85, 219, 837, 15, 1213, 1011, 0 }; + static ulong[] dim562JoeKuoD7Init = { 1, 3, 7, 3, 9, 19, 55, 247, 97, 125, 1377, 3107, 1787, 0 }; + static ulong[] dim563JoeKuoD7Init = { 1, 3, 5, 7, 31, 13, 35, 53, 269, 603, 729, 1827, 1083, 0 }; + static ulong[] dim564JoeKuoD7Init = { 1, 1, 5, 11, 7, 55, 81, 61, 3, 119, 995, 1721, 3205, 0 }; + static ulong[] dim565JoeKuoD7Init = { 1, 1, 7, 13, 11, 57, 81, 63, 271, 1001, 1901, 471, 2217, 0 }; + static ulong[] dim566JoeKuoD7Init = { 1, 1, 5, 1, 1, 47, 79, 175, 145, 615, 1393, 137, 589, 0 }; + static ulong[] dim567JoeKuoD7Init = { 1, 1, 7, 11, 25, 47, 93, 81, 157, 913, 1117, 819, 8079, 0 }; + static ulong[] dim568JoeKuoD7Init = { 1, 1, 7, 1, 23, 51, 85, 101, 41, 115, 303, 1721, 6515, 0 }; + static ulong[] dim569JoeKuoD7Init = { 1, 3, 5, 13, 23, 31, 1, 31, 63, 595, 611, 3153, 7865, 0 }; + static ulong[] dim570JoeKuoD7Init = { 1, 1, 1, 9, 17, 35, 53, 53, 421, 537, 557, 2735, 7813, 0 }; + static ulong[] dim571JoeKuoD7Init = { 1, 3, 3, 11, 7, 17, 105, 1, 201, 45, 1517, 3303, 3287, 0 }; + static ulong[] dim572JoeKuoD7Init = { 1, 1, 7, 15, 15, 63, 45, 129, 81, 901, 1735, 3551, 2885, 0 }; + static ulong[] dim573JoeKuoD7Init = { 1, 1, 5, 15, 21, 9, 63, 133, 245, 807, 1425, 961, 7425, 0 }; + static ulong[] dim574JoeKuoD7Init = { 1, 3, 7, 15, 27, 25, 41, 93, 253, 345, 875, 1663, 5713, 0 }; + static ulong[] dim575JoeKuoD7Init = { 1, 3, 1, 1, 9, 61, 117, 183, 381, 739, 1739, 3285, 747, 0 }; + static ulong[] dim576JoeKuoD7Init = { 1, 3, 5, 15, 7, 49, 39, 233, 465, 511, 1853, 637, 6823, 0 }; + static ulong[] dim577JoeKuoD7Init = { 1, 3, 3, 15, 29, 19, 1, 71, 109, 959, 1575, 3225, 3951, 0 }; + static ulong[] dim578JoeKuoD7Init = { 1, 3, 5, 7, 3, 21, 23, 25, 423, 507, 617, 2175, 7331, 0 }; + static ulong[] dim579JoeKuoD7Init = { 1, 1, 5, 5, 31, 19, 111, 139, 217, 301, 1845, 1789, 5935, 0 }; + static ulong[] dim580JoeKuoD7Init = { 1, 3, 1, 11, 19, 63, 53, 47, 493, 181, 709, 3601, 6163, 0 }; + static ulong[] dim581JoeKuoD7Init = { 1, 3, 3, 9, 7, 57, 57, 89, 25, 757, 1959, 285, 2121, 0 }; + static ulong[] dim582JoeKuoD7Init = { 1, 3, 5, 13, 13, 23, 25, 61, 481, 473, 1933, 1861, 881, 0 }; + static ulong[] dim583JoeKuoD7Init = { 1, 3, 1, 15, 11, 27, 53, 243, 439, 221, 1281, 1129, 6685, 0 }; + static ulong[] dim584JoeKuoD7Init = { 1, 1, 3, 7, 11, 55, 11, 99, 153, 517, 985, 3533, 1363, 0 }; + static ulong[] dim585JoeKuoD7Init = { 1, 1, 3, 3, 11, 7, 95, 193, 161, 183, 1417, 187, 4787, 0 }; + static ulong[] dim586JoeKuoD7Init = { 1, 1, 3, 13, 13, 21, 1, 183, 257, 393, 831, 2149, 2219, 0 }; + static ulong[] dim587JoeKuoD7Init = { 1, 1, 3, 9, 1, 19, 9, 95, 65, 57, 1999, 125, 2181, 0 }; + static ulong[] dim588JoeKuoD7Init = { 1, 1, 3, 11, 3, 29, 57, 249, 93, 143, 1163, 2635, 837, 0 }; + static ulong[] dim589JoeKuoD7Init = { 1, 1, 1, 3, 19, 3, 61, 151, 115, 601, 1085, 2505, 4171, 0 }; + static ulong[] dim590JoeKuoD7Init = { 1, 1, 5, 11, 19, 35, 89, 117, 5, 197, 1763, 415, 5455, 0 }; + static ulong[] dim591JoeKuoD7Init = { 1, 3, 3, 13, 1, 41, 77, 127, 93, 785, 269, 915, 5723, 0 }; + static ulong[] dim592JoeKuoD7Init = { 1, 3, 7, 5, 25, 39, 77, 77, 499, 931, 1707, 3401, 5707, 0 }; + static ulong[] dim593JoeKuoD7Init = { 1, 1, 7, 13, 7, 41, 99, 3, 463, 433, 651, 4079, 409, 0 }; + static ulong[] dim594JoeKuoD7Init = { 1, 1, 5, 3, 25, 25, 51, 211, 269, 867, 1403, 517, 4371, 0 }; + static ulong[] dim595JoeKuoD7Init = { 1, 3, 1, 15, 23, 53, 53, 41, 269, 571, 525, 2309, 431, 0 }; + static ulong[] dim596JoeKuoD7Init = { 1, 1, 5, 5, 19, 25, 125, 133, 249, 555, 781, 2853, 2185, 0 }; + static ulong[] dim597JoeKuoD7Init = { 1, 3, 1, 13, 27, 59, 47, 67, 197, 865, 101, 2291, 6219, 0 }; + static ulong[] dim598JoeKuoD7Init = { 1, 1, 7, 7, 5, 43, 95, 209, 407, 821, 215, 2371, 5059, 0 }; + static ulong[] dim599JoeKuoD7Init = { 1, 3, 7, 1, 7, 25, 75, 239, 327, 969, 575, 2519, 3515, 0 }; + static ulong[] dim600JoeKuoD7Init = { 1, 3, 7, 3, 3, 13, 105, 1, 319, 549, 1003, 3441, 185, 0 }; + static ulong[] dim601JoeKuoD7Init = { 1, 3, 7, 9, 29, 17, 75, 95, 407, 199, 1609, 3537, 7293, 0 }; + static ulong[] dim602JoeKuoD7Init = { 1, 1, 5, 7, 15, 27, 39, 175, 431, 905, 925, 3277, 8029, 0 }; + static ulong[] dim603JoeKuoD7Init = { 1, 3, 1, 3, 3, 19, 73, 87, 107, 605, 45, 3267, 3033, 0 }; + static ulong[] dim604JoeKuoD7Init = { 1, 3, 1, 1, 31, 9, 73, 151, 71, 929, 1995, 739, 1483, 0 }; + static ulong[] dim605JoeKuoD7Init = { 1, 1, 7, 3, 7, 55, 27, 177, 225, 333, 663, 4065, 2559, 0 }; + static ulong[] dim606JoeKuoD7Init = { 1, 3, 3, 5, 21, 61, 121, 159, 269, 267, 1307, 1213, 5057, 0 }; + static ulong[] dim607JoeKuoD7Init = { 1, 3, 3, 15, 3, 35, 29, 243, 199, 695, 1225, 3437, 7451, 0 }; + static ulong[] dim608JoeKuoD7Init = { 1, 3, 3, 9, 15, 23, 15, 43, 383, 95, 239, 945, 5339, 0 }; + static ulong[] dim609JoeKuoD7Init = { 1, 1, 5, 9, 23, 11, 81, 93, 493, 435, 1291, 873, 5101, 0 }; + static ulong[] dim610JoeKuoD7Init = { 1, 1, 5, 7, 23, 11, 89, 95, 203, 533, 583, 981, 2029, 0 }; + static ulong[] dim611JoeKuoD7Init = { 1, 1, 7, 3, 27, 57, 59, 161, 361, 511, 1723, 1893, 4113, 0 }; + static ulong[] dim612JoeKuoD7Init = { 1, 3, 7, 15, 27, 5, 7, 213, 509, 483, 1645, 3487, 2927, 0 }; + static ulong[] dim613JoeKuoD7Init = { 1, 3, 5, 13, 17, 47, 87, 25, 331, 793, 1467, 875, 7147, 0 }; + static ulong[] dim614JoeKuoD7Init = { 1, 3, 5, 1, 29, 51, 21, 223, 289, 461, 1153, 579, 2621, 0 }; + static ulong[] dim615JoeKuoD7Init = { 1, 1, 1, 5, 9, 9, 69, 21, 257, 679, 1031, 809, 1633, 0 }; + static ulong[] dim616JoeKuoD7Init = { 1, 1, 3, 13, 3, 59, 27, 193, 507, 407, 831, 1921, 4411, 0 }; + static ulong[] dim617JoeKuoD7Init = { 1, 1, 1, 9, 19, 61, 77, 163, 103, 35, 803, 2327, 7349, 0 }; + static ulong[] dim618JoeKuoD7Init = { 1, 1, 7, 1, 5, 19, 49, 79, 469, 595, 625, 333, 4861, 0 }; + static ulong[] dim619JoeKuoD7Init = { 1, 1, 3, 13, 9, 17, 97, 229, 263, 63, 1907, 2493, 1001, 0 }; + static ulong[] dim620JoeKuoD7Init = { 1, 3, 3, 11, 25, 23, 111, 51, 7, 551, 1669, 2495, 3409, 0 }; + static ulong[] dim621JoeKuoD7Init = { 1, 1, 3, 13, 5, 39, 115, 179, 473, 179, 2047, 467, 5797, 0 }; + static ulong[] dim622JoeKuoD7Init = { 1, 1, 7, 9, 21, 3, 9, 245, 29, 457, 101, 253, 5757, 0 }; + static ulong[] dim623JoeKuoD7Init = { 1, 1, 3, 5, 1, 11, 123, 29, 43, 259, 1387, 2973, 2509, 0 }; + static ulong[] dim624JoeKuoD7Init = { 1, 3, 7, 9, 15, 35, 85, 165, 91, 793, 1963, 595, 1721, 0 }; + static ulong[] dim625JoeKuoD7Init = { 1, 3, 7, 11, 29, 29, 79, 33, 439, 635, 1639, 803, 847, 0 }; + static ulong[] dim626JoeKuoD7Init = { 1, 1, 3, 5, 29, 9, 121, 239, 33, 535, 1957, 1459, 7997, 0 }; + static ulong[] dim627JoeKuoD7Init = { 1, 3, 1, 9, 7, 15, 11, 91, 495, 939, 1597, 4011, 97, 0 }; + static ulong[] dim628JoeKuoD7Init = { 1, 3, 5, 7, 27, 1, 115, 29, 345, 665, 1433, 3291, 1431, 0 }; + static ulong[] dim629JoeKuoD7Init = { 1, 3, 5, 11, 21, 27, 127, 55, 401, 787, 405, 715, 5385, 0 }; + static ulong[] dim630JoeKuoD7Init = { 1, 3, 5, 7, 7, 59, 109, 221, 179, 217, 1045, 1979, 4003, 0 }; + static ulong[] dim631JoeKuoD7Init = { 1, 1, 5, 9, 17, 57, 73, 219, 369, 235, 43, 65, 919, 0 }; + static ulong[] dim632JoeKuoD7Init = { 1, 3, 3, 13, 19, 29, 73, 7, 405, 691, 1007, 341, 7153, 0 }; + static ulong[] dim633JoeKuoD7Init = { 1, 1, 1, 9, 1, 17, 67, 101, 33, 851, 1227, 41, 8057, 0 }; + static ulong[] dim634JoeKuoD7Init = { 1, 1, 3, 15, 21, 37, 43, 161, 63, 27, 855, 3983, 7661, 0 }; + static ulong[] dim635JoeKuoD7Init = { 1, 3, 3, 3, 25, 11, 85, 127, 309, 979, 1071, 3485, 3513, 0 }; + static ulong[] dim636JoeKuoD7Init = { 1, 1, 1, 1, 21, 51, 37, 87, 71, 923, 1983, 1013, 4677, 0 }; + static ulong[] dim637JoeKuoD7Init = { 1, 1, 1, 3, 29, 13, 93, 193, 207, 229, 185, 2109, 8085, 0 }; + static ulong[] dim638JoeKuoD7Init = { 1, 3, 5, 5, 15, 43, 101, 27, 185, 541, 1371, 1487, 11, 0 }; + static ulong[] dim639JoeKuoD7Init = { 1, 1, 7, 7, 11, 35, 83, 163, 3, 391, 343, 2931, 1183, 0 }; + static ulong[] dim640JoeKuoD7Init = { 1, 1, 1, 7, 5, 1, 109, 195, 389, 679, 571, 121, 2669, 0 }; + static ulong[] dim641JoeKuoD7Init = { 1, 1, 5, 13, 11, 11, 47, 105, 389, 661, 113, 2849, 2861, 0 }; + static ulong[] dim642JoeKuoD7Init = { 1, 3, 7, 7, 27, 3, 33, 105, 81, 817, 691, 1017, 4477, 0 }; + static ulong[] dim643JoeKuoD7Init = { 1, 3, 7, 15, 19, 63, 11, 179, 473, 695, 1033, 363, 1479, 0 }; + static ulong[] dim644JoeKuoD7Init = { 1, 1, 1, 5, 23, 33, 121, 101, 349, 599, 1821, 3975, 263, 0 }; + static ulong[] dim645JoeKuoD7Init = { 1, 3, 1, 11, 21, 1, 115, 123, 367, 497, 609, 1473, 515, 0 }; + static ulong[] dim646JoeKuoD7Init = { 1, 3, 5, 5, 13, 49, 63, 63, 137, 39, 1281, 1289, 6687, 0 }; + static ulong[] dim647JoeKuoD7Init = { 1, 3, 3, 3, 9, 49, 11, 205, 451, 163, 125, 2639, 1921, 0 }; + static ulong[] dim648JoeKuoD7Init = { 1, 1, 7, 5, 5, 29, 67, 33, 169, 133, 599, 2559, 6495, 0 }; + static ulong[] dim649JoeKuoD7Init = { 1, 3, 5, 13, 21, 47, 119, 39, 389, 695, 717, 1003, 4107, 0 }; + static ulong[] dim650JoeKuoD7Init = { 1, 1, 1, 7, 23, 49, 113, 245, 485, 291, 1431, 3577, 1787, 0 }; + static ulong[] dim651JoeKuoD7Init = { 1, 1, 5, 11, 27, 59, 127, 205, 177, 73, 935, 2041, 6899, 0 }; + static ulong[] dim652JoeKuoD7Init = { 1, 3, 7, 13, 27, 41, 115, 121, 239, 939, 1963, 2045, 2457, 0 }; + static ulong[] dim653JoeKuoD7Init = { 1, 3, 1, 11, 23, 51, 13, 177, 51, 145, 651, 3817, 2399, 0 }; + static ulong[] dim654JoeKuoD7Init = { 1, 3, 1, 3, 11, 35, 119, 251, 303, 673, 1475, 1415, 3809, 0 }; + static ulong[] dim655JoeKuoD7Init = { 1, 1, 3, 3, 31, 25, 117, 87, 19, 491, 1681, 2291, 3559, 0 }; + static ulong[] dim656JoeKuoD7Init = { 1, 1, 3, 15, 25, 13, 83, 243, 499, 77, 1809, 81, 4211, 0 }; + static ulong[] dim657JoeKuoD7Init = { 1, 1, 7, 3, 27, 7, 119, 141, 305, 323, 1679, 1143, 2277, 0 }; + static ulong[] dim658JoeKuoD7Init = { 1, 3, 1, 7, 27, 31, 31, 219, 55, 437, 1113, 2801, 1409, 0 }; + static ulong[] dim659JoeKuoD7Init = { 1, 3, 5, 7, 25, 51, 77, 255, 211, 265, 1597, 3883, 5913, 0 }; + static ulong[] dim660JoeKuoD7Init = { 1, 3, 3, 1, 23, 55, 21, 243, 329, 221, 901, 1363, 1449, 0 }; + static ulong[] dim661JoeKuoD7Init = { 1, 1, 7, 3, 7, 53, 63, 143, 503, 295, 135, 4037, 6363, 0 }; + static ulong[] dim662JoeKuoD7Init = { 1, 3, 1, 7, 7, 35, 7, 19, 437, 361, 807, 277, 6335, 0 }; + static ulong[] dim663JoeKuoD7Init = { 1, 3, 5, 5, 5, 53, 121, 219, 447, 453, 1001, 339, 3959, 0 }; + static ulong[] dim664JoeKuoD7Init = { 1, 1, 7, 13, 27, 29, 107, 255, 385, 539, 1787, 3091, 6319, 0 }; + static ulong[] dim665JoeKuoD7Init = { 1, 1, 3, 5, 1, 57, 15, 93, 331, 155, 107, 3295, 7081, 0 }; + static ulong[] dim666JoeKuoD7Init = { 1, 1, 5, 15, 1, 35, 57, 249, 171, 309, 1413, 2677, 1593, 0 }; + static ulong[] dim667JoeKuoD7Init = { 1, 1, 7, 7, 27, 51, 107, 233, 163, 317, 1815, 2443, 3431, 0 }; + static ulong[] dim668JoeKuoD7Init = { 1, 1, 3, 5, 13, 31, 119, 25, 339, 671, 1143, 2317, 1963, 0 }; + static ulong[] dim669JoeKuoD7Init = { 1, 3, 7, 11, 15, 39, 15, 135, 183, 445, 1607, 2397, 7609, 0 }; + static ulong[] dim670JoeKuoD7Init = { 1, 3, 5, 7, 13, 61, 29, 5, 309, 1009, 1241, 3471, 4505, 0 }; + static ulong[] dim671JoeKuoD7Init = { 1, 1, 7, 9, 7, 39, 13, 67, 421, 169, 1751, 2939, 3315, 0 }; + static ulong[] dim672JoeKuoD7Init = { 1, 1, 7, 9, 5, 35, 91, 59, 195, 621, 449, 2245, 3379, 0 }; + static ulong[] dim673JoeKuoD7Init = { 1, 1, 3, 9, 27, 23, 87, 181, 171, 37, 1137, 597, 7443, 0 }; + static ulong[] dim674JoeKuoD7Init = { 1, 1, 1, 13, 15, 41, 109, 81, 149, 709, 1537, 2349, 3999, 0 }; + static ulong[] dim675JoeKuoD7Init = { 1, 3, 1, 3, 9, 27, 93, 211, 239, 391, 411, 1329, 4213, 0 }; + static ulong[] dim676JoeKuoD7Init = { 1, 3, 5, 15, 9, 33, 19, 105, 89, 181, 157, 461, 6505, 0 }; + static ulong[] dim677JoeKuoD7Init = { 1, 3, 5, 15, 15, 3, 113, 79, 49, 463, 299, 1621, 2719, 0 }; + static ulong[] dim678JoeKuoD7Init = { 1, 1, 5, 13, 23, 13, 57, 161, 347, 483, 1521, 3611, 4111, 0 }; + static ulong[] dim679JoeKuoD7Init = { 1, 1, 7, 13, 15, 21, 79, 145, 329, 649, 1809, 1925, 7157, 0 }; + static ulong[] dim680JoeKuoD7Init = { 1, 1, 3, 1, 29, 5, 35, 229, 375, 789, 481, 1863, 6467, 0 }; + static ulong[] dim681JoeKuoD7Init = { 1, 3, 7, 15, 1, 19, 39, 3, 327, 721, 1763, 963, 4397, 0 }; + static ulong[] dim682JoeKuoD7Init = { 1, 3, 1, 3, 3, 51, 97, 1, 109, 337, 535, 2795, 1155, 0 }; + static ulong[] dim683JoeKuoD7Init = { 1, 3, 5, 13, 5, 55, 91, 147, 395, 141, 947, 2647, 1193, 0 }; + static ulong[] dim684JoeKuoD7Init = { 1, 1, 7, 11, 31, 49, 71, 175, 231, 81, 155, 3257, 173, 0 }; + static ulong[] dim685JoeKuoD7Init = { 1, 3, 5, 13, 15, 27, 71, 43, 267, 611, 2041, 1127, 3905, 0 }; + static ulong[] dim686JoeKuoD7Init = { 1, 1, 7, 15, 3, 63, 25, 129, 409, 837, 1601, 2387, 5063, 0 }; + static ulong[] dim687JoeKuoD7Init = { 1, 3, 3, 7, 19, 63, 27, 141, 423, 751, 669, 1945, 3015, 0 }; + static ulong[] dim688JoeKuoD7Init = { 1, 1, 3, 11, 15, 59, 103, 123, 49, 71, 929, 3495, 3591, 0 }; + static ulong[] dim689JoeKuoD7Init = { 1, 1, 3, 5, 9, 17, 49, 3, 67, 63, 1645, 585, 83, 0 }; + static ulong[] dim690JoeKuoD7Init = { 1, 3, 3, 3, 25, 7, 103, 109, 241, 501, 2043, 139, 3865, 0 }; + static ulong[] dim691JoeKuoD7Init = { 1, 3, 1, 5, 19, 41, 35, 223, 351, 853, 961, 2963, 3315, 0 }; + static ulong[] dim692JoeKuoD7Init = { 1, 1, 3, 11, 9, 61, 103, 95, 393, 131, 611, 177, 635, 0 }; + static ulong[] dim693JoeKuoD7Init = { 1, 1, 7, 9, 15, 27, 107, 35, 211, 299, 923, 2629, 2585, 0 }; + static ulong[] dim694JoeKuoD7Init = { 1, 1, 3, 3, 9, 57, 89, 161, 323, 123, 1969, 3545, 5149, 0 }; + static ulong[] dim695JoeKuoD7Init = { 1, 3, 7, 9, 25, 15, 39, 7, 81, 503, 1549, 227, 7267, 0 }; + static ulong[] dim696JoeKuoD7Init = { 1, 1, 1, 1, 29, 41, 77, 131, 181, 555, 1165, 563, 5197, 0 }; + static ulong[] dim697JoeKuoD7Init = { 1, 3, 3, 11, 15, 11, 69, 183, 113, 651, 1265, 1741, 8025, 0 }; + static ulong[] dim698JoeKuoD7Init = { 1, 3, 7, 13, 15, 61, 113, 181, 305, 669, 1903, 575, 6561, 0 }; + static ulong[] dim699JoeKuoD7Init = { 1, 1, 3, 1, 27, 63, 103, 21, 387, 803, 1611, 1793, 1011, 0 }; + static ulong[] dim700JoeKuoD7Init = { 1, 1, 1, 9, 19, 41, 61, 153, 387, 509, 1771, 1715, 4643, 0 }; + static ulong[] dim701JoeKuoD7Init = { 1, 3, 1, 9, 9, 23, 99, 157, 185, 457, 1485, 3153, 6361, 0 }; + static ulong[] dim702JoeKuoD7Init = { 1, 1, 3, 9, 15, 3, 71, 95, 353, 549, 1269, 3451, 403, 0 }; + static ulong[] dim703JoeKuoD7Init = { 1, 3, 5, 5, 17, 45, 49, 249, 185, 367, 1499, 2921, 7485, 0 }; + static ulong[] dim704JoeKuoD7Init = { 1, 3, 1, 13, 1, 61, 57, 95, 213, 333, 603, 697, 6737, 0 }; + static ulong[] dim705JoeKuoD7Init = { 1, 1, 1, 7, 31, 37, 45, 71, 339, 629, 1181, 979, 1473, 0 }; + static ulong[] dim706JoeKuoD7Init = { 1, 3, 7, 5, 7, 5, 9, 139, 89, 683, 569, 1887, 2173, 0 }; + static ulong[] dim707JoeKuoD7Init = { 1, 3, 1, 11, 19, 7, 33, 65, 299, 791, 1281, 3793, 7019, 0 }; + static ulong[] dim708JoeKuoD7Init = { 1, 3, 7, 7, 5, 45, 11, 247, 335, 199, 17, 2829, 2811, 0 }; + static ulong[] dim709JoeKuoD7Init = { 1, 1, 7, 7, 9, 37, 17, 37, 385, 81, 1455, 1921, 6957, 0 }; + static ulong[] dim710JoeKuoD7Init = { 1, 1, 1, 1, 23, 53, 13, 7, 475, 167, 1573, 2235, 4097, 0 }; + static ulong[] dim711JoeKuoD7Init = { 1, 3, 3, 9, 23, 53, 107, 63, 457, 723, 53, 3025, 3153, 0 }; + static ulong[] dim712JoeKuoD7Init = { 1, 3, 1, 5, 21, 39, 1, 123, 293, 275, 1441, 2897, 4645, 0 }; + static ulong[] dim713JoeKuoD7Init = { 1, 3, 3, 7, 21, 5, 93, 63, 427, 47, 559, 2383, 4137, 0 }; + static ulong[] dim714JoeKuoD7Init = { 1, 3, 3, 1, 13, 39, 81, 63, 353, 937, 679, 79, 3319, 0 }; + static ulong[] dim715JoeKuoD7Init = { 1, 1, 7, 3, 19, 3, 57, 207, 115, 439, 835, 389, 4413, 0 }; + static ulong[] dim716JoeKuoD7Init = { 1, 3, 5, 7, 21, 57, 81, 137, 265, 845, 843, 3083, 4453, 0 }; + static ulong[] dim717JoeKuoD7Init = { 1, 1, 1, 13, 13, 29, 77, 181, 483, 871, 1739, 3859, 5005, 0 }; + static ulong[] dim718JoeKuoD7Init = { 1, 1, 1, 13, 9, 45, 73, 73, 427, 783, 617, 1771, 5953, 0 }; + static ulong[] dim719JoeKuoD7Init = { 1, 1, 5, 13, 31, 39, 83, 17, 275, 419, 1405, 3189, 7751, 0 }; + static ulong[] dim720JoeKuoD7Init = { 1, 1, 5, 13, 15, 17, 15, 67, 455, 477, 1911, 2225, 4095, 0 }; + static ulong[] dim721JoeKuoD7Init = { 1, 1, 1, 1, 5, 39, 73, 205, 331, 819, 1499, 1243, 7369, 0 }; + static ulong[] dim722JoeKuoD7Init = { 1, 1, 1, 1, 1, 49, 11, 167, 489, 169, 1683, 2999, 4371, 0 }; + static ulong[] dim723JoeKuoD7Init = { 1, 1, 7, 9, 13, 7, 29, 105, 155, 85, 1311, 617, 1793, 0 }; + static ulong[] dim724JoeKuoD7Init = { 1, 1, 5, 5, 13, 3, 71, 27, 83, 145, 89, 691, 1081, 0 }; + static ulong[] dim725JoeKuoD7Init = { 1, 1, 1, 1, 9, 43, 23, 63, 43, 263, 1849, 1963, 1043, 0 }; + static ulong[] dim726JoeKuoD7Init = { 1, 3, 3, 1, 25, 15, 17, 211, 453, 385, 349, 789, 787, 0 }; + static ulong[] dim727JoeKuoD7Init = { 1, 3, 5, 11, 1, 63, 83, 63, 317, 841, 1779, 669, 253, 0 }; + static ulong[] dim728JoeKuoD7Init = { 1, 3, 3, 5, 7, 49, 67, 69, 167, 29, 217, 1759, 6167, 0 }; + static ulong[] dim729JoeKuoD7Init = { 1, 1, 7, 1, 15, 63, 43, 3, 183, 577, 1301, 1479, 4189, 0 }; + static ulong[] dim730JoeKuoD7Init = { 1, 3, 1, 13, 29, 57, 103, 253, 45, 661, 1593, 1993, 523, 0 }; + static ulong[] dim731JoeKuoD7Init = { 1, 3, 3, 15, 25, 17, 11, 71, 213, 287, 627, 2699, 4909, 0 }; + static ulong[] dim732JoeKuoD7Init = { 1, 1, 3, 9, 11, 53, 117, 59, 225, 469, 109, 583, 4677, 0 }; + static ulong[] dim733JoeKuoD7Init = { 1, 3, 7, 15, 27, 41, 109, 37, 153, 885, 1339, 2783, 7833, 0 }; + static ulong[] dim734JoeKuoD7Init = { 1, 3, 1, 7, 5, 47, 5, 233, 507, 953, 1359, 2505, 6943, 0 }; + static ulong[] dim735JoeKuoD7Init = { 1, 1, 7, 5, 11, 21, 33, 207, 17, 621, 1943, 597, 3993, 0 }; + static ulong[] dim736JoeKuoD7Init = { 1, 3, 5, 3, 13, 55, 11, 247, 321, 533, 715, 2941, 6435, 0 }; + static ulong[] dim737JoeKuoD7Init = { 1, 3, 7, 15, 19, 3, 59, 1, 473, 17, 691, 747, 3917, 0 }; + static ulong[] dim738JoeKuoD7Init = { 1, 3, 7, 1, 25, 49, 11, 185, 185, 821, 1857, 3927, 2641, 0 }; + static ulong[] dim739JoeKuoD7Init = { 1, 1, 1, 11, 27, 31, 47, 33, 63, 935, 1709, 1495, 3869, 0 }; + static ulong[] dim740JoeKuoD7Init = { 1, 3, 3, 3, 23, 35, 73, 171, 207, 535, 751, 3693, 3015, 0 }; + static ulong[] dim741JoeKuoD7Init = { 1, 3, 5, 9, 11, 9, 101, 183, 83, 507, 15, 3993, 3631, 0 }; + static ulong[] dim742JoeKuoD7Init = { 1, 1, 3, 1, 5, 13, 41, 239, 355, 463, 997, 1163, 651, 0 }; + static ulong[] dim743JoeKuoD7Init = { 1, 1, 1, 11, 19, 25, 21, 233, 315, 1009, 1433, 2281, 4685, 0 }; + static ulong[] dim744JoeKuoD7Init = { 1, 1, 5, 5, 17, 11, 31, 47, 47, 873, 1957, 2307, 1757, 0 }; + static ulong[] dim745JoeKuoD7Init = { 1, 1, 3, 15, 1, 43, 93, 27, 315, 357, 787, 3843, 4615, 0 }; + static ulong[] dim746JoeKuoD7Init = { 1, 3, 1, 13, 13, 41, 67, 137, 241, 707, 1207, 1923, 2753, 0 }; + static ulong[] dim747JoeKuoD7Init = { 1, 1, 1, 3, 1, 15, 21, 175, 21, 917, 625, 543, 7235, 0 }; + static ulong[] dim748JoeKuoD7Init = { 1, 1, 7, 15, 3, 49, 97, 195, 443, 689, 1393, 2385, 4111, 0 }; + static ulong[] dim749JoeKuoD7Init = { 1, 1, 1, 3, 19, 53, 55, 243, 491, 213, 1371, 3867, 5323, 0 }; + static ulong[] dim750JoeKuoD7Init = { 1, 3, 1, 1, 9, 47, 7, 169, 151, 53, 1481, 3689, 2539, 0 }; + static ulong[] dim751JoeKuoD7Init = { 1, 1, 7, 9, 31, 7, 49, 27, 57, 769, 687, 1007, 3619, 0 }; + static ulong[] dim752JoeKuoD7Init = { 1, 3, 3, 9, 1, 49, 29, 153, 273, 965, 719, 4023, 1755, 0 }; + static ulong[] dim753JoeKuoD7Init = { 1, 3, 7, 1, 23, 29, 85, 179, 137, 237, 1639, 3759, 5533, 0 }; + static ulong[] dim754JoeKuoD7Init = { 1, 3, 1, 3, 7, 3, 1, 107, 259, 827, 799, 2677, 1677, 0 }; + static ulong[] dim755JoeKuoD7Init = { 1, 1, 1, 5, 9, 51, 89, 255, 97, 419, 703, 3903, 833, 0 }; + static ulong[] dim756JoeKuoD7Init = { 1, 3, 5, 3, 21, 27, 115, 75, 329, 747, 1949, 1309, 3611, 0 }; + static ulong[] dim757JoeKuoD7Init = { 1, 3, 1, 3, 13, 3, 21, 5, 337, 757, 1765, 667, 5607, 0 }; + static ulong[] dim758JoeKuoD7Init = { 1, 1, 5, 1, 19, 29, 113, 7, 51, 283, 1987, 3939, 583, 0 }; + static ulong[] dim759JoeKuoD7Init = { 1, 1, 3, 3, 23, 13, 9, 187, 251, 899, 85, 701, 2597, 0 }; + static ulong[] dim760JoeKuoD7Init = { 1, 3, 3, 7, 1, 15, 83, 183, 471, 533, 1119, 3157, 827, 0 }; + static ulong[] dim761JoeKuoD7Init = { 1, 3, 7, 11, 27, 49, 117, 57, 337, 603, 1247, 3957, 1739, 0 }; + static ulong[] dim762JoeKuoD7Init = { 1, 1, 1, 9, 29, 23, 123, 215, 479, 459, 361, 305, 237, 0 }; + static ulong[] dim763JoeKuoD7Init = { 1, 3, 5, 11, 1, 27, 103, 241, 493, 441, 1171, 3625, 3369, 0 }; + static ulong[] dim764JoeKuoD7Init = { 1, 3, 3, 9, 15, 59, 13, 225, 485, 493, 97, 2705, 7077, 0 }; + static ulong[] dim765JoeKuoD7Init = { 1, 3, 3, 1, 5, 27, 85, 135, 451, 745, 613, 1443, 6047, 0 }; + static ulong[] dim766JoeKuoD7Init = { 1, 1, 5, 7, 5, 41, 57, 167, 105, 721, 365, 833, 4485, 0 }; + static ulong[] dim767JoeKuoD7Init = { 1, 1, 3, 1, 19, 13, 119, 161, 475, 935, 1707, 2971, 6797, 0 }; + static ulong[] dim768JoeKuoD7Init = { 1, 3, 1, 15, 19, 59, 23, 29, 339, 671, 2027, 545, 6197, 0 }; + static ulong[] dim769JoeKuoD7Init = { 1, 1, 7, 3, 7, 41, 3, 169, 479, 567, 865, 2481, 3979, 0 }; + static ulong[] dim770JoeKuoD7Init = { 1, 3, 1, 13, 25, 23, 59, 175, 17, 291, 1283, 1405, 4939, 0 }; + static ulong[] dim771JoeKuoD7Init = { 1, 1, 1, 13, 13, 21, 127, 75, 275, 549, 971, 2019, 199, 0 }; + static ulong[] dim772JoeKuoD7Init = { 1, 1, 3, 3, 9, 61, 47, 23, 51, 589, 73, 265, 7315, 0 }; + static ulong[] dim773JoeKuoD7Init = { 1, 1, 5, 1, 3, 21, 15, 33, 443, 831, 375, 3045, 4215, 0 }; + static ulong[] dim774JoeKuoD7Init = { 1, 1, 7, 1, 27, 47, 123, 9, 131, 487, 393, 2959, 1509, 0 }; + static ulong[] dim775JoeKuoD7Init = { 1, 3, 7, 9, 15, 49, 61, 77, 65, 411, 293, 3827, 5723, 0 }; + static ulong[] dim776JoeKuoD7Init = { 1, 3, 7, 9, 17, 33, 97, 207, 227, 679, 1157, 1237, 2203, 0 }; + static ulong[] dim777JoeKuoD7Init = { 1, 1, 5, 1, 31, 31, 23, 59, 363, 225, 827, 2757, 1979, 0 }; + static ulong[] dim778JoeKuoD7Init = { 1, 1, 1, 11, 13, 31, 19, 27, 225, 901, 727, 2491, 3075, 0 }; + static ulong[] dim779JoeKuoD7Init = { 1, 3, 7, 9, 17, 9, 63, 117, 331, 887, 407, 111, 125, 0 }; + static ulong[] dim780JoeKuoD7Init = { 1, 3, 3, 13, 5, 25, 37, 61, 241, 15, 559, 1981, 3585, 0 }; + static ulong[] dim781JoeKuoD7Init = { 1, 1, 3, 9, 13, 57, 9, 189, 135, 485, 105, 327, 7233, 0 }; + static ulong[] dim782JoeKuoD7Init = { 1, 3, 7, 11, 11, 37, 13, 139, 93, 233, 1171, 165, 4151, 0 }; + static ulong[] dim783JoeKuoD7Init = { 1, 1, 3, 9, 7, 61, 81, 243, 111, 681, 859, 2163, 7019, 0 }; + static ulong[] dim784JoeKuoD7Init = { 1, 3, 1, 5, 31, 57, 85, 105, 323, 729, 131, 2055, 1893, 0 }; + static ulong[] dim785JoeKuoD7Init = { 1, 3, 7, 15, 17, 55, 35, 211, 341, 281, 613, 697, 6479, 0 }; + static ulong[] dim786JoeKuoD7Init = { 1, 1, 1, 1, 9, 35, 107, 47, 243, 917, 683, 1333, 7797, 0 }; + static ulong[] dim787JoeKuoD7Init = { 1, 3, 5, 7, 31, 15, 9, 11, 109, 509, 973, 3817, 2877, 0 }; + static ulong[] dim788JoeKuoD7Init = { 1, 1, 3, 15, 31, 21, 43, 79, 367, 201, 549, 1335, 7231, 0 }; + static ulong[] dim789JoeKuoD7Init = { 1, 1, 3, 5, 23, 21, 63, 207, 333, 395, 925, 705, 8143, 0 }; + static ulong[] dim790JoeKuoD7Init = { 1, 3, 7, 5, 13, 23, 93, 123, 317, 511, 867, 1791, 5621, 0 }; + static ulong[] dim791JoeKuoD7Init = { 1, 3, 3, 3, 1, 1, 61, 133, 23, 885, 1281, 3115, 2717, 0 }; + static ulong[] dim792JoeKuoD7Init = { 1, 3, 7, 13, 5, 3, 59, 59, 453, 787, 1933, 2813, 6405, 0 }; + static ulong[] dim793JoeKuoD7Init = { 1, 3, 7, 9, 7, 39, 85, 65, 33, 85, 1597, 17, 3779, 0 }; + static ulong[] dim794JoeKuoD7Init = { 1, 1, 7, 1, 3, 33, 85, 129, 249, 845, 1481, 3249, 7207, 0 }; + static ulong[] dim795JoeKuoD7Init = { 1, 1, 7, 3, 9, 5, 51, 79, 241, 173, 567, 3047, 6779, 0 }; + static ulong[] dim796JoeKuoD7Init = { 1, 3, 1, 1, 1, 49, 29, 243, 95, 609, 1887, 407, 7875, 0 }; + static ulong[] dim797JoeKuoD7Init = { 1, 1, 1, 15, 29, 55, 69, 171, 337, 701, 1255, 1889, 3365, 0 }; + static ulong[] dim798JoeKuoD7Init = { 1, 1, 1, 5, 11, 27, 3, 167, 325, 397, 545, 2097, 1323, 0 }; + static ulong[] dim799JoeKuoD7Init = { 1, 1, 1, 11, 7, 3, 17, 47, 227, 573, 713, 975, 5991, 0 }; + static ulong[] dim800JoeKuoD7Init = { 1, 3, 1, 15, 7, 55, 71, 41, 195, 227, 821, 3209, 1363, 0 }; + static ulong[] dim801JoeKuoD7Init = { 1, 1, 1, 9, 7, 49, 105, 5, 441, 629, 201, 2951, 5757, 0 }; + static ulong[] dim802JoeKuoD7Init = { 1, 1, 1, 7, 13, 5, 5, 31, 355, 107, 1937, 3553, 697, 0 }; + static ulong[] dim803JoeKuoD7Init = { 1, 3, 3, 7, 23, 59, 109, 185, 289, 257, 1055, 3221, 6445, 0 }; + static ulong[] dim804JoeKuoD7Init = { 1, 3, 7, 7, 3, 27, 61, 85, 383, 93, 639, 1113, 1511, 0 }; + static ulong[] dim805JoeKuoD7Init = { 1, 3, 3, 7, 17, 29, 31, 255, 57, 557, 721, 4015, 7587, 0 }; + static ulong[] dim806JoeKuoD7Init = { 1, 1, 7, 9, 23, 15, 89, 85, 201, 177, 571, 2691, 4521, 0 }; + static ulong[] dim807JoeKuoD7Init = { 1, 1, 5, 9, 9, 25, 91, 75, 405, 13, 587, 2299, 7879, 0 }; + static ulong[] dim808JoeKuoD7Init = { 1, 1, 5, 15, 3, 59, 109, 175, 411, 309, 787, 2979, 5385, 0 }; + static ulong[] dim809JoeKuoD7Init = { 1, 3, 5, 1, 9, 21, 109, 109, 179, 955, 423, 3637, 3283, 0 }; + static ulong[] dim810JoeKuoD7Init = { 1, 3, 1, 1, 7, 51, 31, 83, 273, 545, 1063, 1463, 1857, 0 }; + static ulong[] dim811JoeKuoD7Init = { 1, 3, 5, 9, 1, 51, 49, 241, 365, 423, 1299, 3533, 1771, 0 }; + static ulong[] dim812JoeKuoD7Init = { 1, 1, 7, 15, 25, 21, 95, 221, 65, 335, 697, 759, 4331, 0 }; + static ulong[] dim813JoeKuoD7Init = { 1, 1, 5, 11, 15, 53, 17, 7, 461, 543, 233, 3993, 725, 0 }; + static ulong[] dim814JoeKuoD7Init = { 1, 3, 5, 1, 13, 3, 53, 213, 5, 709, 883, 3261, 855, 0 }; + static ulong[] dim815JoeKuoD7Init = { 1, 3, 1, 13, 1, 33, 61, 255, 385, 793, 525, 929, 4263, 0 }; + static ulong[] dim816JoeKuoD7Init = { 1, 1, 1, 11, 1, 33, 97, 235, 427, 1021, 1683, 2821, 1347, 0 }; + static ulong[] dim817JoeKuoD7Init = { 1, 3, 1, 9, 15, 7, 39, 163, 13, 535, 1259, 653, 7359, 0 }; + static ulong[] dim818JoeKuoD7Init = { 1, 3, 5, 15, 31, 27, 19, 255, 341, 509, 1775, 1493, 6977, 0 }; + static ulong[] dim819JoeKuoD7Init = { 1, 1, 5, 15, 3, 23, 53, 221, 271, 729, 1013, 101, 2837, 0 }; + static ulong[] dim820JoeKuoD7Init = { 1, 1, 7, 3, 19, 63, 83, 149, 385, 813, 1783, 4021, 3645, 0 }; + static ulong[] dim821JoeKuoD7Init = { 1, 1, 5, 7, 11, 57, 121, 97, 479, 33, 579, 1009, 1821, 0 }; + static ulong[] dim822JoeKuoD7Init = { 1, 3, 5, 15, 5, 25, 69, 159, 441, 661, 151, 103, 2659, 0 }; + static ulong[] dim823JoeKuoD7Init = { 1, 1, 5, 7, 11, 7, 15, 159, 19, 457, 1873, 3017, 3927, 0 }; + static ulong[] dim824JoeKuoD7Init = { 1, 1, 5, 11, 9, 43, 73, 187, 107, 603, 387, 3713, 853, 0 }; + static ulong[] dim825JoeKuoD7Init = { 1, 1, 1, 15, 29, 55, 87, 247, 283, 11, 927, 3313, 5147, 0 }; + static ulong[] dim826JoeKuoD7Init = { 1, 1, 1, 5, 27, 25, 1, 123, 19, 237, 1171, 1731, 7079, 0 }; + static ulong[] dim827JoeKuoD7Init = { 1, 1, 5, 7, 29, 43, 15, 91, 61, 329, 1343, 1349, 471, 0 }; + static ulong[] dim828JoeKuoD7Init = { 1, 3, 7, 11, 11, 7, 25, 143, 277, 791, 775, 3711, 7115, 0 }; + static ulong[] dim829JoeKuoD7Init = { 1, 1, 5, 5, 29, 27, 53, 241, 399, 165, 1347, 1661, 4495, 0 }; + static ulong[] dim830JoeKuoD7Init = { 1, 3, 7, 3, 21, 7, 73, 61, 155, 635, 1095, 3295, 7109, 0 }; + static ulong[] dim831JoeKuoD7Init = { 1, 1, 3, 11, 5, 39, 11, 167, 317, 317, 161, 2141, 1327, 0 }; + static ulong[] dim832JoeKuoD7Init = { 1, 1, 1, 7, 23, 45, 59, 13, 107, 47, 2001, 1491, 4463, 0 }; + static ulong[] dim833JoeKuoD7Init = { 1, 3, 3, 15, 27, 63, 41, 143, 503, 711, 277, 2523, 6331, 0 }; + static ulong[] dim834JoeKuoD7Init = { 1, 1, 1, 15, 13, 49, 121, 107, 145, 769, 699, 3793, 2333, 0 }; + static ulong[] dim835JoeKuoD7Init = { 1, 1, 1, 11, 17, 7, 57, 139, 17, 433, 1053, 1279, 833, 0 }; + static ulong[] dim836JoeKuoD7Init = { 1, 3, 7, 3, 21, 19, 61, 229, 271, 831, 495, 1663, 2109, 0 }; + static ulong[] dim837JoeKuoD7Init = { 1, 3, 3, 11, 17, 27, 23, 153, 151, 309, 1935, 3993, 4149, 0 }; + static ulong[] dim838JoeKuoD7Init = { 1, 3, 1, 1, 11, 29, 33, 77, 357, 543, 217, 893, 2989, 0 }; + static ulong[] dim839JoeKuoD7Init = { 1, 3, 3, 13, 21, 25, 121, 211, 491, 983, 1395, 2879, 1173, 0 }; + static ulong[] dim840JoeKuoD7Init = { 1, 1, 1, 11, 31, 61, 45, 125, 21, 175, 1869, 403, 579, 0 }; + static ulong[] dim841JoeKuoD7Init = { 1, 3, 1, 11, 27, 5, 47, 211, 149, 753, 301, 933, 3339, 0 }; + static ulong[] dim842JoeKuoD7Init = { 1, 1, 5, 15, 7, 57, 105, 243, 27, 629, 337, 1917, 2653, 0 }; + static ulong[] dim843JoeKuoD7Init = { 1, 1, 1, 1, 27, 27, 45, 39, 249, 167, 2031, 3427, 6051, 0 }; + static ulong[] dim844JoeKuoD7Init = { 1, 1, 5, 5, 9, 13, 55, 167, 473, 371, 677, 2171, 1859, 0 }; + static ulong[] dim845JoeKuoD7Init = { 1, 3, 7, 13, 21, 49, 25, 193, 507, 531, 1639, 3181, 2763, 0 }; + static ulong[] dim846JoeKuoD7Init = { 1, 3, 3, 11, 15, 3, 115, 163, 63, 383, 835, 2507, 5525, 0 }; + static ulong[] dim847JoeKuoD7Init = { 1, 1, 1, 1, 1, 63, 59, 75, 293, 609, 59, 1729, 4909, 0 }; + static ulong[] dim848JoeKuoD7Init = { 1, 1, 1, 15, 11, 57, 59, 109, 465, 285, 1973, 505, 4447, 0 }; + static ulong[] dim849JoeKuoD7Init = { 1, 1, 1, 13, 11, 63, 87, 149, 185, 493, 831, 2927, 11, 0 }; + static ulong[] dim850JoeKuoD7Init = { 1, 1, 3, 3, 3, 19, 111, 199, 371, 411, 659, 1191, 6279, 0 }; + static ulong[] dim851JoeKuoD7Init = { 1, 1, 5, 9, 21, 57, 73, 189, 307, 515, 1797, 2073, 1085, 0 }; + static ulong[] dim852JoeKuoD7Init = { 1, 1, 5, 9, 23, 21, 21, 23, 487, 715, 449, 2157, 5063, 0 }; + static ulong[] dim853JoeKuoD7Init = { 1, 1, 1, 11, 27, 27, 121, 61, 281, 805, 55, 2111, 2193, 0 }; + static ulong[] dim854JoeKuoD7Init = { 1, 3, 7, 3, 5, 45, 23, 71, 369, 875, 1185, 1611, 2009, 0 }; + static ulong[] dim855JoeKuoD7Init = { 1, 3, 1, 15, 17, 59, 17, 99, 403, 103, 847, 849, 569, 0 }; + static ulong[] dim856JoeKuoD7Init = { 1, 3, 5, 7, 7, 13, 47, 125, 35, 615, 281, 1443, 1199, 0 }; + static ulong[] dim857JoeKuoD7Init = { 1, 3, 3, 15, 13, 63, 73, 191, 137, 257, 1609, 409, 5135, 0 }; + static ulong[] dim858JoeKuoD7Init = { 1, 3, 3, 11, 13, 57, 63, 189, 367, 7, 1261, 211, 2223, 0 }; + static ulong[] dim859JoeKuoD7Init = { 1, 1, 1, 3, 31, 21, 117, 135, 231, 981, 857, 3737, 1631, 0 }; + static ulong[] dim860JoeKuoD7Init = { 1, 1, 3, 5, 11, 13, 55, 193, 99, 969, 1093, 1575, 2367, 0 }; + static ulong[] dim861JoeKuoD7Init = { 1, 3, 5, 9, 9, 45, 81, 139, 479, 561, 1983, 3117, 2539, 0 }; + static ulong[] dim862JoeKuoD7Init = { 1, 1, 3, 11, 19, 37, 107, 125, 415, 653, 517, 2191, 415, 0 }; + static ulong[] dim863JoeKuoD7Init = { 1, 3, 3, 9, 13, 41, 59, 193, 205, 485, 1439, 1333, 2519, 0 }; + static ulong[] dim864JoeKuoD7Init = { 1, 3, 7, 13, 9, 41, 95, 141, 21, 953, 1453, 3585, 2521, 0 }; + static ulong[] dim865JoeKuoD7Init = { 1, 3, 7, 11, 25, 21, 43, 221, 201, 761, 1457, 1597, 2147, 0 }; + static ulong[] dim866JoeKuoD7Init = { 1, 1, 3, 9, 27, 63, 35, 229, 147, 293, 699, 673, 4779, 0 }; + static ulong[] dim867JoeKuoD7Init = { 1, 3, 5, 13, 15, 57, 57, 197, 23, 925, 1433, 681, 1721, 0 }; + static ulong[] dim868JoeKuoD7Init = { 1, 1, 5, 11, 17, 25, 127, 195, 487, 679, 1529, 453, 3955, 0 }; + static ulong[] dim869JoeKuoD7Init = { 1, 3, 7, 1, 29, 17, 49, 13, 299, 305, 11, 3913, 1633, 0 }; + static ulong[] dim870JoeKuoD7Init = { 1, 3, 5, 3, 15, 15, 79, 233, 183, 515, 773, 1761, 5439, 0 }; + static ulong[] dim871JoeKuoD7Init = { 1, 1, 5, 7, 23, 43, 3, 59, 37, 985, 1957, 2373, 7823, 0 }; + static ulong[] dim872JoeKuoD7Init = { 1, 1, 5, 5, 21, 59, 47, 205, 69, 435, 1567, 2661, 3589, 0 }; + static ulong[] dim873JoeKuoD7Init = { 1, 1, 1, 1, 7, 29, 15, 61, 197, 339, 1955, 2815, 4343, 0 }; + static ulong[] dim874JoeKuoD7Init = { 1, 3, 5, 5, 13, 33, 109, 33, 475, 219, 1707, 3747, 7359, 0 }; + static ulong[] dim875JoeKuoD7Init = { 1, 3, 7, 3, 21, 15, 53, 29, 493, 729, 1847, 1387, 1221, 0 }; + static ulong[] dim876JoeKuoD7Init = { 1, 1, 1, 11, 19, 27, 107, 29, 217, 19, 337, 2621, 1199, 0 }; + static ulong[] dim877JoeKuoD7Init = { 1, 1, 5, 11, 11, 39, 111, 195, 373, 239, 355, 359, 1187, 0 }; + static ulong[] dim878JoeKuoD7Init = { 1, 1, 3, 15, 29, 63, 13, 235, 413, 67, 1437, 3227, 5067, 0 }; + static ulong[] dim879JoeKuoD7Init = { 1, 3, 3, 3, 29, 35, 11, 189, 15, 181, 1807, 1711, 3317, 0 }; + static ulong[] dim880JoeKuoD7Init = { 1, 3, 5, 5, 25, 21, 93, 101, 65, 495, 375, 2873, 5253, 0 }; + static ulong[] dim881JoeKuoD7Init = { 1, 1, 7, 3, 19, 47, 13, 229, 3, 377, 1769, 673, 5713, 0 }; + static ulong[] dim882JoeKuoD7Init = { 1, 1, 1, 15, 11, 19, 25, 249, 95, 777, 1763, 2607, 6439, 0 }; + static ulong[] dim883JoeKuoD7Init = { 1, 1, 5, 1, 31, 47, 101, 155, 139, 201, 1687, 1503, 4783, 0 }; + static ulong[] dim884JoeKuoD7Init = { 1, 1, 5, 13, 27, 11, 53, 199, 305, 481, 1071, 143, 3667, 0 }; + static ulong[] dim885JoeKuoD7Init = { 1, 3, 5, 11, 15, 29, 95, 201, 271, 607, 511, 4029, 4269, 0 }; + static ulong[] dim886JoeKuoD7Init = { 1, 1, 1, 3, 29, 13, 99, 161, 55, 997, 1123, 3107, 4255, 0 }; + static ulong[] dim887JoeKuoD7Init = { 1, 3, 5, 11, 13, 5, 121, 253, 315, 465, 851, 3147, 5415, 0 }; + static ulong[] dim888JoeKuoD7Init = { 1, 3, 3, 13, 29, 15, 39, 7, 439, 787, 895, 1859, 5139, 0 }; + static ulong[] dim889JoeKuoD7Init = { 1, 3, 5, 9, 29, 37, 61, 61, 321, 307, 1741, 3143, 1977, 0 }; + static ulong[] dim890JoeKuoD7Init = { 1, 3, 3, 5, 19, 5, 105, 89, 189, 723, 407, 2557, 3817, 0 }; + static ulong[] dim891JoeKuoD7Init = { 1, 1, 1, 7, 15, 9, 93, 15, 461, 337, 1157, 531, 797, 0 }; + static ulong[] dim892JoeKuoD7Init = { 1, 3, 1, 1, 15, 33, 49, 87, 185, 581, 1449, 735, 4891, 0 }; + static ulong[] dim893JoeKuoD7Init = { 1, 1, 3, 7, 31, 49, 125, 99, 237, 655, 825, 2769, 4589, 0 }; + static ulong[] dim894JoeKuoD7Init = { 1, 3, 3, 15, 1, 51, 97, 205, 15, 47, 1453, 3399, 5539, 0 }; + static ulong[] dim895JoeKuoD7Init = { 1, 3, 5, 13, 29, 43, 105, 39, 329, 719, 563, 3817, 2901, 0 }; + static ulong[] dim896JoeKuoD7Init = { 1, 1, 3, 5, 25, 19, 7, 209, 89, 455, 2019, 1481, 7409, 0 }; + static ulong[] dim897JoeKuoD7Init = { 1, 3, 7, 1, 25, 47, 53, 115, 263, 547, 565, 3495, 3759, 0 }; + static ulong[] dim898JoeKuoD7Init = { 1, 3, 7, 15, 25, 47, 121, 193, 99, 45, 1251, 1221, 6425, 0 }; + static ulong[] dim899JoeKuoD7Init = { 1, 1, 1, 9, 3, 47, 91, 231, 189, 39, 1811, 3215, 6593, 0 }; + static ulong[] dim900JoeKuoD7Init = { 1, 3, 7, 5, 3, 57, 67, 63, 23, 627, 2045, 2377, 3805, 0 }; + static ulong[] dim901JoeKuoD7Init = { 1, 1, 1, 13, 7, 47, 29, 99, 481, 923, 119, 1911, 5187, 0 }; + static ulong[] dim902JoeKuoD7Init = { 1, 1, 5, 7, 1, 57, 7, 197, 451, 531, 29, 1851, 7069, 0 }; + static ulong[] dim903JoeKuoD7Init = { 1, 1, 1, 5, 31, 43, 3, 207, 67, 279, 37, 2381, 5997, 0 }; + static ulong[] dim904JoeKuoD7Init = { 1, 3, 5, 7, 23, 57, 91, 109, 165, 549, 837, 3135, 2251, 0 }; + static ulong[] dim905JoeKuoD7Init = { 1, 1, 7, 1, 3, 41, 67, 127, 273, 385, 995, 3263, 5211, 0 }; + static ulong[] dim906JoeKuoD7Init = { 1, 3, 7, 9, 21, 9, 101, 105, 43, 291, 1909, 1641, 7965, 0 }; + static ulong[] dim907JoeKuoD7Init = { 1, 3, 5, 11, 19, 21, 117, 141, 197, 83, 203, 393, 7995, 0 }; + static ulong[] dim908JoeKuoD7Init = { 1, 1, 5, 13, 11, 33, 21, 207, 421, 91, 1233, 1239, 5683, 0 }; + static ulong[] dim909JoeKuoD7Init = { 1, 1, 3, 15, 5, 1, 127, 119, 349, 953, 1297, 1805, 2385, 0 }; + static ulong[] dim910JoeKuoD7Init = { 1, 1, 1, 1, 19, 17, 17, 37, 217, 857, 859, 53, 2091, 0 }; + static ulong[] dim911JoeKuoD7Init = { 1, 3, 1, 15, 27, 37, 69, 121, 101, 1011, 1859, 3297, 5755, 0 }; + static ulong[] dim912JoeKuoD7Init = { 1, 3, 7, 13, 21, 13, 107, 105, 17, 743, 1849, 3169, 5901, 0 }; + static ulong[] dim913JoeKuoD7Init = { 1, 3, 3, 13, 31, 37, 125, 83, 127, 687, 1593, 1257, 4729, 0 }; + static ulong[] dim914JoeKuoD7Init = { 1, 3, 5, 3, 23, 21, 51, 157, 469, 349, 213, 1303, 123, 0 }; + static ulong[] dim915JoeKuoD7Init = { 1, 3, 1, 15, 17, 23, 45, 157, 313, 241, 361, 3967, 3635, 0 }; + static ulong[] dim916JoeKuoD7Init = { 1, 1, 7, 7, 25, 41, 65, 25, 97, 787, 951, 2471, 4621, 0 }; + static ulong[] dim917JoeKuoD7Init = { 1, 1, 7, 3, 31, 29, 75, 173, 55, 613, 283, 195, 5009, 0 }; + static ulong[] dim918JoeKuoD7Init = { 1, 1, 5, 3, 9, 47, 115, 149, 501, 199, 1957, 785, 3391, 0 }; + static ulong[] dim919JoeKuoD7Init = { 1, 1, 7, 11, 31, 57, 71, 191, 333, 157, 809, 3039, 7471, 0 }; + static ulong[] dim920JoeKuoD7Init = { 1, 3, 7, 9, 19, 17, 103, 243, 411, 449, 1495, 3843, 5361, 0 }; + static ulong[] dim921JoeKuoD7Init = { 1, 1, 1, 1, 11, 13, 99, 229, 365, 909, 87, 3669, 6609, 0 }; + static ulong[] dim922JoeKuoD7Init = { 1, 1, 1, 15, 7, 61, 95, 95, 147, 959, 971, 649, 5047, 0 }; + static ulong[] dim923JoeKuoD7Init = { 1, 3, 1, 15, 15, 37, 113, 29, 373, 379, 151, 2741, 1259, 0 }; + static ulong[] dim924JoeKuoD7Init = { 1, 3, 3, 7, 1, 7, 91, 61, 213, 131, 1607, 3957, 4197, 0 }; + static ulong[] dim925JoeKuoD7Init = { 1, 1, 7, 15, 11, 41, 79, 25, 267, 511, 111, 1779, 351, 0 }; + static ulong[] dim926JoeKuoD7Init = { 1, 3, 5, 5, 17, 9, 29, 117, 207, 655, 221, 3567, 6069, 0 }; + static ulong[] dim927JoeKuoD7Init = { 1, 1, 1, 13, 31, 47, 3, 51, 451, 675, 91, 1529, 5729, 0 }; + static ulong[] dim928JoeKuoD7Init = { 1, 1, 7, 15, 27, 37, 27, 189, 183, 619, 509, 2421, 5903, 0 }; + static ulong[] dim929JoeKuoD7Init = { 1, 1, 3, 7, 1, 31, 79, 233, 41, 949, 1313, 3807, 171, 0 }; + static ulong[] dim930JoeKuoD7Init = { 1, 1, 3, 5, 31, 39, 29, 43, 309, 11, 1041, 1893, 4443, 0 }; + static ulong[] dim931JoeKuoD7Init = { 1, 1, 1, 11, 13, 51, 5, 199, 51, 563, 819, 3467, 7003, 0 }; + static ulong[] dim932JoeKuoD7Init = { 1, 1, 3, 15, 19, 27, 1, 3, 393, 901, 1603, 1949, 7119, 0 }; + static ulong[] dim933JoeKuoD7Init = { 1, 1, 1, 3, 13, 39, 35, 53, 437, 263, 783, 1669, 7271, 0 }; + static ulong[] dim934JoeKuoD7Init = { 1, 1, 5, 11, 23, 11, 17, 187, 303, 833, 805, 3395, 181, 0 }; + static ulong[] dim935JoeKuoD7Init = { 1, 3, 5, 9, 15, 23, 113, 37, 131, 89, 923, 2265, 1621, 0 }; + static ulong[] dim936JoeKuoD7Init = { 1, 3, 1, 5, 3, 35, 53, 139, 21, 547, 1765, 3993, 2617, 0 }; + static ulong[] dim937JoeKuoD7Init = { 1, 3, 5, 1, 3, 35, 17, 185, 291, 973, 1267, 301, 7443, 0 }; + static ulong[] dim938JoeKuoD7Init = { 1, 3, 5, 1, 5, 45, 107, 209, 345, 821, 173, 1777, 4215, 0 }; + static ulong[] dim939JoeKuoD7Init = { 1, 1, 5, 3, 13, 11, 17, 5, 445, 411, 825, 3031, 4295, 0 }; + static ulong[] dim940JoeKuoD7Init = { 1, 3, 5, 1, 15, 45, 57, 243, 263, 167, 1889, 2901, 2315, 0 }; + static ulong[] dim941JoeKuoD7Init = { 1, 1, 5, 13, 27, 37, 27, 39, 89, 571, 775, 269, 2633, 0 }; + static ulong[] dim942JoeKuoD7Init = { 1, 3, 1, 15, 5, 41, 59, 89, 475, 745, 431, 489, 2121, 0 }; + static ulong[] dim943JoeKuoD7Init = { 1, 3, 1, 11, 3, 53, 65, 107, 475, 529, 169, 2555, 5189, 0 }; + static ulong[] dim944JoeKuoD7Init = { 1, 1, 1, 7, 27, 7, 55, 11, 493, 687, 365, 3105, 8067, 0 }; + static ulong[] dim945JoeKuoD7Init = { 1, 3, 7, 7, 13, 7, 101, 139, 387, 289, 1157, 785, 1457, 0 }; + static ulong[] dim946JoeKuoD7Init = { 1, 3, 7, 7, 1, 23, 81, 147, 509, 241, 1507, 3947, 795, 0 }; + static ulong[] dim947JoeKuoD7Init = { 1, 3, 1, 3, 3, 3, 39, 205, 67, 409, 1463, 2503, 7003, 0 }; + static ulong[] dim948JoeKuoD7Init = { 1, 3, 5, 7, 13, 3, 49, 157, 271, 813, 1793, 2059, 7233, 0 }; + static ulong[] dim949JoeKuoD7Init = { 1, 1, 1, 11, 17, 7, 35, 251, 91, 725, 157, 2503, 7007, 0 }; + static ulong[] dim950JoeKuoD7Init = { 1, 1, 1, 7, 31, 59, 115, 1, 421, 181, 809, 1739, 5641, 0 }; + static ulong[] dim951JoeKuoD7Init = { 1, 1, 7, 1, 3, 53, 29, 37, 181, 187, 11, 1829, 5031, 0 }; + static ulong[] dim952JoeKuoD7Init = { 1, 3, 3, 3, 5, 49, 11, 69, 109, 11, 1825, 2119, 4697, 0 }; + static ulong[] dim953JoeKuoD7Init = { 1, 3, 3, 7, 7, 31, 115, 197, 39, 177, 1263, 1173, 3845, 0 }; + static ulong[] dim954JoeKuoD7Init = { 1, 3, 7, 1, 15, 61, 49, 3, 141, 599, 809, 2827, 6349, 0 }; + static ulong[] dim955JoeKuoD7Init = { 1, 3, 1, 9, 23, 29, 121, 175, 507, 273, 1945, 2991, 885, 0 }; + static ulong[] dim956JoeKuoD7Init = { 1, 1, 1, 1, 3, 55, 125, 37, 57, 901, 85, 3319, 3477, 0 }; + static ulong[] dim957JoeKuoD7Init = { 1, 1, 7, 15, 3, 27, 69, 143, 431, 47, 603, 1321, 5053, 0 }; + static ulong[] dim958JoeKuoD7Init = { 1, 3, 1, 3, 3, 37, 65, 163, 391, 509, 87, 747, 4301, 0 }; + static ulong[] dim959JoeKuoD7Init = { 1, 3, 7, 9, 5, 53, 75, 179, 389, 97, 373, 963, 3647, 0 }; + static ulong[] dim960JoeKuoD7Init = { 1, 3, 1, 5, 13, 21, 49, 211, 5, 469, 1807, 891, 1543, 0 }; + static ulong[] dim961JoeKuoD7Init = { 1, 3, 1, 9, 13, 29, 39, 55, 39, 667, 1967, 1887, 2619, 0 }; + static ulong[] dim962JoeKuoD7Init = { 1, 1, 7, 9, 25, 47, 1, 221, 421, 175, 461, 1931, 3525, 0 }; + static ulong[] dim963JoeKuoD7Init = { 1, 3, 1, 9, 11, 35, 23, 121, 493, 675, 857, 2989, 4863, 0 }; + static ulong[] dim964JoeKuoD7Init = { 1, 3, 7, 9, 5, 39, 121, 9, 249, 507, 1637, 2991, 4545, 0 }; + static ulong[] dim965JoeKuoD7Init = { 1, 1, 5, 9, 5, 9, 27, 135, 299, 713, 1385, 729, 29, 0 }; + static ulong[] dim966JoeKuoD7Init = { 1, 3, 1, 11, 3, 3, 67, 17, 163, 535, 1731, 1401, 4495, 0 }; + static ulong[] dim967JoeKuoD7Init = { 1, 1, 1, 5, 31, 29, 81, 251, 471, 461, 1151, 1037, 4069, 0 }; + static ulong[] dim968JoeKuoD7Init = { 1, 3, 7, 5, 11, 29, 13, 157, 329, 237, 691, 1895, 653, 0 }; + static ulong[] dim969JoeKuoD7Init = { 1, 3, 5, 13, 23, 23, 57, 149, 111, 607, 1835, 3129, 1827, 0 }; + static ulong[] dim970JoeKuoD7Init = { 1, 3, 1, 5, 11, 11, 95, 143, 495, 805, 1163, 1853, 1017, 0 }; + static ulong[] dim971JoeKuoD7Init = { 1, 1, 1, 9, 15, 19, 89, 143, 305, 121, 1217, 807, 5003, 0 }; + static ulong[] dim972JoeKuoD7Init = { 1, 1, 1, 13, 27, 39, 117, 65, 473, 191, 1863, 3533, 243, 0 }; + static ulong[] dim973JoeKuoD7Init = { 1, 3, 3, 9, 31, 5, 91, 245, 175, 635, 257, 1197, 5965, 0 }; + static ulong[] dim974JoeKuoD7Init = { 1, 3, 5, 1, 9, 13, 37, 19, 177, 949, 49, 3855, 5105, 0 }; + static ulong[] dim975JoeKuoD7Init = { 1, 1, 3, 3, 1, 41, 33, 65, 295, 917, 503, 2665, 1485, 0 }; + static ulong[] dim976JoeKuoD7Init = { 1, 1, 3, 5, 3, 25, 11, 9, 439, 293, 1919, 693, 5797, 0 }; + static ulong[] dim977JoeKuoD7Init = { 1, 3, 7, 15, 17, 51, 7, 17, 153, 105, 807, 1029, 4649, 0 }; + static ulong[] dim978JoeKuoD7Init = { 1, 1, 5, 11, 27, 25, 37, 49, 481, 599, 655, 1497, 6455, 0 }; + static ulong[] dim979JoeKuoD7Init = { 1, 1, 7, 5, 25, 23, 127, 203, 381, 61, 1651, 3535, 6345, 0 }; + static ulong[] dim980JoeKuoD7Init = { 1, 1, 1, 5, 27, 13, 93, 151, 421, 713, 305, 3541, 6741, 0 }; + static ulong[] dim981JoeKuoD7Init = { 1, 1, 5, 5, 3, 1, 93, 55, 65, 437, 1283, 55, 861, 0 }; + static ulong[] dim982JoeKuoD7Init = { 1, 3, 7, 9, 27, 59, 15, 195, 303, 705, 143, 1423, 6793, 0 }; + static ulong[] dim983JoeKuoD7Init = { 1, 1, 7, 13, 3, 21, 81, 89, 325, 103, 573, 1891, 3023, 0 }; + static ulong[] dim984JoeKuoD7Init = { 1, 3, 3, 7, 15, 47, 23, 139, 437, 701, 1453, 1419, 1487, 0 }; + static ulong[] dim985JoeKuoD7Init = { 1, 3, 3, 1, 13, 35, 49, 127, 335, 185, 393, 2239, 2039, 0 }; + static ulong[] dim986JoeKuoD7Init = { 1, 1, 3, 5, 29, 3, 83, 179, 487, 381, 1477, 1849, 7593, 0 }; + static ulong[] dim987JoeKuoD7Init = { 1, 1, 3, 3, 15, 61, 75, 115, 487, 237, 615, 1011, 4725, 0 }; + static ulong[] dim988JoeKuoD7Init = { 1, 3, 7, 5, 25, 39, 105, 81, 401, 939, 343, 3281, 3907, 0 }; + static ulong[] dim989JoeKuoD7Init = { 1, 3, 5, 9, 31, 31, 43, 131, 275, 575, 727, 3035, 363, 0 }; + static ulong[] dim990JoeKuoD7Init = { 1, 3, 7, 11, 31, 9, 27, 145, 99, 261, 1927, 2619, 5853, 0 }; + static ulong[] dim991JoeKuoD7Init = { 1, 3, 7, 5, 25, 33, 85, 77, 435, 453, 1115, 1025, 2477, 0 }; + static ulong[] dim992JoeKuoD7Init = { 1, 3, 7, 13, 19, 55, 85, 155, 455, 385, 1033, 3789, 709, 0 }; + static ulong[] dim993JoeKuoD7Init = { 1, 3, 1, 11, 31, 47, 61, 45, 247, 557, 929, 1579, 3927, 0 }; + static ulong[] dim994JoeKuoD7Init = { 1, 1, 3, 7, 13, 41, 121, 249, 393, 527, 1807, 2493, 67, 0 }; + static ulong[] dim995JoeKuoD7Init = { 1, 3, 7, 13, 3, 17, 9, 215, 181, 841, 1381, 1573, 1531, 0 }; + static ulong[] dim996JoeKuoD7Init = { 1, 1, 7, 3, 21, 39, 119, 89, 267, 395, 1263, 3927, 5419, 0 }; + static ulong[] dim997JoeKuoD7Init = { 1, 1, 1, 5, 17, 21, 35, 217, 165, 837, 1093, 1347, 6361, 0 }; + static ulong[] dim998JoeKuoD7Init = { 1, 3, 3, 9, 9, 1, 59, 31, 41, 229, 925, 2703, 6597, 0 }; + static ulong[] dim999JoeKuoD7Init = { 1, 3, 1, 9, 13, 21, 35, 159, 329, 981, 955, 1871, 3571, 0 }; + static ulong[] dim1000JoeKuoD7Init = { 1, 3, 1, 11, 31, 47, 121, 201, 339, 1021, 1413, 1405, 1261, 0 }; + static ulong[] dim1001JoeKuoD7Init = { 1, 1, 3, 11, 15, 23, 115, 247, 333, 757, 369, 3839, 5217, 0 }; + static ulong[] dim1002JoeKuoD7Init = { 1, 1, 1, 15, 1, 37, 47, 67, 461, 333, 837, 2831, 2293, 0 }; + static ulong[] dim1003JoeKuoD7Init = { 1, 1, 5, 11, 31, 29, 75, 9, 287, 17, 1771, 3523, 7321, 0 }; + static ulong[] dim1004JoeKuoD7Init = { 1, 3, 7, 5, 29, 47, 37, 25, 497, 455, 1929, 2711, 777, 0 }; + static ulong[] dim1005JoeKuoD7Init = { 1, 3, 1, 15, 17, 21, 121, 205, 133, 139, 1343, 2181, 6281, 0 }; + static ulong[] dim1006JoeKuoD7Init = { 1, 3, 5, 3, 17, 59, 93, 105, 359, 27, 1515, 115, 7585, 0 }; + static ulong[] dim1007JoeKuoD7Init = { 1, 3, 1, 3, 25, 43, 71, 71, 315, 137, 1245, 1751, 1589, 0 }; + static ulong[] dim1008JoeKuoD7Init = { 1, 1, 7, 1, 23, 51, 61, 247, 317, 125, 859, 3807, 1175, 0 }; + static ulong[] dim1009JoeKuoD7Init = { 1, 1, 5, 9, 31, 33, 25, 41, 21, 1001, 63, 2105, 1929, 0 }; + static ulong[] dim1010JoeKuoD7Init = { 1, 1, 3, 15, 29, 61, 59, 173, 265, 661, 115, 3127, 4431, 0 }; + static ulong[] dim1011JoeKuoD7Init = { 1, 1, 1, 15, 7, 63, 55, 253, 131, 425, 735, 2917, 5311, 0 }; + static ulong[] dim1012JoeKuoD7Init = { 1, 3, 1, 3, 9, 7, 81, 39, 261, 633, 485, 2091, 3763, 0 }; + static ulong[] dim1013JoeKuoD7Init = { 1, 3, 1, 11, 27, 19, 99, 99, 27, 225, 1007, 1089, 921, 0 }; + static ulong[] dim1014JoeKuoD7Init = { 1, 1, 3, 13, 21, 7, 85, 105, 379, 223, 955, 3533, 3879, 0 }; + static ulong[] dim1015JoeKuoD7Init = { 1, 3, 3, 9, 13, 45, 55, 57, 315, 255, 141, 3255, 5185, 0 }; + static ulong[] dim1016JoeKuoD7Init = { 1, 3, 7, 15, 9, 27, 53, 15, 25, 547, 1573, 1387, 7243, 0 }; + static ulong[] dim1017JoeKuoD7Init = { 1, 1, 3, 15, 19, 17, 77, 253, 105, 1009, 1331, 2773, 7563, 0 }; + static ulong[] dim1018JoeKuoD7Init = { 1, 1, 5, 5, 3, 19, 103, 63, 491, 709, 1299, 1245, 3879, 0 }; + static ulong[] dim1019JoeKuoD7Init = { 1, 3, 1, 1, 13, 43, 37, 41, 167, 349, 1821, 2741, 3025, 0 }; + static ulong[] dim1020JoeKuoD7Init = { 1, 1, 1, 5, 29, 39, 25, 221, 259, 939, 471, 2547, 7119, 0 }; + static ulong[] dim1021JoeKuoD7Init = { 1, 3, 3, 3, 25, 59, 53, 105, 39, 737, 987, 2961, 7703, 0 }; + static ulong[] dim1022JoeKuoD7Init = { 1, 3, 5, 3, 29, 11, 109, 233, 221, 515, 1463, 1233, 7591, 0 }; + static ulong[] dim1023JoeKuoD7Init = { 1, 1, 1, 3, 17, 17, 113, 91, 253, 547, 1203, 2327, 6933, 0 }; + static ulong[] dim1024JoeKuoD7Init = { 1, 1, 3, 11, 25, 3, 17, 27, 239, 723, 1751, 3907, 1199, 0 }; + static ulong[] dim1025JoeKuoD7Init = { 1, 1, 5, 15, 13, 35, 93, 9, 501, 949, 659, 1863, 5319, 0 }; + static ulong[] dim1026JoeKuoD7Init = { 1, 3, 7, 1, 1, 55, 99, 73, 185, 299, 181, 4005, 7239, 0 }; + static ulong[] dim1027JoeKuoD7Init = { 1, 1, 1, 5, 13, 57, 21, 41, 461, 445, 199, 689, 2005, 0 }; + static ulong[] dim1028JoeKuoD7Init = { 1, 1, 1, 9, 11, 39, 45, 157, 295, 907, 1839, 3313, 6397, 0 }; + static ulong[] dim1029JoeKuoD7Init = { 1, 1, 5, 15, 21, 49, 39, 147, 325, 437, 1773, 2533, 8183, 0 }; + static ulong[] dim1030JoeKuoD7Init = { 1, 1, 7, 11, 11, 45, 9, 149, 439, 403, 1717, 3141, 7259, 0 }; + static ulong[] dim1031JoeKuoD7Init = { 1, 1, 7, 3, 13, 41, 79, 93, 123, 135, 541, 1133, 4389, 0 }; + static ulong[] dim1032JoeKuoD7Init = { 1, 3, 1, 11, 17, 45, 3, 49, 117, 193, 1737, 2995, 6821, 0 }; + static ulong[] dim1033JoeKuoD7Init = { 1, 3, 7, 9, 19, 53, 77, 119, 83, 161, 1029, 95, 7065, 0 }; + static ulong[] dim1034JoeKuoD7Init = { 1, 3, 7, 5, 19, 33, 13, 85, 63, 1011, 1857, 2657, 7513, 0 }; + static ulong[] dim1035JoeKuoD7Init = { 1, 1, 5, 13, 15, 31, 121, 75, 343, 915, 1571, 1291, 965, 0 }; + static ulong[] dim1036JoeKuoD7Init = { 1, 1, 1, 15, 17, 27, 31, 183, 79, 219, 341, 2491, 7329, 0 }; + static ulong[] dim1037JoeKuoD7Init = { 1, 3, 3, 15, 5, 5, 53, 151, 149, 471, 413, 967, 4207, 0 }; + static ulong[] dim1038JoeKuoD7Init = { 1, 1, 7, 15, 21, 17, 97, 107, 51, 533, 1195, 1495, 3843, 0 }; + static ulong[] dim1039JoeKuoD7Init = { 1, 1, 3, 7, 3, 5, 109, 19, 401, 179, 1595, 3147, 3847, 0 }; + static ulong[] dim1040JoeKuoD7Init = { 1, 1, 3, 9, 11, 49, 9, 245, 417, 933, 627, 551, 3643, 0 }; + static ulong[] dim1041JoeKuoD7Init = { 1, 1, 1, 11, 5, 33, 101, 247, 57, 597, 377, 7, 7117, 0 }; + static ulong[] dim1042JoeKuoD7Init = { 1, 3, 7, 11, 7, 47, 113, 29, 503, 385, 743, 563, 4775, 0 }; + static ulong[] dim1043JoeKuoD7Init = { 1, 3, 3, 15, 7, 63, 57, 171, 77, 663, 1113, 1901, 5361, 0 }; + static ulong[] dim1044JoeKuoD7Init = { 1, 3, 1, 11, 1, 1, 39, 83, 497, 725, 1105, 863, 113, 0 }; + static ulong[] dim1045JoeKuoD7Init = { 1, 1, 7, 1, 1, 23, 95, 137, 447, 593, 561, 1665, 7565, 0 }; + static ulong[] dim1046JoeKuoD7Init = { 1, 1, 1, 5, 19, 15, 25, 185, 33, 747, 641, 3205, 1373, 0 }; + static ulong[] dim1047JoeKuoD7Init = { 1, 1, 3, 1, 15, 17, 65, 77, 1, 689, 1751, 1885, 3873, 0 }; + static ulong[] dim1048JoeKuoD7Init = { 1, 3, 7, 15, 23, 23, 9, 97, 129, 185, 1527, 3721, 5161, 0 }; + static ulong[] dim1049JoeKuoD7Init = { 1, 1, 1, 5, 23, 33, 33, 131, 99, 929, 1077, 3129, 8153, 0 }; + static ulong[] dim1050JoeKuoD7Init = { 1, 1, 3, 1, 1, 37, 69, 155, 69, 121, 395, 717, 841, 0 }; + static ulong[] dim1051JoeKuoD7Init = { 1, 1, 5, 7, 17, 63, 101, 109, 323, 559, 427, 2279, 5345, 0 }; + static ulong[] dim1052JoeKuoD7Init = { 1, 1, 1, 1, 9, 27, 77, 19, 375, 313, 855, 65, 1359, 0 }; + static ulong[] dim1053JoeKuoD7Init = { 1, 3, 7, 5, 23, 11, 5, 57, 69, 267, 895, 1279, 5083, 0 }; + static ulong[] dim1054JoeKuoD7Init = { 1, 3, 7, 9, 17, 5, 13, 27, 299, 279, 389, 3161, 4633, 0 }; + static ulong[] dim1055JoeKuoD7Init = { 1, 3, 7, 1, 19, 47, 31, 93, 503, 473, 1501, 617, 1621, 0 }; + static ulong[] dim1056JoeKuoD7Init = { 1, 3, 1, 15, 17, 31, 35, 75, 41, 113, 149, 861, 5845, 0 }; + static ulong[] dim1057JoeKuoD7Init = { 1, 3, 7, 1, 7, 21, 31, 77, 307, 709, 531, 1133, 5887, 0 }; + static ulong[] dim1058JoeKuoD7Init = { 1, 1, 7, 7, 25, 37, 23, 233, 339, 705, 123, 79, 3827, 0 }; + static ulong[] dim1059JoeKuoD7Init = { 1, 1, 5, 9, 15, 61, 13, 215, 175, 999, 1147, 523, 7831, 0 }; + static ulong[] dim1060JoeKuoD7Init = { 1, 1, 1, 7, 15, 31, 117, 41, 43, 851, 1657, 669, 7243, 0 }; + static ulong[] dim1061JoeKuoD7Init = { 1, 1, 1, 1, 29, 47, 29, 179, 151, 833, 1911, 3031, 3835, 0 }; + static ulong[] dim1062JoeKuoD7Init = { 1, 1, 1, 13, 27, 41, 127, 203, 381, 395, 201, 1713, 4781, 0 }; + static ulong[] dim1063JoeKuoD7Init = { 1, 1, 3, 7, 11, 11, 127, 13, 257, 1, 1285, 2829, 8077, 0 }; + static ulong[] dim1064JoeKuoD7Init = { 1, 3, 3, 5, 15, 1, 35, 105, 183, 543, 1865, 675, 7747, 0 }; + static ulong[] dim1065JoeKuoD7Init = { 1, 1, 3, 1, 15, 47, 111, 147, 373, 445, 1273, 1989, 2057, 0 }; + static ulong[] dim1066JoeKuoD7Init = { 1, 1, 5, 9, 5, 31, 63, 127, 33, 323, 477, 213, 8137, 0 }; + static ulong[] dim1067JoeKuoD7Init = { 1, 1, 5, 9, 13, 1, 9, 135, 113, 395, 127, 3561, 5903, 0 }; + static ulong[] dim1068JoeKuoD7Init = { 1, 1, 3, 15, 1, 31, 85, 181, 49, 585, 1515, 2105, 541, 0 }; + static ulong[] dim1069JoeKuoD7Init = { 1, 1, 1, 15, 9, 1, 121, 31, 221, 445, 735, 1107, 4073, 0 }; + static ulong[] dim1070JoeKuoD7Init = { 1, 3, 1, 15, 3, 13, 13, 247, 509, 199, 1575, 2721, 2303, 0 }; + static ulong[] dim1071JoeKuoD7Init = { 1, 1, 3, 7, 25, 17, 63, 59, 409, 69, 1947, 427, 5357, 0 }; + static ulong[] dim1072JoeKuoD7Init = { 1, 1, 3, 3, 13, 5, 99, 161, 163, 437, 1467, 2215, 3321, 0 }; + static ulong[] dim1073JoeKuoD7Init = { 1, 3, 1, 3, 15, 55, 101, 207, 75, 601, 1327, 3901, 5773, 0 }; + static ulong[] dim1074JoeKuoD7Init = { 1, 1, 3, 3, 13, 45, 115, 119, 431, 5, 563, 3255, 5077, 0 }; + static ulong[] dim1075JoeKuoD7Init = { 1, 1, 7, 3, 21, 51, 41, 3, 375, 203, 1117, 3921, 387, 0 }; + static ulong[] dim1076JoeKuoD7Init = { 1, 3, 7, 7, 9, 5, 15, 133, 179, 37, 1593, 193, 4975, 0 }; + static ulong[] dim1077JoeKuoD7Init = { 1, 3, 3, 7, 31, 37, 89, 1, 241, 445, 381, 3283, 3851, 0 }; + static ulong[] dim1078JoeKuoD7Init = { 1, 3, 5, 1, 5, 45, 21, 123, 377, 83, 2029, 1913, 659, 0 }; + static ulong[] dim1079JoeKuoD7Init = { 1, 1, 7, 3, 5, 5, 35, 85, 173, 397, 1695, 3517, 175, 0 }; + static ulong[] dim1080JoeKuoD7Init = { 1, 3, 7, 13, 25, 51, 93, 177, 371, 507, 1777, 3335, 5953, 0 }; + static ulong[] dim1081JoeKuoD7Init = { 1, 3, 5, 15, 13, 41, 103, 105, 303, 401, 1339, 21, 5723, 0 }; + static ulong[] dim1082JoeKuoD7Init = { 1, 1, 7, 15, 7, 57, 63, 79, 35, 363, 831, 3911, 5777, 0 }; + static ulong[] dim1083JoeKuoD7Init = { 1, 1, 5, 11, 13, 15, 127, 141, 231, 619, 835, 691, 525, 0 }; + static ulong[] dim1084JoeKuoD7Init = { 1, 1, 3, 5, 7, 33, 81, 83, 497, 459, 493, 725, 2137, 0 }; + static ulong[] dim1085JoeKuoD7Init = { 1, 3, 3, 5, 25, 7, 77, 163, 47, 445, 629, 463, 3597, 0 }; + static ulong[] dim1086JoeKuoD7Init = { 1, 1, 3, 11, 19, 13, 67, 117, 351, 169, 1905, 3105, 93, 0 }; + static ulong[] dim1087JoeKuoD7Init = { 1, 3, 1, 13, 17, 17, 67, 135, 111, 649, 495, 425, 1621, 0 }; + static ulong[] dim1088JoeKuoD7Init = { 1, 3, 5, 1, 19, 59, 11, 227, 137, 525, 1751, 915, 4397, 0 }; + static ulong[] dim1089JoeKuoD7Init = { 1, 1, 3, 3, 15, 53, 87, 153, 69, 867, 833, 2363, 4363, 0 }; + static ulong[] dim1090JoeKuoD7Init = { 1, 3, 5, 13, 13, 19, 35, 103, 441, 23, 1049, 2469, 6595, 0 }; + static ulong[] dim1091JoeKuoD7Init = { 1, 1, 7, 7, 23, 55, 57, 25, 3, 157, 523, 1029, 4177, 0 }; + static ulong[] dim1092JoeKuoD7Init = { 1, 1, 3, 5, 9, 13, 1, 109, 219, 703, 237, 435, 2607, 0 }; + static ulong[] dim1093JoeKuoD7Init = { 1, 1, 1, 13, 21, 23, 5, 109, 467, 197, 1467, 3625, 4997, 0 }; + static ulong[] dim1094JoeKuoD7Init = { 1, 3, 7, 3, 25, 53, 119, 163, 117, 721, 1017, 2499, 4139, 0 }; + static ulong[] dim1095JoeKuoD7Init = { 1, 1, 1, 9, 9, 13, 33, 5, 263, 21, 1393, 3181, 4785, 0 }; + static ulong[] dim1096JoeKuoD7Init = { 1, 1, 5, 13, 15, 5, 57, 233, 99, 305, 745, 2327, 2259, 0 }; + static ulong[] dim1097JoeKuoD7Init = { 1, 1, 3, 3, 15, 39, 99, 115, 395, 99, 947, 3171, 711, 0 }; + static ulong[] dim1098JoeKuoD7Init = { 1, 1, 7, 13, 17, 33, 29, 37, 399, 479, 1083, 285, 6897, 0 }; + static ulong[] dim1099JoeKuoD7Init = { 1, 1, 7, 5, 7, 1, 9, 239, 479, 265, 1129, 3615, 4865, 0 }; + static ulong[] dim1100JoeKuoD7Init = { 1, 3, 3, 15, 31, 45, 7, 179, 467, 675, 1257, 1729, 7879, 0 }; + static ulong[] dim1101JoeKuoD7Init = { 1, 3, 5, 13, 5, 23, 11, 219, 503, 613, 1383, 1733, 3269, 0 }; + static ulong[] dim1102JoeKuoD7Init = { 1, 1, 3, 13, 25, 5, 81, 205, 389, 925, 735, 2981, 4271, 0 }; + static ulong[] dim1103JoeKuoD7Init = { 1, 1, 3, 7, 19, 47, 107, 15, 87, 889, 725, 1123, 2883, 0 }; + static ulong[] dim1104JoeKuoD7Init = { 1, 1, 3, 13, 31, 9, 45, 129, 353, 919, 1529, 827, 3645, 0 }; + static ulong[] dim1105JoeKuoD7Init = { 1, 3, 5, 5, 13, 45, 17, 219, 23, 873, 1127, 1757, 1103, 0 }; + static ulong[] dim1106JoeKuoD7Init = { 1, 3, 3, 11, 31, 45, 33, 215, 107, 941, 1785, 4039, 3393, 0 }; + static ulong[] dim1107JoeKuoD7Init = { 1, 3, 3, 7, 15, 61, 107, 189, 31, 457, 881, 1449, 7351, 0 }; + static ulong[] dim1108JoeKuoD7Init = { 1, 3, 1, 15, 13, 63, 95, 27, 3, 771, 363, 2569, 2195, 0 }; + static ulong[] dim1109JoeKuoD7Init = { 1, 1, 7, 9, 15, 11, 5, 193, 439, 745, 1705, 1249, 7319, 0 }; + static ulong[] dim1110JoeKuoD7Init = { 1, 1, 3, 11, 29, 19, 111, 73, 149, 707, 1337, 1417, 761, 0 }; + static ulong[] dim1111JoeKuoD7Init = { 1, 3, 7, 9, 17, 7, 127, 113, 353, 575, 1979, 3589, 3221, 1801, 0 }; + static ulong[] dim1112JoeKuoD7Init = { 1, 1, 5, 13, 29, 21, 31, 135, 45, 571, 229, 791, 2017, 1023, 0 }; + static ulong[] dim1113JoeKuoD7Init = { 1, 1, 1, 1, 3, 37, 29, 233, 379, 579, 1895, 2359, 5511, 15901, 0 }; + static ulong[] dim1114JoeKuoD7Init = { 1, 3, 1, 3, 11, 63, 83, 219, 275, 441, 581, 3735, 6845, 12669, 0 }; + static ulong[] dim1115JoeKuoD7Init = { 1, 3, 3, 9, 3, 5, 87, 143, 207, 211, 1123, 443, 3139, 15123, 0 }; + static ulong[] dim1116JoeKuoD7Init = { 1, 3, 3, 11, 11, 21, 69, 69, 307, 935, 1353, 163, 1535, 4821, 0 }; + static ulong[] dim1117JoeKuoD7Init = { 1, 1, 7, 13, 11, 47, 41, 107, 463, 1003, 457, 1019, 1699, 4425, 0 }; + static ulong[] dim1118JoeKuoD7Init = { 1, 3, 7, 7, 9, 5, 99, 95, 207, 697, 9, 771, 6895, 9157, 0 }; + static ulong[] dim1119JoeKuoD7Init = { 1, 1, 7, 11, 13, 5, 15, 107, 3, 319, 1187, 3357, 295, 2863, 0 }; + static ulong[] dim1120JoeKuoD7Init = { 1, 3, 3, 1, 13, 23, 89, 149, 337, 435, 633, 885, 1361, 3795, 0 }; + static ulong[] dim1121JoeKuoD7Init = { 1, 3, 1, 13, 1, 9, 63, 203, 377, 305, 1471, 3193, 5507, 2219, 0 }; + static ulong[] dim1122JoeKuoD7Init = { 1, 1, 3, 9, 9, 9, 63, 31, 35, 551, 1379, 135, 4949, 10345, 0 }; + static ulong[] dim1123JoeKuoD7Init = { 1, 3, 1, 3, 7, 61, 121, 27, 127, 901, 1935, 1347, 3179, 13785, 0 }; + static ulong[] dim1124JoeKuoD7Init = { 1, 1, 7, 11, 13, 17, 57, 73, 219, 73, 335, 3705, 591, 3547, 0 }; + static ulong[] dim1125JoeKuoD7Init = { 1, 1, 1, 7, 13, 7, 127, 153, 503, 99, 187, 1697, 3497, 11913, 0 }; + static ulong[] dim1126JoeKuoD7Init = { 1, 1, 7, 5, 3, 21, 99, 125, 87, 889, 1471, 625, 2671, 11729, 0 }; + static ulong[] dim1127JoeKuoD7Init = { 1, 3, 5, 7, 9, 55, 127, 201, 383, 769, 769, 3907, 7087, 1933, 0 }; + static ulong[] dim1128JoeKuoD7Init = { 1, 3, 7, 5, 9, 47, 5, 29, 155, 327, 1413, 2761, 7699, 9129, 0 }; + static ulong[] dim1129JoeKuoD7Init = { 1, 1, 7, 15, 9, 11, 7, 91, 71, 563, 535, 3387, 4769, 4875, 0 }; + static ulong[] dim1130JoeKuoD7Init = { 1, 1, 7, 11, 17, 47, 29, 201, 299, 947, 39, 583, 1723, 877, 0 }; + static ulong[] dim1131JoeKuoD7Init = { 1, 3, 1, 5, 27, 49, 105, 31, 91, 39, 1355, 2729, 6965, 14081, 0 }; + static ulong[] dim1132JoeKuoD7Init = { 1, 1, 7, 7, 17, 63, 65, 229, 497, 431, 1167, 1299, 4641, 10975, 0 }; + static ulong[] dim1133JoeKuoD7Init = { 1, 1, 5, 9, 17, 3, 101, 191, 187, 87, 1229, 369, 2633, 13765, 0 }; + static ulong[] dim1134JoeKuoD7Init = { 1, 1, 1, 7, 29, 7, 57, 17, 319, 839, 799, 151, 431, 9513, 0 }; + static ulong[] dim1135JoeKuoD7Init = { 1, 1, 1, 11, 25, 47, 15, 29, 71, 617, 697, 2633, 1787, 10343, 0 }; + static ulong[] dim1136JoeKuoD7Init = { 1, 1, 3, 3, 13, 1, 41, 211, 265, 501, 1619, 3781, 4091, 7785, 0 }; + static ulong[] dim1137JoeKuoD7Init = { 1, 3, 3, 9, 11, 37, 69, 45, 107, 69, 1227, 311, 187, 10379, 0 }; + static ulong[] dim1138JoeKuoD7Init = { 1, 1, 7, 1, 31, 37, 85, 135, 283, 869, 1159, 3971, 6339, 5511, 0 }; + static ulong[] dim1139JoeKuoD7Init = { 1, 1, 7, 3, 19, 43, 75, 59, 365, 763, 323, 3513, 437, 2371, 0 }; + static ulong[] dim1140JoeKuoD7Init = { 1, 3, 3, 13, 31, 39, 81, 199, 43, 863, 1563, 2811, 4551, 7469, 0 }; + static ulong[] dim1141JoeKuoD7Init = { 1, 1, 3, 5, 17, 59, 17, 9, 53, 527, 1689, 2365, 7673, 14581, 0 }; + static ulong[] dim1142JoeKuoD7Init = { 1, 3, 7, 5, 5, 5, 59, 21, 303, 43, 1379, 3297, 3053, 11115, 0 }; + static ulong[] dim1143JoeKuoD7Init = { 1, 1, 5, 15, 3, 33, 5, 253, 409, 321, 1487, 2083, 405, 15075, 0 }; + static ulong[] dim1144JoeKuoD7Init = { 1, 1, 3, 15, 11, 53, 99, 151, 33, 675, 1781, 1475, 2193, 6073, 0 }; + static ulong[] dim1145JoeKuoD7Init = { 1, 1, 3, 13, 27, 49, 83, 15, 335, 35, 1999, 237, 7359, 12173, 0 }; + static ulong[] dim1146JoeKuoD7Init = { 1, 3, 1, 15, 15, 61, 85, 243, 347, 745, 637, 1057, 5475, 15039, 0 }; + static ulong[] dim1147JoeKuoD7Init = { 1, 1, 3, 7, 1, 1, 31, 197, 499, 741, 191, 3799, 5485, 10129, 0 }; + static ulong[] dim1148JoeKuoD7Init = { 1, 1, 5, 5, 29, 15, 15, 185, 55, 685, 329, 605, 3365, 10203, 0 }; + static ulong[] dim1149JoeKuoD7Init = { 1, 3, 1, 13, 5, 1, 1, 169, 349, 591, 1961, 2989, 131, 2647, 0 }; + static ulong[] dim1150JoeKuoD7Init = { 1, 1, 7, 9, 17, 49, 95, 7, 57, 881, 1065, 3759, 5851, 7439, 0 }; + static ulong[] dim1151JoeKuoD7Init = { 1, 1, 3, 5, 27, 49, 65, 1, 177, 477, 453, 1823, 7615, 1285, 0 }; + static ulong[] dim1152JoeKuoD7Init = { 1, 1, 5, 9, 23, 25, 17, 149, 85, 373, 1585, 1227, 6127, 6003, 0 }; + static ulong[] dim1153JoeKuoD7Init = { 1, 1, 7, 13, 15, 61, 41, 141, 507, 391, 587, 2819, 3311, 853, 0 }; + static ulong[] dim1154JoeKuoD7Init = { 1, 1, 7, 13, 13, 23, 67, 171, 381, 285, 619, 457, 2751, 435, 0 }; + static ulong[] dim1155JoeKuoD7Init = { 1, 1, 5, 15, 13, 9, 21, 197, 385, 511, 1683, 2965, 1367, 7523, 0 }; + static ulong[] dim1156JoeKuoD7Init = { 1, 3, 7, 1, 23, 13, 21, 55, 415, 503, 1765, 1745, 5329, 4665, 0 }; + static ulong[] dim1157JoeKuoD7Init = { 1, 1, 1, 1, 21, 51, 49, 31, 195, 243, 1825, 2831, 467, 6527, 0 }; + static ulong[] dim1158JoeKuoD7Init = { 1, 1, 3, 3, 31, 37, 41, 139, 63, 517, 717, 415, 1137, 1855, 0 }; + static ulong[] dim1159JoeKuoD7Init = { 1, 1, 3, 15, 1, 45, 39, 9, 441, 809, 801, 3133, 2283, 8947, 0 }; + static ulong[] dim1160JoeKuoD7Init = { 1, 1, 3, 13, 13, 47, 55, 115, 155, 347, 1597, 415, 271, 4543, 0 }; + static ulong[] dim1161JoeKuoD7Init = { 1, 1, 1, 1, 1, 45, 5, 239, 187, 293, 59, 1319, 3839, 9945, 0 }; + static ulong[] dim1162JoeKuoD7Init = { 1, 1, 1, 15, 1, 41, 13, 19, 455, 881, 451, 1795, 239, 2695, 0 }; + static ulong[] dim1163JoeKuoD7Init = { 1, 3, 3, 9, 5, 25, 3, 19, 189, 377, 1017, 2501, 2707, 15333, 0 }; + static ulong[] dim1164JoeKuoD7Init = { 1, 1, 5, 5, 29, 57, 45, 35, 297, 663, 359, 2597, 7223, 6265, 0 }; + static ulong[] dim1165JoeKuoD7Init = { 1, 3, 1, 7, 1, 47, 125, 209, 65, 129, 211, 2535, 3617, 16229, 0 }; + static ulong[] dim1166JoeKuoD7Init = { 1, 1, 3, 11, 19, 29, 39, 177, 39, 807, 975, 835, 5509, 791, 0 }; + static ulong[] dim1167JoeKuoD7Init = { 1, 3, 3, 13, 31, 49, 69, 169, 433, 833, 1743, 3187, 8111, 15475, 0 }; + static ulong[] dim1168JoeKuoD7Init = { 1, 1, 5, 7, 31, 9, 27, 73, 335, 363, 1707, 1227, 6459, 12513, 0 }; + static ulong[] dim1169JoeKuoD7Init = { 1, 1, 7, 1, 1, 47, 109, 115, 429, 551, 1805, 3235, 579, 10039, 0 }; + static ulong[] dim1170JoeKuoD7Init = { 1, 1, 1, 7, 17, 61, 61, 1, 35, 917, 1513, 2141, 3939, 15755, 0 }; + static ulong[] dim1171JoeKuoD7Init = { 1, 1, 5, 1, 3, 27, 7, 219, 473, 875, 711, 703, 129, 16359, 0 }; + static ulong[] dim1172JoeKuoD7Init = { 1, 3, 5, 3, 27, 33, 97, 137, 19, 893, 233, 2605, 13, 875, 0 }; + static ulong[] dim1173JoeKuoD7Init = { 1, 3, 7, 11, 31, 43, 77, 225, 403, 861, 141, 2121, 707, 15753, 0 }; + static ulong[] dim1174JoeKuoD7Init = { 1, 1, 1, 3, 17, 33, 29, 103, 381, 179, 735, 2939, 7213, 12679, 0 }; + static ulong[] dim1175JoeKuoD7Init = { 1, 1, 1, 7, 5, 41, 43, 215, 239, 19, 625, 579, 5157, 12457, 0 }; + static ulong[] dim1176JoeKuoD7Init = { 1, 3, 1, 7, 15, 29, 93, 37, 241, 141, 1035, 3283, 193, 9873, 0 }; + static ulong[] dim1177JoeKuoD7Init = { 1, 1, 3, 13, 23, 11, 113, 153, 271, 515, 197, 3723, 1827, 11941, 0 }; + static ulong[] dim1178JoeKuoD7Init = { 1, 3, 7, 1, 29, 13, 45, 23, 421, 957, 1819, 1287, 5615, 4253, 0 }; + static ulong[] dim1179JoeKuoD7Init = { 1, 1, 3, 3, 11, 55, 47, 211, 85, 481, 1199, 3225, 5233, 4295, 0 }; + static ulong[] dim1180JoeKuoD7Init = { 1, 3, 3, 13, 11, 51, 93, 139, 271, 929, 863, 3227, 3075, 3587, 0 }; + static ulong[] dim1181JoeKuoD7Init = { 1, 1, 5, 11, 19, 59, 9, 221, 275, 171, 1703, 1495, 523, 5993, 0 }; + static ulong[] dim1182JoeKuoD7Init = { 1, 3, 1, 13, 15, 11, 21, 147, 291, 639, 1411, 33, 6845, 1431, 0 }; + static ulong[] dim1183JoeKuoD7Init = { 1, 3, 5, 1, 11, 11, 39, 195, 261, 19, 1803, 2869, 4507, 1131, 0 }; + static ulong[] dim1184JoeKuoD7Init = { 1, 3, 3, 11, 15, 27, 125, 5, 309, 569, 361, 4061, 2559, 1631, 0 }; + static ulong[] dim1185JoeKuoD7Init = { 1, 1, 5, 7, 23, 57, 37, 175, 35, 753, 755, 519, 5617, 1419, 0 }; + static ulong[] dim1186JoeKuoD7Init = { 1, 1, 5, 11, 21, 9, 107, 37, 121, 767, 1005, 2609, 2531, 14811, 0 }; + static ulong[] dim1187JoeKuoD7Init = { 1, 3, 7, 7, 3, 9, 91, 203, 219, 523, 319, 3021, 3465, 15579, 0 }; + static ulong[] dim1188JoeKuoD7Init = { 1, 3, 5, 1, 3, 29, 97, 249, 429, 665, 283, 595, 1527, 4559, 0 }; + static ulong[] dim1189JoeKuoD7Init = { 1, 1, 7, 15, 19, 23, 9, 169, 427, 171, 897, 3099, 7339, 13237, 0 }; + static ulong[] dim1190JoeKuoD7Init = { 1, 3, 5, 13, 11, 25, 11, 123, 229, 197, 1395, 2999, 3591, 5017, 0 }; + static ulong[] dim1191JoeKuoD7Init = { 1, 1, 7, 15, 3, 11, 49, 5, 217, 575, 445, 1381, 4407, 9777, 0 }; + static ulong[] dim1192JoeKuoD7Init = { 1, 1, 1, 13, 23, 43, 55, 19, 129, 925, 1623, 4037, 2535, 871, 0 }; + static ulong[] dim1193JoeKuoD7Init = { 1, 3, 3, 15, 3, 7, 29, 109, 251, 627, 1751, 3613, 5741, 7859, 0 }; + static ulong[] dim1194JoeKuoD7Init = { 1, 3, 5, 3, 23, 61, 115, 127, 157, 725, 1321, 1143, 3737, 12559, 0 }; + static ulong[] dim1195JoeKuoD7Init = { 1, 1, 7, 11, 25, 41, 117, 217, 389, 839, 1029, 547, 6149, 8335, 0 }; + static ulong[] dim1196JoeKuoD7Init = { 1, 3, 5, 1, 29, 61, 101, 81, 137, 547, 1989, 3907, 4855, 15949, 0 }; + static ulong[] dim1197JoeKuoD7Init = { 1, 3, 1, 3, 5, 9, 15, 33, 415, 725, 1183, 4091, 411, 4541, 0 }; + static ulong[] dim1198JoeKuoD7Init = { 1, 3, 3, 7, 31, 61, 53, 205, 157, 861, 989, 3265, 2943, 12941, 0 }; + static ulong[] dim1199JoeKuoD7Init = { 1, 3, 5, 11, 11, 13, 89, 39, 241, 153, 439, 2087, 5161, 5705, 0 }; + static ulong[] dim1200JoeKuoD7Init = { 1, 3, 3, 11, 15, 49, 39, 101, 1, 793, 1429, 2109, 1233, 3717, 0 }; + static ulong[] dim1201JoeKuoD7Init = { 1, 3, 7, 9, 29, 59, 45, 111, 157, 421, 853, 273, 1595, 1799, 0 }; + static ulong[] dim1202JoeKuoD7Init = { 1, 3, 7, 11, 3, 45, 31, 89, 475, 887, 563, 3985, 3011, 6903, 0 }; + static ulong[] dim1203JoeKuoD7Init = { 1, 3, 5, 15, 25, 13, 69, 3, 249, 435, 1333, 4079, 2259, 1971, 0 }; + static ulong[] dim1204JoeKuoD7Init = { 1, 3, 3, 11, 9, 51, 7, 203, 231, 155, 375, 2079, 6821, 12973, 0 }; + static ulong[] dim1205JoeKuoD7Init = { 1, 1, 1, 9, 5, 23, 115, 1, 307, 553, 1005, 2113, 6443, 8545, 0 }; + static ulong[] dim1206JoeKuoD7Init = { 1, 1, 3, 11, 7, 49, 49, 255, 73, 373, 413, 2997, 1403, 9501, 0 }; + static ulong[] dim1207JoeKuoD7Init = { 1, 3, 1, 15, 11, 31, 29, 43, 341, 119, 1209, 1471, 5785, 9809, 0 }; + static ulong[] dim1208JoeKuoD7Init = { 1, 1, 3, 15, 3, 35, 75, 187, 421, 911, 169, 1427, 7243, 10511, 0 }; + static ulong[] dim1209JoeKuoD7Init = { 1, 1, 1, 9, 3, 25, 21, 137, 437, 737, 1373, 3417, 2951, 7623, 0 }; + static ulong[] dim1210JoeKuoD7Init = { 1, 3, 1, 15, 27, 19, 97, 237, 341, 679, 473, 2775, 7195, 8093, 0 }; + static ulong[] dim1211JoeKuoD7Init = { 1, 3, 7, 3, 7, 45, 19, 109, 499, 883, 1473, 1907, 7229, 8063, 0 }; + static ulong[] dim1212JoeKuoD7Init = { 1, 3, 1, 1, 5, 49, 65, 213, 49, 941, 833, 3859, 3423, 5723, 0 }; + static ulong[] dim1213JoeKuoD7Init = { 1, 3, 3, 1, 27, 43, 53, 21, 379, 139, 1811, 133, 3641, 3021, 0 }; + static ulong[] dim1214JoeKuoD7Init = { 1, 3, 7, 9, 31, 49, 13, 17, 99, 773, 1127, 1237, 3593, 13233, 0 }; + static ulong[] dim1215JoeKuoD7Init = { 1, 1, 1, 9, 13, 21, 117, 29, 105, 671, 1423, 2449, 1979, 3717, 0 }; + static ulong[] dim1216JoeKuoD7Init = { 1, 3, 1, 13, 17, 55, 37, 45, 163, 475, 665, 115, 2175, 10065, 0 }; + static ulong[] dim1217JoeKuoD7Init = { 1, 1, 7, 9, 7, 31, 67, 215, 153, 981, 569, 2911, 6111, 12189, 0 }; + static ulong[] dim1218JoeKuoD7Init = { 1, 1, 3, 11, 19, 19, 101, 27, 131, 153, 505, 2897, 4573, 13713, 0 }; + static ulong[] dim1219JoeKuoD7Init = { 1, 1, 1, 9, 15, 21, 99, 187, 155, 135, 1421, 1421, 843, 3271, 0 }; + static ulong[] dim1220JoeKuoD7Init = { 1, 3, 1, 5, 1, 9, 17, 243, 111, 223, 1343, 3765, 2439, 717, 0 }; + static ulong[] dim1221JoeKuoD7Init = { 1, 1, 5, 3, 21, 9, 83, 191, 45, 813, 1047, 1483, 209, 2895, 0 }; + static ulong[] dim1222JoeKuoD7Init = { 1, 3, 5, 11, 29, 41, 119, 11, 245, 145, 969, 3017, 6403, 11387, 0 }; + static ulong[] dim1223JoeKuoD7Init = { 1, 1, 1, 13, 1, 19, 107, 35, 49, 381, 225, 595, 7145, 697, 0 }; + static ulong[] dim1224JoeKuoD7Init = { 1, 1, 1, 11, 5, 15, 37, 31, 117, 649, 1263, 1045, 3749, 16177, 0 }; + static ulong[] dim1225JoeKuoD7Init = { 1, 3, 7, 3, 7, 7, 91, 45, 395, 403, 1953, 743, 2207, 12887, 0 }; + static ulong[] dim1226JoeKuoD7Init = { 1, 1, 1, 11, 13, 31, 67, 7, 279, 389, 775, 301, 87, 6705, 0 }; + static ulong[] dim1227JoeKuoD7Init = { 1, 3, 1, 5, 27, 7, 85, 183, 325, 103, 1943, 2421, 4399, 7339, 0 }; + static ulong[] dim1228JoeKuoD7Init = { 1, 1, 7, 7, 21, 13, 69, 1, 289, 727, 1587, 3033, 2921, 12035, 0 }; + static ulong[] dim1229JoeKuoD7Init = { 1, 1, 7, 11, 31, 35, 103, 239, 89, 983, 433, 3027, 3089, 14439, 0 }; + static ulong[] dim1230JoeKuoD7Init = { 1, 3, 5, 9, 11, 9, 107, 207, 87, 563, 129, 2647, 3163, 11327, 0 }; + static ulong[] dim1231JoeKuoD7Init = { 1, 3, 7, 11, 9, 35, 115, 189, 293, 637, 213, 1111, 331, 10115, 0 }; + static ulong[] dim1232JoeKuoD7Init = { 1, 3, 5, 7, 21, 59, 127, 145, 157, 431, 295, 4055, 6207, 5353, 0 }; + static ulong[] dim1233JoeKuoD7Init = { 1, 1, 7, 5, 9, 53, 13, 249, 275, 841, 987, 3243, 7229, 6215, 0 }; + static ulong[] dim1234JoeKuoD7Init = { 1, 3, 5, 9, 11, 5, 47, 247, 57, 799, 1787, 2667, 3615, 4343, 0 }; + static ulong[] dim1235JoeKuoD7Init = { 1, 1, 1, 11, 31, 37, 73, 77, 181, 591, 445, 3081, 5337, 14259, 0 }; + static ulong[] dim1236JoeKuoD7Init = { 1, 3, 3, 11, 11, 49, 59, 229, 159, 139, 1435, 313, 7995, 5623, 0 }; + static ulong[] dim1237JoeKuoD7Init = { 1, 1, 7, 13, 17, 39, 53, 39, 413, 451, 2029, 1549, 485, 1311, 0 }; + static ulong[] dim1238JoeKuoD7Init = { 1, 1, 5, 11, 15, 57, 9, 245, 397, 587, 1733, 459, 2127, 16085, 0 }; + static ulong[] dim1239JoeKuoD7Init = { 1, 3, 3, 3, 17, 5, 17, 231, 439, 355, 1899, 1613, 1529, 12557, 0 }; + static ulong[] dim1240JoeKuoD7Init = { 1, 1, 1, 1, 5, 55, 113, 209, 441, 813, 1025, 191, 853, 2039, 0 }; + static ulong[] dim1241JoeKuoD7Init = { 1, 3, 3, 11, 9, 47, 89, 137, 187, 457, 1169, 3607, 3799, 15121, 0 }; + static ulong[] dim1242JoeKuoD7Init = { 1, 1, 3, 15, 15, 27, 93, 211, 137, 809, 1723, 1865, 6291, 13209, 0 }; + static ulong[] dim1243JoeKuoD7Init = { 1, 1, 5, 15, 5, 15, 67, 55, 445, 781, 829, 3237, 4031, 5147, 0 }; + static ulong[] dim1244JoeKuoD7Init = { 1, 3, 1, 3, 17, 59, 65, 35, 103, 515, 1409, 395, 711, 11773, 0 }; + static ulong[] dim1245JoeKuoD7Init = { 1, 1, 7, 11, 29, 5, 21, 117, 269, 963, 337, 3149, 2569, 9881, 0 }; + static ulong[] dim1246JoeKuoD7Init = { 1, 1, 5, 7, 1, 57, 61, 185, 431, 977, 661, 1285, 2607, 13465, 0 }; + static ulong[] dim1247JoeKuoD7Init = { 1, 3, 7, 5, 25, 35, 61, 227, 437, 75, 1677, 3337, 4601, 10447, 0 }; + static ulong[] dim1248JoeKuoD7Init = { 1, 3, 7, 1, 29, 29, 5, 163, 237, 217, 97, 1607, 911, 6195, 0 }; + static ulong[] dim1249JoeKuoD7Init = { 1, 1, 7, 3, 17, 7, 101, 31, 323, 191, 871, 1691, 3535, 8935, 0 }; + static ulong[] dim1250JoeKuoD7Init = { 1, 3, 5, 3, 11, 47, 117, 179, 25, 735, 989, 1623, 5321, 12603, 0 }; + static ulong[] dim1251JoeKuoD7Init = { 1, 1, 5, 11, 1, 55, 121, 221, 383, 969, 777, 3419, 2621, 1651, 0 }; + static ulong[] dim1252JoeKuoD7Init = { 1, 1, 7, 7, 21, 9, 95, 239, 221, 577, 1479, 1649, 6765, 5601, 0 }; + static ulong[] dim1253JoeKuoD7Init = { 1, 3, 3, 15, 29, 43, 49, 71, 255, 1011, 115, 1859, 7369, 16233, 0 }; + static ulong[] dim1254JoeKuoD7Init = { 1, 1, 3, 1, 13, 9, 21, 193, 255, 315, 1295, 1413, 6851, 4395, 0 }; + static ulong[] dim1255JoeKuoD7Init = { 1, 3, 1, 13, 21, 11, 75, 87, 453, 39, 503, 2937, 5089, 14211, 0 }; + static ulong[] dim1256JoeKuoD7Init = { 1, 1, 7, 13, 1, 17, 121, 153, 89, 113, 1969, 65, 4907, 10165, 0 }; + static ulong[] dim1257JoeKuoD7Init = { 1, 3, 5, 1, 17, 49, 75, 25, 147, 357, 617, 3245, 7313, 753, 0 }; + static ulong[] dim1258JoeKuoD7Init = { 1, 1, 7, 15, 25, 3, 71, 97, 463, 515, 989, 69, 687, 15151, 0 }; + static ulong[] dim1259JoeKuoD7Init = { 1, 3, 3, 3, 25, 61, 95, 219, 429, 143, 565, 463, 4165, 2619, 0 }; + static ulong[] dim1260JoeKuoD7Init = { 1, 1, 5, 13, 3, 45, 11, 59, 237, 387, 109, 253, 651, 13061, 0 }; + static ulong[] dim1261JoeKuoD7Init = { 1, 3, 7, 1, 25, 41, 111, 179, 321, 139, 453, 1061, 6395, 6391, 0 }; + static ulong[] dim1262JoeKuoD7Init = { 1, 3, 3, 1, 5, 11, 73, 131, 469, 839, 459, 2237, 2481, 10087, 0 }; + static ulong[] dim1263JoeKuoD7Init = { 1, 3, 7, 3, 13, 55, 75, 111, 411, 1007, 1303, 1613, 2449, 11337, 0 }; + static ulong[] dim1264JoeKuoD7Init = { 1, 1, 3, 1, 11, 39, 3, 193, 113, 927, 1345, 2747, 4951, 10543, 0 }; + static ulong[] dim1265JoeKuoD7Init = { 1, 3, 1, 15, 23, 39, 47, 115, 129, 51, 921, 1021, 6907, 8139, 0 }; + static ulong[] dim1266JoeKuoD7Init = { 1, 3, 1, 7, 31, 13, 75, 79, 331, 773, 1147, 335, 1729, 4015, 0 }; + static ulong[] dim1267JoeKuoD7Init = { 1, 3, 1, 7, 1, 47, 15, 183, 243, 525, 1515, 3209, 6597, 1895, 0 }; + static ulong[] dim1268JoeKuoD7Init = { 1, 1, 7, 3, 7, 59, 115, 223, 161, 181, 533, 1085, 3405, 2565, 0 }; + static ulong[] dim1269JoeKuoD7Init = { 1, 1, 5, 1, 9, 23, 57, 135, 113, 57, 143, 2949, 2703, 1813, 0 }; + static ulong[] dim1270JoeKuoD7Init = { 1, 3, 1, 9, 25, 43, 103, 7, 167, 393, 1515, 2871, 5167, 9943, 0 }; + static ulong[] dim1271JoeKuoD7Init = { 1, 1, 5, 1, 25, 1, 61, 49, 137, 157, 693, 3615, 1655, 14975, 0 }; + static ulong[] dim1272JoeKuoD7Init = { 1, 1, 7, 11, 21, 41, 89, 7, 171, 49, 1021, 3227, 3989, 11739, 0 }; + static ulong[] dim1273JoeKuoD7Init = { 1, 1, 3, 5, 31, 49, 13, 109, 435, 99, 1435, 709, 4085, 1233, 0 }; + static ulong[] dim1274JoeKuoD7Init = { 1, 1, 7, 1, 1, 55, 5, 107, 435, 663, 441, 3503, 5313, 159, 0 }; + static ulong[] dim1275JoeKuoD7Init = { 1, 1, 7, 13, 19, 57, 17, 13, 25, 1021, 2005, 3445, 4263, 3185, 0 }; + static ulong[] dim1276JoeKuoD7Init = { 1, 3, 1, 7, 5, 5, 37, 99, 237, 563, 483, 1991, 7217, 5433, 0 }; + static ulong[] dim1277JoeKuoD7Init = { 1, 3, 5, 9, 13, 13, 123, 51, 31, 957, 1125, 2125, 2157, 11437, 0 }; + static ulong[] dim1278JoeKuoD7Init = { 1, 1, 7, 11, 5, 59, 53, 193, 337, 5, 1037, 1573, 1147, 7055, 0 }; + static ulong[] dim1279JoeKuoD7Init = { 1, 3, 1, 9, 27, 47, 53, 121, 421, 551, 23, 1603, 1815, 2741, 0 }; + static ulong[] dim1280JoeKuoD7Init = { 1, 3, 3, 13, 27, 7, 79, 255, 209, 441, 1761, 1755, 7077, 3581, 0 }; + static ulong[] dim1281JoeKuoD7Init = { 1, 1, 7, 13, 3, 43, 113, 227, 43, 387, 1255, 1117, 6849, 11715, 0 }; + static ulong[] dim1282JoeKuoD7Init = { 1, 1, 7, 13, 15, 19, 59, 159, 265, 283, 615, 3745, 539, 15195, 0 }; + static ulong[] dim1283JoeKuoD7Init = { 1, 3, 1, 3, 7, 21, 29, 135, 203, 887, 549, 85, 8093, 12527, 0 }; + static ulong[] dim1284JoeKuoD7Init = { 1, 3, 7, 11, 5, 35, 41, 61, 273, 187, 1655, 2449, 2173, 14737, 0 }; + static ulong[] dim1285JoeKuoD7Init = { 1, 3, 1, 9, 29, 49, 11, 33, 477, 671, 1455, 2577, 5239, 5025, 0 }; + static ulong[] dim1286JoeKuoD7Init = { 1, 1, 7, 5, 23, 15, 67, 73, 73, 45, 1727, 645, 2623, 10859, 0 }; + static ulong[] dim1287JoeKuoD7Init = { 1, 1, 7, 15, 29, 37, 45, 183, 97, 297, 593, 833, 5833, 4777, 0 }; + static ulong[] dim1288JoeKuoD7Init = { 1, 1, 7, 5, 27, 21, 5, 253, 243, 993, 1701, 1695, 4037, 1891, 0 }; + static ulong[] dim1289JoeKuoD7Init = { 1, 3, 7, 1, 17, 37, 123, 21, 95, 533, 111, 2605, 7011, 7957, 0 }; + static ulong[] dim1290JoeKuoD7Init = { 1, 3, 1, 1, 5, 43, 11, 143, 457, 607, 469, 1479, 6181, 7579, 0 }; + static ulong[] dim1291JoeKuoD7Init = { 1, 3, 3, 15, 5, 59, 105, 111, 47, 53, 215, 1601, 8057, 4233, 0 }; + static ulong[] dim1292JoeKuoD7Init = { 1, 3, 1, 15, 7, 5, 17, 157, 47, 541, 1487, 2623, 1705, 5565, 0 }; + static ulong[] dim1293JoeKuoD7Init = { 1, 1, 1, 7, 21, 27, 63, 117, 323, 379, 1407, 4043, 3763, 10367, 0 }; + static ulong[] dim1294JoeKuoD7Init = { 1, 1, 3, 7, 27, 11, 35, 81, 447, 279, 811, 1355, 4185, 8281, 0 }; + static ulong[] dim1295JoeKuoD7Init = { 1, 3, 5, 15, 19, 41, 111, 225, 133, 79, 347, 3595, 7863, 5239, 0 }; + static ulong[] dim1296JoeKuoD7Init = { 1, 3, 1, 5, 17, 41, 77, 125, 221, 93, 551, 1263, 1973, 12081, 0 }; + static ulong[] dim1297JoeKuoD7Init = { 1, 3, 5, 3, 17, 55, 9, 149, 203, 217, 1235, 1905, 6139, 7223, 0 }; + static ulong[] dim1298JoeKuoD7Init = { 1, 3, 1, 9, 1, 3, 17, 5, 157, 739, 691, 1471, 709, 1355, 0 }; + static ulong[] dim1299JoeKuoD7Init = { 1, 1, 1, 9, 3, 13, 87, 153, 49, 391, 47, 1703, 1913, 12885, 0 }; + static ulong[] dim1300JoeKuoD7Init = { 1, 1, 7, 3, 19, 49, 91, 47, 263, 287, 1885, 3137, 3709, 8895, 0 }; + static ulong[] dim1301JoeKuoD7Init = { 1, 1, 5, 5, 19, 55, 59, 63, 229, 705, 1791, 1789, 4083, 11827, 0 }; + static ulong[] dim1302JoeKuoD7Init = { 1, 1, 3, 13, 21, 31, 127, 143, 57, 933, 125, 813, 6121, 5883, 0 }; + static ulong[] dim1303JoeKuoD7Init = { 1, 3, 5, 7, 7, 45, 39, 137, 219, 249, 791, 751, 4877, 6935, 0 }; + static ulong[] dim1304JoeKuoD7Init = { 1, 3, 1, 5, 31, 21, 11, 191, 399, 339, 815, 2459, 7621, 1279, 0 }; + static ulong[] dim1305JoeKuoD7Init = { 1, 1, 5, 13, 11, 49, 111, 101, 367, 645, 99, 1759, 2275, 8289, 0 }; + static ulong[] dim1306JoeKuoD7Init = { 1, 1, 1, 9, 15, 23, 17, 93, 339, 705, 1487, 3325, 6585, 13281, 0 }; + static ulong[] dim1307JoeKuoD7Init = { 1, 1, 3, 1, 17, 25, 69, 115, 339, 241, 777, 1585, 2565, 14843, 0 }; + static ulong[] dim1308JoeKuoD7Init = { 1, 3, 5, 7, 5, 45, 99, 161, 505, 511, 591, 2109, 5885, 12547, 0 }; + static ulong[] dim1309JoeKuoD7Init = { 1, 3, 5, 11, 13, 45, 87, 105, 387, 339, 1079, 705, 2385, 9375, 0 }; + static ulong[] dim1310JoeKuoD7Init = { 1, 3, 3, 1, 5, 19, 111, 155, 147, 897, 1879, 243, 3745, 2309, 0 }; + static ulong[] dim1311JoeKuoD7Init = { 1, 3, 3, 1, 1, 1, 123, 153, 409, 101, 105, 1713, 5161, 8915, 0 }; + static ulong[] dim1312JoeKuoD7Init = { 1, 3, 3, 11, 17, 5, 53, 145, 243, 811, 1413, 3735, 6857, 1151, 0 }; + static ulong[] dim1313JoeKuoD7Init = { 1, 1, 3, 13, 9, 35, 127, 245, 479, 691, 281, 845, 4017, 14011, 0 }; + static ulong[] dim1314JoeKuoD7Init = { 1, 1, 1, 15, 3, 27, 11, 231, 47, 1023, 1785, 4039, 137, 3429, 0 }; + static ulong[] dim1315JoeKuoD7Init = { 1, 1, 5, 5, 19, 45, 7, 251, 191, 387, 1853, 3851, 6237, 6475, 0 }; + static ulong[] dim1316JoeKuoD7Init = { 1, 1, 3, 15, 27, 19, 71, 13, 65, 679, 281, 2141, 1211, 4063, 0 }; + static ulong[] dim1317JoeKuoD7Init = { 1, 3, 5, 15, 7, 31, 73, 103, 393, 177, 1929, 809, 3389, 5673, 0 }; + static ulong[] dim1318JoeKuoD7Init = { 1, 1, 5, 7, 1, 45, 35, 247, 485, 25, 1079, 4019, 6101, 4715, 0 }; + static ulong[] dim1319JoeKuoD7Init = { 1, 3, 7, 7, 27, 13, 121, 177, 377, 585, 1503, 1249, 715, 309, 0 }; + static ulong[] dim1320JoeKuoD7Init = { 1, 1, 7, 7, 23, 19, 37, 19, 243, 261, 139, 1261, 3775, 10299, 0 }; + static ulong[] dim1321JoeKuoD7Init = { 1, 1, 1, 11, 23, 1, 123, 225, 497, 131, 1863, 4061, 1247, 12511, 0 }; + static ulong[] dim1322JoeKuoD7Init = { 1, 1, 7, 15, 5, 25, 59, 213, 157, 697, 671, 1431, 2891, 6881, 0 }; + static ulong[] dim1323JoeKuoD7Init = { 1, 1, 5, 9, 1, 33, 67, 121, 165, 867, 393, 1439, 1255, 11839, 0 }; + static ulong[] dim1324JoeKuoD7Init = { 1, 3, 5, 11, 23, 43, 11, 23, 507, 585, 277, 1077, 2697, 4901, 0 }; + static ulong[] dim1325JoeKuoD7Init = { 1, 3, 5, 15, 17, 35, 75, 177, 373, 113, 401, 1999, 1595, 10635, 0 }; + static ulong[] dim1326JoeKuoD7Init = { 1, 3, 7, 11, 31, 49, 65, 225, 217, 783, 787, 1421, 5701, 2185, 0 }; + static ulong[] dim1327JoeKuoD7Init = { 1, 1, 7, 15, 13, 45, 111, 23, 89, 263, 699, 4037, 6937, 6265, 0 }; + static ulong[] dim1328JoeKuoD7Init = { 1, 1, 1, 1, 15, 51, 49, 9, 221, 85, 1983, 2865, 2841, 3105, 0 }; + static ulong[] dim1329JoeKuoD7Init = { 1, 1, 7, 9, 5, 35, 75, 213, 177, 131, 1227, 4069, 5035, 4371, 0 }; + static ulong[] dim1330JoeKuoD7Init = { 1, 1, 7, 5, 1, 33, 75, 125, 5, 283, 667, 1521, 3267, 9641, 0 }; + static ulong[] dim1331JoeKuoD7Init = { 1, 3, 3, 11, 11, 49, 75, 125, 349, 887, 269, 2295, 4049, 1217, 0 }; + static ulong[] dim1332JoeKuoD7Init = { 1, 1, 3, 13, 17, 23, 19, 141, 213, 33, 475, 2543, 3617, 5791, 0 }; + static ulong[] dim1333JoeKuoD7Init = { 1, 3, 3, 11, 3, 39, 95, 139, 277, 109, 601, 2011, 2459, 5915, 0 }; + static ulong[] dim1334JoeKuoD7Init = { 1, 1, 5, 5, 27, 61, 35, 221, 329, 411, 1811, 3397, 1545, 10615, 0 }; + static ulong[] dim1335JoeKuoD7Init = { 1, 3, 5, 3, 3, 55, 71, 187, 371, 223, 1711, 3279, 5541, 4203, 0 }; + static ulong[] dim1336JoeKuoD7Init = { 1, 3, 7, 3, 27, 61, 23, 143, 475, 693, 1717, 353, 4381, 11355, 0 }; + static ulong[] dim1337JoeKuoD7Init = { 1, 1, 7, 13, 9, 23, 109, 11, 483, 1005, 1709, 2883, 5021, 10079, 0 }; + static ulong[] dim1338JoeKuoD7Init = { 1, 1, 5, 9, 25, 19, 79, 169, 433, 177, 1071, 3413, 2071, 3565, 0 }; + static ulong[] dim1339JoeKuoD7Init = { 1, 1, 5, 7, 7, 47, 105, 225, 153, 949, 9, 2383, 3947, 2711, 0 }; + static ulong[] dim1340JoeKuoD7Init = { 1, 3, 7, 9, 1, 17, 87, 159, 107, 41, 1459, 2133, 6261, 15637, 0 }; + static ulong[] dim1341JoeKuoD7Init = { 1, 3, 3, 3, 1, 7, 45, 255, 377, 811, 1911, 2727, 7223, 3825, 0 }; + static ulong[] dim1342JoeKuoD7Init = { 1, 1, 1, 13, 13, 13, 5, 59, 421, 585, 1651, 55, 2877, 11643, 0 }; + static ulong[] dim1343JoeKuoD7Init = { 1, 1, 3, 11, 15, 57, 1, 173, 189, 485, 1881, 3449, 1831, 2501, 0 }; + static ulong[] dim1344JoeKuoD7Init = { 1, 3, 3, 7, 21, 29, 49, 255, 313, 137, 51, 2281, 973, 16053, 0 }; + static ulong[] dim1345JoeKuoD7Init = { 1, 1, 1, 11, 23, 61, 99, 77, 399, 649, 1567, 1701, 4747, 1301, 0 }; + static ulong[] dim1346JoeKuoD7Init = { 1, 3, 7, 3, 11, 57, 45, 169, 247, 73, 1685, 341, 6791, 2833, 0 }; + static ulong[] dim1347JoeKuoD7Init = { 1, 1, 5, 13, 9, 5, 17, 209, 329, 379, 1787, 737, 7271, 7357, 0 }; + static ulong[] dim1348JoeKuoD7Init = { 1, 3, 1, 9, 13, 7, 97, 165, 99, 599, 471, 2945, 3125, 10413, 0 }; + static ulong[] dim1349JoeKuoD7Init = { 1, 3, 1, 11, 31, 29, 45, 3, 457, 673, 589, 2521, 5655, 13973, 0 }; + static ulong[] dim1350JoeKuoD7Init = { 1, 1, 7, 1, 15, 15, 61, 77, 321, 317, 993, 1101, 5885, 5105, 0 }; + static ulong[] dim1351JoeKuoD7Init = { 1, 1, 1, 5, 7, 45, 111, 129, 407, 117, 93, 2399, 1049, 12435, 0 }; + static ulong[] dim1352JoeKuoD7Init = { 1, 3, 7, 3, 11, 29, 103, 189, 29, 899, 1141, 1799, 4439, 2907, 0 }; + static ulong[] dim1353JoeKuoD7Init = { 1, 1, 1, 5, 3, 39, 25, 255, 97, 1015, 727, 377, 8015, 12617, 0 }; + static ulong[] dim1354JoeKuoD7Init = { 1, 3, 3, 11, 29, 23, 103, 51, 95, 333, 171, 3019, 1373, 13379, 0 }; + static ulong[] dim1355JoeKuoD7Init = { 1, 3, 1, 9, 21, 49, 57, 157, 337, 141, 307, 2333, 1857, 8739, 0 }; + static ulong[] dim1356JoeKuoD7Init = { 1, 1, 1, 11, 9, 35, 33, 93, 211, 969, 1093, 4053, 1313, 12771, 0 }; + static ulong[] dim1357JoeKuoD7Init = { 1, 3, 1, 9, 27, 7, 77, 65, 425, 603, 261, 2321, 579, 1249, 0 }; + static ulong[] dim1358JoeKuoD7Init = { 1, 3, 5, 13, 29, 39, 21, 243, 115, 201, 749, 3049, 3113, 1485, 0 }; + static ulong[] dim1359JoeKuoD7Init = { 1, 1, 5, 15, 23, 53, 27, 189, 193, 281, 149, 2205, 6149, 2669, 0 }; + static ulong[] dim1360JoeKuoD7Init = { 1, 1, 5, 13, 9, 13, 65, 37, 161, 59, 1691, 435, 6077, 14827, 0 }; + static ulong[] dim1361JoeKuoD7Init = { 1, 1, 3, 15, 5, 35, 41, 239, 177, 265, 389, 1829, 1229, 14351, 0 }; + static ulong[] dim1362JoeKuoD7Init = { 1, 1, 5, 3, 7, 27, 61, 107, 171, 411, 685, 455, 5175, 4981, 0 }; + static ulong[] dim1363JoeKuoD7Init = { 1, 1, 3, 7, 13, 23, 107, 63, 71, 755, 535, 1819, 1545, 2075, 0 }; + static ulong[] dim1364JoeKuoD7Init = { 1, 1, 5, 15, 1, 27, 61, 247, 333, 549, 981, 3201, 919, 1505, 0 }; + static ulong[] dim1365JoeKuoD7Init = { 1, 1, 3, 5, 29, 27, 93, 147, 105, 83, 209, 61, 3045, 4639, 0 }; + static ulong[] dim1366JoeKuoD7Init = { 1, 1, 7, 7, 25, 35, 77, 59, 157, 993, 325, 3085, 671, 3573, 0 }; + static ulong[] dim1367JoeKuoD7Init = { 1, 3, 1, 15, 15, 45, 31, 93, 367, 747, 969, 3443, 3825, 2997, 0 }; + static ulong[] dim1368JoeKuoD7Init = { 1, 1, 1, 5, 27, 21, 23, 63, 271, 515, 261, 1947, 6257, 12861, 0 }; + static ulong[] dim1369JoeKuoD7Init = { 1, 3, 7, 7, 27, 51, 31, 229, 225, 283, 947, 759, 5431, 2161, 0 }; + static ulong[] dim1370JoeKuoD7Init = { 1, 1, 3, 13, 7, 39, 5, 223, 55, 999, 697, 3383, 1605, 15315, 0 }; + static ulong[] dim1371JoeKuoD7Init = { 1, 1, 3, 3, 29, 13, 103, 215, 73, 715, 1117, 3399, 1867, 8049, 0 }; + static ulong[] dim1372JoeKuoD7Init = { 1, 3, 3, 3, 1, 33, 121, 135, 105, 335, 105, 815, 1601, 15785, 0 }; + static ulong[] dim1373JoeKuoD7Init = { 1, 1, 3, 13, 13, 27, 39, 119, 271, 75, 1531, 649, 8035, 5533, 0 }; + static ulong[] dim1374JoeKuoD7Init = { 1, 3, 7, 3, 9, 47, 109, 85, 135, 553, 1091, 3077, 5527, 15225, 0 }; + static ulong[] dim1375JoeKuoD7Init = { 1, 3, 3, 5, 31, 11, 127, 197, 257, 281, 1939, 3711, 2871, 11953, 0 }; + static ulong[] dim1376JoeKuoD7Init = { 1, 1, 1, 15, 21, 51, 57, 159, 445, 521, 27, 1313, 6031, 2891, 0 }; + static ulong[] dim1377JoeKuoD7Init = { 1, 1, 7, 15, 21, 57, 53, 29, 39, 547, 1995, 3605, 3899, 1199, 0 }; + static ulong[] dim1378JoeKuoD7Init = { 1, 1, 5, 3, 1, 59, 69, 21, 383, 743, 87, 3369, 2309, 9651, 0 }; + static ulong[] dim1379JoeKuoD7Init = { 1, 3, 7, 13, 3, 9, 41, 77, 201, 331, 1007, 1503, 5771, 567, 0 }; + static ulong[] dim1380JoeKuoD7Init = { 1, 1, 3, 15, 19, 19, 61, 221, 257, 903, 83, 1923, 6453, 11275, 0 }; + static ulong[] dim1381JoeKuoD7Init = { 1, 1, 5, 13, 21, 21, 101, 109, 419, 409, 125, 3337, 5763, 4945, 0 }; + static ulong[] dim1382JoeKuoD7Init = { 1, 1, 5, 11, 27, 21, 39, 63, 475, 285, 917, 4017, 1491, 9479, 0 }; + static ulong[] dim1383JoeKuoD7Init = { 1, 1, 7, 1, 23, 59, 119, 89, 309, 567, 1781, 2369, 4311, 16033, 0 }; + static ulong[] dim1384JoeKuoD7Init = { 1, 1, 1, 3, 13, 51, 69, 71, 89, 1013, 329, 69, 1107, 14509, 0 }; + static ulong[] dim1385JoeKuoD7Init = { 1, 1, 3, 7, 23, 39, 9, 137, 65, 83, 1001, 271, 2127, 9715, 0 }; + static ulong[] dim1386JoeKuoD7Init = { 1, 3, 3, 9, 13, 1, 67, 233, 333, 365, 1717, 77, 7173, 1271, 0 }; + static ulong[] dim1387JoeKuoD7Init = { 1, 3, 7, 7, 15, 3, 115, 237, 467, 827, 389, 1901, 6767, 7809, 0 }; + static ulong[] dim1388JoeKuoD7Init = { 1, 3, 1, 15, 23, 27, 117, 99, 49, 863, 1775, 1729, 8069, 9917, 0 }; + static ulong[] dim1389JoeKuoD7Init = { 1, 3, 1, 11, 23, 47, 75, 91, 47, 99, 1187, 1911, 2453, 5055, 0 }; + static ulong[] dim1390JoeKuoD7Init = { 1, 1, 7, 11, 15, 51, 43, 133, 175, 647, 1053, 439, 1933, 7339, 0 }; + static ulong[] dim1391JoeKuoD7Init = { 1, 1, 5, 13, 5, 37, 105, 243, 467, 255, 715, 1023, 4331, 8943, 0 }; + static ulong[] dim1392JoeKuoD7Init = { 1, 1, 1, 15, 15, 55, 59, 111, 351, 345, 1517, 3009, 4149, 8511, 0 }; + static ulong[] dim1393JoeKuoD7Init = { 1, 1, 7, 5, 3, 55, 123, 61, 405, 719, 245, 2745, 7471, 2205, 0 }; + static ulong[] dim1394JoeKuoD7Init = { 1, 1, 1, 9, 19, 25, 43, 105, 215, 117, 563, 513, 4609, 13307, 0 }; + static ulong[] dim1395JoeKuoD7Init = { 1, 3, 5, 5, 21, 27, 107, 131, 329, 519, 369, 2523, 4099, 13943, 0 }; + static ulong[] dim1396JoeKuoD7Init = { 1, 1, 3, 13, 27, 15, 25, 63, 5, 513, 1641, 3955, 4233, 12263, 0 }; + static ulong[] dim1397JoeKuoD7Init = { 1, 3, 5, 5, 3, 51, 49, 49, 197, 919, 281, 3713, 2179, 4573, 0 }; + static ulong[] dim1398JoeKuoD7Init = { 1, 1, 7, 5, 25, 15, 49, 159, 53, 609, 573, 1533, 4589, 10593, 0 }; + static ulong[] dim1399JoeKuoD7Init = { 1, 3, 5, 15, 7, 21, 61, 129, 53, 95, 1107, 57, 2559, 11977, 0 }; + static ulong[] dim1400JoeKuoD7Init = { 1, 1, 5, 5, 5, 5, 75, 153, 359, 345, 1739, 2047, 6355, 5801, 0 }; + static ulong[] dim1401JoeKuoD7Init = { 1, 3, 1, 13, 17, 5, 39, 209, 399, 127, 1215, 2377, 7707, 5191, 0 }; + static ulong[] dim1402JoeKuoD7Init = { 1, 1, 7, 3, 25, 31, 33, 93, 1, 229, 1379, 1587, 2245, 16041, 0 }; + static ulong[] dim1403JoeKuoD7Init = { 1, 3, 5, 13, 25, 51, 5, 1, 237, 471, 637, 3205, 4629, 15929, 0 }; + static ulong[] dim1404JoeKuoD7Init = { 1, 3, 5, 11, 27, 57, 45, 141, 167, 949, 1839, 289, 2637, 2041, 0 }; + static ulong[] dim1405JoeKuoD7Init = { 1, 1, 3, 7, 9, 57, 69, 93, 301, 805, 1265, 3415, 2395, 2949, 0 }; + static ulong[] dim1406JoeKuoD7Init = { 1, 1, 3, 15, 9, 61, 17, 185, 201, 743, 1903, 1161, 1693, 15125, 0 }; + static ulong[] dim1407JoeKuoD7Init = { 1, 3, 3, 3, 21, 47, 125, 117, 213, 761, 1357, 2455, 7065, 7335, 0 }; + static ulong[] dim1408JoeKuoD7Init = { 1, 3, 5, 7, 23, 15, 39, 17, 373, 777, 761, 3853, 3607, 2119, 0 }; + static ulong[] dim1409JoeKuoD7Init = { 1, 3, 1, 1, 31, 9, 45, 109, 209, 797, 777, 2381, 5047, 12453, 0 }; + static ulong[] dim1410JoeKuoD7Init = { 1, 3, 1, 1, 1, 9, 13, 171, 223, 987, 1815, 1953, 4439, 3973, 0 }; + static ulong[] dim1411JoeKuoD7Init = { 1, 1, 7, 9, 19, 11, 37, 87, 117, 399, 705, 2839, 3699, 13249, 0 }; + static ulong[] dim1412JoeKuoD7Init = { 1, 3, 3, 1, 21, 45, 25, 41, 133, 721, 289, 727, 7835, 9811, 0 }; + static ulong[] dim1413JoeKuoD7Init = { 1, 1, 7, 9, 23, 7, 75, 233, 113, 945, 1447, 4031, 6791, 6285, 0 }; + static ulong[] dim1414JoeKuoD7Init = { 1, 1, 3, 9, 3, 1, 127, 139, 391, 745, 807, 3229, 1809, 7587, 0 }; + static ulong[] dim1415JoeKuoD7Init = { 1, 1, 5, 3, 29, 47, 99, 115, 37, 487, 1897, 2433, 4925, 9747, 0 }; + static ulong[] dim1416JoeKuoD7Init = { 1, 1, 7, 15, 23, 25, 95, 165, 257, 67, 1445, 4055, 3761, 10411, 0 }; + static ulong[] dim1417JoeKuoD7Init = { 1, 3, 3, 11, 5, 27, 77, 197, 9, 679, 1259, 3289, 621, 2733, 0 }; + static ulong[] dim1418JoeKuoD7Init = { 1, 3, 7, 9, 27, 51, 57, 189, 511, 633, 431, 43, 2613, 5863, 0 }; + static ulong[] dim1419JoeKuoD7Init = { 1, 1, 1, 11, 29, 53, 79, 237, 15, 377, 45, 347, 5733, 3531, 0 }; + static ulong[] dim1420JoeKuoD7Init = { 1, 1, 1, 1, 25, 7, 87, 211, 429, 745, 673, 3967, 2059, 785, 0 }; + static ulong[] dim1421JoeKuoD7Init = { 1, 3, 1, 5, 21, 31, 7, 43, 381, 635, 35, 1247, 8061, 3907, 0 }; + static ulong[] dim1422JoeKuoD7Init = { 1, 3, 1, 9, 11, 39, 79, 9, 395, 611, 1087, 2837, 6979, 7651, 0 }; + static ulong[] dim1423JoeKuoD7Init = { 1, 3, 3, 13, 11, 37, 35, 61, 373, 1001, 1849, 2169, 903, 10993, 0 }; + static ulong[] dim1424JoeKuoD7Init = { 1, 1, 3, 3, 29, 3, 43, 155, 403, 597, 1437, 4031, 7169, 15333, 0 }; + static ulong[] dim1425JoeKuoD7Init = { 1, 3, 5, 1, 17, 29, 57, 245, 505, 915, 933, 1313, 7295, 12105, 0 }; + static ulong[] dim1426JoeKuoD7Init = { 1, 1, 3, 9, 29, 13, 49, 89, 377, 131, 31, 1869, 1717, 7679, 0 }; + static ulong[] dim1427JoeKuoD7Init = { 1, 1, 1, 7, 27, 43, 1, 107, 167, 851, 743, 2837, 6705, 2913, 0 }; + static ulong[] dim1428JoeKuoD7Init = { 1, 1, 3, 13, 5, 27, 77, 91, 305, 941, 1293, 2343, 5397, 6487, 0 }; + static ulong[] dim1429JoeKuoD7Init = { 1, 1, 7, 5, 11, 29, 25, 233, 391, 221, 1285, 3995, 2713, 9125, 0 }; + static ulong[] dim1430JoeKuoD7Init = { 1, 1, 7, 3, 11, 47, 77, 31, 233, 775, 1399, 1519, 3427, 10027, 0 }; + static ulong[] dim1431JoeKuoD7Init = { 1, 3, 3, 3, 5, 7, 37, 111, 265, 541, 77, 3327, 8115, 5541, 0 }; + static ulong[] dim1432JoeKuoD7Init = { 1, 1, 1, 5, 25, 27, 91, 185, 447, 225, 615, 2141, 2813, 9509, 0 }; + static ulong[] dim1433JoeKuoD7Init = { 1, 1, 7, 5, 15, 21, 107, 61, 259, 651, 1401, 3733, 6255, 5995, 0 }; + static ulong[] dim1434JoeKuoD7Init = { 1, 1, 7, 11, 21, 5, 121, 229, 497, 267, 1077, 3835, 4619, 8791, 0 }; + static ulong[] dim1435JoeKuoD7Init = { 1, 1, 3, 3, 19, 59, 85, 115, 19, 69, 1937, 711, 7911, 2615, 0 }; + static ulong[] dim1436JoeKuoD7Init = { 1, 3, 5, 11, 1, 9, 117, 229, 307, 355, 1635, 863, 4931, 5997, 0 }; + static ulong[] dim1437JoeKuoD7Init = { 1, 3, 5, 11, 21, 17, 119, 163, 297, 641, 291, 2287, 4611, 4419, 0 }; + static ulong[] dim1438JoeKuoD7Init = { 1, 1, 5, 7, 13, 59, 53, 17, 321, 263, 1929, 3277, 6209, 2649, 0 }; + static ulong[] dim1439JoeKuoD7Init = { 1, 3, 5, 13, 3, 35, 35, 249, 359, 479, 1067, 2507, 4809, 7427, 0 }; + static ulong[] dim1440JoeKuoD7Init = { 1, 3, 3, 1, 27, 57, 101, 47, 383, 937, 969, 307, 7617, 9579, 0 }; + static ulong[] dim1441JoeKuoD7Init = { 1, 1, 7, 13, 27, 61, 39, 177, 413, 435, 1529, 2773, 2267, 12597, 0 }; + static ulong[] dim1442JoeKuoD7Init = { 1, 3, 3, 5, 25, 61, 57, 175, 407, 341, 1979, 2237, 3557, 6841, 0 }; + static ulong[] dim1443JoeKuoD7Init = { 1, 3, 7, 5, 11, 23, 97, 247, 187, 555, 1603, 1871, 7427, 10605, 0 }; + static ulong[] dim1444JoeKuoD7Init = { 1, 1, 7, 15, 7, 21, 23, 165, 235, 937, 739, 2579, 6621, 12661, 0 }; + static ulong[] dim1445JoeKuoD7Init = { 1, 1, 5, 1, 13, 47, 103, 107, 87, 941, 563, 1007, 7483, 11721, 0 }; + static ulong[] dim1446JoeKuoD7Init = { 1, 1, 1, 15, 29, 63, 55, 215, 95, 991, 1017, 921, 8113, 11747, 0 }; + static ulong[] dim1447JoeKuoD7Init = { 1, 1, 3, 15, 3, 25, 79, 5, 401, 473, 125, 2135, 6443, 10773, 0 }; + static ulong[] dim1448JoeKuoD7Init = { 1, 3, 1, 9, 31, 21, 71, 185, 75, 43, 1131, 3885, 3879, 2695, 0 }; + static ulong[] dim1449JoeKuoD7Init = { 1, 1, 5, 13, 13, 41, 117, 109, 429, 473, 35, 123, 5545, 7015, 0 }; + static ulong[] dim1450JoeKuoD7Init = { 1, 1, 7, 13, 21, 57, 55, 241, 107, 689, 707, 45, 8175, 15185, 0 }; + static ulong[] dim1451JoeKuoD7Init = { 1, 3, 3, 7, 25, 5, 123, 173, 57, 517, 1605, 2355, 411, 14485, 0 }; + static ulong[] dim1452JoeKuoD7Init = { 1, 1, 3, 13, 11, 17, 95, 129, 9, 1013, 1683, 461, 697, 8089, 0 }; + static ulong[] dim1453JoeKuoD7Init = { 1, 1, 1, 3, 19, 49, 49, 247, 371, 175, 1803, 119, 365, 10281, 0 }; + static ulong[] dim1454JoeKuoD7Init = { 1, 1, 7, 15, 13, 57, 93, 245, 469, 933, 225, 2645, 6325, 9545, 0 }; + static ulong[] dim1455JoeKuoD7Init = { 1, 3, 1, 9, 11, 37, 1, 203, 227, 809, 2035, 99, 2693, 13591, 0 }; + static ulong[] dim1456JoeKuoD7Init = { 1, 3, 1, 3, 29, 7, 71, 7, 295, 203, 401, 461, 5351, 8223, 0 }; + static ulong[] dim1457JoeKuoD7Init = { 1, 1, 7, 1, 25, 31, 57, 35, 131, 411, 945, 1441, 4487, 2659, 0 }; + static ulong[] dim1458JoeKuoD7Init = { 1, 3, 7, 15, 15, 19, 89, 253, 141, 549, 751, 1267, 717, 7185, 0 }; + static ulong[] dim1459JoeKuoD7Init = { 1, 3, 5, 13, 1, 15, 61, 19, 331, 347, 1019, 1913, 6233, 8913, 0 }; + static ulong[] dim1460JoeKuoD7Init = { 1, 3, 7, 15, 7, 25, 59, 75, 455, 411, 325, 553, 5861, 915, 0 }; + static ulong[] dim1461JoeKuoD7Init = { 1, 1, 3, 5, 31, 49, 91, 107, 279, 405, 517, 55, 2121, 6971, 0 }; + static ulong[] dim1462JoeKuoD7Init = { 1, 3, 5, 7, 5, 39, 29, 205, 33, 827, 1593, 3503, 5461, 16147, 0 }; + static ulong[] dim1463JoeKuoD7Init = { 1, 1, 1, 13, 11, 13, 83, 99, 369, 283, 873, 1247, 6159, 15495, 0 }; + static ulong[] dim1464JoeKuoD7Init = { 1, 3, 1, 15, 25, 61, 71, 63, 333, 183, 1317, 3467, 5483, 11591, 0 }; + static ulong[] dim1465JoeKuoD7Init = { 1, 1, 1, 15, 27, 23, 1, 173, 407, 525, 1841, 347, 6103, 6449, 0 }; + static ulong[] dim1466JoeKuoD7Init = { 1, 1, 5, 3, 9, 45, 39, 215, 329, 457, 1341, 3037, 1631, 15335, 0 }; + static ulong[] dim1467JoeKuoD7Init = { 1, 3, 5, 3, 13, 53, 65, 177, 105, 21, 685, 3111, 7487, 1463, 0 }; + static ulong[] dim1468JoeKuoD7Init = { 1, 3, 5, 5, 5, 31, 69, 65, 381, 375, 221, 477, 3311, 12103, 0 }; + static ulong[] dim1469JoeKuoD7Init = { 1, 1, 7, 9, 25, 59, 57, 221, 293, 237, 429, 503, 6539, 14773, 0 }; + static ulong[] dim1470JoeKuoD7Init = { 1, 3, 7, 13, 9, 3, 47, 21, 115, 321, 389, 1631, 2715, 6607, 0 }; + static ulong[] dim1471JoeKuoD7Init = { 1, 3, 7, 15, 7, 31, 105, 5, 449, 195, 65, 3895, 7093, 3229, 0 }; + static ulong[] dim1472JoeKuoD7Init = { 1, 3, 7, 1, 1, 55, 119, 5, 39, 143, 905, 2813, 1723, 3705, 0 }; + static ulong[] dim1473JoeKuoD7Init = { 1, 3, 7, 3, 23, 47, 61, 239, 369, 485, 1857, 2105, 2681, 13723, 0 }; + static ulong[] dim1474JoeKuoD7Init = { 1, 3, 3, 5, 19, 5, 43, 155, 445, 597, 1201, 1625, 5273, 13569, 0 }; + static ulong[] dim1475JoeKuoD7Init = { 1, 1, 3, 9, 3, 63, 35, 103, 67, 259, 493, 2847, 1149, 8367, 0 }; + static ulong[] dim1476JoeKuoD7Init = { 1, 3, 7, 11, 19, 35, 15, 245, 59, 65, 75, 1297, 1637, 9081, 0 }; + static ulong[] dim1477JoeKuoD7Init = { 1, 1, 7, 11, 3, 23, 73, 163, 323, 857, 441, 399, 5447, 16365, 0 }; + static ulong[] dim1478JoeKuoD7Init = { 1, 3, 1, 7, 31, 55, 125, 255, 173, 203, 1537, 475, 2955, 12461, 0 }; + static ulong[] dim1479JoeKuoD7Init = { 1, 3, 5, 9, 27, 37, 69, 183, 319, 435, 807, 557, 7093, 2935, 0 }; + static ulong[] dim1480JoeKuoD7Init = { 1, 1, 3, 5, 23, 53, 105, 211, 49, 815, 97, 915, 7607, 8847, 0 }; + static ulong[] dim1481JoeKuoD7Init = { 1, 1, 1, 13, 13, 49, 43, 203, 293, 771, 1021, 535, 4655, 14727, 0 }; + static ulong[] dim1482JoeKuoD7Init = { 1, 3, 3, 5, 13, 49, 89, 75, 227, 821, 7, 2539, 7627, 6301, 0 }; + static ulong[] dim1483JoeKuoD7Init = { 1, 1, 3, 9, 5, 11, 35, 71, 187, 739, 1191, 2255, 2131, 13649, 0 }; + static ulong[] dim1484JoeKuoD7Init = { 1, 3, 1, 5, 5, 37, 105, 29, 453, 251, 1111, 2345, 6297, 14701, 0 }; + static ulong[] dim1485JoeKuoD7Init = { 1, 3, 1, 7, 31, 21, 5, 33, 245, 1007, 1981, 3775, 8169, 955, 0 }; + static ulong[] dim1486JoeKuoD7Init = { 1, 1, 3, 11, 11, 51, 45, 35, 351, 479, 1307, 3009, 7285, 5261, 0 }; + static ulong[] dim1487JoeKuoD7Init = { 1, 3, 3, 13, 5, 13, 119, 41, 175, 995, 1461, 2739, 7281, 7533, 0 }; + static ulong[] dim1488JoeKuoD7Init = { 1, 3, 5, 9, 7, 5, 7, 153, 233, 209, 1235, 3457, 3113, 13215, 0 }; + static ulong[] dim1489JoeKuoD7Init = { 1, 1, 3, 15, 9, 29, 41, 103, 389, 541, 1697, 893, 6507, 10805, 0 }; + static ulong[] dim1490JoeKuoD7Init = { 1, 1, 3, 3, 19, 11, 73, 73, 439, 985, 1215, 1481, 617, 5343, 0 }; + static ulong[] dim1491JoeKuoD7Init = { 1, 3, 7, 11, 7, 15, 81, 203, 41, 789, 283, 691, 3495, 12143, 0 }; + static ulong[] dim1492JoeKuoD7Init = { 1, 3, 7, 9, 21, 61, 101, 185, 193, 159, 13, 2571, 545, 3043, 0 }; + static ulong[] dim1493JoeKuoD7Init = { 1, 3, 7, 1, 11, 29, 107, 179, 69, 899, 1275, 1647, 1061, 12283, 0 }; + static ulong[] dim1494JoeKuoD7Init = { 1, 3, 1, 7, 15, 43, 3, 207, 75, 669, 1239, 1339, 571, 5483, 0 }; + static ulong[] dim1495JoeKuoD7Init = { 1, 3, 1, 1, 7, 23, 49, 183, 305, 309, 657, 1951, 6377, 4165, 0 }; + static ulong[] dim1496JoeKuoD7Init = { 1, 1, 1, 3, 5, 21, 51, 177, 101, 95, 1331, 357, 6777, 13199, 0 }; + static ulong[] dim1497JoeKuoD7Init = { 1, 3, 7, 3, 31, 3, 11, 179, 95, 219, 395, 603, 7397, 12045, 0 }; + static ulong[] dim1498JoeKuoD7Init = { 1, 3, 7, 1, 21, 35, 79, 255, 443, 123, 551, 1113, 8133, 11621, 0 }; + static ulong[] dim1499JoeKuoD7Init = { 1, 3, 7, 1, 11, 7, 125, 133, 429, 81, 91, 1135, 5165, 14953, 0 }; + static ulong[] dim1500JoeKuoD7Init = { 1, 3, 5, 9, 25, 17, 103, 39, 167, 459, 703, 759, 1771, 723, 0 }; + static ulong[] dim1501JoeKuoD7Init = { 1, 3, 5, 5, 7, 21, 113, 121, 97, 231, 59, 1679, 1409, 5045, 0 }; + static ulong[] dim1502JoeKuoD7Init = { 1, 3, 1, 9, 19, 17, 117, 225, 163, 183, 89, 2251, 4777, 14553, 0 }; + static ulong[] dim1503JoeKuoD7Init = { 1, 3, 1, 7, 7, 61, 25, 211, 65, 273, 1427, 585, 5907, 1031, 0 }; + static ulong[] dim1504JoeKuoD7Init = { 1, 1, 7, 3, 25, 27, 69, 113, 29, 67, 2025, 37, 7357, 14879, 0 }; + static ulong[] dim1505JoeKuoD7Init = { 1, 1, 5, 11, 23, 59, 107, 179, 187, 989, 1043, 409, 489, 3289, 0 }; + static ulong[] dim1506JoeKuoD7Init = { 1, 1, 1, 7, 5, 39, 79, 23, 443, 701, 789, 1723, 7595, 8003, 0 }; + static ulong[] dim1507JoeKuoD7Init = { 1, 3, 1, 11, 13, 25, 29, 167, 143, 735, 1623, 2005, 3731, 1413, 0 }; + static ulong[] dim1508JoeKuoD7Init = { 1, 1, 7, 13, 23, 19, 3, 143, 69, 331, 71, 3233, 4187, 13927, 0 }; + static ulong[] dim1509JoeKuoD7Init = { 1, 3, 3, 5, 23, 21, 121, 47, 291, 883, 43, 419, 297, 8385, 0 }; + static ulong[] dim1510JoeKuoD7Init = { 1, 1, 3, 5, 19, 63, 57, 127, 59, 539, 207, 3805, 4741, 12519, 0 }; + static ulong[] dim1511JoeKuoD7Init = { 1, 3, 3, 5, 5, 23, 117, 45, 501, 903, 1241, 3853, 989, 7997, 0 }; + static ulong[] dim1512JoeKuoD7Init = { 1, 1, 3, 5, 11, 27, 17, 21, 373, 755, 1149, 3443, 3489, 11701, 0 }; + static ulong[] dim1513JoeKuoD7Init = { 1, 1, 5, 7, 7, 55, 75, 29, 241, 707, 555, 1683, 1311, 14769, 0 }; + static ulong[] dim1514JoeKuoD7Init = { 1, 3, 5, 13, 19, 55, 87, 145, 27, 935, 519, 1083, 1115, 10963, 0 }; + static ulong[] dim1515JoeKuoD7Init = { 1, 1, 3, 13, 5, 11, 25, 215, 483, 817, 101, 981, 5125, 15257, 0 }; + static ulong[] dim1516JoeKuoD7Init = { 1, 3, 1, 11, 21, 59, 93, 55, 447, 5, 1225, 827, 1539, 4035, 0 }; + static ulong[] dim1517JoeKuoD7Init = { 1, 1, 1, 13, 3, 53, 5, 39, 475, 475, 905, 355, 6319, 415, 0 }; + static ulong[] dim1518JoeKuoD7Init = { 1, 1, 7, 9, 21, 49, 69, 109, 3, 441, 1533, 2359, 4025, 15949, 0 }; + static ulong[] dim1519JoeKuoD7Init = { 1, 1, 3, 13, 3, 59, 67, 147, 151, 27, 1039, 2331, 2839, 15939, 0 }; + static ulong[] dim1520JoeKuoD7Init = { 1, 3, 7, 9, 7, 17, 13, 153, 415, 147, 181, 3441, 7997, 3175, 0 }; + static ulong[] dim1521JoeKuoD7Init = { 1, 3, 5, 13, 9, 61, 123, 177, 497, 989, 525, 1819, 5963, 2051, 0 }; + static ulong[] dim1522JoeKuoD7Init = { 1, 1, 1, 1, 11, 13, 17, 147, 57, 367, 477, 1009, 4613, 16357, 0 }; + static ulong[] dim1523JoeKuoD7Init = { 1, 3, 7, 9, 27, 27, 29, 61, 499, 191, 43, 1109, 5805, 12799, 0 }; + static ulong[] dim1524JoeKuoD7Init = { 1, 3, 5, 9, 11, 61, 57, 139, 173, 725, 1879, 1861, 7123, 9505, 0 }; + static ulong[] dim1525JoeKuoD7Init = { 1, 3, 1, 5, 11, 1, 93, 179, 3, 893, 1917, 2293, 5105, 12093, 0 }; + static ulong[] dim1526JoeKuoD7Init = { 1, 1, 5, 9, 31, 45, 107, 19, 285, 81, 339, 3051, 1369, 10841, 0 }; + static ulong[] dim1527JoeKuoD7Init = { 1, 1, 7, 9, 27, 49, 19, 29, 155, 389, 1287, 3, 2311, 7561, 0 }; + static ulong[] dim1528JoeKuoD7Init = { 1, 3, 3, 9, 9, 1, 45, 171, 245, 897, 1881, 2683, 4185, 14049, 0 }; + static ulong[] dim1529JoeKuoD7Init = { 1, 3, 1, 15, 19, 37, 19, 227, 133, 573, 1897, 1231, 1649, 8481, 0 }; + static ulong[] dim1530JoeKuoD7Init = { 1, 3, 1, 15, 5, 19, 27, 85, 281, 471, 3, 2149, 4785, 12391, 0 }; + static ulong[] dim1531JoeKuoD7Init = { 1, 1, 7, 3, 17, 5, 127, 37, 299, 467, 1523, 3421, 4119, 11151, 0 }; + static ulong[] dim1532JoeKuoD7Init = { 1, 3, 3, 13, 11, 5, 15, 137, 459, 553, 785, 1149, 6107, 321, 0 }; + static ulong[] dim1533JoeKuoD7Init = { 1, 1, 3, 3, 7, 19, 85, 133, 7, 753, 65, 3341, 5859, 3829, 0 }; + static ulong[] dim1534JoeKuoD7Init = { 1, 3, 3, 11, 19, 13, 17, 191, 121, 895, 761, 2431, 5887, 10961, 0 }; + static ulong[] dim1535JoeKuoD7Init = { 1, 3, 5, 7, 1, 63, 47, 43, 119, 311, 935, 2299, 1509, 4821, 0 }; + static ulong[] dim1536JoeKuoD7Init = { 1, 1, 7, 7, 27, 51, 93, 195, 397, 155, 471, 2547, 8007, 15575, 0 }; + static ulong[] dim1537JoeKuoD7Init = { 1, 3, 3, 5, 25, 13, 125, 239, 93, 983, 293, 1317, 115, 6417, 0 }; + static ulong[] dim1538JoeKuoD7Init = { 1, 3, 3, 3, 9, 61, 93, 15, 495, 295, 1391, 2833, 45, 9039, 0 }; + static ulong[] dim1539JoeKuoD7Init = { 1, 1, 1, 9, 11, 31, 125, 5, 65, 173, 1189, 2363, 6603, 15891, 0 }; + static ulong[] dim1540JoeKuoD7Init = { 1, 1, 7, 5, 5, 63, 53, 35, 311, 935, 1591, 309, 7829, 1495, 0 }; + static ulong[] dim1541JoeKuoD7Init = { 1, 3, 5, 5, 29, 21, 121, 199, 153, 933, 1577, 1681, 1883, 7697, 0 }; + static ulong[] dim1542JoeKuoD7Init = { 1, 1, 1, 11, 19, 23, 111, 113, 73, 99, 1385, 591, 6977, 11995, 0 }; + static ulong[] dim1543JoeKuoD7Init = { 1, 1, 1, 13, 27, 11, 23, 79, 429, 505, 1693, 919, 3699, 3815, 0 }; + static ulong[] dim1544JoeKuoD7Init = { 1, 1, 3, 9, 7, 23, 29, 197, 465, 267, 915, 1455, 2155, 15105, 0 }; + static ulong[] dim1545JoeKuoD7Init = { 1, 1, 7, 9, 17, 3, 7, 73, 417, 841, 1123, 3425, 4691, 14703, 0 }; + static ulong[] dim1546JoeKuoD7Init = { 1, 3, 5, 15, 15, 7, 75, 85, 441, 5, 1593, 43, 1207, 12117, 0 }; + static ulong[] dim1547JoeKuoD7Init = { 1, 1, 1, 7, 21, 45, 93, 133, 31, 249, 701, 97, 1033, 15359, 0 }; + static ulong[] dim1548JoeKuoD7Init = { 1, 1, 3, 7, 3, 5, 9, 21, 339, 661, 1841, 2209, 5869, 10291, 0 }; + static ulong[] dim1549JoeKuoD7Init = { 1, 1, 5, 11, 13, 3, 67, 135, 69, 117, 43, 2885, 5719, 427, 0 }; + static ulong[] dim1550JoeKuoD7Init = { 1, 3, 1, 9, 15, 55, 45, 85, 423, 351, 169, 2693, 3063, 13471, 0 }; + static ulong[] dim1551JoeKuoD7Init = { 1, 1, 1, 7, 21, 17, 51, 59, 251, 697, 787, 3331, 7567, 15413, 0 }; + static ulong[] dim1552JoeKuoD7Init = { 1, 1, 7, 7, 29, 29, 113, 37, 347, 21, 223, 427, 4163, 6773, 0 }; + static ulong[] dim1553JoeKuoD7Init = { 1, 3, 5, 9, 25, 55, 89, 101, 327, 483, 1197, 1377, 3367, 15363, 0 }; + static ulong[] dim1554JoeKuoD7Init = { 1, 3, 3, 5, 15, 37, 87, 131, 279, 981, 623, 105, 3537, 6021, 0 }; + static ulong[] dim1555JoeKuoD7Init = { 1, 3, 5, 13, 19, 27, 49, 187, 249, 17, 1499, 3559, 1691, 525, 0 }; + static ulong[] dim1556JoeKuoD7Init = { 1, 1, 3, 11, 25, 55, 7, 145, 335, 975, 1007, 1853, 2509, 12895, 0 }; + static ulong[] dim1557JoeKuoD7Init = { 1, 1, 7, 15, 31, 29, 43, 91, 51, 543, 251, 3137, 1449, 2465, 0 }; + static ulong[] dim1558JoeKuoD7Init = { 1, 3, 7, 1, 25, 33, 107, 117, 439, 851, 1853, 1309, 7329, 6953, 0 }; + static ulong[] dim1559JoeKuoD7Init = { 1, 1, 7, 9, 13, 13, 105, 113, 161, 307, 939, 579, 6945, 3275, 0 }; + static ulong[] dim1560JoeKuoD7Init = { 1, 3, 3, 3, 19, 61, 85, 247, 31, 781, 599, 1731, 7907, 10855, 0 }; + static ulong[] dim1561JoeKuoD7Init = { 1, 3, 7, 15, 23, 13, 111, 197, 399, 273, 1339, 717, 6365, 11211, 0 }; + static ulong[] dim1562JoeKuoD7Init = { 1, 1, 1, 1, 7, 37, 83, 217, 351, 325, 787, 2735, 6797, 649, 0 }; + static ulong[] dim1563JoeKuoD7Init = { 1, 1, 7, 5, 25, 9, 29, 3, 305, 773, 933, 4091, 7515, 13513, 0 }; + static ulong[] dim1564JoeKuoD7Init = { 1, 1, 1, 7, 5, 9, 53, 79, 509, 101, 187, 4087, 5473, 8581, 0 }; + static ulong[] dim1565JoeKuoD7Init = { 1, 1, 3, 3, 9, 7, 59, 235, 219, 85, 1275, 329, 3661, 2135, 0 }; + static ulong[] dim1566JoeKuoD7Init = { 1, 1, 7, 15, 7, 43, 39, 153, 59, 91, 755, 827, 2399, 5395, 0 }; + static ulong[] dim1567JoeKuoD7Init = { 1, 3, 7, 3, 11, 29, 75, 195, 249, 789, 489, 1297, 1465, 449, 0 }; + static ulong[] dim1568JoeKuoD7Init = { 1, 3, 5, 13, 29, 13, 61, 111, 85, 335, 1835, 4025, 3433, 12839, 0 }; + static ulong[] dim1569JoeKuoD7Init = { 1, 1, 3, 1, 9, 45, 13, 179, 145, 161, 459, 3011, 7809, 11047, 0 }; + static ulong[] dim1570JoeKuoD7Init = { 1, 1, 5, 15, 27, 1, 81, 241, 89, 159, 681, 3525, 4487, 9129, 0 }; + static ulong[] dim1571JoeKuoD7Init = { 1, 3, 7, 15, 7, 1, 15, 103, 81, 59, 1953, 3729, 6451, 15051, 0 }; + static ulong[] dim1572JoeKuoD7Init = { 1, 3, 1, 1, 29, 7, 77, 77, 279, 1007, 1315, 1149, 301, 14183, 0 }; + static ulong[] dim1573JoeKuoD7Init = { 1, 1, 5, 11, 1, 1, 85, 23, 27, 211, 2023, 591, 2949, 10741, 0 }; + static ulong[] dim1574JoeKuoD7Init = { 1, 3, 1, 11, 31, 63, 49, 87, 291, 701, 531, 287, 6117, 16303, 0 }; + static ulong[] dim1575JoeKuoD7Init = { 1, 3, 3, 9, 27, 19, 19, 143, 95, 65, 1027, 2765, 2483, 14347, 0 }; + static ulong[] dim1576JoeKuoD7Init = { 1, 1, 7, 9, 3, 31, 31, 243, 45, 195, 1997, 3361, 7151, 12021, 0 }; + static ulong[] dim1577JoeKuoD7Init = { 1, 3, 3, 9, 11, 43, 83, 1, 389, 843, 1635, 3405, 2497, 4473, 0 }; + static ulong[] dim1578JoeKuoD7Init = { 1, 3, 5, 5, 15, 9, 65, 187, 107, 271, 1049, 1657, 1831, 12291, 0 }; + static ulong[] dim1579JoeKuoD7Init = { 1, 3, 7, 3, 29, 17, 107, 17, 253, 399, 481, 83, 3905, 5817, 0 }; + static ulong[] dim1580JoeKuoD7Init = { 1, 3, 5, 5, 21, 1, 93, 189, 451, 183, 1489, 379, 4673, 9323, 0 }; + static ulong[] dim1581JoeKuoD7Init = { 1, 3, 1, 9, 19, 25, 105, 97, 505, 569, 773, 3155, 3275, 11389, 0 }; + static ulong[] dim1582JoeKuoD7Init = { 1, 3, 3, 11, 29, 25, 87, 205, 321, 187, 239, 2217, 1063, 13323, 0 }; + static ulong[] dim1583JoeKuoD7Init = { 1, 1, 7, 13, 19, 47, 17, 243, 103, 515, 1049, 2119, 2185, 3137, 0 }; + static ulong[] dim1584JoeKuoD7Init = { 1, 3, 1, 15, 17, 19, 45, 191, 257, 453, 779, 3759, 6825, 5711, 0 }; + static ulong[] dim1585JoeKuoD7Init = { 1, 3, 3, 15, 15, 41, 41, 181, 185, 91, 375, 2825, 3841, 14179, 0 }; + static ulong[] dim1586JoeKuoD7Init = { 1, 1, 5, 13, 23, 11, 93, 117, 135, 333, 1985, 3355, 2119, 10511, 0 }; + static ulong[] dim1587JoeKuoD7Init = { 1, 3, 7, 15, 5, 59, 17, 141, 291, 897, 657, 2805, 4423, 559, 0 }; + static ulong[] dim1588JoeKuoD7Init = { 1, 3, 7, 1, 19, 55, 33, 77, 321, 989, 1713, 1553, 5541, 12995, 0 }; + static ulong[] dim1589JoeKuoD7Init = { 1, 1, 3, 5, 11, 9, 69, 123, 223, 201, 1505, 1119, 381, 12361, 0 }; + static ulong[] dim1590JoeKuoD7Init = { 1, 1, 7, 7, 13, 13, 15, 107, 143, 925, 1741, 3697, 5379, 10661, 0 }; + static ulong[] dim1591JoeKuoD7Init = { 1, 1, 5, 1, 25, 43, 47, 209, 57, 1015, 1721, 1707, 3675, 2651, 0 }; + static ulong[] dim1592JoeKuoD7Init = { 1, 3, 3, 3, 21, 27, 101, 41, 309, 585, 159, 2029, 5307, 5919, 0 }; + static ulong[] dim1593JoeKuoD7Init = { 1, 1, 5, 7, 13, 53, 43, 71, 259, 331, 1317, 3367, 2593, 4667, 0 }; + static ulong[] dim1594JoeKuoD7Init = { 1, 3, 7, 13, 1, 31, 115, 159, 203, 39, 19, 1939, 2601, 14819, 0 }; + static ulong[] dim1595JoeKuoD7Init = { 1, 3, 7, 9, 1, 33, 101, 145, 401, 655, 543, 2063, 425, 6397, 0 }; + static ulong[] dim1596JoeKuoD7Init = { 1, 3, 3, 1, 1, 13, 15, 19, 347, 679, 107, 933, 8097, 16213, 0 }; + static ulong[] dim1597JoeKuoD7Init = { 1, 3, 1, 5, 9, 47, 15, 95, 191, 887, 69, 3775, 7839, 767, 0 }; + static ulong[] dim1598JoeKuoD7Init = { 1, 1, 5, 13, 17, 37, 43, 241, 401, 273, 1819, 2437, 2027, 5763, 0 }; + static ulong[] dim1599JoeKuoD7Init = { 1, 1, 3, 11, 25, 49, 31, 17, 153, 771, 1151, 1575, 1719, 12567, 0 }; + static ulong[] dim1600JoeKuoD7Init = { 1, 3, 7, 9, 19, 31, 33, 227, 15, 645, 1499, 967, 6459, 975, 0 }; + static ulong[] dim1601JoeKuoD7Init = { 1, 3, 1, 1, 5, 23, 31, 105, 47, 761, 1911, 3889, 67, 5543, 0 }; + static ulong[] dim1602JoeKuoD7Init = { 1, 1, 5, 3, 15, 1, 7, 119, 247, 759, 1277, 1233, 1055, 15651, 0 }; + static ulong[] dim1603JoeKuoD7Init = { 1, 1, 1, 1, 15, 33, 117, 189, 93, 511, 1709, 3329, 619, 3561, 0 }; + static ulong[] dim1604JoeKuoD7Init = { 1, 1, 7, 9, 21, 39, 35, 59, 121, 149, 2015, 1127, 8035, 8197, 0 }; + static ulong[] dim1605JoeKuoD7Init = { 1, 3, 7, 9, 25, 3, 43, 189, 257, 343, 607, 285, 6003, 1119, 0 }; + static ulong[] dim1606JoeKuoD7Init = { 1, 1, 5, 11, 7, 41, 53, 193, 343, 353, 1743, 1877, 2207, 10765, 0 }; + static ulong[] dim1607JoeKuoD7Init = { 1, 1, 3, 1, 3, 59, 117, 15, 199, 639, 1597, 3833, 7167, 9437, 0 }; + static ulong[] dim1608JoeKuoD7Init = { 1, 3, 7, 13, 15, 49, 79, 19, 131, 1021, 1881, 1113, 6191, 7549, 0 }; + static ulong[] dim1609JoeKuoD7Init = { 1, 1, 5, 5, 29, 57, 69, 181, 167, 179, 317, 4069, 3885, 2641, 0 }; + static ulong[] dim1610JoeKuoD7Init = { 1, 3, 3, 7, 1, 15, 13, 69, 425, 491, 327, 1387, 5333, 14555, 0 }; + static ulong[] dim1611JoeKuoD7Init = { 1, 1, 7, 3, 3, 33, 99, 169, 245, 155, 1843, 2435, 2853, 8871, 0 }; + static ulong[] dim1612JoeKuoD7Init = { 1, 1, 1, 11, 27, 37, 107, 163, 399, 933, 1867, 3321, 2737, 4941, 0 }; + static ulong[] dim1613JoeKuoD7Init = { 1, 3, 5, 11, 27, 25, 31, 193, 219, 21, 1811, 2515, 1027, 10337, 0 }; + static ulong[] dim1614JoeKuoD7Init = { 1, 3, 7, 1, 13, 23, 75, 175, 265, 71, 597, 521, 5343, 5615, 0 }; + static ulong[] dim1615JoeKuoD7Init = { 1, 3, 1, 11, 27, 13, 23, 187, 281, 593, 1559, 1355, 637, 15835, 0 }; + static ulong[] dim1616JoeKuoD7Init = { 1, 3, 5, 15, 25, 7, 29, 1, 403, 175, 401, 3521, 1077, 8699, 0 }; + static ulong[] dim1617JoeKuoD7Init = { 1, 1, 7, 5, 31, 27, 79, 135, 439, 935, 783, 2981, 3747, 10697, 0 }; + static ulong[] dim1618JoeKuoD7Init = { 1, 3, 1, 3, 25, 1, 119, 53, 107, 841, 909, 265, 3845, 8613, 0 }; + static ulong[] dim1619JoeKuoD7Init = { 1, 3, 3, 7, 13, 53, 3, 159, 453, 711, 399, 3267, 1245, 8747, 0 }; + static ulong[] dim1620JoeKuoD7Init = { 1, 1, 1, 9, 15, 59, 99, 255, 331, 241, 1389, 3885, 7497, 13169, 0 }; + static ulong[] dim1621JoeKuoD7Init = { 1, 3, 5, 9, 11, 23, 49, 77, 239, 341, 453, 763, 3241, 13097, 0 }; + static ulong[] dim1622JoeKuoD7Init = { 1, 3, 7, 15, 21, 15, 65, 221, 167, 17, 1621, 4043, 1643, 13481, 0 }; + static ulong[] dim1623JoeKuoD7Init = { 1, 3, 1, 9, 1, 35, 125, 157, 437, 49, 1145, 861, 4323, 11839, 0 }; + static ulong[] dim1624JoeKuoD7Init = { 1, 1, 3, 5, 27, 27, 125, 61, 401, 251, 1171, 2409, 63, 11279, 0 }; + static ulong[] dim1625JoeKuoD7Init = { 1, 3, 3, 5, 27, 57, 39, 37, 337, 999, 549, 2071, 5547, 315, 0 }; + static ulong[] dim1626JoeKuoD7Init = { 1, 1, 1, 15, 29, 29, 119, 89, 325, 665, 783, 1683, 6185, 4301, 0 }; + static ulong[] dim1627JoeKuoD7Init = { 1, 3, 7, 7, 7, 25, 111, 99, 411, 549, 949, 735, 6881, 4681, 0 }; + static ulong[] dim1628JoeKuoD7Init = { 1, 3, 5, 15, 21, 3, 117, 83, 473, 595, 1061, 3905, 4985, 6149, 0 }; + static ulong[] dim1629JoeKuoD7Init = { 1, 3, 7, 1, 17, 13, 27, 101, 95, 773, 1095, 2813, 6253, 2817, 0 }; + static ulong[] dim1630JoeKuoD7Init = { 1, 1, 5, 9, 1, 9, 91, 43, 153, 627, 49, 1109, 1395, 2971, 0 }; + static ulong[] dim1631JoeKuoD7Init = { 1, 3, 7, 11, 25, 57, 1, 141, 227, 161, 3, 2509, 2675, 14093, 0 }; + static ulong[] dim1632JoeKuoD7Init = { 1, 1, 7, 7, 27, 35, 85, 103, 321, 331, 351, 2831, 911, 13259, 0 }; + static ulong[] dim1633JoeKuoD7Init = { 1, 1, 1, 9, 29, 59, 57, 199, 27, 303, 1001, 1393, 3345, 11169, 0 }; + static ulong[] dim1634JoeKuoD7Init = { 1, 3, 5, 15, 11, 37, 83, 127, 79, 683, 669, 1793, 2271, 1643, 0 }; + static ulong[] dim1635JoeKuoD7Init = { 1, 1, 7, 5, 9, 45, 65, 143, 489, 91, 1819, 2679, 4003, 13961, 0 }; + static ulong[] dim1636JoeKuoD7Init = { 1, 3, 1, 1, 5, 9, 127, 61, 209, 597, 463, 961, 1739, 13955, 0 }; + static ulong[] dim1637JoeKuoD7Init = { 1, 3, 5, 11, 29, 13, 73, 61, 233, 891, 1477, 501, 7781, 15911, 0 }; + static ulong[] dim1638JoeKuoD7Init = { 1, 3, 5, 3, 23, 23, 99, 227, 385, 503, 405, 3825, 535, 5997, 0 }; + static ulong[] dim1639JoeKuoD7Init = { 1, 1, 7, 7, 11, 31, 105, 103, 383, 897, 1049, 2757, 7687, 13175, 0 }; + static ulong[] dim1640JoeKuoD7Init = { 1, 1, 3, 15, 7, 55, 43, 205, 451, 195, 1973, 1963, 5791, 14413, 0 }; + static ulong[] dim1641JoeKuoD7Init = { 1, 1, 7, 13, 7, 5, 35, 215, 415, 221, 1245, 399, 1471, 9559, 0 }; + static ulong[] dim1642JoeKuoD7Init = { 1, 3, 1, 13, 3, 27, 119, 245, 291, 633, 641, 779, 533, 12031, 0 }; + static ulong[] dim1643JoeKuoD7Init = { 1, 1, 1, 11, 21, 41, 83, 93, 91, 671, 1579, 3375, 7109, 12321, 0 }; + static ulong[] dim1644JoeKuoD7Init = { 1, 1, 5, 1, 27, 47, 19, 161, 103, 455, 2027, 1461, 633, 5815, 0 }; + static ulong[] dim1645JoeKuoD7Init = { 1, 3, 5, 11, 25, 11, 115, 95, 15, 979, 89, 2489, 255, 13683, 0 }; + static ulong[] dim1646JoeKuoD7Init = { 1, 1, 5, 5, 31, 55, 85, 223, 231, 9, 493, 3117, 3431, 12139, 0 }; + static ulong[] dim1647JoeKuoD7Init = { 1, 1, 1, 13, 1, 59, 5, 33, 111, 711, 1111, 3337, 6595, 15149, 0 }; + static ulong[] dim1648JoeKuoD7Init = { 1, 3, 3, 5, 27, 9, 85, 243, 141, 155, 2007, 673, 3613, 9837, 0 }; + static ulong[] dim1649JoeKuoD7Init = { 1, 3, 1, 13, 17, 53, 105, 125, 295, 467, 29, 1501, 2841, 1531, 0 }; + static ulong[] dim1650JoeKuoD7Init = { 1, 3, 1, 1, 15, 35, 95, 73, 273, 5, 515, 185, 5845, 15793, 0 }; + static ulong[] dim1651JoeKuoD7Init = { 1, 3, 7, 15, 1, 9, 117, 229, 219, 723, 1641, 2639, 5711, 10337, 0 }; + static ulong[] dim1652JoeKuoD7Init = { 1, 1, 5, 1, 9, 47, 13, 179, 353, 167, 1255, 4053, 1279, 6181, 0 }; + static ulong[] dim1653JoeKuoD7Init = { 1, 1, 5, 11, 3, 29, 47, 63, 127, 355, 1459, 441, 6849, 12995, 0 }; + static ulong[] dim1654JoeKuoD7Init = { 1, 1, 5, 5, 15, 27, 99, 11, 63, 405, 1025, 2047, 7239, 13019, 0 }; + static ulong[] dim1655JoeKuoD7Init = { 1, 3, 3, 15, 31, 1, 17, 109, 7, 251, 517, 2923, 2967, 15609, 0 }; + static ulong[] dim1656JoeKuoD7Init = { 1, 3, 5, 5, 5, 9, 89, 77, 77, 619, 793, 195, 3507, 4203, 0 }; + static ulong[] dim1657JoeKuoD7Init = { 1, 3, 1, 1, 29, 47, 83, 117, 387, 601, 35, 1327, 6381, 7673, 0 }; + static ulong[] dim1658JoeKuoD7Init = { 1, 1, 7, 3, 21, 7, 33, 41, 161, 53, 1635, 787, 6197, 4841, 0 }; + static ulong[] dim1659JoeKuoD7Init = { 1, 3, 7, 11, 5, 33, 29, 43, 289, 805, 109, 2099, 7851, 809, 0 }; + static ulong[] dim1660JoeKuoD7Init = { 1, 3, 7, 7, 7, 39, 79, 147, 129, 307, 93, 3349, 7329, 14213, 0 }; + static ulong[] dim1661JoeKuoD7Init = { 1, 3, 5, 13, 27, 59, 35, 235, 413, 631, 1201, 1317, 5489, 13277, 0 }; + static ulong[] dim1662JoeKuoD7Init = { 1, 3, 5, 7, 27, 57, 57, 83, 273, 973, 767, 3993, 5337, 15679, 0 }; + static ulong[] dim1663JoeKuoD7Init = { 1, 1, 1, 11, 29, 49, 63, 211, 253, 947, 21, 1993, 6775, 1551, 0 }; + static ulong[] dim1664JoeKuoD7Init = { 1, 3, 5, 15, 27, 17, 37, 81, 83, 991, 1509, 1931, 7389, 6053, 0 }; + static ulong[] dim1665JoeKuoD7Init = { 1, 3, 3, 15, 19, 23, 53, 225, 131, 935, 333, 577, 7893, 13339, 0 }; + static ulong[] dim1666JoeKuoD7Init = { 1, 1, 7, 1, 27, 41, 97, 131, 135, 857, 89, 2285, 223, 15595, 0 }; + static ulong[] dim1667JoeKuoD7Init = { 1, 1, 5, 13, 13, 29, 47, 179, 63, 261, 1409, 3921, 653, 12425, 0 }; + static ulong[] dim1668JoeKuoD7Init = { 1, 3, 1, 7, 15, 53, 121, 7, 287, 251, 579, 1415, 453, 15615, 0 }; + static ulong[] dim1669JoeKuoD7Init = { 1, 3, 1, 5, 3, 9, 41, 105, 505, 37, 665, 3323, 3613, 4533, 0 }; + static ulong[] dim1670JoeKuoD7Init = { 1, 1, 3, 1, 5, 57, 53, 107, 279, 169, 1797, 3395, 7325, 5825, 0 }; + static ulong[] dim1671JoeKuoD7Init = { 1, 3, 3, 13, 19, 23, 33, 145, 15, 459, 711, 2883, 2879, 7437, 0 }; + static ulong[] dim1672JoeKuoD7Init = { 1, 1, 1, 1, 23, 17, 81, 233, 85, 435, 169, 287, 5913, 11063, 0 }; + static ulong[] dim1673JoeKuoD7Init = { 1, 3, 1, 9, 23, 5, 7, 9, 393, 243, 1301, 365, 7529, 13875, 0 }; + static ulong[] dim1674JoeKuoD7Init = { 1, 1, 1, 1, 9, 43, 127, 81, 49, 783, 1079, 4059, 5829, 7873, 0 }; + static ulong[] dim1675JoeKuoD7Init = { 1, 3, 7, 7, 29, 49, 123, 81, 73, 137, 895, 791, 6801, 1209, 0 }; + static ulong[] dim1676JoeKuoD7Init = { 1, 1, 5, 13, 7, 63, 93, 177, 263, 373, 39, 1713, 6793, 215, 0 }; + static ulong[] dim1677JoeKuoD7Init = { 1, 3, 5, 9, 31, 19, 105, 187, 55, 715, 505, 2597, 2923, 16351, 0 }; + static ulong[] dim1678JoeKuoD7Init = { 1, 3, 1, 15, 9, 29, 113, 41, 83, 667, 605, 1033, 1525, 2781, 0 }; + static ulong[] dim1679JoeKuoD7Init = { 1, 3, 3, 5, 29, 27, 123, 159, 3, 659, 1757, 3603, 6419, 10125, 0 }; + static ulong[] dim1680JoeKuoD7Init = { 1, 3, 3, 3, 17, 19, 1, 19, 459, 833, 1149, 413, 1835, 12449, 0 }; + static ulong[] dim1681JoeKuoD7Init = { 1, 3, 3, 15, 27, 13, 109, 233, 341, 943, 173, 2491, 445, 5669, 0 }; + static ulong[] dim1682JoeKuoD7Init = { 1, 1, 7, 13, 17, 37, 53, 79, 107, 263, 353, 1193, 4445, 13969, 0 }; + static ulong[] dim1683JoeKuoD7Init = { 1, 1, 5, 7, 17, 55, 49, 53, 9, 831, 1551, 1105, 7797, 10667, 0 }; + static ulong[] dim1684JoeKuoD7Init = { 1, 3, 3, 13, 23, 9, 77, 85, 297, 875, 1339, 3019, 7211, 363, 0 }; + static ulong[] dim1685JoeKuoD7Init = { 1, 1, 7, 3, 13, 11, 13, 239, 235, 299, 1433, 3913, 6793, 8471, 0 }; + static ulong[] dim1686JoeKuoD7Init = { 1, 3, 7, 15, 15, 43, 109, 33, 221, 543, 1067, 559, 2541, 5601, 0 }; + static ulong[] dim1687JoeKuoD7Init = { 1, 1, 7, 11, 15, 51, 77, 125, 195, 435, 1769, 1047, 2509, 11143, 0 }; + static ulong[] dim1688JoeKuoD7Init = { 1, 1, 5, 13, 19, 43, 31, 115, 357, 197, 119, 1709, 1851, 5625, 0 }; + static ulong[] dim1689JoeKuoD7Init = { 1, 1, 1, 15, 25, 19, 127, 165, 241, 255, 1737, 4053, 5987, 2573, 0 }; + static ulong[] dim1690JoeKuoD7Init = { 1, 3, 3, 1, 5, 5, 21, 203, 379, 147, 1793, 461, 4863, 14659, 0 }; + static ulong[] dim1691JoeKuoD7Init = { 1, 1, 3, 13, 15, 41, 125, 191, 471, 863, 485, 1029, 6375, 7825, 0 }; + static ulong[] dim1692JoeKuoD7Init = { 1, 1, 5, 1, 13, 47, 53, 221, 351, 621, 1025, 3729, 367, 16091, 0 }; + static ulong[] dim1693JoeKuoD7Init = { 1, 1, 7, 11, 1, 47, 11, 91, 485, 601, 235, 241, 6631, 3159, 0 }; + static ulong[] dim1694JoeKuoD7Init = { 1, 1, 7, 11, 9, 59, 41, 121, 87, 969, 667, 3845, 3317, 14095, 0 }; + static ulong[] dim1695JoeKuoD7Init = { 1, 3, 3, 9, 17, 43, 95, 111, 253, 497, 1263, 1323, 2669, 11567, 0 }; + static ulong[] dim1696JoeKuoD7Init = { 1, 3, 1, 5, 17, 45, 15, 231, 7, 125, 67, 27, 5397, 15347, 0 }; + static ulong[] dim1697JoeKuoD7Init = { 1, 1, 7, 13, 15, 59, 119, 203, 89, 987, 337, 3313, 5533, 13157, 0 }; + static ulong[] dim1698JoeKuoD7Init = { 1, 3, 1, 5, 31, 21, 11, 79, 485, 431, 1333, 3111, 2081, 4327, 0 }; + static ulong[] dim1699JoeKuoD7Init = { 1, 1, 7, 7, 1, 19, 111, 127, 23, 597, 1049, 2337, 6891, 7421, 0 }; + static ulong[] dim1700JoeKuoD7Init = { 1, 3, 7, 7, 23, 3, 121, 171, 41, 3, 147, 397, 5413, 15457, 0 }; + static ulong[] dim1701JoeKuoD7Init = { 1, 1, 1, 9, 11, 9, 107, 55, 303, 285, 599, 2507, 699, 8593, 0 }; + static ulong[] dim1702JoeKuoD7Init = { 1, 3, 5, 3, 19, 61, 9, 33, 385, 761, 1185, 1163, 2251, 8497, 0 }; + static ulong[] dim1703JoeKuoD7Init = { 1, 3, 5, 3, 5, 35, 31, 19, 173, 425, 833, 119, 6691, 11103, 0 }; + static ulong[] dim1704JoeKuoD7Init = { 1, 3, 7, 3, 11, 15, 105, 239, 21, 477, 1303, 3437, 5511, 2469, 0 }; + static ulong[] dim1705JoeKuoD7Init = { 1, 3, 7, 5, 13, 11, 49, 81, 505, 527, 1799, 403, 6849, 4551, 0 }; + static ulong[] dim1706JoeKuoD7Init = { 1, 1, 7, 1, 5, 1, 21, 83, 273, 477, 1281, 3173, 2065, 1559, 0 }; + static ulong[] dim1707JoeKuoD7Init = { 1, 1, 7, 5, 19, 43, 33, 191, 411, 879, 83, 2653, 1271, 10557, 0 }; + static ulong[] dim1708JoeKuoD7Init = { 1, 3, 5, 1, 25, 27, 81, 81, 23, 575, 787, 1715, 7983, 14397, 0 }; + static ulong[] dim1709JoeKuoD7Init = { 1, 1, 7, 11, 27, 57, 31, 139, 65, 445, 1993, 3693, 2627, 941, 0 }; + static ulong[] dim1710JoeKuoD7Init = { 1, 1, 1, 9, 5, 55, 23, 235, 103, 451, 1299, 3901, 2705, 12485, 0 }; + static ulong[] dim1711JoeKuoD7Init = { 1, 1, 1, 11, 9, 57, 57, 129, 269, 841, 1859, 1149, 531, 11977, 0 }; + static ulong[] dim1712JoeKuoD7Init = { 1, 3, 3, 7, 17, 11, 9, 89, 205, 3, 437, 475, 313, 7593, 0 }; + static ulong[] dim1713JoeKuoD7Init = { 1, 3, 5, 13, 9, 37, 9, 109, 453, 965, 1259, 2713, 7301, 15453, 0 }; + static ulong[] dim1714JoeKuoD7Init = { 1, 1, 1, 7, 25, 57, 53, 149, 291, 45, 783, 2327, 7439, 6567, 0 }; + static ulong[] dim1715JoeKuoD7Init = { 1, 1, 1, 13, 5, 17, 65, 15, 279, 435, 1015, 3157, 1411, 3259, 0 }; + static ulong[] dim1716JoeKuoD7Init = { 1, 3, 5, 1, 27, 9, 119, 11, 159, 829, 1499, 3797, 3059, 675, 0 }; + static ulong[] dim1717JoeKuoD7Init = { 1, 1, 3, 7, 27, 5, 65, 141, 403, 431, 645, 3547, 7779, 12565, 0 }; + static ulong[] dim1718JoeKuoD7Init = { 1, 1, 3, 15, 7, 11, 3, 53, 479, 841, 541, 2041, 631, 13969, 0 }; + static ulong[] dim1719JoeKuoD7Init = { 1, 3, 7, 9, 19, 29, 15, 137, 317, 929, 509, 2231, 6273, 305, 0 }; + static ulong[] dim1720JoeKuoD7Init = { 1, 1, 7, 1, 19, 43, 99, 221, 429, 293, 133, 3233, 5097, 7521, 0 }; + static ulong[] dim1721JoeKuoD7Init = { 1, 3, 3, 7, 5, 19, 11, 253, 375, 33, 941, 573, 1855, 13119, 0 }; + static ulong[] dim1722JoeKuoD7Init = { 1, 1, 7, 5, 27, 59, 61, 195, 197, 635, 889, 777, 2559, 3013, 0 }; + static ulong[] dim1723JoeKuoD7Init = { 1, 1, 1, 7, 21, 45, 95, 61, 253, 239, 585, 75, 3737, 2199, 0 }; + static ulong[] dim1724JoeKuoD7Init = { 1, 1, 1, 5, 1, 17, 61, 21, 485, 199, 7, 431, 1117, 2039, 0 }; + static ulong[] dim1725JoeKuoD7Init = { 1, 1, 5, 7, 13, 23, 53, 211, 319, 47, 299, 2681, 6913, 5265, 0 }; + static ulong[] dim1726JoeKuoD7Init = { 1, 1, 3, 1, 21, 49, 1, 197, 413, 475, 79, 3761, 6379, 10689, 0 }; + static ulong[] dim1727JoeKuoD7Init = { 1, 3, 1, 11, 15, 37, 51, 81, 319, 985, 129, 3105, 1321, 9749, 0 }; + static ulong[] dim1728JoeKuoD7Init = { 1, 1, 5, 13, 23, 31, 61, 49, 497, 987, 1401, 2609, 307, 4839, 0 }; + static ulong[] dim1729JoeKuoD7Init = { 1, 3, 5, 7, 11, 25, 9, 97, 337, 535, 543, 145, 241, 1481, 0 }; + static ulong[] dim1730JoeKuoD7Init = { 1, 3, 1, 11, 17, 55, 81, 161, 367, 825, 879, 301, 13, 7089, 0 }; + static ulong[] dim1731JoeKuoD7Init = { 1, 3, 3, 3, 13, 11, 43, 237, 485, 3, 1191, 223, 767, 10297, 0 }; + static ulong[] dim1732JoeKuoD7Init = { 1, 3, 3, 13, 21, 21, 93, 241, 119, 647, 921, 2847, 6889, 7055, 0 }; + static ulong[] dim1733JoeKuoD7Init = { 1, 3, 5, 5, 5, 29, 3, 225, 307, 257, 1961, 2455, 2239, 3405, 0 }; + static ulong[] dim1734JoeKuoD7Init = { 1, 3, 7, 11, 15, 33, 17, 179, 469, 5, 1577, 3539, 7123, 16093, 0 }; + static ulong[] dim1735JoeKuoD7Init = { 1, 1, 3, 7, 27, 43, 45, 115, 507, 657, 1531, 2221, 3175, 1877, 0 }; + static ulong[] dim1736JoeKuoD7Init = { 1, 3, 5, 1, 11, 25, 49, 155, 441, 703, 813, 1143, 219, 12675, 0 }; + static ulong[] dim1737JoeKuoD7Init = { 1, 1, 1, 3, 15, 55, 15, 83, 333, 573, 1527, 3421, 6225, 3115, 0 }; + static ulong[] dim1738JoeKuoD7Init = { 1, 3, 5, 1, 27, 3, 117, 149, 35, 587, 1123, 3037, 8083, 113, 0 }; + static ulong[] dim1739JoeKuoD7Init = { 1, 3, 1, 5, 1, 23, 79, 99, 287, 505, 807, 4003, 4551, 2093, 0 }; + static ulong[] dim1740JoeKuoD7Init = { 1, 3, 7, 9, 29, 5, 59, 111, 401, 179, 1263, 749, 689, 8905, 0 }; + static ulong[] dim1741JoeKuoD7Init = { 1, 3, 7, 3, 17, 41, 81, 191, 313, 343, 809, 83, 405, 10665, 0 }; + static ulong[] dim1742JoeKuoD7Init = { 1, 3, 5, 9, 7, 19, 59, 157, 169, 273, 935, 1435, 4725, 14049, 0 }; + static ulong[] dim1743JoeKuoD7Init = { 1, 1, 5, 7, 11, 41, 61, 47, 43, 13, 783, 3685, 6417, 7859, 0 }; + static ulong[] dim1744JoeKuoD7Init = { 1, 1, 3, 3, 13, 37, 127, 107, 439, 855, 1969, 1257, 1459, 3617, 0 }; + static ulong[] dim1745JoeKuoD7Init = { 1, 3, 5, 1, 5, 7, 41, 77, 175, 679, 353, 2899, 1513, 9241, 0 }; + static ulong[] dim1746JoeKuoD7Init = { 1, 1, 5, 1, 31, 41, 75, 217, 131, 261, 1659, 509, 3327, 14651, 0 }; + static ulong[] dim1747JoeKuoD7Init = { 1, 1, 7, 15, 15, 1, 111, 131, 19, 123, 701, 2633, 5125, 15109, 0 }; + static ulong[] dim1748JoeKuoD7Init = { 1, 3, 3, 3, 15, 51, 19, 133, 41, 561, 869, 447, 1421, 8659, 0 }; + static ulong[] dim1749JoeKuoD7Init = { 1, 1, 3, 9, 15, 47, 103, 5, 23, 97, 1413, 3307, 407, 6943, 0 }; + static ulong[] dim1750JoeKuoD7Init = { 1, 1, 7, 15, 19, 37, 113, 217, 451, 733, 1407, 2805, 6121, 12471, 0 }; + static ulong[] dim1751JoeKuoD7Init = { 1, 1, 3, 13, 7, 53, 1, 159, 503, 603, 1523, 2327, 909, 3685, 0 }; + static ulong[] dim1752JoeKuoD7Init = { 1, 3, 1, 13, 11, 47, 79, 69, 459, 761, 1181, 3369, 7983, 8561, 0 }; + static ulong[] dim1753JoeKuoD7Init = { 1, 1, 5, 9, 3, 51, 69, 93, 375, 451, 1181, 1353, 939, 629, 0 }; + static ulong[] dim1754JoeKuoD7Init = { 1, 1, 5, 9, 29, 57, 89, 145, 477, 17, 55, 2073, 1805, 5389, 0 }; + static ulong[] dim1755JoeKuoD7Init = { 1, 3, 3, 7, 1, 59, 85, 69, 369, 191, 1419, 1331, 7451, 8769, 0 }; + static ulong[] dim1756JoeKuoD7Init = { 1, 3, 3, 11, 11, 49, 31, 249, 285, 29, 633, 3387, 1197, 6363, 0 }; + static ulong[] dim1757JoeKuoD7Init = { 1, 3, 7, 7, 15, 33, 3, 253, 247, 573, 2029, 3419, 8037, 2889, 0 }; + static ulong[] dim1758JoeKuoD7Init = { 1, 3, 5, 1, 23, 31, 35, 113, 221, 659, 755, 2777, 3709, 7511, 0 }; + static ulong[] dim1759JoeKuoD7Init = { 1, 1, 5, 7, 7, 29, 113, 81, 203, 711, 1427, 2233, 6049, 11417, 0 }; + static ulong[] dim1760JoeKuoD7Init = { 1, 3, 3, 1, 19, 55, 107, 87, 383, 25, 935, 1287, 1867, 2133, 0 }; + static ulong[] dim1761JoeKuoD7Init = { 1, 3, 7, 11, 9, 45, 15, 171, 293, 533, 1393, 759, 3009, 7879, 0 }; + static ulong[] dim1762JoeKuoD7Init = { 1, 1, 1, 1, 1, 59, 51, 15, 471, 377, 1031, 3427, 6447, 10465, 0 }; + static ulong[] dim1763JoeKuoD7Init = { 1, 3, 5, 15, 7, 15, 3, 1, 359, 331, 1295, 2777, 373, 4043, 0 }; + static ulong[] dim1764JoeKuoD7Init = { 1, 1, 3, 9, 21, 41, 123, 61, 225, 305, 149, 2041, 7569, 14055, 0 }; + static ulong[] dim1765JoeKuoD7Init = { 1, 3, 5, 3, 27, 15, 79, 47, 463, 327, 1231, 171, 4931, 7549, 0 }; + static ulong[] dim1766JoeKuoD7Init = { 1, 3, 3, 15, 27, 11, 35, 179, 205, 579, 1297, 3149, 1253, 3067, 0 }; + static ulong[] dim1767JoeKuoD7Init = { 1, 3, 1, 5, 15, 41, 17, 69, 369, 57, 779, 3055, 7799, 10755, 0 }; + static ulong[] dim1768JoeKuoD7Init = { 1, 1, 7, 11, 1, 11, 121, 177, 297, 933, 1319, 3123, 1233, 15521, 0 }; + static ulong[] dim1769JoeKuoD7Init = { 1, 1, 7, 7, 27, 59, 17, 155, 17, 109, 1623, 3527, 6227, 14295, 0 }; + static ulong[] dim1770JoeKuoD7Init = { 1, 3, 1, 13, 27, 19, 47, 35, 403, 647, 1257, 1661, 7011, 11981, 0 }; + static ulong[] dim1771JoeKuoD7Init = { 1, 1, 1, 13, 27, 47, 73, 53, 355, 857, 1091, 3165, 2729, 7685, 0 }; + static ulong[] dim1772JoeKuoD7Init = { 1, 3, 1, 9, 7, 55, 53, 183, 109, 655, 1143, 975, 2809, 2709, 0 }; + static ulong[] dim1773JoeKuoD7Init = { 1, 3, 3, 9, 11, 5, 121, 63, 221, 247, 1649, 709, 5215, 12159, 0 }; + static ulong[] dim1774JoeKuoD7Init = { 1, 1, 3, 5, 5, 37, 83, 89, 475, 513, 563, 1965, 2335, 7921, 0 }; + static ulong[] dim1775JoeKuoD7Init = { 1, 1, 3, 3, 15, 23, 79, 79, 499, 343, 917, 3495, 7685, 5939, 0 }; + static ulong[] dim1776JoeKuoD7Init = { 1, 1, 1, 13, 5, 59, 87, 7, 469, 979, 683, 3397, 3787, 5063, 0 }; + static ulong[] dim1777JoeKuoD7Init = { 1, 1, 7, 5, 1, 27, 73, 85, 427, 619, 989, 2323, 4069, 13721, 0 }; + static ulong[] dim1778JoeKuoD7Init = { 1, 3, 5, 3, 3, 39, 55, 153, 293, 483, 235, 2041, 549, 15519, 0 }; + static ulong[] dim1779JoeKuoD7Init = { 1, 3, 1, 9, 17, 13, 61, 227, 435, 383, 513, 1169, 3335, 11257, 0 }; + static ulong[] dim1780JoeKuoD7Init = { 1, 3, 3, 7, 1, 47, 61, 117, 483, 979, 163, 2621, 1701, 13331, 0 }; + static ulong[] dim1781JoeKuoD7Init = { 1, 3, 3, 1, 17, 49, 115, 235, 511, 681, 1493, 137, 539, 5429, 0 }; + static ulong[] dim1782JoeKuoD7Init = { 1, 3, 3, 13, 13, 61, 3, 1, 291, 101, 363, 1677, 2133, 3629, 0 }; + static ulong[] dim1783JoeKuoD7Init = { 1, 1, 7, 3, 1, 11, 83, 127, 291, 599, 819, 2637, 1197, 7435, 0 }; + static ulong[] dim1784JoeKuoD7Init = { 1, 1, 7, 1, 1, 23, 115, 47, 403, 377, 833, 3241, 6843, 10279, 0 }; + static ulong[] dim1785JoeKuoD7Init = { 1, 1, 1, 15, 7, 51, 81, 215, 43, 445, 203, 3375, 6479, 3745, 0 }; + static ulong[] dim1786JoeKuoD7Init = { 1, 1, 7, 5, 7, 13, 25, 43, 233, 725, 267, 1875, 6481, 9685, 0 }; + static ulong[] dim1787JoeKuoD7Init = { 1, 1, 1, 7, 23, 9, 37, 1, 51, 861, 1509, 11, 8119, 9171, 0 }; + static ulong[] dim1788JoeKuoD7Init = { 1, 1, 5, 9, 17, 41, 69, 51, 445, 727, 159, 3317, 4951, 7519, 0 }; + static ulong[] dim1789JoeKuoD7Init = { 1, 1, 3, 13, 11, 3, 9, 211, 453, 957, 1499, 953, 403, 10715, 0 }; + static ulong[] dim1790JoeKuoD7Init = { 1, 3, 7, 7, 19, 1, 13, 255, 351, 325, 1055, 3719, 2343, 12693, 0 }; + static ulong[] dim1791JoeKuoD7Init = { 1, 1, 7, 3, 25, 29, 77, 185, 421, 33, 911, 2791, 4865, 4591, 0 }; + static ulong[] dim1792JoeKuoD7Init = { 1, 3, 7, 1, 5, 53, 77, 25, 359, 69, 169, 225, 237, 2059, 0 }; + static ulong[] dim1793JoeKuoD7Init = { 1, 3, 3, 3, 25, 63, 21, 111, 83, 21, 1513, 565, 1097, 7331, 0 }; + static ulong[] dim1794JoeKuoD7Init = { 1, 3, 5, 15, 23, 33, 127, 221, 121, 95, 909, 1207, 2957, 3367, 0 }; + static ulong[] dim1795JoeKuoD7Init = { 1, 1, 7, 15, 11, 49, 35, 147, 265, 517, 2011, 3585, 3877, 2907, 0 }; + static ulong[] dim1796JoeKuoD7Init = { 1, 3, 3, 1, 11, 37, 53, 47, 35, 323, 1283, 399, 7785, 8341, 0 }; + static ulong[] dim1797JoeKuoD7Init = { 1, 1, 7, 15, 5, 51, 83, 255, 231, 141, 1005, 3681, 3155, 11815, 0 }; + static ulong[] dim1798JoeKuoD7Init = { 1, 1, 3, 7, 3, 15, 75, 81, 23, 137, 897, 2439, 5277, 6377, 0 }; + static ulong[] dim1799JoeKuoD7Init = { 1, 1, 5, 1, 3, 11, 69, 231, 483, 797, 133, 497, 3973, 14993, 0 }; + static ulong[] dim1800JoeKuoD7Init = { 1, 1, 3, 15, 23, 17, 89, 207, 111, 157, 1689, 3165, 7147, 15265, 0 }; + static ulong[] dim1801JoeKuoD7Init = { 1, 3, 1, 5, 9, 31, 45, 131, 423, 53, 1723, 2009, 485, 15329, 0 }; + static ulong[] dim1802JoeKuoD7Init = { 1, 1, 3, 3, 25, 5, 97, 81, 431, 701, 1799, 3595, 3147, 8919, 0 }; + static ulong[] dim1803JoeKuoD7Init = { 1, 3, 7, 3, 3, 37, 3, 219, 291, 553, 1879, 15, 3357, 8479, 0 }; + static ulong[] dim1804JoeKuoD7Init = { 1, 3, 7, 3, 3, 21, 55, 253, 49, 191, 951, 13, 5163, 12243, 0 }; + static ulong[] dim1805JoeKuoD7Init = { 1, 1, 1, 1, 29, 39, 93, 123, 133, 465, 1665, 2023, 6773, 10521, 0 }; + static ulong[] dim1806JoeKuoD7Init = { 1, 1, 1, 15, 15, 15, 107, 209, 103, 59, 33, 1927, 6517, 8479, 0 }; + static ulong[] dim1807JoeKuoD7Init = { 1, 3, 3, 15, 3, 37, 19, 3, 43, 193, 1907, 2579, 7415, 9165, 0 }; + static ulong[] dim1808JoeKuoD7Init = { 1, 3, 5, 11, 29, 63, 47, 79, 227, 569, 67, 4015, 1275, 11963, 0 }; + static ulong[] dim1809JoeKuoD7Init = { 1, 3, 7, 1, 1, 33, 103, 111, 129, 189, 837, 3741, 699, 14433, 0 }; + static ulong[] dim1810JoeKuoD7Init = { 1, 3, 7, 11, 19, 15, 43, 35, 367, 535, 913, 2109, 1397, 12199, 0 }; + static ulong[] dim1811JoeKuoD7Init = { 1, 3, 7, 15, 27, 15, 41, 59, 429, 423, 377, 905, 7403, 6175, 0 }; + static ulong[] dim1812JoeKuoD7Init = { 1, 1, 5, 5, 27, 55, 49, 247, 353, 773, 707, 2501, 7567, 1821, 0 }; + static ulong[] dim1813JoeKuoD7Init = { 1, 1, 7, 15, 5, 11, 31, 49, 331, 1017, 909, 967, 5557, 7279, 0 }; + static ulong[] dim1814JoeKuoD7Init = { 1, 1, 5, 5, 13, 55, 127, 111, 193, 77, 1353, 349, 5785, 16325, 0 }; + static ulong[] dim1815JoeKuoD7Init = { 1, 1, 5, 11, 23, 61, 83, 79, 409, 877, 1625, 705, 6159, 1701, 0 }; + static ulong[] dim1816JoeKuoD7Init = { 1, 1, 5, 1, 29, 39, 69, 221, 29, 83, 21, 3525, 7387, 9249, 0 }; + static ulong[] dim1817JoeKuoD7Init = { 1, 3, 7, 3, 13, 57, 63, 159, 25, 151, 1749, 3191, 4805, 6003, 0 }; + static ulong[] dim1818JoeKuoD7Init = { 1, 1, 3, 15, 11, 49, 71, 241, 421, 859, 1923, 539, 1721, 2903, 0 }; + static ulong[] dim1819JoeKuoD7Init = { 1, 3, 1, 1, 15, 33, 123, 133, 323, 173, 271, 2641, 2649, 5485, 0 }; + static ulong[] dim1820JoeKuoD7Init = { 1, 1, 3, 13, 13, 31, 39, 147, 313, 497, 2019, 3269, 2671, 6599, 0 }; + static ulong[] dim1821JoeKuoD7Init = { 1, 3, 7, 9, 13, 37, 111, 87, 3, 417, 923, 1833, 5383, 12045, 0 }; + static ulong[] dim1822JoeKuoD7Init = { 1, 3, 3, 13, 25, 27, 91, 121, 151, 407, 899, 469, 6647, 2799, 0 }; + static ulong[] dim1823JoeKuoD7Init = { 1, 3, 1, 7, 19, 39, 29, 43, 195, 439, 1065, 2035, 749, 14013, 0 }; + static ulong[] dim1824JoeKuoD7Init = { 1, 1, 5, 13, 21, 1, 69, 223, 83, 457, 1589, 1199, 7635, 1987, 0 }; + static ulong[] dim1825JoeKuoD7Init = { 1, 1, 7, 13, 5, 21, 35, 169, 71, 855, 497, 1119, 6681, 3905, 0 }; + static ulong[] dim1826JoeKuoD7Init = { 1, 3, 1, 13, 25, 55, 109, 113, 41, 461, 185, 3677, 1807, 13773, 0 }; + static ulong[] dim1827JoeKuoD7Init = { 1, 3, 1, 5, 15, 61, 91, 219, 365, 399, 505, 1207, 2237, 9267, 0 }; + static ulong[] dim1828JoeKuoD7Init = { 1, 1, 7, 3, 7, 1, 29, 151, 215, 587, 1499, 355, 5121, 14963, 0 }; + static ulong[] dim1829JoeKuoD7Init = { 1, 3, 1, 1, 3, 23, 127, 189, 139, 987, 1291, 3583, 2881, 1927, 0 }; + static ulong[] dim1830JoeKuoD7Init = { 1, 1, 1, 11, 19, 51, 25, 179, 35, 517, 1531, 3657, 7025, 7079, 0 }; + static ulong[] dim1831JoeKuoD7Init = { 1, 1, 5, 7, 23, 51, 35, 157, 113, 993, 265, 1119, 2639, 14475, 0 }; + static ulong[] dim1832JoeKuoD7Init = { 1, 3, 7, 1, 23, 19, 111, 83, 413, 205, 87, 2389, 7593, 9189, 0 }; + static ulong[] dim1833JoeKuoD7Init = { 1, 3, 5, 11, 25, 25, 39, 59, 419, 477, 1189, 807, 7679, 9867, 0 }; + static ulong[] dim1834JoeKuoD7Init = { 1, 1, 5, 1, 9, 59, 99, 183, 493, 811, 441, 1039, 1099, 10229, 0 }; + static ulong[] dim1835JoeKuoD7Init = { 1, 1, 5, 9, 31, 27, 51, 179, 277, 549, 153, 1785, 5227, 13695, 0 }; + static ulong[] dim1836JoeKuoD7Init = { 1, 3, 7, 11, 29, 43, 9, 205, 499, 55, 745, 2217, 793, 14517, 0 }; + static ulong[] dim1837JoeKuoD7Init = { 1, 3, 5, 7, 29, 47, 15, 153, 73, 971, 149, 2579, 1699, 14849, 0 }; + static ulong[] dim1838JoeKuoD7Init = { 1, 3, 3, 7, 31, 33, 61, 103, 503, 531, 2033, 2415, 4151, 4937, 0 }; + static ulong[] dim1839JoeKuoD7Init = { 1, 3, 1, 15, 15, 53, 27, 67, 351, 273, 637, 4085, 3445, 2085, 0 }; + static ulong[] dim1840JoeKuoD7Init = { 1, 3, 5, 15, 7, 57, 121, 23, 73, 765, 1949, 67, 8061, 11167, 0 }; + static ulong[] dim1841JoeKuoD7Init = { 1, 1, 7, 1, 25, 7, 107, 13, 409, 115, 1451, 1215, 39, 11577, 0 }; + static ulong[] dim1842JoeKuoD7Init = { 1, 1, 5, 15, 3, 15, 71, 1, 337, 929, 1435, 2847, 3257, 12233, 0 }; + static ulong[] dim1843JoeKuoD7Init = { 1, 1, 5, 11, 31, 37, 61, 243, 255, 79, 1735, 3769, 4893, 15103, 0 }; + static ulong[] dim1844JoeKuoD7Init = { 1, 1, 7, 11, 5, 63, 49, 197, 301, 883, 951, 2357, 7501, 15499, 0 }; + static ulong[] dim1845JoeKuoD7Init = { 1, 3, 7, 3, 13, 53, 71, 235, 183, 951, 845, 3361, 4757, 7745, 0 }; + static ulong[] dim1846JoeKuoD7Init = { 1, 1, 7, 3, 25, 61, 119, 3, 487, 503, 179, 2085, 4093, 1339, 0 }; + static ulong[] dim1847JoeKuoD7Init = { 1, 1, 5, 3, 21, 15, 113, 175, 61, 789, 1369, 109, 5963, 9401, 0 }; + static ulong[] dim1848JoeKuoD7Init = { 1, 1, 5, 5, 21, 35, 103, 33, 147, 561, 1033, 1497, 309, 12505, 0 }; + static ulong[] dim1849JoeKuoD7Init = { 1, 3, 3, 13, 25, 17, 29, 101, 103, 719, 329, 1317, 4487, 9115, 0 }; + static ulong[] dim1850JoeKuoD7Init = { 1, 1, 3, 13, 5, 61, 25, 79, 161, 673, 47, 2485, 7711, 4959, 0 }; + static ulong[] dim1851JoeKuoD7Init = { 1, 1, 7, 13, 19, 13, 1, 27, 443, 369, 669, 2555, 3003, 5117, 0 }; + static ulong[] dim1852JoeKuoD7Init = { 1, 3, 3, 5, 21, 29, 65, 211, 343, 717, 949, 1987, 6571, 11299, 0 }; + static ulong[] dim1853JoeKuoD7Init = { 1, 3, 3, 9, 19, 7, 115, 119, 369, 247, 1165, 4033, 861, 5667, 0 }; + static ulong[] dim1854JoeKuoD7Init = { 1, 3, 5, 3, 3, 53, 15, 219, 223, 873, 1145, 2781, 3297, 10551, 0 }; + static ulong[] dim1855JoeKuoD7Init = { 1, 3, 1, 15, 5, 61, 15, 121, 201, 89, 647, 3079, 1505, 10003, 0 }; + static ulong[] dim1856JoeKuoD7Init = { 1, 3, 1, 13, 17, 55, 27, 215, 67, 461, 1955, 765, 483, 11695, 0 }; + static ulong[] dim1857JoeKuoD7Init = { 1, 3, 1, 1, 1, 21, 59, 19, 339, 157, 2019, 971, 1797, 5237, 0 }; + static ulong[] dim1858JoeKuoD7Init = { 1, 3, 7, 9, 15, 1, 67, 119, 63, 59, 1107, 2201, 5499, 3757, 0 }; + static ulong[] dim1859JoeKuoD7Init = { 1, 3, 3, 13, 29, 59, 73, 89, 469, 335, 53, 315, 4371, 6417, 0 }; + static ulong[] dim1860JoeKuoD7Init = { 1, 1, 5, 3, 21, 7, 11, 205, 485, 695, 1959, 2407, 5423, 15359, 0 }; + static ulong[] dim1861JoeKuoD7Init = { 1, 1, 7, 1, 1, 43, 61, 103, 65, 747, 695, 3855, 7765, 13299, 0 }; + static ulong[] dim1862JoeKuoD7Init = { 1, 1, 3, 11, 9, 11, 47, 59, 287, 363, 1677, 613, 4181, 16221, 0 }; + static ulong[] dim1863JoeKuoD7Init = { 1, 1, 1, 3, 9, 43, 1, 107, 291, 493, 571, 2329, 2707, 13683, 0 }; + static ulong[] dim1864JoeKuoD7Init = { 1, 1, 5, 1, 13, 27, 29, 159, 357, 187, 613, 1803, 5563, 14913, 0 }; + static ulong[] dim1865JoeKuoD7Init = { 1, 3, 5, 13, 1, 5, 69, 69, 17, 527, 1019, 2565, 1383, 3695, 0 }; + static ulong[] dim1866JoeKuoD7Init = { 1, 1, 7, 3, 9, 21, 9, 151, 145, 891, 1961, 257, 5885, 5201, 0 }; + static ulong[] dim1867JoeKuoD7Init = { 1, 1, 3, 15, 9, 7, 31, 3, 115, 697, 369, 1531, 3581, 5681, 27421, 0 }; + static ulong[] dim1868JoeKuoD7Init = { 1, 1, 5, 9, 13, 33, 19, 191, 433, 651, 2023, 373, 4665, 15147, 28277, 0 }; + static ulong[] dim1869JoeKuoD7Init = { 1, 3, 5, 7, 27, 3, 15, 57, 137, 903, 355, 503, 3, 13015, 32415, 0 }; + static ulong[] dim1870JoeKuoD7Init = { 1, 3, 5, 1, 13, 57, 69, 55, 75, 633, 1271, 189, 4279, 1293, 5719, 0 }; + static ulong[] dim1871JoeKuoD7Init = { 1, 3, 5, 15, 27, 9, 13, 185, 211, 593, 723, 3725, 5165, 15375, 1055, 0 }; + static ulong[] dim1872JoeKuoD7Init = { 1, 3, 7, 13, 21, 11, 67, 11, 279, 503, 1839, 3509, 1285, 5251, 27835, 0 }; + static ulong[] dim1873JoeKuoD7Init = { 1, 1, 3, 15, 5, 45, 35, 145, 383, 227, 327, 2419, 5207, 15897, 20869, 0 }; + static ulong[] dim1874JoeKuoD7Init = { 1, 1, 7, 11, 31, 25, 69, 169, 363, 819, 1855, 61, 5613, 11835, 24761, 0 }; + static ulong[] dim1875JoeKuoD7Init = { 1, 3, 7, 9, 15, 41, 123, 61, 359, 29, 369, 1167, 489, 12947, 14765, 0 }; + static ulong[] dim1876JoeKuoD7Init = { 1, 3, 3, 5, 7, 33, 115, 193, 427, 123, 1795, 3153, 2771, 6761, 719, 0 }; + static ulong[] dim1877JoeKuoD7Init = { 1, 1, 1, 13, 31, 39, 5, 179, 181, 787, 1891, 2287, 2085, 15081, 2035, 0 }; + static ulong[] dim1878JoeKuoD7Init = { 1, 1, 5, 15, 1, 47, 15, 235, 431, 687, 1787, 225, 7749, 1179, 29243, 0 }; + static ulong[] dim1879JoeKuoD7Init = { 1, 1, 1, 13, 19, 53, 119, 131, 417, 505, 1179, 2291, 4795, 10475, 6307, 0 }; + static ulong[] dim1880JoeKuoD7Init = { 1, 1, 5, 13, 15, 43, 73, 3, 193, 5, 1843, 1617, 7557, 4165, 4089, 0 }; + static ulong[] dim1881JoeKuoD7Init = { 1, 1, 1, 5, 3, 35, 121, 183, 197, 605, 1775, 1647, 4929, 365, 43, 0 }; + static ulong[] dim1882JoeKuoD7Init = { 1, 1, 7, 7, 13, 31, 69, 157, 309, 99, 705, 1705, 2093, 13055, 6727, 0 }; + static ulong[] dim1883JoeKuoD7Init = { 1, 1, 1, 3, 29, 41, 109, 129, 223, 755, 595, 1931, 3967, 8249, 9439, 0 }; + static ulong[] dim1884JoeKuoD7Init = { 1, 3, 5, 1, 21, 45, 101, 229, 343, 455, 125, 1335, 749, 3967, 22777, 0 }; + static ulong[] dim1885JoeKuoD7Init = { 1, 1, 7, 13, 31, 49, 125, 199, 37, 685, 1171, 1793, 1057, 10041, 12693, 0 }; + static ulong[] dim1886JoeKuoD7Init = { 1, 3, 7, 5, 19, 33, 35, 115, 269, 151, 731, 1803, 5241, 3667, 25371, 0 }; + static ulong[] dim1887JoeKuoD7Init = { 1, 3, 5, 3, 7, 27, 25, 249, 275, 331, 1579, 2911, 5859, 9893, 27807, 0 }; + static ulong[] dim1888JoeKuoD7Init = { 1, 3, 1, 7, 21, 41, 81, 239, 141, 861, 827, 1261, 6873, 6413, 19313, 0 }; + static ulong[] dim1889JoeKuoD7Init = { 1, 1, 7, 1, 9, 51, 39, 123, 145, 929, 1101, 2505, 6493, 95, 17247, 0 }; + static ulong[] dim1890JoeKuoD7Init = { 1, 1, 5, 5, 11, 3, 47, 167, 5, 229, 1603, 3541, 5505, 1221, 899, 0 }; + static ulong[] dim1891JoeKuoD7Init = { 1, 1, 1, 9, 5, 17, 7, 21, 499, 597, 1775, 3187, 831, 10995, 7721, 0 }; + static ulong[] dim1892JoeKuoD7Init = { 1, 3, 3, 15, 27, 25, 7, 205, 341, 965, 519, 2907, 373, 5827, 14243, 0 }; + static ulong[] dim1893JoeKuoD7Init = { 1, 3, 1, 3, 19, 27, 13, 207, 287, 983, 575, 891, 3869, 11213, 11377, 0 }; + static ulong[] dim1894JoeKuoD7Init = { 1, 1, 3, 9, 1, 5, 53, 7, 507, 505, 133, 3567, 6601, 7985, 10461, 0 }; + static ulong[] dim1895JoeKuoD7Init = { 1, 1, 3, 9, 15, 9, 87, 231, 39, 701, 625, 2783, 6163, 6945, 4521, 0 }; + static ulong[] dim1896JoeKuoD7Init = { 1, 3, 5, 7, 25, 39, 63, 215, 89, 775, 283, 2919, 151, 7233, 32163, 0 }; + static ulong[] dim1897JoeKuoD7Init = { 1, 3, 3, 13, 31, 31, 55, 125, 433, 77, 1123, 3151, 6421, 6343, 14893, 0 }; + static ulong[] dim1898JoeKuoD7Init = { 1, 1, 5, 9, 17, 55, 63, 31, 331, 945, 1953, 4093, 6875, 3519, 23329, 0 }; + static ulong[] dim1899JoeKuoD7Init = { 1, 1, 1, 3, 23, 17, 17, 39, 173, 1013, 527, 2563, 3623, 10049, 10919, 0 }; + + static ulong[][] JoeKuoD7initializers = + { + dim1JoeKuoD7Init, + dim2JoeKuoD7Init, + dim3JoeKuoD7Init, + dim4JoeKuoD7Init, + dim5JoeKuoD7Init, + dim6JoeKuoD7Init, + dim7JoeKuoD7Init, + dim8JoeKuoD7Init, + dim9JoeKuoD7Init, + dim10JoeKuoD7Init, + dim11JoeKuoD7Init, + dim12JoeKuoD7Init, + dim13JoeKuoD7Init, + dim14JoeKuoD7Init, + dim15JoeKuoD7Init, + dim16JoeKuoD7Init, + dim17JoeKuoD7Init, + dim18JoeKuoD7Init, + dim19JoeKuoD7Init, + dim20JoeKuoD7Init, + dim21JoeKuoD7Init, + dim22JoeKuoD7Init, + dim23JoeKuoD7Init, + dim24JoeKuoD7Init, + dim25JoeKuoD7Init, + dim26JoeKuoD7Init, + dim27JoeKuoD7Init, + dim28JoeKuoD7Init, + dim29JoeKuoD7Init, + dim30JoeKuoD7Init, + dim31JoeKuoD7Init, + dim32JoeKuoD7Init, + dim33JoeKuoD7Init, + dim34JoeKuoD7Init, + dim35JoeKuoD7Init, + dim36JoeKuoD7Init, + dim37JoeKuoD7Init, + dim38JoeKuoD7Init, + dim39JoeKuoD7Init, + dim40JoeKuoD7Init, + dim41JoeKuoD7Init, + dim42JoeKuoD7Init, + dim43JoeKuoD7Init, + dim44JoeKuoD7Init, + dim45JoeKuoD7Init, + dim46JoeKuoD7Init, + dim47JoeKuoD7Init, + dim48JoeKuoD7Init, + dim49JoeKuoD7Init, + dim50JoeKuoD7Init, + dim51JoeKuoD7Init, + dim52JoeKuoD7Init, + dim53JoeKuoD7Init, + dim54JoeKuoD7Init, + dim55JoeKuoD7Init, + dim56JoeKuoD7Init, + dim57JoeKuoD7Init, + dim58JoeKuoD7Init, + dim59JoeKuoD7Init, + dim60JoeKuoD7Init, + dim61JoeKuoD7Init, + dim62JoeKuoD7Init, + dim63JoeKuoD7Init, + dim64JoeKuoD7Init, + dim65JoeKuoD7Init, + dim66JoeKuoD7Init, + dim67JoeKuoD7Init, + dim68JoeKuoD7Init, + dim69JoeKuoD7Init, + dim70JoeKuoD7Init, + dim71JoeKuoD7Init, + dim72JoeKuoD7Init, + dim73JoeKuoD7Init, + dim74JoeKuoD7Init, + dim75JoeKuoD7Init, + dim76JoeKuoD7Init, + dim77JoeKuoD7Init, + dim78JoeKuoD7Init, + dim79JoeKuoD7Init, + dim80JoeKuoD7Init, + dim81JoeKuoD7Init, + dim82JoeKuoD7Init, + dim83JoeKuoD7Init, + dim84JoeKuoD7Init, + dim85JoeKuoD7Init, + dim86JoeKuoD7Init, + dim87JoeKuoD7Init, + dim88JoeKuoD7Init, + dim89JoeKuoD7Init, + dim90JoeKuoD7Init, + dim91JoeKuoD7Init, + dim92JoeKuoD7Init, + dim93JoeKuoD7Init, + dim94JoeKuoD7Init, + dim95JoeKuoD7Init, + dim96JoeKuoD7Init, + dim97JoeKuoD7Init, + dim98JoeKuoD7Init, + dim99JoeKuoD7Init, + dim100JoeKuoD7Init, + dim101JoeKuoD7Init, + dim102JoeKuoD7Init, + dim103JoeKuoD7Init, + dim104JoeKuoD7Init, + dim105JoeKuoD7Init, + dim106JoeKuoD7Init, + dim107JoeKuoD7Init, + dim108JoeKuoD7Init, + dim109JoeKuoD7Init, + dim110JoeKuoD7Init, + dim111JoeKuoD7Init, + dim112JoeKuoD7Init, + dim113JoeKuoD7Init, + dim114JoeKuoD7Init, + dim115JoeKuoD7Init, + dim116JoeKuoD7Init, + dim117JoeKuoD7Init, + dim118JoeKuoD7Init, + dim119JoeKuoD7Init, + dim120JoeKuoD7Init, + dim121JoeKuoD7Init, + dim122JoeKuoD7Init, + dim123JoeKuoD7Init, + dim124JoeKuoD7Init, + dim125JoeKuoD7Init, + dim126JoeKuoD7Init, + dim127JoeKuoD7Init, + dim128JoeKuoD7Init, + dim129JoeKuoD7Init, + dim130JoeKuoD7Init, + dim131JoeKuoD7Init, + dim132JoeKuoD7Init, + dim133JoeKuoD7Init, + dim134JoeKuoD7Init, + dim135JoeKuoD7Init, + dim136JoeKuoD7Init, + dim137JoeKuoD7Init, + dim138JoeKuoD7Init, + dim139JoeKuoD7Init, + dim140JoeKuoD7Init, + dim141JoeKuoD7Init, + dim142JoeKuoD7Init, + dim143JoeKuoD7Init, + dim144JoeKuoD7Init, + dim145JoeKuoD7Init, + dim146JoeKuoD7Init, + dim147JoeKuoD7Init, + dim148JoeKuoD7Init, + dim149JoeKuoD7Init, + dim150JoeKuoD7Init, + dim151JoeKuoD7Init, + dim152JoeKuoD7Init, + dim153JoeKuoD7Init, + dim154JoeKuoD7Init, + dim155JoeKuoD7Init, + dim156JoeKuoD7Init, + dim157JoeKuoD7Init, + dim158JoeKuoD7Init, + dim159JoeKuoD7Init, + dim160JoeKuoD7Init, + dim161JoeKuoD7Init, + dim162JoeKuoD7Init, + dim163JoeKuoD7Init, + dim164JoeKuoD7Init, + dim165JoeKuoD7Init, + dim166JoeKuoD7Init, + dim167JoeKuoD7Init, + dim168JoeKuoD7Init, + dim169JoeKuoD7Init, + dim170JoeKuoD7Init, + dim171JoeKuoD7Init, + dim172JoeKuoD7Init, + dim173JoeKuoD7Init, + dim174JoeKuoD7Init, + dim175JoeKuoD7Init, + dim176JoeKuoD7Init, + dim177JoeKuoD7Init, + dim178JoeKuoD7Init, + dim179JoeKuoD7Init, + dim180JoeKuoD7Init, + dim181JoeKuoD7Init, + dim182JoeKuoD7Init, + dim183JoeKuoD7Init, + dim184JoeKuoD7Init, + dim185JoeKuoD7Init, + dim186JoeKuoD7Init, + dim187JoeKuoD7Init, + dim188JoeKuoD7Init, + dim189JoeKuoD7Init, + dim190JoeKuoD7Init, + dim191JoeKuoD7Init, + dim192JoeKuoD7Init, + dim193JoeKuoD7Init, + dim194JoeKuoD7Init, + dim195JoeKuoD7Init, + dim196JoeKuoD7Init, + dim197JoeKuoD7Init, + dim198JoeKuoD7Init, + dim199JoeKuoD7Init, + dim200JoeKuoD7Init, + dim201JoeKuoD7Init, + dim202JoeKuoD7Init, + dim203JoeKuoD7Init, + dim204JoeKuoD7Init, + dim205JoeKuoD7Init, + dim206JoeKuoD7Init, + dim207JoeKuoD7Init, + dim208JoeKuoD7Init, + dim209JoeKuoD7Init, + dim210JoeKuoD7Init, + dim211JoeKuoD7Init, + dim212JoeKuoD7Init, + dim213JoeKuoD7Init, + dim214JoeKuoD7Init, + dim215JoeKuoD7Init, + dim216JoeKuoD7Init, + dim217JoeKuoD7Init, + dim218JoeKuoD7Init, + dim219JoeKuoD7Init, + dim220JoeKuoD7Init, + dim221JoeKuoD7Init, + dim222JoeKuoD7Init, + dim223JoeKuoD7Init, + dim224JoeKuoD7Init, + dim225JoeKuoD7Init, + dim226JoeKuoD7Init, + dim227JoeKuoD7Init, + dim228JoeKuoD7Init, + dim229JoeKuoD7Init, + dim230JoeKuoD7Init, + dim231JoeKuoD7Init, + dim232JoeKuoD7Init, + dim233JoeKuoD7Init, + dim234JoeKuoD7Init, + dim235JoeKuoD7Init, + dim236JoeKuoD7Init, + dim237JoeKuoD7Init, + dim238JoeKuoD7Init, + dim239JoeKuoD7Init, + dim240JoeKuoD7Init, + dim241JoeKuoD7Init, + dim242JoeKuoD7Init, + dim243JoeKuoD7Init, + dim244JoeKuoD7Init, + dim245JoeKuoD7Init, + dim246JoeKuoD7Init, + dim247JoeKuoD7Init, + dim248JoeKuoD7Init, + dim249JoeKuoD7Init, + dim250JoeKuoD7Init, + dim251JoeKuoD7Init, + dim252JoeKuoD7Init, + dim253JoeKuoD7Init, + dim254JoeKuoD7Init, + dim255JoeKuoD7Init, + dim256JoeKuoD7Init, + dim257JoeKuoD7Init, + dim258JoeKuoD7Init, + dim259JoeKuoD7Init, + dim260JoeKuoD7Init, + dim261JoeKuoD7Init, + dim262JoeKuoD7Init, + dim263JoeKuoD7Init, + dim264JoeKuoD7Init, + dim265JoeKuoD7Init, + dim266JoeKuoD7Init, + dim267JoeKuoD7Init, + dim268JoeKuoD7Init, + dim269JoeKuoD7Init, + dim270JoeKuoD7Init, + dim271JoeKuoD7Init, + dim272JoeKuoD7Init, + dim273JoeKuoD7Init, + dim274JoeKuoD7Init, + dim275JoeKuoD7Init, + dim276JoeKuoD7Init, + dim277JoeKuoD7Init, + dim278JoeKuoD7Init, + dim279JoeKuoD7Init, + dim280JoeKuoD7Init, + dim281JoeKuoD7Init, + dim282JoeKuoD7Init, + dim283JoeKuoD7Init, + dim284JoeKuoD7Init, + dim285JoeKuoD7Init, + dim286JoeKuoD7Init, + dim287JoeKuoD7Init, + dim288JoeKuoD7Init, + dim289JoeKuoD7Init, + dim290JoeKuoD7Init, + dim291JoeKuoD7Init, + dim292JoeKuoD7Init, + dim293JoeKuoD7Init, + dim294JoeKuoD7Init, + dim295JoeKuoD7Init, + dim296JoeKuoD7Init, + dim297JoeKuoD7Init, + dim298JoeKuoD7Init, + dim299JoeKuoD7Init, + dim300JoeKuoD7Init, + dim301JoeKuoD7Init, + dim302JoeKuoD7Init, + dim303JoeKuoD7Init, + dim304JoeKuoD7Init, + dim305JoeKuoD7Init, + dim306JoeKuoD7Init, + dim307JoeKuoD7Init, + dim308JoeKuoD7Init, + dim309JoeKuoD7Init, + dim310JoeKuoD7Init, + dim311JoeKuoD7Init, + dim312JoeKuoD7Init, + dim313JoeKuoD7Init, + dim314JoeKuoD7Init, + dim315JoeKuoD7Init, + dim316JoeKuoD7Init, + dim317JoeKuoD7Init, + dim318JoeKuoD7Init, + dim319JoeKuoD7Init, + dim320JoeKuoD7Init, + dim321JoeKuoD7Init, + dim322JoeKuoD7Init, + dim323JoeKuoD7Init, + dim324JoeKuoD7Init, + dim325JoeKuoD7Init, + dim326JoeKuoD7Init, + dim327JoeKuoD7Init, + dim328JoeKuoD7Init, + dim329JoeKuoD7Init, + dim330JoeKuoD7Init, + dim331JoeKuoD7Init, + dim332JoeKuoD7Init, + dim333JoeKuoD7Init, + dim334JoeKuoD7Init, + dim335JoeKuoD7Init, + dim336JoeKuoD7Init, + dim337JoeKuoD7Init, + dim338JoeKuoD7Init, + dim339JoeKuoD7Init, + dim340JoeKuoD7Init, + dim341JoeKuoD7Init, + dim342JoeKuoD7Init, + dim343JoeKuoD7Init, + dim344JoeKuoD7Init, + dim345JoeKuoD7Init, + dim346JoeKuoD7Init, + dim347JoeKuoD7Init, + dim348JoeKuoD7Init, + dim349JoeKuoD7Init, + dim350JoeKuoD7Init, + dim351JoeKuoD7Init, + dim352JoeKuoD7Init, + dim353JoeKuoD7Init, + dim354JoeKuoD7Init, + dim355JoeKuoD7Init, + dim356JoeKuoD7Init, + dim357JoeKuoD7Init, + dim358JoeKuoD7Init, + dim359JoeKuoD7Init, + dim360JoeKuoD7Init, + dim361JoeKuoD7Init, + dim362JoeKuoD7Init, + dim363JoeKuoD7Init, + dim364JoeKuoD7Init, + dim365JoeKuoD7Init, + dim366JoeKuoD7Init, + dim367JoeKuoD7Init, + dim368JoeKuoD7Init, + dim369JoeKuoD7Init, + dim370JoeKuoD7Init, + dim371JoeKuoD7Init, + dim372JoeKuoD7Init, + dim373JoeKuoD7Init, + dim374JoeKuoD7Init, + dim375JoeKuoD7Init, + dim376JoeKuoD7Init, + dim377JoeKuoD7Init, + dim378JoeKuoD7Init, + dim379JoeKuoD7Init, + dim380JoeKuoD7Init, + dim381JoeKuoD7Init, + dim382JoeKuoD7Init, + dim383JoeKuoD7Init, + dim384JoeKuoD7Init, + dim385JoeKuoD7Init, + dim386JoeKuoD7Init, + dim387JoeKuoD7Init, + dim388JoeKuoD7Init, + dim389JoeKuoD7Init, + dim390JoeKuoD7Init, + dim391JoeKuoD7Init, + dim392JoeKuoD7Init, + dim393JoeKuoD7Init, + dim394JoeKuoD7Init, + dim395JoeKuoD7Init, + dim396JoeKuoD7Init, + dim397JoeKuoD7Init, + dim398JoeKuoD7Init, + dim399JoeKuoD7Init, + dim400JoeKuoD7Init, + dim401JoeKuoD7Init, + dim402JoeKuoD7Init, + dim403JoeKuoD7Init, + dim404JoeKuoD7Init, + dim405JoeKuoD7Init, + dim406JoeKuoD7Init, + dim407JoeKuoD7Init, + dim408JoeKuoD7Init, + dim409JoeKuoD7Init, + dim410JoeKuoD7Init, + dim411JoeKuoD7Init, + dim412JoeKuoD7Init, + dim413JoeKuoD7Init, + dim414JoeKuoD7Init, + dim415JoeKuoD7Init, + dim416JoeKuoD7Init, + dim417JoeKuoD7Init, + dim418JoeKuoD7Init, + dim419JoeKuoD7Init, + dim420JoeKuoD7Init, + dim421JoeKuoD7Init, + dim422JoeKuoD7Init, + dim423JoeKuoD7Init, + dim424JoeKuoD7Init, + dim425JoeKuoD7Init, + dim426JoeKuoD7Init, + dim427JoeKuoD7Init, + dim428JoeKuoD7Init, + dim429JoeKuoD7Init, + dim430JoeKuoD7Init, + dim431JoeKuoD7Init, + dim432JoeKuoD7Init, + dim433JoeKuoD7Init, + dim434JoeKuoD7Init, + dim435JoeKuoD7Init, + dim436JoeKuoD7Init, + dim437JoeKuoD7Init, + dim438JoeKuoD7Init, + dim439JoeKuoD7Init, + dim440JoeKuoD7Init, + dim441JoeKuoD7Init, + dim442JoeKuoD7Init, + dim443JoeKuoD7Init, + dim444JoeKuoD7Init, + dim445JoeKuoD7Init, + dim446JoeKuoD7Init, + dim447JoeKuoD7Init, + dim448JoeKuoD7Init, + dim449JoeKuoD7Init, + dim450JoeKuoD7Init, + dim451JoeKuoD7Init, + dim452JoeKuoD7Init, + dim453JoeKuoD7Init, + dim454JoeKuoD7Init, + dim455JoeKuoD7Init, + dim456JoeKuoD7Init, + dim457JoeKuoD7Init, + dim458JoeKuoD7Init, + dim459JoeKuoD7Init, + dim460JoeKuoD7Init, + dim461JoeKuoD7Init, + dim462JoeKuoD7Init, + dim463JoeKuoD7Init, + dim464JoeKuoD7Init, + dim465JoeKuoD7Init, + dim466JoeKuoD7Init, + dim467JoeKuoD7Init, + dim468JoeKuoD7Init, + dim469JoeKuoD7Init, + dim470JoeKuoD7Init, + dim471JoeKuoD7Init, + dim472JoeKuoD7Init, + dim473JoeKuoD7Init, + dim474JoeKuoD7Init, + dim475JoeKuoD7Init, + dim476JoeKuoD7Init, + dim477JoeKuoD7Init, + dim478JoeKuoD7Init, + dim479JoeKuoD7Init, + dim480JoeKuoD7Init, + dim481JoeKuoD7Init, + dim482JoeKuoD7Init, + dim483JoeKuoD7Init, + dim484JoeKuoD7Init, + dim485JoeKuoD7Init, + dim486JoeKuoD7Init, + dim487JoeKuoD7Init, + dim488JoeKuoD7Init, + dim489JoeKuoD7Init, + dim490JoeKuoD7Init, + dim491JoeKuoD7Init, + dim492JoeKuoD7Init, + dim493JoeKuoD7Init, + dim494JoeKuoD7Init, + dim495JoeKuoD7Init, + dim496JoeKuoD7Init, + dim497JoeKuoD7Init, + dim498JoeKuoD7Init, + dim499JoeKuoD7Init, + dim500JoeKuoD7Init, + dim501JoeKuoD7Init, + dim502JoeKuoD7Init, + dim503JoeKuoD7Init, + dim504JoeKuoD7Init, + dim505JoeKuoD7Init, + dim506JoeKuoD7Init, + dim507JoeKuoD7Init, + dim508JoeKuoD7Init, + dim509JoeKuoD7Init, + dim510JoeKuoD7Init, + dim511JoeKuoD7Init, + dim512JoeKuoD7Init, + dim513JoeKuoD7Init, + dim514JoeKuoD7Init, + dim515JoeKuoD7Init, + dim516JoeKuoD7Init, + dim517JoeKuoD7Init, + dim518JoeKuoD7Init, + dim519JoeKuoD7Init, + dim520JoeKuoD7Init, + dim521JoeKuoD7Init, + dim522JoeKuoD7Init, + dim523JoeKuoD7Init, + dim524JoeKuoD7Init, + dim525JoeKuoD7Init, + dim526JoeKuoD7Init, + dim527JoeKuoD7Init, + dim528JoeKuoD7Init, + dim529JoeKuoD7Init, + dim530JoeKuoD7Init, + dim531JoeKuoD7Init, + dim532JoeKuoD7Init, + dim533JoeKuoD7Init, + dim534JoeKuoD7Init, + dim535JoeKuoD7Init, + dim536JoeKuoD7Init, + dim537JoeKuoD7Init, + dim538JoeKuoD7Init, + dim539JoeKuoD7Init, + dim540JoeKuoD7Init, + dim541JoeKuoD7Init, + dim542JoeKuoD7Init, + dim543JoeKuoD7Init, + dim544JoeKuoD7Init, + dim545JoeKuoD7Init, + dim546JoeKuoD7Init, + dim547JoeKuoD7Init, + dim548JoeKuoD7Init, + dim549JoeKuoD7Init, + dim550JoeKuoD7Init, + dim551JoeKuoD7Init, + dim552JoeKuoD7Init, + dim553JoeKuoD7Init, + dim554JoeKuoD7Init, + dim555JoeKuoD7Init, + dim556JoeKuoD7Init, + dim557JoeKuoD7Init, + dim558JoeKuoD7Init, + dim559JoeKuoD7Init, + dim560JoeKuoD7Init, + dim561JoeKuoD7Init, + dim562JoeKuoD7Init, + dim563JoeKuoD7Init, + dim564JoeKuoD7Init, + dim565JoeKuoD7Init, + dim566JoeKuoD7Init, + dim567JoeKuoD7Init, + dim568JoeKuoD7Init, + dim569JoeKuoD7Init, + dim570JoeKuoD7Init, + dim571JoeKuoD7Init, + dim572JoeKuoD7Init, + dim573JoeKuoD7Init, + dim574JoeKuoD7Init, + dim575JoeKuoD7Init, + dim576JoeKuoD7Init, + dim577JoeKuoD7Init, + dim578JoeKuoD7Init, + dim579JoeKuoD7Init, + dim580JoeKuoD7Init, + dim581JoeKuoD7Init, + dim582JoeKuoD7Init, + dim583JoeKuoD7Init, + dim584JoeKuoD7Init, + dim585JoeKuoD7Init, + dim586JoeKuoD7Init, + dim587JoeKuoD7Init, + dim588JoeKuoD7Init, + dim589JoeKuoD7Init, + dim590JoeKuoD7Init, + dim591JoeKuoD7Init, + dim592JoeKuoD7Init, + dim593JoeKuoD7Init, + dim594JoeKuoD7Init, + dim595JoeKuoD7Init, + dim596JoeKuoD7Init, + dim597JoeKuoD7Init, + dim598JoeKuoD7Init, + dim599JoeKuoD7Init, + dim600JoeKuoD7Init, + dim601JoeKuoD7Init, + dim602JoeKuoD7Init, + dim603JoeKuoD7Init, + dim604JoeKuoD7Init, + dim605JoeKuoD7Init, + dim606JoeKuoD7Init, + dim607JoeKuoD7Init, + dim608JoeKuoD7Init, + dim609JoeKuoD7Init, + dim610JoeKuoD7Init, + dim611JoeKuoD7Init, + dim612JoeKuoD7Init, + dim613JoeKuoD7Init, + dim614JoeKuoD7Init, + dim615JoeKuoD7Init, + dim616JoeKuoD7Init, + dim617JoeKuoD7Init, + dim618JoeKuoD7Init, + dim619JoeKuoD7Init, + dim620JoeKuoD7Init, + dim621JoeKuoD7Init, + dim622JoeKuoD7Init, + dim623JoeKuoD7Init, + dim624JoeKuoD7Init, + dim625JoeKuoD7Init, + dim626JoeKuoD7Init, + dim627JoeKuoD7Init, + dim628JoeKuoD7Init, + dim629JoeKuoD7Init, + dim630JoeKuoD7Init, + dim631JoeKuoD7Init, + dim632JoeKuoD7Init, + dim633JoeKuoD7Init, + dim634JoeKuoD7Init, + dim635JoeKuoD7Init, + dim636JoeKuoD7Init, + dim637JoeKuoD7Init, + dim638JoeKuoD7Init, + dim639JoeKuoD7Init, + dim640JoeKuoD7Init, + dim641JoeKuoD7Init, + dim642JoeKuoD7Init, + dim643JoeKuoD7Init, + dim644JoeKuoD7Init, + dim645JoeKuoD7Init, + dim646JoeKuoD7Init, + dim647JoeKuoD7Init, + dim648JoeKuoD7Init, + dim649JoeKuoD7Init, + dim650JoeKuoD7Init, + dim651JoeKuoD7Init, + dim652JoeKuoD7Init, + dim653JoeKuoD7Init, + dim654JoeKuoD7Init, + dim655JoeKuoD7Init, + dim656JoeKuoD7Init, + dim657JoeKuoD7Init, + dim658JoeKuoD7Init, + dim659JoeKuoD7Init, + dim660JoeKuoD7Init, + dim661JoeKuoD7Init, + dim662JoeKuoD7Init, + dim663JoeKuoD7Init, + dim664JoeKuoD7Init, + dim665JoeKuoD7Init, + dim666JoeKuoD7Init, + dim667JoeKuoD7Init, + dim668JoeKuoD7Init, + dim669JoeKuoD7Init, + dim670JoeKuoD7Init, + dim671JoeKuoD7Init, + dim672JoeKuoD7Init, + dim673JoeKuoD7Init, + dim674JoeKuoD7Init, + dim675JoeKuoD7Init, + dim676JoeKuoD7Init, + dim677JoeKuoD7Init, + dim678JoeKuoD7Init, + dim679JoeKuoD7Init, + dim680JoeKuoD7Init, + dim681JoeKuoD7Init, + dim682JoeKuoD7Init, + dim683JoeKuoD7Init, + dim684JoeKuoD7Init, + dim685JoeKuoD7Init, + dim686JoeKuoD7Init, + dim687JoeKuoD7Init, + dim688JoeKuoD7Init, + dim689JoeKuoD7Init, + dim690JoeKuoD7Init, + dim691JoeKuoD7Init, + dim692JoeKuoD7Init, + dim693JoeKuoD7Init, + dim694JoeKuoD7Init, + dim695JoeKuoD7Init, + dim696JoeKuoD7Init, + dim697JoeKuoD7Init, + dim698JoeKuoD7Init, + dim699JoeKuoD7Init, + dim700JoeKuoD7Init, + dim701JoeKuoD7Init, + dim702JoeKuoD7Init, + dim703JoeKuoD7Init, + dim704JoeKuoD7Init, + dim705JoeKuoD7Init, + dim706JoeKuoD7Init, + dim707JoeKuoD7Init, + dim708JoeKuoD7Init, + dim709JoeKuoD7Init, + dim710JoeKuoD7Init, + dim711JoeKuoD7Init, + dim712JoeKuoD7Init, + dim713JoeKuoD7Init, + dim714JoeKuoD7Init, + dim715JoeKuoD7Init, + dim716JoeKuoD7Init, + dim717JoeKuoD7Init, + dim718JoeKuoD7Init, + dim719JoeKuoD7Init, + dim720JoeKuoD7Init, + dim721JoeKuoD7Init, + dim722JoeKuoD7Init, + dim723JoeKuoD7Init, + dim724JoeKuoD7Init, + dim725JoeKuoD7Init, + dim726JoeKuoD7Init, + dim727JoeKuoD7Init, + dim728JoeKuoD7Init, + dim729JoeKuoD7Init, + dim730JoeKuoD7Init, + dim731JoeKuoD7Init, + dim732JoeKuoD7Init, + dim733JoeKuoD7Init, + dim734JoeKuoD7Init, + dim735JoeKuoD7Init, + dim736JoeKuoD7Init, + dim737JoeKuoD7Init, + dim738JoeKuoD7Init, + dim739JoeKuoD7Init, + dim740JoeKuoD7Init, + dim741JoeKuoD7Init, + dim742JoeKuoD7Init, + dim743JoeKuoD7Init, + dim744JoeKuoD7Init, + dim745JoeKuoD7Init, + dim746JoeKuoD7Init, + dim747JoeKuoD7Init, + dim748JoeKuoD7Init, + dim749JoeKuoD7Init, + dim750JoeKuoD7Init, + dim751JoeKuoD7Init, + dim752JoeKuoD7Init, + dim753JoeKuoD7Init, + dim754JoeKuoD7Init, + dim755JoeKuoD7Init, + dim756JoeKuoD7Init, + dim757JoeKuoD7Init, + dim758JoeKuoD7Init, + dim759JoeKuoD7Init, + dim760JoeKuoD7Init, + dim761JoeKuoD7Init, + dim762JoeKuoD7Init, + dim763JoeKuoD7Init, + dim764JoeKuoD7Init, + dim765JoeKuoD7Init, + dim766JoeKuoD7Init, + dim767JoeKuoD7Init, + dim768JoeKuoD7Init, + dim769JoeKuoD7Init, + dim770JoeKuoD7Init, + dim771JoeKuoD7Init, + dim772JoeKuoD7Init, + dim773JoeKuoD7Init, + dim774JoeKuoD7Init, + dim775JoeKuoD7Init, + dim776JoeKuoD7Init, + dim777JoeKuoD7Init, + dim778JoeKuoD7Init, + dim779JoeKuoD7Init, + dim780JoeKuoD7Init, + dim781JoeKuoD7Init, + dim782JoeKuoD7Init, + dim783JoeKuoD7Init, + dim784JoeKuoD7Init, + dim785JoeKuoD7Init, + dim786JoeKuoD7Init, + dim787JoeKuoD7Init, + dim788JoeKuoD7Init, + dim789JoeKuoD7Init, + dim790JoeKuoD7Init, + dim791JoeKuoD7Init, + dim792JoeKuoD7Init, + dim793JoeKuoD7Init, + dim794JoeKuoD7Init, + dim795JoeKuoD7Init, + dim796JoeKuoD7Init, + dim797JoeKuoD7Init, + dim798JoeKuoD7Init, + dim799JoeKuoD7Init, + dim800JoeKuoD7Init, + dim801JoeKuoD7Init, + dim802JoeKuoD7Init, + dim803JoeKuoD7Init, + dim804JoeKuoD7Init, + dim805JoeKuoD7Init, + dim806JoeKuoD7Init, + dim807JoeKuoD7Init, + dim808JoeKuoD7Init, + dim809JoeKuoD7Init, + dim810JoeKuoD7Init, + dim811JoeKuoD7Init, + dim812JoeKuoD7Init, + dim813JoeKuoD7Init, + dim814JoeKuoD7Init, + dim815JoeKuoD7Init, + dim816JoeKuoD7Init, + dim817JoeKuoD7Init, + dim818JoeKuoD7Init, + dim819JoeKuoD7Init, + dim820JoeKuoD7Init, + dim821JoeKuoD7Init, + dim822JoeKuoD7Init, + dim823JoeKuoD7Init, + dim824JoeKuoD7Init, + dim825JoeKuoD7Init, + dim826JoeKuoD7Init, + dim827JoeKuoD7Init, + dim828JoeKuoD7Init, + dim829JoeKuoD7Init, + dim830JoeKuoD7Init, + dim831JoeKuoD7Init, + dim832JoeKuoD7Init, + dim833JoeKuoD7Init, + dim834JoeKuoD7Init, + dim835JoeKuoD7Init, + dim836JoeKuoD7Init, + dim837JoeKuoD7Init, + dim838JoeKuoD7Init, + dim839JoeKuoD7Init, + dim840JoeKuoD7Init, + dim841JoeKuoD7Init, + dim842JoeKuoD7Init, + dim843JoeKuoD7Init, + dim844JoeKuoD7Init, + dim845JoeKuoD7Init, + dim846JoeKuoD7Init, + dim847JoeKuoD7Init, + dim848JoeKuoD7Init, + dim849JoeKuoD7Init, + dim850JoeKuoD7Init, + dim851JoeKuoD7Init, + dim852JoeKuoD7Init, + dim853JoeKuoD7Init, + dim854JoeKuoD7Init, + dim855JoeKuoD7Init, + dim856JoeKuoD7Init, + dim857JoeKuoD7Init, + dim858JoeKuoD7Init, + dim859JoeKuoD7Init, + dim860JoeKuoD7Init, + dim861JoeKuoD7Init, + dim862JoeKuoD7Init, + dim863JoeKuoD7Init, + dim864JoeKuoD7Init, + dim865JoeKuoD7Init, + dim866JoeKuoD7Init, + dim867JoeKuoD7Init, + dim868JoeKuoD7Init, + dim869JoeKuoD7Init, + dim870JoeKuoD7Init, + dim871JoeKuoD7Init, + dim872JoeKuoD7Init, + dim873JoeKuoD7Init, + dim874JoeKuoD7Init, + dim875JoeKuoD7Init, + dim876JoeKuoD7Init, + dim877JoeKuoD7Init, + dim878JoeKuoD7Init, + dim879JoeKuoD7Init, + dim880JoeKuoD7Init, + dim881JoeKuoD7Init, + dim882JoeKuoD7Init, + dim883JoeKuoD7Init, + dim884JoeKuoD7Init, + dim885JoeKuoD7Init, + dim886JoeKuoD7Init, + dim887JoeKuoD7Init, + dim888JoeKuoD7Init, + dim889JoeKuoD7Init, + dim890JoeKuoD7Init, + dim891JoeKuoD7Init, + dim892JoeKuoD7Init, + dim893JoeKuoD7Init, + dim894JoeKuoD7Init, + dim895JoeKuoD7Init, + dim896JoeKuoD7Init, + dim897JoeKuoD7Init, + dim898JoeKuoD7Init, + dim899JoeKuoD7Init, + dim900JoeKuoD7Init, + dim901JoeKuoD7Init, + dim902JoeKuoD7Init, + dim903JoeKuoD7Init, + dim904JoeKuoD7Init, + dim905JoeKuoD7Init, + dim906JoeKuoD7Init, + dim907JoeKuoD7Init, + dim908JoeKuoD7Init, + dim909JoeKuoD7Init, + dim910JoeKuoD7Init, + dim911JoeKuoD7Init, + dim912JoeKuoD7Init, + dim913JoeKuoD7Init, + dim914JoeKuoD7Init, + dim915JoeKuoD7Init, + dim916JoeKuoD7Init, + dim917JoeKuoD7Init, + dim918JoeKuoD7Init, + dim919JoeKuoD7Init, + dim920JoeKuoD7Init, + dim921JoeKuoD7Init, + dim922JoeKuoD7Init, + dim923JoeKuoD7Init, + dim924JoeKuoD7Init, + dim925JoeKuoD7Init, + dim926JoeKuoD7Init, + dim927JoeKuoD7Init, + dim928JoeKuoD7Init, + dim929JoeKuoD7Init, + dim930JoeKuoD7Init, + dim931JoeKuoD7Init, + dim932JoeKuoD7Init, + dim933JoeKuoD7Init, + dim934JoeKuoD7Init, + dim935JoeKuoD7Init, + dim936JoeKuoD7Init, + dim937JoeKuoD7Init, + dim938JoeKuoD7Init, + dim939JoeKuoD7Init, + dim940JoeKuoD7Init, + dim941JoeKuoD7Init, + dim942JoeKuoD7Init, + dim943JoeKuoD7Init, + dim944JoeKuoD7Init, + dim945JoeKuoD7Init, + dim946JoeKuoD7Init, + dim947JoeKuoD7Init, + dim948JoeKuoD7Init, + dim949JoeKuoD7Init, + dim950JoeKuoD7Init, + dim951JoeKuoD7Init, + dim952JoeKuoD7Init, + dim953JoeKuoD7Init, + dim954JoeKuoD7Init, + dim955JoeKuoD7Init, + dim956JoeKuoD7Init, + dim957JoeKuoD7Init, + dim958JoeKuoD7Init, + dim959JoeKuoD7Init, + dim960JoeKuoD7Init, + dim961JoeKuoD7Init, + dim962JoeKuoD7Init, + dim963JoeKuoD7Init, + dim964JoeKuoD7Init, + dim965JoeKuoD7Init, + dim966JoeKuoD7Init, + dim967JoeKuoD7Init, + dim968JoeKuoD7Init, + dim969JoeKuoD7Init, + dim970JoeKuoD7Init, + dim971JoeKuoD7Init, + dim972JoeKuoD7Init, + dim973JoeKuoD7Init, + dim974JoeKuoD7Init, + dim975JoeKuoD7Init, + dim976JoeKuoD7Init, + dim977JoeKuoD7Init, + dim978JoeKuoD7Init, + dim979JoeKuoD7Init, + dim980JoeKuoD7Init, + dim981JoeKuoD7Init, + dim982JoeKuoD7Init, + dim983JoeKuoD7Init, + dim984JoeKuoD7Init, + dim985JoeKuoD7Init, + dim986JoeKuoD7Init, + dim987JoeKuoD7Init, + dim988JoeKuoD7Init, + dim989JoeKuoD7Init, + dim990JoeKuoD7Init, + dim991JoeKuoD7Init, + dim992JoeKuoD7Init, + dim993JoeKuoD7Init, + dim994JoeKuoD7Init, + dim995JoeKuoD7Init, + dim996JoeKuoD7Init, + dim997JoeKuoD7Init, + dim998JoeKuoD7Init, + dim999JoeKuoD7Init, + dim1000JoeKuoD7Init, + dim1001JoeKuoD7Init, + dim1002JoeKuoD7Init, + dim1003JoeKuoD7Init, + dim1004JoeKuoD7Init, + dim1005JoeKuoD7Init, + dim1006JoeKuoD7Init, + dim1007JoeKuoD7Init, + dim1008JoeKuoD7Init, + dim1009JoeKuoD7Init, + dim1010JoeKuoD7Init, + dim1011JoeKuoD7Init, + dim1012JoeKuoD7Init, + dim1013JoeKuoD7Init, + dim1014JoeKuoD7Init, + dim1015JoeKuoD7Init, + dim1016JoeKuoD7Init, + dim1017JoeKuoD7Init, + dim1018JoeKuoD7Init, + dim1019JoeKuoD7Init, + dim1020JoeKuoD7Init, + dim1021JoeKuoD7Init, + dim1022JoeKuoD7Init, + dim1023JoeKuoD7Init, + dim1024JoeKuoD7Init, + dim1025JoeKuoD7Init, + dim1026JoeKuoD7Init, + dim1027JoeKuoD7Init, + dim1028JoeKuoD7Init, + dim1029JoeKuoD7Init, + dim1030JoeKuoD7Init, + dim1031JoeKuoD7Init, + dim1032JoeKuoD7Init, + dim1033JoeKuoD7Init, + dim1034JoeKuoD7Init, + dim1035JoeKuoD7Init, + dim1036JoeKuoD7Init, + dim1037JoeKuoD7Init, + dim1038JoeKuoD7Init, + dim1039JoeKuoD7Init, + dim1040JoeKuoD7Init, + dim1041JoeKuoD7Init, + dim1042JoeKuoD7Init, + dim1043JoeKuoD7Init, + dim1044JoeKuoD7Init, + dim1045JoeKuoD7Init, + dim1046JoeKuoD7Init, + dim1047JoeKuoD7Init, + dim1048JoeKuoD7Init, + dim1049JoeKuoD7Init, + dim1050JoeKuoD7Init, + dim1051JoeKuoD7Init, + dim1052JoeKuoD7Init, + dim1053JoeKuoD7Init, + dim1054JoeKuoD7Init, + dim1055JoeKuoD7Init, + dim1056JoeKuoD7Init, + dim1057JoeKuoD7Init, + dim1058JoeKuoD7Init, + dim1059JoeKuoD7Init, + dim1060JoeKuoD7Init, + dim1061JoeKuoD7Init, + dim1062JoeKuoD7Init, + dim1063JoeKuoD7Init, + dim1064JoeKuoD7Init, + dim1065JoeKuoD7Init, + dim1066JoeKuoD7Init, + dim1067JoeKuoD7Init, + dim1068JoeKuoD7Init, + dim1069JoeKuoD7Init, + dim1070JoeKuoD7Init, + dim1071JoeKuoD7Init, + dim1072JoeKuoD7Init, + dim1073JoeKuoD7Init, + dim1074JoeKuoD7Init, + dim1075JoeKuoD7Init, + dim1076JoeKuoD7Init, + dim1077JoeKuoD7Init, + dim1078JoeKuoD7Init, + dim1079JoeKuoD7Init, + dim1080JoeKuoD7Init, + dim1081JoeKuoD7Init, + dim1082JoeKuoD7Init, + dim1083JoeKuoD7Init, + dim1084JoeKuoD7Init, + dim1085JoeKuoD7Init, + dim1086JoeKuoD7Init, + dim1087JoeKuoD7Init, + dim1088JoeKuoD7Init, + dim1089JoeKuoD7Init, + dim1090JoeKuoD7Init, + dim1091JoeKuoD7Init, + dim1092JoeKuoD7Init, + dim1093JoeKuoD7Init, + dim1094JoeKuoD7Init, + dim1095JoeKuoD7Init, + dim1096JoeKuoD7Init, + dim1097JoeKuoD7Init, + dim1098JoeKuoD7Init, + dim1099JoeKuoD7Init, + dim1100JoeKuoD7Init, + dim1101JoeKuoD7Init, + dim1102JoeKuoD7Init, + dim1103JoeKuoD7Init, + dim1104JoeKuoD7Init, + dim1105JoeKuoD7Init, + dim1106JoeKuoD7Init, + dim1107JoeKuoD7Init, + dim1108JoeKuoD7Init, + dim1109JoeKuoD7Init, + dim1110JoeKuoD7Init, + dim1111JoeKuoD7Init, + dim1112JoeKuoD7Init, + dim1113JoeKuoD7Init, + dim1114JoeKuoD7Init, + dim1115JoeKuoD7Init, + dim1116JoeKuoD7Init, + dim1117JoeKuoD7Init, + dim1118JoeKuoD7Init, + dim1119JoeKuoD7Init, + dim1120JoeKuoD7Init, + dim1121JoeKuoD7Init, + dim1122JoeKuoD7Init, + dim1123JoeKuoD7Init, + dim1124JoeKuoD7Init, + dim1125JoeKuoD7Init, + dim1126JoeKuoD7Init, + dim1127JoeKuoD7Init, + dim1128JoeKuoD7Init, + dim1129JoeKuoD7Init, + dim1130JoeKuoD7Init, + dim1131JoeKuoD7Init, + dim1132JoeKuoD7Init, + dim1133JoeKuoD7Init, + dim1134JoeKuoD7Init, + dim1135JoeKuoD7Init, + dim1136JoeKuoD7Init, + dim1137JoeKuoD7Init, + dim1138JoeKuoD7Init, + dim1139JoeKuoD7Init, + dim1140JoeKuoD7Init, + dim1141JoeKuoD7Init, + dim1142JoeKuoD7Init, + dim1143JoeKuoD7Init, + dim1144JoeKuoD7Init, + dim1145JoeKuoD7Init, + dim1146JoeKuoD7Init, + dim1147JoeKuoD7Init, + dim1148JoeKuoD7Init, + dim1149JoeKuoD7Init, + dim1150JoeKuoD7Init, + dim1151JoeKuoD7Init, + dim1152JoeKuoD7Init, + dim1153JoeKuoD7Init, + dim1154JoeKuoD7Init, + dim1155JoeKuoD7Init, + dim1156JoeKuoD7Init, + dim1157JoeKuoD7Init, + dim1158JoeKuoD7Init, + dim1159JoeKuoD7Init, + dim1160JoeKuoD7Init, + dim1161JoeKuoD7Init, + dim1162JoeKuoD7Init, + dim1163JoeKuoD7Init, + dim1164JoeKuoD7Init, + dim1165JoeKuoD7Init, + dim1166JoeKuoD7Init, + dim1167JoeKuoD7Init, + dim1168JoeKuoD7Init, + dim1169JoeKuoD7Init, + dim1170JoeKuoD7Init, + dim1171JoeKuoD7Init, + dim1172JoeKuoD7Init, + dim1173JoeKuoD7Init, + dim1174JoeKuoD7Init, + dim1175JoeKuoD7Init, + dim1176JoeKuoD7Init, + dim1177JoeKuoD7Init, + dim1178JoeKuoD7Init, + dim1179JoeKuoD7Init, + dim1180JoeKuoD7Init, + dim1181JoeKuoD7Init, + dim1182JoeKuoD7Init, + dim1183JoeKuoD7Init, + dim1184JoeKuoD7Init, + dim1185JoeKuoD7Init, + dim1186JoeKuoD7Init, + dim1187JoeKuoD7Init, + dim1188JoeKuoD7Init, + dim1189JoeKuoD7Init, + dim1190JoeKuoD7Init, + dim1191JoeKuoD7Init, + dim1192JoeKuoD7Init, + dim1193JoeKuoD7Init, + dim1194JoeKuoD7Init, + dim1195JoeKuoD7Init, + dim1196JoeKuoD7Init, + dim1197JoeKuoD7Init, + dim1198JoeKuoD7Init, + dim1199JoeKuoD7Init, + dim1200JoeKuoD7Init, + dim1201JoeKuoD7Init, + dim1202JoeKuoD7Init, + dim1203JoeKuoD7Init, + dim1204JoeKuoD7Init, + dim1205JoeKuoD7Init, + dim1206JoeKuoD7Init, + dim1207JoeKuoD7Init, + dim1208JoeKuoD7Init, + dim1209JoeKuoD7Init, + dim1210JoeKuoD7Init, + dim1211JoeKuoD7Init, + dim1212JoeKuoD7Init, + dim1213JoeKuoD7Init, + dim1214JoeKuoD7Init, + dim1215JoeKuoD7Init, + dim1216JoeKuoD7Init, + dim1217JoeKuoD7Init, + dim1218JoeKuoD7Init, + dim1219JoeKuoD7Init, + dim1220JoeKuoD7Init, + dim1221JoeKuoD7Init, + dim1222JoeKuoD7Init, + dim1223JoeKuoD7Init, + dim1224JoeKuoD7Init, + dim1225JoeKuoD7Init, + dim1226JoeKuoD7Init, + dim1227JoeKuoD7Init, + dim1228JoeKuoD7Init, + dim1229JoeKuoD7Init, + dim1230JoeKuoD7Init, + dim1231JoeKuoD7Init, + dim1232JoeKuoD7Init, + dim1233JoeKuoD7Init, + dim1234JoeKuoD7Init, + dim1235JoeKuoD7Init, + dim1236JoeKuoD7Init, + dim1237JoeKuoD7Init, + dim1238JoeKuoD7Init, + dim1239JoeKuoD7Init, + dim1240JoeKuoD7Init, + dim1241JoeKuoD7Init, + dim1242JoeKuoD7Init, + dim1243JoeKuoD7Init, + dim1244JoeKuoD7Init, + dim1245JoeKuoD7Init, + dim1246JoeKuoD7Init, + dim1247JoeKuoD7Init, + dim1248JoeKuoD7Init, + dim1249JoeKuoD7Init, + dim1250JoeKuoD7Init, + dim1251JoeKuoD7Init, + dim1252JoeKuoD7Init, + dim1253JoeKuoD7Init, + dim1254JoeKuoD7Init, + dim1255JoeKuoD7Init, + dim1256JoeKuoD7Init, + dim1257JoeKuoD7Init, + dim1258JoeKuoD7Init, + dim1259JoeKuoD7Init, + dim1260JoeKuoD7Init, + dim1261JoeKuoD7Init, + dim1262JoeKuoD7Init, + dim1263JoeKuoD7Init, + dim1264JoeKuoD7Init, + dim1265JoeKuoD7Init, + dim1266JoeKuoD7Init, + dim1267JoeKuoD7Init, + dim1268JoeKuoD7Init, + dim1269JoeKuoD7Init, + dim1270JoeKuoD7Init, + dim1271JoeKuoD7Init, + dim1272JoeKuoD7Init, + dim1273JoeKuoD7Init, + dim1274JoeKuoD7Init, + dim1275JoeKuoD7Init, + dim1276JoeKuoD7Init, + dim1277JoeKuoD7Init, + dim1278JoeKuoD7Init, + dim1279JoeKuoD7Init, + dim1280JoeKuoD7Init, + dim1281JoeKuoD7Init, + dim1282JoeKuoD7Init, + dim1283JoeKuoD7Init, + dim1284JoeKuoD7Init, + dim1285JoeKuoD7Init, + dim1286JoeKuoD7Init, + dim1287JoeKuoD7Init, + dim1288JoeKuoD7Init, + dim1289JoeKuoD7Init, + dim1290JoeKuoD7Init, + dim1291JoeKuoD7Init, + dim1292JoeKuoD7Init, + dim1293JoeKuoD7Init, + dim1294JoeKuoD7Init, + dim1295JoeKuoD7Init, + dim1296JoeKuoD7Init, + dim1297JoeKuoD7Init, + dim1298JoeKuoD7Init, + dim1299JoeKuoD7Init, + dim1300JoeKuoD7Init, + dim1301JoeKuoD7Init, + dim1302JoeKuoD7Init, + dim1303JoeKuoD7Init, + dim1304JoeKuoD7Init, + dim1305JoeKuoD7Init, + dim1306JoeKuoD7Init, + dim1307JoeKuoD7Init, + dim1308JoeKuoD7Init, + dim1309JoeKuoD7Init, + dim1310JoeKuoD7Init, + dim1311JoeKuoD7Init, + dim1312JoeKuoD7Init, + dim1313JoeKuoD7Init, + dim1314JoeKuoD7Init, + dim1315JoeKuoD7Init, + dim1316JoeKuoD7Init, + dim1317JoeKuoD7Init, + dim1318JoeKuoD7Init, + dim1319JoeKuoD7Init, + dim1320JoeKuoD7Init, + dim1321JoeKuoD7Init, + dim1322JoeKuoD7Init, + dim1323JoeKuoD7Init, + dim1324JoeKuoD7Init, + dim1325JoeKuoD7Init, + dim1326JoeKuoD7Init, + dim1327JoeKuoD7Init, + dim1328JoeKuoD7Init, + dim1329JoeKuoD7Init, + dim1330JoeKuoD7Init, + dim1331JoeKuoD7Init, + dim1332JoeKuoD7Init, + dim1333JoeKuoD7Init, + dim1334JoeKuoD7Init, + dim1335JoeKuoD7Init, + dim1336JoeKuoD7Init, + dim1337JoeKuoD7Init, + dim1338JoeKuoD7Init, + dim1339JoeKuoD7Init, + dim1340JoeKuoD7Init, + dim1341JoeKuoD7Init, + dim1342JoeKuoD7Init, + dim1343JoeKuoD7Init, + dim1344JoeKuoD7Init, + dim1345JoeKuoD7Init, + dim1346JoeKuoD7Init, + dim1347JoeKuoD7Init, + dim1348JoeKuoD7Init, + dim1349JoeKuoD7Init, + dim1350JoeKuoD7Init, + dim1351JoeKuoD7Init, + dim1352JoeKuoD7Init, + dim1353JoeKuoD7Init, + dim1354JoeKuoD7Init, + dim1355JoeKuoD7Init, + dim1356JoeKuoD7Init, + dim1357JoeKuoD7Init, + dim1358JoeKuoD7Init, + dim1359JoeKuoD7Init, + dim1360JoeKuoD7Init, + dim1361JoeKuoD7Init, + dim1362JoeKuoD7Init, + dim1363JoeKuoD7Init, + dim1364JoeKuoD7Init, + dim1365JoeKuoD7Init, + dim1366JoeKuoD7Init, + dim1367JoeKuoD7Init, + dim1368JoeKuoD7Init, + dim1369JoeKuoD7Init, + dim1370JoeKuoD7Init, + dim1371JoeKuoD7Init, + dim1372JoeKuoD7Init, + dim1373JoeKuoD7Init, + dim1374JoeKuoD7Init, + dim1375JoeKuoD7Init, + dim1376JoeKuoD7Init, + dim1377JoeKuoD7Init, + dim1378JoeKuoD7Init, + dim1379JoeKuoD7Init, + dim1380JoeKuoD7Init, + dim1381JoeKuoD7Init, + dim1382JoeKuoD7Init, + dim1383JoeKuoD7Init, + dim1384JoeKuoD7Init, + dim1385JoeKuoD7Init, + dim1386JoeKuoD7Init, + dim1387JoeKuoD7Init, + dim1388JoeKuoD7Init, + dim1389JoeKuoD7Init, + dim1390JoeKuoD7Init, + dim1391JoeKuoD7Init, + dim1392JoeKuoD7Init, + dim1393JoeKuoD7Init, + dim1394JoeKuoD7Init, + dim1395JoeKuoD7Init, + dim1396JoeKuoD7Init, + dim1397JoeKuoD7Init, + dim1398JoeKuoD7Init, + dim1399JoeKuoD7Init, + dim1400JoeKuoD7Init, + dim1401JoeKuoD7Init, + dim1402JoeKuoD7Init, + dim1403JoeKuoD7Init, + dim1404JoeKuoD7Init, + dim1405JoeKuoD7Init, + dim1406JoeKuoD7Init, + dim1407JoeKuoD7Init, + dim1408JoeKuoD7Init, + dim1409JoeKuoD7Init, + dim1410JoeKuoD7Init, + dim1411JoeKuoD7Init, + dim1412JoeKuoD7Init, + dim1413JoeKuoD7Init, + dim1414JoeKuoD7Init, + dim1415JoeKuoD7Init, + dim1416JoeKuoD7Init, + dim1417JoeKuoD7Init, + dim1418JoeKuoD7Init, + dim1419JoeKuoD7Init, + dim1420JoeKuoD7Init, + dim1421JoeKuoD7Init, + dim1422JoeKuoD7Init, + dim1423JoeKuoD7Init, + dim1424JoeKuoD7Init, + dim1425JoeKuoD7Init, + dim1426JoeKuoD7Init, + dim1427JoeKuoD7Init, + dim1428JoeKuoD7Init, + dim1429JoeKuoD7Init, + dim1430JoeKuoD7Init, + dim1431JoeKuoD7Init, + dim1432JoeKuoD7Init, + dim1433JoeKuoD7Init, + dim1434JoeKuoD7Init, + dim1435JoeKuoD7Init, + dim1436JoeKuoD7Init, + dim1437JoeKuoD7Init, + dim1438JoeKuoD7Init, + dim1439JoeKuoD7Init, + dim1440JoeKuoD7Init, + dim1441JoeKuoD7Init, + dim1442JoeKuoD7Init, + dim1443JoeKuoD7Init, + dim1444JoeKuoD7Init, + dim1445JoeKuoD7Init, + dim1446JoeKuoD7Init, + dim1447JoeKuoD7Init, + dim1448JoeKuoD7Init, + dim1449JoeKuoD7Init, + dim1450JoeKuoD7Init, + dim1451JoeKuoD7Init, + dim1452JoeKuoD7Init, + dim1453JoeKuoD7Init, + dim1454JoeKuoD7Init, + dim1455JoeKuoD7Init, + dim1456JoeKuoD7Init, + dim1457JoeKuoD7Init, + dim1458JoeKuoD7Init, + dim1459JoeKuoD7Init, + dim1460JoeKuoD7Init, + dim1461JoeKuoD7Init, + dim1462JoeKuoD7Init, + dim1463JoeKuoD7Init, + dim1464JoeKuoD7Init, + dim1465JoeKuoD7Init, + dim1466JoeKuoD7Init, + dim1467JoeKuoD7Init, + dim1468JoeKuoD7Init, + dim1469JoeKuoD7Init, + dim1470JoeKuoD7Init, + dim1471JoeKuoD7Init, + dim1472JoeKuoD7Init, + dim1473JoeKuoD7Init, + dim1474JoeKuoD7Init, + dim1475JoeKuoD7Init, + dim1476JoeKuoD7Init, + dim1477JoeKuoD7Init, + dim1478JoeKuoD7Init, + dim1479JoeKuoD7Init, + dim1480JoeKuoD7Init, + dim1481JoeKuoD7Init, + dim1482JoeKuoD7Init, + dim1483JoeKuoD7Init, + dim1484JoeKuoD7Init, + dim1485JoeKuoD7Init, + dim1486JoeKuoD7Init, + dim1487JoeKuoD7Init, + dim1488JoeKuoD7Init, + dim1489JoeKuoD7Init, + dim1490JoeKuoD7Init, + dim1491JoeKuoD7Init, + dim1492JoeKuoD7Init, + dim1493JoeKuoD7Init, + dim1494JoeKuoD7Init, + dim1495JoeKuoD7Init, + dim1496JoeKuoD7Init, + dim1497JoeKuoD7Init, + dim1498JoeKuoD7Init, + dim1499JoeKuoD7Init, + dim1500JoeKuoD7Init, + dim1501JoeKuoD7Init, + dim1502JoeKuoD7Init, + dim1503JoeKuoD7Init, + dim1504JoeKuoD7Init, + dim1505JoeKuoD7Init, + dim1506JoeKuoD7Init, + dim1507JoeKuoD7Init, + dim1508JoeKuoD7Init, + dim1509JoeKuoD7Init, + dim1510JoeKuoD7Init, + dim1511JoeKuoD7Init, + dim1512JoeKuoD7Init, + dim1513JoeKuoD7Init, + dim1514JoeKuoD7Init, + dim1515JoeKuoD7Init, + dim1516JoeKuoD7Init, + dim1517JoeKuoD7Init, + dim1518JoeKuoD7Init, + dim1519JoeKuoD7Init, + dim1520JoeKuoD7Init, + dim1521JoeKuoD7Init, + dim1522JoeKuoD7Init, + dim1523JoeKuoD7Init, + dim1524JoeKuoD7Init, + dim1525JoeKuoD7Init, + dim1526JoeKuoD7Init, + dim1527JoeKuoD7Init, + dim1528JoeKuoD7Init, + dim1529JoeKuoD7Init, + dim1530JoeKuoD7Init, + dim1531JoeKuoD7Init, + dim1532JoeKuoD7Init, + dim1533JoeKuoD7Init, + dim1534JoeKuoD7Init, + dim1535JoeKuoD7Init, + dim1536JoeKuoD7Init, + dim1537JoeKuoD7Init, + dim1538JoeKuoD7Init, + dim1539JoeKuoD7Init, + dim1540JoeKuoD7Init, + dim1541JoeKuoD7Init, + dim1542JoeKuoD7Init, + dim1543JoeKuoD7Init, + dim1544JoeKuoD7Init, + dim1545JoeKuoD7Init, + dim1546JoeKuoD7Init, + dim1547JoeKuoD7Init, + dim1548JoeKuoD7Init, + dim1549JoeKuoD7Init, + dim1550JoeKuoD7Init, + dim1551JoeKuoD7Init, + dim1552JoeKuoD7Init, + dim1553JoeKuoD7Init, + dim1554JoeKuoD7Init, + dim1555JoeKuoD7Init, + dim1556JoeKuoD7Init, + dim1557JoeKuoD7Init, + dim1558JoeKuoD7Init, + dim1559JoeKuoD7Init, + dim1560JoeKuoD7Init, + dim1561JoeKuoD7Init, + dim1562JoeKuoD7Init, + dim1563JoeKuoD7Init, + dim1564JoeKuoD7Init, + dim1565JoeKuoD7Init, + dim1566JoeKuoD7Init, + dim1567JoeKuoD7Init, + dim1568JoeKuoD7Init, + dim1569JoeKuoD7Init, + dim1570JoeKuoD7Init, + dim1571JoeKuoD7Init, + dim1572JoeKuoD7Init, + dim1573JoeKuoD7Init, + dim1574JoeKuoD7Init, + dim1575JoeKuoD7Init, + dim1576JoeKuoD7Init, + dim1577JoeKuoD7Init, + dim1578JoeKuoD7Init, + dim1579JoeKuoD7Init, + dim1580JoeKuoD7Init, + dim1581JoeKuoD7Init, + dim1582JoeKuoD7Init, + dim1583JoeKuoD7Init, + dim1584JoeKuoD7Init, + dim1585JoeKuoD7Init, + dim1586JoeKuoD7Init, + dim1587JoeKuoD7Init, + dim1588JoeKuoD7Init, + dim1589JoeKuoD7Init, + dim1590JoeKuoD7Init, + dim1591JoeKuoD7Init, + dim1592JoeKuoD7Init, + dim1593JoeKuoD7Init, + dim1594JoeKuoD7Init, + dim1595JoeKuoD7Init, + dim1596JoeKuoD7Init, + dim1597JoeKuoD7Init, + dim1598JoeKuoD7Init, + dim1599JoeKuoD7Init, + dim1600JoeKuoD7Init, + dim1601JoeKuoD7Init, + dim1602JoeKuoD7Init, + dim1603JoeKuoD7Init, + dim1604JoeKuoD7Init, + dim1605JoeKuoD7Init, + dim1606JoeKuoD7Init, + dim1607JoeKuoD7Init, + dim1608JoeKuoD7Init, + dim1609JoeKuoD7Init, + dim1610JoeKuoD7Init, + dim1611JoeKuoD7Init, + dim1612JoeKuoD7Init, + dim1613JoeKuoD7Init, + dim1614JoeKuoD7Init, + dim1615JoeKuoD7Init, + dim1616JoeKuoD7Init, + dim1617JoeKuoD7Init, + dim1618JoeKuoD7Init, + dim1619JoeKuoD7Init, + dim1620JoeKuoD7Init, + dim1621JoeKuoD7Init, + dim1622JoeKuoD7Init, + dim1623JoeKuoD7Init, + dim1624JoeKuoD7Init, + dim1625JoeKuoD7Init, + dim1626JoeKuoD7Init, + dim1627JoeKuoD7Init, + dim1628JoeKuoD7Init, + dim1629JoeKuoD7Init, + dim1630JoeKuoD7Init, + dim1631JoeKuoD7Init, + dim1632JoeKuoD7Init, + dim1633JoeKuoD7Init, + dim1634JoeKuoD7Init, + dim1635JoeKuoD7Init, + dim1636JoeKuoD7Init, + dim1637JoeKuoD7Init, + dim1638JoeKuoD7Init, + dim1639JoeKuoD7Init, + dim1640JoeKuoD7Init, + dim1641JoeKuoD7Init, + dim1642JoeKuoD7Init, + dim1643JoeKuoD7Init, + dim1644JoeKuoD7Init, + dim1645JoeKuoD7Init, + dim1646JoeKuoD7Init, + dim1647JoeKuoD7Init, + dim1648JoeKuoD7Init, + dim1649JoeKuoD7Init, + dim1650JoeKuoD7Init, + dim1651JoeKuoD7Init, + dim1652JoeKuoD7Init, + dim1653JoeKuoD7Init, + dim1654JoeKuoD7Init, + dim1655JoeKuoD7Init, + dim1656JoeKuoD7Init, + dim1657JoeKuoD7Init, + dim1658JoeKuoD7Init, + dim1659JoeKuoD7Init, + dim1660JoeKuoD7Init, + dim1661JoeKuoD7Init, + dim1662JoeKuoD7Init, + dim1663JoeKuoD7Init, + dim1664JoeKuoD7Init, + dim1665JoeKuoD7Init, + dim1666JoeKuoD7Init, + dim1667JoeKuoD7Init, + dim1668JoeKuoD7Init, + dim1669JoeKuoD7Init, + dim1670JoeKuoD7Init, + dim1671JoeKuoD7Init, + dim1672JoeKuoD7Init, + dim1673JoeKuoD7Init, + dim1674JoeKuoD7Init, + dim1675JoeKuoD7Init, + dim1676JoeKuoD7Init, + dim1677JoeKuoD7Init, + dim1678JoeKuoD7Init, + dim1679JoeKuoD7Init, + dim1680JoeKuoD7Init, + dim1681JoeKuoD7Init, + dim1682JoeKuoD7Init, + dim1683JoeKuoD7Init, + dim1684JoeKuoD7Init, + dim1685JoeKuoD7Init, + dim1686JoeKuoD7Init, + dim1687JoeKuoD7Init, + dim1688JoeKuoD7Init, + dim1689JoeKuoD7Init, + dim1690JoeKuoD7Init, + dim1691JoeKuoD7Init, + dim1692JoeKuoD7Init, + dim1693JoeKuoD7Init, + dim1694JoeKuoD7Init, + dim1695JoeKuoD7Init, + dim1696JoeKuoD7Init, + dim1697JoeKuoD7Init, + dim1698JoeKuoD7Init, + dim1699JoeKuoD7Init, + dim1700JoeKuoD7Init, + dim1701JoeKuoD7Init, + dim1702JoeKuoD7Init, + dim1703JoeKuoD7Init, + dim1704JoeKuoD7Init, + dim1705JoeKuoD7Init, + dim1706JoeKuoD7Init, + dim1707JoeKuoD7Init, + dim1708JoeKuoD7Init, + dim1709JoeKuoD7Init, + dim1710JoeKuoD7Init, + dim1711JoeKuoD7Init, + dim1712JoeKuoD7Init, + dim1713JoeKuoD7Init, + dim1714JoeKuoD7Init, + dim1715JoeKuoD7Init, + dim1716JoeKuoD7Init, + dim1717JoeKuoD7Init, + dim1718JoeKuoD7Init, + dim1719JoeKuoD7Init, + dim1720JoeKuoD7Init, + dim1721JoeKuoD7Init, + dim1722JoeKuoD7Init, + dim1723JoeKuoD7Init, + dim1724JoeKuoD7Init, + dim1725JoeKuoD7Init, + dim1726JoeKuoD7Init, + dim1727JoeKuoD7Init, + dim1728JoeKuoD7Init, + dim1729JoeKuoD7Init, + dim1730JoeKuoD7Init, + dim1731JoeKuoD7Init, + dim1732JoeKuoD7Init, + dim1733JoeKuoD7Init, + dim1734JoeKuoD7Init, + dim1735JoeKuoD7Init, + dim1736JoeKuoD7Init, + dim1737JoeKuoD7Init, + dim1738JoeKuoD7Init, + dim1739JoeKuoD7Init, + dim1740JoeKuoD7Init, + dim1741JoeKuoD7Init, + dim1742JoeKuoD7Init, + dim1743JoeKuoD7Init, + dim1744JoeKuoD7Init, + dim1745JoeKuoD7Init, + dim1746JoeKuoD7Init, + dim1747JoeKuoD7Init, + dim1748JoeKuoD7Init, + dim1749JoeKuoD7Init, + dim1750JoeKuoD7Init, + dim1751JoeKuoD7Init, + dim1752JoeKuoD7Init, + dim1753JoeKuoD7Init, + dim1754JoeKuoD7Init, + dim1755JoeKuoD7Init, + dim1756JoeKuoD7Init, + dim1757JoeKuoD7Init, + dim1758JoeKuoD7Init, + dim1759JoeKuoD7Init, + dim1760JoeKuoD7Init, + dim1761JoeKuoD7Init, + dim1762JoeKuoD7Init, + dim1763JoeKuoD7Init, + dim1764JoeKuoD7Init, + dim1765JoeKuoD7Init, + dim1766JoeKuoD7Init, + dim1767JoeKuoD7Init, + dim1768JoeKuoD7Init, + dim1769JoeKuoD7Init, + dim1770JoeKuoD7Init, + dim1771JoeKuoD7Init, + dim1772JoeKuoD7Init, + dim1773JoeKuoD7Init, + dim1774JoeKuoD7Init, + dim1775JoeKuoD7Init, + dim1776JoeKuoD7Init, + dim1777JoeKuoD7Init, + dim1778JoeKuoD7Init, + dim1779JoeKuoD7Init, + dim1780JoeKuoD7Init, + dim1781JoeKuoD7Init, + dim1782JoeKuoD7Init, + dim1783JoeKuoD7Init, + dim1784JoeKuoD7Init, + dim1785JoeKuoD7Init, + dim1786JoeKuoD7Init, + dim1787JoeKuoD7Init, + dim1788JoeKuoD7Init, + dim1789JoeKuoD7Init, + dim1790JoeKuoD7Init, + dim1791JoeKuoD7Init, + dim1792JoeKuoD7Init, + dim1793JoeKuoD7Init, + dim1794JoeKuoD7Init, + dim1795JoeKuoD7Init, + dim1796JoeKuoD7Init, + dim1797JoeKuoD7Init, + dim1798JoeKuoD7Init, + dim1799JoeKuoD7Init, + dim1800JoeKuoD7Init, + dim1801JoeKuoD7Init, + dim1802JoeKuoD7Init, + dim1803JoeKuoD7Init, + dim1804JoeKuoD7Init, + dim1805JoeKuoD7Init, + dim1806JoeKuoD7Init, + dim1807JoeKuoD7Init, + dim1808JoeKuoD7Init, + dim1809JoeKuoD7Init, + dim1810JoeKuoD7Init, + dim1811JoeKuoD7Init, + dim1812JoeKuoD7Init, + dim1813JoeKuoD7Init, + dim1814JoeKuoD7Init, + dim1815JoeKuoD7Init, + dim1816JoeKuoD7Init, + dim1817JoeKuoD7Init, + dim1818JoeKuoD7Init, + dim1819JoeKuoD7Init, + dim1820JoeKuoD7Init, + dim1821JoeKuoD7Init, + dim1822JoeKuoD7Init, + dim1823JoeKuoD7Init, + dim1824JoeKuoD7Init, + dim1825JoeKuoD7Init, + dim1826JoeKuoD7Init, + dim1827JoeKuoD7Init, + dim1828JoeKuoD7Init, + dim1829JoeKuoD7Init, + dim1830JoeKuoD7Init, + dim1831JoeKuoD7Init, + dim1832JoeKuoD7Init, + dim1833JoeKuoD7Init, + dim1834JoeKuoD7Init, + dim1835JoeKuoD7Init, + dim1836JoeKuoD7Init, + dim1837JoeKuoD7Init, + dim1838JoeKuoD7Init, + dim1839JoeKuoD7Init, + dim1840JoeKuoD7Init, + dim1841JoeKuoD7Init, + dim1842JoeKuoD7Init, + dim1843JoeKuoD7Init, + dim1844JoeKuoD7Init, + dim1845JoeKuoD7Init, + dim1846JoeKuoD7Init, + dim1847JoeKuoD7Init, + dim1848JoeKuoD7Init, + dim1849JoeKuoD7Init, + dim1850JoeKuoD7Init, + dim1851JoeKuoD7Init, + dim1852JoeKuoD7Init, + dim1853JoeKuoD7Init, + dim1854JoeKuoD7Init, + dim1855JoeKuoD7Init, + dim1856JoeKuoD7Init, + dim1857JoeKuoD7Init, + dim1858JoeKuoD7Init, + dim1859JoeKuoD7Init, + dim1860JoeKuoD7Init, + dim1861JoeKuoD7Init, + dim1862JoeKuoD7Init, + dim1863JoeKuoD7Init, + dim1864JoeKuoD7Init, + dim1865JoeKuoD7Init, + dim1866JoeKuoD7Init, + dim1867JoeKuoD7Init, + dim1868JoeKuoD7Init, + dim1869JoeKuoD7Init, + dim1870JoeKuoD7Init, + dim1871JoeKuoD7Init, + dim1872JoeKuoD7Init, + dim1873JoeKuoD7Init, + dim1874JoeKuoD7Init, + dim1875JoeKuoD7Init, + dim1876JoeKuoD7Init, + dim1877JoeKuoD7Init, + dim1878JoeKuoD7Init, + dim1879JoeKuoD7Init, + dim1880JoeKuoD7Init, + dim1881JoeKuoD7Init, + dim1882JoeKuoD7Init, + dim1883JoeKuoD7Init, + dim1884JoeKuoD7Init, + dim1885JoeKuoD7Init, + dim1886JoeKuoD7Init, + dim1887JoeKuoD7Init, + dim1888JoeKuoD7Init, + dim1889JoeKuoD7Init, + dim1890JoeKuoD7Init, + dim1891JoeKuoD7Init, + dim1892JoeKuoD7Init, + dim1893JoeKuoD7Init, + dim1894JoeKuoD7Init, + dim1895JoeKuoD7Init, + dim1896JoeKuoD7Init, + dim1897JoeKuoD7Init, + dim1898JoeKuoD7Init, + dim1899JoeKuoD7Init + }; + + static ulong[] dim1JoeKuoD5Init = { 1, 0 }; + static ulong[] dim2JoeKuoD5Init = { 1, 3, 0 }; + static ulong[] dim3JoeKuoD5Init = { 1, 3, 1, 0 }; + static ulong[] dim4JoeKuoD5Init = { 1, 1, 1, 0 }; + static ulong[] dim5JoeKuoD5Init = { 1, 1, 3, 3, 0 }; + static ulong[] dim6JoeKuoD5Init = { 1, 3, 5, 13, 0 }; + static ulong[] dim7JoeKuoD5Init = { 1, 1, 5, 5, 17, 0 }; + static ulong[] dim8JoeKuoD5Init = { 1, 1, 5, 5, 5, 0 }; + static ulong[] dim9JoeKuoD5Init = { 1, 1, 7, 11, 19, 0 }; + static ulong[] dim10JoeKuoD5Init = { 1, 1, 5, 1, 1, 0 }; + static ulong[] dim11JoeKuoD5Init = { 1, 3, 7, 1, 19, 0 }; + static ulong[] dim12JoeKuoD5Init = { 1, 3, 3, 5, 7, 0 }; + static ulong[] dim13JoeKuoD5Init = { 1, 3, 3, 13, 9, 53, 0 }; + static ulong[] dim14JoeKuoD5Init = { 1, 1, 5, 11, 1, 1, 0 }; + static ulong[] dim15JoeKuoD5Init = { 1, 1, 3, 7, 21, 51, 0 }; + static ulong[] dim16JoeKuoD5Init = { 1, 1, 1, 15, 1, 5, 0 }; + static ulong[] dim17JoeKuoD5Init = { 1, 3, 1, 9, 9, 1, 0 }; + static ulong[] dim18JoeKuoD5Init = { 1, 1, 5, 5, 17, 61, 0 }; + static ulong[] dim19JoeKuoD5Init = { 1, 3, 1, 15, 29, 57, 87, 0 }; + static ulong[] dim20JoeKuoD5Init = { 1, 3, 5, 15, 3, 11, 17, 0 }; + static ulong[] dim21JoeKuoD5Init = { 1, 3, 3, 7, 5, 17, 65, 0 }; + static ulong[] dim22JoeKuoD5Init = { 1, 3, 5, 1, 25, 29, 49, 0 }; + static ulong[] dim23JoeKuoD5Init = { 1, 1, 3, 7, 15, 39, 119, 0 }; + static ulong[] dim24JoeKuoD5Init = { 1, 3, 3, 5, 19, 51, 61, 0 }; + static ulong[] dim25JoeKuoD5Init = { 1, 1, 5, 15, 11, 47, 15, 0 }; + static ulong[] dim26JoeKuoD5Init = { 1, 1, 7, 3, 29, 51, 51, 0 }; + static ulong[] dim27JoeKuoD5Init = { 1, 1, 3, 15, 19, 17, 13, 0 }; + static ulong[] dim28JoeKuoD5Init = { 1, 3, 7, 3, 17, 9, 93, 0 }; + static ulong[] dim29JoeKuoD5Init = { 1, 3, 7, 5, 7, 29, 111, 0 }; + static ulong[] dim30JoeKuoD5Init = { 1, 1, 7, 9, 25, 19, 105, 0 }; + static ulong[] dim31JoeKuoD5Init = { 1, 1, 1, 11, 21, 35, 107, 0 }; + static ulong[] dim32JoeKuoD5Init = { 1, 1, 5, 11, 19, 53, 25, 0 }; + static ulong[] dim33JoeKuoD5Init = { 1, 3, 1, 3, 27, 29, 31, 0 }; + static ulong[] dim34JoeKuoD5Init = { 1, 1, 5, 13, 27, 19, 61, 0 }; + static ulong[] dim35JoeKuoD5Init = { 1, 3, 1, 3, 25, 33, 105, 0 }; + static ulong[] dim36JoeKuoD5Init = { 1, 3, 7, 11, 27, 55, 1, 0 }; + static ulong[] dim37JoeKuoD5Init = { 1, 1, 7, 1, 9, 45, 97, 63, 0 }; + static ulong[] dim38JoeKuoD5Init = { 1, 1, 7, 9, 3, 17, 85, 213, 0 }; + static ulong[] dim39JoeKuoD5Init = { 1, 1, 1, 3, 31, 35, 93, 35, 0 }; + static ulong[] dim40JoeKuoD5Init = { 1, 3, 5, 9, 1, 63, 117, 35, 0 }; + static ulong[] dim41JoeKuoD5Init = { 1, 3, 1, 9, 21, 3, 53, 29, 0 }; + static ulong[] dim42JoeKuoD5Init = { 1, 3, 1, 9, 29, 33, 43, 181, 0 }; + static ulong[] dim43JoeKuoD5Init = { 1, 3, 7, 3, 21, 45, 121, 141, 0 }; + static ulong[] dim44JoeKuoD5Init = { 1, 1, 1, 13, 5, 49, 45, 77, 0 }; + static ulong[] dim45JoeKuoD5Init = { 1, 1, 3, 3, 1, 47, 37, 151, 0 }; + static ulong[] dim46JoeKuoD5Init = { 1, 3, 7, 5, 9, 51, 61, 95, 0 }; + static ulong[] dim47JoeKuoD5Init = { 1, 1, 1, 7, 31, 23, 81, 105, 0 }; + static ulong[] dim48JoeKuoD5Init = { 1, 3, 5, 15, 15, 9, 115, 55, 0 }; + static ulong[] dim49JoeKuoD5Init = { 1, 3, 3, 13, 15, 1, 87, 11, 0 }; + static ulong[] dim50JoeKuoD5Init = { 1, 3, 5, 1, 5, 9, 29, 241, 0 }; + static ulong[] dim51JoeKuoD5Init = { 1, 1, 1, 9, 19, 5, 115, 191, 0 }; + static ulong[] dim52JoeKuoD5Init = { 1, 1, 1, 15, 1, 57, 107, 49, 0 }; + static ulong[] dim53JoeKuoD5Init = { 1, 1, 7, 7, 23, 21, 71, 187, 207, 0 }; + static ulong[] dim54JoeKuoD5Init = { 1, 3, 3, 5, 11, 35, 101, 7, 501, 0 }; + static ulong[] dim55JoeKuoD5Init = { 1, 3, 5, 15, 29, 5, 61, 205, 301, 0 }; + static ulong[] dim56JoeKuoD5Init = { 1, 1, 7, 13, 7, 39, 127, 243, 307, 0 }; + static ulong[] dim57JoeKuoD5Init = { 1, 3, 7, 13, 29, 9, 93, 187, 429, 0 }; + static ulong[] dim58JoeKuoD5Init = { 1, 3, 3, 11, 15, 35, 85, 159, 223, 0 }; + static ulong[] dim59JoeKuoD5Init = { 1, 1, 3, 1, 13, 3, 111, 17, 411, 0 }; + static ulong[] dim60JoeKuoD5Init = { 1, 1, 1, 7, 31, 21, 103, 175, 97, 0 }; + static ulong[] dim61JoeKuoD5Init = { 1, 1, 1, 15, 11, 21, 63, 45, 29, 0 }; + static ulong[] dim62JoeKuoD5Init = { 1, 3, 5, 3, 13, 45, 53, 191, 455, 0 }; + static ulong[] dim63JoeKuoD5Init = { 1, 3, 3, 13, 11, 37, 65, 45, 371, 0 }; + static ulong[] dim64JoeKuoD5Init = { 1, 1, 1, 15, 23, 9, 123, 97, 497, 0 }; + static ulong[] dim65JoeKuoD5Init = { 1, 1, 7, 7, 5, 13, 33, 169, 411, 0 }; + static ulong[] dim66JoeKuoD5Init = { 1, 1, 3, 13, 29, 61, 67, 1, 167, 0 }; + static ulong[] dim67JoeKuoD5Init = { 1, 1, 7, 3, 11, 21, 25, 87, 507, 0 }; + static ulong[] dim68JoeKuoD5Init = { 1, 3, 1, 9, 31, 37, 3, 89, 113, 0 }; + static ulong[] dim69JoeKuoD5Init = { 1, 1, 5, 11, 5, 11, 83, 85, 421, 0 }; + static ulong[] dim70JoeKuoD5Init = { 1, 3, 5, 7, 23, 9, 111, 135, 337, 0 }; + static ulong[] dim71JoeKuoD5Init = { 1, 3, 5, 15, 3, 39, 81, 249, 363, 0 }; + static ulong[] dim72JoeKuoD5Init = { 1, 1, 7, 15, 9, 49, 79, 103, 19, 0 }; + static ulong[] dim73JoeKuoD5Init = { 1, 3, 1, 1, 17, 31, 45, 205, 381, 0 }; + static ulong[] dim74JoeKuoD5Init = { 1, 1, 1, 1, 11, 45, 89, 1, 365, 0 }; + static ulong[] dim75JoeKuoD5Init = { 1, 1, 1, 15, 7, 63, 55, 185, 373, 0 }; + static ulong[] dim76JoeKuoD5Init = { 1, 1, 1, 3, 17, 19, 23, 7, 265, 0 }; + static ulong[] dim77JoeKuoD5Init = { 1, 1, 3, 15, 13, 31, 53, 235, 309, 0 }; + static ulong[] dim78JoeKuoD5Init = { 1, 3, 1, 5, 1, 63, 73, 155, 33, 0 }; + static ulong[] dim79JoeKuoD5Init = { 1, 1, 1, 15, 19, 57, 21, 45, 203, 0 }; + static ulong[] dim80JoeKuoD5Init = { 1, 3, 5, 9, 13, 27, 55, 215, 181, 0 }; + static ulong[] dim81JoeKuoD5Init = { 1, 1, 7, 3, 11, 39, 55, 219, 401, 0 }; + static ulong[] dim82JoeKuoD5Init = { 1, 1, 1, 7, 9, 13, 3, 181, 395, 0 }; + static ulong[] dim83JoeKuoD5Init = { 1, 3, 1, 15, 13, 19, 23, 145, 97, 0 }; + static ulong[] dim84JoeKuoD5Init = { 1, 1, 1, 15, 23, 15, 55, 3, 243, 0 }; + static ulong[] dim85JoeKuoD5Init = { 1, 1, 3, 15, 15, 5, 115, 169, 415, 0 }; + static ulong[] dim86JoeKuoD5Init = { 1, 1, 7, 15, 31, 15, 119, 89, 37, 0 }; + static ulong[] dim87JoeKuoD5Init = { 1, 1, 5, 3, 25, 23, 23, 133, 467, 0 }; + static ulong[] dim88JoeKuoD5Init = { 1, 3, 5, 15, 11, 7, 73, 209, 331, 0 }; + static ulong[] dim89JoeKuoD5Init = { 1, 3, 7, 11, 29, 51, 119, 105, 63, 0 }; + static ulong[] dim90JoeKuoD5Init = { 1, 1, 5, 9, 19, 21, 53, 211, 231, 0 }; + static ulong[] dim91JoeKuoD5Init = { 1, 3, 5, 1, 7, 23, 27, 67, 445, 0 }; + static ulong[] dim92JoeKuoD5Init = { 1, 1, 5, 15, 21, 53, 117, 229, 13, 0 }; + static ulong[] dim93JoeKuoD5Init = { 1, 3, 5, 11, 19, 55, 53, 13, 349, 0 }; + static ulong[] dim94JoeKuoD5Init = { 1, 3, 1, 9, 19, 25, 79, 55, 355, 0 }; + static ulong[] dim95JoeKuoD5Init = { 1, 3, 3, 5, 31, 27, 105, 63, 21, 0 }; + static ulong[] dim96JoeKuoD5Init = { 1, 3, 3, 15, 13, 37, 39, 13, 459, 0 }; + static ulong[] dim97JoeKuoD5Init = { 1, 1, 1, 7, 25, 61, 93, 195, 441, 0 }; + static ulong[] dim98JoeKuoD5Init = { 1, 3, 3, 3, 7, 35, 55, 103, 159, 0 }; + static ulong[] dim99JoeKuoD5Init = { 1, 1, 7, 11, 7, 33, 49, 113, 331, 0 }; + static ulong[] dim100JoeKuoD5Init = { 1, 3, 1, 1, 1, 31, 35, 63, 465, 0 }; + static ulong[] dim101JoeKuoD5Init = { 1, 3, 5, 1, 13, 43, 83, 177, 461, 747, 0 }; + static ulong[] dim102JoeKuoD5Init = { 1, 3, 7, 3, 21, 5, 19, 135, 483, 181, 0 }; + static ulong[] dim103JoeKuoD5Init = { 1, 3, 1, 9, 25, 3, 37, 147, 483, 743, 0 }; + static ulong[] dim104JoeKuoD5Init = { 1, 1, 5, 3, 1, 1, 101, 163, 165, 957, 0 }; + static ulong[] dim105JoeKuoD5Init = { 1, 3, 5, 1, 15, 41, 117, 7, 71, 357, 0 }; + static ulong[] dim106JoeKuoD5Init = { 1, 3, 5, 9, 27, 11, 55, 5, 11, 863, 0 }; + static ulong[] dim107JoeKuoD5Init = { 1, 1, 1, 1, 27, 43, 51, 211, 265, 403, 0 }; + static ulong[] dim108JoeKuoD5Init = { 1, 1, 7, 3, 31, 35, 61, 43, 223, 441, 0 }; + static ulong[] dim109JoeKuoD5Init = { 1, 3, 1, 7, 19, 61, 59, 63, 401, 767, 0 }; + static ulong[] dim110JoeKuoD5Init = { 1, 3, 1, 9, 23, 39, 83, 249, 129, 843, 0 }; + static ulong[] dim111JoeKuoD5Init = { 1, 3, 7, 13, 1, 49, 61, 115, 289, 85, 0 }; + static ulong[] dim112JoeKuoD5Init = { 1, 1, 5, 13, 7, 17, 35, 95, 235, 49, 0 }; + static ulong[] dim113JoeKuoD5Init = { 1, 3, 3, 11, 9, 9, 91, 141, 305, 955, 0 }; + static ulong[] dim114JoeKuoD5Init = { 1, 3, 7, 11, 17, 3, 77, 95, 507, 627, 0 }; + static ulong[] dim115JoeKuoD5Init = { 1, 3, 7, 1, 31, 43, 31, 217, 67, 853, 0 }; + static ulong[] dim116JoeKuoD5Init = { 1, 1, 7, 15, 17, 33, 31, 91, 465, 209, 0 }; + static ulong[] dim117JoeKuoD5Init = { 1, 1, 7, 7, 31, 41, 101, 95, 431, 203, 0 }; + static ulong[] dim118JoeKuoD5Init = { 1, 3, 7, 1, 23, 45, 123, 111, 457, 655, 0 }; + static ulong[] dim119JoeKuoD5Init = { 1, 3, 3, 5, 9, 27, 37, 195, 11, 99, 0 }; + static ulong[] dim120JoeKuoD5Init = { 1, 1, 3, 9, 7, 39, 81, 171, 97, 775, 0 }; + static ulong[] dim121JoeKuoD5Init = { 1, 1, 1, 3, 3, 27, 93, 149, 321, 537, 0 }; + static ulong[] dim122JoeKuoD5Init = { 1, 3, 1, 3, 13, 3, 59, 137, 505, 395, 0 }; + static ulong[] dim123JoeKuoD5Init = { 1, 1, 1, 11, 15, 53, 77, 235, 439, 829, 0 }; + static ulong[] dim124JoeKuoD5Init = { 1, 3, 3, 1, 25, 61, 65, 53, 207, 891, 0 }; + static ulong[] dim125JoeKuoD5Init = { 1, 3, 3, 15, 29, 39, 67, 203, 495, 795, 0 }; + static ulong[] dim126JoeKuoD5Init = { 1, 3, 7, 1, 15, 17, 119, 83, 411, 1015, 0 }; + static ulong[] dim127JoeKuoD5Init = { 1, 1, 7, 1, 13, 37, 69, 147, 141, 229, 0 }; + static ulong[] dim128JoeKuoD5Init = { 1, 3, 5, 1, 11, 31, 73, 99, 133, 45, 0 }; + static ulong[] dim129JoeKuoD5Init = { 1, 1, 5, 11, 31, 49, 51, 45, 27, 415, 0 }; + static ulong[] dim130JoeKuoD5Init = { 1, 3, 1, 11, 23, 19, 85, 17, 41, 625, 0 }; + static ulong[] dim131JoeKuoD5Init = { 1, 3, 5, 9, 3, 37, 9, 57, 59, 383, 0 }; + static ulong[] dim132JoeKuoD5Init = { 1, 3, 7, 3, 19, 53, 11, 215, 391, 51, 0 }; + static ulong[] dim133JoeKuoD5Init = { 1, 3, 7, 15, 17, 1, 53, 89, 291, 91, 0 }; + static ulong[] dim134JoeKuoD5Init = { 1, 3, 5, 1, 5, 33, 69, 29, 281, 13, 0 }; + static ulong[] dim135JoeKuoD5Init = { 1, 1, 3, 15, 21, 61, 61, 69, 395, 785, 0 }; + static ulong[] dim136JoeKuoD5Init = { 1, 1, 7, 7, 25, 51, 27, 11, 375, 865, 0 }; + static ulong[] dim137JoeKuoD5Init = { 1, 1, 3, 1, 11, 47, 45, 85, 507, 11, 0 }; + static ulong[] dim138JoeKuoD5Init = { 1, 3, 5, 5, 17, 53, 101, 57, 213, 795, 0 }; + static ulong[] dim139JoeKuoD5Init = { 1, 1, 7, 7, 15, 19, 117, 213, 397, 343, 0 }; + static ulong[] dim140JoeKuoD5Init = { 1, 3, 3, 7, 9, 19, 27, 23, 205, 707, 0 }; + static ulong[] dim141JoeKuoD5Init = { 1, 3, 1, 13, 11, 51, 1, 3, 63, 483, 0 }; + static ulong[] dim142JoeKuoD5Init = { 1, 1, 7, 13, 27, 49, 97, 247, 273, 785, 0 }; + static ulong[] dim143JoeKuoD5Init = { 1, 3, 1, 15, 31, 3, 43, 199, 81, 317, 0 }; + static ulong[] dim144JoeKuoD5Init = { 1, 3, 5, 15, 17, 3, 101, 13, 131, 631, 0 }; + static ulong[] dim145JoeKuoD5Init = { 1, 3, 5, 1, 25, 23, 17, 145, 247, 889, 0 }; + static ulong[] dim146JoeKuoD5Init = { 1, 1, 7, 7, 17, 5, 11, 133, 19, 507, 0 }; + static ulong[] dim147JoeKuoD5Init = { 1, 3, 1, 7, 31, 53, 39, 107, 183, 335, 0 }; + static ulong[] dim148JoeKuoD5Init = { 1, 3, 7, 15, 3, 19, 39, 155, 477, 833, 0 }; + static ulong[] dim149JoeKuoD5Init = { 1, 1, 1, 9, 31, 7, 5, 5, 399, 831, 0 }; + static ulong[] dim150JoeKuoD5Init = { 1, 1, 3, 1, 19, 37, 89, 243, 131, 901, 0 }; + static ulong[] dim151JoeKuoD5Init = { 1, 1, 3, 13, 23, 3, 127, 213, 97, 325, 0 }; + static ulong[] dim152JoeKuoD5Init = { 1, 1, 7, 9, 23, 27, 7, 161, 307, 451, 0 }; + static ulong[] dim153JoeKuoD5Init = { 1, 1, 5, 1, 5, 25, 23, 103, 59, 431, 0 }; + static ulong[] dim154JoeKuoD5Init = { 1, 1, 3, 7, 3, 43, 121, 117, 33, 231, 0 }; + static ulong[] dim155JoeKuoD5Init = { 1, 3, 7, 7, 11, 61, 73, 231, 225, 97, 0 }; + static ulong[] dim156JoeKuoD5Init = { 1, 1, 5, 11, 1, 9, 61, 3, 407, 425, 0 }; + static ulong[] dim157JoeKuoD5Init = { 1, 3, 3, 7, 1, 25, 95, 161, 387, 379, 0 }; + static ulong[] dim158JoeKuoD5Init = { 1, 3, 1, 1, 15, 53, 55, 107, 425, 629, 0 }; + static ulong[] dim159JoeKuoD5Init = { 1, 3, 7, 11, 31, 59, 97, 99, 339, 417, 0 }; + static ulong[] dim160JoeKuoD5Init = { 1, 3, 1, 9, 9, 5, 7, 157, 401, 155, 0 }; + static ulong[] dim161JoeKuoD5Init = { 1, 3, 1, 7, 31, 15, 37, 253, 93, 149, 1255, 0 }; + static ulong[] dim162JoeKuoD5Init = { 1, 1, 1, 9, 11, 61, 65, 71, 53, 929, 1153, 0 }; + static ulong[] dim163JoeKuoD5Init = { 1, 1, 7, 15, 13, 25, 93, 55, 55, 923, 601, 0 }; + static ulong[] dim164JoeKuoD5Init = { 1, 1, 7, 7, 21, 43, 71, 115, 253, 953, 1455, 0 }; + static ulong[] dim165JoeKuoD5Init = { 1, 3, 5, 7, 3, 31, 115, 213, 39, 589, 1029, 0 }; + static ulong[] dim166JoeKuoD5Init = { 1, 3, 5, 1, 7, 59, 31, 87, 233, 75, 365, 0 }; + static ulong[] dim167JoeKuoD5Init = { 1, 1, 1, 15, 13, 27, 55, 117, 327, 465, 1735, 0 }; + static ulong[] dim168JoeKuoD5Init = { 1, 3, 5, 9, 25, 9, 125, 247, 81, 437, 483, 0 }; + static ulong[] dim169JoeKuoD5Init = { 1, 3, 5, 15, 27, 39, 27, 57, 45, 263, 281, 0 }; + static ulong[] dim170JoeKuoD5Init = { 1, 3, 1, 5, 29, 5, 73, 231, 97, 773, 1349, 0 }; + static ulong[] dim171JoeKuoD5Init = { 1, 3, 5, 5, 25, 27, 81, 87, 91, 169, 235, 0 }; + static ulong[] dim172JoeKuoD5Init = { 1, 3, 1, 11, 19, 61, 17, 175, 253, 673, 175, 0 }; + static ulong[] dim173JoeKuoD5Init = { 1, 1, 7, 7, 17, 43, 65, 245, 125, 137, 1475, 0 }; + static ulong[] dim174JoeKuoD5Init = { 1, 1, 7, 5, 15, 57, 39, 151, 197, 529, 393, 0 }; + static ulong[] dim175JoeKuoD5Init = { 1, 3, 3, 3, 29, 41, 93, 47, 375, 729, 709, 0 }; + static ulong[] dim176JoeKuoD5Init = { 1, 1, 7, 9, 13, 35, 49, 197, 107, 381, 1531, 0 }; + static ulong[] dim177JoeKuoD5Init = { 1, 1, 5, 9, 15, 35, 105, 105, 259, 201, 317, 0 }; + static ulong[] dim178JoeKuoD5Init = { 1, 1, 7, 15, 13, 23, 89, 203, 335, 1003, 107, 0 }; + static ulong[] dim179JoeKuoD5Init = { 1, 3, 7, 15, 25, 25, 7, 145, 213, 845, 949, 0 }; + static ulong[] dim180JoeKuoD5Init = { 1, 1, 5, 1, 23, 11, 101, 59, 57, 261, 1627, 0 }; + static ulong[] dim181JoeKuoD5Init = { 1, 3, 5, 11, 23, 63, 43, 137, 49, 249, 1369, 0 }; + static ulong[] dim182JoeKuoD5Init = { 1, 1, 7, 13, 25, 3, 81, 157, 511, 725, 2027, 0 }; + static ulong[] dim183JoeKuoD5Init = { 1, 1, 7, 7, 5, 37, 33, 7, 287, 307, 147, 0 }; + static ulong[] dim184JoeKuoD5Init = { 1, 3, 7, 5, 27, 19, 93, 173, 145, 821, 139, 0 }; + static ulong[] dim185JoeKuoD5Init = { 1, 1, 1, 15, 23, 61, 123, 85, 375, 699, 229, 0 }; + static ulong[] dim186JoeKuoD5Init = { 1, 1, 3, 3, 25, 21, 127, 53, 247, 1005, 831, 0 }; + static ulong[] dim187JoeKuoD5Init = { 1, 1, 5, 7, 25, 39, 27, 247, 319, 659, 1453, 0 }; + static ulong[] dim188JoeKuoD5Init = { 1, 1, 3, 11, 31, 45, 67, 195, 11, 481, 83, 0 }; + static ulong[] dim189JoeKuoD5Init = { 1, 1, 5, 13, 27, 61, 5, 173, 353, 733, 1189, 0 }; + static ulong[] dim190JoeKuoD5Init = { 1, 3, 7, 7, 23, 49, 119, 145, 285, 873, 641, 0 }; + static ulong[] dim191JoeKuoD5Init = { 1, 3, 3, 9, 1, 17, 119, 121, 203, 483, 1601, 0 }; + static ulong[] dim192JoeKuoD5Init = { 1, 3, 1, 11, 21, 35, 121, 11, 213, 93, 77, 0 }; + static ulong[] dim193JoeKuoD5Init = { 1, 1, 3, 7, 7, 5, 27, 153, 223, 831, 679, 0 }; + static ulong[] dim194JoeKuoD5Init = { 1, 3, 3, 5, 1, 39, 39, 233, 483, 667, 1367, 0 }; + static ulong[] dim195JoeKuoD5Init = { 1, 1, 3, 13, 19, 51, 21, 209, 381, 787, 1451, 0 }; + static ulong[] dim196JoeKuoD5Init = { 1, 1, 7, 3, 15, 9, 29, 225, 225, 389, 1075, 0 }; + static ulong[] dim197JoeKuoD5Init = { 1, 1, 3, 5, 13, 57, 55, 229, 279, 1019, 1491, 0 }; + static ulong[] dim198JoeKuoD5Init = { 1, 3, 3, 9, 19, 19, 35, 15, 335, 685, 1987, 0 }; + static ulong[] dim199JoeKuoD5Init = { 1, 3, 7, 11, 1, 5, 3, 29, 19, 363, 247, 0 }; + static ulong[] dim200JoeKuoD5Init = { 1, 1, 5, 11, 13, 17, 17, 253, 365, 397, 1643, 0 }; + static ulong[] dim201JoeKuoD5Init = { 1, 3, 3, 15, 25, 23, 81, 243, 343, 441, 1675, 0 }; + static ulong[] dim202JoeKuoD5Init = { 1, 3, 5, 11, 15, 51, 23, 213, 235, 997, 1205, 0 }; + static ulong[] dim203JoeKuoD5Init = { 1, 1, 7, 7, 5, 39, 99, 165, 331, 795, 803, 0 }; + static ulong[] dim204JoeKuoD5Init = { 1, 3, 7, 13, 31, 63, 109, 171, 151, 269, 581, 0 }; + static ulong[] dim205JoeKuoD5Init = { 1, 3, 1, 7, 25, 13, 41, 75, 411, 425, 267, 0 }; + static ulong[] dim206JoeKuoD5Init = { 1, 1, 3, 7, 1, 31, 49, 113, 473, 677, 395, 0 }; + static ulong[] dim207JoeKuoD5Init = { 1, 3, 3, 5, 23, 43, 111, 171, 489, 949, 1681, 0 }; + static ulong[] dim208JoeKuoD5Init = { 1, 3, 1, 5, 5, 37, 67, 23, 115, 909, 853, 0 }; + static ulong[] dim209JoeKuoD5Init = { 1, 1, 3, 3, 27, 35, 63, 45, 481, 571, 793, 0 }; + static ulong[] dim210JoeKuoD5Init = { 1, 1, 3, 15, 11, 45, 53, 225, 147, 935, 1189, 0 }; + static ulong[] dim211JoeKuoD5Init = { 1, 1, 1, 5, 15, 17, 77, 59, 169, 831, 163, 0 }; + static ulong[] dim212JoeKuoD5Init = { 1, 3, 7, 15, 7, 29, 85, 19, 313, 35, 401, 0 }; + static ulong[] dim213JoeKuoD5Init = { 1, 1, 3, 13, 3, 1, 45, 139, 17, 847, 1309, 0 }; + static ulong[] dim214JoeKuoD5Init = { 1, 1, 3, 3, 25, 1, 117, 185, 291, 251, 1049, 0 }; + static ulong[] dim215JoeKuoD5Init = { 1, 3, 3, 1, 27, 63, 33, 161, 181, 79, 667, 0 }; + static ulong[] dim216JoeKuoD5Init = { 1, 3, 1, 11, 9, 63, 91, 207, 329, 3, 1155, 0 }; + static ulong[] dim217JoeKuoD5Init = { 1, 1, 1, 5, 3, 59, 39, 37, 231, 993, 1147, 0 }; + static ulong[] dim218JoeKuoD5Init = { 1, 3, 1, 3, 7, 41, 85, 223, 407, 403, 573, 0 }; + static ulong[] dim219JoeKuoD5Init = { 1, 3, 7, 3, 15, 51, 1, 191, 123, 103, 1201, 0 }; + static ulong[] dim220JoeKuoD5Init = { 1, 1, 5, 3, 31, 9, 83, 231, 419, 109, 1455, 0 }; + static ulong[] dim221JoeKuoD5Init = { 1, 3, 3, 11, 13, 39, 89, 9, 237, 185, 1113, 0 }; + static ulong[] dim222JoeKuoD5Init = { 1, 1, 7, 9, 1, 43, 121, 241, 165, 263, 1205, 0 }; + static ulong[] dim223JoeKuoD5Init = { 1, 1, 1, 3, 21, 3, 61, 219, 49, 733, 25, 0 }; + static ulong[] dim224JoeKuoD5Init = { 1, 3, 1, 7, 31, 27, 121, 61, 447, 401, 529, 0 }; + static ulong[] dim225JoeKuoD5Init = { 1, 1, 7, 11, 27, 47, 85, 5, 305, 763, 1255, 0 }; + static ulong[] dim226JoeKuoD5Init = { 1, 1, 1, 9, 13, 41, 9, 51, 195, 103, 983, 0 }; + static ulong[] dim227JoeKuoD5Init = { 1, 1, 1, 15, 1, 27, 65, 91, 61, 591, 2039, 0 }; + static ulong[] dim228JoeKuoD5Init = { 1, 1, 1, 1, 15, 19, 107, 197, 121, 879, 771, 0 }; + static ulong[] dim229JoeKuoD5Init = { 1, 3, 7, 7, 19, 53, 9, 3, 67, 893, 1817, 0 }; + static ulong[] dim230JoeKuoD5Init = { 1, 3, 3, 9, 11, 63, 53, 247, 65, 681, 1721, 0 }; + static ulong[] dim231JoeKuoD5Init = { 1, 1, 3, 3, 25, 47, 91, 55, 471, 731, 939, 0 }; + static ulong[] dim232JoeKuoD5Init = { 1, 3, 5, 9, 7, 45, 121, 69, 423, 599, 2027, 0 }; + static ulong[] dim233JoeKuoD5Init = { 1, 1, 3, 11, 23, 7, 43, 179, 511, 571, 1707, 0 }; + static ulong[] dim234JoeKuoD5Init = { 1, 1, 7, 9, 17, 11, 69, 13, 303, 299, 653, 0 }; + static ulong[] dim235JoeKuoD5Init = { 1, 1, 1, 7, 7, 29, 69, 237, 237, 425, 1413, 0 }; + static ulong[] dim236JoeKuoD5Init = { 1, 3, 7, 3, 19, 31, 55, 55, 225, 943, 1027, 0 }; + static ulong[] dim237JoeKuoD5Init = { 1, 1, 5, 7, 25, 9, 9, 29, 485, 885, 1229, 0 }; + static ulong[] dim238JoeKuoD5Init = { 1, 3, 3, 9, 7, 11, 73, 151, 17, 669, 773, 0 }; + static ulong[] dim239JoeKuoD5Init = { 1, 1, 5, 13, 25, 13, 51, 53, 411, 555, 795, 0 }; + static ulong[] dim240JoeKuoD5Init = { 1, 3, 3, 9, 21, 33, 7, 113, 325, 593, 1647, 0 }; + static ulong[] dim241JoeKuoD5Init = { 1, 3, 5, 15, 3, 13, 83, 205, 153, 7, 1181, 0 }; + static ulong[] dim242JoeKuoD5Init = { 1, 1, 5, 5, 1, 55, 91, 17, 383, 453, 1749, 0 }; + static ulong[] dim243JoeKuoD5Init = { 1, 3, 3, 1, 5, 13, 91, 19, 241, 569, 291, 0 }; + static ulong[] dim244JoeKuoD5Init = { 1, 1, 1, 9, 13, 19, 109, 195, 17, 203, 473, 0 }; + static ulong[] dim245JoeKuoD5Init = { 1, 1, 1, 11, 17, 17, 43, 201, 297, 159, 685, 0 }; + static ulong[] dim246JoeKuoD5Init = { 1, 3, 5, 15, 15, 33, 91, 53, 337, 237, 1063, 0 }; + static ulong[] dim247JoeKuoD5Init = { 1, 3, 3, 9, 13, 15, 59, 115, 457, 169, 29, 0 }; + static ulong[] dim248JoeKuoD5Init = { 1, 1, 1, 7, 21, 51, 41, 49, 467, 171, 301, 0 }; + static ulong[] dim249JoeKuoD5Init = { 1, 3, 7, 5, 19, 57, 27, 57, 119, 183, 1519, 0 }; + static ulong[] dim250JoeKuoD5Init = { 1, 1, 1, 9, 19, 21, 117, 35, 43, 829, 1817, 0 }; + static ulong[] dim251JoeKuoD5Init = { 1, 3, 1, 7, 9, 27, 127, 233, 229, 467, 2033, 0 }; + static ulong[] dim252JoeKuoD5Init = { 1, 3, 1, 1, 7, 21, 113, 23, 15, 43, 375, 0 }; + static ulong[] dim253JoeKuoD5Init = { 1, 3, 7, 3, 11, 21, 13, 87, 57, 805, 1529, 0 }; + static ulong[] dim254JoeKuoD5Init = { 1, 3, 5, 15, 3, 39, 115, 179, 199, 907, 1487, 0 }; + static ulong[] dim255JoeKuoD5Init = { 1, 3, 3, 1, 17, 17, 83, 23, 421, 813, 29, 0 }; + static ulong[] dim256JoeKuoD5Init = { 1, 1, 3, 3, 29, 39, 81, 69, 339, 495, 281, 0 }; + static ulong[] dim257JoeKuoD5Init = { 1, 3, 3, 5, 27, 39, 9, 233, 19, 663, 57, 0 }; + static ulong[] dim258JoeKuoD5Init = { 1, 3, 3, 15, 17, 7, 17, 39, 299, 97, 1329, 0 }; + static ulong[] dim259JoeKuoD5Init = { 1, 3, 7, 7, 9, 27, 5, 245, 477, 591, 1021, 0 }; + static ulong[] dim260JoeKuoD5Init = { 1, 3, 3, 13, 9, 37, 19, 141, 201, 57, 1117, 0 }; + static ulong[] dim261JoeKuoD5Init = { 1, 1, 7, 1, 7, 27, 33, 235, 247, 701, 1293, 0 }; + static ulong[] dim262JoeKuoD5Init = { 1, 1, 5, 3, 17, 25, 81, 213, 457, 877, 741, 0 }; + static ulong[] dim263JoeKuoD5Init = { 1, 3, 3, 13, 15, 47, 113, 29, 111, 913, 1695, 0 }; + static ulong[] dim264JoeKuoD5Init = { 1, 1, 1, 3, 5, 53, 119, 215, 163, 933, 1447, 0 }; + static ulong[] dim265JoeKuoD5Init = { 1, 1, 3, 7, 15, 27, 111, 19, 231, 287, 1439, 0 }; + static ulong[] dim266JoeKuoD5Init = { 1, 1, 3, 5, 27, 29, 35, 109, 249, 989, 1837, 0 }; + static ulong[] dim267JoeKuoD5Init = { 1, 1, 3, 9, 29, 35, 51, 241, 509, 163, 831, 0 }; + static ulong[] dim268JoeKuoD5Init = { 1, 1, 3, 9, 7, 59, 43, 111, 119, 639, 899, 0 }; + static ulong[] dim269JoeKuoD5Init = { 1, 3, 1, 3, 15, 47, 95, 219, 377, 899, 535, 0 }; + static ulong[] dim270JoeKuoD5Init = { 1, 1, 1, 11, 3, 19, 115, 59, 143, 13, 701, 0 }; + static ulong[] dim271JoeKuoD5Init = { 1, 3, 5, 11, 5, 17, 17, 91, 223, 923, 1299, 0 }; + static ulong[] dim272JoeKuoD5Init = { 1, 1, 3, 15, 21, 21, 85, 127, 253, 271, 725, 0 }; + static ulong[] dim273JoeKuoD5Init = { 1, 3, 5, 15, 9, 11, 113, 67, 509, 697, 1163, 0 }; + static ulong[] dim274JoeKuoD5Init = { 1, 3, 7, 11, 13, 53, 15, 221, 253, 219, 1839, 0 }; + static ulong[] dim275JoeKuoD5Init = { 1, 3, 3, 3, 31, 63, 85, 171, 345, 243, 711, 0 }; + static ulong[] dim276JoeKuoD5Init = { 1, 1, 5, 1, 25, 13, 65, 91, 441, 609, 1751, 0 }; + static ulong[] dim277JoeKuoD5Init = { 1, 1, 1, 5, 23, 1, 15, 83, 115, 367, 735, 0 }; + static ulong[] dim278JoeKuoD5Init = { 1, 1, 1, 3, 11, 15, 41, 1, 437, 231, 1529, 0 }; + static ulong[] dim279JoeKuoD5Init = { 1, 1, 3, 3, 29, 11, 89, 133, 473, 811, 87, 0 }; + static ulong[] dim280JoeKuoD5Init = { 1, 1, 7, 1, 15, 39, 97, 197, 475, 105, 527, 0 }; + static ulong[] dim281JoeKuoD5Init = { 1, 1, 1, 1, 9, 17, 21, 167, 255, 341, 765, 0 }; + static ulong[] dim282JoeKuoD5Init = { 1, 3, 7, 7, 23, 47, 121, 219, 343, 169, 1147, 0 }; + static ulong[] dim283JoeKuoD5Init = { 1, 3, 1, 7, 3, 57, 27, 147, 383, 157, 1851, 0 }; + static ulong[] dim284JoeKuoD5Init = { 1, 1, 7, 1, 25, 17, 35, 123, 371, 281, 881, 0 }; + static ulong[] dim285JoeKuoD5Init = { 1, 3, 7, 7, 11, 11, 21, 5, 53, 155, 1811, 0 }; + static ulong[] dim286JoeKuoD5Init = { 1, 3, 3, 15, 31, 27, 117, 169, 389, 651, 1513, 0 }; + static ulong[] dim287JoeKuoD5Init = { 1, 1, 7, 5, 31, 15, 103, 59, 73, 575, 1597, 0 }; + static ulong[] dim288JoeKuoD5Init = { 1, 1, 7, 9, 15, 5, 17, 183, 471, 561, 607, 0 }; + static ulong[] dim289JoeKuoD5Init = { 1, 3, 7, 5, 9, 39, 25, 87, 171, 559, 481, 0 }; + static ulong[] dim290JoeKuoD5Init = { 1, 1, 3, 5, 17, 61, 101, 255, 147, 481, 661, 0 }; + static ulong[] dim291JoeKuoD5Init = { 1, 1, 3, 1, 17, 9, 119, 31, 177, 475, 1243, 0 }; + static ulong[] dim292JoeKuoD5Init = { 1, 1, 1, 13, 27, 45, 111, 229, 201, 927, 339, 0 }; + static ulong[] dim293JoeKuoD5Init = { 1, 3, 3, 15, 9, 25, 23, 91, 453, 861, 1919, 0 }; + static ulong[] dim294JoeKuoD5Init = { 1, 3, 1, 3, 7, 57, 93, 75, 223, 63, 7, 0 }; + static ulong[] dim295JoeKuoD5Init = { 1, 1, 5, 13, 7, 29, 71, 197, 405, 401, 585, 0 }; + static ulong[] dim296JoeKuoD5Init = { 1, 1, 3, 13, 11, 11, 7, 157, 1, 105, 473, 0 }; + static ulong[] dim297JoeKuoD5Init = { 1, 3, 7, 1, 29, 3, 127, 243, 93, 123, 1041, 0 }; + static ulong[] dim298JoeKuoD5Init = { 1, 3, 7, 9, 25, 55, 13, 243, 37, 565, 1167, 0 }; + static ulong[] dim299JoeKuoD5Init = { 1, 3, 7, 15, 31, 29, 75, 61, 43, 159, 443, 0 }; + static ulong[] dim300JoeKuoD5Init = { 1, 1, 3, 9, 15, 63, 43, 251, 97, 141, 791, 0 }; + static ulong[] dim301JoeKuoD5Init = { 1, 3, 1, 3, 27, 43, 17, 49, 109, 777, 1999, 0 }; + static ulong[] dim302JoeKuoD5Init = { 1, 3, 1, 1, 25, 5, 15, 145, 75, 855, 771, 0 }; + static ulong[] dim303JoeKuoD5Init = { 1, 3, 3, 13, 7, 27, 3, 221, 451, 533, 1059, 0 }; + static ulong[] dim304JoeKuoD5Init = { 1, 3, 5, 13, 11, 61, 53, 33, 217, 967, 177, 0 }; + static ulong[] dim305JoeKuoD5Init = { 1, 1, 7, 7, 1, 7, 85, 105, 417, 87, 417, 0 }; + static ulong[] dim306JoeKuoD5Init = { 1, 1, 1, 3, 13, 59, 11, 219, 363, 481, 893, 0 }; + static ulong[] dim307JoeKuoD5Init = { 1, 1, 5, 11, 27, 23, 85, 239, 343, 43, 1597, 0 }; + static ulong[] dim308JoeKuoD5Init = { 1, 3, 7, 3, 29, 5, 127, 49, 223, 797, 2003, 0 }; + static ulong[] dim309JoeKuoD5Init = { 1, 3, 1, 9, 29, 61, 21, 191, 157, 355, 2033, 0 }; + static ulong[] dim310JoeKuoD5Init = { 1, 1, 7, 5, 5, 49, 53, 207, 121, 451, 319, 0 }; + static ulong[] dim311JoeKuoD5Init = { 1, 3, 3, 11, 9, 7, 111, 153, 151, 395, 1389, 0 }; + static ulong[] dim312JoeKuoD5Init = { 1, 3, 5, 11, 25, 45, 113, 99, 263, 561, 1181, 0 }; + static ulong[] dim313JoeKuoD5Init = { 1, 3, 5, 1, 13, 27, 77, 1, 109, 741, 59, 0 }; + static ulong[] dim314JoeKuoD5Init = { 1, 1, 3, 1, 15, 57, 43, 7, 507, 885, 747, 0 }; + static ulong[] dim315JoeKuoD5Init = { 1, 3, 5, 5, 25, 7, 45, 147, 375, 975, 619, 0 }; + static ulong[] dim316JoeKuoD5Init = { 1, 1, 5, 11, 13, 11, 107, 81, 199, 11, 1267, 0 }; + static ulong[] dim317JoeKuoD5Init = { 1, 3, 5, 3, 15, 11, 113, 61, 425, 43, 1889, 0 }; + static ulong[] dim318JoeKuoD5Init = { 1, 3, 3, 7, 29, 11, 123, 237, 173, 249, 1091, 0 }; + static ulong[] dim319JoeKuoD5Init = { 1, 3, 7, 15, 29, 13, 21, 159, 149, 379, 1665, 0 }; + static ulong[] dim320JoeKuoD5Init = { 1, 1, 7, 15, 13, 53, 23, 47, 115, 183, 577, 0 }; + static ulong[] dim321JoeKuoD5Init = { 1, 1, 3, 9, 11, 49, 77, 81, 193, 133, 489, 0 }; + static ulong[] dim322JoeKuoD5Init = { 1, 3, 7, 15, 7, 27, 53, 187, 347, 211, 233, 0 }; + static ulong[] dim323JoeKuoD5Init = { 1, 1, 5, 9, 15, 17, 45, 75, 449, 971, 1123, 0 }; + static ulong[] dim324JoeKuoD5Init = { 1, 3, 3, 11, 25, 21, 109, 71, 439, 439, 1397, 0 }; + static ulong[] dim325JoeKuoD5Init = { 1, 1, 1, 7, 9, 47, 117, 117, 165, 531, 271, 0 }; + static ulong[] dim326JoeKuoD5Init = { 1, 3, 5, 9, 11, 5, 31, 199, 159, 87, 1729, 0 }; + static ulong[] dim327JoeKuoD5Init = { 1, 1, 7, 5, 27, 29, 17, 237, 175, 881, 989, 0 }; + static ulong[] dim328JoeKuoD5Init = { 1, 1, 5, 13, 25, 63, 19, 159, 409, 247, 683, 0 }; + static ulong[] dim329JoeKuoD5Init = { 1, 1, 3, 15, 15, 39, 101, 129, 253, 487, 719, 0 }; + static ulong[] dim330JoeKuoD5Init = { 1, 3, 1, 1, 7, 13, 107, 249, 331, 553, 1199, 0 }; + static ulong[] dim331JoeKuoD5Init = { 1, 3, 7, 1, 5, 51, 81, 37, 349, 561, 295, 0 }; + static ulong[] dim332JoeKuoD5Init = { 1, 3, 1, 5, 27, 61, 49, 89, 379, 67, 1063, 0 }; + static ulong[] dim333JoeKuoD5Init = { 1, 3, 7, 9, 15, 37, 119, 141, 81, 341, 2003, 0 }; + static ulong[] dim334JoeKuoD5Init = { 1, 3, 1, 13, 29, 31, 29, 143, 463, 399, 1345, 0 }; + static ulong[] dim335JoeKuoD5Init = { 1, 1, 7, 3, 29, 35, 29, 233, 499, 503, 903, 0 }; + static ulong[] dim336JoeKuoD5Init = { 1, 3, 7, 13, 29, 23, 127, 185, 77, 555, 1311, 0 }; + static ulong[] dim337JoeKuoD5Init = { 1, 1, 3, 11, 23, 3, 111, 159, 503, 889, 1043, 1153, 0 }; + static ulong[] dim338JoeKuoD5Init = { 1, 3, 7, 1, 13, 41, 109, 133, 81, 525, 2027, 3059, 0 }; + static ulong[] dim339JoeKuoD5Init = { 1, 1, 7, 11, 29, 53, 111, 129, 399, 479, 467, 363, 0 }; + static ulong[] dim340JoeKuoD5Init = { 1, 1, 7, 3, 5, 7, 9, 21, 391, 851, 575, 1317, 0 }; + static ulong[] dim341JoeKuoD5Init = { 1, 1, 1, 5, 19, 59, 91, 133, 403, 71, 1895, 3029, 0 }; + static ulong[] dim342JoeKuoD5Init = { 1, 3, 7, 11, 21, 29, 113, 109, 463, 251, 393, 3169, 0 }; + static ulong[] dim343JoeKuoD5Init = { 1, 1, 7, 11, 25, 3, 47, 195, 223, 1003, 947, 121, 0 }; + static ulong[] dim344JoeKuoD5Init = { 1, 1, 7, 9, 31, 61, 63, 31, 49, 907, 389, 3713, 0 }; + static ulong[] dim345JoeKuoD5Init = { 1, 1, 1, 13, 13, 19, 55, 87, 489, 665, 945, 2081, 0 }; + static ulong[] dim346JoeKuoD5Init = { 1, 1, 1, 7, 23, 5, 39, 19, 355, 399, 929, 3077, 0 }; + static ulong[] dim347JoeKuoD5Init = { 1, 3, 1, 11, 7, 59, 43, 69, 285, 753, 75, 2261, 0 }; + static ulong[] dim348JoeKuoD5Init = { 1, 1, 3, 3, 27, 45, 29, 181, 347, 863, 1421, 2077, 0 }; + static ulong[] dim349JoeKuoD5Init = { 1, 1, 1, 3, 7, 27, 77, 67, 399, 919, 917, 1465, 0 }; + static ulong[] dim350JoeKuoD5Init = { 1, 1, 5, 5, 11, 41, 17, 65, 495, 643, 1641, 323, 0 }; + static ulong[] dim351JoeKuoD5Init = { 1, 1, 3, 1, 9, 37, 107, 171, 189, 405, 2005, 2811, 0 }; + static ulong[] dim352JoeKuoD5Init = { 1, 1, 5, 11, 3, 63, 51, 27, 479, 571, 575, 2859, 0 }; + static ulong[] dim353JoeKuoD5Init = { 1, 1, 3, 9, 29, 23, 89, 7, 265, 41, 481, 2177, 0 }; + static ulong[] dim354JoeKuoD5Init = { 1, 3, 5, 7, 29, 15, 79, 217, 411, 867, 49, 469, 0 }; + static ulong[] dim355JoeKuoD5Init = { 1, 1, 7, 3, 3, 27, 69, 177, 291, 965, 637, 3629, 0 }; + static ulong[] dim356JoeKuoD5Init = { 1, 1, 1, 13, 11, 45, 83, 63, 275, 851, 779, 2615, 0 }; + static ulong[] dim357JoeKuoD5Init = { 1, 1, 3, 13, 1, 27, 89, 153, 355, 811, 515, 1541, 0 }; + static ulong[] dim358JoeKuoD5Init = { 1, 3, 1, 13, 1, 21, 75, 5, 255, 813, 1347, 2301, 0 }; + static ulong[] dim359JoeKuoD5Init = { 1, 1, 1, 15, 9, 49, 3, 203, 505, 591, 713, 2893, 0 }; + static ulong[] dim360JoeKuoD5Init = { 1, 3, 3, 3, 1, 51, 11, 161, 41, 17, 435, 3045, 0 }; + static ulong[] dim361JoeKuoD5Init = { 1, 1, 5, 9, 15, 23, 115, 73, 343, 985, 1559, 1615, 0 }; + static ulong[] dim362JoeKuoD5Init = { 1, 3, 5, 5, 9, 43, 17, 187, 311, 749, 1841, 609, 0 }; + static ulong[] dim363JoeKuoD5Init = { 1, 3, 1, 15, 13, 3, 113, 83, 287, 931, 399, 2143, 0 }; + static ulong[] dim364JoeKuoD5Init = { 1, 3, 5, 13, 17, 11, 99, 235, 313, 293, 2005, 2557, 0 }; + static ulong[] dim365JoeKuoD5Init = { 1, 3, 5, 13, 7, 57, 79, 225, 415, 749, 1243, 1303, 0 }; + static ulong[] dim366JoeKuoD5Init = { 1, 1, 5, 5, 21, 37, 55, 53, 389, 141, 1231, 1639, 0 }; + static ulong[] dim367JoeKuoD5Init = { 1, 3, 1, 13, 15, 37, 83, 219, 471, 751, 1241, 269, 0 }; + static ulong[] dim368JoeKuoD5Init = { 1, 3, 1, 11, 7, 51, 37, 81, 97, 857, 1431, 883, 0 }; + static ulong[] dim369JoeKuoD5Init = { 1, 1, 7, 7, 27, 31, 29, 223, 439, 25, 379, 3721, 0 }; + static ulong[] dim370JoeKuoD5Init = { 1, 3, 7, 7, 13, 11, 55, 127, 493, 493, 143, 1595, 0 }; + static ulong[] dim371JoeKuoD5Init = { 1, 3, 3, 15, 27, 55, 93, 91, 49, 931, 99, 1887, 0 }; + static ulong[] dim372JoeKuoD5Init = { 1, 1, 7, 1, 13, 11, 81, 175, 171, 203, 679, 239, 0 }; + static ulong[] dim373JoeKuoD5Init = { 1, 1, 3, 9, 19, 35, 79, 51, 163, 571, 363, 3903, 0 }; + static ulong[] dim374JoeKuoD5Init = { 1, 3, 3, 5, 3, 11, 99, 57, 479, 571, 487, 2141, 0 }; + static ulong[] dim375JoeKuoD5Init = { 1, 3, 7, 13, 1, 3, 123, 191, 349, 523, 53, 2991, 0 }; + static ulong[] dim376JoeKuoD5Init = { 1, 1, 3, 5, 17, 1, 5, 131, 279, 717, 1725, 35, 0 }; + static ulong[] dim377JoeKuoD5Init = { 1, 3, 5, 1, 9, 43, 29, 9, 487, 349, 457, 2551, 0 }; + static ulong[] dim378JoeKuoD5Init = { 1, 1, 5, 5, 7, 55, 75, 245, 249, 623, 1681, 2345, 0 }; + static ulong[] dim379JoeKuoD5Init = { 1, 1, 7, 11, 15, 35, 111, 185, 269, 913, 1899, 4059, 0 }; + static ulong[] dim380JoeKuoD5Init = { 1, 1, 5, 3, 1, 51, 43, 159, 273, 329, 863, 831, 0 }; + static ulong[] dim381JoeKuoD5Init = { 1, 1, 5, 15, 31, 35, 23, 135, 223, 333, 1265, 1183, 0 }; + static ulong[] dim382JoeKuoD5Init = { 1, 1, 3, 9, 9, 21, 93, 33, 341, 649, 1707, 1995, 0 }; + static ulong[] dim383JoeKuoD5Init = { 1, 3, 3, 5, 9, 9, 9, 175, 331, 709, 927, 423, 0 }; + static ulong[] dim384JoeKuoD5Init = { 1, 3, 1, 1, 5, 41, 31, 105, 223, 17, 1485, 2133, 0 }; + static ulong[] dim385JoeKuoD5Init = { 1, 1, 5, 11, 23, 7, 95, 87, 303, 817, 1019, 3335, 0 }; + static ulong[] dim386JoeKuoD5Init = { 1, 3, 7, 1, 21, 3, 7, 133, 23, 235, 1311, 531, 0 }; + static ulong[] dim387JoeKuoD5Init = { 1, 1, 7, 15, 25, 35, 69, 251, 37, 5, 1147, 2593, 0 }; + static ulong[] dim388JoeKuoD5Init = { 1, 1, 1, 9, 21, 55, 27, 129, 239, 887, 1759, 3211, 0 }; + static ulong[] dim389JoeKuoD5Init = { 1, 3, 5, 15, 3, 41, 13, 141, 339, 921, 1081, 4047, 0 }; + static ulong[] dim390JoeKuoD5Init = { 1, 3, 3, 5, 1, 49, 51, 91, 357, 259, 547, 189, 0 }; + static ulong[] dim391JoeKuoD5Init = { 1, 3, 1, 13, 15, 29, 43, 165, 213, 59, 429, 1831, 0 }; + static ulong[] dim392JoeKuoD5Init = { 1, 3, 1, 9, 25, 11, 37, 67, 5, 77, 915, 3865, 0 }; + static ulong[] dim393JoeKuoD5Init = { 1, 3, 5, 9, 31, 63, 61, 209, 283, 223, 1253, 2137, 0 }; + static ulong[] dim394JoeKuoD5Init = { 1, 1, 7, 11, 13, 45, 65, 105, 419, 909, 1943, 2201, 0 }; + static ulong[] dim395JoeKuoD5Init = { 1, 3, 7, 7, 9, 27, 21, 233, 37, 23, 921, 969, 0 }; + static ulong[] dim396JoeKuoD5Init = { 1, 3, 7, 3, 31, 55, 39, 127, 455, 397, 65, 2381, 0 }; + static ulong[] dim397JoeKuoD5Init = { 1, 3, 1, 3, 27, 57, 39, 137, 263, 519, 427, 3289, 0 }; + static ulong[] dim398JoeKuoD5Init = { 1, 1, 1, 5, 9, 29, 21, 99, 21, 807, 1871, 2875, 0 }; + static ulong[] dim399JoeKuoD5Init = { 1, 3, 3, 15, 27, 59, 3, 15, 189, 681, 305, 2969, 0 }; + static ulong[] dim400JoeKuoD5Init = { 1, 3, 5, 13, 25, 43, 111, 179, 281, 377, 1885, 815, 0 }; + static ulong[] dim401JoeKuoD5Init = { 1, 3, 3, 1, 15, 13, 17, 99, 53, 269, 1199, 1771, 0 }; + static ulong[] dim402JoeKuoD5Init = { 1, 1, 1, 7, 7, 59, 115, 209, 327, 913, 715, 279, 0 }; + static ulong[] dim403JoeKuoD5Init = { 1, 1, 5, 5, 11, 29, 81, 69, 191, 453, 379, 1379, 0 }; + static ulong[] dim404JoeKuoD5Init = { 1, 3, 1, 13, 1, 29, 85, 181, 281, 463, 137, 2779, 0 }; + static ulong[] dim405JoeKuoD5Init = { 1, 3, 5, 7, 25, 39, 45, 241, 87, 11, 511, 1919, 0 }; + static ulong[] dim406JoeKuoD5Init = { 1, 1, 3, 13, 21, 17, 57, 249, 91, 165, 1867, 615, 0 }; + static ulong[] dim407JoeKuoD5Init = { 1, 1, 3, 3, 29, 47, 79, 83, 3, 765, 1803, 2741, 0 }; + static ulong[] dim408JoeKuoD5Init = { 1, 1, 1, 15, 29, 41, 23, 9, 205, 657, 721, 2877, 0 }; + static ulong[] dim409JoeKuoD5Init = { 1, 1, 5, 5, 31, 21, 71, 217, 19, 589, 281, 719, 0 }; + static ulong[] dim410JoeKuoD5Init = { 1, 1, 7, 9, 11, 37, 3, 159, 41, 823, 1519, 3395, 0 }; + static ulong[] dim411JoeKuoD5Init = { 1, 1, 3, 3, 7, 51, 49, 193, 37, 981, 687, 3219, 0 }; + static ulong[] dim412JoeKuoD5Init = { 1, 1, 7, 15, 3, 27, 79, 195, 155, 613, 1933, 2083, 0 }; + static ulong[] dim413JoeKuoD5Init = { 1, 3, 1, 11, 13, 39, 75, 109, 395, 809, 545, 499, 0 }; + static ulong[] dim414JoeKuoD5Init = { 1, 3, 7, 11, 1, 63, 47, 77, 455, 617, 739, 2885, 0 }; + static ulong[] dim415JoeKuoD5Init = { 1, 1, 5, 9, 23, 59, 117, 47, 379, 349, 1967, 1895, 0 }; + static ulong[] dim416JoeKuoD5Init = { 1, 1, 1, 15, 1, 3, 7, 7, 105, 703, 1777, 113, 0 }; + static ulong[] dim417JoeKuoD5Init = { 1, 1, 5, 7, 7, 25, 69, 123, 257, 513, 41, 2689, 0 }; + static ulong[] dim418JoeKuoD5Init = { 1, 3, 1, 15, 7, 9, 11, 67, 27, 283, 1139, 1961, 0 }; + static ulong[] dim419JoeKuoD5Init = { 1, 1, 7, 13, 3, 5, 53, 251, 139, 913, 267, 1931, 0 }; + static ulong[] dim420JoeKuoD5Init = { 1, 1, 1, 13, 3, 11, 79, 211, 27, 551, 339, 3383, 0 }; + static ulong[] dim421JoeKuoD5Init = { 1, 1, 1, 1, 9, 47, 111, 47, 399, 353, 1707, 603, 0 }; + static ulong[] dim422JoeKuoD5Init = { 1, 1, 3, 15, 1, 43, 17, 19, 335, 713, 645, 3227, 0 }; + static ulong[] dim423JoeKuoD5Init = { 1, 1, 3, 9, 5, 27, 17, 209, 363, 821, 1365, 143, 0 }; + static ulong[] dim424JoeKuoD5Init = { 1, 3, 3, 7, 29, 11, 47, 253, 421, 599, 465, 2413, 0 }; + static ulong[] dim425JoeKuoD5Init = { 1, 1, 5, 9, 17, 39, 5, 47, 315, 645, 713, 4023, 0 }; + static ulong[] dim426JoeKuoD5Init = { 1, 1, 7, 9, 9, 3, 11, 45, 9, 831, 1513, 2655, 0 }; + static ulong[] dim427JoeKuoD5Init = { 1, 1, 5, 3, 29, 55, 113, 181, 281, 329, 193, 2969, 0 }; + static ulong[] dim428JoeKuoD5Init = { 1, 1, 7, 7, 9, 15, 29, 77, 11, 627, 1191, 3589, 0 }; + static ulong[] dim429JoeKuoD5Init = { 1, 1, 7, 3, 27, 53, 83, 13, 409, 931, 1581, 371, 0 }; + static ulong[] dim430JoeKuoD5Init = { 1, 3, 7, 3, 11, 7, 89, 143, 369, 519, 947, 2047, 0 }; + static ulong[] dim431JoeKuoD5Init = { 1, 3, 5, 11, 27, 59, 27, 75, 199, 965, 1669, 1713, 0 }; + static ulong[] dim432JoeKuoD5Init = { 1, 3, 1, 1, 23, 63, 91, 159, 193, 355, 653, 2659, 0 }; + static ulong[] dim433JoeKuoD5Init = { 1, 3, 5, 11, 23, 37, 15, 73, 457, 789, 1207, 2573, 0 }; + static ulong[] dim434JoeKuoD5Init = { 1, 1, 3, 7, 13, 23, 71, 171, 479, 183, 1285, 1649, 0 }; + static ulong[] dim435JoeKuoD5Init = { 1, 1, 7, 1, 19, 13, 89, 5, 319, 15, 857, 3175, 0 }; + static ulong[] dim436JoeKuoD5Init = { 1, 1, 3, 7, 29, 7, 1, 249, 191, 237, 683, 1261, 0 }; + static ulong[] dim437JoeKuoD5Init = { 1, 3, 7, 7, 17, 53, 99, 119, 35, 63, 1845, 2681, 0 }; + static ulong[] dim438JoeKuoD5Init = { 1, 3, 7, 7, 23, 53, 39, 157, 323, 537, 1989, 1233, 0 }; + static ulong[] dim439JoeKuoD5Init = { 1, 3, 7, 7, 25, 19, 9, 67, 315, 499, 919, 2299, 0 }; + static ulong[] dim440JoeKuoD5Init = { 1, 3, 3, 9, 21, 49, 109, 185, 403, 179, 1967, 1185, 0 }; + static ulong[] dim441JoeKuoD5Init = { 1, 1, 3, 1, 27, 53, 33, 203, 179, 515, 1867, 1775, 0 }; + static ulong[] dim442JoeKuoD5Init = { 1, 1, 7, 15, 19, 25, 23, 77, 51, 467, 143, 1585, 0 }; + static ulong[] dim443JoeKuoD5Init = { 1, 1, 1, 15, 19, 35, 41, 97, 407, 319, 1175, 241, 0 }; + static ulong[] dim444JoeKuoD5Init = { 1, 1, 3, 3, 29, 51, 41, 91, 223, 671, 729, 2009, 0 }; + static ulong[] dim445JoeKuoD5Init = { 1, 1, 5, 7, 7, 55, 125, 75, 425, 699, 1837, 1515, 0 }; + static ulong[] dim446JoeKuoD5Init = { 1, 1, 5, 1, 27, 59, 59, 235, 43, 77, 1433, 3689, 0 }; + static ulong[] dim447JoeKuoD5Init = { 1, 1, 7, 9, 19, 59, 69, 85, 199, 173, 1947, 1383, 0 }; + static ulong[] dim448JoeKuoD5Init = { 1, 3, 1, 13, 29, 47, 121, 131, 45, 341, 85, 257, 0 }; + static ulong[] dim449JoeKuoD5Init = { 1, 1, 3, 1, 17, 17, 113, 103, 407, 815, 225, 2267, 0 }; + static ulong[] dim450JoeKuoD5Init = { 1, 3, 1, 3, 23, 19, 65, 173, 475, 527, 271, 261, 0 }; + static ulong[] dim451JoeKuoD5Init = { 1, 3, 1, 9, 23, 51, 5, 75, 403, 277, 1897, 353, 0 }; + static ulong[] dim452JoeKuoD5Init = { 1, 1, 5, 3, 31, 49, 73, 93, 55, 99, 403, 659, 0 }; + static ulong[] dim453JoeKuoD5Init = { 1, 3, 1, 11, 29, 17, 57, 141, 209, 907, 431, 2265, 0 }; + static ulong[] dim454JoeKuoD5Init = { 1, 1, 3, 15, 25, 55, 105, 61, 273, 201, 23, 1211, 0 }; + static ulong[] dim455JoeKuoD5Init = { 1, 1, 5, 5, 3, 63, 41, 121, 161, 713, 1885, 225, 0 }; + static ulong[] dim456JoeKuoD5Init = { 1, 3, 3, 11, 11, 53, 63, 175, 439, 1, 953, 481, 0 }; + static ulong[] dim457JoeKuoD5Init = { 1, 3, 1, 7, 1, 27, 65, 189, 223, 659, 413, 3677, 0 }; + static ulong[] dim458JoeKuoD5Init = { 1, 3, 3, 5, 17, 9, 51, 39, 307, 811, 941, 2297, 0 }; + static ulong[] dim459JoeKuoD5Init = { 1, 3, 1, 3, 1, 41, 77, 237, 47, 533, 1783, 1385, 0 }; + static ulong[] dim460JoeKuoD5Init = { 1, 3, 3, 13, 19, 39, 31, 249, 449, 639, 1789, 3479, 0 }; + static ulong[] dim461JoeKuoD5Init = { 1, 3, 7, 11, 9, 9, 9, 19, 481, 411, 1669, 863, 0 }; + static ulong[] dim462JoeKuoD5Init = { 1, 3, 7, 7, 15, 15, 89, 161, 171, 377, 2031, 389, 0 }; + static ulong[] dim463JoeKuoD5Init = { 1, 1, 5, 5, 7, 49, 83, 81, 181, 395, 1197, 2455, 0 }; + static ulong[] dim464JoeKuoD5Init = { 1, 3, 5, 9, 15, 25, 21, 35, 287, 369, 693, 1753, 0 }; + static ulong[] dim465JoeKuoD5Init = { 1, 3, 5, 7, 5, 19, 41, 241, 459, 427, 631, 1109, 0 }; + static ulong[] dim466JoeKuoD5Init = { 1, 3, 3, 3, 23, 13, 115, 55, 145, 933, 1985, 753, 0 }; + static ulong[] dim467JoeKuoD5Init = { 1, 3, 5, 5, 19, 15, 73, 67, 335, 583, 315, 1559, 0 }; + static ulong[] dim468JoeKuoD5Init = { 1, 1, 5, 5, 23, 41, 65, 155, 171, 1017, 1283, 1989, 0 }; + static ulong[] dim469JoeKuoD5Init = { 1, 1, 5, 13, 23, 53, 75, 91, 253, 41, 101, 1943, 0 }; + static ulong[] dim470JoeKuoD5Init = { 1, 3, 7, 13, 25, 13, 5, 71, 437, 553, 701, 805, 0 }; + static ulong[] dim471JoeKuoD5Init = { 1, 1, 3, 5, 3, 3, 61, 255, 409, 753, 1265, 2739, 0 }; + static ulong[] dim472JoeKuoD5Init = { 1, 3, 1, 11, 25, 33, 69, 41, 367, 133, 809, 1421, 0 }; + static ulong[] dim473JoeKuoD5Init = { 1, 1, 7, 9, 3, 59, 15, 229, 313, 667, 45, 1485, 0 }; + static ulong[] dim474JoeKuoD5Init = { 1, 3, 3, 11, 3, 45, 73, 245, 47, 489, 1715, 3167, 0 }; + static ulong[] dim475JoeKuoD5Init = { 1, 1, 7, 15, 23, 23, 107, 1, 171, 993, 1617, 3665, 0 }; + static ulong[] dim476JoeKuoD5Init = { 1, 3, 7, 5, 5, 41, 9, 221, 91, 611, 639, 3709, 0 }; + static ulong[] dim477JoeKuoD5Init = { 1, 3, 7, 1, 17, 31, 55, 23, 75, 501, 1605, 2361, 0 }; + static ulong[] dim478JoeKuoD5Init = { 1, 1, 3, 11, 19, 27, 37, 111, 393, 75, 523, 2079, 0 }; + static ulong[] dim479JoeKuoD5Init = { 1, 1, 3, 1, 13, 17, 103, 177, 331, 431, 419, 2781, 0 }; + static ulong[] dim480JoeKuoD5Init = { 1, 1, 5, 1, 31, 57, 9, 87, 111, 761, 1259, 3645, 0 }; + static ulong[] dim481JoeKuoD5Init = { 1, 3, 1, 1, 29, 39, 117, 207, 25, 263, 1875, 3325, 1773, 0 }; + static ulong[] dim482JoeKuoD5Init = { 1, 3, 5, 11, 21, 55, 105, 43, 155, 933, 585, 1617, 1705, 0 }; + static ulong[] dim483JoeKuoD5Init = { 1, 1, 5, 5, 29, 37, 67, 165, 229, 517, 71, 3927, 1131, 0 }; + static ulong[] dim484JoeKuoD5Init = { 1, 1, 1, 3, 1, 15, 7, 139, 431, 599, 101, 1167, 55, 0 }; + static ulong[] dim485JoeKuoD5Init = { 1, 3, 1, 3, 5, 31, 15, 99, 375, 491, 293, 2521, 1599, 0 }; + static ulong[] dim486JoeKuoD5Init = { 1, 1, 1, 13, 29, 59, 99, 155, 295, 21, 1459, 2263, 1997, 0 }; + static ulong[] dim487JoeKuoD5Init = { 1, 3, 7, 5, 29, 61, 103, 151, 37, 431, 1893, 2835, 6509, 0 }; + static ulong[] dim488JoeKuoD5Init = { 1, 1, 3, 7, 17, 15, 1, 163, 481, 547, 701, 2957, 7071, 0 }; + static ulong[] dim489JoeKuoD5Init = { 1, 1, 5, 5, 29, 41, 51, 223, 133, 49, 753, 3769, 8139, 0 }; + static ulong[] dim490JoeKuoD5Init = { 1, 3, 3, 1, 23, 23, 21, 107, 9, 445, 215, 857, 7913, 0 }; + static ulong[] dim491JoeKuoD5Init = { 1, 3, 5, 5, 17, 13, 11, 111, 419, 433, 1289, 2855, 2157, 0 }; + static ulong[] dim492JoeKuoD5Init = { 1, 1, 5, 11, 31, 3, 97, 223, 143, 117, 563, 2179, 1053, 0 }; + static ulong[] dim493JoeKuoD5Init = { 1, 3, 7, 13, 7, 25, 115, 151, 181, 999, 1027, 795, 679, 0 }; + static ulong[] dim494JoeKuoD5Init = { 1, 1, 5, 15, 31, 23, 85, 125, 135, 1001, 909, 339, 5693, 0 }; + static ulong[] dim495JoeKuoD5Init = { 1, 3, 3, 3, 29, 17, 105, 239, 467, 875, 1135, 1859, 6399, 0 }; + static ulong[] dim496JoeKuoD5Init = { 1, 3, 5, 13, 19, 59, 99, 29, 177, 879, 1817, 3747, 1855, 0 }; + static ulong[] dim497JoeKuoD5Init = { 1, 1, 7, 1, 23, 5, 29, 53, 111, 341, 1713, 2285, 7033, 0 }; + static ulong[] dim498JoeKuoD5Init = { 1, 1, 3, 5, 7, 55, 67, 173, 273, 881, 1405, 1663, 2135, 0 }; + static ulong[] dim499JoeKuoD5Init = { 1, 3, 1, 9, 1, 39, 11, 63, 107, 905, 629, 1773, 1059, 0 }; + static ulong[] dim500JoeKuoD5Init = { 1, 1, 3, 15, 29, 51, 111, 189, 337, 505, 453, 1549, 3697, 0 }; + static ulong[] dim501JoeKuoD5Init = { 1, 3, 1, 9, 23, 57, 21, 61, 161, 695, 1097, 809, 5737, 0 }; + static ulong[] dim502JoeKuoD5Init = { 1, 3, 7, 15, 15, 55, 93, 65, 101, 521, 1273, 1949, 7325, 0 }; + static ulong[] dim503JoeKuoD5Init = { 1, 3, 7, 3, 23, 31, 37, 51, 205, 261, 647, 1905, 4407, 0 }; + static ulong[] dim504JoeKuoD5Init = { 1, 1, 7, 3, 3, 9, 91, 51, 271, 623, 1611, 563, 4687, 0 }; + static ulong[] dim505JoeKuoD5Init = { 1, 3, 7, 3, 11, 61, 95, 215, 347, 171, 519, 2331, 2189, 0 }; + static ulong[] dim506JoeKuoD5Init = { 1, 1, 3, 1, 25, 13, 87, 159, 87, 915, 463, 1345, 5901, 0 }; + static ulong[] dim507JoeKuoD5Init = { 1, 3, 3, 11, 31, 21, 81, 75, 153, 337, 2025, 233, 4999, 0 }; + static ulong[] dim508JoeKuoD5Init = { 1, 1, 1, 11, 23, 25, 81, 149, 225, 799, 159, 799, 687, 0 }; + static ulong[] dim509JoeKuoD5Init = { 1, 1, 7, 5, 23, 55, 67, 47, 375, 657, 877, 1505, 1757, 0 }; + static ulong[] dim510JoeKuoD5Init = { 1, 3, 3, 9, 17, 7, 123, 71, 203, 457, 201, 9, 6671, 0 }; + static ulong[] dim511JoeKuoD5Init = { 1, 3, 7, 3, 1, 55, 7, 133, 65, 891, 1705, 389, 4601, 0 }; + static ulong[] dim512JoeKuoD5Init = { 1, 3, 3, 3, 21, 59, 101, 105, 241, 231, 363, 4029, 1279, 0 }; + static ulong[] dim513JoeKuoD5Init = { 1, 3, 7, 11, 31, 61, 115, 219, 249, 575, 201, 547, 5315, 0 }; + static ulong[] dim514JoeKuoD5Init = { 1, 1, 5, 11, 11, 3, 75, 219, 183, 771, 725, 2175, 4077, 0 }; + static ulong[] dim515JoeKuoD5Init = { 1, 3, 1, 13, 1, 37, 1, 165, 431, 423, 2021, 475, 5151, 0 }; + static ulong[] dim516JoeKuoD5Init = { 1, 3, 7, 7, 15, 59, 25, 133, 377, 747, 23, 1195, 3303, 0 }; + static ulong[] dim517JoeKuoD5Init = { 1, 3, 5, 15, 23, 63, 121, 159, 403, 143, 187, 1481, 4755, 0 }; + static ulong[] dim518JoeKuoD5Init = { 1, 3, 7, 13, 21, 29, 55, 165, 483, 495, 579, 1197, 4841, 0 }; + static ulong[] dim519JoeKuoD5Init = { 1, 3, 5, 3, 27, 7, 111, 57, 353, 1023, 1593, 1447, 5819, 0 }; + static ulong[] dim520JoeKuoD5Init = { 1, 3, 7, 3, 13, 37, 115, 65, 23, 707, 603, 1805, 6011, 0 }; + static ulong[] dim521JoeKuoD5Init = { 1, 1, 5, 15, 9, 47, 87, 195, 125, 515, 1885, 89, 1377, 0 }; + static ulong[] dim522JoeKuoD5Init = { 1, 1, 3, 11, 1, 25, 11, 73, 183, 897, 981, 275, 331, 0 }; + static ulong[] dim523JoeKuoD5Init = { 1, 1, 5, 15, 13, 53, 125, 37, 145, 763, 1991, 1971, 4385, 0 }; + static ulong[] dim524JoeKuoD5Init = { 1, 3, 7, 1, 29, 53, 69, 97, 415, 151, 1389, 2867, 3085, 0 }; + static ulong[] dim525JoeKuoD5Init = { 1, 3, 7, 7, 21, 51, 77, 115, 81, 197, 91, 3417, 2357, 0 }; + static ulong[] dim526JoeKuoD5Init = { 1, 3, 7, 11, 31, 31, 21, 21, 93, 221, 1401, 3253, 6875, 0 }; + static ulong[] dim527JoeKuoD5Init = { 1, 3, 3, 9, 11, 17, 87, 75, 333, 871, 1679, 2943, 4803, 0 }; + static ulong[] dim528JoeKuoD5Init = { 1, 1, 7, 11, 11, 61, 67, 141, 79, 757, 965, 1999, 6363, 0 }; + static ulong[] dim529JoeKuoD5Init = { 1, 1, 5, 5, 27, 13, 109, 137, 235, 1007, 1307, 341, 3957, 0 }; + static ulong[] dim530JoeKuoD5Init = { 1, 1, 7, 9, 15, 37, 47, 247, 295, 867, 1433, 553, 5365, 0 }; + static ulong[] dim531JoeKuoD5Init = { 1, 1, 7, 3, 13, 29, 77, 155, 423, 823, 1117, 3939, 1423, 0 }; + static ulong[] dim532JoeKuoD5Init = { 1, 1, 3, 9, 17, 27, 47, 73, 79, 329, 1473, 3241, 697, 0 }; + static ulong[] dim533JoeKuoD5Init = { 1, 3, 5, 9, 23, 5, 47, 89, 427, 893, 2031, 3415, 6367, 0 }; + static ulong[] dim534JoeKuoD5Init = { 1, 3, 5, 1, 17, 47, 31, 113, 461, 417, 2017, 41, 2417, 0 }; + static ulong[] dim535JoeKuoD5Init = { 1, 1, 3, 5, 11, 35, 119, 95, 389, 31, 871, 563, 7547, 0 }; + static ulong[] dim536JoeKuoD5Init = { 1, 3, 5, 9, 3, 49, 63, 237, 511, 619, 589, 3571, 1883, 0 }; + static ulong[] dim537JoeKuoD5Init = { 1, 3, 3, 1, 1, 29, 17, 117, 173, 399, 443, 2625, 2009, 0 }; + static ulong[] dim538JoeKuoD5Init = { 1, 3, 3, 9, 23, 47, 5, 167, 413, 513, 509, 853, 3509, 0 }; + static ulong[] dim539JoeKuoD5Init = { 1, 1, 3, 5, 13, 15, 33, 165, 21, 163, 1613, 3387, 645, 0 }; + static ulong[] dim540JoeKuoD5Init = { 1, 1, 1, 3, 7, 33, 59, 25, 65, 243, 1253, 1893, 1637, 0 }; + static ulong[] dim541JoeKuoD5Init = { 1, 1, 5, 15, 21, 63, 51, 167, 131, 171, 651, 295, 5775, 0 }; + static ulong[] dim542JoeKuoD5Init = { 1, 1, 5, 9, 7, 23, 31, 171, 85, 859, 1691, 2757, 1351, 0 }; + static ulong[] dim543JoeKuoD5Init = { 1, 1, 5, 3, 31, 7, 25, 69, 183, 417, 39, 2671, 5197, 0 }; + static ulong[] dim544JoeKuoD5Init = { 1, 1, 5, 9, 17, 21, 57, 145, 23, 933, 2031, 65, 4583, 0 }; + static ulong[] dim545JoeKuoD5Init = { 1, 3, 3, 5, 1, 59, 117, 191, 197, 627, 659, 2873, 3865, 0 }; + static ulong[] dim546JoeKuoD5Init = { 1, 1, 5, 15, 23, 51, 45, 47, 147, 779, 1619, 1017, 3769, 0 }; + static ulong[] dim547JoeKuoD5Init = { 1, 1, 7, 3, 9, 1, 75, 151, 117, 483, 1499, 2143, 5873, 0 }; + static ulong[] dim548JoeKuoD5Init = { 1, 1, 7, 1, 13, 31, 105, 115, 199, 111, 1403, 1833, 7923, 0 }; + static ulong[] dim549JoeKuoD5Init = { 1, 1, 7, 7, 29, 53, 121, 149, 419, 107, 1299, 1925, 4409, 0 }; + static ulong[] dim550JoeKuoD5Init = { 1, 1, 7, 11, 21, 25, 63, 97, 145, 71, 1693, 465, 5607, 0 }; + static ulong[] dim551JoeKuoD5Init = { 1, 3, 3, 15, 25, 43, 77, 177, 53, 495, 1983, 4083, 2107, 0 }; + static ulong[] dim552JoeKuoD5Init = { 1, 1, 7, 11, 7, 51, 109, 29, 171, 847, 673, 2929, 3887, 0 }; + static ulong[] dim553JoeKuoD5Init = { 1, 1, 5, 9, 31, 47, 63, 225, 371, 453, 1075, 2293, 3323, 0 }; + static ulong[] dim554JoeKuoD5Init = { 1, 3, 1, 9, 31, 29, 67, 227, 135, 369, 481, 187, 3237, 0 }; + static ulong[] dim555JoeKuoD5Init = { 1, 3, 1, 7, 1, 29, 49, 157, 99, 741, 279, 1963, 7881, 0 }; + static ulong[] dim556JoeKuoD5Init = { 1, 3, 5, 13, 17, 49, 33, 73, 103, 941, 209, 1329, 3, 0 }; + static ulong[] dim557JoeKuoD5Init = { 1, 1, 1, 1, 17, 41, 53, 57, 163, 761, 1855, 3423, 5317, 0 }; + static ulong[] dim558JoeKuoD5Init = { 1, 1, 5, 1, 11, 13, 59, 37, 351, 561, 1213, 2355, 8095, 0 }; + static ulong[] dim559JoeKuoD5Init = { 1, 3, 5, 3, 3, 31, 47, 237, 101, 167, 1623, 645, 4787, 0 }; + static ulong[] dim560JoeKuoD5Init = { 1, 1, 3, 9, 21, 33, 55, 15, 433, 129, 279, 2131, 2943, 0 }; + static ulong[] dim561JoeKuoD5Init = { 1, 1, 7, 13, 9, 55, 71, 151, 273, 901, 427, 3749, 8163, 0 }; + static ulong[] dim562JoeKuoD5Init = { 1, 1, 1, 13, 13, 63, 11, 63, 477, 743, 1391, 2045, 6985, 0 }; + static ulong[] dim563JoeKuoD5Init = { 1, 3, 3, 11, 31, 25, 93, 217, 39, 263, 1411, 3, 7313, 0 }; + static ulong[] dim564JoeKuoD5Init = { 1, 1, 7, 1, 21, 13, 3, 255, 107, 851, 1281, 959, 3955, 0 }; + static ulong[] dim565JoeKuoD5Init = { 1, 3, 3, 9, 19, 55, 53, 201, 199, 361, 805, 579, 1459, 0 }; + static ulong[] dim566JoeKuoD5Init = { 1, 3, 3, 15, 9, 59, 109, 245, 29, 21, 137, 717, 607, 0 }; + static ulong[] dim567JoeKuoD5Init = { 1, 3, 3, 11, 15, 23, 49, 3, 195, 185, 85, 3885, 5859, 0 }; + static ulong[] dim568JoeKuoD5Init = { 1, 1, 3, 3, 13, 21, 7, 65, 185, 541, 305, 79, 3125, 0 }; + static ulong[] dim569JoeKuoD5Init = { 1, 3, 3, 3, 7, 59, 11, 125, 127, 283, 943, 3545, 1617, 0 }; + static ulong[] dim570JoeKuoD5Init = { 1, 1, 3, 3, 19, 39, 73, 167, 431, 147, 3, 1099, 6311, 0 }; + static ulong[] dim571JoeKuoD5Init = { 1, 1, 7, 13, 29, 57, 109, 169, 49, 457, 469, 3093, 7505, 0 }; + static ulong[] dim572JoeKuoD5Init = { 1, 3, 1, 1, 15, 29, 69, 133, 423, 737, 673, 2529, 2065, 0 }; + static ulong[] dim573JoeKuoD5Init = { 1, 3, 7, 7, 21, 47, 15, 175, 17, 419, 1917, 1183, 429, 0 }; + static ulong[] dim574JoeKuoD5Init = { 1, 3, 3, 9, 31, 43, 19, 63, 395, 331, 385, 3879, 3233, 0 }; + static ulong[] dim575JoeKuoD5Init = { 1, 1, 1, 9, 5, 11, 101, 65, 315, 805, 719, 641, 343, 0 }; + static ulong[] dim576JoeKuoD5Init = { 1, 1, 3, 1, 15, 5, 17, 115, 503, 395, 531, 1201, 7225, 0 }; + static ulong[] dim577JoeKuoD5Init = { 1, 3, 1, 7, 3, 35, 29, 1, 297, 421, 1365, 1491, 7973, 0 }; + static ulong[] dim578JoeKuoD5Init = { 1, 1, 1, 13, 1, 59, 79, 13, 337, 717, 1229, 2587, 5659, 0 }; + static ulong[] dim579JoeKuoD5Init = { 1, 3, 7, 9, 21, 15, 27, 19, 195, 27, 267, 381, 1969, 0 }; + static ulong[] dim580JoeKuoD5Init = { 1, 3, 7, 7, 25, 63, 119, 155, 243, 229, 897, 629, 7515, 0 }; + static ulong[] dim581JoeKuoD5Init = { 1, 1, 7, 1, 13, 37, 35, 31, 485, 729, 123, 1645, 457, 0 }; + static ulong[] dim582JoeKuoD5Init = { 1, 3, 5, 11, 17, 15, 47, 149, 311, 189, 1925, 9, 7639, 0 }; + static ulong[] dim583JoeKuoD5Init = { 1, 1, 1, 3, 1, 1, 127, 197, 109, 49, 265, 3643, 3629, 0 }; + static ulong[] dim584JoeKuoD5Init = { 1, 1, 3, 15, 21, 49, 71, 187, 189, 631, 1449, 775, 5973, 0 }; + static ulong[] dim585JoeKuoD5Init = { 1, 3, 5, 5, 27, 15, 17, 137, 393, 807, 1189, 2731, 6337, 0 }; + static ulong[] dim586JoeKuoD5Init = { 1, 3, 1, 11, 3, 43, 3, 77, 487, 539, 1781, 3261, 2775, 0 }; + static ulong[] dim587JoeKuoD5Init = { 1, 1, 1, 13, 29, 31, 83, 225, 159, 971, 1899, 1035, 5383, 0 }; + static ulong[] dim588JoeKuoD5Init = { 1, 3, 1, 7, 27, 1, 15, 141, 485, 639, 1895, 3129, 4489, 0 }; + static ulong[] dim589JoeKuoD5Init = { 1, 3, 3, 5, 9, 17, 21, 231, 363, 637, 1851, 3675, 5371, 0 }; + static ulong[] dim590JoeKuoD5Init = { 1, 3, 7, 11, 9, 17, 91, 243, 51, 565, 491, 3333, 3329, 0 }; + static ulong[] dim591JoeKuoD5Init = { 1, 1, 5, 3, 13, 9, 19, 227, 353, 111, 1805, 3917, 6849, 0 }; + static ulong[] dim592JoeKuoD5Init = { 1, 1, 1, 1, 29, 31, 27, 57, 421, 155, 1385, 999, 1581, 0 }; + static ulong[] dim593JoeKuoD5Init = { 1, 3, 5, 7, 1, 55, 35, 35, 311, 357, 1569, 2693, 2251, 0 }; + static ulong[] dim594JoeKuoD5Init = { 1, 3, 1, 9, 27, 41, 111, 119, 265, 165, 1999, 2067, 7801, 0 }; + static ulong[] dim595JoeKuoD5Init = { 1, 3, 5, 15, 31, 55, 31, 39, 305, 581, 373, 2523, 2153, 0 }; + static ulong[] dim596JoeKuoD5Init = { 1, 3, 5, 7, 9, 19, 115, 41, 261, 209, 897, 409, 5201, 0 }; + static ulong[] dim597JoeKuoD5Init = { 1, 3, 7, 13, 3, 15, 95, 143, 407, 719, 1763, 1763, 1173, 0 }; + static ulong[] dim598JoeKuoD5Init = { 1, 1, 5, 11, 17, 13, 69, 17, 293, 815, 1361, 259, 6751, 0 }; + static ulong[] dim599JoeKuoD5Init = { 1, 1, 3, 15, 11, 53, 13, 195, 153, 445, 1873, 1159, 4739, 0 }; + static ulong[] dim600JoeKuoD5Init = { 1, 3, 5, 7, 3, 25, 57, 229, 269, 299, 1687, 2707, 7049, 0 }; + static ulong[] dim601JoeKuoD5Init = { 1, 3, 3, 1, 5, 23, 89, 171, 207, 523, 2031, 2513, 2475, 0 }; + static ulong[] dim602JoeKuoD5Init = { 1, 1, 1, 7, 25, 57, 125, 109, 203, 671, 781, 295, 4001, 0 }; + static ulong[] dim603JoeKuoD5Init = { 1, 1, 1, 3, 17, 37, 51, 169, 441, 797, 871, 3267, 5695, 0 }; + static ulong[] dim604JoeKuoD5Init = { 1, 1, 3, 5, 17, 25, 97, 41, 377, 643, 1463, 141, 3961, 0 }; + static ulong[] dim605JoeKuoD5Init = { 1, 1, 5, 1, 17, 35, 111, 91, 253, 237, 1491, 2839, 2265, 0 }; + static ulong[] dim606JoeKuoD5Init = { 1, 1, 7, 13, 23, 7, 47, 61, 263, 591, 1365, 2371, 4209, 0 }; + static ulong[] dim607JoeKuoD5Init = { 1, 3, 3, 5, 7, 51, 117, 161, 383, 303, 1765, 3105, 3961, 0 }; + static ulong[] dim608JoeKuoD5Init = { 1, 1, 5, 11, 11, 55, 111, 55, 417, 713, 305, 1781, 5283, 0 }; + static ulong[] dim609JoeKuoD5Init = { 1, 1, 3, 11, 25, 51, 17, 215, 335, 47, 1789, 2049, 5349, 0 }; + static ulong[] dim610JoeKuoD5Init = { 1, 3, 3, 3, 1, 9, 71, 105, 397, 517, 1093, 765, 5301, 0 }; + static ulong[] dim611JoeKuoD5Init = { 1, 1, 7, 9, 31, 41, 95, 153, 383, 91, 1649, 3059, 6135, 0 }; + static ulong[] dim612JoeKuoD5Init = { 1, 1, 5, 11, 19, 51, 67, 119, 507, 179, 571, 2767, 5517, 0 }; + static ulong[] dim613JoeKuoD5Init = { 1, 3, 5, 9, 13, 19, 35, 249, 39, 425, 233, 1635, 5915, 0 }; + static ulong[] dim614JoeKuoD5Init = { 1, 1, 1, 11, 17, 15, 43, 29, 351, 25, 1879, 3941, 189, 0 }; + static ulong[] dim615JoeKuoD5Init = { 1, 3, 5, 5, 13, 55, 9, 7, 91, 951, 1681, 2723, 4349, 0 }; + static ulong[] dim616JoeKuoD5Init = { 1, 3, 1, 9, 27, 31, 49, 33, 287, 629, 851, 1353, 6391, 0 }; + static ulong[] dim617JoeKuoD5Init = { 1, 1, 5, 7, 19, 27, 45, 209, 257, 141, 1771, 931, 7839, 0 }; + static ulong[] dim618JoeKuoD5Init = { 1, 1, 5, 1, 9, 47, 87, 71, 183, 249, 311, 1989, 1753, 0 }; + static ulong[] dim619JoeKuoD5Init = { 1, 3, 5, 5, 7, 35, 45, 199, 207, 203, 831, 2643, 1155, 0 }; + static ulong[] dim620JoeKuoD5Init = { 1, 1, 1, 11, 5, 11, 27, 187, 405, 747, 261, 1279, 6153, 0 }; + static ulong[] dim621JoeKuoD5Init = { 1, 1, 5, 9, 7, 43, 23, 117, 421, 775, 1657, 1071, 4551, 0 }; + static ulong[] dim622JoeKuoD5Init = { 1, 1, 7, 9, 1, 51, 5, 27, 121, 459, 1251, 901, 2301, 0 }; + static ulong[] dim623JoeKuoD5Init = { 1, 3, 3, 11, 15, 47, 107, 93, 79, 719, 571, 65, 7589, 0 }; + static ulong[] dim624JoeKuoD5Init = { 1, 3, 5, 3, 19, 33, 103, 253, 469, 109, 913, 2251, 4737, 0 }; + static ulong[] dim625JoeKuoD5Init = { 1, 3, 3, 5, 23, 29, 89, 79, 253, 513, 723, 3823, 5769, 0 }; + static ulong[] dim626JoeKuoD5Init = { 1, 1, 7, 1, 27, 3, 103, 171, 353, 673, 1147, 529, 4737, 0 }; + static ulong[] dim627JoeKuoD5Init = { 1, 3, 7, 7, 27, 5, 103, 61, 101, 759, 443, 2003, 5537, 0 }; + static ulong[] dim628JoeKuoD5Init = { 1, 1, 1, 5, 11, 15, 109, 119, 473, 585, 1759, 319, 5461, 0 }; + static ulong[] dim629JoeKuoD5Init = { 1, 3, 7, 9, 19, 61, 5, 255, 171, 843, 823, 2713, 5313, 0 }; + static ulong[] dim630JoeKuoD5Init = { 1, 3, 7, 3, 9, 11, 57, 3, 365, 471, 1179, 1999, 3333, 0 }; + static ulong[] dim631JoeKuoD5Init = { 1, 3, 7, 9, 1, 3, 3, 195, 441, 193, 1905, 1753, 1839, 0 }; + static ulong[] dim632JoeKuoD5Init = { 1, 3, 1, 3, 1, 49, 99, 85, 175, 603, 1569, 2201, 1979, 0 }; + static ulong[] dim633JoeKuoD5Init = { 1, 1, 3, 5, 27, 37, 61, 137, 219, 469, 973, 1979, 1135, 0 }; + static ulong[] dim634JoeKuoD5Init = { 1, 1, 3, 13, 3, 59, 11, 203, 415, 513, 1469, 1655, 5913, 0 }; + static ulong[] dim635JoeKuoD5Init = { 1, 1, 3, 7, 21, 23, 87, 83, 21, 351, 899, 1633, 6589, 0 }; + static ulong[] dim636JoeKuoD5Init = { 1, 1, 7, 5, 5, 63, 45, 201, 193, 27, 1365, 1197, 1729, 0 }; + static ulong[] dim637JoeKuoD5Init = { 1, 3, 3, 5, 1, 35, 59, 157, 295, 359, 383, 3191, 7019, 0 }; + static ulong[] dim638JoeKuoD5Init = { 1, 1, 1, 13, 3, 23, 17, 149, 59, 115, 1101, 1879, 4243, 0 }; + static ulong[] dim639JoeKuoD5Init = { 1, 3, 3, 5, 3, 21, 71, 31, 85, 93, 1691, 379, 7901, 0 }; + static ulong[] dim640JoeKuoD5Init = { 1, 1, 7, 13, 15, 7, 29, 59, 191, 817, 439, 453, 5073, 0 }; + static ulong[] dim641JoeKuoD5Init = { 1, 3, 3, 9, 29, 7, 119, 35, 393, 9, 509, 3907, 7031, 0 }; + static ulong[] dim642JoeKuoD5Init = { 1, 3, 1, 3, 29, 51, 19, 127, 399, 309, 117, 3491, 5417, 0 }; + static ulong[] dim643JoeKuoD5Init = { 1, 1, 7, 5, 31, 33, 17, 119, 365, 301, 527, 3341, 779, 0 }; + static ulong[] dim644JoeKuoD5Init = { 1, 3, 5, 1, 29, 41, 43, 85, 133, 191, 229, 3407, 3147, 0 }; + static ulong[] dim645JoeKuoD5Init = { 1, 1, 7, 3, 7, 9, 49, 121, 193, 569, 467, 999, 6813, 0 }; + static ulong[] dim646JoeKuoD5Init = { 1, 1, 3, 13, 7, 23, 121, 43, 173, 761, 525, 3221, 5435, 0 }; + static ulong[] dim647JoeKuoD5Init = { 1, 3, 3, 3, 15, 43, 47, 149, 227, 357, 1219, 4087, 1215, 0 }; + static ulong[] dim648JoeKuoD5Init = { 1, 1, 3, 15, 1, 33, 81, 195, 201, 307, 1081, 3201, 4293, 0 }; + static ulong[] dim649JoeKuoD5Init = { 1, 3, 5, 11, 11, 1, 125, 119, 105, 783, 117, 3465, 5713, 0 }; + static ulong[] dim650JoeKuoD5Init = { 1, 1, 3, 1, 1, 51, 17, 141, 107, 875, 1135, 1213, 7113, 0 }; + static ulong[] dim651JoeKuoD5Init = { 1, 1, 1, 1, 7, 41, 63, 91, 465, 893, 1663, 2717, 6313, 0 }; + static ulong[] dim652JoeKuoD5Init = { 1, 3, 1, 15, 23, 43, 77, 49, 131, 953, 1591, 869, 3779, 0 }; + static ulong[] dim653JoeKuoD5Init = { 1, 1, 7, 15, 5, 9, 41, 183, 403, 775, 1163, 2963, 861, 0 }; + static ulong[] dim654JoeKuoD5Init = { 1, 3, 7, 11, 27, 19, 51, 139, 87, 315, 831, 2587, 4847, 0 }; + static ulong[] dim655JoeKuoD5Init = { 1, 3, 3, 13, 23, 23, 117, 189, 405, 735, 681, 457, 337, 0 }; + static ulong[] dim656JoeKuoD5Init = { 1, 1, 7, 5, 13, 21, 25, 207, 179, 715, 629, 593, 6351, 0 }; + static ulong[] dim657JoeKuoD5Init = { 1, 3, 3, 3, 25, 13, 31, 245, 147, 953, 1061, 3749, 6927, 0 }; + static ulong[] dim658JoeKuoD5Init = { 1, 3, 3, 9, 29, 27, 57, 5, 345, 471, 599, 3677, 1801, 0 }; + static ulong[] dim659JoeKuoD5Init = { 1, 1, 3, 5, 21, 47, 27, 21, 473, 881, 1973, 995, 6513, 0 }; + static ulong[] dim660JoeKuoD5Init = { 1, 1, 3, 7, 23, 1, 19, 197, 43, 955, 1503, 2825, 7241, 0 }; + static ulong[] dim661JoeKuoD5Init = { 1, 3, 7, 13, 5, 51, 51, 33, 349, 835, 1367, 1913, 1963, 0 }; + static ulong[] dim662JoeKuoD5Init = { 1, 1, 5, 5, 19, 63, 9, 145, 335, 843, 655, 1049, 3421, 0 }; + static ulong[] dim663JoeKuoD5Init = { 1, 1, 7, 1, 1, 33, 1, 9, 35, 833, 629, 3453, 6341, 0 }; + static ulong[] dim664JoeKuoD5Init = { 1, 3, 5, 11, 3, 55, 119, 87, 441, 43, 169, 761, 753, 0 }; + static ulong[] dim665JoeKuoD5Init = { 1, 3, 7, 5, 17, 11, 87, 165, 421, 1005, 1227, 3381, 1005, 0 }; + static ulong[] dim666JoeKuoD5Init = { 1, 3, 3, 13, 17, 19, 63, 71, 251, 355, 1127, 2575, 1193, 0 }; + static ulong[] dim667JoeKuoD5Init = { 1, 1, 7, 13, 9, 23, 71, 173, 421, 179, 1899, 2507, 8083, 0 }; + static ulong[] dim668JoeKuoD5Init = { 1, 1, 3, 15, 1, 13, 81, 169, 85, 957, 1109, 2767, 447, 0 }; + static ulong[] dim669JoeKuoD5Init = { 1, 3, 7, 15, 19, 41, 61, 247, 325, 273, 469, 1859, 6869, 0 }; + static ulong[] dim670JoeKuoD5Init = { 1, 1, 1, 9, 15, 3, 3, 119, 377, 579, 1155, 325, 143, 0 }; + static ulong[] dim671JoeKuoD5Init = { 1, 1, 3, 11, 31, 1, 43, 135, 375, 383, 1497, 2759, 43, 0 }; + static ulong[] dim672JoeKuoD5Init = { 1, 1, 5, 5, 1, 63, 75, 179, 447, 113, 1037, 631, 4969, 0 }; + static ulong[] dim673JoeKuoD5Init = { 1, 3, 3, 13, 13, 61, 63, 229, 85, 223, 153, 3987, 4685, 0 }; + static ulong[] dim674JoeKuoD5Init = { 1, 1, 7, 13, 17, 33, 17, 247, 399, 559, 369, 1525, 4923, 0 }; + static ulong[] dim675JoeKuoD5Init = { 1, 3, 3, 13, 1, 63, 69, 167, 407, 191, 499, 1697, 3267, 0 }; + static ulong[] dim676JoeKuoD5Init = { 1, 1, 5, 9, 31, 15, 97, 183, 165, 271, 1465, 931, 4061, 0 }; + static ulong[] dim677JoeKuoD5Init = { 1, 3, 3, 1, 31, 7, 121, 37, 429, 375, 1539, 1383, 7317, 0 }; + static ulong[] dim678JoeKuoD5Init = { 1, 1, 5, 9, 13, 41, 49, 205, 233, 847, 187, 359, 2341, 0 }; + static ulong[] dim679JoeKuoD5Init = { 1, 1, 3, 5, 25, 5, 57, 119, 79, 131, 1707, 1601, 1657, 0 }; + static ulong[] dim680JoeKuoD5Init = { 1, 1, 5, 9, 21, 11, 89, 149, 369, 401, 623, 3001, 85, 0 }; + static ulong[] dim681JoeKuoD5Init = { 1, 3, 5, 15, 31, 9, 109, 33, 31, 93, 2035, 3785, 5893, 0 }; + static ulong[] dim682JoeKuoD5Init = { 1, 3, 3, 3, 31, 57, 15, 161, 333, 559, 1487, 1037, 1055, 0 }; + static ulong[] dim683JoeKuoD5Init = { 1, 3, 5, 13, 7, 9, 7, 109, 151, 629, 295, 105, 1121, 0 }; + static ulong[] dim684JoeKuoD5Init = { 1, 3, 7, 3, 7, 25, 49, 5, 95, 321, 303, 2571, 6967, 0 }; + static ulong[] dim685JoeKuoD5Init = { 1, 1, 5, 3, 27, 13, 65, 27, 507, 847, 155, 3183, 5985, 0 }; + static ulong[] dim686JoeKuoD5Init = { 1, 3, 7, 9, 17, 29, 69, 23, 181, 855, 1659, 889, 1273, 0 }; + static ulong[] dim687JoeKuoD5Init = { 1, 1, 3, 5, 19, 41, 109, 97, 373, 591, 1715, 3927, 3101, 0 }; + static ulong[] dim688JoeKuoD5Init = { 1, 1, 3, 3, 9, 9, 75, 63, 1, 39, 941, 3677, 7253, 0 }; + static ulong[] dim689JoeKuoD5Init = { 1, 1, 1, 11, 27, 37, 25, 33, 213, 917, 2037, 145, 4395, 0 }; + static ulong[] dim690JoeKuoD5Init = { 1, 3, 7, 11, 23, 21, 15, 195, 87, 699, 1475, 429, 1641, 0 }; + static ulong[] dim691JoeKuoD5Init = { 1, 3, 3, 1, 1, 51, 117, 13, 369, 711, 625, 3171, 1867, 0 }; + static ulong[] dim692JoeKuoD5Init = { 1, 1, 1, 15, 23, 11, 47, 177, 511, 709, 255, 2355, 71, 0 }; + static ulong[] dim693JoeKuoD5Init = { 1, 1, 1, 9, 7, 21, 21, 35, 303, 105, 525, 589, 5449, 0 }; + static ulong[] dim694JoeKuoD5Init = { 1, 3, 7, 7, 21, 27, 71, 177, 205, 143, 385, 2949, 8169, 0 }; + static ulong[] dim695JoeKuoD5Init = { 1, 1, 3, 9, 19, 39, 79, 241, 103, 489, 1399, 2781, 5533, 0 }; + static ulong[] dim696JoeKuoD5Init = { 1, 1, 3, 5, 23, 9, 121, 51, 145, 927, 1457, 1891, 7475, 0 }; + static ulong[] dim697JoeKuoD5Init = { 1, 3, 7, 1, 7, 23, 67, 145, 161, 63, 569, 395, 6719, 0 }; + static ulong[] dim698JoeKuoD5Init = { 1, 3, 7, 11, 5, 31, 13, 9, 135, 367, 1591, 1963, 7249, 0 }; + static ulong[] dim699JoeKuoD5Init = { 1, 3, 5, 13, 7, 47, 119, 195, 439, 619, 551, 1955, 6913, 0 }; + static ulong[] dim700JoeKuoD5Init = { 1, 3, 1, 1, 29, 57, 43, 213, 113, 339, 1943, 183, 3063, 0 }; + static ulong[] dim701JoeKuoD5Init = { 1, 3, 1, 11, 1, 3, 57, 149, 495, 547, 603, 907, 1349, 0 }; + static ulong[] dim702JoeKuoD5Init = { 1, 3, 1, 7, 7, 31, 87, 49, 239, 827, 1451, 3171, 287, 0 }; + static ulong[] dim703JoeKuoD5Init = { 1, 3, 1, 15, 11, 41, 29, 233, 101, 573, 737, 3813, 7739, 0 }; + static ulong[] dim704JoeKuoD5Init = { 1, 1, 7, 9, 19, 13, 57, 177, 259, 595, 263, 2851, 5771, 0 }; + static ulong[] dim705JoeKuoD5Init = { 1, 1, 3, 13, 13, 5, 27, 133, 17, 725, 417, 2277, 5649, 0 }; + static ulong[] dim706JoeKuoD5Init = { 1, 1, 3, 13, 25, 57, 35, 229, 253, 761, 275, 2519, 7061, 0 }; + static ulong[] dim707JoeKuoD5Init = { 1, 3, 1, 13, 9, 31, 61, 181, 129, 259, 1569, 817, 4665, 0 }; + static ulong[] dim708JoeKuoD5Init = { 1, 1, 1, 5, 23, 3, 69, 161, 429, 143, 455, 905, 3337, 0 }; + static ulong[] dim709JoeKuoD5Init = { 1, 3, 3, 3, 21, 33, 81, 187, 481, 481, 1947, 3563, 4797, 0 }; + static ulong[] dim710JoeKuoD5Init = { 1, 1, 3, 7, 15, 35, 23, 187, 455, 535, 85, 1067, 1793, 0 }; + static ulong[] dim711JoeKuoD5Init = { 1, 3, 5, 3, 11, 17, 89, 255, 443, 791, 1617, 2979, 1357, 0 }; + static ulong[] dim712JoeKuoD5Init = { 1, 3, 3, 15, 17, 49, 1, 233, 3, 587, 1203, 3185, 1173, 0 }; + static ulong[] dim713JoeKuoD5Init = { 1, 1, 3, 9, 5, 53, 37, 13, 47, 1011, 1589, 1073, 5445, 0 }; + static ulong[] dim714JoeKuoD5Init = { 1, 1, 5, 1, 15, 43, 85, 167, 347, 935, 1681, 261, 3623, 0 }; + static ulong[] dim715JoeKuoD5Init = { 1, 1, 3, 3, 3, 31, 121, 241, 129, 555, 1737, 3557, 6515, 0 }; + static ulong[] dim716JoeKuoD5Init = { 1, 3, 1, 15, 25, 7, 125, 105, 13, 927, 1929, 3869, 7429, 0 }; + static ulong[] dim717JoeKuoD5Init = { 1, 3, 5, 1, 31, 47, 3, 29, 149, 827, 771, 2113, 1607, 0 }; + static ulong[] dim718JoeKuoD5Init = { 1, 3, 5, 1, 17, 17, 65, 247, 109, 613, 1975, 2393, 6057, 0 }; + static ulong[] dim719JoeKuoD5Init = { 1, 3, 1, 7, 9, 43, 41, 119, 335, 533, 1053, 1343, 6529, 0 }; + static ulong[] dim720JoeKuoD5Init = { 1, 3, 3, 1, 31, 59, 85, 247, 485, 811, 749, 89, 6677, 0 }; + static ulong[] dim721JoeKuoD5Init = { 1, 1, 7, 13, 7, 47, 77, 193, 25, 27, 639, 109, 6455, 0 }; + static ulong[] dim722JoeKuoD5Init = { 1, 1, 7, 1, 15, 63, 17, 81, 425, 403, 1537, 3205, 6237, 0 }; + static ulong[] dim723JoeKuoD5Init = { 1, 3, 5, 9, 21, 29, 105, 135, 407, 119, 793, 559, 973, 0 }; + static ulong[] dim724JoeKuoD5Init = { 1, 3, 3, 15, 1, 31, 45, 97, 511, 463, 1923, 2487, 1311, 0 }; + static ulong[] dim725JoeKuoD5Init = { 1, 1, 3, 11, 13, 53, 91, 149, 441, 841, 1121, 3305, 975, 0 }; + static ulong[] dim726JoeKuoD5Init = { 1, 1, 3, 15, 5, 55, 81, 181, 333, 63, 1157, 2831, 6231, 0 }; + static ulong[] dim727JoeKuoD5Init = { 1, 1, 3, 15, 29, 21, 69, 87, 41, 623, 475, 723, 5693, 0 }; + static ulong[] dim728JoeKuoD5Init = { 1, 3, 1, 5, 23, 19, 15, 25, 269, 79, 1699, 691, 525, 0 }; + static ulong[] dim729JoeKuoD5Init = { 1, 3, 1, 1, 29, 23, 85, 5, 431, 649, 1187, 3503, 105, 0 }; + static ulong[] dim730JoeKuoD5Init = { 1, 1, 1, 1, 27, 59, 1, 81, 351, 383, 1167, 3747, 5935, 0 }; + static ulong[] dim731JoeKuoD5Init = { 1, 1, 1, 13, 21, 49, 93, 5, 471, 231, 1469, 1089, 5059, 0 }; + static ulong[] dim732JoeKuoD5Init = { 1, 3, 1, 11, 31, 61, 117, 161, 307, 621, 1713, 1325, 283, 0 }; + static ulong[] dim733JoeKuoD5Init = { 1, 3, 1, 7, 21, 35, 7, 79, 157, 723, 57, 25, 2789, 0 }; + static ulong[] dim734JoeKuoD5Init = { 1, 3, 5, 13, 9, 47, 97, 1, 257, 941, 553, 3811, 3775, 0 }; + static ulong[] dim735JoeKuoD5Init = { 1, 3, 3, 13, 19, 5, 73, 233, 289, 241, 175, 2831, 4613, 0 }; + static ulong[] dim736JoeKuoD5Init = { 1, 1, 1, 9, 11, 61, 1, 245, 223, 641, 77, 1811, 3459, 0 }; + static ulong[] dim737JoeKuoD5Init = { 1, 1, 7, 1, 21, 41, 9, 175, 377, 331, 1615, 325, 5413, 0 }; + static ulong[] dim738JoeKuoD5Init = { 1, 1, 1, 3, 23, 57, 99, 161, 127, 47, 1923, 165, 2123, 0 }; + static ulong[] dim739JoeKuoD5Init = { 1, 1, 5, 15, 11, 15, 77, 15, 323, 919, 1001, 377, 6095, 0 }; + static ulong[] dim740JoeKuoD5Init = { 1, 1, 7, 7, 25, 47, 5, 25, 197, 811, 179, 215, 5393, 0 }; + static ulong[] dim741JoeKuoD5Init = { 1, 3, 5, 11, 29, 37, 7, 125, 3, 7, 1881, 3823, 2117, 0 }; + static ulong[] dim742JoeKuoD5Init = { 1, 3, 7, 3, 9, 61, 97, 233, 233, 603, 511, 17, 2081, 0 }; + static ulong[] dim743JoeKuoD5Init = { 1, 3, 5, 9, 15, 35, 73, 199, 113, 575, 537, 883, 6897, 0 }; + static ulong[] dim744JoeKuoD5Init = { 1, 1, 3, 9, 17, 63, 7, 181, 261, 719, 591, 2575, 1065, 0 }; + static ulong[] dim745JoeKuoD5Init = { 1, 1, 7, 1, 13, 15, 1, 207, 385, 277, 547, 1069, 6421, 0 }; + static ulong[] dim746JoeKuoD5Init = { 1, 3, 7, 3, 5, 3, 43, 213, 509, 969, 1799, 3519, 7759, 0 }; + static ulong[] dim747JoeKuoD5Init = { 1, 3, 7, 15, 29, 51, 87, 63, 257, 1001, 741, 1747, 975, 0 }; + static ulong[] dim748JoeKuoD5Init = { 1, 3, 1, 15, 5, 27, 7, 27, 493, 817, 319, 1435, 3243, 0 }; + static ulong[] dim749JoeKuoD5Init = { 1, 3, 3, 15, 5, 9, 113, 153, 397, 63, 2037, 3319, 6355, 0 }; + static ulong[] dim750JoeKuoD5Init = { 1, 1, 1, 1, 29, 9, 97, 171, 113, 729, 1939, 2741, 4699, 0 }; + static ulong[] dim751JoeKuoD5Init = { 1, 1, 1, 11, 29, 3, 49, 183, 69, 313, 153, 2757, 3353, 0 }; + static ulong[] dim752JoeKuoD5Init = { 1, 1, 7, 7, 5, 39, 65, 65, 405, 301, 849, 1211, 3627, 0 }; + static ulong[] dim753JoeKuoD5Init = { 1, 1, 5, 13, 19, 11, 81, 181, 471, 669, 139, 4019, 4057, 0 }; + static ulong[] dim754JoeKuoD5Init = { 1, 3, 3, 13, 3, 31, 125, 229, 181, 913, 2035, 2081, 6573, 0 }; + static ulong[] dim755JoeKuoD5Init = { 1, 1, 1, 5, 13, 25, 37, 209, 255, 761, 1485, 2833, 6617, 0 }; + static ulong[] dim756JoeKuoD5Init = { 1, 1, 5, 7, 29, 17, 55, 59, 337, 953, 775, 3865, 5671, 0 }; + static ulong[] dim757JoeKuoD5Init = { 1, 1, 7, 13, 15, 37, 109, 93, 303, 57, 1727, 615, 3337, 0 }; + static ulong[] dim758JoeKuoD5Init = { 1, 1, 1, 13, 31, 57, 119, 57, 295, 707, 1409, 3769, 6359, 0 }; + static ulong[] dim759JoeKuoD5Init = { 1, 3, 1, 5, 31, 25, 35, 191, 27, 463, 875, 129, 3829, 0 }; + static ulong[] dim760JoeKuoD5Init = { 1, 1, 5, 13, 19, 29, 95, 227, 487, 519, 289, 965, 2121, 0 }; + static ulong[] dim761JoeKuoD5Init = { 1, 3, 5, 5, 21, 37, 7, 43, 213, 673, 25, 1911, 7229, 0 }; + static ulong[] dim762JoeKuoD5Init = { 1, 1, 1, 5, 9, 55, 115, 155, 119, 49, 653, 3425, 299, 0 }; + static ulong[] dim763JoeKuoD5Init = { 1, 1, 1, 11, 7, 55, 65, 21, 93, 295, 1097, 145, 3401, 0 }; + static ulong[] dim764JoeKuoD5Init = { 1, 3, 3, 3, 1, 19, 109, 247, 499, 391, 309, 59, 695, 0 }; + static ulong[] dim765JoeKuoD5Init = { 1, 1, 5, 5, 9, 37, 113, 233, 57, 955, 437, 775, 2673, 0 }; + static ulong[] dim766JoeKuoD5Init = { 1, 3, 7, 3, 5, 27, 57, 53, 149, 929, 41, 1473, 4751, 0 }; + static ulong[] dim767JoeKuoD5Init = { 1, 1, 7, 11, 5, 3, 107, 57, 3, 727, 2001, 3463, 4753, 0 }; + static ulong[] dim768JoeKuoD5Init = { 1, 1, 1, 11, 3, 37, 111, 97, 225, 809, 135, 2049, 2373, 0 }; + static ulong[] dim769JoeKuoD5Init = { 1, 3, 5, 15, 3, 37, 57, 153, 175, 851, 137, 495, 4423, 0 }; + static ulong[] dim770JoeKuoD5Init = { 1, 3, 3, 7, 25, 31, 53, 51, 421, 33, 1241, 2157, 867, 0 }; + static ulong[] dim771JoeKuoD5Init = { 1, 1, 1, 13, 3, 33, 15, 77, 73, 51, 1131, 3387, 7935, 0 }; + static ulong[] dim772JoeKuoD5Init = { 1, 1, 5, 9, 11, 25, 27, 235, 341, 133, 261, 2087, 4079, 0 }; + static ulong[] dim773JoeKuoD5Init = { 1, 3, 3, 13, 11, 63, 33, 99, 65, 485, 561, 2269, 8143, 0 }; + static ulong[] dim774JoeKuoD5Init = { 1, 3, 3, 5, 13, 25, 53, 65, 59, 861, 1705, 627, 1097, 0 }; + static ulong[] dim775JoeKuoD5Init = { 1, 3, 1, 3, 25, 15, 67, 187, 161, 747, 947, 4029, 7547, 0 }; + static ulong[] dim776JoeKuoD5Init = { 1, 3, 3, 5, 7, 27, 119, 239, 197, 165, 457, 1927, 6195, 0 }; + static ulong[] dim777JoeKuoD5Init = { 1, 3, 3, 7, 27, 21, 23, 93, 319, 551, 1317, 69, 6735, 0 }; + static ulong[] dim778JoeKuoD5Init = { 1, 1, 5, 11, 25, 45, 23, 127, 327, 949, 1451, 2245, 6705, 0 }; + static ulong[] dim779JoeKuoD5Init = { 1, 1, 1, 15, 19, 23, 69, 113, 53, 215, 1505, 1255, 5063, 0 }; + static ulong[] dim780JoeKuoD5Init = { 1, 3, 3, 9, 7, 19, 39, 135, 437, 251, 1947, 2219, 4015, 0 }; + static ulong[] dim781JoeKuoD5Init = { 1, 3, 7, 3, 23, 39, 91, 111, 395, 545, 179, 937, 2531, 0 }; + static ulong[] dim782JoeKuoD5Init = { 1, 3, 7, 11, 1, 53, 113, 137, 131, 461, 151, 1617, 6399, 0 }; + static ulong[] dim783JoeKuoD5Init = { 1, 1, 3, 3, 13, 3, 75, 31, 175, 773, 1293, 625, 6563, 0 }; + static ulong[] dim784JoeKuoD5Init = { 1, 1, 3, 15, 9, 51, 87, 223, 405, 751, 1053, 1431, 4701, 0 }; + static ulong[] dim785JoeKuoD5Init = { 1, 1, 3, 13, 21, 21, 111, 145, 311, 733, 635, 1369, 297, 0 }; + static ulong[] dim786JoeKuoD5Init = { 1, 1, 1, 7, 25, 5, 23, 201, 179, 593, 1531, 1197, 3525, 0 }; + static ulong[] dim787JoeKuoD5Init = { 1, 1, 5, 13, 7, 17, 19, 247, 401, 15, 93, 245, 5987, 0 }; + static ulong[] dim788JoeKuoD5Init = { 1, 3, 3, 11, 7, 45, 119, 99, 197, 163, 637, 3143, 1775, 0 }; + static ulong[] dim789JoeKuoD5Init = { 1, 1, 3, 3, 17, 7, 35, 121, 155, 925, 1001, 2941, 107, 0 }; + static ulong[] dim790JoeKuoD5Init = { 1, 3, 7, 15, 15, 3, 89, 205, 171, 279, 763, 2343, 7825, 0 }; + static ulong[] dim791JoeKuoD5Init = { 1, 3, 1, 15, 15, 3, 113, 135, 159, 217, 139, 167, 589, 0 }; + static ulong[] dim792JoeKuoD5Init = { 1, 3, 3, 1, 31, 59, 89, 3, 261, 953, 1527, 447, 1211, 0 }; + static ulong[] dim793JoeKuoD5Init = { 1, 1, 5, 9, 31, 39, 93, 171, 497, 657, 809, 2905, 2399, 0 }; + static ulong[] dim794JoeKuoD5Init = { 1, 1, 5, 15, 27, 19, 25, 179, 293, 829, 1197, 3077, 6631, 0 }; + static ulong[] dim795JoeKuoD5Init = { 1, 1, 1, 7, 31, 55, 53, 177, 157, 619, 197, 3675, 4691, 0 }; + static ulong[] dim796JoeKuoD5Init = { 1, 3, 7, 5, 7, 33, 85, 59, 435, 653, 1363, 731, 3923, 0 }; + static ulong[] dim797JoeKuoD5Init = { 1, 3, 3, 3, 15, 35, 15, 217, 333, 717, 143, 4071, 4769, 0 }; + static ulong[] dim798JoeKuoD5Init = { 1, 1, 5, 7, 23, 31, 65, 77, 261, 389, 1733, 4077, 3387, 0 }; + static ulong[] dim799JoeKuoD5Init = { 1, 1, 7, 9, 21, 45, 21, 103, 163, 237, 1447, 141, 3995, 0 }; + static ulong[] dim800JoeKuoD5Init = { 1, 1, 3, 3, 27, 35, 61, 149, 359, 131, 1309, 3283, 5905, 0 }; + static ulong[] dim801JoeKuoD5Init = { 1, 3, 1, 15, 9, 15, 99, 43, 115, 871, 419, 2787, 7741, 0 }; + static ulong[] dim802JoeKuoD5Init = { 1, 3, 7, 5, 1, 45, 31, 87, 165, 103, 2041, 1529, 5721, 0 }; + static ulong[] dim803JoeKuoD5Init = { 1, 3, 5, 15, 3, 11, 107, 9, 367, 401, 1571, 2657, 4745, 0 }; + static ulong[] dim804JoeKuoD5Init = { 1, 1, 5, 13, 31, 51, 35, 53, 131, 441, 1421, 2367, 7713, 0 }; + static ulong[] dim805JoeKuoD5Init = { 1, 3, 1, 5, 21, 49, 109, 117, 263, 827, 1975, 2639, 1249, 0 }; + static ulong[] dim806JoeKuoD5Init = { 1, 1, 5, 13, 7, 3, 87, 185, 493, 721, 1363, 2201, 1067, 0 }; + static ulong[] dim807JoeKuoD5Init = { 1, 1, 3, 5, 13, 41, 113, 105, 111, 65, 705, 4079, 2461, 0 }; + static ulong[] dim808JoeKuoD5Init = { 1, 1, 7, 13, 9, 1, 75, 103, 181, 587, 1531, 461, 6551, 0 }; + static ulong[] dim809JoeKuoD5Init = { 1, 1, 7, 11, 13, 43, 19, 131, 233, 209, 175, 625, 985, 0 }; + static ulong[] dim810JoeKuoD5Init = { 1, 1, 1, 11, 23, 1, 87, 233, 355, 765, 869, 2569, 5919, 0 }; + static ulong[] dim811JoeKuoD5Init = { 1, 1, 7, 5, 13, 27, 41, 127, 105, 299, 189, 3801, 4677, 0 }; + static ulong[] dim812JoeKuoD5Init = { 1, 3, 3, 13, 21, 49, 111, 95, 27, 433, 1715, 1167, 4943, 0 }; + static ulong[] dim813JoeKuoD5Init = { 1, 3, 1, 11, 5, 17, 93, 91, 79, 355, 111, 1159, 4629, 0 }; + static ulong[] dim814JoeKuoD5Init = { 1, 1, 7, 1, 29, 43, 107, 91, 111, 813, 537, 97, 5337, 0 }; + static ulong[] dim815JoeKuoD5Init = { 1, 3, 3, 5, 27, 1, 69, 181, 247, 51, 409, 1965, 4709, 0 }; + static ulong[] dim816JoeKuoD5Init = { 1, 3, 5, 1, 7, 53, 119, 109, 331, 189, 761, 385, 5227, 0 }; + static ulong[] dim817JoeKuoD5Init = { 1, 3, 5, 15, 5, 61, 57, 3, 157, 737, 1605, 3701, 1069, 0 }; + static ulong[] dim818JoeKuoD5Init = { 1, 3, 5, 1, 17, 27, 89, 235, 53, 521, 1975, 1383, 467, 0 }; + static ulong[] dim819JoeKuoD5Init = { 1, 1, 3, 7, 25, 25, 39, 149, 157, 385, 1651, 105, 1487, 0 }; + static ulong[] dim820JoeKuoD5Init = { 1, 3, 3, 7, 15, 43, 37, 167, 303, 655, 331, 1595, 5405, 0 }; + static ulong[] dim821JoeKuoD5Init = { 1, 3, 7, 9, 13, 29, 13, 163, 405, 903, 1277, 985, 1479, 0 }; + static ulong[] dim822JoeKuoD5Init = { 1, 1, 7, 13, 1, 7, 61, 9, 163, 67, 209, 1923, 6587, 0 }; + static ulong[] dim823JoeKuoD5Init = { 1, 1, 5, 15, 13, 3, 99, 177, 507, 1017, 1565, 757, 5829, 0 }; + static ulong[] dim824JoeKuoD5Init = { 1, 3, 5, 11, 7, 49, 51, 71, 177, 1015, 1321, 187, 875, 0 }; + static ulong[] dim825JoeKuoD5Init = { 1, 1, 7, 1, 29, 49, 111, 143, 99, 297, 659, 3147, 7531, 0 }; + static ulong[] dim826JoeKuoD5Init = { 1, 1, 5, 3, 15, 21, 11, 229, 249, 185, 147, 173, 7895, 0 }; + static ulong[] dim827JoeKuoD5Init = { 1, 1, 7, 1, 17, 23, 123, 157, 373, 501, 411, 2487, 4873, 0 }; + static ulong[] dim828JoeKuoD5Init = { 1, 3, 7, 11, 21, 61, 83, 65, 345, 105, 1533, 981, 1635, 0 }; + static ulong[] dim829JoeKuoD5Init = { 1, 3, 3, 1, 15, 15, 19, 119, 59, 1003, 1595, 2871, 627, 0 }; + static ulong[] dim830JoeKuoD5Init = { 1, 1, 7, 3, 7, 47, 43, 3, 359, 175, 1149, 213, 79, 0 }; + static ulong[] dim831JoeKuoD5Init = { 1, 1, 1, 1, 5, 19, 7, 93, 335, 809, 1867, 1359, 1017, 0 }; + static ulong[] dim832JoeKuoD5Init = { 1, 1, 1, 11, 31, 25, 75, 139, 125, 479, 101, 3969, 1173, 0 }; + static ulong[] dim833JoeKuoD5Init = { 1, 3, 1, 3, 5, 17, 33, 145, 57, 31, 1033, 3975, 5561, 0 }; + static ulong[] dim834JoeKuoD5Init = { 1, 3, 7, 3, 31, 37, 47, 149, 341, 663, 303, 3395, 4327, 0 }; + static ulong[] dim835JoeKuoD5Init = { 1, 3, 5, 1, 31, 31, 37, 207, 189, 435, 347, 2791, 2203, 0 }; + static ulong[] dim836JoeKuoD5Init = { 1, 1, 7, 5, 3, 61, 71, 199, 207, 261, 27, 2281, 6215, 0 }; + static ulong[] dim837JoeKuoD5Init = { 1, 3, 3, 13, 19, 61, 51, 99, 279, 535, 473, 2233, 5637, 0 }; + static ulong[] dim838JoeKuoD5Init = { 1, 3, 5, 15, 7, 51, 25, 159, 63, 611, 1015, 3561, 5763, 0 }; + static ulong[] dim839JoeKuoD5Init = { 1, 3, 1, 7, 9, 13, 101, 13, 203, 733, 1657, 919, 7857, 0 }; + static ulong[] dim840JoeKuoD5Init = { 1, 3, 1, 9, 5, 7, 105, 137, 321, 817, 467, 4043, 603, 0 }; + static ulong[] dim841JoeKuoD5Init = { 1, 1, 7, 9, 5, 7, 105, 93, 295, 617, 713, 3075, 1839, 0 }; + static ulong[] dim842JoeKuoD5Init = { 1, 3, 3, 5, 11, 17, 89, 229, 417, 53, 693, 2101, 1293, 0 }; + static ulong[] dim843JoeKuoD5Init = { 1, 3, 7, 5, 3, 57, 95, 175, 161, 291, 219, 3101, 3387, 0 }; + static ulong[] dim844JoeKuoD5Init = { 1, 3, 1, 3, 25, 53, 89, 7, 9, 863, 675, 1011, 1753, 0 }; + static ulong[] dim845JoeKuoD5Init = { 1, 1, 5, 15, 13, 41, 57, 141, 109, 541, 387, 3805, 2219, 0 }; + static ulong[] dim846JoeKuoD5Init = { 1, 3, 7, 11, 19, 45, 45, 63, 283, 277, 1503, 3909, 4825, 0 }; + static ulong[] dim847JoeKuoD5Init = { 1, 3, 5, 13, 11, 27, 33, 245, 335, 785, 1651, 2503, 7247, 0 }; + static ulong[] dim848JoeKuoD5Init = { 1, 1, 3, 5, 19, 3, 29, 9, 259, 1023, 71, 3659, 3615, 0 }; + static ulong[] dim849JoeKuoD5Init = { 1, 3, 7, 9, 29, 41, 59, 137, 139, 193, 267, 3293, 4769, 0 }; + static ulong[] dim850JoeKuoD5Init = { 1, 3, 1, 5, 21, 29, 107, 227, 107, 929, 1009, 2013, 2791, 0 }; + static ulong[] dim851JoeKuoD5Init = { 1, 1, 3, 7, 25, 61, 105, 159, 125, 873, 293, 1475, 1745, 0 }; + static ulong[] dim852JoeKuoD5Init = { 1, 3, 1, 5, 13, 11, 63, 109, 329, 847, 521, 3045, 2673, 0 }; + static ulong[] dim853JoeKuoD5Init = { 1, 3, 7, 1, 21, 1, 15, 161, 369, 339, 417, 3165, 5047, 0 }; + static ulong[] dim854JoeKuoD5Init = { 1, 1, 1, 9, 31, 61, 109, 25, 491, 969, 1369, 403, 835, 0 }; + static ulong[] dim855JoeKuoD5Init = { 1, 1, 1, 9, 29, 29, 27, 55, 395, 979, 27, 3091, 2383, 0 }; + static ulong[] dim856JoeKuoD5Init = { 1, 1, 7, 1, 25, 17, 73, 117, 55, 381, 641, 2549, 7049, 0 }; + static ulong[] dim857JoeKuoD5Init = { 1, 3, 7, 11, 17, 5, 97, 89, 187, 973, 1343, 3777, 3549, 0 }; + static ulong[] dim858JoeKuoD5Init = { 1, 1, 7, 1, 9, 51, 49, 169, 135, 827, 1941, 3421, 2351, 0 }; + static ulong[] dim859JoeKuoD5Init = { 1, 1, 1, 11, 25, 59, 9, 63, 259, 551, 983, 2743, 3439, 0 }; + static ulong[] dim860JoeKuoD5Init = { 1, 3, 1, 5, 1, 55, 19, 35, 39, 629, 1601, 773, 3697, 0 }; + static ulong[] dim861JoeKuoD5Init = { 1, 1, 7, 7, 17, 59, 55, 201, 467, 945, 707, 2197, 6907, 0 }; + static ulong[] dim862JoeKuoD5Init = { 1, 1, 1, 15, 11, 9, 1, 87, 299, 509, 117, 3249, 3811, 0 }; + static ulong[] dim863JoeKuoD5Init = { 1, 3, 5, 7, 23, 35, 43, 129, 357, 501, 837, 305, 7967, 0 }; + static ulong[] dim864JoeKuoD5Init = { 1, 1, 5, 1, 23, 45, 85, 245, 157, 193, 215, 1021, 5115, 0 }; + static ulong[] dim865JoeKuoD5Init = { 1, 3, 1, 9, 5, 47, 125, 27, 295, 407, 1601, 859, 1203, 0 }; + static ulong[] dim866JoeKuoD5Init = { 1, 3, 5, 7, 21, 3, 23, 141, 75, 841, 199, 2719, 2131, 0 }; + static ulong[] dim867JoeKuoD5Init = { 1, 3, 1, 1, 3, 7, 35, 227, 275, 37, 523, 2849, 4363, 0 }; + static ulong[] dim868JoeKuoD5Init = { 1, 3, 7, 9, 5, 39, 95, 77, 201, 891, 339, 375, 7115, 0 }; + static ulong[] dim869JoeKuoD5Init = { 1, 1, 3, 3, 3, 57, 57, 49, 305, 141, 1149, 3909, 6981, 0 }; + static ulong[] dim870JoeKuoD5Init = { 1, 3, 3, 7, 19, 17, 53, 31, 233, 317, 1541, 235, 1831, 0 }; + static ulong[] dim871JoeKuoD5Init = { 1, 1, 7, 5, 7, 63, 125, 169, 141, 399, 277, 1417, 7989, 0 }; + static ulong[] dim872JoeKuoD5Init = { 1, 1, 1, 1, 17, 61, 89, 11, 411, 505, 1191, 2651, 1175, 0 }; + static ulong[] dim873JoeKuoD5Init = { 1, 1, 3, 1, 11, 41, 39, 69, 279, 229, 1247, 1001, 7163, 0 }; + static ulong[] dim874JoeKuoD5Init = { 1, 1, 1, 5, 13, 29, 115, 51, 79, 57, 315, 173, 5875, 0 }; + static ulong[] dim875JoeKuoD5Init = { 1, 3, 5, 5, 1, 43, 121, 5, 99, 451, 1121, 425, 4581, 0 }; + static ulong[] dim876JoeKuoD5Init = { 1, 3, 5, 5, 19, 5, 101, 33, 19, 5, 1325, 3527, 1733, 0 }; + static ulong[] dim877JoeKuoD5Init = { 1, 1, 7, 7, 15, 35, 91, 141, 127, 1005, 459, 3707, 6551, 0 }; + static ulong[] dim878JoeKuoD5Init = { 1, 3, 5, 11, 15, 27, 31, 49, 153, 337, 1235, 2063, 211, 0 }; + static ulong[] dim879JoeKuoD5Init = { 1, 3, 5, 3, 25, 45, 17, 233, 161, 559, 1687, 3833, 5451, 0 }; + static ulong[] dim880JoeKuoD5Init = { 1, 1, 7, 13, 23, 39, 127, 183, 379, 655, 129, 37, 2283, 0 }; + static ulong[] dim881JoeKuoD5Init = { 1, 3, 5, 13, 23, 33, 35, 111, 491, 343, 1771, 509, 937, 0 }; + static ulong[] dim882JoeKuoD5Init = { 1, 1, 1, 3, 19, 59, 59, 79, 327, 911, 1103, 2695, 3673, 0 }; + static ulong[] dim883JoeKuoD5Init = { 1, 1, 3, 5, 11, 23, 43, 31, 455, 843, 1515, 3059, 505, 0 }; + static ulong[] dim884JoeKuoD5Init = { 1, 3, 3, 7, 15, 1, 63, 35, 327, 801, 237, 1137, 3447, 0 }; + static ulong[] dim885JoeKuoD5Init = { 1, 3, 5, 1, 7, 35, 105, 113, 281, 153, 461, 3165, 659, 0 }; + static ulong[] dim886JoeKuoD5Init = { 1, 1, 3, 13, 29, 5, 119, 45, 313, 713, 1989, 99, 883, 0 }; + static ulong[] dim887JoeKuoD5Init = { 1, 1, 7, 15, 17, 43, 115, 201, 51, 947, 1271, 2465, 5319, 0 }; + static ulong[] dim888JoeKuoD5Init = { 1, 3, 5, 11, 25, 39, 49, 103, 99, 469, 1777, 33, 7115, 0 }; + static ulong[] dim889JoeKuoD5Init = { 1, 1, 3, 1, 17, 43, 53, 97, 473, 231, 1035, 19, 995, 0 }; + static ulong[] dim890JoeKuoD5Init = { 1, 1, 7, 1, 5, 1, 89, 255, 201, 945, 2017, 3181, 3961, 0 }; + static ulong[] dim891JoeKuoD5Init = { 1, 3, 7, 7, 9, 9, 45, 91, 451, 671, 613, 4051, 1233, 0 }; + static ulong[] dim892JoeKuoD5Init = { 1, 3, 5, 11, 27, 49, 37, 151, 59, 489, 341, 507, 5839, 0 }; + static ulong[] dim893JoeKuoD5Init = { 1, 1, 1, 3, 1, 41, 11, 165, 509, 615, 793, 2741, 7269, 0 }; + static ulong[] dim894JoeKuoD5Init = { 1, 1, 3, 13, 11, 33, 115, 87, 131, 653, 995, 1903, 4449, 0 }; + static ulong[] dim895JoeKuoD5Init = { 1, 1, 3, 11, 27, 41, 49, 211, 229, 797, 469, 839, 5047, 0 }; + static ulong[] dim896JoeKuoD5Init = { 1, 1, 3, 3, 9, 43, 57, 13, 77, 623, 245, 2349, 3611, 0 }; + static ulong[] dim897JoeKuoD5Init = { 1, 3, 5, 11, 23, 31, 101, 3, 355, 739, 1287, 3973, 6923, 0 }; + static ulong[] dim898JoeKuoD5Init = { 1, 3, 5, 5, 17, 61, 83, 75, 329, 849, 645, 3125, 8159, 0 }; + static ulong[] dim899JoeKuoD5Init = { 1, 3, 3, 11, 15, 31, 91, 149, 195, 585, 1415, 119, 6737, 0 }; + static ulong[] dim900JoeKuoD5Init = { 1, 1, 7, 13, 7, 3, 41, 25, 481, 175, 1147, 153, 6483, 0 }; + static ulong[] dim901JoeKuoD5Init = { 1, 1, 3, 1, 29, 59, 11, 225, 275, 299, 1083, 401, 6809, 0 }; + static ulong[] dim902JoeKuoD5Init = { 1, 1, 3, 11, 7, 19, 119, 145, 299, 273, 1571, 627, 6597, 0 }; + static ulong[] dim903JoeKuoD5Init = { 1, 1, 1, 13, 17, 7, 63, 19, 141, 359, 879, 2741, 3139, 0 }; + static ulong[] dim904JoeKuoD5Init = { 1, 1, 7, 15, 9, 19, 45, 127, 511, 767, 47, 2389, 7691, 0 }; + static ulong[] dim905JoeKuoD5Init = { 1, 1, 7, 15, 11, 53, 15, 207, 31, 215, 183, 2745, 4703, 0 }; + static ulong[] dim906JoeKuoD5Init = { 1, 3, 7, 7, 13, 43, 13, 65, 165, 157, 1139, 2417, 547, 0 }; + static ulong[] dim907JoeKuoD5Init = { 1, 3, 7, 7, 29, 29, 45, 165, 401, 327, 119, 1449, 1281, 0 }; + static ulong[] dim908JoeKuoD5Init = { 1, 3, 7, 11, 27, 25, 35, 5, 447, 205, 1487, 4089, 4929, 0 }; + static ulong[] dim909JoeKuoD5Init = { 1, 3, 5, 13, 3, 45, 73, 19, 349, 657, 771, 1029, 5047, 0 }; + static ulong[] dim910JoeKuoD5Init = { 1, 1, 5, 7, 29, 63, 23, 69, 425, 997, 9, 2365, 3279, 0 }; + static ulong[] dim911JoeKuoD5Init = { 1, 1, 1, 1, 7, 31, 47, 205, 29, 851, 1735, 1641, 2623, 0 }; + static ulong[] dim912JoeKuoD5Init = { 1, 3, 5, 11, 25, 33, 73, 109, 183, 357, 1585, 3323, 4993, 0 }; + static ulong[] dim913JoeKuoD5Init = { 1, 3, 5, 15, 13, 53, 43, 61, 137, 127, 1769, 2107, 4025, 0 }; + static ulong[] dim914JoeKuoD5Init = { 1, 3, 3, 7, 25, 59, 93, 57, 391, 155, 1367, 4093, 625, 0 }; + static ulong[] dim915JoeKuoD5Init = { 1, 3, 5, 1, 25, 27, 53, 217, 75, 961, 371, 1281, 6553, 0 }; + static ulong[] dim916JoeKuoD5Init = { 1, 3, 3, 5, 19, 5, 89, 87, 377, 199, 1533, 2219, 2705, 0 }; + static ulong[] dim917JoeKuoD5Init = { 1, 3, 1, 7, 15, 1, 61, 143, 137, 379, 1443, 355, 971, 0 }; + static ulong[] dim918JoeKuoD5Init = { 1, 3, 7, 11, 17, 57, 85, 225, 37, 345, 1509, 597, 5731, 0 }; + static ulong[] dim919JoeKuoD5Init = { 1, 1, 3, 11, 29, 55, 69, 27, 155, 481, 925, 3391, 5277, 0 }; + static ulong[] dim920JoeKuoD5Init = { 1, 1, 7, 9, 15, 19, 25, 5, 109, 83, 635, 3073, 3531, 0 }; + static ulong[] dim921JoeKuoD5Init = { 1, 3, 5, 15, 23, 5, 13, 7, 19, 625, 1481, 1827, 3991, 0 }; + static ulong[] dim922JoeKuoD5Init = { 1, 1, 3, 9, 7, 35, 123, 161, 303, 423, 25, 2467, 3411, 0 }; + static ulong[] dim923JoeKuoD5Init = { 1, 1, 1, 1, 9, 47, 27, 159, 249, 573, 1987, 3449, 7639, 0 }; + static ulong[] dim924JoeKuoD5Init = { 1, 1, 3, 5, 19, 59, 7, 209, 27, 495, 1491, 3217, 1321, 0 }; + static ulong[] dim925JoeKuoD5Init = { 1, 3, 1, 11, 17, 11, 109, 87, 315, 917, 1105, 215, 1295, 0 }; + static ulong[] dim926JoeKuoD5Init = { 1, 3, 5, 9, 25, 11, 77, 81, 453, 871, 1541, 141, 1625, 0 }; + static ulong[] dim927JoeKuoD5Init = { 1, 1, 3, 3, 1, 37, 11, 149, 45, 213, 975, 2557, 4263, 0 }; + static ulong[] dim928JoeKuoD5Init = { 1, 1, 3, 13, 17, 55, 59, 33, 39, 285, 1767, 3687, 7087, 0 }; + static ulong[] dim929JoeKuoD5Init = { 1, 1, 5, 7, 27, 9, 103, 191, 405, 25, 595, 1765, 5695, 0 }; + static ulong[] dim930JoeKuoD5Init = { 1, 3, 1, 7, 31, 27, 29, 195, 355, 199, 1297, 3195, 683, 0 }; + static ulong[] dim931JoeKuoD5Init = { 1, 3, 1, 1, 21, 3, 19, 227, 325, 279, 1593, 613, 7527, 0 }; + static ulong[] dim932JoeKuoD5Init = { 1, 3, 7, 15, 27, 17, 91, 179, 385, 133, 823, 3731, 2957, 0 }; + static ulong[] dim933JoeKuoD5Init = { 1, 1, 1, 7, 13, 9, 1, 137, 347, 67, 287, 1403, 5233, 0 }; + static ulong[] dim934JoeKuoD5Init = { 1, 3, 3, 7, 17, 15, 25, 95, 225, 469, 1585, 2513, 1489, 0 }; + static ulong[] dim935JoeKuoD5Init = { 1, 1, 7, 13, 31, 33, 81, 121, 435, 971, 877, 1603, 373, 0 }; + static ulong[] dim936JoeKuoD5Init = { 1, 1, 3, 9, 7, 31, 29, 27, 135, 181, 549, 1901, 813, 0 }; + static ulong[] dim937JoeKuoD5Init = { 1, 3, 3, 3, 3, 5, 11, 229, 255, 981, 1843, 2785, 2573, 0 }; + static ulong[] dim938JoeKuoD5Init = { 1, 1, 7, 13, 25, 29, 13, 87, 361, 431, 969, 1893, 5257, 0 }; + static ulong[] dim939JoeKuoD5Init = { 1, 1, 3, 3, 21, 53, 99, 243, 313, 681, 655, 2733, 4329, 0 }; + static ulong[] dim940JoeKuoD5Init = { 1, 3, 7, 7, 13, 3, 107, 61, 285, 687, 213, 551, 5039, 0 }; + static ulong[] dim941JoeKuoD5Init = { 1, 3, 1, 3, 9, 47, 99, 239, 313, 975, 1403, 3641, 1951, 0 }; + static ulong[] dim942JoeKuoD5Init = { 1, 1, 1, 3, 19, 43, 77, 139, 357, 973, 977, 369, 2775, 0 }; + static ulong[] dim943JoeKuoD5Init = { 1, 3, 5, 15, 23, 43, 109, 91, 321, 1, 1917, 3341, 1441, 0 }; + static ulong[] dim944JoeKuoD5Init = { 1, 1, 1, 9, 7, 19, 61, 255, 25, 729, 479, 837, 13, 0 }; + static ulong[] dim945JoeKuoD5Init = { 1, 1, 5, 9, 27, 29, 123, 101, 349, 443, 1759, 3, 4685, 0 }; + static ulong[] dim946JoeKuoD5Init = { 1, 3, 3, 1, 29, 47, 33, 183, 223, 927, 1341, 797, 8007, 0 }; + static ulong[] dim947JoeKuoD5Init = { 1, 3, 5, 15, 27, 33, 71, 195, 57, 897, 1337, 3455, 5201, 0 }; + static ulong[] dim948JoeKuoD5Init = { 1, 3, 3, 7, 31, 55, 121, 49, 343, 501, 1511, 113, 1549, 0 }; + static ulong[] dim949JoeKuoD5Init = { 1, 1, 7, 3, 9, 61, 19, 215, 323, 427, 1777, 685, 63, 0 }; + static ulong[] dim950JoeKuoD5Init = { 1, 3, 7, 15, 17, 23, 33, 129, 257, 527, 825, 3611, 2123, 0 }; + static ulong[] dim951JoeKuoD5Init = { 1, 3, 5, 1, 5, 45, 79, 9, 211, 493, 1095, 3031, 4093, 0 }; + static ulong[] dim952JoeKuoD5Init = { 1, 1, 5, 9, 21, 29, 29, 247, 489, 735, 11, 1723, 4459, 0 }; + static ulong[] dim953JoeKuoD5Init = { 1, 1, 7, 5, 21, 41, 59, 65, 151, 113, 851, 1213, 6367, 0 }; + static ulong[] dim954JoeKuoD5Init = { 1, 3, 7, 5, 9, 17, 85, 207, 219, 45, 85, 2433, 2219, 0 }; + static ulong[] dim955JoeKuoD5Init = { 1, 1, 3, 5, 7, 9, 39, 201, 369, 369, 113, 2667, 5137, 0 }; + static ulong[] dim956JoeKuoD5Init = { 1, 3, 7, 3, 27, 59, 127, 189, 289, 683, 1285, 2713, 7037, 0 }; + static ulong[] dim957JoeKuoD5Init = { 1, 3, 5, 3, 5, 19, 51, 23, 139, 379, 651, 19, 7705, 0 }; + static ulong[] dim958JoeKuoD5Init = { 1, 3, 3, 11, 31, 23, 11, 37, 161, 679, 1581, 217, 7973, 0 }; + static ulong[] dim959JoeKuoD5Init = { 1, 3, 1, 5, 9, 49, 23, 177, 475, 261, 403, 1415, 2299, 0 }; + static ulong[] dim960JoeKuoD5Init = { 1, 3, 5, 15, 19, 35, 117, 223, 159, 805, 1039, 1359, 6635, 0 }; + static ulong[] dim961JoeKuoD5Init = { 1, 3, 5, 15, 19, 1, 121, 223, 123, 161, 1631, 1161, 6997, 0 }; + static ulong[] dim962JoeKuoD5Init = { 1, 3, 5, 15, 5, 31, 41, 133, 121, 523, 1941, 2583, 6231, 0 }; + static ulong[] dim963JoeKuoD5Init = { 1, 1, 1, 15, 7, 31, 95, 49, 501, 737, 363, 2879, 6561, 0 }; + static ulong[] dim964JoeKuoD5Init = { 1, 1, 7, 11, 31, 47, 61, 17, 399, 3, 605, 907, 4605, 0 }; + static ulong[] dim965JoeKuoD5Init = { 1, 1, 5, 1, 23, 61, 47, 93, 25, 643, 881, 3559, 5251, 0 }; + static ulong[] dim966JoeKuoD5Init = { 1, 3, 3, 5, 27, 63, 1, 147, 425, 639, 1229, 3131, 5833, 0 }; + static ulong[] dim967JoeKuoD5Init = { 1, 3, 3, 15, 31, 31, 57, 121, 183, 39, 1067, 1915, 7321, 0 }; + static ulong[] dim968JoeKuoD5Init = { 1, 1, 5, 9, 21, 25, 125, 29, 53, 433, 189, 3465, 3847, 0 }; + static ulong[] dim969JoeKuoD5Init = { 1, 1, 1, 1, 11, 13, 99, 229, 365, 909, 87, 3669, 6609, 0 }; + static ulong[] dim970JoeKuoD5Init = { 1, 3, 3, 1, 29, 3, 43, 13, 19, 897, 1269, 1091, 3207, 0 }; + static ulong[] dim971JoeKuoD5Init = { 1, 3, 5, 13, 11, 33, 69, 251, 337, 235, 523, 2053, 3655, 0 }; + static ulong[] dim972JoeKuoD5Init = { 1, 3, 5, 15, 1, 11, 75, 169, 507, 391, 1009, 3165, 3691, 0 }; + static ulong[] dim973JoeKuoD5Init = { 1, 3, 1, 13, 3, 39, 119, 193, 169, 661, 813, 143, 7825, 0 }; + static ulong[] dim974JoeKuoD5Init = { 1, 3, 7, 11, 13, 33, 91, 209, 469, 141, 391, 1037, 6591, 0 }; + static ulong[] dim975JoeKuoD5Init = { 1, 3, 3, 7, 17, 45, 39, 19, 449, 691, 187, 2739, 7671, 0 }; + static ulong[] dim976JoeKuoD5Init = { 1, 1, 3, 15, 13, 57, 7, 75, 435, 287, 1479, 2143, 6501, 0 }; + static ulong[] dim977JoeKuoD5Init = { 1, 1, 1, 11, 11, 29, 111, 223, 505, 139, 1587, 3769, 5839, 0 }; + static ulong[] dim978JoeKuoD5Init = { 1, 3, 7, 7, 5, 61, 7, 209, 461, 37, 1771, 3683, 4283, 0 }; + static ulong[] dim979JoeKuoD5Init = { 1, 3, 3, 9, 1, 5, 123, 69, 75, 451, 963, 3273, 2785, 0 }; + static ulong[] dim980JoeKuoD5Init = { 1, 1, 1, 3, 7, 17, 87, 63, 505, 863, 1955, 3253, 463, 0 }; + static ulong[] dim981JoeKuoD5Init = { 1, 3, 5, 15, 15, 55, 127, 213, 277, 829, 165, 2885, 6693, 0 }; + static ulong[] dim982JoeKuoD5Init = { 1, 1, 7, 1, 9, 35, 5, 233, 329, 827, 531, 1435, 899, 0 }; + static ulong[] dim983JoeKuoD5Init = { 1, 1, 3, 11, 15, 25, 19, 233, 375, 327, 241, 3519, 4511, 0 }; + static ulong[] dim984JoeKuoD5Init = { 1, 1, 3, 11, 1, 1, 117, 29, 185, 529, 873, 1769, 6857, 0 }; + static ulong[] dim985JoeKuoD5Init = { 1, 3, 5, 11, 1, 31, 125, 27, 77, 295, 43, 205, 3349, 0 }; + static ulong[] dim986JoeKuoD5Init = { 1, 1, 3, 13, 1, 59, 11, 195, 483, 391, 381, 1251, 205, 0 }; + static ulong[] dim987JoeKuoD5Init = { 1, 3, 5, 1, 5, 51, 33, 159, 143, 213, 573, 1329, 2327, 0 }; + static ulong[] dim988JoeKuoD5Init = { 1, 3, 3, 15, 25, 5, 11, 203, 217, 397, 819, 949, 3987, 0 }; + static ulong[] dim989JoeKuoD5Init = { 1, 1, 5, 13, 17, 1, 29, 219, 161, 437, 685, 2743, 7509, 0 }; + static ulong[] dim990JoeKuoD5Init = { 1, 1, 3, 13, 3, 31, 29, 51, 41, 217, 997, 2581, 4273, 0 }; + static ulong[] dim991JoeKuoD5Init = { 1, 1, 7, 5, 31, 33, 45, 113, 463, 537, 237, 1501, 315, 0 }; + static ulong[] dim992JoeKuoD5Init = { 1, 3, 7, 5, 13, 3, 49, 155, 175, 655, 1995, 2131, 6105, 0 }; + static ulong[] dim993JoeKuoD5Init = { 1, 3, 3, 15, 23, 3, 17, 165, 67, 137, 337, 3805, 257, 0 }; + static ulong[] dim994JoeKuoD5Init = { 1, 1, 5, 13, 31, 11, 39, 111, 79, 585, 1911, 2395, 6239, 0 }; + static ulong[] dim995JoeKuoD5Init = { 1, 3, 5, 13, 5, 13, 61, 87, 309, 571, 321, 2485, 807, 0 }; + static ulong[] dim996JoeKuoD5Init = { 1, 3, 5, 13, 31, 21, 9, 177, 9, 395, 351, 529, 4977, 0 }; + static ulong[] dim997JoeKuoD5Init = { 1, 3, 1, 5, 5, 41, 95, 145, 319, 339, 1559, 203, 2883, 0 }; + static ulong[] dim998JoeKuoD5Init = { 1, 3, 3, 7, 9, 13, 121, 111, 107, 421, 1763, 2671, 259, 0 }; + static ulong[] dim999JoeKuoD5Init = { 1, 3, 7, 13, 25, 47, 71, 249, 119, 83, 1651, 2715, 4819, 0 }; + static ulong[] dim1000JoeKuoD5Init = { 1, 3, 5, 3, 5, 59, 99, 139, 435, 653, 153, 3605, 753, 0 }; + static ulong[] dim1001JoeKuoD5Init = { 1, 3, 5, 13, 19, 13, 3, 17, 215, 1017, 1685, 3795, 2363, 0 }; + static ulong[] dim1002JoeKuoD5Init = { 1, 3, 5, 11, 15, 13, 97, 145, 383, 39, 667, 1217, 1473, 0 }; + static ulong[] dim1003JoeKuoD5Init = { 1, 3, 5, 3, 11, 25, 107, 149, 11, 835, 1013, 1587, 1485, 0 }; + static ulong[] dim1004JoeKuoD5Init = { 1, 1, 5, 7, 15, 33, 15, 251, 473, 723, 959, 3991, 7145, 0 }; + static ulong[] dim1005JoeKuoD5Init = { 1, 1, 3, 13, 1, 49, 73, 195, 139, 893, 1677, 707, 667, 0 }; + static ulong[] dim1006JoeKuoD5Init = { 1, 3, 7, 11, 23, 3, 79, 255, 371, 885, 469, 3673, 5477, 0 }; + static ulong[] dim1007JoeKuoD5Init = { 1, 3, 3, 15, 21, 1, 45, 65, 403, 129, 123, 1171, 8177, 0 }; + static ulong[] dim1008JoeKuoD5Init = { 1, 1, 1, 3, 29, 25, 89, 231, 81, 503, 629, 1925, 2853, 0 }; + static ulong[] dim1009JoeKuoD5Init = { 1, 1, 7, 13, 9, 15, 107, 81, 479, 235, 1483, 3593, 2289, 0 }; + static ulong[] dim1010JoeKuoD5Init = { 1, 3, 1, 5, 9, 49, 119, 161, 233, 321, 1505, 3969, 3131, 0 }; + static ulong[] dim1011JoeKuoD5Init = { 1, 1, 5, 15, 9, 5, 91, 57, 13, 271, 999, 747, 3399, 0 }; + static ulong[] dim1012JoeKuoD5Init = { 1, 1, 7, 1, 1, 21, 1, 179, 449, 963, 33, 2259, 259, 0 }; + static ulong[] dim1013JoeKuoD5Init = { 1, 3, 5, 13, 7, 11, 81, 53, 157, 373, 767, 2489, 2275, 0 }; + static ulong[] dim1014JoeKuoD5Init = { 1, 3, 7, 3, 9, 55, 123, 135, 9, 499, 3, 2039, 2387, 0 }; + static ulong[] dim1015JoeKuoD5Init = { 1, 3, 3, 13, 7, 47, 119, 81, 351, 949, 1159, 859, 99, 0 }; + static ulong[] dim1016JoeKuoD5Init = { 1, 1, 7, 9, 1, 5, 83, 3, 387, 455, 1997, 1253, 77, 0 }; + static ulong[] dim1017JoeKuoD5Init = { 1, 1, 3, 13, 13, 49, 111, 133, 193, 893, 1549, 4003, 3461, 0 }; + static ulong[] dim1018JoeKuoD5Init = { 1, 1, 5, 13, 21, 3, 63, 209, 491, 447, 1635, 2297, 7667, 0 }; + static ulong[] dim1019JoeKuoD5Init = { 1, 3, 1, 1, 3, 61, 93, 115, 417, 465, 1075, 2157, 861, 0 }; + static ulong[] dim1020JoeKuoD5Init = { 1, 3, 1, 1, 7, 33, 7, 61, 509, 539, 1579, 2089, 5633, 0 }; + static ulong[] dim1021JoeKuoD5Init = { 1, 1, 7, 1, 9, 5, 75, 125, 345, 133, 1699, 3183, 5403, 0 }; + static ulong[] dim1022JoeKuoD5Init = { 1, 3, 3, 15, 17, 9, 115, 213, 417, 713, 989, 3987, 3043, 0 }; + static ulong[] dim1023JoeKuoD5Init = { 1, 3, 3, 3, 25, 9, 115, 83, 255, 695, 471, 1819, 2661, 0 }; + static ulong[] dim1024JoeKuoD5Init = { 1, 1, 7, 9, 31, 35, 33, 197, 335, 543, 323, 3241, 7039, 0 }; + static ulong[] dim1025JoeKuoD5Init = { 1, 1, 7, 7, 23, 5, 23, 193, 327, 3, 1425, 2787, 5659, 0 }; + static ulong[] dim1026JoeKuoD5Init = { 1, 3, 3, 9, 27, 25, 37, 241, 373, 411, 783, 621, 2129, 0 }; + static ulong[] dim1027JoeKuoD5Init = { 1, 1, 3, 5, 13, 19, 119, 39, 303, 383, 1965, 725, 1909, 0 }; + static ulong[] dim1028JoeKuoD5Init = { 1, 3, 7, 15, 25, 27, 121, 245, 165, 985, 595, 3325, 7319, 0 }; + static ulong[] dim1029JoeKuoD5Init = { 1, 1, 1, 5, 25, 7, 109, 75, 277, 25, 715, 495, 3911, 0 }; + static ulong[] dim1030JoeKuoD5Init = { 1, 1, 3, 9, 21, 37, 13, 23, 161, 907, 1551, 2453, 5323, 0 }; + static ulong[] dim1031JoeKuoD5Init = { 1, 1, 5, 9, 17, 11, 101, 237, 219, 735, 1865, 209, 5605, 0 }; + static ulong[] dim1032JoeKuoD5Init = { 1, 3, 3, 15, 5, 63, 87, 173, 299, 739, 617, 1883, 2525, 0 }; + static ulong[] dim1033JoeKuoD5Init = { 1, 1, 5, 1, 11, 5, 25, 207, 271, 471, 921, 3819, 5627, 0 }; + static ulong[] dim1034JoeKuoD5Init = { 1, 3, 7, 13, 1, 7, 27, 185, 245, 629, 1329, 611, 7183, 0 }; + static ulong[] dim1035JoeKuoD5Init = { 1, 3, 5, 15, 9, 21, 55, 17, 157, 987, 553, 3823, 6923, 0 }; + static ulong[] dim1036JoeKuoD5Init = { 1, 3, 3, 11, 19, 47, 113, 149, 495, 891, 1885, 2699, 6019, 0 }; + static ulong[] dim1037JoeKuoD5Init = { 1, 1, 3, 9, 23, 53, 27, 241, 453, 103, 1879, 289, 5195, 0 }; + static ulong[] dim1038JoeKuoD5Init = { 1, 1, 1, 3, 13, 37, 125, 83, 341, 793, 193, 297, 3337, 0 }; + static ulong[] dim1039JoeKuoD5Init = { 1, 1, 5, 7, 13, 43, 101, 121, 319, 845, 601, 3357, 3037, 0 }; + static ulong[] dim1040JoeKuoD5Init = { 1, 3, 1, 1, 27, 3, 53, 111, 287, 791, 2017, 3869, 5105, 0 }; + static ulong[] dim1041JoeKuoD5Init = { 1, 3, 7, 1, 19, 33, 107, 203, 135, 783, 497, 1007, 4587, 0 }; + static ulong[] dim1042JoeKuoD5Init = { 1, 1, 3, 13, 7, 41, 101, 59, 407, 525, 1941, 961, 7059, 0 }; + static ulong[] dim1043JoeKuoD5Init = { 1, 3, 5, 5, 17, 33, 9, 217, 31, 695, 1111, 391, 5617, 0 }; + static ulong[] dim1044JoeKuoD5Init = { 1, 3, 5, 5, 15, 13, 107, 223, 477, 91, 449, 901, 3075, 0 }; + static ulong[] dim1045JoeKuoD5Init = { 1, 1, 3, 13, 31, 47, 97, 49, 47, 301, 305, 1159, 6977, 0 }; + static ulong[] dim1046JoeKuoD5Init = { 1, 3, 5, 9, 29, 9, 17, 237, 461, 593, 495, 1099, 5135, 0 }; + static ulong[] dim1047JoeKuoD5Init = { 1, 3, 5, 7, 3, 51, 5, 113, 409, 777, 1323, 2719, 3647, 0 }; + static ulong[] dim1048JoeKuoD5Init = { 1, 3, 3, 5, 15, 45, 33, 49, 167, 933, 1831, 3195, 3121, 0 }; + static ulong[] dim1049JoeKuoD5Init = { 1, 1, 5, 15, 3, 33, 123, 19, 173, 69, 593, 3709, 7193, 0 }; + static ulong[] dim1050JoeKuoD5Init = { 1, 1, 7, 15, 9, 9, 63, 81, 325, 473, 1517, 3483, 7585, 0 }; + static ulong[] dim1051JoeKuoD5Init = { 1, 1, 5, 9, 31, 47, 77, 67, 55, 673, 1963, 111, 839, 0 }; + static ulong[] dim1052JoeKuoD5Init = { 1, 3, 3, 15, 23, 45, 5, 159, 225, 595, 1573, 1891, 301, 0 }; + static ulong[] dim1053JoeKuoD5Init = { 1, 3, 1, 1, 3, 21, 123, 29, 331, 793, 1885, 3299, 3433, 0 }; + static ulong[] dim1054JoeKuoD5Init = { 1, 3, 5, 1, 23, 51, 21, 23, 265, 919, 853, 3969, 2043, 0 }; + static ulong[] dim1055JoeKuoD5Init = { 1, 3, 7, 3, 25, 59, 111, 13, 217, 893, 1005, 3795, 3233, 0 }; + static ulong[] dim1056JoeKuoD5Init = { 1, 3, 5, 7, 7, 11, 69, 183, 509, 51, 727, 2093, 2615, 0 }; + static ulong[] dim1057JoeKuoD5Init = { 1, 1, 1, 11, 3, 13, 119, 209, 365, 895, 1563, 427, 5519, 0 }; + static ulong[] dim1058JoeKuoD5Init = { 1, 3, 7, 5, 23, 9, 87, 29, 19, 519, 763, 3553, 575, 0 }; + static ulong[] dim1059JoeKuoD5Init = { 1, 3, 5, 1, 3, 21, 15, 237, 501, 627, 1557, 545, 2415, 0 }; + static ulong[] dim1060JoeKuoD5Init = { 1, 3, 3, 3, 7, 53, 83, 19, 385, 425, 1145, 1039, 6667, 0 }; + static ulong[] dim1061JoeKuoD5Init = { 1, 1, 5, 15, 31, 31, 39, 51, 233, 755, 1105, 925, 6113, 0 }; + static ulong[] dim1062JoeKuoD5Init = { 1, 3, 3, 13, 17, 25, 45, 135, 347, 707, 1035, 1405, 7105, 0 }; + static ulong[] dim1063JoeKuoD5Init = { 1, 3, 3, 9, 17, 25, 119, 77, 279, 467, 195, 1919, 4959, 0 }; + static ulong[] dim1064JoeKuoD5Init = { 1, 3, 1, 7, 31, 41, 5, 21, 349, 607, 737, 2033, 2323, 0 }; + static ulong[] dim1065JoeKuoD5Init = { 1, 1, 7, 9, 29, 19, 45, 223, 391, 495, 1905, 735, 6309, 0 }; + static ulong[] dim1066JoeKuoD5Init = { 1, 1, 7, 15, 19, 9, 93, 89, 43, 297, 653, 1343, 5897, 0 }; + static ulong[] dim1067JoeKuoD5Init = { 1, 1, 1, 1, 21, 7, 29, 187, 115, 279, 1029, 2817, 1349, 0 }; + static ulong[] dim1068JoeKuoD5Init = { 1, 3, 7, 9, 5, 61, 35, 33, 151, 119, 1713, 1713, 1645, 0 }; + static ulong[] dim1069JoeKuoD5Init = { 1, 3, 5, 1, 23, 21, 101, 131, 355, 75, 1233, 1677, 2463, 0 }; + static ulong[] dim1070JoeKuoD5Init = { 1, 3, 1, 15, 5, 57, 79, 51, 299, 307, 1977, 3473, 6153, 0 }; + static ulong[] dim1071JoeKuoD5Init = { 1, 1, 1, 15, 19, 1, 59, 69, 175, 189, 303, 43, 7561, 0 }; + static ulong[] dim1072JoeKuoD5Init = { 1, 1, 7, 1, 31, 37, 117, 9, 373, 279, 1187, 3501, 715, 0 }; + static ulong[] dim1073JoeKuoD5Init = { 1, 1, 7, 13, 1, 29, 79, 161, 223, 437, 577, 921, 5535, 0 }; + static ulong[] dim1074JoeKuoD5Init = { 1, 3, 5, 1, 31, 27, 93, 63, 281, 187, 1739, 4085, 5669, 0 }; + static ulong[] dim1075JoeKuoD5Init = { 1, 1, 3, 7, 11, 25, 87, 245, 339, 741, 927, 1279, 3889, 0 }; + static ulong[] dim1076JoeKuoD5Init = { 1, 1, 5, 7, 31, 5, 45, 205, 289, 999, 361, 3595, 569, 0 }; + static ulong[] dim1077JoeKuoD5Init = { 1, 1, 1, 13, 19, 23, 103, 73, 403, 85, 1623, 325, 5369, 0 }; + static ulong[] dim1078JoeKuoD5Init = { 1, 1, 7, 15, 13, 23, 27, 155, 359, 777, 1751, 915, 949, 0 }; + static ulong[] dim1079JoeKuoD5Init = { 1, 3, 5, 11, 23, 59, 57, 215, 77, 581, 369, 953, 6987, 0 }; + static ulong[] dim1080JoeKuoD5Init = { 1, 1, 1, 15, 27, 55, 103, 173, 485, 771, 1693, 1227, 3257, 0 }; + static ulong[] dim1081JoeKuoD5Init = { 1, 1, 1, 9, 5, 23, 95, 121, 81, 107, 1897, 1647, 3047, 0 }; + static ulong[] dim1082JoeKuoD5Init = { 1, 1, 3, 11, 17, 47, 119, 83, 137, 897, 1893, 653, 5031, 0 }; + static ulong[] dim1083JoeKuoD5Init = { 1, 1, 7, 13, 31, 3, 73, 129, 159, 529, 1433, 2313, 6143, 0 }; + static ulong[] dim1084JoeKuoD5Init = { 1, 3, 1, 15, 29, 19, 123, 141, 51, 427, 935, 2831, 5799, 0 }; + static ulong[] dim1085JoeKuoD5Init = { 1, 1, 3, 1, 31, 3, 119, 227, 37, 435, 921, 3313, 2129, 0 }; + static ulong[] dim1086JoeKuoD5Init = { 1, 1, 3, 13, 1, 19, 75, 35, 307, 419, 813, 2217, 6603, 0 }; + static ulong[] dim1087JoeKuoD5Init = { 1, 1, 1, 3, 17, 47, 79, 75, 47, 835, 287, 3361, 5875, 0 }; + static ulong[] dim1088JoeKuoD5Init = { 1, 3, 7, 9, 5, 5, 3, 19, 341, 717, 45, 1169, 1305, 0 }; + static ulong[] dim1089JoeKuoD5Init = { 1, 3, 5, 1, 3, 11, 81, 233, 195, 987, 593, 2495, 5213, 0 }; + static ulong[] dim1090JoeKuoD5Init = { 1, 1, 5, 1, 27, 1, 29, 251, 221, 267, 593, 361, 5629, 0 }; + static ulong[] dim1091JoeKuoD5Init = { 1, 1, 7, 15, 21, 33, 15, 37, 341, 301, 293, 2787, 3531, 0 }; + static ulong[] dim1092JoeKuoD5Init = { 1, 3, 3, 7, 3, 3, 9, 7, 257, 509, 1545, 4095, 3309, 0 }; + static ulong[] dim1093JoeKuoD5Init = { 1, 1, 5, 5, 11, 7, 27, 71, 317, 221, 391, 1257, 5885, 0 }; + static ulong[] dim1094JoeKuoD5Init = { 1, 1, 5, 7, 15, 51, 29, 107, 461, 597, 961, 3589, 2325, 0 }; + static ulong[] dim1095JoeKuoD5Init = { 1, 3, 3, 3, 29, 1, 91, 181, 477, 125, 1869, 3209, 3513, 0 }; + static ulong[] dim1096JoeKuoD5Init = { 1, 3, 5, 7, 13, 17, 49, 145, 215, 1003, 1053, 1413, 8011, 0 }; + static ulong[] dim1097JoeKuoD5Init = { 1, 1, 7, 5, 23, 63, 9, 175, 159, 627, 705, 2769, 2469, 0 }; + static ulong[] dim1098JoeKuoD5Init = { 1, 1, 1, 11, 27, 21, 5, 61, 249, 581, 829, 2195, 4241, 0 }; + static ulong[] dim1099JoeKuoD5Init = { 1, 1, 3, 11, 27, 39, 67, 3, 23, 819, 1879, 3775, 6949, 0 }; + static ulong[] dim1100JoeKuoD5Init = { 1, 3, 3, 5, 19, 35, 93, 113, 371, 511, 811, 577, 1121, 0 }; + static ulong[] dim1101JoeKuoD5Init = { 1, 1, 5, 9, 9, 25, 103, 139, 151, 177, 557, 2123, 6677, 0 }; + static ulong[] dim1102JoeKuoD5Init = { 1, 1, 7, 5, 17, 63, 61, 241, 351, 371, 1745, 3133, 7663, 0 }; + static ulong[] dim1103JoeKuoD5Init = { 1, 3, 7, 11, 19, 39, 105, 93, 77, 445, 1433, 1793, 2957, 0 }; + static ulong[] dim1104JoeKuoD5Init = { 1, 3, 1, 15, 5, 15, 29, 211, 229, 887, 413, 701, 737, 0 }; + static ulong[] dim1105JoeKuoD5Init = { 1, 1, 5, 13, 17, 7, 69, 213, 49, 91, 1143, 3743, 4385, 0 }; + static ulong[] dim1106JoeKuoD5Init = { 1, 3, 3, 7, 21, 47, 41, 157, 299, 29, 751, 2427, 1521, 0 }; + static ulong[] dim1107JoeKuoD5Init = { 1, 1, 1, 1, 29, 45, 119, 79, 141, 477, 1289, 515, 8143, 0 }; + static ulong[] dim1108JoeKuoD5Init = { 1, 1, 7, 7, 3, 7, 123, 197, 441, 233, 1841, 267, 6553, 0 }; + static ulong[] dim1109JoeKuoD5Init = { 1, 3, 7, 15, 3, 41, 33, 95, 271, 461, 1505, 2989, 5503, 0 }; + static ulong[] dim1110JoeKuoD5Init = { 1, 1, 1, 11, 19, 15, 1, 23, 13, 737, 51, 289, 6731, 0 }; + static ulong[] dim1111JoeKuoD5Init = { 1, 3, 5, 1, 15, 11, 53, 241, 17, 107, 1931, 3759, 5421, 1889, 0 }; + static ulong[] dim1112JoeKuoD5Init = { 1, 3, 1, 13, 15, 29, 107, 163, 395, 645, 299, 799, 4331, 335, 0 }; + static ulong[] dim1113JoeKuoD5Init = { 1, 1, 3, 13, 5, 47, 91, 41, 439, 319, 1213, 763, 6101, 1543, 0 }; + static ulong[] dim1114JoeKuoD5Init = { 1, 1, 3, 15, 19, 51, 117, 159, 315, 767, 1957, 3655, 6573, 5419, 0 }; + static ulong[] dim1115JoeKuoD5Init = { 1, 3, 1, 11, 23, 51, 115, 223, 125, 633, 637, 3443, 1993, 1887, 0 }; + static ulong[] dim1116JoeKuoD5Init = { 1, 3, 3, 15, 27, 59, 49, 123, 49, 187, 963, 3893, 3921, 14411, 0 }; + static ulong[] dim1117JoeKuoD5Init = { 1, 3, 1, 7, 29, 3, 77, 3, 79, 409, 1151, 3547, 3693, 8367, 0 }; + static ulong[] dim1118JoeKuoD5Init = { 1, 3, 1, 9, 23, 31, 123, 133, 215, 921, 329, 1449, 5535, 9725, 0 }; + static ulong[] dim1119JoeKuoD5Init = { 1, 3, 1, 5, 11, 45, 109, 117, 493, 743, 1473, 2073, 4771, 16321, 0 }; + static ulong[] dim1120JoeKuoD5Init = { 1, 1, 3, 9, 27, 29, 25, 223, 371, 113, 1183, 1723, 6127, 9949, 0 }; + static ulong[] dim1121JoeKuoD5Init = { 1, 1, 7, 15, 27, 55, 119, 31, 21, 849, 2001, 2541, 2611, 15429, 0 }; + static ulong[] dim1122JoeKuoD5Init = { 1, 1, 3, 7, 17, 1, 93, 243, 311, 175, 559, 2177, 5641, 15293, 0 }; + static ulong[] dim1123JoeKuoD5Init = { 1, 3, 5, 15, 25, 31, 121, 179, 169, 61, 1837, 2233, 1735, 6597, 0 }; + static ulong[] dim1124JoeKuoD5Init = { 1, 3, 5, 13, 21, 59, 61, 239, 501, 523, 257, 573, 893, 7275, 0 }; + static ulong[] dim1125JoeKuoD5Init = { 1, 1, 1, 13, 29, 33, 77, 225, 81, 879, 1403, 3279, 2225, 11571, 0 }; + static ulong[] dim1126JoeKuoD5Init = { 1, 3, 5, 5, 15, 5, 29, 7, 157, 717, 397, 2079, 5839, 13297, 0 }; + static ulong[] dim1127JoeKuoD5Init = { 1, 3, 5, 7, 17, 3, 93, 241, 301, 433, 2003, 2089, 5781, 15223, 0 }; + static ulong[] dim1128JoeKuoD5Init = { 1, 1, 5, 13, 5, 19, 53, 189, 41, 17, 897, 2327, 3481, 7185, 0 }; + static ulong[] dim1129JoeKuoD5Init = { 1, 1, 3, 3, 25, 23, 23, 155, 367, 391, 1001, 1179, 3781, 14225, 0 }; + static ulong[] dim1130JoeKuoD5Init = { 1, 1, 5, 7, 9, 23, 63, 73, 439, 361, 233, 3387, 887, 5425, 0 }; + static ulong[] dim1131JoeKuoD5Init = { 1, 3, 3, 13, 5, 57, 55, 35, 369, 85, 1585, 2267, 2927, 13997, 0 }; + static ulong[] dim1132JoeKuoD5Init = { 1, 3, 7, 1, 7, 7, 55, 109, 401, 443, 1777, 3831, 6933, 3661, 0 }; + static ulong[] dim1133JoeKuoD5Init = { 1, 1, 7, 15, 17, 27, 5, 17, 419, 949, 1483, 791, 7353, 1425, 0 }; + static ulong[] dim1134JoeKuoD5Init = { 1, 1, 3, 9, 27, 41, 67, 135, 129, 863, 1679, 4001, 6841, 13561, 0 }; + static ulong[] dim1135JoeKuoD5Init = { 1, 3, 3, 3, 21, 43, 45, 65, 103, 141, 1261, 2865, 5621, 5131, 0 }; + static ulong[] dim1136JoeKuoD5Init = { 1, 1, 1, 15, 19, 3, 97, 159, 465, 31, 1757, 2765, 667, 6943, 0 }; + static ulong[] dim1137JoeKuoD5Init = { 1, 3, 7, 3, 3, 5, 111, 203, 313, 495, 123, 1899, 7765, 2737, 0 }; + static ulong[] dim1138JoeKuoD5Init = { 1, 3, 1, 15, 19, 63, 19, 233, 283, 25, 1009, 2117, 6233, 5059, 0 }; + static ulong[] dim1139JoeKuoD5Init = { 1, 1, 7, 9, 29, 11, 35, 111, 111, 49, 1681, 3483, 2449, 13877, 0 }; + static ulong[] dim1140JoeKuoD5Init = { 1, 3, 5, 13, 7, 61, 27, 217, 275, 137, 2025, 2745, 5565, 7999, 0 }; + static ulong[] dim1141JoeKuoD5Init = { 1, 1, 5, 1, 13, 19, 113, 169, 425, 691, 1425, 1645, 1045, 9237, 0 }; + static ulong[] dim1142JoeKuoD5Init = { 1, 3, 1, 11, 23, 19, 67, 5, 225, 523, 1809, 341, 7919, 3675, 0 }; + static ulong[] dim1143JoeKuoD5Init = { 1, 3, 5, 7, 3, 33, 25, 229, 393, 141, 1953, 1433, 1593, 11569, 0 }; + static ulong[] dim1144JoeKuoD5Init = { 1, 1, 1, 1, 5, 23, 53, 59, 141, 385, 1765, 4079, 2901, 593, 0 }; + static ulong[] dim1145JoeKuoD5Init = { 1, 3, 7, 9, 15, 43, 115, 93, 121, 209, 1797, 633, 2595, 5539, 0 }; + static ulong[] dim1146JoeKuoD5Init = { 1, 3, 3, 15, 5, 25, 9, 141, 37, 313, 1937, 2259, 1051, 8251, 0 }; + static ulong[] dim1147JoeKuoD5Init = { 1, 1, 5, 5, 17, 1, 89, 173, 169, 463, 2003, 4005, 6009, 4373, 0 }; + static ulong[] dim1148JoeKuoD5Init = { 1, 3, 1, 7, 17, 21, 59, 207, 333, 741, 1847, 683, 2847, 11007, 0 }; + static ulong[] dim1149JoeKuoD5Init = { 1, 3, 1, 5, 5, 39, 111, 91, 49, 559, 1937, 1311, 6157, 517, 0 }; + static ulong[] dim1150JoeKuoD5Init = { 1, 1, 1, 15, 29, 1, 113, 125, 343, 939, 1989, 2569, 7215, 5099, 0 }; + static ulong[] dim1151JoeKuoD5Init = { 1, 1, 1, 5, 5, 55, 103, 237, 313, 43, 909, 201, 175, 16025, 0 }; + static ulong[] dim1152JoeKuoD5Init = { 1, 1, 7, 3, 25, 29, 33, 59, 127, 865, 1753, 3649, 5517, 5001, 0 }; + static ulong[] dim1153JoeKuoD5Init = { 1, 3, 1, 15, 27, 31, 97, 153, 451, 241, 59, 515, 2869, 12909, 0 }; + static ulong[] dim1154JoeKuoD5Init = { 1, 3, 3, 3, 13, 51, 3, 55, 105, 497, 701, 483, 5165, 4721, 0 }; + static ulong[] dim1155JoeKuoD5Init = { 1, 3, 5, 3, 19, 57, 39, 55, 197, 409, 199, 1635, 1965, 2489, 0 }; + static ulong[] dim1156JoeKuoD5Init = { 1, 3, 1, 9, 1, 13, 123, 125, 341, 981, 1957, 1619, 1973, 8641, 0 }; + static ulong[] dim1157JoeKuoD5Init = { 1, 3, 7, 1, 29, 13, 31, 71, 443, 867, 1755, 843, 7349, 6015, 0 }; + static ulong[] dim1158JoeKuoD5Init = { 1, 3, 5, 13, 15, 39, 81, 123, 9, 991, 803, 3281, 7859, 15455, 0 }; + static ulong[] dim1159JoeKuoD5Init = { 1, 1, 7, 1, 3, 33, 87, 81, 111, 595, 483, 3273, 847, 2061, 0 }; + static ulong[] dim1160JoeKuoD5Init = { 1, 1, 1, 11, 9, 21, 79, 49, 453, 125, 603, 1733, 7213, 7309, 0 }; + static ulong[] dim1161JoeKuoD5Init = { 1, 1, 7, 3, 29, 47, 21, 99, 35, 275, 69, 3773, 389, 10615, 0 }; + static ulong[] dim1162JoeKuoD5Init = { 1, 3, 7, 5, 15, 21, 9, 55, 293, 639, 135, 903, 973, 9467, 0 }; + static ulong[] dim1163JoeKuoD5Init = { 1, 1, 1, 15, 19, 63, 73, 71, 397, 387, 1859, 2741, 7323, 369, 0 }; + static ulong[] dim1164JoeKuoD5Init = { 1, 1, 5, 9, 21, 23, 55, 129, 183, 721, 1293, 3579, 3629, 13303, 0 }; + static ulong[] dim1165JoeKuoD5Init = { 1, 3, 7, 1, 21, 35, 79, 255, 443, 123, 551, 1113, 8133, 11621, 0 }; + static ulong[] dim1166JoeKuoD5Init = { 1, 3, 3, 7, 19, 61, 35, 161, 145, 291, 1503, 3085, 4589, 7971, 0 }; + static ulong[] dim1167JoeKuoD5Init = { 1, 1, 5, 15, 9, 59, 119, 133, 69, 413, 335, 2089, 8085, 12727, 0 }; + static ulong[] dim1168JoeKuoD5Init = { 1, 1, 7, 11, 17, 5, 83, 125, 161, 745, 1889, 345, 8107, 10693, 0 }; + static ulong[] dim1169JoeKuoD5Init = { 1, 3, 1, 9, 5, 29, 59, 69, 113, 529, 199, 1565, 1611, 12297, 0 }; + static ulong[] dim1170JoeKuoD5Init = { 1, 1, 3, 15, 27, 61, 49, 59, 249, 121, 1569, 407, 1443, 5705, 0 }; + static ulong[] dim1171JoeKuoD5Init = { 1, 3, 3, 13, 5, 3, 93, 99, 417, 499, 1867, 1269, 4293, 14633, 0 }; + static ulong[] dim1172JoeKuoD5Init = { 1, 1, 3, 5, 15, 37, 29, 75, 191, 41, 11, 339, 485, 13635, 0 }; + static ulong[] dim1173JoeKuoD5Init = { 1, 3, 7, 7, 27, 53, 13, 121, 209, 411, 51, 1003, 6587, 8247, 0 }; + static ulong[] dim1174JoeKuoD5Init = { 1, 1, 7, 5, 13, 7, 43, 155, 467, 491, 1181, 1105, 2165, 16347, 0 }; + static ulong[] dim1175JoeKuoD5Init = { 1, 3, 5, 3, 21, 19, 89, 25, 353, 223, 1063, 111, 611, 2225, 0 }; + static ulong[] dim1176JoeKuoD5Init = { 1, 3, 1, 9, 3, 41, 95, 183, 135, 919, 861, 2929, 7189, 5505, 0 }; + static ulong[] dim1177JoeKuoD5Init = { 1, 1, 7, 13, 13, 39, 85, 135, 403, 39, 1893, 3667, 2609, 9251, 0 }; + static ulong[] dim1178JoeKuoD5Init = { 1, 1, 1, 11, 25, 5, 1, 179, 491, 953, 393, 2005, 1401, 12589, 0 }; + static ulong[] dim1179JoeKuoD5Init = { 1, 3, 5, 7, 25, 19, 25, 73, 63, 897, 701, 345, 4995, 2411, 0 }; + static ulong[] dim1180JoeKuoD5Init = { 1, 1, 7, 3, 31, 15, 121, 161, 127, 847, 1547, 3379, 4763, 8349, 0 }; + static ulong[] dim1181JoeKuoD5Init = { 1, 3, 7, 7, 25, 61, 87, 235, 117, 861, 977, 2979, 3333, 10911, 0 }; + static ulong[] dim1182JoeKuoD5Init = { 1, 1, 5, 9, 5, 57, 33, 129, 295, 225, 1497, 2367, 5379, 12721, 0 }; + static ulong[] dim1183JoeKuoD5Init = { 1, 1, 7, 11, 19, 43, 43, 217, 139, 637, 567, 3661, 2807, 11061, 0 }; + static ulong[] dim1184JoeKuoD5Init = { 1, 3, 1, 7, 27, 41, 97, 89, 53, 375, 1871, 2575, 1545, 455, 0 }; + static ulong[] dim1185JoeKuoD5Init = { 1, 1, 5, 3, 13, 15, 77, 229, 329, 663, 1943, 1411, 5755, 16279, 0 }; + static ulong[] dim1186JoeKuoD5Init = { 1, 3, 7, 9, 1, 3, 65, 21, 239, 619, 1801, 233, 3441, 12777, 0 }; + static ulong[] dim1187JoeKuoD5Init = { 1, 3, 1, 5, 9, 63, 9, 19, 65, 759, 1871, 3537, 4453, 15443, 0 }; + static ulong[] dim1188JoeKuoD5Init = { 1, 1, 3, 5, 17, 35, 43, 199, 167, 507, 669, 3593, 1645, 11791, 0 }; + static ulong[] dim1189JoeKuoD5Init = { 1, 3, 1, 7, 25, 21, 111, 171, 349, 423, 1793, 659, 5211, 3547, 0 }; + static ulong[] dim1190JoeKuoD5Init = { 1, 3, 3, 13, 23, 53, 95, 81, 383, 639, 1113, 2021, 7897, 4803, 0 }; + static ulong[] dim1191JoeKuoD5Init = { 1, 1, 5, 9, 19, 63, 61, 165, 3, 565, 829, 3071, 6605, 3625, 0 }; + static ulong[] dim1192JoeKuoD5Init = { 1, 3, 1, 15, 13, 53, 89, 97, 307, 555, 2039, 2753, 169, 941, 0 }; + static ulong[] dim1193JoeKuoD5Init = { 1, 1, 7, 3, 9, 41, 45, 89, 155, 269, 51, 3791, 5563, 4757, 0 }; + static ulong[] dim1194JoeKuoD5Init = { 1, 1, 1, 7, 23, 35, 19, 93, 205, 51, 375, 2107, 6357, 16257, 0 }; + static ulong[] dim1195JoeKuoD5Init = { 1, 1, 1, 5, 3, 45, 107, 141, 315, 107, 219, 51, 7629, 6865, 0 }; + static ulong[] dim1196JoeKuoD5Init = { 1, 1, 7, 1, 19, 23, 17, 77, 409, 59, 1649, 4029, 6541, 1075, 0 }; + static ulong[] dim1197JoeKuoD5Init = { 1, 1, 5, 11, 1, 37, 13, 221, 277, 61, 1509, 1713, 4597, 5907, 0 }; + static ulong[] dim1198JoeKuoD5Init = { 1, 1, 5, 1, 19, 53, 109, 123, 243, 1001, 291, 2265, 45, 437, 0 }; + static ulong[] dim1199JoeKuoD5Init = { 1, 3, 1, 1, 17, 63, 65, 67, 359, 139, 699, 3037, 6123, 11885, 0 }; + static ulong[] dim1200JoeKuoD5Init = { 1, 1, 5, 1, 3, 45, 125, 107, 75, 631, 769, 1431, 2089, 4919, 0 }; + static ulong[] dim1201JoeKuoD5Init = { 1, 3, 7, 5, 27, 31, 63, 75, 265, 727, 1197, 3549, 7677, 10831, 0 }; + static ulong[] dim1202JoeKuoD5Init = { 1, 3, 5, 15, 17, 61, 67, 169, 325, 627, 489, 729, 3585, 14253, 0 }; + static ulong[] dim1203JoeKuoD5Init = { 1, 1, 1, 5, 1, 39, 23, 11, 23, 3, 973, 2161, 5613, 5711, 0 }; + static ulong[] dim1204JoeKuoD5Init = { 1, 1, 7, 11, 3, 33, 31, 139, 275, 391, 1625, 2037, 389, 3853, 0 }; + static ulong[] dim1205JoeKuoD5Init = { 1, 3, 5, 1, 17, 47, 19, 171, 219, 959, 1623, 1069, 1833, 4467, 0 }; + static ulong[] dim1206JoeKuoD5Init = { 1, 3, 1, 11, 3, 29, 59, 159, 385, 183, 1091, 491, 8087, 4047, 0 }; + static ulong[] dim1207JoeKuoD5Init = { 1, 3, 3, 5, 19, 3, 121, 29, 97, 345, 1573, 2993, 7987, 5397, 0 }; + static ulong[] dim1208JoeKuoD5Init = { 1, 1, 1, 1, 31, 9, 57, 33, 489, 389, 1065, 2715, 5955, 11267, 0 }; + static ulong[] dim1209JoeKuoD5Init = { 1, 1, 1, 1, 25, 7, 67, 245, 159, 987, 1297, 277, 2223, 9865, 0 }; + static ulong[] dim1210JoeKuoD5Init = { 1, 1, 7, 1, 5, 11, 109, 171, 181, 303, 1875, 1915, 5007, 15563, 0 }; + static ulong[] dim1211JoeKuoD5Init = { 1, 3, 3, 1, 21, 7, 67, 155, 503, 751, 1721, 3405, 4717, 12567, 0 }; + static ulong[] dim1212JoeKuoD5Init = { 1, 1, 1, 1, 1, 51, 67, 57, 373, 835, 911, 3899, 7235, 5943, 0 }; + static ulong[] dim1213JoeKuoD5Init = { 1, 3, 7, 1, 21, 63, 21, 209, 321, 75, 551, 2741, 535, 14693, 0 }; + static ulong[] dim1214JoeKuoD5Init = { 1, 3, 5, 11, 21, 53, 23, 189, 463, 707, 637, 4055, 851, 12377, 0 }; + static ulong[] dim1215JoeKuoD5Init = { 1, 3, 7, 3, 13, 39, 17, 7, 487, 731, 1965, 2395, 5129, 6677, 0 }; + static ulong[] dim1216JoeKuoD5Init = { 1, 1, 1, 9, 5, 57, 15, 247, 325, 789, 1771, 2811, 6453, 7031, 0 }; + static ulong[] dim1217JoeKuoD5Init = { 1, 3, 3, 13, 21, 21, 27, 113, 345, 999, 7, 3241, 2569, 9175, 0 }; + static ulong[] dim1218JoeKuoD5Init = { 1, 3, 7, 5, 19, 41, 51, 37, 409, 553, 693, 1877, 4015, 1749, 0 }; + static ulong[] dim1219JoeKuoD5Init = { 1, 3, 1, 11, 3, 7, 11, 197, 5, 601, 451, 2117, 4519, 5913, 0 }; + static ulong[] dim1220JoeKuoD5Init = { 1, 1, 3, 7, 11, 53, 81, 187, 169, 419, 175, 2041, 2537, 16333, 0 }; + static ulong[] dim1221JoeKuoD5Init = { 1, 1, 7, 1, 1, 9, 117, 33, 233, 581, 1575, 2131, 2065, 6597, 0 }; + static ulong[] dim1222JoeKuoD5Init = { 1, 3, 5, 3, 27, 7, 111, 51, 311, 297, 1773, 193, 5599, 271, 0 }; + static ulong[] dim1223JoeKuoD5Init = { 1, 3, 1, 7, 17, 49, 85, 247, 7, 1005, 1191, 399, 7775, 5635, 0 }; + static ulong[] dim1224JoeKuoD5Init = { 1, 1, 1, 9, 31, 23, 9, 251, 97, 835, 813, 1335, 7955, 3977, 0 }; + static ulong[] dim1225JoeKuoD5Init = { 1, 1, 1, 15, 3, 39, 5, 19, 111, 523, 1475, 2169, 4121, 1171, 0 }; + static ulong[] dim1226JoeKuoD5Init = { 1, 3, 7, 9, 3, 19, 73, 43, 45, 57, 165, 3659, 7585, 8549, 0 }; + static ulong[] dim1227JoeKuoD5Init = { 1, 3, 3, 11, 25, 57, 117, 15, 289, 953, 1123, 2327, 7957, 6043, 0 }; + static ulong[] dim1228JoeKuoD5Init = { 1, 1, 5, 13, 7, 45, 63, 39, 349, 871, 1215, 2915, 1061, 7633, 0 }; + static ulong[] dim1229JoeKuoD5Init = { 1, 3, 5, 15, 1, 33, 55, 213, 245, 221, 259, 1679, 1507, 14275, 0 }; + static ulong[] dim1230JoeKuoD5Init = { 1, 3, 7, 3, 5, 15, 59, 55, 349, 121, 1471, 2119, 2559, 6379, 0 }; + static ulong[] dim1231JoeKuoD5Init = { 1, 1, 5, 3, 7, 23, 125, 137, 171, 775, 1069, 605, 2945, 16089, 0 }; + static ulong[] dim1232JoeKuoD5Init = { 1, 1, 7, 7, 9, 9, 43, 131, 385, 527, 757, 1263, 5285, 16309, 0 }; + static ulong[] dim1233JoeKuoD5Init = { 1, 3, 5, 3, 3, 39, 5, 163, 459, 697, 715, 3827, 3295, 9163, 0 }; + static ulong[] dim1234JoeKuoD5Init = { 1, 1, 7, 15, 7, 29, 7, 177, 207, 465, 59, 1485, 7731, 9843, 0 }; + static ulong[] dim1235JoeKuoD5Init = { 1, 3, 7, 13, 21, 57, 87, 191, 399, 689, 935, 2771, 1025, 715, 0 }; + static ulong[] dim1236JoeKuoD5Init = { 1, 3, 3, 1, 29, 19, 107, 253, 155, 163, 659, 3711, 2127, 10465, 0 }; + static ulong[] dim1237JoeKuoD5Init = { 1, 3, 3, 13, 7, 43, 27, 211, 407, 153, 1939, 3243, 6655, 15983, 0 }; + static ulong[] dim1238JoeKuoD5Init = { 1, 1, 1, 5, 27, 21, 23, 63, 271, 515, 261, 1947, 6257, 12861, 0 }; + static ulong[] dim1239JoeKuoD5Init = { 1, 3, 3, 1, 19, 57, 67, 221, 179, 725, 1179, 3983, 1585, 5899, 0 }; + static ulong[] dim1240JoeKuoD5Init = { 1, 3, 3, 15, 7, 61, 97, 131, 145, 637, 733, 2533, 1993, 14399, 0 }; + static ulong[] dim1241JoeKuoD5Init = { 1, 1, 5, 15, 13, 39, 83, 247, 235, 621, 1557, 3075, 3165, 16027, 0 }; + static ulong[] dim1242JoeKuoD5Init = { 1, 1, 1, 15, 9, 11, 111, 153, 437, 687, 1845, 3547, 2097, 2219, 0 }; + static ulong[] dim1243JoeKuoD5Init = { 1, 1, 7, 13, 21, 13, 43, 33, 51, 1021, 1883, 1261, 2823, 12771, 0 }; + static ulong[] dim1244JoeKuoD5Init = { 1, 3, 3, 9, 3, 35, 19, 127, 419, 203, 1869, 1477, 5239, 6113, 0 }; + static ulong[] dim1245JoeKuoD5Init = { 1, 1, 5, 13, 31, 63, 75, 185, 507, 401, 1079, 67, 1621, 2849, 0 }; + static ulong[] dim1246JoeKuoD5Init = { 1, 1, 1, 1, 31, 61, 125, 77, 169, 51, 1115, 1625, 3533, 5953, 0 }; + static ulong[] dim1247JoeKuoD5Init = { 1, 1, 3, 15, 29, 51, 23, 43, 505, 313, 887, 551, 4401, 2133, 0 }; + static ulong[] dim1248JoeKuoD5Init = { 1, 3, 7, 15, 11, 37, 55, 161, 353, 347, 1991, 4009, 2073, 12169, 0 }; + static ulong[] dim1249JoeKuoD5Init = { 1, 3, 3, 11, 29, 51, 15, 13, 391, 677, 225, 1467, 6615, 1895, 0 }; + static ulong[] dim1250JoeKuoD5Init = { 1, 1, 7, 3, 29, 15, 93, 103, 147, 323, 837, 1983, 1613, 10667, 0 }; + static ulong[] dim1251JoeKuoD5Init = { 1, 1, 5, 9, 21, 11, 39, 95, 473, 591, 1645, 67, 2793, 11217, 0 }; + static ulong[] dim1252JoeKuoD5Init = { 1, 3, 7, 5, 9, 51, 1, 243, 445, 583, 375, 2289, 4911, 10511, 0 }; + static ulong[] dim1253JoeKuoD5Init = { 1, 1, 7, 7, 23, 15, 111, 239, 247, 511, 1723, 2911, 2627, 10549, 0 }; + static ulong[] dim1254JoeKuoD5Init = { 1, 3, 1, 9, 15, 37, 31, 135, 347, 599, 765, 2561, 4635, 10659, 0 }; + static ulong[] dim1255JoeKuoD5Init = { 1, 1, 5, 11, 9, 49, 93, 187, 415, 247, 1871, 617, 6711, 3283, 0 }; + static ulong[] dim1256JoeKuoD5Init = { 1, 3, 7, 11, 25, 25, 37, 97, 365, 477, 1383, 1357, 693, 14743, 0 }; + static ulong[] dim1257JoeKuoD5Init = { 1, 1, 3, 11, 25, 19, 109, 99, 471, 661, 1633, 3773, 921, 4113, 0 }; + static ulong[] dim1258JoeKuoD5Init = { 1, 1, 3, 11, 13, 61, 21, 255, 161, 233, 1181, 3003, 1465, 9299, 0 }; + static ulong[] dim1259JoeKuoD5Init = { 1, 3, 7, 5, 7, 59, 53, 129, 127, 961, 893, 499, 5265, 2299, 0 }; + static ulong[] dim1260JoeKuoD5Init = { 1, 1, 5, 9, 29, 45, 85, 173, 131, 775, 1527, 1899, 4833, 12763, 0 }; + static ulong[] dim1261JoeKuoD5Init = { 1, 1, 7, 3, 1, 1, 115, 245, 205, 609, 1729, 915, 5965, 11001, 0 }; + static ulong[] dim1262JoeKuoD5Init = { 1, 1, 3, 15, 3, 61, 91, 93, 363, 457, 1497, 2539, 553, 7581, 0 }; + static ulong[] dim1263JoeKuoD5Init = { 1, 1, 3, 1, 29, 5, 7, 171, 393, 381, 935, 3467, 6199, 6625, 0 }; + static ulong[] dim1264JoeKuoD5Init = { 1, 1, 7, 13, 15, 25, 65, 137, 349, 61, 1035, 591, 4317, 13949, 0 }; + static ulong[] dim1265JoeKuoD5Init = { 1, 1, 3, 9, 27, 17, 87, 233, 227, 341, 639, 1813, 871, 12871, 0 }; + static ulong[] dim1266JoeKuoD5Init = { 1, 3, 1, 13, 29, 15, 31, 81, 61, 857, 1305, 3631, 2919, 2093, 0 }; + static ulong[] dim1267JoeKuoD5Init = { 1, 1, 1, 3, 27, 5, 49, 1, 49, 745, 543, 847, 2469, 3513, 0 }; + static ulong[] dim1268JoeKuoD5Init = { 1, 1, 1, 3, 15, 39, 47, 73, 33, 469, 1809, 2105, 7995, 11285, 0 }; + static ulong[] dim1269JoeKuoD5Init = { 1, 3, 5, 15, 9, 9, 81, 211, 295, 791, 1267, 2945, 5639, 6967, 0 }; + static ulong[] dim1270JoeKuoD5Init = { 1, 1, 7, 9, 13, 11, 43, 221, 161, 263, 905, 2767, 4491, 7605, 0 }; + static ulong[] dim1271JoeKuoD5Init = { 1, 1, 3, 15, 13, 9, 91, 123, 449, 21, 941, 1391, 3469, 16027, 0 }; + static ulong[] dim1272JoeKuoD5Init = { 1, 1, 3, 11, 5, 13, 77, 69, 245, 905, 231, 547, 2933, 4307, 0 }; + static ulong[] dim1273JoeKuoD5Init = { 1, 1, 3, 1, 25, 59, 49, 49, 183, 213, 29, 1801, 6271, 16283, 0 }; + static ulong[] dim1274JoeKuoD5Init = { 1, 1, 3, 11, 3, 15, 35, 157, 87, 453, 1939, 2697, 3325, 8679, 0 }; + static ulong[] dim1275JoeKuoD5Init = { 1, 1, 7, 13, 7, 45, 77, 73, 203, 321, 425, 581, 481, 15367, 0 }; + static ulong[] dim1276JoeKuoD5Init = { 1, 3, 1, 15, 11, 51, 11, 59, 355, 677, 1565, 123, 2403, 12835, 0 }; + static ulong[] dim1277JoeKuoD5Init = { 1, 1, 3, 5, 7, 27, 17, 81, 295, 131, 955, 4065, 797, 16165, 0 }; + static ulong[] dim1278JoeKuoD5Init = { 1, 1, 1, 5, 29, 63, 51, 215, 269, 1013, 517, 1857, 141, 4495, 0 }; + static ulong[] dim1279JoeKuoD5Init = { 1, 3, 7, 5, 17, 47, 121, 199, 177, 1023, 1009, 3535, 4825, 16349, 0 }; + static ulong[] dim1280JoeKuoD5Init = { 1, 1, 5, 1, 21, 25, 107, 165, 43, 213, 1847, 1945, 3463, 2259, 0 }; + static ulong[] dim1281JoeKuoD5Init = { 1, 3, 5, 7, 5, 5, 5, 65, 493, 725, 755, 111, 6673, 213, 0 }; + static ulong[] dim1282JoeKuoD5Init = { 1, 1, 3, 1, 3, 29, 17, 87, 207, 793, 873, 2341, 3505, 5751, 0 }; + static ulong[] dim1283JoeKuoD5Init = { 1, 1, 3, 7, 27, 47, 123, 157, 427, 273, 139, 4043, 4083, 14121, 0 }; + static ulong[] dim1284JoeKuoD5Init = { 1, 3, 7, 9, 25, 17, 41, 245, 441, 47, 1, 2393, 405, 4021, 0 }; + static ulong[] dim1285JoeKuoD5Init = { 1, 3, 3, 13, 31, 9, 115, 165, 93, 701, 255, 895, 995, 12371, 0 }; + static ulong[] dim1286JoeKuoD5Init = { 1, 1, 1, 11, 23, 13, 9, 141, 31, 973, 441, 3335, 2567, 6993, 0 }; + static ulong[] dim1287JoeKuoD5Init = { 1, 1, 1, 13, 19, 25, 61, 139, 39, 987, 385, 2199, 7675, 13301, 0 }; + static ulong[] dim1288JoeKuoD5Init = { 1, 3, 5, 3, 1, 35, 121, 187, 273, 905, 245, 1031, 6203, 8165, 0 }; + static ulong[] dim1289JoeKuoD5Init = { 1, 1, 5, 13, 31, 59, 97, 45, 25, 803, 1245, 2659, 7471, 8367, 0 }; + static ulong[] dim1290JoeKuoD5Init = { 1, 1, 5, 11, 21, 41, 47, 183, 419, 279, 1901, 1081, 3575, 8591, 0 }; + static ulong[] dim1291JoeKuoD5Init = { 1, 3, 3, 5, 11, 39, 119, 245, 403, 703, 1547, 743, 7957, 15123, 0 }; + static ulong[] dim1292JoeKuoD5Init = { 1, 3, 5, 11, 11, 31, 71, 55, 3, 961, 991, 1665, 5539, 8187, 0 }; + static ulong[] dim1293JoeKuoD5Init = { 1, 1, 3, 3, 19, 7, 1, 35, 463, 1003, 555, 669, 2119, 10939, 0 }; + static ulong[] dim1294JoeKuoD5Init = { 1, 3, 3, 13, 17, 29, 99, 133, 107, 907, 7, 3047, 1263, 7497, 0 }; + static ulong[] dim1295JoeKuoD5Init = { 1, 3, 3, 15, 1, 53, 39, 191, 201, 189, 465, 453, 1967, 1033, 0 }; + static ulong[] dim1296JoeKuoD5Init = { 1, 3, 7, 13, 25, 19, 5, 155, 105, 923, 2045, 2889, 7685, 13847, 0 }; + static ulong[] dim1297JoeKuoD5Init = { 1, 3, 7, 13, 7, 61, 93, 41, 183, 783, 2011, 2967, 2949, 10247, 0 }; + static ulong[] dim1298JoeKuoD5Init = { 1, 1, 7, 9, 3, 53, 105, 63, 9, 131, 897, 347, 7683, 16027, 0 }; + static ulong[] dim1299JoeKuoD5Init = { 1, 1, 1, 9, 19, 37, 37, 143, 37, 493, 533, 733, 2295, 4203, 0 }; + static ulong[] dim1300JoeKuoD5Init = { 1, 3, 7, 5, 15, 23, 83, 185, 495, 1023, 1473, 1501, 373, 201, 0 }; + static ulong[] dim1301JoeKuoD5Init = { 1, 1, 3, 13, 31, 51, 115, 233, 289, 201, 869, 3177, 4649, 16111, 0 }; + static ulong[] dim1302JoeKuoD5Init = { 1, 3, 5, 5, 23, 7, 59, 233, 447, 781, 1249, 71, 5857, 15481, 0 }; + static ulong[] dim1303JoeKuoD5Init = { 1, 1, 3, 11, 31, 1, 67, 243, 129, 737, 1443, 3647, 2391, 3635, 0 }; + static ulong[] dim1304JoeKuoD5Init = { 1, 3, 7, 1, 17, 39, 117, 81, 395, 119, 413, 1295, 7889, 13569, 0 }; + static ulong[] dim1305JoeKuoD5Init = { 1, 3, 3, 5, 29, 5, 123, 89, 143, 779, 1173, 3211, 3027, 10145, 0 }; + static ulong[] dim1306JoeKuoD5Init = { 1, 1, 1, 7, 19, 53, 39, 199, 487, 797, 123, 871, 6335, 7957, 0 }; + static ulong[] dim1307JoeKuoD5Init = { 1, 3, 1, 7, 13, 11, 105, 121, 403, 283, 413, 1957, 6557, 8429, 0 }; + static ulong[] dim1308JoeKuoD5Init = { 1, 1, 5, 3, 23, 21, 109, 37, 463, 613, 927, 1857, 7003, 3477, 0 }; + static ulong[] dim1309JoeKuoD5Init = { 1, 3, 1, 1, 15, 37, 81, 27, 259, 661, 287, 615, 6151, 13759, 0 }; + static ulong[] dim1310JoeKuoD5Init = { 1, 1, 7, 7, 27, 59, 85, 223, 499, 571, 1853, 1419, 7761, 8385, 0 }; + static ulong[] dim1311JoeKuoD5Init = { 1, 3, 7, 9, 23, 57, 53, 163, 437, 657, 851, 3177, 6477, 13003, 0 }; + static ulong[] dim1312JoeKuoD5Init = { 1, 3, 7, 13, 3, 7, 37, 167, 49, 595, 1493, 369, 687, 13463, 0 }; + static ulong[] dim1313JoeKuoD5Init = { 1, 3, 1, 11, 27, 63, 49, 157, 379, 779, 99, 3457, 4477, 6531, 0 }; + static ulong[] dim1314JoeKuoD5Init = { 1, 1, 1, 1, 5, 55, 77, 159, 371, 369, 743, 3571, 1877, 14767, 0 }; + static ulong[] dim1315JoeKuoD5Init = { 1, 3, 1, 15, 25, 11, 65, 187, 253, 437, 1301, 2871, 6219, 817, 0 }; + static ulong[] dim1316JoeKuoD5Init = { 1, 1, 7, 13, 23, 33, 25, 49, 491, 315, 11, 2163, 6155, 23, 0 }; + static ulong[] dim1317JoeKuoD5Init = { 1, 3, 5, 7, 27, 31, 81, 7, 355, 289, 1481, 2969, 1067, 7399, 0 }; + static ulong[] dim1318JoeKuoD5Init = { 1, 1, 1, 7, 1, 57, 39, 201, 271, 223, 1117, 727, 7491, 4043, 0 }; + static ulong[] dim1319JoeKuoD5Init = { 1, 3, 1, 7, 9, 57, 17, 161, 221, 385, 2027, 1195, 2489, 12377, 0 }; + static ulong[] dim1320JoeKuoD5Init = { 1, 3, 1, 3, 27, 59, 101, 27, 177, 1005, 63, 3029, 7345, 14429, 0 }; + static ulong[] dim1321JoeKuoD5Init = { 1, 1, 7, 7, 17, 5, 111, 239, 85, 57, 1625, 657, 5931, 4929, 0 }; + static ulong[] dim1322JoeKuoD5Init = { 1, 3, 7, 3, 7, 41, 29, 9, 73, 875, 1665, 325, 27, 997, 0 }; + static ulong[] dim1323JoeKuoD5Init = { 1, 1, 5, 7, 21, 61, 119, 247, 307, 1011, 1489, 2361, 5781, 2465, 0 }; + static ulong[] dim1324JoeKuoD5Init = { 1, 3, 7, 3, 1, 21, 105, 77, 57, 983, 1519, 3543, 5025, 14051, 0 }; + static ulong[] dim1325JoeKuoD5Init = { 1, 1, 3, 5, 13, 39, 113, 69, 81, 155, 101, 427, 733, 10085, 0 }; + static ulong[] dim1326JoeKuoD5Init = { 1, 3, 1, 3, 1, 25, 109, 109, 303, 323, 565, 2267, 2755, 9165, 0 }; + static ulong[] dim1327JoeKuoD5Init = { 1, 1, 5, 3, 15, 43, 103, 163, 265, 849, 1969, 2247, 4495, 7301, 0 }; + static ulong[] dim1328JoeKuoD5Init = { 1, 1, 3, 3, 23, 9, 81, 103, 193, 845, 1603, 2493, 4919, 10649, 0 }; + static ulong[] dim1329JoeKuoD5Init = { 1, 1, 5, 1, 9, 23, 91, 33, 115, 599, 1755, 53, 1757, 145, 0 }; + static ulong[] dim1330JoeKuoD5Init = { 1, 3, 1, 11, 1, 39, 5, 233, 399, 187, 943, 2325, 437, 4421, 0 }; + static ulong[] dim1331JoeKuoD5Init = { 1, 1, 5, 13, 11, 39, 29, 131, 363, 885, 1921, 3703, 4197, 9703, 0 }; + static ulong[] dim1332JoeKuoD5Init = { 1, 3, 7, 5, 21, 43, 27, 151, 193, 211, 1229, 4031, 681, 5103, 0 }; + static ulong[] dim1333JoeKuoD5Init = { 1, 3, 7, 3, 19, 23, 41, 47, 315, 169, 271, 1877, 6357, 7709, 0 }; + static ulong[] dim1334JoeKuoD5Init = { 1, 3, 5, 1, 11, 27, 123, 33, 287, 293, 335, 2331, 141, 10095, 0 }; + static ulong[] dim1335JoeKuoD5Init = { 1, 1, 3, 5, 15, 33, 93, 123, 277, 833, 115, 3799, 1519, 153, 0 }; + static ulong[] dim1336JoeKuoD5Init = { 1, 1, 7, 15, 11, 3, 97, 225, 179, 601, 687, 253, 2839, 10985, 0 }; + static ulong[] dim1337JoeKuoD5Init = { 1, 3, 5, 3, 11, 51, 5, 141, 487, 325, 1691, 1291, 4677, 9087, 0 }; + static ulong[] dim1338JoeKuoD5Init = { 1, 3, 5, 9, 5, 11, 99, 195, 459, 171, 361, 1621, 5377, 4651, 0 }; + static ulong[] dim1339JoeKuoD5Init = { 1, 3, 3, 3, 29, 47, 5, 29, 107, 751, 739, 2815, 3709, 15493, 0 }; + static ulong[] dim1340JoeKuoD5Init = { 1, 3, 7, 1, 3, 63, 47, 15, 433, 501, 1687, 2035, 6263, 12681, 0 }; + static ulong[] dim1341JoeKuoD5Init = { 1, 3, 7, 13, 1, 57, 91, 33, 217, 141, 2005, 2405, 1987, 14957, 0 }; + static ulong[] dim1342JoeKuoD5Init = { 1, 3, 3, 13, 25, 23, 93, 37, 129, 747, 1607, 849, 2119, 11855, 0 }; + static ulong[] dim1343JoeKuoD5Init = { 1, 3, 5, 9, 15, 55, 55, 125, 235, 455, 2027, 1709, 7217, 10341, 0 }; + static ulong[] dim1344JoeKuoD5Init = { 1, 3, 5, 7, 1, 3, 69, 167, 373, 87, 901, 2333, 6751, 5809, 0 }; + static ulong[] dim1345JoeKuoD5Init = { 1, 3, 5, 9, 19, 25, 67, 197, 395, 735, 941, 1753, 3923, 8805, 0 }; + static ulong[] dim1346JoeKuoD5Init = { 1, 1, 7, 9, 17, 29, 1, 205, 511, 179, 1191, 17, 3179, 6891, 0 }; + static ulong[] dim1347JoeKuoD5Init = { 1, 1, 1, 9, 9, 31, 99, 133, 253, 239, 1729, 4093, 5759, 15357, 0 }; + static ulong[] dim1348JoeKuoD5Init = { 1, 1, 7, 3, 31, 35, 125, 167, 417, 431, 709, 415, 1093, 11361, 0 }; + static ulong[] dim1349JoeKuoD5Init = { 1, 1, 7, 11, 7, 59, 57, 89, 119, 537, 1157, 2539, 5783, 15093, 0 }; + static ulong[] dim1350JoeKuoD5Init = { 1, 1, 5, 7, 17, 41, 105, 33, 301, 601, 537, 3877, 797, 1319, 0 }; + static ulong[] dim1351JoeKuoD5Init = { 1, 1, 7, 7, 3, 59, 79, 47, 191, 985, 83, 3535, 4135, 16165, 0 }; + static ulong[] dim1352JoeKuoD5Init = { 1, 3, 7, 3, 13, 61, 35, 193, 141, 961, 1733, 4051, 2657, 9183, 0 }; + static ulong[] dim1353JoeKuoD5Init = { 1, 3, 3, 9, 25, 49, 127, 233, 291, 445, 1639, 4023, 4791, 279, 0 }; + static ulong[] dim1354JoeKuoD5Init = { 1, 1, 7, 11, 15, 39, 91, 81, 433, 7, 1897, 2659, 7877, 15733, 0 }; + static ulong[] dim1355JoeKuoD5Init = { 1, 3, 3, 5, 19, 5, 125, 181, 305, 377, 1699, 2157, 4617, 7165, 0 }; + static ulong[] dim1356JoeKuoD5Init = { 1, 3, 5, 13, 11, 27, 19, 217, 171, 343, 61, 3799, 4923, 14279, 0 }; + static ulong[] dim1357JoeKuoD5Init = { 1, 1, 1, 15, 13, 41, 19, 19, 359, 101, 1795, 127, 7067, 4327, 0 }; + static ulong[] dim1358JoeKuoD5Init = { 1, 3, 5, 15, 15, 5, 43, 47, 103, 549, 767, 2695, 1689, 5569, 0 }; + static ulong[] dim1359JoeKuoD5Init = { 1, 1, 7, 9, 7, 33, 35, 105, 283, 957, 1255, 2085, 6263, 4537, 0 }; + static ulong[] dim1360JoeKuoD5Init = { 1, 3, 7, 9, 27, 23, 49, 169, 455, 163, 301, 3107, 6859, 14477, 0 }; + static ulong[] dim1361JoeKuoD5Init = { 1, 1, 5, 15, 13, 11, 25, 231, 171, 173, 661, 1921, 3535, 10157, 0 }; + static ulong[] dim1362JoeKuoD5Init = { 1, 1, 7, 11, 27, 19, 23, 97, 409, 347, 1413, 2273, 7305, 12597, 0 }; + static ulong[] dim1363JoeKuoD5Init = { 1, 3, 7, 15, 11, 63, 49, 247, 459, 195, 1579, 539, 6283, 14829, 0 }; + static ulong[] dim1364JoeKuoD5Init = { 1, 3, 3, 5, 19, 37, 105, 31, 87, 413, 511, 271, 6265, 9499, 0 }; + static ulong[] dim1365JoeKuoD5Init = { 1, 1, 3, 13, 23, 39, 97, 239, 397, 975, 1369, 2397, 409, 3495, 0 }; + static ulong[] dim1366JoeKuoD5Init = { 1, 3, 1, 1, 25, 45, 11, 81, 233, 299, 1269, 1129, 1679, 10195, 0 }; + static ulong[] dim1367JoeKuoD5Init = { 1, 3, 3, 5, 13, 29, 3, 189, 231, 535, 1201, 1215, 1889, 6169, 0 }; + static ulong[] dim1368JoeKuoD5Init = { 1, 3, 1, 15, 31, 53, 17, 197, 453, 13, 181, 2663, 3869, 7269, 0 }; + static ulong[] dim1369JoeKuoD5Init = { 1, 1, 1, 5, 27, 37, 71, 89, 505, 769, 1359, 295, 6061, 8363, 0 }; + static ulong[] dim1370JoeKuoD5Init = { 1, 3, 3, 1, 9, 1, 111, 157, 89, 777, 1713, 117, 285, 6353, 0 }; + static ulong[] dim1371JoeKuoD5Init = { 1, 1, 7, 11, 29, 53, 57, 3, 225, 885, 1445, 3673, 7857, 3843, 0 }; + static ulong[] dim1372JoeKuoD5Init = { 1, 3, 3, 11, 29, 23, 43, 19, 175, 573, 1709, 2303, 5607, 4347, 0 }; + static ulong[] dim1373JoeKuoD5Init = { 1, 1, 5, 7, 19, 41, 93, 13, 3, 483, 1365, 411, 5147, 10505, 0 }; + static ulong[] dim1374JoeKuoD5Init = { 1, 1, 7, 7, 3, 17, 51, 23, 19, 411, 741, 877, 7121, 7639, 0 }; + static ulong[] dim1375JoeKuoD5Init = { 1, 1, 5, 3, 7, 45, 103, 69, 387, 803, 29, 1469, 2139, 6397, 0 }; + static ulong[] dim1376JoeKuoD5Init = { 1, 3, 1, 3, 11, 43, 5, 19, 441, 285, 1657, 2133, 6343, 11817, 0 }; + static ulong[] dim1377JoeKuoD5Init = { 1, 3, 5, 1, 31, 31, 19, 15, 475, 131, 1687, 1647, 4685, 1135, 0 }; + static ulong[] dim1378JoeKuoD5Init = { 1, 1, 7, 7, 17, 59, 125, 127, 63, 451, 949, 4041, 6649, 12187, 0 }; + static ulong[] dim1379JoeKuoD5Init = { 1, 3, 3, 1, 25, 13, 59, 159, 107, 509, 787, 2517, 6679, 2809, 0 }; + static ulong[] dim1380JoeKuoD5Init = { 1, 3, 7, 5, 17, 5, 87, 235, 379, 599, 1971, 969, 853, 10481, 0 }; + static ulong[] dim1381JoeKuoD5Init = { 1, 1, 3, 15, 7, 35, 47, 113, 349, 451, 1827, 2647, 367, 2581, 0 }; + static ulong[] dim1382JoeKuoD5Init = { 1, 1, 7, 9, 1, 39, 29, 45, 365, 317, 129, 137, 5975, 3353, 0 }; + static ulong[] dim1383JoeKuoD5Init = { 1, 1, 1, 15, 17, 3, 5, 61, 11, 587, 769, 2127, 2625, 12545, 0 }; + static ulong[] dim1384JoeKuoD5Init = { 1, 3, 1, 7, 21, 1, 127, 235, 343, 807, 147, 3517, 3471, 4625, 0 }; + static ulong[] dim1385JoeKuoD5Init = { 1, 1, 3, 15, 31, 23, 81, 23, 171, 403, 1083, 4049, 1959, 16307, 0 }; + static ulong[] dim1386JoeKuoD5Init = { 1, 3, 7, 9, 21, 37, 99, 83, 33, 705, 369, 2445, 3253, 16171, 0 }; + static ulong[] dim1387JoeKuoD5Init = { 1, 3, 5, 9, 17, 61, 121, 75, 89, 823, 1519, 1997, 6433, 5013, 0 }; + static ulong[] dim1388JoeKuoD5Init = { 1, 1, 3, 11, 7, 47, 7, 71, 475, 517, 1271, 3815, 5969, 607, 0 }; + static ulong[] dim1389JoeKuoD5Init = { 1, 1, 3, 3, 13, 15, 37, 89, 43, 489, 1853, 1195, 3097, 10297, 0 }; + static ulong[] dim1390JoeKuoD5Init = { 1, 3, 3, 11, 25, 39, 95, 43, 145, 231, 1859, 3201, 1377, 7091, 0 }; + static ulong[] dim1391JoeKuoD5Init = { 1, 1, 7, 3, 13, 43, 117, 111, 231, 101, 1801, 739, 945, 15585, 0 }; + static ulong[] dim1392JoeKuoD5Init = { 1, 3, 5, 7, 23, 3, 35, 167, 485, 951, 1729, 1831, 2639, 6561, 0 }; + static ulong[] dim1393JoeKuoD5Init = { 1, 3, 3, 15, 5, 31, 103, 85, 111, 545, 789, 945, 2691, 327, 0 }; + static ulong[] dim1394JoeKuoD5Init = { 1, 1, 5, 11, 29, 61, 127, 59, 137, 485, 1673, 3295, 4185, 6489, 0 }; + static ulong[] dim1395JoeKuoD5Init = { 1, 1, 5, 9, 31, 9, 115, 11, 73, 267, 195, 1445, 873, 7285, 0 }; + static ulong[] dim1396JoeKuoD5Init = { 1, 3, 3, 7, 3, 19, 9, 71, 287, 89, 329, 953, 2237, 16341, 0 }; + static ulong[] dim1397JoeKuoD5Init = { 1, 3, 1, 13, 19, 31, 5, 49, 293, 65, 291, 93, 2553, 8407, 0 }; + static ulong[] dim1398JoeKuoD5Init = { 1, 1, 5, 15, 17, 13, 15, 111, 211, 935, 1165, 2975, 339, 16333, 0 }; + static ulong[] dim1399JoeKuoD5Init = { 1, 1, 1, 3, 17, 57, 9, 63, 243, 431, 289, 3493, 2879, 4801, 0 }; + static ulong[] dim1400JoeKuoD5Init = { 1, 1, 7, 3, 17, 15, 53, 191, 439, 981, 751, 4025, 7177, 4887, 0 }; + static ulong[] dim1401JoeKuoD5Init = { 1, 1, 5, 3, 11, 61, 43, 103, 151, 33, 421, 1949, 5915, 5515, 0 }; + static ulong[] dim1402JoeKuoD5Init = { 1, 1, 5, 3, 1, 55, 45, 227, 27, 491, 1479, 3323, 5485, 5493, 0 }; + static ulong[] dim1403JoeKuoD5Init = { 1, 1, 7, 1, 9, 11, 1, 249, 113, 415, 295, 3437, 3877, 6675, 0 }; + static ulong[] dim1404JoeKuoD5Init = { 1, 1, 5, 11, 9, 43, 127, 57, 115, 685, 165, 973, 2707, 2503, 0 }; + static ulong[] dim1405JoeKuoD5Init = { 1, 1, 5, 7, 1, 29, 125, 45, 307, 625, 1477, 2565, 2949, 1729, 0 }; + static ulong[] dim1406JoeKuoD5Init = { 1, 3, 1, 1, 23, 7, 45, 245, 301, 531, 1419, 1795, 5757, 15219, 0 }; + static ulong[] dim1407JoeKuoD5Init = { 1, 3, 3, 7, 15, 49, 71, 109, 145, 79, 1333, 1589, 3851, 2879, 0 }; + static ulong[] dim1408JoeKuoD5Init = { 1, 1, 3, 5, 11, 15, 37, 239, 217, 193, 1687, 1721, 8059, 9027, 0 }; + static ulong[] dim1409JoeKuoD5Init = { 1, 3, 5, 13, 13, 49, 57, 189, 433, 569, 1285, 1891, 6079, 13469, 0 }; + static ulong[] dim1410JoeKuoD5Init = { 1, 3, 1, 1, 19, 61, 27, 181, 365, 121, 883, 1611, 1521, 11437, 0 }; + static ulong[] dim1411JoeKuoD5Init = { 1, 1, 5, 3, 17, 37, 71, 71, 495, 519, 879, 2993, 6275, 14345, 0 }; + static ulong[] dim1412JoeKuoD5Init = { 1, 1, 1, 5, 29, 5, 121, 29, 293, 745, 1839, 2061, 2721, 11741, 0 }; + static ulong[] dim1413JoeKuoD5Init = { 1, 3, 1, 13, 23, 61, 55, 99, 409, 211, 783, 1841, 193, 1941, 0 }; + static ulong[] dim1414JoeKuoD5Init = { 1, 1, 5, 7, 11, 49, 87, 81, 225, 211, 1263, 1403, 6169, 6235, 0 }; + static ulong[] dim1415JoeKuoD5Init = { 1, 1, 7, 9, 11, 35, 71, 145, 417, 485, 1565, 2101, 4153, 5239, 0 }; + static ulong[] dim1416JoeKuoD5Init = { 1, 1, 5, 1, 13, 41, 45, 79, 157, 477, 677, 3961, 1127, 1139, 0 }; + static ulong[] dim1417JoeKuoD5Init = { 1, 3, 1, 13, 27, 39, 23, 197, 123, 431, 273, 2723, 1303, 13271, 0 }; + static ulong[] dim1418JoeKuoD5Init = { 1, 3, 5, 9, 13, 21, 59, 109, 267, 173, 997, 2701, 3719, 3703, 0 }; + static ulong[] dim1419JoeKuoD5Init = { 1, 3, 3, 1, 1, 5, 57, 181, 241, 1, 1063, 199, 8181, 12721, 0 }; + static ulong[] dim1420JoeKuoD5Init = { 1, 1, 7, 9, 15, 61, 107, 231, 65, 933, 677, 3883, 2621, 8821, 0 }; + static ulong[] dim1421JoeKuoD5Init = { 1, 1, 7, 1, 9, 33, 41, 55, 503, 683, 747, 3619, 7885, 851, 0 }; + static ulong[] dim1422JoeKuoD5Init = { 1, 1, 5, 5, 9, 25, 27, 123, 97, 731, 583, 2535, 1267, 5921, 0 }; + static ulong[] dim1423JoeKuoD5Init = { 1, 3, 1, 15, 27, 63, 69, 99, 475, 709, 1239, 861, 1229, 11369, 0 }; + static ulong[] dim1424JoeKuoD5Init = { 1, 3, 3, 13, 17, 47, 123, 159, 57, 871, 465, 783, 4093, 15277, 0 }; + static ulong[] dim1425JoeKuoD5Init = { 1, 3, 7, 9, 17, 47, 89, 139, 301, 45, 627, 4073, 3187, 9633, 0 }; + static ulong[] dim1426JoeKuoD5Init = { 1, 3, 5, 11, 21, 43, 19, 25, 457, 879, 113, 847, 201, 15683, 0 }; + static ulong[] dim1427JoeKuoD5Init = { 1, 3, 3, 15, 9, 47, 43, 215, 407, 979, 51, 635, 467, 6365, 0 }; + static ulong[] dim1428JoeKuoD5Init = { 1, 3, 3, 5, 7, 11, 53, 5, 471, 317, 1719, 755, 5211, 7599, 0 }; + static ulong[] dim1429JoeKuoD5Init = { 1, 3, 1, 3, 11, 43, 67, 203, 15, 75, 1063, 1763, 3537, 13511, 0 }; + static ulong[] dim1430JoeKuoD5Init = { 1, 3, 7, 1, 17, 37, 91, 55, 95, 843, 751, 3501, 6203, 2999, 0 }; + static ulong[] dim1431JoeKuoD5Init = { 1, 3, 7, 13, 19, 61, 37, 157, 309, 361, 1499, 1845, 3675, 6221, 0 }; + static ulong[] dim1432JoeKuoD5Init = { 1, 3, 1, 11, 15, 9, 25, 123, 25, 525, 227, 3429, 1573, 12321, 0 }; + static ulong[] dim1433JoeKuoD5Init = { 1, 3, 7, 11, 9, 17, 91, 61, 263, 129, 1853, 1911, 5065, 775, 0 }; + static ulong[] dim1434JoeKuoD5Init = { 1, 1, 3, 3, 31, 15, 3, 207, 505, 123, 477, 1285, 7007, 2873, 0 }; + static ulong[] dim1435JoeKuoD5Init = { 1, 1, 1, 7, 7, 15, 123, 249, 467, 229, 845, 1913, 461, 6235, 0 }; + static ulong[] dim1436JoeKuoD5Init = { 1, 3, 3, 9, 15, 9, 121, 211, 231, 491, 521, 3621, 7285, 3165, 0 }; + static ulong[] dim1437JoeKuoD5Init = { 1, 1, 7, 15, 21, 43, 1, 35, 339, 671, 719, 1739, 501, 9573, 0 }; + static ulong[] dim1438JoeKuoD5Init = { 1, 1, 1, 5, 13, 37, 81, 1, 281, 785, 831, 991, 7485, 15619, 0 }; + static ulong[] dim1439JoeKuoD5Init = { 1, 3, 7, 1, 29, 47, 29, 99, 311, 519, 545, 1115, 6651, 793, 0 }; + static ulong[] dim1440JoeKuoD5Init = { 1, 3, 5, 11, 17, 15, 17, 65, 101, 411, 231, 2959, 8077, 673, 0 }; + static ulong[] dim1441JoeKuoD5Init = { 1, 3, 5, 9, 27, 47, 127, 237, 319, 293, 1109, 3863, 213, 2149, 0 }; + static ulong[] dim1442JoeKuoD5Init = { 1, 1, 3, 13, 11, 61, 27, 129, 57, 743, 889, 3707, 469, 11949, 0 }; + static ulong[] dim1443JoeKuoD5Init = { 1, 1, 7, 13, 23, 13, 119, 125, 75, 753, 1951, 1181, 291, 11737, 0 }; + static ulong[] dim1444JoeKuoD5Init = { 1, 3, 3, 5, 31, 19, 43, 113, 309, 721, 175, 1041, 7123, 103, 0 }; + static ulong[] dim1445JoeKuoD5Init = { 1, 3, 3, 9, 21, 19, 71, 175, 309, 9, 807, 961, 6741, 5075, 0 }; + static ulong[] dim1446JoeKuoD5Init = { 1, 3, 1, 9, 15, 27, 83, 207, 67, 71, 289, 2901, 7637, 9525, 0 }; + static ulong[] dim1447JoeKuoD5Init = { 1, 1, 7, 15, 21, 9, 19, 67, 401, 165, 1297, 3159, 2881, 15979, 0 }; + static ulong[] dim1448JoeKuoD5Init = { 1, 1, 5, 1, 11, 21, 27, 33, 95, 853, 1699, 875, 6519, 9109, 0 }; + static ulong[] dim1449JoeKuoD5Init = { 1, 3, 7, 3, 31, 5, 123, 215, 165, 405, 623, 845, 4149, 5015, 0 }; + static ulong[] dim1450JoeKuoD5Init = { 1, 3, 7, 7, 31, 13, 23, 55, 129, 789, 803, 2077, 1885, 1669, 0 }; + static ulong[] dim1451JoeKuoD5Init = { 1, 1, 5, 11, 31, 39, 93, 7, 485, 571, 417, 3839, 1289, 4127, 0 }; + static ulong[] dim1452JoeKuoD5Init = { 1, 1, 7, 11, 23, 63, 123, 249, 75, 515, 2009, 949, 3291, 727, 0 }; + static ulong[] dim1453JoeKuoD5Init = { 1, 1, 3, 13, 21, 15, 57, 235, 25, 507, 1055, 3161, 4351, 8855, 0 }; + static ulong[] dim1454JoeKuoD5Init = { 1, 3, 5, 7, 23, 39, 71, 151, 377, 469, 665, 1197, 3503, 655, 0 }; + static ulong[] dim1455JoeKuoD5Init = { 1, 3, 5, 3, 5, 35, 67, 203, 33, 319, 925, 1021, 6869, 5145, 0 }; + static ulong[] dim1456JoeKuoD5Init = { 1, 1, 3, 3, 21, 61, 119, 195, 383, 573, 135, 2371, 1665, 4957, 0 }; + static ulong[] dim1457JoeKuoD5Init = { 1, 3, 7, 1, 7, 47, 93, 201, 269, 329, 209, 1659, 1547, 4605, 0 }; + static ulong[] dim1458JoeKuoD5Init = { 1, 3, 1, 1, 9, 47, 71, 13, 451, 51, 1073, 3691, 6881, 14801, 0 }; + static ulong[] dim1459JoeKuoD5Init = { 1, 3, 5, 3, 13, 33, 75, 155, 283, 599, 517, 2251, 6217, 10487, 0 }; + static ulong[] dim1460JoeKuoD5Init = { 1, 1, 1, 3, 7, 49, 65, 235, 159, 733, 939, 283, 6935, 14367, 0 }; + static ulong[] dim1461JoeKuoD5Init = { 1, 1, 3, 13, 7, 19, 71, 227, 307, 515, 1701, 747, 3475, 8165, 0 }; + static ulong[] dim1462JoeKuoD5Init = { 1, 3, 1, 11, 13, 19, 1, 97, 425, 739, 451, 3789, 5337, 2023, 0 }; + static ulong[] dim1463JoeKuoD5Init = { 1, 1, 7, 9, 7, 27, 23, 169, 137, 537, 61, 2207, 917, 1209, 0 }; + static ulong[] dim1464JoeKuoD5Init = { 1, 1, 3, 3, 29, 5, 121, 197, 159, 467, 581, 1679, 6605, 1989, 0 }; + static ulong[] dim1465JoeKuoD5Init = { 1, 1, 1, 13, 5, 33, 61, 77, 383, 977, 781, 175, 8151, 7979, 0 }; + static ulong[] dim1466JoeKuoD5Init = { 1, 3, 1, 13, 1, 1, 3, 95, 193, 453, 649, 1137, 485, 14345, 0 }; + static ulong[] dim1467JoeKuoD5Init = { 1, 3, 7, 7, 1, 13, 41, 159, 327, 105, 1569, 475, 1295, 3767, 0 }; + static ulong[] dim1468JoeKuoD5Init = { 1, 3, 5, 3, 25, 7, 73, 235, 271, 491, 1385, 2567, 1463, 12731, 0 }; + static ulong[] dim1469JoeKuoD5Init = { 1, 3, 5, 1, 9, 9, 37, 199, 249, 9, 299, 3891, 2373, 11553, 0 }; + static ulong[] dim1470JoeKuoD5Init = { 1, 1, 7, 13, 19, 47, 81, 25, 125, 933, 1637, 469, 6351, 4219, 0 }; + static ulong[] dim1471JoeKuoD5Init = { 1, 1, 3, 7, 31, 5, 67, 13, 63, 615, 1089, 2291, 3105, 7009, 0 }; + static ulong[] dim1472JoeKuoD5Init = { 1, 1, 5, 1, 1, 43, 49, 141, 189, 1015, 1527, 1511, 3093, 5497, 0 }; + static ulong[] dim1473JoeKuoD5Init = { 1, 3, 5, 1, 3, 51, 121, 89, 161, 517, 467, 2837, 2275, 4987, 0 }; + static ulong[] dim1474JoeKuoD5Init = { 1, 3, 7, 13, 9, 63, 31, 109, 331, 607, 1271, 3639, 617, 13177, 0 }; + static ulong[] dim1475JoeKuoD5Init = { 1, 1, 1, 15, 9, 25, 73, 237, 145, 885, 1945, 1871, 5401, 15403, 0 }; + static ulong[] dim1476JoeKuoD5Init = { 1, 1, 3, 5, 1, 63, 29, 145, 377, 429, 1663, 1643, 2713, 6621, 0 }; + static ulong[] dim1477JoeKuoD5Init = { 1, 1, 1, 5, 29, 7, 87, 53, 129, 503, 961, 3535, 3255, 7621, 0 }; + static ulong[] dim1478JoeKuoD5Init = { 1, 3, 3, 1, 5, 47, 13, 243, 155, 863, 103, 1699, 5063, 8221, 0 }; + static ulong[] dim1479JoeKuoD5Init = { 1, 1, 1, 9, 31, 61, 1, 253, 67, 369, 521, 3429, 6935, 3383, 0 }; + static ulong[] dim1480JoeKuoD5Init = { 1, 1, 1, 3, 11, 61, 11, 187, 145, 7, 535, 831, 933, 7779, 0 }; + static ulong[] dim1481JoeKuoD5Init = { 1, 3, 7, 1, 25, 33, 117, 161, 169, 33, 1415, 1493, 1599, 1109, 0 }; + static ulong[] dim1482JoeKuoD5Init = { 1, 3, 1, 3, 29, 19, 75, 143, 467, 785, 455, 2593, 7539, 6283, 0 }; + static ulong[] dim1483JoeKuoD5Init = { 1, 3, 3, 15, 11, 5, 19, 187, 357, 955, 631, 3697, 4641, 14353, 0 }; + static ulong[] dim1484JoeKuoD5Init = { 1, 3, 7, 15, 3, 21, 25, 79, 375, 611, 915, 2491, 5691, 773, 0 }; + static ulong[] dim1485JoeKuoD5Init = { 1, 3, 3, 7, 29, 23, 7, 27, 207, 157, 1021, 2411, 5061, 7493, 0 }; + static ulong[] dim1486JoeKuoD5Init = { 1, 3, 7, 5, 13, 7, 7, 159, 393, 51, 1573, 1353, 2373, 12721, 0 }; + static ulong[] dim1487JoeKuoD5Init = { 1, 1, 7, 13, 5, 55, 43, 7, 411, 353, 379, 2213, 6257, 5825, 0 }; + static ulong[] dim1488JoeKuoD5Init = { 1, 1, 3, 1, 5, 37, 65, 69, 251, 893, 1747, 4065, 3937, 1855, 0 }; + static ulong[] dim1489JoeKuoD5Init = { 1, 3, 7, 1, 3, 11, 97, 111, 509, 569, 839, 2431, 3475, 12283, 0 }; + static ulong[] dim1490JoeKuoD5Init = { 1, 1, 3, 11, 13, 63, 85, 193, 351, 491, 205, 1051, 403, 1749, 0 }; + static ulong[] dim1491JoeKuoD5Init = { 1, 3, 3, 1, 27, 61, 61, 169, 189, 549, 1589, 3567, 7301, 12723, 0 }; + static ulong[] dim1492JoeKuoD5Init = { 1, 3, 1, 7, 13, 39, 121, 75, 261, 919, 1557, 635, 2123, 3771, 0 }; + static ulong[] dim1493JoeKuoD5Init = { 1, 1, 3, 13, 7, 39, 107, 109, 165, 91, 1049, 3897, 1395, 9573, 0 }; + static ulong[] dim1494JoeKuoD5Init = { 1, 1, 3, 5, 19, 9, 61, 209, 205, 363, 823, 2445, 7301, 7141, 0 }; + static ulong[] dim1495JoeKuoD5Init = { 1, 1, 1, 15, 5, 31, 13, 61, 153, 847, 67, 2227, 4119, 9231, 0 }; + static ulong[] dim1496JoeKuoD5Init = { 1, 3, 5, 9, 13, 63, 93, 199, 437, 319, 735, 2015, 1719, 3253, 0 }; + static ulong[] dim1497JoeKuoD5Init = { 1, 1, 3, 5, 31, 19, 27, 141, 357, 647, 895, 345, 5937, 15711, 0 }; + static ulong[] dim1498JoeKuoD5Init = { 1, 3, 7, 1, 15, 35, 73, 69, 205, 545, 387, 3487, 7391, 3337, 0 }; + static ulong[] dim1499JoeKuoD5Init = { 1, 1, 7, 5, 27, 55, 51, 179, 125, 1013, 35, 2741, 7793, 4347, 0 }; + static ulong[] dim1500JoeKuoD5Init = { 1, 1, 3, 9, 31, 57, 55, 3, 385, 421, 1543, 2809, 1887, 13709, 0 }; + static ulong[] dim1501JoeKuoD5Init = { 1, 1, 3, 7, 29, 23, 115, 25, 295, 267, 101, 3005, 2601, 4959, 0 }; + static ulong[] dim1502JoeKuoD5Init = { 1, 3, 7, 13, 27, 11, 11, 35, 257, 23, 2013, 1369, 6503, 2589, 0 }; + static ulong[] dim1503JoeKuoD5Init = { 1, 3, 7, 15, 5, 43, 101, 87, 231, 761, 1991, 3167, 5689, 9565, 0 }; + static ulong[] dim1504JoeKuoD5Init = { 1, 3, 1, 11, 17, 37, 65, 249, 119, 727, 793, 929, 6275, 12173, 0 }; + static ulong[] dim1505JoeKuoD5Init = { 1, 1, 7, 9, 1, 11, 93, 27, 291, 411, 1069, 1283, 7593, 4335, 0 }; + static ulong[] dim1506JoeKuoD5Init = { 1, 1, 5, 1, 23, 45, 51, 93, 401, 515, 749, 1293, 8155, 15123, 0 }; + static ulong[] dim1507JoeKuoD5Init = { 1, 1, 1, 3, 21, 17, 67, 69, 371, 507, 143, 2393, 6267, 7143, 0 }; + static ulong[] dim1508JoeKuoD5Init = { 1, 3, 5, 11, 1, 5, 79, 75, 361, 689, 339, 1855, 6863, 15841, 0 }; + static ulong[] dim1509JoeKuoD5Init = { 1, 3, 1, 13, 23, 3, 43, 57, 233, 927, 1095, 1827, 401, 825, 0 }; + static ulong[] dim1510JoeKuoD5Init = { 1, 3, 3, 9, 31, 7, 67, 201, 27, 699, 535, 3073, 6895, 3021, 0 }; + static ulong[] dim1511JoeKuoD5Init = { 1, 3, 1, 13, 1, 19, 13, 83, 221, 727, 745, 2131, 3757, 1493, 0 }; + static ulong[] dim1512JoeKuoD5Init = { 1, 3, 7, 9, 13, 29, 101, 255, 243, 763, 535, 169, 1987, 4071, 0 }; + static ulong[] dim1513JoeKuoD5Init = { 1, 3, 7, 3, 21, 33, 117, 213, 143, 351, 1735, 1651, 5781, 8803, 0 }; + static ulong[] dim1514JoeKuoD5Init = { 1, 1, 3, 7, 17, 39, 57, 209, 141, 865, 1731, 3349, 7107, 15983, 0 }; + static ulong[] dim1515JoeKuoD5Init = { 1, 3, 5, 3, 21, 33, 117, 201, 481, 711, 1207, 1971, 3353, 5827, 0 }; + static ulong[] dim1516JoeKuoD5Init = { 1, 1, 7, 13, 13, 1, 121, 115, 449, 801, 1507, 2323, 6709, 5533, 0 }; + static ulong[] dim1517JoeKuoD5Init = { 1, 3, 3, 7, 5, 5, 35, 81, 469, 691, 443, 501, 6745, 421, 0 }; + static ulong[] dim1518JoeKuoD5Init = { 1, 1, 5, 13, 27, 41, 83, 39, 349, 585, 551, 643, 6659, 61, 0 }; + static ulong[] dim1519JoeKuoD5Init = { 1, 1, 1, 3, 25, 41, 45, 203, 89, 305, 1433, 1879, 6703, 14323, 0 }; + static ulong[] dim1520JoeKuoD5Init = { 1, 1, 5, 15, 27, 37, 97, 117, 431, 197, 807, 1841, 8075, 4613, 0 }; + static ulong[] dim1521JoeKuoD5Init = { 1, 1, 5, 3, 23, 47, 69, 129, 451, 113, 1397, 3005, 7599, 101, 0 }; + static ulong[] dim1522JoeKuoD5Init = { 1, 1, 3, 1, 11, 47, 117, 181, 85, 545, 571, 3227, 4097, 7937, 0 }; + static ulong[] dim1523JoeKuoD5Init = { 1, 1, 3, 9, 27, 53, 11, 181, 177, 121, 363, 2751, 4799, 14215, 0 }; + static ulong[] dim1524JoeKuoD5Init = { 1, 3, 5, 15, 27, 15, 101, 229, 411, 947, 189, 119, 6707, 5177, 0 }; + static ulong[] dim1525JoeKuoD5Init = { 1, 1, 5, 7, 29, 39, 65, 149, 185, 915, 889, 1651, 5977, 273, 0 }; + static ulong[] dim1526JoeKuoD5Init = { 1, 1, 1, 7, 7, 45, 113, 203, 459, 747, 1577, 2247, 5005, 2375, 0 }; + static ulong[] dim1527JoeKuoD5Init = { 1, 1, 7, 9, 9, 5, 63, 83, 193, 363, 257, 4075, 7497, 4579, 0 }; + static ulong[] dim1528JoeKuoD5Init = { 1, 1, 7, 15, 1, 55, 107, 161, 471, 245, 1303, 1821, 3395, 8957, 0 }; + static ulong[] dim1529JoeKuoD5Init = { 1, 3, 3, 15, 5, 17, 83, 215, 467, 489, 827, 1951, 3753, 13333, 0 }; + static ulong[] dim1530JoeKuoD5Init = { 1, 1, 5, 11, 27, 31, 89, 55, 445, 489, 1171, 107, 1479, 1389, 0 }; + static ulong[] dim1531JoeKuoD5Init = { 1, 1, 5, 15, 21, 23, 51, 21, 129, 349, 195, 2177, 529, 5479, 0 }; + static ulong[] dim1532JoeKuoD5Init = { 1, 1, 3, 5, 15, 31, 99, 169, 299, 21, 1379, 3845, 4991, 8755, 0 }; + static ulong[] dim1533JoeKuoD5Init = { 1, 1, 3, 3, 23, 29, 47, 219, 289, 559, 393, 793, 3217, 12103, 0 }; + static ulong[] dim1534JoeKuoD5Init = { 1, 1, 7, 15, 5, 13, 107, 119, 159, 421, 243, 3231, 5331, 14511, 0 }; + static ulong[] dim1535JoeKuoD5Init = { 1, 1, 3, 13, 13, 9, 1, 99, 7, 743, 1125, 2969, 1205, 2963, 0 }; + static ulong[] dim1536JoeKuoD5Init = { 1, 3, 7, 15, 5, 1, 25, 101, 397, 75, 141, 3503, 3003, 11363, 0 }; + static ulong[] dim1537JoeKuoD5Init = { 1, 1, 7, 1, 21, 25, 55, 7, 189, 599, 1071, 343, 2877, 5131, 0 }; + static ulong[] dim1538JoeKuoD5Init = { 1, 1, 5, 7, 13, 25, 113, 175, 31, 265, 1901, 1779, 1787, 14551, 0 }; + static ulong[] dim1539JoeKuoD5Init = { 1, 1, 5, 13, 31, 53, 69, 49, 281, 57, 1865, 3211, 5545, 12597, 0 }; + static ulong[] dim1540JoeKuoD5Init = { 1, 3, 3, 11, 3, 51, 99, 23, 303, 455, 2021, 2903, 2521, 10211, 0 }; + static ulong[] dim1541JoeKuoD5Init = { 1, 3, 1, 3, 17, 49, 55, 147, 177, 515, 1333, 3357, 6483, 4599, 0 }; + static ulong[] dim1542JoeKuoD5Init = { 1, 3, 7, 1, 31, 3, 1, 15, 263, 1007, 1377, 1245, 313, 10227, 0 }; + static ulong[] dim1543JoeKuoD5Init = { 1, 3, 1, 3, 21, 7, 61, 201, 95, 407, 661, 2159, 3255, 5749, 0 }; + static ulong[] dim1544JoeKuoD5Init = { 1, 3, 5, 9, 13, 31, 65, 135, 117, 737, 1165, 2305, 5347, 2739, 0 }; + static ulong[] dim1545JoeKuoD5Init = { 1, 1, 7, 3, 25, 49, 63, 115, 65, 693, 1211, 763, 6949, 11655, 0 }; + static ulong[] dim1546JoeKuoD5Init = { 1, 3, 1, 5, 13, 37, 15, 61, 175, 377, 765, 269, 1363, 8199, 0 }; + static ulong[] dim1547JoeKuoD5Init = { 1, 1, 7, 7, 27, 27, 113, 131, 207, 921, 1051, 2205, 1197, 16233, 0 }; + static ulong[] dim1548JoeKuoD5Init = { 1, 3, 5, 7, 5, 19, 115, 95, 93, 87, 1379, 3295, 5211, 9113, 0 }; + static ulong[] dim1549JoeKuoD5Init = { 1, 1, 3, 11, 21, 19, 9, 39, 101, 5, 1903, 1067, 2845, 2025, 0 }; + static ulong[] dim1550JoeKuoD5Init = { 1, 3, 5, 9, 31, 5, 39, 23, 505, 563, 1445, 1177, 1485, 13551, 0 }; + static ulong[] dim1551JoeKuoD5Init = { 1, 1, 7, 3, 31, 57, 107, 241, 361, 353, 699, 171, 5211, 2235, 0 }; + static ulong[] dim1552JoeKuoD5Init = { 1, 1, 5, 5, 15, 7, 115, 119, 157, 293, 827, 3249, 3463, 11873, 0 }; + static ulong[] dim1553JoeKuoD5Init = { 1, 1, 7, 3, 11, 15, 17, 195, 257, 31, 1207, 549, 7807, 14135, 0 }; + static ulong[] dim1554JoeKuoD5Init = { 1, 3, 7, 7, 25, 59, 37, 205, 507, 855, 303, 683, 4277, 9387, 0 }; + static ulong[] dim1555JoeKuoD5Init = { 1, 3, 5, 1, 25, 1, 121, 29, 485, 707, 319, 3717, 2741, 5241, 0 }; + static ulong[] dim1556JoeKuoD5Init = { 1, 3, 3, 3, 15, 55, 107, 227, 129, 1011, 319, 713, 5263, 7865, 0 }; + static ulong[] dim1557JoeKuoD5Init = { 1, 1, 3, 5, 17, 11, 7, 107, 21, 349, 1101, 3279, 5541, 12485, 0 }; + static ulong[] dim1558JoeKuoD5Init = { 1, 3, 3, 13, 25, 9, 45, 149, 187, 229, 671, 1219, 5171, 2073, 0 }; + static ulong[] dim1559JoeKuoD5Init = { 1, 3, 7, 11, 17, 49, 23, 7, 219, 639, 1497, 3103, 3047, 7723, 0 }; + static ulong[] dim1560JoeKuoD5Init = { 1, 1, 1, 5, 13, 5, 3, 249, 429, 289, 625, 325, 1257, 16251, 0 }; + static ulong[] dim1561JoeKuoD5Init = { 1, 3, 5, 1, 17, 21, 31, 11, 189, 73, 583, 2843, 1873, 1215, 0 }; + static ulong[] dim1562JoeKuoD5Init = { 1, 3, 1, 9, 25, 61, 123, 251, 485, 543, 1851, 2827, 397, 7313, 0 }; + static ulong[] dim1563JoeKuoD5Init = { 1, 1, 1, 9, 29, 59, 103, 159, 295, 227, 1127, 1905, 4121, 3233, 0 }; + static ulong[] dim1564JoeKuoD5Init = { 1, 1, 5, 15, 17, 55, 7, 1, 381, 33, 39, 485, 3967, 4401, 0 }; + static ulong[] dim1565JoeKuoD5Init = { 1, 1, 1, 3, 5, 29, 7, 95, 191, 23, 1205, 2427, 5439, 12585, 0 }; + static ulong[] dim1566JoeKuoD5Init = { 1, 3, 3, 9, 27, 9, 73, 195, 225, 597, 683, 3335, 6341, 10527, 0 }; + static ulong[] dim1567JoeKuoD5Init = { 1, 1, 3, 5, 13, 15, 83, 41, 241, 833, 1253, 3389, 2927, 2629, 0 }; + static ulong[] dim1568JoeKuoD5Init = { 1, 1, 3, 11, 25, 55, 23, 249, 151, 123, 667, 3835, 2215, 6189, 0 }; + static ulong[] dim1569JoeKuoD5Init = { 1, 1, 3, 13, 31, 43, 91, 181, 509, 453, 171, 2883, 1247, 5105, 0 }; + static ulong[] dim1570JoeKuoD5Init = { 1, 1, 7, 15, 3, 17, 59, 127, 173, 343, 901, 3419, 4755, 12367, 0 }; + static ulong[] dim1571JoeKuoD5Init = { 1, 3, 3, 9, 15, 49, 119, 1, 183, 1021, 561, 2405, 4093, 963, 0 }; + static ulong[] dim1572JoeKuoD5Init = { 1, 3, 5, 15, 21, 61, 63, 119, 11, 695, 1591, 2175, 5143, 10491, 0 }; + static ulong[] dim1573JoeKuoD5Init = { 1, 1, 7, 15, 27, 23, 91, 131, 23, 891, 1033, 1341, 1747, 12085, 0 }; + static ulong[] dim1574JoeKuoD5Init = { 1, 3, 1, 9, 11, 1, 35, 189, 131, 617, 417, 3347, 3995, 11723, 0 }; + static ulong[] dim1575JoeKuoD5Init = { 1, 3, 5, 3, 31, 35, 113, 83, 27, 399, 1615, 47, 1455, 4163, 0 }; + static ulong[] dim1576JoeKuoD5Init = { 1, 3, 3, 5, 29, 61, 103, 105, 495, 495, 1751, 2035, 7827, 11193, 0 }; + static ulong[] dim1577JoeKuoD5Init = { 1, 1, 1, 11, 29, 35, 125, 193, 59, 15, 1319, 1169, 3789, 2003, 0 }; + static ulong[] dim1578JoeKuoD5Init = { 1, 3, 3, 9, 27, 9, 33, 197, 65, 191, 783, 3685, 7505, 13407, 0 }; + static ulong[] dim1579JoeKuoD5Init = { 1, 1, 1, 1, 1, 35, 97, 55, 259, 477, 1835, 3083, 7879, 4701, 0 }; + static ulong[] dim1580JoeKuoD5Init = { 1, 1, 5, 11, 5, 31, 5, 125, 393, 317, 1577, 3741, 3823, 12447, 0 }; + static ulong[] dim1581JoeKuoD5Init = { 1, 3, 1, 13, 9, 59, 81, 85, 233, 465, 239, 1525, 3095, 5793, 0 }; + static ulong[] dim1582JoeKuoD5Init = { 1, 1, 1, 1, 9, 49, 49, 239, 81, 475, 799, 2999, 2985, 11587, 0 }; + static ulong[] dim1583JoeKuoD5Init = { 1, 1, 7, 5, 27, 55, 43, 149, 191, 325, 2035, 1645, 2153, 13237, 0 }; + static ulong[] dim1584JoeKuoD5Init = { 1, 1, 1, 15, 27, 59, 5, 49, 277, 75, 1759, 2753, 95, 2959, 0 }; + static ulong[] dim1585JoeKuoD5Init = { 1, 1, 7, 1, 21, 57, 119, 35, 457, 137, 1877, 2613, 4209, 9669, 0 }; + static ulong[] dim1586JoeKuoD5Init = { 1, 3, 3, 1, 25, 21, 51, 65, 155, 37, 783, 3427, 2763, 14361, 0 }; + static ulong[] dim1587JoeKuoD5Init = { 1, 1, 5, 7, 23, 11, 53, 181, 267, 285, 1927, 3591, 3735, 11471, 0 }; + static ulong[] dim1588JoeKuoD5Init = { 1, 3, 7, 1, 5, 25, 51, 31, 201, 851, 871, 3665, 193, 10929, 0 }; + static ulong[] dim1589JoeKuoD5Init = { 1, 3, 1, 5, 1, 25, 35, 133, 459, 45, 525, 3171, 1123, 5679, 0 }; + static ulong[] dim1590JoeKuoD5Init = { 1, 3, 1, 5, 29, 47, 123, 75, 101, 89, 1949, 1801, 3859, 6557, 0 }; + static ulong[] dim1591JoeKuoD5Init = { 1, 3, 3, 3, 25, 1, 93, 205, 447, 865, 1309, 3009, 945, 6961, 0 }; + static ulong[] dim1592JoeKuoD5Init = { 1, 3, 3, 11, 21, 47, 91, 9, 23, 607, 1905, 2291, 5315, 6673, 0 }; + static ulong[] dim1593JoeKuoD5Init = { 1, 3, 1, 13, 3, 33, 83, 27, 491, 467, 1819, 3295, 1589, 4771, 0 }; + static ulong[] dim1594JoeKuoD5Init = { 1, 1, 7, 15, 17, 57, 73, 49, 69, 821, 1773, 459, 7945, 14471, 0 }; + static ulong[] dim1595JoeKuoD5Init = { 1, 3, 1, 1, 19, 29, 9, 181, 311, 353, 2045, 2873, 7417, 15243, 0 }; + static ulong[] dim1596JoeKuoD5Init = { 1, 1, 1, 7, 29, 45, 43, 17, 237, 915, 1069, 1429, 5629, 4501, 0 }; + static ulong[] dim1597JoeKuoD5Init = { 1, 3, 5, 9, 9, 53, 57, 55, 275, 233, 1697, 2857, 919, 4507, 0 }; + static ulong[] dim1598JoeKuoD5Init = { 1, 1, 3, 13, 17, 45, 81, 101, 209, 769, 783, 1949, 5933, 137, 0 }; + static ulong[] dim1599JoeKuoD5Init = { 1, 1, 7, 7, 1, 33, 17, 87, 35, 927, 1595, 2443, 285, 12821, 0 }; + static ulong[] dim1600JoeKuoD5Init = { 1, 3, 1, 9, 3, 33, 113, 243, 51, 203, 1683, 389, 2789, 9255, 0 }; + static ulong[] dim1601JoeKuoD5Init = { 1, 3, 1, 3, 9, 1, 7, 227, 27, 773, 621, 3743, 6591, 407, 0 }; + static ulong[] dim1602JoeKuoD5Init = { 1, 3, 5, 5, 29, 51, 113, 99, 305, 267, 907, 3861, 5335, 10851, 0 }; + static ulong[] dim1603JoeKuoD5Init = { 1, 3, 1, 9, 27, 63, 65, 249, 87, 105, 2023, 1383, 4267, 8995, 0 }; + static ulong[] dim1604JoeKuoD5Init = { 1, 1, 1, 13, 15, 11, 77, 9, 365, 711, 1367, 2101, 5833, 9799, 0 }; + static ulong[] dim1605JoeKuoD5Init = { 1, 3, 7, 3, 7, 29, 13, 157, 259, 455, 389, 3177, 4243, 7615, 0 }; + static ulong[] dim1606JoeKuoD5Init = { 1, 1, 5, 3, 25, 27, 31, 91, 195, 109, 1767, 987, 2715, 7613, 0 }; + static ulong[] dim1607JoeKuoD5Init = { 1, 3, 5, 7, 23, 51, 89, 127, 485, 361, 1555, 441, 4963, 3371, 0 }; + static ulong[] dim1608JoeKuoD5Init = { 1, 3, 5, 7, 27, 31, 25, 249, 35, 115, 1021, 1051, 3449, 3395, 0 }; + static ulong[] dim1609JoeKuoD5Init = { 1, 1, 7, 3, 17, 41, 117, 173, 491, 281, 885, 471, 6665, 10041, 0 }; + static ulong[] dim1610JoeKuoD5Init = { 1, 1, 5, 3, 7, 53, 117, 117, 479, 449, 569, 4049, 2747, 12963, 0 }; + static ulong[] dim1611JoeKuoD5Init = { 1, 1, 3, 7, 11, 13, 107, 171, 7, 547, 1635, 1697, 1005, 11137, 0 }; + static ulong[] dim1612JoeKuoD5Init = { 1, 1, 1, 13, 17, 51, 109, 81, 111, 395, 349, 1467, 1399, 15545, 0 }; + static ulong[] dim1613JoeKuoD5Init = { 1, 3, 1, 9, 13, 47, 79, 119, 31, 239, 41, 2043, 2849, 16079, 0 }; + static ulong[] dim1614JoeKuoD5Init = { 1, 1, 7, 1, 17, 41, 95, 193, 511, 879, 1223, 3133, 1675, 3929, 0 }; + static ulong[] dim1615JoeKuoD5Init = { 1, 1, 7, 3, 15, 55, 21, 143, 279, 11, 717, 3021, 6207, 4499, 0 }; + static ulong[] dim1616JoeKuoD5Init = { 1, 1, 7, 3, 3, 25, 37, 91, 227, 619, 1873, 1991, 793, 10021, 0 }; + static ulong[] dim1617JoeKuoD5Init = { 1, 3, 3, 11, 17, 39, 75, 191, 117, 997, 735, 3771, 4243, 2491, 0 }; + static ulong[] dim1618JoeKuoD5Init = { 1, 1, 1, 7, 19, 9, 71, 89, 427, 791, 623, 903, 6685, 9029, 0 }; + static ulong[] dim1619JoeKuoD5Init = { 1, 1, 3, 3, 13, 49, 13, 151, 389, 677, 727, 3135, 1029, 12669, 0 }; + static ulong[] dim1620JoeKuoD5Init = { 1, 3, 5, 11, 27, 31, 119, 219, 491, 819, 755, 3529, 3071, 16095, 0 }; + static ulong[] dim1621JoeKuoD5Init = { 1, 1, 7, 9, 1, 57, 127, 171, 481, 467, 1131, 1481, 2491, 2717, 0 }; + static ulong[] dim1622JoeKuoD5Init = { 1, 1, 1, 15, 7, 25, 55, 87, 225, 363, 843, 3581, 2511, 6685, 0 }; + static ulong[] dim1623JoeKuoD5Init = { 1, 3, 3, 3, 29, 21, 91, 251, 403, 1007, 307, 2869, 6033, 14169, 0 }; + static ulong[] dim1624JoeKuoD5Init = { 1, 3, 5, 13, 31, 43, 77, 71, 101, 995, 625, 2763, 7537, 1213, 0 }; + static ulong[] dim1625JoeKuoD5Init = { 1, 3, 3, 5, 9, 45, 11, 235, 59, 561, 547, 815, 6123, 8173, 0 }; + static ulong[] dim1626JoeKuoD5Init = { 1, 3, 1, 3, 25, 19, 107, 47, 103, 467, 1889, 2021, 2861, 7617, 0 }; + static ulong[] dim1627JoeKuoD5Init = { 1, 3, 1, 9, 9, 3, 11, 231, 217, 213, 1497, 3125, 7421, 6221, 0 }; + static ulong[] dim1628JoeKuoD5Init = { 1, 1, 5, 7, 27, 57, 27, 9, 507, 191, 1297, 3307, 4687, 13299, 0 }; + static ulong[] dim1629JoeKuoD5Init = { 1, 3, 3, 1, 25, 17, 109, 57, 231, 123, 1297, 77, 785, 13731, 0 }; + static ulong[] dim1630JoeKuoD5Init = { 1, 1, 7, 3, 25, 5, 85, 177, 365, 301, 655, 1743, 2009, 7759, 0 }; + static ulong[] dim1631JoeKuoD5Init = { 1, 3, 7, 7, 19, 29, 105, 57, 469, 735, 875, 3749, 619, 15569, 0 }; + static ulong[] dim1632JoeKuoD5Init = { 1, 3, 7, 1, 19, 21, 105, 19, 83, 117, 1599, 655, 63, 12143, 0 }; + static ulong[] dim1633JoeKuoD5Init = { 1, 3, 3, 7, 9, 35, 123, 195, 109, 321, 1713, 793, 8067, 6903, 0 }; + static ulong[] dim1634JoeKuoD5Init = { 1, 1, 7, 9, 1, 41, 43, 41, 51, 711, 1713, 3063, 6427, 3577, 0 }; + static ulong[] dim1635JoeKuoD5Init = { 1, 1, 5, 11, 17, 3, 95, 159, 23, 605, 1431, 1289, 2225, 1689, 0 }; + static ulong[] dim1636JoeKuoD5Init = { 1, 1, 7, 15, 19, 3, 83, 61, 133, 707, 453, 2487, 551, 13605, 0 }; + static ulong[] dim1637JoeKuoD5Init = { 1, 1, 7, 5, 31, 37, 51, 157, 51, 423, 2021, 1837, 1873, 2919, 0 }; + static ulong[] dim1638JoeKuoD5Init = { 1, 3, 1, 13, 3, 17, 19, 19, 181, 961, 669, 47, 7513, 7551, 0 }; + static ulong[] dim1639JoeKuoD5Init = { 1, 3, 1, 1, 9, 7, 61, 219, 347, 21, 467, 955, 3255, 275, 0 }; + static ulong[] dim1640JoeKuoD5Init = { 1, 1, 3, 1, 31, 57, 51, 9, 49, 491, 119, 1155, 3641, 16095, 0 }; + static ulong[] dim1641JoeKuoD5Init = { 1, 3, 1, 1, 15, 37, 93, 27, 205, 889, 1463, 1567, 453, 13757, 0 }; + static ulong[] dim1642JoeKuoD5Init = { 1, 3, 3, 15, 27, 51, 43, 189, 357, 591, 1783, 549, 761, 8683, 0 }; + static ulong[] dim1643JoeKuoD5Init = { 1, 3, 1, 15, 13, 27, 25, 67, 145, 471, 1589, 2395, 6625, 3837, 0 }; + static ulong[] dim1644JoeKuoD5Init = { 1, 3, 3, 15, 25, 61, 111, 125, 475, 489, 15, 3835, 5077, 14487, 0 }; + static ulong[] dim1645JoeKuoD5Init = { 1, 1, 1, 9, 15, 55, 35, 169, 267, 135, 383, 733, 6913, 14153, 0 }; + static ulong[] dim1646JoeKuoD5Init = { 1, 3, 3, 1, 19, 55, 89, 61, 175, 467, 1243, 1431, 1743, 8641, 0 }; + static ulong[] dim1647JoeKuoD5Init = { 1, 1, 3, 7, 19, 41, 13, 45, 503, 285, 1727, 587, 5073, 13053, 0 }; + static ulong[] dim1648JoeKuoD5Init = { 1, 3, 7, 3, 11, 39, 93, 167, 385, 165, 881, 1037, 1471, 14527, 0 }; + static ulong[] dim1649JoeKuoD5Init = { 1, 3, 7, 15, 9, 7, 49, 163, 219, 955, 1083, 2723, 3749, 15415, 0 }; + static ulong[] dim1650JoeKuoD5Init = { 1, 3, 1, 3, 7, 43, 67, 87, 375, 405, 1663, 1263, 1895, 2229, 0 }; + static ulong[] dim1651JoeKuoD5Init = { 1, 3, 5, 1, 27, 47, 77, 147, 417, 843, 1829, 3451, 2973, 7313, 0 }; + static ulong[] dim1652JoeKuoD5Init = { 1, 1, 3, 1, 3, 25, 69, 255, 413, 43, 837, 957, 261, 8663, 0 }; + static ulong[] dim1653JoeKuoD5Init = { 1, 3, 3, 7, 29, 35, 9, 57, 421, 751, 593, 3745, 3203, 14179, 0 }; + static ulong[] dim1654JoeKuoD5Init = { 1, 3, 5, 3, 13, 25, 109, 169, 331, 537, 69, 2089, 7263, 15133, 0 }; + static ulong[] dim1655JoeKuoD5Init = { 1, 3, 5, 5, 21, 21, 21, 145, 223, 167, 1297, 3257, 7465, 1557, 0 }; + static ulong[] dim1656JoeKuoD5Init = { 1, 1, 5, 3, 11, 7, 31, 205, 97, 737, 79, 4083, 5601, 8411, 0 }; + static ulong[] dim1657JoeKuoD5Init = { 1, 1, 3, 3, 7, 39, 117, 203, 225, 801, 741, 1861, 8091, 3169, 0 }; + static ulong[] dim1658JoeKuoD5Init = { 1, 3, 3, 3, 15, 49, 109, 171, 109, 845, 1757, 2687, 5643, 3967, 0 }; + static ulong[] dim1659JoeKuoD5Init = { 1, 3, 3, 13, 7, 41, 93, 165, 127, 629, 959, 1483, 3837, 2093, 0 }; + static ulong[] dim1660JoeKuoD5Init = { 1, 1, 1, 5, 9, 39, 115, 153, 395, 777, 1601, 3443, 3581, 1419, 0 }; + static ulong[] dim1661JoeKuoD5Init = { 1, 3, 3, 3, 23, 61, 87, 179, 463, 55, 1727, 99, 7527, 15281, 0 }; + static ulong[] dim1662JoeKuoD5Init = { 1, 3, 5, 9, 9, 49, 27, 103, 221, 277, 1093, 3547, 8009, 8711, 0 }; + static ulong[] dim1663JoeKuoD5Init = { 1, 3, 1, 7, 15, 59, 79, 59, 451, 763, 1687, 389, 1665, 12149, 0 }; + static ulong[] dim1664JoeKuoD5Init = { 1, 3, 7, 9, 25, 25, 37, 53, 173, 1003, 1175, 3881, 4355, 6247, 0 }; + static ulong[] dim1665JoeKuoD5Init = { 1, 3, 5, 3, 15, 31, 123, 133, 79, 581, 405, 2869, 2759, 2295, 0 }; + static ulong[] dim1666JoeKuoD5Init = { 1, 3, 7, 13, 19, 3, 35, 135, 287, 433, 205, 2119, 6293, 2931, 0 }; + static ulong[] dim1667JoeKuoD5Init = { 1, 1, 5, 13, 21, 29, 69, 109, 401, 753, 1371, 3777, 5473, 8357, 0 }; + static ulong[] dim1668JoeKuoD5Init = { 1, 1, 3, 7, 11, 27, 101, 153, 483, 639, 687, 2325, 329, 12427, 0 }; + static ulong[] dim1669JoeKuoD5Init = { 1, 1, 3, 13, 31, 41, 93, 83, 121, 645, 479, 1417, 1967, 2807, 0 }; + static ulong[] dim1670JoeKuoD5Init = { 1, 1, 7, 5, 3, 29, 41, 115, 41, 81, 5, 1063, 943, 10151, 0 }; + static ulong[] dim1671JoeKuoD5Init = { 1, 1, 1, 13, 5, 33, 79, 245, 271, 373, 1339, 1471, 4695, 12791, 0 }; + static ulong[] dim1672JoeKuoD5Init = { 1, 1, 3, 3, 5, 5, 19, 101, 109, 429, 1587, 3453, 4549, 8173, 0 }; + static ulong[] dim1673JoeKuoD5Init = { 1, 1, 7, 7, 5, 33, 5, 15, 183, 241, 871, 1263, 85, 13525, 0 }; + static ulong[] dim1674JoeKuoD5Init = { 1, 3, 5, 1, 15, 5, 115, 165, 451, 789, 515, 3359, 1231, 3129, 0 }; + static ulong[] dim1675JoeKuoD5Init = { 1, 3, 7, 3, 5, 45, 109, 233, 369, 819, 987, 3157, 5961, 5705, 0 }; + static ulong[] dim1676JoeKuoD5Init = { 1, 3, 3, 11, 7, 63, 43, 249, 95, 853, 917, 1749, 4275, 10109, 0 }; + static ulong[] dim1677JoeKuoD5Init = { 1, 1, 1, 9, 21, 5, 53, 249, 3, 11, 1171, 3289, 6659, 6555, 0 }; + static ulong[] dim1678JoeKuoD5Init = { 1, 3, 5, 11, 9, 19, 35, 253, 13, 229, 149, 3153, 3833, 11635, 0 }; + static ulong[] dim1679JoeKuoD5Init = { 1, 1, 1, 11, 1, 19, 127, 119, 405, 19, 589, 2613, 399, 3869, 0 }; + static ulong[] dim1680JoeKuoD5Init = { 1, 1, 5, 1, 3, 11, 35, 147, 11, 765, 237, 2451, 5041, 4919, 0 }; + static ulong[] dim1681JoeKuoD5Init = { 1, 1, 1, 11, 15, 7, 91, 7, 5, 223, 1505, 3513, 185, 2767, 0 }; + static ulong[] dim1682JoeKuoD5Init = { 1, 1, 7, 7, 27, 17, 81, 181, 11, 803, 319, 3891, 4505, 6035, 0 }; + static ulong[] dim1683JoeKuoD5Init = { 1, 3, 5, 15, 29, 13, 47, 137, 301, 975, 77, 3351, 6307, 2613, 0 }; + static ulong[] dim1684JoeKuoD5Init = { 1, 3, 7, 5, 15, 41, 99, 171, 465, 145, 1859, 2949, 7915, 7755, 0 }; + static ulong[] dim1685JoeKuoD5Init = { 1, 1, 5, 5, 3, 25, 123, 251, 423, 921, 987, 793, 2199, 1255, 0 }; + static ulong[] dim1686JoeKuoD5Init = { 1, 3, 7, 3, 1, 63, 75, 101, 219, 1013, 1761, 2171, 2763, 11185, 0 }; + static ulong[] dim1687JoeKuoD5Init = { 1, 3, 5, 13, 13, 15, 33, 147, 5, 915, 1903, 2607, 3847, 167, 0 }; + static ulong[] dim1688JoeKuoD5Init = { 1, 1, 3, 1, 23, 27, 71, 17, 381, 269, 603, 2303, 1399, 13795, 0 }; + static ulong[] dim1689JoeKuoD5Init = { 1, 3, 7, 5, 29, 5, 51, 151, 271, 369, 595, 531, 7155, 15871, 0 }; + static ulong[] dim1690JoeKuoD5Init = { 1, 1, 7, 13, 9, 49, 49, 119, 191, 105, 1203, 3431, 7063, 10831, 0 }; + static ulong[] dim1691JoeKuoD5Init = { 1, 1, 5, 15, 31, 49, 37, 147, 155, 865, 339, 257, 4065, 7249, 0 }; + static ulong[] dim1692JoeKuoD5Init = { 1, 1, 3, 11, 3, 23, 127, 19, 363, 733, 1059, 3693, 4623, 2853, 0 }; + static ulong[] dim1693JoeKuoD5Init = { 1, 1, 5, 3, 3, 55, 13, 177, 453, 447, 183, 3247, 5923, 15485, 0 }; + static ulong[] dim1694JoeKuoD5Init = { 1, 1, 1, 7, 3, 57, 93, 13, 347, 225, 535, 3187, 6047, 11315, 0 }; + static ulong[] dim1695JoeKuoD5Init = { 1, 3, 5, 9, 17, 5, 121, 35, 35, 393, 1941, 1901, 7099, 2639, 0 }; + static ulong[] dim1696JoeKuoD5Init = { 1, 1, 5, 13, 13, 43, 61, 143, 291, 667, 103, 3679, 7899, 3603, 0 }; + static ulong[] dim1697JoeKuoD5Init = { 1, 3, 1, 15, 31, 57, 41, 101, 455, 541, 1001, 1879, 1879, 7411, 0 }; + static ulong[] dim1698JoeKuoD5Init = { 1, 3, 3, 7, 13, 29, 113, 151, 305, 593, 147, 737, 6643, 14463, 0 }; + static ulong[] dim1699JoeKuoD5Init = { 1, 3, 7, 3, 17, 55, 3, 179, 277, 873, 1915, 2541, 4245, 4357, 0 }; + static ulong[] dim1700JoeKuoD5Init = { 1, 1, 5, 11, 21, 43, 97, 251, 15, 443, 957, 923, 7497, 9377, 0 }; + static ulong[] dim1701JoeKuoD5Init = { 1, 3, 7, 7, 23, 19, 27, 3, 35, 407, 451, 3653, 813, 8833, 0 }; + static ulong[] dim1702JoeKuoD5Init = { 1, 1, 1, 5, 15, 25, 5, 165, 231, 221, 1325, 641, 4545, 7667, 0 }; + static ulong[] dim1703JoeKuoD5Init = { 1, 3, 7, 1, 13, 17, 25, 225, 237, 289, 187, 2881, 4723, 15579, 0 }; + static ulong[] dim1704JoeKuoD5Init = { 1, 3, 1, 3, 15, 43, 53, 241, 163, 853, 491, 2497, 761, 1707, 0 }; + static ulong[] dim1705JoeKuoD5Init = { 1, 1, 1, 3, 13, 19, 83, 97, 7, 639, 1985, 3553, 3971, 10661, 0 }; + static ulong[] dim1706JoeKuoD5Init = { 1, 3, 1, 1, 15, 37, 21, 139, 33, 643, 63, 2213, 1807, 14483, 0 }; + static ulong[] dim1707JoeKuoD5Init = { 1, 1, 7, 11, 3, 55, 67, 45, 313, 539, 1057, 455, 6473, 1499, 0 }; + static ulong[] dim1708JoeKuoD5Init = { 1, 3, 1, 9, 1, 29, 91, 133, 461, 301, 539, 2001, 8189, 2009, 0 }; + static ulong[] dim1709JoeKuoD5Init = { 1, 1, 5, 9, 17, 5, 77, 221, 423, 505, 419, 1987, 8171, 12985, 0 }; + static ulong[] dim1710JoeKuoD5Init = { 1, 1, 5, 13, 21, 11, 69, 53, 43, 819, 1513, 1767, 2981, 4333, 0 }; + static ulong[] dim1711JoeKuoD5Init = { 1, 3, 3, 9, 9, 29, 83, 183, 9, 815, 1051, 819, 2089, 13917, 0 }; + static ulong[] dim1712JoeKuoD5Init = { 1, 3, 7, 1, 21, 41, 87, 133, 149, 847, 205, 1511, 2441, 13537, 0 }; + static ulong[] dim1713JoeKuoD5Init = { 1, 1, 5, 3, 23, 1, 121, 89, 349, 355, 1919, 2045, 1723, 11859, 0 }; + static ulong[] dim1714JoeKuoD5Init = { 1, 3, 5, 1, 21, 47, 111, 65, 367, 505, 805, 2823, 5807, 6221, 0 }; + static ulong[] dim1715JoeKuoD5Init = { 1, 3, 7, 7, 7, 39, 35, 35, 497, 411, 387, 203, 1513, 15385, 0 }; + static ulong[] dim1716JoeKuoD5Init = { 1, 3, 1, 7, 3, 7, 23, 195, 353, 241, 327, 1041, 4667, 4333, 0 }; + static ulong[] dim1717JoeKuoD5Init = { 1, 1, 1, 9, 31, 51, 45, 243, 485, 785, 419, 1107, 7691, 2303, 0 }; + static ulong[] dim1718JoeKuoD5Init = { 1, 1, 1, 7, 31, 1, 121, 79, 263, 153, 695, 3617, 7435, 11587, 0 }; + static ulong[] dim1719JoeKuoD5Init = { 1, 3, 7, 7, 27, 33, 43, 223, 153, 755, 1151, 3343, 2795, 7781, 0 }; + static ulong[] dim1720JoeKuoD5Init = { 1, 1, 1, 15, 5, 41, 39, 181, 485, 129, 529, 2335, 6843, 7733, 0 }; + static ulong[] dim1721JoeKuoD5Init = { 1, 1, 5, 11, 31, 55, 117, 157, 227, 125, 557, 315, 3031, 8671, 0 }; + static ulong[] dim1722JoeKuoD5Init = { 1, 1, 3, 7, 15, 5, 117, 149, 239, 85, 341, 995, 1709, 9303, 0 }; + static ulong[] dim1723JoeKuoD5Init = { 1, 3, 1, 9, 3, 23, 17, 87, 327, 929, 519, 3441, 7599, 15021, 0 }; + static ulong[] dim1724JoeKuoD5Init = { 1, 3, 3, 9, 23, 31, 81, 37, 493, 451, 603, 1943, 1055, 3959, 0 }; + static ulong[] dim1725JoeKuoD5Init = { 1, 1, 3, 13, 7, 61, 61, 127, 303, 675, 955, 249, 7653, 8441, 0 }; + static ulong[] dim1726JoeKuoD5Init = { 1, 3, 1, 5, 23, 1, 95, 109, 155, 853, 1567, 4007, 4205, 7839, 0 }; + static ulong[] dim1727JoeKuoD5Init = { 1, 3, 7, 1, 11, 27, 57, 167, 285, 421, 143, 3937, 4865, 10581, 0 }; + static ulong[] dim1728JoeKuoD5Init = { 1, 1, 1, 11, 15, 19, 49, 39, 383, 549, 1563, 2499, 7889, 239, 0 }; + static ulong[] dim1729JoeKuoD5Init = { 1, 1, 1, 7, 13, 47, 61, 77, 443, 961, 1979, 931, 433, 6457, 0 }; + static ulong[] dim1730JoeKuoD5Init = { 1, 1, 1, 5, 5, 1, 49, 137, 417, 579, 1079, 1511, 1611, 16083, 0 }; + static ulong[] dim1731JoeKuoD5Init = { 1, 3, 3, 11, 7, 51, 43, 29, 199, 525, 801, 3887, 619, 3389, 0 }; + static ulong[] dim1732JoeKuoD5Init = { 1, 1, 1, 11, 25, 23, 65, 65, 201, 875, 787, 3747, 7275, 6191, 0 }; + static ulong[] dim1733JoeKuoD5Init = { 1, 1, 3, 1, 19, 21, 117, 169, 39, 901, 3, 3579, 6119, 2057, 0 }; + static ulong[] dim1734JoeKuoD5Init = { 1, 3, 1, 9, 13, 59, 33, 43, 237, 767, 819, 3555, 1337, 13469, 0 }; + static ulong[] dim1735JoeKuoD5Init = { 1, 3, 7, 1, 25, 51, 59, 11, 427, 353, 1601, 3905, 6975, 1065, 0 }; + static ulong[] dim1736JoeKuoD5Init = { 1, 1, 7, 5, 19, 35, 43, 137, 227, 17, 803, 919, 6651, 3339, 0 }; + static ulong[] dim1737JoeKuoD5Init = { 1, 3, 1, 15, 21, 21, 41, 197, 373, 849, 1753, 515, 4093, 15407, 0 }; + static ulong[] dim1738JoeKuoD5Init = { 1, 1, 3, 3, 11, 5, 49, 223, 351, 349, 987, 1785, 269, 3037, 0 }; + static ulong[] dim1739JoeKuoD5Init = { 1, 3, 3, 9, 3, 47, 103, 225, 21, 285, 1529, 399, 4951, 10767, 0 }; + static ulong[] dim1740JoeKuoD5Init = { 1, 1, 5, 11, 25, 27, 97, 87, 487, 613, 607, 1905, 6019, 423, 0 }; + static ulong[] dim1741JoeKuoD5Init = { 1, 1, 7, 3, 23, 53, 23, 147, 69, 781, 373, 1261, 8011, 9611, 0 }; + static ulong[] dim1742JoeKuoD5Init = { 1, 3, 7, 11, 21, 43, 67, 87, 173, 57, 1147, 1841, 6031, 11261, 0 }; + static ulong[] dim1743JoeKuoD5Init = { 1, 1, 5, 7, 29, 23, 15, 113, 485, 699, 259, 1175, 7489, 5119, 0 }; + static ulong[] dim1744JoeKuoD5Init = { 1, 3, 7, 13, 15, 13, 85, 219, 107, 811, 1599, 2267, 8047, 12427, 0 }; + static ulong[] dim1745JoeKuoD5Init = { 1, 1, 3, 11, 9, 7, 127, 201, 275, 293, 1313, 3251, 3745, 15237, 0 }; + static ulong[] dim1746JoeKuoD5Init = { 1, 1, 3, 15, 1, 3, 57, 235, 509, 353, 513, 467, 1409, 4733, 0 }; + static ulong[] dim1747JoeKuoD5Init = { 1, 3, 5, 7, 13, 43, 9, 41, 39, 919, 1545, 43, 8029, 1413, 0 }; + static ulong[] dim1748JoeKuoD5Init = { 1, 1, 7, 3, 21, 7, 33, 41, 161, 53, 1635, 787, 6197, 4841, 0 }; + static ulong[] dim1749JoeKuoD5Init = { 1, 3, 3, 9, 29, 41, 19, 161, 205, 1003, 1899, 7, 4329, 11151, 0 }; + static ulong[] dim1750JoeKuoD5Init = { 1, 3, 3, 7, 23, 23, 27, 145, 375, 433, 1729, 3787, 4985, 2167, 0 }; + static ulong[] dim1751JoeKuoD5Init = { 1, 1, 3, 5, 15, 21, 77, 13, 33, 227, 837, 1373, 2745, 2339, 0 }; + static ulong[] dim1752JoeKuoD5Init = { 1, 3, 1, 13, 17, 57, 31, 83, 135, 535, 693, 803, 1459, 319, 0 }; + static ulong[] dim1753JoeKuoD5Init = { 1, 1, 1, 15, 11, 39, 105, 111, 247, 901, 395, 573, 3359, 8955, 0 }; + static ulong[] dim1754JoeKuoD5Init = { 1, 1, 3, 5, 23, 27, 99, 83, 277, 229, 429, 1451, 4755, 13951, 0 }; + static ulong[] dim1755JoeKuoD5Init = { 1, 3, 5, 15, 27, 17, 37, 81, 83, 991, 1509, 1931, 7389, 6053, 0 }; + static ulong[] dim1756JoeKuoD5Init = { 1, 1, 3, 13, 27, 55, 117, 93, 55, 65, 155, 3933, 3159, 9507, 0 }; + static ulong[] dim1757JoeKuoD5Init = { 1, 1, 7, 7, 15, 47, 109, 79, 379, 175, 419, 3285, 3207, 1675, 0 }; + static ulong[] dim1758JoeKuoD5Init = { 1, 1, 7, 15, 31, 19, 123, 229, 151, 549, 1329, 3835, 511, 14679, 0 }; + static ulong[] dim1759JoeKuoD5Init = { 1, 1, 5, 5, 25, 43, 89, 145, 419, 5, 1131, 2143, 7473, 14101, 0 }; + static ulong[] dim1760JoeKuoD5Init = { 1, 1, 1, 11, 21, 43, 7, 123, 15, 743, 241, 1737, 2239, 11007, 0 }; + static ulong[] dim1761JoeKuoD5Init = { 1, 1, 1, 15, 27, 3, 119, 157, 361, 471, 1673, 1873, 4555, 16337, 0 }; + static ulong[] dim1762JoeKuoD5Init = { 1, 1, 1, 7, 15, 39, 95, 189, 353, 605, 349, 2763, 5125, 7943, 0 }; + static ulong[] dim1763JoeKuoD5Init = { 1, 3, 3, 13, 13, 1, 45, 69, 191, 183, 1967, 2455, 3879, 2397, 0 }; + static ulong[] dim1764JoeKuoD5Init = { 1, 3, 7, 1, 3, 23, 109, 123, 127, 813, 1499, 39, 1991, 9767, 0 }; + static ulong[] dim1765JoeKuoD5Init = { 1, 3, 3, 1, 7, 3, 125, 93, 279, 803, 1203, 3623, 4359, 4251, 0 }; + static ulong[] dim1766JoeKuoD5Init = { 1, 3, 1, 15, 25, 57, 61, 103, 219, 983, 957, 895, 4077, 11799, 0 }; + static ulong[] dim1767JoeKuoD5Init = { 1, 3, 1, 9, 21, 11, 15, 137, 491, 643, 1737, 3459, 4367, 5727, 0 }; + static ulong[] dim1768JoeKuoD5Init = { 1, 3, 5, 9, 25, 57, 111, 129, 101, 807, 1481, 3703, 2713, 6375, 0 }; + static ulong[] dim1769JoeKuoD5Init = { 1, 3, 3, 1, 31, 59, 75, 173, 209, 273, 121, 747, 257, 9713, 0 }; + static ulong[] dim1770JoeKuoD5Init = { 1, 3, 5, 11, 5, 31, 107, 243, 189, 407, 773, 503, 6197, 9455, 0 }; + static ulong[] dim1771JoeKuoD5Init = { 1, 3, 5, 5, 29, 25, 31, 169, 393, 857, 1739, 883, 2147, 15569, 0 }; + static ulong[] dim1772JoeKuoD5Init = { 1, 1, 3, 11, 31, 47, 17, 119, 499, 595, 207, 1709, 4585, 12855, 0 }; + static ulong[] dim1773JoeKuoD5Init = { 1, 3, 5, 3, 21, 33, 55, 197, 349, 41, 453, 1913, 2301, 6461, 0 }; + static ulong[] dim1774JoeKuoD5Init = { 1, 3, 5, 13, 27, 37, 105, 217, 145, 1007, 259, 2681, 477, 15931, 0 }; + static ulong[] dim1775JoeKuoD5Init = { 1, 3, 3, 13, 3, 39, 9, 231, 395, 735, 501, 1631, 2931, 11947, 0 }; + static ulong[] dim1776JoeKuoD5Init = { 1, 3, 3, 11, 13, 61, 113, 113, 473, 591, 499, 2169, 6419, 10619, 0 }; + static ulong[] dim1777JoeKuoD5Init = { 1, 1, 1, 5, 29, 63, 43, 127, 243, 647, 1633, 1361, 3755, 11315, 0 }; + static ulong[] dim1778JoeKuoD5Init = { 1, 3, 5, 1, 13, 31, 111, 63, 69, 1005, 1955, 339, 2415, 4855, 0 }; + static ulong[] dim1779JoeKuoD5Init = { 1, 3, 5, 13, 25, 11, 21, 1, 343, 259, 1359, 597, 7029, 16229, 0 }; + static ulong[] dim1780JoeKuoD5Init = { 1, 1, 1, 7, 27, 13, 17, 43, 509, 105, 347, 443, 5939, 12173, 0 }; + static ulong[] dim1781JoeKuoD5Init = { 1, 3, 1, 13, 15, 25, 93, 199, 305, 725, 597, 1497, 313, 10677, 0 }; + static ulong[] dim1782JoeKuoD5Init = { 1, 3, 3, 15, 17, 7, 103, 95, 83, 433, 441, 2587, 3365, 14771, 0 }; + static ulong[] dim1783JoeKuoD5Init = { 1, 1, 7, 1, 17, 7, 55, 189, 451, 729, 817, 243, 4089, 6569, 0 }; + static ulong[] dim1784JoeKuoD5Init = { 1, 3, 1, 1, 5, 7, 19, 113, 191, 211, 1205, 4005, 3221, 7521, 0 }; + static ulong[] dim1785JoeKuoD5Init = { 1, 3, 1, 15, 25, 49, 77, 187, 105, 87, 955, 2381, 1243, 11335, 0 }; + static ulong[] dim1786JoeKuoD5Init = { 1, 3, 5, 1, 19, 63, 113, 3, 7, 105, 185, 1499, 6885, 9063, 0 }; + static ulong[] dim1787JoeKuoD5Init = { 1, 3, 3, 11, 31, 47, 37, 107, 31, 691, 1049, 2273, 1595, 4431, 0 }; + static ulong[] dim1788JoeKuoD5Init = { 1, 1, 1, 3, 23, 57, 51, 17, 225, 551, 965, 3497, 2549, 1153, 0 }; + static ulong[] dim1789JoeKuoD5Init = { 1, 3, 1, 5, 25, 41, 123, 143, 13, 437, 1081, 1625, 147, 6239, 0 }; + static ulong[] dim1790JoeKuoD5Init = { 1, 3, 3, 3, 31, 49, 17, 119, 315, 155, 37, 1125, 1223, 341, 0 }; + static ulong[] dim1791JoeKuoD5Init = { 1, 3, 1, 7, 9, 49, 35, 223, 449, 147, 317, 29, 4651, 15995, 0 }; + static ulong[] dim1792JoeKuoD5Init = { 1, 1, 3, 3, 9, 23, 97, 209, 343, 279, 1947, 3465, 7775, 5779, 0 }; + static ulong[] dim1793JoeKuoD5Init = { 1, 1, 7, 1, 7, 61, 111, 135, 473, 105, 1529, 2855, 3457, 7053, 0 }; + static ulong[] dim1794JoeKuoD5Init = { 1, 3, 5, 7, 29, 3, 63, 25, 115, 423, 1425, 1363, 77, 11485, 0 }; + static ulong[] dim1795JoeKuoD5Init = { 1, 3, 1, 15, 23, 59, 101, 87, 319, 785, 1639, 3427, 3165, 11273, 0 }; + static ulong[] dim1796JoeKuoD5Init = { 1, 3, 1, 13, 23, 7, 47, 221, 137, 775, 329, 1777, 3091, 4693, 0 }; + static ulong[] dim1797JoeKuoD5Init = { 1, 3, 7, 13, 1, 33, 31, 177, 481, 865, 739, 97, 5113, 16371, 0 }; + static ulong[] dim1798JoeKuoD5Init = { 1, 1, 3, 9, 31, 57, 99, 241, 465, 915, 1181, 225, 6795, 5743, 0 }; + static ulong[] dim1799JoeKuoD5Init = { 1, 1, 5, 3, 13, 25, 71, 119, 31, 169, 1745, 4085, 2945, 13357, 0 }; + static ulong[] dim1800JoeKuoD5Init = { 1, 1, 5, 5, 31, 61, 123, 71, 375, 1003, 1303, 2149, 5867, 10523, 0 }; + static ulong[] dim1801JoeKuoD5Init = { 1, 3, 3, 11, 21, 13, 25, 147, 147, 591, 259, 1707, 1777, 5869, 0 }; + static ulong[] dim1802JoeKuoD5Init = { 1, 3, 1, 13, 7, 13, 87, 227, 305, 235, 1263, 953, 4509, 11375, 0 }; + static ulong[] dim1803JoeKuoD5Init = { 1, 3, 5, 1, 11, 23, 103, 177, 9, 329, 1519, 2393, 6627, 14631, 0 }; + static ulong[] dim1804JoeKuoD5Init = { 1, 1, 7, 9, 25, 19, 75, 87, 361, 741, 1745, 3281, 6771, 3111, 0 }; + static ulong[] dim1805JoeKuoD5Init = { 1, 3, 7, 5, 23, 5, 1, 247, 43, 61, 1489, 3537, 5079, 11545, 0 }; + static ulong[] dim1806JoeKuoD5Init = { 1, 1, 5, 15, 9, 43, 49, 213, 191, 567, 1237, 681, 6715, 6471, 0 }; + static ulong[] dim1807JoeKuoD5Init = { 1, 3, 7, 1, 31, 53, 83, 53, 117, 1001, 525, 841, 2891, 4281, 0 }; + static ulong[] dim1808JoeKuoD5Init = { 1, 1, 1, 9, 21, 49, 21, 215, 209, 611, 1849, 969, 3081, 9485, 0 }; + static ulong[] dim1809JoeKuoD5Init = { 1, 3, 5, 15, 13, 25, 37, 31, 357, 611, 83, 1615, 8137, 14505, 0 }; + static ulong[] dim1810JoeKuoD5Init = { 1, 3, 3, 11, 29, 31, 9, 27, 427, 883, 555, 2559, 7039, 11345, 0 }; + static ulong[] dim1811JoeKuoD5Init = { 1, 1, 3, 11, 3, 17, 9, 251, 493, 977, 1713, 2711, 4377, 3171, 0 }; + static ulong[] dim1812JoeKuoD5Init = { 1, 1, 1, 7, 9, 1, 27, 179, 345, 425, 413, 2101, 3417, 1497, 0 }; + static ulong[] dim1813JoeKuoD5Init = { 1, 1, 3, 3, 13, 33, 121, 81, 247, 1003, 1405, 2769, 1919, 10807, 0 }; + static ulong[] dim1814JoeKuoD5Init = { 1, 1, 3, 15, 29, 51, 13, 101, 237, 165, 1483, 3961, 2389, 8379, 0 }; + static ulong[] dim1815JoeKuoD5Init = { 1, 3, 5, 11, 17, 3, 51, 141, 295, 165, 1089, 3889, 6415, 4969, 0 }; + static ulong[] dim1816JoeKuoD5Init = { 1, 1, 7, 3, 25, 47, 1, 17, 499, 409, 1417, 2975, 3935, 13363, 0 }; + static ulong[] dim1817JoeKuoD5Init = { 1, 1, 3, 13, 7, 55, 91, 121, 509, 675, 1203, 795, 1225, 15329, 0 }; + static ulong[] dim1818JoeKuoD5Init = { 1, 3, 7, 5, 3, 29, 19, 103, 11, 511, 799, 773, 515, 9931, 0 }; + static ulong[] dim1819JoeKuoD5Init = { 1, 1, 5, 3, 27, 63, 19, 83, 213, 977, 1923, 999, 7935, 2081, 0 }; + static ulong[] dim1820JoeKuoD5Init = { 1, 3, 7, 3, 19, 17, 127, 251, 417, 711, 85, 2757, 6461, 83, 0 }; + static ulong[] dim1821JoeKuoD5Init = { 1, 1, 3, 9, 11, 7, 113, 127, 287, 647, 1775, 3201, 2551, 13389, 0 }; + static ulong[] dim1822JoeKuoD5Init = { 1, 1, 7, 15, 31, 33, 81, 53, 207, 361, 665, 2073, 4249, 6699, 0 }; + static ulong[] dim1823JoeKuoD5Init = { 1, 3, 5, 11, 25, 43, 83, 159, 31, 693, 1315, 2043, 3463, 15771, 0 }; + static ulong[] dim1824JoeKuoD5Init = { 1, 1, 7, 15, 9, 1, 93, 207, 97, 293, 67, 2411, 1241, 10819, 0 }; + static ulong[] dim1825JoeKuoD5Init = { 1, 1, 7, 15, 17, 41, 113, 153, 7, 499, 131, 737, 7881, 2691, 0 }; + static ulong[] dim1826JoeKuoD5Init = { 1, 3, 1, 11, 5, 3, 125, 49, 63, 375, 811, 3295, 7997, 1063, 0 }; + static ulong[] dim1827JoeKuoD5Init = { 1, 1, 1, 5, 1, 27, 37, 101, 179, 975, 421, 2785, 8093, 11803, 0 }; + static ulong[] dim1828JoeKuoD5Init = { 1, 3, 7, 3, 27, 35, 89, 111, 481, 821, 223, 2983, 2369, 4861, 0 }; + static ulong[] dim1829JoeKuoD5Init = { 1, 1, 5, 3, 21, 59, 25, 237, 73, 451, 309, 241, 4955, 9889, 0 }; + static ulong[] dim1830JoeKuoD5Init = { 1, 3, 3, 15, 25, 37, 85, 29, 103, 893, 337, 2831, 6679, 15171, 0 }; + static ulong[] dim1831JoeKuoD5Init = { 1, 1, 7, 3, 13, 1, 101, 109, 223, 243, 1749, 3611, 4097, 14439, 0 }; + static ulong[] dim1832JoeKuoD5Init = { 1, 3, 3, 11, 31, 49, 97, 181, 269, 567, 1801, 3129, 2697, 15167, 0 }; + static ulong[] dim1833JoeKuoD5Init = { 1, 3, 1, 5, 11, 11, 105, 161, 163, 363, 187, 3671, 6793, 4197, 0 }; + static ulong[] dim1834JoeKuoD5Init = { 1, 1, 3, 1, 23, 61, 127, 9, 101, 493, 1875, 3943, 3501, 1685, 0 }; + static ulong[] dim1835JoeKuoD5Init = { 1, 1, 5, 3, 29, 13, 11, 185, 437, 151, 927, 199, 7739, 14771, 0 }; + static ulong[] dim1836JoeKuoD5Init = { 1, 3, 1, 5, 17, 17, 35, 147, 387, 401, 1385, 1993, 1551, 2421, 0 }; + static ulong[] dim1837JoeKuoD5Init = { 1, 1, 5, 7, 25, 27, 1, 43, 407, 503, 1917, 23, 3459, 7653, 0 }; + static ulong[] dim1838JoeKuoD5Init = { 1, 3, 7, 1, 29, 37, 69, 193, 359, 901, 1661, 4049, 2923, 15553, 0 }; + static ulong[] dim1839JoeKuoD5Init = { 1, 1, 3, 11, 31, 53, 45, 5, 143, 823, 483, 669, 8037, 14021, 0 }; + static ulong[] dim1840JoeKuoD5Init = { 1, 3, 3, 15, 23, 47, 105, 185, 267, 347, 85, 3121, 5811, 6229, 0 }; + static ulong[] dim1841JoeKuoD5Init = { 1, 1, 5, 5, 27, 43, 25, 143, 197, 425, 1537, 1701, 6061, 12125, 0 }; + static ulong[] dim1842JoeKuoD5Init = { 1, 3, 1, 1, 31, 57, 21, 21, 301, 573, 947, 2087, 3135, 1767, 0 }; + static ulong[] dim1843JoeKuoD5Init = { 1, 1, 5, 15, 23, 35, 35, 191, 195, 131, 1669, 3311, 4107, 9311, 0 }; + static ulong[] dim1844JoeKuoD5Init = { 1, 1, 7, 5, 23, 13, 111, 165, 283, 949, 1575, 2359, 5891, 9911, 0 }; + static ulong[] dim1845JoeKuoD5Init = { 1, 1, 5, 13, 17, 31, 31, 179, 45, 475, 975, 251, 353, 6331, 0 }; + static ulong[] dim1846JoeKuoD5Init = { 1, 3, 1, 13, 15, 9, 127, 35, 463, 711, 1783, 837, 7859, 14299, 0 }; + static ulong[] dim1847JoeKuoD5Init = { 1, 3, 5, 5, 31, 57, 79, 7, 319, 517, 677, 3923, 1363, 11355, 0 }; + static ulong[] dim1848JoeKuoD5Init = { 1, 3, 7, 3, 17, 17, 49, 171, 95, 519, 775, 2265, 7953, 617, 0 }; + static ulong[] dim1849JoeKuoD5Init = { 1, 3, 5, 9, 3, 35, 87, 185, 369, 795, 1171, 3777, 4983, 1153, 0 }; + static ulong[] dim1850JoeKuoD5Init = { 1, 1, 5, 3, 9, 3, 1, 131, 275, 921, 507, 1877, 1573, 6231, 0 }; + static ulong[] dim1851JoeKuoD5Init = { 1, 1, 5, 15, 7, 53, 77, 255, 329, 449, 1859, 3625, 7027, 9921, 0 }; + static ulong[] dim1852JoeKuoD5Init = { 1, 1, 5, 7, 1, 47, 57, 111, 303, 749, 689, 2963, 8085, 9097, 0 }; + static ulong[] dim1853JoeKuoD5Init = { 1, 3, 7, 11, 19, 47, 61, 3, 481, 371, 1737, 287, 5485, 15433, 0 }; + static ulong[] dim1854JoeKuoD5Init = { 1, 3, 1, 13, 23, 45, 33, 83, 483, 411, 257, 749, 3959, 10269, 0 }; + static ulong[] dim1855JoeKuoD5Init = { 1, 1, 7, 5, 25, 15, 11, 181, 131, 943, 125, 3367, 2429, 2151, 0 }; + static ulong[] dim1856JoeKuoD5Init = { 1, 3, 5, 15, 25, 35, 37, 163, 399, 575, 843, 1567, 4401, 14757, 0 }; + static ulong[] dim1857JoeKuoD5Init = { 1, 1, 5, 1, 5, 3, 31, 199, 479, 525, 973, 2843, 7831, 6693, 0 }; + static ulong[] dim1858JoeKuoD5Init = { 1, 1, 5, 3, 21, 7, 123, 31, 207, 741, 425, 2139, 2965, 1017, 0 }; + static ulong[] dim1859JoeKuoD5Init = { 1, 1, 1, 11, 3, 31, 61, 85, 303, 627, 1995, 3211, 5747, 14897, 0 }; + static ulong[] dim1860JoeKuoD5Init = { 1, 1, 7, 7, 9, 25, 45, 73, 427, 945, 1505, 1121, 7585, 13115, 0 }; + static ulong[] dim1861JoeKuoD5Init = { 1, 1, 5, 1, 9, 43, 75, 63, 445, 709, 645, 1105, 1375, 12303, 0 }; + static ulong[] dim1862JoeKuoD5Init = { 1, 1, 3, 5, 25, 37, 101, 209, 239, 429, 1455, 3587, 4231, 6501, 0 }; + static ulong[] dim1863JoeKuoD5Init = { 1, 3, 7, 1, 21, 23, 113, 227, 151, 97, 367, 889, 7675, 14093, 0 }; + static ulong[] dim1864JoeKuoD5Init = { 1, 1, 7, 11, 13, 31, 63, 7, 31, 973, 1935, 53, 4941, 9057, 0 }; + static ulong[] dim1865JoeKuoD5Init = { 1, 3, 1, 13, 21, 23, 79, 43, 255, 1003, 1741, 1003, 355, 3839, 0 }; + static ulong[] dim1866JoeKuoD5Init = { 1, 1, 5, 9, 31, 17, 45, 235, 271, 711, 61, 235, 513, 11321, 0 }; + static ulong[] dim1867JoeKuoD5Init = { 1, 1, 3, 9, 29, 35, 43, 115, 9, 787, 325, 625, 7905, 8191, 29233, 0 }; + static ulong[] dim1868JoeKuoD5Init = { 1, 1, 1, 13, 5, 17, 67, 161, 357, 163, 1129, 3819, 3601, 5961, 9259, 0 }; + static ulong[] dim1869JoeKuoD5Init = { 1, 3, 7, 13, 25, 17, 83, 41, 463, 879, 1881, 1107, 4337, 409, 8633, 0 }; + static ulong[] dim1870JoeKuoD5Init = { 1, 3, 1, 1, 17, 45, 127, 213, 285, 791, 479, 3153, 3001, 16207, 32669, 0 }; + static ulong[] dim1871JoeKuoD5Init = { 1, 1, 7, 11, 23, 41, 103, 209, 81, 903, 1787, 907, 161, 15739, 17367, 0 }; + static ulong[] dim1872JoeKuoD5Init = { 1, 3, 1, 11, 17, 61, 69, 251, 321, 361, 905, 1081, 5749, 2639, 21195, 0 }; + static ulong[] dim1873JoeKuoD5Init = { 1, 1, 7, 13, 27, 39, 61, 161, 139, 837, 579, 1979, 4413, 8701, 16301, 0 }; + static ulong[] dim1874JoeKuoD5Init = { 1, 3, 3, 7, 3, 49, 111, 77, 423, 491, 1489, 2615, 4997, 3695, 15109, 0 }; + static ulong[] dim1875JoeKuoD5Init = { 1, 1, 5, 7, 31, 3, 53, 113, 45, 767, 1561, 2925, 605, 3211, 8413, 0 }; + static ulong[] dim1876JoeKuoD5Init = { 1, 3, 1, 15, 31, 29, 65, 13, 19, 159, 639, 2155, 2699, 7001, 15575, 0 }; + static ulong[] dim1877JoeKuoD5Init = { 1, 3, 5, 1, 3, 33, 37, 89, 189, 661, 1685, 503, 6037, 12993, 9571, 0 }; + static ulong[] dim1878JoeKuoD5Init = { 1, 3, 5, 13, 31, 13, 41, 35, 217, 193, 1273, 443, 1385, 13661, 14873, 0 }; + static ulong[] dim1879JoeKuoD5Init = { 1, 1, 7, 15, 3, 9, 123, 251, 155, 545, 813, 317, 5127, 15305, 5571, 0 }; + static ulong[] dim1880JoeKuoD5Init = { 1, 1, 1, 15, 3, 39, 41, 39, 273, 881, 809, 1643, 687, 5525, 3473, 0 }; + static ulong[] dim1881JoeKuoD5Init = { 1, 3, 5, 11, 7, 25, 25, 27, 263, 773, 155, 1541, 7545, 873, 32713, 0 }; + static ulong[] dim1882JoeKuoD5Init = { 1, 1, 5, 9, 1, 49, 57, 17, 433, 73, 635, 1073, 7459, 15653, 47, 0 }; + static ulong[] dim1883JoeKuoD5Init = { 1, 1, 1, 13, 1, 5, 65, 105, 353, 361, 339, 3983, 2707, 10165, 20883, 0 }; + static ulong[] dim1884JoeKuoD5Init = { 1, 3, 5, 3, 23, 29, 125, 223, 463, 493, 1989, 1583, 8153, 13475, 5789, 0 }; + static ulong[] dim1885JoeKuoD5Init = { 1, 1, 7, 7, 27, 39, 61, 127, 387, 215, 1769, 2279, 7883, 1491, 29625, 0 }; + static ulong[] dim1886JoeKuoD5Init = { 1, 1, 7, 5, 5, 13, 11, 47, 409, 673, 1927, 1277, 6971, 8195, 22663, 0 }; + static ulong[] dim1887JoeKuoD5Init = { 1, 3, 3, 13, 1, 53, 123, 187, 25, 29, 1107, 1929, 6995, 5081, 8861, 0 }; + static ulong[] dim1888JoeKuoD5Init = { 1, 3, 1, 5, 25, 27, 53, 65, 239, 299, 21, 3389, 1587, 1437, 26209, 0 }; + static ulong[] dim1889JoeKuoD5Init = { 1, 1, 1, 7, 15, 35, 37, 105, 169, 843, 623, 3763, 7101, 5245, 17203, 0 }; + static ulong[] dim1890JoeKuoD5Init = { 1, 1, 3, 15, 21, 7, 29, 29, 465, 149, 189, 1115, 6471, 11275, 28769, 0 }; + static ulong[] dim1891JoeKuoD5Init = { 1, 1, 1, 9, 31, 1, 99, 101, 321, 675, 1631, 1371, 7733, 1697, 4437, 0 }; + static ulong[] dim1892JoeKuoD5Init = { 1, 1, 3, 9, 7, 27, 47, 207, 295, 787, 1539, 2233, 7849, 15843, 11149, 0 }; + static ulong[] dim1893JoeKuoD5Init = { 1, 3, 1, 3, 17, 29, 61, 143, 289, 939, 729, 297, 1513, 4387, 3347, 0 }; + static ulong[] dim1894JoeKuoD5Init = { 1, 3, 5, 13, 15, 25, 125, 13, 157, 377, 317, 827, 5137, 829, 21215, 0 }; + static ulong[] dim1895JoeKuoD5Init = { 1, 3, 5, 13, 17, 37, 79, 87, 163, 847, 1009, 2259, 6543, 8697, 4837, 0 }; + static ulong[] dim1896JoeKuoD5Init = { 1, 1, 5, 11, 29, 7, 13, 91, 279, 439, 691, 4047, 159, 9403, 27735, 0 }; + static ulong[] dim1897JoeKuoD5Init = { 1, 1, 5, 5, 23, 61, 53, 93, 343, 349, 355, 1275, 3573, 12847, 8969, 0 }; + static ulong[] dim1898JoeKuoD5Init = { 1, 1, 3, 11, 1, 49, 47, 255, 371, 511, 579, 2385, 2237, 2015, 23973, 0 }; + static ulong[] dim1899JoeKuoD5Init = { 1, 1, 7, 11, 15, 31, 13, 121, 399, 957, 731, 3743, 1573, 2293, 27755, 0 }; + static ulong[] dim1900JoeKuoD5Init = { 1, 3, 5, 5, 23, 19, 57, 211, 133, 197, 379, 1037, 625, 9405, 11547, 0 }; + static ulong[] dim1901JoeKuoD5Init = { 1, 1, 5, 15, 7, 13, 75, 93, 415, 551, 1885, 2259, 23, 14321, 21509, 0 }; + static ulong[] dim1902JoeKuoD5Init = { 1, 1, 3, 5, 29, 37, 23, 59, 199, 559, 1761, 821, 5077, 12017, 16505, 0 }; + static ulong[] dim1903JoeKuoD5Init = { 1, 1, 7, 7, 19, 29, 31, 101, 121, 605, 1679, 2317, 3359, 13557, 17567, 0 }; + static ulong[] dim1904JoeKuoD5Init = { 1, 1, 3, 15, 3, 5, 45, 201, 401, 689, 1775, 3615, 2641, 14149, 29241, 0 }; + static ulong[] dim1905JoeKuoD5Init = { 1, 3, 1, 5, 9, 13, 51, 101, 41, 347, 57, 613, 5813, 3753, 22007, 0 }; + static ulong[] dim1906JoeKuoD5Init = { 1, 1, 5, 15, 19, 59, 57, 57, 405, 647, 1943, 353, 1691, 9287, 29567, 0 }; + static ulong[] dim1907JoeKuoD5Init = { 1, 3, 1, 13, 29, 11, 51, 137, 163, 365, 153, 3791, 5367, 4649, 11255, 0 }; + static ulong[] dim1908JoeKuoD5Init = { 1, 3, 1, 1, 27, 37, 99, 211, 377, 543, 649, 2107, 3511, 10385, 1093, 0 }; + static ulong[] dim1909JoeKuoD5Init = { 1, 1, 5, 9, 29, 25, 85, 75, 55, 75, 825, 2129, 6867, 9053, 22687, 0 }; + static ulong[] dim1910JoeKuoD5Init = { 1, 3, 7, 1, 19, 57, 29, 99, 369, 107, 1187, 2919, 6163, 15209, 7911, 0 }; + static ulong[] dim1911JoeKuoD5Init = { 1, 1, 3, 11, 25, 55, 111, 197, 329, 307, 1531, 1753, 1275, 5543, 23411, 0 }; + static ulong[] dim1912JoeKuoD5Init = { 1, 1, 5, 9, 21, 59, 97, 211, 117, 331, 1919, 1763, 1755, 12517, 16579, 0 }; + static ulong[] dim1913JoeKuoD5Init = { 1, 3, 7, 11, 5, 37, 21, 229, 109, 341, 421, 2413, 785, 3251, 10245, 0 }; + static ulong[] dim1914JoeKuoD5Init = { 1, 3, 5, 11, 27, 3, 89, 15, 455, 53, 1447, 137, 681, 7811, 16817, 0 }; + static ulong[] dim1915JoeKuoD5Init = { 1, 3, 5, 13, 9, 57, 45, 101, 459, 801, 409, 911, 749, 11875, 6039, 0 }; + static ulong[] dim1916JoeKuoD5Init = { 1, 3, 1, 13, 23, 31, 49, 105, 255, 485, 1587, 1137, 2113, 16313, 19073, 0 }; + static ulong[] dim1917JoeKuoD5Init = { 1, 3, 7, 9, 31, 59, 117, 213, 293, 195, 991, 3531, 157, 1747, 20883, 0 }; + static ulong[] dim1918JoeKuoD5Init = { 1, 1, 3, 11, 17, 31, 63, 33, 415, 341, 779, 423, 5661, 2533, 23031, 0 }; + static ulong[] dim1919JoeKuoD5Init = { 1, 3, 5, 3, 11, 41, 69, 117, 441, 3, 885, 3387, 4291, 497, 9991, 0 }; + static ulong[] dim1920JoeKuoD5Init = { 1, 3, 1, 15, 27, 29, 17, 109, 315, 433, 291, 577, 3209, 3305, 6759, 0 }; + static ulong[] dim1921JoeKuoD5Init = { 1, 1, 5, 1, 29, 37, 75, 139, 243, 217, 319, 1025, 2415, 5957, 8303, 0 }; + static ulong[] dim1922JoeKuoD5Init = { 1, 3, 5, 9, 15, 41, 19, 21, 279, 563, 893, 1391, 4907, 14381, 7165, 0 }; + static ulong[] dim1923JoeKuoD5Init = { 1, 3, 1, 13, 21, 35, 23, 139, 441, 463, 563, 155, 2009, 14887, 30943, 0 }; + static ulong[] dim1924JoeKuoD5Init = { 1, 1, 5, 3, 23, 23, 13, 157, 511, 401, 1573, 3019, 1791, 587, 10927, 0 }; + static ulong[] dim1925JoeKuoD5Init = { 1, 1, 5, 5, 1, 45, 127, 85, 27, 729, 993, 1487, 5577, 14113, 23163, 0 }; + static ulong[] dim1926JoeKuoD5Init = { 1, 3, 7, 5, 31, 15, 19, 7, 503, 359, 595, 1471, 2587, 7827, 31497, 0 }; + static ulong[] dim1927JoeKuoD5Init = { 1, 3, 1, 1, 13, 29, 35, 49, 381, 677, 407, 2681, 7923, 2917, 4001, 0 }; + static ulong[] dim1928JoeKuoD5Init = { 1, 3, 3, 5, 25, 51, 3, 33, 229, 105, 1449, 417, 2577, 5185, 18737, 0 }; + static ulong[] dim1929JoeKuoD5Init = { 1, 3, 7, 9, 29, 17, 9, 185, 253, 929, 1267, 2559, 2271, 10501, 21687, 0 }; + static ulong[] dim1930JoeKuoD5Init = { 1, 3, 3, 13, 9, 29, 89, 193, 309, 385, 73, 1835, 5193, 10235, 29827, 0 }; + static ulong[] dim1931JoeKuoD5Init = { 1, 3, 5, 7, 29, 23, 9, 119, 325, 277, 1883, 613, 6299, 10799, 16271, 0 }; + static ulong[] dim1932JoeKuoD5Init = { 1, 1, 5, 11, 29, 55, 71, 5, 99, 303, 1853, 2225, 3047, 16019, 23257, 0 }; + static ulong[] dim1933JoeKuoD5Init = { 1, 3, 1, 1, 19, 19, 35, 39, 389, 737, 433, 1489, 5903, 10181, 11249, 0 }; + static ulong[] dim1934JoeKuoD5Init = { 1, 1, 3, 13, 15, 13, 21, 191, 369, 939, 1353, 2645, 221, 49, 14783, 0 }; + static ulong[] dim1935JoeKuoD5Init = { 1, 1, 1, 1, 17, 5, 21, 121, 359, 863, 893, 2887, 4431, 5245, 20865, 0 }; + static ulong[] dim1936JoeKuoD5Init = { 1, 3, 5, 11, 15, 25, 59, 37, 263, 425, 1143, 3843, 4955, 6639, 8411, 0 }; + static ulong[] dim1937JoeKuoD5Init = { 1, 1, 7, 15, 3, 5, 123, 131, 229, 93, 113, 3609, 2007, 7709, 32141, 0 }; + static ulong[] dim1938JoeKuoD5Init = { 1, 3, 5, 11, 25, 43, 103, 199, 243, 533, 1947, 683, 1013, 13155, 29877, 0 }; + static ulong[] dim1939JoeKuoD5Init = { 1, 3, 1, 9, 17, 41, 57, 99, 137, 839, 1437, 3997, 2473, 10169, 20253, 0 }; + static ulong[] dim1940JoeKuoD5Init = { 1, 1, 3, 5, 19, 49, 55, 185, 175, 319, 1173, 1049, 5289, 3297, 23755, 0 }; + static ulong[] dim1941JoeKuoD5Init = { 1, 3, 7, 5, 25, 7, 81, 119, 319, 743, 1655, 3719, 5731, 11015, 11309, 0 }; + static ulong[] dim1942JoeKuoD5Init = { 1, 1, 1, 9, 31, 53, 61, 119, 207, 689, 81, 367, 2495, 1965, 15559, 0 }; + static ulong[] dim1943JoeKuoD5Init = { 1, 1, 1, 3, 21, 47, 9, 199, 273, 397, 1293, 2709, 3687, 5755, 6015, 0 }; + static ulong[] dim1944JoeKuoD5Init = { 1, 3, 5, 15, 1, 7, 55, 55, 343, 363, 1207, 3731, 7489, 2365, 25301, 0 }; + static ulong[] dim1945JoeKuoD5Init = { 1, 3, 3, 7, 3, 31, 87, 15, 327, 479, 177, 1261, 913, 4189, 4565, 0 }; + static ulong[] dim1946JoeKuoD5Init = { 1, 1, 7, 9, 19, 37, 29, 17, 185, 827, 239, 281, 287, 16105, 23549, 0 }; + static ulong[] dim1947JoeKuoD5Init = { 1, 1, 1, 3, 23, 17, 73, 123, 287, 665, 297, 215, 359, 11741, 29159, 0 }; + static ulong[] dim1948JoeKuoD5Init = { 1, 3, 1, 11, 13, 45, 35, 81, 211, 257, 655, 911, 5949, 9597, 11677, 0 }; + static ulong[] dim1949JoeKuoD5Init = { 1, 3, 3, 15, 7, 39, 31, 103, 341, 871, 299, 635, 951, 13669, 30083, 0 }; + static ulong[] dim1950JoeKuoD5Init = { 1, 1, 1, 7, 7, 15, 55, 45, 375, 711, 1339, 3045, 4691, 13247, 14611, 0 }; + static ulong[] dim1951JoeKuoD5Init = { 1, 1, 1, 9, 19, 33, 67, 91, 83, 541, 1229, 3209, 2783, 11519, 10729, 0 }; + static ulong[] dim1952JoeKuoD5Init = { 1, 3, 5, 7, 15, 15, 89, 7, 173, 809, 1229, 117, 2323, 15145, 2863, 0 }; + static ulong[] dim1953JoeKuoD5Init = { 1, 3, 5, 13, 1, 55, 39, 187, 491, 675, 1357, 1109, 2701, 14891, 17061, 0 }; + static ulong[] dim1954JoeKuoD5Init = { 1, 3, 3, 5, 7, 47, 127, 111, 481, 177, 1553, 2949, 6403, 1993, 26227, 0 }; + static ulong[] dim1955JoeKuoD5Init = { 1, 1, 3, 11, 31, 3, 111, 193, 445, 359, 1039, 667, 7463, 7983, 10901, 0 }; + static ulong[] dim1956JoeKuoD5Init = { 1, 3, 5, 15, 29, 17, 15, 69, 111, 27, 647, 3377, 185, 12083, 21197, 0 }; + static ulong[] dim1957JoeKuoD5Init = { 1, 3, 7, 5, 17, 57, 5, 189, 383, 407, 145, 1185, 3307, 12373, 28531, 0 }; + static ulong[] dim1958JoeKuoD5Init = { 1, 1, 5, 9, 23, 43, 41, 19, 127, 687, 1841, 3707, 4983, 14585, 15253, 0 }; + static ulong[] dim1959JoeKuoD5Init = { 1, 1, 3, 9, 13, 61, 13, 113, 43, 423, 1073, 1843, 1071, 7869, 21137, 0 }; + static ulong[] dim1960JoeKuoD5Init = { 1, 1, 3, 3, 7, 43, 87, 185, 375, 699, 283, 3265, 4905, 9317, 3055, 0 }; + static ulong[] dim1961JoeKuoD5Init = { 1, 1, 7, 9, 17, 15, 47, 73, 211, 37, 427, 3841, 2801, 12131, 19619, 0 }; + static ulong[] dim1962JoeKuoD5Init = { 1, 1, 1, 7, 17, 35, 53, 67, 221, 97, 199, 2825, 1997, 9903, 3003, 0 }; + static ulong[] dim1963JoeKuoD5Init = { 1, 3, 5, 9, 23, 53, 69, 225, 413, 307, 553, 2631, 6499, 6277, 30337, 0 }; + static ulong[] dim1964JoeKuoD5Init = { 1, 3, 5, 13, 5, 23, 85, 193, 437, 607, 397, 2003, 4345, 3575, 27939, 0 }; + static ulong[] dim1965JoeKuoD5Init = { 1, 3, 1, 13, 13, 45, 117, 191, 143, 477, 473, 3051, 5903, 6253, 22679, 0 }; + static ulong[] dim1966JoeKuoD5Init = { 1, 1, 1, 13, 31, 49, 31, 217, 119, 893, 1415, 1633, 7573, 8353, 32231, 0 }; + static ulong[] dim1967JoeKuoD5Init = { 1, 1, 3, 5, 29, 47, 25, 3, 425, 883, 1461, 3679, 6635, 9103, 26793, 0 }; + static ulong[] dim1968JoeKuoD5Init = { 1, 1, 5, 15, 11, 27, 87, 31, 153, 115, 1573, 745, 6515, 14321, 21301, 0 }; + static ulong[] dim1969JoeKuoD5Init = { 1, 1, 5, 11, 15, 57, 41, 157, 147, 867, 1959, 943, 6431, 14581, 9579, 0 }; + static ulong[] dim1970JoeKuoD5Init = { 1, 3, 7, 9, 5, 13, 1, 203, 317, 185, 1569, 3621, 4873, 13249, 19153, 0 }; + static ulong[] dim1971JoeKuoD5Init = { 1, 1, 1, 5, 5, 29, 41, 3, 37, 919, 1037, 237, 4699, 12011, 18669, 0 }; + static ulong[] dim1972JoeKuoD5Init = { 1, 1, 1, 1, 21, 1, 55, 195, 289, 635, 981, 1395, 1827, 7481, 19163, 0 }; + static ulong[] dim1973JoeKuoD5Init = { 1, 1, 5, 13, 15, 15, 89, 109, 17, 111, 815, 2637, 6917, 7973, 9471, 0 }; + static ulong[] dim1974JoeKuoD5Init = { 1, 1, 1, 15, 9, 25, 73, 101, 417, 519, 1697, 2861, 2281, 10959, 30433, 0 }; + static ulong[] dim1975JoeKuoD5Init = { 1, 3, 3, 3, 21, 51, 89, 157, 181, 307, 355, 661, 4885, 12411, 23473, 0 }; + static ulong[] dim1976JoeKuoD5Init = { 1, 1, 1, 15, 17, 37, 19, 139, 205, 73, 97, 2463, 2785, 9355, 23989, 0 }; + static ulong[] dim1977JoeKuoD5Init = { 1, 1, 3, 1, 7, 39, 117, 191, 395, 539, 1823, 2333, 1205, 14131, 2301, 0 }; + static ulong[] dim1978JoeKuoD5Init = { 1, 1, 5, 13, 21, 11, 49, 43, 381, 15, 1743, 641, 95, 10581, 15437, 0 }; + static ulong[] dim1979JoeKuoD5Init = { 1, 3, 7, 7, 5, 53, 55, 23, 265, 163, 173, 1399, 7257, 15097, 13491, 0 }; + static ulong[] dim1980JoeKuoD5Init = { 1, 3, 3, 13, 27, 55, 97, 51, 469, 7, 871, 3213, 5719, 871, 11669, 0 }; + static ulong[] dim1981JoeKuoD5Init = { 1, 1, 7, 3, 29, 35, 47, 31, 77, 335, 537, 1695, 461, 14417, 23945, 0 }; + static ulong[] dim1982JoeKuoD5Init = { 1, 3, 5, 13, 1, 47, 97, 113, 235, 593, 1437, 3893, 5299, 857, 451, 0 }; + static ulong[] dim1983JoeKuoD5Init = { 1, 3, 7, 3, 3, 53, 51, 203, 177, 205, 773, 281, 7689, 8039, 7275, 0 }; + static ulong[] dim1984JoeKuoD5Init = { 1, 1, 7, 3, 3, 37, 33, 113, 429, 791, 1593, 3259, 1275, 11113, 16001, 0 }; + static ulong[] dim1985JoeKuoD5Init = { 1, 3, 5, 7, 27, 9, 109, 229, 453, 633, 2047, 1803, 4127, 3453, 15625, 0 }; + static ulong[] dim1986JoeKuoD5Init = { 1, 3, 5, 15, 17, 59, 15, 73, 105, 627, 1181, 2925, 2077, 16067, 15829, 0 }; + static ulong[] dim1987JoeKuoD5Init = { 1, 3, 1, 1, 15, 41, 1, 143, 493, 261, 845, 737, 6249, 7663, 32439, 0 }; + static ulong[] dim1988JoeKuoD5Init = { 1, 3, 5, 9, 11, 45, 101, 227, 227, 211, 243, 2817, 179, 3361, 20535, 0 }; + static ulong[] dim1989JoeKuoD5Init = { 1, 3, 1, 3, 11, 25, 105, 173, 249, 465, 853, 2365, 5035, 11541, 5481, 0 }; + static ulong[] dim1990JoeKuoD5Init = { 1, 3, 5, 9, 21, 29, 77, 245, 311, 879, 1007, 2545, 1561, 2949, 24855, 0 }; + static ulong[] dim1991JoeKuoD5Init = { 1, 1, 5, 13, 1, 31, 105, 151, 127, 413, 553, 645, 863, 15943, 32731, 0 }; + static ulong[] dim1992JoeKuoD5Init = { 1, 3, 7, 11, 21, 13, 71, 229, 283, 493, 1445, 15, 4681, 3137, 18199, 0 }; + static ulong[] dim1993JoeKuoD5Init = { 1, 1, 3, 15, 27, 17, 37, 213, 253, 117, 205, 1489, 2997, 6483, 17201, 0 }; + static ulong[] dim1994JoeKuoD5Init = { 1, 1, 7, 13, 3, 29, 83, 109, 503, 139, 1119, 59, 5259, 8289, 7717, 0 }; + static ulong[] dim1995JoeKuoD5Init = { 1, 1, 3, 13, 13, 5, 65, 231, 117, 1009, 163, 21, 7639, 16275, 10661, 0 }; + static ulong[] dim1996JoeKuoD5Init = { 1, 3, 7, 7, 19, 63, 31, 211, 487, 277, 27, 3685, 5371, 8157, 29735, 0 }; + static ulong[] dim1997JoeKuoD5Init = { 1, 1, 3, 1, 11, 49, 113, 191, 3, 923, 797, 2055, 3999, 8511, 23931, 0 }; + static ulong[] dim1998JoeKuoD5Init = { 1, 1, 7, 7, 13, 27, 87, 43, 433, 401, 1441, 1301, 2639, 5773, 12431, 0 }; + static ulong[] dim1999JoeKuoD5Init = { 1, 1, 3, 15, 21, 55, 17, 57, 449, 811, 519, 2329, 7607, 4255, 2845, 0 }; + + static ulong[][] JoeKuoD5initializers = + { + dim1JoeKuoD5Init, + dim2JoeKuoD5Init, + dim3JoeKuoD5Init, + dim4JoeKuoD5Init, + dim5JoeKuoD5Init, + dim6JoeKuoD5Init, + dim7JoeKuoD5Init, + dim8JoeKuoD5Init, + dim9JoeKuoD5Init, + dim10JoeKuoD5Init, + dim11JoeKuoD5Init, + dim12JoeKuoD5Init, + dim13JoeKuoD5Init, + dim14JoeKuoD5Init, + dim15JoeKuoD5Init, + dim16JoeKuoD5Init, + dim17JoeKuoD5Init, + dim18JoeKuoD5Init, + dim19JoeKuoD5Init, + dim20JoeKuoD5Init, + dim21JoeKuoD5Init, + dim22JoeKuoD5Init, + dim23JoeKuoD5Init, + dim24JoeKuoD5Init, + dim25JoeKuoD5Init, + dim26JoeKuoD5Init, + dim27JoeKuoD5Init, + dim28JoeKuoD5Init, + dim29JoeKuoD5Init, + dim30JoeKuoD5Init, + dim31JoeKuoD5Init, + dim32JoeKuoD5Init, + dim33JoeKuoD5Init, + dim34JoeKuoD5Init, + dim35JoeKuoD5Init, + dim36JoeKuoD5Init, + dim37JoeKuoD5Init, + dim38JoeKuoD5Init, + dim39JoeKuoD5Init, + dim40JoeKuoD5Init, + dim41JoeKuoD5Init, + dim42JoeKuoD5Init, + dim43JoeKuoD5Init, + dim44JoeKuoD5Init, + dim45JoeKuoD5Init, + dim46JoeKuoD5Init, + dim47JoeKuoD5Init, + dim48JoeKuoD5Init, + dim49JoeKuoD5Init, + dim50JoeKuoD5Init, + dim51JoeKuoD5Init, + dim52JoeKuoD5Init, + dim53JoeKuoD5Init, + dim54JoeKuoD5Init, + dim55JoeKuoD5Init, + dim56JoeKuoD5Init, + dim57JoeKuoD5Init, + dim58JoeKuoD5Init, + dim59JoeKuoD5Init, + dim60JoeKuoD5Init, + dim61JoeKuoD5Init, + dim62JoeKuoD5Init, + dim63JoeKuoD5Init, + dim64JoeKuoD5Init, + dim65JoeKuoD5Init, + dim66JoeKuoD5Init, + dim67JoeKuoD5Init, + dim68JoeKuoD5Init, + dim69JoeKuoD5Init, + dim70JoeKuoD5Init, + dim71JoeKuoD5Init, + dim72JoeKuoD5Init, + dim73JoeKuoD5Init, + dim74JoeKuoD5Init, + dim75JoeKuoD5Init, + dim76JoeKuoD5Init, + dim77JoeKuoD5Init, + dim78JoeKuoD5Init, + dim79JoeKuoD5Init, + dim80JoeKuoD5Init, + dim81JoeKuoD5Init, + dim82JoeKuoD5Init, + dim83JoeKuoD5Init, + dim84JoeKuoD5Init, + dim85JoeKuoD5Init, + dim86JoeKuoD5Init, + dim87JoeKuoD5Init, + dim88JoeKuoD5Init, + dim89JoeKuoD5Init, + dim90JoeKuoD5Init, + dim91JoeKuoD5Init, + dim92JoeKuoD5Init, + dim93JoeKuoD5Init, + dim94JoeKuoD5Init, + dim95JoeKuoD5Init, + dim96JoeKuoD5Init, + dim97JoeKuoD5Init, + dim98JoeKuoD5Init, + dim99JoeKuoD5Init, + dim100JoeKuoD5Init, + dim101JoeKuoD5Init, + dim102JoeKuoD5Init, + dim103JoeKuoD5Init, + dim104JoeKuoD5Init, + dim105JoeKuoD5Init, + dim106JoeKuoD5Init, + dim107JoeKuoD5Init, + dim108JoeKuoD5Init, + dim109JoeKuoD5Init, + dim110JoeKuoD5Init, + dim111JoeKuoD5Init, + dim112JoeKuoD5Init, + dim113JoeKuoD5Init, + dim114JoeKuoD5Init, + dim115JoeKuoD5Init, + dim116JoeKuoD5Init, + dim117JoeKuoD5Init, + dim118JoeKuoD5Init, + dim119JoeKuoD5Init, + dim120JoeKuoD5Init, + dim121JoeKuoD5Init, + dim122JoeKuoD5Init, + dim123JoeKuoD5Init, + dim124JoeKuoD5Init, + dim125JoeKuoD5Init, + dim126JoeKuoD5Init, + dim127JoeKuoD5Init, + dim128JoeKuoD5Init, + dim129JoeKuoD5Init, + dim130JoeKuoD5Init, + dim131JoeKuoD5Init, + dim132JoeKuoD5Init, + dim133JoeKuoD5Init, + dim134JoeKuoD5Init, + dim135JoeKuoD5Init, + dim136JoeKuoD5Init, + dim137JoeKuoD5Init, + dim138JoeKuoD5Init, + dim139JoeKuoD5Init, + dim140JoeKuoD5Init, + dim141JoeKuoD5Init, + dim142JoeKuoD5Init, + dim143JoeKuoD5Init, + dim144JoeKuoD5Init, + dim145JoeKuoD5Init, + dim146JoeKuoD5Init, + dim147JoeKuoD5Init, + dim148JoeKuoD5Init, + dim149JoeKuoD5Init, + dim150JoeKuoD5Init, + dim151JoeKuoD5Init, + dim152JoeKuoD5Init, + dim153JoeKuoD5Init, + dim154JoeKuoD5Init, + dim155JoeKuoD5Init, + dim156JoeKuoD5Init, + dim157JoeKuoD5Init, + dim158JoeKuoD5Init, + dim159JoeKuoD5Init, + dim160JoeKuoD5Init, + dim161JoeKuoD5Init, + dim162JoeKuoD5Init, + dim163JoeKuoD5Init, + dim164JoeKuoD5Init, + dim165JoeKuoD5Init, + dim166JoeKuoD5Init, + dim167JoeKuoD5Init, + dim168JoeKuoD5Init, + dim169JoeKuoD5Init, + dim170JoeKuoD5Init, + dim171JoeKuoD5Init, + dim172JoeKuoD5Init, + dim173JoeKuoD5Init, + dim174JoeKuoD5Init, + dim175JoeKuoD5Init, + dim176JoeKuoD5Init, + dim177JoeKuoD5Init, + dim178JoeKuoD5Init, + dim179JoeKuoD5Init, + dim180JoeKuoD5Init, + dim181JoeKuoD5Init, + dim182JoeKuoD5Init, + dim183JoeKuoD5Init, + dim184JoeKuoD5Init, + dim185JoeKuoD5Init, + dim186JoeKuoD5Init, + dim187JoeKuoD5Init, + dim188JoeKuoD5Init, + dim189JoeKuoD5Init, + dim190JoeKuoD5Init, + dim191JoeKuoD5Init, + dim192JoeKuoD5Init, + dim193JoeKuoD5Init, + dim194JoeKuoD5Init, + dim195JoeKuoD5Init, + dim196JoeKuoD5Init, + dim197JoeKuoD5Init, + dim198JoeKuoD5Init, + dim199JoeKuoD5Init, + dim200JoeKuoD5Init, + dim201JoeKuoD5Init, + dim202JoeKuoD5Init, + dim203JoeKuoD5Init, + dim204JoeKuoD5Init, + dim205JoeKuoD5Init, + dim206JoeKuoD5Init, + dim207JoeKuoD5Init, + dim208JoeKuoD5Init, + dim209JoeKuoD5Init, + dim210JoeKuoD5Init, + dim211JoeKuoD5Init, + dim212JoeKuoD5Init, + dim213JoeKuoD5Init, + dim214JoeKuoD5Init, + dim215JoeKuoD5Init, + dim216JoeKuoD5Init, + dim217JoeKuoD5Init, + dim218JoeKuoD5Init, + dim219JoeKuoD5Init, + dim220JoeKuoD5Init, + dim221JoeKuoD5Init, + dim222JoeKuoD5Init, + dim223JoeKuoD5Init, + dim224JoeKuoD5Init, + dim225JoeKuoD5Init, + dim226JoeKuoD5Init, + dim227JoeKuoD5Init, + dim228JoeKuoD5Init, + dim229JoeKuoD5Init, + dim230JoeKuoD5Init, + dim231JoeKuoD5Init, + dim232JoeKuoD5Init, + dim233JoeKuoD5Init, + dim234JoeKuoD5Init, + dim235JoeKuoD5Init, + dim236JoeKuoD5Init, + dim237JoeKuoD5Init, + dim238JoeKuoD5Init, + dim239JoeKuoD5Init, + dim240JoeKuoD5Init, + dim241JoeKuoD5Init, + dim242JoeKuoD5Init, + dim243JoeKuoD5Init, + dim244JoeKuoD5Init, + dim245JoeKuoD5Init, + dim246JoeKuoD5Init, + dim247JoeKuoD5Init, + dim248JoeKuoD5Init, + dim249JoeKuoD5Init, + dim250JoeKuoD5Init, + dim251JoeKuoD5Init, + dim252JoeKuoD5Init, + dim253JoeKuoD5Init, + dim254JoeKuoD5Init, + dim255JoeKuoD5Init, + dim256JoeKuoD5Init, + dim257JoeKuoD5Init, + dim258JoeKuoD5Init, + dim259JoeKuoD5Init, + dim260JoeKuoD5Init, + dim261JoeKuoD5Init, + dim262JoeKuoD5Init, + dim263JoeKuoD5Init, + dim264JoeKuoD5Init, + dim265JoeKuoD5Init, + dim266JoeKuoD5Init, + dim267JoeKuoD5Init, + dim268JoeKuoD5Init, + dim269JoeKuoD5Init, + dim270JoeKuoD5Init, + dim271JoeKuoD5Init, + dim272JoeKuoD5Init, + dim273JoeKuoD5Init, + dim274JoeKuoD5Init, + dim275JoeKuoD5Init, + dim276JoeKuoD5Init, + dim277JoeKuoD5Init, + dim278JoeKuoD5Init, + dim279JoeKuoD5Init, + dim280JoeKuoD5Init, + dim281JoeKuoD5Init, + dim282JoeKuoD5Init, + dim283JoeKuoD5Init, + dim284JoeKuoD5Init, + dim285JoeKuoD5Init, + dim286JoeKuoD5Init, + dim287JoeKuoD5Init, + dim288JoeKuoD5Init, + dim289JoeKuoD5Init, + dim290JoeKuoD5Init, + dim291JoeKuoD5Init, + dim292JoeKuoD5Init, + dim293JoeKuoD5Init, + dim294JoeKuoD5Init, + dim295JoeKuoD5Init, + dim296JoeKuoD5Init, + dim297JoeKuoD5Init, + dim298JoeKuoD5Init, + dim299JoeKuoD5Init, + dim300JoeKuoD5Init, + dim301JoeKuoD5Init, + dim302JoeKuoD5Init, + dim303JoeKuoD5Init, + dim304JoeKuoD5Init, + dim305JoeKuoD5Init, + dim306JoeKuoD5Init, + dim307JoeKuoD5Init, + dim308JoeKuoD5Init, + dim309JoeKuoD5Init, + dim310JoeKuoD5Init, + dim311JoeKuoD5Init, + dim312JoeKuoD5Init, + dim313JoeKuoD5Init, + dim314JoeKuoD5Init, + dim315JoeKuoD5Init, + dim316JoeKuoD5Init, + dim317JoeKuoD5Init, + dim318JoeKuoD5Init, + dim319JoeKuoD5Init, + dim320JoeKuoD5Init, + dim321JoeKuoD5Init, + dim322JoeKuoD5Init, + dim323JoeKuoD5Init, + dim324JoeKuoD5Init, + dim325JoeKuoD5Init, + dim326JoeKuoD5Init, + dim327JoeKuoD5Init, + dim328JoeKuoD5Init, + dim329JoeKuoD5Init, + dim330JoeKuoD5Init, + dim331JoeKuoD5Init, + dim332JoeKuoD5Init, + dim333JoeKuoD5Init, + dim334JoeKuoD5Init, + dim335JoeKuoD5Init, + dim336JoeKuoD5Init, + dim337JoeKuoD5Init, + dim338JoeKuoD5Init, + dim339JoeKuoD5Init, + dim340JoeKuoD5Init, + dim341JoeKuoD5Init, + dim342JoeKuoD5Init, + dim343JoeKuoD5Init, + dim344JoeKuoD5Init, + dim345JoeKuoD5Init, + dim346JoeKuoD5Init, + dim347JoeKuoD5Init, + dim348JoeKuoD5Init, + dim349JoeKuoD5Init, + dim350JoeKuoD5Init, + dim351JoeKuoD5Init, + dim352JoeKuoD5Init, + dim353JoeKuoD5Init, + dim354JoeKuoD5Init, + dim355JoeKuoD5Init, + dim356JoeKuoD5Init, + dim357JoeKuoD5Init, + dim358JoeKuoD5Init, + dim359JoeKuoD5Init, + dim360JoeKuoD5Init, + dim361JoeKuoD5Init, + dim362JoeKuoD5Init, + dim363JoeKuoD5Init, + dim364JoeKuoD5Init, + dim365JoeKuoD5Init, + dim366JoeKuoD5Init, + dim367JoeKuoD5Init, + dim368JoeKuoD5Init, + dim369JoeKuoD5Init, + dim370JoeKuoD5Init, + dim371JoeKuoD5Init, + dim372JoeKuoD5Init, + dim373JoeKuoD5Init, + dim374JoeKuoD5Init, + dim375JoeKuoD5Init, + dim376JoeKuoD5Init, + dim377JoeKuoD5Init, + dim378JoeKuoD5Init, + dim379JoeKuoD5Init, + dim380JoeKuoD5Init, + dim381JoeKuoD5Init, + dim382JoeKuoD5Init, + dim383JoeKuoD5Init, + dim384JoeKuoD5Init, + dim385JoeKuoD5Init, + dim386JoeKuoD5Init, + dim387JoeKuoD5Init, + dim388JoeKuoD5Init, + dim389JoeKuoD5Init, + dim390JoeKuoD5Init, + dim391JoeKuoD5Init, + dim392JoeKuoD5Init, + dim393JoeKuoD5Init, + dim394JoeKuoD5Init, + dim395JoeKuoD5Init, + dim396JoeKuoD5Init, + dim397JoeKuoD5Init, + dim398JoeKuoD5Init, + dim399JoeKuoD5Init, + dim400JoeKuoD5Init, + dim401JoeKuoD5Init, + dim402JoeKuoD5Init, + dim403JoeKuoD5Init, + dim404JoeKuoD5Init, + dim405JoeKuoD5Init, + dim406JoeKuoD5Init, + dim407JoeKuoD5Init, + dim408JoeKuoD5Init, + dim409JoeKuoD5Init, + dim410JoeKuoD5Init, + dim411JoeKuoD5Init, + dim412JoeKuoD5Init, + dim413JoeKuoD5Init, + dim414JoeKuoD5Init, + dim415JoeKuoD5Init, + dim416JoeKuoD5Init, + dim417JoeKuoD5Init, + dim418JoeKuoD5Init, + dim419JoeKuoD5Init, + dim420JoeKuoD5Init, + dim421JoeKuoD5Init, + dim422JoeKuoD5Init, + dim423JoeKuoD5Init, + dim424JoeKuoD5Init, + dim425JoeKuoD5Init, + dim426JoeKuoD5Init, + dim427JoeKuoD5Init, + dim428JoeKuoD5Init, + dim429JoeKuoD5Init, + dim430JoeKuoD5Init, + dim431JoeKuoD5Init, + dim432JoeKuoD5Init, + dim433JoeKuoD5Init, + dim434JoeKuoD5Init, + dim435JoeKuoD5Init, + dim436JoeKuoD5Init, + dim437JoeKuoD5Init, + dim438JoeKuoD5Init, + dim439JoeKuoD5Init, + dim440JoeKuoD5Init, + dim441JoeKuoD5Init, + dim442JoeKuoD5Init, + dim443JoeKuoD5Init, + dim444JoeKuoD5Init, + dim445JoeKuoD5Init, + dim446JoeKuoD5Init, + dim447JoeKuoD5Init, + dim448JoeKuoD5Init, + dim449JoeKuoD5Init, + dim450JoeKuoD5Init, + dim451JoeKuoD5Init, + dim452JoeKuoD5Init, + dim453JoeKuoD5Init, + dim454JoeKuoD5Init, + dim455JoeKuoD5Init, + dim456JoeKuoD5Init, + dim457JoeKuoD5Init, + dim458JoeKuoD5Init, + dim459JoeKuoD5Init, + dim460JoeKuoD5Init, + dim461JoeKuoD5Init, + dim462JoeKuoD5Init, + dim463JoeKuoD5Init, + dim464JoeKuoD5Init, + dim465JoeKuoD5Init, + dim466JoeKuoD5Init, + dim467JoeKuoD5Init, + dim468JoeKuoD5Init, + dim469JoeKuoD5Init, + dim470JoeKuoD5Init, + dim471JoeKuoD5Init, + dim472JoeKuoD5Init, + dim473JoeKuoD5Init, + dim474JoeKuoD5Init, + dim475JoeKuoD5Init, + dim476JoeKuoD5Init, + dim477JoeKuoD5Init, + dim478JoeKuoD5Init, + dim479JoeKuoD5Init, + dim480JoeKuoD5Init, + dim481JoeKuoD5Init, + dim482JoeKuoD5Init, + dim483JoeKuoD5Init, + dim484JoeKuoD5Init, + dim485JoeKuoD5Init, + dim486JoeKuoD5Init, + dim487JoeKuoD5Init, + dim488JoeKuoD5Init, + dim489JoeKuoD5Init, + dim490JoeKuoD5Init, + dim491JoeKuoD5Init, + dim492JoeKuoD5Init, + dim493JoeKuoD5Init, + dim494JoeKuoD5Init, + dim495JoeKuoD5Init, + dim496JoeKuoD5Init, + dim497JoeKuoD5Init, + dim498JoeKuoD5Init, + dim499JoeKuoD5Init, + dim500JoeKuoD5Init, + dim501JoeKuoD5Init, + dim502JoeKuoD5Init, + dim503JoeKuoD5Init, + dim504JoeKuoD5Init, + dim505JoeKuoD5Init, + dim506JoeKuoD5Init, + dim507JoeKuoD5Init, + dim508JoeKuoD5Init, + dim509JoeKuoD5Init, + dim510JoeKuoD5Init, + dim511JoeKuoD5Init, + dim512JoeKuoD5Init, + dim513JoeKuoD5Init, + dim514JoeKuoD5Init, + dim515JoeKuoD5Init, + dim516JoeKuoD5Init, + dim517JoeKuoD5Init, + dim518JoeKuoD5Init, + dim519JoeKuoD5Init, + dim520JoeKuoD5Init, + dim521JoeKuoD5Init, + dim522JoeKuoD5Init, + dim523JoeKuoD5Init, + dim524JoeKuoD5Init, + dim525JoeKuoD5Init, + dim526JoeKuoD5Init, + dim527JoeKuoD5Init, + dim528JoeKuoD5Init, + dim529JoeKuoD5Init, + dim530JoeKuoD5Init, + dim531JoeKuoD5Init, + dim532JoeKuoD5Init, + dim533JoeKuoD5Init, + dim534JoeKuoD5Init, + dim535JoeKuoD5Init, + dim536JoeKuoD5Init, + dim537JoeKuoD5Init, + dim538JoeKuoD5Init, + dim539JoeKuoD5Init, + dim540JoeKuoD5Init, + dim541JoeKuoD5Init, + dim542JoeKuoD5Init, + dim543JoeKuoD5Init, + dim544JoeKuoD5Init, + dim545JoeKuoD5Init, + dim546JoeKuoD5Init, + dim547JoeKuoD5Init, + dim548JoeKuoD5Init, + dim549JoeKuoD5Init, + dim550JoeKuoD5Init, + dim551JoeKuoD5Init, + dim552JoeKuoD5Init, + dim553JoeKuoD5Init, + dim554JoeKuoD5Init, + dim555JoeKuoD5Init, + dim556JoeKuoD5Init, + dim557JoeKuoD5Init, + dim558JoeKuoD5Init, + dim559JoeKuoD5Init, + dim560JoeKuoD5Init, + dim561JoeKuoD5Init, + dim562JoeKuoD5Init, + dim563JoeKuoD5Init, + dim564JoeKuoD5Init, + dim565JoeKuoD5Init, + dim566JoeKuoD5Init, + dim567JoeKuoD5Init, + dim568JoeKuoD5Init, + dim569JoeKuoD5Init, + dim570JoeKuoD5Init, + dim571JoeKuoD5Init, + dim572JoeKuoD5Init, + dim573JoeKuoD5Init, + dim574JoeKuoD5Init, + dim575JoeKuoD5Init, + dim576JoeKuoD5Init, + dim577JoeKuoD5Init, + dim578JoeKuoD5Init, + dim579JoeKuoD5Init, + dim580JoeKuoD5Init, + dim581JoeKuoD5Init, + dim582JoeKuoD5Init, + dim583JoeKuoD5Init, + dim584JoeKuoD5Init, + dim585JoeKuoD5Init, + dim586JoeKuoD5Init, + dim587JoeKuoD5Init, + dim588JoeKuoD5Init, + dim589JoeKuoD5Init, + dim590JoeKuoD5Init, + dim591JoeKuoD5Init, + dim592JoeKuoD5Init, + dim593JoeKuoD5Init, + dim594JoeKuoD5Init, + dim595JoeKuoD5Init, + dim596JoeKuoD5Init, + dim597JoeKuoD5Init, + dim598JoeKuoD5Init, + dim599JoeKuoD5Init, + dim600JoeKuoD5Init, + dim601JoeKuoD5Init, + dim602JoeKuoD5Init, + dim603JoeKuoD5Init, + dim604JoeKuoD5Init, + dim605JoeKuoD5Init, + dim606JoeKuoD5Init, + dim607JoeKuoD5Init, + dim608JoeKuoD5Init, + dim609JoeKuoD5Init, + dim610JoeKuoD5Init, + dim611JoeKuoD5Init, + dim612JoeKuoD5Init, + dim613JoeKuoD5Init, + dim614JoeKuoD5Init, + dim615JoeKuoD5Init, + dim616JoeKuoD5Init, + dim617JoeKuoD5Init, + dim618JoeKuoD5Init, + dim619JoeKuoD5Init, + dim620JoeKuoD5Init, + dim621JoeKuoD5Init, + dim622JoeKuoD5Init, + dim623JoeKuoD5Init, + dim624JoeKuoD5Init, + dim625JoeKuoD5Init, + dim626JoeKuoD5Init, + dim627JoeKuoD5Init, + dim628JoeKuoD5Init, + dim629JoeKuoD5Init, + dim630JoeKuoD5Init, + dim631JoeKuoD5Init, + dim632JoeKuoD5Init, + dim633JoeKuoD5Init, + dim634JoeKuoD5Init, + dim635JoeKuoD5Init, + dim636JoeKuoD5Init, + dim637JoeKuoD5Init, + dim638JoeKuoD5Init, + dim639JoeKuoD5Init, + dim640JoeKuoD5Init, + dim641JoeKuoD5Init, + dim642JoeKuoD5Init, + dim643JoeKuoD5Init, + dim644JoeKuoD5Init, + dim645JoeKuoD5Init, + dim646JoeKuoD5Init, + dim647JoeKuoD5Init, + dim648JoeKuoD5Init, + dim649JoeKuoD5Init, + dim650JoeKuoD5Init, + dim651JoeKuoD5Init, + dim652JoeKuoD5Init, + dim653JoeKuoD5Init, + dim654JoeKuoD5Init, + dim655JoeKuoD5Init, + dim656JoeKuoD5Init, + dim657JoeKuoD5Init, + dim658JoeKuoD5Init, + dim659JoeKuoD5Init, + dim660JoeKuoD5Init, + dim661JoeKuoD5Init, + dim662JoeKuoD5Init, + dim663JoeKuoD5Init, + dim664JoeKuoD5Init, + dim665JoeKuoD5Init, + dim666JoeKuoD5Init, + dim667JoeKuoD5Init, + dim668JoeKuoD5Init, + dim669JoeKuoD5Init, + dim670JoeKuoD5Init, + dim671JoeKuoD5Init, + dim672JoeKuoD5Init, + dim673JoeKuoD5Init, + dim674JoeKuoD5Init, + dim675JoeKuoD5Init, + dim676JoeKuoD5Init, + dim677JoeKuoD5Init, + dim678JoeKuoD5Init, + dim679JoeKuoD5Init, + dim680JoeKuoD5Init, + dim681JoeKuoD5Init, + dim682JoeKuoD5Init, + dim683JoeKuoD5Init, + dim684JoeKuoD5Init, + dim685JoeKuoD5Init, + dim686JoeKuoD5Init, + dim687JoeKuoD5Init, + dim688JoeKuoD5Init, + dim689JoeKuoD5Init, + dim690JoeKuoD5Init, + dim691JoeKuoD5Init, + dim692JoeKuoD5Init, + dim693JoeKuoD5Init, + dim694JoeKuoD5Init, + dim695JoeKuoD5Init, + dim696JoeKuoD5Init, + dim697JoeKuoD5Init, + dim698JoeKuoD5Init, + dim699JoeKuoD5Init, + dim700JoeKuoD5Init, + dim701JoeKuoD5Init, + dim702JoeKuoD5Init, + dim703JoeKuoD5Init, + dim704JoeKuoD5Init, + dim705JoeKuoD5Init, + dim706JoeKuoD5Init, + dim707JoeKuoD5Init, + dim708JoeKuoD5Init, + dim709JoeKuoD5Init, + dim710JoeKuoD5Init, + dim711JoeKuoD5Init, + dim712JoeKuoD5Init, + dim713JoeKuoD5Init, + dim714JoeKuoD5Init, + dim715JoeKuoD5Init, + dim716JoeKuoD5Init, + dim717JoeKuoD5Init, + dim718JoeKuoD5Init, + dim719JoeKuoD5Init, + dim720JoeKuoD5Init, + dim721JoeKuoD5Init, + dim722JoeKuoD5Init, + dim723JoeKuoD5Init, + dim724JoeKuoD5Init, + dim725JoeKuoD5Init, + dim726JoeKuoD5Init, + dim727JoeKuoD5Init, + dim728JoeKuoD5Init, + dim729JoeKuoD5Init, + dim730JoeKuoD5Init, + dim731JoeKuoD5Init, + dim732JoeKuoD5Init, + dim733JoeKuoD5Init, + dim734JoeKuoD5Init, + dim735JoeKuoD5Init, + dim736JoeKuoD5Init, + dim737JoeKuoD5Init, + dim738JoeKuoD5Init, + dim739JoeKuoD5Init, + dim740JoeKuoD5Init, + dim741JoeKuoD5Init, + dim742JoeKuoD5Init, + dim743JoeKuoD5Init, + dim744JoeKuoD5Init, + dim745JoeKuoD5Init, + dim746JoeKuoD5Init, + dim747JoeKuoD5Init, + dim748JoeKuoD5Init, + dim749JoeKuoD5Init, + dim750JoeKuoD5Init, + dim751JoeKuoD5Init, + dim752JoeKuoD5Init, + dim753JoeKuoD5Init, + dim754JoeKuoD5Init, + dim755JoeKuoD5Init, + dim756JoeKuoD5Init, + dim757JoeKuoD5Init, + dim758JoeKuoD5Init, + dim759JoeKuoD5Init, + dim760JoeKuoD5Init, + dim761JoeKuoD5Init, + dim762JoeKuoD5Init, + dim763JoeKuoD5Init, + dim764JoeKuoD5Init, + dim765JoeKuoD5Init, + dim766JoeKuoD5Init, + dim767JoeKuoD5Init, + dim768JoeKuoD5Init, + dim769JoeKuoD5Init, + dim770JoeKuoD5Init, + dim771JoeKuoD5Init, + dim772JoeKuoD5Init, + dim773JoeKuoD5Init, + dim774JoeKuoD5Init, + dim775JoeKuoD5Init, + dim776JoeKuoD5Init, + dim777JoeKuoD5Init, + dim778JoeKuoD5Init, + dim779JoeKuoD5Init, + dim780JoeKuoD5Init, + dim781JoeKuoD5Init, + dim782JoeKuoD5Init, + dim783JoeKuoD5Init, + dim784JoeKuoD5Init, + dim785JoeKuoD5Init, + dim786JoeKuoD5Init, + dim787JoeKuoD5Init, + dim788JoeKuoD5Init, + dim789JoeKuoD5Init, + dim790JoeKuoD5Init, + dim791JoeKuoD5Init, + dim792JoeKuoD5Init, + dim793JoeKuoD5Init, + dim794JoeKuoD5Init, + dim795JoeKuoD5Init, + dim796JoeKuoD5Init, + dim797JoeKuoD5Init, + dim798JoeKuoD5Init, + dim799JoeKuoD5Init, + dim800JoeKuoD5Init, + dim801JoeKuoD5Init, + dim802JoeKuoD5Init, + dim803JoeKuoD5Init, + dim804JoeKuoD5Init, + dim805JoeKuoD5Init, + dim806JoeKuoD5Init, + dim807JoeKuoD5Init, + dim808JoeKuoD5Init, + dim809JoeKuoD5Init, + dim810JoeKuoD5Init, + dim811JoeKuoD5Init, + dim812JoeKuoD5Init, + dim813JoeKuoD5Init, + dim814JoeKuoD5Init, + dim815JoeKuoD5Init, + dim816JoeKuoD5Init, + dim817JoeKuoD5Init, + dim818JoeKuoD5Init, + dim819JoeKuoD5Init, + dim820JoeKuoD5Init, + dim821JoeKuoD5Init, + dim822JoeKuoD5Init, + dim823JoeKuoD5Init, + dim824JoeKuoD5Init, + dim825JoeKuoD5Init, + dim826JoeKuoD5Init, + dim827JoeKuoD5Init, + dim828JoeKuoD5Init, + dim829JoeKuoD5Init, + dim830JoeKuoD5Init, + dim831JoeKuoD5Init, + dim832JoeKuoD5Init, + dim833JoeKuoD5Init, + dim834JoeKuoD5Init, + dim835JoeKuoD5Init, + dim836JoeKuoD5Init, + dim837JoeKuoD5Init, + dim838JoeKuoD5Init, + dim839JoeKuoD5Init, + dim840JoeKuoD5Init, + dim841JoeKuoD5Init, + dim842JoeKuoD5Init, + dim843JoeKuoD5Init, + dim844JoeKuoD5Init, + dim845JoeKuoD5Init, + dim846JoeKuoD5Init, + dim847JoeKuoD5Init, + dim848JoeKuoD5Init, + dim849JoeKuoD5Init, + dim850JoeKuoD5Init, + dim851JoeKuoD5Init, + dim852JoeKuoD5Init, + dim853JoeKuoD5Init, + dim854JoeKuoD5Init, + dim855JoeKuoD5Init, + dim856JoeKuoD5Init, + dim857JoeKuoD5Init, + dim858JoeKuoD5Init, + dim859JoeKuoD5Init, + dim860JoeKuoD5Init, + dim861JoeKuoD5Init, + dim862JoeKuoD5Init, + dim863JoeKuoD5Init, + dim864JoeKuoD5Init, + dim865JoeKuoD5Init, + dim866JoeKuoD5Init, + dim867JoeKuoD5Init, + dim868JoeKuoD5Init, + dim869JoeKuoD5Init, + dim870JoeKuoD5Init, + dim871JoeKuoD5Init, + dim872JoeKuoD5Init, + dim873JoeKuoD5Init, + dim874JoeKuoD5Init, + dim875JoeKuoD5Init, + dim876JoeKuoD5Init, + dim877JoeKuoD5Init, + dim878JoeKuoD5Init, + dim879JoeKuoD5Init, + dim880JoeKuoD5Init, + dim881JoeKuoD5Init, + dim882JoeKuoD5Init, + dim883JoeKuoD5Init, + dim884JoeKuoD5Init, + dim885JoeKuoD5Init, + dim886JoeKuoD5Init, + dim887JoeKuoD5Init, + dim888JoeKuoD5Init, + dim889JoeKuoD5Init, + dim890JoeKuoD5Init, + dim891JoeKuoD5Init, + dim892JoeKuoD5Init, + dim893JoeKuoD5Init, + dim894JoeKuoD5Init, + dim895JoeKuoD5Init, + dim896JoeKuoD5Init, + dim897JoeKuoD5Init, + dim898JoeKuoD5Init, + dim899JoeKuoD5Init, + dim900JoeKuoD5Init, + dim901JoeKuoD5Init, + dim902JoeKuoD5Init, + dim903JoeKuoD5Init, + dim904JoeKuoD5Init, + dim905JoeKuoD5Init, + dim906JoeKuoD5Init, + dim907JoeKuoD5Init, + dim908JoeKuoD5Init, + dim909JoeKuoD5Init, + dim910JoeKuoD5Init, + dim911JoeKuoD5Init, + dim912JoeKuoD5Init, + dim913JoeKuoD5Init, + dim914JoeKuoD5Init, + dim915JoeKuoD5Init, + dim916JoeKuoD5Init, + dim917JoeKuoD5Init, + dim918JoeKuoD5Init, + dim919JoeKuoD5Init, + dim920JoeKuoD5Init, + dim921JoeKuoD5Init, + dim922JoeKuoD5Init, + dim923JoeKuoD5Init, + dim924JoeKuoD5Init, + dim925JoeKuoD5Init, + dim926JoeKuoD5Init, + dim927JoeKuoD5Init, + dim928JoeKuoD5Init, + dim929JoeKuoD5Init, + dim930JoeKuoD5Init, + dim931JoeKuoD5Init, + dim932JoeKuoD5Init, + dim933JoeKuoD5Init, + dim934JoeKuoD5Init, + dim935JoeKuoD5Init, + dim936JoeKuoD5Init, + dim937JoeKuoD5Init, + dim938JoeKuoD5Init, + dim939JoeKuoD5Init, + dim940JoeKuoD5Init, + dim941JoeKuoD5Init, + dim942JoeKuoD5Init, + dim943JoeKuoD5Init, + dim944JoeKuoD5Init, + dim945JoeKuoD5Init, + dim946JoeKuoD5Init, + dim947JoeKuoD5Init, + dim948JoeKuoD5Init, + dim949JoeKuoD5Init, + dim950JoeKuoD5Init, + dim951JoeKuoD5Init, + dim952JoeKuoD5Init, + dim953JoeKuoD5Init, + dim954JoeKuoD5Init, + dim955JoeKuoD5Init, + dim956JoeKuoD5Init, + dim957JoeKuoD5Init, + dim958JoeKuoD5Init, + dim959JoeKuoD5Init, + dim960JoeKuoD5Init, + dim961JoeKuoD5Init, + dim962JoeKuoD5Init, + dim963JoeKuoD5Init, + dim964JoeKuoD5Init, + dim965JoeKuoD5Init, + dim966JoeKuoD5Init, + dim967JoeKuoD5Init, + dim968JoeKuoD5Init, + dim969JoeKuoD5Init, + dim970JoeKuoD5Init, + dim971JoeKuoD5Init, + dim972JoeKuoD5Init, + dim973JoeKuoD5Init, + dim974JoeKuoD5Init, + dim975JoeKuoD5Init, + dim976JoeKuoD5Init, + dim977JoeKuoD5Init, + dim978JoeKuoD5Init, + dim979JoeKuoD5Init, + dim980JoeKuoD5Init, + dim981JoeKuoD5Init, + dim982JoeKuoD5Init, + dim983JoeKuoD5Init, + dim984JoeKuoD5Init, + dim985JoeKuoD5Init, + dim986JoeKuoD5Init, + dim987JoeKuoD5Init, + dim988JoeKuoD5Init, + dim989JoeKuoD5Init, + dim990JoeKuoD5Init, + dim991JoeKuoD5Init, + dim992JoeKuoD5Init, + dim993JoeKuoD5Init, + dim994JoeKuoD5Init, + dim995JoeKuoD5Init, + dim996JoeKuoD5Init, + dim997JoeKuoD5Init, + dim998JoeKuoD5Init, + dim999JoeKuoD5Init, + dim1000JoeKuoD5Init, + dim1001JoeKuoD5Init, + dim1002JoeKuoD5Init, + dim1003JoeKuoD5Init, + dim1004JoeKuoD5Init, + dim1005JoeKuoD5Init, + dim1006JoeKuoD5Init, + dim1007JoeKuoD5Init, + dim1008JoeKuoD5Init, + dim1009JoeKuoD5Init, + dim1010JoeKuoD5Init, + dim1011JoeKuoD5Init, + dim1012JoeKuoD5Init, + dim1013JoeKuoD5Init, + dim1014JoeKuoD5Init, + dim1015JoeKuoD5Init, + dim1016JoeKuoD5Init, + dim1017JoeKuoD5Init, + dim1018JoeKuoD5Init, + dim1019JoeKuoD5Init, + dim1020JoeKuoD5Init, + dim1021JoeKuoD5Init, + dim1022JoeKuoD5Init, + dim1023JoeKuoD5Init, + dim1024JoeKuoD5Init, + dim1025JoeKuoD5Init, + dim1026JoeKuoD5Init, + dim1027JoeKuoD5Init, + dim1028JoeKuoD5Init, + dim1029JoeKuoD5Init, + dim1030JoeKuoD5Init, + dim1031JoeKuoD5Init, + dim1032JoeKuoD5Init, + dim1033JoeKuoD5Init, + dim1034JoeKuoD5Init, + dim1035JoeKuoD5Init, + dim1036JoeKuoD5Init, + dim1037JoeKuoD5Init, + dim1038JoeKuoD5Init, + dim1039JoeKuoD5Init, + dim1040JoeKuoD5Init, + dim1041JoeKuoD5Init, + dim1042JoeKuoD5Init, + dim1043JoeKuoD5Init, + dim1044JoeKuoD5Init, + dim1045JoeKuoD5Init, + dim1046JoeKuoD5Init, + dim1047JoeKuoD5Init, + dim1048JoeKuoD5Init, + dim1049JoeKuoD5Init, + dim1050JoeKuoD5Init, + dim1051JoeKuoD5Init, + dim1052JoeKuoD5Init, + dim1053JoeKuoD5Init, + dim1054JoeKuoD5Init, + dim1055JoeKuoD5Init, + dim1056JoeKuoD5Init, + dim1057JoeKuoD5Init, + dim1058JoeKuoD5Init, + dim1059JoeKuoD5Init, + dim1060JoeKuoD5Init, + dim1061JoeKuoD5Init, + dim1062JoeKuoD5Init, + dim1063JoeKuoD5Init, + dim1064JoeKuoD5Init, + dim1065JoeKuoD5Init, + dim1066JoeKuoD5Init, + dim1067JoeKuoD5Init, + dim1068JoeKuoD5Init, + dim1069JoeKuoD5Init, + dim1070JoeKuoD5Init, + dim1071JoeKuoD5Init, + dim1072JoeKuoD5Init, + dim1073JoeKuoD5Init, + dim1074JoeKuoD5Init, + dim1075JoeKuoD5Init, + dim1076JoeKuoD5Init, + dim1077JoeKuoD5Init, + dim1078JoeKuoD5Init, + dim1079JoeKuoD5Init, + dim1080JoeKuoD5Init, + dim1081JoeKuoD5Init, + dim1082JoeKuoD5Init, + dim1083JoeKuoD5Init, + dim1084JoeKuoD5Init, + dim1085JoeKuoD5Init, + dim1086JoeKuoD5Init, + dim1087JoeKuoD5Init, + dim1088JoeKuoD5Init, + dim1089JoeKuoD5Init, + dim1090JoeKuoD5Init, + dim1091JoeKuoD5Init, + dim1092JoeKuoD5Init, + dim1093JoeKuoD5Init, + dim1094JoeKuoD5Init, + dim1095JoeKuoD5Init, + dim1096JoeKuoD5Init, + dim1097JoeKuoD5Init, + dim1098JoeKuoD5Init, + dim1099JoeKuoD5Init, + dim1100JoeKuoD5Init, + dim1101JoeKuoD5Init, + dim1102JoeKuoD5Init, + dim1103JoeKuoD5Init, + dim1104JoeKuoD5Init, + dim1105JoeKuoD5Init, + dim1106JoeKuoD5Init, + dim1107JoeKuoD5Init, + dim1108JoeKuoD5Init, + dim1109JoeKuoD5Init, + dim1110JoeKuoD5Init, + dim1111JoeKuoD5Init, + dim1112JoeKuoD5Init, + dim1113JoeKuoD5Init, + dim1114JoeKuoD5Init, + dim1115JoeKuoD5Init, + dim1116JoeKuoD5Init, + dim1117JoeKuoD5Init, + dim1118JoeKuoD5Init, + dim1119JoeKuoD5Init, + dim1120JoeKuoD5Init, + dim1121JoeKuoD5Init, + dim1122JoeKuoD5Init, + dim1123JoeKuoD5Init, + dim1124JoeKuoD5Init, + dim1125JoeKuoD5Init, + dim1126JoeKuoD5Init, + dim1127JoeKuoD5Init, + dim1128JoeKuoD5Init, + dim1129JoeKuoD5Init, + dim1130JoeKuoD5Init, + dim1131JoeKuoD5Init, + dim1132JoeKuoD5Init, + dim1133JoeKuoD5Init, + dim1134JoeKuoD5Init, + dim1135JoeKuoD5Init, + dim1136JoeKuoD5Init, + dim1137JoeKuoD5Init, + dim1138JoeKuoD5Init, + dim1139JoeKuoD5Init, + dim1140JoeKuoD5Init, + dim1141JoeKuoD5Init, + dim1142JoeKuoD5Init, + dim1143JoeKuoD5Init, + dim1144JoeKuoD5Init, + dim1145JoeKuoD5Init, + dim1146JoeKuoD5Init, + dim1147JoeKuoD5Init, + dim1148JoeKuoD5Init, + dim1149JoeKuoD5Init, + dim1150JoeKuoD5Init, + dim1151JoeKuoD5Init, + dim1152JoeKuoD5Init, + dim1153JoeKuoD5Init, + dim1154JoeKuoD5Init, + dim1155JoeKuoD5Init, + dim1156JoeKuoD5Init, + dim1157JoeKuoD5Init, + dim1158JoeKuoD5Init, + dim1159JoeKuoD5Init, + dim1160JoeKuoD5Init, + dim1161JoeKuoD5Init, + dim1162JoeKuoD5Init, + dim1163JoeKuoD5Init, + dim1164JoeKuoD5Init, + dim1165JoeKuoD5Init, + dim1166JoeKuoD5Init, + dim1167JoeKuoD5Init, + dim1168JoeKuoD5Init, + dim1169JoeKuoD5Init, + dim1170JoeKuoD5Init, + dim1171JoeKuoD5Init, + dim1172JoeKuoD5Init, + dim1173JoeKuoD5Init, + dim1174JoeKuoD5Init, + dim1175JoeKuoD5Init, + dim1176JoeKuoD5Init, + dim1177JoeKuoD5Init, + dim1178JoeKuoD5Init, + dim1179JoeKuoD5Init, + dim1180JoeKuoD5Init, + dim1181JoeKuoD5Init, + dim1182JoeKuoD5Init, + dim1183JoeKuoD5Init, + dim1184JoeKuoD5Init, + dim1185JoeKuoD5Init, + dim1186JoeKuoD5Init, + dim1187JoeKuoD5Init, + dim1188JoeKuoD5Init, + dim1189JoeKuoD5Init, + dim1190JoeKuoD5Init, + dim1191JoeKuoD5Init, + dim1192JoeKuoD5Init, + dim1193JoeKuoD5Init, + dim1194JoeKuoD5Init, + dim1195JoeKuoD5Init, + dim1196JoeKuoD5Init, + dim1197JoeKuoD5Init, + dim1198JoeKuoD5Init, + dim1199JoeKuoD5Init, + dim1200JoeKuoD5Init, + dim1201JoeKuoD5Init, + dim1202JoeKuoD5Init, + dim1203JoeKuoD5Init, + dim1204JoeKuoD5Init, + dim1205JoeKuoD5Init, + dim1206JoeKuoD5Init, + dim1207JoeKuoD5Init, + dim1208JoeKuoD5Init, + dim1209JoeKuoD5Init, + dim1210JoeKuoD5Init, + dim1211JoeKuoD5Init, + dim1212JoeKuoD5Init, + dim1213JoeKuoD5Init, + dim1214JoeKuoD5Init, + dim1215JoeKuoD5Init, + dim1216JoeKuoD5Init, + dim1217JoeKuoD5Init, + dim1218JoeKuoD5Init, + dim1219JoeKuoD5Init, + dim1220JoeKuoD5Init, + dim1221JoeKuoD5Init, + dim1222JoeKuoD5Init, + dim1223JoeKuoD5Init, + dim1224JoeKuoD5Init, + dim1225JoeKuoD5Init, + dim1226JoeKuoD5Init, + dim1227JoeKuoD5Init, + dim1228JoeKuoD5Init, + dim1229JoeKuoD5Init, + dim1230JoeKuoD5Init, + dim1231JoeKuoD5Init, + dim1232JoeKuoD5Init, + dim1233JoeKuoD5Init, + dim1234JoeKuoD5Init, + dim1235JoeKuoD5Init, + dim1236JoeKuoD5Init, + dim1237JoeKuoD5Init, + dim1238JoeKuoD5Init, + dim1239JoeKuoD5Init, + dim1240JoeKuoD5Init, + dim1241JoeKuoD5Init, + dim1242JoeKuoD5Init, + dim1243JoeKuoD5Init, + dim1244JoeKuoD5Init, + dim1245JoeKuoD5Init, + dim1246JoeKuoD5Init, + dim1247JoeKuoD5Init, + dim1248JoeKuoD5Init, + dim1249JoeKuoD5Init, + dim1250JoeKuoD5Init, + dim1251JoeKuoD5Init, + dim1252JoeKuoD5Init, + dim1253JoeKuoD5Init, + dim1254JoeKuoD5Init, + dim1255JoeKuoD5Init, + dim1256JoeKuoD5Init, + dim1257JoeKuoD5Init, + dim1258JoeKuoD5Init, + dim1259JoeKuoD5Init, + dim1260JoeKuoD5Init, + dim1261JoeKuoD5Init, + dim1262JoeKuoD5Init, + dim1263JoeKuoD5Init, + dim1264JoeKuoD5Init, + dim1265JoeKuoD5Init, + dim1266JoeKuoD5Init, + dim1267JoeKuoD5Init, + dim1268JoeKuoD5Init, + dim1269JoeKuoD5Init, + dim1270JoeKuoD5Init, + dim1271JoeKuoD5Init, + dim1272JoeKuoD5Init, + dim1273JoeKuoD5Init, + dim1274JoeKuoD5Init, + dim1275JoeKuoD5Init, + dim1276JoeKuoD5Init, + dim1277JoeKuoD5Init, + dim1278JoeKuoD5Init, + dim1279JoeKuoD5Init, + dim1280JoeKuoD5Init, + dim1281JoeKuoD5Init, + dim1282JoeKuoD5Init, + dim1283JoeKuoD5Init, + dim1284JoeKuoD5Init, + dim1285JoeKuoD5Init, + dim1286JoeKuoD5Init, + dim1287JoeKuoD5Init, + dim1288JoeKuoD5Init, + dim1289JoeKuoD5Init, + dim1290JoeKuoD5Init, + dim1291JoeKuoD5Init, + dim1292JoeKuoD5Init, + dim1293JoeKuoD5Init, + dim1294JoeKuoD5Init, + dim1295JoeKuoD5Init, + dim1296JoeKuoD5Init, + dim1297JoeKuoD5Init, + dim1298JoeKuoD5Init, + dim1299JoeKuoD5Init, + dim1300JoeKuoD5Init, + dim1301JoeKuoD5Init, + dim1302JoeKuoD5Init, + dim1303JoeKuoD5Init, + dim1304JoeKuoD5Init, + dim1305JoeKuoD5Init, + dim1306JoeKuoD5Init, + dim1307JoeKuoD5Init, + dim1308JoeKuoD5Init, + dim1309JoeKuoD5Init, + dim1310JoeKuoD5Init, + dim1311JoeKuoD5Init, + dim1312JoeKuoD5Init, + dim1313JoeKuoD5Init, + dim1314JoeKuoD5Init, + dim1315JoeKuoD5Init, + dim1316JoeKuoD5Init, + dim1317JoeKuoD5Init, + dim1318JoeKuoD5Init, + dim1319JoeKuoD5Init, + dim1320JoeKuoD5Init, + dim1321JoeKuoD5Init, + dim1322JoeKuoD5Init, + dim1323JoeKuoD5Init, + dim1324JoeKuoD5Init, + dim1325JoeKuoD5Init, + dim1326JoeKuoD5Init, + dim1327JoeKuoD5Init, + dim1328JoeKuoD5Init, + dim1329JoeKuoD5Init, + dim1330JoeKuoD5Init, + dim1331JoeKuoD5Init, + dim1332JoeKuoD5Init, + dim1333JoeKuoD5Init, + dim1334JoeKuoD5Init, + dim1335JoeKuoD5Init, + dim1336JoeKuoD5Init, + dim1337JoeKuoD5Init, + dim1338JoeKuoD5Init, + dim1339JoeKuoD5Init, + dim1340JoeKuoD5Init, + dim1341JoeKuoD5Init, + dim1342JoeKuoD5Init, + dim1343JoeKuoD5Init, + dim1344JoeKuoD5Init, + dim1345JoeKuoD5Init, + dim1346JoeKuoD5Init, + dim1347JoeKuoD5Init, + dim1348JoeKuoD5Init, + dim1349JoeKuoD5Init, + dim1350JoeKuoD5Init, + dim1351JoeKuoD5Init, + dim1352JoeKuoD5Init, + dim1353JoeKuoD5Init, + dim1354JoeKuoD5Init, + dim1355JoeKuoD5Init, + dim1356JoeKuoD5Init, + dim1357JoeKuoD5Init, + dim1358JoeKuoD5Init, + dim1359JoeKuoD5Init, + dim1360JoeKuoD5Init, + dim1361JoeKuoD5Init, + dim1362JoeKuoD5Init, + dim1363JoeKuoD5Init, + dim1364JoeKuoD5Init, + dim1365JoeKuoD5Init, + dim1366JoeKuoD5Init, + dim1367JoeKuoD5Init, + dim1368JoeKuoD5Init, + dim1369JoeKuoD5Init, + dim1370JoeKuoD5Init, + dim1371JoeKuoD5Init, + dim1372JoeKuoD5Init, + dim1373JoeKuoD5Init, + dim1374JoeKuoD5Init, + dim1375JoeKuoD5Init, + dim1376JoeKuoD5Init, + dim1377JoeKuoD5Init, + dim1378JoeKuoD5Init, + dim1379JoeKuoD5Init, + dim1380JoeKuoD5Init, + dim1381JoeKuoD5Init, + dim1382JoeKuoD5Init, + dim1383JoeKuoD5Init, + dim1384JoeKuoD5Init, + dim1385JoeKuoD5Init, + dim1386JoeKuoD5Init, + dim1387JoeKuoD5Init, + dim1388JoeKuoD5Init, + dim1389JoeKuoD5Init, + dim1390JoeKuoD5Init, + dim1391JoeKuoD5Init, + dim1392JoeKuoD5Init, + dim1393JoeKuoD5Init, + dim1394JoeKuoD5Init, + dim1395JoeKuoD5Init, + dim1396JoeKuoD5Init, + dim1397JoeKuoD5Init, + dim1398JoeKuoD5Init, + dim1399JoeKuoD5Init, + dim1400JoeKuoD5Init, + dim1401JoeKuoD5Init, + dim1402JoeKuoD5Init, + dim1403JoeKuoD5Init, + dim1404JoeKuoD5Init, + dim1405JoeKuoD5Init, + dim1406JoeKuoD5Init, + dim1407JoeKuoD5Init, + dim1408JoeKuoD5Init, + dim1409JoeKuoD5Init, + dim1410JoeKuoD5Init, + dim1411JoeKuoD5Init, + dim1412JoeKuoD5Init, + dim1413JoeKuoD5Init, + dim1414JoeKuoD5Init, + dim1415JoeKuoD5Init, + dim1416JoeKuoD5Init, + dim1417JoeKuoD5Init, + dim1418JoeKuoD5Init, + dim1419JoeKuoD5Init, + dim1420JoeKuoD5Init, + dim1421JoeKuoD5Init, + dim1422JoeKuoD5Init, + dim1423JoeKuoD5Init, + dim1424JoeKuoD5Init, + dim1425JoeKuoD5Init, + dim1426JoeKuoD5Init, + dim1427JoeKuoD5Init, + dim1428JoeKuoD5Init, + dim1429JoeKuoD5Init, + dim1430JoeKuoD5Init, + dim1431JoeKuoD5Init, + dim1432JoeKuoD5Init, + dim1433JoeKuoD5Init, + dim1434JoeKuoD5Init, + dim1435JoeKuoD5Init, + dim1436JoeKuoD5Init, + dim1437JoeKuoD5Init, + dim1438JoeKuoD5Init, + dim1439JoeKuoD5Init, + dim1440JoeKuoD5Init, + dim1441JoeKuoD5Init, + dim1442JoeKuoD5Init, + dim1443JoeKuoD5Init, + dim1444JoeKuoD5Init, + dim1445JoeKuoD5Init, + dim1446JoeKuoD5Init, + dim1447JoeKuoD5Init, + dim1448JoeKuoD5Init, + dim1449JoeKuoD5Init, + dim1450JoeKuoD5Init, + dim1451JoeKuoD5Init, + dim1452JoeKuoD5Init, + dim1453JoeKuoD5Init, + dim1454JoeKuoD5Init, + dim1455JoeKuoD5Init, + dim1456JoeKuoD5Init, + dim1457JoeKuoD5Init, + dim1458JoeKuoD5Init, + dim1459JoeKuoD5Init, + dim1460JoeKuoD5Init, + dim1461JoeKuoD5Init, + dim1462JoeKuoD5Init, + dim1463JoeKuoD5Init, + dim1464JoeKuoD5Init, + dim1465JoeKuoD5Init, + dim1466JoeKuoD5Init, + dim1467JoeKuoD5Init, + dim1468JoeKuoD5Init, + dim1469JoeKuoD5Init, + dim1470JoeKuoD5Init, + dim1471JoeKuoD5Init, + dim1472JoeKuoD5Init, + dim1473JoeKuoD5Init, + dim1474JoeKuoD5Init, + dim1475JoeKuoD5Init, + dim1476JoeKuoD5Init, + dim1477JoeKuoD5Init, + dim1478JoeKuoD5Init, + dim1479JoeKuoD5Init, + dim1480JoeKuoD5Init, + dim1481JoeKuoD5Init, + dim1482JoeKuoD5Init, + dim1483JoeKuoD5Init, + dim1484JoeKuoD5Init, + dim1485JoeKuoD5Init, + dim1486JoeKuoD5Init, + dim1487JoeKuoD5Init, + dim1488JoeKuoD5Init, + dim1489JoeKuoD5Init, + dim1490JoeKuoD5Init, + dim1491JoeKuoD5Init, + dim1492JoeKuoD5Init, + dim1493JoeKuoD5Init, + dim1494JoeKuoD5Init, + dim1495JoeKuoD5Init, + dim1496JoeKuoD5Init, + dim1497JoeKuoD5Init, + dim1498JoeKuoD5Init, + dim1499JoeKuoD5Init, + dim1500JoeKuoD5Init, + dim1501JoeKuoD5Init, + dim1502JoeKuoD5Init, + dim1503JoeKuoD5Init, + dim1504JoeKuoD5Init, + dim1505JoeKuoD5Init, + dim1506JoeKuoD5Init, + dim1507JoeKuoD5Init, + dim1508JoeKuoD5Init, + dim1509JoeKuoD5Init, + dim1510JoeKuoD5Init, + dim1511JoeKuoD5Init, + dim1512JoeKuoD5Init, + dim1513JoeKuoD5Init, + dim1514JoeKuoD5Init, + dim1515JoeKuoD5Init, + dim1516JoeKuoD5Init, + dim1517JoeKuoD5Init, + dim1518JoeKuoD5Init, + dim1519JoeKuoD5Init, + dim1520JoeKuoD5Init, + dim1521JoeKuoD5Init, + dim1522JoeKuoD5Init, + dim1523JoeKuoD5Init, + dim1524JoeKuoD5Init, + dim1525JoeKuoD5Init, + dim1526JoeKuoD5Init, + dim1527JoeKuoD5Init, + dim1528JoeKuoD5Init, + dim1529JoeKuoD5Init, + dim1530JoeKuoD5Init, + dim1531JoeKuoD5Init, + dim1532JoeKuoD5Init, + dim1533JoeKuoD5Init, + dim1534JoeKuoD5Init, + dim1535JoeKuoD5Init, + dim1536JoeKuoD5Init, + dim1537JoeKuoD5Init, + dim1538JoeKuoD5Init, + dim1539JoeKuoD5Init, + dim1540JoeKuoD5Init, + dim1541JoeKuoD5Init, + dim1542JoeKuoD5Init, + dim1543JoeKuoD5Init, + dim1544JoeKuoD5Init, + dim1545JoeKuoD5Init, + dim1546JoeKuoD5Init, + dim1547JoeKuoD5Init, + dim1548JoeKuoD5Init, + dim1549JoeKuoD5Init, + dim1550JoeKuoD5Init, + dim1551JoeKuoD5Init, + dim1552JoeKuoD5Init, + dim1553JoeKuoD5Init, + dim1554JoeKuoD5Init, + dim1555JoeKuoD5Init, + dim1556JoeKuoD5Init, + dim1557JoeKuoD5Init, + dim1558JoeKuoD5Init, + dim1559JoeKuoD5Init, + dim1560JoeKuoD5Init, + dim1561JoeKuoD5Init, + dim1562JoeKuoD5Init, + dim1563JoeKuoD5Init, + dim1564JoeKuoD5Init, + dim1565JoeKuoD5Init, + dim1566JoeKuoD5Init, + dim1567JoeKuoD5Init, + dim1568JoeKuoD5Init, + dim1569JoeKuoD5Init, + dim1570JoeKuoD5Init, + dim1571JoeKuoD5Init, + dim1572JoeKuoD5Init, + dim1573JoeKuoD5Init, + dim1574JoeKuoD5Init, + dim1575JoeKuoD5Init, + dim1576JoeKuoD5Init, + dim1577JoeKuoD5Init, + dim1578JoeKuoD5Init, + dim1579JoeKuoD5Init, + dim1580JoeKuoD5Init, + dim1581JoeKuoD5Init, + dim1582JoeKuoD5Init, + dim1583JoeKuoD5Init, + dim1584JoeKuoD5Init, + dim1585JoeKuoD5Init, + dim1586JoeKuoD5Init, + dim1587JoeKuoD5Init, + dim1588JoeKuoD5Init, + dim1589JoeKuoD5Init, + dim1590JoeKuoD5Init, + dim1591JoeKuoD5Init, + dim1592JoeKuoD5Init, + dim1593JoeKuoD5Init, + dim1594JoeKuoD5Init, + dim1595JoeKuoD5Init, + dim1596JoeKuoD5Init, + dim1597JoeKuoD5Init, + dim1598JoeKuoD5Init, + dim1599JoeKuoD5Init, + dim1600JoeKuoD5Init, + dim1601JoeKuoD5Init, + dim1602JoeKuoD5Init, + dim1603JoeKuoD5Init, + dim1604JoeKuoD5Init, + dim1605JoeKuoD5Init, + dim1606JoeKuoD5Init, + dim1607JoeKuoD5Init, + dim1608JoeKuoD5Init, + dim1609JoeKuoD5Init, + dim1610JoeKuoD5Init, + dim1611JoeKuoD5Init, + dim1612JoeKuoD5Init, + dim1613JoeKuoD5Init, + dim1614JoeKuoD5Init, + dim1615JoeKuoD5Init, + dim1616JoeKuoD5Init, + dim1617JoeKuoD5Init, + dim1618JoeKuoD5Init, + dim1619JoeKuoD5Init, + dim1620JoeKuoD5Init, + dim1621JoeKuoD5Init, + dim1622JoeKuoD5Init, + dim1623JoeKuoD5Init, + dim1624JoeKuoD5Init, + dim1625JoeKuoD5Init, + dim1626JoeKuoD5Init, + dim1627JoeKuoD5Init, + dim1628JoeKuoD5Init, + dim1629JoeKuoD5Init, + dim1630JoeKuoD5Init, + dim1631JoeKuoD5Init, + dim1632JoeKuoD5Init, + dim1633JoeKuoD5Init, + dim1634JoeKuoD5Init, + dim1635JoeKuoD5Init, + dim1636JoeKuoD5Init, + dim1637JoeKuoD5Init, + dim1638JoeKuoD5Init, + dim1639JoeKuoD5Init, + dim1640JoeKuoD5Init, + dim1641JoeKuoD5Init, + dim1642JoeKuoD5Init, + dim1643JoeKuoD5Init, + dim1644JoeKuoD5Init, + dim1645JoeKuoD5Init, + dim1646JoeKuoD5Init, + dim1647JoeKuoD5Init, + dim1648JoeKuoD5Init, + dim1649JoeKuoD5Init, + dim1650JoeKuoD5Init, + dim1651JoeKuoD5Init, + dim1652JoeKuoD5Init, + dim1653JoeKuoD5Init, + dim1654JoeKuoD5Init, + dim1655JoeKuoD5Init, + dim1656JoeKuoD5Init, + dim1657JoeKuoD5Init, + dim1658JoeKuoD5Init, + dim1659JoeKuoD5Init, + dim1660JoeKuoD5Init, + dim1661JoeKuoD5Init, + dim1662JoeKuoD5Init, + dim1663JoeKuoD5Init, + dim1664JoeKuoD5Init, + dim1665JoeKuoD5Init, + dim1666JoeKuoD5Init, + dim1667JoeKuoD5Init, + dim1668JoeKuoD5Init, + dim1669JoeKuoD5Init, + dim1670JoeKuoD5Init, + dim1671JoeKuoD5Init, + dim1672JoeKuoD5Init, + dim1673JoeKuoD5Init, + dim1674JoeKuoD5Init, + dim1675JoeKuoD5Init, + dim1676JoeKuoD5Init, + dim1677JoeKuoD5Init, + dim1678JoeKuoD5Init, + dim1679JoeKuoD5Init, + dim1680JoeKuoD5Init, + dim1681JoeKuoD5Init, + dim1682JoeKuoD5Init, + dim1683JoeKuoD5Init, + dim1684JoeKuoD5Init, + dim1685JoeKuoD5Init, + dim1686JoeKuoD5Init, + dim1687JoeKuoD5Init, + dim1688JoeKuoD5Init, + dim1689JoeKuoD5Init, + dim1690JoeKuoD5Init, + dim1691JoeKuoD5Init, + dim1692JoeKuoD5Init, + dim1693JoeKuoD5Init, + dim1694JoeKuoD5Init, + dim1695JoeKuoD5Init, + dim1696JoeKuoD5Init, + dim1697JoeKuoD5Init, + dim1698JoeKuoD5Init, + dim1699JoeKuoD5Init, + dim1700JoeKuoD5Init, + dim1701JoeKuoD5Init, + dim1702JoeKuoD5Init, + dim1703JoeKuoD5Init, + dim1704JoeKuoD5Init, + dim1705JoeKuoD5Init, + dim1706JoeKuoD5Init, + dim1707JoeKuoD5Init, + dim1708JoeKuoD5Init, + dim1709JoeKuoD5Init, + dim1710JoeKuoD5Init, + dim1711JoeKuoD5Init, + dim1712JoeKuoD5Init, + dim1713JoeKuoD5Init, + dim1714JoeKuoD5Init, + dim1715JoeKuoD5Init, + dim1716JoeKuoD5Init, + dim1717JoeKuoD5Init, + dim1718JoeKuoD5Init, + dim1719JoeKuoD5Init, + dim1720JoeKuoD5Init, + dim1721JoeKuoD5Init, + dim1722JoeKuoD5Init, + dim1723JoeKuoD5Init, + dim1724JoeKuoD5Init, + dim1725JoeKuoD5Init, + dim1726JoeKuoD5Init, + dim1727JoeKuoD5Init, + dim1728JoeKuoD5Init, + dim1729JoeKuoD5Init, + dim1730JoeKuoD5Init, + dim1731JoeKuoD5Init, + dim1732JoeKuoD5Init, + dim1733JoeKuoD5Init, + dim1734JoeKuoD5Init, + dim1735JoeKuoD5Init, + dim1736JoeKuoD5Init, + dim1737JoeKuoD5Init, + dim1738JoeKuoD5Init, + dim1739JoeKuoD5Init, + dim1740JoeKuoD5Init, + dim1741JoeKuoD5Init, + dim1742JoeKuoD5Init, + dim1743JoeKuoD5Init, + dim1744JoeKuoD5Init, + dim1745JoeKuoD5Init, + dim1746JoeKuoD5Init, + dim1747JoeKuoD5Init, + dim1748JoeKuoD5Init, + dim1749JoeKuoD5Init, + dim1750JoeKuoD5Init, + dim1751JoeKuoD5Init, + dim1752JoeKuoD5Init, + dim1753JoeKuoD5Init, + dim1754JoeKuoD5Init, + dim1755JoeKuoD5Init, + dim1756JoeKuoD5Init, + dim1757JoeKuoD5Init, + dim1758JoeKuoD5Init, + dim1759JoeKuoD5Init, + dim1760JoeKuoD5Init, + dim1761JoeKuoD5Init, + dim1762JoeKuoD5Init, + dim1763JoeKuoD5Init, + dim1764JoeKuoD5Init, + dim1765JoeKuoD5Init, + dim1766JoeKuoD5Init, + dim1767JoeKuoD5Init, + dim1768JoeKuoD5Init, + dim1769JoeKuoD5Init, + dim1770JoeKuoD5Init, + dim1771JoeKuoD5Init, + dim1772JoeKuoD5Init, + dim1773JoeKuoD5Init, + dim1774JoeKuoD5Init, + dim1775JoeKuoD5Init, + dim1776JoeKuoD5Init, + dim1777JoeKuoD5Init, + dim1778JoeKuoD5Init, + dim1779JoeKuoD5Init, + dim1780JoeKuoD5Init, + dim1781JoeKuoD5Init, + dim1782JoeKuoD5Init, + dim1783JoeKuoD5Init, + dim1784JoeKuoD5Init, + dim1785JoeKuoD5Init, + dim1786JoeKuoD5Init, + dim1787JoeKuoD5Init, + dim1788JoeKuoD5Init, + dim1789JoeKuoD5Init, + dim1790JoeKuoD5Init, + dim1791JoeKuoD5Init, + dim1792JoeKuoD5Init, + dim1793JoeKuoD5Init, + dim1794JoeKuoD5Init, + dim1795JoeKuoD5Init, + dim1796JoeKuoD5Init, + dim1797JoeKuoD5Init, + dim1798JoeKuoD5Init, + dim1799JoeKuoD5Init, + dim1800JoeKuoD5Init, + dim1801JoeKuoD5Init, + dim1802JoeKuoD5Init, + dim1803JoeKuoD5Init, + dim1804JoeKuoD5Init, + dim1805JoeKuoD5Init, + dim1806JoeKuoD5Init, + dim1807JoeKuoD5Init, + dim1808JoeKuoD5Init, + dim1809JoeKuoD5Init, + dim1810JoeKuoD5Init, + dim1811JoeKuoD5Init, + dim1812JoeKuoD5Init, + dim1813JoeKuoD5Init, + dim1814JoeKuoD5Init, + dim1815JoeKuoD5Init, + dim1816JoeKuoD5Init, + dim1817JoeKuoD5Init, + dim1818JoeKuoD5Init, + dim1819JoeKuoD5Init, + dim1820JoeKuoD5Init, + dim1821JoeKuoD5Init, + dim1822JoeKuoD5Init, + dim1823JoeKuoD5Init, + dim1824JoeKuoD5Init, + dim1825JoeKuoD5Init, + dim1826JoeKuoD5Init, + dim1827JoeKuoD5Init, + dim1828JoeKuoD5Init, + dim1829JoeKuoD5Init, + dim1830JoeKuoD5Init, + dim1831JoeKuoD5Init, + dim1832JoeKuoD5Init, + dim1833JoeKuoD5Init, + dim1834JoeKuoD5Init, + dim1835JoeKuoD5Init, + dim1836JoeKuoD5Init, + dim1837JoeKuoD5Init, + dim1838JoeKuoD5Init, + dim1839JoeKuoD5Init, + dim1840JoeKuoD5Init, + dim1841JoeKuoD5Init, + dim1842JoeKuoD5Init, + dim1843JoeKuoD5Init, + dim1844JoeKuoD5Init, + dim1845JoeKuoD5Init, + dim1846JoeKuoD5Init, + dim1847JoeKuoD5Init, + dim1848JoeKuoD5Init, + dim1849JoeKuoD5Init, + dim1850JoeKuoD5Init, + dim1851JoeKuoD5Init, + dim1852JoeKuoD5Init, + dim1853JoeKuoD5Init, + dim1854JoeKuoD5Init, + dim1855JoeKuoD5Init, + dim1856JoeKuoD5Init, + dim1857JoeKuoD5Init, + dim1858JoeKuoD5Init, + dim1859JoeKuoD5Init, + dim1860JoeKuoD5Init, + dim1861JoeKuoD5Init, + dim1862JoeKuoD5Init, + dim1863JoeKuoD5Init, + dim1864JoeKuoD5Init, + dim1865JoeKuoD5Init, + dim1866JoeKuoD5Init, + dim1867JoeKuoD5Init, + dim1868JoeKuoD5Init, + dim1869JoeKuoD5Init, + dim1870JoeKuoD5Init, + dim1871JoeKuoD5Init, + dim1872JoeKuoD5Init, + dim1873JoeKuoD5Init, + dim1874JoeKuoD5Init, + dim1875JoeKuoD5Init, + dim1876JoeKuoD5Init, + dim1877JoeKuoD5Init, + dim1878JoeKuoD5Init, + dim1879JoeKuoD5Init, + dim1880JoeKuoD5Init, + dim1881JoeKuoD5Init, + dim1882JoeKuoD5Init, + dim1883JoeKuoD5Init, + dim1884JoeKuoD5Init, + dim1885JoeKuoD5Init, + dim1886JoeKuoD5Init, + dim1887JoeKuoD5Init, + dim1888JoeKuoD5Init, + dim1889JoeKuoD5Init, + dim1890JoeKuoD5Init, + dim1891JoeKuoD5Init, + dim1892JoeKuoD5Init, + dim1893JoeKuoD5Init, + dim1894JoeKuoD5Init, + dim1895JoeKuoD5Init, + dim1896JoeKuoD5Init, + dim1897JoeKuoD5Init, + dim1898JoeKuoD5Init, + dim1899JoeKuoD5Init, + dim1900JoeKuoD5Init, + dim1901JoeKuoD5Init, + dim1902JoeKuoD5Init, + dim1903JoeKuoD5Init, + dim1904JoeKuoD5Init, + dim1905JoeKuoD5Init, + dim1906JoeKuoD5Init, + dim1907JoeKuoD5Init, + dim1908JoeKuoD5Init, + dim1909JoeKuoD5Init, + dim1910JoeKuoD5Init, + dim1911JoeKuoD5Init, + dim1912JoeKuoD5Init, + dim1913JoeKuoD5Init, + dim1914JoeKuoD5Init, + dim1915JoeKuoD5Init, + dim1916JoeKuoD5Init, + dim1917JoeKuoD5Init, + dim1918JoeKuoD5Init, + dim1919JoeKuoD5Init, + dim1920JoeKuoD5Init, + dim1921JoeKuoD5Init, + dim1922JoeKuoD5Init, + dim1923JoeKuoD5Init, + dim1924JoeKuoD5Init, + dim1925JoeKuoD5Init, + dim1926JoeKuoD5Init, + dim1927JoeKuoD5Init, + dim1928JoeKuoD5Init, + dim1929JoeKuoD5Init, + dim1930JoeKuoD5Init, + dim1931JoeKuoD5Init, + dim1932JoeKuoD5Init, + dim1933JoeKuoD5Init, + dim1934JoeKuoD5Init, + dim1935JoeKuoD5Init, + dim1936JoeKuoD5Init, + dim1937JoeKuoD5Init, + dim1938JoeKuoD5Init, + dim1939JoeKuoD5Init, + dim1940JoeKuoD5Init, + dim1941JoeKuoD5Init, + dim1942JoeKuoD5Init, + dim1943JoeKuoD5Init, + dim1944JoeKuoD5Init, + dim1945JoeKuoD5Init, + dim1946JoeKuoD5Init, + dim1947JoeKuoD5Init, + dim1948JoeKuoD5Init, + dim1949JoeKuoD5Init, + dim1950JoeKuoD5Init, + dim1951JoeKuoD5Init, + dim1952JoeKuoD5Init, + dim1953JoeKuoD5Init, + dim1954JoeKuoD5Init, + dim1955JoeKuoD5Init, + dim1956JoeKuoD5Init, + dim1957JoeKuoD5Init, + dim1958JoeKuoD5Init, + dim1959JoeKuoD5Init, + dim1960JoeKuoD5Init, + dim1961JoeKuoD5Init, + dim1962JoeKuoD5Init, + dim1963JoeKuoD5Init, + dim1964JoeKuoD5Init, + dim1965JoeKuoD5Init, + dim1966JoeKuoD5Init, + dim1967JoeKuoD5Init, + dim1968JoeKuoD5Init, + dim1969JoeKuoD5Init, + dim1970JoeKuoD5Init, + dim1971JoeKuoD5Init, + dim1972JoeKuoD5Init, + dim1973JoeKuoD5Init, + dim1974JoeKuoD5Init, + dim1975JoeKuoD5Init, + dim1976JoeKuoD5Init, + dim1977JoeKuoD5Init, + dim1978JoeKuoD5Init, + dim1979JoeKuoD5Init, + dim1980JoeKuoD5Init, + dim1981JoeKuoD5Init, + dim1982JoeKuoD5Init, + dim1983JoeKuoD5Init, + dim1984JoeKuoD5Init, + dim1985JoeKuoD5Init, + dim1986JoeKuoD5Init, + dim1987JoeKuoD5Init, + dim1988JoeKuoD5Init, + dim1989JoeKuoD5Init, + dim1990JoeKuoD5Init, + dim1991JoeKuoD5Init, + dim1992JoeKuoD5Init, + dim1993JoeKuoD5Init, + dim1994JoeKuoD5Init, + dim1995JoeKuoD5Init, + dim1996JoeKuoD5Init, + dim1997JoeKuoD5Init, + dim1998JoeKuoD5Init, + dim1999JoeKuoD5Init + }; + + static ulong[] dim1Kuo2Init = { 1, 0 }; + static ulong[] dim2Kuo2Init = { 1, 1, 0 }; + static ulong[] dim3Kuo2Init = { 1, 1, 1, 0 }; + static ulong[] dim4Kuo2Init = { 1, 3, 1, 0 }; + static ulong[] dim5Kuo2Init = { 1, 3, 7, 1, 0 }; + static ulong[] dim6Kuo2Init = { 1, 1, 3, 7, 0 }; + static ulong[] dim7Kuo2Init = { 1, 3, 1, 7, 23, 0 }; + static ulong[] dim8Kuo2Init = { 1, 1, 5, 1, 27, 0 }; + static ulong[] dim9Kuo2Init = { 1, 3, 5, 3, 25, 0 }; + static ulong[] dim10Kuo2Init = { 1, 1, 5, 9, 21, 0 }; + static ulong[] dim11Kuo2Init = { 1, 1, 3, 13, 27, 0 }; + static ulong[] dim12Kuo2Init = { 1, 3, 7, 11, 3, 0 }; + static ulong[] dim13Kuo2Init = { 1, 3, 1, 13, 31, 47, 0 }; + static ulong[] dim14Kuo2Init = { 1, 3, 3, 5, 13, 17, 0 }; + static ulong[] dim15Kuo2Init = { 1, 1, 7, 3, 13, 51, 0 }; + static ulong[] dim16Kuo2Init = { 1, 3, 3, 11, 7, 63, 0 }; + static ulong[] dim17Kuo2Init = { 1, 1, 1, 7, 3, 53, 0 }; + static ulong[] dim18Kuo2Init = { 1, 3, 5, 11, 3, 43, 0 }; + static ulong[] dim19Kuo2Init = { 1, 1, 7, 5, 19, 59, 59, 0 }; + static ulong[] dim20Kuo2Init = { 1, 1, 7, 9, 15, 25, 63, 0 }; + static ulong[] dim21Kuo2Init = { 1, 3, 7, 7, 27, 5, 17, 0 }; + static ulong[] dim22Kuo2Init = { 1, 3, 1, 5, 7, 51, 69, 0 }; + static ulong[] dim23Kuo2Init = { 1, 3, 3, 11, 23, 5, 35, 0 }; + static ulong[] dim24Kuo2Init = { 1, 1, 5, 1, 3, 17, 59, 0 }; + static ulong[] dim25Kuo2Init = { 1, 3, 7, 7, 3, 51, 57, 0 }; + static ulong[] dim26Kuo2Init = { 1, 3, 7, 11, 17, 1, 17, 0 }; + static ulong[] dim27Kuo2Init = { 1, 1, 1, 11, 25, 45, 3, 0 }; + static ulong[] dim28Kuo2Init = { 1, 1, 5, 15, 23, 53, 79, 0 }; + static ulong[] dim29Kuo2Init = { 1, 3, 3, 3, 19, 31, 39, 0 }; + static ulong[] dim30Kuo2Init = { 1, 1, 1, 9, 9, 21, 23, 0 }; + static ulong[] dim31Kuo2Init = { 1, 1, 3, 5, 31, 13, 97, 0 }; + static ulong[] dim32Kuo2Init = { 1, 1, 1, 15, 9, 39, 3, 0 }; + static ulong[] dim33Kuo2Init = { 1, 3, 1, 1, 27, 55, 37, 0 }; + static ulong[] dim34Kuo2Init = { 1, 3, 7, 11, 21, 49, 17, 0 }; + static ulong[] dim35Kuo2Init = { 1, 3, 3, 9, 31, 37, 95, 0 }; + static ulong[] dim36Kuo2Init = { 1, 1, 1, 1, 7, 35, 95, 0 }; + static ulong[] dim37Kuo2Init = { 1, 1, 5, 15, 15, 61, 11, 211, 0 }; + static ulong[] dim38Kuo2Init = { 1, 1, 7, 7, 29, 33, 127, 171, 0 }; + static ulong[] dim39Kuo2Init = { 1, 3, 5, 9, 17, 27, 85, 95, 0 }; + static ulong[] dim40Kuo2Init = { 1, 3, 7, 1, 25, 43, 35, 21, 0 }; + static ulong[] dim41Kuo2Init = { 1, 3, 5, 15, 9, 17, 43, 253, 0 }; + static ulong[] dim42Kuo2Init = { 1, 1, 5, 11, 27, 45, 37, 147, 0 }; + static ulong[] dim43Kuo2Init = { 1, 1, 7, 5, 7, 35, 29, 191, 0 }; + static ulong[] dim44Kuo2Init = { 1, 3, 1, 1, 15, 33, 21, 125, 0 }; + static ulong[] dim45Kuo2Init = { 1, 1, 1, 7, 31, 41, 33, 11, 0 }; + static ulong[] dim46Kuo2Init = { 1, 1, 7, 7, 27, 9, 111, 209, 0 }; + static ulong[] dim47Kuo2Init = { 1, 3, 7, 15, 1, 57, 63, 43, 0 }; + static ulong[] dim48Kuo2Init = { 1, 3, 3, 13, 1, 51, 5, 51, 0 }; + static ulong[] dim49Kuo2Init = { 1, 3, 5, 3, 27, 17, 103, 247, 0 }; + static ulong[] dim50Kuo2Init = { 1, 3, 7, 7, 11, 27, 51, 103, 0 }; + static ulong[] dim51Kuo2Init = { 1, 3, 3, 1, 23, 21, 65, 135, 0 }; + static ulong[] dim52Kuo2Init = { 1, 1, 7, 9, 1, 7, 71, 251, 0 }; + static ulong[] dim53Kuo2Init = { 1, 3, 1, 5, 11, 31, 43, 129, 225, 0 }; + static ulong[] dim54Kuo2Init = { 1, 1, 1, 5, 15, 15, 127, 225, 439, 0 }; + static ulong[] dim55Kuo2Init = { 1, 1, 3, 13, 27, 45, 103, 65, 313, 0 }; + static ulong[] dim56Kuo2Init = { 1, 3, 3, 15, 13, 31, 27, 231, 183, 0 }; + static ulong[] dim57Kuo2Init = { 1, 1, 3, 7, 23, 5, 15, 75, 159, 0 }; + static ulong[] dim58Kuo2Init = { 1, 1, 5, 15, 21, 3, 99, 23, 465, 0 }; + static ulong[] dim59Kuo2Init = { 1, 3, 7, 5, 23, 47, 119, 103, 271, 0 }; + static ulong[] dim60Kuo2Init = { 1, 3, 1, 11, 25, 13, 83, 5, 21, 0 }; + static ulong[] dim61Kuo2Init = { 1, 3, 5, 3, 7, 41, 123, 87, 243, 0 }; + static ulong[] dim62Kuo2Init = { 1, 1, 3, 11, 3, 7, 91, 227, 349, 0 }; + static ulong[] dim63Kuo2Init = { 1, 1, 1, 9, 29, 23, 31, 175, 145, 0 }; + static ulong[] dim64Kuo2Init = { 1, 1, 7, 7, 13, 25, 67, 59, 109, 0 }; + static ulong[] dim65Kuo2Init = { 1, 3, 7, 11, 25, 49, 23, 55, 135, 0 }; + static ulong[] dim66Kuo2Init = { 1, 3, 5, 7, 27, 61, 5, 193, 375, 0 }; + static ulong[] dim67Kuo2Init = { 1, 1, 5, 9, 23, 27, 41, 239, 383, 0 }; + static ulong[] dim68Kuo2Init = { 1, 1, 3, 15, 3, 43, 81, 77, 91, 0 }; + static ulong[] dim69Kuo2Init = { 1, 1, 1, 13, 29, 17, 23, 105, 393, 0 }; + static ulong[] dim70Kuo2Init = { 1, 3, 3, 3, 27, 41, 89, 79, 295, 0 }; + static ulong[] dim71Kuo2Init = { 1, 3, 3, 5, 27, 63, 29, 189, 505, 0 }; + static ulong[] dim72Kuo2Init = { 1, 1, 3, 7, 23, 63, 117, 75, 165, 0 }; + static ulong[] dim73Kuo2Init = { 1, 1, 5, 13, 1, 47, 123, 159, 485, 0 }; + static ulong[] dim74Kuo2Init = { 1, 3, 5, 1, 23, 27, 125, 45, 351, 0 }; + static ulong[] dim75Kuo2Init = { 1, 3, 1, 5, 11, 33, 75, 17, 85, 0 }; + static ulong[] dim76Kuo2Init = { 1, 3, 7, 9, 23, 31, 33, 91, 131, 0 }; + static ulong[] dim77Kuo2Init = { 1, 1, 3, 7, 23, 31, 89, 243, 229, 0 }; + static ulong[] dim78Kuo2Init = { 1, 1, 7, 15, 3, 9, 97, 59, 159, 0 }; + static ulong[] dim79Kuo2Init = { 1, 3, 3, 9, 23, 1, 105, 217, 491, 0 }; + static ulong[] dim80Kuo2Init = { 1, 3, 7, 13, 19, 3, 95, 149, 169, 0 }; + static ulong[] dim81Kuo2Init = { 1, 1, 5, 11, 29, 57, 7, 69, 33, 0 }; + static ulong[] dim82Kuo2Init = { 1, 1, 7, 7, 23, 1, 17, 3, 325, 0 }; + static ulong[] dim83Kuo2Init = { 1, 3, 1, 7, 23, 7, 49, 251, 501, 0 }; + static ulong[] dim84Kuo2Init = { 1, 1, 5, 9, 13, 59, 51, 15, 231, 0 }; + static ulong[] dim85Kuo2Init = { 1, 1, 1, 7, 13, 43, 21, 227, 165, 0 }; + static ulong[] dim86Kuo2Init = { 1, 1, 5, 1, 17, 59, 85, 13, 81, 0 }; + static ulong[] dim87Kuo2Init = { 1, 1, 5, 11, 25, 39, 109, 149, 89, 0 }; + static ulong[] dim88Kuo2Init = { 1, 3, 1, 13, 3, 47, 85, 1, 241, 0 }; + static ulong[] dim89Kuo2Init = { 1, 1, 7, 7, 29, 25, 71, 13, 221, 0 }; + static ulong[] dim90Kuo2Init = { 1, 1, 3, 5, 1, 3, 17, 241, 227, 0 }; + static ulong[] dim91Kuo2Init = { 1, 3, 1, 7, 3, 23, 127, 209, 139, 0 }; + static ulong[] dim92Kuo2Init = { 1, 1, 3, 5, 31, 39, 55, 193, 27, 0 }; + static ulong[] dim93Kuo2Init = { 1, 3, 5, 3, 5, 19, 71, 161, 255, 0 }; + static ulong[] dim94Kuo2Init = { 1, 3, 3, 7, 17, 27, 105, 13, 131, 0 }; + static ulong[] dim95Kuo2Init = { 1, 1, 3, 1, 23, 7, 43, 171, 503, 0 }; + static ulong[] dim96Kuo2Init = { 1, 3, 5, 7, 7, 11, 9, 243, 173, 0 }; + static ulong[] dim97Kuo2Init = { 1, 1, 7, 13, 23, 3, 119, 243, 189, 0 }; + static ulong[] dim98Kuo2Init = { 1, 1, 3, 11, 17, 55, 53, 159, 339, 0 }; + static ulong[] dim99Kuo2Init = { 1, 3, 3, 11, 5, 17, 69, 103, 453, 0 }; + static ulong[] dim100Kuo2Init = { 1, 3, 7, 7, 9, 41, 31, 165, 117, 0 }; + static ulong[] dim101Kuo2Init = { 1, 1, 5, 3, 5, 39, 79, 141, 205, 483, 0 }; + static ulong[] dim102Kuo2Init = { 1, 3, 1, 3, 3, 59, 57, 189, 279, 769, 0 }; + static ulong[] dim103Kuo2Init = { 1, 1, 3, 13, 25, 21, 107, 61, 329, 695, 0 }; + static ulong[] dim104Kuo2Init = { 1, 3, 5, 15, 3, 61, 71, 161, 55, 757, 0 }; + static ulong[] dim105Kuo2Init = { 1, 1, 1, 11, 9, 17, 121, 41, 177, 261, 0 }; + static ulong[] dim106Kuo2Init = { 1, 1, 5, 3, 25, 49, 55, 119, 171, 213, 0 }; + static ulong[] dim107Kuo2Init = { 1, 3, 3, 13, 21, 35, 73, 33, 43, 673, 0 }; + static ulong[] dim108Kuo2Init = { 1, 3, 5, 7, 25, 5, 7, 93, 485, 635, 0 }; + static ulong[] dim109Kuo2Init = { 1, 1, 5, 1, 5, 55, 17, 33, 67, 553, 0 }; + static ulong[] dim110Kuo2Init = { 1, 1, 7, 1, 15, 31, 67, 219, 241, 233, 0 }; + static ulong[] dim111Kuo2Init = { 1, 1, 3, 7, 9, 33, 77, 115, 401, 617, 0 }; + static ulong[] dim112Kuo2Init = { 1, 1, 3, 3, 1, 11, 79, 49, 327, 287, 0 }; + static ulong[] dim113Kuo2Init = { 1, 3, 5, 15, 19, 49, 115, 73, 193, 615, 0 }; + static ulong[] dim114Kuo2Init = { 1, 3, 5, 13, 15, 41, 17, 133, 369, 783, 0 }; + static ulong[] dim115Kuo2Init = { 1, 1, 7, 13, 9, 15, 59, 43, 129, 337, 0 }; + static ulong[] dim116Kuo2Init = { 1, 1, 3, 11, 13, 41, 35, 111, 385, 243, 0 }; + static ulong[] dim117Kuo2Init = { 1, 3, 5, 11, 7, 25, 79, 9, 5, 159, 0 }; + static ulong[] dim118Kuo2Init = { 1, 3, 3, 1, 7, 17, 31, 3, 27, 829, 0 }; + static ulong[] dim119Kuo2Init = { 1, 3, 3, 15, 27, 33, 13, 29, 223, 545, 0 }; + static ulong[] dim120Kuo2Init = { 1, 1, 5, 1, 7, 7, 31, 103, 307, 315, 0 }; + static ulong[] dim121Kuo2Init = { 1, 3, 7, 9, 15, 9, 61, 75, 99, 173, 0 }; + static ulong[] dim122Kuo2Init = { 1, 3, 3, 15, 21, 31, 49, 45, 301, 593, 0 }; + static ulong[] dim123Kuo2Init = { 1, 3, 1, 11, 3, 1, 37, 109, 413, 517, 0 }; + static ulong[] dim124Kuo2Init = { 1, 3, 1, 15, 1, 47, 45, 189, 331, 3, 0 }; + static ulong[] dim125Kuo2Init = { 1, 3, 7, 5, 3, 47, 107, 141, 257, 189, 0 }; + static ulong[] dim126Kuo2Init = { 1, 1, 1, 11, 5, 31, 49, 35, 139, 895, 0 }; + static ulong[] dim127Kuo2Init = { 1, 3, 3, 7, 17, 23, 47, 229, 225, 393, 0 }; + static ulong[] dim128Kuo2Init = { 1, 1, 1, 11, 17, 39, 125, 223, 251, 95, 0 }; + static ulong[] dim129Kuo2Init = { 1, 3, 7, 9, 31, 1, 29, 81, 301, 309, 0 }; + static ulong[] dim130Kuo2Init = { 1, 1, 1, 5, 29, 3, 5, 7, 481, 989, 0 }; + static ulong[] dim131Kuo2Init = { 1, 1, 1, 5, 19, 29, 103, 103, 385, 541, 0 }; + static ulong[] dim132Kuo2Init = { 1, 3, 7, 13, 31, 53, 27, 51, 305, 345, 0 }; + static ulong[] dim133Kuo2Init = { 1, 3, 5, 5, 19, 51, 41, 15, 31, 761, 0 }; + static ulong[] dim134Kuo2Init = { 1, 1, 5, 3, 25, 21, 93, 205, 129, 179, 0 }; + static ulong[] dim135Kuo2Init = { 1, 3, 7, 11, 5, 31, 29, 143, 103, 227, 0 }; + static ulong[] dim136Kuo2Init = { 1, 3, 1, 11, 29, 47, 97, 217, 13, 897, 0 }; + static ulong[] dim137Kuo2Init = { 1, 1, 3, 13, 15, 39, 85, 181, 471, 853, 0 }; + static ulong[] dim138Kuo2Init = { 1, 3, 1, 11, 11, 21, 5, 233, 415, 897, 0 }; + static ulong[] dim139Kuo2Init = { 1, 1, 5, 7, 3, 19, 103, 27, 353, 775, 0 }; + static ulong[] dim140Kuo2Init = { 1, 3, 3, 1, 21, 57, 123, 27, 61, 719, 0 }; + static ulong[] dim141Kuo2Init = { 1, 1, 3, 13, 5, 57, 87, 77, 301, 633, 0 }; + static ulong[] dim142Kuo2Init = { 1, 3, 7, 5, 21, 59, 19, 177, 147, 357, 0 }; + static ulong[] dim143Kuo2Init = { 1, 1, 5, 1, 5, 57, 43, 249, 475, 189, 0 }; + static ulong[] dim144Kuo2Init = { 1, 3, 7, 9, 15, 49, 29, 75, 75, 839, 0 }; + static ulong[] dim145Kuo2Init = { 1, 1, 3, 7, 23, 47, 17, 83, 275, 917, 0 }; + static ulong[] dim146Kuo2Init = { 1, 3, 7, 1, 23, 17, 35, 237, 357, 363, 0 }; + static ulong[] dim147Kuo2Init = { 1, 1, 3, 1, 17, 35, 85, 215, 405, 469, 0 }; + static ulong[] dim148Kuo2Init = { 1, 3, 1, 9, 21, 21, 103, 205, 79, 431, 0 }; + static ulong[] dim149Kuo2Init = { 1, 1, 3, 1, 7, 13, 127, 233, 93, 215, 0 }; + static ulong[] dim150Kuo2Init = { 1, 3, 1, 11, 13, 19, 87, 219, 49, 133, 0 }; + static ulong[] dim151Kuo2Init = { 1, 3, 7, 3, 27, 51, 125, 235, 159, 981, 0 }; + static ulong[] dim152Kuo2Init = { 1, 1, 3, 7, 29, 37, 3, 189, 419, 329, 0 }; + static ulong[] dim153Kuo2Init = { 1, 1, 5, 13, 9, 61, 125, 29, 111, 751, 0 }; + static ulong[] dim154Kuo2Init = { 1, 1, 3, 5, 5, 43, 59, 15, 445, 803, 0 }; + static ulong[] dim155Kuo2Init = { 1, 1, 7, 15, 25, 55, 37, 231, 287, 97, 0 }; + static ulong[] dim156Kuo2Init = { 1, 1, 1, 1, 13, 5, 97, 25, 53, 579, 0 }; + static ulong[] dim157Kuo2Init = { 1, 3, 5, 13, 27, 63, 17, 197, 285, 741, 0 }; + static ulong[] dim158Kuo2Init = { 1, 1, 5, 3, 7, 31, 13, 167, 235, 965, 0 }; + static ulong[] dim159Kuo2Init = { 1, 3, 5, 7, 3, 35, 97, 131, 89, 313, 0 }; + static ulong[] dim160Kuo2Init = { 1, 1, 3, 13, 23, 3, 91, 155, 249, 829, 0 }; + static ulong[] dim161Kuo2Init = { 1, 3, 7, 13, 1, 41, 51, 233, 233, 163, 1357, 0 }; + static ulong[] dim162Kuo2Init = { 1, 3, 1, 3, 13, 3, 55, 9, 511, 441, 811, 0 }; + static ulong[] dim163Kuo2Init = { 1, 3, 5, 5, 11, 57, 45, 65, 397, 199, 1195, 0 }; + static ulong[] dim164Kuo2Init = { 1, 3, 5, 11, 11, 15, 95, 163, 319, 727, 1793, 0 }; + static ulong[] dim165Kuo2Init = { 1, 1, 5, 7, 31, 47, 49, 177, 229, 719, 241, 0 }; + static ulong[] dim166Kuo2Init = { 1, 3, 1, 13, 9, 25, 69, 67, 151, 369, 1205, 0 }; + static ulong[] dim167Kuo2Init = { 1, 1, 7, 3, 9, 39, 99, 109, 111, 787, 181, 0 }; + static ulong[] dim168Kuo2Init = { 1, 1, 3, 11, 23, 1, 49, 111, 45, 293, 1603, 0 }; + static ulong[] dim169Kuo2Init = { 1, 1, 1, 3, 5, 45, 11, 197, 357, 109, 1291, 0 }; + static ulong[] dim170Kuo2Init = { 1, 3, 5, 11, 5, 25, 91, 91, 339, 559, 311, 0 }; + static ulong[] dim171Kuo2Init = { 1, 3, 3, 3, 21, 37, 69, 129, 205, 333, 165, 0 }; + static ulong[] dim172Kuo2Init = { 1, 1, 1, 15, 9, 19, 115, 153, 23, 381, 1727, 0 }; + static ulong[] dim173Kuo2Init = { 1, 1, 3, 1, 3, 35, 77, 217, 133, 943, 169, 0 }; + static ulong[] dim174Kuo2Init = { 1, 1, 5, 9, 1, 39, 67, 217, 143, 529, 769, 0 }; + static ulong[] dim175Kuo2Init = { 1, 1, 3, 3, 9, 9, 9, 203, 425, 601, 1389, 0 }; + static ulong[] dim176Kuo2Init = { 1, 3, 7, 3, 15, 19, 109, 31, 417, 127, 1109, 0 }; + static ulong[] dim177Kuo2Init = { 1, 3, 1, 15, 1, 37, 75, 199, 419, 917, 1929, 0 }; + static ulong[] dim178Kuo2Init = { 1, 3, 3, 9, 21, 37, 23, 165, 67, 39, 1685, 0 }; + static ulong[] dim179Kuo2Init = { 1, 3, 3, 7, 3, 25, 75, 67, 451, 889, 1015, 0 }; + static ulong[] dim180Kuo2Init = { 1, 3, 1, 1, 27, 37, 39, 7, 411, 391, 463, 0 }; + static ulong[] dim181Kuo2Init = { 1, 1, 7, 15, 25, 19, 55, 131, 245, 887, 971, 0 }; + static ulong[] dim182Kuo2Init = { 1, 3, 1, 9, 19, 9, 9, 31, 143, 647, 39, 0 }; + static ulong[] dim183Kuo2Init = { 1, 3, 7, 1, 27, 7, 107, 179, 327, 947, 953, 0 }; + static ulong[] dim184Kuo2Init = { 1, 3, 7, 13, 23, 31, 65, 29, 157, 67, 2009, 0 }; + static ulong[] dim185Kuo2Init = { 1, 3, 5, 13, 19, 31, 19, 249, 385, 209, 281, 0 }; + static ulong[] dim186Kuo2Init = { 1, 1, 7, 15, 3, 63, 1, 97, 349, 1007, 1463, 0 }; + static ulong[] dim187Kuo2Init = { 1, 3, 3, 11, 25, 3, 21, 195, 213, 1013, 637, 0 }; + static ulong[] dim188Kuo2Init = { 1, 3, 1, 1, 27, 7, 95, 215, 473, 1023, 231, 0 }; + static ulong[] dim189Kuo2Init = { 1, 3, 3, 11, 15, 15, 45, 55, 63, 693, 845, 0 }; + static ulong[] dim190Kuo2Init = { 1, 1, 3, 1, 27, 3, 63, 139, 139, 729, 861, 0 }; + static ulong[] dim191Kuo2Init = { 1, 1, 5, 3, 31, 37, 125, 175, 311, 951, 1745, 0 }; + static ulong[] dim192Kuo2Init = { 1, 1, 1, 11, 1, 19, 7, 203, 301, 403, 1293, 0 }; + static ulong[] dim193Kuo2Init = { 1, 3, 1, 5, 13, 39, 27, 155, 27, 725, 993, 0 }; + static ulong[] dim194Kuo2Init = { 1, 3, 5, 1, 5, 57, 19, 225, 407, 713, 1687, 0 }; + static ulong[] dim195Kuo2Init = { 1, 1, 1, 1, 29, 23, 83, 191, 469, 105, 311, 0 }; + static ulong[] dim196Kuo2Init = { 1, 1, 1, 11, 5, 17, 111, 5, 395, 183, 1167, 0 }; + static ulong[] dim197Kuo2Init = { 1, 3, 1, 9, 1, 41, 3, 49, 253, 735, 693, 0 }; + static ulong[] dim198Kuo2Init = { 1, 1, 5, 3, 21, 11, 43, 33, 225, 291, 1581, 0 }; + static ulong[] dim199Kuo2Init = { 1, 1, 1, 1, 5, 29, 43, 85, 465, 879, 1161, 0 }; + static ulong[] dim200Kuo2Init = { 1, 3, 1, 7, 11, 43, 61, 41, 287, 655, 1417, 0 }; + static ulong[] dim201Kuo2Init = { 1, 3, 1, 15, 21, 13, 85, 69, 353, 1005, 1109, 0 }; + static ulong[] dim202Kuo2Init = { 1, 1, 7, 1, 3, 29, 115, 227, 473, 877, 443, 0 }; + static ulong[] dim203Kuo2Init = { 1, 3, 3, 13, 13, 57, 95, 91, 473, 667, 1551, 0 }; + static ulong[] dim204Kuo2Init = { 1, 3, 3, 3, 13, 5, 45, 219, 371, 843, 95, 0 }; + static ulong[] dim205Kuo2Init = { 1, 3, 7, 1, 17, 45, 93, 63, 235, 37, 1081, 0 }; + static ulong[] dim206Kuo2Init = { 1, 3, 3, 1, 17, 21, 5, 91, 433, 321, 645, 0 }; + static ulong[] dim207Kuo2Init = { 1, 1, 7, 11, 9, 5, 33, 189, 205, 51, 259, 0 }; + static ulong[] dim208Kuo2Init = { 1, 1, 7, 3, 17, 9, 11, 235, 477, 419, 721, 0 }; + static ulong[] dim209Kuo2Init = { 1, 1, 1, 15, 21, 49, 25, 103, 25, 273, 1159, 0 }; + static ulong[] dim210Kuo2Init = { 1, 1, 1, 15, 29, 7, 97, 47, 219, 979, 961, 0 }; + static ulong[] dim211Kuo2Init = { 1, 1, 7, 13, 3, 9, 103, 179, 471, 841, 1265, 0 }; + static ulong[] dim212Kuo2Init = { 1, 1, 7, 15, 11, 33, 57, 181, 125, 307, 535, 0 }; + static ulong[] dim213Kuo2Init = { 1, 1, 7, 15, 21, 27, 15, 65, 235, 45, 1169, 0 }; + static ulong[] dim214Kuo2Init = { 1, 3, 1, 5, 9, 59, 123, 25, 391, 253, 1801, 0 }; + static ulong[] dim215Kuo2Init = { 1, 3, 1, 1, 13, 17, 85, 207, 417, 179, 951, 0 }; + static ulong[] dim216Kuo2Init = { 1, 1, 1, 15, 27, 13, 51, 169, 351, 351, 1255, 0 }; + static ulong[] dim217Kuo2Init = { 1, 3, 7, 13, 21, 63, 93, 27, 277, 999, 1381, 0 }; + static ulong[] dim218Kuo2Init = { 1, 1, 5, 9, 21, 11, 99, 199, 281, 281, 373, 0 }; + static ulong[] dim219Kuo2Init = { 1, 1, 5, 1, 1, 41, 17, 43, 411, 315, 1953, 0 }; + static ulong[] dim220Kuo2Init = { 1, 1, 5, 11, 25, 49, 7, 61, 359, 989, 1165, 0 }; + static ulong[] dim221Kuo2Init = { 1, 1, 5, 1, 21, 23, 77, 51, 501, 579, 1969, 0 }; + static ulong[] dim222Kuo2Init = { 1, 3, 7, 3, 15, 43, 89, 107, 331, 723, 771, 0 }; + static ulong[] dim223Kuo2Init = { 1, 1, 3, 15, 3, 57, 41, 241, 183, 579, 1577, 0 }; + static ulong[] dim224Kuo2Init = { 1, 3, 7, 3, 29, 31, 31, 121, 87, 1009, 235, 0 }; + static ulong[] dim225Kuo2Init = { 1, 3, 3, 1, 25, 11, 67, 33, 275, 297, 1143, 0 }; + static ulong[] dim226Kuo2Init = { 1, 1, 7, 13, 17, 29, 99, 39, 111, 29, 881, 0 }; + static ulong[] dim227Kuo2Init = { 1, 1, 7, 1, 7, 25, 27, 107, 169, 77, 1037, 0 }; + static ulong[] dim228Kuo2Init = { 1, 3, 1, 15, 17, 59, 105, 87, 295, 253, 1847, 0 }; + static ulong[] dim229Kuo2Init = { 1, 1, 7, 11, 25, 57, 75, 129, 379, 95, 381, 0 }; + static ulong[] dim230Kuo2Init = { 1, 1, 7, 11, 19, 51, 69, 23, 443, 89, 1245, 0 }; + static ulong[] dim231Kuo2Init = { 1, 3, 7, 15, 3, 43, 71, 173, 435, 125, 1039, 0 }; + static ulong[] dim232Kuo2Init = { 1, 1, 1, 13, 27, 37, 101, 97, 201, 187, 243, 0 }; + static ulong[] dim233Kuo2Init = { 1, 1, 3, 15, 13, 37, 11, 81, 233, 701, 1629, 0 }; + static ulong[] dim234Kuo2Init = { 1, 1, 3, 11, 21, 43, 37, 233, 129, 281, 511, 0 }; + static ulong[] dim235Kuo2Init = { 1, 3, 7, 3, 17, 7, 89, 19, 59, 339, 337, 0 }; + static ulong[] dim236Kuo2Init = { 1, 3, 7, 13, 27, 31, 97, 197, 485, 367, 1169, 0 }; + static ulong[] dim237Kuo2Init = { 1, 1, 7, 13, 9, 5, 93, 93, 289, 79, 57, 0 }; + static ulong[] dim238Kuo2Init = { 1, 3, 5, 13, 23, 61, 99, 201, 115, 583, 1271, 0 }; + static ulong[] dim239Kuo2Init = { 1, 3, 3, 15, 9, 55, 1, 197, 149, 919, 805, 0 }; + static ulong[] dim240Kuo2Init = { 1, 1, 1, 5, 29, 43, 119, 55, 397, 973, 1843, 0 }; + static ulong[] dim241Kuo2Init = { 1, 3, 1, 1, 5, 55, 99, 223, 323, 543, 1851, 0 }; + static ulong[] dim242Kuo2Init = { 1, 1, 1, 15, 1, 31, 17, 107, 303, 675, 1093, 0 }; + static ulong[] dim243Kuo2Init = { 1, 1, 5, 11, 9, 19, 61, 123, 411, 65, 317, 0 }; + static ulong[] dim244Kuo2Init = { 1, 3, 5, 5, 9, 15, 35, 181, 467, 289, 85, 0 }; + static ulong[] dim245Kuo2Init = { 1, 1, 1, 13, 19, 59, 75, 167, 507, 249, 259, 0 }; + static ulong[] dim246Kuo2Init = { 1, 3, 5, 3, 13, 7, 53, 87, 97, 667, 1493, 0 }; + static ulong[] dim247Kuo2Init = { 1, 1, 7, 1, 17, 35, 109, 21, 437, 225, 155, 0 }; + static ulong[] dim248Kuo2Init = { 1, 3, 7, 11, 3, 25, 51, 29, 499, 987, 223, 0 }; + static ulong[] dim249Kuo2Init = { 1, 1, 7, 7, 23, 57, 13, 23, 335, 627, 887, 0 }; + static ulong[] dim250Kuo2Init = { 1, 1, 7, 3, 15, 45, 89, 217, 393, 235, 969, 0 }; + static ulong[] dim251Kuo2Init = { 1, 3, 3, 7, 19, 47, 1, 193, 229, 45, 1617, 0 }; + static ulong[] dim252Kuo2Init = { 1, 3, 1, 9, 29, 63, 15, 57, 509, 147, 323, 0 }; + static ulong[] dim253Kuo2Init = { 1, 3, 5, 9, 9, 33, 77, 83, 109, 335, 481, 0 }; + static ulong[] dim254Kuo2Init = { 1, 1, 3, 1, 7, 47, 69, 3, 23, 243, 1787, 0 }; + static ulong[] dim255Kuo2Init = { 1, 3, 7, 7, 7, 13, 77, 211, 349, 383, 1793, 0 }; + static ulong[] dim256Kuo2Init = { 1, 1, 5, 11, 9, 9, 1, 173, 263, 965, 993, 0 }; + static ulong[] dim257Kuo2Init = { 1, 3, 3, 1, 11, 57, 85, 1, 293, 921, 1711, 0 }; + static ulong[] dim258Kuo2Init = { 1, 3, 3, 13, 29, 25, 13, 143, 373, 575, 1985, 0 }; + static ulong[] dim259Kuo2Init = { 1, 3, 1, 13, 1, 9, 71, 135, 117, 989, 1331, 0 }; + static ulong[] dim260Kuo2Init = { 1, 3, 3, 13, 29, 21, 47, 225, 199, 107, 117, 0 }; + static ulong[] dim261Kuo2Init = { 1, 1, 7, 13, 25, 5, 57, 135, 397, 411, 1275, 0 }; + static ulong[] dim262Kuo2Init = { 1, 1, 3, 1, 11, 19, 39, 9, 165, 813, 871, 0 }; + static ulong[] dim263Kuo2Init = { 1, 3, 1, 11, 29, 1, 71, 35, 361, 331, 773, 0 }; + static ulong[] dim264Kuo2Init = { 1, 1, 3, 9, 23, 23, 73, 7, 505, 183, 563, 0 }; + static ulong[] dim265Kuo2Init = { 1, 3, 5, 9, 25, 35, 123, 111, 221, 1, 873, 0 }; + static ulong[] dim266Kuo2Init = { 1, 1, 3, 3, 15, 43, 53, 71, 339, 321, 1973, 0 }; + static ulong[] dim267Kuo2Init = { 1, 1, 5, 13, 13, 57, 27, 151, 337, 739, 1205, 0 }; + static ulong[] dim268Kuo2Init = { 1, 3, 5, 13, 23, 3, 111, 101, 37, 523, 659, 0 }; + static ulong[] dim269Kuo2Init = { 1, 3, 5, 13, 23, 53, 53, 91, 505, 779, 759, 0 }; + static ulong[] dim270Kuo2Init = { 1, 1, 5, 7, 21, 43, 91, 213, 163, 29, 137, 0 }; + static ulong[] dim271Kuo2Init = { 1, 1, 1, 3, 21, 37, 97, 241, 77, 169, 1255, 0 }; + static ulong[] dim272Kuo2Init = { 1, 3, 3, 1, 5, 31, 119, 127, 137, 915, 1705, 0 }; + static ulong[] dim273Kuo2Init = { 1, 3, 3, 13, 5, 47, 117, 171, 67, 285, 225, 0 }; + static ulong[] dim274Kuo2Init = { 1, 1, 7, 9, 3, 35, 25, 25, 147, 537, 1703, 0 }; + static ulong[] dim275Kuo2Init = { 1, 3, 5, 3, 27, 41, 57, 71, 383, 763, 431, 0 }; + static ulong[] dim276Kuo2Init = { 1, 3, 3, 1, 17, 9, 105, 119, 243, 459, 881, 0 }; + static ulong[] dim277Kuo2Init = { 1, 3, 5, 15, 13, 45, 49, 41, 117, 473, 1701, 0 }; + static ulong[] dim278Kuo2Init = { 1, 1, 3, 11, 13, 5, 77, 17, 11, 1019, 353, 0 }; + static ulong[] dim279Kuo2Init = { 1, 3, 1, 11, 31, 35, 87, 195, 371, 169, 1075, 0 }; + static ulong[] dim280Kuo2Init = { 1, 3, 5, 1, 1, 1, 65, 177, 35, 497, 103, 0 }; + static ulong[] dim281Kuo2Init = { 1, 1, 3, 1, 31, 21, 77, 153, 139, 663, 443, 0 }; + static ulong[] dim282Kuo2Init = { 1, 1, 1, 1, 31, 25, 21, 87, 345, 13, 301, 0 }; + static ulong[] dim283Kuo2Init = { 1, 1, 1, 7, 7, 1, 95, 5, 429, 551, 1011, 0 }; + static ulong[] dim284Kuo2Init = { 1, 3, 5, 15, 23, 63, 119, 185, 463, 371, 567, 0 }; + static ulong[] dim285Kuo2Init = { 1, 1, 5, 5, 21, 21, 33, 141, 181, 885, 717, 0 }; + static ulong[] dim286Kuo2Init = { 1, 1, 1, 5, 11, 35, 37, 231, 67, 951, 1721, 0 }; + static ulong[] dim287Kuo2Init = { 1, 3, 7, 9, 13, 29, 113, 55, 27, 625, 285, 0 }; + static ulong[] dim288Kuo2Init = { 1, 1, 7, 5, 19, 45, 5, 233, 133, 401, 99, 0 }; + static ulong[] dim289Kuo2Init = { 1, 1, 5, 1, 7, 49, 127, 173, 187, 513, 171, 0 }; + static ulong[] dim290Kuo2Init = { 1, 1, 7, 3, 17, 59, 51, 81, 197, 1021, 763, 0 }; + static ulong[] dim291Kuo2Init = { 1, 1, 3, 1, 9, 51, 31, 149, 397, 929, 81, 0 }; + static ulong[] dim292Kuo2Init = { 1, 1, 7, 9, 29, 29, 21, 191, 107, 9, 807, 0 }; + static ulong[] dim293Kuo2Init = { 1, 1, 5, 3, 15, 3, 125, 105, 225, 571, 33, 0 }; + static ulong[] dim294Kuo2Init = { 1, 1, 5, 15, 31, 61, 113, 7, 59, 829, 1259, 0 }; + static ulong[] dim295Kuo2Init = { 1, 3, 1, 5, 29, 27, 33, 145, 211, 837, 749, 0 }; + static ulong[] dim296Kuo2Init = { 1, 1, 1, 1, 27, 15, 25, 197, 51, 71, 813, 0 }; + static ulong[] dim297Kuo2Init = { 1, 1, 1, 3, 27, 59, 1, 163, 467, 991, 1489, 0 }; + static ulong[] dim298Kuo2Init = { 1, 3, 3, 13, 1, 27, 105, 225, 403, 803, 409, 0 }; + static ulong[] dim299Kuo2Init = { 1, 1, 5, 3, 7, 31, 99, 55, 275, 487, 983, 0 }; + static ulong[] dim300Kuo2Init = { 1, 1, 1, 5, 27, 63, 107, 161, 491, 887, 825, 0 }; + static ulong[] dim301Kuo2Init = { 1, 1, 5, 15, 15, 19, 87, 165, 55, 477, 1641, 0 }; + static ulong[] dim302Kuo2Init = { 1, 3, 5, 7, 21, 49, 105, 151, 251, 385, 1265, 0 }; + static ulong[] dim303Kuo2Init = { 1, 1, 5, 3, 5, 43, 47, 213, 387, 523, 1547, 0 }; + static ulong[] dim304Kuo2Init = { 1, 3, 1, 11, 15, 55, 93, 167, 377, 201, 1031, 0 }; + static ulong[] dim305Kuo2Init = { 1, 1, 7, 7, 9, 27, 35, 251, 425, 27, 1527, 0 }; + static ulong[] dim306Kuo2Init = { 1, 1, 7, 7, 15, 55, 123, 21, 53, 77, 345, 0 }; + static ulong[] dim307Kuo2Init = { 1, 1, 5, 15, 13, 11, 75, 101, 75, 217, 219, 0 }; + static ulong[] dim308Kuo2Init = { 1, 1, 3, 9, 1, 29, 117, 209, 301, 803, 1487, 0 }; + static ulong[] dim309Kuo2Init = { 1, 3, 5, 3, 31, 57, 63, 171, 59, 591, 1323, 0 }; + static ulong[] dim310Kuo2Init = { 1, 3, 7, 11, 19, 27, 111, 87, 439, 1023, 691, 0 }; + static ulong[] dim311Kuo2Init = { 1, 3, 7, 13, 15, 57, 11, 249, 383, 291, 1221, 0 }; + static ulong[] dim312Kuo2Init = { 1, 1, 3, 13, 23, 43, 31, 75, 293, 701, 1065, 0 }; + static ulong[] dim313Kuo2Init = { 1, 1, 5, 5, 9, 53, 115, 235, 389, 907, 1883, 0 }; + static ulong[] dim314Kuo2Init = { 1, 1, 1, 11, 17, 31, 111, 187, 483, 323, 307, 0 }; + static ulong[] dim315Kuo2Init = { 1, 1, 3, 1, 23, 33, 25, 27, 267, 231, 467, 0 }; + static ulong[] dim316Kuo2Init = { 1, 3, 1, 1, 29, 15, 1, 151, 369, 943, 1293, 0 }; + static ulong[] dim317Kuo2Init = { 1, 1, 1, 15, 31, 9, 1, 223, 7, 99, 1725, 0 }; + static ulong[] dim318Kuo2Init = { 1, 1, 1, 1, 13, 3, 103, 177, 61, 939, 1321, 0 }; + static ulong[] dim319Kuo2Init = { 1, 3, 3, 7, 29, 45, 63, 119, 467, 1011, 1687, 0 }; + static ulong[] dim320Kuo2Init = { 1, 3, 5, 13, 13, 51, 69, 113, 231, 807, 863, 0 }; + static ulong[] dim321Kuo2Init = { 1, 1, 1, 13, 13, 57, 121, 219, 77, 959, 1883, 0 }; + static ulong[] dim322Kuo2Init = { 1, 1, 3, 13, 25, 19, 83, 139, 31, 3, 367, 0 }; + static ulong[] dim323Kuo2Init = { 1, 3, 7, 13, 19, 49, 45, 47, 197, 253, 1769, 0 }; + static ulong[] dim324Kuo2Init = { 1, 3, 1, 5, 13, 59, 65, 23, 31, 127, 1693, 0 }; + static ulong[] dim325Kuo2Init = { 1, 1, 7, 5, 15, 33, 85, 59, 483, 87, 1109, 0 }; + static ulong[] dim326Kuo2Init = { 1, 1, 1, 13, 29, 39, 87, 109, 223, 927, 723, 0 }; + static ulong[] dim327Kuo2Init = { 1, 1, 7, 11, 29, 19, 13, 73, 479, 989, 767, 0 }; + static ulong[] dim328Kuo2Init = { 1, 3, 1, 15, 27, 33, 119, 237, 117, 181, 1719, 0 }; + static ulong[] dim329Kuo2Init = { 1, 1, 7, 9, 1, 55, 115, 91, 355, 21, 531, 0 }; + static ulong[] dim330Kuo2Init = { 1, 1, 5, 7, 29, 23, 41, 227, 455, 587, 523, 0 }; + static ulong[] dim331Kuo2Init = { 1, 3, 5, 9, 31, 21, 105, 139, 69, 907, 1195, 0 }; + static ulong[] dim332Kuo2Init = { 1, 1, 1, 13, 11, 63, 33, 161, 133, 493, 1055, 0 }; + static ulong[] dim333Kuo2Init = { 1, 1, 7, 15, 19, 37, 37, 145, 321, 781, 575, 0 }; + static ulong[] dim334Kuo2Init = { 1, 1, 5, 5, 29, 17, 109, 193, 271, 831, 915, 0 }; + static ulong[] dim335Kuo2Init = { 1, 3, 3, 11, 17, 63, 57, 245, 347, 647, 321, 0 }; + static ulong[] dim336Kuo2Init = { 1, 3, 5, 7, 15, 15, 45, 11, 383, 231, 267, 0 }; + static ulong[] dim337Kuo2Init = { 1, 3, 5, 13, 15, 45, 67, 135, 135, 247, 1261, 205, 0 }; + static ulong[] dim338Kuo2Init = { 1, 1, 7, 5, 13, 37, 63, 179, 43, 679, 1127, 779, 0 }; + static ulong[] dim339Kuo2Init = { 1, 3, 7, 15, 7, 11, 105, 207, 93, 127, 907, 3931, 0 }; + static ulong[] dim340Kuo2Init = { 1, 3, 7, 3, 29, 45, 53, 91, 97, 175, 1847, 1119, 0 }; + static ulong[] dim341Kuo2Init = { 1, 3, 7, 13, 29, 25, 49, 245, 39, 651, 1353, 481, 0 }; + static ulong[] dim342Kuo2Init = { 1, 1, 5, 13, 13, 49, 119, 85, 101, 361, 1163, 2693, 0 }; + static ulong[] dim343Kuo2Init = { 1, 1, 7, 11, 3, 13, 23, 95, 169, 1005, 1911, 849, 0 }; + static ulong[] dim344Kuo2Init = { 1, 3, 7, 15, 1, 25, 45, 111, 3, 683, 1383, 1387, 0 }; + static ulong[] dim345Kuo2Init = { 1, 3, 1, 3, 19, 37, 97, 183, 27, 971, 853, 255, 0 }; + static ulong[] dim346Kuo2Init = { 1, 3, 5, 7, 7, 61, 19, 163, 161, 921, 1561, 841, 0 }; + static ulong[] dim347Kuo2Init = { 1, 1, 3, 7, 3, 17, 43, 185, 231, 513, 1499, 695, 0 }; + static ulong[] dim348Kuo2Init = { 1, 3, 1, 13, 27, 17, 123, 155, 13, 873, 21, 1687, 0 }; + static ulong[] dim349Kuo2Init = { 1, 1, 5, 11, 7, 15, 83, 103, 489, 529, 1331, 3783, 0 }; + static ulong[] dim350Kuo2Init = { 1, 1, 7, 13, 11, 45, 11, 105, 341, 39, 1697, 2701, 0 }; + static ulong[] dim351Kuo2Init = { 1, 1, 1, 15, 1, 37, 119, 179, 471, 343, 927, 2469, 0 }; + static ulong[] dim352Kuo2Init = { 1, 1, 3, 9, 29, 57, 59, 133, 309, 587, 1775, 1811, 0 }; + static ulong[] dim353Kuo2Init = { 1, 1, 5, 15, 7, 51, 25, 151, 173, 961, 1449, 2215, 0 }; + static ulong[] dim354Kuo2Init = { 1, 3, 1, 5, 21, 49, 113, 199, 433, 563, 849, 2741, 0 }; + static ulong[] dim355Kuo2Init = { 1, 3, 7, 9, 19, 7, 3, 95, 259, 919, 1939, 2747, 0 }; + static ulong[] dim356Kuo2Init = { 1, 3, 5, 1, 19, 35, 83, 95, 359, 85, 677, 805, 0 }; + static ulong[] dim357Kuo2Init = { 1, 3, 1, 9, 19, 37, 63, 43, 251, 301, 1217, 3361, 0 }; + static ulong[] dim358Kuo2Init = { 1, 1, 3, 7, 5, 33, 45, 15, 191, 49, 1511, 157, 0 }; + static ulong[] dim359Kuo2Init = { 1, 3, 3, 3, 7, 3, 1, 241, 239, 229, 103, 215, 0 }; + static ulong[] dim360Kuo2Init = { 1, 3, 3, 3, 29, 27, 31, 61, 331, 847, 1699, 923, 0 }; + static ulong[] dim361Kuo2Init = { 1, 3, 1, 5, 11, 15, 81, 97, 411, 471, 1521, 73, 0 }; + static ulong[] dim362Kuo2Init = { 1, 1, 7, 7, 7, 17, 95, 245, 415, 31, 259, 1835, 0 }; + static ulong[] dim363Kuo2Init = { 1, 1, 1, 1, 23, 55, 27, 201, 21, 651, 1965, 1723, 0 }; + static ulong[] dim364Kuo2Init = { 1, 1, 7, 11, 19, 43, 33, 7, 1, 635, 1651, 1041, 0 }; + static ulong[] dim365Kuo2Init = { 1, 1, 1, 15, 29, 11, 31, 11, 29, 935, 715, 1115, 0 }; + static ulong[] dim366Kuo2Init = { 1, 1, 3, 3, 23, 51, 115, 55, 45, 135, 913, 3181, 0 }; + static ulong[] dim367Kuo2Init = { 1, 3, 7, 5, 15, 23, 39, 145, 51, 243, 1705, 3889, 0 }; + static ulong[] dim368Kuo2Init = { 1, 1, 7, 5, 27, 43, 63, 15, 365, 299, 1413, 1553, 0 }; + static ulong[] dim369Kuo2Init = { 1, 3, 1, 1, 19, 41, 123, 123, 331, 487, 2033, 1849, 0 }; + static ulong[] dim370Kuo2Init = { 1, 3, 5, 13, 21, 27, 91, 225, 387, 529, 1529, 1855, 0 }; + static ulong[] dim371Kuo2Init = { 1, 3, 5, 13, 23, 51, 27, 213, 55, 619, 773, 2037, 0 }; + static ulong[] dim372Kuo2Init = { 1, 3, 3, 1, 11, 9, 125, 205, 255, 813, 925, 2031, 0 }; + static ulong[] dim373Kuo2Init = { 1, 3, 5, 9, 23, 45, 43, 197, 475, 487, 79, 3649, 0 }; + static ulong[] dim374Kuo2Init = { 1, 1, 1, 1, 5, 53, 97, 243, 433, 75, 467, 1213, 0 }; + static ulong[] dim375Kuo2Init = { 1, 1, 5, 7, 5, 53, 15, 91, 405, 791, 1293, 1517, 0 }; + static ulong[] dim376Kuo2Init = { 1, 1, 1, 3, 17, 27, 19, 81, 227, 935, 1511, 3709, 0 }; + static ulong[] dim377Kuo2Init = { 1, 1, 5, 11, 17, 41, 125, 131, 295, 867, 1291, 2833, 0 }; + static ulong[] dim378Kuo2Init = { 1, 3, 7, 13, 3, 11, 63, 159, 341, 143, 1779, 1441, 0 }; + static ulong[] dim379Kuo2Init = { 1, 1, 7, 3, 29, 3, 103, 7, 145, 589, 723, 663, 0 }; + static ulong[] dim380Kuo2Init = { 1, 1, 7, 15, 5, 25, 105, 129, 277, 163, 349, 219, 0 }; + static ulong[] dim381Kuo2Init = { 1, 3, 1, 9, 21, 27, 127, 167, 285, 135, 1493, 3825, 0 }; + static ulong[] dim382Kuo2Init = { 1, 3, 1, 1, 7, 41, 95, 255, 273, 75, 383, 15, 0 }; + static ulong[] dim383Kuo2Init = { 1, 3, 5, 7, 21, 19, 67, 19, 465, 899, 1515, 425, 0 }; + static ulong[] dim384Kuo2Init = { 1, 1, 5, 15, 17, 45, 31, 227, 229, 271, 1169, 3915, 0 }; + static ulong[] dim385Kuo2Init = { 1, 3, 7, 11, 7, 23, 117, 195, 435, 171, 777, 3473, 0 }; + static ulong[] dim386Kuo2Init = { 1, 1, 3, 3, 27, 7, 99, 11, 361, 129, 717, 1241, 0 }; + static ulong[] dim387Kuo2Init = { 1, 1, 5, 9, 27, 1, 11, 115, 15, 561, 1989, 3857, 0 }; + static ulong[] dim388Kuo2Init = { 1, 1, 1, 5, 29, 55, 23, 83, 45, 427, 987, 3627, 0 }; + static ulong[] dim389Kuo2Init = { 1, 1, 1, 9, 5, 59, 119, 77, 297, 129, 1675, 2621, 0 }; + static ulong[] dim390Kuo2Init = { 1, 1, 5, 11, 27, 49, 69, 115, 453, 863, 811, 535, 0 }; + static ulong[] dim391Kuo2Init = { 1, 1, 5, 9, 21, 43, 109, 207, 5, 987, 1747, 47, 0 }; + static ulong[] dim392Kuo2Init = { 1, 3, 5, 5, 27, 31, 67, 133, 153, 137, 1167, 325, 0 }; + static ulong[] dim393Kuo2Init = { 1, 1, 3, 15, 9, 7, 51, 221, 317, 917, 1589, 1701, 0 }; + static ulong[] dim394Kuo2Init = { 1, 1, 3, 11, 7, 21, 3, 235, 237, 853, 1883, 2733, 0 }; + static ulong[] dim395Kuo2Init = { 1, 3, 7, 1, 9, 59, 69, 71, 191, 507, 1387, 2643, 0 }; + static ulong[] dim396Kuo2Init = { 1, 1, 1, 7, 13, 17, 59, 115, 401, 373, 431, 2895, 0 }; + static ulong[] dim397Kuo2Init = { 1, 3, 7, 7, 31, 23, 51, 173, 425, 823, 1375, 1675, 0 }; + static ulong[] dim398Kuo2Init = { 1, 3, 1, 13, 1, 57, 57, 203, 275, 825, 969, 1357, 0 }; + static ulong[] dim399Kuo2Init = { 1, 3, 1, 1, 31, 39, 125, 49, 11, 255, 373, 805, 0 }; + static ulong[] dim400Kuo2Init = { 1, 3, 7, 1, 7, 59, 43, 143, 447, 73, 1979, 3401, 0 }; + static ulong[] dim401Kuo2Init = { 1, 3, 7, 15, 29, 31, 11, 49, 241, 157, 1147, 1049, 0 }; + static ulong[] dim402Kuo2Init = { 1, 1, 3, 11, 19, 39, 41, 145, 219, 811, 425, 3561, 0 }; + static ulong[] dim403Kuo2Init = { 1, 1, 3, 13, 23, 49, 123, 3, 423, 661, 329, 3883, 0 }; + static ulong[] dim404Kuo2Init = { 1, 3, 1, 15, 21, 21, 5, 105, 19, 171, 1187, 1451, 0 }; + static ulong[] dim405Kuo2Init = { 1, 1, 7, 3, 27, 7, 31, 25, 339, 107, 827, 2813, 0 }; + static ulong[] dim406Kuo2Init = { 1, 1, 3, 3, 7, 9, 5, 241, 419, 19, 303, 1327, 0 }; + static ulong[] dim407Kuo2Init = { 1, 3, 3, 5, 1, 17, 105, 143, 345, 953, 857, 2241, 0 }; + static ulong[] dim408Kuo2Init = { 1, 3, 7, 5, 11, 63, 39, 49, 3, 601, 1491, 3095, 0 }; + static ulong[] dim409Kuo2Init = { 1, 1, 5, 1, 27, 35, 25, 231, 265, 27, 83, 511, 0 }; + static ulong[] dim410Kuo2Init = { 1, 3, 5, 3, 29, 1, 119, 39, 81, 551, 1709, 2105, 0 }; + static ulong[] dim411Kuo2Init = { 1, 3, 1, 5, 29, 31, 99, 93, 391, 691, 411, 637, 0 }; + static ulong[] dim412Kuo2Init = { 1, 3, 5, 1, 21, 53, 81, 171, 303, 987, 1235, 1559, 0 }; + static ulong[] dim413Kuo2Init = { 1, 3, 3, 5, 7, 63, 51, 89, 257, 489, 275, 2309, 0 }; + static ulong[] dim414Kuo2Init = { 1, 3, 1, 5, 5, 33, 25, 55, 241, 259, 1213, 2409, 0 }; + static ulong[] dim415Kuo2Init = { 1, 3, 7, 3, 11, 57, 85, 209, 329, 611, 45, 1183, 0 }; + static ulong[] dim416Kuo2Init = { 1, 3, 3, 15, 3, 15, 31, 27, 363, 291, 1063, 229, 0 }; + static ulong[] dim417Kuo2Init = { 1, 3, 1, 1, 1, 3, 47, 189, 287, 337, 879, 1881, 0 }; + static ulong[] dim418Kuo2Init = { 1, 1, 3, 5, 9, 11, 65, 237, 499, 431, 1677, 2503, 0 }; + static ulong[] dim419Kuo2Init = { 1, 3, 1, 15, 3, 17, 101, 23, 367, 643, 1485, 1625, 0 }; + static ulong[] dim420Kuo2Init = { 1, 3, 3, 13, 9, 3, 87, 11, 137, 835, 1095, 891, 0 }; + static ulong[] dim421Kuo2Init = { 1, 1, 5, 7, 15, 3, 49, 253, 29, 159, 315, 2133, 0 }; + static ulong[] dim422Kuo2Init = { 1, 1, 3, 15, 11, 11, 17, 37, 287, 35, 813, 2715, 0 }; + static ulong[] dim423Kuo2Init = { 1, 1, 1, 9, 3, 51, 57, 205, 385, 157, 811, 627, 0 }; + static ulong[] dim424Kuo2Init = { 1, 3, 7, 15, 13, 33, 65, 117, 339, 805, 19, 3775, 0 }; + static ulong[] dim425Kuo2Init = { 1, 3, 5, 5, 9, 5, 25, 177, 469, 599, 1527, 3799, 0 }; + static ulong[] dim426Kuo2Init = { 1, 1, 3, 9, 1, 45, 65, 69, 121, 263, 1355, 1205, 0 }; + static ulong[] dim427Kuo2Init = { 1, 1, 3, 3, 3, 33, 121, 163, 95, 137, 1393, 4017, 0 }; + static ulong[] dim428Kuo2Init = { 1, 3, 7, 7, 19, 27, 17, 239, 253, 305, 1929, 1725, 0 }; + static ulong[] dim429Kuo2Init = { 1, 3, 5, 7, 5, 19, 115, 95, 93, 87, 1379, 3295, 0 }; + static ulong[] dim430Kuo2Init = { 1, 3, 3, 3, 5, 51, 7, 171, 153, 329, 1627, 3503, 0 }; + static ulong[] dim431Kuo2Init = { 1, 1, 5, 9, 27, 15, 91, 99, 433, 689, 1551, 1827, 0 }; + static ulong[] dim432Kuo2Init = { 1, 3, 3, 11, 17, 35, 29, 203, 171, 513, 771, 2011, 0 }; + static ulong[] dim433Kuo2Init = { 1, 3, 5, 11, 29, 57, 69, 239, 87, 477, 187, 4079, 0 }; + static ulong[] dim434Kuo2Init = { 1, 1, 1, 11, 9, 25, 37, 41, 113, 339, 1347, 3475, 0 }; + static ulong[] dim435Kuo2Init = { 1, 3, 1, 15, 17, 17, 53, 17, 327, 123, 915, 655, 0 }; + static ulong[] dim436Kuo2Init = { 1, 1, 5, 13, 29, 3, 85, 173, 139, 51, 929, 3407, 0 }; + static ulong[] dim437Kuo2Init = { 1, 3, 5, 3, 25, 13, 19, 91, 285, 309, 105, 2331, 0 }; + static ulong[] dim438Kuo2Init = { 1, 3, 7, 7, 13, 23, 103, 7, 435, 571, 731, 431, 0 }; + static ulong[] dim439Kuo2Init = { 1, 1, 3, 11, 23, 3, 29, 25, 369, 941, 2031, 2311, 0 }; + static ulong[] dim440Kuo2Init = { 1, 3, 5, 3, 11, 49, 69, 61, 267, 241, 1221, 1533, 0 }; + static ulong[] dim441Kuo2Init = { 1, 3, 3, 5, 17, 43, 27, 191, 201, 653, 933, 2571, 0 }; + static ulong[] dim442Kuo2Init = { 1, 1, 1, 13, 1, 7, 117, 179, 61, 1003, 379, 2359, 0 }; + static ulong[] dim443Kuo2Init = { 1, 3, 5, 15, 9, 53, 23, 217, 237, 647, 377, 677, 0 }; + static ulong[] dim444Kuo2Init = { 1, 1, 1, 1, 15, 55, 73, 1, 119, 679, 203, 309, 0 }; + static ulong[] dim445Kuo2Init = { 1, 1, 5, 15, 11, 13, 15, 211, 105, 655, 739, 1439, 0 }; + static ulong[] dim446Kuo2Init = { 1, 3, 5, 5, 9, 41, 87, 237, 65, 837, 1127, 2539, 0 }; + static ulong[] dim447Kuo2Init = { 1, 1, 3, 9, 3, 57, 23, 55, 359, 909, 969, 1437, 0 }; + static ulong[] dim448Kuo2Init = { 1, 1, 1, 9, 23, 57, 23, 127, 139, 961, 1985, 2785, 0 }; + static ulong[] dim449Kuo2Init = { 1, 3, 7, 1, 31, 7, 65, 215, 305, 245, 971, 139, 0 }; + static ulong[] dim450Kuo2Init = { 1, 3, 3, 11, 3, 3, 29, 173, 189, 807, 219, 2807, 0 }; + static ulong[] dim451Kuo2Init = { 1, 3, 5, 7, 25, 39, 7, 157, 397, 773, 461, 3051, 0 }; + static ulong[] dim452Kuo2Init = { 1, 3, 7, 7, 9, 7, 33, 19, 127, 177, 189, 1247, 0 }; + static ulong[] dim453Kuo2Init = { 1, 3, 5, 3, 5, 13, 77, 219, 339, 969, 1193, 2545, 0 }; + static ulong[] dim454Kuo2Init = { 1, 3, 3, 13, 29, 45, 123, 9, 335, 985, 1923, 2449, 0 }; + static ulong[] dim455Kuo2Init = { 1, 3, 1, 9, 7, 43, 29, 83, 153, 381, 1849, 2563, 0 }; + static ulong[] dim456Kuo2Init = { 1, 3, 3, 1, 29, 31, 107, 151, 171, 137, 1749, 1541, 0 }; + static ulong[] dim457Kuo2Init = { 1, 3, 7, 1, 13, 53, 27, 119, 295, 879, 1113, 1293, 0 }; + static ulong[] dim458Kuo2Init = { 1, 1, 7, 9, 19, 25, 127, 215, 271, 521, 1093, 1595, 0 }; + static ulong[] dim459Kuo2Init = { 1, 1, 5, 11, 11, 9, 35, 55, 447, 513, 1415, 2427, 0 }; + static ulong[] dim460Kuo2Init = { 1, 3, 1, 5, 19, 19, 19, 111, 73, 895, 1879, 3679, 0 }; + static ulong[] dim461Kuo2Init = { 1, 1, 7, 13, 13, 55, 65, 131, 461, 775, 1817, 1795, 0 }; + static ulong[] dim462Kuo2Init = { 1, 3, 7, 9, 31, 41, 119, 75, 419, 319, 1463, 3491, 0 }; + static ulong[] dim463Kuo2Init = { 1, 1, 7, 7, 27, 33, 71, 223, 381, 181, 541, 1695, 0 }; + static ulong[] dim464Kuo2Init = { 1, 3, 7, 5, 29, 53, 109, 109, 35, 607, 559, 4045, 0 }; + static ulong[] dim465Kuo2Init = { 1, 3, 1, 13, 11, 9, 9, 91, 85, 41, 1155, 3989, 0 }; + static ulong[] dim466Kuo2Init = { 1, 1, 3, 15, 23, 13, 3, 243, 443, 671, 1461, 3329, 0 }; + static ulong[] dim467Kuo2Init = { 1, 1, 1, 1, 27, 25, 37, 153, 299, 51, 371, 1269, 0 }; + static ulong[] dim468Kuo2Init = { 1, 3, 7, 11, 13, 51, 85, 177, 489, 867, 779, 3423, 0 }; + static ulong[] dim469Kuo2Init = { 1, 1, 7, 1, 25, 51, 105, 117, 105, 743, 67, 2889, 0 }; + static ulong[] dim470Kuo2Init = { 1, 1, 3, 3, 29, 31, 65, 11, 87, 647, 193, 1229, 0 }; + static ulong[] dim471Kuo2Init = { 1, 3, 5, 9, 19, 19, 19, 193, 441, 947, 1385, 1321, 0 }; + static ulong[] dim472Kuo2Init = { 1, 1, 1, 9, 9, 31, 109, 77, 449, 775, 187, 2609, 0 }; + static ulong[] dim473Kuo2Init = { 1, 1, 1, 13, 31, 57, 121, 251, 9, 673, 473, 755, 0 }; + static ulong[] dim474Kuo2Init = { 1, 3, 3, 7, 25, 21, 93, 183, 277, 167, 1305, 897, 0 }; + static ulong[] dim475Kuo2Init = { 1, 1, 5, 5, 29, 15, 29, 67, 193, 525, 851, 2287, 0 }; + static ulong[] dim476Kuo2Init = { 1, 1, 5, 9, 7, 53, 117, 203, 89, 221, 235, 2783, 0 }; + static ulong[] dim477Kuo2Init = { 1, 3, 5, 13, 7, 25, 69, 25, 329, 151, 1721, 1279, 0 }; + static ulong[] dim478Kuo2Init = { 1, 1, 1, 7, 15, 9, 119, 75, 95, 297, 1149, 1385, 0 }; + static ulong[] dim479Kuo2Init = { 1, 3, 3, 15, 23, 1, 109, 81, 249, 189, 737, 1809, 0 }; + static ulong[] dim480Kuo2Init = { 1, 1, 7, 5, 29, 53, 77, 79, 339, 625, 1131, 2539, 0 }; + static ulong[] dim481Kuo2Init = { 1, 1, 7, 15, 23, 35, 39, 25, 287, 321, 151, 193, 6637, 0 }; + static ulong[] dim482Kuo2Init = { 1, 3, 5, 9, 15, 31, 31, 111, 393, 97, 407, 1087, 1413, 0 }; + static ulong[] dim483Kuo2Init = { 1, 1, 1, 13, 21, 63, 71, 193, 443, 541, 1989, 2979, 7087, 0 }; + static ulong[] dim484Kuo2Init = { 1, 3, 3, 1, 11, 41, 19, 219, 497, 273, 1293, 2233, 2967, 0 }; + static ulong[] dim485Kuo2Init = { 1, 1, 5, 7, 23, 15, 119, 245, 223, 773, 1261, 1623, 8067, 0 }; + static ulong[] dim486Kuo2Init = { 1, 1, 1, 15, 3, 39, 39, 11, 141, 347, 1473, 3503, 3595, 0 }; + static ulong[] dim487Kuo2Init = { 1, 1, 1, 5, 27, 15, 81, 159, 279, 907, 143, 3195, 7127, 0 }; + static ulong[] dim488Kuo2Init = { 1, 1, 1, 9, 27, 29, 109, 29, 147, 255, 1851, 677, 2883, 0 }; + static ulong[] dim489Kuo2Init = { 1, 1, 5, 1, 1, 23, 3, 107, 9, 757, 319, 949, 3887, 0 }; + static ulong[] dim490Kuo2Init = { 1, 1, 7, 1, 13, 41, 21, 9, 53, 179, 1273, 17, 5195, 0 }; + static ulong[] dim491Kuo2Init = { 1, 3, 3, 15, 9, 41, 121, 13, 245, 415, 2041, 3813, 6807, 0 }; + static ulong[] dim492Kuo2Init = { 1, 3, 5, 13, 7, 5, 43, 137, 191, 855, 735, 3711, 2459, 0 }; + static ulong[] dim493Kuo2Init = { 1, 3, 3, 13, 15, 53, 13, 245, 217, 159, 271, 261, 7383, 0 }; + static ulong[] dim494Kuo2Init = { 1, 3, 1, 9, 1, 39, 79, 73, 349, 367, 51, 155, 53, 0 }; + static ulong[] dim495Kuo2Init = { 1, 1, 7, 5, 11, 19, 99, 131, 217, 729, 1481, 4015, 6109, 0 }; + static ulong[] dim496Kuo2Init = { 1, 3, 1, 3, 9, 7, 55, 119, 285, 803, 427, 3755, 3153, 0 }; + static ulong[] dim497Kuo2Init = { 1, 1, 7, 13, 25, 3, 111, 51, 1, 995, 657, 1551, 3633, 0 }; + static ulong[] dim498Kuo2Init = { 1, 3, 3, 1, 29, 49, 15, 219, 295, 335, 191, 611, 1151, 0 }; + static ulong[] dim499Kuo2Init = { 1, 3, 3, 3, 5, 37, 115, 199, 143, 11, 1487, 3841, 4669, 0 }; + static ulong[] dim500Kuo2Init = { 1, 1, 3, 5, 23, 33, 67, 51, 433, 351, 1467, 2935, 4135, 0 }; + static ulong[] dim501Kuo2Init = { 1, 3, 3, 15, 3, 57, 55, 7, 487, 983, 1481, 799, 6141, 0 }; + static ulong[] dim502Kuo2Init = { 1, 3, 5, 3, 23, 1, 37, 117, 131, 55, 449, 637, 693, 0 }; + static ulong[] dim503Kuo2Init = { 1, 3, 1, 9, 11, 7, 43, 149, 463, 349, 1773, 643, 765, 0 }; + static ulong[] dim504Kuo2Init = { 1, 3, 1, 1, 25, 39, 1, 33, 209, 131, 157, 2695, 623, 0 }; + static ulong[] dim505Kuo2Init = { 1, 1, 1, 7, 15, 41, 105, 51, 465, 453, 1091, 905, 4831, 0 }; + static ulong[] dim506Kuo2Init = { 1, 3, 7, 9, 1, 39, 45, 117, 481, 481, 87, 1869, 7063, 0 }; + static ulong[] dim507Kuo2Init = { 1, 1, 7, 1, 27, 1, 87, 75, 295, 287, 163, 911, 1725, 0 }; + static ulong[] dim508Kuo2Init = { 1, 3, 3, 9, 31, 61, 75, 53, 63, 179, 1941, 555, 1303, 0 }; + static ulong[] dim509Kuo2Init = { 1, 3, 3, 9, 31, 37, 9, 51, 381, 639, 595, 731, 7531, 0 }; + static ulong[] dim510Kuo2Init = { 1, 3, 1, 1, 3, 25, 59, 19, 187, 235, 173, 893, 4845, 0 }; + static ulong[] dim511Kuo2Init = { 1, 1, 7, 7, 1, 23, 9, 9, 493, 643, 53, 179, 6993, 0 }; + static ulong[] dim512Kuo2Init = { 1, 1, 1, 1, 25, 55, 81, 63, 67, 967, 957, 1025, 8033, 0 }; + static ulong[] dim513Kuo2Init = { 1, 3, 1, 7, 5, 43, 67, 127, 103, 241, 77, 43, 5173, 0 }; + static ulong[] dim514Kuo2Init = { 1, 1, 3, 7, 9, 25, 17, 231, 315, 699, 787, 591, 7257, 0 }; + static ulong[] dim515Kuo2Init = { 1, 3, 1, 15, 21, 19, 7, 179, 335, 701, 323, 121, 4733, 0 }; + static ulong[] dim516Kuo2Init = { 1, 1, 3, 7, 11, 59, 75, 147, 391, 535, 1841, 3025, 5621, 0 }; + static ulong[] dim517Kuo2Init = { 1, 1, 3, 7, 21, 25, 101, 71, 195, 495, 1241, 2229, 2865, 0 }; + static ulong[] dim518Kuo2Init = { 1, 3, 1, 5, 19, 55, 93, 41, 287, 787, 929, 3161, 4247, 0 }; + static ulong[] dim519Kuo2Init = { 1, 3, 3, 11, 25, 31, 79, 225, 189, 187, 595, 465, 7169, 0 }; + static ulong[] dim520Kuo2Init = { 1, 1, 3, 13, 25, 37, 7, 87, 511, 451, 1681, 1911, 5269, 0 }; + static ulong[] dim521Kuo2Init = { 1, 3, 3, 13, 21, 31, 117, 73, 391, 127, 1201, 189, 6621, 0 }; + static ulong[] dim522Kuo2Init = { 1, 3, 1, 7, 9, 49, 77, 91, 197, 889, 119, 1335, 4833, 0 }; + static ulong[] dim523Kuo2Init = { 1, 1, 7, 3, 11, 61, 103, 19, 345, 937, 1393, 963, 2283, 0 }; + static ulong[] dim524Kuo2Init = { 1, 1, 1, 9, 3, 3, 113, 189, 383, 727, 781, 3515, 5045, 0 }; + static ulong[] dim525Kuo2Init = { 1, 1, 7, 15, 27, 45, 65, 137, 5, 185, 1561, 2063, 761, 0 }; + static ulong[] dim526Kuo2Init = { 1, 1, 3, 9, 17, 5, 71, 209, 387, 693, 773, 2105, 1265, 0 }; + static ulong[] dim527Kuo2Init = { 1, 1, 3, 11, 9, 49, 53, 53, 7, 5, 543, 1605, 265, 0 }; + static ulong[] dim528Kuo2Init = { 1, 3, 3, 3, 23, 21, 27, 187, 495, 101, 517, 853, 2801, 0 }; + static ulong[] dim529Kuo2Init = { 1, 3, 5, 1, 7, 61, 47, 113, 375, 307, 255, 3341, 3663, 0 }; + static ulong[] dim530Kuo2Init = { 1, 1, 1, 1, 19, 9, 33, 235, 413, 999, 1889, 3633, 745, 0 }; + static ulong[] dim531Kuo2Init = { 1, 1, 1, 7, 27, 27, 19, 57, 1, 639, 831, 3481, 395, 0 }; + static ulong[] dim532Kuo2Init = { 1, 3, 3, 5, 19, 55, 27, 215, 319, 855, 1597, 1539, 4359, 0 }; + static ulong[] dim533Kuo2Init = { 1, 3, 7, 11, 3, 35, 5, 3, 341, 795, 315, 935, 2417, 0 }; + static ulong[] dim534Kuo2Init = { 1, 1, 1, 3, 25, 55, 53, 143, 361, 203, 863, 2491, 4701, 0 }; + static ulong[] dim535Kuo2Init = { 1, 1, 5, 9, 19, 9, 29, 153, 387, 373, 647, 2825, 1391, 0 }; + static ulong[] dim536Kuo2Init = { 1, 1, 3, 9, 1, 37, 103, 17, 347, 577, 181, 2863, 6525, 0 }; + static ulong[] dim537Kuo2Init = { 1, 1, 1, 3, 17, 19, 41, 61, 49, 75, 1243, 33, 7725, 0 }; + static ulong[] dim538Kuo2Init = { 1, 3, 1, 9, 7, 23, 107, 227, 225, 139, 451, 1303, 5657, 0 }; + static ulong[] dim539Kuo2Init = { 1, 3, 5, 11, 27, 37, 95, 195, 261, 827, 817, 2555, 8189, 0 }; + static ulong[] dim540Kuo2Init = { 1, 3, 1, 11, 13, 17, 73, 113, 287, 73, 977, 2815, 4281, 0 }; + static ulong[] dim541Kuo2Init = { 1, 1, 5, 7, 23, 7, 103, 41, 237, 745, 1645, 2041, 6063, 0 }; + static ulong[] dim542Kuo2Init = { 1, 1, 3, 15, 17, 1, 63, 115, 303, 175, 1511, 3027, 1265, 0 }; + static ulong[] dim543Kuo2Init = { 1, 3, 5, 3, 29, 57, 1, 51, 127, 539, 1171, 3567, 6409, 0 }; + static ulong[] dim544Kuo2Init = { 1, 1, 1, 9, 29, 63, 85, 127, 375, 453, 539, 563, 5709, 0 }; + static ulong[] dim545Kuo2Init = { 1, 1, 1, 7, 29, 31, 109, 159, 15, 621, 1593, 3793, 4503, 0 }; + static ulong[] dim546Kuo2Init = { 1, 1, 3, 3, 17, 27, 59, 9, 263, 705, 909, 643, 4967, 0 }; + static ulong[] dim547Kuo2Init = { 1, 3, 5, 7, 23, 13, 37, 179, 439, 77, 1055, 3129, 371, 0 }; + static ulong[] dim548Kuo2Init = { 1, 3, 1, 11, 25, 1, 123, 109, 27, 393, 1729, 3597, 5197, 0 }; + static ulong[] dim549Kuo2Init = { 1, 3, 5, 11, 15, 9, 25, 19, 1, 927, 39, 925, 87, 0 }; + static ulong[] dim550Kuo2Init = { 1, 3, 5, 1, 9, 7, 85, 95, 497, 487, 311, 2109, 259, 0 }; + static ulong[] dim551Kuo2Init = { 1, 3, 5, 1, 5, 59, 75, 243, 179, 975, 187, 415, 1161, 0 }; + static ulong[] dim552Kuo2Init = { 1, 3, 3, 13, 11, 61, 109, 129, 71, 917, 523, 1189, 4857, 0 }; + static ulong[] dim553Kuo2Init = { 1, 3, 1, 1, 3, 57, 15, 79, 265, 839, 559, 729, 2737, 0 }; + static ulong[] dim554Kuo2Init = { 1, 1, 7, 9, 21, 45, 69, 245, 331, 197, 1947, 3145, 6927, 0 }; + static ulong[] dim555Kuo2Init = { 1, 3, 7, 7, 31, 41, 73, 59, 93, 565, 1885, 3803, 7013, 0 }; + static ulong[] dim556Kuo2Init = { 1, 1, 1, 13, 23, 19, 107, 77, 449, 965, 99, 1215, 4699, 0 }; + static ulong[] dim557Kuo2Init = { 1, 1, 3, 13, 11, 3, 37, 209, 221, 197, 1913, 631, 1621, 0 }; + static ulong[] dim558Kuo2Init = { 1, 1, 5, 9, 27, 51, 61, 249, 269, 507, 1005, 2471, 4621, 0 }; + static ulong[] dim559Kuo2Init = { 1, 3, 5, 1, 3, 49, 69, 227, 289, 261, 1103, 389, 4883, 0 }; + static ulong[] dim560Kuo2Init = { 1, 1, 5, 3, 29, 35, 43, 167, 451, 1017, 865, 1507, 7387, 0 }; + static ulong[] dim561Kuo2Init = { 1, 1, 3, 15, 13, 1, 53, 9, 23, 581, 627, 3823, 6767, 0 }; + static ulong[] dim562Kuo2Init = { 1, 3, 1, 7, 3, 21, 115, 73, 353, 725, 1971, 1623, 7359, 0 }; + static ulong[] dim563Kuo2Init = { 1, 1, 3, 5, 17, 15, 37, 219, 187, 699, 1463, 1563, 2785, 0 }; + static ulong[] dim564Kuo2Init = { 1, 3, 7, 13, 11, 43, 9, 49, 125, 681, 499, 2127, 6613, 0 }; + static ulong[] dim565Kuo2Init = { 1, 3, 5, 11, 5, 21, 115, 227, 305, 247, 1947, 853, 5357, 0 }; + static ulong[] dim566Kuo2Init = { 1, 3, 1, 9, 29, 37, 1, 181, 427, 435, 1757, 1535, 4383, 0 }; + static ulong[] dim567Kuo2Init = { 1, 3, 1, 15, 15, 41, 123, 7, 367, 767, 777, 3455, 7739, 0 }; + static ulong[] dim568Kuo2Init = { 1, 1, 5, 9, 13, 3, 5, 79, 3, 121, 1113, 1731, 501, 0 }; + static ulong[] dim569Kuo2Init = { 1, 1, 3, 13, 1, 13, 127, 215, 329, 381, 205, 2391, 581, 0 }; + static ulong[] dim570Kuo2Init = { 1, 1, 3, 7, 7, 19, 9, 23, 463, 455, 1921, 763, 5077, 0 }; + static ulong[] dim571Kuo2Init = { 1, 1, 3, 3, 13, 23, 65, 7, 337, 603, 1243, 2161, 5883, 0 }; + static ulong[] dim572Kuo2Init = { 1, 3, 5, 1, 15, 23, 73, 151, 243, 847, 1189, 1663, 2011, 0 }; + static ulong[] dim573Kuo2Init = { 1, 1, 7, 7, 11, 17, 91, 219, 127, 317, 1807, 1369, 7433, 0 }; + static ulong[] dim574Kuo2Init = { 1, 3, 5, 9, 31, 49, 65, 47, 11, 541, 55, 2743, 4987, 0 }; + static ulong[] dim575Kuo2Init = { 1, 3, 7, 13, 23, 23, 51, 129, 111, 319, 1195, 1593, 4407, 0 }; + static ulong[] dim576Kuo2Init = { 1, 3, 1, 7, 21, 25, 35, 187, 409, 981, 293, 873, 7447, 0 }; + static ulong[] dim577Kuo2Init = { 1, 3, 1, 9, 3, 11, 25, 75, 347, 907, 1645, 2997, 5953, 0 }; + static ulong[] dim578Kuo2Init = { 1, 3, 7, 7, 25, 49, 99, 37, 45, 81, 95, 2637, 1337, 0 }; + static ulong[] dim579Kuo2Init = { 1, 3, 5, 3, 29, 35, 85, 167, 503, 257, 1101, 2647, 1469, 0 }; + static ulong[] dim580Kuo2Init = { 1, 3, 5, 1, 27, 17, 93, 197, 485, 899, 1201, 3633, 1289, 0 }; + static ulong[] dim581Kuo2Init = { 1, 3, 1, 7, 5, 17, 53, 167, 353, 1023, 1063, 2221, 3635, 0 }; + static ulong[] dim582Kuo2Init = { 1, 1, 5, 11, 9, 43, 123, 241, 77, 657, 1789, 235, 2105, 0 }; + static ulong[] dim583Kuo2Init = { 1, 1, 5, 9, 9, 53, 109, 185, 443, 803, 115, 2079, 7839, 0 }; + static ulong[] dim584Kuo2Init = { 1, 1, 1, 13, 29, 29, 35, 235, 253, 529, 153, 1613, 6723, 0 }; + static ulong[] dim585Kuo2Init = { 1, 3, 1, 13, 11, 31, 81, 177, 135, 659, 605, 1253, 5077, 0 }; + static ulong[] dim586Kuo2Init = { 1, 3, 5, 3, 25, 53, 87, 183, 285, 639, 657, 2307, 5477, 0 }; + static ulong[] dim587Kuo2Init = { 1, 1, 7, 7, 9, 35, 31, 83, 165, 735, 1445, 3935, 515, 0 }; + static ulong[] dim588Kuo2Init = { 1, 3, 5, 1, 13, 59, 99, 191, 187, 375, 959, 1145, 1487, 0 }; + static ulong[] dim589Kuo2Init = { 1, 3, 7, 3, 1, 1, 127, 127, 101, 583, 121, 2879, 63, 0 }; + static ulong[] dim590Kuo2Init = { 1, 3, 7, 11, 13, 1, 125, 81, 31, 177, 107, 2339, 755, 0 }; + static ulong[] dim591Kuo2Init = { 1, 1, 3, 13, 7, 33, 9, 247, 395, 255, 1817, 1509, 5401, 0 }; + static ulong[] dim592Kuo2Init = { 1, 1, 7, 7, 27, 19, 87, 167, 425, 1019, 1419, 4025, 5483, 0 }; + static ulong[] dim593Kuo2Init = { 1, 3, 7, 7, 5, 49, 97, 65, 355, 207, 323, 2367, 171, 0 }; + static ulong[] dim594Kuo2Init = { 1, 3, 7, 5, 23, 5, 125, 131, 115, 585, 1533, 3489, 507, 0 }; + static ulong[] dim595Kuo2Init = { 1, 3, 3, 15, 29, 51, 79, 239, 289, 909, 1339, 857, 1661, 0 }; + static ulong[] dim596Kuo2Init = { 1, 3, 5, 11, 23, 1, 65, 123, 439, 349, 1593, 1913, 433, 0 }; + static ulong[] dim597Kuo2Init = { 1, 1, 7, 5, 27, 45, 59, 33, 375, 553, 1955, 731, 4335, 0 }; + static ulong[] dim598Kuo2Init = { 1, 1, 3, 7, 25, 63, 51, 183, 67, 783, 885, 3385, 7109, 0 }; + static ulong[] dim599Kuo2Init = { 1, 3, 7, 9, 3, 43, 105, 145, 123, 503, 203, 1029, 6713, 0 }; + static ulong[] dim600Kuo2Init = { 1, 3, 7, 7, 11, 49, 113, 69, 489, 649, 1393, 1475, 6663, 0 }; + static ulong[] dim601Kuo2Init = { 1, 1, 5, 11, 13, 5, 105, 21, 451, 137, 2029, 1459, 7981, 0 }; + static ulong[] dim602Kuo2Init = { 1, 1, 7, 5, 7, 17, 3, 213, 255, 867, 89, 2437, 1151, 0 }; + static ulong[] dim603Kuo2Init = { 1, 1, 7, 9, 19, 23, 115, 161, 257, 419, 1133, 1291, 243, 0 }; + static ulong[] dim604Kuo2Init = { 1, 3, 5, 7, 27, 45, 23, 157, 371, 219, 1001, 343, 2419, 0 }; + static ulong[] dim605Kuo2Init = { 1, 3, 1, 1, 21, 59, 91, 153, 19, 469, 1923, 2439, 3837, 0 }; + static ulong[] dim606Kuo2Init = { 1, 3, 7, 3, 23, 29, 57, 201, 209, 249, 63, 2929, 2719, 0 }; + static ulong[] dim607Kuo2Init = { 1, 1, 5, 3, 11, 3, 75, 91, 157, 557, 1775, 387, 803, 0 }; + static ulong[] dim608Kuo2Init = { 1, 3, 3, 3, 27, 57, 69, 135, 317, 897, 1417, 1853, 747, 0 }; + static ulong[] dim609Kuo2Init = { 1, 1, 7, 11, 15, 19, 115, 219, 57, 925, 1869, 609, 1631, 0 }; + static ulong[] dim610Kuo2Init = { 1, 1, 1, 11, 29, 21, 45, 19, 91, 271, 971, 2569, 423, 0 }; + static ulong[] dim611Kuo2Init = { 1, 3, 3, 13, 5, 9, 5, 101, 147, 777, 1647, 457, 4053, 0 }; + static ulong[] dim612Kuo2Init = { 1, 1, 5, 9, 9, 25, 13, 175, 53, 467, 1555, 2969, 1669, 0 }; + static ulong[] dim613Kuo2Init = { 1, 1, 1, 7, 21, 49, 1, 49, 317, 505, 1495, 1053, 2293, 0 }; + static ulong[] dim614Kuo2Init = { 1, 1, 1, 3, 15, 43, 91, 207, 211, 725, 2039, 803, 4029, 0 }; + static ulong[] dim615Kuo2Init = { 1, 1, 7, 13, 17, 45, 39, 125, 129, 169, 47, 2105, 1749, 0 }; + static ulong[] dim616Kuo2Init = { 1, 3, 7, 11, 19, 13, 5, 105, 203, 611, 147, 2291, 1823, 0 }; + static ulong[] dim617Kuo2Init = { 1, 1, 5, 1, 5, 15, 15, 35, 33, 467, 59, 2435, 3141, 0 }; + static ulong[] dim618Kuo2Init = { 1, 3, 1, 5, 29, 43, 35, 3, 173, 619, 1595, 347, 2513, 0 }; + static ulong[] dim619Kuo2Init = { 1, 3, 3, 1, 23, 37, 3, 123, 301, 403, 1603, 2345, 1031, 0 }; + static ulong[] dim620Kuo2Init = { 1, 3, 5, 9, 23, 55, 23, 19, 497, 501, 99, 1925, 6243, 0 }; + static ulong[] dim621Kuo2Init = { 1, 3, 5, 1, 21, 37, 83, 59, 285, 107, 1909, 3647, 8041, 0 }; + static ulong[] dim622Kuo2Init = { 1, 3, 5, 1, 7, 11, 91, 1, 357, 643, 1319, 2895, 2193, 0 }; + static ulong[] dim623Kuo2Init = { 1, 1, 5, 9, 27, 29, 25, 125, 433, 525, 1511, 585, 5263, 0 }; + static ulong[] dim624Kuo2Init = { 1, 3, 1, 11, 13, 49, 79, 37, 165, 923, 749, 2207, 4673, 0 }; + static ulong[] dim625Kuo2Init = { 1, 1, 5, 9, 29, 37, 51, 3, 133, 859, 153, 1199, 2269, 0 }; + static ulong[] dim626Kuo2Init = { 1, 1, 7, 5, 9, 57, 101, 231, 383, 245, 1997, 2661, 6069, 0 }; + static ulong[] dim627Kuo2Init = { 1, 1, 7, 7, 25, 61, 25, 185, 247, 509, 1953, 3309, 4879, 0 }; + static ulong[] dim628Kuo2Init = { 1, 1, 3, 7, 19, 61, 95, 105, 355, 219, 103, 249, 579, 0 }; + static ulong[] dim629Kuo2Init = { 1, 3, 7, 15, 7, 3, 51, 143, 273, 203, 353, 1587, 2239, 0 }; + static ulong[] dim630Kuo2Init = { 1, 3, 3, 9, 27, 47, 123, 185, 337, 183, 983, 2313, 815, 0 }; + static ulong[] dim631Kuo2Init = { 1, 1, 5, 15, 19, 19, 3, 199, 247, 151, 1911, 301, 5311, 0 }; + static ulong[] dim632Kuo2Init = { 1, 1, 1, 3, 7, 63, 61, 151, 297, 541, 1457, 2945, 5703, 0 }; + static ulong[] dim633Kuo2Init = { 1, 3, 7, 5, 31, 1, 109, 179, 197, 109, 695, 2429, 3483, 0 }; + static ulong[] dim634Kuo2Init = { 1, 3, 7, 1, 27, 25, 27, 113, 455, 655, 1813, 2341, 4785, 0 }; + static ulong[] dim635Kuo2Init = { 1, 1, 5, 15, 9, 47, 105, 15, 75, 901, 1539, 2599, 1013, 0 }; + static ulong[] dim636Kuo2Init = { 1, 3, 1, 11, 17, 17, 29, 219, 121, 383, 1575, 3153, 6151, 0 }; + static ulong[] dim637Kuo2Init = { 1, 1, 1, 3, 29, 51, 35, 95, 89, 279, 1255, 2967, 455, 0 }; + static ulong[] dim638Kuo2Init = { 1, 3, 5, 15, 3, 3, 15, 181, 91, 169, 1703, 777, 6539, 0 }; + static ulong[] dim639Kuo2Init = { 1, 1, 3, 13, 15, 29, 115, 225, 179, 271, 737, 2425, 3149, 0 }; + static ulong[] dim640Kuo2Init = { 1, 3, 7, 3, 13, 29, 1, 169, 35, 145, 725, 3679, 2593, 0 }; + static ulong[] dim641Kuo2Init = { 1, 1, 7, 9, 11, 1, 51, 65, 283, 791, 449, 1387, 7347, 0 }; + static ulong[] dim642Kuo2Init = { 1, 3, 1, 13, 21, 23, 79, 207, 425, 839, 737, 243, 6761, 0 }; + static ulong[] dim643Kuo2Init = { 1, 3, 3, 5, 11, 25, 93, 119, 245, 539, 405, 1925, 1595, 0 }; + static ulong[] dim644Kuo2Init = { 1, 3, 7, 15, 5, 19, 97, 225, 471, 801, 379, 923, 1961, 0 }; + static ulong[] dim645Kuo2Init = { 1, 3, 7, 15, 25, 49, 41, 237, 11, 983, 1889, 3947, 2579, 0 }; + static ulong[] dim646Kuo2Init = { 1, 3, 5, 13, 3, 39, 51, 131, 477, 699, 1101, 1289, 7683, 0 }; + static ulong[] dim647Kuo2Init = { 1, 1, 7, 1, 23, 39, 99, 167, 53, 333, 1059, 2947, 2097, 0 }; + static ulong[] dim648Kuo2Init = { 1, 1, 5, 15, 9, 55, 33, 121, 485, 767, 793, 1015, 7657, 0 }; + static ulong[] dim649Kuo2Init = { 1, 1, 7, 13, 15, 57, 5, 39, 197, 67, 1471, 841, 1797, 0 }; + static ulong[] dim650Kuo2Init = { 1, 3, 5, 3, 15, 17, 11, 139, 21, 827, 465, 1341, 1115, 0 }; + static ulong[] dim651Kuo2Init = { 1, 3, 7, 11, 7, 3, 29, 107, 79, 19, 493, 1705, 4631, 0 }; + static ulong[] dim652Kuo2Init = { 1, 1, 7, 1, 9, 61, 79, 23, 83, 863, 1189, 2653, 2139, 0 }; + static ulong[] dim653Kuo2Init = { 1, 1, 7, 7, 7, 39, 105, 147, 293, 799, 781, 1085, 1405, 0 }; + static ulong[] dim654Kuo2Init = { 1, 3, 3, 13, 27, 55, 89, 73, 255, 845, 485, 739, 4937, 0 }; + static ulong[] dim655Kuo2Init = { 1, 3, 1, 5, 19, 41, 93, 125, 203, 789, 1447, 189, 4743, 0 }; + static ulong[] dim656Kuo2Init = { 1, 3, 3, 11, 9, 9, 51, 237, 353, 313, 101, 873, 5605, 0 }; + static ulong[] dim657Kuo2Init = { 1, 3, 1, 5, 1, 33, 67, 29, 361, 945, 5, 305, 1461, 0 }; + static ulong[] dim658Kuo2Init = { 1, 1, 7, 3, 5, 31, 47, 145, 369, 419, 415, 2645, 4665, 0 }; + static ulong[] dim659Kuo2Init = { 1, 1, 1, 1, 9, 35, 3, 67, 233, 991, 1683, 1145, 6283, 0 }; + static ulong[] dim660Kuo2Init = { 1, 1, 1, 7, 13, 43, 95, 141, 415, 219, 1877, 2763, 3975, 0 }; + static ulong[] dim661Kuo2Init = { 1, 1, 3, 9, 25, 1, 125, 139, 31, 791, 2033, 2477, 297, 0 }; + static ulong[] dim662Kuo2Init = { 1, 1, 3, 7, 13, 53, 29, 53, 341, 905, 1953, 593, 3121, 0 }; + static ulong[] dim663Kuo2Init = { 1, 3, 3, 5, 21, 45, 97, 231, 377, 117, 1449, 1159, 1831, 0 }; + static ulong[] dim664Kuo2Init = { 1, 3, 7, 3, 13, 25, 33, 15, 479, 141, 1101, 1611, 2145, 0 }; + static ulong[] dim665Kuo2Init = { 1, 3, 5, 13, 19, 33, 85, 215, 107, 273, 1361, 1103, 3461, 0 }; + static ulong[] dim666Kuo2Init = { 1, 3, 5, 9, 7, 29, 91, 55, 239, 971, 1389, 301, 6011, 0 }; + static ulong[] dim667Kuo2Init = { 1, 3, 3, 3, 31, 39, 73, 131, 53, 583, 1387, 3827, 5621, 0 }; + static ulong[] dim668Kuo2Init = { 1, 1, 7, 1, 21, 47, 39, 99, 95, 915, 1281, 675, 4147, 0 }; + static ulong[] dim669Kuo2Init = { 1, 3, 7, 13, 19, 17, 121, 151, 163, 447, 1741, 2563, 957, 0 }; + static ulong[] dim670Kuo2Init = { 1, 3, 1, 11, 19, 19, 9, 31, 105, 829, 1957, 3327, 2923, 0 }; + static ulong[] dim671Kuo2Init = { 1, 1, 1, 1, 29, 49, 67, 135, 165, 203, 691, 4043, 4973, 0 }; + static ulong[] dim672Kuo2Init = { 1, 3, 3, 15, 17, 57, 53, 123, 311, 169, 1705, 3853, 3243, 0 }; + static ulong[] dim673Kuo2Init = { 1, 1, 7, 5, 11, 51, 39, 215, 209, 353, 1857, 369, 1793, 0 }; + static ulong[] dim674Kuo2Init = { 1, 1, 1, 3, 1, 55, 19, 145, 283, 471, 929, 3207, 5819, 0 }; + static ulong[] dim675Kuo2Init = { 1, 1, 3, 13, 21, 23, 49, 241, 53, 153, 591, 949, 859, 0 }; + static ulong[] dim676Kuo2Init = { 1, 3, 1, 5, 21, 13, 105, 147, 29, 407, 589, 1659, 5265, 0 }; + static ulong[] dim677Kuo2Init = { 1, 1, 1, 9, 19, 27, 83, 175, 329, 459, 1401, 2195, 5997, 0 }; + static ulong[] dim678Kuo2Init = { 1, 1, 5, 1, 29, 39, 33, 73, 363, 143, 617, 1507, 5871, 0 }; + static ulong[] dim679Kuo2Init = { 1, 1, 1, 7, 29, 23, 19, 51, 331, 299, 1883, 1973, 1969, 0 }; + static ulong[] dim680Kuo2Init = { 1, 3, 7, 13, 1, 49, 25, 43, 17, 297, 683, 1189, 6049, 0 }; + static ulong[] dim681Kuo2Init = { 1, 3, 1, 15, 23, 25, 29, 231, 425, 501, 1787, 3223, 5789, 0 }; + static ulong[] dim682Kuo2Init = { 1, 3, 7, 1, 1, 3, 23, 231, 377, 485, 1469, 1089, 1539, 0 }; + static ulong[] dim683Kuo2Init = { 1, 1, 5, 5, 29, 25, 93, 51, 249, 25, 1355, 23, 2961, 0 }; + static ulong[] dim684Kuo2Init = { 1, 3, 5, 13, 11, 55, 117, 221, 137, 941, 1127, 735, 4835, 0 }; + static ulong[] dim685Kuo2Init = { 1, 3, 3, 15, 5, 53, 35, 245, 31, 985, 2035, 163, 5223, 0 }; + static ulong[] dim686Kuo2Init = { 1, 1, 7, 7, 27, 25, 17, 113, 187, 283, 723, 2703, 4873, 0 }; + static ulong[] dim687Kuo2Init = { 1, 1, 1, 1, 3, 61, 81, 125, 335, 997, 975, 2371, 1829, 0 }; + static ulong[] dim688Kuo2Init = { 1, 3, 1, 15, 21, 9, 67, 55, 109, 657, 837, 1737, 5147, 0 }; + static ulong[] dim689Kuo2Init = { 1, 1, 3, 3, 19, 41, 117, 39, 441, 985, 955, 1467, 7297, 0 }; + static ulong[] dim690Kuo2Init = { 1, 1, 7, 7, 23, 1, 11, 11, 221, 539, 1807, 1887, 7921, 0 }; + static ulong[] dim691Kuo2Init = { 1, 3, 3, 1, 27, 45, 73, 39, 217, 233, 2015, 1209, 7101, 0 }; + static ulong[] dim692Kuo2Init = { 1, 3, 1, 11, 19, 57, 85, 45, 395, 23, 405, 2723, 653, 0 }; + static ulong[] dim693Kuo2Init = { 1, 1, 5, 15, 3, 43, 95, 149, 395, 359, 1067, 3571, 6219, 0 }; + static ulong[] dim694Kuo2Init = { 1, 1, 5, 5, 15, 3, 33, 181, 427, 565, 103, 261, 2375, 0 }; + static ulong[] dim695Kuo2Init = { 1, 3, 3, 15, 1, 3, 89, 239, 461, 675, 1149, 819, 3481, 0 }; + static ulong[] dim696Kuo2Init = { 1, 1, 5, 9, 23, 57, 1, 147, 245, 941, 1425, 2403, 7915, 0 }; + static ulong[] dim697Kuo2Init = { 1, 3, 1, 13, 3, 25, 43, 205, 295, 799, 1845, 2695, 3183, 0 }; + static ulong[] dim698Kuo2Init = { 1, 3, 1, 15, 11, 19, 111, 83, 479, 927, 709, 2739, 1233, 0 }; + static ulong[] dim699Kuo2Init = { 1, 3, 7, 13, 25, 41, 49, 39, 63, 265, 717, 3843, 3091, 0 }; + static ulong[] dim700Kuo2Init = { 1, 3, 1, 5, 27, 11, 55, 31, 103, 263, 759, 1969, 1301, 0 }; + static ulong[] dim701Kuo2Init = { 1, 1, 7, 15, 15, 33, 61, 93, 177, 645, 387, 3999, 4511, 0 }; + static ulong[] dim702Kuo2Init = { 1, 1, 7, 9, 5, 43, 87, 125, 443, 825, 1423, 1575, 2661, 0 }; + static ulong[] dim703Kuo2Init = { 1, 3, 1, 5, 3, 59, 59, 91, 63, 805, 1461, 4009, 4235, 0 }; + static ulong[] dim704Kuo2Init = { 1, 1, 3, 7, 15, 13, 95, 179, 479, 735, 1075, 4089, 4807, 0 }; + static ulong[] dim705Kuo2Init = { 1, 3, 1, 3, 23, 63, 63, 77, 299, 939, 661, 1007, 3299, 0 }; + static ulong[] dim706Kuo2Init = { 1, 1, 5, 3, 7, 49, 1, 217, 87, 561, 275, 3137, 4355, 0 }; + static ulong[] dim707Kuo2Init = { 1, 3, 5, 9, 21, 25, 49, 199, 207, 513, 231, 3053, 8023, 0 }; + static ulong[] dim708Kuo2Init = { 1, 1, 5, 1, 19, 39, 79, 225, 213, 719, 577, 3885, 7151, 0 }; + static ulong[] dim709Kuo2Init = { 1, 3, 1, 7, 9, 7, 9, 63, 185, 877, 253, 1401, 7665, 0 }; + static ulong[] dim710Kuo2Init = { 1, 1, 7, 15, 7, 9, 33, 79, 241, 727, 681, 2195, 5285, 0 }; + static ulong[] dim711Kuo2Init = { 1, 3, 3, 9, 21, 27, 9, 17, 277, 365, 1497, 2323, 1215, 0 }; + static ulong[] dim712Kuo2Init = { 1, 1, 3, 3, 29, 23, 63, 209, 487, 243, 1137, 45, 3949, 0 }; + static ulong[] dim713Kuo2Init = { 1, 1, 1, 15, 1, 33, 29, 245, 25, 497, 809, 4017, 2149, 0 }; + static ulong[] dim714Kuo2Init = { 1, 3, 3, 3, 25, 11, 117, 129, 23, 547, 175, 463, 2731, 0 }; + static ulong[] dim715Kuo2Init = { 1, 3, 3, 3, 5, 47, 69, 197, 131, 101, 1003, 1573, 3629, 0 }; + static ulong[] dim716Kuo2Init = { 1, 1, 1, 9, 7, 33, 63, 53, 159, 1009, 963, 203, 3395, 0 }; + static ulong[] dim717Kuo2Init = { 1, 3, 1, 1, 9, 11, 95, 73, 359, 357, 421, 1169, 7317, 0 }; + static ulong[] dim718Kuo2Init = { 1, 3, 5, 15, 27, 57, 105, 109, 457, 161, 901, 2239, 2143, 0 }; + static ulong[] dim719Kuo2Init = { 1, 1, 3, 7, 7, 61, 11, 211, 7, 515, 895, 1341, 2603, 0 }; + static ulong[] dim720Kuo2Init = { 1, 3, 3, 3, 7, 15, 67, 237, 5, 345, 1631, 923, 4269, 0 }; + static ulong[] dim721Kuo2Init = { 1, 1, 1, 15, 15, 27, 73, 7, 359, 49, 381, 2415, 1979, 0 }; + static ulong[] dim722Kuo2Init = { 1, 3, 7, 7, 15, 33, 1, 39, 19, 171, 93, 1815, 2675, 0 }; + static ulong[] dim723Kuo2Init = { 1, 3, 7, 9, 13, 37, 85, 75, 395, 767, 1855, 3413, 1845, 0 }; + static ulong[] dim724Kuo2Init = { 1, 3, 5, 15, 7, 59, 33, 235, 455, 21, 237, 3103, 6065, 0 }; + static ulong[] dim725Kuo2Init = { 1, 1, 3, 3, 29, 9, 67, 173, 303, 9, 1899, 3799, 63, 0 }; + static ulong[] dim726Kuo2Init = { 1, 1, 3, 5, 15, 53, 13, 149, 45, 223, 823, 1351, 4517, 0 }; + static ulong[] dim727Kuo2Init = { 1, 3, 3, 15, 21, 59, 81, 185, 245, 589, 1149, 3351, 4879, 0 }; + static ulong[] dim728Kuo2Init = { 1, 1, 1, 1, 11, 29, 17, 57, 199, 941, 1497, 227, 6271, 0 }; + static ulong[] dim729Kuo2Init = { 1, 3, 5, 7, 13, 35, 97, 247, 439, 687, 1821, 1583, 5919, 0 }; + static ulong[] dim730Kuo2Init = { 1, 1, 3, 7, 27, 25, 123, 129, 15, 497, 1491, 171, 6369, 0 }; + static ulong[] dim731Kuo2Init = { 1, 3, 1, 1, 25, 27, 63, 27, 261, 707, 579, 2599, 5925, 0 }; + static ulong[] dim732Kuo2Init = { 1, 1, 3, 9, 9, 39, 63, 141, 293, 601, 573, 445, 1003, 0 }; + static ulong[] dim733Kuo2Init = { 1, 3, 3, 15, 7, 25, 21, 189, 137, 13, 1923, 1019, 7219, 0 }; + static ulong[] dim734Kuo2Init = { 1, 3, 5, 9, 27, 45, 13, 251, 403, 781, 2009, 239, 4777, 0 }; + static ulong[] dim735Kuo2Init = { 1, 1, 5, 3, 21, 35, 93, 89, 249, 473, 1241, 2485, 291, 0 }; + static ulong[] dim736Kuo2Init = { 1, 3, 7, 15, 5, 53, 45, 213, 41, 393, 529, 599, 4993, 0 }; + static ulong[] dim737Kuo2Init = { 1, 3, 7, 5, 29, 29, 9, 163, 27, 617, 2015, 117, 6065, 0 }; + static ulong[] dim738Kuo2Init = { 1, 1, 7, 3, 9, 19, 31, 67, 395, 1003, 1907, 1165, 3375, 0 }; + static ulong[] dim739Kuo2Init = { 1, 1, 7, 1, 1, 37, 41, 131, 397, 181, 481, 2691, 6519, 0 }; + static ulong[] dim740Kuo2Init = { 1, 3, 5, 3, 9, 31, 127, 145, 435, 149, 597, 3611, 7715, 0 }; + static ulong[] dim741Kuo2Init = { 1, 1, 3, 9, 27, 33, 37, 165, 167, 699, 1313, 3599, 827, 0 }; + static ulong[] dim742Kuo2Init = { 1, 1, 1, 9, 15, 3, 21, 123, 319, 1009, 901, 819, 823, 0 }; + static ulong[] dim743Kuo2Init = { 1, 1, 7, 9, 29, 27, 101, 33, 341, 449, 607, 2807, 5553, 0 }; + static ulong[] dim744Kuo2Init = { 1, 3, 5, 3, 21, 25, 41, 105, 255, 339, 1971, 175, 47, 0 }; + static ulong[] dim745Kuo2Init = { 1, 1, 3, 5, 5, 3, 21, 73, 111, 293, 1283, 2531, 7609, 0 }; + static ulong[] dim746Kuo2Init = { 1, 3, 7, 3, 29, 47, 83, 165, 249, 281, 175, 1043, 4143, 0 }; + static ulong[] dim747Kuo2Init = { 1, 3, 1, 15, 27, 59, 3, 101, 343, 813, 1559, 553, 7801, 0 }; + static ulong[] dim748Kuo2Init = { 1, 1, 7, 15, 1, 9, 77, 205, 151, 255, 701, 2653, 2079, 0 }; + static ulong[] dim749Kuo2Init = { 1, 3, 3, 3, 13, 39, 37, 161, 499, 657, 1557, 3969, 3489, 0 }; + static ulong[] dim750Kuo2Init = { 1, 1, 1, 15, 9, 27, 41, 253, 119, 583, 73, 3255, 6067, 0 }; + static ulong[] dim751Kuo2Init = { 1, 1, 7, 7, 27, 43, 53, 99, 245, 169, 659, 81, 2943, 0 }; + static ulong[] dim752Kuo2Init = { 1, 1, 1, 11, 27, 13, 41, 217, 493, 145, 835, 3745, 97, 0 }; + static ulong[] dim753Kuo2Init = { 1, 3, 1, 9, 7, 13, 117, 113, 197, 503, 953, 2433, 7663, 0 }; + static ulong[] dim754Kuo2Init = { 1, 3, 5, 5, 9, 47, 101, 47, 187, 469, 69, 4031, 6231, 0 }; + static ulong[] dim755Kuo2Init = { 1, 1, 1, 3, 27, 27, 47, 219, 11, 201, 1267, 2703, 6711, 0 }; + static ulong[] dim756Kuo2Init = { 1, 3, 7, 7, 27, 27, 97, 101, 7, 541, 105, 3821, 7533, 0 }; + static ulong[] dim757Kuo2Init = { 1, 3, 5, 13, 21, 17, 99, 213, 347, 595, 519, 1113, 5427, 0 }; + static ulong[] dim758Kuo2Init = { 1, 1, 7, 13, 31, 1, 25, 111, 387, 27, 99, 119, 3265, 0 }; + static ulong[] dim759Kuo2Init = { 1, 1, 7, 15, 11, 43, 19, 177, 11, 943, 3, 623, 4223, 0 }; + static ulong[] dim760Kuo2Init = { 1, 3, 7, 3, 31, 59, 21, 241, 375, 703, 1465, 2375, 2853, 0 }; + static ulong[] dim761Kuo2Init = { 1, 1, 7, 15, 1, 49, 51, 161, 397, 583, 913, 985, 5519, 0 }; + static ulong[] dim762Kuo2Init = { 1, 3, 1, 3, 13, 37, 23, 165, 223, 427, 129, 1553, 4145, 0 }; + static ulong[] dim763Kuo2Init = { 1, 3, 3, 3, 1, 23, 47, 237, 371, 315, 1631, 2037, 61, 0 }; + static ulong[] dim764Kuo2Init = { 1, 3, 5, 15, 23, 59, 71, 237, 487, 443, 1475, 3065, 2453, 0 }; + static ulong[] dim765Kuo2Init = { 1, 1, 3, 13, 25, 57, 71, 3, 247, 145, 2011, 553, 7565, 0 }; + static ulong[] dim766Kuo2Init = { 1, 1, 1, 9, 21, 1, 61, 91, 3, 807, 1795, 2665, 473, 0 }; + static ulong[] dim767Kuo2Init = { 1, 3, 7, 11, 9, 7, 123, 233, 249, 825, 1505, 3599, 6653, 0 }; + static ulong[] dim768Kuo2Init = { 1, 1, 3, 15, 11, 37, 119, 63, 233, 541, 1373, 765, 4913, 0 }; + static ulong[] dim769Kuo2Init = { 1, 1, 1, 9, 5, 15, 77, 65, 321, 613, 1857, 3699, 1, 0 }; + static ulong[] dim770Kuo2Init = { 1, 3, 1, 15, 13, 37, 123, 9, 105, 121, 893, 1009, 7871, 0 }; + static ulong[] dim771Kuo2Init = { 1, 3, 5, 1, 23, 61, 29, 223, 209, 605, 409, 875, 5233, 0 }; + static ulong[] dim772Kuo2Init = { 1, 1, 3, 11, 5, 61, 9, 85, 361, 613, 1555, 2323, 5119, 0 }; + static ulong[] dim773Kuo2Init = { 1, 1, 1, 1, 17, 49, 67, 191, 247, 873, 1283, 171, 1689, 0 }; + static ulong[] dim774Kuo2Init = { 1, 3, 3, 13, 17, 17, 45, 73, 175, 243, 97, 315, 1429, 0 }; + static ulong[] dim775Kuo2Init = { 1, 3, 5, 5, 13, 1, 113, 87, 241, 199, 145, 3823, 5965, 0 }; + static ulong[] dim776Kuo2Init = { 1, 3, 3, 7, 7, 47, 115, 139, 239, 547, 109, 2251, 6987, 0 }; + static ulong[] dim777Kuo2Init = { 1, 3, 1, 11, 3, 59, 111, 225, 385, 887, 425, 1879, 4535, 0 }; + static ulong[] dim778Kuo2Init = { 1, 1, 3, 9, 27, 35, 55, 125, 379, 529, 191, 1657, 2835, 0 }; + static ulong[] dim779Kuo2Init = { 1, 1, 7, 11, 25, 11, 85, 21, 65, 377, 1989, 1963, 6985, 0 }; + static ulong[] dim780Kuo2Init = { 1, 3, 7, 11, 15, 59, 91, 51, 145, 627, 1617, 3029, 3621, 0 }; + static ulong[] dim781Kuo2Init = { 1, 3, 7, 11, 29, 9, 15, 189, 495, 997, 467, 343, 7615, 0 }; + static ulong[] dim782Kuo2Init = { 1, 1, 7, 7, 17, 37, 89, 31, 355, 323, 1361, 3785, 643, 0 }; + static ulong[] dim783Kuo2Init = { 1, 1, 7, 1, 27, 19, 15, 5, 383, 1023, 923, 3283, 2997, 0 }; + static ulong[] dim784Kuo2Init = { 1, 3, 7, 15, 11, 41, 117, 255, 407, 117, 495, 99, 7687, 0 }; + static ulong[] dim785Kuo2Init = { 1, 1, 1, 9, 9, 29, 109, 103, 81, 237, 1547, 3083, 2449, 0 }; + static ulong[] dim786Kuo2Init = { 1, 3, 5, 1, 19, 57, 43, 215, 251, 417, 1719, 3767, 1543, 0 }; + static ulong[] dim787Kuo2Init = { 1, 3, 7, 11, 15, 9, 1, 171, 439, 637, 1709, 1483, 4111, 0 }; + static ulong[] dim788Kuo2Init = { 1, 3, 1, 5, 25, 31, 101, 101, 301, 169, 803, 2119, 5035, 0 }; + static ulong[] dim789Kuo2Init = { 1, 1, 7, 5, 21, 57, 59, 149, 31, 1023, 1063, 2465, 1517, 0 }; + static ulong[] dim790Kuo2Init = { 1, 1, 5, 5, 7, 29, 101, 19, 49, 187, 715, 843, 1553, 0 }; + static ulong[] dim791Kuo2Init = { 1, 3, 3, 5, 21, 43, 27, 203, 125, 629, 1395, 15, 7647, 0 }; + static ulong[] dim792Kuo2Init = { 1, 1, 3, 11, 27, 49, 69, 135, 447, 503, 1589, 209, 791, 0 }; + static ulong[] dim793Kuo2Init = { 1, 3, 1, 15, 17, 57, 27, 55, 237, 223, 949, 2119, 3221, 0 }; + static ulong[] dim794Kuo2Init = { 1, 3, 3, 9, 3, 37, 43, 49, 41, 899, 1657, 2463, 1303, 0 }; + static ulong[] dim795Kuo2Init = { 1, 1, 7, 13, 27, 27, 19, 93, 139, 745, 889, 951, 6925, 0 }; + static ulong[] dim796Kuo2Init = { 1, 3, 1, 13, 15, 33, 97, 217, 333, 295, 683, 397, 3889, 0 }; + static ulong[] dim797Kuo2Init = { 1, 3, 5, 15, 17, 57, 47, 173, 15, 77, 863, 1441, 6851, 0 }; + static ulong[] dim798Kuo2Init = { 1, 3, 5, 7, 3, 43, 21, 37, 349, 1021, 725, 1985, 481, 0 }; + static ulong[] dim799Kuo2Init = { 1, 1, 1, 13, 9, 45, 85, 177, 15, 915, 187, 15, 6621, 0 }; + static ulong[] dim800Kuo2Init = { 1, 3, 5, 11, 5, 29, 113, 95, 461, 607, 1637, 1897, 721, 0 }; + static ulong[] dim801Kuo2Init = { 1, 3, 1, 11, 13, 23, 55, 169, 29, 803, 1433, 2113, 7255, 0 }; + static ulong[] dim802Kuo2Init = { 1, 1, 5, 3, 31, 1, 45, 251, 129, 267, 1489, 427, 4993, 0 }; + static ulong[] dim803Kuo2Init = { 1, 1, 1, 9, 9, 11, 19, 31, 493, 195, 1545, 2681, 2187, 0 }; + static ulong[] dim804Kuo2Init = { 1, 3, 1, 7, 3, 51, 121, 149, 325, 921, 241, 999, 6039, 0 }; + static ulong[] dim805Kuo2Init = { 1, 3, 3, 15, 17, 37, 41, 157, 209, 587, 1351, 2353, 1197, 0 }; + static ulong[] dim806Kuo2Init = { 1, 1, 5, 13, 13, 55, 45, 3, 475, 9, 11, 3175, 2185, 0 }; + static ulong[] dim807Kuo2Init = { 1, 3, 5, 13, 31, 33, 63, 149, 463, 493, 1483, 1457, 6051, 0 }; + static ulong[] dim808Kuo2Init = { 1, 1, 1, 3, 3, 11, 119, 177, 207, 631, 105, 263, 2533, 0 }; + static ulong[] dim809Kuo2Init = { 1, 1, 1, 15, 23, 27, 73, 77, 143, 523, 1883, 3289, 1685, 0 }; + static ulong[] dim810Kuo2Init = { 1, 3, 1, 5, 21, 31, 25, 183, 71, 679, 1697, 3473, 4233, 0 }; + static ulong[] dim811Kuo2Init = { 1, 1, 7, 15, 9, 13, 103, 125, 223, 83, 1255, 2755, 1447, 0 }; + static ulong[] dim812Kuo2Init = { 1, 3, 5, 15, 15, 51, 69, 101, 369, 463, 1515, 3485, 1871, 0 }; + static ulong[] dim813Kuo2Init = { 1, 3, 5, 7, 21, 31, 55, 223, 477, 995, 147, 387, 7917, 0 }; + static ulong[] dim814Kuo2Init = { 1, 3, 5, 5, 7, 31, 73, 243, 283, 949, 705, 449, 3309, 0 }; + static ulong[] dim815Kuo2Init = { 1, 1, 5, 9, 15, 5, 25, 219, 379, 1013, 1683, 703, 4855, 0 }; + static ulong[] dim816Kuo2Init = { 1, 1, 7, 15, 25, 15, 99, 217, 265, 851, 149, 1557, 8107, 0 }; + static ulong[] dim817Kuo2Init = { 1, 3, 3, 5, 1, 59, 35, 119, 245, 9, 765, 833, 1707, 0 }; + static ulong[] dim818Kuo2Init = { 1, 1, 1, 13, 23, 49, 25, 153, 215, 365, 1943, 2975, 1301, 0 }; + static ulong[] dim819Kuo2Init = { 1, 3, 5, 7, 15, 45, 25, 215, 225, 431, 1161, 2389, 1969, 0 }; + static ulong[] dim820Kuo2Init = { 1, 3, 5, 9, 19, 31, 121, 189, 331, 23, 419, 3171, 6241, 0 }; + static ulong[] dim821Kuo2Init = { 1, 1, 5, 5, 17, 39, 69, 215, 307, 827, 557, 3251, 3211, 0 }; + static ulong[] dim822Kuo2Init = { 1, 1, 3, 11, 31, 27, 23, 119, 463, 605, 453, 1573, 1981, 0 }; + static ulong[] dim823Kuo2Init = { 1, 1, 5, 11, 1, 15, 37, 111, 481, 331, 1481, 1013, 3259, 0 }; + static ulong[] dim824Kuo2Init = { 1, 1, 1, 11, 21, 39, 25, 183, 351, 553, 3, 3969, 2551, 0 }; + static ulong[] dim825Kuo2Init = { 1, 3, 7, 1, 19, 5, 3, 55, 483, 373, 1529, 535, 4215, 0 }; + static ulong[] dim826Kuo2Init = { 1, 1, 3, 1, 25, 61, 89, 197, 465, 493, 661, 2361, 4211, 0 }; + static ulong[] dim827Kuo2Init = { 1, 3, 1, 9, 29, 61, 59, 175, 389, 973, 1763, 4077, 6211, 0 }; + static ulong[] dim828Kuo2Init = { 1, 3, 1, 7, 11, 41, 117, 75, 291, 125, 273, 5, 8169, 0 }; + static ulong[] dim829Kuo2Init = { 1, 1, 5, 11, 21, 53, 121, 31, 451, 631, 1901, 4059, 6801, 0 }; + static ulong[] dim830Kuo2Init = { 1, 3, 7, 3, 13, 33, 51, 247, 409, 881, 935, 1927, 1559, 0 }; + static ulong[] dim831Kuo2Init = { 1, 1, 3, 13, 15, 51, 105, 209, 159, 333, 325, 3699, 5461, 0 }; + static ulong[] dim832Kuo2Init = { 1, 3, 3, 5, 17, 7, 47, 57, 59, 673, 611, 253, 1531, 0 }; + static ulong[] dim833Kuo2Init = { 1, 1, 7, 1, 19, 27, 15, 189, 319, 649, 1593, 875, 8187, 0 }; + static ulong[] dim834Kuo2Init = { 1, 1, 1, 3, 15, 17, 81, 183, 409, 433, 679, 1881, 7827, 0 }; + static ulong[] dim835Kuo2Init = { 1, 1, 3, 9, 23, 37, 83, 235, 225, 599, 1979, 2871, 1353, 0 }; + static ulong[] dim836Kuo2Init = { 1, 1, 7, 7, 27, 11, 93, 115, 339, 233, 1733, 2071, 3187, 0 }; + static ulong[] dim837Kuo2Init = { 1, 1, 1, 7, 27, 47, 61, 73, 361, 621, 1907, 3103, 1873, 0 }; + static ulong[] dim838Kuo2Init = { 1, 1, 1, 9, 9, 13, 67, 161, 21, 953, 1101, 2255, 4841, 0 }; + static ulong[] dim839Kuo2Init = { 1, 3, 7, 7, 29, 39, 31, 73, 351, 401, 441, 4085, 2829, 0 }; + static ulong[] dim840Kuo2Init = { 1, 1, 5, 15, 9, 23, 127, 111, 309, 955, 623, 1995, 1961, 0 }; + static ulong[] dim841Kuo2Init = { 1, 3, 5, 9, 3, 3, 27, 91, 287, 73, 1449, 1347, 8069, 0 }; + static ulong[] dim842Kuo2Init = { 1, 1, 5, 3, 9, 49, 87, 3, 59, 193, 1999, 2295, 2247, 0 }; + static ulong[] dim843Kuo2Init = { 1, 3, 3, 3, 21, 21, 97, 47, 195, 65, 1281, 1411, 6503, 0 }; + static ulong[] dim844Kuo2Init = { 1, 1, 7, 13, 1, 11, 85, 195, 429, 71, 1053, 3623, 2921, 0 }; + static ulong[] dim845Kuo2Init = { 1, 3, 1, 5, 17, 15, 105, 155, 291, 889, 1997, 3629, 7025, 0 }; + static ulong[] dim846Kuo2Init = { 1, 1, 3, 7, 9, 3, 79, 41, 21, 819, 1665, 4021, 7057, 0 }; + static ulong[] dim847Kuo2Init = { 1, 1, 3, 1, 1, 23, 73, 5, 75, 435, 889, 2577, 697, 0 }; + static ulong[] dim848Kuo2Init = { 1, 3, 7, 1, 1, 5, 77, 183, 109, 159, 1463, 2689, 7799, 0 }; + static ulong[] dim849Kuo2Init = { 1, 1, 1, 13, 29, 55, 123, 247, 509, 909, 247, 3053, 7301, 0 }; + static ulong[] dim850Kuo2Init = { 1, 1, 5, 13, 7, 23, 43, 177, 59, 643, 1517, 1869, 3269, 0 }; + static ulong[] dim851Kuo2Init = { 1, 3, 1, 9, 7, 43, 3, 13, 387, 893, 1013, 7, 7481, 0 }; + static ulong[] dim852Kuo2Init = { 1, 1, 1, 1, 9, 35, 111, 199, 77, 375, 981, 3475, 2339, 0 }; + static ulong[] dim853Kuo2Init = { 1, 3, 5, 7, 5, 13, 27, 5, 113, 65, 1785, 1517, 8027, 0 }; + static ulong[] dim854Kuo2Init = { 1, 3, 7, 5, 25, 47, 15, 7, 45, 441, 7, 1601, 6543, 0 }; + static ulong[] dim855Kuo2Init = { 1, 1, 7, 3, 17, 59, 71, 93, 441, 763, 769, 1977, 287, 0 }; + static ulong[] dim856Kuo2Init = { 1, 1, 7, 11, 29, 23, 61, 199, 469, 757, 1473, 2625, 5909, 0 }; + static ulong[] dim857Kuo2Init = { 1, 1, 5, 11, 27, 47, 41, 91, 457, 1003, 217, 401, 8113, 0 }; + static ulong[] dim858Kuo2Init = { 1, 1, 5, 7, 1, 33, 43, 45, 169, 485, 191, 615, 5141, 0 }; + static ulong[] dim859Kuo2Init = { 1, 3, 1, 5, 5, 53, 19, 185, 189, 681, 1685, 661, 6825, 0 }; + static ulong[] dim860Kuo2Init = { 1, 3, 3, 1, 1, 7, 47, 27, 275, 63, 1029, 449, 4665, 0 }; + static ulong[] dim861Kuo2Init = { 1, 3, 3, 1, 3, 31, 1, 77, 275, 871, 1031, 1025, 4683, 0 }; + static ulong[] dim862Kuo2Init = { 1, 1, 3, 3, 9, 35, 39, 43, 363, 129, 431, 1351, 8037, 0 }; + static ulong[] dim863Kuo2Init = { 1, 1, 5, 3, 3, 39, 29, 99, 441, 819, 175, 3503, 4911, 0 }; + static ulong[] dim864Kuo2Init = { 1, 3, 5, 13, 9, 17, 87, 5, 311, 307, 659, 2795, 4055, 0 }; + static ulong[] dim865Kuo2Init = { 1, 1, 3, 13, 13, 51, 69, 99, 65, 257, 87, 1407, 3157, 0 }; + static ulong[] dim866Kuo2Init = { 1, 1, 5, 9, 19, 41, 97, 231, 85, 743, 637, 755, 6209, 0 }; + static ulong[] dim867Kuo2Init = { 1, 1, 5, 15, 21, 63, 81, 35, 477, 39, 873, 3679, 6477, 0 }; + static ulong[] dim868Kuo2Init = { 1, 1, 7, 13, 23, 37, 115, 87, 171, 33, 1779, 3169, 3205, 0 }; + static ulong[] dim869Kuo2Init = { 1, 3, 7, 11, 9, 41, 111, 9, 5, 441, 1677, 311, 1019, 0 }; + static ulong[] dim870Kuo2Init = { 1, 1, 5, 15, 7, 23, 7, 181, 461, 357, 187, 3461, 6689, 0 }; + static ulong[] dim871Kuo2Init = { 1, 1, 3, 11, 15, 37, 101, 125, 271, 205, 57, 3361, 3965, 0 }; + static ulong[] dim872Kuo2Init = { 1, 3, 3, 9, 25, 41, 97, 133, 39, 383, 669, 4007, 25, 0 }; + static ulong[] dim873Kuo2Init = { 1, 3, 7, 13, 17, 13, 79, 61, 145, 567, 1079, 287, 467, 0 }; + static ulong[] dim874Kuo2Init = { 1, 1, 5, 1, 7, 47, 97, 131, 119, 1013, 1991, 741, 27, 0 }; + static ulong[] dim875Kuo2Init = { 1, 3, 5, 9, 23, 21, 71, 209, 239, 801, 133, 2891, 1141, 0 }; + static ulong[] dim876Kuo2Init = { 1, 1, 7, 9, 17, 11, 109, 251, 127, 447, 1257, 3831, 1511, 0 }; + static ulong[] dim877Kuo2Init = { 1, 3, 1, 13, 21, 9, 69, 241, 61, 521, 1281, 3499, 4001, 0 }; + static ulong[] dim878Kuo2Init = { 1, 1, 5, 15, 5, 23, 117, 111, 159, 861, 295, 3403, 981, 0 }; + static ulong[] dim879Kuo2Init = { 1, 3, 3, 5, 3, 37, 85, 129, 281, 261, 1753, 1399, 43, 0 }; + static ulong[] dim880Kuo2Init = { 1, 1, 5, 5, 3, 49, 67, 221, 3, 143, 617, 2579, 373, 0 }; + static ulong[] dim881Kuo2Init = { 1, 3, 5, 11, 29, 49, 59, 47, 21, 725, 655, 3467, 2375, 0 }; + static ulong[] dim882Kuo2Init = { 1, 3, 3, 13, 15, 43, 19, 185, 411, 299, 1351, 3543, 5429, 0 }; + static ulong[] dim883Kuo2Init = { 1, 1, 5, 11, 19, 63, 19, 167, 439, 627, 1729, 245, 193, 0 }; + static ulong[] dim884Kuo2Init = { 1, 1, 3, 1, 5, 5, 115, 127, 295, 321, 1167, 3187, 6165, 0 }; + static ulong[] dim885Kuo2Init = { 1, 3, 1, 9, 9, 51, 87, 205, 211, 427, 1817, 3169, 1469, 0 }; + static ulong[] dim886Kuo2Init = { 1, 3, 1, 15, 27, 57, 15, 199, 87, 361, 583, 2467, 1367, 0 }; + static ulong[] dim887Kuo2Init = { 1, 1, 1, 11, 27, 7, 53, 173, 505, 839, 929, 3977, 7667, 0 }; + static ulong[] dim888Kuo2Init = { 1, 3, 3, 13, 7, 37, 51, 109, 249, 233, 899, 3991, 6667, 0 }; + static ulong[] dim889Kuo2Init = { 1, 3, 1, 11, 17, 23, 105, 213, 425, 175, 869, 3185, 6301, 0 }; + static ulong[] dim890Kuo2Init = { 1, 1, 5, 5, 17, 47, 5, 135, 497, 227, 1135, 689, 5047, 0 }; + static ulong[] dim891Kuo2Init = { 1, 3, 3, 11, 5, 49, 29, 177, 325, 727, 1719, 1805, 3361, 0 }; + static ulong[] dim892Kuo2Init = { 1, 1, 3, 3, 11, 7, 87, 169, 27, 137, 1835, 1377, 4915, 0 }; + static ulong[] dim893Kuo2Init = { 1, 3, 5, 5, 21, 53, 99, 137, 133, 599, 479, 2859, 6731, 0 }; + static ulong[] dim894Kuo2Init = { 1, 1, 5, 5, 15, 15, 31, 239, 183, 167, 1799, 1533, 309, 0 }; + static ulong[] dim895Kuo2Init = { 1, 3, 5, 15, 23, 51, 85, 133, 51, 991, 899, 3777, 2231, 0 }; + static ulong[] dim896Kuo2Init = { 1, 1, 3, 1, 15, 19, 29, 5, 415, 531, 253, 49, 7197, 0 }; + static ulong[] dim897Kuo2Init = { 1, 1, 5, 15, 21, 23, 41, 213, 189, 579, 1181, 3425, 8037, 0 }; + static ulong[] dim898Kuo2Init = { 1, 1, 5, 13, 9, 63, 21, 195, 71, 137, 1283, 2895, 3301, 0 }; + static ulong[] dim899Kuo2Init = { 1, 1, 7, 1, 11, 5, 103, 183, 403, 177, 1561, 201, 2843, 0 }; + static ulong[] dim900Kuo2Init = { 1, 3, 3, 9, 19, 15, 85, 123, 273, 891, 493, 3761, 557, 0 }; + static ulong[] dim901Kuo2Init = { 1, 3, 7, 9, 9, 23, 123, 243, 71, 137, 1937, 3199, 6865, 0 }; + static ulong[] dim902Kuo2Init = { 1, 1, 1, 15, 15, 55, 119, 203, 449, 969, 181, 2573, 3261, 0 }; + static ulong[] dim903Kuo2Init = { 1, 1, 1, 9, 29, 9, 87, 117, 85, 369, 911, 1203, 7287, 0 }; + static ulong[] dim904Kuo2Init = { 1, 1, 1, 7, 1, 35, 9, 85, 253, 123, 67, 2089, 4693, 0 }; + static ulong[] dim905Kuo2Init = { 1, 3, 5, 15, 11, 13, 43, 97, 407, 1011, 1839, 525, 6809, 0 }; + static ulong[] dim906Kuo2Init = { 1, 3, 3, 7, 11, 49, 5, 29, 299, 35, 1883, 763, 3099, 0 }; + static ulong[] dim907Kuo2Init = { 1, 3, 3, 13, 31, 5, 61, 79, 409, 1001, 1057, 1673, 4689, 0 }; + static ulong[] dim908Kuo2Init = { 1, 1, 3, 7, 23, 53, 23, 243, 335, 847, 1011, 659, 3739, 0 }; + static ulong[] dim909Kuo2Init = { 1, 3, 5, 1, 15, 55, 15, 161, 417, 225, 227, 3933, 5625, 0 }; + static ulong[] dim910Kuo2Init = { 1, 3, 7, 11, 25, 1, 75, 33, 401, 777, 1999, 1649, 1269, 0 }; + static ulong[] dim911Kuo2Init = { 1, 3, 5, 5, 3, 1, 13, 99, 447, 579, 225, 3851, 5379, 0 }; + static ulong[] dim912Kuo2Init = { 1, 1, 3, 13, 19, 33, 39, 93, 133, 889, 113, 3983, 1115, 0 }; + static ulong[] dim913Kuo2Init = { 1, 3, 5, 13, 1, 47, 113, 231, 461, 653, 1965, 849, 4513, 0 }; + static ulong[] dim914Kuo2Init = { 1, 1, 3, 1, 23, 7, 105, 115, 463, 385, 1355, 1417, 6341, 0 }; + static ulong[] dim915Kuo2Init = { 1, 1, 5, 7, 9, 27, 123, 193, 5, 735, 733, 2385, 6569, 0 }; + static ulong[] dim916Kuo2Init = { 1, 3, 1, 11, 13, 51, 53, 15, 289, 433, 951, 3657, 5239, 0 }; + static ulong[] dim917Kuo2Init = { 1, 1, 7, 3, 7, 59, 69, 57, 471, 247, 259, 2617, 47, 0 }; + static ulong[] dim918Kuo2Init = { 1, 3, 7, 13, 5, 41, 45, 67, 363, 295, 1715, 3567, 2457, 0 }; + static ulong[] dim919Kuo2Init = { 1, 1, 5, 3, 21, 19, 79, 37, 273, 613, 475, 3989, 3779, 0 }; + static ulong[] dim920Kuo2Init = { 1, 1, 5, 3, 21, 11, 53, 117, 367, 295, 1027, 2579, 2717, 0 }; + static ulong[] dim921Kuo2Init = { 1, 1, 5, 7, 29, 1, 47, 185, 377, 267, 1375, 801, 5967, 0 }; + static ulong[] dim922Kuo2Init = { 1, 3, 3, 3, 15, 5, 51, 183, 249, 789, 785, 1459, 7865, 0 }; + static ulong[] dim923Kuo2Init = { 1, 3, 5, 5, 31, 17, 89, 9, 247, 67, 1259, 3099, 2805, 0 }; + static ulong[] dim924Kuo2Init = { 1, 3, 3, 11, 31, 51, 55, 37, 201, 779, 1235, 1905, 1995, 0 }; + static ulong[] dim925Kuo2Init = { 1, 3, 1, 1, 27, 31, 25, 37, 443, 399, 1911, 3951, 4311, 0 }; + static ulong[] dim926Kuo2Init = { 1, 3, 3, 11, 11, 13, 69, 209, 295, 431, 573, 1781, 7767, 0 }; + static ulong[] dim927Kuo2Init = { 1, 3, 1, 3, 23, 55, 57, 29, 137, 407, 1339, 1411, 123, 0 }; + static ulong[] dim928Kuo2Init = { 1, 3, 3, 13, 5, 15, 7, 29, 353, 143, 133, 2351, 1555, 0 }; + static ulong[] dim929Kuo2Init = { 1, 1, 7, 9, 17, 53, 61, 197, 245, 327, 147, 3231, 1825, 0 }; + static ulong[] dim930Kuo2Init = { 1, 3, 5, 3, 27, 55, 31, 15, 429, 703, 1863, 3697, 2169, 0 }; + static ulong[] dim931Kuo2Init = { 1, 3, 3, 1, 19, 45, 61, 179, 471, 219, 1127, 3521, 8065, 0 }; + static ulong[] dim932Kuo2Init = { 1, 3, 5, 5, 17, 21, 77, 117, 331, 979, 175, 3155, 1589, 0 }; + static ulong[] dim933Kuo2Init = { 1, 3, 1, 9, 13, 41, 25, 221, 115, 333, 1851, 543, 5479, 0 }; + static ulong[] dim934Kuo2Init = { 1, 3, 3, 13, 25, 35, 113, 107, 21, 85, 815, 3013, 8067, 0 }; + static ulong[] dim935Kuo2Init = { 1, 1, 3, 9, 23, 37, 55, 193, 301, 463, 1361, 3455, 5745, 0 }; + static ulong[] dim936Kuo2Init = { 1, 3, 5, 7, 3, 63, 73, 83, 35, 709, 719, 1133, 6711, 0 }; + static ulong[] dim937Kuo2Init = { 1, 1, 5, 7, 11, 7, 67, 199, 285, 527, 1181, 39, 5639, 0 }; + static ulong[] dim938Kuo2Init = { 1, 3, 3, 3, 17, 13, 33, 213, 97, 499, 1651, 3369, 6001, 0 }; + static ulong[] dim939Kuo2Init = { 1, 1, 3, 1, 15, 37, 67, 31, 225, 205, 1009, 2579, 331, 0 }; + static ulong[] dim940Kuo2Init = { 1, 1, 7, 1, 29, 3, 91, 153, 395, 89, 2019, 1297, 7035, 0 }; + static ulong[] dim941Kuo2Init = { 1, 3, 3, 5, 29, 31, 65, 137, 289, 351, 677, 3305, 5073, 0 }; + static ulong[] dim942Kuo2Init = { 1, 1, 3, 13, 15, 21, 43, 227, 399, 921, 123, 3199, 6925, 0 }; + static ulong[] dim943Kuo2Init = { 1, 1, 7, 13, 17, 11, 107, 251, 55, 525, 869, 209, 6209, 0 }; + static ulong[] dim944Kuo2Init = { 1, 1, 3, 11, 29, 39, 123, 171, 223, 441, 525, 2583, 71, 0 }; + static ulong[] dim945Kuo2Init = { 1, 3, 7, 9, 5, 3, 3, 205, 119, 631, 1997, 3105, 6483, 0 }; + static ulong[] dim946Kuo2Init = { 1, 1, 7, 7, 23, 37, 79, 245, 401, 241, 1471, 2941, 4389, 0 }; + static ulong[] dim947Kuo2Init = { 1, 3, 1, 13, 25, 7, 43, 215, 155, 805, 1497, 387, 2045, 0 }; + static ulong[] dim948Kuo2Init = { 1, 1, 3, 3, 7, 37, 115, 39, 139, 555, 1325, 2351, 6045, 0 }; + static ulong[] dim949Kuo2Init = { 1, 1, 5, 7, 3, 53, 35, 103, 505, 361, 457, 2495, 1325, 0 }; + static ulong[] dim950Kuo2Init = { 1, 3, 7, 13, 21, 33, 39, 81, 465, 601, 1131, 2977, 1409, 0 }; + static ulong[] dim951Kuo2Init = { 1, 1, 5, 5, 25, 1, 21, 241, 255, 663, 1509, 2455, 5705, 0 }; + static ulong[] dim952Kuo2Init = { 1, 1, 7, 13, 1, 47, 91, 195, 195, 503, 1931, 1681, 5131, 0 }; + static ulong[] dim953Kuo2Init = { 1, 1, 3, 9, 27, 37, 103, 21, 237, 677, 1949, 357, 2781, 0 }; + static ulong[] dim954Kuo2Init = { 1, 3, 7, 9, 29, 51, 107, 49, 251, 433, 1235, 4041, 2971, 0 }; + static ulong[] dim955Kuo2Init = { 1, 3, 3, 1, 19, 37, 113, 75, 365, 145, 93, 1185, 1871, 0 }; + static ulong[] dim956Kuo2Init = { 1, 1, 5, 5, 25, 15, 113, 239, 27, 321, 1351, 1441, 3333, 0 }; + static ulong[] dim957Kuo2Init = { 1, 1, 5, 13, 31, 35, 103, 83, 111, 573, 59, 3753, 5667, 0 }; + static ulong[] dim958Kuo2Init = { 1, 1, 5, 13, 1, 43, 75, 115, 397, 187, 1669, 3837, 5219, 0 }; + static ulong[] dim959Kuo2Init = { 1, 1, 3, 1, 23, 13, 65, 145, 271, 909, 1517, 1659, 7975, 0 }; + static ulong[] dim960Kuo2Init = { 1, 1, 7, 15, 21, 23, 1, 33, 37, 313, 687, 2375, 555, 0 }; + static ulong[] dim961Kuo2Init = { 1, 1, 7, 13, 1, 35, 11, 157, 295, 403, 1295, 3301, 4805, 0 }; + static ulong[] dim962Kuo2Init = { 1, 3, 1, 13, 9, 27, 3, 111, 133, 395, 981, 2399, 7009, 0 }; + static ulong[] dim963Kuo2Init = { 1, 1, 7, 15, 23, 11, 75, 31, 5, 599, 1589, 2243, 3263, 0 }; + static ulong[] dim964Kuo2Init = { 1, 1, 3, 9, 7, 49, 31, 5, 457, 93, 221, 2463, 2287, 0 }; + static ulong[] dim965Kuo2Init = { 1, 1, 5, 3, 9, 31, 49, 5, 481, 145, 53, 2477, 5569, 0 }; + static ulong[] dim966Kuo2Init = { 1, 1, 1, 1, 19, 47, 59, 83, 19, 887, 335, 2305, 6265, 0 }; + static ulong[] dim967Kuo2Init = { 1, 3, 7, 15, 27, 15, 93, 37, 213, 17, 311, 3159, 6911, 0 }; + static ulong[] dim968Kuo2Init = { 1, 1, 3, 9, 19, 47, 93, 31, 489, 731, 1905, 1675, 1, 0 }; + static ulong[] dim969Kuo2Init = { 1, 1, 1, 7, 9, 3, 17, 185, 203, 963, 521, 2797, 7511, 0 }; + static ulong[] dim970Kuo2Init = { 1, 3, 7, 11, 31, 27, 47, 147, 467, 505, 1991, 2247, 4207, 0 }; + static ulong[] dim971Kuo2Init = { 1, 3, 1, 5, 9, 11, 89, 199, 359, 723, 1203, 1511, 7915, 0 }; + static ulong[] dim972Kuo2Init = { 1, 3, 5, 9, 27, 63, 93, 19, 305, 641, 997, 1725, 5681, 0 }; + static ulong[] dim973Kuo2Init = { 1, 3, 3, 3, 13, 19, 9, 43, 99, 111, 1353, 935, 7765, 0 }; + static ulong[] dim974Kuo2Init = { 1, 3, 1, 9, 5, 39, 109, 79, 497, 351, 1345, 3019, 5909, 0 }; + static ulong[] dim975Kuo2Init = { 1, 1, 3, 1, 13, 29, 11, 199, 31, 443, 1587, 3397, 7045, 0 }; + static ulong[] dim976Kuo2Init = { 1, 1, 1, 11, 7, 9, 49, 107, 153, 207, 887, 2135, 1389, 0 }; + static ulong[] dim977Kuo2Init = { 1, 1, 1, 3, 29, 53, 111, 143, 421, 521, 1099, 1709, 7027, 0 }; + static ulong[] dim978Kuo2Init = { 1, 1, 5, 5, 5, 19, 127, 99, 501, 819, 1729, 1701, 5829, 0 }; + static ulong[] dim979Kuo2Init = { 1, 3, 7, 5, 7, 15, 43, 49, 223, 793, 889, 793, 271, 0 }; + static ulong[] dim980Kuo2Init = { 1, 3, 5, 11, 27, 27, 55, 69, 185, 511, 951, 2821, 5357, 0 }; + static ulong[] dim981Kuo2Init = { 1, 3, 7, 13, 17, 19, 31, 9, 401, 397, 829, 1063, 693, 0 }; + static ulong[] dim982Kuo2Init = { 1, 1, 7, 9, 21, 13, 75, 13, 327, 929, 955, 1421, 2809, 0 }; + static ulong[] dim983Kuo2Init = { 1, 1, 3, 15, 17, 5, 115, 231, 29, 23, 1743, 779, 5083, 0 }; + static ulong[] dim984Kuo2Init = { 1, 1, 7, 11, 9, 51, 93, 3, 155, 111, 243, 3889, 6733, 0 }; + static ulong[] dim985Kuo2Init = { 1, 1, 5, 9, 29, 63, 119, 145, 391, 1021, 503, 555, 4657, 0 }; + static ulong[] dim986Kuo2Init = { 1, 1, 1, 15, 15, 41, 69, 131, 365, 195, 1809, 2773, 4067, 0 }; + static ulong[] dim987Kuo2Init = { 1, 1, 1, 15, 5, 3, 119, 63, 243, 759, 2037, 3443, 5771, 0 }; + static ulong[] dim988Kuo2Init = { 1, 3, 5, 5, 1, 1, 21, 163, 481, 781, 769, 3031, 2707, 0 }; + static ulong[] dim989Kuo2Init = { 1, 1, 5, 7, 15, 29, 3, 119, 13, 977, 1759, 2327, 3961, 0 }; + static ulong[] dim990Kuo2Init = { 1, 1, 3, 1, 9, 25, 55, 131, 335, 289, 1049, 3589, 3131, 0 }; + static ulong[] dim991Kuo2Init = { 1, 1, 7, 1, 27, 55, 113, 97, 249, 817, 1497, 3773, 6183, 0 }; + static ulong[] dim992Kuo2Init = { 1, 3, 3, 7, 3, 15, 11, 157, 201, 145, 1741, 721, 4945, 0 }; + static ulong[] dim993Kuo2Init = { 1, 1, 7, 3, 19, 9, 123, 151, 169, 841, 65, 2463, 5357, 0 }; + static ulong[] dim994Kuo2Init = { 1, 3, 1, 11, 5, 31, 123, 69, 93, 541, 131, 1469, 5791, 0 }; + static ulong[] dim995Kuo2Init = { 1, 3, 5, 1, 25, 23, 115, 69, 333, 457, 17, 1155, 523, 0 }; + static ulong[] dim996Kuo2Init = { 1, 3, 5, 11, 11, 51, 21, 145, 209, 557, 1109, 2293, 4631, 0 }; + static ulong[] dim997Kuo2Init = { 1, 1, 7, 5, 11, 21, 107, 41, 409, 485, 1745, 3471, 1699, 0 }; + static ulong[] dim998Kuo2Init = { 1, 1, 3, 7, 5, 47, 65, 79, 299, 191, 381, 3803, 6499, 0 }; + static ulong[] dim999Kuo2Init = { 1, 3, 3, 7, 19, 11, 73, 69, 461, 777, 1871, 47, 1281, 0 }; + static ulong[] dim1000Kuo2Init = { 1, 3, 5, 7, 13, 39, 63, 103, 103, 845, 1023, 3241, 1291, 0 }; + static ulong[] dim1001Kuo2Init = { 1, 1, 5, 13, 3, 11, 103, 135, 403, 801, 847, 371, 6243, 0 }; + static ulong[] dim1002Kuo2Init = { 1, 3, 1, 5, 21, 57, 19, 205, 33, 399, 777, 2981, 2365, 0 }; + static ulong[] dim1003Kuo2Init = { 1, 1, 1, 5, 17, 11, 105, 23, 243, 581, 1391, 1509, 8009, 0 }; + static ulong[] dim1004Kuo2Init = { 1, 3, 3, 3, 11, 13, 85, 107, 181, 89, 1323, 3059, 5097, 0 }; + static ulong[] dim1005Kuo2Init = { 1, 1, 1, 15, 1, 29, 57, 221, 389, 127, 841, 1727, 6217, 0 }; + static ulong[] dim1006Kuo2Init = { 1, 3, 1, 9, 25, 51, 89, 67, 257, 921, 621, 1523, 3449, 0 }; + static ulong[] dim1007Kuo2Init = { 1, 3, 5, 5, 25, 15, 25, 47, 29, 775, 1925, 3819, 8063, 0 }; + static ulong[] dim1008Kuo2Init = { 1, 1, 1, 5, 25, 55, 89, 75, 47, 135, 1155, 1923, 2241, 0 }; + static ulong[] dim1009Kuo2Init = { 1, 3, 5, 9, 29, 5, 55, 43, 355, 879, 127, 3565, 2583, 0 }; + static ulong[] dim1010Kuo2Init = { 1, 1, 3, 13, 23, 47, 27, 63, 217, 119, 357, 423, 5897, 0 }; + static ulong[] dim1011Kuo2Init = { 1, 3, 5, 1, 23, 1, 89, 255, 381, 175, 1069, 3809, 1743, 0 }; + static ulong[] dim1012Kuo2Init = { 1, 1, 7, 3, 7, 35, 47, 159, 347, 543, 187, 1103, 5019, 0 }; + static ulong[] dim1013Kuo2Init = { 1, 1, 1, 7, 19, 3, 89, 15, 487, 541, 625, 1711, 3713, 0 }; + static ulong[] dim1014Kuo2Init = { 1, 1, 5, 15, 17, 61, 13, 45, 359, 107, 1487, 121, 6919, 0 }; + static ulong[] dim1015Kuo2Init = { 1, 3, 3, 3, 1, 5, 99, 255, 147, 737, 1675, 4069, 7685, 0 }; + static ulong[] dim1016Kuo2Init = { 1, 3, 7, 1, 5, 33, 39, 217, 255, 833, 661, 3411, 7273, 0 }; + static ulong[] dim1017Kuo2Init = { 1, 3, 3, 5, 9, 41, 25, 223, 319, 45, 687, 3861, 2603, 0 }; + static ulong[] dim1018Kuo2Init = { 1, 1, 3, 15, 15, 43, 61, 163, 45, 835, 545, 561, 4895, 0 }; + static ulong[] dim1019Kuo2Init = { 1, 3, 7, 3, 21, 61, 65, 119, 337, 609, 1185, 2863, 1431, 0 }; + static ulong[] dim1020Kuo2Init = { 1, 1, 3, 3, 29, 49, 51, 173, 107, 21, 1655, 1333, 4703, 0 }; + static ulong[] dim1021Kuo2Init = { 1, 3, 1, 3, 27, 23, 111, 77, 3, 789, 943, 3089, 2865, 0 }; + static ulong[] dim1022Kuo2Init = { 1, 3, 1, 1, 5, 7, 85, 209, 317, 241, 1159, 2193, 229, 0 }; + static ulong[] dim1023Kuo2Init = { 1, 1, 3, 13, 23, 27, 115, 111, 265, 427, 1457, 2281, 2235, 0 }; + static ulong[] dim1024Kuo2Init = { 1, 3, 1, 13, 5, 51, 21, 125, 335, 359, 1189, 1095, 6843, 0 }; + static ulong[] dim1025Kuo2Init = { 1, 3, 5, 7, 5, 17, 93, 43, 297, 109, 1721, 3991, 6861, 0 }; + static ulong[] dim1026Kuo2Init = { 1, 3, 7, 7, 23, 45, 61, 149, 89, 1009, 937, 2477, 1617, 0 }; + static ulong[] dim1027Kuo2Init = { 1, 1, 3, 1, 23, 19, 21, 29, 481, 771, 261, 2377, 2323, 0 }; + static ulong[] dim1028Kuo2Init = { 1, 1, 3, 7, 29, 21, 99, 159, 219, 983, 1169, 667, 3073, 0 }; + static ulong[] dim1029Kuo2Init = { 1, 3, 5, 9, 7, 61, 69, 197, 29, 3, 1767, 2113, 689, 0 }; + static ulong[] dim1030Kuo2Init = { 1, 1, 3, 7, 9, 37, 45, 11, 405, 243, 661, 2545, 5185, 0 }; + static ulong[] dim1031Kuo2Init = { 1, 1, 7, 3, 7, 23, 13, 193, 91, 551, 1963, 2663, 7605, 0 }; + static ulong[] dim1032Kuo2Init = { 1, 1, 1, 1, 27, 17, 79, 251, 103, 33, 45, 2517, 3611, 0 }; + static ulong[] dim1033Kuo2Init = { 1, 3, 3, 1, 19, 57, 15, 175, 77, 299, 1805, 3331, 1365, 0 }; + static ulong[] dim1034Kuo2Init = { 1, 1, 3, 5, 31, 59, 51, 85, 359, 197, 679, 3017, 7929, 0 }; + static ulong[] dim1035Kuo2Init = { 1, 3, 7, 13, 15, 19, 71, 31, 69, 353, 489, 1167, 337, 0 }; + static ulong[] dim1036Kuo2Init = { 1, 1, 3, 13, 5, 33, 35, 33, 345, 63, 1775, 3475, 1375, 0 }; + static ulong[] dim1037Kuo2Init = { 1, 1, 3, 1, 29, 53, 109, 3, 191, 1011, 1043, 3057, 4757, 0 }; + static ulong[] dim1038Kuo2Init = { 1, 1, 5, 11, 3, 21, 101, 137, 155, 959, 683, 1407, 1239, 0 }; + static ulong[] dim1039Kuo2Init = { 1, 3, 5, 13, 3, 9, 117, 81, 143, 753, 561, 871, 2417, 0 }; + static ulong[] dim1040Kuo2Init = { 1, 1, 7, 7, 25, 11, 33, 173, 321, 487, 33, 551, 6613, 0 }; + static ulong[] dim1041Kuo2Init = { 1, 3, 5, 7, 3, 29, 9, 133, 251, 561, 975, 3153, 1115, 0 }; + static ulong[] dim1042Kuo2Init = { 1, 3, 5, 3, 1, 11, 89, 145, 33, 967, 365, 3661, 2917, 0 }; + static ulong[] dim1043Kuo2Init = { 1, 3, 7, 5, 21, 55, 49, 139, 507, 405, 99, 2819, 6541, 0 }; + static ulong[] dim1044Kuo2Init = { 1, 1, 7, 1, 13, 41, 77, 53, 185, 995, 2045, 1659, 1081, 0 }; + static ulong[] dim1045Kuo2Init = { 1, 3, 1, 3, 5, 29, 25, 111, 173, 793, 953, 2825, 673, 0 }; + static ulong[] dim1046Kuo2Init = { 1, 3, 1, 3, 13, 3, 73, 39, 143, 603, 253, 2879, 3827, 0 }; + static ulong[] dim1047Kuo2Init = { 1, 3, 1, 11, 3, 35, 93, 237, 401, 1005, 1047, 3065, 6285, 0 }; + static ulong[] dim1048Kuo2Init = { 1, 3, 1, 13, 7, 7, 17, 65, 107, 971, 999, 623, 6491, 0 }; + static ulong[] dim1049Kuo2Init = { 1, 3, 3, 11, 31, 1, 83, 111, 255, 969, 871, 3459, 2419, 0 }; + static ulong[] dim1050Kuo2Init = { 1, 3, 1, 7, 3, 49, 99, 27, 253, 937, 1237, 343, 6133, 0 }; + static ulong[] dim1051Kuo2Init = { 1, 1, 5, 11, 31, 7, 83, 75, 77, 583, 847, 2263, 1925, 0 }; + static ulong[] dim1052Kuo2Init = { 1, 1, 3, 11, 3, 37, 119, 229, 411, 953, 1087, 3005, 1521, 0 }; + static ulong[] dim1053Kuo2Init = { 1, 3, 7, 13, 5, 53, 125, 207, 297, 465, 1989, 1769, 5113, 0 }; + static ulong[] dim1054Kuo2Init = { 1, 3, 5, 11, 13, 13, 9, 105, 303, 641, 997, 929, 393, 0 }; + static ulong[] dim1055Kuo2Init = { 1, 3, 5, 9, 21, 21, 125, 49, 509, 993, 317, 2367, 2775, 0 }; + static ulong[] dim1056Kuo2Init = { 1, 3, 3, 9, 15, 1, 91, 101, 339, 625, 1521, 2285, 1847, 0 }; + static ulong[] dim1057Kuo2Init = { 1, 1, 5, 15, 15, 31, 57, 253, 407, 715, 1143, 3707, 5105, 0 }; + static ulong[] dim1058Kuo2Init = { 1, 3, 1, 5, 21, 1, 77, 139, 499, 777, 349, 1647, 1389, 0 }; + static ulong[] dim1059Kuo2Init = { 1, 3, 5, 5, 11, 55, 29, 209, 491, 823, 1961, 3833, 5825, 0 }; + static ulong[] dim1060Kuo2Init = { 1, 1, 7, 11, 3, 21, 43, 147, 83, 245, 139, 3585, 975, 0 }; + static ulong[] dim1061Kuo2Init = { 1, 1, 1, 3, 19, 9, 19, 251, 163, 85, 239, 2573, 1079, 0 }; + static ulong[] dim1062Kuo2Init = { 1, 1, 5, 13, 27, 35, 27, 191, 279, 589, 1737, 2759, 1691, 0 }; + static ulong[] dim1063Kuo2Init = { 1, 1, 7, 3, 17, 5, 47, 173, 183, 713, 667, 3683, 2167, 0 }; + static ulong[] dim1064Kuo2Init = { 1, 3, 5, 13, 25, 41, 29, 125, 173, 325, 1341, 481, 365, 0 }; + static ulong[] dim1065Kuo2Init = { 1, 3, 1, 5, 27, 61, 23, 11, 265, 255, 801, 921, 7145, 0 }; + static ulong[] dim1066Kuo2Init = { 1, 3, 5, 5, 27, 49, 27, 245, 253, 787, 1451, 2349, 2125, 0 }; + static ulong[] dim1067Kuo2Init = { 1, 1, 7, 7, 13, 31, 61, 215, 339, 315, 377, 1121, 2667, 0 }; + static ulong[] dim1068Kuo2Init = { 1, 3, 5, 9, 31, 63, 27, 115, 367, 939, 437, 1771, 1219, 0 }; + static ulong[] dim1069Kuo2Init = { 1, 1, 3, 5, 3, 7, 33, 147, 177, 249, 649, 2505, 4705, 0 }; + static ulong[] dim1070Kuo2Init = { 1, 3, 1, 9, 11, 31, 23, 237, 223, 311, 493, 1255, 2121, 0 }; + static ulong[] dim1071Kuo2Init = { 1, 3, 5, 7, 5, 43, 51, 1, 425, 115, 1487, 373, 3765, 0 }; + static ulong[] dim1072Kuo2Init = { 1, 3, 3, 9, 3, 11, 125, 31, 375, 73, 673, 1933, 7763, 0 }; + static ulong[] dim1073Kuo2Init = { 1, 1, 3, 7, 31, 43, 67, 177, 33, 693, 185, 137, 4869, 0 }; + static ulong[] dim1074Kuo2Init = { 1, 1, 1, 9, 21, 53, 111, 41, 249, 845, 193, 2519, 4745, 0 }; + static ulong[] dim1075Kuo2Init = { 1, 3, 5, 3, 11, 15, 11, 249, 325, 561, 411, 71, 6973, 0 }; + static ulong[] dim1076Kuo2Init = { 1, 1, 7, 5, 5, 13, 31, 113, 149, 475, 869, 627, 2789, 0 }; + static ulong[] dim1077Kuo2Init = { 1, 1, 1, 5, 7, 23, 49, 65, 201, 111, 1061, 393, 2101, 0 }; + static ulong[] dim1078Kuo2Init = { 1, 1, 3, 5, 23, 47, 49, 111, 315, 227, 1985, 3579, 875, 0 }; + static ulong[] dim1079Kuo2Init = { 1, 3, 5, 5, 21, 17, 101, 135, 475, 505, 51, 3203, 1735, 0 }; + static ulong[] dim1080Kuo2Init = { 1, 1, 7, 15, 19, 41, 53, 197, 117, 315, 1663, 143, 1081, 0 }; + static ulong[] dim1081Kuo2Init = { 1, 1, 3, 7, 5, 29, 87, 39, 235, 675, 1101, 1257, 4045, 0 }; + static ulong[] dim1082Kuo2Init = { 1, 3, 5, 15, 25, 49, 63, 125, 447, 181, 357, 3017, 6861, 0 }; + static ulong[] dim1083Kuo2Init = { 1, 1, 5, 15, 31, 21, 61, 197, 133, 85, 913, 3031, 855, 0 }; + static ulong[] dim1084Kuo2Init = { 1, 1, 5, 7, 31, 45, 111, 243, 277, 569, 1311, 125, 3417, 0 }; + static ulong[] dim1085Kuo2Init = { 1, 1, 3, 11, 9, 49, 127, 151, 407, 407, 915, 1831, 4093, 0 }; + static ulong[] dim1086Kuo2Init = { 1, 3, 5, 11, 3, 47, 69, 97, 315, 993, 845, 67, 39, 0 }; + static ulong[] dim1087Kuo2Init = { 1, 3, 3, 11, 1, 5, 105, 115, 293, 187, 1369, 3039, 6833, 0 }; + static ulong[] dim1088Kuo2Init = { 1, 3, 3, 15, 23, 19, 15, 59, 139, 523, 1599, 1773, 8059, 0 }; + static ulong[] dim1089Kuo2Init = { 1, 1, 1, 13, 3, 9, 39, 205, 115, 35, 1737, 2713, 3263, 0 }; + static ulong[] dim1090Kuo2Init = { 1, 1, 3, 7, 11, 41, 71, 61, 329, 11, 1069, 2565, 6359, 0 }; + static ulong[] dim1091Kuo2Init = { 1, 3, 7, 9, 1, 57, 5, 17, 117, 37, 827, 3449, 1297, 0 }; + static ulong[] dim1092Kuo2Init = { 1, 1, 5, 1, 29, 49, 3, 7, 145, 183, 1777, 2351, 6675, 0 }; + static ulong[] dim1093Kuo2Init = { 1, 1, 5, 7, 5, 57, 97, 61, 197, 713, 695, 2385, 1917, 0 }; + static ulong[] dim1094Kuo2Init = { 1, 3, 1, 11, 21, 49, 41, 133, 307, 473, 1983, 3693, 3241, 0 }; + static ulong[] dim1095Kuo2Init = { 1, 1, 5, 1, 3, 59, 47, 141, 49, 531, 1237, 3085, 5651, 0 }; + static ulong[] dim1096Kuo2Init = { 1, 1, 5, 1, 17, 21, 3, 101, 169, 475, 473, 255, 6637, 0 }; + static ulong[] dim1097Kuo2Init = { 1, 3, 5, 1, 19, 25, 71, 251, 327, 715, 1945, 1123, 4911, 0 }; + static ulong[] dim1098Kuo2Init = { 1, 1, 5, 3, 15, 55, 127, 221, 163, 281, 1391, 4083, 7995, 0 }; + static ulong[] dim1099Kuo2Init = { 1, 1, 3, 9, 27, 7, 65, 143, 433, 599, 1971, 2169, 813, 0 }; + static ulong[] dim1100Kuo2Init = { 1, 3, 3, 1, 9, 49, 107, 103, 381, 1005, 705, 2385, 5007, 0 }; + static ulong[] dim1101Kuo2Init = { 1, 3, 5, 7, 15, 45, 41, 175, 137, 1019, 1869, 2337, 3433, 0 }; + static ulong[] dim1102Kuo2Init = { 1, 3, 7, 15, 15, 51, 89, 193, 325, 391, 197, 2607, 6717, 0 }; + static ulong[] dim1103Kuo2Init = { 1, 3, 7, 1, 15, 11, 113, 245, 255, 481, 237, 3205, 4551, 0 }; + static ulong[] dim1104Kuo2Init = { 1, 3, 3, 1, 11, 19, 93, 97, 67, 793, 1165, 989, 4643, 0 }; + static ulong[] dim1105Kuo2Init = { 1, 1, 1, 15, 17, 51, 63, 37, 353, 745, 1439, 2599, 2771, 0 }; + static ulong[] dim1106Kuo2Init = { 1, 1, 7, 9, 7, 3, 87, 245, 257, 399, 311, 3063, 3801, 0 }; + static ulong[] dim1107Kuo2Init = { 1, 1, 5, 11, 13, 3, 83, 39, 165, 827, 1581, 2491, 2067, 0 }; + static ulong[] dim1108Kuo2Init = { 1, 3, 3, 3, 21, 3, 21, 95, 505, 971, 1599, 2479, 4155, 0 }; + static ulong[] dim1109Kuo2Init = { 1, 3, 1, 11, 11, 57, 115, 83, 473, 457, 2015, 1855, 1851, 0 }; + static ulong[] dim1110Kuo2Init = { 1, 3, 7, 11, 29, 7, 73, 203, 445, 771, 1225, 3587, 245, 0 }; + static ulong[] dim1111Kuo2Init = { 1, 3, 5, 1, 13, 53, 79, 245, 347, 277, 779, 653, 6213, 7661, 0 }; + static ulong[] dim1112Kuo2Init = { 1, 3, 5, 3, 17, 43, 31, 251, 177, 337, 157, 3171, 3813, 7787, 0 }; + static ulong[] dim1113Kuo2Init = { 1, 3, 5, 9, 23, 9, 7, 45, 65, 517, 1449, 1943, 4995, 2403, 0 }; + static ulong[] dim1114Kuo2Init = { 1, 3, 3, 9, 19, 45, 71, 91, 491, 113, 1041, 717, 681, 13331, 0 }; + static ulong[] dim1115Kuo2Init = { 1, 3, 5, 9, 15, 35, 19, 25, 119, 677, 1355, 3065, 6325, 7821, 0 }; + static ulong[] dim1116Kuo2Init = { 1, 3, 7, 5, 27, 63, 41, 117, 271, 327, 1731, 3501, 4489, 11119, 0 }; + static ulong[] dim1117Kuo2Init = { 1, 1, 3, 5, 11, 35, 51, 79, 347, 905, 857, 3647, 4773, 15111, 0 }; + static ulong[] dim1118Kuo2Init = { 1, 3, 7, 3, 21, 3, 19, 147, 429, 275, 1813, 1937, 4489, 7993, 0 }; + static ulong[] dim1119Kuo2Init = { 1, 3, 7, 9, 27, 59, 77, 179, 209, 897, 807, 1121, 7575, 9769, 0 }; + static ulong[] dim1120Kuo2Init = { 1, 3, 3, 9, 15, 39, 81, 183, 213, 419, 125, 1943, 5621, 9073, 0 }; + static ulong[] dim1121Kuo2Init = { 1, 3, 1, 7, 11, 41, 111, 169, 31, 807, 1277, 3293, 3233, 409, 0 }; + static ulong[] dim1122Kuo2Init = { 1, 1, 3, 11, 31, 11, 39, 69, 429, 185, 1523, 469, 5453, 12453, 0 }; + static ulong[] dim1123Kuo2Init = { 1, 1, 5, 13, 15, 59, 5, 179, 457, 803, 1503, 633, 7591, 8861, 0 }; + static ulong[] dim1124Kuo2Init = { 1, 3, 5, 13, 19, 47, 15, 37, 271, 361, 1403, 2043, 6671, 4171, 0 }; + static ulong[] dim1125Kuo2Init = { 1, 3, 3, 15, 3, 37, 107, 29, 505, 465, 955, 2431, 5899, 11363, 0 }; + static ulong[] dim1126Kuo2Init = { 1, 1, 3, 9, 11, 49, 71, 191, 197, 365, 757, 309, 3881, 9427, 0 }; + static ulong[] dim1127Kuo2Init = { 1, 1, 7, 13, 11, 9, 3, 109, 403, 403, 867, 325, 329, 13675, 0 }; + static ulong[] dim1128Kuo2Init = { 1, 3, 3, 7, 13, 61, 33, 125, 431, 797, 565, 4065, 6375, 10343, 0 }; + static ulong[] dim1129Kuo2Init = { 1, 1, 1, 1, 23, 59, 45, 103, 231, 829, 1197, 1547, 2319, 13541, 0 }; + static ulong[] dim1130Kuo2Init = { 1, 1, 7, 13, 17, 59, 119, 51, 305, 153, 571, 1323, 6427, 12291, 0 }; + static ulong[] dim1131Kuo2Init = { 1, 3, 3, 9, 21, 17, 27, 223, 311, 1015, 1925, 1497, 6407, 15517, 0 }; + static ulong[] dim1132Kuo2Init = { 1, 3, 1, 15, 13, 63, 99, 163, 35, 583, 787, 2679, 4991, 5933, 0 }; + static ulong[] dim1133Kuo2Init = { 1, 1, 3, 7, 31, 43, 77, 141, 153, 455, 745, 1377, 7363, 7301, 0 }; + static ulong[] dim1134Kuo2Init = { 1, 1, 3, 15, 23, 49, 1, 149, 393, 483, 1577, 1885, 7483, 9769, 0 }; + static ulong[] dim1135Kuo2Init = { 1, 1, 7, 11, 23, 5, 103, 143, 35, 899, 2001, 2643, 2533, 7827, 0 }; + static ulong[] dim1136Kuo2Init = { 1, 3, 5, 5, 13, 49, 121, 113, 75, 271, 1111, 535, 1255, 6977, 0 }; + static ulong[] dim1137Kuo2Init = { 1, 1, 1, 3, 25, 53, 11, 151, 107, 985, 1933, 2791, 4101, 14515, 0 }; + static ulong[] dim1138Kuo2Init = { 1, 3, 1, 7, 29, 39, 73, 103, 139, 65, 573, 3909, 2645, 9603, 0 }; + static ulong[] dim1139Kuo2Init = { 1, 3, 7, 9, 3, 31, 45, 79, 195, 749, 65, 4041, 3915, 3137, 0 }; + static ulong[] dim1140Kuo2Init = { 1, 3, 3, 13, 5, 37, 87, 211, 61, 237, 1903, 755, 4077, 14791, 0 }; + static ulong[] dim1141Kuo2Init = { 1, 1, 7, 5, 3, 63, 63, 45, 357, 887, 1511, 2503, 6669, 3163, 0 }; + static ulong[] dim1142Kuo2Init = { 1, 3, 1, 5, 17, 29, 113, 117, 487, 369, 1337, 3129, 3517, 2107, 0 }; + static ulong[] dim1143Kuo2Init = { 1, 1, 7, 1, 7, 13, 15, 203, 421, 267, 1049, 1645, 2047, 11733, 0 }; + static ulong[] dim1144Kuo2Init = { 1, 1, 1, 5, 17, 27, 5, 101, 109, 651, 601, 673, 67, 8539, 0 }; + static ulong[] dim1145Kuo2Init = { 1, 1, 5, 13, 9, 53, 85, 165, 197, 979, 925, 419, 4631, 15269, 0 }; + static ulong[] dim1146Kuo2Init = { 1, 3, 7, 15, 5, 5, 61, 205, 257, 279, 81, 4059, 2375, 12821, 0 }; + static ulong[] dim1147Kuo2Init = { 1, 3, 1, 11, 27, 41, 39, 41, 75, 1017, 529, 2709, 3385, 3879, 0 }; + static ulong[] dim1148Kuo2Init = { 1, 3, 1, 13, 25, 63, 125, 137, 27, 839, 617, 2129, 711, 3955, 0 }; + static ulong[] dim1149Kuo2Init = { 1, 3, 5, 5, 27, 19, 27, 51, 369, 593, 605, 2471, 6995, 5957, 0 }; + static ulong[] dim1150Kuo2Init = { 1, 3, 3, 5, 9, 11, 63, 157, 447, 713, 1145, 2013, 3061, 13763, 0 }; + static ulong[] dim1151Kuo2Init = { 1, 1, 5, 1, 15, 51, 49, 185, 337, 109, 1335, 841, 7005, 8969, 0 }; + static ulong[] dim1152Kuo2Init = { 1, 1, 5, 15, 17, 25, 31, 135, 43, 469, 1895, 3369, 6981, 8515, 0 }; + static ulong[] dim1153Kuo2Init = { 1, 1, 5, 9, 21, 11, 117, 79, 39, 63, 1355, 2309, 4409, 6463, 0 }; + static ulong[] dim1154Kuo2Init = { 1, 3, 3, 15, 11, 55, 55, 75, 251, 209, 1715, 697, 2199, 2155, 0 }; + static ulong[] dim1155Kuo2Init = { 1, 3, 5, 13, 31, 29, 55, 23, 391, 1011, 1701, 787, 8165, 1315, 0 }; + static ulong[] dim1156Kuo2Init = { 1, 1, 7, 7, 23, 55, 125, 15, 77, 107, 2043, 1501, 727, 13693, 0 }; + static ulong[] dim1157Kuo2Init = { 1, 1, 7, 7, 27, 37, 47, 247, 227, 595, 175, 3459, 395, 9903, 0 }; + static ulong[] dim1158Kuo2Init = { 1, 3, 5, 9, 7, 7, 61, 81, 405, 117, 51, 3715, 2757, 2797, 0 }; + static ulong[] dim1159Kuo2Init = { 1, 1, 1, 15, 15, 25, 9, 109, 497, 395, 777, 1187, 7451, 15959, 0 }; + static ulong[] dim1160Kuo2Init = { 1, 3, 3, 7, 7, 23, 69, 27, 97, 145, 1165, 993, 235, 1785, 0 }; + static ulong[] dim1161Kuo2Init = { 1, 1, 3, 15, 17, 49, 73, 27, 223, 83, 295, 1425, 4817, 7325, 0 }; + static ulong[] dim1162Kuo2Init = { 1, 3, 7, 5, 25, 13, 69, 119, 483, 635, 1105, 2547, 457, 5607, 0 }; + static ulong[] dim1163Kuo2Init = { 1, 1, 7, 9, 13, 29, 69, 7, 223, 95, 1255, 459, 4633, 12609, 0 }; + static ulong[] dim1164Kuo2Init = { 1, 1, 1, 1, 15, 57, 105, 161, 429, 615, 201, 2601, 3169, 3163, 0 }; + static ulong[] dim1165Kuo2Init = { 1, 3, 3, 1, 5, 5, 127, 129, 457, 59, 459, 3731, 2069, 9147, 0 }; + static ulong[] dim1166Kuo2Init = { 1, 1, 1, 7, 25, 45, 101, 111, 119, 739, 157, 3967, 6427, 2845, 0 }; + static ulong[] dim1167Kuo2Init = { 1, 3, 1, 9, 15, 15, 105, 147, 119, 815, 1263, 2201, 5413, 15255, 0 }; + static ulong[] dim1168Kuo2Init = { 1, 3, 1, 5, 15, 47, 87, 131, 451, 805, 1043, 2917, 5495, 5103, 0 }; + static ulong[] dim1169Kuo2Init = { 1, 1, 3, 11, 29, 35, 33, 135, 509, 425, 723, 1947, 7237, 8941, 0 }; + static ulong[] dim1170Kuo2Init = { 1, 1, 3, 7, 5, 39, 83, 83, 353, 685, 195, 385, 2431, 8753, 0 }; + static ulong[] dim1171Kuo2Init = { 1, 3, 3, 7, 25, 45, 3, 129, 413, 1005, 625, 3503, 5473, 3577, 0 }; + static ulong[] dim1172Kuo2Init = { 1, 1, 3, 13, 7, 37, 29, 163, 397, 671, 1043, 3581, 465, 9521, 0 }; + static ulong[] dim1173Kuo2Init = { 1, 1, 3, 5, 31, 21, 111, 95, 385, 787, 1205, 795, 4779, 11421, 0 }; + static ulong[] dim1174Kuo2Init = { 1, 1, 1, 3, 25, 15, 51, 149, 423, 907, 863, 1535, 5809, 1069, 0 }; + static ulong[] dim1175Kuo2Init = { 1, 3, 5, 5, 19, 57, 51, 49, 39, 349, 1453, 3091, 4861, 8771, 0 }; + static ulong[] dim1176Kuo2Init = { 1, 1, 5, 15, 1, 45, 93, 85, 511, 607, 793, 1023, 1525, 535, 0 }; + static ulong[] dim1177Kuo2Init = { 1, 3, 3, 11, 7, 53, 83, 139, 173, 947, 1381, 433, 5821, 4173, 0 }; + static ulong[] dim1178Kuo2Init = { 1, 3, 5, 9, 27, 17, 17, 237, 427, 295, 929, 1539, 2373, 6671, 0 }; + static ulong[] dim1179Kuo2Init = { 1, 1, 1, 1, 9, 53, 87, 129, 443, 729, 1067, 359, 789, 7637, 0 }; + static ulong[] dim1180Kuo2Init = { 1, 1, 1, 7, 7, 23, 71, 115, 343, 207, 889, 3561, 475, 3437, 0 }; + static ulong[] dim1181Kuo2Init = { 1, 3, 5, 9, 17, 31, 85, 135, 155, 269, 575, 537, 5305, 979, 0 }; + static ulong[] dim1182Kuo2Init = { 1, 3, 1, 5, 19, 41, 61, 103, 49, 93, 733, 1791, 3577, 1763, 0 }; + static ulong[] dim1183Kuo2Init = { 1, 1, 3, 3, 27, 23, 3, 143, 341, 847, 1859, 995, 5277, 5025, 0 }; + static ulong[] dim1184Kuo2Init = { 1, 3, 5, 13, 7, 29, 37, 201, 359, 255, 1543, 3735, 1217, 7251, 0 }; + static ulong[] dim1185Kuo2Init = { 1, 1, 7, 9, 27, 45, 15, 187, 181, 571, 1345, 1473, 519, 7499, 0 }; + static ulong[] dim1186Kuo2Init = { 1, 1, 7, 7, 11, 11, 75, 179, 455, 495, 283, 2995, 1515, 5497, 0 }; + static ulong[] dim1187Kuo2Init = { 1, 1, 7, 3, 11, 19, 91, 165, 175, 967, 1719, 739, 103, 15259, 0 }; + static ulong[] dim1188Kuo2Init = { 1, 3, 3, 9, 7, 5, 121, 65, 83, 687, 837, 2303, 1953, 15419, 0 }; + static ulong[] dim1189Kuo2Init = { 1, 3, 1, 13, 31, 39, 43, 69, 129, 815, 1419, 3179, 595, 14471, 0 }; + static ulong[] dim1190Kuo2Init = { 1, 1, 5, 9, 9, 33, 75, 141, 271, 259, 91, 553, 7521, 9591, 0 }; + static ulong[] dim1191Kuo2Init = { 1, 1, 5, 1, 27, 55, 125, 41, 103, 161, 9, 1339, 3205, 973, 0 }; + static ulong[] dim1192Kuo2Init = { 1, 1, 3, 3, 13, 15, 93, 179, 435, 667, 1365, 169, 4685, 16175, 0 }; + static ulong[] dim1193Kuo2Init = { 1, 1, 5, 9, 17, 55, 45, 237, 291, 837, 1019, 2983, 1679, 13583, 0 }; + static ulong[] dim1194Kuo2Init = { 1, 3, 1, 3, 3, 37, 37, 239, 265, 117, 1239, 529, 4855, 11423, 0 }; + static ulong[] dim1195Kuo2Init = { 1, 3, 5, 3, 11, 11, 121, 81, 55, 35, 1551, 775, 6973, 13525, 0 }; + static ulong[] dim1196Kuo2Init = { 1, 3, 3, 11, 15, 19, 49, 117, 269, 147, 1891, 2975, 1779, 9327, 0 }; + static ulong[] dim1197Kuo2Init = { 1, 1, 1, 7, 9, 39, 111, 131, 179, 629, 1807, 3327, 1535, 2845, 0 }; + static ulong[] dim1198Kuo2Init = { 1, 3, 7, 13, 11, 59, 125, 41, 13, 637, 1679, 487, 4655, 8045, 0 }; + static ulong[] dim1199Kuo2Init = { 1, 1, 3, 7, 17, 15, 63, 105, 271, 205, 283, 3427, 1921, 12729, 0 }; + static ulong[] dim1200Kuo2Init = { 1, 1, 3, 5, 13, 57, 23, 141, 261, 829, 1149, 945, 4191, 13277, 0 }; + static ulong[] dim1201Kuo2Init = { 1, 1, 5, 7, 13, 59, 79, 221, 473, 803, 2027, 437, 7823, 14225, 0 }; + static ulong[] dim1202Kuo2Init = { 1, 3, 3, 9, 15, 21, 53, 69, 13, 479, 193, 1031, 4911, 12011, 0 }; + static ulong[] dim1203Kuo2Init = { 1, 1, 5, 7, 25, 7, 99, 81, 21, 247, 1019, 2537, 3647, 8211, 0 }; + static ulong[] dim1204Kuo2Init = { 1, 3, 7, 15, 27, 47, 105, 141, 49, 65, 525, 1717, 1339, 9079, 0 }; + static ulong[] dim1205Kuo2Init = { 1, 1, 7, 3, 27, 1, 31, 135, 175, 997, 1517, 1139, 7975, 14941, 0 }; + static ulong[] dim1206Kuo2Init = { 1, 1, 1, 5, 9, 5, 77, 175, 333, 975, 873, 523, 2967, 9463, 0 }; + static ulong[] dim1207Kuo2Init = { 1, 3, 5, 9, 5, 61, 17, 141, 405, 591, 711, 1077, 2875, 8827, 0 }; + static ulong[] dim1208Kuo2Init = { 1, 3, 1, 11, 9, 13, 29, 9, 443, 717, 2019, 1031, 6459, 6673, 0 }; + static ulong[] dim1209Kuo2Init = { 1, 1, 3, 5, 7, 51, 45, 163, 113, 705, 1411, 3861, 527, 6119, 0 }; + static ulong[] dim1210Kuo2Init = { 1, 1, 1, 5, 9, 43, 57, 79, 221, 131, 1543, 2243, 5277, 6249, 0 }; + static ulong[] dim1211Kuo2Init = { 1, 1, 1, 7, 15, 63, 89, 11, 211, 245, 89, 219, 241, 545, 0 }; + static ulong[] dim1212Kuo2Init = { 1, 3, 3, 7, 31, 21, 97, 43, 457, 941, 363, 3275, 4731, 3167, 0 }; + static ulong[] dim1213Kuo2Init = { 1, 1, 7, 9, 31, 45, 15, 119, 283, 645, 1239, 3835, 5317, 4643, 0 }; + static ulong[] dim1214Kuo2Init = { 1, 1, 5, 3, 23, 31, 49, 67, 487, 935, 1899, 2545, 8135, 12609, 0 }; + static ulong[] dim1215Kuo2Init = { 1, 3, 7, 9, 21, 63, 15, 233, 463, 763, 327, 2585, 4399, 14643, 0 }; + static ulong[] dim1216Kuo2Init = { 1, 1, 7, 9, 13, 5, 95, 11, 239, 507, 955, 569, 6443, 3009, 0 }; + static ulong[] dim1217Kuo2Init = { 1, 3, 5, 9, 31, 27, 99, 251, 487, 383, 1117, 2231, 6541, 10409, 0 }; + static ulong[] dim1218Kuo2Init = { 1, 3, 3, 15, 23, 37, 81, 149, 127, 341, 1749, 207, 2257, 2659, 0 }; + static ulong[] dim1219Kuo2Init = { 1, 1, 7, 9, 15, 7, 59, 63, 187, 719, 1295, 3509, 2293, 4959, 0 }; + static ulong[] dim1220Kuo2Init = { 1, 1, 5, 13, 3, 49, 27, 17, 261, 463, 1719, 793, 4365, 4041, 0 }; + static ulong[] dim1221Kuo2Init = { 1, 3, 3, 7, 7, 37, 19, 133, 197, 789, 383, 1005, 7353, 2431, 0 }; + static ulong[] dim1222Kuo2Init = { 1, 1, 1, 13, 21, 11, 27, 247, 309, 103, 1707, 2555, 2731, 11755, 0 }; + static ulong[] dim1223Kuo2Init = { 1, 3, 1, 15, 13, 45, 119, 233, 387, 781, 851, 3207, 5251, 9741, 0 }; + static ulong[] dim1224Kuo2Init = { 1, 3, 7, 15, 3, 17, 13, 217, 245, 267, 55, 3065, 3733, 2577, 0 }; + static ulong[] dim1225Kuo2Init = { 1, 1, 7, 13, 11, 25, 7, 219, 209, 295, 1725, 359, 5489, 1057, 0 }; + static ulong[] dim1226Kuo2Init = { 1, 3, 1, 3, 7, 1, 93, 33, 485, 977, 1113, 3049, 7015, 14275, 0 }; + static ulong[] dim1227Kuo2Init = { 1, 3, 3, 13, 15, 9, 115, 113, 221, 1, 875, 1485, 3523, 6817, 0 }; + static ulong[] dim1228Kuo2Init = { 1, 1, 5, 15, 3, 41, 113, 5, 7, 1023, 349, 1901, 1223, 11355, 0 }; + static ulong[] dim1229Kuo2Init = { 1, 3, 7, 13, 27, 59, 113, 123, 81, 795, 803, 955, 7101, 7715, 0 }; + static ulong[] dim1230Kuo2Init = { 1, 1, 1, 15, 15, 19, 123, 183, 341, 9, 943, 549, 1261, 8305, 0 }; + static ulong[] dim1231Kuo2Init = { 1, 1, 3, 5, 25, 45, 109, 239, 399, 405, 1859, 3721, 2023, 12543, 0 }; + static ulong[] dim1232Kuo2Init = { 1, 3, 1, 11, 11, 51, 119, 83, 189, 119, 51, 3601, 1589, 3821, 0 }; + static ulong[] dim1233Kuo2Init = { 1, 3, 3, 3, 9, 41, 13, 91, 329, 625, 1837, 2539, 5603, 2135, 0 }; + static ulong[] dim1234Kuo2Init = { 1, 3, 5, 7, 5, 59, 125, 133, 321, 759, 237, 3299, 4663, 15767, 0 }; + static ulong[] dim1235Kuo2Init = { 1, 1, 7, 7, 29, 3, 45, 37, 69, 437, 1321, 3545, 373, 3349, 0 }; + static ulong[] dim1236Kuo2Init = { 1, 1, 1, 13, 13, 47, 87, 33, 93, 639, 673, 1675, 5997, 9049, 0 }; + static ulong[] dim1237Kuo2Init = { 1, 3, 1, 3, 31, 27, 33, 175, 71, 509, 229, 2959, 7929, 7551, 0 }; + static ulong[] dim1238Kuo2Init = { 1, 1, 3, 7, 17, 41, 101, 119, 51, 297, 595, 41, 7919, 6173, 0 }; + static ulong[] dim1239Kuo2Init = { 1, 3, 5, 11, 11, 63, 17, 177, 349, 327, 531, 783, 4025, 3367, 0 }; + static ulong[] dim1240Kuo2Init = { 1, 3, 1, 13, 11, 31, 97, 137, 117, 981, 3, 2873, 6399, 5055, 0 }; + static ulong[] dim1241Kuo2Init = { 1, 3, 7, 11, 9, 63, 53, 237, 255, 161, 1709, 3591, 2569, 8687, 0 }; + static ulong[] dim1242Kuo2Init = { 1, 3, 3, 11, 23, 9, 97, 143, 403, 597, 1651, 933, 1351, 3675, 0 }; + static ulong[] dim1243Kuo2Init = { 1, 1, 1, 9, 23, 11, 93, 103, 245, 797, 723, 4029, 4313, 14217, 0 }; + static ulong[] dim1244Kuo2Init = { 1, 1, 1, 3, 13, 51, 77, 237, 109, 933, 449, 429, 6991, 13475, 0 }; + static ulong[] dim1245Kuo2Init = { 1, 3, 1, 1, 29, 63, 65, 63, 129, 693, 1441, 3877, 3015, 7817, 0 }; + static ulong[] dim1246Kuo2Init = { 1, 1, 7, 3, 7, 57, 63, 129, 15, 257, 739, 3395, 1473, 12735, 0 }; + static ulong[] dim1247Kuo2Init = { 1, 1, 1, 9, 23, 21, 123, 81, 297, 899, 1719, 3523, 4895, 12503, 0 }; + static ulong[] dim1248Kuo2Init = { 1, 1, 3, 1, 9, 3, 61, 7, 251, 1003, 289, 1321, 7041, 6811, 0 }; + static ulong[] dim1249Kuo2Init = { 1, 3, 5, 9, 3, 9, 87, 13, 363, 713, 673, 717, 1449, 6869, 0 }; + static ulong[] dim1250Kuo2Init = { 1, 1, 3, 9, 25, 53, 115, 111, 499, 425, 1037, 3751, 5767, 10047, 0 }; + static ulong[] dim1251Kuo2Init = { 1, 3, 7, 11, 23, 43, 75, 101, 105, 115, 887, 3747, 149, 5513, 0 }; + static ulong[] dim1252Kuo2Init = { 1, 3, 1, 9, 7, 43, 125, 63, 3, 365, 1345, 821, 731, 14007, 0 }; + static ulong[] dim1253Kuo2Init = { 1, 3, 1, 7, 29, 49, 55, 37, 343, 481, 1319, 1167, 4835, 10549, 0 }; + static ulong[] dim1254Kuo2Init = { 1, 1, 7, 13, 11, 33, 123, 91, 301, 765, 1037, 2935, 1213, 10141, 0 }; + static ulong[] dim1255Kuo2Init = { 1, 1, 7, 1, 21, 55, 57, 79, 187, 977, 297, 63, 3431, 10597, 0 }; + static ulong[] dim1256Kuo2Init = { 1, 3, 5, 9, 5, 25, 33, 25, 477, 105, 1757, 2051, 1263, 15421, 0 }; + static ulong[] dim1257Kuo2Init = { 1, 3, 5, 11, 5, 39, 63, 209, 223, 497, 785, 2127, 4293, 7583, 0 }; + static ulong[] dim1258Kuo2Init = { 1, 1, 5, 3, 9, 23, 107, 125, 319, 143, 947, 1135, 4391, 6297, 0 }; + static ulong[] dim1259Kuo2Init = { 1, 3, 7, 15, 19, 21, 103, 161, 5, 739, 1537, 2697, 1827, 8287, 0 }; + static ulong[] dim1260Kuo2Init = { 1, 1, 7, 3, 29, 37, 117, 199, 35, 683, 1539, 2915, 8129, 14785, 0 }; + static ulong[] dim1261Kuo2Init = { 1, 3, 1, 3, 7, 35, 39, 181, 111, 165, 1919, 1583, 4219, 179, 0 }; + static ulong[] dim1262Kuo2Init = { 1, 3, 3, 11, 15, 5, 13, 123, 93, 615, 1811, 3235, 4533, 2423, 0 }; + static ulong[] dim1263Kuo2Init = { 1, 1, 1, 15, 25, 17, 21, 37, 5, 413, 1681, 2297, 5571, 6037, 0 }; + static ulong[] dim1264Kuo2Init = { 1, 1, 1, 9, 27, 21, 7, 139, 235, 163, 1809, 783, 507, 8867, 0 }; + static ulong[] dim1265Kuo2Init = { 1, 3, 7, 9, 23, 57, 1, 55, 311, 687, 1987, 463, 5639, 4795, 0 }; + static ulong[] dim1266Kuo2Init = { 1, 1, 7, 9, 11, 55, 31, 77, 277, 447, 799, 993, 489, 3539, 0 }; + static ulong[] dim1267Kuo2Init = { 1, 1, 1, 5, 27, 19, 23, 207, 11, 81, 1539, 1051, 1155, 11475, 0 }; + static ulong[] dim1268Kuo2Init = { 1, 1, 5, 1, 23, 63, 23, 247, 261, 789, 1305, 3003, 1033, 1883, 0 }; + static ulong[] dim1269Kuo2Init = { 1, 1, 5, 15, 1, 35, 1, 147, 51, 513, 35, 3285, 7461, 13733, 0 }; + static ulong[] dim1270Kuo2Init = { 1, 1, 1, 5, 29, 25, 107, 91, 355, 213, 203, 2371, 1383, 14285, 0 }; + static ulong[] dim1271Kuo2Init = { 1, 3, 7, 13, 11, 35, 109, 171, 229, 209, 375, 2911, 1943, 7037, 0 }; + static ulong[] dim1272Kuo2Init = { 1, 1, 5, 11, 21, 39, 113, 5, 167, 769, 2047, 3083, 7421, 14085, 0 }; + static ulong[] dim1273Kuo2Init = { 1, 3, 7, 13, 13, 27, 83, 67, 171, 671, 1675, 2473, 3241, 15283, 0 }; + static ulong[] dim1274Kuo2Init = { 1, 1, 1, 7, 5, 27, 23, 171, 443, 243, 217, 3349, 1919, 2345, 0 }; + static ulong[] dim1275Kuo2Init = { 1, 1, 1, 11, 7, 1, 41, 25, 47, 835, 1071, 3091, 6133, 7249, 0 }; + static ulong[] dim1276Kuo2Init = { 1, 1, 7, 15, 27, 41, 3, 153, 479, 447, 1457, 2267, 3781, 9851, 0 }; + static ulong[] dim1277Kuo2Init = { 1, 1, 7, 7, 25, 1, 125, 129, 231, 505, 1709, 3117, 6069, 3103, 0 }; + static ulong[] dim1278Kuo2Init = { 1, 3, 3, 13, 9, 53, 73, 93, 185, 1007, 1883, 3087, 7453, 13335, 0 }; + static ulong[] dim1279Kuo2Init = { 1, 1, 1, 5, 7, 51, 65, 189, 397, 73, 377, 2593, 6703, 16145, 0 }; + static ulong[] dim1280Kuo2Init = { 1, 1, 7, 3, 17, 55, 93, 251, 29, 937, 223, 721, 3275, 11881, 0 }; + static ulong[] dim1281Kuo2Init = { 1, 3, 7, 1, 1, 45, 99, 117, 279, 87, 2015, 3681, 5625, 5191, 0 }; + static ulong[] dim1282Kuo2Init = { 1, 3, 7, 9, 7, 63, 23, 83, 277, 959, 693, 3945, 4551, 13711, 0 }; + static ulong[] dim1283Kuo2Init = { 1, 3, 1, 1, 23, 57, 127, 7, 323, 545, 1909, 2399, 4483, 12165, 0 }; + static ulong[] dim1284Kuo2Init = { 1, 3, 1, 7, 23, 37, 39, 213, 45, 949, 661, 397, 189, 2835, 0 }; + static ulong[] dim1285Kuo2Init = { 1, 1, 1, 11, 17, 11, 97, 141, 389, 137, 907, 3939, 1205, 9751, 0 }; + static ulong[] dim1286Kuo2Init = { 1, 1, 5, 9, 25, 45, 53, 101, 43, 503, 777, 1327, 8127, 1977, 0 }; + static ulong[] dim1287Kuo2Init = { 1, 3, 1, 5, 19, 15, 71, 193, 443, 817, 1507, 291, 3781, 5841, 0 }; + static ulong[] dim1288Kuo2Init = { 1, 3, 3, 1, 25, 41, 121, 17, 471, 357, 1193, 3079, 2025, 773, 0 }; + static ulong[] dim1289Kuo2Init = { 1, 1, 3, 9, 5, 31, 123, 35, 103, 439, 1199, 1887, 6923, 9439, 0 }; + static ulong[] dim1290Kuo2Init = { 1, 3, 1, 5, 7, 35, 1, 151, 467, 573, 517, 3681, 4563, 3143, 0 }; + static ulong[] dim1291Kuo2Init = { 1, 3, 1, 7, 19, 61, 43, 57, 217, 113, 1045, 3773, 1197, 14627, 0 }; + static ulong[] dim1292Kuo2Init = { 1, 3, 7, 11, 7, 51, 71, 31, 71, 143, 319, 2979, 849, 14403, 0 }; + static ulong[] dim1293Kuo2Init = { 1, 1, 1, 15, 17, 25, 119, 253, 13, 959, 1217, 261, 2853, 10449, 0 }; + static ulong[] dim1294Kuo2Init = { 1, 3, 7, 15, 23, 19, 71, 205, 63, 915, 317, 1637, 1963, 10047, 0 }; + static ulong[] dim1295Kuo2Init = { 1, 1, 5, 9, 21, 57, 119, 223, 169, 87, 593, 2871, 1201, 4531, 0 }; + static ulong[] dim1296Kuo2Init = { 1, 3, 5, 3, 7, 11, 25, 129, 469, 199, 323, 4021, 2983, 1459, 0 }; + static ulong[] dim1297Kuo2Init = { 1, 3, 1, 1, 7, 39, 41, 75, 75, 113, 985, 3353, 5393, 7055, 0 }; + static ulong[] dim1298Kuo2Init = { 1, 3, 3, 11, 19, 55, 37, 235, 221, 197, 1041, 3447, 8045, 801, 0 }; + static ulong[] dim1299Kuo2Init = { 1, 1, 7, 7, 9, 19, 3, 221, 265, 963, 1815, 469, 2929, 10711, 0 }; + static ulong[] dim1300Kuo2Init = { 1, 3, 1, 5, 27, 11, 59, 57, 91, 235, 1465, 825, 6429, 15537, 0 }; + static ulong[] dim1301Kuo2Init = { 1, 1, 1, 1, 19, 21, 47, 235, 223, 761, 173, 3793, 2197, 10919, 0 }; + static ulong[] dim1302Kuo2Init = { 1, 3, 3, 9, 11, 61, 19, 121, 51, 617, 441, 1889, 6225, 3317, 0 }; + static ulong[] dim1303Kuo2Init = { 1, 3, 1, 7, 25, 27, 65, 163, 165, 7, 1303, 3275, 173, 6923, 0 }; + static ulong[] dim1304Kuo2Init = { 1, 3, 1, 13, 23, 39, 35, 105, 267, 679, 1675, 2837, 1213, 14985, 0 }; + static ulong[] dim1305Kuo2Init = { 1, 1, 5, 1, 21, 39, 1, 229, 101, 421, 513, 571, 7195, 9975, 0 }; + static ulong[] dim1306Kuo2Init = { 1, 1, 1, 1, 13, 23, 97, 157, 1, 969, 2011, 295, 6775, 7397, 0 }; + static ulong[] dim1307Kuo2Init = { 1, 1, 5, 5, 15, 9, 63, 21, 435, 51, 1279, 1309, 4303, 15771, 0 }; + static ulong[] dim1308Kuo2Init = { 1, 3, 1, 3, 3, 43, 121, 59, 365, 437, 215, 2899, 761, 1369, 0 }; + static ulong[] dim1309Kuo2Init = { 1, 1, 3, 7, 17, 25, 29, 149, 291, 117, 247, 2779, 7379, 11671, 0 }; + static ulong[] dim1310Kuo2Init = { 1, 3, 5, 15, 7, 3, 87, 213, 467, 91, 145, 1241, 1557, 6427, 0 }; + static ulong[] dim1311Kuo2Init = { 1, 1, 3, 9, 3, 51, 1, 61, 259, 535, 399, 3101, 5781, 14635, 0 }; + static ulong[] dim1312Kuo2Init = { 1, 3, 3, 11, 21, 17, 127, 117, 203, 825, 1481, 3979, 3605, 10537, 0 }; + static ulong[] dim1313Kuo2Init = { 1, 1, 5, 13, 15, 5, 119, 79, 439, 209, 1811, 3199, 7933, 1677, 0 }; + static ulong[] dim1314Kuo2Init = { 1, 1, 3, 15, 9, 9, 111, 103, 145, 839, 187, 2937, 6871, 10573, 0 }; + static ulong[] dim1315Kuo2Init = { 1, 3, 1, 9, 19, 7, 39, 37, 209, 83, 1143, 3767, 6013, 8829, 0 }; + static ulong[] dim1316Kuo2Init = { 1, 1, 7, 5, 31, 39, 97, 167, 323, 343, 999, 2179, 6683, 4079, 0 }; + static ulong[] dim1317Kuo2Init = { 1, 1, 1, 7, 1, 31, 5, 109, 391, 17, 1943, 2753, 3825, 327, 0 }; + static ulong[] dim1318Kuo2Init = { 1, 1, 7, 9, 9, 19, 49, 137, 421, 669, 829, 3261, 3995, 4347, 0 }; + static ulong[] dim1319Kuo2Init = { 1, 3, 5, 3, 25, 43, 51, 97, 315, 1021, 183, 87, 6465, 15415, 0 }; + static ulong[] dim1320Kuo2Init = { 1, 3, 1, 1, 15, 61, 111, 249, 99, 1001, 791, 869, 7017, 5943, 0 }; + static ulong[] dim1321Kuo2Init = { 1, 3, 7, 3, 3, 7, 51, 127, 275, 683, 1055, 3727, 1273, 3007, 0 }; + static ulong[] dim1322Kuo2Init = { 1, 3, 1, 15, 19, 33, 113, 167, 473, 287, 233, 905, 2213, 12233, 0 }; + static ulong[] dim1323Kuo2Init = { 1, 3, 3, 7, 3, 45, 83, 107, 7, 651, 603, 2663, 5261, 15521, 0 }; + static ulong[] dim1324Kuo2Init = { 1, 3, 3, 9, 19, 49, 51, 81, 101, 23, 1345, 17, 4215, 7089, 0 }; + static ulong[] dim1325Kuo2Init = { 1, 3, 5, 5, 7, 7, 65, 221, 7, 513, 1567, 4041, 6339, 8665, 0 }; + static ulong[] dim1326Kuo2Init = { 1, 1, 7, 9, 15, 61, 91, 29, 85, 903, 1805, 1957, 63, 13941, 0 }; + static ulong[] dim1327Kuo2Init = { 1, 1, 1, 1, 29, 19, 31, 21, 43, 353, 1419, 3999, 6651, 1897, 0 }; + static ulong[] dim1328Kuo2Init = { 1, 1, 3, 13, 31, 7, 65, 57, 25, 1015, 1969, 1547, 4815, 4183, 0 }; + static ulong[] dim1329Kuo2Init = { 1, 1, 7, 11, 25, 37, 91, 163, 287, 283, 1531, 149, 7799, 15, 0 }; + static ulong[] dim1330Kuo2Init = { 1, 3, 5, 7, 23, 25, 71, 7, 439, 645, 843, 315, 4577, 6703, 0 }; + static ulong[] dim1331Kuo2Init = { 1, 1, 5, 15, 13, 39, 57, 115, 91, 475, 2003, 3787, 4053, 13299, 0 }; + static ulong[] dim1332Kuo2Init = { 1, 3, 3, 7, 1, 53, 53, 83, 7, 133, 1523, 347, 3569, 6495, 0 }; + static ulong[] dim1333Kuo2Init = { 1, 1, 7, 13, 15, 53, 31, 153, 181, 465, 687, 3375, 3393, 565, 0 }; + static ulong[] dim1334Kuo2Init = { 1, 3, 3, 3, 19, 21, 95, 45, 399, 1, 213, 2003, 221, 11961, 0 }; + static ulong[] dim1335Kuo2Init = { 1, 1, 5, 13, 27, 29, 35, 55, 239, 999, 23, 2645, 5399, 865, 0 }; + static ulong[] dim1336Kuo2Init = { 1, 1, 5, 11, 5, 3, 43, 217, 321, 159, 1611, 495, 435, 6989, 0 }; + static ulong[] dim1337Kuo2Init = { 1, 1, 5, 1, 27, 15, 29, 109, 385, 449, 651, 1551, 5983, 12985, 0 }; + static ulong[] dim1338Kuo2Init = { 1, 3, 5, 11, 27, 35, 11, 155, 279, 5, 389, 1157, 2401, 12485, 0 }; + static ulong[] dim1339Kuo2Init = { 1, 1, 3, 3, 7, 7, 3, 185, 469, 995, 271, 2315, 3269, 909, 0 }; + static ulong[] dim1340Kuo2Init = { 1, 3, 5, 3, 27, 31, 111, 47, 351, 17, 1321, 3973, 457, 15773, 0 }; + static ulong[] dim1341Kuo2Init = { 1, 3, 1, 7, 19, 59, 71, 215, 93, 235, 1985, 1149, 1887, 2963, 0 }; + static ulong[] dim1342Kuo2Init = { 1, 3, 5, 3, 3, 3, 87, 205, 187, 373, 1557, 311, 5807, 13343, 0 }; + static ulong[] dim1343Kuo2Init = { 1, 1, 7, 13, 19, 17, 31, 113, 183, 31, 1117, 3241, 4781, 15071, 0 }; + static ulong[] dim1344Kuo2Init = { 1, 3, 5, 5, 3, 25, 33, 93, 473, 353, 1005, 2385, 649, 5219, 0 }; + static ulong[] dim1345Kuo2Init = { 1, 1, 3, 5, 25, 37, 39, 109, 511, 1005, 641, 3597, 7601, 613, 0 }; + static ulong[] dim1346Kuo2Init = { 1, 1, 7, 7, 3, 17, 69, 145, 147, 321, 849, 3057, 7299, 12343, 0 }; + static ulong[] dim1347Kuo2Init = { 1, 1, 3, 15, 11, 35, 19, 179, 337, 53, 679, 4009, 769, 2899, 0 }; + static ulong[] dim1348Kuo2Init = { 1, 1, 7, 11, 19, 47, 61, 11, 349, 769, 445, 2051, 5653, 7143, 0 }; + static ulong[] dim1349Kuo2Init = { 1, 1, 3, 9, 3, 39, 53, 193, 313, 299, 1579, 2237, 661, 6047, 0 }; + static ulong[] dim1350Kuo2Init = { 1, 1, 7, 7, 29, 17, 9, 225, 143, 285, 1169, 3109, 927, 5257, 0 }; + static ulong[] dim1351Kuo2Init = { 1, 3, 7, 5, 5, 27, 107, 253, 439, 1017, 253, 3437, 5435, 13479, 0 }; + static ulong[] dim1352Kuo2Init = { 1, 3, 3, 1, 9, 61, 111, 75, 241, 451, 1361, 2853, 5457, 15853, 0 }; + static ulong[] dim1353Kuo2Init = { 1, 1, 1, 5, 15, 23, 21, 115, 505, 265, 131, 1277, 2545, 8955, 0 }; + static ulong[] dim1354Kuo2Init = { 1, 1, 1, 1, 17, 43, 3, 253, 315, 19, 787, 1477, 2529, 6527, 0 }; + static ulong[] dim1355Kuo2Init = { 1, 1, 1, 7, 17, 31, 87, 121, 201, 367, 265, 3899, 1961, 12761, 0 }; + static ulong[] dim1356Kuo2Init = { 1, 1, 7, 9, 9, 55, 101, 163, 39, 351, 1877, 2481, 3265, 15575, 0 }; + static ulong[] dim1357Kuo2Init = { 1, 1, 3, 5, 29, 19, 21, 39, 187, 401, 547, 2477, 995, 3339, 0 }; + static ulong[] dim1358Kuo2Init = { 1, 3, 3, 5, 19, 25, 59, 247, 389, 733, 1867, 3401, 5115, 12791, 0 }; + static ulong[] dim1359Kuo2Init = { 1, 1, 3, 15, 11, 39, 29, 239, 157, 145, 1553, 3419, 5787, 3983, 0 }; + static ulong[] dim1360Kuo2Init = { 1, 1, 1, 15, 23, 47, 99, 71, 335, 749, 875, 5, 8049, 4585, 0 }; + static ulong[] dim1361Kuo2Init = { 1, 3, 7, 11, 19, 17, 25, 23, 243, 171, 929, 1981, 363, 13631, 0 }; + static ulong[] dim1362Kuo2Init = { 1, 1, 1, 1, 19, 43, 101, 199, 157, 431, 1127, 3261, 4063, 10569, 0 }; + static ulong[] dim1363Kuo2Init = { 1, 3, 5, 15, 15, 43, 1, 199, 281, 841, 1643, 2827, 6997, 11309, 0 }; + static ulong[] dim1364Kuo2Init = { 1, 1, 1, 11, 5, 53, 127, 147, 141, 319, 1605, 3717, 6519, 15315, 0 }; + static ulong[] dim1365Kuo2Init = { 1, 3, 3, 7, 31, 5, 39, 221, 91, 521, 527, 3253, 2877, 1439, 0 }; + static ulong[] dim1366Kuo2Init = { 1, 3, 5, 1, 9, 61, 69, 27, 393, 557, 1949, 3035, 3717, 5099, 0 }; + static ulong[] dim1367Kuo2Init = { 1, 3, 7, 3, 19, 43, 77, 161, 469, 721, 73, 685, 1681, 5581, 0 }; + static ulong[] dim1368Kuo2Init = { 1, 1, 7, 5, 27, 3, 119, 223, 255, 905, 501, 1809, 5591, 29, 0 }; + static ulong[] dim1369Kuo2Init = { 1, 1, 3, 11, 13, 1, 13, 103, 305, 679, 1485, 4077, 1419, 7893, 0 }; + static ulong[] dim1370Kuo2Init = { 1, 1, 1, 15, 21, 7, 39, 49, 451, 291, 93, 3563, 5071, 15353, 0 }; + static ulong[] dim1371Kuo2Init = { 1, 3, 7, 9, 19, 53, 57, 149, 171, 377, 1903, 235, 2181, 8207, 0 }; + static ulong[] dim1372Kuo2Init = { 1, 3, 5, 15, 23, 25, 63, 53, 23, 263, 1681, 3305, 461, 9875, 0 }; + static ulong[] dim1373Kuo2Init = { 1, 1, 3, 5, 5, 15, 71, 217, 493, 323, 1451, 1629, 7677, 15945, 0 }; + static ulong[] dim1374Kuo2Init = { 1, 1, 5, 9, 31, 53, 95, 37, 357, 61, 1601, 3565, 3705, 6617, 0 }; + static ulong[] dim1375Kuo2Init = { 1, 3, 1, 5, 17, 33, 81, 119, 233, 219, 1429, 2183, 771, 7199, 0 }; + static ulong[] dim1376Kuo2Init = { 1, 1, 7, 9, 27, 17, 7, 17, 281, 959, 1065, 3489, 6665, 14469, 0 }; + static ulong[] dim1377Kuo2Init = { 1, 3, 1, 15, 21, 15, 99, 77, 437, 571, 207, 609, 7287, 9395, 0 }; + static ulong[] dim1378Kuo2Init = { 1, 1, 7, 1, 1, 49, 39, 189, 111, 65, 1345, 2559, 7835, 9869, 0 }; + static ulong[] dim1379Kuo2Init = { 1, 1, 1, 1, 27, 17, 93, 83, 339, 465, 1445, 3557, 6489, 6985, 0 }; + static ulong[] dim1380Kuo2Init = { 1, 1, 5, 3, 1, 7, 35, 39, 491, 563, 1815, 2513, 5523, 12691, 0 }; + static ulong[] dim1381Kuo2Init = { 1, 1, 3, 5, 3, 31, 127, 91, 87, 447, 1237, 3419, 6979, 6311, 0 }; + static ulong[] dim1382Kuo2Init = { 1, 1, 7, 3, 25, 61, 45, 219, 455, 859, 781, 2991, 6585, 11511, 0 }; + static ulong[] dim1383Kuo2Init = { 1, 3, 3, 13, 15, 37, 77, 211, 403, 349, 35, 2785, 4439, 5715, 0 }; + static ulong[] dim1384Kuo2Init = { 1, 1, 3, 1, 1, 19, 45, 37, 459, 839, 17, 3223, 6411, 9209, 0 }; + static ulong[] dim1385Kuo2Init = { 1, 3, 1, 3, 27, 43, 63, 241, 455, 593, 1855, 3689, 7825, 10197, 0 }; + static ulong[] dim1386Kuo2Init = { 1, 3, 3, 1, 5, 17, 71, 209, 57, 991, 617, 3097, 5431, 2057, 0 }; + static ulong[] dim1387Kuo2Init = { 1, 1, 5, 15, 31, 21, 119, 53, 447, 969, 335, 3793, 3225, 9809, 0 }; + static ulong[] dim1388Kuo2Init = { 1, 1, 1, 11, 17, 51, 17, 7, 257, 221, 119, 2631, 6395, 8495, 0 }; + static ulong[] dim1389Kuo2Init = { 1, 3, 1, 15, 31, 13, 3, 9, 479, 233, 1051, 1953, 7863, 5969, 0 }; + static ulong[] dim1390Kuo2Init = { 1, 3, 1, 9, 13, 49, 57, 161, 65, 871, 2021, 3337, 7071, 12969, 0 }; + static ulong[] dim1391Kuo2Init = { 1, 3, 5, 15, 1, 53, 3, 77, 487, 207, 1761, 847, 3131, 1933, 0 }; + static ulong[] dim1392Kuo2Init = { 1, 3, 1, 7, 7, 21, 55, 217, 167, 113, 1029, 2761, 2063, 5267, 0 }; + static ulong[] dim1393Kuo2Init = { 1, 3, 3, 7, 15, 57, 119, 9, 211, 93, 209, 2905, 2589, 12341, 0 }; + static ulong[] dim1394Kuo2Init = { 1, 3, 1, 15, 25, 7, 41, 87, 451, 613, 353, 2619, 6015, 14003, 0 }; + static ulong[] dim1395Kuo2Init = { 1, 3, 3, 11, 23, 5, 3, 145, 471, 685, 3, 3431, 2843, 11725, 0 }; + static ulong[] dim1396Kuo2Init = { 1, 3, 7, 11, 13, 45, 73, 45, 169, 395, 1279, 2589, 1419, 14965, 0 }; + static ulong[] dim1397Kuo2Init = { 1, 3, 5, 9, 25, 23, 77, 149, 27, 441, 1391, 1853, 3993, 15507, 0 }; + static ulong[] dim1398Kuo2Init = { 1, 1, 1, 7, 21, 33, 39, 59, 161, 399, 447, 1249, 5407, 11825, 0 }; + static ulong[] dim1399Kuo2Init = { 1, 1, 5, 3, 25, 53, 37, 237, 91, 625, 1195, 1161, 7005, 7831, 0 }; + static ulong[] dim1400Kuo2Init = { 1, 3, 7, 5, 7, 63, 37, 101, 399, 645, 545, 3419, 6619, 2179, 0 }; + static ulong[] dim1401Kuo2Init = { 1, 1, 5, 11, 11, 51, 103, 207, 267, 909, 1975, 2279, 1991, 1891, 0 }; + static ulong[] dim1402Kuo2Init = { 1, 1, 7, 1, 27, 45, 9, 1, 423, 197, 697, 2765, 2653, 2613, 0 }; + static ulong[] dim1403Kuo2Init = { 1, 3, 7, 1, 27, 13, 45, 47, 493, 131, 565, 1363, 4921, 10023, 0 }; + static ulong[] dim1404Kuo2Init = { 1, 3, 7, 1, 7, 47, 99, 107, 343, 933, 1017, 3931, 1329, 2833, 0 }; + static ulong[] dim1405Kuo2Init = { 1, 1, 3, 1, 13, 9, 5, 131, 475, 537, 1857, 2579, 6377, 14363, 0 }; + static ulong[] dim1406Kuo2Init = { 1, 1, 5, 5, 15, 7, 87, 39, 51, 563, 1145, 3639, 4261, 9585, 0 }; + static ulong[] dim1407Kuo2Init = { 1, 3, 1, 3, 3, 61, 23, 223, 221, 165, 315, 2475, 7907, 10171, 0 }; + static ulong[] dim1408Kuo2Init = { 1, 1, 3, 9, 23, 57, 121, 171, 439, 101, 261, 1115, 1291, 2951, 0 }; + static ulong[] dim1409Kuo2Init = { 1, 1, 1, 9, 15, 23, 81, 189, 301, 515, 297, 915, 763, 11037, 0 }; + static ulong[] dim1410Kuo2Init = { 1, 3, 5, 9, 17, 45, 33, 101, 65, 687, 2011, 1821, 6891, 7321, 0 }; + static ulong[] dim1411Kuo2Init = { 1, 3, 5, 5, 9, 61, 11, 69, 345, 211, 393, 331, 3953, 13987, 0 }; + static ulong[] dim1412Kuo2Init = { 1, 1, 5, 15, 9, 23, 11, 45, 325, 1019, 1499, 831, 127, 9237, 0 }; + static ulong[] dim1413Kuo2Init = { 1, 1, 5, 5, 19, 9, 53, 213, 417, 761, 1275, 2117, 465, 15195, 0 }; + static ulong[] dim1414Kuo2Init = { 1, 3, 1, 7, 25, 53, 57, 95, 31, 791, 345, 3769, 3487, 4269, 0 }; + static ulong[] dim1415Kuo2Init = { 1, 3, 3, 1, 17, 9, 127, 203, 67, 435, 281, 3857, 819, 11235, 0 }; + static ulong[] dim1416Kuo2Init = { 1, 3, 1, 7, 23, 45, 127, 197, 501, 11, 1125, 2781, 7979, 1699, 0 }; + static ulong[] dim1417Kuo2Init = { 1, 3, 3, 13, 21, 21, 57, 125, 225, 593, 27, 539, 7989, 9597, 0 }; + static ulong[] dim1418Kuo2Init = { 1, 3, 7, 7, 29, 27, 57, 19, 51, 981, 205, 169, 5713, 4777, 0 }; + static ulong[] dim1419Kuo2Init = { 1, 3, 7, 7, 1, 59, 57, 61, 145, 683, 1043, 11, 5277, 5095, 0 }; + static ulong[] dim1420Kuo2Init = { 1, 1, 1, 3, 7, 39, 123, 251, 259, 295, 1333, 395, 5463, 11593, 0 }; + static ulong[] dim1421Kuo2Init = { 1, 1, 7, 15, 1, 9, 71, 79, 299, 1007, 1403, 237, 4845, 10521, 0 }; + static ulong[] dim1422Kuo2Init = { 1, 1, 5, 5, 11, 51, 45, 51, 489, 865, 511, 1415, 7867, 4235, 0 }; + static ulong[] dim1423Kuo2Init = { 1, 3, 3, 9, 23, 31, 83, 77, 461, 111, 1985, 3401, 271, 9763, 0 }; + static ulong[] dim1424Kuo2Init = { 1, 3, 5, 11, 19, 53, 45, 135, 171, 593, 1761, 1019, 7715, 9835, 0 }; + static ulong[] dim1425Kuo2Init = { 1, 1, 3, 5, 21, 47, 95, 1, 419, 547, 447, 3475, 7829, 12019, 0 }; + static ulong[] dim1426Kuo2Init = { 1, 3, 7, 13, 15, 29, 21, 197, 491, 997, 453, 3415, 745, 11259, 0 }; + static ulong[] dim1427Kuo2Init = { 1, 1, 3, 11, 19, 39, 99, 83, 35, 941, 1175, 2749, 4181, 8791, 0 }; + static ulong[] dim1428Kuo2Init = { 1, 1, 5, 7, 23, 3, 101, 11, 81, 291, 1815, 3391, 7615, 1305, 0 }; + static ulong[] dim1429Kuo2Init = { 1, 3, 5, 13, 27, 35, 71, 185, 87, 939, 1025, 1577, 5919, 5335, 0 }; + static ulong[] dim1430Kuo2Init = { 1, 3, 3, 9, 3, 31, 23, 213, 371, 595, 2003, 647, 909, 7503, 0 }; + static ulong[] dim1431Kuo2Init = { 1, 1, 5, 9, 31, 63, 125, 113, 273, 985, 1049, 1819, 2773, 6495, 0 }; + static ulong[] dim1432Kuo2Init = { 1, 1, 1, 5, 21, 7, 87, 207, 455, 403, 677, 175, 531, 10467, 0 }; + static ulong[] dim1433Kuo2Init = { 1, 1, 5, 1, 3, 45, 109, 75, 429, 983, 423, 3491, 7949, 15253, 0 }; + static ulong[] dim1434Kuo2Init = { 1, 1, 3, 1, 23, 27, 91, 5, 235, 121, 1087, 325, 5191, 8271, 0 }; + static ulong[] dim1435Kuo2Init = { 1, 3, 3, 15, 29, 63, 91, 129, 305, 827, 1311, 2765, 253, 1495, 0 }; + static ulong[] dim1436Kuo2Init = { 1, 3, 1, 15, 21, 45, 7, 21, 169, 275, 629, 589, 4623, 5491, 0 }; + static ulong[] dim1437Kuo2Init = { 1, 3, 1, 3, 13, 45, 127, 105, 377, 49, 1161, 489, 595, 7041, 0 }; + static ulong[] dim1438Kuo2Init = { 1, 1, 5, 11, 31, 61, 91, 1, 35, 189, 1479, 2041, 1585, 13009, 0 }; + static ulong[] dim1439Kuo2Init = { 1, 3, 3, 1, 23, 47, 69, 47, 361, 375, 77, 3777, 5769, 9925, 0 }; + static ulong[] dim1440Kuo2Init = { 1, 3, 3, 9, 5, 13, 31, 119, 411, 735, 839, 2919, 543, 12929, 0 }; + static ulong[] dim1441Kuo2Init = { 1, 3, 5, 11, 19, 5, 29, 185, 115, 841, 507, 1433, 5091, 3593, 0 }; + static ulong[] dim1442Kuo2Init = { 1, 3, 1, 13, 15, 19, 23, 83, 319, 99, 785, 697, 3703, 8733, 0 }; + static ulong[] dim1443Kuo2Init = { 1, 3, 5, 3, 7, 31, 53, 213, 287, 797, 1807, 879, 4227, 12013, 0 }; + static ulong[] dim1444Kuo2Init = { 1, 3, 3, 1, 23, 53, 91, 173, 253, 971, 1017, 2185, 4911, 15359, 0 }; + static ulong[] dim1445Kuo2Init = { 1, 3, 7, 3, 17, 27, 77, 225, 97, 199, 607, 1615, 963, 671, 0 }; + static ulong[] dim1446Kuo2Init = { 1, 1, 5, 11, 9, 61, 3, 105, 455, 953, 455, 3925, 3947, 7873, 0 }; + static ulong[] dim1447Kuo2Init = { 1, 3, 7, 7, 3, 49, 121, 109, 239, 855, 789, 3627, 3873, 6785, 0 }; + static ulong[] dim1448Kuo2Init = { 1, 1, 5, 5, 29, 35, 99, 159, 17, 221, 855, 2081, 2791, 11413, 0 }; + static ulong[] dim1449Kuo2Init = { 1, 3, 7, 5, 23, 53, 75, 93, 207, 189, 2035, 1829, 7581, 1425, 0 }; + static ulong[] dim1450Kuo2Init = { 1, 1, 3, 9, 3, 61, 61, 237, 53, 875, 1617, 727, 2683, 15797, 0 }; + static ulong[] dim1451Kuo2Init = { 1, 1, 1, 11, 23, 3, 105, 107, 353, 579, 119, 3041, 3005, 15581, 0 }; + static ulong[] dim1452Kuo2Init = { 1, 1, 1, 11, 31, 15, 89, 215, 161, 39, 629, 2873, 1635, 1029, 0 }; + static ulong[] dim1453Kuo2Init = { 1, 3, 3, 15, 15, 25, 53, 27, 167, 497, 1795, 1283, 7869, 15821, 0 }; + static ulong[] dim1454Kuo2Init = { 1, 3, 7, 3, 27, 39, 111, 29, 445, 365, 273, 2183, 475, 12503, 0 }; + static ulong[] dim1455Kuo2Init = { 1, 3, 7, 5, 9, 13, 25, 115, 419, 387, 1663, 3445, 157, 10549, 0 }; + static ulong[] dim1456Kuo2Init = { 1, 1, 5, 13, 23, 39, 7, 247, 127, 285, 675, 1785, 1823, 10183, 0 }; + static ulong[] dim1457Kuo2Init = { 1, 1, 1, 11, 31, 39, 93, 19, 125, 453, 1963, 2619, 6195, 2231, 0 }; + static ulong[] dim1458Kuo2Init = { 1, 1, 7, 3, 31, 51, 59, 19, 15, 251, 749, 2469, 369, 15413, 0 }; + static ulong[] dim1459Kuo2Init = { 1, 1, 7, 9, 19, 59, 111, 255, 91, 89, 1447, 353, 6701, 7955, 0 }; + static ulong[] dim1460Kuo2Init = { 1, 1, 7, 3, 3, 21, 115, 159, 489, 609, 1993, 2961, 3117, 3977, 0 }; + static ulong[] dim1461Kuo2Init = { 1, 3, 7, 13, 13, 13, 57, 41, 5, 337, 2005, 2587, 3873, 12829, 0 }; + static ulong[] dim1462Kuo2Init = { 1, 1, 3, 9, 9, 3, 39, 165, 155, 353, 985, 2221, 2973, 6331, 0 }; + static ulong[] dim1463Kuo2Init = { 1, 3, 3, 5, 3, 15, 121, 191, 367, 513, 1765, 3957, 3113, 10669, 0 }; + static ulong[] dim1464Kuo2Init = { 1, 3, 7, 1, 13, 41, 63, 241, 405, 43, 1211, 1499, 1095, 11867, 0 }; + static ulong[] dim1465Kuo2Init = { 1, 3, 7, 15, 17, 17, 63, 197, 377, 981, 1615, 2407, 6669, 411, 0 }; + static ulong[] dim1466Kuo2Init = { 1, 1, 3, 1, 3, 39, 85, 15, 9, 747, 423, 3103, 7341, 10953, 0 }; + static ulong[] dim1467Kuo2Init = { 1, 1, 7, 13, 25, 9, 17, 137, 267, 405, 1819, 641, 7305, 13971, 0 }; + static ulong[] dim1468Kuo2Init = { 1, 3, 5, 5, 19, 45, 121, 65, 385, 715, 267, 1841, 6317, 5827, 0 }; + static ulong[] dim1469Kuo2Init = { 1, 1, 7, 9, 11, 31, 57, 123, 107, 913, 669, 1053, 1213, 8791, 0 }; + static ulong[] dim1470Kuo2Init = { 1, 1, 3, 7, 21, 3, 57, 227, 401, 443, 1847, 3523, 4717, 2505, 0 }; + static ulong[] dim1471Kuo2Init = { 1, 3, 3, 15, 29, 41, 67, 217, 431, 37, 1775, 297, 1921, 8715, 0 }; + static ulong[] dim1472Kuo2Init = { 1, 3, 7, 7, 27, 35, 113, 57, 23, 927, 141, 1363, 4209, 4399, 0 }; + static ulong[] dim1473Kuo2Init = { 1, 1, 7, 9, 19, 51, 107, 189, 463, 695, 1931, 1541, 1285, 15703, 0 }; + static ulong[] dim1474Kuo2Init = { 1, 3, 5, 7, 29, 43, 109, 117, 389, 7, 1129, 1945, 6987, 799, 0 }; + static ulong[] dim1475Kuo2Init = { 1, 1, 1, 13, 9, 7, 119, 61, 385, 315, 1953, 1745, 8117, 15863, 0 }; + static ulong[] dim1476Kuo2Init = { 1, 1, 7, 7, 21, 55, 95, 113, 293, 899, 1327, 161, 6613, 14949, 0 }; + static ulong[] dim1477Kuo2Init = { 1, 1, 7, 9, 19, 21, 89, 5, 477, 441, 1477, 1995, 6633, 5523, 0 }; + static ulong[] dim1478Kuo2Init = { 1, 3, 3, 11, 15, 27, 17, 239, 263, 267, 1729, 3583, 4117, 13637, 0 }; + static ulong[] dim1479Kuo2Init = { 1, 1, 5, 5, 11, 53, 15, 201, 401, 845, 741, 2803, 3087, 9001, 0 }; + static ulong[] dim1480Kuo2Init = { 1, 3, 3, 11, 17, 21, 65, 109, 163, 251, 1487, 1541, 481, 10545, 0 }; + static ulong[] dim1481Kuo2Init = { 1, 3, 3, 13, 21, 61, 71, 121, 331, 551, 1237, 805, 3799, 1437, 0 }; + static ulong[] dim1482Kuo2Init = { 1, 3, 1, 11, 21, 29, 61, 161, 193, 745, 935, 1013, 3507, 6091, 0 }; + static ulong[] dim1483Kuo2Init = { 1, 3, 7, 15, 5, 59, 99, 147, 467, 625, 1873, 3459, 5749, 10571, 0 }; + static ulong[] dim1484Kuo2Init = { 1, 3, 1, 3, 9, 21, 57, 63, 205, 891, 1963, 2271, 6303, 9565, 0 }; + static ulong[] dim1485Kuo2Init = { 1, 1, 1, 1, 17, 55, 21, 105, 181, 763, 763, 337, 2283, 5203, 0 }; + static ulong[] dim1486Kuo2Init = { 1, 3, 3, 11, 25, 33, 7, 107, 329, 49, 31, 995, 757, 9781, 0 }; + static ulong[] dim1487Kuo2Init = { 1, 3, 7, 13, 17, 19, 107, 189, 359, 709, 819, 3943, 1891, 12173, 0 }; + static ulong[] dim1488Kuo2Init = { 1, 1, 7, 5, 3, 55, 121, 37, 493, 579, 2021, 3129, 6519, 14569, 0 }; + static ulong[] dim1489Kuo2Init = { 1, 1, 5, 15, 17, 3, 59, 75, 453, 323, 1559, 3695, 7711, 7665, 0 }; + static ulong[] dim1490Kuo2Init = { 1, 3, 3, 7, 9, 35, 121, 179, 345, 973, 337, 3655, 3815, 6317, 0 }; + static ulong[] dim1491Kuo2Init = { 1, 3, 7, 7, 9, 27, 59, 253, 9, 221, 587, 1087, 7295, 12193, 0 }; + static ulong[] dim1492Kuo2Init = { 1, 1, 3, 7, 27, 1, 105, 99, 49, 555, 2019, 2863, 5211, 2485, 0 }; + static ulong[] dim1493Kuo2Init = { 1, 1, 3, 15, 25, 55, 23, 221, 501, 671, 11, 1801, 6485, 14983, 0 }; + static ulong[] dim1494Kuo2Init = { 1, 3, 1, 3, 27, 45, 69, 159, 77, 541, 1441, 2043, 5609, 6799, 0 }; + static ulong[] dim1495Kuo2Init = { 1, 1, 5, 3, 21, 31, 7, 197, 511, 299, 1523, 3341, 301, 8639, 0 }; + static ulong[] dim1496Kuo2Init = { 1, 1, 7, 1, 9, 59, 63, 253, 191, 653, 383, 1239, 7839, 3699, 0 }; + static ulong[] dim1497Kuo2Init = { 1, 1, 3, 9, 13, 33, 73, 209, 125, 939, 1507, 3527, 6039, 14027, 0 }; + static ulong[] dim1498Kuo2Init = { 1, 1, 3, 13, 13, 21, 5, 15, 301, 625, 713, 2867, 3129, 4939, 0 }; + static ulong[] dim1499Kuo2Init = { 1, 1, 1, 13, 23, 5, 115, 69, 101, 327, 563, 2623, 6491, 7381, 0 }; + static ulong[] dim1500Kuo2Init = { 1, 1, 5, 7, 9, 53, 1, 91, 53, 823, 281, 2281, 6509, 2515, 0 }; + static ulong[] dim1501Kuo2Init = { 1, 1, 5, 5, 13, 61, 105, 183, 39, 493, 773, 1815, 1549, 7511, 0 }; + static ulong[] dim1502Kuo2Init = { 1, 1, 3, 13, 29, 27, 97, 205, 425, 13, 1227, 625, 137, 6785, 0 }; + static ulong[] dim1503Kuo2Init = { 1, 3, 7, 11, 13, 29, 105, 85, 251, 151, 1515, 3137, 8051, 14333, 0 }; + static ulong[] dim1504Kuo2Init = { 1, 3, 7, 9, 25, 59, 99, 43, 435, 361, 297, 449, 5633, 5813, 0 }; + static ulong[] dim1505Kuo2Init = { 1, 3, 1, 13, 17, 45, 113, 79, 315, 781, 785, 3463, 1299, 5959, 0 }; + static ulong[] dim1506Kuo2Init = { 1, 1, 7, 15, 19, 47, 35, 13, 487, 227, 1965, 4035, 4285, 14395, 0 }; + static ulong[] dim1507Kuo2Init = { 1, 3, 7, 5, 9, 41, 91, 127, 101, 519, 1147, 3851, 7929, 1807, 0 }; + static ulong[] dim1508Kuo2Init = { 1, 1, 7, 1, 19, 63, 45, 75, 437, 309, 1327, 3913, 5961, 2825, 0 }; + static ulong[] dim1509Kuo2Init = { 1, 1, 1, 15, 11, 1, 77, 11, 105, 499, 859, 2403, 4453, 12297, 0 }; + static ulong[] dim1510Kuo2Init = { 1, 1, 5, 5, 9, 33, 87, 85, 167, 35, 501, 1027, 4489, 10513, 0 }; + static ulong[] dim1511Kuo2Init = { 1, 1, 7, 13, 5, 3, 75, 75, 417, 319, 423, 1107, 371, 12493, 0 }; + static ulong[] dim1512Kuo2Init = { 1, 3, 7, 7, 15, 57, 7, 105, 95, 287, 1865, 2795, 5187, 543, 0 }; + static ulong[] dim1513Kuo2Init = { 1, 1, 1, 11, 1, 3, 121, 99, 299, 415, 47, 997, 2939, 8529, 0 }; + static ulong[] dim1514Kuo2Init = { 1, 1, 7, 11, 23, 17, 101, 209, 267, 459, 1965, 2153, 6361, 9553, 0 }; + static ulong[] dim1515Kuo2Init = { 1, 1, 3, 5, 1, 9, 7, 17, 109, 245, 701, 2161, 2109, 3301, 0 }; + static ulong[] dim1516Kuo2Init = { 1, 3, 5, 3, 13, 21, 113, 159, 261, 467, 127, 437, 8071, 11647, 0 }; + static ulong[] dim1517Kuo2Init = { 1, 3, 1, 15, 29, 63, 93, 31, 189, 881, 17, 2689, 1273, 4991, 0 }; + static ulong[] dim1518Kuo2Init = { 1, 3, 3, 7, 31, 23, 39, 177, 505, 207, 67, 2897, 315, 5981, 0 }; + static ulong[] dim1519Kuo2Init = { 1, 3, 5, 5, 31, 19, 87, 237, 119, 439, 1893, 3079, 3709, 15051, 0 }; + static ulong[] dim1520Kuo2Init = { 1, 3, 5, 1, 31, 35, 125, 173, 197, 765, 1419, 465, 1919, 2641, 0 }; + static ulong[] dim1521Kuo2Init = { 1, 1, 5, 11, 19, 15, 49, 255, 447, 939, 137, 2371, 6617, 79, 0 }; + static ulong[] dim1522Kuo2Init = { 1, 3, 3, 1, 11, 29, 81, 81, 327, 593, 135, 415, 2417, 8671, 0 }; + static ulong[] dim1523Kuo2Init = { 1, 1, 7, 11, 11, 35, 9, 143, 311, 57, 557, 793, 6597, 12979, 0 }; + static ulong[] dim1524Kuo2Init = { 1, 1, 7, 1, 27, 1, 105, 149, 417, 605, 431, 2419, 4113, 5651, 0 }; + static ulong[] dim1525Kuo2Init = { 1, 1, 3, 15, 1, 45, 63, 119, 167, 607, 961, 2561, 7839, 13343, 0 }; + static ulong[] dim1526Kuo2Init = { 1, 1, 5, 15, 11, 47, 75, 209, 175, 219, 443, 1311, 3383, 14073, 0 }; + static ulong[] dim1527Kuo2Init = { 1, 3, 5, 15, 17, 49, 97, 3, 343, 515, 129, 2243, 1567, 6119, 0 }; + static ulong[] dim1528Kuo2Init = { 1, 1, 3, 13, 3, 31, 111, 173, 97, 211, 69, 1771, 3039, 10305, 0 }; + static ulong[] dim1529Kuo2Init = { 1, 1, 1, 11, 7, 27, 5, 163, 277, 959, 1287, 3603, 2617, 12883, 0 }; + static ulong[] dim1530Kuo2Init = { 1, 1, 7, 5, 7, 63, 25, 235, 301, 575, 1979, 1519, 5765, 6331, 0 }; + static ulong[] dim1531Kuo2Init = { 1, 3, 5, 7, 23, 35, 43, 171, 481, 559, 1495, 665, 6325, 2733, 0 }; + static ulong[] dim1532Kuo2Init = { 1, 1, 7, 5, 3, 55, 99, 141, 37, 757, 11, 911, 2523, 11031, 0 }; + static ulong[] dim1533Kuo2Init = { 1, 1, 5, 7, 17, 9, 91, 9, 141, 693, 581, 2151, 3527, 11575, 0 }; + static ulong[] dim1534Kuo2Init = { 1, 1, 7, 1, 19, 31, 23, 59, 215, 873, 161, 1719, 509, 4509, 0 }; + static ulong[] dim1535Kuo2Init = { 1, 1, 7, 9, 17, 29, 57, 31, 233, 109, 865, 759, 3289, 11595, 0 }; + static ulong[] dim1536Kuo2Init = { 1, 3, 3, 15, 5, 61, 17, 69, 413, 95, 41, 1375, 1959, 11945, 0 }; + static ulong[] dim1537Kuo2Init = { 1, 3, 7, 1, 25, 3, 77, 9, 301, 117, 255, 3169, 3493, 5503, 0 }; + static ulong[] dim1538Kuo2Init = { 1, 1, 5, 3, 31, 1, 87, 211, 45, 185, 329, 3883, 3621, 4007, 0 }; + static ulong[] dim1539Kuo2Init = { 1, 1, 5, 15, 11, 5, 123, 131, 479, 981, 921, 3557, 5897, 9387, 0 }; + static ulong[] dim1540Kuo2Init = { 1, 1, 3, 3, 9, 43, 25, 57, 151, 975, 403, 727, 1155, 13495, 0 }; + static ulong[] dim1541Kuo2Init = { 1, 3, 3, 15, 29, 59, 31, 169, 201, 1007, 1017, 3121, 3989, 7835, 0 }; + static ulong[] dim1542Kuo2Init = { 1, 1, 3, 9, 19, 7, 103, 137, 135, 855, 179, 2859, 6959, 9749, 0 }; + static ulong[] dim1543Kuo2Init = { 1, 3, 3, 15, 3, 3, 121, 231, 461, 511, 1203, 2105, 6379, 6809, 0 }; + static ulong[] dim1544Kuo2Init = { 1, 1, 7, 15, 29, 5, 19, 215, 13, 813, 1421, 1725, 7809, 2379, 0 }; + static ulong[] dim1545Kuo2Init = { 1, 3, 5, 1, 9, 55, 127, 129, 95, 449, 1607, 4043, 5175, 6063, 0 }; + static ulong[] dim1546Kuo2Init = { 1, 1, 1, 9, 17, 31, 103, 107, 89, 5, 1747, 3405, 5739, 1959, 0 }; + static ulong[] dim1547Kuo2Init = { 1, 3, 1, 15, 5, 43, 41, 15, 453, 691, 739, 3755, 6597, 9737, 0 }; + static ulong[] dim1548Kuo2Init = { 1, 1, 3, 5, 27, 55, 111, 19, 349, 753, 1667, 3683, 4617, 12663, 0 }; + static ulong[] dim1549Kuo2Init = { 1, 1, 5, 11, 29, 57, 111, 187, 45, 957, 2001, 2743, 2813, 3831, 0 }; + static ulong[] dim1550Kuo2Init = { 1, 3, 7, 5, 13, 63, 25, 59, 169, 577, 301, 1535, 5355, 15835, 0 }; + static ulong[] dim1551Kuo2Init = { 1, 3, 3, 7, 7, 25, 101, 249, 59, 217, 557, 2565, 5103, 13787, 0 }; + static ulong[] dim1552Kuo2Init = { 1, 3, 7, 9, 5, 31, 97, 19, 435, 205, 1217, 3659, 7687, 8381, 0 }; + static ulong[] dim1553Kuo2Init = { 1, 1, 1, 5, 7, 33, 41, 89, 243, 769, 1915, 2235, 757, 367, 0 }; + static ulong[] dim1554Kuo2Init = { 1, 1, 1, 15, 3, 11, 103, 41, 79, 585, 1661, 1739, 2075, 15113, 0 }; + static ulong[] dim1555Kuo2Init = { 1, 1, 5, 5, 5, 53, 103, 167, 387, 591, 317, 2539, 3763, 3341, 0 }; + static ulong[] dim1556Kuo2Init = { 1, 1, 7, 7, 31, 29, 69, 43, 257, 471, 435, 3895, 445, 10941, 0 }; + static ulong[] dim1557Kuo2Init = { 1, 1, 1, 9, 13, 63, 3, 167, 447, 569, 949, 2289, 6383, 5887, 0 }; + static ulong[] dim1558Kuo2Init = { 1, 1, 5, 5, 11, 31, 35, 9, 383, 933, 519, 3773, 4987, 2737, 0 }; + static ulong[] dim1559Kuo2Init = { 1, 1, 7, 7, 15, 17, 121, 109, 299, 579, 683, 1365, 2471, 14275, 0 }; + static ulong[] dim1560Kuo2Init = { 1, 1, 1, 9, 19, 9, 17, 229, 405, 545, 1923, 991, 473, 11233, 0 }; + static ulong[] dim1561Kuo2Init = { 1, 1, 3, 13, 13, 1, 101, 241, 51, 885, 1835, 1095, 2917, 15167, 0 }; + static ulong[] dim1562Kuo2Init = { 1, 3, 5, 3, 31, 35, 127, 17, 153, 415, 769, 299, 7791, 8697, 0 }; + static ulong[] dim1563Kuo2Init = { 1, 3, 3, 3, 23, 35, 77, 237, 427, 611, 2025, 3201, 7855, 789, 0 }; + static ulong[] dim1564Kuo2Init = { 1, 3, 1, 5, 9, 25, 123, 215, 387, 939, 471, 1123, 6747, 14803, 0 }; + static ulong[] dim1565Kuo2Init = { 1, 1, 5, 15, 1, 55, 85, 249, 315, 253, 1705, 35, 7351, 11255, 0 }; + static ulong[] dim1566Kuo2Init = { 1, 3, 5, 3, 7, 15, 5, 167, 351, 145, 1891, 2691, 3035, 873, 0 }; + static ulong[] dim1567Kuo2Init = { 1, 3, 1, 15, 19, 33, 85, 241, 259, 625, 615, 97, 5977, 4777, 0 }; + static ulong[] dim1568Kuo2Init = { 1, 3, 7, 9, 19, 17, 9, 197, 141, 5, 355, 3001, 6903, 13809, 0 }; + static ulong[] dim1569Kuo2Init = { 1, 1, 7, 13, 9, 39, 79, 43, 465, 49, 849, 1509, 5251, 11239, 0 }; + static ulong[] dim1570Kuo2Init = { 1, 1, 7, 3, 5, 21, 37, 159, 461, 1015, 329, 4095, 2513, 6213, 0 }; + static ulong[] dim1571Kuo2Init = { 1, 1, 7, 7, 7, 19, 127, 15, 61, 439, 1381, 677, 2851, 1635, 0 }; + static ulong[] dim1572Kuo2Init = { 1, 1, 3, 5, 17, 19, 125, 171, 175, 441, 1153, 2445, 2907, 13089, 0 }; + static ulong[] dim1573Kuo2Init = { 1, 1, 7, 9, 17, 59, 53, 81, 5, 685, 1257, 3179, 5067, 10131, 0 }; + static ulong[] dim1574Kuo2Init = { 1, 1, 5, 3, 9, 47, 25, 111, 235, 117, 65, 2565, 865, 15173, 0 }; + static ulong[] dim1575Kuo2Init = { 1, 3, 1, 7, 27, 5, 55, 155, 221, 451, 1823, 1277, 1397, 15715, 0 }; + static ulong[] dim1576Kuo2Init = { 1, 1, 1, 15, 17, 5, 115, 209, 393, 973, 177, 825, 3315, 8333, 0 }; + static ulong[] dim1577Kuo2Init = { 1, 1, 3, 13, 23, 47, 121, 47, 379, 433, 807, 3723, 2595, 14727, 0 }; + static ulong[] dim1578Kuo2Init = { 1, 1, 3, 5, 29, 59, 39, 205, 327, 999, 1897, 3441, 5355, 12881, 0 }; + static ulong[] dim1579Kuo2Init = { 1, 1, 3, 3, 27, 63, 57, 175, 225, 353, 675, 2955, 6581, 2735, 0 }; + static ulong[] dim1580Kuo2Init = { 1, 3, 3, 1, 11, 55, 55, 191, 239, 579, 1355, 2449, 563, 9757, 0 }; + static ulong[] dim1581Kuo2Init = { 1, 1, 7, 5, 1, 49, 35, 19, 25, 783, 1453, 1063, 4811, 1449, 0 }; + static ulong[] dim1582Kuo2Init = { 1, 3, 1, 13, 11, 63, 17, 203, 479, 133, 1951, 385, 6803, 13453, 0 }; + static ulong[] dim1583Kuo2Init = { 1, 3, 7, 9, 21, 19, 15, 125, 397, 109, 1903, 4053, 6449, 8821, 0 }; + static ulong[] dim1584Kuo2Init = { 1, 3, 7, 15, 1, 33, 45, 161, 43, 729, 397, 4093, 8123, 3123, 0 }; + static ulong[] dim1585Kuo2Init = { 1, 3, 7, 7, 3, 35, 3, 183, 231, 351, 1381, 1251, 3423, 3361, 0 }; + static ulong[] dim1586Kuo2Init = { 1, 1, 1, 5, 23, 11, 71, 137, 323, 809, 827, 1573, 4483, 8691, 0 }; + static ulong[] dim1587Kuo2Init = { 1, 3, 7, 7, 17, 29, 121, 47, 139, 687, 95, 1507, 2009, 1679, 0 }; + static ulong[] dim1588Kuo2Init = { 1, 3, 7, 9, 25, 53, 127, 137, 295, 863, 299, 1831, 5359, 4787, 0 }; + static ulong[] dim1589Kuo2Init = { 1, 3, 1, 9, 29, 3, 83, 35, 367, 675, 1511, 381, 6675, 897, 0 }; + static ulong[] dim1590Kuo2Init = { 1, 3, 5, 13, 1, 15, 57, 199, 349, 873, 1059, 3767, 841, 16259, 0 }; + static ulong[] dim1591Kuo2Init = { 1, 3, 7, 3, 13, 5, 47, 203, 211, 899, 1107, 743, 6825, 8703, 0 }; + static ulong[] dim1592Kuo2Init = { 1, 3, 7, 11, 31, 41, 11, 59, 59, 859, 787, 977, 2223, 15921, 0 }; + static ulong[] dim1593Kuo2Init = { 1, 3, 5, 5, 31, 11, 39, 105, 109, 487, 1459, 2935, 3723, 4697, 0 }; + static ulong[] dim1594Kuo2Init = { 1, 3, 3, 13, 9, 17, 39, 239, 183, 885, 123, 387, 2369, 16179, 0 }; + static ulong[] dim1595Kuo2Init = { 1, 1, 1, 7, 25, 47, 23, 29, 95, 331, 2005, 633, 649, 1623, 0 }; + static ulong[] dim1596Kuo2Init = { 1, 1, 3, 13, 9, 21, 41, 125, 287, 309, 1421, 1637, 2611, 2259, 0 }; + static ulong[] dim1597Kuo2Init = { 1, 1, 3, 3, 11, 27, 117, 93, 419, 521, 1699, 233, 1967, 14147, 0 }; + static ulong[] dim1598Kuo2Init = { 1, 1, 3, 11, 25, 21, 61, 15, 415, 693, 1685, 1727, 961, 3887, 0 }; + static ulong[] dim1599Kuo2Init = { 1, 3, 7, 9, 15, 39, 41, 19, 237, 231, 1605, 2641, 6047, 10235, 0 }; + static ulong[] dim1600Kuo2Init = { 1, 1, 3, 9, 5, 49, 113, 133, 499, 545, 467, 683, 579, 8123, 0 }; + static ulong[] dim1601Kuo2Init = { 1, 3, 5, 13, 11, 31, 121, 229, 225, 135, 85, 1389, 5317, 13453, 0 }; + static ulong[] dim1602Kuo2Init = { 1, 3, 7, 9, 17, 51, 77, 141, 413, 805, 1759, 1139, 5847, 16153, 0 }; + static ulong[] dim1603Kuo2Init = { 1, 3, 5, 7, 23, 29, 79, 235, 113, 981, 1147, 219, 2609, 1089, 0 }; + static ulong[] dim1604Kuo2Init = { 1, 1, 5, 7, 5, 45, 123, 123, 335, 409, 115, 971, 827, 427, 0 }; + static ulong[] dim1605Kuo2Init = { 1, 3, 7, 13, 13, 45, 41, 173, 261, 151, 1199, 2803, 5801, 2449, 0 }; + static ulong[] dim1606Kuo2Init = { 1, 3, 1, 7, 5, 17, 9, 91, 475, 505, 1983, 2539, 339, 16365, 0 }; + static ulong[] dim1607Kuo2Init = { 1, 1, 7, 5, 25, 31, 77, 53, 293, 735, 1423, 165, 4363, 5923, 0 }; + static ulong[] dim1608Kuo2Init = { 1, 1, 1, 15, 7, 51, 117, 91, 347, 677, 1059, 2861, 3583, 11995, 0 }; + static ulong[] dim1609Kuo2Init = { 1, 3, 3, 13, 27, 27, 123, 251, 47, 885, 2015, 1089, 4077, 8591, 0 }; + static ulong[] dim1610Kuo2Init = { 1, 1, 7, 11, 17, 41, 97, 47, 201, 789, 881, 1565, 1169, 10967, 0 }; + static ulong[] dim1611Kuo2Init = { 1, 1, 3, 15, 25, 43, 45, 237, 73, 909, 1041, 1025, 3217, 9347, 0 }; + static ulong[] dim1612Kuo2Init = { 1, 1, 1, 3, 7, 59, 51, 177, 223, 125, 63, 3311, 3171, 8725, 0 }; + static ulong[] dim1613Kuo2Init = { 1, 1, 1, 1, 31, 25, 55, 117, 493, 419, 1749, 2799, 6943, 12427, 0 }; + static ulong[] dim1614Kuo2Init = { 1, 3, 5, 13, 1, 59, 123, 239, 239, 589, 667, 1029, 1357, 6801, 0 }; + static ulong[] dim1615Kuo2Init = { 1, 1, 7, 15, 21, 7, 43, 103, 159, 685, 1435, 529, 4225, 5051, 0 }; + static ulong[] dim1616Kuo2Init = { 1, 3, 1, 13, 29, 21, 19, 229, 369, 317, 1681, 685, 5301, 11107, 0 }; + static ulong[] dim1617Kuo2Init = { 1, 3, 7, 9, 17, 13, 117, 21, 203, 123, 1933, 3981, 5133, 11729, 0 }; + static ulong[] dim1618Kuo2Init = { 1, 3, 3, 1, 29, 5, 119, 27, 135, 913, 1891, 2785, 6311, 8439, 0 }; + static ulong[] dim1619Kuo2Init = { 1, 3, 7, 5, 3, 31, 95, 55, 89, 541, 609, 773, 6513, 10015, 0 }; + static ulong[] dim1620Kuo2Init = { 1, 3, 7, 1, 25, 27, 71, 153, 215, 921, 29, 2103, 1605, 59, 0 }; + static ulong[] dim1621Kuo2Init = { 1, 1, 3, 5, 15, 31, 65, 35, 221, 571, 873, 1271, 5399, 15659, 0 }; + static ulong[] dim1622Kuo2Init = { 1, 3, 5, 3, 31, 31, 127, 251, 379, 801, 905, 1661, 225, 11939, 0 }; + static ulong[] dim1623Kuo2Init = { 1, 3, 1, 15, 31, 59, 51, 117, 325, 491, 1801, 669, 2867, 5325, 0 }; + static ulong[] dim1624Kuo2Init = { 1, 1, 5, 13, 1, 15, 3, 105, 81, 229, 573, 3047, 6373, 11947, 0 }; + static ulong[] dim1625Kuo2Init = { 1, 1, 3, 9, 7, 51, 83, 103, 277, 5, 1189, 89, 7173, 1617, 0 }; + static ulong[] dim1626Kuo2Init = { 1, 1, 5, 3, 11, 13, 5, 205, 179, 23, 1327, 3049, 23, 5123, 0 }; + static ulong[] dim1627Kuo2Init = { 1, 3, 5, 7, 7, 23, 117, 133, 449, 265, 1087, 1565, 7185, 7099, 0 }; + static ulong[] dim1628Kuo2Init = { 1, 1, 3, 5, 7, 13, 31, 197, 29, 659, 1485, 2395, 3239, 5837, 0 }; + static ulong[] dim1629Kuo2Init = { 1, 3, 5, 13, 15, 53, 67, 107, 103, 675, 253, 471, 283, 1221, 0 }; + static ulong[] dim1630Kuo2Init = { 1, 1, 5, 11, 17, 17, 65, 165, 141, 839, 217, 3779, 1151, 3551, 0 }; + static ulong[] dim1631Kuo2Init = { 1, 1, 7, 13, 13, 23, 57, 241, 253, 565, 371, 3713, 4539, 1033, 0 }; + static ulong[] dim1632Kuo2Init = { 1, 1, 7, 11, 17, 11, 121, 193, 9, 33, 695, 1361, 6433, 895, 0 }; + static ulong[] dim1633Kuo2Init = { 1, 1, 1, 3, 15, 11, 87, 87, 419, 605, 163, 377, 3729, 4309, 0 }; + static ulong[] dim1634Kuo2Init = { 1, 3, 5, 3, 17, 43, 13, 99, 409, 919, 1347, 1407, 1723, 11317, 0 }; + static ulong[] dim1635Kuo2Init = { 1, 1, 1, 9, 1, 21, 111, 225, 191, 65, 1231, 27, 387, 12225, 0 }; + static ulong[] dim1636Kuo2Init = { 1, 1, 3, 11, 19, 63, 61, 103, 31, 241, 1807, 3101, 7275, 2333, 0 }; + static ulong[] dim1637Kuo2Init = { 1, 1, 7, 5, 31, 41, 115, 77, 347, 85, 69, 1911, 7345, 15269, 0 }; + static ulong[] dim1638Kuo2Init = { 1, 1, 7, 1, 25, 41, 105, 5, 161, 721, 1667, 1285, 6197, 14823, 0 }; + static ulong[] dim1639Kuo2Init = { 1, 3, 3, 9, 15, 33, 43, 155, 269, 215, 663, 3425, 7725, 15307, 0 }; + static ulong[] dim1640Kuo2Init = { 1, 3, 5, 15, 23, 43, 71, 79, 163, 167, 1207, 741, 141, 8269, 0 }; + static ulong[] dim1641Kuo2Init = { 1, 1, 7, 9, 21, 21, 39, 181, 379, 383, 343, 1685, 1713, 10377, 0 }; + static ulong[] dim1642Kuo2Init = { 1, 3, 3, 7, 3, 17, 45, 11, 351, 111, 229, 3241, 6953, 7143, 0 }; + static ulong[] dim1643Kuo2Init = { 1, 1, 7, 13, 15, 57, 87, 247, 361, 943, 801, 1861, 5705, 14499, 0 }; + static ulong[] dim1644Kuo2Init = { 1, 1, 5, 7, 11, 9, 89, 235, 235, 225, 1053, 2909, 993, 15471, 0 }; + static ulong[] dim1645Kuo2Init = { 1, 3, 3, 11, 15, 47, 73, 13, 477, 703, 1353, 3633, 4059, 16367, 0 }; + static ulong[] dim1646Kuo2Init = { 1, 1, 5, 15, 9, 39, 49, 141, 181, 917, 1331, 427, 7455, 13753, 0 }; + static ulong[] dim1647Kuo2Init = { 1, 3, 1, 13, 11, 7, 113, 101, 473, 851, 771, 1287, 8157, 2113, 0 }; + static ulong[] dim1648Kuo2Init = { 1, 3, 1, 15, 23, 33, 87, 5, 245, 853, 1433, 85, 5655, 11579, 0 }; + static ulong[] dim1649Kuo2Init = { 1, 1, 5, 15, 19, 59, 103, 249, 247, 589, 797, 2733, 6603, 2065, 0 }; + static ulong[] dim1650Kuo2Init = { 1, 1, 1, 7, 25, 63, 105, 183, 497, 25, 739, 521, 7327, 12711, 0 }; + static ulong[] dim1651Kuo2Init = { 1, 3, 3, 7, 27, 13, 63, 23, 417, 303, 155, 2227, 5621, 1643, 0 }; + static ulong[] dim1652Kuo2Init = { 1, 1, 5, 9, 29, 13, 75, 199, 353, 577, 1715, 3939, 2659, 5969, 0 }; + static ulong[] dim1653Kuo2Init = { 1, 1, 5, 11, 11, 37, 55, 185, 435, 763, 333, 3243, 7553, 9741, 0 }; + static ulong[] dim1654Kuo2Init = { 1, 3, 7, 13, 7, 1, 65, 243, 443, 869, 769, 4027, 4831, 7333, 0 }; + static ulong[] dim1655Kuo2Init = { 1, 1, 5, 11, 31, 23, 93, 117, 323, 157, 811, 1543, 449, 8371, 0 }; + static ulong[] dim1656Kuo2Init = { 1, 3, 1, 9, 27, 25, 87, 223, 467, 761, 547, 2381, 411, 14035, 0 }; + static ulong[] dim1657Kuo2Init = { 1, 1, 7, 9, 31, 27, 127, 11, 243, 263, 255, 831, 6801, 10923, 0 }; + static ulong[] dim1658Kuo2Init = { 1, 3, 5, 15, 23, 11, 77, 5, 255, 699, 13, 3883, 4703, 2785, 0 }; + static ulong[] dim1659Kuo2Init = { 1, 3, 1, 1, 25, 37, 47, 75, 79, 881, 1505, 2825, 2477, 1963, 0 }; + static ulong[] dim1660Kuo2Init = { 1, 1, 3, 7, 29, 39, 33, 151, 153, 869, 65, 107, 7173, 5059, 0 }; + static ulong[] dim1661Kuo2Init = { 1, 1, 5, 13, 29, 41, 61, 37, 353, 429, 587, 2431, 3711, 14149, 0 }; + static ulong[] dim1662Kuo2Init = { 1, 1, 3, 7, 13, 23, 29, 157, 427, 353, 1485, 879, 3851, 15775, 0 }; + static ulong[] dim1663Kuo2Init = { 1, 1, 5, 11, 7, 17, 91, 225, 275, 923, 1383, 2587, 7545, 7203, 0 }; + static ulong[] dim1664Kuo2Init = { 1, 1, 5, 3, 3, 57, 75, 97, 233, 233, 1547, 1915, 1229, 8559, 0 }; + static ulong[] dim1665Kuo2Init = { 1, 3, 3, 11, 11, 63, 15, 121, 209, 31, 171, 1117, 2373, 7545, 0 }; + static ulong[] dim1666Kuo2Init = { 1, 1, 1, 3, 27, 7, 89, 155, 7, 829, 537, 3639, 1721, 8199, 0 }; + static ulong[] dim1667Kuo2Init = { 1, 1, 1, 1, 5, 43, 59, 245, 321, 869, 785, 367, 2693, 8603, 0 }; + static ulong[] dim1668Kuo2Init = { 1, 1, 3, 1, 23, 17, 19, 79, 303, 919, 1119, 303, 907, 9033, 0 }; + static ulong[] dim1669Kuo2Init = { 1, 3, 1, 15, 17, 43, 1, 207, 395, 251, 727, 1341, 2073, 16319, 0 }; + static ulong[] dim1670Kuo2Init = { 1, 3, 3, 15, 3, 31, 97, 111, 161, 947, 1509, 2143, 4773, 3569, 0 }; + static ulong[] dim1671Kuo2Init = { 1, 3, 7, 3, 5, 33, 19, 149, 233, 221, 517, 21, 7651, 14987, 0 }; + static ulong[] dim1672Kuo2Init = { 1, 3, 3, 7, 19, 1, 39, 253, 311, 681, 897, 2777, 5181, 6985, 0 }; + static ulong[] dim1673Kuo2Init = { 1, 3, 5, 13, 3, 39, 75, 225, 491, 631, 513, 935, 2775, 6405, 0 }; + static ulong[] dim1674Kuo2Init = { 1, 3, 5, 9, 29, 57, 67, 67, 53, 955, 1297, 3871, 131, 7317, 0 }; + static ulong[] dim1675Kuo2Init = { 1, 3, 3, 9, 31, 55, 53, 179, 305, 625, 1097, 1203, 1973, 2807, 0 }; + static ulong[] dim1676Kuo2Init = { 1, 1, 1, 5, 5, 47, 25, 7, 279, 751, 1149, 2871, 2985, 11941, 0 }; + static ulong[] dim1677Kuo2Init = { 1, 3, 7, 5, 21, 47, 29, 23, 419, 181, 517, 1261, 2329, 11667, 0 }; + static ulong[] dim1678Kuo2Init = { 1, 1, 1, 3, 5, 53, 61, 1, 273, 165, 1227, 2901, 2739, 2453, 0 }; + static ulong[] dim1679Kuo2Init = { 1, 3, 1, 7, 1, 21, 89, 27, 487, 167, 717, 3653, 3971, 7825, 0 }; + static ulong[] dim1680Kuo2Init = { 1, 1, 3, 5, 3, 43, 19, 221, 21, 329, 1415, 1137, 1073, 2869, 0 }; + static ulong[] dim1681Kuo2Init = { 1, 1, 7, 13, 27, 61, 65, 93, 469, 975, 5, 3919, 7565, 13885, 0 }; + static ulong[] dim1682Kuo2Init = { 1, 1, 5, 9, 9, 9, 111, 97, 35, 595, 997, 797, 5963, 12977, 0 }; + static ulong[] dim1683Kuo2Init = { 1, 3, 7, 11, 5, 1, 125, 169, 393, 127, 1297, 3853, 1177, 10553, 0 }; + static ulong[] dim1684Kuo2Init = { 1, 1, 3, 13, 11, 53, 55, 119, 41, 895, 1379, 1955, 7059, 143, 0 }; + static ulong[] dim1685Kuo2Init = { 1, 3, 1, 7, 1, 9, 49, 165, 479, 247, 1555, 2199, 6695, 8983, 0 }; + static ulong[] dim1686Kuo2Init = { 1, 3, 3, 3, 17, 53, 47, 97, 301, 649, 1121, 7, 1335, 11535, 0 }; + static ulong[] dim1687Kuo2Init = { 1, 3, 1, 1, 25, 49, 5, 227, 335, 401, 651, 3089, 823, 3159, 0 }; + static ulong[] dim1688Kuo2Init = { 1, 1, 5, 7, 7, 25, 79, 15, 79, 381, 991, 2319, 6087, 5919, 0 }; + static ulong[] dim1689Kuo2Init = { 1, 3, 7, 3, 17, 53, 99, 237, 305, 411, 1751, 753, 4785, 57, 0 }; + static ulong[] dim1690Kuo2Init = { 1, 1, 5, 7, 15, 27, 91, 159, 451, 877, 715, 1183, 3619, 4521, 0 }; + static ulong[] dim1691Kuo2Init = { 1, 3, 7, 5, 25, 9, 9, 1, 421, 707, 1619, 1423, 7183, 687, 0 }; + static ulong[] dim1692Kuo2Init = { 1, 3, 7, 3, 3, 49, 79, 249, 299, 559, 1619, 2071, 8135, 1975, 0 }; + static ulong[] dim1693Kuo2Init = { 1, 3, 1, 9, 29, 63, 67, 93, 373, 505, 193, 791, 5761, 8329, 0 }; + static ulong[] dim1694Kuo2Init = { 1, 1, 3, 3, 7, 33, 33, 233, 507, 471, 1369, 3355, 27, 6389, 0 }; + static ulong[] dim1695Kuo2Init = { 1, 3, 3, 9, 21, 13, 25, 249, 39, 305, 827, 3559, 937, 6079, 0 }; + static ulong[] dim1696Kuo2Init = { 1, 1, 1, 13, 25, 29, 115, 165, 65, 217, 1519, 3117, 3211, 7211, 0 }; + static ulong[] dim1697Kuo2Init = { 1, 1, 1, 3, 21, 17, 55, 117, 61, 807, 1821, 703, 3403, 14181, 0 }; + static ulong[] dim1698Kuo2Init = { 1, 3, 5, 1, 3, 5, 65, 199, 399, 695, 1527, 1187, 7887, 15437, 0 }; + static ulong[] dim1699Kuo2Init = { 1, 3, 1, 3, 23, 47, 43, 49, 377, 893, 423, 3745, 4291, 2579, 0 }; + static ulong[] dim1700Kuo2Init = { 1, 3, 3, 13, 15, 13, 19, 235, 209, 963, 1331, 1559, 5631, 2411, 0 }; + static ulong[] dim1701Kuo2Init = { 1, 3, 5, 1, 3, 47, 5, 179, 483, 163, 123, 1241, 5767, 4361, 0 }; + static ulong[] dim1702Kuo2Init = { 1, 3, 5, 13, 15, 25, 123, 13, 313, 959, 1845, 3949, 7395, 5727, 0 }; + static ulong[] dim1703Kuo2Init = { 1, 3, 7, 7, 21, 35, 67, 209, 229, 213, 1403, 561, 4229, 13611, 0 }; + static ulong[] dim1704Kuo2Init = { 1, 3, 5, 15, 17, 45, 93, 5, 493, 779, 1357, 243, 2067, 4621, 0 }; + static ulong[] dim1705Kuo2Init = { 1, 3, 7, 1, 19, 29, 11, 219, 247, 133, 443, 1331, 5027, 6953, 0 }; + static ulong[] dim1706Kuo2Init = { 1, 1, 7, 5, 29, 41, 21, 95, 175, 761, 1425, 2471, 4597, 7071, 0 }; + static ulong[] dim1707Kuo2Init = { 1, 3, 7, 15, 25, 5, 49, 153, 415, 703, 321, 3727, 4541, 9711, 0 }; + static ulong[] dim1708Kuo2Init = { 1, 3, 5, 5, 21, 49, 15, 41, 203, 909, 953, 1587, 6323, 12589, 0 }; + static ulong[] dim1709Kuo2Init = { 1, 3, 3, 7, 29, 21, 59, 245, 287, 411, 1211, 2527, 5247, 11691, 0 }; + static ulong[] dim1710Kuo2Init = { 1, 1, 3, 15, 5, 29, 25, 123, 29, 613, 627, 269, 6479, 817, 0 }; + static ulong[] dim1711Kuo2Init = { 1, 3, 5, 3, 23, 11, 15, 177, 421, 803, 273, 3145, 7211, 7141, 0 }; + static ulong[] dim1712Kuo2Init = { 1, 1, 7, 13, 13, 37, 59, 81, 57, 349, 833, 871, 1343, 8911, 0 }; + static ulong[] dim1713Kuo2Init = { 1, 3, 5, 3, 23, 11, 33, 39, 123, 77, 259, 2667, 2121, 203, 0 }; + static ulong[] dim1714Kuo2Init = { 1, 3, 7, 5, 5, 57, 31, 101, 463, 633, 1351, 2209, 5235, 8591, 0 }; + static ulong[] dim1715Kuo2Init = { 1, 1, 7, 9, 1, 35, 39, 121, 155, 847, 1355, 2161, 3073, 5873, 0 }; + static ulong[] dim1716Kuo2Init = { 1, 3, 7, 11, 19, 23, 29, 233, 501, 321, 1131, 641, 4023, 11955, 0 }; + static ulong[] dim1717Kuo2Init = { 1, 3, 3, 7, 13, 39, 119, 157, 261, 167, 511, 2349, 1489, 11523, 0 }; + static ulong[] dim1718Kuo2Init = { 1, 3, 5, 15, 27, 3, 19, 165, 229, 591, 1975, 3411, 4453, 3291, 0 }; + static ulong[] dim1719Kuo2Init = { 1, 3, 5, 15, 11, 41, 61, 117, 505, 347, 957, 2545, 1123, 16229, 0 }; + static ulong[] dim1720Kuo2Init = { 1, 1, 5, 15, 1, 21, 101, 123, 341, 613, 451, 3731, 8031, 1611, 0 }; + static ulong[] dim1721Kuo2Init = { 1, 1, 5, 11, 27, 1, 53, 69, 509, 751, 407, 2777, 1319, 10897, 0 }; + static ulong[] dim1722Kuo2Init = { 1, 3, 5, 7, 7, 5, 127, 91, 17, 699, 1761, 2083, 4587, 10747, 0 }; + static ulong[] dim1723Kuo2Init = { 1, 3, 5, 11, 1, 57, 107, 245, 89, 899, 1765, 3521, 4933, 721, 0 }; + static ulong[] dim1724Kuo2Init = { 1, 1, 1, 1, 27, 49, 113, 201, 491, 921, 417, 3541, 5889, 8417, 0 }; + static ulong[] dim1725Kuo2Init = { 1, 3, 5, 11, 1, 37, 5, 43, 337, 883, 1351, 351, 269, 5501, 0 }; + static ulong[] dim1726Kuo2Init = { 1, 3, 5, 5, 9, 11, 127, 87, 463, 999, 635, 2355, 763, 11959, 0 }; + static ulong[] dim1727Kuo2Init = { 1, 3, 1, 15, 25, 21, 111, 241, 31, 35, 1869, 2913, 5963, 9989, 0 }; + static ulong[] dim1728Kuo2Init = { 1, 1, 7, 13, 23, 57, 7, 225, 115, 649, 395, 515, 5335, 10829, 0 }; + static ulong[] dim1729Kuo2Init = { 1, 3, 5, 13, 21, 21, 51, 1, 39, 927, 681, 1341, 7703, 631, 0 }; + static ulong[] dim1730Kuo2Init = { 1, 1, 3, 13, 25, 35, 101, 215, 15, 207, 137, 409, 6239, 11609, 0 }; + static ulong[] dim1731Kuo2Init = { 1, 3, 1, 15, 11, 47, 17, 131, 405, 633, 35, 3335, 821, 4681, 0 }; + static ulong[] dim1732Kuo2Init = { 1, 1, 1, 9, 17, 17, 105, 81, 449, 421, 707, 1041, 3991, 2943, 0 }; + static ulong[] dim1733Kuo2Init = { 1, 1, 1, 1, 29, 55, 43, 161, 449, 163, 1295, 2583, 1405, 14211, 0 }; + static ulong[] dim1734Kuo2Init = { 1, 1, 1, 7, 15, 41, 125, 65, 347, 753, 1245, 2343, 733, 2269, 0 }; + static ulong[] dim1735Kuo2Init = { 1, 3, 7, 5, 15, 25, 107, 35, 369, 395, 939, 427, 5201, 15761, 0 }; + static ulong[] dim1736Kuo2Init = { 1, 1, 3, 13, 29, 11, 9, 53, 393, 855, 483, 3773, 3491, 14857, 0 }; + static ulong[] dim1737Kuo2Init = { 1, 1, 5, 11, 25, 55, 25, 9, 161, 307, 1381, 2129, 1923, 8779, 0 }; + static ulong[] dim1738Kuo2Init = { 1, 1, 5, 1, 5, 1, 99, 205, 207, 607, 639, 29, 8045, 7159, 0 }; + static ulong[] dim1739Kuo2Init = { 1, 1, 3, 7, 29, 55, 15, 133, 217, 425, 1331, 2337, 2209, 1839, 0 }; + static ulong[] dim1740Kuo2Init = { 1, 3, 5, 1, 25, 1, 47, 135, 433, 647, 1693, 3983, 975, 14725, 0 }; + static ulong[] dim1741Kuo2Init = { 1, 3, 7, 13, 29, 41, 115, 227, 505, 17, 2041, 247, 7409, 12353, 0 }; + static ulong[] dim1742Kuo2Init = { 1, 1, 1, 13, 19, 29, 25, 175, 189, 581, 877, 2775, 737, 223, 0 }; + static ulong[] dim1743Kuo2Init = { 1, 3, 7, 11, 27, 61, 21, 209, 51, 653, 631, 3723, 7471, 11083, 0 }; + static ulong[] dim1744Kuo2Init = { 1, 3, 1, 9, 9, 41, 33, 61, 97, 551, 1029, 663, 5373, 8443, 0 }; + static ulong[] dim1745Kuo2Init = { 1, 3, 3, 9, 9, 39, 85, 103, 95, 865, 269, 1243, 5709, 3969, 0 }; + static ulong[] dim1746Kuo2Init = { 1, 3, 5, 15, 9, 17, 75, 199, 3, 681, 1447, 1663, 7139, 10459, 0 }; + static ulong[] dim1747Kuo2Init = { 1, 1, 1, 15, 3, 21, 99, 203, 161, 669, 611, 771, 7773, 6069, 0 }; + static ulong[] dim1748Kuo2Init = { 1, 3, 3, 3, 17, 13, 111, 93, 35, 119, 113, 1169, 4891, 7753, 0 }; + static ulong[] dim1749Kuo2Init = { 1, 1, 1, 11, 17, 7, 91, 39, 293, 443, 1819, 275, 7699, 8043, 0 }; + static ulong[] dim1750Kuo2Init = { 1, 1, 3, 13, 21, 37, 93, 165, 281, 515, 1913, 839, 2177, 4907, 0 }; + static ulong[] dim1751Kuo2Init = { 1, 3, 5, 11, 17, 23, 59, 161, 99, 371, 1223, 2815, 4019, 9225, 0 }; + static ulong[] dim1752Kuo2Init = { 1, 3, 1, 5, 31, 31, 31, 111, 441, 585, 393, 1665, 1421, 7305, 0 }; + static ulong[] dim1753Kuo2Init = { 1, 1, 5, 11, 19, 29, 81, 71, 223, 759, 2035, 1027, 2725, 4869, 0 }; + static ulong[] dim1754Kuo2Init = { 1, 1, 1, 11, 19, 13, 33, 139, 457, 321, 793, 2043, 4823, 10819, 0 }; + static ulong[] dim1755Kuo2Init = { 1, 3, 3, 5, 27, 9, 93, 141, 269, 177, 545, 1977, 1049, 8445, 0 }; + static ulong[] dim1756Kuo2Init = { 1, 1, 7, 3, 3, 25, 11, 75, 241, 641, 523, 2255, 6649, 2191, 0 }; + static ulong[] dim1757Kuo2Init = { 1, 1, 5, 11, 31, 31, 109, 235, 345, 291, 127, 2015, 7745, 4527, 0 }; + static ulong[] dim1758Kuo2Init = { 1, 1, 3, 7, 3, 55, 107, 51, 145, 545, 1601, 1973, 4083, 3297, 0 }; + static ulong[] dim1759Kuo2Init = { 1, 3, 5, 1, 21, 29, 31, 147, 245, 229, 1387, 2763, 769, 513, 0 }; + static ulong[] dim1760Kuo2Init = { 1, 3, 5, 15, 3, 41, 119, 61, 401, 361, 443, 3663, 3691, 1851, 0 }; + static ulong[] dim1761Kuo2Init = { 1, 3, 5, 5, 17, 7, 55, 159, 121, 841, 913, 3507, 5989, 15807, 0 }; + static ulong[] dim1762Kuo2Init = { 1, 1, 3, 13, 5, 39, 65, 3, 261, 159, 439, 739, 6899, 61, 0 }; + static ulong[] dim1763Kuo2Init = { 1, 1, 5, 13, 13, 43, 111, 17, 1, 503, 587, 1943, 7773, 14015, 0 }; + static ulong[] dim1764Kuo2Init = { 1, 3, 1, 1, 5, 43, 55, 7, 171, 637, 39, 2341, 3027, 8521, 0 }; + static ulong[] dim1765Kuo2Init = { 1, 3, 5, 7, 15, 49, 103, 157, 187, 773, 1391, 21, 5909, 14537, 0 }; + static ulong[] dim1766Kuo2Init = { 1, 1, 5, 13, 1, 29, 63, 249, 473, 351, 705, 1999, 4135, 9683, 0 }; + static ulong[] dim1767Kuo2Init = { 1, 3, 1, 7, 5, 7, 77, 179, 347, 101, 1055, 549, 297, 3195, 0 }; + static ulong[] dim1768Kuo2Init = { 1, 1, 1, 5, 19, 51, 15, 247, 269, 545, 43, 2647, 1245, 6051, 0 }; + static ulong[] dim1769Kuo2Init = { 1, 1, 5, 1, 9, 19, 45, 81, 145, 369, 1505, 1973, 3203, 10947, 0 }; + static ulong[] dim1770Kuo2Init = { 1, 3, 5, 3, 11, 51, 113, 173, 121, 923, 969, 4005, 247, 1729, 0 }; + static ulong[] dim1771Kuo2Init = { 1, 1, 7, 13, 1, 51, 111, 125, 163, 307, 1183, 1865, 2517, 9017, 0 }; + static ulong[] dim1772Kuo2Init = { 1, 1, 5, 13, 7, 9, 115, 191, 53, 891, 1703, 2507, 3103, 12511, 0 }; + static ulong[] dim1773Kuo2Init = { 1, 1, 3, 11, 9, 19, 3, 213, 421, 299, 1341, 3313, 637, 4977, 0 }; + static ulong[] dim1774Kuo2Init = { 1, 3, 5, 13, 21, 7, 89, 185, 337, 105, 415, 375, 4357, 16305, 0 }; + static ulong[] dim1775Kuo2Init = { 1, 1, 7, 7, 23, 25, 55, 19, 253, 879, 1779, 2451, 3485, 3383, 0 }; + static ulong[] dim1776Kuo2Init = { 1, 3, 7, 7, 25, 33, 77, 67, 211, 571, 2029, 161, 3747, 11275, 0 }; + static ulong[] dim1777Kuo2Init = { 1, 1, 3, 3, 15, 33, 55, 121, 97, 5, 907, 1869, 8171, 1553, 0 }; + static ulong[] dim1778Kuo2Init = { 1, 1, 1, 9, 3, 33, 21, 165, 181, 211, 437, 1887, 895, 11549, 0 }; + static ulong[] dim1779Kuo2Init = { 1, 3, 5, 3, 5, 7, 103, 95, 477, 585, 1307, 1017, 4115, 6011, 0 }; + static ulong[] dim1780Kuo2Init = { 1, 1, 3, 11, 25, 45, 67, 239, 171, 869, 285, 2495, 4091, 15037, 0 }; + static ulong[] dim1781Kuo2Init = { 1, 1, 3, 13, 5, 41, 103, 17, 283, 833, 179, 1183, 3323, 9777, 0 }; + static ulong[] dim1782Kuo2Init = { 1, 3, 3, 5, 13, 29, 111, 37, 245, 329, 677, 4039, 2533, 3759, 0 }; + static ulong[] dim1783Kuo2Init = { 1, 1, 7, 15, 23, 63, 115, 243, 347, 869, 587, 3073, 7727, 399, 0 }; + static ulong[] dim1784Kuo2Init = { 1, 1, 7, 7, 5, 57, 49, 39, 463, 417, 1183, 1007, 3823, 15299, 0 }; + static ulong[] dim1785Kuo2Init = { 1, 1, 1, 5, 23, 41, 65, 207, 151, 919, 1495, 2841, 1453, 6273, 0 }; + static ulong[] dim1786Kuo2Init = { 1, 1, 1, 1, 15, 19, 51, 193, 187, 711, 11, 1291, 143, 15375, 0 }; + static ulong[] dim1787Kuo2Init = { 1, 1, 3, 13, 25, 19, 3, 113, 157, 699, 1699, 1793, 29, 1869, 0 }; + static ulong[] dim1788Kuo2Init = { 1, 3, 3, 7, 7, 37, 25, 73, 353, 443, 1517, 2621, 489, 15411, 0 }; + static ulong[] dim1789Kuo2Init = { 1, 1, 1, 1, 7, 9, 91, 67, 471, 395, 1417, 431, 4793, 9517, 0 }; + static ulong[] dim1790Kuo2Init = { 1, 3, 1, 5, 31, 15, 63, 67, 109, 537, 1543, 1021, 2549, 13587, 0 }; + static ulong[] dim1791Kuo2Init = { 1, 1, 1, 3, 7, 63, 127, 141, 23, 281, 523, 283, 347, 2095, 0 }; + static ulong[] dim1792Kuo2Init = { 1, 1, 7, 9, 21, 21, 71, 97, 357, 887, 1785, 3471, 3187, 12163, 0 }; + static ulong[] dim1793Kuo2Init = { 1, 3, 3, 3, 25, 23, 127, 135, 199, 661, 7, 3279, 91, 11879, 0 }; + static ulong[] dim1794Kuo2Init = { 1, 1, 7, 5, 29, 51, 41, 5, 387, 901, 233, 1559, 511, 7735, 0 }; + static ulong[] dim1795Kuo2Init = { 1, 1, 5, 9, 3, 13, 45, 119, 177, 381, 1363, 3627, 259, 771, 0 }; + static ulong[] dim1796Kuo2Init = { 1, 1, 5, 11, 5, 31, 73, 151, 487, 371, 1543, 1183, 697, 10225, 0 }; + static ulong[] dim1797Kuo2Init = { 1, 3, 5, 7, 29, 39, 125, 245, 373, 43, 583, 233, 5799, 7865, 0 }; + static ulong[] dim1798Kuo2Init = { 1, 1, 7, 13, 17, 41, 47, 7, 161, 717, 947, 2421, 1983, 12963, 0 }; + static ulong[] dim1799Kuo2Init = { 1, 3, 3, 3, 31, 19, 11, 131, 217, 533, 1407, 421, 163, 5849, 0 }; + static ulong[] dim1800Kuo2Init = { 1, 1, 3, 13, 31, 49, 77, 33, 335, 627, 1135, 4021, 6609, 819, 0 }; + static ulong[] dim1801Kuo2Init = { 1, 3, 5, 5, 17, 51, 27, 83, 153, 469, 85, 2725, 4297, 8869, 0 }; + static ulong[] dim1802Kuo2Init = { 1, 3, 5, 9, 29, 7, 93, 53, 251, 579, 1243, 2689, 4655, 9247, 0 }; + static ulong[] dim1803Kuo2Init = { 1, 3, 1, 13, 9, 35, 59, 213, 181, 409, 1177, 3783, 6339, 339, 0 }; + static ulong[] dim1804Kuo2Init = { 1, 1, 1, 7, 25, 55, 111, 133, 481, 757, 1683, 2193, 681, 12141, 0 }; + static ulong[] dim1805Kuo2Init = { 1, 1, 3, 13, 11, 1, 57, 137, 359, 325, 67, 3069, 1125, 8305, 0 }; + static ulong[] dim1806Kuo2Init = { 1, 1, 1, 5, 21, 11, 79, 195, 335, 85, 1749, 1859, 4253, 6391, 0 }; + static ulong[] dim1807Kuo2Init = { 1, 1, 3, 13, 17, 55, 23, 119, 159, 843, 1677, 1725, 1139, 2051, 0 }; + static ulong[] dim1808Kuo2Init = { 1, 3, 1, 11, 31, 35, 11, 49, 497, 807, 191, 3889, 7811, 13217, 0 }; + static ulong[] dim1809Kuo2Init = { 1, 3, 1, 9, 29, 63, 117, 161, 191, 371, 245, 219, 1559, 13303, 0 }; + static ulong[] dim1810Kuo2Init = { 1, 3, 3, 7, 5, 19, 37, 231, 381, 323, 233, 3973, 6531, 8807, 0 }; + static ulong[] dim1811Kuo2Init = { 1, 1, 1, 11, 3, 43, 35, 103, 291, 363, 531, 1129, 3321, 3167, 0 }; + static ulong[] dim1812Kuo2Init = { 1, 3, 3, 15, 25, 9, 47, 139, 143, 155, 2005, 1573, 2007, 6483, 0 }; + static ulong[] dim1813Kuo2Init = { 1, 3, 7, 5, 25, 3, 125, 19, 255, 699, 1651, 1449, 3753, 12873, 0 }; + static ulong[] dim1814Kuo2Init = { 1, 1, 7, 5, 7, 7, 63, 31, 255, 991, 1029, 1635, 4941, 7891, 0 }; + static ulong[] dim1815Kuo2Init = { 1, 3, 3, 1, 3, 13, 59, 73, 429, 931, 53, 711, 3305, 7621, 0 }; + static ulong[] dim1816Kuo2Init = { 1, 3, 3, 5, 15, 55, 103, 159, 185, 365, 1283, 1171, 6659, 2547, 0 }; + static ulong[] dim1817Kuo2Init = { 1, 1, 5, 5, 25, 33, 91, 87, 323, 235, 1997, 1397, 6777, 10065, 0 }; + static ulong[] dim1818Kuo2Init = { 1, 3, 1, 1, 7, 35, 19, 5, 327, 163, 651, 215, 7965, 1143, 0 }; + static ulong[] dim1819Kuo2Init = { 1, 1, 1, 11, 7, 13, 69, 129, 277, 665, 1763, 33, 8145, 7131, 0 }; + static ulong[] dim1820Kuo2Init = { 1, 3, 3, 13, 17, 25, 111, 247, 91, 537, 325, 2627, 1777, 2861, 0 }; + static ulong[] dim1821Kuo2Init = { 1, 3, 3, 3, 29, 15, 87, 41, 103, 957, 105, 757, 2635, 4825, 0 }; + static ulong[] dim1822Kuo2Init = { 1, 1, 3, 11, 21, 43, 73, 143, 31, 913, 1579, 1725, 6679, 2491, 0 }; + static ulong[] dim1823Kuo2Init = { 1, 3, 1, 11, 1, 31, 93, 231, 327, 177, 921, 2715, 8015, 3295, 0 }; + static ulong[] dim1824Kuo2Init = { 1, 3, 1, 3, 5, 47, 59, 1, 105, 991, 1581, 115, 1957, 10753, 0 }; + static ulong[] dim1825Kuo2Init = { 1, 3, 7, 9, 13, 31, 65, 241, 353, 613, 1065, 1201, 7267, 2099, 0 }; + static ulong[] dim1826Kuo2Init = { 1, 3, 7, 11, 5, 55, 121, 45, 279, 765, 1263, 993, 5047, 12059, 0 }; + static ulong[] dim1827Kuo2Init = { 1, 1, 7, 3, 25, 27, 13, 123, 357, 339, 1299, 297, 361, 4951, 0 }; + static ulong[] dim1828Kuo2Init = { 1, 3, 5, 3, 13, 43, 117, 237, 3, 463, 911, 3447, 7463, 5985, 0 }; + static ulong[] dim1829Kuo2Init = { 1, 3, 1, 15, 13, 1, 21, 213, 115, 291, 1317, 2201, 7939, 16135, 0 }; + static ulong[] dim1830Kuo2Init = { 1, 1, 3, 15, 13, 15, 55, 51, 203, 277, 71, 1025, 4237, 301, 0 }; + static ulong[] dim1831Kuo2Init = { 1, 1, 5, 5, 17, 31, 95, 25, 7, 519, 1971, 3069, 1937, 5693, 0 }; + static ulong[] dim1832Kuo2Init = { 1, 3, 7, 5, 11, 17, 31, 111, 219, 199, 303, 2527, 4185, 13185, 0 }; + static ulong[] dim1833Kuo2Init = { 1, 3, 5, 13, 11, 17, 105, 147, 51, 885, 675, 3035, 4245, 3257, 0 }; + static ulong[] dim1834Kuo2Init = { 1, 3, 3, 5, 9, 17, 37, 139, 251, 85, 361, 2569, 2727, 14111, 0 }; + static ulong[] dim1835Kuo2Init = { 1, 3, 5, 9, 31, 5, 101, 1, 475, 645, 1515, 2713, 2771, 2981, 0 }; + static ulong[] dim1836Kuo2Init = { 1, 3, 3, 13, 21, 21, 31, 117, 511, 525, 1105, 2881, 6361, 6991, 0 }; + static ulong[] dim1837Kuo2Init = { 1, 1, 5, 5, 15, 5, 47, 11, 391, 239, 65, 1545, 691, 3973, 0 }; + static ulong[] dim1838Kuo2Init = { 1, 3, 1, 1, 9, 3, 91, 49, 505, 353, 1593, 4009, 2535, 4947, 0 }; + static ulong[] dim1839Kuo2Init = { 1, 3, 1, 13, 15, 27, 45, 255, 503, 487, 613, 3453, 655, 10083, 0 }; + static ulong[] dim1840Kuo2Init = { 1, 1, 1, 9, 23, 17, 39, 219, 281, 669, 867, 773, 2555, 12565, 0 }; + static ulong[] dim1841Kuo2Init = { 1, 3, 1, 7, 21, 29, 61, 85, 441, 273, 1889, 1441, 6291, 2599, 0 }; + static ulong[] dim1842Kuo2Init = { 1, 1, 1, 7, 1, 7, 95, 9, 105, 77, 463, 701, 6001, 13491, 0 }; + static ulong[] dim1843Kuo2Init = { 1, 3, 7, 3, 29, 57, 61, 123, 105, 909, 1925, 1255, 7069, 3049, 0 }; + static ulong[] dim1844Kuo2Init = { 1, 1, 3, 11, 15, 37, 23, 25, 359, 743, 1599, 575, 4095, 11539, 0 }; + static ulong[] dim1845Kuo2Init = { 1, 3, 3, 9, 17, 33, 59, 245, 119, 457, 147, 1027, 4051, 507, 0 }; + static ulong[] dim1846Kuo2Init = { 1, 3, 1, 11, 25, 59, 97, 37, 199, 247, 985, 635, 3501, 11213, 0 }; + static ulong[] dim1847Kuo2Init = { 1, 1, 5, 7, 21, 19, 17, 181, 183, 331, 817, 1069, 3863, 7547, 0 }; + static ulong[] dim1848Kuo2Init = { 1, 3, 5, 1, 11, 25, 121, 127, 105, 57, 689, 701, 1527, 5301, 0 }; + static ulong[] dim1849Kuo2Init = { 1, 1, 7, 3, 25, 59, 67, 103, 265, 649, 957, 3073, 3047, 12881, 0 }; + static ulong[] dim1850Kuo2Init = { 1, 3, 1, 3, 17, 15, 103, 37, 359, 665, 1677, 2563, 7079, 2577, 0 }; + static ulong[] dim1851Kuo2Init = { 1, 1, 1, 13, 21, 43, 117, 187, 447, 711, 749, 643, 183, 13053, 0 }; + static ulong[] dim1852Kuo2Init = { 1, 3, 7, 3, 15, 45, 23, 169, 481, 841, 625, 3241, 7739, 13463, 0 }; + static ulong[] dim1853Kuo2Init = { 1, 3, 7, 9, 7, 11, 9, 73, 57, 595, 1981, 3499, 53, 3445, 0 }; + static ulong[] dim1854Kuo2Init = { 1, 3, 3, 11, 17, 13, 61, 139, 445, 287, 705, 3157, 7503, 15279, 0 }; + static ulong[] dim1855Kuo2Init = { 1, 3, 5, 5, 15, 5, 15, 117, 177, 517, 1907, 399, 1613, 9495, 0 }; + static ulong[] dim1856Kuo2Init = { 1, 3, 5, 13, 19, 37, 81, 179, 473, 477, 551, 1235, 6503, 14401, 0 }; + static ulong[] dim1857Kuo2Init = { 1, 3, 5, 7, 1, 21, 29, 181, 25, 349, 1915, 1047, 6645, 5153, 0 }; + static ulong[] dim1858Kuo2Init = { 1, 3, 1, 11, 31, 31, 13, 165, 147, 995, 1767, 4013, 4993, 51, 0 }; + static ulong[] dim1859Kuo2Init = { 1, 1, 3, 11, 19, 33, 47, 179, 465, 811, 1535, 2555, 1843, 10877, 0 }; + static ulong[] dim1860Kuo2Init = { 1, 3, 5, 7, 25, 13, 49, 105, 39, 893, 1729, 1297, 6071, 685, 0 }; + static ulong[] dim1861Kuo2Init = { 1, 1, 3, 5, 3, 17, 69, 141, 83, 393, 1377, 3401, 1749, 10307, 0 }; + static ulong[] dim1862Kuo2Init = { 1, 3, 7, 7, 5, 43, 27, 39, 61, 119, 829, 2105, 8155, 1647, 0 }; + static ulong[] dim1863Kuo2Init = { 1, 1, 1, 3, 7, 61, 83, 253, 129, 459, 1241, 569, 7457, 3635, 0 }; + static ulong[] dim1864Kuo2Init = { 1, 1, 1, 5, 21, 17, 97, 213, 463, 549, 1219, 3685, 3721, 8659, 0 }; + static ulong[] dim1865Kuo2Init = { 1, 3, 7, 5, 19, 53, 45, 151, 15, 483, 1077, 1811, 4861, 9979, 0 }; + static ulong[] dim1866Kuo2Init = { 1, 1, 5, 13, 7, 21, 11, 117, 267, 723, 573, 3335, 6331, 3255, 0 }; + static ulong[] dim1867Kuo2Init = { 1, 3, 5, 3, 23, 17, 83, 171, 501, 249, 1937, 593, 3757, 6035, 30841, 0 }; + static ulong[] dim1868Kuo2Init = { 1, 3, 7, 1, 13, 15, 19, 33, 191, 509, 1461, 2105, 2175, 10593, 27199, 0 }; + static ulong[] dim1869Kuo2Init = { 1, 3, 3, 3, 9, 7, 7, 51, 199, 339, 393, 2543, 4269, 2447, 17671, 0 }; + static ulong[] dim1870Kuo2Init = { 1, 3, 1, 1, 17, 3, 71, 119, 15, 333, 1313, 2609, 1077, 2493, 23109, 0 }; + static ulong[] dim1871Kuo2Init = { 1, 1, 1, 11, 7, 45, 69, 69, 241, 995, 1111, 2141, 5467, 5003, 11135, 0 }; + static ulong[] dim1872Kuo2Init = { 1, 1, 7, 11, 21, 1, 25, 35, 445, 379, 449, 3703, 3281, 3433, 5207, 0 }; + static ulong[] dim1873Kuo2Init = { 1, 3, 3, 5, 15, 49, 119, 11, 331, 681, 1209, 161, 7969, 11115, 4775, 0 }; + static ulong[] dim1874Kuo2Init = { 1, 3, 7, 15, 1, 1, 61, 131, 141, 849, 2035, 125, 2457, 9209, 18411, 0 }; + static ulong[] dim1875Kuo2Init = { 1, 1, 5, 5, 25, 17, 91, 255, 137, 815, 1803, 3521, 181, 15683, 32099, 0 }; + static ulong[] dim1876Kuo2Init = { 1, 3, 1, 11, 29, 13, 91, 129, 167, 323, 823, 3717, 473, 7617, 5431, 0 }; + static ulong[] dim1877Kuo2Init = { 1, 1, 5, 9, 17, 41, 65, 5, 57, 441, 765, 2761, 5033, 14551, 28223, 0 }; + static ulong[] dim1878Kuo2Init = { 1, 3, 1, 1, 11, 11, 35, 109, 197, 349, 1495, 4057, 5255, 8327, 29281, 0 }; + static ulong[] dim1879Kuo2Init = { 1, 1, 7, 1, 27, 33, 7, 133, 439, 329, 655, 2459, 5369, 14681, 12271, 0 }; + static ulong[] dim1880Kuo2Init = { 1, 1, 1, 13, 29, 11, 15, 71, 117, 849, 285, 3779, 1181, 6315, 23627, 0 }; + static ulong[] dim1881Kuo2Init = { 1, 3, 3, 7, 15, 33, 93, 133, 239, 169, 197, 3005, 1035, 6771, 10881, 0 }; + static ulong[] dim1882Kuo2Init = { 1, 3, 3, 13, 29, 13, 69, 157, 275, 335, 1977, 461, 8087, 10027, 6377, 0 }; + static ulong[] dim1883Kuo2Init = { 1, 3, 1, 15, 25, 23, 107, 125, 27, 455, 207, 3425, 5319, 4861, 4853, 0 }; + static ulong[] dim1884Kuo2Init = { 1, 1, 5, 15, 17, 49, 3, 129, 401, 451, 363, 553, 3999, 8115, 25621, 0 }; + static ulong[] dim1885Kuo2Init = { 1, 3, 3, 3, 9, 63, 71, 219, 331, 43, 1369, 3821, 5189, 8799, 19413, 0 }; + static ulong[] dim1886Kuo2Init = { 1, 1, 3, 13, 31, 19, 57, 127, 229, 429, 535, 591, 1135, 12559, 4219, 0 }; + static ulong[] dim1887Kuo2Init = { 1, 1, 7, 3, 11, 41, 49, 45, 423, 299, 571, 1907, 1755, 10813, 14199, 0 }; + static ulong[] dim1888Kuo2Init = { 1, 3, 1, 1, 1, 41, 53, 139, 345, 521, 1051, 691, 7367, 923, 2171, 0 }; + static ulong[] dim1889Kuo2Init = { 1, 1, 7, 1, 23, 39, 21, 241, 433, 269, 1733, 3455, 8171, 585, 9035, 0 }; + static ulong[] dim1890Kuo2Init = { 1, 1, 3, 3, 15, 31, 39, 75, 223, 827, 1799, 2699, 6927, 4251, 16799, 0 }; + static ulong[] dim1891Kuo2Init = { 1, 1, 7, 11, 25, 17, 5, 199, 265, 953, 1609, 185, 5069, 10061, 31235, 0 }; + static ulong[] dim1892Kuo2Init = { 1, 3, 3, 7, 11, 17, 125, 149, 29, 149, 1241, 3975, 2915, 13847, 8245, 0 }; + static ulong[] dim1893Kuo2Init = { 1, 3, 5, 15, 19, 7, 115, 127, 325, 147, 505, 3199, 2261, 15309, 1925, 0 }; + static ulong[] dim1894Kuo2Init = { 1, 1, 3, 15, 19, 27, 45, 131, 35, 69, 275, 2895, 8131, 6311, 15507, 0 }; + static ulong[] dim1895Kuo2Init = { 1, 3, 7, 5, 5, 35, 115, 39, 343, 491, 199, 985, 7767, 13183, 23341, 0 }; + static ulong[] dim1896Kuo2Init = { 1, 3, 3, 3, 17, 19, 125, 237, 393, 1, 1763, 2129, 2221, 4993, 23023, 0 }; + static ulong[] dim1897Kuo2Init = { 1, 1, 5, 13, 1, 39, 53, 77, 43, 665, 173, 1923, 5071, 2713, 28507, 0 }; + static ulong[] dim1898Kuo2Init = { 1, 1, 3, 5, 7, 57, 77, 19, 9, 441, 1941, 475, 4059, 3977, 25689, 0 }; + static ulong[] dim1899Kuo2Init = { 1, 1, 3, 9, 23, 49, 35, 139, 189, 431, 1077, 1057, 1565, 5597, 23755, 0 }; + static ulong[] dim1900Kuo2Init = { 1, 1, 7, 1, 7, 5, 121, 69, 277, 797, 1879, 3479, 3023, 1781, 31307, 0 }; + static ulong[] dim1901Kuo2Init = { 1, 1, 5, 15, 5, 23, 75, 181, 97, 491, 399, 63, 3211, 7099, 14597, 0 }; + static ulong[] dim1902Kuo2Init = { 1, 3, 1, 11, 9, 3, 85, 159, 143, 13, 599, 3685, 4291, 11457, 24571, 0 }; + static ulong[] dim1903Kuo2Init = { 1, 3, 7, 9, 23, 45, 17, 197, 351, 997, 1789, 3965, 1163, 9027, 28843, 0 }; + static ulong[] dim1904Kuo2Init = { 1, 1, 5, 15, 25, 13, 93, 141, 395, 905, 933, 3169, 7551, 1775, 22043, 0 }; + static ulong[] dim1905Kuo2Init = { 1, 3, 3, 11, 17, 47, 115, 211, 157, 887, 1829, 767, 6821, 5243, 26423, 0 }; + static ulong[] dim1906Kuo2Init = { 1, 1, 1, 1, 15, 33, 27, 239, 405, 5, 861, 1909, 1261, 1921, 32245, 0 }; + static ulong[] dim1907Kuo2Init = { 1, 1, 1, 15, 5, 15, 21, 251, 489, 789, 507, 321, 6429, 1885, 23139, 0 }; + static ulong[] dim1908Kuo2Init = { 1, 1, 1, 13, 19, 61, 59, 201, 69, 933, 83, 1657, 1331, 16183, 23085, 0 }; + static ulong[] dim1909Kuo2Init = { 1, 3, 1, 5, 29, 59, 61, 149, 95, 897, 1107, 2853, 5271, 7069, 3759, 0 }; + static ulong[] dim1910Kuo2Init = { 1, 1, 3, 9, 17, 53, 71, 183, 29, 353, 1621, 4015, 6395, 8737, 12507, 0 }; + static ulong[] dim1911Kuo2Init = { 1, 3, 3, 15, 23, 31, 77, 187, 429, 59, 117, 641, 1039, 15113, 1177, 0 }; + static ulong[] dim1912Kuo2Init = { 1, 1, 3, 7, 17, 9, 73, 37, 177, 901, 573, 2503, 5865, 13939, 10123, 0 }; + static ulong[] dim1913Kuo2Init = { 1, 3, 1, 1, 7, 21, 55, 255, 85, 993, 583, 3345, 3211, 6027, 18677, 0 }; + static ulong[] dim1914Kuo2Init = { 1, 3, 3, 1, 27, 37, 111, 235, 281, 363, 121, 3749, 7381, 14959, 22997, 0 }; + static ulong[] dim1915Kuo2Init = { 1, 1, 1, 11, 13, 19, 47, 203, 157, 975, 1173, 1389, 1021, 6481, 547, 0 }; + static ulong[] dim1916Kuo2Init = { 1, 3, 5, 11, 7, 51, 121, 99, 289, 303, 1759, 571, 3585, 2263, 21231, 0 }; + static ulong[] dim1917Kuo2Init = { 1, 3, 5, 9, 9, 7, 25, 39, 443, 635, 1597, 2095, 6739, 16367, 11285, 0 }; + static ulong[] dim1918Kuo2Init = { 1, 1, 1, 9, 5, 47, 107, 223, 389, 25, 1353, 501, 8025, 7269, 23617, 0 }; + static ulong[] dim1919Kuo2Init = { 1, 1, 5, 5, 23, 25, 59, 133, 387, 761, 835, 105, 45, 5469, 13461, 0 }; + static ulong[] dim1920Kuo2Init = { 1, 1, 3, 11, 5, 33, 121, 149, 121, 881, 603, 3455, 7667, 3039, 8471, 0 }; + static ulong[] dim1921Kuo2Init = { 1, 3, 5, 9, 17, 41, 1, 109, 67, 511, 617, 1139, 7605, 12211, 8603, 0 }; + static ulong[] dim1922Kuo2Init = { 1, 1, 3, 9, 13, 27, 5, 163, 17, 889, 199, 77, 5233, 6383, 15787, 0 }; + static ulong[] dim1923Kuo2Init = { 1, 1, 1, 13, 5, 27, 45, 47, 213, 473, 1101, 623, 6169, 3139, 27561, 0 }; + static ulong[] dim1924Kuo2Init = { 1, 1, 3, 13, 15, 63, 79, 51, 47, 227, 1771, 3167, 2975, 16075, 9117, 0 }; + static ulong[] dim1925Kuo2Init = { 1, 1, 5, 5, 29, 9, 87, 213, 349, 763, 1341, 1299, 1183, 4763, 14869, 0 }; + static ulong[] dim1926Kuo2Init = { 1, 3, 7, 1, 23, 3, 37, 99, 341, 67, 1273, 3383, 7805, 8373, 19401, 0 }; + static ulong[] dim1927Kuo2Init = { 1, 3, 3, 3, 7, 25, 23, 231, 291, 591, 291, 1077, 7291, 9763, 515, 0 }; + static ulong[] dim1928Kuo2Init = { 1, 1, 1, 3, 9, 49, 99, 127, 501, 375, 995, 1883, 6229, 1141, 16513, 0 }; + static ulong[] dim1929Kuo2Init = { 1, 1, 1, 13, 21, 35, 43, 39, 405, 283, 1555, 3189, 4999, 139, 11031, 0 }; + static ulong[] dim1930Kuo2Init = { 1, 3, 3, 1, 25, 3, 29, 89, 71, 975, 435, 2513, 4667, 14859, 22495, 0 }; + static ulong[] dim1931Kuo2Init = { 1, 3, 5, 9, 27, 45, 29, 145, 97, 149, 341, 3253, 5385, 8099, 169, 0 }; + static ulong[] dim1932Kuo2Init = { 1, 1, 1, 3, 17, 49, 73, 31, 291, 191, 959, 3139, 6221, 423, 5247, 0 }; + static ulong[] dim1933Kuo2Init = { 1, 3, 7, 3, 11, 23, 25, 65, 291, 877, 15, 437, 3883, 6545, 16327, 0 }; + static ulong[] dim1934Kuo2Init = { 1, 3, 1, 7, 21, 53, 35, 143, 433, 117, 1135, 467, 6825, 16041, 3351, 0 }; + static ulong[] dim1935Kuo2Init = { 1, 3, 5, 1, 11, 57, 105, 147, 443, 1, 1879, 2963, 4041, 8929, 219, 0 }; + static ulong[] dim1936Kuo2Init = { 1, 3, 3, 11, 13, 59, 57, 175, 151, 1015, 629, 1549, 4161, 16147, 25857, 0 }; + static ulong[] dim1937Kuo2Init = { 1, 1, 7, 9, 15, 27, 19, 111, 495, 7, 1219, 2679, 3257, 7111, 23187, 0 }; + static ulong[] dim1938Kuo2Init = { 1, 1, 1, 7, 5, 3, 37, 247, 43, 223, 1681, 225, 6573, 7523, 14433, 0 }; + static ulong[] dim1939Kuo2Init = { 1, 1, 3, 3, 7, 31, 71, 141, 341, 319, 653, 3463, 963, 10133, 27313, 0 }; + static ulong[] dim1940Kuo2Init = { 1, 1, 1, 11, 3, 61, 71, 9, 253, 69, 527, 2927, 1637, 15141, 32423, 0 }; + static ulong[] dim1941Kuo2Init = { 1, 3, 3, 3, 21, 41, 119, 175, 363, 629, 909, 439, 8043, 12489, 18635, 0 }; + static ulong[] dim1942Kuo2Init = { 1, 1, 5, 3, 11, 19, 73, 87, 133, 947, 537, 803, 965, 9139, 7429, 0 }; + static ulong[] dim1943Kuo2Init = { 1, 1, 7, 3, 9, 45, 113, 213, 499, 493, 811, 389, 5323, 409, 17147, 0 }; + static ulong[] dim1944Kuo2Init = { 1, 3, 1, 1, 9, 29, 61, 231, 55, 625, 1917, 3157, 4635, 11441, 24799, 0 }; + static ulong[] dim1945Kuo2Init = { 1, 3, 3, 15, 15, 11, 93, 245, 247, 405, 1123, 2639, 1739, 11957, 19131, 0 }; + static ulong[] dim1946Kuo2Init = { 1, 3, 5, 3, 19, 7, 47, 241, 97, 635, 1871, 2609, 5529, 11591, 13895, 0 }; + static ulong[] dim1947Kuo2Init = { 1, 1, 1, 11, 11, 45, 11, 13, 109, 141, 83, 2109, 3259, 7441, 25881, 0 }; + static ulong[] dim1948Kuo2Init = { 1, 1, 7, 13, 21, 61, 73, 129, 393, 175, 699, 2551, 4761, 13133, 9993, 0 }; + static ulong[] dim1949Kuo2Init = { 1, 1, 7, 1, 31, 17, 85, 57, 457, 383, 1099, 1819, 503, 1389, 28341, 0 }; + static ulong[] dim1950Kuo2Init = { 1, 3, 5, 7, 3, 17, 41, 33, 245, 815, 31, 2259, 1293, 9051, 13241, 0 }; + static ulong[] dim1951Kuo2Init = { 1, 3, 7, 7, 23, 15, 81, 77, 193, 201, 785, 1271, 3061, 4429, 26665, 0 }; + static ulong[] dim1952Kuo2Init = { 1, 1, 5, 15, 29, 23, 43, 227, 119, 843, 55, 1837, 51, 13115, 27725, 0 }; + static ulong[] dim1953Kuo2Init = { 1, 3, 1, 11, 1, 33, 25, 233, 43, 367, 705, 2323, 2721, 12845, 29415, 0 }; + static ulong[] dim1954Kuo2Init = { 1, 3, 5, 1, 25, 23, 5, 233, 507, 267, 607, 3009, 5035, 1069, 30735, 0 }; + static ulong[] dim1955Kuo2Init = { 1, 1, 7, 5, 27, 5, 69, 5, 371, 951, 657, 421, 5707, 10455, 10961, 0 }; + static ulong[] dim1956Kuo2Init = { 1, 1, 3, 11, 13, 13, 71, 113, 381, 619, 1713, 315, 7903, 4737, 24747, 0 }; + static ulong[] dim1957Kuo2Init = { 1, 3, 5, 11, 15, 21, 39, 221, 9, 263, 1697, 3189, 7095, 7769, 10915, 0 }; + static ulong[] dim1958Kuo2Init = { 1, 1, 1, 1, 17, 47, 77, 27, 377, 79, 1245, 1233, 3761, 3667, 12785, 0 }; + static ulong[] dim1959Kuo2Init = { 1, 1, 3, 13, 11, 9, 89, 57, 339, 845, 393, 1717, 3415, 5725, 28655, 0 }; + static ulong[] dim1960Kuo2Init = { 1, 3, 7, 3, 11, 61, 89, 37, 59, 117, 883, 1911, 4513, 561, 31273, 0 }; + static ulong[] dim1961Kuo2Init = { 1, 1, 1, 13, 21, 29, 9, 147, 109, 783, 1647, 2147, 7285, 4035, 8181, 0 }; + static ulong[] dim1962Kuo2Init = { 1, 3, 1, 13, 29, 15, 95, 71, 319, 489, 601, 1731, 7927, 9115, 32607, 0 }; + static ulong[] dim1963Kuo2Init = { 1, 1, 3, 13, 1, 59, 53, 193, 105, 653, 249, 3285, 7817, 4157, 13299, 0 }; + static ulong[] dim1964Kuo2Init = { 1, 1, 7, 15, 5, 63, 5, 111, 427, 781, 1077, 1267, 7253, 4883, 24539, 0 }; + static ulong[] dim1965Kuo2Init = { 1, 1, 1, 5, 15, 13, 97, 187, 175, 617, 931, 3675, 8085, 14433, 22179, 0 }; + static ulong[] dim1966Kuo2Init = { 1, 3, 3, 13, 29, 29, 7, 45, 295, 185, 15, 3171, 5701, 11099, 8663, 0 }; + static ulong[] dim1967Kuo2Init = { 1, 3, 5, 15, 21, 47, 37, 189, 447, 123, 1979, 3633, 4875, 12667, 2349, 0 }; + static ulong[] dim1968Kuo2Init = { 1, 3, 1, 3, 17, 37, 97, 167, 207, 347, 499, 129, 3131, 6649, 10051, 0 }; + static ulong[] dim1969Kuo2Init = { 1, 3, 7, 13, 21, 21, 15, 125, 405, 175, 89, 3299, 1321, 15595, 26015, 0 }; + static ulong[] dim1970Kuo2Init = { 1, 1, 5, 1, 25, 21, 11, 25, 351, 1011, 753, 1813, 2229, 9675, 10073, 0 }; + static ulong[] dim1971Kuo2Init = { 1, 3, 5, 1, 21, 49, 61, 241, 303, 833, 653, 259, 4397, 545, 24857, 0 }; + static ulong[] dim1972Kuo2Init = { 1, 1, 5, 5, 27, 61, 99, 181, 415, 945, 763, 1207, 5413, 11447, 11117, 0 }; + static ulong[] dim1973Kuo2Init = { 1, 1, 3, 3, 27, 11, 5, 197, 211, 971, 1991, 4007, 2337, 2683, 27371, 0 }; + static ulong[] dim1974Kuo2Init = { 1, 1, 5, 3, 5, 39, 25, 59, 223, 117, 1543, 2527, 2673, 15411, 8769, 0 }; + static ulong[] dim1975Kuo2Init = { 1, 3, 7, 11, 31, 7, 33, 7, 319, 679, 685, 953, 491, 251, 16333, 0 }; + static ulong[] dim1976Kuo2Init = { 1, 1, 5, 5, 1, 15, 69, 87, 447, 363, 1883, 937, 2691, 14777, 19757, 0 }; + static ulong[] dim1977Kuo2Init = { 1, 1, 1, 1, 11, 51, 21, 183, 143, 577, 819, 3693, 5421, 9105, 10465, 0 }; + static ulong[] dim1978Kuo2Init = { 1, 1, 7, 1, 7, 7, 25, 131, 63, 881, 931, 2039, 1371, 7479, 7009, 0 }; + static ulong[] dim1979Kuo2Init = { 1, 1, 5, 5, 17, 37, 121, 101, 133, 829, 495, 1031, 6843, 13863, 6543, 0 }; + static ulong[] dim1980Kuo2Init = { 1, 1, 1, 9, 5, 53, 15, 11, 215, 295, 1401, 1633, 395, 201, 18941, 0 }; + static ulong[] dim1981Kuo2Init = { 1, 3, 7, 7, 21, 39, 107, 153, 139, 557, 683, 1993, 3495, 9929, 12067, 0 }; + static ulong[] dim1982Kuo2Init = { 1, 3, 3, 13, 27, 57, 63, 151, 13, 827, 1079, 1209, 5631, 9627, 4765, 0 }; + static ulong[] dim1983Kuo2Init = { 1, 1, 3, 13, 9, 9, 75, 209, 437, 475, 1905, 3021, 7097, 10637, 13301, 0 }; + static ulong[] dim1984Kuo2Init = { 1, 1, 3, 1, 21, 43, 45, 7, 467, 825, 1189, 1525, 3295, 2575, 12071, 0 }; + static ulong[] dim1985Kuo2Init = { 1, 3, 3, 1, 25, 57, 23, 243, 79, 39, 881, 467, 4183, 13881, 26719, 0 }; + static ulong[] dim1986Kuo2Init = { 1, 1, 1, 11, 27, 41, 79, 223, 443, 489, 1531, 3671, 7905, 9593, 175, 0 }; + static ulong[] dim1987Kuo2Init = { 1, 3, 3, 5, 1, 25, 89, 151, 165, 681, 1099, 665, 1209, 13617, 15259, 0 }; + static ulong[] dim1988Kuo2Init = { 1, 3, 3, 3, 17, 25, 13, 85, 179, 335, 951, 4085, 3251, 15061, 14609, 0 }; + static ulong[] dim1989Kuo2Init = { 1, 1, 5, 11, 15, 25, 89, 135, 27, 323, 1143, 7, 3569, 6841, 9243, 0 }; + static ulong[] dim1990Kuo2Init = { 1, 1, 7, 5, 13, 43, 83, 23, 477, 229, 1623, 2641, 1235, 681, 17379, 0 }; + static ulong[] dim1991Kuo2Init = { 1, 3, 1, 13, 1, 17, 77, 125, 121, 253, 1329, 1081, 1191, 7477, 13441, 0 }; + static ulong[] dim1992Kuo2Init = { 1, 1, 7, 15, 5, 61, 23, 251, 407, 373, 1399, 1907, 4145, 15997, 12069, 0 }; + static ulong[] dim1993Kuo2Init = { 1, 1, 3, 7, 9, 27, 85, 209, 21, 225, 745, 1405, 813, 1605, 17463, 0 }; + static ulong[] dim1994Kuo2Init = { 1, 1, 7, 5, 19, 47, 111, 215, 335, 211, 1437, 425, 2325, 15761, 13937, 0 }; + static ulong[] dim1995Kuo2Init = { 1, 3, 5, 9, 31, 21, 113, 89, 369, 165, 1673, 3143, 6765, 13897, 15295, 0 }; + static ulong[] dim1996Kuo2Init = { 1, 3, 1, 1, 23, 57, 97, 9, 219, 513, 1001, 1903, 6033, 4561, 8157, 0 }; + static ulong[] dim1997Kuo2Init = { 1, 3, 5, 13, 17, 59, 125, 93, 397, 277, 1273, 529, 3881, 3345, 32553, 0 }; + static ulong[] dim1998Kuo2Init = { 1, 3, 1, 3, 29, 3, 73, 201, 129, 747, 1417, 77, 4399, 10283, 3677, 0 }; + static ulong[] dim1999Kuo2Init = { 1, 3, 5, 11, 15, 13, 15, 193, 139, 683, 839, 1849, 1229, 7903, 15797, 0 }; + static ulong[] dim2000Kuo2Init = { 1, 1, 7, 1, 19, 37, 103, 173, 63, 269, 1125, 425, 1235, 4193, 10095, 0 }; + static ulong[] dim2001Kuo2Init = { 1, 3, 1, 3, 31, 33, 101, 71, 333, 565, 651, 1741, 3613, 2641, 27201, 0 }; + static ulong[] dim2002Kuo2Init = { 1, 1, 7, 7, 9, 43, 111, 231, 383, 221, 1239, 1927, 715, 7663, 24709, 0 }; + static ulong[] dim2003Kuo2Init = { 1, 1, 7, 1, 3, 41, 117, 129, 53, 527, 1973, 3377, 2803, 10855, 9405, 0 }; + static ulong[] dim2004Kuo2Init = { 1, 3, 5, 15, 15, 61, 29, 75, 141, 517, 255, 1797, 1291, 13859, 10255, 0 }; + static ulong[] dim2005Kuo2Init = { 1, 1, 5, 9, 1, 55, 99, 133, 9, 793, 1525, 2565, 1755, 7293, 27221, 0 }; + static ulong[] dim2006Kuo2Init = { 1, 3, 7, 1, 19, 25, 113, 47, 117, 285, 1937, 513, 75, 2149, 25369, 0 }; + static ulong[] dim2007Kuo2Init = { 1, 3, 3, 7, 3, 45, 1, 145, 501, 197, 423, 1131, 4649, 11027, 25237, 0 }; + static ulong[] dim2008Kuo2Init = { 1, 1, 1, 9, 29, 49, 17, 85, 137, 765, 649, 809, 103, 7537, 5603, 0 }; + static ulong[] dim2009Kuo2Init = { 1, 3, 1, 13, 23, 63, 85, 83, 135, 495, 2023, 2331, 1743, 16221, 2421, 0 }; + static ulong[] dim2010Kuo2Init = { 1, 1, 1, 3, 25, 15, 75, 123, 309, 729, 481, 2335, 6963, 16309, 24593, 0 }; + static ulong[] dim2011Kuo2Init = { 1, 3, 1, 7, 1, 3, 41, 57, 353, 821, 1439, 3445, 2295, 15269, 15821, 0 }; + static ulong[] dim2012Kuo2Init = { 1, 3, 7, 1, 19, 41, 107, 159, 361, 1017, 1435, 2593, 3849, 1139, 5059, 0 }; + static ulong[] dim2013Kuo2Init = { 1, 1, 7, 5, 23, 63, 23, 67, 263, 939, 1167, 3367, 2003, 7903, 1361, 0 }; + static ulong[] dim2014Kuo2Init = { 1, 3, 5, 15, 11, 21, 109, 135, 219, 183, 1303, 2023, 6471, 8203, 21717, 0 }; + static ulong[] dim2015Kuo2Init = { 1, 3, 3, 11, 11, 7, 109, 183, 313, 701, 1661, 2215, 7993, 6097, 15583, 0 }; + static ulong[] dim2016Kuo2Init = { 1, 1, 7, 9, 5, 55, 85, 123, 507, 303, 1701, 767, 313, 12517, 10969, 0 }; + static ulong[] dim2017Kuo2Init = { 1, 3, 1, 15, 1, 31, 97, 249, 407, 829, 693, 135, 5929, 13287, 23105, 0 }; + static ulong[] dim2018Kuo2Init = { 1, 3, 3, 15, 23, 45, 13, 209, 365, 715, 827, 1451, 3817, 9039, 8601, 0 }; + static ulong[] dim2019Kuo2Init = { 1, 1, 5, 3, 3, 5, 41, 175, 65, 467, 179, 1941, 2261, 14143, 10277, 0 }; + static ulong[] dim2020Kuo2Init = { 1, 1, 7, 1, 15, 61, 37, 231, 275, 69, 7, 417, 8131, 12569, 16275, 0 }; + static ulong[] dim2021Kuo2Init = { 1, 1, 7, 11, 3, 49, 1, 243, 237, 303, 2033, 1501, 8059, 1479, 1675, 0 }; + static ulong[] dim2022Kuo2Init = { 1, 1, 3, 5, 21, 49, 87, 5, 235, 343, 1635, 3459, 3961, 14433, 10965, 0 }; + static ulong[] dim2023Kuo2Init = { 1, 1, 7, 13, 29, 5, 105, 167, 57, 247, 1683, 1011, 2071, 10681, 679, 0 }; + static ulong[] dim2024Kuo2Init = { 1, 1, 3, 7, 11, 31, 39, 19, 501, 945, 2043, 3591, 657, 8087, 21159, 0 }; + static ulong[] dim2025Kuo2Init = { 1, 3, 5, 9, 7, 23, 3, 5, 35, 101, 409, 3769, 7163, 739, 28421, 0 }; + static ulong[] dim2026Kuo2Init = { 1, 3, 5, 1, 23, 61, 65, 105, 303, 765, 1483, 883, 5743, 13479, 21489, 0 }; + static ulong[] dim2027Kuo2Init = { 1, 1, 7, 13, 11, 5, 17, 237, 105, 539, 1237, 2727, 3781, 13195, 17029, 0 }; + static ulong[] dim2028Kuo2Init = { 1, 3, 3, 15, 15, 23, 47, 129, 485, 797, 705, 931, 3865, 5029, 27847, 0 }; + static ulong[] dim2029Kuo2Init = { 1, 3, 5, 13, 23, 61, 77, 221, 155, 429, 1933, 3007, 8001, 2137, 15737, 0 }; + static ulong[] dim2030Kuo2Init = { 1, 3, 3, 15, 3, 57, 79, 95, 419, 953, 449, 1843, 6893, 1061, 28427, 0 }; + static ulong[] dim2031Kuo2Init = { 1, 3, 3, 9, 19, 9, 39, 5, 189, 3, 181, 3091, 4215, 14881, 18273, 0 }; + static ulong[] dim2032Kuo2Init = { 1, 1, 3, 13, 17, 63, 27, 49, 483, 947, 173, 3667, 3529, 15343, 23189, 0 }; + static ulong[] dim2033Kuo2Init = { 1, 1, 3, 9, 17, 51, 37, 245, 177, 231, 689, 29, 1029, 12397, 26265, 0 }; + static ulong[] dim2034Kuo2Init = { 1, 3, 1, 13, 15, 35, 55, 5, 303, 559, 1853, 3859, 1879, 3167, 6903, 0 }; + static ulong[] dim2035Kuo2Init = { 1, 3, 3, 9, 9, 47, 59, 163, 373, 621, 1349, 2661, 1787, 13611, 28199, 0 }; + static ulong[] dim2036Kuo2Init = { 1, 3, 3, 9, 15, 55, 93, 193, 267, 325, 1705, 155, 3001, 407, 20829, 0 }; + static ulong[] dim2037Kuo2Init = { 1, 3, 5, 15, 13, 9, 65, 123, 325, 313, 25, 991, 2227, 6597, 30453, 0 }; + static ulong[] dim2038Kuo2Init = { 1, 1, 5, 1, 23, 51, 61, 229, 27, 285, 1185, 1943, 7603, 10565, 22741, 0 }; + static ulong[] dim2039Kuo2Init = { 1, 3, 7, 3, 17, 43, 21, 153, 359, 437, 1275, 3589, 1089, 3941, 16777, 0 }; + static ulong[] dim2040Kuo2Init = { 1, 3, 5, 3, 19, 43, 127, 213, 181, 255, 929, 2553, 1101, 231, 2977, 0 }; + static ulong[] dim2041Kuo2Init = { 1, 3, 7, 11, 7, 49, 39, 209, 141, 691, 1903, 1211, 687, 13107, 17055, 0 }; + static ulong[] dim2042Kuo2Init = { 1, 1, 5, 1, 15, 21, 65, 209, 305, 65, 1383, 2247, 5813, 8961, 16281, 0 }; + static ulong[] dim2043Kuo2Init = { 1, 3, 7, 11, 27, 1, 71, 97, 129, 317, 601, 981, 1947, 8897, 23489, 0 }; + static ulong[] dim2044Kuo2Init = { 1, 1, 3, 9, 17, 35, 57, 37, 243, 217, 703, 3159, 4791, 1365, 14885, 0 }; + static ulong[] dim2045Kuo2Init = { 1, 3, 5, 7, 7, 43, 59, 253, 141, 537, 547, 955, 5351, 13087, 5465, 0 }; + static ulong[] dim2046Kuo2Init = { 1, 1, 5, 9, 15, 53, 47, 105, 55, 1017, 819, 3355, 3653, 11051, 29509, 0 }; + static ulong[] dim2047Kuo2Init = { 1, 1, 3, 7, 17, 39, 13, 125, 161, 985, 1753, 1327, 7635, 11045, 3935, 0 }; + static ulong[] dim2048Kuo2Init = { 1, 1, 7, 9, 1, 19, 55, 227, 111, 347, 85, 3871, 7153, 10527, 3137, 0 }; + static ulong[] dim2049Kuo2Init = { 1, 3, 5, 9, 13, 7, 35, 25, 17, 269, 611, 1523, 3539, 15611, 11837, 0 }; + static ulong[] dim2050Kuo2Init = { 1, 1, 5, 7, 29, 13, 109, 253, 355, 25, 243, 1433, 7463, 10149, 31469, 0 }; + static ulong[] dim2051Kuo2Init = { 1, 3, 3, 15, 1, 51, 85, 27, 137, 299, 1943, 3805, 2661, 8091, 385, 0 }; + static ulong[] dim2052Kuo2Init = { 1, 1, 5, 11, 19, 39, 103, 89, 285, 305, 1157, 149, 6661, 1423, 27163, 0 }; + static ulong[] dim2053Kuo2Init = { 1, 1, 7, 9, 25, 35, 7, 227, 125, 811, 1867, 1851, 5271, 11405, 21457, 0 }; + static ulong[] dim2054Kuo2Init = { 1, 1, 7, 1, 31, 19, 103, 239, 301, 395, 1737, 3467, 7153, 12437, 25795, 0 }; + static ulong[] dim2055Kuo2Init = { 1, 3, 3, 15, 25, 43, 69, 155, 437, 9, 863, 2497, 6857, 3947, 12231, 0 }; + static ulong[] dim2056Kuo2Init = { 1, 3, 7, 11, 3, 63, 27, 207, 87, 727, 791, 1663, 8121, 13149, 3927, 0 }; + static ulong[] dim2057Kuo2Init = { 1, 3, 1, 7, 9, 19, 123, 131, 415, 565, 1571, 1085, 2989, 13693, 32487, 0 }; + static ulong[] dim2058Kuo2Init = { 1, 3, 7, 9, 11, 27, 117, 63, 255, 297, 1147, 1501, 3435, 5861, 21351, 0 }; + static ulong[] dim2059Kuo2Init = { 1, 3, 1, 5, 19, 5, 115, 89, 153, 705, 1233, 1803, 7237, 983, 9299, 0 }; + static ulong[] dim2060Kuo2Init = { 1, 3, 3, 13, 21, 13, 89, 135, 5, 221, 191, 2611, 6007, 9177, 11101, 0 }; + static ulong[] dim2061Kuo2Init = { 1, 3, 7, 15, 9, 43, 123, 123, 301, 233, 1727, 3973, 5241, 13437, 24507, 0 }; + static ulong[] dim2062Kuo2Init = { 1, 3, 3, 5, 19, 29, 33, 127, 185, 319, 1767, 1133, 95, 7745, 32213, 0 }; + static ulong[] dim2063Kuo2Init = { 1, 3, 7, 11, 13, 1, 91, 189, 75, 91, 583, 2317, 5257, 12133, 1951, 0 }; + static ulong[] dim2064Kuo2Init = { 1, 1, 3, 9, 23, 23, 65, 7, 157, 143, 781, 997, 2357, 4907, 16797, 0 }; + static ulong[] dim2065Kuo2Init = { 1, 1, 1, 11, 5, 43, 45, 131, 331, 253, 1975, 415, 2571, 14905, 9595, 0 }; + static ulong[] dim2066Kuo2Init = { 1, 3, 7, 11, 1, 11, 95, 133, 393, 117, 833, 2661, 1683, 14333, 26279, 0 }; + static ulong[] dim2067Kuo2Init = { 1, 3, 7, 5, 23, 51, 57, 9, 63, 377, 2043, 1967, 7039, 13783, 16075, 0 }; + static ulong[] dim2068Kuo2Init = { 1, 3, 5, 5, 13, 49, 65, 59, 449, 665, 2017, 375, 3781, 15139, 26341, 0 }; + static ulong[] dim2069Kuo2Init = { 1, 1, 7, 13, 15, 63, 83, 229, 465, 319, 469, 951, 2405, 15357, 6051, 0 }; + static ulong[] dim2070Kuo2Init = { 1, 3, 3, 7, 15, 37, 97, 37, 89, 717, 449, 1821, 3319, 4957, 5455, 0 }; + static ulong[] dim2071Kuo2Init = { 1, 1, 5, 3, 3, 7, 55, 39, 131, 497, 349, 4083, 6695, 14939, 13979, 0 }; + static ulong[] dim2072Kuo2Init = { 1, 3, 3, 7, 15, 45, 109, 239, 415, 453, 729, 835, 4585, 12751, 8595, 0 }; + static ulong[] dim2073Kuo2Init = { 1, 1, 7, 9, 29, 1, 13, 85, 185, 419, 1269, 981, 5079, 2723, 5275, 0 }; + static ulong[] dim2074Kuo2Init = { 1, 1, 7, 11, 7, 41, 121, 75, 91, 943, 1487, 995, 6815, 15881, 27113, 0 }; + static ulong[] dim2075Kuo2Init = { 1, 1, 7, 9, 1, 53, 83, 209, 327, 547, 1505, 1517, 6105, 5903, 13823, 0 }; + static ulong[] dim2076Kuo2Init = { 1, 1, 3, 15, 25, 1, 33, 61, 249, 367, 1733, 3351, 273, 10053, 27115, 0 }; + static ulong[] dim2077Kuo2Init = { 1, 3, 3, 11, 29, 27, 75, 143, 103, 509, 813, 1881, 2631, 933, 31141, 0 }; + static ulong[] dim2078Kuo2Init = { 1, 3, 3, 7, 31, 9, 27, 69, 291, 927, 183, 1755, 7383, 7721, 4405, 0 }; + static ulong[] dim2079Kuo2Init = { 1, 3, 1, 11, 25, 23, 89, 99, 101, 725, 1791, 2669, 7055, 6703, 27507, 0 }; + static ulong[] dim2080Kuo2Init = { 1, 3, 5, 15, 1, 41, 23, 103, 123, 863, 1643, 947, 1349, 549, 29299, 0 }; + static ulong[] dim2081Kuo2Init = { 1, 1, 3, 3, 9, 53, 67, 187, 203, 565, 1455, 645, 7983, 5311, 8827, 0 }; + static ulong[] dim2082Kuo2Init = { 1, 1, 3, 7, 11, 29, 35, 207, 449, 537, 245, 945, 4067, 10961, 27301, 0 }; + static ulong[] dim2083Kuo2Init = { 1, 3, 1, 13, 3, 23, 15, 171, 439, 217, 1245, 3301, 289, 6895, 30095, 0 }; + static ulong[] dim2084Kuo2Init = { 1, 3, 5, 9, 21, 47, 71, 191, 425, 11, 1831, 3111, 7399, 13689, 28163, 0 }; + static ulong[] dim2085Kuo2Init = { 1, 1, 5, 15, 5, 61, 97, 41, 451, 459, 1007, 2439, 5613, 7985, 9255, 0 }; + static ulong[] dim2086Kuo2Init = { 1, 1, 1, 1, 9, 57, 61, 143, 3, 753, 1839, 2623, 5261, 6169, 13195, 0 }; + static ulong[] dim2087Kuo2Init = { 1, 1, 1, 3, 19, 23, 15, 31, 481, 123, 653, 2763, 5663, 12771, 7469, 0 }; + static ulong[] dim2088Kuo2Init = { 1, 1, 1, 11, 17, 55, 111, 181, 293, 9, 41, 3625, 2865, 9109, 14261, 0 }; + static ulong[] dim2089Kuo2Init = { 1, 1, 5, 15, 27, 13, 45, 109, 321, 609, 551, 4071, 6467, 8245, 6889, 0 }; + static ulong[] dim2090Kuo2Init = { 1, 1, 1, 11, 23, 15, 75, 9, 261, 189, 287, 2479, 2319, 2647, 3415, 0 }; + static ulong[] dim2091Kuo2Init = { 1, 3, 1, 3, 31, 47, 45, 73, 439, 789, 687, 3205, 863, 2471, 27997, 0 }; + static ulong[] dim2092Kuo2Init = { 1, 3, 3, 13, 17, 47, 111, 205, 307, 299, 439, 965, 6093, 3215, 29381, 0 }; + static ulong[] dim2093Kuo2Init = { 1, 1, 7, 11, 11, 31, 119, 93, 385, 149, 843, 3081, 6793, 4427, 23967, 0 }; + static ulong[] dim2094Kuo2Init = { 1, 3, 7, 11, 7, 9, 27, 135, 465, 169, 1229, 1491, 3527, 13801, 13187, 0 }; + static ulong[] dim2095Kuo2Init = { 1, 3, 7, 1, 27, 43, 9, 213, 95, 273, 1067, 1819, 4087, 15955, 7865, 0 }; + static ulong[] dim2096Kuo2Init = { 1, 1, 3, 5, 25, 53, 49, 15, 159, 713, 203, 1599, 4807, 7275, 20589, 0 }; + static ulong[] dim2097Kuo2Init = { 1, 3, 1, 7, 9, 33, 5, 41, 289, 611, 153, 1019, 5571, 8459, 2903, 0 }; + static ulong[] dim2098Kuo2Init = { 1, 1, 5, 11, 5, 9, 9, 245, 205, 821, 73, 2907, 2061, 10255, 24837, 0 }; + static ulong[] dim2099Kuo2Init = { 1, 3, 3, 15, 3, 29, 79, 139, 57, 181, 741, 667, 3251, 15741, 2349, 0 }; + static ulong[] dim2100Kuo2Init = { 1, 1, 7, 11, 15, 31, 63, 115, 475, 801, 195, 155, 2167, 9215, 11041, 0 }; + static ulong[] dim2101Kuo2Init = { 1, 3, 7, 3, 7, 45, 17, 151, 353, 751, 373, 1523, 6271, 10307, 637, 0 }; + static ulong[] dim2102Kuo2Init = { 1, 1, 1, 13, 15, 59, 99, 143, 261, 349, 327, 3931, 3365, 12179, 3017, 0 }; + static ulong[] dim2103Kuo2Init = { 1, 3, 5, 1, 27, 13, 105, 127, 177, 857, 405, 185, 5793, 8043, 11671, 0 }; + static ulong[] dim2104Kuo2Init = { 1, 1, 7, 5, 9, 51, 127, 47, 421, 687, 961, 1413, 6619, 3459, 9093, 0 }; + static ulong[] dim2105Kuo2Init = { 1, 1, 7, 11, 15, 45, 7, 123, 479, 55, 491, 2901, 5183, 6081, 31719, 0 }; + static ulong[] dim2106Kuo2Init = { 1, 3, 3, 13, 3, 49, 29, 147, 453, 659, 753, 233, 251, 12445, 6573, 0 }; + static ulong[] dim2107Kuo2Init = { 1, 1, 3, 9, 7, 41, 3, 59, 187, 37, 1503, 4079, 5687, 16213, 9573, 0 }; + static ulong[] dim2108Kuo2Init = { 1, 3, 7, 13, 19, 49, 75, 173, 219, 889, 859, 2021, 2249, 4031, 29485, 0 }; + static ulong[] dim2109Kuo2Init = { 1, 3, 7, 9, 3, 21, 37, 79, 277, 307, 465, 1219, 4099, 5285, 27883, 0 }; + static ulong[] dim2110Kuo2Init = { 1, 3, 5, 3, 19, 49, 97, 7, 483, 995, 775, 883, 2011, 16321, 31869, 0 }; + static ulong[] dim2111Kuo2Init = { 1, 3, 7, 1, 25, 59, 113, 177, 507, 911, 1251, 571, 917, 2655, 31463, 0 }; + static ulong[] dim2112Kuo2Init = { 1, 3, 1, 5, 15, 23, 47, 79, 401, 245, 317, 1033, 3377, 2605, 13021, 0 }; + static ulong[] dim2113Kuo2Init = { 1, 1, 3, 7, 3, 1, 41, 253, 507, 283, 707, 1305, 2353, 5721, 15469, 0 }; + static ulong[] dim2114Kuo2Init = { 1, 3, 1, 7, 25, 25, 15, 79, 193, 235, 1981, 2059, 2057, 1647, 5443, 0 }; + static ulong[] dim2115Kuo2Init = { 1, 1, 1, 3, 7, 37, 51, 169, 163, 223, 457, 1841, 857, 15847, 27369, 0 }; + static ulong[] dim2116Kuo2Init = { 1, 1, 3, 11, 23, 49, 93, 89, 347, 213, 615, 1305, 885, 6195, 6659, 0 }; + static ulong[] dim2117Kuo2Init = { 1, 3, 7, 9, 9, 27, 3, 217, 337, 977, 1109, 1915, 677, 8927, 4449, 0 }; + static ulong[] dim2118Kuo2Init = { 1, 1, 7, 5, 11, 39, 23, 189, 467, 735, 817, 2269, 5959, 2933, 15667, 0 }; + static ulong[] dim2119Kuo2Init = { 1, 1, 5, 5, 21, 33, 21, 241, 75, 751, 671, 3053, 7865, 4261, 13455, 0 }; + static ulong[] dim2120Kuo2Init = { 1, 3, 1, 7, 25, 11, 21, 149, 429, 275, 1815, 1153, 4471, 14993, 3543, 0 }; + static ulong[] dim2121Kuo2Init = { 1, 3, 5, 1, 3, 47, 9, 113, 423, 205, 1905, 57, 6157, 6335, 7425, 0 }; + static ulong[] dim2122Kuo2Init = { 1, 1, 7, 11, 17, 13, 97, 99, 145, 319, 945, 1559, 3379, 12559, 22479, 0 }; + static ulong[] dim2123Kuo2Init = { 1, 1, 7, 9, 3, 47, 105, 251, 87, 293, 1191, 2211, 4631, 8443, 11789, 0 }; + static ulong[] dim2124Kuo2Init = { 1, 1, 1, 3, 5, 1, 41, 115, 331, 401, 1649, 179, 1639, 16241, 18481, 0 }; + static ulong[] dim2125Kuo2Init = { 1, 3, 1, 7, 15, 33, 117, 121, 81, 807, 1897, 1731, 2793, 12531, 8863, 0 }; + static ulong[] dim2126Kuo2Init = { 1, 3, 1, 13, 1, 41, 83, 5, 331, 423, 855, 1327, 5799, 3679, 21461, 0 }; + static ulong[] dim2127Kuo2Init = { 1, 3, 1, 3, 19, 37, 75, 39, 413, 123, 1073, 2299, 5379, 12805, 3527, 0 }; + static ulong[] dim2128Kuo2Init = { 1, 3, 3, 1, 7, 17, 25, 227, 383, 501, 673, 2609, 1843, 3367, 9901, 0 }; + static ulong[] dim2129Kuo2Init = { 1, 1, 7, 11, 25, 29, 95, 33, 431, 257, 1013, 3755, 2813, 15247, 1045, 0 }; + static ulong[] dim2130Kuo2Init = { 1, 1, 7, 3, 15, 25, 79, 67, 175, 697, 1867, 1967, 8023, 2017, 15449, 0 }; + static ulong[] dim2131Kuo2Init = { 1, 3, 3, 1, 21, 25, 67, 177, 479, 81, 495, 3531, 1997, 5169, 15861, 0 }; + static ulong[] dim2132Kuo2Init = { 1, 3, 3, 9, 7, 23, 57, 97, 7, 917, 1969, 3421, 2149, 11379, 1035, 0 }; + static ulong[] dim2133Kuo2Init = { 1, 1, 5, 9, 5, 45, 51, 29, 289, 49, 1311, 4005, 3619, 12337, 7693, 0 }; + static ulong[] dim2134Kuo2Init = { 1, 3, 1, 7, 25, 9, 11, 23, 281, 517, 1309, 2719, 3133, 529, 21795, 0 }; + static ulong[] dim2135Kuo2Init = { 1, 3, 3, 1, 5, 43, 79, 87, 389, 189, 547, 3161, 4765, 10751, 15557, 0 }; + static ulong[] dim2136Kuo2Init = { 1, 3, 1, 13, 29, 11, 5, 75, 453, 323, 999, 341, 6991, 14803, 31057, 0 }; + static ulong[] dim2137Kuo2Init = { 1, 1, 5, 11, 7, 3, 81, 201, 195, 221, 1949, 2205, 2273, 12029, 21089, 0 }; + static ulong[] dim2138Kuo2Init = { 1, 1, 7, 1, 25, 53, 7, 135, 7, 179, 797, 567, 1459, 9773, 2839, 0 }; + static ulong[] dim2139Kuo2Init = { 1, 1, 3, 7, 31, 27, 41, 253, 273, 749, 1605, 2259, 7171, 11861, 11769, 0 }; + static ulong[] dim2140Kuo2Init = { 1, 1, 1, 5, 13, 49, 25, 131, 397, 783, 1849, 3585, 2727, 8213, 14849, 0 }; + static ulong[] dim2141Kuo2Init = { 1, 3, 5, 1, 25, 35, 121, 159, 27, 305, 1841, 1893, 829, 11659, 9859, 0 }; + static ulong[] dim2142Kuo2Init = { 1, 1, 5, 5, 3, 11, 79, 49, 95, 755, 1011, 2247, 5731, 12975, 20241, 0 }; + static ulong[] dim2143Kuo2Init = { 1, 1, 5, 3, 25, 5, 103, 35, 337, 619, 35, 3655, 5137, 4867, 6055, 0 }; + static ulong[] dim2144Kuo2Init = { 1, 1, 7, 1, 15, 35, 67, 113, 381, 1001, 177, 3981, 1059, 4433, 26845, 0 }; + static ulong[] dim2145Kuo2Init = { 1, 3, 7, 9, 19, 3, 107, 161, 109, 129, 1447, 4053, 7435, 3483, 7595, 0 }; + static ulong[] dim2146Kuo2Init = { 1, 1, 7, 9, 13, 25, 19, 137, 149, 191, 719, 1279, 6129, 6367, 9335, 0 }; + static ulong[] dim2147Kuo2Init = { 1, 3, 5, 11, 19, 55, 19, 191, 31, 341, 485, 1165, 501, 11771, 17423, 0 }; + static ulong[] dim2148Kuo2Init = { 1, 3, 7, 1, 21, 35, 115, 163, 99, 581, 1769, 1887, 6349, 13467, 10503, 0 }; + static ulong[] dim2149Kuo2Init = { 1, 1, 7, 3, 23, 21, 105, 255, 501, 171, 1689, 1747, 2603, 11783, 7633, 0 }; + static ulong[] dim2150Kuo2Init = { 1, 1, 7, 7, 9, 45, 65, 95, 47, 163, 1597, 2693, 7407, 8155, 13645, 0 }; + static ulong[] dim2151Kuo2Init = { 1, 1, 1, 1, 9, 5, 105, 55, 217, 773, 43, 741, 1093, 8087, 8003, 0 }; + static ulong[] dim2152Kuo2Init = { 1, 3, 5, 15, 19, 29, 127, 29, 23, 27, 2011, 623, 2649, 2979, 269, 0 }; + static ulong[] dim2153Kuo2Init = { 1, 3, 3, 15, 3, 17, 121, 85, 313, 333, 89, 1, 1147, 15909, 24017, 0 }; + static ulong[] dim2154Kuo2Init = { 1, 3, 5, 13, 17, 53, 89, 27, 219, 451, 629, 2539, 4151, 4811, 17057, 0 }; + static ulong[] dim2155Kuo2Init = { 1, 1, 1, 3, 31, 47, 127, 63, 85, 387, 61, 685, 1103, 1257, 19305, 0 }; + static ulong[] dim2156Kuo2Init = { 1, 3, 7, 11, 25, 7, 39, 209, 449, 667, 227, 605, 987, 1699, 11001, 0 }; + static ulong[] dim2157Kuo2Init = { 1, 3, 5, 15, 23, 35, 15, 193, 25, 1021, 1371, 3015, 7837, 14087, 21779, 0 }; + static ulong[] dim2158Kuo2Init = { 1, 1, 5, 1, 1, 25, 25, 241, 493, 901, 1261, 261, 6959, 16013, 2849, 0 }; + static ulong[] dim2159Kuo2Init = { 1, 3, 1, 5, 13, 27, 85, 41, 139, 567, 753, 3255, 5633, 15687, 3019, 0 }; + static ulong[] dim2160Kuo2Init = { 1, 1, 3, 11, 19, 61, 43, 153, 299, 931, 1481, 203, 593, 5019, 28309, 0 }; + static ulong[] dim2161Kuo2Init = { 1, 3, 7, 7, 9, 11, 107, 243, 227, 69, 605, 3761, 1091, 4503, 21203, 0 }; + static ulong[] dim2162Kuo2Init = { 1, 3, 5, 11, 11, 55, 47, 167, 291, 883, 1411, 3099, 1099, 11619, 9781, 0 }; + static ulong[] dim2163Kuo2Init = { 1, 3, 7, 15, 23, 53, 109, 247, 459, 793, 839, 3069, 1829, 5151, 26255, 0 }; + static ulong[] dim2164Kuo2Init = { 1, 3, 1, 15, 11, 31, 73, 193, 341, 791, 187, 3787, 4481, 11435, 715, 0 }; + static ulong[] dim2165Kuo2Init = { 1, 3, 1, 13, 13, 61, 79, 193, 455, 571, 1277, 1565, 7385, 4393, 27447, 0 }; + static ulong[] dim2166Kuo2Init = { 1, 3, 7, 3, 13, 35, 39, 89, 335, 701, 1423, 2441, 2895, 2795, 28511, 0 }; + static ulong[] dim2167Kuo2Init = { 1, 3, 1, 1, 9, 27, 39, 163, 127, 163, 1881, 1995, 2629, 4541, 1669, 0 }; + static ulong[] dim2168Kuo2Init = { 1, 1, 5, 3, 5, 53, 29, 223, 433, 643, 1035, 2339, 5947, 3047, 27409, 0 }; + static ulong[] dim2169Kuo2Init = { 1, 3, 1, 15, 5, 35, 47, 49, 347, 579, 551, 2285, 3171, 8041, 8223, 0 }; + static ulong[] dim2170Kuo2Init = { 1, 1, 1, 1, 1, 57, 51, 219, 339, 95, 1585, 2811, 4771, 1475, 7919, 0 }; + static ulong[] dim2171Kuo2Init = { 1, 3, 7, 3, 21, 11, 51, 143, 111, 475, 1669, 3717, 6579, 7161, 9491, 0 }; + static ulong[] dim2172Kuo2Init = { 1, 3, 1, 5, 1, 17, 15, 179, 485, 587, 571, 3259, 3299, 207, 2121, 0 }; + static ulong[] dim2173Kuo2Init = { 1, 3, 5, 13, 27, 19, 23, 47, 289, 997, 523, 3183, 8087, 2621, 31471, 0 }; + static ulong[] dim2174Kuo2Init = { 1, 1, 3, 7, 23, 21, 125, 181, 393, 177, 419, 2809, 6727, 1063, 10889, 0 }; + static ulong[] dim2175Kuo2Init = { 1, 3, 5, 1, 19, 29, 115, 149, 439, 125, 7, 2173, 6691, 4063, 8193, 0 }; + static ulong[] dim2176Kuo2Init = { 1, 1, 3, 11, 3, 17, 9, 251, 493, 977, 1713, 2711, 4377, 3171, 22195, 0 }; + static ulong[] dim2177Kuo2Init = { 1, 1, 3, 1, 17, 63, 73, 141, 323, 875, 713, 2133, 3283, 10039, 11431, 0 }; + static ulong[] dim2178Kuo2Init = { 1, 1, 7, 5, 29, 33, 63, 19, 191, 915, 1523, 3505, 2431, 9531, 5253, 0 }; + static ulong[] dim2179Kuo2Init = { 1, 3, 5, 5, 15, 25, 81, 97, 455, 141, 1947, 2001, 6015, 11439, 29725, 0 }; + static ulong[] dim2180Kuo2Init = { 1, 1, 1, 1, 7, 35, 71, 205, 485, 495, 345, 1991, 6905, 12535, 2209, 0 }; + static ulong[] dim2181Kuo2Init = { 1, 1, 7, 15, 27, 23, 19, 119, 347, 519, 423, 1567, 7783, 15095, 23609, 0 }; + static ulong[] dim2182Kuo2Init = { 1, 3, 7, 1, 23, 13, 23, 239, 199, 575, 1149, 771, 3779, 12437, 32301, 0 }; + static ulong[] dim2183Kuo2Init = { 1, 3, 5, 3, 31, 55, 87, 111, 233, 633, 1037, 4053, 2007, 15197, 31531, 0 }; + static ulong[] dim2184Kuo2Init = { 1, 1, 1, 7, 3, 47, 11, 169, 293, 959, 903, 2129, 1049, 1311, 4027, 0 }; + static ulong[] dim2185Kuo2Init = { 1, 3, 3, 7, 1, 15, 37, 79, 299, 989, 969, 2699, 4531, 8455, 30613, 0 }; + static ulong[] dim2186Kuo2Init = { 1, 3, 1, 15, 13, 25, 57, 237, 117, 659, 517, 1821, 4755, 6745, 13269, 0 }; + static ulong[] dim2187Kuo2Init = { 1, 3, 7, 11, 3, 27, 53, 197, 285, 897, 5, 675, 255, 5999, 7629, 0 }; + static ulong[] dim2188Kuo2Init = { 1, 3, 7, 7, 21, 21, 71, 117, 347, 251, 1025, 2455, 7177, 9135, 15569, 0 }; + static ulong[] dim2189Kuo2Init = { 1, 3, 1, 3, 25, 7, 113, 229, 243, 173, 1903, 427, 2743, 2245, 12783, 0 }; + static ulong[] dim2190Kuo2Init = { 1, 1, 1, 15, 11, 53, 45, 209, 181, 147, 183, 3133, 4793, 14731, 16491, 0 }; + static ulong[] dim2191Kuo2Init = { 1, 3, 7, 5, 27, 45, 77, 211, 89, 555, 1829, 4073, 839, 12079, 27745, 0 }; + static ulong[] dim2192Kuo2Init = { 1, 1, 3, 7, 1, 29, 17, 65, 47, 995, 85, 69, 641, 4139, 1221, 0 }; + static ulong[] dim2193Kuo2Init = { 1, 3, 3, 3, 11, 57, 11, 69, 285, 837, 1129, 3465, 323, 4599, 6593, 0 }; + static ulong[] dim2194Kuo2Init = { 1, 3, 5, 7, 19, 27, 1, 197, 259, 315, 567, 613, 5385, 4495, 13507, 0 }; + static ulong[] dim2195Kuo2Init = { 1, 3, 3, 7, 13, 63, 3, 81, 363, 67, 1025, 1403, 4469, 9881, 3563, 0 }; + static ulong[] dim2196Kuo2Init = { 1, 1, 1, 5, 23, 1, 103, 51, 445, 1017, 361, 811, 4555, 6013, 25117, 0 }; + static ulong[] dim2197Kuo2Init = { 1, 1, 1, 11, 21, 33, 73, 13, 155, 419, 371, 499, 3003, 7577, 19191, 0 }; + static ulong[] dim2198Kuo2Init = { 1, 1, 1, 13, 19, 57, 91, 251, 157, 551, 1529, 2649, 7785, 4357, 18533, 0 }; + static ulong[] dim2199Kuo2Init = { 1, 1, 1, 15, 29, 23, 33, 139, 495, 87, 1291, 1441, 819, 321, 24597, 0 }; + static ulong[] dim2200Kuo2Init = { 1, 1, 5, 7, 11, 21, 127, 135, 395, 511, 213, 4043, 5869, 5733, 23157, 0 }; + static ulong[] dim2201Kuo2Init = { 1, 3, 5, 5, 1, 61, 99, 155, 415, 111, 1335, 241, 1935, 7457, 7127, 0 }; + static ulong[] dim2202Kuo2Init = { 1, 1, 3, 7, 25, 43, 69, 97, 423, 989, 1433, 107, 7253, 6543, 1685, 0 }; + static ulong[] dim2203Kuo2Init = { 1, 3, 1, 3, 9, 51, 77, 69, 1, 75, 1859, 3735, 1199, 13725, 6689, 0 }; + static ulong[] dim2204Kuo2Init = { 1, 3, 5, 7, 13, 7, 103, 91, 465, 675, 1221, 2853, 6785, 7113, 12671, 0 }; + static ulong[] dim2205Kuo2Init = { 1, 3, 1, 15, 9, 9, 75, 17, 357, 559, 1021, 1023, 779, 10805, 12707, 0 }; + static ulong[] dim2206Kuo2Init = { 1, 3, 5, 1, 19, 41, 25, 209, 61, 225, 533, 2661, 6735, 4877, 20085, 0 }; + static ulong[] dim2207Kuo2Init = { 1, 1, 5, 7, 29, 35, 61, 21, 203, 689, 1431, 2009, 3475, 2103, 19457, 0 }; + static ulong[] dim2208Kuo2Init = { 1, 1, 3, 9, 7, 51, 119, 115, 357, 969, 779, 2407, 1669, 4671, 21945, 0 }; + static ulong[] dim2209Kuo2Init = { 1, 1, 5, 13, 5, 33, 125, 61, 123, 569, 7, 2389, 3325, 15701, 16931, 0 }; + static ulong[] dim2210Kuo2Init = { 1, 1, 3, 7, 13, 29, 7, 205, 397, 861, 1035, 675, 5963, 9229, 14537, 0 }; + static ulong[] dim2211Kuo2Init = { 1, 3, 7, 5, 13, 41, 69, 25, 461, 745, 189, 3239, 4515, 2717, 22815, 0 }; + static ulong[] dim2212Kuo2Init = { 1, 1, 1, 7, 29, 47, 49, 91, 403, 325, 1241, 2295, 6371, 6791, 911, 0 }; + static ulong[] dim2213Kuo2Init = { 1, 1, 1, 5, 13, 47, 83, 161, 371, 779, 1935, 3445, 735, 1963, 17267, 0 }; + static ulong[] dim2214Kuo2Init = { 1, 3, 7, 7, 19, 59, 41, 217, 71, 407, 1639, 4081, 8011, 4805, 1847, 0 }; + static ulong[] dim2215Kuo2Init = { 1, 1, 7, 9, 21, 11, 113, 151, 269, 119, 615, 2657, 1835, 16071, 7475, 0 }; + static ulong[] dim2216Kuo2Init = { 1, 1, 1, 13, 13, 53, 121, 231, 419, 439, 1287, 3043, 8187, 4355, 16377, 0 }; + static ulong[] dim2217Kuo2Init = { 1, 1, 1, 3, 1, 51, 69, 49, 403, 549, 659, 501, 7497, 9461, 8813, 0 }; + static ulong[] dim2218Kuo2Init = { 1, 3, 3, 9, 15, 13, 11, 65, 241, 77, 675, 2077, 927, 11841, 2527, 0 }; + static ulong[] dim2219Kuo2Init = { 1, 1, 5, 9, 23, 35, 113, 33, 497, 1001, 1105, 2157, 1209, 7821, 20345, 0 }; + static ulong[] dim2220Kuo2Init = { 1, 1, 1, 5, 23, 39, 81, 151, 259, 491, 1129, 1115, 4501, 5513, 20347, 0 }; + static ulong[] dim2221Kuo2Init = { 1, 1, 5, 1, 11, 59, 55, 195, 157, 915, 35, 489, 2805, 9059, 14757, 0 }; + static ulong[] dim2222Kuo2Init = { 1, 3, 5, 15, 9, 21, 91, 59, 425, 127, 1939, 2763, 1243, 4303, 4549, 0 }; + static ulong[] dim2223Kuo2Init = { 1, 1, 5, 13, 19, 29, 127, 251, 91, 419, 333, 2943, 1649, 8653, 32401, 0 }; + static ulong[] dim2224Kuo2Init = { 1, 3, 1, 11, 13, 13, 73, 153, 131, 675, 1235, 1565, 2153, 3999, 3075, 0 }; + static ulong[] dim2225Kuo2Init = { 1, 1, 5, 13, 1, 29, 111, 229, 23, 649, 1017, 2257, 1967, 9839, 21179, 0 }; + static ulong[] dim2226Kuo2Init = { 1, 1, 3, 9, 13, 59, 39, 243, 453, 51, 801, 727, 5391, 11987, 12431, 0 }; + static ulong[] dim2227Kuo2Init = { 1, 1, 7, 5, 9, 7, 59, 203, 177, 255, 1525, 1869, 5187, 135, 11205, 0 }; + static ulong[] dim2228Kuo2Init = { 1, 1, 5, 5, 17, 49, 115, 101, 45, 385, 1751, 883, 7437, 3839, 7997, 0 }; + static ulong[] dim2229Kuo2Init = { 1, 1, 1, 13, 11, 17, 99, 127, 457, 333, 395, 1387, 4533, 2247, 5999, 0 }; + static ulong[] dim2230Kuo2Init = { 1, 3, 7, 7, 15, 61, 103, 217, 175, 133, 1721, 1735, 8083, 14973, 20891, 0 }; + static ulong[] dim2231Kuo2Init = { 1, 1, 1, 13, 31, 35, 69, 53, 191, 671, 1339, 1677, 4463, 1951, 28129, 0 }; + static ulong[] dim2232Kuo2Init = { 1, 3, 3, 15, 19, 13, 73, 171, 481, 981, 343, 1831, 2967, 1801, 9923, 0 }; + static ulong[] dim2233Kuo2Init = { 1, 1, 7, 7, 9, 29, 57, 113, 425, 705, 673, 3749, 1883, 12295, 9669, 0 }; + static ulong[] dim2234Kuo2Init = { 1, 3, 1, 3, 13, 35, 23, 35, 303, 281, 773, 3053, 3841, 7943, 5023, 0 }; + static ulong[] dim2235Kuo2Init = { 1, 1, 7, 15, 11, 27, 85, 163, 349, 289, 297, 3043, 6469, 12029, 8087, 0 }; + static ulong[] dim2236Kuo2Init = { 1, 1, 5, 15, 27, 47, 3, 51, 87, 583, 893, 971, 6859, 7459, 6931, 0 }; + static ulong[] dim2237Kuo2Init = { 1, 3, 3, 15, 21, 57, 65, 141, 129, 345, 745, 2281, 4753, 2899, 1891, 0 }; + static ulong[] dim2238Kuo2Init = { 1, 1, 1, 11, 7, 3, 87, 127, 133, 243, 241, 557, 6537, 1645, 24843, 0 }; + static ulong[] dim2239Kuo2Init = { 1, 1, 7, 1, 7, 37, 91, 9, 337, 787, 1833, 3259, 1335, 6365, 30259, 0 }; + static ulong[] dim2240Kuo2Init = { 1, 1, 1, 9, 7, 3, 127, 41, 41, 377, 1633, 3031, 4483, 12555, 23921, 0 }; + static ulong[] dim2241Kuo2Init = { 1, 1, 7, 1, 21, 9, 77, 243, 373, 289, 715, 2323, 2549, 8891, 22603, 0 }; + static ulong[] dim2242Kuo2Init = { 1, 1, 1, 5, 19, 53, 81, 83, 111, 593, 1041, 499, 5849, 1261, 9561, 0 }; + static ulong[] dim2243Kuo2Init = { 1, 3, 5, 15, 11, 45, 13, 217, 309, 249, 1597, 2829, 2185, 11919, 22975, 0 }; + static ulong[] dim2244Kuo2Init = { 1, 1, 1, 3, 31, 3, 69, 105, 449, 339, 1705, 551, 1701, 1163, 22551, 0 }; + static ulong[] dim2245Kuo2Init = { 1, 1, 3, 7, 29, 23, 115, 119, 25, 425, 225, 1379, 1443, 9549, 31083, 0 }; + static ulong[] dim2246Kuo2Init = { 1, 1, 7, 11, 31, 37, 121, 29, 367, 171, 1611, 3147, 4887, 15191, 27943, 0 }; + static ulong[] dim2247Kuo2Init = { 1, 1, 5, 1, 25, 11, 39, 137, 251, 557, 1833, 2803, 2081, 819, 12493, 0 }; + static ulong[] dim2248Kuo2Init = { 1, 1, 1, 3, 17, 19, 87, 123, 333, 215, 685, 1235, 2327, 5927, 16909, 0 }; + static ulong[] dim2249Kuo2Init = { 1, 1, 7, 7, 5, 31, 127, 205, 197, 671, 1101, 1767, 7871, 4157, 31301, 0 }; + static ulong[] dim2250Kuo2Init = { 1, 1, 5, 5, 17, 5, 23, 175, 363, 831, 563, 2599, 7081, 11695, 10301, 0 }; + static ulong[] dim2251Kuo2Init = { 1, 3, 3, 1, 21, 55, 97, 163, 443, 533, 1889, 1431, 6671, 14699, 26863, 0 }; + static ulong[] dim2252Kuo2Init = { 1, 3, 5, 15, 27, 15, 7, 215, 7, 557, 819, 3855, 619, 10185, 23715, 0 }; + static ulong[] dim2253Kuo2Init = { 1, 3, 7, 1, 17, 23, 25, 59, 369, 675, 463, 809, 8097, 9263, 8907, 0 }; + static ulong[] dim2254Kuo2Init = { 1, 1, 1, 3, 1, 29, 63, 65, 103, 659, 1883, 1141, 641, 6083, 16237, 0 }; + static ulong[] dim2255Kuo2Init = { 1, 1, 1, 3, 5, 41, 13, 143, 349, 811, 1645, 1871, 3385, 12795, 25105, 0 }; + static ulong[] dim2256Kuo2Init = { 1, 1, 1, 15, 17, 7, 73, 195, 439, 85, 1701, 3989, 1619, 5319, 20593, 0 }; + static ulong[] dim2257Kuo2Init = { 1, 1, 3, 15, 1, 9, 61, 223, 441, 543, 765, 3477, 2569, 6061, 25353, 0 }; + static ulong[] dim2258Kuo2Init = { 1, 1, 3, 11, 29, 63, 9, 149, 307, 705, 871, 2975, 4145, 431, 14483, 0 }; + static ulong[] dim2259Kuo2Init = { 1, 1, 1, 3, 11, 7, 103, 85, 389, 719, 1201, 3139, 2941, 13867, 1915, 0 }; + static ulong[] dim2260Kuo2Init = { 1, 1, 3, 3, 21, 27, 65, 59, 223, 335, 1845, 1315, 3619, 1851, 4313, 0 }; + static ulong[] dim2261Kuo2Init = { 1, 3, 7, 13, 21, 21, 19, 181, 39, 89, 1703, 791, 597, 3349, 14387, 0 }; + static ulong[] dim2262Kuo2Init = { 1, 3, 5, 3, 9, 19, 49, 253, 61, 313, 1763, 629, 1951, 16157, 14435, 0 }; + static ulong[] dim2263Kuo2Init = { 1, 1, 5, 13, 23, 41, 45, 107, 111, 287, 1829, 33, 5433, 7283, 20573, 0 }; + static ulong[] dim2264Kuo2Init = { 1, 3, 3, 5, 17, 43, 117, 55, 275, 763, 1581, 2349, 1219, 16145, 545, 0 }; + static ulong[] dim2265Kuo2Init = { 1, 1, 5, 3, 13, 23, 65, 97, 347, 169, 1371, 2373, 4577, 14667, 5713, 0 }; + static ulong[] dim2266Kuo2Init = { 1, 1, 5, 11, 1, 43, 17, 87, 287, 943, 1257, 3383, 2389, 3349, 11641, 0 }; + static ulong[] dim2267Kuo2Init = { 1, 3, 1, 7, 27, 37, 127, 27, 239, 5, 575, 1811, 7185, 10233, 20519, 0 }; + static ulong[] dim2268Kuo2Init = { 1, 3, 1, 13, 21, 33, 91, 147, 351, 283, 1765, 3497, 3113, 7635, 21229, 0 }; + static ulong[] dim2269Kuo2Init = { 1, 3, 7, 3, 19, 39, 47, 135, 495, 401, 843, 551, 5239, 6525, 32339, 0 }; + static ulong[] dim2270Kuo2Init = { 1, 3, 3, 3, 1, 37, 61, 243, 491, 139, 613, 685, 3027, 8053, 4935, 0 }; + static ulong[] dim2271Kuo2Init = { 1, 1, 7, 1, 13, 43, 25, 117, 43, 161, 747, 3005, 5445, 7559, 31029, 0 }; + static ulong[] dim2272Kuo2Init = { 1, 1, 1, 1, 9, 31, 107, 57, 121, 733, 1813, 2057, 2473, 1769, 14649, 0 }; + static ulong[] dim2273Kuo2Init = { 1, 1, 7, 7, 7, 53, 105, 163, 401, 391, 849, 2359, 6819, 13905, 17267, 0 }; + static ulong[] dim2274Kuo2Init = { 1, 1, 5, 7, 23, 9, 31, 39, 7, 767, 153, 2969, 5539, 6581, 30515, 0 }; + static ulong[] dim2275Kuo2Init = { 1, 3, 7, 5, 3, 63, 73, 167, 485, 837, 403, 193, 2707, 2017, 743, 0 }; + static ulong[] dim2276Kuo2Init = { 1, 1, 5, 15, 17, 59, 115, 115, 463, 203, 607, 343, 577, 6985, 8797, 0 }; + static ulong[] dim2277Kuo2Init = { 1, 1, 7, 3, 19, 61, 33, 245, 337, 105, 597, 807, 1669, 5447, 15173, 0 }; + static ulong[] dim2278Kuo2Init = { 1, 3, 3, 9, 27, 51, 67, 135, 151, 215, 217, 221, 6467, 3693, 4563, 0 }; + static ulong[] dim2279Kuo2Init = { 1, 1, 1, 3, 1, 5, 91, 223, 491, 783, 287, 4067, 6747, 2489, 11513, 0 }; + static ulong[] dim2280Kuo2Init = { 1, 3, 1, 3, 25, 15, 9, 3, 445, 893, 399, 2073, 3715, 2493, 7761, 0 }; + static ulong[] dim2281Kuo2Init = { 1, 3, 1, 11, 5, 41, 121, 107, 15, 547, 1417, 1275, 7255, 14979, 26993, 0 }; + static ulong[] dim2282Kuo2Init = { 1, 1, 5, 5, 29, 41, 115, 195, 305, 887, 335, 3919, 6607, 15783, 21457, 0 }; + static ulong[] dim2283Kuo2Init = { 1, 1, 7, 15, 11, 43, 53, 19, 37, 219, 1905, 1153, 4783, 11817, 11119, 0 }; + static ulong[] dim2284Kuo2Init = { 1, 1, 5, 13, 31, 57, 73, 237, 443, 755, 1141, 793, 8177, 9053, 25949, 0 }; + static ulong[] dim2285Kuo2Init = { 1, 1, 3, 9, 9, 11, 1, 151, 249, 701, 523, 2383, 647, 7979, 28965, 0 }; + static ulong[] dim2286Kuo2Init = { 1, 3, 1, 9, 7, 47, 47, 117, 239, 213, 1747, 3093, 3111, 6689, 22451, 0 }; + static ulong[] dim2287Kuo2Init = { 1, 1, 3, 1, 21, 43, 111, 97, 323, 733, 1051, 3567, 1217, 3731, 15475, 0 }; + static ulong[] dim2288Kuo2Init = { 1, 3, 1, 9, 29, 13, 63, 151, 469, 211, 927, 1893, 7741, 9733, 5777, 0 }; + static ulong[] dim2289Kuo2Init = { 1, 1, 1, 15, 17, 49, 65, 81, 325, 847, 193, 3777, 4979, 1621, 17401, 0 }; + static ulong[] dim2290Kuo2Init = { 1, 3, 3, 15, 27, 31, 37, 185, 339, 731, 1317, 527, 1889, 10609, 27419, 0 }; + static ulong[] dim2291Kuo2Init = { 1, 1, 3, 13, 27, 45, 85, 193, 293, 909, 205, 2245, 2845, 11575, 21997, 0 }; + static ulong[] dim2292Kuo2Init = { 1, 3, 1, 3, 13, 63, 49, 97, 343, 331, 2015, 2117, 6367, 13501, 12029, 0 }; + static ulong[] dim2293Kuo2Init = { 1, 3, 3, 1, 15, 9, 61, 41, 355, 327, 1285, 571, 3437, 10489, 24383, 0 }; + static ulong[] dim2294Kuo2Init = { 1, 1, 7, 13, 23, 13, 7, 127, 329, 323, 2037, 31, 407, 11301, 28027, 0 }; + static ulong[] dim2295Kuo2Init = { 1, 1, 3, 1, 23, 61, 99, 237, 15, 257, 1575, 2077, 6507, 3365, 21885, 0 }; + static ulong[] dim2296Kuo2Init = { 1, 3, 5, 11, 15, 61, 111, 25, 309, 853, 1203, 2943, 4875, 9233, 197, 0 }; + static ulong[] dim2297Kuo2Init = { 1, 3, 3, 7, 5, 15, 17, 97, 213, 991, 867, 2291, 8129, 9381, 787, 0 }; + static ulong[] dim2298Kuo2Init = { 1, 3, 5, 1, 31, 45, 105, 35, 403, 595, 1007, 3633, 5167, 11245, 6643, 0 }; + static ulong[] dim2299Kuo2Init = { 1, 3, 5, 5, 1, 51, 121, 161, 109, 369, 447, 213, 4879, 5639, 7233, 0 }; + static ulong[] dim2300Kuo2Init = { 1, 1, 7, 5, 3, 27, 35, 143, 489, 435, 1483, 3261, 7427, 3105, 5297, 0 }; + static ulong[] dim2301Kuo2Init = { 1, 3, 1, 5, 11, 1, 75, 63, 367, 523, 291, 1429, 5509, 8641, 6847, 0 }; + static ulong[] dim2302Kuo2Init = { 1, 1, 7, 13, 5, 59, 69, 81, 359, 905, 723, 3449, 3961, 16231, 19789, 0 }; + static ulong[] dim2303Kuo2Init = { 1, 1, 7, 7, 13, 53, 119, 129, 87, 325, 415, 3313, 6045, 5293, 21325, 0 }; + static ulong[] dim2304Kuo2Init = { 1, 1, 3, 3, 3, 45, 73, 109, 337, 185, 781, 3277, 2575, 15999, 8309, 0 }; + static ulong[] dim2305Kuo2Init = { 1, 1, 3, 15, 15, 59, 35, 77, 441, 635, 627, 183, 4599, 8749, 24149, 0 }; + static ulong[] dim2306Kuo2Init = { 1, 3, 3, 7, 23, 51, 31, 23, 367, 473, 27, 1021, 2587, 3063, 32563, 0 }; + static ulong[] dim2307Kuo2Init = { 1, 1, 7, 5, 9, 57, 45, 147, 95, 233, 1349, 1497, 7103, 4049, 905, 0 }; + static ulong[] dim2308Kuo2Init = { 1, 1, 7, 9, 9, 21, 89, 59, 379, 467, 1619, 809, 3947, 1715, 9841, 0 }; + static ulong[] dim2309Kuo2Init = { 1, 3, 5, 9, 23, 41, 43, 213, 429, 825, 279, 1117, 659, 13157, 3977, 0 }; + static ulong[] dim2310Kuo2Init = { 1, 1, 3, 15, 1, 57, 79, 87, 285, 693, 1947, 3417, 4241, 8595, 18075, 0 }; + static ulong[] dim2311Kuo2Init = { 1, 1, 1, 1, 11, 19, 9, 79, 407, 475, 655, 2925, 2919, 6343, 19637, 0 }; + static ulong[] dim2312Kuo2Init = { 1, 3, 3, 13, 1, 41, 107, 185, 29, 169, 915, 3535, 3543, 8015, 7097, 0 }; + static ulong[] dim2313Kuo2Init = { 1, 1, 3, 11, 29, 1, 25, 199, 129, 471, 1335, 3413, 7373, 9881, 32595, 0 }; + static ulong[] dim2314Kuo2Init = { 1, 3, 3, 1, 25, 13, 95, 23, 145, 775, 1873, 2347, 323, 10021, 20551, 0 }; + static ulong[] dim2315Kuo2Init = { 1, 3, 3, 15, 3, 35, 25, 79, 279, 251, 245, 2917, 1147, 9525, 9473, 0 }; + static ulong[] dim2316Kuo2Init = { 1, 3, 3, 11, 25, 35, 115, 13, 191, 447, 1041, 3437, 5941, 903, 26727, 0 }; + static ulong[] dim2317Kuo2Init = { 1, 3, 5, 15, 27, 49, 29, 169, 167, 685, 931, 1705, 4513, 16217, 8545, 0 }; + static ulong[] dim2318Kuo2Init = { 1, 3, 5, 3, 5, 55, 55, 113, 129, 491, 1583, 2103, 2233, 12669, 2809, 0 }; + static ulong[] dim2319Kuo2Init = { 1, 1, 1, 7, 7, 57, 47, 43, 91, 415, 1903, 1067, 4281, 16095, 19919, 0 }; + static ulong[] dim2320Kuo2Init = { 1, 3, 7, 7, 29, 7, 65, 19, 119, 473, 493, 2861, 7765, 15057, 13809, 0 }; + static ulong[] dim2321Kuo2Init = { 1, 1, 5, 9, 3, 49, 83, 73, 135, 971, 1233, 3623, 7351, 15255, 29921, 0 }; + static ulong[] dim2322Kuo2Init = { 1, 3, 3, 11, 29, 53, 5, 57, 41, 215, 477, 1851, 2219, 16289, 23801, 0 }; + static ulong[] dim2323Kuo2Init = { 1, 1, 3, 7, 9, 29, 55, 37, 415, 537, 1459, 431, 4559, 5569, 2031, 0 }; + static ulong[] dim2324Kuo2Init = { 1, 1, 5, 1, 5, 15, 47, 159, 369, 677, 691, 2647, 6243, 15909, 17725, 0 }; + static ulong[] dim2325Kuo2Init = { 1, 1, 5, 9, 13, 43, 45, 167, 503, 939, 1609, 1123, 2799, 3903, 27007, 0 }; + static ulong[] dim2326Kuo2Init = { 1, 3, 1, 13, 19, 43, 95, 247, 475, 193, 1513, 885, 5391, 7041, 13473, 0 }; + static ulong[] dim2327Kuo2Init = { 1, 1, 7, 13, 25, 61, 3, 237, 473, 671, 101, 1129, 787, 14697, 909, 0 }; + static ulong[] dim2328Kuo2Init = { 1, 1, 7, 15, 25, 3, 53, 81, 147, 27, 1691, 2093, 2627, 9523, 16021, 0 }; + static ulong[] dim2329Kuo2Init = { 1, 1, 7, 15, 11, 17, 35, 39, 187, 119, 541, 485, 3997, 16067, 12707, 0 }; + static ulong[] dim2330Kuo2Init = { 1, 3, 7, 9, 17, 5, 57, 31, 75, 637, 1521, 3435, 387, 9325, 8165, 0 }; + static ulong[] dim2331Kuo2Init = { 1, 1, 7, 3, 17, 33, 65, 55, 193, 55, 777, 151, 7605, 6927, 22731, 0 }; + static ulong[] dim2332Kuo2Init = { 1, 1, 3, 15, 9, 21, 33, 29, 395, 179, 445, 895, 203, 14665, 28945, 0 }; + static ulong[] dim2333Kuo2Init = { 1, 3, 3, 11, 25, 63, 35, 51, 261, 83, 1227, 2897, 8157, 11703, 21067, 0 }; + static ulong[] dim2334Kuo2Init = { 1, 1, 5, 11, 15, 59, 1, 115, 225, 427, 397, 2113, 8117, 9387, 15817, 0 }; + static ulong[] dim2335Kuo2Init = { 1, 1, 5, 3, 25, 23, 15, 3, 227, 341, 449, 217, 3583, 5617, 5215, 0 }; + static ulong[] dim2336Kuo2Init = { 1, 3, 1, 9, 15, 61, 29, 241, 245, 857, 217, 1253, 2643, 435, 11991, 0 }; + static ulong[] dim2337Kuo2Init = { 1, 1, 7, 7, 27, 17, 89, 123, 121, 97, 1749, 3341, 2279, 1067, 28845, 0 }; + static ulong[] dim2338Kuo2Init = { 1, 1, 1, 13, 17, 21, 27, 153, 135, 831, 361, 3487, 7221, 9343, 26523, 0 }; + static ulong[] dim2339Kuo2Init = { 1, 1, 7, 15, 11, 59, 115, 103, 425, 221, 1485, 3471, 773, 14989, 1193, 0 }; + static ulong[] dim2340Kuo2Init = { 1, 1, 7, 11, 1, 19, 113, 115, 149, 429, 1695, 409, 2343, 11843, 16319, 0 }; + static ulong[] dim2341Kuo2Init = { 1, 1, 1, 9, 29, 5, 37, 29, 197, 331, 2033, 1319, 5667, 1311, 3563, 0 }; + static ulong[] dim2342Kuo2Init = { 1, 1, 1, 11, 13, 7, 73, 25, 391, 245, 1447, 4001, 7059, 3091, 27423, 0 }; + static ulong[] dim2343Kuo2Init = { 1, 1, 5, 13, 21, 1, 125, 201, 103, 349, 1123, 2067, 7007, 12927, 27169, 0 }; + static ulong[] dim2344Kuo2Init = { 1, 3, 3, 5, 25, 49, 73, 31, 55, 659, 1407, 3433, 6513, 151, 18409, 0 }; + static ulong[] dim2345Kuo2Init = { 1, 1, 5, 13, 5, 19, 57, 73, 197, 69, 1477, 2763, 5691, 6639, 23613, 0 }; + static ulong[] dim2346Kuo2Init = { 1, 3, 5, 5, 17, 47, 49, 77, 275, 341, 2017, 3257, 111, 925, 549, 0 }; + static ulong[] dim2347Kuo2Init = { 1, 1, 7, 9, 29, 7, 27, 195, 411, 435, 1689, 1537, 3381, 11521, 4505, 0 }; + static ulong[] dim2348Kuo2Init = { 1, 1, 1, 15, 13, 23, 97, 189, 285, 351, 1371, 3161, 2337, 5239, 31675, 0 }; + static ulong[] dim2349Kuo2Init = { 1, 1, 5, 3, 27, 57, 105, 197, 423, 109, 1967, 3363, 1925, 14261, 13569, 0 }; + static ulong[] dim2350Kuo2Init = { 1, 1, 3, 15, 21, 15, 7, 45, 411, 905, 1323, 3225, 5867, 2281, 13213, 0 }; + static ulong[] dim2351Kuo2Init = { 1, 3, 7, 9, 29, 51, 41, 97, 393, 381, 1765, 1159, 965, 6013, 12541, 0 }; + static ulong[] dim2352Kuo2Init = { 1, 1, 7, 5, 13, 35, 107, 231, 135, 745, 259, 2999, 1291, 14025, 2065, 0 }; + static ulong[] dim2353Kuo2Init = { 1, 3, 5, 13, 13, 29, 65, 91, 101, 469, 1337, 2717, 1781, 10019, 23097, 0 }; + static ulong[] dim2354Kuo2Init = { 1, 3, 3, 9, 3, 11, 23, 253, 175, 35, 1651, 3713, 3575, 4837, 10385, 0 }; + static ulong[] dim2355Kuo2Init = { 1, 3, 1, 11, 13, 57, 33, 39, 55, 717, 679, 2417, 3665, 7753, 27659, 0 }; + static ulong[] dim2356Kuo2Init = { 1, 3, 1, 15, 25, 9, 93, 205, 369, 567, 1525, 3797, 6047, 407, 2155, 0 }; + static ulong[] dim2357Kuo2Init = { 1, 3, 7, 3, 5, 47, 15, 227, 325, 837, 1849, 3577, 1427, 5629, 17023, 0 }; + static ulong[] dim2358Kuo2Init = { 1, 3, 5, 7, 17, 23, 43, 231, 23, 95, 423, 2225, 8051, 6775, 4087, 0 }; + static ulong[] dim2359Kuo2Init = { 1, 1, 3, 15, 11, 45, 87, 213, 187, 159, 377, 3269, 2393, 7587, 8027, 0 }; + static ulong[] dim2360Kuo2Init = { 1, 1, 5, 3, 5, 25, 115, 19, 229, 13, 935, 3269, 3877, 8081, 20583, 0 }; + static ulong[] dim2361Kuo2Init = { 1, 3, 3, 15, 31, 47, 21, 179, 503, 43, 915, 2987, 323, 15843, 18869, 0 }; + static ulong[] dim2362Kuo2Init = { 1, 1, 7, 7, 25, 9, 27, 169, 431, 495, 65, 3999, 4363, 8677, 12049, 0 }; + static ulong[] dim2363Kuo2Init = { 1, 3, 5, 13, 17, 37, 123, 197, 185, 501, 1471, 149, 4649, 2337, 10279, 0 }; + static ulong[] dim2364Kuo2Init = { 1, 1, 7, 13, 11, 11, 3, 103, 43, 97, 349, 3515, 2621, 11587, 26495, 0 }; + static ulong[] dim2365Kuo2Init = { 1, 1, 1, 5, 3, 19, 99, 135, 355, 265, 1719, 2533, 4313, 11301, 18415, 0 }; + static ulong[] dim2366Kuo2Init = { 1, 3, 7, 9, 1, 55, 115, 251, 293, 903, 931, 3687, 5019, 14277, 589, 0 }; + static ulong[] dim2367Kuo2Init = { 1, 1, 3, 5, 31, 5, 123, 179, 51, 135, 9, 2779, 8143, 10033, 31473, 0 }; + static ulong[] dim2368Kuo2Init = { 1, 3, 1, 5, 3, 39, 87, 235, 289, 907, 1211, 453, 611, 4009, 25787, 0 }; + static ulong[] dim2369Kuo2Init = { 1, 3, 7, 9, 27, 7, 47, 123, 333, 713, 1349, 1345, 1641, 5935, 19127, 0 }; + static ulong[] dim2370Kuo2Init = { 1, 1, 5, 11, 13, 17, 47, 235, 329, 955, 1761, 1957, 3611, 9705, 20307, 0 }; + static ulong[] dim2371Kuo2Init = { 1, 1, 7, 15, 15, 59, 45, 17, 57, 871, 407, 943, 1881, 12929, 2181, 0 }; + static ulong[] dim2372Kuo2Init = { 1, 1, 7, 1, 7, 43, 41, 193, 29, 675, 1449, 2121, 1681, 13951, 21659, 0 }; + static ulong[] dim2373Kuo2Init = { 1, 1, 5, 3, 21, 53, 63, 75, 7, 793, 245, 349, 4801, 4057, 13269, 0 }; + static ulong[] dim2374Kuo2Init = { 1, 1, 3, 13, 23, 9, 109, 167, 165, 573, 685, 129, 1781, 10331, 9429, 0 }; + static ulong[] dim2375Kuo2Init = { 1, 3, 3, 15, 29, 43, 109, 25, 461, 991, 1509, 39, 6959, 13245, 18505, 0 }; + static ulong[] dim2376Kuo2Init = { 1, 3, 1, 7, 25, 43, 57, 61, 399, 787, 1479, 1613, 4295, 4189, 1371, 0 }; + static ulong[] dim2377Kuo2Init = { 1, 3, 3, 13, 27, 57, 49, 139, 189, 683, 115, 963, 5833, 3249, 28785, 0 }; + static ulong[] dim2378Kuo2Init = { 1, 3, 5, 1, 3, 29, 41, 49, 341, 299, 1195, 57, 5791, 4409, 17733, 0 }; + static ulong[] dim2379Kuo2Init = { 1, 1, 5, 7, 11, 21, 115, 145, 207, 41, 1531, 1897, 2627, 3653, 267, 0 }; + static ulong[] dim2380Kuo2Init = { 1, 3, 3, 9, 1, 3, 5, 79, 449, 281, 1711, 2863, 6267, 14863, 29957, 0 }; + static ulong[] dim2381Kuo2Init = { 1, 3, 1, 3, 15, 63, 127, 123, 457, 523, 1409, 2709, 4543, 13071, 17751, 0 }; + static ulong[] dim2382Kuo2Init = { 1, 3, 1, 3, 7, 61, 21, 139, 481, 747, 107, 1041, 359, 7683, 30327, 0 }; + static ulong[] dim2383Kuo2Init = { 1, 3, 3, 7, 3, 25, 7, 113, 39, 853, 1461, 2655, 2601, 7619, 2923, 0 }; + static ulong[] dim2384Kuo2Init = { 1, 3, 3, 1, 19, 25, 5, 27, 439, 407, 1281, 2487, 2275, 8793, 119, 0 }; + static ulong[] dim2385Kuo2Init = { 1, 3, 3, 1, 11, 37, 55, 131, 227, 79, 117, 2367, 1495, 15873, 24341, 0 }; + static ulong[] dim2386Kuo2Init = { 1, 3, 1, 1, 11, 21, 35, 167, 413, 645, 1139, 2535, 8167, 5937, 29047, 0 }; + static ulong[] dim2387Kuo2Init = { 1, 3, 7, 1, 5, 43, 31, 5, 419, 577, 1333, 1599, 3745, 10219, 27501, 0 }; + static ulong[] dim2388Kuo2Init = { 1, 3, 1, 13, 21, 35, 115, 105, 187, 567, 1303, 1637, 3681, 14089, 12705, 0 }; + static ulong[] dim2389Kuo2Init = { 1, 1, 3, 15, 19, 61, 65, 115, 395, 501, 1015, 2117, 7647, 3077, 15265, 0 }; + static ulong[] dim2390Kuo2Init = { 1, 3, 1, 1, 29, 11, 21, 177, 15, 193, 1177, 1225, 6251, 9983, 12599, 0 }; + static ulong[] dim2391Kuo2Init = { 1, 1, 1, 5, 5, 27, 27, 249, 197, 125, 571, 277, 4659, 14943, 19805, 0 }; + static ulong[] dim2392Kuo2Init = { 1, 3, 3, 7, 27, 37, 75, 235, 249, 191, 1123, 1355, 4249, 14971, 11349, 0 }; + static ulong[] dim2393Kuo2Init = { 1, 1, 5, 9, 31, 19, 7, 91, 87, 515, 293, 1289, 2495, 11311, 3939, 0 }; + static ulong[] dim2394Kuo2Init = { 1, 1, 5, 15, 15, 51, 43, 231, 401, 557, 689, 1103, 457, 3493, 22193, 0 }; + static ulong[] dim2395Kuo2Init = { 1, 3, 5, 9, 25, 39, 125, 91, 373, 331, 39, 35, 2397, 5043, 32061, 0 }; + static ulong[] dim2396Kuo2Init = { 1, 1, 3, 11, 13, 37, 61, 27, 349, 377, 1589, 3711, 6551, 4795, 5507, 0 }; + static ulong[] dim2397Kuo2Init = { 1, 3, 5, 7, 25, 49, 107, 189, 371, 363, 1011, 2133, 6923, 2441, 8295, 0 }; + static ulong[] dim2398Kuo2Init = { 1, 1, 3, 11, 3, 11, 27, 9, 193, 979, 867, 3085, 3783, 14851, 11565, 0 }; + static ulong[] dim2399Kuo2Init = { 1, 1, 3, 1, 1, 55, 17, 239, 351, 373, 939, 2115, 3697, 7881, 6603, 0 }; + static ulong[] dim2400Kuo2Init = { 1, 3, 1, 7, 23, 17, 81, 143, 497, 875, 939, 3193, 7023, 3327, 29327, 0 }; + static ulong[] dim2401Kuo2Init = { 1, 3, 7, 13, 27, 61, 1, 127, 369, 471, 1511, 2227, 565, 4121, 11155, 0 }; + static ulong[] dim2402Kuo2Init = { 1, 3, 3, 5, 5, 53, 77, 185, 11, 801, 1289, 975, 5191, 3733, 18489, 0 }; + static ulong[] dim2403Kuo2Init = { 1, 3, 1, 7, 19, 19, 67, 9, 121, 473, 377, 3771, 7561, 5751, 26295, 0 }; + static ulong[] dim2404Kuo2Init = { 1, 3, 1, 5, 19, 41, 7, 227, 465, 803, 1979, 281, 1337, 7973, 20341, 0 }; + static ulong[] dim2405Kuo2Init = { 1, 1, 1, 5, 9, 5, 123, 45, 65, 801, 373, 2093, 1473, 14503, 1401, 0 }; + static ulong[] dim2406Kuo2Init = { 1, 1, 3, 9, 29, 39, 123, 17, 253, 649, 1755, 4081, 3415, 8805, 28635, 0 }; + static ulong[] dim2407Kuo2Init = { 1, 3, 1, 1, 23, 7, 57, 163, 93, 829, 93, 1767, 1073, 14825, 21505, 0 }; + static ulong[] dim2408Kuo2Init = { 1, 1, 7, 13, 21, 59, 59, 229, 175, 485, 621, 3785, 4949, 12281, 14569, 0 }; + static ulong[] dim2409Kuo2Init = { 1, 3, 5, 13, 7, 51, 123, 221, 119, 61, 1271, 1857, 3505, 14413, 20975, 0 }; + static ulong[] dim2410Kuo2Init = { 1, 3, 7, 5, 17, 51, 67, 123, 121, 379, 605, 3361, 5557, 9127, 15251, 0 }; + static ulong[] dim2411Kuo2Init = { 1, 3, 7, 9, 27, 11, 33, 33, 439, 347, 1305, 11, 6839, 493, 771, 0 }; + static ulong[] dim2412Kuo2Init = { 1, 3, 5, 15, 5, 13, 7, 131, 129, 865, 1115, 2651, 1567, 783, 15073, 0 }; + static ulong[] dim2413Kuo2Init = { 1, 1, 3, 11, 11, 13, 95, 115, 361, 1009, 413, 2671, 6267, 5393, 18963, 0 }; + static ulong[] dim2414Kuo2Init = { 1, 3, 1, 9, 27, 11, 33, 183, 343, 113, 1323, 3197, 3889, 8533, 31493, 0 }; + static ulong[] dim2415Kuo2Init = { 1, 3, 3, 11, 11, 21, 93, 35, 177, 133, 539, 679, 6263, 8619, 2751, 0 }; + static ulong[] dim2416Kuo2Init = { 1, 1, 3, 1, 27, 31, 21, 157, 365, 635, 1279, 575, 2245, 11597, 3899, 0 }; + static ulong[] dim2417Kuo2Init = { 1, 3, 1, 5, 7, 45, 15, 237, 191, 541, 1631, 1459, 1973, 15333, 30419, 0 }; + static ulong[] dim2418Kuo2Init = { 1, 3, 1, 13, 3, 47, 103, 101, 423, 739, 947, 3225, 783, 14771, 20183, 0 }; + static ulong[] dim2419Kuo2Init = { 1, 3, 1, 5, 23, 19, 21, 245, 341, 907, 745, 1913, 1545, 7801, 9995, 0 }; + static ulong[] dim2420Kuo2Init = { 1, 3, 1, 3, 7, 47, 55, 15, 193, 123, 73, 427, 6415, 6611, 6317, 0 }; + static ulong[] dim2421Kuo2Init = { 1, 1, 1, 7, 3, 17, 27, 5, 295, 453, 1503, 2327, 4209, 3663, 16843, 0 }; + static ulong[] dim2422Kuo2Init = { 1, 1, 1, 3, 25, 19, 41, 161, 333, 153, 999, 1129, 103, 9471, 12707, 0 }; + static ulong[] dim2423Kuo2Init = { 1, 3, 3, 3, 21, 37, 73, 159, 179, 913, 691, 755, 3033, 1999, 15459, 0 }; + static ulong[] dim2424Kuo2Init = { 1, 1, 5, 13, 1, 3, 67, 131, 119, 769, 747, 1047, 6751, 2753, 22611, 0 }; + static ulong[] dim2425Kuo2Init = { 1, 3, 7, 5, 11, 1, 27, 81, 423, 691, 357, 3679, 2467, 15107, 13029, 0 }; + static ulong[] dim2426Kuo2Init = { 1, 3, 5, 9, 21, 21, 109, 69, 319, 283, 1831, 1403, 5531, 14461, 14057, 0 }; + static ulong[] dim2427Kuo2Init = { 1, 3, 7, 13, 21, 33, 77, 149, 495, 361, 401, 3313, 1849, 14009, 5933, 0 }; + static ulong[] dim2428Kuo2Init = { 1, 3, 7, 15, 11, 3, 33, 181, 21, 437, 1843, 3591, 589, 1721, 27495, 0 }; + static ulong[] dim2429Kuo2Init = { 1, 1, 1, 9, 25, 61, 103, 25, 71, 471, 219, 3623, 1517, 15471, 23179, 0 }; + static ulong[] dim2430Kuo2Init = { 1, 1, 7, 1, 7, 59, 99, 143, 387, 231, 241, 1215, 3785, 13543, 27469, 0 }; + static ulong[] dim2431Kuo2Init = { 1, 3, 1, 11, 25, 61, 93, 171, 421, 515, 1761, 1399, 7791, 291, 28455, 0 }; + static ulong[] dim2432Kuo2Init = { 1, 1, 3, 11, 1, 23, 117, 251, 467, 445, 737, 2637, 4183, 8561, 24977, 0 }; + static ulong[] dim2433Kuo2Init = { 1, 3, 5, 11, 11, 35, 111, 209, 415, 485, 1609, 1113, 3329, 15365, 1999, 0 }; + static ulong[] dim2434Kuo2Init = { 1, 1, 3, 15, 19, 17, 43, 67, 191, 711, 395, 921, 2511, 8417, 4071, 0 }; + static ulong[] dim2435Kuo2Init = { 1, 3, 3, 11, 9, 5, 89, 115, 451, 533, 1057, 1835, 2137, 9253, 19217, 0 }; + static ulong[] dim2436Kuo2Init = { 1, 3, 7, 11, 9, 45, 119, 89, 485, 109, 1755, 709, 7729, 14659, 19203, 0 }; + static ulong[] dim2437Kuo2Init = { 1, 1, 3, 7, 11, 7, 107, 113, 305, 431, 481, 2965, 6195, 2369, 14843, 0 }; + static ulong[] dim2438Kuo2Init = { 1, 3, 1, 13, 5, 37, 11, 193, 135, 697, 665, 3085, 4691, 3799, 11915, 0 }; + static ulong[] dim2439Kuo2Init = { 1, 1, 1, 9, 1, 47, 23, 143, 255, 93, 615, 2039, 6591, 14479, 24963, 0 }; + static ulong[] dim2440Kuo2Init = { 1, 3, 3, 11, 15, 11, 75, 57, 151, 29, 1073, 2763, 5613, 15703, 2447, 0 }; + static ulong[] dim2441Kuo2Init = { 1, 1, 5, 9, 19, 15, 79, 113, 359, 997, 1799, 695, 7075, 10091, 15271, 0 }; + static ulong[] dim2442Kuo2Init = { 1, 3, 5, 9, 3, 63, 45, 253, 257, 739, 1759, 317, 1955, 1283, 11127, 0 }; + static ulong[] dim2443Kuo2Init = { 1, 3, 5, 13, 29, 37, 67, 177, 203, 497, 947, 2339, 2401, 9199, 22331, 0 }; + static ulong[] dim2444Kuo2Init = { 1, 1, 1, 5, 23, 15, 67, 131, 213, 21, 1167, 1729, 3297, 337, 12253, 0 }; + static ulong[] dim2445Kuo2Init = { 1, 3, 3, 11, 21, 7, 69, 79, 297, 401, 1491, 1655, 2525, 4871, 17919, 0 }; + static ulong[] dim2446Kuo2Init = { 1, 3, 5, 15, 5, 15, 113, 45, 205, 317, 109, 2793, 4975, 5563, 3649, 0 }; + static ulong[] dim2447Kuo2Init = { 1, 3, 3, 7, 13, 59, 17, 63, 311, 161, 419, 1693, 2937, 8671, 24741, 0 }; + static ulong[] dim2448Kuo2Init = { 1, 1, 5, 3, 17, 21, 103, 105, 117, 211, 941, 385, 6455, 9069, 10147, 0 }; + static ulong[] dim2449Kuo2Init = { 1, 3, 5, 7, 5, 13, 43, 155, 89, 747, 359, 219, 6597, 5175, 24585, 0 }; + static ulong[] dim2450Kuo2Init = { 1, 3, 5, 13, 7, 45, 17, 169, 421, 161, 207, 2033, 4805, 2737, 7799, 0 }; + static ulong[] dim2451Kuo2Init = { 1, 1, 7, 9, 15, 55, 55, 219, 441, 409, 443, 3363, 6895, 16339, 16091, 0 }; + static ulong[] dim2452Kuo2Init = { 1, 1, 3, 5, 3, 23, 17, 217, 93, 799, 1419, 3405, 7911, 15609, 25461, 0 }; + static ulong[] dim2453Kuo2Init = { 1, 1, 1, 5, 29, 19, 17, 97, 319, 743, 1773, 2513, 2395, 1885, 6835, 0 }; + static ulong[] dim2454Kuo2Init = { 1, 3, 3, 3, 25, 41, 79, 191, 175, 319, 1903, 2281, 5709, 2817, 14213, 0 }; + static ulong[] dim2455Kuo2Init = { 1, 3, 5, 9, 21, 55, 9, 51, 223, 519, 225, 2543, 4183, 283, 599, 0 }; + static ulong[] dim2456Kuo2Init = { 1, 1, 1, 15, 23, 39, 21, 171, 167, 739, 1779, 3469, 8121, 7013, 23445, 0 }; + static ulong[] dim2457Kuo2Init = { 1, 3, 3, 9, 9, 5, 55, 253, 43, 397, 927, 237, 4459, 12817, 29563, 0 }; + static ulong[] dim2458Kuo2Init = { 1, 3, 7, 3, 3, 57, 113, 221, 391, 365, 311, 1027, 3369, 7637, 25765, 0 }; + static ulong[] dim2459Kuo2Init = { 1, 3, 3, 1, 19, 3, 91, 161, 421, 961, 1237, 4063, 2573, 483, 3375, 0 }; + static ulong[] dim2460Kuo2Init = { 1, 1, 1, 5, 19, 35, 119, 211, 489, 649, 1233, 447, 3727, 15541, 4769, 0 }; + static ulong[] dim2461Kuo2Init = { 1, 3, 7, 15, 7, 1, 15, 103, 81, 59, 1953, 3729, 6451, 15051, 17421, 0 }; + static ulong[] dim2462Kuo2Init = { 1, 1, 3, 11, 11, 41, 73, 63, 485, 47, 585, 3503, 4787, 12445, 8513, 0 }; + static ulong[] dim2463Kuo2Init = { 1, 1, 5, 1, 29, 35, 37, 99, 443, 171, 1455, 1705, 5587, 8791, 6269, 0 }; + static ulong[] dim2464Kuo2Init = { 1, 3, 3, 9, 19, 23, 103, 19, 307, 615, 2037, 3289, 1453, 12955, 28069, 0 }; + static ulong[] dim2465Kuo2Init = { 1, 3, 7, 5, 21, 57, 89, 29, 419, 681, 1413, 3375, 7341, 14825, 18251, 0 }; + static ulong[] dim2466Kuo2Init = { 1, 3, 5, 11, 21, 49, 67, 69, 47, 33, 449, 1831, 1125, 1011, 16223, 0 }; + static ulong[] dim2467Kuo2Init = { 1, 1, 3, 5, 17, 11, 67, 237, 299, 843, 1177, 1825, 1109, 12157, 9347, 0 }; + static ulong[] dim2468Kuo2Init = { 1, 3, 3, 9, 21, 63, 47, 239, 219, 319, 1505, 393, 143, 5009, 9017, 0 }; + static ulong[] dim2469Kuo2Init = { 1, 3, 5, 11, 1, 25, 21, 1, 15, 947, 1533, 1201, 3929, 7943, 9335, 0 }; + static ulong[] dim2470Kuo2Init = { 1, 1, 1, 15, 29, 45, 29, 119, 419, 793, 345, 789, 6415, 5481, 31111, 0 }; + static ulong[] dim2471Kuo2Init = { 1, 1, 1, 1, 19, 59, 3, 199, 247, 905, 1347, 4021, 1913, 15315, 15265, 0 }; + static ulong[] dim2472Kuo2Init = { 1, 3, 3, 7, 23, 63, 1, 87, 455, 1013, 789, 603, 7027, 11527, 17571, 0 }; + static ulong[] dim2473Kuo2Init = { 1, 3, 3, 15, 13, 27, 95, 61, 343, 201, 997, 2153, 3239, 2475, 9827, 0 }; + static ulong[] dim2474Kuo2Init = { 1, 3, 3, 1, 29, 49, 77, 245, 167, 873, 1467, 2475, 3951, 10253, 8345, 0 }; + static ulong[] dim2475Kuo2Init = { 1, 1, 1, 15, 5, 41, 71, 81, 491, 971, 1955, 1901, 4383, 13961, 3745, 0 }; + static ulong[] dim2476Kuo2Init = { 1, 1, 1, 7, 21, 31, 11, 247, 47, 251, 509, 739, 2745, 14531, 19633, 0 }; + static ulong[] dim2477Kuo2Init = { 1, 1, 7, 13, 31, 47, 105, 167, 443, 623, 503, 3283, 1935, 2627, 19807, 0 }; + static ulong[] dim2478Kuo2Init = { 1, 1, 7, 3, 21, 9, 67, 39, 263, 395, 407, 3813, 5033, 14647, 11963, 0 }; + static ulong[] dim2479Kuo2Init = { 1, 1, 1, 9, 3, 29, 9, 101, 313, 861, 529, 1171, 7943, 13701, 16497, 0 }; + static ulong[] dim2480Kuo2Init = { 1, 1, 5, 15, 9, 3, 29, 53, 379, 721, 1777, 2767, 7591, 8923, 16909, 0 }; + static ulong[] dim2481Kuo2Init = { 1, 1, 3, 9, 19, 7, 103, 189, 325, 995, 1419, 333, 4053, 10441, 1287, 0 }; + static ulong[] dim2482Kuo2Init = { 1, 1, 7, 1, 1, 1, 53, 31, 425, 477, 695, 389, 6523, 7565, 95, 0 }; + static ulong[] dim2483Kuo2Init = { 1, 1, 7, 15, 1, 5, 75, 211, 487, 641, 287, 3709, 2257, 12017, 31921, 0 }; + static ulong[] dim2484Kuo2Init = { 1, 3, 5, 7, 31, 7, 33, 177, 349, 257, 1383, 303, 469, 10941, 16211, 0 }; + static ulong[] dim2485Kuo2Init = { 1, 1, 5, 1, 7, 21, 89, 229, 237, 447, 1805, 3271, 7073, 3401, 7143, 0 }; + static ulong[] dim2486Kuo2Init = { 1, 3, 1, 7, 11, 35, 127, 139, 497, 629, 543, 77, 2505, 8781, 30445, 0 }; + static ulong[] dim2487Kuo2Init = { 1, 1, 7, 13, 1, 27, 59, 125, 399, 37, 597, 431, 4531, 7525, 2629, 0 }; + static ulong[] dim2488Kuo2Init = { 1, 3, 3, 1, 25, 27, 75, 221, 269, 587, 669, 1807, 5437, 12715, 22419, 0 }; + static ulong[] dim2489Kuo2Init = { 1, 1, 5, 7, 31, 29, 7, 135, 493, 1011, 1273, 3899, 6069, 9657, 21375, 0 }; + static ulong[] dim2490Kuo2Init = { 1, 3, 5, 7, 3, 13, 123, 39, 37, 397, 1023, 2733, 2275, 8415, 12011, 0 }; + static ulong[] dim2491Kuo2Init = { 1, 1, 5, 3, 1, 63, 115, 191, 159, 283, 7, 1073, 5609, 13113, 1755, 0 }; + static ulong[] dim2492Kuo2Init = { 1, 1, 3, 5, 11, 35, 83, 91, 315, 823, 1961, 1023, 4191, 1013, 24451, 0 }; + static ulong[] dim2493Kuo2Init = { 1, 1, 3, 15, 31, 13, 121, 213, 289, 763, 297, 3405, 4987, 13713, 16853, 0 }; + static ulong[] dim2494Kuo2Init = { 1, 3, 1, 3, 9, 57, 53, 171, 203, 71, 1973, 3555, 5079, 16173, 6399, 0 }; + static ulong[] dim2495Kuo2Init = { 1, 1, 3, 7, 21, 51, 105, 237, 491, 465, 597, 3055, 1657, 131, 19281, 0 }; + static ulong[] dim2496Kuo2Init = { 1, 1, 7, 15, 15, 41, 1, 61, 3, 879, 1985, 651, 3945, 6979, 793, 0 }; + static ulong[] dim2497Kuo2Init = { 1, 1, 1, 3, 15, 45, 51, 23, 1, 265, 1345, 3967, 1419, 247, 9225, 0 }; + static ulong[] dim2498Kuo2Init = { 1, 1, 5, 5, 19, 31, 107, 73, 331, 135, 1645, 3465, 6809, 12793, 15589, 0 }; + static ulong[] dim2499Kuo2Init = { 1, 1, 1, 1, 29, 47, 103, 133, 15, 113, 717, 891, 1967, 6063, 24975, 0 }; + static ulong[] dim2500Kuo2Init = { 1, 1, 3, 1, 17, 39, 3, 103, 373, 379, 267, 131, 473, 10475, 18595, 0 }; + static ulong[] dim2501Kuo2Init = { 1, 1, 3, 3, 27, 51, 17, 227, 425, 29, 969, 1515, 7045, 5869, 2031, 0 }; + static ulong[] dim2502Kuo2Init = { 1, 3, 7, 5, 17, 59, 69, 21, 119, 359, 1805, 1225, 1969, 14601, 7175, 0 }; + static ulong[] dim2503Kuo2Init = { 1, 3, 7, 9, 5, 23, 89, 89, 269, 159, 2017, 269, 4247, 14369, 4413, 0 }; + static ulong[] dim2504Kuo2Init = { 1, 1, 7, 1, 19, 35, 67, 243, 71, 653, 1673, 647, 1171, 16167, 15223, 0 }; + static ulong[] dim2505Kuo2Init = { 1, 1, 7, 7, 19, 37, 27, 69, 253, 233, 933, 649, 5449, 10651, 24709, 0 }; + static ulong[] dim2506Kuo2Init = { 1, 1, 5, 15, 13, 39, 113, 253, 351, 281, 309, 2351, 2225, 14121, 24059, 0 }; + static ulong[] dim2507Kuo2Init = { 1, 3, 1, 9, 13, 43, 115, 137, 107, 921, 37, 1743, 183, 5037, 4649, 0 }; + static ulong[] dim2508Kuo2Init = { 1, 1, 5, 15, 23, 11, 121, 161, 337, 155, 1053, 2907, 1163, 12929, 9065, 0 }; + static ulong[] dim2509Kuo2Init = { 1, 1, 3, 1, 1, 23, 85, 253, 245, 359, 1881, 581, 381, 15877, 15781, 0 }; + static ulong[] dim2510Kuo2Init = { 1, 3, 5, 11, 17, 49, 33, 133, 247, 339, 969, 3347, 1791, 16115, 10821, 0 }; + static ulong[] dim2511Kuo2Init = { 1, 3, 1, 9, 31, 41, 31, 103, 79, 339, 1311, 2609, 7455, 4543, 14765, 0 }; + static ulong[] dim2512Kuo2Init = { 1, 3, 7, 13, 13, 25, 75, 219, 443, 543, 9, 1101, 6833, 2091, 20729, 0 }; + static ulong[] dim2513Kuo2Init = { 1, 1, 3, 9, 3, 51, 125, 137, 107, 123, 1113, 3735, 655, 6897, 32047, 0 }; + static ulong[] dim2514Kuo2Init = { 1, 1, 3, 1, 17, 49, 31, 87, 399, 405, 1497, 1199, 6135, 6889, 23913, 0 }; + static ulong[] dim2515Kuo2Init = { 1, 1, 1, 13, 17, 59, 87, 153, 183, 539, 1231, 569, 1877, 11605, 9301, 0 }; + static ulong[] dim2516Kuo2Init = { 1, 3, 1, 9, 15, 57, 41, 247, 107, 1019, 1423, 49, 3093, 1667, 28241, 0 }; + static ulong[] dim2517Kuo2Init = { 1, 1, 1, 1, 19, 9, 41, 79, 383, 83, 1091, 457, 7245, 3639, 24411, 0 }; + static ulong[] dim2518Kuo2Init = { 1, 3, 7, 11, 31, 23, 71, 157, 327, 973, 39, 1303, 3519, 6071, 19297, 0 }; + static ulong[] dim2519Kuo2Init = { 1, 1, 7, 13, 27, 17, 105, 245, 83, 825, 33, 2331, 6469, 5547, 5409, 0 }; + static ulong[] dim2520Kuo2Init = { 1, 3, 1, 9, 21, 1, 105, 161, 269, 767, 2039, 941, 5063, 2763, 31333, 0 }; + static ulong[] dim2521Kuo2Init = { 1, 3, 1, 1, 17, 33, 37, 185, 505, 979, 239, 3001, 1441, 7803, 23377, 0 }; + static ulong[] dim2522Kuo2Init = { 1, 1, 3, 3, 23, 5, 63, 249, 409, 501, 1177, 655, 5109, 309, 3791, 0 }; + static ulong[] dim2523Kuo2Init = { 1, 1, 5, 1, 11, 37, 67, 5, 399, 479, 1119, 295, 2343, 11141, 28209, 0 }; + static ulong[] dim2524Kuo2Init = { 1, 1, 5, 11, 3, 17, 75, 93, 69, 957, 1851, 2297, 6757, 9401, 15847, 0 }; + static ulong[] dim2525Kuo2Init = { 1, 1, 3, 9, 5, 39, 75, 143, 235, 411, 1309, 1327, 863, 5579, 5153, 0 }; + static ulong[] dim2526Kuo2Init = { 1, 1, 7, 13, 23, 3, 39, 7, 257, 941, 1441, 2931, 1651, 4669, 16193, 0 }; + static ulong[] dim2527Kuo2Init = { 1, 1, 1, 15, 27, 43, 51, 197, 369, 531, 397, 387, 3021, 8885, 21943, 0 }; + static ulong[] dim2528Kuo2Init = { 1, 1, 5, 11, 25, 49, 9, 227, 501, 687, 131, 2899, 7175, 11359, 19997, 0 }; + static ulong[] dim2529Kuo2Init = { 1, 3, 3, 9, 23, 1, 51, 53, 437, 331, 1503, 3345, 5909, 439, 4771, 0 }; + static ulong[] dim2530Kuo2Init = { 1, 3, 1, 7, 13, 13, 101, 71, 345, 675, 653, 2297, 1099, 11115, 28917, 0 }; + static ulong[] dim2531Kuo2Init = { 1, 1, 3, 5, 5, 23, 69, 155, 133, 527, 1443, 1099, 2395, 2213, 16533, 0 }; + static ulong[] dim2532Kuo2Init = { 1, 1, 7, 7, 9, 37, 75, 17, 397, 919, 1223, 491, 4719, 3915, 30101, 0 }; + static ulong[] dim2533Kuo2Init = { 1, 3, 1, 7, 7, 51, 105, 31, 5, 149, 1275, 1381, 1963, 14737, 30975, 0 }; + static ulong[] dim2534Kuo2Init = { 1, 1, 7, 5, 1, 51, 49, 21, 371, 293, 159, 3681, 7979, 15611, 255, 0 }; + static ulong[] dim2535Kuo2Init = { 1, 1, 1, 7, 27, 53, 51, 135, 181, 419, 757, 2913, 941, 5863, 19619, 0 }; + static ulong[] dim2536Kuo2Init = { 1, 1, 7, 5, 19, 1, 115, 113, 29, 355, 1203, 279, 7967, 12419, 1003, 0 }; + static ulong[] dim2537Kuo2Init = { 1, 1, 1, 11, 1, 63, 109, 215, 285, 801, 1995, 3771, 4113, 11973, 16507, 0 }; + static ulong[] dim2538Kuo2Init = { 1, 3, 3, 9, 19, 55, 107, 139, 95, 139, 1595, 929, 7023, 15245, 30163, 0 }; + static ulong[] dim2539Kuo2Init = { 1, 1, 1, 13, 19, 1, 33, 23, 325, 245, 1671, 3065, 6767, 13583, 4683, 0 }; + static ulong[] dim2540Kuo2Init = { 1, 1, 7, 5, 17, 55, 33, 235, 119, 715, 83, 1089, 5943, 11897, 13259, 0 }; + static ulong[] dim2541Kuo2Init = { 1, 3, 7, 5, 25, 27, 111, 225, 99, 917, 731, 2617, 7915, 7283, 357, 0 }; + static ulong[] dim2542Kuo2Init = { 1, 3, 1, 3, 13, 9, 127, 251, 189, 573, 1897, 2147, 2641, 13191, 3847, 0 }; + static ulong[] dim2543Kuo2Init = { 1, 3, 7, 1, 19, 49, 49, 231, 321, 67, 1067, 2267, 7873, 2825, 445, 0 }; + static ulong[] dim2544Kuo2Init = { 1, 3, 7, 5, 27, 55, 23, 155, 103, 969, 1929, 2171, 5601, 1267, 31897, 0 }; + static ulong[] dim2545Kuo2Init = { 1, 3, 3, 7, 3, 27, 107, 7, 61, 601, 1957, 4075, 2955, 7717, 10473, 0 }; + static ulong[] dim2546Kuo2Init = { 1, 3, 5, 13, 31, 25, 111, 11, 391, 727, 243, 1471, 143, 16161, 5591, 0 }; + static ulong[] dim2547Kuo2Init = { 1, 1, 1, 11, 11, 43, 117, 117, 173, 933, 163, 1571, 1901, 3201, 1151, 0 }; + static ulong[] dim2548Kuo2Init = { 1, 3, 5, 3, 17, 13, 47, 217, 351, 777, 607, 401, 3485, 8679, 20357, 0 }; + static ulong[] dim2549Kuo2Init = { 1, 1, 7, 15, 5, 13, 37, 7, 469, 413, 1343, 947, 5883, 6125, 14803, 0 }; + static ulong[] dim2550Kuo2Init = { 1, 3, 1, 3, 1, 61, 7, 67, 229, 931, 1997, 3067, 3507, 11675, 31837, 0 }; + static ulong[] dim2551Kuo2Init = { 1, 1, 5, 1, 5, 35, 43, 65, 101, 75, 629, 1149, 625, 1865, 5215, 0 }; + static ulong[] dim2552Kuo2Init = { 1, 1, 7, 7, 17, 61, 47, 29, 277, 861, 1901, 35, 1405, 4393, 26899, 0 }; + static ulong[] dim2553Kuo2Init = { 1, 1, 5, 13, 13, 11, 21, 27, 473, 145, 867, 2781, 2865, 2793, 3265, 0 }; + static ulong[] dim2554Kuo2Init = { 1, 1, 7, 11, 11, 31, 41, 119, 243, 989, 2047, 1455, 8037, 11633, 31199, 0 }; + static ulong[] dim2555Kuo2Init = { 1, 1, 7, 5, 29, 19, 1, 89, 63, 41, 323, 2135, 2091, 15061, 29039, 0 }; + static ulong[] dim2556Kuo2Init = { 1, 3, 5, 15, 9, 53, 15, 191, 229, 487, 1287, 1163, 6985, 881, 4789, 0 }; + static ulong[] dim2557Kuo2Init = { 1, 1, 3, 9, 11, 57, 89, 205, 355, 551, 1643, 1565, 4181, 10805, 29359, 0 }; + static ulong[] dim2558Kuo2Init = { 1, 1, 7, 7, 31, 3, 103, 165, 37, 195, 245, 1225, 2811, 14785, 9307, 0 }; + static ulong[] dim2559Kuo2Init = { 1, 1, 7, 5, 19, 31, 47, 115, 361, 1019, 1517, 4079, 3717, 11301, 12051, 0 }; + static ulong[] dim2560Kuo2Init = { 1, 3, 5, 9, 31, 21, 57, 27, 353, 623, 1217, 3079, 5429, 8645, 10773, 0 }; + static ulong[] dim2561Kuo2Init = { 1, 1, 7, 7, 3, 11, 55, 209, 239, 509, 959, 2091, 123, 11365, 26593, 0 }; + static ulong[] dim2562Kuo2Init = { 1, 1, 5, 9, 7, 19, 51, 179, 103, 901, 1717, 1837, 4327, 9753, 24147, 0 }; + static ulong[] dim2563Kuo2Init = { 1, 1, 1, 5, 9, 63, 19, 103, 265, 893, 1519, 4063, 7951, 15601, 15019, 0 }; + static ulong[] dim2564Kuo2Init = { 1, 1, 3, 1, 19, 29, 15, 11, 235, 785, 77, 3957, 4829, 9903, 8483, 0 }; + static ulong[] dim2565Kuo2Init = { 1, 1, 3, 9, 27, 33, 25, 103, 387, 131, 1555, 301, 1471, 11331, 15091, 0 }; + static ulong[] dim2566Kuo2Init = { 1, 3, 3, 13, 25, 63, 75, 245, 189, 527, 1829, 1943, 407, 15219, 24453, 0 }; + static ulong[] dim2567Kuo2Init = { 1, 3, 1, 11, 29, 27, 35, 5, 215, 949, 97, 3843, 7911, 15947, 25037, 0 }; + static ulong[] dim2568Kuo2Init = { 1, 3, 3, 9, 29, 49, 43, 245, 257, 741, 1067, 2405, 3793, 3787, 22921, 0 }; + static ulong[] dim2569Kuo2Init = { 1, 1, 3, 15, 29, 29, 39, 25, 485, 257, 1003, 77, 1617, 5151, 29595, 0 }; + static ulong[] dim2570Kuo2Init = { 1, 1, 3, 5, 9, 39, 61, 59, 197, 501, 527, 3371, 1739, 5697, 11857, 0 }; + static ulong[] dim2571Kuo2Init = { 1, 1, 1, 15, 31, 27, 41, 91, 11, 373, 627, 361, 8001, 12231, 5715, 0 }; + static ulong[] dim2572Kuo2Init = { 1, 3, 3, 9, 31, 27, 67, 203, 95, 221, 1911, 1045, 1311, 11633, 5375, 0 }; + static ulong[] dim2573Kuo2Init = { 1, 1, 5, 15, 31, 49, 59, 185, 285, 173, 1351, 1665, 5941, 2075, 26087, 0 }; + static ulong[] dim2574Kuo2Init = { 1, 1, 7, 9, 23, 33, 95, 171, 71, 743, 11, 33, 1263, 1595, 18281, 0 }; + static ulong[] dim2575Kuo2Init = { 1, 1, 1, 7, 13, 59, 99, 245, 497, 951, 1195, 1503, 6069, 2293, 31661, 0 }; + static ulong[] dim2576Kuo2Init = { 1, 3, 5, 3, 3, 3, 29, 3, 197, 697, 105, 435, 4583, 5407, 32727, 0 }; + static ulong[] dim2577Kuo2Init = { 1, 3, 7, 1, 9, 41, 77, 199, 495, 999, 1791, 2183, 2819, 10771, 6957, 0 }; + static ulong[] dim2578Kuo2Init = { 1, 1, 7, 15, 27, 13, 51, 33, 243, 947, 835, 2251, 1751, 10319, 3269, 0 }; + static ulong[] dim2579Kuo2Init = { 1, 3, 5, 7, 17, 59, 125, 151, 113, 889, 21, 3839, 1475, 10643, 3291, 0 }; + static ulong[] dim2580Kuo2Init = { 1, 3, 7, 3, 27, 55, 101, 13, 177, 967, 35, 3081, 3559, 6539, 13557, 0 }; + static ulong[] dim2581Kuo2Init = { 1, 3, 5, 13, 27, 7, 107, 147, 455, 605, 1589, 2325, 6891, 10431, 18227, 0 }; + static ulong[] dim2582Kuo2Init = { 1, 1, 3, 3, 27, 13, 121, 249, 205, 359, 1909, 4011, 6833, 11583, 8705, 0 }; + static ulong[] dim2583Kuo2Init = { 1, 3, 5, 9, 21, 47, 77, 103, 173, 637, 1921, 991, 6471, 6053, 1963, 0 }; + static ulong[] dim2584Kuo2Init = { 1, 1, 3, 15, 11, 9, 71, 161, 253, 1, 973, 3079, 4887, 10045, 20467, 0 }; + static ulong[] dim2585Kuo2Init = { 1, 1, 5, 13, 27, 45, 11, 147, 79, 375, 533, 43, 7217, 9393, 20773, 0 }; + static ulong[] dim2586Kuo2Init = { 1, 1, 5, 3, 21, 47, 107, 83, 505, 463, 967, 3437, 3051, 11239, 20271, 0 }; + static ulong[] dim2587Kuo2Init = { 1, 1, 1, 15, 7, 9, 97, 143, 483, 393, 39, 447, 7779, 11037, 23283, 0 }; + static ulong[] dim2588Kuo2Init = { 1, 3, 1, 1, 31, 59, 85, 231, 209, 297, 353, 2577, 6209, 6691, 2941, 0 }; + static ulong[] dim2589Kuo2Init = { 1, 1, 7, 3, 19, 7, 81, 41, 419, 987, 1221, 2151, 5297, 1601, 1289, 0 }; + static ulong[] dim2590Kuo2Init = { 1, 3, 3, 13, 25, 13, 57, 199, 101, 157, 1273, 159, 5417, 5153, 30529, 0 }; + static ulong[] dim2591Kuo2Init = { 1, 1, 5, 1, 31, 41, 67, 71, 95, 929, 133, 3007, 6837, 7863, 23759, 0 }; + static ulong[] dim2592Kuo2Init = { 1, 1, 5, 3, 13, 59, 35, 11, 187, 251, 1119, 1517, 1433, 15475, 17981, 0 }; + static ulong[] dim2593Kuo2Init = { 1, 1, 3, 7, 5, 37, 11, 39, 111, 775, 761, 2853, 2283, 203, 22563, 0 }; + static ulong[] dim2594Kuo2Init = { 1, 1, 1, 11, 5, 45, 119, 81, 125, 481, 547, 3659, 5583, 6577, 17239, 0 }; + static ulong[] dim2595Kuo2Init = { 1, 3, 3, 13, 9, 25, 43, 103, 283, 637, 715, 3841, 5633, 503, 21933, 0 }; + static ulong[] dim2596Kuo2Init = { 1, 3, 1, 13, 21, 39, 1, 215, 235, 171, 1377, 2131, 2907, 11311, 11337, 0 }; + static ulong[] dim2597Kuo2Init = { 1, 3, 1, 3, 27, 19, 73, 83, 325, 451, 1779, 1665, 555, 7729, 26757, 0 }; + static ulong[] dim2598Kuo2Init = { 1, 3, 5, 13, 9, 29, 123, 177, 289, 553, 1323, 2531, 4071, 7395, 25847, 0 }; + static ulong[] dim2599Kuo2Init = { 1, 1, 7, 13, 1, 1, 29, 125, 253, 179, 1905, 821, 5329, 6181, 18445, 0 }; + static ulong[] dim2600Kuo2Init = { 1, 1, 1, 9, 15, 19, 59, 227, 63, 637, 1315, 2611, 1163, 6451, 8919, 0 }; + static ulong[] dim2601Kuo2Init = { 1, 1, 1, 5, 23, 39, 57, 143, 9, 811, 1101, 609, 1281, 9457, 14999, 0 }; + static ulong[] dim2602Kuo2Init = { 1, 3, 3, 7, 5, 31, 21, 31, 33, 271, 381, 1179, 4039, 14033, 19741, 0 }; + static ulong[] dim2603Kuo2Init = { 1, 3, 7, 15, 9, 41, 91, 247, 59, 201, 1837, 2609, 5481, 15479, 32253, 0 }; + static ulong[] dim2604Kuo2Init = { 1, 1, 3, 5, 15, 53, 7, 193, 451, 935, 701, 177, 7943, 5687, 15725, 0 }; + static ulong[] dim2605Kuo2Init = { 1, 3, 1, 13, 19, 9, 33, 173, 229, 993, 1637, 905, 5665, 9083, 10737, 0 }; + static ulong[] dim2606Kuo2Init = { 1, 1, 7, 9, 17, 33, 3, 145, 213, 317, 1135, 3281, 4169, 4601, 30347, 0 }; + static ulong[] dim2607Kuo2Init = { 1, 1, 1, 3, 23, 1, 49, 173, 351, 827, 937, 2423, 6443, 6413, 20383, 0 }; + static ulong[] dim2608Kuo2Init = { 1, 3, 5, 3, 21, 9, 7, 29, 293, 489, 339, 2403, 6303, 12283, 18047, 0 }; + static ulong[] dim2609Kuo2Init = { 1, 1, 7, 11, 23, 25, 49, 135, 389, 821, 17, 169, 4265, 5203, 3893, 0 }; + static ulong[] dim2610Kuo2Init = { 1, 1, 3, 3, 27, 63, 109, 165, 141, 129, 1441, 1443, 3991, 1639, 31461, 0 }; + static ulong[] dim2611Kuo2Init = { 1, 3, 7, 7, 25, 15, 85, 217, 223, 537, 1671, 2865, 4157, 8353, 18335, 0 }; + static ulong[] dim2612Kuo2Init = { 1, 3, 5, 11, 19, 19, 95, 159, 161, 599, 1059, 2065, 7159, 11273, 17501, 0 }; + static ulong[] dim2613Kuo2Init = { 1, 3, 7, 3, 15, 29, 5, 97, 95, 65, 1913, 1221, 329, 11601, 27033, 0 }; + static ulong[] dim2614Kuo2Init = { 1, 3, 3, 1, 25, 39, 103, 139, 379, 547, 1415, 4027, 559, 2101, 6133, 0 }; + static ulong[] dim2615Kuo2Init = { 1, 1, 7, 15, 21, 47, 115, 171, 17, 559, 1757, 745, 2573, 13969, 4193, 0 }; + static ulong[] dim2616Kuo2Init = { 1, 3, 3, 9, 19, 15, 37, 131, 199, 377, 67, 2455, 6807, 3365, 19697, 0 }; + static ulong[] dim2617Kuo2Init = { 1, 3, 5, 9, 25, 59, 9, 61, 369, 285, 231, 2911, 1817, 2125, 27637, 0 }; + static ulong[] dim2618Kuo2Init = { 1, 3, 1, 13, 25, 55, 61, 153, 507, 105, 149, 1589, 7167, 12363, 10257, 0 }; + static ulong[] dim2619Kuo2Init = { 1, 3, 1, 7, 9, 23, 109, 29, 167, 463, 101, 979, 3671, 10165, 12553, 0 }; + static ulong[] dim2620Kuo2Init = { 1, 3, 3, 9, 21, 49, 103, 217, 269, 761, 915, 3529, 125, 429, 24131, 0 }; + static ulong[] dim2621Kuo2Init = { 1, 3, 5, 15, 27, 61, 73, 13, 339, 1023, 967, 3883, 5515, 5893, 26183, 0 }; + static ulong[] dim2622Kuo2Init = { 1, 1, 1, 5, 5, 39, 87, 183, 141, 147, 779, 1733, 6137, 5985, 1335, 0 }; + static ulong[] dim2623Kuo2Init = { 1, 3, 5, 11, 23, 9, 61, 67, 235, 823, 1129, 401, 3049, 5593, 5193, 0 }; + static ulong[] dim2624Kuo2Init = { 1, 1, 3, 3, 27, 39, 27, 111, 81, 27, 283, 4081, 6511, 6785, 20953, 0 }; + static ulong[] dim2625Kuo2Init = { 1, 3, 7, 7, 17, 49, 93, 85, 327, 287, 1473, 3769, 2229, 12221, 27355, 0 }; + static ulong[] dim2626Kuo2Init = { 1, 3, 1, 3, 15, 15, 71, 105, 139, 137, 1139, 859, 7923, 581, 7697, 0 }; + static ulong[] dim2627Kuo2Init = { 1, 3, 7, 15, 29, 45, 17, 159, 233, 345, 1827, 2261, 6773, 5435, 17961, 0 }; + static ulong[] dim2628Kuo2Init = { 1, 3, 5, 13, 21, 15, 33, 229, 71, 709, 1757, 1479, 7289, 15629, 24041, 0 }; + static ulong[] dim2629Kuo2Init = { 1, 3, 3, 1, 27, 9, 103, 115, 137, 911, 603, 3615, 7671, 2439, 10041, 0 }; + static ulong[] dim2630Kuo2Init = { 1, 1, 5, 5, 21, 59, 67, 193, 249, 781, 761, 403, 6299, 527, 8533, 0 }; + static ulong[] dim2631Kuo2Init = { 1, 3, 3, 3, 5, 61, 71, 183, 151, 801, 1645, 2789, 5911, 11681, 5907, 0 }; + static ulong[] dim2632Kuo2Init = { 1, 1, 5, 7, 9, 19, 53, 239, 259, 273, 679, 2101, 1525, 2139, 30353, 0 }; + static ulong[] dim2633Kuo2Init = { 1, 1, 3, 1, 31, 25, 37, 225, 287, 31, 433, 2407, 1717, 6669, 10743, 0 }; + static ulong[] dim2634Kuo2Init = { 1, 3, 1, 13, 31, 13, 89, 225, 173, 723, 651, 3315, 6457, 9387, 7759, 0 }; + static ulong[] dim2635Kuo2Init = { 1, 1, 5, 7, 3, 25, 45, 79, 11, 843, 2031, 2827, 5029, 1359, 23489, 0 }; + static ulong[] dim2636Kuo2Init = { 1, 3, 5, 9, 7, 1, 53, 135, 327, 13, 1051, 2911, 5553, 6557, 16415, 0 }; + static ulong[] dim2637Kuo2Init = { 1, 1, 1, 5, 19, 19, 57, 147, 43, 503, 1899, 1709, 5589, 4251, 10871, 0 }; + static ulong[] dim2638Kuo2Init = { 1, 1, 5, 7, 1, 41, 83, 51, 89, 1015, 1441, 1735, 7217, 11431, 29623, 0 }; + static ulong[] dim2639Kuo2Init = { 1, 3, 7, 7, 29, 45, 73, 233, 399, 553, 961, 2053, 3537, 4015, 19963, 0 }; + static ulong[] dim2640Kuo2Init = { 1, 1, 5, 3, 21, 5, 1, 105, 341, 355, 849, 2235, 2801, 13749, 17933, 0 }; + static ulong[] dim2641Kuo2Init = { 1, 1, 7, 1, 25, 57, 29, 233, 485, 807, 1005, 1933, 3897, 1267, 30807, 0 }; + static ulong[] dim2642Kuo2Init = { 1, 1, 7, 15, 31, 53, 49, 31, 325, 335, 671, 1183, 2955, 3, 31739, 0 }; + static ulong[] dim2643Kuo2Init = { 1, 1, 5, 3, 17, 41, 19, 73, 215, 227, 1251, 907, 3303, 5343, 30385, 0 }; + static ulong[] dim2644Kuo2Init = { 1, 1, 1, 5, 15, 61, 123, 61, 27, 759, 645, 2571, 411, 13925, 29905, 0 }; + static ulong[] dim2645Kuo2Init = { 1, 3, 1, 5, 7, 55, 81, 241, 497, 1005, 1593, 2479, 25, 10627, 14043, 0 }; + static ulong[] dim2646Kuo2Init = { 1, 3, 3, 9, 19, 33, 87, 63, 441, 773, 1367, 2945, 4897, 14209, 6667, 0 }; + static ulong[] dim2647Kuo2Init = { 1, 1, 7, 15, 31, 59, 121, 153, 111, 329, 833, 2031, 4063, 13775, 9033, 0 }; + static ulong[] dim2648Kuo2Init = { 1, 3, 1, 11, 3, 33, 47, 65, 329, 149, 1509, 3617, 1381, 9003, 4953, 0 }; + static ulong[] dim2649Kuo2Init = { 1, 3, 1, 3, 7, 59, 39, 173, 157, 741, 343, 1039, 1695, 12077, 13203, 0 }; + static ulong[] dim2650Kuo2Init = { 1, 3, 7, 1, 17, 21, 21, 5, 65, 163, 711, 2251, 4761, 11895, 15571, 0 }; + static ulong[] dim2651Kuo2Init = { 1, 3, 7, 7, 7, 59, 31, 227, 283, 223, 163, 2639, 3037, 14423, 21507, 0 }; + static ulong[] dim2652Kuo2Init = { 1, 1, 1, 5, 9, 37, 5, 149, 395, 491, 711, 447, 5657, 443, 7183, 0 }; + static ulong[] dim2653Kuo2Init = { 1, 1, 5, 9, 17, 61, 31, 229, 207, 755, 199, 1585, 2771, 1499, 4911, 0 }; + static ulong[] dim2654Kuo2Init = { 1, 3, 5, 7, 1, 1, 53, 185, 407, 57, 525, 543, 5009, 1825, 8583, 0 }; + static ulong[] dim2655Kuo2Init = { 1, 1, 1, 3, 13, 49, 85, 175, 261, 653, 665, 3173, 4709, 11547, 14881, 0 }; + static ulong[] dim2656Kuo2Init = { 1, 1, 1, 3, 21, 47, 21, 33, 265, 171, 765, 3871, 3577, 15135, 13483, 0 }; + static ulong[] dim2657Kuo2Init = { 1, 3, 1, 3, 29, 5, 109, 3, 249, 379, 1259, 677, 1177, 13061, 31985, 0 }; + static ulong[] dim2658Kuo2Init = { 1, 3, 7, 3, 15, 25, 123, 93, 193, 419, 1173, 2493, 2937, 14909, 3147, 0 }; + static ulong[] dim2659Kuo2Init = { 1, 3, 3, 3, 9, 59, 55, 95, 93, 319, 1281, 587, 8065, 15697, 32101, 0 }; + static ulong[] dim2660Kuo2Init = { 1, 3, 5, 7, 25, 61, 105, 199, 101, 255, 849, 377, 3245, 8139, 8383, 0 }; + static ulong[] dim2661Kuo2Init = { 1, 1, 5, 9, 3, 47, 79, 155, 15, 661, 1417, 87, 4225, 13241, 15971, 0 }; + static ulong[] dim2662Kuo2Init = { 1, 3, 3, 1, 13, 39, 101, 79, 271, 21, 1983, 2821, 4177, 14081, 31219, 0 }; + static ulong[] dim2663Kuo2Init = { 1, 1, 1, 7, 15, 51, 123, 17, 29, 123, 1131, 147, 4191, 6729, 19359, 0 }; + static ulong[] dim2664Kuo2Init = { 1, 1, 7, 7, 17, 39, 47, 215, 219, 643, 1877, 3965, 5799, 16131, 24675, 0 }; + static ulong[] dim2665Kuo2Init = { 1, 3, 5, 7, 11, 53, 57, 133, 289, 33, 1631, 2037, 6699, 14153, 25309, 0 }; + static ulong[] dim2666Kuo2Init = { 1, 3, 7, 7, 9, 17, 125, 123, 91, 15, 1279, 297, 2583, 11141, 7257, 0 }; + static ulong[] dim2667Kuo2Init = { 1, 1, 7, 9, 13, 9, 83, 117, 365, 533, 343, 121, 7553, 14417, 23239, 0 }; + static ulong[] dim2668Kuo2Init = { 1, 3, 3, 9, 5, 27, 97, 229, 321, 123, 1669, 621, 4937, 683, 31061, 0 }; + static ulong[] dim2669Kuo2Init = { 1, 3, 1, 3, 1, 23, 63, 21, 271, 695, 601, 113, 6331, 8837, 16721, 0 }; + static ulong[] dim2670Kuo2Init = { 1, 3, 7, 13, 15, 41, 53, 115, 225, 5, 1315, 2285, 3815, 5949, 4263, 0 }; + static ulong[] dim2671Kuo2Init = { 1, 1, 1, 9, 21, 41, 25, 47, 9, 423, 1171, 2515, 3461, 13273, 13059, 0 }; + static ulong[] dim2672Kuo2Init = { 1, 3, 5, 15, 5, 29, 111, 15, 505, 347, 347, 2521, 4583, 5729, 11645, 0 }; + static ulong[] dim2673Kuo2Init = { 1, 3, 3, 1, 9, 15, 57, 211, 163, 749, 1549, 1015, 441, 16025, 28943, 0 }; + static ulong[] dim2674Kuo2Init = { 1, 1, 3, 15, 15, 27, 111, 79, 131, 831, 2045, 1937, 6969, 11223, 22711, 0 }; + static ulong[] dim2675Kuo2Init = { 1, 3, 5, 1, 3, 37, 37, 221, 143, 955, 1387, 3483, 5845, 13411, 16225, 0 }; + static ulong[] dim2676Kuo2Init = { 1, 3, 1, 3, 7, 13, 75, 57, 357, 109, 241, 165, 1845, 213, 8337, 0 }; + static ulong[] dim2677Kuo2Init = { 1, 3, 1, 15, 5, 41, 109, 129, 91, 459, 1237, 467, 8015, 14499, 19897, 0 }; + static ulong[] dim2678Kuo2Init = { 1, 1, 5, 7, 23, 45, 73, 135, 161, 921, 127, 3723, 1795, 4047, 16607, 0 }; + static ulong[] dim2679Kuo2Init = { 1, 3, 1, 9, 21, 17, 13, 133, 251, 927, 1551, 3087, 317, 2989, 30481, 0 }; + static ulong[] dim2680Kuo2Init = { 1, 1, 3, 7, 15, 51, 17, 77, 345, 833, 983, 2855, 383, 10873, 20019, 0 }; + static ulong[] dim2681Kuo2Init = { 1, 1, 7, 7, 3, 9, 65, 115, 449, 375, 27, 2053, 175, 6793, 9761, 0 }; + static ulong[] dim2682Kuo2Init = { 1, 3, 5, 7, 17, 7, 51, 207, 389, 995, 1663, 3697, 5539, 13495, 4053, 0 }; + static ulong[] dim2683Kuo2Init = { 1, 1, 1, 13, 5, 25, 125, 139, 123, 433, 1323, 273, 6061, 7145, 13929, 0 }; + static ulong[] dim2684Kuo2Init = { 1, 3, 7, 3, 3, 1, 65, 217, 203, 887, 121, 961, 2843, 16171, 8433, 0 }; + static ulong[] dim2685Kuo2Init = { 1, 1, 3, 1, 21, 25, 93, 237, 203, 721, 1135, 751, 7193, 7453, 29593, 0 }; + static ulong[] dim2686Kuo2Init = { 1, 1, 5, 13, 27, 41, 125, 31, 145, 69, 1865, 471, 6031, 6589, 16185, 0 }; + static ulong[] dim2687Kuo2Init = { 1, 1, 5, 1, 13, 39, 15, 251, 125, 781, 1635, 231, 7503, 12647, 9493, 0 }; + static ulong[] dim2688Kuo2Init = { 1, 1, 3, 11, 31, 35, 39, 49, 279, 281, 285, 1707, 607, 3405, 5803, 0 }; + static ulong[] dim2689Kuo2Init = { 1, 3, 5, 7, 29, 61, 43, 15, 413, 759, 159, 2027, 4065, 9501, 31597, 0 }; + static ulong[] dim2690Kuo2Init = { 1, 1, 5, 3, 21, 19, 25, 31, 21, 139, 1273, 871, 423, 13737, 1633, 0 }; + static ulong[] dim2691Kuo2Init = { 1, 1, 5, 11, 9, 15, 15, 247, 459, 49, 2047, 289, 7457, 13367, 3343, 0 }; + static ulong[] dim2692Kuo2Init = { 1, 3, 7, 1, 5, 43, 49, 115, 201, 131, 297, 2069, 801, 7599, 675, 0 }; + static ulong[] dim2693Kuo2Init = { 1, 1, 3, 15, 11, 19, 41, 135, 107, 325, 431, 2459, 7629, 3407, 19635, 0 }; + static ulong[] dim2694Kuo2Init = { 1, 1, 7, 15, 1, 45, 89, 249, 463, 319, 1577, 549, 3623, 7053, 23037, 0 }; + static ulong[] dim2695Kuo2Init = { 1, 3, 1, 11, 27, 23, 123, 63, 219, 77, 179, 3283, 2887, 14023, 28277, 0 }; + static ulong[] dim2696Kuo2Init = { 1, 3, 1, 9, 29, 47, 39, 61, 413, 327, 1529, 593, 7779, 14857, 14165, 0 }; + static ulong[] dim2697Kuo2Init = { 1, 3, 5, 3, 29, 15, 73, 231, 141, 435, 1835, 1023, 289, 1859, 1069, 0 }; + static ulong[] dim2698Kuo2Init = { 1, 3, 3, 3, 9, 35, 1, 153, 111, 521, 461, 3001, 5401, 9529, 19845, 0 }; + static ulong[] dim2699Kuo2Init = { 1, 1, 1, 15, 17, 43, 49, 227, 87, 199, 179, 1619, 6093, 15695, 30739, 0 }; + static ulong[] dim2700Kuo2Init = { 1, 3, 3, 9, 17, 53, 67, 199, 263, 931, 413, 1019, 679, 15483, 22211, 0 }; + static ulong[] dim2701Kuo2Init = { 1, 1, 7, 3, 19, 7, 55, 111, 499, 587, 1685, 1007, 5147, 6097, 31801, 0 }; + static ulong[] dim2702Kuo2Init = { 1, 3, 7, 5, 17, 15, 41, 167, 495, 439, 1161, 3737, 5957, 4151, 26597, 0 }; + static ulong[] dim2703Kuo2Init = { 1, 3, 5, 13, 17, 35, 103, 205, 83, 613, 1541, 2825, 2773, 14487, 177, 0 }; + static ulong[] dim2704Kuo2Init = { 1, 3, 1, 5, 11, 31, 1, 93, 87, 917, 1209, 1489, 4063, 7811, 31291, 0 }; + static ulong[] dim2705Kuo2Init = { 1, 1, 5, 9, 27, 25, 15, 121, 51, 207, 567, 2091, 6177, 121, 15305, 0 }; + static ulong[] dim2706Kuo2Init = { 1, 3, 7, 13, 17, 27, 13, 31, 443, 487, 863, 3253, 4961, 2695, 6427, 0 }; + static ulong[] dim2707Kuo2Init = { 1, 3, 7, 15, 23, 23, 85, 229, 123, 151, 519, 2581, 4073, 5915, 23715, 0 }; + static ulong[] dim2708Kuo2Init = { 1, 3, 5, 9, 19, 41, 33, 71, 511, 683, 1387, 2975, 5069, 4327, 25881, 0 }; + static ulong[] dim2709Kuo2Init = { 1, 1, 7, 3, 9, 25, 29, 73, 55, 323, 483, 1509, 4895, 5151, 13095, 0 }; + static ulong[] dim2710Kuo2Init = { 1, 3, 7, 3, 7, 19, 95, 163, 239, 721, 747, 3965, 6943, 11771, 5991, 0 }; + static ulong[] dim2711Kuo2Init = { 1, 3, 1, 9, 27, 11, 5, 9, 291, 987, 313, 129, 4147, 1005, 25719, 0 }; + static ulong[] dim2712Kuo2Init = { 1, 1, 1, 5, 7, 25, 85, 197, 177, 759, 1083, 2615, 3647, 11873, 17035, 0 }; + static ulong[] dim2713Kuo2Init = { 1, 3, 1, 13, 13, 11, 29, 45, 103, 319, 1325, 2987, 7253, 3967, 32547, 0 }; + static ulong[] dim2714Kuo2Init = { 1, 3, 5, 9, 11, 27, 103, 75, 113, 741, 175, 2715, 1595, 7899, 261, 0 }; + static ulong[] dim2715Kuo2Init = { 1, 1, 3, 5, 3, 39, 113, 19, 301, 19, 1369, 2759, 467, 10387, 15763, 0 }; + static ulong[] dim2716Kuo2Init = { 1, 1, 5, 5, 5, 23, 47, 21, 69, 57, 1183, 2725, 2329, 4829, 22769, 0 }; + static ulong[] dim2717Kuo2Init = { 1, 3, 3, 13, 1, 39, 111, 11, 133, 143, 465, 1551, 2969, 2353, 9381, 0 }; + static ulong[] dim2718Kuo2Init = { 1, 3, 7, 3, 29, 19, 75, 97, 139, 325, 189, 477, 5687, 11105, 17325, 0 }; + static ulong[] dim2719Kuo2Init = { 1, 1, 3, 15, 25, 51, 53, 177, 41, 677, 233, 467, 4977, 8055, 30257, 0 }; + static ulong[] dim2720Kuo2Init = { 1, 3, 7, 5, 29, 49, 23, 247, 167, 229, 719, 1583, 3451, 11901, 10991, 0 }; + static ulong[] dim2721Kuo2Init = { 1, 1, 1, 13, 5, 39, 35, 247, 185, 409, 1481, 3993, 2023, 9251, 1253, 0 }; + static ulong[] dim2722Kuo2Init = { 1, 1, 3, 13, 27, 35, 49, 251, 359, 161, 1535, 3277, 1483, 8045, 22373, 0 }; + static ulong[] dim2723Kuo2Init = { 1, 1, 1, 7, 3, 63, 103, 7, 141, 305, 1803, 3429, 6819, 3389, 12915, 0 }; + static ulong[] dim2724Kuo2Init = { 1, 3, 3, 15, 15, 7, 19, 121, 421, 633, 1619, 1225, 4061, 13649, 25537, 0 }; + static ulong[] dim2725Kuo2Init = { 1, 3, 7, 13, 5, 49, 117, 97, 85, 13, 55, 2991, 6215, 15087, 29311, 0 }; + static ulong[] dim2726Kuo2Init = { 1, 1, 7, 13, 29, 37, 23, 75, 11, 899, 1519, 2151, 235, 7121, 20881, 0 }; + static ulong[] dim2727Kuo2Init = { 1, 3, 5, 13, 7, 9, 97, 57, 307, 791, 745, 881, 6627, 1639, 22029, 0 }; + static ulong[] dim2728Kuo2Init = { 1, 3, 7, 11, 31, 25, 67, 153, 397, 115, 1951, 553, 2511, 853, 22771, 0 }; + static ulong[] dim2729Kuo2Init = { 1, 1, 7, 13, 13, 33, 3, 49, 281, 847, 395, 2671, 7173, 11035, 2809, 0 }; + static ulong[] dim2730Kuo2Init = { 1, 3, 7, 11, 7, 13, 21, 93, 279, 453, 1793, 1183, 4071, 11357, 15871, 0 }; + static ulong[] dim2731Kuo2Init = { 1, 3, 5, 1, 31, 27, 87, 115, 373, 519, 1691, 3339, 5319, 10765, 3497, 0 }; + static ulong[] dim2732Kuo2Init = { 1, 3, 5, 11, 27, 13, 73, 111, 349, 889, 1447, 1733, 7701, 9263, 27267, 0 }; + static ulong[] dim2733Kuo2Init = { 1, 1, 1, 13, 15, 25, 31, 187, 227, 119, 955, 1233, 2749, 8477, 12031, 0 }; + static ulong[] dim2734Kuo2Init = { 1, 3, 1, 7, 19, 13, 89, 151, 61, 267, 1833, 3023, 8177, 12863, 13851, 0 }; + static ulong[] dim2735Kuo2Init = { 1, 1, 7, 11, 11, 19, 65, 223, 175, 893, 1515, 2323, 6725, 747, 10299, 0 }; + static ulong[] dim2736Kuo2Init = { 1, 1, 1, 15, 3, 17, 109, 119, 371, 193, 1289, 219, 463, 9043, 31471, 0 }; + static ulong[] dim2737Kuo2Init = { 1, 1, 1, 3, 9, 9, 71, 185, 81, 849, 917, 2495, 4065, 14161, 14287, 0 }; + static ulong[] dim2738Kuo2Init = { 1, 1, 5, 3, 5, 59, 111, 133, 351, 247, 1035, 3277, 3865, 5879, 16537, 0 }; + static ulong[] dim2739Kuo2Init = { 1, 3, 3, 11, 23, 47, 3, 39, 343, 71, 109, 4005, 7453, 8327, 9797, 0 }; + static ulong[] dim2740Kuo2Init = { 1, 1, 1, 5, 21, 31, 53, 33, 115, 287, 431, 2085, 5275, 5253, 18137, 0 }; + static ulong[] dim2741Kuo2Init = { 1, 3, 1, 15, 21, 43, 95, 143, 103, 611, 583, 41, 483, 13973, 30231, 0 }; + static ulong[] dim2742Kuo2Init = { 1, 1, 1, 9, 9, 33, 49, 35, 329, 887, 1593, 2301, 229, 10291, 21153, 0 }; + static ulong[] dim2743Kuo2Init = { 1, 3, 5, 9, 25, 55, 55, 207, 381, 747, 997, 3105, 377, 15327, 24367, 0 }; + static ulong[] dim2744Kuo2Init = { 1, 3, 7, 15, 23, 25, 101, 225, 345, 579, 975, 2383, 7833, 12727, 15991, 0 }; + static ulong[] dim2745Kuo2Init = { 1, 3, 3, 1, 23, 13, 51, 45, 471, 271, 151, 1407, 2079, 3521, 6469, 0 }; + static ulong[] dim2746Kuo2Init = { 1, 3, 1, 9, 3, 11, 117, 115, 89, 871, 1989, 1341, 2415, 12921, 3531, 0 }; + static ulong[] dim2747Kuo2Init = { 1, 3, 3, 1, 3, 49, 41, 215, 277, 155, 1185, 2837, 4361, 14495, 19877, 0 }; + static ulong[] dim2748Kuo2Init = { 1, 1, 1, 9, 9, 19, 31, 211, 179, 367, 1597, 561, 5397, 7525, 2963, 0 }; + static ulong[] dim2749Kuo2Init = { 1, 3, 7, 11, 25, 45, 29, 151, 107, 13, 1461, 235, 6939, 6223, 13111, 0 }; + static ulong[] dim2750Kuo2Init = { 1, 3, 7, 15, 17, 11, 43, 113, 65, 321, 1393, 1131, 2481, 13139, 14647, 0 }; + static ulong[] dim2751Kuo2Init = { 1, 3, 7, 3, 15, 23, 45, 229, 175, 857, 1303, 783, 3929, 855, 13581, 0 }; + static ulong[] dim2752Kuo2Init = { 1, 3, 7, 3, 7, 55, 99, 85, 415, 667, 603, 593, 427, 10725, 6973, 0 }; + static ulong[] dim2753Kuo2Init = { 1, 3, 7, 3, 1, 23, 93, 177, 59, 601, 1947, 3253, 639, 10007, 1441, 0 }; + static ulong[] dim2754Kuo2Init = { 1, 3, 5, 11, 13, 37, 79, 19, 395, 161, 945, 969, 1579, 13537, 6347, 0 }; + static ulong[] dim2755Kuo2Init = { 1, 3, 1, 15, 3, 61, 101, 3, 289, 707, 61, 1405, 811, 6727, 22339, 0 }; + static ulong[] dim2756Kuo2Init = { 1, 3, 5, 11, 3, 45, 19, 125, 503, 153, 1439, 2105, 7483, 1835, 22841, 0 }; + static ulong[] dim2757Kuo2Init = { 1, 1, 7, 3, 23, 49, 49, 227, 413, 57, 1829, 37, 407, 4203, 20575, 0 }; + static ulong[] dim2758Kuo2Init = { 1, 3, 5, 11, 3, 43, 93, 85, 37, 471, 1971, 1559, 5151, 11641, 13011, 0 }; + static ulong[] dim2759Kuo2Init = { 1, 1, 5, 15, 5, 13, 17, 209, 125, 581, 57, 43, 7089, 3367, 16073, 0 }; + static ulong[] dim2760Kuo2Init = { 1, 3, 3, 9, 29, 51, 93, 223, 73, 917, 1657, 2811, 1593, 8595, 23347, 0 }; + static ulong[] dim2761Kuo2Init = { 1, 3, 1, 15, 25, 21, 111, 207, 61, 815, 805, 1439, 5745, 5065, 9877, 0 }; + static ulong[] dim2762Kuo2Init = { 1, 3, 3, 15, 7, 1, 113, 225, 467, 341, 1145, 3839, 1127, 5085, 885, 0 }; + static ulong[] dim2763Kuo2Init = { 1, 1, 7, 3, 13, 27, 103, 17, 175, 351, 1321, 2093, 3407, 3387, 1663, 0 }; + static ulong[] dim2764Kuo2Init = { 1, 3, 5, 13, 5, 61, 31, 223, 249, 797, 1541, 3985, 2165, 8741, 561, 0 }; + static ulong[] dim2765Kuo2Init = { 1, 1, 1, 7, 21, 51, 119, 9, 331, 305, 1279, 3331, 2769, 673, 26293, 0 }; + static ulong[] dim2766Kuo2Init = { 1, 1, 3, 9, 7, 61, 65, 157, 7, 259, 871, 557, 7917, 12839, 18521, 0 }; + static ulong[] dim2767Kuo2Init = { 1, 3, 3, 5, 9, 63, 21, 109, 409, 843, 1811, 1869, 6833, 6041, 31557, 0 }; + static ulong[] dim2768Kuo2Init = { 1, 1, 5, 15, 17, 17, 25, 79, 157, 657, 1049, 2071, 4381, 14123, 4609, 0 }; + static ulong[] dim2769Kuo2Init = { 1, 1, 5, 3, 3, 7, 45, 69, 311, 197, 1729, 2803, 2621, 1165, 26455, 0 }; + static ulong[] dim2770Kuo2Init = { 1, 3, 7, 7, 23, 21, 21, 227, 481, 825, 1871, 325, 3199, 5591, 22061, 0 }; + static ulong[] dim2771Kuo2Init = { 1, 3, 1, 7, 7, 53, 125, 163, 133, 1015, 727, 329, 403, 3347, 8957, 0 }; + static ulong[] dim2772Kuo2Init = { 1, 1, 3, 1, 13, 19, 107, 31, 261, 771, 195, 2381, 2577, 5381, 7159, 0 }; + static ulong[] dim2773Kuo2Init = { 1, 3, 7, 9, 7, 21, 61, 179, 405, 745, 689, 2527, 4189, 12869, 32101, 0 }; + static ulong[] dim2774Kuo2Init = { 1, 3, 7, 1, 3, 25, 35, 103, 107, 433, 1039, 3557, 7207, 13945, 27751, 0 }; + static ulong[] dim2775Kuo2Init = { 1, 3, 5, 5, 7, 9, 55, 93, 39, 965, 1391, 1069, 6003, 3785, 17337, 0 }; + static ulong[] dim2776Kuo2Init = { 1, 1, 5, 5, 11, 33, 127, 247, 443, 697, 2007, 491, 3773, 4921, 21083, 0 }; + static ulong[] dim2777Kuo2Init = { 1, 1, 5, 9, 1, 3, 33, 99, 31, 797, 295, 2855, 1911, 5741, 21255, 0 }; + static ulong[] dim2778Kuo2Init = { 1, 1, 5, 9, 25, 27, 77, 111, 119, 1, 193, 2825, 3721, 2923, 1301, 0 }; + static ulong[] dim2779Kuo2Init = { 1, 1, 1, 9, 11, 51, 51, 193, 331, 867, 1711, 969, 1245, 2815, 13165, 0 }; + static ulong[] dim2780Kuo2Init = { 1, 3, 5, 1, 23, 29, 23, 193, 357, 567, 983, 2861, 3973, 3613, 8049, 0 }; + static ulong[] dim2781Kuo2Init = { 1, 1, 7, 3, 27, 1, 117, 255, 149, 427, 1211, 2945, 4057, 725, 11061, 0 }; + static ulong[] dim2782Kuo2Init = { 1, 1, 7, 5, 13, 5, 101, 21, 167, 535, 825, 639, 6659, 9779, 11939, 0 }; + static ulong[] dim2783Kuo2Init = { 1, 3, 7, 1, 23, 25, 5, 15, 491, 531, 1035, 1989, 2125, 2779, 3207, 0 }; + static ulong[] dim2784Kuo2Init = { 1, 1, 3, 13, 13, 25, 43, 155, 251, 761, 123, 1373, 649, 11709, 22331, 0 }; + static ulong[] dim2785Kuo2Init = { 1, 3, 5, 13, 25, 37, 15, 247, 303, 95, 1837, 499, 2181, 11223, 1633, 0 }; + static ulong[] dim2786Kuo2Init = { 1, 1, 1, 5, 15, 53, 29, 193, 11, 625, 21, 3893, 957, 493, 32393, 0 }; + static ulong[] dim2787Kuo2Init = { 1, 1, 5, 9, 31, 13, 3, 235, 65, 563, 1787, 387, 2573, 3435, 8669, 0 }; + static ulong[] dim2788Kuo2Init = { 1, 3, 5, 1, 29, 17, 73, 81, 207, 335, 1949, 3519, 6491, 9185, 2305, 0 }; + static ulong[] dim2789Kuo2Init = { 1, 1, 3, 11, 5, 43, 15, 141, 347, 171, 1965, 2733, 7873, 7295, 10571, 0 }; + static ulong[] dim2790Kuo2Init = { 1, 1, 5, 11, 5, 3, 73, 89, 189, 77, 877, 1127, 3609, 11649, 31191, 0 }; + static ulong[] dim2791Kuo2Init = { 1, 1, 3, 15, 15, 25, 103, 73, 363, 261, 833, 2297, 4295, 13505, 8435, 0 }; + static ulong[] dim2792Kuo2Init = { 1, 1, 3, 9, 23, 57, 15, 87, 215, 789, 975, 2659, 6407, 9883, 3863, 0 }; + static ulong[] dim2793Kuo2Init = { 1, 1, 1, 9, 19, 51, 127, 77, 259, 161, 1527, 1911, 6707, 15573, 12479, 0 }; + static ulong[] dim2794Kuo2Init = { 1, 3, 1, 15, 11, 5, 35, 89, 235, 281, 269, 511, 783, 307, 19887, 0 }; + static ulong[] dim2795Kuo2Init = { 1, 3, 7, 15, 1, 43, 85, 25, 133, 577, 1719, 3999, 4597, 125, 12945, 0 }; + static ulong[] dim2796Kuo2Init = { 1, 3, 5, 15, 3, 1, 3, 111, 145, 485, 1959, 1859, 3567, 4219, 7507, 0 }; + static ulong[] dim2797Kuo2Init = { 1, 1, 3, 5, 27, 17, 45, 157, 87, 895, 497, 3, 1553, 2697, 24767, 0 }; + static ulong[] dim2798Kuo2Init = { 1, 3, 5, 1, 31, 23, 123, 67, 349, 717, 1699, 823, 851, 1283, 25641, 0 }; + static ulong[] dim2799Kuo2Init = { 1, 1, 5, 15, 9, 61, 43, 171, 33, 367, 1887, 917, 1901, 10881, 5699, 0 }; + static ulong[] dim2800Kuo2Init = { 1, 3, 1, 7, 11, 33, 45, 19, 71, 913, 687, 265, 1579, 13857, 3833, 0 }; + static ulong[] dim2801Kuo2Init = { 1, 3, 1, 5, 7, 15, 11, 87, 277, 435, 1479, 3025, 4663, 12063, 25185, 0 }; + static ulong[] dim2802Kuo2Init = { 1, 1, 1, 1, 15, 11, 91, 99, 195, 77, 967, 2741, 4291, 4441, 2763, 0 }; + static ulong[] dim2803Kuo2Init = { 1, 3, 7, 9, 9, 47, 25, 225, 193, 569, 561, 2567, 2751, 9035, 21613, 0 }; + static ulong[] dim2804Kuo2Init = { 1, 1, 3, 9, 3, 25, 99, 95, 33, 811, 479, 99, 7893, 869, 6879, 0 }; + static ulong[] dim2805Kuo2Init = { 1, 1, 5, 7, 11, 43, 111, 131, 107, 989, 147, 529, 6361, 769, 26651, 0 }; + static ulong[] dim2806Kuo2Init = { 1, 1, 5, 9, 23, 47, 81, 97, 357, 613, 609, 357, 2001, 14795, 25093, 0 }; + static ulong[] dim2807Kuo2Init = { 1, 1, 7, 3, 1, 13, 31, 171, 471, 981, 1923, 3053, 1577, 14433, 1795, 0 }; + static ulong[] dim2808Kuo2Init = { 1, 1, 3, 11, 29, 15, 107, 5, 281, 773, 1323, 763, 6821, 15309, 21459, 0 }; + static ulong[] dim2809Kuo2Init = { 1, 1, 5, 3, 17, 47, 49, 159, 17, 595, 1405, 1307, 3027, 3023, 17231, 0 }; + static ulong[] dim2810Kuo2Init = { 1, 3, 3, 11, 5, 37, 39, 247, 391, 587, 1305, 969, 7183, 1079, 5723, 0 }; + static ulong[] dim2811Kuo2Init = { 1, 3, 7, 5, 11, 57, 49, 55, 505, 961, 115, 2445, 583, 9175, 11897, 0 }; + static ulong[] dim2812Kuo2Init = { 1, 1, 7, 13, 23, 35, 9, 59, 147, 139, 361, 1497, 1691, 1149, 19777, 0 }; + static ulong[] dim2813Kuo2Init = { 1, 3, 7, 1, 19, 41, 71, 63, 401, 193, 107, 1891, 5353, 4619, 18311, 0 }; + static ulong[] dim2814Kuo2Init = { 1, 1, 7, 1, 27, 7, 49, 69, 179, 461, 1625, 2431, 5149, 3221, 14221, 0 }; + static ulong[] dim2815Kuo2Init = { 1, 3, 7, 13, 7, 11, 55, 93, 191, 1011, 139, 2323, 5103, 9655, 28605, 0 }; + static ulong[] dim2816Kuo2Init = { 1, 1, 5, 7, 29, 53, 117, 253, 193, 29, 2003, 2051, 6113, 4941, 18407, 0 }; + static ulong[] dim2817Kuo2Init = { 1, 1, 5, 5, 31, 7, 63, 179, 371, 1007, 107, 113, 6845, 8507, 9691, 0 }; + static ulong[] dim2818Kuo2Init = { 1, 1, 7, 7, 9, 31, 91, 225, 115, 905, 1593, 2791, 1507, 13323, 787, 0 }; + static ulong[] dim2819Kuo2Init = { 1, 3, 1, 9, 31, 13, 81, 111, 255, 467, 2007, 3591, 3849, 3445, 6859, 0 }; + static ulong[] dim2820Kuo2Init = { 1, 3, 7, 15, 19, 3, 89, 171, 445, 803, 1583, 1875, 5631, 10583, 32527, 0 }; + static ulong[] dim2821Kuo2Init = { 1, 3, 3, 15, 29, 29, 41, 199, 237, 507, 1715, 3887, 2951, 5803, 32749, 0 }; + static ulong[] dim2822Kuo2Init = { 1, 1, 3, 5, 21, 51, 29, 131, 459, 611, 967, 99, 8057, 12685, 16021, 0 }; + static ulong[] dim2823Kuo2Init = { 1, 3, 5, 5, 21, 19, 103, 131, 149, 477, 437, 4003, 7141, 2465, 32723, 0 }; + static ulong[] dim2824Kuo2Init = { 1, 3, 7, 15, 9, 41, 115, 47, 261, 589, 1859, 631, 719, 4459, 26475, 0 }; + static ulong[] dim2825Kuo2Init = { 1, 3, 1, 7, 9, 43, 79, 51, 383, 355, 1977, 739, 7333, 3573, 16061, 0 }; + static ulong[] dim2826Kuo2Init = { 1, 1, 3, 1, 11, 9, 79, 141, 135, 195, 755, 585, 7125, 4643, 31791, 0 }; + static ulong[] dim2827Kuo2Init = { 1, 1, 1, 7, 21, 23, 5, 225, 57, 307, 455, 3713, 8167, 4759, 10337, 0 }; + static ulong[] dim2828Kuo2Init = { 1, 3, 1, 15, 3, 45, 9, 225, 167, 847, 1205, 2105, 2547, 10925, 31181, 0 }; + static ulong[] dim2829Kuo2Init = { 1, 1, 3, 5, 3, 25, 57, 21, 45, 685, 53, 2447, 3139, 10949, 14939, 0 }; + static ulong[] dim2830Kuo2Init = { 1, 3, 5, 7, 13, 55, 13, 185, 353, 613, 1655, 1171, 6261, 1703, 26859, 0 }; + static ulong[] dim2831Kuo2Init = { 1, 1, 1, 15, 25, 29, 99, 81, 141, 387, 1369, 2177, 289, 14499, 23795, 0 }; + static ulong[] dim2832Kuo2Init = { 1, 3, 7, 5, 1, 37, 123, 99, 1, 707, 1415, 1275, 3979, 3359, 17807, 0 }; + static ulong[] dim2833Kuo2Init = { 1, 1, 5, 15, 19, 7, 113, 51, 329, 109, 1705, 517, 1887, 393, 8283, 0 }; + static ulong[] dim2834Kuo2Init = { 1, 3, 1, 13, 23, 63, 89, 117, 89, 515, 1221, 3267, 2371, 5065, 16391, 0 }; + static ulong[] dim2835Kuo2Init = { 1, 3, 5, 15, 1, 17, 39, 129, 453, 503, 841, 2997, 4279, 8639, 17623, 0 }; + static ulong[] dim2836Kuo2Init = { 1, 3, 5, 15, 27, 23, 127, 85, 301, 491, 959, 3241, 7525, 13723, 12317, 0 }; + static ulong[] dim2837Kuo2Init = { 1, 3, 5, 9, 31, 63, 45, 237, 173, 823, 223, 3129, 3285, 359, 3549, 0 }; + static ulong[] dim2838Kuo2Init = { 1, 3, 5, 7, 19, 29, 85, 191, 395, 717, 1305, 2529, 7939, 10905, 8941, 0 }; + static ulong[] dim2839Kuo2Init = { 1, 1, 5, 13, 31, 3, 41, 61, 461, 341, 683, 1973, 7127, 2183, 2137, 0 }; + static ulong[] dim2840Kuo2Init = { 1, 3, 1, 7, 27, 33, 97, 97, 319, 329, 1075, 539, 3313, 6343, 11249, 0 }; + static ulong[] dim2841Kuo2Init = { 1, 3, 5, 7, 25, 31, 99, 59, 337, 169, 861, 1989, 5999, 5397, 20563, 0 }; + static ulong[] dim2842Kuo2Init = { 1, 1, 5, 13, 17, 37, 83, 33, 75, 887, 379, 3499, 733, 4343, 31503, 0 }; + static ulong[] dim2843Kuo2Init = { 1, 1, 3, 1, 3, 45, 3, 245, 37, 797, 43, 943, 5301, 6857, 6653, 0 }; + static ulong[] dim2844Kuo2Init = { 1, 1, 1, 3, 9, 7, 39, 231, 349, 481, 1831, 2115, 6381, 13021, 18775, 0 }; + static ulong[] dim2845Kuo2Init = { 1, 3, 1, 11, 31, 27, 33, 103, 469, 987, 663, 3533, 1441, 4703, 23383, 0 }; + static ulong[] dim2846Kuo2Init = { 1, 3, 3, 15, 27, 59, 31, 31, 463, 851, 1957, 2905, 4823, 12549, 849, 0 }; + static ulong[] dim2847Kuo2Init = { 1, 3, 7, 5, 17, 31, 125, 183, 189, 297, 417, 1387, 5811, 10517, 19367, 0 }; + static ulong[] dim2848Kuo2Init = { 1, 3, 7, 7, 7, 9, 91, 9, 343, 267, 493, 431, 2345, 7173, 1769, 0 }; + static ulong[] dim2849Kuo2Init = { 1, 1, 1, 13, 13, 43, 75, 83, 19, 115, 1609, 2449, 5647, 12201, 27053, 0 }; + static ulong[] dim2850Kuo2Init = { 1, 3, 7, 7, 1, 7, 81, 89, 371, 283, 993, 3875, 6853, 16039, 12725, 0 }; + static ulong[] dim2851Kuo2Init = { 1, 1, 7, 1, 21, 61, 121, 135, 333, 339, 39, 2543, 3517, 9099, 27495, 0 }; + static ulong[] dim2852Kuo2Init = { 1, 1, 7, 13, 19, 59, 65, 65, 407, 255, 915, 2679, 2841, 13981, 6351, 0 }; + static ulong[] dim2853Kuo2Init = { 1, 3, 1, 5, 9, 45, 73, 217, 93, 3, 493, 531, 6709, 6543, 26243, 0 }; + static ulong[] dim2854Kuo2Init = { 1, 3, 3, 13, 9, 25, 77, 223, 495, 789, 1885, 383, 7767, 4309, 29863, 0 }; + static ulong[] dim2855Kuo2Init = { 1, 3, 5, 7, 21, 55, 11, 13, 19, 605, 1067, 667, 1163, 3847, 17997, 0 }; + static ulong[] dim2856Kuo2Init = { 1, 1, 7, 1, 15, 51, 69, 115, 19, 1003, 1307, 3245, 7087, 6935, 25439, 0 }; + static ulong[] dim2857Kuo2Init = { 1, 1, 7, 5, 11, 7, 85, 171, 301, 953, 507, 3873, 1121, 1663, 6321, 0 }; + static ulong[] dim2858Kuo2Init = { 1, 1, 1, 13, 11, 1, 105, 175, 163, 847, 983, 3869, 3571, 3405, 25475, 0 }; + static ulong[] dim2859Kuo2Init = { 1, 3, 5, 15, 7, 51, 89, 127, 347, 867, 429, 1483, 5203, 5215, 18521, 0 }; + static ulong[] dim2860Kuo2Init = { 1, 1, 3, 7, 21, 35, 91, 107, 111, 895, 1827, 3273, 3189, 4253, 12643, 0 }; + static ulong[] dim2861Kuo2Init = { 1, 3, 5, 15, 31, 33, 59, 27, 59, 297, 7, 1521, 1571, 10275, 32537, 0 }; + static ulong[] dim2862Kuo2Init = { 1, 1, 5, 11, 1, 27, 17, 115, 349, 593, 1819, 707, 4915, 2053, 13393, 0 }; + static ulong[] dim2863Kuo2Init = { 1, 1, 1, 1, 25, 47, 73, 163, 191, 637, 1723, 2431, 4821, 4283, 14647, 0 }; + static ulong[] dim2864Kuo2Init = { 1, 3, 7, 13, 1, 55, 67, 89, 113, 757, 1675, 255, 99, 9427, 953, 0 }; + static ulong[] dim2865Kuo2Init = { 1, 3, 7, 5, 1, 33, 7, 49, 299, 205, 1933, 2319, 6047, 6837, 6411, 0 }; + static ulong[] dim2866Kuo2Init = { 1, 1, 7, 5, 11, 35, 61, 211, 487, 253, 1463, 2039, 3859, 4315, 29603, 0 }; + static ulong[] dim2867Kuo2Init = { 1, 3, 1, 15, 23, 49, 99, 41, 263, 177, 193, 921, 1031, 13745, 14283, 0 }; + static ulong[] dim2868Kuo2Init = { 1, 3, 7, 5, 19, 35, 91, 19, 481, 305, 477, 2989, 7319, 2477, 2481, 0 }; + static ulong[] dim2869Kuo2Init = { 1, 3, 7, 13, 1, 15, 25, 133, 175, 571, 15, 505, 7459, 13283, 10253, 0 }; + static ulong[] dim2870Kuo2Init = { 1, 3, 7, 11, 13, 27, 95, 179, 149, 267, 481, 543, 3643, 4261, 1241, 0 }; + static ulong[] dim2871Kuo2Init = { 1, 1, 3, 1, 5, 25, 115, 27, 503, 595, 43, 975, 6223, 14173, 12977, 0 }; + static ulong[] dim2872Kuo2Init = { 1, 1, 1, 13, 17, 55, 3, 129, 125, 565, 785, 2787, 5963, 12565, 11061, 0 }; + static ulong[] dim2873Kuo2Init = { 1, 1, 1, 1, 23, 25, 51, 89, 317, 887, 1007, 1619, 3221, 4015, 18183, 0 }; + static ulong[] dim2874Kuo2Init = { 1, 3, 3, 7, 27, 37, 33, 131, 379, 505, 1679, 2381, 629, 8593, 15553, 0 }; + static ulong[] dim2875Kuo2Init = { 1, 3, 1, 9, 21, 53, 79, 85, 27, 541, 997, 1721, 2379, 9939, 32197, 0 }; + static ulong[] dim2876Kuo2Init = { 1, 3, 7, 5, 29, 3, 29, 7, 499, 195, 157, 1431, 1117, 14781, 14811, 0 }; + static ulong[] dim2877Kuo2Init = { 1, 3, 3, 9, 23, 19, 41, 59, 313, 391, 193, 3813, 2769, 7845, 4853, 0 }; + static ulong[] dim2878Kuo2Init = { 1, 1, 7, 7, 7, 61, 103, 45, 225, 753, 339, 963, 3991, 8699, 19805, 0 }; + static ulong[] dim2879Kuo2Init = { 1, 1, 3, 5, 15, 61, 125, 121, 53, 105, 121, 1939, 4745, 1193, 1733, 0 }; + static ulong[] dim2880Kuo2Init = { 1, 1, 7, 7, 29, 29, 71, 137, 195, 757, 1251, 3483, 6977, 1189, 4929, 0 }; + static ulong[] dim2881Kuo2Init = { 1, 1, 3, 9, 1, 11, 21, 39, 199, 873, 1063, 3327, 2171, 14611, 15283, 0 }; + static ulong[] dim2882Kuo2Init = { 1, 3, 3, 15, 11, 19, 71, 185, 235, 211, 1435, 543, 3445, 2533, 25037, 0 }; + static ulong[] dim2883Kuo2Init = { 1, 3, 1, 7, 15, 17, 33, 139, 301, 853, 2027, 1665, 4931, 2083, 9775, 0 }; + static ulong[] dim2884Kuo2Init = { 1, 3, 5, 1, 31, 21, 91, 71, 273, 119, 801, 2071, 4537, 541, 743, 0 }; + static ulong[] dim2885Kuo2Init = { 1, 1, 3, 5, 29, 23, 15, 225, 333, 979, 443, 1425, 3383, 5137, 27273, 0 }; + static ulong[] dim2886Kuo2Init = { 1, 1, 1, 5, 21, 27, 121, 169, 495, 883, 355, 3923, 1505, 13033, 6421, 0 }; + static ulong[] dim2887Kuo2Init = { 1, 3, 1, 5, 3, 17, 19, 169, 43, 659, 893, 1913, 885, 1239, 4055, 0 }; + static ulong[] dim2888Kuo2Init = { 1, 1, 1, 13, 13, 39, 1, 123, 29, 573, 475, 535, 4685, 6377, 30009, 0 }; + static ulong[] dim2889Kuo2Init = { 1, 3, 7, 7, 15, 53, 93, 183, 379, 125, 489, 4059, 5411, 7909, 25799, 0 }; + static ulong[] dim2890Kuo2Init = { 1, 1, 1, 3, 23, 31, 75, 61, 75, 379, 1221, 3045, 7111, 10639, 3177, 0 }; + static ulong[] dim2891Kuo2Init = { 1, 1, 1, 7, 27, 37, 77, 145, 35, 1005, 1105, 1301, 5217, 3011, 22631, 0 }; + static ulong[] dim2892Kuo2Init = { 1, 1, 5, 5, 29, 7, 55, 139, 323, 413, 31, 1719, 2315, 5809, 9521, 0 }; + static ulong[] dim2893Kuo2Init = { 1, 3, 1, 3, 21, 61, 45, 143, 427, 511, 1007, 1009, 6775, 4243, 29573, 0 }; + static ulong[] dim2894Kuo2Init = { 1, 1, 3, 9, 11, 13, 29, 99, 179, 493, 1793, 375, 109, 8561, 14799, 0 }; + static ulong[] dim2895Kuo2Init = { 1, 3, 1, 9, 5, 37, 83, 227, 241, 933, 869, 2125, 2733, 205, 14985, 0 }; + static ulong[] dim2896Kuo2Init = { 1, 3, 7, 3, 11, 17, 39, 97, 229, 805, 491, 2881, 4147, 2159, 32461, 0 }; + static ulong[] dim2897Kuo2Init = { 1, 3, 7, 15, 27, 17, 71, 227, 247, 731, 1287, 397, 7237, 10869, 7799, 0 }; + static ulong[] dim2898Kuo2Init = { 1, 3, 7, 15, 7, 1, 63, 163, 249, 111, 1015, 2379, 7051, 11615, 20031, 0 }; + static ulong[] dim2899Kuo2Init = { 1, 1, 7, 1, 1, 41, 61, 99, 385, 725, 161, 2595, 1789, 6619, 13397, 0 }; + static ulong[] dim2900Kuo2Init = { 1, 1, 7, 15, 5, 53, 59, 153, 427, 251, 1977, 1757, 821, 6391, 7825, 0 }; + static ulong[] dim2901Kuo2Init = { 1, 1, 3, 15, 17, 19, 83, 55, 199, 573, 337, 919, 649, 555, 27791, 0 }; + static ulong[] dim2902Kuo2Init = { 1, 3, 1, 5, 25, 11, 23, 167, 443, 325, 2037, 2533, 643, 1815, 24747, 0 }; + static ulong[] dim2903Kuo2Init = { 1, 1, 1, 7, 3, 15, 21, 73, 165, 241, 1089, 337, 4465, 11867, 31075, 0 }; + static ulong[] dim2904Kuo2Init = { 1, 3, 1, 9, 31, 33, 41, 217, 185, 973, 1971, 1537, 1251, 4307, 22729, 0 }; + static ulong[] dim2905Kuo2Init = { 1, 1, 1, 11, 7, 51, 17, 37, 113, 339, 211, 947, 4649, 8061, 1533, 0 }; + static ulong[] dim2906Kuo2Init = { 1, 3, 3, 11, 7, 1, 29, 233, 145, 121, 83, 3311, 2007, 15325, 2507, 0 }; + static ulong[] dim2907Kuo2Init = { 1, 3, 1, 5, 25, 9, 117, 227, 359, 401, 695, 841, 5825, 14661, 14937, 0 }; + static ulong[] dim2908Kuo2Init = { 1, 3, 3, 13, 27, 43, 61, 117, 297, 773, 1589, 347, 3227, 10893, 3331, 0 }; + static ulong[] dim2909Kuo2Init = { 1, 1, 5, 13, 5, 15, 65, 97, 155, 905, 655, 1665, 2759, 14709, 14327, 0 }; + static ulong[] dim2910Kuo2Init = { 1, 3, 3, 11, 31, 9, 63, 207, 287, 895, 817, 1753, 1961, 15363, 5269, 0 }; + static ulong[] dim2911Kuo2Init = { 1, 1, 1, 11, 3, 17, 21, 131, 295, 553, 1583, 1797, 6949, 7047, 30351, 0 }; + static ulong[] dim2912Kuo2Init = { 1, 3, 7, 5, 23, 9, 123, 155, 1, 525, 469, 165, 591, 6113, 17593, 0 }; + static ulong[] dim2913Kuo2Init = { 1, 3, 5, 13, 27, 21, 125, 175, 323, 113, 1805, 3775, 443, 15723, 187, 0 }; + static ulong[] dim2914Kuo2Init = { 1, 3, 5, 13, 29, 7, 89, 123, 349, 469, 635, 629, 1227, 11601, 10409, 0 }; + static ulong[] dim2915Kuo2Init = { 1, 3, 1, 5, 13, 7, 13, 209, 431, 59, 2001, 1347, 4619, 11581, 23281, 0 }; + static ulong[] dim2916Kuo2Init = { 1, 3, 5, 3, 3, 9, 15, 169, 77, 293, 17, 3205, 5035, 14777, 2175, 0 }; + static ulong[] dim2917Kuo2Init = { 1, 1, 1, 9, 27, 5, 39, 237, 275, 121, 217, 1283, 1619, 9115, 18019, 0 }; + static ulong[] dim2918Kuo2Init = { 1, 1, 1, 11, 31, 43, 111, 235, 439, 217, 769, 513, 5147, 4033, 27329, 0 }; + static ulong[] dim2919Kuo2Init = { 1, 1, 5, 5, 31, 25, 35, 71, 441, 1013, 963, 2945, 4507, 16329, 5965, 0 }; + static ulong[] dim2920Kuo2Init = { 1, 3, 1, 7, 27, 25, 109, 43, 421, 963, 553, 3347, 3159, 11909, 29827, 0 }; + static ulong[] dim2921Kuo2Init = { 1, 3, 3, 11, 5, 17, 1, 253, 497, 209, 423, 3837, 5233, 3919, 4593, 0 }; + static ulong[] dim2922Kuo2Init = { 1, 3, 5, 11, 1, 61, 85, 61, 59, 637, 1017, 455, 5529, 7495, 16645, 0 }; + static ulong[] dim2923Kuo2Init = { 1, 1, 1, 5, 11, 11, 111, 151, 297, 289, 259, 1737, 4033, 5545, 22049, 0 }; + static ulong[] dim2924Kuo2Init = { 1, 1, 3, 9, 11, 33, 53, 43, 95, 859, 1113, 3201, 2705, 15009, 24945, 0 }; + static ulong[] dim2925Kuo2Init = { 1, 1, 7, 3, 7, 1, 59, 201, 127, 1023, 879, 1359, 4323, 11829, 32591, 0 }; + static ulong[] dim2926Kuo2Init = { 1, 1, 5, 13, 1, 15, 65, 3, 7, 373, 427, 3987, 3849, 16289, 3669, 0 }; + static ulong[] dim2927Kuo2Init = { 1, 1, 1, 3, 23, 21, 49, 215, 159, 577, 963, 3257, 5919, 4397, 14811, 0 }; + static ulong[] dim2928Kuo2Init = { 1, 3, 1, 9, 3, 43, 51, 49, 331, 717, 791, 279, 3305, 955, 14003, 0 }; + static ulong[] dim2929Kuo2Init = { 1, 1, 7, 7, 19, 45, 11, 249, 9, 221, 1525, 2413, 1807, 191, 3063, 0 }; + static ulong[] dim2930Kuo2Init = { 1, 3, 7, 1, 17, 33, 45, 201, 471, 683, 13, 3851, 7337, 2249, 8287, 0 }; + static ulong[] dim2931Kuo2Init = { 1, 3, 3, 1, 11, 21, 85, 141, 445, 691, 577, 2781, 3677, 11799, 25555, 0 }; + static ulong[] dim2932Kuo2Init = { 1, 1, 7, 1, 3, 27, 71, 245, 341, 69, 1355, 1289, 8165, 1159, 6001, 0 }; + static ulong[] dim2933Kuo2Init = { 1, 3, 3, 15, 11, 31, 31, 117, 193, 847, 1755, 1629, 6707, 5447, 15961, 0 }; + static ulong[] dim2934Kuo2Init = { 1, 1, 1, 1, 23, 13, 69, 107, 33, 731, 233, 2225, 201, 2667, 19935, 0 }; + static ulong[] dim2935Kuo2Init = { 1, 1, 1, 9, 31, 9, 25, 225, 373, 99, 1725, 3029, 5019, 10927, 541, 0 }; + static ulong[] dim2936Kuo2Init = { 1, 3, 3, 1, 29, 29, 37, 235, 135, 99, 599, 581, 7663, 1607, 7957, 0 }; + static ulong[] dim2937Kuo2Init = { 1, 3, 1, 11, 1, 31, 79, 33, 319, 341, 1701, 973, 5783, 3003, 15311, 0 }; + static ulong[] dim2938Kuo2Init = { 1, 3, 5, 15, 19, 11, 95, 51, 35, 887, 1505, 207, 7925, 1919, 30735, 0 }; + static ulong[] dim2939Kuo2Init = { 1, 3, 5, 7, 3, 27, 55, 41, 293, 519, 1885, 617, 321, 5911, 26813, 0 }; + static ulong[] dim2940Kuo2Init = { 1, 1, 7, 1, 7, 59, 9, 59, 291, 927, 1241, 1707, 3833, 13859, 3311, 0 }; + static ulong[] dim2941Kuo2Init = { 1, 3, 3, 13, 17, 61, 1, 155, 355, 943, 159, 2519, 7835, 14097, 671, 0 }; + static ulong[] dim2942Kuo2Init = { 1, 1, 3, 3, 29, 33, 59, 37, 363, 605, 365, 2431, 2529, 6449, 8847, 0 }; + static ulong[] dim2943Kuo2Init = { 1, 3, 7, 5, 1, 33, 87, 215, 465, 937, 2031, 421, 2535, 10017, 18395, 0 }; + static ulong[] dim2944Kuo2Init = { 1, 1, 7, 1, 27, 25, 7, 103, 501, 53, 1491, 99, 7433, 8251, 18849, 0 }; + static ulong[] dim2945Kuo2Init = { 1, 3, 1, 1, 31, 15, 7, 89, 145, 457, 7, 2821, 6595, 5893, 29049, 0 }; + static ulong[] dim2946Kuo2Init = { 1, 1, 3, 7, 15, 55, 127, 39, 493, 39, 1753, 643, 4005, 12041, 21811, 0 }; + static ulong[] dim2947Kuo2Init = { 1, 3, 3, 3, 17, 23, 79, 129, 181, 1017, 767, 1869, 4589, 4059, 15391, 0 }; + static ulong[] dim2948Kuo2Init = { 1, 1, 1, 3, 13, 17, 109, 253, 441, 361, 1641, 1647, 2139, 11629, 21061, 0 }; + static ulong[] dim2949Kuo2Init = { 1, 1, 3, 15, 5, 15, 43, 113, 455, 17, 353, 3431, 4871, 14777, 3257, 0 }; + static ulong[] dim2950Kuo2Init = { 1, 3, 1, 1, 7, 5, 49, 199, 295, 467, 1151, 2563, 1261, 1611, 8457, 0 }; + static ulong[] dim2951Kuo2Init = { 1, 3, 3, 9, 21, 1, 107, 71, 67, 271, 427, 673, 2093, 13255, 15941, 0 }; + static ulong[] dim2952Kuo2Init = { 1, 1, 7, 7, 19, 55, 127, 109, 101, 773, 1423, 2725, 2403, 1419, 2543, 0 }; + static ulong[] dim2953Kuo2Init = { 1, 3, 5, 9, 25, 49, 15, 77, 423, 723, 2033, 275, 1593, 3055, 12043, 0 }; + static ulong[] dim2954Kuo2Init = { 1, 3, 1, 9, 29, 27, 115, 5, 407, 797, 2041, 155, 2389, 9749, 31653, 0 }; + static ulong[] dim2955Kuo2Init = { 1, 3, 3, 7, 5, 29, 123, 139, 467, 377, 1853, 2769, 6523, 14195, 31539, 0 }; + static ulong[] dim2956Kuo2Init = { 1, 3, 3, 5, 25, 41, 103, 89, 469, 577, 1583, 1061, 7609, 4261, 17323, 0 }; + static ulong[] dim2957Kuo2Init = { 1, 1, 5, 5, 29, 37, 79, 179, 189, 185, 535, 3433, 6091, 4935, 21853, 0 }; + static ulong[] dim2958Kuo2Init = { 1, 1, 5, 13, 17, 63, 119, 191, 7, 353, 1591, 2881, 7857, 11355, 32427, 0 }; + static ulong[] dim2959Kuo2Init = { 1, 3, 1, 7, 13, 53, 21, 151, 499, 721, 1495, 2101, 7061, 12529, 16733, 0 }; + static ulong[] dim2960Kuo2Init = { 1, 1, 7, 1, 1, 1, 17, 141, 221, 875, 1569, 3165, 2583, 2803, 21001, 0 }; + static ulong[] dim2961Kuo2Init = { 1, 3, 3, 13, 7, 7, 99, 129, 381, 237, 159, 2359, 2223, 7465, 25437, 0 }; + static ulong[] dim2962Kuo2Init = { 1, 1, 3, 15, 31, 19, 103, 17, 475, 649, 279, 1321, 1751, 6957, 26055, 0 }; + static ulong[] dim2963Kuo2Init = { 1, 1, 1, 7, 5, 41, 3, 29, 23, 513, 1619, 291, 3949, 12117, 15175, 0 }; + static ulong[] dim2964Kuo2Init = { 1, 3, 1, 3, 13, 13, 73, 77, 373, 999, 1985, 161, 3223, 10873, 2967, 0 }; + static ulong[] dim2965Kuo2Init = { 1, 1, 5, 7, 27, 1, 47, 79, 463, 499, 37, 113, 3207, 6753, 13207, 0 }; + static ulong[] dim2966Kuo2Init = { 1, 1, 1, 9, 29, 33, 71, 225, 71, 943, 197, 3645, 7459, 5495, 22449, 0 }; + static ulong[] dim2967Kuo2Init = { 1, 1, 3, 9, 1, 21, 101, 31, 357, 689, 1081, 165, 621, 11277, 21773, 0 }; + static ulong[] dim2968Kuo2Init = { 1, 1, 7, 3, 13, 13, 21, 11, 87, 741, 765, 3299, 2741, 12825, 13383, 0 }; + static ulong[] dim2969Kuo2Init = { 1, 3, 3, 5, 5, 51, 49, 215, 427, 513, 621, 4067, 661, 12261, 6839, 0 }; + static ulong[] dim2970Kuo2Init = { 1, 1, 7, 9, 13, 9, 77, 17, 229, 139, 1053, 2061, 4915, 1047, 3621, 0 }; + static ulong[] dim2971Kuo2Init = { 1, 1, 3, 1, 9, 7, 125, 165, 301, 721, 493, 543, 4885, 5011, 24545, 0 }; + static ulong[] dim2972Kuo2Init = { 1, 3, 3, 11, 31, 11, 5, 61, 89, 35, 1551, 3031, 1175, 16223, 19433, 0 }; + static ulong[] dim2973Kuo2Init = { 1, 1, 1, 11, 27, 31, 115, 181, 487, 53, 795, 1789, 7343, 7821, 20469, 0 }; + static ulong[] dim2974Kuo2Init = { 1, 1, 5, 3, 7, 25, 89, 145, 107, 361, 171, 2407, 1159, 9341, 23877, 0 }; + static ulong[] dim2975Kuo2Init = { 1, 3, 3, 15, 27, 47, 31, 53, 53, 479, 1479, 427, 461, 7287, 15947, 0 }; + static ulong[] dim2976Kuo2Init = { 1, 3, 7, 5, 3, 11, 79, 151, 463, 315, 919, 1531, 2367, 5189, 6971, 0 }; + static ulong[] dim2977Kuo2Init = { 1, 1, 5, 9, 25, 17, 3, 111, 167, 365, 871, 355, 6763, 11889, 5531, 0 }; + static ulong[] dim2978Kuo2Init = { 1, 1, 1, 13, 25, 31, 25, 185, 63, 335, 177, 3017, 941, 11849, 6879, 0 }; + static ulong[] dim2979Kuo2Init = { 1, 1, 3, 7, 29, 13, 81, 121, 119, 807, 1647, 569, 23, 9045, 15513, 0 }; + static ulong[] dim2980Kuo2Init = { 1, 1, 1, 5, 5, 61, 115, 79, 115, 401, 383, 3679, 8159, 15199, 1531, 0 }; + static ulong[] dim2981Kuo2Init = { 1, 3, 3, 11, 17, 45, 17, 37, 175, 735, 849, 3597, 7253, 11863, 5215, 0 }; + static ulong[] dim2982Kuo2Init = { 1, 1, 1, 13, 7, 59, 99, 67, 223, 635, 1645, 3169, 2655, 15925, 14969, 0 }; + static ulong[] dim2983Kuo2Init = { 1, 3, 7, 15, 25, 17, 17, 25, 1, 799, 829, 2085, 7371, 6905, 11573, 0 }; + static ulong[] dim2984Kuo2Init = { 1, 1, 5, 1, 19, 33, 127, 31, 305, 523, 1141, 1171, 3707, 14687, 27897, 0 }; + static ulong[] dim2985Kuo2Init = { 1, 1, 1, 11, 3, 7, 95, 243, 373, 481, 1663, 1449, 687, 5643, 3265, 0 }; + static ulong[] dim2986Kuo2Init = { 1, 3, 7, 11, 17, 35, 45, 15, 201, 389, 1085, 1597, 5073, 5009, 6921, 0 }; + static ulong[] dim2987Kuo2Init = { 1, 1, 5, 1, 25, 33, 99, 57, 429, 153, 1663, 1797, 785, 7323, 24763, 0 }; + static ulong[] dim2988Kuo2Init = { 1, 1, 7, 15, 1, 63, 93, 225, 189, 297, 927, 2127, 7335, 5187, 12047, 0 }; + static ulong[] dim2989Kuo2Init = { 1, 1, 5, 9, 23, 47, 27, 113, 469, 649, 1135, 1363, 6777, 2047, 5759, 0 }; + static ulong[] dim2990Kuo2Init = { 1, 1, 3, 1, 9, 33, 21, 123, 309, 635, 1217, 1087, 4525, 10165, 18071, 0 }; + static ulong[] dim2991Kuo2Init = { 1, 3, 3, 3, 19, 49, 13, 217, 155, 945, 1987, 2425, 3891, 13831, 21777, 0 }; + static ulong[] dim2992Kuo2Init = { 1, 1, 3, 11, 25, 9, 75, 149, 241, 175, 799, 1285, 3265, 14103, 30147, 0 }; + static ulong[] dim2993Kuo2Init = { 1, 1, 1, 3, 13, 41, 87, 127, 179, 723, 1345, 667, 4155, 8037, 29583, 0 }; + static ulong[] dim2994Kuo2Init = { 1, 1, 1, 9, 15, 57, 67, 197, 131, 957, 1855, 2857, 2939, 6459, 5807, 0 }; + static ulong[] dim2995Kuo2Init = { 1, 3, 5, 5, 23, 39, 19, 95, 103, 961, 239, 1151, 1069, 10261, 6065, 0 }; + static ulong[] dim2996Kuo2Init = { 1, 3, 3, 15, 23, 29, 51, 121, 45, 561, 1317, 1777, 1325, 5833, 5765, 0 }; + static ulong[] dim2997Kuo2Init = { 1, 1, 5, 1, 31, 3, 67, 9, 453, 281, 525, 1751, 5771, 14257, 11869, 0 }; + static ulong[] dim2998Kuo2Init = { 1, 1, 7, 1, 13, 35, 33, 59, 117, 737, 929, 547, 4839, 7013, 28395, 0 }; + static ulong[] dim2999Kuo2Init = { 1, 3, 7, 15, 21, 41, 19, 15, 73, 377, 665, 3867, 6445, 13137, 995, 0 }; + static ulong[] dim3000Kuo2Init = { 1, 3, 7, 11, 13, 41, 53, 115, 435, 607, 871, 315, 6573, 6321, 10413, 0 }; + static ulong[] dim3001Kuo2Init = { 1, 3, 3, 3, 27, 31, 23, 7, 151, 923, 1903, 789, 5031, 10631, 777, 0 }; + static ulong[] dim3002Kuo2Init = { 1, 1, 7, 7, 9, 25, 17, 241, 19, 569, 1269, 1211, 3947, 11351, 31211, 0 }; + static ulong[] dim3003Kuo2Init = { 1, 1, 7, 13, 25, 31, 79, 111, 157, 483, 1787, 1201, 3491, 7943, 4879, 0 }; + static ulong[] dim3004Kuo2Init = { 1, 3, 7, 13, 19, 9, 31, 133, 125, 347, 15, 1287, 4355, 15357, 21391, 0 }; + static ulong[] dim3005Kuo2Init = { 1, 3, 3, 13, 1, 29, 63, 175, 279, 799, 1867, 2221, 6043, 307, 12475, 0 }; + static ulong[] dim3006Kuo2Init = { 1, 1, 7, 5, 23, 51, 93, 65, 209, 45, 409, 3405, 2053, 1399, 4423, 0 }; + static ulong[] dim3007Kuo2Init = { 1, 3, 7, 13, 23, 55, 21, 121, 281, 115, 85, 1941, 2609, 7041, 16267, 0 }; + static ulong[] dim3008Kuo2Init = { 1, 1, 3, 5, 25, 3, 113, 107, 37, 393, 737, 2671, 7405, 12191, 27679, 0 }; + static ulong[] dim3009Kuo2Init = { 1, 1, 3, 13, 15, 13, 33, 233, 25, 163, 1097, 2977, 6933, 14625, 29587, 0 }; + static ulong[] dim3010Kuo2Init = { 1, 1, 1, 1, 31, 13, 11, 25, 47, 589, 2035, 3595, 1299, 10171, 12695, 0 }; + static ulong[] dim3011Kuo2Init = { 1, 3, 5, 11, 31, 63, 97, 67, 381, 1021, 1029, 2869, 5779, 15451, 4291, 0 }; + static ulong[] dim3012Kuo2Init = { 1, 1, 1, 5, 9, 37, 9, 205, 169, 375, 1367, 1749, 8015, 1019, 12671, 0 }; + static ulong[] dim3013Kuo2Init = { 1, 3, 5, 7, 13, 29, 75, 53, 173, 535, 1795, 1705, 3601, 2487, 29851, 0 }; + static ulong[] dim3014Kuo2Init = { 1, 3, 3, 5, 5, 17, 81, 209, 229, 913, 959, 3597, 1515, 13401, 1531, 0 }; + static ulong[] dim3015Kuo2Init = { 1, 3, 3, 5, 29, 47, 5, 43, 117, 215, 1469, 3743, 6801, 10511, 11097, 0 }; + static ulong[] dim3016Kuo2Init = { 1, 1, 1, 9, 11, 5, 79, 247, 43, 853, 663, 1967, 355, 12263, 15877, 0 }; + static ulong[] dim3017Kuo2Init = { 1, 3, 3, 5, 25, 23, 105, 203, 255, 677, 1855, 527, 825, 433, 27701, 0 }; + static ulong[] dim3018Kuo2Init = { 1, 3, 3, 1, 13, 29, 119, 47, 331, 203, 1515, 1581, 1707, 10621, 19371, 0 }; + static ulong[] dim3019Kuo2Init = { 1, 1, 1, 13, 27, 15, 5, 255, 201, 861, 1809, 703, 1707, 8209, 5175, 0 }; + static ulong[] dim3020Kuo2Init = { 1, 3, 1, 13, 17, 61, 41, 143, 459, 291, 1747, 3605, 5545, 7441, 21493, 0 }; + static ulong[] dim3021Kuo2Init = { 1, 1, 3, 9, 21, 61, 77, 61, 79, 855, 57, 1543, 2755, 6249, 3387, 0 }; + static ulong[] dim3022Kuo2Init = { 1, 1, 3, 1, 17, 5, 117, 243, 153, 397, 693, 701, 2201, 11375, 23753, 0 }; + static ulong[] dim3023Kuo2Init = { 1, 1, 7, 7, 17, 25, 123, 239, 411, 633, 395, 3809, 1483, 15125, 22221, 0 }; + static ulong[] dim3024Kuo2Init = { 1, 3, 3, 3, 7, 45, 57, 51, 35, 463, 1287, 3101, 4213, 12931, 28639, 0 }; + static ulong[] dim3025Kuo2Init = { 1, 3, 1, 5, 13, 7, 103, 177, 277, 645, 833, 883, 3607, 13545, 6405, 0 }; + static ulong[] dim3026Kuo2Init = { 1, 3, 7, 11, 17, 3, 41, 161, 511, 483, 773, 147, 8113, 2203, 29711, 0 }; + static ulong[] dim3027Kuo2Init = { 1, 3, 1, 5, 13, 29, 79, 189, 351, 65, 93, 1195, 5205, 7989, 14085, 0 }; + static ulong[] dim3028Kuo2Init = { 1, 1, 3, 11, 13, 5, 13, 35, 231, 627, 1155, 1117, 3889, 3645, 25099, 0 }; + static ulong[] dim3029Kuo2Init = { 1, 3, 5, 3, 13, 63, 73, 83, 249, 559, 303, 3303, 5387, 15773, 16249, 0 }; + static ulong[] dim3030Kuo2Init = { 1, 1, 1, 9, 21, 23, 63, 153, 291, 951, 1409, 1333, 5385, 14621, 13763, 0 }; + static ulong[] dim3031Kuo2Init = { 1, 3, 1, 9, 1, 45, 13, 139, 437, 495, 773, 1401, 1599, 2555, 21579, 0 }; + static ulong[] dim3032Kuo2Init = { 1, 3, 1, 9, 11, 15, 51, 123, 393, 223, 1045, 1001, 6955, 12755, 5979, 0 }; + static ulong[] dim3033Kuo2Init = { 1, 1, 1, 7, 31, 31, 57, 127, 339, 133, 1489, 3055, 3051, 14931, 7757, 0 }; + static ulong[] dim3034Kuo2Init = { 1, 3, 5, 9, 1, 23, 97, 79, 491, 641, 295, 2597, 3857, 1889, 16295, 0 }; + static ulong[] dim3035Kuo2Init = { 1, 3, 7, 7, 21, 31, 111, 77, 199, 401, 1829, 925, 6023, 16161, 1783, 0 }; + static ulong[] dim3036Kuo2Init = { 1, 3, 3, 1, 5, 9, 53, 133, 347, 761, 841, 841, 3031, 10201, 27245, 0 }; + static ulong[] dim3037Kuo2Init = { 1, 1, 3, 13, 31, 35, 21, 19, 95, 861, 1385, 3607, 335, 14643, 20435, 0 }; + static ulong[] dim3038Kuo2Init = { 1, 3, 3, 13, 7, 61, 47, 225, 235, 333, 1923, 2961, 61, 14463, 12329, 0 }; + static ulong[] dim3039Kuo2Init = { 1, 3, 5, 5, 23, 35, 43, 175, 25, 573, 1253, 233, 5377, 3153, 24543, 0 }; + static ulong[] dim3040Kuo2Init = { 1, 1, 5, 11, 27, 55, 49, 239, 479, 475, 223, 2947, 89, 5517, 2925, 0 }; + static ulong[] dim3041Kuo2Init = { 1, 3, 5, 13, 31, 45, 11, 255, 251, 647, 1161, 847, 1175, 1219, 19735, 0 }; + static ulong[] dim3042Kuo2Init = { 1, 3, 5, 1, 13, 19, 13, 31, 309, 165, 49, 2281, 5607, 11987, 19255, 0 }; + static ulong[] dim3043Kuo2Init = { 1, 3, 7, 7, 15, 35, 51, 243, 119, 179, 1055, 3751, 4133, 14873, 12317, 0 }; + static ulong[] dim3044Kuo2Init = { 1, 3, 7, 13, 13, 47, 87, 169, 203, 27, 449, 2755, 5407, 11857, 291, 0 }; + static ulong[] dim3045Kuo2Init = { 1, 3, 3, 5, 29, 27, 1, 225, 493, 649, 1075, 2197, 2201, 14425, 18853, 0 }; + static ulong[] dim3046Kuo2Init = { 1, 3, 7, 1, 23, 21, 87, 237, 377, 575, 445, 1845, 6689, 10945, 17517, 0 }; + static ulong[] dim3047Kuo2Init = { 1, 1, 5, 5, 19, 43, 5, 177, 507, 395, 945, 2933, 1237, 10069, 15707, 0 }; + static ulong[] dim3048Kuo2Init = { 1, 1, 1, 9, 31, 61, 85, 45, 325, 915, 863, 839, 2335, 14631, 32479, 0 }; + static ulong[] dim3049Kuo2Init = { 1, 1, 3, 5, 11, 61, 47, 119, 439, 407, 203, 2841, 2205, 5335, 29721, 0 }; + static ulong[] dim3050Kuo2Init = { 1, 3, 5, 11, 9, 9, 63, 179, 315, 257, 901, 5, 4523, 11085, 23639, 0 }; + static ulong[] dim3051Kuo2Init = { 1, 1, 5, 1, 11, 9, 83, 109, 265, 601, 1457, 795, 509, 5605, 13235, 0 }; + static ulong[] dim3052Kuo2Init = { 1, 3, 3, 13, 31, 25, 59, 37, 25, 811, 657, 467, 1317, 3783, 27645, 0 }; + static ulong[] dim3053Kuo2Init = { 1, 1, 1, 9, 31, 51, 81, 255, 379, 575, 1401, 2341, 2411, 11893, 29599, 0 }; + static ulong[] dim3054Kuo2Init = { 1, 1, 5, 13, 3, 47, 79, 183, 111, 409, 1223, 1305, 1073, 9251, 28331, 0 }; + static ulong[] dim3055Kuo2Init = { 1, 3, 3, 7, 31, 9, 39, 125, 269, 999, 1427, 1845, 4427, 3825, 29289, 0 }; + static ulong[] dim3056Kuo2Init = { 1, 1, 3, 3, 17, 41, 3, 29, 9, 253, 925, 1279, 2263, 15521, 25455, 0 }; + static ulong[] dim3057Kuo2Init = { 1, 1, 7, 7, 31, 31, 53, 95, 225, 967, 893, 1315, 5683, 3311, 15259, 0 }; + static ulong[] dim3058Kuo2Init = { 1, 1, 7, 3, 31, 21, 123, 145, 117, 137, 499, 2381, 6467, 15677, 2079, 0 }; + static ulong[] dim3059Kuo2Init = { 1, 1, 3, 15, 3, 15, 17, 235, 463, 493, 1465, 1717, 6511, 5331, 10265, 0 }; + static ulong[] dim3060Kuo2Init = { 1, 3, 3, 1, 25, 41, 31, 225, 115, 199, 1831, 29, 5563, 2697, 26689, 0 }; + static ulong[] dim3061Kuo2Init = { 1, 3, 7, 15, 7, 23, 29, 79, 35, 493, 997, 2139, 3813, 9915, 16693, 0 }; + static ulong[] dim3062Kuo2Init = { 1, 1, 7, 13, 13, 59, 71, 127, 41, 271, 1513, 2239, 6739, 6351, 11331, 0 }; + static ulong[] dim3063Kuo2Init = { 1, 3, 5, 1, 23, 63, 109, 225, 413, 277, 927, 1781, 843, 5959, 16655, 0 }; + static ulong[] dim3064Kuo2Init = { 1, 3, 5, 13, 9, 55, 91, 143, 401, 695, 1857, 205, 3617, 11847, 27339, 0 }; + static ulong[] dim3065Kuo2Init = { 1, 1, 3, 1, 21, 41, 5, 1, 207, 247, 1269, 3071, 8045, 8711, 3595, 0 }; + static ulong[] dim3066Kuo2Init = { 1, 3, 7, 15, 5, 23, 29, 119, 435, 961, 333, 2337, 3469, 6363, 29145, 0 }; + static ulong[] dim3067Kuo2Init = { 1, 3, 5, 5, 21, 19, 65, 177, 309, 115, 707, 1659, 941, 6825, 3595, 0 }; + static ulong[] dim3068Kuo2Init = { 1, 1, 1, 5, 29, 5, 113, 15, 13, 897, 1535, 3453, 3539, 3937, 22647, 0 }; + static ulong[] dim3069Kuo2Init = { 1, 1, 3, 9, 13, 41, 45, 11, 259, 127, 1421, 195, 4555, 11643, 30239, 0 }; + static ulong[] dim3070Kuo2Init = { 1, 3, 3, 15, 5, 17, 115, 89, 183, 729, 1655, 3599, 1443, 11799, 29777, 0 }; + static ulong[] dim3071Kuo2Init = { 1, 3, 3, 15, 19, 57, 61, 3, 53, 221, 799, 3243, 5255, 3271, 8677, 0 }; + static ulong[] dim3072Kuo2Init = { 1, 3, 1, 5, 23, 45, 103, 173, 453, 111, 1145, 891, 4989, 3195, 20129, 0 }; + static ulong[] dim3073Kuo2Init = { 1, 3, 1, 13, 13, 25, 71, 71, 125, 753, 397, 613, 1641, 2611, 1879, 0 }; + static ulong[] dim3074Kuo2Init = { 1, 1, 1, 15, 23, 59, 25, 199, 285, 161, 225, 4039, 5427, 13711, 23643, 0 }; + static ulong[] dim3075Kuo2Init = { 1, 1, 7, 13, 25, 9, 119, 121, 369, 811, 1857, 2227, 5711, 2761, 23033, 0 }; + static ulong[] dim3076Kuo2Init = { 1, 1, 3, 15, 27, 43, 75, 231, 221, 869, 603, 537, 3679, 15963, 27183, 0 }; + static ulong[] dim3077Kuo2Init = { 1, 1, 5, 3, 9, 35, 33, 39, 383, 415, 1769, 3837, 1479, 3411, 20917, 0 }; + static ulong[] dim3078Kuo2Init = { 1, 1, 5, 15, 7, 47, 119, 105, 31, 79, 229, 135, 1509, 1571, 24355, 0 }; + static ulong[] dim3079Kuo2Init = { 1, 1, 5, 7, 7, 15, 99, 79, 65, 869, 1781, 2111, 2405, 1901, 8419, 0 }; + static ulong[] dim3080Kuo2Init = { 1, 1, 3, 15, 7, 59, 13, 211, 439, 543, 755, 2177, 971, 6045, 24943, 0 }; + static ulong[] dim3081Kuo2Init = { 1, 1, 3, 7, 13, 25, 89, 71, 453, 71, 1205, 1419, 971, 11139, 25075, 0 }; + static ulong[] dim3082Kuo2Init = { 1, 3, 5, 3, 7, 63, 21, 17, 179, 749, 915, 3977, 5399, 11385, 13825, 0 }; + static ulong[] dim3083Kuo2Init = { 1, 1, 5, 9, 19, 49, 77, 47, 351, 815, 1925, 559, 4503, 8095, 3115, 0 }; + static ulong[] dim3084Kuo2Init = { 1, 3, 1, 9, 13, 61, 79, 245, 509, 691, 387, 2067, 1493, 10783, 31911, 0 }; + static ulong[] dim3085Kuo2Init = { 1, 3, 1, 11, 31, 27, 117, 55, 93, 389, 1299, 573, 6883, 10449, 19779, 0 }; + static ulong[] dim3086Kuo2Init = { 1, 3, 3, 7, 15, 27, 5, 207, 215, 773, 1989, 2341, 2101, 10585, 6675, 0 }; + static ulong[] dim3087Kuo2Init = { 1, 3, 3, 15, 19, 37, 93, 127, 233, 49, 557, 1683, 7299, 5399, 21571, 0 }; + static ulong[] dim3088Kuo2Init = { 1, 3, 1, 15, 15, 21, 95, 81, 167, 113, 245, 3607, 2007, 1847, 2317, 0 }; + static ulong[] dim3089Kuo2Init = { 1, 3, 3, 9, 21, 13, 1, 203, 361, 695, 539, 3927, 4149, 249, 8425, 0 }; + static ulong[] dim3090Kuo2Init = { 1, 3, 3, 11, 1, 61, 25, 159, 215, 235, 1561, 99, 2965, 13035, 11673, 0 }; + static ulong[] dim3091Kuo2Init = { 1, 3, 1, 1, 5, 27, 13, 83, 457, 57, 995, 2163, 257, 12671, 18391, 0 }; + static ulong[] dim3092Kuo2Init = { 1, 1, 5, 13, 23, 25, 69, 15, 53, 253, 1789, 3415, 3667, 3255, 26871, 0 }; + static ulong[] dim3093Kuo2Init = { 1, 1, 3, 3, 9, 13, 25, 81, 247, 483, 921, 649, 4759, 15037, 4923, 0 }; + static ulong[] dim3094Kuo2Init = { 1, 3, 5, 1, 5, 1, 111, 179, 329, 395, 1661, 2647, 6487, 11109, 15465, 0 }; + static ulong[] dim3095Kuo2Init = { 1, 1, 3, 7, 27, 27, 13, 123, 225, 181, 1205, 2703, 1753, 2513, 1671, 0 }; + static ulong[] dim3096Kuo2Init = { 1, 3, 7, 9, 23, 51, 1, 9, 233, 709, 257, 999, 5761, 3281, 8083, 0 }; + static ulong[] dim3097Kuo2Init = { 1, 1, 7, 11, 31, 33, 29, 83, 251, 1021, 1395, 447, 4071, 13257, 5821, 0 }; + static ulong[] dim3098Kuo2Init = { 1, 1, 5, 1, 11, 19, 67, 35, 371, 425, 613, 1065, 269, 3895, 19507, 0 }; + static ulong[] dim3099Kuo2Init = { 1, 3, 5, 1, 1, 53, 79, 229, 489, 373, 1195, 3221, 7425, 2731, 16607, 0 }; + static ulong[] dim3100Kuo2Init = { 1, 1, 3, 3, 3, 11, 49, 241, 269, 727, 549, 2463, 6983, 13067, 19829, 0 }; + static ulong[] dim3101Kuo2Init = { 1, 3, 5, 15, 13, 41, 53, 215, 131, 363, 595, 2777, 3929, 1305, 12725, 0 }; + static ulong[] dim3102Kuo2Init = { 1, 3, 3, 1, 5, 41, 87, 243, 485, 401, 1599, 397, 4207, 3707, 28949, 0 }; + static ulong[] dim3103Kuo2Init = { 1, 1, 1, 3, 7, 5, 31, 59, 25, 391, 1419, 2355, 953, 1179, 22605, 0 }; + static ulong[] dim3104Kuo2Init = { 1, 3, 3, 5, 13, 47, 3, 167, 25, 381, 341, 1999, 3423, 4465, 19517, 0 }; + static ulong[] dim3105Kuo2Init = { 1, 1, 3, 3, 21, 55, 93, 93, 243, 67, 1743, 139, 5783, 2261, 22411, 0 }; + static ulong[] dim3106Kuo2Init = { 1, 1, 1, 15, 25, 19, 1, 247, 325, 641, 347, 1095, 7301, 7079, 25403, 0 }; + static ulong[] dim3107Kuo2Init = { 1, 3, 5, 13, 29, 53, 23, 229, 425, 311, 1159, 2241, 105, 11165, 28737, 0 }; + static ulong[] dim3108Kuo2Init = { 1, 1, 7, 9, 31, 23, 3, 191, 119, 113, 543, 1119, 3375, 13605, 27753, 0 }; + static ulong[] dim3109Kuo2Init = { 1, 1, 7, 15, 1, 49, 23, 193, 165, 869, 509, 1017, 1045, 13709, 16293, 0 }; + static ulong[] dim3110Kuo2Init = { 1, 1, 1, 13, 3, 15, 25, 239, 423, 359, 409, 1075, 2629, 2291, 20293, 0 }; + static ulong[] dim3111Kuo2Init = { 1, 1, 3, 15, 27, 35, 67, 83, 11, 1, 1129, 1917, 1475, 14831, 13161, 0 }; + static ulong[] dim3112Kuo2Init = { 1, 1, 7, 11, 27, 21, 117, 191, 321, 721, 929, 2293, 2257, 9259, 4849, 0 }; + static ulong[] dim3113Kuo2Init = { 1, 1, 1, 1, 25, 61, 21, 211, 491, 127, 1423, 2291, 5121, 14065, 14835, 0 }; + static ulong[] dim3114Kuo2Init = { 1, 1, 7, 15, 17, 15, 81, 221, 319, 1015, 1643, 665, 7429, 7829, 5369, 0 }; + static ulong[] dim3115Kuo2Init = { 1, 3, 7, 13, 31, 45, 77, 103, 79, 891, 43, 1561, 295, 3977, 17699, 0 }; + static ulong[] dim3116Kuo2Init = { 1, 3, 5, 1, 11, 19, 105, 1, 179, 699, 655, 3125, 5851, 9577, 29513, 0 }; + static ulong[] dim3117Kuo2Init = { 1, 3, 7, 13, 1, 15, 105, 239, 113, 917, 219, 1857, 801, 11703, 20955, 0 }; + static ulong[] dim3118Kuo2Init = { 1, 1, 1, 9, 3, 35, 69, 43, 133, 455, 471, 1785, 4659, 6325, 3183, 0 }; + static ulong[] dim3119Kuo2Init = { 1, 1, 5, 3, 7, 57, 127, 13, 151, 359, 135, 2445, 1795, 3257, 32305, 0 }; + static ulong[] dim3120Kuo2Init = { 1, 1, 3, 9, 11, 43, 51, 109, 323, 789, 1181, 1577, 4445, 1623, 28489, 0 }; + static ulong[] dim3121Kuo2Init = { 1, 3, 7, 5, 19, 55, 71, 65, 35, 605, 165, 1573, 1429, 7123, 1967, 0 }; + static ulong[] dim3122Kuo2Init = { 1, 1, 1, 15, 15, 27, 87, 67, 503, 833, 1841, 2639, 5629, 5511, 12393, 0 }; + static ulong[] dim3123Kuo2Init = { 1, 3, 1, 11, 9, 59, 85, 59, 289, 679, 1957, 399, 7949, 4735, 709, 0 }; + static ulong[] dim3124Kuo2Init = { 1, 3, 5, 7, 3, 37, 109, 3, 33, 971, 123, 1585, 3273, 8421, 20903, 0 }; + static ulong[] dim3125Kuo2Init = { 1, 1, 1, 3, 17, 37, 99, 3, 405, 579, 755, 1337, 3649, 8217, 11011, 0 }; + static ulong[] dim3126Kuo2Init = { 1, 1, 7, 9, 25, 59, 87, 115, 237, 749, 355, 1781, 5199, 7019, 10615, 0 }; + static ulong[] dim3127Kuo2Init = { 1, 1, 3, 11, 23, 5, 105, 129, 453, 813, 1423, 2703, 6241, 14969, 22943, 0 }; + static ulong[] dim3128Kuo2Init = { 1, 1, 5, 7, 21, 41, 89, 129, 473, 139, 595, 925, 3915, 12059, 19675, 0 }; + static ulong[] dim3129Kuo2Init = { 1, 1, 5, 3, 17, 19, 83, 19, 191, 757, 1185, 1849, 3403, 779, 24773, 0 }; + static ulong[] dim3130Kuo2Init = { 1, 1, 5, 11, 13, 31, 121, 211, 357, 487, 829, 1215, 1, 15103, 10835, 0 }; + static ulong[] dim3131Kuo2Init = { 1, 1, 5, 15, 1, 15, 105, 137, 169, 295, 993, 261, 6787, 16339, 20307, 0 }; + static ulong[] dim3132Kuo2Init = { 1, 1, 5, 15, 21, 11, 53, 149, 443, 285, 371, 2541, 7041, 5745, 12127, 0 }; + static ulong[] dim3133Kuo2Init = { 1, 3, 5, 1, 9, 23, 89, 77, 337, 623, 329, 1021, 2013, 11023, 27045, 0 }; + static ulong[] dim3134Kuo2Init = { 1, 1, 7, 7, 1, 11, 35, 67, 93, 121, 1155, 1063, 4997, 9567, 24023, 0 }; + static ulong[] dim3135Kuo2Init = { 1, 1, 7, 7, 3, 33, 119, 243, 423, 615, 721, 3057, 7873, 9329, 20783, 0 }; + static ulong[] dim3136Kuo2Init = { 1, 3, 3, 15, 3, 23, 41, 121, 111, 483, 1607, 181, 895, 12923, 21707, 0 }; + static ulong[] dim3137Kuo2Init = { 1, 3, 7, 5, 9, 63, 65, 87, 235, 915, 1569, 3421, 1373, 2159, 353, 0 }; + static ulong[] dim3138Kuo2Init = { 1, 1, 7, 7, 29, 3, 35, 193, 95, 977, 1405, 23, 1135, 5047, 16429, 0 }; + static ulong[] dim3139Kuo2Init = { 1, 1, 7, 3, 7, 57, 123, 111, 33, 781, 613, 3423, 4701, 8727, 22665, 0 }; + static ulong[] dim3140Kuo2Init = { 1, 1, 1, 11, 13, 43, 101, 83, 447, 503, 1955, 2125, 4469, 14937, 24067, 0 }; + static ulong[] dim3141Kuo2Init = { 1, 1, 5, 15, 7, 41, 115, 17, 335, 497, 1753, 1131, 4623, 11483, 5181, 0 }; + static ulong[] dim3142Kuo2Init = { 1, 1, 7, 9, 19, 37, 1, 89, 117, 211, 1203, 2469, 5989, 11429, 31597, 0 }; + static ulong[] dim3143Kuo2Init = { 1, 3, 3, 11, 3, 7, 125, 97, 203, 935, 533, 2607, 6075, 12995, 9997, 0 }; + static ulong[] dim3144Kuo2Init = { 1, 1, 7, 1, 27, 25, 53, 99, 243, 729, 1521, 875, 2363, 3309, 22621, 0 }; + static ulong[] dim3145Kuo2Init = { 1, 3, 3, 1, 21, 7, 79, 105, 363, 227, 9, 2445, 3021, 15177, 19029, 0 }; + static ulong[] dim3146Kuo2Init = { 1, 3, 7, 7, 13, 53, 55, 21, 137, 953, 1583, 3439, 2995, 4447, 19881, 0 }; + static ulong[] dim3147Kuo2Init = { 1, 1, 7, 11, 29, 21, 83, 195, 387, 133, 1135, 1425, 4655, 9171, 19217, 0 }; + static ulong[] dim3148Kuo2Init = { 1, 3, 5, 7, 3, 19, 45, 249, 451, 797, 693, 3511, 7213, 12851, 31915, 0 }; + static ulong[] dim3149Kuo2Init = { 1, 3, 3, 15, 17, 35, 119, 153, 493, 815, 1621, 2305, 7963, 6405, 6253, 0 }; + static ulong[] dim3150Kuo2Init = { 1, 1, 3, 15, 19, 23, 111, 223, 469, 1015, 799, 1453, 7639, 2307, 20595, 0 }; + static ulong[] dim3151Kuo2Init = { 1, 1, 5, 9, 9, 49, 33, 233, 3, 531, 1723, 845, 3585, 13993, 11955, 0 }; + static ulong[] dim3152Kuo2Init = { 1, 1, 7, 7, 1, 7, 3, 217, 191, 1, 2013, 3143, 5919, 3285, 10733, 0 }; + static ulong[] dim3153Kuo2Init = { 1, 1, 3, 15, 25, 9, 93, 127, 471, 51, 1227, 341, 3455, 11015, 21427, 0 }; + static ulong[] dim3154Kuo2Init = { 1, 1, 5, 9, 23, 45, 9, 1, 445, 927, 661, 829, 411, 13531, 30903, 0 }; + static ulong[] dim3155Kuo2Init = { 1, 3, 3, 5, 21, 25, 17, 225, 43, 209, 659, 3681, 3281, 10135, 6121, 0 }; + static ulong[] dim3156Kuo2Init = { 1, 3, 1, 7, 17, 33, 103, 209, 187, 759, 617, 2971, 3563, 12925, 23503, 0 }; + static ulong[] dim3157Kuo2Init = { 1, 3, 5, 13, 21, 13, 35, 65, 507, 95, 695, 961, 7589, 9633, 29065, 0 }; + static ulong[] dim3158Kuo2Init = { 1, 3, 5, 5, 13, 17, 11, 145, 11, 115, 1449, 2361, 2959, 6713, 15345, 0 }; + static ulong[] dim3159Kuo2Init = { 1, 1, 3, 9, 21, 19, 15, 7, 303, 995, 1245, 349, 4117, 10993, 20627, 0 }; + static ulong[] dim3160Kuo2Init = { 1, 3, 1, 3, 1, 9, 21, 43, 259, 725, 1735, 1515, 3465, 10867, 14895, 0 }; + static ulong[] dim3161Kuo2Init = { 1, 1, 1, 3, 7, 25, 57, 29, 435, 663, 383, 1197, 981, 4943, 24527, 0 }; + static ulong[] dim3162Kuo2Init = { 1, 1, 3, 13, 3, 29, 43, 149, 351, 293, 1549, 3177, 6771, 7291, 23227, 0 }; + static ulong[] dim3163Kuo2Init = { 1, 1, 1, 9, 29, 53, 9, 43, 369, 763, 1269, 595, 6559, 13799, 27751, 0 }; + static ulong[] dim3164Kuo2Init = { 1, 1, 3, 3, 7, 53, 79, 167, 121, 761, 1015, 1299, 1523, 55, 4431, 0 }; + static ulong[] dim3165Kuo2Init = { 1, 3, 1, 15, 19, 9, 103, 17, 121, 621, 765, 2225, 4123, 815, 4305, 0 }; + static ulong[] dim3166Kuo2Init = { 1, 3, 7, 7, 29, 59, 43, 73, 505, 755, 617, 2113, 5605, 11887, 10211, 0 }; + static ulong[] dim3167Kuo2Init = { 1, 1, 5, 15, 23, 47, 27, 241, 287, 649, 1601, 2461, 7851, 7901, 24305, 0 }; + static ulong[] dim3168Kuo2Init = { 1, 3, 1, 3, 9, 31, 43, 103, 227, 381, 813, 3871, 2293, 5317, 4907, 0 }; + static ulong[] dim3169Kuo2Init = { 1, 3, 7, 1, 29, 41, 49, 75, 389, 799, 1283, 1823, 6907, 11715, 24101, 0 }; + static ulong[] dim3170Kuo2Init = { 1, 1, 3, 9, 1, 17, 53, 61, 133, 485, 317, 1779, 2437, 6195, 4745, 0 }; + static ulong[] dim3171Kuo2Init = { 1, 3, 7, 11, 1, 55, 79, 147, 511, 29, 495, 1145, 677, 8581, 9491, 0 }; + static ulong[] dim3172Kuo2Init = { 1, 1, 1, 7, 15, 23, 51, 243, 139, 605, 2035, 1039, 1135, 10747, 28225, 0 }; + static ulong[] dim3173Kuo2Init = { 1, 3, 3, 1, 15, 5, 121, 73, 403, 861, 1587, 2985, 2217, 1969, 10459, 0 }; + static ulong[] dim3174Kuo2Init = { 1, 1, 3, 3, 15, 45, 123, 235, 85, 973, 915, 2217, 2405, 4473, 8119, 0 }; + static ulong[] dim3175Kuo2Init = { 1, 1, 3, 3, 29, 29, 9, 47, 173, 121, 861, 1081, 917, 9757, 25923, 0 }; + static ulong[] dim3176Kuo2Init = { 1, 1, 3, 7, 25, 59, 57, 35, 291, 529, 1069, 4037, 4865, 5047, 1133, 0 }; + static ulong[] dim3177Kuo2Init = { 1, 1, 5, 7, 5, 25, 49, 171, 363, 427, 1807, 1903, 6455, 12201, 12043, 0 }; + static ulong[] dim3178Kuo2Init = { 1, 1, 3, 3, 23, 13, 77, 61, 415, 307, 1237, 2785, 1133, 14337, 25755, 0 }; + static ulong[] dim3179Kuo2Init = { 1, 1, 1, 3, 3, 49, 95, 117, 409, 641, 393, 3205, 5047, 4795, 22773, 0 }; + static ulong[] dim3180Kuo2Init = { 1, 3, 7, 5, 15, 25, 39, 37, 15, 735, 1107, 2467, 8037, 6395, 26043, 0 }; + static ulong[] dim3181Kuo2Init = { 1, 1, 3, 7, 15, 51, 53, 211, 223, 165, 217, 3519, 6973, 823, 15733, 0 }; + static ulong[] dim3182Kuo2Init = { 1, 1, 3, 11, 25, 15, 57, 9, 373, 445, 369, 2199, 2793, 12279, 7413, 0 }; + static ulong[] dim3183Kuo2Init = { 1, 1, 3, 1, 29, 13, 37, 91, 429, 5, 467, 813, 2375, 10467, 10373, 0 }; + static ulong[] dim3184Kuo2Init = { 1, 1, 7, 15, 1, 21, 65, 145, 341, 839, 467, 1029, 3127, 11519, 6711, 0 }; + static ulong[] dim3185Kuo2Init = { 1, 1, 3, 11, 29, 55, 115, 65, 501, 375, 1669, 2227, 125, 8059, 15489, 0 }; + static ulong[] dim3186Kuo2Init = { 1, 3, 1, 3, 7, 9, 71, 179, 203, 1017, 107, 49, 1093, 4847, 14383, 0 }; + static ulong[] dim3187Kuo2Init = { 1, 3, 7, 13, 9, 57, 75, 139, 67, 587, 1681, 1717, 459, 7835, 317, 0 }; + static ulong[] dim3188Kuo2Init = { 1, 3, 1, 1, 13, 15, 37, 123, 233, 467, 1425, 2119, 2589, 10087, 31997, 0 }; + static ulong[] dim3189Kuo2Init = { 1, 3, 7, 9, 29, 53, 119, 19, 387, 225, 1845, 2849, 181, 1991, 10323, 0 }; + static ulong[] dim3190Kuo2Init = { 1, 3, 5, 11, 1, 61, 5, 221, 389, 595, 499, 2103, 5967, 4677, 17551, 0 }; + static ulong[] dim3191Kuo2Init = { 1, 1, 7, 5, 31, 9, 63, 121, 505, 997, 939, 7, 7809, 11337, 11825, 0 }; + static ulong[] dim3192Kuo2Init = { 1, 1, 1, 7, 27, 35, 99, 145, 401, 887, 657, 1023, 6215, 15775, 13477, 0 }; + static ulong[] dim3193Kuo2Init = { 1, 3, 3, 15, 7, 39, 35, 63, 395, 621, 1551, 2061, 7817, 6159, 13765, 0 }; + static ulong[] dim3194Kuo2Init = { 1, 1, 7, 3, 13, 5, 17, 19, 469, 541, 707, 1697, 699, 5031, 4121, 0 }; + static ulong[] dim3195Kuo2Init = { 1, 3, 3, 1, 31, 7, 21, 15, 137, 151, 599, 857, 6267, 4725, 20317, 0 }; + static ulong[] dim3196Kuo2Init = { 1, 1, 7, 9, 23, 13, 59, 169, 73, 517, 1209, 2063, 1881, 849, 3263, 0 }; + static ulong[] dim3197Kuo2Init = { 1, 1, 1, 9, 3, 61, 115, 75, 161, 395, 1889, 1229, 6153, 597, 5667, 0 }; + static ulong[] dim3198Kuo2Init = { 1, 1, 3, 11, 5, 31, 37, 163, 469, 237, 91, 3531, 7197, 12673, 13741, 0 }; + static ulong[] dim3199Kuo2Init = { 1, 1, 3, 1, 17, 61, 31, 29, 3, 855, 1703, 2091, 2791, 1963, 7385, 0 }; + static ulong[] dim3200Kuo2Init = { 1, 1, 1, 5, 13, 53, 105, 239, 143, 199, 2003, 4005, 1911, 4965, 31675, 0 }; + static ulong[] dim3201Kuo2Init = { 1, 3, 7, 3, 7, 37, 73, 85, 219, 165, 887, 243, 117, 767, 5519, 0 }; + static ulong[] dim3202Kuo2Init = { 1, 1, 7, 9, 21, 3, 89, 13, 261, 835, 529, 3851, 4905, 2881, 3889, 0 }; + static ulong[] dim3203Kuo2Init = { 1, 1, 7, 3, 15, 41, 21, 89, 137, 959, 839, 4087, 1689, 11347, 17701, 0 }; + static ulong[] dim3204Kuo2Init = { 1, 3, 7, 3, 15, 17, 63, 31, 493, 509, 1079, 3223, 7649, 4377, 20291, 0 }; + static ulong[] dim3205Kuo2Init = { 1, 3, 5, 5, 5, 63, 101, 83, 431, 201, 1965, 1227, 2161, 14661, 2027, 0 }; + static ulong[] dim3206Kuo2Init = { 1, 1, 7, 3, 29, 19, 81, 245, 125, 795, 181, 4017, 4061, 12909, 30591, 0 }; + static ulong[] dim3207Kuo2Init = { 1, 1, 5, 11, 19, 63, 49, 205, 485, 789, 1123, 715, 6553, 5637, 7977, 0 }; + static ulong[] dim3208Kuo2Init = { 1, 3, 3, 7, 13, 63, 113, 63, 187, 515, 725, 3583, 1699, 5165, 21823, 0 }; + static ulong[] dim3209Kuo2Init = { 1, 3, 1, 3, 27, 17, 17, 241, 205, 593, 697, 4023, 7603, 15421, 9679, 0 }; + static ulong[] dim3210Kuo2Init = { 1, 3, 1, 1, 3, 15, 39, 209, 53, 405, 601, 3315, 5487, 12163, 14741, 0 }; + static ulong[] dim3211Kuo2Init = { 1, 1, 3, 13, 31, 9, 9, 159, 187, 307, 1115, 381, 7763, 4231, 2387, 0 }; + static ulong[] dim3212Kuo2Init = { 1, 1, 7, 13, 1, 41, 17, 101, 321, 473, 515, 1959, 7589, 9323, 23947, 0 }; + static ulong[] dim3213Kuo2Init = { 1, 3, 3, 9, 21, 55, 55, 137, 115, 791, 1411, 3543, 8173, 14403, 28019, 0 }; + static ulong[] dim3214Kuo2Init = { 1, 3, 3, 7, 29, 35, 83, 119, 243, 561, 423, 2435, 7613, 1081, 29911, 0 }; + static ulong[] dim3215Kuo2Init = { 1, 3, 1, 15, 13, 21, 9, 205, 3, 901, 1305, 4015, 4045, 11685, 489, 0 }; + static ulong[] dim3216Kuo2Init = { 1, 1, 5, 13, 27, 57, 73, 173, 391, 259, 757, 3177, 3767, 5251, 12381, 0 }; + static ulong[] dim3217Kuo2Init = { 1, 1, 3, 1, 3, 15, 121, 1, 85, 795, 1465, 1247, 5703, 3399, 28519, 0 }; + static ulong[] dim3218Kuo2Init = { 1, 1, 1, 7, 27, 7, 41, 147, 277, 317, 1161, 2205, 1845, 12379, 9121, 0 }; + static ulong[] dim3219Kuo2Init = { 1, 3, 3, 9, 5, 59, 107, 115, 13, 469, 595, 3979, 7563, 521, 6407, 0 }; + static ulong[] dim3220Kuo2Init = { 1, 1, 7, 9, 31, 43, 107, 107, 49, 67, 475, 1371, 3205, 2035, 6349, 0 }; + static ulong[] dim3221Kuo2Init = { 1, 3, 1, 3, 19, 33, 73, 171, 493, 473, 1963, 2453, 2833, 6847, 9899, 0 }; + static ulong[] dim3222Kuo2Init = { 1, 3, 1, 1, 31, 57, 33, 201, 431, 623, 327, 481, 2377, 6533, 30339, 0 }; + static ulong[] dim3223Kuo2Init = { 1, 1, 7, 1, 31, 11, 47, 183, 209, 661, 357, 3809, 4129, 5465, 29141, 0 }; + static ulong[] dim3224Kuo2Init = { 1, 1, 3, 3, 19, 43, 99, 45, 471, 983, 627, 2397, 753, 6735, 24945, 0 }; + static ulong[] dim3225Kuo2Init = { 1, 3, 5, 11, 3, 31, 127, 255, 175, 549, 1743, 3417, 3753, 11497, 5273, 0 }; + static ulong[] dim3226Kuo2Init = { 1, 3, 5, 7, 5, 17, 77, 99, 109, 973, 93, 1287, 1781, 6055, 6987, 0 }; + static ulong[] dim3227Kuo2Init = { 1, 1, 7, 5, 17, 31, 23, 231, 63, 315, 1119, 2175, 5807, 6497, 12991, 0 }; + static ulong[] dim3228Kuo2Init = { 1, 3, 5, 1, 25, 17, 51, 81, 253, 725, 1351, 1941, 3893, 13059, 27373, 0 }; + static ulong[] dim3229Kuo2Init = { 1, 3, 3, 7, 17, 43, 35, 151, 127, 587, 229, 2253, 4299, 10269, 169, 0 }; + static ulong[] dim3230Kuo2Init = { 1, 1, 5, 11, 15, 11, 65, 31, 263, 897, 1345, 3011, 6767, 15851, 16801, 0 }; + static ulong[] dim3231Kuo2Init = { 1, 3, 3, 15, 15, 1, 119, 235, 57, 339, 503, 2633, 1307, 14387, 28759, 0 }; + static ulong[] dim3232Kuo2Init = { 1, 3, 1, 5, 5, 57, 111, 117, 273, 703, 1363, 1579, 97, 15323, 24897, 0 }; + static ulong[] dim3233Kuo2Init = { 1, 3, 5, 13, 23, 29, 43, 171, 347, 651, 869, 3623, 1643, 14647, 16271, 0 }; + static ulong[] dim3234Kuo2Init = { 1, 3, 5, 15, 11, 35, 41, 121, 117, 67, 1649, 1201, 213, 13013, 20403, 0 }; + static ulong[] dim3235Kuo2Init = { 1, 3, 5, 7, 3, 33, 61, 97, 439, 371, 117, 1341, 6513, 11043, 10055, 0 }; + static ulong[] dim3236Kuo2Init = { 1, 3, 3, 1, 25, 9, 25, 13, 121, 593, 1879, 2487, 385, 4341, 11515, 0 }; + static ulong[] dim3237Kuo2Init = { 1, 3, 1, 7, 11, 23, 65, 181, 205, 381, 1749, 3837, 5343, 12389, 27243, 0 }; + static ulong[] dim3238Kuo2Init = { 1, 3, 3, 15, 19, 9, 11, 185, 109, 49, 311, 1225, 7445, 14459, 12631, 0 }; + static ulong[] dim3239Kuo2Init = { 1, 3, 7, 7, 27, 3, 87, 179, 467, 823, 1641, 189, 3489, 3203, 10447, 0 }; + static ulong[] dim3240Kuo2Init = { 1, 3, 5, 3, 5, 15, 117, 139, 39, 497, 1137, 1193, 2281, 12945, 1329, 0 }; + static ulong[] dim3241Kuo2Init = { 1, 3, 7, 15, 21, 9, 111, 115, 461, 987, 1091, 2363, 5453, 3929, 26887, 0 }; + static ulong[] dim3242Kuo2Init = { 1, 1, 1, 11, 19, 25, 113, 65, 301, 491, 1679, 4007, 4709, 4547, 25155, 0 }; + static ulong[] dim3243Kuo2Init = { 1, 3, 1, 15, 29, 23, 87, 209, 471, 247, 633, 2533, 1077, 5079, 10311, 0 }; + static ulong[] dim3244Kuo2Init = { 1, 3, 3, 1, 27, 21, 27, 57, 69, 883, 145, 1559, 6751, 873, 28941, 0 }; + static ulong[] dim3245Kuo2Init = { 1, 1, 7, 5, 23, 63, 113, 57, 243, 133, 1159, 3837, 4781, 6029, 391, 0 }; + static ulong[] dim3246Kuo2Init = { 1, 1, 1, 7, 27, 47, 33, 211, 317, 891, 1955, 3201, 803, 1645, 26669, 0 }; + static ulong[] dim3247Kuo2Init = { 1, 1, 7, 9, 17, 5, 69, 233, 491, 489, 49, 1395, 1907, 10189, 17853, 0 }; + static ulong[] dim3248Kuo2Init = { 1, 1, 7, 13, 9, 29, 25, 169, 469, 1015, 1729, 3095, 281, 15537, 32565, 0 }; + static ulong[] dim3249Kuo2Init = { 1, 1, 1, 7, 23, 63, 55, 65, 1, 913, 343, 3749, 3085, 13557, 32121, 0 }; + static ulong[] dim3250Kuo2Init = { 1, 3, 7, 13, 15, 29, 15, 141, 113, 315, 645, 821, 5083, 12141, 1603, 0 }; + static ulong[] dim3251Kuo2Init = { 1, 3, 5, 11, 19, 7, 73, 245, 139, 923, 731, 211, 7223, 8179, 20811, 0 }; + static ulong[] dim3252Kuo2Init = { 1, 3, 7, 11, 31, 21, 35, 253, 373, 889, 1671, 1069, 3475, 1947, 16129, 0 }; + static ulong[] dim3253Kuo2Init = { 1, 1, 1, 11, 17, 11, 3, 223, 169, 577, 2045, 2591, 2593, 10911, 20657, 0 }; + static ulong[] dim3254Kuo2Init = { 1, 3, 3, 5, 21, 57, 121, 185, 329, 581, 471, 1799, 393, 1059, 19339, 0 }; + static ulong[] dim3255Kuo2Init = { 1, 1, 3, 3, 17, 63, 39, 227, 447, 157, 1803, 239, 93, 5297, 801, 0 }; + static ulong[] dim3256Kuo2Init = { 1, 3, 5, 5, 23, 47, 127, 211, 415, 943, 757, 213, 5071, 5811, 2135, 0 }; + static ulong[] dim3257Kuo2Init = { 1, 3, 1, 5, 7, 63, 95, 83, 307, 241, 511, 1417, 2141, 2599, 1665, 0 }; + static ulong[] dim3258Kuo2Init = { 1, 1, 7, 1, 17, 31, 113, 53, 27, 611, 45, 1909, 6519, 5687, 23335, 0 }; + static ulong[] dim3259Kuo2Init = { 1, 1, 5, 9, 5, 43, 81, 99, 505, 739, 633, 1563, 6385, 14799, 24813, 0 }; + static ulong[] dim3260Kuo2Init = { 1, 3, 7, 13, 19, 47, 11, 87, 403, 763, 483, 3793, 7445, 4865, 13187, 0 }; + static ulong[] dim3261Kuo2Init = { 1, 1, 7, 9, 17, 49, 25, 57, 417, 253, 1901, 115, 3933, 11743, 1925, 0 }; + static ulong[] dim3262Kuo2Init = { 1, 3, 5, 7, 15, 21, 13, 143, 399, 953, 1397, 3905, 7935, 11957, 4817, 0 }; + static ulong[] dim3263Kuo2Init = { 1, 1, 5, 1, 7, 63, 49, 11, 321, 181, 545, 2035, 5339, 2727, 11623, 0 }; + static ulong[] dim3264Kuo2Init = { 1, 3, 7, 1, 15, 13, 49, 101, 499, 831, 427, 531, 4165, 7087, 14077, 0 }; + static ulong[] dim3265Kuo2Init = { 1, 3, 5, 9, 13, 19, 119, 115, 283, 1015, 1189, 2507, 2491, 13467, 10437, 0 }; + static ulong[] dim3266Kuo2Init = { 1, 1, 5, 3, 11, 31, 103, 3, 421, 717, 611, 2711, 2221, 13187, 19973, 0 }; + static ulong[] dim3267Kuo2Init = { 1, 1, 1, 11, 3, 53, 61, 3, 337, 55, 751, 3467, 7851, 3437, 31047, 0 }; + static ulong[] dim3268Kuo2Init = { 1, 1, 1, 5, 1, 57, 81, 127, 425, 965, 1633, 2193, 7061, 2239, 18383, 0 }; + static ulong[] dim3269Kuo2Init = { 1, 1, 5, 15, 11, 55, 49, 31, 497, 715, 1725, 1359, 177, 13011, 11291, 0 }; + static ulong[] dim3270Kuo2Init = { 1, 1, 5, 9, 3, 11, 121, 217, 77, 627, 1857, 41, 7613, 3471, 10591, 0 }; + static ulong[] dim3271Kuo2Init = { 1, 1, 7, 11, 13, 23, 81, 253, 263, 663, 1581, 1839, 1327, 7735, 22843, 0 }; + static ulong[] dim3272Kuo2Init = { 1, 1, 7, 3, 31, 29, 97, 243, 215, 893, 1179, 953, 915, 16003, 32685, 0 }; + static ulong[] dim3273Kuo2Init = { 1, 1, 7, 3, 5, 61, 7, 35, 439, 1023, 1079, 3639, 3179, 8793, 8413, 0 }; + static ulong[] dim3274Kuo2Init = { 1, 1, 5, 13, 31, 1, 99, 199, 181, 75, 283, 1581, 1137, 2725, 27179, 0 }; + static ulong[] dim3275Kuo2Init = { 1, 3, 7, 1, 27, 35, 45, 49, 179, 403, 593, 2849, 2349, 5835, 32533, 0 }; + static ulong[] dim3276Kuo2Init = { 1, 1, 1, 1, 5, 31, 21, 153, 169, 19, 813, 3077, 2569, 12355, 3805, 0 }; + static ulong[] dim3277Kuo2Init = { 1, 1, 5, 11, 1, 15, 77, 31, 17, 827, 2005, 799, 5663, 779, 28605, 0 }; + static ulong[] dim3278Kuo2Init = { 1, 1, 5, 3, 29, 51, 3, 91, 505, 161, 2041, 2841, 269, 33, 21771, 0 }; + static ulong[] dim3279Kuo2Init = { 1, 1, 3, 5, 17, 55, 105, 233, 9, 647, 987, 3801, 1421, 8589, 23389, 0 }; + static ulong[] dim3280Kuo2Init = { 1, 1, 7, 15, 27, 63, 73, 87, 111, 233, 1231, 3631, 4355, 15843, 1227, 0 }; + static ulong[] dim3281Kuo2Init = { 1, 1, 3, 15, 17, 5, 63, 23, 55, 655, 1909, 891, 7873, 11163, 26269, 0 }; + static ulong[] dim3282Kuo2Init = { 1, 1, 1, 5, 19, 7, 47, 31, 41, 229, 1381, 773, 2183, 1687, 15761, 0 }; + static ulong[] dim3283Kuo2Init = { 1, 1, 7, 3, 17, 57, 81, 115, 41, 907, 1353, 981, 2601, 10247, 13753, 0 }; + static ulong[] dim3284Kuo2Init = { 1, 3, 3, 1, 5, 13, 83, 19, 107, 935, 1519, 795, 2035, 5649, 21125, 0 }; + static ulong[] dim3285Kuo2Init = { 1, 1, 3, 9, 21, 7, 77, 229, 85, 837, 1085, 781, 6599, 5645, 15481, 0 }; + static ulong[] dim3286Kuo2Init = { 1, 3, 3, 1, 13, 23, 109, 21, 77, 223, 131, 4013, 7507, 10463, 25621, 0 }; + static ulong[] dim3287Kuo2Init = { 1, 3, 5, 11, 21, 55, 99, 195, 447, 57, 1395, 1283, 377, 15019, 26951, 0 }; + static ulong[] dim3288Kuo2Init = { 1, 3, 5, 13, 13, 35, 119, 39, 161, 609, 247, 2541, 3133, 9625, 12129, 0 }; + static ulong[] dim3289Kuo2Init = { 1, 3, 3, 15, 7, 55, 69, 169, 459, 461, 1359, 255, 4567, 7915, 16883, 0 }; + static ulong[] dim3290Kuo2Init = { 1, 1, 1, 11, 25, 41, 93, 105, 147, 893, 515, 3161, 351, 12079, 3445, 0 }; + static ulong[] dim3291Kuo2Init = { 1, 3, 3, 5, 15, 59, 93, 61, 235, 971, 1203, 2213, 3257, 16001, 20581, 0 }; + static ulong[] dim3292Kuo2Init = { 1, 1, 1, 11, 19, 5, 53, 49, 101, 653, 897, 3761, 8087, 14891, 30595, 0 }; + static ulong[] dim3293Kuo2Init = { 1, 1, 3, 7, 13, 27, 37, 29, 181, 875, 1429, 2483, 2987, 15951, 16217, 0 }; + static ulong[] dim3294Kuo2Init = { 1, 3, 5, 7, 11, 53, 69, 33, 309, 467, 1149, 3103, 3713, 9701, 16637, 0 }; + static ulong[] dim3295Kuo2Init = { 1, 1, 5, 1, 31, 63, 5, 187, 371, 895, 1365, 2671, 5899, 15493, 9685, 0 }; + static ulong[] dim3296Kuo2Init = { 1, 3, 1, 5, 19, 3, 127, 251, 39, 335, 489, 3359, 4939, 413, 521, 0 }; + static ulong[] dim3297Kuo2Init = { 1, 1, 7, 11, 11, 37, 51, 135, 191, 535, 1037, 2365, 381, 8253, 21177, 0 }; + static ulong[] dim3298Kuo2Init = { 1, 1, 3, 13, 9, 23, 77, 147, 93, 793, 1223, 2655, 3873, 6049, 19201, 0 }; + static ulong[] dim3299Kuo2Init = { 1, 3, 5, 5, 15, 41, 21, 217, 149, 965, 1173, 1779, 501, 4829, 17439, 0 }; + static ulong[] dim3300Kuo2Init = { 1, 3, 5, 15, 11, 37, 63, 233, 103, 453, 799, 571, 1991, 439, 26713, 0 }; + static ulong[] dim3301Kuo2Init = { 1, 1, 7, 9, 31, 1, 11, 155, 483, 875, 1943, 1355, 3125, 8771, 30531, 0 }; + static ulong[] dim3302Kuo2Init = { 1, 3, 3, 13, 7, 31, 9, 139, 277, 203, 1937, 31, 4519, 2127, 22557, 0 }; + static ulong[] dim3303Kuo2Init = { 1, 1, 1, 3, 19, 53, 117, 225, 391, 501, 607, 1493, 3119, 10817, 6307, 0 }; + static ulong[] dim3304Kuo2Init = { 1, 1, 3, 11, 3, 19, 3, 51, 507, 245, 1563, 3987, 7461, 4851, 23697, 0 }; + static ulong[] dim3305Kuo2Init = { 1, 3, 3, 9, 1, 39, 49, 21, 39, 631, 1777, 1689, 665, 5657, 26469, 0 }; + static ulong[] dim3306Kuo2Init = { 1, 3, 7, 3, 17, 41, 73, 13, 97, 649, 1737, 653, 5093, 629, 4389, 0 }; + static ulong[] dim3307Kuo2Init = { 1, 3, 5, 1, 13, 9, 99, 149, 389, 151, 313, 2517, 77, 2157, 4713, 0 }; + static ulong[] dim3308Kuo2Init = { 1, 3, 5, 1, 15, 25, 3, 129, 111, 847, 585, 3103, 6237, 8491, 24519, 0 }; + static ulong[] dim3309Kuo2Init = { 1, 1, 3, 1, 11, 25, 71, 229, 325, 51, 537, 3393, 6561, 6871, 30609, 0 }; + static ulong[] dim3310Kuo2Init = { 1, 3, 7, 15, 5, 3, 109, 237, 469, 235, 1703, 525, 2579, 9107, 13261, 0 }; + static ulong[] dim3311Kuo2Init = { 1, 3, 7, 13, 7, 31, 65, 67, 165, 1003, 957, 371, 5857, 16307, 4069, 0 }; + static ulong[] dim3312Kuo2Init = { 1, 1, 7, 15, 7, 63, 51, 199, 63, 259, 1383, 2747, 5945, 8061, 30961, 0 }; + static ulong[] dim3313Kuo2Init = { 1, 1, 1, 7, 13, 43, 67, 143, 407, 369, 1803, 2405, 4737, 5741, 21311, 0 }; + static ulong[] dim3314Kuo2Init = { 1, 3, 7, 11, 19, 25, 127, 251, 325, 327, 169, 3745, 2115, 4591, 12383, 0 }; + static ulong[] dim3315Kuo2Init = { 1, 1, 3, 13, 31, 61, 35, 209, 161, 171, 1155, 531, 5493, 13607, 23809, 0 }; + static ulong[] dim3316Kuo2Init = { 1, 1, 3, 9, 21, 39, 93, 185, 421, 355, 2039, 259, 7309, 6747, 745, 0 }; + static ulong[] dim3317Kuo2Init = { 1, 3, 5, 11, 1, 39, 43, 169, 137, 21, 1377, 3091, 4893, 1197, 1785, 0 }; + static ulong[] dim3318Kuo2Init = { 1, 1, 5, 5, 29, 59, 89, 79, 457, 463, 193, 727, 2505, 10509, 5379, 0 }; + static ulong[] dim3319Kuo2Init = { 1, 3, 3, 9, 23, 23, 59, 35, 425, 47, 1787, 1705, 3469, 14583, 3439, 0 }; + static ulong[] dim3320Kuo2Init = { 1, 1, 7, 5, 27, 5, 85, 51, 31, 277, 851, 2731, 5613, 11305, 23727, 0 }; + static ulong[] dim3321Kuo2Init = { 1, 3, 1, 15, 15, 47, 109, 211, 385, 505, 791, 253, 4123, 13393, 31515, 0 }; + static ulong[] dim3322Kuo2Init = { 1, 3, 5, 3, 25, 9, 73, 35, 203, 721, 1111, 1791, 5241, 15307, 4385, 0 }; + static ulong[] dim3323Kuo2Init = { 1, 3, 5, 1, 9, 43, 127, 127, 191, 21, 1967, 3523, 5959, 5775, 24635, 0 }; + static ulong[] dim3324Kuo2Init = { 1, 3, 7, 5, 7, 23, 75, 37, 307, 375, 1731, 2945, 763, 11723, 32033, 0 }; + static ulong[] dim3325Kuo2Init = { 1, 3, 3, 13, 31, 19, 83, 185, 457, 109, 349, 1085, 7381, 8851, 27633, 0 }; + static ulong[] dim3326Kuo2Init = { 1, 3, 3, 1, 25, 17, 79, 73, 381, 655, 409, 2043, 6803, 9041, 25733, 0 }; + static ulong[] dim3327Kuo2Init = { 1, 3, 5, 7, 17, 9, 61, 47, 429, 507, 1933, 1653, 2057, 15791, 12035, 0 }; + static ulong[] dim3328Kuo2Init = { 1, 1, 7, 1, 5, 57, 31, 83, 223, 281, 1485, 2965, 4543, 9719, 22109, 0 }; + static ulong[] dim3329Kuo2Init = { 1, 1, 3, 3, 5, 11, 69, 65, 229, 87, 1707, 2701, 985, 12261, 32209, 0 }; + static ulong[] dim3330Kuo2Init = { 1, 3, 7, 15, 13, 29, 121, 1, 475, 905, 1843, 571, 5595, 1685, 8061, 0 }; + static ulong[] dim3331Kuo2Init = { 1, 3, 5, 1, 9, 37, 115, 35, 309, 117, 17, 3537, 4491, 13863, 12611, 0 }; + static ulong[] dim3332Kuo2Init = { 1, 1, 7, 15, 9, 1, 79, 135, 95, 417, 633, 2109, 7911, 15009, 32399, 0 }; + static ulong[] dim3333Kuo2Init = { 1, 3, 7, 5, 9, 41, 23, 137, 135, 429, 267, 3787, 4643, 1221, 20257, 0 }; + static ulong[] dim3334Kuo2Init = { 1, 3, 3, 1, 11, 37, 97, 107, 43, 273, 213, 1779, 2317, 7325, 2495, 0 }; + static ulong[] dim3335Kuo2Init = { 1, 1, 3, 9, 13, 57, 29, 29, 5, 45, 633, 3437, 8147, 11819, 16397, 0 }; + static ulong[] dim3336Kuo2Init = { 1, 3, 7, 5, 19, 47, 67, 39, 281, 1003, 1489, 199, 3099, 3925, 17517, 0 }; + static ulong[] dim3337Kuo2Init = { 1, 3, 3, 3, 21, 49, 91, 47, 435, 193, 683, 1845, 6237, 5573, 10647, 0 }; + static ulong[] dim3338Kuo2Init = { 1, 3, 1, 11, 3, 59, 5, 197, 393, 389, 1735, 1417, 2061, 11827, 7587, 0 }; + static ulong[] dim3339Kuo2Init = { 1, 1, 5, 15, 1, 35, 113, 81, 233, 435, 1481, 2007, 6043, 9005, 19277, 0 }; + static ulong[] dim3340Kuo2Init = { 1, 3, 1, 11, 9, 53, 109, 193, 329, 187, 35, 3693, 951, 9735, 5587, 0 }; + static ulong[] dim3341Kuo2Init = { 1, 1, 1, 5, 19, 41, 25, 225, 269, 317, 201, 2817, 971, 2873, 22637, 0 }; + static ulong[] dim3342Kuo2Init = { 1, 3, 7, 1, 9, 47, 105, 219, 69, 633, 1073, 1895, 1759, 12353, 9011, 0 }; + static ulong[] dim3343Kuo2Init = { 1, 1, 7, 11, 11, 59, 3, 163, 361, 157, 1937, 3589, 1531, 9303, 3627, 0 }; + static ulong[] dim3344Kuo2Init = { 1, 1, 3, 9, 31, 15, 23, 5, 447, 59, 1907, 197, 2775, 11303, 32553, 0 }; + static ulong[] dim3345Kuo2Init = { 1, 3, 1, 13, 11, 35, 83, 97, 225, 761, 907, 3107, 1827, 14745, 235, 0 }; + static ulong[] dim3346Kuo2Init = { 1, 3, 1, 13, 13, 37, 127, 55, 511, 861, 1769, 3999, 8135, 445, 12537, 0 }; + static ulong[] dim3347Kuo2Init = { 1, 1, 7, 11, 21, 61, 111, 107, 129, 43, 837, 3811, 3261, 15273, 24319, 0 }; + static ulong[] dim3348Kuo2Init = { 1, 3, 7, 1, 17, 15, 23, 27, 227, 573, 1739, 2611, 3977, 493, 24091, 0 }; + static ulong[] dim3349Kuo2Init = { 1, 3, 3, 5, 17, 59, 17, 61, 443, 215, 1171, 1587, 55, 14417, 30225, 0 }; + static ulong[] dim3350Kuo2Init = { 1, 3, 3, 5, 5, 51, 5, 101, 147, 951, 445, 2203, 6731, 3993, 12935, 0 }; + static ulong[] dim3351Kuo2Init = { 1, 1, 3, 13, 31, 15, 117, 125, 413, 927, 1837, 2781, 2569, 12177, 20551, 0 }; + static ulong[] dim3352Kuo2Init = { 1, 1, 1, 9, 27, 13, 115, 243, 211, 123, 1631, 1277, 1217, 15271, 26377, 0 }; + static ulong[] dim3353Kuo2Init = { 1, 3, 7, 3, 27, 55, 5, 91, 255, 367, 503, 659, 1527, 15907, 4485, 0 }; + static ulong[] dim3354Kuo2Init = { 1, 3, 3, 13, 9, 11, 29, 175, 305, 593, 1209, 551, 7579, 1273, 22545, 0 }; + static ulong[] dim3355Kuo2Init = { 1, 3, 3, 13, 17, 33, 101, 83, 93, 261, 1395, 573, 6665, 10073, 26139, 0 }; + static ulong[] dim3356Kuo2Init = { 1, 1, 3, 7, 25, 35, 93, 11, 29, 941, 525, 457, 1293, 15753, 19273, 0 }; + static ulong[] dim3357Kuo2Init = { 1, 3, 5, 15, 5, 31, 101, 211, 383, 759, 1287, 429, 291, 12347, 12683, 0 }; + static ulong[] dim3358Kuo2Init = { 1, 1, 7, 3, 9, 53, 119, 81, 91, 113, 1525, 1037, 8021, 2913, 11205, 0 }; + static ulong[] dim3359Kuo2Init = { 1, 1, 3, 1, 9, 47, 59, 23, 497, 273, 453, 1063, 2523, 8929, 43, 0 }; + static ulong[] dim3360Kuo2Init = { 1, 1, 3, 9, 1, 23, 65, 147, 327, 851, 177, 4047, 3881, 2885, 21021, 0 }; + static ulong[] dim3361Kuo2Init = { 1, 1, 7, 1, 19, 53, 13, 117, 267, 803, 21, 3825, 2387, 7273, 19753, 0 }; + static ulong[] dim3362Kuo2Init = { 1, 3, 5, 7, 9, 9, 107, 9, 261, 797, 1337, 1535, 663, 6635, 3383, 0 }; + static ulong[] dim3363Kuo2Init = { 1, 1, 7, 13, 13, 27, 65, 75, 375, 805, 1079, 947, 993, 1793, 16235, 0 }; + static ulong[] dim3364Kuo2Init = { 1, 3, 3, 9, 11, 17, 119, 57, 501, 105, 1109, 3607, 1805, 8277, 24869, 0 }; + static ulong[] dim3365Kuo2Init = { 1, 3, 7, 1, 1, 29, 125, 205, 453, 607, 1371, 2169, 2723, 7381, 23411, 0 }; + static ulong[] dim3366Kuo2Init = { 1, 3, 7, 13, 13, 57, 83, 149, 197, 739, 823, 1551, 5329, 10781, 6055, 0 }; + static ulong[] dim3367Kuo2Init = { 1, 3, 7, 1, 5, 33, 9, 237, 37, 733, 879, 1303, 365, 5595, 32425, 0 }; + static ulong[] dim3368Kuo2Init = { 1, 1, 1, 1, 17, 13, 117, 189, 323, 377, 1645, 2143, 4469, 9497, 11573, 0 }; + static ulong[] dim3369Kuo2Init = { 1, 3, 1, 5, 13, 47, 19, 19, 155, 681, 1909, 913, 6985, 11449, 9981, 0 }; + static ulong[] dim3370Kuo2Init = { 1, 3, 7, 11, 29, 55, 73, 113, 291, 865, 239, 209, 67, 10813, 19287, 0 }; + static ulong[] dim3371Kuo2Init = { 1, 3, 5, 9, 3, 7, 27, 119, 267, 649, 1125, 2953, 3393, 3281, 15539, 0 }; + static ulong[] dim3372Kuo2Init = { 1, 3, 3, 13, 9, 41, 25, 145, 233, 475, 873, 631, 2429, 12071, 18123, 0 }; + static ulong[] dim3373Kuo2Init = { 1, 3, 1, 3, 17, 53, 85, 71, 193, 339, 493, 2495, 4369, 7239, 21395, 0 }; + static ulong[] dim3374Kuo2Init = { 1, 3, 1, 3, 25, 51, 87, 11, 291, 659, 455, 1217, 5737, 3263, 15213, 0 }; + static ulong[] dim3375Kuo2Init = { 1, 3, 1, 11, 5, 37, 93, 51, 359, 113, 1847, 4007, 2497, 12287, 16961, 0 }; + static ulong[] dim3376Kuo2Init = { 1, 3, 5, 11, 1, 27, 107, 189, 353, 499, 395, 1717, 6313, 315, 17027, 0 }; + static ulong[] dim3377Kuo2Init = { 1, 1, 3, 3, 15, 57, 105, 107, 17, 769, 1207, 3243, 179, 305, 16425, 0 }; + static ulong[] dim3378Kuo2Init = { 1, 3, 5, 1, 19, 9, 87, 5, 303, 653, 481, 1673, 3101, 7751, 23301, 0 }; + static ulong[] dim3379Kuo2Init = { 1, 1, 5, 9, 31, 39, 67, 225, 287, 285, 1937, 413, 2101, 10941, 32071, 0 }; + static ulong[] dim3380Kuo2Init = { 1, 3, 5, 5, 1, 25, 49, 61, 309, 19, 641, 247, 7909, 13761, 14231, 0 }; + static ulong[] dim3381Kuo2Init = { 1, 1, 5, 5, 13, 31, 55, 141, 223, 573, 895, 2853, 5663, 15519, 10871, 0 }; + static ulong[] dim3382Kuo2Init = { 1, 3, 3, 11, 31, 27, 61, 239, 215, 897, 857, 2591, 6251, 14317, 10973, 0 }; + static ulong[] dim3383Kuo2Init = { 1, 3, 1, 5, 29, 23, 115, 5, 449, 455, 1597, 3329, 4463, 10653, 17079, 0 }; + static ulong[] dim3384Kuo2Init = { 1, 1, 1, 1, 31, 27, 25, 43, 99, 817, 1863, 1563, 7021, 4981, 5049, 0 }; + static ulong[] dim3385Kuo2Init = { 1, 1, 7, 5, 1, 13, 95, 241, 269, 145, 737, 1479, 7469, 10069, 21421, 0 }; + static ulong[] dim3386Kuo2Init = { 1, 1, 5, 5, 21, 47, 111, 153, 411, 763, 2003, 1809, 5887, 4543, 7505, 0 }; + static ulong[] dim3387Kuo2Init = { 1, 3, 3, 7, 1, 31, 75, 131, 103, 873, 1893, 2025, 6525, 57, 19701, 0 }; + static ulong[] dim3388Kuo2Init = { 1, 1, 1, 7, 13, 3, 41, 243, 19, 1007, 365, 601, 7015, 485, 6313, 0 }; + static ulong[] dim3389Kuo2Init = { 1, 3, 5, 9, 9, 49, 27, 47, 139, 837, 43, 2843, 83, 9987, 29817, 0 }; + static ulong[] dim3390Kuo2Init = { 1, 3, 7, 15, 27, 51, 95, 133, 275, 625, 1489, 4077, 3049, 15213, 23817, 0 }; + static ulong[] dim3391Kuo2Init = { 1, 1, 1, 7, 1, 33, 101, 109, 131, 997, 101, 881, 3051, 1215, 4783, 0 }; + static ulong[] dim3392Kuo2Init = { 1, 3, 7, 5, 9, 7, 3, 223, 343, 467, 697, 3441, 4723, 4265, 29517, 0 }; + static ulong[] dim3393Kuo2Init = { 1, 1, 7, 3, 17, 25, 97, 191, 413, 211, 263, 2027, 2025, 6125, 9667, 0 }; + static ulong[] dim3394Kuo2Init = { 1, 1, 7, 11, 15, 15, 57, 151, 351, 187, 103, 1231, 567, 7829, 17941, 0 }; + static ulong[] dim3395Kuo2Init = { 1, 3, 3, 7, 13, 43, 49, 235, 195, 271, 1945, 1459, 2335, 141, 27615, 0 }; + static ulong[] dim3396Kuo2Init = { 1, 1, 7, 9, 5, 49, 123, 231, 133, 781, 697, 157, 2889, 12929, 18099, 0 }; + static ulong[] dim3397Kuo2Init = { 1, 1, 3, 7, 19, 25, 127, 181, 169, 981, 1955, 3289, 2077, 10627, 30383, 0 }; + static ulong[] dim3398Kuo2Init = { 1, 3, 7, 9, 1, 53, 99, 163, 291, 701, 1367, 3941, 3211, 6661, 29143, 0 }; + static ulong[] dim3399Kuo2Init = { 1, 1, 7, 9, 7, 49, 83, 77, 9, 549, 705, 527, 5609, 10933, 27715, 0 }; + static ulong[] dim3400Kuo2Init = { 1, 3, 5, 7, 27, 15, 31, 75, 39, 823, 497, 875, 435, 14427, 30859, 0 }; + static ulong[] dim3401Kuo2Init = { 1, 1, 7, 5, 21, 49, 63, 245, 357, 653, 45, 2053, 169, 7459, 2441, 0 }; + static ulong[] dim3402Kuo2Init = { 1, 3, 1, 13, 7, 53, 109, 167, 243, 585, 1173, 1925, 601, 13899, 29, 0 }; + static ulong[] dim3403Kuo2Init = { 1, 3, 3, 15, 21, 1, 119, 33, 129, 893, 1047, 1223, 3335, 5711, 28213, 0 }; + static ulong[] dim3404Kuo2Init = { 1, 1, 5, 11, 21, 47, 97, 9, 201, 647, 1595, 3091, 3635, 15487, 21375, 0 }; + static ulong[] dim3405Kuo2Init = { 1, 3, 1, 11, 11, 17, 11, 133, 447, 925, 97, 2841, 4147, 15803, 6311, 0 }; + static ulong[] dim3406Kuo2Init = { 1, 3, 1, 7, 13, 27, 27, 201, 105, 37, 399, 1695, 4263, 6081, 21461, 0 }; + static ulong[] dim3407Kuo2Init = { 1, 1, 7, 5, 7, 25, 45, 83, 327, 283, 1799, 691, 2795, 12961, 125, 0 }; + static ulong[] dim3408Kuo2Init = { 1, 1, 5, 11, 23, 23, 11, 221, 189, 353, 887, 3087, 4937, 11335, 29193, 0 }; + static ulong[] dim3409Kuo2Init = { 1, 1, 1, 9, 1, 47, 49, 141, 391, 661, 1289, 3937, 5833, 10731, 26501, 0 }; + static ulong[] dim3410Kuo2Init = { 1, 3, 7, 5, 21, 57, 89, 123, 163, 137, 1575, 4073, 7663, 13611, 11511, 0 }; + static ulong[] dim3411Kuo2Init = { 1, 1, 7, 15, 17, 27, 27, 149, 67, 147, 1069, 353, 3323, 7763, 11549, 0 }; + static ulong[] dim3412Kuo2Init = { 1, 3, 1, 3, 19, 61, 11, 19, 403, 451, 737, 3107, 847, 13403, 25943, 0 }; + static ulong[] dim3413Kuo2Init = { 1, 1, 1, 11, 11, 55, 93, 185, 241, 807, 1017, 1707, 2745, 1923, 20451, 0 }; + static ulong[] dim3414Kuo2Init = { 1, 3, 1, 5, 25, 51, 125, 87, 275, 43, 65, 3327, 3313, 211, 24217, 0 }; + static ulong[] dim3415Kuo2Init = { 1, 3, 3, 7, 23, 9, 3, 207, 367, 939, 423, 3741, 4051, 2673, 25363, 0 }; + static ulong[] dim3416Kuo2Init = { 1, 1, 1, 9, 5, 41, 47, 255, 359, 179, 365, 3037, 6377, 14293, 21925, 0 }; + static ulong[] dim3417Kuo2Init = { 1, 1, 7, 9, 31, 31, 97, 77, 479, 375, 491, 1101, 6717, 5499, 12693, 0 }; + static ulong[] dim3418Kuo2Init = { 1, 1, 3, 1, 29, 55, 75, 209, 231, 15, 49, 3233, 3627, 11307, 11413, 0 }; + static ulong[] dim3419Kuo2Init = { 1, 1, 7, 5, 13, 25, 105, 165, 15, 863, 827, 3691, 3531, 1487, 14615, 0 }; + static ulong[] dim3420Kuo2Init = { 1, 3, 3, 1, 19, 17, 51, 37, 349, 71, 31, 2545, 1151, 6187, 26835, 0 }; + static ulong[] dim3421Kuo2Init = { 1, 3, 3, 13, 21, 43, 19, 81, 307, 751, 61, 3319, 2129, 9275, 18825, 0 }; + static ulong[] dim3422Kuo2Init = { 1, 3, 7, 11, 11, 57, 117, 29, 189, 267, 31, 579, 6103, 10553, 15037, 0 }; + static ulong[] dim3423Kuo2Init = { 1, 3, 3, 5, 7, 41, 101, 149, 43, 693, 797, 2447, 2973, 11177, 5795, 0 }; + static ulong[] dim3424Kuo2Init = { 1, 1, 1, 15, 25, 55, 117, 207, 187, 211, 109, 3719, 8161, 8091, 8301, 0 }; + static ulong[] dim3425Kuo2Init = { 1, 1, 5, 11, 3, 27, 17, 61, 71, 555, 847, 1733, 6171, 6467, 2289, 0 }; + static ulong[] dim3426Kuo2Init = { 1, 3, 7, 15, 31, 57, 103, 173, 127, 513, 2003, 1483, 3495, 1951, 30371, 0 }; + static ulong[] dim3427Kuo2Init = { 1, 3, 7, 1, 13, 3, 107, 63, 77, 647, 1645, 2935, 4019, 595, 21603, 0 }; + static ulong[] dim3428Kuo2Init = { 1, 3, 7, 15, 23, 23, 121, 51, 163, 321, 2005, 3873, 41, 15907, 26881, 0 }; + static ulong[] dim3429Kuo2Init = { 1, 3, 1, 11, 27, 63, 1, 173, 423, 1023, 1123, 1683, 5395, 15017, 31877, 0 }; + static ulong[] dim3430Kuo2Init = { 1, 1, 3, 1, 19, 19, 67, 121, 277, 409, 809, 4061, 6041, 2161, 13845, 0 }; + static ulong[] dim3431Kuo2Init = { 1, 3, 7, 9, 13, 1, 111, 241, 193, 463, 1585, 2787, 2651, 4439, 27315, 0 }; + static ulong[] dim3432Kuo2Init = { 1, 3, 1, 3, 5, 1, 83, 213, 425, 623, 1709, 3523, 4547, 5827, 14637, 0 }; + static ulong[] dim3433Kuo2Init = { 1, 1, 5, 9, 11, 43, 87, 31, 455, 559, 1117, 2541, 6381, 6333, 16025, 0 }; + static ulong[] dim3434Kuo2Init = { 1, 1, 3, 11, 5, 61, 69, 115, 253, 743, 719, 3745, 3739, 5511, 12207, 0 }; + static ulong[] dim3435Kuo2Init = { 1, 3, 7, 1, 31, 63, 11, 239, 217, 569, 749, 2445, 7183, 11169, 15683, 0 }; + static ulong[] dim3436Kuo2Init = { 1, 1, 1, 13, 21, 47, 11, 187, 65, 19, 217, 2205, 5435, 14333, 8095, 0 }; + static ulong[] dim3437Kuo2Init = { 1, 1, 5, 1, 15, 63, 81, 3, 291, 289, 1575, 3499, 5583, 16189, 14587, 0 }; + static ulong[] dim3438Kuo2Init = { 1, 1, 1, 11, 29, 1, 105, 195, 37, 875, 203, 3937, 3661, 1103, 569, 0 }; + static ulong[] dim3439Kuo2Init = { 1, 3, 3, 7, 25, 55, 7, 75, 185, 995, 569, 1861, 1149, 14763, 7581, 0 }; + static ulong[] dim3440Kuo2Init = { 1, 1, 3, 15, 13, 3, 107, 223, 273, 607, 1877, 3595, 3985, 1675, 9387, 0 }; + static ulong[] dim3441Kuo2Init = { 1, 3, 7, 15, 15, 35, 57, 95, 99, 5, 351, 3767, 7617, 7071, 1465, 0 }; + static ulong[] dim3442Kuo2Init = { 1, 1, 7, 1, 13, 11, 19, 169, 381, 245, 99, 1121, 7127, 6145, 625, 0 }; + static ulong[] dim3443Kuo2Init = { 1, 3, 5, 15, 29, 13, 89, 81, 31, 827, 989, 445, 6361, 7953, 5035, 0 }; + static ulong[] dim3444Kuo2Init = { 1, 1, 5, 11, 5, 9, 21, 27, 321, 739, 557, 3953, 3739, 15215, 5467, 0 }; + static ulong[] dim3445Kuo2Init = { 1, 3, 5, 7, 9, 41, 111, 195, 385, 647, 829, 2109, 3313, 2457, 10925, 0 }; + static ulong[] dim3446Kuo2Init = { 1, 3, 7, 1, 9, 47, 107, 15, 367, 385, 969, 1947, 1069, 6929, 16135, 0 }; + static ulong[] dim3447Kuo2Init = { 1, 1, 5, 7, 31, 27, 19, 133, 413, 79, 1051, 173, 1033, 9609, 17485, 0 }; + static ulong[] dim3448Kuo2Init = { 1, 1, 5, 9, 23, 19, 71, 135, 203, 659, 385, 771, 2053, 6803, 27443, 0 }; + static ulong[] dim3449Kuo2Init = { 1, 1, 1, 11, 5, 11, 15, 117, 353, 949, 1873, 3925, 6831, 12609, 20761, 0 }; + static ulong[] dim3450Kuo2Init = { 1, 1, 5, 9, 13, 51, 111, 105, 75, 147, 543, 2177, 2595, 4397, 20075, 0 }; + static ulong[] dim3451Kuo2Init = { 1, 3, 7, 1, 31, 41, 17, 81, 477, 143, 1671, 131, 3861, 7937, 12421, 0 }; + static ulong[] dim3452Kuo2Init = { 1, 1, 7, 9, 29, 55, 59, 141, 407, 287, 1205, 2349, 5033, 15907, 19857, 0 }; + static ulong[] dim3453Kuo2Init = { 1, 3, 7, 11, 5, 7, 123, 183, 333, 547, 849, 3447, 2419, 6873, 16951, 0 }; + static ulong[] dim3454Kuo2Init = { 1, 3, 7, 9, 9, 31, 63, 249, 211, 63, 1577, 235, 621, 4907, 25537, 0 }; + static ulong[] dim3455Kuo2Init = { 1, 1, 1, 1, 13, 41, 1, 37, 455, 111, 1959, 1529, 4029, 10687, 17283, 0 }; + static ulong[] dim3456Kuo2Init = { 1, 3, 1, 7, 9, 31, 105, 63, 39, 409, 1151, 2631, 1491, 2837, 2489, 0 }; + static ulong[] dim3457Kuo2Init = { 1, 3, 1, 5, 23, 63, 61, 31, 229, 685, 1869, 3101, 4285, 4485, 15371, 0 }; + static ulong[] dim3458Kuo2Init = { 1, 3, 1, 5, 17, 1, 9, 149, 239, 393, 1925, 2111, 1035, 16343, 10655, 0 }; + static ulong[] dim3459Kuo2Init = { 1, 1, 5, 15, 5, 35, 107, 155, 381, 119, 1157, 3875, 2647, 3149, 141, 0 }; + static ulong[] dim3460Kuo2Init = { 1, 1, 3, 1, 31, 1, 123, 163, 337, 653, 659, 2011, 2613, 15469, 16925, 0 }; + static ulong[] dim3461Kuo2Init = { 1, 1, 7, 5, 19, 51, 3, 17, 151, 705, 349, 3015, 7791, 9899, 30235, 0 }; + static ulong[] dim3462Kuo2Init = { 1, 1, 3, 11, 25, 55, 51, 201, 511, 67, 857, 1233, 2813, 10031, 17433, 0 }; + static ulong[] dim3463Kuo2Init = { 1, 1, 5, 9, 17, 3, 27, 193, 81, 765, 711, 2551, 2569, 9081, 9997, 0 }; + static ulong[] dim3464Kuo2Init = { 1, 3, 1, 9, 17, 19, 51, 41, 249, 157, 989, 597, 6059, 7699, 14761, 0 }; + static ulong[] dim3465Kuo2Init = { 1, 1, 1, 11, 7, 3, 87, 101, 171, 287, 1259, 1161, 2765, 9293, 1343, 0 }; + static ulong[] dim3466Kuo2Init = { 1, 3, 1, 11, 1, 49, 91, 179, 287, 661, 573, 255, 2873, 12153, 16505, 0 }; + static ulong[] dim3467Kuo2Init = { 1, 3, 1, 5, 27, 9, 101, 15, 173, 327, 1523, 3727, 6089, 195, 29999, 0 }; + static ulong[] dim3468Kuo2Init = { 1, 3, 3, 13, 5, 17, 31, 61, 395, 451, 743, 2337, 7295, 2411, 31039, 0 }; + static ulong[] dim3469Kuo2Init = { 1, 1, 1, 11, 17, 25, 59, 209, 255, 401, 321, 1881, 4539, 5371, 25829, 0 }; + static ulong[] dim3470Kuo2Init = { 1, 3, 5, 1, 21, 15, 57, 11, 233, 13, 1969, 1839, 7923, 11731, 32641, 0 }; + static ulong[] dim3471Kuo2Init = { 1, 1, 1, 15, 15, 11, 69, 179, 167, 867, 1901, 1113, 5613, 1481, 18975, 0 }; + static ulong[] dim3472Kuo2Init = { 1, 3, 3, 11, 15, 61, 1, 35, 111, 347, 141, 2749, 2987, 5587, 12385, 0 }; + static ulong[] dim3473Kuo2Init = { 1, 1, 7, 9, 3, 41, 53, 101, 417, 729, 403, 2043, 453, 2479, 21141, 0 }; + static ulong[] dim3474Kuo2Init = { 1, 1, 3, 7, 3, 55, 47, 227, 331, 425, 1361, 1657, 7231, 727, 4093, 0 }; + static ulong[] dim3475Kuo2Init = { 1, 1, 1, 1, 9, 37, 91, 207, 493, 463, 161, 3887, 543, 8349, 17949, 0 }; + static ulong[] dim3476Kuo2Init = { 1, 3, 3, 15, 25, 9, 89, 221, 293, 997, 969, 3239, 5147, 7173, 11277, 0 }; + static ulong[] dim3477Kuo2Init = { 1, 1, 7, 3, 21, 29, 87, 7, 331, 939, 1919, 5, 113, 2189, 21471, 0 }; + static ulong[] dim3478Kuo2Init = { 1, 3, 3, 5, 11, 47, 67, 119, 5, 357, 981, 4055, 6327, 13281, 185, 0 }; + static ulong[] dim3479Kuo2Init = { 1, 3, 7, 13, 27, 55, 39, 23, 209, 721, 2043, 417, 655, 15333, 5015, 0 }; + static ulong[] dim3480Kuo2Init = { 1, 3, 7, 5, 27, 7, 95, 125, 9, 1001, 557, 2947, 553, 4991, 11517, 0 }; + static ulong[] dim3481Kuo2Init = { 1, 3, 5, 13, 3, 25, 5, 99, 355, 63, 1241, 2559, 4717, 9935, 19245, 0 }; + static ulong[] dim3482Kuo2Init = { 1, 3, 1, 13, 3, 27, 45, 141, 123, 859, 603, 2495, 3815, 4229, 17501, 0 }; + static ulong[] dim3483Kuo2Init = { 1, 3, 5, 3, 13, 53, 5, 157, 33, 493, 1611, 105, 7855, 12173, 6877, 0 }; + static ulong[] dim3484Kuo2Init = { 1, 3, 7, 7, 13, 29, 89, 19, 267, 563, 645, 2637, 6889, 8283, 25807, 0 }; + static ulong[] dim3485Kuo2Init = { 1, 3, 5, 15, 23, 55, 89, 69, 363, 333, 377, 3109, 5125, 1411, 22499, 0 }; + static ulong[] dim3486Kuo2Init = { 1, 1, 5, 3, 29, 5, 11, 151, 455, 667, 1697, 1087, 1147, 12269, 14291, 0 }; + static ulong[] dim3487Kuo2Init = { 1, 3, 7, 11, 1, 29, 21, 209, 173, 719, 1679, 1637, 6835, 8629, 27391, 0 }; + static ulong[] dim3488Kuo2Init = { 1, 3, 7, 7, 23, 47, 125, 145, 93, 425, 2039, 2665, 3219, 12491, 12731, 0 }; + static ulong[] dim3489Kuo2Init = { 1, 1, 3, 9, 19, 55, 99, 253, 39, 189, 559, 1893, 2155, 7165, 7705, 0 }; + static ulong[] dim3490Kuo2Init = { 1, 1, 7, 15, 1, 63, 85, 9, 281, 551, 1697, 1341, 6039, 3315, 26821, 0 }; + static ulong[] dim3491Kuo2Init = { 1, 3, 1, 15, 19, 29, 63, 221, 201, 671, 529, 1221, 4455, 2769, 941, 0 }; + static ulong[] dim3492Kuo2Init = { 1, 3, 5, 11, 23, 17, 113, 167, 173, 17, 1911, 1995, 6459, 1517, 19169, 0 }; + static ulong[] dim3493Kuo2Init = { 1, 3, 5, 7, 23, 7, 77, 231, 157, 237, 1855, 2771, 7871, 13523, 18143, 0 }; + static ulong[] dim3494Kuo2Init = { 1, 3, 5, 5, 17, 49, 59, 175, 269, 765, 1863, 3661, 4979, 7029, 4071, 0 }; + static ulong[] dim3495Kuo2Init = { 1, 3, 3, 7, 31, 53, 9, 89, 353, 557, 1805, 3153, 4761, 14547, 20487, 0 }; + static ulong[] dim3496Kuo2Init = { 1, 1, 1, 15, 23, 45, 31, 151, 299, 745, 1899, 3113, 4177, 107, 28863, 0 }; + static ulong[] dim3497Kuo2Init = { 1, 3, 7, 3, 5, 39, 21, 145, 487, 35, 1891, 3985, 2501, 16217, 11963, 0 }; + static ulong[] dim3498Kuo2Init = { 1, 3, 1, 3, 29, 7, 15, 207, 235, 789, 1195, 253, 6443, 8921, 26009, 0 }; + static ulong[] dim3499Kuo2Init = { 1, 3, 1, 15, 23, 53, 105, 233, 71, 595, 765, 2383, 7959, 3543, 5795, 0 }; + static ulong[] dim3500Kuo2Init = { 1, 3, 1, 9, 1, 13, 95, 113, 311, 839, 1375, 4083, 7621, 4261, 6067, 0 }; + static ulong[] dim3501Kuo2Init = { 1, 1, 3, 1, 25, 41, 111, 185, 15, 779, 375, 927, 3487, 8293, 11101, 0 }; + static ulong[] dim3502Kuo2Init = { 1, 3, 3, 7, 3, 15, 79, 233, 255, 279, 171, 1659, 2131, 3659, 2381, 0 }; + static ulong[] dim3503Kuo2Init = { 1, 3, 5, 15, 21, 47, 19, 163, 481, 135, 875, 1143, 5929, 1269, 30729, 0 }; + static ulong[] dim3504Kuo2Init = { 1, 3, 5, 9, 15, 33, 45, 83, 345, 751, 2045, 3221, 3101, 8727, 3785, 0 }; + static ulong[] dim3505Kuo2Init = { 1, 3, 3, 15, 29, 49, 95, 83, 31, 433, 693, 2459, 3563, 12973, 17627, 0 }; + static ulong[] dim3506Kuo2Init = { 1, 3, 3, 15, 31, 19, 97, 165, 353, 109, 1957, 1493, 3025, 15721, 21733, 0 }; + static ulong[] dim3507Kuo2Init = { 1, 1, 3, 15, 17, 55, 23, 47, 473, 803, 1921, 2523, 6493, 1881, 2277, 0 }; + static ulong[] dim3508Kuo2Init = { 1, 3, 7, 1, 11, 11, 27, 137, 259, 825, 1093, 305, 1289, 9177, 22177, 0 }; + static ulong[] dim3509Kuo2Init = { 1, 1, 3, 3, 5, 13, 85, 191, 319, 533, 1579, 351, 987, 13229, 8727, 0 }; + static ulong[] dim3510Kuo2Init = { 1, 3, 5, 11, 21, 21, 21, 107, 201, 281, 809, 2331, 1513, 10721, 31379, 0 }; + static ulong[] dim3511Kuo2Init = { 1, 3, 3, 3, 1, 21, 55, 157, 487, 303, 891, 2035, 7329, 16203, 11811, 0 }; + static ulong[] dim3512Kuo2Init = { 1, 1, 3, 15, 3, 35, 91, 157, 501, 169, 1437, 1765, 395, 4991, 19543, 0 }; + static ulong[] dim3513Kuo2Init = { 1, 3, 7, 7, 1, 43, 3, 33, 13, 393, 805, 1453, 6409, 3153, 3609, 0 }; + static ulong[] dim3514Kuo2Init = { 1, 3, 5, 9, 25, 57, 13, 189, 333, 639, 1241, 277, 3665, 16025, 12687, 0 }; + static ulong[] dim3515Kuo2Init = { 1, 1, 3, 9, 5, 31, 45, 93, 193, 469, 1325, 3109, 2115, 15903, 2211, 0 }; + static ulong[] dim3516Kuo2Init = { 1, 3, 5, 15, 9, 37, 125, 163, 75, 505, 383, 705, 2155, 15999, 29139, 0 }; + static ulong[] dim3517Kuo2Init = { 1, 1, 1, 5, 13, 33, 37, 101, 459, 943, 821, 975, 5511, 3923, 12037, 0 }; + static ulong[] dim3518Kuo2Init = { 1, 3, 7, 3, 11, 45, 77, 79, 35, 289, 499, 2285, 1179, 953, 19641, 0 }; + static ulong[] dim3519Kuo2Init = { 1, 3, 5, 1, 21, 25, 27, 13, 49, 365, 2047, 3015, 6483, 15287, 21813, 0 }; + static ulong[] dim3520Kuo2Init = { 1, 1, 1, 11, 21, 5, 113, 215, 247, 377, 625, 2481, 7681, 343, 29051, 0 }; + static ulong[] dim3521Kuo2Init = { 1, 1, 3, 15, 17, 33, 85, 143, 97, 443, 2029, 2343, 2539, 6033, 23371, 0 }; + static ulong[] dim3522Kuo2Init = { 1, 1, 7, 13, 31, 31, 59, 135, 415, 1015, 1295, 2477, 1119, 15633, 23699, 0 }; + static ulong[] dim3523Kuo2Init = { 1, 3, 5, 3, 3, 23, 61, 135, 273, 501, 1245, 427, 6981, 12135, 15081, 0 }; + static ulong[] dim3524Kuo2Init = { 1, 3, 7, 1, 15, 35, 15, 127, 57, 813, 1769, 1919, 659, 7051, 30567, 0 }; + static ulong[] dim3525Kuo2Init = { 1, 3, 1, 5, 31, 11, 85, 131, 483, 33, 1311, 1101, 3939, 8531, 21019, 0 }; + static ulong[] dim3526Kuo2Init = { 1, 1, 5, 15, 17, 17, 127, 33, 111, 805, 1139, 2631, 7015, 11253, 13141, 0 }; + static ulong[] dim3527Kuo2Init = { 1, 3, 3, 9, 5, 5, 55, 223, 237, 641, 1081, 1145, 3773, 15829, 2309, 0 }; + static ulong[] dim3528Kuo2Init = { 1, 1, 7, 3, 29, 35, 97, 197, 259, 665, 1101, 2423, 1689, 12363, 16037, 0 }; + static ulong[] dim3529Kuo2Init = { 1, 1, 7, 15, 7, 59, 59, 199, 187, 83, 803, 1391, 6701, 8105, 22967, 0 }; + static ulong[] dim3530Kuo2Init = { 1, 1, 5, 9, 1, 59, 91, 253, 277, 1019, 87, 3727, 3367, 13351, 10217, 0 }; + static ulong[] dim3531Kuo2Init = { 1, 3, 3, 11, 19, 39, 35, 29, 259, 525, 555, 1683, 1885, 8957, 17431, 0 }; + static ulong[] dim3532Kuo2Init = { 1, 1, 1, 5, 3, 5, 99, 49, 19, 211, 135, 1677, 37, 14611, 25219, 0 }; + static ulong[] dim3533Kuo2Init = { 1, 3, 7, 3, 15, 31, 3, 201, 329, 755, 1013, 1917, 785, 14243, 28877, 0 }; + static ulong[] dim3534Kuo2Init = { 1, 3, 5, 15, 3, 13, 113, 41, 123, 157, 165, 125, 5147, 10085, 13903, 0 }; + static ulong[] dim3535Kuo2Init = { 1, 3, 7, 11, 15, 29, 127, 249, 51, 543, 667, 2401, 2623, 2447, 9471, 0 }; + static ulong[] dim3536Kuo2Init = { 1, 3, 3, 1, 7, 55, 127, 165, 235, 271, 1721, 2301, 1705, 8209, 10837, 0 }; + static ulong[] dim3537Kuo2Init = { 1, 1, 3, 15, 31, 27, 49, 13, 33, 797, 1533, 3325, 7257, 21, 16787, 0 }; + static ulong[] dim3538Kuo2Init = { 1, 1, 3, 13, 17, 29, 43, 79, 219, 133, 15, 2707, 5517, 15923, 18125, 0 }; + static ulong[] dim3539Kuo2Init = { 1, 1, 7, 1, 21, 1, 61, 233, 123, 599, 201, 1431, 3637, 7921, 14069, 0 }; + static ulong[] dim3540Kuo2Init = { 1, 3, 3, 9, 1, 1, 113, 187, 189, 1013, 1085, 3693, 337, 9807, 25367, 0 }; + static ulong[] dim3541Kuo2Init = { 1, 3, 3, 13, 11, 13, 125, 243, 77, 671, 177, 647, 1985, 15007, 27919, 0 }; + static ulong[] dim3542Kuo2Init = { 1, 3, 7, 13, 23, 3, 85, 13, 15, 443, 673, 1, 8119, 16227, 4497, 0 }; + static ulong[] dim3543Kuo2Init = { 1, 1, 3, 3, 5, 25, 113, 125, 503, 141, 945, 631, 6413, 2997, 28309, 0 }; + static ulong[] dim3544Kuo2Init = { 1, 3, 5, 5, 15, 37, 7, 169, 423, 917, 485, 3557, 1093, 11613, 11301, 0 }; + static ulong[] dim3545Kuo2Init = { 1, 1, 7, 3, 5, 35, 45, 99, 215, 537, 1055, 3109, 7745, 15741, 30499, 0 }; + static ulong[] dim3546Kuo2Init = { 1, 3, 5, 13, 19, 21, 37, 127, 83, 489, 1809, 2479, 5875, 2559, 13593, 0 }; + static ulong[] dim3547Kuo2Init = { 1, 1, 3, 15, 11, 31, 19, 111, 245, 619, 793, 453, 2557, 16269, 2823, 0 }; + static ulong[] dim3548Kuo2Init = { 1, 3, 3, 7, 31, 1, 99, 255, 187, 277, 71, 1985, 3919, 8445, 10791, 0 }; + static ulong[] dim3549Kuo2Init = { 1, 3, 1, 11, 25, 1, 63, 5, 219, 601, 1155, 2411, 7673, 8979, 23729, 0 }; + static ulong[] dim3550Kuo2Init = { 1, 1, 1, 11, 31, 59, 11, 37, 361, 145, 879, 2655, 3591, 13615, 25559, 0 }; + static ulong[] dim3551Kuo2Init = { 1, 3, 5, 7, 15, 5, 117, 175, 417, 825, 585, 1429, 5163, 335, 32281, 0 }; + static ulong[] dim3552Kuo2Init = { 1, 1, 1, 5, 27, 9, 107, 181, 493, 651, 1317, 2059, 4155, 15039, 27693, 0 }; + static ulong[] dim3553Kuo2Init = { 1, 3, 7, 3, 1, 11, 13, 187, 173, 991, 1743, 2403, 5279, 11387, 11035, 0 }; + static ulong[] dim3554Kuo2Init = { 1, 3, 1, 11, 31, 39, 87, 63, 177, 581, 609, 3315, 4859, 9597, 29901, 0 }; + static ulong[] dim3555Kuo2Init = { 1, 3, 3, 11, 15, 47, 1, 53, 91, 39, 37, 1697, 6719, 383, 1793, 0 }; + static ulong[] dim3556Kuo2Init = { 1, 3, 5, 5, 7, 19, 123, 167, 509, 585, 1153, 1803, 987, 2633, 14177, 0 }; + static ulong[] dim3557Kuo2Init = { 1, 1, 5, 7, 9, 5, 59, 137, 209, 95, 519, 177, 5627, 7843, 23207, 0 }; + static ulong[] dim3558Kuo2Init = { 1, 1, 1, 15, 7, 3, 89, 31, 125, 391, 545, 3781, 985, 7355, 27935, 0 }; + static ulong[] dim3559Kuo2Init = { 1, 3, 7, 3, 31, 11, 7, 147, 155, 421, 195, 861, 3787, 10843, 2239, 0 }; + static ulong[] dim3560Kuo2Init = { 1, 1, 3, 15, 23, 29, 71, 79, 279, 157, 853, 421, 6499, 7695, 5527, 0 }; + static ulong[] dim3561Kuo2Init = { 1, 3, 3, 11, 3, 63, 49, 199, 5, 457, 479, 3419, 6649, 14259, 17789, 0 }; + static ulong[] dim3562Kuo2Init = { 1, 1, 3, 3, 23, 7, 85, 105, 281, 929, 1487, 3797, 3487, 15959, 25859, 0 }; + static ulong[] dim3563Kuo2Init = { 1, 3, 5, 5, 23, 27, 33, 5, 283, 853, 1939, 3745, 2995, 14715, 32739, 0 }; + static ulong[] dim3564Kuo2Init = { 1, 3, 3, 5, 9, 7, 111, 53, 299, 237, 1263, 2053, 6359, 15617, 29347, 0 }; + static ulong[] dim3565Kuo2Init = { 1, 3, 3, 13, 29, 61, 55, 181, 49, 377, 729, 117, 8125, 15317, 32363, 0 }; + static ulong[] dim3566Kuo2Init = { 1, 1, 7, 1, 9, 31, 77, 107, 21, 375, 1719, 1701, 5439, 4187, 32397, 0 }; + static ulong[] dim3567Kuo2Init = { 1, 1, 3, 11, 31, 41, 101, 1, 171, 401, 1711, 3027, 161, 441, 15589, 0 }; + static ulong[] dim3568Kuo2Init = { 1, 1, 3, 15, 25, 35, 7, 85, 45, 409, 1769, 767, 2615, 1313, 7031, 0 }; + static ulong[] dim3569Kuo2Init = { 1, 3, 5, 7, 29, 7, 73, 25, 397, 767, 315, 2105, 4677, 12081, 7763, 0 }; + static ulong[] dim3570Kuo2Init = { 1, 3, 5, 13, 31, 63, 87, 29, 81, 969, 1931, 3713, 7217, 15899, 20505, 0 }; + static ulong[] dim3571Kuo2Init = { 1, 1, 5, 3, 15, 31, 121, 141, 209, 697, 941, 1565, 1363, 11919, 24479, 0 }; + static ulong[] dim3572Kuo2Init = { 1, 1, 7, 15, 23, 9, 5, 179, 437, 259, 1223, 2159, 4825, 2977, 20851, 0 }; + static ulong[] dim3573Kuo2Init = { 1, 1, 1, 13, 13, 25, 33, 169, 91, 1001, 1931, 1853, 6173, 5411, 21081, 0 }; + static ulong[] dim3574Kuo2Init = { 1, 1, 1, 13, 1, 53, 109, 53, 345, 519, 771, 1673, 6721, 3585, 6289, 0 }; + static ulong[] dim3575Kuo2Init = { 1, 3, 3, 3, 27, 37, 77, 243, 207, 791, 1585, 1965, 3327, 4719, 7121, 0 }; + static ulong[] dim3576Kuo2Init = { 1, 3, 1, 7, 3, 15, 115, 175, 303, 59, 835, 3347, 6055, 4959, 6963, 0 }; + static ulong[] dim3577Kuo2Init = { 1, 3, 5, 1, 11, 5, 99, 139, 351, 709, 281, 2635, 379, 2543, 29879, 0 }; + static ulong[] dim3578Kuo2Init = { 1, 3, 1, 11, 7, 9, 117, 209, 221, 667, 491, 2833, 1113, 12289, 7947, 0 }; + static ulong[] dim3579Kuo2Init = { 1, 3, 5, 9, 17, 11, 11, 43, 475, 169, 1167, 2601, 2733, 243, 17279, 0 }; + static ulong[] dim3580Kuo2Init = { 1, 1, 5, 15, 31, 43, 7, 107, 309, 993, 635, 3779, 1041, 9997, 23049, 0 }; + static ulong[] dim3581Kuo2Init = { 1, 3, 5, 9, 21, 15, 21, 41, 451, 1021, 131, 1539, 7147, 1639, 31157, 0 }; + static ulong[] dim3582Kuo2Init = { 1, 1, 3, 1, 25, 37, 67, 91, 463, 63, 653, 4045, 1255, 3315, 10747, 0 }; + static ulong[] dim3583Kuo2Init = { 1, 1, 3, 3, 29, 3, 95, 125, 477, 845, 563, 3095, 2985, 8935, 23247, 0 }; + static ulong[] dim3584Kuo2Init = { 1, 3, 5, 13, 11, 5, 21, 193, 121, 857, 997, 3487, 4613, 12231, 7819, 0 }; + static ulong[] dim3585Kuo2Init = { 1, 1, 3, 15, 27, 1, 65, 219, 241, 99, 1193, 3157, 7641, 10327, 25241, 0 }; + static ulong[] dim3586Kuo2Init = { 1, 3, 7, 1, 3, 25, 61, 191, 501, 219, 1863, 4039, 5879, 11203, 10581, 0 }; + static ulong[] dim3587Kuo2Init = { 1, 1, 5, 3, 23, 39, 81, 37, 477, 969, 1, 1161, 7171, 3595, 375, 0 }; + static ulong[] dim3588Kuo2Init = { 1, 3, 3, 3, 21, 17, 99, 101, 165, 849, 607, 1863, 6675, 13557, 3349, 0 }; + static ulong[] dim3589Kuo2Init = { 1, 3, 5, 15, 9, 1, 125, 93, 211, 971, 1275, 545, 3625, 1503, 10735, 0 }; + static ulong[] dim3590Kuo2Init = { 1, 3, 3, 7, 19, 53, 1, 169, 453, 227, 425, 2831, 6751, 11693, 20483, 0 }; + static ulong[] dim3591Kuo2Init = { 1, 1, 1, 3, 9, 19, 121, 203, 55, 485, 37, 3977, 2193, 9819, 4635, 0 }; + static ulong[] dim3592Kuo2Init = { 1, 3, 5, 15, 17, 35, 121, 207, 233, 149, 1607, 3599, 1013, 2295, 9113, 0 }; + static ulong[] dim3593Kuo2Init = { 1, 3, 3, 13, 29, 17, 39, 85, 47, 477, 1967, 701, 1063, 3521, 23583, 0 }; + static ulong[] dim3594Kuo2Init = { 1, 3, 3, 3, 23, 57, 69, 49, 55, 81, 1195, 347, 3869, 4843, 97, 0 }; + static ulong[] dim3595Kuo2Init = { 1, 3, 3, 1, 9, 19, 31, 199, 173, 5, 1557, 2669, 5471, 7203, 27289, 0 }; + static ulong[] dim3596Kuo2Init = { 1, 3, 3, 3, 3, 1, 121, 195, 193, 359, 1269, 973, 3443, 1669, 31895, 0 }; + static ulong[] dim3597Kuo2Init = { 1, 1, 3, 7, 3, 43, 39, 77, 149, 111, 425, 1567, 1289, 13443, 30175, 0 }; + static ulong[] dim3598Kuo2Init = { 1, 3, 3, 5, 15, 55, 67, 209, 167, 439, 825, 3165, 6537, 10291, 2561, 0 }; + static ulong[] dim3599Kuo2Init = { 1, 1, 5, 7, 1, 27, 49, 67, 123, 905, 759, 1471, 4379, 8211, 1829, 0 }; + static ulong[] dim3600Kuo2Init = { 1, 1, 7, 13, 23, 7, 99, 169, 349, 889, 1671, 3039, 6757, 7071, 20707, 0 }; + static ulong[] dim3601Kuo2Init = { 1, 3, 3, 5, 21, 59, 103, 167, 69, 77, 155, 301, 6647, 13487, 19241, 0 }; + static ulong[] dim3602Kuo2Init = { 1, 1, 7, 9, 5, 53, 19, 17, 239, 691, 1079, 3485, 4941, 1769, 6953, 0 }; + static ulong[] dim3603Kuo2Init = { 1, 3, 5, 13, 15, 37, 87, 137, 205, 743, 965, 3911, 1421, 3003, 26639, 0 }; + static ulong[] dim3604Kuo2Init = { 1, 1, 5, 7, 31, 17, 49, 151, 159, 323, 1393, 1677, 2335, 289, 30059, 0 }; + static ulong[] dim3605Kuo2Init = { 1, 1, 7, 11, 25, 37, 93, 221, 441, 329, 421, 903, 2803, 11455, 20521, 0 }; + static ulong[] dim3606Kuo2Init = { 1, 3, 5, 3, 11, 1, 127, 231, 451, 333, 1501, 1353, 1741, 7149, 17527, 0 }; + static ulong[] dim3607Kuo2Init = { 1, 1, 7, 9, 25, 33, 101, 255, 69, 693, 1579, 2307, 6071, 6711, 20071, 0 }; + static ulong[] dim3608Kuo2Init = { 1, 3, 5, 15, 29, 61, 39, 31, 193, 573, 1151, 2237, 125, 7851, 29569, 0 }; + static ulong[] dim3609Kuo2Init = { 1, 3, 5, 15, 25, 15, 93, 93, 309, 765, 23, 2111, 7001, 3885, 18391, 0 }; + static ulong[] dim3610Kuo2Init = { 1, 1, 1, 5, 29, 9, 119, 165, 127, 847, 753, 4089, 5739, 10385, 28691, 0 }; + static ulong[] dim3611Kuo2Init = { 1, 1, 1, 7, 5, 23, 41, 39, 429, 851, 1221, 3817, 8049, 14547, 9277, 0 }; + static ulong[] dim3612Kuo2Init = { 1, 3, 7, 1, 7, 23, 105, 231, 241, 49, 1083, 3903, 1469, 11055, 27949, 0 }; + static ulong[] dim3613Kuo2Init = { 1, 1, 7, 15, 9, 11, 127, 83, 425, 671, 657, 2431, 1003, 2997, 5593, 0 }; + static ulong[] dim3614Kuo2Init = { 1, 3, 1, 13, 15, 35, 73, 193, 155, 183, 2033, 2385, 7979, 8551, 2507, 0 }; + static ulong[] dim3615Kuo2Init = { 1, 3, 5, 9, 29, 43, 59, 17, 227, 159, 1839, 4047, 1667, 2541, 30517, 0 }; + static ulong[] dim3616Kuo2Init = { 1, 3, 7, 9, 31, 45, 109, 243, 163, 871, 951, 2463, 5573, 8415, 16857, 0 }; + static ulong[] dim3617Kuo2Init = { 1, 3, 7, 7, 11, 57, 93, 243, 227, 863, 483, 2371, 6781, 6811, 23423, 0 }; + static ulong[] dim3618Kuo2Init = { 1, 3, 1, 1, 13, 9, 113, 3, 207, 735, 1021, 1933, 6635, 13609, 19651, 0 }; + static ulong[] dim3619Kuo2Init = { 1, 1, 7, 9, 5, 33, 33, 159, 273, 291, 159, 1693, 217, 12487, 21853, 0 }; + static ulong[] dim3620Kuo2Init = { 1, 3, 1, 13, 27, 51, 65, 117, 485, 471, 29, 3929, 4509, 13577, 6745, 0 }; + static ulong[] dim3621Kuo2Init = { 1, 3, 3, 13, 5, 29, 23, 81, 353, 727, 1437, 3239, 717, 13857, 18881, 0 }; + static ulong[] dim3622Kuo2Init = { 1, 3, 1, 1, 11, 41, 97, 73, 271, 847, 471, 2857, 691, 10951, 31465, 0 }; + static ulong[] dim3623Kuo2Init = { 1, 1, 1, 9, 11, 59, 3, 71, 235, 715, 1349, 199, 2853, 13641, 5025, 0 }; + static ulong[] dim3624Kuo2Init = { 1, 3, 1, 9, 23, 7, 23, 49, 31, 145, 533, 2625, 207, 3661, 25215, 0 }; + static ulong[] dim3625Kuo2Init = { 1, 3, 5, 15, 17, 17, 53, 129, 105, 285, 1423, 3985, 8015, 3565, 24495, 0 }; + static ulong[] dim3626Kuo2Init = { 1, 1, 1, 13, 7, 29, 93, 123, 167, 845, 69, 2297, 543, 9165, 4029, 0 }; + static ulong[] dim3627Kuo2Init = { 1, 3, 7, 15, 19, 57, 71, 99, 95, 165, 1875, 4011, 4779, 4057, 16331, 0 }; + static ulong[] dim3628Kuo2Init = { 1, 1, 5, 11, 19, 43, 45, 83, 383, 111, 1859, 2767, 1469, 3687, 18343, 0 }; + static ulong[] dim3629Kuo2Init = { 1, 1, 5, 1, 11, 7, 63, 51, 487, 609, 1619, 3399, 1, 7253, 24325, 0 }; + static ulong[] dim3630Kuo2Init = { 1, 3, 3, 7, 29, 27, 83, 61, 353, 913, 1359, 689, 7741, 3357, 7731, 0 }; + static ulong[] dim3631Kuo2Init = { 1, 1, 1, 7, 31, 9, 5, 221, 177, 379, 1953, 3389, 3861, 10265, 1347, 0 }; + static ulong[] dim3632Kuo2Init = { 1, 3, 5, 13, 7, 13, 57, 9, 233, 601, 719, 1855, 6481, 9987, 16463, 0 }; + static ulong[] dim3633Kuo2Init = { 1, 1, 3, 1, 15, 27, 67, 211, 289, 969, 1719, 2329, 3665, 7133, 24645, 0 }; + static ulong[] dim3634Kuo2Init = { 1, 1, 3, 9, 21, 37, 63, 11, 19, 797, 1591, 2037, 7731, 12533, 2799, 0 }; + static ulong[] dim3635Kuo2Init = { 1, 3, 5, 9, 15, 37, 1, 123, 209, 321, 737, 837, 561, 2631, 18547, 0 }; + static ulong[] dim3636Kuo2Init = { 1, 3, 1, 1, 13, 33, 27, 119, 407, 675, 903, 2229, 1963, 3857, 5795, 0 }; + static ulong[] dim3637Kuo2Init = { 1, 1, 5, 5, 9, 31, 25, 115, 471, 353, 113, 3297, 87, 9413, 25209, 0 }; + static ulong[] dim3638Kuo2Init = { 1, 3, 5, 7, 23, 27, 29, 95, 387, 747, 155, 3991, 3505, 975, 6371, 0 }; + static ulong[] dim3639Kuo2Init = { 1, 1, 5, 13, 15, 45, 3, 213, 299, 775, 525, 2639, 491, 12039, 20295, 0 }; + static ulong[] dim3640Kuo2Init = { 1, 1, 7, 15, 5, 47, 59, 131, 165, 93, 583, 3823, 7781, 16339, 16523, 0 }; + static ulong[] dim3641Kuo2Init = { 1, 3, 5, 3, 25, 61, 23, 75, 343, 15, 347, 259, 4621, 8275, 10323, 0 }; + static ulong[] dim3642Kuo2Init = { 1, 3, 3, 13, 7, 25, 1, 153, 199, 225, 1217, 161, 1185, 10775, 6709, 0 }; + static ulong[] dim3643Kuo2Init = { 1, 1, 1, 1, 1, 49, 27, 67, 411, 425, 1385, 3921, 6373, 14581, 25159, 0 }; + static ulong[] dim3644Kuo2Init = { 1, 1, 1, 11, 5, 59, 125, 239, 391, 823, 969, 3287, 7257, 5405, 15, 0 }; + static ulong[] dim3645Kuo2Init = { 1, 1, 5, 1, 1, 17, 109, 145, 289, 601, 1539, 807, 1123, 14541, 15885, 0 }; + static ulong[] dim3646Kuo2Init = { 1, 1, 3, 9, 23, 29, 119, 79, 253, 921, 1935, 4047, 7639, 10419, 26597, 0 }; + static ulong[] dim3647Kuo2Init = { 1, 1, 5, 11, 27, 53, 63, 123, 85, 121, 481, 3581, 4545, 7275, 981, 0 }; + static ulong[] dim3648Kuo2Init = { 1, 3, 3, 1, 27, 5, 43, 247, 299, 411, 299, 2545, 4403, 9903, 16161, 0 }; + static ulong[] dim3649Kuo2Init = { 1, 3, 1, 11, 29, 21, 83, 37, 425, 741, 899, 3643, 6641, 5241, 3627, 0 }; + static ulong[] dim3650Kuo2Init = { 1, 1, 7, 9, 11, 23, 43, 191, 225, 101, 1423, 927, 1303, 15417, 25553, 0 }; + static ulong[] dim3651Kuo2Init = { 1, 3, 1, 1, 23, 47, 103, 177, 437, 113, 295, 699, 1225, 8259, 19469, 0 }; + static ulong[] dim3652Kuo2Init = { 1, 1, 7, 3, 13, 61, 119, 231, 33, 217, 1419, 989, 4413, 9171, 1199, 0 }; + static ulong[] dim3653Kuo2Init = { 1, 1, 1, 1, 5, 13, 87, 185, 69, 471, 1665, 2201, 5889, 7931, 2913, 0 }; + static ulong[] dim3654Kuo2Init = { 1, 1, 1, 15, 17, 7, 111, 27, 91, 127, 301, 3641, 561, 6697, 16767, 0 }; + static ulong[] dim3655Kuo2Init = { 1, 3, 3, 9, 11, 25, 127, 139, 355, 475, 821, 843, 493, 2713, 16877, 0 }; + static ulong[] dim3656Kuo2Init = { 1, 3, 5, 7, 27, 19, 51, 127, 211, 869, 339, 2469, 1515, 9007, 28807, 0 }; + static ulong[] dim3657Kuo2Init = { 1, 1, 3, 7, 15, 23, 79, 49, 185, 465, 1165, 1103, 5975, 13867, 30039, 0 }; + static ulong[] dim3658Kuo2Init = { 1, 3, 1, 5, 27, 41, 49, 195, 23, 441, 1225, 3861, 6661, 7261, 25415, 0 }; + static ulong[] dim3659Kuo2Init = { 1, 1, 3, 3, 27, 41, 57, 139, 87, 403, 1351, 2063, 5445, 4559, 7181, 0 }; + static ulong[] dim3660Kuo2Init = { 1, 1, 3, 15, 7, 35, 43, 177, 63, 1021, 1157, 3831, 1515, 8117, 16567, 0 }; + static ulong[] dim3661Kuo2Init = { 1, 3, 7, 9, 5, 47, 59, 221, 415, 541, 857, 257, 6961, 16349, 28975, 0 }; + static ulong[] dim3662Kuo2Init = { 1, 3, 5, 9, 13, 55, 55, 63, 7, 817, 693, 1183, 7417, 7087, 31173, 0 }; + static ulong[] dim3663Kuo2Init = { 1, 3, 5, 9, 1, 29, 17, 15, 417, 559, 155, 495, 6269, 11163, 15073, 0 }; + static ulong[] dim3664Kuo2Init = { 1, 1, 5, 1, 29, 59, 49, 253, 489, 657, 1723, 1969, 471, 10821, 3527, 0 }; + static ulong[] dim3665Kuo2Init = { 1, 1, 1, 5, 29, 33, 121, 9, 73, 33, 89, 3419, 6491, 5361, 31587, 0 }; + static ulong[] dim3666Kuo2Init = { 1, 3, 3, 5, 1, 49, 121, 25, 481, 813, 607, 757, 5493, 4353, 14355, 0 }; + static ulong[] dim3667Kuo2Init = { 1, 1, 1, 1, 21, 45, 61, 101, 357, 875, 1381, 1731, 6505, 12891, 19595, 54305, 0 }; + static ulong[] dim3668Kuo2Init = { 1, 3, 7, 7, 19, 55, 99, 131, 309, 303, 1575, 3241, 6799, 6543, 26973, 46843, 0 }; + static ulong[] dim3669Kuo2Init = { 1, 1, 3, 3, 27, 11, 63, 237, 13, 949, 1359, 1563, 5501, 5293, 923, 3413, 0 }; + static ulong[] dim3670Kuo2Init = { 1, 1, 3, 7, 13, 55, 117, 143, 225, 161, 805, 3259, 4113, 8457, 461, 55507, 0 }; + static ulong[] dim3671Kuo2Init = { 1, 1, 1, 15, 15, 57, 127, 249, 409, 885, 587, 285, 7087, 11613, 725, 61955, 0 }; + static ulong[] dim3672Kuo2Init = { 1, 1, 3, 9, 21, 5, 127, 179, 193, 683, 2045, 2555, 6707, 63, 815, 57953, 0 }; + static ulong[] dim3673Kuo2Init = { 1, 3, 7, 7, 25, 45, 49, 37, 289, 431, 719, 3071, 7343, 1377, 18515, 33777, 0 }; + static ulong[] dim3674Kuo2Init = { 1, 3, 3, 7, 19, 5, 127, 29, 385, 895, 1951, 3817, 3277, 7677, 19781, 31181, 0 }; + static ulong[] dim3675Kuo2Init = { 1, 3, 3, 9, 19, 25, 105, 123, 445, 923, 801, 455, 955, 5529, 29133, 47531, 0 }; + static ulong[] dim3676Kuo2Init = { 1, 1, 3, 11, 1, 15, 51, 5, 27, 335, 523, 2859, 5605, 15197, 14669, 29623, 0 }; + static ulong[] dim3677Kuo2Init = { 1, 1, 3, 1, 11, 53, 97, 229, 477, 991, 749, 607, 6833, 6817, 2397, 31543, 0 }; + static ulong[] dim3678Kuo2Init = { 1, 3, 3, 9, 9, 45, 123, 201, 129, 587, 1373, 3733, 2331, 9741, 29441, 24711, 0 }; + static ulong[] dim3679Kuo2Init = { 1, 1, 7, 9, 1, 53, 29, 99, 475, 227, 1955, 351, 2583, 2335, 1821, 21105, 0 }; + static ulong[] dim3680Kuo2Init = { 1, 1, 7, 7, 13, 7, 121, 121, 163, 325, 13, 779, 4173, 7285, 26205, 19693, 0 }; + static ulong[] dim3681Kuo2Init = { 1, 1, 3, 13, 17, 23, 23, 167, 131, 821, 933, 1919, 853, 7525, 8195, 7357, 0 }; + static ulong[] dim3682Kuo2Init = { 1, 1, 5, 9, 21, 29, 97, 105, 85, 865, 459, 1405, 5767, 8379, 23397, 35269, 0 }; + static ulong[] dim3683Kuo2Init = { 1, 3, 3, 15, 7, 41, 125, 107, 507, 323, 149, 3475, 1149, 8811, 8295, 20543, 0 }; + static ulong[] dim3684Kuo2Init = { 1, 1, 5, 11, 13, 35, 41, 249, 195, 603, 873, 3825, 1679, 11727, 13839, 22241, 0 }; + static ulong[] dim3685Kuo2Init = { 1, 3, 5, 3, 13, 15, 19, 113, 141, 7, 627, 1285, 6701, 15921, 4235, 30879, 0 }; + static ulong[] dim3686Kuo2Init = { 1, 1, 7, 9, 15, 57, 65, 239, 49, 657, 673, 4039, 5493, 2487, 1807, 14341, 0 }; + static ulong[] dim3687Kuo2Init = { 1, 1, 1, 13, 25, 47, 19, 191, 177, 163, 1721, 3473, 6667, 10017, 19863, 43803, 0 }; + static ulong[] dim3688Kuo2Init = { 1, 3, 5, 11, 15, 39, 33, 95, 353, 121, 503, 3025, 4773, 3853, 14263, 61149, 0 }; + static ulong[] dim3689Kuo2Init = { 1, 1, 5, 3, 1, 57, 7, 105, 363, 797, 635, 23, 1795, 13501, 45, 22081, 0 }; + static ulong[] dim3690Kuo2Init = { 1, 3, 7, 15, 19, 21, 9, 237, 249, 641, 1599, 3623, 2941, 12917, 5511, 18017, 0 }; + static ulong[] dim3691Kuo2Init = { 1, 1, 5, 9, 17, 57, 81, 165, 315, 985, 1965, 3571, 2693, 11591, 13675, 36739, 0 }; + static ulong[] dim3692Kuo2Init = { 1, 1, 7, 15, 5, 3, 11, 247, 79, 707, 1601, 2301, 7281, 4871, 26735, 14277, 0 }; + static ulong[] dim3693Kuo2Init = { 1, 1, 5, 7, 17, 27, 101, 211, 507, 95, 1333, 2919, 1251, 3905, 1897, 12791, 0 }; + static ulong[] dim3694Kuo2Init = { 1, 3, 5, 15, 29, 15, 119, 3, 181, 621, 349, 2509, 295, 15719, 1593, 27333, 0 }; + static ulong[] dim3695Kuo2Init = { 1, 1, 7, 9, 9, 29, 75, 245, 353, 147, 1197, 2571, 7033, 15903, 28319, 7733, 0 }; + static ulong[] dim3696Kuo2Init = { 1, 1, 7, 11, 19, 23, 53, 41, 377, 673, 1843, 1283, 1343, 2089, 12295, 33189, 0 }; + static ulong[] dim3697Kuo2Init = { 1, 1, 1, 9, 17, 21, 17, 251, 399, 531, 2007, 3449, 265, 289, 15937, 19571, 0 }; + static ulong[] dim3698Kuo2Init = { 1, 1, 5, 15, 15, 53, 21, 141, 387, 885, 1409, 2883, 2101, 4741, 597, 23435, 0 }; + static ulong[] dim3699Kuo2Init = { 1, 3, 1, 7, 27, 63, 33, 157, 331, 921, 1097, 3963, 3275, 14909, 2359, 12327, 0 }; + static ulong[] dim3700Kuo2Init = { 1, 1, 3, 11, 15, 7, 121, 235, 219, 181, 1305, 3877, 2233, 4921, 31409, 28211, 0 }; + static ulong[] dim3701Kuo2Init = { 1, 3, 3, 7, 23, 25, 67, 147, 211, 757, 1903, 3077, 3931, 11885, 3053, 45709, 0 }; + static ulong[] dim3702Kuo2Init = { 1, 1, 1, 5, 29, 21, 121, 115, 231, 957, 203, 689, 5521, 2467, 21489, 10057, 0 }; + static ulong[] dim3703Kuo2Init = { 1, 1, 5, 9, 15, 17, 11, 177, 319, 547, 801, 3899, 5919, 8785, 12019, 2535, 0 }; + static ulong[] dim3704Kuo2Init = { 1, 3, 1, 3, 21, 51, 83, 121, 317, 715, 467, 3587, 383, 3519, 26731, 64151, 0 }; + static ulong[] dim3705Kuo2Init = { 1, 3, 3, 13, 31, 47, 41, 247, 211, 333, 691, 2679, 4599, 2479, 27687, 45793, 0 }; + static ulong[] dim3706Kuo2Init = { 1, 1, 1, 11, 31, 9, 41, 241, 439, 391, 949, 2957, 5105, 5073, 7607, 4809, 0 }; + static ulong[] dim3707Kuo2Init = { 1, 1, 1, 9, 5, 57, 11, 167, 193, 1019, 533, 2559, 3899, 15199, 13723, 1909, 0 }; + static ulong[] dim3708Kuo2Init = { 1, 3, 3, 3, 5, 17, 5, 21, 445, 857, 2017, 2759, 5011, 8415, 881, 15747, 0 }; + static ulong[] dim3709Kuo2Init = { 1, 1, 1, 1, 1, 25, 31, 61, 407, 71, 263, 681, 5325, 13747, 10833, 12191, 0 }; + static ulong[] dim3710Kuo2Init = { 1, 3, 3, 9, 27, 3, 73, 145, 5, 851, 1519, 2809, 5857, 2327, 32659, 11145, 0 }; + static ulong[] dim3711Kuo2Init = { 1, 3, 3, 5, 21, 3, 47, 11, 17, 1023, 621, 3527, 613, 5607, 19377, 49671, 0 }; + static ulong[] dim3712Kuo2Init = { 1, 3, 1, 11, 5, 5, 57, 39, 221, 847, 735, 3951, 6661, 13959, 16735, 26471, 0 }; + static ulong[] dim3713Kuo2Init = { 1, 3, 1, 11, 3, 31, 15, 121, 31, 689, 151, 849, 2859, 14903, 6065, 9203, 0 }; + static ulong[] dim3714Kuo2Init = { 1, 3, 3, 9, 5, 63, 27, 51, 379, 657, 1381, 67, 2733, 7673, 13217, 14265, 0 }; + static ulong[] dim3715Kuo2Init = { 1, 1, 7, 15, 27, 63, 21, 25, 315, 101, 851, 2585, 4423, 7857, 30561, 60301, 0 }; + static ulong[] dim3716Kuo2Init = { 1, 3, 3, 11, 21, 51, 9, 39, 123, 763, 1777, 3427, 5071, 7905, 1017, 15373, 0 }; + static ulong[] dim3717Kuo2Init = { 1, 3, 1, 7, 25, 59, 3, 223, 71, 33, 731, 2303, 7153, 12847, 9707, 50871, 0 }; + static ulong[] dim3718Kuo2Init = { 1, 1, 5, 11, 31, 61, 13, 155, 467, 501, 371, 1447, 7925, 13135, 27629, 45097, 0 }; + static ulong[] dim3719Kuo2Init = { 1, 1, 1, 1, 13, 25, 35, 153, 333, 9, 1609, 539, 5029, 2059, 3547, 55407, 0 }; + static ulong[] dim3720Kuo2Init = { 1, 1, 7, 9, 21, 55, 101, 199, 279, 77, 1337, 3503, 2365, 4969, 2411, 16853, 0 }; + static ulong[] dim3721Kuo2Init = { 1, 1, 7, 11, 29, 9, 111, 63, 435, 445, 1711, 3981, 6517, 14593, 29433, 31027, 0 }; + static ulong[] dim3722Kuo2Init = { 1, 1, 7, 1, 15, 57, 43, 137, 189, 83, 187, 417, 3425, 14653, 17805, 57685, 0 }; + static ulong[] dim3723Kuo2Init = { 1, 1, 5, 3, 27, 23, 71, 65, 399, 605, 421, 463, 2019, 10707, 26201, 23573, 0 }; + static ulong[] dim3724Kuo2Init = { 1, 1, 3, 15, 17, 57, 119, 125, 365, 681, 1967, 241, 7647, 13317, 23661, 55683, 0 }; + static ulong[] dim3725Kuo2Init = { 1, 1, 7, 1, 7, 63, 91, 161, 45, 533, 1833, 2465, 5081, 6341, 16713, 34685, 0 }; + static ulong[] dim3726Kuo2Init = { 1, 3, 1, 9, 23, 9, 43, 157, 307, 521, 1611, 3851, 6943, 14939, 13833, 20099, 0 }; + static ulong[] dim3727Kuo2Init = { 1, 1, 5, 3, 27, 13, 35, 131, 129, 257, 1015, 1849, 6645, 11567, 13385, 30943, 0 }; + static ulong[] dim3728Kuo2Init = { 1, 1, 5, 1, 21, 49, 101, 77, 301, 541, 481, 2903, 8121, 2689, 21541, 25337, 0 }; + static ulong[] dim3729Kuo2Init = { 1, 1, 5, 11, 1, 13, 125, 209, 327, 245, 1055, 1097, 4931, 15721, 8193, 19923, 0 }; + static ulong[] dim3730Kuo2Init = { 1, 1, 1, 11, 17, 31, 85, 159, 405, 287, 1083, 1679, 6227, 305, 9549, 27303, 0 }; + static ulong[] dim3731Kuo2Init = { 1, 1, 1, 13, 7, 45, 125, 181, 219, 811, 1471, 999, 93, 12845, 4597, 60641, 0 }; + static ulong[] dim3732Kuo2Init = { 1, 3, 5, 7, 29, 23, 109, 37, 367, 185, 1467, 1871, 6349, 8563, 8743, 30277, 0 }; + static ulong[] dim3733Kuo2Init = { 1, 1, 1, 15, 19, 23, 75, 93, 191, 993, 1111, 1531, 2105, 8869, 27217, 16609, 0 }; + static ulong[] dim3734Kuo2Init = { 1, 3, 1, 15, 31, 29, 23, 145, 467, 465, 637, 3169, 889, 9225, 17917, 8379, 0 }; + static ulong[] dim3735Kuo2Init = { 1, 3, 5, 1, 1, 33, 7, 209, 99, 753, 113, 2945, 345, 14091, 13169, 4799, 0 }; + static ulong[] dim3736Kuo2Init = { 1, 3, 3, 11, 21, 5, 9, 97, 347, 537, 1287, 1401, 815, 9289, 17259, 11755, 0 }; + static ulong[] dim3737Kuo2Init = { 1, 1, 5, 1, 7, 9, 21, 87, 495, 685, 1675, 1909, 4215, 1589, 18229, 2253, 0 }; + static ulong[] dim3738Kuo2Init = { 1, 1, 1, 3, 7, 29, 121, 67, 383, 351, 1555, 3091, 3677, 3489, 30241, 55309, 0 }; + static ulong[] dim3739Kuo2Init = { 1, 1, 7, 11, 21, 39, 33, 201, 195, 601, 1235, 3499, 1657, 4495, 26501, 49783, 0 }; + static ulong[] dim3740Kuo2Init = { 1, 1, 5, 1, 15, 37, 91, 169, 65, 471, 1409, 3017, 1071, 15331, 27085, 22837, 0 }; + static ulong[] dim3741Kuo2Init = { 1, 1, 5, 13, 23, 45, 115, 153, 27, 773, 637, 2673, 79, 4275, 21133, 38509, 0 }; + static ulong[] dim3742Kuo2Init = { 1, 3, 1, 13, 17, 53, 49, 55, 439, 255, 383, 1057, 4995, 3853, 29839, 2529, 0 }; + static ulong[] dim3743Kuo2Init = { 1, 3, 5, 9, 17, 29, 73, 205, 1, 685, 991, 3563, 4281, 2341, 27111, 36609, 0 }; + static ulong[] dim3744Kuo2Init = { 1, 3, 5, 9, 19, 25, 65, 167, 425, 289, 963, 1653, 131, 4599, 4615, 57653, 0 }; + static ulong[] dim3745Kuo2Init = { 1, 1, 1, 11, 19, 57, 93, 239, 375, 739, 1101, 881, 7391, 921, 11493, 50417, 0 }; + static ulong[] dim3746Kuo2Init = { 1, 3, 5, 15, 7, 33, 5, 59, 381, 123, 33, 1903, 2639, 12073, 511, 659, 0 }; + static ulong[] dim3747Kuo2Init = { 1, 1, 3, 1, 23, 1, 77, 55, 455, 687, 1825, 1355, 2997, 615, 123, 17611, 0 }; + static ulong[] dim3748Kuo2Init = { 1, 1, 7, 13, 25, 61, 119, 101, 397, 645, 485, 3361, 899, 5103, 3307, 9765, 0 }; + static ulong[] dim3749Kuo2Init = { 1, 3, 1, 3, 25, 59, 27, 245, 3, 915, 1001, 977, 7913, 4667, 24845, 37183, 0 }; + static ulong[] dim3750Kuo2Init = { 1, 1, 7, 15, 19, 21, 1, 233, 175, 347, 1335, 2757, 1615, 8381, 10611, 32409, 0 }; + static ulong[] dim3751Kuo2Init = { 1, 1, 7, 15, 23, 33, 7, 51, 235, 735, 615, 3305, 4555, 15079, 21309, 55397, 0 }; + static ulong[] dim3752Kuo2Init = { 1, 3, 1, 3, 19, 49, 59, 213, 155, 23, 239, 753, 1473, 6869, 19993, 14383, 0 }; + static ulong[] dim3753Kuo2Init = { 1, 1, 5, 9, 17, 37, 23, 163, 45, 409, 1103, 289, 4707, 12657, 26033, 27547, 0 }; + static ulong[] dim3754Kuo2Init = { 1, 3, 7, 9, 23, 49, 83, 63, 79, 643, 107, 3041, 1921, 10343, 19179, 4961, 0 }; + static ulong[] dim3755Kuo2Init = { 1, 1, 7, 7, 31, 7, 81, 145, 281, 751, 867, 535, 6593, 7255, 13785, 62137, 0 }; + static ulong[] dim3756Kuo2Init = { 1, 1, 7, 1, 13, 55, 59, 203, 329, 421, 483, 2931, 521, 3013, 1077, 3405, 0 }; + static ulong[] dim3757Kuo2Init = { 1, 3, 5, 1, 15, 13, 21, 205, 187, 491, 887, 893, 3917, 6989, 23569, 48729, 0 }; + static ulong[] dim3758Kuo2Init = { 1, 1, 3, 11, 15, 35, 63, 109, 157, 643, 961, 3713, 1459, 8585, 6113, 7339, 0 }; + static ulong[] dim3759Kuo2Init = { 1, 3, 7, 9, 7, 53, 57, 251, 203, 701, 2041, 73, 7637, 12745, 8003, 45849, 0 }; + static ulong[] dim3760Kuo2Init = { 1, 3, 5, 1, 23, 27, 109, 211, 273, 1013, 19, 2499, 377, 5185, 25261, 8997, 0 }; + static ulong[] dim3761Kuo2Init = { 1, 3, 7, 15, 3, 35, 41, 85, 391, 409, 1945, 25, 6069, 3499, 10879, 38239, 0 }; + static ulong[] dim3762Kuo2Init = { 1, 3, 1, 3, 3, 37, 65, 229, 441, 675, 909, 3887, 7347, 3221, 1935, 65147, 0 }; + static ulong[] dim3763Kuo2Init = { 1, 3, 5, 13, 13, 29, 119, 29, 277, 303, 685, 1921, 4863, 12483, 9303, 59355, 0 }; + static ulong[] dim3764Kuo2Init = { 1, 1, 1, 9, 21, 43, 115, 253, 349, 655, 779, 1965, 4831, 6491, 16051, 6975, 0 }; + static ulong[] dim3765Kuo2Init = { 1, 3, 3, 7, 1, 9, 55, 253, 21, 655, 133, 3777, 4239, 14447, 7221, 59819, 0 }; + static ulong[] dim3766Kuo2Init = { 1, 1, 7, 3, 19, 49, 11, 93, 39, 149, 683, 3295, 6519, 12187, 2231, 39829, 0 }; + static ulong[] dim3767Kuo2Init = { 1, 3, 7, 5, 23, 9, 101, 197, 3, 873, 1459, 747, 6939, 5629, 27305, 32235, 0 }; + static ulong[] dim3768Kuo2Init = { 1, 1, 5, 7, 13, 9, 31, 251, 481, 877, 773, 993, 4431, 12081, 15987, 27081, 0 }; + static ulong[] dim3769Kuo2Init = { 1, 1, 1, 1, 9, 49, 13, 89, 39, 797, 815, 319, 5917, 621, 25867, 46433, 0 }; + static ulong[] dim3770Kuo2Init = { 1, 3, 1, 7, 23, 27, 83, 123, 83, 177, 1001, 995, 2765, 6401, 15593, 20205, 0 }; + static ulong[] dim3771Kuo2Init = { 1, 1, 5, 13, 25, 9, 59, 123, 141, 737, 1111, 1883, 2647, 733, 3551, 44453, 0 }; + static ulong[] dim3772Kuo2Init = { 1, 3, 1, 5, 7, 49, 25, 177, 297, 87, 1039, 1917, 3167, 11025, 22959, 63929, 0 }; + static ulong[] dim3773Kuo2Init = { 1, 1, 1, 3, 17, 57, 103, 99, 127, 579, 903, 2835, 607, 9723, 22397, 36621, 0 }; + static ulong[] dim3774Kuo2Init = { 1, 1, 3, 15, 13, 47, 77, 213, 383, 371, 887, 281, 6171, 10383, 12157, 57899, 0 }; + static ulong[] dim3775Kuo2Init = { 1, 3, 1, 5, 5, 15, 65, 119, 303, 265, 783, 3075, 7893, 441, 22065, 52157, 0 }; + static ulong[] dim3776Kuo2Init = { 1, 3, 5, 15, 7, 49, 105, 145, 301, 57, 1949, 3073, 435, 1171, 27691, 34821, 0 }; + static ulong[] dim3777Kuo2Init = { 1, 3, 1, 11, 5, 31, 33, 159, 319, 437, 453, 1005, 3335, 5895, 15407, 159, 0 }; + static ulong[] dim3778Kuo2Init = { 1, 3, 3, 9, 31, 15, 69, 129, 221, 991, 1879, 1251, 5303, 6677, 15823, 46319, 0 }; + static ulong[] dim3779Kuo2Init = { 1, 3, 7, 11, 1, 47, 49, 13, 401, 755, 1703, 2021, 5195, 9489, 9191, 30427, 0 }; + static ulong[] dim3780Kuo2Init = { 1, 1, 7, 9, 7, 11, 25, 147, 471, 31, 489, 3477, 3025, 4011, 7733, 22091, 0 }; + static ulong[] dim3781Kuo2Init = { 1, 1, 5, 9, 7, 7, 99, 23, 397, 67, 2027, 3885, 3269, 15385, 24367, 1715, 0 }; + static ulong[] dim3782Kuo2Init = { 1, 1, 5, 1, 7, 45, 83, 159, 501, 561, 993, 1495, 4415, 2559, 27, 60825, 0 }; + static ulong[] dim3783Kuo2Init = { 1, 3, 1, 7, 7, 43, 99, 159, 117, 453, 1841, 1807, 1881, 12513, 16413, 37993, 0 }; + static ulong[] dim3784Kuo2Init = { 1, 3, 1, 13, 15, 37, 53, 173, 279, 415, 535, 2553, 3995, 8245, 4507, 19575, 0 }; + static ulong[] dim3785Kuo2Init = { 1, 1, 7, 9, 25, 7, 79, 25, 105, 525, 1179, 1793, 4899, 10253, 22655, 1419, 0 }; + static ulong[] dim3786Kuo2Init = { 1, 1, 5, 11, 11, 35, 77, 139, 449, 879, 619, 1645, 3309, 37, 10607, 43757, 0 }; + static ulong[] dim3787Kuo2Init = { 1, 1, 1, 13, 17, 17, 7, 69, 389, 733, 775, 791, 5451, 15737, 9043, 16573, 0 }; + static ulong[] dim3788Kuo2Init = { 1, 1, 7, 5, 15, 57, 81, 19, 307, 207, 241, 449, 7745, 521, 16975, 11907, 0 }; + static ulong[] dim3789Kuo2Init = { 1, 1, 1, 5, 25, 1, 55, 229, 123, 809, 1673, 3461, 7729, 8615, 8755, 35929, 0 }; + static ulong[] dim3790Kuo2Init = { 1, 3, 3, 1, 23, 7, 19, 235, 375, 79, 899, 21, 7681, 7169, 13057, 1379, 0 }; + static ulong[] dim3791Kuo2Init = { 1, 3, 3, 7, 29, 49, 93, 217, 409, 263, 225, 2333, 1621, 14741, 4933, 58263, 0 }; + static ulong[] dim3792Kuo2Init = { 1, 3, 1, 13, 11, 35, 19, 55, 71, 937, 551, 1693, 3843, 7411, 29501, 31525, 0 }; + static ulong[] dim3793Kuo2Init = { 1, 1, 5, 13, 17, 17, 105, 31, 181, 915, 321, 3161, 5247, 13317, 23595, 21783, 0 }; + static ulong[] dim3794Kuo2Init = { 1, 3, 5, 15, 31, 19, 85, 71, 55, 933, 1425, 2419, 2891, 15813, 18209, 30347, 0 }; + static ulong[] dim3795Kuo2Init = { 1, 1, 7, 9, 1, 45, 31, 1, 193, 445, 1293, 2563, 5837, 6113, 5741, 12245, 0 }; + static ulong[] dim3796Kuo2Init = { 1, 3, 5, 9, 25, 25, 7, 155, 267, 65, 2015, 2021, 6331, 6973, 1303, 14833, 0 }; + static ulong[] dim3797Kuo2Init = { 1, 1, 5, 11, 21, 31, 87, 21, 509, 555, 429, 1405, 4417, 1891, 15679, 3819, 0 }; + static ulong[] dim3798Kuo2Init = { 1, 3, 7, 3, 19, 49, 53, 251, 423, 949, 971, 425, 1589, 5257, 19021, 16817, 0 }; + static ulong[] dim3799Kuo2Init = { 1, 1, 5, 7, 1, 27, 71, 185, 357, 1009, 897, 491, 6433, 6717, 23445, 29097, 0 }; + static ulong[] dim3800Kuo2Init = { 1, 3, 7, 15, 9, 39, 87, 25, 149, 291, 1249, 3987, 7441, 11225, 18051, 17747, 0 }; + static ulong[] dim3801Kuo2Init = { 1, 1, 7, 1, 13, 61, 13, 141, 39, 317, 579, 2181, 6735, 14749, 25997, 16025, 0 }; + static ulong[] dim3802Kuo2Init = { 1, 1, 7, 7, 27, 19, 127, 231, 13, 7, 1707, 87, 7379, 8171, 27435, 47911, 0 }; + static ulong[] dim3803Kuo2Init = { 1, 1, 1, 15, 21, 33, 33, 85, 205, 321, 785, 4051, 2503, 15589, 10881, 63103, 0 }; + static ulong[] dim3804Kuo2Init = { 1, 1, 1, 3, 15, 11, 31, 105, 185, 113, 293, 3279, 4867, 9249, 14403, 24951, 0 }; + static ulong[] dim3805Kuo2Init = { 1, 3, 5, 13, 7, 47, 105, 253, 117, 577, 2019, 2089, 1357, 5299, 27961, 36675, 0 }; + static ulong[] dim3806Kuo2Init = { 1, 1, 1, 7, 31, 33, 117, 51, 283, 453, 1657, 1343, 6491, 649, 1029, 44809, 0 }; + static ulong[] dim3807Kuo2Init = { 1, 1, 1, 3, 3, 45, 121, 155, 191, 607, 1087, 3291, 8171, 3757, 14247, 49647, 0 }; + static ulong[] dim3808Kuo2Init = { 1, 3, 1, 3, 7, 17, 109, 163, 87, 63, 573, 3127, 3361, 6733, 26729, 44427, 0 }; + static ulong[] dim3809Kuo2Init = { 1, 1, 1, 5, 13, 23, 29, 173, 487, 345, 351, 3401, 4611, 5591, 6209, 58537, 0 }; + static ulong[] dim3810Kuo2Init = { 1, 3, 1, 5, 23, 49, 31, 51, 157, 623, 1103, 681, 6645, 2147, 1715, 42253, 0 }; + static ulong[] dim3811Kuo2Init = { 1, 1, 7, 9, 7, 61, 85, 129, 309, 701, 1139, 3211, 4943, 8365, 20727, 51025, 0 }; + static ulong[] dim3812Kuo2Init = { 1, 1, 3, 11, 29, 47, 119, 181, 109, 403, 1459, 39, 609, 7405, 25651, 61395, 0 }; + static ulong[] dim3813Kuo2Init = { 1, 3, 3, 7, 5, 55, 65, 155, 273, 177, 1879, 3901, 3219, 8699, 10445, 40141, 0 }; + static ulong[] dim3814Kuo2Init = { 1, 3, 7, 15, 3, 11, 45, 85, 473, 1013, 1725, 155, 3369, 7345, 1475, 28781, 0 }; + static ulong[] dim3815Kuo2Init = { 1, 1, 1, 11, 13, 61, 31, 217, 111, 719, 161, 1053, 1451, 10437, 28909, 1173, 0 }; + static ulong[] dim3816Kuo2Init = { 1, 1, 3, 11, 9, 21, 119, 119, 355, 563, 855, 853, 4243, 5201, 2521, 41389, 0 }; + static ulong[] dim3817Kuo2Init = { 1, 1, 5, 15, 9, 5, 15, 79, 489, 499, 1065, 2073, 7567, 5385, 9329, 17643, 0 }; + static ulong[] dim3818Kuo2Init = { 1, 3, 3, 7, 15, 53, 61, 225, 381, 217, 163, 4005, 7269, 4481, 23697, 46055, 0 }; + static ulong[] dim3819Kuo2Init = { 1, 3, 3, 13, 1, 55, 77, 95, 345, 113, 1359, 539, 6979, 5459, 9551, 45035, 0 }; + static ulong[] dim3820Kuo2Init = { 1, 1, 5, 3, 5, 45, 93, 147, 387, 165, 1529, 1243, 7639, 5531, 22381, 63517, 0 }; + static ulong[] dim3821Kuo2Init = { 1, 1, 3, 1, 9, 27, 109, 161, 71, 547, 259, 1399, 5815, 1569, 26627, 63133, 0 }; + static ulong[] dim3822Kuo2Init = { 1, 1, 3, 3, 29, 37, 21, 205, 49, 863, 707, 307, 573, 3167, 17595, 63485, 0 }; + static ulong[] dim3823Kuo2Init = { 1, 1, 5, 1, 17, 15, 95, 21, 111, 991, 657, 3865, 8091, 7589, 30487, 63229, 0 }; + static ulong[] dim3824Kuo2Init = { 1, 1, 1, 7, 29, 11, 65, 201, 357, 269, 281, 1329, 6359, 7875, 23561, 44489, 0 }; + static ulong[] dim3825Kuo2Init = { 1, 1, 7, 7, 27, 29, 1, 15, 475, 393, 1917, 3605, 4463, 7809, 16529, 64599, 0 }; + static ulong[] dim3826Kuo2Init = { 1, 3, 5, 13, 29, 15, 11, 255, 315, 209, 895, 2813, 2263, 7095, 1447, 55307, 0 }; + static ulong[] dim3827Kuo2Init = { 1, 3, 1, 15, 17, 11, 73, 57, 13, 529, 35, 1065, 81, 13801, 19531, 27249, 0 }; + static ulong[] dim3828Kuo2Init = { 1, 3, 1, 11, 19, 15, 117, 235, 219, 109, 1885, 4005, 3565, 2591, 29233, 47111, 0 }; + static ulong[] dim3829Kuo2Init = { 1, 3, 3, 11, 21, 35, 27, 227, 393, 57, 1637, 537, 2463, 4483, 32153, 22035, 0 }; + static ulong[] dim3830Kuo2Init = { 1, 1, 7, 5, 13, 9, 79, 147, 341, 1007, 1093, 3837, 5581, 3363, 10637, 60109, 0 }; + static ulong[] dim3831Kuo2Init = { 1, 3, 5, 13, 31, 49, 121, 231, 485, 947, 127, 1817, 3005, 11085, 14157, 21145, 0 }; + static ulong[] dim3832Kuo2Init = { 1, 1, 3, 1, 1, 23, 17, 195, 351, 527, 1787, 3885, 2281, 729, 25083, 63523, 0 }; + static ulong[] dim3833Kuo2Init = { 1, 3, 5, 15, 19, 31, 51, 5, 55, 551, 33, 1735, 427, 2859, 3941, 48639, 0 }; + static ulong[] dim3834Kuo2Init = { 1, 3, 7, 7, 11, 59, 101, 125, 167, 311, 1487, 969, 5023, 3893, 22065, 48803, 0 }; + static ulong[] dim3835Kuo2Init = { 1, 3, 3, 11, 27, 11, 77, 43, 295, 31, 1061, 2999, 4451, 10339, 9213, 63705, 0 }; + static ulong[] dim3836Kuo2Init = { 1, 3, 1, 11, 1, 63, 83, 179, 413, 317, 1921, 2917, 6697, 6637, 5291, 48791, 0 }; + static ulong[] dim3837Kuo2Init = { 1, 1, 3, 3, 19, 57, 55, 159, 137, 291, 1353, 81, 2495, 12315, 31031, 41081, 0 }; + static ulong[] dim3838Kuo2Init = { 1, 1, 3, 3, 25, 49, 49, 239, 53, 999, 303, 3083, 2455, 3977, 13945, 22667, 0 }; + static ulong[] dim3839Kuo2Init = { 1, 3, 5, 15, 7, 15, 85, 215, 463, 301, 1061, 3993, 5927, 703, 23083, 44633, 0 }; + static ulong[] dim3840Kuo2Init = { 1, 3, 3, 1, 9, 53, 21, 165, 129, 697, 1867, 2427, 5383, 13223, 12127, 60477, 0 }; + static ulong[] dim3841Kuo2Init = { 1, 3, 5, 5, 17, 13, 37, 151, 337, 425, 829, 2415, 1705, 10389, 26299, 45655, 0 }; + static ulong[] dim3842Kuo2Init = { 1, 3, 1, 9, 13, 3, 99, 111, 371, 589, 605, 3137, 4515, 5303, 6151, 14225, 0 }; + static ulong[] dim3843Kuo2Init = { 1, 1, 3, 11, 15, 59, 31, 95, 305, 133, 751, 13, 7691, 2603, 21761, 18577, 0 }; + static ulong[] dim3844Kuo2Init = { 1, 1, 1, 13, 25, 47, 93, 251, 341, 465, 1043, 3391, 271, 3431, 16465, 53283, 0 }; + static ulong[] dim3845Kuo2Init = { 1, 1, 5, 9, 31, 1, 31, 77, 383, 151, 1243, 3165, 2363, 13751, 10251, 55111, 0 }; + static ulong[] dim3846Kuo2Init = { 1, 1, 5, 13, 23, 35, 123, 229, 193, 29, 201, 2661, 7539, 10407, 30831, 56091, 0 }; + static ulong[] dim3847Kuo2Init = { 1, 1, 5, 15, 19, 17, 83, 157, 265, 649, 815, 531, 3905, 10691, 4137, 29875, 0 }; + static ulong[] dim3848Kuo2Init = { 1, 1, 3, 7, 29, 41, 29, 153, 509, 617, 151, 2409, 4631, 6525, 8539, 20855, 0 }; + static ulong[] dim3849Kuo2Init = { 1, 1, 1, 5, 27, 37, 55, 215, 135, 463, 163, 1415, 1457, 2675, 9461, 6585, 0 }; + static ulong[] dim3850Kuo2Init = { 1, 3, 5, 7, 23, 17, 29, 183, 33, 593, 717, 1487, 4777, 6281, 3299, 37531, 0 }; + static ulong[] dim3851Kuo2Init = { 1, 1, 5, 15, 15, 17, 91, 243, 259, 655, 1347, 3229, 1449, 10069, 2671, 11391, 0 }; + static ulong[] dim3852Kuo2Init = { 1, 1, 7, 15, 17, 35, 35, 105, 285, 761, 1989, 3427, 3649, 223, 21887, 6153, 0 }; + static ulong[] dim3853Kuo2Init = { 1, 3, 1, 5, 17, 55, 47, 235, 7, 829, 1437, 1669, 2837, 6573, 3847, 32347, 0 }; + static ulong[] dim3854Kuo2Init = { 1, 1, 5, 11, 5, 19, 41, 151, 59, 427, 1917, 3339, 4139, 13781, 15171, 50597, 0 }; + static ulong[] dim3855Kuo2Init = { 1, 3, 5, 1, 3, 47, 77, 175, 239, 729, 1957, 2941, 4749, 15157, 30351, 57657, 0 }; + static ulong[] dim3856Kuo2Init = { 1, 3, 5, 1, 23, 39, 51, 239, 455, 347, 1673, 1355, 1707, 10125, 18923, 53953, 0 }; + static ulong[] dim3857Kuo2Init = { 1, 3, 3, 11, 5, 21, 113, 161, 325, 663, 9, 641, 4089, 7043, 9771, 16719, 0 }; + static ulong[] dim3858Kuo2Init = { 1, 3, 7, 7, 1, 63, 3, 77, 67, 575, 313, 1249, 1203, 8121, 13647, 563, 0 }; + static ulong[] dim3859Kuo2Init = { 1, 3, 3, 15, 17, 61, 95, 75, 421, 671, 835, 4015, 6591, 7589, 8039, 10055, 0 }; + static ulong[] dim3860Kuo2Init = { 1, 1, 3, 3, 27, 43, 75, 121, 143, 235, 1243, 2063, 7711, 7925, 2943, 23419, 0 }; + static ulong[] dim3861Kuo2Init = { 1, 3, 5, 15, 1, 21, 41, 225, 427, 843, 1417, 3481, 5239, 16373, 11599, 37267, 0 }; + static ulong[] dim3862Kuo2Init = { 1, 1, 7, 15, 17, 23, 95, 185, 193, 471, 1475, 861, 5115, 4573, 12909, 12337, 0 }; + static ulong[] dim3863Kuo2Init = { 1, 3, 1, 7, 19, 25, 107, 171, 355, 57, 1301, 2343, 6425, 5537, 29391, 27187, 0 }; + static ulong[] dim3864Kuo2Init = { 1, 3, 5, 9, 19, 35, 67, 157, 183, 477, 961, 1087, 7329, 15787, 9547, 59001, 0 }; + static ulong[] dim3865Kuo2Init = { 1, 1, 3, 5, 29, 57, 29, 119, 315, 533, 717, 1099, 713, 1473, 19511, 59777, 0 }; + static ulong[] dim3866Kuo2Init = { 1, 3, 7, 7, 17, 63, 71, 181, 103, 943, 305, 1657, 6117, 11921, 6119, 26437, 0 }; + static ulong[] dim3867Kuo2Init = { 1, 3, 7, 9, 3, 61, 91, 65, 389, 331, 549, 2355, 4591, 3385, 19913, 62541, 0 }; + static ulong[] dim3868Kuo2Init = { 1, 1, 5, 1, 17, 1, 127, 127, 471, 139, 1147, 1463, 5403, 10877, 11469, 65283, 0 }; + static ulong[] dim3869Kuo2Init = { 1, 3, 1, 13, 27, 29, 31, 57, 433, 941, 1559, 2495, 83, 14701, 20787, 10761, 0 }; + static ulong[] dim3870Kuo2Init = { 1, 3, 3, 9, 23, 59, 23, 175, 25, 865, 751, 3395, 4111, 10287, 28191, 38487, 0 }; + static ulong[] dim3871Kuo2Init = { 1, 1, 3, 7, 21, 3, 107, 205, 349, 473, 1115, 1647, 2379, 4709, 21697, 47899, 0 }; + static ulong[] dim3872Kuo2Init = { 1, 3, 5, 15, 27, 49, 113, 73, 487, 487, 1531, 357, 8073, 10275, 7713, 9169, 0 }; + static ulong[] dim3873Kuo2Init = { 1, 3, 3, 13, 1, 55, 97, 19, 5, 997, 1, 437, 343, 4867, 4897, 20291, 0 }; + static ulong[] dim3874Kuo2Init = { 1, 3, 7, 5, 19, 51, 25, 3, 143, 783, 1415, 2231, 1809, 2011, 32607, 33817, 0 }; + static ulong[] dim3875Kuo2Init = { 1, 1, 5, 1, 3, 59, 49, 183, 447, 55, 17, 1455, 3753, 13531, 17193, 22375, 0 }; + static ulong[] dim3876Kuo2Init = { 1, 3, 7, 5, 21, 55, 25, 79, 161, 763, 815, 2161, 1639, 7165, 15681, 53681, 0 }; + static ulong[] dim3877Kuo2Init = { 1, 3, 7, 3, 15, 53, 75, 243, 49, 701, 519, 1781, 8073, 16349, 487, 35051, 0 }; + static ulong[] dim3878Kuo2Init = { 1, 3, 3, 15, 11, 33, 65, 93, 157, 499, 1487, 627, 4483, 9001, 26869, 11713, 0 }; + static ulong[] dim3879Kuo2Init = { 1, 1, 3, 9, 15, 43, 29, 159, 125, 329, 1619, 41, 2565, 6043, 23983, 33397, 0 }; + static ulong[] dim3880Kuo2Init = { 1, 1, 1, 9, 31, 25, 71, 53, 109, 415, 1895, 309, 5121, 3659, 24591, 5207, 0 }; + static ulong[] dim3881Kuo2Init = { 1, 3, 1, 5, 23, 33, 35, 95, 171, 395, 171, 1085, 6629, 757, 29347, 22703, 0 }; + static ulong[] dim3882Kuo2Init = { 1, 1, 7, 5, 17, 59, 35, 9, 141, 311, 1075, 2499, 321, 14733, 4069, 46015, 0 }; + static ulong[] dim3883Kuo2Init = { 1, 1, 1, 13, 5, 27, 93, 105, 205, 875, 1867, 2423, 3015, 2939, 27529, 24221, 0 }; + static ulong[] dim3884Kuo2Init = { 1, 1, 1, 15, 21, 51, 55, 239, 95, 517, 1449, 537, 8083, 11519, 30293, 56663, 0 }; + static ulong[] dim3885Kuo2Init = { 1, 3, 5, 7, 3, 1, 31, 77, 75, 343, 423, 3781, 1171, 5331, 8885, 1917, 0 }; + static ulong[] dim3886Kuo2Init = { 1, 3, 1, 13, 1, 45, 127, 123, 153, 769, 1549, 3049, 4023, 10475, 3185, 7973, 0 }; + static ulong[] dim3887Kuo2Init = { 1, 3, 5, 15, 17, 17, 63, 197, 483, 253, 1655, 4053, 3753, 4159, 23551, 34501, 0 }; + static ulong[] dim3888Kuo2Init = { 1, 3, 7, 7, 27, 35, 91, 241, 377, 299, 1741, 2009, 4051, 3753, 18631, 56383, 0 }; + static ulong[] dim3889Kuo2Init = { 1, 1, 3, 9, 11, 45, 101, 221, 167, 845, 249, 2297, 967, 5203, 29305, 8875, 0 }; + static ulong[] dim3890Kuo2Init = { 1, 3, 5, 9, 31, 41, 21, 251, 421, 47, 421, 3037, 867, 12623, 23289, 39289, 0 }; + static ulong[] dim3891Kuo2Init = { 1, 1, 7, 9, 31, 13, 99, 207, 181, 683, 1881, 2047, 2299, 15795, 24597, 46881, 0 }; + static ulong[] dim3892Kuo2Init = { 1, 1, 1, 15, 1, 45, 57, 171, 149, 909, 1493, 181, 4539, 9625, 20357, 9291, 0 }; + static ulong[] dim3893Kuo2Init = { 1, 3, 5, 15, 5, 19, 101, 167, 245, 213, 1453, 1447, 19, 2091, 27345, 45839, 0 }; + static ulong[] dim3894Kuo2Init = { 1, 1, 5, 5, 5, 61, 59, 159, 343, 51, 2009, 3651, 5263, 1425, 4399, 34357, 0 }; + static ulong[] dim3895Kuo2Init = { 1, 3, 1, 15, 15, 61, 49, 15, 415, 365, 551, 797, 7147, 12771, 17557, 30663, 0 }; + static ulong[] dim3896Kuo2Init = { 1, 3, 1, 7, 17, 15, 125, 195, 455, 553, 1259, 1851, 5149, 6843, 29195, 15015, 0 }; + static ulong[] dim3897Kuo2Init = { 1, 3, 7, 3, 23, 21, 5, 195, 77, 881, 941, 2839, 2837, 10405, 22289, 6211, 0 }; + static ulong[] dim3898Kuo2Init = { 1, 1, 1, 7, 11, 61, 99, 247, 251, 183, 1263, 157, 511, 8627, 19503, 43933, 0 }; + static ulong[] dim3899Kuo2Init = { 1, 3, 1, 9, 15, 15, 113, 255, 225, 173, 1427, 3837, 6607, 3777, 4913, 11173, 0 }; + static ulong[] dim3900Kuo2Init = { 1, 1, 1, 5, 17, 51, 65, 249, 361, 377, 1597, 3065, 5949, 9363, 25597, 40657, 0 }; + static ulong[] dim3901Kuo2Init = { 1, 1, 3, 13, 15, 41, 51, 75, 277, 611, 517, 3751, 721, 6673, 32715, 29053, 0 }; + static ulong[] dim3902Kuo2Init = { 1, 3, 3, 11, 31, 61, 97, 163, 79, 267, 1601, 3155, 1623, 6301, 12897, 1555, 0 }; + static ulong[] dim3903Kuo2Init = { 1, 1, 5, 1, 31, 33, 29, 239, 15, 235, 1675, 1453, 1005, 4811, 21601, 34343, 0 }; + static ulong[] dim3904Kuo2Init = { 1, 3, 7, 9, 13, 23, 43, 119, 313, 249, 643, 3797, 5299, 5127, 5639, 8509, 0 }; + static ulong[] dim3905Kuo2Init = { 1, 1, 7, 5, 11, 51, 85, 181, 231, 641, 1285, 1417, 4535, 10417, 21261, 4965, 0 }; + static ulong[] dim3906Kuo2Init = { 1, 3, 5, 1, 15, 47, 109, 197, 93, 115, 47, 2315, 863, 2787, 25487, 4069, 0 }; + static ulong[] dim3907Kuo2Init = { 1, 1, 7, 11, 13, 43, 117, 203, 189, 151, 549, 1045, 7953, 11003, 17637, 3627, 0 }; + static ulong[] dim3908Kuo2Init = { 1, 3, 5, 7, 7, 29, 5, 55, 281, 767, 1809, 2489, 6417, 10927, 30935, 10769, 0 }; + static ulong[] dim3909Kuo2Init = { 1, 3, 7, 1, 5, 21, 75, 247, 127, 223, 103, 1737, 6577, 389, 26319, 20005, 0 }; + static ulong[] dim3910Kuo2Init = { 1, 1, 1, 5, 15, 55, 33, 171, 115, 535, 1523, 383, 2029, 16339, 12799, 46209, 0 }; + static ulong[] dim3911Kuo2Init = { 1, 1, 5, 5, 21, 39, 9, 239, 221, 497, 913, 2465, 561, 15701, 18851, 11207, 0 }; + static ulong[] dim3912Kuo2Init = { 1, 3, 7, 3, 5, 33, 97, 227, 91, 283, 1971, 3791, 2313, 9519, 11039, 46973, 0 }; + static ulong[] dim3913Kuo2Init = { 1, 1, 7, 7, 1, 35, 1, 23, 391, 365, 1099, 429, 5159, 409, 17641, 55545, 0 }; + static ulong[] dim3914Kuo2Init = { 1, 3, 7, 9, 29, 11, 5, 63, 1, 401, 265, 753, 6933, 899, 10407, 21391, 0 }; + static ulong[] dim3915Kuo2Init = { 1, 1, 3, 5, 25, 7, 95, 251, 241, 625, 661, 829, 1077, 2157, 27767, 32355, 0 }; + static ulong[] dim3916Kuo2Init = { 1, 3, 7, 3, 21, 17, 63, 85, 83, 507, 265, 1183, 6095, 343, 11011, 39071, 0 }; + static ulong[] dim3917Kuo2Init = { 1, 3, 7, 11, 7, 23, 17, 67, 83, 875, 1487, 2565, 6619, 8651, 31249, 28487, 0 }; + static ulong[] dim3918Kuo2Init = { 1, 3, 3, 7, 9, 27, 63, 23, 107, 103, 1059, 2029, 1417, 8883, 7003, 4729, 0 }; + static ulong[] dim3919Kuo2Init = { 1, 1, 1, 11, 5, 53, 67, 41, 227, 643, 1767, 615, 2165, 14475, 21143, 22079, 0 }; + static ulong[] dim3920Kuo2Init = { 1, 1, 7, 7, 1, 19, 77, 211, 379, 173, 1097, 3865, 3735, 10719, 9223, 209, 0 }; + static ulong[] dim3921Kuo2Init = { 1, 1, 5, 7, 31, 53, 77, 73, 329, 587, 1121, 2139, 7433, 9569, 20289, 47867, 0 }; + static ulong[] dim3922Kuo2Init = { 1, 1, 3, 3, 7, 21, 19, 181, 209, 603, 885, 2251, 1563, 6435, 9455, 1753, 0 }; + static ulong[] dim3923Kuo2Init = { 1, 1, 5, 11, 5, 7, 67, 111, 355, 457, 193, 1311, 5987, 5223, 13489, 49679, 0 }; + static ulong[] dim3924Kuo2Init = { 1, 1, 3, 9, 23, 11, 21, 217, 361, 803, 325, 2767, 3363, 9753, 26523, 20517, 0 }; + static ulong[] dim3925Kuo2Init = { 1, 3, 5, 11, 27, 13, 71, 127, 249, 49, 153, 4017, 289, 10705, 19671, 21929, 0 }; + static ulong[] dim3926Kuo2Init = { 1, 1, 5, 5, 13, 51, 113, 109, 135, 507, 719, 2011, 3803, 12049, 13629, 50781, 0 }; + static ulong[] dim3927Kuo2Init = { 1, 3, 1, 9, 5, 33, 125, 223, 309, 909, 1209, 3099, 3431, 853, 2553, 1845, 0 }; + static ulong[] dim3928Kuo2Init = { 1, 3, 1, 5, 21, 61, 63, 21, 485, 101, 1307, 3777, 6331, 3549, 20867, 41487, 0 }; + static ulong[] dim3929Kuo2Init = { 1, 3, 7, 1, 1, 33, 115, 97, 445, 521, 1801, 2869, 7893, 10229, 27265, 7749, 0 }; + static ulong[] dim3930Kuo2Init = { 1, 1, 1, 15, 7, 25, 23, 87, 277, 699, 783, 2891, 5033, 14031, 22947, 15921, 0 }; + static ulong[] dim3931Kuo2Init = { 1, 3, 5, 11, 17, 1, 53, 195, 125, 937, 739, 999, 1729, 14809, 16855, 16407, 0 }; + static ulong[] dim3932Kuo2Init = { 1, 1, 7, 15, 11, 21, 13, 205, 367, 167, 1967, 4003, 1145, 5679, 26437, 27597, 0 }; + static ulong[] dim3933Kuo2Init = { 1, 1, 1, 15, 15, 45, 51, 23, 51, 279, 1463, 1585, 5863, 6625, 32427, 33877, 0 }; + static ulong[] dim3934Kuo2Init = { 1, 1, 1, 9, 9, 47, 83, 61, 493, 399, 1055, 231, 671, 11643, 9151, 48169, 0 }; + static ulong[] dim3935Kuo2Init = { 1, 3, 1, 13, 9, 43, 3, 119, 439, 335, 1167, 249, 193, 4305, 8821, 49611, 0 }; + static ulong[] dim3936Kuo2Init = { 1, 3, 5, 1, 19, 55, 43, 251, 17, 865, 147, 507, 1315, 12029, 5077, 6003, 0 }; + static ulong[] dim3937Kuo2Init = { 1, 3, 7, 7, 3, 23, 83, 7, 241, 197, 139, 1325, 7777, 8425, 27451, 47015, 0 }; + static ulong[] dim3938Kuo2Init = { 1, 1, 3, 3, 27, 29, 37, 31, 325, 937, 59, 2615, 7331, 15635, 29159, 49697, 0 }; + static ulong[] dim3939Kuo2Init = { 1, 3, 3, 5, 27, 47, 125, 165, 363, 573, 189, 3249, 1471, 7869, 6169, 43525, 0 }; + static ulong[] dim3940Kuo2Init = { 1, 1, 3, 13, 19, 33, 15, 123, 245, 939, 209, 853, 6485, 5059, 21891, 7115, 0 }; + static ulong[] dim3941Kuo2Init = { 1, 3, 7, 1, 23, 59, 91, 197, 79, 381, 151, 3533, 7553, 511, 3381, 29339, 0 }; + static ulong[] dim3942Kuo2Init = { 1, 3, 5, 3, 21, 61, 73, 57, 317, 77, 2027, 1055, 3599, 15157, 17017, 23563, 0 }; + static ulong[] dim3943Kuo2Init = { 1, 1, 7, 1, 15, 43, 97, 205, 421, 901, 1589, 2051, 5737, 13231, 15325, 54725, 0 }; + static ulong[] dim3944Kuo2Init = { 1, 1, 5, 5, 31, 33, 93, 129, 385, 961, 733, 277, 3555, 5619, 16499, 57747, 0 }; + static ulong[] dim3945Kuo2Init = { 1, 3, 1, 5, 17, 3, 65, 167, 237, 785, 771, 4033, 6053, 343, 9499, 55861, 0 }; + static ulong[] dim3946Kuo2Init = { 1, 3, 3, 3, 19, 57, 23, 119, 75, 435, 1023, 2357, 4671, 14581, 15343, 2383, 0 }; + + static ulong[][] Kuo2initializers = + { + dim1Kuo2Init, + dim2Kuo2Init, + dim3Kuo2Init, + dim4Kuo2Init, + dim5Kuo2Init, + dim6Kuo2Init, + dim7Kuo2Init, + dim8Kuo2Init, + dim9Kuo2Init, + dim10Kuo2Init, + dim11Kuo2Init, + dim12Kuo2Init, + dim13Kuo2Init, + dim14Kuo2Init, + dim15Kuo2Init, + dim16Kuo2Init, + dim17Kuo2Init, + dim18Kuo2Init, + dim19Kuo2Init, + dim20Kuo2Init, + dim21Kuo2Init, + dim22Kuo2Init, + dim23Kuo2Init, + dim24Kuo2Init, + dim25Kuo2Init, + dim26Kuo2Init, + dim27Kuo2Init, + dim28Kuo2Init, + dim29Kuo2Init, + dim30Kuo2Init, + dim31Kuo2Init, + dim32Kuo2Init, + dim33Kuo2Init, + dim34Kuo2Init, + dim35Kuo2Init, + dim36Kuo2Init, + dim37Kuo2Init, + dim38Kuo2Init, + dim39Kuo2Init, + dim40Kuo2Init, + dim41Kuo2Init, + dim42Kuo2Init, + dim43Kuo2Init, + dim44Kuo2Init, + dim45Kuo2Init, + dim46Kuo2Init, + dim47Kuo2Init, + dim48Kuo2Init, + dim49Kuo2Init, + dim50Kuo2Init, + dim51Kuo2Init, + dim52Kuo2Init, + dim53Kuo2Init, + dim54Kuo2Init, + dim55Kuo2Init, + dim56Kuo2Init, + dim57Kuo2Init, + dim58Kuo2Init, + dim59Kuo2Init, + dim60Kuo2Init, + dim61Kuo2Init, + dim62Kuo2Init, + dim63Kuo2Init, + dim64Kuo2Init, + dim65Kuo2Init, + dim66Kuo2Init, + dim67Kuo2Init, + dim68Kuo2Init, + dim69Kuo2Init, + dim70Kuo2Init, + dim71Kuo2Init, + dim72Kuo2Init, + dim73Kuo2Init, + dim74Kuo2Init, + dim75Kuo2Init, + dim76Kuo2Init, + dim77Kuo2Init, + dim78Kuo2Init, + dim79Kuo2Init, + dim80Kuo2Init, + dim81Kuo2Init, + dim82Kuo2Init, + dim83Kuo2Init, + dim84Kuo2Init, + dim85Kuo2Init, + dim86Kuo2Init, + dim87Kuo2Init, + dim88Kuo2Init, + dim89Kuo2Init, + dim90Kuo2Init, + dim91Kuo2Init, + dim92Kuo2Init, + dim93Kuo2Init, + dim94Kuo2Init, + dim95Kuo2Init, + dim96Kuo2Init, + dim97Kuo2Init, + dim98Kuo2Init, + dim99Kuo2Init, + dim100Kuo2Init, + dim101Kuo2Init, + dim102Kuo2Init, + dim103Kuo2Init, + dim104Kuo2Init, + dim105Kuo2Init, + dim106Kuo2Init, + dim107Kuo2Init, + dim108Kuo2Init, + dim109Kuo2Init, + dim110Kuo2Init, + dim111Kuo2Init, + dim112Kuo2Init, + dim113Kuo2Init, + dim114Kuo2Init, + dim115Kuo2Init, + dim116Kuo2Init, + dim117Kuo2Init, + dim118Kuo2Init, + dim119Kuo2Init, + dim120Kuo2Init, + dim121Kuo2Init, + dim122Kuo2Init, + dim123Kuo2Init, + dim124Kuo2Init, + dim125Kuo2Init, + dim126Kuo2Init, + dim127Kuo2Init, + dim128Kuo2Init, + dim129Kuo2Init, + dim130Kuo2Init, + dim131Kuo2Init, + dim132Kuo2Init, + dim133Kuo2Init, + dim134Kuo2Init, + dim135Kuo2Init, + dim136Kuo2Init, + dim137Kuo2Init, + dim138Kuo2Init, + dim139Kuo2Init, + dim140Kuo2Init, + dim141Kuo2Init, + dim142Kuo2Init, + dim143Kuo2Init, + dim144Kuo2Init, + dim145Kuo2Init, + dim146Kuo2Init, + dim147Kuo2Init, + dim148Kuo2Init, + dim149Kuo2Init, + dim150Kuo2Init, + dim151Kuo2Init, + dim152Kuo2Init, + dim153Kuo2Init, + dim154Kuo2Init, + dim155Kuo2Init, + dim156Kuo2Init, + dim157Kuo2Init, + dim158Kuo2Init, + dim159Kuo2Init, + dim160Kuo2Init, + dim161Kuo2Init, + dim162Kuo2Init, + dim163Kuo2Init, + dim164Kuo2Init, + dim165Kuo2Init, + dim166Kuo2Init, + dim167Kuo2Init, + dim168Kuo2Init, + dim169Kuo2Init, + dim170Kuo2Init, + dim171Kuo2Init, + dim172Kuo2Init, + dim173Kuo2Init, + dim174Kuo2Init, + dim175Kuo2Init, + dim176Kuo2Init, + dim177Kuo2Init, + dim178Kuo2Init, + dim179Kuo2Init, + dim180Kuo2Init, + dim181Kuo2Init, + dim182Kuo2Init, + dim183Kuo2Init, + dim184Kuo2Init, + dim185Kuo2Init, + dim186Kuo2Init, + dim187Kuo2Init, + dim188Kuo2Init, + dim189Kuo2Init, + dim190Kuo2Init, + dim191Kuo2Init, + dim192Kuo2Init, + dim193Kuo2Init, + dim194Kuo2Init, + dim195Kuo2Init, + dim196Kuo2Init, + dim197Kuo2Init, + dim198Kuo2Init, + dim199Kuo2Init, + dim200Kuo2Init, + dim201Kuo2Init, + dim202Kuo2Init, + dim203Kuo2Init, + dim204Kuo2Init, + dim205Kuo2Init, + dim206Kuo2Init, + dim207Kuo2Init, + dim208Kuo2Init, + dim209Kuo2Init, + dim210Kuo2Init, + dim211Kuo2Init, + dim212Kuo2Init, + dim213Kuo2Init, + dim214Kuo2Init, + dim215Kuo2Init, + dim216Kuo2Init, + dim217Kuo2Init, + dim218Kuo2Init, + dim219Kuo2Init, + dim220Kuo2Init, + dim221Kuo2Init, + dim222Kuo2Init, + dim223Kuo2Init, + dim224Kuo2Init, + dim225Kuo2Init, + dim226Kuo2Init, + dim227Kuo2Init, + dim228Kuo2Init, + dim229Kuo2Init, + dim230Kuo2Init, + dim231Kuo2Init, + dim232Kuo2Init, + dim233Kuo2Init, + dim234Kuo2Init, + dim235Kuo2Init, + dim236Kuo2Init, + dim237Kuo2Init, + dim238Kuo2Init, + dim239Kuo2Init, + dim240Kuo2Init, + dim241Kuo2Init, + dim242Kuo2Init, + dim243Kuo2Init, + dim244Kuo2Init, + dim245Kuo2Init, + dim246Kuo2Init, + dim247Kuo2Init, + dim248Kuo2Init, + dim249Kuo2Init, + dim250Kuo2Init, + dim251Kuo2Init, + dim252Kuo2Init, + dim253Kuo2Init, + dim254Kuo2Init, + dim255Kuo2Init, + dim256Kuo2Init, + dim257Kuo2Init, + dim258Kuo2Init, + dim259Kuo2Init, + dim260Kuo2Init, + dim261Kuo2Init, + dim262Kuo2Init, + dim263Kuo2Init, + dim264Kuo2Init, + dim265Kuo2Init, + dim266Kuo2Init, + dim267Kuo2Init, + dim268Kuo2Init, + dim269Kuo2Init, + dim270Kuo2Init, + dim271Kuo2Init, + dim272Kuo2Init, + dim273Kuo2Init, + dim274Kuo2Init, + dim275Kuo2Init, + dim276Kuo2Init, + dim277Kuo2Init, + dim278Kuo2Init, + dim279Kuo2Init, + dim280Kuo2Init, + dim281Kuo2Init, + dim282Kuo2Init, + dim283Kuo2Init, + dim284Kuo2Init, + dim285Kuo2Init, + dim286Kuo2Init, + dim287Kuo2Init, + dim288Kuo2Init, + dim289Kuo2Init, + dim290Kuo2Init, + dim291Kuo2Init, + dim292Kuo2Init, + dim293Kuo2Init, + dim294Kuo2Init, + dim295Kuo2Init, + dim296Kuo2Init, + dim297Kuo2Init, + dim298Kuo2Init, + dim299Kuo2Init, + dim300Kuo2Init, + dim301Kuo2Init, + dim302Kuo2Init, + dim303Kuo2Init, + dim304Kuo2Init, + dim305Kuo2Init, + dim306Kuo2Init, + dim307Kuo2Init, + dim308Kuo2Init, + dim309Kuo2Init, + dim310Kuo2Init, + dim311Kuo2Init, + dim312Kuo2Init, + dim313Kuo2Init, + dim314Kuo2Init, + dim315Kuo2Init, + dim316Kuo2Init, + dim317Kuo2Init, + dim318Kuo2Init, + dim319Kuo2Init, + dim320Kuo2Init, + dim321Kuo2Init, + dim322Kuo2Init, + dim323Kuo2Init, + dim324Kuo2Init, + dim325Kuo2Init, + dim326Kuo2Init, + dim327Kuo2Init, + dim328Kuo2Init, + dim329Kuo2Init, + dim330Kuo2Init, + dim331Kuo2Init, + dim332Kuo2Init, + dim333Kuo2Init, + dim334Kuo2Init, + dim335Kuo2Init, + dim336Kuo2Init, + dim337Kuo2Init, + dim338Kuo2Init, + dim339Kuo2Init, + dim340Kuo2Init, + dim341Kuo2Init, + dim342Kuo2Init, + dim343Kuo2Init, + dim344Kuo2Init, + dim345Kuo2Init, + dim346Kuo2Init, + dim347Kuo2Init, + dim348Kuo2Init, + dim349Kuo2Init, + dim350Kuo2Init, + dim351Kuo2Init, + dim352Kuo2Init, + dim353Kuo2Init, + dim354Kuo2Init, + dim355Kuo2Init, + dim356Kuo2Init, + dim357Kuo2Init, + dim358Kuo2Init, + dim359Kuo2Init, + dim360Kuo2Init, + dim361Kuo2Init, + dim362Kuo2Init, + dim363Kuo2Init, + dim364Kuo2Init, + dim365Kuo2Init, + dim366Kuo2Init, + dim367Kuo2Init, + dim368Kuo2Init, + dim369Kuo2Init, + dim370Kuo2Init, + dim371Kuo2Init, + dim372Kuo2Init, + dim373Kuo2Init, + dim374Kuo2Init, + dim375Kuo2Init, + dim376Kuo2Init, + dim377Kuo2Init, + dim378Kuo2Init, + dim379Kuo2Init, + dim380Kuo2Init, + dim381Kuo2Init, + dim382Kuo2Init, + dim383Kuo2Init, + dim384Kuo2Init, + dim385Kuo2Init, + dim386Kuo2Init, + dim387Kuo2Init, + dim388Kuo2Init, + dim389Kuo2Init, + dim390Kuo2Init, + dim391Kuo2Init, + dim392Kuo2Init, + dim393Kuo2Init, + dim394Kuo2Init, + dim395Kuo2Init, + dim396Kuo2Init, + dim397Kuo2Init, + dim398Kuo2Init, + dim399Kuo2Init, + dim400Kuo2Init, + dim401Kuo2Init, + dim402Kuo2Init, + dim403Kuo2Init, + dim404Kuo2Init, + dim405Kuo2Init, + dim406Kuo2Init, + dim407Kuo2Init, + dim408Kuo2Init, + dim409Kuo2Init, + dim410Kuo2Init, + dim411Kuo2Init, + dim412Kuo2Init, + dim413Kuo2Init, + dim414Kuo2Init, + dim415Kuo2Init, + dim416Kuo2Init, + dim417Kuo2Init, + dim418Kuo2Init, + dim419Kuo2Init, + dim420Kuo2Init, + dim421Kuo2Init, + dim422Kuo2Init, + dim423Kuo2Init, + dim424Kuo2Init, + dim425Kuo2Init, + dim426Kuo2Init, + dim427Kuo2Init, + dim428Kuo2Init, + dim429Kuo2Init, + dim430Kuo2Init, + dim431Kuo2Init, + dim432Kuo2Init, + dim433Kuo2Init, + dim434Kuo2Init, + dim435Kuo2Init, + dim436Kuo2Init, + dim437Kuo2Init, + dim438Kuo2Init, + dim439Kuo2Init, + dim440Kuo2Init, + dim441Kuo2Init, + dim442Kuo2Init, + dim443Kuo2Init, + dim444Kuo2Init, + dim445Kuo2Init, + dim446Kuo2Init, + dim447Kuo2Init, + dim448Kuo2Init, + dim449Kuo2Init, + dim450Kuo2Init, + dim451Kuo2Init, + dim452Kuo2Init, + dim453Kuo2Init, + dim454Kuo2Init, + dim455Kuo2Init, + dim456Kuo2Init, + dim457Kuo2Init, + dim458Kuo2Init, + dim459Kuo2Init, + dim460Kuo2Init, + dim461Kuo2Init, + dim462Kuo2Init, + dim463Kuo2Init, + dim464Kuo2Init, + dim465Kuo2Init, + dim466Kuo2Init, + dim467Kuo2Init, + dim468Kuo2Init, + dim469Kuo2Init, + dim470Kuo2Init, + dim471Kuo2Init, + dim472Kuo2Init, + dim473Kuo2Init, + dim474Kuo2Init, + dim475Kuo2Init, + dim476Kuo2Init, + dim477Kuo2Init, + dim478Kuo2Init, + dim479Kuo2Init, + dim480Kuo2Init, + dim481Kuo2Init, + dim482Kuo2Init, + dim483Kuo2Init, + dim484Kuo2Init, + dim485Kuo2Init, + dim486Kuo2Init, + dim487Kuo2Init, + dim488Kuo2Init, + dim489Kuo2Init, + dim490Kuo2Init, + dim491Kuo2Init, + dim492Kuo2Init, + dim493Kuo2Init, + dim494Kuo2Init, + dim495Kuo2Init, + dim496Kuo2Init, + dim497Kuo2Init, + dim498Kuo2Init, + dim499Kuo2Init, + dim500Kuo2Init, + dim501Kuo2Init, + dim502Kuo2Init, + dim503Kuo2Init, + dim504Kuo2Init, + dim505Kuo2Init, + dim506Kuo2Init, + dim507Kuo2Init, + dim508Kuo2Init, + dim509Kuo2Init, + dim510Kuo2Init, + dim511Kuo2Init, + dim512Kuo2Init, + dim513Kuo2Init, + dim514Kuo2Init, + dim515Kuo2Init, + dim516Kuo2Init, + dim517Kuo2Init, + dim518Kuo2Init, + dim519Kuo2Init, + dim520Kuo2Init, + dim521Kuo2Init, + dim522Kuo2Init, + dim523Kuo2Init, + dim524Kuo2Init, + dim525Kuo2Init, + dim526Kuo2Init, + dim527Kuo2Init, + dim528Kuo2Init, + dim529Kuo2Init, + dim530Kuo2Init, + dim531Kuo2Init, + dim532Kuo2Init, + dim533Kuo2Init, + dim534Kuo2Init, + dim535Kuo2Init, + dim536Kuo2Init, + dim537Kuo2Init, + dim538Kuo2Init, + dim539Kuo2Init, + dim540Kuo2Init, + dim541Kuo2Init, + dim542Kuo2Init, + dim543Kuo2Init, + dim544Kuo2Init, + dim545Kuo2Init, + dim546Kuo2Init, + dim547Kuo2Init, + dim548Kuo2Init, + dim549Kuo2Init, + dim550Kuo2Init, + dim551Kuo2Init, + dim552Kuo2Init, + dim553Kuo2Init, + dim554Kuo2Init, + dim555Kuo2Init, + dim556Kuo2Init, + dim557Kuo2Init, + dim558Kuo2Init, + dim559Kuo2Init, + dim560Kuo2Init, + dim561Kuo2Init, + dim562Kuo2Init, + dim563Kuo2Init, + dim564Kuo2Init, + dim565Kuo2Init, + dim566Kuo2Init, + dim567Kuo2Init, + dim568Kuo2Init, + dim569Kuo2Init, + dim570Kuo2Init, + dim571Kuo2Init, + dim572Kuo2Init, + dim573Kuo2Init, + dim574Kuo2Init, + dim575Kuo2Init, + dim576Kuo2Init, + dim577Kuo2Init, + dim578Kuo2Init, + dim579Kuo2Init, + dim580Kuo2Init, + dim581Kuo2Init, + dim582Kuo2Init, + dim583Kuo2Init, + dim584Kuo2Init, + dim585Kuo2Init, + dim586Kuo2Init, + dim587Kuo2Init, + dim588Kuo2Init, + dim589Kuo2Init, + dim590Kuo2Init, + dim591Kuo2Init, + dim592Kuo2Init, + dim593Kuo2Init, + dim594Kuo2Init, + dim595Kuo2Init, + dim596Kuo2Init, + dim597Kuo2Init, + dim598Kuo2Init, + dim599Kuo2Init, + dim600Kuo2Init, + dim601Kuo2Init, + dim602Kuo2Init, + dim603Kuo2Init, + dim604Kuo2Init, + dim605Kuo2Init, + dim606Kuo2Init, + dim607Kuo2Init, + dim608Kuo2Init, + dim609Kuo2Init, + dim610Kuo2Init, + dim611Kuo2Init, + dim612Kuo2Init, + dim613Kuo2Init, + dim614Kuo2Init, + dim615Kuo2Init, + dim616Kuo2Init, + dim617Kuo2Init, + dim618Kuo2Init, + dim619Kuo2Init, + dim620Kuo2Init, + dim621Kuo2Init, + dim622Kuo2Init, + dim623Kuo2Init, + dim624Kuo2Init, + dim625Kuo2Init, + dim626Kuo2Init, + dim627Kuo2Init, + dim628Kuo2Init, + dim629Kuo2Init, + dim630Kuo2Init, + dim631Kuo2Init, + dim632Kuo2Init, + dim633Kuo2Init, + dim634Kuo2Init, + dim635Kuo2Init, + dim636Kuo2Init, + dim637Kuo2Init, + dim638Kuo2Init, + dim639Kuo2Init, + dim640Kuo2Init, + dim641Kuo2Init, + dim642Kuo2Init, + dim643Kuo2Init, + dim644Kuo2Init, + dim645Kuo2Init, + dim646Kuo2Init, + dim647Kuo2Init, + dim648Kuo2Init, + dim649Kuo2Init, + dim650Kuo2Init, + dim651Kuo2Init, + dim652Kuo2Init, + dim653Kuo2Init, + dim654Kuo2Init, + dim655Kuo2Init, + dim656Kuo2Init, + dim657Kuo2Init, + dim658Kuo2Init, + dim659Kuo2Init, + dim660Kuo2Init, + dim661Kuo2Init, + dim662Kuo2Init, + dim663Kuo2Init, + dim664Kuo2Init, + dim665Kuo2Init, + dim666Kuo2Init, + dim667Kuo2Init, + dim668Kuo2Init, + dim669Kuo2Init, + dim670Kuo2Init, + dim671Kuo2Init, + dim672Kuo2Init, + dim673Kuo2Init, + dim674Kuo2Init, + dim675Kuo2Init, + dim676Kuo2Init, + dim677Kuo2Init, + dim678Kuo2Init, + dim679Kuo2Init, + dim680Kuo2Init, + dim681Kuo2Init, + dim682Kuo2Init, + dim683Kuo2Init, + dim684Kuo2Init, + dim685Kuo2Init, + dim686Kuo2Init, + dim687Kuo2Init, + dim688Kuo2Init, + dim689Kuo2Init, + dim690Kuo2Init, + dim691Kuo2Init, + dim692Kuo2Init, + dim693Kuo2Init, + dim694Kuo2Init, + dim695Kuo2Init, + dim696Kuo2Init, + dim697Kuo2Init, + dim698Kuo2Init, + dim699Kuo2Init, + dim700Kuo2Init, + dim701Kuo2Init, + dim702Kuo2Init, + dim703Kuo2Init, + dim704Kuo2Init, + dim705Kuo2Init, + dim706Kuo2Init, + dim707Kuo2Init, + dim708Kuo2Init, + dim709Kuo2Init, + dim710Kuo2Init, + dim711Kuo2Init, + dim712Kuo2Init, + dim713Kuo2Init, + dim714Kuo2Init, + dim715Kuo2Init, + dim716Kuo2Init, + dim717Kuo2Init, + dim718Kuo2Init, + dim719Kuo2Init, + dim720Kuo2Init, + dim721Kuo2Init, + dim722Kuo2Init, + dim723Kuo2Init, + dim724Kuo2Init, + dim725Kuo2Init, + dim726Kuo2Init, + dim727Kuo2Init, + dim728Kuo2Init, + dim729Kuo2Init, + dim730Kuo2Init, + dim731Kuo2Init, + dim732Kuo2Init, + dim733Kuo2Init, + dim734Kuo2Init, + dim735Kuo2Init, + dim736Kuo2Init, + dim737Kuo2Init, + dim738Kuo2Init, + dim739Kuo2Init, + dim740Kuo2Init, + dim741Kuo2Init, + dim742Kuo2Init, + dim743Kuo2Init, + dim744Kuo2Init, + dim745Kuo2Init, + dim746Kuo2Init, + dim747Kuo2Init, + dim748Kuo2Init, + dim749Kuo2Init, + dim750Kuo2Init, + dim751Kuo2Init, + dim752Kuo2Init, + dim753Kuo2Init, + dim754Kuo2Init, + dim755Kuo2Init, + dim756Kuo2Init, + dim757Kuo2Init, + dim758Kuo2Init, + dim759Kuo2Init, + dim760Kuo2Init, + dim761Kuo2Init, + dim762Kuo2Init, + dim763Kuo2Init, + dim764Kuo2Init, + dim765Kuo2Init, + dim766Kuo2Init, + dim767Kuo2Init, + dim768Kuo2Init, + dim769Kuo2Init, + dim770Kuo2Init, + dim771Kuo2Init, + dim772Kuo2Init, + dim773Kuo2Init, + dim774Kuo2Init, + dim775Kuo2Init, + dim776Kuo2Init, + dim777Kuo2Init, + dim778Kuo2Init, + dim779Kuo2Init, + dim780Kuo2Init, + dim781Kuo2Init, + dim782Kuo2Init, + dim783Kuo2Init, + dim784Kuo2Init, + dim785Kuo2Init, + dim786Kuo2Init, + dim787Kuo2Init, + dim788Kuo2Init, + dim789Kuo2Init, + dim790Kuo2Init, + dim791Kuo2Init, + dim792Kuo2Init, + dim793Kuo2Init, + dim794Kuo2Init, + dim795Kuo2Init, + dim796Kuo2Init, + dim797Kuo2Init, + dim798Kuo2Init, + dim799Kuo2Init, + dim800Kuo2Init, + dim801Kuo2Init, + dim802Kuo2Init, + dim803Kuo2Init, + dim804Kuo2Init, + dim805Kuo2Init, + dim806Kuo2Init, + dim807Kuo2Init, + dim808Kuo2Init, + dim809Kuo2Init, + dim810Kuo2Init, + dim811Kuo2Init, + dim812Kuo2Init, + dim813Kuo2Init, + dim814Kuo2Init, + dim815Kuo2Init, + dim816Kuo2Init, + dim817Kuo2Init, + dim818Kuo2Init, + dim819Kuo2Init, + dim820Kuo2Init, + dim821Kuo2Init, + dim822Kuo2Init, + dim823Kuo2Init, + dim824Kuo2Init, + dim825Kuo2Init, + dim826Kuo2Init, + dim827Kuo2Init, + dim828Kuo2Init, + dim829Kuo2Init, + dim830Kuo2Init, + dim831Kuo2Init, + dim832Kuo2Init, + dim833Kuo2Init, + dim834Kuo2Init, + dim835Kuo2Init, + dim836Kuo2Init, + dim837Kuo2Init, + dim838Kuo2Init, + dim839Kuo2Init, + dim840Kuo2Init, + dim841Kuo2Init, + dim842Kuo2Init, + dim843Kuo2Init, + dim844Kuo2Init, + dim845Kuo2Init, + dim846Kuo2Init, + dim847Kuo2Init, + dim848Kuo2Init, + dim849Kuo2Init, + dim850Kuo2Init, + dim851Kuo2Init, + dim852Kuo2Init, + dim853Kuo2Init, + dim854Kuo2Init, + dim855Kuo2Init, + dim856Kuo2Init, + dim857Kuo2Init, + dim858Kuo2Init, + dim859Kuo2Init, + dim860Kuo2Init, + dim861Kuo2Init, + dim862Kuo2Init, + dim863Kuo2Init, + dim864Kuo2Init, + dim865Kuo2Init, + dim866Kuo2Init, + dim867Kuo2Init, + dim868Kuo2Init, + dim869Kuo2Init, + dim870Kuo2Init, + dim871Kuo2Init, + dim872Kuo2Init, + dim873Kuo2Init, + dim874Kuo2Init, + dim875Kuo2Init, + dim876Kuo2Init, + dim877Kuo2Init, + dim878Kuo2Init, + dim879Kuo2Init, + dim880Kuo2Init, + dim881Kuo2Init, + dim882Kuo2Init, + dim883Kuo2Init, + dim884Kuo2Init, + dim885Kuo2Init, + dim886Kuo2Init, + dim887Kuo2Init, + dim888Kuo2Init, + dim889Kuo2Init, + dim890Kuo2Init, + dim891Kuo2Init, + dim892Kuo2Init, + dim893Kuo2Init, + dim894Kuo2Init, + dim895Kuo2Init, + dim896Kuo2Init, + dim897Kuo2Init, + dim898Kuo2Init, + dim899Kuo2Init, + dim900Kuo2Init, + dim901Kuo2Init, + dim902Kuo2Init, + dim903Kuo2Init, + dim904Kuo2Init, + dim905Kuo2Init, + dim906Kuo2Init, + dim907Kuo2Init, + dim908Kuo2Init, + dim909Kuo2Init, + dim910Kuo2Init, + dim911Kuo2Init, + dim912Kuo2Init, + dim913Kuo2Init, + dim914Kuo2Init, + dim915Kuo2Init, + dim916Kuo2Init, + dim917Kuo2Init, + dim918Kuo2Init, + dim919Kuo2Init, + dim920Kuo2Init, + dim921Kuo2Init, + dim922Kuo2Init, + dim923Kuo2Init, + dim924Kuo2Init, + dim925Kuo2Init, + dim926Kuo2Init, + dim927Kuo2Init, + dim928Kuo2Init, + dim929Kuo2Init, + dim930Kuo2Init, + dim931Kuo2Init, + dim932Kuo2Init, + dim933Kuo2Init, + dim934Kuo2Init, + dim935Kuo2Init, + dim936Kuo2Init, + dim937Kuo2Init, + dim938Kuo2Init, + dim939Kuo2Init, + dim940Kuo2Init, + dim941Kuo2Init, + dim942Kuo2Init, + dim943Kuo2Init, + dim944Kuo2Init, + dim945Kuo2Init, + dim946Kuo2Init, + dim947Kuo2Init, + dim948Kuo2Init, + dim949Kuo2Init, + dim950Kuo2Init, + dim951Kuo2Init, + dim952Kuo2Init, + dim953Kuo2Init, + dim954Kuo2Init, + dim955Kuo2Init, + dim956Kuo2Init, + dim957Kuo2Init, + dim958Kuo2Init, + dim959Kuo2Init, + dim960Kuo2Init, + dim961Kuo2Init, + dim962Kuo2Init, + dim963Kuo2Init, + dim964Kuo2Init, + dim965Kuo2Init, + dim966Kuo2Init, + dim967Kuo2Init, + dim968Kuo2Init, + dim969Kuo2Init, + dim970Kuo2Init, + dim971Kuo2Init, + dim972Kuo2Init, + dim973Kuo2Init, + dim974Kuo2Init, + dim975Kuo2Init, + dim976Kuo2Init, + dim977Kuo2Init, + dim978Kuo2Init, + dim979Kuo2Init, + dim980Kuo2Init, + dim981Kuo2Init, + dim982Kuo2Init, + dim983Kuo2Init, + dim984Kuo2Init, + dim985Kuo2Init, + dim986Kuo2Init, + dim987Kuo2Init, + dim988Kuo2Init, + dim989Kuo2Init, + dim990Kuo2Init, + dim991Kuo2Init, + dim992Kuo2Init, + dim993Kuo2Init, + dim994Kuo2Init, + dim995Kuo2Init, + dim996Kuo2Init, + dim997Kuo2Init, + dim998Kuo2Init, + dim999Kuo2Init, + dim1000Kuo2Init, + dim1001Kuo2Init, + dim1002Kuo2Init, + dim1003Kuo2Init, + dim1004Kuo2Init, + dim1005Kuo2Init, + dim1006Kuo2Init, + dim1007Kuo2Init, + dim1008Kuo2Init, + dim1009Kuo2Init, + dim1010Kuo2Init, + dim1011Kuo2Init, + dim1012Kuo2Init, + dim1013Kuo2Init, + dim1014Kuo2Init, + dim1015Kuo2Init, + dim1016Kuo2Init, + dim1017Kuo2Init, + dim1018Kuo2Init, + dim1019Kuo2Init, + dim1020Kuo2Init, + dim1021Kuo2Init, + dim1022Kuo2Init, + dim1023Kuo2Init, + dim1024Kuo2Init, + dim1025Kuo2Init, + dim1026Kuo2Init, + dim1027Kuo2Init, + dim1028Kuo2Init, + dim1029Kuo2Init, + dim1030Kuo2Init, + dim1031Kuo2Init, + dim1032Kuo2Init, + dim1033Kuo2Init, + dim1034Kuo2Init, + dim1035Kuo2Init, + dim1036Kuo2Init, + dim1037Kuo2Init, + dim1038Kuo2Init, + dim1039Kuo2Init, + dim1040Kuo2Init, + dim1041Kuo2Init, + dim1042Kuo2Init, + dim1043Kuo2Init, + dim1044Kuo2Init, + dim1045Kuo2Init, + dim1046Kuo2Init, + dim1047Kuo2Init, + dim1048Kuo2Init, + dim1049Kuo2Init, + dim1050Kuo2Init, + dim1051Kuo2Init, + dim1052Kuo2Init, + dim1053Kuo2Init, + dim1054Kuo2Init, + dim1055Kuo2Init, + dim1056Kuo2Init, + dim1057Kuo2Init, + dim1058Kuo2Init, + dim1059Kuo2Init, + dim1060Kuo2Init, + dim1061Kuo2Init, + dim1062Kuo2Init, + dim1063Kuo2Init, + dim1064Kuo2Init, + dim1065Kuo2Init, + dim1066Kuo2Init, + dim1067Kuo2Init, + dim1068Kuo2Init, + dim1069Kuo2Init, + dim1070Kuo2Init, + dim1071Kuo2Init, + dim1072Kuo2Init, + dim1073Kuo2Init, + dim1074Kuo2Init, + dim1075Kuo2Init, + dim1076Kuo2Init, + dim1077Kuo2Init, + dim1078Kuo2Init, + dim1079Kuo2Init, + dim1080Kuo2Init, + dim1081Kuo2Init, + dim1082Kuo2Init, + dim1083Kuo2Init, + dim1084Kuo2Init, + dim1085Kuo2Init, + dim1086Kuo2Init, + dim1087Kuo2Init, + dim1088Kuo2Init, + dim1089Kuo2Init, + dim1090Kuo2Init, + dim1091Kuo2Init, + dim1092Kuo2Init, + dim1093Kuo2Init, + dim1094Kuo2Init, + dim1095Kuo2Init, + dim1096Kuo2Init, + dim1097Kuo2Init, + dim1098Kuo2Init, + dim1099Kuo2Init, + dim1100Kuo2Init, + dim1101Kuo2Init, + dim1102Kuo2Init, + dim1103Kuo2Init, + dim1104Kuo2Init, + dim1105Kuo2Init, + dim1106Kuo2Init, + dim1107Kuo2Init, + dim1108Kuo2Init, + dim1109Kuo2Init, + dim1110Kuo2Init, + dim1111Kuo2Init, + dim1112Kuo2Init, + dim1113Kuo2Init, + dim1114Kuo2Init, + dim1115Kuo2Init, + dim1116Kuo2Init, + dim1117Kuo2Init, + dim1118Kuo2Init, + dim1119Kuo2Init, + dim1120Kuo2Init, + dim1121Kuo2Init, + dim1122Kuo2Init, + dim1123Kuo2Init, + dim1124Kuo2Init, + dim1125Kuo2Init, + dim1126Kuo2Init, + dim1127Kuo2Init, + dim1128Kuo2Init, + dim1129Kuo2Init, + dim1130Kuo2Init, + dim1131Kuo2Init, + dim1132Kuo2Init, + dim1133Kuo2Init, + dim1134Kuo2Init, + dim1135Kuo2Init, + dim1136Kuo2Init, + dim1137Kuo2Init, + dim1138Kuo2Init, + dim1139Kuo2Init, + dim1140Kuo2Init, + dim1141Kuo2Init, + dim1142Kuo2Init, + dim1143Kuo2Init, + dim1144Kuo2Init, + dim1145Kuo2Init, + dim1146Kuo2Init, + dim1147Kuo2Init, + dim1148Kuo2Init, + dim1149Kuo2Init, + dim1150Kuo2Init, + dim1151Kuo2Init, + dim1152Kuo2Init, + dim1153Kuo2Init, + dim1154Kuo2Init, + dim1155Kuo2Init, + dim1156Kuo2Init, + dim1157Kuo2Init, + dim1158Kuo2Init, + dim1159Kuo2Init, + dim1160Kuo2Init, + dim1161Kuo2Init, + dim1162Kuo2Init, + dim1163Kuo2Init, + dim1164Kuo2Init, + dim1165Kuo2Init, + dim1166Kuo2Init, + dim1167Kuo2Init, + dim1168Kuo2Init, + dim1169Kuo2Init, + dim1170Kuo2Init, + dim1171Kuo2Init, + dim1172Kuo2Init, + dim1173Kuo2Init, + dim1174Kuo2Init, + dim1175Kuo2Init, + dim1176Kuo2Init, + dim1177Kuo2Init, + dim1178Kuo2Init, + dim1179Kuo2Init, + dim1180Kuo2Init, + dim1181Kuo2Init, + dim1182Kuo2Init, + dim1183Kuo2Init, + dim1184Kuo2Init, + dim1185Kuo2Init, + dim1186Kuo2Init, + dim1187Kuo2Init, + dim1188Kuo2Init, + dim1189Kuo2Init, + dim1190Kuo2Init, + dim1191Kuo2Init, + dim1192Kuo2Init, + dim1193Kuo2Init, + dim1194Kuo2Init, + dim1195Kuo2Init, + dim1196Kuo2Init, + dim1197Kuo2Init, + dim1198Kuo2Init, + dim1199Kuo2Init, + dim1200Kuo2Init, + dim1201Kuo2Init, + dim1202Kuo2Init, + dim1203Kuo2Init, + dim1204Kuo2Init, + dim1205Kuo2Init, + dim1206Kuo2Init, + dim1207Kuo2Init, + dim1208Kuo2Init, + dim1209Kuo2Init, + dim1210Kuo2Init, + dim1211Kuo2Init, + dim1212Kuo2Init, + dim1213Kuo2Init, + dim1214Kuo2Init, + dim1215Kuo2Init, + dim1216Kuo2Init, + dim1217Kuo2Init, + dim1218Kuo2Init, + dim1219Kuo2Init, + dim1220Kuo2Init, + dim1221Kuo2Init, + dim1222Kuo2Init, + dim1223Kuo2Init, + dim1224Kuo2Init, + dim1225Kuo2Init, + dim1226Kuo2Init, + dim1227Kuo2Init, + dim1228Kuo2Init, + dim1229Kuo2Init, + dim1230Kuo2Init, + dim1231Kuo2Init, + dim1232Kuo2Init, + dim1233Kuo2Init, + dim1234Kuo2Init, + dim1235Kuo2Init, + dim1236Kuo2Init, + dim1237Kuo2Init, + dim1238Kuo2Init, + dim1239Kuo2Init, + dim1240Kuo2Init, + dim1241Kuo2Init, + dim1242Kuo2Init, + dim1243Kuo2Init, + dim1244Kuo2Init, + dim1245Kuo2Init, + dim1246Kuo2Init, + dim1247Kuo2Init, + dim1248Kuo2Init, + dim1249Kuo2Init, + dim1250Kuo2Init, + dim1251Kuo2Init, + dim1252Kuo2Init, + dim1253Kuo2Init, + dim1254Kuo2Init, + dim1255Kuo2Init, + dim1256Kuo2Init, + dim1257Kuo2Init, + dim1258Kuo2Init, + dim1259Kuo2Init, + dim1260Kuo2Init, + dim1261Kuo2Init, + dim1262Kuo2Init, + dim1263Kuo2Init, + dim1264Kuo2Init, + dim1265Kuo2Init, + dim1266Kuo2Init, + dim1267Kuo2Init, + dim1268Kuo2Init, + dim1269Kuo2Init, + dim1270Kuo2Init, + dim1271Kuo2Init, + dim1272Kuo2Init, + dim1273Kuo2Init, + dim1274Kuo2Init, + dim1275Kuo2Init, + dim1276Kuo2Init, + dim1277Kuo2Init, + dim1278Kuo2Init, + dim1279Kuo2Init, + dim1280Kuo2Init, + dim1281Kuo2Init, + dim1282Kuo2Init, + dim1283Kuo2Init, + dim1284Kuo2Init, + dim1285Kuo2Init, + dim1286Kuo2Init, + dim1287Kuo2Init, + dim1288Kuo2Init, + dim1289Kuo2Init, + dim1290Kuo2Init, + dim1291Kuo2Init, + dim1292Kuo2Init, + dim1293Kuo2Init, + dim1294Kuo2Init, + dim1295Kuo2Init, + dim1296Kuo2Init, + dim1297Kuo2Init, + dim1298Kuo2Init, + dim1299Kuo2Init, + dim1300Kuo2Init, + dim1301Kuo2Init, + dim1302Kuo2Init, + dim1303Kuo2Init, + dim1304Kuo2Init, + dim1305Kuo2Init, + dim1306Kuo2Init, + dim1307Kuo2Init, + dim1308Kuo2Init, + dim1309Kuo2Init, + dim1310Kuo2Init, + dim1311Kuo2Init, + dim1312Kuo2Init, + dim1313Kuo2Init, + dim1314Kuo2Init, + dim1315Kuo2Init, + dim1316Kuo2Init, + dim1317Kuo2Init, + dim1318Kuo2Init, + dim1319Kuo2Init, + dim1320Kuo2Init, + dim1321Kuo2Init, + dim1322Kuo2Init, + dim1323Kuo2Init, + dim1324Kuo2Init, + dim1325Kuo2Init, + dim1326Kuo2Init, + dim1327Kuo2Init, + dim1328Kuo2Init, + dim1329Kuo2Init, + dim1330Kuo2Init, + dim1331Kuo2Init, + dim1332Kuo2Init, + dim1333Kuo2Init, + dim1334Kuo2Init, + dim1335Kuo2Init, + dim1336Kuo2Init, + dim1337Kuo2Init, + dim1338Kuo2Init, + dim1339Kuo2Init, + dim1340Kuo2Init, + dim1341Kuo2Init, + dim1342Kuo2Init, + dim1343Kuo2Init, + dim1344Kuo2Init, + dim1345Kuo2Init, + dim1346Kuo2Init, + dim1347Kuo2Init, + dim1348Kuo2Init, + dim1349Kuo2Init, + dim1350Kuo2Init, + dim1351Kuo2Init, + dim1352Kuo2Init, + dim1353Kuo2Init, + dim1354Kuo2Init, + dim1355Kuo2Init, + dim1356Kuo2Init, + dim1357Kuo2Init, + dim1358Kuo2Init, + dim1359Kuo2Init, + dim1360Kuo2Init, + dim1361Kuo2Init, + dim1362Kuo2Init, + dim1363Kuo2Init, + dim1364Kuo2Init, + dim1365Kuo2Init, + dim1366Kuo2Init, + dim1367Kuo2Init, + dim1368Kuo2Init, + dim1369Kuo2Init, + dim1370Kuo2Init, + dim1371Kuo2Init, + dim1372Kuo2Init, + dim1373Kuo2Init, + dim1374Kuo2Init, + dim1375Kuo2Init, + dim1376Kuo2Init, + dim1377Kuo2Init, + dim1378Kuo2Init, + dim1379Kuo2Init, + dim1380Kuo2Init, + dim1381Kuo2Init, + dim1382Kuo2Init, + dim1383Kuo2Init, + dim1384Kuo2Init, + dim1385Kuo2Init, + dim1386Kuo2Init, + dim1387Kuo2Init, + dim1388Kuo2Init, + dim1389Kuo2Init, + dim1390Kuo2Init, + dim1391Kuo2Init, + dim1392Kuo2Init, + dim1393Kuo2Init, + dim1394Kuo2Init, + dim1395Kuo2Init, + dim1396Kuo2Init, + dim1397Kuo2Init, + dim1398Kuo2Init, + dim1399Kuo2Init, + dim1400Kuo2Init, + dim1401Kuo2Init, + dim1402Kuo2Init, + dim1403Kuo2Init, + dim1404Kuo2Init, + dim1405Kuo2Init, + dim1406Kuo2Init, + dim1407Kuo2Init, + dim1408Kuo2Init, + dim1409Kuo2Init, + dim1410Kuo2Init, + dim1411Kuo2Init, + dim1412Kuo2Init, + dim1413Kuo2Init, + dim1414Kuo2Init, + dim1415Kuo2Init, + dim1416Kuo2Init, + dim1417Kuo2Init, + dim1418Kuo2Init, + dim1419Kuo2Init, + dim1420Kuo2Init, + dim1421Kuo2Init, + dim1422Kuo2Init, + dim1423Kuo2Init, + dim1424Kuo2Init, + dim1425Kuo2Init, + dim1426Kuo2Init, + dim1427Kuo2Init, + dim1428Kuo2Init, + dim1429Kuo2Init, + dim1430Kuo2Init, + dim1431Kuo2Init, + dim1432Kuo2Init, + dim1433Kuo2Init, + dim1434Kuo2Init, + dim1435Kuo2Init, + dim1436Kuo2Init, + dim1437Kuo2Init, + dim1438Kuo2Init, + dim1439Kuo2Init, + dim1440Kuo2Init, + dim1441Kuo2Init, + dim1442Kuo2Init, + dim1443Kuo2Init, + dim1444Kuo2Init, + dim1445Kuo2Init, + dim1446Kuo2Init, + dim1447Kuo2Init, + dim1448Kuo2Init, + dim1449Kuo2Init, + dim1450Kuo2Init, + dim1451Kuo2Init, + dim1452Kuo2Init, + dim1453Kuo2Init, + dim1454Kuo2Init, + dim1455Kuo2Init, + dim1456Kuo2Init, + dim1457Kuo2Init, + dim1458Kuo2Init, + dim1459Kuo2Init, + dim1460Kuo2Init, + dim1461Kuo2Init, + dim1462Kuo2Init, + dim1463Kuo2Init, + dim1464Kuo2Init, + dim1465Kuo2Init, + dim1466Kuo2Init, + dim1467Kuo2Init, + dim1468Kuo2Init, + dim1469Kuo2Init, + dim1470Kuo2Init, + dim1471Kuo2Init, + dim1472Kuo2Init, + dim1473Kuo2Init, + dim1474Kuo2Init, + dim1475Kuo2Init, + dim1476Kuo2Init, + dim1477Kuo2Init, + dim1478Kuo2Init, + dim1479Kuo2Init, + dim1480Kuo2Init, + dim1481Kuo2Init, + dim1482Kuo2Init, + dim1483Kuo2Init, + dim1484Kuo2Init, + dim1485Kuo2Init, + dim1486Kuo2Init, + dim1487Kuo2Init, + dim1488Kuo2Init, + dim1489Kuo2Init, + dim1490Kuo2Init, + dim1491Kuo2Init, + dim1492Kuo2Init, + dim1493Kuo2Init, + dim1494Kuo2Init, + dim1495Kuo2Init, + dim1496Kuo2Init, + dim1497Kuo2Init, + dim1498Kuo2Init, + dim1499Kuo2Init, + dim1500Kuo2Init, + dim1501Kuo2Init, + dim1502Kuo2Init, + dim1503Kuo2Init, + dim1504Kuo2Init, + dim1505Kuo2Init, + dim1506Kuo2Init, + dim1507Kuo2Init, + dim1508Kuo2Init, + dim1509Kuo2Init, + dim1510Kuo2Init, + dim1511Kuo2Init, + dim1512Kuo2Init, + dim1513Kuo2Init, + dim1514Kuo2Init, + dim1515Kuo2Init, + dim1516Kuo2Init, + dim1517Kuo2Init, + dim1518Kuo2Init, + dim1519Kuo2Init, + dim1520Kuo2Init, + dim1521Kuo2Init, + dim1522Kuo2Init, + dim1523Kuo2Init, + dim1524Kuo2Init, + dim1525Kuo2Init, + dim1526Kuo2Init, + dim1527Kuo2Init, + dim1528Kuo2Init, + dim1529Kuo2Init, + dim1530Kuo2Init, + dim1531Kuo2Init, + dim1532Kuo2Init, + dim1533Kuo2Init, + dim1534Kuo2Init, + dim1535Kuo2Init, + dim1536Kuo2Init, + dim1537Kuo2Init, + dim1538Kuo2Init, + dim1539Kuo2Init, + dim1540Kuo2Init, + dim1541Kuo2Init, + dim1542Kuo2Init, + dim1543Kuo2Init, + dim1544Kuo2Init, + dim1545Kuo2Init, + dim1546Kuo2Init, + dim1547Kuo2Init, + dim1548Kuo2Init, + dim1549Kuo2Init, + dim1550Kuo2Init, + dim1551Kuo2Init, + dim1552Kuo2Init, + dim1553Kuo2Init, + dim1554Kuo2Init, + dim1555Kuo2Init, + dim1556Kuo2Init, + dim1557Kuo2Init, + dim1558Kuo2Init, + dim1559Kuo2Init, + dim1560Kuo2Init, + dim1561Kuo2Init, + dim1562Kuo2Init, + dim1563Kuo2Init, + dim1564Kuo2Init, + dim1565Kuo2Init, + dim1566Kuo2Init, + dim1567Kuo2Init, + dim1568Kuo2Init, + dim1569Kuo2Init, + dim1570Kuo2Init, + dim1571Kuo2Init, + dim1572Kuo2Init, + dim1573Kuo2Init, + dim1574Kuo2Init, + dim1575Kuo2Init, + dim1576Kuo2Init, + dim1577Kuo2Init, + dim1578Kuo2Init, + dim1579Kuo2Init, + dim1580Kuo2Init, + dim1581Kuo2Init, + dim1582Kuo2Init, + dim1583Kuo2Init, + dim1584Kuo2Init, + dim1585Kuo2Init, + dim1586Kuo2Init, + dim1587Kuo2Init, + dim1588Kuo2Init, + dim1589Kuo2Init, + dim1590Kuo2Init, + dim1591Kuo2Init, + dim1592Kuo2Init, + dim1593Kuo2Init, + dim1594Kuo2Init, + dim1595Kuo2Init, + dim1596Kuo2Init, + dim1597Kuo2Init, + dim1598Kuo2Init, + dim1599Kuo2Init, + dim1600Kuo2Init, + dim1601Kuo2Init, + dim1602Kuo2Init, + dim1603Kuo2Init, + dim1604Kuo2Init, + dim1605Kuo2Init, + dim1606Kuo2Init, + dim1607Kuo2Init, + dim1608Kuo2Init, + dim1609Kuo2Init, + dim1610Kuo2Init, + dim1611Kuo2Init, + dim1612Kuo2Init, + dim1613Kuo2Init, + dim1614Kuo2Init, + dim1615Kuo2Init, + dim1616Kuo2Init, + dim1617Kuo2Init, + dim1618Kuo2Init, + dim1619Kuo2Init, + dim1620Kuo2Init, + dim1621Kuo2Init, + dim1622Kuo2Init, + dim1623Kuo2Init, + dim1624Kuo2Init, + dim1625Kuo2Init, + dim1626Kuo2Init, + dim1627Kuo2Init, + dim1628Kuo2Init, + dim1629Kuo2Init, + dim1630Kuo2Init, + dim1631Kuo2Init, + dim1632Kuo2Init, + dim1633Kuo2Init, + dim1634Kuo2Init, + dim1635Kuo2Init, + dim1636Kuo2Init, + dim1637Kuo2Init, + dim1638Kuo2Init, + dim1639Kuo2Init, + dim1640Kuo2Init, + dim1641Kuo2Init, + dim1642Kuo2Init, + dim1643Kuo2Init, + dim1644Kuo2Init, + dim1645Kuo2Init, + dim1646Kuo2Init, + dim1647Kuo2Init, + dim1648Kuo2Init, + dim1649Kuo2Init, + dim1650Kuo2Init, + dim1651Kuo2Init, + dim1652Kuo2Init, + dim1653Kuo2Init, + dim1654Kuo2Init, + dim1655Kuo2Init, + dim1656Kuo2Init, + dim1657Kuo2Init, + dim1658Kuo2Init, + dim1659Kuo2Init, + dim1660Kuo2Init, + dim1661Kuo2Init, + dim1662Kuo2Init, + dim1663Kuo2Init, + dim1664Kuo2Init, + dim1665Kuo2Init, + dim1666Kuo2Init, + dim1667Kuo2Init, + dim1668Kuo2Init, + dim1669Kuo2Init, + dim1670Kuo2Init, + dim1671Kuo2Init, + dim1672Kuo2Init, + dim1673Kuo2Init, + dim1674Kuo2Init, + dim1675Kuo2Init, + dim1676Kuo2Init, + dim1677Kuo2Init, + dim1678Kuo2Init, + dim1679Kuo2Init, + dim1680Kuo2Init, + dim1681Kuo2Init, + dim1682Kuo2Init, + dim1683Kuo2Init, + dim1684Kuo2Init, + dim1685Kuo2Init, + dim1686Kuo2Init, + dim1687Kuo2Init, + dim1688Kuo2Init, + dim1689Kuo2Init, + dim1690Kuo2Init, + dim1691Kuo2Init, + dim1692Kuo2Init, + dim1693Kuo2Init, + dim1694Kuo2Init, + dim1695Kuo2Init, + dim1696Kuo2Init, + dim1697Kuo2Init, + dim1698Kuo2Init, + dim1699Kuo2Init, + dim1700Kuo2Init, + dim1701Kuo2Init, + dim1702Kuo2Init, + dim1703Kuo2Init, + dim1704Kuo2Init, + dim1705Kuo2Init, + dim1706Kuo2Init, + dim1707Kuo2Init, + dim1708Kuo2Init, + dim1709Kuo2Init, + dim1710Kuo2Init, + dim1711Kuo2Init, + dim1712Kuo2Init, + dim1713Kuo2Init, + dim1714Kuo2Init, + dim1715Kuo2Init, + dim1716Kuo2Init, + dim1717Kuo2Init, + dim1718Kuo2Init, + dim1719Kuo2Init, + dim1720Kuo2Init, + dim1721Kuo2Init, + dim1722Kuo2Init, + dim1723Kuo2Init, + dim1724Kuo2Init, + dim1725Kuo2Init, + dim1726Kuo2Init, + dim1727Kuo2Init, + dim1728Kuo2Init, + dim1729Kuo2Init, + dim1730Kuo2Init, + dim1731Kuo2Init, + dim1732Kuo2Init, + dim1733Kuo2Init, + dim1734Kuo2Init, + dim1735Kuo2Init, + dim1736Kuo2Init, + dim1737Kuo2Init, + dim1738Kuo2Init, + dim1739Kuo2Init, + dim1740Kuo2Init, + dim1741Kuo2Init, + dim1742Kuo2Init, + dim1743Kuo2Init, + dim1744Kuo2Init, + dim1745Kuo2Init, + dim1746Kuo2Init, + dim1747Kuo2Init, + dim1748Kuo2Init, + dim1749Kuo2Init, + dim1750Kuo2Init, + dim1751Kuo2Init, + dim1752Kuo2Init, + dim1753Kuo2Init, + dim1754Kuo2Init, + dim1755Kuo2Init, + dim1756Kuo2Init, + dim1757Kuo2Init, + dim1758Kuo2Init, + dim1759Kuo2Init, + dim1760Kuo2Init, + dim1761Kuo2Init, + dim1762Kuo2Init, + dim1763Kuo2Init, + dim1764Kuo2Init, + dim1765Kuo2Init, + dim1766Kuo2Init, + dim1767Kuo2Init, + dim1768Kuo2Init, + dim1769Kuo2Init, + dim1770Kuo2Init, + dim1771Kuo2Init, + dim1772Kuo2Init, + dim1773Kuo2Init, + dim1774Kuo2Init, + dim1775Kuo2Init, + dim1776Kuo2Init, + dim1777Kuo2Init, + dim1778Kuo2Init, + dim1779Kuo2Init, + dim1780Kuo2Init, + dim1781Kuo2Init, + dim1782Kuo2Init, + dim1783Kuo2Init, + dim1784Kuo2Init, + dim1785Kuo2Init, + dim1786Kuo2Init, + dim1787Kuo2Init, + dim1788Kuo2Init, + dim1789Kuo2Init, + dim1790Kuo2Init, + dim1791Kuo2Init, + dim1792Kuo2Init, + dim1793Kuo2Init, + dim1794Kuo2Init, + dim1795Kuo2Init, + dim1796Kuo2Init, + dim1797Kuo2Init, + dim1798Kuo2Init, + dim1799Kuo2Init, + dim1800Kuo2Init, + dim1801Kuo2Init, + dim1802Kuo2Init, + dim1803Kuo2Init, + dim1804Kuo2Init, + dim1805Kuo2Init, + dim1806Kuo2Init, + dim1807Kuo2Init, + dim1808Kuo2Init, + dim1809Kuo2Init, + dim1810Kuo2Init, + dim1811Kuo2Init, + dim1812Kuo2Init, + dim1813Kuo2Init, + dim1814Kuo2Init, + dim1815Kuo2Init, + dim1816Kuo2Init, + dim1817Kuo2Init, + dim1818Kuo2Init, + dim1819Kuo2Init, + dim1820Kuo2Init, + dim1821Kuo2Init, + dim1822Kuo2Init, + dim1823Kuo2Init, + dim1824Kuo2Init, + dim1825Kuo2Init, + dim1826Kuo2Init, + dim1827Kuo2Init, + dim1828Kuo2Init, + dim1829Kuo2Init, + dim1830Kuo2Init, + dim1831Kuo2Init, + dim1832Kuo2Init, + dim1833Kuo2Init, + dim1834Kuo2Init, + dim1835Kuo2Init, + dim1836Kuo2Init, + dim1837Kuo2Init, + dim1838Kuo2Init, + dim1839Kuo2Init, + dim1840Kuo2Init, + dim1841Kuo2Init, + dim1842Kuo2Init, + dim1843Kuo2Init, + dim1844Kuo2Init, + dim1845Kuo2Init, + dim1846Kuo2Init, + dim1847Kuo2Init, + dim1848Kuo2Init, + dim1849Kuo2Init, + dim1850Kuo2Init, + dim1851Kuo2Init, + dim1852Kuo2Init, + dim1853Kuo2Init, + dim1854Kuo2Init, + dim1855Kuo2Init, + dim1856Kuo2Init, + dim1857Kuo2Init, + dim1858Kuo2Init, + dim1859Kuo2Init, + dim1860Kuo2Init, + dim1861Kuo2Init, + dim1862Kuo2Init, + dim1863Kuo2Init, + dim1864Kuo2Init, + dim1865Kuo2Init, + dim1866Kuo2Init, + dim1867Kuo2Init, + dim1868Kuo2Init, + dim1869Kuo2Init, + dim1870Kuo2Init, + dim1871Kuo2Init, + dim1872Kuo2Init, + dim1873Kuo2Init, + dim1874Kuo2Init, + dim1875Kuo2Init, + dim1876Kuo2Init, + dim1877Kuo2Init, + dim1878Kuo2Init, + dim1879Kuo2Init, + dim1880Kuo2Init, + dim1881Kuo2Init, + dim1882Kuo2Init, + dim1883Kuo2Init, + dim1884Kuo2Init, + dim1885Kuo2Init, + dim1886Kuo2Init, + dim1887Kuo2Init, + dim1888Kuo2Init, + dim1889Kuo2Init, + dim1890Kuo2Init, + dim1891Kuo2Init, + dim1892Kuo2Init, + dim1893Kuo2Init, + dim1894Kuo2Init, + dim1895Kuo2Init, + dim1896Kuo2Init, + dim1897Kuo2Init, + dim1898Kuo2Init, + dim1899Kuo2Init, + dim1900Kuo2Init, + dim1901Kuo2Init, + dim1902Kuo2Init, + dim1903Kuo2Init, + dim1904Kuo2Init, + dim1905Kuo2Init, + dim1906Kuo2Init, + dim1907Kuo2Init, + dim1908Kuo2Init, + dim1909Kuo2Init, + dim1910Kuo2Init, + dim1911Kuo2Init, + dim1912Kuo2Init, + dim1913Kuo2Init, + dim1914Kuo2Init, + dim1915Kuo2Init, + dim1916Kuo2Init, + dim1917Kuo2Init, + dim1918Kuo2Init, + dim1919Kuo2Init, + dim1920Kuo2Init, + dim1921Kuo2Init, + dim1922Kuo2Init, + dim1923Kuo2Init, + dim1924Kuo2Init, + dim1925Kuo2Init, + dim1926Kuo2Init, + dim1927Kuo2Init, + dim1928Kuo2Init, + dim1929Kuo2Init, + dim1930Kuo2Init, + dim1931Kuo2Init, + dim1932Kuo2Init, + dim1933Kuo2Init, + dim1934Kuo2Init, + dim1935Kuo2Init, + dim1936Kuo2Init, + dim1937Kuo2Init, + dim1938Kuo2Init, + dim1939Kuo2Init, + dim1940Kuo2Init, + dim1941Kuo2Init, + dim1942Kuo2Init, + dim1943Kuo2Init, + dim1944Kuo2Init, + dim1945Kuo2Init, + dim1946Kuo2Init, + dim1947Kuo2Init, + dim1948Kuo2Init, + dim1949Kuo2Init, + dim1950Kuo2Init, + dim1951Kuo2Init, + dim1952Kuo2Init, + dim1953Kuo2Init, + dim1954Kuo2Init, + dim1955Kuo2Init, + dim1956Kuo2Init, + dim1957Kuo2Init, + dim1958Kuo2Init, + dim1959Kuo2Init, + dim1960Kuo2Init, + dim1961Kuo2Init, + dim1962Kuo2Init, + dim1963Kuo2Init, + dim1964Kuo2Init, + dim1965Kuo2Init, + dim1966Kuo2Init, + dim1967Kuo2Init, + dim1968Kuo2Init, + dim1969Kuo2Init, + dim1970Kuo2Init, + dim1971Kuo2Init, + dim1972Kuo2Init, + dim1973Kuo2Init, + dim1974Kuo2Init, + dim1975Kuo2Init, + dim1976Kuo2Init, + dim1977Kuo2Init, + dim1978Kuo2Init, + dim1979Kuo2Init, + dim1980Kuo2Init, + dim1981Kuo2Init, + dim1982Kuo2Init, + dim1983Kuo2Init, + dim1984Kuo2Init, + dim1985Kuo2Init, + dim1986Kuo2Init, + dim1987Kuo2Init, + dim1988Kuo2Init, + dim1989Kuo2Init, + dim1990Kuo2Init, + dim1991Kuo2Init, + dim1992Kuo2Init, + dim1993Kuo2Init, + dim1994Kuo2Init, + dim1995Kuo2Init, + dim1996Kuo2Init, + dim1997Kuo2Init, + dim1998Kuo2Init, + dim1999Kuo2Init, + dim2000Kuo2Init, + dim2001Kuo2Init, + dim2002Kuo2Init, + dim2003Kuo2Init, + dim2004Kuo2Init, + dim2005Kuo2Init, + dim2006Kuo2Init, + dim2007Kuo2Init, + dim2008Kuo2Init, + dim2009Kuo2Init, + dim2010Kuo2Init, + dim2011Kuo2Init, + dim2012Kuo2Init, + dim2013Kuo2Init, + dim2014Kuo2Init, + dim2015Kuo2Init, + dim2016Kuo2Init, + dim2017Kuo2Init, + dim2018Kuo2Init, + dim2019Kuo2Init, + dim2020Kuo2Init, + dim2021Kuo2Init, + dim2022Kuo2Init, + dim2023Kuo2Init, + dim2024Kuo2Init, + dim2025Kuo2Init, + dim2026Kuo2Init, + dim2027Kuo2Init, + dim2028Kuo2Init, + dim2029Kuo2Init, + dim2030Kuo2Init, + dim2031Kuo2Init, + dim2032Kuo2Init, + dim2033Kuo2Init, + dim2034Kuo2Init, + dim2035Kuo2Init, + dim2036Kuo2Init, + dim2037Kuo2Init, + dim2038Kuo2Init, + dim2039Kuo2Init, + dim2040Kuo2Init, + dim2041Kuo2Init, + dim2042Kuo2Init, + dim2043Kuo2Init, + dim2044Kuo2Init, + dim2045Kuo2Init, + dim2046Kuo2Init, + dim2047Kuo2Init, + dim2048Kuo2Init, + dim2049Kuo2Init, + dim2050Kuo2Init, + dim2051Kuo2Init, + dim2052Kuo2Init, + dim2053Kuo2Init, + dim2054Kuo2Init, + dim2055Kuo2Init, + dim2056Kuo2Init, + dim2057Kuo2Init, + dim2058Kuo2Init, + dim2059Kuo2Init, + dim2060Kuo2Init, + dim2061Kuo2Init, + dim2062Kuo2Init, + dim2063Kuo2Init, + dim2064Kuo2Init, + dim2065Kuo2Init, + dim2066Kuo2Init, + dim2067Kuo2Init, + dim2068Kuo2Init, + dim2069Kuo2Init, + dim2070Kuo2Init, + dim2071Kuo2Init, + dim2072Kuo2Init, + dim2073Kuo2Init, + dim2074Kuo2Init, + dim2075Kuo2Init, + dim2076Kuo2Init, + dim2077Kuo2Init, + dim2078Kuo2Init, + dim2079Kuo2Init, + dim2080Kuo2Init, + dim2081Kuo2Init, + dim2082Kuo2Init, + dim2083Kuo2Init, + dim2084Kuo2Init, + dim2085Kuo2Init, + dim2086Kuo2Init, + dim2087Kuo2Init, + dim2088Kuo2Init, + dim2089Kuo2Init, + dim2090Kuo2Init, + dim2091Kuo2Init, + dim2092Kuo2Init, + dim2093Kuo2Init, + dim2094Kuo2Init, + dim2095Kuo2Init, + dim2096Kuo2Init, + dim2097Kuo2Init, + dim2098Kuo2Init, + dim2099Kuo2Init, + dim2100Kuo2Init, + dim2101Kuo2Init, + dim2102Kuo2Init, + dim2103Kuo2Init, + dim2104Kuo2Init, + dim2105Kuo2Init, + dim2106Kuo2Init, + dim2107Kuo2Init, + dim2108Kuo2Init, + dim2109Kuo2Init, + dim2110Kuo2Init, + dim2111Kuo2Init, + dim2112Kuo2Init, + dim2113Kuo2Init, + dim2114Kuo2Init, + dim2115Kuo2Init, + dim2116Kuo2Init, + dim2117Kuo2Init, + dim2118Kuo2Init, + dim2119Kuo2Init, + dim2120Kuo2Init, + dim2121Kuo2Init, + dim2122Kuo2Init, + dim2123Kuo2Init, + dim2124Kuo2Init, + dim2125Kuo2Init, + dim2126Kuo2Init, + dim2127Kuo2Init, + dim2128Kuo2Init, + dim2129Kuo2Init, + dim2130Kuo2Init, + dim2131Kuo2Init, + dim2132Kuo2Init, + dim2133Kuo2Init, + dim2134Kuo2Init, + dim2135Kuo2Init, + dim2136Kuo2Init, + dim2137Kuo2Init, + dim2138Kuo2Init, + dim2139Kuo2Init, + dim2140Kuo2Init, + dim2141Kuo2Init, + dim2142Kuo2Init, + dim2143Kuo2Init, + dim2144Kuo2Init, + dim2145Kuo2Init, + dim2146Kuo2Init, + dim2147Kuo2Init, + dim2148Kuo2Init, + dim2149Kuo2Init, + dim2150Kuo2Init, + dim2151Kuo2Init, + dim2152Kuo2Init, + dim2153Kuo2Init, + dim2154Kuo2Init, + dim2155Kuo2Init, + dim2156Kuo2Init, + dim2157Kuo2Init, + dim2158Kuo2Init, + dim2159Kuo2Init, + dim2160Kuo2Init, + dim2161Kuo2Init, + dim2162Kuo2Init, + dim2163Kuo2Init, + dim2164Kuo2Init, + dim2165Kuo2Init, + dim2166Kuo2Init, + dim2167Kuo2Init, + dim2168Kuo2Init, + dim2169Kuo2Init, + dim2170Kuo2Init, + dim2171Kuo2Init, + dim2172Kuo2Init, + dim2173Kuo2Init, + dim2174Kuo2Init, + dim2175Kuo2Init, + dim2176Kuo2Init, + dim2177Kuo2Init, + dim2178Kuo2Init, + dim2179Kuo2Init, + dim2180Kuo2Init, + dim2181Kuo2Init, + dim2182Kuo2Init, + dim2183Kuo2Init, + dim2184Kuo2Init, + dim2185Kuo2Init, + dim2186Kuo2Init, + dim2187Kuo2Init, + dim2188Kuo2Init, + dim2189Kuo2Init, + dim2190Kuo2Init, + dim2191Kuo2Init, + dim2192Kuo2Init, + dim2193Kuo2Init, + dim2194Kuo2Init, + dim2195Kuo2Init, + dim2196Kuo2Init, + dim2197Kuo2Init, + dim2198Kuo2Init, + dim2199Kuo2Init, + dim2200Kuo2Init, + dim2201Kuo2Init, + dim2202Kuo2Init, + dim2203Kuo2Init, + dim2204Kuo2Init, + dim2205Kuo2Init, + dim2206Kuo2Init, + dim2207Kuo2Init, + dim2208Kuo2Init, + dim2209Kuo2Init, + dim2210Kuo2Init, + dim2211Kuo2Init, + dim2212Kuo2Init, + dim2213Kuo2Init, + dim2214Kuo2Init, + dim2215Kuo2Init, + dim2216Kuo2Init, + dim2217Kuo2Init, + dim2218Kuo2Init, + dim2219Kuo2Init, + dim2220Kuo2Init, + dim2221Kuo2Init, + dim2222Kuo2Init, + dim2223Kuo2Init, + dim2224Kuo2Init, + dim2225Kuo2Init, + dim2226Kuo2Init, + dim2227Kuo2Init, + dim2228Kuo2Init, + dim2229Kuo2Init, + dim2230Kuo2Init, + dim2231Kuo2Init, + dim2232Kuo2Init, + dim2233Kuo2Init, + dim2234Kuo2Init, + dim2235Kuo2Init, + dim2236Kuo2Init, + dim2237Kuo2Init, + dim2238Kuo2Init, + dim2239Kuo2Init, + dim2240Kuo2Init, + dim2241Kuo2Init, + dim2242Kuo2Init, + dim2243Kuo2Init, + dim2244Kuo2Init, + dim2245Kuo2Init, + dim2246Kuo2Init, + dim2247Kuo2Init, + dim2248Kuo2Init, + dim2249Kuo2Init, + dim2250Kuo2Init, + dim2251Kuo2Init, + dim2252Kuo2Init, + dim2253Kuo2Init, + dim2254Kuo2Init, + dim2255Kuo2Init, + dim2256Kuo2Init, + dim2257Kuo2Init, + dim2258Kuo2Init, + dim2259Kuo2Init, + dim2260Kuo2Init, + dim2261Kuo2Init, + dim2262Kuo2Init, + dim2263Kuo2Init, + dim2264Kuo2Init, + dim2265Kuo2Init, + dim2266Kuo2Init, + dim2267Kuo2Init, + dim2268Kuo2Init, + dim2269Kuo2Init, + dim2270Kuo2Init, + dim2271Kuo2Init, + dim2272Kuo2Init, + dim2273Kuo2Init, + dim2274Kuo2Init, + dim2275Kuo2Init, + dim2276Kuo2Init, + dim2277Kuo2Init, + dim2278Kuo2Init, + dim2279Kuo2Init, + dim2280Kuo2Init, + dim2281Kuo2Init, + dim2282Kuo2Init, + dim2283Kuo2Init, + dim2284Kuo2Init, + dim2285Kuo2Init, + dim2286Kuo2Init, + dim2287Kuo2Init, + dim2288Kuo2Init, + dim2289Kuo2Init, + dim2290Kuo2Init, + dim2291Kuo2Init, + dim2292Kuo2Init, + dim2293Kuo2Init, + dim2294Kuo2Init, + dim2295Kuo2Init, + dim2296Kuo2Init, + dim2297Kuo2Init, + dim2298Kuo2Init, + dim2299Kuo2Init, + dim2300Kuo2Init, + dim2301Kuo2Init, + dim2302Kuo2Init, + dim2303Kuo2Init, + dim2304Kuo2Init, + dim2305Kuo2Init, + dim2306Kuo2Init, + dim2307Kuo2Init, + dim2308Kuo2Init, + dim2309Kuo2Init, + dim2310Kuo2Init, + dim2311Kuo2Init, + dim2312Kuo2Init, + dim2313Kuo2Init, + dim2314Kuo2Init, + dim2315Kuo2Init, + dim2316Kuo2Init, + dim2317Kuo2Init, + dim2318Kuo2Init, + dim2319Kuo2Init, + dim2320Kuo2Init, + dim2321Kuo2Init, + dim2322Kuo2Init, + dim2323Kuo2Init, + dim2324Kuo2Init, + dim2325Kuo2Init, + dim2326Kuo2Init, + dim2327Kuo2Init, + dim2328Kuo2Init, + dim2329Kuo2Init, + dim2330Kuo2Init, + dim2331Kuo2Init, + dim2332Kuo2Init, + dim2333Kuo2Init, + dim2334Kuo2Init, + dim2335Kuo2Init, + dim2336Kuo2Init, + dim2337Kuo2Init, + dim2338Kuo2Init, + dim2339Kuo2Init, + dim2340Kuo2Init, + dim2341Kuo2Init, + dim2342Kuo2Init, + dim2343Kuo2Init, + dim2344Kuo2Init, + dim2345Kuo2Init, + dim2346Kuo2Init, + dim2347Kuo2Init, + dim2348Kuo2Init, + dim2349Kuo2Init, + dim2350Kuo2Init, + dim2351Kuo2Init, + dim2352Kuo2Init, + dim2353Kuo2Init, + dim2354Kuo2Init, + dim2355Kuo2Init, + dim2356Kuo2Init, + dim2357Kuo2Init, + dim2358Kuo2Init, + dim2359Kuo2Init, + dim2360Kuo2Init, + dim2361Kuo2Init, + dim2362Kuo2Init, + dim2363Kuo2Init, + dim2364Kuo2Init, + dim2365Kuo2Init, + dim2366Kuo2Init, + dim2367Kuo2Init, + dim2368Kuo2Init, + dim2369Kuo2Init, + dim2370Kuo2Init, + dim2371Kuo2Init, + dim2372Kuo2Init, + dim2373Kuo2Init, + dim2374Kuo2Init, + dim2375Kuo2Init, + dim2376Kuo2Init, + dim2377Kuo2Init, + dim2378Kuo2Init, + dim2379Kuo2Init, + dim2380Kuo2Init, + dim2381Kuo2Init, + dim2382Kuo2Init, + dim2383Kuo2Init, + dim2384Kuo2Init, + dim2385Kuo2Init, + dim2386Kuo2Init, + dim2387Kuo2Init, + dim2388Kuo2Init, + dim2389Kuo2Init, + dim2390Kuo2Init, + dim2391Kuo2Init, + dim2392Kuo2Init, + dim2393Kuo2Init, + dim2394Kuo2Init, + dim2395Kuo2Init, + dim2396Kuo2Init, + dim2397Kuo2Init, + dim2398Kuo2Init, + dim2399Kuo2Init, + dim2400Kuo2Init, + dim2401Kuo2Init, + dim2402Kuo2Init, + dim2403Kuo2Init, + dim2404Kuo2Init, + dim2405Kuo2Init, + dim2406Kuo2Init, + dim2407Kuo2Init, + dim2408Kuo2Init, + dim2409Kuo2Init, + dim2410Kuo2Init, + dim2411Kuo2Init, + dim2412Kuo2Init, + dim2413Kuo2Init, + dim2414Kuo2Init, + dim2415Kuo2Init, + dim2416Kuo2Init, + dim2417Kuo2Init, + dim2418Kuo2Init, + dim2419Kuo2Init, + dim2420Kuo2Init, + dim2421Kuo2Init, + dim2422Kuo2Init, + dim2423Kuo2Init, + dim2424Kuo2Init, + dim2425Kuo2Init, + dim2426Kuo2Init, + dim2427Kuo2Init, + dim2428Kuo2Init, + dim2429Kuo2Init, + dim2430Kuo2Init, + dim2431Kuo2Init, + dim2432Kuo2Init, + dim2433Kuo2Init, + dim2434Kuo2Init, + dim2435Kuo2Init, + dim2436Kuo2Init, + dim2437Kuo2Init, + dim2438Kuo2Init, + dim2439Kuo2Init, + dim2440Kuo2Init, + dim2441Kuo2Init, + dim2442Kuo2Init, + dim2443Kuo2Init, + dim2444Kuo2Init, + dim2445Kuo2Init, + dim2446Kuo2Init, + dim2447Kuo2Init, + dim2448Kuo2Init, + dim2449Kuo2Init, + dim2450Kuo2Init, + dim2451Kuo2Init, + dim2452Kuo2Init, + dim2453Kuo2Init, + dim2454Kuo2Init, + dim2455Kuo2Init, + dim2456Kuo2Init, + dim2457Kuo2Init, + dim2458Kuo2Init, + dim2459Kuo2Init, + dim2460Kuo2Init, + dim2461Kuo2Init, + dim2462Kuo2Init, + dim2463Kuo2Init, + dim2464Kuo2Init, + dim2465Kuo2Init, + dim2466Kuo2Init, + dim2467Kuo2Init, + dim2468Kuo2Init, + dim2469Kuo2Init, + dim2470Kuo2Init, + dim2471Kuo2Init, + dim2472Kuo2Init, + dim2473Kuo2Init, + dim2474Kuo2Init, + dim2475Kuo2Init, + dim2476Kuo2Init, + dim2477Kuo2Init, + dim2478Kuo2Init, + dim2479Kuo2Init, + dim2480Kuo2Init, + dim2481Kuo2Init, + dim2482Kuo2Init, + dim2483Kuo2Init, + dim2484Kuo2Init, + dim2485Kuo2Init, + dim2486Kuo2Init, + dim2487Kuo2Init, + dim2488Kuo2Init, + dim2489Kuo2Init, + dim2490Kuo2Init, + dim2491Kuo2Init, + dim2492Kuo2Init, + dim2493Kuo2Init, + dim2494Kuo2Init, + dim2495Kuo2Init, + dim2496Kuo2Init, + dim2497Kuo2Init, + dim2498Kuo2Init, + dim2499Kuo2Init, + dim2500Kuo2Init, + dim2501Kuo2Init, + dim2502Kuo2Init, + dim2503Kuo2Init, + dim2504Kuo2Init, + dim2505Kuo2Init, + dim2506Kuo2Init, + dim2507Kuo2Init, + dim2508Kuo2Init, + dim2509Kuo2Init, + dim2510Kuo2Init, + dim2511Kuo2Init, + dim2512Kuo2Init, + dim2513Kuo2Init, + dim2514Kuo2Init, + dim2515Kuo2Init, + dim2516Kuo2Init, + dim2517Kuo2Init, + dim2518Kuo2Init, + dim2519Kuo2Init, + dim2520Kuo2Init, + dim2521Kuo2Init, + dim2522Kuo2Init, + dim2523Kuo2Init, + dim2524Kuo2Init, + dim2525Kuo2Init, + dim2526Kuo2Init, + dim2527Kuo2Init, + dim2528Kuo2Init, + dim2529Kuo2Init, + dim2530Kuo2Init, + dim2531Kuo2Init, + dim2532Kuo2Init, + dim2533Kuo2Init, + dim2534Kuo2Init, + dim2535Kuo2Init, + dim2536Kuo2Init, + dim2537Kuo2Init, + dim2538Kuo2Init, + dim2539Kuo2Init, + dim2540Kuo2Init, + dim2541Kuo2Init, + dim2542Kuo2Init, + dim2543Kuo2Init, + dim2544Kuo2Init, + dim2545Kuo2Init, + dim2546Kuo2Init, + dim2547Kuo2Init, + dim2548Kuo2Init, + dim2549Kuo2Init, + dim2550Kuo2Init, + dim2551Kuo2Init, + dim2552Kuo2Init, + dim2553Kuo2Init, + dim2554Kuo2Init, + dim2555Kuo2Init, + dim2556Kuo2Init, + dim2557Kuo2Init, + dim2558Kuo2Init, + dim2559Kuo2Init, + dim2560Kuo2Init, + dim2561Kuo2Init, + dim2562Kuo2Init, + dim2563Kuo2Init, + dim2564Kuo2Init, + dim2565Kuo2Init, + dim2566Kuo2Init, + dim2567Kuo2Init, + dim2568Kuo2Init, + dim2569Kuo2Init, + dim2570Kuo2Init, + dim2571Kuo2Init, + dim2572Kuo2Init, + dim2573Kuo2Init, + dim2574Kuo2Init, + dim2575Kuo2Init, + dim2576Kuo2Init, + dim2577Kuo2Init, + dim2578Kuo2Init, + dim2579Kuo2Init, + dim2580Kuo2Init, + dim2581Kuo2Init, + dim2582Kuo2Init, + dim2583Kuo2Init, + dim2584Kuo2Init, + dim2585Kuo2Init, + dim2586Kuo2Init, + dim2587Kuo2Init, + dim2588Kuo2Init, + dim2589Kuo2Init, + dim2590Kuo2Init, + dim2591Kuo2Init, + dim2592Kuo2Init, + dim2593Kuo2Init, + dim2594Kuo2Init, + dim2595Kuo2Init, + dim2596Kuo2Init, + dim2597Kuo2Init, + dim2598Kuo2Init, + dim2599Kuo2Init, + dim2600Kuo2Init, + dim2601Kuo2Init, + dim2602Kuo2Init, + dim2603Kuo2Init, + dim2604Kuo2Init, + dim2605Kuo2Init, + dim2606Kuo2Init, + dim2607Kuo2Init, + dim2608Kuo2Init, + dim2609Kuo2Init, + dim2610Kuo2Init, + dim2611Kuo2Init, + dim2612Kuo2Init, + dim2613Kuo2Init, + dim2614Kuo2Init, + dim2615Kuo2Init, + dim2616Kuo2Init, + dim2617Kuo2Init, + dim2618Kuo2Init, + dim2619Kuo2Init, + dim2620Kuo2Init, + dim2621Kuo2Init, + dim2622Kuo2Init, + dim2623Kuo2Init, + dim2624Kuo2Init, + dim2625Kuo2Init, + dim2626Kuo2Init, + dim2627Kuo2Init, + dim2628Kuo2Init, + dim2629Kuo2Init, + dim2630Kuo2Init, + dim2631Kuo2Init, + dim2632Kuo2Init, + dim2633Kuo2Init, + dim2634Kuo2Init, + dim2635Kuo2Init, + dim2636Kuo2Init, + dim2637Kuo2Init, + dim2638Kuo2Init, + dim2639Kuo2Init, + dim2640Kuo2Init, + dim2641Kuo2Init, + dim2642Kuo2Init, + dim2643Kuo2Init, + dim2644Kuo2Init, + dim2645Kuo2Init, + dim2646Kuo2Init, + dim2647Kuo2Init, + dim2648Kuo2Init, + dim2649Kuo2Init, + dim2650Kuo2Init, + dim2651Kuo2Init, + dim2652Kuo2Init, + dim2653Kuo2Init, + dim2654Kuo2Init, + dim2655Kuo2Init, + dim2656Kuo2Init, + dim2657Kuo2Init, + dim2658Kuo2Init, + dim2659Kuo2Init, + dim2660Kuo2Init, + dim2661Kuo2Init, + dim2662Kuo2Init, + dim2663Kuo2Init, + dim2664Kuo2Init, + dim2665Kuo2Init, + dim2666Kuo2Init, + dim2667Kuo2Init, + dim2668Kuo2Init, + dim2669Kuo2Init, + dim2670Kuo2Init, + dim2671Kuo2Init, + dim2672Kuo2Init, + dim2673Kuo2Init, + dim2674Kuo2Init, + dim2675Kuo2Init, + dim2676Kuo2Init, + dim2677Kuo2Init, + dim2678Kuo2Init, + dim2679Kuo2Init, + dim2680Kuo2Init, + dim2681Kuo2Init, + dim2682Kuo2Init, + dim2683Kuo2Init, + dim2684Kuo2Init, + dim2685Kuo2Init, + dim2686Kuo2Init, + dim2687Kuo2Init, + dim2688Kuo2Init, + dim2689Kuo2Init, + dim2690Kuo2Init, + dim2691Kuo2Init, + dim2692Kuo2Init, + dim2693Kuo2Init, + dim2694Kuo2Init, + dim2695Kuo2Init, + dim2696Kuo2Init, + dim2697Kuo2Init, + dim2698Kuo2Init, + dim2699Kuo2Init, + dim2700Kuo2Init, + dim2701Kuo2Init, + dim2702Kuo2Init, + dim2703Kuo2Init, + dim2704Kuo2Init, + dim2705Kuo2Init, + dim2706Kuo2Init, + dim2707Kuo2Init, + dim2708Kuo2Init, + dim2709Kuo2Init, + dim2710Kuo2Init, + dim2711Kuo2Init, + dim2712Kuo2Init, + dim2713Kuo2Init, + dim2714Kuo2Init, + dim2715Kuo2Init, + dim2716Kuo2Init, + dim2717Kuo2Init, + dim2718Kuo2Init, + dim2719Kuo2Init, + dim2720Kuo2Init, + dim2721Kuo2Init, + dim2722Kuo2Init, + dim2723Kuo2Init, + dim2724Kuo2Init, + dim2725Kuo2Init, + dim2726Kuo2Init, + dim2727Kuo2Init, + dim2728Kuo2Init, + dim2729Kuo2Init, + dim2730Kuo2Init, + dim2731Kuo2Init, + dim2732Kuo2Init, + dim2733Kuo2Init, + dim2734Kuo2Init, + dim2735Kuo2Init, + dim2736Kuo2Init, + dim2737Kuo2Init, + dim2738Kuo2Init, + dim2739Kuo2Init, + dim2740Kuo2Init, + dim2741Kuo2Init, + dim2742Kuo2Init, + dim2743Kuo2Init, + dim2744Kuo2Init, + dim2745Kuo2Init, + dim2746Kuo2Init, + dim2747Kuo2Init, + dim2748Kuo2Init, + dim2749Kuo2Init, + dim2750Kuo2Init, + dim2751Kuo2Init, + dim2752Kuo2Init, + dim2753Kuo2Init, + dim2754Kuo2Init, + dim2755Kuo2Init, + dim2756Kuo2Init, + dim2757Kuo2Init, + dim2758Kuo2Init, + dim2759Kuo2Init, + dim2760Kuo2Init, + dim2761Kuo2Init, + dim2762Kuo2Init, + dim2763Kuo2Init, + dim2764Kuo2Init, + dim2765Kuo2Init, + dim2766Kuo2Init, + dim2767Kuo2Init, + dim2768Kuo2Init, + dim2769Kuo2Init, + dim2770Kuo2Init, + dim2771Kuo2Init, + dim2772Kuo2Init, + dim2773Kuo2Init, + dim2774Kuo2Init, + dim2775Kuo2Init, + dim2776Kuo2Init, + dim2777Kuo2Init, + dim2778Kuo2Init, + dim2779Kuo2Init, + dim2780Kuo2Init, + dim2781Kuo2Init, + dim2782Kuo2Init, + dim2783Kuo2Init, + dim2784Kuo2Init, + dim2785Kuo2Init, + dim2786Kuo2Init, + dim2787Kuo2Init, + dim2788Kuo2Init, + dim2789Kuo2Init, + dim2790Kuo2Init, + dim2791Kuo2Init, + dim2792Kuo2Init, + dim2793Kuo2Init, + dim2794Kuo2Init, + dim2795Kuo2Init, + dim2796Kuo2Init, + dim2797Kuo2Init, + dim2798Kuo2Init, + dim2799Kuo2Init, + dim2800Kuo2Init, + dim2801Kuo2Init, + dim2802Kuo2Init, + dim2803Kuo2Init, + dim2804Kuo2Init, + dim2805Kuo2Init, + dim2806Kuo2Init, + dim2807Kuo2Init, + dim2808Kuo2Init, + dim2809Kuo2Init, + dim2810Kuo2Init, + dim2811Kuo2Init, + dim2812Kuo2Init, + dim2813Kuo2Init, + dim2814Kuo2Init, + dim2815Kuo2Init, + dim2816Kuo2Init, + dim2817Kuo2Init, + dim2818Kuo2Init, + dim2819Kuo2Init, + dim2820Kuo2Init, + dim2821Kuo2Init, + dim2822Kuo2Init, + dim2823Kuo2Init, + dim2824Kuo2Init, + dim2825Kuo2Init, + dim2826Kuo2Init, + dim2827Kuo2Init, + dim2828Kuo2Init, + dim2829Kuo2Init, + dim2830Kuo2Init, + dim2831Kuo2Init, + dim2832Kuo2Init, + dim2833Kuo2Init, + dim2834Kuo2Init, + dim2835Kuo2Init, + dim2836Kuo2Init, + dim2837Kuo2Init, + dim2838Kuo2Init, + dim2839Kuo2Init, + dim2840Kuo2Init, + dim2841Kuo2Init, + dim2842Kuo2Init, + dim2843Kuo2Init, + dim2844Kuo2Init, + dim2845Kuo2Init, + dim2846Kuo2Init, + dim2847Kuo2Init, + dim2848Kuo2Init, + dim2849Kuo2Init, + dim2850Kuo2Init, + dim2851Kuo2Init, + dim2852Kuo2Init, + dim2853Kuo2Init, + dim2854Kuo2Init, + dim2855Kuo2Init, + dim2856Kuo2Init, + dim2857Kuo2Init, + dim2858Kuo2Init, + dim2859Kuo2Init, + dim2860Kuo2Init, + dim2861Kuo2Init, + dim2862Kuo2Init, + dim2863Kuo2Init, + dim2864Kuo2Init, + dim2865Kuo2Init, + dim2866Kuo2Init, + dim2867Kuo2Init, + dim2868Kuo2Init, + dim2869Kuo2Init, + dim2870Kuo2Init, + dim2871Kuo2Init, + dim2872Kuo2Init, + dim2873Kuo2Init, + dim2874Kuo2Init, + dim2875Kuo2Init, + dim2876Kuo2Init, + dim2877Kuo2Init, + dim2878Kuo2Init, + dim2879Kuo2Init, + dim2880Kuo2Init, + dim2881Kuo2Init, + dim2882Kuo2Init, + dim2883Kuo2Init, + dim2884Kuo2Init, + dim2885Kuo2Init, + dim2886Kuo2Init, + dim2887Kuo2Init, + dim2888Kuo2Init, + dim2889Kuo2Init, + dim2890Kuo2Init, + dim2891Kuo2Init, + dim2892Kuo2Init, + dim2893Kuo2Init, + dim2894Kuo2Init, + dim2895Kuo2Init, + dim2896Kuo2Init, + dim2897Kuo2Init, + dim2898Kuo2Init, + dim2899Kuo2Init, + dim2900Kuo2Init, + dim2901Kuo2Init, + dim2902Kuo2Init, + dim2903Kuo2Init, + dim2904Kuo2Init, + dim2905Kuo2Init, + dim2906Kuo2Init, + dim2907Kuo2Init, + dim2908Kuo2Init, + dim2909Kuo2Init, + dim2910Kuo2Init, + dim2911Kuo2Init, + dim2912Kuo2Init, + dim2913Kuo2Init, + dim2914Kuo2Init, + dim2915Kuo2Init, + dim2916Kuo2Init, + dim2917Kuo2Init, + dim2918Kuo2Init, + dim2919Kuo2Init, + dim2920Kuo2Init, + dim2921Kuo2Init, + dim2922Kuo2Init, + dim2923Kuo2Init, + dim2924Kuo2Init, + dim2925Kuo2Init, + dim2926Kuo2Init, + dim2927Kuo2Init, + dim2928Kuo2Init, + dim2929Kuo2Init, + dim2930Kuo2Init, + dim2931Kuo2Init, + dim2932Kuo2Init, + dim2933Kuo2Init, + dim2934Kuo2Init, + dim2935Kuo2Init, + dim2936Kuo2Init, + dim2937Kuo2Init, + dim2938Kuo2Init, + dim2939Kuo2Init, + dim2940Kuo2Init, + dim2941Kuo2Init, + dim2942Kuo2Init, + dim2943Kuo2Init, + dim2944Kuo2Init, + dim2945Kuo2Init, + dim2946Kuo2Init, + dim2947Kuo2Init, + dim2948Kuo2Init, + dim2949Kuo2Init, + dim2950Kuo2Init, + dim2951Kuo2Init, + dim2952Kuo2Init, + dim2953Kuo2Init, + dim2954Kuo2Init, + dim2955Kuo2Init, + dim2956Kuo2Init, + dim2957Kuo2Init, + dim2958Kuo2Init, + dim2959Kuo2Init, + dim2960Kuo2Init, + dim2961Kuo2Init, + dim2962Kuo2Init, + dim2963Kuo2Init, + dim2964Kuo2Init, + dim2965Kuo2Init, + dim2966Kuo2Init, + dim2967Kuo2Init, + dim2968Kuo2Init, + dim2969Kuo2Init, + dim2970Kuo2Init, + dim2971Kuo2Init, + dim2972Kuo2Init, + dim2973Kuo2Init, + dim2974Kuo2Init, + dim2975Kuo2Init, + dim2976Kuo2Init, + dim2977Kuo2Init, + dim2978Kuo2Init, + dim2979Kuo2Init, + dim2980Kuo2Init, + dim2981Kuo2Init, + dim2982Kuo2Init, + dim2983Kuo2Init, + dim2984Kuo2Init, + dim2985Kuo2Init, + dim2986Kuo2Init, + dim2987Kuo2Init, + dim2988Kuo2Init, + dim2989Kuo2Init, + dim2990Kuo2Init, + dim2991Kuo2Init, + dim2992Kuo2Init, + dim2993Kuo2Init, + dim2994Kuo2Init, + dim2995Kuo2Init, + dim2996Kuo2Init, + dim2997Kuo2Init, + dim2998Kuo2Init, + dim2999Kuo2Init, + dim3000Kuo2Init, + dim3001Kuo2Init, + dim3002Kuo2Init, + dim3003Kuo2Init, + dim3004Kuo2Init, + dim3005Kuo2Init, + dim3006Kuo2Init, + dim3007Kuo2Init, + dim3008Kuo2Init, + dim3009Kuo2Init, + dim3010Kuo2Init, + dim3011Kuo2Init, + dim3012Kuo2Init, + dim3013Kuo2Init, + dim3014Kuo2Init, + dim3015Kuo2Init, + dim3016Kuo2Init, + dim3017Kuo2Init, + dim3018Kuo2Init, + dim3019Kuo2Init, + dim3020Kuo2Init, + dim3021Kuo2Init, + dim3022Kuo2Init, + dim3023Kuo2Init, + dim3024Kuo2Init, + dim3025Kuo2Init, + dim3026Kuo2Init, + dim3027Kuo2Init, + dim3028Kuo2Init, + dim3029Kuo2Init, + dim3030Kuo2Init, + dim3031Kuo2Init, + dim3032Kuo2Init, + dim3033Kuo2Init, + dim3034Kuo2Init, + dim3035Kuo2Init, + dim3036Kuo2Init, + dim3037Kuo2Init, + dim3038Kuo2Init, + dim3039Kuo2Init, + dim3040Kuo2Init, + dim3041Kuo2Init, + dim3042Kuo2Init, + dim3043Kuo2Init, + dim3044Kuo2Init, + dim3045Kuo2Init, + dim3046Kuo2Init, + dim3047Kuo2Init, + dim3048Kuo2Init, + dim3049Kuo2Init, + dim3050Kuo2Init, + dim3051Kuo2Init, + dim3052Kuo2Init, + dim3053Kuo2Init, + dim3054Kuo2Init, + dim3055Kuo2Init, + dim3056Kuo2Init, + dim3057Kuo2Init, + dim3058Kuo2Init, + dim3059Kuo2Init, + dim3060Kuo2Init, + dim3061Kuo2Init, + dim3062Kuo2Init, + dim3063Kuo2Init, + dim3064Kuo2Init, + dim3065Kuo2Init, + dim3066Kuo2Init, + dim3067Kuo2Init, + dim3068Kuo2Init, + dim3069Kuo2Init, + dim3070Kuo2Init, + dim3071Kuo2Init, + dim3072Kuo2Init, + dim3073Kuo2Init, + dim3074Kuo2Init, + dim3075Kuo2Init, + dim3076Kuo2Init, + dim3077Kuo2Init, + dim3078Kuo2Init, + dim3079Kuo2Init, + dim3080Kuo2Init, + dim3081Kuo2Init, + dim3082Kuo2Init, + dim3083Kuo2Init, + dim3084Kuo2Init, + dim3085Kuo2Init, + dim3086Kuo2Init, + dim3087Kuo2Init, + dim3088Kuo2Init, + dim3089Kuo2Init, + dim3090Kuo2Init, + dim3091Kuo2Init, + dim3092Kuo2Init, + dim3093Kuo2Init, + dim3094Kuo2Init, + dim3095Kuo2Init, + dim3096Kuo2Init, + dim3097Kuo2Init, + dim3098Kuo2Init, + dim3099Kuo2Init, + dim3100Kuo2Init, + dim3101Kuo2Init, + dim3102Kuo2Init, + dim3103Kuo2Init, + dim3104Kuo2Init, + dim3105Kuo2Init, + dim3106Kuo2Init, + dim3107Kuo2Init, + dim3108Kuo2Init, + dim3109Kuo2Init, + dim3110Kuo2Init, + dim3111Kuo2Init, + dim3112Kuo2Init, + dim3113Kuo2Init, + dim3114Kuo2Init, + dim3115Kuo2Init, + dim3116Kuo2Init, + dim3117Kuo2Init, + dim3118Kuo2Init, + dim3119Kuo2Init, + dim3120Kuo2Init, + dim3121Kuo2Init, + dim3122Kuo2Init, + dim3123Kuo2Init, + dim3124Kuo2Init, + dim3125Kuo2Init, + dim3126Kuo2Init, + dim3127Kuo2Init, + dim3128Kuo2Init, + dim3129Kuo2Init, + dim3130Kuo2Init, + dim3131Kuo2Init, + dim3132Kuo2Init, + dim3133Kuo2Init, + dim3134Kuo2Init, + dim3135Kuo2Init, + dim3136Kuo2Init, + dim3137Kuo2Init, + dim3138Kuo2Init, + dim3139Kuo2Init, + dim3140Kuo2Init, + dim3141Kuo2Init, + dim3142Kuo2Init, + dim3143Kuo2Init, + dim3144Kuo2Init, + dim3145Kuo2Init, + dim3146Kuo2Init, + dim3147Kuo2Init, + dim3148Kuo2Init, + dim3149Kuo2Init, + dim3150Kuo2Init, + dim3151Kuo2Init, + dim3152Kuo2Init, + dim3153Kuo2Init, + dim3154Kuo2Init, + dim3155Kuo2Init, + dim3156Kuo2Init, + dim3157Kuo2Init, + dim3158Kuo2Init, + dim3159Kuo2Init, + dim3160Kuo2Init, + dim3161Kuo2Init, + dim3162Kuo2Init, + dim3163Kuo2Init, + dim3164Kuo2Init, + dim3165Kuo2Init, + dim3166Kuo2Init, + dim3167Kuo2Init, + dim3168Kuo2Init, + dim3169Kuo2Init, + dim3170Kuo2Init, + dim3171Kuo2Init, + dim3172Kuo2Init, + dim3173Kuo2Init, + dim3174Kuo2Init, + dim3175Kuo2Init, + dim3176Kuo2Init, + dim3177Kuo2Init, + dim3178Kuo2Init, + dim3179Kuo2Init, + dim3180Kuo2Init, + dim3181Kuo2Init, + dim3182Kuo2Init, + dim3183Kuo2Init, + dim3184Kuo2Init, + dim3185Kuo2Init, + dim3186Kuo2Init, + dim3187Kuo2Init, + dim3188Kuo2Init, + dim3189Kuo2Init, + dim3190Kuo2Init, + dim3191Kuo2Init, + dim3192Kuo2Init, + dim3193Kuo2Init, + dim3194Kuo2Init, + dim3195Kuo2Init, + dim3196Kuo2Init, + dim3197Kuo2Init, + dim3198Kuo2Init, + dim3199Kuo2Init, + dim3200Kuo2Init, + dim3201Kuo2Init, + dim3202Kuo2Init, + dim3203Kuo2Init, + dim3204Kuo2Init, + dim3205Kuo2Init, + dim3206Kuo2Init, + dim3207Kuo2Init, + dim3208Kuo2Init, + dim3209Kuo2Init, + dim3210Kuo2Init, + dim3211Kuo2Init, + dim3212Kuo2Init, + dim3213Kuo2Init, + dim3214Kuo2Init, + dim3215Kuo2Init, + dim3216Kuo2Init, + dim3217Kuo2Init, + dim3218Kuo2Init, + dim3219Kuo2Init, + dim3220Kuo2Init, + dim3221Kuo2Init, + dim3222Kuo2Init, + dim3223Kuo2Init, + dim3224Kuo2Init, + dim3225Kuo2Init, + dim3226Kuo2Init, + dim3227Kuo2Init, + dim3228Kuo2Init, + dim3229Kuo2Init, + dim3230Kuo2Init, + dim3231Kuo2Init, + dim3232Kuo2Init, + dim3233Kuo2Init, + dim3234Kuo2Init, + dim3235Kuo2Init, + dim3236Kuo2Init, + dim3237Kuo2Init, + dim3238Kuo2Init, + dim3239Kuo2Init, + dim3240Kuo2Init, + dim3241Kuo2Init, + dim3242Kuo2Init, + dim3243Kuo2Init, + dim3244Kuo2Init, + dim3245Kuo2Init, + dim3246Kuo2Init, + dim3247Kuo2Init, + dim3248Kuo2Init, + dim3249Kuo2Init, + dim3250Kuo2Init, + dim3251Kuo2Init, + dim3252Kuo2Init, + dim3253Kuo2Init, + dim3254Kuo2Init, + dim3255Kuo2Init, + dim3256Kuo2Init, + dim3257Kuo2Init, + dim3258Kuo2Init, + dim3259Kuo2Init, + dim3260Kuo2Init, + dim3261Kuo2Init, + dim3262Kuo2Init, + dim3263Kuo2Init, + dim3264Kuo2Init, + dim3265Kuo2Init, + dim3266Kuo2Init, + dim3267Kuo2Init, + dim3268Kuo2Init, + dim3269Kuo2Init, + dim3270Kuo2Init, + dim3271Kuo2Init, + dim3272Kuo2Init, + dim3273Kuo2Init, + dim3274Kuo2Init, + dim3275Kuo2Init, + dim3276Kuo2Init, + dim3277Kuo2Init, + dim3278Kuo2Init, + dim3279Kuo2Init, + dim3280Kuo2Init, + dim3281Kuo2Init, + dim3282Kuo2Init, + dim3283Kuo2Init, + dim3284Kuo2Init, + dim3285Kuo2Init, + dim3286Kuo2Init, + dim3287Kuo2Init, + dim3288Kuo2Init, + dim3289Kuo2Init, + dim3290Kuo2Init, + dim3291Kuo2Init, + dim3292Kuo2Init, + dim3293Kuo2Init, + dim3294Kuo2Init, + dim3295Kuo2Init, + dim3296Kuo2Init, + dim3297Kuo2Init, + dim3298Kuo2Init, + dim3299Kuo2Init, + dim3300Kuo2Init, + dim3301Kuo2Init, + dim3302Kuo2Init, + dim3303Kuo2Init, + dim3304Kuo2Init, + dim3305Kuo2Init, + dim3306Kuo2Init, + dim3307Kuo2Init, + dim3308Kuo2Init, + dim3309Kuo2Init, + dim3310Kuo2Init, + dim3311Kuo2Init, + dim3312Kuo2Init, + dim3313Kuo2Init, + dim3314Kuo2Init, + dim3315Kuo2Init, + dim3316Kuo2Init, + dim3317Kuo2Init, + dim3318Kuo2Init, + dim3319Kuo2Init, + dim3320Kuo2Init, + dim3321Kuo2Init, + dim3322Kuo2Init, + dim3323Kuo2Init, + dim3324Kuo2Init, + dim3325Kuo2Init, + dim3326Kuo2Init, + dim3327Kuo2Init, + dim3328Kuo2Init, + dim3329Kuo2Init, + dim3330Kuo2Init, + dim3331Kuo2Init, + dim3332Kuo2Init, + dim3333Kuo2Init, + dim3334Kuo2Init, + dim3335Kuo2Init, + dim3336Kuo2Init, + dim3337Kuo2Init, + dim3338Kuo2Init, + dim3339Kuo2Init, + dim3340Kuo2Init, + dim3341Kuo2Init, + dim3342Kuo2Init, + dim3343Kuo2Init, + dim3344Kuo2Init, + dim3345Kuo2Init, + dim3346Kuo2Init, + dim3347Kuo2Init, + dim3348Kuo2Init, + dim3349Kuo2Init, + dim3350Kuo2Init, + dim3351Kuo2Init, + dim3352Kuo2Init, + dim3353Kuo2Init, + dim3354Kuo2Init, + dim3355Kuo2Init, + dim3356Kuo2Init, + dim3357Kuo2Init, + dim3358Kuo2Init, + dim3359Kuo2Init, + dim3360Kuo2Init, + dim3361Kuo2Init, + dim3362Kuo2Init, + dim3363Kuo2Init, + dim3364Kuo2Init, + dim3365Kuo2Init, + dim3366Kuo2Init, + dim3367Kuo2Init, + dim3368Kuo2Init, + dim3369Kuo2Init, + dim3370Kuo2Init, + dim3371Kuo2Init, + dim3372Kuo2Init, + dim3373Kuo2Init, + dim3374Kuo2Init, + dim3375Kuo2Init, + dim3376Kuo2Init, + dim3377Kuo2Init, + dim3378Kuo2Init, + dim3379Kuo2Init, + dim3380Kuo2Init, + dim3381Kuo2Init, + dim3382Kuo2Init, + dim3383Kuo2Init, + dim3384Kuo2Init, + dim3385Kuo2Init, + dim3386Kuo2Init, + dim3387Kuo2Init, + dim3388Kuo2Init, + dim3389Kuo2Init, + dim3390Kuo2Init, + dim3391Kuo2Init, + dim3392Kuo2Init, + dim3393Kuo2Init, + dim3394Kuo2Init, + dim3395Kuo2Init, + dim3396Kuo2Init, + dim3397Kuo2Init, + dim3398Kuo2Init, + dim3399Kuo2Init, + dim3400Kuo2Init, + dim3401Kuo2Init, + dim3402Kuo2Init, + dim3403Kuo2Init, + dim3404Kuo2Init, + dim3405Kuo2Init, + dim3406Kuo2Init, + dim3407Kuo2Init, + dim3408Kuo2Init, + dim3409Kuo2Init, + dim3410Kuo2Init, + dim3411Kuo2Init, + dim3412Kuo2Init, + dim3413Kuo2Init, + dim3414Kuo2Init, + dim3415Kuo2Init, + dim3416Kuo2Init, + dim3417Kuo2Init, + dim3418Kuo2Init, + dim3419Kuo2Init, + dim3420Kuo2Init, + dim3421Kuo2Init, + dim3422Kuo2Init, + dim3423Kuo2Init, + dim3424Kuo2Init, + dim3425Kuo2Init, + dim3426Kuo2Init, + dim3427Kuo2Init, + dim3428Kuo2Init, + dim3429Kuo2Init, + dim3430Kuo2Init, + dim3431Kuo2Init, + dim3432Kuo2Init, + dim3433Kuo2Init, + dim3434Kuo2Init, + dim3435Kuo2Init, + dim3436Kuo2Init, + dim3437Kuo2Init, + dim3438Kuo2Init, + dim3439Kuo2Init, + dim3440Kuo2Init, + dim3441Kuo2Init, + dim3442Kuo2Init, + dim3443Kuo2Init, + dim3444Kuo2Init, + dim3445Kuo2Init, + dim3446Kuo2Init, + dim3447Kuo2Init, + dim3448Kuo2Init, + dim3449Kuo2Init, + dim3450Kuo2Init, + dim3451Kuo2Init, + dim3452Kuo2Init, + dim3453Kuo2Init, + dim3454Kuo2Init, + dim3455Kuo2Init, + dim3456Kuo2Init, + dim3457Kuo2Init, + dim3458Kuo2Init, + dim3459Kuo2Init, + dim3460Kuo2Init, + dim3461Kuo2Init, + dim3462Kuo2Init, + dim3463Kuo2Init, + dim3464Kuo2Init, + dim3465Kuo2Init, + dim3466Kuo2Init, + dim3467Kuo2Init, + dim3468Kuo2Init, + dim3469Kuo2Init, + dim3470Kuo2Init, + dim3471Kuo2Init, + dim3472Kuo2Init, + dim3473Kuo2Init, + dim3474Kuo2Init, + dim3475Kuo2Init, + dim3476Kuo2Init, + dim3477Kuo2Init, + dim3478Kuo2Init, + dim3479Kuo2Init, + dim3480Kuo2Init, + dim3481Kuo2Init, + dim3482Kuo2Init, + dim3483Kuo2Init, + dim3484Kuo2Init, + dim3485Kuo2Init, + dim3486Kuo2Init, + dim3487Kuo2Init, + dim3488Kuo2Init, + dim3489Kuo2Init, + dim3490Kuo2Init, + dim3491Kuo2Init, + dim3492Kuo2Init, + dim3493Kuo2Init, + dim3494Kuo2Init, + dim3495Kuo2Init, + dim3496Kuo2Init, + dim3497Kuo2Init, + dim3498Kuo2Init, + dim3499Kuo2Init, + dim3500Kuo2Init, + dim3501Kuo2Init, + dim3502Kuo2Init, + dim3503Kuo2Init, + dim3504Kuo2Init, + dim3505Kuo2Init, + dim3506Kuo2Init, + dim3507Kuo2Init, + dim3508Kuo2Init, + dim3509Kuo2Init, + dim3510Kuo2Init, + dim3511Kuo2Init, + dim3512Kuo2Init, + dim3513Kuo2Init, + dim3514Kuo2Init, + dim3515Kuo2Init, + dim3516Kuo2Init, + dim3517Kuo2Init, + dim3518Kuo2Init, + dim3519Kuo2Init, + dim3520Kuo2Init, + dim3521Kuo2Init, + dim3522Kuo2Init, + dim3523Kuo2Init, + dim3524Kuo2Init, + dim3525Kuo2Init, + dim3526Kuo2Init, + dim3527Kuo2Init, + dim3528Kuo2Init, + dim3529Kuo2Init, + dim3530Kuo2Init, + dim3531Kuo2Init, + dim3532Kuo2Init, + dim3533Kuo2Init, + dim3534Kuo2Init, + dim3535Kuo2Init, + dim3536Kuo2Init, + dim3537Kuo2Init, + dim3538Kuo2Init, + dim3539Kuo2Init, + dim3540Kuo2Init, + dim3541Kuo2Init, + dim3542Kuo2Init, + dim3543Kuo2Init, + dim3544Kuo2Init, + dim3545Kuo2Init, + dim3546Kuo2Init, + dim3547Kuo2Init, + dim3548Kuo2Init, + dim3549Kuo2Init, + dim3550Kuo2Init, + dim3551Kuo2Init, + dim3552Kuo2Init, + dim3553Kuo2Init, + dim3554Kuo2Init, + dim3555Kuo2Init, + dim3556Kuo2Init, + dim3557Kuo2Init, + dim3558Kuo2Init, + dim3559Kuo2Init, + dim3560Kuo2Init, + dim3561Kuo2Init, + dim3562Kuo2Init, + dim3563Kuo2Init, + dim3564Kuo2Init, + dim3565Kuo2Init, + dim3566Kuo2Init, + dim3567Kuo2Init, + dim3568Kuo2Init, + dim3569Kuo2Init, + dim3570Kuo2Init, + dim3571Kuo2Init, + dim3572Kuo2Init, + dim3573Kuo2Init, + dim3574Kuo2Init, + dim3575Kuo2Init, + dim3576Kuo2Init, + dim3577Kuo2Init, + dim3578Kuo2Init, + dim3579Kuo2Init, + dim3580Kuo2Init, + dim3581Kuo2Init, + dim3582Kuo2Init, + dim3583Kuo2Init, + dim3584Kuo2Init, + dim3585Kuo2Init, + dim3586Kuo2Init, + dim3587Kuo2Init, + dim3588Kuo2Init, + dim3589Kuo2Init, + dim3590Kuo2Init, + dim3591Kuo2Init, + dim3592Kuo2Init, + dim3593Kuo2Init, + dim3594Kuo2Init, + dim3595Kuo2Init, + dim3596Kuo2Init, + dim3597Kuo2Init, + dim3598Kuo2Init, + dim3599Kuo2Init, + dim3600Kuo2Init, + dim3601Kuo2Init, + dim3602Kuo2Init, + dim3603Kuo2Init, + dim3604Kuo2Init, + dim3605Kuo2Init, + dim3606Kuo2Init, + dim3607Kuo2Init, + dim3608Kuo2Init, + dim3609Kuo2Init, + dim3610Kuo2Init, + dim3611Kuo2Init, + dim3612Kuo2Init, + dim3613Kuo2Init, + dim3614Kuo2Init, + dim3615Kuo2Init, + dim3616Kuo2Init, + dim3617Kuo2Init, + dim3618Kuo2Init, + dim3619Kuo2Init, + dim3620Kuo2Init, + dim3621Kuo2Init, + dim3622Kuo2Init, + dim3623Kuo2Init, + dim3624Kuo2Init, + dim3625Kuo2Init, + dim3626Kuo2Init, + dim3627Kuo2Init, + dim3628Kuo2Init, + dim3629Kuo2Init, + dim3630Kuo2Init, + dim3631Kuo2Init, + dim3632Kuo2Init, + dim3633Kuo2Init, + dim3634Kuo2Init, + dim3635Kuo2Init, + dim3636Kuo2Init, + dim3637Kuo2Init, + dim3638Kuo2Init, + dim3639Kuo2Init, + dim3640Kuo2Init, + dim3641Kuo2Init, + dim3642Kuo2Init, + dim3643Kuo2Init, + dim3644Kuo2Init, + dim3645Kuo2Init, + dim3646Kuo2Init, + dim3647Kuo2Init, + dim3648Kuo2Init, + dim3649Kuo2Init, + dim3650Kuo2Init, + dim3651Kuo2Init, + dim3652Kuo2Init, + dim3653Kuo2Init, + dim3654Kuo2Init, + dim3655Kuo2Init, + dim3656Kuo2Init, + dim3657Kuo2Init, + dim3658Kuo2Init, + dim3659Kuo2Init, + dim3660Kuo2Init, + dim3661Kuo2Init, + dim3662Kuo2Init, + dim3663Kuo2Init, + dim3664Kuo2Init, + dim3665Kuo2Init, + dim3666Kuo2Init, + dim3667Kuo2Init, + dim3668Kuo2Init, + dim3669Kuo2Init, + dim3670Kuo2Init, + dim3671Kuo2Init, + dim3672Kuo2Init, + dim3673Kuo2Init, + dim3674Kuo2Init, + dim3675Kuo2Init, + dim3676Kuo2Init, + dim3677Kuo2Init, + dim3678Kuo2Init, + dim3679Kuo2Init, + dim3680Kuo2Init, + dim3681Kuo2Init, + dim3682Kuo2Init, + dim3683Kuo2Init, + dim3684Kuo2Init, + dim3685Kuo2Init, + dim3686Kuo2Init, + dim3687Kuo2Init, + dim3688Kuo2Init, + dim3689Kuo2Init, + dim3690Kuo2Init, + dim3691Kuo2Init, + dim3692Kuo2Init, + dim3693Kuo2Init, + dim3694Kuo2Init, + dim3695Kuo2Init, + dim3696Kuo2Init, + dim3697Kuo2Init, + dim3698Kuo2Init, + dim3699Kuo2Init, + dim3700Kuo2Init, + dim3701Kuo2Init, + dim3702Kuo2Init, + dim3703Kuo2Init, + dim3704Kuo2Init, + dim3705Kuo2Init, + dim3706Kuo2Init, + dim3707Kuo2Init, + dim3708Kuo2Init, + dim3709Kuo2Init, + dim3710Kuo2Init, + dim3711Kuo2Init, + dim3712Kuo2Init, + dim3713Kuo2Init, + dim3714Kuo2Init, + dim3715Kuo2Init, + dim3716Kuo2Init, + dim3717Kuo2Init, + dim3718Kuo2Init, + dim3719Kuo2Init, + dim3720Kuo2Init, + dim3721Kuo2Init, + dim3722Kuo2Init, + dim3723Kuo2Init, + dim3724Kuo2Init, + dim3725Kuo2Init, + dim3726Kuo2Init, + dim3727Kuo2Init, + dim3728Kuo2Init, + dim3729Kuo2Init, + dim3730Kuo2Init, + dim3731Kuo2Init, + dim3732Kuo2Init, + dim3733Kuo2Init, + dim3734Kuo2Init, + dim3735Kuo2Init, + dim3736Kuo2Init, + dim3737Kuo2Init, + dim3738Kuo2Init, + dim3739Kuo2Init, + dim3740Kuo2Init, + dim3741Kuo2Init, + dim3742Kuo2Init, + dim3743Kuo2Init, + dim3744Kuo2Init, + dim3745Kuo2Init, + dim3746Kuo2Init, + dim3747Kuo2Init, + dim3748Kuo2Init, + dim3749Kuo2Init, + dim3750Kuo2Init, + dim3751Kuo2Init, + dim3752Kuo2Init, + dim3753Kuo2Init, + dim3754Kuo2Init, + dim3755Kuo2Init, + dim3756Kuo2Init, + dim3757Kuo2Init, + dim3758Kuo2Init, + dim3759Kuo2Init, + dim3760Kuo2Init, + dim3761Kuo2Init, + dim3762Kuo2Init, + dim3763Kuo2Init, + dim3764Kuo2Init, + dim3765Kuo2Init, + dim3766Kuo2Init, + dim3767Kuo2Init, + dim3768Kuo2Init, + dim3769Kuo2Init, + dim3770Kuo2Init, + dim3771Kuo2Init, + dim3772Kuo2Init, + dim3773Kuo2Init, + dim3774Kuo2Init, + dim3775Kuo2Init, + dim3776Kuo2Init, + dim3777Kuo2Init, + dim3778Kuo2Init, + dim3779Kuo2Init, + dim3780Kuo2Init, + dim3781Kuo2Init, + dim3782Kuo2Init, + dim3783Kuo2Init, + dim3784Kuo2Init, + dim3785Kuo2Init, + dim3786Kuo2Init, + dim3787Kuo2Init, + dim3788Kuo2Init, + dim3789Kuo2Init, + dim3790Kuo2Init, + dim3791Kuo2Init, + dim3792Kuo2Init, + dim3793Kuo2Init, + dim3794Kuo2Init, + dim3795Kuo2Init, + dim3796Kuo2Init, + dim3797Kuo2Init, + dim3798Kuo2Init, + dim3799Kuo2Init, + dim3800Kuo2Init, + dim3801Kuo2Init, + dim3802Kuo2Init, + dim3803Kuo2Init, + dim3804Kuo2Init, + dim3805Kuo2Init, + dim3806Kuo2Init, + dim3807Kuo2Init, + dim3808Kuo2Init, + dim3809Kuo2Init, + dim3810Kuo2Init, + dim3811Kuo2Init, + dim3812Kuo2Init, + dim3813Kuo2Init, + dim3814Kuo2Init, + dim3815Kuo2Init, + dim3816Kuo2Init, + dim3817Kuo2Init, + dim3818Kuo2Init, + dim3819Kuo2Init, + dim3820Kuo2Init, + dim3821Kuo2Init, + dim3822Kuo2Init, + dim3823Kuo2Init, + dim3824Kuo2Init, + dim3825Kuo2Init, + dim3826Kuo2Init, + dim3827Kuo2Init, + dim3828Kuo2Init, + dim3829Kuo2Init, + dim3830Kuo2Init, + dim3831Kuo2Init, + dim3832Kuo2Init, + dim3833Kuo2Init, + dim3834Kuo2Init, + dim3835Kuo2Init, + dim3836Kuo2Init, + dim3837Kuo2Init, + dim3838Kuo2Init, + dim3839Kuo2Init, + dim3840Kuo2Init, + dim3841Kuo2Init, + dim3842Kuo2Init, + dim3843Kuo2Init, + dim3844Kuo2Init, + dim3845Kuo2Init, + dim3846Kuo2Init, + dim3847Kuo2Init, + dim3848Kuo2Init, + dim3849Kuo2Init, + dim3850Kuo2Init, + dim3851Kuo2Init, + dim3852Kuo2Init, + dim3853Kuo2Init, + dim3854Kuo2Init, + dim3855Kuo2Init, + dim3856Kuo2Init, + dim3857Kuo2Init, + dim3858Kuo2Init, + dim3859Kuo2Init, + dim3860Kuo2Init, + dim3861Kuo2Init, + dim3862Kuo2Init, + dim3863Kuo2Init, + dim3864Kuo2Init, + dim3865Kuo2Init, + dim3866Kuo2Init, + dim3867Kuo2Init, + dim3868Kuo2Init, + dim3869Kuo2Init, + dim3870Kuo2Init, + dim3871Kuo2Init, + dim3872Kuo2Init, + dim3873Kuo2Init, + dim3874Kuo2Init, + dim3875Kuo2Init, + dim3876Kuo2Init, + dim3877Kuo2Init, + dim3878Kuo2Init, + dim3879Kuo2Init, + dim3880Kuo2Init, + dim3881Kuo2Init, + dim3882Kuo2Init, + dim3883Kuo2Init, + dim3884Kuo2Init, + dim3885Kuo2Init, + dim3886Kuo2Init, + dim3887Kuo2Init, + dim3888Kuo2Init, + dim3889Kuo2Init, + dim3890Kuo2Init, + dim3891Kuo2Init, + dim3892Kuo2Init, + dim3893Kuo2Init, + dim3894Kuo2Init, + dim3895Kuo2Init, + dim3896Kuo2Init, + dim3897Kuo2Init, + dim3898Kuo2Init, + dim3899Kuo2Init, + dim3900Kuo2Init, + dim3901Kuo2Init, + dim3902Kuo2Init, + dim3903Kuo2Init, + dim3904Kuo2Init, + dim3905Kuo2Init, + dim3906Kuo2Init, + dim3907Kuo2Init, + dim3908Kuo2Init, + dim3909Kuo2Init, + dim3910Kuo2Init, + dim3911Kuo2Init, + dim3912Kuo2Init, + dim3913Kuo2Init, + dim3914Kuo2Init, + dim3915Kuo2Init, + dim3916Kuo2Init, + dim3917Kuo2Init, + dim3918Kuo2Init, + dim3919Kuo2Init, + dim3920Kuo2Init, + dim3921Kuo2Init, + dim3922Kuo2Init, + dim3923Kuo2Init, + dim3924Kuo2Init, + dim3925Kuo2Init, + dim3926Kuo2Init, + dim3927Kuo2Init, + dim3928Kuo2Init, + dim3929Kuo2Init, + dim3930Kuo2Init, + dim3931Kuo2Init, + dim3932Kuo2Init, + dim3933Kuo2Init, + dim3934Kuo2Init, + dim3935Kuo2Init, + dim3936Kuo2Init, + dim3937Kuo2Init, + dim3938Kuo2Init, + dim3939Kuo2Init, + dim3940Kuo2Init, + dim3941Kuo2Init, + dim3942Kuo2Init, + dim3943Kuo2Init, + dim3944Kuo2Init, + dim3945Kuo2Init, + dim3946Kuo2Init, + }; + } + +#endif + +} diff --git a/src/QLNet/Math/randomnumbers/primitivepolynomials.cs b/src/QLNet/Math/randomnumbers/primitivepolynomials.cs deleted file mode 100644 index 3e096461f..000000000 --- a/src/QLNet/Math/randomnumbers/primitivepolynomials.cs +++ /dev/null @@ -1,21485 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -namespace QLNet { -/* this file is a slightly edited version of - * PrimitivePolynomialsModuloTwoUpToDegree27.h - * © 2002 "Monte Carlo Methods in Finance" - * as provided ready for compilation in the directory - * "PrimitivePolynomialsModuloTwo" on the CD accompanying the book - * "Monte Carlo Methods in Finance" by Peter Jдckel. - * - * =========================================================================== - * NOTE: The following copyright notice applies to the original code, - * - * Copyright (C) 2002 Peter Jдckel "Monte Carlo Methods in Finance". - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software is freely - * granted, provided that this notice is preserved. - * =========================================================================== - */ - -/* This file is provided for the use with Sobol' sequences of higher - * dimensions. The dimensionality of the Sobol' sequence can be extended to - * virtually any size you ever might need by the aid of the table of - * primitive polynomials modulo two. - * It is up to you to define a macro PPMT_MAX_DIM to a positive integer - * less than or equal to 8129334. If you don't define it, it will be set - * below to N_PRIMITIVES_UP_TO_DEGREE_18 which is 21200. That's how many - * primitive polynomials are provided by the standard primitivepolynomial.c - * distributed with QuantLib and that will be compiled into a static array. - * Should you need more, get the original version of primitivepolynomial.c - * as provided ready for compilation in the directory - * "PrimitivePolynomialsModuloTwo" on the CD accompanying the book - * "Monte Carlo Methods in Finance" by Peter Jдckel. - * The file provides polynomials up to degree 27 - * for a grand total of 8129334 dimensions. - * Since 8129334 longs compile into an object file of at least 32517336 byte - * size (in fact, gcc -c -O0 PrimitivePolynomialsModuloTwoUpToDegree27.c - * produced a file PrimitivePolynomialsModuloTwoUpToDegree27.o with 32519920 - * bytes), it is recommended to only compile as many as you may ever need. - * Worse even than the output file size is the virtual memory requirement - * for the compilation. For Visual C++ 6 you will need to use the /Zm compiler - * option to set the compiler's memory allocation limit (/Zm1500 should work) - * So really only take the maximum of what you think you might ever need. - * After all, you can always recompile with more, should you need it. - */ - -/* PPMT : Primitive Polynomials Modulo Two - * - * - * The encoding is as follows: - * - * The coefficients of each primitive polynomial are the bits of the given - * integer. The leading and trailing coefficients, which are 1 for all of the - * polynomials, have been omitted. - * - * Example: The polynomial - * - * 4 2 - * x + x + 1 - * - * is encoded as 2 in the array of polynomials of degree 4 because the - * binary sequence of coefficients - * - * 10101 - * - * becomes - * - * 0101 - * - * after stripping off the top bit, and this is converted to - * - * 010 - * - * by right-shifting and losing the rightmost bit. Similarly, we have - * - * 5 4 2 - * x + x + x + x + 1 - * - * encoded as 13 [ (1)1101(1) ] in the array for degree 5. - */ - -/* Example: replace primitivepolynomials.c provided by QuantLib standard - * distribution with the 8129334 polinomials version and - * comment out the line below if you want absolutely all of the - * provided primitive polynomials modulo two. - * - * #define PPMT_MAX_DIM 8129334 - * - * Note that PPMT_MAX_DIM will be redefined to be the nearest equal or larger - * number of polynomials up to one of the predefined macros - * N_PRIMITIVES_UP_TO_DEGREE_XX - * below. - */ - - #if NOPOLY - public partial class SobolRsg - { - public const long PPMT_MAX_DIM = 0; - public const int N_MAX_DEGREE = 0; - - public static long[][] PrimitivePolynomials; - } - -#else - - public partial class SobolRsg { - - public const long PPMT_MAX_DIM = 21200; - public const int N_MAX_DEGREE = 18; - - static long[] PrimitivePolynomialDegree01 = { - 0, /* x+1 (1)(1) */ - -1 }; - - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_01 - static long[] PrimitivePolynomialDegree02 = { - 1, /* x^2+x+1 (1)1(1) */ - -1 }; - ////#endif - - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_02 - static long[] PrimitivePolynomialDegree03 = { - 1, /* x^3 +x+1 (1)01(1) */ - 2, /* x^3+x^2 +1 (1)10(1) */ - -1 }; - ////#endif - - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_03 - static long[] PrimitivePolynomialDegree04 = { - 1, /* x^4+ +x+1 (1)001(1) */ - 4, /* x^4+x^3+ +1 (1)100(1) */ - -1 }; - ////#endif - - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_04 - static long[] PrimitivePolynomialDegree05 = { - 2, /* x^5 +x^2 +1 (1)0010(1) */ - 4, /* x^5 +x^3 +1 (1)0100(1) */ - 7, /* x^5 +x^3+x^2+x+1 (1)0111(1) */ - 11, /* x^5+x^4 +x^2+x+1 (1)1011(1) */ - 13, /* x^5+x^4+x^3 +x+1 (1)1101(1) */ - 14, /* x^5+x^4+x^3+x^2 +1 (1)1110(1) */ - -1 }; - ////#endif - - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_05 - static long[] PrimitivePolynomialDegree06 = { - 1, /* x^6 +x+1 (1)00001(1) */ - 13, /* x^6 +x^4+x^3 +x+1 (1)01101(1) */ - 16, /* x^6+x^5 +1 (1)10000(1) */ - 19, /* x^6 +x^2+x+1 (1)10011(1) */ - 22, /* x^6+x^5 +x^3+x^2 +1 (1)10110(1) */ - 25, /* x^6+x^5+x^4 +x+1 (1)11001(1) */ - -1 }; - //#endif - - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_06 - static long[] PrimitivePolynomialDegree07 = { - 1, /* x^7 +x+1 (1)000001(1) */ - 4, /* x^7 +x^3 +1 (1)000100(1) */ - 7, /* x^7 +x^3+x^2+x+1 (1)000111(1) */ - 8, /* x^7 +x^4 +1 (1)001000(1) */ - 14, /* x^7 +x^4+x^3+x^2 +1 (1)001110(1) */ - 19, /* x^7 +x^5 +x^2+x+1 (1)010011(1) */ - 21, /* x^7 +x^5 +x^3 +x+1 (1)010101(1) */ - 28, /* x^7 +x^5+x^4+x^3 +1 (1)011100(1) */ - 31, /* x^7 +x^5+x^4+x^3+x^2+x+1 (1)011111(1) */ - 32, /* x^7+x^6 +1 (1)100000(1) */ - 37, /* x^7+x^6 +x^3 +x+1 (1)100101(1) */ - 41, /* x^7+x^6 +x^4 +x+1 (1)101001(1) */ - 42, /* x^7+x^6 +x^4 +x^2 +1 (1)101010(1) */ - /* 32 polynomials so far ... let's go ahead */ - 50, /* x^7+x^6+x^5 +x^2 +1 (1)110010(1) */ - 55, /* x^7+x^6+x^5 +x^3+x^2+x+1 (1)110111(1) */ - 56, /* x^7+x^6+x^5+x^4 +1 (1)111000(1) */ - 59, /* x^7+x^6+x^5+x^4 +x^2+x+1 (1)111011(1) */ - 62, /* x^7+x^6+x^5+x^4+x^3+x^2 +1 (1)111110(1) */ - -1 }; - //#endif - - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_07 - static long[] PrimitivePolynomialDegree08 = { - 14, - 21, - 22, - 38, - 47, - 49, - 50, - 52, - 56, - 67, - 70, - 84, - 97, - 103, - 115, - 122, - -1 }; - //#endif - - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_08 - static long[] PrimitivePolynomialDegree09 = { - 8, - 13, - 16, - 22, - 25, - 44, - 47, - 52, - 55, - 59, - 62, - 67, - 74, - 81, - 82, - 87, - 91, - 94, - 103, - 104, - 109, - 122, - 124, - 137, - 138, - 143, - 145, - 152, - 157, - 167, - 173, - 176, - 181, - 182, - 185, - 191, - 194, - 199, - 218, - 220, - 227, - 229, - 230, - 234, - 236, - 241, - 244, - 253, - -1 }; - //#endif - - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_09 - static long[] PrimitivePolynomialDegree10 = { - 4, - 13, - 19, - 22, - 50, - 55, - 64, - 69, - 98, - 107, - 115, - 121, - 127, - 134, - 140, - 145, - 152, - 158, - 161, - 171, - 181, - 194, - 199, - 203, - 208, - 227, - 242, - 251, - 253, - 265, - 266, - 274, - 283, - 289, - 295, - 301, - 316, - 319, - 324, - 346, - 352, - 361, - 367, - 382, - 395, - 398, - 400, - 412, - 419, - 422, - 426, - 428, - 433, - 446, - 454, - 457, - 472, - 493, - 505, - 508, - -1 }; - //#endif - - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_10 - static long[] PrimitivePolynomialDegree11 = { - 2, - 11, - 21, - 22, - 35, - 49, - 50, - 56, - 61, - 70, - 74, - 79, - 84, - 88, - 103, - 104, - 112, - 115, - 117, - 122, - 134, - 137, - 146, - 148, - 157, - 158, - 162, - 164, - 168, - 173, - 185, - 186, - 191, - 193, - 199, - 213, - 214, - 220, - 227, - 236, - 242, - 251, - 256, - 259, - 265, - 266, - 276, - 292, - 304, - 310, - 316, - 319, - 322, - 328, - 334, - 339, - 341, - 345, - 346, - 362, - 367, - 372, - 375, - 376, - 381, - 385, - 388, - 392, - 409, - 415, - 416, - 421, - 428, - 431, - 434, - 439, - 446, - 451, - 453, - 457, - 458, - 471, - 475, - 478, - 484, - 493, - 494, - 499, - 502, - 517, - 518, - 524, - 527, - 555, - 560, - 565, - 569, - 578, - 580, - 587, - 589, - 590, - 601, - 607, - 611, - 614, - 617, - 618, - 625, - 628, - 635, - 641, - 647, - 654, - 659, - 662, - 672, - 675, - 682, - 684, - 689, - 695, - 696, - 713, - 719, - 724, - 733, - 734, - 740, - 747, - 749, - 752, - 755, - 762, - 770, - 782, - 784, - 787, - 789, - 793, - 796, - 803, - 805, - 810, - 815, - 824, - 829, - 830, - 832, - 841, - 847, - 849, - 861, - 871, - 878, - 889, - 892, - 901, - 908, - 920, - 923, - 942, - 949, - 950, - 954, - 961, - 968, - 971, - 973, - 979, - 982, - 986, - 998, - 1001, - 1010, - 1012, - -1 }; - //#endif - - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_11 - static long[] PrimitivePolynomialDegree12 = { - 41, - 52, - 61, - 62, - 76, - 104, - 117, - 131, - 143, - 145, - 157, - 167, - 171, - 176, - 181, - 194, - 217, - 236, - 239, - 262, - 283, - 286, - 307, - 313, - 319, - 348, - 352, - 357, - 391, - 398, - 400, - 412, - 415, - 422, - 440, - 460, - 465, - 468, - 515, - 536, - 539, - 551, - 558, - 563, - 570, - 595, - 598, - 617, - 647, - 654, - 678, - 713, - 738, - 747, - 750, - 757, - 772, - 803, - 810, - 812, - 850, - 862, - 906, - 908, - 929, - 930, - 954, - 964, - 982, - 985, - 991, - 992, - 1067, - 1070, - 1096, - 1099, - 1116, - 1143, - 1165, - 1178, - 1184, - 1202, - 1213, - 1221, - 1240, - 1246, - 1252, - 1255, - 1267, - 1293, - 1301, - 1305, - 1332, - 1349, - 1384, - 1392, - 1402, - 1413, - 1417, - 1423, - 1451, - 1480, - 1491, - 1503, - 1504, - 1513, - 1538, - 1544, - 1547, - 1555, - 1574, - 1603, - 1615, - 1618, - 1629, - 1634, - 1636, - 1639, - 1657, - 1667, - 1681, - 1697, - 1704, - 1709, - 1722, - 1730, - 1732, - 1802, - 1804, - 1815, - 1826, - 1832, - 1843, - 1849, - 1863, - 1905, - 1928, - 1933, - 1939, - 1976, - 1996, - 2013, - 2014, - 2020, - -1 }; - //#endif - - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_12 - static long[] PrimitivePolynomialDegree13 = { - 13, - 19, - 26, - 41, - 50, - 55, - 69, - 70, - 79, - 82, - 87, - 93, - 94, - 97, - 100, - 112, - 121, - 134, - 138, - 148, - 151, - 157, - 161, - 179, - 181, - 188, - 196, - 203, - 206, - 223, - 224, - 227, - 230, - 239, - 241, - 248, - 253, - 268, - 274, - 283, - 286, - 289, - 301, - 302, - 316, - 319, - 324, - 331, - 333, - 345, - 351, - 358, - 375, - 379, - 381, - 386, - 403, - 405, - 419, - 426, - 428, - 439, - 440, - 446, - 451, - 454, - 458, - 465, - 468, - 472, - 475, - 477, - 496, - 502, - 508, - 517, - 521, - 527, - 530, - 532, - 542, - 552, - 555, - 560, - 566, - 575, - 577, - 589, - 590, - 602, - 607, - 608, - 611, - 613, - 625, - 644, - 651, - 654, - 656, - 662, - 668, - 681, - 682, - 689, - 696, - 699, - 707, - 709, - 714, - 716, - 719, - 727, - 734, - 738, - 743, - 747, - 757, - 769, - 770, - 776, - 790, - 799, - 805, - 809, - 812, - 820, - 827, - 829, - 835, - 841, - 844, - 856, - 859, - 862, - 865, - 885, - 890, - 905, - 916, - 925, - 935, - 939, - 942, - 949, - 953, - 956, - 961, - 968, - 976, - 988, - 995, - 997, - 1007, - 1015, - 1016, - 1027, - 1036, - 1039, - 1041, - 1048, - 1053, - 1054, - 1058, - 1075, - 1082, - 1090, - 1109, - 1110, - 1119, - 1126, - 1130, - 1135, - 1137, - 1140, - 1149, - 1156, - 1159, - 1160, - 1165, - 1173, - 1178, - 1183, - 1184, - 1189, - 1194, - 1211, - 1214, - 1216, - 1225, - 1231, - 1239, - 1243, - 1246, - 1249, - 1259, - 1273, - 1274, - 1281, - 1287, - 1294, - 1296, - 1305, - 1306, - 1318, - 1332, - 1335, - 1336, - 1341, - 1342, - 1362, - 1364, - 1368, - 1378, - 1387, - 1389, - 1397, - 1401, - 1408, - 1418, - 1425, - 1426, - 1431, - 1435, - 1441, - 1444, - 1462, - 1471, - 1474, - 1483, - 1485, - 1494, - 1497, - 1516, - 1522, - 1534, - 1543, - 1552, - 1557, - 1558, - 1567, - 1568, - 1574, - 1592, - 1605, - 1606, - 1610, - 1617, - 1623, - 1630, - 1634, - 1640, - 1643, - 1648, - 1651, - 1653, - 1670, - 1676, - 1684, - 1687, - 1691, - 1693, - 1698, - 1709, - 1715, - 1722, - 1732, - 1735, - 1747, - 1749, - 1754, - 1777, - 1784, - 1790, - 1795, - 1801, - 1802, - 1812, - 1828, - 1831, - 1837, - 1838, - 1840, - 1845, - 1863, - 1864, - 1867, - 1870, - 1877, - 1881, - 1884, - 1903, - 1917, - 1918, - 1922, - 1924, - 1928, - 1931, - 1951, - 1952, - 1957, - 1958, - 1964, - 1967, - 1970, - 1972, - 1994, - 2002, - 2007, - 2008, - 2023, - 2030, - 2035, - 2038, - 2042, - 2047, - 2051, - 2058, - 2060, - 2071, - 2084, - 2087, - 2099, - 2108, - 2111, - 2120, - 2128, - 2138, - 2143, - 2144, - 2153, - 2156, - 2162, - 2167, - 2178, - 2183, - 2202, - 2211, - 2214, - 2223, - 2225, - 2232, - 2237, - 2257, - 2260, - 2267, - 2274, - 2276, - 2285, - 2288, - 2293, - 2294, - 2297, - 2303, - 2308, - 2311, - 2318, - 2323, - 2332, - 2341, - 2345, - 2348, - 2354, - 2368, - 2377, - 2380, - 2383, - 2388, - 2395, - 2397, - 2401, - 2411, - 2413, - 2419, - 2435, - 2442, - 2455, - 2472, - 2478, - 2490, - 2507, - 2509, - 2517, - 2524, - 2528, - 2531, - 2538, - 2545, - 2546, - 2555, - 2557, - 2564, - 2573, - 2579, - 2592, - 2598, - 2607, - 2612, - 2619, - 2621, - 2627, - 2633, - 2636, - 2642, - 2654, - 2660, - 2669, - 2675, - 2684, - 2694, - 2703, - 2706, - 2712, - 2715, - 2722, - 2727, - 2734, - 2742, - 2745, - 2751, - 2766, - 2768, - 2780, - 2790, - 2794, - 2796, - 2801, - 2804, - 2807, - 2816, - 2821, - 2831, - 2834, - 2839, - 2845, - 2852, - 2856, - 2861, - 2873, - 2874, - 2888, - 2893, - 2894, - 2902, - 2917, - 2921, - 2922, - 2929, - 2935, - 2946, - 2951, - 2957, - 2960, - 2966, - 2972, - 2976, - 2979, - 2985, - 3000, - 3003, - 3013, - 3018, - 3020, - 3025, - 3042, - 3047, - 3048, - 3051, - 3054, - 3056, - 3065, - 3073, - 3074, - 3083, - 3086, - 3091, - 3097, - 3109, - 3116, - 3124, - 3128, - 3153, - 3160, - 3165, - 3172, - 3175, - 3184, - 3193, - 3196, - 3200, - 3203, - 3205, - 3209, - 3224, - 3239, - 3251, - 3254, - 3265, - 3266, - 3275, - 3280, - 3283, - 3286, - 3301, - 3302, - 3305, - 3319, - 3323, - 3326, - 3331, - 3348, - 3351, - 3358, - 3368, - 3374, - 3376, - 3379, - 3385, - 3386, - 3396, - 3420, - 3423, - 3430, - 3433, - 3434, - 3439, - 3442, - 3444, - 3453, - 3464, - 3477, - 3478, - 3482, - 3487, - 3497, - 3500, - 3505, - 3506, - 3511, - 3512, - 3515, - 3525, - 3532, - 3538, - 3540, - 3547, - 3549, - 3560, - 3571, - 3577, - 3583, - 3590, - 3593, - 3594, - 3599, - 3601, - 3602, - 3613, - 3623, - 3630, - 3638, - 3649, - 3655, - 3662, - 3667, - 3669, - 3676, - 3683, - 3700, - 3709, - 3710, - 3713, - 3723, - 3725, - 3728, - 3734, - 3737, - 3738, - 3744, - 3750, - 3762, - 3764, - 3774, - 3776, - 3786, - 3800, - 3803, - 3809, - 3816, - 3821, - 3827, - 3829, - 3836, - 3842, - 3844, - 3847, - 3853, - 3861, - 3871, - 3872, - 3881, - 3890, - 3892, - 3909, - 3921, - 3934, - 3938, - 3947, - 3950, - 3952, - 3964, - 3974, - 3980, - 3983, - 3986, - 3995, - 3998, - 4001, - 4002, - 4004, - 4008, - 4011, - 4016, - 4033, - 4036, - 4040, - 4053, - 4058, - 4081, - 4091, - 4094, - -1 }; - //#endif - - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_13 - static long[] PrimitivePolynomialDegree14 = { - 21, - 28, - 41, - 47, - 61, - 84, - 87, - 93, - 94, - 103, - 117, - 121, - 134, - 137, - 157, - 161, - 205, - 206, - 211, - 214, - 218, - 234, - 236, - 248, - 262, - 299, - 304, - 319, - 322, - 334, - 355, - 357, - 358, - 369, - 372, - 375, - 388, - 400, - 415, - 446, - 451, - 458, - 471, - 484, - 501, - 502, - 517, - 545, - 569, - 617, - 618, - 623, - 625, - 637, - 661, - 668, - 684, - 695, - 716, - 719, - 722, - 731, - 738, - 747, - 755, - 761, - 767, - 775, - 782, - 787, - 794, - 803, - 812, - 817, - 824, - 829, - 850, - 866, - 871, - 877, - 920, - 935, - 959, - 979, - 992, - 1010, - 1012, - 1015, - 1033, - 1036, - 1053, - 1057, - 1069, - 1072, - 1075, - 1087, - 1089, - 1137, - 1166, - 1174, - 1180, - 1204, - 1211, - 1219, - 1236, - 1255, - 1264, - 1306, - 1330, - 1341, - 1344, - 1347, - 1349, - 1361, - 1380, - 1390, - 1404, - 1435, - 1444, - 1453, - 1461, - 1462, - 1465, - 1468, - 1474, - 1483, - 1488, - 1493, - 1500, - 1509, - 1510, - 1514, - 1519, - 1528, - 1533, - 1540, - 1550, - 1567, - 1571, - 1573, - 1578, - 1598, - 1606, - 1618, - 1630, - 1634, - 1640, - 1643, - 1654, - 1679, - 1688, - 1698, - 1703, - 1704, - 1722, - 1735, - 1750, - 1753, - 1760, - 1789, - 1792, - 1802, - 1819, - 1825, - 1828, - 1832, - 1845, - 1846, - 1857, - 1869, - 1897, - 1906, - 1908, - 1911, - 1934, - 1962, - 1967, - 1972, - 1975, - 1999, - 2004, - 2011, - 2013, - 2037, - 2051, - 2063, - 2066, - 2094, - 2128, - 2154, - 2164, - 2198, - 2217, - 2220, - 2223, - 2238, - 2245, - 2252, - 2258, - 2264, - 2280, - 2285, - 2293, - 2294, - 2298, - 2303, - 2306, - 2311, - 2326, - 2354, - 2373, - 2380, - 2385, - 2392, - 2401, - 2402, - 2408, - 2419, - 2450, - 2452, - 2477, - 2509, - 2510, - 2515, - 2524, - 2527, - 2531, - 2552, - 2561, - 2567, - 2571, - 2586, - 2588, - 2595, - 2607, - 2621, - 2630, - 2639, - 2653, - 2670, - 2672, - 2700, - 2711, - 2715, - 2748, - 2751, - 2753, - 2754, - 2760, - 2774, - 2784, - 2793, - 2804, - 2811, - 2822, - 2826, - 2836, - 2839, - 2840, - 2893, - 2901, - 2902, - 2905, - 2912, - 2915, - 2918, - 2939, - 2965, - 2966, - 2975, - 2988, - 2993, - 3006, - 3017, - 3031, - 3038, - 3041, - 3042, - 3051, - 3073, - 3088, - 3097, - 3098, - 3103, - 3104, - 3146, - 3148, - 3153, - 3159, - 3182, - 3187, - 3189, - 3199, - 3239, - 3263, - 3271, - 3275, - 3278, - 3280, - 3283, - 3290, - 3311, - 3316, - 3343, - 3346, - 3357, - 3358, - 3361, - 3362, - 3364, - 3386, - 3418, - 3424, - 3433, - 3434, - 3436, - 3463, - 3467, - 3477, - 3484, - 3505, - 3508, - 3515, - 3532, - 3553, - 3554, - 3568, - 3573, - 3587, - 3589, - 3596, - 3608, - 3620, - 3630, - 3644, - 3649, - 3664, - 3679, - 3680, - 3685, - 3686, - 3698, - 3714, - 3726, - 3737, - 3767, - 3782, - 3786, - 3793, - 3796, - 3805, - 3815, - 3841, - 3847, - 3853, - 3862, - 3875, - 3902, - 3904, - 3916, - 3947, - 3949, - 3955, - 3962, - 3971, - 3980, - 3985, - 3998, - 4001, - 4002, - 4016, - 4021, - 4026, - 4043, - 4079, - 4102, - 4106, - 4119, - 4126, - 4147, - 4149, - 4164, - 4174, - 4181, - 4185, - 4188, - 4202, - 4228, - 4232, - 4246, - 4252, - 4256, - 4286, - 4303, - 4306, - 4311, - 4317, - 4342, - 4346, - 4377, - 4401, - 4407, - 4414, - 4422, - 4431, - 4434, - 4436, - 4443, - 4459, - 4461, - 4462, - 4473, - 4497, - 4504, - 4507, - 4525, - 4534, - 4538, - 4548, - 4552, - 4560, - 4575, - 4599, - 4612, - 4619, - 4640, - 4643, - 4677, - 4687, - 4723, - 4730, - 4736, - 4741, - 4763, - 4765, - 4770, - 4781, - 4808, - 4822, - 4828, - 4831, - 4842, - 4855, - 4859, - 4867, - 4870, - 4881, - 4893, - 4910, - 4917, - 4929, - 4939, - 4947, - 4949, - 4954, - 4972, - 4975, - 5000, - 5005, - 5029, - 5039, - 5044, - 5051, - 5056, - 5073, - 5096, - 5128, - 5134, - 5161, - 5179, - 5193, - 5199, - 5202, - 5204, - 5218, - 5247, - 5260, - 5271, - 5301, - 5305, - 5319, - 5326, - 5328, - 5333, - 5364, - 5376, - 5399, - 5416, - 5421, - 5427, - 5429, - 5430, - 5434, - 5441, - 5451, - 5465, - 5466, - 5471, - 5477, - 5492, - 5495, - 5505, - 5515, - 5525, - 5529, - 5532, - 5539, - 5541, - 5556, - 5566, - 5568, - 5574, - 5595, - 5602, - 5611, - 5616, - 5622, - 5628, - 5655, - 5662, - 5675, - 5689, - 5722, - 5724, - 5728, - 5731, - 5746, - 5764, - 5771, - 5781, - 5801, - 5809, - 5810, - 5812, - 5841, - 5848, - 5853, - 5854, - 5858, - 5892, - 5907, - 5910, - 5913, - 5920, - 5929, - 5949, - 5952, - 5955, - 5962, - 5975, - 5985, - 5997, - 5998, - 6012, - 6016, - 6026, - 6036, - 6040, - 6045, - 6055, - 6059, - 6088, - 6115, - 6124, - 6127, - 6132, - 6146, - 6158, - 6169, - 6206, - 6228, - 6237, - 6244, - 6247, - 6256, - 6281, - 6282, - 6284, - 6296, - 6299, - 6302, - 6325, - 6349, - 6352, - 6362, - 6383, - 6386, - 6395, - 6397, - 6415, - 6424, - 6429, - 6439, - 6451, - 6489, - 6496, - 6502, - 6511, - 6514, - 6520, - 6523, - 6529, - 6532, - 6547, - 6549, - 6598, - 6601, - 6610, - 6622, - 6632, - 6655, - 6665, - 6666, - 6695, - 6701, - 6709, - 6710, - 6741, - 6745, - 6758, - 6767, - 6772, - 6782, - 6797, - 6800, - 6843, - 6845, - 6860, - 6865, - 6878, - 6887, - 6888, - 6901, - 6906, - 6940, - 6947, - 6953, - 6954, - 6959, - 6961, - 6964, - 6991, - 6993, - 6999, - 7016, - 7029, - 7036, - 7045, - 7076, - 7083, - 7094, - 7097, - 7123, - 7130, - 7139, - 7145, - 7146, - 7178, - 7186, - 7192, - 7198, - 7222, - 7269, - 7270, - 7276, - 7287, - 7307, - 7315, - 7334, - 7340, - 7351, - 7352, - 7357, - 7360, - 7363, - 7384, - 7396, - 7403, - 7406, - 7425, - 7437, - 7445, - 7450, - 7455, - 7461, - 7466, - 7488, - 7494, - 7515, - 7517, - 7521, - 7536, - 7546, - 7569, - 7591, - 7592, - 7598, - 7612, - 7623, - 7632, - 7637, - 7644, - 7657, - 7665, - 7672, - 7682, - 7699, - 7702, - 7724, - 7749, - 7753, - 7754, - 7761, - 7771, - 7777, - 7784, - 7804, - 7807, - 7808, - 7818, - 7835, - 7842, - 7865, - 7868, - 7880, - 7883, - 7891, - 7897, - 7907, - 7910, - 7924, - 7933, - 7934, - 7942, - 7948, - 7959, - 7984, - 7994, - 7999, - 8014, - 8021, - 8041, - 8049, - 8050, - 8068, - 8080, - 8095, - 8102, - 8106, - 8120, - 8133, - 8134, - 8143, - 8162, - 8168, - 8179, - -1 }; - //#endif - - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_14 - static long[] PrimitivePolynomialDegree15 = { - 1, - 8, - 11, - 22, - 26, - 47, - 59, - 64, - 67, - 73, - 82, - 97, - 103, - 110, - 115, - 122, - 128, - 138, - 146, - 171, - 174, - 176, - 182, - 194, - 208, - 211, - 220, - 229, - 230, - 239, - 254, - 265, - 285, - 290, - 319, - 324, - 327, - 333, - 357, - 364, - 395, - 397, - 405, - 409, - 419, - 422, - 431, - 433, - 436, - 440, - 453, - 460, - 471, - 478, - 482, - 488, - 524, - 529, - 535, - 536, - 539, - 563, - 566, - 572, - 577, - 587, - 592, - 602, - 623, - 635, - 638, - 654, - 656, - 659, - 665, - 675, - 677, - 687, - 696, - 701, - 704, - 710, - 721, - 728, - 738, - 740, - 749, - 758, - 761, - 772, - 776, - 782, - 789, - 810, - 812, - 818, - 830, - 832, - 852, - 855, - 859, - 865, - 877, - 895, - 901, - 902, - 906, - 916, - 920, - 949, - 962, - 964, - 967, - 981, - 982, - 985, - 991, - 1007, - 1016, - 1024, - 1051, - 1060, - 1070, - 1072, - 1084, - 1089, - 1095, - 1114, - 1123, - 1132, - 1154, - 1156, - 1163, - 1171, - 1202, - 1228, - 1239, - 1255, - 1256, - 1262, - 1270, - 1279, - 1308, - 1322, - 1329, - 1330, - 1336, - 1341, - 1347, - 1349, - 1359, - 1367, - 1368, - 1390, - 1413, - 1414, - 1437, - 1441, - 1462, - 1465, - 1480, - 1486, - 1504, - 1509, - 1514, - 1522, - 1528, - 1552, - 1555, - 1571, - 1578, - 1585, - 1588, - 1603, - 1609, - 1617, - 1620, - 1629, - 1636, - 1648, - 1667, - 1669, - 1682, - 1697, - 1704, - 1709, - 1727, - 1730, - 1732, - 1741, - 1744, - 1759, - 1765, - 1766, - 1778, - 1780, - 1783, - 1797, - 1807, - 1821, - 1832, - 1835, - 1849, - 1850, - 1863, - 1867, - 1869, - 1872, - 1887, - 1888, - 1897, - 1906, - 1917, - 1927, - 1939, - 1941, - 1948, - 1970, - 1979, - 1982, - 2002, - 2020, - 2024, - 2032, - 2053, - 2060, - 2063, - 2066, - 2075, - 2078, - 2081, - 2091, - 2096, - 2102, - 2106, - 2116, - 2120, - 2125, - 2134, - 2178, - 2180, - 2187, - 2189, - 2190, - 2208, - 2214, - 2237, - 2252, - 2257, - 2260, - 2264, - 2270, - 2279, - 2288, - 2305, - 2312, - 2317, - 2323, - 2329, - 2335, - 2342, - 2345, - 2365, - 2371, - 2378, - 2385, - 2395, - 2404, - 2414, - 2426, - 2428, - 2441, - 2456, - 2466, - 2468, - 2475, - 2489, - 2495, - 2497, - 2510, - 2512, - 2522, - 2533, - 2543, - 2551, - 2552, - 2557, - 2567, - 2581, - 2586, - 2597, - 2601, - 2622, - 2633, - 2636, - 2642, - 2644, - 2653, - 2667, - 2669, - 2672, - 2675, - 2682, - 2687, - 2691, - 2698, - 2708, - 2712, - 2718, - 2722, - 2736, - 2741, - 2756, - 2765, - 2774, - 2799, - 2804, - 2825, - 2826, - 2840, - 2843, - 2846, - 2849, - 2867, - 2876, - 2891, - 2902, - 2912, - 2917, - 2927, - 2941, - 2965, - 2970, - 2982, - 2993, - 3018, - 3023, - 3025, - 3026, - 3028, - 3032, - 3053, - 3054, - 3065, - 3071, - 3076, - 3088, - 3107, - 3146, - 3148, - 3159, - 3165, - 3170, - 3179, - 3182, - 3205, - 3212, - 3218, - 3220, - 3223, - 3227, - 3233, - 3234, - 3254, - 3263, - 3268, - 3272, - 3277, - 3292, - 3295, - 3296, - 3301, - 3306, - 3313, - 3346, - 3367, - 3371, - 3373, - 3374, - 3376, - 3382, - 3388, - 3391, - 3403, - 3406, - 3413, - 3420, - 3427, - 3441, - 3453, - 3464, - 3469, - 3481, - 3488, - 3497, - 3503, - 3511, - 3515, - 3525, - 3529, - 3547, - 3550, - 3573, - 3583, - 3594, - 3607, - 3613, - 3624, - 3630, - 3635, - 3642, - 3644, - 3650, - 3679, - 3690, - 3698, - 3704, - 3707, - 3713, - 3754, - 3756, - 3761, - 3776, - 3781, - 3788, - 3791, - 3794, - 3806, - 3841, - 3848, - 3851, - 3856, - 3868, - 3875, - 3882, - 3884, - 3889, - 3892, - 3919, - 3921, - 3958, - 3961, - 3973, - 3977, - 3985, - 3991, - 4004, - 4007, - 4019, - 4045, - 4054, - 4057, - 4058, - 4070, - 4101, - 4113, - 4114, - 4119, - 4129, - 4141, - 4142, - 4147, - 4149, - 4150, - 4164, - 4168, - 4186, - 4198, - 4207, - 4221, - 4225, - 4231, - 4238, - 4243, - 4249, - 4250, - 4252, - 4259, - 4279, - 4285, - 4288, - 4303, - 4312, - 4322, - 4327, - 4336, - 4359, - 4384, - 4387, - 4401, - 4407, - 4428, - 4436, - 4450, - 4452, - 4459, - 4461, - 4470, - 4483, - 4485, - 4486, - 4492, - 4497, - 4514, - 4533, - 4537, - 4546, - 4551, - 4555, - 4560, - 4569, - 4576, - 4582, - 4586, - 4609, - 4610, - 4612, - 4649, - 4652, - 4672, - 4677, - 4684, - 4690, - 4695, - 4696, - 4702, - 4705, - 4717, - 4726, - 4736, - 4753, - 4754, - 4756, - 4775, - 4801, - 4819, - 4828, - 4838, - 4852, - 4856, - 4873, - 4887, - 4891, - 4904, - 4912, - 4921, - 4936, - 4941, - 4942, - 4963, - 4984, - 4990, - 5005, - 5013, - 5020, - 5039, - 5048, - 5062, - 5080, - 5085, - 5086, - 5095, - 5096, - 5102, - 5107, - 5141, - 5145, - 5148, - 5157, - 5158, - 5162, - 5172, - 5182, - 5184, - 5193, - 5199, - 5201, - 5204, - 5211, - 5223, - 5230, - 5232, - 5253, - 5257, - 5260, - 5284, - 5306, - 5331, - 5334, - 5364, - 5367, - 5371, - 5382, - 5386, - 5399, - 5400, - 5409, - 5415, - 5416, - 5424, - 5436, - 5454, - 5462, - 5468, - 5481, - 5505, - 5511, - 5518, - 5530, - 5532, - 5539, - 5553, - 5573, - 5580, - 5597, - 5602, - 5608, - 5611, - 5613, - 5625, - 5632, - 5635, - 5638, - 5652, - 5659, - 5677, - 5686, - 5689, - 5698, - 5703, - 5707, - 5731, - 5738, - 5743, - 5748, - 5758, - 5762, - 5768, - 5773, - 5776, - 5815, - 5841, - 5847, - 5860, - 5870, - 5875, - 5877, - 5884, - 5892, - 5902, - 5910, - 5916, - 5919, - 5935, - 5937, - 5944, - 5947, - 5958, - 5962, - 5969, - 5981, - 5995, - 5998, - 6003, - 6010, - 6016, - 6025, - 6031, - 6036, - 6039, - 6045, - 6049, - 6052, - 6067, - 6074, - 6087, - 6101, - 6121, - 6129, - 6142, - 6151, - 6157, - 6166, - 6170, - 6175, - 6186, - 6203, - 6217, - 6231, - 6241, - 6242, - 6248, - 6256, - 6265, - 6275, - 6277, - 6302, - 6315, - 6318, - 6330, - 6343, - 6347, - 6350, - 6352, - 6371, - 6383, - 6386, - 6405, - 6409, - 6410, - 6433, - 6436, - 6439, - 6463, - 6468, - 6477, - 6496, - 6511, - 6516, - 6519, - 6523, - 6530, - 6539, - 6547, - 6589, - 6592, - 6601, - 6610, - 6616, - 6619, - 6626, - 6635, - 6637, - 6638, - 6652, - 6656, - 6662, - 6689, - 6699, - 6710, - 6714, - 6719, - 6739, - 6751, - 6775, - 6779, - 6788, - 6798, - 6815, - 6819, - 6825, - 6826, - 6836, - 6843, - 6845, - 6858, - 6868, - 6877, - 6881, - 6891, - 6896, - 6899, - 6901, - 6908, - 6914, - 6916, - 6923, - 6925, - 6928, - 6931, - 6934, - 6937, - 6938, - 6949, - 6956, - 6973, - 6976, - 6981, - 6988, - 6999, - 7016, - 7027, - 7029, - 7055, - 7058, - 7074, - 7083, - 7093, - 7100, - 7105, - 7112, - 7118, - 7120, - 7129, - 7166, - 7207, - 7216, - 7226, - 7234, - 7236, - 7246, - 7248, - 7254, - 7263, - 7273, - 7274, - 7293, - 7297, - 7310, - 7315, - 7317, - 7331, - 7338, - 7340, - 7346, - 7355, - 7366, - 7383, - 7389, - 7393, - 7396, - 7400, - 7414, - 7417, - 7426, - 7432, - 7452, - 7468, - 7488, - 7491, - 7494, - 7497, - 7515, - 7531, - 7552, - 7562, - 7564, - 7569, - 7582, - 7585, - 7588, - 7592, - 7597, - 7603, - 7610, - 7624, - 7642, - 7647, - 7653, - 7654, - 7666, - 7668, - 7684, - 7705, - 7732, - 7741, - 7749, - 7750, - 7759, - 7764, - 7777, - 7790, - 7817, - 7826, - 7831, - 7859, - 7871, - 7873, - 7876, - 7900, - 7904, - 7913, - 7916, - 7922, - 7946, - 7953, - 7956, - 7963, - 7979, - 7981, - 7984, - 7989, - 7999, - 8001, - 8021, - 8056, - 8080, - 8083, - 8089, - 8090, - 8114, - 8128, - 8133, - 8145, - 8155, - 8161, - 8182, - 8186, - 8191, - 8192, - 8195, - 8201, - 8207, - 8210, - 8228, - 8249, - 8252, - 8258, - 8267, - 8270, - 8275, - 8284, - 8293, - 8298, - 8305, - 8317, - 8328, - 8336, - 8345, - 8351, - 8367, - 8379, - 8381, - 8382, - 8393, - 8402, - 8414, - 8417, - 8420, - 8429, - 8435, - 8438, - 8450, - 8452, - 8459, - 8470, - 8486, - 8490, - 8500, - 8524, - 8536, - 8552, - 8558, - 8570, - 8576, - 8582, - 8594, - 8606, - 8619, - 8621, - 8624, - 8633, - 8641, - 8653, - 8654, - 8662, - 8675, - 8689, - 8695, - 8702, - 8706, - 8720, - 8729, - 8739, - 8741, - 8751, - 8759, - 8766, - 8777, - 8783, - 8786, - 8795, - 8802, - 8814, - 8821, - 8828, - 8831, - 8837, - 8842, - 8855, - 8856, - 8868, - 8877, - 8890, - 8892, - 8900, - 8909, - 8912, - 8921, - 8922, - 8927, - 8943, - 8948, - 8951, - 8958, - 8984, - 8994, - 9000, - 9013, - 9018, - 9020, - 9031, - 9035, - 9045, - 9052, - 9056, - 9059, - 9066, - 9076, - 9089, - 9129, - 9132, - 9147, - 9164, - 9167, - 9185, - 9195, - 9197, - 9210, - 9217, - 9229, - 9248, - 9254, - 9263, - 9266, - 9268, - 9290, - 9310, - 9316, - 9338, - 9340, - 9343, - 9344, - 9350, - 9354, - 9359, - 9361, - 9364, - 9368, - 9371, - 9373, - 9389, - 9390, - 9409, - 9443, - 9445, - 9446, - 9452, - 9490, - 9492, - 9495, - 9508, - 9523, - 9543, - 9558, - 9567, - 9580, - 9585, - 9591, - 9611, - 9613, - 9614, - 9621, - 9631, - 9642, - 9656, - 9661, - 9667, - 9694, - 9715, - 9722, - 9738, - 9745, - 9758, - 9764, - 9782, - 9791, - 9793, - 9794, - 9805, - 9808, - 9811, - 9817, - 9824, - 9836, - 9851, - 9853, - 9854, - 9877, - 9881, - 9923, - 9935, - 9937, - 9954, - 9959, - 9963, - 9968, - 9973, - 9974, - 9980, - 9983, - 9985, - 10003, - 10010, - 10034, - 10040, - 10063, - 10077, - 10081, - 10082, - 10084, - 10088, - 10091, - 10105, - 10111, - 10118, - 10127, - 10135, - 10169, - 10172, - 10183, - 10190, - 10192, - 10211, - 10218, - 10228, - 10235, - 10242, - 10244, - 10271, - 10278, - 10296, - 10299, - 10307, - 10309, - 10310, - 10314, - 10316, - 10321, - 10328, - 10338, - 10343, - 10344, - 10347, - 10352, - 10364, - 10373, - 10386, - 10391, - 10398, - 10408, - 10413, - 10422, - 10445, - 10460, - 10463, - 10464, - 10474, - 10476, - 10487, - 10494, - 10499, - 10506, - 10513, - 10516, - 10523, - 10539, - 10549, - 10550, - 10567, - 10576, - 10625, - 10635, - 10643, - 10656, - 10671, - 10676, - 10683, - 10685, - 10688, - 10697, - 10700, - 10712, - 10724, - 10728, - 10734, - 10739, - 10762, - 10772, - 10781, - 10800, - 10805, - 10827, - 10830, - 10837, - 10841, - 10847, - 10848, - 10857, - 10866, - 10868, - 10872, - 10887, - 10899, - 10901, - 10915, - 10924, - 10929, - 10942, - 10971, - 10992, - 10995, - 11002, - 11010, - 11027, - 11029, - 11045, - 11057, - 11070, - 11092, - 11099, - 11106, - 11115, - 11120, - 11126, - 11153, - 11190, - 11199, - 11222, - 11225, - 11226, - 11231, - 11244, - 11259, - 11261, - 11270, - 11273, - 11300, - 11307, - 11318, - 11332, - 11335, - 11341, - 11347, - 11354, - 11360, - 11369, - 11372, - 11378, - 11396, - 11405, - 11417, - 11424, - 11427, - 11430, - 11439, - 11442, - 11448, - 11461, - 11468, - 11471, - 11473, - 11476, - 11480, - 11489, - 11499, - 11516, - 11522, - 11531, - 11539, - 11546, - 11551, - 11564, - 11582, - 11589, - 11593, - 11601, - 11608, - 11617, - 11630, - 11663, - 11666, - 11668, - 11677, - 11682, - 11687, - 11696, - 11713, - 11728, - 11747, - 11750, - 11754, - 11759, - 11761, - 11764, - 11767, - 11797, - 11804, - 11808, - 11831, - 11832, - 11849, - 11855, - 11863, - 11880, - 11883, - 11885, - 11898, - 11916, - 11924, - 11928, - 11947, - 11955, - 11961, - 11962, - 11982, - 11990, - 12010, - 12018, - 12027, - 12029, - 12035, - 12055, - 12062, - 12068, - 12071, - 12072, - 12086, - 12097, - 12098, - 12100, - 12112, - 12118, - 12133, - 12134, - 12137, - 12161, - 12162, - 12171, - 12174, - 12185, - 12204, - 12212, - 12215, - 12216, - 12253, - 12260, - 12277, - 12289, - 12295, - 12314, - 12323, - 12325, - 12335, - 12349, - 12358, - 12372, - 12376, - 12379, - 12386, - 12395, - 12416, - 12421, - 12440, - 12452, - 12455, - 12456, - 12462, - 12467, - 12479, - 12505, - 12521, - 12535, - 12547, - 12556, - 12561, - 12568, - 12578, - 12583, - 12595, - 12604, - 12610, - 12621, - 12622, - 12624, - 12629, - 12630, - 12639, - 12640, - 12650, - 12679, - 12680, - 12698, - 12716, - 12721, - 12722, - 12731, - 12742, - 12745, - 12751, - 12759, - 12763, - 12769, - 12781, - 12793, - 12799, - 12815, - 12824, - 12836, - 12845, - 12853, - 12854, - 12857, - 12866, - 12872, - 12875, - 12878, - 12880, - 12885, - 12901, - 12902, - 12920, - 12926, - 12929, - 12939, - 12941, - 12950, - 12953, - 12992, - 13002, - 13010, - 13058, - 13072, - 13084, - 13087, - 13091, - 13097, - 13108, - 13123, - 13149, - 13150, - 13163, - 13166, - 13178, - 13180, - 13184, - 13204, - 13238, - 13242, - 13249, - 13255, - 13269, - 13270, - 13274, - 13285, - 13289, - 13298, - 13307, - 13312, - 13335, - 13345, - 13357, - 13366, - 13372, - 13380, - 13384, - 13395, - 13407, - 13408, - 13413, - 13414, - 13417, - 13437, - 13441, - 13447, - 13456, - 13459, - 13461, - 13466, - 13484, - 13487, - 13489, - 13492, - 13496, - 13510, - 13531, - 13538, - 13543, - 13547, - 13572, - 13581, - 13590, - 13605, - 13612, - 13624, - 13630, - 13632, - 13638, - 13661, - 13665, - 13668, - 13686, - 13699, - 13701, - 13708, - 13716, - 13725, - 13730, - 13742, - 13747, - 13749, - 13753, - 13754, - 13771, - 13773, - 13782, - 13785, - 13798, - 13802, - 13809, - 13828, - 13832, - 13840, - 13850, - 13861, - 13874, - 13876, - 13886, - 13897, - 13900, - 13915, - 13927, - 13951, - 13955, - 13962, - 13969, - 13979, - 13988, - 13998, - 14000, - 14005, - 14027, - 14037, - 14051, - 14054, - 14060, - 14063, - 14071, - 14078, - 14080, - 14085, - 14086, - 14095, - 14138, - 14145, - 14158, - 14166, - 14179, - 14181, - 14188, - 14193, - 14200, - 14203, - 14215, - 14224, - 14230, - 14233, - 14236, - 14246, - 14267, - 14282, - 14287, - 14301, - 14323, - 14325, - 14329, - 14339, - 14342, - 14351, - 14356, - 14359, - 14370, - 14402, - 14411, - 14421, - 14431, - 14435, - 14442, - 14447, - 14456, - 14459, - 14472, - 14477, - 14490, - 14496, - 14501, - 14505, - 14513, - 14520, - 14534, - 14562, - 14576, - 14579, - 14585, - 14586, - 14606, - 14627, - 14630, - 14634, - 14636, - 14647, - 14653, - 14659, - 14671, - 14674, - 14701, - 14716, - 14719, - 14720, - 14725, - 14730, - 14743, - 14747, - 14786, - 14788, - 14792, - 14795, - 14809, - 14831, - 14834, - 14850, - 14855, - 14859, - 14864, - 14876, - 14889, - 14890, - 14898, - 14909, - 14917, - 14924, - 14929, - 14942, - 14951, - 14969, - 14970, - 14972, - 14982, - 14988, - 14994, - 15005, - 15016, - 15024, - 15030, - 15048, - 15054, - 15066, - 15071, - 15072, - 15075, - 15119, - 15121, - 15133, - 15138, - 15143, - 15170, - 15194, - 15212, - 15223, - 15229, - 15254, - 15263, - 15270, - 15273, - 15287, - 15299, - 15301, - 15306, - 15313, - 15320, - 15323, - 15329, - 15332, - 15341, - 15359, - 15361, - 15364, - 15367, - 15379, - 15391, - 15415, - 15416, - 15419, - 15433, - 15469, - 15478, - 15481, - 15482, - 15498, - 15505, - 15517, - 15518, - 15527, - 15528, - 15545, - 15548, - 15554, - 15565, - 15577, - 15580, - 15587, - 15601, - 15604, - 15611, - 15616, - 15619, - 15625, - 15633, - 15674, - 15681, - 15691, - 15693, - 15696, - 15712, - 15717, - 15724, - 15727, - 15730, - 15746, - 15751, - 15760, - 15770, - 15782, - 15791, - 15796, - 15808, - 15814, - 15825, - 15828, - 15835, - 15844, - 15847, - 15853, - 15856, - 15877, - 15878, - 15887, - 15908, - 15917, - 15923, - 15930, - 15937, - 15958, - 15977, - 15991, - 16007, - 16011, - 16014, - 16021, - 16022, - 16028, - 16035, - 16041, - 16056, - 16069, - 16076, - 16081, - 16087, - 16088, - 16110, - 16112, - 16117, - 16150, - 16153, - 16160, - 16166, - 16172, - 16190, - 16195, - 16204, - 16216, - 16222, - 16228, - 16245, - 16255, - 16265, - 16273, - 16276, - 16283, - 16295, - 16304, - 16313, - 16319, - 16328, - 16345, - 16355, - 16364, - 16372, - 16375, - 16382, - -1 }; - //#endif - - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_15 - static long[] PrimitivePolynomialDegree16 = { - 22, - 28, - 31, - 41, - 94, - 107, - 151, - 158, - 167, - 174, - 203, - 208, - 214, - 223, - 227, - 266, - 268, - 274, - 279, - 302, - 310, - 322, - 328, - 336, - 370, - 398, - 421, - 436, - 440, - 451, - 454, - 463, - 465, - 494, - 508, - 532, - 555, - 563, - 577, - 580, - 584, - 607, - 608, - 665, - 675, - 692, - 707, - 737, - 750, - 757, - 800, - 805, - 809, - 837, - 865, - 949, - 950, - 956, - 961, - 1016, - 1030, - 1072, - 1119, - 1130, - 1135, - 1137, - 1144, - 1149, - 1180, - 1214, - 1221, - 1234, - 1239, - 1249, - 1250, - 1267, - 1273, - 1342, - 1344, - 1373, - 1378, - 1408, - 1417, - 1418, - 1448, - 1454, - 1510, - 1513, - 1522, - 1543, - 1550, - 1552, - 1588, - 1592, - 1597, - 1606, - 1610, - 1617, - 1623, - 1657, - 1697, - 1729, - 1735, - 1769, - 1778, - 1826, - 1858, - 1870, - 1875, - 1922, - 1924, - 1933, - 1972, - 1979, - 1987, - 1994, - 2008, - 2023, - 2029, - 2053, - 2081, - 2087, - 2094, - 2111, - 2113, - 2114, - 2123, - 2190, - 2231, - 2276, - 2285, - 2297, - 2336, - 2345, - 2353, - 2363, - 2368, - 2373, - 2391, - 2402, - 2413, - 2422, - 2425, - 2461, - 2462, - 2490, - 2492, - 2510, - 2564, - 2573, - 2598, - 2627, - 2633, - 2647, - 2660, - 2664, - 2678, - 2684, - 2691, - 2759, - 2768, - 2773, - 2794, - 2813, - 2831, - 2843, - 2846, - 2849, - 2856, - 2893, - 2901, - 2924, - 2942, - 2975, - 2979, - 2985, - 3020, - 3025, - 3028, - 3051, - 3127, - 3142, - 3145, - 3156, - 3165, - 3196, - 3199, - 3217, - 3218, - 3253, - 3258, - 3260, - 3289, - 3314, - 3326, - 3331, - 3371, - 3381, - 3396, - 3441, - 3442, - 3460, - 3477, - 3491, - 3493, - 3543, - 3549, - 3550, - 3553, - 3563, - 3568, - 3604, - 3632, - 3650, - 3662, - 3674, - 3685, - 3686, - 3700, - 3703, - 3704, - 3723, - 3743, - 3753, - 3756, - 3759, - 3762, - 3771, - 3776, - 3779, - 3839, - 3856, - 3871, - 3887, - 3896, - 3901, - 3916, - 3919, - 3937, - 3943, - 3955, - 3961, - 3988, - 3997, - 4011, - 4026, - 4033, - 4045, - 4060, - 4063, - 4064, - 4126, - 4136, - 4167, - 4173, - 4188, - 4195, - 4226, - 4291, - 4298, - 4308, - 4312, - 4336, - 4371, - 4378, - 4384, - 4393, - 4421, - 4425, - 4439, - 4440, - 4500, - 4514, - 4523, - 4534, - 4593, - 4615, - 4630, - 4636, - 4645, - 4684, - 4687, - 4723, - 4735, - 4746, - 4779, - 4782, - 4793, - 4796, - 4813, - 4850, - 4867, - 4874, - 4881, - 4894, - 4904, - 4927, - 4929, - 4989, - 5000, - 5020, - 5036, - 5041, - 5059, - 5074, - 5090, - 5110, - 5134, - 5152, - 5176, - 5181, - 5204, - 5218, - 5242, - 5253, - 5260, - 5281, - 5282, - 5313, - 5316, - 5326, - 5340, - 5347, - 5354, - 5368, - 5394, - 5396, - 5400, - 5405, - 5439, - 5442, - 5459, - 5478, - 5484, - 5508, - 5523, - 5545, - 5565, - 5566, - 5580, - 5608, - 5613, - 5647, - 5661, - 5671, - 5678, - 5680, - 5685, - 5689, - 5692, - 5724, - 5745, - 5755, - 5757, - 5786, - 5792, - 5810, - 5824, - 5869, - 5872, - 5895, - 5923, - 5925, - 5926, - 5944, - 5986, - 6012, - 6015, - 6046, - 6049, - 6061, - 6067, - 6099, - 6121, - 6155, - 6163, - 6203, - 6208, - 6231, - 6241, - 6254, - 6262, - 6266, - 6275, - 6278, - 6292, - 6329, - 6355, - 6357, - 6374, - 6380, - 6423, - 6427, - 6430, - 6436, - 6443, - 6445, - 6458, - 6478, - 6490, - 6508, - 6519, - 6520, - 6530, - 6541, - 6556, - 6607, - 6612, - 6626, - 6632, - 6649, - 6666, - 6674, - 6733, - 6782, - 6786, - 6798, - 6821, - 6840, - 6846, - 6865, - 6884, - 6891, - 6925, - 6938, - 6967, - 6988, - 6996, - 7009, - 7016, - 7030, - 7043, - 7045, - 7052, - 7073, - 7142, - 7153, - 7168, - 7174, - 7183, - 7195, - 7204, - 7214, - 7222, - 7267, - 7269, - 7279, - 7293, - 7312, - 7327, - 7334, - 7337, - 7343, - 7346, - 7372, - 7387, - 7390, - 7396, - 7423, - 7428, - 7437, - 7466, - 7474, - 7476, - 7483, - 7518, - 7527, - 7545, - 7572, - 7586, - 7597, - 7630, - 7653, - 7657, - 7671, - 7672, - 7715, - 7717, - 7732, - 7735, - 7753, - 7811, - 7817, - 7825, - 7832, - 7838, - 7841, - 7844, - 7859, - 7861, - 7873, - 7880, - 7897, - 7904, - 7910, - 7960, - 7969, - 7970, - 7976, - 7979, - 8007, - 8041, - 8047, - 8052, - 8061, - 8078, - 8128, - 8146, - 8162, - 8250, - 8270, - 8294, - 8324, - 8351, - 8357, - 8361, - 8364, - 8393, - 8396, - 8407, - 8413, - 8414, - 8432, - 8435, - 8441, - 8447, - 8449, - 8456, - 8485, - 8504, - 8512, - 8532, - 8551, - 8560, - 8566, - 8581, - 8609, - 8639, - 8641, - 8671, - 8695, - 8701, - 8711, - 8739, - 8763, - 8778, - 8783, - 8785, - 8797, - 8802, - 8816, - 8828, - 8837, - 8852, - 8859, - 8889, - 8900, - 8903, - 8909, - 8910, - 8922, - 8924, - 8955, - 8958, - 8980, - 8994, - 9006, - 9017, - 9032, - 9040, - 9061, - 9066, - 9071, - 9076, - 9086, - 9104, - 9150, - 9161, - 9164, - 9185, - 9188, - 9212, - 9230, - 9242, - 9247, - 9260, - 9280, - 9300, - 9313, - 9325, - 9343, - 9349, - 9354, - 9367, - 9368, - 9455, - 9458, - 9469, - 9481, - 9482, - 9495, - 9526, - 9530, - 9558, - 9562, - 9573, - 9583, - 9595, - 9597, - 9616, - 9638, - 9649, - 9662, - 9691, - 9700, - 9703, - 9710, - 9721, - 9724, - 9727, - 9743, - 9779, - 9785, - 9811, - 9820, - 9827, - 9851, - 9854, - 9863, - 9884, - 9894, - 9903, - 9908, - 9912, - 9925, - 9926, - 9971, - 9973, - 9977, - 10021, - 10039, - 10048, - 10051, - 10065, - 10071, - 10072, - 10101, - 10106, - 10130, - 10136, - 10148, - 10155, - 10157, - 10160, - 10166, - 10183, - 10192, - 10225, - 10241, - 10247, - 10284, - 10304, - 10322, - 10331, - 10333, - 10340, - 10347, - 10357, - 10371, - 10386, - 10404, - 10414, - 10422, - 10448, - 10451, - 10473, - 10479, - 10501, - 10530, - 10542, - 10544, - 10571, - 10628, - 10643, - 10673, - 10683, - 10736, - 10795, - 10797, - 10815, - 10817, - 10842, - 10844, - 10863, - 10899, - 10902, - 10917, - 10953, - 10967, - 11002, - 11024, - 11029, - 11030, - 11043, - 11087, - 11106, - 11130, - 11156, - 11176, - 11221, - 11267, - 11282, - 11294, - 11332, - 11353, - 11369, - 11372, - 11375, - 11413, - 11429, - 11430, - 11444, - 11462, - 11465, - 11471, - 11473, - 11495, - 11499, - 11519, - 11562, - 11576, - 11582, - 11596, - 11602, - 11611, - 11627, - 11682, - 11687, - 11691, - 11733, - 11747, - 11759, - 11778, - 11852, - 11857, - 11858, - 11893, - 11907, - 11928, - 11931, - 11933, - 11967, - 11976, - 11989, - 12003, - 12024, - 12030, - 12037, - 12044, - 12052, - 12059, - 12075, - 12083, - 12117, - 12138, - 12146, - 12202, - 12230, - 12254, - 12304, - 12316, - 12337, - 12347, - 12367, - 12398, - 12421, - 12428, - 12446, - 12449, - 12467, - 12479, - 12502, - 12521, - 12553, - 12568, - 12573, - 12592, - 12597, - 12601, - 12615, - 12619, - 12694, - 12697, - 12698, - 12713, - 12722, - 12733, - 12736, - 12790, - 12794, - 12803, - 12815, - 12829, - 12833, - 12840, - 12875, - 12877, - 12916, - 12923, - 12935, - 12949, - 12954, - 12956, - 12959, - 12978, - 13001, - 13010, - 13043, - 13049, - 13058, - 13112, - 13140, - 13149, - 13163, - 13187, - 13196, - 13237, - 13244, - 13264, - 13279, - 13292, - 13295, - 13307, - 13312, - 13317, - 13327, - 13348, - 13390, - 13413, - 13417, - 13418, - 13451, - 13475, - 13482, - 13510, - 13527, - 13543, - 13547, - 13627, - 13650, - 13683, - 13696, - 13702, - 13713, - 13739, - 13749, - 13767, - 13774, - 13781, - 13795, - 13821, - 13825, - 13838, - 13852, - 13879, - 13888, - 13897, - 13906, - 13939, - 13962, - 13981, - 13985, - 14020, - 14030, - 14041, - 14047, - 14048, - 14066, - 14092, - 14120, - 14126, - 14131, - 14143, - 14146, - 14152, - 14155, - 14157, - 14188, - 14206, - 14243, - 14278, - 14308, - 14317, - 14335, - 14354, - 14356, - 14379, - 14381, - 14384, - 14389, - 14390, - 14414, - 14425, - 14462, - 14472, - 14508, - 14511, - 14519, - 14528, - 14561, - 14574, - 14588, - 14594, - 14606, - 14614, - 14639, - 14641, - 14648, - 14668, - 14673, - 14679, - 14695, - 14702, - 14704, - 14740, - 14754, - 14774, - 14792, - 14797, - 14806, - 14812, - 14856, - 14876, - 14900, - 14910, - 14912, - 14915, - 14922, - 14939, - 14946, - 14955, - 14966, - 14976, - 14986, - 14993, - 15012, - 15041, - 15053, - 15056, - 15059, - 15110, - 15116, - 15133, - 15134, - 15137, - 15147, - 15182, - 15203, - 15215, - 15245, - 15246, - 15264, - 15269, - 15296, - 15314, - 15323, - 15364, - 15386, - 15391, - 15436, - 15460, - 15464, - 15469, - 15470, - 15477, - 15488, - 15494, - 15548, - 15551, - 15560, - 15563, - 15604, - 15607, - 15616, - 15631, - 15699, - 15701, - 15708, - 15739, - 15746, - 15772, - 15793, - 15832, - 15837, - 15866, - 15899, - 15911, - 15918, - 15952, - 15962, - 15967, - 15973, - 15977, - 16016, - 16035, - 16044, - 16067, - 16082, - 16084, - 16098, - 16107, - 16142, - 16149, - 16165, - 16172, - 16178, - 16197, - 16201, - 16215, - 16221, - 16226, - 16232, - 16246, - 16261, - 16279, - 16280, - 16290, - 16314, - 16345, - 16355, - 16361, - 16393, - 16394, - 16438, - 16450, - 16507, - 16523, - 16533, - 16603, - 16648, - 16653, - 16672, - 16682, - 16709, - 16713, - 16719, - 16733, - 16740, - 16761, - 16767, - 16771, - 16788, - 16811, - 16814, - 16816, - 16828, - 16834, - 16863, - 16864, - 16879, - 16888, - 16904, - 16909, - 16921, - 16934, - 16951, - 16983, - 16999, - 17000, - 17006, - 17020, - 17030, - 17033, - 17044, - 17051, - 17072, - 17078, - 17084, - 17087, - 17090, - 17123, - 17132, - 17140, - 17149, - 17157, - 17164, - 17170, - 17179, - 17237, - 17248, - 17260, - 17272, - 17275, - 17287, - 17294, - 17296, - 17305, - 17312, - 17321, - 17367, - 17368, - 17378, - 17433, - 17455, - 17457, - 17508, - 17559, - 17560, - 17582, - 17596, - 17599, - 17613, - 17619, - 17622, - 17655, - 17661, - 17698, - 17712, - 17715, - 17721, - 17722, - 17742, - 17778, - 17818, - 17836, - 17841, - 17856, - 17883, - 17896, - 17901, - 17926, - 17937, - 17992, - 17995, - 17998, - 18021, - 18039, - 18067, - 18122, - 18129, - 18130, - 18142, - 18148, - 18163, - 18192, - 18211, - 18228, - 18264, - 18347, - 18372, - 18409, - 18412, - 18418, - 18423, - 18433, - 18439, - 18445, - 18451, - 18467, - 18502, - 18514, - 18547, - 18575, - 18593, - 18613, - 18620, - 18637, - 18640, - 18712, - 18728, - 18742, - 18748, - 18753, - 18756, - 18771, - 18814, - 18818, - 18827, - 18835, - 18842, - 18854, - 18858, - 18895, - 18914, - 18925, - 18933, - 18937, - 18944, - 18973, - 19001, - 19012, - 19016, - 19027, - 19040, - 19074, - 19085, - 19093, - 19100, - 19107, - 19128, - 19141, - 19142, - 19156, - 19169, - 19176, - 19222, - 19226, - 19247, - 19259, - 19262, - 19291, - 19309, - 19324, - 19334, - 19338, - 19343, - 19376, - 19408, - 19413, - 19420, - 19441, - 19444, - 19454, - 19461, - 19473, - 19479, - 19489, - 19591, - 19605, - 19616, - 19619, - 19653, - 19654, - 19681, - 19711, - 19719, - 19726, - 19738, - 19767, - 19819, - 19864, - 19867, - 19885, - 19894, - 19900, - 19903, - 19941, - 19951, - 19959, - 19966, - 20009, - 20018, - 20020, - 20038, - 20049, - 20066, - 20108, - 20130, - 20132, - 20167, - 20219, - 20227, - 20263, - 20267, - 20272, - 20289, - 20296, - 20307, - 20316, - 20323, - 20335, - 20344, - 20354, - 20360, - 20368, - 20390, - 20402, - 20413, - 20425, - 20428, - 20434, - 20443, - 20488, - 20502, - 20505, - 20535, - 20541, - 20554, - 20577, - 20583, - 20602, - 20611, - 20614, - 20626, - 20628, - 20635, - 20642, - 20674, - 20716, - 20734, - 20765, - 20801, - 20804, - 20808, - 20831, - 20832, - 20862, - 20877, - 20880, - 20885, - 20889, - 20905, - 20914, - 20967, - 21028, - 21031, - 21043, - 21052, - 21058, - 21087, - 21088, - 21093, - 21106, - 21108, - 21118, - 21122, - 21131, - 21139, - 21141, - 21146, - 21162, - 21164, - 21184, - 21208, - 21211, - 21213, - 21230, - 21270, - 21276, - 21285, - 21297, - 21304, - 21310, - 21330, - 21339, - 21346, - 21391, - 21427, - 21451, - 21465, - 21468, - 21471, - 21533, - 21610, - 21615, - 21630, - 21633, - 21657, - 21658, - 21669, - 21670, - 21673, - 21701, - 21719, - 21720, - 21747, - 21819, - 21839, - 21854, - 21857, - 21864, - 21882, - 21900, - 21903, - 21928, - 21931, - 21946, - 21971, - 21974, - 21978, - 21993, - 21994, - 22030, - 22035, - 22063, - 22068, - 22086, - 22104, - 22119, - 22153, - 22168, - 22183, - 22189, - 22204, - 22230, - 22240, - 22246, - 22269, - 22282, - 22302, - 22330, - 22347, - 22349, - 22383, - 22386, - 22432, - 22450, - 22473, - 22487, - 22527, - 22537, - 22557, - 22561, - 22568, - 22573, - 22591, - 22593, - 22605, - 22620, - 22627, - 22636, - 22647, - 22697, - 22715, - 22725, - 22732, - 22749, - 22766, - 22768, - 22771, - 22788, - 22797, - 22822, - 22828, - 22851, - 22888, - 22893, - 22901, - 22902, - 22921, - 22929, - 22946, - 22948, - 22951, - 22958, - 22975, - 22983, - 22990, - 23032, - 23047, - 23053, - 23054, - 23082, - 23095, - 23116, - 23197, - 23221, - 23257, - 23260, - 23263, - 23267, - 23282, - 23284, - 23314, - 23326, - 23335, - 23368, - 23373, - 23401, - 23415, - 23432, - 23476, - 23479, - 23497, - 23505, - 23508, - 23531, - 23536, - 23542, - 23565, - 23573, - 23590, - 23593, - 23604, - 23621, - 23622, - 23636, - 23662, - 23667, - 23703, - 23725, - 23734, - 23738, - 23752, - 23800, - 23803, - 23818, - 23832, - 23842, - 23851, - 23873, - 23883, - 23888, - 23910, - 23934, - 23938, - 23949, - 23955, - 23967, - 23973, - 23991, - 24024, - 24030, - 24039, - 24067, - 24069, - 24084, - 24112, - 24115, - 24184, - 24187, - 24262, - 24276, - 24279, - 24313, - 24331, - 24336, - 24348, - 24367, - 24372, - 24402, - 24420, - 24444, - 24465, - 24466, - 24471, - 24475, - 24481, - 24488, - 24501, - 24514, - 24531, - 24534, - 24559, - 24602, - 24614, - 24637, - 24664, - 24676, - 24679, - 24697, - 24709, - 24714, - 24716, - 24731, - 24744, - 24762, - 24764, - 24769, - 24806, - 24812, - 24872, - 24878, - 24883, - 24909, - 24943, - 24946, - 24964, - 24992, - 25016, - 25022, - 25024, - 25039, - 25051, - 25060, - 25072, - 25097, - 25122, - 25148, - 25194, - 25201, - 25204, - 25238, - 25241, - 25248, - 25257, - 25275, - 25278, - 25304, - 25307, - 25320, - 25334, - 25348, - 25357, - 25372, - 25394, - 25454, - 25465, - 25472, - 25492, - 25505, - 25517, - 25530, - 25558, - 25562, - 25598, - 25609, - 25612, - 25627, - 25651, - 25653, - 25668, - 25711, - 25765, - 25770, - 25775, - 25777, - 25783, - 25801, - 25802, - 25812, - 25821, - 25897, - 25906, - 25929, - 25940, - 25950, - 25968, - 25971, - 25977, - 25994, - 25996, - 25999, - 26001, - 26030, - 26069, - 26100, - 26109, - 26131, - 26144, - 26149, - 26162, - 26167, - 26173, - 26179, - 26193, - 26230, - 26234, - 26246, - 26267, - 26283, - 26300, - 26341, - 26356, - 26377, - 26397, - 26404, - 26411, - 26422, - 26451, - 26454, - 26463, - 26488, - 26498, - 26509, - 26512, - 26517, - 26534, - 26545, - 26546, - 26636, - 26749, - 26753, - 26759, - 26774, - 26789, - 26808, - 26825, - 26831, - 26859, - 26888, - 26918, - 26929, - 26950, - 26954, - 26973, - 26997, - 26998, - 27008, - 27038, - 27109, - 27127, - 27150, - 27168, - 27178, - 27212, - 27224, - 27229, - 27246, - 27251, - 27257, - 27258, - 27260, - 27287, - 27300, - 27315, - 27329, - 27332, - 27349, - 27350, - 27354, - 27359, - 27377, - 27378, - 27383, - 27384, - 27387, - 27392, - 27402, - 27438, - 27481, - 27482, - 27494, - 27531, - 27542, - 27546, - 27564, - 27567, - 27582, - 27608, - 27611, - 27624, - 27629, - 27655, - 27667, - 27676, - 27710, - 27724, - 27745, - 27752, - 27770, - 27779, - 27781, - 27791, - 27809, - 27810, - 27815, - 27827, - 27834, - 27865, - 27899, - 27901, - 27914, - 27950, - 27994, - 28005, - 28009, - 28033, - 28039, - 28060, - 28067, - 28069, - 28099, - 28113, - 28114, - 28139, - 28142, - 28153, - 28166, - 28172, - 28183, - 28194, - 28232, - 28245, - 28246, - 28252, - 28265, - 28301, - 28323, - 28344, - 28362, - 28400, - 28417, - 28454, - 28466, - 28468, - 28477, - 28498, - 28510, - 28513, - 28571, - 28573, - 28578, - 28587, - 28601, - 28646, - 28663, - 28681, - 28682, - 28699, - 28706, - 28708, - 28717, - 28720, - 28735, - 28761, - 28783, - 28788, - 28811, - 28825, - 28838, - 28850, - 28891, - 28897, - 28932, - 28975, - 28998, - 29052, - 29090, - 29096, - 29104, - 29113, - 29133, - 29142, - 29170, - 29192, - 29221, - 29236, - 29246, - 29293, - 29305, - 29312, - 29339, - 29365, - 29389, - 29402, - 29423, - 29443, - 29445, - 29463, - 29473, - 29493, - 29506, - 29518, - 29532, - 29560, - 29590, - 29594, - 29637, - 29647, - 29650, - 29655, - 29661, - 29680, - 29721, - 29751, - 29755, - 29760, - 29772, - 29778, - 29799, - 29824, - 29841, - 29842, - 29853, - 29867, - 29949, - 29950, - 29964, - 29967, - 29985, - 29992, - 30000, - 30020, - 30024, - 30030, - 30066, - 30071, - 30078, - 30082, - 30096, - 30101, - 30102, - 30122, - 30141, - 30159, - 30168, - 30177, - 30183, - 30197, - 30213, - 30231, - 30232, - 30241, - 30253, - 30259, - 30262, - 30268, - 30297, - 30316, - 30322, - 30344, - 30350, - 30355, - 30429, - 30445, - 30477, - 30513, - 30520, - 30540, - 30551, - 30573, - 30609, - 30622, - 30635, - 30658, - 30667, - 30681, - 30684, - 30703, - 30705, - 30715, - 30742, - 30748, - 30758, - 30767, - 30770, - 30772, - 30807, - 30814, - 30824, - 30857, - 30875, - 30931, - 30933, - 30949, - 30953, - 30982, - 31010, - 31012, - 31039, - 31041, - 31061, - 31082, - 31087, - 31096, - 31115, - 31130, - 31168, - 31171, - 31177, - 31180, - 31191, - 31207, - 31247, - 31249, - 31285, - 31303, - 31310, - 31337, - 31352, - 31357, - 31374, - 31379, - 31388, - 31410, - 31416, - 31467, - 31495, - 31504, - 31507, - 31509, - 31514, - 31516, - 31530, - 31555, - 31567, - 31570, - 31586, - 31598, - 31605, - 31609, - 31612, - 31626, - 31634, - 31655, - 31681, - 31705, - 31706, - 31718, - 31735, - 31741, - 31744, - 31762, - 31774, - 31864, - 31874, - 31900, - 31910, - 31928, - 31965, - 31976, - 32016, - 32032, - 32037, - 32062, - 32069, - 32115, - 32128, - 32171, - 32173, - 32182, - 32191, - 32193, - 32194, - 32229, - 32230, - 32248, - 32263, - 32264, - 32269, - 32298, - 32335, - 32340, - 32356, - 32374, - 32390, - 32401, - 32414, - 32417, - 32442, - 32450, - 32461, - 32473, - 32479, - 32530, - 32536, - 32548, - 32577, - 32628, - 32642, - 32665, - 32666, - 32668, - 32696, - 32722, - 32757, - 32758, - -1 }; - //#endif - - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_16 - static long[] PrimitivePolynomialDegree17 = { - 4, - 7, - 16, - 22, - 25, - 31, - 32, - 42, - 52, - 61, - 70, - 76, - 81, - 87, - 93, - 98, - 122, - 133, - 134, - 140, - 146, - 158, - 171, - 176, - 179, - 182, - 191, - 193, - 224, - 227, - 229, - 236, - 248, - 262, - 273, - 276, - 280, - 283, - 290, - 309, - 316, - 319, - 321, - 328, - 346, - 355, - 367, - 369, - 372, - 382, - 388, - 392, - 395, - 397, - 403, - 409, - 410, - 425, - 443, - 472, - 475, - 481, - 488, - 493, - 501, - 515, - 522, - 524, - 527, - 535, - 542, - 545, - 555, - 558, - 560, - 563, - 570, - 578, - 583, - 590, - 597, - 604, - 608, - 614, - 635, - 637, - 653, - 654, - 659, - 666, - 671, - 689, - 690, - 695, - 713, - 722, - 733, - 758, - 770, - 782, - 784, - 793, - 803, - 805, - 812, - 838, - 849, - 875, - 877, - 880, - 892, - 895, - 899, - 919, - 920, - 932, - 935, - 936, - 941, - 950, - 961, - 962, - 971, - 982, - 986, - 1012, - 1021, - 1024, - 1029, - 1030, - 1051, - 1054, - 1064, - 1067, - 1082, - 1096, - 1116, - 1119, - 1129, - 1130, - 1132, - 1137, - 1147, - 1150, - 1154, - 1165, - 1166, - 1174, - 1177, - 1184, - 1194, - 1204, - 1208, - 1213, - 1219, - 1233, - 1264, - 1267, - 1281, - 1312, - 1321, - 1330, - 1332, - 1335, - 1341, - 1356, - 1371, - 1377, - 1380, - 1384, - 1395, - 1397, - 1411, - 1414, - 1426, - 1432, - 1435, - 1437, - 1442, - 1454, - 1468, - 1473, - 1488, - 1491, - 1509, - 1524, - 1533, - 1555, - 1567, - 1571, - 1586, - 1592, - 1595, - 1600, - 1606, - 1627, - 1648, - 1651, - 1654, - 1667, - 1669, - 1674, - 1687, - 1698, - 1710, - 1717, - 1722, - 1735, - 1741, - 1749, - 1750, - 1769, - 1775, - 1777, - 1778, - 1792, - 1797, - 1802, - 1822, - 1825, - 1831, - 1838, - 1852, - 1855, - 1860, - 1867, - 1869, - 1875, - 1882, - 1903, - 1908, - 1917, - 1927, - 1941, - 1945, - 1948, - 1962, - 1975, - 1976, - 1987, - 1993, - 2004, - 2020, - 2029, - 2030, - 2038, - 2041, - 2048, - 2054, - 2057, - 2058, - 2068, - 2072, - 2075, - 2077, - 2082, - 2084, - 2087, - 2101, - 2111, - 2113, - 2119, - 2147, - 2154, - 2161, - 2164, - 2177, - 2178, - 2184, - 2198, - 2201, - 2213, - 2217, - 2228, - 2240, - 2245, - 2250, - 2263, - 2267, - 2285, - 2286, - 2291, - 2298, - 2306, - 2325, - 2329, - 2332, - 2335, - 2339, - 2346, - 2351, - 2353, - 2363, - 2378, - 2383, - 2391, - 2401, - 2408, - 2414, - 2419, - 2428, - 2441, - 2444, - 2461, - 2480, - 2483, - 2486, - 2489, - 2490, - 2518, - 2527, - 2540, - 2558, - 2567, - 2571, - 2574, - 2579, - 2585, - 2615, - 2639, - 2641, - 2644, - 2663, - 2667, - 2669, - 2672, - 2687, - 2700, - 2705, - 2724, - 2728, - 2733, - 2741, - 2748, - 2751, - 2756, - 2771, - 2774, - 2793, - 2796, - 2804, - 2814, - 2822, - 2845, - 2846, - 2850, - 2855, - 2856, - 2867, - 2891, - 2894, - 2902, - 2908, - 2951, - 2970, - 2972, - 2975, - 2976, - 2981, - 2986, - 2999, - 3000, - 3006, - 3014, - 3028, - 3031, - 3035, - 3037, - 3053, - 3059, - 3065, - 3080, - 3091, - 3094, - 3109, - 3110, - 3113, - 3116, - 3136, - 3139, - 3141, - 3154, - 3160, - 3169, - 3182, - 3187, - 3189, - 3190, - 3203, - 3217, - 3229, - 3236, - 3248, - 3257, - 3278, - 3283, - 3289, - 3292, - 3302, - 3316, - 3328, - 3333, - 3337, - 3340, - 3368, - 3371, - 3376, - 3385, - 3386, - 3393, - 3399, - 3405, - 3414, - 3433, - 3436, - 3448, - 3467, - 3469, - 3472, - 3477, - 3484, - 3494, - 3505, - 3515, - 3523, - 3530, - 3543, - 3559, - 3568, - 3577, - 3578, - 3594, - 3601, - 3607, - 3608, - 3620, - 3629, - 3644, - 3656, - 3664, - 3670, - 3680, - 3685, - 3686, - 3695, - 3698, - 3703, - 3710, - 3714, - 3726, - 3731, - 3733, - 3737, - 3756, - 3759, - 3767, - 3776, - 3785, - 3793, - 3812, - 3815, - 3824, - 3844, - 3859, - 3866, - 3872, - 3884, - 3889, - 3899, - 3902, - 3909, - 3913, - 3933, - 3938, - 3949, - 3952, - 3980, - 3991, - 3992, - 4002, - 4008, - 4011, - 4016, - 4034, - 4036, - 4063, - 4067, - 4073, - 4082, - 4091, - 4093, - 4101, - 4113, - 4120, - 4125, - 4126, - 4139, - 4142, - 4144, - 4147, - 4153, - 4154, - 4164, - 4174, - 4182, - 4185, - 4188, - 4191, - 4195, - 4219, - 4225, - 4228, - 4232, - 4246, - 4255, - 4274, - 4283, - 4286, - 4306, - 4311, - 4317, - 4321, - 4324, - 4331, - 4333, - 4359, - 4360, - 4368, - 4373, - 4389, - 4394, - 4413, - 4422, - 4431, - 4436, - 4440, - 4445, - 4452, - 4462, - 4469, - 4470, - 4473, - 4479, - 4480, - 4483, - 4489, - 4503, - 4519, - 4520, - 4525, - 4526, - 4533, - 4552, - 4581, - 4585, - 4591, - 4594, - 4596, - 4599, - 4612, - 4621, - 4630, - 4636, - 4640, - 4649, - 4650, - 4660, - 4677, - 4687, - 4696, - 4701, - 4705, - 4706, - 4711, - 4720, - 4723, - 4732, - 4736, - 4742, - 4748, - 4754, - 4759, - 4769, - 4787, - 4807, - 4814, - 4837, - 4867, - 4873, - 4879, - 4884, - 4898, - 4907, - 4910, - 4918, - 4924, - 4953, - 4956, - 4965, - 4966, - 4970, - 4972, - 4983, - 4989, - 4994, - 5000, - 5005, - 5014, - 5018, - 5023, - 5039, - 5053, - 5054, - 5061, - 5065, - 5080, - 5083, - 5107, - 5119, - 5146, - 5151, - 5152, - 5155, - 5169, - 5170, - 5176, - 5179, - 5182, - 5189, - 5193, - 5196, - 5204, - 5207, - 5211, - 5220, - 5258, - 5265, - 5271, - 5277, - 5278, - 5282, - 5296, - 5299, - 5319, - 5328, - 5343, - 5353, - 5364, - 5368, - 5379, - 5381, - 5399, - 5415, - 5422, - 5441, - 5451, - 5456, - 5462, - 5490, - 5495, - 5501, - 5502, - 5505, - 5512, - 5523, - 5529, - 5548, - 5551, - 5553, - 5565, - 5568, - 5577, - 5578, - 5583, - 5585, - 5588, - 5613, - 5614, - 5616, - 5622, - 5631, - 5637, - 5638, - 5668, - 5675, - 5683, - 5695, - 5703, - 5710, - 5715, - 5727, - 5738, - 5752, - 5767, - 5773, - 5776, - 5781, - 5791, - 5792, - 5795, - 5798, - 5801, - 5810, - 5812, - 5836, - 5839, - 5841, - 5867, - 5870, - 5877, - 5881, - 5899, - 5914, - 5925, - 5929, - 5943, - 5949, - 5962, - 5969, - 5976, - 5988, - 5997, - 6006, - 6010, - 6016, - 6022, - 6026, - 6031, - 6040, - 6043, - 6050, - 6059, - 6079, - 6099, - 6101, - 6105, - 6108, - 6124, - 6132, - 6145, - 6146, - 6151, - 6152, - 6158, - 6160, - 6163, - 6165, - 6170, - 6182, - 6196, - 6199, - 6200, - 6205, - 6226, - 6228, - 6237, - 6247, - 6251, - 6253, - 6256, - 6268, - 6272, - 6275, - 6281, - 6289, - 6335, - 6338, - 6355, - 6362, - 6373, - 6386, - 6388, - 6391, - 6397, - 6405, - 6406, - 6410, - 6417, - 6443, - 6457, - 6468, - 6475, - 6486, - 6489, - 6495, - 6499, - 6505, - 6511, - 6520, - 6529, - 6542, - 6547, - 6550, - 6554, - 6556, - 6560, - 6569, - 6572, - 6590, - 6592, - 6601, - 6610, - 6632, - 6635, - 6640, - 6643, - 6649, - 6659, - 6662, - 6666, - 6690, - 6692, - 6704, - 6713, - 6728, - 6731, - 6734, - 6746, - 6755, - 6757, - 6764, - 6772, - 6792, - 6797, - 6821, - 6822, - 6831, - 6834, - 6851, - 6858, - 6860, - 6871, - 6875, - 6884, - 6888, - 6894, - 6919, - 6940, - 6950, - 6959, - 6968, - 6981, - 6988, - 6996, - 6999, - 7015, - 7019, - 7022, - 7040, - 7045, - 7049, - 7055, - 7073, - 7076, - 7085, - 7091, - 7103, - 7112, - 7117, - 7118, - 7123, - 7126, - 7154, - 7180, - 7192, - 7195, - 7207, - 7208, - 7214, - 7222, - 7234, - 7254, - 7258, - 7264, - 7279, - 7282, - 7293, - 7297, - 7322, - 7324, - 7351, - 7363, - 7380, - 7384, - 7389, - 7396, - 7413, - 7417, - 7431, - 7443, - 7445, - 7450, - 7456, - 7466, - 7468, - 7474, - 7479, - 7486, - 7497, - 7508, - 7515, - 7533, - 7542, - 7546, - 7551, - 7569, - 7572, - 7595, - 7603, - 7605, - 7629, - 7632, - 7638, - 7648, - 7654, - 7663, - 7675, - 7693, - 7705, - 7717, - 7724, - 7727, - 7735, - 7761, - 7767, - 7783, - 7784, - 7798, - 7802, - 7811, - 7817, - 7823, - 7832, - 7837, - 7842, - 7853, - 7854, - 7856, - 7861, - 7862, - 7873, - 7874, - 7886, - 7914, - 7927, - 7936, - 7951, - 7963, - 7966, - 7976, - 7993, - 8001, - 8004, - 8013, - 8021, - 8026, - 8028, - 8031, - 8035, - 8042, - 8071, - 8085, - 8092, - 8102, - 8105, - 8114, - 8123, - 8131, - 8140, - 8145, - 8157, - 8158, - 8185, - 8186, - 8188, - 8192, - 8212, - 8219, - 8221, - 8235, - 8237, - 8249, - 8260, - 8264, - 8270, - 8282, - 8291, - 8293, - 8297, - 8298, - 8305, - 8306, - 8311, - 8318, - 8327, - 8345, - 8379, - 8390, - 8394, - 8414, - 8417, - 8432, - 8437, - 8441, - 8449, - 8456, - 8473, - 8489, - 8495, - 8522, - 8524, - 8529, - 8545, - 8557, - 8565, - 8572, - 8576, - 8582, - 8594, - 8629, - 8636, - 8668, - 8678, - 8701, - 8702, - 8708, - 8712, - 8745, - 8754, - 8759, - 8763, - 8766, - 8780, - 8783, - 8786, - 8798, - 8804, - 8819, - 8826, - 8835, - 8838, - 8856, - 8862, - 8871, - 8875, - 8890, - 8892, - 8898, - 8927, - 8928, - 8945, - 8952, - 8955, - 8965, - 8972, - 8977, - 8990, - 8996, - 9025, - 9037, - 9040, - 9049, - 9062, - 9068, - 9076, - 9079, - 9099, - 9107, - 9114, - 9123, - 9126, - 9137, - 9149, - 9150, - 9155, - 9161, - 9162, - 9167, - 9172, - 9186, - 9188, - 9191, - 9198, - 9200, - 9205, - 9206, - 9215, - 9227, - 9232, - 9241, - 9244, - 9251, - 9254, - 9275, - 9283, - 9285, - 9303, - 9304, - 9313, - 9314, - 9320, - 9328, - 9333, - 9337, - 9338, - 9340, - 9353, - 9356, - 9364, - 9373, - 9374, - 9378, - 9380, - 9389, - 9395, - 9412, - 9422, - 9439, - 9450, - 9452, - 9482, - 9487, - 9489, - 9499, - 9501, - 9508, - 9515, - 9518, - 9520, - 9526, - 9537, - 9552, - 9571, - 9588, - 9613, - 9619, - 9622, - 9637, - 9652, - 9655, - 9661, - 9664, - 9669, - 9681, - 9682, - 9688, - 9697, - 9700, - 9715, - 9722, - 9727, - 9734, - 9740, - 9743, - 9745, - 9757, - 9761, - 9762, - 9767, - 9768, - 9774, - 9786, - 9796, - 9820, - 9823, - 9839, - 9844, - 9851, - 9853, - 9863, - 9864, - 9877, - 9884, - 9888, - 9897, - 9915, - 9925, - 9949, - 9954, - 9960, - 9965, - 9978, - 9986, - 9992, - 9995, - 10005, - 10026, - 10031, - 10040, - 10051, - 10057, - 10072, - 10096, - 10102, - 10105, - 10115, - 10124, - 10139, - 10145, - 10148, - 10157, - 10158, - 10163, - 10180, - 10187, - 10198, - 10208, - 10214, - 10220, - 10237, - 10238, - 10241, - 10244, - 10251, - 10253, - 10256, - 10259, - 10266, - 10284, - 10290, - 10331, - 10334, - 10350, - 10355, - 10357, - 10367, - 10368, - 10377, - 10388, - 10407, - 10421, - 10434, - 10439, - 10440, - 10443, - 10446, - 10457, - 10469, - 10476, - 10479, - 10481, - 10494, - 10501, - 10505, - 10516, - 10532, - 10541, - 10547, - 10550, - 10591, - 10597, - 10602, - 10610, - 10619, - 10631, - 10646, - 10655, - 10665, - 10673, - 10674, - 10680, - 10693, - 10700, - 10721, - 10727, - 10746, - 10748, - 10757, - 10761, - 10770, - 10776, - 10782, - 10791, - 10792, - 10805, - 10810, - 10832, - 10835, - 10841, - 10842, - 10847, - 10853, - 10860, - 10871, - 10878, - 10881, - 10888, - 10894, - 10901, - 10915, - 10918, - 10922, - 10936, - 10954, - 10968, - 10971, - 10973, - 10978, - 10998, - 11009, - 11021, - 11029, - 11030, - 11034, - 11050, - 11063, - 11064, - 11077, - 11078, - 11105, - 11106, - 11126, - 11129, - 11135, - 11151, - 11159, - 11165, - 11176, - 11179, - 11182, - 11189, - 11204, - 11216, - 11232, - 11235, - 11242, - 11250, - 11264, - 11273, - 11282, - 11288, - 11291, - 11293, - 11318, - 11321, - 11329, - 11336, - 11339, - 11342, - 11356, - 11383, - 11389, - 11405, - 11411, - 11423, - 11424, - 11430, - 11444, - 11447, - 11459, - 11465, - 11473, - 11479, - 11501, - 11510, - 11514, - 11522, - 11527, - 11533, - 11536, - 11548, - 11551, - 11552, - 11555, - 11572, - 11587, - 11601, - 11613, - 11614, - 11618, - 11624, - 11630, - 11663, - 11682, - 11684, - 11702, - 11705, - 11713, - 11731, - 11734, - 11740, - 11747, - 11754, - 11761, - 11762, - 11787, - 11792, - 11814, - 11823, - 11825, - 11837, - 11838, - 11846, - 11855, - 11864, - 11876, - 11885, - 11904, - 11909, - 11913, - 11916, - 11940, - 11943, - 11972, - 11981, - 11990, - 11993, - 12000, - 12005, - 12015, - 12020, - 12038, - 12042, - 12056, - 12065, - 12066, - 12072, - 12080, - 12083, - 12090, - 12092, - 12103, - 12109, - 12112, - 12117, - 12121, - 12137, - 12143, - 12145, - 12148, - 12168, - 12174, - 12188, - 12191, - 12192, - 12201, - 12224, - 12230, - 12239, - 12242, - 12251, - 12258, - 12264, - 12310, - 12319, - 12323, - 12325, - 12332, - 12343, - 12344, - 12352, - 12370, - 12388, - 12395, - 12403, - 12409, - 12410, - 12415, - 12419, - 12426, - 12439, - 12445, - 12459, - 12464, - 12474, - 12484, - 12491, - 12501, - 12505, - 12508, - 12511, - 12521, - 12522, - 12530, - 12544, - 12547, - 12561, - 12571, - 12580, - 12597, - 12607, - 12609, - 12610, - 12616, - 12621, - 12624, - 12639, - 12645, - 12652, - 12655, - 12660, - 12667, - 12686, - 12688, - 12697, - 12700, - 12707, - 12710, - 12719, - 12739, - 12742, - 12746, - 12754, - 12765, - 12772, - 12784, - 12789, - 12800, - 12805, - 12809, - 12815, - 12827, - 12830, - 12833, - 12840, - 12851, - 12868, - 12871, - 12886, - 12899, - 12923, - 12926, - 12932, - 12935, - 12939, - 12942, - 12953, - 12959, - 12960, - 13002, - 13004, - 13016, - 13021, - 13035, - 13038, - 13052, - 13058, - 13069, - 13082, - 13093, - 13094, - 13100, - 13115, - 13125, - 13132, - 13143, - 13144, - 13153, - 13160, - 13165, - 13173, - 13174, - 13187, - 13190, - 13204, - 13218, - 13247, - 13250, - 13262, - 13267, - 13274, - 13304, - 13309, - 13315, - 13317, - 13324, - 13332, - 13342, - 13346, - 13355, - 13358, - 13360, - 13369, - 13372, - 13398, - 13404, - 13407, - 13414, - 13426, - 13432, - 13466, - 13481, - 13490, - 13496, - 13504, - 13516, - 13527, - 13533, - 13537, - 13552, - 13561, - 13567, - 13582, - 13587, - 13589, - 13593, - 13596, - 13615, - 13617, - 13623, - 13641, - 13647, - 13650, - 13659, - 13671, - 13677, - 13678, - 13680, - 13685, - 13689, - 13701, - 13706, - 13720, - 13729, - 13735, - 13736, - 13756, - 13759, - 13761, - 13771, - 13782, - 13786, - 13798, - 13810, - 13819, - 13826, - 13831, - 13837, - 13846, - 13856, - 13862, - 13866, - 13885, - 13891, - 13893, - 13905, - 13908, - 13912, - 13917, - 13918, - 13946, - 13948, - 13964, - 13970, - 13975, - 13979, - 13997, - 14000, - 14006, - 14020, - 14023, - 14024, - 14029, - 14035, - 14044, - 14047, - 14058, - 14066, - 14075, - 14080, - 14095, - 14100, - 14114, - 14116, - 14123, - 14134, - 14143, - 14151, - 14160, - 14163, - 14179, - 14181, - 14193, - 14209, - 14210, - 14224, - 14245, - 14249, - 14255, - 14267, - 14270, - 14277, - 14305, - 14308, - 14312, - 14325, - 14332, - 14345, - 14354, - 14372, - 14387, - 14390, - 14402, - 14408, - 14413, - 14431, - 14438, - 14447, - 14455, - 14461, - 14466, - 14480, - 14490, - 14492, - 14508, - 14513, - 14516, - 14519, - 14525, - 14534, - 14537, - 14543, - 14545, - 14552, - 14562, - 14571, - 14574, - 14582, - 14611, - 14614, - 14620, - 14633, - 14641, - 14648, - 14671, - 14674, - 14689, - 14690, - 14692, - 14699, - 14710, - 14719, - 14730, - 14732, - 14743, - 14744, - 14750, - 14759, - 14763, - 14768, - 14773, - 14777, - 14786, - 14795, - 14800, - 14812, - 14816, - 14836, - 14840, - 14856, - 14859, - 14870, - 14873, - 14879, - 14880, - 14889, - 14892, - 14895, - 14900, - 14903, - 14910, - 14912, - 14942, - 14948, - 14957, - 14963, - 14975, - 14985, - 14993, - 15003, - 15010, - 15022, - 15039, - 15041, - 15047, - 15048, - 15056, - 15066, - 15068, - 15075, - 15077, - 15082, - 15096, - 15102, - 15116, - 15122, - 15127, - 15133, - 15137, - 15138, - 15149, - 15152, - 15155, - 15158, - 15187, - 15189, - 15190, - 15196, - 15199, - 15205, - 15212, - 15236, - 15243, - 15246, - 15260, - 15267, - 15274, - 15279, - 15281, - 15282, - 15284, - 15291, - 15293, - 15302, - 15319, - 15329, - 15336, - 15347, - 15353, - 15361, - 15371, - 15397, - 15404, - 15407, - 15421, - 15433, - 15441, - 15442, - 15463, - 15472, - 15478, - 15488, - 15493, - 15498, - 15511, - 15521, - 15534, - 15539, - 15541, - 15560, - 15563, - 15574, - 15578, - 15584, - 15593, - 15604, - 15614, - 15619, - 15622, - 15633, - 15639, - 15646, - 15673, - 15674, - 15684, - 15691, - 15694, - 15696, - 15701, - 15705, - 15715, - 15729, - 15730, - 15741, - 15745, - 15748, - 15757, - 15765, - 15766, - 15775, - 15776, - 15779, - 15786, - 15788, - 15813, - 15814, - 15842, - 15851, - 15862, - 15875, - 15878, - 15889, - 15896, - 15901, - 15908, - 15911, - 15915, - 15938, - 15944, - 15950, - 15955, - 15974, - 15978, - 15980, - 15983, - 15991, - 16004, - 16011, - 16016, - 16019, - 16025, - 16041, - 16064, - 16067, - 16074, - 16082, - 16103, - 16109, - 16122, - 16149, - 16170, - 16175, - 16178, - 16189, - 16202, - 16204, - 16222, - 16231, - 16238, - 16262, - 16265, - 16276, - 16285, - 16313, - 16314, - 16321, - 16327, - 16333, - 16334, - 16364, - 16369, - 16370, - 16375, - 16376, - 16379, - 16393, - 16402, - 16408, - 16418, - 16438, - 16441, - 16447, - 16450, - 16455, - 16459, - 16483, - 16490, - 16492, - 16495, - 16523, - 16528, - 16543, - 16553, - 16562, - 16564, - 16576, - 16588, - 16612, - 16630, - 16654, - 16656, - 16668, - 16672, - 16675, - 16678, - 16681, - 16689, - 16699, - 16719, - 16734, - 16737, - 16750, - 16752, - 16757, - 16761, - 16773, - 16774, - 16801, - 16802, - 16822, - 16831, - 16840, - 16854, - 16858, - 16863, - 16867, - 16876, - 16891, - 16894, - 16898, - 16907, - 16915, - 16917, - 16922, - 16924, - 16933, - 16938, - 16952, - 16960, - 16963, - 16969, - 16978, - 17014, - 17020, - 17034, - 17036, - 17042, - 17047, - 17051, - 17054, - 17063, - 17069, - 17075, - 17077, - 17089, - 17090, - 17107, - 17126, - 17135, - 17150, - 17162, - 17169, - 17172, - 17175, - 17176, - 17191, - 17209, - 17218, - 17220, - 17227, - 17229, - 17238, - 17251, - 17257, - 17258, - 17272, - 17277, - 17308, - 17311, - 17321, - 17329, - 17342, - 17344, - 17350, - 17356, - 17371, - 17374, - 17392, - 17402, - 17410, - 17421, - 17424, - 17427, - 17434, - 17449, - 17452, - 17463, - 17470, - 17477, - 17482, - 17490, - 17496, - 17508, - 17511, - 17536, - 17563, - 17570, - 17581, - 17590, - 17608, - 17616, - 17621, - 17628, - 17644, - 17649, - 17652, - 17679, - 17691, - 17693, - 17697, - 17698, - 17700, - 17704, - 17707, - 17715, - 17718, - 17721, - 17722, - 17727, - 17729, - 17747, - 17754, - 17756, - 17760, - 17765, - 17778, - 17784, - 17794, - 17805, - 17806, - 17817, - 17824, - 17839, - 17842, - 17844, - 17851, - 17862, - 17868, - 17871, - 17873, - 17896, - 17904, - 17909, - 17920, - 17923, - 17947, - 17950, - 17956, - 17959, - 17966, - 17971, - 17973, - 17992, - 18006, - 18009, - 18010, - 18022, - 18039, - 18046, - 18069, - 18074, - 18076, - 18085, - 18086, - 18095, - 18100, - 18109, - 18121, - 18127, - 18129, - 18132, - 18141, - 18146, - 18151, - 18157, - 18160, - 18183, - 18204, - 18218, - 18226, - 18238, - 18245, - 18249, - 18260, - 18267, - 18270, - 18273, - 18274, - 18276, - 18283, - 18307, - 18314, - 18321, - 18334, - 18355, - 18364, - 18372, - 18390, - 18399, - 18415, - 18420, - 18434, - 18443, - 18446, - 18460, - 18467, - 18482, - 18484, - 18501, - 18506, - 18516, - 18519, - 18547, - 18569, - 18575, - 18589, - 18590, - 18605, - 18611, - 18625, - 18652, - 18665, - 18673, - 18674, - 18683, - 18688, - 18691, - 18698, - 18717, - 18733, - 18754, - 18759, - 18760, - 18771, - 18777, - 18796, - 18799, - 18807, - 18813, - 18817, - 18820, - 18827, - 18829, - 18838, - 18842, - 18848, - 18853, - 18885, - 18890, - 18898, - 18903, - 18910, - 18913, - 18931, - 18934, - 18956, - 18961, - 18968, - 18978, - 18983, - 18987, - 18992, - 18997, - 19002, - 19004, - 19010, - 19012, - 19030, - 19043, - 19049, - 19079, - 19086, - 19100, - 19103, - 19107, - 19109, - 19113, - 19116, - 19127, - 19134, - 19141, - 19179, - 19193, - 19194, - 19201, - 19208, - 19214, - 19225, - 19226, - 19235, - 19242, - 19264, - 19267, - 19293, - 19309, - 19318, - 19324, - 19337, - 19340, - 19345, - 19346, - 19352, - 19364, - 19382, - 19391, - 19405, - 19411, - 19439, - 19442, - 19444, - 19451, - 19465, - 19471, - 19474, - 19476, - 19479, - 19485, - 19489, - 19496, - 19507, - 19513, - 19514, - 19521, - 19524, - 19546, - 19552, - 19555, - 19557, - 19575, - 19579, - 19591, - 19595, - 19605, - 19615, - 19616, - 19626, - 19631, - 19634, - 19640, - 19645, - 19678, - 19681, - 19682, - 19706, - 19708, - 19713, - 19714, - 19720, - 19725, - 19743, - 19753, - 19756, - 19759, - 19762, - 19776, - 19786, - 19799, - 19800, - 19803, - 19806, - 19815, - 19816, - 19857, - 19860, - 19874, - 19883, - 19885, - 19886, - 19893, - 19932, - 19960, - 19972, - 19975, - 20005, - 20009, - 20010, - 20012, - 20023, - 20024, - 20030, - 20038, - 20041, - 20055, - 20059, - 20061, - 20080, - 20086, - 20089, - 20095, - 20111, - 20116, - 20130, - 20136, - 20147, - 20153, - 20156, - 20167, - 20173, - 20182, - 20185, - 20202, - 20209, - 20229, - 20233, - 20236, - 20241, - 20242, - 20248, - 20278, - 20282, - 20299, - 20307, - 20313, - 20314, - 20320, - 20326, - 20332, - 20350, - 20360, - 20371, - 20373, - 20377, - 20390, - 20396, - 20404, - 20413, - 20434, - 20436, - 20440, - 20443, - 20445, - 20464, - 20476, - 20494, - 20496, - 20501, - 20518, - 20527, - 20529, - 20535, - 20544, - 20568, - 20589, - 20592, - 20601, - 20617, - 20625, - 20626, - 20632, - 20638, - 20644, - 20647, - 20662, - 20671, - 20674, - 20683, - 20704, - 20724, - 20742, - 20748, - 20765, - 20776, - 20789, - 20796, - 20802, - 20807, - 20814, - 20821, - 20832, - 20835, - 20847, - 20859, - 20871, - 20883, - 20886, - 20892, - 20906, - 20908, - 20957, - 20962, - 20968, - 20979, - 20991, - 20998, - 21007, - 21010, - 21026, - 21037, - 21038, - 21045, - 21057, - 21082, - 21093, - 21094, - 21105, - 21117, - 21121, - 21124, - 21136, - 21139, - 21142, - 21145, - 21167, - 21170, - 21175, - 21179, - 21182, - 21193, - 21194, - 21207, - 21217, - 21224, - 21244, - 21247, - 21252, - 21264, - 21273, - 21289, - 21290, - 21295, - 21297, - 21309, - 21318, - 21322, - 21324, - 21329, - 21332, - 21336, - 21342, - 21351, - 21355, - 21363, - 21372, - 21382, - 21388, - 21394, - 21403, - 21409, - 21416, - 21421, - 21424, - 21444, - 21453, - 21466, - 21471, - 21495, - 21499, - 21504, - 21507, - 21521, - 21527, - 21555, - 21558, - 21562, - 21570, - 21576, - 21579, - 21581, - 21587, - 21590, - 21599, - 21605, - 21612, - 21618, - 21630, - 21639, - 21640, - 21643, - 21648, - 21669, - 21679, - 21681, - 21687, - 21688, - 21706, - 21713, - 21714, - 21716, - 21730, - 21732, - 21749, - 21756, - 21774, - 21779, - 21781, - 21786, - 21792, - 21810, - 21819, - 21829, - 21830, - 21844, - 21853, - 21867, - 21869, - 21882, - 21891, - 21898, - 21917, - 21934, - 21946, - 21948, - 21963, - 21966, - 21968, - 21973, - 21977, - 21980, - 21984, - 21994, - 21999, - 22018, - 22020, - 22029, - 22032, - 22041, - 22047, - 22048, - 22071, - 22075, - 22078, - 22083, - 22089, - 22097, - 22110, - 22113, - 22119, - 22120, - 22126, - 22133, - 22134, - 22140, - 22147, - 22161, - 22164, - 22173, - 22197, - 22207, - 22210, - 22216, - 22234, - 22257, - 22264, - 22278, - 22284, - 22287, - 22299, - 22301, - 22308, - 22337, - 22349, - 22350, - 22357, - 22364, - 22373, - 22377, - 22380, - 22386, - 22391, - 22392, - 22411, - 22422, - 22425, - 22431, - 22438, - 22441, - 22442, - 22449, - 22452, - 22461, - 22467, - 22479, - 22484, - 22487, - 22493, - 22510, - 22521, - 22533, - 22534, - 22543, - 22548, - 22552, - 22558, - 22561, - 22562, - 22568, - 22571, - 22574, - 22581, - 22594, - 22603, - 22605, - 22606, - 22623, - 22630, - 22651, - 22657, - 22669, - 22670, - 22677, - 22682, - 22698, - 22712, - 22715, - 22729, - 22732, - 22735, - 22738, - 22740, - 22750, - 22753, - 22760, - 22765, - 22768, - 22778, - 22785, - 22809, - 22810, - 22812, - 22828, - 22840, - 22845, - 22848, - 22857, - 22877, - 22882, - 22887, - 22894, - 22912, - 22930, - 22936, - 22939, - 22957, - 22970, - 22980, - 22984, - 22992, - 22998, - 23001, - 23044, - 23061, - 23062, - 23071, - 23075, - 23089, - 23090, - 23096, - 23101, - 23114, - 23121, - 23124, - 23127, - 23128, - 23137, - 23138, - 23150, - 23155, - 23168, - 23173, - 23174, - 23195, - 23202, - 23225, - 23226, - 23239, - 23253, - 23263, - 23264, - 23281, - 23282, - 23288, - 23294, - 23302, - 23311, - 23320, - 23325, - 23356, - 23374, - 23388, - 23402, - 23415, - 23421, - 23426, - 23443, - 23446, - 23455, - 23461, - 23468, - 23471, - 23485, - 23486, - 23488, - 23498, - 23500, - 23515, - 23521, - 23527, - 23534, - 23546, - 23559, - 23560, - 23566, - 23584, - 23587, - 23594, - 23602, - 23607, - 23616, - 23621, - 23631, - 23634, - 23636, - 23649, - 23652, - 23679, - 23686, - 23697, - 23703, - 23714, - 23719, - 23723, - 23726, - 23728, - 23733, - 23740, - 23751, - 23755, - 23765, - 23766, - 23769, - 23779, - 23794, - 23796, - 23803, - 23813, - 23820, - 23841, - 23853, - 23861, - 23862, - 23873, - 23876, - 23897, - 23898, - 23903, - 23904, - 23910, - 23931, - 23933, - 23934, - 23943, - 23952, - 23955, - 23962, - 23971, - 23978, - 23998, - 24003, - 24009, - 24017, - 24045, - 24046, - 24060, - 24064, - 24076, - 24079, - 24087, - 24094, - 24100, - 24118, - 24121, - 24132, - 24147, - 24165, - 24172, - 24177, - 24184, - 24187, - 24213, - 24217, - 24223, - 24230, - 24234, - 24241, - 24248, - 24259, - 24262, - 24271, - 24279, - 24286, - 24289, - 24295, - 24296, - 24299, - 24314, - 24336, - 24342, - 24346, - 24357, - 24367, - 24370, - 24372, - 24387, - 24389, - 24402, - 24414, - 24420, - 24435, - 24437, - 24442, - 24444, - 24447, - 24468, - 24475, - 24484, - 24493, - 24494, - 24496, - 24514, - 24519, - 24533, - 24538, - 24559, - 24568, - 24573, - 24577, - 24587, - 24592, - 24601, - 24602, - 24608, - 24645, - 24650, - 24657, - 24664, - 24670, - 24673, - 24676, - 24680, - 24686, - 24700, - 24704, - 24714, - 24728, - 24731, - 24733, - 24747, - 24749, - 24750, - 24764, - 24782, - 24784, - 24793, - 24794, - 24810, - 24817, - 24820, - 24823, - 24832, - 24855, - 24859, - 24862, - 24877, - 24890, - 24900, - 24904, - 24909, - 24910, - 24915, - 24922, - 24937, - 24945, - 24962, - 24964, - 24991, - 24992, - 24995, - 25001, - 25009, - 25019, - 25021, - 25029, - 25034, - 25036, - 25039, - 25057, - 25063, - 25064, - 25075, - 25077, - 25084, - 25088, - 25091, - 25105, - 25134, - 25165, - 25183, - 25184, - 25202, - 25204, - 25211, - 25223, - 25224, - 25235, - 25241, - 25253, - 25258, - 25277, - 25278, - 25280, - 25290, - 25295, - 25300, - 25307, - 25319, - 25323, - 25326, - 25333, - 25334, - 25337, - 25348, - 25351, - 25372, - 25381, - 25403, - 25406, - 25431, - 25437, - 25453, - 25459, - 25462, - 25466, - 25477, - 25484, - 25495, - 25501, - 25506, - 25511, - 25515, - 25525, - 25529, - 25532, - 25538, - 25549, - 25552, - 25564, - 25567, - 25574, - 25577, - 25583, - 25588, - 25603, - 25610, - 25615, - 25624, - 25636, - 25639, - 25643, - 25645, - 25648, - 25671, - 25678, - 25689, - 25708, - 25716, - 25725, - 25730, - 25739, - 25747, - 25753, - 25790, - 25797, - 25804, - 25809, - 25816, - 25825, - 25831, - 25845, - 25846, - 25867, - 25870, - 25897, - 25908, - 25937, - 25940, - 25944, - 25949, - 25954, - 25960, - 25963, - 25966, - 25978, - 25996, - 26007, - 26011, - 26027, - 26032, - 26038, - 26049, - 26052, - 26055, - 26085, - 26089, - 26090, - 26098, - 26104, - 26110, - 26113, - 26126, - 26133, - 26138, - 26140, - 26156, - 26159, - 26176, - 26186, - 26203, - 26210, - 26222, - 26224, - 26229, - 26233, - 26236, - 26239, - 26267, - 26291, - 26293, - 26298, - 26303, - 26308, - 26312, - 26315, - 26342, - 26354, - 26363, - 26365, - 26383, - 26391, - 26398, - 26416, - 26421, - 26425, - 26434, - 26439, - 26453, - 26454, - 26470, - 26491, - 26493, - 26500, - 26509, - 26518, - 26531, - 26533, - 26540, - 26552, - 26566, - 26569, - 26583, - 26590, - 26596, - 26624, - 26636, - 26667, - 26669, - 26672, - 26675, - 26687, - 26689, - 26696, - 26702, - 26714, - 26716, - 26729, - 26732, - 26737, - 26747, - 26773, - 26780, - 26801, - 26811, - 26813, - 26831, - 26836, - 26839, - 26849, - 26862, - 26869, - 26873, - 26874, - 26888, - 26891, - 26896, - 26899, - 26912, - 26921, - 26935, - 26941, - 26949, - 26954, - 26967, - 26977, - 27011, - 27018, - 27026, - 27028, - 27032, - 27044, - 27053, - 27062, - 27065, - 27068, - 27080, - 27083, - 27093, - 27098, - 27107, - 27110, - 27114, - 27121, - 27127, - 27137, - 27144, - 27155, - 27171, - 27178, - 27180, - 27185, - 27191, - 27192, - 27195, - 27212, - 27215, - 27218, - 27230, - 27234, - 27245, - 27248, - 27263, - 27279, - 27288, - 27294, - 27303, - 27304, - 27312, - 27330, - 27341, - 27342, - 27344, - 27353, - 27356, - 27366, - 27369, - 27377, - 27387, - 27409, - 27437, - 27443, - 27446, - 27450, - 27452, - 27457, - 27472, - 27475, - 27487, - 27488, - 27493, - 27506, - 27508, - 27521, - 27522, - 27527, - 27536, - 27539, - 27541, - 27546, - 27557, - 27564, - 27572, - 27576, - 27584, - 27608, - 27611, - 27618, - 27620, - 27627, - 27630, - 27637, - 27638, - 27641, - 27647, - 27650, - 27676, - 27683, - 27690, - 27695, - 27700, - 27704, - 27709, - 27715, - 27727, - 27745, - 27763, - 27769, - 27770, - 27796, - 27810, - 27812, - 27834, - 27847, - 27848, - 27862, - 27868, - 27881, - 27884, - 27890, - 27895, - 27904, - 27914, - 27919, - 27921, - 27931, - 27933, - 27938, - 27943, - 27949, - 28005, - 28012, - 28017, - 28024, - 28030, - 28034, - 28045, - 28048, - 28054, - 28063, - 28069, - 28070, - 28073, - 28084, - 28096, - 28114, - 28126, - 28141, - 28149, - 28165, - 28177, - 28189, - 28190, - 28203, - 28206, - 28208, - 28220, - 28226, - 28231, - 28249, - 28256, - 28259, - 28265, - 28266, - 28271, - 28274, - 28280, - 28296, - 28316, - 28319, - 28343, - 28344, - 28357, - 28358, - 28364, - 28370, - 28372, - 28379, - 28388, - 28392, - 28395, - 28406, - 28418, - 28423, - 28435, - 28444, - 28454, - 28468, - 28477, - 28478, - 28480, - 28486, - 28489, - 28500, - 28507, - 28519, - 28523, - 28534, - 28547, - 28549, - 28562, - 28571, - 28583, - 28584, - 28595, - 28597, - 28604, - 28607, - 28609, - 28612, - 28630, - 28640, - 28669, - 28677, - 28682, - 28690, - 28695, - 28696, - 28717, - 28730, - 28737, - 28752, - 28761, - 28774, - 28783, - 28791, - 28801, - 28802, - 28814, - 28837, - 28838, - 28842, - 28844, - 28849, - 28864, - 28867, - 28881, - 28882, - 28893, - 28903, - 28907, - 28909, - 28921, - 28927, - 28929, - 28935, - 28941, - 28942, - 28954, - 28959, - 28960, - 28990, - 28992, - 29004, - 29010, - 29012, - 29021, - 29035, - 29040, - 29059, - 29068, - 29080, - 29086, - 29089, - 29090, - 29095, - 29113, - 29127, - 29131, - 29148, - 29161, - 29172, - 29179, - 29188, - 29192, - 29195, - 29206, - 29210, - 29215, - 29221, - 29222, - 29236, - 29246, - 29248, - 29253, - 29272, - 29288, - 29293, - 29294, - 29308, - 29318, - 29321, - 29322, - 29339, - 29365, - 29369, - 29372, - 29377, - 29392, - 29401, - 29402, - 29418, - 29437, - 29445, - 29446, - 29460, - 29467, - 29473, - 29476, - 29488, - 29511, - 29512, - 29517, - 29523, - 29526, - 29535, - 29539, - 29545, - 29559, - 29560, - 29589, - 29593, - 29599, - 29603, - 29610, - 29629, - 29644, - 29656, - 29662, - 29675, - 29692, - 29704, - 29707, - 29715, - 29717, - 29722, - 29731, - 29740, - 29743, - 29752, - 29760, - 29766, - 29770, - 29794, - 29796, - 29814, - 29817, - 29829, - 29841, - 29851, - 29860, - 29864, - 29869, - 29870, - 29889, - 29896, - 29901, - 29913, - 29919, - 29920, - 29947, - 29958, - 29975, - 29981, - 29985, - 29998, - 30010, - 30012, - 30044, - 30048, - 30051, - 30063, - 30065, - 30072, - 30077, - 30087, - 30088, - 30101, - 30112, - 30121, - 30122, - 30130, - 30135, - 30139, - 30142, - 30164, - 30167, - 30180, - 30202, - 30211, - 30214, - 30217, - 30223, - 30228, - 30235, - 30256, - 30265, - 30286, - 30293, - 30298, - 30310, - 30314, - 30327, - 30333, - 30334, - 30337, - 30338, - 30344, - 30349, - 30352, - 30362, - 30374, - 30380, - 30388, - 30391, - 30395, - 30403, - 30409, - 30424, - 30427, - 30430, - 30451, - 30460, - 30475, - 30480, - 30485, - 30486, - 30489, - 30492, - 30499, - 30511, - 30533, - 30534, - 30540, - 30545, - 30552, - 30557, - 30558, - 30567, - 30568, - 30581, - 30597, - 30607, - 30621, - 30632, - 30650, - 30655, - 30657, - 30660, - 30669, - 30675, - 30678, - 30682, - 30687, - 30688, - 30698, - 30711, - 30728, - 30733, - 30741, - 30746, - 30752, - 30764, - 30769, - 30784, - 30796, - 30799, - 30804, - 30811, - 30814, - 30818, - 30827, - 30838, - 30842, - 30854, - 30863, - 30865, - 30877, - 30881, - 30887, - 30908, - 30916, - 30919, - 30925, - 30928, - 30944, - 30947, - 30950, - 30968, - 30971, - 30973, - 30976, - 30986, - 30993, - 30994, - 31012, - 31016, - 31029, - 31039, - 31041, - 31042, - 31044, - 31053, - 31059, - 31062, - 31077, - 31095, - 31101, - 31105, - 31118, - 31129, - 31132, - 31141, - 31159, - 31183, - 31185, - 31195, - 31202, - 31213, - 31238, - 31241, - 31252, - 31262, - 31265, - 31295, - 31300, - 31303, - 31317, - 31318, - 31324, - 31338, - 31340, - 31345, - 31355, - 31362, - 31371, - 31373, - 31381, - 31391, - 31409, - 31410, - 31412, - 31434, - 31458, - 31467, - 31470, - 31475, - 31481, - 31482, - 31484, - 31492, - 31507, - 31514, - 31538, - 31547, - 31549, - 31555, - 31557, - 31597, - 31598, - 31610, - 31625, - 31634, - 31643, - 31645, - 31659, - 31669, - 31670, - 31682, - 31694, - 31717, - 31718, - 31729, - 31736, - 31742, - 31749, - 31773, - 31777, - 31778, - 31784, - 31801, - 31812, - 31821, - 31822, - 31836, - 31850, - 31855, - 31858, - 31860, - 31886, - 31891, - 31909, - 31928, - 31931, - 31934, - 31941, - 31942, - 31945, - 31951, - 31959, - 31963, - 31970, - 31984, - 31987, - 31990, - 32001, - 32007, - 32008, - 32025, - 32035, - 32038, - 32047, - 32049, - 32062, - 32067, - 32070, - 32073, - 32074, - 32079, - 32081, - 32082, - 32107, - 32127, - 32145, - 32151, - 32152, - 32173, - 32174, - 32186, - 32194, - 32196, - 32200, - 32208, - 32218, - 32236, - 32260, - 32263, - 32288, - 32298, - 32315, - 32332, - 32340, - 32354, - 32359, - 32366, - 32368, - 32377, - 32384, - 32399, - 32417, - 32424, - 32427, - 32429, - 32438, - 32442, - 32447, - 32469, - 32479, - 32483, - 32498, - 32503, - 32507, - 32521, - 32532, - 32539, - 32551, - 32572, - 32577, - 32578, - 32587, - 32592, - 32602, - 32604, - 32613, - 32625, - 32631, - 32641, - 32642, - 32644, - 32656, - 32678, - 32681, - 32701, - 32713, - 32721, - 32727, - 32731, - 32734, - 32740, - 32773, - 32774, - 32785, - 32788, - 32792, - 32797, - 32801, - 32811, - 32821, - 32828, - 32839, - 32854, - 32867, - 32870, - 32873, - 32881, - 32891, - 32900, - 32903, - 32910, - 32917, - 32922, - 32928, - 32945, - 32946, - 32951, - 32958, - 32965, - 32978, - 32980, - 32983, - 32987, - 33023, - 33031, - 33032, - 33035, - 33038, - 33040, - 33043, - 33050, - 33059, - 33080, - 33098, - 33108, - 33115, - 33117, - 33133, - 33134, - 33157, - 33169, - 33170, - 33176, - 33182, - 33192, - 33205, - 33212, - 33215, - 33217, - 33227, - 33229, - 33238, - 33241, - 33260, - 33271, - 33278, - 33293, - 33294, - 33296, - 33302, - 33305, - 33329, - 33330, - 33332, - 33354, - 33383, - 33387, - 33397, - 33408, - 33417, - 33420, - 33423, - 33431, - 33438, - 33442, - 33444, - 33448, - 33456, - 33459, - 33466, - 33473, - 33476, - 33491, - 33494, - 33507, - 33514, - 33521, - 33528, - 33534, - 33536, - 33551, - 33554, - 33563, - 33575, - 33579, - 33582, - 33601, - 33602, - 33614, - 33625, - 33628, - 33637, - 33656, - 33665, - 33683, - 33695, - 33696, - 33702, - 33708, - 33711, - 33716, - 33728, - 33737, - 33761, - 33774, - 33782, - 33788, - 33791, - 33793, - 33811, - 33813, - 33818, - 33829, - 33842, - 33854, - 33856, - 33868, - 33879, - 33885, - 33886, - 33892, - 33907, - 33913, - 33923, - 33925, - 33935, - 33937, - 33954, - 33963, - 33966, - 33977, - 33978, - 33991, - 33998, - 34012, - 34016, - 34025, - 34033, - 34036, - 34045, - 34065, - 34078, - 34093, - 34101, - 34108, - 34111, - 34120, - 34123, - 34125, - 34153, - 34171, - 34174, - 34178, - 34183, - 34190, - 34201, - 34211, - 34220, - 34225, - 34237, - 34249, - 34250, - 34264, - 34269, - 34276, - 34279, - 34293, - 34303, - 34310, - 34340, - 34349, - 34352, - 34355, - 34358, - 34362, - 34376, - 34381, - 34387, - 34389, - 34394, - 34410, - 34423, - 34434, - 34436, - 34448, - 34453, - 34454, - 34460, - 34464, - 34479, - 34491, - 34501, - 34508, - 34516, - 34529, - 34530, - 34553, - 34564, - 34568, - 34571, - 34582, - 34586, - 34598, - 34604, - 34610, - 34619, - 34621, - 34633, - 34634, - 34657, - 34682, - 34688, - 34691, - 34694, - 34706, - 34708, - 34724, - 34727, - 34751, - 34753, - 34759, - 34763, - 34777, - 34778, - 34780, - 34796, - 34799, - 34801, - 34817, - 34824, - 34827, - 34837, - 34841, - 34853, - 34858, - 34877, - 34886, - 34895, - 34897, - 34898, - 34916, - 34923, - 34928, - 34934, - 34940, - 34944, - 34947, - 34953, - 34956, - 34967, - 34968, - 34971, - 34974, - 34977, - 34980, - 34983, - 34998, - 35004, - 35010, - 35012, - 35030, - 35039, - 35058, - 35063, - 35082, - 35095, - 35096, - 35101, - 35102, - 35105, - 35112, - 35118, - 35120, - 35130, - 35143, - 35147, - 35152, - 35157, - 35164, - 35178, - 35195, - 35197, - 35201, - 35207, - 35231, - 35249, - 35250, - 35256, - 35259, - 35262, - 35273, - 35282, - 35298, - 35307, - 35328, - 35334, - 35343, - 35345, - 35355, - 35388, - 35399, - 35403, - 35408, - 35413, - 35418, - 35434, - 35436, - 35448, - 35460, - 35475, - 35494, - 35497, - 35503, - 35508, - 35511, - 35518, - 35520, - 35530, - 35537, - 35543, - 35560, - 35566, - 35571, - 35598, - 35609, - 35612, - 35615, - 35616, - 35622, - 35626, - 35633, - 35636, - 35645, - 35653, - 35663, - 35665, - 35682, - 35687, - 35688, - 35691, - 35696, - 35727, - 35741, - 35742, - 35746, - 35748, - 35752, - 35770, - 35811, - 35817, - 35832, - 35838, - 35850, - 35863, - 35870, - 35879, - 35880, - 35891, - 35893, - 35903, - 35905, - 35926, - 35930, - 35941, - 35956, - 35963, - 35970, - 35984, - 35996, - 36005, - 36012, - 36015, - 36030, - 36035, - 36042, - 36047, - 36049, - 36059, - 36071, - 36080, - 36085, - 36097, - 36110, - 36115, - 36118, - 36124, - 36137, - 36138, - 36155, - 36160, - 36189, - 36190, - 36203, - 36211, - 36218, - 36230, - 36241, - 36244, - 36253, - 36257, - 36264, - 36272, - 36290, - 36292, - 36301, - 36309, - 36313, - 36316, - 36319, - 36330, - 36335, - 36347, - 36353, - 36356, - 36368, - 36374, - 36377, - 36384, - 36407, - 36413, - 36419, - 36425, - 36426, - 36446, - 36461, - 36467, - 36474, - 36480, - 36486, - 36489, - 36495, - 36525, - 36526, - 36533, - 36534, - 36540, - 36555, - 36563, - 36565, - 36588, - 36593, - 36596, - 36606, - 36614, - 36626, - 36628, - 36641, - 36642, - 36651, - 36653, - 36673, - 36676, - 36679, - 36694, - 36698, - 36704, - 36714, - 36721, - 36722, - 36727, - 36749, - 36758, - 36761, - 36771, - 36788, - 36797, - 36805, - 36830, - 36833, - 36839, - 36843, - 36860, - 36866, - 36871, - 36875, - 36877, - 36880, - 36892, - 36911, - 36914, - 36916, - 36923, - 36940, - 36943, - 36948, - 36957, - 36958, - 36967, - 36974, - 36981, - 37001, - 37012, - 37015, - 37019, - 37035, - 37040, - 37063, - 37064, - 37069, - 37077, - 37093, - 37097, - 37106, - 37115, - 37118, - 37123, - 37129, - 37130, - 37135, - 37137, - 37138, - 37140, - 37144, - 37149, - 37156, - 37159, - 37163, - 37165, - 37183, - 37185, - 37195, - 37198, - 37203, - 37212, - 37233, - 37236, - 37240, - 37256, - 37264, - 37267, - 37273, - 37295, - 37315, - 37330, - 37336, - 37339, - 37342, - 37357, - 37365, - 37372, - 37381, - 37399, - 37416, - 37429, - 37436, - 37442, - 37451, - 37453, - 37475, - 37482, - 37489, - 37490, - 37523, - 37525, - 37530, - 37535, - 37539, - 37548, - 37559, - 37560, - 37566, - 37597, - 37601, - 37602, - 37604, - 37616, - 37622, - 37658, - 37660, - 37667, - 37684, - 37693, - 37694, - 37696, - 37706, - 37711, - 37730, - 37735, - 37742, - 37744, - 37759, - 37777, - 37783, - 37784, - 37793, - 37800, - 37818, - 37823, - 37825, - 37828, - 37832, - 37849, - 37856, - 37861, - 37862, - 37886, - 37893, - 37915, - 37922, - 37936, - 37939, - 37945, - 37956, - 37960, - 37971, - 37980, - 38002, - 38007, - 38018, - 38020, - 38038, - 38041, - 38044, - 38048, - 38051, - 38054, - 38065, - 38066, - 38077, - 38090, - 38109, - 38119, - 38120, - 38123, - 38146, - 38155, - 38160, - 38181, - 38188, - 38199, - 38203, - 38225, - 38226, - 38231, - 38244, - 38248, - 38259, - 38268, - 38271, - 38272, - 38278, - 38292, - 38296, - 38318, - 38326, - 38338, - 38347, - 38373, - 38378, - 38380, - 38388, - 38392, - 38397, - 38398, - 38401, - 38404, - 38422, - 38432, - 38469, - 38482, - 38493, - 38507, - 38518, - 38521, - 38527, - 38533, - 38534, - 38552, - 38561, - 38576, - 38581, - 38585, - 38594, - 38606, - 38613, - 38617, - 38634, - 38644, - 38651, - 38661, - 38665, - 38668, - 38674, - 38689, - 38695, - 38696, - 38707, - 38710, - 38716, - 38733, - 38736, - 38742, - 38751, - 38752, - 38775, - 38779, - 38792, - 38798, - 38819, - 38822, - 38839, - 38851, - 38854, - 38863, - 38865, - 38887, - 38896, - 38901, - 38912, - 38918, - 38929, - 38941, - 38948, - 38965, - 38969, - 38977, - 38987, - 38992, - 38995, - 39001, - 39004, - 39011, - 39018, - 39025, - 39031, - 39032, - 39044, - 39056, - 39065, - 39066, - 39084, - 39095, - 39099, - 39101, - 39102, - 39104, - 39109, - 39114, - 39121, - 39122, - 39127, - 39150, - 39172, - 39181, - 39184, - 39193, - 39199, - 39200, - 39206, - 39209, - 39235, - 39238, - 39242, - 39244, - 39280, - 39290, - 39292, - 39296, - 39305, - 39308, - 39311, - 39326, - 39329, - 39330, - 39336, - 39339, - 39353, - 39359, - 39374, - 39391, - 39392, - 39402, - 39409, - 39410, - 39415, - 39419, - 39431, - 39432, - 39438, - 39443, - 39445, - 39449, - 39461, - 39462, - 39485, - 39508, - 39515, - 39522, - 39533, - 39541, - 39542, - 39557, - 39570, - 39575, - 39576, - 39591, - 39597, - 39603, - 39610, - 39612, - 39617, - 39620, - 39624, - 39627, - 39635, - 39641, - 39666, - 39668, - 39686, - 39692, - 39700, - 39709, - 39726, - 39728, - 39737, - 39738, - 39755, - 39757, - 39758, - 39765, - 39766, - 39769, - 39779, - 39785, - 39794, - 39796, - 39809, - 39815, - 39829, - 39834, - 39839, - 39850, - 39857, - 39881, - 39905, - 39912, - 39938, - 39940, - 39944, - 39955, - 39961, - 39977, - 39980, - 39986, - 39988, - 39991, - 39998, - 40003, - 40005, - 40023, - 40024, - 40045, - 40046, - 40058, - 40088, - 40091, - 40098, - 40109, - 40112, - 40124, - 40130, - 40153, - 40166, - 40175, - 40183, - 40184, - 40207, - 40215, - 40225, - 40235, - 40240, - 40255, - 40263, - 40270, - 40277, - 40282, - 40297, - 40306, - 40315, - 40333, - 40334, - 40336, - 40342, - 40345, - 40348, - 40355, - 40372, - 40381, - 40390, - 40407, - 40435, - 40437, - 40441, - 40444, - 40458, - 40460, - 40481, - 40484, - 40487, - 40493, - 40494, - 40501, - 40502, - 40525, - 40550, - 40553, - 40559, - 40562, - 40573, - 40574, - 40578, - 40583, - 40584, - 40587, - 40597, - 40620, - 40623, - 40631, - 40643, - 40660, - 40667, - 40676, - 40693, - 40697, - 40708, - 40718, - 40726, - 40735, - 40739, - 40748, - 40760, - 40763, - 40773, - 40774, - 40786, - 40791, - 40798, - 40801, - 40808, - 40811, - 40813, - 40825, - 40831, - 40835, - 40856, - 40861, - 40880, - 40889, - 40912, - 40918, - 40924, - 40927, - 40928, - 40938, - 40952, - 40957, - 40961, - 40968, - 40974, - 40986, - 40992, - 41001, - 41004, - 41022, - 41033, - 41036, - 41039, - 41044, - 41064, - 41078, - 41091, - 41103, - 41108, - 41112, - 41127, - 41128, - 41136, - 41141, - 41146, - 41156, - 41159, - 41163, - 41165, - 41166, - 41184, - 41193, - 41202, - 41211, - 41216, - 41239, - 41243, - 41249, - 41262, - 41267, - 41276, - 41279, - 41305, - 41306, - 41312, - 41317, - 41321, - 41332, - 41335, - 41345, - 41346, - 41351, - 41365, - 41388, - 41399, - 41405, - 41414, - 41432, - 41454, - 41461, - 41462, - 41471, - 41478, - 41490, - 41506, - 41508, - 41512, - 41517, - 41520, - 41529, - 41530, - 41544, - 41550, - 41571, - 41577, - 41580, - 41595, - 41613, - 41622, - 41635, - 41642, - 41661, - 41676, - 41681, - 41684, - 41687, - 41688, - 41694, - 41698, - 41710, - 41712, - 41721, - 41722, - 41729, - 41744, - 41747, - 41753, - 41766, - 41783, - 41790, - 41810, - 41819, - 41825, - 41828, - 41843, - 41846, - 41862, - 41871, - 41874, - 41876, - 41892, - 41899, - 41916, - 41928, - 41957, - 41964, - 41969, - 41981, - 41996, - 41999, - 42001, - 42017, - 42023, - 42027, - 42032, - 42035, - 42044, - 42050, - 42061, - 42062, - 42073, - 42098, - 42104, - 42109, - 42120, - 42125, - 42131, - 42143, - 42153, - 42176, - 42182, - 42188, - 42203, - 42216, - 42219, - 42227, - 42234, - 42251, - 42254, - 42256, - 42259, - 42282, - 42289, - 42302, - 42307, - 42310, - 42322, - 42328, - 42338, - 42349, - 42367, - 42386, - 42398, - 42404, - 42413, - 42419, - 42421, - 42422, - 42431, - 42445, - 42448, - 42451, - 42454, - 42458, - 42470, - 42476, - 42500, - 42509, - 42538, - 42543, - 42545, - 42546, - 42563, - 42570, - 42580, - 42584, - 42589, - 42608, - 42618, - 42629, - 42636, - 42639, - 42644, - 42647, - 42651, - 42654, - 42658, - 42669, - 42678, - 42689, - 42695, - 42696, - 42710, - 42716, - 42730, - 42732, - 42747, - 42750, - 42752, - 42761, - 42772, - 42776, - 42779, - 42797, - 42815, - 42824, - 42837, - 42844, - 42868, - 42877, - 42888, - 42891, - 42912, - 42918, - 42921, - 42927, - 42949, - 42953, - 42967, - 42974, - 42989, - 42995, - 42997, - 43007, - 43018, - 43025, - 43031, - 43032, - 43038, - 43041, - 43054, - 43074, - 43085, - 43097, - 43098, - 43110, - 43119, - 43131, - 43143, - 43144, - 43152, - 43157, - 43178, - 43180, - 43192, - 43197, - 43203, - 43220, - 43236, - 43245, - 43246, - 43260, - 43265, - 43271, - 43285, - 43286, - 43290, - 43299, - 43314, - 43323, - 43337, - 43348, - 43355, - 43357, - 43358, - 43361, - 43362, - 43364, - 43368, - 43376, - 43385, - 43386, - 43391, - 43397, - 43431, - 43438, - 43440, - 43452, - 43463, - 43470, - 43478, - 43481, - 43488, - 43491, - 43506, - 43512, - 43539, - 43567, - 43579, - 43584, - 43601, - 43614, - 43617, - 43623, - 43630, - 43647, - 43658, - 43663, - 43665, - 43691, - 43701, - 43705, - 43708, - 43719, - 43731, - 43737, - 43740, - 43747, - 43749, - 43750, - 43754, - 43764, - 43767, - 43768, - 43773, - 43785, - 43788, - 43810, - 43819, - 43834, - 43853, - 43866, - 43871, - 43872, - 43881, - 43889, - 43902, - 43926, - 43935, - 43946, - 43951, - 43953, - 43971, - 44008, - 44011, - 44026, - 44033, - 44048, - 44057, - 44058, - 44067, - 44081, - 44087, - 44099, - 44105, - 44106, - 44114, - 44116, - 44130, - 44139, - 44141, - 44153, - 44159, - 44160, - 44170, - 44172, - 44187, - 44190, - 44193, - 44199, - 44213, - 44218, - 44223, - 44235, - 44243, - 44262, - 44283, - 44291, - 44293, - 44308, - 44327, - 44341, - 44346, - 44348, - 44354, - 44366, - 44368, - 44373, - 44384, - 44390, - 44393, - 44394, - 44399, - 44401, - 44408, - 44411, - 44417, - 44420, - 44424, - 44444, - 44451, - 44453, - 44466, - 44472, - 44475, - 44486, - 44500, - 44510, - 44531, - 44534, - 44553, - 44559, - 44564, - 44580, - 44583, - 44589, - 44592, - 44609, - 44627, - 44633, - 44643, - 44646, - 44650, - 44674, - 44676, - 44680, - 44683, - 44703, - 44704, - 44716, - 44733, - 44748, - 44759, - 44763, - 44781, - 44782, - 44789, - 44794, - 44799, - 44804, - 44813, - 44822, - 44838, - 44842, - 44849, - 44856, - 44870, - 44887, - 44904, - 44915, - 44917, - 44921, - 44928, - 44933, - 44934, - 44937, - 44940, - 44951, - 44961, - 44962, - 44971, - 44982, - 44985, - 44996, - 44999, - 45014, - 45029, - 45033, - 45036, - 45047, - 45065, - 45076, - 45085, - 45086, - 45090, - 45107, - 45119, - 45121, - 45128, - 45139, - 45151, - 45157, - 45162, - 45164, - 45176, - 45179, - 45198, - 45209, - 45231, - 45234, - 45236, - 45251, - 45260, - 45268, - 45277, - 45299, - 45301, - 45338, - 45344, - 45349, - 45364, - 45367, - 45371, - 45373, - 45376, - 45381, - 45400, - 45406, - 45416, - 45422, - 45427, - 45440, - 45458, - 45467, - 45474, - 45476, - 45488, - 45494, - 45497, - 45500, - 45512, - 45515, - 45523, - 45542, - 45553, - 45559, - 45589, - 45594, - 45596, - 45603, - 45605, - 45610, - 45630, - 45638, - 45641, - 45647, - 45655, - 45659, - 45665, - 45689, - 45695, - 45702, - 45708, - 45726, - 45729, - 45739, - 45744, - 45747, - 45762, - 45764, - 45773, - 45774, - 45781, - 45785, - 45792, - 45801, - 45802, - 45812, - 45816, - 45829, - 45833, - 45847, - 45851, - 45854, - 45863, - 45870, - 45901, - 45910, - 45920, - 45932, - 45938, - 45940, - 45943, - 45949, - 45953, - 45963, - 45971, - 45989, - 45999, - 46001, - 46008, - 46022, - 46026, - 46034, - 46040, - 46043, - 46045, - 46061, - 46062, - 46076, - 46084, - 46094, - 46102, - 46118, - 46149, - 46154, - 46167, - 46173, - 46177, - 46192, - 46197, - 46201, - 46214, - 46217, - 46223, - 46226, - 46228, - 46237, - 46241, - 46251, - 46259, - 46262, - 46266, - 46294, - 46300, - 46303, - 46309, - 46321, - 46331, - 46339, - 46342, - 46354, - 46370, - 46372, - 46379, - 46382, - 46393, - 46402, - 46407, - 46416, - 46425, - 46437, - 46444, - 46447, - 46449, - 46456, - 46462, - 46472, - 46475, - 46486, - 46490, - 46495, - 46501, - 46514, - 46526, - 46528, - 46538, - 46551, - 46552, - 46564, - 46579, - 46586, - 46602, - 46615, - 46616, - 46621, - 46635, - 46643, - 46645, - 46649, - 46667, - 46670, - 46672, - 46678, - 46681, - 46684, - 46687, - 46705, - 46708, - 46721, - 46724, - 46739, - 46757, - 46762, - 46764, - 46776, - 46784, - 46790, - 46796, - 46799, - 46802, - 46813, - 46814, - 46824, - 46832, - 46841, - 46856, - 46862, - 46864, - 46869, - 46874, - 46895, - 46900, - 46903, - 46927, - 46946, - 46948, - 46955, - 46965, - 46972, - 46976, - 46985, - 46999, - 47003, - 47006, - 47016, - 47030, - 47034, - 47053, - 47056, - 47059, - 47072, - 47077, - 47099, - 47105, - 47108, - 47112, - 47115, - 47117, - 47120, - 47129, - 47135, - 47151, - 47154, - 47156, - 47166, - 47171, - 47195, - 47204, - 47213, - 47222, - 47228, - 47241, - 47242, - 47247, - 47249, - 47250, - 47261, - 47266, - 47268, - 47278, - 47286, - 47312, - 47315, - 47321, - 47322, - 47324, - 47331, - 47338, - 47366, - 47372, - 47375, - 47378, - 47387, - 47389, - 47390, - 47396, - 47400, - 47405, - 47408, - 47411, - 47431, - 47443, - 47459, - 47466, - 47479, - 47480, - 47495, - 47504, - 47519, - 47520, - 47530, - 47537, - 47555, - 47558, - 47567, - 47569, - 47572, - 47582, - 47591, - 47595, - 47598, - 47609, - 47612, - 47616, - 47625, - 47640, - 47649, - 47655, - 47661, - 47688, - 47711, - 47717, - 47721, - 47724, - 47727, - 47730, - 47739, - 47745, - 47752, - 47758, - 47765, - 47770, - 47782, - 47786, - 47791, - 47793, - 47796, - 47814, - 47823, - 47826, - 47837, - 47854, - 47856, - 47871, - 47879, - 47880, - 47885, - 47886, - 47903, - 47907, - 47913, - 47916, - 47928, - 47936, - 47945, - 47948, - 47956, - 47965, - 47970, - 47972, - 47981, - 47987, - 48010, - 48012, - 48023, - 48033, - 48051, - 48071, - 48075, - 48077, - 48080, - 48099, - 48106, - 48114, - 48120, - 48128, - 48145, - 48152, - 48155, - 48182, - 48188, - 48203, - 48217, - 48218, - 48236, - 48241, - 48244, - 48264, - 48269, - 48278, - 48282, - 48288, - 48311, - 48315, - 48317, - 48329, - 48330, - 48337, - 48350, - 48353, - 48360, - 48374, - 48380, - 48405, - 48406, - 48409, - 48412, - 48416, - 48419, - 48425, - 48434, - 48443, - 48445, - 48453, - 48454, - 48482, - 48491, - 48501, - 48517, - 48518, - 48545, - 48548, - 48552, - 48569, - 48575, - 48580, - 48584, - 48590, - 48595, - 48602, - 48604, - 48618, - 48625, - 48626, - 48638, - 48668, - 48677, - 48678, - 48687, - 48692, - 48696, - 48704, - 48707, - 48714, - 48731, - 48740, - 48750, - 48761, - 48785, - 48786, - 48798, - 48807, - 48808, - 48814, - 48826, - 48828, - 48834, - 48840, - 48845, - 48858, - 48864, - 48869, - 48870, - 48879, - 48887, - 48899, - 48911, - 48920, - 48926, - 48929, - 48971, - 48974, - 48981, - 48998, - 49007, - 49028, - 49031, - 49056, - 49065, - 49079, - 49083, - 49088, - 49093, - 49100, - 49103, - 49124, - 49136, - 49139, - 49142, - 49145, - 49146, - 49171, - 49187, - 49190, - 49194, - 49196, - 49207, - 49216, - 49219, - 49222, - 49240, - 49250, - 49262, - 49276, - 49289, - 49292, - 49298, - 49319, - 49320, - 49325, - 49333, - 49340, - 49343, - 49352, - 49363, - 49375, - 49391, - 49405, - 49413, - 49420, - 49425, - 49431, - 49432, - 49441, - 49456, - 49476, - 49479, - 49504, - 49514, - 49528, - 49543, - 49544, - 49550, - 49558, - 49568, - 49578, - 49600, - 49612, - 49633, - 49634, - 49636, - 49643, - 49654, - 49657, - 49663, - 49667, - 49693, - 49700, - 49703, - 49712, - 49717, - 49718, - 49721, - 49727, - 49730, - 49735, - 49739, - 49747, - 49765, - 49770, - 49772, - 49777, - 49789, - 49817, - 49829, - 49839, - 49844, - 49851, - 49854, - 49874, - 49883, - 49886, - 49892, - 49895, - 49914, - 49931, - 49933, - 49934, - 49941, - 49952, - 49967, - 49969, - 49972, - 49976, - 49979, - 49999, - 50008, - 50030, - 50041, - 50042, - 50044, - 50057, - 50060, - 50075, - 50077, - 50091, - 50096, - 50099, - 50106, - 50116, - 50133, - 50144, - 50153, - 50154, - 50168, - 50179, - 50188, - 50194, - 50203, - 50212, - 50216, - 50222, - 50229, - 50230, - 50234, - 50251, - 50253, - 50262, - 50266, - 50272, - 50287, - 50295, - 50305, - 50306, - 50311, - 50320, - 50323, - 50325, - 50339, - 50356, - 50365, - 50366, - 50368, - 50377, - 50386, - 50397, - 50411, - 50414, - 50425, - 50451, - 50463, - 50467, - 50473, - 50487, - 50501, - 50505, - 50514, - 50516, - 50536, - 50547, - 50566, - 50572, - 50583, - 50593, - 50599, - 50613, - 50617, - 50618, - 50620, - 50628, - 50638, - 50652, - 50655, - 50662, - 50665, - 50673, - 50683, - 50689, - 50690, - 50692, - 50696, - 50704, - 50713, - 50719, - 50738, - 50757, - 50761, - 50764, - 50770, - 50776, - 50803, - 50805, - 50806, - 50816, - 50826, - 50840, - 50845, - 50852, - 50855, - 50862, - 50876, - 50879, - 50882, - 50894, - 50899, - 50905, - 50924, - 50936, - 50944, - 50973, - 50974, - 51002, - 51007, - 51009, - 51029, - 51036, - 51063, - 51067, - 51070, - 51074, - 51079, - 51083, - 51093, - 51094, - 51124, - 51131, - 51151, - 51153, - 51156, - 51165, - 51175, - 51184, - 51187, - 51203, - 51220, - 51224, - 51233, - 51234, - 51239, - 51246, - 51248, - 51251, - 51257, - 51266, - 51280, - 51285, - 51286, - 51289, - 51295, - 51296, - 51311, - 51329, - 51350, - 51356, - 51363, - 51365, - 51370, - 51372, - 51377, - 51383, - 51384, - 51397, - 51407, - 51422, - 51435, - 51440, - 51446, - 51463, - 51467, - 51491, - 51493, - 51494, - 51508, - 51518, - 51520, - 51526, - 51529, - 51530, - 51537, - 51547, - 51559, - 51565, - 51568, - 51580, - 51583, - 51584, - 51593, - 51594, - 51607, - 51608, - 51620, - 51624, - 51642, - 51649, - 51652, - 51659, - 51661, - 51670, - 51674, - 51698, - 51707, - 51725, - 51737, - 51753, - 51754, - 51779, - 51791, - 51796, - 51809, - 51816, - 51819, - 51827, - 51829, - 51834, - 51836, - 51846, - 51849, - 51855, - 51858, - 51869, - 51870, - 51874, - 51918, - 51926, - 51932, - 51936, - 51948, - 51954, - 51959, - 51971, - 51983, - 51992, - 51997, - 52016, - 52021, - 52031, - 52033, - 52034, - 52048, - 52053, - 52057, - 52067, - 52076, - 52079, - 52081, - 52109, - 52127, - 52128, - 52133, - 52148, - 52155, - 52157, - 52172, - 52178, - 52184, - 52199, - 52200, - 52205, - 52206, - 52232, - 52237, - 52243, - 52246, - 52252, - 52261, - 52265, - 52266, - 52273, - 52274, - 52288, - 52300, - 52303, - 52321, - 52322, - 52328, - 52333, - 52351, - 52357, - 52372, - 52381, - 52386, - 52395, - 52403, - 52423, - 52427, - 52432, - 52438, - 52444, - 52457, - 52468, - 52480, - 52498, - 52516, - 52520, - 52525, - 52531, - 52540, - 52545, - 52546, - 52552, - 52557, - 52569, - 52575, - 52582, - 52594, - 52615, - 52619, - 52624, - 52645, - 52663, - 52664, - 52675, - 52687, - 52696, - 52701, - 52706, - 52708, - 52711, - 52726, - 52748, - 52754, - 52756, - 52759, - 52769, - 52784, - 52790, - 52804, - 52807, - 52808, - 52819, - 52826, - 52828, - 52832, - 52835, - 52849, - 52859, - 52877, - 52880, - 52896, - 52899, - 52905, - 52913, - 52933, - 52934, - 52938, - 52957, - 52979, - 52981, - 52986, - 53005, - 53008, - 53024, - 53029, - 53054, - 53073, - 53083, - 53086, - 53095, - 53102, - 53107, - 53126, - 53130, - 53138, - 53144, - 53156, - 53163, - 53165, - 53173, - 53177, - 53183, - 53192, - 53195, - 53200, - 53212, - 53219, - 53221, - 53245, - 53254, - 53257, - 53265, - 53266, - 53268, - 53275, - 53277, - 53284, - 53294, - 53308, - 53314, - 53319, - 53326, - 53328, - 53340, - 53364, - 53367, - 53377, - 53395, - 53398, - 53407, - 53413, - 53414, - 53417, - 53443, - 53473, - 53476, - 53480, - 53486, - 53506, - 53542, - 53546, - 53554, - 53563, - 53580, - 53591, - 53598, - 53611, - 53621, - 53625, - 53628, - 53632, - 53650, - 53655, - 53675, - 53677, - 53680, - 53683, - 53700, - 53709, - 53724, - 53731, - 53733, - 53738, - 53762, - 53767, - 53785, - 53786, - 53795, - 53802, - 53812, - 53821, - 53827, - 53833, - 53841, - 53848, - 53869, - 53897, - 53905, - 53912, - 53921, - 53928, - 53948, - 53954, - 53968, - 53977, - 53983, - 53984, - 54002, - 54007, - 54013, - 54014, - 54021, - 54026, - 54028, - 54031, - 54036, - 54067, - 54069, - 54074, - 54076, - 54105, - 54111, - 54118, - 54129, - 54145, - 54157, - 54158, - 54163, - 54166, - 54172, - 54185, - 54186, - 54188, - 54208, - 54223, - 54237, - 54241, - 54244, - 54259, - 54273, - 54276, - 54280, - 54294, - 54298, - 54303, - 54304, - 54309, - 54310, - 54316, - 54336, - 54354, - 54359, - 54375, - 54376, - 54381, - 54390, - 54396, - 54399, - 54409, - 54424, - 54434, - 54436, - 54439, - 54445, - 54448, - 54457, - 54465, - 54471, - 54472, - 54485, - 54508, - 54513, - 54528, - 54534, - 54537, - 54540, - 54551, - 54561, - 54573, - 54579, - 54586, - 54591, - 54596, - 54599, - 54605, - 54613, - 54623, - 54654, - 54667, - 54681, - 54684, - 54687, - 54694, - 54706, - 54712, - 54715, - 54723, - 54725, - 54726, - 54740, - 54750, - 54760, - 54768, - 54771, - 54773, - 54796, - 54801, - 54808, - 54814, - 54837, - 54847, - 54849, - 54864, - 54867, - 54889, - 54895, - 54907, - 54919, - 54923, - 54926, - 54940, - 54950, - 54954, - 54961, - 54973, - 54974, - 54976, - 54986, - 54993, - 55000, - 55010, - 55019, - 55021, - 55030, - 55033, - 55039, - 55047, - 55048, - 55054, - 55059, - 55068, - 55071, - 55075, - 55077, - 55081, - 55095, - 55099, - 55110, - 55116, - 55122, - 55134, - 55144, - 55147, - 55158, - 55162, - 55171, - 55185, - 55192, - 55197, - 55207, - 55228, - 55246, - 55253, - 55254, - 55281, - 55300, - 55303, - 55307, - 55312, - 55328, - 55331, - 55337, - 55348, - 55352, - 55357, - 55372, - 55375, - 55377, - 55394, - 55406, - 55424, - 55429, - 55430, - 55436, - 55439, - 55447, - 55453, - 55458, - 55460, - 55478, - 55489, - 55501, - 55502, - 55519, - 55525, - 55530, - 55544, - 55550, - 55558, - 55561, - 55569, - 55586, - 55591, - 55598, - 55605, - 55609, - 55618, - 55630, - 55642, - 55644, - 55653, - 55654, - 55660, - 55671, - 55693, - 55706, - 55712, - 55718, - 55739, - 55747, - 55754, - 55771, - 55774, - 55780, - 55783, - 55784, - 55789, - 55798, - 55802, - 55823, - 55828, - 55837, - 55838, - 55847, - 55848, - 55885, - 55897, - 55904, - 55910, - 55919, - 55922, - 55931, - 55933, - 55937, - 55943, - 55955, - 55957, - 55968, - 55980, - 55986, - 55992, - 56005, - 56034, - 56051, - 56054, - 56065, - 56080, - 56101, - 56113, - 56126, - 56131, - 56134, - 56143, - 56148, - 56152, - 56174, - 56181, - 56182, - 56185, - 56192, - 56201, - 56215, - 56219, - 56222, - 56258, - 56264, - 56269, - 56272, - 56278, - 56282, - 56306, - 56308, - 56318, - 56329, - 56356, - 56360, - 56383, - 56388, - 56391, - 56405, - 56406, - 56416, - 56426, - 56439, - 56446, - 56450, - 56459, - 56461, - 56464, - 56469, - 56489, - 56490, - 56497, - 56509, - 56515, - 56518, - 56524, - 56535, - 56542, - 56545, - 56551, - 56555, - 56560, - 56569, - 56580, - 56584, - 56598, - 56601, - 56602, - 56623, - 56637, - 56638, - 56643, - 56650, - 56673, - 56676, - 56686, - 56704, - 56710, - 56721, - 56731, - 56738, - 56747, - 56750, - 56752, - 56757, - 56787, - 56796, - 56803, - 56812, - 56815, - 56824, - 56829, - 56833, - 56839, - 56840, - 56845, - 56853, - 56854, - 56858, - 56863, - 56864, - 56881, - 56882, - 56896, - 56901, - 56902, - 56908, - 56923, - 56925, - 56926, - 56932, - 56939, - 56947, - 56954, - 56970, - 56972, - 56977, - 56980, - 56993, - 57013, - 57017, - 57018, - 57031, - 57059, - 57062, - 57065, - 57071, - 57083, - 57093, - 57097, - 57106, - 57118, - 57133, - 57134, - 57141, - 57146, - 57156, - 57174, - 57183, - 57189, - 57190, - 57193, - 57196, - 57207, - 57211, - 57214, - 57218, - 57230, - 57235, - 57241, - 57251, - 57260, - 57263, - 57265, - 57271, - 57272, - 57290, - 57295, - 57298, - 57325, - 57328, - 57340, - 57344, - 57353, - 57368, - 57371, - 57383, - 57402, - 57407, - 57419, - 57424, - 57433, - 57452, - 57458, - 57467, - 57470, - 57473, - 57479, - 57480, - 57486, - 57491, - 57493, - 57524, - 57528, - 57534, - 57542, - 57560, - 57565, - 57570, - 57579, - 57590, - 57601, - 57604, - 57607, - 57621, - 57635, - 57642, - 57650, - 57655, - 57670, - 57676, - 57682, - 57687, - 57691, - 57700, - 57704, - 57707, - 57721, - 57731, - 57733, - 57738, - 57745, - 57748, - 57751, - 57757, - 57761, - 57774, - 57779, - 57786, - 57808, - 57814, - 57817, - 57824, - 57827, - 57848, - 57853, - 57857, - 57858, - 57867, - 57872, - 57887, - 57894, - 57915, - 57920, - 57923, - 57932, - 57937, - 57943, - 57950, - 57960, - 57971, - 57974, - 57983, - 57987, - 57994, - 58001, - 58002, - 58013, - 58023, - 58027, - 58029, - 58032, - 58041, - 58047, - 58062, - 58086, - 58092, - 58095, - 58097, - 58100, - 58117, - 58121, - 58132, - 58142, - 58145, - 58152, - 58155, - 58163, - 58166, - 58170, - 58175, - 58184, - 58197, - 58202, - 58204, - 58208, - 58213, - 58220, - 58226, - 58231, - 58235, - 58254, - 58261, - 58271, - 58278, - 58287, - 58327, - 58333, - 58337, - 58357, - 58362, - 58364, - 58375, - 58384, - 58387, - 58405, - 58406, - 58417, - 58424, - 58435, - 58450, - 58452, - 58459, - 58461, - 58466, - 58468, - 58485, - 58489, - 58492, - 58495, - 58505, - 58523, - 58535, - 58536, - 58549, - 58550, - 58561, - 58562, - 58573, - 58576, - 58592, - 58601, - 58622, - 58627, - 58629, - 58634, - 58639, - 58641, - 58644, - 58654, - 58663, - 58667, - 58677, - 58682, - 58690, - 58692, - 58695, - 58710, - 58713, - 58723, - 58740, - 58749, - 58760, - 58766, - 58773, - 58780, - 58787, - 58796, - 58816, - 58822, - 58831, - 58839, - 58849, - 58859, - 58870, - 58879, - 58889, - 58904, - 58914, - 58923, - 58940, - 58945, - 58952, - 58960, - 58965, - 58986, - 59000, - 59006, - 59027, - 59034, - 59052, - 59058, - 59081, - 59082, - 59089, - 59096, - 59118, - 59123, - 59126, - 59132, - 59135, - 59150, - 59174, - 59177, - 59185, - 59195, - 59203, - 59206, - 59234, - 59248, - 59258, - 59260, - 59270, - 59284, - 59291, - 59293, - 59297, - 59312, - 59315, - 59327, - 59332, - 59347, - 59354, - 59363, - 59369, - 59377, - 59406, - 59413, - 59423, - 59434, - 59441, - 59442, - 59456, - 59465, - 59479, - 59501, - 59504, - 59507, - 59514, - 59523, - 59525, - 59526, - 59537, - 59543, - 59560, - 59563, - 59566, - 59577, - 59580, - 59586, - 59597, - 59612, - 59615, - 59622, - 59631, - 59657, - 59660, - 59665, - 59671, - 59675, - 59688, - 59706, - 59708, - 59713, - 59714, - 59720, - 59737, - 59743, - 59744, - 59749, - 59756, - 59783, - 59784, - 59787, - 59795, - 59804, - 59811, - 59814, - 59823, - 59838, - 59840, - 59846, - 59849, - 59855, - 59860, - 59867, - 59869, - 59885, - 59888, - 59893, - 59904, - 59919, - 59922, - 59927, - 59937, - 59940, - 59944, - 59947, - 59949, - 59961, - 59975, - 59981, - 59994, - 59999, - 60018, - 60023, - 60024, - 60039, - 60043, - 60048, - 60054, - 60073, - 60079, - 60082, - 60102, - 60108, - 60111, - 60120, - 60149, - 60153, - 60161, - 60168, - 60176, - 60182, - 60185, - 60204, - 60212, - 60215, - 60219, - 60222, - 60229, - 60234, - 60241, - 60248, - 60277, - 60282, - 60287, - 60303, - 60306, - 60327, - 60333, - 60334, - 60336, - 60345, - 60359, - 60368, - 60380, - 60389, - 60390, - 60394, - 60407, - 60414, - 60419, - 60426, - 60428, - 60431, - 60440, - 60450, - 60469, - 60473, - 60474, - 60484, - 60496, - 60502, - 60508, - 60511, - 60522, - 60529, - 60530, - 60536, - 60551, - 60557, - 60566, - 60576, - 60579, - 60585, - 60588, - 60600, - 60613, - 60628, - 60631, - 60648, - 60651, - 60653, - 60671, - 60673, - 60691, - 60697, - 60700, - 60714, - 60724, - 60728, - 60733, - 60736, - 60745, - 60746, - 60753, - 60754, - 60782, - 60784, - 60790, - 60793, - 60805, - 60830, - 60836, - 60846, - 60851, - 60880, - 60896, - 60905, - 60923, - 60925, - 60932, - 60939, - 60942, - 60953, - 60956, - 60959, - 60963, - 60969, - 60978, - 60980, - 60987, - 61007, - 61012, - 61015, - 61025, - 61026, - 61038, - 61040, - 61052, - 61061, - 61074, - 61083, - 61085, - 61086, - 61096, - 61119, - 61124, - 61127, - 61128, - 61133, - 61134, - 61146, - 61155, - 61161, - 61162, - 61169, - 61179, - 61182, - 61190, - 61201, - 61208, - 61238, - 61241, - 61247, - 61259, - 61267, - 61269, - 61295, - 61304, - 61309, - 61310, - 61313, - 61320, - 61325, - 61334, - 61337, - 61386, - 61399, - 61422, - 61429, - 61436, - 61439, - 61466, - 61477, - 61478, - 61490, - 61495, - 61504, - 61514, - 61516, - 61521, - 61527, - 61531, - 61540, - 61550, - 61557, - 61562, - 61577, - 61583, - 61597, - 61602, - 61604, - 61607, - 61622, - 61625, - 61633, - 61640, - 61643, - 61651, - 61658, - 61670, - 61674, - 61676, - 61679, - 61688, - 61693, - 61701, - 61711, - 61714, - 61723, - 61725, - 61726, - 61729, - 61741, - 61761, - 61779, - 61781, - 61782, - 61797, - 61809, - 61810, - 61816, - 61822, - 61849, - 61876, - 61893, - 61905, - 61908, - 61911, - 61912, - 61928, - 61934, - 61957, - 61961, - 61969, - 61979, - 61982, - 62003, - 62006, - 62010, - 62015, - 62020, - 62024, - 62029, - 62032, - 62035, - 62038, - 62047, - 62068, - 62071, - 62082, - 62088, - 62096, - 62108, - 62124, - 62142, - 62147, - 62153, - 62159, - 62161, - 62171, - 62189, - 62207, - 62227, - 62230, - 62234, - 62236, - 62239, - 62257, - 62270, - 62278, - 62287, - 62295, - 62301, - 62306, - 62312, - 62317, - 62330, - 62342, - 62359, - 62365, - 62366, - 62370, - 62375, - 62376, - 62387, - 62404, - 62411, - 62435, - 62441, - 62442, - 62452, - 62459, - 62461, - 62473, - 62474, - 62493, - 62510, - 62518, - 62524, - 62549, - 62556, - 62565, - 62566, - 62580, - 62584, - 62589, - 62596, - 62608, - 62636, - 62642, - 62651, - 62654, - 62659, - 62666, - 62680, - 62692, - 62701, - 62702, - 62714, - 62716, - 62733, - 62762, - 62769, - 62770, - 62787, - 62794, - 62801, - 62807, - 62808, - 62813, - 62817, - 62818, - 62832, - 62841, - 62857, - 62860, - 62871, - 62882, - 62888, - 62913, - 62919, - 62920, - 62925, - 62933, - 62938, - 62940, - 62949, - 62956, - 62971, - 62978, - 62990, - 62995, - 62997, - 63004, - 63011, - 63032, - 63038, - 63067, - 63069, - 63076, - 63083, - 63088, - 63094, - 63097, - 63100, - 63104, - 63114, - 63116, - 63122, - 63128, - 63149, - 63150, - 63157, - 63167, - 63187, - 63200, - 63220, - 63223, - 63229, - 63235, - 63247, - 63252, - 63255, - 63289, - 63298, - 63303, - 63327, - 63328, - 63348, - 63355, - 63357, - 63368, - 63391, - 63402, - 63409, - 63416, - 63419, - 63430, - 63442, - 63457, - 63458, - 63482, - 63487, - 63488, - 63500, - 63511, - 63517, - 63528, - 63531, - 63559, - 63566, - 63578, - 63580, - 63584, - 63587, - 63594, - 63607, - 63611, - 63630, - 63632, - 63641, - 63647, - 63651, - 63666, - 63668, - 63695, - 63697, - 63709, - 63723, - 63737, - 63746, - 63752, - 63755, - 63775, - 63781, - 63794, - 63796, - 63808, - 63817, - 63820, - 63826, - 63838, - 63848, - 63861, - 63862, - 63866, - 63878, - 63889, - 63892, - 63901, - 63915, - 63917, - 63926, - 63932, - 63937, - 63938, - 63943, - 63944, - 63950, - 63952, - 63955, - 63957, - 63961, - 63962, - 63978, - 63983, - 63988, - 64008, - 64013, - 64019, - 64026, - 64028, - 64032, - 64042, - 64044, - 64055, - 64070, - 64079, - 64084, - 64087, - 64093, - 64100, - 64104, - 64109, - 64140, - 64148, - 64151, - 64152, - 64171, - 64179, - 64186, - 64203, - 64206, - 64213, - 64214, - 64220, - 64233, - 64239, - 64248, - 64251, - 64259, - 64268, - 64273, - 64279, - 64283, - 64292, - 64296, - 64301, - 64302, - 64324, - 64331, - 64346, - 64364, - 64382, - 64386, - 64400, - 64409, - 64419, - 64433, - 64454, - 64458, - 64482, - 64494, - 64496, - 64505, - 64514, - 64519, - 64525, - 64528, - 64534, - 64561, - 64571, - 64579, - 64591, - 64606, - 64616, - 64619, - 64640, - 64645, - 64649, - 64652, - 64670, - 64673, - 64674, - 64683, - 64697, - 64703, - 64711, - 64723, - 64736, - 64739, - 64741, - 64748, - 64759, - 64768, - 64771, - 64778, - 64792, - 64821, - 64831, - 64839, - 64848, - 64860, - 64867, - 64870, - 64874, - 64879, - 64887, - 64894, - 64897, - 64898, - 64921, - 64933, - 64940, - 64957, - 64969, - 64972, - 64978, - 64984, - 64993, - 64999, - 65000, - 65006, - 65011, - 65014, - 65036, - 65044, - 65063, - 65067, - 65075, - 65077, - 65082, - 65095, - 65101, - 65104, - 65109, - 65110, - 65116, - 65126, - 65129, - 65138, - 65160, - 65171, - 65173, - 65180, - 65189, - 65193, - 65208, - 65214, - 65216, - 65225, - 65236, - 65239, - 65273, - 65274, - 65281, - 65294, - 65324, - 65335, - 65354, - 65359, - 65373, - 65383, - 65387, - 65397, - 65411, - 65413, - 65418, - 65441, - 65444, - 65447, - 65448, - 65473, - 65476, - 65480, - 65494, - 65509, - 65519, - 65527, - -1 }; - //#endif - - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_17 - static long[] PrimitivePolynomialDegree18 = { - 19, - 31, - 38, - 61, - 64, - 109, - 115, - 118, - 131, - 167, - 200, - 241, - 244, - 247, - 261, - 265, - 304, - 314, - 341, - 376, - 395, - 405, - 406, - 443, - 451, - 458, - 460, - 468, - 472, - 482, - 491, - 496, - 524, - 536, - 542, - 557, - 572, - 580, - 592, - 656, - 713, - 719, - 738, - 749, - 752, - 767, - 772, - 782, - 789, - 830, - 838, - 916, - 920, - 936, - 991, - 998, - 1016, - 1024, - 1053, - 1081, - 1090, - 1125, - 1135, - 1143, - 1150, - 1154, - 1171, - 1174, - 1202, - 1213, - 1225, - 1233, - 1234, - 1252, - 1255, - 1294, - 1349, - 1354, - 1378, - 1383, - 1387, - 1392, - 1402, - 1420, - 1428, - 1437, - 1448, - 1459, - 1473, - 1507, - 1516, - 1528, - 1573, - 1592, - 1597, - 1654, - 1663, - 1730, - 1739, - 1741, - 1753, - 1783, - 1804, - 1807, - 1832, - 1850, - 1852, - 1881, - 1894, - 1927, - 1952, - 1969, - 1999, - 2018, - 2047, - 2066, - 2068, - 2093, - 2105, - 2116, - 2149, - 2201, - 2228, - 2245, - 2246, - 2283, - 2288, - 2320, - 2326, - 2386, - 2392, - 2395, - 2413, - 2419, - 2441, - 2466, - 2477, - 2485, - 2492, - 2495, - 2498, - 2504, - 2515, - 2521, - 2561, - 2579, - 2604, - 2657, - 2681, - 2691, - 2731, - 2739, - 2765, - 2790, - 2802, - 2819, - 2891, - 2905, - 2911, - 2912, - 2921, - 2924, - 2945, - 2952, - 2972, - 2986, - 3000, - 3008, - 3011, - 3018, - 3047, - 3071, - 3079, - 3083, - 3086, - 3148, - 3156, - 3194, - 3230, - 3233, - 3254, - 3268, - 3305, - 3323, - 3326, - 3343, - 3345, - 3382, - 3413, - 3420, - 3434, - 3453, - 3472, - 3488, - 3503, - 3506, - 3518, - 3532, - 3543, - 3547, - 3573, - 3574, - 3587, - 3632, - 3664, - 3713, - 3726, - 3768, - 3771, - 3810, - 3848, - 3868, - 3896, - 3910, - 3921, - 3928, - 3940, - 3947, - 3949, - 4001, - 4004, - 4022, - 4026, - 4036, - 4073, - 4093, - 4099, - 4120, - 4136, - 4156, - 4176, - 4182, - 4191, - 4198, - 4252, - 4259, - 4261, - 4294, - 4341, - 4348, - 4356, - 4384, - 4389, - 4401, - 4428, - 4431, - 4445, - 4470, - 4473, - 4474, - 4490, - 4509, - 4510, - 4533, - 4548, - 4558, - 4594, - 4596, - 4603, - 4610, - 4619, - 4630, - 4652, - 4658, - 4682, - 4708, - 4736, - 4753, - 4760, - 4781, - 4784, - 4799, - 4807, - 4808, - 4842, - 4882, - 4897, - 4900, - 4922, - 4936, - 4960, - 4970, - 4978, - 4994, - 5003, - 5044, - 5061, - 5107, - 5127, - 5131, - 5136, - 5145, - 5146, - 5175, - 5218, - 5223, - 5248, - 5294, - 5299, - 5301, - 5311, - 5343, - 5344, - 5396, - 5406, - 5410, - 5424, - 5447, - 5461, - 5468, - 5475, - 5478, - 5523, - 5530, - 5535, - 5548, - 5559, - 5580, - 5604, - 5622, - 5641, - 5649, - 5656, - 5671, - 5689, - 5721, - 5731, - 5734, - 5738, - 5740, - 5748, - 5791, - 5801, - 5807, - 5822, - 5829, - 5834, - 5847, - 5854, - 5878, - 5882, - 5919, - 5947, - 5981, - 5982, - 6025, - 6028, - 6039, - 6056, - 6064, - 6073, - 6081, - 6088, - 6101, - 6139, - 6142, - 6194, - 6199, - 6200, - 6203, - 6214, - 6238, - 6241, - 6244, - 6248, - 6256, - 6266, - 6271, - 6275, - 6295, - 6315, - 6364, - 6368, - 6377, - 6400, - 6430, - 6477, - 6480, - 6490, - 6526, - 6539, - 6556, - 6584, - 6598, - 6601, - 6609, - 6612, - 6645, - 6655, - 6679, - 6683, - 6719, - 6727, - 6734, - 6770, - 6776, - 6791, - 6798, - 6800, - 6826, - 6833, - 6836, - 6858, - 6882, - 6901, - 6923, - 6967, - 6979, - 7022, - 7060, - 7064, - 7083, - 7093, - 7094, - 7120, - 7125, - 7142, - 7151, - 7165, - 7173, - 7188, - 7191, - 7202, - 7216, - 7219, - 7267, - 7358, - 7383, - 7387, - 7396, - 7408, - 7432, - 7462, - 7480, - 7488, - 7497, - 7531, - 7561, - 7582, - 7591, - 7612, - 7677, - 7687, - 7701, - 7705, - 7712, - 7721, - 7736, - 7756, - 7777, - 7783, - 7792, - 7797, - 7802, - 7808, - 7866, - 7885, - 7891, - 7913, - 7936, - 7946, - 7963, - 7996, - 7999, - 8011, - 8014, - 8028, - 8047, - 8077, - 8101, - 8119, - 8125, - 8140, - 8152, - 8209, - 8212, - 8231, - 8258, - 8275, - 8303, - 8308, - 8312, - 8345, - 8346, - 8370, - 8402, - 8411, - 8414, - 8424, - 8435, - 8452, - 8462, - 8479, - 8509, - 8515, - 8522, - 8541, - 8560, - 8563, - 8585, - 8594, - 8596, - 8603, - 8610, - 8647, - 8661, - 8662, - 8672, - 8690, - 8696, - 8739, - 8783, - 8811, - 8813, - 8821, - 8856, - 8877, - 8885, - 8897, - 8898, - 8934, - 8955, - 8972, - 8977, - 9038, - 9045, - 9071, - 9085, - 9110, - 9120, - 9157, - 9164, - 9185, - 9203, - 9235, - 9278, - 9290, - 9292, - 9319, - 9334, - 9362, - 9387, - 9404, - 9407, - 9410, - 9422, - 9478, - 9512, - 9535, - 9604, - 9616, - 9622, - 9631, - 9656, - 9710, - 9721, - 9728, - 9733, - 9738, - 9774, - 9791, - 9803, - 9805, - 9817, - 9823, - 9839, - 9847, - 9854, - 9863, - 9872, - 9884, - 9935, - 9937, - 9974, - 9980, - 10003, - 10015, - 10016, - 10066, - 10093, - 10118, - 10132, - 10135, - 10151, - 10158, - 10169, - 10172, - 10180, - 10187, - 10189, - 10192, - 10197, - 10211, - 10214, - 10256, - 10278, - 10290, - 10301, - 10310, - 10344, - 10473, - 10474, - 10482, - 10499, - 10525, - 10532, - 10535, - 10556, - 10568, - 10579, - 10586, - 10609, - 10612, - 10650, - 10665, - 10685, - 10686, - 10688, - 10711, - 10728, - 10748, - 10751, - 10781, - 10805, - 10823, - 10838, - 10857, - 10865, - 10872, - 10893, - 10899, - 10917, - 10935, - 11001, - 11072, - 11089, - 11090, - 11108, - 11117, - 11136, - 11148, - 11153, - 11181, - 11190, - 11201, - 11204, - 11216, - 11237, - 11259, - 11279, - 11282, - 11304, - 11312, - 11332, - 11341, - 11354, - 11356, - 11365, - 11377, - 11417, - 11427, - 11433, - 11434, - 11439, - 11444, - 11448, - 11461, - 11466, - 11468, - 11473, - 11489, - 11499, - 11516, - 11531, - 11533, - 11557, - 11572, - 11608, - 11635, - 11638, - 11644, - 11684, - 11702, - 11740, - 11749, - 11754, - 11764, - 11767, - 11784, - 11789, - 11795, - 11798, - 11804, - 11818, - 11820, - 11860, - 11869, - 11874, - 11903, - 11916, - 11927, - 11933, - 11962, - 12009, - 12020, - 12035, - 12041, - 12049, - 12065, - 12072, - 12098, - 12100, - 12107, - 12167, - 12202, - 12207, - 12233, - 12269, - 12290, - 12304, - 12314, - 12340, - 12416, - 12425, - 12428, - 12446, - 12462, - 12476, - 12496, - 12511, - 12518, - 12530, - 12532, - 12539, - 12567, - 12597, - 12601, - 12602, - 12622, - 12693, - 12707, - 12713, - 12716, - 12734, - 12763, - 12765, - 12799, - 12843, - 12853, - 12865, - 12866, - 12919, - 12926, - 12936, - 12944, - 12959, - 12965, - 12980, - 13004, - 13016, - 13019, - 13037, - 13055, - 13063, - 13098, - 13103, - 13106, - 13115, - 13143, - 13144, - 13153, - 13171, - 13184, - 13193, - 13199, - 13207, - 13217, - 13227, - 13232, - 13276, - 13283, - 13307, - 13317, - 13330, - 13345, - 13363, - 13387, - 13426, - 13428, - 13431, - 13489, - 13501, - 13533, - 13589, - 13600, - 13603, - 13623, - 13665, - 13672, - 13675, - 13708, - 13713, - 13720, - 13730, - 13735, - 13767, - 13773, - 13792, - 13843, - 13891, - 13946, - 13967, - 13976, - 14017, - 14030, - 14041, - 14054, - 14058, - 14060, - 14063, - 14078, - 14080, - 14089, - 14131, - 14134, - 14137, - 14188, - 14215, - 14222, - 14249, - 14292, - 14320, - 14339, - 14346, - 14353, - 14365, - 14384, - 14414, - 14428, - 14435, - 14483, - 14486, - 14506, - 14513, - 14520, - 14526, - 14528, - 14533, - 14576, - 14599, - 14613, - 14639, - 14644, - 14653, - 14662, - 14695, - 14704, - 14713, - 14725, - 14783, - 14810, - 14816, - 14822, - 14828, - 14883, - 14889, - 14904, - 14917, - 14927, - 14941, - 14946, - 14952, - 15010, - 15012, - 15033, - 15041, - 15047, - 15066, - 15068, - 15072, - 15095, - 15150, - 15152, - 15175, - 15176, - 15210, - 15245, - 15258, - 15263, - 15264, - 15279, - 15301, - 15306, - 15313, - 15329, - 15341, - 15367, - 15368, - 15386, - 15404, - 15422, - 15436, - 15444, - 15467, - 15498, - 15503, - 15528, - 15534, - 15536, - 15559, - 15565, - 15583, - 15599, - 15602, - 15616, - 15626, - 15667, - 15684, - 15711, - 15745, - 15763, - 15779, - 15811, - 15814, - 15817, - 15853, - 15881, - 15890, - 15899, - 15905, - 15915, - 15937, - 15950, - 16002, - 16041, - 16042, - 16052, - 16121, - 16132, - 16136, - 16150, - 16153, - 16180, - 16190, - 16192, - 16195, - 16210, - 16225, - 16256, - 16266, - 16274, - 16302, - 16310, - 16322, - 16339, - 16345, - 16348, - 16357, - 16382, - 16402, - 16461, - 16469, - 16474, - 16483, - 16497, - 16523, - 16534, - 16550, - 16564, - 16582, - 16591, - 16609, - 16642, - 16648, - 16656, - 16662, - 16665, - 16678, - 16701, - 16713, - 16716, - 16758, - 16768, - 16797, - 16804, - 16811, - 16813, - 16881, - 16888, - 16893, - 16922, - 16937, - 16958, - 16965, - 16978, - 16980, - 16989, - 17011, - 17014, - 17023, - 17063, - 17081, - 17084, - 17099, - 17126, - 17129, - 17138, - 17164, - 17170, - 17203, - 17206, - 17224, - 17305, - 17322, - 17327, - 17332, - 17342, - 17387, - 17410, - 17419, - 17429, - 17439, - 17440, - 17457, - 17458, - 17469, - 17477, - 17512, - 17518, - 17532, - 17536, - 17559, - 17569, - 17641, - 17667, - 17674, - 17693, - 17710, - 17729, - 17754, - 17763, - 17780, - 17784, - 17790, - 17830, - 17851, - 17868, - 17879, - 17896, - 17901, - 17916, - 17935, - 17953, - 17991, - 18009, - 18016, - 18034, - 18061, - 18070, - 18079, - 18132, - 18145, - 18169, - 18170, - 18190, - 18192, - 18201, - 18228, - 18243, - 18260, - 18279, - 18285, - 18297, - 18300, - 18321, - 18344, - 18358, - 18364, - 18376, - 18390, - 18399, - 18400, - 18427, - 18443, - 18487, - 18493, - 18508, - 18532, - 18535, - 18580, - 18587, - 18606, - 18659, - 18662, - 18679, - 18694, - 18697, - 18706, - 18708, - 18728, - 18731, - 18733, - 18751, - 18766, - 18773, - 18796, - 18811, - 18823, - 18832, - 18854, - 18858, - 18883, - 18900, - 18967, - 18974, - 18990, - 19009, - 19055, - 19058, - 19074, - 19079, - 19086, - 19128, - 19145, - 19163, - 19175, - 19189, - 19196, - 19204, - 19213, - 19237, - 19276, - 19287, - 19291, - 19293, - 19304, - 19371, - 19379, - 19381, - 19405, - 19417, - 19420, - 19424, - 19462, - 19474, - 19492, - 19501, - 19504, - 19516, - 19519, - 19534, - 19555, - 19597, - 19600, - 19615, - 19621, - 19646, - 19651, - 19693, - 19702, - 19726, - 19754, - 19759, - 19764, - 19788, - 19793, - 19836, - 19855, - 19858, - 19880, - 19883, - 19917, - 19918, - 19936, - 19946, - 19954, - 19979, - 19993, - 19994, - 20006, - 20017, - 20032, - 20038, - 20050, - 20080, - 20135, - 20142, - 20159, - 20173, - 20186, - 20229, - 20234, - 20263, - 20270, - 20299, - 20304, - 20319, - 20329, - 20337, - 20353, - 20401, - 20434, - 20436, - 20473, - 20488, - 20512, - 20515, - 20517, - 20530, - 20571, - 20574, - 20589, - 20592, - 20611, - 20613, - 20628, - 20637, - 20638, - 20719, - 20724, - 20772, - 20796, - 20799, - 20816, - 20841, - 20844, - 20862, - 20865, - 20902, - 20938, - 20957, - 20971, - 20973, - 20981, - 20982, - 20985, - 20991, - 21012, - 21022, - 21026, - 21028, - 21050, - 21075, - 21077, - 21078, - 21106, - 21122, - 21127, - 21155, - 21167, - 21169, - 21204, - 21230, - 21256, - 21285, - 21312, - 21329, - 21351, - 21372, - 21376, - 21424, - 21448, - 21465, - 21495, - 21509, - 21550, - 21562, - 21575, - 21579, - 21582, - 21600, - 21615, - 21617, - 21624, - 21633, - 21636, - 21645, - 21654, - 21660, - 21667, - 21702, - 21714, - 21719, - 21736, - 21767, - 21781, - 21795, - 21841, - 21853, - 21867, - 21878, - 21891, - 21897, - 21954, - 21956, - 21965, - 21977, - 21978, - 21983, - 22002, - 22013, - 22014, - 22054, - 22058, - 22066, - 22085, - 22103, - 22138, - 22140, - 22153, - 22164, - 22167, - 22189, - 22202, - 22212, - 22234, - 22239, - 22245, - 22272, - 22308, - 22318, - 22320, - 22338, - 22350, - 22374, - 22388, - 22391, - 22422, - 22426, - 22441, - 22481, - 22488, - 22500, - 22517, - 22531, - 22552, - 22574, - 22579, - 22582, - 22586, - 22594, - 22611, - 22614, - 22700, - 22711, - 22749, - 22759, - 22774, - 22777, - 22780, - 22783, - 22785, - 22840, - 22878, - 22884, - 22888, - 22927, - 22941, - 22951, - 22958, - 22980, - 23007, - 23032, - 23041, - 23044, - 23059, - 23065, - 23072, - 23137, - 23144, - 23155, - 23162, - 23167, - 23183, - 23192, - 23197, - 23216, - 23221, - 23228, - 23233, - 23234, - 23251, - 23257, - 23258, - 23288, - 23302, - 23341, - 23373, - 23402, - 23409, - 23428, - 23435, - 23440, - 23449, - 23459, - 23473, - 23500, - 23511, - 23548, - 23560, - 23563, - 23594, - 23601, - 23625, - 23640, - 23650, - 23662, - 23692, - 23726, - 23738, - 23743, - 23755, - 23760, - 23799, - 23848, - 23859, - 23876, - 23897, - 23907, - 23919, - 23921, - 23931, - 23933, - 23943, - 23957, - 23986, - 24020, - 24043, - 24064, - 24082, - 24084, - 24088, - 24117, - 24149, - 24165, - 24223, - 24247, - 24259, - 24283, - 24296, - 24336, - 24342, - 24389, - 24394, - 24414, - 24424, - 24441, - 24491, - 24502, - 24534, - 24540, - 24543, - 24549, - 24567, - 24583, - 24693, - 24704, - 24719, - 24749, - 24799, - 24830, - 24835, - 24907, - 24917, - 24940, - 24943, - 24958, - 24962, - 24964, - 24968, - 25015, - 25024, - 25027, - 25033, - 25041, - 25047, - 25057, - 25082, - 25093, - 25105, - 25112, - 25117, - 25131, - 25139, - 25194, - 25204, - 25244, - 25247, - 25253, - 25258, - 25275, - 25320, - 25338, - 25343, - 25351, - 25358, - 25372, - 25399, - 25408, - 25432, - 25442, - 25462, - 25465, - 25468, - 25482, - 25489, - 25490, - 25505, - 25511, - 25512, - 25552, - 25555, - 25595, - 25636, - 25672, - 25685, - 25696, - 25720, - 25730, - 25735, - 25753, - 25756, - 25769, - 25821, - 25825, - 25840, - 25860, - 25869, - 25872, - 25956, - 25973, - 25994, - 26002, - 26020, - 26023, - 26041, - 26044, - 26069, - 26097, - 26113, - 26138, - 26167, - 26216, - 26230, - 26243, - 26245, - 26263, - 26264, - 26269, - 26311, - 26346, - 26354, - 26365, - 26368, - 26398, - 26401, - 26426, - 26436, - 26443, - 26448, - 26458, - 26464, - 26476, - 26503, - 26504, - 26515, - 26531, - 26548, - 26570, - 26589, - 26594, - 26608, - 26623, - 26678, - 26690, - 26709, - 26725, - 26744, - 26763, - 26765, - 26768, - 26784, - 26802, - 26814, - 26856, - 26861, - 26862, - 26894, - 26908, - 26915, - 26929, - 26930, - 26939, - 26941, - 26987, - 27023, - 27066, - 27079, - 27086, - 27091, - 27113, - 27157, - 27174, - 27188, - 27191, - 27197, - 27206, - 27210, - 27245, - 27254, - 27383, - 27387, - 27416, - 27422, - 27472, - 27478, - 27548, - 27579, - 27582, - 27589, - 27593, - 27613, - 27649, - 27717, - 27729, - 27751, - 27757, - 27766, - 27791, - 27794, - 27854, - 27856, - 27866, - 27875, - 27902, - 27916, - 27924, - 27933, - 27940, - 27947, - 27969, - 27981, - 27996, - 28005, - 28030, - 28064, - 28102, - 28108, - 28120, - 28125, - 28130, - 28142, - 28149, - 28165, - 28169, - 28177, - 28211, - 28213, - 28220, - 28261, - 28271, - 28299, - 28326, - 28330, - 28350, - 28355, - 28367, - 28376, - 28379, - 28381, - 28447, - 28465, - 28471, - 28472, - 28478, - 28480, - 28489, - 28514, - 28525, - 28537, - 28550, - 28559, - 28595, - 28601, - 28629, - 28657, - 28667, - 28711, - 28718, - 28730, - 28732, - 28777, - 28801, - 28822, - 28855, - 28859, - 28869, - 28893, - 28904, - 28922, - 28930, - 28949, - 28972, - 29002, - 29009, - 29061, - 29068, - 29107, - 29119, - 29142, - 29146, - 29152, - 29200, - 29206, - 29245, - 29254, - 29258, - 29260, - 29268, - 29281, - 29306, - 29317, - 29324, - 29342, - 29375, - 29384, - 29389, - 29411, - 29413, - 29446, - 29457, - 29458, - 29483, - 29488, - 29494, - 29506, - 29553, - 29569, - 29587, - 29590, - 29600, - 29612, - 29665, - 29722, - 29745, - 29746, - 29752, - 29775, - 29778, - 29800, - 29829, - 29830, - 29877, - 29881, - 29884, - 29895, - 29899, - 29916, - 29923, - 29935, - 29955, - 29962, - 29969, - 29997, - 30032, - 30041, - 30048, - 30060, - 30063, - 30105, - 30122, - 30141, - 30142, - 30153, - 30171, - 30192, - 30197, - 30223, - 30235, - 30241, - 30256, - 30291, - 30293, - 30300, - 30331, - 30349, - 30361, - 30367, - 30392, - 30405, - 30410, - 30415, - 30439, - 30446, - 30501, - 30526, - 30531, - 30537, - 30546, - 30568, - 30581, - 30588, - 30598, - 30607, - 30609, - 30616, - 30626, - 30628, - 30638, - 30658, - 30663, - 30675, - 30698, - 30708, - 30712, - 30727, - 30736, - 30748, - 30758, - 30775, - 30793, - 30802, - 30820, - 30823, - 30827, - 30848, - 30893, - 30906, - 30950, - 30956, - 30996, - 31015, - 31016, - 31034, - 31099, - 31123, - 31145, - 31166, - 31168, - 31174, - 31216, - 31219, - 31238, - 31256, - 31304, - 31315, - 31324, - 31364, - 31379, - 31382, - 31412, - 31451, - 31487, - 31509, - 31510, - 31520, - 31535, - 31564, - 31585, - 31586, - 31600, - 31643, - 31646, - 31649, - 31650, - 31674, - 31679, - 31684, - 31688, - 31706, - 31735, - 31754, - 31761, - 31774, - 31807, - 31812, - 31821, - 31855, - 31919, - 31934, - 31956, - 31965, - 31975, - 31981, - 31999, - 32014, - 32022, - 32049, - 32055, - 32082, - 32087, - 32100, - 32104, - 32109, - 32138, - 32140, - 32148, - 32161, - 32162, - 32174, - 32196, - 32220, - 32223, - 32267, - 32272, - 32308, - 32315, - 32317, - 32347, - 32360, - 32394, - 32411, - 32420, - 32423, - 32455, - 32456, - 32510, - 32517, - 32541, - 32552, - 32555, - 32580, - 32598, - 32654, - 32662, - 32665, - 32678, - 32682, - 32687, - 32692, - 32710, - 32791, - 32792, - 32813, - 32826, - 32831, - 32836, - 32843, - 32854, - 32893, - 32897, - 32912, - 32951, - 32963, - 32970, - 32975, - 33028, - 33052, - 33061, - 33083, - 33103, - 33117, - 33139, - 33151, - 33162, - 33209, - 33210, - 33223, - 33227, - 33241, - 33263, - 33341, - 33344, - 33356, - 33390, - 33398, - 33423, - 33428, - 33444, - 33454, - 33479, - 33510, - 33514, - 33528, - 33548, - 33566, - 33570, - 33593, - 33599, - 33619, - 33635, - 33659, - 33680, - 33699, - 33713, - 33758, - 33771, - 33779, - 33800, - 33829, - 33836, - 33844, - 33856, - 33859, - 33873, - 33874, - 33929, - 33944, - 33965, - 33978, - 33986, - 34006, - 34025, - 34106, - 34126, - 34171, - 34189, - 34204, - 34260, - 34270, - 34280, - 34298, - 34313, - 34321, - 34333, - 34370, - 34376, - 34387, - 34389, - 34417, - 34429, - 34440, - 34443, - 34451, - 34470, - 34484, - 34493, - 34496, - 34514, - 34526, - 34535, - 34585, - 34591, - 34592, - 34602, - 34607, - 34644, - 34657, - 34675, - 34681, - 34693, - 34706, - 34745, - 34759, - 34765, - 34774, - 34780, - 34794, - 34807, - 34808, - 34835, - 34842, - 34865, - 34907, - 34928, - 34949, - 34961, - 34964, - 34987, - 34990, - 35019, - 35069, - 35077, - 35090, - 35152, - 35173, - 35174, - 35202, - 35214, - 35219, - 35226, - 35235, - 35255, - 35310, - 35318, - 35321, - 35333, - 35337, - 35346, - 35373, - 35414, - 35478, - 35497, - 35503, - 35512, - 35515, - 35526, - 35577, - 35585, - 35592, - 35615, - 35616, - 35622, - 35634, - 35657, - 35672, - 35708, - 35772, - 35790, - 35804, - 35811, - 35814, - 35837, - 35846, - 35873, - 35883, - 35918, - 35920, - 35925, - 35926, - 35945, - 35956, - 36003, - 36023, - 36024, - 36059, - 36061, - 36072, - 36075, - 36103, - 36110, - 36131, - 36151, - 36160, - 36199, - 36223, - 36227, - 36234, - 36236, - 36284, - 36319, - 36332, - 36343, - 36373, - 36401, - 36413, - 36433, - 36459, - 36480, - 36485, - 36510, - 36513, - 36523, - 36528, - 36537, - 36558, - 36563, - 36576, - 36608, - 36611, - 36617, - 36653, - 36716, - 36721, - 36733, - 36761, - 36783, - 36786, - 36795, - 36800, - 36810, - 36812, - 36817, - 36818, - 36851, - 36853, - 36868, - 36889, - 36890, - 36896, - 36905, - 36919, - 36938, - 36946, - 36951, - 36952, - 36964, - 36968, - 36979, - 36981, - 37021, - 37026, - 37075, - 37077, - 37108, - 37112, - 37150, - 37154, - 37156, - 37163, - 37178, - 37183, - 37185, - 37191, - 37198, - 37203, - 37225, - 37243, - 37252, - 37262, - 37264, - 37276, - 37327, - 37355, - 37403, - 37415, - 37422, - 37448, - 37451, - 37478, - 37484, - 37525, - 37553, - 37640, - 37645, - 37658, - 37667, - 37708, - 37723, - 37732, - 37747, - 37753, - 37772, - 37789, - 37817, - 37826, - 37831, - 37845, - 37855, - 37859, - 37866, - 37880, - 37885, - 37897, - 37906, - 37948, - 37954, - 37978, - 37980, - 37990, - 38001, - 38020, - 38029, - 38047, - 38063, - 38077, - 38110, - 38116, - 38119, - 38176, - 38186, - 38194, - 38218, - 38241, - 38247, - 38261, - 38268, - 38277, - 38287, - 38295, - 38299, - 38301, - 38305, - 38312, - 38315, - 38317, - 38343, - 38344, - 38350, - 38358, - 38364, - 38371, - 38373, - 38377, - 38392, - 38407, - 38408, - 38421, - 38438, - 38442, - 38464, - 38473, - 38484, - 38491, - 38510, - 38518, - 38531, - 38537, - 38538, - 38567, - 38594, - 38647, - 38651, - 38654, - 38686, - 38702, - 38751, - 38821, - 38825, - 38853, - 38863, - 38882, - 38884, - 38932, - 38941, - 38952, - 38960, - 38980, - 38995, - 39004, - 39013, - 39017, - 39026, - 39056, - 39121, - 39124, - 39133, - 39157, - 39181, - 39187, - 39212, - 39223, - 39250, - 39265, - 39320, - 39330, - 39335, - 39353, - 39371, - 39385, - 39421, - 39432, - 39443, - 39450, - 39455, - 39468, - 39473, - 39488, - 39497, - 39521, - 39531, - 39542, - 39585, - 39605, - 39658, - 39677, - 39703, - 39726, - 39731, - 39745, - 39776, - 39796, - 39809, - 39833, - 39850, - 39869, - 39882, - 39906, - 39918, - 39929, - 39947, - 39985, - 39986, - 40023, - 40024, - 40039, - 40053, - 40079, - 40084, - 40087, - 40094, - 40100, - 40112, - 40129, - 40132, - 40142, - 40154, - 40177, - 40178, - 40202, - 40219, - 40303, - 40305, - 40311, - 40336, - 40342, - 40358, - 40381, - 40417, - 40438, - 40463, - 40471, - 40472, - 40488, - 40491, - 40525, - 40526, - 40550, - 40553, - 40562, - 40568, - 40580, - 40608, - 40613, - 40652, - 40703, - 40712, - 40720, - 40723, - 40746, - 40759, - 40765, - 40771, - 40778, - 40788, - 40804, - 40835, - 40841, - 40907, - 40934, - 40955, - 40986, - 41007, - 41016, - 41034, - 41041, - 41063, - 41084, - 41093, - 41097, - 41111, - 41118, - 41121, - 41141, - 41160, - 41207, - 41214, - 41255, - 41284, - 41287, - 41308, - 41330, - 41336, - 41437, - 41444, - 41456, - 41481, - 41489, - 41499, - 41555, - 41561, - 41562, - 41571, - 41592, - 41631, - 41661, - 41682, - 41710, - 41724, - 41727, - 41730, - 41744, - 41769, - 41795, - 41798, - 41804, - 41826, - 41852, - 41868, - 41910, - 41914, - 41942, - 41969, - 41975, - 41976, - 41994, - 42002, - 42037, - 42056, - 42079, - 42085, - 42089, - 42123, - 42128, - 42140, - 42149, - 42156, - 42186, - 42191, - 42205, - 42221, - 42222, - 42230, - 42233, - 42241, - 42247, - 42248, - 42254, - 42259, - 42268, - 42295, - 42304, - 42322, - 42334, - 42355, - 42361, - 42373, - 42374, - 42398, - 42411, - 42443, - 42446, - 42463, - 42479, - 42482, - 42484, - 42498, - 42534, - 42537, - 42557, - 42570, - 42599, - 42600, - 42633, - 42639, - 42672, - 42681, - 42687, - 42704, - 42713, - 42714, - 42716, - 42726, - 42730, - 42737, - 42752, - 42757, - 42772, - 42809, - 42853, - 42857, - 42902, - 42912, - 42930, - 42936, - 42956, - 42959, - 42978, - 43001, - 43011, - 43047, - 43059, - 43094, - 43124, - 43218, - 43220, - 43240, - 43258, - 43263, - 43265, - 43290, - 43346, - 43364, - 43373, - 43401, - 43416, - 43443, - 43458, - 43497, - 43506, - 43545, - 43558, - 43576, - 43579, - 43624, - 43630, - 43637, - 43654, - 43660, - 43696, - 43706, - 43725, - 43733, - 43753, - 43756, - 43761, - 43768, - 43812, - 43822, - 43841, - 43861, - 43868, - 43877, - 43878, - 43908, - 43917, - 43936, - 43954, - 43963, - 43977, - 44008, - 44013, - 44026, - 44028, - 44045, - 44046, - 44053, - 44091, - 44101, - 44129, - 44139, - 44172, - 44203, - 44211, - 44240, - 44259, - 44305, - 44383, - 44384, - 44389, - 44390, - 44432, - 44435, - 44468, - 44472, - 44483, - 44497, - 44550, - 44577, - 44584, - 44601, - 44674, - 44683, - 44688, - 44694, - 44703, - 44713, - 44721, - 44722, - 44733, - 44746, - 44748, - 44760, - 44765, - 44766, - 44775, - 44794, - 44822, - 44841, - 44859, - 44894, - 44900, - 44904, - 44946, - 44967, - 44994, - 44999, - 45013, - 45017, - 45020, - 45027, - 45029, - 45066, - 45074, - 45080, - 45090, - 45101, - 45110, - 45113, - 45134, - 45136, - 45148, - 45158, - 45176, - 45181, - 45185, - 45188, - 45203, - 45209, - 45231, - 45234, - 45239, - 45246, - 45260, - 45284, - 45301, - 45333, - 45350, - 45354, - 45446, - 45458, - 45518, - 45566, - 45569, - 45575, - 45576, - 45587, - 45615, - 45661, - 45798, - 45829, - 45847, - 45858, - 45864, - 45899, - 45904, - 45919, - 45974, - 45987, - 45989, - 46008, - 46036, - 46039, - 46043, - 46045, - 46079, - 46084, - 46091, - 46105, - 46117, - 46141, - 46147, - 46162, - 46184, - 46197, - 46207, - 46214, - 46218, - 46237, - 46247, - 46251, - 46327, - 46333, - 46342, - 46366, - 46376, - 46384, - 46404, - 46478, - 46511, - 46540, - 46638, - 46700, - 46706, - 46745, - 46757, - 46772, - 46776, - 46790, - 46794, - 46804, - 46820, - 46849, - 46870, - 46876, - 46903, - 46904, - 46907, - 46932, - 46955, - 46963, - 46991, - 47029, - 47036, - 47054, - 47099, - 47106, - 47132, - 47145, - 47151, - 47156, - 47171, - 47188, - 47201, - 47219, - 47226, - 47241, - 47252, - 47261, - 47295, - 47297, - 47333, - 47337, - 47360, - 47377, - 47378, - 47384, - 47389, - 47417, - 47420, - 47426, - 47443, - 47504, - 47507, - 47510, - 47526, - 47550, - 47552, - 47557, - 47564, - 47591, - 47610, - 47621, - 47639, - 47646, - 47676, - 47682, - 47732, - 47741, - 47751, - 47757, - 47786, - 47803, - 47828, - 47848, - 47853, - 47856, - 47862, - 47874, - 47883, - 47916, - 47934, - 47951, - 47979, - 48010, - 48027, - 48046, - 48060, - 48065, - 48075, - 48096, - 48119, - 48173, - 48176, - 48186, - 48213, - 48223, - 48224, - 48229, - 48241, - 48281, - 48284, - 48291, - 48308, - 48340, - 48344, - 48368, - 48400, - 48406, - 48409, - 48421, - 48448, - 48453, - 48457, - 48478, - 48493, - 48527, - 48583, - 48597, - 48641, - 48668, - 48671, - 48682, - 48709, - 48719, - 48731, - 48780, - 48791, - 48797, - 48807, - 48811, - 48814, - 48821, - 48836, - 48846, - 48848, - 48854, - 48874, - 48908, - 48929, - 48941, - 48954, - 48961, - 48962, - 48985, - 49001, - 49007, - 49015, - 49035, - 49062, - 49066, - 49085, - 49091, - 49094, - 49127, - 49134, - 49183, - 49221, - 49231, - 49250, - 49252, - 49270, - 49297, - 49313, - 49340, - 49365, - 49379, - 49386, - 49391, - 49417, - 49438, - 49444, - 49453, - 49454, - 49480, - 49485, - 49498, - 49513, - 49527, - 49531, - 49564, - 49588, - 49609, - 49617, - 49645, - 49646, - 49654, - 49697, - 49718, - 49741, - 49754, - 49756, - 49833, - 49834, - 49879, - 49942, - 49946, - 49982, - 49994, - 50001, - 50023, - 50047, - 50120, - 50133, - 50137, - 50140, - 50156, - 50199, - 50205, - 50215, - 50216, - 50224, - 50229, - 50233, - 50251, - 50281, - 50326, - 50332, - 50348, - 50359, - 50374, - 50404, - 50443, - 50488, - 50493, - 50505, - 50511, - 50525, - 50542, - 50550, - 50560, - 50570, - 50587, - 50593, - 50611, - 50649, - 50656, - 50685, - 50686, - 50692, - 50702, - 50704, - 50709, - 50720, - 50726, - 50729, - 50737, - 50758, - 50772, - 50849, - 50850, - 50881, - 50901, - 50906, - 50915, - 50961, - 50992, - 50997, - 51001, - 51004, - 51033, - 51045, - 51052, - 51064, - 51085, - 51127, - 51139, - 51153, - 51181, - 51182, - 51194, - 51196, - 51200, - 51239, - 51240, - 51254, - 51260, - 51342, - 51370, - 51372, - 51377, - 51398, - 51402, - 51407, - 51410, - 51412, - 51419, - 51428, - 51431, - 51460, - 51475, - 51477, - 51478, - 51482, - 51511, - 51518, - 51568, - 51607, - 51618, - 51630, - 51655, - 51673, - 51683, - 51709, - 51716, - 51774, - 51829, - 51830, - 51839, - 51849, - 51869, - 51886, - 51905, - 51906, - 51915, - 51948, - 51988, - 51998, - 52004, - 52026, - 52036, - 52082, - 52127, - 52145, - 52157, - 52165, - 52193, - 52211, - 52213, - 52218, - 52220, - 52238, - 52240, - 52243, - 52250, - 52279, - 52285, - 52306, - 52370, - 52432, - 52457, - 52466, - 52514, - 52557, - 52560, - 52585, - 52586, - 52603, - 52650, - 52672, - 52681, - 52692, - 52735, - 52760, - 52772, - 52781, - 52793, - 52796, - 52807, - 52821, - 52849, - 52866, - 52868, - 52872, - 52875, - 52886, - 52890, - 52896, - 52925, - 52931, - 52937, - 52938, - 52952, - 52979, - 53013, - 53023, - 53027, - 53033, - 53039, - 53041, - 53048, - 53073, - 53095, - 53099, - 53120, - 53154, - 53168, - 53192, - 53205, - 53206, - 53234, - 53246, - 53253, - 53263, - 53275, - 53313, - 53331, - 53349, - 53367, - 53383, - 53392, - 53404, - 53407, - 53411, - 53417, - 53425, - 53443, - 53469, - 53480, - 53508, - 53535, - 53536, - 53542, - 53563, - 53577, - 53591, - 53607, - 53626, - 53628, - 53638, - 53675, - 53685, - 53692, - 53703, - 53722, - 53738, - 53748, - 53752, - 53764, - 53781, - 53788, - 53791, - 53816, - 53824, - 53830, - 53839, - 53844, - 53875, - 53921, - 53922, - 53927, - 53948, - 53956, - 53990, - 53994, - 54001, - 54016, - 54019, - 54070, - 54074, - 54088, - 54102, - 54111, - 54130, - 54152, - 54170, - 54172, - 54211, - 54218, - 54228, - 54251, - 54253, - 54268, - 54271, - 54274, - 54288, - 54314, - 54319, - 54321, - 54324, - 54341, - 54353, - 54366, - 54370, - 54420, - 54423, - 54434, - 54440, - 54454, - 54495, - 54501, - 54526, - 54639, - 54653, - 54667, - 54678, - 54700, - 54717, - 54780, - 54801, - 54813, - 54814, - 54850, - 54883, - 54907, - 54919, - 54931, - 54933, - 54991, - 55003, - 55009, - 55030, - 55034, - 55039, - 55048, - 55059, - 55061, - 55068, - 55077, - 55122, - 55149, - 55157, - 55158, - 55178, - 55222, - 55234, - 55236, - 55251, - 55269, - 55270, - 55284, - 55309, - 55322, - 55334, - 55340, - 55348, - 55377, - 55430, - 55433, - 55441, - 55470, - 55535, - 55561, - 55567, - 55597, - 55630, - 55648, - 55653, - 55657, - 55665, - 55678, - 55684, - 55691, - 55693, - 55702, - 55708, - 55715, - 55739, - 55761, - 55767, - 55768, - 55774, - 55787, - 55811, - 55835, - 55894, - 55897, - 55904, - 55931, - 55950, - 55961, - 55973, - 56078, - 56099, - 56105, - 56119, - 56133, - 56168, - 56191, - 56202, - 56209, - 56215, - 56232, - 56240, - 56260, - 56270, - 56278, - 56281, - 56288, - 56303, - 56308, - 56312, - 56320, - 56326, - 56392, - 56395, - 56403, - 56419, - 56428, - 56450, - 56452, - 56485, - 56486, - 56492, - 56498, - 56510, - 56512, - 56524, - 56530, - 56545, - 56551, - 56565, - 56580, - 56587, - 56589, - 56592, - 56611, - 56623, - 56635, - 56646, - 56660, - 56680, - 56686, - 56716, - 56749, - 56790, - 56809, - 56869, - 56884, - 56887, - 56893, - 56906, - 56932, - 56959, - 56965, - 56983, - 57018, - 57023, - 57025, - 57032, - 57040, - 57046, - 57071, - 57091, - 57094, - 57108, - 57122, - 57127, - 57168, - 57183, - 57184, - 57193, - 57202, - 57235, - 57237, - 57251, - 57289, - 57349, - 57359, - 57374, - 57377, - 57387, - 57415, - 57440, - 57446, - 57450, - 57469, - 57491, - 57503, - 57507, - 57542, - 57569, - 57599, - 57601, - 57607, - 57608, - 57625, - 57644, - 57662, - 57664, - 57674, - 57698, - 57700, - 57709, - 57724, - 57728, - 57740, - 57745, - 57751, - 57774, - 57782, - 57796, - 57803, - 57823, - 57863, - 57894, - 57925, - 57971, - 58013, - 58020, - 58032, - 58038, - 58061, - 58069, - 58080, - 58089, - 58107, - 58121, - 58130, - 58146, - 58190, - 58195, - 58202, - 58237, - 58253, - 58299, - 58302, - 58327, - 58328, - 58364, - 58367, - 58375, - 58394, - 58405, - 58417, - 58424, - 58430, - 58452, - 58466, - 58468, - 58495, - 58501, - 58544, - 58571, - 58609, - 58610, - 58616, - 58619, - 58641, - 58642, - 58648, - 58660, - 58675, - 58678, - 58690, - 58735, - 58760, - 58766, - 58799, - 58825, - 58836, - 58855, - 58864, - 58910, - 58937, - 58943, - 58952, - 58965, - 58988, - 58994, - 58999, - 59006, - 59029, - 59033, - 59069, - 59096, - 59106, - 59123, - 59130, - 59152, - 59162, - 59180, - 59183, - 59195, - 59205, - 59210, - 59217, - 59218, - 59236, - 59267, - 59298, - 59318, - 59321, - 59327, - 59354, - 59363, - 59377, - 59389, - 59403, - 59420, - 59444, - 59471, - 59476, - 59483, - 59502, - 59509, - 59538, - 59556, - 59571, - 59592, - 59610, - 59654, - 59677, - 59699, - 59716, - 59719, - 59737, - 59747, - 59789, - 59807, - 59811, - 59818, - 59825, - 59826, - 59832, - 59858, - 59860, - 59873, - 59876, - 59907, - 59928, - 59933, - 59938, - 59940, - 59958, - 59984, - 60020, - 60024, - 60033, - 60034, - 60063, - 60070, - 60087, - 60091, - 60105, - 60126, - 60132, - 60154, - 60174, - 60181, - 60198, - 60212, - 60247, - 60254, - 60275, - 60284, - 60317, - 60318, - 60346, - 60360, - 60380, - 60389, - 60393, - 60401, - 60407, - 60408, - 60462, - 60484, - 60505, - 60521, - 60527, - 60532, - 60545, - 60546, - 60555, - 60563, - 60586, - 60626, - 60637, - 60665, - 60673, - 60685, - 60703, - 60734, - 60742, - 60790, - 60830, - 60848, - 60857, - 60871, - 60875, - 60913, - 60923, - 60972, - 60989, - 61001, - 61002, - 61019, - 61022, - 61059, - 61065, - 61066, - 61071, - 61076, - 61141, - 61148, - 61167, - 61190, - 61218, - 61247, - 61256, - 61289, - 61292, - 61307, - 61319, - 61353, - 61362, - 61379, - 61382, - 61433, - 61434, - 61454, - 61461, - 61475, - 61481, - 61534, - 61547, - 61564, - 61568, - 61588, - 61604, - 61626, - 61645, - 61646, - 61654, - 61663, - 61669, - 61702, - 61705, - 61714, - 61739, - 61744, - 61749, - 61776, - 61786, - 61822, - 61826, - 61862, - 61865, - 61868, - 61879, - 61885, - 61900, - 61905, - 61906, - 61962, - 61967, - 61972, - 61976, - 62027, - 62048, - 62051, - 62066, - 62081, - 62108, - 62178, - 62189, - 62224, - 62229, - 62282, - 62318, - 62320, - 62329, - 62341, - 62353, - 62359, - 62382, - 62389, - 62396, - 62425, - 62455, - 62484, - 62494, - 62507, - 62512, - 62550, - 62577, - 62590, - 62599, - 62617, - 62679, - 62702, - 62745, - 62772, - 62794, - 62835, - 62842, - 62847, - 62857, - 62894, - 62911, - 62928, - 62954, - 62964, - 62977, - 62984, - 63007, - 63017, - 63058, - 63067, - 63085, - 63150, - 63170, - 63184, - 63210, - 63215, - 63217, - 63229, - 63237, - 63259, - 63265, - 63271, - 63286, - 63298, - 63343, - 63355, - 63361, - 63362, - 63379, - 63397, - 63415, - 63421, - 63463, - 63491, - 63527, - 63545, - 63553, - 63560, - 63563, - 63566, - 63589, - 63599, - 63601, - 63608, - 63620, - 63654, - 63703, - 63719, - 63758, - 63769, - 63782, - 63803, - 63811, - 63851, - 63854, - 63872, - 63878, - 63895, - 63917, - 63930, - 63935, - 63955, - 63964, - 63967, - 63980, - 63985, - 63992, - 64021, - 64026, - 64044, - 64055, - 64056, - 64061, - 64067, - 64081, - 64100, - 64109, - 64112, - 64118, - 64124, - 64145, - 64151, - 64203, - 64208, - 64236, - 64254, - 64261, - 64280, - 64296, - 64313, - 64314, - 64316, - 64348, - 64352, - 64355, - 64361, - 64388, - 64398, - 64403, - 64419, - 64421, - 64428, - 64453, - 64463, - 64475, - 64511, - 64537, - 64576, - 64579, - 64581, - 64606, - 64615, - 64649, - 64655, - 64664, - 64667, - 64712, - 64715, - 64718, - 64741, - 64766, - 64780, - 64788, - 64791, - 64795, - 64798, - 64816, - 64819, - 64822, - 64833, - 64836, - 64876, - 64891, - 64907, - 64943, - 64965, - 64977, - 64999, - 65034, - 65036, - 65089, - 65107, - 65110, - 65120, - 65132, - 65143, - 65150, - 65177, - 65201, - 65214, - 65234, - 65240, - 65243, - 65259, - 65276, - 65287, - 65306, - 65311, - 65321, - 65350, - 65364, - 65451, - 65488, - 65510, - 65528, - 65533, - 65553, - 65563, - 65579, - 65621, - 65625, - 65635, - 65644, - 65690, - 65696, - 65705, - 65716, - 65725, - 65733, - 65740, - 65758, - 65786, - 65806, - 65834, - 65844, - 65866, - 65895, - 65902, - 65953, - 65954, - 65983, - 65985, - 66003, - 66010, - 66025, - 66050, - 66074, - 66076, - 66097, - 66132, - 66158, - 66175, - 66185, - 66199, - 66206, - 66222, - 66227, - 66241, - 66272, - 66324, - 66424, - 66460, - 66464, - 66481, - 66482, - 66523, - 66526, - 66532, - 66539, - 66541, - 66573, - 66582, - 66591, - 66615, - 66622, - 66629, - 66641, - 66712, - 66724, - 66731, - 66745, - 66759, - 66808, - 66814, - 66821, - 66831, - 66834, - 66879, - 66884, - 66899, - 66901, - 66924, - 66929, - 66942, - 66985, - 66986, - 66994, - 67066, - 67075, - 67099, - 67130, - 67173, - 67183, - 67186, - 67197, - 67201, - 67208, - 67221, - 67238, - 67252, - 67256, - 67270, - 67288, - 67318, - 67329, - 67349, - 67369, - 67392, - 67435, - 67473, - 67496, - 67507, - 67514, - 67536, - 67555, - 67598, - 67615, - 67625, - 67645, - 67651, - 67663, - 67672, - 67682, - 67699, - 67718, - 67780, - 67795, - 67804, - 67818, - 67832, - 67941, - 67984, - 68044, - 68059, - 68062, - 68065, - 68071, - 68072, - 68085, - 68090, - 68101, - 68102, - 68106, - 68164, - 68191, - 68192, - 68195, - 68209, - 68245, - 68246, - 68274, - 68293, - 68294, - 68322, - 68353, - 68359, - 68377, - 68401, - 68422, - 68434, - 68443, - 68445, - 68476, - 68492, - 68504, - 68525, - 68540, - 68543, - 68555, - 68563, - 68576, - 68581, - 68617, - 68631, - 68656, - 68666, - 68714, - 68743, - 68761, - 68764, - 68767, - 68768, - 68786, - 68788, - 68848, - 68851, - 68914, - 68946, - 68952, - 68973, - 69001, - 69016, - 69035, - 69037, - 69049, - 69052, - 69058, - 69063, - 69075, - 69112, - 69117, - 69124, - 69127, - 69134, - 69139, - 69161, - 69196, - 69224, - 69238, - 69301, - 69316, - 69325, - 69334, - 69347, - 69359, - 69381, - 69388, - 69393, - 69409, - 69422, - 69453, - 69459, - 69481, - 69487, - 69490, - 69495, - 69501, - 69511, - 69512, - 69532, - 69542, - 69560, - 69565, - 69571, - 69611, - 69633, - 69640, - 69667, - 69669, - 69679, - 69688, - 69699, - 69756, - 69759, - 69770, - 69772, - 69826, - 69840, - 69846, - 69868, - 69885, - 69946, - 69966, - 69973, - 69977, - 69980, - 69984, - 69994, - 70024, - 70044, - 70053, - 70086, - 70113, - 70120, - 70131, - 70150, - 70178, - 70198, - 70227, - 70285, - 70288, - 70291, - 70309, - 70334, - 70339, - 70381, - 70413, - 70414, - 70481, - 70488, - 70493, - 70515, - 70540, - 70543, - 70558, - 70568, - 70582, - 70593, - 70596, - 70613, - 70620, - 70647, - 70666, - 70710, - 70719, - 70721, - 70722, - 70742, - 70757, - 70764, - 70781, - 70795, - 70803, - 70809, - 70821, - 70846, - 70882, - 70887, - 70940, - 70961, - 70996, - 71012, - 71046, - 71057, - 71060, - 71063, - 71079, - 71080, - 71111, - 71118, - 71129, - 71136, - 71142, - 71145, - 71151, - 71163, - 71218, - 71223, - 71232, - 71237, - 71272, - 71323, - 71339, - 71341, - 71349, - 71368, - 71379, - 71395, - 71407, - 71421, - 71430, - 71436, - 71454, - 71467, - 71472, - 71478, - 71481, - 71501, - 71519, - 71530, - 71550, - 71573, - 71593, - 71608, - 71619, - 71622, - 71636, - 71650, - 71655, - 71685, - 71703, - 71714, - 71748, - 71758, - 71766, - 71772, - 71785, - 71794, - 71796, - 71803, - 71809, - 71858, - 71863, - 71878, - 71895, - 71899, - 71906, - 71908, - 71917, - 71952, - 71957, - 71961, - 71973, - 71980, - 71997, - 72017, - 72060, - 72091, - 72097, - 72166, - 72172, - 72183, - 72203, - 72205, - 72213, - 72214, - 72230, - 72239, - 72248, - 72251, - 72280, - 72313, - 72338, - 72340, - 72343, - 72368, - 72371, - 72426, - 72439, - 72446, - 72494, - 72519, - 72573, - 72577, - 72578, - 72614, - 72628, - 72640, - 72676, - 72708, - 72717, - 72766, - 72786, - 72788, - 72795, - 72797, - 72798, - 72808, - 72826, - 72835, - 72837, - 72865, - 72871, - 72872, - 72898, - 72907, - 72909, - 72917, - 72934, - 72987, - 73000, - 73005, - 73014, - 73023, - 73025, - 73074, - 73076, - 73113, - 73116, - 73140, - 73149, - 73186, - 73188, - 73191, - 73205, - 73215, - 73216, - 73239, - 73294, - 73311, - 73330, - 73366, - 73379, - 73386, - 73391, - 73418, - 73438, - 73476, - 73503, - 73509, - 73534, - 73545, - 73548, - 73563, - 73575, - 73582, - 73603, - 73609, - 73610, - 73645, - 73646, - 73678, - 73685, - 73708, - 73747, - 73765, - 73797, - 73810, - 73819, - 73825, - 73845, - 73855, - 73866, - 73890, - 73919, - 73922, - 73936, - 73939, - 73964, - 73976, - 73984, - 73990, - 74013, - 74014, - 74020, - 74035, - 74038, - 74069, - 74119, - 74123, - 74126, - 74153, - 74179, - 74200, - 74210, - 74216, - 74250, - 74263, - 74264, - 74279, - 74285, - 74294, - 74298, - 74303, - 74306, - 74366, - 74369, - 74403, - 74406, - 74442, - 74450, - 74452, - 74459, - 74461, - 74477, - 74478, - 74489, - 74504, - 74528, - 74533, - 74538, - 74551, - 74580, - 74589, - 74590, - 74593, - 74608, - 74611, - 74617, - 74623, - 74648, - 74704, - 74735, - 74737, - 74738, - 74779, - 74781, - 74809, - 74812, - 74827, - 74868, - 74871, - 74905, - 74930, - 74962, - 74990, - 74995, - 75007, - 75012, - 75030, - 75033, - 75039, - 75055, - 75078, - 75120, - 75130, - 75159, - 75163, - 75170, - 75193, - 75228, - 75244, - 75249, - 75328, - 75357, - 75373, - 75392, - 75428, - 75438, - 75469, - 75487, - 75494, - 75515, - 75526, - 75532, - 75543, - 75549, - 75559, - 75563, - 75568, - 75598, - 75612, - 75622, - 75640, - 75683, - 75689, - 75690, - 75692, - 75752, - 75766, - 75769, - 75791, - 75794, - 75806, - 75809, - 75819, - 75834, - 75895, - 75908, - 75951, - 75960, - 75965, - 75974, - 75978, - 75998, - 76001, - 76007, - 76016, - 76091, - 76119, - 76135, - 76170, - 76189, - 76214, - 76225, - 76235, - 76259, - 76261, - 76262, - 76266, - 76286, - 76289, - 76310, - 76319, - 76364, - 76375, - 76392, - 76422, - 76450, - 76496, - 76521, - 76522, - 76527, - 76536, - 76541, - 76553, - 76568, - 76574, - 76584, - 76604, - 76607, - 76609, - 76669, - 76683, - 76745, - 76753, - 76754, - 76756, - 76760, - 76782, - 76821, - 76828, - 76849, - 76850, - 76870, - 76874, - 76898, - 76903, - 76910, - 76921, - 76968, - 77013, - 77027, - 77042, - 77059, - 77062, - 77074, - 77076, - 77110, - 77113, - 77131, - 77157, - 77158, - 77216, - 77246, - 77258, - 77281, - 77284, - 77294, - 77302, - 77306, - 77315, - 77352, - 77360, - 77365, - 77370, - 77378, - 77380, - 77407, - 77408, - 77414, - 77444, - 77454, - 77481, - 77482, - 77531, - 77544, - 77552, - 77569, - 77579, - 77610, - 77612, - 77623, - 77649, - 77650, - 77661, - 77675, - 77686, - 77742, - 77791, - 77792, - 77807, - 77815, - 77842, - 77847, - 77899, - 77901, - 77904, - 77914, - 77925, - 77950, - 77959, - 77994, - 78004, - 78043, - 78052, - 78061, - 78064, - 78084, - 78094, - 78099, - 78129, - 78142, - 78149, - 78153, - 78171, - 78173, - 78174, - 78195, - 78201, - 78202, - 78241, - 78247, - 78274, - 78276, - 78303, - 78307, - 78328, - 78344, - 78362, - 78367, - 78368, - 78409, - 78412, - 78417, - 78430, - 78433, - 78440, - 78451, - 78453, - 78458, - 78467, - 78479, - 78507, - 78518, - 78535, - 78542, - 78549, - 78554, - 78556, - 78583, - 78590, - 78615, - 78635, - 78649, - 78684, - 78691, - 78705, - 78724, - 78755, - 78770, - 78772, - 78818, - 78837, - 78844, - 78849, - 78909, - 78915, - 78941, - 78958, - 78975, - 78979, - 78986, - 79029, - 79030, - 79044, - 79048, - 79056, - 79095, - 79099, - 79121, - 79150, - 79196, - 79199, - 79220, - 79229, - 79263, - 79264, - 79296, - 79302, - 79354, - 79387, - 79399, - 79435, - 79525, - 79540, - 79552, - 79562, - 79576, - 79579, - 79605, - 79618, - 79648, - 79654, - 79666, - 79686, - 79697, - 79700, - 79723, - 79749, - 79750, - 79764, - 79771, - 79774, - 79780, - 79789, - 79798, - 79821, - 79850, - 79864, - 79898, - 79904, - 79934, - 79936, - 79942, - 79945, - 79963, - 79987, - 80057, - 80077, - 80078, - 80080, - 80102, - 80106, - 80111, - 80152, - 80155, - 80173, - 80186, - 80203, - 80223, - 80233, - 80258, - 80281, - 80318, - 80326, - 80330, - 80337, - 80344, - 80365, - 80383, - 80389, - 80413, - 80441, - 80449, - 80461, - 80467, - 80476, - 80507, - 80516, - 80519, - 80568, - 80571, - 80579, - 80586, - 80599, - 80610, - 80629, - 80642, - 80690, - 80713, - 80716, - 80737, - 80743, - 80750, - 80786, - 80811, - 80834, - 80839, - 80840, - 80846, - 80848, - 80876, - 80911, - 80947, - 81001, - 81031, - 81045, - 81056, - 81073, - 81083, - 81145, - 81168, - 81177, - 81207, - 81208, - 81226, - 81245, - 81269, - 81285, - 81289, - 81292, - 81298, - 81310, - 81346, - 81348, - 81355, - 81388, - 81396, - 81415, - 81460, - 81482, - 81518, - 81523, - 81529, - 81545, - 81570, - 81576, - 81604, - 81613, - 81631, - 81656, - 81679, - 81684, - 81698, - 81736, - 81747, - 81765, - 81775, - 81805, - 81842, - 81859, - 81865, - 81866, - 81892, - 81902, - 81933, - 81934, - 81942, - 81969, - 81981, - 81999, - 82004, - 82008, - 82032, - 82035, - 82060, - 82063, - 82071, - 82081, - 82082, - 82105, - 82106, - 82120, - 82125, - 82156, - 82176, - 82203, - 82210, - 82241, - 82287, - 82323, - 82330, - 82366, - 82378, - 82395, - 82398, - 82401, - 82404, - 82419, - 82421, - 82428, - 82442, - 82452, - 82455, - 82466, - 82510, - 82524, - 82545, - 82555, - 82581, - 82588, - 82591, - 82636, - 82658, - 82675, - 82678, - 82716, - 82725, - 82743, - 82744, - 82762, - 82770, - 82809, - 82846, - 82855, - 82882, - 82899, - 82905, - 82950, - 82953, - 82967, - 82971, - 82987, - 83007, - 83009, - 83012, - 83030, - 83045, - 83050, - 83052, - 83070, - 83076, - 83086, - 83128, - 83141, - 83153, - 83156, - 83194, - 83225, - 83261, - 83264, - 83322, - 83382, - 83391, - 83399, - 83406, - 83427, - 83439, - 83444, - 83453, - 83457, - 83475, - 83484, - 83488, - 83493, - 83512, - 83525, - 83535, - 83560, - 83617, - 83664, - 83676, - 83757, - 83770, - 83775, - 83835, - 83838, - 83848, - 83856, - 83878, - 83884, - 83896, - 83902, - 83922, - 83977, - 83985, - 83988, - 84034, - 84046, - 84058, - 84069, - 84107, - 84155, - 84157, - 84160, - 84165, - 84187, - 84214, - 84226, - 84235, - 84240, - 84255, - 84273, - 84291, - 84311, - 84317, - 84328, - 84346, - 84357, - 84361, - 84372, - 84388, - 84415, - 84438, - 84444, - 84447, - 84451, - 84465, - 84471, - 84496, - 84554, - 84561, - 84571, - 84580, - 84598, - 84611, - 84620, - 84625, - 84632, - 84648, - 84659, - 84662, - 84683, - 84697, - 84698, - 84709, - 84722, - 84753, - 84775, - 84789, - 84885, - 84890, - 84899, - 84926, - 84946, - 84958, - 84976, - 84979, - 85003, - 85014, - 85017, - 85024, - 85029, - 85036, - 85042, - 85054, - 85056, - 85061, - 85066, - 85073, - 85096, - 85101, - 85109, - 85114, - 85119, - 85123, - 85149, - 85185, - 85228, - 85236, - 85281, - 85282, - 85293, - 85302, - 85319, - 85353, - 85354, - 85356, - 85389, - 85418, - 85446, - 85450, - 85463, - 85497, - 85534, - 85543, - 85549, - 85562, - 85587, - 85590, - 85599, - 85630, - 85660, - 85669, - 85693, - 85711, - 85716, - 85773, - 85801, - 85815, - 85839, - 85842, - 85864, - 85867, - 85903, - 85917, - 85921, - 85928, - 85934, - 85974, - 85994, - 85999, - 86004, - 86008, - 86046, - 86067, - 86084, - 86087, - 86093, - 86121, - 86122, - 86127, - 86151, - 86166, - 86179, - 86188, - 86193, - 86206, - 86214, - 86226, - 86242, - 86256, - 86259, - 86298, - 86300, - 86307, - 86310, - 86319, - 86321, - 86328, - 86356, - 86360, - 86375, - 86399, - 86400, - 86403, - 86430, - 86446, - 86460, - 86465, - 86486, - 86502, - 86563, - 86595, - 86635, - 86649, - 86661, - 86674, - 86689, - 86721, - 86734, - 86741, - 86742, - 86784, - 86799, - 86808, - 86837, - 86869, - 86900, - 86949, - 86993, - 86999, - 87030, - 87041, - 87044, - 87084, - 87116, - 87138, - 87162, - 87188, - 87211, - 87234, - 87245, - 87246, - 87260, - 87270, - 87284, - 87293, - 87296, - 87299, - 87305, - 87308, - 87313, - 87323, - 87332, - 87361, - 87376, - 87392, - 87419, - 87432, - 87435, - 87445, - 87466, - 87491, - 87503, - 87558, - 87570, - 87581, - 87603, - 87615, - 87623, - 87635, - 87647, - 87651, - 87657, - 87665, - 87694, - 87701, - 87705, - 87722, - 87739, - 87750, - 87790, - 87795, - 87797, - 87816, - 87884, - 87917, - 87930, - 87942, - 87953, - 87954, - 87984, - 87989, - 88008, - 88016, - 88038, - 88042, - 88044, - 88049, - 88083, - 88119, - 88134, - 88138, - 88143, - 88191, - 88216, - 88231, - 88232, - 88297, - 88300, - 88308, - 88317, - 88344, - 88350, - 88371, - 88469, - 88483, - 88485, - 88518, - 88586, - 88605, - 88621, - 88651, - 88656, - 88665, - 88668, - 88712, - 88717, - 88751, - 88754, - 88756, - 88785, - 88801, - 88807, - 88826, - 88848, - 88854, - 88864, - 88879, - 88939, - 88947, - 88987, - 88990, - 88996, - 89008, - 89011, - 89043, - 89045, - 89050, - 89097, - 89100, - 89106, - 89134, - 89178, - 89189, - 89202, - 89211, - 89224, - 89241, - 89251, - 89254, - 89258, - 89295, - 89328, - 89357, - 89403, - 89420, - 89426, - 89465, - 89471, - 89475, - 89547, - 89549, - 89558, - 89564, - 89611, - 89616, - 89626, - 89650, - 89691, - 89718, - 89764, - 89776, - 89785, - 89813, - 89817, - 89861, - 89876, - 89889, - 89904, - 89939, - 89948, - 89952, - 89964, - 89969, - 89979, - 90009, - 90022, - 90031, - 90043, - 90045, - 90068, - 90071, - 90082, - 90087, - 90117, - 90127, - 90163, - 90166, - 90177, - 90211, - 90218, - 90225, - 90231, - 90235, - 90289, - 90344, - 90347, - 90379, - 90387, - 90418, - 90435, - 90444, - 90472, - 90478, - 90485, - 90486, - 90513, - 90514, - 90532, - 90567, - 90595, - 90597, - 90621, - 90631, - 90668, - 90706, - 90708, - 90715, - 90724, - 90769, - 90791, - 90792, - 90805, - 90810, - 90820, - 90844, - 90907, - 90925, - 90926, - 90934, - 90946, - 90981, - 90999, - 91003, - 91019, - 91022, - 91050, - 91055, - 91064, - 91078, - 91117, - 91120, - 91129, - 91140, - 91157, - 91161, - 91240, - 91260, - 91270, - 91287, - 91321, - 91336, - 91341, - 91378, - 91398, - 91437, - 91440, - 91475, - 91494, - 91500, - 91511, - 91567, - 91572, - 91601, - 91617, - 91653, - 91678, - 91705, - 91723, - 91725, - 91733, - 91761, - 91768, - 91790, - 91804, - 91807, - 91808, - 91818, - 91840, - 91849, - 91869, - 91873, - 91876, - 91888, - 91891, - 91897, - 91911, - 91965, - 91971, - 91988, - 91992, - 92004, - 92021, - 92035, - 92068, - 92098, - 92104, - 92121, - 92127, - 92151, - 92162, - 92186, - 92191, - 92192, - 92207, - 92260, - 92282, - 92288, - 92297, - 92303, - 92315, - 92322, - 92327, - 92341, - 92389, - 92390, - 92422, - 92439, - 92452, - 92470, - 92473, - 92493, - 92508, - 92517, - 92529, - 92551, - 92557, - 92596, - 92611, - 92613, - 92642, - 92666, - 92684, - 92723, - 92732, - 92738, - 92783, - 92808, - 92816, - 92835, - 92847, - 92879, - 92881, - 92884, - 92932, - 92935, - 92960, - 92990, - 93010, - 93025, - 93046, - 93085, - 93089, - 93096, - 93145, - 93155, - 93169, - 93179, - 93184, - 93204, - 93211, - 93213, - 93227, - 93285, - 93292, - 93320, - 93356, - 93371, - 93374, - 93385, - 93403, - 93406, - 93427, - 93451, - 93454, - 93472, - 93482, - 93507, - 93537, - 93562, - 93564, - 93608, - 93636, - 93640, - 93653, - 93654, - 93664, - 93676, - 93721, - 93740, - 93743, - 93745, - 93751, - 93770, - 93796, - 93820, - 93824, - 93833, - 93841, - 93847, - 93848, - 93854, - 93882, - 93943, - 93958, - 93972, - 93975, - 94003, - 94009, - 94020, - 94072, - 94081, - 94093, - 94102, - 94122, - 94135, - 94136, - 94150, - 94184, - 94187, - 94258, - 94264, - 94272, - 94278, - 94281, - 94317, - 94348, - 94376, - 94382, - 94387, - 94389, - 94393, - 94402, - 94421, - 94422, - 94431, - 94473, - 94487, - 94504, - 94510, - 94522, - 94532, - 94572, - 94589, - 94599, - 94603, - 94647, - 94665, - 94695, - 94716, - 94738, - 94740, - 94778, - 94803, - 94810, - 94815, - 94821, - 94862, - 94886, - 94900, - 94924, - 94952, - 94963, - 94970, - 94980, - 94992, - 95017, - 95028, - 95031, - 95035, - 95040, - 95058, - 95079, - 95122, - 95149, - 95150, - 95167, - 95175, - 95205, - 95229, - 95321, - 95345, - 95364, - 95379, - 95386, - 95395, - 95416, - 95419, - 95433, - 95464, - 95490, - 95496, - 95504, - 95513, - 95523, - 95525, - 95558, - 95572, - 95591, - 95609, - 95619, - 95625, - 95633, - 95649, - 95652, - 95655, - 95696, - 95721, - 95766, - 95772, - 95775, - 95794, - 95796, - 95818, - 95820, - 95832, - 95842, - 95851, - 95854, - 95859, - 95868, - 95881, - 95895, - 95943, - 95949, - 95978, - 95980, - 96010, - 96020, - 96024, - 96063, - 96108, - 96125, - 96154, - 96172, - 96189, - 96204, - 96219, - 96256, - 96261, - 96289, - 96292, - 96296, - 96324, - 96345, - 96346, - 96358, - 96386, - 96412, - 96428, - 96445, - 96446, - 96448, - 96458, - 96475, - 96482, - 96494, - 96502, - 96508, - 96511, - 96516, - 96520, - 96547, - 96556, - 96561, - 96568, - 96581, - 96582, - 96679, - 96683, - 96717, - 96754, - 96769, - 96799, - 96805, - 96809, - 96823, - 96829, - 96832, - 96850, - 96856, - 96906, - 96962, - 96974, - 96979, - 96997, - 96998, - 97002, - 97054, - 97064, - 97067, - 97110, - 97116, - 97137, - 97138, - 97143, - 97183, - 97187, - 97190, - 97202, - 97219, - 97239, - 97245, - 97246, - 97249, - 97264, - 97267, - 97269, - 97274, - 97282, - 97287, - 97294, - 97299, - 97306, - 97347, - 97361, - 97371, - 97435, - 97466, - 97473, - 97474, - 97559, - 97565, - 97587, - 97611, - 97622, - 97625, - 97632, - 97635, - 97652, - 97672, - 97678, - 97683, - 97695, - 97705, - 97713, - 97719, - 97757, - 97761, - 97762, - 97771, - 97795, - 97809, - 97826, - 97845, - 97877, - 97882, - 97891, - 97903, - 97961, - 97970, - 97975, - 97996, - 98001, - 98014, - 98023, - 98035, - 98052, - 98059, - 98061, - 98086, - 98098, - 98117, - 98118, - 98132, - 98135, - 98145, - 98160, - 98194, - 98205, - 98210, - 98224, - 98227, - 98254, - 98271, - 98272, - 98302, - 98320, - 98346, - 98356, - 98360, - 98366, - 98478, - 98483, - 98486, - 98497, - 98528, - 98537, - 98551, - 98557, - 98572, - 98575, - 98600, - 98628, - 98635, - 98645, - 98652, - 98655, - 98665, - 98710, - 98719, - 98720, - 98786, - 98792, - 98806, - 98816, - 98836, - 98859, - 98864, - 98879, - 98905, - 98917, - 98929, - 98969, - 98975, - 98976, - 98981, - 98999, - 99020, - 99026, - 99054, - 99083, - 99093, - 99103, - 99131, - 99156, - 99159, - 99165, - 99170, - 99189, - 99223, - 99227, - 99271, - 99277, - 99278, - 99313, - 99314, - 99345, - 99361, - 99367, - 99386, - 99394, - 99417, - 99418, - 99453, - 99454, - 99477, - 99518, - 99544, - 99559, - 99592, - 99597, - 99603, - 99621, - 99646, - 99693, - 99722, - 99760, - 99780, - 99789, - 99804, - 99823, - 99826, - 99832, - 99842, - 99851, - 99862, - 99871, - 99899, - 99940, - 99983, - 99985, - 100025, - 100043, - 100070, - 100076, - 100084, - 100096, - 100105, - 100108, - 100123, - 100132, - 100141, - 100181, - 100191, - 100202, - 100216, - 100246, - 100256, - 100271, - 100285, - 100294, - 100305, - 100321, - 100331, - 100334, - 100345, - 100346, - 100369, - 100372, - 100382, - 100403, - 100451, - 100488, - 100499, - 100501, - 100511, - 100536, - 100629, - 100652, - 100655, - 100669, - 100687, - 100692, - 100696, - 100701, - 100706, - 100711, - 100726, - 100754, - 100759, - 100790, - 100838, - 100878, - 100880, - 100885, - 100886, - 100943, - 100948, - 100957, - 100962, - 100968, - 100981, - 100986, - 101001, - 101012, - 101015, - 101019, - 101037, - 101063, - 101105, - 101144, - 101147, - 101154, - 101163, - 101166, - 101173, - 101174, - 101219, - 101240, - 101250, - 101259, - 101273, - 101274, - 101285, - 101300, - 101309, - 101310, - 101321, - 101324, - 101363, - 101366, - 101377, - 101380, - 101389, - 101407, - 101411, - 101432, - 101476, - 101488, - 101494, - 101514, - 101534, - 101537, - 101543, - 101547, - 101584, - 101589, - 101590, - 101629, - 101678, - 101683, - 101700, - 101712, - 101748, - 101757, - 101762, - 101771, - 101785, - 101795, - 101822, - 101851, - 101863, - 101894, - 101903, - 101924, - 101939, - 101980, - 101993, - 101994, - 101996, - 102007, - 102044, - 102086, - 102097, - 102113, - 102123, - 102155, - 102157, - 102169, - 102181, - 102182, - 102185, - 102199, - 102208, - 102213, - 102226, - 102290, - 102296, - 102306, - 102317, - 102337, - 102344, - 102350, - 102378, - 102383, - 102391, - 102400, - 102409, - 102427, - 102434, - 102453, - 102472, - 102502, - 102525, - 102547, - 102554, - 102560, - 102578, - 102580, - 102597, - 102616, - 102625, - 102632, - 102663, - 102669, - 102681, - 102694, - 102706, - 102715, - 102723, - 102730, - 102743, - 102856, - 102870, - 102898, - 102926, - 102931, - 102938, - 102947, - 102968, - 102976, - 102993, - 103005, - 103019, - 103022, - 103057, - 103080, - 103100, - 103106, - 103126, - 103173, - 103202, - 103207, - 103219, - 103226, - 103228, - 103248, - 103274, - 103288, - 103291, - 103293, - 103324, - 103358, - 103372, - 103375, - 103390, - 103414, - 103432, - 103446, - 103455, - 103471, - 103474, - 103476, - 103515, - 103527, - 103542, - 103562, - 103569, - 103572, - 103581, - 103609, - 103612, - 103618, - 103637, - 103644, - 103653, - 103663, - 103671, - 103678, - 103695, - 103698, - 103720, - 103723, - 103738, - 103743, - 103745, - 103757, - 103810, - 103822, - 103855, - 103887, - 103905, - 103915, - 103925, - 103929, - 103945, - 103954, - 103969, - 104011, - 104055, - 104111, - 104116, - 104125, - 104145, - 104162, - 104176, - 104193, - 104199, - 104224, - 104236, - 104247, - 104254, - 104289, - 104325, - 104332, - 104335, - 104353, - 104363, - 104371, - 104373, - 104406, - 104412, - 104440, - 104459, - 104461, - 104469, - 104479, - 104483, - 104490, - 104500, - 104536, - 104560, - 104569, - 104588, - 104591, - 104621, - 104661, - 104675, - 104684, - 104713, - 104747, - 104750, - 104757, - 104775, - 104782, - 104803, - 104820, - 104824, - 104829, - 104830, - 104836, - 104851, - 104882, - 104920, - 104941, - 104963, - 104989, - 104999, - 105006, - 105040, - 105066, - 105089, - 105120, - 105125, - 105137, - 105179, - 105215, - 105244, - 105258, - 105263, - 105280, - 105286, - 105380, - 105397, - 105409, - 105427, - 105452, - 105469, - 105472, - 105477, - 105490, - 105505, - 105529, - 105530, - 105604, - 105614, - 105622, - 105625, - 105652, - 105687, - 105693, - 105707, - 105721, - 105730, - 105736, - 105753, - 105759, - 105760, - 105802, - 105822, - 105832, - 105865, - 105873, - 105874, - 105880, - 105899, - 105902, - 105909, - 105919, - 105922, - 105946, - 105975, - 105992, - 106005, - 106057, - 106081, - 106093, - 106117, - 106127, - 106135, - 106141, - 106189, - 106190, - 106197, - 106214, - 106237, - 106245, - 106257, - 106300, - 106335, - 106351, - 106370, - 106375, - 106376, - 106384, - 106403, - 106405, - 106406, - 106429, - 106447, - 106466, - 106495, - 106532, - 106542, - 106547, - 106564, - 106576, - 106586, - 106592, - 106597, - 106610, - 106612, - 106635, - 106640, - 106673, - 106691, - 106724, - 106731, - 106741, - 106748, - 106765, - 106789, - 106822, - 106856, - 106861, - 106870, - 106883, - 106895, - 106928, - 106938, - 106979, - 106985, - 107005, - 107012, - 107019, - 107045, - 107052, - 107082, - 107089, - 107118, - 107163, - 107202, - 107238, - 107242, - 107244, - 107264, - 107273, - 107291, - 107293, - 107312, - 107318, - 107335, - 107349, - 107350, - 107363, - 107390, - 107405, - 107408, - 107427, - 107433, - 107444, - 107514, - 107522, - 107545, - 107582, - 107590, - 107593, - 107599, - 107604, - 107608, - 107627, - 107638, - 107666, - 107678, - 107701, - 107720, - 107723, - 107725, - 107731, - 107737, - 107767, - 107779, - 107788, - 107799, - 107819, - 107833, - 107881, - 107901, - 107911, - 107930, - 107936, - 107980, - 108004, - 108008, - 108016, - 108066, - 108071, - 108107, - 108110, - 108124, - 108145, - 108148, - 108158, - 108164, - 108197, - 108198, - 108219, - 108222, - 108224, - 108227, - 108290, - 108302, - 108329, - 108335, - 108338, - 108362, - 108398, - 108405, - 108409, - 108431, - 108449, - 108474, - 108488, - 108530, - 108545, - 108551, - 108558, - 108585, - 108613, - 108638, - 108642, - 108653, - 108671, - 108675, - 108684, - 108687, - 108696, - 108786, - 108792, - 108795, - 108818, - 108830, - 108836, - 108839, - 108851, - 108875, - 108883, - 108895, - 108908, - 108953, - 108956, - 108963, - 108989, - 109001, - 109009, - 109052, - 109083, - 109090, - 109104, - 109121, - 109128, - 109141, - 109146, - 109155, - 109162, - 109209, - 109216, - 109243, - 109265, - 109282, - 109306, - 109316, - 109334, - 109359, - 109373, - 109386, - 109394, - 109403, - 109409, - 109412, - 109427, - 109439, - 109464, - 109467, - 109476, - 109488, - 109497, - 109523, - 109551, - 109556, - 109566, - 109598, - 109628, - 109643, - 109663, - 109674, - 109688, - 109691, - 109704, - 109715, - 109717, - 109746, - 109789, - 109794, - 109868, - 109886, - 109888, - 109903, - 109908, - 109912, - 109927, - 109936, - 109979, - 110005, - 110010, - 110017, - 110041, - 110042, - 110047, - 110048, - 110053, - 110054, - 110057, - 110091, - 110093, - 110112, - 110127, - 110178, - 110183, - 110184, - 110195, - 110307, - 110334, - 110336, - 110354, - 110356, - 110390, - 110419, - 110452, - 110461, - 110465, - 110466, - 110468, - 110486, - 110511, - 110531, - 110561, - 110573, - 110593, - 110611, - 110614, - 110651, - 110661, - 110665, - 110701, - 110730, - 110735, - 110738, - 110759, - 110763, - 110768, - 110774, - 110783, - 110785, - 110809, - 110812, - 110840, - 110853, - 110905, - 110933, - 110961, - 110962, - 110974, - 110987, - 110989, - 111007, - 111011, - 111043, - 111070, - 111088, - 111127, - 111140, - 111149, - 111229, - 111230, - 111243, - 111267, - 111287, - 111313, - 111356, - 111368, - 111409, - 111419, - 111430, - 111433, - 111442, - 111467, - 111491, - 111503, - 111527, - 111531, - 111541, - 111546, - 111548, - 111577, - 111625, - 111636, - 111650, - 111655, - 111662, - 111673, - 111699, - 111727, - 111729, - 111741, - 111757, - 111781, - 111791, - 111826, - 111838, - 111854, - 111861, - 111866, - 111868, - 111897, - 111903, - 111904, - 111959, - 111975, - 112018, - 112023, - 112033, - 112036, - 112043, - 112095, - 112113, - 112136, - 112153, - 112165, - 112166, - 112177, - 112189, - 112226, - 112237, - 112240, - 112255, - 112265, - 112280, - 112292, - 112307, - 112316, - 112342, - 112345, - 112351, - 112361, - 112364, - 112372, - 112382, - 112389, - 112408, - 112417, - 112423, - 112476, - 112480, - 112483, - 112513, - 112538, - 112543, - 112574, - 112599, - 112605, - 112667, - 112688, - 112735, - 112746, - 112810, - 112817, - 112827, - 112835, - 112892, - 112898, - 112915, - 112918, - 112937, - 112940, - 112958, - 113013, - 113014, - 113027, - 113048, - 113051, - 113053, - 113102, - 113104, - 113114, - 113130, - 113159, - 113180, - 113189, - 113211, - 113245, - 113261, - 113273, - 113292, - 113314, - 113319, - 113323, - 113326, - 113337, - 113338, - 113355, - 113365, - 113376, - 113408, - 113462, - 113476, - 113503, - 113550, - 113578, - 113580, - 113634, - 113653, - 113677, - 113713, - 113751, - 113771, - 113781, - 113797, - 113846, - 113849, - 113855, - 113878, - 113884, - 113926, - 113938, - 113956, - 113980, - 113986, - 113991, - 114005, - 114022, - 114036, - 114046, - 114050, - 114061, - 114067, - 114117, - 114142, - 114158, - 114165, - 114200, - 114219, - 114254, - 114265, - 114272, - 114312, - 114318, - 114348, - 114377, - 114383, - 114386, - 114431, - 114448, - 114479, - 114487, - 114513, - 114542, - 114572, - 114584, - 114600, - 114605, - 114623, - 114628, - 114640, - 114650, - 114668, - 114671, - 114674, - 114700, - 114731, - 114748, - 114759, - 114766, - 114768, - 114784, - 114808, - 114813, - 114829, - 114830, - 114842, - 114875, - 114898, - 114903, - 114913, - 114928, - 114937, - 114958, - 114963, - 115000, - 115018, - 115023, - 115028, - 115042, - 115084, - 115096, - 115105, - 115117, - 115149, - 115155, - 115198, - 115221, - 115222, - 115225, - 115276, - 115294, - 115297, - 115321, - 115348, - 115364, - 115376, - 115385, - 115386, - 115400, - 115414, - 115465, - 115485, - 115492, - 115501, - 115519, - 115527, - 115531, - 115567, - 115572, - 115631, - 115648, - 115660, - 115672, - 115681, - 115688, - 115694, - 115699, - 115719, - 115726, - 115733, - 115796, - 115879, - 115880, - 115888, - 115908, - 115925, - 115942, - 115978, - 115986, - 116014, - 116019, - 116031, - 116048, - 116069, - 116091, - 116103, - 116107, - 116145, - 116152, - 116247, - 116289, - 116316, - 116344, - 116354, - 116368, - 116377, - 116383, - 116387, - 116408, - 116428, - 116445, - 116476, - 116482, - 116488, - 116493, - 116502, - 116518, - 116524, - 116527, - 116549, - 116561, - 116562, - 116568, - 116577, - 116590, - 116602, - 116607, - 116611, - 116626, - 116637, - 116647, - 116665, - 116674, - 116700, - 116714, - 116719, - 116744, - 116764, - 116774, - 116778, - 116798, - 116803, - 116806, - 116827, - 116839, - 116863, - 116873, - 116882, - 116887, - 116915, - 116939, - 116944, - 116953, - 116965, - 117002, - 117007, - 117015, - 117032, - 117035, - 117052, - 117087, - 117139, - 117157, - 117193, - 117211, - 117214, - 117220, - 117238, - 117248, - 117275, - 117293, - 117301, - 117319, - 117338, - 117347, - 117361, - 117380, - 117389, - 117398, - 117435, - 117458, - 117476, - 117498, - 117500, - 117529, - 117554, - 117556, - 117565, - 117580, - 117585, - 117592, - 117597, - 117616, - 117637, - 117644, - 117659, - 117703, - 117704, - 117727, - 117738, - 117770, - 117796, - 117799, - 117820, - 117832, - 117840, - 117843, - 117865, - 117868, - 117874, - 117886, - 117962, - 117967, - 117995, - 118000, - 118017, - 118037, - 118038, - 118051, - 118057, - 118072, - 118080, - 118098, - 118107, - 118109, - 118114, - 118123, - 118150, - 118159, - 118164, - 118173, - 118201, - 118212, - 118246, - 118257, - 118303, - 118310, - 118313, - 118324, - 118334, - 118336, - 118339, - 118353, - 118354, - 118390, - 118396, - 118436, - 118453, - 118466, - 118492, - 118506, - 118525, - 118557, - 118561, - 118586, - 118606, - 118627, - 118641, - 118654, - 118687, - 118688, - 118735, - 118737, - 118750, - 118773, - 118778, - 118786, - 118809, - 118833, - 118853, - 118854, - 118863, - 118881, - 118896, - 118917, - 118921, - 118939, - 118948, - 118960, - 118970, - 118983, - 119025, - 119026, - 119064, - 119069, - 119079, - 119085, - 119115, - 119165, - 119166, - 119193, - 119194, - 119199, - 119215, - 119218, - 119241, - 119277, - 119301, - 119306, - 119335, - 119344, - 119364, - 119373, - 119382, - 119410, - 119425, - 119459, - 119473, - 119486, - 119500, - 119508, - 119511, - 119517, - 119528, - 119533, - 119539, - 119542, - 119546, - 119566, - 119587, - 119590, - 119607, - 119614, - 119625, - 119633, - 119634, - 119643, - 119683, - 119704, - 119710, - 119734, - 119752, - 119760, - 119826, - 119922, - 119931, - 119977, - 120015, - 120020, - 120083, - 120086, - 120101, - 120105, - 120155, - 120188, - 120195, - 120216, - 120228, - 120238, - 120255, - 120317, - 120327, - 120369, - 120382, - 120404, - 120414, - 120432, - 120435, - 120454, - 120463, - 120471, - 120505, - 120528, - 120588, - 120616, - 120630, - 120644, - 120672, - 120677, - 120718, - 120725, - 120730, - 120756, - 120759, - 120765, - 120795, - 120821, - 120850, - 120868, - 120880, - 120885, - 120892, - 120897, - 120912, - 120934, - 120991, - 121004, - 121021, - 121022, - 121036, - 121041, - 121069, - 121078, - 121126, - 121135, - 121138, - 121162, - 121176, - 121186, - 121209, - 121212, - 121221, - 121225, - 121228, - 121239, - 121245, - 121264, - 121270, - 121299, - 121306, - 121315, - 121317, - 121321, - 121324, - 121330, - 121339, - 121346, - 121370, - 121372, - 121393, - 121396, - 121414, - 121442, - 121475, - 121499, - 121512, - 121518, - 121588, - 121597, - 121612, - 121629, - 121630, - 121634, - 121680, - 121725, - 121798, - 121815, - 121822, - 121837, - 121840, - 121869, - 121878, - 121897, - 121920, - 121929, - 121944, - 121999, - 122008, - 122056, - 122062, - 122067, - 122083, - 122095, - 122110, - 122118, - 122127, - 122189, - 122207, - 122226, - 122253, - 122301, - 122324, - 122337, - 122362, - 122368, - 122371, - 122378, - 122404, - 122443, - 122451, - 122457, - 122458, - 122479, - 122484, - 122521, - 122540, - 122545, - 122552, - 122560, - 122575, - 122578, - 122605, - 122661, - 122673, - 122722, - 122728, - 122739, - 122751, - 122762, - 122769, - 122772, - 122782, - 122798, - 122810, - 122812, - 122818, - 122829, - 122851, - 122857, - 122868, - 122893, - 122894, - 122902, - 122921, - 122959, - 122984, - 123001, - 123038, - 123076, - 123100, - 123107, - 123122, - 123139, - 123175, - 123190, - 123201, - 123219, - 123232, - 123255, - 123285, - 123328, - 123385, - 123397, - 123404, - 123419, - 123435, - 123437, - 123443, - 123500, - 123506, - 123511, - 123512, - 123518, - 123522, - 123545, - 123572, - 123587, - 123594, - 123607, - 123608, - 123630, - 123635, - 123659, - 123692, - 123695, - 123700, - 123730, - 123748, - 123751, - 123770, - 123793, - 123800, - 123803, - 123851, - 123859, - 123866, - 123868, - 123877, - 123884, - 123909, - 123910, - 123919, - 123927, - 123937, - 123950, - 123957, - 123979, - 123996, - 124040, - 124054, - 124063, - 124067, - 124088, - 124101, - 124154, - 124162, - 124167, - 124176, - 124195, - 124230, - 124267, - 124346, - 124389, - 124418, - 124420, - 124454, - 124490, - 124503, - 124519, - 124533, - 124544, - 124589, - 124616, - 124630, - 124636, - 124645, - 124652, - 124663, - 124667, - 124690, - 124755, - 124757, - 124819, - 124862, - 124864, - 124874, - 124882, - 124903, - 124915, - 124938, - 124945, - 124973, - 124986, - 124991, - 125011, - 125014, - 125082, - 125105, - 125163, - 125165, - 125205, - 125219, - 125239, - 125240, - 125257, - 125284, - 125302, - 125327, - 125336, - 125355, - 125363, - 125365, - 125372, - 125378, - 125383, - 125387, - 125390, - 125414, - 125435, - 125466, - 125481, - 125522, - 125531, - 125544, - 125564, - 125588, - 125602, - 125613, - 125621, - 125648, - 125651, - 125681, - 125719, - 125773, - 125774, - 125779, - 125786, - 125792, - 125822, - 125828, - 125831, - 125837, - 125880, - 125891, - 125922, - 125928, - 125931, - 125941, - 125948, - 125960, - 125973, - 126014, - 126016, - 126036, - 126043, - 126062, - 126076, - 126116, - 126125, - 126145, - 126152, - 126175, - 126188, - 126199, - 126205, - 126213, - 126220, - 126286, - 126294, - 126300, - 126322, - 126324, - 126343, - 126344, - 126430, - 126433, - 126448, - 126451, - 126457, - 126458, - 126463, - 126470, - 126484, - 126518, - 126521, - 126547, - 126556, - 126583, - 126584, - 126633, - 126673, - 126680, - 126686, - 126689, - 126702, - 126710, - 126722, - 126787, - 126789, - 126794, - 126801, - 126857, - 126891, - 126896, - 126902, - 126911, - 126919, - 126943, - 126947, - 126949, - 126953, - 126971, - 126976, - 126982, - 127009, - 127021, - 127027, - 127039, - 127041, - 127044, - 127059, - 127071, - 127075, - 127126, - 127129, - 127145, - 127154, - 127165, - 127171, - 127197, - 127198, - 127207, - 127226, - 127240, - 127254, - 127269, - 127305, - 127323, - 127342, - 127347, - 127363, - 127394, - 127426, - 127432, - 127440, - 127462, - 127468, - 127473, - 127486, - 127502, - 127510, - 127523, - 127543, - 127567, - 127570, - 127585, - 127588, - 127619, - 127621, - 127626, - 127628, - 127640, - 127662, - 127684, - 127687, - 127693, - 127696, - 127708, - 127711, - 127722, - 127732, - 127747, - 127767, - 127771, - 127790, - 127816, - 127824, - 127833, - 127869, - 127910, - 127928, - 127933, - 127963, - 127975, - 128016, - 128031, - 128059, - 128074, - 128107, - 128122, - 128157, - 128161, - 128200, - 128213, - 128229, - 128233, - 128241, - 128259, - 128295, - 128299, - 128313, - 128345, - 128362, - 128375, - 128376, - 128406, - 128410, - 128416, - 128443, - 128451, - 128465, - 128466, - 128484, - 128499, - 128502, - 128524, - 128536, - 128541, - 128542, - 128592, - 128598, - 128623, - 128632, - 128671, - 128713, - 128724, - 128731, - 128761, - 128767, - 128782, - 128793, - 128805, - 128820, - 128830, - 128842, - 128852, - 128859, - 128866, - 128875, - 128892, - 128896, - 128914, - 128935, - 128964, - 128973, - 129001, - 129007, - 129012, - 129021, - 129026, - 129055, - 129071, - 129093, - 129105, - 129124, - 129148, - 129151, - 129155, - 129161, - 129200, - 129224, - 129230, - 129237, - 129298, - 129300, - 129316, - 129345, - 129351, - 129352, - 129363, - 129393, - 129410, - 129415, - 129449, - 129477, - 129501, - 129518, - 129520, - 129545, - 129563, - 129594, - 129608, - 129616, - 129652, - 129659, - 129680, - 129692, - 129738, - 129764, - 129782, - 129793, - 129820, - 129824, - 129829, - 129848, - 129854, - 129861, - 129879, - 129886, - 129907, - 129949, - 129953, - 129980, - 129998, - 130031, - 130043, - 130057, - 130065, - 130087, - 130091, - 130096, - 130101, - 130111, - 130126, - 130137, - 130138, - 130149, - 130177, - 130180, - 130214, - 130228, - 130240, - 130267, - 130280, - 130294, - 130306, - 130325, - 130398, - 130402, - 130421, - 130438, - 130441, - 130475, - 130486, - 130503, - 130551, - 130574, - 130602, - 130612, - 130621, - 130633, - 130684, - 130688, - 130698, - 130700, - 130712, - 130739, - 130748, - 130774, - 130783, - 130802, - 130811, - 130836, - 130840, - 130856, - 130864, - 130873, - 130918, - 130927, - 130929, - 130958, - 130966, - 130970, - 130976, - 131006, - 131008, - 131020, - 131059, - -1 }; - //#endif - - /*! You can access the following array as in PrimitivePolynomials[i][j] - with i and j counting from 0 in C convention. PrimitivePolynomials[i][j] - will get you the j-th (counting from zero) primitive polynomial of degree - i+1. Each one-dimensional array of primitive polynomials of a given - degree is terminated with an entry of -1. Accessing beyond this entry - will result in a memory violation and must be avoided. */ - public static long[][] PrimitivePolynomials { get { return PrimitivePolynomials_; } } - private static long[][] PrimitivePolynomials_ = new long[N_MAX_DEGREE][] { - PrimitivePolynomialDegree01 - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_01 - , PrimitivePolynomialDegree02 - //#endif - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_02 - , PrimitivePolynomialDegree03 - //#endif - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_03 - , PrimitivePolynomialDegree04 - //#endif - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_04 - , PrimitivePolynomialDegree05 - //#endif - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_05 - , PrimitivePolynomialDegree06 - //#endif - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_06 - , PrimitivePolynomialDegree07 - //#endif - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_07 - , PrimitivePolynomialDegree08 - //#endif - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_08 - , PrimitivePolynomialDegree09 - //#endif - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_09 - , PrimitivePolynomialDegree10 - //#endif - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_10 - , PrimitivePolynomialDegree11 - //#endif - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_11 - , PrimitivePolynomialDegree12 - //#endif - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_12 - , PrimitivePolynomialDegree13 - //#endif - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_13 - , PrimitivePolynomialDegree14 - //#endif - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_14 - , PrimitivePolynomialDegree15 - //#endif - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_15 - , PrimitivePolynomialDegree16 - //#endif - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_16 - , PrimitivePolynomialDegree17 - //#endif - //#if PPMT_MAX_DIM > N_PRIMITIVES_UP_TO_DEGREE_17 - , PrimitivePolynomialDegree18 - //#endif - }; - - } - -#endif - - -} diff --git a/src/QLNet/Math/randomnumbers/randomsequencegenerator.cs b/src/QLNet/Math/randomnumbers/randomsequencegenerator.cs deleted file mode 100644 index c821ece2e..000000000 --- a/src/QLNet/Math/randomnumbers/randomsequencegenerator.cs +++ /dev/null @@ -1,88 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet { - public interface IRNG { - int dimension(); - Sample> nextSequence(); - Sample> lastSequence(); - - IRNG factory(int dimensionality, ulong seed); - } - - /*! Random sequence generator based on a pseudo-random number generator RNG. - Do not use with low-discrepancy sequence generator. - */ - public class RandomSequenceGenerator : IRNG where RNG : IRNGTraits, new() { - private int dimensionality_; - - private RNG rng_; - private Sample> sequence_; - private List int32Sequence_; - - public RandomSequenceGenerator(int dimensionality, RNG rng) { - dimensionality_ = dimensionality; - rng_ = rng; - - List ls = new List(); - for (int i = 0; i < dimensionality; i++) - ls.Add(0.0); - sequence_ = new Sample>(ls, 1.0); - int32Sequence_ = new InitializedList(dimensionality); - - Utils.QL_REQUIRE(dimensionality>0,()=> "dimensionality must be greater than 0"); - } - - public RandomSequenceGenerator(int dimensionality, ulong seed) { - dimensionality_ = dimensionality; - rng_ = (RNG)FastActivator.Create().factory(seed); - sequence_ = new Sample>(new InitializedList(dimensionality), 1.0); - int32Sequence_ = new InitializedList(dimensionality); - } - - public List nextInt32Sequence() { - for (int i = 0; i < dimensionality_; i++) { - int32Sequence_[i] = rng_.nextInt32(); - } - return int32Sequence_; - } - - #region IRGN interface - public Sample> nextSequence() { - sequence_.weight = 1.0; - for (int i = 0; i < dimensionality_; i++) { - Sample x = rng_.next(); - sequence_.value[i] = x.value; - sequence_.weight *= x.weight; - } - return sequence_; - } - - public Sample> lastSequence() { return sequence_; } - - public int dimension() { return dimensionality_; } - - public IRNG factory(int dimensionality, ulong seed) { - return new RandomSequenceGenerator(dimensionality, seed); - } - #endregion - } -} diff --git a/src/QLNet/Math/randomnumbers/rngtraits.cs b/src/QLNet/Math/randomnumbers/rngtraits.cs deleted file mode 100644 index 57b65bbd1..000000000 --- a/src/QLNet/Math/randomnumbers/rngtraits.cs +++ /dev/null @@ -1,96 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -namespace QLNet { - public interface IRNGTraits { - ulong nextInt32(); - Sample next(); - - IRNGTraits factory(ulong seed); - } - - public interface IRSG { - int allowsErrorEstimate { get; } - object make_sequence_generator(int dimension, ulong seed); - } - - // random number traits - public class GenericPseudoRandom : IRSG where URNG : IRNGTraits, new() where IC : IValue, new() - { - // data - private static IC icInstance_ = FastActivator.Create(); - - // more traits - public int allowsErrorEstimate - { - get { return 1; } - } - - public static IC icInstance - { - get { return icInstance_; } - set { icInstance_ = value; } - } - - // factory - public object make_sequence_generator(int dimension, ulong seed) - { - RandomSequenceGenerator g = new RandomSequenceGenerator(dimension, seed); - return (icInstance_ != null - ? new InverseCumulativeRsg, IC>(g, icInstance_) - : new InverseCumulativeRsg, IC>(g)); - } - } - - //! default traits for pseudo-random number generation - /*! \test a sequence generator is generated and tested by comparing samples against known good values. */ - public class PseudoRandom : GenericPseudoRandom { } - - //! traits for Poisson-distributed pseudo-random number generation - /*! \test sequence generators are generated and tested by comparing - samples against known good values. - */ - public class PoissonPseudoRandom : GenericPseudoRandom { } - - - public class GenericLowDiscrepancy : IRSG where URSG : IRNG, new() where IC : IValue, new() - { - // data - private static IC icInstance_ = FastActivator.Create(); - public static IC icInstance - { - get { return icInstance_; } - set { icInstance_ = value; } - } - - - // more traits - public int allowsErrorEstimate { get { return 0; } } - - // factory - public object make_sequence_generator(int dimension, ulong seed) { - URSG g = (URSG)FastActivator.Create().factory(dimension, seed); - return (icInstance != null ? new InverseCumulativeRsg(g, icInstance) - : new InverseCumulativeRsg(g)); - } - } - - //! default traits for low-discrepancy sequence generation - public class LowDiscrepancy : GenericLowDiscrepancy { } -} diff --git a/src/QLNet/Math/randomnumbers/seedgenerator.cs b/src/QLNet/Math/randomnumbers/seedgenerator.cs deleted file mode 100644 index e5206b3a6..000000000 --- a/src/QLNet/Math/randomnumbers/seedgenerator.cs +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet { - //! Random seed generator - /*! Random number generator used for automatic generation of initialization seeds. */ - public class SeedGenerator { - private MersenneTwisterUniformRng rng_; - - private static readonly SeedGenerator instance_ = new SeedGenerator(); - private SeedGenerator() { - rng_ = new MersenneTwisterUniformRng(42UL); - initialize(); - } - - public ulong get() { - return rng_.nextInt32(); - } - - public static SeedGenerator instance() { return instance_; } - - private void initialize() { - // firstSeed is chosen based on clock() and used for the first rng - ulong firstSeed = (ulong)DateTime.Now.Ticks; - MersenneTwisterUniformRng first = new MersenneTwisterUniformRng(firstSeed); - - // secondSeed is as random as it could be - // feel free to suggest improvements - ulong secondSeed = first.nextInt32(); - - MersenneTwisterUniformRng second = new MersenneTwisterUniformRng(secondSeed); - - // use the second rng to initialize the final one - ulong skip = second.nextInt32() % 1000; - List init = new InitializedList(4); - init[0]=second.nextInt32(); - init[1]=second.nextInt32(); - init[2]=second.nextInt32(); - init[3]=second.nextInt32(); - - rng_ = new MersenneTwisterUniformRng(init); - - for (ulong i=0; i. - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICAR PURPOSE. See the license for more details. -*/ - -namespace QLNet { - -#if NOPOLY - public partial class SobolRsg - { - const uint maxAltDegree = 0; - static long[][] AltPrimitivePolynomials; - static ulong[][] initializers; - static ulong[][] SLinitializers; - static ulong[][] Linitializers; - static ulong[][] JoeKuoD5initializers; - static ulong[][] JoeKuoD6initializers; - static ulong[][] JoeKuoD7initializers; - static ulong[][] Kuoinitializers; - static ulong[][] Kuo2initializers; - static ulong[][] Kuo3initializers; - } - -#else - - - public partial class SobolRsg { - // number of dimensions in the alternative primitive polynomials - const uint maxAltDegree = 52; - - static long[] AltPrimitivePolynomialDegree01 = - { - 0, /* x+1 (1)(1) */ - -1 - }; - - static long[] AltPrimitivePolynomialDegree02 = - { - 1, /* x^2+x+1 (1)1(1) */ - -1 - }; - - static long[] AltPrimitivePolynomialDegree03 = - { - 1, /* x^3 +x+1 (1)01(1) */ - 2, /* x^3+x^2 +1 (1)10(1) */ - -1 - }; - - static long[] AltPrimitivePolynomialDegree04 = - { - 1, /* x^4+ +x+1 (1)001(1) */ - 4, /* x^4+x^3+ +1 (1)100(1) */ - -1 - }; - - - static long[] AltPrimitivePolynomialDegree05 = - { - 2, /* x^5 +x^2 +1 (1)0010(1) */ - 13, /* x^5+x^4+x^3 +x+1 (1)1101(1) */ - 7, /* x^5 +x^3+x^2+x+1 (1)0111(1) */ - 14, /* x^5+x^4+x^3+x^2 +1 (1)1110(1) */ - 11, /* x^5+x^4 +x^2+x+1 (1)1011(1) */ - 4, /* x^5 +x^3 +1 (1)0100(1) */ - -1 - }; - - static long[] AltPrimitivePolynomialDegree06 = - { - 1, /* x^6 +x+1 (1)00001(1) */ - 16, /* x^6+x^5 +1 (1)10000(1) */ - 13, /* x^6 +x^4+x^3 +x+1 (1)01101(1) */ - 22, /* x^6+x^5 +x^3+x^2 +1 (1)10110(1) */ - 19, /* x^6 +x^2+x+1 (1)10011(1) */ - 25, /* x^6+x^5+x^4 +x+1 (1)11001(1) */ - -1 - }; - - - static long[] AltPrimitivePolynomialDegree07 = - { - 1, /* x^7 +x+1 (1)000001(1) */ - 32, /* x^7+x^6 +1 (1)100000(1) */ - 4, /* x^7 +x^3 +1 (1)000100(1) */ - 8, /* x^7 +x^4 +1 (1)001000(1) */ - 7, /* x^7 +x^3+x^2+x+1 (1)000111(1) */ - 56, /* x^7+x^6+x^5+x^4 +1 (1)111000(1) */ - 14, /* x^7 +x^4+x^3+x^2 +1 (1)001110(1) */ - 28, /* x^7 +x^5+x^4+x^3 +1 (1)011100(1) */ - 19, /* x^7 +x^5 +x^2+x+1 (1)010011(1) */ - 50, /* x^7+x^6+x^5 +x^2 +1 (1)110010(1) */ - 21, /* x^7 +x^5 +x^3 +x+1 (1)010101(1) */ - 42, /* x^7+x^6 +x^4 +x^2 +1 (1)101010(1) */ - 31, /* x^7 +x^5+x^4+x^3+x^2+x+1 (1)011111(1) */ - 62, /* x^7+x^6+x^5+x^4+x^3+x^2 +1 (1)111110(1) */ - 37, /* x^7+x^6 +x^3 +x+1 (1)100101(1) */ - 41, /* x^7+x^6 +x^4 +x+1 (1)101001(1) */ - 55, /* x^7+x^6+x^5 +x^3+x^2+x+1 (1)110111(1) */ - 59, /* x^7+x^6+x^5+x^4 +x^2+x+1 (1)111011(1) */ - -1 - }; - - static long[] AltPrimitivePolynomialDegree08 = - { - 14, - 56, - 21, - 22, - 38, - 47, - 49, - 50, - 52, - 67, - 70, - 84, - 97, - 103, - 115, - 122, - -1 - }; - - static long[][] AltPrimitivePolynomials = - { - AltPrimitivePolynomialDegree01, - AltPrimitivePolynomialDegree02, - AltPrimitivePolynomialDegree03, - AltPrimitivePolynomialDegree04, - AltPrimitivePolynomialDegree05, - AltPrimitivePolynomialDegree06, - AltPrimitivePolynomialDegree07, - AltPrimitivePolynomialDegree08 - }; - - /* Sobol' Levitan coefficients of the free direction integers as given by Bratley, P., Fox, B.L. (1988) */ - static ulong[] dim02SLinitializers = { 1, 0 }; - static ulong[] dim03SLinitializers = { 1, 1, 0 }; - static ulong[] dim04SLinitializers = { 1, 3, 7, 0 }; - static ulong[] dim05SLinitializers = { 1, 1, 5, 0 }; - static ulong[] dim06SLinitializers = { 1, 3, 1, 1, 0 }; - static ulong[] dim07SLinitializers = { 1, 1, 3, 7, 0 }; - static ulong[] dim08SLinitializers = { 1, 3, 3, 9, 9, 0 }; - static ulong[] dim09SLinitializers = { 1, 3, 7, 13, 3, 0 }; - static ulong[] dim10SLinitializers = { 1, 1, 5, 11, 27, 0 }; - static ulong[] dim11SLinitializers = { 1, 3, 5, 1, 15, 0 }; - static ulong[] dim12SLinitializers = { 1, 1, 7, 3, 29, 0 }; - static ulong[] dim13SLinitializers = { 1, 3, 7, 7, 21, 0 }; - static ulong[] dim14SLinitializers = { 1, 1, 1, 9, 23, 37, 0 }; - static ulong[] dim15SLinitializers = { 1, 3, 3, 5, 19, 33, 0 }; - static ulong[] dim16SLinitializers = { 1, 1, 3, 13, 11, 7, 0 }; - static ulong[] dim17SLinitializers = { 1, 1, 7, 13, 25, 5, 0 }; - static ulong[] dim18SLinitializers = { 1, 3, 5, 11, 7, 11, 0 }; - static ulong[] dim19SLinitializers = { 1, 1, 1, 3, 13, 39, 0 }; - static ulong[] dim20SLinitializers = { 1, 3, 1, 15, 17, 63, 13, 0 }; - static ulong[] dim21SLinitializers = { 1, 1, 5, 5, 1, 27, 33, 0 }; - static ulong[] dim22SLinitializers = { 1, 3, 3, 3, 25, 17, 115, 0 }; - static ulong[] dim23SLinitializers = { 1, 1, 3, 15, 29, 15, 41, 0 }; - static ulong[] dim24SLinitializers = { 1, 3, 1, 7, 3, 23, 79, 0 }; - static ulong[] dim25SLinitializers = { 1, 3, 7, 9, 31, 29, 17, 0 }; - static ulong[] dim26SLinitializers = { 1, 1, 5, 13, 11, 3, 29, 0 }; - static ulong[] dim27SLinitializers = { 1, 3, 1, 9, 5, 21, 119, 0 }; - static ulong[] dim28SLinitializers = { 1, 1, 3, 1, 23, 13, 75, 0 }; - static ulong[] dim29SLinitializers = { 1, 3, 3, 11, 27, 31, 73, 0 }; - static ulong[] dim30SLinitializers = { 1, 1, 7, 7, 19, 25, 105, 0 }; - static ulong[] dim31SLinitializers = { 1, 3, 5, 5, 21, 9, 7, 0 }; - static ulong[] dim32SLinitializers = { 1, 1, 1, 15, 5, 49, 59, 0 }; - static ulong[] dim33SLinitializers = { 1, 1, 1, 1, 1, 33, 65, 0 }; - static ulong[] dim34SLinitializers = { 1, 3, 5, 15, 17, 19, 21, 0 }; - static ulong[] dim35SLinitializers = { 1, 1, 7, 11, 13, 29, 3, 0 }; - static ulong[] dim36SLinitializers = { 1, 3, 7, 5, 7, 11, 113, 0 }; - static ulong[] dim37SLinitializers = { 1, 1, 5, 3, 15, 19, 61, 0 }; - static ulong[] dim38SLinitializers = { 1, 3, 1, 1, 9, 27, 89, 7, 0 }; - static ulong[] dim39SLinitializers = { 1, 1, 3, 7, 31, 15, 45, 23, 0 }; - static ulong[] dim40SLinitializers = { 1, 3, 3, 9, 9, 25, 107, 39, 0 }; - - static ulong[][] SLinitializers = { - dim02SLinitializers, - dim03SLinitializers, - dim04SLinitializers, - dim05SLinitializers, - dim06SLinitializers, - dim07SLinitializers, - dim08SLinitializers, - dim09SLinitializers, - dim10SLinitializers, - dim11SLinitializers, - dim12SLinitializers, - dim13SLinitializers, - dim14SLinitializers, - dim15SLinitializers, - dim16SLinitializers, - dim17SLinitializers, - dim18SLinitializers, - dim19SLinitializers, - dim20SLinitializers, - dim21SLinitializers, - dim22SLinitializers, - dim23SLinitializers, - dim24SLinitializers, - dim25SLinitializers, - dim26SLinitializers, - dim27SLinitializers, - dim28SLinitializers, - dim29SLinitializers, - dim30SLinitializers, - dim31SLinitializers, - dim32SLinitializers, - dim33SLinitializers, - dim34SLinitializers, - dim35SLinitializers, - dim36SLinitializers, - dim37SLinitializers, - dim38SLinitializers, - dim39SLinitializers, - dim40SLinitializers - }; - - /* coefficients of the free direction integers as given in - "Monte Carlo Methods in Finance", by Peter Jдckel, section 8.3 - */ - static ulong[] dim09initializers = { 1, 3, 7, 7, 21, 0 }; - static ulong[] dim10initializers = { 1, 1, 5, 11, 27, 0 }; - static ulong[] dim11initializers = { 1, 1, 7, 3, 29, 0 }; - static ulong[] dim12initializers = { 1, 3, 7, 13, 3, 0 }; - static ulong[] dim13initializers = { 1, 3, 5, 1, 15, 0 }; - static ulong[] dim14initializers = { 1, 1, 1, 9, 23, 37, 0 }; - static ulong[] dim15initializers = { 1, 1, 3, 13, 11, 7, 0 }; - static ulong[] dim16initializers = { 1, 3, 3, 5, 19, 33, 0 }; - static ulong[] dim17initializers = { 1, 1, 7, 13, 25, 5, 0 }; - static ulong[] dim18initializers = { 1, 1, 1, 3, 13, 39, 0 }; - static ulong[] dim19initializers = { 1, 3, 5, 11, 7, 11, 0 }; - static ulong[] dim20initializers = { 1, 3, 1, 7, 3, 23, 79, 0 }; - static ulong[] dim21initializers = { 1, 3, 1, 15, 17, 63, 13, 0 }; - static ulong[] dim22initializers = { 1, 3, 3, 3, 25, 17, 115, 0 }; - static ulong[] dim23initializers = { 1, 3, 7, 9, 31, 29, 17, 0 }; - static ulong[] dim24initializers = { 1, 1, 3, 15, 29, 15, 41, 0 }; - static ulong[] dim25initializers = { 1, 3, 1, 9, 5, 21, 119, 0 }; - static ulong[] dim26initializers = { 1, 1, 5, 5, 1, 27, 33, 0 }; - static ulong[] dim27initializers = { 1, 1, 3, 1, 23, 13, 75, 0 }; - static ulong[] dim28initializers = { 1, 1, 7, 7, 19, 25, 105, 0 }; - static ulong[] dim29initializers = { 1, 3, 5, 5, 21, 9, 7, 0 }; - static ulong[] dim30initializers = { 1, 1, 1, 15, 5, 49, 59, 0 }; - static ulong[] dim31initializers = { 1, 3, 5, 15, 17, 19, 21, 0 }; - static ulong[] dim32initializers = { 1, 1, 7, 11, 13, 29, 3, 0 }; - - static ulong[][] initializers = { - dim02SLinitializers, - dim03SLinitializers, - dim04SLinitializers, - dim05SLinitializers, - dim06SLinitializers, - dim07SLinitializers, - dim08SLinitializers, - dim09initializers, - dim10initializers, - dim11initializers, - dim12initializers, - dim13initializers, - dim14initializers, - dim15initializers, - dim16initializers, - dim17initializers, - dim18initializers, - dim19initializers, - dim20initializers, - dim21initializers, - dim22initializers, - dim23initializers, - dim24initializers, - dim25initializers, - dim26initializers, - dim27initializers, - dim28initializers, - dim29initializers, - dim30initializers, - dim31initializers, - dim32initializers - }; - - /* Lemieux coefficients of the free direction integers as given - in Christiane Lemieux, private communication, September 2004 - */ - static ulong[] dim041Linitializers = { 1,1,3,13,7,35,61,91,0}; - static ulong[] dim042Linitializers = { 1,1,7,11,5,35,55,75,0}; - static ulong[] dim043Linitializers = { 1,3,5,5,11,23,29,139,0}; - static ulong[] dim044Linitializers = { 1,1,1,7,11,15,17,81,0}; - static ulong[] dim045Linitializers = { 1,1,7,9,5,57,79,103,0}; - static ulong[] dim046Linitializers = { 1,1,7,13,19,5,5,185,0}; - static ulong[] dim047Linitializers = { 1,3,1,3,13,57,97,131,0}; - static ulong[] dim048Linitializers = { 1,1,5,5,21,25,125,197,0}; - static ulong[] dim049Linitializers = { 1,3,3,9,31,11,103,201,0}; - static ulong[] dim050Linitializers = { 1,1,5,3,7,25,51,121,0}; - static ulong[] dim051Linitializers = { 1,3,7,15,19,53,73,189,0}; - static ulong[] dim052Linitializers = { 1,1,1,15,19,55,27,183,0}; - static ulong[] dim053Linitializers = { 1,1,7,13,3,29,109,69,0}; - static ulong[] dim054Linitializers = { 1,1,5,15,15,23,15,1,57,0}; - static ulong[] dim055Linitializers = { 1,3,1,3,23,55,43,143,397,0}; - static ulong[] dim056Linitializers = { 1,1,3,11,29,9,35,131,411,0}; - static ulong[] dim057Linitializers = { 1,3,1,7,27,39,103,199,277,0}; - static ulong[] dim058Linitializers = { 1,3,7,3,19,55,127,67,449,0}; - static ulong[] dim059Linitializers = { 1,3,7,3,5,29,45,85,3,0}; - static ulong[] dim060Linitializers = { 1,3,5,5,13,23,75,245,453,0}; - static ulong[] dim061Linitializers = { 1,3,1,15,21,47,3,77,165,0}; - static ulong[] dim062Linitializers = { 1,1,7,9,15,5,117,73,473,0}; - static ulong[] dim063Linitializers = { 1,3,1,9,1,21,13,173,313,0}; - static ulong[] dim064Linitializers = { 1,1,7,3,11,45,63,77,49,0}; - static ulong[] dim065Linitializers = { 1,1,1,1,1,25,123,39,259,0}; - static ulong[] dim066Linitializers = { 1,1,1,5,23,11,59,11,203,0}; - static ulong[] dim067Linitializers = { 1,3,3,15,21,1,73,71,421,0}; - static ulong[] dim068Linitializers = { 1,1,5,11,15,31,115,95,217,0}; - static ulong[] dim069Linitializers = { 1,1,3,3,7,53,37,43,439,0}; - static ulong[] dim070Linitializers = { 1,1,1,1,27,53,69,159,321,0}; - static ulong[] dim071Linitializers = { 1,1,5,15,29,17,19,43,449,0}; - static ulong[] dim072Linitializers = { 1,1,3,9,1,55,121,205,255,0}; - static ulong[] dim073Linitializers = { 1,1,3,11,9,47,107,11,417,0}; - static ulong[] dim074Linitializers = { 1,1,1,5,17,25,21,83,95,0}; - static ulong[] dim075Linitializers = { 1,3,5,13,31,25,61,157,407,0}; - static ulong[] dim076Linitializers = { 1,1,7,9,25,33,41,35,17,0}; - static ulong[] dim077Linitializers = { 1,3,7,15,13,39,61,187,461,0}; - static ulong[] dim078Linitializers = { 1,3,7,13,5,57,23,177,435,0}; - static ulong[] dim079Linitializers = { 1,1,3,15,11,27,115,5,337,0}; - static ulong[] dim080Linitializers = { 1,3,7,3,15,63,61,171,339,0}; - static ulong[] dim081Linitializers = { 1,3,3,13,15,61,59,47,1,0}; - static ulong[] dim082Linitializers = { 1,1,5,15,13,5,39,83,329,0}; - static ulong[] dim083Linitializers = { 1,1,5,5,5,27,25,39,301,0}; - static ulong[] dim084Linitializers = { 1,1,5,11,31,41,35,233,27,0}; - static ulong[] dim085Linitializers = { 1,3,5,15,7,37,119,171,419,0}; - static ulong[] dim086Linitializers = { 1,3,5,5,3,29,21,189,417,0}; - static ulong[] dim087Linitializers = { 1,1,1,1,21,41,117,119,351,0}; - static ulong[] dim088Linitializers = { 1,1,3,1,7,27,87,19,213,0}; - static ulong[] dim089Linitializers = { 1,1,1,1,17,7,97,217,477,0}; - static ulong[] dim090Linitializers = { 1,1,7,1,29,61,103,231,269,0}; - static ulong[] dim091Linitializers = { 1,1,7,13,9,27,107,207,311,0}; - static ulong[] dim092Linitializers = { 1,1,7,5,25,21,107,179,423,0}; - static ulong[] dim093Linitializers = { 1,3,5,11,7,1,17,245,281,0}; - static ulong[] dim094Linitializers = { 1,3,5,9,1,5,53,59,125,0}; - static ulong[] dim095Linitializers = { 1,1,7,1,31,57,71,245,125,0}; - static ulong[] dim096Linitializers = { 1,1,7,5,5,57,53,253,441,0}; - static ulong[] dim097Linitializers = { 1,3,1,13,19,35,119,235,381,0}; - static ulong[] dim098Linitializers = { 1,3,1,7,19,59,115,33,361,0}; - static ulong[] dim099Linitializers = { 1,1,3,5,13,1,49,143,501,0}; - static ulong[] dim100Linitializers = { 1,1,3,5,1,63,101,85,189,0}; - static ulong[] dim101Linitializers = { 1,1,5,11,27,63,13,131,5,0}; - static ulong[] dim102Linitializers = { 1,1,5,7,15,45,75,59,455,585,0}; - static ulong[] dim103Linitializers = { 1,3,1,3,7,7,111,23,119,959,0}; - static ulong[] dim104Linitializers = { 1,3,3,9,11,41,109,163,161,879,0}; - static ulong[] dim105Linitializers = { 1,3,5,1,21,41,121,183,315,219,0}; - static ulong[] dim106Linitializers = { 1,1,3,9,15,3,9,223,441,929,0}; - static ulong[] dim107Linitializers = { 1,1,7,9,3,5,93,57,253,457,0}; - static ulong[] dim108Linitializers = { 1,1,7,13,15,29,83,21,35,45,0}; - static ulong[] dim109Linitializers = { 1,1,3,7,13,61,119,219,85,505,0}; - static ulong[] dim110Linitializers = { 1,1,3,3,17,13,35,197,291,109,0}; - static ulong[] dim111Linitializers = { 1,1,3,3,5,1,113,103,217,253,0}; - static ulong[] dim112Linitializers = { 1,1,7,1,15,39,63,223,17,9,0}; - static ulong[] dim113Linitializers = { 1,3,7,1,17,29,67,103,495,383,0}; - static ulong[] dim114Linitializers = { 1,3,3,15,31,59,75,165,51,913,0}; - static ulong[] dim115Linitializers = { 1,3,7,9,5,27,79,219,233,37,0}; - static ulong[] dim116Linitializers = { 1,3,5,15,1,11,15,211,417,811,0}; - static ulong[] dim117Linitializers = { 1,3,5,3,29,27,39,137,407,231,0}; - static ulong[] dim118Linitializers = { 1,1,3,5,29,43,125,135,109,67,0}; - static ulong[] dim119Linitializers = { 1,1,1,5,11,39,107,159,323,381,0}; - static ulong[] dim120Linitializers = { 1,1,1,1,9,11,33,55,169,253,0}; - static ulong[] dim121Linitializers = { 1,3,5,5,11,53,63,101,251,897,0}; - static ulong[] dim122Linitializers = { 1,3,7,1,25,15,83,119,53,157,0}; - static ulong[] dim123Linitializers = { 1,3,5,13,5,5,3,195,111,451,0}; - static ulong[] dim124Linitializers = { 1,3,1,15,11,1,19,11,307,777,0}; - static ulong[] dim125Linitializers = { 1,3,7,11,5,5,17,231,345,981,0}; - static ulong[] dim126Linitializers = { 1,1,3,3,1,33,83,201,57,475,0}; - static ulong[] dim127Linitializers = { 1,3,7,7,17,13,35,175,499,809,0}; - static ulong[] dim128Linitializers = { 1,1,5,3,3,17,103,119,499,865,0}; - static ulong[] dim129Linitializers = { 1,1,1,11,27,25,37,121,401,11,0}; - static ulong[] dim130Linitializers = { 1,1,1,11,9,25,25,241,403,3,0}; - static ulong[] dim131Linitializers = { 1,1,1,1,11,1,39,163,231,573,0}; - static ulong[] dim132Linitializers = { 1,1,1,13,13,21,75,185,99,545,0}; - static ulong[] dim133Linitializers = { 1,1,1,15,3,63,69,11,173,315,0}; - static ulong[] dim134Linitializers = { 1,3,5,15,11,3,95,49,123,765,0}; - static ulong[] dim135Linitializers = { 1,1,1,15,3,63,77,31,425,711,0}; - static ulong[] dim136Linitializers = { 1,1,7,15,1,37,119,145,489,583,0}; - static ulong[] dim137Linitializers = { 1,3,5,15,3,49,117,211,165,323,0}; - static ulong[] dim138Linitializers = { 1,3,7,1,27,63,77,201,225,803,0}; - static ulong[] dim139Linitializers = { 1,1,1,11,23,35,67,21,469,357,0}; - static ulong[] dim140Linitializers = { 1,1,7,7,9,7,25,237,237,571,0}; - static ulong[] dim141Linitializers = { 1,1,3,15,29,5,107,109,241,47,0}; - static ulong[] dim142Linitializers = { 1,3,5,11,27,63,29,13,203,675,0}; - static ulong[] dim143Linitializers = { 1,1,3,9,9,11,103,179,449,263,0}; - static ulong[] dim144Linitializers = { 1,3,5,11,29,63,53,151,259,223,0}; - static ulong[] dim145Linitializers = { 1,1,3,7,9,25,5,197,237,163,0}; - static ulong[] dim146Linitializers = { 1,3,7,13,5,57,67,193,147,241,0}; - static ulong[] dim147Linitializers = { 1,1,5,15,15,33,17,67,161,341,0}; - static ulong[] dim148Linitializers = { 1,1,3,13,17,43,21,197,441,985,0}; - static ulong[] dim149Linitializers = { 1,3,1,5,15,33,33,193,305,829,0}; - static ulong[] dim150Linitializers = { 1,1,1,13,19,27,71,187,477,239,0}; - static ulong[] dim151Linitializers = { 1,1,1,9,9,17,41,177,229,983,0}; - static ulong[] dim152Linitializers = { 1,3,5,9,15,45,97,205,43,767,0}; - static ulong[] dim153Linitializers = { 1,1,1,9,31,31,77,159,395,809,0}; - static ulong[] dim154Linitializers = { 1,3,3,3,29,19,73,123,165,307,0}; - static ulong[] dim155Linitializers = { 1,3,1,7,5,11,77,227,355,403,0}; - static ulong[] dim156Linitializers = { 1,3,5,5,25,31,1,215,451,195,0}; - static ulong[] dim157Linitializers = { 1,3,7,15,29,37,101,241,17,633,0}; - static ulong[] dim158Linitializers = { 1,1,5,1,11,3,107,137,489,5,0}; - static ulong[] dim159Linitializers = { 1,1,1,7,19,19,75,85,471,355,0}; - static ulong[] dim160Linitializers = { 1,1,3,3,9,13,113,167,13,27,0}; - static ulong[] dim161Linitializers = { 1,3,5,11,21,3,89,205,377,307,0}; - static ulong[] dim162Linitializers = { 1,1,1,9,31,61,65,9,391,141,867,0}; - static ulong[] dim163Linitializers = { 1,1,1,9,19,19,61,227,241,55,161,0}; - static ulong[] dim164Linitializers = { 1,1,1,11,1,19,7,233,463,171,1941,0}; - static ulong[] dim165Linitializers = { 1,1,5,7,25,13,103,75,19,1021,1063,0}; - static ulong[] dim166Linitializers = { 1,1,1,15,17,17,79,63,391,403,1221,0}; - static ulong[] dim167Linitializers = { 1,3,3,11,29,25,29,107,335,475,963,0}; - static ulong[] dim168Linitializers = { 1,3,5,1,31,33,49,43,155,9,1285,0}; - static ulong[] dim169Linitializers = { 1,1,5,5,15,47,39,161,357,863,1039,0}; - static ulong[] dim170Linitializers = { 1,3,7,15,1,39,47,109,427,393,1103,0}; - static ulong[] dim171Linitializers = { 1,1,1,9,9,29,121,233,157,99,701,0}; - static ulong[] dim172Linitializers = { 1,1,1,7,1,29,75,121,439,109,993,0}; - static ulong[] dim173Linitializers = { 1,1,1,9,5,1,39,59,89,157,1865,0}; - static ulong[] dim174Linitializers = { 1,1,5,1,3,37,89,93,143,533,175,0}; - static ulong[] dim175Linitializers = { 1,1,3,5,7,33,35,173,159,135,241,0}; - static ulong[] dim176Linitializers = { 1,1,1,15,17,37,79,131,43,891,229,0}; - static ulong[] dim177Linitializers = { 1,1,1,1,1,35,121,177,397,1017,583,0}; - static ulong[] dim178Linitializers = { 1,1,3,15,31,21,43,67,467,923,1473,0}; - static ulong[] dim179Linitializers = { 1,1,1,7,1,33,77,111,125,771,1975,0}; - static ulong[] dim180Linitializers = { 1,3,7,13,1,51,113,139,245,573,503,0}; - static ulong[] dim181Linitializers = { 1,3,1,9,21,49,15,157,49,483,291,0}; - static ulong[] dim182Linitializers = { 1,1,1,1,29,35,17,65,403,485,1603,0}; - static ulong[] dim183Linitializers = { 1,1,1,7,19,1,37,129,203,321,1809,0}; - static ulong[] dim184Linitializers = { 1,3,7,15,15,9,5,77,29,485,581,0}; - static ulong[] dim185Linitializers = { 1,1,3,5,15,49,97,105,309,875,1581,0}; - static ulong[] dim186Linitializers = { 1,3,5,1,5,19,63,35,165,399,1489,0}; - static ulong[] dim187Linitializers = { 1,3,5,3,23,5,79,137,115,599,1127,0}; - static ulong[] dim188Linitializers = { 1,1,7,5,3,61,27,177,257,91,841,0}; - static ulong[] dim189Linitializers = { 1,1,3,5,9,31,91,209,409,661,159,0}; - static ulong[] dim190Linitializers = { 1,3,1,15,23,39,23,195,245,203,947,0}; - static ulong[] dim191Linitializers = { 1,1,3,1,15,59,67,95,155,461,147,0}; - static ulong[] dim192Linitializers = { 1,3,7,5,23,25,87,11,51,449,1631,0}; - static ulong[] dim193Linitializers = { 1,1,1,1,17,57,7,197,409,609,135,0}; - static ulong[] dim194Linitializers = { 1,1,1,9,1,61,115,113,495,895,1595,0}; - static ulong[] dim195Linitializers = { 1,3,7,15,9,47,121,211,379,985,1755,0}; - static ulong[] dim196Linitializers = { 1,3,1,3,7,57,27,231,339,325,1023,0}; - static ulong[] dim197Linitializers = { 1,1,1,1,19,63,63,239,31,643,373,0}; - static ulong[] dim198Linitializers = { 1,3,1,11,19,9,7,171,21,691,215,0}; - static ulong[] dim199Linitializers = { 1,1,5,13,11,57,39,211,241,893,555,0}; - static ulong[] dim200Linitializers = { 1,1,7,5,29,21,45,59,509,223,491,0}; - static ulong[] dim201Linitializers = { 1,1,7,9,15,61,97,75,127,779,839,0}; - static ulong[] dim202Linitializers = { 1,1,7,15,17,33,75,237,191,925,681,0}; - static ulong[] dim203Linitializers = { 1,3,5,7,27,57,123,111,101,371,1129,0}; - static ulong[] dim204Linitializers = { 1,3,5,5,29,45,59,127,229,967,2027,0}; - static ulong[] dim205Linitializers = { 1,1,1,1,17,7,23,199,241,455,135,0}; - static ulong[] dim206Linitializers = { 1,1,7,15,27,29,105,171,337,503,1817,0}; - static ulong[] dim207Linitializers = { 1,1,3,7,21,35,61,71,405,647,2045,0}; - static ulong[] dim208Linitializers = { 1,1,1,1,1,15,65,167,501,79,737,0}; - static ulong[] dim209Linitializers = { 1,1,5,1,3,49,27,189,341,615,1287,0}; - static ulong[] dim210Linitializers = { 1,1,1,9,1,7,31,159,503,327,1613,0}; - static ulong[] dim211Linitializers = { 1,3,3,3,3,23,99,115,323,997,987,0}; - static ulong[] dim212Linitializers = { 1,1,1,9,19,33,93,247,509,453,891,0}; - static ulong[] dim213Linitializers = { 1,1,3,1,13,19,35,153,161,633,445,0}; - static ulong[] dim214Linitializers = { 1,3,5,15,31,5,87,197,183,783,1823,0}; - static ulong[] dim215Linitializers = { 1,1,7,5,19,63,69,221,129,231,1195,0}; - static ulong[] dim216Linitializers = { 1,1,5,5,13,23,19,231,245,917,379,0}; - static ulong[] dim217Linitializers = { 1,3,1,15,19,43,27,223,171,413,125,0}; - static ulong[] dim218Linitializers = { 1,1,1,9,1,59,21,15,509,207,589,0}; - static ulong[] dim219Linitializers = { 1,3,5,3,19,31,113,19,23,733,499,0}; - static ulong[] dim220Linitializers = { 1,1,7,1,19,51,101,165,47,925,1093,0}; - static ulong[] dim221Linitializers = { 1,3,3,9,15,21,43,243,237,461,1361,0}; - static ulong[] dim222Linitializers = { 1,1,1,9,17,15,75,75,113,715,1419,0}; - static ulong[] dim223Linitializers = { 1,1,7,13,17,1,99,15,347,721,1405,0}; - static ulong[] dim224Linitializers = { 1,1,7,15,7,27,23,183,39,59,571,0}; - static ulong[] dim225Linitializers = { 1,3,5,9,7,43,35,165,463,567,859,0}; - static ulong[] dim226Linitializers = { 1,3,3,11,15,19,17,129,311,343,15,0}; - static ulong[] dim227Linitializers = { 1,1,1,15,31,59,63,39,347,359,105,0}; - static ulong[] dim228Linitializers = { 1,1,1,15,5,43,87,241,109,61,685,0}; - static ulong[] dim229Linitializers = { 1,1,7,7,9,39,121,127,369,579,853,0}; - static ulong[] dim230Linitializers = { 1,1,1,1,17,15,15,95,325,627,299,0}; - static ulong[] dim231Linitializers = { 1,1,3,13,31,53,85,111,289,811,1635,0}; - static ulong[] dim232Linitializers = { 1,3,7,1,19,29,75,185,153,573,653,0}; - static ulong[] dim233Linitializers = { 1,3,7,1,29,31,55,91,249,247,1015,0}; - static ulong[] dim234Linitializers = { 1,3,5,7,1,49,113,139,257,127,307,0}; - static ulong[] dim235Linitializers = { 1,3,5,9,15,15,123,105,105,225,1893,0}; - static ulong[] dim236Linitializers = { 1,3,3,1,15,5,105,249,73,709,1557,0}; - static ulong[] dim237Linitializers = { 1,1,1,9,17,31,113,73,65,701,1439,0}; - static ulong[] dim238Linitializers = { 1,3,5,15,13,21,117,131,243,859,323,0}; - static ulong[] dim239Linitializers = { 1,1,1,9,19,15,69,149,89,681,515,0}; - static ulong[] dim240Linitializers = { 1,1,1,5,29,13,21,97,301,27,967,0}; - static ulong[] dim241Linitializers = { 1,1,3,3,15,45,107,227,495,769,1935,0}; - static ulong[] dim242Linitializers = { 1,1,1,11,5,27,41,173,261,703,1349,0}; - static ulong[] dim243Linitializers = { 1,3,3,3,11,35,97,43,501,563,1331,0}; - static ulong[] dim244Linitializers = { 1,1,1,7,1,17,87,17,429,245,1941,0}; - static ulong[] dim245Linitializers = { 1,1,7,15,29,13,1,175,425,233,797,0}; - static ulong[] dim246Linitializers = { 1,1,3,11,21,57,49,49,163,685,701,0}; - static ulong[] dim247Linitializers = { 1,3,3,7,11,45,107,111,379,703,1403,0}; - static ulong[] dim248Linitializers = { 1,1,7,3,21,7,117,49,469,37,775,0}; - static ulong[] dim249Linitializers = { 1,1,5,15,31,63,101,77,507,489,1955,0}; - static ulong[] dim250Linitializers = { 1,3,3,11,19,21,101,255,203,673,665,0}; - static ulong[] dim251Linitializers = { 1,3,3,15,17,47,125,187,271,899,2003,0}; - static ulong[] dim252Linitializers = { 1,1,7,7,1,35,13,235,5,337,905,0}; - static ulong[] dim253Linitializers = { 1,3,1,15,1,43,1,27,37,695,1429,0}; - static ulong[] dim254Linitializers = { 1,3,1,11,21,27,93,161,299,665,495,0}; - static ulong[] dim255Linitializers = { 1,3,3,15,3,1,81,111,105,547,897,0}; - static ulong[] dim256Linitializers = { 1,3,5,1,3,53,97,253,401,827,1467,0}; - static ulong[] dim257Linitializers = {1,1,1,5,19,59,105,125,271,351,719,0}; - static ulong[] dim258Linitializers = {1,3,5,13,7,11,91,41,441,759,1827,0}; - static ulong[] dim259Linitializers = {1,3,7,11,29,61,61,23,307,863,363,0}; - static ulong[] dim260Linitializers = {1,1,7,1,15,35,29,133,415,473,1737,0}; - static ulong[] dim261Linitializers = {1,1,1,13,7,33,35,225,117,681,1545,0}; - static ulong[] dim262Linitializers = {1,1,1,3,5,41,83,247,13,373,1091,0}; - static ulong[] dim263Linitializers = {1,3,1,13,25,61,71,217,233,313,547,0}; - static ulong[] dim264Linitializers = {1,3,1,7,3,29,3,49,93,465,15,0}; - static ulong[] dim265Linitializers = {1,1,1,9,17,61,99,163,129,485,1087,0}; - static ulong[] dim266Linitializers = {1,1,1,9,9,33,31,163,145,649,253,0}; - static ulong[] dim267Linitializers = {1,1,1,1,17,63,43,235,287,111,567,0}; - static ulong[] dim268Linitializers = {1,3,5,13,29,7,11,69,153,127,449,0}; - static ulong[] dim269Linitializers = {1,1,5,9,11,21,15,189,431,493,1219,0}; - static ulong[] dim270Linitializers = {1,1,1,15,19,5,47,91,399,293,1743,0}; - static ulong[] dim271Linitializers = {1,3,3,11,29,53,53,225,409,303,333,0}; - static ulong[] dim272Linitializers = {1,1,1,15,31,31,21,81,147,287,1753,0}; - static ulong[] dim273Linitializers = {1,3,5,5,5,63,35,125,41,687,1793,0}; - static ulong[] dim274Linitializers = {1,1,1,9,19,59,107,219,455,971,297,0}; - static ulong[] dim275Linitializers = {1,1,3,5,3,51,121,31,245,105,1311,0}; - static ulong[] dim276Linitializers = {1,3,1,5,5,57,75,107,161,431,1693,0}; - static ulong[] dim277Linitializers = {1,3,1,3,19,53,27,31,191,565,1015,0}; - static ulong[] dim278Linitializers = {1,3,5,13,9,41,35,249,287,49,123,0}; - static ulong[] dim279Linitializers = {1,1,5,7,27,17,21,3,151,885,1165,0}; - static ulong[] dim280Linitializers = {1,1,7,1,15,17,65,139,427,339,1171,0}; - static ulong[] dim281Linitializers = {1,1,1,5,23,5,9,89,321,907,391,0}; - static ulong[] dim282Linitializers = {1,1,7,9,15,1,77,71,87,701,917,0}; - static ulong[] dim283Linitializers = {1,1,7,1,17,37,115,127,469,779,1543,0}; - static ulong[] dim284Linitializers = {1,3,7,3,5,61,15,37,301,951,1437,0}; - static ulong[] dim285Linitializers = {1,1,1,13,9,51,127,145,229,55,1567,0}; - static ulong[] dim286Linitializers = {1,3,7,15,19,47,53,153,295,47,1337,0}; - static ulong[] dim287Linitializers = {1,3,3,5,11,31,29,133,327,287,507,0}; - static ulong[] dim288Linitializers = {1,1,7,7,25,31,37,199,25,927,1317,0}; - static ulong[] dim289Linitializers = {1,1,7,9,3,39,127,167,345,467,759,0}; - static ulong[] dim290Linitializers = {1,1,1,1,31,21,15,101,293,787,1025,0}; - static ulong[] dim291Linitializers = {1,1,5,3,11,41,105,109,149,837,1813,0}; - static ulong[] dim292Linitializers = {1,1,3,5,29,13,19,97,309,901,753,0}; - static ulong[] dim293Linitializers = {1,1,7,1,19,17,31,39,173,361,1177,0}; - static ulong[] dim294Linitializers = {1,3,3,3,3,41,81,7,341,491,43,0}; - static ulong[] dim295Linitializers = {1,1,7,7,31,35,29,77,11,335,1275,0}; - static ulong[] dim296Linitializers = {1,3,3,15,17,45,19,63,151,849,129,0}; - static ulong[] dim297Linitializers = {1,1,7,5,7,13,47,73,79,31,499,0}; - static ulong[] dim298Linitializers = {1,3,1,11,1,41,59,151,247,115,1295,0}; - static ulong[] dim299Linitializers = {1,1,1,9,31,37,73,23,295,483,179,0}; - static ulong[] dim300Linitializers = {1,3,1,15,13,63,81,27,169,825,2037,0}; - static ulong[] dim301Linitializers = {1,3,5,15,7,11,73,1,451,101,2039,0}; - static ulong[] dim302Linitializers = {1,3,5,3,13,53,31,137,173,319,1521,0}; - static ulong[] dim303Linitializers = {1,3,1,3,29,1,73,227,377,337,1189,0}; - static ulong[] dim304Linitializers = {1,3,3,13,27,9,31,101,229,165,1983,0}; - static ulong[] dim305Linitializers = {1,3,1,13,13,19,19,111,319,421,223,0}; - static ulong[] dim306Linitializers = {1,1,7,15,25,37,61,55,359,255,1955,0}; - static ulong[] dim307Linitializers = {1,1,5,13,17,43,49,215,383,915,51,0}; - static ulong[] dim308Linitializers = {1,1,3,1,3,7,13,119,155,585,967,0}; - static ulong[] dim309Linitializers = {1,3,1,13,1,63,125,21,103,287,457,0}; - static ulong[] dim310Linitializers = {1,1,7,1,31,17,125,137,345,379,1925,0}; - static ulong[] dim311Linitializers = {1,1,3,5,5,25,119,153,455,271,2023,0}; - static ulong[] dim312Linitializers = {1,1,7,9,9,37,115,47,5,255,917,0}; - static ulong[] dim313Linitializers = {1,3,5,3,31,21,75,203,489,593,1,0}; - static ulong[] dim314Linitializers = {1,3,7,15,19,63,123,153,135,977,1875,0}; - static ulong[] dim315Linitializers = {1,1,1,1,5,59,31,25,127,209,745,0}; - static ulong[] dim316Linitializers = {1,1,1,1,19,45,67,159,301,199,535,0}; - static ulong[] dim317Linitializers = {1,1,7,1,31,17,19,225,369,125,421,0}; - static ulong[] dim318Linitializers = {1,3,3,11,7,59,115,197,459,469,1055,0}; - static ulong[] dim319Linitializers = {1,3,1,3,27,45,35,131,349,101,411,0}; - static ulong[] dim320Linitializers = {1,3,7,11,9,3,67,145,299,253,1339,0}; - static ulong[] dim321Linitializers = {1,3,3,11,9,37,123,229,273,269,515,0}; - static ulong[] dim322Linitializers = {1,3,7,15,11,25,75,5,367,217,951,0}; - static ulong[] dim323Linitializers = {1,1,3,7,9,23,63,237,385,159,1273,0}; - static ulong[] dim324Linitializers = {1,1,5,11,23,5,55,193,109,865,663,0}; - static ulong[] dim325Linitializers = {1,1,7,15,1,57,17,141,51,217,1259,0}; - static ulong[] dim326Linitializers = {1,1,3,3,15,7,89,233,71,329,203,0}; - static ulong[] dim327Linitializers = {1,3,7,11,11,1,19,155,89,437,573,0}; - static ulong[] dim328Linitializers = {1,3,1,9,27,61,47,109,161,913,1681,0}; - static ulong[] dim329Linitializers = {1,1,7,15,1,33,19,15,23,913,989,0}; - static ulong[] dim330Linitializers = {1,3,1,1,25,39,119,193,13,571,157,0}; - static ulong[] dim331Linitializers = {1,1,7,13,9,55,59,147,361,935,515,0}; - static ulong[] dim332Linitializers = {1,1,1,9,7,59,67,117,71,855,1493,0}; - static ulong[] dim333Linitializers = {1,3,1,3,13,19,57,141,305,275,1079,0}; - static ulong[] dim334Linitializers = {1,1,1,9,17,61,33,7,43,931,781,0}; - static ulong[] dim335Linitializers = {1,1,3,1,11,17,21,97,295,277,1721,0}; - static ulong[] dim336Linitializers = {1,3,1,13,15,43,11,241,147,391,1641,0}; - static ulong[] dim337Linitializers = {1,1,1,1,1,19,37,21,255,263,1571,0}; - static ulong[] dim338Linitializers = {1,1,3,3,23,59,89,17,475,303,757,543,0}; - static ulong[] dim339Linitializers = {1,3,3,9,11,55,35,159,139,203,1531,1825,0}; - static ulong[] dim340Linitializers = {1,1,5,3,17,53,51,241,269,949,1373,325,0}; - static ulong[] dim341Linitializers = {1,3,7,7,5,29,91,149,239,193,1951,2675,0}; - static ulong[] dim342Linitializers = {1,3,5,1,27,33,69,11,51,371,833,2685,0}; - static ulong[] dim343Linitializers = {1,1,1,15,1,17,35,57,171,1007,449,367,0}; - static ulong[] dim344Linitializers = {1,1,1,7,25,61,73,219,379,53,589,4065,0}; - static ulong[] dim345Linitializers = {1,3,5,13,21,29,45,19,163,169,147,597,0}; - static ulong[] dim346Linitializers = {1,1,5,11,21,27,7,17,237,591,255,1235,0}; - static ulong[] dim347Linitializers = {1,1,7,7,17,41,69,237,397,173,1229,2341,0}; - static ulong[] dim348Linitializers = {1,1,3,1,1,33,125,47,11,783,1323,2469,0}; - static ulong[] dim349Linitializers = {1,3,1,11,3,39,35,133,153,55,1171,3165,0}; - static ulong[] dim350Linitializers = {1,1,5,11,27,23,103,245,375,753,477,2165,0}; - static ulong[] dim351Linitializers = {1,3,1,15,15,49,127,223,387,771,1719,1465,0}; - static ulong[] dim352Linitializers = {1,1,1,9,11,9,17,185,239,899,1273,3961,0}; - static ulong[] dim353Linitializers = {1,1,3,13,11,51,73,81,389,647,1767,1215,0}; - static ulong[] dim354Linitializers = {1,3,5,15,19,9,69,35,349,977,1603,1435,0}; - static ulong[] dim355Linitializers = {1,1,1,1,19,59,123,37,41,961,181,1275,0}; - static ulong[] dim356Linitializers = {1,1,1,1,31,29,37,71,205,947,115,3017,0}; - static ulong[] dim357Linitializers = {1,1,7,15,5,37,101,169,221,245,687,195,0}; - static ulong[] dim358Linitializers = {1,1,1,1,19,9,125,157,119,283,1721,743,0}; - static ulong[] dim359Linitializers = {1,1,7,3,1,7,61,71,119,257,1227,2893,0}; - static ulong[] dim360Linitializers = {1,3,3,3,25,41,25,225,31,57,925,2139,0}; - - static ulong[][] Linitializers = { - dim02SLinitializers, - dim03SLinitializers, - dim04SLinitializers, - dim05SLinitializers, - dim06SLinitializers, - dim07SLinitializers, - dim08SLinitializers, - dim09SLinitializers, - dim10SLinitializers, - dim11SLinitializers, - dim12SLinitializers, - dim13SLinitializers, - dim14SLinitializers, - dim15SLinitializers, - dim16SLinitializers, - dim17SLinitializers, - dim18SLinitializers, - dim19SLinitializers, - dim20SLinitializers, - dim21SLinitializers, - dim22SLinitializers, - dim23SLinitializers, - dim24SLinitializers, - dim25SLinitializers, - dim26SLinitializers, - dim27SLinitializers, - dim28SLinitializers, - dim29SLinitializers, - dim30SLinitializers, - dim31SLinitializers, - dim32SLinitializers, - dim33SLinitializers, - dim34SLinitializers, - dim35SLinitializers, - dim36SLinitializers, - dim37SLinitializers, - dim38SLinitializers, - dim39SLinitializers, - dim40SLinitializers, - dim041Linitializers, - dim042Linitializers, - dim043Linitializers, - dim044Linitializers, - dim045Linitializers, - dim046Linitializers, - dim047Linitializers, - dim048Linitializers, - dim049Linitializers, - dim050Linitializers, - dim051Linitializers, - dim052Linitializers, - dim053Linitializers, - dim054Linitializers, - dim055Linitializers, - dim056Linitializers, - dim057Linitializers, - dim058Linitializers, - dim059Linitializers, - dim060Linitializers, - dim061Linitializers, - dim062Linitializers, - dim063Linitializers, - dim064Linitializers, - dim065Linitializers, - dim066Linitializers, - dim067Linitializers, - dim068Linitializers, - dim069Linitializers, - dim070Linitializers, - dim071Linitializers, - dim072Linitializers, - dim073Linitializers, - dim074Linitializers, - dim075Linitializers, - dim076Linitializers, - dim077Linitializers, - dim078Linitializers, - dim079Linitializers, - dim080Linitializers, - dim081Linitializers, - dim082Linitializers, - dim083Linitializers, - dim084Linitializers, - dim085Linitializers, - dim086Linitializers, - dim087Linitializers, - dim088Linitializers, - dim089Linitializers, - dim090Linitializers, - dim091Linitializers, - dim092Linitializers, - dim093Linitializers, - dim094Linitializers, - dim095Linitializers, - dim096Linitializers, - dim097Linitializers, - dim098Linitializers, - dim099Linitializers, - dim100Linitializers, - dim101Linitializers, - dim102Linitializers, - dim103Linitializers, - dim104Linitializers, - dim105Linitializers, - dim106Linitializers, - dim107Linitializers, - dim108Linitializers, - dim109Linitializers, - dim110Linitializers, - dim111Linitializers, - dim112Linitializers, - dim113Linitializers, - dim114Linitializers, - dim115Linitializers, - dim116Linitializers, - dim117Linitializers, - dim118Linitializers, - dim119Linitializers, - dim120Linitializers, - dim121Linitializers, - dim122Linitializers, - dim123Linitializers, - dim124Linitializers, - dim125Linitializers, - dim126Linitializers, - dim127Linitializers, - dim128Linitializers, - dim129Linitializers, - dim130Linitializers, - dim131Linitializers, - dim132Linitializers, - dim133Linitializers, - dim134Linitializers, - dim135Linitializers, - dim136Linitializers, - dim137Linitializers, - dim138Linitializers, - dim139Linitializers, - dim140Linitializers, - dim141Linitializers, - dim142Linitializers, - dim143Linitializers, - dim144Linitializers, - dim145Linitializers, - dim146Linitializers, - dim147Linitializers, - dim148Linitializers, - dim149Linitializers, - dim150Linitializers, - dim151Linitializers, - dim152Linitializers, - dim153Linitializers, - dim154Linitializers, - dim155Linitializers, - dim156Linitializers, - dim157Linitializers, - dim158Linitializers, - dim159Linitializers, - dim160Linitializers, - dim161Linitializers, - dim162Linitializers, - dim163Linitializers, - dim164Linitializers, - dim165Linitializers, - dim166Linitializers, - dim167Linitializers, - dim168Linitializers, - dim169Linitializers, - dim170Linitializers, - dim171Linitializers, - dim172Linitializers, - dim173Linitializers, - dim174Linitializers, - dim175Linitializers, - dim176Linitializers, - dim177Linitializers, - dim178Linitializers, - dim179Linitializers, - dim180Linitializers, - dim181Linitializers, - dim182Linitializers, - dim183Linitializers, - dim184Linitializers, - dim185Linitializers, - dim186Linitializers, - dim187Linitializers, - dim188Linitializers, - dim189Linitializers, - dim190Linitializers, - dim191Linitializers, - dim192Linitializers, - dim193Linitializers, - dim194Linitializers, - dim195Linitializers, - dim196Linitializers, - dim197Linitializers, - dim198Linitializers, - dim199Linitializers, - dim200Linitializers, - dim201Linitializers, - dim202Linitializers, - dim203Linitializers, - dim204Linitializers, - dim205Linitializers, - dim206Linitializers, - dim207Linitializers, - dim208Linitializers, - dim209Linitializers, - dim210Linitializers, - dim211Linitializers, - dim212Linitializers, - dim213Linitializers, - dim214Linitializers, - dim215Linitializers, - dim216Linitializers, - dim217Linitializers, - dim218Linitializers, - dim219Linitializers, - dim220Linitializers, - dim221Linitializers, - dim222Linitializers, - dim223Linitializers, - dim224Linitializers, - dim225Linitializers, - dim226Linitializers, - dim227Linitializers, - dim228Linitializers, - dim229Linitializers, - dim230Linitializers, - dim231Linitializers, - dim232Linitializers, - dim233Linitializers, - dim234Linitializers, - dim235Linitializers, - dim236Linitializers, - dim237Linitializers, - dim238Linitializers, - dim239Linitializers, - dim240Linitializers, - dim241Linitializers, - dim242Linitializers, - dim243Linitializers, - dim244Linitializers, - dim245Linitializers, - dim246Linitializers, - dim247Linitializers, - dim248Linitializers, - dim249Linitializers, - dim250Linitializers, - dim251Linitializers, - dim252Linitializers, - dim253Linitializers, - dim254Linitializers, - dim255Linitializers, - dim256Linitializers, - dim257Linitializers, - dim258Linitializers, - dim259Linitializers, - dim260Linitializers, - dim261Linitializers, - dim262Linitializers, - dim263Linitializers, - dim264Linitializers, - dim265Linitializers, - dim266Linitializers, - dim267Linitializers, - dim268Linitializers, - dim269Linitializers, - dim270Linitializers, - dim271Linitializers, - dim272Linitializers, - dim273Linitializers, - dim274Linitializers, - dim275Linitializers, - dim276Linitializers, - dim277Linitializers, - dim278Linitializers, - dim279Linitializers, - dim280Linitializers, - dim281Linitializers, - dim282Linitializers, - dim283Linitializers, - dim284Linitializers, - dim285Linitializers, - dim286Linitializers, - dim287Linitializers, - dim288Linitializers, - dim289Linitializers, - dim290Linitializers, - dim291Linitializers, - dim292Linitializers, - dim293Linitializers, - dim294Linitializers, - dim295Linitializers, - dim296Linitializers, - dim297Linitializers, - dim298Linitializers, - dim299Linitializers, - dim300Linitializers, - dim301Linitializers, - dim302Linitializers, - dim303Linitializers, - dim304Linitializers, - dim305Linitializers, - dim306Linitializers, - dim307Linitializers, - dim308Linitializers, - dim309Linitializers, - dim310Linitializers, - dim311Linitializers, - dim312Linitializers, - dim313Linitializers, - dim314Linitializers, - dim315Linitializers, - dim316Linitializers, - dim317Linitializers, - dim318Linitializers, - dim319Linitializers, - dim320Linitializers, - dim321Linitializers, - dim322Linitializers, - dim323Linitializers, - dim324Linitializers, - dim325Linitializers, - dim326Linitializers, - dim327Linitializers, - dim328Linitializers, - dim329Linitializers, - dim330Linitializers, - dim331Linitializers, - dim332Linitializers, - dim333Linitializers, - dim334Linitializers, - dim335Linitializers, - dim336Linitializers, - dim337Linitializers, - dim338Linitializers, - dim339Linitializers, - dim340Linitializers, - dim341Linitializers, - dim342Linitializers, - dim343Linitializers, - dim344Linitializers, - dim345Linitializers, - dim346Linitializers, - dim347Linitializers, - dim348Linitializers, - dim349Linitializers, - dim350Linitializers, - dim351Linitializers, - dim352Linitializers, - dim353Linitializers, - dim354Linitializers, - dim355Linitializers, - dim356Linitializers, - dim357Linitializers, - dim358Linitializers, - dim359Linitializers, - dim360Linitializers - }; - - static ulong[] dim1KuoInit = { 1 ,0 }; - static ulong[] dim2KuoInit = { 1 , 1 ,0 }; - static ulong[] dim3KuoInit = { 1 , 1 , 1 ,0 }; - static ulong[] dim4KuoInit = { 1 , 3 , 1 ,0 }; - static ulong[] dim5KuoInit = { 1 , 1 , 7 , 13 ,0 }; - static ulong[] dim6KuoInit = { 1 , 1 , 3 , 7 ,0 }; - static ulong[] dim7KuoInit = { 1 , 3 , 1 , 7 , 21 ,0 }; - static ulong[] dim8KuoInit = { 1 , 3 , 1 , 3 , 9 ,0 }; - static ulong[] dim9KuoInit = { 1 , 1 , 5 , 9 , 13 ,0 }; - static ulong[] dim10KuoInit = { 1 , 1 , 3 , 9 , 13 ,0 }; - static ulong[] dim11KuoInit = { 1 , 1 , 5 , 3 , 7 ,0 }; - static ulong[] dim12KuoInit = { 1 , 1 , 5 , 7 , 11 ,0 }; - static ulong[] dim13KuoInit = { 1 , 3 , 3 , 13 , 15 , 43 ,0 }; - static ulong[] dim14KuoInit = { 1 , 3 , 5 , 11 , 25 , 45 ,0 }; - static ulong[] dim15KuoInit = { 1 , 1 , 3 , 11 , 3 , 45 ,0 }; - static ulong[] dim16KuoInit = { 1 , 3 , 5 , 1 , 9 , 21 ,0 }; - static ulong[] dim17KuoInit = { 1 , 1 , 3 , 13 , 9 , 9 ,0 }; - static ulong[] dim18KuoInit = { 1 , 3 , 5 , 7 , 17 , 53 ,0 }; - static ulong[] dim19KuoInit = { 1 , 3 , 1 , 7 , 11 , 51 , 115 ,0 }; - static ulong[] dim20KuoInit = { 1 , 1 , 7 , 9 , 25 , 35 , 11 ,0 }; - static ulong[] dim21KuoInit = { 1 , 3 , 1 , 1 , 31 , 5 , 1 ,0 }; - static ulong[] dim22KuoInit = { 1 , 1 , 5 , 9 , 11 , 1 , 121 ,0 }; - static ulong[] dim23KuoInit = { 1 , 1 , 1 , 15 , 11 , 59 , 21 ,0 }; - static ulong[] dim24KuoInit = { 1 , 3 , 1 , 3 , 17 , 49 , 51 ,0 }; - static ulong[] dim25KuoInit = { 1 , 1 , 5 , 7 , 15 , 25 , 13 ,0 }; - static ulong[] dim26KuoInit = { 1 , 3 , 7 , 7 , 1 , 45 , 7 ,0 }; - static ulong[] dim27KuoInit = { 1 , 1 , 5 , 7 , 21 , 21 , 37 ,0 }; - static ulong[] dim28KuoInit = { 1 , 3 , 1 , 13 , 9 , 49 , 23 ,0 }; - static ulong[] dim29KuoInit = { 1 , 1 , 1 , 3 , 3 , 35 , 123 ,0 }; - static ulong[] dim30KuoInit = { 1 , 1 , 7 , 5 , 15 , 47 , 117 ,0 }; - static ulong[] dim31KuoInit = { 1 , 1 , 3 , 13 , 9 , 23 , 33 ,0 }; - static ulong[] dim32KuoInit = { 1 , 1 , 1 , 13 , 25 , 23 , 63 ,0 }; - static ulong[] dim33KuoInit = { 1 , 1 , 5 , 3 , 5 , 13 , 91 ,0 }; - static ulong[] dim34KuoInit = { 1 , 1 , 5 , 5 , 23 , 7 , 101 ,0 }; - static ulong[] dim35KuoInit = { 1 , 3 , 1 , 11 , 9 , 61 , 127 ,0 }; - static ulong[] dim36KuoInit = { 1 , 3 , 1 , 9 , 1 , 57 , 93 ,0 }; - static ulong[] dim37KuoInit = { 1 , 1 , 1 , 1 , 31 , 31 , 25 , 231 ,0 }; - static ulong[] dim38KuoInit = { 1 , 3 , 7 , 7 , 29 , 17 , 59 , 215 ,0 }; - static ulong[] dim39KuoInit = { 1 , 1 , 3 , 15 , 5 , 63 , 117 , 217 ,0 }; - static ulong[] dim40KuoInit = { 1 , 3 , 1 , 1 , 29 , 5 , 111 , 51 ,0 }; - static ulong[] dim41KuoInit = { 1 , 1 , 7 , 1 , 17 , 37 , 11 , 53 ,0 }; - static ulong[] dim42KuoInit = { 1 , 3 , 7 , 15 , 29 , 5 , 3 , 67 ,0 }; - static ulong[] dim43KuoInit = { 1 , 3 , 7 , 11 , 23 , 27 , 35 , 143 ,0 }; - static ulong[] dim44KuoInit = { 1 , 1 , 5 , 11 , 11 , 33 , 103 , 179 ,0 }; - static ulong[] dim45KuoInit = { 1 , 3 , 5 , 7 , 13 , 45 , 87 , 143 ,0 }; - static ulong[] dim46KuoInit = { 1 , 3 , 1 , 13 , 17 , 17 , 49 , 249 ,0 }; - static ulong[] dim47KuoInit = { 1 , 1 , 1 , 3 , 17 , 29 , 75 , 143 ,0 }; - static ulong[] dim48KuoInit = { 1 , 1 , 1 , 3 , 19 , 55 , 65 , 109 ,0 }; - static ulong[] dim49KuoInit = { 1 , 1 , 7 , 3 , 21 , 29 , 13 , 191 ,0 }; - static ulong[] dim50KuoInit = { 1 , 1 , 3 , 7 , 7 , 5 , 97 , 179 ,0 }; - static ulong[] dim51KuoInit = { 1 , 3 , 5 , 13 , 1 , 17 , 113 , 149 ,0 }; - static ulong[] dim52KuoInit = { 1 , 3 , 3 , 11 , 25 , 13 , 105 , 75 ,0 }; - static ulong[] dim53KuoInit = { 1 , 3 , 1 , 13 , 29 , 33 , 71 , 117 , 77 ,0 }; - static ulong[] dim54KuoInit = { 1 , 1 , 1 , 1 , 31 , 41 , 9 , 245 , 205 ,0 }; - static ulong[] dim55KuoInit = { 1 , 1 , 1 , 15 , 25 , 23 , 111 , 105 , 95 ,0 }; - static ulong[] dim56KuoInit = { 1 , 1 , 3 , 5 , 3 , 5 , 81 , 251 , 221 ,0 }; - static ulong[] dim57KuoInit = { 1 , 3 , 5 , 5 , 9 , 53 , 37 , 41 , 509 ,0 }; - static ulong[] dim58KuoInit = { 1 , 1 , 5 , 15 , 21 , 25 , 77 , 225 , 333 ,0 }; - static ulong[] dim59KuoInit = { 1 , 3 , 5 , 13 , 3 , 17 , 1 , 101 , 397 ,0 }; - static ulong[] dim60KuoInit = { 1 , 3 , 5 , 11 , 27 , 53 , 115 , 87 , 47 ,0 }; - static ulong[] dim61KuoInit = { 1 , 1 , 3 , 11 , 31 , 39 , 21 , 233 , 9 ,0 }; - static ulong[] dim62KuoInit = { 1 , 1 , 3 , 15 , 17 , 19 , 73 , 147 , 351 ,0 }; - static ulong[] dim63KuoInit = { 1 , 1 , 3 , 3 , 29 , 17 , 1 , 105 , 293 ,0 }; - static ulong[] dim64KuoInit = { 1 , 1 , 3 , 15 , 9 , 21 , 103 , 239 , 433 ,0 }; - static ulong[] dim65KuoInit = { 1 , 1 , 1 , 15 , 17 , 35 , 49 , 7 , 435 ,0 }; - static ulong[] dim66KuoInit = { 1 , 3 , 7 , 3 , 9 , 51 , 91 , 177 , 255 ,0 }; - static ulong[] dim67KuoInit = { 1 , 1 , 5 , 5 , 31 , 9 , 39 , 209 , 511 ,0 }; - static ulong[] dim68KuoInit = { 1 , 1 , 7 , 3 , 11 , 11 , 19 , 227 , 343 ,0 }; - static ulong[] dim69KuoInit = { 1 , 3 , 7 , 3 , 17 , 13 , 105 , 151 , 225 ,0 }; - static ulong[] dim70KuoInit = { 1 , 1 , 7 , 11 , 29 , 35 , 105 , 11 , 497 ,0 }; - static ulong[] dim71KuoInit = { 1 , 3 , 7 , 15 , 5 , 13 , 31 , 201 , 63 ,0 }; - static ulong[] dim72KuoInit = { 1 , 1 , 5 , 7 , 17 , 31 , 9 , 63 , 167 ,0 }; - static ulong[] dim73KuoInit = { 1 , 1 , 1 , 13 , 1 , 51 , 9 , 115 , 217 ,0 }; - static ulong[] dim74KuoInit = { 1 , 1 , 7 , 15 , 23 , 49 , 125 , 163 , 39 ,0 }; - static ulong[] dim75KuoInit = { 1 , 1 , 3 , 13 , 11 , 45 , 77 , 149 , 173 ,0 }; - static ulong[] dim76KuoInit = { 1 , 3 , 3 , 3 , 7 , 27 , 43 , 27 , 361 ,0 }; - static ulong[] dim77KuoInit = { 1 , 3 , 3 , 5 , 5 , 37 , 9 , 51 , 149 ,0 }; - static ulong[] dim78KuoInit = { 1 , 1 , 1 , 15 , 13 , 13 , 49 , 251 , 385 ,0 }; - static ulong[] dim79KuoInit = { 1 , 1 , 3 , 7 , 1 , 57 , 27 , 25 , 335 ,0 }; - static ulong[] dim80KuoInit = { 1 , 3 , 3 , 9 , 31 , 55 , 41 , 143 , 97 ,0 }; - static ulong[] dim81KuoInit = { 1 , 3 , 3 , 11 , 31 , 33 , 65 , 57 , 113 ,0 }; - static ulong[] dim82KuoInit = { 1 , 1 , 5 , 13 , 19 , 63 , 5 , 71 , 317 ,0 }; - static ulong[] dim83KuoInit = { 1 , 1 , 1 , 5 , 29 , 45 , 35 , 107 , 113 ,0 }; - static ulong[] dim84KuoInit = { 1 , 1 , 3 , 7 , 3 , 31 , 81 , 57 , 439 ,0 }; - static ulong[] dim85KuoInit = { 1 , 3 , 5 , 5 , 1 , 7 , 3 , 21 , 319 ,0 }; - static ulong[] dim86KuoInit = { 1 , 3 , 1 , 15 , 27 , 49 , 25 , 247 , 455 ,0 }; - static ulong[] dim87KuoInit = { 1 , 1 , 3 , 5 , 5 , 43 , 105 , 207 , 271 ,0 }; - static ulong[] dim88KuoInit = { 1 , 3 , 3 , 7 , 29 , 63 , 25 , 239 , 165 ,0 }; - static ulong[] dim89KuoInit = { 1 , 3 , 7 , 1 , 19 , 23 , 87 , 23 , 161 ,0 }; - static ulong[] dim90KuoInit = { 1 , 3 , 7 , 5 , 27 , 1 , 15 , 113 , 85 ,0 }; - static ulong[] dim91KuoInit = { 1 , 1 , 1 , 13 , 23 , 39 , 103 , 59 , 105 ,0 }; - static ulong[] dim92KuoInit = { 1 , 3 , 1 , 15 , 9 , 35 , 65 , 225 , 385 ,0 }; - static ulong[] dim93KuoInit = { 1 , 1 , 5 , 9 , 5 , 63 , 109 , 153 , 25 ,0 }; - static ulong[] dim94KuoInit = { 1 , 3 , 7 , 11 , 5 , 41 , 103 , 103 , 245 ,0 }; - static ulong[] dim95KuoInit = { 1 , 1 , 1 , 3 , 25 , 5 , 71 , 203 , 351 ,0 }; - static ulong[] dim96KuoInit = { 1 , 1 , 5 , 5 , 27 , 49 , 111 , 253 , 265 ,0 }; - static ulong[] dim97KuoInit = { 1 , 1 , 1 , 11 , 31 , 63 , 91 , 179 , 359 ,0 }; - static ulong[] dim98KuoInit = { 1 , 3 , 7 , 1 , 9 , 41 , 117 , 69 , 141 ,0 }; - static ulong[] dim99KuoInit = { 1 , 3 , 1 , 5 , 11 , 25 , 7 , 73 , 477 ,0 }; - static ulong[] dim100KuoInit = { 1 , 1 , 3 , 1 , 31 , 7 , 51 , 67 , 97 ,0 }; - static ulong[] dim101KuoInit = { 1 , 3 , 3 , 15 , 31 , 61 , 27 , 137 , 319 , 605 ,0 }; - static ulong[] dim102KuoInit = { 1 , 3 , 5 , 7 , 29 , 45 , 31 , 211 , 287 , 13 ,0 }; - static ulong[] dim103KuoInit = { 1 , 3 , 1 , 7 , 25 , 61 , 121 , 91 , 215 , 439 ,0 }; - static ulong[] dim104KuoInit = { 1 , 1 , 3 , 11 , 31 , 51 , 31 , 151 , 421 , 195 ,0 }; - static ulong[] dim105KuoInit = { 1 , 1 , 5 , 13 , 17 , 23 , 47 , 9 , 33 , 1003 ,0 }; - static ulong[] dim106KuoInit = { 1 , 1 , 1 , 3 , 23 , 5 , 109 , 23 , 125 , 773 ,0 }; - static ulong[] dim107KuoInit = { 1 , 3 , 5 , 9 , 7 , 41 , 33 , 81 , 277 , 623 ,0 }; - static ulong[] dim108KuoInit = { 1 , 1 , 1 , 11 , 9 , 33 , 51 , 31 , 181 , 985 ,0 }; - static ulong[] dim109KuoInit = { 1 , 1 , 7 , 11 , 3 , 37 , 3 , 107 , 405 , 639 ,0 }; - static ulong[] dim110KuoInit = { 1 , 1 , 5 , 15 , 17 , 7 , 35 , 221 , 255 , 753 ,0 }; - static ulong[] dim111KuoInit = { 1 , 1 , 7 , 3 , 31 , 11 , 113 , 105 , 275 , 683 ,0 }; - static ulong[] dim112KuoInit = { 1 , 1 , 3 , 11 , 3 , 39 , 57 , 237 , 189 , 561 ,0 }; - static ulong[] dim113KuoInit = { 1 , 3 , 3 , 7 , 17 , 37 , 55 , 97 , 499 , 511 ,0 }; - static ulong[] dim114KuoInit = { 1 , 1 , 7 , 11 , 31 , 27 , 21 , 241 , 127 , 279 ,0 }; - static ulong[] dim115KuoInit = { 1 , 3 , 1 , 7 , 1 , 19 , 95 , 3 , 511 , 143 ,0 }; - static ulong[] dim116KuoInit = { 1 , 3 , 5 , 3 , 21 , 39 , 115 , 155 , 67 , 607 ,0 }; - static ulong[] dim117KuoInit = { 1 , 1 , 7 , 7 , 25 , 37 , 33 , 149 , 89 , 997 ,0 }; - static ulong[] dim118KuoInit = { 1 , 3 , 1 , 7 , 3 , 7 , 113 , 165 , 235 , 943 ,0 }; - static ulong[] dim119KuoInit = { 1 , 3 , 7 , 9 , 29 , 5 , 93 , 255 , 323 , 555 ,0 }; - static ulong[] dim120KuoInit = { 1 , 1 , 1 , 3 , 13 , 45 , 89 , 87 , 29 , 23 ,0 }; - static ulong[] dim121KuoInit = { 1 , 3 , 3 , 11 , 11 , 29 , 75 , 91 , 211 , 459 ,0 }; - static ulong[] dim122KuoInit = { 1 , 3 , 5 , 15 , 11 , 43 , 105 , 1 , 227 , 711 ,0 }; - static ulong[] dim123KuoInit = { 1 , 1 , 5 , 5 , 13 , 33 , 29 , 217 , 511 , 241 ,0 }; - static ulong[] dim124KuoInit = { 1 , 3 , 7 , 9 , 1 , 47 , 125 , 151 , 375 , 815 ,0 }; - static ulong[] dim125KuoInit = { 1 , 1 , 1 , 3 , 25 , 29 , 5 , 39 , 133 , 585 ,0 }; - static ulong[] dim126KuoInit = { 1 , 1 , 5 , 9 , 9 , 31 , 79 , 227 , 395 , 517 ,0 }; - static ulong[] dim127KuoInit = { 1 , 3 , 3 , 3 , 15 , 3 , 47 , 159 , 233 , 339 ,0 }; - static ulong[] dim128KuoInit = { 1 , 3 , 5 , 3 , 15 , 13 , 79 , 109 , 187 , 249 ,0 }; - static ulong[] dim129KuoInit = { 1 , 3 , 1 , 15 , 23 , 39 , 85 , 157 , 323 , 535 ,0 }; - static ulong[] dim130KuoInit = { 1 , 1 , 1 , 5 , 11 , 25 , 5 , 153 , 19 , 779 ,0 }; - static ulong[] dim131KuoInit = { 1 , 3 , 5 , 1 , 9 , 43 , 27 , 179 , 407 , 167 ,0 }; - static ulong[] dim132KuoInit = { 1 , 3 , 5 , 5 , 25 , 47 , 21 , 23 , 57 , 415 ,0 }; - static ulong[] dim133KuoInit = { 1 , 1 , 1 , 7 , 3 , 29 , 45 , 195 , 349 , 267 ,0 }; - static ulong[] dim134KuoInit = { 1 , 3 , 5 , 3 , 19 , 13 , 61 , 243 , 125 , 961 ,0 }; - static ulong[] dim135KuoInit = { 1 , 3 , 7 , 3 , 29 , 49 , 7 , 197 , 387 , 747 ,0 }; - static ulong[] dim136KuoInit = { 1 , 3 , 7 , 11 , 31 , 31 , 109 , 87 , 345 , 807 ,0 }; - static ulong[] dim137KuoInit = { 1 , 3 , 1 , 3 , 21 , 57 , 43 , 207 , 221 , 85 ,0 }; - static ulong[] dim138KuoInit = { 1 , 1 , 3 , 13 , 19 , 19 , 41 , 19 , 509 , 419 ,0 }; - static ulong[] dim139KuoInit = { 1 , 1 , 3 , 3 , 23 , 17 , 85 , 99 , 421 , 875 ,0 }; - static ulong[] dim140KuoInit = { 1 , 3 , 1 , 15 , 27 , 43 , 89 , 151 , 39 , 643 ,0 }; - static ulong[] dim141KuoInit = { 1 , 1 , 1 , 5 , 3 , 59 , 25 , 79 , 319 , 959 ,0 }; - static ulong[] dim142KuoInit = { 1 , 3 , 5 , 9 , 3 , 27 , 71 , 209 , 195 , 569 ,0 }; - static ulong[] dim143KuoInit = { 1 , 3 , 3 , 3 , 11 , 47 , 67 , 1 , 221 , 119 ,0 }; - static ulong[] dim144KuoInit = { 1 , 1 , 5 , 11 , 11 , 39 , 95 , 29 , 7 , 957 ,0 }; - static ulong[] dim145KuoInit = { 1 , 1 , 7 , 13 , 13 , 57 , 47 , 71 , 165 , 393 ,0 }; - static ulong[] dim146KuoInit = { 1 , 3 , 5 , 3 , 5 , 47 , 127 , 209 , 377 , 53 ,0 }; - static ulong[] dim147KuoInit = { 1 , 3 , 1 , 5 , 13 , 51 , 69 , 165 , 477 , 961 ,0 }; - static ulong[] dim148KuoInit = { 1 , 3 , 5 , 9 , 25 , 37 , 5 , 133 , 117 , 29 ,0 }; - static ulong[] dim149KuoInit = { 1 , 1 , 1 , 9 , 7 , 21 , 95 , 53 , 205 , 805 ,0 }; - static ulong[] dim150KuoInit = { 1 , 1 , 5 , 11 , 25 , 39 , 25 , 15 , 497 , 525 ,0 }; - static ulong[] dim151KuoInit = { 1 , 3 , 5 , 5 , 15 , 37 , 33 , 255 , 97 , 341 ,0 }; - static ulong[] dim152KuoInit = { 1 , 3 , 1 , 13 , 31 , 63 , 35 , 203 , 415 , 903 ,0 }; - static ulong[] dim153KuoInit = { 1 , 1 , 5 , 7 , 13 , 59 , 55 , 17 , 103 , 221 ,0 }; - static ulong[] dim154KuoInit = { 1 , 1 , 5 , 3 , 7 , 37 , 113 , 139 , 269 , 987 ,0 }; - static ulong[] dim155KuoInit = { 1 , 3 , 3 , 7 , 21 , 3 , 47 , 175 , 327 , 633 ,0 }; - static ulong[] dim156KuoInit = { 1 , 1 , 1 , 3 , 13 , 61 , 19 , 209 , 39 , 695 ,0 }; - static ulong[] dim157KuoInit = { 1 , 1 , 1 , 9 , 31 , 61 , 21 , 75 , 445 , 647 ,0 }; - static ulong[] dim158KuoInit = { 1 , 1 , 5 , 3 , 21 , 1 , 65 , 211 , 405 , 629 ,0 }; - static ulong[] dim159KuoInit = { 1 , 3 , 7 , 15 , 9 , 25 , 119 , 13 , 465 , 865 ,0 }; - static ulong[] dim160KuoInit = { 1 , 3 , 1 , 15 , 29 , 19 , 103 , 39 , 37 , 289 ,0 }; - static ulong[] dim161KuoInit = { 1 , 1 , 1 , 5 , 25 , 23 , 21 , 111 , 455 , 665 , 1609 ,0 }; - static ulong[] dim162KuoInit = { 1 , 3 , 3 , 13 , 27 , 29 , 45 , 191 , 385 , 413 , 1875 ,0 }; - static ulong[] dim163KuoInit = { 1 , 3 , 7 , 7 , 19 , 17 , 47 , 231 , 337 , 781 , 1235 ,0 }; - static ulong[] dim164KuoInit = { 1 , 1 , 5 , 7 , 7 , 25 , 99 , 239 , 501 , 29 , 159 ,0 }; - static ulong[] dim165KuoInit = { 1 , 1 , 1 , 3 , 5 , 19 , 101 , 147 , 225 , 353 , 1117 ,0 }; - static ulong[] dim166KuoInit = { 1 , 3 , 7 , 11 , 17 , 57 , 45 , 73 , 219 , 853 , 1379 ,0 }; - static ulong[] dim167KuoInit = { 1 , 3 , 3 , 7 , 11 , 47 , 23 , 67 , 157 , 283 , 867 ,0 }; - static ulong[] dim168KuoInit = { 1 , 1 , 7 , 7 , 23 , 55 , 71 , 155 , 237 , 927 , 929 ,0 }; - static ulong[] dim169KuoInit = { 1 , 3 , 3 , 15 , 11 , 19 , 59 , 147 , 373 , 619 , 53 ,0 }; - static ulong[] dim170KuoInit = { 1 , 1 , 3 , 15 , 13 , 23 , 11 , 33 , 45 , 121 , 241 ,0 }; - static ulong[] dim171KuoInit = { 1 , 1 , 1 , 9 , 13 , 29 , 3 , 131 , 373 , 91 , 1207 ,0 }; - static ulong[] dim172KuoInit = { 1 , 1 , 1 , 15 , 21 , 29 , 59 , 197 , 375 , 637 , 1275 ,0 }; - static ulong[] dim173KuoInit = { 1 , 1 , 3 , 11 , 27 , 31 , 87 , 95 , 119 , 249 , 1913 ,0 }; - static ulong[] dim174KuoInit = { 1 , 3 , 1 , 5 , 25 , 51 , 1 , 241 , 53 , 883 , 61 ,0 }; - static ulong[] dim175KuoInit = { 1 , 3 , 1 , 5 , 23 , 37 , 83 , 45 , 287 , 911 , 717 ,0 }; - static ulong[] dim176KuoInit = { 1 , 3 , 1 , 3 , 9 , 39 , 105 , 129 , 475 , 399 , 1783 ,0 }; - static ulong[] dim177KuoInit = { 1 , 3 , 5 , 5 , 23 , 11 , 119 , 205 , 317 , 797 , 605 ,0 }; - static ulong[] dim178KuoInit = { 1 , 1 , 7 , 5 , 13 , 57 , 19 , 225 , 53 , 987 , 1463 ,0 }; - static ulong[] dim179KuoInit = { 1 , 3 , 5 , 11 , 3 , 59 , 1 , 201 , 97 , 1011 , 1059 ,0 }; - static ulong[] dim180KuoInit = { 1 , 3 , 3 , 9 , 29 , 51 , 39 , 199 , 243 , 877 , 883 ,0 }; - static ulong[] dim181KuoInit = { 1 , 1 , 3 , 5 , 29 , 13 , 97 , 15 , 387 , 435 , 701 ,0 }; - static ulong[] dim182KuoInit = { 1 , 3 , 3 , 11 , 21 , 41 , 3 , 119 , 385 , 503 , 2015 ,0 }; - static ulong[] dim183KuoInit = { 1 , 3 , 3 , 1 , 17 , 9 , 49 , 13 , 309 , 29 , 1501 ,0 }; - static ulong[] dim184KuoInit = { 1 , 3 , 1 , 3 , 13 , 29 , 91 , 51 , 225 , 989 , 1701 ,0 }; - static ulong[] dim185KuoInit = { 1 , 1 , 7 , 13 , 1 , 55 , 59 , 243 , 399 , 65 , 1725 ,0 }; - static ulong[] dim186KuoInit = { 1 , 3 , 7 , 7 , 19 , 29 , 97 , 161 , 195 , 257 , 1595 ,0 }; - static ulong[] dim187KuoInit = { 1 , 3 , 7 , 15 , 29 , 49 , 49 , 23 , 157 , 363 , 1355 ,0 }; - static ulong[] dim188KuoInit = { 1 , 3 , 1 , 13 , 23 , 39 , 45 , 73 , 147 , 323 , 1965 ,0 }; - static ulong[] dim189KuoInit = { 1 , 3 , 1 , 15 , 17 , 27 , 17 , 19 , 371 , 387 , 395 ,0 }; - static ulong[] dim190KuoInit = { 1 , 1 , 1 , 9 , 19 , 39 , 31 , 3 , 291 , 379 , 605 ,0 }; - static ulong[] dim191KuoInit = { 1 , 1 , 7 , 1 , 15 , 17 , 47 , 133 , 485 , 145 , 629 ,0 }; - static ulong[] dim192KuoInit = { 1 , 1 , 1 , 13 , 11 , 11 , 117 , 233 , 85 , 1 , 1357 ,0 }; - static ulong[] dim193KuoInit = { 1 , 1 , 7 , 15 , 19 , 51 , 115 , 19 , 333 , 683 , 917 ,0 }; - static ulong[] dim194KuoInit = { 1 , 3 , 7 , 9 , 27 , 47 , 17 , 209 , 461 , 261 , 761 ,0 }; - static ulong[] dim195KuoInit = { 1 , 1 , 3 , 1 , 27 , 15 , 43 , 141 , 291 , 363 , 605 ,0 }; - static ulong[] dim196KuoInit = { 1 , 3 , 7 , 5 , 1 , 3 , 43 , 75 , 115 , 653 , 847 ,0 }; - static ulong[] dim197KuoInit = { 1 , 1 , 3 , 1 , 11 , 51 , 69 , 119 , 195 , 979 , 1543 ,0 }; - static ulong[] dim198KuoInit = { 1 , 1 , 7 , 3 , 11 , 29 , 29 , 59 , 339 , 273 , 855 ,0 }; - static ulong[] dim199KuoInit = { 1 , 1 , 1 , 1 , 11 , 15 , 59 , 97 , 267 , 647 , 2037 ,0 }; - static ulong[] dim200KuoInit = { 1 , 1 , 5 , 3 , 25 , 43 , 41 , 195 , 457 , 155 , 1707 ,0 }; - static ulong[] dim201KuoInit = { 1 , 3 , 3 , 15 , 11 , 47 , 43 , 15 , 505 , 761 , 1259 ,0 }; - static ulong[] dim202KuoInit = { 1 , 3 , 5 , 15 , 27 , 29 , 55 , 109 , 187 , 545 , 1177 ,0 }; - static ulong[] dim203KuoInit = { 1 , 3 , 1 , 5 , 29 , 25 , 89 , 11 , 75 , 771 , 1437 ,0 }; - static ulong[] dim204KuoInit = { 1 , 3 , 5 , 11 , 19 , 17 , 27 , 59 , 231 , 35 , 391 ,0 }; - static ulong[] dim205KuoInit = { 1 , 1 , 7 , 9 , 3 , 17 , 31 , 81 , 317 , 973 , 1913 ,0 }; - static ulong[] dim206KuoInit = { 1 , 1 , 1 , 7 , 3 , 21 , 113 , 41 , 335 , 789 , 1195 ,0 }; - static ulong[] dim207KuoInit = { 1 , 1 , 7 , 1 , 13 , 61 , 41 , 117 , 301 , 707 , 693 ,0 }; - static ulong[] dim208KuoInit = { 1 , 1 , 1 , 7 , 3 , 1 , 79 , 145 , 137 , 307 , 205 ,0 }; - static ulong[] dim209KuoInit = { 1 , 3 , 7 , 1 , 27 , 49 , 83 , 127 , 265 , 669 , 87 ,0 }; - static ulong[] dim210KuoInit = { 1 , 1 , 3 , 15 , 21 , 31 , 115 , 115 , 343 , 55 , 1049 ,0 }; - static ulong[] dim211KuoInit = { 1 , 1 , 5 , 9 , 7 , 25 , 43 , 255 , 363 , 123 , 299 ,0 }; - static ulong[] dim212KuoInit = { 1 , 3 , 5 , 13 , 1 , 9 , 79 , 245 , 91 , 233 , 1703 ,0 }; - static ulong[] dim213KuoInit = { 1 , 3 , 5 , 1 , 17 , 39 , 81 , 147 , 147 , 335 , 819 ,0 }; - static ulong[] dim214KuoInit = { 1 , 3 , 7 , 3 , 31 , 63 , 55 , 53 , 389 , 307 , 451 ,0 }; - static ulong[] dim215KuoInit = { 1 , 1 , 7 , 7 , 23 , 41 , 125 , 147 , 323 , 7 , 1211 ,0 }; - static ulong[] dim216KuoInit = { 1 , 1 , 1 , 13 , 23 , 9 , 35 , 177 , 165 , 315 , 1885 ,0 }; - static ulong[] dim217KuoInit = { 1 , 3 , 3 , 7 , 11 , 39 , 99 , 197 , 405 , 377 , 555 ,0 }; - static ulong[] dim218KuoInit = { 1 , 3 , 3 , 11 , 15 , 39 , 125 , 59 , 323 , 377 , 325 ,0 }; - static ulong[] dim219KuoInit = { 1 , 3 , 5 , 9 , 7 , 45 , 75 , 143 , 265 , 161 , 1701 ,0 }; - static ulong[] dim220KuoInit = { 1 , 1 , 7 , 5 , 31 , 21 , 35 , 1 , 511 , 585 , 923 ,0 }; - static ulong[] dim221KuoInit = { 1 , 3 , 1 , 5 , 3 , 31 , 65 , 33 , 199 , 205 , 1673 ,0 }; - static ulong[] dim222KuoInit = { 1 , 3 , 7 , 9 , 17 , 61 , 123 , 33 , 405 , 235 , 645 ,0 }; - static ulong[] dim223KuoInit = { 1 , 3 , 3 , 15 , 27 , 1 , 35 , 165 , 509 , 681 , 621 ,0 }; - static ulong[] dim224KuoInit = { 1 , 3 , 5 , 15 , 19 , 13 , 49 , 85 , 5 , 661 , 805 ,0 }; - static ulong[] dim225KuoInit = { 1 , 3 , 7 , 3 , 3 , 51 , 77 , 167 , 461 , 731 , 1681 ,0 }; - static ulong[] dim226KuoInit = { 1 , 1 , 3 , 5 , 21 , 51 , 125 , 65 , 41 , 613 , 1009 ,0 }; - static ulong[] dim227KuoInit = { 1 , 3 , 7 , 11 , 17 , 39 , 127 , 31 , 423 , 87 , 1413 ,0 }; - static ulong[] dim228KuoInit = { 1 , 3 , 1 , 5 , 11 , 41 , 25 , 49 , 169 , 637 , 1599 ,0 }; - static ulong[] dim229KuoInit = { 1 , 3 , 5 , 13 , 31 , 27 , 75 , 65 , 391 , 857 , 1491 ,0 }; - static ulong[] dim230KuoInit = { 1 , 1 , 1 , 13 , 5 , 61 , 65 , 183 , 373 , 161 , 235 ,0 }; - static ulong[] dim231KuoInit = { 1 , 3 , 1 , 1 , 27 , 49 , 47 , 55 , 503 , 683 , 301 ,0 }; - static ulong[] dim232KuoInit = { 1 , 1 , 7 , 11 , 17 , 31 , 113 , 255 , 281 , 341 , 2033 ,0 }; - static ulong[] dim233KuoInit = { 1 , 3 , 3 , 13 , 27 , 27 , 27 , 225 , 161 , 187 , 485 ,0 }; - static ulong[] dim234KuoInit = { 1 , 1 , 1 , 3 , 21 , 27 , 105 , 215 , 241 , 211 , 899 ,0 }; - static ulong[] dim235KuoInit = { 1 , 3 , 5 , 5 , 11 , 37 , 1 , 7 , 335 , 221 , 757 ,0 }; - static ulong[] dim236KuoInit = { 1 , 1 , 5 , 7 , 21 , 55 , 61 , 99 , 23 , 957 , 35 ,0 }; - static ulong[] dim237KuoInit = { 1 , 3 , 5 , 5 , 13 , 53 , 31 , 121 , 111 , 47 , 1491 ,0 }; - static ulong[] dim238KuoInit = { 1 , 1 , 5 , 13 , 17 , 5 , 11 , 179 , 357 , 1003 , 1179 ,0 }; - static ulong[] dim239KuoInit = { 1 , 1 , 5 , 13 , 29 , 9 , 3 , 91 , 471 , 369 , 323 ,0 }; - static ulong[] dim240KuoInit = { 1 , 3 , 7 , 5 , 7 , 25 , 109 , 43 , 133 , 261 , 1623 ,0 }; - static ulong[] dim241KuoInit = { 1 , 3 , 7 , 15 , 13 , 33 , 125 , 81 , 491 , 331 , 1243 ,0 }; - static ulong[] dim242KuoInit = { 1 , 3 , 3 , 11 , 15 , 21 , 57 , 63 , 55 , 341 , 1717 ,0 }; - static ulong[] dim243KuoInit = { 1 , 3 , 1 , 1 , 31 , 13 , 67 , 89 , 459 , 879 , 863 ,0 }; - static ulong[] dim244KuoInit = { 1 , 3 , 7 , 15 , 7 , 21 , 117 , 229 , 467 , 227 , 1463 ,0 }; - static ulong[] dim245KuoInit = { 1 , 1 , 1 , 7 , 23 , 43 , 53 , 79 , 3 , 905 , 1049 ,0 }; - static ulong[] dim246KuoInit = { 1 , 3 , 7 , 1 , 19 , 1 , 61 , 15 , 377 , 579 , 145 ,0 }; - static ulong[] dim247KuoInit = { 1 , 3 , 1 , 15 , 27 , 25 , 61 , 171 , 425 , 631 , 1343 ,0 }; - static ulong[] dim248KuoInit = { 1 , 3 , 7 , 5 , 15 , 31 , 69 , 5 , 217 , 809 , 647 ,0 }; - static ulong[] dim249KuoInit = { 1 , 1 , 5 , 3 , 5 , 35 , 101 , 21 , 33 , 757 , 559 ,0 }; - static ulong[] dim250KuoInit = { 1 , 3 , 5 , 13 , 3 , 7 , 101 , 93 , 31 , 315 , 1897 ,0 }; - static ulong[] dim251KuoInit = { 1 , 1 , 3 , 1 , 21 , 31 , 37 , 127 , 211 , 429 , 1019 ,0 }; - static ulong[] dim252KuoInit = { 1 , 1 , 3 , 9 , 11 , 27 , 113 , 203 , 115 , 765 , 759 ,0 }; - static ulong[] dim253KuoInit = { 1 , 1 , 3 , 13 , 7 , 21 , 89 , 99 , 469 , 729 , 683 ,0 }; - static ulong[] dim254KuoInit = { 1 , 1 , 1 , 5 , 27 , 17 , 43 , 177 , 225 , 405 , 1929 ,0 }; - static ulong[] dim255KuoInit = { 1 , 3 , 1 , 7 , 21 , 55 , 69 , 41 , 309 , 487 , 681 ,0 }; - static ulong[] dim256KuoInit = { 1 , 3 , 5 , 11 , 19 , 21 , 61 , 163 , 337 , 61 , 301 ,0 }; - static ulong[] dim257KuoInit = { 1 , 3 , 1 , 7 , 21 , 61 , 67 , 219 , 281 , 21 , 1271 ,0 }; - static ulong[] dim258KuoInit = { 1 , 1 , 5 , 11 , 5 , 25 , 51 , 207 , 235 , 289 , 395 ,0 }; - static ulong[] dim259KuoInit = { 1 , 1 , 3 , 3 , 17 , 61 , 5 , 179 , 457 , 941 , 1577 ,0 }; - static ulong[] dim260KuoInit = { 1 , 1 , 7 , 7 , 17 , 23 , 127 , 35 , 407 , 545 , 169 ,0 }; - static ulong[] dim261KuoInit = { 1 , 3 , 7 , 15 , 21 , 19 , 123 , 145 , 97 , 263 , 1881 ,0 }; - static ulong[] dim262KuoInit = { 1 , 3 , 7 , 11 , 25 , 49 , 117 , 165 , 79 , 137 , 1311 ,0 }; - static ulong[] dim263KuoInit = { 1 , 3 , 1 , 11 , 3 , 17 , 9 , 177 , 367 , 863 , 1255 ,0 }; - static ulong[] dim264KuoInit = { 1 , 1 , 5 , 13 , 9 , 1 , 31 , 3 , 69 , 1009 , 1091 ,0 }; - static ulong[] dim265KuoInit = { 1 , 3 , 7 , 15 , 25 , 41 , 13 , 3 , 319 , 131 , 493 ,0 }; - static ulong[] dim266KuoInit = { 1 , 1 , 1 , 15 , 9 , 45 , 25 , 21 , 405 , 61 , 1167 ,0 }; - static ulong[] dim267KuoInit = { 1 , 1 , 1 , 1 , 31 , 3 , 95 , 113 , 475 , 209 , 1473 ,0 }; - static ulong[] dim268KuoInit = { 1 , 1 , 5 , 5 , 27 , 9 , 95 , 121 , 193 , 481 , 1785 ,0 }; - static ulong[] dim269KuoInit = { 1 , 1 , 3 , 13 , 1 , 13 , 57 , 167 , 273 , 491 , 867 ,0 }; - static ulong[] dim270KuoInit = { 1 , 1 , 7 , 1 , 9 , 27 , 123 , 65 , 407 , 609 , 1979 ,0 }; - static ulong[] dim271KuoInit = { 1 , 3 , 1 , 15 , 5 , 5 , 89 , 17 , 207 , 249 , 1725 ,0 }; - static ulong[] dim272KuoInit = { 1 , 3 , 5 , 11 , 11 , 15 , 91 , 33 , 113 , 531 , 831 ,0 }; - static ulong[] dim273KuoInit = { 1 , 1 , 5 , 9 , 27 , 51 , 17 , 141 , 215 , 171 , 455 ,0 }; - static ulong[] dim274KuoInit = { 1 , 1 , 5 , 9 , 11 , 25 , 115 , 5 , 173 , 209 , 1455 ,0 }; - static ulong[] dim275KuoInit = { 1 , 1 , 7 , 7 , 13 , 51 , 21 , 79 , 357 , 423 , 1855 ,0 }; - static ulong[] dim276KuoInit = { 1 , 1 , 7 , 1 , 13 , 37 , 123 , 27 , 477 , 1023 , 1235 ,0 }; - static ulong[] dim277KuoInit = { 1 , 1 , 7 , 13 , 25 , 43 , 123 , 41 , 199 , 779 , 1691 ,0 }; - static ulong[] dim278KuoInit = { 1 , 3 , 3 , 9 , 7 , 27 , 81 , 147 , 465 , 135 , 829 ,0 }; - static ulong[] dim279KuoInit = { 1 , 1 , 7 , 11 , 17 , 5 , 25 , 177 , 377 , 629 , 915 ,0 }; - static ulong[] dim280KuoInit = { 1 , 1 , 3 , 15 , 11 , 19 , 45 , 229 , 409 , 187 , 507 ,0 }; - static ulong[] dim281KuoInit = { 1 , 1 , 7 , 5 , 7 , 49 , 21 , 49 , 395 , 185 , 391 ,0 }; - static ulong[] dim282KuoInit = { 1 , 3 , 1 , 1 , 1 , 37 , 123 , 255 , 223 , 473 , 1011 ,0 }; - static ulong[] dim283KuoInit = { 1 , 3 , 3 , 13 , 3 , 7 , 113 , 183 , 457 , 561 , 1427 ,0 }; - static ulong[] dim284KuoInit = { 1 , 1 , 1 , 11 , 27 , 39 , 125 , 241 , 279 , 905 , 1907 ,0 }; - static ulong[] dim285KuoInit = { 1 , 3 , 1 , 15 , 19 , 19 , 9 , 233 , 39 , 701 , 939 ,0 }; - static ulong[] dim286KuoInit = { 1 , 3 , 5 , 11 , 15 , 51 , 1 , 25 , 461 , 671 , 611 ,0 }; - static ulong[] dim287KuoInit = { 1 , 3 , 1 , 3 , 23 , 39 , 23 , 191 , 219 , 911 , 1247 ,0 }; - static ulong[] dim288KuoInit = { 1 , 3 , 1 , 3 , 1 , 27 , 91 , 97 , 55 , 863 , 805 ,0 }; - static ulong[] dim289KuoInit = { 1 , 3 , 7 , 7 , 5 , 63 , 81 , 33 , 383 , 645 , 841 ,0 }; - static ulong[] dim290KuoInit = { 1 , 3 , 7 , 5 , 27 , 39 , 33 , 25 , 185 , 799 , 1109 ,0 }; - static ulong[] dim291KuoInit = { 1 , 3 , 1 , 11 , 11 , 61 , 109 , 209 , 345 , 465 , 935 ,0 }; - static ulong[] dim292KuoInit = { 1 , 3 , 5 , 13 , 19 , 55 , 117 , 237 , 455 , 953 , 905 ,0 }; - static ulong[] dim293KuoInit = { 1 , 3 , 7 , 9 , 9 , 25 , 77 , 37 , 111 , 357 , 131 ,0 }; - static ulong[] dim294KuoInit = { 1 , 1 , 3 , 13 , 1 , 51 , 27 , 235 , 349 , 517 , 653 ,0 }; - static ulong[] dim295KuoInit = { 1 , 3 , 7 , 3 , 27 , 43 , 23 , 129 , 455 , 431 , 1999 ,0 }; - static ulong[] dim296KuoInit = { 1 , 3 , 7 , 13 , 11 , 3 , 19 , 55 , 261 , 217 , 535 ,0 }; - static ulong[] dim297KuoInit = { 1 , 3 , 7 , 7 , 23 , 53 , 33 , 237 , 73 , 421 , 1439 ,0 }; - static ulong[] dim298KuoInit = { 1 , 1 , 5 , 5 , 19 , 7 , 9 , 201 , 339 , 33 , 2019 ,0 }; - static ulong[] dim299KuoInit = { 1 , 3 , 5 , 7 , 1 , 3 , 9 , 79 , 265 , 125 , 1063 ,0 }; - static ulong[] dim300KuoInit = { 1 , 1 , 7 , 11 , 31 , 61 , 83 , 71 , 93 , 393 , 851 ,0 }; - static ulong[] dim301KuoInit = { 1 , 3 , 1 , 13 , 13 , 45 , 65 , 89 , 87 , 657 , 1635 ,0 }; - static ulong[] dim302KuoInit = { 1 , 3 , 5 , 7 , 21 , 3 , 27 , 251 , 287 , 305 , 1143 ,0 }; - static ulong[] dim303KuoInit = { 1 , 1 , 3 , 13 , 5 , 45 , 35 , 89 , 61 , 347 , 1349 ,0 }; - static ulong[] dim304KuoInit = { 1 , 1 , 7 , 1 , 7 , 61 , 19 , 33 , 11 , 845 , 839 ,0 }; - static ulong[] dim305KuoInit = { 1 , 3 , 5 , 15 , 3 , 1 , 127 , 245 , 423 , 57 , 865 ,0 }; - static ulong[] dim306KuoInit = { 1 , 3 , 5 , 7 , 31 , 33 , 53 , 109 , 397 , 705 , 307 ,0 }; - static ulong[] dim307KuoInit = { 1 , 3 , 7 , 7 , 11 , 51 , 53 , 75 , 325 , 61 , 2035 ,0 }; - static ulong[] dim308KuoInit = { 1 , 3 , 3 , 9 , 23 , 37 , 63 , 115 , 377 , 741 , 1181 ,0 }; - static ulong[] dim309KuoInit = { 1 , 1 , 1 , 13 , 13 , 7 , 77 , 171 , 129 , 615 , 157 ,0 }; - static ulong[] dim310KuoInit = { 1 , 1 , 5 , 5 , 9 , 41 , 59 , 215 , 275 , 969 , 31 ,0 }; - static ulong[] dim311KuoInit = { 1 , 1 , 3 , 1 , 27 , 1 , 33 , 111 , 459 , 503 , 1703 ,0 }; - static ulong[] dim312KuoInit = { 1 , 3 , 3 , 9 , 11 , 41 , 27 , 213 , 67 , 203 , 497 ,0 }; - static ulong[] dim313KuoInit = { 1 , 3 , 3 , 3 , 1 , 35 , 39 , 69 , 457 , 765 , 903 ,0 }; - static ulong[] dim314KuoInit = { 1 , 3 , 5 , 11 , 11 , 31 , 31 , 195 , 481 , 831 , 1727 ,0 }; - static ulong[] dim315KuoInit = { 1 , 3 , 1 , 1 , 9 , 39 , 11 , 179 , 241 , 945 , 439 ,0 }; - static ulong[] dim316KuoInit = { 1 , 1 , 5 , 13 , 1 , 29 , 37 , 113 , 193 , 229 , 1639 ,0 }; - static ulong[] dim317KuoInit = { 1 , 3 , 5 , 7 , 9 , 27 , 75 , 105 , 449 , 631 , 2025 ,0 }; - static ulong[] dim318KuoInit = { 1 , 3 , 7 , 11 , 7 , 9 , 73 , 201 , 273 , 915 , 729 ,0 }; - static ulong[] dim319KuoInit = { 1 , 3 , 3 , 15 , 3 , 41 , 61 , 5 , 475 , 193 , 699 ,0 }; - static ulong[] dim320KuoInit = { 1 , 1 , 3 , 3 , 13 , 57 , 51 , 201 , 313 , 877 , 507 ,0 }; - static ulong[] dim321KuoInit = { 1 , 1 , 7 , 9 , 7 , 3 , 73 , 103 , 113 , 719 , 1747 ,0 }; - static ulong[] dim322KuoInit = { 1 , 1 , 7 , 1 , 1 , 25 , 77 , 249 , 185 , 583 , 123 ,0 }; - static ulong[] dim323KuoInit = { 1 , 1 , 5 , 11 , 25 , 49 , 17 , 45 , 161 , 647 , 1685 ,0 }; - static ulong[] dim324KuoInit = { 1 , 3 , 1 , 15 , 15 , 49 , 35 , 59 , 47 , 523 , 1961 ,0 }; - static ulong[] dim325KuoInit = { 1 , 1 , 5 , 5 , 19 , 11 , 105 , 33 , 333 , 451 , 45 ,0 }; - static ulong[] dim326KuoInit = { 1 , 3 , 1 , 7 , 21 , 1 , 1 , 15 , 465 , 731 , 447 ,0 }; - static ulong[] dim327KuoInit = { 1 , 3 , 5 , 7 , 3 , 9 , 31 , 205 , 479 , 921 , 1705 ,0 }; - static ulong[] dim328KuoInit = { 1 , 1 , 7 , 13 , 7 , 29 , 55 , 1 , 293 , 135 , 1459 ,0 }; - static ulong[] dim329KuoInit = { 1 , 1 , 7 , 5 , 19 , 17 , 7 , 217 , 133 , 959 , 811 ,0 }; - static ulong[] dim330KuoInit = { 1 , 1 , 1 , 15 , 3 , 37 , 55 , 223 , 253 , 535 , 1039 ,0 }; - static ulong[] dim331KuoInit = { 1 , 3 , 7 , 3 , 19 , 47 , 125 , 117 , 473 , 257 , 1215 ,0 }; - static ulong[] dim332KuoInit = { 1 , 1 , 3 , 5 , 5 , 1 , 87 , 95 , 189 , 431 , 1355 ,0 }; - static ulong[] dim333KuoInit = { 1 , 1 , 5 , 11 , 17 , 5 , 63 , 15 , 153 , 325 , 259 ,0 }; - static ulong[] dim334KuoInit = { 1 , 1 , 3 , 11 , 9 , 41 , 101 , 21 , 161 , 653 , 1091 ,0 }; - static ulong[] dim335KuoInit = { 1 , 3 , 3 , 13 , 5 , 19 , 37 , 223 , 469 , 953 , 15 ,0 }; - static ulong[] dim336KuoInit = { 1 , 1 , 1 , 5 , 3 , 33 , 7 , 63 , 111 , 685 , 381 ,0 }; - static ulong[] dim337KuoInit = { 1 , 1 , 3 , 11 , 31 , 27 , 49 , 119 , 277 , 303 , 1719 , 909 ,0 }; - static ulong[] dim338KuoInit = { 1 , 3 , 1 , 11 , 27 , 13 , 9 , 107 , 251 , 759 , 1641 , 2177 ,0 }; - static ulong[] dim339KuoInit = { 1 , 3 , 3 , 3 , 3 , 57 , 33 , 169 , 239 , 357 , 1519 , 997 ,0 }; - static ulong[] dim340KuoInit = { 1 , 3 , 3 , 3 , 11 , 29 , 53 , 109 , 411 , 775 , 1647 , 819 ,0 }; - static ulong[] dim341KuoInit = { 1 , 1 , 5 , 13 , 9 , 3 , 15 , 219 , 483 , 513 , 1319 , 965 ,0 }; - static ulong[] dim342KuoInit = { 1 , 1 , 1 , 5 , 3 , 41 , 9 , 53 , 303 , 349 , 1071 , 681 ,0 }; - static ulong[] dim343KuoInit = { 1 , 3 , 5 , 15 , 27 , 15 , 107 , 211 , 317 , 283 , 1317 , 2661 ,0 }; - static ulong[] dim344KuoInit = { 1 , 3 , 3 , 1 , 13 , 41 , 29 , 17 , 91 , 985 , 327 , 1637 ,0 }; - static ulong[] dim345KuoInit = { 1 , 1 , 3 , 15 , 27 , 3 , 127 , 233 , 177 , 877 , 1467 , 3951 ,0 }; - static ulong[] dim346KuoInit = { 1 , 3 , 1 , 5 , 1 , 51 , 5 , 195 , 501 , 859 , 905 , 3163 ,0 }; - static ulong[] dim347KuoInit = { 1 , 1 , 1 , 5 , 1 , 25 , 5 , 205 , 65 , 435 , 1645 , 4013 ,0 }; - static ulong[] dim348KuoInit = { 1 , 3 , 5 , 13 , 29 , 57 , 101 , 59 , 289 , 701 , 1363 , 961 ,0 }; - static ulong[] dim349KuoInit = { 1 , 3 , 7 , 5 , 1 , 61 , 33 , 117 , 311 , 395 , 1531 , 2491 ,0 }; - static ulong[] dim350KuoInit = { 1 , 1 , 1 , 1 , 5 , 35 , 15 , 59 , 201 , 195 , 1423 , 2195 ,0 }; - static ulong[] dim351KuoInit = { 1 , 1 , 7 , 7 , 13 , 29 , 37 , 109 , 481 , 573 , 1347 , 3335 ,0 }; - static ulong[] dim352KuoInit = { 1 , 1 , 5 , 5 , 25 , 1 , 63 , 53 , 419 , 475 , 1527 , 3327 ,0 }; - static ulong[] dim353KuoInit = { 1 , 1 , 3 , 1 , 27 , 55 , 75 , 225 , 379 , 471 , 211 , 1655 ,0 }; - static ulong[] dim354KuoInit = { 1 , 1 , 7 , 15 , 13 , 61 , 111 , 95 , 457 , 801 , 1865 , 2529 ,0 }; - static ulong[] dim355KuoInit = { 1 , 3 , 5 , 5 , 21 , 3 , 31 , 97 , 3 , 495 , 1953 , 145 ,0 }; - static ulong[] dim356KuoInit = { 1 , 3 , 3 , 5 , 13 , 27 , 31 , 143 , 133 , 357 , 1975 , 1077 ,0 }; - static ulong[] dim357KuoInit = { 1 , 3 , 3 , 15 , 19 , 19 , 23 , 221 , 9 , 783 , 1403 , 4003 ,0 }; - static ulong[] dim358KuoInit = { 1 , 3 , 7 , 3 , 5 , 53 , 63 , 35 , 209 , 221 , 1517 , 1915 ,0 }; - static ulong[] dim359KuoInit = { 1 , 3 , 3 , 11 , 27 , 21 , 53 , 95 , 359 , 925 , 1035 , 3093 ,0 }; - static ulong[] dim360KuoInit = { 1 , 1 , 3 , 9 , 9 , 13 , 25 , 125 , 101 , 119 , 1361 , 3503 ,0 }; - static ulong[] dim361KuoInit = { 1 , 3 , 7 , 11 , 19 , 43 , 125 , 95 , 113 , 373 , 655 , 1001 ,0 }; - static ulong[] dim362KuoInit = { 1 , 1 , 3 , 15 , 3 , 29 , 125 , 5 , 287 , 859 , 567 , 3451 ,0 }; - static ulong[] dim363KuoInit = { 1 , 3 , 1 , 1 , 7 , 21 , 67 , 249 , 487 , 663 , 2041 , 799 ,0 }; - static ulong[] dim364KuoInit = { 1 , 1 , 3 , 9 , 9 , 29 , 11 , 229 , 303 , 821 , 1187 , 287 ,0 }; - static ulong[] dim365KuoInit = { 1 , 1 , 5 , 11 , 25 , 19 , 77 , 93 , 209 , 155 , 1717 , 4085 ,0 }; - static ulong[] dim366KuoInit = { 1 , 1 , 3 , 3 , 23 , 39 , 5 , 29 , 295 , 757 , 1185 , 817 ,0 }; - static ulong[] dim367KuoInit = { 1 , 3 , 7 , 7 , 27 , 25 , 33 , 73 , 489 , 543 , 2011 , 447 ,0 }; - static ulong[] dim368KuoInit = { 1 , 3 , 1 , 5 , 21 , 59 , 107 , 109 , 415 , 599 , 325 , 1457 ,0 }; - static ulong[] dim369KuoInit = { 1 , 3 , 1 , 5 , 27 , 61 , 45 , 129 , 37 , 923 , 285 , 2077 ,0 }; - static ulong[] dim370KuoInit = { 1 , 1 , 1 , 3 , 11 , 11 , 17 , 157 , 289 , 575 , 749 , 2463 ,0 }; - static ulong[] dim371KuoInit = { 1 , 1 , 3 , 7 , 25 , 1 , 19 , 177 , 361 , 831 , 911 , 1833 ,0 }; - static ulong[] dim372KuoInit = { 1 , 3 , 7 , 7 , 25 , 27 , 11 , 105 , 489 , 399 , 483 , 1287 ,0 }; - static ulong[] dim373KuoInit = { 1 , 3 , 7 , 11 , 3 , 49 , 27 , 63 , 33 , 991 , 341 , 2239 ,0 }; - static ulong[] dim374KuoInit = { 1 , 3 , 1 , 5 , 3 , 49 , 23 , 23 , 157 , 145 , 1709 , 1459 ,0 }; - static ulong[] dim375KuoInit = { 1 , 1 , 5 , 9 , 29 , 29 , 5 , 239 , 201 , 503 , 229 , 1943 ,0 }; - static ulong[] dim376KuoInit = { 1 , 3 , 7 , 3 , 5 , 39 , 43 , 127 , 239 , 679 , 1225 , 2123 ,0 }; - static ulong[] dim377KuoInit = { 1 , 1 , 7 , 11 , 13 , 17 , 125 , 253 , 223 , 67 , 1319 , 4019 ,0 }; - static ulong[] dim378KuoInit = { 1 , 3 , 3 , 3 , 7 , 57 , 71 , 131 , 205 , 953 , 915 , 1349 ,0 }; - static ulong[] dim379KuoInit = { 1 , 1 , 1 , 7 , 1 , 59 , 77 , 221 , 227 , 67 , 1853 , 2577 ,0 }; - static ulong[] dim380KuoInit = { 1 , 1 , 7 , 11 , 31 , 15 , 103 , 51 , 505 , 403 , 1947 , 1915 ,0 }; - static ulong[] dim381KuoInit = { 1 , 3 , 3 , 3 , 15 , 7 , 41 , 179 , 265 , 787 , 1249 , 3663 ,0 }; - static ulong[] dim382KuoInit = { 1 , 3 , 1 , 11 , 27 , 53 , 123 , 95 , 427 , 877 , 471 , 2167 ,0 }; - static ulong[] dim383KuoInit = { 1 , 1 , 1 , 9 , 25 , 7 , 31 , 47 , 21 , 299 , 1397 , 1119 ,0 }; - static ulong[] dim384KuoInit = { 1 , 3 , 3 , 9 , 15 , 49 , 9 , 255 , 19 , 995 , 837 , 2323 ,0 }; - static ulong[] dim385KuoInit = { 1 , 1 , 7 , 3 , 31 , 45 , 35 , 93 , 179 , 561 , 1737 , 3969 ,0 }; - static ulong[] dim386KuoInit = { 1 , 1 , 1 , 5 , 7 , 59 , 27 , 71 , 9 , 411 , 59 , 1783 ,0 }; - static ulong[] dim387KuoInit = { 1 , 3 , 3 , 7 , 27 , 17 , 43 , 37 , 505 , 893 , 709 , 3163 ,0 }; - static ulong[] dim388KuoInit = { 1 , 1 , 5 , 7 , 7 , 59 , 47 , 119 , 39 , 153 , 259 , 1409 ,0 }; - static ulong[] dim389KuoInit = { 1 , 3 , 5 , 1 , 21 , 29 , 23 , 153 , 309 , 137 , 1015 , 1527 ,0 }; - static ulong[] dim390KuoInit = { 1 , 1 , 5 , 15 , 15 , 27 , 41 , 15 , 135 , 707 , 481 , 2429 ,0 }; - static ulong[] dim391KuoInit = { 1 , 1 , 7 , 13 , 1 , 17 , 95 , 131 , 497 , 873 , 193 , 1683 ,0 }; - static ulong[] dim392KuoInit = { 1 , 1 , 1 , 13 , 29 , 39 , 55 , 51 , 163 , 581 , 1867 , 2219 ,0 }; - static ulong[] dim393KuoInit = { 1 , 1 , 7 , 3 , 21 , 29 , 9 , 111 , 503 , 7 , 89 , 3431 ,0 }; - static ulong[] dim394KuoInit = { 1 , 3 , 7 , 9 , 13 , 45 , 61 , 239 , 61 , 969 , 77 , 4053 ,0 }; - static ulong[] dim395KuoInit = { 1 , 1 , 7 , 11 , 13 , 29 , 79 , 39 , 361 , 635 , 1867 , 3051 ,0 }; - static ulong[] dim396KuoInit = { 1 , 3 , 7 , 3 , 29 , 11 , 81 , 193 , 469 , 365 , 17 , 3657 ,0 }; - static ulong[] dim397KuoInit = { 1 , 3 , 3 , 15 , 13 , 45 , 69 , 181 , 95 , 315 , 1025 , 1935 ,0 }; - static ulong[] dim398KuoInit = { 1 , 1 , 5 , 15 , 31 , 61 , 97 , 117 , 207 , 409 , 69 , 187 ,0 }; - static ulong[] dim399KuoInit = { 1 , 1 , 5 , 9 , 27 , 59 , 123 , 157 , 409 , 999 , 905 , 1097 ,0 }; - static ulong[] dim400KuoInit = { 1 , 1 , 7 , 1 , 1 , 51 , 99 , 143 , 255 , 817 , 179 , 3317 ,0 }; - static ulong[] dim401KuoInit = { 1 , 1 , 1 , 1 , 23 , 15 , 117 , 139 , 245 , 865 , 1723 , 3501 ,0 }; - static ulong[] dim402KuoInit = { 1 , 1 , 5 , 15 , 25 , 53 , 9 , 207 , 291 , 137 , 291 , 653 ,0 }; - static ulong[] dim403KuoInit = { 1 , 1 , 3 , 9 , 9 , 63 , 55 , 147 , 199 , 455 , 2047 , 2903 ,0 }; - static ulong[] dim404KuoInit = { 1 , 1 , 5 , 15 , 29 , 55 , 85 , 13 , 117 , 479 , 1371 , 2939 ,0 }; - static ulong[] dim405KuoInit = { 1 , 3 , 3 , 5 , 17 , 15 , 33 , 83 , 359 , 469 , 463 , 491 ,0 }; - static ulong[] dim406KuoInit = { 1 , 1 , 3 , 5 , 23 , 39 , 35 , 83 , 387 , 891 , 789 , 1469 ,0 }; - static ulong[] dim407KuoInit = { 1 , 3 , 7 , 9 , 27 , 49 , 41 , 49 , 207 , 39 , 25 , 2355 ,0 }; - static ulong[] dim408KuoInit = { 1 , 3 , 5 , 1 , 5 , 7 , 29 , 233 , 169 , 827 , 1631 , 2263 ,0 }; - static ulong[] dim409KuoInit = { 1 , 1 , 1 , 1 , 1 , 13 , 97 , 109 , 255 , 449 , 345 , 2533 ,0 }; - static ulong[] dim410KuoInit = { 1 , 3 , 1 , 5 , 3 , 15 , 77 , 217 , 237 , 57 , 1711 , 725 ,0 }; - static ulong[] dim411KuoInit = { 1 , 3 , 3 , 7 , 9 , 49 , 93 , 213 , 487 , 811 , 1659 , 3019 ,0 }; - static ulong[] dim412KuoInit = { 1 , 1 , 1 , 7 , 7 , 9 , 57 , 223 , 263 , 9 , 443 , 1103 ,0 }; - static ulong[] dim413KuoInit = { 1 , 1 , 5 , 11 , 21 , 11 , 83 , 239 , 347 , 489 , 983 , 677 ,0 }; - static ulong[] dim414KuoInit = { 1 , 1 , 1 , 11 , 9 , 29 , 25 , 105 , 391 , 1001 , 1807 , 1041 ,0 }; - static ulong[] dim415KuoInit = { 1 , 3 , 3 , 1 , 11 , 21 , 89 , 85 , 259 , 237 , 1489 , 3825 ,0 }; - static ulong[] dim416KuoInit = { 1 , 3 , 5 , 5 , 1 , 21 , 53 , 127 , 269 , 741 , 529 , 1649 ,0 }; - static ulong[] dim417KuoInit = { 1 , 3 , 1 , 7 , 3 , 35 , 71 , 65 , 21 , 985 , 111 , 2199 ,0 }; - static ulong[] dim418KuoInit = { 1 , 1 , 5 , 13 , 3 , 39 , 33 , 151 , 95 , 655 , 1805 , 1545 ,0 }; - static ulong[] dim419KuoInit = { 1 , 3 , 1 , 11 , 17 , 53 , 63 , 171 , 275 , 649 , 1791 , 3309 ,0 }; - static ulong[] dim420KuoInit = { 1 , 1 , 7 , 1 , 3 , 5 , 63 , 241 , 77 , 677 , 1713 , 1643 ,0 }; - static ulong[] dim421KuoInit = { 1 , 3 , 3 , 3 , 9 , 25 , 7 , 33 , 277 , 837 , 1235 , 3289 ,0 }; - static ulong[] dim422KuoInit = { 1 , 3 , 3 , 1 , 27 , 13 , 97 , 79 , 145 , 197 , 1237 , 1689 ,0 }; - static ulong[] dim423KuoInit = { 1 , 3 , 5 , 7 , 27 , 45 , 71 , 165 , 405 , 251 , 383 , 737 ,0 }; - static ulong[] dim424KuoInit = { 1 , 3 , 7 , 1 , 13 , 21 , 107 , 7 , 207 , 329 , 1671 , 2053 ,0 }; - static ulong[] dim425KuoInit = { 1 , 3 , 7 , 1 , 31 , 33 , 25 , 223 , 37 , 693 , 1831 , 2249 ,0 }; - static ulong[] dim426KuoInit = { 1 , 3 , 3 , 15 , 5 , 53 , 111 , 11 , 317 , 819 , 1345 , 401 ,0 }; - static ulong[] dim427KuoInit = { 1 , 3 , 1 , 9 , 7 , 61 , 35 , 127 , 453 , 565 , 37 , 17 ,0 }; - static ulong[] dim428KuoInit = { 1 , 3 , 1 , 1 , 15 , 3 , 37 , 133 , 339 , 181 , 377 , 2339 ,0 }; - static ulong[] dim429KuoInit = { 1 , 3 , 7 , 3 , 27 , 57 , 27 , 23 , 45 , 219 , 455 , 2821 ,0 }; - static ulong[] dim430KuoInit = { 1 , 3 , 7 , 9 , 3 , 43 , 79 , 67 , 15 , 797 , 129 , 1233 ,0 }; - static ulong[] dim431KuoInit = { 1 , 3 , 5 , 11 , 5 , 45 , 123 , 161 , 355 , 447 , 1165 , 2437 ,0 }; - static ulong[] dim432KuoInit = { 1 , 3 , 7 , 1 , 3 , 59 , 65 , 109 , 253 , 447 , 649 , 379 ,0 }; - static ulong[] dim433KuoInit = { 1 , 3 , 1 , 5 , 21 , 23 , 45 , 47 , 213 , 813 , 1475 , 1271 ,0 }; - static ulong[] dim434KuoInit = { 1 , 1 , 1 , 7 , 9 , 31 , 91 , 47 , 161 , 535 , 1529 , 881 ,0 }; - static ulong[] dim435KuoInit = { 1 , 1 , 5 , 13 , 1 , 25 , 85 , 107 , 59 , 487 , 221 , 51 ,0 }; - static ulong[] dim436KuoInit = { 1 , 1 , 1 , 1 , 1 , 55 , 93 , 95 , 267 , 157 , 1255 , 2115 ,0 }; - static ulong[] dim437KuoInit = { 1 , 3 , 1 , 11 , 23 , 55 , 29 , 187 , 261 , 139 , 515 , 2627 ,0 }; - static ulong[] dim438KuoInit = { 1 , 3 , 3 , 13 , 31 , 3 , 121 , 245 , 475 , 67 , 195 , 979 ,0 }; - static ulong[] dim439KuoInit = { 1 , 1 , 3 , 7 , 25 , 13 , 79 , 129 , 475 , 177 , 1519 , 1069 ,0 }; - static ulong[] dim440KuoInit = { 1 , 3 , 3 , 9 , 17 , 23 , 83 , 191 , 133 , 901 , 1161 , 1657 ,0 }; - static ulong[] dim441KuoInit = { 1 , 3 , 7 , 15 , 23 , 61 , 111 , 135 , 107 , 27 , 583 , 225 ,0 }; - static ulong[] dim442KuoInit = { 1 , 1 , 5 , 1 , 17 , 11 , 31 , 197 , 111 , 953 , 1227 , 3737 ,0 }; - static ulong[] dim443KuoInit = { 1 , 1 , 3 , 9 , 19 , 25 , 83 , 97 , 489 , 781 , 1591 , 2061 ,0 }; - static ulong[] dim444KuoInit = { 1 , 1 , 1 , 1 , 9 , 61 , 31 , 93 , 39 , 53 , 1613 , 3371 ,0 }; - static ulong[] dim445KuoInit = { 1 , 1 , 1 , 7 , 3 , 5 , 103 , 247 , 255 , 333 , 31 , 3087 ,0 }; - static ulong[] dim446KuoInit = { 1 , 1 , 7 , 7 , 17 , 35 , 51 , 153 , 363 , 897 , 395 , 1153 ,0 }; - static ulong[] dim447KuoInit = { 1 , 3 , 7 , 9 , 3 , 59 , 127 , 177 , 191 , 255 , 1543 , 503 ,0 }; - static ulong[] dim448KuoInit = { 1 , 1 , 7 , 3 , 1 , 7 , 81 , 199 , 411 , 565 , 1717 , 615 ,0 }; - static ulong[] dim449KuoInit = { 1 , 1 , 1 , 11 , 17 , 35 , 35 , 245 , 507 , 439 , 523 , 2343 ,0 }; - static ulong[] dim450KuoInit = { 1 , 1 , 7 , 15 , 13 , 61 , 31 , 99 , 241 , 605 , 1575 , 1321 ,0 }; - static ulong[] dim451KuoInit = { 1 , 3 , 1 , 5 , 15 , 31 , 45 , 89 , 193 , 905 , 691 , 3917 ,0 }; - static ulong[] dim452KuoInit = { 1 , 3 , 3 , 9 , 29 , 31 , 101 , 151 , 187 , 199 , 1543 , 3951 ,0 }; - static ulong[] dim453KuoInit = { 1 , 1 , 7 , 9 , 21 , 45 , 71 , 19 , 395 , 175 , 503 , 3759 ,0 }; - static ulong[] dim454KuoInit = { 1 , 3 , 7 , 7 , 17 , 31 , 47 , 7 , 135 , 719 , 567 , 1447 ,0 }; - static ulong[] dim455KuoInit = { 1 , 3 , 3 , 9 , 1 , 39 , 1 , 53 , 5 , 553 , 371 , 3833 ,0 }; - static ulong[] dim456KuoInit = { 1 , 1 , 1 , 11 , 1 , 33 , 97 , 209 , 377 , 187 , 1683 , 143 ,0 }; - static ulong[] dim457KuoInit = { 1 , 1 , 1 , 3 , 29 , 33 , 111 , 35 , 343 , 511 , 273 , 445 ,0 }; - static ulong[] dim458KuoInit = { 1 , 1 , 1 , 15 , 15 , 63 , 73 , 1 , 111 , 775 , 665 , 2737 ,0 }; - static ulong[] dim459KuoInit = { 1 , 1 , 1 , 9 , 29 , 23 , 127 , 77 , 33 , 131 , 1055 , 2351 ,0 }; - static ulong[] dim460KuoInit = { 1 , 3 , 5 , 7 , 31 , 53 , 117 , 57 , 287 , 221 , 1099 , 1147 ,0 }; - static ulong[] dim461KuoInit = { 1 , 3 , 7 , 15 , 3 , 17 , 15 , 177 , 189 , 379 , 179 , 1095 ,0 }; - static ulong[] dim462KuoInit = { 1 , 3 , 1 , 15 , 25 , 19 , 43 , 113 , 123 , 123 , 877 , 1869 ,0 }; - static ulong[] dim463KuoInit = { 1 , 3 , 1 , 1 , 13 , 63 , 1 , 83 , 197 , 215 , 1005 , 3531 ,0 }; - static ulong[] dim464KuoInit = { 1 , 3 , 7 , 1 , 27 , 25 , 111 , 199 , 239 , 909 , 485 , 3399 ,0 }; - static ulong[] dim465KuoInit = { 1 , 1 , 7 , 3 , 19 , 57 , 43 , 75 , 163 , 111 , 359 , 1987 ,0 }; - static ulong[] dim466KuoInit = { 1 , 1 , 3 , 7 , 11 , 63 , 79 , 235 , 197 , 757 , 293 , 3795 ,0 }; - static ulong[] dim467KuoInit = { 1 , 3 , 5 , 9 , 13 , 55 , 49 , 29 , 133 , 949 , 1185 , 905 ,0 }; - static ulong[] dim468KuoInit = { 1 , 1 , 7 , 1 , 15 , 51 , 13 , 223 , 243 , 831 , 845 , 2663 ,0 }; - static ulong[] dim469KuoInit = { 1 , 1 , 3 , 11 , 25 , 21 , 65 , 57 , 483 , 665 , 741 , 2713 ,0 }; - static ulong[] dim470KuoInit = { 1 , 3 , 5 , 3 , 21 , 3 , 81 , 57 , 133 , 553 , 683 , 425 ,0 }; - static ulong[] dim471KuoInit = { 1 , 1 , 5 , 11 , 31 , 29 , 59 , 189 , 399 , 751 , 651 , 4093 ,0 }; - static ulong[] dim472KuoInit = { 1 , 3 , 3 , 7 , 13 , 59 , 19 , 217 , 267 , 355 , 173 , 4051 ,0 }; - static ulong[] dim473KuoInit = { 1 , 1 , 5 , 9 , 23 , 49 , 57 , 145 , 77 , 591 , 1913 , 779 ,0 }; - static ulong[] dim474KuoInit = { 1 , 3 , 7 , 3 , 25 , 1 , 83 , 103 , 393 , 121 , 1415 , 1503 ,0 }; - static ulong[] dim475KuoInit = { 1 , 1 , 7 , 9 , 23 , 41 , 35 , 157 , 63 , 293 , 1911 , 2303 ,0 }; - static ulong[] dim476KuoInit = { 1 , 3 , 5 , 15 , 7 , 3 , 9 , 1 , 201 , 913 , 1275 , 3495 ,0 }; - static ulong[] dim477KuoInit = { 1 , 1 , 7 , 11 , 15 , 5 , 107 , 57 , 53 , 451 , 351 , 2621 ,0 }; - static ulong[] dim478KuoInit = { 1 , 3 , 7 , 15 , 23 , 25 , 97 , 29 , 111 , 531 , 1979 , 2115 ,0 }; - static ulong[] dim479KuoInit = { 1 , 1 , 1 , 1 , 19 , 11 , 49 , 229 , 355 , 195 , 2033 , 1701 ,0 }; - static ulong[] dim480KuoInit = { 1 , 3 , 3 , 3 , 15 , 35 , 17 , 13 , 425 , 285 , 965 , 159 ,0 }; - static ulong[] dim481KuoInit = { 1 , 3 , 1 , 11 , 11 , 11 , 1 , 145 , 365 , 471 , 1527 , 2309 , 5863 ,0 }; - static ulong[] dim482KuoInit = { 1 , 1 , 3 , 9 , 21 , 59 , 35 , 123 , 91 , 741 , 527 , 2061 , 5505 ,0 }; - static ulong[] dim483KuoInit = { 1 , 3 , 7 , 9 , 9 , 37 , 75 , 171 , 75 , 943 , 443 , 201 , 4861 ,0 }; - static ulong[] dim484KuoInit = { 1 , 1 , 7 , 13 , 23 , 49 , 67 , 103 , 453 , 643 , 1117 , 1621 , 7135 ,0 }; - static ulong[] dim485KuoInit = { 1 , 3 , 1 , 7 , 15 , 43 , 113 , 17 , 277 , 301 , 349 , 1155 , 5285 ,0 }; - static ulong[] dim486KuoInit = { 1 , 3 , 5 , 1 , 25 , 61 , 103 , 81 , 141 , 347 , 1467 , 1535 , 421 ,0 }; - static ulong[] dim487KuoInit = { 1 , 3 , 5 , 13 , 29 , 45 , 43 , 31 , 403 , 711 , 455 , 3387 , 3521 ,0 }; - static ulong[] dim488KuoInit = { 1 , 3 , 3 , 7 , 7 , 41 , 71 , 251 , 147 , 241 , 1129 , 2093 , 7683 ,0 }; - static ulong[] dim489KuoInit = { 1 , 1 , 1 , 5 , 23 , 61 , 57 , 97 , 177 , 387 , 1557 , 3587 , 751 ,0 }; - static ulong[] dim490KuoInit = { 1 , 3 , 1 , 13 , 11 , 33 , 47 , 147 , 321 , 661 , 53 , 2437 , 3087 ,0 }; - static ulong[] dim491KuoInit = { 1 , 3 , 1 , 3 , 17 , 21 , 79 , 91 , 77 , 1011 , 745 , 3551 , 1857 ,0 }; - static ulong[] dim492KuoInit = { 1 , 1 , 3 , 15 , 19 , 27 , 63 , 231 , 267 , 879 , 1959 , 3019 , 1655 ,0 }; - static ulong[] dim493KuoInit = { 1 , 1 , 7 , 15 , 27 , 55 , 21 , 37 , 417 , 69 , 327 , 2709 , 6335 ,0 }; - static ulong[] dim494KuoInit = { 1 , 3 , 1 , 15 , 1 , 9 , 27 , 89 , 205 , 355 , 373 , 2191 , 311 ,0 }; - static ulong[] dim495KuoInit = { 1 , 1 , 3 , 5 , 15 , 51 , 85 , 233 , 21 , 971 , 1823 , 1843 , 1417 ,0 }; - static ulong[] dim496KuoInit = { 1 , 3 , 5 , 13 , 31 , 57 , 3 , 199 , 211 , 401 , 1559 , 3601 , 4569 ,0 }; - static ulong[] dim497KuoInit = { 1 , 3 , 3 , 1 , 27 , 63 , 93 , 123 , 223 , 601 , 1023 , 2501 , 7105 ,0 }; - static ulong[] dim498KuoInit = { 1 , 1 , 1 , 7 , 3 , 31 , 5 , 51 , 453 , 535 , 255 , 735 , 749 ,0 }; - static ulong[] dim499KuoInit = { 1 , 3 , 5 , 9 , 23 , 63 , 109 , 163 , 221 , 845 , 911 , 933 , 361 ,0 }; - static ulong[] dim500KuoInit = { 1 , 1 , 1 , 13 , 13 , 17 , 19 , 191 , 227 , 711 , 1523 , 1635 , 6397 ,0 }; - static ulong[] dim501KuoInit = { 1 , 3 , 7 , 7 , 21 , 21 , 23 , 91 , 439 , 227 , 1831 , 1475 , 705 ,0 }; - static ulong[] dim502KuoInit = { 1 , 3 , 7 , 7 , 13 , 39 , 99 , 199 , 149 , 1005 , 149 , 445 , 3367 ,0 }; - static ulong[] dim503KuoInit = { 1 , 3 , 1 , 5 , 25 , 61 , 99 , 187 , 33 , 619 , 1833 , 2177 , 7631 ,0 }; - static ulong[] dim504KuoInit = { 1 , 1 , 1 , 13 , 15 , 45 , 1 , 225 , 129 , 113 , 2009 , 1223 , 49 ,0 }; - static ulong[] dim505KuoInit = { 1 , 3 , 1 , 9 , 7 , 43 , 57 , 193 , 409 , 265 , 1151 , 2635 , 6005 ,0 }; - static ulong[] dim506KuoInit = { 1 , 3 , 5 , 5 , 13 , 13 , 99 , 163 , 1 , 629 , 87 , 925 , 137 ,0 }; - static ulong[] dim507KuoInit = { 1 , 3 , 7 , 9 , 23 , 43 , 43 , 1 , 505 , 179 , 335 , 2033 , 8065 ,0 }; - static ulong[] dim508KuoInit = { 1 , 3 , 5 , 1 , 7 , 55 , 99 , 159 , 19 , 883 , 1503 , 801 , 1433 ,0 }; - static ulong[] dim509KuoInit = { 1 , 3 , 7 , 1 , 1 , 55 , 53 , 241 , 95 , 315 , 723 , 3571 , 4685 ,0 }; - static ulong[] dim510KuoInit = { 1 , 3 , 5 , 15 , 29 , 43 , 97 , 159 , 427 , 87 , 1995 , 1849 , 6771 ,0 }; - static ulong[] dim511KuoInit = { 1 , 1 , 1 , 7 , 5 , 55 , 55 , 203 , 119 , 185 , 1333 , 2107 , 4271 ,0 }; - static ulong[] dim512KuoInit = { 1 , 1 , 3 , 15 , 5 , 7 , 19 , 185 , 75 , 601 , 2015 , 2175 , 4259 ,0 }; - static ulong[] dim513KuoInit = { 1 , 3 , 3 , 15 , 3 , 49 , 33 , 115 , 413 , 321 , 1787 , 469 , 3721 ,0 }; - static ulong[] dim514KuoInit = { 1 , 3 , 1 , 9 , 25 , 63 , 123 , 17 , 355 , 903 , 1269 , 3737 , 5333 ,0 }; - static ulong[] dim515KuoInit = { 1 , 1 , 3 , 7 , 25 , 41 , 113 , 239 , 373 , 533 , 1823 , 3513 , 7745 ,0 }; - static ulong[] dim516KuoInit = { 1 , 1 , 1 , 11 , 13 , 7 , 7 , 43 , 145 , 607 , 2043 , 2397 , 4051 ,0 }; - static ulong[] dim517KuoInit = { 1 , 1 , 3 , 3 , 9 , 49 , 5 , 173 , 63 , 157 , 637 , 2307 , 6603 ,0 }; - static ulong[] dim518KuoInit = { 1 , 3 , 1 , 3 , 23 , 33 , 89 , 139 , 207 , 389 , 1389 , 3385 , 2169 ,0 }; - static ulong[] dim519KuoInit = { 1 , 1 , 7 , 3 , 7 , 7 , 19 , 7 , 217 , 189 , 739 , 2475 , 7925 ,0 }; - static ulong[] dim520KuoInit = { 1 , 1 , 7 , 5 , 23 , 37 , 71 , 31 , 145 , 29 , 537 , 959 , 2227 ,0 }; - static ulong[] dim521KuoInit = { 1 , 1 , 7 , 11 , 7 , 55 , 39 , 167 , 347 , 293 , 577 , 3077 , 531 ,0 }; - static ulong[] dim522KuoInit = { 1 , 3 , 1 , 5 , 19 , 1 , 119 , 133 , 487 , 867 , 1331 , 1759 , 3683 ,0 }; - static ulong[] dim523KuoInit = { 1 , 3 , 5 , 13 , 27 , 31 , 77 , 71 , 465 , 133 , 105 , 477 , 6301 ,0 }; - static ulong[] dim524KuoInit = { 1 , 3 , 5 , 15 , 25 , 49 , 35 , 75 , 57 , 663 , 195 , 1041 , 5697 ,0 }; - static ulong[] dim525KuoInit = { 1 , 3 , 7 , 9 , 9 , 7 , 47 , 233 , 397 , 155 , 439 , 2487 , 4697 ,0 }; - static ulong[] dim526KuoInit = { 1 , 1 , 5 , 9 , 5 , 41 , 125 , 9 , 477 , 567 , 2033 , 769 , 1553 ,0 }; - static ulong[] dim527KuoInit = { 1 , 1 , 3 , 7 , 7 , 25 , 95 , 45 , 211 , 453 , 483 , 3965 , 1865 ,0 }; - static ulong[] dim528KuoInit = { 1 , 3 , 7 , 5 , 17 , 41 , 109 , 59 , 385 , 1023 , 1527 , 2445 , 6303 ,0 }; - static ulong[] dim529KuoInit = { 1 , 3 , 3 , 9 , 7 , 29 , 91 , 245 , 189 , 251 , 1237 , 2825 , 7919 ,0 }; - static ulong[] dim530KuoInit = { 1 , 3 , 7 , 1 , 25 , 43 , 27 , 11 , 63 , 641 , 1765 , 1683 , 2445 ,0 }; - static ulong[] dim531KuoInit = { 1 , 1 , 1 , 7 , 3 , 59 , 19 , 81 , 387 , 207 , 31 , 1583 , 607 ,0 }; - static ulong[] dim532KuoInit = { 1 , 1 , 3 , 1 , 3 , 33 , 99 , 135 , 267 , 355 , 585 , 4017 , 2385 ,0 }; - static ulong[] dim533KuoInit = { 1 , 1 , 7 , 15 , 1 , 49 , 35 , 211 , 359 , 379 , 1173 , 2709 , 3945 ,0 }; - static ulong[] dim534KuoInit = { 1 , 1 , 5 , 7 , 29 , 23 , 99 , 219 , 269 , 977 , 1175 , 2305 , 5633 ,0 }; - static ulong[] dim535KuoInit = { 1 , 3 , 3 , 15 , 17 , 9 , 115 , 21 , 503 , 329 , 1725 , 289 , 4667 ,0 }; - static ulong[] dim536KuoInit = { 1 , 1 , 7 , 1 , 9 , 1 , 31 , 145 , 209 , 833 , 1527 , 4021 , 2177 ,0 }; - static ulong[] dim537KuoInit = { 1 , 3 , 3 , 1 , 25 , 13 , 37 , 143 , 217 , 891 , 1289 , 3635 , 6931 ,0 }; - static ulong[] dim538KuoInit = { 1 , 1 , 3 , 9 , 9 , 49 , 33 , 123 , 435 , 993 , 389 , 2491 , 2097 ,0 }; - static ulong[] dim539KuoInit = { 1 , 3 , 5 , 9 , 11 , 53 , 121 , 25 , 31 , 589 , 1939 , 3981 , 621 ,0 }; - static ulong[] dim540KuoInit = { 1 , 1 , 1 , 1 , 27 , 53 , 9 , 217 , 135 , 605 , 1779 , 3053 , 2865 ,0 }; - static ulong[] dim541KuoInit = { 1 , 1 , 7 , 5 , 3 , 53 , 9 , 15 , 275 , 613 , 1395 , 2287 , 1111 ,0 }; - static ulong[] dim542KuoInit = { 1 , 1 , 3 , 1 , 13 , 17 , 3 , 103 , 195 , 509 , 493 , 2395 , 4669 ,0 }; - static ulong[] dim543KuoInit = { 1 , 3 , 5 , 1 , 13 , 17 , 59 , 3 , 117 , 39 , 1699 , 2339 , 5203 ,0 }; - static ulong[] dim544KuoInit = { 1 , 3 , 5 , 3 , 29 , 23 , 59 , 251 , 139 , 625 , 935 , 785 , 7547 ,0 }; - static ulong[] dim545KuoInit = { 1 , 3 , 1 , 13 , 23 , 47 , 5 , 91 , 283 , 59 , 919 , 2427 , 1631 ,0 }; - static ulong[] dim546KuoInit = { 1 , 1 , 3 , 9 , 15 , 35 , 67 , 131 , 183 , 891 , 345 , 3741 , 3175 ,0 }; - static ulong[] dim547KuoInit = { 1 , 3 , 1 , 3 , 23 , 11 , 85 , 135 , 269 , 347 , 713 , 2947 , 1617 ,0 }; - static ulong[] dim548KuoInit = { 1 , 3 , 1 , 3 , 27 , 33 , 77 , 189 , 243 , 893 , 283 , 885 , 1999 ,0 }; - static ulong[] dim549KuoInit = { 1 , 1 , 5 , 1 , 31 , 39 , 99 , 21 , 437 , 979 , 919 , 3663 , 6689 ,0 }; - static ulong[] dim550KuoInit = { 1 , 1 , 1 , 1 , 17 , 27 , 55 , 161 , 205 , 583 , 383 , 1681 , 6445 ,0 }; - static ulong[] dim551KuoInit = { 1 , 3 , 7 , 1 , 31 , 59 , 111 , 129 , 121 , 555 , 653 , 2787 , 3899 ,0 }; - static ulong[] dim552KuoInit = { 1 , 3 , 1 , 9 , 11 , 59 , 51 , 115 , 349 , 809 , 513 , 1585 , 31 ,0 }; - static ulong[] dim553KuoInit = { 1 , 1 , 1 , 3 , 29 , 17 , 3 , 173 , 111 , 671 , 1289 , 397 , 799 ,0 }; - static ulong[] dim554KuoInit = { 1 , 3 , 1 , 7 , 17 , 55 , 85 , 49 , 23 , 915 , 1929 , 685 , 7021 ,0 }; - static ulong[] dim555KuoInit = { 1 , 3 , 7 , 11 , 3 , 41 , 123 , 227 , 111 , 805 , 1567 , 751 , 7927 ,0 }; - static ulong[] dim556KuoInit = { 1 , 1 , 7 , 3 , 15 , 45 , 117 , 39 , 491 , 401 , 1775 , 2197 , 4303 ,0 }; - static ulong[] dim557KuoInit = { 1 , 1 , 7 , 9 , 13 , 23 , 63 , 245 , 163 , 595 , 1271 , 2143 , 8105 ,0 }; - static ulong[] dim558KuoInit = { 1 , 1 , 3 , 1 , 31 , 57 , 45 , 35 , 327 , 89 , 1845 , 1075 , 4649 ,0 }; - static ulong[] dim559KuoInit = { 1 , 3 , 7 , 7 , 11 , 31 , 51 , 209 , 103 , 215 , 1693 , 3427 , 677 ,0 }; - static ulong[] dim560KuoInit = { 1 , 1 , 5 , 13 , 3 , 7 , 83 , 199 , 325 , 461 , 1185 , 1997 , 2327 ,0 }; - static ulong[] dim561KuoInit = { 1 , 1 , 3 , 15 , 23 , 13 , 23 , 39 , 209 , 267 , 1995 , 3999 , 6277 ,0 }; - static ulong[] dim562KuoInit = { 1 , 1 , 7 , 1 , 5 , 37 , 99 , 117 , 509 , 303 , 655 , 935 , 6321 ,0 }; - static ulong[] dim563KuoInit = { 1 , 1 , 1 , 15 , 23 , 39 , 123 , 11 , 445 , 897 , 1327 , 2819 , 1899 ,0 }; - static ulong[] dim564KuoInit = { 1 , 1 , 5 , 5 , 7 , 7 , 7 , 61 , 349 , 865 , 707 , 2097 , 1217 ,0 }; - static ulong[] dim565KuoInit = { 1 , 1 , 5 , 9 , 1 , 63 , 35 , 187 , 207 , 53 , 1917 , 621 , 2113 ,0 }; - static ulong[] dim566KuoInit = { 1 , 1 , 1 , 15 , 21 , 61 , 101 , 169 , 129 , 813 , 453 , 323 , 7283 ,0 }; - static ulong[] dim567KuoInit = { 1 , 1 , 7 , 7 , 27 , 1 , 27 , 141 , 33 , 307 , 2023 , 2561 , 8111 ,0 }; - static ulong[] dim568KuoInit = { 1 , 1 , 5 , 13 , 3 , 9 , 3 , 87 , 451 , 691 , 973 , 539 , 4393 ,0 }; - static ulong[] dim569KuoInit = { 1 , 1 , 5 , 1 , 23 , 23 , 9 , 101 , 349 , 299 , 583 , 2037 , 5247 ,0 }; - static ulong[] dim570KuoInit = { 1 , 1 , 5 , 11 , 15 , 39 , 99 , 163 , 395 , 123 , 1067 , 2735 , 4407 ,0 }; - static ulong[] dim571KuoInit = { 1 , 3 , 5 , 11 , 9 , 61 , 51 , 237 , 483 , 501 , 1767 , 1419 , 5047 ,0 }; - static ulong[] dim572KuoInit = { 1 , 1 , 7 , 9 , 27 , 31 , 57 , 103 , 291 , 537 , 1759 , 1861 , 3815 ,0 }; - static ulong[] dim573KuoInit = { 1 , 1 , 5 , 15 , 31 , 5 , 107 , 103 , 159 , 939 , 1331 , 1219 , 2045 ,0 }; - static ulong[] dim574KuoInit = { 1 , 3 , 5 , 15 , 7 , 45 , 99 , 175 , 131 , 967 , 593 , 3191 , 5403 ,0 }; - static ulong[] dim575KuoInit = { 1 , 3 , 7 , 11 , 19 , 43 , 57 , 129 , 285 , 943 , 1507 , 3979 , 2807 ,0 }; - static ulong[] dim576KuoInit = { 1 , 1 , 5 , 3 , 11 , 7 , 117 , 241 , 393 , 1023 , 95 , 535 , 7235 ,0 }; - static ulong[] dim577KuoInit = { 1 , 3 , 1 , 5 , 17 , 5 , 111 , 165 , 343 , 65 , 1393 , 2855 , 3801 ,0 }; - static ulong[] dim578KuoInit = { 1 , 1 , 5 , 5 , 27 , 1 , 87 , 9 , 177 , 455 , 1915 , 1557 , 7175 ,0 }; - static ulong[] dim579KuoInit = { 1 , 1 , 5 , 11 , 31 , 33 , 105 , 255 , 281 , 303 , 1831 , 1575 , 1179 ,0 }; - static ulong[] dim580KuoInit = { 1 , 3 , 3 , 9 , 7 , 37 , 3 , 85 , 161 , 491 , 299 , 4003 , 7429 ,0 }; - static ulong[] dim581KuoInit = { 1 , 1 , 5 , 9 , 1 , 19 , 23 , 175 , 497 , 613 , 2043 , 1467 , 2379 ,0 }; - static ulong[] dim582KuoInit = { 1 , 3 , 7 , 13 , 5 , 57 , 93 , 17 , 383 , 801 , 1465 , 3151 , 4717 ,0 }; - static ulong[] dim583KuoInit = { 1 , 3 , 7 , 5 , 3 , 19 , 87 , 25 , 95 , 643 , 79 , 123 , 7175 ,0 }; - static ulong[] dim584KuoInit = { 1 , 1 , 1 , 5 , 3 , 27 , 49 , 155 , 45 , 655 , 1079 , 3243 , 8147 ,0 }; - static ulong[] dim585KuoInit = { 1 , 3 , 1 , 11 , 13 , 57 , 107 , 37 , 147 , 119 , 887 , 1317 , 6687 ,0 }; - static ulong[] dim586KuoInit = { 1 , 3 , 3 , 13 , 29 , 23 , 105 , 137 , 339 , 509 , 1543 , 2339 , 2167 ,0 }; - static ulong[] dim587KuoInit = { 1 , 1 , 5 , 3 , 29 , 5 , 89 , 65 , 191 , 33 , 755 , 737 , 3495 ,0 }; - static ulong[] dim588KuoInit = { 1 , 1 , 5 , 1 , 19 , 27 , 123 , 67 , 323 , 731 , 1753 , 1773 , 1731 ,0 }; - static ulong[] dim589KuoInit = { 1 , 1 , 5 , 11 , 23 , 35 , 21 , 1 , 107 , 509 , 1617 , 1565 , 1617 ,0 }; - static ulong[] dim590KuoInit = { 1 , 1 , 7 , 15 , 31 , 7 , 31 , 241 , 479 , 457 , 1353 , 1531 , 5939 ,0 }; - static ulong[] dim591KuoInit = { 1 , 3 , 1 , 1 , 31 , 19 , 71 , 127 , 379 , 151 , 739 , 893 , 7857 ,0 }; - static ulong[] dim592KuoInit = { 1 , 1 , 1 , 3 , 31 , 41 , 99 , 55 , 229 , 585 , 1881 , 2267 , 3555 ,0 }; - static ulong[] dim593KuoInit = { 1 , 3 , 3 , 1 , 25 , 3 , 55 , 95 , 409 , 429 , 527 , 611 , 6551 ,0 }; - static ulong[] dim594KuoInit = { 1 , 3 , 5 , 3 , 3 , 59 , 81 , 83 , 131 , 981 , 67 , 295 , 3313 ,0 }; - static ulong[] dim595KuoInit = { 1 , 1 , 1 , 13 , 23 , 57 , 47 , 127 , 307 , 621 , 865 , 2589 , 4033 ,0 }; - static ulong[] dim596KuoInit = { 1 , 1 , 7 , 11 , 7 , 17 , 15 , 207 , 89 , 77 , 1923 , 3649 , 119 ,0 }; - static ulong[] dim597KuoInit = { 1 , 3 , 5 , 3 , 23 , 5 , 87 , 247 , 233 , 43 , 475 , 999 , 6999 ,0 }; - static ulong[] dim598KuoInit = { 1 , 1 , 7 , 13 , 19 , 49 , 53 , 21 , 105 , 181 , 1569 , 3151 , 5089 ,0 }; - static ulong[] dim599KuoInit = { 1 , 1 , 5 , 7 , 11 , 53 , 119 , 11 , 301 , 647 , 759 , 2849 , 4541 ,0 }; - static ulong[] dim600KuoInit = { 1 , 1 , 7 , 11 , 31 , 31 , 83 , 107 , 373 , 41 , 921 , 3935 , 2859 ,0 }; - static ulong[] dim601KuoInit = { 1 , 3 , 5 , 13 , 13 , 57 , 121 , 133 , 355 , 153 , 607 , 3199 , 8097 ,0 }; - static ulong[] dim602KuoInit = { 1 , 1 , 5 , 9 , 5 , 25 , 113 , 21 , 17 , 643 , 415 , 2705 , 903 ,0 }; - static ulong[] dim603KuoInit = { 1 , 1 , 5 , 1 , 19 , 3 , 119 , 199 , 241 , 957 , 1203 , 1291 , 6355 ,0 }; - static ulong[] dim604KuoInit = { 1 , 1 , 3 , 13 , 19 , 1 , 11 , 73 , 387 , 97 , 783 , 3875 , 4573 ,0 }; - static ulong[] dim605KuoInit = { 1 , 1 , 7 , 3 , 27 , 11 , 99 , 193 , 311 , 889 , 535 , 801 , 4467 ,0 }; - static ulong[] dim606KuoInit = { 1 , 1 , 1 , 1 , 3 , 53 , 61 , 245 , 497 , 127 , 1213 , 1147 , 2225 ,0 }; - static ulong[] dim607KuoInit = { 1 , 3 , 5 , 1 , 9 , 49 , 21 , 229 , 481 , 23 , 47 , 3959 , 2991 ,0 }; - static ulong[] dim608KuoInit = { 1 , 1 , 5 , 1 , 9 , 21 , 123 , 107 , 359 , 759 , 993 , 695 , 5609 ,0 }; - static ulong[] dim609KuoInit = { 1 , 3 , 5 , 11 , 25 , 55 , 73 , 245 , 373 , 525 , 1399 , 1727 , 1763 ,0 }; - static ulong[] dim610KuoInit = { 1 , 1 , 5 , 3 , 21 , 41 , 83 , 161 , 43 , 563 , 1655 , 3539 , 7941 ,0 }; - static ulong[] dim611KuoInit = { 1 , 3 , 1 , 13 , 29 , 59 , 25 , 119 , 199 , 375 , 1507 , 2095 , 3281 ,0 }; - static ulong[] dim612KuoInit = { 1 , 3 , 3 , 5 , 21 , 23 , 63 , 85 , 115 , 77 , 745 , 771 , 3319 ,0 }; - static ulong[] dim613KuoInit = { 1 , 1 , 7 , 3 , 3 , 37 , 11 , 233 , 173 , 51 , 1723 , 1441 , 6529 ,0 }; - static ulong[] dim614KuoInit = { 1 , 1 , 1 , 11 , 1 , 55 , 113 , 25 , 369 , 1023 , 1691 , 1797 , 159 ,0 }; - static ulong[] dim615KuoInit = { 1 , 3 , 1 , 15 , 13 , 43 , 63 , 113 , 55 , 351 , 1459 , 3117 , 3499 ,0 }; - static ulong[] dim616KuoInit = { 1 , 3 , 7 , 1 , 19 , 61 , 17 , 243 , 203 , 349 , 1069 , 105 , 6015 ,0 }; - static ulong[] dim617KuoInit = { 1 , 1 , 5 , 1 , 23 , 49 , 7 , 129 , 99 , 377 , 1989 , 531 , 6315 ,0 }; - static ulong[] dim618KuoInit = { 1 , 1 , 7 , 7 , 11 , 23 , 107 , 63 , 163 , 351 , 1385 , 127 , 7439 ,0 }; - static ulong[] dim619KuoInit = { 1 , 3 , 5 , 15 , 15 , 43 , 81 , 229 , 21 , 179 , 1357 , 3813 , 7345 ,0 }; - static ulong[] dim620KuoInit = { 1 , 1 , 1 , 15 , 23 , 19 , 89 , 251 , 161 , 443 , 983 , 1059 , 1241 ,0 }; - static ulong[] dim621KuoInit = { 1 , 3 , 3 , 9 , 7 , 17 , 11 , 239 , 325 , 117 , 893 , 917 , 6327 ,0 }; - static ulong[] dim622KuoInit = { 1 , 1 , 7 , 1 , 31 , 33 , 23 , 241 , 255 , 991 , 903 , 3973 , 3935 ,0 }; - static ulong[] dim623KuoInit = { 1 , 3 , 7 , 3 , 11 , 17 , 61 , 219 , 461 , 437 , 1843 , 1845 , 771 ,0 }; - static ulong[] dim624KuoInit = { 1 , 3 , 7 , 5 , 7 , 61 , 79 , 225 , 215 , 411 , 885 , 3949 , 2757 ,0 }; - static ulong[] dim625KuoInit = { 1 , 3 , 7 , 3 , 3 , 15 , 25 , 49 , 351 , 671 , 1573 , 3643 , 2383 ,0 }; - static ulong[] dim626KuoInit = { 1 , 1 , 7 , 1 , 29 , 1 , 121 , 61 , 49 , 833 , 1363 , 427 , 3237 ,0 }; - static ulong[] dim627KuoInit = { 1 , 3 , 3 , 5 , 11 , 9 , 79 , 113 , 341 , 25 , 1797 , 1641 , 6899 ,0 }; - static ulong[] dim628KuoInit = { 1 , 1 , 5 , 9 , 11 , 15 , 71 , 169 , 269 , 359 , 1991 , 3673 , 601 ,0 }; - static ulong[] dim629KuoInit = { 1 , 1 , 1 , 11 , 31 , 7 , 5 , 165 , 23 , 917 , 617 , 4059 , 2599 ,0 }; - static ulong[] dim630KuoInit = { 1 , 1 , 7 , 9 , 19 , 25 , 119 , 103 , 115 , 247 , 1265 , 859 , 5543 ,0 }; - static ulong[] dim631KuoInit = { 1 , 1 , 7 , 7 , 15 , 27 , 45 , 29 , 67 , 989 , 753 , 3215 , 6281 ,0 }; - static ulong[] dim632KuoInit = { 1 , 3 , 1 , 7 , 11 , 15 , 35 , 39 , 61 , 483 , 1427 , 193 , 3469 ,0 }; - static ulong[] dim633KuoInit = { 1 , 3 , 5 , 9 , 21 , 41 , 21 , 223 , 233 , 341 , 177 , 1167 , 3101 ,0 }; - static ulong[] dim634KuoInit = { 1 , 3 , 3 , 5 , 19 , 25 , 53 , 247 , 29 , 909 , 2047 , 1683 , 4433 ,0 }; - static ulong[] dim635KuoInit = { 1 , 3 , 3 , 9 , 31 , 7 , 71 , 85 , 501 , 447 , 113 , 3465 , 3445 ,0 }; - static ulong[] dim636KuoInit = { 1 , 1 , 3 , 15 , 19 , 9 , 127 , 69 , 429 , 451 , 531 , 1319 , 507 ,0 }; - static ulong[] dim637KuoInit = { 1 , 3 , 1 , 3 , 29 , 1 , 53 , 63 , 267 , 293 , 333 , 2749 , 1785 ,0 }; - static ulong[] dim638KuoInit = { 1 , 3 , 1 , 7 , 5 , 43 , 71 , 165 , 325 , 309 , 921 , 2277 , 6423 ,0 }; - static ulong[] dim639KuoInit = { 1 , 1 , 7 , 5 , 23 , 31 , 63 , 35 , 221 , 733 , 1901 , 153 , 3577 ,0 }; - static ulong[] dim640KuoInit = { 1 , 3 , 7 , 11 , 7 , 5 , 39 , 141 , 293 , 237 , 501 , 1759 , 7763 ,0 }; - static ulong[] dim641KuoInit = { 1 , 1 , 3 , 15 , 1 , 49 , 5 , 7 , 239 , 1021 , 1215 , 3857 , 4637 ,0 }; - static ulong[] dim642KuoInit = { 1 , 1 , 5 , 1 , 1 , 31 , 77 , 243 , 155 , 505 , 855 , 3117 , 815 ,0 }; - static ulong[] dim643KuoInit = { 1 , 1 , 7 , 3 , 3 , 33 , 55 , 249 , 185 , 443 , 543 , 1333 , 5041 ,0 }; - static ulong[] dim644KuoInit = { 1 , 3 , 5 , 11 , 13 , 13 , 83 , 55 , 443 , 723 , 135 , 3073 , 4215 ,0 }; - static ulong[] dim645KuoInit = { 1 , 3 , 5 , 9 , 15 , 5 , 13 , 209 , 313 , 891 , 431 , 4009 , 7531 ,0 }; - static ulong[] dim646KuoInit = { 1 , 1 , 5 , 15 , 13 , 37 , 91 , 117 , 321 , 791 , 2045 , 4073 , 6787 ,0 }; - static ulong[] dim647KuoInit = { 1 , 1 , 3 , 7 , 1 , 43 , 61 , 121 , 393 , 797 , 1347 , 491 , 341 ,0 }; - static ulong[] dim648KuoInit = { 1 , 1 , 7 , 3 , 1 , 31 , 63 , 205 , 43 , 359 , 325 , 3329 , 4961 ,0 }; - static ulong[] dim649KuoInit = { 1 , 1 , 7 , 11 , 27 , 21 , 83 , 151 , 97 , 45 , 1839 , 3221 , 2575 ,0 }; - static ulong[] dim650KuoInit = { 1 , 3 , 7 , 3 , 13 , 7 , 97 , 89 , 277 , 351 , 1493 , 1161 , 6629 ,0 }; - static ulong[] dim651KuoInit = { 1 , 3 , 7 , 11 , 27 , 17 , 19 , 211 , 373 , 73 , 1325 , 183 , 1073 ,0 }; - static ulong[] dim652KuoInit = { 1 , 3 , 3 , 13 , 9 , 23 , 111 , 235 , 153 , 857 , 1669 , 3423 , 3817 ,0 }; - static ulong[] dim653KuoInit = { 1 , 1 , 1 , 5 , 25 , 63 , 99 , 11 , 283 , 755 , 999 , 2795 , 7795 ,0 }; - static ulong[] dim654KuoInit = { 1 , 1 , 5 , 11 , 3 , 53 , 127 , 73 , 61 , 91 , 1099 , 921 , 1787 ,0 }; - static ulong[] dim655KuoInit = { 1 , 3 , 5 , 1 , 9 , 39 , 9 , 181 , 287 , 545 , 1343 , 2587 , 961 ,0 }; - static ulong[] dim656KuoInit = { 1 , 3 , 7 , 5 , 9 , 47 , 7 , 113 , 69 , 531 , 753 , 2225 , 5705 ,0 }; - static ulong[] dim657KuoInit = { 1 , 1 , 3 , 13 , 29 , 39 , 71 , 223 , 179 , 871 , 1743 , 2645 , 7355 ,0 }; - static ulong[] dim658KuoInit = { 1 , 1 , 7 , 5 , 1 , 41 , 87 , 251 , 303 , 271 , 791 , 2825 , 2723 ,0 }; - static ulong[] dim659KuoInit = { 1 , 3 , 1 , 11 , 31 , 15 , 119 , 127 , 451 , 161 , 1909 , 3591 , 2811 ,0 }; - static ulong[] dim660KuoInit = { 1 , 1 , 3 , 13 , 31 , 27 , 111 , 119 , 423 , 419 , 1659 , 941 , 6123 ,0 }; - static ulong[] dim661KuoInit = { 1 , 1 , 1 , 7 , 27 , 39 , 27 , 61 , 417 , 629 , 1411 , 1489 , 5915 ,0 }; - static ulong[] dim662KuoInit = { 1 , 3 , 3 , 1 , 29 , 37 , 111 , 13 , 129 , 831 , 1423 , 3859 , 7009 ,0 }; - static ulong[] dim663KuoInit = { 1 , 1 , 1 , 3 , 3 , 51 , 67 , 45 , 289 , 715 , 183 , 357 , 3661 ,0 }; - static ulong[] dim664KuoInit = { 1 , 3 , 3 , 1 , 23 , 49 , 55 , 99 , 77 , 795 , 429 , 1815 , 1867 ,0 }; - static ulong[] dim665KuoInit = { 1 , 1 , 5 , 7 , 1 , 37 , 45 , 27 , 57 , 937 , 1583 , 899 , 819 ,0 }; - static ulong[] dim666KuoInit = { 1 , 3 , 5 , 7 , 7 , 37 , 1 , 109 , 217 , 203 , 207 , 2243 , 2337 ,0 }; - static ulong[] dim667KuoInit = { 1 , 1 , 3 , 15 , 27 , 51 , 119 , 45 , 289 , 395 , 95 , 2425 , 7421 ,0 }; - static ulong[] dim668KuoInit = { 1 , 3 , 1 , 9 , 27 , 61 , 41 , 227 , 279 , 31 , 1105 , 153 , 5045 ,0 }; - static ulong[] dim669KuoInit = { 1 , 1 , 7 , 15 , 31 , 43 , 109 , 67 , 347 , 611 , 1811 , 2969 , 3545 ,0 }; - static ulong[] dim670KuoInit = { 1 , 3 , 1 , 7 , 17 , 15 , 103 , 35 , 407 , 935 , 1159 , 2357 , 6559 ,0 }; - static ulong[] dim671KuoInit = { 1 , 1 , 1 , 7 , 5 , 7 , 101 , 43 , 301 , 189 , 641 , 3015 , 6955 ,0 }; - static ulong[] dim672KuoInit = { 1 , 3 , 1 , 1 , 3 , 41 , 61 , 43 , 213 , 595 , 955 , 377 , 7527 ,0 }; - static ulong[] dim673KuoInit = { 1 , 3 , 3 , 15 , 19 , 45 , 59 , 57 , 425 , 683 , 1187 , 221 , 4265 ,0 }; - static ulong[] dim674KuoInit = { 1 , 3 , 5 , 3 , 27 , 47 , 85 , 73 , 67 , 509 , 555 , 3887 , 1883 ,0 }; - static ulong[] dim675KuoInit = { 1 , 3 , 5 , 13 , 19 , 45 , 83 , 191 , 117 , 723 , 701 , 2783 , 389 ,0 }; - static ulong[] dim676KuoInit = { 1 , 1 , 1 , 3 , 17 , 21 , 125 , 13 , 387 , 613 , 1647 , 2555 , 2435 ,0 }; - static ulong[] dim677KuoInit = { 1 , 3 , 3 , 11 , 21 , 53 , 105 , 5 , 493 , 167 , 1195 , 2815 , 5761 ,0 }; - static ulong[] dim678KuoInit = { 1 , 1 , 1 , 7 , 27 , 17 , 107 , 83 , 31 , 787 , 1541 , 3761 , 4083 ,0 }; - static ulong[] dim679KuoInit = { 1 , 3 , 5 , 11 , 5 , 15 , 17 , 219 , 273 , 207 , 119 , 1693 , 373 ,0 }; - static ulong[] dim680KuoInit = { 1 , 1 , 5 , 15 , 7 , 11 , 9 , 103 , 253 , 377 , 1667 , 1159 , 5669 ,0 }; - static ulong[] dim681KuoInit = { 1 , 3 , 7 , 5 , 17 , 55 , 23 , 77 , 341 , 419 , 1165 , 1625 , 6609 ,0 }; - static ulong[] dim682KuoInit = { 1 , 3 , 1 , 15 , 29 , 7 , 101 , 183 , 181 , 111 , 751 , 247 , 4205 ,0 }; - static ulong[] dim683KuoInit = { 1 , 1 , 1 , 11 , 3 , 5 , 91 , 43 , 247 , 661 , 621 , 2791 , 4245 ,0 }; - static ulong[] dim684KuoInit = { 1 , 1 , 1 , 11 , 11 , 63 , 25 , 239 , 39 , 311 , 1603 , 1179 , 4959 ,0 }; - static ulong[] dim685KuoInit = { 1 , 3 , 1 , 7 , 23 , 61 , 49 , 99 , 287 , 251 , 1053 , 3819 , 5575 ,0 }; - static ulong[] dim686KuoInit = { 1 , 1 , 1 , 7 , 21 , 17 , 33 , 163 , 503 , 537 , 1159 , 2473 , 8113 ,0 }; - static ulong[] dim687KuoInit = { 1 , 1 , 5 , 13 , 23 , 57 , 57 , 89 , 503 , 299 , 1319 , 2177 , 8155 ,0 }; - static ulong[] dim688KuoInit = { 1 , 3 , 3 , 5 , 5 , 5 , 61 , 103 , 247 , 339 , 1137 , 3717 , 747 ,0 }; - static ulong[] dim689KuoInit = { 1 , 3 , 1 , 7 , 17 , 55 , 41 , 155 , 363 , 873 , 59 , 2093 , 4255 ,0 }; - static ulong[] dim690KuoInit = { 1 , 3 , 3 , 7 , 9 , 25 , 93 , 87 , 479 , 477 , 2047 , 321 , 2277 ,0 }; - static ulong[] dim691KuoInit = { 1 , 1 , 3 , 11 , 7 , 37 , 41 , 237 , 121 , 187 , 929 , 1823 , 313 ,0 }; - static ulong[] dim692KuoInit = { 1 , 1 , 1 , 11 , 29 , 41 , 79 , 11 , 295 , 715 , 979 , 2649 , 915 ,0 }; - static ulong[] dim693KuoInit = { 1 , 1 , 3 , 13 , 5 , 9 , 55 , 159 , 343 , 887 , 235 , 53 , 593 ,0 }; - static ulong[] dim694KuoInit = { 1 , 1 , 1 , 3 , 13 , 23 , 105 , 125 , 405 , 521 , 897 , 559 , 1561 ,0 }; - static ulong[] dim695KuoInit = { 1 , 1 , 3 , 9 , 23 , 33 , 121 , 183 , 181 , 141 , 1103 , 821 , 7193 ,0 }; - static ulong[] dim696KuoInit = { 1 , 1 , 3 , 9 , 23 , 1 , 113 , 63 , 59 , 783 , 1525 , 115 , 3193 ,0 }; - static ulong[] dim697KuoInit = { 1 , 3 , 1 , 9 , 23 , 29 , 83 , 237 , 83 , 477 , 1163 , 2951 , 3523 ,0 }; - static ulong[] dim698KuoInit = { 1 , 3 , 5 , 1 , 21 , 25 , 55 , 79 , 39 , 45 , 1509 , 2127 , 5259 ,0 }; - static ulong[] dim699KuoInit = { 1 , 1 , 7 , 9 , 31 , 61 , 83 , 145 , 89 , 723 , 393 , 1543 , 7765 ,0 }; - static ulong[] dim700KuoInit = { 1 , 1 , 5 , 15 , 21 , 17 , 73 , 189 , 473 , 1023 , 1627 , 2305 , 7127 ,0 }; - static ulong[] dim701KuoInit = { 1 , 3 , 1 , 7 , 7 , 23 , 61 , 203 , 373 , 941 , 975 , 3225 , 7659 ,0 }; - static ulong[] dim702KuoInit = { 1 , 3 , 1 , 15 , 31 , 19 , 99 , 197 , 113 , 131 , 263 , 2427 , 2085 ,0 }; - static ulong[] dim703KuoInit = { 1 , 1 , 1 , 13 , 25 , 27 , 3 , 139 , 351 , 267 , 1583 , 913 , 5497 ,0 }; - static ulong[] dim704KuoInit = { 1 , 3 , 5 , 11 , 7 , 1 , 65 , 85 , 271 , 151 , 1003 , 889 , 6127 ,0 }; - static ulong[] dim705KuoInit = { 1 , 3 , 7 , 5 , 21 , 27 , 39 , 147 , 139 , 81 , 1377 , 1969 , 6171 ,0 }; - static ulong[] dim706KuoInit = { 1 , 3 , 5 , 13 , 1 , 11 , 101 , 27 , 285 , 939 , 1055 , 3237 , 7063 ,0 }; - static ulong[] dim707KuoInit = { 1 , 3 , 3 , 7 , 23 , 43 , 67 , 89 , 201 , 393 , 277 , 3531 , 4003 ,0 }; - static ulong[] dim708KuoInit = { 1 , 3 , 7 , 9 , 3 , 13 , 103 , 241 , 161 , 111 , 61 , 4001 , 6291 ,0 }; - static ulong[] dim709KuoInit = { 1 , 1 , 5 , 7 , 5 , 27 , 57 , 87 , 313 , 471 , 227 , 1395 , 2821 ,0 }; - static ulong[] dim710KuoInit = { 1 , 3 , 1 , 5 , 11 , 35 , 11 , 157 , 257 , 679 , 245 , 329 , 2423 ,0 }; - static ulong[] dim711KuoInit = { 1 , 1 , 7 , 11 , 15 , 5 , 29 , 229 , 365 , 911 , 477 , 219 , 4851 ,0 }; - static ulong[] dim712KuoInit = { 1 , 3 , 1 , 9 , 5 , 57 , 87 , 19 , 93 , 403 , 1729 , 1843 , 7301 ,0 }; - static ulong[] dim713KuoInit = { 1 , 1 , 3 , 3 , 27 , 29 , 11 , 99 , 149 , 917 , 709 , 3761 , 6947 ,0 }; - static ulong[] dim714KuoInit = { 1 , 1 , 5 , 1 , 19 , 63 , 69 , 71 , 209 , 423 , 2015 , 3905 , 2077 ,0 }; - static ulong[] dim715KuoInit = { 1 , 3 , 7 , 7 , 7 , 3 , 9 , 63 , 137 , 781 , 1825 , 1331 , 2987 ,0 }; - static ulong[] dim716KuoInit = { 1 , 3 , 7 , 11 , 15 , 23 , 7 , 205 , 27 , 619 , 225 , 297 , 8179 ,0 }; - static ulong[] dim717KuoInit = { 1 , 3 , 3 , 13 , 11 , 15 , 11 , 185 , 343 , 269 , 1415 , 843 , 4001 ,0 }; - static ulong[] dim718KuoInit = { 1 , 3 , 3 , 1 , 15 , 47 , 101 , 49 , 25 , 933 , 903 , 1927 , 6641 ,0 }; - static ulong[] dim719KuoInit = { 1 , 3 , 3 , 13 , 7 , 45 , 29 , 51 , 143 , 549 , 119 , 235 , 7345 ,0 }; - static ulong[] dim720KuoInit = { 1 , 1 , 3 , 9 , 29 , 45 , 53 , 133 , 173 , 543 , 545 , 2015 , 149 ,0 }; - static ulong[] dim721KuoInit = { 1 , 1 , 3 , 11 , 3 , 3 , 109 , 193 , 349 , 243 , 1381 , 3547 , 4387 ,0 }; - static ulong[] dim722KuoInit = { 1 , 3 , 7 , 9 , 7 , 3 , 37 , 121 , 79 , 59 , 1453 , 3273 , 477 ,0 }; - static ulong[] dim723KuoInit = { 1 , 3 , 5 , 15 , 19 , 15 , 83 , 5 , 203 , 603 , 373 , 955 , 1587 ,0 }; - static ulong[] dim724KuoInit = { 1 , 1 , 5 , 11 , 25 , 41 , 89 , 47 , 313 , 443 , 1799 , 1827 , 5881 ,0 }; - static ulong[] dim725KuoInit = { 1 , 1 , 3 , 5 , 9 , 7 , 15 , 87 , 285 , 509 , 289 , 855 , 3131 ,0 }; - static ulong[] dim726KuoInit = { 1 , 1 , 3 , 11 , 13 , 57 , 41 , 235 , 357 , 213 , 1867 , 1961 , 2759 ,0 }; - static ulong[] dim727KuoInit = { 1 , 3 , 5 , 9 , 25 , 15 , 111 , 197 , 479 , 539 , 1833 , 105 , 7245 ,0 }; - static ulong[] dim728KuoInit = { 1 , 1 , 5 , 5 , 23 , 47 , 101 , 97 , 97 , 261 , 1301 , 3895 , 5425 ,0 }; - static ulong[] dim729KuoInit = { 1 , 1 , 7 , 11 , 13 , 49 , 39 , 233 , 7 , 965 , 2015 , 1341 , 941 ,0 }; - static ulong[] dim730KuoInit = { 1 , 1 , 5 , 7 , 19 , 63 , 91 , 77 , 469 , 367 , 1849 , 1213 , 7611 ,0 }; - static ulong[] dim731KuoInit = { 1 , 3 , 3 , 15 , 17 , 57 , 27 , 107 , 133 , 431 , 445 , 2885 , 5963 ,0 }; - static ulong[] dim732KuoInit = { 1 , 1 , 3 , 1 , 27 , 37 , 119 , 241 , 403 , 239 , 833 , 3057 , 5557 ,0 }; - static ulong[] dim733KuoInit = { 1 , 3 , 3 , 13 , 11 , 47 , 35 , 41 , 243 , 143 , 1923 , 1883 , 2543 ,0 }; - static ulong[] dim734KuoInit = { 1 , 1 , 5 , 5 , 3 , 15 , 45 , 205 , 179 , 515 , 161 , 895 , 3679 ,0 }; - static ulong[] dim735KuoInit = { 1 , 3 , 1 , 1 , 5 , 39 , 99 , 221 , 115 , 983 , 1913 , 665 , 7835 ,0 }; - static ulong[] dim736KuoInit = { 1 , 3 , 5 , 15 , 5 , 5 , 111 , 45 , 373 , 143 , 1107 , 1413 , 2935 ,0 }; - static ulong[] dim737KuoInit = { 1 , 3 , 7 , 11 , 17 , 53 , 77 , 159 , 319 , 279 , 835 , 139 , 3633 ,0 }; - static ulong[] dim738KuoInit = { 1 , 1 , 7 , 15 , 5 , 57 , 105 , 139 , 491 , 409 , 51 , 2875 , 427 ,0 }; - static ulong[] dim739KuoInit = { 1 , 1 , 1 , 9 , 9 , 9 , 93 , 45 , 265 , 307 , 589 , 557 , 3971 ,0 }; - static ulong[] dim740KuoInit = { 1 , 3 , 5 , 3 , 23 , 45 , 5 , 9 , 123 , 841 , 679 , 2213 , 4507 ,0 }; - static ulong[] dim741KuoInit = { 1 , 3 , 5 , 3 , 27 , 55 , 55 , 19 , 405 , 43 , 1897 , 3515 , 683 ,0 }; - static ulong[] dim742KuoInit = { 1 , 1 , 7 , 15 , 23 , 47 , 121 , 105 , 341 , 707 , 799 , 1843 , 7011 ,0 }; - static ulong[] dim743KuoInit = { 1 , 1 , 3 , 13 , 23 , 51 , 71 , 161 , 415 , 819 , 729 , 297 , 4461 ,0 }; - static ulong[] dim744KuoInit = { 1 , 3 , 5 , 15 , 13 , 39 , 43 , 103 , 251 , 583 , 775 , 877 , 4947 ,0 }; - static ulong[] dim745KuoInit = { 1 , 3 , 7 , 5 , 19 , 61 , 121 , 49 , 75 , 963 , 297 , 3751 , 911 ,0 }; - static ulong[] dim746KuoInit = { 1 , 3 , 5 , 7 , 15 , 51 , 23 , 23 , 453 , 675 , 1575 , 473 , 3763 ,0 }; - static ulong[] dim747KuoInit = { 1 , 1 , 7 , 11 , 9 , 37 , 69 , 137 , 251 , 89 , 1823 , 1289 , 2983 ,0 }; - static ulong[] dim748KuoInit = { 1 , 3 , 3 , 5 , 11 , 39 , 39 , 231 , 427 , 633 , 1453 , 579 , 5823 ,0 }; - static ulong[] dim749KuoInit = { 1 , 3 , 7 , 11 , 31 , 57 , 87 , 81 , 161 , 929 , 1293 , 3215 , 4803 ,0 }; - static ulong[] dim750KuoInit = { 1 , 3 , 5 , 5 , 27 , 33 , 11 , 151 , 25 , 1017 , 41 , 61 , 4381 ,0 }; - static ulong[] dim751KuoInit = { 1 , 3 , 1 , 15 , 23 , 25 , 7 , 21 , 231 , 407 , 817 , 2089 , 839 ,0 }; - static ulong[] dim752KuoInit = { 1 , 1 , 7 , 1 , 5 , 51 , 117 , 59 , 251 , 861 , 727 , 481 , 2207 ,0 }; - static ulong[] dim753KuoInit = { 1 , 1 , 5 , 3 , 21 , 19 , 97 , 199 , 135 , 203 , 1177 , 2751 , 2863 ,0 }; - static ulong[] dim754KuoInit = { 1 , 3 , 7 , 3 , 27 , 3 , 5 , 109 , 17 , 933 , 911 , 921 , 1173 ,0 }; - static ulong[] dim755KuoInit = { 1 , 3 , 7 , 1 , 7 , 1 , 121 , 205 , 381 , 971 , 255 , 3313 , 5479 ,0 }; - static ulong[] dim756KuoInit = { 1 , 3 , 1 , 1 , 17 , 59 , 3 , 5 , 271 , 149 , 111 , 3707 , 7893 ,0 }; - static ulong[] dim757KuoInit = { 1 , 1 , 1 , 1 , 17 , 61 , 47 , 117 , 187 , 839 , 435 , 399 , 3173 ,0 }; - static ulong[] dim758KuoInit = { 1 , 3 , 3 , 7 , 5 , 9 , 119 , 191 , 197 , 791 , 375 , 3361 , 6677 ,0 }; - static ulong[] dim759KuoInit = { 1 , 1 , 5 , 3 , 21 , 49 , 69 , 249 , 39 , 69 , 673 , 109 , 7051 ,0 }; - static ulong[] dim760KuoInit = { 1 , 1 , 3 , 11 , 21 , 37 , 121 , 93 , 261 , 5 , 1269 , 767 , 2801 ,0 }; - static ulong[] dim761KuoInit = { 1 , 1 , 5 , 9 , 31 , 49 , 9 , 87 , 375 , 773 , 1517 , 3057 , 2169 ,0 }; - static ulong[] dim762KuoInit = { 1 , 1 , 5 , 3 , 13 , 33 , 31 , 87 , 353 , 991 , 1809 , 859 , 6117 ,0 }; - static ulong[] dim763KuoInit = { 1 , 1 , 5 , 11 , 3 , 21 , 103 , 41 , 129 , 137 , 1567 , 3483 , 5317 ,0 }; - static ulong[] dim764KuoInit = { 1 , 3 , 5 , 1 , 3 , 31 , 5 , 15 , 109 , 723 , 1439 , 2543 , 2377 ,0 }; - static ulong[] dim765KuoInit = { 1 , 3 , 3 , 13 , 11 , 17 , 9 , 243 , 233 , 543 , 903 , 2775 , 6877 ,0 }; - static ulong[] dim766KuoInit = { 1 , 1 , 7 , 1 , 23 , 45 , 61 , 137 , 207 , 457 , 245 , 3833 , 6533 ,0 }; - static ulong[] dim767KuoInit = { 1 , 3 , 1 , 1 , 31 , 7 , 71 , 153 , 501 , 749 , 1477 , 621 , 6577 ,0 }; - static ulong[] dim768KuoInit = { 1 , 3 , 1 , 13 , 3 , 45 , 3 , 233 , 85 , 847 , 1031 , 141 , 5029 ,0 }; - static ulong[] dim769KuoInit = { 1 , 3 , 1 , 13 , 17 , 35 , 49 , 157 , 243 , 175 , 905 , 539 , 8059 ,0 }; - static ulong[] dim770KuoInit = { 1 , 3 , 1 , 11 , 19 , 45 , 31 , 49 , 399 , 341 , 2047 , 1527 , 5993 ,0 }; - static ulong[] dim771KuoInit = { 1 , 3 , 1 , 3 , 5 , 5 , 33 , 163 , 239 , 607 , 1367 , 2747 , 1513 ,0 }; - static ulong[] dim772KuoInit = { 1 , 3 , 3 , 11 , 9 , 29 , 33 , 255 , 29 , 955 , 367 , 1709 , 4993 ,0 }; - static ulong[] dim773KuoInit = { 1 , 3 , 7 , 5 , 19 , 35 , 11 , 47 , 109 , 235 , 1125 , 4019 , 5395 ,0 }; - static ulong[] dim774KuoInit = { 1 , 1 , 7 , 1 , 19 , 29 , 43 , 1 , 199 , 479 , 1025 , 1065 , 2203 ,0 }; - static ulong[] dim775KuoInit = { 1 , 3 , 1 , 9 , 17 , 13 , 45 , 167 , 125 , 869 , 1667 , 1083 , 4015 ,0 }; - static ulong[] dim776KuoInit = { 1 , 1 , 5 , 11 , 27 , 45 , 115 , 199 , 375 , 761 , 1641 , 3761 , 5509 ,0 }; - static ulong[] dim777KuoInit = { 1 , 1 , 7 , 15 , 9 , 47 , 47 , 133 , 401 , 555 , 1077 , 1381 , 1903 ,0 }; - static ulong[] dim778KuoInit = { 1 , 3 , 3 , 15 , 3 , 45 , 19 , 49 , 377 , 135 , 239 , 3605 , 1053 ,0 }; - static ulong[] dim779KuoInit = { 1 , 3 , 1 , 11 , 17 , 5 , 83 , 101 , 247 , 267 , 1337 , 2649 , 513 ,0 }; - static ulong[] dim780KuoInit = { 1 , 3 , 1 , 11 , 13 , 41 , 41 , 113 , 243 , 463 , 1077 , 565 , 2871 ,0 }; - static ulong[] dim781KuoInit = { 1 , 3 , 5 , 11 , 19 , 63 , 81 , 51 , 139 , 921 , 2021 , 417 , 1305 ,0 }; - static ulong[] dim782KuoInit = { 1 , 3 , 3 , 1 , 23 , 61 , 13 , 123 , 135 , 521 , 1963 , 3085 , 4395 ,0 }; - static ulong[] dim783KuoInit = { 1 , 3 , 1 , 1 , 15 , 61 , 17 , 245 , 479 , 77 , 287 , 3043 , 2647 ,0 }; - static ulong[] dim784KuoInit = { 1 , 1 , 7 , 15 , 29 , 5 , 125 , 123 , 149 , 919 , 1779 , 3763 , 1479 ,0 }; - static ulong[] dim785KuoInit = { 1 , 1 , 3 , 1 , 19 , 49 , 27 , 127 , 253 , 279 , 739 , 147 , 6835 ,0 }; - static ulong[] dim786KuoInit = { 1 , 3 , 5 , 11 , 21 , 27 , 33 , 85 , 419 , 441 , 1341 , 289 , 2759 ,0 }; - static ulong[] dim787KuoInit = { 1 , 3 , 1 , 3 , 3 , 9 , 17 , 99 , 375 , 251 , 1823 , 2433 , 1525 ,0 }; - static ulong[] dim788KuoInit = { 1 , 3 , 1 , 3 , 5 , 55 , 25 , 225 , 473 , 825 , 1061 , 2987 , 4397 ,0 }; - static ulong[] dim789KuoInit = { 1 , 1 , 7 , 15 , 23 , 59 , 9 , 163 , 105 , 911 , 905 , 3715 , 4917 ,0 }; - static ulong[] dim790KuoInit = { 1 , 3 , 1 , 11 , 21 , 53 , 127 , 3 , 507 , 467 , 547 , 3003 , 6939 ,0 }; - static ulong[] dim791KuoInit = { 1 , 1 , 1 , 13 , 15 , 7 , 1 , 7 , 101 , 645 , 1469 , 843 , 2843 ,0 }; - static ulong[] dim792KuoInit = { 1 , 3 , 3 , 9 , 11 , 35 , 95 , 53 , 291 , 459 , 669 , 1163 , 4893 ,0 }; - static ulong[] dim793KuoInit = { 1 , 1 , 3 , 3 , 25 , 29 , 29 , 223 , 21 , 553 , 177 , 3347 , 3575 ,0 }; - static ulong[] dim794KuoInit = { 1 , 1 , 5 , 1 , 23 , 17 , 21 , 57 , 383 , 427 , 397 , 1947 , 2627 ,0 }; - static ulong[] dim795KuoInit = { 1 , 3 , 7 , 1 , 21 , 53 , 79 , 59 , 133 , 461 , 1703 , 3071 , 4679 ,0 }; - static ulong[] dim796KuoInit = { 1 , 3 , 5 , 1 , 27 , 31 , 83 , 159 , 505 , 121 , 1969 , 1073 , 2117 ,0 }; - static ulong[] dim797KuoInit = { 1 , 1 , 3 , 1 , 19 , 25 , 43 , 115 , 191 , 845 , 1923 , 903 , 2319 ,0 }; - static ulong[] dim798KuoInit = { 1 , 1 , 3 , 9 , 27 , 37 , 31 , 111 , 437 , 925 , 501 , 883 , 3485 ,0 }; - static ulong[] dim799KuoInit = { 1 , 3 , 5 , 5 , 15 , 25 , 51 , 131 , 149 , 811 , 1827 , 1519 , 1435 ,0 }; - static ulong[] dim800KuoInit = { 1 , 1 , 7 , 13 , 3 , 39 , 103 , 107 , 473 , 553 , 1763 , 399 , 2137 ,0 }; - static ulong[] dim801KuoInit = { 1 , 3 , 7 , 13 , 27 , 25 , 49 , 29 , 497 , 863 , 1715 , 99 , 1521 ,0 }; - static ulong[] dim802KuoInit = { 1 , 1 , 1 , 9 , 27 , 37 , 67 , 59 , 11 , 369 , 893 , 2249 , 5303 ,0 }; - static ulong[] dim803KuoInit = { 1 , 3 , 3 , 13 , 19 , 9 , 93 , 29 , 247 , 35 , 833 , 1037 , 7137 ,0 }; - static ulong[] dim804KuoInit = { 1 , 3 , 7 , 3 , 25 , 17 , 63 , 239 , 395 , 367 , 1935 , 2095 , 5191 ,0 }; - static ulong[] dim805KuoInit = { 1 , 3 , 5 , 15 , 23 , 51 , 13 , 101 , 477 , 511 , 1951 , 2505 , 4155 ,0 }; - static ulong[] dim806KuoInit = { 1 , 3 , 3 , 15 , 3 , 55 , 15 , 173 , 21 , 699 , 1617 , 1573 , 2645 ,0 }; - static ulong[] dim807KuoInit = { 1 , 1 , 3 , 11 , 7 , 55 , 69 , 165 , 255 , 397 , 2033 , 9 , 843 ,0 }; - static ulong[] dim808KuoInit = { 1 , 3 , 1 , 13 , 5 , 3 , 37 , 99 , 165 , 971 , 555 , 2379 , 7879 ,0 }; - static ulong[] dim809KuoInit = { 1 , 1 , 5 , 3 , 19 , 37 , 23 , 197 , 145 , 315 , 981 , 161 , 323 ,0 }; - static ulong[] dim810KuoInit = { 1 , 1 , 7 , 7 , 17 , 37 , 27 , 189 , 371 , 145 , 1097 , 2801 , 5469 ,0 }; - static ulong[] dim811KuoInit = { 1 , 1 , 3 , 9 , 23 , 15 , 39 , 7 , 25 , 221 , 757 , 1393 , 4629 ,0 }; - static ulong[] dim812KuoInit = { 1 , 1 , 1 , 1 , 13 , 31 , 29 , 197 , 237 , 173 , 337 , 743 , 1459 ,0 }; - static ulong[] dim813KuoInit = { 1 , 1 , 5 , 15 , 17 , 7 , 127 , 29 , 307 , 965 , 1567 , 2771 , 6053 ,0 }; - static ulong[] dim814KuoInit = { 1 , 3 , 1 , 1 , 13 , 57 , 41 , 59 , 77 , 67 , 1985 , 3443 , 7495 ,0 }; - static ulong[] dim815KuoInit = { 1 , 3 , 7 , 15 , 17 , 21 , 57 , 143 , 179 , 99 , 217 , 1763 , 873 ,0 }; - static ulong[] dim816KuoInit = { 1 , 1 , 7 , 1 , 21 , 17 , 123 , 39 , 95 , 775 , 1865 , 341 , 6167 ,0 }; - static ulong[] dim817KuoInit = { 1 , 3 , 7 , 3 , 31 , 33 , 33 , 163 , 281 , 765 , 1809 , 1469 , 7011 ,0 }; - static ulong[] dim818KuoInit = { 1 , 3 , 7 , 7 , 25 , 35 , 45 , 109 , 221 , 25 , 757 , 597 , 3057 ,0 }; - static ulong[] dim819KuoInit = { 1 , 3 , 5 , 3 , 27 , 25 , 97 , 21 , 351 , 841 , 1339 , 565 , 7181 ,0 }; - static ulong[] dim820KuoInit = { 1 , 1 , 1 , 15 , 23 , 61 , 97 , 57 , 503 , 379 , 25 , 1197 , 6957 ,0 }; - static ulong[] dim821KuoInit = { 1 , 3 , 3 , 3 , 13 , 49 , 127 , 89 , 329 , 503 , 1957 , 3569 , 7013 ,0 }; - static ulong[] dim822KuoInit = { 1 , 1 , 7 , 7 , 7 , 15 , 43 , 61 , 227 , 859 , 279 , 3309 , 1941 ,0 }; - static ulong[] dim823KuoInit = { 1 , 3 , 1 , 9 , 19 , 1 , 111 , 45 , 315 , 339 , 1049 , 121 , 2711 ,0 }; - static ulong[] dim824KuoInit = { 1 , 1 , 3 , 11 , 7 , 33 , 121 , 253 , 267 , 845 , 1677 , 569 , 3743 ,0 }; - static ulong[] dim825KuoInit = { 1 , 3 , 7 , 9 , 9 , 53 , 113 , 11 , 177 , 165 , 1707 , 2027 , 2099 ,0 }; - static ulong[] dim826KuoInit = { 1 , 1 , 5 , 7 , 19 , 41 , 33 , 129 , 389 , 249 , 1945 , 1393 , 5941 ,0 }; - static ulong[] dim827KuoInit = { 1 , 1 , 1 , 1 , 27 , 37 , 63 , 171 , 301 , 179 , 223 , 3775 , 1189 ,0 }; - static ulong[] dim828KuoInit = { 1 , 3 , 3 , 5 , 5 , 33 , 101 , 37 , 505 , 561 , 1681 , 567 , 2197 ,0 }; - static ulong[] dim829KuoInit = { 1 , 3 , 7 , 13 , 25 , 23 , 29 , 27 , 325 , 757 , 5 , 487 , 3241 ,0 }; - static ulong[] dim830KuoInit = { 1 , 3 , 3 , 7 , 27 , 13 , 85 , 35 , 171 , 565 , 969 , 773 , 7173 ,0 }; - static ulong[] dim831KuoInit = { 1 , 3 , 5 , 5 , 11 , 55 , 33 , 243 , 401 , 939 , 73 , 775 , 1159 ,0 }; - static ulong[] dim832KuoInit = { 1 , 1 , 3 , 13 , 13 , 63 , 9 , 161 , 343 , 547 , 1659 , 1005 , 8041 ,0 }; - static ulong[] dim833KuoInit = { 1 , 3 , 5 , 7 , 15 , 27 , 27 , 51 , 475 , 957 , 445 , 3745 , 5113 ,0 }; - static ulong[] dim834KuoInit = { 1 , 1 , 3 , 7 , 15 , 49 , 63 , 181 , 15 , 1 , 1915 , 633 , 1039 ,0 }; - static ulong[] dim835KuoInit = { 1 , 3 , 7 , 1 , 1 , 11 , 15 , 221 , 375 , 59 , 1471 , 113 , 5661 ,0 }; - static ulong[] dim836KuoInit = { 1 , 3 , 5 , 5 , 11 , 41 , 115 , 87 , 263 , 173 , 1249 , 2235 , 6863 ,0 }; - static ulong[] dim837KuoInit = { 1 , 1 , 5 , 11 , 19 , 1 , 61 , 25 , 239 , 5 , 1869 , 2269 , 3911 ,0 }; - static ulong[] dim838KuoInit = { 1 , 3 , 5 , 7 , 23 , 59 , 99 , 47 , 439 , 105 , 455 , 547 , 2447 ,0 }; - static ulong[] dim839KuoInit = { 1 , 1 , 7 , 15 , 25 , 15 , 117 , 185 , 83 , 243 , 1099 , 2613 , 7721 ,0 }; - static ulong[] dim840KuoInit = { 1 , 3 , 1 , 9 , 5 , 49 , 27 , 237 , 239 , 177 , 1507 , 2059 , 1731 ,0 }; - static ulong[] dim841KuoInit = { 1 , 3 , 3 , 11 , 29 , 47 , 119 , 243 , 475 , 443 , 111 , 787 , 2597 ,0 }; - static ulong[] dim842KuoInit = { 1 , 1 , 7 , 1 , 25 , 39 , 95 , 107 , 391 , 149 , 397 , 3755 , 2735 ,0 }; - static ulong[] dim843KuoInit = { 1 , 3 , 7 , 11 , 13 , 49 , 37 , 135 , 99 , 473 , 1961 , 1233 , 7359 ,0 }; - static ulong[] dim844KuoInit = { 1 , 3 , 5 , 11 , 29 , 59 , 123 , 53 , 371 , 573 , 1099 , 3035 , 3217 ,0 }; - static ulong[] dim845KuoInit = { 1 , 1 , 1 , 11 , 25 , 47 , 105 , 147 , 317 , 69 , 1201 , 3781 , 2457 ,0 }; - static ulong[] dim846KuoInit = { 1 , 1 , 5 , 9 , 3 , 31 , 25 , 127 , 153 , 303 , 1367 , 3583 , 5229 ,0 }; - static ulong[] dim847KuoInit = { 1 , 1 , 3 , 13 , 25 , 33 , 11 , 101 , 85 , 741 , 1191 , 1769 , 4119 ,0 }; - static ulong[] dim848KuoInit = { 1 , 1 , 3 , 13 , 19 , 59 , 81 , 71 , 255 , 277 , 991 , 2183 , 3257 ,0 }; - static ulong[] dim849KuoInit = { 1 , 3 , 1 , 3 , 23 , 27 , 89 , 237 , 249 , 837 , 759 , 43 , 5571 ,0 }; - static ulong[] dim850KuoInit = { 1 , 1 , 1 , 9 , 15 , 35 , 45 , 213 , 423 , 159 , 353 , 3123 , 6399 ,0 }; - static ulong[] dim851KuoInit = { 1 , 1 , 5 , 9 , 15 , 45 , 83 , 65 , 115 , 513 , 361 , 1877 , 4307 ,0 }; - static ulong[] dim852KuoInit = { 1 , 1 , 7 , 11 , 17 , 61 , 15 , 143 , 491 , 253 , 443 , 3521 , 7611 ,0 }; - static ulong[] dim853KuoInit = { 1 , 1 , 3 , 11 , 11 , 49 , 117 , 117 , 279 , 715 , 1365 , 689 , 4339 ,0 }; - static ulong[] dim854KuoInit = { 1 , 1 , 3 , 13 , 3 , 53 , 123 , 89 , 91 , 471 , 1723 , 1811 , 1285 ,0 }; - static ulong[] dim855KuoInit = { 1 , 3 , 7 , 13 , 7 , 5 , 99 , 235 , 465 , 915 , 1813 , 3137 , 7645 ,0 }; - static ulong[] dim856KuoInit = { 1 , 3 , 3 , 13 , 5 , 45 , 37 , 99 , 459 , 541 , 225 , 2417 , 6385 ,0 }; - static ulong[] dim857KuoInit = { 1 , 1 , 1 , 15 , 19 , 39 , 109 , 21 , 117 , 589 , 1261 , 3695 , 4251 ,0 }; - static ulong[] dim858KuoInit = { 1 , 1 , 7 , 11 , 23 , 43 , 35 , 43 , 135 , 509 , 1331 , 1567 , 7085 ,0 }; - static ulong[] dim859KuoInit = { 1 , 1 , 5 , 5 , 23 , 3 , 61 , 151 , 171 , 295 , 1377 , 2165 , 2125 ,0 }; - static ulong[] dim860KuoInit = { 1 , 3 , 3 , 5 , 3 , 57 , 17 , 73 , 71 , 55 , 1373 , 2067 , 3249 ,0 }; - static ulong[] dim861KuoInit = { 1 , 1 , 5 , 9 , 25 , 39 , 65 , 75 , 141 , 849 , 237 , 3719 , 6705 ,0 }; - static ulong[] dim862KuoInit = { 1 , 1 , 7 , 1 , 17 , 17 , 23 , 91 , 333 , 749 , 657 , 3267 , 3343 ,0 }; - static ulong[] dim863KuoInit = { 1 , 3 , 1 , 5 , 5 , 27 , 15 , 107 , 345 , 405 , 111 , 345 , 5505 ,0 }; - static ulong[] dim864KuoInit = { 1 , 3 , 3 , 13 , 1 , 9 , 19 , 63 , 427 , 995 , 1257 , 923 , 267 ,0 }; - static ulong[] dim865KuoInit = { 1 , 1 , 1 , 7 , 21 , 19 , 65 , 249 , 401 , 729 , 1403 , 1579 , 3443 ,0 }; - static ulong[] dim866KuoInit = { 1 , 3 , 5 , 1 , 3 , 43 , 81 , 11 , 473 , 1011 , 1755 , 117 , 2881 ,0 }; - static ulong[] dim867KuoInit = { 1 , 1 , 7 , 13 , 3 , 63 , 95 , 11 , 23 , 895 , 1591 , 2623 , 6887 ,0 }; - static ulong[] dim868KuoInit = { 1 , 3 , 1 , 3 , 17 , 11 , 39 , 165 , 367 , 363 , 1207 , 2555 , 5437 ,0 }; - static ulong[] dim869KuoInit = { 1 , 1 , 1 , 7 , 17 , 9 , 19 , 175 , 7 , 535 , 1779 , 3341 , 4825 ,0 }; - static ulong[] dim870KuoInit = { 1 , 1 , 7 , 3 , 27 , 7 , 19 , 217 , 479 , 143 , 1189 , 2809 , 339 ,0 }; - static ulong[] dim871KuoInit = { 1 , 3 , 7 , 9 , 25 , 41 , 9 , 39 , 391 , 331 , 1427 , 2321 , 1673 ,0 }; - static ulong[] dim872KuoInit = { 1 , 3 , 1 , 13 , 7 , 17 , 11 , 27 , 125 , 799 , 1325 , 517 , 1043 ,0 }; - static ulong[] dim873KuoInit = { 1 , 1 , 3 , 15 , 29 , 11 , 73 , 11 , 289 , 1 , 839 , 3311 , 7535 ,0 }; - static ulong[] dim874KuoInit = { 1 , 1 , 1 , 11 , 11 , 59 , 25 , 47 , 153 , 297 , 679 , 1441 , 7105 ,0 }; - static ulong[] dim875KuoInit = { 1 , 3 , 5 , 7 , 25 , 29 , 13 , 227 , 379 , 247 , 449 , 679 , 6581 ,0 }; - static ulong[] dim876KuoInit = { 1 , 1 , 1 , 5 , 9 , 59 , 81 , 195 , 289 , 705 , 183 , 1 , 3703 ,0 }; - static ulong[] dim877KuoInit = { 1 , 3 , 3 , 9 , 31 , 1 , 71 , 155 , 307 , 467 , 1699 , 269 , 6077 ,0 }; - static ulong[] dim878KuoInit = { 1 , 3 , 1 , 11 , 31 , 21 , 59 , 225 , 385 , 623 , 117 , 1435 , 3195 ,0 }; - static ulong[] dim879KuoInit = { 1 , 1 , 7 , 9 , 3 , 43 , 97 , 15 , 145 , 279 , 1785 , 545 , 3977 ,0 }; - static ulong[] dim880KuoInit = { 1 , 1 , 5 , 9 , 25 , 27 , 113 , 193 , 31 , 255 , 691 , 3315 , 7005 ,0 }; - static ulong[] dim881KuoInit = { 1 , 3 , 7 , 5 , 9 , 19 , 69 , 87 , 379 , 931 , 1567 , 1391 , 4765 ,0 }; - static ulong[] dim882KuoInit = { 1 , 1 , 1 , 15 , 15 , 23 , 127 , 69 , 113 , 801 , 1923 , 2847 , 1073 ,0 }; - static ulong[] dim883KuoInit = { 1 , 1 , 1 , 1 , 21 , 51 , 65 , 133 , 465 , 739 , 2029 , 2243 , 4023 ,0 }; - static ulong[] dim884KuoInit = { 1 , 1 , 5 , 11 , 9 , 41 , 71 , 217 , 317 , 855 , 275 , 1965 , 3151 ,0 }; - static ulong[] dim885KuoInit = { 1 , 1 , 7 , 5 , 19 , 3 , 81 , 127 , 423 , 415 , 565 , 1941 , 5079 ,0 }; - static ulong[] dim886KuoInit = { 1 , 1 , 3 , 1 , 19 , 19 , 117 , 169 , 353 , 159 , 1235 , 845 , 2381 ,0 }; - static ulong[] dim887KuoInit = { 1 , 3 , 1 , 15 , 21 , 27 , 77 , 5 , 113 , 201 , 311 , 2263 , 7855 ,0 }; - static ulong[] dim888KuoInit = { 1 , 3 , 5 , 9 , 5 , 21 , 41 , 119 , 447 , 983 , 1703 , 2707 , 2789 ,0 }; - static ulong[] dim889KuoInit = { 1 , 1 , 5 , 3 , 5 , 19 , 9 , 131 , 269 , 999 , 1259 , 3843 , 7753 ,0 }; - static ulong[] dim890KuoInit = { 1 , 3 , 7 , 11 , 25 , 27 , 91 , 187 , 177 , 921 , 163 , 1141 , 4903 ,0 }; - static ulong[] dim891KuoInit = { 1 , 3 , 1 , 7 , 15 , 21 , 67 , 155 , 335 , 149 , 2011 , 2483 , 7015 ,0 }; - static ulong[] dim892KuoInit = { 1 , 1 , 1 , 7 , 3 , 53 , 29 , 119 , 21 , 933 , 595 , 3141 , 7925 ,0 }; - static ulong[] dim893KuoInit = { 1 , 1 , 1 , 9 , 21 , 33 , 55 , 87 , 451 , 297 , 1615 , 697 , 2299 ,0 }; - static ulong[] dim894KuoInit = { 1 , 3 , 1 , 9 , 9 , 5 , 3 , 113 , 197 , 137 , 1105 , 1949 , 4651 ,0 }; - static ulong[] dim895KuoInit = { 1 , 1 , 7 , 3 , 7 , 27 , 109 , 99 , 121 , 463 , 621 , 887 , 5847 ,0 }; - static ulong[] dim896KuoInit = { 1 , 3 , 7 , 7 , 31 , 61 , 21 , 69 , 443 , 81 , 151 , 3601 , 699 ,0 }; - static ulong[] dim897KuoInit = { 1 , 1 , 7 , 11 , 7 , 63 , 97 , 241 , 87 , 961 , 1279 , 1715 , 3183 ,0 }; - static ulong[] dim898KuoInit = { 1 , 1 , 3 , 5 , 7 , 41 , 5 , 123 , 189 , 283 , 1775 , 49 , 6107 ,0 }; - static ulong[] dim899KuoInit = { 1 , 1 , 7 , 15 , 7 , 19 , 71 , 117 , 195 , 67 , 1583 , 3371 , 777 ,0 }; - static ulong[] dim900KuoInit = { 1 , 1 , 1 , 15 , 19 , 43 , 81 , 103 , 173 , 209 , 447 , 1735 , 5023 ,0 }; - static ulong[] dim901KuoInit = { 1 , 1 , 5 , 15 , 15 , 9 , 99 , 185 , 451 , 605 , 1429 , 1257 , 6825 ,0 }; - static ulong[] dim902KuoInit = { 1 , 3 , 1 , 11 , 11 , 21 , 79 , 13 , 23 , 607 , 1601 , 3603 , 147 ,0 }; - static ulong[] dim903KuoInit = { 1 , 1 , 3 , 1 , 27 , 51 , 83 , 191 , 59 , 281 , 1853 , 1441 , 5359 ,0 }; - static ulong[] dim904KuoInit = { 1 , 1 , 1 , 11 , 31 , 17 , 117 , 239 , 385 , 465 , 1787 , 2645 , 6047 ,0 }; - static ulong[] dim905KuoInit = { 1 , 1 , 7 , 5 , 17 , 59 , 111 , 143 , 419 , 163 , 763 , 2327 , 1741 ,0 }; - static ulong[] dim906KuoInit = { 1 , 1 , 1 , 3 , 3 , 43 , 3 , 203 , 1 , 373 , 1829 , 3493 , 2347 ,0 }; - static ulong[] dim907KuoInit = { 1 , 3 , 7 , 13 , 21 , 17 , 89 , 147 , 51 , 665 , 397 , 2475 , 3393 ,0 }; - static ulong[] dim908KuoInit = { 1 , 3 , 7 , 15 , 19 , 33 , 1 , 211 , 155 , 355 , 1137 , 1633 , 5025 ,0 }; - static ulong[] dim909KuoInit = { 1 , 3 , 3 , 9 , 7 , 63 , 127 , 59 , 205 , 645 , 2047 , 1187 , 2711 ,0 }; - static ulong[] dim910KuoInit = { 1 , 3 , 3 , 5 , 7 , 59 , 125 , 35 , 285 , 811 , 1489 , 3269 , 2737 ,0 }; - static ulong[] dim911KuoInit = { 1 , 1 , 7 , 3 , 15 , 39 , 75 , 229 , 213 , 23 , 1825 , 2269 , 6739 ,0 }; - static ulong[] dim912KuoInit = { 1 , 1 , 3 , 7 , 1 , 5 , 73 , 173 , 305 , 681 , 1225 , 2475 , 6981 ,0 }; - static ulong[] dim913KuoInit = { 1 , 1 , 5 , 3 , 21 , 3 , 27 , 241 , 475 , 543 , 1065 , 2731 , 1739 ,0 }; - static ulong[] dim914KuoInit = { 1 , 3 , 7 , 13 , 19 , 35 , 57 , 19 , 307 , 113 , 451 , 1897 , 2135 ,0 }; - static ulong[] dim915KuoInit = { 1 , 1 , 3 , 11 , 31 , 13 , 63 , 15 , 477 , 389 , 829 , 2167 , 3317 ,0 }; - static ulong[] dim916KuoInit = { 1 , 1 , 7 , 11 , 9 , 39 , 1 , 41 , 99 , 295 , 1009 , 1411 , 3423 ,0 }; - static ulong[] dim917KuoInit = { 1 , 1 , 5 , 9 , 15 , 17 , 93 , 171 , 361 , 51 , 455 , 2413 , 7295 ,0 }; - static ulong[] dim918KuoInit = { 1 , 1 , 5 , 13 , 7 , 27 , 127 , 153 , 163 , 635 , 1065 , 2243 , 3813 ,0 }; - static ulong[] dim919KuoInit = { 1 , 1 , 7 , 9 , 15 , 45 , 7 , 241 , 365 , 447 , 1435 , 3473 , 715 ,0 }; - static ulong[] dim920KuoInit = { 1 , 1 , 5 , 9 , 9 , 11 , 21 , 21 , 255 , 717 , 1579 , 217 , 6921 ,0 }; - static ulong[] dim921KuoInit = { 1 , 1 , 5 , 15 , 25 , 21 , 31 , 47 , 455 , 631 , 971 , 3105 , 2219 ,0 }; - static ulong[] dim922KuoInit = { 1 , 3 , 1 , 7 , 9 , 1 , 75 , 85 , 351 , 555 , 1379 , 1361 , 6163 ,0 }; - static ulong[] dim923KuoInit = { 1 , 3 , 5 , 7 , 9 , 63 , 19 , 99 , 335 , 173 , 1385 , 3011 , 5787 ,0 }; - static ulong[] dim924KuoInit = { 1 , 3 , 5 , 1 , 23 , 35 , 79 , 163 , 97 , 213 , 1281 , 1739 , 477 ,0 }; - static ulong[] dim925KuoInit = { 1 , 1 , 5 , 5 , 9 , 13 , 41 , 167 , 349 , 959 , 925 , 1383 , 883 ,0 }; - static ulong[] dim926KuoInit = { 1 , 3 , 7 , 7 , 17 , 23 , 69 , 241 , 447 , 31 , 767 , 2981 , 253 ,0 }; - static ulong[] dim927KuoInit = { 1 , 3 , 7 , 15 , 31 , 15 , 3 , 107 , 225 , 207 , 429 , 959 , 2627 ,0 }; - static ulong[] dim928KuoInit = { 1 , 3 , 3 , 11 , 29 , 25 , 109 , 41 , 261 , 585 , 1049 , 3013 , 4361 ,0 }; - static ulong[] dim929KuoInit = { 1 , 1 , 7 , 11 , 29 , 63 , 117 , 147 , 149 , 427 , 1371 , 2171 , 7797 ,0 }; - static ulong[] dim930KuoInit = { 1 , 3 , 5 , 3 , 13 , 33 , 103 , 33 , 227 , 785 , 1277 , 27 , 6713 ,0 }; - static ulong[] dim931KuoInit = { 1 , 3 , 1 , 3 , 19 , 3 , 121 , 123 , 313 , 283 , 1231 , 3331 , 7271 ,0 }; - static ulong[] dim932KuoInit = { 1 , 1 , 7 , 3 , 21 , 57 , 53 , 9 , 275 , 661 , 1665 , 1557 , 3813 ,0 }; - static ulong[] dim933KuoInit = { 1 , 3 , 5 , 1 , 19 , 63 , 69 , 149 , 373 , 667 , 975 , 3483 , 7605 ,0 }; - static ulong[] dim934KuoInit = { 1 , 3 , 5 , 3 , 3 , 53 , 37 , 247 , 293 , 491 , 657 , 3123 , 1165 ,0 }; - static ulong[] dim935KuoInit = { 1 , 1 , 1 , 13 , 27 , 41 , 23 , 185 , 405 , 215 , 455 , 433 , 7775 ,0 }; - static ulong[] dim936KuoInit = { 1 , 1 , 3 , 13 , 23 , 61 , 63 , 61 , 195 , 83 , 33 , 1903 , 269 ,0 }; - static ulong[] dim937KuoInit = { 1 , 1 , 3 , 7 , 5 , 7 , 1 , 161 , 295 , 539 , 1371 , 3911 , 4095 ,0 }; - static ulong[] dim938KuoInit = { 1 , 1 , 7 , 9 , 7 , 7 , 63 , 115 , 323 , 95 , 1965 , 137 , 7147 ,0 }; - static ulong[] dim939KuoInit = { 1 , 3 , 7 , 11 , 19 , 55 , 107 , 71 , 169 , 937 , 939 , 113 , 6187 ,0 }; - static ulong[] dim940KuoInit = { 1 , 1 , 3 , 7 , 13 , 17 , 55 , 5 , 167 , 337 , 2043 , 1485 , 5069 ,0 }; - static ulong[] dim941KuoInit = { 1 , 1 , 7 , 9 , 21 , 3 , 107 , 125 , 253 , 363 , 49 , 469 , 2873 ,0 }; - static ulong[] dim942KuoInit = { 1 , 1 , 7 , 9 , 9 , 31 , 91 , 65 , 315 , 973 , 653 , 1023 , 6479 ,0 }; - static ulong[] dim943KuoInit = { 1 , 3 , 5 , 11 , 1 , 5 , 19 , 109 , 143 , 335 , 1035 , 3893 , 4573 ,0 }; - static ulong[] dim944KuoInit = { 1 , 3 , 3 , 13 , 27 , 53 , 37 , 177 , 407 , 315 , 1943 , 3111 , 1385 ,0 }; - static ulong[] dim945KuoInit = { 1 , 3 , 5 , 15 , 27 , 47 , 57 , 105 , 131 , 31 , 551 , 3733 , 5157 ,0 }; - static ulong[] dim946KuoInit = { 1 , 3 , 5 , 9 , 15 , 31 , 41 , 11 , 93 , 895 , 587 , 421 , 885 ,0 }; - static ulong[] dim947KuoInit = { 1 , 3 , 7 , 1 , 5 , 35 , 107 , 189 , 287 , 457 , 645 , 519 , 7459 ,0 }; - static ulong[] dim948KuoInit = { 1 , 1 , 7 , 5 , 23 , 7 , 79 , 45 , 73 , 711 , 575 , 3571 , 1453 ,0 }; - static ulong[] dim949KuoInit = { 1 , 1 , 3 , 9 , 9 , 7 , 89 , 197 , 215 , 111 , 1099 , 3915 , 3709 ,0 }; - static ulong[] dim950KuoInit = { 1 , 3 , 1 , 7 , 25 , 1 , 83 , 55 , 449 , 227 , 1563 , 1103 , 4129 ,0 }; - static ulong[] dim951KuoInit = { 1 , 1 , 1 , 9 , 23 , 25 , 103 , 183 , 379 , 541 , 673 , 2711 , 7409 ,0 }; - static ulong[] dim952KuoInit = { 1 , 3 , 1 , 11 , 27 , 21 , 83 , 61 , 65 , 867 , 1755 , 3815 , 7235 ,0 }; - static ulong[] dim953KuoInit = { 1 , 1 , 3 , 15 , 15 , 55 , 13 , 185 , 145 , 955 , 785 , 189 , 6653 ,0 }; - static ulong[] dim954KuoInit = { 1 , 3 , 5 , 15 , 5 , 19 , 83 , 157 , 429 , 57 , 1293 , 1551 , 581 ,0 }; - static ulong[] dim955KuoInit = { 1 , 3 , 3 , 11 , 25 , 19 , 117 , 73 , 503 , 1015 , 203 , 2689 , 6697 ,0 }; - static ulong[] dim956KuoInit = { 1 , 1 , 7 , 1 , 27 , 31 , 111 , 193 , 403 , 267 , 233 , 3031 , 5451 ,0 }; - static ulong[] dim957KuoInit = { 1 , 3 , 7 , 5 , 9 , 7 , 73 , 221 , 27 , 483 , 185 , 1805 , 1813 ,0 }; - static ulong[] dim958KuoInit = { 1 , 3 , 3 , 5 , 19 , 27 , 103 , 197 , 245 , 191 , 301 , 531 , 3677 ,0 }; - static ulong[] dim959KuoInit = { 1 , 1 , 5 , 1 , 9 , 49 , 5 , 55 , 81 , 907 , 313 , 3379 , 2573 ,0 }; - static ulong[] dim960KuoInit = { 1 , 3 , 5 , 3 , 13 , 11 , 75 , 145 , 143 , 991 , 201 , 3769 , 5041 ,0 }; - static ulong[] dim961KuoInit = { 1 , 3 , 1 , 5 , 15 , 45 , 89 , 17 , 209 , 91 , 1635 , 3025 , 3885 ,0 }; - static ulong[] dim962KuoInit = { 1 , 3 , 3 , 5 , 15 , 37 , 79 , 163 , 455 , 477 , 69 , 3617 , 1263 ,0 }; - static ulong[] dim963KuoInit = { 1 , 1 , 3 , 11 , 15 , 47 , 77 , 73 , 199 , 493 , 207 , 2109 , 4991 ,0 }; - static ulong[] dim964KuoInit = { 1 , 1 , 5 , 15 , 29 , 23 , 35 , 177 , 483 , 151 , 1497 , 631 , 1647 ,0 }; - static ulong[] dim965KuoInit = { 1 , 3 , 7 , 5 , 29 , 45 , 127 , 199 , 491 , 965 , 371 , 3549 , 2757 ,0 }; - static ulong[] dim966KuoInit = { 1 , 1 , 7 , 5 , 21 , 11 , 27 , 217 , 407 , 493 , 1979 , 359 , 6187 ,0 }; - static ulong[] dim967KuoInit = { 1 , 3 , 5 , 7 , 31 , 61 , 113 , 197 , 109 , 781 , 1859 , 991 , 3617 ,0 }; - static ulong[] dim968KuoInit = { 1 , 3 , 1 , 5 , 17 , 43 , 75 , 169 , 413 , 257 , 1751 , 4047 , 1951 ,0 }; - static ulong[] dim969KuoInit = { 1 , 3 , 1 , 13 , 17 , 49 , 95 , 223 , 439 , 587 , 427 , 89 , 7723 ,0 }; - static ulong[] dim970KuoInit = { 1 , 3 , 5 , 1 , 7 , 53 , 1 , 79 , 111 , 721 , 169 , 4087 , 5255 ,0 }; - static ulong[] dim971KuoInit = { 1 , 1 , 7 , 15 , 31 , 7 , 111 , 163 , 491 , 559 , 259 , 3057 , 5669 ,0 }; - static ulong[] dim972KuoInit = { 1 , 3 , 3 , 9 , 25 , 41 , 45 , 101 , 145 , 769 , 1313 , 3101 , 405 ,0 }; - static ulong[] dim973KuoInit = { 1 , 3 , 3 , 11 , 3 , 39 , 67 , 201 , 171 , 79 , 1727 , 2331 , 8161 ,0 }; - static ulong[] dim974KuoInit = { 1 , 3 , 5 , 5 , 31 , 29 , 13 , 111 , 449 , 579 , 1133 , 1321 , 2447 ,0 }; - static ulong[] dim975KuoInit = { 1 , 3 , 3 , 15 , 21 , 39 , 57 , 203 , 39 , 733 , 1773 , 2867 , 6751 ,0 }; - static ulong[] dim976KuoInit = { 1 , 3 , 5 , 3 , 19 , 33 , 73 , 219 , 159 , 901 , 919 , 1445 , 1387 ,0 }; - static ulong[] dim977KuoInit = { 1 , 3 , 1 , 7 , 9 , 33 , 113 , 221 , 315 , 503 , 1795 , 577 , 1605 ,0 }; - static ulong[] dim978KuoInit = { 1 , 1 , 7 , 11 , 31 , 47 , 51 , 53 , 159 , 731 , 1101 , 1895 , 2061 ,0 }; - static ulong[] dim979KuoInit = { 1 , 3 , 5 , 7 , 29 , 11 , 107 , 39 , 89 , 357 , 13 , 805 , 5527 ,0 }; - static ulong[] dim980KuoInit = { 1 , 3 , 1 , 9 , 13 , 15 , 59 , 95 , 467 , 875 , 217 , 3345 , 1579 ,0 }; - static ulong[] dim981KuoInit = { 1 , 3 , 1 , 15 , 29 , 33 , 11 , 121 , 243 , 429 , 1017 , 1511 , 6289 ,0 }; - static ulong[] dim982KuoInit = { 1 , 3 , 7 , 1 , 27 , 41 , 125 , 121 , 265 , 695 , 155 , 3933 , 661 ,0 }; - static ulong[] dim983KuoInit = { 1 , 1 , 3 , 7 , 5 , 3 , 95 , 213 , 385 , 183 , 1693 , 2685 , 5647 ,0 }; - static ulong[] dim984KuoInit = { 1 , 1 , 5 , 5 , 23 , 29 , 21 , 193 , 327 , 965 , 49 , 2157 , 1539 ,0 }; - static ulong[] dim985KuoInit = { 1 , 3 , 1 , 7 , 15 , 15 , 103 , 191 , 249 , 347 , 283 , 2459 , 5957 ,0 }; - static ulong[] dim986KuoInit = { 1 , 1 , 7 , 5 , 21 , 43 , 29 , 205 , 125 , 63 , 1645 , 3357 , 3333 ,0 }; - static ulong[] dim987KuoInit = { 1 , 3 , 1 , 5 , 11 , 21 , 109 , 213 , 123 , 587 , 2047 , 343 , 6669 ,0 }; - static ulong[] dim988KuoInit = { 1 , 1 , 5 , 5 , 25 , 63 , 75 , 237 , 421 , 883 , 801 , 2403 , 4723 ,0 }; - static ulong[] dim989KuoInit = { 1 , 3 , 5 , 11 , 13 , 63 , 87 , 107 , 411 , 3 , 139 , 3097 , 6109 ,0 }; - static ulong[] dim990KuoInit = { 1 , 3 , 7 , 9 , 19 , 31 , 33 , 23 , 499 , 105 , 471 , 2311 , 439 ,0 }; - static ulong[] dim991KuoInit = { 1 , 3 , 3 , 13 , 13 , 39 , 19 , 253 , 53 , 315 , 1381 , 3875 , 5741 ,0 }; - static ulong[] dim992KuoInit = { 1 , 1 , 1 , 7 , 19 , 9 , 47 , 169 , 265 , 1005 , 159 , 2957 , 2987 ,0 }; - static ulong[] dim993KuoInit = { 1 , 3 , 3 , 3 , 1 , 35 , 107 , 77 , 47 , 89 , 1901 , 1719 , 2873 ,0 }; - static ulong[] dim994KuoInit = { 1 , 1 , 5 , 7 , 7 , 51 , 87 , 91 , 45 , 991 , 1369 , 3759 , 3511 ,0 }; - static ulong[] dim995KuoInit = { 1 , 3 , 7 , 15 , 17 , 51 , 93 , 43 , 71 , 213 , 1637 , 2617 , 1767 ,0 }; - static ulong[] dim996KuoInit = { 1 , 1 , 5 , 15 , 29 , 63 , 81 , 15 , 409 , 779 , 1419 , 497 , 463 ,0 }; - static ulong[] dim997KuoInit = { 1 , 1 , 7 , 1 , 1 , 31 , 21 , 167 , 445 , 893 , 1687 , 603 , 3211 ,0 }; - static ulong[] dim998KuoInit = { 1 , 3 , 7 , 15 , 19 , 3 , 41 , 53 , 175 , 971 , 1873 , 43 , 4795 ,0 }; - static ulong[] dim999KuoInit = { 1 , 3 , 5 , 15 , 21 , 59 , 77 , 67 , 495 , 547 , 411 , 2373 , 5187 ,0 }; - static ulong[] dim1000KuoInit = { 1 , 1 , 5 , 1 , 27 , 45 , 119 , 201 , 237 , 499 , 261 , 3331 , 3973 ,0 }; - static ulong[] dim1001KuoInit = { 1 , 3 , 5 , 9 , 17 , 31 , 33 , 15 , 237 , 135 , 1751 , 297 , 6331 ,0 }; - static ulong[] dim1002KuoInit = { 1 , 3 , 7 , 9 , 15 , 1 , 11 , 135 , 355 , 617 , 805 , 1201 , 457 ,0 }; - static ulong[] dim1003KuoInit = { 1 , 1 , 7 , 5 , 19 , 55 , 21 , 121 , 205 , 999 , 1719 , 2815 , 6753 ,0 }; - static ulong[] dim1004KuoInit = { 1 , 1 , 5 , 3 , 9 , 5 , 7 , 231 , 323 , 953 , 1811 , 2847 , 2059 ,0 }; - static ulong[] dim1005KuoInit = { 1 , 3 , 3 , 9 , 17 , 15 , 85 , 3 , 259 , 989 , 287 , 3995 , 2677 ,0 }; - static ulong[] dim1006KuoInit = { 1 , 1 , 3 , 11 , 13 , 61 , 69 , 143 , 167 , 187 , 481 , 2359 , 1913 ,0 }; - static ulong[] dim1007KuoInit = { 1 , 1 , 5 , 13 , 29 , 3 , 29 , 247 , 407 , 733 , 677 , 99 , 1625 ,0 }; - static ulong[] dim1008KuoInit = { 1 , 1 , 7 , 13 , 7 , 17 , 67 , 115 , 299 , 765 , 1885 , 2769 , 1619 ,0 }; - static ulong[] dim1009KuoInit = { 1 , 1 , 3 , 3 , 17 , 7 , 27 , 61 , 433 , 323 , 1091 , 1309 , 7239 ,0 }; - static ulong[] dim1010KuoInit = { 1 , 1 , 7 , 3 , 19 , 63 , 41 , 157 , 43 , 743 , 675 , 2149 , 6729 ,0 }; - static ulong[] dim1011KuoInit = { 1 , 1 , 5 , 1 , 21 , 35 , 45 , 145 , 235 , 185 , 1563 , 1117 , 3669 ,0 }; - static ulong[] dim1012KuoInit = { 1 , 3 , 1 , 9 , 9 , 37 , 105 , 61 , 259 , 935 , 793 , 823 , 1765 ,0 }; - static ulong[] dim1013KuoInit = { 1 , 3 , 3 , 11 , 25 , 41 , 35 , 11 , 389 , 399 , 339 , 859 , 4299 ,0 }; - static ulong[] dim1014KuoInit = { 1 , 3 , 5 , 13 , 7 , 29 , 53 , 91 , 185 , 163 , 1689 , 983 , 4545 ,0 }; - static ulong[] dim1015KuoInit = { 1 , 3 , 7 , 11 , 19 , 35 , 45 , 141 , 445 , 469 , 1827 , 3523 , 377 ,0 }; - static ulong[] dim1016KuoInit = { 1 , 3 , 5 , 13 , 27 , 29 , 35 , 199 , 73 , 163 , 1591 , 1021 , 2867 ,0 }; - static ulong[] dim1017KuoInit = { 1 , 1 , 1 , 15 , 7 , 61 , 95 , 95 , 147 , 959 , 971 , 649 , 5047 ,0 }; - static ulong[] dim1018KuoInit = { 1 , 1 , 1 , 15 , 11 , 23 , 49 , 231 , 359 , 677 , 1401 , 2889 , 3799 ,0 }; - static ulong[] dim1019KuoInit = { 1 , 3 , 7 , 11 , 11 , 15 , 119 , 103 , 403 , 983 , 399 , 321 , 437 ,0 }; - static ulong[] dim1020KuoInit = { 1 , 3 , 7 , 1 , 29 , 13 , 83 , 55 , 175 , 835 , 1637 , 209 , 1923 ,0 }; - static ulong[] dim1021KuoInit = { 1 , 1 , 5 , 13 , 25 , 37 , 5 , 239 , 227 , 229 , 243 , 1837 , 4821 ,0 }; - static ulong[] dim1022KuoInit = { 1 , 1 , 7 , 9 , 9 , 59 , 29 , 135 , 227 , 473 , 1759 , 3711 , 4113 ,0 }; - static ulong[] dim1023KuoInit = { 1 , 3 , 3 , 3 , 15 , 3 , 53 , 225 , 165 , 375 , 537 , 331 , 5085 ,0 }; - static ulong[] dim1024KuoInit = { 1 , 1 , 1 , 5 , 15 , 41 , 57 , 165 , 45 , 137 , 931 , 1015 , 6451 ,0 }; - static ulong[] dim1025KuoInit = { 1 , 3 , 5 , 7 , 5 , 47 , 35 , 249 , 89 , 111 , 1275 , 529 , 3297 ,0 }; - static ulong[] dim1026KuoInit = { 1 , 3 , 1 , 1 , 27 , 21 , 65 , 193 , 381 , 861 , 59 , 1457 , 2447 ,0 }; - static ulong[] dim1027KuoInit = { 1 , 1 , 7 , 15 , 17 , 25 , 75 , 171 , 263 , 401 , 1369 , 2609 , 6265 ,0 }; - static ulong[] dim1028KuoInit = { 1 , 1 , 3 , 7 , 17 , 61 , 75 , 77 , 487 , 7 , 1565 , 527 , 7213 ,0 }; - static ulong[] dim1029KuoInit = { 1 , 3 , 5 , 9 , 5 , 45 , 47 , 27 , 163 , 43 , 219 , 2119 , 1793 ,0 }; - static ulong[] dim1030KuoInit = { 1 , 1 , 3 , 3 , 27 , 9 , 89 , 151 , 487 , 925 , 1257 , 1065 , 3413 ,0 }; - static ulong[] dim1031KuoInit = { 1 , 1 , 5 , 3 , 11 , 27 , 9 , 161 , 303 , 457 , 1367 , 2319 , 6145 ,0 }; - static ulong[] dim1032KuoInit = { 1 , 3 , 1 , 13 , 23 , 43 , 115 , 227 , 319 , 469 , 1651 , 1693 , 2095 ,0 }; - static ulong[] dim1033KuoInit = { 1 , 1 , 1 , 11 , 23 , 5 , 91 , 103 , 393 , 787 , 1557 , 925 , 7189 ,0 }; - static ulong[] dim1034KuoInit = { 1 , 3 , 5 , 7 , 31 , 5 , 51 , 171 , 375 , 309 , 199 , 1833 , 2741 ,0 }; - static ulong[] dim1035KuoInit = { 1 , 1 , 5 , 13 , 27 , 59 , 15 , 255 , 205 , 807 , 1407 , 161 , 6955 ,0 }; - static ulong[] dim1036KuoInit = { 1 , 3 , 5 , 5 , 5 , 35 , 7 , 167 , 265 , 67 , 1133 , 699 , 6225 ,0 }; - static ulong[] dim1037KuoInit = { 1 , 1 , 1 , 7 , 19 , 31 , 5 , 243 , 279 , 505 , 303 , 2303 , 5367 ,0 }; - static ulong[] dim1038KuoInit = { 1 , 3 , 1 , 3 , 19 , 47 , 105 , 159 , 309 , 783 , 1845 , 2603 , 4663 ,0 }; - static ulong[] dim1039KuoInit = { 1 , 1 , 7 , 13 , 13 , 35 , 101 , 123 , 99 , 559 , 1681 , 2751 , 1965 ,0 }; - static ulong[] dim1040KuoInit = { 1 , 3 , 7 , 5 , 1 , 63 , 29 , 245 , 105 , 469 , 939 , 721 , 6213 ,0 }; - static ulong[] dim1041KuoInit = { 1 , 3 , 7 , 15 , 11 , 45 , 13 , 121 , 81 , 15 , 1503 , 2203 , 7467 ,0 }; - static ulong[] dim1042KuoInit = { 1 , 1 , 7 , 11 , 29 , 25 , 59 , 93 , 5 , 551 , 1799 , 2251 , 115 ,0 }; - static ulong[] dim1043KuoInit = { 1 , 1 , 1 , 7 , 17 , 37 , 81 , 117 , 183 , 301 , 1085 , 3925 , 697 ,0 }; - static ulong[] dim1044KuoInit = { 1 , 3 , 7 , 7 , 13 , 13 , 5 , 207 , 443 , 723 , 897 , 3481 , 3377 ,0 }; - static ulong[] dim1045KuoInit = { 1 , 3 , 7 , 13 , 9 , 41 , 25 , 161 , 283 , 3 , 1515 , 2445 , 2179 ,0 }; - static ulong[] dim1046KuoInit = { 1 , 1 , 1 , 1 , 29 , 17 , 73 , 129 , 499 , 457 , 103 , 2287 , 525 ,0 }; - static ulong[] dim1047KuoInit = { 1 , 3 , 7 , 11 , 9 , 13 , 95 , 31 , 411 , 185 , 931 , 119 , 711 ,0 }; - static ulong[] dim1048KuoInit = { 1 , 1 , 3 , 13 , 19 , 53 , 49 , 209 , 217 , 593 , 733 , 4057 , 2853 ,0 }; - static ulong[] dim1049KuoInit = { 1 , 3 , 5 , 1 , 7 , 63 , 95 , 45 , 209 , 641 , 1767 , 3001 , 4089 ,0 }; - static ulong[] dim1050KuoInit = { 1 , 1 , 5 , 9 , 9 , 25 , 69 , 85 , 345 , 475 , 613 , 3975 , 2179 ,0 }; - static ulong[] dim1051KuoInit = { 1 , 1 , 1 , 9 , 19 , 9 , 47 , 51 , 111 , 7 , 627 , 1635 , 3857 ,0 }; - static ulong[] dim1052KuoInit = { 1 , 3 , 7 , 1 , 25 , 37 , 27 , 253 , 111 , 369 , 235 , 2887 , 5649 ,0 }; - static ulong[] dim1053KuoInit = { 1 , 1 , 7 , 3 , 15 , 5 , 13 , 181 , 471 , 825 , 121 , 3007 , 777 ,0 }; - static ulong[] dim1054KuoInit = { 1 , 1 , 1 , 9 , 27 , 41 , 59 , 9 , 391 , 779 , 915 , 3965 , 4431 ,0 }; - static ulong[] dim1055KuoInit = { 1 , 3 , 1 , 1 , 25 , 27 , 75 , 123 , 385 , 923 , 141 , 3771 , 2227 ,0 }; - static ulong[] dim1056KuoInit = { 1 , 3 , 3 , 15 , 17 , 29 , 85 , 253 , 261 , 517 , 87 , 621 , 7947 ,0 }; - static ulong[] dim1057KuoInit = { 1 , 3 , 7 , 5 , 13 , 15 , 83 , 49 , 399 , 875 , 845 , 1731 , 7071 ,0 }; - static ulong[] dim1058KuoInit = { 1 , 1 , 3 , 5 , 21 , 49 , 93 , 121 , 271 , 921 , 183 , 1533 , 1609 ,0 }; - static ulong[] dim1059KuoInit = { 1 , 3 , 7 , 7 , 9 , 51 , 89 , 135 , 389 , 151 , 1813 , 3673 , 2099 ,0 }; - static ulong[] dim1060KuoInit = { 1 , 1 , 1 , 11 , 25 , 63 , 127 , 239 , 329 , 455 , 403 , 363 , 2689 ,0 }; - static ulong[] dim1061KuoInit = { 1 , 3 , 5 , 13 , 1 , 45 , 65 , 93 , 371 , 577 , 669 , 2433 , 3507 ,0 }; - static ulong[] dim1062KuoInit = { 1 , 3 , 5 , 9 , 9 , 15 , 13 , 85 , 67 , 809 , 1133 , 129 , 3869 ,0 }; - static ulong[] dim1063KuoInit = { 1 , 3 , 7 , 15 , 3 , 47 , 31 , 79 , 395 , 227 , 677 , 3399 , 8173 ,0 }; - static ulong[] dim1064KuoInit = { 1 , 3 , 1 , 11 , 7 , 19 , 81 , 27 , 393 , 49 , 299 , 879 , 5401 ,0 }; - static ulong[] dim1065KuoInit = { 1 , 1 , 1 , 1 , 3 , 25 , 105 , 67 , 147 , 23 , 749 , 2677 , 2799 ,0 }; - static ulong[] dim1066KuoInit = { 1 , 1 , 3 , 15 , 3 , 49 , 55 , 131 , 249 , 183 , 399 , 4065 , 4575 ,0 }; - static ulong[] dim1067KuoInit = { 1 , 3 , 7 , 13 , 21 , 1 , 105 , 167 , 379 , 567 , 1843 , 3019 , 7479 ,0 }; - static ulong[] dim1068KuoInit = { 1 , 1 , 7 , 3 , 7 , 15 , 65 , 213 , 191 , 735 , 1087 , 1223 , 7827 ,0 }; - static ulong[] dim1069KuoInit = { 1 , 1 , 3 , 3 , 13 , 35 , 79 , 55 , 169 , 513 , 639 , 1153 , 1129 ,0 }; - static ulong[] dim1070KuoInit = { 1 , 3 , 5 , 15 , 1 , 37 , 49 , 209 , 355 , 533 , 1073 , 3249 , 4309 ,0 }; - static ulong[] dim1071KuoInit = { 1 , 1 , 3 , 15 , 23 , 45 , 69 , 195 , 155 , 267 , 291 , 1773 , 3575 ,0 }; - static ulong[] dim1072KuoInit = { 1 , 3 , 1 , 13 , 25 , 3 , 51 , 175 , 505 , 467 , 1909 , 1929 , 4909 ,0 }; - static ulong[] dim1073KuoInit = { 1 , 3 , 3 , 1 , 31 , 51 , 99 , 119 , 505 , 57 , 1987 , 1303 , 4273 ,0 }; - static ulong[] dim1074KuoInit = { 1 , 3 , 7 , 9 , 19 , 49 , 61 , 147 , 29 , 1001 , 633 , 963 , 5601 ,0 }; - static ulong[] dim1075KuoInit = { 1 , 3 , 5 , 7 , 1 , 13 , 101 , 133 , 31 , 263 , 2033 , 575 , 983 ,0 }; - static ulong[] dim1076KuoInit = { 1 , 1 , 1 , 15 , 21 , 29 , 101 , 143 , 263 , 601 , 1239 , 1187 , 3045 ,0 }; - static ulong[] dim1077KuoInit = { 1 , 3 , 3 , 15 , 5 , 49 , 7 , 165 , 411 , 517 , 619 , 1517 , 1839 ,0 }; - static ulong[] dim1078KuoInit = { 1 , 3 , 5 , 15 , 29 , 45 , 71 , 245 , 67 , 469 , 1793 , 3353 , 7799 ,0 }; - static ulong[] dim1079KuoInit = { 1 , 1 , 5 , 7 , 15 , 49 , 5 , 183 , 345 , 585 , 1877 , 2205 , 7963 ,0 }; - static ulong[] dim1080KuoInit = { 1 , 3 , 1 , 1 , 7 , 39 , 85 , 183 , 131 , 527 , 1731 , 1899 , 3813 ,0 }; - static ulong[] dim1081KuoInit = { 1 , 1 , 7 , 9 , 29 , 23 , 77 , 233 , 77 , 699 , 1963 , 171 , 6557 ,0 }; - static ulong[] dim1082KuoInit = { 1 , 3 , 5 , 15 , 5 , 3 , 79 , 199 , 279 , 279 , 399 , 769 , 1661 ,0 }; - static ulong[] dim1083KuoInit = { 1 , 3 , 7 , 1 , 17 , 61 , 61 , 227 , 289 , 541 , 379 , 3155 , 5791 ,0 }; - static ulong[] dim1084KuoInit = { 1 , 3 , 3 , 7 , 31 , 37 , 73 , 215 , 47 , 895 , 1511 , 305 , 5247 ,0 }; - static ulong[] dim1085KuoInit = { 1 , 1 , 7 , 5 , 31 , 47 , 123 , 191 , 175 , 875 , 501 , 2203 , 1781 ,0 }; - static ulong[] dim1086KuoInit = { 1 , 3 , 3 , 3 , 13 , 5 , 43 , 145 , 183 , 705 , 1143 , 3113 , 1959 ,0 }; - static ulong[] dim1087KuoInit = { 1 , 3 , 7 , 1 , 23 , 53 , 93 , 133 , 13 , 987 , 1711 , 2241 , 7721 ,0 }; - static ulong[] dim1088KuoInit = { 1 , 3 , 1 , 7 , 3 , 19 , 123 , 65 , 421 , 891 , 159 , 1633 , 733 ,0 }; - static ulong[] dim1089KuoInit = { 1 , 3 , 3 , 3 , 23 , 59 , 127 , 109 , 315 , 939 , 1177 , 1237 , 1805 ,0 }; - static ulong[] dim1090KuoInit = { 1 , 3 , 5 , 15 , 13 , 19 , 39 , 97 , 437 , 949 , 539 , 1171 , 151 ,0 }; - static ulong[] dim1091KuoInit = { 1 , 3 , 5 , 9 , 13 , 45 , 107 , 159 , 363 , 727 , 509 , 3051 , 4071 ,0 }; - static ulong[] dim1092KuoInit = { 1 , 3 , 3 , 1 , 15 , 11 , 93 , 199 , 137 , 947 , 479 , 2127 , 1377 ,0 }; - static ulong[] dim1093KuoInit = { 1 , 3 , 7 , 15 , 13 , 5 , 67 , 227 , 69 , 795 , 299 , 1845 , 4765 ,0 }; - static ulong[] dim1094KuoInit = { 1 , 1 , 5 , 7 , 31 , 15 , 11 , 255 , 361 , 599 , 1235 , 1785 , 1611 ,0 }; - static ulong[] dim1095KuoInit = { 1 , 3 , 5 , 15 , 29 , 21 , 85 , 49 , 101 , 785 , 1071 , 1333 , 1691 ,0 }; - static ulong[] dim1096KuoInit = { 1 , 3 , 1 , 1 , 19 , 11 , 23 , 157 , 201 , 67 , 789 , 999 , 4281 ,0 }; - static ulong[] dim1097KuoInit = { 1 , 1 , 7 , 3 , 7 , 61 , 109 , 253 , 455 , 863 , 81 , 3185 , 7105 ,0 }; - static ulong[] dim1098KuoInit = { 1 , 1 , 1 , 1 , 11 , 29 , 51 , 43 , 211 , 103 , 1333 , 3425 , 6669 ,0 }; - static ulong[] dim1099KuoInit = { 1 , 3 , 3 , 3 , 19 , 15 , 25 , 21 , 9 , 563 , 1737 , 159 , 1827 ,0 }; - static ulong[] dim1100KuoInit = { 1 , 3 , 5 , 11 , 9 , 35 , 19 , 145 , 159 , 345 , 475 , 1453 , 7807 ,0 }; - static ulong[] dim1101KuoInit = { 1 , 3 , 7 , 9 , 19 , 41 , 61 , 63 , 77 , 3 , 997 , 223 , 5493 ,0 }; - static ulong[] dim1102KuoInit = { 1 , 3 , 7 , 15 , 25 , 17 , 87 , 99 , 441 , 973 , 713 , 631 , 4039 ,0 }; - static ulong[] dim1103KuoInit = { 1 , 3 , 5 , 15 , 17 , 19 , 89 , 11 , 321 , 143 , 11 , 915 , 3359 ,0 }; - static ulong[] dim1104KuoInit = { 1 , 3 , 7 , 1 , 11 , 55 , 43 , 3 , 1 , 893 , 1845 , 1237 , 693 ,0 }; - static ulong[] dim1105KuoInit = { 1 , 3 , 7 , 13 , 25 , 21 , 93 , 43 , 127 , 197 , 1349 , 1727 , 1133 ,0 }; - static ulong[] dim1106KuoInit = { 1 , 3 , 7 , 15 , 29 , 57 , 19 , 35 , 37 , 81 , 1599 , 3469 , 4327 ,0 }; - static ulong[] dim1107KuoInit = { 1 , 1 , 7 , 9 , 15 , 47 , 119 , 203 , 301 , 835 , 1221 , 2771 , 2023 ,0 }; - static ulong[] dim1108KuoInit = { 1 , 3 , 5 , 9 , 25 , 43 , 109 , 51 , 431 , 189 , 255 , 2595 , 2447 ,0 }; - static ulong[] dim1109KuoInit = { 1 , 1 , 5 , 5 , 13 , 3 , 113 , 109 , 321 , 837 , 159 , 2617 , 2277 ,0 }; - static ulong[] dim1110KuoInit = { 1 , 1 , 1 , 11 , 29 , 43 , 33 , 173 , 47 , 395 , 1113 , 1711 , 7909 ,0 }; - static ulong[] dim1111KuoInit = { 1 , 1 , 3 , 15 , 31 , 45 , 37 , 95 , 13 , 449 , 1377 , 2117 , 6607 , 11053 ,0 }; - static ulong[] dim1112KuoInit = { 1 , 1 , 1 , 9 , 21 , 7 , 127 , 71 , 11 , 271 , 65 , 3681 , 4209 , 3183 ,0 }; - static ulong[] dim1113KuoInit = { 1 , 3 , 3 , 15 , 19 , 27 , 99 , 243 , 371 , 77 , 629 , 3989 , 3105 , 6287 ,0 }; - static ulong[] dim1114KuoInit = { 1 , 3 , 1 , 15 , 7 , 35 , 115 , 237 , 403 , 273 , 697 , 117 , 6887 , 3243 ,0 }; - static ulong[] dim1115KuoInit = { 1 , 1 , 5 , 9 , 29 , 1 , 117 , 101 , 483 , 909 , 867 , 2051 , 7081 , 14905 ,0 }; - static ulong[] dim1116KuoInit = { 1 , 1 , 7 , 13 , 21 , 49 , 107 , 101 , 121 , 979 , 309 , 1871 , 7339 , 4213 ,0 }; - static ulong[] dim1117KuoInit = { 1 , 1 , 7 , 13 , 9 , 25 , 13 , 61 , 409 , 469 , 411 , 2041 , 7685 , 15501 ,0 }; - static ulong[] dim1118KuoInit = { 1 , 1 , 7 , 5 , 1 , 29 , 109 , 125 , 63 , 829 , 175 , 957 , 4781 , 12473 ,0 }; - static ulong[] dim1119KuoInit = { 1 , 3 , 3 , 1 , 11 , 53 , 17 , 171 , 393 , 165 , 51 , 737 , 1697 , 4137 ,0 }; - static ulong[] dim1120KuoInit = { 1 , 3 , 7 , 9 , 15 , 45 , 49 , 219 , 105 , 121 , 549 , 991 , 1337 , 11311 ,0 }; - static ulong[] dim1121KuoInit = { 1 , 3 , 3 , 5 , 27 , 9 , 39 , 207 , 85 , 185 , 901 , 3077 , 5295 , 3933 ,0 }; - static ulong[] dim1122KuoInit = { 1 , 1 , 5 , 7 , 23 , 29 , 95 , 63 , 125 , 447 , 573 , 2053 , 4621 , 10135 ,0 }; - static ulong[] dim1123KuoInit = { 1 , 1 , 1 , 7 , 23 , 45 , 3 , 109 , 335 , 339 , 1453 , 3121 , 37 , 9155 ,0 }; - static ulong[] dim1124KuoInit = { 1 , 3 , 1 , 13 , 9 , 25 , 27 , 67 , 35 , 573 , 215 , 1969 , 7083 , 15729 ,0 }; - static ulong[] dim1125KuoInit = { 1 , 3 , 1 , 9 , 21 , 3 , 21 , 143 , 131 , 613 , 299 , 1127 , 5647 , 15007 ,0 }; - static ulong[] dim1126KuoInit = { 1 , 3 , 7 , 9 , 29 , 47 , 53 , 223 , 409 , 633 , 535 , 2423 , 5763 , 11633 ,0 }; - static ulong[] dim1127KuoInit = { 1 , 3 , 1 , 9 , 1 , 21 , 5 , 1 , 359 , 547 , 285 , 779 , 2091 , 11785 ,0 }; - static ulong[] dim1128KuoInit = { 1 , 3 , 7 , 7 , 1 , 31 , 61 , 245 , 331 , 45 , 1559 , 3223 , 7577 , 2157 ,0 }; - static ulong[] dim1129KuoInit = { 1 , 1 , 1 , 7 , 3 , 27 , 37 , 191 , 229 , 205 , 1535 , 887 , 701 , 10867 ,0 }; - static ulong[] dim1130KuoInit = { 1 , 3 , 3 , 15 , 21 , 53 , 61 , 177 , 485 , 575 , 681 , 1447 , 1427 , 11279 ,0 }; - static ulong[] dim1131KuoInit = { 1 , 1 , 1 , 3 , 17 , 3 , 5 , 49 , 311 , 507 , 995 , 3971 , 471 , 3045 ,0 }; - static ulong[] dim1132KuoInit = { 1 , 1 , 3 , 9 , 7 , 45 , 73 , 183 , 419 , 635 , 523 , 1793 , 7549 , 9727 ,0 }; - static ulong[] dim1133KuoInit = { 1 , 1 , 7 , 3 , 19 , 33 , 109 , 91 , 19 , 825 , 1629 , 2111 , 2673 , 6677 ,0 }; - static ulong[] dim1134KuoInit = { 1 , 1 , 3 , 9 , 31 , 13 , 71 , 199 , 113 , 77 , 371 , 3117 , 7799 , 15919 ,0 }; - static ulong[] dim1135KuoInit = { 1 , 1 , 7 , 5 , 27 , 41 , 91 , 183 , 75 , 159 , 911 , 2081 , 7065 , 16313 ,0 }; - static ulong[] dim1136KuoInit = { 1 , 3 , 1 , 15 , 17 , 29 , 65 , 9 , 399 , 259 , 671 , 525 , 1393 , 13367 ,0 }; - static ulong[] dim1137KuoInit = { 1 , 3 , 3 , 13 , 1 , 29 , 101 , 187 , 231 , 413 , 1245 , 269 , 201 , 1673 ,0 }; - static ulong[] dim1138KuoInit = { 1 , 1 , 7 , 3 , 27 , 47 , 11 , 149 , 49 , 309 , 1923 , 1187 , 3165 , 7927 ,0 }; - static ulong[] dim1139KuoInit = { 1 , 1 , 1 , 5 , 31 , 57 , 29 , 203 , 11 , 305 , 1771 , 2997 , 377 , 5777 ,0 }; - static ulong[] dim1140KuoInit = { 1 , 1 , 7 , 5 , 1 , 29 , 29 , 205 , 93 , 821 , 1583 , 2991 , 4137 , 14967 ,0 }; - static ulong[] dim1141KuoInit = { 1 , 1 , 3 , 3 , 7 , 57 , 13 , 179 , 261 , 547 , 219 , 1979 , 4951 , 2529 ,0 }; - static ulong[] dim1142KuoInit = { 1 , 3 , 1 , 5 , 3 , 51 , 89 , 7 , 121 , 611 , 1655 , 3639 , 1991 , 9911 ,0 }; - static ulong[] dim1143KuoInit = { 1 , 3 , 3 , 15 , 1 , 21 , 9 , 173 , 93 , 579 , 1685 , 767 , 5183 , 3965 ,0 }; - static ulong[] dim1144KuoInit = { 1 , 1 , 3 , 7 , 15 , 47 , 55 , 113 , 27 , 941 , 1633 , 3791 , 1705 , 16293 ,0 }; - static ulong[] dim1145KuoInit = { 1 , 3 , 3 , 1 , 7 , 41 , 11 , 229 , 367 , 997 , 543 , 933 , 4249 , 7049 ,0 }; - static ulong[] dim1146KuoInit = { 1 , 1 , 1 , 13 , 7 , 7 , 25 , 87 , 213 , 277 , 627 , 721 , 6161 , 14877 ,0 }; - static ulong[] dim1147KuoInit = { 1 , 3 , 5 , 7 , 25 , 61 , 47 , 103 , 199 , 983 , 543 , 1935 , 4663 , 3597 ,0 }; - static ulong[] dim1148KuoInit = { 1 , 3 , 1 , 15 , 15 , 49 , 125 , 27 , 153 , 521 , 351 , 1129 , 5897 , 11325 ,0 }; - static ulong[] dim1149KuoInit = { 1 , 3 , 1 , 13 , 13 , 35 , 81 , 53 , 217 , 739 , 963 , 3441 , 6843 , 3505 ,0 }; - static ulong[] dim1150KuoInit = { 1 , 3 , 7 , 1 , 17 , 35 , 119 , 187 , 475 , 919 , 1325 , 3269 , 677 , 617 ,0 }; - static ulong[] dim1151KuoInit = { 1 , 1 , 7 , 15 , 7 , 15 , 91 , 99 , 259 , 37 , 1461 , 1145 , 6973 , 15643 ,0 }; - static ulong[] dim1152KuoInit = { 1 , 1 , 5 , 15 , 13 , 11 , 27 , 75 , 9 , 611 , 1331 , 2057 , 863 , 6245 ,0 }; - static ulong[] dim1153KuoInit = { 1 , 1 , 1 , 15 , 3 , 25 , 117 , 45 , 141 , 839 , 1201 , 629 , 6289 , 12231 ,0 }; - static ulong[] dim1154KuoInit = { 1 , 1 , 3 , 13 , 17 , 61 , 23 , 243 , 349 , 153 , 1747 , 3107 , 7763 , 10067 ,0 }; - static ulong[] dim1155KuoInit = { 1 , 1 , 1 , 1 , 21 , 25 , 53 , 67 , 97 , 851 , 1921 , 2247 , 5769 , 5779 ,0 }; - static ulong[] dim1156KuoInit = { 1 , 3 , 3 , 3 , 9 , 37 , 93 , 247 , 287 , 609 , 1643 , 427 , 4269 , 15923 ,0 }; - static ulong[] dim1157KuoInit = { 1 , 3 , 3 , 15 , 7 , 35 , 111 , 105 , 357 , 539 , 319 , 993 , 6155 , 6587 ,0 }; - static ulong[] dim1158KuoInit = { 1 , 1 , 3 , 1 , 13 , 33 , 99 , 73 , 89 , 231 , 1537 , 309 , 3837 , 6669 ,0 }; - static ulong[] dim1159KuoInit = { 1 , 3 , 1 , 1 , 9 , 25 , 105 , 197 , 399 , 259 , 1381 , 1631 , 3551 , 4593 ,0 }; - static ulong[] dim1160KuoInit = { 1 , 3 , 1 , 3 , 7 , 63 , 113 , 65 , 109 , 529 , 1451 , 1169 , 3321 , 6811 ,0 }; - static ulong[] dim1161KuoInit = { 1 , 1 , 1 , 5 , 11 , 55 , 109 , 27 , 65 , 199 , 199 , 2745 , 2009 , 14853 ,0 }; - static ulong[] dim1162KuoInit = { 1 , 3 , 1 , 9 , 13 , 31 , 109 , 119 , 431 , 363 , 1191 , 703 , 2617 , 6817 ,0 }; - static ulong[] dim1163KuoInit = { 1 , 1 , 3 , 11 , 27 , 1 , 107 , 11 , 457 , 495 , 215 , 1459 , 4137 , 13007 ,0 }; - static ulong[] dim1164KuoInit = { 1 , 1 , 7 , 3 , 7 , 29 , 11 , 19 , 159 , 821 , 1881 , 3277 , 1303 , 7145 ,0 }; - static ulong[] dim1165KuoInit = { 1 , 3 , 3 , 11 , 25 , 11 , 125 , 241 , 197 , 863 , 423 , 2107 , 5885 , 14279 ,0 }; - static ulong[] dim1166KuoInit = { 1 , 3 , 3 , 1 , 7 , 29 , 97 , 249 , 333 , 945 , 1081 , 2405 , 109 , 2869 ,0 }; - static ulong[] dim1167KuoInit = { 1 , 3 , 3 , 3 , 27 , 57 , 89 , 243 , 481 , 431 , 269 , 3371 , 3667 , 13293 ,0 }; - static ulong[] dim1168KuoInit = { 1 , 3 , 7 , 7 , 23 , 3 , 91 , 57 , 79 , 165 , 629 , 2771 , 7927 , 2689 ,0 }; - static ulong[] dim1169KuoInit = { 1 , 1 , 1 , 11 , 17 , 51 , 81 , 147 , 19 , 501 , 861 , 159 , 2117 , 6777 ,0 }; - static ulong[] dim1170KuoInit = { 1 , 3 , 3 , 15 , 7 , 9 , 51 , 197 , 97 , 983 , 133 , 1819 , 4449 , 7821 ,0 }; - static ulong[] dim1171KuoInit = { 1 , 3 , 3 , 7 , 21 , 55 , 61 , 171 , 461 , 741 , 1901 , 2195 , 5477 , 1681 ,0 }; - static ulong[] dim1172KuoInit = { 1 , 1 , 3 , 1 , 13 , 37 , 73 , 151 , 479 , 561 , 1483 , 2679 , 295 , 7325 ,0 }; - static ulong[] dim1173KuoInit = { 1 , 3 , 3 , 9 , 11 , 17 , 127 , 115 , 371 , 979 , 1391 , 2189 , 2805 , 7471 ,0 }; - static ulong[] dim1174KuoInit = { 1 , 1 , 3 , 13 , 31 , 25 , 65 , 249 , 91 , 649 , 1103 , 493 , 6341 , 10313 ,0 }; - static ulong[] dim1175KuoInit = { 1 , 1 , 1 , 3 , 7 , 31 , 85 , 201 , 277 , 771 , 1007 , 69 , 3357 , 15059 ,0 }; - static ulong[] dim1176KuoInit = { 1 , 1 , 1 , 7 , 17 , 17 , 9 , 229 , 269 , 591 , 945 , 3003 , 6723 , 16101 ,0 }; - static ulong[] dim1177KuoInit = { 1 , 1 , 3 , 5 , 1 , 29 , 119 , 181 , 269 , 269 , 1781 , 2935 , 6265 , 13989 ,0 }; - static ulong[] dim1178KuoInit = { 1 , 3 , 1 , 11 , 13 , 51 , 117 , 141 , 467 , 521 , 449 , 797 , 3447 , 11693 ,0 }; - static ulong[] dim1179KuoInit = { 1 , 1 , 5 , 15 , 3 , 57 , 61 , 209 , 423 , 213 , 1663 , 3735 , 5229 , 11809 ,0 }; - static ulong[] dim1180KuoInit = { 1 , 3 , 7 , 9 , 13 , 51 , 113 , 127 , 229 , 793 , 905 , 3271 , 7501 , 10801 ,0 }; - static ulong[] dim1181KuoInit = { 1 , 3 , 7 , 7 , 5 , 19 , 43 , 87 , 9 , 981 , 221 , 3925 , 2095 , 7185 ,0 }; - static ulong[] dim1182KuoInit = { 1 , 1 , 7 , 15 , 23 , 35 , 113 , 175 , 383 , 699 , 1617 , 3771 , 5847 , 9097 ,0 }; - static ulong[] dim1183KuoInit = { 1 , 3 , 1 , 7 , 25 , 23 , 27 , 77 , 491 , 211 , 1785 , 199 , 4865 , 10147 ,0 }; - static ulong[] dim1184KuoInit = { 1 , 3 , 1 , 11 , 25 , 39 , 15 , 15 , 191 , 889 , 457 , 2647 , 4555 , 4799 ,0 }; - static ulong[] dim1185KuoInit = { 1 , 1 , 7 , 5 , 15 , 1 , 117 , 169 , 245 , 917 , 1025 , 3805 , 1455 , 3051 ,0 }; - static ulong[] dim1186KuoInit = { 1 , 3 , 7 , 5 , 7 , 15 , 43 , 13 , 359 , 685 , 75 , 271 , 555 , 3595 ,0 }; - static ulong[] dim1187KuoInit = { 1 , 3 , 7 , 5 , 19 , 9 , 29 , 15 , 139 , 13 , 753 , 205 , 677 , 5945 ,0 }; - static ulong[] dim1188KuoInit = { 1 , 3 , 1 , 9 , 5 , 21 , 99 , 77 , 287 , 663 , 589 , 229 , 5255 , 4177 ,0 }; - static ulong[] dim1189KuoInit = { 1 , 1 , 1 , 9 , 15 , 47 , 21 , 149 , 461 , 871 , 577 , 3393 , 6879 , 6353 ,0 }; - static ulong[] dim1190KuoInit = { 1 , 3 , 3 , 3 , 21 , 33 , 29 , 25 , 195 , 1 , 1817 , 3437 , 4265 , 16121 ,0 }; - static ulong[] dim1191KuoInit = { 1 , 3 , 1 , 7 , 27 , 31 , 93 , 141 , 471 , 735 , 1737 , 2997 , 3529 , 12285 ,0 }; - static ulong[] dim1192KuoInit = { 1 , 1 , 3 , 15 , 15 , 49 , 105 , 157 , 165 , 593 , 651 , 3331 , 4333 , 8607 ,0 }; - static ulong[] dim1193KuoInit = { 1 , 3 , 7 , 1 , 5 , 35 , 73 , 53 , 461 , 41 , 1407 , 357 , 3537 , 1123 ,0 }; - static ulong[] dim1194KuoInit = { 1 , 1 , 7 , 9 , 15 , 39 , 83 , 23 , 501 , 3 , 743 , 3819 , 5491 , 15317 ,0 }; - static ulong[] dim1195KuoInit = { 1 , 1 , 7 , 15 , 31 , 29 , 125 , 173 , 465 , 347 , 1515 , 2871 , 3861 , 9353 ,0 }; - static ulong[] dim1196KuoInit = { 1 , 1 , 7 , 5 , 9 , 31 , 121 , 221 , 491 , 579 , 313 , 3549 , 711 , 12501 ,0 }; - static ulong[] dim1197KuoInit = { 1 , 1 , 7 , 15 , 7 , 47 , 15 , 175 , 201 , 399 , 609 , 749 , 3587 , 10091 ,0 }; - static ulong[] dim1198KuoInit = { 1 , 1 , 5 , 11 , 1 , 39 , 43 , 69 , 429 , 87 , 2017 , 1961 , 5679 , 3179 ,0 }; - static ulong[] dim1199KuoInit = { 1 , 1 , 3 , 3 , 29 , 51 , 27 , 13 , 377 , 99 , 1291 , 247 , 2657 , 4793 ,0 }; - static ulong[] dim1200KuoInit = { 1 , 1 , 1 , 1 , 23 , 63 , 119 , 33 , 405 , 689 , 517 , 1331 , 1047 , 403 ,0 }; - static ulong[] dim1201KuoInit = { 1 , 1 , 1 , 5 , 9 , 27 , 121 , 49 , 317 , 181 , 623 , 1789 , 5867 , 11009 ,0 }; - static ulong[] dim1202KuoInit = { 1 , 1 , 7 , 15 , 15 , 63 , 113 , 129 , 299 , 889 , 361 , 2339 , 3893 , 3953 ,0 }; - static ulong[] dim1203KuoInit = { 1 , 1 , 1 , 15 , 9 , 51 , 73 , 77 , 511 , 745 , 639 , 1261 , 439 , 13409 ,0 }; - static ulong[] dim1204KuoInit = { 1 , 3 , 5 , 3 , 29 , 15 , 37 , 31 , 47 , 901 , 1383 , 1979 , 7341 , 13411 ,0 }; - static ulong[] dim1205KuoInit = { 1 , 3 , 7 , 5 , 31 , 59 , 87 , 35 , 123 , 943 , 1181 , 3877 , 4821 , 9231 ,0 }; - static ulong[] dim1206KuoInit = { 1 , 3 , 5 , 13 , 3 , 47 , 123 , 89 , 41 , 883 , 241 , 2055 , 1723 , 6747 ,0 }; - static ulong[] dim1207KuoInit = { 1 , 1 , 7 , 5 , 21 , 29 , 89 , 101 , 423 , 279 , 29 , 2089 , 6233 , 7343 ,0 }; - static ulong[] dim1208KuoInit = { 1 , 1 , 7 , 5 , 29 , 25 , 23 , 179 , 13 , 707 , 1603 , 585 , 4159 , 10767 ,0 }; - static ulong[] dim1209KuoInit = { 1 , 1 , 1 , 1 , 15 , 11 , 55 , 159 , 279 , 613 , 1445 , 613 , 499 , 7095 ,0 }; - static ulong[] dim1210KuoInit = { 1 , 1 , 1 , 5 , 15 , 61 , 75 , 171 , 173 , 765 , 1763 , 2193 , 7897 , 4559 ,0 }; - static ulong[] dim1211KuoInit = { 1 , 1 , 1 , 9 , 9 , 57 , 127 , 113 , 7 , 269 , 791 , 619 , 2923 , 6309 ,0 }; - static ulong[] dim1212KuoInit = { 1 , 1 , 3 , 13 , 21 , 9 , 99 , 1 , 263 , 69 , 1879 , 4079 , 33 , 7313 ,0 }; - static ulong[] dim1213KuoInit = { 1 , 1 , 7 , 9 , 17 , 1 , 69 , 93 , 147 , 461 , 1777 , 3375 , 4067 , 15307 ,0 }; - static ulong[] dim1214KuoInit = { 1 , 3 , 7 , 11 , 11 , 7 , 77 , 159 , 125 , 159 , 625 , 1339 , 2301 , 11525 ,0 }; - static ulong[] dim1215KuoInit = { 1 , 1 , 7 , 9 , 1 , 5 , 23 , 115 , 25 , 755 , 1523 , 2767 , 7667 , 7129 ,0 }; - static ulong[] dim1216KuoInit = { 1 , 1 , 5 , 5 , 23 , 31 , 41 , 3 , 249 , 69 , 1821 , 155 , 585 , 7905 ,0 }; - static ulong[] dim1217KuoInit = { 1 , 3 , 7 , 11 , 21 , 35 , 7 , 161 , 409 , 771 , 967 , 2429 , 1 , 5391 ,0 }; - static ulong[] dim1218KuoInit = { 1 , 1 , 1 , 9 , 9 , 3 , 13 , 125 , 87 , 115 , 1013 , 2103 , 4769 , 7389 ,0 }; - static ulong[] dim1219KuoInit = { 1 , 3 , 3 , 7 , 27 , 25 , 85 , 119 , 115 , 775 , 189 , 3577 , 5369 , 5213 ,0 }; - static ulong[] dim1220KuoInit = { 1 , 3 , 7 , 3 , 27 , 49 , 81 , 23 , 223 , 523 , 1939 , 431 , 6247 , 10509 ,0 }; - static ulong[] dim1221KuoInit = { 1 , 3 , 3 , 3 , 31 , 7 , 119 , 235 , 315 , 431 , 1669 , 1223 , 5785 , 6507 ,0 }; - static ulong[] dim1222KuoInit = { 1 , 1 , 5 , 9 , 27 , 23 , 35 , 141 , 327 , 395 , 869 , 177 , 3997 , 11191 ,0 }; - static ulong[] dim1223KuoInit = { 1 , 1 , 7 , 9 , 21 , 15 , 35 , 163 , 273 , 93 , 835 , 3339 , 6109 , 2617 ,0 }; - static ulong[] dim1224KuoInit = { 1 , 3 , 5 , 9 , 1 , 29 , 107 , 161 , 301 , 27 , 1391 , 211 , 5263 , 10899 ,0 }; - static ulong[] dim1225KuoInit = { 1 , 3 , 7 , 7 , 13 , 61 , 91 , 179 , 227 , 193 , 1909 , 3759 , 5875 , 6799 ,0 }; - static ulong[] dim1226KuoInit = { 1 , 3 , 1 , 9 , 17 , 23 , 57 , 117 , 201 , 459 , 1841 , 2371 , 2641 , 13927 ,0 }; - static ulong[] dim1227KuoInit = { 1 , 3 , 7 , 11 , 1 , 1 , 13 , 139 , 313 , 1 , 1551 , 2693 , 2785 , 6959 ,0 }; - static ulong[] dim1228KuoInit = { 1 , 3 , 3 , 13 , 1 , 29 , 117 , 67 , 147 , 821 , 1935 , 2913 , 7911 , 4829 ,0 }; - static ulong[] dim1229KuoInit = { 1 , 1 , 7 , 7 , 19 , 17 , 57 , 33 , 93 , 819 , 1035 , 3493 , 1831 , 5345 ,0 }; - static ulong[] dim1230KuoInit = { 1 , 3 , 5 , 13 , 9 , 13 , 117 , 219 , 415 , 743 , 381 , 2343 , 3865 , 3915 ,0 }; - static ulong[] dim1231KuoInit = { 1 , 1 , 5 , 15 , 3 , 25 , 67 , 197 , 59 , 419 , 461 , 1951 , 4657 , 9263 ,0 }; - static ulong[] dim1232KuoInit = { 1 , 1 , 7 , 15 , 31 , 53 , 33 , 213 , 169 , 231 , 615 , 441 , 7055 , 16079 ,0 }; - static ulong[] dim1233KuoInit = { 1 , 1 , 1 , 15 , 5 , 27 , 57 , 79 , 373 , 713 , 583 , 3773 , 4239 , 14231 ,0 }; - static ulong[] dim1234KuoInit = { 1 , 1 , 7 , 15 , 21 , 55 , 119 , 219 , 371 , 321 , 185 , 1103 , 7783 , 8705 ,0 }; - static ulong[] dim1235KuoInit = { 1 , 3 , 5 , 15 , 3 , 11 , 69 , 127 , 27 , 223 , 867 , 2249 , 597 , 10051 ,0 }; - static ulong[] dim1236KuoInit = { 1 , 3 , 5 , 7 , 5 , 13 , 99 , 115 , 21 , 659 , 1287 , 1941 , 6505 , 1091 ,0 }; - static ulong[] dim1237KuoInit = { 1 , 1 , 7 , 1 , 17 , 57 , 57 , 155 , 373 , 729 , 1521 , 3741 , 4935 , 13867 ,0 }; - static ulong[] dim1238KuoInit = { 1 , 1 , 7 , 1 , 19 , 21 , 39 , 47 , 451 , 67 , 463 , 1849 , 5311 , 5831 ,0 }; - static ulong[] dim1239KuoInit = { 1 , 3 , 7 , 7 , 29 , 11 , 59 , 161 , 29 , 107 , 1413 , 3915 , 6863 , 5095 ,0 }; - static ulong[] dim1240KuoInit = { 1 , 1 , 7 , 15 , 13 , 37 , 29 , 91 , 83 , 663 , 1629 , 3005 , 655 , 7601 ,0 }; - static ulong[] dim1241KuoInit = { 1 , 1 , 3 , 3 , 31 , 47 , 29 , 31 , 509 , 319 , 929 , 1481 , 6255 , 14003 ,0 }; - static ulong[] dim1242KuoInit = { 1 , 3 , 3 , 3 , 5 , 7 , 97 , 253 , 163 , 801 , 283 , 813 , 6277 , 3201 ,0 }; - static ulong[] dim1243KuoInit = { 1 , 3 , 3 , 15 , 5 , 59 , 49 , 47 , 259 , 837 , 2003 , 1489 , 3425 , 6863 ,0 }; - static ulong[] dim1244KuoInit = { 1 , 3 , 5 , 13 , 25 , 55 , 37 , 139 , 347 , 95 , 259 , 3175 , 1043 , 1395 ,0 }; - static ulong[] dim1245KuoInit = { 1 , 3 , 7 , 5 , 31 , 37 , 73 , 7 , 1 , 883 , 1641 , 1941 , 6885 , 23 ,0 }; - static ulong[] dim1246KuoInit = { 1 , 1 , 3 , 9 , 13 , 45 , 85 , 67 , 55 , 11 , 1717 , 3461 , 3189 , 15989 ,0 }; - static ulong[] dim1247KuoInit = { 1 , 1 , 1 , 13 , 27 , 15 , 93 , 39 , 329 , 43 , 175 , 2253 , 1193 , 13257 ,0 }; - static ulong[] dim1248KuoInit = { 1 , 3 , 3 , 1 , 25 , 41 , 111 , 211 , 99 , 267 , 965 , 1311 , 2661 , 1981 ,0 }; - static ulong[] dim1249KuoInit = { 1 , 3 , 7 , 15 , 31 , 15 , 37 , 73 , 239 , 505 , 983 , 3299 , 2891 , 8247 ,0 }; - static ulong[] dim1250KuoInit = { 1 , 1 , 5 , 3 , 19 , 5 , 45 , 55 , 251 , 125 , 977 , 955 , 1169 , 8495 ,0 }; - static ulong[] dim1251KuoInit = { 1 , 3 , 1 , 3 , 19 , 31 , 121 , 119 , 185 , 43 , 847 , 3939 , 2511 , 10889 ,0 }; - static ulong[] dim1252KuoInit = { 1 , 3 , 1 , 7 , 7 , 17 , 81 , 37 , 425 , 663 , 1715 , 789 , 661 , 9089 ,0 }; - static ulong[] dim1253KuoInit = { 1 , 3 , 3 , 11 , 1 , 3 , 17 , 247 , 311 , 369 , 211 , 97 , 6355 , 16297 ,0 }; - static ulong[] dim1254KuoInit = { 1 , 3 , 7 , 13 , 21 , 53 , 33 , 71 , 73 , 629 , 1321 , 3181 , 6627 , 161 ,0 }; - static ulong[] dim1255KuoInit = { 1 , 1 , 3 , 5 , 21 , 25 , 21 , 231 , 291 , 585 , 111 , 1651 , 1031 , 13705 ,0 }; - static ulong[] dim1256KuoInit = { 1 , 3 , 3 , 9 , 5 , 31 , 59 , 51 , 245 , 465 , 37 , 3425 , 4251 , 1121 ,0 }; - static ulong[] dim1257KuoInit = { 1 , 3 , 7 , 11 , 31 , 45 , 125 , 245 , 335 , 973 , 49 , 1557 , 4847 , 10739 ,0 }; - static ulong[] dim1258KuoInit = { 1 , 1 , 1 , 3 , 21 , 39 , 127 , 67 , 101 , 9 , 1099 , 1159 , 2483 , 4283 ,0 }; - static ulong[] dim1259KuoInit = { 1 , 1 , 7 , 13 , 29 , 53 , 49 , 65 , 5 , 775 , 433 , 351 , 493 , 7233 ,0 }; - static ulong[] dim1260KuoInit = { 1 , 3 , 5 , 5 , 27 , 13 , 73 , 83 , 417 , 31 , 1891 , 1809 , 1103 , 4555 ,0 }; - static ulong[] dim1261KuoInit = { 1 , 1 , 5 , 9 , 15 , 1 , 25 , 63 , 191 , 251 , 1759 , 429 , 2477 , 12577 ,0 }; - static ulong[] dim1262KuoInit = { 1 , 1 , 3 , 5 , 3 , 21 , 61 , 245 , 191 , 217 , 845 , 2121 , 2133 , 6045 ,0 }; - static ulong[] dim1263KuoInit = { 1 , 3 , 3 , 5 , 23 , 33 , 85 , 15 , 57 , 645 , 1109 , 3411 , 2895 , 6885 ,0 }; - static ulong[] dim1264KuoInit = { 1 , 3 , 3 , 11 , 13 , 41 , 13 , 59 , 45 , 199 , 1145 , 2637 , 6741 , 1273 ,0 }; - static ulong[] dim1265KuoInit = { 1 , 3 , 3 , 5 , 27 , 33 , 121 , 21 , 75 , 687 , 349 , 2097 , 1195 , 4227 ,0 }; - static ulong[] dim1266KuoInit = { 1 , 1 , 7 , 9 , 25 , 51 , 71 , 85 , 281 , 825 , 1335 , 277 , 797 , 407 ,0 }; - static ulong[] dim1267KuoInit = { 1 , 3 , 3 , 15 , 21 , 31 , 19 , 11 , 39 , 821 , 1623 , 97 , 1573 , 13297 ,0 }; - static ulong[] dim1268KuoInit = { 1 , 1 , 3 , 1 , 25 , 39 , 67 , 113 , 109 , 719 , 1427 , 2539 , 5885 , 13537 ,0 }; - static ulong[] dim1269KuoInit = { 1 , 1 , 5 , 3 , 15 , 53 , 11 , 139 , 393 , 365 , 709 , 1603 , 4929 , 2651 ,0 }; - static ulong[] dim1270KuoInit = { 1 , 3 , 7 , 5 , 3 , 11 , 19 , 41 , 123 , 7 , 993 , 3627 , 2027 , 4009 ,0 }; - static ulong[] dim1271KuoInit = { 1 , 1 , 3 , 7 , 3 , 17 , 63 , 129 , 323 , 303 , 1669 , 1023 , 1259 , 289 ,0 }; - static ulong[] dim1272KuoInit = { 1 , 3 , 7 , 15 , 15 , 33 , 69 , 229 , 291 , 939 , 969 , 2497 , 4323 , 16299 ,0 }; - static ulong[] dim1273KuoInit = { 1 , 3 , 5 , 5 , 17 , 35 , 79 , 33 , 471 , 857 , 975 , 297 , 7219 , 12903 ,0 }; - static ulong[] dim1274KuoInit = { 1 , 1 , 7 , 7 , 21 , 5 , 65 , 53 , 11 , 265 , 1447 , 1405 , 3351 , 2661 ,0 }; - static ulong[] dim1275KuoInit = { 1 , 3 , 3 , 3 , 1 , 21 , 123 , 123 , 361 , 71 , 1233 , 2673 , 7643 , 9519 ,0 }; - static ulong[] dim1276KuoInit = { 1 , 1 , 5 , 7 , 27 , 41 , 117 , 239 , 125 , 183 , 1375 , 649 , 5267 , 1735 ,0 }; - static ulong[] dim1277KuoInit = { 1 , 1 , 1 , 11 , 7 , 33 , 59 , 7 , 37 , 705 , 1055 , 1661 , 6213 , 2083 ,0 }; - static ulong[] dim1278KuoInit = { 1 , 3 , 1 , 9 , 11 , 61 , 91 , 143 , 113 , 229 , 809 , 431 , 1971 , 12453 ,0 }; - static ulong[] dim1279KuoInit = { 1 , 1 , 3 , 9 , 17 , 23 , 97 , 249 , 109 , 669 , 1643 , 3305 , 6141 , 1793 ,0 }; - static ulong[] dim1280KuoInit = { 1 , 1 , 5 , 13 , 3 , 39 , 37 , 107 , 123 , 637 , 869 , 1969 , 4195 , 9431 ,0 }; - static ulong[] dim1281KuoInit = { 1 , 1 , 7 , 13 , 7 , 25 , 97 , 63 , 395 , 1011 , 161 , 827 , 4001 , 15159 ,0 }; - static ulong[] dim1282KuoInit = { 1 , 1 , 3 , 7 , 11 , 59 , 11 , 49 , 25 , 691 , 73 , 1171 , 2937 , 13877 ,0 }; - static ulong[] dim1283KuoInit = { 1 , 3 , 7 , 15 , 1 , 19 , 119 , 129 , 63 , 451 , 1593 , 1207 , 67 , 3621 ,0 }; - static ulong[] dim1284KuoInit = { 1 , 1 , 1 , 1 , 25 , 27 , 45 , 23 , 111 , 191 , 1205 , 4079 , 1821 , 5571 ,0 }; - static ulong[] dim1285KuoInit = { 1 , 1 , 7 , 5 , 17 , 37 , 37 , 249 , 81 , 909 , 153 , 209 , 7919 , 10763 ,0 }; - static ulong[] dim1286KuoInit = { 1 , 3 , 5 , 5 , 19 , 9 , 101 , 193 , 431 , 63 , 1309 , 2693 , 2413 , 14513 ,0 }; - static ulong[] dim1287KuoInit = { 1 , 3 , 5 , 7 , 13 , 5 , 5 , 203 , 313 , 723 , 1637 , 2725 , 4197 , 3767 ,0 }; - static ulong[] dim1288KuoInit = { 1 , 3 , 3 , 11 , 1 , 53 , 33 , 245 , 181 , 1001 , 1057 , 2701 , 5861 , 4199 ,0 }; - static ulong[] dim1289KuoInit = { 1 , 1 , 5 , 3 , 31 , 35 , 19 , 253 , 403 , 429 , 1667 , 1671 , 7491 , 1023 ,0 }; - static ulong[] dim1290KuoInit = { 1 , 3 , 5 , 7 , 15 , 51 , 41 , 253 , 247 , 883 , 1887 , 1067 , 3227 , 13259 ,0 }; - static ulong[] dim1291KuoInit = { 1 , 3 , 7 , 15 , 5 , 63 , 9 , 97 , 87 , 11 , 1873 , 2529 , 833 , 5583 ,0 }; - static ulong[] dim1292KuoInit = { 1 , 1 , 5 , 7 , 17 , 59 , 23 , 225 , 91 , 189 , 923 , 3177 , 599 , 4315 ,0 }; - static ulong[] dim1293KuoInit = { 1 , 3 , 3 , 11 , 15 , 59 , 85 , 75 , 281 , 935 , 1219 , 3121 , 231 , 13839 ,0 }; - static ulong[] dim1294KuoInit = { 1 , 1 , 5 , 9 , 15 , 61 , 105 , 27 , 179 , 145 , 827 , 2985 , 6907 , 14961 ,0 }; - static ulong[] dim1295KuoInit = { 1 , 1 , 1 , 1 , 1 , 63 , 7 , 3 , 449 , 387 , 483 , 603 , 6607 , 13241 ,0 }; - static ulong[] dim1296KuoInit = { 1 , 1 , 7 , 1 , 9 , 37 , 73 , 255 , 331 , 797 , 679 , 579 , 3015 , 2517 ,0 }; - static ulong[] dim1297KuoInit = { 1 , 1 , 3 , 5 , 23 , 15 , 97 , 159 , 9 , 469 , 881 , 1935 , 1871 , 7943 ,0 }; - static ulong[] dim1298KuoInit = { 1 , 1 , 7 , 15 , 31 , 33 , 103 , 247 , 7 , 217 , 397 , 3761 , 3071 , 15357 ,0 }; - static ulong[] dim1299KuoInit = { 1 , 3 , 3 , 9 , 23 , 25 , 61 , 61 , 495 , 195 , 1615 , 923 , 6583 , 11169 ,0 }; - static ulong[] dim1300KuoInit = { 1 , 1 , 3 , 9 , 25 , 7 , 67 , 105 , 423 , 519 , 327 , 2789 , 7527 , 13465 ,0 }; - static ulong[] dim1301KuoInit = { 1 , 1 , 3 , 11 , 29 , 57 , 21 , 47 , 71 , 771 , 1255 , 1469 , 737 , 11533 ,0 }; - static ulong[] dim1302KuoInit = { 1 , 1 , 5 , 11 , 23 , 31 , 103 , 145 , 19 , 931 , 963 , 2627 , 1419 , 14451 ,0 }; - static ulong[] dim1303KuoInit = { 1 , 3 , 7 , 1 , 15 , 45 , 37 , 57 , 223 , 151 , 979 , 2569 , 2487 , 2877 ,0 }; - static ulong[] dim1304KuoInit = { 1 , 1 , 3 , 7 , 13 , 39 , 83 , 127 , 341 , 687 , 1575 , 3193 , 2845 , 725 ,0 }; - static ulong[] dim1305KuoInit = { 1 , 1 , 1 , 5 , 23 , 39 , 71 , 205 , 53 , 477 , 1961 , 3967 , 7169 , 5443 ,0 }; - static ulong[] dim1306KuoInit = { 1 , 1 , 5 , 5 , 23 , 17 , 107 , 151 , 291 , 101 , 1917 , 3429 , 6279 , 1781 ,0 }; - static ulong[] dim1307KuoInit = { 1 , 3 , 3 , 11 , 23 , 45 , 11 , 137 , 243 , 257 , 495 , 3267 , 1373 , 15477 ,0 }; - static ulong[] dim1308KuoInit = { 1 , 1 , 7 , 5 , 23 , 13 , 37 , 139 , 473 , 215 , 1281 , 989 , 2187 , 1551 ,0 }; - static ulong[] dim1309KuoInit = { 1 , 1 , 7 , 7 , 5 , 21 , 113 , 195 , 247 , 493 , 513 , 1775 , 1885 , 5131 ,0 }; - static ulong[] dim1310KuoInit = { 1 , 1 , 7 , 15 , 29 , 31 , 9 , 59 , 329 , 11 , 1739 , 1657 , 1745 , 8969 ,0 }; - static ulong[] dim1311KuoInit = { 1 , 1 , 3 , 7 , 19 , 29 , 121 , 171 , 33 , 393 , 1463 , 1817 , 393 , 2509 ,0 }; - static ulong[] dim1312KuoInit = { 1 , 1 , 5 , 11 , 23 , 55 , 103 , 169 , 313 , 293 , 1791 , 2727 , 2311 , 14519 ,0 }; - static ulong[] dim1313KuoInit = { 1 , 3 , 7 , 11 , 13 , 21 , 95 , 205 , 87 , 431 , 667 , 367 , 6879 , 9843 ,0 }; - static ulong[] dim1314KuoInit = { 1 , 3 , 1 , 3 , 3 , 53 , 75 , 43 , 115 , 561 , 795 , 613 , 4491 , 913 ,0 }; - static ulong[] dim1315KuoInit = { 1 , 1 , 5 , 5 , 25 , 37 , 71 , 13 , 499 , 105 , 9 , 3759 , 4997 , 14747 ,0 }; - static ulong[] dim1316KuoInit = { 1 , 3 , 3 , 13 , 25 , 63 , 27 , 163 , 359 , 431 , 5 , 3371 , 6051 , 1099 ,0 }; - static ulong[] dim1317KuoInit = { 1 , 1 , 3 , 7 , 5 , 45 , 19 , 217 , 423 , 171 , 933 , 3441 , 7451 , 11831 ,0 }; - static ulong[] dim1318KuoInit = { 1 , 3 , 7 , 7 , 7 , 53 , 81 , 67 , 465 , 713 , 1761 , 3945 , 3051 , 8139 ,0 }; - static ulong[] dim1319KuoInit = { 1 , 1 , 5 , 7 , 23 , 55 , 85 , 205 , 265 , 99 , 353 , 4061 , 3385 , 4273 ,0 }; - static ulong[] dim1320KuoInit = { 1 , 3 , 7 , 7 , 9 , 19 , 7 , 81 , 9 , 373 , 837 , 1397 , 3945 , 14325 ,0 }; - static ulong[] dim1321KuoInit = { 1 , 1 , 5 , 7 , 7 , 47 , 61 , 195 , 101 , 931 , 1667 , 3277 , 7701 , 14697 ,0 }; - static ulong[] dim1322KuoInit = { 1 , 3 , 7 , 7 , 11 , 57 , 43 , 55 , 399 , 783 , 1647 , 269 , 6055 , 9935 ,0 }; - static ulong[] dim1323KuoInit = { 1 , 1 , 5 , 3 , 5 , 57 , 87 , 193 , 15 , 515 , 1663 , 495 , 4725 , 7221 ,0 }; - static ulong[] dim1324KuoInit = { 1 , 1 , 5 , 3 , 23 , 23 , 87 , 231 , 133 , 123 , 1477 , 1811 , 7383 , 16339 ,0 }; - static ulong[] dim1325KuoInit = { 1 , 3 , 5 , 13 , 31 , 57 , 105 , 237 , 375 , 129 , 193 , 1293 , 2445 , 13383 ,0 }; - static ulong[] dim1326KuoInit = { 1 , 3 , 7 , 13 , 19 , 51 , 91 , 27 , 309 , 421 , 647 , 3777 , 6779 , 2807 ,0 }; - static ulong[] dim1327KuoInit = { 1 , 3 , 5 , 15 , 5 , 43 , 125 , 37 , 269 , 155 , 1733 , 447 , 7883 , 6085 ,0 }; - static ulong[] dim1328KuoInit = { 1 , 3 , 7 , 7 , 27 , 63 , 91 , 7 , 117 , 369 , 1019 , 847 , 6747 , 5057 ,0 }; - static ulong[] dim1329KuoInit = { 1 , 3 , 5 , 3 , 31 , 19 , 87 , 125 , 259 , 355 , 161 , 1421 , 2295 , 9683 ,0 }; - static ulong[] dim1330KuoInit = { 1 , 3 , 3 , 13 , 25 , 37 , 63 , 169 , 477 , 633 , 231 , 2039 , 3469 , 2531 ,0 }; - static ulong[] dim1331KuoInit = { 1 , 3 , 1 , 1 , 25 , 1 , 81 , 211 , 237 , 233 , 1743 , 961 , 645 , 2605 ,0 }; - static ulong[] dim1332KuoInit = { 1 , 3 , 1 , 11 , 3 , 25 , 3 , 111 , 123 , 417 , 1799 , 1419 , 2501 , 5765 ,0 }; - static ulong[] dim1333KuoInit = { 1 , 1 , 3 , 15 , 11 , 17 , 27 , 95 , 295 , 315 , 987 , 481 , 6627 , 16171 ,0 }; - static ulong[] dim1334KuoInit = { 1 , 3 , 5 , 15 , 15 , 61 , 123 , 5 , 369 , 161 , 897 , 855 , 625 , 9975 ,0 }; - static ulong[] dim1335KuoInit = { 1 , 1 , 5 , 3 , 9 , 45 , 59 , 53 , 43 , 117 , 789 , 21 , 7799 , 11061 ,0 }; - static ulong[] dim1336KuoInit = { 1 , 1 , 3 , 7 , 3 , 17 , 113 , 159 , 115 , 965 , 1541 , 1037 , 4723 , 10151 ,0 }; - static ulong[] dim1337KuoInit = { 1 , 3 , 1 , 9 , 7 , 15 , 19 , 161 , 123 , 421 , 109 , 433 , 7387 , 6047 ,0 }; - static ulong[] dim1338KuoInit = { 1 , 3 , 1 , 13 , 19 , 49 , 31 , 215 , 25 , 289 , 1995 , 1135 , 3719 , 8453 ,0 }; - static ulong[] dim1339KuoInit = { 1 , 3 , 3 , 9 , 3 , 33 , 15 , 191 , 83 , 963 , 199 , 2199 , 3273 , 16165 ,0 }; - static ulong[] dim1340KuoInit = { 1 , 3 , 3 , 11 , 17 , 63 , 71 , 49 , 427 , 633 , 735 , 2009 , 5049 , 13649 ,0 }; - static ulong[] dim1341KuoInit = { 1 , 1 , 3 , 7 , 25 , 41 , 79 , 161 , 293 , 967 , 969 , 3253 , 269 , 6971 ,0 }; - static ulong[] dim1342KuoInit = { 1 , 1 , 5 , 7 , 25 , 9 , 43 , 237 , 283 , 135 , 669 , 2193 , 4193 , 4787 ,0 }; - static ulong[] dim1343KuoInit = { 1 , 3 , 3 , 7 , 5 , 19 , 83 , 89 , 443 , 443 , 1511 , 2309 , 5483 , 7583 ,0 }; - static ulong[] dim1344KuoInit = { 1 , 3 , 3 , 15 , 21 , 29 , 113 , 127 , 405 , 465 , 1135 , 2401 , 7715 , 13061 ,0 }; - static ulong[] dim1345KuoInit = { 1 , 3 , 7 , 7 , 23 , 19 , 17 , 59 , 483 , 519 , 1439 , 3839 , 1691 , 5 ,0 }; - static ulong[] dim1346KuoInit = { 1 , 1 , 1 , 13 , 23 , 43 , 115 , 103 , 155 , 769 , 455 , 17 , 7791 , 3333 ,0 }; - static ulong[] dim1347KuoInit = { 1 , 1 , 7 , 9 , 3 , 25 , 31 , 7 , 125 , 357 , 759 , 1203 , 2107 , 5361 ,0 }; - static ulong[] dim1348KuoInit = { 1 , 1 , 5 , 11 , 27 , 31 , 23 , 73 , 77 , 449 , 661 , 2337 , 941 , 9421 ,0 }; - static ulong[] dim1349KuoInit = { 1 , 1 , 7 , 15 , 27 , 17 , 35 , 15 , 405 , 317 , 1977 , 2449 , 237 , 7741 ,0 }; - static ulong[] dim1350KuoInit = { 1 , 1 , 7 , 3 , 1 , 15 , 63 , 251 , 61 , 123 , 855 , 773 , 4291 , 15581 ,0 }; - static ulong[] dim1351KuoInit = { 1 , 1 , 5 , 9 , 15 , 49 , 101 , 215 , 239 , 31 , 1193 , 3839 , 1913 , 15471 ,0 }; - static ulong[] dim1352KuoInit = { 1 , 3 , 3 , 5 , 29 , 1 , 109 , 211 , 97 , 1017 , 1477 , 2131 , 6539 , 4891 ,0 }; - static ulong[] dim1353KuoInit = { 1 , 1 , 3 , 11 , 15 , 63 , 67 , 175 , 209 , 105 , 1427 , 769 , 7021 , 287 ,0 }; - static ulong[] dim1354KuoInit = { 1 , 3 , 3 , 7 , 19 , 41 , 109 , 165 , 307 , 935 , 379 , 395 , 2533 , 6291 ,0 }; - static ulong[] dim1355KuoInit = { 1 , 3 , 5 , 13 , 17 , 3 , 69 , 79 , 437 , 861 , 1115 , 1351 , 4951 , 1753 ,0 }; - static ulong[] dim1356KuoInit = { 1 , 3 , 1 , 7 , 19 , 15 , 83 , 85 , 431 , 207 , 481 , 711 , 6715 , 13439 ,0 }; - static ulong[] dim1357KuoInit = { 1 , 1 , 1 , 5 , 3 , 13 , 127 , 27 , 223 , 297 , 985 , 227 , 6665 , 13587 ,0 }; - static ulong[] dim1358KuoInit = { 1 , 3 , 7 , 7 , 7 , 61 , 113 , 73 , 443 , 397 , 717 , 1151 , 3047 , 3247 ,0 }; - static ulong[] dim1359KuoInit = { 1 , 1 , 1 , 9 , 1 , 1 , 103 , 239 , 351 , 305 , 1345 , 3543 , 4321 , 9147 ,0 }; - static ulong[] dim1360KuoInit = { 1 , 1 , 3 , 1 , 11 , 53 , 57 , 85 , 95 , 707 , 1817 , 249 , 357 , 11769 ,0 }; - static ulong[] dim1361KuoInit = { 1 , 3 , 1 , 15 , 15 , 25 , 7 , 169 , 499 , 717 , 915 , 365 , 3131 , 12487 ,0 }; - static ulong[] dim1362KuoInit = { 1 , 1 , 3 , 11 , 15 , 47 , 109 , 9 , 171 , 67 , 1473 , 1779 , 5567 , 3799 ,0 }; - static ulong[] dim1363KuoInit = { 1 , 3 , 5 , 15 , 23 , 21 , 31 , 59 , 1 , 505 , 1157 , 1209 , 7661 , 11903 ,0 }; - static ulong[] dim1364KuoInit = { 1 , 3 , 1 , 13 , 11 , 5 , 75 , 53 , 481 , 433 , 915 , 2881 , 5299 , 2835 ,0 }; - static ulong[] dim1365KuoInit = { 1 , 3 , 7 , 5 , 23 , 13 , 127 , 229 , 157 , 643 , 847 , 3613 , 1999 , 3807 ,0 }; - static ulong[] dim1366KuoInit = { 1 , 3 , 5 , 11 , 13 , 39 , 79 , 11 , 131 , 603 , 1013 , 1197 , 7583 , 8195 ,0 }; - static ulong[] dim1367KuoInit = { 1 , 3 , 3 , 7 , 27 , 29 , 99 , 19 , 503 , 455 , 1453 , 2233 , 2479 , 8489 ,0 }; - static ulong[] dim1368KuoInit = { 1 , 3 , 5 , 1 , 21 , 37 , 27 , 207 , 405 , 87 , 319 , 3323 , 4809 , 12599 ,0 }; - static ulong[] dim1369KuoInit = { 1 , 3 , 7 , 15 , 29 , 3 , 121 , 249 , 31 , 601 , 865 , 2819 , 2633 , 15541 ,0 }; - static ulong[] dim1370KuoInit = { 1 , 3 , 5 , 1 , 25 , 53 , 121 , 57 , 75 , 327 , 2047 , 253 , 7945 , 14209 ,0 }; - static ulong[] dim1371KuoInit = { 1 , 1 , 7 , 11 , 21 , 3 , 13 , 91 , 417 , 825 , 1381 , 3653 , 4187 , 4685 ,0 }; - static ulong[] dim1372KuoInit = { 1 , 3 , 3 , 9 , 11 , 17 , 87 , 75 , 333 , 871 , 1679 , 2943 , 4803 , 8147 ,0 }; - static ulong[] dim1373KuoInit = { 1 , 1 , 1 , 9 , 13 , 1 , 105 , 95 , 347 , 543 , 1435 , 2337 , 5971 , 7605 ,0 }; - static ulong[] dim1374KuoInit = { 1 , 3 , 5 , 15 , 19 , 51 , 35 , 91 , 187 , 833 , 1921 , 573 , 3605 , 8627 ,0 }; - static ulong[] dim1375KuoInit = { 1 , 3 , 5 , 7 , 25 , 7 , 115 , 93 , 87 , 13 , 1323 , 3821 , 587 , 5079 ,0 }; - static ulong[] dim1376KuoInit = { 1 , 3 , 5 , 3 , 25 , 25 , 89 , 185 , 473 , 909 , 1245 , 1589 , 63 , 10765 ,0 }; - static ulong[] dim1377KuoInit = { 1 , 3 , 5 , 5 , 15 , 3 , 9 , 149 , 237 , 107 , 879 , 2487 , 7995 , 12713 ,0 }; - static ulong[] dim1378KuoInit = { 1 , 3 , 3 , 3 , 19 , 55 , 43 , 221 , 289 , 129 , 1123 , 3411 , 703 , 9585 ,0 }; - static ulong[] dim1379KuoInit = { 1 , 1 , 5 , 3 , 7 , 63 , 13 , 243 , 235 , 253 , 357 , 563 , 519 , 3471 ,0 }; - static ulong[] dim1380KuoInit = { 1 , 1 , 3 , 13 , 9 , 59 , 67 , 61 , 321 , 149 , 365 , 2645 , 2309 , 3303 ,0 }; - static ulong[] dim1381KuoInit = { 1 , 1 , 5 , 5 , 13 , 7 , 53 , 175 , 207 , 507 , 1159 , 3869 , 8139 , 13899 ,0 }; - static ulong[] dim1382KuoInit = { 1 , 3 , 5 , 3 , 23 , 9 , 123 , 37 , 325 , 41 , 679 , 513 , 4379 , 3493 ,0 }; - static ulong[] dim1383KuoInit = { 1 , 1 , 7 , 3 , 29 , 9 , 117 , 203 , 461 , 831 , 1757 , 2815 , 1215 , 1725 ,0 }; - static ulong[] dim1384KuoInit = { 1 , 1 , 7 , 7 , 23 , 45 , 75 , 159 , 395 , 315 , 709 , 887 , 6935 , 2307 ,0 }; - static ulong[] dim1385KuoInit = { 1 , 1 , 7 , 7 , 5 , 51 , 29 , 141 , 215 , 783 , 1161 , 3887 , 8103 , 7461 ,0 }; - static ulong[] dim1386KuoInit = { 1 , 1 , 7 , 3 , 21 , 5 , 59 , 123 , 283 , 921 , 225 , 453 , 2125 , 559 ,0 }; - static ulong[] dim1387KuoInit = { 1 , 3 , 7 , 13 , 21 , 19 , 121 , 201 , 367 , 215 , 1727 , 1743 , 4875 , 2819 ,0 }; - static ulong[] dim1388KuoInit = { 1 , 3 , 3 , 13 , 15 , 53 , 57 , 35 , 419 , 595 , 1581 , 2881 , 3473 , 7201 ,0 }; - static ulong[] dim1389KuoInit = { 1 , 3 , 5 , 5 , 19 , 17 , 113 , 175 , 195 , 829 , 115 , 491 , 6439 , 4085 ,0 }; - static ulong[] dim1390KuoInit = { 1 , 1 , 5 , 9 , 7 , 9 , 111 , 23 , 459 , 335 , 1529 , 1519 , 2855 , 11923 ,0 }; - static ulong[] dim1391KuoInit = { 1 , 3 , 7 , 9 , 13 , 41 , 19 , 229 , 73 , 865 , 1379 , 1315 , 1403 , 10489 ,0 }; - static ulong[] dim1392KuoInit = { 1 , 1 , 1 , 7 , 17 , 35 , 71 , 199 , 195 , 89 , 855 , 355 , 5087 , 13173 ,0 }; - static ulong[] dim1393KuoInit = { 1 , 3 , 5 , 7 , 3 , 45 , 77 , 109 , 105 , 919 , 21 , 2749 , 5401 , 11701 ,0 }; - static ulong[] dim1394KuoInit = { 1 , 3 , 1 , 15 , 5 , 9 , 29 , 213 , 489 , 455 , 791 , 215 , 1011 , 2501 ,0 }; - static ulong[] dim1395KuoInit = { 1 , 3 , 1 , 9 , 17 , 7 , 61 , 99 , 381 , 669 , 1787 , 1443 , 6135 , 3273 ,0 }; - static ulong[] dim1396KuoInit = { 1 , 3 , 1 , 3 , 27 , 47 , 31 , 153 , 365 , 271 , 1499 , 1229 , 5791 , 2251 ,0 }; - static ulong[] dim1397KuoInit = { 1 , 1 , 1 , 3 , 9 , 31 , 109 , 53 , 293 , 135 , 1329 , 2795 , 4335 , 14817 ,0 }; - static ulong[] dim1398KuoInit = { 1 , 3 , 1 , 15 , 19 , 7 , 43 , 223 , 483 , 237 , 803 , 1713 , 7969 , 9681 ,0 }; - static ulong[] dim1399KuoInit = { 1 , 1 , 7 , 1 , 23 , 45 , 67 , 87 , 57 , 261 , 955 , 2917 , 549 , 4725 ,0 }; - static ulong[] dim1400KuoInit = { 1 , 1 , 1 , 7 , 13 , 43 , 63 , 153 , 395 , 313 , 1219 , 655 , 6489 , 2129 ,0 }; - static ulong[] dim1401KuoInit = { 1 , 3 , 3 , 3 , 7 , 51 , 35 , 233 , 289 , 715 , 1227 , 2041 , 3639 , 1465 ,0 }; - static ulong[] dim1402KuoInit = { 1 , 3 , 1 , 7 , 3 , 37 , 97 , 149 , 51 , 313 , 1883 , 1411 , 3319 , 2599 ,0 }; - static ulong[] dim1403KuoInit = { 1 , 1 , 7 , 13 , 25 , 13 , 89 , 245 , 251 , 841 , 1367 , 4039 , 4389 , 7129 ,0 }; - static ulong[] dim1404KuoInit = { 1 , 3 , 5 , 15 , 3 , 55 , 113 , 97 , 159 , 621 , 251 , 2539 , 7017 , 1039 ,0 }; - static ulong[] dim1405KuoInit = { 1 , 3 , 3 , 9 , 27 , 31 , 53 , 61 , 165 , 753 , 1733 , 671 , 665 , 4893 ,0 }; - static ulong[] dim1406KuoInit = { 1 , 1 , 7 , 5 , 25 , 11 , 7 , 189 , 457 , 5 , 97 , 2399 , 3089 , 4811 ,0 }; - static ulong[] dim1407KuoInit = { 1 , 1 , 3 , 13 , 29 , 19 , 73 , 105 , 187 , 871 , 499 , 443 , 6807 , 3753 ,0 }; - static ulong[] dim1408KuoInit = { 1 , 3 , 1 , 5 , 9 , 15 , 53 , 83 , 91 , 763 , 1585 , 1675 , 5137 , 10483 ,0 }; - static ulong[] dim1409KuoInit = { 1 , 1 , 7 , 5 , 25 , 51 , 43 , 47 , 151 , 13 , 1117 , 1465 , 2497 , 7677 ,0 }; - static ulong[] dim1410KuoInit = { 1 , 1 , 1 , 3 , 15 , 15 , 43 , 53 , 161 , 689 , 2027 , 437 , 3599 , 6837 ,0 }; - static ulong[] dim1411KuoInit = { 1 , 3 , 3 , 9 , 21 , 5 , 81 , 99 , 249 , 785 , 763 , 1203 , 1541 , 6497 ,0 }; - static ulong[] dim1412KuoInit = { 1 , 1 , 5 , 7 , 27 , 7 , 121 , 91 , 271 , 461 , 1531 , 3255 , 847 , 14503 ,0 }; - static ulong[] dim1413KuoInit = { 1 , 1 , 3 , 15 , 9 , 53 , 125 , 107 , 321 , 579 , 813 , 2295 , 2521 , 6773 ,0 }; - static ulong[] dim1414KuoInit = { 1 , 3 , 3 , 1 , 15 , 55 , 71 , 61 , 307 , 917 , 217 , 1133 , 7255 , 16083 ,0 }; - static ulong[] dim1415KuoInit = { 1 , 3 , 1 , 1 , 3 , 7 , 57 , 27 , 243 , 989 , 223 , 3857 , 2357 , 11315 ,0 }; - static ulong[] dim1416KuoInit = { 1 , 3 , 5 , 5 , 23 , 41 , 55 , 75 , 241 , 829 , 1865 , 909 , 4509 , 5163 ,0 }; - static ulong[] dim1417KuoInit = { 1 , 1 , 1 , 13 , 27 , 5 , 117 , 79 , 171 , 135 , 623 , 2515 , 3661 , 941 ,0 }; - static ulong[] dim1418KuoInit = { 1 , 3 , 5 , 13 , 17 , 29 , 9 , 147 , 73 , 321 , 895 , 3263 , 6897 , 8551 ,0 }; - static ulong[] dim1419KuoInit = { 1 , 1 , 5 , 11 , 21 , 45 , 57 , 153 , 83 , 971 , 403 , 617 , 545 , 6489 ,0 }; - static ulong[] dim1420KuoInit = { 1 , 1 , 5 , 9 , 31 , 37 , 19 , 241 , 89 , 583 , 1365 , 2649 , 7011 , 6183 ,0 }; - static ulong[] dim1421KuoInit = { 1 , 3 , 5 , 9 , 3 , 5 , 45 , 237 , 351 , 811 , 445 , 557 , 4103 , 11185 ,0 }; - static ulong[] dim1422KuoInit = { 1 , 3 , 3 , 13 , 25 , 23 , 21 , 249 , 209 , 775 , 1397 , 2501 , 4535 , 4957 ,0 }; - static ulong[] dim1423KuoInit = { 1 , 1 , 1 , 13 , 7 , 43 , 55 , 179 , 239 , 43 , 225 , 2827 , 955 , 665 ,0 }; - static ulong[] dim1424KuoInit = { 1 , 1 , 3 , 5 , 15 , 35 , 77 , 153 , 429 , 35 , 539 , 3543 , 1971 , 2865 ,0 }; - static ulong[] dim1425KuoInit = { 1 , 3 , 7 , 3 , 27 , 35 , 87 , 51 , 281 , 247 , 547 , 2185 , 2593 , 1301 ,0 }; - static ulong[] dim1426KuoInit = { 1 , 3 , 5 , 11 , 19 , 11 , 79 , 241 , 467 , 515 , 531 , 3285 , 1575 , 7869 ,0 }; - static ulong[] dim1427KuoInit = { 1 , 3 , 1 , 13 , 25 , 15 , 109 , 231 , 349 , 955 , 2019 , 3475 , 2927 , 14383 ,0 }; - static ulong[] dim1428KuoInit = { 1 , 1 , 7 , 1 , 17 , 43 , 43 , 131 , 485 , 179 , 901 , 483 , 4879 , 15189 ,0 }; - static ulong[] dim1429KuoInit = { 1 , 1 , 5 , 11 , 7 , 39 , 111 , 27 , 29 , 79 , 261 , 77 , 231 , 8577 ,0 }; - static ulong[] dim1430KuoInit = { 1 , 3 , 1 , 11 , 25 , 15 , 25 , 41 , 457 , 677 , 1033 , 161 , 3215 , 105 ,0 }; - static ulong[] dim1431KuoInit = { 1 , 3 , 1 , 15 , 3 , 57 , 125 , 41 , 325 , 467 , 1325 , 1287 , 51 , 9463 ,0 }; - static ulong[] dim1432KuoInit = { 1 , 1 , 1 , 9 , 1 , 33 , 39 , 47 , 313 , 305 , 2023 , 1131 , 4167 , 4519 ,0 }; - static ulong[] dim1433KuoInit = { 1 , 1 , 5 , 15 , 1 , 47 , 123 , 151 , 263 , 143 , 91 , 1673 , 4175 , 4575 ,0 }; - static ulong[] dim1434KuoInit = { 1 , 1 , 7 , 3 , 7 , 41 , 95 , 27 , 183 , 437 , 587 , 3821 , 8035 , 7627 ,0 }; - static ulong[] dim1435KuoInit = { 1 , 1 , 3 , 5 , 17 , 53 , 95 , 73 , 335 , 497 , 643 , 3309 , 7139 , 10811 ,0 }; - static ulong[] dim1436KuoInit = { 1 , 3 , 1 , 13 , 7 , 29 , 83 , 15 , 29 , 881 , 881 , 1253 , 7267 , 4221 ,0 }; - static ulong[] dim1437KuoInit = { 1 , 3 , 7 , 13 , 15 , 47 , 71 , 63 , 493 , 365 , 1209 , 2503 , 3963 , 5069 ,0 }; - static ulong[] dim1438KuoInit = { 1 , 1 , 5 , 5 , 23 , 55 , 107 , 255 , 17 , 561 , 1131 , 497 , 5731 , 13287 ,0 }; - static ulong[] dim1439KuoInit = { 1 , 3 , 5 , 11 , 5 , 59 , 25 , 131 , 375 , 165 , 1051 , 3129 , 6517 , 6317 ,0 }; - static ulong[] dim1440KuoInit = { 1 , 3 , 5 , 9 , 17 , 29 , 57 , 215 , 77 , 197 , 1775 , 3959 , 185 , 11431 ,0 }; - static ulong[] dim1441KuoInit = { 1 , 1 , 1 , 11 , 11 , 45 , 29 , 245 , 193 , 747 , 1449 , 2185 , 7751 , 10009 ,0 }; - static ulong[] dim1442KuoInit = { 1 , 1 , 1 , 5 , 27 , 19 , 39 , 161 , 355 , 455 , 1625 , 1283 , 1547 , 8707 ,0 }; - static ulong[] dim1443KuoInit = { 1 , 1 , 1 , 11 , 7 , 15 , 35 , 193 , 489 , 619 , 515 , 199 , 5439 , 15711 ,0 }; - static ulong[] dim1444KuoInit = { 1 , 1 , 7 , 1 , 29 , 21 , 69 , 13 , 343 , 581 , 495 , 3963 , 911 , 3995 ,0 }; - static ulong[] dim1445KuoInit = { 1 , 1 , 1 , 7 , 21 , 5 , 9 , 31 , 291 , 825 , 7 , 2621 , 1149 , 2709 ,0 }; - static ulong[] dim1446KuoInit = { 1 , 3 , 3 , 13 , 7 , 35 , 69 , 43 , 397 , 641 , 89 , 3325 , 5567 , 3487 ,0 }; - static ulong[] dim1447KuoInit = { 1 , 3 , 5 , 5 , 1 , 17 , 11 , 97 , 309 , 371 , 145 , 3255 , 5161 , 7787 ,0 }; - static ulong[] dim1448KuoInit = { 1 , 3 , 7 , 7 , 27 , 1 , 1 , 235 , 47 , 251 , 1525 , 2661 , 3971 , 11319 ,0 }; - static ulong[] dim1449KuoInit = { 1 , 3 , 5 , 3 , 11 , 21 , 69 , 97 , 13 , 931 , 1955 , 3497 , 3963 , 519 ,0 }; - static ulong[] dim1450KuoInit = { 1 , 1 , 5 , 9 , 21 , 15 , 11 , 201 , 175 , 855 , 1867 , 3941 , 6505 , 3451 ,0 }; - static ulong[] dim1451KuoInit = { 1 , 1 , 7 , 13 , 25 , 45 , 27 , 91 , 149 , 827 , 1791 , 139 , 6721 , 9 ,0 }; - static ulong[] dim1452KuoInit = { 1 , 3 , 3 , 7 , 19 , 13 , 95 , 161 , 91 , 333 , 203 , 3195 , 517 , 3911 ,0 }; - static ulong[] dim1453KuoInit = { 1 , 1 , 5 , 1 , 3 , 7 , 113 , 195 , 501 , 203 , 193 , 3585 , 3217 , 2009 ,0 }; - static ulong[] dim1454KuoInit = { 1 , 1 , 5 , 13 , 21 , 29 , 9 , 209 , 381 , 245 , 1317 , 3577 , 3327 , 9253 ,0 }; - static ulong[] dim1455KuoInit = { 1 , 3 , 3 , 15 , 1 , 5 , 75 , 215 , 349 , 143 , 1607 , 2817 , 8185 , 13991 ,0 }; - static ulong[] dim1456KuoInit = { 1 , 3 , 3 , 11 , 23 , 29 , 73 , 15 , 159 , 425 , 1169 , 2989 , 5835 , 12687 ,0 }; - static ulong[] dim1457KuoInit = { 1 , 1 , 1 , 11 , 13 , 13 , 79 , 97 , 351 , 455 , 1465 , 2013 , 5133 , 1747 ,0 }; - static ulong[] dim1458KuoInit = { 1 , 3 , 3 , 13 , 3 , 29 , 53 , 37 , 357 , 55 , 195 , 43 , 3903 , 7013 ,0 }; - static ulong[] dim1459KuoInit = { 1 , 3 , 5 , 13 , 25 , 43 , 19 , 233 , 17 , 31 , 1727 , 557 , 2581 , 847 ,0 }; - static ulong[] dim1460KuoInit = { 1 , 1 , 7 , 5 , 21 , 27 , 7 , 27 , 487 , 961 , 1095 , 3813 , 7967 , 15283 ,0 }; - static ulong[] dim1461KuoInit = { 1 , 3 , 7 , 7 , 27 , 49 , 15 , 199 , 413 , 295 , 441 , 2023 , 2453 , 2243 ,0 }; - static ulong[] dim1462KuoInit = { 1 , 3 , 7 , 9 , 19 , 13 , 99 , 85 , 227 , 61 , 933 , 3897 , 2399 , 455 ,0 }; - static ulong[] dim1463KuoInit = { 1 , 3 , 1 , 15 , 13 , 45 , 123 , 13 , 39 , 431 , 1573 , 2771 , 2273 , 12613 ,0 }; - static ulong[] dim1464KuoInit = { 1 , 1 , 3 , 13 , 1 , 29 , 127 , 59 , 159 , 1005 , 483 , 3031 , 5029 , 1763 ,0 }; - static ulong[] dim1465KuoInit = { 1 , 1 , 7 , 9 , 17 , 27 , 87 , 25 , 313 , 305 , 1611 , 693 , 3701 , 573 ,0 }; - static ulong[] dim1466KuoInit = { 1 , 3 , 7 , 13 , 5 , 61 , 93 , 69 , 357 , 681 , 291 , 1251 , 3889 , 3687 ,0 }; - static ulong[] dim1467KuoInit = { 1 , 1 , 3 , 15 , 9 , 31 , 121 , 213 , 115 , 231 , 349 , 2141 , 4443 , 12319 ,0 }; - static ulong[] dim1468KuoInit = { 1 , 1 , 1 , 5 , 1 , 37 , 59 , 21 , 399 , 751 , 841 , 33 , 7195 , 8403 ,0 }; - static ulong[] dim1469KuoInit = { 1 , 3 , 3 , 13 , 5 , 41 , 111 , 21 , 135 , 945 , 1915 , 2351 , 6429 , 10993 ,0 }; - static ulong[] dim1470KuoInit = { 1 , 1 , 1 , 1 , 29 , 43 , 45 , 13 , 395 , 407 , 47 , 1007 , 7525 , 6707 ,0 }; - static ulong[] dim1471KuoInit = { 1 , 3 , 5 , 15 , 23 , 3 , 49 , 149 , 391 , 689 , 147 , 1173 , 3793 , 4249 ,0 }; - static ulong[] dim1472KuoInit = { 1 , 3 , 1 , 13 , 25 , 35 , 109 , 147 , 323 , 161 , 257 , 2023 , 5693 , 16199 ,0 }; - static ulong[] dim1473KuoInit = { 1 , 3 , 3 , 9 , 17 , 3 , 9 , 191 , 19 , 405 , 1841 , 1669 , 4691 , 11907 ,0 }; - static ulong[] dim1474KuoInit = { 1 , 1 , 3 , 5 , 13 , 35 , 45 , 27 , 127 , 329 , 931 , 1 , 2521 , 15307 ,0 }; - static ulong[] dim1475KuoInit = { 1 , 1 , 5 , 3 , 11 , 25 , 31 , 233 , 1 , 769 , 433 , 3785 , 3631 , 8573 ,0 }; - static ulong[] dim1476KuoInit = { 1 , 1 , 3 , 1 , 23 , 57 , 67 , 227 , 393 , 469 , 1579 , 2235 , 493 , 2477 ,0 }; - static ulong[] dim1477KuoInit = { 1 , 3 , 7 , 3 , 9 , 19 , 69 , 123 , 205 , 553 , 1871 , 3807 , 1563 , 2771 ,0 }; - static ulong[] dim1478KuoInit = { 1 , 3 , 3 , 11 , 11 , 33 , 55 , 27 , 51 , 903 , 1681 , 2613 , 2519 , 9529 ,0 }; - static ulong[] dim1479KuoInit = { 1 , 1 , 7 , 11 , 29 , 55 , 31 , 185 , 85 , 929 , 233 , 2619 , 2989 , 191 ,0 }; - static ulong[] dim1480KuoInit = { 1 , 1 , 1 , 3 , 1 , 47 , 47 , 225 , 387 , 717 , 815 , 853 , 819 , 5645 ,0 }; - static ulong[] dim1481KuoInit = { 1 , 1 , 5 , 3 , 1 , 55 , 89 , 59 , 39 , 687 , 1395 , 535 , 4977 , 8155 ,0 }; - static ulong[] dim1482KuoInit = { 1 , 3 , 7 , 1 , 11 , 57 , 107 , 137 , 407 , 155 , 313 , 2205 , 3095 , 15179 ,0 }; - static ulong[] dim1483KuoInit = { 1 , 1 , 7 , 13 , 29 , 5 , 121 , 173 , 21 , 247 , 1663 , 1937 , 5113 , 7439 ,0 }; - static ulong[] dim1484KuoInit = { 1 , 3 , 1 , 7 , 1 , 39 , 31 , 129 , 109 , 447 , 1269 , 3133 , 4933 , 11893 ,0 }; - static ulong[] dim1485KuoInit = { 1 , 3 , 3 , 15 , 9 , 7 , 21 , 157 , 397 , 465 , 1057 , 2355 , 4663 , 13955 ,0 }; - static ulong[] dim1486KuoInit = { 1 , 1 , 7 , 3 , 1 , 35 , 71 , 175 , 439 , 1019 , 1479 , 2519 , 5119 , 15245 ,0 }; - static ulong[] dim1487KuoInit = { 1 , 1 , 7 , 3 , 23 , 49 , 55 , 91 , 269 , 407 , 393 , 1495 , 6153 , 15703 ,0 }; - static ulong[] dim1488KuoInit = { 1 , 1 , 3 , 7 , 25 , 3 , 45 , 87 , 141 , 693 , 555 , 3629 , 2723 , 4357 ,0 }; - static ulong[] dim1489KuoInit = { 1 , 3 , 3 , 7 , 15 , 27 , 103 , 161 , 423 , 785 , 1171 , 2335 , 1845 , 14373 ,0 }; - static ulong[] dim1490KuoInit = { 1 , 3 , 5 , 5 , 1 , 31 , 117 , 35 , 181 , 263 , 1337 , 3239 , 617 , 11499 ,0 }; - static ulong[] dim1491KuoInit = { 1 , 1 , 1 , 9 , 15 , 17 , 103 , 201 , 79 , 211 , 2043 , 3733 , 7593 , 6523 ,0 }; - static ulong[] dim1492KuoInit = { 1 , 3 , 5 , 5 , 3 , 59 , 11 , 163 , 155 , 215 , 1621 , 2615 , 2915 , 2459 ,0 }; - static ulong[] dim1493KuoInit = { 1 , 3 , 7 , 11 , 11 , 11 , 93 , 239 , 367 , 553 , 1341 , 129 , 7651 , 2841 ,0 }; - static ulong[] dim1494KuoInit = { 1 , 3 , 7 , 7 , 7 , 21 , 45 , 99 , 63 , 601 , 1877 , 765 , 5831 , 1825 ,0 }; - static ulong[] dim1495KuoInit = { 1 , 1 , 7 , 3 , 21 , 27 , 71 , 53 , 185 , 675 , 891 , 657 , 5343 , 3583 ,0 }; - static ulong[] dim1496KuoInit = { 1 , 3 , 5 , 9 , 17 , 57 , 95 , 57 , 427 , 329 , 681 , 2663 , 3183 , 7429 ,0 }; - static ulong[] dim1497KuoInit = { 1 , 3 , 7 , 3 , 17 , 9 , 93 , 105 , 409 , 975 , 205 , 429 , 4473 , 10269 ,0 }; - static ulong[] dim1498KuoInit = { 1 , 3 , 1 , 1 , 11 , 51 , 25 , 97 , 333 , 71 , 1513 , 1273 , 1235 , 5023 ,0 }; - static ulong[] dim1499KuoInit = { 1 , 1 , 7 , 9 , 17 , 59 , 75 , 51 , 277 , 377 , 3 , 3357 , 2595 , 7939 ,0 }; - static ulong[] dim1500KuoInit = { 1 , 3 , 3 , 1 , 7 , 47 , 11 , 241 , 235 , 761 , 283 , 3277 , 2121 , 69 ,0 }; - static ulong[] dim1501KuoInit = { 1 , 3 , 1 , 3 , 5 , 5 , 57 , 5 , 99 , 869 , 707 , 2379 , 5439 , 4981 ,0 }; - static ulong[] dim1502KuoInit = { 1 , 3 , 7 , 9 , 5 , 9 , 115 , 155 , 191 , 905 , 1173 , 975 , 6825 , 8257 ,0 }; - static ulong[] dim1503KuoInit = { 1 , 1 , 3 , 13 , 17 , 13 , 63 , 143 , 305 , 577 , 1895 , 1943 , 2335 , 8957 ,0 }; - static ulong[] dim1504KuoInit = { 1 , 3 , 7 , 3 , 15 , 19 , 89 , 91 , 497 , 145 , 1419 , 1449 , 5305 , 1379 ,0 }; - static ulong[] dim1505KuoInit = { 1 , 3 , 1 , 13 , 9 , 51 , 103 , 169 , 265 , 347 , 697 , 3735 , 6987 , 2565 ,0 }; - static ulong[] dim1506KuoInit = { 1 , 3 , 3 , 5 , 1 , 19 , 83 , 211 , 247 , 81 , 131 , 2243 , 7563 , 14221 ,0 }; - static ulong[] dim1507KuoInit = { 1 , 3 , 3 , 11 , 27 , 1 , 97 , 85 , 265 , 423 , 173 , 1873 , 3889 , 1845 ,0 }; - static ulong[] dim1508KuoInit = { 1 , 1 , 1 , 11 , 15 , 25 , 25 , 155 , 111 , 327 , 1089 , 335 , 7635 , 6467 ,0 }; - static ulong[] dim1509KuoInit = { 1 , 3 , 5 , 7 , 15 , 33 , 103 , 231 , 455 , 681 , 547 , 3389 , 4279 , 6037 ,0 }; - static ulong[] dim1510KuoInit = { 1 , 3 , 3 , 7 , 3 , 11 , 11 , 165 , 113 , 499 , 977 , 3805 , 2733 , 15643 ,0 }; - static ulong[] dim1511KuoInit = { 1 , 1 , 3 , 7 , 23 , 49 , 39 , 165 , 323 , 313 , 1731 , 2977 , 4795 , 12387 ,0 }; - static ulong[] dim1512KuoInit = { 1 , 1 , 5 , 15 , 27 , 15 , 43 , 149 , 71 , 19 , 1025 , 2585 , 5975 , 12473 ,0 }; - static ulong[] dim1513KuoInit = { 1 , 3 , 7 , 15 , 15 , 21 , 33 , 29 , 351 , 909 , 813 , 3901 , 3235 , 3719 ,0 }; - static ulong[] dim1514KuoInit = { 1 , 3 , 3 , 1 , 29 , 63 , 55 , 173 , 405 , 841 , 871 , 213 , 4747 , 11611 ,0 }; - static ulong[] dim1515KuoInit = { 1 , 1 , 1 , 7 , 15 , 11 , 83 , 21 , 123 , 929 , 1137 , 3843 , 5919 , 151 ,0 }; - static ulong[] dim1516KuoInit = { 1 , 1 , 3 , 1 , 29 , 53 , 111 , 133 , 285 , 499 , 2011 , 121 , 2853 , 7587 ,0 }; - static ulong[] dim1517KuoInit = { 1 , 3 , 7 , 1 , 15 , 33 , 87 , 139 , 429 , 97 , 375 , 1273 , 2745 , 12045 ,0 }; - static ulong[] dim1518KuoInit = { 1 , 1 , 5 , 13 , 17 , 55 , 43 , 3 , 465 , 1 , 1065 , 647 , 2497 , 14775 ,0 }; - static ulong[] dim1519KuoInit = { 1 , 1 , 5 , 5 , 15 , 41 , 39 , 37 , 397 , 621 , 1735 , 1009 , 1289 , 2375 ,0 }; - static ulong[] dim1520KuoInit = { 1 , 3 , 5 , 11 , 1 , 45 , 73 , 207 , 375 , 825 , 697 , 3765 , 7181 , 4953 ,0 }; - static ulong[] dim1521KuoInit = { 1 , 3 , 7 , 7 , 23 , 15 , 75 , 11 , 137 , 1017 , 203 , 1325 , 6661 , 8569 ,0 }; - static ulong[] dim1522KuoInit = { 1 , 1 , 1 , 15 , 23 , 9 , 15 , 157 , 179 , 699 , 1493 , 2161 , 3159 , 2709 ,0 }; - static ulong[] dim1523KuoInit = { 1 , 3 , 7 , 3 , 15 , 51 , 95 , 101 , 467 , 303 , 1867 , 3819 , 7593 , 6133 ,0 }; - static ulong[] dim1524KuoInit = { 1 , 3 , 7 , 13 , 25 , 27 , 87 , 11 , 113 , 861 , 1393 , 1521 , 2109 , 11899 ,0 }; - static ulong[] dim1525KuoInit = { 1 , 3 , 5 , 11 , 25 , 53 , 27 , 249 , 193 , 783 , 609 , 3069 , 3901 , 391 ,0 }; - static ulong[] dim1526KuoInit = { 1 , 3 , 5 , 11 , 19 , 13 , 55 , 147 , 325 , 131 , 659 , 1277 , 6127 , 1033 ,0 }; - static ulong[] dim1527KuoInit = { 1 , 3 , 1 , 7 , 31 , 13 , 1 , 141 , 377 , 159 , 1945 , 2031 , 8039 , 13851 ,0 }; - static ulong[] dim1528KuoInit = { 1 , 3 , 5 , 7 , 27 , 17 , 79 , 47 , 421 , 517 , 751 , 3049 , 6109 , 11027 ,0 }; - static ulong[] dim1529KuoInit = { 1 , 3 , 3 , 11 , 23 , 41 , 89 , 225 , 367 , 109 , 1295 , 2691 , 4677 , 9207 ,0 }; - static ulong[] dim1530KuoInit = { 1 , 1 , 7 , 7 , 7 , 27 , 89 , 221 , 267 , 537 , 2003 , 3357 , 8113 , 8173 ,0 }; - static ulong[] dim1531KuoInit = { 1 , 1 , 7 , 15 , 19 , 23 , 21 , 173 , 159 , 535 , 1685 , 2259 , 6515 , 15853 ,0 }; - static ulong[] dim1532KuoInit = { 1 , 3 , 3 , 15 , 13 , 21 , 105 , 173 , 173 , 13 , 423 , 2259 , 4145 , 6543 ,0 }; - static ulong[] dim1533KuoInit = { 1 , 1 , 3 , 11 , 13 , 41 , 35 , 239 , 307 , 893 , 73 , 1325 , 7975 , 8395 ,0 }; - static ulong[] dim1534KuoInit = { 1 , 1 , 7 , 11 , 11 , 11 , 115 , 195 , 407 , 543 , 801 , 1449 , 8121 , 9627 ,0 }; - static ulong[] dim1535KuoInit = { 1 , 1 , 1 , 1 , 13 , 33 , 41 , 207 , 347 , 49 , 897 , 557 , 5917 , 13163 ,0 }; - static ulong[] dim1536KuoInit = { 1 , 1 , 7 , 13 , 7 , 9 , 51 , 241 , 47 , 479 , 1399 , 3229 , 5201 , 537 ,0 }; - static ulong[] dim1537KuoInit = { 1 , 3 , 7 , 3 , 9 , 63 , 31 , 109 , 381 , 631 , 521 , 139 , 4229 , 1639 ,0 }; - static ulong[] dim1538KuoInit = { 1 , 3 , 3 , 7 , 1 , 23 , 15 , 99 , 395 , 991 , 627 , 571 , 833 , 6631 ,0 }; - static ulong[] dim1539KuoInit = { 1 , 1 , 7 , 3 , 31 , 9 , 99 , 145 , 237 , 181 , 1911 , 2985 , 2415 , 5363 ,0 }; - static ulong[] dim1540KuoInit = { 1 , 3 , 5 , 3 , 27 , 1 , 111 , 133 , 307 , 211 , 1119 , 2289 , 5333 , 14747 ,0 }; - static ulong[] dim1541KuoInit = { 1 , 3 , 7 , 5 , 9 , 27 , 5 , 101 , 113 , 505 , 931 , 677 , 6225 , 16279 ,0 }; - static ulong[] dim1542KuoInit = { 1 , 1 , 5 , 9 , 19 , 47 , 57 , 3 , 281 , 207 , 621 , 939 , 839 , 4089 ,0 }; - static ulong[] dim1543KuoInit = { 1 , 1 , 5 , 11 , 25 , 61 , 117 , 139 , 5 , 325 , 745 , 3423 , 31 , 1451 ,0 }; - static ulong[] dim1544KuoInit = { 1 , 3 , 5 , 5 , 3 , 9 , 121 , 185 , 497 , 203 , 367 , 3049 , 4827 , 3363 ,0 }; - static ulong[] dim1545KuoInit = { 1 , 3 , 7 , 5 , 1 , 45 , 91 , 199 , 183 , 577 , 625 , 3641 , 963 , 9379 ,0 }; - static ulong[] dim1546KuoInit = { 1 , 3 , 5 , 9 , 5 , 53 , 17 , 205 , 331 , 329 , 669 , 2403 , 3027 , 297 ,0 }; - static ulong[] dim1547KuoInit = { 1 , 3 , 5 , 9 , 19 , 31 , 43 , 249 , 361 , 923 , 635 , 3461 , 3901 , 439 ,0 }; - static ulong[] dim1548KuoInit = { 1 , 3 , 7 , 15 , 21 , 25 , 115 , 115 , 457 , 607 , 699 , 2649 , 3003 , 1599 ,0 }; - static ulong[] dim1549KuoInit = { 1 , 1 , 5 , 15 , 21 , 35 , 61 , 97 , 131 , 521 , 1045 , 2401 , 2885 , 11795 ,0 }; - static ulong[] dim1550KuoInit = { 1 , 1 , 1 , 11 , 19 , 13 , 119 , 117 , 31 , 575 , 427 , 3689 , 3801 , 12267 ,0 }; - static ulong[] dim1551KuoInit = { 1 , 1 , 3 , 7 , 27 , 45 , 15 , 235 , 281 , 777 , 1181 , 2445 , 7947 , 2081 ,0 }; - static ulong[] dim1552KuoInit = { 1 , 1 , 5 , 3 , 31 , 57 , 57 , 219 , 135 , 717 , 1369 , 2221 , 4397 , 16195 ,0 }; - static ulong[] dim1553KuoInit = { 1 , 3 , 5 , 13 , 11 , 17 , 7 , 189 , 97 , 7 , 397 , 1557 , 7181 , 16205 ,0 }; - static ulong[] dim1554KuoInit = { 1 , 1 , 7 , 15 , 13 , 25 , 79 , 241 , 143 , 959 , 529 , 3899 , 5411 , 8769 ,0 }; - static ulong[] dim1555KuoInit = { 1 , 1 , 7 , 1 , 3 , 17 , 109 , 25 , 389 , 463 , 1675 , 627 , 6383 , 5007 ,0 }; - static ulong[] dim1556KuoInit = { 1 , 3 , 1 , 13 , 19 , 3 , 13 , 3 , 293 , 755 , 1827 , 755 , 3325 , 13447 ,0 }; - static ulong[] dim1557KuoInit = { 1 , 1 , 7 , 15 , 17 , 5 , 87 , 17 , 423 , 901 , 777 , 919 , 2655 , 1423 ,0 }; - static ulong[] dim1558KuoInit = { 1 , 1 , 3 , 13 , 19 , 41 , 89 , 9 , 475 , 479 , 981 , 1031 , 7207 , 3605 ,0 }; - static ulong[] dim1559KuoInit = { 1 , 3 , 5 , 7 , 9 , 41 , 111 , 201 , 389 , 139 , 1853 , 1773 , 233 , 3695 ,0 }; - static ulong[] dim1560KuoInit = { 1 , 1 , 3 , 1 , 3 , 47 , 83 , 15 , 49 , 867 , 1513 , 3203 , 3081 , 8429 ,0 }; - static ulong[] dim1561KuoInit = { 1 , 1 , 5 , 11 , 11 , 33 , 67 , 225 , 303 , 825 , 1711 , 1521 , 1569 , 5233 ,0 }; - static ulong[] dim1562KuoInit = { 1 , 3 , 3 , 11 , 27 , 41 , 37 , 247 , 211 , 143 , 855 , 3755 , 569 , 10155 ,0 }; - static ulong[] dim1563KuoInit = { 1 , 1 , 7 , 3 , 21 , 57 , 7 , 83 , 133 , 791 , 565 , 2217 , 7621 , 14141 ,0 }; - static ulong[] dim1564KuoInit = { 1 , 1 , 5 , 13 , 3 , 57 , 7 , 29 , 131 , 935 , 1555 , 1103 , 7395 , 4079 ,0 }; - static ulong[] dim1565KuoInit = { 1 , 1 , 7 , 3 , 13 , 9 , 13 , 71 , 345 , 1003 , 1519 , 1757 , 539 , 9207 ,0 }; - static ulong[] dim1566KuoInit = { 1 , 3 , 1 , 3 , 1 , 11 , 13 , 143 , 365 , 981 , 1691 , 2501 , 7155 , 4189 ,0 }; - static ulong[] dim1567KuoInit = { 1 , 3 , 3 , 1 , 23 , 37 , 33 , 229 , 411 , 329 , 915 , 2373 , 2525 , 12319 ,0 }; - static ulong[] dim1568KuoInit = { 1 , 1 , 3 , 3 , 5 , 45 , 77 , 23 , 317 , 311 , 425 , 1329 , 3619 , 11941 ,0 }; - static ulong[] dim1569KuoInit = { 1 , 3 , 1 , 1 , 19 , 17 , 39 , 37 , 405 , 275 , 983 , 995 , 4925 , 1005 ,0 }; - static ulong[] dim1570KuoInit = { 1 , 1 , 1 , 5 , 31 , 1 , 71 , 137 , 481 , 489 , 1381 , 3919 , 7841 , 14843 ,0 }; - static ulong[] dim1571KuoInit = { 1 , 1 , 7 , 15 , 13 , 37 , 11 , 201 , 43 , 311 , 921 , 2755 , 2997 , 4753 ,0 }; - static ulong[] dim1572KuoInit = { 1 , 1 , 3 , 7 , 27 , 35 , 87 , 203 , 197 , 27 , 1839 , 2847 , 3261 , 3139 ,0 }; - static ulong[] dim1573KuoInit = { 1 , 1 , 7 , 1 , 25 , 5 , 9 , 9 , 497 , 125 , 1451 , 1381 , 1975 , 10493 ,0 }; - static ulong[] dim1574KuoInit = { 1 , 1 , 1 , 11 , 11 , 25 , 3 , 9 , 39 , 989 , 975 , 1825 , 7089 , 10475 ,0 }; - static ulong[] dim1575KuoInit = { 1 , 1 , 5 , 13 , 25 , 33 , 69 , 55 , 179 , 163 , 1233 , 1601 , 1893 , 8225 ,0 }; - static ulong[] dim1576KuoInit = { 1 , 1 , 3 , 15 , 23 , 11 , 117 , 71 , 151 , 437 , 371 , 1543 , 2417 , 13195 ,0 }; - static ulong[] dim1577KuoInit = { 1 , 3 , 7 , 9 , 25 , 33 , 63 , 215 , 193 , 415 , 1771 , 715 , 4011 , 11739 ,0 }; - static ulong[] dim1578KuoInit = { 1 , 3 , 3 , 13 , 17 , 1 , 105 , 169 , 5 , 259 , 169 , 1207 , 5425 , 6091 ,0 }; - static ulong[] dim1579KuoInit = { 1 , 1 , 5 , 11 , 29 , 43 , 25 , 245 , 33 , 995 , 1797 , 279 , 6443 , 14507 ,0 }; - static ulong[] dim1580KuoInit = { 1 , 3 , 7 , 7 , 5 , 29 , 117 , 141 , 409 , 367 , 1223 , 1499 , 5651 , 3337 ,0 }; - static ulong[] dim1581KuoInit = { 1 , 1 , 3 , 9 , 15 , 21 , 21 , 27 , 23 , 693 , 1431 , 2055 , 2959 , 1347 ,0 }; - static ulong[] dim1582KuoInit = { 1 , 1 , 1 , 9 , 7 , 27 , 67 , 127 , 63 , 213 , 763 , 1221 , 2319 , 5313 ,0 }; - static ulong[] dim1583KuoInit = { 1 , 1 , 3 , 11 , 21 , 33 , 43 , 243 , 113 , 223 , 1095 , 2433 , 1253 , 16303 ,0 }; - static ulong[] dim1584KuoInit = { 1 , 1 , 5 , 15 , 21 , 61 , 39 , 147 , 263 , 943 , 321 , 2599 , 3513 , 6595 ,0 }; - static ulong[] dim1585KuoInit = { 1 , 1 , 7 , 3 , 9 , 25 , 19 , 73 , 253 , 889 , 1699 , 1709 , 6451 , 2939 ,0 }; - static ulong[] dim1586KuoInit = { 1 , 3 , 3 , 15 , 29 , 29 , 53 , 133 , 349 , 553 , 1677 , 3949 , 1701 , 1187 ,0 }; - static ulong[] dim1587KuoInit = { 1 , 3 , 7 , 9 , 27 , 5 , 17 , 15 , 185 , 583 , 1117 , 2869 , 6929 , 8117 ,0 }; - static ulong[] dim1588KuoInit = { 1 , 1 , 5 , 1 , 3 , 15 , 117 , 73 , 321 , 245 , 537 , 2689 , 4883 , 5993 ,0 }; - static ulong[] dim1589KuoInit = { 1 , 3 , 7 , 15 , 31 , 57 , 103 , 65 , 89 , 323 , 1341 , 1951 , 4999 , 12663 ,0 }; - static ulong[] dim1590KuoInit = { 1 , 3 , 5 , 5 , 7 , 23 , 77 , 133 , 413 , 157 , 1281 , 3779 , 2081 , 12201 ,0 }; - static ulong[] dim1591KuoInit = { 1 , 3 , 7 , 13 , 15 , 49 , 119 , 45 , 27 , 621 , 2017 , 1351 , 7647 , 8845 ,0 }; - static ulong[] dim1592KuoInit = { 1 , 1 , 7 , 15 , 7 , 51 , 77 , 181 , 25 , 769 , 1159 , 1505 , 5219 , 647 ,0 }; - static ulong[] dim1593KuoInit = { 1 , 1 , 3 , 5 , 3 , 35 , 69 , 43 , 327 , 383 , 755 , 253 , 1137 , 16133 ,0 }; - static ulong[] dim1594KuoInit = { 1 , 1 , 7 , 9 , 13 , 63 , 69 , 215 , 357 , 873 , 477 , 1243 , 5475 , 5335 ,0 }; - static ulong[] dim1595KuoInit = { 1 , 3 , 1 , 9 , 27 , 13 , 115 , 197 , 131 , 651 , 741 , 2539 , 265 , 15757 ,0 }; - static ulong[] dim1596KuoInit = { 1 , 1 , 5 , 11 , 13 , 47 , 45 , 235 , 103 , 597 , 523 , 3129 , 5113 , 7031 ,0 }; - static ulong[] dim1597KuoInit = { 1 , 1 , 1 , 13 , 31 , 63 , 25 , 75 , 343 , 537 , 83 , 3165 , 3247 , 2589 ,0 }; - static ulong[] dim1598KuoInit = { 1 , 3 , 5 , 5 , 11 , 13 , 29 , 79 , 233 , 901 , 627 , 1691 , 2659 , 10251 ,0 }; - static ulong[] dim1599KuoInit = { 1 , 3 , 7 , 1 , 11 , 63 , 123 , 63 , 441 , 931 , 573 , 4083 , 4483 , 5685 ,0 }; - static ulong[] dim1600KuoInit = { 1 , 3 , 7 , 1 , 23 , 51 , 107 , 113 , 233 , 921 , 1761 , 207 , 5083 , 9165 ,0 }; - static ulong[] dim1601KuoInit = { 1 , 3 , 3 , 15 , 13 , 23 , 5 , 151 , 487 , 157 , 23 , 3967 , 6241 , 487 ,0 }; - static ulong[] dim1602KuoInit = { 1 , 1 , 7 , 1 , 7 , 39 , 95 , 185 , 379 , 225 , 1685 , 513 , 2463 , 11033 ,0 }; - static ulong[] dim1603KuoInit = { 1 , 1 , 5 , 11 , 19 , 43 , 55 , 69 , 433 , 933 , 811 , 3717 , 5555 , 15391 ,0 }; - static ulong[] dim1604KuoInit = { 1 , 1 , 7 , 7 , 21 , 17 , 19 , 149 , 185 , 475 , 1817 , 913 , 4463 , 12837 ,0 }; - static ulong[] dim1605KuoInit = { 1 , 1 , 7 , 5 , 27 , 63 , 5 , 131 , 217 , 271 , 889 , 3905 , 2881 , 419 ,0 }; - static ulong[] dim1606KuoInit = { 1 , 3 , 7 , 11 , 5 , 55 , 103 , 135 , 59 , 775 , 1105 , 2017 , 493 , 12747 ,0 }; - static ulong[] dim1607KuoInit = { 1 , 1 , 3 , 5 , 9 , 25 , 65 , 9 , 61 , 709 , 1925 , 1769 , 3273 , 1627 ,0 }; - static ulong[] dim1608KuoInit = { 1 , 3 , 1 , 11 , 7 , 35 , 37 , 223 , 105 , 55 , 293 , 2103 , 7531 , 2795 ,0 }; - static ulong[] dim1609KuoInit = { 1 , 3 , 7 , 13 , 17 , 23 , 35 , 163 , 177 , 797 , 1539 , 3843 , 6761 , 11817 ,0 }; - static ulong[] dim1610KuoInit = { 1 , 1 , 3 , 15 , 11 , 19 , 55 , 161 , 33 , 701 , 601 , 1055 , 4949 , 10741 ,0 }; - static ulong[] dim1611KuoInit = { 1 , 1 , 7 , 3 , 11 , 45 , 71 , 199 , 233 , 917 , 1447 , 3651 , 6021 , 4745 ,0 }; - static ulong[] dim1612KuoInit = { 1 , 1 , 3 , 11 , 21 , 17 , 39 , 141 , 17 , 827 , 355 , 3337 , 6897 , 9005 ,0 }; - static ulong[] dim1613KuoInit = { 1 , 3 , 3 , 1 , 11 , 61 , 67 , 103 , 377 , 351 , 1863 , 207 , 7333 , 4481 ,0 }; - static ulong[] dim1614KuoInit = { 1 , 1 , 1 , 1 , 7 , 33 , 103 , 121 , 361 , 233 , 195 , 985 , 4743 , 8715 ,0 }; - static ulong[] dim1615KuoInit = { 1 , 3 , 1 , 9 , 17 , 47 , 127 , 129 , 93 , 217 , 1049 , 689 , 5595 , 13625 ,0 }; - static ulong[] dim1616KuoInit = { 1 , 1 , 5 , 11 , 13 , 33 , 59 , 29 , 439 , 447 , 21 , 621 , 3731 , 9371 ,0 }; - static ulong[] dim1617KuoInit = { 1 , 3 , 1 , 7 , 15 , 31 , 41 , 217 , 275 , 97 , 143 , 3779 , 5453 , 13167 ,0 }; - static ulong[] dim1618KuoInit = { 1 , 3 , 7 , 1 , 11 , 31 , 7 , 249 , 193 , 907 , 1275 , 691 , 5701 , 6215 ,0 }; - static ulong[] dim1619KuoInit = { 1 , 3 , 5 , 1 , 11 , 63 , 7 , 209 , 227 , 959 , 1313 , 1107 , 2281 , 5567 ,0 }; - static ulong[] dim1620KuoInit = { 1 , 3 , 7 , 9 , 25 , 5 , 103 , 193 , 137 , 345 , 1953 , 369 , 2201 , 9435 ,0 }; - static ulong[] dim1621KuoInit = { 1 , 1 , 3 , 1 , 5 , 19 , 11 , 191 , 101 , 861 , 1665 , 1439 , 6889 , 2467 ,0 }; - static ulong[] dim1622KuoInit = { 1 , 1 , 7 , 5 , 19 , 47 , 13 , 123 , 363 , 659 , 1011 , 2961 , 2231 , 11523 ,0 }; - static ulong[] dim1623KuoInit = { 1 , 3 , 1 , 1 , 9 , 19 , 7 , 1 , 351 , 461 , 1323 , 1125 , 3063 , 9589 ,0 }; - static ulong[] dim1624KuoInit = { 1 , 1 , 5 , 11 , 1 , 25 , 79 , 171 , 503 , 319 , 729 , 2133 , 1979 , 13769 ,0 }; - static ulong[] dim1625KuoInit = { 1 , 3 , 1 , 3 , 17 , 45 , 55 , 109 , 143 , 541 , 65 , 431 , 2949 , 11501 ,0 }; - static ulong[] dim1626KuoInit = { 1 , 3 , 7 , 7 , 7 , 7 , 85 , 81 , 317 , 245 , 1683 , 1009 , 3853 , 12597 ,0 }; - static ulong[] dim1627KuoInit = { 1 , 1 , 1 , 7 , 9 , 25 , 85 , 19 , 59 , 5 , 1919 , 577 , 7723 , 9365 ,0 }; - static ulong[] dim1628KuoInit = { 1 , 1 , 7 , 11 , 13 , 27 , 35 , 163 , 209 , 491 , 1759 , 383 , 5697 , 13131 ,0 }; - static ulong[] dim1629KuoInit = { 1 , 1 , 7 , 13 , 19 , 57 , 121 , 61 , 143 , 735 , 721 , 3405 , 6939 , 4691 ,0 }; - static ulong[] dim1630KuoInit = { 1 , 1 , 7 , 15 , 21 , 23 , 55 , 203 , 145 , 673 , 419 , 3023 , 6439 , 6361 ,0 }; - static ulong[] dim1631KuoInit = { 1 , 1 , 5 , 15 , 5 , 21 , 11 , 153 , 223 , 229 , 721 , 715 , 7981 , 15459 ,0 }; - static ulong[] dim1632KuoInit = { 1 , 3 , 5 , 7 , 21 , 59 , 47 , 15 , 213 , 549 , 465 , 1353 , 2611 , 11989 ,0 }; - static ulong[] dim1633KuoInit = { 1 , 3 , 5 , 7 , 13 , 51 , 65 , 11 , 295 , 63 , 1887 , 3347 , 3061 , 2219 ,0 }; - static ulong[] dim1634KuoInit = { 1 , 1 , 5 , 3 , 29 , 29 , 83 , 175 , 507 , 341 , 2031 , 3737 , 1741 , 7615 ,0 }; - static ulong[] dim1635KuoInit = { 1 , 3 , 7 , 13 , 11 , 55 , 59 , 213 , 197 , 851 , 1723 , 2805 , 2461 , 8071 ,0 }; - static ulong[] dim1636KuoInit = { 1 , 1 , 3 , 15 , 5 , 37 , 55 , 237 , 319 , 345 , 1677 , 1791 , 5063 , 4301 ,0 }; - static ulong[] dim1637KuoInit = { 1 , 3 , 1 , 11 , 25 , 13 , 87 , 85 , 293 , 97 , 557 , 3583 , 7077 , 6433 ,0 }; - static ulong[] dim1638KuoInit = { 1 , 3 , 3 , 1 , 31 , 9 , 63 , 29 , 193 , 351 , 1071 , 3587 , 4695 , 1771 ,0 }; - static ulong[] dim1639KuoInit = { 1 , 3 , 7 , 11 , 11 , 3 , 45 , 119 , 215 , 367 , 677 , 3405 , 7177 , 14607 ,0 }; - static ulong[] dim1640KuoInit = { 1 , 3 , 7 , 3 , 3 , 23 , 33 , 33 , 223 , 209 , 1033 , 3167 , 4189 , 2195 ,0 }; - static ulong[] dim1641KuoInit = { 1 , 1 , 5 , 1 , 3 , 53 , 21 , 151 , 475 , 987 , 1671 , 393 , 7783 , 2561 ,0 }; - static ulong[] dim1642KuoInit = { 1 , 3 , 7 , 13 , 15 , 5 , 21 , 247 , 225 , 861 , 1707 , 3237 , 5793 , 14557 ,0 }; - static ulong[] dim1643KuoInit = { 1 , 3 , 5 , 9 , 13 , 3 , 37 , 49 , 119 , 33 , 805 , 681 , 7591 , 1707 ,0 }; - static ulong[] dim1644KuoInit = { 1 , 1 , 3 , 15 , 27 , 55 , 99 , 17 , 361 , 773 , 1415 , 3547 , 5427 , 4579 ,0 }; - static ulong[] dim1645KuoInit = { 1 , 3 , 5 , 9 , 17 , 55 , 89 , 111 , 189 , 719 , 1691 , 1565 , 941 , 15481 ,0 }; - static ulong[] dim1646KuoInit = { 1 , 1 , 1 , 11 , 17 , 3 , 77 , 57 , 71 , 739 , 869 , 165 , 6411 , 1565 ,0 }; - static ulong[] dim1647KuoInit = { 1 , 3 , 3 , 11 , 31 , 47 , 87 , 105 , 241 , 999 , 245 , 3695 , 5151 , 9087 ,0 }; - static ulong[] dim1648KuoInit = { 1 , 3 , 1 , 15 , 27 , 59 , 15 , 45 , 413 , 291 , 87 , 1735 , 779 , 5977 ,0 }; - static ulong[] dim1649KuoInit = { 1 , 3 , 7 , 1 , 9 , 19 , 7 , 183 , 133 , 833 , 1347 , 3559 , 7745 , 11071 ,0 }; - static ulong[] dim1650KuoInit = { 1 , 1 , 3 , 13 , 23 , 59 , 13 , 227 , 407 , 661 , 217 , 299 , 6033 , 14519 ,0 }; - static ulong[] dim1651KuoInit = { 1 , 1 , 5 , 5 , 27 , 33 , 105 , 15 , 141 , 555 , 397 , 3287 , 5859 , 9553 ,0 }; - static ulong[] dim1652KuoInit = { 1 , 3 , 3 , 9 , 27 , 59 , 11 , 47 , 379 , 275 , 889 , 3069 , 4135 , 15735 ,0 }; - static ulong[] dim1653KuoInit = { 1 , 1 , 5 , 13 , 27 , 47 , 107 , 165 , 487 , 463 , 425 , 3949 , 3213 , 4161 ,0 }; - static ulong[] dim1654KuoInit = { 1 , 3 , 5 , 7 , 27 , 55 , 17 , 3 , 159 , 181 , 393 , 2441 , 2531 , 895 ,0 }; - static ulong[] dim1655KuoInit = { 1 , 3 , 7 , 7 , 31 , 3 , 95 , 81 , 181 , 367 , 1689 , 2351 , 193 , 7165 ,0 }; - static ulong[] dim1656KuoInit = { 1 , 3 , 7 , 15 , 1 , 17 , 103 , 181 , 29 , 851 , 15 , 1447 , 435 , 14059 ,0 }; - static ulong[] dim1657KuoInit = { 1 , 1 , 1 , 15 , 21 , 31 , 83 , 41 , 237 , 437 , 509 , 3757 , 5609 , 15859 ,0 }; - static ulong[] dim1658KuoInit = { 1 , 1 , 7 , 15 , 5 , 35 , 101 , 37 , 245 , 487 , 449 , 2089 , 27 , 13667 ,0 }; - static ulong[] dim1659KuoInit = { 1 , 1 , 7 , 15 , 29 , 49 , 89 , 161 , 271 , 455 , 1599 , 3843 , 1673 , 3683 ,0 }; - static ulong[] dim1660KuoInit = { 1 , 1 , 7 , 1 , 1 , 25 , 37 , 211 , 369 , 207 , 243 , 2113 , 2707 , 7951 ,0 }; - static ulong[] dim1661KuoInit = { 1 , 1 , 7 , 5 , 19 , 21 , 25 , 161 , 97 , 505 , 273 , 1443 , 4461 , 1407 ,0 }; - static ulong[] dim1662KuoInit = { 1 , 1 , 5 , 15 , 17 , 57 , 115 , 175 , 511 , 389 , 1333 , 2459 , 5561 , 4409 ,0 }; - static ulong[] dim1663KuoInit = { 1 , 1 , 5 , 9 , 29 , 45 , 45 , 121 , 159 , 51 , 865 , 531 , 1387 , 3517 ,0 }; - static ulong[] dim1664KuoInit = { 1 , 3 , 5 , 15 , 25 , 17 , 59 , 161 , 193 , 495 , 611 , 1009 , 5035 , 15325 ,0 }; - static ulong[] dim1665KuoInit = { 1 , 1 , 1 , 7 , 7 , 53 , 99 , 241 , 305 , 989 , 175 , 2841 , 2891 , 4975 ,0 }; - static ulong[] dim1666KuoInit = { 1 , 1 , 7 , 1 , 31 , 45 , 85 , 251 , 339 , 731 , 513 , 2557 , 3119 , 15961 ,0 }; - static ulong[] dim1667KuoInit = { 1 , 3 , 7 , 15 , 11 , 37 , 73 , 93 , 83 , 931 , 1561 , 791 , 3263 , 10789 ,0 }; - static ulong[] dim1668KuoInit = { 1 , 3 , 1 , 11 , 27 , 25 , 29 , 71 , 199 , 673 , 173 , 2267 , 1277 , 4373 ,0 }; - static ulong[] dim1669KuoInit = { 1 , 1 , 5 , 5 , 7 , 19 , 79 , 143 , 63 , 139 , 977 , 845 , 5125 , 5635 ,0 }; - static ulong[] dim1670KuoInit = { 1 , 1 , 3 , 15 , 3 , 27 , 117 , 219 , 393 , 457 , 1001 , 1235 , 6409 , 10883 ,0 }; - static ulong[] dim1671KuoInit = { 1 , 1 , 3 , 3 , 19 , 31 , 61 , 225 , 391 , 719 , 1919 , 1843 , 4883 , 10499 ,0 }; - static ulong[] dim1672KuoInit = { 1 , 3 , 1 , 3 , 13 , 63 , 73 , 103 , 15 , 777 , 1019 , 2677 , 7317 , 4349 ,0 }; - static ulong[] dim1673KuoInit = { 1 , 3 , 5 , 15 , 5 , 7 , 31 , 33 , 237 , 1021 , 2045 , 2283 , 7045 , 13829 ,0 }; - static ulong[] dim1674KuoInit = { 1 , 1 , 3 , 13 , 11 , 43 , 47 , 239 , 5 , 293 , 2015 , 3613 , 1551 , 3203 ,0 }; - static ulong[] dim1675KuoInit = { 1 , 3 , 1 , 11 , 11 , 11 , 67 , 201 , 287 , 161 , 193 , 1815 , 1493 , 2863 ,0 }; - static ulong[] dim1676KuoInit = { 1 , 3 , 5 , 13 , 11 , 31 , 119 , 57 , 305 , 1009 , 915 , 2855 , 3595 , 11653 ,0 }; - static ulong[] dim1677KuoInit = { 1 , 1 , 1 , 9 , 17 , 7 , 59 , 27 , 189 , 227 , 763 , 2843 , 7335 , 13559 ,0 }; - static ulong[] dim1678KuoInit = { 1 , 1 , 5 , 13 , 3 , 1 , 17 , 129 , 83 , 763 , 443 , 895 , 1573 , 7343 ,0 }; - static ulong[] dim1679KuoInit = { 1 , 3 , 7 , 3 , 5 , 43 , 31 , 95 , 503 , 815 , 1725 , 2319 , 2323 , 12543 ,0 }; - static ulong[] dim1680KuoInit = { 1 , 1 , 1 , 9 , 29 , 27 , 103 , 43 , 39 , 289 , 277 , 453 , 4297 , 1009 ,0 }; - static ulong[] dim1681KuoInit = { 1 , 1 , 7 , 5 , 31 , 61 , 105 , 79 , 259 , 141 , 49 , 925 , 2793 , 13247 ,0 }; - static ulong[] dim1682KuoInit = { 1 , 1 , 1 , 5 , 15 , 23 , 59 , 55 , 497 , 561 , 343 , 3633 , 2097 , 2035 ,0 }; - static ulong[] dim1683KuoInit = { 1 , 1 , 3 , 13 , 17 , 23 , 13 , 23 , 15 , 519 , 105 , 3719 , 3639 , 6387 ,0 }; - static ulong[] dim1684KuoInit = { 1 , 1 , 1 , 11 , 1 , 43 , 97 , 73 , 295 , 841 , 1033 , 11 , 3027 , 4073 ,0 }; - static ulong[] dim1685KuoInit = { 1 , 3 , 1 , 3 , 21 , 15 , 67 , 95 , 425 , 979 , 1641 , 3059 , 4195 , 14291 ,0 }; - static ulong[] dim1686KuoInit = { 1 , 3 , 5 , 3 , 9 , 23 , 83 , 203 , 479 , 999 , 1469 , 2227 , 7995 , 4053 ,0 }; - static ulong[] dim1687KuoInit = { 1 , 1 , 5 , 7 , 1 , 13 , 17 , 191 , 297 , 397 , 329 , 1551 , 6885 , 2413 ,0 }; - static ulong[] dim1688KuoInit = { 1 , 1 , 7 , 13 , 31 , 21 , 123 , 59 , 79 , 647 , 475 , 347 , 667 , 9871 ,0 }; - static ulong[] dim1689KuoInit = { 1 , 1 , 7 , 15 , 25 , 43 , 35 , 117 , 323 , 805 , 1543 , 2631 , 2919 , 1377 ,0 }; - static ulong[] dim1690KuoInit = { 1 , 1 , 3 , 11 , 17 , 55 , 45 , 213 , 507 , 641 , 1947 , 2439 , 4749 , 6865 ,0 }; - static ulong[] dim1691KuoInit = { 1 , 3 , 7 , 5 , 13 , 31 , 51 , 31 , 167 , 431 , 1999 , 1041 , 3613 , 16289 ,0 }; - static ulong[] dim1692KuoInit = { 1 , 3 , 7 , 9 , 1 , 15 , 19 , 191 , 181 , 247 , 11 , 2305 , 5451 , 1719 ,0 }; - static ulong[] dim1693KuoInit = { 1 , 3 , 1 , 11 , 25 , 39 , 13 , 123 , 93 , 527 , 1359 , 1985 , 6789 , 2045 ,0 }; - static ulong[] dim1694KuoInit = { 1 , 1 , 1 , 7 , 25 , 57 , 113 , 91 , 311 , 661 , 1461 , 2801 , 5281 , 13423 ,0 }; - static ulong[] dim1695KuoInit = { 1 , 1 , 1 , 11 , 31 , 9 , 119 , 55 , 91 , 965 , 1973 , 2901 , 1147 , 9341 ,0 }; - static ulong[] dim1696KuoInit = { 1 , 1 , 7 , 15 , 9 , 59 , 83 , 21 , 49 , 921 , 749 , 1249 , 3577 , 14341 ,0 }; - static ulong[] dim1697KuoInit = { 1 , 3 , 5 , 13 , 25 , 63 , 65 , 135 , 337 , 743 , 1669 , 2519 , 341 , 16285 ,0 }; - static ulong[] dim1698KuoInit = { 1 , 3 , 3 , 7 , 23 , 9 , 97 , 205 , 87 , 289 , 1195 , 2843 , 7419 , 4183 ,0 }; - static ulong[] dim1699KuoInit = { 1 , 3 , 1 , 9 , 3 , 33 , 117 , 243 , 161 , 977 , 109 , 3333 , 4639 , 2299 ,0 }; - static ulong[] dim1700KuoInit = { 1 , 1 , 3 , 7 , 1 , 53 , 79 , 73 , 71 , 953 , 349 , 2517 , 6281 , 2625 ,0 }; - static ulong[] dim1701KuoInit = { 1 , 1 , 5 , 9 , 21 , 59 , 31 , 253 , 265 , 403 , 603 , 2185 , 7277 , 6057 ,0 }; - static ulong[] dim1702KuoInit = { 1 , 1 , 1 , 13 , 27 , 35 , 63 , 109 , 483 , 205 , 1245 , 2599 , 1697 , 11381 ,0 }; - static ulong[] dim1703KuoInit = { 1 , 1 , 7 , 15 , 25 , 29 , 107 , 205 , 411 , 627 , 745 , 1585 , 1175 , 3077 ,0 }; - static ulong[] dim1704KuoInit = { 1 , 3 , 5 , 3 , 25 , 15 , 121 , 97 , 283 , 809 , 753 , 2577 , 1099 , 12155 ,0 }; - static ulong[] dim1705KuoInit = { 1 , 1 , 7 , 15 , 29 , 21 , 55 , 53 , 101 , 69 , 657 , 2727 , 931 , 4873 ,0 }; - static ulong[] dim1706KuoInit = { 1 , 3 , 7 , 15 , 5 , 57 , 9 , 11 , 269 , 261 , 1681 , 1025 , 4001 , 16111 ,0 }; - static ulong[] dim1707KuoInit = { 1 , 1 , 3 , 7 , 9 , 51 , 29 , 77 , 313 , 199 , 1305 , 2665 , 5971 , 7525 ,0 }; - static ulong[] dim1708KuoInit = { 1 , 1 , 3 , 15 , 3 , 29 , 99 , 255 , 331 , 925 , 1973 , 3825 , 3549 , 8537 ,0 }; - static ulong[] dim1709KuoInit = { 1 , 1 , 3 , 1 , 27 , 33 , 19 , 225 , 209 , 895 , 47 , 4063 , 1873 , 15631 ,0 }; - static ulong[] dim1710KuoInit = { 1 , 3 , 1 , 9 , 11 , 57 , 121 , 205 , 89 , 565 , 1387 , 1119 , 7375 , 6153 ,0 }; - static ulong[] dim1711KuoInit = { 1 , 1 , 3 , 15 , 1 , 27 , 9 , 177 , 443 , 437 , 1487 , 2119 , 5299 , 16251 ,0 }; - static ulong[] dim1712KuoInit = { 1 , 3 , 7 , 5 , 17 , 33 , 79 , 153 , 327 , 719 , 1587 , 407 , 1137 , 9607 ,0 }; - static ulong[] dim1713KuoInit = { 1 , 1 , 3 , 15 , 7 , 31 , 109 , 251 , 501 , 553 , 785 , 3047 , 8141 , 6305 ,0 }; - static ulong[] dim1714KuoInit = { 1 , 1 , 3 , 9 , 11 , 63 , 65 , 135 , 257 , 313 , 191 , 1073 , 6821 , 10629 ,0 }; - static ulong[] dim1715KuoInit = { 1 , 1 , 7 , 1 , 19 , 55 , 7 , 69 , 503 , 131 , 1133 , 3325 , 347 , 9255 ,0 }; - static ulong[] dim1716KuoInit = { 1 , 3 , 5 , 3 , 11 , 55 , 115 , 171 , 261 , 581 , 1169 , 3609 , 307 , 14055 ,0 }; - static ulong[] dim1717KuoInit = { 1 , 3 , 7 , 15 , 29 , 3 , 33 , 229 , 431 , 969 , 281 , 1617 , 3685 , 13583 ,0 }; - static ulong[] dim1718KuoInit = { 1 , 1 , 7 , 11 , 9 , 23 , 5 , 147 , 305 , 651 , 1419 , 3225 , 7029 , 15331 ,0 }; - static ulong[] dim1719KuoInit = { 1 , 3 , 7 , 15 , 23 , 61 , 111 , 221 , 145 , 809 , 1127 , 2287 , 6023 , 6103 ,0 }; - static ulong[] dim1720KuoInit = { 1 , 3 , 1 , 7 , 1 , 49 , 93 , 251 , 239 , 617 , 401 , 3419 , 8123 , 4855 ,0 }; - static ulong[] dim1721KuoInit = { 1 , 3 , 5 , 5 , 15 , 9 , 69 , 5 , 509 , 83 , 405 , 3451 , 4401 , 3321 ,0 }; - static ulong[] dim1722KuoInit = { 1 , 1 , 3 , 9 , 29 , 39 , 53 , 155 , 73 , 207 , 499 , 3179 , 6099 , 1377 ,0 }; - static ulong[] dim1723KuoInit = { 1 , 1 , 1 , 11 , 9 , 43 , 101 , 211 , 439 , 865 , 621 , 3271 , 4699 , 5329 ,0 }; - static ulong[] dim1724KuoInit = { 1 , 3 , 5 , 9 , 21 , 59 , 105 , 89 , 5 , 493 , 227 , 1177 , 6829 , 8659 ,0 }; - static ulong[] dim1725KuoInit = { 1 , 1 , 1 , 3 , 27 , 19 , 49 , 209 , 337 , 961 , 93 , 81 , 4607 , 13579 ,0 }; - static ulong[] dim1726KuoInit = { 1 , 3 , 7 , 1 , 31 , 53 , 77 , 213 , 3 , 555 , 1409 , 3917 , 23 , 7837 ,0 }; - static ulong[] dim1727KuoInit = { 1 , 3 , 1 , 1 , 21 , 37 , 121 , 17 , 295 , 367 , 1105 , 3053 , 1453 , 8869 ,0 }; - static ulong[] dim1728KuoInit = { 1 , 3 , 5 , 5 , 31 , 23 , 13 , 145 , 459 , 609 , 77 , 197 , 4457 , 5145 ,0 }; - static ulong[] dim1729KuoInit = { 1 , 1 , 3 , 7 , 27 , 23 , 83 , 165 , 25 , 491 , 1487 , 2335 , 7019 , 499 ,0 }; - static ulong[] dim1730KuoInit = { 1 , 1 , 7 , 15 , 29 , 53 , 87 , 47 , 21 , 233 , 253 , 2529 , 1651 , 16091 ,0 }; - static ulong[] dim1731KuoInit = { 1 , 3 , 5 , 11 , 7 , 55 , 99 , 193 , 395 , 63 , 817 , 2109 , 1167 , 5739 ,0 }; - static ulong[] dim1732KuoInit = { 1 , 1 , 7 , 15 , 13 , 21 , 61 , 31 , 45 , 723 , 103 , 1347 , 4259 , 13185 ,0 }; - static ulong[] dim1733KuoInit = { 1 , 1 , 5 , 9 , 7 , 51 , 43 , 21 , 411 , 887 , 1303 , 3389 , 6653 , 9265 ,0 }; - static ulong[] dim1734KuoInit = { 1 , 1 , 3 , 7 , 3 , 7 , 43 , 197 , 151 , 977 , 717 , 2293 , 3135 , 5223 ,0 }; - static ulong[] dim1735KuoInit = { 1 , 1 , 1 , 1 , 23 , 49 , 23 , 105 , 279 , 401 , 1309 , 3485 , 4305 , 13181 ,0 }; - static ulong[] dim1736KuoInit = { 1 , 3 , 1 , 15 , 23 , 15 , 89 , 171 , 237 , 513 , 369 , 3731 , 4753 , 4655 ,0 }; - static ulong[] dim1737KuoInit = { 1 , 1 , 7 , 11 , 3 , 35 , 49 , 211 , 353 , 843 , 705 , 2237 , 7843 , 9009 ,0 }; - static ulong[] dim1738KuoInit = { 1 , 3 , 3 , 9 , 29 , 25 , 63 , 29 , 369 , 777 , 477 , 547 , 6575 , 13769 ,0 }; - static ulong[] dim1739KuoInit = { 1 , 1 , 3 , 1 , 3 , 5 , 101 , 107 , 11 , 817 , 413 , 3241 , 6275 , 4035 ,0 }; - static ulong[] dim1740KuoInit = { 1 , 1 , 1 , 3 , 21 , 17 , 25 , 113 , 183 , 159 , 307 , 447 , 7881 , 7399 ,0 }; - static ulong[] dim1741KuoInit = { 1 , 1 , 7 , 15 , 7 , 45 , 39 , 39 , 111 , 191 , 151 , 267 , 7133 , 5557 ,0 }; - static ulong[] dim1742KuoInit = { 1 , 3 , 7 , 5 , 27 , 39 , 29 , 59 , 141 , 835 , 1307 , 1007 , 2101 , 7675 ,0 }; - static ulong[] dim1743KuoInit = { 1 , 3 , 1 , 11 , 9 , 15 , 65 , 47 , 371 , 385 , 683 , 3495 , 711 , 3963 ,0 }; - static ulong[] dim1744KuoInit = { 1 , 1 , 7 , 3 , 5 , 59 , 81 , 9 , 23 , 885 , 291 , 2349 , 5495 , 12985 ,0 }; - static ulong[] dim1745KuoInit = { 1 , 3 , 5 , 1 , 21 , 49 , 99 , 101 , 447 , 289 , 659 , 1061 , 5771 , 7591 ,0 }; - static ulong[] dim1746KuoInit = { 1 , 3 , 5 , 7 , 5 , 11 , 13 , 255 , 7 , 775 , 1919 , 1965 , 7069 , 10379 ,0 }; - static ulong[] dim1747KuoInit = { 1 , 1 , 7 , 15 , 29 , 23 , 61 , 183 , 117 , 817 , 113 , 1665 , 2349 , 305 ,0 }; - static ulong[] dim1748KuoInit = { 1 , 3 , 7 , 13 , 25 , 9 , 97 , 161 , 361 , 33 , 1781 , 3717 , 6319 , 13199 ,0 }; - static ulong[] dim1749KuoInit = { 1 , 3 , 5 , 13 , 21 , 63 , 85 , 225 , 447 , 169 , 1601 , 2359 , 8087 , 2609 ,0 }; - static ulong[] dim1750KuoInit = { 1 , 1 , 3 , 9 , 1 , 11 , 1 , 173 , 345 , 217 , 1131 , 493 , 4613 , 9223 ,0 }; - static ulong[] dim1751KuoInit = { 1 , 3 , 7 , 3 , 5 , 51 , 55 , 235 , 129 , 451 , 1191 , 2065 , 6781 , 9135 ,0 }; - static ulong[] dim1752KuoInit = { 1 , 3 , 7 , 1 , 27 , 41 , 123 , 49 , 495 , 999 , 1731 , 1597 , 7471 , 1129 ,0 }; - static ulong[] dim1753KuoInit = { 1 , 1 , 5 , 3 , 13 , 3 , 123 , 83 , 199 , 325 , 1521 , 1023 , 2703 , 10915 ,0 }; - static ulong[] dim1754KuoInit = { 1 , 1 , 3 , 1 , 15 , 19 , 45 , 223 , 17 , 643 , 661 , 633 , 6475 , 10153 ,0 }; - static ulong[] dim1755KuoInit = { 1 , 1 , 7 , 9 , 17 , 21 , 101 , 137 , 39 , 975 , 1003 , 1419 , 353 , 11971 ,0 }; - static ulong[] dim1756KuoInit = { 1 , 3 , 5 , 3 , 11 , 37 , 75 , 87 , 49 , 535 , 801 , 1689 , 8125 , 12419 ,0 }; - static ulong[] dim1757KuoInit = { 1 , 3 , 3 , 3 , 19 , 11 , 99 , 97 , 285 , 641 , 1485 , 257 , 5417 , 8669 ,0 }; - static ulong[] dim1758KuoInit = { 1 , 1 , 1 , 1 , 21 , 53 , 19 , 61 , 223 , 917 , 931 , 1779 , 5859 , 3111 ,0 }; - static ulong[] dim1759KuoInit = { 1 , 3 , 1 , 13 , 25 , 17 , 55 , 227 , 61 , 953 , 255 , 3939 , 2523 , 2119 ,0 }; - static ulong[] dim1760KuoInit = { 1 , 1 , 7 , 11 , 23 , 43 , 111 , 21 , 263 , 399 , 723 , 1067 , 3633 , 4165 ,0 }; - static ulong[] dim1761KuoInit = { 1 , 3 , 7 , 3 , 31 , 29 , 69 , 135 , 105 , 839 , 1077 , 1479 , 643 , 1063 ,0 }; - static ulong[] dim1762KuoInit = { 1 , 3 , 1 , 11 , 23 , 29 , 51 , 235 , 287 , 941 , 393 , 2241 , 1601 , 4629 ,0 }; - static ulong[] dim1763KuoInit = { 1 , 3 , 3 , 1 , 1 , 7 , 47 , 119 , 369 , 789 , 1943 , 3417 , 4073 , 7495 ,0 }; - static ulong[] dim1764KuoInit = { 1 , 1 , 7 , 7 , 21 , 37 , 25 , 217 , 267 , 275 , 903 , 865 , 6251 , 1323 ,0 }; - static ulong[] dim1765KuoInit = { 1 , 3 , 7 , 15 , 13 , 61 , 77 , 181 , 479 , 1003 , 335 , 2917 , 1133 , 14321 ,0 }; - static ulong[] dim1766KuoInit = { 1 , 1 , 7 , 7 , 9 , 53 , 47 , 197 , 257 , 823 , 421 , 2465 , 4333 , 3841 ,0 }; - static ulong[] dim1767KuoInit = { 1 , 3 , 3 , 9 , 23 , 17 , 83 , 131 , 427 , 25 , 319 , 517 , 4109 , 15841 ,0 }; - static ulong[] dim1768KuoInit = { 1 , 1 , 7 , 7 , 7 , 25 , 105 , 63 , 117 , 173 , 909 , 2731 , 877 , 1095 ,0 }; - static ulong[] dim1769KuoInit = { 1 , 1 , 3 , 9 , 29 , 17 , 125 , 45 , 269 , 681 , 1389 , 283 , 7217 , 15315 ,0 }; - static ulong[] dim1770KuoInit = { 1 , 1 , 7 , 3 , 3 , 59 , 29 , 177 , 191 , 803 , 809 , 131 , 857 , 16213 ,0 }; - static ulong[] dim1771KuoInit = { 1 , 1 , 1 , 15 , 15 , 21 , 41 , 177 , 245 , 543 , 761 , 2423 , 1381 , 1125 ,0 }; - static ulong[] dim1772KuoInit = { 1 , 3 , 5 , 13 , 31 , 5 , 121 , 183 , 477 , 143 , 559 , 765 , 703 , 12255 ,0 }; - static ulong[] dim1773KuoInit = { 1 , 1 , 1 , 15 , 21 , 23 , 127 , 227 , 331 , 963 , 333 , 2101 , 2215 , 10107 ,0 }; - static ulong[] dim1774KuoInit = { 1 , 3 , 7 , 3 , 1 , 47 , 53 , 189 , 331 , 587 , 1417 , 731 , 4317 , 11629 ,0 }; - static ulong[] dim1775KuoInit = { 1 , 3 , 7 , 13 , 11 , 21 , 45 , 109 , 455 , 347 , 1483 , 2589 , 6933 , 8343 ,0 }; - static ulong[] dim1776KuoInit = { 1 , 1 , 1 , 11 , 5 , 31 , 45 , 85 , 253 , 729 , 111 , 3315 , 3183 , 12847 ,0 }; - static ulong[] dim1777KuoInit = { 1 , 3 , 1 , 1 , 25 , 5 , 3 , 219 , 263 , 517 , 247 , 2303 , 2709 , 11973 ,0 }; - static ulong[] dim1778KuoInit = { 1 , 1 , 5 , 11 , 21 , 39 , 115 , 231 , 5 , 451 , 1503 , 1527 , 4071 , 5879 ,0 }; - static ulong[] dim1779KuoInit = { 1 , 3 , 5 , 15 , 23 , 31 , 15 , 61 , 313 , 83 , 49 , 1377 , 7029 , 14187 ,0 }; - static ulong[] dim1780KuoInit = { 1 , 3 , 7 , 9 , 29 , 7 , 117 , 111 , 493 , 159 , 513 , 3841 , 7011 , 14723 ,0 }; - static ulong[] dim1781KuoInit = { 1 , 1 , 5 , 13 , 21 , 15 , 3 , 139 , 463 , 1023 , 1301 , 243 , 5105 , 2259 ,0 }; - static ulong[] dim1782KuoInit = { 1 , 1 , 7 , 13 , 5 , 3 , 119 , 111 , 447 , 75 , 1161 , 1917 , 345 , 557 ,0 }; - static ulong[] dim1783KuoInit = { 1 , 1 , 5 , 5 , 25 , 21 , 87 , 93 , 237 , 921 , 475 , 2555 , 4105 , 5691 ,0 }; - static ulong[] dim1784KuoInit = { 1 , 1 , 3 , 15 , 29 , 51 , 5 , 73 , 471 , 421 , 861 , 3833 , 2531 , 1059 ,0 }; - static ulong[] dim1785KuoInit = { 1 , 3 , 7 , 9 , 3 , 11 , 101 , 35 , 271 , 981 , 1661 , 1629 , 7321 , 1335 ,0 }; - static ulong[] dim1786KuoInit = { 1 , 1 , 5 , 9 , 9 , 37 , 9 , 127 , 45 , 215 , 611 , 1193 , 659 , 5975 ,0 }; - static ulong[] dim1787KuoInit = { 1 , 1 , 3 , 9 , 31 , 31 , 21 , 167 , 415 , 513 , 1917 , 829 , 1161 , 3585 ,0 }; - static ulong[] dim1788KuoInit = { 1 , 1 , 7 , 1 , 19 , 23 , 49 , 55 , 169 , 351 , 1389 , 3251 , 5001 , 13445 ,0 }; - static ulong[] dim1789KuoInit = { 1 , 3 , 1 , 15 , 3 , 3 , 113 , 193 , 391 , 851 , 681 , 2961 , 7239 , 12837 ,0 }; - static ulong[] dim1790KuoInit = { 1 , 3 , 5 , 15 , 5 , 43 , 71 , 1 , 347 , 635 , 1123 , 3399 , 2087 , 8209 ,0 }; - static ulong[] dim1791KuoInit = { 1 , 1 , 3 , 15 , 23 , 7 , 59 , 115 , 139 , 311 , 893 , 2421 , 405 , 6541 ,0 }; - static ulong[] dim1792KuoInit = { 1 , 3 , 3 , 3 , 25 , 23 , 127 , 135 , 199 , 661 , 7 , 3279 , 91 , 11879 ,0 }; - static ulong[] dim1793KuoInit = { 1 , 1 , 3 , 3 , 19 , 37 , 33 , 159 , 3 , 425 , 379 , 1321 , 369 , 13125 ,0 }; - static ulong[] dim1794KuoInit = { 1 , 3 , 5 , 15 , 7 , 17 , 47 , 47 , 167 , 909 , 403 , 95 , 7861 , 231 ,0 }; - static ulong[] dim1795KuoInit = { 1 , 1 , 5 , 1 , 15 , 5 , 69 , 179 , 229 , 597 , 1743 , 467 , 1859 , 2059 ,0 }; - static ulong[] dim1796KuoInit = { 1 , 1 , 7 , 15 , 5 , 63 , 109 , 191 , 271 , 281 , 907 , 489 , 5863 , 12697 ,0 }; - static ulong[] dim1797KuoInit = { 1 , 1 , 3 , 3 , 31 , 1 , 67 , 81 , 3 , 755 , 1839 , 1481 , 4691 , 14549 ,0 }; - static ulong[] dim1798KuoInit = { 1 , 3 , 3 , 15 , 17 , 13 , 59 , 23 , 85 , 951 , 1259 , 363 , 5479 , 10705 ,0 }; - static ulong[] dim1799KuoInit = { 1 , 1 , 3 , 15 , 11 , 61 , 111 , 109 , 361 , 483 , 1691 , 1039 , 3777 , 14613 ,0 }; - static ulong[] dim1800KuoInit = { 1 , 1 , 3 , 5 , 29 , 55 , 101 , 55 , 407 , 61 , 607 , 829 , 8011 , 14021 ,0 }; - static ulong[] dim1801KuoInit = { 1 , 1 , 1 , 13 , 1 , 39 , 29 , 19 , 389 , 85 , 313 , 1123 , 1303 , 11535 ,0 }; - static ulong[] dim1802KuoInit = { 1 , 1 , 1 , 5 , 5 , 45 , 47 , 139 , 165 , 937 , 1677 , 2973 , 501 , 4387 ,0 }; - static ulong[] dim1803KuoInit = { 1 , 3 , 5 , 9 , 5 , 55 , 89 , 235 , 29 , 75 , 1839 , 801 , 5753 , 4409 ,0 }; - static ulong[] dim1804KuoInit = { 1 , 1 , 3 , 5 , 7 , 41 , 7 , 185 , 297 , 661 , 1955 , 2193 , 6001 , 12349 ,0 }; - static ulong[] dim1805KuoInit = { 1 , 1 , 7 , 15 , 27 , 47 , 7 , 7 , 183 , 725 , 1511 , 3021 , 6091 , 10567 ,0 }; - static ulong[] dim1806KuoInit = { 1 , 3 , 3 , 13 , 21 , 7 , 79 , 133 , 307 , 759 , 369 , 2779 , 7629 , 16191 ,0 }; - static ulong[] dim1807KuoInit = { 1 , 1 , 5 , 9 , 5 , 47 , 15 , 141 , 293 , 339 , 1471 , 127 , 5805 , 5543 ,0 }; - static ulong[] dim1808KuoInit = { 1 , 3 , 1 , 9 , 31 , 7 , 125 , 27 , 511 , 549 , 619 , 743 , 3471 , 8595 ,0 }; - static ulong[] dim1809KuoInit = { 1 , 1 , 7 , 5 , 15 , 9 , 25 , 35 , 161 , 691 , 659 , 909 , 969 , 9285 ,0 }; - static ulong[] dim1810KuoInit = { 1 , 1 , 7 , 11 , 31 , 17 , 59 , 255 , 281 , 7 , 1075 , 2561 , 6883 , 8193 ,0 }; - static ulong[] dim1811KuoInit = { 1 , 1 , 7 , 1 , 9 , 15 , 83 , 253 , 415 , 601 , 417 , 3999 , 7513 , 3663 ,0 }; - static ulong[] dim1812KuoInit = { 1 , 3 , 5 , 7 , 11 , 25 , 109 , 135 , 41 , 5 , 697 , 1703 , 8175 , 11369 ,0 }; - static ulong[] dim1813KuoInit = { 1 , 1 , 7 , 15 , 7 , 39 , 1 , 253 , 373 , 273 , 857 , 401 , 1609 , 2391 ,0 }; - static ulong[] dim1814KuoInit = { 1 , 1 , 5 , 1 , 1 , 61 , 85 , 213 , 183 , 695 , 523 , 1237 , 5485 , 6843 ,0 }; - static ulong[] dim1815KuoInit = { 1 , 1 , 7 , 9 , 17 , 41 , 125 , 209 , 285 , 823 , 857 , 31 , 839 , 10847 ,0 }; - static ulong[] dim1816KuoInit = { 1 , 3 , 5 , 9 , 31 , 23 , 65 , 75 , 243 , 471 , 669 , 539 , 3949 , 14913 ,0 }; - static ulong[] dim1817KuoInit = { 1 , 1 , 7 , 3 , 25 , 23 , 109 , 19 , 89 , 983 , 193 , 1433 , 6401 , 663 ,0 }; - static ulong[] dim1818KuoInit = { 1 , 3 , 1 , 15 , 25 , 9 , 93 , 13 , 133 , 561 , 1343 , 4049 , 6221 , 3137 ,0 }; - static ulong[] dim1819KuoInit = { 1 , 1 , 3 , 3 , 31 , 47 , 105 , 225 , 231 , 75 , 187 , 963 , 3339 , 9705 ,0 }; - static ulong[] dim1820KuoInit = { 1 , 3 , 7 , 1 , 9 , 31 , 21 , 221 , 309 , 791 , 2011 , 241 , 5507 , 11579 ,0 }; - static ulong[] dim1821KuoInit = { 1 , 3 , 7 , 9 , 1 , 19 , 53 , 239 , 305 , 151 , 53 , 873 , 5235 , 13357 ,0 }; - static ulong[] dim1822KuoInit = { 1 , 1 , 5 , 15 , 13 , 27 , 23 , 255 , 75 , 435 , 209 , 2001 , 2529 , 5363 ,0 }; - static ulong[] dim1823KuoInit = { 1 , 1 , 7 , 5 , 25 , 53 , 71 , 203 , 259 , 403 , 1535 , 3381 , 6791 , 16061 ,0 }; - static ulong[] dim1824KuoInit = { 1 , 3 , 5 , 3 , 29 , 5 , 93 , 5 , 179 , 813 , 1569 , 2875 , 7855 , 13863 ,0 }; - static ulong[] dim1825KuoInit = { 1 , 1 , 3 , 7 , 1 , 13 , 97 , 125 , 479 , 209 , 1659 , 2997 , 3405 , 9707 ,0 }; - static ulong[] dim1826KuoInit = { 1 , 3 , 1 , 9 , 5 , 43 , 15 , 29 , 317 , 317 , 1317 , 3177 , 519 , 8115 ,0 }; - static ulong[] dim1827KuoInit = { 1 , 1 , 1 , 5 , 1 , 55 , 49 , 145 , 415 , 785 , 1489 , 1217 , 3829 , 10207 ,0 }; - static ulong[] dim1828KuoInit = { 1 , 3 , 3 , 9 , 17 , 5 , 99 , 235 , 277 , 921 , 71 , 343 , 2935 , 12495 ,0 }; - static ulong[] dim1829KuoInit = { 1 , 1 , 3 , 15 , 25 , 11 , 11 , 69 , 209 , 543 , 17 , 1489 , 8119 , 3557 ,0 }; - static ulong[] dim1830KuoInit = { 1 , 1 , 7 , 9 , 29 , 43 , 125 , 87 , 11 , 947 , 1709 , 17 , 3467 , 3339 ,0 }; - static ulong[] dim1831KuoInit = { 1 , 3 , 5 , 15 , 23 , 47 , 113 , 185 , 75 , 523 , 1253 , 859 , 6359 , 15563 ,0 }; - static ulong[] dim1832KuoInit = { 1 , 1 , 7 , 11 , 1 , 25 , 25 , 23 , 267 , 275 , 1751 , 3237 , 3967 , 9943 ,0 }; - static ulong[] dim1833KuoInit = { 1 , 1 , 1 , 13 , 7 , 35 , 43 , 151 , 489 , 97 , 143 , 257 , 771 , 8181 ,0 }; - static ulong[] dim1834KuoInit = { 1 , 1 , 3 , 7 , 19 , 11 , 17 , 23 , 425 , 869 , 525 , 95 , 2217 , 3931 ,0 }; - static ulong[] dim1835KuoInit = { 1 , 3 , 7 , 11 , 3 , 19 , 77 , 219 , 501 , 23 , 773 , 2421 , 3713 , 6209 ,0 }; - static ulong[] dim1836KuoInit = { 1 , 1 , 3 , 1 , 7 , 1 , 33 , 35 , 229 , 329 , 201 , 291 , 4165 , 16059 ,0 }; - static ulong[] dim1837KuoInit = { 1 , 3 , 5 , 9 , 17 , 23 , 107 , 23 , 3 , 673 , 609 , 2931 , 5989 , 3133 ,0 }; - static ulong[] dim1838KuoInit = { 1 , 3 , 3 , 3 , 17 , 59 , 31 , 63 , 111 , 287 , 407 , 769 , 2381 , 2203 ,0 }; - static ulong[] dim1839KuoInit = { 1 , 1 , 1 , 15 , 3 , 51 , 105 , 57 , 313 , 847 , 261 , 2697 , 749 , 15419 ,0 }; - static ulong[] dim1840KuoInit = { 1 , 3 , 1 , 11 , 3 , 21 , 65 , 139 , 363 , 21 , 1889 , 1007 , 6969 , 3609 ,0 }; - static ulong[] dim1841KuoInit = { 1 , 3 , 7 , 15 , 17 , 51 , 73 , 121 , 481 , 339 , 1409 , 131 , 2005 , 11847 ,0 }; - static ulong[] dim1842KuoInit = { 1 , 3 , 5 , 3 , 31 , 13 , 107 , 253 , 125 , 973 , 1027 , 3473 , 6883 , 15061 ,0 }; - static ulong[] dim1843KuoInit = { 1 , 3 , 1 , 5 , 25 , 17 , 11 , 255 , 209 , 35 , 1987 , 2275 , 2327 , 16079 ,0 }; - static ulong[] dim1844KuoInit = { 1 , 3 , 7 , 5 , 3 , 1 , 25 , 93 , 397 , 467 , 1895 , 3199 , 1861 , 10943 ,0 }; - static ulong[] dim1845KuoInit = { 1 , 3 , 7 , 1 , 23 , 27 , 13 , 211 , 299 , 117 , 1689 , 457 , 6335 , 11921 ,0 }; - static ulong[] dim1846KuoInit = { 1 , 1 , 5 , 5 , 9 , 59 , 49 , 177 , 81 , 913 , 429 , 2705 , 339 , 9347 ,0 }; - static ulong[] dim1847KuoInit = { 1 , 3 , 1 , 15 , 1 , 61 , 81 , 143 , 455 , 311 , 381 , 235 , 2537 , 12511 ,0 }; - static ulong[] dim1848KuoInit = { 1 , 3 , 5 , 11 , 7 , 33 , 103 , 137 , 377 , 717 , 851 , 2939 , 303 , 11175 ,0 }; - static ulong[] dim1849KuoInit = { 1 , 3 , 3 , 13 , 25 , 59 , 15 , 43 , 71 , 767 , 47 , 3425 , 7015 , 14431 ,0 }; - static ulong[] dim1850KuoInit = { 1 , 3 , 3 , 9 , 25 , 37 , 37 , 39 , 279 , 491 , 1483 , 2633 , 3791 , 14311 ,0 }; - static ulong[] dim1851KuoInit = { 1 , 1 , 1 , 13 , 29 , 63 , 83 , 89 , 339 , 923 , 455 , 965 , 7339 , 16383 ,0 }; - static ulong[] dim1852KuoInit = { 1 , 1 , 3 , 1 , 9 , 33 , 7 , 63 , 385 , 717 , 1449 , 2705 , 6233 , 10753 ,0 }; - static ulong[] dim1853KuoInit = { 1 , 3 , 1 , 11 , 15 , 13 , 11 , 181 , 271 , 749 , 1825 , 875 , 2497 , 12999 ,0 }; - static ulong[] dim1854KuoInit = { 1 , 3 , 3 , 7 , 13 , 49 , 35 , 65 , 467 , 259 , 429 , 549 , 5481 , 11343 ,0 }; - static ulong[] dim1855KuoInit = { 1 , 3 , 7 , 15 , 17 , 55 , 125 , 217 , 91 , 495 , 133 , 1985 , 4871 , 3415 ,0 }; - static ulong[] dim1856KuoInit = { 1 , 3 , 3 , 13 , 11 , 33 , 29 , 53 , 253 , 935 , 1919 , 2607 , 3205 , 819 ,0 }; - static ulong[] dim1857KuoInit = { 1 , 1 , 1 , 3 , 25 , 23 , 127 , 151 , 39 , 583 , 985 , 715 , 765 , 16343 ,0 }; - static ulong[] dim1858KuoInit = { 1 , 3 , 5 , 3 , 7 , 21 , 127 , 179 , 239 , 353 , 221 , 531 , 5147 , 6699 ,0 }; - static ulong[] dim1859KuoInit = { 1 , 1 , 7 , 9 , 7 , 63 , 91 , 99 , 495 , 111 , 1295 , 2609 , 6389 , 7719 ,0 }; - static ulong[] dim1860KuoInit = { 1 , 3 , 5 , 7 , 9 , 27 , 123 , 171 , 155 , 683 , 1209 , 2081 , 2823 , 1007 ,0 }; - static ulong[] dim1861KuoInit = { 1 , 3 , 3 , 15 , 25 , 45 , 91 , 93 , 329 , 961 , 1843 , 2637 , 4333 , 8359 ,0 }; - static ulong[] dim1862KuoInit = { 1 , 3 , 1 , 5 , 9 , 5 , 73 , 221 , 71 , 951 , 1175 , 2489 , 4565 , 7221 ,0 }; - static ulong[] dim1863KuoInit = { 1 , 3 , 1 , 3 , 31 , 33 , 67 , 127 , 427 , 487 , 239 , 787 , 1731 , 11867 ,0 }; - static ulong[] dim1864KuoInit = { 1 , 1 , 1 , 9 , 17 , 23 , 5 , 201 , 175 , 661 , 1381 , 3017 , 4237 , 14403 ,0 }; - static ulong[] dim1865KuoInit = { 1 , 3 , 7 , 7 , 31 , 7 , 39 , 141 , 299 , 237 , 281 , 3057 , 5553 , 11339 ,0 }; - static ulong[] dim1866KuoInit = { 1 , 1 , 1 , 15 , 25 , 49 , 51 , 135 , 363 , 377 , 1767 , 4069 , 3001 , 7111 ,0 }; - static ulong[] dim1867KuoInit = { 1 , 3 , 7 , 11 , 29 , 7 , 91 , 145 , 263 , 581 , 35 , 3101 , 6227 , 12007 , 30807 ,0 }; - static ulong[] dim1868KuoInit = { 1 , 1 , 1 , 13 , 11 , 41 , 61 , 135 , 61 , 501 , 189 , 1923 , 129 , 14563 , 12247 ,0 }; - static ulong[] dim1869KuoInit = { 1 , 1 , 3 , 5 , 17 , 45 , 53 , 5 , 199 , 165 , 859 , 771 , 4553 , 14723 , 17293 ,0 }; - static ulong[] dim1870KuoInit = { 1 , 1 , 3 , 15 , 27 , 57 , 41 , 3 , 437 , 543 , 1291 , 1083 , 1311 , 4407 , 9107 ,0 }; - static ulong[] dim1871KuoInit = { 1 , 1 , 3 , 11 , 19 , 23 , 17 , 251 , 267 , 575 , 1675 , 775 , 1281 , 12389 , 11781 ,0 }; - static ulong[] dim1872KuoInit = { 1 , 3 , 3 , 9 , 19 , 41 , 69 , 45 , 113 , 683 , 1843 , 1217 , 1075 , 7141 , 11259 ,0 }; - static ulong[] dim1873KuoInit = { 1 , 3 , 5 , 5 , 21 , 45 , 75 , 199 , 227 , 717 , 267 , 3211 , 5893 , 6559 , 16445 ,0 }; - static ulong[] dim1874KuoInit = { 1 , 1 , 3 , 15 , 25 , 19 , 13 , 3 , 477 , 511 , 1607 , 61 , 5937 , 6471 , 4561 ,0 }; - static ulong[] dim1875KuoInit = { 1 , 1 , 7 , 9 , 25 , 9 , 59 , 209 , 181 , 671 , 1473 , 1863 , 6835 , 5915 , 21573 ,0 }; - static ulong[] dim1876KuoInit = { 1 , 1 , 7 , 5 , 31 , 43 , 91 , 191 , 505 , 979 , 1431 , 1347 , 1445 , 9759 , 31653 ,0 }; - static ulong[] dim1877KuoInit = { 1 , 1 , 5 , 3 , 11 , 63 , 35 , 1 , 313 , 863 , 577 , 3039 , 5205 , 5089 , 20009 ,0 }; - static ulong[] dim1878KuoInit = { 1 , 3 , 3 , 7 , 1 , 27 , 79 , 21 , 179 , 187 , 917 , 1831 , 1737 , 2879 , 5801 ,0 }; - static ulong[] dim1879KuoInit = { 1 , 1 , 1 , 3 , 19 , 51 , 77 , 201 , 499 , 345 , 617 , 33 , 543 , 6925 , 5945 ,0 }; - static ulong[] dim1880KuoInit = { 1 , 3 , 1 , 1 , 19 , 49 , 67 , 51 , 181 , 1015 , 1159 , 2109 , 879 , 10257 , 23207 ,0 }; - static ulong[] dim1881KuoInit = { 1 , 1 , 7 , 7 , 19 , 29 , 7 , 111 , 365 , 373 , 1309 , 3633 , 5951 , 2597 , 27947 ,0 }; - static ulong[] dim1882KuoInit = { 1 , 3 , 5 , 13 , 21 , 27 , 85 , 71 , 149 , 665 , 1499 , 4025 , 3939 , 8947 , 15811 ,0 }; - static ulong[] dim1883KuoInit = { 1 , 3 , 7 , 5 , 25 , 47 , 77 , 99 , 105 , 739 , 1077 , 3145 , 7859 , 1925 , 16765 ,0 }; - static ulong[] dim1884KuoInit = { 1 , 1 , 3 , 11 , 25 , 9 , 113 , 105 , 309 , 397 , 1687 , 1171 , 455 , 3183 , 12487 ,0 }; - static ulong[] dim1885KuoInit = { 1 , 1 , 7 , 15 , 7 , 9 , 51 , 239 , 469 , 415 , 1895 , 89 , 4243 , 967 , 7113 ,0 }; - static ulong[] dim1886KuoInit = { 1 , 1 , 5 , 1 , 23 , 41 , 39 , 247 , 115 , 541 , 1461 , 2907 , 2175 , 3133 , 3171 ,0 }; - static ulong[] dim1887KuoInit = { 1 , 3 , 7 , 11 , 7 , 53 , 43 , 187 , 213 , 549 , 947 , 3695 , 3931 , 699 , 21299 ,0 }; - static ulong[] dim1888KuoInit = { 1 , 1 , 1 , 7 , 15 , 9 , 9 , 3 , 175 , 231 , 1529 , 337 , 5333 , 6945 , 1359 ,0 }; - static ulong[] dim1889KuoInit = { 1 , 1 , 3 , 3 , 13 , 25 , 123 , 231 , 389 , 351 , 1695 , 2959 , 1037 , 2103 , 327 ,0 }; - static ulong[] dim1890KuoInit = { 1 , 3 , 5 , 11 , 9 , 31 , 19 , 149 , 1 , 477 , 1819 , 3487 , 3299 , 8835 , 10351 ,0 }; - static ulong[] dim1891KuoInit = { 1 , 1 , 5 , 7 , 9 , 37 , 123 , 93 , 267 , 481 , 901 , 3927 , 7295 , 13251 , 22551 ,0 }; - static ulong[] dim1892KuoInit = { 1 , 1 , 7 , 11 , 21 , 13 , 127 , 173 , 459 , 169 , 1511 , 1649 , 5431 , 8637 , 3601 ,0 }; - static ulong[] dim1893KuoInit = { 1 , 1 , 1 , 9 , 29 , 3 , 101 , 135 , 159 , 295 , 1767 , 3089 , 3753 , 4969 , 21523 ,0 }; - static ulong[] dim1894KuoInit = { 1 , 3 , 5 , 3 , 3 , 9 , 45 , 143 , 301 , 307 , 191 , 3337 , 6721 , 12095 , 7017 ,0 }; - static ulong[] dim1895KuoInit = { 1 , 3 , 7 , 13 , 17 , 25 , 55 , 37 , 379 , 725 , 1079 , 311 , 2853 , 15097 , 31857 ,0 }; - static ulong[] dim1896KuoInit = { 1 , 3 , 1 , 13 , 19 , 57 , 39 , 99 , 39 , 283 , 425 , 2447 , 2077 , 815 , 7639 ,0 }; - static ulong[] dim1897KuoInit = { 1 , 3 , 3 , 15 , 11 , 5 , 17 , 83 , 231 , 535 , 35 , 2773 , 4127 , 9951 , 5773 ,0 }; - static ulong[] dim1898KuoInit = { 1 , 3 , 3 , 15 , 7 , 47 , 87 , 119 , 291 , 523 , 1325 , 1757 , 2377 , 6481 , 7901 ,0 }; - static ulong[] dim1899KuoInit = { 1 , 3 , 7 , 15 , 25 , 21 , 29 , 87 , 241 , 241 , 1273 , 2813 , 2011 , 8549 , 7253 ,0 }; - static ulong[] dim1900KuoInit = { 1 , 1 , 1 , 7 , 19 , 35 , 119 , 227 , 483 , 1015 , 685 , 1149 , 4823 , 4113 , 7169 ,0 }; - static ulong[] dim1901KuoInit = { 1 , 3 , 3 , 5 , 11 , 59 , 125 , 99 , 255 , 149 , 829 , 2869 , 7927 , 6779 , 31949 ,0 }; - static ulong[] dim1902KuoInit = { 1 , 3 , 7 , 3 , 3 , 49 , 21 , 111 , 219 , 33 , 91 , 1585 , 303 , 14931 , 11777 ,0 }; - static ulong[] dim1903KuoInit = { 1 , 3 , 3 , 11 , 3 , 47 , 27 , 227 , 477 , 891 , 1281 , 1927 , 7325 , 14075 , 26633 ,0 }; - static ulong[] dim1904KuoInit = { 1 , 1 , 5 , 5 , 5 , 29 , 25 , 23 , 223 , 65 , 1511 , 2563 , 7825 , 7339 , 32095 ,0 }; - static ulong[] dim1905KuoInit = { 1 , 1 , 5 , 7 , 3 , 29 , 49 , 83 , 317 , 513 , 755 , 1339 , 4829 , 6213 , 29055 ,0 }; - static ulong[] dim1906KuoInit = { 1 , 1 , 3 , 5 , 23 , 23 , 97 , 27 , 379 , 183 , 933 , 3431 , 797 , 9655 , 32061 ,0 }; - static ulong[] dim1907KuoInit = { 1 , 1 , 7 , 1 , 29 , 61 , 31 , 75 , 331 , 487 , 229 , 2319 , 1385 , 14697 , 17081 ,0 }; - static ulong[] dim1908KuoInit = { 1 , 1 , 1 , 5 , 19 , 1 , 43 , 27 , 433 , 751 , 1283 , 559 , 7941 , 7385 , 13809 ,0 }; - static ulong[] dim1909KuoInit = { 1 , 1 , 3 , 15 , 19 , 37 , 97 , 219 , 217 , 39 , 1969 , 1909 , 2895 , 749 , 27607 ,0 }; - static ulong[] dim1910KuoInit = { 1 , 3 , 5 , 9 , 25 , 17 , 79 , 213 , 321 , 73 , 533 , 3773 , 6989 , 10183 , 20179 ,0 }; - static ulong[] dim1911KuoInit = { 1 , 1 , 5 , 7 , 15 , 51 , 71 , 161 , 107 , 531 , 461 , 15 , 2887 , 13271 , 24273 ,0 }; - static ulong[] dim1912KuoInit = { 1 , 3 , 5 , 7 , 29 , 21 , 119 , 53 , 207 , 471 , 987 , 1771 , 7259 , 4377 , 15405 ,0 }; - static ulong[] dim1913KuoInit = { 1 , 1 , 3 , 11 , 3 , 5 , 7 , 189 , 231 , 181 , 751 , 1 , 225 , 12575 , 4853 ,0 }; - static ulong[] dim1914KuoInit = { 1 , 1 , 1 , 13 , 1 , 51 , 35 , 239 , 145 , 827 , 1169 , 3671 , 7585 , 4593 , 4433 ,0 }; - static ulong[] dim1915KuoInit = { 1 , 1 , 3 , 13 , 15 , 55 , 43 , 157 , 13 , 517 , 1669 , 25 , 1175 , 3971 , 11165 ,0 }; - static ulong[] dim1916KuoInit = { 1 , 3 , 7 , 15 , 15 , 37 , 33 , 155 , 243 , 375 , 947 , 1869 , 2693 , 5191 , 9865 ,0 }; - static ulong[] dim1917KuoInit = { 1 , 3 , 7 , 1 , 15 , 57 , 73 , 15 , 389 , 341 , 207 , 3249 , 439 , 5975 , 23461 ,0 }; - static ulong[] dim1918KuoInit = { 1 , 3 , 3 , 11 , 17 , 3 , 35 , 245 , 349 , 915 , 1221 , 1495 , 5525 , 10223 , 29109 ,0 }; - static ulong[] dim1919KuoInit = { 1 , 1 , 7 , 9 , 19 , 17 , 39 , 49 , 159 , 163 , 419 , 1117 , 7947 , 7177 , 10945 ,0 }; - static ulong[] dim1920KuoInit = { 1 , 3 , 7 , 5 , 23 , 35 , 31 , 33 , 325 , 565 , 1951 , 745 , 6867 , 13121 , 25831 ,0 }; - static ulong[] dim1921KuoInit = { 1 , 3 , 7 , 7 , 27 , 11 , 89 , 191 , 233 , 57 , 1621 , 2167 , 7155 , 15613 , 14111 ,0 }; - static ulong[] dim1922KuoInit = { 1 , 1 , 7 , 15 , 31 , 49 , 3 , 245 , 51 , 173 , 1809 , 379 , 8085 , 5125 , 10279 ,0 }; - static ulong[] dim1923KuoInit = { 1 , 1 , 7 , 7 , 29 , 59 , 37 , 197 , 377 , 5 , 1851 , 3685 , 3537 , 1897 , 24257 ,0 }; - static ulong[] dim1924KuoInit = { 1 , 1 , 1 , 11 , 13 , 9 , 11 , 19 , 377 , 435 , 869 , 497 , 8181 , 3411 , 4415 ,0 }; - static ulong[] dim1925KuoInit = { 1 , 1 , 5 , 7 , 7 , 21 , 51 , 115 , 435 , 9 , 1099 , 987 , 1633 , 7689 , 19131 ,0 }; - static ulong[] dim1926KuoInit = { 1 , 3 , 3 , 5 , 17 , 59 , 93 , 131 , 17 , 637 , 211 , 2759 , 3059 , 4691 , 10225 ,0 }; - static ulong[] dim1927KuoInit = { 1 , 3 , 3 , 13 , 5 , 35 , 55 , 49 , 425 , 395 , 615 , 1505 , 1477 , 6689 , 28435 ,0 }; - static ulong[] dim1928KuoInit = { 1 , 1 , 3 , 5 , 27 , 1 , 43 , 53 , 375 , 657 , 1307 , 1869 , 415 , 1143 , 16961 ,0 }; - static ulong[] dim1929KuoInit = { 1 , 1 , 7 , 5 , 13 , 27 , 111 , 113 , 459 , 149 , 139 , 79 , 5031 , 15165 , 443 ,0 }; - static ulong[] dim1930KuoInit = { 1 , 3 , 1 , 11 , 9 , 45 , 35 , 217 , 259 , 523 , 601 , 499 , 7683 , 1447 , 5267 ,0 }; - static ulong[] dim1931KuoInit = { 1 , 3 , 1 , 7 , 3 , 51 , 101 , 191 , 469 , 435 , 883 , 343 , 1897 , 5245 , 1037 ,0 }; - static ulong[] dim1932KuoInit = { 1 , 3 , 5 , 1 , 19 , 21 , 109 , 105 , 363 , 409 , 1651 , 3739 , 339 , 12915 , 31603 ,0 }; - static ulong[] dim1933KuoInit = { 1 , 3 , 5 , 13 , 9 , 7 , 65 , 193 , 447 , 829 , 1123 , 2431 , 3357 , 6687 , 26903 ,0 }; - static ulong[] dim1934KuoInit = { 1 , 3 , 5 , 5 , 11 , 9 , 69 , 147 , 331 , 657 , 1589 , 3417 , 5805 , 8673 , 2517 ,0 }; - static ulong[] dim1935KuoInit = { 1 , 3 , 1 , 5 , 23 , 45 , 59 , 53 , 285 , 711 , 1447 , 927 , 8005 , 3513 , 18147 ,0 }; - static ulong[] dim1936KuoInit = { 1 , 3 , 5 , 9 , 9 , 15 , 17 , 85 , 165 , 923 , 915 , 3263 , 1103 , 9445 , 15371 ,0 }; - static ulong[] dim1937KuoInit = { 1 , 1 , 5 , 13 , 13 , 13 , 33 , 249 , 501 , 495 , 1771 , 1305 , 2821 , 9405 , 7193 ,0 }; - static ulong[] dim1938KuoInit = { 1 , 1 , 3 , 5 , 9 , 11 , 23 , 5 , 359 , 977 , 613 , 2163 , 4511 , 7901 , 1609 ,0 }; - static ulong[] dim1939KuoInit = { 1 , 1 , 3 , 5 , 29 , 29 , 73 , 69 , 155 , 863 , 243 , 2705 , 4005 , 11249 , 13983 ,0 }; - static ulong[] dim1940KuoInit = { 1 , 3 , 7 , 9 , 9 , 15 , 75 , 171 , 213 , 931 , 1613 , 3801 , 4617 , 3929 , 24787 ,0 }; - static ulong[] dim1941KuoInit = { 1 , 3 , 5 , 11 , 19 , 35 , 107 , 251 , 121 , 455 , 2027 , 2323 , 4297 , 7949 , 12043 ,0 }; - static ulong[] dim1942KuoInit = { 1 , 3 , 3 , 7 , 3 , 59 , 13 , 151 , 161 , 615 , 1427 , 2469 , 3211 , 6601 , 26829 ,0 }; - static ulong[] dim1943KuoInit = { 1 , 1 , 1 , 9 , 31 , 1 , 41 , 247 , 225 , 65 , 1751 , 3557 , 935 , 16115 , 3009 ,0 }; - static ulong[] dim1944KuoInit = { 1 , 1 , 7 , 1 , 31 , 3 , 31 , 39 , 279 , 213 , 1141 , 371 , 7529 , 12485 , 6585 ,0 }; - static ulong[] dim1945KuoInit = { 1 , 3 , 3 , 3 , 13 , 31 , 121 , 185 , 171 , 991 , 147 , 1913 , 475 , 15155 , 2427 ,0 }; - static ulong[] dim1946KuoInit = { 1 , 3 , 5 , 5 , 7 , 13 , 59 , 127 , 175 , 717 , 759 , 3949 , 4229 , 2091 , 20267 ,0 }; - static ulong[] dim1947KuoInit = { 1 , 3 , 1 , 15 , 21 , 33 , 45 , 57 , 1 , 463 , 1217 , 1499 , 269 , 11159 , 17175 ,0 }; - static ulong[] dim1948KuoInit = { 1 , 1 , 1 , 9 , 21 , 29 , 51 , 63 , 299 , 775 , 239 , 575 , 1033 , 3627 , 12017 ,0 }; - static ulong[] dim1949KuoInit = { 1 , 3 , 3 , 3 , 23 , 35 , 63 , 197 , 341 , 775 , 675 , 1835 , 4155 , 7439 , 1797 ,0 }; - static ulong[] dim1950KuoInit = { 1 , 3 , 7 , 5 , 23 , 57 , 71 , 181 , 1 , 95 , 337 , 1971 , 5721 , 15013 , 3387 ,0 }; - static ulong[] dim1951KuoInit = { 1 , 3 , 1 , 5 , 31 , 21 , 33 , 203 , 463 , 3 , 1261 , 555 , 3847 , 5653 , 18155 ,0 }; - static ulong[] dim1952KuoInit = { 1 , 1 , 3 , 9 , 27 , 57 , 57 , 119 , 213 , 723 , 1695 , 2233 , 1605 , 8169 , 28485 ,0 }; - static ulong[] dim1953KuoInit = { 1 , 1 , 7 , 11 , 17 , 35 , 119 , 167 , 391 , 111 , 229 , 695 , 4209 , 5457 , 6729 ,0 }; - static ulong[] dim1954KuoInit = { 1 , 1 , 7 , 11 , 5 , 23 , 5 , 223 , 89 , 447 , 2015 , 3403 , 1335 , 15235 , 20897 ,0 }; - static ulong[] dim1955KuoInit = { 1 , 1 , 1 , 7 , 1 , 63 , 55 , 233 , 351 , 323 , 497 , 1247 , 2455 , 2337 , 17523 ,0 }; - static ulong[] dim1956KuoInit = { 1 , 3 , 1 , 11 , 7 , 21 , 127 , 207 , 197 , 479 , 611 , 3525 , 2093 , 2591 , 21085 ,0 }; - static ulong[] dim1957KuoInit = { 1 , 3 , 5 , 5 , 1 , 37 , 107 , 199 , 29 , 995 , 1857 , 133 , 1423 , 9967 , 11367 ,0 }; - static ulong[] dim1958KuoInit = { 1 , 1 , 7 , 11 , 25 , 25 , 17 , 155 , 221 , 539 , 1895 , 1909 , 2921 , 13107 , 21681 ,0 }; - static ulong[] dim1959KuoInit = { 1 , 1 , 1 , 13 , 25 , 59 , 45 , 41 , 401 , 657 , 2043 , 1317 , 8065 , 11897 , 4767 ,0 }; - static ulong[] dim1960KuoInit = { 1 , 1 , 7 , 15 , 21 , 29 , 43 , 125 , 407 , 851 , 1421 , 1101 , 811 , 9577 , 27 ,0 }; - static ulong[] dim1961KuoInit = { 1 , 3 , 5 , 7 , 25 , 49 , 65 , 175 , 319 , 807 , 1691 , 357 , 4015 , 1059 , 599 ,0 }; - static ulong[] dim1962KuoInit = { 1 , 1 , 7 , 13 , 23 , 5 , 65 , 79 , 43 , 665 , 1931 , 2143 , 4577 , 5905 , 14917 ,0 }; - static ulong[] dim1963KuoInit = { 1 , 3 , 1 , 7 , 5 , 41 , 121 , 251 , 395 , 951 , 795 , 1589 , 4027 , 13671 , 18787 ,0 }; - static ulong[] dim1964KuoInit = { 1 , 3 , 7 , 11 , 3 , 51 , 57 , 177 , 63 , 33 , 1085 , 1357 , 5039 , 2583 , 2805 ,0 }; - static ulong[] dim1965KuoInit = { 1 , 1 , 1 , 1 , 29 , 53 , 117 , 225 , 373 , 1 , 901 , 3871 , 2815 , 9871 , 7737 ,0 }; - static ulong[] dim1966KuoInit = { 1 , 3 , 7 , 7 , 31 , 61 , 89 , 253 , 291 , 829 , 9 , 1131 , 4951 , 14509 , 23491 ,0 }; - static ulong[] dim1967KuoInit = { 1 , 1 , 7 , 5 , 25 , 43 , 35 , 63 , 425 , 757 , 217 , 821 , 1453 , 8413 , 7745 ,0 }; - static ulong[] dim1968KuoInit = { 1 , 1 , 5 , 5 , 7 , 1 , 41 , 233 , 235 , 599 , 833 , 3637 , 7005 , 789 , 27709 ,0 }; - static ulong[] dim1969KuoInit = { 1 , 1 , 3 , 13 , 7 , 57 , 69 , 115 , 417 , 99 , 1435 , 3119 , 1655 , 3515 , 7273 ,0 }; - static ulong[] dim1970KuoInit = { 1 , 1 , 3 , 15 , 9 , 13 , 33 , 57 , 179 , 847 , 289 , 2213 , 4635 , 2349 , 20203 ,0 }; - static ulong[] dim1971KuoInit = { 1 , 1 , 3 , 9 , 1 , 39 , 63 , 147 , 277 , 389 , 575 , 423 , 4943 , 4327 , 29067 ,0 }; - static ulong[] dim1972KuoInit = { 1 , 1 , 3 , 13 , 9 , 9 , 69 , 167 , 119 , 591 , 1679 , 3543 , 4517 , 9263 , 17957 ,0 }; - static ulong[] dim1973KuoInit = { 1 , 3 , 5 , 13 , 25 , 37 , 127 , 159 , 391 , 29 , 329 , 3477 , 6513 , 11971 , 18791 ,0 }; - static ulong[] dim1974KuoInit = { 1 , 1 , 7 , 5 , 25 , 29 , 49 , 135 , 387 , 921 , 391 , 665 , 6315 , 16183 , 553 ,0 }; - static ulong[] dim1975KuoInit = { 1 , 1 , 7 , 3 , 27 , 43 , 43 , 253 , 9 , 285 , 1073 , 2627 , 7417 , 3223 , 2649 ,0 }; - static ulong[] dim1976KuoInit = { 1 , 1 , 5 , 3 , 13 , 57 , 119 , 37 , 475 , 471 , 1145 , 2709 , 2115 , 6507 , 12393 ,0 }; - static ulong[] dim1977KuoInit = { 1 , 1 , 3 , 1 , 17 , 29 , 117 , 189 , 319 , 533 , 1299 , 1987 , 4971 , 15719 , 19395 ,0 }; - static ulong[] dim1978KuoInit = { 1 , 1 , 1 , 15 , 11 , 63 , 77 , 245 , 57 , 9 , 1285 , 2069 , 579 , 5105 , 13797 ,0 }; - static ulong[] dim1979KuoInit = { 1 , 3 , 1 , 11 , 19 , 49 , 1 , 241 , 89 , 519 , 591 , 3875 , 1585 , 7239 , 25867 ,0 }; - static ulong[] dim1980KuoInit = { 1 , 1 , 5 , 11 , 27 , 47 , 1 , 143 , 209 , 695 , 539 , 3781 , 6317 , 14075 , 27849 ,0 }; - static ulong[] dim1981KuoInit = { 1 , 1 , 3 , 5 , 17 , 3 , 17 , 201 , 105 , 771 , 497 , 735 , 3517 , 5207 , 20897 ,0 }; - static ulong[] dim1982KuoInit = { 1 , 1 , 3 , 15 , 3 , 3 , 103 , 35 , 421 , 235 , 1527 , 3139 , 2693 , 9739 , 63 ,0 }; - static ulong[] dim1983KuoInit = { 1 , 3 , 1 , 13 , 21 , 39 , 101 , 213 , 205 , 853 , 1455 , 39 , 7917 , 7893 , 4627 ,0 }; - static ulong[] dim1984KuoInit = { 1 , 3 , 7 , 5 , 13 , 5 , 9 , 239 , 129 , 355 , 809 , 3413 , 7535 , 7063 , 29149 ,0 }; - static ulong[] dim1985KuoInit = { 1 , 1 , 5 , 3 , 19 , 37 , 125 , 55 , 495 , 597 , 735 , 1729 , 619 , 12881 , 22913 ,0 }; - static ulong[] dim1986KuoInit = { 1 , 1 , 5 , 11 , 27 , 31 , 87 , 65 , 413 , 421 , 575 , 2185 , 4217 , 12223 , 22487 ,0 }; - static ulong[] dim1987KuoInit = { 1 , 3 , 3 , 7 , 23 , 51 , 115 , 221 , 369 , 27 , 229 , 613 , 3739 , 1425 , 10927 ,0 }; - static ulong[] dim1988KuoInit = { 1 , 1 , 1 , 13 , 23 , 49 , 73 , 223 , 139 , 511 , 899 , 483 , 7747 , 7947 , 32357 ,0 }; - static ulong[] dim1989KuoInit = { 1 , 3 , 5 , 3 , 7 , 31 , 9 , 119 , 417 , 723 , 2033 , 663 , 5927 , 1787 , 12841 ,0 }; - static ulong[] dim1990KuoInit = { 1 , 1 , 5 , 9 , 7 , 5 , 55 , 201 , 245 , 221 , 1447 , 405 , 447 , 2447 , 24331 ,0 }; - static ulong[] dim1991KuoInit = { 1 , 3 , 5 , 11 , 9 , 47 , 33 , 175 , 187 , 513 , 1613 , 2413 , 4207 , 6941 , 2341 ,0 }; - static ulong[] dim1992KuoInit = { 1 , 1 , 5 , 9 , 19 , 33 , 33 , 181 , 505 , 923 , 1923 , 2471 , 6499 , 11243 , 29653 ,0 }; - static ulong[] dim1993KuoInit = { 1 , 1 , 5 , 15 , 1 , 49 , 21 , 15 , 443 , 565 , 1955 , 3299 , 139 , 14389 , 28011 ,0 }; - static ulong[] dim1994KuoInit = { 1 , 1 , 3 , 9 , 17 , 27 , 29 , 65 , 509 , 867 , 707 , 2425 , 7279 , 15271 , 18239 ,0 }; - static ulong[] dim1995KuoInit = { 1 , 1 , 7 , 15 , 3 , 1 , 103 , 79 , 49 , 909 , 529 , 1207 , 231 , 11181 , 23319 ,0 }; - static ulong[] dim1996KuoInit = { 1 , 1 , 5 , 1 , 13 , 23 , 33 , 29 , 189 , 491 , 129 , 501 , 2635 , 2071 , 18057 ,0 }; - static ulong[] dim1997KuoInit = { 1 , 1 , 7 , 7 , 19 , 1 , 95 , 185 , 67 , 251 , 1017 , 105 , 3683 , 9797 , 24413 ,0 }; - static ulong[] dim1998KuoInit = { 1 , 3 , 5 , 9 , 13 , 35 , 79 , 213 , 223 , 1013 , 1205 , 1777 , 1415 , 5023 , 15901 ,0 }; - static ulong[] dim1999KuoInit = { 1 , 1 , 1 , 5 , 15 , 13 , 91 , 57 , 447 , 897 , 935 , 1543 , 5461 , 5091 , 12697 ,0 }; - static ulong[] dim2000KuoInit = { 1 , 1 , 1 , 11 , 9 , 61 , 81 , 147 , 55 , 121 , 449 , 2833 , 2383 , 12065 , 19435 ,0 }; - static ulong[] dim2001KuoInit = { 1 , 3 , 1 , 3 , 17 , 27 , 77 , 203 , 415 , 489 , 665 , 21 , 6453 , 5069 , 29629 ,0 }; - static ulong[] dim2002KuoInit = { 1 , 1 , 1 , 9 , 7 , 3 , 33 , 209 , 85 , 851 , 367 , 783 , 309 , 14821 , 1217 ,0 }; - static ulong[] dim2003KuoInit = { 1 , 1 , 1 , 15 , 5 , 39 , 15 , 225 , 241 , 477 , 999 , 841 , 4637 , 5383 , 18081 ,0 }; - static ulong[] dim2004KuoInit = { 1 , 1 , 5 , 5 , 19 , 49 , 101 , 115 , 87 , 781 , 815 , 2405 , 2579 , 15043 , 31067 ,0 }; - static ulong[] dim2005KuoInit = { 1 , 1 , 3 , 5 , 3 , 57 , 123 , 191 , 305 , 999 , 1091 , 733 , 3219 , 891 , 30495 ,0 }; - static ulong[] dim2006KuoInit = { 1 , 1 , 5 , 3 , 27 , 17 , 95 , 121 , 39 , 41 , 171 , 97 , 7363 , 11279 , 28039 ,0 }; - static ulong[] dim2007KuoInit = { 1 , 3 , 7 , 5 , 21 , 9 , 21 , 147 , 269 , 475 , 1825 , 1459 , 6337 , 3259 , 27731 ,0 }; - static ulong[] dim2008KuoInit = { 1 , 1 , 3 , 5 , 9 , 17 , 107 , 171 , 253 , 71 , 629 , 1671 , 2587 , 11429 , 8985 ,0 }; - static ulong[] dim2009KuoInit = { 1 , 3 , 3 , 9 , 25 , 1 , 63 , 15 , 173 , 79 , 1465 , 2647 , 6885 , 13043 , 24703 ,0 }; - static ulong[] dim2010KuoInit = { 1 , 3 , 1 , 9 , 1 , 13 , 3 , 217 , 49 , 77 , 1635 , 3767 , 173 , 12697 , 11837 ,0 }; - static ulong[] dim2011KuoInit = { 1 , 3 , 5 , 13 , 31 , 7 , 11 , 181 , 509 , 601 , 1267 , 1857 , 7871 , 1703 , 6091 ,0 }; - static ulong[] dim2012KuoInit = { 1 , 1 , 1 , 11 , 29 , 61 , 117 , 151 , 487 , 185 , 1899 , 575 , 7341 , 3055 , 26513 ,0 }; - static ulong[] dim2013KuoInit = { 1 , 3 , 7 , 15 , 1 , 49 , 87 , 23 , 483 , 603 , 1197 , 2589 , 1705 , 5759 , 19791 ,0 }; - static ulong[] dim2014KuoInit = { 1 , 3 , 3 , 11 , 1 , 37 , 71 , 115 , 59 , 167 , 1907 , 2225 , 5673 , 14571 , 19389 ,0 }; - static ulong[] dim2015KuoInit = { 1 , 1 , 3 , 7 , 15 , 57 , 33 , 143 , 45 , 321 , 779 , 543 , 3465 , 4769 , 19753 ,0 }; - static ulong[] dim2016KuoInit = { 1 , 3 , 5 , 5 , 31 , 21 , 21 , 141 , 197 , 397 , 1041 , 317 , 109 , 9395 , 7141 ,0 }; - static ulong[] dim2017KuoInit = { 1 , 3 , 7 , 11 , 1 , 61 , 45 , 215 , 405 , 365 , 1801 , 2767 , 6381 , 12975 , 41 ,0 }; - static ulong[] dim2018KuoInit = { 1 , 3 , 7 , 7 , 23 , 13 , 37 , 193 , 305 , 883 , 1427 , 3859 , 2049 , 16065 , 2471 ,0 }; - static ulong[] dim2019KuoInit = { 1 , 3 , 3 , 3 , 31 , 3 , 9 , 169 , 433 , 187 , 545 , 985 , 7699 , 1183 , 27773 ,0 }; - static ulong[] dim2020KuoInit = { 1 , 3 , 5 , 15 , 11 , 15 , 9 , 171 , 89 , 711 , 163 , 3637 , 5725 , 5079 , 13373 ,0 }; - static ulong[] dim2021KuoInit = { 1 , 1 , 7 , 1 , 1 , 29 , 123 , 235 , 229 , 667 , 1155 , 3387 , 129 , 13889 , 24547 ,0 }; - static ulong[] dim2022KuoInit = { 1 , 3 , 3 , 7 , 27 , 15 , 75 , 117 , 335 , 821 , 609 , 3843 , 79 , 6787 , 5605 ,0 }; - static ulong[] dim2023KuoInit = { 1 , 1 , 3 , 15 , 27 , 47 , 13 , 163 , 205 , 773 , 541 , 1155 , 4341 , 14155 , 6643 ,0 }; - static ulong[] dim2024KuoInit = { 1 , 3 , 3 , 11 , 31 , 1 , 67 , 35 , 443 , 723 , 1089 , 2605 , 4193 , 6133 , 31127 ,0 }; - static ulong[] dim2025KuoInit = { 1 , 1 , 1 , 15 , 27 , 57 , 11 , 153 , 199 , 219 , 1987 , 2517 , 1455 , 6051 , 9615 ,0 }; - static ulong[] dim2026KuoInit = { 1 , 3 , 5 , 9 , 5 , 7 , 79 , 187 , 93 , 679 , 1607 , 799 , 2753 , 6513 , 11371 ,0 }; - static ulong[] dim2027KuoInit = { 1 , 3 , 1 , 15 , 31 , 55 , 5 , 175 , 261 , 545 , 995 , 2225 , 2217 , 2037 , 14785 ,0 }; - static ulong[] dim2028KuoInit = { 1 , 3 , 5 , 9 , 29 , 5 , 101 , 223 , 241 , 829 , 1625 , 3417 , 1335 , 10705 , 531 ,0 }; - static ulong[] dim2029KuoInit = { 1 , 3 , 3 , 1 , 19 , 15 , 5 , 203 , 97 , 165 , 99 , 2371 , 3267 , 13169 , 22229 ,0 }; - static ulong[] dim2030KuoInit = { 1 , 1 , 1 , 7 , 11 , 63 , 113 , 255 , 145 , 589 , 1149 , 683 , 2619 , 5569 , 5933 ,0 }; - static ulong[] dim2031KuoInit = { 1 , 1 , 5 , 9 , 23 , 41 , 21 , 217 , 503 , 975 , 329 , 3433 , 6299 , 5337 , 199 ,0 }; - static ulong[] dim2032KuoInit = { 1 , 1 , 7 , 13 , 3 , 39 , 109 , 223 , 241 , 521 , 1071 , 589 , 1199 , 13059 , 24921 ,0 }; - static ulong[] dim2033KuoInit = { 1 , 1 , 3 , 7 , 11 , 23 , 27 , 15 , 107 , 679 , 87 , 3259 , 4369 , 7365 , 16293 ,0 }; - static ulong[] dim2034KuoInit = { 1 , 3 , 3 , 11 , 11 , 5 , 75 , 111 , 21 , 587 , 1707 , 1915 , 6617 , 11143 , 24389 ,0 }; - static ulong[] dim2035KuoInit = { 1 , 1 , 5 , 9 , 5 , 59 , 77 , 3 , 43 , 583 , 1601 , 2183 , 6209 , 5409 , 18175 ,0 }; - static ulong[] dim2036KuoInit = { 1 , 1 , 1 , 1 , 15 , 1 , 55 , 95 , 437 , 731 , 1559 , 2421 , 7441 , 6567 , 1549 ,0 }; - static ulong[] dim2037KuoInit = { 1 , 3 , 3 , 11 , 17 , 21 , 13 , 61 , 153 , 81 , 141 , 3095 , 5485 , 14461 , 8495 ,0 }; - static ulong[] dim2038KuoInit = { 1 , 1 , 1 , 13 , 25 , 61 , 87 , 195 , 243 , 47 , 103 , 3451 , 5583 , 1611 , 11939 ,0 }; - static ulong[] dim2039KuoInit = { 1 , 1 , 5 , 7 , 31 , 53 , 93 , 101 , 145 , 917 , 1669 , 867 , 6949 , 16333 , 12577 ,0 }; - static ulong[] dim2040KuoInit = { 1 , 1 , 5 , 1 , 5 , 41 , 35 , 75 , 331 , 671 , 1623 , 1573 , 4275 , 9031 , 9047 ,0 }; - static ulong[] dim2041KuoInit = { 1 , 3 , 5 , 13 , 15 , 39 , 29 , 183 , 477 , 787 , 1333 , 2499 , 2189 , 8387 , 2783 ,0 }; - static ulong[] dim2042KuoInit = { 1 , 1 , 3 , 7 , 19 , 33 , 117 , 201 , 177 , 595 , 69 , 3341 , 1841 , 11091 , 16745 ,0 }; - static ulong[] dim2043KuoInit = { 1 , 3 , 7 , 11 , 29 , 59 , 69 , 119 , 433 , 595 , 221 , 1245 , 7805 , 1761 , 27657 ,0 }; - static ulong[] dim2044KuoInit = { 1 , 3 , 5 , 3 , 23 , 19 , 75 , 189 , 279 , 867 , 113 , 3817 , 6093 , 12237 , 20297 ,0 }; - static ulong[] dim2045KuoInit = { 1 , 1 , 1 , 15 , 21 , 39 , 15 , 249 , 9 , 997 , 51 , 1317 , 1083 , 13683 , 5759 ,0 }; - static ulong[] dim2046KuoInit = { 1 , 1 , 5 , 15 , 29 , 29 , 25 , 93 , 465 , 549 , 283 , 1673 , 1745 , 3913 , 7931 ,0 }; - static ulong[] dim2047KuoInit = { 1 , 3 , 5 , 1 , 5 , 23 , 123 , 217 , 211 , 215 , 1999 , 1229 , 6969 , 13481 , 14795 ,0 }; - static ulong[] dim2048KuoInit = { 1 , 1 , 3 , 5 , 17 , 35 , 107 , 163 , 103 , 807 , 463 , 2999 , 4889 , 12863 , 24619 ,0 }; - static ulong[] dim2049KuoInit = { 1 , 3 , 1 , 15 , 5 , 17 , 121 , 209 , 49 , 871 , 1931 , 345 , 6887 , 1357 , 14693 ,0 }; - static ulong[] dim2050KuoInit = { 1 , 1 , 1 , 1 , 23 , 63 , 53 , 35 , 511 , 261 , 11 , 283 , 3283 , 1963 , 11703 ,0 }; - static ulong[] dim2051KuoInit = { 1 , 3 , 3 , 13 , 15 , 41 , 19 , 39 , 445 , 21 , 513 , 2957 , 2307 , 11451 , 6539 ,0 }; - static ulong[] dim2052KuoInit = { 1 , 1 , 3 , 11 , 19 , 45 , 7 , 155 , 387 , 287 , 347 , 1557 , 7407 , 10885 , 31829 ,0 }; - static ulong[] dim2053KuoInit = { 1 , 3 , 5 , 13 , 9 , 53 , 61 , 99 , 355 , 449 , 1353 , 3135 , 2329 , 733 , 22443 ,0 }; - static ulong[] dim2054KuoInit = { 1 , 1 , 3 , 5 , 27 , 47 , 43 , 217 , 113 , 385 , 903 , 3015 , 4169 , 10705 , 11351 ,0 }; - static ulong[] dim2055KuoInit = { 1 , 3 , 7 , 11 , 9 , 33 , 7 , 167 , 473 , 465 , 357 , 2387 , 2901 , 12995 , 16871 ,0 }; - static ulong[] dim2056KuoInit = { 1 , 3 , 7 , 3 , 29 , 35 , 85 , 201 , 311 , 581 , 491 , 2977 , 7433 , 14615 , 29995 ,0 }; - static ulong[] dim2057KuoInit = { 1 , 3 , 1 , 15 , 5 , 5 , 121 , 17 , 93 , 847 , 835 , 3885 , 2437 , 2237 , 15669 ,0 }; - static ulong[] dim2058KuoInit = { 1 , 3 , 7 , 5 , 29 , 39 , 57 , 241 , 247 , 847 , 311 , 3115 , 7605 , 3117 , 30677 ,0 }; - static ulong[] dim2059KuoInit = { 1 , 3 , 1 , 13 , 21 , 27 , 123 , 77 , 511 , 319 , 1699 , 709 , 7021 , 14377 , 9601 ,0 }; - static ulong[] dim2060KuoInit = { 1 , 3 , 3 , 5 , 31 , 1 , 49 , 249 , 271 , 595 , 1069 , 2307 , 567 , 13145 , 8779 ,0 }; - static ulong[] dim2061KuoInit = { 1 , 3 , 3 , 3 , 29 , 25 , 55 , 63 , 289 , 617 , 1209 , 3949 , 481 , 13495 , 16659 ,0 }; - static ulong[] dim2062KuoInit = { 1 , 3 , 3 , 3 , 5 , 19 , 47 , 125 , 323 , 917 , 1875 , 1683 , 7451 , 16145 , 3029 ,0 }; - static ulong[] dim2063KuoInit = { 1 , 1 , 7 , 5 , 27 , 33 , 3 , 133 , 477 , 457 , 803 , 1141 , 3965 , 9127 , 21173 ,0 }; - static ulong[] dim2064KuoInit = { 1 , 3 , 5 , 7 , 19 , 61 , 17 , 27 , 297 , 995 , 1119 , 2555 , 6741 , 3233 , 13735 ,0 }; - static ulong[] dim2065KuoInit = { 1 , 3 , 7 , 11 , 11 , 21 , 21 , 143 , 319 , 143 , 675 , 187 , 6909 , 7145 , 27029 ,0 }; - static ulong[] dim2066KuoInit = { 1 , 3 , 3 , 1 , 29 , 5 , 1 , 65 , 123 , 801 , 933 , 3105 , 1163 , 15703 , 9567 ,0 }; - static ulong[] dim2067KuoInit = { 1 , 1 , 3 , 11 , 3 , 15 , 11 , 109 , 117 , 1011 , 1407 , 3287 , 5799 , 147 , 32641 ,0 }; - static ulong[] dim2068KuoInit = { 1 , 1 , 1 , 5 , 29 , 25 , 63 , 39 , 139 , 379 , 1887 , 417 , 2965 , 4409 , 19149 ,0 }; - static ulong[] dim2069KuoInit = { 1 , 1 , 1 , 13 , 31 , 25 , 123 , 187 , 311 , 397 , 1467 , 15 , 4253 , 14565 , 32609 ,0 }; - static ulong[] dim2070KuoInit = { 1 , 3 , 5 , 7 , 25 , 5 , 13 , 25 , 489 , 837 , 865 , 527 , 4965 , 2567 , 13505 ,0 }; - static ulong[] dim2071KuoInit = { 1 , 1 , 3 , 9 , 3 , 15 , 59 , 115 , 339 , 459 , 2011 , 3311 , 4067 , 3437 , 21435 ,0 }; - static ulong[] dim2072KuoInit = { 1 , 1 , 5 , 3 , 17 , 35 , 49 , 11 , 217 , 401 , 385 , 569 , 1727 , 9927 , 27229 ,0 }; - static ulong[] dim2073KuoInit = { 1 , 3 , 1 , 5 , 27 , 43 , 21 , 11 , 459 , 555 , 237 , 87 , 7531 , 16117 , 23625 ,0 }; - static ulong[] dim2074KuoInit = { 1 , 3 , 3 , 5 , 15 , 57 , 93 , 35 , 31 , 257 , 77 , 3437 , 3665 , 3137 , 2477 ,0 }; - static ulong[] dim2075KuoInit = { 1 , 3 , 5 , 9 , 1 , 43 , 91 , 55 , 53 , 265 , 1495 , 551 , 4729 , 7839 , 23475 ,0 }; - static ulong[] dim2076KuoInit = { 1 , 1 , 7 , 11 , 11 , 45 , 9 , 27 , 485 , 397 , 925 , 3601 , 4419 , 4563 , 6443 ,0 }; - static ulong[] dim2077KuoInit = { 1 , 3 , 5 , 3 , 15 , 35 , 103 , 239 , 193 , 831 , 559 , 1299 , 4939 , 8051 , 6899 ,0 }; - static ulong[] dim2078KuoInit = { 1 , 3 , 3 , 11 , 17 , 47 , 77 , 13 , 227 , 935 , 1973 , 1789 , 4357 , 5135 , 27643 ,0 }; - static ulong[] dim2079KuoInit = { 1 , 1 , 3 , 7 , 11 , 51 , 109 , 143 , 101 , 131 , 565 , 3503 , 5649 , 10007 , 6283 ,0 }; - static ulong[] dim2080KuoInit = { 1 , 1 , 3 , 15 , 19 , 5 , 15 , 241 , 399 , 341 , 943 , 587 , 4757 , 13941 , 7571 ,0 }; - static ulong[] dim2081KuoInit = { 1 , 3 , 3 , 3 , 21 , 9 , 119 , 119 , 445 , 349 , 1517 , 17 , 3593 , 11983 , 9713 ,0 }; - static ulong[] dim2082KuoInit = { 1 , 1 , 3 , 3 , 23 , 55 , 21 , 251 , 191 , 585 , 1619 , 431 , 4161 , 5667 , 17703 ,0 }; - static ulong[] dim2083KuoInit = { 1 , 3 , 3 , 3 , 1 , 57 , 65 , 231 , 67 , 531 , 1403 , 3883 , 4463 , 12795 , 4427 ,0 }; - static ulong[] dim2084KuoInit = { 1 , 1 , 5 , 15 , 19 , 7 , 9 , 163 , 487 , 455 , 1663 , 3141 , 5975 , 11001 , 24781 ,0 }; - static ulong[] dim2085KuoInit = { 1 , 1 , 5 , 1 , 29 , 19 , 45 , 235 , 371 , 935 , 1757 , 187 , 7729 , 6241 , 27171 ,0 }; - static ulong[] dim2086KuoInit = { 1 , 1 , 1 , 1 , 15 , 39 , 39 , 171 , 145 , 413 , 1545 , 3733 , 1815 , 9443 , 32705 ,0 }; - static ulong[] dim2087KuoInit = { 1 , 1 , 3 , 9 , 31 , 1 , 87 , 11 , 219 , 913 , 131 , 3625 , 7927 , 9945 , 2595 ,0 }; - static ulong[] dim2088KuoInit = { 1 , 3 , 3 , 13 , 21 , 15 , 39 , 29 , 267 , 275 , 973 , 701 , 1057 , 13641 , 22149 ,0 }; - static ulong[] dim2089KuoInit = { 1 , 3 , 3 , 5 , 3 , 33 , 81 , 29 , 85 , 515 , 1719 , 3967 , 5145 , 12921 , 8303 ,0 }; - static ulong[] dim2090KuoInit = { 1 , 3 , 7 , 11 , 17 , 23 , 113 , 129 , 395 , 153 , 427 , 1113 , 8157 , 9087 , 20471 ,0 }; - static ulong[] dim2091KuoInit = { 1 , 1 , 5 , 9 , 23 , 5 , 119 , 67 , 215 , 581 , 1249 , 3949 , 731 , 10387 , 27979 ,0 }; - static ulong[] dim2092KuoInit = { 1 , 1 , 5 , 5 , 5 , 53 , 7 , 39 , 51 , 519 , 225 , 119 , 4335 , 11723 , 27971 ,0 }; - static ulong[] dim2093KuoInit = { 1 , 3 , 5 , 3 , 5 , 49 , 105 , 29 , 443 , 457 , 191 , 2679 , 5803 , 12017 , 2205 ,0 }; - static ulong[] dim2094KuoInit = { 1 , 1 , 3 , 1 , 23 , 31 , 11 , 199 , 479 , 231 , 431 , 1989 , 705 , 6557 , 27763 ,0 }; - static ulong[] dim2095KuoInit = { 1 , 1 , 3 , 1 , 27 , 9 , 39 , 105 , 149 , 1017 , 79 , 1575 , 6365 , 839 , 27601 ,0 }; - static ulong[] dim2096KuoInit = { 1 , 1 , 3 , 7 , 1 , 29 , 61 , 129 , 253 , 541 , 1953 , 351 , 2895 , 14385 , 23685 ,0 }; - static ulong[] dim2097KuoInit = { 1 , 3 , 1 , 7 , 19 , 15 , 55 , 133 , 195 , 881 , 311 , 2021 , 7935 , 4513 , 31065 ,0 }; - static ulong[] dim2098KuoInit = { 1 , 1 , 5 , 13 , 23 , 55 , 53 , 169 , 79 , 707 , 1415 , 3999 , 299 , 6689 , 10219 ,0 }; - static ulong[] dim2099KuoInit = { 1 , 3 , 3 , 7 , 7 , 47 , 77 , 209 , 467 , 39 , 291 , 3769 , 1295 , 12407 , 2205 ,0 }; - static ulong[] dim2100KuoInit = { 1 , 1 , 3 , 9 , 13 , 3 , 63 , 241 , 251 , 939 , 1391 , 2053 , 719 , 13739 , 12167 ,0 }; - static ulong[] dim2101KuoInit = { 1 , 1 , 7 , 9 , 21 , 31 , 37 , 11 , 187 , 201 , 1425 , 249 , 2475 , 12421 , 14443 ,0 }; - static ulong[] dim2102KuoInit = { 1 , 1 , 3 , 9 , 31 , 51 , 53 , 119 , 19 , 13 , 1513 , 1115 , 1265 , 15707 , 22795 ,0 }; - static ulong[] dim2103KuoInit = { 1 , 3 , 5 , 9 , 23 , 13 , 69 , 247 , 103 , 773 , 997 , 703 , 2921 , 3165 , 3027 ,0 }; - static ulong[] dim2104KuoInit = { 1 , 3 , 7 , 7 , 15 , 27 , 81 , 221 , 259 , 405 , 391 , 2635 , 1747 , 7743 , 28833 ,0 }; - static ulong[] dim2105KuoInit = { 1 , 1 , 3 , 9 , 29 , 47 , 23 , 127 , 49 , 81 , 543 , 919 , 5517 , 9573 , 1523 ,0 }; - static ulong[] dim2106KuoInit = { 1 , 3 , 3 , 9 , 11 , 37 , 123 , 199 , 343 , 697 , 293 , 3123 , 4601 , 14209 , 30425 ,0 }; - static ulong[] dim2107KuoInit = { 1 , 1 , 5 , 7 , 3 , 31 , 127 , 13 , 191 , 509 , 1999 , 3379 , 2365 , 10307 , 26693 ,0 }; - static ulong[] dim2108KuoInit = { 1 , 3 , 7 , 3 , 3 , 41 , 71 , 153 , 119 , 9 , 1601 , 3839 , 369 , 16241 , 19115 ,0 }; - static ulong[] dim2109KuoInit = { 1 , 1 , 5 , 5 , 3 , 17 , 7 , 65 , 191 , 143 , 127 , 1973 , 6885 , 13615 , 26289 ,0 }; - static ulong[] dim2110KuoInit = { 1 , 1 , 3 , 5 , 13 , 5 , 87 , 17 , 445 , 975 , 1527 , 253 , 5983 , 7095 , 21271 ,0 }; - static ulong[] dim2111KuoInit = { 1 , 3 , 1 , 3 , 7 , 49 , 29 , 19 , 37 , 695 , 603 , 3153 , 4065 , 5421 , 3285 ,0 }; - static ulong[] dim2112KuoInit = { 1 , 1 , 5 , 13 , 25 , 47 , 43 , 35 , 205 , 629 , 1255 , 2843 , 7533 , 751 , 10119 ,0 }; - static ulong[] dim2113KuoInit = { 1 , 3 , 1 , 11 , 13 , 27 , 127 , 221 , 67 , 523 , 217 , 1493 , 1793 , 10871 , 14289 ,0 }; - static ulong[] dim2114KuoInit = { 1 , 1 , 1 , 5 , 21 , 47 , 45 , 73 , 479 , 653 , 1553 , 695 , 3131 , 8773 , 20303 ,0 }; - static ulong[] dim2115KuoInit = { 1 , 3 , 1 , 1 , 19 , 31 , 25 , 207 , 361 , 961 , 1595 , 1807 , 3649 , 1029 , 31579 ,0 }; - static ulong[] dim2116KuoInit = { 1 , 1 , 1 , 1 , 27 , 23 , 109 , 111 , 477 , 233 , 1305 , 51 , 4517 , 14867 , 4075 ,0 }; - static ulong[] dim2117KuoInit = { 1 , 1 , 7 , 11 , 21 , 5 , 51 , 9 , 131 , 671 , 191 , 4045 , 7773 , 5037 , 23229 ,0 }; - static ulong[] dim2118KuoInit = { 1 , 1 , 5 , 7 , 3 , 57 , 75 , 141 , 439 , 269 , 99 , 1595 , 3597 , 10183 , 19849 ,0 }; - static ulong[] dim2119KuoInit = { 1 , 1 , 3 , 3 , 17 , 61 , 81 , 75 , 471 , 1023 , 1045 , 849 , 3741 , 12803 , 10735 ,0 }; - static ulong[] dim2120KuoInit = { 1 , 1 , 7 , 11 , 3 , 33 , 79 , 113 , 335 , 245 , 1807 , 1927 , 7381 , 6405 , 20035 ,0 }; - static ulong[] dim2121KuoInit = { 1 , 3 , 1 , 11 , 5 , 37 , 31 , 177 , 233 , 937 , 1655 , 511 , 1109 , 5083 , 31325 ,0 }; - static ulong[] dim2122KuoInit = { 1 , 3 , 5 , 15 , 15 , 35 , 125 , 105 , 313 , 553 , 259 , 1433 , 327 , 2079 , 5279 ,0 }; - static ulong[] dim2123KuoInit = { 1 , 3 , 1 , 1 , 25 , 57 , 121 , 189 , 409 , 459 , 749 , 3159 , 6389 , 4141 , 16463 ,0 }; - static ulong[] dim2124KuoInit = { 1 , 1 , 7 , 15 , 7 , 21 , 113 , 139 , 241 , 617 , 1385 , 1387 , 145 , 6605 , 2057 ,0 }; - static ulong[] dim2125KuoInit = { 1 , 3 , 3 , 11 , 17 , 33 , 89 , 17 , 341 , 369 , 719 , 2481 , 7589 , 16283 , 28157 ,0 }; - static ulong[] dim2126KuoInit = { 1 , 3 , 7 , 1 , 11 , 17 , 31 , 135 , 333 , 335 , 197 , 2401 , 7637 , 703 , 3001 ,0 }; - static ulong[] dim2127KuoInit = { 1 , 3 , 5 , 11 , 17 , 31 , 33 , 249 , 315 , 475 , 1743 , 2429 , 4923 , 2779 , 25677 ,0 }; - static ulong[] dim2128KuoInit = { 1 , 1 , 5 , 5 , 11 , 29 , 111 , 103 , 143 , 779 , 1437 , 3759 , 5827 , 3129 , 26961 ,0 }; - static ulong[] dim2129KuoInit = { 1 , 3 , 5 , 3 , 25 , 1 , 109 , 117 , 159 , 53 , 1291 , 1787 , 7851 , 14363 , 15271 ,0 }; - static ulong[] dim2130KuoInit = { 1 , 1 , 1 , 9 , 9 , 1 , 31 , 131 , 163 , 723 , 1023 , 27 , 853 , 2623 , 16859 ,0 }; - static ulong[] dim2131KuoInit = { 1 , 1 , 3 , 11 , 23 , 13 , 91 , 87 , 141 , 111 , 1677 , 1483 , 1461 , 15981 , 29417 ,0 }; - static ulong[] dim2132KuoInit = { 1 , 3 , 7 , 9 , 17 , 17 , 115 , 43 , 397 , 683 , 2017 , 985 , 3703 , 16135 , 3661 ,0 }; - static ulong[] dim2133KuoInit = { 1 , 1 , 7 , 13 , 17 , 45 , 71 , 149 , 317 , 559 , 279 , 2441 , 2323 , 16071 , 29709 ,0 }; - static ulong[] dim2134KuoInit = { 1 , 3 , 5 , 11 , 31 , 33 , 105 , 127 , 375 , 1001 , 115 , 1429 , 7003 , 13369 , 23281 ,0 }; - static ulong[] dim2135KuoInit = { 1 , 1 , 5 , 7 , 21 , 7 , 27 , 105 , 99 , 479 , 849 , 1361 , 4935 , 14831 , 29 ,0 }; - static ulong[] dim2136KuoInit = { 1 , 3 , 7 , 9 , 15 , 53 , 63 , 109 , 171 , 323 , 289 , 2937 , 3177 , 4615 , 10711 ,0 }; - static ulong[] dim2137KuoInit = { 1 , 1 , 1 , 1 , 27 , 41 , 29 , 101 , 209 , 673 , 1597 , 3743 , 827 , 4025 , 27267 ,0 }; - static ulong[] dim2138KuoInit = { 1 , 3 , 7 , 13 , 25 , 17 , 19 , 219 , 233 , 769 , 909 , 3585 , 55 , 13349 , 13685 ,0 }; - static ulong[] dim2139KuoInit = { 1 , 1 , 1 , 15 , 17 , 57 , 63 , 181 , 339 , 319 , 655 , 699 , 1633 , 8181 , 23039 ,0 }; - static ulong[] dim2140KuoInit = { 1 , 1 , 3 , 1 , 25 , 11 , 61 , 195 , 311 , 723 , 365 , 2791 , 1281 , 9113 , 26741 ,0 }; - static ulong[] dim2141KuoInit = { 1 , 1 , 7 , 11 , 19 , 43 , 65 , 37 , 89 , 847 , 951 , 851 , 4441 , 6681 , 917 ,0 }; - static ulong[] dim2142KuoInit = { 1 , 3 , 5 , 13 , 1 , 11 , 55 , 29 , 419 , 769 , 815 , 1487 , 2151 , 7981 , 19509 ,0 }; - static ulong[] dim2143KuoInit = { 1 , 1 , 5 , 13 , 11 , 55 , 127 , 19 , 419 , 679 , 119 , 1417 , 1717 , 5849 , 6365 ,0 }; - static ulong[] dim2144KuoInit = { 1 , 1 , 7 , 5 , 29 , 5 , 9 , 241 , 405 , 253 , 1015 , 2027 , 7695 , 12003 , 659 ,0 }; - static ulong[] dim2145KuoInit = { 1 , 3 , 7 , 5 , 27 , 63 , 87 , 221 , 219 , 355 , 941 , 3901 , 6535 , 4715 , 3571 ,0 }; - static ulong[] dim2146KuoInit = { 1 , 3 , 3 , 9 , 13 , 1 , 113 , 21 , 71 , 353 , 1063 , 1447 , 2157 , 5195 , 21311 ,0 }; - static ulong[] dim2147KuoInit = { 1 , 1 , 3 , 15 , 29 , 1 , 7 , 223 , 43 , 605 , 1063 , 67 , 2529 , 1125 , 16933 ,0 }; - static ulong[] dim2148KuoInit = { 1 , 3 , 1 , 15 , 29 , 37 , 51 , 239 , 117 , 351 , 1953 , 1933 , 6371 , 13467 , 8265 ,0 }; - static ulong[] dim2149KuoInit = { 1 , 1 , 3 , 5 , 7 , 25 , 19 , 221 , 409 , 121 , 89 , 219 , 105 , 4213 , 1903 ,0 }; - static ulong[] dim2150KuoInit = { 1 , 3 , 7 , 1 , 13 , 3 , 79 , 123 , 423 , 589 , 1085 , 3387 , 6117 , 8749 , 8947 ,0 }; - static ulong[] dim2151KuoInit = { 1 , 3 , 7 , 9 , 21 , 49 , 1 , 39 , 461 , 115 , 1131 , 719 , 3709 , 1495 , 23871 ,0 }; - static ulong[] dim2152KuoInit = { 1 , 1 , 7 , 5 , 23 , 41 , 107 , 225 , 499 , 721 , 1977 , 2063 , 1825 , 9589 , 22137 ,0 }; - static ulong[] dim2153KuoInit = { 1 , 1 , 5 , 7 , 15 , 53 , 33 , 145 , 179 , 109 , 425 , 2729 , 7637 , 6805 , 26223 ,0 }; - static ulong[] dim2154KuoInit = { 1 , 1 , 5 , 13 , 1 , 1 , 31 , 117 , 25 , 427 , 681 , 2991 , 7681 , 15927 , 20913 ,0 }; - static ulong[] dim2155KuoInit = { 1 , 1 , 5 , 13 , 31 , 53 , 23 , 71 , 397 , 661 , 131 , 2815 , 2351 , 15881 , 10321 ,0 }; - static ulong[] dim2156KuoInit = { 1 , 3 , 1 , 15 , 19 , 41 , 39 , 57 , 349 , 761 , 1999 , 1151 , 201 , 1025 , 18821 ,0 }; - static ulong[] dim2157KuoInit = { 1 , 1 , 3 , 3 , 17 , 43 , 73 , 163 , 187 , 913 , 31 , 81 , 4829 , 6993 , 32175 ,0 }; - static ulong[] dim2158KuoInit = { 1 , 3 , 1 , 15 , 19 , 41 , 79 , 13 , 343 , 415 , 863 , 1943 , 2231 , 11353 , 15631 ,0 }; - static ulong[] dim2159KuoInit = { 1 , 3 , 1 , 15 , 29 , 35 , 101 , 23 , 111 , 937 , 833 , 2369 , 3503 , 6605 , 14279 ,0 }; - static ulong[] dim2160KuoInit = { 1 , 3 , 7 , 15 , 27 , 61 , 43 , 211 , 259 , 583 , 1529 , 1013 , 8005 , 7717 , 1085 ,0 }; - static ulong[] dim2161KuoInit = { 1 , 1 , 7 , 15 , 23 , 39 , 17 , 201 , 465 , 289 , 1051 , 33 , 7403 , 7971 , 24905 ,0 }; - static ulong[] dim2162KuoInit = { 1 , 1 , 5 , 13 , 23 , 41 , 5 , 239 , 9 , 23 , 1353 , 2005 , 2513 , 8707 , 3893 ,0 }; - static ulong[] dim2163KuoInit = { 1 , 3 , 1 , 7 , 7 , 41 , 73 , 177 , 351 , 297 , 1057 , 3867 , 2481 , 15751 , 25231 ,0 }; - static ulong[] dim2164KuoInit = { 1 , 1 , 3 , 1 , 17 , 59 , 45 , 171 , 367 , 575 , 1085 , 953 , 3467 , 8435 , 6345 ,0 }; - static ulong[] dim2165KuoInit = { 1 , 3 , 1 , 9 , 5 , 21 , 125 , 137 , 415 , 101 , 121 , 3499 , 6671 , 15541 , 14081 ,0 }; - static ulong[] dim2166KuoInit = { 1 , 3 , 5 , 15 , 15 , 19 , 111 , 235 , 53 , 119 , 1307 , 583 , 1695 , 211 , 5567 ,0 }; - static ulong[] dim2167KuoInit = { 1 , 1 , 5 , 9 , 7 , 13 , 119 , 109 , 273 , 677 , 2001 , 3307 , 7999 , 11769 , 10069 ,0 }; - static ulong[] dim2168KuoInit = { 1 , 1 , 1 , 15 , 11 , 15 , 57 , 233 , 77 , 815 , 31 , 669 , 6365 , 5085 , 13583 ,0 }; - static ulong[] dim2169KuoInit = { 1 , 3 , 7 , 1 , 31 , 9 , 101 , 33 , 13 , 699 , 637 , 1159 , 5101 , 13805 , 32651 ,0 }; - static ulong[] dim2170KuoInit = { 1 , 1 , 7 , 13 , 15 , 9 , 125 , 71 , 241 , 147 , 529 , 1863 , 1551 , 4981 , 30389 ,0 }; - static ulong[] dim2171KuoInit = { 1 , 1 , 7 , 13 , 11 , 35 , 11 , 5 , 473 , 55 , 1589 , 2835 , 3771 , 11433 , 11099 ,0 }; - static ulong[] dim2172KuoInit = { 1 , 1 , 7 , 15 , 11 , 11 , 35 , 207 , 267 , 289 , 999 , 3183 , 3827 , 6617 , 29015 ,0 }; - static ulong[] dim2173KuoInit = { 1 , 1 , 3 , 1 , 3 , 11 , 119 , 223 , 255 , 319 , 1823 , 1301 , 4401 , 12827 , 889 ,0 }; - static ulong[] dim2174KuoInit = { 1 , 3 , 5 , 1 , 1 , 5 , 5 , 109 , 27 , 963 , 727 , 335 , 6295 , 9775 , 32681 ,0 }; - static ulong[] dim2175KuoInit = { 1 , 3 , 7 , 15 , 29 , 47 , 55 , 253 , 281 , 303 , 857 , 903 , 2977 , 14777 , 31689 ,0 }; - static ulong[] dim2176KuoInit = { 1 , 3 , 1 , 7 , 17 , 49 , 105 , 155 , 467 , 467 , 1287 , 1281 , 3429 , 3195 , 15297 ,0 }; - static ulong[] dim2177KuoInit = { 1 , 3 , 1 , 1 , 27 , 31 , 17 , 201 , 23 , 897 , 1991 , 2661 , 645 , 16127 , 30857 ,0 }; - static ulong[] dim2178KuoInit = { 1 , 3 , 3 , 11 , 9 , 15 , 85 , 183 , 31 , 179 , 779 , 171 , 5989 , 7253 , 15077 ,0 }; - static ulong[] dim2179KuoInit = { 1 , 1 , 1 , 5 , 19 , 23 , 37 , 39 , 281 , 707 , 17 , 2707 , 289 , 12081 , 4381 ,0 }; - static ulong[] dim2180KuoInit = { 1 , 1 , 7 , 9 , 21 , 27 , 115 , 179 , 99 , 277 , 331 , 3407 , 2057 , 13893 , 11501 ,0 }; - static ulong[] dim2181KuoInit = { 1 , 3 , 1 , 9 , 31 , 51 , 51 , 25 , 319 , 319 , 27 , 2161 , 89 , 3421 , 18273 ,0 }; - static ulong[] dim2182KuoInit = { 1 , 1 , 7 , 15 , 13 , 21 , 11 , 189 , 63 , 15 , 363 , 1951 , 5751 , 5797 , 22123 ,0 }; - static ulong[] dim2183KuoInit = { 1 , 1 , 3 , 1 , 25 , 47 , 99 , 77 , 77 , 595 , 1473 , 1653 , 6751 , 5005 , 29051 ,0 }; - static ulong[] dim2184KuoInit = { 1 , 1 , 3 , 7 , 25 , 47 , 31 , 13 , 311 , 269 , 1095 , 1359 , 305 , 6811 , 16455 ,0 }; - static ulong[] dim2185KuoInit = { 1 , 1 , 5 , 3 , 13 , 63 , 87 , 13 , 221 , 459 , 1177 , 891 , 5781 , 13803 , 18795 ,0 }; - static ulong[] dim2186KuoInit = { 1 , 1 , 7 , 3 , 23 , 13 , 25 , 115 , 47 , 903 , 1551 , 2887 , 229 , 16067 , 9511 ,0 }; - static ulong[] dim2187KuoInit = { 1 , 1 , 7 , 15 , 23 , 15 , 7 , 65 , 27 , 677 , 1503 , 125 , 7739 , 14655 , 29577 ,0 }; - static ulong[] dim2188KuoInit = { 1 , 1 , 1 , 5 , 9 , 23 , 93 , 187 , 205 , 915 , 599 , 2105 , 7767 , 2411 , 15045 ,0 }; - static ulong[] dim2189KuoInit = { 1 , 3 , 5 , 1 , 21 , 45 , 17 , 57 , 171 , 491 , 1465 , 2013 , 3253 , 5517 , 19113 ,0 }; - static ulong[] dim2190KuoInit = { 1 , 1 , 7 , 5 , 5 , 25 , 87 , 247 , 301 , 385 , 1655 , 1351 , 6307 , 14695 , 29745 ,0 }; - static ulong[] dim2191KuoInit = { 1 , 3 , 7 , 3 , 31 , 25 , 113 , 155 , 123 , 755 , 649 , 1809 , 1703 , 875 , 5235 ,0 }; - static ulong[] dim2192KuoInit = { 1 , 1 , 1 , 7 , 7 , 43 , 121 , 47 , 499 , 63 , 449 , 2039 , 835 , 2883 , 2287 ,0 }; - static ulong[] dim2193KuoInit = { 1 , 3 , 7 , 1 , 9 , 11 , 99 , 169 , 305 , 469 , 157 , 2043 , 4851 , 3367 , 8689 ,0 }; - static ulong[] dim2194KuoInit = { 1 , 1 , 1 , 11 , 17 , 15 , 41 , 209 , 377 , 81 , 335 , 1685 , 143 , 1513 , 28465 ,0 }; - static ulong[] dim2195KuoInit = { 1 , 3 , 1 , 15 , 9 , 45 , 83 , 123 , 347 , 437 , 783 , 3561 , 6003 , 9329 , 4729 ,0 }; - static ulong[] dim2196KuoInit = { 1 , 1 , 1 , 1 , 13 , 33 , 109 , 217 , 403 , 539 , 1393 , 1069 , 235 , 11261 , 13423 ,0 }; - static ulong[] dim2197KuoInit = { 1 , 1 , 5 , 13 , 27 , 1 , 81 , 139 , 421 , 301 , 55 , 1883 , 1525 , 6029 , 1879 ,0 }; - static ulong[] dim2198KuoInit = { 1 , 1 , 1 , 15 , 15 , 55 , 49 , 249 , 487 , 373 , 737 , 2133 , 6883 , 1603 , 27607 ,0 }; - static ulong[] dim2199KuoInit = { 1 , 1 , 1 , 13 , 25 , 17 , 17 , 15 , 119 , 571 , 1053 , 2153 , 5221 , 2681 , 24595 ,0 }; - static ulong[] dim2200KuoInit = { 1 , 3 , 1 , 5 , 3 , 63 , 31 , 9 , 263 , 977 , 575 , 1225 , 4127 , 15649 , 1281 ,0 }; - static ulong[] dim2201KuoInit = { 1 , 1 , 7 , 9 , 19 , 1 , 37 , 109 , 13 , 191 , 1483 , 465 , 1321 , 13697 , 26065 ,0 }; - static ulong[] dim2202KuoInit = { 1 , 1 , 3 , 9 , 17 , 15 , 103 , 97 , 237 , 861 , 1251 , 2069 , 4459 , 9999 , 7369 ,0 }; - static ulong[] dim2203KuoInit = { 1 , 3 , 7 , 9 , 15 , 33 , 55 , 5 , 355 , 519 , 445 , 4033 , 627 , 2375 , 31013 ,0 }; - static ulong[] dim2204KuoInit = { 1 , 1 , 1 , 3 , 23 , 51 , 65 , 177 , 225 , 63 , 987 , 2921 , 823 , 1781 , 22923 ,0 }; - static ulong[] dim2205KuoInit = { 1 , 3 , 5 , 7 , 27 , 33 , 111 , 47 , 465 , 379 , 1575 , 1793 , 513 , 14033 , 27409 ,0 }; - static ulong[] dim2206KuoInit = { 1 , 3 , 5 , 7 , 1 , 57 , 31 , 195 , 393 , 257 , 1489 , 2589 , 5339 , 7487 , 29023 ,0 }; - static ulong[] dim2207KuoInit = { 1 , 3 , 5 , 11 , 15 , 27 , 39 , 89 , 387 , 753 , 1213 , 2417 , 6287 , 129 , 12295 ,0 }; - static ulong[] dim2208KuoInit = { 1 , 1 , 3 , 11 , 11 , 37 , 117 , 55 , 55 , 677 , 1057 , 3971 , 5017 , 12941 , 3001 ,0 }; - static ulong[] dim2209KuoInit = { 1 , 3 , 1 , 7 , 21 , 33 , 103 , 19 , 427 , 637 , 393 , 2245 , 2853 , 15927 , 14633 ,0 }; - static ulong[] dim2210KuoInit = { 1 , 1 , 5 , 7 , 31 , 11 , 75 , 191 , 367 , 659 , 121 , 2947 , 515 , 10625 , 19753 ,0 }; - static ulong[] dim2211KuoInit = { 1 , 1 , 5 , 5 , 15 , 63 , 115 , 119 , 85 , 527 , 875 , 67 , 475 , 2207 , 4101 ,0 }; - static ulong[] dim2212KuoInit = { 1 , 3 , 3 , 9 , 23 , 37 , 53 , 187 , 37 , 535 , 509 , 1765 , 6577 , 13249 , 3875 ,0 }; - static ulong[] dim2213KuoInit = { 1 , 3 , 3 , 5 , 13 , 49 , 23 , 193 , 109 , 295 , 309 , 2457 , 4193 , 9927 , 16313 ,0 }; - static ulong[] dim2214KuoInit = { 1 , 3 , 3 , 5 , 5 , 15 , 33 , 69 , 225 , 231 , 131 , 3135 , 3597 , 2989 , 12365 ,0 }; - static ulong[] dim2215KuoInit = { 1 , 3 , 7 , 1 , 27 , 33 , 9 , 139 , 507 , 789 , 663 , 1693 , 949 , 9149 , 29529 ,0 }; - static ulong[] dim2216KuoInit = { 1 , 1 , 7 , 7 , 11 , 1 , 57 , 159 , 511 , 929 , 1337 , 2181 , 5573 , 425 , 26935 ,0 }; - static ulong[] dim2217KuoInit = { 1 , 1 , 5 , 9 , 15 , 53 , 57 , 81 , 105 , 389 , 1563 , 1 , 669 , 8403 , 15747 ,0 }; - static ulong[] dim2218KuoInit = { 1 , 3 , 3 , 5 , 19 , 21 , 29 , 133 , 203 , 689 , 2011 , 1825 , 3365 , 1957 , 21393 ,0 }; - static ulong[] dim2219KuoInit = { 1 , 1 , 3 , 15 , 7 , 11 , 73 , 189 , 63 , 81 , 1429 , 3403 , 4249 , 16265 , 22423 ,0 }; - static ulong[] dim2220KuoInit = { 1 , 1 , 5 , 1 , 31 , 47 , 75 , 199 , 343 , 957 , 691 , 939 , 2165 , 10523 , 3577 ,0 }; - static ulong[] dim2221KuoInit = { 1 , 1 , 7 , 13 , 3 , 27 , 5 , 131 , 437 , 405 , 1809 , 2637 , 5735 , 12897 , 22905 ,0 }; - static ulong[] dim2222KuoInit = { 1 , 1 , 5 , 1 , 17 , 17 , 85 , 161 , 205 , 81 , 1125 , 1783 , 2241 , 6321 , 10891 ,0 }; - static ulong[] dim2223KuoInit = { 1 , 3 , 7 , 15 , 27 , 7 , 119 , 61 , 383 , 171 , 1495 , 1237 , 729 , 1977 , 11779 ,0 }; - static ulong[] dim2224KuoInit = { 1 , 1 , 5 , 7 , 21 , 3 , 63 , 167 , 493 , 117 , 855 , 143 , 2579 , 7527 , 7395 ,0 }; - static ulong[] dim2225KuoInit = { 1 , 1 , 1 , 9 , 31 , 61 , 15 , 31 , 445 , 397 , 1369 , 1047 , 4751 , 10375 , 30319 ,0 }; - static ulong[] dim2226KuoInit = { 1 , 3 , 1 , 15 , 7 , 13 , 87 , 99 , 333 , 433 , 287 , 2861 , 2085 , 14691 , 14801 ,0 }; - static ulong[] dim2227KuoInit = { 1 , 3 , 3 , 7 , 27 , 45 , 41 , 69 , 391 , 259 , 899 , 1019 , 2999 , 6487 , 19831 ,0 }; - static ulong[] dim2228KuoInit = { 1 , 3 , 5 , 11 , 19 , 33 , 49 , 87 , 89 , 649 , 1209 , 43 , 8035 , 12687 , 24783 ,0 }; - static ulong[] dim2229KuoInit = { 1 , 3 , 1 , 9 , 13 , 11 , 55 , 5 , 315 , 347 , 1361 , 41 , 807 , 11551 , 499 ,0 }; - static ulong[] dim2230KuoInit = { 1 , 1 , 7 , 1 , 25 , 15 , 11 , 19 , 233 , 269 , 135 , 2577 , 4385 , 8109 , 13161 ,0 }; - static ulong[] dim2231KuoInit = { 1 , 3 , 1 , 9 , 19 , 13 , 127 , 79 , 49 , 525 , 1499 , 1209 , 3747 , 8311 , 15061 ,0 }; - static ulong[] dim2232KuoInit = { 1 , 3 , 1 , 15 , 9 , 47 , 59 , 81 , 491 , 401 , 1691 , 543 , 7129 , 13617 , 17031 ,0 }; - static ulong[] dim2233KuoInit = { 1 , 3 , 3 , 5 , 15 , 51 , 41 , 85 , 245 , 91 , 1293 , 2041 , 7205 , 12709 , 17421 ,0 }; - static ulong[] dim2234KuoInit = { 1 , 3 , 1 , 5 , 3 , 19 , 29 , 149 , 51 , 133 , 953 , 2385 , 7471 , 14829 , 8197 ,0 }; - static ulong[] dim2235KuoInit = { 1 , 3 , 1 , 11 , 31 , 15 , 5 , 139 , 299 , 595 , 1585 , 2115 , 5647 , 12125 , 1265 ,0 }; - static ulong[] dim2236KuoInit = { 1 , 3 , 7 , 9 , 7 , 5 , 93 , 187 , 307 , 329 , 671 , 3983 , 817 , 3965 , 21561 ,0 }; - static ulong[] dim2237KuoInit = { 1 , 3 , 7 , 1 , 21 , 57 , 67 , 159 , 467 , 65 , 1365 , 2797 , 7051 , 12603 , 10429 ,0 }; - static ulong[] dim2238KuoInit = { 1 , 3 , 1 , 7 , 27 , 59 , 113 , 199 , 13 , 393 , 1605 , 3215 , 5233 , 12749 , 32365 ,0 }; - static ulong[] dim2239KuoInit = { 1 , 3 , 1 , 1 , 1 , 13 , 15 , 217 , 317 , 945 , 1713 , 1951 , 5585 , 1529 , 4969 ,0 }; - static ulong[] dim2240KuoInit = { 1 , 1 , 7 , 15 , 3 , 59 , 23 , 255 , 71 , 539 , 21 , 2603 , 5145 , 295 , 2681 ,0 }; - static ulong[] dim2241KuoInit = { 1 , 1 , 1 , 13 , 11 , 41 , 85 , 145 , 209 , 1001 , 659 , 951 , 4039 , 1409 , 4059 ,0 }; - static ulong[] dim2242KuoInit = { 1 , 1 , 7 , 13 , 15 , 41 , 15 , 121 , 485 , 515 , 325 , 3673 , 2883 , 8119 , 29183 ,0 }; - static ulong[] dim2243KuoInit = { 1 , 3 , 3 , 13 , 21 , 39 , 31 , 163 , 13 , 219 , 411 , 2061 , 1999 , 2999 , 24835 ,0 }; - static ulong[] dim2244KuoInit = { 1 , 3 , 7 , 7 , 21 , 49 , 9 , 75 , 401 , 339 , 191 , 2679 , 7483 , 1361 , 21399 ,0 }; - static ulong[] dim2245KuoInit = { 1 , 3 , 1 , 13 , 5 , 29 , 9 , 77 , 459 , 247 , 1777 , 3873 , 6747 , 7541 , 12015 ,0 }; - static ulong[] dim2246KuoInit = { 1 , 1 , 5 , 9 , 23 , 27 , 55 , 51 , 389 , 63 , 1163 , 255 , 6049 , 1737 , 12403 ,0 }; - static ulong[] dim2247KuoInit = { 1 , 1 , 7 , 3 , 23 , 25 , 81 , 247 , 261 , 445 , 1297 , 1945 , 2769 , 1287 , 24403 ,0 }; - static ulong[] dim2248KuoInit = { 1 , 1 , 5 , 15 , 19 , 13 , 127 , 105 , 475 , 859 , 683 , 941 , 2911 , 14571 , 22769 ,0 }; - static ulong[] dim2249KuoInit = { 1 , 1 , 1 , 13 , 31 , 25 , 55 , 63 , 355 , 525 , 397 , 3213 , 2267 , 2731 , 32145 ,0 }; - static ulong[] dim2250KuoInit = { 1 , 1 , 5 , 15 , 3 , 21 , 45 , 229 , 83 , 661 , 149 , 1615 , 5309 , 12233 , 23101 ,0 }; - static ulong[] dim2251KuoInit = { 1 , 1 , 7 , 1 , 15 , 41 , 91 , 17 , 119 , 65 , 1921 , 97 , 6521 , 8969 , 5419 ,0 }; - static ulong[] dim2252KuoInit = { 1 , 1 , 7 , 11 , 31 , 35 , 73 , 123 , 331 , 83 , 125 , 3001 , 5485 , 1693 , 24327 ,0 }; - static ulong[] dim2253KuoInit = { 1 , 3 , 5 , 15 , 29 , 37 , 63 , 229 , 143 , 529 , 961 , 2845 , 8003 , 7741 , 23393 ,0 }; - static ulong[] dim2254KuoInit = { 1 , 3 , 1 , 15 , 25 , 27 , 91 , 171 , 361 , 575 , 1977 , 2141 , 89 , 7097 , 8115 ,0 }; - static ulong[] dim2255KuoInit = { 1 , 3 , 7 , 15 , 13 , 7 , 51 , 253 , 17 , 991 , 595 , 1819 , 7091 , 8619 , 1147 ,0 }; - static ulong[] dim2256KuoInit = { 1 , 3 , 3 , 7 , 13 , 31 , 41 , 11 , 57 , 185 , 1353 , 907 , 6585 , 8597 , 10239 ,0 }; - static ulong[] dim2257KuoInit = { 1 , 3 , 1 , 11 , 31 , 1 , 119 , 165 , 105 , 725 , 493 , 3279 , 7117 , 15141 , 5957 ,0 }; - static ulong[] dim2258KuoInit = { 1 , 3 , 3 , 13 , 29 , 1 , 35 , 95 , 477 , 847 , 733 , 2599 , 581 , 6487 , 10879 ,0 }; - static ulong[] dim2259KuoInit = { 1 , 3 , 7 , 3 , 15 , 23 , 115 , 177 , 409 , 711 , 1179 , 685 , 4071 , 15129 , 2951 ,0 }; - static ulong[] dim2260KuoInit = { 1 , 1 , 3 , 11 , 19 , 5 , 69 , 33 , 41 , 501 , 135 , 1063 , 4857 , 15537 , 29247 ,0 }; - static ulong[] dim2261KuoInit = { 1 , 3 , 5 , 13 , 1 , 25 , 123 , 1 , 431 , 399 , 483 , 3159 , 7359 , 6169 , 22525 ,0 }; - static ulong[] dim2262KuoInit = { 1 , 3 , 5 , 7 , 1 , 9 , 125 , 131 , 99 , 911 , 421 , 1403 , 993 , 14155 , 20863 ,0 }; - static ulong[] dim2263KuoInit = { 1 , 3 , 1 , 3 , 1 , 43 , 93 , 9 , 345 , 483 , 1809 , 2379 , 653 , 14851 , 20619 ,0 }; - static ulong[] dim2264KuoInit = { 1 , 3 , 7 , 5 , 15 , 37 , 33 , 185 , 173 , 397 , 2021 , 613 , 37 , 7185 , 15399 ,0 }; - static ulong[] dim2265KuoInit = { 1 , 3 , 5 , 5 , 17 , 55 , 119 , 207 , 301 , 461 , 1853 , 2471 , 3611 , 1149 , 3321 ,0 }; - static ulong[] dim2266KuoInit = { 1 , 3 , 3 , 3 , 25 , 57 , 51 , 135 , 337 , 935 , 619 , 1165 , 1613 , 8711 , 2329 ,0 }; - static ulong[] dim2267KuoInit = { 1 , 3 , 1 , 15 , 27 , 25 , 63 , 127 , 169 , 221 , 1103 , 1087 , 1729 , 3967 , 6323 ,0 }; - static ulong[] dim2268KuoInit = { 1 , 1 , 3 , 11 , 13 , 29 , 105 , 189 , 321 , 103 , 2047 , 923 , 4443 , 2175 , 12411 ,0 }; - static ulong[] dim2269KuoInit = { 1 , 1 , 7 , 9 , 7 , 3 , 3 , 61 , 479 , 533 , 227 , 3137 , 6065 , 3621 , 3583 ,0 }; - static ulong[] dim2270KuoInit = { 1 , 1 , 5 , 13 , 11 , 31 , 23 , 147 , 67 , 823 , 663 , 3717 , 6747 , 10935 , 21931 ,0 }; - static ulong[] dim2271KuoInit = { 1 , 1 , 5 , 13 , 29 , 9 , 75 , 31 , 349 , 603 , 1071 , 1767 , 1811 , 15921 , 25681 ,0 }; - static ulong[] dim2272KuoInit = { 1 , 3 , 7 , 13 , 29 , 31 , 57 , 15 , 405 , 263 , 715 , 445 , 1825 , 15057 , 3449 ,0 }; - static ulong[] dim2273KuoInit = { 1 , 3 , 5 , 5 , 5 , 21 , 61 , 137 , 15 , 935 , 897 , 125 , 6651 , 6813 , 27863 ,0 }; - static ulong[] dim2274KuoInit = { 1 , 1 , 3 , 13 , 9 , 53 , 5 , 91 , 93 , 179 , 489 , 3615 , 5911 , 7501 , 14205 ,0 }; - static ulong[] dim2275KuoInit = { 1 , 1 , 5 , 13 , 27 , 49 , 35 , 93 , 371 , 519 , 589 , 1563 , 2609 , 14055 , 28071 ,0 }; - static ulong[] dim2276KuoInit = { 1 , 1 , 5 , 7 , 29 , 41 , 23 , 135 , 491 , 745 , 1327 , 4065 , 6327 , 6375 , 24901 ,0 }; - static ulong[] dim2277KuoInit = { 1 , 3 , 3 , 5 , 23 , 47 , 113 , 85 , 453 , 321 , 597 , 1817 , 7579 , 11633 , 25569 ,0 }; - static ulong[] dim2278KuoInit = { 1 , 3 , 1 , 13 , 13 , 55 , 127 , 47 , 159 , 885 , 235 , 199 , 3133 , 9793 , 25877 ,0 }; - static ulong[] dim2279KuoInit = { 1 , 1 , 3 , 9 , 17 , 21 , 27 , 237 , 413 , 999 , 451 , 3279 , 1607 , 9625 , 16943 ,0 }; - static ulong[] dim2280KuoInit = { 1 , 3 , 1 , 1 , 21 , 61 , 29 , 143 , 33 , 235 , 1591 , 2379 , 3573 , 1399 , 16215 ,0 }; - static ulong[] dim2281KuoInit = { 1 , 1 , 7 , 1 , 29 , 23 , 95 , 207 , 87 , 199 , 1389 , 3587 , 71 , 14401 , 28431 ,0 }; - static ulong[] dim2282KuoInit = { 1 , 1 , 5 , 13 , 23 , 43 , 109 , 119 , 151 , 451 , 23 , 2709 , 3125 , 11541 , 3923 ,0 }; - static ulong[] dim2283KuoInit = { 1 , 3 , 7 , 3 , 11 , 55 , 5 , 227 , 171 , 465 , 1685 , 333 , 2605 , 15055 , 8333 ,0 }; - static ulong[] dim2284KuoInit = { 1 , 3 , 5 , 3 , 21 , 11 , 57 , 37 , 67 , 667 , 521 , 2961 , 6145 , 12527 , 17433 ,0 }; - static ulong[] dim2285KuoInit = { 1 , 1 , 7 , 11 , 9 , 39 , 103 , 83 , 313 , 827 , 721 , 2965 , 3231 , 10121 , 19991 ,0 }; - static ulong[] dim2286KuoInit = { 1 , 1 , 5 , 7 , 23 , 9 , 31 , 39 , 7 , 767 , 153 , 2969 , 5539 , 6581 , 30515 ,0 }; - static ulong[] dim2287KuoInit = { 1 , 1 , 3 , 13 , 3 , 43 , 49 , 143 , 3 , 227 , 99 , 597 , 7207 , 4737 , 2259 ,0 }; - static ulong[] dim2288KuoInit = { 1 , 3 , 3 , 3 , 3 , 57 , 69 , 243 , 199 , 803 , 657 , 1209 , 1343 , 11673 , 21543 ,0 }; - static ulong[] dim2289KuoInit = { 1 , 1 , 1 , 1 , 17 , 27 , 127 , 107 , 171 , 391 , 1737 , 1247 , 1389 , 14387 , 1671 ,0 }; - static ulong[] dim2290KuoInit = { 1 , 3 , 3 , 9 , 23 , 47 , 97 , 139 , 435 , 943 , 1111 , 2723 , 1021 , 1155 , 10241 ,0 }; - static ulong[] dim2291KuoInit = { 1 , 3 , 3 , 13 , 15 , 15 , 101 , 205 , 229 , 639 , 1077 , 1613 , 3035 , 12897 , 14303 ,0 }; - static ulong[] dim2292KuoInit = { 1 , 1 , 1 , 9 , 17 , 43 , 3 , 81 , 149 , 931 , 731 , 4005 , 7397 , 8707 , 27927 ,0 }; - static ulong[] dim2293KuoInit = { 1 , 3 , 7 , 15 , 19 , 59 , 97 , 97 , 347 , 489 , 1577 , 3927 , 3431 , 4051 , 8489 ,0 }; - static ulong[] dim2294KuoInit = { 1 , 1 , 5 , 3 , 29 , 49 , 19 , 151 , 27 , 701 , 541 , 481 , 101 , 10701 , 31909 ,0 }; - static ulong[] dim2295KuoInit = { 1 , 1 , 1 , 9 , 11 , 47 , 59 , 45 , 439 , 757 , 1579 , 1681 , 6701 , 11707 , 10715 ,0 }; - static ulong[] dim2296KuoInit = { 1 , 3 , 3 , 11 , 27 , 55 , 1 , 35 , 491 , 767 , 1247 , 1143 , 5079 , 8029 , 10267 ,0 }; - static ulong[] dim2297KuoInit = { 1 , 3 , 3 , 1 , 15 , 5 , 53 , 215 , 249 , 659 , 329 , 1959 , 249 , 11775 , 4815 ,0 }; - static ulong[] dim2298KuoInit = { 1 , 3 , 7 , 15 , 19 , 17 , 41 , 29 , 157 , 995 , 235 , 1397 , 3983 , 11739 , 7523 ,0 }; - static ulong[] dim2299KuoInit = { 1 , 3 , 5 , 5 , 13 , 3 , 55 , 211 , 59 , 717 , 1389 , 3219 , 2279 , 9583 , 16981 ,0 }; - static ulong[] dim2300KuoInit = { 1 , 3 , 5 , 11 , 31 , 41 , 95 , 217 , 375 , 255 , 1433 , 1595 , 5795 , 11893 , 16665 ,0 }; - static ulong[] dim2301KuoInit = { 1 , 3 , 1 , 13 , 15 , 45 , 19 , 125 , 387 , 1017 , 1075 , 3469 , 7873 , 9135 , 28215 ,0 }; - static ulong[] dim2302KuoInit = { 1 , 3 , 7 , 5 , 23 , 41 , 35 , 171 , 159 , 545 , 2043 , 887 , 8167 , 8977 , 30985 ,0 }; - static ulong[] dim2303KuoInit = { 1 , 3 , 1 , 3 , 21 , 17 , 31 , 171 , 45 , 979 , 757 , 3839 , 4221 , 8659 , 7005 ,0 }; - static ulong[] dim2304KuoInit = { 1 , 3 , 3 , 1 , 3 , 23 , 81 , 157 , 385 , 233 , 527 , 2357 , 7299 , 10977 , 16285 ,0 }; - static ulong[] dim2305KuoInit = { 1 , 1 , 7 , 13 , 23 , 27 , 31 , 211 , 451 , 211 , 45 , 2239 , 981 , 14279 , 14515 ,0 }; - static ulong[] dim2306KuoInit = { 1 , 3 , 1 , 5 , 13 , 61 , 17 , 197 , 455 , 457 , 2023 , 1809 , 4243 , 3269 , 7159 ,0 }; - static ulong[] dim2307KuoInit = { 1 , 1 , 5 , 5 , 9 , 61 , 49 , 111 , 281 , 827 , 1155 , 3107 , 5761 , 12043 , 3061 ,0 }; - static ulong[] dim2308KuoInit = { 1 , 1 , 1 , 5 , 19 , 29 , 63 , 209 , 207 , 503 , 1563 , 2539 , 5115 , 12939 , 22977 ,0 }; - static ulong[] dim2309KuoInit = { 1 , 3 , 7 , 5 , 31 , 33 , 91 , 45 , 399 , 263 , 53 , 2723 , 7909 , 7125 , 14795 ,0 }; - static ulong[] dim2310KuoInit = { 1 , 1 , 7 , 11 , 9 , 5 , 119 , 91 , 87 , 847 , 85 , 4025 , 1891 , 791 , 30447 ,0 }; - static ulong[] dim2311KuoInit = { 1 , 1 , 1 , 1 , 25 , 59 , 101 , 85 , 159 , 491 , 635 , 1047 , 6221 , 11579 , 13943 ,0 }; - static ulong[] dim2312KuoInit = { 1 , 3 , 7 , 3 , 27 , 55 , 19 , 29 , 479 , 299 , 1705 , 3505 , 6811 , 14851 , 6827 ,0 }; - static ulong[] dim2313KuoInit = { 1 , 1 , 1 , 9 , 23 , 19 , 47 , 235 , 81 , 35 , 1297 , 2029 , 1303 , 6877 , 30813 ,0 }; - static ulong[] dim2314KuoInit = { 1 , 3 , 1 , 11 , 21 , 37 , 49 , 209 , 93 , 439 , 2023 , 437 , 6405 , 2407 , 10475 ,0 }; - static ulong[] dim2315KuoInit = { 1 , 1 , 3 , 3 , 5 , 51 , 11 , 127 , 339 , 419 , 1495 , 43 , 5707 , 3905 , 331 ,0 }; - static ulong[] dim2316KuoInit = { 1 , 1 , 5 , 15 , 27 , 7 , 73 , 137 , 111 , 283 , 1017 , 1487 , 7359 , 4921 , 3285 ,0 }; - static ulong[] dim2317KuoInit = { 1 , 1 , 1 , 9 , 3 , 23 , 123 , 75 , 317 , 517 , 109 , 2307 , 1095 , 10309 , 27651 ,0 }; - static ulong[] dim2318KuoInit = { 1 , 3 , 1 , 1 , 21 , 55 , 5 , 115 , 483 , 379 , 1935 , 3483 , 2485 , 1991 , 2403 ,0 }; - static ulong[] dim2319KuoInit = { 1 , 3 , 5 , 9 , 27 , 57 , 1 , 227 , 235 , 373 , 241 , 1115 , 3037 , 6841 , 28711 ,0 }; - static ulong[] dim2320KuoInit = { 1 , 3 , 1 , 13 , 21 , 27 , 19 , 217 , 449 , 727 , 475 , 515 , 7933 , 4401 , 5455 ,0 }; - static ulong[] dim2321KuoInit = { 1 , 3 , 5 , 13 , 27 , 3 , 117 , 67 , 293 , 625 , 1463 , 3713 , 1271 , 11873 , 24239 ,0 }; - static ulong[] dim2322KuoInit = { 1 , 1 , 3 , 1 , 7 , 25 , 5 , 187 , 377 , 15 , 1973 , 597 , 725 , 8809 , 2419 ,0 }; - static ulong[] dim2323KuoInit = { 1 , 1 , 7 , 13 , 7 , 9 , 89 , 41 , 443 , 921 , 17 , 3675 , 715 , 7147 , 25345 ,0 }; - static ulong[] dim2324KuoInit = { 1 , 1 , 5 , 1 , 31 , 27 , 127 , 139 , 101 , 349 , 1551 , 1703 , 5981 , 3259 , 31203 ,0 }; - static ulong[] dim2325KuoInit = { 1 , 1 , 1 , 5 , 31 , 59 , 1 , 149 , 111 , 947 , 1919 , 2841 , 5383 , 6973 , 19565 ,0 }; - static ulong[] dim2326KuoInit = { 1 , 3 , 3 , 11 , 5 , 57 , 65 , 197 , 413 , 741 , 1737 , 1333 , 5101 , 14375 , 28969 ,0 }; - static ulong[] dim2327KuoInit = { 1 , 1 , 1 , 3 , 5 , 21 , 31 , 187 , 51 , 267 , 539 , 1305 , 4085 , 14735 , 9441 ,0 }; - static ulong[] dim2328KuoInit = { 1 , 1 , 7 , 1 , 9 , 27 , 123 , 13 , 383 , 739 , 649 , 1253 , 4697 , 9571 , 16983 ,0 }; - static ulong[] dim2329KuoInit = { 1 , 3 , 1 , 11 , 23 , 3 , 31 , 153 , 185 , 969 , 329 , 3919 , 3905 , 14321 , 16535 ,0 }; - static ulong[] dim2330KuoInit = { 1 , 1 , 1 , 5 , 15 , 31 , 97 , 243 , 117 , 269 , 1545 , 1495 , 167 , 14281 , 1369 ,0 }; - static ulong[] dim2331KuoInit = { 1 , 1 , 1 , 1 , 7 , 47 , 9 , 187 , 233 , 629 , 1981 , 2327 , 7473 , 14641 , 31829 ,0 }; - static ulong[] dim2332KuoInit = { 1 , 1 , 1 , 11 , 11 , 43 , 117 , 193 , 395 , 501 , 1213 , 3499 , 3369 , 817 , 22069 ,0 }; - static ulong[] dim2333KuoInit = { 1 , 3 , 7 , 1 , 13 , 63 , 67 , 67 , 119 , 371 , 1887 , 1281 , 129 , 14277 , 5213 ,0 }; - static ulong[] dim2334KuoInit = { 1 , 3 , 1 , 11 , 11 , 57 , 47 , 149 , 119 , 547 , 389 , 1977 , 1709 , 2335 , 7023 ,0 }; - static ulong[] dim2335KuoInit = { 1 , 1 , 7 , 7 , 15 , 41 , 19 , 57 , 279 , 737 , 29 , 2015 , 1103 , 4933 , 26145 ,0 }; - static ulong[] dim2336KuoInit = { 1 , 3 , 1 , 1 , 23 , 61 , 17 , 1 , 309 , 637 , 809 , 3443 , 135 , 6851 , 27321 ,0 }; - static ulong[] dim2337KuoInit = { 1 , 3 , 1 , 3 , 21 , 63 , 81 , 131 , 495 , 209 , 1901 , 2921 , 1021 , 7207 , 22053 ,0 }; - static ulong[] dim2338KuoInit = { 1 , 1 , 7 , 9 , 7 , 63 , 1 , 119 , 329 , 553 , 1405 , 97 , 4751 , 6955 , 20049 ,0 }; - static ulong[] dim2339KuoInit = { 1 , 3 , 7 , 15 , 1 , 59 , 99 , 201 , 487 , 271 , 2035 , 3261 , 4953 , 15257 , 11835 ,0 }; - static ulong[] dim2340KuoInit = { 1 , 1 , 5 , 11 , 27 , 21 , 27 , 227 , 331 , 779 , 1003 , 2291 , 7139 , 14125 , 14371 ,0 }; - static ulong[] dim2341KuoInit = { 1 , 1 , 3 , 13 , 15 , 43 , 23 , 183 , 463 , 273 , 1707 , 2001 , 3219 , 14481 , 751 ,0 }; - static ulong[] dim2342KuoInit = { 1 , 1 , 5 , 5 , 23 , 31 , 51 , 39 , 221 , 687 , 2003 , 1251 , 3541 , 6347 , 551 ,0 }; - static ulong[] dim2343KuoInit = { 1 , 1 , 7 , 3 , 17 , 51 , 3 , 57 , 131 , 13 , 2027 , 3301 , 4223 , 6499 , 30913 ,0 }; - static ulong[] dim2344KuoInit = { 1 , 1 , 7 , 13 , 11 , 47 , 53 , 205 , 59 , 315 , 1595 , 3747 , 2623 , 7317 , 8309 ,0 }; - static ulong[] dim2345KuoInit = { 1 , 3 , 1 , 11 , 13 , 45 , 83 , 131 , 193 , 739 , 61 , 1657 , 3789 , 9859 , 3755 ,0 }; - static ulong[] dim2346KuoInit = { 1 , 3 , 7 , 11 , 25 , 7 , 123 , 103 , 307 , 463 , 1113 , 2245 , 2819 , 12983 , 18077 ,0 }; - static ulong[] dim2347KuoInit = { 1 , 1 , 1 , 1 , 7 , 23 , 103 , 183 , 409 , 657 , 583 , 583 , 5449 , 7397 , 13085 ,0 }; - static ulong[] dim2348KuoInit = { 1 , 3 , 3 , 5 , 3 , 61 , 31 , 147 , 31 , 449 , 1579 , 4021 , 1163 , 9719 , 27079 ,0 }; - static ulong[] dim2349KuoInit = { 1 , 3 , 1 , 3 , 9 , 53 , 125 , 77 , 99 , 863 , 1719 , 51 , 4183 , 13009 , 791 ,0 }; - static ulong[] dim2350KuoInit = { 1 , 3 , 3 , 11 , 27 , 33 , 43 , 5 , 173 , 775 , 593 , 3701 , 3323 , 6481 , 25765 ,0 }; - static ulong[] dim2351KuoInit = { 1 , 1 , 7 , 15 , 11 , 3 , 109 , 221 , 375 , 883 , 903 , 2361 , 255 , 12851 , 16697 ,0 }; - static ulong[] dim2352KuoInit = { 1 , 1 , 5 , 9 , 3 , 61 , 127 , 89 , 213 , 71 , 303 , 2525 , 3691 , 2945 , 12359 ,0 }; - static ulong[] dim2353KuoInit = { 1 , 3 , 1 , 13 , 19 , 15 , 7 , 231 , 159 , 275 , 1161 , 819 , 3003 , 12707 , 20699 ,0 }; - static ulong[] dim2354KuoInit = { 1 , 1 , 3 , 1 , 31 , 51 , 125 , 21 , 27 , 427 , 941 , 237 , 4343 , 9555 , 30511 ,0 }; - static ulong[] dim2355KuoInit = { 1 , 3 , 3 , 9 , 17 , 23 , 105 , 21 , 471 , 357 , 773 , 1185 , 2655 , 2317 , 9969 ,0 }; - static ulong[] dim2356KuoInit = { 1 , 1 , 5 , 7 , 15 , 55 , 87 , 249 , 111 , 319 , 985 , 2305 , 1641 , 12655 , 7321 ,0 }; - static ulong[] dim2357KuoInit = { 1 , 3 , 5 , 3 , 23 , 49 , 85 , 31 , 299 , 391 , 549 , 3831 , 1413 , 13803 , 30599 ,0 }; - static ulong[] dim2358KuoInit = { 1 , 1 , 3 , 3 , 31 , 39 , 43 , 253 , 67 , 321 , 463 , 2327 , 6831 , 10461 , 18077 ,0 }; - static ulong[] dim2359KuoInit = { 1 , 3 , 1 , 9 , 13 , 13 , 127 , 175 , 425 , 567 , 1663 , 195 , 1763 , 13271 , 1739 ,0 }; - static ulong[] dim2360KuoInit = { 1 , 1 , 7 , 9 , 9 , 33 , 11 , 167 , 87 , 901 , 1625 , 2055 , 2475 , 7241 , 29717 ,0 }; - static ulong[] dim2361KuoInit = { 1 , 1 , 1 , 1 , 15 , 63 , 127 , 29 , 227 , 817 , 637 , 1873 , 4885 , 16299 , 31243 ,0 }; - static ulong[] dim2362KuoInit = { 1 , 3 , 7 , 3 , 17 , 27 , 81 , 237 , 283 , 161 , 1905 , 1551 , 6171 , 4519 , 11047 ,0 }; - static ulong[] dim2363KuoInit = { 1 , 1 , 7 , 9 , 25 , 23 , 25 , 1 , 461 , 623 , 493 , 827 , 5795 , 16065 , 8401 ,0 }; - static ulong[] dim2364KuoInit = { 1 , 3 , 5 , 11 , 29 , 29 , 91 , 133 , 91 , 565 , 1821 , 269 , 1731 , 1499 , 7975 ,0 }; - static ulong[] dim2365KuoInit = { 1 , 1 , 1 , 13 , 3 , 41 , 99 , 23 , 239 , 945 , 219 , 1127 , 4919 , 9713 , 3321 ,0 }; - static ulong[] dim2366KuoInit = { 1 , 3 , 1 , 11 , 25 , 59 , 59 , 127 , 83 , 643 , 881 , 1671 , 3521 , 459 , 15479 ,0 }; - static ulong[] dim2367KuoInit = { 1 , 1 , 5 , 11 , 15 , 23 , 111 , 225 , 145 , 703 , 1643 , 419 , 4853 , 7195 , 20879 ,0 }; - static ulong[] dim2368KuoInit = { 1 , 3 , 7 , 15 , 5 , 31 , 111 , 151 , 489 , 629 , 473 , 1507 , 117 , 15305 , 11011 ,0 }; - static ulong[] dim2369KuoInit = { 1 , 1 , 3 , 3 , 1 , 55 , 55 , 223 , 489 , 911 , 1721 , 3533 , 5893 , 2891 , 8929 ,0 }; - static ulong[] dim2370KuoInit = { 1 , 1 , 5 , 13 , 7 , 43 , 113 , 99 , 19 , 681 , 1765 , 1983 , 5477 , 7531 , 26507 ,0 }; - static ulong[] dim2371KuoInit = { 1 , 1 , 3 , 1 , 9 , 7 , 77 , 231 , 345 , 745 , 285 , 3213 , 2611 , 4449 , 24621 ,0 }; - static ulong[] dim2372KuoInit = { 1 , 1 , 5 , 1 , 21 , 21 , 3 , 11 , 131 , 327 , 1893 , 33 , 6947 , 337 , 8877 ,0 }; - static ulong[] dim2373KuoInit = { 1 , 1 , 5 , 13 , 5 , 11 , 41 , 7 , 447 , 625 , 1231 , 3621 , 3785 , 12351 , 13829 ,0 }; - static ulong[] dim2374KuoInit = { 1 , 3 , 1 , 13 , 29 , 41 , 11 , 63 , 357 , 723 , 1657 , 91 , 1373 , 6383 , 8327 ,0 }; - static ulong[] dim2375KuoInit = { 1 , 3 , 3 , 15 , 23 , 51 , 85 , 113 , 103 , 499 , 1669 , 3685 , 63 , 2853 , 20859 ,0 }; - static ulong[] dim2376KuoInit = { 1 , 1 , 5 , 11 , 31 , 39 , 15 , 103 , 365 , 231 , 443 , 3213 , 6951 , 1715 , 32301 ,0 }; - static ulong[] dim2377KuoInit = { 1 , 3 , 7 , 5 , 19 , 23 , 13 , 127 , 475 , 281 , 1095 , 473 , 4955 , 2217 , 10427 ,0 }; - static ulong[] dim2378KuoInit = { 1 , 1 , 5 , 13 , 17 , 41 , 47 , 121 , 131 , 69 , 1747 , 3679 , 2765 , 4349 , 32041 ,0 }; - static ulong[] dim2379KuoInit = { 1 , 1 , 7 , 9 , 3 , 47 , 11 , 127 , 321 , 669 , 1283 , 797 , 6393 , 12351 , 5161 ,0 }; - static ulong[] dim2380KuoInit = { 1 , 3 , 7 , 15 , 21 , 37 , 73 , 15 , 393 , 173 , 1461 , 1437 , 2367 , 7171 , 15123 ,0 }; - static ulong[] dim2381KuoInit = { 1 , 3 , 5 , 15 , 7 , 57 , 29 , 83 , 241 , 221 , 1607 , 1291 , 4839 , 11293 , 1837 ,0 }; - static ulong[] dim2382KuoInit = { 1 , 3 , 5 , 7 , 1 , 31 , 59 , 143 , 487 , 317 , 535 , 1505 , 3705 , 9947 , 6149 ,0 }; - static ulong[] dim2383KuoInit = { 1 , 3 , 1 , 3 , 29 , 31 , 69 , 63 , 183 , 173 , 1965 , 3331 , 4473 , 993 , 4937 ,0 }; - static ulong[] dim2384KuoInit = { 1 , 1 , 1 , 15 , 13 , 13 , 55 , 43 , 283 , 897 , 1019 , 2761 , 3237 , 14661 , 12309 ,0 }; - static ulong[] dim2385KuoInit = { 1 , 3 , 1 , 15 , 9 , 15 , 1 , 19 , 227 , 777 , 1713 , 3471 , 2917 , 1117 , 16397 ,0 }; - static ulong[] dim2386KuoInit = { 1 , 1 , 1 , 1 , 21 , 19 , 49 , 3 , 477 , 659 , 61 , 2373 , 6363 , 13771 , 5675 ,0 }; - static ulong[] dim2387KuoInit = { 1 , 3 , 3 , 3 , 13 , 23 , 43 , 253 , 483 , 975 , 1629 , 19 , 6339 , 13963 , 6065 ,0 }; - static ulong[] dim2388KuoInit = { 1 , 3 , 7 , 3 , 9 , 31 , 65 , 1 , 311 , 67 , 293 , 667 , 3685 , 3589 , 25251 ,0 }; - static ulong[] dim2389KuoInit = { 1 , 1 , 3 , 1 , 29 , 31 , 47 , 85 , 431 , 131 , 1495 , 1271 , 6121 , 7183 , 20477 ,0 }; - static ulong[] dim2390KuoInit = { 1 , 1 , 7 , 5 , 13 , 37 , 83 , 201 , 277 , 643 , 19 , 2519 , 2589 , 2471 , 19727 ,0 }; - static ulong[] dim2391KuoInit = { 1 , 3 , 5 , 13 , 27 , 13 , 97 , 183 , 463 , 639 , 87 , 181 , 747 , 3715 , 16207 ,0 }; - static ulong[] dim2392KuoInit = { 1 , 1 , 7 , 3 , 9 , 29 , 21 , 191 , 485 , 211 , 541 , 69 , 511 , 9923 , 24543 ,0 }; - static ulong[] dim2393KuoInit = { 1 , 3 , 5 , 9 , 19 , 43 , 85 , 189 , 47 , 723 , 1211 , 1259 , 1645 , 2983 , 27195 ,0 }; - static ulong[] dim2394KuoInit = { 1 , 1 , 7 , 15 , 17 , 25 , 103 , 83 , 389 , 229 , 1457 , 4045 , 161 , 15471 , 19929 ,0 }; - static ulong[] dim2395KuoInit = { 1 , 1 , 3 , 9 , 5 , 27 , 55 , 231 , 245 , 723 , 479 , 3761 , 787 , 12939 , 30227 ,0 }; - static ulong[] dim2396KuoInit = { 1 , 3 , 3 , 1 , 19 , 39 , 63 , 27 , 137 , 399 , 1353 , 1143 , 5835 , 2013 , 4107 ,0 }; - static ulong[] dim2397KuoInit = { 1 , 3 , 5 , 7 , 5 , 39 , 45 , 207 , 7 , 131 , 961 , 1715 , 3761 , 11501 , 9803 ,0 }; - static ulong[] dim2398KuoInit = { 1 , 3 , 1 , 7 , 17 , 11 , 23 , 45 , 417 , 289 , 1545 , 2585 , 1345 , 15529 , 8365 ,0 }; - static ulong[] dim2399KuoInit = { 1 , 1 , 1 , 7 , 21 , 27 , 97 , 23 , 461 , 983 , 997 , 1321 , 2551 , 5485 , 23565 ,0 }; - static ulong[] dim2400KuoInit = { 1 , 1 , 5 , 5 , 23 , 19 , 77 , 103 , 171 , 553 , 1767 , 3255 , 7955 , 249 , 32681 ,0 }; - static ulong[] dim2401KuoInit = { 1 , 1 , 7 , 1 , 23 , 43 , 73 , 15 , 381 , 245 , 1389 , 3693 , 1975 , 13629 , 2079 ,0 }; - static ulong[] dim2402KuoInit = { 1 , 1 , 7 , 11 , 23 , 61 , 79 , 39 , 345 , 541 , 875 , 1375 , 123 , 15305 , 13731 ,0 }; - static ulong[] dim2403KuoInit = { 1 , 1 , 3 , 15 , 3 , 17 , 19 , 11 , 79 , 415 , 1791 , 447 , 6529 , 11243 , 10427 ,0 }; - static ulong[] dim2404KuoInit = { 1 , 1 , 7 , 15 , 9 , 31 , 121 , 247 , 403 , 935 , 705 , 2921 , 3769 , 625 , 22905 ,0 }; - static ulong[] dim2405KuoInit = { 1 , 3 , 5 , 15 , 19 , 9 , 5 , 47 , 135 , 585 , 1155 , 1517 , 4961 , 15725 , 7585 ,0 }; - static ulong[] dim2406KuoInit = { 1 , 3 , 3 , 7 , 19 , 57 , 37 , 69 , 117 , 485 , 115 , 2709 , 1909 , 12781 , 19323 ,0 }; - static ulong[] dim2407KuoInit = { 1 , 1 , 1 , 5 , 7 , 1 , 37 , 39 , 141 , 1017 , 993 , 191 , 6173 , 8083 , 9733 ,0 }; - static ulong[] dim2408KuoInit = { 1 , 1 , 7 , 3 , 3 , 21 , 17 , 55 , 129 , 353 , 673 , 3233 , 6289 , 10955 , 19357 ,0 }; - static ulong[] dim2409KuoInit = { 1 , 3 , 7 , 11 , 31 , 31 , 31 , 105 , 187 , 839 , 733 , 1795 , 5075 , 1053 , 613 ,0 }; - static ulong[] dim2410KuoInit = { 1 , 3 , 3 , 1 , 9 , 9 , 23 , 139 , 417 , 431 , 1943 , 3067 , 267 , 4401 , 9847 ,0 }; - static ulong[] dim2411KuoInit = { 1 , 3 , 5 , 11 , 23 , 61 , 61 , 119 , 383 , 869 , 503 , 195 , 1935 , 4617 , 21393 ,0 }; - static ulong[] dim2412KuoInit = { 1 , 1 , 1 , 5 , 7 , 15 , 51 , 53 , 427 , 499 , 1829 , 2533 , 3029 , 12485 , 28425 ,0 }; - static ulong[] dim2413KuoInit = { 1 , 3 , 3 , 7 , 9 , 11 , 55 , 205 , 255 , 619 , 1323 , 1983 , 15 , 4237 , 20983 ,0 }; - static ulong[] dim2414KuoInit = { 1 , 1 , 3 , 15 , 15 , 37 , 109 , 247 , 179 , 1005 , 1111 , 77 , 4533 , 12849 , 25601 ,0 }; - static ulong[] dim2415KuoInit = { 1 , 1 , 5 , 3 , 15 , 25 , 59 , 117 , 55 , 755 , 681 , 649 , 6041 , 1695 , 13719 ,0 }; - static ulong[] dim2416KuoInit = { 1 , 3 , 1 , 3 , 15 , 17 , 117 , 113 , 197 , 701 , 773 , 1097 , 1267 , 16093 , 21555 ,0 }; - static ulong[] dim2417KuoInit = { 1 , 3 , 1 , 5 , 9 , 57 , 39 , 171 , 449 , 507 , 29 , 3581 , 1929 , 12715 , 24575 ,0 }; - static ulong[] dim2418KuoInit = { 1 , 3 , 5 , 5 , 23 , 1 , 67 , 153 , 375 , 333 , 379 , 3163 , 8121 , 13465 , 27641 ,0 }; - static ulong[] dim2419KuoInit = { 1 , 3 , 5 , 5 , 31 , 27 , 83 , 243 , 415 , 997 , 1787 , 4021 , 5955 , 1861 , 10511 ,0 }; - static ulong[] dim2420KuoInit = { 1 , 3 , 1 , 3 , 13 , 47 , 69 , 169 , 185 , 645 , 1857 , 3487 , 1557 , 9589 , 7971 ,0 }; - static ulong[] dim2421KuoInit = { 1 , 3 , 3 , 15 , 3 , 1 , 93 , 97 , 71 , 433 , 1371 , 2495 , 8171 , 9101 , 32435 ,0 }; - static ulong[] dim2422KuoInit = { 1 , 3 , 7 , 11 , 3 , 29 , 37 , 167 , 169 , 15 , 1575 , 1331 , 7163 , 1555 , 32439 ,0 }; - static ulong[] dim2423KuoInit = { 1 , 1 , 5 , 1 , 29 , 11 , 83 , 135 , 367 , 37 , 1455 , 3939 , 3383 , 5291 , 14269 ,0 }; - static ulong[] dim2424KuoInit = { 1 , 1 , 5 , 15 , 7 , 63 , 17 , 45 , 259 , 57 , 1933 , 3101 , 7871 , 12633 , 15789 ,0 }; - static ulong[] dim2425KuoInit = { 1 , 1 , 1 , 7 , 19 , 37 , 89 , 159 , 487 , 101 , 1551 , 3703 , 4323 , 9153 , 6155 ,0 }; - static ulong[] dim2426KuoInit = { 1 , 3 , 3 , 13 , 15 , 49 , 81 , 51 , 267 , 761 , 863 , 2239 , 7683 , 15491 , 28655 ,0 }; - static ulong[] dim2427KuoInit = { 1 , 3 , 1 , 1 , 25 , 53 , 113 , 117 , 11 , 1003 , 539 , 3603 , 1007 , 11329 , 15099 ,0 }; - static ulong[] dim2428KuoInit = { 1 , 3 , 5 , 7 , 9 , 27 , 125 , 231 , 301 , 461 , 2031 , 183 , 6361 , 10811 , 29425 ,0 }; - static ulong[] dim2429KuoInit = { 1 , 1 , 3 , 1 , 3 , 37 , 65 , 127 , 487 , 611 , 867 , 2361 , 5243 , 11829 , 31297 ,0 }; - static ulong[] dim2430KuoInit = { 1 , 3 , 3 , 15 , 9 , 39 , 31 , 219 , 77 , 97 , 1061 , 435 , 2449 , 14751 , 20273 ,0 }; - static ulong[] dim2431KuoInit = { 1 , 1 , 5 , 11 , 1 , 23 , 41 , 239 , 183 , 287 , 969 , 1325 , 3553 , 6751 , 14679 ,0 }; - static ulong[] dim2432KuoInit = { 1 , 3 , 7 , 1 , 17 , 61 , 47 , 207 , 509 , 601 , 1539 , 345 , 3723 , 5415 , 11667 ,0 }; - static ulong[] dim2433KuoInit = { 1 , 1 , 7 , 7 , 23 , 33 , 25 , 165 , 345 , 569 , 983 , 2857 , 1563 , 1737 , 19285 ,0 }; - static ulong[] dim2434KuoInit = { 1 , 1 , 1 , 7 , 3 , 43 , 107 , 229 , 223 , 583 , 1495 , 3487 , 7497 , 10367 , 20575 ,0 }; - static ulong[] dim2435KuoInit = { 1 , 3 , 3 , 13 , 21 , 49 , 17 , 195 , 115 , 797 , 1489 , 1587 , 7847 , 11013 , 14547 ,0 }; - static ulong[] dim2436KuoInit = { 1 , 3 , 5 , 11 , 9 , 29 , 19 , 245 , 153 , 779 , 1311 , 425 , 5809 , 4457 , 6905 ,0 }; - static ulong[] dim2437KuoInit = { 1 , 1 , 5 , 3 , 21 , 33 , 13 , 193 , 343 , 971 , 1315 , 1989 , 1969 , 9227 , 8881 ,0 }; - static ulong[] dim2438KuoInit = { 1 , 3 , 7 , 15 , 3 , 59 , 87 , 205 , 261 , 567 , 557 , 1143 , 6923 , 9451 , 20239 ,0 }; - static ulong[] dim2439KuoInit = { 1 , 1 , 1 , 15 , 29 , 35 , 127 , 123 , 173 , 807 , 1279 , 2413 , 1899 , 11657 , 22257 ,0 }; - static ulong[] dim2440KuoInit = { 1 , 3 , 5 , 3 , 23 , 35 , 125 , 129 , 239 , 951 , 499 , 1609 , 4643 , 339 , 26701 ,0 }; - static ulong[] dim2441KuoInit = { 1 , 3 , 3 , 13 , 9 , 15 , 23 , 55 , 105 , 81 , 591 , 947 , 3761 , 7351 , 25697 ,0 }; - static ulong[] dim2442KuoInit = { 1 , 1 , 7 , 13 , 23 , 17 , 127 , 149 , 227 , 1005 , 839 , 3391 , 5761 , 10431 , 31899 ,0 }; - static ulong[] dim2443KuoInit = { 1 , 3 , 1 , 1 , 23 , 7 , 11 , 3 , 77 , 457 , 375 , 3823 , 5447 , 8339 , 18847 ,0 }; - static ulong[] dim2444KuoInit = { 1 , 3 , 7 , 3 , 29 , 1 , 19 , 39 , 23 , 285 , 569 , 2979 , 7029 , 11311 , 18269 ,0 }; - static ulong[] dim2445KuoInit = { 1 , 1 , 5 , 9 , 21 , 19 , 85 , 211 , 437 , 185 , 597 , 787 , 4555 , 2853 , 18493 ,0 }; - static ulong[] dim2446KuoInit = { 1 , 3 , 3 , 9 , 11 , 27 , 25 , 245 , 55 , 869 , 323 , 3999 , 2639 , 9385 , 26823 ,0 }; - static ulong[] dim2447KuoInit = { 1 , 3 , 1 , 7 , 19 , 61 , 51 , 111 , 115 , 721 , 893 , 23 , 6375 , 5101 , 25567 ,0 }; - static ulong[] dim2448KuoInit = { 1 , 3 , 5 , 9 , 9 , 13 , 9 , 241 , 297 , 391 , 1529 , 3843 , 737 , 5897 , 23469 ,0 }; - static ulong[] dim2449KuoInit = { 1 , 3 , 7 , 3 , 31 , 53 , 43 , 219 , 81 , 507 , 1627 , 3503 , 817 , 6533 , 31633 ,0 }; - static ulong[] dim2450KuoInit = { 1 , 1 , 7 , 1 , 13 , 59 , 13 , 185 , 387 , 869 , 1013 , 2291 , 4945 , 11493 , 7785 ,0 }; - static ulong[] dim2451KuoInit = { 1 , 3 , 5 , 9 , 31 , 35 , 11 , 225 , 235 , 893 , 1749 , 2393 , 5317 , 10069 , 8569 ,0 }; - static ulong[] dim2452KuoInit = { 1 , 1 , 1 , 3 , 5 , 15 , 93 , 25 , 503 , 205 , 65 , 2563 , 7971 , 2917 , 19687 ,0 }; - static ulong[] dim2453KuoInit = { 1 , 3 , 3 , 13 , 1 , 37 , 127 , 63 , 339 , 121 , 1895 , 1943 , 7527 , 15869 , 20533 ,0 }; - static ulong[] dim2454KuoInit = { 1 , 1 , 5 , 7 , 19 , 25 , 87 , 27 , 279 , 419 , 1261 , 613 , 7687 , 5301 , 6761 ,0 }; - static ulong[] dim2455KuoInit = { 1 , 1 , 1 , 1 , 13 , 33 , 59 , 235 , 471 , 811 , 695 , 2727 , 5615 , 6269 , 13469 ,0 }; - static ulong[] dim2456KuoInit = { 1 , 3 , 1 , 15 , 17 , 23 , 123 , 71 , 15 , 1005 , 973 , 411 , 2627 , 1967 , 25597 ,0 }; - static ulong[] dim2457KuoInit = { 1 , 3 , 5 , 1 , 3 , 61 , 71 , 217 , 377 , 613 , 1819 , 141 , 6265 , 9223 , 20635 ,0 }; - static ulong[] dim2458KuoInit = { 1 , 1 , 5 , 11 , 15 , 1 , 39 , 121 , 83 , 57 , 1133 , 3165 , 7675 , 13715 , 11383 ,0 }; - static ulong[] dim2459KuoInit = { 1 , 3 , 7 , 15 , 9 , 3 , 97 , 223 , 493 , 77 , 159 , 2921 , 5475 , 9289 , 20925 ,0 }; - static ulong[] dim2460KuoInit = { 1 , 1 , 3 , 7 , 29 , 13 , 87 , 219 , 327 , 879 , 883 , 1637 , 3451 , 13939 , 8203 ,0 }; - static ulong[] dim2461KuoInit = { 1 , 3 , 7 , 15 , 25 , 21 , 95 , 129 , 343 , 9 , 1415 , 2965 , 747 , 7297 , 24293 ,0 }; - static ulong[] dim2462KuoInit = { 1 , 1 , 1 , 3 , 23 , 47 , 57 , 31 , 359 , 1017 , 769 , 2761 , 1933 , 6091 , 6475 ,0 }; - static ulong[] dim2463KuoInit = { 1 , 1 , 5 , 9 , 27 , 45 , 125 , 67 , 145 , 581 , 157 , 2153 , 2727 , 8025 , 28165 ,0 }; - static ulong[] dim2464KuoInit = { 1 , 3 , 5 , 9 , 7 , 53 , 27 , 161 , 343 , 139 , 1651 , 1275 , 2981 , 9027 , 31175 ,0 }; - static ulong[] dim2465KuoInit = { 1 , 3 , 3 , 11 , 7 , 15 , 81 , 229 , 115 , 849 , 459 , 1651 , 3867 , 7029 , 6741 ,0 }; - static ulong[] dim2466KuoInit = { 1 , 1 , 3 , 5 , 31 , 45 , 17 , 107 , 467 , 401 , 1473 , 1953 , 3779 , 11237 , 31257 ,0 }; - static ulong[] dim2467KuoInit = { 1 , 3 , 3 , 11 , 3 , 27 , 45 , 217 , 133 , 515 , 1487 , 1427 , 1999 , 12979 , 3543 ,0 }; - static ulong[] dim2468KuoInit = { 1 , 3 , 7 , 3 , 17 , 31 , 123 , 205 , 263 , 963 , 1697 , 2453 , 1249 , 603 , 8581 ,0 }; - static ulong[] dim2469KuoInit = { 1 , 3 , 1 , 15 , 23 , 9 , 23 , 251 , 489 , 393 , 1103 , 3273 , 5703 , 3033 , 22631 ,0 }; - static ulong[] dim2470KuoInit = { 1 , 3 , 3 , 13 , 23 , 29 , 49 , 233 , 461 , 795 , 991 , 3695 , 4715 , 7211 , 3695 ,0 }; - static ulong[] dim2471KuoInit = { 1 , 3 , 3 , 15 , 21 , 11 , 33 , 69 , 347 , 535 , 25 , 3465 , 2825 , 9345 , 4485 ,0 }; - static ulong[] dim2472KuoInit = { 1 , 3 , 7 , 3 , 23 , 47 , 65 , 209 , 357 , 363 , 1979 , 289 , 35 , 4459 , 17929 ,0 }; - static ulong[] dim2473KuoInit = { 1 , 3 , 1 , 11 , 19 , 17 , 125 , 231 , 221 , 953 , 2041 , 2359 , 5925 , 15693 , 30859 ,0 }; - static ulong[] dim2474KuoInit = { 1 , 1 , 3 , 13 , 31 , 11 , 11 , 215 , 335 , 153 , 1459 , 2303 , 3471 , 7415 , 3783 ,0 }; - static ulong[] dim2475KuoInit = { 1 , 1 , 7 , 5 , 11 , 55 , 47 , 43 , 355 , 469 , 963 , 383 , 667 , 2233 , 27759 ,0 }; - static ulong[] dim2476KuoInit = { 1 , 3 , 1 , 9 , 23 , 29 , 27 , 135 , 359 , 111 , 387 , 3021 , 817 , 4211 , 17243 ,0 }; - static ulong[] dim2477KuoInit = { 1 , 1 , 3 , 9 , 25 , 27 , 63 , 89 , 195 , 359 , 413 , 3509 , 3831 , 4785 , 30097 ,0 }; - static ulong[] dim2478KuoInit = { 1 , 1 , 5 , 5 , 11 , 29 , 29 , 25 , 445 , 643 , 261 , 3901 , 3019 , 14213 , 16115 ,0 }; - static ulong[] dim2479KuoInit = { 1 , 3 , 3 , 15 , 21 , 31 , 7 , 255 , 207 , 535 , 1033 , 1017 , 3791 , 11455 , 31701 ,0 }; - static ulong[] dim2480KuoInit = { 1 , 3 , 5 , 13 , 15 , 37 , 79 , 205 , 439 , 609 , 1433 , 3333 , 6583 , 9689 , 14979 ,0 }; - static ulong[] dim2481KuoInit = { 1 , 1 , 7 , 3 , 31 , 27 , 53 , 101 , 427 , 773 , 1877 , 1715 , 6177 , 11851 , 17989 ,0 }; - static ulong[] dim2482KuoInit = { 1 , 3 , 1 , 3 , 21 , 11 , 101 , 203 , 49 , 543 , 1979 , 1469 , 6701 , 9963 , 7793 ,0 }; - static ulong[] dim2483KuoInit = { 1 , 1 , 3 , 1 , 15 , 47 , 123 , 141 , 433 , 783 , 211 , 1489 , 4983 , 6417 , 29767 ,0 }; - static ulong[] dim2484KuoInit = { 1 , 1 , 5 , 3 , 1 , 41 , 109 , 13 , 465 , 959 , 431 , 543 , 4681 , 8573 , 7889 ,0 }; - static ulong[] dim2485KuoInit = { 1 , 1 , 1 , 3 , 15 , 43 , 15 , 63 , 145 , 859 , 939 , 629 , 7077 , 5617 , 16779 ,0 }; - static ulong[] dim2486KuoInit = { 1 , 3 , 3 , 1 , 23 , 63 , 67 , 139 , 219 , 257 , 943 , 1501 , 827 , 10855 , 10035 ,0 }; - static ulong[] dim2487KuoInit = { 1 , 3 , 1 , 15 , 9 , 47 , 27 , 119 , 231 , 767 , 999 , 3553 , 7683 , 5399 , 11553 ,0 }; - static ulong[] dim2488KuoInit = { 1 , 3 , 3 , 11 , 15 , 13 , 35 , 139 , 463 , 985 , 553 , 3997 , 2935 , 7707 , 2511 ,0 }; - static ulong[] dim2489KuoInit = { 1 , 1 , 3 , 11 , 23 , 53 , 103 , 1 , 409 , 853 , 737 , 2077 , 523 , 1839 , 32145 ,0 }; - static ulong[] dim2490KuoInit = { 1 , 3 , 1 , 15 , 23 , 7 , 77 , 185 , 371 , 447 , 499 , 569 , 6647 , 501 , 27649 ,0 }; - static ulong[] dim2491KuoInit = { 1 , 1 , 3 , 5 , 19 , 31 , 119 , 157 , 385 , 427 , 1411 , 4031 , 4199 , 14567 , 8133 ,0 }; - static ulong[] dim2492KuoInit = { 1 , 3 , 7 , 5 , 31 , 3 , 123 , 149 , 209 , 467 , 1619 , 879 , 5949 , 7295 , 25165 ,0 }; - static ulong[] dim2493KuoInit = { 1 , 3 , 1 , 15 , 31 , 47 , 111 , 129 , 359 , 385 , 463 , 3363 , 6823 , 10751 , 4473 ,0 }; - static ulong[] dim2494KuoInit = { 1 , 3 , 3 , 7 , 5 , 39 , 71 , 45 , 439 , 161 , 597 , 2093 , 1725 , 11285 , 18149 ,0 }; - static ulong[] dim2495KuoInit = { 1 , 3 , 3 , 7 , 21 , 55 , 115 , 199 , 339 , 425 , 71 , 305 , 1161 , 3359 , 16835 ,0 }; - static ulong[] dim2496KuoInit = { 1 , 1 , 7 , 7 , 1 , 53 , 51 , 31 , 57 , 581 , 147 , 903 , 7269 , 1461 , 7417 ,0 }; - static ulong[] dim2497KuoInit = { 1 , 3 , 7 , 3 , 17 , 31 , 65 , 195 , 47 , 575 , 1877 , 1603 , 3043 , 5385 , 15177 ,0 }; - static ulong[] dim2498KuoInit = { 1 , 1 , 3 , 11 , 15 , 7 , 121 , 51 , 67 , 391 , 1553 , 1817 , 6503 , 2907 , 3611 ,0 }; - static ulong[] dim2499KuoInit = { 1 , 1 , 1 , 9 , 13 , 51 , 95 , 19 , 315 , 549 , 1417 , 2073 , 485 , 5257 , 32419 ,0 }; - static ulong[] dim2500KuoInit = { 1 , 3 , 1 , 9 , 31 , 63 , 107 , 103 , 173 , 681 , 211 , 3283 , 2413 , 2073 , 24497 ,0 }; - static ulong[] dim2501KuoInit = { 1 , 3 , 1 , 7 , 3 , 41 , 49 , 81 , 289 , 177 , 699 , 1305 , 7867 , 4699 , 27669 ,0 }; - static ulong[] dim2502KuoInit = { 1 , 1 , 5 , 3 , 7 , 15 , 73 , 57 , 319 , 959 , 701 , 2071 , 1587 , 4701 , 2595 ,0 }; - static ulong[] dim2503KuoInit = { 1 , 1 , 5 , 7 , 7 , 1 , 29 , 129 , 361 , 619 , 1405 , 2185 , 6631 , 3505 , 391 ,0 }; - static ulong[] dim2504KuoInit = { 1 , 3 , 3 , 5 , 19 , 9 , 31 , 63 , 149 , 181 , 299 , 2755 , 1511 , 5745 , 20323 ,0 }; - static ulong[] dim2505KuoInit = { 1 , 1 , 3 , 11 , 23 , 5 , 29 , 175 , 119 , 25 , 319 , 835 , 1339 , 5429 , 7175 ,0 }; - static ulong[] dim2506KuoInit = { 1 , 1 , 3 , 3 , 31 , 57 , 55 , 181 , 473 , 229 , 309 , 1567 , 5063 , 9745 , 3713 ,0 }; - static ulong[] dim2507KuoInit = { 1 , 3 , 3 , 13 , 1 , 15 , 23 , 175 , 71 , 53 , 1749 , 743 , 285 , 49 , 7389 ,0 }; - static ulong[] dim2508KuoInit = { 1 , 3 , 1 , 5 , 7 , 39 , 75 , 177 , 259 , 975 , 257 , 1497 , 1565 , 6973 , 3827 ,0 }; - static ulong[] dim2509KuoInit = { 1 , 3 , 7 , 13 , 1 , 39 , 43 , 213 , 291 , 941 , 613 , 3041 , 1859 , 10755 , 29831 ,0 }; - static ulong[] dim2510KuoInit = { 1 , 3 , 3 , 9 , 17 , 43 , 15 , 135 , 473 , 989 , 429 , 3287 , 3699 , 14349 , 16311 ,0 }; - static ulong[] dim2511KuoInit = { 1 , 3 , 1 , 15 , 1 , 51 , 59 , 203 , 383 , 731 , 171 , 1259 , 5833 , 12029 , 18099 ,0 }; - static ulong[] dim2512KuoInit = { 1 , 3 , 1 , 3 , 19 , 63 , 125 , 57 , 429 , 93 , 1179 , 2707 , 449 , 2213 , 4759 ,0 }; - static ulong[] dim2513KuoInit = { 1 , 1 , 7 , 3 , 19 , 11 , 107 , 127 , 359 , 759 , 503 , 761 , 6817 , 15343 , 13777 ,0 }; - static ulong[] dim2514KuoInit = { 1 , 1 , 1 , 7 , 21 , 49 , 67 , 179 , 241 , 403 , 769 , 3341 , 1845 , 2855 , 3825 ,0 }; - static ulong[] dim2515KuoInit = { 1 , 3 , 3 , 3 , 7 , 29 , 71 , 35 , 389 , 297 , 673 , 1353 , 6781 , 5633 , 12459 ,0 }; - static ulong[] dim2516KuoInit = { 1 , 1 , 1 , 15 , 13 , 15 , 11 , 57 , 143 , 35 , 809 , 2295 , 6497 , 455 , 23689 ,0 }; - static ulong[] dim2517KuoInit = { 1 , 3 , 7 , 15 , 23 , 39 , 39 , 211 , 335 , 537 , 1569 , 3989 , 5777 , 12951 , 22841 ,0 }; - static ulong[] dim2518KuoInit = { 1 , 1 , 7 , 3 , 23 , 17 , 107 , 237 , 241 , 533 , 57 , 3421 , 263 , 889 , 28841 ,0 }; - static ulong[] dim2519KuoInit = { 1 , 1 , 5 , 1 , 11 , 29 , 17 , 141 , 431 , 809 , 1227 , 2835 , 2955 , 11823 , 23061 ,0 }; - static ulong[] dim2520KuoInit = { 1 , 1 , 3 , 9 , 5 , 51 , 73 , 43 , 75 , 985 , 1665 , 1369 , 519 , 6379 , 8665 ,0 }; - static ulong[] dim2521KuoInit = { 1 , 3 , 3 , 13 , 17 , 21 , 9 , 173 , 333 , 689 , 277 , 1755 , 5173 , 7651 , 30597 ,0 }; - static ulong[] dim2522KuoInit = { 1 , 3 , 5 , 9 , 3 , 59 , 59 , 221 , 177 , 819 , 1483 , 1945 , 4725 , 4821 , 3709 ,0 }; - static ulong[] dim2523KuoInit = { 1 , 1 , 7 , 7 , 19 , 35 , 93 , 47 , 49 , 861 , 561 , 753 , 8047 , 419 , 4335 ,0 }; - static ulong[] dim2524KuoInit = { 1 , 3 , 3 , 15 , 31 , 3 , 97 , 177 , 443 , 55 , 1541 , 2627 , 6129 , 4165 , 3079 ,0 }; - static ulong[] dim2525KuoInit = { 1 , 1 , 1 , 9 , 13 , 13 , 13 , 29 , 309 , 679 , 1893 , 3629 , 513 , 16333 , 25371 ,0 }; - static ulong[] dim2526KuoInit = { 1 , 3 , 1 , 5 , 3 , 23 , 85 , 169 , 143 , 537 , 1387 , 3997 , 3659 , 12107 , 11689 ,0 }; - static ulong[] dim2527KuoInit = { 1 , 1 , 1 , 5 , 9 , 7 , 11 , 59 , 325 , 855 , 1853 , 855 , 5743 , 7625 , 10381 ,0 }; - static ulong[] dim2528KuoInit = { 1 , 3 , 3 , 3 , 5 , 37 , 109 , 101 , 243 , 301 , 1849 , 1633 , 4451 , 8859 , 22017 ,0 }; - static ulong[] dim2529KuoInit = { 1 , 3 , 5 , 1 , 7 , 1 , 9 , 1 , 411 , 941 , 153 , 2709 , 389 , 9403 , 24103 ,0 }; - static ulong[] dim2530KuoInit = { 1 , 1 , 1 , 15 , 17 , 19 , 105 , 127 , 271 , 543 , 449 , 1385 , 7387 , 8335 , 741 ,0 }; - static ulong[] dim2531KuoInit = { 1 , 3 , 7 , 5 , 23 , 21 , 43 , 17 , 357 , 499 , 649 , 1121 , 7655 , 15623 , 12975 ,0 }; - static ulong[] dim2532KuoInit = { 1 , 1 , 5 , 5 , 1 , 57 , 37 , 91 , 159 , 1013 , 653 , 3371 , 4857 , 441 , 17729 ,0 }; - static ulong[] dim2533KuoInit = { 1 , 3 , 7 , 15 , 15 , 31 , 71 , 77 , 113 , 47 , 1597 , 43 , 1139 , 3191 , 31775 ,0 }; - static ulong[] dim2534KuoInit = { 1 , 1 , 1 , 13 , 19 , 39 , 93 , 15 , 433 , 867 , 1091 , 2333 , 6113 , 13005 , 13309 ,0 }; - static ulong[] dim2535KuoInit = { 1 , 1 , 1 , 9 , 5 , 57 , 21 , 7 , 267 , 79 , 1829 , 43 , 211 , 2795 , 18739 ,0 }; - static ulong[] dim2536KuoInit = { 1 , 1 , 5 , 13 , 25 , 59 , 93 , 213 , 23 , 281 , 625 , 439 , 1449 , 2259 , 31713 ,0 }; - static ulong[] dim2537KuoInit = { 1 , 1 , 1 , 3 , 9 , 13 , 41 , 171 , 365 , 907 , 395 , 3465 , 6433 , 33 , 17191 ,0 }; - static ulong[] dim2538KuoInit = { 1 , 1 , 1 , 5 , 3 , 41 , 45 , 55 , 413 , 579 , 1215 , 3983 , 1201 , 3019 , 16401 ,0 }; - static ulong[] dim2539KuoInit = { 1 , 1 , 3 , 3 , 9 , 25 , 111 , 33 , 359 , 427 , 63 , 4005 , 2753 , 15063 , 1925 ,0 }; - static ulong[] dim2540KuoInit = { 1 , 1 , 5 , 3 , 21 , 55 , 15 , 5 , 121 , 867 , 1645 , 2387 , 1167 , 13865 , 15899 ,0 }; - static ulong[] dim2541KuoInit = { 1 , 3 , 5 , 15 , 13 , 49 , 9 , 173 , 291 , 517 , 143 , 399 , 7545 , 7225 , 29753 ,0 }; - static ulong[] dim2542KuoInit = { 1 , 1 , 3 , 5 , 29 , 23 , 105 , 165 , 35 , 325 , 983 , 215 , 2537 , 8661 , 1715 ,0 }; - static ulong[] dim2543KuoInit = { 1 , 3 , 7 , 7 , 19 , 1 , 91 , 77 , 311 , 715 , 347 , 1705 , 1045 , 15003 , 10961 ,0 }; - static ulong[] dim2544KuoInit = { 1 , 1 , 1 , 15 , 5 , 3 , 73 , 159 , 113 , 201 , 257 , 181 , 551 , 1189 , 30719 ,0 }; - static ulong[] dim2545KuoInit = { 1 , 1 , 1 , 3 , 15 , 57 , 69 , 85 , 133 , 735 , 429 , 2087 , 1453 , 14277 , 15245 ,0 }; - static ulong[] dim2546KuoInit = { 1 , 3 , 1 , 1 , 27 , 5 , 27 , 247 , 401 , 841 , 1723 , 3717 , 3545 , 3123 , 27441 ,0 }; - static ulong[] dim2547KuoInit = { 1 , 3 , 1 , 15 , 5 , 11 , 97 , 117 , 331 , 843 , 1101 , 2977 , 5123 , 5761 , 2019 ,0 }; - static ulong[] dim2548KuoInit = { 1 , 3 , 1 , 5 , 31 , 25 , 53 , 191 , 265 , 961 , 1695 , 1847 , 6377 , 13261 , 8853 ,0 }; - static ulong[] dim2549KuoInit = { 1 , 3 , 1 , 5 , 5 , 29 , 85 , 3 , 127 , 407 , 1511 , 549 , 4015 , 15327 , 9167 ,0 }; - static ulong[] dim2550KuoInit = { 1 , 3 , 5 , 3 , 9 , 11 , 1 , 217 , 53 , 201 , 1237 , 2663 , 7429 , 7349 , 5619 ,0 }; - static ulong[] dim2551KuoInit = { 1 , 3 , 3 , 15 , 13 , 63 , 21 , 173 , 59 , 881 , 351 , 1285 , 7155 , 6665 , 25117 ,0 }; - static ulong[] dim2552KuoInit = { 1 , 1 , 3 , 3 , 3 , 43 , 103 , 227 , 397 , 75 , 1211 , 2959 , 3507 , 3105 , 21739 ,0 }; - static ulong[] dim2553KuoInit = { 1 , 1 , 3 , 11 , 1 , 1 , 5 , 3 , 41 , 243 , 1317 , 2205 , 4079 , 7447 , 22493 ,0 }; - static ulong[] dim2554KuoInit = { 1 , 3 , 1 , 3 , 7 , 39 , 23 , 171 , 263 , 375 , 805 , 2309 , 7123 , 4935 , 4517 ,0 }; - static ulong[] dim2555KuoInit = { 1 , 1 , 5 , 15 , 5 , 47 , 35 , 15 , 131 , 875 , 1771 , 3001 , 951 , 14269 , 6395 ,0 }; - static ulong[] dim2556KuoInit = { 1 , 1 , 3 , 9 , 27 , 1 , 59 , 247 , 295 , 229 , 309 , 213 , 6661 , 10415 , 17855 ,0 }; - static ulong[] dim2557KuoInit = { 1 , 3 , 5 , 1 , 15 , 61 , 47 , 175 , 279 , 221 , 1665 , 3475 , 4171 , 15515 , 30835 ,0 }; - static ulong[] dim2558KuoInit = { 1 , 3 , 3 , 15 , 29 , 21 , 61 , 123 , 57 , 839 , 399 , 3069 , 4617 , 7051 , 3245 ,0 }; - static ulong[] dim2559KuoInit = { 1 , 3 , 7 , 11 , 27 , 57 , 83 , 163 , 499 , 901 , 855 , 2049 , 2993 , 10323 , 3391 ,0 }; - static ulong[] dim2560KuoInit = { 1 , 1 , 7 , 5 , 17 , 5 , 23 , 51 , 445 , 639 , 811 , 139 , 2863 , 9447 , 25971 ,0 }; - static ulong[] dim2561KuoInit = { 1 , 3 , 3 , 13 , 31 , 43 , 75 , 251 , 9 , 239 , 1573 , 871 , 2211 , 15057 , 879 ,0 }; - static ulong[] dim2562KuoInit = { 1 , 1 , 5 , 11 , 23 , 39 , 69 , 79 , 335 , 729 , 1807 , 1497 , 2363 , 8713 , 3987 ,0 }; - static ulong[] dim2563KuoInit = { 1 , 3 , 5 , 11 , 27 , 9 , 1 , 5 , 207 , 217 , 1097 , 2737 , 6815 , 9969 , 21731 ,0 }; - static ulong[] dim2564KuoInit = { 1 , 3 , 3 , 15 , 9 , 33 , 71 , 85 , 15 , 323 , 1955 , 1299 , 4439 , 6413 , 23055 ,0 }; - static ulong[] dim2565KuoInit = { 1 , 3 , 5 , 13 , 15 , 11 , 75 , 201 , 5 , 69 , 1067 , 2287 , 8099 , 11293 , 22547 ,0 }; - static ulong[] dim2566KuoInit = { 1 , 3 , 1 , 7 , 19 , 1 , 63 , 195 , 463 , 463 , 1741 , 915 , 1289 , 11275 , 16383 ,0 }; - static ulong[] dim2567KuoInit = { 1 , 1 , 7 , 3 , 3 , 53 , 51 , 95 , 389 , 385 , 1621 , 955 , 137 , 8523 , 24087 ,0 }; - static ulong[] dim2568KuoInit = { 1 , 3 , 5 , 11 , 25 , 27 , 49 , 27 , 459 , 979 , 277 , 2917 , 6639 , 3471 , 20407 ,0 }; - static ulong[] dim2569KuoInit = { 1 , 1 , 5 , 3 , 19 , 25 , 75 , 47 , 395 , 269 , 1445 , 287 , 4563 , 8817 , 10645 ,0 }; - static ulong[] dim2570KuoInit = { 1 , 1 , 1 , 15 , 5 , 9 , 59 , 177 , 463 , 683 , 1917 , 1189 , 2423 , 6967 , 433 ,0 }; - static ulong[] dim2571KuoInit = { 1 , 3 , 5 , 7 , 11 , 53 , 101 , 81 , 89 , 419 , 1605 , 3719 , 5449 , 4303 , 11235 ,0 }; - static ulong[] dim2572KuoInit = { 1 , 1 , 7 , 15 , 7 , 55 , 5 , 133 , 273 , 757 , 313 , 3451 , 7837 , 14543 , 1607 ,0 }; - static ulong[] dim2573KuoInit = { 1 , 3 , 7 , 11 , 9 , 13 , 103 , 95 , 301 , 637 , 1951 , 2577 , 2571 , 7881 , 27057 ,0 }; - static ulong[] dim2574KuoInit = { 1 , 3 , 3 , 9 , 25 , 17 , 119 , 11 , 7 , 141 , 1219 , 3091 , 1737 , 16355 , 2807 ,0 }; - static ulong[] dim2575KuoInit = { 1 , 1 , 1 , 1 , 3 , 55 , 59 , 193 , 23 , 643 , 159 , 3393 , 2671 , 14737 , 21193 ,0 }; - static ulong[] dim2576KuoInit = { 1 , 3 , 5 , 9 , 9 , 11 , 109 , 227 , 333 , 861 , 915 , 3239 , 6199 , 9555 , 28563 ,0 }; - static ulong[] dim2577KuoInit = { 1 , 3 , 3 , 9 , 1 , 33 , 51 , 169 , 291 , 159 , 1983 , 173 , 4133 , 11477 , 31525 ,0 }; - static ulong[] dim2578KuoInit = { 1 , 3 , 5 , 5 , 31 , 39 , 47 , 195 , 421 , 949 , 311 , 1537 , 8009 , 6273 , 10893 ,0 }; - static ulong[] dim2579KuoInit = { 1 , 1 , 1 , 1 , 17 , 19 , 37 , 211 , 245 , 553 , 769 , 2131 , 2819 , 16119 , 25851 ,0 }; - static ulong[] dim2580KuoInit = { 1 , 3 , 3 , 13 , 7 , 3 , 63 , 141 , 465 , 367 , 949 , 3997 , 5217 , 3425 , 31161 ,0 }; - static ulong[] dim2581KuoInit = { 1 , 3 , 3 , 5 , 19 , 35 , 91 , 115 , 153 , 127 , 231 , 3723 , 7911 , 4421 , 2271 ,0 }; - static ulong[] dim2582KuoInit = { 1 , 3 , 5 , 9 , 17 , 57 , 49 , 151 , 263 , 89 , 1635 , 2991 , 7011 , 13243 , 1473 ,0 }; - static ulong[] dim2583KuoInit = { 1 , 1 , 1 , 15 , 21 , 59 , 53 , 179 , 113 , 839 , 649 , 2083 , 7015 , 5507 , 9539 ,0 }; - static ulong[] dim2584KuoInit = { 1 , 1 , 1 , 1 , 13 , 49 , 97 , 81 , 255 , 973 , 275 , 2005 , 5493 , 11019 , 14427 ,0 }; - static ulong[] dim2585KuoInit = { 1 , 1 , 7 , 5 , 5 , 53 , 27 , 197 , 269 , 699 , 285 , 3725 , 7681 , 3767 , 11881 ,0 }; - static ulong[] dim2586KuoInit = { 1 , 1 , 1 , 13 , 15 , 15 , 11 , 245 , 419 , 559 , 727 , 1545 , 1821 , 5655 , 26971 ,0 }; - static ulong[] dim2587KuoInit = { 1 , 1 , 3 , 3 , 5 , 1 , 77 , 211 , 139 , 949 , 1945 , 3327 , 6699 , 6227 , 9769 ,0 }; - static ulong[] dim2588KuoInit = { 1 , 3 , 1 , 1 , 3 , 9 , 113 , 17 , 283 , 939 , 1941 , 19 , 7431 , 14503 , 24541 ,0 }; - static ulong[] dim2589KuoInit = { 1 , 1 , 1 , 3 , 1 , 57 , 17 , 85 , 371 , 491 , 775 , 2093 , 5615 , 4977 , 30995 ,0 }; - static ulong[] dim2590KuoInit = { 1 , 1 , 3 , 3 , 1 , 61 , 75 , 163 , 307 , 527 , 1821 , 1291 , 5761 , 9983 , 4647 ,0 }; - static ulong[] dim2591KuoInit = { 1 , 1 , 1 , 13 , 7 , 61 , 9 , 203 , 255 , 293 , 1683 , 1081 , 3179 , 13283 , 13759 ,0 }; - static ulong[] dim2592KuoInit = { 1 , 1 , 5 , 5 , 5 , 25 , 23 , 97 , 37 , 277 , 1787 , 2709 , 6201 , 8041 , 2301 ,0 }; - static ulong[] dim2593KuoInit = { 1 , 3 , 1 , 1 , 21 , 57 , 33 , 13 , 307 , 427 , 1577 , 2043 , 8131 , 11723 , 14353 ,0 }; - static ulong[] dim2594KuoInit = { 1 , 1 , 3 , 5 , 19 , 39 , 63 , 11 , 139 , 173 , 517 , 1597 , 3871 , 15533 , 4123 ,0 }; - static ulong[] dim2595KuoInit = { 1 , 3 , 1 , 11 , 19 , 43 , 123 , 127 , 237 , 599 , 893 , 3645 , 947 , 12565 , 9367 ,0 }; - static ulong[] dim2596KuoInit = { 1 , 1 , 7 , 11 , 27 , 9 , 119 , 251 , 499 , 777 , 1667 , 1699 , 3431 , 2727 , 7097 ,0 }; - static ulong[] dim2597KuoInit = { 1 , 1 , 1 , 11 , 7 , 25 , 95 , 143 , 319 , 659 , 1567 , 1391 , 5149 , 15177 , 6583 ,0 }; - static ulong[] dim2598KuoInit = { 1 , 3 , 1 , 13 , 7 , 39 , 125 , 219 , 405 , 739 , 1267 , 3065 , 7529 , 3195 , 21889 ,0 }; - static ulong[] dim2599KuoInit = { 1 , 3 , 3 , 9 , 27 , 13 , 87 , 129 , 451 , 997 , 103 , 1667 , 545 , 6341 , 3105 ,0 }; - static ulong[] dim2600KuoInit = { 1 , 1 , 5 , 3 , 11 , 43 , 95 , 205 , 445 , 919 , 1353 , 2435 , 269 , 3221 , 8983 ,0 }; - static ulong[] dim2601KuoInit = { 1 , 1 , 3 , 1 , 5 , 47 , 15 , 127 , 47 , 89 , 1409 , 1935 , 2047 , 10629 , 4867 ,0 }; - static ulong[] dim2602KuoInit = { 1 , 1 , 5 , 9 , 21 , 51 , 31 , 175 , 337 , 643 , 1233 , 1049 , 569 , 3383 , 18771 ,0 }; - static ulong[] dim2603KuoInit = { 1 , 1 , 7 , 11 , 7 , 7 , 29 , 139 , 65 , 621 , 363 , 513 , 4149 , 5225 , 11595 ,0 }; - static ulong[] dim2604KuoInit = { 1 , 1 , 7 , 7 , 11 , 31 , 43 , 223 , 249 , 661 , 123 , 2725 , 5179 , 13237 , 10483 ,0 }; - static ulong[] dim2605KuoInit = { 1 , 1 , 5 , 3 , 5 , 35 , 121 , 193 , 33 , 343 , 413 , 1879 , 8013 , 11161 , 7945 ,0 }; - static ulong[] dim2606KuoInit = { 1 , 3 , 7 , 5 , 27 , 43 , 123 , 25 , 45 , 279 , 979 , 1121 , 1041 , 3757 , 22217 ,0 }; - static ulong[] dim2607KuoInit = { 1 , 3 , 5 , 1 , 29 , 45 , 29 , 215 , 39 , 679 , 799 , 1491 , 885 , 15475 , 29269 ,0 }; - static ulong[] dim2608KuoInit = { 1 , 1 , 3 , 1 , 1 , 5 , 49 , 181 , 441 , 691 , 639 , 859 , 2785 , 3237 , 1703 ,0 }; - static ulong[] dim2609KuoInit = { 1 , 1 , 1 , 9 , 19 , 1 , 41 , 131 , 469 , 999 , 1665 , 2309 , 4447 , 13851 , 7063 ,0 }; - static ulong[] dim2610KuoInit = { 1 , 3 , 5 , 3 , 21 , 53 , 51 , 155 , 41 , 43 , 127 , 1653 , 6237 , 10481 , 22557 ,0 }; - static ulong[] dim2611KuoInit = { 1 , 3 , 5 , 7 , 31 , 21 , 39 , 177 , 283 , 535 , 771 , 3783 , 3033 , 10971 , 8691 ,0 }; - static ulong[] dim2612KuoInit = { 1 , 1 , 3 , 1 , 25 , 57 , 13 , 139 , 169 , 717 , 795 , 2337 , 7347 , 6951 , 20509 ,0 }; - static ulong[] dim2613KuoInit = { 1 , 1 , 5 , 11 , 1 , 29 , 27 , 21 , 259 , 889 , 83 , 3295 , 3699 , 1523 , 6227 ,0 }; - static ulong[] dim2614KuoInit = { 1 , 3 , 5 , 3 , 9 , 37 , 35 , 95 , 217 , 335 , 865 , 3093 , 3077 , 9831 , 12173 ,0 }; - static ulong[] dim2615KuoInit = { 1 , 1 , 7 , 13 , 31 , 7 , 69 , 193 , 459 , 967 , 481 , 3271 , 677 , 13131 , 22665 ,0 }; - static ulong[] dim2616KuoInit = { 1 , 3 , 3 , 9 , 13 , 31 , 43 , 155 , 465 , 303 , 1153 , 1591 , 7793 , 921 , 12805 ,0 }; - static ulong[] dim2617KuoInit = { 1 , 1 , 5 , 5 , 23 , 59 , 3 , 151 , 391 , 729 , 913 , 899 , 1793 , 10173 , 19681 ,0 }; - static ulong[] dim2618KuoInit = { 1 , 3 , 1 , 5 , 31 , 21 , 19 , 219 , 311 , 1013 , 227 , 1813 , 3103 , 14191 , 22995 ,0 }; - static ulong[] dim2619KuoInit = { 1 , 1 , 3 , 5 , 3 , 59 , 11 , 191 , 433 , 63 , 465 , 3505 , 6801 , 3047 , 16913 ,0 }; - static ulong[] dim2620KuoInit = { 1 , 1 , 7 , 9 , 19 , 3 , 95 , 203 , 1 , 679 , 1719 , 269 , 1747 , 9465 , 24445 ,0 }; - static ulong[] dim2621KuoInit = { 1 , 1 , 7 , 9 , 9 , 17 , 79 , 45 , 179 , 863 , 801 , 2825 , 5345 , 637 , 9729 ,0 }; - static ulong[] dim2622KuoInit = { 1 , 3 , 7 , 11 , 11 , 59 , 45 , 107 , 45 , 891 , 629 , 443 , 805 , 15277 , 1961 ,0 }; - static ulong[] dim2623KuoInit = { 1 , 1 , 3 , 5 , 9 , 49 , 123 , 183 , 13 , 867 , 261 , 3883 , 2479 , 8221 , 3327 ,0 }; - static ulong[] dim2624KuoInit = { 1 , 1 , 5 , 11 , 19 , 19 , 95 , 85 , 351 , 861 , 1499 , 3697 , 7369 , 10757 , 16445 ,0 }; - static ulong[] dim2625KuoInit = { 1 , 3 , 5 , 5 , 27 , 13 , 119 , 243 , 437 , 655 , 955 , 1919 , 3643 , 12389 , 6865 ,0 }; - static ulong[] dim2626KuoInit = { 1 , 3 , 3 , 1 , 23 , 15 , 43 , 65 , 87 , 833 , 503 , 999 , 703 , 4411 , 3343 ,0 }; - static ulong[] dim2627KuoInit = { 1 , 3 , 7 , 1 , 31 , 13 , 67 , 199 , 261 , 257 , 1767 , 3983 , 823 , 149 , 32353 ,0 }; - static ulong[] dim2628KuoInit = { 1 , 3 , 1 , 15 , 15 , 17 , 69 , 237 , 441 , 657 , 1125 , 3377 , 5971 , 15477 , 31363 ,0 }; - static ulong[] dim2629KuoInit = { 1 , 3 , 1 , 13 , 3 , 55 , 67 , 93 , 315 , 1015 , 61 , 35 , 3059 , 15503 , 16811 ,0 }; - static ulong[] dim2630KuoInit = { 1 , 1 , 3 , 9 , 1 , 51 , 91 , 213 , 3 , 37 , 849 , 2329 , 2237 , 6189 , 625 ,0 }; - static ulong[] dim2631KuoInit = { 1 , 1 , 5 , 7 , 25 , 3 , 57 , 103 , 401 , 357 , 461 , 2677 , 6059 , 291 , 11461 ,0 }; - static ulong[] dim2632KuoInit = { 1 , 1 , 5 , 7 , 23 , 29 , 119 , 61 , 121 , 535 , 251 , 565 , 7307 , 1085 , 8429 ,0 }; - static ulong[] dim2633KuoInit = { 1 , 1 , 3 , 13 , 23 , 19 , 63 , 155 , 5 , 617 , 9 , 715 , 5399 , 1747 , 17633 ,0 }; - static ulong[] dim2634KuoInit = { 1 , 1 , 1 , 13 , 3 , 57 , 13 , 161 , 123 , 389 , 1695 , 4083 , 1957 , 11359 , 18961 ,0 }; - static ulong[] dim2635KuoInit = { 1 , 1 , 3 , 15 , 27 , 25 , 65 , 15 , 205 , 695 , 995 , 1471 , 1131 , 11435 , 22107 ,0 }; - static ulong[] dim2636KuoInit = { 1 , 3 , 3 , 11 , 31 , 29 , 109 , 121 , 81 , 15 , 1087 , 299 , 3495 , 14137 , 19073 ,0 }; - static ulong[] dim2637KuoInit = { 1 , 3 , 3 , 15 , 23 , 23 , 117 , 55 , 215 , 287 , 1421 , 731 , 279 , 15497 , 15545 ,0 }; - static ulong[] dim2638KuoInit = { 1 , 3 , 5 , 15 , 1 , 31 , 95 , 249 , 403 , 239 , 771 , 1279 , 1863 , 12893 , 21043 ,0 }; - static ulong[] dim2639KuoInit = { 1 , 3 , 1 , 9 , 21 , 23 , 123 , 169 , 69 , 591 , 621 , 1697 , 5867 , 5193 , 16573 ,0 }; - static ulong[] dim2640KuoInit = { 1 , 3 , 3 , 5 , 29 , 19 , 105 , 177 , 143 , 141 , 1455 , 3119 , 347 , 8797 , 3925 ,0 }; - static ulong[] dim2641KuoInit = { 1 , 3 , 3 , 15 , 9 , 11 , 41 , 169 , 141 , 555 , 1761 , 3441 , 2245 , 14205 , 9769 ,0 }; - static ulong[] dim2642KuoInit = { 1 , 1 , 1 , 5 , 9 , 33 , 125 , 203 , 333 , 461 , 551 , 569 , 1305 , 10213 , 24549 ,0 }; - static ulong[] dim2643KuoInit = { 1 , 1 , 7 , 13 , 21 , 9 , 99 , 43 , 395 , 667 , 121 , 1225 , 7835 , 8327 , 17717 ,0 }; - static ulong[] dim2644KuoInit = { 1 , 3 , 3 , 7 , 21 , 9 , 31 , 59 , 321 , 505 , 1357 , 3213 , 4219 , 10637 , 11127 ,0 }; - static ulong[] dim2645KuoInit = { 1 , 1 , 1 , 7 , 17 , 49 , 77 , 243 , 189 , 115 , 1339 , 2023 , 7431 , 5087 , 24495 ,0 }; - static ulong[] dim2646KuoInit = { 1 , 1 , 1 , 11 , 1 , 39 , 41 , 51 , 315 , 383 , 237 , 3877 , 5731 , 11 , 21307 ,0 }; - static ulong[] dim2647KuoInit = { 1 , 1 , 7 , 5 , 5 , 3 , 17 , 227 , 483 , 395 , 1251 , 1265 , 3965 , 15203 , 17163 ,0 }; - static ulong[] dim2648KuoInit = { 1 , 3 , 7 , 7 , 23 , 41 , 53 , 45 , 43 , 989 , 629 , 1557 , 2891 , 4613 , 3647 ,0 }; - static ulong[] dim2649KuoInit = { 1 , 3 , 3 , 5 , 15 , 39 , 35 , 127 , 267 , 45 , 1299 , 2251 , 7363 , 13595 , 31061 ,0 }; - static ulong[] dim2650KuoInit = { 1 , 3 , 7 , 15 , 23 , 45 , 99 , 153 , 419 , 727 , 1077 , 3407 , 4861 , 3697 , 14479 ,0 }; - static ulong[] dim2651KuoInit = { 1 , 3 , 5 , 15 , 19 , 21 , 123 , 173 , 295 , 47 , 1977 , 1185 , 7403 , 11901 , 29753 ,0 }; - static ulong[] dim2652KuoInit = { 1 , 1 , 3 , 13 , 21 , 53 , 83 , 151 , 309 , 293 , 439 , 2381 , 7965 , 3449 , 8861 ,0 }; - static ulong[] dim2653KuoInit = { 1 , 1 , 1 , 3 , 31 , 49 , 61 , 81 , 327 , 173 , 111 , 3893 , 2621 , 1409 , 13255 ,0 }; - static ulong[] dim2654KuoInit = { 1 , 3 , 5 , 5 , 3 , 13 , 75 , 71 , 271 , 689 , 369 , 2719 , 759 , 8691 , 24611 ,0 }; - static ulong[] dim2655KuoInit = { 1 , 1 , 1 , 5 , 21 , 7 , 69 , 17 , 347 , 699 , 1581 , 1095 , 1727 , 8213 , 5033 ,0 }; - static ulong[] dim2656KuoInit = { 1 , 1 , 1 , 1 , 23 , 41 , 85 , 233 , 43 , 863 , 553 , 2625 , 2323 , 7471 , 12457 ,0 }; - static ulong[] dim2657KuoInit = { 1 , 1 , 3 , 15 , 3 , 7 , 99 , 27 , 173 , 539 , 113 , 2309 , 1771 , 11709 , 29703 ,0 }; - static ulong[] dim2658KuoInit = { 1 , 3 , 1 , 1 , 7 , 43 , 73 , 91 , 151 , 961 , 251 , 2089 , 4475 , 2745 , 6077 ,0 }; - static ulong[] dim2659KuoInit = { 1 , 1 , 3 , 7 , 15 , 61 , 91 , 139 , 161 , 613 , 603 , 1587 , 3995 , 9241 , 24467 ,0 }; - static ulong[] dim2660KuoInit = { 1 , 1 , 1 , 3 , 1 , 21 , 7 , 157 , 311 , 451 , 137 , 3289 , 5583 , 5107 , 24471 ,0 }; - static ulong[] dim2661KuoInit = { 1 , 1 , 7 , 9 , 15 , 3 , 7 , 19 , 375 , 265 , 1781 , 335 , 233 , 3569 , 21407 ,0 }; - static ulong[] dim2662KuoInit = { 1 , 1 , 5 , 13 , 7 , 53 , 81 , 79 , 355 , 89 , 1233 , 267 , 6523 , 8819 , 30595 ,0 }; - static ulong[] dim2663KuoInit = { 1 , 1 , 7 , 7 , 1 , 59 , 65 , 93 , 251 , 565 , 1575 , 2709 , 7845 , 13355 , 6043 ,0 }; - static ulong[] dim2664KuoInit = { 1 , 1 , 5 , 7 , 9 , 21 , 71 , 97 , 383 , 189 , 3 , 1841 , 1403 , 9649 , 25053 ,0 }; - static ulong[] dim2665KuoInit = { 1 , 3 , 5 , 9 , 25 , 47 , 41 , 63 , 177 , 551 , 1389 , 1639 , 4209 , 15787 , 26499 ,0 }; - static ulong[] dim2666KuoInit = { 1 , 1 , 3 , 15 , 29 , 53 , 119 , 3 , 33 , 677 , 207 , 1239 , 453 , 6281 , 26701 ,0 }; - static ulong[] dim2667KuoInit = { 1 , 3 , 5 , 13 , 7 , 37 , 87 , 241 , 477 , 765 , 1511 , 2659 , 1043 , 313 , 27957 ,0 }; - static ulong[] dim2668KuoInit = { 1 , 3 , 5 , 3 , 1 , 31 , 101 , 27 , 401 , 547 , 617 , 3605 , 4899 , 5093 , 19933 ,0 }; - static ulong[] dim2669KuoInit = { 1 , 1 , 7 , 13 , 7 , 45 , 127 , 191 , 439 , 383 , 745 , 3143 , 2083 , 2941 , 31981 ,0 }; - static ulong[] dim2670KuoInit = { 1 , 3 , 3 , 13 , 7 , 15 , 31 , 203 , 75 , 297 , 603 , 2945 , 1823 , 12359 , 29245 ,0 }; - static ulong[] dim2671KuoInit = { 1 , 3 , 7 , 15 , 1 , 57 , 35 , 255 , 77 , 483 , 1051 , 1999 , 4975 , 16211 , 22903 ,0 }; - static ulong[] dim2672KuoInit = { 1 , 1 , 5 , 5 , 23 , 53 , 13 , 251 , 181 , 1011 , 983 , 3735 , 4221 , 5557 , 25777 ,0 }; - static ulong[] dim2673KuoInit = { 1 , 1 , 1 , 11 , 13 , 51 , 21 , 155 , 293 , 79 , 1015 , 2653 , 2959 , 9913 , 17751 ,0 }; - static ulong[] dim2674KuoInit = { 1 , 1 , 5 , 3 , 17 , 33 , 27 , 125 , 437 , 663 , 343 , 1799 , 2129 , 7993 , 1373 ,0 }; - static ulong[] dim2675KuoInit = { 1 , 3 , 3 , 3 , 9 , 17 , 31 , 123 , 453 , 853 , 1221 , 2863 , 4637 , 8239 , 27233 ,0 }; - static ulong[] dim2676KuoInit = { 1 , 1 , 5 , 1 , 7 , 19 , 43 , 77 , 19 , 559 , 1397 , 1631 , 3187 , 1445 , 25437 ,0 }; - static ulong[] dim2677KuoInit = { 1 , 1 , 3 , 5 , 31 , 21 , 71 , 127 , 223 , 127 , 717 , 3163 , 2079 , 2399 , 16415 ,0 }; - static ulong[] dim2678KuoInit = { 1 , 1 , 1 , 13 , 17 , 13 , 99 , 227 , 127 , 625 , 1065 , 1779 , 7275 , 11865 , 17397 ,0 }; - static ulong[] dim2679KuoInit = { 1 , 3 , 3 , 11 , 31 , 43 , 27 , 231 , 103 , 873 , 949 , 1179 , 3149 , 2251 , 22993 ,0 }; - static ulong[] dim2680KuoInit = { 1 , 3 , 1 , 11 , 25 , 11 , 89 , 149 , 71 , 171 , 1985 , 3779 , 901 , 16307 , 5663 ,0 }; - static ulong[] dim2681KuoInit = { 1 , 1 , 3 , 5 , 1 , 25 , 125 , 241 , 167 , 381 , 407 , 2801 , 635 , 313 , 10199 ,0 }; - static ulong[] dim2682KuoInit = { 1 , 1 , 3 , 15 , 29 , 31 , 101 , 121 , 251 , 685 , 677 , 1683 , 3499 , 16193 , 7139 ,0 }; - static ulong[] dim2683KuoInit = { 1 , 3 , 5 , 3 , 7 , 13 , 27 , 101 , 7 , 159 , 2005 , 3297 , 2775 , 11193 , 17385 ,0 }; - static ulong[] dim2684KuoInit = { 1 , 1 , 5 , 5 , 25 , 31 , 119 , 43 , 317 , 371 , 1505 , 2631 , 1021 , 1297 , 22791 ,0 }; - static ulong[] dim2685KuoInit = { 1 , 3 , 5 , 7 , 17 , 57 , 63 , 229 , 97 , 599 , 1485 , 1113 , 403 , 77 , 25541 ,0 }; - static ulong[] dim2686KuoInit = { 1 , 1 , 7 , 13 , 11 , 43 , 29 , 85 , 335 , 943 , 1605 , 1757 , 2787 , 3313 , 14991 ,0 }; - static ulong[] dim2687KuoInit = { 1 , 3 , 7 , 13 , 17 , 43 , 5 , 231 , 441 , 883 , 465 , 841 , 2785 , 8193 , 7951 ,0 }; - static ulong[] dim2688KuoInit = { 1 , 3 , 1 , 3 , 27 , 33 , 1 , 215 , 295 , 381 , 283 , 219 , 3419 , 3343 , 17629 ,0 }; - static ulong[] dim2689KuoInit = { 1 , 1 , 5 , 9 , 5 , 49 , 107 , 179 , 281 , 223 , 1845 , 2505 , 2281 , 12051 , 12609 ,0 }; - static ulong[] dim2690KuoInit = { 1 , 1 , 7 , 13 , 21 , 13 , 109 , 183 , 385 , 293 , 773 , 3975 , 4737 , 8143 , 1335 ,0 }; - static ulong[] dim2691KuoInit = { 1 , 1 , 1 , 13 , 13 , 47 , 23 , 27 , 271 , 957 , 1937 , 4091 , 3563 , 4055 , 17595 ,0 }; - static ulong[] dim2692KuoInit = { 1 , 3 , 3 , 15 , 31 , 45 , 43 , 7 , 125 , 549 , 169 , 1567 , 5405 , 3919 , 21795 ,0 }; - static ulong[] dim2693KuoInit = { 1 , 3 , 5 , 7 , 5 , 53 , 121 , 107 , 217 , 745 , 861 , 481 , 5503 , 3723 , 12215 ,0 }; - static ulong[] dim2694KuoInit = { 1 , 3 , 7 , 3 , 23 , 27 , 91 , 175 , 477 , 289 , 817 , 2483 , 6071 , 5429 , 12923 ,0 }; - static ulong[] dim2695KuoInit = { 1 , 1 , 3 , 15 , 7 , 63 , 29 , 157 , 323 , 851 , 1941 , 1927 , 5165 , 9875 , 11809 ,0 }; - static ulong[] dim2696KuoInit = { 1 , 3 , 3 , 1 , 13 , 17 , 93 , 187 , 329 , 187 , 1417 , 1477 , 7891 , 11093 , 24705 ,0 }; - static ulong[] dim2697KuoInit = { 1 , 3 , 3 , 13 , 5 , 41 , 119 , 135 , 255 , 47 , 803 , 3941 , 1647 , 7777 , 17515 ,0 }; - static ulong[] dim2698KuoInit = { 1 , 1 , 5 , 9 , 25 , 11 , 15 , 231 , 81 , 267 , 1633 , 407 , 3319 , 12033 , 9651 ,0 }; - static ulong[] dim2699KuoInit = { 1 , 3 , 1 , 1 , 31 , 43 , 3 , 101 , 435 , 869 , 159 , 441 , 613 , 10283 , 6873 ,0 }; - static ulong[] dim2700KuoInit = { 1 , 1 , 5 , 1 , 11 , 55 , 7 , 65 , 357 , 595 , 1543 , 3957 , 6075 , 7265 , 27063 ,0 }; - static ulong[] dim2701KuoInit = { 1 , 3 , 3 , 11 , 23 , 23 , 41 , 205 , 197 , 863 , 695 , 971 , 39 , 12389 , 2983 ,0 }; - static ulong[] dim2702KuoInit = { 1 , 1 , 3 , 15 , 7 , 39 , 39 , 25 , 173 , 277 , 999 , 3797 , 3051 , 189 , 13559 ,0 }; - static ulong[] dim2703KuoInit = { 1 , 1 , 7 , 5 , 3 , 7 , 47 , 79 , 411 , 109 , 55 , 3803 , 6617 , 14317 , 9533 ,0 }; - static ulong[] dim2704KuoInit = { 1 , 1 , 3 , 9 , 31 , 17 , 53 , 97 , 495 , 995 , 1735 , 1055 , 6805 , 6865 , 23321 ,0 }; - static ulong[] dim2705KuoInit = { 1 , 3 , 7 , 13 , 3 , 63 , 37 , 185 , 311 , 995 , 1819 , 2633 , 2593 , 2107 , 15755 ,0 }; - static ulong[] dim2706KuoInit = { 1 , 3 , 7 , 11 , 25 , 37 , 79 , 179 , 435 , 167 , 147 , 2159 , 5909 , 10427 , 12487 ,0 }; - static ulong[] dim2707KuoInit = { 1 , 3 , 5 , 7 , 31 , 9 , 69 , 93 , 477 , 283 , 479 , 1895 , 5693 , 4809 , 3157 ,0 }; - static ulong[] dim2708KuoInit = { 1 , 1 , 3 , 11 , 27 , 21 , 11 , 3 , 157 , 1011 , 1473 , 2393 , 259 , 4155 , 28375 ,0 }; - static ulong[] dim2709KuoInit = { 1 , 3 , 1 , 9 , 7 , 11 , 73 , 215 , 289 , 933 , 1369 , 2911 , 3251 , 727 , 19237 ,0 }; - static ulong[] dim2710KuoInit = { 1 , 1 , 1 , 15 , 29 , 19 , 77 , 59 , 213 , 1005 , 2009 , 1899 , 5987 , 7429 , 5607 ,0 }; - static ulong[] dim2711KuoInit = { 1 , 1 , 1 , 13 , 7 , 53 , 79 , 151 , 443 , 911 , 1777 , 1223 , 663 , 2099 , 17297 ,0 }; - static ulong[] dim2712KuoInit = { 1 , 1 , 1 , 9 , 11 , 7 , 81 , 175 , 265 , 879 , 1867 , 539 , 2353 , 5667 , 4973 ,0 }; - static ulong[] dim2713KuoInit = { 1 , 1 , 1 , 9 , 23 , 63 , 35 , 57 , 139 , 653 , 1837 , 681 , 6993 , 643 , 21771 ,0 }; - static ulong[] dim2714KuoInit = { 1 , 3 , 7 , 9 , 11 , 13 , 123 , 199 , 405 , 373 , 1817 , 3331 , 5585 , 11721 , 9355 ,0 }; - static ulong[] dim2715KuoInit = { 1 , 1 , 7 , 7 , 27 , 29 , 79 , 121 , 399 , 85 , 531 , 507 , 4361 , 6167 , 29317 ,0 }; - static ulong[] dim2716KuoInit = { 1 , 1 , 7 , 11 , 13 , 19 , 75 , 245 , 197 , 731 , 233 , 487 , 2245 , 11413 , 31865 ,0 }; - static ulong[] dim2717KuoInit = { 1 , 1 , 7 , 5 , 27 , 43 , 109 , 135 , 91 , 475 , 209 , 865 , 2239 , 8065 , 23295 ,0 }; - static ulong[] dim2718KuoInit = { 1 , 1 , 1 , 9 , 13 , 27 , 101 , 121 , 23 , 319 , 873 , 251 , 299 , 7145 , 26225 ,0 }; - static ulong[] dim2719KuoInit = { 1 , 1 , 7 , 1 , 31 , 51 , 85 , 91 , 299 , 545 , 1557 , 2447 , 4055 , 3911 , 12805 ,0 }; - static ulong[] dim2720KuoInit = { 1 , 3 , 1 , 9 , 31 , 63 , 123 , 191 , 241 , 7 , 347 , 23 , 5135 , 7353 , 30865 ,0 }; - static ulong[] dim2721KuoInit = { 1 , 1 , 5 , 1 , 3 , 13 , 81 , 249 , 65 , 853 , 893 , 219 , 6555 , 4941 , 21669 ,0 }; - static ulong[] dim2722KuoInit = { 1 , 3 , 5 , 13 , 13 , 27 , 13 , 203 , 205 , 459 , 883 , 1723 , 2721 , 9173 , 9643 ,0 }; - static ulong[] dim2723KuoInit = { 1 , 1 , 5 , 5 , 11 , 59 , 109 , 25 , 107 , 1007 , 357 , 2877 , 5075 , 3251 , 29541 ,0 }; - static ulong[] dim2724KuoInit = { 1 , 1 , 1 , 15 , 19 , 37 , 99 , 183 , 267 , 571 , 49 , 975 , 2441 , 4459 , 15481 ,0 }; - static ulong[] dim2725KuoInit = { 1 , 3 , 1 , 1 , 21 , 7 , 89 , 233 , 209 , 151 , 1919 , 31 , 4363 , 9781 , 4683 ,0 }; - static ulong[] dim2726KuoInit = { 1 , 1 , 3 , 9 , 15 , 35 , 101 , 29 , 27 , 737 , 1577 , 2611 , 3727 , 2245 , 31889 ,0 }; - static ulong[] dim2727KuoInit = { 1 , 3 , 5 , 9 , 19 , 19 , 125 , 229 , 313 , 239 , 67 , 1373 , 6459 , 1339 , 19909 ,0 }; - static ulong[] dim2728KuoInit = { 1 , 3 , 3 , 13 , 19 , 35 , 17 , 31 , 183 , 391 , 1515 , 2357 , 2673 , 10055 , 943 ,0 }; - static ulong[] dim2729KuoInit = { 1 , 1 , 3 , 11 , 31 , 17 , 37 , 239 , 79 , 869 , 629 , 2755 , 7431 , 127 , 19155 ,0 }; - static ulong[] dim2730KuoInit = { 1 , 3 , 5 , 3 , 9 , 13 , 91 , 27 , 163 , 455 , 2007 , 2479 , 2387 , 1557 , 437 ,0 }; - static ulong[] dim2731KuoInit = { 1 , 1 , 1 , 13 , 15 , 63 , 11 , 105 , 51 , 673 , 997 , 2487 , 35 , 8655 , 21481 ,0 }; - static ulong[] dim2732KuoInit = { 1 , 3 , 5 , 11 , 1 , 3 , 27 , 117 , 195 , 233 , 269 , 2163 , 2083 , 8907 , 28005 ,0 }; - static ulong[] dim2733KuoInit = { 1 , 1 , 1 , 9 , 9 , 17 , 63 , 211 , 87 , 107 , 1183 , 2705 , 6811 , 9959 , 13937 ,0 }; - static ulong[] dim2734KuoInit = { 1 , 1 , 1 , 1 , 1 , 3 , 57 , 231 , 209 , 949 , 895 , 2773 , 237 , 8943 , 22453 ,0 }; - static ulong[] dim2735KuoInit = { 1 , 3 , 7 , 11 , 7 , 53 , 1 , 247 , 279 , 411 , 1247 , 2121 , 3127 , 16279 , 277 ,0 }; - static ulong[] dim2736KuoInit = { 1 , 3 , 5 , 5 , 15 , 35 , 15 , 15 , 485 , 763 , 1631 , 1717 , 191 , 6609 , 32383 ,0 }; - static ulong[] dim2737KuoInit = { 1 , 1 , 5 , 11 , 27 , 5 , 73 , 143 , 127 , 477 , 535 , 3815 , 3135 , 9865 , 5375 ,0 }; - static ulong[] dim2738KuoInit = { 1 , 1 , 7 , 9 , 21 , 31 , 83 , 63 , 313 , 775 , 875 , 4053 , 905 , 14255 , 31537 ,0 }; - static ulong[] dim2739KuoInit = { 1 , 1 , 1 , 3 , 7 , 3 , 107 , 231 , 333 , 935 , 1625 , 2527 , 2293 , 10407 , 4795 ,0 }; - static ulong[] dim2740KuoInit = { 1 , 3 , 5 , 7 , 25 , 19 , 123 , 193 , 353 , 353 , 1403 , 3007 , 677 , 15333 , 1263 ,0 }; - static ulong[] dim2741KuoInit = { 1 , 1 , 3 , 9 , 1 , 39 , 79 , 251 , 59 , 973 , 1707 , 2153 , 7445 , 9083 , 6675 ,0 }; - static ulong[] dim2742KuoInit = { 1 , 1 , 7 , 3 , 7 , 55 , 21 , 101 , 203 , 735 , 1789 , 3119 , 6633 , 3643 , 1947 ,0 }; - static ulong[] dim2743KuoInit = { 1 , 1 , 5 , 9 , 13 , 49 , 103 , 141 , 181 , 893 , 385 , 1541 , 5887 , 10687 , 16183 ,0 }; - static ulong[] dim2744KuoInit = { 1 , 3 , 3 , 7 , 17 , 59 , 35 , 119 , 467 , 77 , 1591 , 469 , 4991 , 8113 , 20231 ,0 }; - static ulong[] dim2745KuoInit = { 1 , 3 , 1 , 15 , 19 , 41 , 5 , 71 , 247 , 955 , 565 , 1931 , 2895 , 13189 , 28461 ,0 }; - static ulong[] dim2746KuoInit = { 1 , 3 , 5 , 9 , 19 , 21 , 123 , 39 , 175 , 35 , 673 , 107 , 3157 , 1495 , 16341 ,0 }; - static ulong[] dim2747KuoInit = { 1 , 1 , 3 , 9 , 31 , 25 , 9 , 17 , 463 , 585 , 1701 , 3325 , 6071 , 2719 , 4479 ,0 }; - static ulong[] dim2748KuoInit = { 1 , 3 , 3 , 15 , 25 , 51 , 63 , 241 , 289 , 787 , 1109 , 453 , 5119 , 139 , 377 ,0 }; - static ulong[] dim2749KuoInit = { 1 , 3 , 5 , 7 , 29 , 3 , 53 , 119 , 219 , 367 , 1785 , 777 , 5255 , 10013 , 27979 ,0 }; - static ulong[] dim2750KuoInit = { 1 , 1 , 1 , 3 , 1 , 45 , 3 , 239 , 429 , 595 , 1591 , 3111 , 2373 , 4121 , 12671 ,0 }; - static ulong[] dim2751KuoInit = { 1 , 3 , 3 , 9 , 5 , 49 , 11 , 145 , 167 , 19 , 155 , 2017 , 3593 , 15275 , 22319 ,0 }; - static ulong[] dim2752KuoInit = { 1 , 3 , 1 , 3 , 11 , 15 , 17 , 241 , 293 , 345 , 1663 , 301 , 627 , 12161 , 19939 ,0 }; - static ulong[] dim2753KuoInit = { 1 , 3 , 5 , 1 , 3 , 19 , 41 , 75 , 121 , 611 , 1741 , 4055 , 5567 , 773 , 767 ,0 }; - static ulong[] dim2754KuoInit = { 1 , 1 , 1 , 3 , 5 , 49 , 127 , 49 , 93 , 819 , 1391 , 2173 , 4021 , 11953 , 28465 ,0 }; - static ulong[] dim2755KuoInit = { 1 , 1 , 3 , 5 , 9 , 59 , 63 , 85 , 249 , 239 , 521 , 3333 , 6301 , 15283 , 10645 ,0 }; - static ulong[] dim2756KuoInit = { 1 , 1 , 1 , 7 , 9 , 53 , 107 , 201 , 151 , 79 , 1561 , 3497 , 4473 , 4369 , 6231 ,0 }; - static ulong[] dim2757KuoInit = { 1 , 1 , 1 , 9 , 11 , 61 , 57 , 69 , 215 , 637 , 1087 , 2827 , 2495 , 7471 , 19127 ,0 }; - static ulong[] dim2758KuoInit = { 1 , 1 , 1 , 13 , 3 , 25 , 87 , 131 , 171 , 577 , 957 , 989 , 3391 , 3803 , 27229 ,0 }; - static ulong[] dim2759KuoInit = { 1 , 1 , 5 , 5 , 1 , 25 , 83 , 71 , 161 , 477 , 573 , 3709 , 4393 , 4607 , 32373 ,0 }; - static ulong[] dim2760KuoInit = { 1 , 1 , 7 , 5 , 13 , 21 , 19 , 71 , 207 , 433 , 849 , 2685 , 4455 , 463 , 25163 ,0 }; - static ulong[] dim2761KuoInit = { 1 , 1 , 7 , 3 , 5 , 19 , 35 , 41 , 487 , 3 , 865 , 25 , 7925 , 9015 , 29397 ,0 }; - static ulong[] dim2762KuoInit = { 1 , 1 , 7 , 3 , 7 , 41 , 83 , 27 , 79 , 501 , 267 , 2015 , 8109 , 8877 , 4029 ,0 }; - static ulong[] dim2763KuoInit = { 1 , 3 , 5 , 1 , 1 , 31 , 71 , 233 , 167 , 185 , 33 , 1249 , 3755 , 2805 , 29559 ,0 }; - static ulong[] dim2764KuoInit = { 1 , 1 , 1 , 7 , 11 , 21 , 111 , 105 , 469 , 527 , 711 , 3551 , 521 , 10593 , 22701 ,0 }; - static ulong[] dim2765KuoInit = { 1 , 1 , 1 , 1 , 29 , 1 , 79 , 109 , 279 , 643 , 1263 , 2405 , 3717 , 11395 , 4325 ,0 }; - static ulong[] dim2766KuoInit = { 1 , 1 , 1 , 1 , 29 , 47 , 59 , 1 , 195 , 399 , 1963 , 265 , 317 , 15117 , 9935 ,0 }; - static ulong[] dim2767KuoInit = { 1 , 1 , 7 , 5 , 21 , 43 , 93 , 113 , 273 , 67 , 281 , 477 , 6309 , 3649 , 20147 ,0 }; - static ulong[] dim2768KuoInit = { 1 , 1 , 3 , 15 , 29 , 61 , 69 , 151 , 185 , 809 , 993 , 2383 , 7263 , 901 , 18607 ,0 }; - static ulong[] dim2769KuoInit = { 1 , 1 , 3 , 9 , 27 , 33 , 25 , 103 , 387 , 131 , 1555 , 301 , 1471 , 11331 , 15091 ,0 }; - static ulong[] dim2770KuoInit = { 1 , 1 , 7 , 7 , 19 , 55 , 115 , 121 , 99 , 371 , 1563 , 895 , 6207 , 93 , 8549 ,0 }; - static ulong[] dim2771KuoInit = { 1 , 1 , 1 , 9 , 19 , 23 , 13 , 181 , 281 , 479 , 1 , 1515 , 3853 , 8601 , 19241 ,0 }; - static ulong[] dim2772KuoInit = { 1 , 3 , 1 , 15 , 29 , 63 , 113 , 253 , 105 , 421 , 1679 , 2113 , 4671 , 7923 , 7671 ,0 }; - static ulong[] dim2773KuoInit = { 1 , 3 , 1 , 3 , 17 , 9 , 15 , 241 , 339 , 619 , 417 , 3257 , 5917 , 9981 , 19033 ,0 }; - static ulong[] dim2774KuoInit = { 1 , 3 , 3 , 13 , 21 , 11 , 97 , 201 , 257 , 307 , 133 , 1793 , 193 , 8609 , 27771 ,0 }; - static ulong[] dim2775KuoInit = { 1 , 1 , 7 , 3 , 25 , 55 , 51 , 97 , 453 , 37 , 639 , 3451 , 6587 , 3835 , 13229 ,0 }; - static ulong[] dim2776KuoInit = { 1 , 3 , 1 , 1 , 3 , 21 , 123 , 81 , 447 , 963 , 449 , 1329 , 4887 , 1141 , 3213 ,0 }; - static ulong[] dim2777KuoInit = { 1 , 1 , 3 , 1 , 5 , 33 , 107 , 89 , 67 , 229 , 2025 , 1925 , 5369 , 14049 , 10461 ,0 }; - static ulong[] dim2778KuoInit = { 1 , 1 , 7 , 3 , 23 , 17 , 75 , 79 , 51 , 25 , 1541 , 3475 , 6129 , 13391 , 31091 ,0 }; - static ulong[] dim2779KuoInit = { 1 , 3 , 3 , 13 , 17 , 27 , 5 , 57 , 147 , 549 , 721 , 2477 , 893 , 6413 , 24053 ,0 }; - static ulong[] dim2780KuoInit = { 1 , 3 , 1 , 15 , 11 , 29 , 119 , 149 , 185 , 713 , 1603 , 3671 , 3409 , 2689 , 7933 ,0 }; - static ulong[] dim2781KuoInit = { 1 , 1 , 7 , 15 , 9 , 33 , 97 , 85 , 185 , 225 , 1747 , 1677 , 4133 , 11421 , 26591 ,0 }; - static ulong[] dim2782KuoInit = { 1 , 1 , 5 , 15 , 29 , 43 , 75 , 251 , 157 , 861 , 517 , 3341 , 4447 , 14803 , 18465 ,0 }; - static ulong[] dim2783KuoInit = { 1 , 3 , 5 , 15 , 11 , 37 , 57 , 189 , 423 , 881 , 1199 , 1263 , 2691 , 6969 , 21803 ,0 }; - static ulong[] dim2784KuoInit = { 1 , 1 , 3 , 3 , 25 , 47 , 15 , 107 , 119 , 885 , 1149 , 673 , 4459 , 9997 , 4519 ,0 }; - static ulong[] dim2785KuoInit = { 1 , 3 , 7 , 13 , 23 , 7 , 37 , 161 , 17 , 499 , 1675 , 2309 , 4159 , 13771 , 17741 ,0 }; - static ulong[] dim2786KuoInit = { 1 , 3 , 1 , 13 , 7 , 51 , 111 , 163 , 313 , 835 , 1903 , 2201 , 321 , 14655 , 16845 ,0 }; - static ulong[] dim2787KuoInit = { 1 , 1 , 3 , 3 , 7 , 41 , 23 , 87 , 101 , 371 , 257 , 1679 , 7449 , 12967 , 31 ,0 }; - static ulong[] dim2788KuoInit = { 1 , 3 , 3 , 7 , 29 , 37 , 57 , 163 , 507 , 1 , 691 , 2933 , 4687 , 10621 , 32351 ,0 }; - static ulong[] dim2789KuoInit = { 1 , 3 , 7 , 3 , 31 , 63 , 73 , 67 , 503 , 289 , 1533 , 1203 , 7931 , 11399 , 23463 ,0 }; - static ulong[] dim2790KuoInit = { 1 , 1 , 5 , 7 , 23 , 39 , 19 , 73 , 467 , 65 , 791 , 2017 , 1763 , 11921 , 31643 ,0 }; - static ulong[] dim2791KuoInit = { 1 , 3 , 3 , 1 , 19 , 21 , 53 , 61 , 401 , 429 , 1095 , 297 , 7931 , 13085 , 2013 ,0 }; - static ulong[] dim2792KuoInit = { 1 , 1 , 5 , 11 , 27 , 41 , 23 , 225 , 299 , 943 , 823 , 3507 , 4333 , 817 , 26137 ,0 }; - static ulong[] dim2793KuoInit = { 1 , 1 , 1 , 7 , 27 , 29 , 31 , 251 , 499 , 151 , 295 , 1731 , 7661 , 11825 , 29587 ,0 }; - static ulong[] dim2794KuoInit = { 1 , 1 , 3 , 7 , 17 , 43 , 17 , 5 , 25 , 813 , 1875 , 2941 , 1407 , 11669 , 16753 ,0 }; - static ulong[] dim2795KuoInit = { 1 , 3 , 1 , 1 , 17 , 59 , 93 , 173 , 335 , 933 , 369 , 3421 , 2769 , 16361 , 11891 ,0 }; - static ulong[] dim2796KuoInit = { 1 , 1 , 1 , 3 , 27 , 5 , 63 , 7 , 415 , 533 , 179 , 851 , 1623 , 16375 , 1271 ,0 }; - static ulong[] dim2797KuoInit = { 1 , 1 , 5 , 1 , 17 , 45 , 125 , 93 , 43 , 311 , 153 , 1225 , 4891 , 5621 , 14355 ,0 }; - static ulong[] dim2798KuoInit = { 1 , 3 , 7 , 5 , 13 , 63 , 103 , 205 , 119 , 953 , 1087 , 703 , 3729 , 10249 , 19085 ,0 }; - static ulong[] dim2799KuoInit = { 1 , 3 , 5 , 3 , 11 , 51 , 17 , 97 , 323 , 657 , 269 , 467 , 2747 , 13603 , 22803 ,0 }; - static ulong[] dim2800KuoInit = { 1 , 3 , 3 , 15 , 3 , 5 , 35 , 23 , 433 , 259 , 1857 , 2313 , 7709 , 2297 , 31109 ,0 }; - static ulong[] dim2801KuoInit = { 1 , 3 , 1 , 15 , 19 , 11 , 51 , 251 , 167 , 741 , 1705 , 3763 , 967 , 2593 , 28229 ,0 }; - static ulong[] dim2802KuoInit = { 1 , 3 , 3 , 13 , 29 , 47 , 47 , 183 , 305 , 223 , 381 , 1753 , 2285 , 9113 , 21685 ,0 }; - static ulong[] dim2803KuoInit = { 1 , 3 , 7 , 13 , 31 , 17 , 105 , 25 , 49 , 679 , 1501 , 3887 , 5007 , 4275 , 31161 ,0 }; - static ulong[] dim2804KuoInit = { 1 , 3 , 7 , 5 , 27 , 59 , 17 , 183 , 477 , 191 , 1111 , 383 , 5519 , 7435 , 20341 ,0 }; - static ulong[] dim2805KuoInit = { 1 , 1 , 7 , 13 , 25 , 15 , 67 , 57 , 5 , 955 , 731 , 3785 , 2055 , 13017 , 27843 ,0 }; - static ulong[] dim2806KuoInit = { 1 , 1 , 5 , 1 , 27 , 45 , 67 , 93 , 311 , 635 , 1893 , 1753 , 7307 , 2765 , 6263 ,0 }; - static ulong[] dim2807KuoInit = { 1 , 1 , 3 , 1 , 13 , 53 , 109 , 5 , 3 , 705 , 1745 , 2233 , 3425 , 6125 , 28839 ,0 }; - static ulong[] dim2808KuoInit = { 1 , 3 , 5 , 5 , 5 , 39 , 5 , 251 , 431 , 85 , 599 , 3459 , 3211 , 15611 , 28739 ,0 }; - static ulong[] dim2809KuoInit = { 1 , 1 , 7 , 7 , 25 , 5 , 25 , 31 , 283 , 909 , 399 , 1335 , 6973 , 15791 , 28351 ,0 }; - static ulong[] dim2810KuoInit = { 1 , 1 , 5 , 5 , 3 , 29 , 47 , 227 , 463 , 815 , 1089 , 2217 , 4911 , 14743 , 17843 ,0 }; - static ulong[] dim2811KuoInit = { 1 , 1 , 7 , 3 , 29 , 39 , 125 , 165 , 367 , 461 , 569 , 3441 , 1293 , 1577 , 10567 ,0 }; - static ulong[] dim2812KuoInit = { 1 , 1 , 1 , 11 , 5 , 11 , 19 , 129 , 401 , 111 , 2019 , 899 , 2079 , 7363 , 32675 ,0 }; - static ulong[] dim2813KuoInit = { 1 , 3 , 1 , 7 , 13 , 27 , 47 , 183 , 465 , 421 , 665 , 1279 , 5629 , 7559 , 21265 ,0 }; - static ulong[] dim2814KuoInit = { 1 , 1 , 7 , 1 , 11 , 19 , 75 , 1 , 137 , 893 , 1709 , 385 , 2221 , 15185 , 10923 ,0 }; - static ulong[] dim2815KuoInit = { 1 , 3 , 5 , 5 , 9 , 1 , 115 , 203 , 133 , 259 , 915 , 2477 , 3615 , 1749 , 7643 ,0 }; - static ulong[] dim2816KuoInit = { 1 , 3 , 3 , 5 , 9 , 57 , 21 , 113 , 453 , 739 , 1857 , 685 , 5727 , 10625 , 23469 ,0 }; - static ulong[] dim2817KuoInit = { 1 , 1 , 5 , 5 , 13 , 45 , 37 , 25 , 495 , 723 , 1805 , 1631 , 4889 , 12885 , 16895 ,0 }; - static ulong[] dim2818KuoInit = { 1 , 1 , 5 , 7 , 17 , 59 , 111 , 29 , 143 , 863 , 1757 , 1621 , 3995 , 7315 , 30271 ,0 }; - static ulong[] dim2819KuoInit = { 1 , 1 , 1 , 1 , 5 , 31 , 81 , 161 , 275 , 623 , 2017 , 967 , 2395 , 14923 , 23931 ,0 }; - static ulong[] dim2820KuoInit = { 1 , 3 , 5 , 11 , 31 , 33 , 95 , 135 , 477 , 221 , 1603 , 231 , 5957 , 12461 , 2623 ,0 }; - static ulong[] dim2821KuoInit = { 1 , 3 , 5 , 11 , 7 , 3 , 53 , 43 , 351 , 557 , 1981 , 2127 , 909 , 8943 , 21035 ,0 }; - static ulong[] dim2822KuoInit = { 1 , 3 , 5 , 9 , 31 , 11 , 13 , 231 , 145 , 321 , 567 , 1919 , 7101 , 12089 , 8331 ,0 }; - static ulong[] dim2823KuoInit = { 1 , 1 , 7 , 1 , 13 , 27 , 101 , 229 , 89 , 395 , 349 , 1785 , 6441 , 8241 , 30735 ,0 }; - static ulong[] dim2824KuoInit = { 1 , 1 , 7 , 9 , 21 , 57 , 123 , 77 , 251 , 347 , 1367 , 2205 , 4017 , 16057 , 9247 ,0 }; - static ulong[] dim2825KuoInit = { 1 , 3 , 3 , 11 , 5 , 1 , 47 , 57 , 69 , 381 , 1613 , 1525 , 5715 , 3677 , 13015 ,0 }; - static ulong[] dim2826KuoInit = { 1 , 3 , 7 , 9 , 31 , 33 , 15 , 255 , 149 , 1021 , 1149 , 3609 , 1739 , 11867 , 3093 ,0 }; - static ulong[] dim2827KuoInit = { 1 , 1 , 7 , 15 , 27 , 25 , 57 , 5 , 137 , 1005 , 343 , 2567 , 1025 , 8615 , 6357 ,0 }; - static ulong[] dim2828KuoInit = { 1 , 3 , 5 , 1 , 29 , 57 , 85 , 65 , 85 , 789 , 1179 , 2523 , 7589 , 14657 , 23637 ,0 }; - static ulong[] dim2829KuoInit = { 1 , 3 , 1 , 11 , 3 , 3 , 107 , 37 , 125 , 423 , 225 , 2991 , 4515 , 5057 , 31181 ,0 }; - static ulong[] dim2830KuoInit = { 1 , 1 , 5 , 9 , 31 , 5 , 111 , 241 , 301 , 37 , 943 , 555 , 7051 , 11627 , 7125 ,0 }; - static ulong[] dim2831KuoInit = { 1 , 3 , 3 , 15 , 17 , 31 , 119 , 185 , 187 , 621 , 395 , 3595 , 1055 , 7993 , 28441 ,0 }; - static ulong[] dim2832KuoInit = { 1 , 1 , 5 , 1 , 31 , 25 , 113 , 223 , 493 , 919 , 1455 , 31 , 4743 , 14435 , 31627 ,0 }; - static ulong[] dim2833KuoInit = { 1 , 1 , 1 , 1 , 27 , 59 , 45 , 75 , 343 , 701 , 1737 , 161 , 6919 , 13537 , 26835 ,0 }; - static ulong[] dim2834KuoInit = { 1 , 3 , 1 , 9 , 31 , 45 , 89 , 215 , 137 , 237 , 1135 , 3239 , 3345 , 12063 , 14599 ,0 }; - static ulong[] dim2835KuoInit = { 1 , 3 , 5 , 15 , 5 , 51 , 85 , 73 , 353 , 943 , 1981 , 127 , 2605 , 5673 , 10037 ,0 }; - static ulong[] dim2836KuoInit = { 1 , 1 , 7 , 1 , 3 , 49 , 109 , 105 , 483 , 499 , 1581 , 793 , 5857 , 5509 , 4651 ,0 }; - static ulong[] dim2837KuoInit = { 1 , 3 , 5 , 9 , 23 , 5 , 109 , 83 , 7 , 155 , 187 , 2205 , 4199 , 5487 , 31925 ,0 }; - static ulong[] dim2838KuoInit = { 1 , 1 , 7 , 5 , 13 , 11 , 75 , 53 , 125 , 139 , 1241 , 203 , 7361 , 13783 , 4317 ,0 }; - static ulong[] dim2839KuoInit = { 1 , 3 , 7 , 5 , 25 , 57 , 105 , 197 , 207 , 261 , 1251 , 4057 , 3877 , 13613 , 7829 ,0 }; - static ulong[] dim2840KuoInit = { 1 , 1 , 5 , 13 , 31 , 21 , 89 , 73 , 163 , 941 , 1683 , 2239 , 1893 , 16067 , 609 ,0 }; - static ulong[] dim2841KuoInit = { 1 , 1 , 1 , 3 , 5 , 9 , 41 , 149 , 43 , 333 , 1459 , 277 , 5687 , 14201 , 26879 ,0 }; - static ulong[] dim2842KuoInit = { 1 , 1 , 3 , 15 , 21 , 37 , 67 , 227 , 443 , 767 , 1109 , 2151 , 7875 , 15519 , 13741 ,0 }; - static ulong[] dim2843KuoInit = { 1 , 3 , 1 , 5 , 31 , 15 , 107 , 43 , 343 , 27 , 1321 , 3009 , 5751 , 2931 , 9733 ,0 }; - static ulong[] dim2844KuoInit = { 1 , 1 , 1 , 11 , 5 , 27 , 49 , 33 , 439 , 555 , 97 , 59 , 4043 , 12063 , 27227 ,0 }; - static ulong[] dim2845KuoInit = { 1 , 3 , 7 , 7 , 27 , 9 , 55 , 69 , 485 , 75 , 1255 , 101 , 7193 , 9427 , 31125 ,0 }; - static ulong[] dim2846KuoInit = { 1 , 3 , 7 , 3 , 15 , 23 , 51 , 145 , 501 , 875 , 1611 , 1321 , 6809 , 5051 , 17135 ,0 }; - static ulong[] dim2847KuoInit = { 1 , 3 , 3 , 13 , 5 , 45 , 35 , 115 , 3 , 639 , 1705 , 207 , 4235 , 3329 , 14481 ,0 }; - static ulong[] dim2848KuoInit = { 1 , 3 , 3 , 1 , 5 , 15 , 17 , 115 , 175 , 583 , 1649 , 2195 , 3827 , 16227 , 21401 ,0 }; - static ulong[] dim2849KuoInit = { 1 , 3 , 3 , 7 , 1 , 3 , 107 , 167 , 195 , 953 , 743 , 1375 , 701 , 1155 , 1027 ,0 }; - static ulong[] dim2850KuoInit = { 1 , 1 , 7 , 1 , 31 , 31 , 67 , 133 , 219 , 307 , 1031 , 3321 , 4855 , 11285 , 16987 ,0 }; - static ulong[] dim2851KuoInit = { 1 , 1 , 7 , 1 , 25 , 9 , 41 , 105 , 89 , 289 , 1851 , 2245 , 1647 , 2925 , 8637 ,0 }; - static ulong[] dim2852KuoInit = { 1 , 3 , 7 , 15 , 29 , 29 , 107 , 21 , 101 , 419 , 1207 , 3301 , 1217 , 14157 , 17373 ,0 }; - static ulong[] dim2853KuoInit = { 1 , 1 , 5 , 11 , 9 , 41 , 49 , 165 , 353 , 215 , 883 , 2031 , 7363 , 13221 , 8329 ,0 }; - static ulong[] dim2854KuoInit = { 1 , 1 , 5 , 15 , 17 , 7 , 67 , 217 , 87 , 217 , 2013 , 3809 , 4983 , 5341 , 30353 ,0 }; - static ulong[] dim2855KuoInit = { 1 , 1 , 7 , 9 , 1 , 37 , 97 , 109 , 485 , 777 , 171 , 1391 , 781 , 5019 , 19883 ,0 }; - static ulong[] dim2856KuoInit = { 1 , 3 , 3 , 13 , 7 , 17 , 27 , 69 , 265 , 663 , 569 , 2909 , 7409 , 14813 , 5849 ,0 }; - static ulong[] dim2857KuoInit = { 1 , 3 , 5 , 13 , 11 , 29 , 27 , 105 , 215 , 59 , 1251 , 2003 , 2201 , 7221 , 7549 ,0 }; - static ulong[] dim2858KuoInit = { 1 , 1 , 1 , 3 , 15 , 7 , 79 , 237 , 327 , 839 , 1167 , 3211 , 275 , 16031 , 25691 ,0 }; - static ulong[] dim2859KuoInit = { 1 , 1 , 5 , 3 , 3 , 33 , 117 , 113 , 361 , 381 , 1093 , 1791 , 2399 , 1245 , 23275 ,0 }; - static ulong[] dim2860KuoInit = { 1 , 1 , 1 , 3 , 7 , 49 , 77 , 5 , 217 , 995 , 1127 , 3891 , 81 , 13331 , 12479 ,0 }; - static ulong[] dim2861KuoInit = { 1 , 1 , 7 , 9 , 9 , 57 , 119 , 227 , 41 , 337 , 183 , 3201 , 3627 , 16263 , 28153 ,0 }; - static ulong[] dim2862KuoInit = { 1 , 3 , 1 , 13 , 11 , 9 , 81 , 99 , 247 , 157 , 1421 , 1087 , 151 , 6529 , 13537 ,0 }; - static ulong[] dim2863KuoInit = { 1 , 3 , 3 , 5 , 31 , 43 , 113 , 143 , 163 , 583 , 2031 , 3087 , 7565 , 4987 , 17131 ,0 }; - static ulong[] dim2864KuoInit = { 1 , 1 , 3 , 1 , 9 , 1 , 121 , 93 , 113 , 849 , 679 , 1403 , 6815 , 15605 , 29785 ,0 }; - static ulong[] dim2865KuoInit = { 1 , 3 , 7 , 11 , 27 , 63 , 53 , 83 , 397 , 935 , 23 , 125 , 5813 , 15765 , 2869 ,0 }; - static ulong[] dim2866KuoInit = { 1 , 1 , 3 , 3 , 9 , 11 , 65 , 77 , 387 , 129 , 1039 , 1583 , 2235 , 3851 , 30603 ,0 }; - static ulong[] dim2867KuoInit = { 1 , 1 , 7 , 3 , 5 , 27 , 45 , 233 , 351 , 827 , 215 , 1209 , 409 , 2185 , 3827 ,0 }; - static ulong[] dim2868KuoInit = { 1 , 1 , 3 , 3 , 31 , 23 , 35 , 83 , 271 , 65 , 553 , 3189 , 2435 , 12865 , 28271 ,0 }; - static ulong[] dim2869KuoInit = { 1 , 1 , 5 , 1 , 29 , 51 , 35 , 105 , 477 , 1001 , 1859 , 2063 , 6895 , 1855 , 13931 ,0 }; - static ulong[] dim2870KuoInit = { 1 , 3 , 3 , 11 , 17 , 63 , 125 , 165 , 37 , 671 , 2001 , 1237 , 7355 , 339 , 24771 ,0 }; - static ulong[] dim2871KuoInit = { 1 , 3 , 3 , 5 , 13 , 5 , 9 , 201 , 183 , 39 , 119 , 3889 , 949 , 7889 , 25951 ,0 }; - static ulong[] dim2872KuoInit = { 1 , 1 , 3 , 5 , 13 , 63 , 71 , 117 , 209 , 955 , 1175 , 317 , 4261 , 2341 , 29819 ,0 }; - static ulong[] dim2873KuoInit = { 1 , 3 , 5 , 5 , 9 , 59 , 109 , 137 , 353 , 355 , 1227 , 3183 , 1553 , 15039 , 27979 ,0 }; - static ulong[] dim2874KuoInit = { 1 , 3 , 1 , 5 , 25 , 57 , 87 , 231 , 259 , 333 , 975 , 3413 , 6035 , 14783 , 22309 ,0 }; - static ulong[] dim2875KuoInit = { 1 , 3 , 5 , 11 , 19 , 37 , 55 , 229 , 423 , 761 , 1669 , 3023 , 2517 , 2961 , 12043 ,0 }; - static ulong[] dim2876KuoInit = { 1 , 1 , 3 , 13 , 23 , 5 , 87 , 193 , 113 , 577 , 269 , 983 , 5453 , 7827 , 28197 ,0 }; - static ulong[] dim2877KuoInit = { 1 , 1 , 7 , 13 , 1 , 49 , 89 , 107 , 155 , 767 , 1547 , 2139 , 5951 , 3143 , 12735 ,0 }; - static ulong[] dim2878KuoInit = { 1 , 3 , 1 , 13 , 13 , 57 , 53 , 243 , 231 , 131 , 1505 , 1255 , 7831 , 15615 , 28755 ,0 }; - static ulong[] dim2879KuoInit = { 1 , 1 , 5 , 11 , 21 , 21 , 37 , 65 , 327 , 353 , 1625 , 543 , 669 , 1139 , 20745 ,0 }; - static ulong[] dim2880KuoInit = { 1 , 3 , 1 , 1 , 5 , 33 , 87 , 211 , 21 , 581 , 397 , 2691 , 1069 , 10449 , 17727 ,0 }; - static ulong[] dim2881KuoInit = { 1 , 1 , 7 , 7 , 1 , 5 , 115 , 143 , 99 , 523 , 51 , 939 , 4635 , 11491 , 32731 ,0 }; - static ulong[] dim2882KuoInit = { 1 , 3 , 3 , 15 , 1 , 19 , 119 , 193 , 127 , 897 , 1337 , 3977 , 5027 , 5913 , 9329 ,0 }; - static ulong[] dim2883KuoInit = { 1 , 1 , 5 , 15 , 15 , 1 , 93 , 209 , 427 , 625 , 1581 , 2639 , 1291 , 11177 , 26943 ,0 }; - static ulong[] dim2884KuoInit = { 1 , 1 , 3 , 13 , 27 , 9 , 47 , 243 , 211 , 21 , 1159 , 3157 , 6729 , 219 , 19671 ,0 }; - static ulong[] dim2885KuoInit = { 1 , 3 , 1 , 15 , 19 , 27 , 39 , 237 , 39 , 389 , 1201 , 2237 , 7623 , 12041 , 18491 ,0 }; - static ulong[] dim2886KuoInit = { 1 , 1 , 3 , 5 , 25 , 43 , 47 , 101 , 319 , 749 , 659 , 2319 , 1221 , 3887 , 29927 ,0 }; - static ulong[] dim2887KuoInit = { 1 , 3 , 3 , 9 , 1 , 55 , 57 , 179 , 163 , 695 , 611 , 2511 , 1261 , 15561 , 29535 ,0 }; - static ulong[] dim2888KuoInit = { 1 , 1 , 1 , 13 , 7 , 31 , 79 , 21 , 143 , 993 , 377 , 791 , 187 , 6485 , 6827 ,0 }; - static ulong[] dim2889KuoInit = { 1 , 3 , 5 , 1 , 11 , 57 , 39 , 159 , 373 , 179 , 1907 , 2475 , 1355 , 9885 , 18683 ,0 }; - static ulong[] dim2890KuoInit = { 1 , 1 , 1 , 3 , 7 , 5 , 83 , 151 , 267 , 377 , 1463 , 365 , 4725 , 2319 , 18957 ,0 }; - static ulong[] dim2891KuoInit = { 1 , 3 , 7 , 3 , 21 , 51 , 115 , 119 , 73 , 561 , 1513 , 403 , 4889 , 2329 , 20141 ,0 }; - static ulong[] dim2892KuoInit = { 1 , 1 , 1 , 15 , 21 , 47 , 31 , 61 , 171 , 529 , 185 , 717 , 7065 , 4273 , 16643 ,0 }; - static ulong[] dim2893KuoInit = { 1 , 3 , 5 , 9 , 3 , 55 , 41 , 213 , 489 , 379 , 1951 , 1957 , 7721 , 6415 , 27049 ,0 }; - static ulong[] dim2894KuoInit = { 1 , 3 , 1 , 13 , 19 , 43 , 29 , 203 , 139 , 137 , 463 , 1447 , 2585 , 14381 , 29073 ,0 }; - static ulong[] dim2895KuoInit = { 1 , 1 , 1 , 1 , 19 , 37 , 111 , 119 , 411 , 671 , 1135 , 2891 , 7929 , 7465 , 21699 ,0 }; - static ulong[] dim2896KuoInit = { 1 , 1 , 5 , 13 , 21 , 31 , 83 , 227 , 435 , 61 , 969 , 2171 , 789 , 3415 , 18293 ,0 }; - static ulong[] dim2897KuoInit = { 1 , 3 , 3 , 15 , 31 , 33 , 87 , 227 , 369 , 341 , 1515 , 25 , 2891 , 16199 , 22179 ,0 }; - static ulong[] dim2898KuoInit = { 1 , 3 , 3 , 1 , 25 , 49 , 111 , 167 , 59 , 355 , 1687 , 1799 , 5963 , 6161 , 32157 ,0 }; - static ulong[] dim2899KuoInit = { 1 , 1 , 1 , 5 , 7 , 57 , 95 , 171 , 417 , 277 , 47 , 847 , 3889 , 8645 , 3367 ,0 }; - static ulong[] dim2900KuoInit = { 1 , 1 , 7 , 3 , 25 , 51 , 99 , 251 , 463 , 833 , 491 , 3595 , 2883 , 8183 , 28937 ,0 }; - static ulong[] dim2901KuoInit = { 1 , 1 , 3 , 7 , 1 , 5 , 73 , 151 , 397 , 521 , 905 , 603 , 2315 , 15231 , 17955 ,0 }; - static ulong[] dim2902KuoInit = { 1 , 1 , 1 , 13 , 23 , 59 , 9 , 187 , 163 , 727 , 1909 , 1135 , 6135 , 11563 , 2047 ,0 }; - static ulong[] dim2903KuoInit = { 1 , 1 , 3 , 3 , 9 , 1 , 121 , 207 , 55 , 947 , 873 , 419 , 2799 , 3285 , 10237 ,0 }; - static ulong[] dim2904KuoInit = { 1 , 1 , 1 , 3 , 21 , 27 , 27 , 241 , 509 , 295 , 1509 , 3527 , 4269 , 13579 , 29125 ,0 }; - static ulong[] dim2905KuoInit = { 1 , 3 , 1 , 5 , 7 , 21 , 35 , 67 , 251 , 883 , 1117 , 1311 , 1251 , 10401 , 10615 ,0 }; - static ulong[] dim2906KuoInit = { 1 , 3 , 7 , 3 , 21 , 13 , 23 , 75 , 401 , 279 , 1557 , 1419 , 7067 , 2563 , 22285 ,0 }; - static ulong[] dim2907KuoInit = { 1 , 3 , 1 , 7 , 23 , 15 , 11 , 189 , 315 , 353 , 1377 , 3551 , 4939 , 14529 , 12459 ,0 }; - static ulong[] dim2908KuoInit = { 1 , 3 , 1 , 3 , 21 , 41 , 111 , 67 , 311 , 95 , 1919 , 165 , 2097 , 12965 , 12517 ,0 }; - static ulong[] dim2909KuoInit = { 1 , 3 , 3 , 11 , 29 , 61 , 33 , 35 , 209 , 541 , 149 , 3073 , 8187 , 15087 , 17617 ,0 }; - static ulong[] dim2910KuoInit = { 1 , 1 , 7 , 5 , 9 , 53 , 73 , 145 , 205 , 157 , 1737 , 1737 , 6471 , 12327 , 11605 ,0 }; - static ulong[] dim2911KuoInit = { 1 , 1 , 5 , 5 , 15 , 35 , 105 , 99 , 467 , 421 , 483 , 3191 , 2321 , 8953 , 22045 ,0 }; - static ulong[] dim2912KuoInit = { 1 , 3 , 3 , 9 , 1 , 35 , 65 , 249 , 37 , 535 , 1301 , 2141 , 1629 , 9709 , 995 ,0 }; - static ulong[] dim2913KuoInit = { 1 , 3 , 1 , 13 , 9 , 27 , 75 , 115 , 121 , 731 , 1567 , 2341 , 6657 , 14959 , 6781 ,0 }; - static ulong[] dim2914KuoInit = { 1 , 1 , 1 , 5 , 13 , 33 , 89 , 215 , 189 , 693 , 357 , 3383 , 6345 , 14263 , 23973 ,0 }; - static ulong[] dim2915KuoInit = { 1 , 3 , 1 , 9 , 21 , 5 , 59 , 11 , 21 , 703 , 1217 , 2623 , 6429 , 479 , 28659 ,0 }; - static ulong[] dim2916KuoInit = { 1 , 3 , 3 , 9 , 11 , 15 , 113 , 89 , 453 , 233 , 1323 , 3859 , 1841 , 2753 , 2839 ,0 }; - static ulong[] dim2917KuoInit = { 1 , 1 , 5 , 15 , 19 , 1 , 119 , 83 , 205 , 861 , 787 , 1039 , 5257 , 8945 , 27271 ,0 }; - static ulong[] dim2918KuoInit = { 1 , 3 , 1 , 15 , 9 , 37 , 7 , 83 , 51 , 611 , 1121 , 3185 , 1603 , 5821 , 14533 ,0 }; - static ulong[] dim2919KuoInit = { 1 , 1 , 7 , 7 , 27 , 61 , 115 , 191 , 357 , 93 , 1647 , 3249 , 2479 , 2423 , 649 ,0 }; - static ulong[] dim2920KuoInit = { 1 , 1 , 7 , 11 , 25 , 17 , 13 , 213 , 37 , 571 , 1179 , 3897 , 3817 , 7597 , 26239 ,0 }; - static ulong[] dim2921KuoInit = { 1 , 1 , 5 , 5 , 27 , 57 , 73 , 209 , 433 , 779 , 75 , 2135 , 8183 , 7343 , 23751 ,0 }; - static ulong[] dim2922KuoInit = { 1 , 1 , 7 , 13 , 27 , 51 , 31 , 33 , 195 , 443 , 1639 , 1415 , 6203 , 4373 , 31271 ,0 }; - static ulong[] dim2923KuoInit = { 1 , 1 , 7 , 11 , 9 , 9 , 75 , 103 , 237 , 521 , 1653 , 1209 , 5981 , 5961 , 15229 ,0 }; - static ulong[] dim2924KuoInit = { 1 , 3 , 3 , 11 , 15 , 29 , 1 , 201 , 171 , 81 , 729 , 589 , 441 , 2453 , 25209 ,0 }; - static ulong[] dim2925KuoInit = { 1 , 3 , 1 , 1 , 21 , 11 , 95 , 225 , 213 , 981 , 1479 , 3259 , 4415 , 8393 , 17647 ,0 }; - static ulong[] dim2926KuoInit = { 1 , 1 , 7 , 1 , 7 , 11 , 95 , 135 , 329 , 483 , 1711 , 3223 , 4841 , 11083 , 4033 ,0 }; - static ulong[] dim2927KuoInit = { 1 , 1 , 3 , 5 , 23 , 37 , 77 , 39 , 363 , 555 , 1451 , 99 , 6963 , 13279 , 24155 ,0 }; - static ulong[] dim2928KuoInit = { 1 , 3 , 7 , 11 , 11 , 17 , 31 , 29 , 357 , 177 , 411 , 1439 , 815 , 7017 , 25527 ,0 }; - static ulong[] dim2929KuoInit = { 1 , 3 , 3 , 15 , 25 , 7 , 105 , 9 , 301 , 209 , 917 , 1369 , 2941 , 11599 , 25847 ,0 }; - static ulong[] dim2930KuoInit = { 1 , 1 , 7 , 7 , 11 , 33 , 121 , 9 , 465 , 945 , 201 , 3929 , 5521 , 4787 , 10713 ,0 }; - static ulong[] dim2931KuoInit = { 1 , 1 , 7 , 9 , 27 , 3 , 77 , 11 , 103 , 181 , 1199 , 2833 , 6259 , 3879 , 13217 ,0 }; - static ulong[] dim2932KuoInit = { 1 , 3 , 3 , 11 , 11 , 9 , 5 , 217 , 471 , 973 , 293 , 3693 , 5457 , 11359 , 30043 ,0 }; - static ulong[] dim2933KuoInit = { 1 , 1 , 3 , 15 , 27 , 25 , 7 , 65 , 95 , 883 , 277 , 3147 , 6203 , 12201 , 23203 ,0 }; - static ulong[] dim2934KuoInit = { 1 , 1 , 3 , 9 , 3 , 19 , 51 , 55 , 381 , 879 , 845 , 1605 , 2433 , 4781 , 5075 ,0 }; - static ulong[] dim2935KuoInit = { 1 , 1 , 3 , 15 , 17 , 49 , 21 , 81 , 209 , 285 , 1483 , 1897 , 5591 , 131 , 30459 ,0 }; - static ulong[] dim2936KuoInit = { 1 , 3 , 1 , 9 , 17 , 19 , 47 , 97 , 325 , 963 , 1665 , 3361 , 369 , 11023 , 23701 ,0 }; - static ulong[] dim2937KuoInit = { 1 , 3 , 1 , 13 , 3 , 19 , 57 , 7 , 57 , 383 , 1945 , 3357 , 2553 , 5161 , 22363 ,0 }; - static ulong[] dim2938KuoInit = { 1 , 1 , 3 , 15 , 15 , 37 , 41 , 123 , 453 , 879 , 337 , 251 , 7137 , 4117 , 30879 ,0 }; - static ulong[] dim2939KuoInit = { 1 , 3 , 5 , 3 , 13 , 45 , 55 , 151 , 357 , 429 , 671 , 1183 , 3047 , 4991 , 15273 ,0 }; - static ulong[] dim2940KuoInit = { 1 , 1 , 3 , 3 , 15 , 15 , 65 , 131 , 505 , 339 , 869 , 2983 , 4451 , 2375 , 26745 ,0 }; - static ulong[] dim2941KuoInit = { 1 , 3 , 5 , 9 , 15 , 55 , 23 , 83 , 255 , 395 , 15 , 1175 , 849 , 5959 , 17355 ,0 }; - static ulong[] dim2942KuoInit = { 1 , 1 , 3 , 7 , 9 , 3 , 57 , 95 , 7 , 267 , 801 , 3843 , 3139 , 12565 , 20737 ,0 }; - static ulong[] dim2943KuoInit = { 1 , 3 , 7 , 7 , 9 , 41 , 121 , 77 , 489 , 975 , 215 , 325 , 7505 , 15517 , 8833 ,0 }; - static ulong[] dim2944KuoInit = { 1 , 3 , 3 , 1 , 9 , 43 , 105 , 199 , 339 , 335 , 1719 , 1999 , 4153 , 9665 , 15457 ,0 }; - static ulong[] dim2945KuoInit = { 1 , 3 , 1 , 13 , 1 , 35 , 47 , 157 , 3 , 93 , 1399 , 471 , 6337 , 2789 , 32727 ,0 }; - static ulong[] dim2946KuoInit = { 1 , 3 , 5 , 1 , 29 , 9 , 101 , 195 , 371 , 573 , 1361 , 521 , 5737 , 4845 , 4871 ,0 }; - static ulong[] dim2947KuoInit = { 1 , 1 , 7 , 9 , 9 , 11 , 43 , 129 , 295 , 1015 , 665 , 451 , 1249 , 7733 , 8861 ,0 }; - static ulong[] dim2948KuoInit = { 1 , 1 , 1 , 11 , 19 , 31 , 127 , 171 , 341 , 865 , 1391 , 955 , 5585 , 1481 , 1311 ,0 }; - static ulong[] dim2949KuoInit = { 1 , 3 , 1 , 11 , 19 , 43 , 113 , 83 , 285 , 865 , 815 , 807 , 779 , 6685 , 22315 ,0 }; - static ulong[] dim2950KuoInit = { 1 , 1 , 1 , 11 , 1 , 19 , 99 , 19 , 455 , 155 , 637 , 2153 , 3013 , 4791 , 20619 ,0 }; - static ulong[] dim2951KuoInit = { 1 , 1 , 1 , 1 , 13 , 39 , 95 , 229 , 35 , 515 , 1945 , 3631 , 3359 , 7913 , 8081 ,0 }; - static ulong[] dim2952KuoInit = { 1 , 3 , 7 , 13 , 1 , 5 , 25 , 227 , 487 , 269 , 1213 , 303 , 4041 , 15847 , 1125 ,0 }; - static ulong[] dim2953KuoInit = { 1 , 1 , 3 , 7 , 27 , 53 , 121 , 143 , 1 , 977 , 1963 , 807 , 253 , 7649 , 16047 ,0 }; - static ulong[] dim2954KuoInit = { 1 , 3 , 5 , 9 , 29 , 17 , 97 , 93 , 83 , 739 , 1221 , 963 , 6849 , 4307 , 17277 ,0 }; - static ulong[] dim2955KuoInit = { 1 , 1 , 7 , 1 , 27 , 55 , 71 , 177 , 63 , 11 , 1781 , 3341 , 2797 , 8035 , 6135 ,0 }; - static ulong[] dim2956KuoInit = { 1 , 1 , 1 , 11 , 15 , 43 , 59 , 107 , 485 , 995 , 1571 , 1527 , 2195 , 4883 , 32563 ,0 }; - static ulong[] dim2957KuoInit = { 1 , 3 , 5 , 15 , 7 , 45 , 55 , 211 , 425 , 771 , 621 , 1141 , 5277 , 13575 , 203 ,0 }; - static ulong[] dim2958KuoInit = { 1 , 1 , 7 , 1 , 21 , 51 , 81 , 41 , 71 , 551 , 839 , 3315 , 5075 , 3651 , 6649 ,0 }; - static ulong[] dim2959KuoInit = { 1 , 1 , 1 , 9 , 17 , 45 , 51 , 211 , 349 , 329 , 987 , 3153 , 7121 , 16101 , 1475 ,0 }; - static ulong[] dim2960KuoInit = { 1 , 3 , 3 , 9 , 5 , 5 , 99 , 17 , 245 , 827 , 231 , 949 , 2577 , 12925 , 2055 ,0 }; - static ulong[] dim2961KuoInit = { 1 , 1 , 5 , 1 , 19 , 59 , 75 , 97 , 303 , 649 , 901 , 3987 , 1209 , 14483 , 25855 ,0 }; - static ulong[] dim2962KuoInit = { 1 , 3 , 7 , 15 , 25 , 51 , 5 , 69 , 199 , 845 , 1847 , 1491 , 6183 , 3359 , 11809 ,0 }; - static ulong[] dim2963KuoInit = { 1 , 1 , 5 , 5 , 19 , 43 , 17 , 113 , 215 , 337 , 583 , 2199 , 6375 , 499 , 11283 ,0 }; - static ulong[] dim2964KuoInit = { 1 , 1 , 5 , 15 , 5 , 3 , 45 , 219 , 375 , 269 , 1251 , 2711 , 7897 , 3379 , 11887 ,0 }; - static ulong[] dim2965KuoInit = { 1 , 1 , 7 , 13 , 3 , 59 , 17 , 41 , 275 , 1007 , 711 , 1689 , 3727 , 14237 , 32057 ,0 }; - static ulong[] dim2966KuoInit = { 1 , 3 , 5 , 7 , 5 , 27 , 73 , 167 , 295 , 581 , 233 , 585 , 7207 , 12709 , 3847 ,0 }; - static ulong[] dim2967KuoInit = { 1 , 1 , 7 , 5 , 9 , 17 , 65 , 15 , 439 , 385 , 455 , 1073 , 5727 , 2679 , 3689 ,0 }; - static ulong[] dim2968KuoInit = { 1 , 1 , 7 , 5 , 7 , 63 , 111 , 161 , 85 , 295 , 755 , 2805 , 3031 , 4833 , 11149 ,0 }; - static ulong[] dim2969KuoInit = { 1 , 1 , 5 , 7 , 13 , 53 , 63 , 47 , 163 , 275 , 289 , 1377 , 639 , 15367 , 32517 ,0 }; - static ulong[] dim2970KuoInit = { 1 , 1 , 7 , 9 , 21 , 43 , 123 , 221 , 451 , 901 , 1339 , 3367 , 2531 , 9319 , 4461 ,0 }; - static ulong[] dim2971KuoInit = { 1 , 3 , 3 , 9 , 3 , 53 , 87 , 117 , 471 , 349 , 1487 , 2375 , 7399 , 8561 , 19611 ,0 }; - static ulong[] dim2972KuoInit = { 1 , 3 , 1 , 7 , 29 , 55 , 53 , 197 , 301 , 701 , 357 , 3651 , 2233 , 6365 , 705 ,0 }; - static ulong[] dim2973KuoInit = { 1 , 3 , 5 , 3 , 17 , 19 , 23 , 17 , 433 , 979 , 1377 , 213 , 3993 , 3773 , 24369 ,0 }; - static ulong[] dim2974KuoInit = { 1 , 3 , 5 , 5 , 17 , 9 , 105 , 149 , 145 , 751 , 1173 , 1831 , 7005 , 3559 , 10913 ,0 }; - static ulong[] dim2975KuoInit = { 1 , 3 , 1 , 9 , 23 , 47 , 83 , 213 , 135 , 223 , 937 , 3607 , 7375 , 4731 , 14307 ,0 }; - static ulong[] dim2976KuoInit = { 1 , 1 , 7 , 3 , 23 , 21 , 71 , 241 , 399 , 199 , 289 , 2049 , 7959 , 14897 , 18661 ,0 }; - static ulong[] dim2977KuoInit = { 1 , 3 , 3 , 9 , 13 , 45 , 125 , 217 , 325 , 893 , 1523 , 2477 , 7829 , 15737 , 2127 ,0 }; - static ulong[] dim2978KuoInit = { 1 , 1 , 5 , 1 , 21 , 51 , 117 , 203 , 253 , 713 , 545 , 191 , 729 , 8403 , 8381 ,0 }; - static ulong[] dim2979KuoInit = { 1 , 3 , 7 , 7 , 11 , 23 , 3 , 193 , 421 , 341 , 1309 , 2457 , 5805 , 7457 , 26857 ,0 }; - static ulong[] dim2980KuoInit = { 1 , 3 , 7 , 15 , 1 , 17 , 27 , 159 , 127 , 713 , 1465 , 3551 , 7409 , 7957 , 2317 ,0 }; - static ulong[] dim2981KuoInit = { 1 , 3 , 1 , 15 , 7 , 33 , 17 , 1 , 237 , 199 , 527 , 3361 , 3785 , 13111 , 19119 ,0 }; - static ulong[] dim2982KuoInit = { 1 , 3 , 3 , 1 , 23 , 37 , 91 , 31 , 35 , 969 , 661 , 85 , 5917 , 10895 , 11049 ,0 }; - static ulong[] dim2983KuoInit = { 1 , 3 , 1 , 7 , 23 , 53 , 101 , 181 , 381 , 159 , 1967 , 3427 , 4499 , 6877 , 12155 ,0 }; - static ulong[] dim2984KuoInit = { 1 , 3 , 3 , 13 , 9 , 57 , 77 , 27 , 223 , 101 , 1709 , 3023 , 6655 , 6221 , 1027 ,0 }; - static ulong[] dim2985KuoInit = { 1 , 3 , 5 , 7 , 19 , 47 , 73 , 175 , 103 , 35 , 1039 , 343 , 6757 , 11521 , 24495 ,0 }; - static ulong[] dim2986KuoInit = { 1 , 3 , 1 , 9 , 17 , 19 , 9 , 205 , 279 , 373 , 173 , 3641 , 3945 , 10831 , 15621 ,0 }; - static ulong[] dim2987KuoInit = { 1 , 1 , 3 , 13 , 29 , 63 , 71 , 217 , 367 , 381 , 647 , 9 , 5521 , 5209 , 24275 ,0 }; - static ulong[] dim2988KuoInit = { 1 , 3 , 7 , 7 , 23 , 15 , 7 , 203 , 153 , 655 , 2047 , 287 , 973 , 6757 , 29207 ,0 }; - static ulong[] dim2989KuoInit = { 1 , 1 , 1 , 9 , 17 , 33 , 63 , 97 , 49 , 31 , 1989 , 569 , 3321 , 4017 , 6437 ,0 }; - static ulong[] dim2990KuoInit = { 1 , 1 , 7 , 11 , 15 , 15 , 57 , 255 , 381 , 115 , 573 , 3903 , 7141 , 1569 , 11789 ,0 }; - static ulong[] dim2991KuoInit = { 1 , 1 , 5 , 13 , 9 , 45 , 69 , 111 , 91 , 389 , 1347 , 3351 , 3023 , 517 , 28373 ,0 }; - static ulong[] dim2992KuoInit = { 1 , 3 , 3 , 15 , 9 , 11 , 81 , 205 , 299 , 903 , 661 , 3377 , 5355 , 9151 , 17597 ,0 }; - static ulong[] dim2993KuoInit = { 1 , 1 , 3 , 9 , 19 , 55 , 45 , 123 , 285 , 161 , 1591 , 1971 , 5471 , 8221 , 2855 ,0 }; - static ulong[] dim2994KuoInit = { 1 , 3 , 5 , 13 , 23 , 25 , 87 , 197 , 303 , 487 , 395 , 3137 , 4395 , 5861 , 5847 ,0 }; - static ulong[] dim2995KuoInit = { 1 , 3 , 7 , 5 , 23 , 9 , 107 , 13 , 127 , 971 , 1701 , 2387 , 6195 , 5041 , 24857 ,0 }; - static ulong[] dim2996KuoInit = { 1 , 1 , 3 , 3 , 19 , 63 , 91 , 205 , 207 , 897 , 295 , 2093 , 1223 , 14599 , 13803 ,0 }; - static ulong[] dim2997KuoInit = { 1 , 1 , 5 , 1 , 1 , 25 , 93 , 33 , 393 , 221 , 1845 , 2517 , 1723 , 13881 , 15777 ,0 }; - static ulong[] dim2998KuoInit = { 1 , 3 , 5 , 3 , 1 , 21 , 115 , 103 , 377 , 789 , 541 , 3423 , 3111 , 8077 , 25089 ,0 }; - static ulong[] dim2999KuoInit = { 1 , 1 , 1 , 11 , 31 , 55 , 95 , 53 , 141 , 697 , 1085 , 3031 , 653 , 4145 , 28121 ,0 }; - static ulong[] dim3000KuoInit = { 1 , 3 , 1 , 1 , 7 , 39 , 55 , 57 , 447 , 257 , 101 , 2307 , 5623 , 8505 , 995 ,0 }; - static ulong[] dim3001KuoInit = { 1 , 3 , 5 , 11 , 25 , 37 , 11 , 203 , 361 , 281 , 701 , 3643 , 957 , 14541 , 8109 ,0 }; - static ulong[] dim3002KuoInit = { 1 , 3 , 1 , 3 , 21 , 49 , 57 , 225 , 21 , 523 , 1275 , 3743 , 6259 , 13625 , 26721 ,0 }; - static ulong[] dim3003KuoInit = { 1 , 1 , 1 , 1 , 13 , 53 , 9 , 167 , 117 , 971 , 875 , 2659 , 7589 , 13575 , 11659 ,0 }; - static ulong[] dim3004KuoInit = { 1 , 1 , 7 , 13 , 21 , 1 , 35 , 201 , 261 , 533 , 1069 , 1459 , 5433 , 7211 , 3535 ,0 }; - static ulong[] dim3005KuoInit = { 1 , 1 , 3 , 13 , 23 , 7 , 41 , 137 , 341 , 767 , 1823 , 3745 , 1415 , 4811 , 21669 ,0 }; - static ulong[] dim3006KuoInit = { 1 , 3 , 3 , 5 , 5 , 11 , 71 , 117 , 451 , 1 , 381 , 967 , 7977 , 10741 , 20141 ,0 }; - static ulong[] dim3007KuoInit = { 1 , 3 , 1 , 3 , 21 , 1 , 65 , 37 , 451 , 29 , 327 , 2471 , 7573 , 5051 , 23925 ,0 }; - static ulong[] dim3008KuoInit = { 1 , 3 , 3 , 11 , 17 , 61 , 97 , 121 , 327 , 929 , 1165 , 185 , 2343 , 1479 , 3817 ,0 }; - static ulong[] dim3009KuoInit = { 1 , 1 , 3 , 7 , 27 , 55 , 87 , 53 , 389 , 577 , 1051 , 2413 , 609 , 12651 , 15695 ,0 }; - static ulong[] dim3010KuoInit = { 1 , 3 , 5 , 13 , 1 , 41 , 25 , 149 , 175 , 667 , 1219 , 2297 , 6599 , 1667 , 19647 ,0 }; - static ulong[] dim3011KuoInit = { 1 , 1 , 3 , 11 , 17 , 63 , 83 , 37 , 425 , 675 , 1111 , 499 , 7727 , 7491 , 9759 ,0 }; - static ulong[] dim3012KuoInit = { 1 , 1 , 3 , 1 , 21 , 23 , 17 , 125 , 485 , 643 , 341 , 1159 , 7073 , 14405 , 22409 ,0 }; - static ulong[] dim3013KuoInit = { 1 , 3 , 7 , 15 , 15 , 53 , 23 , 17 , 365 , 101 , 685 , 1391 , 5123 , 14961 , 31179 ,0 }; - static ulong[] dim3014KuoInit = { 1 , 3 , 3 , 3 , 23 , 11 , 101 , 139 , 401 , 779 , 1723 , 3421 , 623 , 3443 , 17179 ,0 }; - static ulong[] dim3015KuoInit = { 1 , 1 , 1 , 7 , 13 , 19 , 93 , 129 , 127 , 389 , 1361 , 2341 , 6491 , 15063 , 8199 ,0 }; - static ulong[] dim3016KuoInit = { 1 , 1 , 7 , 1 , 31 , 1 , 55 , 169 , 373 , 69 , 539 , 513 , 6329 , 393 , 21963 ,0 }; - static ulong[] dim3017KuoInit = { 1 , 1 , 7 , 1 , 5 , 39 , 73 , 87 , 401 , 923 , 1747 , 565 , 2227 , 14509 , 7601 ,0 }; - static ulong[] dim3018KuoInit = { 1 , 3 , 3 , 1 , 25 , 3 , 77 , 207 , 149 , 591 , 1165 , 3235 , 7615 , 12237 , 20849 ,0 }; - static ulong[] dim3019KuoInit = { 1 , 3 , 1 , 11 , 21 , 41 , 83 , 109 , 265 , 349 , 485 , 1411 , 2705 , 13017 , 25205 ,0 }; - static ulong[] dim3020KuoInit = { 1 , 1 , 7 , 7 , 31 , 27 , 55 , 23 , 129 , 369 , 1785 , 2031 , 1993 , 123 , 20063 ,0 }; - static ulong[] dim3021KuoInit = { 1 , 3 , 5 , 9 , 9 , 45 , 75 , 37 , 69 , 957 , 2047 , 2515 , 5327 , 15345 , 2147 ,0 }; - static ulong[] dim3022KuoInit = { 1 , 3 , 1 , 7 , 5 , 57 , 91 , 19 , 499 , 173 , 765 , 3653 , 6397 , 1509 , 11223 ,0 }; - static ulong[] dim3023KuoInit = { 1 , 3 , 5 , 15 , 1 , 15 , 69 , 107 , 225 , 233 , 1015 , 807 , 4265 , 8823 , 22047 ,0 }; - static ulong[] dim3024KuoInit = { 1 , 1 , 7 , 13 , 15 , 55 , 15 , 83 , 49 , 711 , 935 , 1865 , 29 , 607 , 8113 ,0 }; - static ulong[] dim3025KuoInit = { 1 , 3 , 1 , 15 , 13 , 15 , 127 , 193 , 219 , 653 , 1787 , 905 , 3311 , 11595 , 21193 ,0 }; - static ulong[] dim3026KuoInit = { 1 , 3 , 5 , 11 , 21 , 51 , 67 , 97 , 371 , 367 , 1763 , 2953 , 3701 , 15983 , 18631 ,0 }; - static ulong[] dim3027KuoInit = { 1 , 1 , 5 , 9 , 13 , 1 , 83 , 15 , 305 , 939 , 1073 , 1577 , 2073 , 5335 , 17173 ,0 }; - static ulong[] dim3028KuoInit = { 1 , 3 , 5 , 7 , 19 , 7 , 27 , 213 , 357 , 681 , 1969 , 4007 , 7887 , 11191 , 19395 ,0 }; - static ulong[] dim3029KuoInit = { 1 , 1 , 5 , 3 , 19 , 29 , 119 , 239 , 123 , 559 , 1613 , 1563 , 8047 , 5753 , 26719 ,0 }; - static ulong[] dim3030KuoInit = { 1 , 3 , 7 , 5 , 3 , 3 , 127 , 241 , 333 , 453 , 1407 , 2687 , 4603 , 3637 , 23041 ,0 }; - static ulong[] dim3031KuoInit = { 1 , 1 , 1 , 15 , 17 , 9 , 7 , 31 , 145 , 613 , 1851 , 1981 , 3921 , 6469 , 32397 ,0 }; - static ulong[] dim3032KuoInit = { 1 , 1 , 5 , 3 , 9 , 39 , 113 , 79 , 165 , 359 , 1573 , 2311 , 651 , 7047 , 15961 ,0 }; - static ulong[] dim3033KuoInit = { 1 , 3 , 7 , 7 , 11 , 57 , 59 , 153 , 363 , 279 , 77 , 3085 , 5971 , 29 , 22087 ,0 }; - static ulong[] dim3034KuoInit = { 1 , 1 , 7 , 11 , 25 , 47 , 49 , 229 , 147 , 777 , 1177 , 1117 , 3783 , 3681 , 1465 ,0 }; - static ulong[] dim3035KuoInit = { 1 , 3 , 5 , 11 , 3 , 45 , 11 , 139 , 393 , 9 , 471 , 1643 , 4963 , 5837 , 17023 ,0 }; - static ulong[] dim3036KuoInit = { 1 , 3 , 1 , 7 , 5 , 41 , 123 , 113 , 223 , 237 , 239 , 1099 , 6065 , 11105 , 10259 ,0 }; - static ulong[] dim3037KuoInit = { 1 , 1 , 3 , 11 , 15 , 57 , 41 , 173 , 169 , 585 , 201 , 2133 , 2629 , 12861 , 16559 ,0 }; - static ulong[] dim3038KuoInit = { 1 , 1 , 7 , 5 , 9 , 27 , 3 , 157 , 279 , 393 , 1849 , 437 , 5549 , 10009 , 11783 ,0 }; - static ulong[] dim3039KuoInit = { 1 , 1 , 7 , 9 , 17 , 23 , 67 , 143 , 1 , 203 , 153 , 1699 , 1333 , 16001 , 11755 ,0 }; - static ulong[] dim3040KuoInit = { 1 , 3 , 5 , 15 , 17 , 61 , 59 , 235 , 67 , 393 , 1597 , 3523 , 2049 , 11887 , 7737 ,0 }; - static ulong[] dim3041KuoInit = { 1 , 3 , 5 , 13 , 21 , 45 , 5 , 221 , 299 , 887 , 699 , 959 , 1143 , 4879 , 8767 ,0 }; - static ulong[] dim3042KuoInit = { 1 , 3 , 7 , 15 , 11 , 35 , 83 , 237 , 167 , 1 , 1429 , 2877 , 4611 , 14881 , 4453 ,0 }; - static ulong[] dim3043KuoInit = { 1 , 3 , 5 , 3 , 7 , 55 , 21 , 237 , 9 , 743 , 1707 , 1229 , 6827 , 407 , 777 ,0 }; - static ulong[] dim3044KuoInit = { 1 , 3 , 7 , 3 , 15 , 39 , 3 , 127 , 163 , 747 , 1773 , 1569 , 2377 , 15023 , 32249 ,0 }; - static ulong[] dim3045KuoInit = { 1 , 1 , 7 , 7 , 19 , 33 , 1 , 55 , 319 , 585 , 413 , 1241 , 95 , 7163 , 29935 ,0 }; - static ulong[] dim3046KuoInit = { 1 , 3 , 1 , 1 , 7 , 51 , 77 , 197 , 481 , 517 , 1441 , 1779 , 1405 , 3633 , 32545 ,0 }; - static ulong[] dim3047KuoInit = { 1 , 3 , 7 , 5 , 13 , 51 , 69 , 35 , 131 , 115 , 1759 , 3991 , 8065 , 10311 , 12749 ,0 }; - static ulong[] dim3048KuoInit = { 1 , 3 , 3 , 5 , 5 , 35 , 37 , 181 , 371 , 543 , 1389 , 815 , 3261 , 11997 , 29665 ,0 }; - static ulong[] dim3049KuoInit = { 1 , 3 , 7 , 11 , 31 , 47 , 33 , 147 , 445 , 663 , 63 , 1033 , 6081 , 15523 , 28477 ,0 }; - static ulong[] dim3050KuoInit = { 1 , 1 , 7 , 11 , 11 , 9 , 1 , 39 , 357 , 873 , 1829 , 3245 , 3219 , 601 , 1335 ,0 }; - static ulong[] dim3051KuoInit = { 1 , 1 , 5 , 7 , 5 , 5 , 33 , 145 , 465 , 5 , 1959 , 3573 , 3791 , 8689 , 14513 ,0 }; - static ulong[] dim3052KuoInit = { 1 , 1 , 1 , 13 , 31 , 37 , 103 , 255 , 87 , 903 , 1325 , 1423 , 8031 , 14845 , 12261 ,0 }; - static ulong[] dim3053KuoInit = { 1 , 3 , 3 , 13 , 31 , 25 , 41 , 45 , 261 , 225 , 1711 , 641 , 2331 , 10825 , 21539 ,0 }; - static ulong[] dim3054KuoInit = { 1 , 3 , 1 , 9 , 9 , 33 , 23 , 135 , 165 , 363 , 1435 , 3019 , 4907 , 9791 , 1337 ,0 }; - static ulong[] dim3055KuoInit = { 1 , 3 , 3 , 3 , 13 , 23 , 109 , 161 , 107 , 829 , 1635 , 791 , 2757 , 15265 , 8771 ,0 }; - static ulong[] dim3056KuoInit = { 1 , 1 , 1 , 11 , 7 , 17 , 45 , 167 , 69 , 437 , 1051 , 1443 , 875 , 2461 , 28471 ,0 }; - static ulong[] dim3057KuoInit = { 1 , 3 , 5 , 11 , 23 , 43 , 55 , 69 , 365 , 497 , 1529 , 1101 , 211 , 8145 , 10579 ,0 }; - static ulong[] dim3058KuoInit = { 1 , 1 , 5 , 3 , 19 , 9 , 91 , 91 , 453 , 875 , 1815 , 1455 , 7969 , 5621 , 4773 ,0 }; - static ulong[] dim3059KuoInit = { 1 , 1 , 5 , 1 , 17 , 63 , 19 , 193 , 335 , 571 , 703 , 919 , 773 , 1789 , 17839 ,0 }; - static ulong[] dim3060KuoInit = { 1 , 1 , 5 , 7 , 1 , 57 , 11 , 171 , 11 , 833 , 191 , 1719 , 7649 , 11005 , 20171 ,0 }; - static ulong[] dim3061KuoInit = { 1 , 1 , 7 , 15 , 25 , 55 , 63 , 71 , 127 , 445 , 1151 , 2709 , 6633 , 4959 , 13511 ,0 }; - static ulong[] dim3062KuoInit = { 1 , 1 , 3 , 1 , 3 , 41 , 43 , 59 , 211 , 123 , 987 , 3701 , 6391 , 6755 , 3069 ,0 }; - static ulong[] dim3063KuoInit = { 1 , 1 , 3 , 11 , 5 , 3 , 93 , 29 , 233 , 365 , 117 , 1483 , 4917 , 1949 , 23697 ,0 }; - static ulong[] dim3064KuoInit = { 1 , 3 , 5 , 1 , 15 , 53 , 21 , 9 , 23 , 701 , 1337 , 2591 , 7719 , 14063 , 28453 ,0 }; - static ulong[] dim3065KuoInit = { 1 , 1 , 1 , 11 , 21 , 3 , 127 , 179 , 409 , 261 , 1683 , 3197 , 1999 , 10009 , 25031 ,0 }; - static ulong[] dim3066KuoInit = { 1 , 3 , 5 , 13 , 31 , 57 , 9 , 91 , 31 , 125 , 1831 , 1943 , 5931 , 15015 , 22269 ,0 }; - static ulong[] dim3067KuoInit = { 1 , 3 , 5 , 9 , 7 , 7 , 83 , 113 , 203 , 679 , 1279 , 3403 , 7069 , 8617 , 27827 ,0 }; - static ulong[] dim3068KuoInit = { 1 , 3 , 7 , 5 , 29 , 47 , 93 , 59 , 315 , 107 , 807 , 2861 , 2345 , 11787 , 6543 ,0 }; - static ulong[] dim3069KuoInit = { 1 , 3 , 1 , 7 , 21 , 25 , 3 , 35 , 345 , 833 , 2029 , 281 , 2389 , 11529 , 20647 ,0 }; - static ulong[] dim3070KuoInit = { 1 , 1 , 1 , 13 , 19 , 47 , 109 , 21 , 251 , 625 , 1699 , 2169 , 7293 , 14035 , 24277 ,0 }; - static ulong[] dim3071KuoInit = { 1 , 3 , 5 , 13 , 15 , 7 , 51 , 125 , 423 , 981 , 437 , 1021 , 5209 , 11447 , 26181 ,0 }; - static ulong[] dim3072KuoInit = { 1 , 3 , 1 , 1 , 15 , 41 , 75 , 227 , 13 , 85 , 675 , 3993 , 8163 , 8095 , 23801 ,0 }; - static ulong[] dim3073KuoInit = { 1 , 3 , 3 , 9 , 25 , 1 , 85 , 143 , 309 , 815 , 1271 , 1331 , 6565 , 369 , 7975 ,0 }; - static ulong[] dim3074KuoInit = { 1 , 1 , 7 , 1 , 21 , 45 , 113 , 153 , 283 , 117 , 1481 , 3527 , 3371 , 15801 , 22337 ,0 }; - static ulong[] dim3075KuoInit = { 1 , 3 , 5 , 1 , 17 , 47 , 107 , 25 , 373 , 549 , 1387 , 1247 , 2307 , 6469 , 24327 ,0 }; - static ulong[] dim3076KuoInit = { 1 , 1 , 5 , 15 , 9 , 57 , 43 , 179 , 157 , 119 , 547 , 3665 , 1495 , 13405 , 2391 ,0 }; - static ulong[] dim3077KuoInit = { 1 , 3 , 1 , 1 , 7 , 57 , 123 , 189 , 281 , 87 , 1559 , 2863 , 8017 , 10279 , 32005 ,0 }; - static ulong[] dim3078KuoInit = { 1 , 1 , 5 , 1 , 29 , 21 , 51 , 123 , 351 , 683 , 1505 , 681 , 49 , 2929 , 7591 ,0 }; - static ulong[] dim3079KuoInit = { 1 , 1 , 3 , 7 , 17 , 63 , 119 , 209 , 441 , 717 , 567 , 1283 , 1007 , 14661 , 32383 ,0 }; - static ulong[] dim3080KuoInit = { 1 , 3 , 1 , 7 , 27 , 41 , 41 , 157 , 487 , 257 , 1267 , 165 , 1023 , 16065 , 16431 ,0 }; - static ulong[] dim3081KuoInit = { 1 , 1 , 3 , 9 , 17 , 53 , 51 , 175 , 367 , 453 , 1445 , 1889 , 4567 , 1781 , 6543 ,0 }; - static ulong[] dim3082KuoInit = { 1 , 1 , 7 , 1 , 27 , 47 , 95 , 51 , 483 , 581 , 1617 , 685 , 3017 , 4889 , 6185 ,0 }; - static ulong[] dim3083KuoInit = { 1 , 3 , 3 , 9 , 29 , 23 , 9 , 23 , 165 , 3 , 279 , 861 , 1007 , 9607 , 24999 ,0 }; - static ulong[] dim3084KuoInit = { 1 , 1 , 1 , 5 , 11 , 59 , 55 , 135 , 399 , 729 , 683 , 2119 , 3781 , 15525 , 1125 ,0 }; - static ulong[] dim3085KuoInit = { 1 , 3 , 3 , 15 , 25 , 61 , 123 , 153 , 267 , 823 , 951 , 4069 , 8017 , 4899 , 6535 ,0 }; - static ulong[] dim3086KuoInit = { 1 , 1 , 7 , 11 , 5 , 43 , 5 , 123 , 57 , 229 , 129 , 131 , 7491 , 2105 , 16411 ,0 }; - static ulong[] dim3087KuoInit = { 1 , 1 , 5 , 11 , 9 , 37 , 123 , 211 , 331 , 623 , 1469 , 1155 , 6327 , 12591 , 18971 ,0 }; - static ulong[] dim3088KuoInit = { 1 , 1 , 1 , 11 , 17 , 35 , 59 , 137 , 451 , 829 , 365 , 305 , 5857 , 2095 , 14597 ,0 }; - static ulong[] dim3089KuoInit = { 1 , 3 , 7 , 7 , 15 , 11 , 23 , 201 , 247 , 883 , 1103 , 4035 , 5915 , 4275 , 12511 ,0 }; - static ulong[] dim3090KuoInit = { 1 , 3 , 7 , 1 , 27 , 19 , 87 , 189 , 91 , 113 , 237 , 2073 , 419 , 1339 , 16705 ,0 }; - static ulong[] dim3091KuoInit = { 1 , 3 , 7 , 7 , 15 , 59 , 99 , 237 , 167 , 327 , 1507 , 771 , 3743 , 1723 , 28873 ,0 }; - static ulong[] dim3092KuoInit = { 1 , 3 , 5 , 15 , 27 , 19 , 35 , 175 , 403 , 1 , 617 , 2425 , 2021 , 12547 , 23655 ,0 }; - static ulong[] dim3093KuoInit = { 1 , 1 , 7 , 1 , 7 , 1 , 45 , 169 , 43 , 501 , 1653 , 593 , 7219 , 5501 , 3671 ,0 }; - static ulong[] dim3094KuoInit = { 1 , 1 , 5 , 3 , 23 , 53 , 117 , 165 , 329 , 177 , 89 , 2269 , 7897 , 11225 , 25807 ,0 }; - static ulong[] dim3095KuoInit = { 1 , 1 , 5 , 11 , 25 , 41 , 91 , 43 , 107 , 699 , 1745 , 3117 , 7497 , 6579 , 21803 ,0 }; - static ulong[] dim3096KuoInit = { 1 , 3 , 3 , 13 , 19 , 9 , 103 , 65 , 413 , 459 , 1751 , 4025 , 6695 , 9589 , 1443 ,0 }; - static ulong[] dim3097KuoInit = { 1 , 3 , 5 , 15 , 31 , 31 , 23 , 251 , 343 , 809 , 283 , 1501 , 445 , 7945 , 26993 ,0 }; - static ulong[] dim3098KuoInit = { 1 , 3 , 7 , 11 , 1 , 11 , 113 , 235 , 127 , 45 , 109 , 2421 , 3955 , 1017 , 21497 ,0 }; - static ulong[] dim3099KuoInit = { 1 , 3 , 1 , 13 , 5 , 57 , 47 , 227 , 447 , 499 , 1755 , 3527 , 1625 , 13341 , 22301 ,0 }; - static ulong[] dim3100KuoInit = { 1 , 3 , 1 , 9 , 13 , 9 , 113 , 101 , 377 , 39 , 991 , 3791 , 7351 , 12841 , 2911 ,0 }; - static ulong[] dim3101KuoInit = { 1 , 1 , 3 , 1 , 1 , 31 , 111 , 85 , 247 , 387 , 1907 , 3061 , 569 , 5845 , 6729 ,0 }; - static ulong[] dim3102KuoInit = { 1 , 3 , 7 , 15 , 31 , 17 , 77 , 33 , 109 , 661 , 67 , 3725 , 955 , 9475 , 14345 ,0 }; - static ulong[] dim3103KuoInit = { 1 , 1 , 7 , 15 , 11 , 23 , 63 , 23 , 67 , 843 , 1747 , 2441 , 2063 , 8575 , 11921 ,0 }; - static ulong[] dim3104KuoInit = { 1 , 3 , 5 , 13 , 25 , 19 , 43 , 177 , 67 , 57 , 1127 , 3817 , 3097 , 6143 , 27757 ,0 }; - static ulong[] dim3105KuoInit = { 1 , 1 , 3 , 1 , 19 , 25 , 65 , 135 , 143 , 863 , 1013 , 1285 , 6133 , 13491 , 5093 ,0 }; - static ulong[] dim3106KuoInit = { 1 , 3 , 5 , 15 , 7 , 17 , 61 , 199 , 39 , 767 , 295 , 127 , 335 , 10789 , 20473 ,0 }; - static ulong[] dim3107KuoInit = { 1 , 3 , 3 , 15 , 15 , 51 , 87 , 75 , 439 , 71 , 1371 , 1911 , 1145 , 4201 , 26883 ,0 }; - static ulong[] dim3108KuoInit = { 1 , 1 , 3 , 11 , 3 , 15 , 79 , 237 , 43 , 375 , 1925 , 1517 , 6415 , 303 , 2217 ,0 }; - static ulong[] dim3109KuoInit = { 1 , 3 , 1 , 3 , 21 , 23 , 19 , 83 , 159 , 249 , 1297 , 1853 , 2609 , 13635 , 29119 ,0 }; - static ulong[] dim3110KuoInit = { 1 , 1 , 3 , 9 , 29 , 53 , 125 , 73 , 299 , 45 , 557 , 3641 , 1593 , 10585 , 22545 ,0 }; - static ulong[] dim3111KuoInit = { 1 , 1 , 3 , 9 , 13 , 45 , 53 , 245 , 401 , 635 , 785 , 2841 , 3033 , 12377 , 1235 ,0 }; - static ulong[] dim3112KuoInit = { 1 , 1 , 3 , 11 , 23 , 35 , 71 , 207 , 211 , 901 , 351 , 1473 , 6683 , 981 , 17449 ,0 }; - static ulong[] dim3113KuoInit = { 1 , 1 , 3 , 9 , 17 , 13 , 125 , 213 , 109 , 631 , 677 , 2141 , 1037 , 6119 , 25945 ,0 }; - static ulong[] dim3114KuoInit = { 1 , 3 , 7 , 1 , 29 , 3 , 53 , 23 , 45 , 347 , 27 , 1537 , 7833 , 16315 , 12337 ,0 }; - static ulong[] dim3115KuoInit = { 1 , 3 , 1 , 1 , 31 , 23 , 15 , 241 , 315 , 977 , 99 , 3067 , 3227 , 6153 , 9751 ,0 }; - static ulong[] dim3116KuoInit = { 1 , 1 , 7 , 7 , 13 , 33 , 5 , 5 , 29 , 547 , 1105 , 1135 , 7263 , 7421 , 9545 ,0 }; - static ulong[] dim3117KuoInit = { 1 , 3 , 7 , 13 , 19 , 25 , 53 , 239 , 65 , 417 , 1681 , 659 , 133 , 4113 , 16735 ,0 }; - static ulong[] dim3118KuoInit = { 1 , 3 , 7 , 5 , 3 , 55 , 57 , 33 , 357 , 885 , 941 , 3471 , 6863 , 777 , 19111 ,0 }; - static ulong[] dim3119KuoInit = { 1 , 1 , 1 , 9 , 27 , 47 , 65 , 161 , 115 , 577 , 1951 , 363 , 2045 , 2497 , 6931 ,0 }; - static ulong[] dim3120KuoInit = { 1 , 3 , 3 , 11 , 29 , 37 , 21 , 235 , 233 , 833 , 81 , 2875 , 4759 , 8435 , 16017 ,0 }; - static ulong[] dim3121KuoInit = { 1 , 1 , 3 , 7 , 9 , 57 , 89 , 21 , 291 , 445 , 1833 , 735 , 3935 , 14943 , 30987 ,0 }; - static ulong[] dim3122KuoInit = { 1 , 1 , 5 , 13 , 23 , 9 , 37 , 71 , 175 , 899 , 1897 , 707 , 6201 , 15543 , 13801 ,0 }; - static ulong[] dim3123KuoInit = { 1 , 3 , 7 , 1 , 13 , 25 , 17 , 209 , 455 , 969 , 755 , 397 , 4103 , 3159 , 28665 ,0 }; - static ulong[] dim3124KuoInit = { 1 , 1 , 1 , 5 , 15 , 7 , 17 , 249 , 299 , 423 , 83 , 1203 , 7397 , 15657 , 15661 ,0 }; - static ulong[] dim3125KuoInit = { 1 , 1 , 7 , 7 , 19 , 19 , 21 , 231 , 443 , 729 , 947 , 1451 , 3399 , 5691 , 11943 ,0 }; - static ulong[] dim3126KuoInit = { 1 , 1 , 5 , 7 , 15 , 11 , 89 , 211 , 459 , 3 , 741 , 105 , 1147 , 927 , 31805 ,0 }; - static ulong[] dim3127KuoInit = { 1 , 1 , 7 , 9 , 7 , 1 , 61 , 145 , 291 , 1021 , 221 , 821 , 4999 , 3165 , 22549 ,0 }; - static ulong[] dim3128KuoInit = { 1 , 1 , 1 , 7 , 5 , 41 , 101 , 137 , 143 , 249 , 87 , 4045 , 2301 , 3833 , 9841 ,0 }; - static ulong[] dim3129KuoInit = { 1 , 1 , 5 , 5 , 19 , 61 , 111 , 109 , 87 , 65 , 971 , 3943 , 6559 , 9647 , 3049 ,0 }; - static ulong[] dim3130KuoInit = { 1 , 1 , 1 , 13 , 9 , 11 , 41 , 61 , 145 , 27 , 1287 , 3537 , 1943 , 10635 , 32557 ,0 }; - static ulong[] dim3131KuoInit = { 1 , 3 , 5 , 7 , 17 , 35 , 29 , 177 , 5 , 131 , 465 , 1235 , 1383 , 14253 , 17595 ,0 }; - static ulong[] dim3132KuoInit = { 1 , 1 , 3 , 7 , 15 , 63 , 21 , 119 , 195 , 627 , 1635 , 2369 , 5549 , 7641 , 29481 ,0 }; - static ulong[] dim3133KuoInit = { 1 , 1 , 7 , 13 , 25 , 3 , 73 , 233 , 115 , 749 , 707 , 1939 , 3667 , 1899 , 22345 ,0 }; - static ulong[] dim3134KuoInit = { 1 , 1 , 5 , 9 , 15 , 33 , 17 , 91 , 507 , 289 , 1929 , 2001 , 629 , 15559 , 12725 ,0 }; - static ulong[] dim3135KuoInit = { 1 , 1 , 1 , 13 , 7 , 7 , 91 , 171 , 95 , 257 , 1611 , 3527 , 2769 , 5779 , 7783 ,0 }; - static ulong[] dim3136KuoInit = { 1 , 1 , 1 , 13 , 27 , 27 , 55 , 113 , 171 , 61 , 1229 , 3681 , 4487 , 9815 , 20357 ,0 }; - static ulong[] dim3137KuoInit = { 1 , 3 , 7 , 15 , 1 , 21 , 57 , 67 , 185 , 189 , 1673 , 3637 , 2987 , 4619 , 6339 ,0 }; - static ulong[] dim3138KuoInit = { 1 , 3 , 7 , 3 , 9 , 45 , 71 , 183 , 107 , 145 , 821 , 1115 , 6067 , 8301 , 7565 ,0 }; - static ulong[] dim3139KuoInit = { 1 , 3 , 5 , 1 , 21 , 29 , 85 , 9 , 427 , 553 , 887 , 2463 , 4023 , 9107 , 25405 ,0 }; - static ulong[] dim3140KuoInit = { 1 , 1 , 5 , 13 , 25 , 45 , 89 , 235 , 349 , 671 , 1667 , 2023 , 2385 , 1831 , 515 ,0 }; - static ulong[] dim3141KuoInit = { 1 , 1 , 1 , 11 , 17 , 37 , 95 , 77 , 445 , 169 , 829 , 9 , 2589 , 12809 , 32469 ,0 }; - static ulong[] dim3142KuoInit = { 1 , 1 , 5 , 5 , 23 , 31 , 117 , 81 , 275 , 861 , 1439 , 4041 , 3337 , 14945 , 15921 ,0 }; - static ulong[] dim3143KuoInit = { 1 , 1 , 3 , 13 , 9 , 21 , 121 , 23 , 133 , 563 , 1889 , 1939 , 4427 , 5501 , 4609 ,0 }; - static ulong[] dim3144KuoInit = { 1 , 1 , 7 , 7 , 17 , 25 , 7 , 245 , 319 , 697 , 1561 , 3209 , 2369 , 16045 , 31799 ,0 }; - static ulong[] dim3145KuoInit = { 1 , 1 , 7 , 5 , 13 , 19 , 83 , 165 , 457 , 1005 , 743 , 4049 , 2563 , 14487 , 23699 ,0 }; - static ulong[] dim3146KuoInit = { 1 , 1 , 7 , 1 , 5 , 25 , 65 , 185 , 27 , 235 , 1771 , 3505 , 6807 , 14715 , 19841 ,0 }; - static ulong[] dim3147KuoInit = { 1 , 1 , 7 , 11 , 15 , 15 , 19 , 111 , 99 , 397 , 315 , 2587 , 7335 , 4371 , 11753 ,0 }; - static ulong[] dim3148KuoInit = { 1 , 1 , 7 , 9 , 1 , 21 , 55 , 255 , 105 , 865 , 179 , 2127 , 4485 , 1803 , 19503 ,0 }; - static ulong[] dim3149KuoInit = { 1 , 3 , 7 , 13 , 27 , 23 , 9 , 9 , 323 , 421 , 671 , 3323 , 5263 , 2963 , 16065 ,0 }; - static ulong[] dim3150KuoInit = { 1 , 1 , 5 , 7 , 17 , 47 , 79 , 255 , 259 , 913 , 1691 , 1553 , 2443 , 14167 , 24499 ,0 }; - static ulong[] dim3151KuoInit = { 1 , 3 , 3 , 3 , 21 , 7 , 17 , 71 , 57 , 715 , 2023 , 2133 , 5439 , 12483 , 32547 ,0 }; - static ulong[] dim3152KuoInit = { 1 , 3 , 3 , 15 , 1 , 37 , 23 , 235 , 35 , 739 , 1767 , 3531 , 597 , 13259 , 7869 ,0 }; - static ulong[] dim3153KuoInit = { 1 , 3 , 3 , 9 , 7 , 5 , 29 , 129 , 223 , 991 , 31 , 375 , 1917 , 1157 , 9723 ,0 }; - static ulong[] dim3154KuoInit = { 1 , 3 , 5 , 5 , 29 , 33 , 33 , 73 , 339 , 21 , 2037 , 1127 , 6385 , 16335 , 25825 ,0 }; - static ulong[] dim3155KuoInit = { 1 , 3 , 7 , 7 , 7 , 49 , 103 , 235 , 503 , 687 , 277 , 2639 , 5997 , 11797 , 27141 ,0 }; - static ulong[] dim3156KuoInit = { 1 , 1 , 1 , 13 , 27 , 31 , 103 , 145 , 245 , 493 , 867 , 2075 , 5369 , 12551 , 4907 ,0 }; - static ulong[] dim3157KuoInit = { 1 , 3 , 1 , 5 , 19 , 57 , 101 , 165 , 61 , 201 , 1299 , 3081 , 8173 , 12835 , 7915 ,0 }; - static ulong[] dim3158KuoInit = { 1 , 3 , 5 , 3 , 29 , 23 , 49 , 41 , 473 , 273 , 1493 , 1915 , 6669 , 14263 , 13385 ,0 }; - static ulong[] dim3159KuoInit = { 1 , 1 , 5 , 9 , 21 , 27 , 49 , 73 , 281 , 1017 , 1905 , 1005 , 631 , 5963 , 5729 ,0 }; - static ulong[] dim3160KuoInit = { 1 , 3 , 3 , 5 , 9 , 25 , 1 , 155 , 275 , 675 , 831 , 109 , 5349 , 9607 , 22431 ,0 }; - static ulong[] dim3161KuoInit = { 1 , 1 , 1 , 3 , 11 , 33 , 43 , 63 , 293 , 425 , 1525 , 4091 , 1865 , 13187 , 25191 ,0 }; - static ulong[] dim3162KuoInit = { 1 , 1 , 1 , 7 , 27 , 25 , 89 , 39 , 11 , 961 , 1601 , 785 , 3317 , 13121 , 13647 ,0 }; - static ulong[] dim3163KuoInit = { 1 , 1 , 7 , 1 , 31 , 59 , 25 , 75 , 317 , 305 , 1585 , 3649 , 7099 , 1819 , 10977 ,0 }; - static ulong[] dim3164KuoInit = { 1 , 3 , 7 , 5 , 7 , 29 , 85 , 189 , 137 , 783 , 395 , 1887 , 6253 , 4043 , 32279 ,0 }; - static ulong[] dim3165KuoInit = { 1 , 1 , 3 , 7 , 15 , 47 , 53 , 125 , 325 , 579 , 1783 , 3393 , 485 , 13923 , 4947 ,0 }; - static ulong[] dim3166KuoInit = { 1 , 3 , 5 , 1 , 19 , 53 , 67 , 47 , 503 , 875 , 1717 , 857 , 5151 , 12279 , 21249 ,0 }; - static ulong[] dim3167KuoInit = { 1 , 1 , 5 , 11 , 1 , 53 , 49 , 211 , 139 , 955 , 1129 , 1967 , 6833 , 2923 , 13251 ,0 }; - static ulong[] dim3168KuoInit = { 1 , 3 , 3 , 9 , 15 , 53 , 103 , 71 , 51 , 379 , 1565 , 2017 , 6013 , 13147 , 1227 ,0 }; - static ulong[] dim3169KuoInit = { 1 , 3 , 3 , 1 , 17 , 25 , 105 , 177 , 275 , 969 , 1373 , 2471 , 6959 , 11107 , 23657 ,0 }; - static ulong[] dim3170KuoInit = { 1 , 3 , 1 , 13 , 15 , 3 , 19 , 145 , 309 , 1021 , 985 , 2385 , 5727 , 10357 , 4915 ,0 }; - static ulong[] dim3171KuoInit = { 1 , 3 , 1 , 9 , 27 , 33 , 63 , 115 , 369 , 613 , 277 , 751 , 1959 , 5709 , 1851 ,0 }; - static ulong[] dim3172KuoInit = { 1 , 1 , 7 , 7 , 11 , 31 , 95 , 131 , 383 , 821 , 725 , 1381 , 3953 , 14945 , 29101 ,0 }; - static ulong[] dim3173KuoInit = { 1 , 1 , 1 , 11 , 1 , 59 , 81 , 89 , 325 , 27 , 1865 , 987 , 3877 , 12509 , 4129 ,0 }; - static ulong[] dim3174KuoInit = { 1 , 3 , 5 , 7 , 3 , 33 , 63 , 141 , 429 , 847 , 1355 , 1451 , 4741 , 5427 , 16907 ,0 }; - static ulong[] dim3175KuoInit = { 1 , 3 , 5 , 9 , 25 , 45 , 27 , 249 , 453 , 673 , 1519 , 905 , 5235 , 10057 , 24965 ,0 }; - static ulong[] dim3176KuoInit = { 1 , 1 , 5 , 3 , 27 , 43 , 91 , 61 , 121 , 485 , 1047 , 405 , 8159 , 8363 , 19695 ,0 }; - static ulong[] dim3177KuoInit = { 1 , 1 , 3 , 9 , 17 , 5 , 107 , 139 , 293 , 685 , 521 , 253 , 3309 , 15335 , 4967 ,0 }; - static ulong[] dim3178KuoInit = { 1 , 1 , 7 , 13 , 7 , 43 , 63 , 119 , 225 , 269 , 1489 , 2983 , 1041 , 15149 , 21039 ,0 }; - static ulong[] dim3179KuoInit = { 1 , 3 , 1 , 5 , 5 , 1 , 123 , 255 , 469 , 139 , 1861 , 385 , 3123 , 14739 , 23049 ,0 }; - static ulong[] dim3180KuoInit = { 1 , 3 , 5 , 9 , 25 , 47 , 107 , 55 , 435 , 935 , 1751 , 555 , 973 , 10123 , 31869 ,0 }; - static ulong[] dim3181KuoInit = { 1 , 3 , 7 , 5 , 21 , 25 , 113 , 169 , 313 , 607 , 631 , 3409 , 6539 , 5781 , 12681 ,0 }; - static ulong[] dim3182KuoInit = { 1 , 1 , 3 , 15 , 7 , 13 , 1 , 245 , 57 , 495 , 905 , 1627 , 7107 , 13939 , 22091 ,0 }; - static ulong[] dim3183KuoInit = { 1 , 1 , 1 , 5 , 7 , 55 , 121 , 137 , 93 , 265 , 1263 , 2251 , 7101 , 3095 , 13779 ,0 }; - static ulong[] dim3184KuoInit = { 1 , 1 , 5 , 13 , 21 , 11 , 37 , 193 , 481 , 551 , 1659 , 563 , 4405 , 9541 , 8495 ,0 }; - static ulong[] dim3185KuoInit = { 1 , 1 , 3 , 15 , 5 , 7 , 23 , 19 , 147 , 779 , 1089 , 723 , 3837 , 16291 , 23911 ,0 }; - static ulong[] dim3186KuoInit = { 1 , 1 , 1 , 11 , 27 , 17 , 57 , 191 , 337 , 361 , 1261 , 3605 , 8051 , 8909 , 14951 ,0 }; - static ulong[] dim3187KuoInit = { 1 , 3 , 3 , 9 , 25 , 23 , 39 , 109 , 107 , 605 , 373 , 649 , 5747 , 2037 , 24933 ,0 }; - static ulong[] dim3188KuoInit = { 1 , 3 , 5 , 7 , 9 , 27 , 91 , 53 , 153 , 497 , 941 , 2999 , 3721 , 11115 , 17589 ,0 }; - static ulong[] dim3189KuoInit = { 1 , 3 , 1 , 7 , 31 , 7 , 101 , 115 , 419 , 479 , 1097 , 2253 , 4365 , 14285 , 26469 ,0 }; - static ulong[] dim3190KuoInit = { 1 , 1 , 1 , 15 , 13 , 37 , 31 , 231 , 195 , 539 , 941 , 3723 , 2483 , 2603 , 18897 ,0 }; - static ulong[] dim3191KuoInit = { 1 , 3 , 5 , 13 , 7 , 31 , 19 , 99 , 197 , 833 , 79 , 3899 , 7045 , 6913 , 17959 ,0 }; - static ulong[] dim3192KuoInit = { 1 , 1 , 3 , 5 , 1 , 51 , 83 , 135 , 307 , 121 , 187 , 2135 , 2927 , 6183 , 20327 ,0 }; - static ulong[] dim3193KuoInit = { 1 , 3 , 5 , 11 , 7 , 31 , 47 , 123 , 409 , 239 , 1787 , 3063 , 6685 , 7487 , 31243 ,0 }; - static ulong[] dim3194KuoInit = { 1 , 3 , 7 , 9 , 9 , 31 , 57 , 5 , 493 , 771 , 1941 , 199 , 6389 , 681 , 19379 ,0 }; - static ulong[] dim3195KuoInit = { 1 , 1 , 5 , 3 , 1 , 57 , 63 , 35 , 369 , 267 , 923 , 2019 , 6487 , 15555 , 6993 ,0 }; - static ulong[] dim3196KuoInit = { 1 , 3 , 7 , 15 , 15 , 59 , 123 , 179 , 5 , 35 , 1061 , 125 , 1025 , 5907 , 29671 ,0 }; - static ulong[] dim3197KuoInit = { 1 , 3 , 1 , 11 , 21 , 63 , 71 , 237 , 333 , 893 , 1139 , 1969 , 2007 , 10017 , 27597 ,0 }; - static ulong[] dim3198KuoInit = { 1 , 1 , 1 , 13 , 15 , 29 , 103 , 241 , 25 , 135 , 1147 , 1263 , 4793 , 16109 , 22447 ,0 }; - static ulong[] dim3199KuoInit = { 1 , 1 , 3 , 7 , 11 , 21 , 85 , 7 , 123 , 69 , 1379 , 3243 , 7907 , 15859 , 19993 ,0 }; - static ulong[] dim3200KuoInit = { 1 , 3 , 5 , 3 , 17 , 49 , 125 , 211 , 165 , 307 , 1331 , 2287 , 1127 , 4031 , 13719 ,0 }; - static ulong[] dim3201KuoInit = { 1 , 1 , 7 , 1 , 23 , 23 , 21 , 159 , 387 , 443 , 291 , 2843 , 4413 , 9035 , 28887 ,0 }; - static ulong[] dim3202KuoInit = { 1 , 1 , 7 , 15 , 9 , 25 , 113 , 185 , 285 , 211 , 317 , 3721 , 6921 , 4921 , 2353 ,0 }; - static ulong[] dim3203KuoInit = { 1 , 1 , 3 , 5 , 21 , 9 , 53 , 21 , 337 , 51 , 429 , 4035 , 4697 , 3695 , 22589 ,0 }; - static ulong[] dim3204KuoInit = { 1 , 1 , 5 , 5 , 21 , 63 , 79 , 213 , 471 , 183 , 299 , 409 , 6125 , 3653 , 9785 ,0 }; - static ulong[] dim3205KuoInit = { 1 , 3 , 3 , 3 , 27 , 27 , 9 , 73 , 129 , 391 , 1877 , 4023 , 1631 , 7101 , 1491 ,0 }; - static ulong[] dim3206KuoInit = { 1 , 3 , 5 , 3 , 21 , 7 , 93 , 51 , 469 , 3 , 1343 , 3827 , 6623 , 10149 , 29233 ,0 }; - static ulong[] dim3207KuoInit = { 1 , 1 , 1 , 9 , 31 , 25 , 35 , 249 , 469 , 393 , 1315 , 1247 , 275 , 15841 , 23877 ,0 }; - static ulong[] dim3208KuoInit = { 1 , 3 , 5 , 11 , 25 , 47 , 105 , 45 , 79 , 131 , 499 , 1411 , 2077 , 9809 , 14917 ,0 }; - static ulong[] dim3209KuoInit = { 1 , 3 , 3 , 3 , 13 , 15 , 117 , 27 , 499 , 885 , 301 , 935 , 3443 , 3845 , 26873 ,0 }; - static ulong[] dim3210KuoInit = { 1 , 3 , 3 , 1 , 1 , 47 , 21 , 97 , 245 , 95 , 899 , 993 , 2493 , 5249 , 32695 ,0 }; - static ulong[] dim3211KuoInit = { 1 , 3 , 3 , 11 , 21 , 39 , 53 , 15 , 53 , 687 , 1269 , 1673 , 2015 , 3205 , 21447 ,0 }; - static ulong[] dim3212KuoInit = { 1 , 1 , 5 , 11 , 1 , 39 , 117 , 85 , 277 , 635 , 1459 , 3977 , 2449 , 13341 , 30607 ,0 }; - static ulong[] dim3213KuoInit = { 1 , 1 , 1 , 13 , 27 , 45 , 7 , 255 , 281 , 807 , 533 , 2173 , 4561 , 2501 , 5767 ,0 }; - static ulong[] dim3214KuoInit = { 1 , 3 , 5 , 1 , 21 , 17 , 65 , 123 , 239 , 431 , 1003 , 241 , 8115 , 11633 , 27709 ,0 }; - static ulong[] dim3215KuoInit = { 1 , 3 , 1 , 1 , 23 , 39 , 81 , 35 , 33 , 905 , 2019 , 3327 , 1197 , 6891 , 5521 ,0 }; - static ulong[] dim3216KuoInit = { 1 , 3 , 3 , 11 , 1 , 51 , 51 , 153 , 23 , 685 , 1663 , 3167 , 5803 , 11111 , 3371 ,0 }; - static ulong[] dim3217KuoInit = { 1 , 3 , 3 , 11 , 31 , 29 , 7 , 173 , 27 , 129 , 341 , 2971 , 4907 , 13481 , 19619 ,0 }; - static ulong[] dim3218KuoInit = { 1 , 3 , 3 , 9 , 29 , 29 , 115 , 3 , 45 , 765 , 385 , 3775 , 5349 , 8809 , 11019 ,0 }; - static ulong[] dim3219KuoInit = { 1 , 1 , 5 , 7 , 15 , 19 , 21 , 29 , 377 , 915 , 1835 , 517 , 3763 , 5439 , 7649 ,0 }; - static ulong[] dim3220KuoInit = { 1 , 3 , 7 , 13 , 25 , 27 , 33 , 225 , 135 , 869 , 1383 , 3817 , 2981 , 8185 , 5689 ,0 }; - static ulong[] dim3221KuoInit = { 1 , 1 , 5 , 9 , 1 , 27 , 19 , 55 , 39 , 451 , 365 , 2905 , 4311 , 16005 , 4537 ,0 }; - static ulong[] dim3222KuoInit = { 1 , 1 , 7 , 15 , 19 , 1 , 99 , 177 , 163 , 877 , 511 , 1977 , 3291 , 7739 , 6383 ,0 }; - static ulong[] dim3223KuoInit = { 1 , 1 , 7 , 15 , 1 , 29 , 27 , 1 , 411 , 425 , 2027 , 1739 , 5137 , 107 , 3515 ,0 }; - static ulong[] dim3224KuoInit = { 1 , 3 , 7 , 5 , 5 , 29 , 15 , 55 , 423 , 671 , 1145 , 2403 , 5429 , 11507 , 24747 ,0 }; - static ulong[] dim3225KuoInit = { 1 , 1 , 1 , 13 , 9 , 61 , 93 , 215 , 447 , 969 , 853 , 487 , 5735 , 2153 , 27857 ,0 }; - static ulong[] dim3226KuoInit = { 1 , 3 , 1 , 3 , 29 , 41 , 47 , 245 , 197 , 261 , 77 , 805 , 965 , 14089 , 29199 ,0 }; - static ulong[] dim3227KuoInit = { 1 , 1 , 5 , 11 , 3 , 49 , 53 , 7 , 91 , 123 , 413 , 123 , 7611 , 11493 , 16417 ,0 }; - static ulong[] dim3228KuoInit = { 1 , 3 , 7 , 9 , 23 , 59 , 105 , 191 , 13 , 421 , 1541 , 2045 , 2821 , 9769 , 19893 ,0 }; - static ulong[] dim3229KuoInit = { 1 , 3 , 5 , 13 , 3 , 19 , 37 , 229 , 465 , 1015 , 1871 , 1101 , 7515 , 8547 , 7853 ,0 }; - static ulong[] dim3230KuoInit = { 1 , 3 , 5 , 13 , 9 , 61 , 113 , 209 , 503 , 441 , 905 , 2693 , 1827 , 9551 , 26081 ,0 }; - static ulong[] dim3231KuoInit = { 1 , 1 , 1 , 7 , 31 , 27 , 123 , 37 , 415 , 729 , 921 , 453 , 673 , 14393 , 9139 ,0 }; - static ulong[] dim3232KuoInit = { 1 , 1 , 5 , 3 , 13 , 9 , 79 , 243 , 211 , 89 , 295 , 3663 , 8165 , 12099 , 1413 ,0 }; - static ulong[] dim3233KuoInit = { 1 , 1 , 5 , 7 , 23 , 33 , 33 , 129 , 51 , 965 , 1145 , 713 , 8143 , 10045 , 5291 ,0 }; - static ulong[] dim3234KuoInit = { 1 , 1 , 3 , 3 , 11 , 45 , 77 , 223 , 423 , 1021 , 343 , 3103 , 119 , 3371 , 24053 ,0 }; - static ulong[] dim3235KuoInit = { 1 , 1 , 7 , 7 , 7 , 3 , 65 , 31 , 433 , 277 , 1541 , 2001 , 121 , 13543 , 6723 ,0 }; - static ulong[] dim3236KuoInit = { 1 , 1 , 7 , 1 , 1 , 15 , 83 , 85 , 351 , 351 , 1063 , 3989 , 5739 , 11939 , 28009 ,0 }; - static ulong[] dim3237KuoInit = { 1 , 1 , 5 , 11 , 25 , 57 , 73 , 127 , 25 , 67 , 1789 , 199 , 6373 , 10945 , 17839 ,0 }; - static ulong[] dim3238KuoInit = { 1 , 3 , 5 , 11 , 17 , 15 , 5 , 191 , 209 , 455 , 89 , 2611 , 7557 , 16167 , 25993 ,0 }; - static ulong[] dim3239KuoInit = { 1 , 1 , 7 , 7 , 29 , 21 , 79 , 81 , 257 , 373 , 557 , 2363 , 5497 , 8343 , 2011 ,0 }; - static ulong[] dim3240KuoInit = { 1 , 1 , 5 , 11 , 25 , 63 , 83 , 31 , 477 , 201 , 2013 , 3349 , 3517 , 9527 , 14883 ,0 }; - static ulong[] dim3241KuoInit = { 1 , 3 , 7 , 13 , 21 , 13 , 41 , 151 , 359 , 829 , 661 , 1959 , 6109 , 13757 , 17677 ,0 }; - static ulong[] dim3242KuoInit = { 1 , 3 , 7 , 1 , 11 , 15 , 119 , 25 , 351 , 135 , 515 , 3727 , 5701 , 5283 , 18771 ,0 }; - static ulong[] dim3243KuoInit = { 1 , 1 , 1 , 3 , 3 , 59 , 55 , 117 , 269 , 161 , 645 , 3459 , 8173 , 7193 , 10275 ,0 }; - static ulong[] dim3244KuoInit = { 1 , 3 , 5 , 7 , 21 , 25 , 53 , 211 , 237 , 775 , 43 , 3613 , 5555 , 1689 , 1781 ,0 }; - static ulong[] dim3245KuoInit = { 1 , 1 , 1 , 7 , 31 , 43 , 71 , 201 , 371 , 457 , 1757 , 2529 , 7067 , 2987 , 3945 ,0 }; - static ulong[] dim3246KuoInit = { 1 , 1 , 5 , 7 , 15 , 47 , 29 , 83 , 259 , 813 , 881 , 1901 , 6635 , 8515 , 20385 ,0 }; - static ulong[] dim3247KuoInit = { 1 , 1 , 5 , 5 , 3 , 45 , 55 , 43 , 17 , 179 , 1801 , 49 , 8121 , 9333 , 12701 ,0 }; - static ulong[] dim3248KuoInit = { 1 , 1 , 3 , 9 , 21 , 9 , 55 , 59 , 275 , 775 , 1567 , 1557 , 3465 , 5727 , 12881 ,0 }; - static ulong[] dim3249KuoInit = { 1 , 1 , 1 , 5 , 21 , 63 , 81 , 27 , 139 , 859 , 1211 , 3787 , 1179 , 4045 , 26225 ,0 }; - static ulong[] dim3250KuoInit = { 1 , 3 , 7 , 3 , 7 , 5 , 99 , 125 , 499 , 437 , 1141 , 3557 , 5349 , 2701 , 25741 ,0 }; - static ulong[] dim3251KuoInit = { 1 , 1 , 5 , 1 , 7 , 59 , 65 , 117 , 201 , 351 , 1063 , 3083 , 6637 , 5969 , 23037 ,0 }; - static ulong[] dim3252KuoInit = { 1 , 3 , 7 , 7 , 25 , 45 , 115 , 31 , 351 , 203 , 1791 , 2931 , 7127 , 12117 , 10781 ,0 }; - static ulong[] dim3253KuoInit = { 1 , 1 , 3 , 3 , 29 , 59 , 85 , 101 , 147 , 219 , 1293 , 1645 , 7653 , 649 , 32221 ,0 }; - static ulong[] dim3254KuoInit = { 1 , 1 , 7 , 5 , 29 , 51 , 127 , 139 , 205 , 77 , 859 , 2277 , 2333 , 105 , 9053 ,0 }; - static ulong[] dim3255KuoInit = { 1 , 3 , 5 , 3 , 29 , 23 , 119 , 71 , 263 , 551 , 1095 , 359 , 6223 , 7665 , 1095 ,0 }; - static ulong[] dim3256KuoInit = { 1 , 3 , 1 , 11 , 13 , 47 , 11 , 207 , 507 , 139 , 1383 , 1339 , 4111 , 11685 , 12607 ,0 }; - static ulong[] dim3257KuoInit = { 1 , 3 , 7 , 3 , 25 , 9 , 87 , 117 , 21 , 289 , 351 , 225 , 4045 , 5275 , 531 ,0 }; - static ulong[] dim3258KuoInit = { 1 , 3 , 7 , 3 , 29 , 55 , 31 , 57 , 83 , 423 , 201 , 4055 , 1977 , 8891 , 17961 ,0 }; - static ulong[] dim3259KuoInit = { 1 , 1 , 1 , 3 , 9 , 7 , 45 , 237 , 413 , 53 , 1063 , 23 , 6615 , 16359 , 4743 ,0 }; - static ulong[] dim3260KuoInit = { 1 , 3 , 1 , 3 , 21 , 57 , 63 , 221 , 111 , 95 , 647 , 3419 , 1919 , 923 , 8357 ,0 }; - static ulong[] dim3261KuoInit = { 1 , 1 , 1 , 3 , 27 , 25 , 119 , 237 , 397 , 73 , 41 , 17 , 6839 , 15695 , 30365 ,0 }; - static ulong[] dim3262KuoInit = { 1 , 3 , 1 , 1 , 23 , 59 , 107 , 121 , 267 , 163 , 181 , 2289 , 167 , 7077 , 12895 ,0 }; - static ulong[] dim3263KuoInit = { 1 , 1 , 5 , 5 , 15 , 45 , 45 , 179 , 195 , 95 , 43 , 377 , 629 , 11983 , 23439 ,0 }; - static ulong[] dim3264KuoInit = { 1 , 3 , 3 , 9 , 17 , 43 , 67 , 143 , 223 , 243 , 209 , 3 , 7651 , 12607 , 3927 ,0 }; - static ulong[] dim3265KuoInit = { 1 , 3 , 1 , 11 , 19 , 21 , 59 , 75 , 353 , 509 , 1215 , 3223 , 2373 , 3873 , 20391 ,0 }; - static ulong[] dim3266KuoInit = { 1 , 1 , 7 , 3 , 7 , 9 , 53 , 89 , 407 , 987 , 1165 , 2473 , 4295 , 2531 , 5615 ,0 }; - static ulong[] dim3267KuoInit = { 1 , 1 , 3 , 11 , 23 , 7 , 111 , 147 , 49 , 627 , 1769 , 3497 , 2807 , 4743 , 26491 ,0 }; - static ulong[] dim3268KuoInit = { 1 , 3 , 3 , 13 , 29 , 29 , 83 , 57 , 377 , 581 , 1699 , 1689 , 2297 , 1377 , 24551 ,0 }; - static ulong[] dim3269KuoInit = { 1 , 3 , 5 , 15 , 25 , 33 , 41 , 187 , 195 , 647 , 73 , 619 , 5585 , 8379 , 26079 ,0 }; - static ulong[] dim3270KuoInit = { 1 , 1 , 3 , 9 , 3 , 47 , 105 , 83 , 501 , 843 , 1867 , 1855 , 6347 , 3269 , 26155 ,0 }; - static ulong[] dim3271KuoInit = { 1 , 3 , 3 , 15 , 29 , 33 , 117 , 141 , 171 , 801 , 1489 , 1 , 4081 , 15529 , 4081 ,0 }; - static ulong[] dim3272KuoInit = { 1 , 1 , 3 , 13 , 21 , 43 , 13 , 75 , 75 , 443 , 1443 , 3227 , 907 , 11821 , 24209 ,0 }; - static ulong[] dim3273KuoInit = { 1 , 1 , 3 , 3 , 31 , 31 , 111 , 193 , 275 , 545 , 371 , 3071 , 3491 , 6661 , 1113 ,0 }; - static ulong[] dim3274KuoInit = { 1 , 1 , 7 , 3 , 11 , 39 , 17 , 107 , 303 , 201 , 321 , 3083 , 6839 , 4381 , 3449 ,0 }; - static ulong[] dim3275KuoInit = { 1 , 1 , 7 , 15 , 31 , 21 , 7 , 143 , 211 , 369 , 369 , 323 , 3811 , 5131 , 11425 ,0 }; - static ulong[] dim3276KuoInit = { 1 , 1 , 1 , 3 , 9 , 27 , 23 , 21 , 349 , 607 , 529 , 1161 , 5753 , 6015 , 20489 ,0 }; - static ulong[] dim3277KuoInit = { 1 , 3 , 7 , 11 , 23 , 17 , 103 , 97 , 227 , 933 , 2011 , 1705 , 5185 , 299 , 5673 ,0 }; - static ulong[] dim3278KuoInit = { 1 , 3 , 5 , 9 , 7 , 45 , 63 , 43 , 339 , 299 , 1617 , 1393 , 4507 , 13513 , 29039 ,0 }; - static ulong[] dim3279KuoInit = { 1 , 1 , 5 , 5 , 17 , 11 , 49 , 159 , 51 , 449 , 497 , 2627 , 1541 , 15711 , 16591 ,0 }; - static ulong[] dim3280KuoInit = { 1 , 1 , 7 , 3 , 23 , 19 , 53 , 79 , 133 , 279 , 327 , 2847 , 5825 , 14429 , 26491 ,0 }; - static ulong[] dim3281KuoInit = { 1 , 3 , 1 , 3 , 17 , 3 , 33 , 55 , 263 , 663 , 1253 , 1509 , 4487 , 1811 , 32123 ,0 }; - static ulong[] dim3282KuoInit = { 1 , 3 , 7 , 9 , 17 , 7 , 23 , 87 , 221 , 183 , 1577 , 1373 , 2717 , 3323 , 24573 ,0 }; - static ulong[] dim3283KuoInit = { 1 , 3 , 3 , 9 , 5 , 51 , 45 , 11 , 11 , 135 , 505 , 221 , 3847 , 13487 , 23843 ,0 }; - static ulong[] dim3284KuoInit = { 1 , 1 , 5 , 13 , 15 , 61 , 85 , 53 , 321 , 433 , 61 , 3377 , 3993 , 15325 , 8641 ,0 }; - static ulong[] dim3285KuoInit = { 1 , 3 , 7 , 13 , 27 , 35 , 57 , 43 , 509 , 595 , 2033 , 77 , 7533 , 5027 , 15567 ,0 }; - static ulong[] dim3286KuoInit = { 1 , 1 , 1 , 1 , 31 , 51 , 69 , 157 , 105 , 797 , 249 , 2033 , 2457 , 10773 , 31537 ,0 }; - static ulong[] dim3287KuoInit = { 1 , 3 , 3 , 13 , 23 , 25 , 75 , 11 , 145 , 361 , 819 , 3689 , 5751 , 6395 , 30685 ,0 }; - static ulong[] dim3288KuoInit = { 1 , 1 , 7 , 11 , 13 , 25 , 13 , 175 , 11 , 685 , 835 , 2641 , 2037 , 2037 , 2807 ,0 }; - static ulong[] dim3289KuoInit = { 1 , 1 , 7 , 11 , 21 , 27 , 115 , 91 , 21 , 105 , 1817 , 2057 , 2797 , 3825 , 23761 ,0 }; - static ulong[] dim3290KuoInit = { 1 , 3 , 3 , 5 , 5 , 49 , 51 , 57 , 425 , 959 , 473 , 575 , 6851 , 3683 , 27429 ,0 }; - static ulong[] dim3291KuoInit = { 1 , 1 , 7 , 5 , 29 , 1 , 65 , 13 , 447 , 467 , 1193 , 4021 , 275 , 13453 , 29749 ,0 }; - static ulong[] dim3292KuoInit = { 1 , 3 , 5 , 11 , 27 , 53 , 71 , 63 , 125 , 545 , 1673 , 3917 , 6625 , 12805 , 2905 ,0 }; - static ulong[] dim3293KuoInit = { 1 , 3 , 3 , 1 , 7 , 1 , 45 , 65 , 23 , 237 , 1573 , 3445 , 6307 , 5015 , 11263 ,0 }; - static ulong[] dim3294KuoInit = { 1 , 1 , 5 , 1 , 7 , 29 , 67 , 35 , 307 , 675 , 727 , 2789 , 2353 , 13241 , 16621 ,0 }; - static ulong[] dim3295KuoInit = { 1 , 3 , 1 , 15 , 13 , 5 , 115 , 75 , 21 , 745 , 2027 , 265 , 3583 , 1365 , 397 ,0 }; - static ulong[] dim3296KuoInit = { 1 , 1 , 5 , 7 , 9 , 31 , 115 , 25 , 441 , 433 , 1665 , 2499 , 5765 , 4001 , 22105 ,0 }; - static ulong[] dim3297KuoInit = { 1 , 3 , 7 , 9 , 23 , 21 , 71 , 165 , 353 , 101 , 1335 , 3411 , 1415 , 12641 , 21961 ,0 }; - static ulong[] dim3298KuoInit = { 1 , 3 , 7 , 1 , 3 , 3 , 21 , 157 , 85 , 117 , 469 , 1573 , 2475 , 6471 , 15975 ,0 }; - static ulong[] dim3299KuoInit = { 1 , 1 , 7 , 9 , 31 , 35 , 127 , 221 , 447 , 697 , 1393 , 701 , 7291 , 4279 , 2897 ,0 }; - static ulong[] dim3300KuoInit = { 1 , 3 , 5 , 5 , 21 , 13 , 15 , 15 , 395 , 519 , 1985 , 2331 , 5483 , 13905 , 31549 ,0 }; - static ulong[] dim3301KuoInit = { 1 , 1 , 7 , 5 , 1 , 43 , 57 , 131 , 7 , 893 , 1631 , 1581 , 6691 , 6249 , 4975 ,0 }; - static ulong[] dim3302KuoInit = { 1 , 3 , 3 , 9 , 29 , 33 , 51 , 177 , 423 , 459 , 1293 , 2467 , 3877 , 15653 , 2727 ,0 }; - static ulong[] dim3303KuoInit = { 1 , 3 , 5 , 1 , 5 , 45 , 11 , 27 , 311 , 645 , 283 , 65 , 5913 , 12811 , 20041 ,0 }; - static ulong[] dim3304KuoInit = { 1 , 3 , 7 , 5 , 19 , 3 , 39 , 99 , 269 , 429 , 1901 , 2213 , 6755 , 1205 , 16073 ,0 }; - static ulong[] dim3305KuoInit = { 1 , 3 , 5 , 13 , 7 , 37 , 109 , 113 , 395 , 981 , 1991 , 845 , 2473 , 3801 , 24405 ,0 }; - static ulong[] dim3306KuoInit = { 1 , 1 , 1 , 15 , 9 , 31 , 117 , 213 , 141 , 867 , 387 , 1985 , 1985 , 12683 , 20501 ,0 }; - static ulong[] dim3307KuoInit = { 1 , 1 , 1 , 15 , 11 , 3 , 25 , 31 , 375 , 437 , 645 , 335 , 207 , 14915 , 2577 ,0 }; - static ulong[] dim3308KuoInit = { 1 , 1 , 7 , 7 , 19 , 61 , 87 , 107 , 53 , 777 , 31 , 3335 , 157 , 2927 , 25905 ,0 }; - static ulong[] dim3309KuoInit = { 1 , 1 , 7 , 9 , 13 , 13 , 21 , 151 , 51 , 501 , 213 , 2177 , 2821 , 3081 , 5955 ,0 }; - static ulong[] dim3310KuoInit = { 1 , 1 , 5 , 13 , 19 , 33 , 5 , 209 , 283 , 613 , 281 , 715 , 297 , 15033 , 20489 ,0 }; - static ulong[] dim3311KuoInit = { 1 , 3 , 5 , 5 , 31 , 7 , 31 , 49 , 5 , 41 , 939 , 2359 , 3663 , 10151 , 20457 ,0 }; - static ulong[] dim3312KuoInit = { 1 , 1 , 7 , 1 , 7 , 61 , 69 , 255 , 17 , 637 , 863 , 3351 , 6033 , 5005 , 23107 ,0 }; - static ulong[] dim3313KuoInit = { 1 , 1 , 5 , 3 , 5 , 61 , 15 , 87 , 111 , 383 , 1577 , 3515 , 789 , 4219 , 2527 ,0 }; - static ulong[] dim3314KuoInit = { 1 , 1 , 5 , 11 , 19 , 9 , 37 , 61 , 329 , 811 , 1829 , 3109 , 397 , 2065 , 32001 ,0 }; - static ulong[] dim3315KuoInit = { 1 , 3 , 1 , 9 , 7 , 13 , 55 , 7 , 463 , 307 , 1551 , 3161 , 649 , 14073 , 20839 ,0 }; - static ulong[] dim3316KuoInit = { 1 , 3 , 1 , 9 , 1 , 43 , 71 , 87 , 149 , 557 , 857 , 2739 , 6269 , 3297 , 26067 ,0 }; - static ulong[] dim3317KuoInit = { 1 , 3 , 1 , 5 , 5 , 29 , 45 , 159 , 125 , 389 , 627 , 983 , 755 , 15585 , 12555 ,0 }; - static ulong[] dim3318KuoInit = { 1 , 1 , 3 , 7 , 9 , 53 , 79 , 29 , 423 , 423 , 1493 , 61 , 1631 , 5157 , 29845 ,0 }; - static ulong[] dim3319KuoInit = { 1 , 3 , 5 , 9 , 23 , 27 , 57 , 235 , 57 , 833 , 371 , 1797 , 4541 , 12491 , 23127 ,0 }; - static ulong[] dim3320KuoInit = { 1 , 3 , 3 , 1 , 17 , 1 , 79 , 87 , 247 , 987 , 651 , 3167 , 4423 , 831 , 16811 ,0 }; - static ulong[] dim3321KuoInit = { 1 , 3 , 3 , 5 , 15 , 23 , 51 , 167 , 421 , 493 , 1877 , 1079 , 4147 , 13485 , 28619 ,0 }; - static ulong[] dim3322KuoInit = { 1 , 1 , 7 , 13 , 19 , 15 , 69 , 31 , 225 , 597 , 1477 , 2363 , 6969 , 13221 , 2561 ,0 }; - static ulong[] dim3323KuoInit = { 1 , 3 , 1 , 7 , 19 , 61 , 75 , 199 , 103 , 823 , 375 , 1301 , 4349 , 135 , 5701 ,0 }; - static ulong[] dim3324KuoInit = { 1 , 3 , 7 , 11 , 21 , 25 , 85 , 249 , 91 , 885 , 469 , 1809 , 4351 , 14393 , 19607 ,0 }; - static ulong[] dim3325KuoInit = { 1 , 3 , 5 , 1 , 25 , 19 , 71 , 111 , 427 , 523 , 1691 , 4085 , 7587 , 1949 , 10471 ,0 }; - static ulong[] dim3326KuoInit = { 1 , 3 , 1 , 11 , 27 , 59 , 13 , 117 , 155 , 369 , 1767 , 2951 , 6109 , 13867 , 13887 ,0 }; - static ulong[] dim3327KuoInit = { 1 , 3 , 3 , 3 , 31 , 53 , 35 , 101 , 295 , 653 , 337 , 2281 , 7563 , 8847 , 15235 ,0 }; - static ulong[] dim3328KuoInit = { 1 , 1 , 7 , 13 , 3 , 17 , 63 , 251 , 293 , 861 , 1539 , 2409 , 663 , 1637 , 22309 ,0 }; - static ulong[] dim3329KuoInit = { 1 , 3 , 7 , 9 , 13 , 27 , 41 , 81 , 483 , 901 , 1963 , 1855 , 799 , 10933 , 14395 ,0 }; - static ulong[] dim3330KuoInit = { 1 , 1 , 3 , 5 , 19 , 23 , 97 , 179 , 93 , 657 , 1361 , 4019 , 7577 , 355 , 4881 ,0 }; - static ulong[] dim3331KuoInit = { 1 , 3 , 3 , 15 , 23 , 25 , 101 , 141 , 91 , 37 , 1165 , 3509 , 2445 , 7675 , 30803 ,0 }; - static ulong[] dim3332KuoInit = { 1 , 1 , 1 , 5 , 13 , 53 , 87 , 197 , 321 , 297 , 277 , 2159 , 5457 , 6463 , 1797 ,0 }; - static ulong[] dim3333KuoInit = { 1 , 3 , 3 , 7 , 3 , 3 , 117 , 5 , 95 , 527 , 755 , 2865 , 6359 , 4859 , 11395 ,0 }; - static ulong[] dim3334KuoInit = { 1 , 3 , 3 , 13 , 1 , 49 , 43 , 247 , 369 , 351 , 1277 , 1639 , 3133 , 4193 , 26645 ,0 }; - static ulong[] dim3335KuoInit = { 1 , 1 , 1 , 9 , 27 , 21 , 59 , 191 , 365 , 95 , 337 , 3279 , 4455 , 8235 , 12457 ,0 }; - static ulong[] dim3336KuoInit = { 1 , 1 , 7 , 5 , 9 , 1 , 7 , 23 , 117 , 711 , 1027 , 613 , 4729 , 14415 , 15705 ,0 }; - static ulong[] dim3337KuoInit = { 1 , 3 , 1 , 3 , 29 , 13 , 43 , 3 , 117 , 763 , 1787 , 2109 , 4949 , 7579 , 24083 ,0 }; - static ulong[] dim3338KuoInit = { 1 , 1 , 5 , 11 , 7 , 61 , 107 , 113 , 127 , 495 , 1167 , 2871 , 7187 , 13235 , 2037 ,0 }; - static ulong[] dim3339KuoInit = { 1 , 1 , 5 , 5 , 13 , 33 , 23 , 69 , 5 , 137 , 157 , 1107 , 1025 , 1907 , 2279 ,0 }; - static ulong[] dim3340KuoInit = { 1 , 1 , 1 , 9 , 11 , 63 , 27 , 13 , 295 , 951 , 2027 , 3625 , 1447 , 8939 , 3965 ,0 }; - static ulong[] dim3341KuoInit = { 1 , 3 , 3 , 13 , 29 , 31 , 67 , 221 , 413 , 13 , 1643 , 2847 , 4889 , 3733 , 25713 ,0 }; - static ulong[] dim3342KuoInit = { 1 , 3 , 5 , 11 , 11 , 17 , 37 , 37 , 159 , 835 , 1775 , 2059 , 2995 , 6141 , 12277 ,0 }; - static ulong[] dim3343KuoInit = { 1 , 3 , 3 , 7 , 11 , 25 , 107 , 239 , 361 , 835 , 1943 , 1375 , 7077 , 13843 , 5685 ,0 }; - static ulong[] dim3344KuoInit = { 1 , 1 , 3 , 11 , 23 , 27 , 3 , 191 , 339 , 675 , 1181 , 2005 , 245 , 7305 , 5831 ,0 }; - static ulong[] dim3345KuoInit = { 1 , 3 , 5 , 9 , 15 , 17 , 91 , 15 , 255 , 201 , 535 , 3063 , 4351 , 12527 , 15981 ,0 }; - static ulong[] dim3346KuoInit = { 1 , 3 , 5 , 9 , 7 , 47 , 111 , 245 , 223 , 781 , 367 , 559 , 1433 , 9631 , 7207 ,0 }; - static ulong[] dim3347KuoInit = { 1 , 3 , 7 , 5 , 23 , 5 , 111 , 237 , 371 , 541 , 663 , 693 , 6591 , 13089 , 11381 ,0 }; - static ulong[] dim3348KuoInit = { 1 , 1 , 3 , 9 , 25 , 5 , 99 , 17 , 401 , 787 , 971 , 1035 , 1143 , 12041 , 22455 ,0 }; - static ulong[] dim3349KuoInit = { 1 , 1 , 5 , 1 , 3 , 5 , 125 , 193 , 69 , 939 , 37 , 2843 , 3139 , 7967 , 15099 ,0 }; - static ulong[] dim3350KuoInit = { 1 , 1 , 5 , 3 , 11 , 39 , 35 , 103 , 203 , 255 , 727 , 2513 , 1981 , 12855 , 20887 ,0 }; - static ulong[] dim3351KuoInit = { 1 , 3 , 3 , 15 , 27 , 41 , 41 , 57 , 275 , 497 , 727 , 901 , 5653 , 12917 , 20783 ,0 }; - static ulong[] dim3352KuoInit = { 1 , 3 , 1 , 5 , 17 , 13 , 101 , 95 , 465 , 155 , 973 , 1911 , 2719 , 157 , 19475 ,0 }; - static ulong[] dim3353KuoInit = { 1 , 3 , 3 , 5 , 3 , 61 , 31 , 225 , 351 , 931 , 855 , 3871 , 1835 , 11133 , 25203 ,0 }; - static ulong[] dim3354KuoInit = { 1 , 3 , 7 , 7 , 25 , 1 , 91 , 193 , 455 , 873 , 1255 , 1657 , 4143 , 433 , 22789 ,0 }; - static ulong[] dim3355KuoInit = { 1 , 3 , 7 , 9 , 31 , 19 , 35 , 81 , 175 , 885 , 1007 , 3443 , 2063 , 3179 , 28563 ,0 }; - static ulong[] dim3356KuoInit = { 1 , 1 , 3 , 9 , 1 , 25 , 109 , 249 , 341 , 393 , 497 , 1181 , 2943 , 9021 , 9985 ,0 }; - static ulong[] dim3357KuoInit = { 1 , 1 , 7 , 13 , 15 , 49 , 27 , 145 , 351 , 119 , 257 , 151 , 4287 , 1709 , 2585 ,0 }; - static ulong[] dim3358KuoInit = { 1 , 1 , 7 , 7 , 3 , 19 , 105 , 51 , 443 , 693 , 29 , 2657 , 6967 , 4797 , 14565 ,0 }; - static ulong[] dim3359KuoInit = { 1 , 3 , 3 , 1 , 25 , 53 , 65 , 169 , 461 , 275 , 1191 , 731 , 6295 , 15083 , 28445 ,0 }; - static ulong[] dim3360KuoInit = { 1 , 3 , 1 , 1 , 11 , 39 , 21 , 3 , 411 , 45 , 1325 , 3279 , 3153 , 289 , 30973 ,0 }; - static ulong[] dim3361KuoInit = { 1 , 1 , 1 , 11 , 29 , 57 , 107 , 245 , 279 , 677 , 599 , 1145 , 5135 , 6131 , 12667 ,0 }; - static ulong[] dim3362KuoInit = { 1 , 3 , 1 , 15 , 27 , 7 , 99 , 215 , 17 , 171 , 977 , 2065 , 1357 , 8705 , 29641 ,0 }; - static ulong[] dim3363KuoInit = { 1 , 1 , 3 , 9 , 31 , 23 , 53 , 9 , 177 , 645 , 99 , 3175 , 3543 , 13637 , 9923 ,0 }; - static ulong[] dim3364KuoInit = { 1 , 1 , 1 , 13 , 5 , 45 , 69 , 39 , 207 , 651 , 1507 , 2969 , 2743 , 4025 , 9983 ,0 }; - static ulong[] dim3365KuoInit = { 1 , 1 , 5 , 13 , 13 , 57 , 27 , 215 , 51 , 927 , 1973 , 3127 , 3655 , 10653 , 5649 ,0 }; - static ulong[] dim3366KuoInit = { 1 , 3 , 3 , 7 , 21 , 7 , 119 , 163 , 461 , 859 , 253 , 2817 , 8001 , 393 , 20171 ,0 }; - static ulong[] dim3367KuoInit = { 1 , 3 , 3 , 3 , 25 , 7 , 101 , 109 , 57 , 185 , 2005 , 3167 , 3539 , 2465 , 783 ,0 }; - static ulong[] dim3368KuoInit = { 1 , 3 , 1 , 3 , 31 , 43 , 69 , 189 , 471 , 669 , 339 , 1125 , 4273 , 10417 , 20129 ,0 }; - static ulong[] dim3369KuoInit = { 1 , 1 , 3 , 7 , 19 , 37 , 115 , 111 , 439 , 19 , 425 , 995 , 3983 , 15523 , 25679 ,0 }; - static ulong[] dim3370KuoInit = { 1 , 3 , 5 , 9 , 5 , 1 , 37 , 105 , 359 , 423 , 545 , 1099 , 6809 , 8531 , 25155 ,0 }; - static ulong[] dim3371KuoInit = { 1 , 1 , 3 , 3 , 9 , 37 , 37 , 149 , 457 , 1017 , 25 , 3641 , 2673 , 1501 , 28811 ,0 }; - static ulong[] dim3372KuoInit = { 1 , 3 , 5 , 11 , 25 , 31 , 57 , 233 , 125 , 755 , 1807 , 337 , 81 , 14709 , 4061 ,0 }; - static ulong[] dim3373KuoInit = { 1 , 1 , 1 , 7 , 25 , 7 , 37 , 35 , 437 , 889 , 965 , 3997 , 4493 , 1357 , 26383 ,0 }; - static ulong[] dim3374KuoInit = { 1 , 1 , 1 , 3 , 9 , 37 , 105 , 127 , 283 , 141 , 1451 , 2275 , 3261 , 8135 , 429 ,0 }; - static ulong[] dim3375KuoInit = { 1 , 1 , 1 , 5 , 3 , 19 , 9 , 233 , 293 , 827 , 103 , 1963 , 2877 , 7701 , 17431 ,0 }; - static ulong[] dim3376KuoInit = { 1 , 3 , 7 , 11 , 15 , 17 , 87 , 243 , 141 , 721 , 829 , 3569 , 4081 , 6039 , 21523 ,0 }; - static ulong[] dim3377KuoInit = { 1 , 3 , 3 , 11 , 17 , 21 , 31 , 169 , 425 , 755 , 1391 , 3433 , 3275 , 15657 , 9085 ,0 }; - static ulong[] dim3378KuoInit = { 1 , 3 , 1 , 7 , 25 , 23 , 49 , 227 , 103 , 5 , 1995 , 3803 , 1109 , 6015 , 2433 ,0 }; - static ulong[] dim3379KuoInit = { 1 , 1 , 7 , 7 , 19 , 39 , 91 , 219 , 403 , 475 , 1629 , 117 , 2317 , 3991 , 23467 ,0 }; - static ulong[] dim3380KuoInit = { 1 , 1 , 7 , 5 , 19 , 63 , 79 , 9 , 19 , 747 , 1045 , 875 , 5809 , 949 , 10943 ,0 }; - static ulong[] dim3381KuoInit = { 1 , 1 , 3 , 11 , 3 , 29 , 83 , 103 , 481 , 565 , 451 , 1353 , 5417 , 2747 , 141 ,0 }; - static ulong[] dim3382KuoInit = { 1 , 1 , 1 , 11 , 17 , 43 , 75 , 51 , 335 , 257 , 1077 , 517 , 4029 , 13761 , 8653 ,0 }; - static ulong[] dim3383KuoInit = { 1 , 1 , 1 , 1 , 13 , 51 , 41 , 195 , 331 , 155 , 1711 , 2787 , 6163 , 12641 , 20731 ,0 }; - static ulong[] dim3384KuoInit = { 1 , 1 , 1 , 11 , 5 , 37 , 117 , 97 , 133 , 793 , 491 , 2185 , 3671 , 12257 , 6239 ,0 }; - static ulong[] dim3385KuoInit = { 1 , 1 , 1 , 5 , 9 , 33 , 69 , 153 , 29 , 443 , 921 , 3679 , 7385 , 7229 , 16443 ,0 }; - static ulong[] dim3386KuoInit = { 1 , 3 , 3 , 9 , 19 , 19 , 87 , 147 , 113 , 577 , 505 , 343 , 7385 , 3247 , 6411 ,0 }; - static ulong[] dim3387KuoInit = { 1 , 1 , 7 , 9 , 15 , 33 , 83 , 69 , 27 , 519 , 115 , 4059 , 5281 , 7995 , 25537 ,0 }; - static ulong[] dim3388KuoInit = { 1 , 1 , 5 , 15 , 21 , 25 , 37 , 35 , 263 , 531 , 197 , 27 , 7871 , 7383 , 28467 ,0 }; - static ulong[] dim3389KuoInit = { 1 , 3 , 5 , 1 , 1 , 49 , 87 , 173 , 37 , 633 , 65 , 2449 , 149 , 7145 , 6461 ,0 }; - static ulong[] dim3390KuoInit = { 1 , 1 , 3 , 7 , 17 , 35 , 91 , 45 , 257 , 351 , 1569 , 3757 , 5203 , 8071 , 32211 ,0 }; - static ulong[] dim3391KuoInit = { 1 , 1 , 3 , 9 , 9 , 39 , 51 , 33 , 77 , 663 , 287 , 1127 , 4549 , 6321 , 16199 ,0 }; - static ulong[] dim3392KuoInit = { 1 , 1 , 5 , 9 , 3 , 3 , 123 , 35 , 75 , 253 , 1661 , 3191 , 1749 , 14421 , 15767 ,0 }; - static ulong[] dim3393KuoInit = { 1 , 1 , 1 , 15 , 21 , 27 , 69 , 233 , 425 , 89 , 1069 , 603 , 5439 , 5597 , 24183 ,0 }; - static ulong[] dim3394KuoInit = { 1 , 1 , 7 , 15 , 19 , 57 , 127 , 83 , 445 , 619 , 1541 , 2695 , 1657 , 10787 , 27703 ,0 }; - static ulong[] dim3395KuoInit = { 1 , 3 , 1 , 3 , 31 , 31 , 29 , 61 , 245 , 449 , 145 , 3619 , 5267 , 9403 , 9637 ,0 }; - static ulong[] dim3396KuoInit = { 1 , 1 , 5 , 9 , 29 , 61 , 33 , 245 , 341 , 991 , 639 , 3391 , 2971 , 857 , 26191 ,0 }; - static ulong[] dim3397KuoInit = { 1 , 1 , 1 , 5 , 9 , 7 , 57 , 33 , 79 , 489 , 379 , 3907 , 3759 , 4243 , 9811 ,0 }; - static ulong[] dim3398KuoInit = { 1 , 3 , 5 , 15 , 7 , 61 , 7 , 119 , 51 , 927 , 1505 , 2997 , 723 , 8987 , 29007 ,0 }; - static ulong[] dim3399KuoInit = { 1 , 1 , 3 , 1 , 31 , 55 , 63 , 15 , 421 , 423 , 1041 , 3967 , 2471 , 13273 , 18587 ,0 }; - static ulong[] dim3400KuoInit = { 1 , 3 , 3 , 13 , 9 , 49 , 111 , 211 , 87 , 887 , 1867 , 19 , 5329 , 12411 , 18537 ,0 }; - static ulong[] dim3401KuoInit = { 1 , 3 , 1 , 1 , 27 , 35 , 89 , 81 , 119 , 635 , 63 , 2185 , 7001 , 11283 , 11883 ,0 }; - static ulong[] dim3402KuoInit = { 1 , 1 , 3 , 9 , 31 , 61 , 55 , 237 , 327 , 537 , 123 , 3589 , 3019 , 705 , 16701 ,0 }; - static ulong[] dim3403KuoInit = { 1 , 1 , 7 , 1 , 7 , 13 , 103 , 101 , 473 , 7 , 381 , 3643 , 1227 , 11335 , 615 ,0 }; - static ulong[] dim3404KuoInit = { 1 , 3 , 5 , 13 , 1 , 9 , 127 , 65 , 479 , 623 , 469 , 3403 , 2423 , 4269 , 15195 ,0 }; - static ulong[] dim3405KuoInit = { 1 , 1 , 7 , 15 , 3 , 23 , 125 , 195 , 267 , 923 , 961 , 799 , 783 , 893 , 22403 ,0 }; - static ulong[] dim3406KuoInit = { 1 , 3 , 1 , 3 , 21 , 7 , 21 , 151 , 373 , 377 , 1685 , 3731 , 6019 , 1059 , 32457 ,0 }; - static ulong[] dim3407KuoInit = { 1 , 3 , 3 , 11 , 9 , 31 , 55 , 207 , 109 , 945 , 1073 , 3545 , 4191 , 12965 , 20863 ,0 }; - static ulong[] dim3408KuoInit = { 1 , 1 , 1 , 5 , 27 , 45 , 15 , 67 , 101 , 207 , 77 , 3309 , 747 , 13857 , 25737 ,0 }; - static ulong[] dim3409KuoInit = { 1 , 1 , 1 , 5 , 1 , 31 , 15 , 235 , 57 , 449 , 411 , 3739 , 5093 , 12963 , 30649 ,0 }; - static ulong[] dim3410KuoInit = { 1 , 3 , 7 , 5 , 5 , 33 , 87 , 13 , 57 , 727 , 1041 , 3369 , 6047 , 1007 , 4587 ,0 }; - static ulong[] dim3411KuoInit = { 1 , 1 , 3 , 9 , 29 , 43 , 11 , 251 , 99 , 413 , 1943 , 3461 , 993 , 13983 , 8157 ,0 }; - static ulong[] dim3412KuoInit = { 1 , 1 , 5 , 15 , 7 , 27 , 105 , 9 , 69 , 949 , 245 , 2537 , 5941 , 10961 , 17115 ,0 }; - static ulong[] dim3413KuoInit = { 1 , 1 , 7 , 5 , 17 , 41 , 63 , 167 , 45 , 391 , 895 , 2565 , 2681 , 10855 , 6919 ,0 }; - static ulong[] dim3414KuoInit = { 1 , 3 , 7 , 3 , 7 , 53 , 15 , 207 , 467 , 131 , 761 , 189 , 4977 , 4345 , 7539 ,0 }; - static ulong[] dim3415KuoInit = { 1 , 1 , 5 , 5 , 23 , 17 , 127 , 3 , 455 , 787 , 383 , 2381 , 6407 , 3253 , 1787 ,0 }; - static ulong[] dim3416KuoInit = { 1 , 3 , 5 , 15 , 5 , 7 , 37 , 75 , 351 , 141 , 93 , 2631 , 609 , 11455 , 20603 ,0 }; - static ulong[] dim3417KuoInit = { 1 , 3 , 7 , 9 , 5 , 33 , 19 , 15 , 101 , 1005 , 7 , 1341 , 4577 , 11627 , 17061 ,0 }; - static ulong[] dim3418KuoInit = { 1 , 3 , 3 , 9 , 5 , 7 , 87 , 181 , 197 , 423 , 361 , 545 , 2459 , 7419 , 14457 ,0 }; - static ulong[] dim3419KuoInit = { 1 , 1 , 7 , 7 , 25 , 37 , 93 , 85 , 345 , 459 , 465 , 3377 , 795 , 13439 , 4765 ,0 }; - static ulong[] dim3420KuoInit = { 1 , 1 , 7 , 9 , 25 , 55 , 109 , 63 , 381 , 329 , 1787 , 3163 , 279 , 4647 , 8723 ,0 }; - static ulong[] dim3421KuoInit = { 1 , 3 , 3 , 13 , 23 , 33 , 85 , 41 , 151 , 319 , 265 , 259 , 29 , 4217 , 21025 ,0 }; - static ulong[] dim3422KuoInit = { 1 , 1 , 5 , 9 , 31 , 17 , 93 , 27 , 455 , 1015 , 81 , 621 , 6511 , 7617 , 6775 ,0 }; - static ulong[] dim3423KuoInit = { 1 , 1 , 1 , 11 , 25 , 21 , 73 , 161 , 267 , 911 , 25 , 1385 , 4073 , 14423 , 31473 ,0 }; - static ulong[] dim3424KuoInit = { 1 , 3 , 5 , 11 , 13 , 33 , 95 , 113 , 371 , 291 , 1055 , 3779 , 991 , 9699 , 9495 ,0 }; - static ulong[] dim3425KuoInit = { 1 , 1 , 1 , 7 , 31 , 55 , 111 , 215 , 399 , 721 , 1443 , 763 , 3119 , 11075 , 15489 ,0 }; - static ulong[] dim3426KuoInit = { 1 , 1 , 1 , 3 , 17 , 57 , 119 , 171 , 299 , 299 , 1919 , 3103 , 5691 , 7927 , 18875 ,0 }; - static ulong[] dim3427KuoInit = { 1 , 1 , 5 , 7 , 13 , 41 , 35 , 209 , 383 , 381 , 901 , 3341 , 3421 , 11501 , 2187 ,0 }; - static ulong[] dim3428KuoInit = { 1 , 3 , 1 , 7 , 1 , 3 , 83 , 105 , 495 , 297 , 413 , 2941 , 4309 , 9829 , 32115 ,0 }; - static ulong[] dim3429KuoInit = { 1 , 3 , 5 , 3 , 3 , 7 , 81 , 9 , 55 , 19 , 225 , 2915 , 6255 , 10967 , 8767 ,0 }; - static ulong[] dim3430KuoInit = { 1 , 3 , 1 , 1 , 23 , 59 , 21 , 127 , 7 , 703 , 1189 , 2375 , 6273 , 1655 , 10115 ,0 }; - static ulong[] dim3431KuoInit = { 1 , 1 , 1 , 15 , 19 , 35 , 39 , 185 , 143 , 163 , 1491 , 201 , 2473 , 661 , 12827 ,0 }; - static ulong[] dim3432KuoInit = { 1 , 1 , 1 , 5 , 29 , 49 , 5 , 27 , 131 , 1005 , 991 , 1159 , 5437 , 5039 , 4037 ,0 }; - static ulong[] dim3433KuoInit = { 1 , 3 , 7 , 3 , 11 , 41 , 123 , 43 , 11 , 443 , 109 , 3995 , 5377 , 2907 , 30035 ,0 }; - static ulong[] dim3434KuoInit = { 1 , 3 , 1 , 1 , 31 , 59 , 53 , 219 , 185 , 31 , 641 , 1695 , 5817 , 9001 , 28827 ,0 }; - static ulong[] dim3435KuoInit = { 1 , 1 , 1 , 3 , 13 , 37 , 37 , 119 , 123 , 57 , 1241 , 551 , 5825 , 11551 , 23521 ,0 }; - static ulong[] dim3436KuoInit = { 1 , 1 , 3 , 15 , 13 , 37 , 33 , 61 , 209 , 375 , 335 , 1223 , 4023 , 12743 , 8375 ,0 }; - static ulong[] dim3437KuoInit = { 1 , 3 , 3 , 3 , 31 , 7 , 103 , 43 , 451 , 517 , 1025 , 2853 , 5943 , 13655 , 21409 ,0 }; - static ulong[] dim3438KuoInit = { 1 , 1 , 1 , 13 , 11 , 37 , 11 , 167 , 271 , 763 , 85 , 3727 , 641 , 2841 , 23803 ,0 }; - static ulong[] dim3439KuoInit = { 1 , 1 , 7 , 5 , 3 , 19 , 117 , 225 , 275 , 327 , 1263 , 1597 , 1439 , 8531 , 18063 ,0 }; - static ulong[] dim3440KuoInit = { 1 , 3 , 5 , 3 , 9 , 45 , 57 , 169 , 453 , 949 , 585 , 1365 , 4263 , 3461 , 7191 ,0 }; - static ulong[] dim3441KuoInit = { 1 , 3 , 7 , 9 , 25 , 51 , 97 , 255 , 457 , 293 , 1027 , 1291 , 6685 , 2617 , 3055 ,0 }; - static ulong[] dim3442KuoInit = { 1 , 3 , 7 , 5 , 27 , 33 , 47 , 65 , 43 , 545 , 123 , 1093 , 5563 , 3013 , 18451 ,0 }; - static ulong[] dim3443KuoInit = { 1 , 1 , 3 , 11 , 9 , 25 , 71 , 241 , 495 , 561 , 1565 , 703 , 809 , 10961 , 3001 ,0 }; - static ulong[] dim3444KuoInit = { 1 , 3 , 5 , 1 , 1 , 47 , 97 , 233 , 259 , 39 , 543 , 303 , 2705 , 3683 , 32123 ,0 }; - static ulong[] dim3445KuoInit = { 1 , 1 , 5 , 7 , 1 , 35 , 91 , 43 , 417 , 299 , 1635 , 2163 , 7959 , 9015 , 5661 ,0 }; - static ulong[] dim3446KuoInit = { 1 , 1 , 3 , 11 , 1 , 63 , 49 , 209 , 125 , 241 , 987 , 3173 , 631 , 9767 , 8467 ,0 }; - static ulong[] dim3447KuoInit = { 1 , 1 , 1 , 5 , 25 , 49 , 43 , 117 , 65 , 81 , 313 , 1917 , 6087 , 1503 , 3383 ,0 }; - static ulong[] dim3448KuoInit = { 1 , 3 , 5 , 1 , 23 , 53 , 43 , 29 , 91 , 727 , 1157 , 2985 , 3851 , 15897 , 17577 ,0 }; - static ulong[] dim3449KuoInit = { 1 , 1 , 3 , 15 , 15 , 27 , 35 , 129 , 161 , 679 , 1001 , 2681 , 5287 , 10367 , 21017 ,0 }; - static ulong[] dim3450KuoInit = { 1 , 3 , 3 , 1 , 23 , 51 , 127 , 119 , 467 , 161 , 1229 , 2969 , 6321 , 1141 , 7827 ,0 }; - static ulong[] dim3451KuoInit = { 1 , 3 , 5 , 15 , 19 , 45 , 33 , 173 , 205 , 815 , 783 , 1323 , 69 , 5191 , 23795 ,0 }; - static ulong[] dim3452KuoInit = { 1 , 3 , 5 , 9 , 19 , 1 , 111 , 253 , 463 , 247 , 1877 , 1831 , 8037 , 12769 , 8111 ,0 }; - static ulong[] dim3453KuoInit = { 1 , 3 , 1 , 1 , 21 , 7 , 19 , 241 , 297 , 953 , 1759 , 2187 , 1587 , 14857 , 13245 ,0 }; - static ulong[] dim3454KuoInit = { 1 , 1 , 1 , 15 , 27 , 21 , 111 , 37 , 333 , 485 , 127 , 1781 , 545 , 251 , 2757 ,0 }; - static ulong[] dim3455KuoInit = { 1 , 3 , 1 , 1 , 3 , 7 , 21 , 69 , 171 , 225 , 1505 , 2725 , 923 , 9451 , 29443 ,0 }; - static ulong[] dim3456KuoInit = { 1 , 3 , 7 , 7 , 13 , 57 , 97 , 175 , 429 , 529 , 677 , 1501 , 4717 , 12705 , 31473 ,0 }; - static ulong[] dim3457KuoInit = { 1 , 3 , 7 , 11 , 29 , 7 , 57 , 115 , 55 , 167 , 903 , 3855 , 8051 , 15567 , 31733 ,0 }; - static ulong[] dim3458KuoInit = { 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,0 }; - static ulong[] dim3459KuoInit = { 1 , 1 , 1 , 13 , 11 , 17 , 73 , 193 , 151 , 927 , 1375 , 4037 , 6855 , 10481 , 8973 ,0 }; - static ulong[] dim3460KuoInit = { 1 , 3 , 7 , 1 , 25 , 7 , 115 , 39 , 469 , 903 , 655 , 299 , 6007 , 6629 , 11871 ,0 }; - static ulong[] dim3461KuoInit = { 1 , 3 , 7 , 5 , 15 , 49 , 79 , 115 , 55 , 841 , 1091 , 1641 , 5693 , 3607 , 13699 ,0 }; - static ulong[] dim3462KuoInit = { 1 , 1 , 1 , 15 , 5 , 33 , 99 , 239 , 157 , 133 , 2023 , 683 , 3419 , 10993 , 32187 ,0 }; - static ulong[] dim3463KuoInit = { 1 , 1 , 7 , 1 , 3 , 13 , 95 , 233 , 341 , 243 , 2043 , 653 , 4673 , 1441 , 19087 ,0 }; - static ulong[] dim3464KuoInit = { 1 , 3 , 3 , 3 , 29 , 51 , 117 , 199 , 49 , 467 , 461 , 2465 , 7541 , 6815 , 28711 ,0 }; - static ulong[] dim3465KuoInit = { 1 , 3 , 1 , 1 , 25 , 47 , 31 , 79 , 9 , 39 , 733 , 3567 , 5965 , 6627 , 1109 ,0 }; - static ulong[] dim3466KuoInit = { 1 , 3 , 1 , 13 , 9 , 53 , 27 , 101 , 341 , 369 , 1659 , 1645 , 4465 , 10175 , 4565 ,0 }; - static ulong[] dim3467KuoInit = { 1 , 3 , 5 , 7 , 13 , 61 , 67 , 125 , 427 , 105 , 133 , 2303 , 5595 , 4527 , 23151 ,0 }; - static ulong[] dim3468KuoInit = { 1 , 1 , 5 , 7 , 19 , 29 , 87 , 167 , 141 , 657 , 947 , 367 , 2617 , 9287 , 629 ,0 }; - static ulong[] dim3469KuoInit = { 1 , 3 , 7 , 5 , 21 , 25 , 35 , 21 , 391 , 1019 , 991 , 3343 , 1221 , 1591 , 18095 ,0 }; - static ulong[] dim3470KuoInit = { 1 , 3 , 7 , 9 , 31 , 49 , 99 , 185 , 405 , 261 , 935 , 3447 , 4081 , 5537 , 26329 ,0 }; - static ulong[] dim3471KuoInit = { 1 , 1 , 3 , 7 , 25 , 51 , 107 , 83 , 449 , 733 , 597 , 1023 , 7457 , 14343 , 7119 ,0 }; - static ulong[] dim3472KuoInit = { 1 , 1 , 1 , 5 , 23 , 21 , 35 , 83 , 185 , 531 , 1283 , 2235 , 7775 , 15895 , 32651 ,0 }; - static ulong[] dim3473KuoInit = { 1 , 1 , 5 , 15 , 27 , 13 , 23 , 227 , 491 , 701 , 341 , 2109 , 8045 , 1529 , 10589 ,0 }; - static ulong[] dim3474KuoInit = { 1 , 1 , 5 , 5 , 21 , 51 , 31 , 101 , 31 , 861 , 401 , 1519 , 5349 , 2623 , 22667 ,0 }; - static ulong[] dim3475KuoInit = { 1 , 3 , 5 , 5 , 1 , 41 , 43 , 25 , 491 , 329 , 537 , 1357 , 5567 , 3951 , 15293 ,0 }; - static ulong[] dim3476KuoInit = { 1 , 3 , 7 , 3 , 15 , 39 , 113 , 105 , 51 , 483 , 1417 , 2971 , 3 , 9673 , 4331 ,0 }; - static ulong[] dim3477KuoInit = { 1 , 3 , 5 , 13 , 17 , 3 , 19 , 55 , 443 , 967 , 327 , 3463 , 5427 , 195 , 7495 ,0 }; - static ulong[] dim3478KuoInit = { 1 , 1 , 3 , 3 , 15 , 15 , 11 , 157 , 311 , 967 , 89 , 3691 , 7307 , 12309 , 1915 ,0 }; - static ulong[] dim3479KuoInit = { 1 , 3 , 5 , 7 , 25 , 7 , 125 , 163 , 231 , 177 , 1497 , 3119 , 3281 , 15033 , 9457 ,0 }; - static ulong[] dim3480KuoInit = { 1 , 3 , 3 , 9 , 25 , 51 , 51 , 243 , 427 , 831 , 709 , 3741 , 445 , 14275 , 32323 ,0 }; - static ulong[] dim3481KuoInit = { 1 , 3 , 3 , 13 , 1 , 41 , 123 , 237 , 401 , 19 , 1161 , 985 , 5119 , 14879 , 5785 ,0 }; - static ulong[] dim3482KuoInit = { 1 , 3 , 1 , 3 , 3 , 11 , 121 , 209 , 507 , 271 , 1045 , 2547 , 1019 , 7107 , 31823 ,0 }; - static ulong[] dim3483KuoInit = { 1 , 1 , 5 , 3 , 21 , 3 , 33 , 73 , 79 , 607 , 47 , 3045 , 2471 , 2023 , 8115 ,0 }; - static ulong[] dim3484KuoInit = { 1 , 3 , 7 , 13 , 19 , 49 , 111 , 185 , 209 , 683 , 1459 , 3827 , 6591 , 13139 , 2057 ,0 }; - static ulong[] dim3485KuoInit = { 1 , 3 , 7 , 9 , 17 , 63 , 77 , 217 , 161 , 287 , 335 , 3947 , 5255 , 12297 , 16829 ,0 }; - static ulong[] dim3486KuoInit = { 1 , 3 , 1 , 11 , 17 , 17 , 31 , 231 , 483 , 437 , 431 , 957 , 6499 , 12947 , 29751 ,0 }; - static ulong[] dim3487KuoInit = { 1 , 3 , 7 , 15 , 5 , 57 , 119 , 43 , 385 , 743 , 249 , 3479 , 7751 , 6321 , 31747 ,0 }; - static ulong[] dim3488KuoInit = { 1 , 1 , 5 , 3 , 5 , 1 , 113 , 87 , 439 , 507 , 1517 , 2081 , 5947 , 10967 , 10219 ,0 }; - static ulong[] dim3489KuoInit = { 1 , 3 , 1 , 13 , 23 , 29 , 39 , 33 , 129 , 493 , 1119 , 2177 , 4135 , 5051 , 20241 ,0 }; - static ulong[] dim3490KuoInit = { 1 , 3 , 7 , 13 , 19 , 13 , 71 , 163 , 107 , 285 , 1999 , 3371 , 3555 , 16265 , 2825 ,0 }; - static ulong[] dim3491KuoInit = { 1 , 3 , 7 , 11 , 5 , 19 , 67 , 201 , 203 , 619 , 927 , 1769 , 5655 , 4539 , 1719 ,0 }; - static ulong[] dim3492KuoInit = { 1 , 3 , 5 , 7 , 15 , 43 , 107 , 91 , 315 , 281 , 525 , 3243 , 7751 , 8991 , 29195 ,0 }; - static ulong[] dim3493KuoInit = { 1 , 1 , 7 , 7 , 21 , 43 , 35 , 81 , 199 , 51 , 935 , 357 , 1723 , 8183 , 6209 ,0 }; - static ulong[] dim3494KuoInit = { 1 , 3 , 5 , 5 , 9 , 31 , 75 , 71 , 375 , 181 , 1503 , 3479 , 2255 , 1371 , 16127 ,0 }; - static ulong[] dim3495KuoInit = { 1 , 1 , 7 , 11 , 29 , 61 , 57 , 145 , 149 , 673 , 1953 , 2111 , 3525 , 1007 , 15927 ,0 }; - static ulong[] dim3496KuoInit = { 1 , 1 , 7 , 15 , 25 , 25 , 103 , 175 , 273 , 193 , 1215 , 3059 , 7805 , 1455 , 1627 ,0 }; - static ulong[] dim3497KuoInit = { 1 , 3 , 1 , 1 , 23 , 45 , 61 , 227 , 487 , 89 , 739 , 1867 , 3643 , 9879 , 17307 ,0 }; - static ulong[] dim3498KuoInit = { 1 , 1 , 5 , 1 , 23 , 5 , 117 , 25 , 325 , 725 , 1999 , 3453 , 2353 , 5467 , 2065 ,0 }; - static ulong[] dim3499KuoInit = { 1 , 1 , 5 , 5 , 25 , 3 , 95 , 243 , 175 , 291 , 821 , 3531 , 4873 , 9975 , 30437 ,0 }; - static ulong[] dim3500KuoInit = { 1 , 3 , 3 , 11 , 5 , 41 , 121 , 23 , 15 , 195 , 1141 , 171 , 2245 , 8043 , 2201 ,0 }; - static ulong[] dim3501KuoInit = { 1 , 3 , 7 , 1 , 29 , 1 , 41 , 233 , 217 , 501 , 913 , 3589 , 1153 , 4601 , 23147 ,0 }; - static ulong[] dim3502KuoInit = { 1 , 1 , 5 , 15 , 1 , 41 , 71 , 255 , 283 , 125 , 845 , 1261 , 7519 , 15623 , 13301 ,0 }; - static ulong[] dim3503KuoInit = { 1 , 3 , 3 , 15 , 11 , 3 , 73 , 161 , 203 , 775 , 905 , 411 , 4139 , 8289 , 8581 ,0 }; - static ulong[] dim3504KuoInit = { 1 , 1 , 7 , 13 , 7 , 57 , 17 , 115 , 273 , 949 , 913 , 3267 , 6949 , 6785 , 30449 ,0 }; - static ulong[] dim3505KuoInit = { 1 , 1 , 7 , 5 , 3 , 49 , 55 , 191 , 505 , 807 , 287 , 3595 , 2261 , 13751 , 15339 ,0 }; - static ulong[] dim3506KuoInit = { 1 , 1 , 5 , 11 , 23 , 13 , 83 , 145 , 387 , 37 , 341 , 111 , 3309 , 4481 , 21679 ,0 }; - static ulong[] dim3507KuoInit = { 1 , 1 , 7 , 15 , 3 , 51 , 13 , 247 , 419 , 555 , 431 , 187 , 2753 , 9071 , 25189 ,0 }; - static ulong[] dim3508KuoInit = { 1 , 3 , 7 , 3 , 29 , 33 , 119 , 63 , 363 , 197 , 1901 , 2231 , 1453 , 3901 , 13713 ,0 }; - static ulong[] dim3509KuoInit = { 1 , 1 , 5 , 7 , 9 , 15 , 91 , 107 , 397 , 739 , 1419 , 481 , 5713 , 14089 , 11699 ,0 }; - static ulong[] dim3510KuoInit = { 1 , 3 , 3 , 7 , 9 , 37 , 47 , 183 , 45 , 135 , 903 , 2769 , 5929 , 8175 , 8661 ,0 }; - static ulong[] dim3511KuoInit = { 1 , 1 , 3 , 9 , 7 , 63 , 117 , 81 , 385 , 459 , 1455 , 4089 , 395 , 7569 , 18089 ,0 }; - static ulong[] dim3512KuoInit = { 1 , 1 , 1 , 3 , 15 , 29 , 71 , 47 , 423 , 177 , 1481 , 1087 , 3703 , 5857 , 9631 ,0 }; - static ulong[] dim3513KuoInit = { 1 , 3 , 1 , 7 , 23 , 45 , 127 , 91 , 457 , 81 , 681 , 257 , 361 , 11739 , 1503 ,0 }; - static ulong[] dim3514KuoInit = { 1 , 3 , 3 , 9 , 29 , 29 , 107 , 125 , 55 , 759 , 1287 , 1937 , 353 , 1275 , 14349 ,0 }; - static ulong[] dim3515KuoInit = { 1 , 3 , 5 , 11 , 15 , 53 , 35 , 1 , 419 , 255 , 1891 , 7 , 3005 , 1493 , 165 ,0 }; - static ulong[] dim3516KuoInit = { 1 , 3 , 5 , 1 , 5 , 19 , 45 , 109 , 479 , 309 , 277 , 2749 , 4859 , 4301 , 17799 ,0 }; - static ulong[] dim3517KuoInit = { 1 , 3 , 7 , 15 , 21 , 57 , 39 , 19 , 433 , 77 , 1999 , 3467 , 2097 , 6853 , 1763 ,0 }; - static ulong[] dim3518KuoInit = { 1 , 1 , 5 , 5 , 7 , 39 , 109 , 53 , 1 , 543 , 623 , 573 , 4039 , 1367 , 23177 ,0 }; - static ulong[] dim3519KuoInit = { 1 , 3 , 1 , 11 , 1 , 31 , 3 , 203 , 409 , 409 , 1471 , 1245 , 3881 , 14467 , 22731 ,0 }; - static ulong[] dim3520KuoInit = { 1 , 3 , 1 , 11 , 19 , 41 , 39 , 95 , 187 , 823 , 973 , 3055 , 3803 , 4229 , 29363 ,0 }; - static ulong[] dim3521KuoInit = { 1 , 1 , 5 , 15 , 29 , 41 , 69 , 121 , 385 , 717 , 1601 , 3061 , 6523 , 13423 , 12559 ,0 }; - static ulong[] dim3522KuoInit = { 1 , 3 , 7 , 1 , 5 , 45 , 85 , 153 , 337 , 587 , 595 , 1183 , 3799 , 12775 , 19537 ,0 }; - static ulong[] dim3523KuoInit = { 1 , 3 , 7 , 15 , 11 , 45 , 97 , 37 , 167 , 227 , 1003 , 2991 , 2291 , 15865 , 6645 ,0 }; - static ulong[] dim3524KuoInit = { 1 , 3 , 3 , 7 , 31 , 41 , 123 , 225 , 275 , 733 , 1611 , 1599 , 7345 , 297 , 22551 ,0 }; - static ulong[] dim3525KuoInit = { 1 , 1 , 5 , 3 , 7 , 45 , 45 , 155 , 41 , 581 , 635 , 4065 , 3993 , 7233 , 27097 ,0 }; - static ulong[] dim3526KuoInit = { 1 , 1 , 7 , 11 , 9 , 39 , 17 , 19 , 335 , 819 , 1845 , 1199 , 591 , 7743 , 26797 ,0 }; - static ulong[] dim3527KuoInit = { 1 , 3 , 7 , 9 , 29 , 33 , 35 , 19 , 287 , 935 , 1463 , 3639 , 5537 , 2751 , 20073 ,0 }; - static ulong[] dim3528KuoInit = { 1 , 3 , 5 , 5 , 3 , 45 , 59 , 117 , 431 , 419 , 1325 , 983 , 6065 , 3501 , 15765 ,0 }; - static ulong[] dim3529KuoInit = { 1 , 1 , 1 , 9 , 27 , 7 , 123 , 205 , 155 , 59 , 1139 , 1147 , 4845 , 15131 , 10155 ,0 }; - static ulong[] dim3530KuoInit = { 1 , 3 , 7 , 5 , 23 , 37 , 97 , 33 , 337 , 837 , 1379 , 2459 , 469 , 10615 , 16475 ,0 }; - static ulong[] dim3531KuoInit = { 1 , 3 , 1 , 7 , 1 , 23 , 27 , 63 , 503 , 635 , 935 , 1767 , 6887 , 6675 , 10973 ,0 }; - static ulong[] dim3532KuoInit = { 1 , 3 , 1 , 9 , 13 , 29 , 15 , 109 , 185 , 33 , 1039 , 959 , 1745 , 10587 , 9269 ,0 }; - static ulong[] dim3533KuoInit = { 1 , 3 , 3 , 1 , 5 , 29 , 89 , 63 , 341 , 773 , 1851 , 775 , 1717 , 6041 , 11901 ,0 }; - static ulong[] dim3534KuoInit = { 1 , 1 , 7 , 9 , 23 , 47 , 21 , 111 , 289 , 997 , 1559 , 501 , 5913 , 4737 , 4623 ,0 }; - static ulong[] dim3535KuoInit = { 1 , 1 , 1 , 15 , 3 , 3 , 87 , 197 , 391 , 121 , 627 , 3705 , 4093 , 3933 , 13787 ,0 }; - static ulong[] dim3536KuoInit = { 1 , 3 , 3 , 15 , 31 , 9 , 117 , 47 , 373 , 697 , 131 , 3933 , 3135 , 9155 , 3937 ,0 }; - static ulong[] dim3537KuoInit = { 1 , 1 , 7 , 3 , 11 , 39 , 5 , 27 , 253 , 301 , 1151 , 3771 , 1581 , 9811 , 17617 ,0 }; - static ulong[] dim3538KuoInit = { 1 , 3 , 7 , 15 , 25 , 59 , 97 , 229 , 291 , 349 , 1153 , 1859 , 3357 , 7919 , 2733 ,0 }; - static ulong[] dim3539KuoInit = { 1 , 1 , 5 , 13 , 5 , 7 , 37 , 177 , 177 , 969 , 29 , 4017 , 6791 , 2823 , 10607 ,0 }; - static ulong[] dim3540KuoInit = { 1 , 1 , 7 , 13 , 27 , 17 , 25 , 137 , 325 , 949 , 1519 , 3711 , 4399 , 9501 , 2989 ,0 }; - static ulong[] dim3541KuoInit = { 1 , 1 , 5 , 5 , 29 , 27 , 75 , 195 , 417 , 945 , 1851 , 2887 , 2379 , 15229 , 4805 ,0 }; - static ulong[] dim3542KuoInit = { 1 , 1 , 3 , 11 , 31 , 45 , 105 , 87 , 241 , 153 , 1941 , 3459 , 4809 , 9823 , 19419 ,0 }; - static ulong[] dim3543KuoInit = { 1 , 1 , 1 , 1 , 1 , 59 , 75 , 51 , 309 , 671 , 1039 , 2999 , 1025 , 15823 , 4835 ,0 }; - static ulong[] dim3544KuoInit = { 1 , 3 , 7 , 13 , 19 , 37 , 41 , 85 , 11 , 713 , 1047 , 989 , 2941 , 6423 , 7983 ,0 }; - static ulong[] dim3545KuoInit = { 1 , 3 , 5 , 13 , 1 , 55 , 103 , 207 , 275 , 431 , 563 , 101 , 691 , 1997 , 17227 ,0 }; - static ulong[] dim3546KuoInit = { 1 , 3 , 1 , 3 , 19 , 15 , 67 , 197 , 125 , 377 , 367 , 601 , 4983 , 1699 , 29315 ,0 }; - static ulong[] dim3547KuoInit = { 1 , 1 , 5 , 3 , 23 , 19 , 19 , 133 , 83 , 625 , 757 , 1349 , 5821 , 2483 , 26653 ,0 }; - static ulong[] dim3548KuoInit = { 1 , 1 , 3 , 3 , 19 , 17 , 19 , 83 , 235 , 657 , 733 , 1773 , 7011 , 3893 , 8495 ,0 }; - static ulong[] dim3549KuoInit = { 1 , 1 , 3 , 15 , 19 , 33 , 37 , 69 , 385 , 835 , 1025 , 1585 , 6685 , 10627 , 19203 ,0 }; - static ulong[] dim3550KuoInit = { 1 , 1 , 5 , 11 , 9 , 31 , 65 , 177 , 153 , 781 , 1183 , 1215 , 6271 , 13099 , 12449 ,0 }; - static ulong[] dim3551KuoInit = { 1 , 1 , 7 , 9 , 13 , 49 , 41 , 57 , 443 , 633 , 1953 , 2423 , 789 , 5591 , 20891 ,0 }; - static ulong[] dim3552KuoInit = { 1 , 1 , 1 , 15 , 17 , 21 , 69 , 177 , 57 , 797 , 13 , 3987 , 6597 , 9935 , 26559 ,0 }; - static ulong[] dim3553KuoInit = { 1 , 3 , 3 , 1 , 21 , 27 , 17 , 207 , 139 , 43 , 1935 , 3285 , 4251 , 4411 , 24469 ,0 }; - static ulong[] dim3554KuoInit = { 1 , 3 , 3 , 11 , 11 , 47 , 63 , 243 , 19 , 801 , 971 , 1925 , 5981 , 13055 , 12185 ,0 }; - static ulong[] dim3555KuoInit = { 1 , 3 , 5 , 5 , 9 , 13 , 49 , 251 , 315 , 889 , 1613 , 1007 , 7849 , 3121 , 4279 ,0 }; - static ulong[] dim3556KuoInit = { 1 , 3 , 1 , 15 , 7 , 37 , 95 , 253 , 65 , 177 , 1551 , 2307 , 2325 , 9975 , 18277 ,0 }; - static ulong[] dim3557KuoInit = { 1 , 3 , 1 , 15 , 7 , 53 , 45 , 5 , 447 , 1005 , 279 , 2141 , 4271 , 4707 , 11225 ,0 }; - static ulong[] dim3558KuoInit = { 1 , 1 , 3 , 13 , 31 , 11 , 15 , 133 , 313 , 249 , 1971 , 2905 , 819 , 11603 , 25679 ,0 }; - static ulong[] dim3559KuoInit = { 1 , 3 , 3 , 15 , 21 , 49 , 107 , 229 , 101 , 449 , 245 , 1401 , 391 , 3749 , 14555 ,0 }; - static ulong[] dim3560KuoInit = { 1 , 1 , 1 , 15 , 7 , 39 , 69 , 223 , 37 , 771 , 1469 , 2085 , 1075 , 14485 , 10019 ,0 }; - static ulong[] dim3561KuoInit = { 1 , 3 , 1 , 13 , 3 , 27 , 37 , 59 , 69 , 675 , 807 , 2711 , 3867 , 9737 , 21913 ,0 }; - static ulong[] dim3562KuoInit = { 1 , 1 , 3 , 9 , 25 , 45 , 109 , 113 , 267 , 867 , 771 , 1647 , 2063 , 14063 , 27737 ,0 }; - static ulong[] dim3563KuoInit = { 1 , 1 , 7 , 15 , 23 , 51 , 71 , 33 , 103 , 71 , 1177 , 2353 , 4741 , 6907 , 11121 ,0 }; - static ulong[] dim3564KuoInit = { 1 , 3 , 3 , 7 , 21 , 31 , 77 , 255 , 341 , 249 , 1263 , 505 , 1845 , 12867 , 11393 ,0 }; - static ulong[] dim3565KuoInit = { 1 , 3 , 1 , 1 , 3 , 1 , 5 , 215 , 155 , 107 , 1283 , 3501 , 8079 , 13921 , 22415 ,0 }; - static ulong[] dim3566KuoInit = { 1 , 1 , 7 , 9 , 31 , 21 , 21 , 29 , 341 , 13 , 155 , 2161 , 517 , 13135 , 15893 ,0 }; - static ulong[] dim3567KuoInit = { 1 , 1 , 7 , 5 , 21 , 33 , 23 , 131 , 367 , 939 , 1139 , 865 , 6015 , 6945 , 2301 ,0 }; - static ulong[] dim3568KuoInit = { 1 , 3 , 7 , 3 , 1 , 25 , 109 , 183 , 267 , 757 , 371 , 1459 , 3671 , 2925 , 10345 ,0 }; - static ulong[] dim3569KuoInit = { 1 , 1 , 5 , 15 , 29 , 57 , 95 , 169 , 301 , 645 , 5 , 225 , 5711 , 305 , 16515 ,0 }; - static ulong[] dim3570KuoInit = { 1 , 3 , 7 , 9 , 27 , 47 , 95 , 121 , 203 , 341 , 657 , 2467 , 7619 , 9587 , 7981 ,0 }; - static ulong[] dim3571KuoInit = { 1 , 3 , 1 , 5 , 27 , 11 , 103 , 67 , 19 , 289 , 187 , 3857 , 8117 , 12931 , 11279 ,0 }; - static ulong[] dim3572KuoInit = { 1 , 1 , 5 , 1 , 31 , 9 , 57 , 67 , 507 , 405 , 181 , 2301 , 715 , 12165 , 18415 ,0 }; - static ulong[] dim3573KuoInit = { 1 , 1 , 7 , 1 , 11 , 3 , 35 , 215 , 177 , 679 , 735 , 1569 , 6231 , 5141 , 28291 ,0 }; - static ulong[] dim3574KuoInit = { 1 , 3 , 1 , 9 , 7 , 7 , 101 , 247 , 103 , 373 , 1485 , 2515 , 3981 , 12029 , 5845 ,0 }; - static ulong[] dim3575KuoInit = { 1 , 1 , 1 , 9 , 29 , 27 , 117 , 111 , 107 , 737 , 629 , 1331 , 7495 , 9813 , 24925 ,0 }; - static ulong[] dim3576KuoInit = { 1 , 1 , 1 , 13 , 17 , 11 , 95 , 11 , 1 , 525 , 1677 , 2673 , 2353 , 7211 , 1075 ,0 }; - static ulong[] dim3577KuoInit = { 1 , 3 , 3 , 7 , 9 , 29 , 9 , 125 , 249 , 815 , 105 , 1649 , 2789 , 6041 , 15287 ,0 }; - static ulong[] dim3578KuoInit = { 1 , 3 , 3 , 3 , 25 , 53 , 87 , 99 , 427 , 255 , 285 , 2339 , 5003 , 10395 , 20969 ,0 }; - static ulong[] dim3579KuoInit = { 1 , 3 , 1 , 5 , 25 , 33 , 97 , 149 , 207 , 925 , 645 , 1867 , 4591 , 10823 , 16603 ,0 }; - static ulong[] dim3580KuoInit = { 1 , 3 , 3 , 13 , 1 , 33 , 71 , 49 , 417 , 535 , 923 , 525 , 811 , 7443 , 12971 ,0 }; - static ulong[] dim3581KuoInit = { 1 , 3 , 5 , 3 , 5 , 9 , 39 , 121 , 87 , 883 , 1957 , 1375 , 4109 , 12691 , 15557 ,0 }; - static ulong[] dim3582KuoInit = { 1 , 1 , 7 , 9 , 23 , 11 , 59 , 41 , 117 , 243 , 1953 , 3967 , 7303 , 10767 , 1345 ,0 }; - static ulong[] dim3583KuoInit = { 1 , 3 , 1 , 7 , 29 , 59 , 19 , 177 , 405 , 197 , 59 , 855 , 5009 , 11887 , 6361 ,0 }; - static ulong[] dim3584KuoInit = { 1 , 3 , 7 , 7 , 19 , 59 , 71 , 199 , 207 , 757 , 1147 , 1857 , 3787 , 16081 , 29557 ,0 }; - static ulong[] dim3585KuoInit = { 1 , 1 , 5 , 9 , 25 , 13 , 37 , 27 , 511 , 983 , 1087 , 371 , 4953 , 8987 , 3155 ,0 }; - static ulong[] dim3586KuoInit = { 1 , 3 , 7 , 15 , 21 , 43 , 75 , 227 , 441 , 523 , 551 , 3517 , 77 , 5869 , 24607 ,0 }; - static ulong[] dim3587KuoInit = { 1 , 1 , 5 , 15 , 1 , 33 , 25 , 217 , 277 , 73 , 105 , 1697 , 1545 , 10205 , 4275 ,0 }; - static ulong[] dim3588KuoInit = { 1 , 1 , 5 , 7 , 3 , 53 , 99 , 19 , 121 , 427 , 585 , 2471 , 103 , 3771 , 23525 ,0 }; - static ulong[] dim3589KuoInit = { 1 , 3 , 5 , 3 , 15 , 17 , 35 , 205 , 9 , 941 , 1281 , 1339 , 7421 , 3341 , 4393 ,0 }; - static ulong[] dim3590KuoInit = { 1 , 1 , 1 , 13 , 27 , 13 , 35 , 99 , 87 , 157 , 951 , 2739 , 1993 , 6107 , 29023 ,0 }; - static ulong[] dim3591KuoInit = { 1 , 3 , 5 , 15 , 15 , 5 , 83 , 5 , 283 , 393 , 1273 , 2251 , 4181 , 3851 , 6845 ,0 }; - static ulong[] dim3592KuoInit = { 1 , 1 , 5 , 3 , 1 , 9 , 63 , 97 , 83 , 93 , 293 , 2087 , 2259 , 10313 , 1037 ,0 }; - static ulong[] dim3593KuoInit = { 1 , 1 , 1 , 5 , 11 , 19 , 39 , 19 , 327 , 329 , 189 , 3851 , 4839 , 1669 , 25805 ,0 }; - static ulong[] dim3594KuoInit = { 1 , 3 , 3 , 7 , 21 , 1 , 41 , 233 , 497 , 265 , 1041 , 4003 , 8029 , 15 , 14437 ,0 }; - static ulong[] dim3595KuoInit = { 1 , 3 , 7 , 5 , 7 , 15 , 123 , 215 , 403 , 931 , 277 , 3501 , 3667 , 13313 , 23977 ,0 }; - static ulong[] dim3596KuoInit = { 1 , 1 , 3 , 9 , 5 , 23 , 99 , 161 , 25 , 403 , 1695 , 2493 , 199 , 15745 , 9167 ,0 }; - static ulong[] dim3597KuoInit = { 1 , 1 , 1 , 15 , 1 , 25 , 93 , 31 , 227 , 833 , 1891 , 1171 , 4551 , 3329 , 30593 ,0 }; - static ulong[] dim3598KuoInit = { 1 , 3 , 1 , 11 , 29 , 51 , 109 , 27 , 475 , 511 , 1763 , 2285 , 3191 , 7943 , 8373 ,0 }; - static ulong[] dim3599KuoInit = { 1 , 1 , 5 , 3 , 21 , 63 , 89 , 9 , 429 , 613 , 141 , 4011 , 6563 , 5871 , 30701 ,0 }; - static ulong[] dim3600KuoInit = { 1 , 1 , 5 , 1 , 31 , 49 , 87 , 15 , 481 , 237 , 133 , 3267 , 7385 , 4733 , 16853 ,0 }; - static ulong[] dim3601KuoInit = { 1 , 3 , 7 , 9 , 1 , 63 , 95 , 17 , 311 , 29 , 1543 , 2971 , 695 , 3641 , 28155 ,0 }; - static ulong[] dim3602KuoInit = { 1 , 3 , 3 , 7 , 27 , 1 , 59 , 181 , 321 , 431 , 143 , 213 , 1471 , 4707 , 22897 ,0 }; - static ulong[] dim3603KuoInit = { 1 , 1 , 3 , 11 , 19 , 3 , 95 , 1 , 407 , 755 , 1581 , 3435 , 2025 , 7781 , 5573 ,0 }; - static ulong[] dim3604KuoInit = { 1 , 1 , 1 , 1 , 19 , 15 , 119 , 169 , 109 , 1003 , 403 , 1633 , 4963 , 9785 , 18483 ,0 }; - static ulong[] dim3605KuoInit = { 1 , 3 , 7 , 1 , 23 , 5 , 77 , 79 , 429 , 921 , 1913 , 2075 , 7923 , 5515 , 19257 ,0 }; - static ulong[] dim3606KuoInit = { 1 , 3 , 1 , 11 , 1 , 45 , 99 , 249 , 385 , 427 , 1201 , 1363 , 335 , 12561 , 18753 ,0 }; - static ulong[] dim3607KuoInit = { 1 , 1 , 1 , 11 , 27 , 41 , 9 , 13 , 267 , 987 , 1023 , 2723 , 3873 , 15911 , 3165 ,0 }; - static ulong[] dim3608KuoInit = { 1 , 3 , 5 , 1 , 17 , 7 , 117 , 241 , 509 , 757 , 1301 , 3935 , 3361 , 13745 , 27239 ,0 }; - static ulong[] dim3609KuoInit = { 1 , 1 , 5 , 15 , 21 , 33 , 55 , 245 , 1 , 263 , 437 , 2279 , 1201 , 2043 , 20473 ,0 }; - static ulong[] dim3610KuoInit = { 1 , 3 , 7 , 5 , 29 , 9 , 31 , 165 , 299 , 923 , 847 , 769 , 5683 , 1805 , 13433 ,0 }; - static ulong[] dim3611KuoInit = { 1 , 1 , 1 , 11 , 29 , 13 , 49 , 173 , 269 , 35 , 1057 , 973 , 1853 , 12677 , 13565 ,0 }; - static ulong[] dim3612KuoInit = { 1 , 3 , 1 , 11 , 11 , 21 , 19 , 3 , 127 , 133 , 193 , 2665 , 7187 , 15425 , 23805 ,0 }; - static ulong[] dim3613KuoInit = { 1 , 3 , 5 , 7 , 13 , 61 , 95 , 17 , 197 , 381 , 865 , 1241 , 685 , 9525 , 2503 ,0 }; - static ulong[] dim3614KuoInit = { 1 , 1 , 5 , 7 , 13 , 19 , 83 , 141 , 179 , 201 , 463 , 2083 , 3617 , 1945 , 20371 ,0 }; - static ulong[] dim3615KuoInit = { 1 , 3 , 5 , 13 , 9 , 39 , 47 , 3 , 13 , 739 , 1501 , 1007 , 6963 , 15819 , 29739 ,0 }; - static ulong[] dim3616KuoInit = { 1 , 1 , 5 , 7 , 3 , 17 , 105 , 27 , 165 , 515 , 949 , 81 , 947 , 9615 , 24403 ,0 }; - static ulong[] dim3617KuoInit = { 1 , 3 , 7 , 5 , 23 , 43 , 81 , 141 , 181 , 1007 , 1343 , 1919 , 5971 , 8563 , 17091 ,0 }; - static ulong[] dim3618KuoInit = { 1 , 3 , 3 , 11 , 1 , 25 , 19 , 117 , 225 , 347 , 785 , 791 , 7321 , 15647 , 25491 ,0 }; - static ulong[] dim3619KuoInit = { 1 , 1 , 5 , 5 , 11 , 61 , 25 , 205 , 145 , 695 , 713 , 1787 , 8087 , 5935 , 5105 ,0 }; - static ulong[] dim3620KuoInit = { 1 , 1 , 7 , 1 , 15 , 17 , 25 , 141 , 75 , 657 , 1641 , 575 , 3387 , 6093 , 15565 ,0 }; - static ulong[] dim3621KuoInit = { 1 , 3 , 7 , 11 , 31 , 49 , 113 , 37 , 321 , 547 , 819 , 2079 , 7231 , 7497 , 29877 ,0 }; - static ulong[] dim3622KuoInit = { 1 , 1 , 3 , 11 , 31 , 19 , 39 , 99 , 271 , 527 , 1551 , 2491 , 5515 , 5541 , 6131 ,0 }; - static ulong[] dim3623KuoInit = { 1 , 1 , 1 , 7 , 23 , 35 , 31 , 35 , 315 , 911 , 1133 , 3509 , 1381 , 15869 , 23211 ,0 }; - static ulong[] dim3624KuoInit = { 1 , 3 , 3 , 5 , 1 , 33 , 127 , 175 , 311 , 497 , 187 , 2983 , 6553 , 9653 , 5711 ,0 }; - static ulong[] dim3625KuoInit = { 1 , 1 , 3 , 13 , 19 , 3 , 65 , 91 , 265 , 199 , 2035 , 1277 , 4575 , 5517 , 15247 ,0 }; - static ulong[] dim3626KuoInit = { 1 , 1 , 5 , 15 , 31 , 39 , 71 , 167 , 337 , 245 , 399 , 2681 , 1257 , 15117 , 24145 ,0 }; - static ulong[] dim3627KuoInit = { 1 , 1 , 1 , 11 , 7 , 19 , 113 , 133 , 83 , 851 , 1543 , 1699 , 4527 , 3167 , 10793 ,0 }; - static ulong[] dim3628KuoInit = { 1 , 3 , 3 , 3 , 31 , 55 , 35 , 161 , 133 , 83 , 469 , 3011 , 4513 , 4677 , 2363 ,0 }; - static ulong[] dim3629KuoInit = { 1 , 1 , 3 , 1 , 29 , 51 , 29 , 163 , 95 , 221 , 973 , 2819 , 3103 , 9969 , 10347 ,0 }; - static ulong[] dim3630KuoInit = { 1 , 1 , 5 , 7 , 31 , 5 , 73 , 159 , 339 , 523 , 399 , 4041 , 4341 , 11527 , 505 ,0 }; - static ulong[] dim3631KuoInit = { 1 , 1 , 3 , 7 , 15 , 55 , 91 , 117 , 233 , 497 , 485 , 1187 , 5185 , 13127 , 14393 ,0 }; - static ulong[] dim3632KuoInit = { 1 , 3 , 7 , 9 , 27 , 19 , 23 , 197 , 99 , 779 , 423 , 2735 , 3513 , 8227 , 31127 ,0 }; - static ulong[] dim3633KuoInit = { 1 , 3 , 3 , 1 , 3 , 61 , 89 , 137 , 189 , 325 , 1797 , 2287 , 5033 , 7351 , 1131 ,0 }; - static ulong[] dim3634KuoInit = { 1 , 3 , 3 , 15 , 19 , 9 , 83 , 87 , 451 , 317 , 667 , 3379 , 2225 , 6437 , 31515 ,0 }; - static ulong[] dim3635KuoInit = { 1 , 1 , 1 , 15 , 13 , 31 , 121 , 131 , 473 , 717 , 1507 , 1483 , 4819 , 14375 , 24667 ,0 }; - static ulong[] dim3636KuoInit = { 1 , 1 , 1 , 5 , 5 , 55 , 101 , 111 , 89 , 481 , 2031 , 3043 , 5727 , 1253 , 11951 ,0 }; - static ulong[] dim3637KuoInit = { 1 , 3 , 1 , 1 , 3 , 13 , 67 , 129 , 311 , 125 , 121 , 2833 , 3555 , 7761 , 27343 ,0 }; - static ulong[] dim3638KuoInit = { 1 , 3 , 7 , 7 , 29 , 37 , 63 , 59 , 5 , 691 , 1625 , 97 , 6113 , 14795 , 31471 ,0 }; - static ulong[] dim3639KuoInit = { 1 , 3 , 3 , 3 , 25 , 7 , 65 , 207 , 371 , 29 , 1627 , 1785 , 5203 , 5153 , 1461 ,0 }; - static ulong[] dim3640KuoInit = { 1 , 3 , 3 , 11 , 1 , 37 , 121 , 249 , 381 , 309 , 1545 , 4039 , 5657 , 6783 , 1889 ,0 }; - static ulong[] dim3641KuoInit = { 1 , 1 , 1 , 9 , 29 , 19 , 51 , 213 , 185 , 481 , 1929 , 2475 , 567 , 10045 , 32619 ,0 }; - static ulong[] dim3642KuoInit = { 1 , 1 , 3 , 7 , 13 , 13 , 17 , 47 , 55 , 521 , 473 , 495 , 7807 , 1645 , 17713 ,0 }; - static ulong[] dim3643KuoInit = { 1 , 1 , 1 , 3 , 5 , 63 , 119 , 167 , 357 , 231 , 1915 , 3605 , 3579 , 3041 , 603 ,0 }; - static ulong[] dim3644KuoInit = { 1 , 3 , 3 , 7 , 31 , 5 , 93 , 193 , 175 , 801 , 1963 , 1413 , 1641 , 4073 , 16017 ,0 }; - static ulong[] dim3645KuoInit = { 1 , 3 , 3 , 11 , 11 , 49 , 53 , 57 , 1 , 799 , 301 , 2611 , 2975 , 7595 , 25891 ,0 }; - static ulong[] dim3646KuoInit = { 1 , 3 , 1 , 3 , 19 , 41 , 63 , 173 , 257 , 903 , 1977 , 3799 , 3985 , 14807 , 24903 ,0 }; - static ulong[] dim3647KuoInit = { 1 , 3 , 3 , 11 , 17 , 53 , 61 , 115 , 453 , 395 , 993 , 3365 , 4071 , 4737 , 29469 ,0 }; - static ulong[] dim3648KuoInit = { 1 , 3 , 1 , 13 , 3 , 55 , 109 , 149 , 313 , 621 , 345 , 4037 , 677 , 3787 , 6701 ,0 }; - static ulong[] dim3649KuoInit = { 1 , 3 , 3 , 9 , 23 , 11 , 63 , 21 , 47 , 949 , 47 , 3055 , 3403 , 7581 , 12853 ,0 }; - static ulong[] dim3650KuoInit = { 1 , 1 , 1 , 9 , 7 , 21 , 15 , 203 , 167 , 677 , 49 , 2777 , 7817 , 13207 , 31485 ,0 }; - static ulong[] dim3651KuoInit = { 1 , 1 , 1 , 3 , 29 , 41 , 37 , 61 , 343 , 279 , 127 , 925 , 7091 , 14477 , 24149 ,0 }; - static ulong[] dim3652KuoInit = { 1 , 1 , 1 , 11 , 3 , 33 , 35 , 237 , 133 , 653 , 1491 , 2183 , 3565 , 14773 , 4521 ,0 }; - static ulong[] dim3653KuoInit = { 1 , 1 , 5 , 3 , 31 , 43 , 13 , 79 , 465 , 785 , 1913 , 1133 , 2701 , 9007 , 15695 ,0 }; - static ulong[] dim3654KuoInit = { 1 , 3 , 3 , 1 , 23 , 43 , 5 , 155 , 369 , 131 , 671 , 1109 , 7951 , 1929 , 23965 ,0 }; - static ulong[] dim3655KuoInit = { 1 , 1 , 5 , 7 , 9 , 15 , 23 , 59 , 511 , 931 , 259 , 1953 , 1197 , 9441 , 25545 ,0 }; - static ulong[] dim3656KuoInit = { 1 , 1 , 7 , 7 , 27 , 25 , 51 , 81 , 479 , 491 , 203 , 4009 , 4621 , 11153 , 12049 ,0 }; - static ulong[] dim3657KuoInit = { 1 , 3 , 5 , 15 , 25 , 11 , 77 , 253 , 249 , 761 , 707 , 161 , 7519 , 5381 , 1549 ,0 }; - static ulong[] dim3658KuoInit = { 1 , 1 , 1 , 13 , 11 , 39 , 59 , 191 , 443 , 471 , 53 , 1639 , 505 , 1281 , 1919 ,0 }; - static ulong[] dim3659KuoInit = { 1 , 1 , 3 , 7 , 29 , 47 , 121 , 135 , 411 , 95 , 1255 , 635 , 835 , 7905 , 18435 ,0 }; - static ulong[] dim3660KuoInit = { 1 , 1 , 3 , 15 , 21 , 57 , 65 , 75 , 333 , 61 , 1861 , 3903 , 6051 , 8311 , 2791 ,0 }; - static ulong[] dim3661KuoInit = { 1 , 3 , 3 , 7 , 7 , 49 , 121 , 233 , 305 , 697 , 525 , 3921 , 5747 , 2951 , 24321 ,0 }; - static ulong[] dim3662KuoInit = { 1 , 1 , 3 , 3 , 9 , 23 , 53 , 121 , 187 , 35 , 1973 , 829 , 575 , 4003 , 32159 ,0 }; - static ulong[] dim3663KuoInit = { 1 , 1 , 3 , 1 , 3 , 57 , 25 , 99 , 383 , 97 , 1751 , 1799 , 2001 , 8335 , 20349 ,0 }; - static ulong[] dim3664KuoInit = { 1 , 1 , 7 , 9 , 11 , 17 , 25 , 107 , 483 , 183 , 559 , 2531 , 6509 , 9449 , 1793 ,0 }; - static ulong[] dim3665KuoInit = { 1 , 3 , 3 , 1 , 3 , 43 , 89 , 57 , 15 , 269 , 521 , 1119 , 3573 , 9801 , 30943 ,0 }; - static ulong[] dim3666KuoInit = { 1 , 3 , 7 , 3 , 7 , 41 , 101 , 177 , 47 , 47 , 2009 , 2127 , 5113 , 13541 , 4133 ,0 }; - static ulong[] dim3667KuoInit = { 1 , 1 , 3 , 7 , 23 , 63 , 67 , 73 , 335 , 471 , 1137 , 3101 , 5539 , 16203 , 15395 , 12455 ,0 }; - static ulong[] dim3668KuoInit = { 1 , 3 , 1 , 11 , 5 , 9 , 43 , 123 , 91 , 23 , 1199 , 287 , 5343 , 1937 , 12115 , 4749 ,0 }; - static ulong[] dim3669KuoInit = { 1 , 1 , 7 , 11 , 27 , 3 , 29 , 251 , 413 , 147 , 403 , 2065 , 2695 , 11657 , 15519 , 49391 ,0 }; - static ulong[] dim3670KuoInit = { 1 , 3 , 7 , 11 , 25 , 7 , 125 , 137 , 479 , 753 , 309 , 1075 , 7991 , 2629 , 4039 , 6749 ,0 }; - static ulong[] dim3671KuoInit = { 1 , 1 , 7 , 1 , 3 , 27 , 69 , 227 , 503 , 915 , 569 , 115 , 4299 , 10799 , 13745 , 7973 ,0 }; - static ulong[] dim3672KuoInit = { 1 , 3 , 1 , 11 , 17 , 49 , 33 , 161 , 429 , 153 , 1179 , 4005 , 6507 , 10507 , 1779 , 5331 ,0 }; - static ulong[] dim3673KuoInit = { 1 , 3 , 1 , 13 , 25 , 45 , 117 , 47 , 253 , 851 , 627 , 593 , 7555 , 3677 , 30695 , 38851 ,0 }; - static ulong[] dim3674KuoInit = { 1 , 3 , 1 , 11 , 25 , 19 , 95 , 191 , 505 , 683 , 67 , 2375 , 995 , 8647 , 4853 , 17483 ,0 }; - static ulong[] dim3675KuoInit = { 1 , 3 , 3 , 15 , 7 , 57 , 101 , 151 , 477 , 343 , 879 , 2161 , 1585 , 1903 , 6459 , 45285 ,0 }; - static ulong[] dim3676KuoInit = { 1 , 1 , 5 , 3 , 7 , 7 , 31 , 219 , 137 , 107 , 119 , 2959 , 7453 , 9215 , 20463 , 61165 ,0 }; - static ulong[] dim3677KuoInit = { 1 , 1 , 3 , 15 , 25 , 39 , 41 , 165 , 421 , 567 , 1095 , 4055 , 7321 , 831 , 81 , 50377 ,0 }; - static ulong[] dim3678KuoInit = { 1 , 1 , 3 , 1 , 21 , 23 , 65 , 31 , 331 , 875 , 1449 , 653 , 1975 , 783 , 29021 , 47225 ,0 }; - static ulong[] dim3679KuoInit = { 1 , 1 , 7 , 1 , 21 , 21 , 39 , 39 , 289 , 129 , 345 , 2983 , 2419 , 133 , 2519 , 33307 ,0 }; - static ulong[] dim3680KuoInit = { 1 , 3 , 5 , 1 , 27 , 23 , 53 , 63 , 315 , 93 , 335 , 3239 , 6749 , 12985 , 5863 , 49565 ,0 }; - static ulong[] dim3681KuoInit = { 1 , 3 , 7 , 11 , 17 , 23 , 89 , 253 , 329 , 837 , 589 , 1135 , 4099 , 3123 , 25567 , 21017 ,0 }; - static ulong[] dim3682KuoInit = { 1 , 3 , 7 , 3 , 21 , 17 , 111 , 21 , 73 , 901 , 2017 , 3711 , 159 , 6703 , 32209 , 34411 ,0 }; - static ulong[] dim3683KuoInit = { 1 , 1 , 1 , 9 , 19 , 59 , 1 , 31 , 273 , 683 , 1155 , 2543 , 477 , 8479 , 25235 , 61595 ,0 }; - static ulong[] dim3684KuoInit = { 1 , 1 , 7 , 1 , 13 , 17 , 97 , 49 , 221 , 63 , 197 , 465 , 1801 , 5389 , 10395 , 54157 ,0 }; - static ulong[] dim3685KuoInit = { 1 , 1 , 5 , 9 , 11 , 59 , 79 , 139 , 249 , 185 , 1131 , 507 , 3325 , 2713 , 27293 , 21539 ,0 }; - static ulong[] dim3686KuoInit = { 1 , 1 , 3 , 5 , 9 , 45 , 103 , 145 , 327 , 675 , 1609 , 1703 , 761 , 4947 , 187 , 53903 ,0 }; - static ulong[] dim3687KuoInit = { 1 , 1 , 1 , 9 , 19 , 13 , 77 , 143 , 303 , 119 , 1985 , 1347 , 6661 , 6081 , 9723 , 52129 ,0 }; - static ulong[] dim3688KuoInit = { 1 , 3 , 3 , 3 , 27 , 27 , 15 , 163 , 139 , 159 , 1921 , 3549 , 6477 , 11423 , 16055 , 32399 ,0 }; - static ulong[] dim3689KuoInit = { 1 , 3 , 1 , 13 , 19 , 59 , 5 , 73 , 481 , 945 , 187 , 1223 , 1771 , 12961 , 13853 , 14513 ,0 }; - static ulong[] dim3690KuoInit = { 1 , 1 , 7 , 11 , 5 , 63 , 33 , 185 , 477 , 857 , 1057 , 2509 , 7341 , 7669 , 13829 , 51965 ,0 }; - static ulong[] dim3691KuoInit = { 1 , 1 , 3 , 5 , 23 , 17 , 7 , 87 , 101 , 817 , 241 , 853 , 4067 , 6409 , 28217 , 54395 ,0 }; - static ulong[] dim3692KuoInit = { 1 , 3 , 3 , 3 , 21 , 55 , 47 , 159 , 407 , 675 , 1805 , 2079 , 1113 , 149 , 26071 , 30829 ,0 }; - static ulong[] dim3693KuoInit = { 1 , 1 , 3 , 13 , 7 , 3 , 89 , 161 , 95 , 333 , 525 , 3979 , 6831 , 8007 , 7063 , 45299 ,0 }; - static ulong[] dim3694KuoInit = { 1 , 1 , 7 , 5 , 17 , 37 , 95 , 129 , 215 , 313 , 1395 , 2415 , 6191 , 6409 , 29717 , 4199 ,0 }; - static ulong[] dim3695KuoInit = { 1 , 1 , 1 , 7 , 7 , 45 , 75 , 175 , 407 , 763 , 1037 , 2477 , 3167 , 6991 , 23905 , 14707 ,0 }; - static ulong[] dim3696KuoInit = { 1 , 3 , 7 , 7 , 23 , 23 , 103 , 217 , 479 , 779 , 941 , 3173 , 3639 , 12833 , 7133 , 39269 ,0 }; - static ulong[] dim3697KuoInit = { 1 , 1 , 1 , 5 , 9 , 55 , 19 , 147 , 287 , 291 , 1751 , 2475 , 6639 , 5933 , 27837 , 33713 ,0 }; - static ulong[] dim3698KuoInit = { 1 , 1 , 5 , 5 , 11 , 39 , 65 , 109 , 95 , 637 , 1897 , 2395 , 6975 , 12431 , 25097 , 15649 ,0 }; - static ulong[] dim3699KuoInit = { 1 , 1 , 3 , 7 , 25 , 37 , 27 , 53 , 373 , 881 , 1221 , 2127 , 1775 , 2025 , 10249 , 55325 ,0 }; - static ulong[] dim3700KuoInit = { 1 , 1 , 7 , 15 , 5 , 37 , 1 , 99 , 249 , 209 , 1177 , 2953 , 4455 , 12125 , 7679 , 25543 ,0 }; - static ulong[] dim3701KuoInit = { 1 , 3 , 3 , 13 , 9 , 19 , 97 , 11 , 331 , 107 , 1475 , 769 , 1749 , 9375 , 19477 , 47559 ,0 }; - static ulong[] dim3702KuoInit = { 1 , 3 , 7 , 15 , 25 , 57 , 69 , 45 , 21 , 455 , 1841 , 1101 , 2931 , 2845 , 21925 , 43731 ,0 }; - static ulong[] dim3703KuoInit = { 1 , 1 , 3 , 11 , 27 , 33 , 31 , 33 , 9 , 825 , 883 , 2259 , 7317 , 5507 , 3931 , 61075 ,0 }; - static ulong[] dim3704KuoInit = { 1 , 3 , 7 , 5 , 7 , 21 , 97 , 203 , 449 , 671 , 1037 , 3985 , 5655 , 11099 , 21981 , 50149 ,0 }; - static ulong[] dim3705KuoInit = { 1 , 1 , 1 , 1 , 5 , 19 , 109 , 247 , 73 , 981 , 1981 , 3613 , 6575 , 3493 , 9553 , 259 ,0 }; - static ulong[] dim3706KuoInit = { 1 , 1 , 7 , 9 , 3 , 55 , 13 , 175 , 285 , 865 , 1817 , 911 , 6393 , 4843 , 31569 , 30115 ,0 }; - static ulong[] dim3707KuoInit = { 1 , 1 , 3 , 15 , 21 , 51 , 85 , 239 , 171 , 741 , 881 , 749 , 4021 , 2049 , 25495 , 62913 ,0 }; - static ulong[] dim3708KuoInit = { 1 , 3 , 1 , 1 , 19 , 9 , 111 , 119 , 171 , 903 , 567 , 1513 , 8179 , 10553 , 5315 , 63291 ,0 }; - static ulong[] dim3709KuoInit = { 1 , 3 , 5 , 1 , 1 , 61 , 21 , 197 , 165 , 371 , 3 , 2085 , 669 , 4497 , 27467 , 52995 ,0 }; - static ulong[] dim3710KuoInit = { 1 , 3 , 5 , 13 , 29 , 37 , 95 , 247 , 161 , 621 , 83 , 2597 , 6779 , 13747 , 18873 , 6173 ,0 }; - static ulong[] dim3711KuoInit = { 1 , 1 , 3 , 5 , 21 , 5 , 41 , 137 , 77 , 829 , 689 , 563 , 5331 , 8061 , 21371 , 58565 ,0 }; - static ulong[] dim3712KuoInit = { 1 , 3 , 7 , 13 , 1 , 19 , 11 , 111 , 35 , 39 , 1513 , 1241 , 3739 , 16191 , 25097 , 25947 ,0 }; - static ulong[] dim3713KuoInit = { 1 , 1 , 5 , 1 , 27 , 45 , 11 , 29 , 153 , 321 , 1657 , 1419 , 6983 , 11935 , 8295 , 24313 ,0 }; - static ulong[] dim3714KuoInit = { 1 , 3 , 3 , 11 , 1 , 57 , 109 , 139 , 53 , 883 , 81 , 333 , 5133 , 13891 , 7775 , 13401 ,0 }; - static ulong[] dim3715KuoInit = { 1 , 3 , 5 , 15 , 5 , 35 , 121 , 15 , 73 , 313 , 1903 , 437 , 1567 , 11905 , 7679 , 14265 ,0 }; - static ulong[] dim3716KuoInit = { 1 , 3 , 7 , 3 , 31 , 63 , 69 , 135 , 75 , 489 , 1271 , 585 , 7361 , 15965 , 3099 , 37309 ,0 }; - static ulong[] dim3717KuoInit = { 1 , 1 , 7 , 11 , 15 , 21 , 97 , 73 , 115 , 795 , 421 , 69 , 7795 , 9895 , 1755 , 44375 ,0 }; - static ulong[] dim3718KuoInit = { 1 , 3 , 5 , 9 , 17 , 13 , 49 , 61 , 395 , 637 , 1737 , 3103 , 5197 , 7799 , 25425 , 56313 ,0 }; - static ulong[] dim3719KuoInit = { 1 , 3 , 1 , 9 , 17 , 19 , 87 , 131 , 315 , 865 , 813 , 163 , 1045 , 12573 , 12657 , 43715 ,0 }; - static ulong[] dim3720KuoInit = { 1 , 3 , 7 , 3 , 27 , 23 , 9 , 185 , 291 , 421 , 603 , 1339 , 1085 , 15449 , 1543 , 5815 ,0 }; - static ulong[] dim3721KuoInit = { 1 , 3 , 1 , 5 , 29 , 35 , 15 , 75 , 135 , 911 , 1153 , 3067 , 3475 , 11653 , 27485 , 8459 ,0 }; - static ulong[] dim3722KuoInit = { 1 , 3 , 5 , 7 , 3 , 9 , 43 , 29 , 77 , 551 , 973 , 2165 , 1499 , 9185 , 27025 , 31605 ,0 }; - static ulong[] dim3723KuoInit = { 1 , 1 , 1 , 9 , 23 , 49 , 13 , 229 , 295 , 497 , 187 , 1995 , 1883 , 9109 , 2689 , 37275 ,0 }; - static ulong[] dim3724KuoInit = { 1 , 1 , 7 , 15 , 11 , 1 , 61 , 183 , 129 , 869 , 1271 , 3439 , 7743 , 5831 , 12829 , 1341 ,0 }; - static ulong[] dim3725KuoInit = { 1 , 3 , 7 , 1 , 17 , 45 , 31 , 29 , 441 , 533 , 1479 , 3519 , 2083 , 149 , 22119 , 37615 ,0 }; - static ulong[] dim3726KuoInit = { 1 , 1 , 3 , 7 , 31 , 39 , 101 , 209 , 237 , 211 , 1015 , 1339 , 857 , 3833 , 16875 , 38147 ,0 }; - static ulong[] dim3727KuoInit = { 1 , 3 , 7 , 13 , 29 , 23 , 9 , 79 , 71 , 363 , 487 , 595 , 259 , 12425 , 28181 , 20717 ,0 }; - static ulong[] dim3728KuoInit = { 1 , 3 , 3 , 11 , 1 , 21 , 97 , 39 , 101 , 1 , 121 , 3083 , 109 , 7889 , 29005 , 57081 ,0 }; - static ulong[] dim3729KuoInit = { 1 , 3 , 3 , 15 , 19 , 19 , 91 , 17 , 281 , 121 , 1653 , 3099 , 181 , 15911 , 29553 , 10047 ,0 }; - static ulong[] dim3730KuoInit = { 1 , 1 , 3 , 9 , 27 , 39 , 69 , 57 , 25 , 595 , 723 , 1779 , 7537 , 9397 , 5563 , 8197 ,0 }; - static ulong[] dim3731KuoInit = { 1 , 1 , 1 , 1 , 11 , 61 , 127 , 81 , 439 , 723 , 1147 , 3639 , 1207 , 5127 , 10209 , 33629 ,0 }; - static ulong[] dim3732KuoInit = { 1 , 3 , 1 , 9 , 27 , 55 , 69 , 147 , 477 , 663 , 833 , 3113 , 2585 , 9497 , 679 , 62759 ,0 }; - static ulong[] dim3733KuoInit = { 1 , 3 , 1 , 15 , 9 , 51 , 67 , 191 , 105 , 3 , 1439 , 1915 , 3059 , 3001 , 4035 , 551 ,0 }; - static ulong[] dim3734KuoInit = { 1 , 1 , 3 , 15 , 1 , 3 , 11 , 171 , 189 , 659 , 1279 , 3995 , 6729 , 6187 , 22213 , 22709 ,0 }; - static ulong[] dim3735KuoInit = { 1 , 1 , 7 , 11 , 27 , 31 , 3 , 183 , 209 , 931 , 99 , 1901 , 113 , 15779 , 11525 , 29949 ,0 }; - static ulong[] dim3736KuoInit = { 1 , 3 , 7 , 13 , 11 , 51 , 1 , 173 , 271 , 785 , 1875 , 2115 , 1977 , 189 , 7819 , 8133 ,0 }; - static ulong[] dim3737KuoInit = { 1 , 3 , 7 , 7 , 21 , 9 , 5 , 253 , 495 , 415 , 3 , 1979 , 2331 , 12229 , 29901 , 7115 ,0 }; - static ulong[] dim3738KuoInit = { 1 , 3 , 1 , 15 , 21 , 11 , 105 , 81 , 269 , 347 , 901 , 81 , 7077 , 11813 , 18739 , 57959 ,0 }; - static ulong[] dim3739KuoInit = { 1 , 1 , 1 , 1 , 19 , 57 , 17 , 87 , 325 , 129 , 1907 , 1641 , 6247 , 12073 , 31629 , 28503 ,0 }; - static ulong[] dim3740KuoInit = { 1 , 1 , 5 , 15 , 29 , 27 , 81 , 11 , 383 , 881 , 1385 , 3787 , 503 , 1369 , 25031 , 42049 ,0 }; - static ulong[] dim3741KuoInit = { 1 , 3 , 7 , 15 , 27 , 15 , 13 , 13 , 279 , 785 , 163 , 1907 , 4523 , 12133 , 1497 , 18845 ,0 }; - static ulong[] dim3742KuoInit = { 1 , 3 , 7 , 9 , 13 , 37 , 51 , 83 , 309 , 645 , 383 , 1607 , 2087 , 14287 , 14375 , 39619 ,0 }; - static ulong[] dim3743KuoInit = { 1 , 3 , 7 , 5 , 11 , 13 , 21 , 45 , 95 , 667 , 1597 , 1823 , 5887 , 10909 , 26279 , 29845 ,0 }; - static ulong[] dim3744KuoInit = { 1 , 3 , 1 , 1 , 25 , 61 , 21 , 91 , 81 , 173 , 1271 , 339 , 2185 , 16033 , 3687 , 53797 ,0 }; - static ulong[] dim3745KuoInit = { 1 , 3 , 3 , 15 , 19 , 27 , 59 , 153 , 453 , 523 , 85 , 3367 , 4439 , 13605 , 6219 , 25593 ,0 }; - static ulong[] dim3746KuoInit = { 1 , 3 , 5 , 3 , 27 , 57 , 127 , 225 , 199 , 823 , 431 , 2911 , 4421 , 14063 , 1467 , 46787 ,0 }; - static ulong[] dim3747KuoInit = { 1 , 3 , 5 , 1 , 31 , 33 , 17 , 73 , 357 , 199 , 677 , 2015 , 1213 , 8503 , 4785 , 54835 ,0 }; - static ulong[] dim3748KuoInit = { 1 , 1 , 1 , 11 , 15 , 13 , 65 , 1 , 311 , 469 , 1307 , 2605 , 5281 , 15665 , 6349 , 61753 ,0 }; - static ulong[] dim3749KuoInit = { 1 , 1 , 1 , 3 , 19 , 33 , 49 , 141 , 229 , 925 , 1059 , 1295 , 3093 , 6207 , 7607 , 63987 ,0 }; - static ulong[] dim3750KuoInit = { 1 , 1 , 3 , 1 , 21 , 63 , 17 , 131 , 27 , 295 , 1969 , 3259 , 2011 , 11005 , 32249 , 57641 ,0 }; - static ulong[] dim3751KuoInit = { 1 , 3 , 7 , 15 , 25 , 27 , 11 , 105 , 99 , 923 , 1003 , 2765 , 49 , 10367 , 22119 , 27199 ,0 }; - static ulong[] dim3752KuoInit = { 1 , 1 , 1 , 3 , 31 , 11 , 57 , 253 , 31 , 259 , 1687 , 1135 , 1675 , 12051 , 3543 , 19087 ,0 }; - static ulong[] dim3753KuoInit = { 1 , 3 , 5 , 9 , 9 , 53 , 119 , 215 , 213 , 67 , 343 , 2743 , 7303 , 14225 , 13379 , 51001 ,0 }; - static ulong[] dim3754KuoInit = { 1 , 3 , 7 , 9 , 1 , 45 , 11 , 125 , 209 , 459 , 1037 , 673 , 2497 , 669 , 11251 , 19387 ,0 }; - static ulong[] dim3755KuoInit = { 1 , 1 , 1 , 15 , 21 , 47 , 63 , 45 , 349 , 561 , 1823 , 2005 , 4173 , 5595 , 3789 , 34133 ,0 }; - static ulong[] dim3756KuoInit = { 1 , 1 , 3 , 3 , 5 , 7 , 83 , 63 , 305 , 679 , 879 , 3613 , 7627 , 9849 , 3987 , 28795 ,0 }; - static ulong[] dim3757KuoInit = { 1 , 3 , 7 , 11 , 7 , 51 , 119 , 1 , 21 , 213 , 1399 , 3715 , 7775 , 1003 , 6749 , 5547 ,0 }; - static ulong[] dim3758KuoInit = { 1 , 1 , 7 , 9 , 21 , 53 , 51 , 137 , 379 , 439 , 1497 , 3455 , 2509 , 2539 , 3583 , 5107 ,0 }; - static ulong[] dim3759KuoInit = { 1 , 3 , 5 , 3 , 9 , 13 , 73 , 237 , 65 , 53 , 663 , 3895 , 7579 , 10027 , 23969 , 34767 ,0 }; - static ulong[] dim3760KuoInit = { 1 , 3 , 7 , 3 , 13 , 57 , 125 , 245 , 243 , 561 , 91 , 863 , 1925 , 13553 , 4113 , 31077 ,0 }; - static ulong[] dim3761KuoInit = { 1 , 1 , 5 , 7 , 9 , 31 , 9 , 83 , 355 , 249 , 1741 , 3593 , 425 , 6377 , 10607 , 48275 ,0 }; - static ulong[] dim3762KuoInit = { 1 , 3 , 7 , 3 , 19 , 17 , 123 , 75 , 413 , 981 , 877 , 3489 , 5907 , 6141 , 2729 , 49219 ,0 }; - static ulong[] dim3763KuoInit = { 1 , 3 , 1 , 3 , 31 , 39 , 97 , 233 , 99 , 17 , 105 , 2911 , 347 , 4069 , 32535 , 47179 ,0 }; - static ulong[] dim3764KuoInit = { 1 , 1 , 5 , 7 , 1 , 51 , 1 , 59 , 197 , 487 , 1763 , 2449 , 4249 , 55 , 11885 , 57597 ,0 }; - static ulong[] dim3765KuoInit = { 1 , 3 , 5 , 3 , 25 , 49 , 43 , 101 , 353 , 759 , 1295 , 3441 , 1521 , 2879 , 9815 , 27091 ,0 }; - static ulong[] dim3766KuoInit = { 1 , 3 , 5 , 11 , 1 , 7 , 69 , 205 , 271 , 511 , 1157 , 3597 , 2857 , 10997 , 15525 , 6807 ,0 }; - static ulong[] dim3767KuoInit = { 1 , 1 , 1 , 15 , 11 , 1 , 45 , 213 , 463 , 389 , 1761 , 3005 , 3359 , 12829 , 18211 , 2107 ,0 }; - static ulong[] dim3768KuoInit = { 1 , 1 , 7 , 13 , 27 , 59 , 115 , 203 , 321 , 711 , 1489 , 2893 , 1427 , 4599 , 17105 , 10063 ,0 }; - static ulong[] dim3769KuoInit = { 1 , 3 , 1 , 13 , 5 , 5 , 53 , 221 , 97 , 535 , 1967 , 1951 , 4077 , 327 , 18243 , 43285 ,0 }; - static ulong[] dim3770KuoInit = { 1 , 3 , 5 , 13 , 9 , 61 , 59 , 255 , 143 , 21 , 1859 , 3509 , 4295 , 5107 , 11117 , 29431 ,0 }; - static ulong[] dim3771KuoInit = { 1 , 3 , 3 , 13 , 19 , 13 , 33 , 169 , 17 , 773 , 1693 , 147 , 5143 , 2357 , 2295 , 50187 ,0 }; - static ulong[] dim3772KuoInit = { 1 , 1 , 5 , 11 , 11 , 19 , 79 , 151 , 441 , 825 , 665 , 2947 , 5391 , 8695 , 155 , 26751 ,0 }; - static ulong[] dim3773KuoInit = { 1 , 1 , 7 , 15 , 13 , 31 , 77 , 61 , 249 , 341 , 1737 , 3567 , 6337 , 14457 , 3799 , 20283 ,0 }; - static ulong[] dim3774KuoInit = { 1 , 1 , 7 , 11 , 13 , 5 , 83 , 59 , 185 , 325 , 2029 , 1329 , 1125 , 10799 , 27107 , 2817 ,0 }; - static ulong[] dim3775KuoInit = { 1 , 3 , 5 , 7 , 17 , 43 , 21 , 113 , 57 , 503 , 1647 , 393 , 4525 , 8385 , 27153 , 37175 ,0 }; - static ulong[] dim3776KuoInit = { 1 , 3 , 1 , 15 , 23 , 57 , 3 , 177 , 419 , 65 , 1895 , 1107 , 7705 , 7915 , 20677 , 27931 ,0 }; - static ulong[] dim3777KuoInit = { 1 , 3 , 7 , 13 , 13 , 63 , 53 , 237 , 237 , 161 , 265 , 1053 , 161 , 11635 , 1455 , 55551 ,0 }; - static ulong[] dim3778KuoInit = { 1 , 3 , 7 , 5 , 15 , 41 , 7 , 77 , 93 , 737 , 1195 , 1381 , 399 , 7829 , 6251 , 34883 ,0 }; - static ulong[] dim3779KuoInit = { 1 , 1 , 5 , 7 , 23 , 63 , 119 , 35 , 115 , 829 , 441 , 4059 , 4755 , 11331 , 18071 , 6911 ,0 }; - static ulong[] dim3780KuoInit = { 1 , 3 , 3 , 7 , 21 , 33 , 49 , 47 , 329 , 341 , 45 , 3093 , 5937 , 6803 , 31681 , 9575 ,0 }; - static ulong[] dim3781KuoInit = { 1 , 1 , 1 , 13 , 13 , 19 , 121 , 71 , 231 , 915 , 981 , 93 , 5879 , 15645 , 8555 , 58411 ,0 }; - static ulong[] dim3782KuoInit = { 1 , 3 , 7 , 5 , 31 , 45 , 71 , 189 , 337 , 955 , 1263 , 2271 , 1615 , 15137 , 29933 , 16585 ,0 }; - static ulong[] dim3783KuoInit = { 1 , 1 , 7 , 15 , 29 , 49 , 85 , 255 , 143 , 585 , 1099 , 1159 , 1519 , 15593 , 6177 , 16083 ,0 }; - static ulong[] dim3784KuoInit = { 1 , 3 , 5 , 1 , 13 , 59 , 79 , 67 , 341 , 815 , 703 , 3857 , 4711 , 15155 , 15997 , 31699 ,0 }; - static ulong[] dim3785KuoInit = { 1 , 3 , 3 , 7 , 11 , 51 , 77 , 231 , 241 , 261 , 1607 , 4031 , 3779 , 4289 , 22039 , 47177 ,0 }; - static ulong[] dim3786KuoInit = { 1 , 3 , 7 , 1 , 21 , 23 , 31 , 233 , 225 , 883 , 715 , 777 , 2433 , 3665 , 26695 , 60997 ,0 }; - static ulong[] dim3787KuoInit = { 1 , 3 , 1 , 1 , 27 , 17 , 55 , 33 , 133 , 899 , 1443 , 283 , 6839 , 9497 , 22399 , 60527 ,0 }; - static ulong[] dim3788KuoInit = { 1 , 1 , 3 , 3 , 5 , 63 , 91 , 5 , 275 , 219 , 1679 , 2385 , 4727 , 9995 , 14079 , 24695 ,0 }; - static ulong[] dim3789KuoInit = { 1 , 3 , 7 , 15 , 9 , 3 , 77 , 215 , 265 , 317 , 1655 , 1027 , 5029 , 6867 , 9465 , 64257 ,0 }; - static ulong[] dim3790KuoInit = { 1 , 3 , 1 , 3 , 23 , 7 , 67 , 63 , 503 , 269 , 85 , 3669 , 5941 , 13833 , 25857 , 34221 ,0 }; - static ulong[] dim3791KuoInit = { 1 , 1 , 1 , 7 , 13 , 31 , 83 , 113 , 389 , 923 , 1173 , 2457 , 997 , 9761 , 17033 , 50521 ,0 }; - static ulong[] dim3792KuoInit = { 1 , 3 , 1 , 1 , 15 , 31 , 93 , 243 , 221 , 331 , 1961 , 3251 , 6459 , 3341 , 28535 , 27909 ,0 }; - static ulong[] dim3793KuoInit = { 1 , 3 , 1 , 15 , 27 , 1 , 75 , 169 , 277 , 921 , 5 , 1391 , 5665 , 14659 , 6895 , 37927 ,0 }; - static ulong[] dim3794KuoInit = { 1 , 3 , 1 , 9 , 17 , 63 , 93 , 35 , 225 , 109 , 977 , 2623 , 3779 , 8011 , 11643 , 57789 ,0 }; - static ulong[] dim3795KuoInit = { 1 , 1 , 5 , 3 , 17 , 5 , 63 , 109 , 449 , 695 , 1021 , 2749 , 3981 , 2073 , 24537 , 43643 ,0 }; - static ulong[] dim3796KuoInit = { 1 , 1 , 5 , 1 , 1 , 19 , 15 , 249 , 3 , 431 , 743 , 3813 , 4013 , 4027 , 1943 , 23569 ,0 }; - static ulong[] dim3797KuoInit = { 1 , 3 , 7 , 1 , 9 , 49 , 93 , 59 , 425 , 325 , 1925 , 495 , 6611 , 2425 , 19847 , 58683 ,0 }; - static ulong[] dim3798KuoInit = { 1 , 3 , 5 , 5 , 7 , 21 , 71 , 51 , 335 , 67 , 373 , 1805 , 1805 , 4069 , 6585 , 56579 ,0 }; - static ulong[] dim3799KuoInit = { 1 , 3 , 1 , 7 , 25 , 27 , 49 , 131 , 491 , 105 , 1467 , 665 , 6777 , 15467 , 13597 , 49141 ,0 }; - static ulong[] dim3800KuoInit = { 1 , 3 , 5 , 13 , 9 , 9 , 37 , 159 , 19 , 91 , 1963 , 3133 , 5147 , 8655 , 11153 , 44491 ,0 }; - static ulong[] dim3801KuoInit = { 1 , 3 , 5 , 7 , 13 , 55 , 41 , 67 , 155 , 853 , 1651 , 3511 , 4391 , 6359 , 9129 , 32359 ,0 }; - static ulong[] dim3802KuoInit = { 1 , 3 , 5 , 5 , 9 , 3 , 27 , 101 , 467 , 185 , 1071 , 1477 , 1523 , 9535 , 15433 , 7493 ,0 }; - static ulong[] dim3803KuoInit = { 1 , 1 , 1 , 3 , 15 , 19 , 3 , 97 , 241 , 995 , 451 , 1651 , 241 , 1063 , 2521 , 65531 ,0 }; - static ulong[] dim3804KuoInit = { 1 , 3 , 3 , 5 , 23 , 13 , 117 , 65 , 119 , 871 , 1245 , 3577 , 7303 , 9433 , 13701 , 21321 ,0 }; - static ulong[] dim3805KuoInit = { 1 , 1 , 1 , 11 , 25 , 33 , 121 , 203 , 325 , 775 , 1835 , 1385 , 2541 , 3399 , 275 , 54311 ,0 }; - static ulong[] dim3806KuoInit = { 1 , 1 , 3 , 3 , 13 , 41 , 5 , 63 , 415 , 771 , 375 , 3933 , 5239 , 1731 , 7675 , 11855 ,0 }; - static ulong[] dim3807KuoInit = { 1 , 1 , 5 , 7 , 23 , 49 , 27 , 119 , 231 , 897 , 1995 , 3847 , 25 , 7505 , 2823 , 10115 ,0 }; - static ulong[] dim3808KuoInit = { 1 , 3 , 5 , 1 , 5 , 41 , 41 , 129 , 339 , 861 , 147 , 3299 , 1123 , 2175 , 27111 , 2067 ,0 }; - static ulong[] dim3809KuoInit = { 1 , 1 , 3 , 5 , 5 , 39 , 71 , 53 , 483 , 585 , 1167 , 2037 , 3125 , 499 , 29491 , 43467 ,0 }; - static ulong[] dim3810KuoInit = { 1 , 1 , 1 , 3 , 25 , 9 , 85 , 197 , 271 , 457 , 1159 , 3805 , 2423 , 11777 , 4383 , 57495 ,0 }; - static ulong[] dim3811KuoInit = { 1 , 3 , 7 , 9 , 25 , 5 , 33 , 255 , 325 , 643 , 499 , 3233 , 4477 , 14189 , 12183 , 7667 ,0 }; - static ulong[] dim3812KuoInit = { 1 , 3 , 3 , 5 , 1 , 63 , 3 , 51 , 173 , 1011 , 1423 , 3453 , 2471 , 7801 , 29989 , 8347 ,0 }; - static ulong[] dim3813KuoInit = { 1 , 1 , 7 , 11 , 17 , 39 , 23 , 13 , 413 , 503 , 321 , 3699 , 6441 , 11953 , 24253 , 2561 ,0 }; - static ulong[] dim3814KuoInit = { 1 , 1 , 1 , 3 , 31 , 45 , 21 , 215 , 55 , 555 , 771 , 2703 , 8113 , 3279 , 6053 , 48617 ,0 }; - static ulong[] dim3815KuoInit = { 1 , 1 , 7 , 9 , 25 , 25 , 33 , 101 , 111 , 643 , 1277 , 3833 , 7431 , 14395 , 20849 , 14455 ,0 }; - static ulong[] dim3816KuoInit = { 1 , 3 , 7 , 11 , 21 , 15 , 95 , 179 , 437 , 747 , 1131 , 83 , 415 , 12605 , 29245 , 28021 ,0 }; - static ulong[] dim3817KuoInit = { 1 , 3 , 7 , 5 , 13 , 59 , 9 , 217 , 287 , 929 , 691 , 3201 , 4915 , 3301 , 15371 , 17063 ,0 }; - static ulong[] dim3818KuoInit = { 1 , 1 , 1 , 7 , 31 , 3 , 27 , 229 , 151 , 321 , 801 , 1271 , 1195 , 11221 , 16903 , 27919 ,0 }; - static ulong[] dim3819KuoInit = { 1 , 1 , 5 , 9 , 5 , 41 , 105 , 133 , 265 , 167 , 505 , 3939 , 771 , 1291 , 1109 , 52601 ,0 }; - static ulong[] dim3820KuoInit = { 1 , 3 , 5 , 11 , 21 , 23 , 23 , 229 , 197 , 623 , 1973 , 901 , 147 , 15751 , 29429 , 13159 ,0 }; - static ulong[] dim3821KuoInit = { 1 , 1 , 5 , 11 , 25 , 53 , 79 , 123 , 245 , 939 , 1889 , 4073 , 417 , 13625 , 14691 , 56965 ,0 }; - static ulong[] dim3822KuoInit = { 1 , 1 , 1 , 11 , 1 , 39 , 51 , 231 , 367 , 233 , 1453 , 3095 , 6071 , 7521 , 469 , 8407 ,0 }; - static ulong[] dim3823KuoInit = { 1 , 3 , 5 , 1 , 9 , 17 , 109 , 135 , 85 , 151 , 1217 , 1643 , 4455 , 3923 , 11681 , 32807 ,0 }; - static ulong[] dim3824KuoInit = { 1 , 1 , 1 , 13 , 11 , 39 , 27 , 205 , 85 , 1019 , 1759 , 1705 , 4585 , 8311 , 29123 , 44045 ,0 }; - static ulong[] dim3825KuoInit = { 1 , 3 , 1 , 3 , 9 , 33 , 65 , 253 , 319 , 65 , 851 , 3357 , 2827 , 10107 , 10197 , 19111 ,0 }; - static ulong[] dim3826KuoInit = { 1 , 3 , 7 , 3 , 3 , 53 , 67 , 99 , 501 , 603 , 1409 , 359 , 7395 , 12827 , 10867 , 17473 ,0 }; - static ulong[] dim3827KuoInit = { 1 , 1 , 7 , 5 , 5 , 35 , 97 , 49 , 365 , 971 , 1707 , 1305 , 6801 , 14451 , 32473 , 57269 ,0 }; - static ulong[] dim3828KuoInit = { 1 , 1 , 5 , 11 , 25 , 57 , 115 , 195 , 47 , 923 , 1515 , 2043 , 803 , 6371 , 25341 , 63263 ,0 }; - static ulong[] dim3829KuoInit = { 1 , 1 , 5 , 3 , 27 , 53 , 83 , 91 , 367 , 695 , 1809 , 927 , 6815 , 1229 , 27359 , 28937 ,0 }; - static ulong[] dim3830KuoInit = { 1 , 1 , 3 , 7 , 3 , 3 , 17 , 203 , 95 , 577 , 1531 , 1645 , 7271 , 5541 , 30905 , 38825 ,0 }; - static ulong[] dim3831KuoInit = { 1 , 1 , 7 , 9 , 7 , 57 , 97 , 185 , 75 , 681 , 1197 , 3713 , 6429 , 4723 , 26275 , 23495 ,0 }; - static ulong[] dim3832KuoInit = { 1 , 3 , 1 , 3 , 5 , 25 , 71 , 171 , 143 , 603 , 1349 , 1723 , 7493 , 8417 , 24171 , 13421 ,0 }; - static ulong[] dim3833KuoInit = { 1 , 3 , 1 , 15 , 23 , 57 , 33 , 247 , 409 , 511 , 29 , 1403 , 5831 , 1749 , 28441 , 4117 ,0 }; - static ulong[] dim3834KuoInit = { 1 , 1 , 3 , 15 , 31 , 11 , 105 , 239 , 431 , 127 , 343 , 961 , 6449 , 1677 , 24937 , 15859 ,0 }; - static ulong[] dim3835KuoInit = { 1 , 1 , 5 , 3 , 27 , 57 , 61 , 245 , 425 , 417 , 301 , 521 , 2425 , 2547 , 11349 , 47931 ,0 }; - static ulong[] dim3836KuoInit = { 1 , 3 , 5 , 3 , 15 , 19 , 19 , 127 , 151 , 913 , 1061 , 1795 , 2519 , 6297 , 2519 , 56677 ,0 }; - static ulong[] dim3837KuoInit = { 1 , 1 , 3 , 9 , 25 , 3 , 67 , 53 , 305 , 609 , 1067 , 1003 , 6933 , 14009 , 24475 , 23183 ,0 }; - static ulong[] dim3838KuoInit = { 1 , 1 , 5 , 7 , 21 , 35 , 89 , 95 , 399 , 341 , 1337 , 2815 , 3605 , 3209 , 9881 , 6399 ,0 }; - static ulong[] dim3839KuoInit = { 1 , 1 , 7 , 1 , 29 , 63 , 23 , 219 , 145 , 583 , 985 , 2577 , 3951 , 15199 , 26981 , 2755 ,0 }; - static ulong[] dim3840KuoInit = { 1 , 3 , 7 , 1 , 13 , 45 , 105 , 139 , 103 , 83 , 819 , 2655 , 39 , 11661 , 11057 , 38189 ,0 }; - static ulong[] dim3841KuoInit = { 1 , 3 , 1 , 15 , 23 , 41 , 79 , 237 , 353 , 67 , 1551 , 2345 , 1169 , 4623 , 1391 , 18607 ,0 }; - static ulong[] dim3842KuoInit = { 1 , 1 , 1 , 13 , 29 , 31 , 43 , 65 , 25 , 387 , 1109 , 2515 , 3967 , 2221 , 27321 , 20511 ,0 }; - static ulong[] dim3843KuoInit = { 1 , 1 , 1 , 3 , 17 , 45 , 35 , 211 , 31 , 45 , 1791 , 2225 , 6995 , 15241 , 24555 , 45993 ,0 }; - static ulong[] dim3844KuoInit = { 1 , 1 , 5 , 5 , 31 , 25 , 71 , 57 , 87 , 531 , 117 , 267 , 2415 , 2213 , 603 , 23369 ,0 }; - static ulong[] dim3845KuoInit = { 1 , 1 , 1 , 5 , 23 , 53 , 39 , 3 , 93 , 697 , 25 , 465 , 1517 , 6061 , 11759 , 34863 ,0 }; - static ulong[] dim3846KuoInit = { 1 , 1 , 1 , 13 , 29 , 29 , 41 , 27 , 499 , 285 , 355 , 3915 , 1683 , 11933 , 24685 , 59013 ,0 }; - static ulong[] dim3847KuoInit = { 1 , 3 , 1 , 3 , 21 , 21 , 25 , 251 , 109 , 469 , 1841 , 889 , 6541 , 12961 , 9449 , 48755 ,0 }; - static ulong[] dim3848KuoInit = { 1 , 3 , 1 , 1 , 21 , 59 , 41 , 159 , 159 , 105 , 999 , 2535 , 3251 , 12213 , 24005 , 17145 ,0 }; - static ulong[] dim3849KuoInit = { 1 , 1 , 7 , 9 , 1 , 39 , 43 , 235 , 447 , 767 , 871 , 453 , 7285 , 3387 , 14625 , 40099 ,0 }; - static ulong[] dim3850KuoInit = { 1 , 1 , 3 , 3 , 5 , 11 , 15 , 205 , 183 , 309 , 1747 , 1089 , 3141 , 9129 , 25149 , 63109 ,0 }; - static ulong[] dim3851KuoInit = { 1 , 3 , 7 , 15 , 23 , 15 , 7 , 157 , 45 , 263 , 1383 , 735 , 205 , 16021 , 13233 , 23425 ,0 }; - static ulong[] dim3852KuoInit = { 1 , 1 , 7 , 13 , 11 , 31 , 53 , 23 , 357 , 953 , 611 , 2579 , 475 , 15183 , 12755 , 10347 ,0 }; - static ulong[] dim3853KuoInit = { 1 , 1 , 1 , 5 , 7 , 27 , 41 , 215 , 247 , 1001 , 1369 , 3105 , 3195 , 13417 , 6967 , 52501 ,0 }; - static ulong[] dim3854KuoInit = { 1 , 3 , 7 , 3 , 3 , 61 , 35 , 175 , 415 , 835 , 1381 , 3951 , 6857 , 10273 , 26657 , 5239 ,0 }; - static ulong[] dim3855KuoInit = { 1 , 3 , 7 , 5 , 1 , 27 , 3 , 251 , 499 , 637 , 1101 , 3817 , 4823 , 3065 , 29919 , 4151 ,0 }; - static ulong[] dim3856KuoInit = { 1 , 3 , 7 , 13 , 19 , 39 , 1 , 141 , 353 , 853 , 295 , 1201 , 6895 , 3965 , 6417 , 47379 ,0 }; - static ulong[] dim3857KuoInit = { 1 , 1 , 7 , 13 , 11 , 9 , 99 , 225 , 161 , 349 , 421 , 2803 , 4461 , 2319 , 2495 , 62429 ,0 }; - static ulong[] dim3858KuoInit = { 1 , 3 , 1 , 13 , 31 , 1 , 47 , 115 , 299 , 331 , 1917 , 2547 , 969 , 4841 , 8237 , 2405 ,0 }; - static ulong[] dim3859KuoInit = { 1 , 1 , 1 , 9 , 9 , 19 , 77 , 35 , 225 , 211 , 1875 , 3531 , 2753 , 12679 , 6863 , 42143 ,0 }; - static ulong[] dim3860KuoInit = { 1 , 1 , 1 , 3 , 29 , 25 , 105 , 19 , 269 , 863 , 811 , 2741 , 143 , 6353 , 25109 , 62251 ,0 }; - static ulong[] dim3861KuoInit = { 1 , 3 , 5 , 3 , 27 , 51 , 11 , 61 , 245 , 517 , 891 , 2081 , 4523 , 11703 , 31477 , 12113 ,0 }; - static ulong[] dim3862KuoInit = { 1 , 1 , 1 , 1 , 27 , 29 , 25 , 47 , 143 , 489 , 1475 , 1139 , 1855 , 8031 , 21341 , 23619 ,0 }; - static ulong[] dim3863KuoInit = { 1 , 1 , 5 , 1 , 3 , 45 , 103 , 59 , 123 , 831 , 1883 , 149 , 5843 , 10275 , 3121 , 21411 ,0 }; - static ulong[] dim3864KuoInit = { 1 , 1 , 7 , 1 , 21 , 11 , 1 , 35 , 285 , 501 , 1407 , 1307 , 1371 , 15057 , 14091 , 52279 ,0 }; - static ulong[] dim3865KuoInit = { 1 , 1 , 3 , 13 , 3 , 5 , 9 , 167 , 139 , 255 , 1561 , 2183 , 1079 , 2055 , 24779 , 19737 ,0 }; - static ulong[] dim3866KuoInit = { 1 , 1 , 7 , 13 , 31 , 29 , 59 , 157 , 311 , 447 , 21 , 2177 , 3679 , 7519 , 987 , 44221 ,0 }; - static ulong[] dim3867KuoInit = { 1 , 3 , 3 , 1 , 11 , 31 , 95 , 23 , 457 , 733 , 1413 , 273 , 333 , 14391 , 16557 , 35227 ,0 }; - static ulong[] dim3868KuoInit = { 1 , 1 , 3 , 9 , 5 , 3 , 103 , 59 , 21 , 475 , 1455 , 2995 , 7651 , 4893 , 21739 , 21379 ,0 }; - static ulong[] dim3869KuoInit = { 1 , 3 , 5 , 1 , 9 , 63 , 55 , 127 , 283 , 603 , 1477 , 331 , 2115 , 15965 , 22433 , 17311 ,0 }; - static ulong[] dim3870KuoInit = { 1 , 1 , 3 , 3 , 5 , 61 , 105 , 175 , 245 , 431 , 479 , 821 , 3835 , 3585 , 16533 , 63233 ,0 }; - static ulong[] dim3871KuoInit = { 1 , 1 , 7 , 1 , 31 , 57 , 9 , 11 , 145 , 519 , 1915 , 2809 , 2943 , 13885 , 31223 , 32897 ,0 }; - static ulong[] dim3872KuoInit = { 1 , 3 , 1 , 15 , 5 , 39 , 67 , 179 , 285 , 91 , 1429 , 3571 , 1925 , 9737 , 28647 , 8189 ,0 }; - static ulong[] dim3873KuoInit = { 1 , 3 , 7 , 11 , 21 , 25 , 51 , 173 , 151 , 283 , 765 , 2717 , 3541 , 10317 , 9827 , 24445 ,0 }; - static ulong[] dim3874KuoInit = { 1 , 3 , 1 , 13 , 31 , 25 , 121 , 71 , 347 , 129 , 159 , 1845 , 475 , 12777 , 19607 , 7163 ,0 }; - static ulong[] dim3875KuoInit = { 1 , 3 , 1 , 9 , 29 , 37 , 59 , 117 , 375 , 411 , 1031 , 3781 , 3119 , 6851 , 30759 , 46181 ,0 }; - static ulong[] dim3876KuoInit = { 1 , 3 , 1 , 7 , 5 , 41 , 81 , 141 , 377 , 817 , 1007 , 2211 , 7303 , 5833 , 6117 , 52265 ,0 }; - static ulong[] dim3877KuoInit = { 1 , 3 , 5 , 3 , 7 , 63 , 83 , 181 , 169 , 19 , 1589 , 3793 , 7003 , 12145 , 25625 , 35731 ,0 }; - static ulong[] dim3878KuoInit = { 1 , 1 , 1 , 5 , 21 , 39 , 15 , 225 , 231 , 497 , 917 , 559 , 6515 , 13637 , 17721 , 4725 ,0 }; - static ulong[] dim3879KuoInit = { 1 , 3 , 1 , 15 , 17 , 19 , 93 , 65 , 281 , 775 , 613 , 2453 , 1969 , 2499 , 5373 , 28207 ,0 }; - static ulong[] dim3880KuoInit = { 1 , 1 , 5 , 11 , 9 , 37 , 103 , 211 , 357 , 409 , 457 , 1527 , 3289 , 14293 , 7681 , 58069 ,0 }; - static ulong[] dim3881KuoInit = { 1 , 3 , 5 , 9 , 1 , 29 , 83 , 1 , 35 , 655 , 491 , 1447 , 725 , 7807 , 13311 , 345 ,0 }; - static ulong[] dim3882KuoInit = { 1 , 3 , 1 , 7 , 19 , 59 , 103 , 243 , 157 , 209 , 399 , 1113 , 1595 , 15075 , 22475 , 42835 ,0 }; - static ulong[] dim3883KuoInit = { 1 , 3 , 5 , 5 , 27 , 53 , 69 , 73 , 413 , 443 , 559 , 427 , 2841 , 13107 , 8909 , 35265 ,0 }; - static ulong[] dim3884KuoInit = { 1 , 3 , 3 , 7 , 21 , 39 , 99 , 75 , 341 , 917 , 11 , 1247 , 247 , 14285 , 24531 , 58523 ,0 }; - static ulong[] dim3885KuoInit = { 1 , 1 , 7 , 9 , 29 , 1 , 55 , 143 , 363 , 527 , 103 , 3735 , 6373 , 7837 , 24451 , 36999 ,0 }; - static ulong[] dim3886KuoInit = { 1 , 1 , 3 , 3 , 3 , 51 , 71 , 103 , 173 , 397 , 1683 , 489 , 6515 , 2531 , 12517 , 63165 ,0 }; - static ulong[] dim3887KuoInit = { 1 , 3 , 7 , 3 , 27 , 15 , 31 , 63 , 323 , 903 , 1025 , 2761 , 1813 , 2839 , 2065 , 20013 ,0 }; - static ulong[] dim3888KuoInit = { 1 , 1 , 1 , 13 , 19 , 37 , 49 , 207 , 57 , 45 , 1517 , 2715 , 6315 , 10499 , 27195 , 56175 ,0 }; - static ulong[] dim3889KuoInit = { 1 , 3 , 5 , 11 , 13 , 47 , 91 , 81 , 459 , 801 , 1111 , 3023 , 5901 , 12735 , 14233 , 24383 ,0 }; - static ulong[] dim3890KuoInit = { 1 , 3 , 1 , 5 , 19 , 39 , 11 , 69 , 333 , 17 , 1339 , 2991 , 4411 , 2749 , 15423 , 13805 ,0 }; - static ulong[] dim3891KuoInit = { 1 , 3 , 5 , 9 , 19 , 3 , 109 , 45 , 461 , 103 , 811 , 3089 , 893 , 16121 , 1337 , 31929 ,0 }; - static ulong[] dim3892KuoInit = { 1 , 3 , 7 , 11 , 3 , 21 , 125 , 241 , 355 , 519 , 1551 , 3273 , 2413 , 3371 , 11435 , 2277 ,0 }; - static ulong[] dim3893KuoInit = { 1 , 1 , 5 , 9 , 7 , 21 , 93 , 79 , 25 , 265 , 1045 , 2011 , 4883 , 8631 , 22461 , 31117 ,0 }; - static ulong[] dim3894KuoInit = { 1 , 1 , 3 , 9 , 13 , 35 , 61 , 203 , 371 , 185 , 1445 , 2017 , 363 , 13603 , 23097 , 22617 ,0 }; - static ulong[] dim3895KuoInit = { 1 , 1 , 1 , 1 , 29 , 33 , 9 , 139 , 73 , 119 , 755 , 2117 , 3949 , 3403 , 30007 , 58147 ,0 }; - static ulong[] dim3896KuoInit = { 1 , 1 , 3 , 5 , 9 , 29 , 85 , 1 , 349 , 573 , 1191 , 133 , 235 , 1557 , 18147 , 5839 ,0 }; - static ulong[] dim3897KuoInit = { 1 , 3 , 3 , 5 , 15 , 45 , 5 , 95 , 359 , 223 , 37 , 547 , 3407 , 4927 , 32417 , 49205 ,0 }; - static ulong[] dim3898KuoInit = { 1 , 1 , 7 , 11 , 21 , 57 , 127 , 95 , 355 , 903 , 1555 , 9 , 1249 , 2463 , 7921 , 20633 ,0 }; - static ulong[] dim3899KuoInit = { 1 , 3 , 3 , 11 , 29 , 35 , 95 , 237 , 43 , 289 , 1547 , 3951 , 5489 , 2699 , 347 , 14405 ,0 }; - static ulong[] dim3900KuoInit = { 1 , 3 , 3 , 11 , 11 , 23 , 33 , 171 , 37 , 989 , 917 , 139 , 5497 , 617 , 25555 , 27031 ,0 }; - static ulong[] dim3901KuoInit = { 1 , 1 , 5 , 1 , 21 , 55 , 63 , 191 , 93 , 207 , 1799 , 2143 , 4147 , 6853 , 18129 , 18287 ,0 }; - static ulong[] dim3902KuoInit = { 1 , 3 , 7 , 15 , 23 , 39 , 59 , 131 , 51 , 113 , 941 , 2599 , 5593 , 11311 , 30561 , 22307 ,0 }; - static ulong[] dim3903KuoInit = { 1 , 3 , 7 , 5 , 21 , 49 , 93 , 5 , 399 , 173 , 1017 , 3551 , 937 , 13653 , 21411 , 56835 ,0 }; - static ulong[] dim3904KuoInit = { 1 , 3 , 1 , 1 , 15 , 47 , 57 , 19 , 93 , 931 , 1803 , 2947 , 1291 , 10979 , 22069 , 47485 ,0 }; - static ulong[] dim3905KuoInit = { 1 , 3 , 7 , 11 , 31 , 19 , 75 , 195 , 23 , 235 , 137 , 2521 , 4109 , 233 , 26961 , 19185 ,0 }; - static ulong[] dim3906KuoInit = { 1 , 3 , 3 , 15 , 9 , 17 , 87 , 239 , 233 , 939 , 1643 , 1189 , 7875 , 5199 , 26603 , 52223 ,0 }; - static ulong[] dim3907KuoInit = { 1 , 3 , 5 , 7 , 3 , 31 , 21 , 255 , 41 , 95 , 1267 , 1873 , 5535 , 8419 , 19791 , 14811 ,0 }; - static ulong[] dim3908KuoInit = { 1 , 1 , 7 , 15 , 7 , 51 , 27 , 35 , 17 , 1015 , 661 , 2679 , 1269 , 15729 , 17329 , 33555 ,0 }; - static ulong[] dim3909KuoInit = { 1 , 1 , 5 , 1 , 13 , 19 , 39 , 105 , 173 , 255 , 1873 , 1527 , 253 , 3517 , 19867 , 56765 ,0 }; - static ulong[] dim3910KuoInit = { 1 , 1 , 7 , 1 , 15 , 13 , 85 , 27 , 491 , 827 , 1151 , 3591 , 7819 , 10085 , 11307 , 45059 ,0 }; - static ulong[] dim3911KuoInit = { 1 , 3 , 5 , 15 , 21 , 17 , 23 , 207 , 223 , 721 , 655 , 243 , 4289 , 4973 , 29709 , 9203 ,0 }; - static ulong[] dim3912KuoInit = { 1 , 1 , 5 , 11 , 27 , 51 , 3 , 199 , 277 , 121 , 1637 , 3973 , 861 , 7215 , 32577 , 4391 ,0 }; - static ulong[] dim3913KuoInit = { 1 , 1 , 7 , 9 , 21 , 27 , 33 , 199 , 29 , 917 , 99 , 2755 , 821 , 16003 , 8325 , 55587 ,0 }; - static ulong[] dim3914KuoInit = { 1 , 1 , 7 , 1 , 19 , 17 , 61 , 39 , 377 , 739 , 13 , 3435 , 5081 , 10591 , 11957 , 30049 ,0 }; - static ulong[] dim3915KuoInit = { 1 , 1 , 5 , 1 , 25 , 13 , 117 , 5 , 479 , 579 , 907 , 3135 , 1011 , 3389 , 135 , 41711 ,0 }; - static ulong[] dim3916KuoInit = { 1 , 3 , 5 , 5 , 19 , 15 , 89 , 169 , 321 , 981 , 365 , 333 , 4913 , 9577 , 13835 , 23439 ,0 }; - static ulong[] dim3917KuoInit = { 1 , 1 , 5 , 11 , 31 , 27 , 103 , 25 , 129 , 207 , 259 , 2033 , 7931 , 8357 , 17451 , 60583 ,0 }; - static ulong[] dim3918KuoInit = { 1 , 1 , 7 , 11 , 15 , 47 , 59 , 151 , 291 , 669 , 663 , 111 , 4809 , 14179 , 22313 , 51969 ,0 }; - static ulong[] dim3919KuoInit = { 1 , 3 , 3 , 5 , 1 , 5 , 87 , 25 , 179 , 641 , 1133 , 629 , 2281 , 6213 , 14281 , 54147 ,0 }; - static ulong[] dim3920KuoInit = { 1 , 1 , 5 , 15 , 29 , 33 , 89 , 63 , 331 , 379 , 453 , 1903 , 7319 , 15063 , 31383 , 23099 ,0 }; - static ulong[] dim3921KuoInit = { 1 , 3 , 1 , 15 , 23 , 7 , 13 , 71 , 367 , 53 , 983 , 3615 , 5601 , 2569 , 18173 , 40563 ,0 }; - static ulong[] dim3922KuoInit = { 1 , 3 , 1 , 15 , 23 , 41 , 35 , 215 , 401 , 807 , 1809 , 3919 , 5651 , 1249 , 9699 , 14275 ,0 }; - static ulong[] dim3923KuoInit = { 1 , 1 , 3 , 1 , 15 , 55 , 7 , 235 , 171 , 911 , 1351 , 2863 , 5735 , 8577 , 7489 , 42047 ,0 }; - static ulong[] dim3924KuoInit = { 1 , 3 , 1 , 5 , 29 , 35 , 11 , 211 , 133 , 507 , 1127 , 2443 , 7895 , 10519 , 13035 , 26165 ,0 }; - static ulong[] dim3925KuoInit = { 1 , 1 , 1 , 9 , 21 , 39 , 107 , 55 , 235 , 409 , 39 , 1681 , 2699 , 3143 , 847 , 35635 ,0 }; - static ulong[] dim3926KuoInit = { 1 , 3 , 7 , 3 , 27 , 57 , 79 , 173 , 273 , 919 , 1917 , 4005 , 1299 , 14743 , 24093 , 64047 ,0 }; - static ulong[] dim3927KuoInit = { 1 , 1 , 7 , 11 , 13 , 53 , 45 , 195 , 39 , 379 , 1699 , 2401 , 7131 , 7205 , 24419 , 32161 ,0 }; - static ulong[] dim3928KuoInit = { 1 , 3 , 3 , 15 , 31 , 31 , 35 , 199 , 421 , 367 , 1517 , 1559 , 3627 , 10281 , 27963 , 31115 ,0 }; - static ulong[] dim3929KuoInit = { 1 , 1 , 5 , 15 , 5 , 59 , 89 , 195 , 263 , 853 , 1043 , 3699 , 2543 , 9893 , 727 , 62533 ,0 }; - static ulong[] dim3930KuoInit = { 1 , 1 , 7 , 5 , 29 , 49 , 101 , 219 , 135 , 643 , 321 , 83 , 1651 , 2347 , 1519 , 21683 ,0 }; - static ulong[] dim3931KuoInit = { 1 , 1 , 3 , 5 , 11 , 17 , 3 , 75 , 255 , 359 , 1231 , 2333 , 6745 , 2393 , 4213 , 7689 ,0 }; - static ulong[] dim3932KuoInit = { 1 , 1 , 5 , 13 , 23 , 27 , 53 , 51 , 307 , 87 , 1409 , 3555 , 8139 , 8597 , 27357 , 28489 ,0 }; - static ulong[] dim3933KuoInit = { 1 , 3 , 3 , 1 , 29 , 31 , 53 , 175 , 245 , 815 , 461 , 1681 , 2255 , 761 , 18061 , 13273 ,0 }; - static ulong[] dim3934KuoInit = { 1 , 3 , 3 , 7 , 21 , 41 , 81 , 243 , 9 , 973 , 1411 , 2327 , 4575 , 2659 , 22903 , 27605 ,0 }; - static ulong[] dim3935KuoInit = { 1 , 1 , 3 , 7 , 1 , 3 , 91 , 203 , 149 , 101 , 1745 , 1427 , 4107 , 11967 , 13545 , 19249 ,0 }; - static ulong[] dim3936KuoInit = { 1 , 3 , 1 , 1 , 3 , 13 , 47 , 13 , 291 , 813 , 97 , 2741 , 2847 , 2845 , 6437 , 1497 ,0 }; - static ulong[] dim3937KuoInit = { 1 , 3 , 3 , 1 , 15 , 7 , 121 , 173 , 333 , 977 , 357 , 3439 , 8023 , 8741 , 205 , 11447 ,0 }; - static ulong[] dim3938KuoInit = { 1 , 1 , 3 , 13 , 17 , 57 , 79 , 3 , 455 , 673 , 1877 , 2019 , 4809 , 10635 , 19927 , 38703 ,0 }; - static ulong[] dim3939KuoInit = { 1 , 1 , 1 , 15 , 17 , 23 , 65 , 157 , 265 , 177 , 697 , 3281 , 409 , 471 , 113 , 16349 ,0 }; - static ulong[] dim3940KuoInit = { 1 , 3 , 3 , 11 , 19 , 57 , 125 , 55 , 343 , 177 , 621 , 1827 , 983 , 2491 , 10389 , 49879 ,0 }; - static ulong[] dim3941KuoInit = { 1 , 1 , 5 , 1 , 23 , 21 , 125 , 13 , 155 , 459 , 1677 , 2585 , 6703 , 945 , 5341 , 54821 ,0 }; - static ulong[] dim3942KuoInit = { 1 , 3 , 3 , 1 , 1 , 59 , 75 , 137 , 261 , 563 , 1145 , 759 , 2363 , 12949 , 16677 , 43535 ,0 }; - static ulong[] dim3943KuoInit = { 1 , 3 , 1 , 1 , 31 , 13 , 29 , 59 , 263 , 879 , 49 , 1365 , 4977 , 6981 , 32683 , 25063 ,0 }; - static ulong[] dim3944KuoInit = { 1 , 3 , 3 , 11 , 27 , 63 , 41 , 101 , 353 , 611 , 349 , 1947 , 6473 , 3099 , 28855 , 27945 ,0 }; - static ulong[] dim3945KuoInit = { 1 , 1 , 5 , 3 , 13 , 49 , 59 , 5 , 401 , 679 , 2045 , 2267 , 5879 , 12809 , 23767 , 47855 ,0 }; - static ulong[] dim3946KuoInit = { 1 , 1 , 5 , 11 , 17 , 1 , 25 , 235 , 67 , 155 , 629 , 25 , 2565 , 12261 , 28847 , 19987 ,0 }; - static ulong[] dim3947KuoInit = { 1 , 3 , 1 , 1 , 23 , 39 , 117 , 147 , 155 , 797 , 1487 , 921 , 1205 , 9947 , 14603 , 21335 ,0 }; - static ulong[] dim3948KuoInit = { 1 , 1 , 3 , 13 , 21 , 45 , 49 , 175 , 447 , 303 , 531 , 2923 , 3887 , 16273 , 5121 , 38965 ,0 }; - static ulong[] dim3949KuoInit = { 1 , 1 , 7 , 11 , 5 , 21 , 53 , 201 , 1 , 207 , 181 , 1263 , 833 , 5435 , 28363 , 62913 ,0 }; - static ulong[] dim3950KuoInit = { 1 , 1 , 3 , 5 , 11 , 31 , 1 , 63 , 343 , 221 , 23 , 1315 , 7639 , 9983 , 9167 , 63489 ,0 }; - static ulong[] dim3951KuoInit = { 1 , 3 , 3 , 1 , 21 , 43 , 7 , 161 , 471 , 749 , 1547 , 1645 , 1557 , 9719 , 14017 , 43281 ,0 }; - static ulong[] dim3952KuoInit = { 1 , 1 , 1 , 7 , 3 , 23 , 49 , 29 , 259 , 367 , 1929 , 3925 , 4197 , 8353 , 28995 , 41225 ,0 }; - static ulong[] dim3953KuoInit = { 1 , 3 , 1 , 9 , 5 , 31 , 33 , 195 , 33 , 171 , 1021 , 127 , 5275 , 10751 , 12483 , 7097 ,0 }; - static ulong[] dim3954KuoInit = { 1 , 3 , 5 , 3 , 19 , 21 , 3 , 113 , 217 , 953 , 419 , 1689 , 8011 , 805 , 20691 , 39159 ,0 }; - static ulong[] dim3955KuoInit = { 1 , 1 , 5 , 1 , 27 , 35 , 83 , 173 , 299 , 687 , 493 , 3965 , 5963 , 1307 , 16379 , 34297 ,0 }; - static ulong[] dim3956KuoInit = { 1 , 3 , 7 , 3 , 11 , 63 , 103 , 199 , 207 , 25 , 1471 , 2047 , 7271 , 7735 , 4313 , 45205 ,0 }; - static ulong[] dim3957KuoInit = { 1 , 3 , 1 , 7 , 9 , 23 , 33 , 207 , 213 , 125 , 1871 , 2073 , 53 , 9953 , 1327 , 41943 ,0 }; - static ulong[] dim3958KuoInit = { 1 , 3 , 7 , 3 , 19 , 55 , 3 , 159 , 147 , 649 , 1161 , 2245 , 4303 , 9971 , 29633 , 56535 ,0 }; - static ulong[] dim3959KuoInit = { 1 , 3 , 3 , 5 , 1 , 1 , 57 , 101 , 265 , 859 , 137 , 763 , 6657 , 8659 , 21037 , 22757 ,0 }; - static ulong[] dim3960KuoInit = { 1 , 1 , 1 , 7 , 11 , 23 , 39 , 129 , 49 , 987 , 2013 , 4071 , 1289 , 6471 , 6231 , 23987 ,0 }; - static ulong[] dim3961KuoInit = { 1 , 3 , 7 , 3 , 29 , 7 , 87 , 253 , 111 , 55 , 1719 , 321 , 3579 , 4489 , 28323 , 35091 ,0 }; - static ulong[] dim3962KuoInit = { 1 , 1 , 5 , 13 , 17 , 1 , 39 , 73 , 455 , 31 , 1215 , 2683 , 6193 , 15725 , 2737 , 24927 ,0 }; - static ulong[] dim3963KuoInit = { 1 , 3 , 1 , 7 , 15 , 63 , 69 , 125 , 127 , 337 , 129 , 2667 , 4723 , 8489 , 6129 , 14973 ,0 }; - static ulong[] dim3964KuoInit = { 1 , 3 , 1 , 9 , 21 , 37 , 109 , 91 , 499 , 767 , 1095 , 2731 , 6129 , 2167 , 21311 , 43503 ,0 }; - static ulong[] dim3965KuoInit = { 1 , 3 , 7 , 7 , 29 , 11 , 87 , 101 , 19 , 699 , 1601 , 2341 , 3623 , 1799 , 2253 , 40705 ,0 }; - static ulong[] dim3966KuoInit = { 1 , 1 , 7 , 1 , 27 , 25 , 111 , 91 , 49 , 3 , 13 , 3851 , 3735 , 13387 , 4501 , 64303 ,0 }; - static ulong[] dim3967KuoInit = { 1 , 1 , 3 , 13 , 21 , 63 , 7 , 65 , 241 , 925 , 705 , 3745 , 827 , 7227 , 1869 , 60375 ,0 }; - static ulong[] dim3968KuoInit = { 1 , 3 , 1 , 7 , 31 , 45 , 5 , 51 , 45 , 595 , 1069 , 3139 , 5843 , 2581 , 22573 , 53297 ,0 }; - static ulong[] dim3969KuoInit = { 1 , 1 , 5 , 3 , 5 , 9 , 89 , 91 , 349 , 241 , 369 , 279 , 617 , 4479 , 12761 , 14473 ,0 }; - static ulong[] dim3970KuoInit = { 1 , 3 , 1 , 1 , 13 , 45 , 91 , 29 , 219 , 341 , 1831 , 1993 , 3661 , 1855 , 7243 , 3477 ,0 }; - static ulong[] dim3971KuoInit = { 1 , 3 , 3 , 13 , 15 , 17 , 27 , 123 , 223 , 127 , 111 , 2375 , 3919 , 7569 , 4419 , 24957 ,0 }; - static ulong[] dim3972KuoInit = { 1 , 3 , 7 , 1 , 17 , 1 , 49 , 111 , 103 , 67 , 75 , 3109 , 1783 , 13291 , 5409 , 33123 ,0 }; - static ulong[] dim3973KuoInit = { 1 , 3 , 5 , 3 , 1 , 51 , 107 , 89 , 233 , 51 , 745 , 2005 , 5485 , 7537 , 13353 , 34579 ,0 }; - static ulong[] dim3974KuoInit = { 1 , 1 , 7 , 3 , 9 , 3 , 25 , 95 , 413 , 461 , 1597 , 767 , 3183 , 10285 , 10579 , 26581 ,0 }; - static ulong[] dim3975KuoInit = { 1 , 1 , 5 , 7 , 25 , 3 , 27 , 93 , 433 , 59 , 701 , 1825 , 6375 , 6477 , 6743 , 42101 ,0 }; - static ulong[] dim3976KuoInit = { 1 , 3 , 1 , 3 , 19 , 45 , 95 , 207 , 267 , 623 , 1523 , 1541 , 3955 , 4681 , 2365 , 16661 ,0 }; - static ulong[] dim3977KuoInit = { 1 , 1 , 3 , 13 , 19 , 35 , 83 , 151 , 159 , 825 , 205 , 2215 , 4767 , 797 , 12821 , 14951 ,0 }; - static ulong[] dim3978KuoInit = { 1 , 1 , 5 , 13 , 15 , 5 , 99 , 141 , 21 , 537 , 657 , 2055 , 1571 , 12725 , 4227 , 21061 ,0 }; - static ulong[] dim3979KuoInit = { 1 , 1 , 1 , 13 , 1 , 39 , 85 , 229 , 9 , 721 , 1117 , 519 , 1763 , 13211 , 32533 , 41393 ,0 }; - static ulong[] dim3980KuoInit = { 1 , 1 , 3 , 15 , 23 , 11 , 125 , 59 , 439 , 887 , 1273 , 3707 , 7737 , 4115 , 7013 , 47453 ,0 }; - static ulong[] dim3981KuoInit = { 1 , 1 , 1 , 5 , 9 , 25 , 53 , 203 , 9 , 189 , 471 , 637 , 5983 , 1693 , 8425 , 52181 ,0 }; - static ulong[] dim3982KuoInit = { 1 , 1 , 1 , 1 , 29 , 61 , 33 , 87 , 153 , 625 , 539 , 3595 , 3161 , 3929 , 22825 , 50113 ,0 }; - static ulong[] dim3983KuoInit = { 1 , 3 , 7 , 7 , 1 , 31 , 105 , 169 , 475 , 631 , 1511 , 3687 , 5321 , 3859 , 19329 , 9571 ,0 }; - static ulong[] dim3984KuoInit = { 1 , 3 , 7 , 1 , 9 , 13 , 111 , 79 , 245 , 351 , 69 , 59 , 5561 , 4713 , 22789 , 14929 ,0 }; - static ulong[] dim3985KuoInit = { 1 , 1 , 3 , 1 , 1 , 55 , 87 , 147 , 37 , 587 , 479 , 3175 , 5437 , 12267 , 7057 , 57899 ,0 }; - static ulong[] dim3986KuoInit = { 1 , 1 , 5 , 11 , 15 , 55 , 87 , 53 , 359 , 491 , 343 , 621 , 1055 , 8697 , 28993 , 20473 ,0 }; - static ulong[] dim3987KuoInit = { 1 , 3 , 3 , 15 , 13 , 11 , 63 , 179 , 293 , 639 , 809 , 1365 , 7043 , 13269 , 5423 , 36465 ,0 }; - static ulong[] dim3988KuoInit = { 1 , 1 , 5 , 11 , 31 , 49 , 27 , 71 , 187 , 377 , 283 , 2407 , 2987 , 8565 , 15159 , 44501 ,0 }; - static ulong[] dim3989KuoInit = { 1 , 3 , 1 , 1 , 27 , 5 , 79 , 211 , 315 , 645 , 951 , 4025 , 1647 , 2893 , 23829 , 23941 ,0 }; - static ulong[] dim3990KuoInit = { 1 , 1 , 7 , 15 , 15 , 29 , 81 , 133 , 345 , 573 , 1605 , 2693 , 5293 , 13579 , 21793 , 30981 ,0 }; - static ulong[] dim3991KuoInit = { 1 , 3 , 7 , 5 , 31 , 19 , 109 , 141 , 389 , 473 , 1359 , 1695 , 6761 , 3701 , 27583 , 47907 ,0 }; - static ulong[] dim3992KuoInit = { 1 , 1 , 3 , 5 , 7 , 43 , 51 , 139 , 81 , 111 , 417 , 2627 , 2297 , 12493 , 24401 , 42525 ,0 }; - static ulong[] dim3993KuoInit = { 1 , 3 , 7 , 3 , 21 , 9 , 65 , 141 , 119 , 971 , 589 , 2635 , 6365 , 1925 , 15853 , 47123 ,0 }; - static ulong[] dim3994KuoInit = { 1 , 1 , 3 , 1 , 25 , 15 , 93 , 151 , 443 , 325 , 457 , 3779 , 7669 , 2063 , 20005 , 6513 ,0 }; - static ulong[] dim3995KuoInit = { 1 , 1 , 5 , 11 , 7 , 13 , 127 , 55 , 183 , 663 , 437 , 3475 , 6391 , 8423 , 8473 , 41971 ,0 }; - static ulong[] dim3996KuoInit = { 1 , 1 , 5 , 9 , 7 , 15 , 113 , 225 , 259 , 85 , 945 , 645 , 5129 , 3657 , 931 , 30429 ,0 }; - static ulong[] dim3997KuoInit = { 1 , 3 , 3 , 15 , 9 , 63 , 23 , 117 , 205 , 295 , 1325 , 1349 , 5521 , 9399 , 7907 , 26373 ,0 }; - static ulong[] dim3998KuoInit = { 1 , 3 , 7 , 5 , 17 , 23 , 47 , 75 , 97 , 35 , 1363 , 793 , 2811 , 3491 , 18173 , 8353 ,0 }; - static ulong[] dim3999KuoInit = { 1 , 3 , 3 , 11 , 25 , 27 , 107 , 9 , 331 , 1017 , 615 , 1123 , 1303 , 5705 , 14013 , 39207 ,0 }; - static ulong[] dim4000KuoInit = { 1 , 3 , 1 , 7 , 3 , 17 , 101 , 17 , 461 , 781 , 345 , 2687 , 5867 , 1367 , 17245 , 18929 ,0 }; - static ulong[] dim4001KuoInit = { 1 , 1 , 1 , 13 , 3 , 53 , 55 , 37 , 257 , 101 , 195 , 1193 , 5419 , 4243 , 6079 , 32461 ,0 }; - static ulong[] dim4002KuoInit = { 1 , 1 , 1 , 13 , 29 , 21 , 51 , 123 , 145 , 105 , 639 , 2389 , 6985 , 2519 , 12351 , 45859 ,0 }; - static ulong[] dim4003KuoInit = { 1 , 1 , 3 , 13 , 31 , 17 , 75 , 121 , 11 , 945 , 1917 , 601 , 3765 , 14215 , 19075 , 26317 ,0 }; - static ulong[] dim4004KuoInit = { 1 , 3 , 7 , 13 , 21 , 3 , 57 , 17 , 97 , 567 , 839 , 135 , 2441 , 4613 , 10511 , 21927 ,0 }; - static ulong[] dim4005KuoInit = { 1 , 3 , 5 , 1 , 21 , 27 , 1 , 109 , 381 , 241 , 1701 , 1255 , 1469 , 8415 , 18789 , 1769 ,0 }; - static ulong[] dim4006KuoInit = { 1 , 3 , 1 , 11 , 11 , 45 , 77 , 209 , 55 , 371 , 1323 , 2899 , 7387 , 10317 , 32695 , 52199 ,0 }; - static ulong[] dim4007KuoInit = { 1 , 3 , 5 , 9 , 15 , 59 , 45 , 97 , 369 , 247 , 1621 , 2037 , 4569 , 16043 , 2225 , 39055 ,0 }; - static ulong[] dim4008KuoInit = { 1 , 1 , 7 , 1 , 21 , 43 , 85 , 195 , 99 , 85 , 1759 , 547 , 4371 , 14467 , 17551 , 52185 ,0 }; - static ulong[] dim4009KuoInit = { 1 , 1 , 3 , 1 , 17 , 53 , 79 , 203 , 49 , 289 , 1547 , 1173 , 1445 , 11593 , 29927 , 63479 ,0 }; - static ulong[] dim4010KuoInit = { 1 , 3 , 3 , 5 , 3 , 61 , 31 , 71 , 321 , 923 , 1337 , 3465 , 3305 , 10841 , 31921 , 3057 ,0 }; - static ulong[] dim4011KuoInit = { 1 , 3 , 5 , 11 , 31 , 1 , 39 , 201 , 57 , 913 , 1953 , 193 , 4185 , 5895 , 27027 , 10889 ,0 }; - static ulong[] dim4012KuoInit = { 1 , 3 , 1 , 9 , 7 , 9 , 89 , 145 , 445 , 643 , 279 , 1983 , 491 , 11825 , 1857 , 11201 ,0 }; - static ulong[] dim4013KuoInit = { 1 , 3 , 1 , 5 , 9 , 39 , 21 , 245 , 403 , 393 , 779 , 1419 , 967 , 14309 , 6789 , 54477 ,0 }; - static ulong[] dim4014KuoInit = { 1 , 3 , 5 , 7 , 31 , 21 , 65 , 211 , 447 , 263 , 665 , 3311 , 405 , 1775 , 31121 , 54025 ,0 }; - static ulong[] dim4015KuoInit = { 1 , 3 , 5 , 11 , 13 , 9 , 95 , 243 , 139 , 733 , 813 , 3855 , 2731 , 11651 , 2175 , 9655 ,0 }; - static ulong[] dim4016KuoInit = { 1 , 1 , 1 , 1 , 21 , 5 , 5 , 241 , 415 , 241 , 1223 , 3237 , 2265 , 3761 , 26883 , 37875 ,0 }; - static ulong[] dim4017KuoInit = { 1 , 1 , 1 , 13 , 25 , 45 , 97 , 73 , 353 , 393 , 1217 , 563 , 5813 , 2791 , 16477 , 4401 ,0 }; - static ulong[] dim4018KuoInit = { 1 , 3 , 5 , 13 , 17 , 61 , 1 , 247 , 439 , 1013 , 501 , 881 , 353 , 4689 , 18733 , 46731 ,0 }; - static ulong[] dim4019KuoInit = { 1 , 3 , 1 , 11 , 11 , 29 , 87 , 53 , 461 , 751 , 1503 , 2851 , 2891 , 15231 , 1513 , 12573 ,0 }; - static ulong[] dim4020KuoInit = { 1 , 3 , 1 , 3 , 1 , 13 , 95 , 239 , 151 , 159 , 55 , 1203 , 1331 , 10429 , 19159 , 18431 ,0 }; - static ulong[] dim4021KuoInit = { 1 , 3 , 3 , 15 , 11 , 43 , 81 , 133 , 449 , 523 , 667 , 2759 , 6829 , 15129 , 19829 , 31745 ,0 }; - static ulong[] dim4022KuoInit = { 1 , 1 , 1 , 13 , 25 , 43 , 115 , 171 , 475 , 553 , 1615 , 1421 , 2363 , 13091 , 27505 , 21247 ,0 }; - static ulong[] dim4023KuoInit = { 1 , 3 , 5 , 13 , 1 , 23 , 15 , 25 , 205 , 797 , 1013 , 1903 , 1595 , 16373 , 29983 , 23009 ,0 }; - static ulong[] dim4024KuoInit = { 1 , 1 , 1 , 11 , 3 , 27 , 79 , 179 , 147 , 905 , 1893 , 2459 , 3063 , 7447 , 16293 , 14331 ,0 }; - static ulong[] dim4025KuoInit = { 1 , 3 , 7 , 1 , 19 , 49 , 41 , 19 , 97 , 559 , 1213 , 847 , 3715 , 13963 , 20273 , 25565 ,0 }; - static ulong[] dim4026KuoInit = { 1 , 3 , 7 , 3 , 27 , 21 , 75 , 1 , 157 , 715 , 41 , 2383 , 4609 , 9875 , 21509 , 57199 ,0 }; - static ulong[] dim4027KuoInit = { 1 , 1 , 1 , 9 , 5 , 51 , 93 , 115 , 495 , 687 , 1805 , 1369 , 1525 , 15841 , 8897 , 21023 ,0 }; - static ulong[] dim4028KuoInit = { 1 , 1 , 3 , 11 , 21 , 41 , 93 , 107 , 391 , 567 , 223 , 2331 , 6009 , 9405 , 13137 , 54727 ,0 }; - static ulong[] dim4029KuoInit = { 1 , 3 , 1 , 15 , 5 , 59 , 119 , 165 , 485 , 765 , 243 , 2589 , 4631 , 4045 , 26867 , 55329 ,0 }; - static ulong[] dim4030KuoInit = { 1 , 1 , 7 , 9 , 17 , 45 , 35 , 219 , 137 , 315 , 293 , 1137 , 6675 , 10693 , 17455 , 35603 ,0 }; - static ulong[] dim4031KuoInit = { 1 , 3 , 7 , 13 , 11 , 43 , 65 , 205 , 351 , 155 , 1371 , 3069 , 1345 , 859 , 21385 , 25923 ,0 }; - static ulong[] dim4032KuoInit = { 1 , 1 , 3 , 3 , 11 , 21 , 39 , 195 , 349 , 333 , 687 , 1155 , 1491 , 10453 , 17615 , 64801 ,0 }; - static ulong[] dim4033KuoInit = { 1 , 3 , 1 , 9 , 17 , 45 , 39 , 137 , 25 , 105 , 441 , 2437 , 7715 , 8501 , 3999 , 15913 ,0 }; - static ulong[] dim4034KuoInit = { 1 , 1 , 1 , 9 , 31 , 21 , 93 , 31 , 63 , 635 , 331 , 149 , 1683 , 6183 , 19333 , 34947 ,0 }; - static ulong[] dim4035KuoInit = { 1 , 3 , 3 , 5 , 23 , 11 , 15 , 239 , 365 , 983 , 389 , 945 , 1765 , 6417 , 4471 , 41431 ,0 }; - static ulong[] dim4036KuoInit = { 1 , 3 , 1 , 5 , 5 , 49 , 49 , 27 , 417 , 605 , 1495 , 4021 , 1775 , 3691 , 21803 , 60999 ,0 }; - static ulong[] dim4037KuoInit = { 1 , 3 , 3 , 5 , 23 , 21 , 33 , 205 , 481 , 105 , 359 , 1407 , 4007 , 35 , 10789 , 27721 ,0 }; - static ulong[] dim4038KuoInit = { 1 , 1 , 5 , 3 , 5 , 33 , 51 , 61 , 29 , 337 , 1523 , 955 , 4923 , 1977 , 16505 , 21249 ,0 }; - static ulong[] dim4039KuoInit = { 1 , 3 , 1 , 11 , 17 , 19 , 39 , 7 , 443 , 557 , 611 , 4037 , 5873 , 15161 , 449 , 41747 ,0 }; - static ulong[] dim4040KuoInit = { 1 , 1 , 7 , 11 , 5 , 53 , 91 , 227 , 217 , 689 , 7 , 775 , 8139 , 10997 , 29539 , 60185 ,0 }; - static ulong[] dim4041KuoInit = { 1 , 1 , 5 , 1 , 7 , 59 , 117 , 101 , 145 , 779 , 1359 , 3375 , 2493 , 13075 , 11475 , 49507 ,0 }; - static ulong[] dim4042KuoInit = { 1 , 1 , 1 , 3 , 13 , 31 , 39 , 219 , 181 , 203 , 19 , 659 , 533 , 2541 , 7285 , 29353 ,0 }; - static ulong[] dim4043KuoInit = { 1 , 3 , 3 , 1 , 29 , 33 , 1 , 125 , 283 , 61 , 303 , 1613 , 4309 , 1891 , 7107 , 25977 ,0 }; - static ulong[] dim4044KuoInit = { 1 , 3 , 5 , 9 , 21 , 59 , 41 , 63 , 123 , 715 , 893 , 3509 , 6785 , 11009 , 17749 , 18349 ,0 }; - static ulong[] dim4045KuoInit = { 1 , 3 , 1 , 1 , 25 , 23 , 15 , 1 , 147 , 709 , 957 , 1101 , 2733 , 14069 , 18905 , 12467 ,0 }; - static ulong[] dim4046KuoInit = { 1 , 3 , 3 , 13 , 9 , 63 , 109 , 39 , 123 , 919 , 427 , 435 , 5241 , 14169 , 31179 , 15887 ,0 }; - static ulong[] dim4047KuoInit = { 1 , 1 , 7 , 15 , 13 , 25 , 29 , 187 , 433 , 633 , 1203 , 113 , 4577 , 13349 , 18407 , 62825 ,0 }; - static ulong[] dim4048KuoInit = { 1 , 1 , 5 , 1 , 15 , 33 , 53 , 209 , 415 , 711 , 1543 , 1529 , 4991 , 9545 , 19655 , 40427 ,0 }; - static ulong[] dim4049KuoInit = { 1 , 1 , 5 , 5 , 23 , 59 , 27 , 23 , 7 , 841 , 1715 , 43 , 4987 , 2073 , 13765 , 36105 ,0 }; - static ulong[] dim4050KuoInit = { 1 , 3 , 3 , 15 , 31 , 5 , 51 , 183 , 319 , 443 , 621 , 349 , 2835 , 10847 , 19059 , 51689 ,0 }; - static ulong[] dim4051KuoInit = { 1 , 3 , 1 , 9 , 5 , 3 , 21 , 81 , 357 , 609 , 2019 , 2613 , 333 , 5699 , 2485 , 52105 ,0 }; - static ulong[] dim4052KuoInit = { 1 , 1 , 3 , 15 , 3 , 11 , 73 , 121 , 263 , 833 , 65 , 347 , 4821 , 4631 , 29929 , 42157 ,0 }; - static ulong[] dim4053KuoInit = { 1 , 1 , 7 , 3 , 1 , 63 , 7 , 191 , 47 , 405 , 43 , 1499 , 5539 , 12607 , 26095 , 20759 ,0 }; - static ulong[] dim4054KuoInit = { 1 , 3 , 3 , 5 , 15 , 21 , 109 , 3 , 15 , 57 , 1669 , 4033 , 5251 , 4465 , 28057 , 64943 ,0 }; - static ulong[] dim4055KuoInit = { 1 , 1 , 3 , 9 , 7 , 61 , 31 , 17 , 331 , 671 , 1955 , 1035 , 7183 , 6559 , 19299 , 10225 ,0 }; - static ulong[] dim4056KuoInit = { 1 , 1 , 5 , 11 , 31 , 15 , 97 , 3 , 361 , 541 , 323 , 1463 , 6867 , 12717 , 9593 , 15407 ,0 }; - static ulong[] dim4057KuoInit = { 1 , 1 , 1 , 5 , 29 , 39 , 71 , 27 , 305 , 589 , 1441 , 2349 , 185 , 447 , 24223 , 53591 ,0 }; - static ulong[] dim4058KuoInit = { 1 , 1 , 7 , 15 , 15 , 59 , 81 , 77 , 371 , 891 , 31 , 457 , 3073 , 8427 , 8225 , 53157 ,0 }; - static ulong[] dim4059KuoInit = { 1 , 3 , 3 , 11 , 23 , 61 , 71 , 85 , 39 , 77 , 1583 , 933 , 6147 , 2271 , 24761 , 15835 ,0 }; - static ulong[] dim4060KuoInit = { 1 , 3 , 7 , 11 , 25 , 55 , 41 , 131 , 275 , 603 , 43 , 761 , 5071 , 14149 , 4001 , 6545 ,0 }; - static ulong[] dim4061KuoInit = { 1 , 1 , 5 , 3 , 5 , 1 , 25 , 217 , 445 , 197 , 863 , 3557 , 585 , 13599 , 12329 , 17331 ,0 }; - static ulong[] dim4062KuoInit = { 1 , 3 , 3 , 13 , 9 , 21 , 21 , 89 , 121 , 1017 , 1559 , 83 , 5225 , 13247 , 12003 , 10049 ,0 }; - static ulong[] dim4063KuoInit = { 1 , 3 , 3 , 9 , 31 , 15 , 71 , 45 , 161 , 895 , 1431 , 1277 , 2547 , 1943 , 17631 , 59133 ,0 }; - static ulong[] dim4064KuoInit = { 1 , 1 , 1 , 9 , 11 , 17 , 29 , 157 , 355 , 89 , 401 , 983 , 8175 , 11687 , 20087 , 7541 ,0 }; - static ulong[] dim4065KuoInit = { 1 , 3 , 7 , 5 , 15 , 45 , 23 , 141 , 365 , 593 , 1137 , 873 , 2903 , 8861 , 25805 , 22601 ,0 }; - static ulong[] dim4066KuoInit = { 1 , 1 , 3 , 11 , 27 , 17 , 97 , 3 , 359 , 531 , 329 , 437 , 3483 , 8653 , 15953 , 48333 ,0 }; - static ulong[] dim4067KuoInit = { 1 , 3 , 5 , 3 , 9 , 43 , 79 , 223 , 149 , 177 , 1075 , 545 , 7235 , 4271 , 20153 , 65481 ,0 }; - static ulong[] dim4068KuoInit = { 1 , 3 , 1 , 13 , 5 , 55 , 29 , 51 , 497 , 677 , 167 , 391 , 1371 , 8753 , 23771 , 48167 ,0 }; - static ulong[] dim4069KuoInit = { 1 , 1 , 5 , 3 , 7 , 17 , 7 , 227 , 21 , 521 , 221 , 3529 , 5641 , 4139 , 14839 , 49863 ,0 }; - static ulong[] dim4070KuoInit = { 1 , 1 , 3 , 9 , 7 , 41 , 17 , 151 , 401 , 407 , 689 , 507 , 6683 , 12515 , 26895 , 60863 ,0 }; - static ulong[] dim4071KuoInit = { 1 , 1 , 3 , 7 , 3 , 53 , 27 , 185 , 119 , 891 , 2025 , 607 , 6961 , 4263 , 7795 , 34157 ,0 }; - static ulong[] dim4072KuoInit = { 1 , 1 , 3 , 3 , 25 , 19 , 15 , 131 , 323 , 27 , 1749 , 2429 , 2207 , 9207 , 18333 , 25857 ,0 }; - static ulong[] dim4073KuoInit = { 1 , 1 , 5 , 5 , 21 , 57 , 61 , 93 , 305 , 497 , 1465 , 3639 , 7695 , 3903 , 31201 , 45699 ,0 }; - static ulong[] dim4074KuoInit = { 1 , 1 , 5 , 11 , 25 , 35 , 93 , 55 , 415 , 397 , 1375 , 809 , 6205 , 9761 , 23129 , 28757 ,0 }; - static ulong[] dim4075KuoInit = { 1 , 3 , 5 , 9 , 13 , 21 , 1 , 167 , 65 , 689 , 525 , 2839 , 4069 , 10123 , 24403 , 4121 ,0 }; - static ulong[] dim4076KuoInit = { 1 , 1 , 3 , 13 , 11 , 21 , 67 , 159 , 131 , 579 , 1397 , 251 , 3933 , 14737 , 22047 , 4173 ,0 }; - static ulong[] dim4077KuoInit = { 1 , 1 , 3 , 13 , 9 , 47 , 71 , 81 , 141 , 607 , 1879 , 3057 , 6493 , 1177 , 27261 , 59313 ,0 }; - static ulong[] dim4078KuoInit = { 1 , 1 , 3 , 11 , 25 , 45 , 35 , 193 , 251 , 223 , 1725 , 1533 , 5799 , 12417 , 29765 , 50203 ,0 }; - static ulong[] dim4079KuoInit = { 1 , 3 , 1 , 13 , 27 , 1 , 41 , 171 , 293 , 65 , 607 , 2843 , 2955 , 8783 , 21249 , 41695 ,0 }; - static ulong[] dim4080KuoInit = { 1 , 3 , 1 , 3 , 3 , 57 , 39 , 31 , 507 , 687 , 2009 , 2881 , 4595 , 9275 , 9773 , 31489 ,0 }; - static ulong[] dim4081KuoInit = { 1 , 3 , 1 , 7 , 17 , 11 , 47 , 233 , 193 , 395 , 1879 , 1983 , 4811 , 1221 , 27279 , 52089 ,0 }; - static ulong[] dim4082KuoInit = { 1 , 3 , 1 , 1 , 13 , 57 , 51 , 253 , 381 , 779 , 897 , 2893 , 4373 , 6599 , 7533 , 30359 ,0 }; - static ulong[] dim4083KuoInit = { 1 , 3 , 3 , 3 , 5 , 35 , 1 , 117 , 81 , 35 , 2005 , 2133 , 4493 , 9773 , 24265 , 45945 ,0 }; - static ulong[] dim4084KuoInit = { 1 , 1 , 3 , 1 , 21 , 57 , 67 , 157 , 111 , 857 , 899 , 2081 , 2097 , 16005 , 20535 , 2955 ,0 }; - static ulong[] dim4085KuoInit = { 1 , 1 , 1 , 11 , 19 , 45 , 109 , 83 , 375 , 1003 , 79 , 3801 , 3433 , 4429 , 32385 , 31551 ,0 }; - static ulong[] dim4086KuoInit = { 1 , 1 , 3 , 3 , 1 , 15 , 115 , 47 , 511 , 533 , 1711 , 2433 , 3027 , 13511 , 23743 , 23805 ,0 }; - static ulong[] dim4087KuoInit = { 1 , 1 , 7 , 15 , 31 , 11 , 107 , 215 , 431 , 935 , 1033 , 213 , 7913 , 557 , 22063 , 7947 ,0 }; - static ulong[] dim4088KuoInit = { 1 , 3 , 3 , 1 , 23 , 25 , 109 , 183 , 445 , 477 , 1297 , 2269 , 3593 , 5657 , 995 , 19821 ,0 }; - static ulong[] dim4089KuoInit = { 1 , 3 , 3 , 9 , 5 , 19 , 93 , 137 , 155 , 5 , 1905 , 1551 , 6321 , 11213 , 6305 , 5063 ,0 }; - static ulong[] dim4090KuoInit = { 1 , 1 , 3 , 15 , 9 , 5 , 123 , 203 , 379 , 159 , 1871 , 2377 , 665 , 4877 , 17663 , 60371 ,0 }; - static ulong[] dim4091KuoInit = { 1 , 1 , 1 , 15 , 3 , 7 , 109 , 15 , 109 , 117 , 79 , 3061 , 667 , 6963 , 30565 , 25745 ,0 }; - static ulong[] dim4092KuoInit = { 1 , 3 , 5 , 1 , 15 , 7 , 105 , 139 , 29 , 923 , 1449 , 1349 , 2951 , 7443 , 10243 , 51739 ,0 }; - static ulong[] dim4093KuoInit = { 1 , 1 , 7 , 5 , 5 , 47 , 91 , 77 , 437 , 483 , 1309 , 1559 , 6491 , 13469 , 9461 , 40993 ,0 }; - static ulong[] dim4094KuoInit = { 1 , 1 , 7 , 5 , 5 , 35 , 57 , 139 , 207 , 267 , 707 , 1887 , 3447 , 3959 , 8169 , 14511 ,0 }; - static ulong[] dim4095KuoInit = { 1 , 1 , 7 , 15 , 23 , 9 , 57 , 183 , 437 , 595 , 1317 , 3847 , 2515 , 13415 , 26651 , 41885 ,0 }; - static ulong[] dim4096KuoInit = { 1 , 3 , 3 , 3 , 21 , 49 , 71 , 129 , 15 , 183 , 315 , 57 , 1739 , 15119 , 15293 , 8489 ,0 }; - static ulong[] dim4097KuoInit = { 1 , 3 , 1 , 3 , 7 , 63 , 91 , 241 , 355 , 921 , 1827 , 1 , 5713 , 3233 , 21901 , 48009 ,0 }; - static ulong[] dim4098KuoInit = { 1 , 3 , 7 , 13 , 31 , 9 , 103 , 209 , 289 , 575 , 1543 , 653 , 7189 , 1843 , 5205 , 27325 ,0 }; - static ulong[] dim4099KuoInit = { 1 , 1 , 7 , 7 , 15 , 63 , 7 , 71 , 95 , 861 , 857 , 701 , 6843 , 10609 , 11177 , 21043 ,0 }; - static ulong[] dim4100KuoInit = { 1 , 3 , 3 , 9 , 25 , 31 , 85 , 255 , 247 , 773 , 1503 , 2379 , 7231 , 6013 , 16193 , 33855 ,0 }; - static ulong[] dim4101KuoInit = { 1 , 1 , 3 , 11 , 5 , 27 , 125 , 159 , 381 , 665 , 1059 , 2527 , 1423 , 3055 , 8363 , 57053 ,0 }; - static ulong[] dim4102KuoInit = { 1 , 1 , 5 , 3 , 25 , 57 , 107 , 89 , 499 , 761 , 909 , 1487 , 1569 , 9353 , 27477 , 39373 ,0 }; - static ulong[] dim4103KuoInit = { 1 , 3 , 5 , 9 , 1 , 57 , 81 , 27 , 41 , 371 , 1111 , 2437 , 3669 , 6033 , 28601 , 38985 ,0 }; - static ulong[] dim4104KuoInit = { 1 , 3 , 5 , 5 , 25 , 63 , 85 , 171 , 187 , 387 , 1971 , 579 , 2779 , 7667 , 25423 , 61005 ,0 }; - static ulong[] dim4105KuoInit = { 1 , 1 , 5 , 1 , 25 , 37 , 87 , 93 , 387 , 95 , 65 , 3345 , 6581 , 13325 , 9683 , 25399 ,0 }; - static ulong[] dim4106KuoInit = { 1 , 3 , 5 , 11 , 9 , 33 , 81 , 69 , 483 , 79 , 123 , 3241 , 2599 , 7545 , 17775 , 34933 ,0 }; - static ulong[] dim4107KuoInit = { 1 , 1 , 7 , 1 , 9 , 41 , 27 , 191 , 385 , 439 , 347 , 1279 , 4491 , 8883 , 31599 , 27167 ,0 }; - static ulong[] dim4108KuoInit = { 1 , 3 , 5 , 13 , 1 , 57 , 51 , 81 , 161 , 15 , 7 , 3695 , 1777 , 14947 , 27853 , 22383 ,0 }; - static ulong[] dim4109KuoInit = { 1 , 1 , 5 , 5 , 15 , 21 , 79 , 159 , 85 , 677 , 401 , 665 , 3547 , 13659 , 18035 , 38181 ,0 }; - static ulong[] dim4110KuoInit = { 1 , 3 , 3 , 15 , 11 , 55 , 29 , 219 , 45 , 683 , 673 , 2653 , 6841 , 7809 , 8969 , 17773 ,0 }; - static ulong[] dim4111KuoInit = { 1 , 3 , 5 , 13 , 25 , 61 , 19 , 67 , 469 , 265 , 1835 , 2733 , 4537 , 8113 , 27089 , 59191 ,0 }; - static ulong[] dim4112KuoInit = { 1 , 1 , 5 , 11 , 9 , 37 , 99 , 31 , 229 , 635 , 1615 , 3073 , 2161 , 13917 , 22197 , 4331 ,0 }; - static ulong[] dim4113KuoInit = { 1 , 3 , 1 , 11 , 13 , 59 , 119 , 65 , 55 , 113 , 189 , 57 , 903 , 11119 , 3835 , 30549 ,0 }; - static ulong[] dim4114KuoInit = { 1 , 1 , 1 , 5 , 23 , 25 , 29 , 167 , 199 , 669 , 691 , 3047 , 7433 , 15043 , 22471 , 39473 ,0 }; - static ulong[] dim4115KuoInit = { 1 , 1 , 5 , 13 , 13 , 15 , 121 , 127 , 343 , 293 , 511 , 1873 , 4535 , 6395 , 10161 , 52113 ,0 }; - static ulong[] dim4116KuoInit = { 1 , 3 , 1 , 11 , 13 , 7 , 95 , 151 , 187 , 221 , 843 , 2433 , 5083 , 15319 , 5763 , 46801 ,0 }; - static ulong[] dim4117KuoInit = { 1 , 3 , 5 , 3 , 3 , 57 , 109 , 65 , 203 , 583 , 209 , 2395 , 5615 , 14949 , 10819 , 5109 ,0 }; - static ulong[] dim4118KuoInit = { 1 , 3 , 7 , 15 , 23 , 41 , 65 , 17 , 351 , 89 , 1451 , 219 , 5863 , 15197 , 22741 , 16599 ,0 }; - static ulong[] dim4119KuoInit = { 1 , 1 , 3 , 13 , 23 , 49 , 51 , 9 , 365 , 595 , 1619 , 933 , 2231 , 15219 , 105 , 1657 ,0 }; - static ulong[] dim4120KuoInit = { 1 , 3 , 5 , 7 , 27 , 33 , 39 , 243 , 257 , 299 , 479 , 1999 , 1781 , 9267 , 3631 , 21449 ,0 }; - static ulong[] dim4121KuoInit = { 1 , 3 , 1 , 3 , 13 , 1 , 83 , 9 , 373 , 99 , 1873 , 3959 , 1009 , 31 , 29329 , 1489 ,0 }; - static ulong[] dim4122KuoInit = { 1 , 1 , 7 , 3 , 15 , 21 , 99 , 25 , 265 , 461 , 467 , 2475 , 8149 , 5685 , 22679 , 9787 ,0 }; - static ulong[] dim4123KuoInit = { 1 , 1 , 3 , 1 , 5 , 43 , 109 , 55 , 451 , 11 , 1631 , 999 , 1181 , 3377 , 4807 , 14675 ,0 }; - static ulong[] dim4124KuoInit = { 1 , 3 , 7 , 11 , 5 , 43 , 27 , 253 , 73 , 697 , 81 , 3739 , 4267 , 3801 , 2913 , 33117 ,0 }; - static ulong[] dim4125KuoInit = { 1 , 3 , 1 , 5 , 11 , 55 , 97 , 3 , 3 , 949 , 155 , 3575 , 941 , 3727 , 4047 , 26071 ,0 }; - static ulong[] dim4126KuoInit = { 1 , 1 , 5 , 3 , 17 , 35 , 3 , 9 , 185 , 1 , 421 , 2831 , 957 , 4505 , 6421 , 16279 ,0 }; - static ulong[] dim4127KuoInit = { 1 , 1 , 3 , 9 , 21 , 43 , 115 , 183 , 231 , 13 , 1711 , 3403 , 5447 , 2761 , 27591 , 431 ,0 }; - static ulong[] dim4128KuoInit = { 1 , 3 , 3 , 15 , 1 , 25 , 111 , 157 , 429 , 981 , 1117 , 2767 , 3107 , 2203 , 15335 , 62597 ,0 }; - static ulong[] dim4129KuoInit = { 1 , 1 , 1 , 9 , 5 , 11 , 59 , 163 , 37 , 101 , 63 , 2829 , 5583 , 12695 , 21683 , 62563 ,0 }; - static ulong[] dim4130KuoInit = { 1 , 3 , 3 , 15 , 7 , 29 , 39 , 241 , 333 , 321 , 931 , 3811 , 1981 , 229 , 18877 , 6597 ,0 }; - static ulong[] dim4131KuoInit = { 1 , 3 , 3 , 13 , 31 , 3 , 83 , 21 , 253 , 117 , 757 , 2335 , 291 , 3723 , 24961 , 41985 ,0 }; - static ulong[] dim4132KuoInit = { 1 , 1 , 1 , 1 , 23 , 37 , 71 , 227 , 211 , 671 , 757 , 597 , 4015 , 7297 , 26275 , 46051 ,0 }; - static ulong[] dim4133KuoInit = { 1 , 3 , 3 , 11 , 9 , 15 , 23 , 143 , 207 , 235 , 1215 , 1401 , 7487 , 13397 , 30443 , 43735 ,0 }; - static ulong[] dim4134KuoInit = { 1 , 1 , 7 , 7 , 23 , 5 , 57 , 169 , 3 , 609 , 1077 , 109 , 6029 , 14891 , 6641 , 26525 ,0 }; - static ulong[] dim4135KuoInit = { 1 , 3 , 7 , 13 , 7 , 45 , 99 , 187 , 43 , 751 , 1189 , 1787 , 4903 , 10605 , 15799 , 61769 ,0 }; - static ulong[] dim4136KuoInit = { 1 , 3 , 1 , 5 , 31 , 51 , 95 , 127 , 149 , 557 , 1027 , 3377 , 1461 , 15217 , 16955 , 27339 ,0 }; - static ulong[] dim4137KuoInit = { 1 , 3 , 5 , 11 , 31 , 29 , 11 , 143 , 47 , 709 , 1413 , 343 , 5421 , 3567 , 5383 , 62347 ,0 }; - static ulong[] dim4138KuoInit = { 1 , 3 , 3 , 11 , 13 , 3 , 33 , 19 , 79 , 751 , 1979 , 785 , 6339 , 4133 , 31633 , 1963 ,0 }; - static ulong[] dim4139KuoInit = { 1 , 3 , 3 , 9 , 15 , 21 , 117 , 13 , 105 , 519 , 1575 , 3041 , 5465 , 7167 , 17443 , 15781 ,0 }; - static ulong[] dim4140KuoInit = { 1 , 1 , 1 , 7 , 29 , 25 , 51 , 237 , 11 , 431 , 1597 , 751 , 4115 , 12345 , 9451 , 1417 ,0 }; - static ulong[] dim4141KuoInit = { 1 , 3 , 5 , 13 , 1 , 43 , 61 , 141 , 279 , 541 , 149 , 3783 , 1503 , 7597 , 25469 , 21143 ,0 }; - static ulong[] dim4142KuoInit = { 1 , 1 , 3 , 13 , 23 , 13 , 21 , 53 , 49 , 491 , 135 , 3079 , 2593 , 10611 , 24467 , 18627 ,0 }; - static ulong[] dim4143KuoInit = { 1 , 3 , 3 , 5 , 19 , 31 , 59 , 139 , 137 , 839 , 799 , 1081 , 251 , 2685 , 15993 , 15909 ,0 }; - static ulong[] dim4144KuoInit = { 1 , 3 , 5 , 1 , 3 , 1 , 33 , 131 , 259 , 137 , 651 , 3879 , 3089 , 6957 , 24589 , 8945 ,0 }; - static ulong[] dim4145KuoInit = { 1 , 1 , 3 , 1 , 23 , 13 , 127 , 255 , 325 , 451 , 275 , 1425 , 3649 , 8149 , 28913 , 16481 ,0 }; - static ulong[] dim4146KuoInit = { 1 , 1 , 5 , 3 , 19 , 35 , 55 , 183 , 383 , 419 , 551 , 961 , 5413 , 3779 , 10935 , 30523 ,0 }; - static ulong[] dim4147KuoInit = { 1 , 1 , 7 , 3 , 19 , 35 , 125 , 165 , 21 , 23 , 1119 , 4061 , 8057 , 5129 , 6035 , 29907 ,0 }; - static ulong[] dim4148KuoInit = { 1 , 1 , 1 , 11 , 31 , 5 , 9 , 165 , 189 , 117 , 1371 , 3171 , 3723 , 9051 , 11071 , 1669 ,0 }; - static ulong[] dim4149KuoInit = { 1 , 1 , 1 , 7 , 23 , 37 , 61 , 241 , 253 , 79 , 241 , 2629 , 6791 , 2305 , 17085 , 17163 ,0 }; - static ulong[] dim4150KuoInit = { 1 , 1 , 7 , 11 , 25 , 49 , 109 , 139 , 271 , 325 , 1673 , 1827 , 319 , 10729 , 15739 , 19971 ,0 }; - static ulong[] dim4151KuoInit = { 1 , 3 , 3 , 9 , 15 , 3 , 21 , 153 , 229 , 781 , 2029 , 3169 , 2191 , 7861 , 26817 , 44695 ,0 }; - static ulong[] dim4152KuoInit = { 1 , 1 , 1 , 11 , 9 , 45 , 93 , 117 , 361 , 319 , 1747 , 2379 , 259 , 15451 , 2431 , 29633 ,0 }; - static ulong[] dim4153KuoInit = { 1 , 1 , 3 , 1 , 21 , 3 , 87 , 157 , 389 , 373 , 1235 , 1347 , 6573 , 3447 , 1569 , 42287 ,0 }; - static ulong[] dim4154KuoInit = { 1 , 3 , 5 , 1 , 3 , 35 , 27 , 49 , 283 , 281 , 733 , 1557 , 3589 , 4047 , 4589 , 981 ,0 }; - static ulong[] dim4155KuoInit = { 1 , 3 , 5 , 5 , 11 , 15 , 69 , 209 , 319 , 601 , 1559 , 35 , 185 , 8659 , 26943 , 10885 ,0 }; - static ulong[] dim4156KuoInit = { 1 , 3 , 3 , 15 , 15 , 25 , 105 , 241 , 153 , 813 , 481 , 2269 , 5677 , 11121 , 21781 , 29427 ,0 }; - static ulong[] dim4157KuoInit = { 1 , 1 , 1 , 13 , 1 , 41 , 123 , 235 , 487 , 339 , 1815 , 241 , 5673 , 9319 , 6031 , 3785 ,0 }; - static ulong[] dim4158KuoInit = { 1 , 1 , 3 , 9 , 3 , 15 , 111 , 207 , 281 , 7 , 1089 , 709 , 8001 , 14277 , 27351 , 21503 ,0 }; - static ulong[] dim4159KuoInit = { 1 , 3 , 1 , 11 , 29 , 11 , 69 , 111 , 471 , 549 , 1731 , 115 , 1067 , 8417 , 19377 , 18729 ,0 }; - static ulong[] dim4160KuoInit = { 1 , 1 , 7 , 1 , 29 , 11 , 31 , 251 , 437 , 217 , 1815 , 1229 , 5735 , 11813 , 20831 , 27237 ,0 }; - static ulong[] dim4161KuoInit = { 1 , 1 , 3 , 9 , 25 , 63 , 115 , 45 , 71 , 359 , 1313 , 543 , 1837 , 5359 , 13635 , 47057 ,0 }; - static ulong[] dim4162KuoInit = { 1 , 3 , 1 , 13 , 5 , 21 , 73 , 47 , 13 , 553 , 471 , 465 , 591 , 1943 , 12549 , 20245 ,0 }; - static ulong[] dim4163KuoInit = { 1 , 3 , 5 , 1 , 5 , 35 , 1 , 5 , 403 , 797 , 987 , 1227 , 2847 , 931 , 7417 , 7551 ,0 }; - static ulong[] dim4164KuoInit = { 1 , 3 , 3 , 11 , 15 , 13 , 7 , 201 , 145 , 475 , 1557 , 2871 , 3161 , 3489 , 7893 , 1745 ,0 }; - static ulong[] dim4165KuoInit = { 1 , 1 , 1 , 7 , 15 , 27 , 9 , 129 , 83 , 31 , 1351 , 647 , 6217 , 15201 , 21019 , 39925 ,0 }; - static ulong[] dim4166KuoInit = { 1 , 1 , 7 , 3 , 19 , 39 , 99 , 253 , 491 , 455 , 405 , 131 , 4755 , 8395 , 26647 , 65287 ,0 }; - static ulong[] dim4167KuoInit = { 1 , 3 , 5 , 13 , 13 , 13 , 15 , 49 , 397 , 237 , 1491 , 1881 , 4233 , 15801 , 25591 , 47061 ,0 }; - static ulong[] dim4168KuoInit = { 1 , 1 , 1 , 15 , 11 , 11 , 11 , 161 , 225 , 257 , 231 , 3303 , 5145 , 5217 , 21527 , 50231 ,0 }; - static ulong[] dim4169KuoInit = { 1 , 3 , 1 , 13 , 21 , 51 , 11 , 161 , 55 , 945 , 1835 , 1493 , 5069 , 9443 , 31181 , 2157 ,0 }; - static ulong[] dim4170KuoInit = { 1 , 3 , 1 , 15 , 29 , 45 , 75 , 141 , 475 , 43 , 219 , 2689 , 7579 , 523 , 27125 , 48615 ,0 }; - static ulong[] dim4171KuoInit = { 1 , 3 , 7 , 13 , 5 , 7 , 125 , 13 , 73 , 231 , 1397 , 295 , 3197 , 4023 , 2167 , 42101 ,0 }; - static ulong[] dim4172KuoInit = { 1 , 1 , 5 , 11 , 5 , 15 , 99 , 241 , 1 , 49 , 1635 , 2467 , 4939 , 9411 , 145 , 62117 ,0 }; - static ulong[] dim4173KuoInit = { 1 , 3 , 7 , 1 , 3 , 43 , 91 , 179 , 379 , 997 , 1839 , 3463 , 4967 , 12773 , 26273 , 52999 ,0 }; - static ulong[] dim4174KuoInit = { 1 , 1 , 1 , 5 , 7 , 45 , 127 , 213 , 63 , 93 , 1735 , 623 , 153 , 7039 , 4233 , 49775 ,0 }; - static ulong[] dim4175KuoInit = { 1 , 3 , 1 , 9 , 19 , 57 , 27 , 225 , 225 , 361 , 1349 , 829 , 1441 , 3557 , 7595 , 48405 ,0 }; - static ulong[] dim4176KuoInit = { 1 , 1 , 7 , 13 , 27 , 19 , 119 , 115 , 15 , 929 , 345 , 2199 , 8101 , 5787 , 3105 , 58313 ,0 }; - static ulong[] dim4177KuoInit = { 1 , 3 , 3 , 9 , 23 , 41 , 81 , 19 , 445 , 11 , 771 , 3767 , 6781 , 6969 , 28385 , 8473 ,0 }; - static ulong[] dim4178KuoInit = { 1 , 1 , 1 , 3 , 1 , 49 , 5 , 149 , 383 , 567 , 1663 , 1277 , 733 , 7651 , 4835 , 56429 ,0 }; - static ulong[] dim4179KuoInit = { 1 , 1 , 7 , 1 , 29 , 53 , 33 , 135 , 491 , 957 , 1215 , 687 , 1025 , 607 , 459 , 58433 ,0 }; - static ulong[] dim4180KuoInit = { 1 , 1 , 1 , 5 , 17 , 29 , 67 , 149 , 93 , 169 , 851 , 2311 , 4971 , 13403 , 15023 , 31645 ,0 }; - static ulong[] dim4181KuoInit = { 1 , 1 , 7 , 15 , 25 , 61 , 127 , 73 , 379 , 279 , 1407 , 285 , 5697 , 11141 , 28961 , 35551 ,0 }; - static ulong[] dim4182KuoInit = { 1 , 3 , 1 , 3 , 17 , 17 , 123 , 113 , 349 , 203 , 685 , 687 , 6957 , 13033 , 25147 , 61541 ,0 }; - static ulong[] dim4183KuoInit = { 1 , 3 , 7 , 3 , 29 , 47 , 67 , 161 , 163 , 427 , 241 , 2767 , 6855 , 4975 , 19081 , 4613 ,0 }; - static ulong[] dim4184KuoInit = { 1 , 1 , 1 , 3 , 7 , 51 , 81 , 57 , 107 , 171 , 1671 , 2373 , 341 , 4071 , 12877 , 55775 ,0 }; - static ulong[] dim4185KuoInit = { 1 , 1 , 7 , 15 , 29 , 63 , 111 , 255 , 189 , 33 , 1613 , 113 , 4347 , 549 , 9793 , 52611 ,0 }; - static ulong[] dim4186KuoInit = { 1 , 3 , 3 , 3 , 17 , 11 , 41 , 103 , 509 , 387 , 1341 , 663 , 611 , 12977 , 6435 , 40351 ,0 }; - static ulong[] dim4187KuoInit = { 1 , 1 , 1 , 5 , 5 , 39 , 13 , 229 , 473 , 159 , 585 , 2905 , 3467 , 8331 , 11539 , 57525 ,0 }; - static ulong[] dim4188KuoInit = { 1 , 3 , 1 , 7 , 13 , 25 , 87 , 115 , 199 , 611 , 635 , 2653 , 5559 , 7959 , 9545 , 14829 ,0 }; - static ulong[] dim4189KuoInit = { 1 , 1 , 3 , 7 , 5 , 57 , 53 , 155 , 57 , 301 , 263 , 1597 , 7805 , 8327 , 20457 , 6761 ,0 }; - static ulong[] dim4190KuoInit = { 1 , 3 , 3 , 5 , 17 , 39 , 105 , 177 , 317 , 681 , 679 , 691 , 7751 , 959 , 2989 , 31533 ,0 }; - static ulong[] dim4191KuoInit = { 1 , 1 , 3 , 1 , 23 , 15 , 65 , 223 , 379 , 523 , 1285 , 3175 , 1821 , 15655 , 25183 , 9415 ,0 }; - static ulong[] dim4192KuoInit = { 1 , 3 , 3 , 1 , 11 , 15 , 49 , 33 , 243 , 755 , 2027 , 3115 , 4665 , 12511 , 8653 , 35519 ,0 }; - static ulong[] dim4193KuoInit = { 1 , 3 , 3 , 7 , 5 , 45 , 45 , 183 , 409 , 107 , 1277 , 2975 , 2291 , 13839 , 18513 , 62993 ,0 }; - static ulong[] dim4194KuoInit = { 1 , 3 , 5 , 3 , 21 , 39 , 47 , 175 , 197 , 737 , 707 , 2769 , 171 , 12341 , 22361 , 16647 ,0 }; - static ulong[] dim4195KuoInit = { 1 , 3 , 3 , 1 , 3 , 35 , 127 , 23 , 349 , 477 , 1347 , 1939 , 1199 , 14441 , 9795 , 48051 ,0 }; - static ulong[] dim4196KuoInit = { 1 , 3 , 1 , 15 , 23 , 59 , 69 , 227 , 429 , 359 , 507 , 3615 , 2331 , 5741 , 23905 , 977 ,0 }; - static ulong[] dim4197KuoInit = { 1 , 3 , 3 , 1 , 7 , 5 , 111 , 17 , 425 , 697 , 1957 , 1771 , 3495 , 14373 , 8385 , 59295 ,0 }; - static ulong[] dim4198KuoInit = { 1 , 3 , 3 , 1 , 1 , 25 , 113 , 237 , 393 , 23 , 575 , 1117 , 665 , 3803 , 28291 , 60053 ,0 }; - static ulong[] dim4199KuoInit = { 1 , 1 , 7 , 7 , 5 , 33 , 43 , 121 , 109 , 201 , 877 , 3203 , 7967 , 11671 , 13397 , 9063 ,0 }; - static ulong[] dim4200KuoInit = { 1 , 1 , 1 , 9 , 31 , 57 , 31 , 75 , 429 , 471 , 683 , 3593 , 4277 , 10315 , 1913 , 54527 ,0 }; - static ulong[] dim4201KuoInit = { 1 , 1 , 1 , 3 , 29 , 17 , 69 , 75 , 251 , 595 , 1127 , 3015 , 5621 , 389 , 2245 , 43007 ,0 }; - static ulong[] dim4202KuoInit = { 1 , 1 , 1 , 5 , 7 , 41 , 127 , 57 , 321 , 971 , 1217 , 3731 , 4667 , 5919 , 29871 , 60487 ,0 }; - static ulong[] dim4203KuoInit = { 1 , 3 , 3 , 7 , 21 , 9 , 83 , 109 , 489 , 689 , 1601 , 2979 , 405 , 3131 , 19409 , 20739 ,0 }; - static ulong[] dim4204KuoInit = { 1 , 3 , 7 , 15 , 31 , 45 , 77 , 129 , 269 , 473 , 427 , 2751 , 6841 , 5957 , 25297 , 2301 ,0 }; - static ulong[] dim4205KuoInit = { 1 , 3 , 7 , 3 , 27 , 3 , 107 , 99 , 37 , 421 , 1853 , 2683 , 7305 , 467 , 32481 , 1085 ,0 }; - static ulong[] dim4206KuoInit = { 1 , 3 , 7 , 15 , 25 , 3 , 79 , 7 , 47 , 299 , 731 , 1321 , 1917 , 4315 , 17177 , 26499 ,0 }; - static ulong[] dim4207KuoInit = { 1 , 3 , 7 , 15 , 5 , 1 , 19 , 163 , 335 , 13 , 1855 , 3805 , 6707 , 2133 , 19671 , 53653 ,0 }; - static ulong[] dim4208KuoInit = { 1 , 1 , 3 , 7 , 3 , 5 , 77 , 69 , 31 , 959 , 1815 , 669 , 5965 , 2925 , 16285 , 42043 ,0 }; - static ulong[] dim4209KuoInit = { 1 , 3 , 5 , 15 , 25 , 5 , 35 , 175 , 55 , 765 , 597 , 703 , 3141 , 9825 , 29067 , 32817 ,0 }; - static ulong[] dim4210KuoInit = { 1 , 1 , 3 , 5 , 1 , 57 , 119 , 85 , 167 , 299 , 561 , 1045 , 4255 , 14663 , 27787 , 38785 ,0 }; - static ulong[] dim4211KuoInit = { 1 , 3 , 5 , 13 , 5 , 41 , 97 , 31 , 55 , 773 , 707 , 1083 , 359 , 15955 , 11203 , 50129 ,0 }; - static ulong[] dim4212KuoInit = { 1 , 3 , 7 , 5 , 9 , 35 , 101 , 231 , 23 , 301 , 683 , 3075 , 3221 , 7763 , 5585 , 35205 ,0 }; - static ulong[] dim4213KuoInit = { 1 , 3 , 1 , 13 , 23 , 29 , 83 , 227 , 111 , 307 , 837 , 465 , 5933 , 5265 , 4507 , 8719 ,0 }; - static ulong[] dim4214KuoInit = { 1 , 3 , 3 , 11 , 21 , 9 , 49 , 157 , 271 , 809 , 1467 , 1337 , 5893 , 13681 , 11261 , 56709 ,0 }; - static ulong[] dim4215KuoInit = { 1 , 3 , 7 , 1 , 29 , 33 , 89 , 39 , 131 , 339 , 359 , 3087 , 5167 , 5659 , 629 , 53865 ,0 }; - static ulong[] dim4216KuoInit = { 1 , 3 , 1 , 15 , 11 , 23 , 59 , 105 , 201 , 17 , 923 , 613 , 1665 , 8931 , 28457 , 63933 ,0 }; - static ulong[] dim4217KuoInit = { 1 , 1 , 5 , 13 , 17 , 33 , 67 , 73 , 367 , 263 , 1377 , 393 , 1561 , 3409 , 24453 , 61637 ,0 }; - static ulong[] dim4218KuoInit = { 1 , 1 , 5 , 1 , 29 , 9 , 31 , 51 , 485 , 775 , 741 , 1427 , 1857 , 10243 , 18101 , 29795 ,0 }; - static ulong[] dim4219KuoInit = { 1 , 1 , 1 , 5 , 5 , 39 , 29 , 137 , 171 , 837 , 347 , 1271 , 7365 , 3783 , 22731 , 18131 ,0 }; - static ulong[] dim4220KuoInit = { 1 , 1 , 5 , 11 , 1 , 45 , 89 , 175 , 11 , 859 , 355 , 1033 , 4767 , 11495 , 28761 , 11335 ,0 }; - static ulong[] dim4221KuoInit = { 1 , 1 , 7 , 1 , 25 , 7 , 85 , 229 , 243 , 259 , 383 , 1163 , 4833 , 11283 , 31573 , 30891 ,0 }; - static ulong[] dim4222KuoInit = { 1 , 3 , 7 , 5 , 11 , 41 , 111 , 87 , 203 , 177 , 1113 , 415 , 3613 , 1327 , 20103 , 61295 ,0 }; - static ulong[] dim4223KuoInit = { 1 , 3 , 3 , 9 , 15 , 53 , 25 , 245 , 335 , 31 , 1335 , 3339 , 2337 , 5719 , 3333 , 51325 ,0 }; - static ulong[] dim4224KuoInit = { 1 , 1 , 5 , 3 , 5 , 29 , 117 , 11 , 239 , 135 , 1501 , 2707 , 2775 , 2135 , 11477 , 44363 ,0 }; - static ulong[] dim4225KuoInit = { 1 , 1 , 3 , 1 , 23 , 33 , 3 , 219 , 301 , 643 , 1555 , 1 , 709 , 11 , 30649 , 19729 ,0 }; - static ulong[] dim4226KuoInit = { 1 , 1 , 5 , 7 , 31 , 9 , 45 , 185 , 203 , 741 , 1851 , 981 , 6437 , 1559 , 27245 , 36797 ,0 }; - static ulong[] dim4227KuoInit = { 1 , 1 , 3 , 7 , 1 , 41 , 11 , 141 , 53 , 533 , 927 , 2733 , 1049 , 16191 , 1241 , 49695 ,0 }; - static ulong[] dim4228KuoInit = { 1 , 3 , 7 , 1 , 31 , 21 , 105 , 181 , 487 , 1009 , 135 , 3649 , 6459 , 3397 , 1805 , 29793 ,0 }; - static ulong[] dim4229KuoInit = { 1 , 1 , 3 , 1 , 1 , 29 , 65 , 127 , 461 , 297 , 1151 , 2403 , 4875 , 343 , 24293 , 47203 ,0 }; - static ulong[] dim4230KuoInit = { 1 , 1 , 7 , 3 , 9 , 1 , 23 , 139 , 337 , 591 , 1557 , 1993 , 6927 , 5791 , 29199 , 2991 ,0 }; - static ulong[] dim4231KuoInit = { 1 , 1 , 7 , 9 , 7 , 1 , 81 , 129 , 469 , 215 , 695 , 2691 , 6165 , 14741 , 24339 , 58681 ,0 }; - static ulong[] dim4232KuoInit = { 1 , 3 , 5 , 13 , 29 , 59 , 113 , 143 , 15 , 399 , 1141 , 975 , 1285 , 12773 , 593 , 15481 ,0 }; - static ulong[] dim4233KuoInit = { 1 , 1 , 3 , 11 , 19 , 41 , 85 , 95 , 479 , 311 , 1721 , 1089 , 7199 , 15683 , 15909 , 40911 ,0 }; - static ulong[] dim4234KuoInit = { 1 , 1 , 1 , 3 , 25 , 55 , 23 , 195 , 413 , 623 , 411 , 279 , 3381 , 15313 , 19323 , 22829 ,0 }; - static ulong[] dim4235KuoInit = { 1 , 3 , 5 , 15 , 13 , 1 , 55 , 91 , 493 , 967 , 1571 , 2887 , 2791 , 1331 , 20565 , 61267 ,0 }; - static ulong[] dim4236KuoInit = { 1 , 3 , 5 , 1 , 1 , 17 , 127 , 253 , 249 , 559 , 739 , 2921 , 1315 , 13699 , 22501 , 9699 ,0 }; - static ulong[] dim4237KuoInit = { 1 , 3 , 7 , 13 , 19 , 53 , 31 , 103 , 307 , 821 , 661 , 591 , 5379 , 6401 , 10109 , 7325 ,0 }; - static ulong[] dim4238KuoInit = { 1 , 1 , 1 , 5 , 15 , 35 , 59 , 149 , 443 , 413 , 139 , 1851 , 3679 , 10721 , 31393 , 37329 ,0 }; - static ulong[] dim4239KuoInit = { 1 , 1 , 3 , 3 , 15 , 47 , 43 , 241 , 323 , 357 , 1567 , 3183 , 6869 , 4615 , 5617 , 28691 ,0 }; - static ulong[] dim4240KuoInit = { 1 , 3 , 3 , 1 , 25 , 11 , 55 , 55 , 105 , 277 , 1317 , 3631 , 5351 , 12747 , 1685 , 61239 ,0 }; - static ulong[] dim4241KuoInit = { 1 , 1 , 7 , 7 , 31 , 19 , 87 , 119 , 409 , 817 , 97 , 3549 , 3517 , 13901 , 11707 , 9501 ,0 }; - static ulong[] dim4242KuoInit = { 1 , 1 , 7 , 11 , 13 , 17 , 55 , 195 , 457 , 223 , 837 , 453 , 2953 , 2269 , 10149 , 48941 ,0 }; - static ulong[] dim4243KuoInit = { 1 , 3 , 3 , 13 , 5 , 31 , 63 , 117 , 419 , 329 , 1759 , 1167 , 7967 , 8975 , 11247 , 37159 ,0 }; - static ulong[] dim4244KuoInit = { 1 , 1 , 7 , 1 , 17 , 19 , 41 , 61 , 349 , 299 , 1449 , 2329 , 471 , 5119 , 29595 , 43335 ,0 }; - static ulong[] dim4245KuoInit = { 1 , 1 , 1 , 13 , 13 , 63 , 99 , 239 , 239 , 903 , 55 , 1347 , 969 , 9409 , 11603 , 28553 ,0 }; - static ulong[] dim4246KuoInit = { 1 , 3 , 1 , 7 , 25 , 59 , 23 , 241 , 361 , 1005 , 771 , 923 , 3315 , 4201 , 32695 , 54151 ,0 }; - static ulong[] dim4247KuoInit = { 1 , 3 , 3 , 5 , 19 , 1 , 113 , 103 , 469 , 591 , 319 , 2297 , 1033 , 9273 , 20529 , 58301 ,0 }; - static ulong[] dim4248KuoInit = { 1 , 3 , 7 , 11 , 23 , 1 , 77 , 161 , 321 , 855 , 1987 , 3735 , 4533 , 12061 , 19305 , 31679 ,0 }; - static ulong[] dim4249KuoInit = { 1 , 1 , 3 , 7 , 27 , 15 , 73 , 83 , 113 , 455 , 1855 , 2677 , 3243 , 14961 , 27147 , 21865 ,0 }; - static ulong[] dim4250KuoInit = { 1 , 3 , 5 , 11 , 15 , 33 , 61 , 87 , 237 , 775 , 1765 , 2783 , 3051 , 3617 , 32519 , 43991 ,0 }; - static ulong[] dim4251KuoInit = { 1 , 3 , 5 , 1 , 9 , 57 , 21 , 177 , 499 , 605 , 391 , 381 , 2027 , 9221 , 11213 , 10365 ,0 }; - static ulong[] dim4252KuoInit = { 1 , 1 , 7 , 5 , 31 , 29 , 57 , 159 , 413 , 321 , 245 , 2007 , 2817 , 5173 , 23227 , 19885 ,0 }; - static ulong[] dim4253KuoInit = { 1 , 1 , 7 , 7 , 29 , 43 , 113 , 173 , 505 , 449 , 409 , 981 , 2257 , 13261 , 85 , 6477 ,0 }; - static ulong[] dim4254KuoInit = { 1 , 1 , 5 , 13 , 9 , 51 , 1 , 127 , 65 , 963 , 1541 , 1321 , 7849 , 6481 , 1583 , 14737 ,0 }; - static ulong[] dim4255KuoInit = { 1 , 1 , 3 , 3 , 1 , 45 , 11 , 157 , 375 , 439 , 1673 , 271 , 3853 , 8795 , 23287 , 45365 ,0 }; - static ulong[] dim4256KuoInit = { 1 , 1 , 3 , 11 , 17 , 7 , 43 , 3 , 3 , 1005 , 523 , 2553 , 2457 , 259 , 20999 , 23611 ,0 }; - static ulong[] dim4257KuoInit = { 1 , 3 , 3 , 11 , 17 , 33 , 97 , 227 , 19 , 19 , 2039 , 3181 , 1393 , 1427 , 215 , 49915 ,0 }; - static ulong[] dim4258KuoInit = { 1 , 1 , 5 , 9 , 19 , 1 , 83 , 95 , 7 , 571 , 655 , 1281 , 3841 , 3925 , 24603 , 38413 ,0 }; - static ulong[] dim4259KuoInit = { 1 , 3 , 1 , 3 , 19 , 47 , 43 , 105 , 431 , 921 , 927 , 3713 , 8181 , 4177 , 9411 , 1481 ,0 }; - static ulong[] dim4260KuoInit = { 1 , 3 , 1 , 9 , 3 , 29 , 11 , 121 , 505 , 629 , 959 , 523 , 257 , 3089 , 15075 , 14087 ,0 }; - static ulong[] dim4261KuoInit = { 1 , 3 , 5 , 13 , 9 , 3 , 5 , 167 , 7 , 705 , 1737 , 583 , 2297 , 13073 , 27617 , 22083 ,0 }; - static ulong[] dim4262KuoInit = { 1 , 3 , 3 , 13 , 9 , 51 , 33 , 191 , 263 , 961 , 1019 , 2771 , 3487 , 7471 , 10939 , 23831 ,0 }; - static ulong[] dim4263KuoInit = { 1 , 1 , 5 , 5 , 25 , 19 , 75 , 115 , 221 , 93 , 1135 , 257 , 5597 , 14715 , 2385 , 46659 ,0 }; - static ulong[] dim4264KuoInit = { 1 , 1 , 3 , 5 , 31 , 13 , 63 , 231 , 463 , 501 , 1437 , 1777 , 6161 , 9885 , 10543 , 26031 ,0 }; - static ulong[] dim4265KuoInit = { 1 , 1 , 5 , 5 , 5 , 1 , 51 , 141 , 311 , 929 , 261 , 2959 , 59 , 4163 , 9855 , 54825 ,0 }; - static ulong[] dim4266KuoInit = { 1 , 3 , 1 , 9 , 1 , 57 , 31 , 21 , 395 , 211 , 89 , 3703 , 7565 , 2095 , 16273 , 52105 ,0 }; - static ulong[] dim4267KuoInit = { 1 , 1 , 3 , 11 , 25 , 57 , 27 , 163 , 459 , 849 , 955 , 2437 , 7115 , 8029 , 165 , 12007 ,0 }; - static ulong[] dim4268KuoInit = { 1 , 1 , 3 , 7 , 29 , 57 , 49 , 71 , 389 , 483 , 991 , 629 , 1517 , 2481 , 4881 , 39431 ,0 }; - static ulong[] dim4269KuoInit = { 1 , 3 , 5 , 1 , 1 , 11 , 29 , 81 , 323 , 581 , 1515 , 905 , 2813 , 12221 , 20181 , 9855 ,0 }; - static ulong[] dim4270KuoInit = { 1 , 3 , 1 , 5 , 27 , 3 , 41 , 65 , 369 , 925 , 1449 , 2711 , 3333 , 6263 , 10639 , 43537 ,0 }; - static ulong[] dim4271KuoInit = { 1 , 1 , 1 , 15 , 17 , 5 , 31 , 181 , 77 , 999 , 1011 , 2631 , 1761 , 10139 , 24369 , 39093 ,0 }; - static ulong[] dim4272KuoInit = { 1 , 3 , 3 , 11 , 11 , 23 , 65 , 165 , 41 , 591 , 1045 , 263 , 1707 , 4419 , 24005 , 47489 ,0 }; - static ulong[] dim4273KuoInit = { 1 , 1 , 7 , 13 , 11 , 43 , 65 , 161 , 229 , 35 , 637 , 3693 , 721 , 6863 , 12001 , 48067 ,0 }; - static ulong[] dim4274KuoInit = { 1 , 3 , 3 , 15 , 9 , 39 , 27 , 65 , 407 , 103 , 1437 , 3403 , 7355 , 2009 , 5979 , 37959 ,0 }; - static ulong[] dim4275KuoInit = { 1 , 1 , 5 , 5 , 13 , 23 , 65 , 145 , 395 , 603 , 1711 , 1529 , 6309 , 14631 , 4615 , 24459 ,0 }; - static ulong[] dim4276KuoInit = { 1 , 3 , 7 , 13 , 25 , 27 , 109 , 91 , 205 , 53 , 199 , 1215 , 4371 , 4821 , 11793 , 20719 ,0 }; - static ulong[] dim4277KuoInit = { 1 , 1 , 5 , 5 , 9 , 9 , 115 , 77 , 223 , 381 , 1035 , 1961 , 5285 , 12465 , 20531 , 51677 ,0 }; - static ulong[] dim4278KuoInit = { 1 , 3 , 3 , 9 , 13 , 31 , 123 , 123 , 325 , 719 , 1683 , 1253 , 4241 , 1443 , 7507 , 8253 ,0 }; - static ulong[] dim4279KuoInit = { 1 , 3 , 3 , 7 , 5 , 1 , 71 , 145 , 299 , 1021 , 677 , 1733 , 2791 , 12337 , 24395 , 64145 ,0 }; - static ulong[] dim4280KuoInit = { 1 , 1 , 7 , 11 , 21 , 31 , 113 , 79 , 1 , 29 , 1171 , 4081 , 7599 , 11661 , 4305 , 11383 ,0 }; - static ulong[] dim4281KuoInit = { 1 , 3 , 3 , 7 , 27 , 9 , 97 , 117 , 205 , 391 , 1571 , 1801 , 6085 , 15867 , 8987 , 29925 ,0 }; - static ulong[] dim4282KuoInit = { 1 , 3 , 3 , 3 , 5 , 35 , 27 , 143 , 503 , 533 , 1293 , 3737 , 3011 , 4457 , 18381 , 45513 ,0 }; - static ulong[] dim4283KuoInit = { 1 , 3 , 1 , 1 , 21 , 55 , 113 , 127 , 365 , 265 , 1211 , 841 , 807 , 3901 , 28993 , 28467 ,0 }; - static ulong[] dim4284KuoInit = { 1 , 1 , 1 , 7 , 21 , 17 , 101 , 217 , 413 , 273 , 53 , 2415 , 655 , 9939 , 11233 , 31631 ,0 }; - static ulong[] dim4285KuoInit = { 1 , 3 , 7 , 13 , 11 , 11 , 111 , 63 , 301 , 343 , 1757 , 2615 , 1683 , 11143 , 16405 , 16671 ,0 }; - static ulong[] dim4286KuoInit = { 1 , 1 , 5 , 15 , 17 , 19 , 83 , 195 , 475 , 189 , 1881 , 699 , 4853 , 7849 , 15063 , 5517 ,0 }; - static ulong[] dim4287KuoInit = { 1 , 1 , 5 , 5 , 27 , 25 , 19 , 239 , 153 , 725 , 709 , 3717 , 4801 , 1433 , 17789 , 34549 ,0 }; - static ulong[] dim4288KuoInit = { 1 , 3 , 1 , 9 , 9 , 5 , 47 , 215 , 123 , 161 , 583 , 917 , 5373 , 6839 , 20747 , 47179 ,0 }; - static ulong[] dim4289KuoInit = { 1 , 1 , 1 , 15 , 1 , 25 , 31 , 217 , 185 , 331 , 261 , 3877 , 2339 , 11557 , 22779 , 58509 ,0 }; - static ulong[] dim4290KuoInit = { 1 , 1 , 7 , 15 , 11 , 1 , 13 , 53 , 319 , 237 , 763 , 2411 , 7953 , 2117 , 24947 , 26643 ,0 }; - static ulong[] dim4291KuoInit = { 1 , 3 , 5 , 5 , 17 , 53 , 9 , 253 , 219 , 715 , 1923 , 823 , 1495 , 1975 , 3739 , 61343 ,0 }; - static ulong[] dim4292KuoInit = { 1 , 1 , 1 , 11 , 27 , 31 , 121 , 253 , 319 , 1001 , 125 , 567 , 215 , 6879 , 22581 , 38495 ,0 }; - static ulong[] dim4293KuoInit = { 1 , 1 , 1 , 11 , 23 , 17 , 83 , 65 , 279 , 725 , 1611 , 3911 , 509 , 1729 , 30025 , 10791 ,0 }; - static ulong[] dim4294KuoInit = { 1 , 3 , 1 , 11 , 19 , 17 , 67 , 101 , 129 , 607 , 557 , 3475 , 1445 , 8789 , 1815 , 18171 ,0 }; - static ulong[] dim4295KuoInit = { 1 , 3 , 7 , 7 , 23 , 57 , 69 , 127 , 147 , 743 , 549 , 3269 , 6193 , 12667 , 17081 , 6899 ,0 }; - static ulong[] dim4296KuoInit = { 1 , 3 , 1 , 9 , 9 , 29 , 83 , 175 , 389 , 289 , 367 , 1259 , 6631 , 15675 , 20975 , 54067 ,0 }; - static ulong[] dim4297KuoInit = { 1 , 1 , 7 , 1 , 27 , 11 , 31 , 209 , 159 , 615 , 1813 , 3235 , 7487 , 7103 , 5857 , 19435 ,0 }; - static ulong[] dim4298KuoInit = { 1 , 3 , 7 , 7 , 17 , 3 , 13 , 255 , 405 , 925 , 55 , 3539 , 3351 , 359 , 7633 , 38209 ,0 }; - static ulong[] dim4299KuoInit = { 1 , 3 , 5 , 5 , 5 , 51 , 123 , 61 , 485 , 785 , 1975 , 121 , 7841 , 7253 , 11769 , 7389 ,0 }; - static ulong[] dim4300KuoInit = { 1 , 1 , 1 , 9 , 1 , 3 , 51 , 169 , 163 , 875 , 35 , 1573 , 7931 , 13611 , 14697 , 64843 ,0 }; - static ulong[] dim4301KuoInit = { 1 , 1 , 5 , 13 , 11 , 35 , 47 , 135 , 475 , 893 , 39 , 2763 , 2671 , 7417 , 22905 , 60593 ,0 }; - static ulong[] dim4302KuoInit = { 1 , 3 , 5 , 3 , 27 , 27 , 85 , 219 , 341 , 509 , 1131 , 3607 , 1307 , 15265 , 28589 , 61113 ,0 }; - static ulong[] dim4303KuoInit = { 1 , 1 , 5 , 11 , 11 , 37 , 53 , 67 , 177 , 951 , 237 , 3865 , 2233 , 1405 , 28373 , 47767 ,0 }; - static ulong[] dim4304KuoInit = { 1 , 3 , 7 , 9 , 17 , 49 , 35 , 167 , 67 , 397 , 927 , 3305 , 2791 , 3609 , 3111 , 4555 ,0 }; - static ulong[] dim4305KuoInit = { 1 , 1 , 5 , 13 , 13 , 41 , 123 , 89 , 65 , 931 , 1959 , 1751 , 2765 , 8361 , 23653 , 45677 ,0 }; - static ulong[] dim4306KuoInit = { 1 , 1 , 1 , 3 , 25 , 37 , 91 , 225 , 181 , 275 , 1515 , 1355 , 7971 , 16081 , 13715 , 63963 ,0 }; - static ulong[] dim4307KuoInit = { 1 , 3 , 3 , 3 , 7 , 11 , 125 , 181 , 127 , 855 , 1277 , 3587 , 1351 , 4907 , 16985 , 357 ,0 }; - static ulong[] dim4308KuoInit = { 1 , 3 , 5 , 13 , 13 , 57 , 23 , 99 , 115 , 923 , 1395 , 3083 , 3939 , 475 , 12385 , 30113 ,0 }; - static ulong[] dim4309KuoInit = { 1 , 3 , 1 , 1 , 1 , 19 , 27 , 73 , 91 , 155 , 1145 , 467 , 5655 , 341 , 8875 , 61583 ,0 }; - static ulong[] dim4310KuoInit = { 1 , 3 , 1 , 1 , 17 , 33 , 113 , 219 , 99 , 817 , 1731 , 3379 , 5729 , 13615 , 19047 , 14143 ,0 }; - static ulong[] dim4311KuoInit = { 1 , 1 , 3 , 5 , 29 , 7 , 35 , 111 , 405 , 207 , 1811 , 3701 , 6101 , 7147 , 13825 , 52081 ,0 }; - static ulong[] dim4312KuoInit = { 1 , 1 , 7 , 9 , 19 , 23 , 89 , 95 , 503 , 311 , 1615 , 371 , 5853 , 4635 , 31911 , 65345 ,0 }; - static ulong[] dim4313KuoInit = { 1 , 1 , 7 , 5 , 17 , 41 , 49 , 143 , 445 , 855 , 1311 , 3961 , 3559 , 5483 , 31609 , 34147 ,0 }; - static ulong[] dim4314KuoInit = { 1 , 3 , 1 , 15 , 19 , 49 , 67 , 141 , 293 , 757 , 1905 , 2513 , 4405 , 41 , 1191 , 15259 ,0 }; - static ulong[] dim4315KuoInit = { 1 , 1 , 3 , 11 , 11 , 39 , 113 , 73 , 23 , 117 , 1315 , 725 , 7429 , 5483 , 26213 , 9331 ,0 }; - static ulong[] dim4316KuoInit = { 1 , 1 , 3 , 3 , 3 , 9 , 119 , 35 , 309 , 515 , 751 , 323 , 2521 , 12093 , 1123 , 43651 ,0 }; - static ulong[] dim4317KuoInit = { 1 , 1 , 3 , 3 , 29 , 43 , 49 , 53 , 481 , 269 , 915 , 1845 , 3341 , 511 , 23845 , 34623 ,0 }; - static ulong[] dim4318KuoInit = { 1 , 1 , 3 , 1 , 23 , 23 , 71 , 225 , 269 , 713 , 21 , 1051 , 7635 , 14245 , 3947 , 41757 ,0 }; - static ulong[] dim4319KuoInit = { 1 , 3 , 5 , 11 , 5 , 19 , 39 , 99 , 309 , 531 , 1645 , 787 , 6913 , 8159 , 1359 , 61973 ,0 }; - static ulong[] dim4320KuoInit = { 1 , 1 , 5 , 5 , 5 , 61 , 107 , 91 , 197 , 109 , 369 , 1053 , 1995 , 11551 , 4751 , 4981 ,0 }; - static ulong[] dim4321KuoInit = { 1 , 3 , 5 , 11 , 29 , 31 , 103 , 21 , 393 , 63 , 1465 , 2813 , 995 , 67 , 11997 , 34887 ,0 }; - static ulong[] dim4322KuoInit = { 1 , 3 , 1 , 7 , 9 , 49 , 111 , 135 , 83 , 79 , 353 , 2703 , 5027 , 10287 , 3753 , 60785 ,0 }; - static ulong[] dim4323KuoInit = { 1 , 1 , 7 , 15 , 17 , 17 , 51 , 69 , 465 , 25 , 1231 , 995 , 4643 , 3405 , 2237 , 54357 ,0 }; - static ulong[] dim4324KuoInit = { 1 , 1 , 1 , 1 , 5 , 39 , 31 , 187 , 459 , 197 , 905 , 279 , 2279 , 6585 , 7073 , 1897 ,0 }; - static ulong[] dim4325KuoInit = { 1 , 3 , 3 , 15 , 13 , 17 , 105 , 29 , 183 , 193 , 541 , 977 , 2247 , 5173 , 10511 , 59969 ,0 }; - static ulong[] dim4326KuoInit = { 1 , 1 , 1 , 15 , 3 , 11 , 89 , 1 , 411 , 503 , 267 , 2875 , 2585 , 9391 , 19395 , 30107 ,0 }; - static ulong[] dim4327KuoInit = { 1 , 1 , 7 , 9 , 7 , 19 , 45 , 251 , 143 , 729 , 1825 , 2571 , 6277 , 12759 , 5057 , 58455 ,0 }; - static ulong[] dim4328KuoInit = { 1 , 3 , 3 , 9 , 7 , 49 , 119 , 3 , 127 , 1015 , 937 , 2585 , 1229 , 16289 , 30087 , 45069 ,0 }; - static ulong[] dim4329KuoInit = { 1 , 3 , 5 , 13 , 15 , 39 , 39 , 13 , 315 , 533 , 143 , 2107 , 805 , 1487 , 8049 , 3643 ,0 }; - static ulong[] dim4330KuoInit = { 1 , 3 , 1 , 15 , 23 , 35 , 127 , 143 , 247 , 491 , 837 , 2263 , 1375 , 8283 , 24527 , 37967 ,0 }; - static ulong[] dim4331KuoInit = { 1 , 3 , 7 , 11 , 13 , 9 , 51 , 171 , 421 , 161 , 1777 , 3679 , 4821 , 10113 , 28459 , 55339 ,0 }; - static ulong[] dim4332KuoInit = { 1 , 3 , 3 , 1 , 25 , 61 , 53 , 145 , 81 , 509 , 2001 , 315 , 7775 , 7741 , 9239 , 10041 ,0 }; - static ulong[] dim4333KuoInit = { 1 , 1 , 3 , 3 , 11 , 31 , 21 , 91 , 425 , 415 , 523 , 3649 , 6595 , 9409 , 26631 , 8761 ,0 }; - static ulong[] dim4334KuoInit = { 1 , 3 , 7 , 7 , 13 , 1 , 51 , 53 , 123 , 125 , 1055 , 3951 , 6621 , 9207 , 25991 , 36435 ,0 }; - static ulong[] dim4335KuoInit = { 1 , 3 , 5 , 3 , 21 , 63 , 57 , 35 , 197 , 601 , 665 , 3223 , 817 , 3467 , 2667 , 2811 ,0 }; - static ulong[] dim4336KuoInit = { 1 , 3 , 1 , 11 , 7 , 29 , 51 , 29 , 383 , 969 , 557 , 795 , 7535 , 513 , 1329 , 57567 ,0 }; - static ulong[] dim4337KuoInit = { 1 , 1 , 1 , 13 , 11 , 59 , 85 , 183 , 163 , 445 , 1595 , 133 , 4277 , 3323 , 6833 , 50359 ,0 }; - static ulong[] dim4338KuoInit = { 1 , 3 , 1 , 13 , 9 , 11 , 65 , 209 , 509 , 65 , 1299 , 2225 , 7727 , 3851 , 17661 , 39777 ,0 }; - static ulong[] dim4339KuoInit = { 1 , 1 , 5 , 5 , 13 , 31 , 15 , 189 , 43 , 435 , 707 , 83 , 6713 , 13721 , 24013 , 47037 ,0 }; - static ulong[] dim4340KuoInit = { 1 , 1 , 1 , 9 , 29 , 49 , 101 , 205 , 7 , 539 , 1809 , 4095 , 7581 , 8187 , 16475 , 10923 ,0 }; - static ulong[] dim4341KuoInit = { 1 , 3 , 3 , 7 , 27 , 39 , 65 , 117 , 183 , 439 , 997 , 1389 , 2945 , 13303 , 10621 , 63085 ,0 }; - static ulong[] dim4342KuoInit = { 1 , 1 , 3 , 15 , 11 , 21 , 121 , 179 , 37 , 993 , 1299 , 2741 , 5797 , 10677 , 32519 , 45061 ,0 }; - static ulong[] dim4343KuoInit = { 1 , 1 , 7 , 1 , 23 , 47 , 107 , 131 , 145 , 679 , 1519 , 1147 , 887 , 2017 , 31191 , 4047 ,0 }; - static ulong[] dim4344KuoInit = { 1 , 1 , 3 , 11 , 1 , 51 , 1 , 105 , 245 , 269 , 1067 , 3551 , 6323 , 3729 , 16351 , 62965 ,0 }; - static ulong[] dim4345KuoInit = { 1 , 1 , 3 , 3 , 17 , 11 , 53 , 163 , 387 , 601 , 75 , 3219 , 5683 , 783 , 28143 , 20695 ,0 }; - static ulong[] dim4346KuoInit = { 1 , 1 , 5 , 15 , 21 , 21 , 33 , 171 , 73 , 157 , 49 , 3443 , 4057 , 8631 , 17555 , 8959 ,0 }; - static ulong[] dim4347KuoInit = { 1 , 1 , 5 , 9 , 3 , 35 , 13 , 211 , 181 , 425 , 1367 , 2217 , 5949 , 2741 , 8141 , 45769 ,0 }; - static ulong[] dim4348KuoInit = { 1 , 3 , 1 , 11 , 27 , 43 , 117 , 3 , 331 , 553 , 1847 , 2085 , 7125 , 10827 , 10583 , 60169 ,0 }; - static ulong[] dim4349KuoInit = { 1 , 1 , 3 , 1 , 15 , 35 , 81 , 15 , 259 , 89 , 1071 , 3807 , 3149 , 3309 , 17791 , 63869 ,0 }; - static ulong[] dim4350KuoInit = { 1 , 3 , 3 , 5 , 19 , 7 , 113 , 131 , 399 , 691 , 57 , 1837 , 3613 , 1755 , 521 , 64867 ,0 }; - static ulong[] dim4351KuoInit = { 1 , 3 , 1 , 11 , 25 , 53 , 11 , 241 , 187 , 237 , 1591 , 4059 , 6021 , 8451 , 14305 , 30965 ,0 }; - static ulong[] dim4352KuoInit = { 1 , 1 , 7 , 11 , 27 , 15 , 9 , 209 , 43 , 137 , 1351 , 2553 , 2841 , 6375 , 20291 , 2523 ,0 }; - static ulong[] dim4353KuoInit = { 1 , 3 , 3 , 5 , 27 , 37 , 83 , 61 , 365 , 739 , 69 , 725 , 6745 , 7353 , 2621 , 57747 ,0 }; - static ulong[] dim4354KuoInit = { 1 , 1 , 1 , 1 , 17 , 9 , 53 , 93 , 103 , 467 , 1543 , 2353 , 4901 , 13269 , 21635 , 63425 ,0 }; - static ulong[] dim4355KuoInit = { 1 , 3 , 1 , 9 , 15 , 19 , 61 , 127 , 423 , 749 , 809 , 515 , 7819 , 1209 , 22879 , 54069 ,0 }; - static ulong[] dim4356KuoInit = { 1 , 1 , 3 , 7 , 11 , 23 , 93 , 5 , 91 , 613 , 1529 , 2621 , 2689 , 2251 , 16049 , 60773 ,0 }; - static ulong[] dim4357KuoInit = { 1 , 1 , 5 , 5 , 15 , 27 , 57 , 177 , 477 , 585 , 249 , 3673 , 2651 , 10137 , 30395 , 57475 ,0 }; - static ulong[] dim4358KuoInit = { 1 , 3 , 1 , 5 , 31 , 39 , 25 , 185 , 233 , 915 , 1335 , 2889 , 1135 , 12515 , 27385 , 54785 ,0 }; - static ulong[] dim4359KuoInit = { 1 , 3 , 5 , 15 , 3 , 19 , 13 , 105 , 465 , 11 , 799 , 1699 , 6495 , 14307 , 18071 , 55405 ,0 }; - static ulong[] dim4360KuoInit = { 1 , 1 , 1 , 15 , 31 , 49 , 27 , 209 , 503 , 979 , 877 , 3121 , 3545 , 12875 , 799 , 44427 ,0 }; - static ulong[] dim4361KuoInit = { 1 , 1 , 5 , 3 , 23 , 17 , 113 , 109 , 301 , 587 , 1865 , 1623 , 453 , 14449 , 26901 , 34687 ,0 }; - static ulong[] dim4362KuoInit = { 1 , 3 , 7 , 11 , 1 , 29 , 25 , 113 , 147 , 53 , 27 , 2971 , 5663 , 12013 , 1281 , 65173 ,0 }; - static ulong[] dim4363KuoInit = { 1 , 3 , 1 , 11 , 13 , 47 , 13 , 209 , 339 , 393 , 1389 , 2205 , 537 , 10911 , 20093 , 61499 ,0 }; - static ulong[] dim4364KuoInit = { 1 , 1 , 7 , 9 , 21 , 45 , 75 , 43 , 425 , 89 , 1319 , 2245 , 6519 , 12819 , 30653 , 18927 ,0 }; - static ulong[] dim4365KuoInit = { 1 , 1 , 3 , 11 , 1 , 31 , 55 , 29 , 337 , 733 , 1303 , 1721 , 7163 , 13807 , 5865 , 20009 ,0 }; - static ulong[] dim4366KuoInit = { 1 , 1 , 3 , 15 , 1 , 5 , 101 , 211 , 263 , 865 , 59 , 2473 , 3857 , 9909 , 21353 , 8807 ,0 }; - static ulong[] dim4367KuoInit = { 1 , 1 , 3 , 9 , 25 , 29 , 5 , 157 , 17 , 985 , 369 , 1903 , 2431 , 15395 , 20245 , 51253 ,0 }; - static ulong[] dim4368KuoInit = { 1 , 3 , 3 , 11 , 7 , 31 , 45 , 209 , 287 , 13 , 591 , 3907 , 7501 , 10003 , 21815 , 43213 ,0 }; - static ulong[] dim4369KuoInit = { 1 , 3 , 7 , 5 , 27 , 25 , 73 , 191 , 361 , 731 , 757 , 1907 , 9 , 16357 , 4241 , 40187 ,0 }; - static ulong[] dim4370KuoInit = { 1 , 1 , 7 , 1 , 5 , 55 , 121 , 89 , 39 , 531 , 493 , 3453 , 5709 , 8215 , 21831 , 5661 ,0 }; - static ulong[] dim4371KuoInit = { 1 , 3 , 7 , 11 , 27 , 59 , 49 , 251 , 17 , 223 , 875 , 1133 , 3161 , 10273 , 26463 , 45987 ,0 }; - static ulong[] dim4372KuoInit = { 1 , 3 , 5 , 9 , 17 , 39 , 117 , 153 , 243 , 449 , 1261 , 3917 , 1359 , 4525 , 22119 , 1781 ,0 }; - static ulong[] dim4373KuoInit = { 1 , 1 , 3 , 7 , 15 , 15 , 19 , 151 , 411 , 693 , 445 , 2525 , 2867 , 12809 , 1487 , 7019 ,0 }; - static ulong[] dim4374KuoInit = { 1 , 1 , 7 , 7 , 15 , 57 , 61 , 243 , 427 , 529 , 1051 , 3391 , 6259 , 8791 , 3405 , 54757 ,0 }; - static ulong[] dim4375KuoInit = { 1 , 3 , 1 , 5 , 13 , 41 , 105 , 73 , 485 , 881 , 1943 , 1419 , 5761 , 11807 , 16497 , 12763 ,0 }; - static ulong[] dim4376KuoInit = { 1 , 3 , 3 , 15 , 7 , 47 , 61 , 99 , 473 , 487 , 1973 , 1675 , 3163 , 4033 , 5323 , 31313 ,0 }; - static ulong[] dim4377KuoInit = { 1 , 1 , 1 , 3 , 21 , 33 , 23 , 129 , 469 , 743 , 769 , 1561 , 235 , 13713 , 6827 , 61273 ,0 }; - static ulong[] dim4378KuoInit = { 1 , 3 , 1 , 13 , 11 , 19 , 59 , 37 , 431 , 5 , 1333 , 2381 , 5707 , 2499 , 9339 , 35803 ,0 }; - static ulong[] dim4379KuoInit = { 1 , 1 , 5 , 1 , 17 , 11 , 77 , 137 , 111 , 567 , 1469 , 543 , 5633 , 1927 , 26491 , 37955 ,0 }; - static ulong[] dim4380KuoInit = { 1 , 3 , 5 , 15 , 21 , 9 , 57 , 35 , 291 , 371 , 65 , 2891 , 841 , 11859 , 16685 , 5641 ,0 }; - static ulong[] dim4381KuoInit = { 1 , 3 , 7 , 1 , 3 , 35 , 121 , 153 , 353 , 633 , 995 , 121 , 7317 , 273 , 23329 , 32591 ,0 }; - static ulong[] dim4382KuoInit = { 1 , 3 , 5 , 1 , 25 , 19 , 35 , 221 , 295 , 543 , 1269 , 3901 , 2109 , 4463 , 4275 , 89 ,0 }; - static ulong[] dim4383KuoInit = { 1 , 3 , 7 , 13 , 1 , 13 , 85 , 97 , 155 , 731 , 1017 , 3713 , 1613 , 805 , 8927 , 32165 ,0 }; - static ulong[] dim4384KuoInit = { 1 , 3 , 3 , 13 , 17 , 1 , 21 , 235 , 103 , 875 , 1849 , 2669 , 3193 , 9053 , 16123 , 29481 ,0 }; - static ulong[] dim4385KuoInit = { 1 , 3 , 7 , 9 , 23 , 21 , 37 , 251 , 441 , 437 , 629 , 1009 , 5663 , 14447 , 23437 , 32521 ,0 }; - static ulong[] dim4386KuoInit = { 1 , 1 , 7 , 5 , 9 , 5 , 7 , 123 , 483 , 433 , 867 , 149 , 1975 , 5497 , 7887 , 25779 ,0 }; - static ulong[] dim4387KuoInit = { 1 , 3 , 3 , 3 , 31 , 17 , 81 , 167 , 399 , 1 , 1777 , 833 , 8035 , 8597 , 28371 , 19293 ,0 }; - static ulong[] dim4388KuoInit = { 1 , 3 , 3 , 11 , 9 , 45 , 125 , 121 , 147 , 613 , 599 , 111 , 7583 , 3189 , 13185 , 35603 ,0 }; - static ulong[] dim4389KuoInit = { 1 , 1 , 1 , 15 , 31 , 51 , 9 , 191 , 55 , 837 , 1773 , 2781 , 6351 , 1909 , 5407 , 7533 ,0 }; - static ulong[] dim4390KuoInit = { 1 , 1 , 3 , 13 , 13 , 35 , 71 , 25 , 465 , 377 , 613 , 2487 , 6297 , 8299 , 27541 , 17779 ,0 }; - static ulong[] dim4391KuoInit = { 1 , 1 , 3 , 15 , 21 , 59 , 43 , 115 , 369 , 315 , 315 , 3451 , 5785 , 6353 , 22609 , 42793 ,0 }; - static ulong[] dim4392KuoInit = { 1 , 1 , 5 , 15 , 13 , 3 , 127 , 87 , 211 , 981 , 629 , 2683 , 5683 , 15475 , 20431 , 32977 ,0 }; - static ulong[] dim4393KuoInit = { 1 , 1 , 3 , 7 , 31 , 3 , 23 , 7 , 117 , 1001 , 431 , 2215 , 5817 , 16283 , 12781 , 63883 ,0 }; - static ulong[] dim4394KuoInit = { 1 , 1 , 3 , 1 , 27 , 11 , 43 , 195 , 329 , 375 , 655 , 3815 , 5699 , 11259 , 6733 , 26015 ,0 }; - static ulong[] dim4395KuoInit = { 1 , 3 , 3 , 11 , 19 , 3 , 63 , 187 , 47 , 891 , 1463 , 3259 , 1479 , 15109 , 25387 , 43753 ,0 }; - static ulong[] dim4396KuoInit = { 1 , 1 , 5 , 11 , 31 , 43 , 59 , 149 , 205 , 447 , 1787 , 627 , 6227 , 9951 , 19069 , 50193 ,0 }; - static ulong[] dim4397KuoInit = { 1 , 3 , 3 , 7 , 7 , 1 , 41 , 33 , 395 , 139 , 689 , 1597 , 529 , 6861 , 2025 , 19569 ,0 }; - static ulong[] dim4398KuoInit = { 1 , 1 , 1 , 7 , 17 , 63 , 17 , 73 , 459 , 1007 , 1563 , 879 , 1441 , 525 , 32679 , 56409 ,0 }; - static ulong[] dim4399KuoInit = { 1 , 3 , 3 , 13 , 3 , 5 , 23 , 239 , 7 , 807 , 1999 , 1427 , 6647 , 2249 , 17687 , 5519 ,0 }; - static ulong[] dim4400KuoInit = { 1 , 3 , 5 , 1 , 7 , 15 , 7 , 243 , 347 , 415 , 1519 , 2267 , 3119 , 3145 , 27799 , 24453 ,0 }; - static ulong[] dim4401KuoInit = { 1 , 3 , 3 , 3 , 5 , 1 , 93 , 215 , 475 , 209 , 361 , 951 , 147 , 1401 , 6851 , 59257 ,0 }; - static ulong[] dim4402KuoInit = { 1 , 1 , 7 , 3 , 29 , 39 , 67 , 195 , 287 , 587 , 315 , 1747 , 7169 , 11967 , 4893 , 797 ,0 }; - static ulong[] dim4403KuoInit = { 1 , 3 , 5 , 5 , 13 , 49 , 47 , 97 , 105 , 203 , 1237 , 805 , 3595 , 9225 , 23105 , 52679 ,0 }; - static ulong[] dim4404KuoInit = { 1 , 1 , 5 , 1 , 23 , 41 , 39 , 85 , 7 , 237 , 1545 , 2591 , 1771 , 2291 , 20185 , 46995 ,0 }; - static ulong[] dim4405KuoInit = { 1 , 1 , 1 , 3 , 15 , 5 , 43 , 211 , 109 , 599 , 77 , 703 , 5749 , 15909 , 12619 , 41635 ,0 }; - static ulong[] dim4406KuoInit = { 1 , 3 , 1 , 9 , 19 , 9 , 49 , 211 , 149 , 883 , 1617 , 497 , 7689 , 4253 , 18737 , 25293 ,0 }; - static ulong[] dim4407KuoInit = { 1 , 1 , 7 , 11 , 25 , 3 , 57 , 83 , 181 , 801 , 1515 , 3821 , 5287 , 15243 , 2347 , 42333 ,0 }; - static ulong[] dim4408KuoInit = { 1 , 3 , 7 , 15 , 15 , 25 , 107 , 79 , 249 , 721 , 1237 , 1587 , 3469 , 10319 , 6421 , 59103 ,0 }; - static ulong[] dim4409KuoInit = { 1 , 1 , 3 , 3 , 17 , 21 , 81 , 35 , 173 , 101 , 1879 , 3301 , 4409 , 8563 , 27981 , 64269 ,0 }; - static ulong[] dim4410KuoInit = { 1 , 1 , 7 , 3 , 29 , 17 , 103 , 17 , 443 , 821 , 1133 , 73 , 2587 , 16119 , 17385 , 2293 ,0 }; - static ulong[] dim4411KuoInit = { 1 , 3 , 7 , 13 , 9 , 3 , 41 , 125 , 149 , 403 , 537 , 695 , 3885 , 15769 , 11315 , 53979 ,0 }; - static ulong[] dim4412KuoInit = { 1 , 3 , 5 , 7 , 11 , 47 , 57 , 105 , 433 , 1009 , 1749 , 2453 , 2083 , 1543 , 25941 , 58037 ,0 }; - static ulong[] dim4413KuoInit = { 1 , 1 , 1 , 3 , 19 , 63 , 45 , 251 , 265 , 591 , 1235 , 1349 , 6069 , 14139 , 4299 , 32719 ,0 }; - static ulong[] dim4414KuoInit = { 1 , 3 , 5 , 9 , 1 , 49 , 125 , 217 , 247 , 915 , 1289 , 3589 , 7 , 5285 , 32443 , 56439 ,0 }; - static ulong[] dim4415KuoInit = { 1 , 3 , 5 , 3 , 31 , 31 , 67 , 55 , 203 , 487 , 983 , 1841 , 1587 , 14881 , 29187 , 59293 ,0 }; - static ulong[] dim4416KuoInit = { 1 , 1 , 1 , 13 , 1 , 59 , 121 , 57 , 99 , 857 , 1085 , 3505 , 3615 , 13725 , 10363 , 16841 ,0 }; - static ulong[] dim4417KuoInit = { 1 , 1 , 5 , 3 , 19 , 55 , 43 , 95 , 141 , 217 , 1087 , 1129 , 3417 , 515 , 23815 , 13135 ,0 }; - static ulong[] dim4418KuoInit = { 1 , 1 , 1 , 15 , 9 , 63 , 5 , 139 , 327 , 743 , 1321 , 4055 , 4337 , 15115 , 8635 , 53571 ,0 }; - static ulong[] dim4419KuoInit = { 1 , 1 , 5 , 11 , 31 , 47 , 105 , 91 , 493 , 77 , 1767 , 1647 , 4287 , 5455 , 1875 , 6669 ,0 }; - static ulong[] dim4420KuoInit = { 1 , 3 , 1 , 1 , 25 , 47 , 19 , 243 , 131 , 387 , 69 , 2057 , 7151 , 8497 , 10975 , 64383 ,0 }; - static ulong[] dim4421KuoInit = { 1 , 3 , 3 , 1 , 13 , 19 , 93 , 35 , 63 , 881 , 1787 , 331 , 57 , 12875 , 5689 , 56411 ,0 }; - static ulong[] dim4422KuoInit = { 1 , 3 , 5 , 1 , 1 , 33 , 39 , 193 , 17 , 291 , 1507 , 1719 , 3507 , 12683 , 16467 , 21453 ,0 }; - static ulong[] dim4423KuoInit = { 1 , 1 , 7 , 7 , 15 , 41 , 113 , 23 , 499 , 641 , 937 , 2505 , 4093 , 4897 , 2493 , 28043 ,0 }; - static ulong[] dim4424KuoInit = { 1 , 3 , 1 , 15 , 13 , 11 , 59 , 175 , 299 , 233 , 189 , 675 , 2623 , 15695 , 2895 , 29213 ,0 }; - static ulong[] dim4425KuoInit = { 1 , 1 , 3 , 3 , 25 , 33 , 113 , 81 , 485 , 615 , 1451 , 1331 , 607 , 13451 , 5853 , 5051 ,0 }; - static ulong[] dim4426KuoInit = { 1 , 1 , 7 , 15 , 13 , 55 , 107 , 43 , 343 , 383 , 63 , 2761 , 5543 , 10249 , 2903 , 28567 ,0 }; - static ulong[] dim4427KuoInit = { 1 , 1 , 7 , 13 , 7 , 23 , 13 , 199 , 109 , 87 , 389 , 561 , 2403 , 12411 , 18247 , 40239 ,0 }; - static ulong[] dim4428KuoInit = { 1 , 1 , 1 , 13 , 21 , 31 , 3 , 109 , 97 , 803 , 991 , 847 , 6517 , 3389 , 15347 , 18295 ,0 }; - static ulong[] dim4429KuoInit = { 1 , 1 , 1 , 1 , 27 , 41 , 115 , 59 , 189 , 105 , 63 , 3169 , 2293 , 6051 , 26017 , 49947 ,0 }; - static ulong[] dim4430KuoInit = { 1 , 3 , 5 , 13 , 19 , 27 , 47 , 13 , 9 , 135 , 637 , 2167 , 2865 , 13353 , 1725 , 41671 ,0 }; - static ulong[] dim4431KuoInit = { 1 , 1 , 5 , 7 , 17 , 61 , 37 , 247 , 447 , 633 , 1761 , 2075 , 6385 , 12393 , 31483 , 1857 ,0 }; - static ulong[] dim4432KuoInit = { 1 , 3 , 5 , 13 , 17 , 17 , 103 , 47 , 391 , 725 , 1379 , 3939 , 6467 , 6723 , 4229 , 50221 ,0 }; - static ulong[] dim4433KuoInit = { 1 , 1 , 5 , 5 , 1 , 61 , 13 , 157 , 379 , 935 , 105 , 419 , 147 , 6369 , 15413 , 38553 ,0 }; - static ulong[] dim4434KuoInit = { 1 , 1 , 5 , 1 , 13 , 49 , 63 , 165 , 207 , 741 , 1285 , 3247 , 4053 , 1647 , 6571 , 61075 ,0 }; - static ulong[] dim4435KuoInit = { 1 , 1 , 5 , 15 , 29 , 41 , 51 , 5 , 123 , 45 , 537 , 2887 , 1329 , 9447 , 22285 , 45247 ,0 }; - static ulong[] dim4436KuoInit = { 1 , 3 , 1 , 3 , 29 , 51 , 65 , 91 , 153 , 673 , 1759 , 401 , 2969 , 6631 , 16965 , 49027 ,0 }; - static ulong[] dim4437KuoInit = { 1 , 3 , 3 , 15 , 29 , 61 , 31 , 85 , 13 , 427 , 1833 , 2145 , 4229 , 14543 , 22741 , 24913 ,0 }; - static ulong[] dim4438KuoInit = { 1 , 3 , 5 , 3 , 21 , 9 , 45 , 253 , 89 , 397 , 965 , 685 , 4013 , 11731 , 2947 , 11995 ,0 }; - static ulong[] dim4439KuoInit = { 1 , 3 , 3 , 11 , 27 , 45 , 101 , 151 , 21 , 563 , 203 , 445 , 6863 , 2151 , 4999 , 8839 ,0 }; - static ulong[] dim4440KuoInit = { 1 , 3 , 5 , 9 , 25 , 57 , 15 , 29 , 3 , 127 , 871 , 1851 , 7825 , 1593 , 11143 , 24507 ,0 }; - static ulong[] dim4441KuoInit = { 1 , 1 , 1 , 7 , 17 , 27 , 49 , 159 , 425 , 773 , 1841 , 1693 , 7829 , 2905 , 16347 , 5581 ,0 }; - static ulong[] dim4442KuoInit = { 1 , 3 , 5 , 7 , 13 , 29 , 81 , 77 , 349 , 747 , 119 , 1195 , 5 , 8481 , 1543 , 50033 ,0 }; - static ulong[] dim4443KuoInit = { 1 , 1 , 7 , 15 , 1 , 25 , 33 , 13 , 9 , 565 , 555 , 699 , 4691 , 1749 , 9531 , 30133 ,0 }; - static ulong[] dim4444KuoInit = { 1 , 1 , 5 , 5 , 13 , 43 , 17 , 31 , 199 , 381 , 393 , 3511 , 6331 , 10377 , 31467 , 25305 ,0 }; - static ulong[] dim4445KuoInit = { 1 , 3 , 3 , 13 , 1 , 49 , 23 , 241 , 499 , 791 , 1851 , 321 , 6057 , 2141 , 8825 , 1829 ,0 }; - static ulong[] dim4446KuoInit = { 1 , 1 , 1 , 1 , 13 , 23 , 77 , 103 , 123 , 247 , 1655 , 1403 , 6059 , 14505 , 1579 , 48169 ,0 }; - static ulong[] dim4447KuoInit = { 1 , 1 , 7 , 13 , 9 , 23 , 125 , 15 , 479 , 447 , 327 , 3743 , 1199 , 5015 , 19009 , 50929 ,0 }; - static ulong[] dim4448KuoInit = { 1 , 1 , 7 , 5 , 5 , 55 , 39 , 131 , 229 , 607 , 1591 , 769 , 2899 , 9681 , 11789 , 62135 ,0 }; - static ulong[] dim4449KuoInit = { 1 , 3 , 3 , 13 , 17 , 59 , 65 , 117 , 299 , 85 , 1187 , 3249 , 295 , 15603 , 28909 , 60317 ,0 }; - static ulong[] dim4450KuoInit = { 1 , 1 , 5 , 13 , 13 , 31 , 7 , 5 , 65 , 785 , 985 , 1637 , 3015 , 14261 , 15089 , 37337 ,0 }; - static ulong[] dim4451KuoInit = { 1 , 3 , 3 , 3 , 17 , 49 , 123 , 151 , 41 , 419 , 391 , 1265 , 6225 , 2037 , 8409 , 13437 ,0 }; - static ulong[] dim4452KuoInit = { 1 , 1 , 5 , 13 , 1 , 23 , 111 , 21 , 381 , 343 , 519 , 1071 , 3889 , 14897 , 9611 , 10657 ,0 }; - static ulong[] dim4453KuoInit = { 1 , 3 , 5 , 13 , 25 , 15 , 79 , 215 , 99 , 783 , 107 , 3845 , 443 , 1115 , 24657 , 54263 ,0 }; - static ulong[] dim4454KuoInit = { 1 , 3 , 3 , 7 , 7 , 29 , 15 , 213 , 165 , 911 , 351 , 4025 , 7657 , 2079 , 21525 , 60751 ,0 }; - static ulong[] dim4455KuoInit = { 1 , 1 , 3 , 3 , 15 , 19 , 107 , 181 , 177 , 279 , 803 , 2825 , 4609 , 9955 , 7725 , 44161 ,0 }; - static ulong[] dim4456KuoInit = { 1 , 1 , 3 , 7 , 21 , 9 , 69 , 107 , 43 , 239 , 397 , 2567 , 1375 , 12483 , 19783 , 27889 ,0 }; - static ulong[] dim4457KuoInit = { 1 , 3 , 7 , 5 , 7 , 39 , 39 , 71 , 397 , 829 , 373 , 1869 , 6229 , 2299 , 19737 , 58479 ,0 }; - static ulong[] dim4458KuoInit = { 1 , 1 , 3 , 7 , 13 , 53 , 39 , 41 , 105 , 547 , 1687 , 153 , 4067 , 16317 , 15 , 52949 ,0 }; - static ulong[] dim4459KuoInit = { 1 , 3 , 7 , 11 , 9 , 19 , 97 , 45 , 225 , 977 , 545 , 3691 , 5315 , 6239 , 26833 , 28115 ,0 }; - static ulong[] dim4460KuoInit = { 1 , 3 , 7 , 3 , 23 , 11 , 17 , 13 , 437 , 145 , 1153 , 1193 , 835 , 5095 , 5535 , 17033 ,0 }; - static ulong[] dim4461KuoInit = { 1 , 3 , 1 , 3 , 7 , 13 , 17 , 197 , 289 , 875 , 97 , 1721 , 2369 , 8351 , 10813 , 10129 ,0 }; - static ulong[] dim4462KuoInit = { 1 , 3 , 7 , 13 , 7 , 59 , 11 , 37 , 77 , 541 , 837 , 2943 , 423 , 6093 , 32495 , 59203 ,0 }; - static ulong[] dim4463KuoInit = { 1 , 1 , 5 , 9 , 13 , 17 , 117 , 239 , 499 , 819 , 1585 , 1755 , 219 , 4681 , 10771 , 14713 ,0 }; - static ulong[] dim4464KuoInit = { 1 , 3 , 1 , 9 , 15 , 21 , 3 , 123 , 303 , 223 , 1579 , 1959 , 7767 , 6079 , 2085 , 7683 ,0 }; - static ulong[] dim4465KuoInit = { 1 , 1 , 7 , 15 , 13 , 37 , 35 , 37 , 479 , 341 , 1315 , 3339 , 3059 , 251 , 31629 , 32757 ,0 }; - static ulong[] dim4466KuoInit = { 1 , 1 , 5 , 11 , 19 , 23 , 55 , 109 , 443 , 77 , 577 , 1963 , 3769 , 1783 , 5059 , 35905 ,0 }; - static ulong[] dim4467KuoInit = { 1 , 1 , 5 , 15 , 17 , 45 , 53 , 139 , 261 , 147 , 1117 , 2255 , 1389 , 6505 , 21785 , 52763 ,0 }; - static ulong[] dim4468KuoInit = { 1 , 1 , 7 , 15 , 21 , 61 , 97 , 147 , 397 , 231 , 775 , 3297 , 4883 , 7059 , 16769 , 22765 ,0 }; - static ulong[] dim4469KuoInit = { 1 , 3 , 7 , 13 , 13 , 29 , 67 , 117 , 381 , 505 , 1437 , 939 , 4551 , 8767 , 7355 , 10507 ,0 }; - static ulong[] dim4470KuoInit = { 1 , 3 , 3 , 7 , 5 , 57 , 115 , 205 , 159 , 587 , 169 , 3787 , 1271 , 9583 , 12205 , 63993 ,0 }; - static ulong[] dim4471KuoInit = { 1 , 3 , 3 , 13 , 9 , 59 , 51 , 165 , 159 , 391 , 421 , 2179 , 2943 , 505 , 19315 , 16175 ,0 }; - static ulong[] dim4472KuoInit = { 1 , 3 , 5 , 13 , 21 , 53 , 95 , 131 , 275 , 421 , 435 , 2655 , 4999 , 14225 , 26417 , 57465 ,0 }; - static ulong[] dim4473KuoInit = { 1 , 1 , 1 , 5 , 29 , 39 , 115 , 183 , 507 , 849 , 1935 , 2849 , 6301 , 11937 , 19519 , 37019 ,0 }; - static ulong[] dim4474KuoInit = { 1 , 1 , 5 , 1 , 13 , 15 , 37 , 25 , 113 , 885 , 1265 , 2287 , 4535 , 12265 , 10433 , 56641 ,0 }; - static ulong[] dim4475KuoInit = { 1 , 3 , 1 , 9 , 29 , 11 , 67 , 19 , 11 , 347 , 1659 , 3251 , 3179 , 2583 , 10127 , 21549 ,0 }; - static ulong[] dim4476KuoInit = { 1 , 3 , 7 , 7 , 13 , 27 , 101 , 101 , 197 , 381 , 987 , 1699 , 2913 , 5179 , 3423 , 30389 ,0 }; - static ulong[] dim4477KuoInit = { 1 , 1 , 7 , 13 , 29 , 39 , 87 , 65 , 265 , 891 , 973 , 1487 , 6687 , 7875 , 13389 , 39141 ,0 }; - static ulong[] dim4478KuoInit = { 1 , 1 , 1 , 3 , 7 , 13 , 101 , 223 , 181 , 143 , 1291 , 2803 , 251 , 12541 , 20713 , 18137 ,0 }; - static ulong[] dim4479KuoInit = { 1 , 1 , 1 , 15 , 3 , 9 , 103 , 137 , 121 , 563 , 1079 , 3119 , 5619 , 2175 , 27223 , 25289 ,0 }; - static ulong[] dim4480KuoInit = { 1 , 3 , 3 , 15 , 7 , 13 , 109 , 201 , 385 , 347 , 319 , 883 , 13 , 3683 , 19615 , 9781 ,0 }; - static ulong[] dim4481KuoInit = { 1 , 1 , 1 , 5 , 13 , 15 , 127 , 161 , 353 , 567 , 555 , 2287 , 1791 , 9535 , 26227 , 15335 ,0 }; - static ulong[] dim4482KuoInit = { 1 , 1 , 5 , 9 , 3 , 63 , 11 , 83 , 235 , 741 , 977 , 2265 , 449 , 10293 , 20451 , 25143 ,0 }; - static ulong[] dim4483KuoInit = { 1 , 1 , 3 , 3 , 23 , 25 , 119 , 1 , 381 , 463 , 67 , 257 , 7087 , 10553 , 10781 , 60003 ,0 }; - static ulong[] dim4484KuoInit = { 1 , 3 , 7 , 15 , 17 , 11 , 81 , 17 , 363 , 163 , 1765 , 285 , 4239 , 14777 , 15081 , 54151 ,0 }; - static ulong[] dim4485KuoInit = { 1 , 3 , 3 , 13 , 17 , 9 , 73 , 237 , 273 , 439 , 1419 , 1539 , 667 , 13833 , 31783 , 49459 ,0 }; - static ulong[] dim4486KuoInit = { 1 , 1 , 3 , 3 , 15 , 11 , 85 , 3 , 481 , 169 , 1443 , 3403 , 1157 , 595 , 6851 , 59343 ,0 }; - static ulong[] dim4487KuoInit = { 1 , 3 , 7 , 1 , 23 , 21 , 13 , 251 , 403 , 859 , 175 , 1373 , 3711 , 1233 , 16879 , 4659 ,0 }; - static ulong[] dim4488KuoInit = { 1 , 1 , 5 , 7 , 21 , 7 , 15 , 165 , 265 , 117 , 385 , 2661 , 1481 , 1709 , 19843 , 29639 ,0 }; - static ulong[] dim4489KuoInit = { 1 , 1 , 1 , 11 , 3 , 7 , 81 , 3 , 429 , 997 , 1759 , 285 , 375 , 3487 , 5257 , 14203 ,0 }; - static ulong[] dim4490KuoInit = { 1 , 3 , 7 , 1 , 15 , 17 , 93 , 69 , 303 , 809 , 929 , 3025 , 6333 , 4525 , 6441 , 32265 ,0 }; - static ulong[] dim4491KuoInit = { 1 , 3 , 1 , 5 , 27 , 41 , 119 , 25 , 461 , 347 , 369 , 489 , 377 , 3899 , 12711 , 24475 ,0 }; - static ulong[] dim4492KuoInit = { 1 , 3 , 7 , 5 , 29 , 59 , 101 , 159 , 305 , 337 , 1371 , 891 , 6013 , 2987 , 27201 , 61055 ,0 }; - static ulong[] dim4493KuoInit = { 1 , 1 , 1 , 3 , 19 , 5 , 3 , 219 , 71 , 213 , 137 , 1925 , 2365 , 583 , 11591 , 9495 ,0 }; - static ulong[] dim4494KuoInit = { 1 , 3 , 7 , 3 , 31 , 31 , 85 , 115 , 169 , 499 , 1669 , 499 , 1987 , 2505 , 435 , 6377 ,0 }; - static ulong[] dim4495KuoInit = { 1 , 1 , 3 , 5 , 3 , 33 , 33 , 41 , 199 , 187 , 1023 , 771 , 3447 , 4355 , 29353 , 42293 ,0 }; - static ulong[] dim4496KuoInit = { 1 , 1 , 5 , 7 , 1 , 41 , 17 , 231 , 305 , 975 , 975 , 1697 , 7267 , 9567 , 9975 , 51313 ,0 }; - static ulong[] dim4497KuoInit = { 1 , 3 , 5 , 3 , 9 , 41 , 27 , 29 , 285 , 469 , 1845 , 665 , 3007 , 4199 , 3367 , 50849 ,0 }; - static ulong[] dim4498KuoInit = { 1 , 1 , 5 , 9 , 29 , 5 , 93 , 63 , 227 , 751 , 1591 , 649 , 6219 , 13371 , 3473 , 34033 ,0 }; - static ulong[] dim4499KuoInit = { 1 , 3 , 3 , 1 , 13 , 5 , 27 , 239 , 89 , 893 , 1869 , 3789 , 7569 , 525 , 32019 , 17501 ,0 }; - static ulong[] dim4500KuoInit = { 1 , 1 , 5 , 11 , 9 , 5 , 51 , 149 , 351 , 81 , 1895 , 3011 , 2521 , 4185 , 1277 , 65397 ,0 }; - static ulong[] dim4501KuoInit = { 1 , 3 , 5 , 3 , 21 , 13 , 121 , 213 , 67 , 825 , 1493 , 2933 , 6189 , 14135 , 7021 , 47435 ,0 }; - static ulong[] dim4502KuoInit = { 1 , 3 , 7 , 15 , 11 , 51 , 63 , 163 , 371 , 363 , 1885 , 1535 , 629 , 2939 , 12547 , 24779 ,0 }; - static ulong[] dim4503KuoInit = { 1 , 3 , 7 , 3 , 3 , 3 , 49 , 47 , 409 , 963 , 1499 , 1107 , 8063 , 11137 , 21251 , 4695 ,0 }; - static ulong[] dim4504KuoInit = { 1 , 1 , 3 , 1 , 31 , 17 , 61 , 149 , 263 , 503 , 219 , 3419 , 4525 , 14689 , 30841 , 60799 ,0 }; - static ulong[] dim4505KuoInit = { 1 , 3 , 3 , 5 , 31 , 25 , 5 , 247 , 219 , 79 , 1605 , 3523 , 4815 , 12907 , 22017 , 16145 ,0 }; - static ulong[] dim4506KuoInit = { 1 , 1 , 7 , 11 , 21 , 51 , 47 , 85 , 37 , 461 , 1299 , 2007 , 2093 , 10707 , 17997 , 4221 ,0 }; - static ulong[] dim4507KuoInit = { 1 , 3 , 3 , 11 , 11 , 59 , 63 , 191 , 359 , 859 , 1265 , 853 , 6733 , 4605 , 27559 , 32557 ,0 }; - static ulong[] dim4508KuoInit = { 1 , 3 , 7 , 11 , 29 , 61 , 119 , 73 , 73 , 259 , 1939 , 59 , 5177 , 12375 , 22143 , 28073 ,0 }; - static ulong[] dim4509KuoInit = { 1 , 3 , 7 , 7 , 21 , 29 , 19 , 33 , 59 , 539 , 281 , 2989 , 2239 , 6671 , 31629 , 16065 ,0 }; - static ulong[] dim4510KuoInit = { 1 , 3 , 5 , 7 , 17 , 27 , 39 , 57 , 483 , 463 , 51 , 3771 , 5641 , 5875 , 2369 , 21619 ,0 }; - static ulong[] dim4511KuoInit = { 1 , 3 , 1 , 1 , 15 , 9 , 121 , 217 , 107 , 615 , 1413 , 2083 , 231 , 9177 , 12275 , 20069 ,0 }; - static ulong[] dim4512KuoInit = { 1 , 3 , 5 , 15 , 17 , 55 , 85 , 27 , 477 , 687 , 1295 , 3471 , 6951 , 2645 , 30051 , 36149 ,0 }; - static ulong[] dim4513KuoInit = { 1 , 3 , 3 , 1 , 1 , 27 , 9 , 183 , 39 , 559 , 1639 , 5 , 1177 , 16011 , 1447 , 42897 ,0 }; - static ulong[] dim4514KuoInit = { 1 , 1 , 1 , 5 , 21 , 9 , 75 , 217 , 311 , 679 , 1913 , 2623 , 3853 , 10889 , 22501 , 40089 ,0 }; - static ulong[] dim4515KuoInit = { 1 , 3 , 5 , 7 , 17 , 59 , 23 , 199 , 147 , 339 , 1027 , 1471 , 6539 , 7963 , 30713 , 1939 ,0 }; - static ulong[] dim4516KuoInit = { 1 , 1 , 3 , 11 , 23 , 51 , 111 , 175 , 433 , 803 , 1577 , 4091 , 2197 , 10003 , 2597 , 53553 ,0 }; - static ulong[] dim4517KuoInit = { 1 , 3 , 5 , 1 , 3 , 11 , 125 , 11 , 281 , 969 , 1943 , 1003 , 2189 , 3551 , 25831 , 64261 ,0 }; - static ulong[] dim4518KuoInit = { 1 , 3 , 7 , 1 , 17 , 19 , 111 , 235 , 511 , 723 , 1779 , 1041 , 4067 , 3827 , 17285 , 63075 ,0 }; - static ulong[] dim4519KuoInit = { 1 , 1 , 3 , 15 , 3 , 63 , 7 , 165 , 153 , 829 , 221 , 1485 , 4319 , 9865 , 937 , 65171 ,0 }; - static ulong[] dim4520KuoInit = { 1 , 1 , 7 , 1 , 21 , 21 , 89 , 233 , 417 , 15 , 367 , 311 , 3575 , 11285 , 5245 , 3947 ,0 }; - static ulong[] dim4521KuoInit = { 1 , 3 , 7 , 9 , 27 , 55 , 3 , 71 , 227 , 397 , 561 , 4075 , 5495 , 16071 , 11495 , 48733 ,0 }; - static ulong[] dim4522KuoInit = { 1 , 3 , 3 , 3 , 3 , 39 , 57 , 219 , 237 , 151 , 1305 , 2485 , 5045 , 5065 , 21041 , 20055 ,0 }; - static ulong[] dim4523KuoInit = { 1 , 1 , 3 , 11 , 15 , 33 , 75 , 241 , 335 , 207 , 1695 , 119 , 839 , 12449 , 28467 , 7445 ,0 }; - static ulong[] dim4524KuoInit = { 1 , 1 , 7 , 3 , 21 , 3 , 43 , 137 , 321 , 763 , 575 , 2317 , 8073 , 1225 , 8257 , 11639 ,0 }; - static ulong[] dim4525KuoInit = { 1 , 3 , 5 , 11 , 27 , 21 , 17 , 115 , 265 , 1023 , 1403 , 853 , 757 , 1799 , 25505 , 49207 ,0 }; - static ulong[] dim4526KuoInit = { 1 , 1 , 7 , 5 , 9 , 45 , 57 , 77 , 127 , 447 , 1097 , 1729 , 2361 , 1599 , 15727 , 49413 ,0 }; - static ulong[] dim4527KuoInit = { 1 , 1 , 1 , 15 , 21 , 41 , 13 , 41 , 183 , 151 , 441 , 3077 , 4205 , 125 , 23767 , 44667 ,0 }; - static ulong[] dim4528KuoInit = { 1 , 3 , 3 , 9 , 3 , 37 , 5 , 203 , 39 , 49 , 1793 , 3523 , 7541 , 23 , 22527 , 35999 ,0 }; - static ulong[] dim4529KuoInit = { 1 , 3 , 7 , 13 , 13 , 5 , 127 , 169 , 465 , 759 , 393 , 1543 , 3327 , 6223 , 18675 , 36075 ,0 }; - static ulong[] dim4530KuoInit = { 1 , 3 , 5 , 15 , 17 , 57 , 83 , 237 , 307 , 495 , 135 , 1461 , 4353 , 15251 , 10005 , 12769 ,0 }; - static ulong[] dim4531KuoInit = { 1 , 1 , 7 , 13 , 27 , 49 , 57 , 19 , 463 , 97 , 217 , 2825 , 7729 , 2375 , 8339 , 17563 ,0 }; - static ulong[] dim4532KuoInit = { 1 , 3 , 7 , 1 , 31 , 13 , 17 , 245 , 329 , 1021 , 619 , 3149 , 7089 , 4381 , 14079 , 35659 ,0 }; - static ulong[] dim4533KuoInit = { 1 , 3 , 5 , 15 , 31 , 19 , 15 , 217 , 115 , 159 , 281 , 2233 , 4315 , 7429 , 25527 , 44671 ,0 }; - static ulong[] dim4534KuoInit = { 1 , 1 , 7 , 1 , 11 , 23 , 7 , 181 , 43 , 271 , 607 , 389 , 357 , 3003 , 15899 , 50849 ,0 }; - static ulong[] dim4535KuoInit = { 1 , 1 , 7 , 15 , 11 , 15 , 41 , 247 , 37 , 163 , 665 , 3059 , 5151 , 15335 , 13167 , 18541 ,0 }; - static ulong[] dim4536KuoInit = { 1 , 1 , 7 , 15 , 25 , 33 , 33 , 135 , 425 , 785 , 1557 , 793 , 7153 , 13473 , 8833 , 21335 ,0 }; - static ulong[] dim4537KuoInit = { 1 , 3 , 3 , 1 , 17 , 27 , 7 , 75 , 205 , 71 , 581 , 733 , 5009 , 1029 , 27537 , 41905 ,0 }; - static ulong[] dim4538KuoInit = { 1 , 3 , 3 , 3 , 5 , 63 , 121 , 3 , 381 , 607 , 1099 , 1571 , 1077 , 15491 , 13785 , 31537 ,0 }; - static ulong[] dim4539KuoInit = { 1 , 1 , 5 , 7 , 17 , 15 , 87 , 81 , 313 , 683 , 31 , 3301 , 1683 , 12667 , 17867 , 38405 ,0 }; - static ulong[] dim4540KuoInit = { 1 , 1 , 1 , 13 , 3 , 23 , 51 , 95 , 409 , 711 , 381 , 245 , 7 , 15679 , 14281 , 39789 ,0 }; - static ulong[] dim4541KuoInit = { 1 , 3 , 1 , 1 , 31 , 35 , 97 , 35 , 121 , 45 , 1397 , 4009 , 2829 , 3273 , 2725 , 913 ,0 }; - static ulong[] dim4542KuoInit = { 1 , 3 , 1 , 11 , 29 , 29 , 111 , 153 , 499 , 371 , 1767 , 3063 , 6175 , 8205 , 3485 , 8951 ,0 }; - static ulong[] dim4543KuoInit = { 1 , 3 , 5 , 5 , 27 , 9 , 113 , 141 , 295 , 901 , 1367 , 791 , 1645 , 5993 , 6139 , 12853 ,0 }; - static ulong[] dim4544KuoInit = { 1 , 1 , 1 , 7 , 27 , 17 , 113 , 187 , 293 , 517 , 1327 , 579 , 1191 , 12039 , 13973 , 51129 ,0 }; - static ulong[] dim4545KuoInit = { 1 , 1 , 7 , 3 , 11 , 9 , 55 , 71 , 47 , 787 , 1311 , 2567 , 7555 , 2825 , 11485 , 16787 ,0 }; - static ulong[] dim4546KuoInit = { 1 , 3 , 1 , 7 , 29 , 33 , 115 , 115 , 69 , 155 , 1185 , 2653 , 7127 , 1449 , 8875 , 34819 ,0 }; - static ulong[] dim4547KuoInit = { 1 , 3 , 5 , 15 , 9 , 61 , 61 , 161 , 29 , 33 , 1155 , 613 , 7233 , 2811 , 4837 , 27781 ,0 }; - static ulong[] dim4548KuoInit = { 1 , 1 , 5 , 3 , 25 , 57 , 85 , 121 , 505 , 45 , 1143 , 3237 , 6403 , 2377 , 30791 , 26637 ,0 }; - static ulong[] dim4549KuoInit = { 1 , 3 , 3 , 5 , 31 , 39 , 63 , 255 , 153 , 417 , 865 , 441 , 7649 , 16321 , 29147 , 11089 ,0 }; - static ulong[] dim4550KuoInit = { 1 , 1 , 7 , 5 , 25 , 19 , 43 , 45 , 457 , 353 , 25 , 1135 , 4663 , 11419 , 25373 , 8411 ,0 }; - static ulong[] dim4551KuoInit = { 1 , 3 , 7 , 11 , 11 , 47 , 101 , 255 , 437 , 937 , 263 , 1171 , 7893 , 277 , 4413 , 20197 ,0 }; - static ulong[] dim4552KuoInit = { 1 , 1 , 5 , 13 , 21 , 61 , 1 , 31 , 227 , 345 , 1535 , 1597 , 7061 , 11595 , 12055 , 29611 ,0 }; - static ulong[] dim4553KuoInit = { 1 , 1 , 3 , 1 , 19 , 49 , 83 , 61 , 305 , 611 , 399 , 1397 , 4753 , 2309 , 15097 , 13439 ,0 }; - static ulong[] dim4554KuoInit = { 1 , 1 , 3 , 9 , 27 , 37 , 77 , 165 , 273 , 85 , 483 , 299 , 5073 , 1255 , 4073 , 56333 ,0 }; - static ulong[] dim4555KuoInit = { 1 , 1 , 7 , 3 , 5 , 11 , 127 , 157 , 489 , 653 , 165 , 2071 , 4819 , 121 , 32755 , 21623 ,0 }; - static ulong[] dim4556KuoInit = { 1 , 3 , 5 , 11 , 23 , 5 , 111 , 25 , 173 , 661 , 353 , 1167 , 2625 , 8021 , 18731 , 42705 ,0 }; - static ulong[] dim4557KuoInit = { 1 , 3 , 5 , 15 , 9 , 33 , 31 , 137 , 283 , 925 , 1641 , 115 , 7047 , 11365 , 13097 , 4711 ,0 }; - static ulong[] dim4558KuoInit = { 1 , 3 , 7 , 13 , 13 , 13 , 29 , 135 , 273 , 325 , 1085 , 1683 , 1365 , 9931 , 8557 , 3855 ,0 }; - static ulong[] dim4559KuoInit = { 1 , 3 , 5 , 13 , 17 , 27 , 103 , 183 , 237 , 343 , 907 , 2945 , 3039 , 12873 , 28635 , 14791 ,0 }; - static ulong[] dim4560KuoInit = { 1 , 3 , 3 , 13 , 5 , 51 , 13 , 57 , 131 , 1021 , 1995 , 921 , 6911 , 14381 , 17113 , 56783 ,0 }; - static ulong[] dim4561KuoInit = { 1 , 3 , 5 , 5 , 5 , 55 , 89 , 29 , 409 , 687 , 1151 , 3423 , 1893 , 12153 , 8167 , 14849 ,0 }; - static ulong[] dim4562KuoInit = { 1 , 3 , 5 , 1 , 1 , 53 , 41 , 53 , 81 , 797 , 1665 , 85 , 8131 , 3853 , 17815 , 7771 ,0 }; - static ulong[] dim4563KuoInit = { 1 , 1 , 7 , 3 , 31 , 41 , 37 , 107 , 319 , 421 , 279 , 2061 , 1981 , 6917 , 25545 , 46053 ,0 }; - static ulong[] dim4564KuoInit = { 1 , 3 , 3 , 11 , 13 , 25 , 85 , 203 , 399 , 863 , 1577 , 1445 , 8093 , 1845 , 16307 , 61075 ,0 }; - static ulong[] dim4565KuoInit = { 1 , 1 , 5 , 5 , 1 , 35 , 117 , 201 , 271 , 901 , 1939 , 2291 , 343 , 13591 , 28371 , 61429 ,0 }; - static ulong[] dim4566KuoInit = { 1 , 3 , 3 , 7 , 21 , 55 , 85 , 123 , 183 , 787 , 1121 , 447 , 5761 , 6925 , 22407 , 53149 ,0 }; - static ulong[] dim4567KuoInit = { 1 , 3 , 1 , 13 , 31 , 25 , 63 , 247 , 109 , 741 , 231 , 2621 , 4939 , 11155 , 21625 , 30433 ,0 }; - static ulong[] dim4568KuoInit = { 1 , 1 , 5 , 15 , 3 , 49 , 63 , 147 , 117 , 703 , 1317 , 2803 , 4655 , 5981 , 14473 , 52739 ,0 }; - static ulong[] dim4569KuoInit = { 1 , 1 , 7 , 1 , 27 , 45 , 117 , 55 , 391 , 275 , 1793 , 1279 , 4799 , 15509 , 17173 , 25103 ,0 }; - static ulong[] dim4570KuoInit = { 1 , 3 , 3 , 1 , 27 , 15 , 35 , 43 , 209 , 869 , 1833 , 3625 , 5973 , 8965 , 1443 , 59053 ,0 }; - static ulong[] dim4571KuoInit = { 1 , 1 , 1 , 1 , 1 , 19 , 93 , 63 , 407 , 735 , 1821 , 2875 , 1263 , 1461 , 7811 , 17257 ,0 }; - static ulong[] dim4572KuoInit = { 1 , 1 , 7 , 5 , 15 , 35 , 3 , 89 , 355 , 983 , 1183 , 2709 , 127 , 10671 , 31223 , 26689 ,0 }; - static ulong[] dim4573KuoInit = { 1 , 3 , 3 , 3 , 15 , 29 , 105 , 239 , 293 , 57 , 515 , 363 , 5227 , 14693 , 18437 , 13107 ,0 }; - static ulong[] dim4574KuoInit = { 1 , 1 , 5 , 1 , 29 , 61 , 65 , 77 , 23 , 311 , 1581 , 215 , 1409 , 2575 , 13915 , 63179 ,0 }; - static ulong[] dim4575KuoInit = { 1 , 3 , 1 , 5 , 27 , 17 , 113 , 255 , 347 , 493 , 1795 , 817 , 7483 , 10611 , 9941 , 56425 ,0 }; - static ulong[] dim4576KuoInit = { 1 , 3 , 1 , 11 , 1 , 29 , 79 , 153 , 183 , 975 , 1127 , 881 , 1319 , 11481 , 16807 , 23167 ,0 }; - static ulong[] dim4577KuoInit = { 1 , 1 , 5 , 15 , 7 , 31 , 107 , 245 , 59 , 579 , 423 , 2165 , 5137 , 14735 , 13187 , 28781 ,0 }; - static ulong[] dim4578KuoInit = { 1 , 3 , 1 , 13 , 13 , 55 , 63 , 155 , 63 , 581 , 1083 , 2249 , 7397 , 2081 , 23727 , 23981 ,0 }; - static ulong[] dim4579KuoInit = { 1 , 3 , 7 , 9 , 23 , 29 , 93 , 215 , 361 , 71 , 119 , 3215 , 3529 , 14249 , 29593 , 27305 ,0 }; - static ulong[] dim4580KuoInit = { 1 , 1 , 7 , 9 , 5 , 63 , 45 , 181 , 463 , 21 , 229 , 4069 , 4889 , 2141 , 25623 , 6191 ,0 }; - static ulong[] dim4581KuoInit = { 1 , 3 , 1 , 1 , 17 , 31 , 105 , 153 , 301 , 433 , 517 , 585 , 285 , 12805 , 30173 , 21363 ,0 }; - static ulong[] dim4582KuoInit = { 1 , 3 , 3 , 15 , 29 , 23 , 117 , 19 , 415 , 389 , 881 , 2067 , 583 , 11383 , 24951 , 34745 ,0 }; - static ulong[] dim4583KuoInit = { 1 , 1 , 3 , 13 , 27 , 55 , 37 , 5 , 337 , 943 , 1851 , 3227 , 3881 , 7365 , 10853 , 23325 ,0 }; - static ulong[] dim4584KuoInit = { 1 , 3 , 1 , 11 , 25 , 5 , 39 , 189 , 503 , 745 , 1349 , 3881 , 5037 , 13855 , 19537 , 22329 ,0 }; - static ulong[] dim4585KuoInit = { 1 , 3 , 7 , 9 , 7 , 33 , 63 , 61 , 39 , 825 , 53 , 1471 , 3589 , 13473 , 29241 , 40829 ,0 }; - static ulong[] dim4586KuoInit = { 1 , 1 , 7 , 1 , 1 , 37 , 111 , 251 , 427 , 427 , 937 , 3921 , 8033 , 269 , 14261 , 37345 ,0 }; - static ulong[] dim4587KuoInit = { 1 , 1 , 7 , 7 , 31 , 59 , 111 , 205 , 285 , 113 , 951 , 2867 , 3769 , 5237 , 693 , 42097 ,0 }; - static ulong[] dim4588KuoInit = { 1 , 1 , 1 , 15 , 29 , 43 , 15 , 253 , 383 , 783 , 1407 , 3851 , 4333 , 11607 , 12777 , 55499 ,0 }; - static ulong[] dim4589KuoInit = { 1 , 1 , 3 , 15 , 15 , 27 , 75 , 57 , 87 , 185 , 1079 , 2721 , 915 , 13633 , 26439 , 10697 ,0 }; - static ulong[] dim4590KuoInit = { 1 , 1 , 7 , 13 , 17 , 63 , 43 , 65 , 5 , 699 , 1157 , 2271 , 837 , 687 , 29551 , 22109 ,0 }; - static ulong[] dim4591KuoInit = { 1 , 3 , 7 , 3 , 5 , 47 , 103 , 143 , 281 , 81 , 283 , 3073 , 3741 , 11525 , 4499 , 41325 ,0 }; - static ulong[] dim4592KuoInit = { 1 , 3 , 7 , 11 , 13 , 19 , 63 , 215 , 215 , 21 , 1443 , 2485 , 2661 , 8123 , 11739 , 48729 ,0 }; - static ulong[] dim4593KuoInit = { 1 , 3 , 3 , 3 , 27 , 13 , 111 , 153 , 17 , 715 , 1453 , 1827 , 5201 , 1139 , 19531 , 18853 ,0 }; - static ulong[] dim4594KuoInit = { 1 , 3 , 7 , 15 , 7 , 61 , 109 , 213 , 383 , 483 , 301 , 1791 , 559 , 14205 , 28441 , 13179 ,0 }; - static ulong[] dim4595KuoInit = { 1 , 1 , 7 , 7 , 23 , 55 , 119 , 45 , 467 , 775 , 951 , 2533 , 6703 , 15791 , 12891 , 54513 ,0 }; - static ulong[] dim4596KuoInit = { 1 , 1 , 7 , 15 , 19 , 49 , 71 , 127 , 455 , 881 , 329 , 663 , 4997 , 8755 , 17517 , 31507 ,0 }; - static ulong[] dim4597KuoInit = { 1 , 1 , 5 , 9 , 9 , 13 , 75 , 161 , 109 , 631 , 153 , 15 , 1181 , 14299 , 11815 , 32017 ,0 }; - static ulong[] dim4598KuoInit = { 1 , 3 , 5 , 15 , 9 , 63 , 101 , 85 , 487 , 213 , 1743 , 2575 , 6979 , 14421 , 18051 , 14505 ,0 }; - static ulong[] dim4599KuoInit = { 1 , 1 , 5 , 7 , 5 , 5 , 109 , 245 , 427 , 765 , 2013 , 2929 , 6737 , 14561 , 32227 , 60605 ,0 }; - static ulong[] dim4600KuoInit = { 1 , 3 , 1 , 3 , 1 , 7 , 17 , 169 , 27 , 925 , 1711 , 101 , 2065 , 4857 , 863 , 38371 ,0 }; - static ulong[] dim4601KuoInit = { 1 , 1 , 7 , 5 , 5 , 25 , 119 , 145 , 27 , 377 , 1535 , 441 , 5181 , 9789 , 26757 , 46977 ,0 }; - static ulong[] dim4602KuoInit = { 1 , 1 , 7 , 5 , 31 , 1 , 79 , 223 , 199 , 409 , 2033 , 1781 , 5269 , 2631 , 10627 , 41785 ,0 }; - static ulong[] dim4603KuoInit = { 1 , 3 , 5 , 3 , 29 , 7 , 91 , 123 , 407 , 19 , 847 , 4019 , 1029 , 15763 , 30265 , 49287 ,0 }; - static ulong[] dim4604KuoInit = { 1 , 1 , 3 , 9 , 1 , 37 , 33 , 53 , 49 , 949 , 1737 , 229 , 3419 , 5125 , 16365 , 48867 ,0 }; - static ulong[] dim4605KuoInit = { 1 , 3 , 7 , 9 , 25 , 17 , 13 , 31 , 27 , 53 , 287 , 4021 , 7687 , 14511 , 12627 , 54409 ,0 }; - static ulong[] dim4606KuoInit = { 1 , 1 , 3 , 9 , 21 , 29 , 1 , 193 , 479 , 895 , 605 , 2013 , 6571 , 14073 , 28185 , 58845 ,0 }; - static ulong[] dim4607KuoInit = { 1 , 3 , 5 , 11 , 3 , 21 , 111 , 215 , 259 , 941 , 1729 , 645 , 695 , 3295 , 23825 , 1009 ,0 }; - static ulong[] dim4608KuoInit = { 1 , 3 , 3 , 9 , 25 , 17 , 103 , 187 , 153 , 287 , 911 , 1265 , 41 , 1687 , 22443 , 21117 ,0 }; - static ulong[] dim4609KuoInit = { 1 , 3 , 5 , 5 , 31 , 25 , 3 , 107 , 271 , 531 , 1413 , 2813 , 5075 , 2127 , 18647 , 5257 ,0 }; - static ulong[] dim4610KuoInit = { 1 , 1 , 1 , 7 , 5 , 25 , 71 , 225 , 391 , 877 , 1713 , 1841 , 3239 , 9063 , 11445 , 48693 ,0 }; - static ulong[] dim4611KuoInit = { 1 , 1 , 1 , 13 , 21 , 25 , 15 , 157 , 59 , 37 , 1349 , 413 , 6401 , 3533 , 6019 , 40373 ,0 }; - static ulong[] dim4612KuoInit = { 1 , 1 , 5 , 5 , 5 , 3 , 31 , 185 , 59 , 933 , 1415 , 901 , 6075 , 4839 , 32477 , 43085 ,0 }; - static ulong[] dim4613KuoInit = { 1 , 3 , 1 , 5 , 11 , 7 , 81 , 109 , 167 , 277 , 1803 , 39 , 7421 , 15573 , 2233 , 8193 ,0 }; - static ulong[] dim4614KuoInit = { 1 , 3 , 1 , 1 , 13 , 15 , 47 , 109 , 279 , 515 , 1393 , 1785 , 4297 , 813 , 19177 , 5951 ,0 }; - static ulong[] dim4615KuoInit = { 1 , 3 , 3 , 1 , 21 , 23 , 3 , 27 , 317 , 677 , 1775 , 1109 , 93 , 9007 , 8767 , 42181 ,0 }; - static ulong[] dim4616KuoInit = { 1 , 3 , 5 , 13 , 23 , 15 , 49 , 9 , 369 , 293 , 529 , 2115 , 4781 , 1955 , 21897 , 22871 ,0 }; - static ulong[] dim4617KuoInit = { 1 , 1 , 7 , 9 , 5 , 39 , 85 , 85 , 405 , 837 , 1891 , 27 , 509 , 14643 , 10497 , 34021 ,0 }; - static ulong[] dim4618KuoInit = { 1 , 1 , 7 , 9 , 7 , 47 , 49 , 87 , 481 , 1003 , 741 , 329 , 2951 , 5317 , 21601 , 20485 ,0 }; - static ulong[] dim4619KuoInit = { 1 , 3 , 5 , 11 , 27 , 61 , 45 , 251 , 489 , 623 , 1673 , 891 , 5429 , 4457 , 23147 , 5201 ,0 }; - static ulong[] dim4620KuoInit = { 1 , 3 , 3 , 7 , 25 , 27 , 3 , 233 , 193 , 253 , 483 , 1881 , 6753 , 7843 , 3975 , 23413 ,0 }; - static ulong[] dim4621KuoInit = { 1 , 3 , 1 , 15 , 27 , 31 , 51 , 213 , 463 , 995 , 1127 , 3589 , 1409 , 15743 , 22755 , 39913 ,0 }; - static ulong[] dim4622KuoInit = { 1 , 3 , 1 , 13 , 21 , 17 , 35 , 157 , 233 , 899 , 1003 , 201 , 3425 , 6703 , 26585 , 18389 ,0 }; - static ulong[] dim4623KuoInit = { 1 , 3 , 1 , 9 , 11 , 23 , 69 , 93 , 361 , 177 , 1071 , 3523 , 4117 , 6107 , 3701 , 64213 ,0 }; - static ulong[] dim4624KuoInit = { 1 , 3 , 5 , 1 , 19 , 1 , 35 , 95 , 385 , 853 , 1635 , 1815 , 5307 , 3155 , 11347 , 39289 ,0 }; - static ulong[] dim4625KuoInit = { 1 , 1 , 7 , 9 , 3 , 41 , 37 , 161 , 293 , 1005 , 1915 , 2867 , 841 , 195 , 4247 , 8621 ,0 }; - static ulong[] dim4626KuoInit = { 1 , 3 , 7 , 11 , 19 , 43 , 69 , 95 , 455 , 669 , 217 , 129 , 1275 , 8431 , 22519 , 39261 ,0 }; - static ulong[] dim4627KuoInit = { 1 , 3 , 7 , 13 , 31 , 49 , 105 , 61 , 437 , 923 , 1579 , 1695 , 7129 , 10555 , 3177 , 6667 ,0 }; - static ulong[] dim4628KuoInit = { 1 , 1 , 5 , 7 , 3 , 47 , 29 , 159 , 207 , 969 , 433 , 3541 , 689 , 1255 , 1359 , 38349 ,0 }; - static ulong[] dim4629KuoInit = { 1 , 1 , 3 , 9 , 9 , 31 , 23 , 37 , 435 , 729 , 121 , 2483 , 8009 , 14229 , 6961 , 40681 ,0 }; - static ulong[] dim4630KuoInit = { 1 , 3 , 1 , 7 , 19 , 33 , 111 , 131 , 155 , 641 , 795 , 3753 , 4381 , 11135 , 8381 , 62553 ,0 }; - static ulong[] dim4631KuoInit = { 1 , 3 , 7 , 13 , 29 , 37 , 15 , 245 , 341 , 1023 , 1123 , 3317 , 2409 , 8957 , 4607 , 53947 ,0 }; - static ulong[] dim4632KuoInit = { 1 , 1 , 7 , 15 , 7 , 19 , 105 , 187 , 407 , 339 , 607 , 11 , 1679 , 13701 , 2385 , 6203 ,0 }; - static ulong[] dim4633KuoInit = { 1 , 3 , 3 , 9 , 7 , 63 , 7 , 173 , 475 , 87 , 807 , 1467 , 791 , 1949 , 20839 , 54179 ,0 }; - static ulong[] dim4634KuoInit = { 1 , 3 , 3 , 3 , 25 , 25 , 111 , 155 , 249 , 55 , 1455 , 2503 , 6869 , 14463 , 10519 , 56761 ,0 }; - static ulong[] dim4635KuoInit = { 1 , 3 , 1 , 9 , 9 , 31 , 89 , 235 , 499 , 61 , 747 , 487 , 6767 , 4777 , 12513 , 43677 ,0 }; - static ulong[] dim4636KuoInit = { 1 , 3 , 3 , 5 , 25 , 47 , 13 , 3 , 313 , 541 , 1323 , 3551 , 7971 , 1453 , 1531 , 38915 ,0 }; - static ulong[] dim4637KuoInit = { 1 , 1 , 1 , 5 , 7 , 63 , 125 , 243 , 199 , 875 , 791 , 103 , 3997 , 16199 , 20615 , 18359 ,0 }; - static ulong[] dim4638KuoInit = { 1 , 1 , 7 , 1 , 21 , 19 , 13 , 9 , 117 , 625 , 1333 , 561 , 889 , 10961 , 11313 , 48139 ,0 }; - static ulong[] dim4639KuoInit = { 1 , 3 , 5 , 9 , 19 , 57 , 121 , 163 , 333 , 681 , 1065 , 885 , 5961 , 6385 , 20135 , 19733 ,0 }; - static ulong[] dim4640KuoInit = { 1 , 1 , 7 , 13 , 27 , 11 , 113 , 187 , 91 , 83 , 591 , 517 , 7379 , 12823 , 31815 , 14721 ,0 }; - static ulong[] dim4641KuoInit = { 1 , 3 , 5 , 7 , 27 , 21 , 47 , 203 , 411 , 191 , 881 , 2597 , 6107 , 135 , 14525 , 4059 ,0 }; - static ulong[] dim4642KuoInit = { 1 , 3 , 5 , 7 , 29 , 3 , 61 , 231 , 259 , 425 , 1953 , 803 , 7921 , 2321 , 28919 , 41349 ,0 }; - static ulong[] dim4643KuoInit = { 1 , 3 , 1 , 1 , 27 , 7 , 87 , 197 , 287 , 345 , 457 , 1813 , 2701 , 2095 , 32705 , 52579 ,0 }; - static ulong[] dim4644KuoInit = { 1 , 3 , 3 , 9 , 13 , 59 , 87 , 105 , 49 , 387 , 73 , 2983 , 6453 , 10977 , 8851 , 61031 ,0 }; - static ulong[] dim4645KuoInit = { 1 , 3 , 5 , 7 , 1 , 53 , 121 , 129 , 307 , 251 , 1405 , 3093 , 4487 , 1953 , 2681 , 4391 ,0 }; - static ulong[] dim4646KuoInit = { 1 , 1 , 3 , 1 , 1 , 29 , 119 , 125 , 95 , 425 , 385 , 1577 , 3387 , 14709 , 25143 , 4317 ,0 }; - static ulong[] dim4647KuoInit = { 1 , 3 , 1 , 3 , 27 , 59 , 53 , 203 , 75 , 731 , 1019 , 3179 , 4533 , 3217 , 30801 , 53439 ,0 }; - static ulong[] dim4648KuoInit = { 1 , 1 , 3 , 11 , 29 , 53 , 93 , 251 , 441 , 75 , 363 , 2405 , 6263 , 12121 , 11963 , 13219 ,0 }; - static ulong[] dim4649KuoInit = { 1 , 3 , 1 , 13 , 3 , 7 , 57 , 169 , 387 , 543 , 1027 , 1169 , 5089 , 5077 , 17933 , 8131 ,0 }; - static ulong[] dim4650KuoInit = { 1 , 1 , 3 , 5 , 17 , 17 , 123 , 161 , 21 , 641 , 795 , 2415 , 2743 , 1489 , 25137 , 19393 ,0 }; - static ulong[] dim4651KuoInit = { 1 , 3 , 3 , 1 , 1 , 47 , 37 , 95 , 315 , 37 , 1481 , 2189 , 687 , 2859 , 5339 , 26907 ,0 }; - static ulong[] dim4652KuoInit = { 1 , 3 , 7 , 15 , 23 , 51 , 71 , 203 , 237 , 777 , 417 , 2767 , 5243 , 1453 , 17269 , 27679 ,0 }; - static ulong[] dim4653KuoInit = { 1 , 3 , 1 , 15 , 17 , 41 , 29 , 45 , 363 , 77 , 1071 , 3419 , 6453 , 13897 , 25275 , 26379 ,0 }; - static ulong[] dim4654KuoInit = { 1 , 3 , 7 , 11 , 21 , 5 , 89 , 133 , 339 , 971 , 1581 , 377 , 6563 , 13073 , 24521 , 41107 ,0 }; - static ulong[] dim4655KuoInit = { 1 , 1 , 7 , 15 , 1 , 27 , 57 , 249 , 511 , 833 , 269 , 2771 , 4127 , 12567 , 27359 , 22105 ,0 }; - static ulong[] dim4656KuoInit = { 1 , 1 , 3 , 5 , 31 , 47 , 63 , 221 , 25 , 869 , 1947 , 3075 , 6857 , 13507 , 16601 , 29621 ,0 }; - static ulong[] dim4657KuoInit = { 1 , 1 , 3 , 7 , 17 , 23 , 109 , 169 , 211 , 407 , 1147 , 2453 , 2281 , 10763 , 11539 , 49127 ,0 }; - static ulong[] dim4658KuoInit = { 1 , 1 , 3 , 11 , 27 , 25 , 111 , 75 , 465 , 67 , 1641 , 3623 , 7957 , 14307 , 17469 , 52229 ,0 }; - static ulong[] dim4659KuoInit = { 1 , 3 , 1 , 5 , 23 , 31 , 49 , 131 , 351 , 311 , 1937 , 2181 , 7485 , 10883 , 20843 , 33447 ,0 }; - static ulong[] dim4660KuoInit = { 1 , 3 , 1 , 3 , 5 , 47 , 81 , 47 , 305 , 567 , 219 , 2495 , 1207 , 14359 , 4683 , 53717 ,0 }; - static ulong[] dim4661KuoInit = { 1 , 1 , 3 , 3 , 29 , 43 , 107 , 81 , 227 , 795 , 1261 , 3887 , 6177 , 6219 , 2557 , 53203 ,0 }; - static ulong[] dim4662KuoInit = { 1 , 3 , 1 , 9 , 25 , 47 , 87 , 177 , 511 , 899 , 1967 , 601 , 3659 , 3961 , 27301 , 9497 ,0 }; - static ulong[] dim4663KuoInit = { 1 , 1 , 5 , 11 , 7 , 19 , 69 , 95 , 319 , 811 , 1539 , 931 , 6609 , 4325 , 4639 , 60125 ,0 }; - static ulong[] dim4664KuoInit = { 1 , 3 , 3 , 13 , 31 , 25 , 65 , 137 , 67 , 903 , 1519 , 3 , 81 , 9991 , 24985 , 12571 ,0 }; - static ulong[] dim4665KuoInit = { 1 , 3 , 1 , 15 , 13 , 45 , 87 , 95 , 185 , 531 , 591 , 3649 , 2289 , 6353 , 4305 , 12801 ,0 }; - static ulong[] dim4666KuoInit = { 1 , 3 , 7 , 11 , 13 , 49 , 79 , 205 , 9 , 457 , 151 , 3363 , 1865 , 12337 , 3601 , 23781 ,0 }; - static ulong[] dim4667KuoInit = { 1 , 3 , 3 , 7 , 21 , 7 , 117 , 177 , 327 , 547 , 385 , 301 , 5595 , 14389 , 8243 , 3133 ,0 }; - static ulong[] dim4668KuoInit = { 1 , 3 , 1 , 3 , 17 , 39 , 61 , 45 , 489 , 769 , 1893 , 1633 , 2645 , 10849 , 3827 , 41365 ,0 }; - static ulong[] dim4669KuoInit = { 1 , 1 , 1 , 11 , 11 , 43 , 93 , 81 , 497 , 731 , 1049 , 91 , 7979 , 4707 , 8757 , 54837 ,0 }; - static ulong[] dim4670KuoInit = { 1 , 1 , 3 , 7 , 1 , 63 , 127 , 173 , 137 , 291 , 473 , 3095 , 6291 , 14415 , 20763 , 45687 ,0 }; - static ulong[] dim4671KuoInit = { 1 , 1 , 5 , 13 , 29 , 59 , 73 , 47 , 171 , 1001 , 537 , 2009 , 5057 , 15013 , 22195 , 56067 ,0 }; - static ulong[] dim4672KuoInit = { 1 , 1 , 3 , 5 , 21 , 35 , 121 , 169 , 377 , 389 , 1209 , 415 , 2641 , 10423 , 11327 , 64157 ,0 }; - static ulong[] dim4673KuoInit = { 1 , 1 , 7 , 1 , 23 , 43 , 59 , 205 , 39 , 455 , 633 , 1965 , 7955 , 305 , 12245 , 45229 ,0 }; - static ulong[] dim4674KuoInit = { 1 , 3 , 1 , 15 , 15 , 27 , 49 , 77 , 407 , 549 , 1159 , 1701 , 7331 , 6421 , 1799 , 43539 ,0 }; - static ulong[] dim4675KuoInit = { 1 , 3 , 5 , 3 , 5 , 33 , 41 , 127 , 141 , 149 , 1957 , 2823 , 1303 , 7339 , 25253 , 32329 ,0 }; - static ulong[] dim4676KuoInit = { 1 , 1 , 5 , 15 , 5 , 37 , 119 , 111 , 329 , 781 , 983 , 2021 , 1191 , 1579 , 4191 , 24065 ,0 }; - static ulong[] dim4677KuoInit = { 1 , 3 , 7 , 9 , 7 , 11 , 25 , 111 , 301 , 819 , 1073 , 2311 , 2357 , 6385 , 17015 , 8051 ,0 }; - static ulong[] dim4678KuoInit = { 1 , 1 , 1 , 9 , 29 , 63 , 91 , 101 , 71 , 679 , 267 , 2909 , 5359 , 2305 , 2523 , 32423 ,0 }; - static ulong[] dim4679KuoInit = { 1 , 3 , 1 , 5 , 11 , 45 , 107 , 95 , 487 , 605 , 1647 , 1977 , 5305 , 8855 , 9057 , 7809 ,0 }; - static ulong[] dim4680KuoInit = { 1 , 1 , 1 , 1 , 5 , 45 , 51 , 51 , 97 , 775 , 1559 , 935 , 7421 , 2823 , 11415 , 49193 ,0 }; - static ulong[] dim4681KuoInit = { 1 , 3 , 3 , 5 , 23 , 63 , 99 , 189 , 175 , 77 , 675 , 4021 , 899 , 11315 , 18627 , 46175 ,0 }; - static ulong[] dim4682KuoInit = { 1 , 1 , 3 , 13 , 9 , 31 , 67 , 235 , 409 , 541 , 2013 , 2715 , 2121 , 3695 , 11953 , 5745 ,0 }; - static ulong[] dim4683KuoInit = { 1 , 3 , 5 , 1 , 13 , 3 , 15 , 111 , 455 , 849 , 231 , 2711 , 6831 , 7813 , 17173 , 26019 ,0 }; - static ulong[] dim4684KuoInit = { 1 , 1 , 1 , 15 , 19 , 3 , 21 , 135 , 275 , 891 , 61 , 5 , 2901 , 15727 , 18015 , 55741 ,0 }; - static ulong[] dim4685KuoInit = { 1 , 3 , 1 , 5 , 5 , 31 , 5 , 147 , 353 , 199 , 229 , 3821 , 537 , 11667 , 649 , 33923 ,0 }; - static ulong[] dim4686KuoInit = { 1 , 1 , 7 , 13 , 3 , 9 , 75 , 217 , 423 , 487 , 723 , 4091 , 7075 , 819 , 2755 , 13593 ,0 }; - static ulong[] dim4687KuoInit = { 1 , 1 , 1 , 9 , 25 , 45 , 69 , 41 , 183 , 547 , 69 , 3591 , 1331 , 5701 , 25891 , 26553 ,0 }; - static ulong[] dim4688KuoInit = { 1 , 3 , 3 , 13 , 29 , 51 , 79 , 153 , 145 , 923 , 1345 , 3113 , 93 , 10617 , 12865 , 27341 ,0 }; - static ulong[] dim4689KuoInit = { 1 , 3 , 3 , 13 , 13 , 61 , 67 , 115 , 295 , 767 , 1077 , 3959 , 7741 , 16145 , 3571 , 38941 ,0 }; - static ulong[] dim4690KuoInit = { 1 , 1 , 3 , 3 , 1 , 11 , 25 , 33 , 481 , 901 , 135 , 2093 , 3531 , 12137 , 4521 , 42301 ,0 }; - static ulong[] dim4691KuoInit = { 1 , 1 , 3 , 1 , 9 , 59 , 105 , 71 , 57 , 131 , 1491 , 3259 , 4125 , 10279 , 7537 , 38827 ,0 }; - static ulong[] dim4692KuoInit = { 1 , 3 , 7 , 13 , 7 , 53 , 83 , 43 , 243 , 423 , 43 , 2021 , 4269 , 1793 , 9969 , 55429 ,0 }; - static ulong[] dim4693KuoInit = { 1 , 1 , 3 , 11 , 17 , 57 , 73 , 55 , 369 , 975 , 603 , 1893 , 3299 , 12177 , 8965 , 17159 ,0 }; - static ulong[] dim4694KuoInit = { 1 , 3 , 5 , 11 , 23 , 11 , 61 , 11 , 119 , 905 , 1841 , 2597 , 691 , 6237 , 2285 , 33503 ,0 }; - static ulong[] dim4695KuoInit = { 1 , 3 , 5 , 3 , 21 , 17 , 35 , 169 , 511 , 1009 , 1287 , 3967 , 1543 , 6983 , 6895 , 24959 ,0 }; - static ulong[] dim4696KuoInit = { 1 , 1 , 1 , 13 , 23 , 9 , 21 , 47 , 119 , 323 , 1255 , 3601 , 3157 , 14041 , 32065 , 4759 ,0 }; - static ulong[] dim4697KuoInit = { 1 , 1 , 7 , 15 , 9 , 1 , 103 , 43 , 485 , 281 , 1651 , 1957 , 4215 , 2105 , 24455 , 51001 ,0 }; - static ulong[] dim4698KuoInit = { 1 , 1 , 5 , 7 , 11 , 11 , 59 , 31 , 351 , 275 , 573 , 2481 , 2545 , 15767 , 4319 , 63375 ,0 }; - static ulong[] dim4699KuoInit = { 1 , 3 , 1 , 1 , 1 , 41 , 41 , 13 , 33 , 693 , 1035 , 905 , 6129 , 11131 , 23571 , 28789 ,0 }; - static ulong[] dim4700KuoInit = { 1 , 1 , 7 , 11 , 9 , 39 , 119 , 31 , 109 , 837 , 1905 , 763 , 3737 , 16031 , 8751 , 17307 ,0 }; - static ulong[] dim4701KuoInit = { 1 , 3 , 3 , 7 , 17 , 49 , 77 , 199 , 33 , 185 , 1489 , 445 , 5495 , 13693 , 21453 , 21039 ,0 }; - static ulong[] dim4702KuoInit = { 1 , 3 , 5 , 15 , 5 , 9 , 113 , 179 , 315 , 85 , 1559 , 1505 , 593 , 259 , 10393 , 39025 ,0 }; - static ulong[] dim4703KuoInit = { 1 , 1 , 1 , 5 , 31 , 33 , 41 , 45 , 313 , 513 , 861 , 2697 , 4767 , 10737 , 25019 , 12715 ,0 }; - static ulong[] dim4704KuoInit = { 1 , 3 , 3 , 1 , 19 , 21 , 19 , 19 , 127 , 1009 , 859 , 829 , 6887 , 5407 , 28491 , 61079 ,0 }; - static ulong[] dim4705KuoInit = { 1 , 1 , 3 , 15 , 15 , 35 , 69 , 255 , 367 , 889 , 49 , 3237 , 3269 , 1559 , 26337 , 16967 ,0 }; - static ulong[] dim4706KuoInit = { 1 , 1 , 5 , 3 , 17 , 5 , 125 , 171 , 505 , 981 , 773 , 2973 , 2905 , 1537 , 17729 , 52289 ,0 }; - static ulong[] dim4707KuoInit = { 1 , 1 , 3 , 3 , 29 , 5 , 57 , 247 , 149 , 707 , 673 , 429 , 7583 , 12135 , 5405 , 313 ,0 }; - static ulong[] dim4708KuoInit = { 1 , 1 , 3 , 13 , 31 , 35 , 117 , 69 , 413 , 723 , 645 , 3989 , 6461 , 77 , 29713 , 32381 ,0 }; - static ulong[] dim4709KuoInit = { 1 , 3 , 3 , 13 , 11 , 59 , 5 , 53 , 507 , 355 , 335 , 4027 , 3111 , 8385 , 22369 , 42907 ,0 }; - static ulong[] dim4710KuoInit = { 1 , 1 , 5 , 9 , 1 , 47 , 87 , 13 , 397 , 693 , 1745 , 2907 , 3919 , 14843 , 869 , 24161 ,0 }; - static ulong[] dim4711KuoInit = { 1 , 3 , 7 , 13 , 11 , 25 , 25 , 153 , 501 , 305 , 941 , 2379 , 2587 , 8225 , 27951 , 14809 ,0 }; - static ulong[] dim4712KuoInit = { 1 , 1 , 7 , 3 , 31 , 7 , 9 , 47 , 129 , 611 , 1367 , 1575 , 4421 , 2277 , 8113 , 34229 ,0 }; - static ulong[] dim4713KuoInit = { 1 , 1 , 5 , 11 , 7 , 41 , 65 , 5 , 289 , 799 , 1143 , 291 , 243 , 12957 , 2729 , 14589 ,0 }; - static ulong[] dim4714KuoInit = { 1 , 3 , 3 , 7 , 15 , 29 , 49 , 243 , 191 , 565 , 271 , 2485 , 1507 , 13479 , 3541 , 10039 ,0 }; - static ulong[] dim4715KuoInit = { 1 , 3 , 5 , 3 , 25 , 29 , 113 , 157 , 357 , 891 , 199 , 3113 , 7133 , 11047 , 27517 , 26795 ,0 }; - static ulong[] dim4716KuoInit = { 1 , 1 , 3 , 15 , 27 , 23 , 5 , 207 , 183 , 85 , 247 , 15 , 5559 , 8005 , 32485 , 26403 ,0 }; - static ulong[] dim4717KuoInit = { 1 , 1 , 3 , 9 , 13 , 9 , 87 , 9 , 237 , 875 , 1621 , 2955 , 4105 , 9645 , 9613 , 31235 ,0 }; - static ulong[] dim4718KuoInit = { 1 , 1 , 7 , 11 , 17 , 3 , 77 , 241 , 75 , 433 , 1481 , 1901 , 6249 , 12411 , 18975 , 18911 ,0 }; - static ulong[] dim4719KuoInit = { 1 , 3 , 5 , 15 , 3 , 43 , 99 , 197 , 407 , 161 , 1103 , 587 , 6695 , 255 , 15571 , 7523 ,0 }; - static ulong[] dim4720KuoInit = { 1 , 1 , 1 , 13 , 1 , 21 , 9 , 155 , 447 , 785 , 1573 , 2497 , 1515 , 6031 , 23509 , 38199 ,0 }; - static ulong[] dim4721KuoInit = { 1 , 1 , 5 , 15 , 23 , 43 , 125 , 187 , 57 , 259 , 941 , 1213 , 2303 , 1127 , 31819 , 53539 ,0 }; - static ulong[] dim4722KuoInit = { 1 , 3 , 3 , 9 , 23 , 19 , 29 , 83 , 431 , 79 , 781 , 1887 , 4857 , 2079 , 11521 , 64925 ,0 }; - static ulong[] dim4723KuoInit = { 1 , 3 , 5 , 5 , 23 , 11 , 33 , 107 , 127 , 173 , 223 , 491 , 1529 , 14655 , 18857 , 25247 ,0 }; - static ulong[] dim4724KuoInit = { 1 , 3 , 3 , 9 , 17 , 53 , 119 , 159 , 503 , 153 , 697 , 657 , 6207 , 7659 , 23899 , 10347 ,0 }; - static ulong[] dim4725KuoInit = { 1 , 3 , 1 , 15 , 13 , 37 , 117 , 219 , 341 , 983 , 193 , 1641 , 7811 , 11961 , 12553 , 9467 ,0 }; - static ulong[] dim4726KuoInit = { 1 , 1 , 7 , 5 , 27 , 11 , 35 , 45 , 89 , 535 , 965 , 1269 , 1243 , 3987 , 4629 , 45335 ,0 }; - static ulong[] dim4727KuoInit = { 1 , 1 , 7 , 1 , 17 , 25 , 79 , 133 , 287 , 7 , 269 , 697 , 2537 , 241 , 15747 , 49429 ,0 }; - static ulong[] dim4728KuoInit = { 1 , 3 , 3 , 3 , 27 , 63 , 23 , 229 , 3 , 625 , 453 , 3037 , 5747 , 13525 , 28835 , 13411 ,0 }; - static ulong[] dim4729KuoInit = { 1 , 3 , 5 , 5 , 25 , 57 , 101 , 13 , 81 , 917 , 1849 , 3931 , 3319 , 1353 , 8253 , 28897 ,0 }; - static ulong[] dim4730KuoInit = { 1 , 1 , 3 , 15 , 3 , 41 , 89 , 165 , 1 , 935 , 1859 , 2881 , 4351 , 6737 , 12361 , 27821 ,0 }; - static ulong[] dim4731KuoInit = { 1 , 3 , 5 , 3 , 9 , 45 , 89 , 251 , 77 , 899 , 777 , 4063 , 8111 , 5953 , 26645 , 62567 ,0 }; - static ulong[] dim4732KuoInit = { 1 , 3 , 5 , 1 , 25 , 7 , 15 , 189 , 157 , 751 , 627 , 629 , 2875 , 11143 , 23841 , 58751 ,0 }; - static ulong[] dim4733KuoInit = { 1 , 1 , 1 , 9 , 7 , 43 , 95 , 171 , 311 , 809 , 971 , 1317 , 3521 , 15227 , 18155 , 11409 ,0 }; - static ulong[] dim4734KuoInit = { 1 , 3 , 3 , 7 , 29 , 7 , 69 , 1 , 235 , 699 , 971 , 3149 , 71 , 3609 , 859 , 17059 ,0 }; - static ulong[] dim4735KuoInit = { 1 , 3 , 1 , 1 , 3 , 43 , 3 , 181 , 465 , 843 , 1391 , 3313 , 8115 , 1835 , 32365 , 31303 ,0 }; - static ulong[] dim4736KuoInit = { 1 , 1 , 5 , 1 , 27 , 49 , 15 , 37 , 257 , 365 , 1577 , 3037 , 2767 , 8183 , 173 , 43089 ,0 }; - static ulong[] dim4737KuoInit = { 1 , 1 , 1 , 7 , 7 , 29 , 81 , 33 , 299 , 827 , 221 , 2049 , 1163 , 13023 , 6755 , 53987 ,0 }; - static ulong[] dim4738KuoInit = { 1 , 3 , 1 , 11 , 19 , 17 , 63 , 19 , 469 , 925 , 37 , 3291 , 2699 , 10083 , 32197 , 53749 ,0 }; - static ulong[] dim4739KuoInit = { 1 , 3 , 5 , 15 , 1 , 23 , 71 , 173 , 441 , 109 , 391 , 3611 , 7515 , 5095 , 26379 , 55999 ,0 }; - static ulong[] dim4740KuoInit = { 1 , 3 , 3 , 13 , 29 , 13 , 23 , 57 , 329 , 285 , 1595 , 2681 , 5427 , 3251 , 7025 , 3921 ,0 }; - static ulong[] dim4741KuoInit = { 1 , 1 , 1 , 13 , 7 , 45 , 121 , 19 , 19 , 317 , 1619 , 2245 , 7151 , 5797 , 31369 , 7765 ,0 }; - static ulong[] dim4742KuoInit = { 1 , 3 , 7 , 13 , 9 , 17 , 11 , 127 , 337 , 271 , 2005 , 787 , 1017 , 3075 , 29453 , 62275 ,0 }; - static ulong[] dim4743KuoInit = { 1 , 3 , 3 , 13 , 9 , 51 , 77 , 31 , 395 , 175 , 247 , 1021 , 4343 , 3829 , 959 , 12069 ,0 }; - static ulong[] dim4744KuoInit = { 1 , 3 , 1 , 9 , 21 , 33 , 3 , 129 , 327 , 13 , 1943 , 3305 , 6173 , 6903 , 32539 , 9525 ,0 }; - static ulong[] dim4745KuoInit = { 1 , 1 , 3 , 15 , 23 , 5 , 49 , 125 , 445 , 849 , 547 , 2911 , 7611 , 8137 , 28701 , 6883 ,0 }; - static ulong[] dim4746KuoInit = { 1 , 1 , 3 , 13 , 11 , 15 , 21 , 35 , 303 , 401 , 187 , 1981 , 7919 , 6179 , 15643 , 10327 ,0 }; - static ulong[] dim4747KuoInit = { 1 , 1 , 5 , 7 , 9 , 45 , 95 , 205 , 137 , 425 , 353 , 673 , 1337 , 4357 , 12521 , 55229 ,0 }; - static ulong[] dim4748KuoInit = { 1 , 3 , 5 , 5 , 29 , 47 , 93 , 213 , 357 , 821 , 467 , 395 , 5079 , 10341 , 24117 , 59757 ,0 }; - static ulong[] dim4749KuoInit = { 1 , 3 , 7 , 5 , 29 , 39 , 25 , 85 , 437 , 873 , 795 , 91 , 1979 , 15503 , 12157 , 6803 ,0 }; - static ulong[] dim4750KuoInit = { 1 , 3 , 7 , 1 , 31 , 21 , 31 , 245 , 79 , 661 , 323 , 1843 , 2225 , 15383 , 17507 , 30667 ,0 }; - static ulong[] dim4751KuoInit = { 1 , 3 , 5 , 11 , 1 , 11 , 119 , 151 , 489 , 303 , 835 , 319 , 2071 , 1497 , 10343 , 40641 ,0 }; - static ulong[] dim4752KuoInit = { 1 , 1 , 1 , 13 , 7 , 7 , 125 , 237 , 103 , 65 , 1917 , 2203 , 5895 , 8651 , 7331 , 27591 ,0 }; - static ulong[] dim4753KuoInit = { 1 , 3 , 3 , 15 , 21 , 17 , 73 , 21 , 485 , 985 , 253 , 1877 , 7423 , 6569 , 25971 , 57821 ,0 }; - static ulong[] dim4754KuoInit = { 1 , 3 , 5 , 13 , 3 , 59 , 9 , 77 , 99 , 851 , 343 , 2655 , 367 , 7253 , 16357 , 61563 ,0 }; - static ulong[] dim4755KuoInit = { 1 , 3 , 7 , 13 , 11 , 1 , 15 , 227 , 223 , 317 , 1111 , 2287 , 4035 , 6803 , 16787 , 27797 ,0 }; - static ulong[] dim4756KuoInit = { 1 , 3 , 3 , 5 , 17 , 49 , 103 , 191 , 245 , 473 , 2007 , 3297 , 6487 , 7371 , 30497 , 40255 ,0 }; - static ulong[] dim4757KuoInit = { 1 , 3 , 5 , 13 , 1 , 61 , 39 , 1 , 501 , 665 , 1085 , 3933 , 855 , 883 , 26949 , 48761 ,0 }; - static ulong[] dim4758KuoInit = { 1 , 3 , 3 , 13 , 29 , 39 , 5 , 43 , 39 , 529 , 1605 , 2235 , 5081 , 7467 , 20727 , 48611 ,0 }; - static ulong[] dim4759KuoInit = { 1 , 1 , 3 , 11 , 19 , 61 , 89 , 15 , 149 , 639 , 337 , 2953 , 2229 , 11161 , 21981 , 26003 ,0 }; - static ulong[] dim4760KuoInit = { 1 , 1 , 3 , 5 , 29 , 47 , 71 , 65 , 107 , 485 , 57 , 2255 , 4383 , 12383 , 18161 , 40233 ,0 }; - static ulong[] dim4761KuoInit = { 1 , 1 , 7 , 3 , 21 , 41 , 75 , 133 , 141 , 343 , 633 , 2043 , 2441 , 5479 , 2493 , 45707 ,0 }; - static ulong[] dim4762KuoInit = { 1 , 1 , 7 , 15 , 21 , 37 , 19 , 73 , 361 , 195 , 1007 , 1265 , 4075 , 1383 , 11809 , 64265 ,0 }; - static ulong[] dim4763KuoInit = { 1 , 1 , 5 , 11 , 19 , 63 , 21 , 163 , 349 , 961 , 1221 , 2265 , 4801 , 14049 , 8655 , 32823 ,0 }; - static ulong[] dim4764KuoInit = { 1 , 1 , 5 , 1 , 9 , 1 , 101 , 37 , 473 , 293 , 1191 , 791 , 5327 , 13739 , 21761 , 5755 ,0 }; - static ulong[] dim4765KuoInit = { 1 , 1 , 1 , 15 , 23 , 57 , 63 , 195 , 451 , 627 , 1725 , 2405 , 6943 , 6855 , 31563 , 44699 ,0 }; - static ulong[] dim4766KuoInit = { 1 , 3 , 7 , 1 , 31 , 41 , 51 , 177 , 95 , 961 , 1407 , 2847 , 7 , 8975 , 4017 , 46229 ,0 }; - static ulong[] dim4767KuoInit = { 1 , 1 , 3 , 13 , 19 , 9 , 67 , 183 , 255 , 1 , 1769 , 2585 , 2157 , 9747 , 32047 , 13063 ,0 }; - static ulong[] dim4768KuoInit = { 1 , 3 , 3 , 1 , 21 , 39 , 31 , 117 , 397 , 441 , 1443 , 3849 , 5993 , 13981 , 23579 , 40637 ,0 }; - static ulong[] dim4769KuoInit = { 1 , 1 , 7 , 1 , 31 , 23 , 61 , 203 , 111 , 273 , 1693 , 3031 , 4125 , 1527 , 30525 , 17465 ,0 }; - static ulong[] dim4770KuoInit = { 1 , 3 , 5 , 9 , 19 , 39 , 127 , 51 , 419 , 205 , 425 , 1939 , 3703 , 12009 , 6291 , 48639 ,0 }; - static ulong[] dim4771KuoInit = { 1 , 3 , 5 , 13 , 15 , 27 , 63 , 239 , 483 , 181 , 1621 , 3789 , 1929 , 11115 , 29385 , 53075 ,0 }; - static ulong[] dim4772KuoInit = { 1 , 1 , 1 , 9 , 13 , 9 , 61 , 15 , 221 , 163 , 1645 , 419 , 639 , 15081 , 2097 , 42133 ,0 }; - static ulong[] dim4773KuoInit = { 1 , 3 , 1 , 7 , 7 , 31 , 27 , 141 , 215 , 645 , 1293 , 2237 , 7129 , 12619 , 14563 , 46081 ,0 }; - static ulong[] dim4774KuoInit = { 1 , 3 , 1 , 13 , 3 , 41 , 85 , 37 , 295 , 815 , 1417 , 3083 , 5873 , 2037 , 29909 , 3817 ,0 }; - static ulong[] dim4775KuoInit = { 1 , 3 , 3 , 9 , 11 , 49 , 77 , 103 , 189 , 319 , 439 , 3547 , 173 , 1105 , 12125 , 49989 ,0 }; - static ulong[] dim4776KuoInit = { 1 , 3 , 1 , 15 , 21 , 9 , 5 , 37 , 87 , 905 , 145 , 1151 , 2213 , 4157 , 16171 , 56121 ,0 }; - static ulong[] dim4777KuoInit = { 1 , 3 , 5 , 3 , 15 , 21 , 91 , 103 , 367 , 423 , 101 , 327 , 3819 , 3141 , 3515 , 11433 ,0 }; - static ulong[] dim4778KuoInit = { 1 , 3 , 1 , 13 , 13 , 11 , 61 , 175 , 265 , 1011 , 1825 , 937 , 983 , 9575 , 6053 , 19633 ,0 }; - static ulong[] dim4779KuoInit = { 1 , 3 , 3 , 9 , 25 , 47 , 55 , 233 , 397 , 325 , 1217 , 1691 , 2751 , 5339 , 14269 , 28791 ,0 }; - static ulong[] dim4780KuoInit = { 1 , 1 , 7 , 15 , 15 , 51 , 29 , 215 , 47 , 713 , 1879 , 1981 , 3087 , 9945 , 8959 , 59367 ,0 }; - static ulong[] dim4781KuoInit = { 1 , 1 , 1 , 9 , 1 , 33 , 97 , 7 , 247 , 893 , 655 , 3137 , 6593 , 7261 , 11829 , 22101 ,0 }; - static ulong[] dim4782KuoInit = { 1 , 1 , 1 , 7 , 11 , 23 , 75 , 55 , 313 , 533 , 529 , 1929 , 3647 , 3317 , 2987 , 11917 ,0 }; - static ulong[] dim4783KuoInit = { 1 , 1 , 1 , 11 , 17 , 35 , 105 , 221 , 211 , 545 , 1595 , 1949 , 1895 , 39 , 7163 , 33303 ,0 }; - static ulong[] dim4784KuoInit = { 1 , 1 , 1 , 9 , 21 , 29 , 73 , 235 , 189 , 11 , 1747 , 1023 , 3987 , 10337 , 1689 , 64043 ,0 }; - static ulong[] dim4785KuoInit = { 1 , 3 , 1 , 5 , 11 , 17 , 115 , 57 , 465 , 899 , 1421 , 1329 , 6099 , 8081 , 11297 , 13217 ,0 }; - static ulong[] dim4786KuoInit = { 1 , 3 , 3 , 9 , 5 , 23 , 53 , 23 , 11 , 177 , 817 , 3003 , 5073 , 12071 , 11263 , 43159 ,0 }; - static ulong[] dim4787KuoInit = { 1 , 1 , 3 , 13 , 1 , 63 , 127 , 41 , 303 , 681 , 1559 , 2385 , 6265 , 2417 , 7063 , 57965 ,0 }; - static ulong[] dim4788KuoInit = { 1 , 3 , 1 , 1 , 3 , 21 , 21 , 37 , 485 , 771 , 2043 , 2065 , 7047 , 8867 , 7019 , 31437 ,0 }; - static ulong[] dim4789KuoInit = { 1 , 3 , 1 , 11 , 27 , 49 , 77 , 89 , 391 , 623 , 1675 , 1919 , 3575 , 2187 , 22801 , 11059 ,0 }; - static ulong[] dim4790KuoInit = { 1 , 1 , 3 , 5 , 9 , 57 , 51 , 255 , 287 , 851 , 1999 , 811 , 7769 , 11185 , 19279 , 65491 ,0 }; - static ulong[] dim4791KuoInit = { 1 , 3 , 1 , 15 , 31 , 43 , 113 , 11 , 461 , 95 , 841 , 2937 , 3969 , 5901 , 32681 , 9231 ,0 }; - static ulong[] dim4792KuoInit = { 1 , 3 , 3 , 5 , 31 , 47 , 21 , 187 , 171 , 249 , 787 , 459 , 6897 , 12131 , 14843 , 11805 ,0 }; - static ulong[] dim4793KuoInit = { 1 , 1 , 7 , 13 , 27 , 61 , 91 , 77 , 9 , 393 , 1231 , 1901 , 291 , 1487 , 22139 , 30569 ,0 }; - static ulong[] dim4794KuoInit = { 1 , 1 , 1 , 1 , 27 , 33 , 55 , 151 , 89 , 603 , 551 , 3767 , 695 , 15225 , 9665 , 60459 ,0 }; - static ulong[] dim4795KuoInit = { 1 , 1 , 7 , 13 , 31 , 19 , 83 , 27 , 381 , 105 , 481 , 3095 , 137 , 10433 , 12967 , 19555 ,0 }; - static ulong[] dim4796KuoInit = { 1 , 1 , 1 , 11 , 15 , 1 , 3 , 121 , 107 , 435 , 1571 , 3205 , 5213 , 3689 , 31365 , 14353 ,0 }; - static ulong[] dim4797KuoInit = { 1 , 3 , 7 , 11 , 23 , 61 , 93 , 59 , 179 , 361 , 965 , 413 , 7757 , 15779 , 1119 , 34673 ,0 }; - static ulong[] dim4798KuoInit = { 1 , 1 , 3 , 13 , 29 , 63 , 79 , 135 , 431 , 723 , 727 , 2685 , 1775 , 9027 , 27051 , 42581 ,0 }; - static ulong[] dim4799KuoInit = { 1 , 3 , 5 , 9 , 27 , 19 , 17 , 141 , 367 , 1021 , 651 , 2549 , 4003 , 15737 , 22063 , 12443 ,0 }; - static ulong[] dim4800KuoInit = { 1 , 1 , 1 , 11 , 23 , 27 , 35 , 225 , 399 , 173 , 451 , 1701 , 1093 , 5639 , 1855 , 1817 ,0 }; - static ulong[] dim4801KuoInit = { 1 , 3 , 7 , 11 , 23 , 63 , 119 , 13 , 147 , 997 , 53 , 3127 , 101 , 6633 , 14377 , 61843 ,0 }; - static ulong[] dim4802KuoInit = { 1 , 1 , 1 , 15 , 23 , 21 , 65 , 213 , 311 , 789 , 1395 , 1239 , 241 , 15041 , 14683 , 27805 ,0 }; - static ulong[] dim4803KuoInit = { 1 , 3 , 3 , 9 , 7 , 29 , 83 , 153 , 231 , 337 , 153 , 3097 , 6137 , 11003 , 31091 , 57005 ,0 }; - static ulong[] dim4804KuoInit = { 1 , 3 , 7 , 9 , 19 , 33 , 91 , 235 , 123 , 747 , 1331 , 2307 , 3791 , 2063 , 23613 , 3589 ,0 }; - static ulong[] dim4805KuoInit = { 1 , 3 , 3 , 15 , 9 , 25 , 95 , 237 , 381 , 349 , 1339 , 3187 , 2387 , 3487 , 4149 , 39343 ,0 }; - static ulong[] dim4806KuoInit = { 1 , 1 , 1 , 13 , 5 , 3 , 43 , 193 , 431 , 853 , 1419 , 905 , 2395 , 11459 , 26109 , 31277 ,0 }; - static ulong[] dim4807KuoInit = { 1 , 3 , 1 , 15 , 13 , 29 , 13 , 253 , 475 , 81 , 1199 , 841 , 7385 , 2609 , 10445 , 11151 ,0 }; - static ulong[] dim4808KuoInit = { 1 , 1 , 7 , 15 , 29 , 11 , 81 , 91 , 287 , 615 , 949 , 2541 , 5059 , 12567 , 9547 , 45647 ,0 }; - static ulong[] dim4809KuoInit = { 1 , 3 , 7 , 13 , 9 , 27 , 123 , 165 , 249 , 457 , 607 , 1203 , 987 , 4477 , 21205 , 44547 ,0 }; - static ulong[] dim4810KuoInit = { 1 , 1 , 3 , 15 , 3 , 1 , 37 , 43 , 445 , 205 , 1849 , 3461 , 7667 , 209 , 8773 , 1507 ,0 }; - static ulong[] dim4811KuoInit = { 1 , 3 , 1 , 3 , 27 , 43 , 75 , 199 , 185 , 249 , 725 , 301 , 2181 , 6859 , 16825 , 3471 ,0 }; - static ulong[] dim4812KuoInit = { 1 , 3 , 1 , 9 , 29 , 5 , 55 , 5 , 345 , 325 , 1853 , 3925 , 1739 , 14991 , 27845 , 6931 ,0 }; - static ulong[] dim4813KuoInit = { 1 , 1 , 3 , 5 , 31 , 15 , 33 , 47 , 201 , 649 , 415 , 639 , 391 , 12065 , 17343 , 3063 ,0 }; - static ulong[] dim4814KuoInit = { 1 , 1 , 7 , 11 , 19 , 37 , 39 , 77 , 367 , 29 , 1251 , 2637 , 5601 , 10661 , 17647 , 22131 ,0 }; - static ulong[] dim4815KuoInit = { 1 , 1 , 7 , 15 , 29 , 51 , 13 , 129 , 279 , 427 , 1535 , 2185 , 2651 , 8251 , 14857 , 61467 ,0 }; - static ulong[] dim4816KuoInit = { 1 , 1 , 7 , 5 , 25 , 55 , 45 , 105 , 213 , 31 , 735 , 3795 , 6627 , 14299 , 3155 , 3659 ,0 }; - static ulong[] dim4817KuoInit = { 1 , 1 , 1 , 9 , 21 , 27 , 21 , 85 , 315 , 793 , 1663 , 437 , 4113 , 4639 , 11321 , 13633 ,0 }; - static ulong[] dim4818KuoInit = { 1 , 3 , 5 , 9 , 23 , 17 , 49 , 35 , 451 , 799 , 1451 , 539 , 4549 , 43 , 1901 , 21155 ,0 }; - static ulong[] dim4819KuoInit = { 1 , 3 , 7 , 9 , 23 , 53 , 25 , 71 , 371 , 1005 , 129 , 157 , 2977 , 15823 , 30393 , 55629 ,0 }; - static ulong[] dim4820KuoInit = { 1 , 1 , 7 , 7 , 9 , 27 , 79 , 101 , 147 , 511 , 199 , 2843 , 101 , 14975 , 3455 , 843 ,0 }; - static ulong[] dim4821KuoInit = { 1 , 3 , 1 , 7 , 11 , 33 , 43 , 7 , 445 , 501 , 1071 , 1851 , 5763 , 5233 , 16121 , 23357 ,0 }; - static ulong[] dim4822KuoInit = { 1 , 1 , 1 , 13 , 11 , 21 , 75 , 153 , 421 , 311 , 1709 , 3745 , 2971 , 11219 , 23107 , 40057 ,0 }; - static ulong[] dim4823KuoInit = { 1 , 1 , 3 , 15 , 17 , 39 , 17 , 165 , 103 , 31 , 575 , 3945 , 1921 , 11305 , 13417 , 20603 ,0 }; - static ulong[] dim4824KuoInit = { 1 , 3 , 3 , 3 , 5 , 49 , 37 , 61 , 177 , 595 , 1133 , 1883 , 819 , 5137 , 10423 , 42009 ,0 }; - static ulong[] dim4825KuoInit = { 1 , 1 , 3 , 5 , 5 , 15 , 89 , 191 , 97 , 1017 , 205 , 4037 , 3431 , 13877 , 29867 , 26041 ,0 }; - static ulong[] dim4826KuoInit = { 1 , 3 , 3 , 7 , 9 , 9 , 109 , 157 , 357 , 815 , 1539 , 3507 , 1379 , 1105 , 14387 , 46689 ,0 }; - static ulong[] dim4827KuoInit = { 1 , 3 , 3 , 9 , 3 , 11 , 77 , 161 , 473 , 619 , 741 , 2945 , 5123 , 3325 , 8679 , 36167 ,0 }; - static ulong[] dim4828KuoInit = { 1 , 1 , 1 , 9 , 9 , 53 , 3 , 77 , 319 , 223 , 875 , 425 , 1369 , 509 , 25895 , 32803 ,0 }; - static ulong[] dim4829KuoInit = { 1 , 1 , 3 , 13 , 31 , 15 , 113 , 133 , 473 , 29 , 1009 , 1385 , 871 , 15785 , 1015 , 42627 ,0 }; - static ulong[] dim4830KuoInit = { 1 , 3 , 7 , 13 , 5 , 53 , 123 , 7 , 465 , 485 , 1413 , 1663 , 6541 , 13051 , 12251 , 36151 ,0 }; - static ulong[] dim4831KuoInit = { 1 , 1 , 1 , 13 , 9 , 21 , 123 , 223 , 483 , 849 , 489 , 3905 , 4697 , 7583 , 5373 , 62397 ,0 }; - static ulong[] dim4832KuoInit = { 1 , 1 , 7 , 9 , 29 , 53 , 85 , 151 , 511 , 917 , 1719 , 937 , 2035 , 6385 , 23529 , 62213 ,0 }; - static ulong[] dim4833KuoInit = { 1 , 1 , 3 , 15 , 11 , 47 , 111 , 79 , 377 , 585 , 475 , 3201 , 7025 , 1483 , 8815 , 47235 ,0 }; - static ulong[] dim4834KuoInit = { 1 , 1 , 3 , 13 , 13 , 5 , 39 , 31 , 71 , 39 , 941 , 2215 , 2195 , 2827 , 24353 , 18435 ,0 }; - static ulong[] dim4835KuoInit = { 1 , 1 , 7 , 15 , 13 , 31 , 31 , 15 , 421 , 81 , 895 , 1345 , 7049 , 4373 , 28005 , 41781 ,0 }; - static ulong[] dim4836KuoInit = { 1 , 1 , 3 , 15 , 17 , 57 , 21 , 175 , 453 , 755 , 1295 , 353 , 5257 , 15901 , 15643 , 31725 ,0 }; - static ulong[] dim4837KuoInit = { 1 , 1 , 1 , 9 , 17 , 17 , 71 , 209 , 155 , 511 , 1461 , 3313 , 7515 , 8407 , 9561 , 48169 ,0 }; - static ulong[] dim4838KuoInit = { 1 , 3 , 7 , 15 , 23 , 59 , 89 , 39 , 85 , 857 , 1285 , 3099 , 6497 , 5501 , 21321 , 34319 ,0 }; - static ulong[] dim4839KuoInit = { 1 , 3 , 5 , 5 , 27 , 13 , 41 , 1 , 191 , 275 , 1567 , 895 , 13 , 673 , 10079 , 55075 ,0 }; - static ulong[] dim4840KuoInit = { 1 , 1 , 7 , 15 , 9 , 33 , 33 , 35 , 55 , 597 , 365 , 3205 , 6427 , 837 , 16011 , 23279 ,0 }; - static ulong[] dim4841KuoInit = { 1 , 3 , 5 , 11 , 23 , 23 , 9 , 79 , 383 , 303 , 1715 , 1651 , 7507 , 14553 , 30715 , 56659 ,0 }; - static ulong[] dim4842KuoInit = { 1 , 3 , 1 , 11 , 1 , 61 , 31 , 85 , 181 , 593 , 1783 , 901 , 6069 , 1521 , 13275 , 18057 ,0 }; - static ulong[] dim4843KuoInit = { 1 , 3 , 1 , 13 , 23 , 59 , 111 , 221 , 47 , 599 , 193 , 1547 , 4077 , 15271 , 19315 , 1115 ,0 }; - static ulong[] dim4844KuoInit = { 1 , 3 , 7 , 7 , 23 , 53 , 115 , 69 , 19 , 409 , 1041 , 3395 , 6429 , 9263 , 21637 , 35533 ,0 }; - static ulong[] dim4845KuoInit = { 1 , 1 , 7 , 1 , 31 , 45 , 43 , 251 , 163 , 907 , 761 , 2009 , 3807 , 1529 , 12001 , 38823 ,0 }; - static ulong[] dim4846KuoInit = { 1 , 3 , 5 , 3 , 3 , 59 , 87 , 247 , 179 , 931 , 709 , 53 , 6283 , 13723 , 15407 , 22417 ,0 }; - static ulong[] dim4847KuoInit = { 1 , 1 , 1 , 5 , 27 , 17 , 21 , 183 , 393 , 177 , 1187 , 19 , 5409 , 2539 , 17401 , 29287 ,0 }; - static ulong[] dim4848KuoInit = { 1 , 1 , 5 , 15 , 3 , 51 , 91 , 95 , 389 , 855 , 1453 , 2815 , 7507 , 5449 , 12459 , 59111 ,0 }; - static ulong[] dim4849KuoInit = { 1 , 1 , 5 , 3 , 7 , 53 , 101 , 255 , 395 , 345 , 915 , 1649 , 6641 , 7771 , 20747 , 17067 ,0 }; - static ulong[] dim4850KuoInit = { 1 , 3 , 1 , 7 , 5 , 35 , 69 , 63 , 249 , 189 , 1937 , 965 , 3463 , 13615 , 12449 , 11891 ,0 }; - static ulong[] dim4851KuoInit = { 1 , 3 , 3 , 9 , 5 , 59 , 57 , 187 , 403 , 825 , 1291 , 2995 , 6365 , 15995 , 6871 , 25785 ,0 }; - static ulong[] dim4852KuoInit = { 1 , 3 , 5 , 15 , 17 , 23 , 117 , 103 , 131 , 601 , 1259 , 1331 , 3039 , 4761 , 8105 , 14521 ,0 }; - static ulong[] dim4853KuoInit = { 1 , 1 , 3 , 15 , 27 , 51 , 97 , 221 , 345 , 615 , 487 , 2535 , 139 , 16233 , 16271 , 713 ,0 }; - static ulong[] dim4854KuoInit = { 1 , 3 , 7 , 13 , 25 , 49 , 99 , 71 , 353 , 1015 , 1889 , 689 , 1925 , 6523 , 30995 , 23057 ,0 }; - static ulong[] dim4855KuoInit = { 1 , 3 , 5 , 9 , 21 , 55 , 11 , 29 , 477 , 581 , 1719 , 2603 , 1757 , 3995 , 27025 , 62833 ,0 }; - static ulong[] dim4856KuoInit = { 1 , 3 , 1 , 9 , 9 , 39 , 9 , 121 , 459 , 991 , 2021 , 1469 , 2399 , 4441 , 11829 , 36865 ,0 }; - static ulong[] dim4857KuoInit = { 1 , 3 , 1 , 5 , 9 , 13 , 115 , 27 , 487 , 307 , 453 , 351 , 885 , 12539 , 39 , 33887 ,0 }; - static ulong[] dim4858KuoInit = { 1 , 3 , 1 , 7 , 23 , 35 , 87 , 131 , 129 , 1 , 2015 , 3921 , 1309 , 7915 , 16661 , 45945 ,0 }; - static ulong[] dim4859KuoInit = { 1 , 3 , 1 , 3 , 1 , 15 , 93 , 255 , 285 , 915 , 563 , 527 , 7763 , 4581 , 11161 , 64619 ,0 }; - static ulong[] dim4860KuoInit = { 1 , 3 , 3 , 9 , 31 , 37 , 87 , 81 , 313 , 647 , 1065 , 863 , 6121 , 1385 , 26171 , 56323 ,0 }; - static ulong[] dim4861KuoInit = { 1 , 1 , 3 , 7 , 25 , 49 , 23 , 107 , 507 , 511 , 951 , 669 , 67 , 14319 , 17669 , 32497 ,0 }; - static ulong[] dim4862KuoInit = { 1 , 3 , 1 , 13 , 9 , 33 , 93 , 171 , 457 , 687 , 703 , 1073 , 3699 , 7029 , 28983 , 14501 ,0 }; - static ulong[] dim4863KuoInit = { 1 , 1 , 7 , 13 , 29 , 3 , 19 , 173 , 131 , 285 , 469 , 1223 , 7779 , 15367 , 643 , 63715 ,0 }; - static ulong[] dim4864KuoInit = { 1 , 3 , 7 , 5 , 5 , 37 , 21 , 223 , 227 , 939 , 1205 , 3167 , 5535 , 11543 , 7411 , 30841 ,0 }; - static ulong[] dim4865KuoInit = { 1 , 3 , 5 , 11 , 31 , 37 , 75 , 39 , 171 , 135 , 1487 , 3503 , 7939 , 77 , 19745 , 2551 ,0 }; - static ulong[] dim4866KuoInit = { 1 , 3 , 5 , 13 , 25 , 33 , 79 , 213 , 289 , 27 , 1435 , 1839 , 3089 , 8173 , 27555 , 20599 ,0 }; - static ulong[] dim4867KuoInit = { 1 , 1 , 3 , 13 , 19 , 31 , 67 , 9 , 229 , 591 , 561 , 3797 , 1833 , 3311 , 16053 , 61183 ,0 }; - static ulong[] dim4868KuoInit = { 1 , 1 , 3 , 3 , 27 , 27 , 79 , 95 , 7 , 1023 , 517 , 3627 , 4117 , 8165 , 17961 , 39011 ,0 }; - static ulong[] dim4869KuoInit = { 1 , 3 , 5 , 3 , 3 , 43 , 37 , 231 , 389 , 367 , 517 , 3117 , 2643 , 2103 , 127 , 42669 ,0 }; - static ulong[] dim4870KuoInit = { 1 , 1 , 1 , 11 , 11 , 49 , 35 , 71 , 295 , 87 , 1653 , 1899 , 1177 , 16071 , 8429 , 54751 ,0 }; - static ulong[] dim4871KuoInit = { 1 , 1 , 7 , 13 , 5 , 47 , 7 , 229 , 261 , 837 , 645 , 1581 , 159 , 73 , 10233 , 18557 ,0 }; - static ulong[] dim4872KuoInit = { 1 , 3 , 1 , 9 , 11 , 45 , 25 , 3 , 271 , 1005 , 1193 , 507 , 269 , 14689 , 7601 , 56781 ,0 }; - static ulong[] dim4873KuoInit = { 1 , 1 , 5 , 11 , 13 , 61 , 107 , 29 , 155 , 415 , 1435 , 1979 , 7339 , 1839 , 21097 , 5851 ,0 }; - static ulong[] dim4874KuoInit = { 1 , 1 , 5 , 9 , 9 , 27 , 83 , 163 , 15 , 539 , 765 , 463 , 7493 , 1413 , 15597 , 42819 ,0 }; - static ulong[] dim4875KuoInit = { 1 , 3 , 1 , 9 , 21 , 7 , 91 , 213 , 463 , 827 , 1847 , 2825 , 2115 , 14549 , 29923 , 61355 ,0 }; - static ulong[] dim4876KuoInit = { 1 , 1 , 3 , 15 , 1 , 55 , 69 , 85 , 7 , 847 , 1935 , 3225 , 693 , 12069 , 26303 , 19143 ,0 }; - static ulong[] dim4877KuoInit = { 1 , 3 , 1 , 11 , 15 , 47 , 53 , 181 , 327 , 493 , 483 , 999 , 4421 , 6707 , 27933 , 11533 ,0 }; - static ulong[] dim4878KuoInit = { 1 , 3 , 3 , 3 , 23 , 7 , 7 , 63 , 235 , 493 , 937 , 2935 , 2869 , 14243 , 30975 , 12881 ,0 }; - static ulong[] dim4879KuoInit = { 1 , 1 , 3 , 9 , 9 , 7 , 113 , 203 , 297 , 183 , 1687 , 3211 , 8131 , 7033 , 15007 , 1307 ,0 }; - static ulong[] dim4880KuoInit = { 1 , 3 , 1 , 9 , 9 , 39 , 99 , 5 , 61 , 435 , 427 , 2719 , 7741 , 4267 , 2423 , 37573 ,0 }; - static ulong[] dim4881KuoInit = { 1 , 3 , 7 , 3 , 17 , 1 , 105 , 13 , 89 , 693 , 1835 , 2455 , 1135 , 15545 , 2447 , 25673 ,0 }; - static ulong[] dim4882KuoInit = { 1 , 3 , 5 , 5 , 15 , 47 , 103 , 167 , 21 , 791 , 1297 , 3523 , 4427 , 7013 , 1845 , 44461 ,0 }; - static ulong[] dim4883KuoInit = { 1 , 1 , 5 , 7 , 11 , 17 , 55 , 247 , 317 , 229 , 1465 , 3781 , 2397 , 10541 , 8943 , 29155 ,0 }; - static ulong[] dim4884KuoInit = { 1 , 1 , 5 , 3 , 17 , 17 , 97 , 141 , 153 , 883 , 449 , 1163 , 3165 , 125 , 4689 , 44461 ,0 }; - static ulong[] dim4885KuoInit = { 1 , 3 , 7 , 1 , 17 , 13 , 9 , 235 , 87 , 251 , 57 , 2769 , 4845 , 5733 , 4305 , 49489 ,0 }; - static ulong[] dim4886KuoInit = { 1 , 1 , 7 , 1 , 9 , 41 , 79 , 97 , 201 , 789 , 37 , 2593 , 8023 , 139 , 30623 , 7667 ,0 }; - static ulong[] dim4887KuoInit = { 1 , 1 , 7 , 7 , 7 , 27 , 9 , 99 , 199 , 163 , 1175 , 729 , 2731 , 4391 , 27597 , 23087 ,0 }; - static ulong[] dim4888KuoInit = { 1 , 3 , 5 , 5 , 29 , 39 , 5 , 129 , 395 , 1007 , 1751 , 3951 , 5879 , 13105 , 26223 , 31361 ,0 }; - static ulong[] dim4889KuoInit = { 1 , 3 , 5 , 3 , 3 , 55 , 89 , 253 , 207 , 553 , 1407 , 2277 , 6879 , 16027 , 23477 , 43633 ,0 }; - static ulong[] dim4890KuoInit = { 1 , 1 , 1 , 3 , 13 , 21 , 9 , 149 , 31 , 359 , 1631 , 2199 , 2937 , 15663 , 5899 , 59959 ,0 }; - static ulong[] dim4891KuoInit = { 1 , 1 , 1 , 7 , 25 , 63 , 87 , 13 , 179 , 237 , 359 , 3841 , 6467 , 5621 , 29459 , 31339 ,0 }; - static ulong[] dim4892KuoInit = { 1 , 1 , 1 , 15 , 25 , 45 , 77 , 17 , 419 , 759 , 1045 , 1285 , 6739 , 11035 , 11401 , 44821 ,0 }; - static ulong[] dim4893KuoInit = { 1 , 3 , 7 , 1 , 31 , 47 , 17 , 237 , 69 , 389 , 1251 , 1205 , 833 , 2313 , 17005 , 32683 ,0 }; - static ulong[] dim4894KuoInit = { 1 , 1 , 7 , 9 , 13 , 19 , 51 , 69 , 261 , 85 , 215 , 2215 , 1643 , 12985 , 10363 , 17123 ,0 }; - static ulong[] dim4895KuoInit = { 1 , 3 , 1 , 3 , 3 , 51 , 41 , 173 , 161 , 633 , 1727 , 3089 , 7791 , 7367 , 32641 , 14361 ,0 }; - static ulong[] dim4896KuoInit = { 1 , 3 , 5 , 3 , 21 , 49 , 19 , 243 , 427 , 589 , 1699 , 2187 , 4177 , 927 , 6201 , 46319 ,0 }; - static ulong[] dim4897KuoInit = { 1 , 1 , 3 , 11 , 1 , 59 , 49 , 235 , 345 , 731 , 793 , 1893 , 4735 , 10647 , 31169 , 12051 ,0 }; - static ulong[] dim4898KuoInit = { 1 , 1 , 7 , 15 , 23 , 51 , 67 , 151 , 253 , 793 , 1673 , 3255 , 4919 , 11309 , 24903 , 9083 ,0 }; - static ulong[] dim4899KuoInit = { 1 , 3 , 3 , 9 , 7 , 59 , 41 , 225 , 397 , 671 , 513 , 1351 , 2835 , 15789 , 17679 , 28641 ,0 }; - static ulong[] dim4900KuoInit = { 1 , 3 , 1 , 7 , 17 , 39 , 49 , 103 , 181 , 375 , 1843 , 1183 , 4219 , 2931 , 18385 , 1203 ,0 }; - static ulong[] dim4901KuoInit = { 1 , 1 , 1 , 3 , 29 , 19 , 113 , 55 , 81 , 69 , 1541 , 3249 , 643 , 841 , 6053 , 63571 ,0 }; - static ulong[] dim4902KuoInit = { 1 , 1 , 7 , 5 , 1 , 3 , 39 , 237 , 283 , 283 , 813 , 3539 , 5899 , 8489 , 18393 , 22371 ,0 }; - static ulong[] dim4903KuoInit = { 1 , 3 , 7 , 13 , 5 , 53 , 15 , 129 , 95 , 181 , 657 , 3735 , 7517 , 2435 , 17245 , 4075 ,0 }; - static ulong[] dim4904KuoInit = { 1 , 1 , 5 , 3 , 9 , 37 , 73 , 95 , 175 , 989 , 1443 , 1745 , 8117 , 5867 , 29729 , 28441 ,0 }; - static ulong[] dim4905KuoInit = { 1 , 3 , 3 , 11 , 5 , 41 , 25 , 3 , 177 , 735 , 187 , 357 , 5365 , 8161 , 2071 , 41651 ,0 }; - static ulong[] dim4906KuoInit = { 1 , 1 , 1 , 15 , 29 , 47 , 27 , 233 , 177 , 339 , 1839 , 1761 , 5483 , 7203 , 32411 , 59859 ,0 }; - static ulong[] dim4907KuoInit = { 1 , 3 , 7 , 9 , 13 , 59 , 25 , 17 , 157 , 247 , 697 , 4011 , 4539 , 4253 , 1381 , 63009 ,0 }; - static ulong[] dim4908KuoInit = { 1 , 1 , 5 , 13 , 19 , 21 , 19 , 161 , 325 , 389 , 1067 , 525 , 529 , 277 , 13775 , 52265 ,0 }; - static ulong[] dim4909KuoInit = { 1 , 1 , 5 , 13 , 21 , 17 , 77 , 191 , 329 , 627 , 1857 , 1705 , 2207 , 5329 , 29833 , 1523 ,0 }; - static ulong[] dim4910KuoInit = { 1 , 3 , 3 , 1 , 21 , 3 , 107 , 85 , 29 , 887 , 793 , 1089 , 1361 , 10361 , 15869 , 1659 ,0 }; - static ulong[] dim4911KuoInit = { 1 , 1 , 1 , 15 , 11 , 47 , 85 , 137 , 373 , 777 , 875 , 2735 , 4381 , 8831 , 5891 , 44809 ,0 }; - static ulong[] dim4912KuoInit = { 1 , 1 , 1 , 11 , 19 , 9 , 77 , 59 , 497 , 643 , 51 , 3115 , 7267 , 11927 , 28119 , 28151 ,0 }; - static ulong[] dim4913KuoInit = { 1 , 3 , 1 , 3 , 13 , 27 , 55 , 201 , 319 , 167 , 1435 , 2197 , 5049 , 5923 , 12759 , 62383 ,0 }; - static ulong[] dim4914KuoInit = { 1 , 3 , 1 , 3 , 23 , 43 , 45 , 193 , 221 , 647 , 1933 , 2915 , 6461 , 4927 , 22105 , 54557 ,0 }; - static ulong[] dim4915KuoInit = { 1 , 1 , 5 , 11 , 5 , 23 , 67 , 59 , 79 , 507 , 925 , 3015 , 317 , 3887 , 29967 , 17205 ,0 }; - static ulong[] dim4916KuoInit = { 1 , 3 , 7 , 7 , 19 , 39 , 51 , 159 , 485 , 315 , 1739 , 2617 , 8017 , 11655 , 1141 , 26055 ,0 }; - static ulong[] dim4917KuoInit = { 1 , 1 , 3 , 1 , 27 , 53 , 119 , 113 , 135 , 85 , 2023 , 1659 , 307 , 8189 , 28339 , 53297 ,0 }; - static ulong[] dim4918KuoInit = { 1 , 3 , 3 , 5 , 9 , 61 , 57 , 225 , 137 , 381 , 1045 , 1253 , 1185 , 9885 , 30153 , 29355 ,0 }; - static ulong[] dim4919KuoInit = { 1 , 1 , 3 , 5 , 19 , 9 , 87 , 87 , 393 , 421 , 1941 , 57 , 2483 , 10855 , 26741 , 28091 ,0 }; - static ulong[] dim4920KuoInit = { 1 , 1 , 7 , 5 , 3 , 35 , 35 , 137 , 123 , 327 , 933 , 3429 , 281 , 1705 , 17123 , 29337 ,0 }; - static ulong[] dim4921KuoInit = { 1 , 3 , 7 , 13 , 9 , 61 , 111 , 207 , 45 , 57 , 1093 , 2223 , 575 , 11959 , 21147 , 30273 ,0 }; - static ulong[] dim4922KuoInit = { 1 , 1 , 5 , 5 , 31 , 37 , 123 , 5 , 277 , 273 , 525 , 1773 , 2685 , 11607 , 32079 , 25199 ,0 }; - static ulong[] dim4923KuoInit = { 1 , 1 , 7 , 11 , 5 , 29 , 121 , 193 , 437 , 417 , 1521 , 3057 , 4681 , 2773 , 5391 , 59747 ,0 }; - static ulong[] dim4924KuoInit = { 1 , 3 , 7 , 11 , 27 , 3 , 103 , 17 , 395 , 695 , 1731 , 4055 , 2727 , 2171 , 26893 , 7047 ,0 }; - static ulong[] dim4925KuoInit = { 1 , 3 , 7 , 5 , 23 , 9 , 25 , 167 , 241 , 755 , 1789 , 1977 , 6325 , 5425 , 23247 , 64181 ,0 }; - - static ulong[][] Kuoinitializers = { - dim1KuoInit, - dim2KuoInit, - dim3KuoInit, - dim4KuoInit, - dim5KuoInit, - dim6KuoInit, - dim7KuoInit, - dim8KuoInit, - dim9KuoInit, - dim10KuoInit, - dim11KuoInit, - dim12KuoInit, - dim13KuoInit, - dim14KuoInit, - dim15KuoInit, - dim16KuoInit, - dim17KuoInit, - dim18KuoInit, - dim19KuoInit, - dim20KuoInit, - dim21KuoInit, - dim22KuoInit, - dim23KuoInit, - dim24KuoInit, - dim25KuoInit, - dim26KuoInit, - dim27KuoInit, - dim28KuoInit, - dim29KuoInit, - dim30KuoInit, - dim31KuoInit, - dim32KuoInit, - dim33KuoInit, - dim34KuoInit, - dim35KuoInit, - dim36KuoInit, - dim37KuoInit, - dim38KuoInit, - dim39KuoInit, - dim40KuoInit, - dim41KuoInit, - dim42KuoInit, - dim43KuoInit, - dim44KuoInit, - dim45KuoInit, - dim46KuoInit, - dim47KuoInit, - dim48KuoInit, - dim49KuoInit, - dim50KuoInit, - dim51KuoInit, - dim52KuoInit, - dim53KuoInit, - dim54KuoInit, - dim55KuoInit, - dim56KuoInit, - dim57KuoInit, - dim58KuoInit, - dim59KuoInit, - dim60KuoInit, - dim61KuoInit, - dim62KuoInit, - dim63KuoInit, - dim64KuoInit, - dim65KuoInit, - dim66KuoInit, - dim67KuoInit, - dim68KuoInit, - dim69KuoInit, - dim70KuoInit, - dim71KuoInit, - dim72KuoInit, - dim73KuoInit, - dim74KuoInit, - dim75KuoInit, - dim76KuoInit, - dim77KuoInit, - dim78KuoInit, - dim79KuoInit, - dim80KuoInit, - dim81KuoInit, - dim82KuoInit, - dim83KuoInit, - dim84KuoInit, - dim85KuoInit, - dim86KuoInit, - dim87KuoInit, - dim88KuoInit, - dim89KuoInit, - dim90KuoInit, - dim91KuoInit, - dim92KuoInit, - dim93KuoInit, - dim94KuoInit, - dim95KuoInit, - dim96KuoInit, - dim97KuoInit, - dim98KuoInit, - dim99KuoInit, - dim100KuoInit, - dim101KuoInit, - dim102KuoInit, - dim103KuoInit, - dim104KuoInit, - dim105KuoInit, - dim106KuoInit, - dim107KuoInit, - dim108KuoInit, - dim109KuoInit, - dim110KuoInit, - dim111KuoInit, - dim112KuoInit, - dim113KuoInit, - dim114KuoInit, - dim115KuoInit, - dim116KuoInit, - dim117KuoInit, - dim118KuoInit, - dim119KuoInit, - dim120KuoInit, - dim121KuoInit, - dim122KuoInit, - dim123KuoInit, - dim124KuoInit, - dim125KuoInit, - dim126KuoInit, - dim127KuoInit, - dim128KuoInit, - dim129KuoInit, - dim130KuoInit, - dim131KuoInit, - dim132KuoInit, - dim133KuoInit, - dim134KuoInit, - dim135KuoInit, - dim136KuoInit, - dim137KuoInit, - dim138KuoInit, - dim139KuoInit, - dim140KuoInit, - dim141KuoInit, - dim142KuoInit, - dim143KuoInit, - dim144KuoInit, - dim145KuoInit, - dim146KuoInit, - dim147KuoInit, - dim148KuoInit, - dim149KuoInit, - dim150KuoInit, - dim151KuoInit, - dim152KuoInit, - dim153KuoInit, - dim154KuoInit, - dim155KuoInit, - dim156KuoInit, - dim157KuoInit, - dim158KuoInit, - dim159KuoInit, - dim160KuoInit, - dim161KuoInit, - dim162KuoInit, - dim163KuoInit, - dim164KuoInit, - dim165KuoInit, - dim166KuoInit, - dim167KuoInit, - dim168KuoInit, - dim169KuoInit, - dim170KuoInit, - dim171KuoInit, - dim172KuoInit, - dim173KuoInit, - dim174KuoInit, - dim175KuoInit, - dim176KuoInit, - dim177KuoInit, - dim178KuoInit, - dim179KuoInit, - dim180KuoInit, - dim181KuoInit, - dim182KuoInit, - dim183KuoInit, - dim184KuoInit, - dim185KuoInit, - dim186KuoInit, - dim187KuoInit, - dim188KuoInit, - dim189KuoInit, - dim190KuoInit, - dim191KuoInit, - dim192KuoInit, - dim193KuoInit, - dim194KuoInit, - dim195KuoInit, - dim196KuoInit, - dim197KuoInit, - dim198KuoInit, - dim199KuoInit, - dim200KuoInit, - dim201KuoInit, - dim202KuoInit, - dim203KuoInit, - dim204KuoInit, - dim205KuoInit, - dim206KuoInit, - dim207KuoInit, - dim208KuoInit, - dim209KuoInit, - dim210KuoInit, - dim211KuoInit, - dim212KuoInit, - dim213KuoInit, - dim214KuoInit, - dim215KuoInit, - dim216KuoInit, - dim217KuoInit, - dim218KuoInit, - dim219KuoInit, - dim220KuoInit, - dim221KuoInit, - dim222KuoInit, - dim223KuoInit, - dim224KuoInit, - dim225KuoInit, - dim226KuoInit, - dim227KuoInit, - dim228KuoInit, - dim229KuoInit, - dim230KuoInit, - dim231KuoInit, - dim232KuoInit, - dim233KuoInit, - dim234KuoInit, - dim235KuoInit, - dim236KuoInit, - dim237KuoInit, - dim238KuoInit, - dim239KuoInit, - dim240KuoInit, - dim241KuoInit, - dim242KuoInit, - dim243KuoInit, - dim244KuoInit, - dim245KuoInit, - dim246KuoInit, - dim247KuoInit, - dim248KuoInit, - dim249KuoInit, - dim250KuoInit, - dim251KuoInit, - dim252KuoInit, - dim253KuoInit, - dim254KuoInit, - dim255KuoInit, - dim256KuoInit, - dim257KuoInit, - dim258KuoInit, - dim259KuoInit, - dim260KuoInit, - dim261KuoInit, - dim262KuoInit, - dim263KuoInit, - dim264KuoInit, - dim265KuoInit, - dim266KuoInit, - dim267KuoInit, - dim268KuoInit, - dim269KuoInit, - dim270KuoInit, - dim271KuoInit, - dim272KuoInit, - dim273KuoInit, - dim274KuoInit, - dim275KuoInit, - dim276KuoInit, - dim277KuoInit, - dim278KuoInit, - dim279KuoInit, - dim280KuoInit, - dim281KuoInit, - dim282KuoInit, - dim283KuoInit, - dim284KuoInit, - dim285KuoInit, - dim286KuoInit, - dim287KuoInit, - dim288KuoInit, - dim289KuoInit, - dim290KuoInit, - dim291KuoInit, - dim292KuoInit, - dim293KuoInit, - dim294KuoInit, - dim295KuoInit, - dim296KuoInit, - dim297KuoInit, - dim298KuoInit, - dim299KuoInit, - dim300KuoInit, - dim301KuoInit, - dim302KuoInit, - dim303KuoInit, - dim304KuoInit, - dim305KuoInit, - dim306KuoInit, - dim307KuoInit, - dim308KuoInit, - dim309KuoInit, - dim310KuoInit, - dim311KuoInit, - dim312KuoInit, - dim313KuoInit, - dim314KuoInit, - dim315KuoInit, - dim316KuoInit, - dim317KuoInit, - dim318KuoInit, - dim319KuoInit, - dim320KuoInit, - dim321KuoInit, - dim322KuoInit, - dim323KuoInit, - dim324KuoInit, - dim325KuoInit, - dim326KuoInit, - dim327KuoInit, - dim328KuoInit, - dim329KuoInit, - dim330KuoInit, - dim331KuoInit, - dim332KuoInit, - dim333KuoInit, - dim334KuoInit, - dim335KuoInit, - dim336KuoInit, - dim337KuoInit, - dim338KuoInit, - dim339KuoInit, - dim340KuoInit, - dim341KuoInit, - dim342KuoInit, - dim343KuoInit, - dim344KuoInit, - dim345KuoInit, - dim346KuoInit, - dim347KuoInit, - dim348KuoInit, - dim349KuoInit, - dim350KuoInit, - dim351KuoInit, - dim352KuoInit, - dim353KuoInit, - dim354KuoInit, - dim355KuoInit, - dim356KuoInit, - dim357KuoInit, - dim358KuoInit, - dim359KuoInit, - dim360KuoInit, - dim361KuoInit, - dim362KuoInit, - dim363KuoInit, - dim364KuoInit, - dim365KuoInit, - dim366KuoInit, - dim367KuoInit, - dim368KuoInit, - dim369KuoInit, - dim370KuoInit, - dim371KuoInit, - dim372KuoInit, - dim373KuoInit, - dim374KuoInit, - dim375KuoInit, - dim376KuoInit, - dim377KuoInit, - dim378KuoInit, - dim379KuoInit, - dim380KuoInit, - dim381KuoInit, - dim382KuoInit, - dim383KuoInit, - dim384KuoInit, - dim385KuoInit, - dim386KuoInit, - dim387KuoInit, - dim388KuoInit, - dim389KuoInit, - dim390KuoInit, - dim391KuoInit, - dim392KuoInit, - dim393KuoInit, - dim394KuoInit, - dim395KuoInit, - dim396KuoInit, - dim397KuoInit, - dim398KuoInit, - dim399KuoInit, - dim400KuoInit, - dim401KuoInit, - dim402KuoInit, - dim403KuoInit, - dim404KuoInit, - dim405KuoInit, - dim406KuoInit, - dim407KuoInit, - dim408KuoInit, - dim409KuoInit, - dim410KuoInit, - dim411KuoInit, - dim412KuoInit, - dim413KuoInit, - dim414KuoInit, - dim415KuoInit, - dim416KuoInit, - dim417KuoInit, - dim418KuoInit, - dim419KuoInit, - dim420KuoInit, - dim421KuoInit, - dim422KuoInit, - dim423KuoInit, - dim424KuoInit, - dim425KuoInit, - dim426KuoInit, - dim427KuoInit, - dim428KuoInit, - dim429KuoInit, - dim430KuoInit, - dim431KuoInit, - dim432KuoInit, - dim433KuoInit, - dim434KuoInit, - dim435KuoInit, - dim436KuoInit, - dim437KuoInit, - dim438KuoInit, - dim439KuoInit, - dim440KuoInit, - dim441KuoInit, - dim442KuoInit, - dim443KuoInit, - dim444KuoInit, - dim445KuoInit, - dim446KuoInit, - dim447KuoInit, - dim448KuoInit, - dim449KuoInit, - dim450KuoInit, - dim451KuoInit, - dim452KuoInit, - dim453KuoInit, - dim454KuoInit, - dim455KuoInit, - dim456KuoInit, - dim457KuoInit, - dim458KuoInit, - dim459KuoInit, - dim460KuoInit, - dim461KuoInit, - dim462KuoInit, - dim463KuoInit, - dim464KuoInit, - dim465KuoInit, - dim466KuoInit, - dim467KuoInit, - dim468KuoInit, - dim469KuoInit, - dim470KuoInit, - dim471KuoInit, - dim472KuoInit, - dim473KuoInit, - dim474KuoInit, - dim475KuoInit, - dim476KuoInit, - dim477KuoInit, - dim478KuoInit, - dim479KuoInit, - dim480KuoInit, - dim481KuoInit, - dim482KuoInit, - dim483KuoInit, - dim484KuoInit, - dim485KuoInit, - dim486KuoInit, - dim487KuoInit, - dim488KuoInit, - dim489KuoInit, - dim490KuoInit, - dim491KuoInit, - dim492KuoInit, - dim493KuoInit, - dim494KuoInit, - dim495KuoInit, - dim496KuoInit, - dim497KuoInit, - dim498KuoInit, - dim499KuoInit, - dim500KuoInit, - dim501KuoInit, - dim502KuoInit, - dim503KuoInit, - dim504KuoInit, - dim505KuoInit, - dim506KuoInit, - dim507KuoInit, - dim508KuoInit, - dim509KuoInit, - dim510KuoInit, - dim511KuoInit, - dim512KuoInit, - dim513KuoInit, - dim514KuoInit, - dim515KuoInit, - dim516KuoInit, - dim517KuoInit, - dim518KuoInit, - dim519KuoInit, - dim520KuoInit, - dim521KuoInit, - dim522KuoInit, - dim523KuoInit, - dim524KuoInit, - dim525KuoInit, - dim526KuoInit, - dim527KuoInit, - dim528KuoInit, - dim529KuoInit, - dim530KuoInit, - dim531KuoInit, - dim532KuoInit, - dim533KuoInit, - dim534KuoInit, - dim535KuoInit, - dim536KuoInit, - dim537KuoInit, - dim538KuoInit, - dim539KuoInit, - dim540KuoInit, - dim541KuoInit, - dim542KuoInit, - dim543KuoInit, - dim544KuoInit, - dim545KuoInit, - dim546KuoInit, - dim547KuoInit, - dim548KuoInit, - dim549KuoInit, - dim550KuoInit, - dim551KuoInit, - dim552KuoInit, - dim553KuoInit, - dim554KuoInit, - dim555KuoInit, - dim556KuoInit, - dim557KuoInit, - dim558KuoInit, - dim559KuoInit, - dim560KuoInit, - dim561KuoInit, - dim562KuoInit, - dim563KuoInit, - dim564KuoInit, - dim565KuoInit, - dim566KuoInit, - dim567KuoInit, - dim568KuoInit, - dim569KuoInit, - dim570KuoInit, - dim571KuoInit, - dim572KuoInit, - dim573KuoInit, - dim574KuoInit, - dim575KuoInit, - dim576KuoInit, - dim577KuoInit, - dim578KuoInit, - dim579KuoInit, - dim580KuoInit, - dim581KuoInit, - dim582KuoInit, - dim583KuoInit, - dim584KuoInit, - dim585KuoInit, - dim586KuoInit, - dim587KuoInit, - dim588KuoInit, - dim589KuoInit, - dim590KuoInit, - dim591KuoInit, - dim592KuoInit, - dim593KuoInit, - dim594KuoInit, - dim595KuoInit, - dim596KuoInit, - dim597KuoInit, - dim598KuoInit, - dim599KuoInit, - dim600KuoInit, - dim601KuoInit, - dim602KuoInit, - dim603KuoInit, - dim604KuoInit, - dim605KuoInit, - dim606KuoInit, - dim607KuoInit, - dim608KuoInit, - dim609KuoInit, - dim610KuoInit, - dim611KuoInit, - dim612KuoInit, - dim613KuoInit, - dim614KuoInit, - dim615KuoInit, - dim616KuoInit, - dim617KuoInit, - dim618KuoInit, - dim619KuoInit, - dim620KuoInit, - dim621KuoInit, - dim622KuoInit, - dim623KuoInit, - dim624KuoInit, - dim625KuoInit, - dim626KuoInit, - dim627KuoInit, - dim628KuoInit, - dim629KuoInit, - dim630KuoInit, - dim631KuoInit, - dim632KuoInit, - dim633KuoInit, - dim634KuoInit, - dim635KuoInit, - dim636KuoInit, - dim637KuoInit, - dim638KuoInit, - dim639KuoInit, - dim640KuoInit, - dim641KuoInit, - dim642KuoInit, - dim643KuoInit, - dim644KuoInit, - dim645KuoInit, - dim646KuoInit, - dim647KuoInit, - dim648KuoInit, - dim649KuoInit, - dim650KuoInit, - dim651KuoInit, - dim652KuoInit, - dim653KuoInit, - dim654KuoInit, - dim655KuoInit, - dim656KuoInit, - dim657KuoInit, - dim658KuoInit, - dim659KuoInit, - dim660KuoInit, - dim661KuoInit, - dim662KuoInit, - dim663KuoInit, - dim664KuoInit, - dim665KuoInit, - dim666KuoInit, - dim667KuoInit, - dim668KuoInit, - dim669KuoInit, - dim670KuoInit, - dim671KuoInit, - dim672KuoInit, - dim673KuoInit, - dim674KuoInit, - dim675KuoInit, - dim676KuoInit, - dim677KuoInit, - dim678KuoInit, - dim679KuoInit, - dim680KuoInit, - dim681KuoInit, - dim682KuoInit, - dim683KuoInit, - dim684KuoInit, - dim685KuoInit, - dim686KuoInit, - dim687KuoInit, - dim688KuoInit, - dim689KuoInit, - dim690KuoInit, - dim691KuoInit, - dim692KuoInit, - dim693KuoInit, - dim694KuoInit, - dim695KuoInit, - dim696KuoInit, - dim697KuoInit, - dim698KuoInit, - dim699KuoInit, - dim700KuoInit, - dim701KuoInit, - dim702KuoInit, - dim703KuoInit, - dim704KuoInit, - dim705KuoInit, - dim706KuoInit, - dim707KuoInit, - dim708KuoInit, - dim709KuoInit, - dim710KuoInit, - dim711KuoInit, - dim712KuoInit, - dim713KuoInit, - dim714KuoInit, - dim715KuoInit, - dim716KuoInit, - dim717KuoInit, - dim718KuoInit, - dim719KuoInit, - dim720KuoInit, - dim721KuoInit, - dim722KuoInit, - dim723KuoInit, - dim724KuoInit, - dim725KuoInit, - dim726KuoInit, - dim727KuoInit, - dim728KuoInit, - dim729KuoInit, - dim730KuoInit, - dim731KuoInit, - dim732KuoInit, - dim733KuoInit, - dim734KuoInit, - dim735KuoInit, - dim736KuoInit, - dim737KuoInit, - dim738KuoInit, - dim739KuoInit, - dim740KuoInit, - dim741KuoInit, - dim742KuoInit, - dim743KuoInit, - dim744KuoInit, - dim745KuoInit, - dim746KuoInit, - dim747KuoInit, - dim748KuoInit, - dim749KuoInit, - dim750KuoInit, - dim751KuoInit, - dim752KuoInit, - dim753KuoInit, - dim754KuoInit, - dim755KuoInit, - dim756KuoInit, - dim757KuoInit, - dim758KuoInit, - dim759KuoInit, - dim760KuoInit, - dim761KuoInit, - dim762KuoInit, - dim763KuoInit, - dim764KuoInit, - dim765KuoInit, - dim766KuoInit, - dim767KuoInit, - dim768KuoInit, - dim769KuoInit, - dim770KuoInit, - dim771KuoInit, - dim772KuoInit, - dim773KuoInit, - dim774KuoInit, - dim775KuoInit, - dim776KuoInit, - dim777KuoInit, - dim778KuoInit, - dim779KuoInit, - dim780KuoInit, - dim781KuoInit, - dim782KuoInit, - dim783KuoInit, - dim784KuoInit, - dim785KuoInit, - dim786KuoInit, - dim787KuoInit, - dim788KuoInit, - dim789KuoInit, - dim790KuoInit, - dim791KuoInit, - dim792KuoInit, - dim793KuoInit, - dim794KuoInit, - dim795KuoInit, - dim796KuoInit, - dim797KuoInit, - dim798KuoInit, - dim799KuoInit, - dim800KuoInit, - dim801KuoInit, - dim802KuoInit, - dim803KuoInit, - dim804KuoInit, - dim805KuoInit, - dim806KuoInit, - dim807KuoInit, - dim808KuoInit, - dim809KuoInit, - dim810KuoInit, - dim811KuoInit, - dim812KuoInit, - dim813KuoInit, - dim814KuoInit, - dim815KuoInit, - dim816KuoInit, - dim817KuoInit, - dim818KuoInit, - dim819KuoInit, - dim820KuoInit, - dim821KuoInit, - dim822KuoInit, - dim823KuoInit, - dim824KuoInit, - dim825KuoInit, - dim826KuoInit, - dim827KuoInit, - dim828KuoInit, - dim829KuoInit, - dim830KuoInit, - dim831KuoInit, - dim832KuoInit, - dim833KuoInit, - dim834KuoInit, - dim835KuoInit, - dim836KuoInit, - dim837KuoInit, - dim838KuoInit, - dim839KuoInit, - dim840KuoInit, - dim841KuoInit, - dim842KuoInit, - dim843KuoInit, - dim844KuoInit, - dim845KuoInit, - dim846KuoInit, - dim847KuoInit, - dim848KuoInit, - dim849KuoInit, - dim850KuoInit, - dim851KuoInit, - dim852KuoInit, - dim853KuoInit, - dim854KuoInit, - dim855KuoInit, - dim856KuoInit, - dim857KuoInit, - dim858KuoInit, - dim859KuoInit, - dim860KuoInit, - dim861KuoInit, - dim862KuoInit, - dim863KuoInit, - dim864KuoInit, - dim865KuoInit, - dim866KuoInit, - dim867KuoInit, - dim868KuoInit, - dim869KuoInit, - dim870KuoInit, - dim871KuoInit, - dim872KuoInit, - dim873KuoInit, - dim874KuoInit, - dim875KuoInit, - dim876KuoInit, - dim877KuoInit, - dim878KuoInit, - dim879KuoInit, - dim880KuoInit, - dim881KuoInit, - dim882KuoInit, - dim883KuoInit, - dim884KuoInit, - dim885KuoInit, - dim886KuoInit, - dim887KuoInit, - dim888KuoInit, - dim889KuoInit, - dim890KuoInit, - dim891KuoInit, - dim892KuoInit, - dim893KuoInit, - dim894KuoInit, - dim895KuoInit, - dim896KuoInit, - dim897KuoInit, - dim898KuoInit, - dim899KuoInit, - dim900KuoInit, - dim901KuoInit, - dim902KuoInit, - dim903KuoInit, - dim904KuoInit, - dim905KuoInit, - dim906KuoInit, - dim907KuoInit, - dim908KuoInit, - dim909KuoInit, - dim910KuoInit, - dim911KuoInit, - dim912KuoInit, - dim913KuoInit, - dim914KuoInit, - dim915KuoInit, - dim916KuoInit, - dim917KuoInit, - dim918KuoInit, - dim919KuoInit, - dim920KuoInit, - dim921KuoInit, - dim922KuoInit, - dim923KuoInit, - dim924KuoInit, - dim925KuoInit, - dim926KuoInit, - dim927KuoInit, - dim928KuoInit, - dim929KuoInit, - dim930KuoInit, - dim931KuoInit, - dim932KuoInit, - dim933KuoInit, - dim934KuoInit, - dim935KuoInit, - dim936KuoInit, - dim937KuoInit, - dim938KuoInit, - dim939KuoInit, - dim940KuoInit, - dim941KuoInit, - dim942KuoInit, - dim943KuoInit, - dim944KuoInit, - dim945KuoInit, - dim946KuoInit, - dim947KuoInit, - dim948KuoInit, - dim949KuoInit, - dim950KuoInit, - dim951KuoInit, - dim952KuoInit, - dim953KuoInit, - dim954KuoInit, - dim955KuoInit, - dim956KuoInit, - dim957KuoInit, - dim958KuoInit, - dim959KuoInit, - dim960KuoInit, - dim961KuoInit, - dim962KuoInit, - dim963KuoInit, - dim964KuoInit, - dim965KuoInit, - dim966KuoInit, - dim967KuoInit, - dim968KuoInit, - dim969KuoInit, - dim970KuoInit, - dim971KuoInit, - dim972KuoInit, - dim973KuoInit, - dim974KuoInit, - dim975KuoInit, - dim976KuoInit, - dim977KuoInit, - dim978KuoInit, - dim979KuoInit, - dim980KuoInit, - dim981KuoInit, - dim982KuoInit, - dim983KuoInit, - dim984KuoInit, - dim985KuoInit, - dim986KuoInit, - dim987KuoInit, - dim988KuoInit, - dim989KuoInit, - dim990KuoInit, - dim991KuoInit, - dim992KuoInit, - dim993KuoInit, - dim994KuoInit, - dim995KuoInit, - dim996KuoInit, - dim997KuoInit, - dim998KuoInit, - dim999KuoInit, - dim1000KuoInit, - dim1001KuoInit, - dim1002KuoInit, - dim1003KuoInit, - dim1004KuoInit, - dim1005KuoInit, - dim1006KuoInit, - dim1007KuoInit, - dim1008KuoInit, - dim1009KuoInit, - dim1010KuoInit, - dim1011KuoInit, - dim1012KuoInit, - dim1013KuoInit, - dim1014KuoInit, - dim1015KuoInit, - dim1016KuoInit, - dim1017KuoInit, - dim1018KuoInit, - dim1019KuoInit, - dim1020KuoInit, - dim1021KuoInit, - dim1022KuoInit, - dim1023KuoInit, - dim1024KuoInit, - dim1025KuoInit, - dim1026KuoInit, - dim1027KuoInit, - dim1028KuoInit, - dim1029KuoInit, - dim1030KuoInit, - dim1031KuoInit, - dim1032KuoInit, - dim1033KuoInit, - dim1034KuoInit, - dim1035KuoInit, - dim1036KuoInit, - dim1037KuoInit, - dim1038KuoInit, - dim1039KuoInit, - dim1040KuoInit, - dim1041KuoInit, - dim1042KuoInit, - dim1043KuoInit, - dim1044KuoInit, - dim1045KuoInit, - dim1046KuoInit, - dim1047KuoInit, - dim1048KuoInit, - dim1049KuoInit, - dim1050KuoInit, - dim1051KuoInit, - dim1052KuoInit, - dim1053KuoInit, - dim1054KuoInit, - dim1055KuoInit, - dim1056KuoInit, - dim1057KuoInit, - dim1058KuoInit, - dim1059KuoInit, - dim1060KuoInit, - dim1061KuoInit, - dim1062KuoInit, - dim1063KuoInit, - dim1064KuoInit, - dim1065KuoInit, - dim1066KuoInit, - dim1067KuoInit, - dim1068KuoInit, - dim1069KuoInit, - dim1070KuoInit, - dim1071KuoInit, - dim1072KuoInit, - dim1073KuoInit, - dim1074KuoInit, - dim1075KuoInit, - dim1076KuoInit, - dim1077KuoInit, - dim1078KuoInit, - dim1079KuoInit, - dim1080KuoInit, - dim1081KuoInit, - dim1082KuoInit, - dim1083KuoInit, - dim1084KuoInit, - dim1085KuoInit, - dim1086KuoInit, - dim1087KuoInit, - dim1088KuoInit, - dim1089KuoInit, - dim1090KuoInit, - dim1091KuoInit, - dim1092KuoInit, - dim1093KuoInit, - dim1094KuoInit, - dim1095KuoInit, - dim1096KuoInit, - dim1097KuoInit, - dim1098KuoInit, - dim1099KuoInit, - dim1100KuoInit, - dim1101KuoInit, - dim1102KuoInit, - dim1103KuoInit, - dim1104KuoInit, - dim1105KuoInit, - dim1106KuoInit, - dim1107KuoInit, - dim1108KuoInit, - dim1109KuoInit, - dim1110KuoInit, - dim1111KuoInit, - dim1112KuoInit, - dim1113KuoInit, - dim1114KuoInit, - dim1115KuoInit, - dim1116KuoInit, - dim1117KuoInit, - dim1118KuoInit, - dim1119KuoInit, - dim1120KuoInit, - dim1121KuoInit, - dim1122KuoInit, - dim1123KuoInit, - dim1124KuoInit, - dim1125KuoInit, - dim1126KuoInit, - dim1127KuoInit, - dim1128KuoInit, - dim1129KuoInit, - dim1130KuoInit, - dim1131KuoInit, - dim1132KuoInit, - dim1133KuoInit, - dim1134KuoInit, - dim1135KuoInit, - dim1136KuoInit, - dim1137KuoInit, - dim1138KuoInit, - dim1139KuoInit, - dim1140KuoInit, - dim1141KuoInit, - dim1142KuoInit, - dim1143KuoInit, - dim1144KuoInit, - dim1145KuoInit, - dim1146KuoInit, - dim1147KuoInit, - dim1148KuoInit, - dim1149KuoInit, - dim1150KuoInit, - dim1151KuoInit, - dim1152KuoInit, - dim1153KuoInit, - dim1154KuoInit, - dim1155KuoInit, - dim1156KuoInit, - dim1157KuoInit, - dim1158KuoInit, - dim1159KuoInit, - dim1160KuoInit, - dim1161KuoInit, - dim1162KuoInit, - dim1163KuoInit, - dim1164KuoInit, - dim1165KuoInit, - dim1166KuoInit, - dim1167KuoInit, - dim1168KuoInit, - dim1169KuoInit, - dim1170KuoInit, - dim1171KuoInit, - dim1172KuoInit, - dim1173KuoInit, - dim1174KuoInit, - dim1175KuoInit, - dim1176KuoInit, - dim1177KuoInit, - dim1178KuoInit, - dim1179KuoInit, - dim1180KuoInit, - dim1181KuoInit, - dim1182KuoInit, - dim1183KuoInit, - dim1184KuoInit, - dim1185KuoInit, - dim1186KuoInit, - dim1187KuoInit, - dim1188KuoInit, - dim1189KuoInit, - dim1190KuoInit, - dim1191KuoInit, - dim1192KuoInit, - dim1193KuoInit, - dim1194KuoInit, - dim1195KuoInit, - dim1196KuoInit, - dim1197KuoInit, - dim1198KuoInit, - dim1199KuoInit, - dim1200KuoInit, - dim1201KuoInit, - dim1202KuoInit, - dim1203KuoInit, - dim1204KuoInit, - dim1205KuoInit, - dim1206KuoInit, - dim1207KuoInit, - dim1208KuoInit, - dim1209KuoInit, - dim1210KuoInit, - dim1211KuoInit, - dim1212KuoInit, - dim1213KuoInit, - dim1214KuoInit, - dim1215KuoInit, - dim1216KuoInit, - dim1217KuoInit, - dim1218KuoInit, - dim1219KuoInit, - dim1220KuoInit, - dim1221KuoInit, - dim1222KuoInit, - dim1223KuoInit, - dim1224KuoInit, - dim1225KuoInit, - dim1226KuoInit, - dim1227KuoInit, - dim1228KuoInit, - dim1229KuoInit, - dim1230KuoInit, - dim1231KuoInit, - dim1232KuoInit, - dim1233KuoInit, - dim1234KuoInit, - dim1235KuoInit, - dim1236KuoInit, - dim1237KuoInit, - dim1238KuoInit, - dim1239KuoInit, - dim1240KuoInit, - dim1241KuoInit, - dim1242KuoInit, - dim1243KuoInit, - dim1244KuoInit, - dim1245KuoInit, - dim1246KuoInit, - dim1247KuoInit, - dim1248KuoInit, - dim1249KuoInit, - dim1250KuoInit, - dim1251KuoInit, - dim1252KuoInit, - dim1253KuoInit, - dim1254KuoInit, - dim1255KuoInit, - dim1256KuoInit, - dim1257KuoInit, - dim1258KuoInit, - dim1259KuoInit, - dim1260KuoInit, - dim1261KuoInit, - dim1262KuoInit, - dim1263KuoInit, - dim1264KuoInit, - dim1265KuoInit, - dim1266KuoInit, - dim1267KuoInit, - dim1268KuoInit, - dim1269KuoInit, - dim1270KuoInit, - dim1271KuoInit, - dim1272KuoInit, - dim1273KuoInit, - dim1274KuoInit, - dim1275KuoInit, - dim1276KuoInit, - dim1277KuoInit, - dim1278KuoInit, - dim1279KuoInit, - dim1280KuoInit, - dim1281KuoInit, - dim1282KuoInit, - dim1283KuoInit, - dim1284KuoInit, - dim1285KuoInit, - dim1286KuoInit, - dim1287KuoInit, - dim1288KuoInit, - dim1289KuoInit, - dim1290KuoInit, - dim1291KuoInit, - dim1292KuoInit, - dim1293KuoInit, - dim1294KuoInit, - dim1295KuoInit, - dim1296KuoInit, - dim1297KuoInit, - dim1298KuoInit, - dim1299KuoInit, - dim1300KuoInit, - dim1301KuoInit, - dim1302KuoInit, - dim1303KuoInit, - dim1304KuoInit, - dim1305KuoInit, - dim1306KuoInit, - dim1307KuoInit, - dim1308KuoInit, - dim1309KuoInit, - dim1310KuoInit, - dim1311KuoInit, - dim1312KuoInit, - dim1313KuoInit, - dim1314KuoInit, - dim1315KuoInit, - dim1316KuoInit, - dim1317KuoInit, - dim1318KuoInit, - dim1319KuoInit, - dim1320KuoInit, - dim1321KuoInit, - dim1322KuoInit, - dim1323KuoInit, - dim1324KuoInit, - dim1325KuoInit, - dim1326KuoInit, - dim1327KuoInit, - dim1328KuoInit, - dim1329KuoInit, - dim1330KuoInit, - dim1331KuoInit, - dim1332KuoInit, - dim1333KuoInit, - dim1334KuoInit, - dim1335KuoInit, - dim1336KuoInit, - dim1337KuoInit, - dim1338KuoInit, - dim1339KuoInit, - dim1340KuoInit, - dim1341KuoInit, - dim1342KuoInit, - dim1343KuoInit, - dim1344KuoInit, - dim1345KuoInit, - dim1346KuoInit, - dim1347KuoInit, - dim1348KuoInit, - dim1349KuoInit, - dim1350KuoInit, - dim1351KuoInit, - dim1352KuoInit, - dim1353KuoInit, - dim1354KuoInit, - dim1355KuoInit, - dim1356KuoInit, - dim1357KuoInit, - dim1358KuoInit, - dim1359KuoInit, - dim1360KuoInit, - dim1361KuoInit, - dim1362KuoInit, - dim1363KuoInit, - dim1364KuoInit, - dim1365KuoInit, - dim1366KuoInit, - dim1367KuoInit, - dim1368KuoInit, - dim1369KuoInit, - dim1370KuoInit, - dim1371KuoInit, - dim1372KuoInit, - dim1373KuoInit, - dim1374KuoInit, - dim1375KuoInit, - dim1376KuoInit, - dim1377KuoInit, - dim1378KuoInit, - dim1379KuoInit, - dim1380KuoInit, - dim1381KuoInit, - dim1382KuoInit, - dim1383KuoInit, - dim1384KuoInit, - dim1385KuoInit, - dim1386KuoInit, - dim1387KuoInit, - dim1388KuoInit, - dim1389KuoInit, - dim1390KuoInit, - dim1391KuoInit, - dim1392KuoInit, - dim1393KuoInit, - dim1394KuoInit, - dim1395KuoInit, - dim1396KuoInit, - dim1397KuoInit, - dim1398KuoInit, - dim1399KuoInit, - dim1400KuoInit, - dim1401KuoInit, - dim1402KuoInit, - dim1403KuoInit, - dim1404KuoInit, - dim1405KuoInit, - dim1406KuoInit, - dim1407KuoInit, - dim1408KuoInit, - dim1409KuoInit, - dim1410KuoInit, - dim1411KuoInit, - dim1412KuoInit, - dim1413KuoInit, - dim1414KuoInit, - dim1415KuoInit, - dim1416KuoInit, - dim1417KuoInit, - dim1418KuoInit, - dim1419KuoInit, - dim1420KuoInit, - dim1421KuoInit, - dim1422KuoInit, - dim1423KuoInit, - dim1424KuoInit, - dim1425KuoInit, - dim1426KuoInit, - dim1427KuoInit, - dim1428KuoInit, - dim1429KuoInit, - dim1430KuoInit, - dim1431KuoInit, - dim1432KuoInit, - dim1433KuoInit, - dim1434KuoInit, - dim1435KuoInit, - dim1436KuoInit, - dim1437KuoInit, - dim1438KuoInit, - dim1439KuoInit, - dim1440KuoInit, - dim1441KuoInit, - dim1442KuoInit, - dim1443KuoInit, - dim1444KuoInit, - dim1445KuoInit, - dim1446KuoInit, - dim1447KuoInit, - dim1448KuoInit, - dim1449KuoInit, - dim1450KuoInit, - dim1451KuoInit, - dim1452KuoInit, - dim1453KuoInit, - dim1454KuoInit, - dim1455KuoInit, - dim1456KuoInit, - dim1457KuoInit, - dim1458KuoInit, - dim1459KuoInit, - dim1460KuoInit, - dim1461KuoInit, - dim1462KuoInit, - dim1463KuoInit, - dim1464KuoInit, - dim1465KuoInit, - dim1466KuoInit, - dim1467KuoInit, - dim1468KuoInit, - dim1469KuoInit, - dim1470KuoInit, - dim1471KuoInit, - dim1472KuoInit, - dim1473KuoInit, - dim1474KuoInit, - dim1475KuoInit, - dim1476KuoInit, - dim1477KuoInit, - dim1478KuoInit, - dim1479KuoInit, - dim1480KuoInit, - dim1481KuoInit, - dim1482KuoInit, - dim1483KuoInit, - dim1484KuoInit, - dim1485KuoInit, - dim1486KuoInit, - dim1487KuoInit, - dim1488KuoInit, - dim1489KuoInit, - dim1490KuoInit, - dim1491KuoInit, - dim1492KuoInit, - dim1493KuoInit, - dim1494KuoInit, - dim1495KuoInit, - dim1496KuoInit, - dim1497KuoInit, - dim1498KuoInit, - dim1499KuoInit, - dim1500KuoInit, - dim1501KuoInit, - dim1502KuoInit, - dim1503KuoInit, - dim1504KuoInit, - dim1505KuoInit, - dim1506KuoInit, - dim1507KuoInit, - dim1508KuoInit, - dim1509KuoInit, - dim1510KuoInit, - dim1511KuoInit, - dim1512KuoInit, - dim1513KuoInit, - dim1514KuoInit, - dim1515KuoInit, - dim1516KuoInit, - dim1517KuoInit, - dim1518KuoInit, - dim1519KuoInit, - dim1520KuoInit, - dim1521KuoInit, - dim1522KuoInit, - dim1523KuoInit, - dim1524KuoInit, - dim1525KuoInit, - dim1526KuoInit, - dim1527KuoInit, - dim1528KuoInit, - dim1529KuoInit, - dim1530KuoInit, - dim1531KuoInit, - dim1532KuoInit, - dim1533KuoInit, - dim1534KuoInit, - dim1535KuoInit, - dim1536KuoInit, - dim1537KuoInit, - dim1538KuoInit, - dim1539KuoInit, - dim1540KuoInit, - dim1541KuoInit, - dim1542KuoInit, - dim1543KuoInit, - dim1544KuoInit, - dim1545KuoInit, - dim1546KuoInit, - dim1547KuoInit, - dim1548KuoInit, - dim1549KuoInit, - dim1550KuoInit, - dim1551KuoInit, - dim1552KuoInit, - dim1553KuoInit, - dim1554KuoInit, - dim1555KuoInit, - dim1556KuoInit, - dim1557KuoInit, - dim1558KuoInit, - dim1559KuoInit, - dim1560KuoInit, - dim1561KuoInit, - dim1562KuoInit, - dim1563KuoInit, - dim1564KuoInit, - dim1565KuoInit, - dim1566KuoInit, - dim1567KuoInit, - dim1568KuoInit, - dim1569KuoInit, - dim1570KuoInit, - dim1571KuoInit, - dim1572KuoInit, - dim1573KuoInit, - dim1574KuoInit, - dim1575KuoInit, - dim1576KuoInit, - dim1577KuoInit, - dim1578KuoInit, - dim1579KuoInit, - dim1580KuoInit, - dim1581KuoInit, - dim1582KuoInit, - dim1583KuoInit, - dim1584KuoInit, - dim1585KuoInit, - dim1586KuoInit, - dim1587KuoInit, - dim1588KuoInit, - dim1589KuoInit, - dim1590KuoInit, - dim1591KuoInit, - dim1592KuoInit, - dim1593KuoInit, - dim1594KuoInit, - dim1595KuoInit, - dim1596KuoInit, - dim1597KuoInit, - dim1598KuoInit, - dim1599KuoInit, - dim1600KuoInit, - dim1601KuoInit, - dim1602KuoInit, - dim1603KuoInit, - dim1604KuoInit, - dim1605KuoInit, - dim1606KuoInit, - dim1607KuoInit, - dim1608KuoInit, - dim1609KuoInit, - dim1610KuoInit, - dim1611KuoInit, - dim1612KuoInit, - dim1613KuoInit, - dim1614KuoInit, - dim1615KuoInit, - dim1616KuoInit, - dim1617KuoInit, - dim1618KuoInit, - dim1619KuoInit, - dim1620KuoInit, - dim1621KuoInit, - dim1622KuoInit, - dim1623KuoInit, - dim1624KuoInit, - dim1625KuoInit, - dim1626KuoInit, - dim1627KuoInit, - dim1628KuoInit, - dim1629KuoInit, - dim1630KuoInit, - dim1631KuoInit, - dim1632KuoInit, - dim1633KuoInit, - dim1634KuoInit, - dim1635KuoInit, - dim1636KuoInit, - dim1637KuoInit, - dim1638KuoInit, - dim1639KuoInit, - dim1640KuoInit, - dim1641KuoInit, - dim1642KuoInit, - dim1643KuoInit, - dim1644KuoInit, - dim1645KuoInit, - dim1646KuoInit, - dim1647KuoInit, - dim1648KuoInit, - dim1649KuoInit, - dim1650KuoInit, - dim1651KuoInit, - dim1652KuoInit, - dim1653KuoInit, - dim1654KuoInit, - dim1655KuoInit, - dim1656KuoInit, - dim1657KuoInit, - dim1658KuoInit, - dim1659KuoInit, - dim1660KuoInit, - dim1661KuoInit, - dim1662KuoInit, - dim1663KuoInit, - dim1664KuoInit, - dim1665KuoInit, - dim1666KuoInit, - dim1667KuoInit, - dim1668KuoInit, - dim1669KuoInit, - dim1670KuoInit, - dim1671KuoInit, - dim1672KuoInit, - dim1673KuoInit, - dim1674KuoInit, - dim1675KuoInit, - dim1676KuoInit, - dim1677KuoInit, - dim1678KuoInit, - dim1679KuoInit, - dim1680KuoInit, - dim1681KuoInit, - dim1682KuoInit, - dim1683KuoInit, - dim1684KuoInit, - dim1685KuoInit, - dim1686KuoInit, - dim1687KuoInit, - dim1688KuoInit, - dim1689KuoInit, - dim1690KuoInit, - dim1691KuoInit, - dim1692KuoInit, - dim1693KuoInit, - dim1694KuoInit, - dim1695KuoInit, - dim1696KuoInit, - dim1697KuoInit, - dim1698KuoInit, - dim1699KuoInit, - dim1700KuoInit, - dim1701KuoInit, - dim1702KuoInit, - dim1703KuoInit, - dim1704KuoInit, - dim1705KuoInit, - dim1706KuoInit, - dim1707KuoInit, - dim1708KuoInit, - dim1709KuoInit, - dim1710KuoInit, - dim1711KuoInit, - dim1712KuoInit, - dim1713KuoInit, - dim1714KuoInit, - dim1715KuoInit, - dim1716KuoInit, - dim1717KuoInit, - dim1718KuoInit, - dim1719KuoInit, - dim1720KuoInit, - dim1721KuoInit, - dim1722KuoInit, - dim1723KuoInit, - dim1724KuoInit, - dim1725KuoInit, - dim1726KuoInit, - dim1727KuoInit, - dim1728KuoInit, - dim1729KuoInit, - dim1730KuoInit, - dim1731KuoInit, - dim1732KuoInit, - dim1733KuoInit, - dim1734KuoInit, - dim1735KuoInit, - dim1736KuoInit, - dim1737KuoInit, - dim1738KuoInit, - dim1739KuoInit, - dim1740KuoInit, - dim1741KuoInit, - dim1742KuoInit, - dim1743KuoInit, - dim1744KuoInit, - dim1745KuoInit, - dim1746KuoInit, - dim1747KuoInit, - dim1748KuoInit, - dim1749KuoInit, - dim1750KuoInit, - dim1751KuoInit, - dim1752KuoInit, - dim1753KuoInit, - dim1754KuoInit, - dim1755KuoInit, - dim1756KuoInit, - dim1757KuoInit, - dim1758KuoInit, - dim1759KuoInit, - dim1760KuoInit, - dim1761KuoInit, - dim1762KuoInit, - dim1763KuoInit, - dim1764KuoInit, - dim1765KuoInit, - dim1766KuoInit, - dim1767KuoInit, - dim1768KuoInit, - dim1769KuoInit, - dim1770KuoInit, - dim1771KuoInit, - dim1772KuoInit, - dim1773KuoInit, - dim1774KuoInit, - dim1775KuoInit, - dim1776KuoInit, - dim1777KuoInit, - dim1778KuoInit, - dim1779KuoInit, - dim1780KuoInit, - dim1781KuoInit, - dim1782KuoInit, - dim1783KuoInit, - dim1784KuoInit, - dim1785KuoInit, - dim1786KuoInit, - dim1787KuoInit, - dim1788KuoInit, - dim1789KuoInit, - dim1790KuoInit, - dim1791KuoInit, - dim1792KuoInit, - dim1793KuoInit, - dim1794KuoInit, - dim1795KuoInit, - dim1796KuoInit, - dim1797KuoInit, - dim1798KuoInit, - dim1799KuoInit, - dim1800KuoInit, - dim1801KuoInit, - dim1802KuoInit, - dim1803KuoInit, - dim1804KuoInit, - dim1805KuoInit, - dim1806KuoInit, - dim1807KuoInit, - dim1808KuoInit, - dim1809KuoInit, - dim1810KuoInit, - dim1811KuoInit, - dim1812KuoInit, - dim1813KuoInit, - dim1814KuoInit, - dim1815KuoInit, - dim1816KuoInit, - dim1817KuoInit, - dim1818KuoInit, - dim1819KuoInit, - dim1820KuoInit, - dim1821KuoInit, - dim1822KuoInit, - dim1823KuoInit, - dim1824KuoInit, - dim1825KuoInit, - dim1826KuoInit, - dim1827KuoInit, - dim1828KuoInit, - dim1829KuoInit, - dim1830KuoInit, - dim1831KuoInit, - dim1832KuoInit, - dim1833KuoInit, - dim1834KuoInit, - dim1835KuoInit, - dim1836KuoInit, - dim1837KuoInit, - dim1838KuoInit, - dim1839KuoInit, - dim1840KuoInit, - dim1841KuoInit, - dim1842KuoInit, - dim1843KuoInit, - dim1844KuoInit, - dim1845KuoInit, - dim1846KuoInit, - dim1847KuoInit, - dim1848KuoInit, - dim1849KuoInit, - dim1850KuoInit, - dim1851KuoInit, - dim1852KuoInit, - dim1853KuoInit, - dim1854KuoInit, - dim1855KuoInit, - dim1856KuoInit, - dim1857KuoInit, - dim1858KuoInit, - dim1859KuoInit, - dim1860KuoInit, - dim1861KuoInit, - dim1862KuoInit, - dim1863KuoInit, - dim1864KuoInit, - dim1865KuoInit, - dim1866KuoInit, - dim1867KuoInit, - dim1868KuoInit, - dim1869KuoInit, - dim1870KuoInit, - dim1871KuoInit, - dim1872KuoInit, - dim1873KuoInit, - dim1874KuoInit, - dim1875KuoInit, - dim1876KuoInit, - dim1877KuoInit, - dim1878KuoInit, - dim1879KuoInit, - dim1880KuoInit, - dim1881KuoInit, - dim1882KuoInit, - dim1883KuoInit, - dim1884KuoInit, - dim1885KuoInit, - dim1886KuoInit, - dim1887KuoInit, - dim1888KuoInit, - dim1889KuoInit, - dim1890KuoInit, - dim1891KuoInit, - dim1892KuoInit, - dim1893KuoInit, - dim1894KuoInit, - dim1895KuoInit, - dim1896KuoInit, - dim1897KuoInit, - dim1898KuoInit, - dim1899KuoInit, - dim1900KuoInit, - dim1901KuoInit, - dim1902KuoInit, - dim1903KuoInit, - dim1904KuoInit, - dim1905KuoInit, - dim1906KuoInit, - dim1907KuoInit, - dim1908KuoInit, - dim1909KuoInit, - dim1910KuoInit, - dim1911KuoInit, - dim1912KuoInit, - dim1913KuoInit, - dim1914KuoInit, - dim1915KuoInit, - dim1916KuoInit, - dim1917KuoInit, - dim1918KuoInit, - dim1919KuoInit, - dim1920KuoInit, - dim1921KuoInit, - dim1922KuoInit, - dim1923KuoInit, - dim1924KuoInit, - dim1925KuoInit, - dim1926KuoInit, - dim1927KuoInit, - dim1928KuoInit, - dim1929KuoInit, - dim1930KuoInit, - dim1931KuoInit, - dim1932KuoInit, - dim1933KuoInit, - dim1934KuoInit, - dim1935KuoInit, - dim1936KuoInit, - dim1937KuoInit, - dim1938KuoInit, - dim1939KuoInit, - dim1940KuoInit, - dim1941KuoInit, - dim1942KuoInit, - dim1943KuoInit, - dim1944KuoInit, - dim1945KuoInit, - dim1946KuoInit, - dim1947KuoInit, - dim1948KuoInit, - dim1949KuoInit, - dim1950KuoInit, - dim1951KuoInit, - dim1952KuoInit, - dim1953KuoInit, - dim1954KuoInit, - dim1955KuoInit, - dim1956KuoInit, - dim1957KuoInit, - dim1958KuoInit, - dim1959KuoInit, - dim1960KuoInit, - dim1961KuoInit, - dim1962KuoInit, - dim1963KuoInit, - dim1964KuoInit, - dim1965KuoInit, - dim1966KuoInit, - dim1967KuoInit, - dim1968KuoInit, - dim1969KuoInit, - dim1970KuoInit, - dim1971KuoInit, - dim1972KuoInit, - dim1973KuoInit, - dim1974KuoInit, - dim1975KuoInit, - dim1976KuoInit, - dim1977KuoInit, - dim1978KuoInit, - dim1979KuoInit, - dim1980KuoInit, - dim1981KuoInit, - dim1982KuoInit, - dim1983KuoInit, - dim1984KuoInit, - dim1985KuoInit, - dim1986KuoInit, - dim1987KuoInit, - dim1988KuoInit, - dim1989KuoInit, - dim1990KuoInit, - dim1991KuoInit, - dim1992KuoInit, - dim1993KuoInit, - dim1994KuoInit, - dim1995KuoInit, - dim1996KuoInit, - dim1997KuoInit, - dim1998KuoInit, - dim1999KuoInit, - dim2000KuoInit, - dim2001KuoInit, - dim2002KuoInit, - dim2003KuoInit, - dim2004KuoInit, - dim2005KuoInit, - dim2006KuoInit, - dim2007KuoInit, - dim2008KuoInit, - dim2009KuoInit, - dim2010KuoInit, - dim2011KuoInit, - dim2012KuoInit, - dim2013KuoInit, - dim2014KuoInit, - dim2015KuoInit, - dim2016KuoInit, - dim2017KuoInit, - dim2018KuoInit, - dim2019KuoInit, - dim2020KuoInit, - dim2021KuoInit, - dim2022KuoInit, - dim2023KuoInit, - dim2024KuoInit, - dim2025KuoInit, - dim2026KuoInit, - dim2027KuoInit, - dim2028KuoInit, - dim2029KuoInit, - dim2030KuoInit, - dim2031KuoInit, - dim2032KuoInit, - dim2033KuoInit, - dim2034KuoInit, - dim2035KuoInit, - dim2036KuoInit, - dim2037KuoInit, - dim2038KuoInit, - dim2039KuoInit, - dim2040KuoInit, - dim2041KuoInit, - dim2042KuoInit, - dim2043KuoInit, - dim2044KuoInit, - dim2045KuoInit, - dim2046KuoInit, - dim2047KuoInit, - dim2048KuoInit, - dim2049KuoInit, - dim2050KuoInit, - dim2051KuoInit, - dim2052KuoInit, - dim2053KuoInit, - dim2054KuoInit, - dim2055KuoInit, - dim2056KuoInit, - dim2057KuoInit, - dim2058KuoInit, - dim2059KuoInit, - dim2060KuoInit, - dim2061KuoInit, - dim2062KuoInit, - dim2063KuoInit, - dim2064KuoInit, - dim2065KuoInit, - dim2066KuoInit, - dim2067KuoInit, - dim2068KuoInit, - dim2069KuoInit, - dim2070KuoInit, - dim2071KuoInit, - dim2072KuoInit, - dim2073KuoInit, - dim2074KuoInit, - dim2075KuoInit, - dim2076KuoInit, - dim2077KuoInit, - dim2078KuoInit, - dim2079KuoInit, - dim2080KuoInit, - dim2081KuoInit, - dim2082KuoInit, - dim2083KuoInit, - dim2084KuoInit, - dim2085KuoInit, - dim2086KuoInit, - dim2087KuoInit, - dim2088KuoInit, - dim2089KuoInit, - dim2090KuoInit, - dim2091KuoInit, - dim2092KuoInit, - dim2093KuoInit, - dim2094KuoInit, - dim2095KuoInit, - dim2096KuoInit, - dim2097KuoInit, - dim2098KuoInit, - dim2099KuoInit, - dim2100KuoInit, - dim2101KuoInit, - dim2102KuoInit, - dim2103KuoInit, - dim2104KuoInit, - dim2105KuoInit, - dim2106KuoInit, - dim2107KuoInit, - dim2108KuoInit, - dim2109KuoInit, - dim2110KuoInit, - dim2111KuoInit, - dim2112KuoInit, - dim2113KuoInit, - dim2114KuoInit, - dim2115KuoInit, - dim2116KuoInit, - dim2117KuoInit, - dim2118KuoInit, - dim2119KuoInit, - dim2120KuoInit, - dim2121KuoInit, - dim2122KuoInit, - dim2123KuoInit, - dim2124KuoInit, - dim2125KuoInit, - dim2126KuoInit, - dim2127KuoInit, - dim2128KuoInit, - dim2129KuoInit, - dim2130KuoInit, - dim2131KuoInit, - dim2132KuoInit, - dim2133KuoInit, - dim2134KuoInit, - dim2135KuoInit, - dim2136KuoInit, - dim2137KuoInit, - dim2138KuoInit, - dim2139KuoInit, - dim2140KuoInit, - dim2141KuoInit, - dim2142KuoInit, - dim2143KuoInit, - dim2144KuoInit, - dim2145KuoInit, - dim2146KuoInit, - dim2147KuoInit, - dim2148KuoInit, - dim2149KuoInit, - dim2150KuoInit, - dim2151KuoInit, - dim2152KuoInit, - dim2153KuoInit, - dim2154KuoInit, - dim2155KuoInit, - dim2156KuoInit, - dim2157KuoInit, - dim2158KuoInit, - dim2159KuoInit, - dim2160KuoInit, - dim2161KuoInit, - dim2162KuoInit, - dim2163KuoInit, - dim2164KuoInit, - dim2165KuoInit, - dim2166KuoInit, - dim2167KuoInit, - dim2168KuoInit, - dim2169KuoInit, - dim2170KuoInit, - dim2171KuoInit, - dim2172KuoInit, - dim2173KuoInit, - dim2174KuoInit, - dim2175KuoInit, - dim2176KuoInit, - dim2177KuoInit, - dim2178KuoInit, - dim2179KuoInit, - dim2180KuoInit, - dim2181KuoInit, - dim2182KuoInit, - dim2183KuoInit, - dim2184KuoInit, - dim2185KuoInit, - dim2186KuoInit, - dim2187KuoInit, - dim2188KuoInit, - dim2189KuoInit, - dim2190KuoInit, - dim2191KuoInit, - dim2192KuoInit, - dim2193KuoInit, - dim2194KuoInit, - dim2195KuoInit, - dim2196KuoInit, - dim2197KuoInit, - dim2198KuoInit, - dim2199KuoInit, - dim2200KuoInit, - dim2201KuoInit, - dim2202KuoInit, - dim2203KuoInit, - dim2204KuoInit, - dim2205KuoInit, - dim2206KuoInit, - dim2207KuoInit, - dim2208KuoInit, - dim2209KuoInit, - dim2210KuoInit, - dim2211KuoInit, - dim2212KuoInit, - dim2213KuoInit, - dim2214KuoInit, - dim2215KuoInit, - dim2216KuoInit, - dim2217KuoInit, - dim2218KuoInit, - dim2219KuoInit, - dim2220KuoInit, - dim2221KuoInit, - dim2222KuoInit, - dim2223KuoInit, - dim2224KuoInit, - dim2225KuoInit, - dim2226KuoInit, - dim2227KuoInit, - dim2228KuoInit, - dim2229KuoInit, - dim2230KuoInit, - dim2231KuoInit, - dim2232KuoInit, - dim2233KuoInit, - dim2234KuoInit, - dim2235KuoInit, - dim2236KuoInit, - dim2237KuoInit, - dim2238KuoInit, - dim2239KuoInit, - dim2240KuoInit, - dim2241KuoInit, - dim2242KuoInit, - dim2243KuoInit, - dim2244KuoInit, - dim2245KuoInit, - dim2246KuoInit, - dim2247KuoInit, - dim2248KuoInit, - dim2249KuoInit, - dim2250KuoInit, - dim2251KuoInit, - dim2252KuoInit, - dim2253KuoInit, - dim2254KuoInit, - dim2255KuoInit, - dim2256KuoInit, - dim2257KuoInit, - dim2258KuoInit, - dim2259KuoInit, - dim2260KuoInit, - dim2261KuoInit, - dim2262KuoInit, - dim2263KuoInit, - dim2264KuoInit, - dim2265KuoInit, - dim2266KuoInit, - dim2267KuoInit, - dim2268KuoInit, - dim2269KuoInit, - dim2270KuoInit, - dim2271KuoInit, - dim2272KuoInit, - dim2273KuoInit, - dim2274KuoInit, - dim2275KuoInit, - dim2276KuoInit, - dim2277KuoInit, - dim2278KuoInit, - dim2279KuoInit, - dim2280KuoInit, - dim2281KuoInit, - dim2282KuoInit, - dim2283KuoInit, - dim2284KuoInit, - dim2285KuoInit, - dim2286KuoInit, - dim2287KuoInit, - dim2288KuoInit, - dim2289KuoInit, - dim2290KuoInit, - dim2291KuoInit, - dim2292KuoInit, - dim2293KuoInit, - dim2294KuoInit, - dim2295KuoInit, - dim2296KuoInit, - dim2297KuoInit, - dim2298KuoInit, - dim2299KuoInit, - dim2300KuoInit, - dim2301KuoInit, - dim2302KuoInit, - dim2303KuoInit, - dim2304KuoInit, - dim2305KuoInit, - dim2306KuoInit, - dim2307KuoInit, - dim2308KuoInit, - dim2309KuoInit, - dim2310KuoInit, - dim2311KuoInit, - dim2312KuoInit, - dim2313KuoInit, - dim2314KuoInit, - dim2315KuoInit, - dim2316KuoInit, - dim2317KuoInit, - dim2318KuoInit, - dim2319KuoInit, - dim2320KuoInit, - dim2321KuoInit, - dim2322KuoInit, - dim2323KuoInit, - dim2324KuoInit, - dim2325KuoInit, - dim2326KuoInit, - dim2327KuoInit, - dim2328KuoInit, - dim2329KuoInit, - dim2330KuoInit, - dim2331KuoInit, - dim2332KuoInit, - dim2333KuoInit, - dim2334KuoInit, - dim2335KuoInit, - dim2336KuoInit, - dim2337KuoInit, - dim2338KuoInit, - dim2339KuoInit, - dim2340KuoInit, - dim2341KuoInit, - dim2342KuoInit, - dim2343KuoInit, - dim2344KuoInit, - dim2345KuoInit, - dim2346KuoInit, - dim2347KuoInit, - dim2348KuoInit, - dim2349KuoInit, - dim2350KuoInit, - dim2351KuoInit, - dim2352KuoInit, - dim2353KuoInit, - dim2354KuoInit, - dim2355KuoInit, - dim2356KuoInit, - dim2357KuoInit, - dim2358KuoInit, - dim2359KuoInit, - dim2360KuoInit, - dim2361KuoInit, - dim2362KuoInit, - dim2363KuoInit, - dim2364KuoInit, - dim2365KuoInit, - dim2366KuoInit, - dim2367KuoInit, - dim2368KuoInit, - dim2369KuoInit, - dim2370KuoInit, - dim2371KuoInit, - dim2372KuoInit, - dim2373KuoInit, - dim2374KuoInit, - dim2375KuoInit, - dim2376KuoInit, - dim2377KuoInit, - dim2378KuoInit, - dim2379KuoInit, - dim2380KuoInit, - dim2381KuoInit, - dim2382KuoInit, - dim2383KuoInit, - dim2384KuoInit, - dim2385KuoInit, - dim2386KuoInit, - dim2387KuoInit, - dim2388KuoInit, - dim2389KuoInit, - dim2390KuoInit, - dim2391KuoInit, - dim2392KuoInit, - dim2393KuoInit, - dim2394KuoInit, - dim2395KuoInit, - dim2396KuoInit, - dim2397KuoInit, - dim2398KuoInit, - dim2399KuoInit, - dim2400KuoInit, - dim2401KuoInit, - dim2402KuoInit, - dim2403KuoInit, - dim2404KuoInit, - dim2405KuoInit, - dim2406KuoInit, - dim2407KuoInit, - dim2408KuoInit, - dim2409KuoInit, - dim2410KuoInit, - dim2411KuoInit, - dim2412KuoInit, - dim2413KuoInit, - dim2414KuoInit, - dim2415KuoInit, - dim2416KuoInit, - dim2417KuoInit, - dim2418KuoInit, - dim2419KuoInit, - dim2420KuoInit, - dim2421KuoInit, - dim2422KuoInit, - dim2423KuoInit, - dim2424KuoInit, - dim2425KuoInit, - dim2426KuoInit, - dim2427KuoInit, - dim2428KuoInit, - dim2429KuoInit, - dim2430KuoInit, - dim2431KuoInit, - dim2432KuoInit, - dim2433KuoInit, - dim2434KuoInit, - dim2435KuoInit, - dim2436KuoInit, - dim2437KuoInit, - dim2438KuoInit, - dim2439KuoInit, - dim2440KuoInit, - dim2441KuoInit, - dim2442KuoInit, - dim2443KuoInit, - dim2444KuoInit, - dim2445KuoInit, - dim2446KuoInit, - dim2447KuoInit, - dim2448KuoInit, - dim2449KuoInit, - dim2450KuoInit, - dim2451KuoInit, - dim2452KuoInit, - dim2453KuoInit, - dim2454KuoInit, - dim2455KuoInit, - dim2456KuoInit, - dim2457KuoInit, - dim2458KuoInit, - dim2459KuoInit, - dim2460KuoInit, - dim2461KuoInit, - dim2462KuoInit, - dim2463KuoInit, - dim2464KuoInit, - dim2465KuoInit, - dim2466KuoInit, - dim2467KuoInit, - dim2468KuoInit, - dim2469KuoInit, - dim2470KuoInit, - dim2471KuoInit, - dim2472KuoInit, - dim2473KuoInit, - dim2474KuoInit, - dim2475KuoInit, - dim2476KuoInit, - dim2477KuoInit, - dim2478KuoInit, - dim2479KuoInit, - dim2480KuoInit, - dim2481KuoInit, - dim2482KuoInit, - dim2483KuoInit, - dim2484KuoInit, - dim2485KuoInit, - dim2486KuoInit, - dim2487KuoInit, - dim2488KuoInit, - dim2489KuoInit, - dim2490KuoInit, - dim2491KuoInit, - dim2492KuoInit, - dim2493KuoInit, - dim2494KuoInit, - dim2495KuoInit, - dim2496KuoInit, - dim2497KuoInit, - dim2498KuoInit, - dim2499KuoInit, - dim2500KuoInit, - dim2501KuoInit, - dim2502KuoInit, - dim2503KuoInit, - dim2504KuoInit, - dim2505KuoInit, - dim2506KuoInit, - dim2507KuoInit, - dim2508KuoInit, - dim2509KuoInit, - dim2510KuoInit, - dim2511KuoInit, - dim2512KuoInit, - dim2513KuoInit, - dim2514KuoInit, - dim2515KuoInit, - dim2516KuoInit, - dim2517KuoInit, - dim2518KuoInit, - dim2519KuoInit, - dim2520KuoInit, - dim2521KuoInit, - dim2522KuoInit, - dim2523KuoInit, - dim2524KuoInit, - dim2525KuoInit, - dim2526KuoInit, - dim2527KuoInit, - dim2528KuoInit, - dim2529KuoInit, - dim2530KuoInit, - dim2531KuoInit, - dim2532KuoInit, - dim2533KuoInit, - dim2534KuoInit, - dim2535KuoInit, - dim2536KuoInit, - dim2537KuoInit, - dim2538KuoInit, - dim2539KuoInit, - dim2540KuoInit, - dim2541KuoInit, - dim2542KuoInit, - dim2543KuoInit, - dim2544KuoInit, - dim2545KuoInit, - dim2546KuoInit, - dim2547KuoInit, - dim2548KuoInit, - dim2549KuoInit, - dim2550KuoInit, - dim2551KuoInit, - dim2552KuoInit, - dim2553KuoInit, - dim2554KuoInit, - dim2555KuoInit, - dim2556KuoInit, - dim2557KuoInit, - dim2558KuoInit, - dim2559KuoInit, - dim2560KuoInit, - dim2561KuoInit, - dim2562KuoInit, - dim2563KuoInit, - dim2564KuoInit, - dim2565KuoInit, - dim2566KuoInit, - dim2567KuoInit, - dim2568KuoInit, - dim2569KuoInit, - dim2570KuoInit, - dim2571KuoInit, - dim2572KuoInit, - dim2573KuoInit, - dim2574KuoInit, - dim2575KuoInit, - dim2576KuoInit, - dim2577KuoInit, - dim2578KuoInit, - dim2579KuoInit, - dim2580KuoInit, - dim2581KuoInit, - dim2582KuoInit, - dim2583KuoInit, - dim2584KuoInit, - dim2585KuoInit, - dim2586KuoInit, - dim2587KuoInit, - dim2588KuoInit, - dim2589KuoInit, - dim2590KuoInit, - dim2591KuoInit, - dim2592KuoInit, - dim2593KuoInit, - dim2594KuoInit, - dim2595KuoInit, - dim2596KuoInit, - dim2597KuoInit, - dim2598KuoInit, - dim2599KuoInit, - dim2600KuoInit, - dim2601KuoInit, - dim2602KuoInit, - dim2603KuoInit, - dim2604KuoInit, - dim2605KuoInit, - dim2606KuoInit, - dim2607KuoInit, - dim2608KuoInit, - dim2609KuoInit, - dim2610KuoInit, - dim2611KuoInit, - dim2612KuoInit, - dim2613KuoInit, - dim2614KuoInit, - dim2615KuoInit, - dim2616KuoInit, - dim2617KuoInit, - dim2618KuoInit, - dim2619KuoInit, - dim2620KuoInit, - dim2621KuoInit, - dim2622KuoInit, - dim2623KuoInit, - dim2624KuoInit, - dim2625KuoInit, - dim2626KuoInit, - dim2627KuoInit, - dim2628KuoInit, - dim2629KuoInit, - dim2630KuoInit, - dim2631KuoInit, - dim2632KuoInit, - dim2633KuoInit, - dim2634KuoInit, - dim2635KuoInit, - dim2636KuoInit, - dim2637KuoInit, - dim2638KuoInit, - dim2639KuoInit, - dim2640KuoInit, - dim2641KuoInit, - dim2642KuoInit, - dim2643KuoInit, - dim2644KuoInit, - dim2645KuoInit, - dim2646KuoInit, - dim2647KuoInit, - dim2648KuoInit, - dim2649KuoInit, - dim2650KuoInit, - dim2651KuoInit, - dim2652KuoInit, - dim2653KuoInit, - dim2654KuoInit, - dim2655KuoInit, - dim2656KuoInit, - dim2657KuoInit, - dim2658KuoInit, - dim2659KuoInit, - dim2660KuoInit, - dim2661KuoInit, - dim2662KuoInit, - dim2663KuoInit, - dim2664KuoInit, - dim2665KuoInit, - dim2666KuoInit, - dim2667KuoInit, - dim2668KuoInit, - dim2669KuoInit, - dim2670KuoInit, - dim2671KuoInit, - dim2672KuoInit, - dim2673KuoInit, - dim2674KuoInit, - dim2675KuoInit, - dim2676KuoInit, - dim2677KuoInit, - dim2678KuoInit, - dim2679KuoInit, - dim2680KuoInit, - dim2681KuoInit, - dim2682KuoInit, - dim2683KuoInit, - dim2684KuoInit, - dim2685KuoInit, - dim2686KuoInit, - dim2687KuoInit, - dim2688KuoInit, - dim2689KuoInit, - dim2690KuoInit, - dim2691KuoInit, - dim2692KuoInit, - dim2693KuoInit, - dim2694KuoInit, - dim2695KuoInit, - dim2696KuoInit, - dim2697KuoInit, - dim2698KuoInit, - dim2699KuoInit, - dim2700KuoInit, - dim2701KuoInit, - dim2702KuoInit, - dim2703KuoInit, - dim2704KuoInit, - dim2705KuoInit, - dim2706KuoInit, - dim2707KuoInit, - dim2708KuoInit, - dim2709KuoInit, - dim2710KuoInit, - dim2711KuoInit, - dim2712KuoInit, - dim2713KuoInit, - dim2714KuoInit, - dim2715KuoInit, - dim2716KuoInit, - dim2717KuoInit, - dim2718KuoInit, - dim2719KuoInit, - dim2720KuoInit, - dim2721KuoInit, - dim2722KuoInit, - dim2723KuoInit, - dim2724KuoInit, - dim2725KuoInit, - dim2726KuoInit, - dim2727KuoInit, - dim2728KuoInit, - dim2729KuoInit, - dim2730KuoInit, - dim2731KuoInit, - dim2732KuoInit, - dim2733KuoInit, - dim2734KuoInit, - dim2735KuoInit, - dim2736KuoInit, - dim2737KuoInit, - dim2738KuoInit, - dim2739KuoInit, - dim2740KuoInit, - dim2741KuoInit, - dim2742KuoInit, - dim2743KuoInit, - dim2744KuoInit, - dim2745KuoInit, - dim2746KuoInit, - dim2747KuoInit, - dim2748KuoInit, - dim2749KuoInit, - dim2750KuoInit, - dim2751KuoInit, - dim2752KuoInit, - dim2753KuoInit, - dim2754KuoInit, - dim2755KuoInit, - dim2756KuoInit, - dim2757KuoInit, - dim2758KuoInit, - dim2759KuoInit, - dim2760KuoInit, - dim2761KuoInit, - dim2762KuoInit, - dim2763KuoInit, - dim2764KuoInit, - dim2765KuoInit, - dim2766KuoInit, - dim2767KuoInit, - dim2768KuoInit, - dim2769KuoInit, - dim2770KuoInit, - dim2771KuoInit, - dim2772KuoInit, - dim2773KuoInit, - dim2774KuoInit, - dim2775KuoInit, - dim2776KuoInit, - dim2777KuoInit, - dim2778KuoInit, - dim2779KuoInit, - dim2780KuoInit, - dim2781KuoInit, - dim2782KuoInit, - dim2783KuoInit, - dim2784KuoInit, - dim2785KuoInit, - dim2786KuoInit, - dim2787KuoInit, - dim2788KuoInit, - dim2789KuoInit, - dim2790KuoInit, - dim2791KuoInit, - dim2792KuoInit, - dim2793KuoInit, - dim2794KuoInit, - dim2795KuoInit, - dim2796KuoInit, - dim2797KuoInit, - dim2798KuoInit, - dim2799KuoInit, - dim2800KuoInit, - dim2801KuoInit, - dim2802KuoInit, - dim2803KuoInit, - dim2804KuoInit, - dim2805KuoInit, - dim2806KuoInit, - dim2807KuoInit, - dim2808KuoInit, - dim2809KuoInit, - dim2810KuoInit, - dim2811KuoInit, - dim2812KuoInit, - dim2813KuoInit, - dim2814KuoInit, - dim2815KuoInit, - dim2816KuoInit, - dim2817KuoInit, - dim2818KuoInit, - dim2819KuoInit, - dim2820KuoInit, - dim2821KuoInit, - dim2822KuoInit, - dim2823KuoInit, - dim2824KuoInit, - dim2825KuoInit, - dim2826KuoInit, - dim2827KuoInit, - dim2828KuoInit, - dim2829KuoInit, - dim2830KuoInit, - dim2831KuoInit, - dim2832KuoInit, - dim2833KuoInit, - dim2834KuoInit, - dim2835KuoInit, - dim2836KuoInit, - dim2837KuoInit, - dim2838KuoInit, - dim2839KuoInit, - dim2840KuoInit, - dim2841KuoInit, - dim2842KuoInit, - dim2843KuoInit, - dim2844KuoInit, - dim2845KuoInit, - dim2846KuoInit, - dim2847KuoInit, - dim2848KuoInit, - dim2849KuoInit, - dim2850KuoInit, - dim2851KuoInit, - dim2852KuoInit, - dim2853KuoInit, - dim2854KuoInit, - dim2855KuoInit, - dim2856KuoInit, - dim2857KuoInit, - dim2858KuoInit, - dim2859KuoInit, - dim2860KuoInit, - dim2861KuoInit, - dim2862KuoInit, - dim2863KuoInit, - dim2864KuoInit, - dim2865KuoInit, - dim2866KuoInit, - dim2867KuoInit, - dim2868KuoInit, - dim2869KuoInit, - dim2870KuoInit, - dim2871KuoInit, - dim2872KuoInit, - dim2873KuoInit, - dim2874KuoInit, - dim2875KuoInit, - dim2876KuoInit, - dim2877KuoInit, - dim2878KuoInit, - dim2879KuoInit, - dim2880KuoInit, - dim2881KuoInit, - dim2882KuoInit, - dim2883KuoInit, - dim2884KuoInit, - dim2885KuoInit, - dim2886KuoInit, - dim2887KuoInit, - dim2888KuoInit, - dim2889KuoInit, - dim2890KuoInit, - dim2891KuoInit, - dim2892KuoInit, - dim2893KuoInit, - dim2894KuoInit, - dim2895KuoInit, - dim2896KuoInit, - dim2897KuoInit, - dim2898KuoInit, - dim2899KuoInit, - dim2900KuoInit, - dim2901KuoInit, - dim2902KuoInit, - dim2903KuoInit, - dim2904KuoInit, - dim2905KuoInit, - dim2906KuoInit, - dim2907KuoInit, - dim2908KuoInit, - dim2909KuoInit, - dim2910KuoInit, - dim2911KuoInit, - dim2912KuoInit, - dim2913KuoInit, - dim2914KuoInit, - dim2915KuoInit, - dim2916KuoInit, - dim2917KuoInit, - dim2918KuoInit, - dim2919KuoInit, - dim2920KuoInit, - dim2921KuoInit, - dim2922KuoInit, - dim2923KuoInit, - dim2924KuoInit, - dim2925KuoInit, - dim2926KuoInit, - dim2927KuoInit, - dim2928KuoInit, - dim2929KuoInit, - dim2930KuoInit, - dim2931KuoInit, - dim2932KuoInit, - dim2933KuoInit, - dim2934KuoInit, - dim2935KuoInit, - dim2936KuoInit, - dim2937KuoInit, - dim2938KuoInit, - dim2939KuoInit, - dim2940KuoInit, - dim2941KuoInit, - dim2942KuoInit, - dim2943KuoInit, - dim2944KuoInit, - dim2945KuoInit, - dim2946KuoInit, - dim2947KuoInit, - dim2948KuoInit, - dim2949KuoInit, - dim2950KuoInit, - dim2951KuoInit, - dim2952KuoInit, - dim2953KuoInit, - dim2954KuoInit, - dim2955KuoInit, - dim2956KuoInit, - dim2957KuoInit, - dim2958KuoInit, - dim2959KuoInit, - dim2960KuoInit, - dim2961KuoInit, - dim2962KuoInit, - dim2963KuoInit, - dim2964KuoInit, - dim2965KuoInit, - dim2966KuoInit, - dim2967KuoInit, - dim2968KuoInit, - dim2969KuoInit, - dim2970KuoInit, - dim2971KuoInit, - dim2972KuoInit, - dim2973KuoInit, - dim2974KuoInit, - dim2975KuoInit, - dim2976KuoInit, - dim2977KuoInit, - dim2978KuoInit, - dim2979KuoInit, - dim2980KuoInit, - dim2981KuoInit, - dim2982KuoInit, - dim2983KuoInit, - dim2984KuoInit, - dim2985KuoInit, - dim2986KuoInit, - dim2987KuoInit, - dim2988KuoInit, - dim2989KuoInit, - dim2990KuoInit, - dim2991KuoInit, - dim2992KuoInit, - dim2993KuoInit, - dim2994KuoInit, - dim2995KuoInit, - dim2996KuoInit, - dim2997KuoInit, - dim2998KuoInit, - dim2999KuoInit, - dim3000KuoInit, - dim3001KuoInit, - dim3002KuoInit, - dim3003KuoInit, - dim3004KuoInit, - dim3005KuoInit, - dim3006KuoInit, - dim3007KuoInit, - dim3008KuoInit, - dim3009KuoInit, - dim3010KuoInit, - dim3011KuoInit, - dim3012KuoInit, - dim3013KuoInit, - dim3014KuoInit, - dim3015KuoInit, - dim3016KuoInit, - dim3017KuoInit, - dim3018KuoInit, - dim3019KuoInit, - dim3020KuoInit, - dim3021KuoInit, - dim3022KuoInit, - dim3023KuoInit, - dim3024KuoInit, - dim3025KuoInit, - dim3026KuoInit, - dim3027KuoInit, - dim3028KuoInit, - dim3029KuoInit, - dim3030KuoInit, - dim3031KuoInit, - dim3032KuoInit, - dim3033KuoInit, - dim3034KuoInit, - dim3035KuoInit, - dim3036KuoInit, - dim3037KuoInit, - dim3038KuoInit, - dim3039KuoInit, - dim3040KuoInit, - dim3041KuoInit, - dim3042KuoInit, - dim3043KuoInit, - dim3044KuoInit, - dim3045KuoInit, - dim3046KuoInit, - dim3047KuoInit, - dim3048KuoInit, - dim3049KuoInit, - dim3050KuoInit, - dim3051KuoInit, - dim3052KuoInit, - dim3053KuoInit, - dim3054KuoInit, - dim3055KuoInit, - dim3056KuoInit, - dim3057KuoInit, - dim3058KuoInit, - dim3059KuoInit, - dim3060KuoInit, - dim3061KuoInit, - dim3062KuoInit, - dim3063KuoInit, - dim3064KuoInit, - dim3065KuoInit, - dim3066KuoInit, - dim3067KuoInit, - dim3068KuoInit, - dim3069KuoInit, - dim3070KuoInit, - dim3071KuoInit, - dim3072KuoInit, - dim3073KuoInit, - dim3074KuoInit, - dim3075KuoInit, - dim3076KuoInit, - dim3077KuoInit, - dim3078KuoInit, - dim3079KuoInit, - dim3080KuoInit, - dim3081KuoInit, - dim3082KuoInit, - dim3083KuoInit, - dim3084KuoInit, - dim3085KuoInit, - dim3086KuoInit, - dim3087KuoInit, - dim3088KuoInit, - dim3089KuoInit, - dim3090KuoInit, - dim3091KuoInit, - dim3092KuoInit, - dim3093KuoInit, - dim3094KuoInit, - dim3095KuoInit, - dim3096KuoInit, - dim3097KuoInit, - dim3098KuoInit, - dim3099KuoInit, - dim3100KuoInit, - dim3101KuoInit, - dim3102KuoInit, - dim3103KuoInit, - dim3104KuoInit, - dim3105KuoInit, - dim3106KuoInit, - dim3107KuoInit, - dim3108KuoInit, - dim3109KuoInit, - dim3110KuoInit, - dim3111KuoInit, - dim3112KuoInit, - dim3113KuoInit, - dim3114KuoInit, - dim3115KuoInit, - dim3116KuoInit, - dim3117KuoInit, - dim3118KuoInit, - dim3119KuoInit, - dim3120KuoInit, - dim3121KuoInit, - dim3122KuoInit, - dim3123KuoInit, - dim3124KuoInit, - dim3125KuoInit, - dim3126KuoInit, - dim3127KuoInit, - dim3128KuoInit, - dim3129KuoInit, - dim3130KuoInit, - dim3131KuoInit, - dim3132KuoInit, - dim3133KuoInit, - dim3134KuoInit, - dim3135KuoInit, - dim3136KuoInit, - dim3137KuoInit, - dim3138KuoInit, - dim3139KuoInit, - dim3140KuoInit, - dim3141KuoInit, - dim3142KuoInit, - dim3143KuoInit, - dim3144KuoInit, - dim3145KuoInit, - dim3146KuoInit, - dim3147KuoInit, - dim3148KuoInit, - dim3149KuoInit, - dim3150KuoInit, - dim3151KuoInit, - dim3152KuoInit, - dim3153KuoInit, - dim3154KuoInit, - dim3155KuoInit, - dim3156KuoInit, - dim3157KuoInit, - dim3158KuoInit, - dim3159KuoInit, - dim3160KuoInit, - dim3161KuoInit, - dim3162KuoInit, - dim3163KuoInit, - dim3164KuoInit, - dim3165KuoInit, - dim3166KuoInit, - dim3167KuoInit, - dim3168KuoInit, - dim3169KuoInit, - dim3170KuoInit, - dim3171KuoInit, - dim3172KuoInit, - dim3173KuoInit, - dim3174KuoInit, - dim3175KuoInit, - dim3176KuoInit, - dim3177KuoInit, - dim3178KuoInit, - dim3179KuoInit, - dim3180KuoInit, - dim3181KuoInit, - dim3182KuoInit, - dim3183KuoInit, - dim3184KuoInit, - dim3185KuoInit, - dim3186KuoInit, - dim3187KuoInit, - dim3188KuoInit, - dim3189KuoInit, - dim3190KuoInit, - dim3191KuoInit, - dim3192KuoInit, - dim3193KuoInit, - dim3194KuoInit, - dim3195KuoInit, - dim3196KuoInit, - dim3197KuoInit, - dim3198KuoInit, - dim3199KuoInit, - dim3200KuoInit, - dim3201KuoInit, - dim3202KuoInit, - dim3203KuoInit, - dim3204KuoInit, - dim3205KuoInit, - dim3206KuoInit, - dim3207KuoInit, - dim3208KuoInit, - dim3209KuoInit, - dim3210KuoInit, - dim3211KuoInit, - dim3212KuoInit, - dim3213KuoInit, - dim3214KuoInit, - dim3215KuoInit, - dim3216KuoInit, - dim3217KuoInit, - dim3218KuoInit, - dim3219KuoInit, - dim3220KuoInit, - dim3221KuoInit, - dim3222KuoInit, - dim3223KuoInit, - dim3224KuoInit, - dim3225KuoInit, - dim3226KuoInit, - dim3227KuoInit, - dim3228KuoInit, - dim3229KuoInit, - dim3230KuoInit, - dim3231KuoInit, - dim3232KuoInit, - dim3233KuoInit, - dim3234KuoInit, - dim3235KuoInit, - dim3236KuoInit, - dim3237KuoInit, - dim3238KuoInit, - dim3239KuoInit, - dim3240KuoInit, - dim3241KuoInit, - dim3242KuoInit, - dim3243KuoInit, - dim3244KuoInit, - dim3245KuoInit, - dim3246KuoInit, - dim3247KuoInit, - dim3248KuoInit, - dim3249KuoInit, - dim3250KuoInit, - dim3251KuoInit, - dim3252KuoInit, - dim3253KuoInit, - dim3254KuoInit, - dim3255KuoInit, - dim3256KuoInit, - dim3257KuoInit, - dim3258KuoInit, - dim3259KuoInit, - dim3260KuoInit, - dim3261KuoInit, - dim3262KuoInit, - dim3263KuoInit, - dim3264KuoInit, - dim3265KuoInit, - dim3266KuoInit, - dim3267KuoInit, - dim3268KuoInit, - dim3269KuoInit, - dim3270KuoInit, - dim3271KuoInit, - dim3272KuoInit, - dim3273KuoInit, - dim3274KuoInit, - dim3275KuoInit, - dim3276KuoInit, - dim3277KuoInit, - dim3278KuoInit, - dim3279KuoInit, - dim3280KuoInit, - dim3281KuoInit, - dim3282KuoInit, - dim3283KuoInit, - dim3284KuoInit, - dim3285KuoInit, - dim3286KuoInit, - dim3287KuoInit, - dim3288KuoInit, - dim3289KuoInit, - dim3290KuoInit, - dim3291KuoInit, - dim3292KuoInit, - dim3293KuoInit, - dim3294KuoInit, - dim3295KuoInit, - dim3296KuoInit, - dim3297KuoInit, - dim3298KuoInit, - dim3299KuoInit, - dim3300KuoInit, - dim3301KuoInit, - dim3302KuoInit, - dim3303KuoInit, - dim3304KuoInit, - dim3305KuoInit, - dim3306KuoInit, - dim3307KuoInit, - dim3308KuoInit, - dim3309KuoInit, - dim3310KuoInit, - dim3311KuoInit, - dim3312KuoInit, - dim3313KuoInit, - dim3314KuoInit, - dim3315KuoInit, - dim3316KuoInit, - dim3317KuoInit, - dim3318KuoInit, - dim3319KuoInit, - dim3320KuoInit, - dim3321KuoInit, - dim3322KuoInit, - dim3323KuoInit, - dim3324KuoInit, - dim3325KuoInit, - dim3326KuoInit, - dim3327KuoInit, - dim3328KuoInit, - dim3329KuoInit, - dim3330KuoInit, - dim3331KuoInit, - dim3332KuoInit, - dim3333KuoInit, - dim3334KuoInit, - dim3335KuoInit, - dim3336KuoInit, - dim3337KuoInit, - dim3338KuoInit, - dim3339KuoInit, - dim3340KuoInit, - dim3341KuoInit, - dim3342KuoInit, - dim3343KuoInit, - dim3344KuoInit, - dim3345KuoInit, - dim3346KuoInit, - dim3347KuoInit, - dim3348KuoInit, - dim3349KuoInit, - dim3350KuoInit, - dim3351KuoInit, - dim3352KuoInit, - dim3353KuoInit, - dim3354KuoInit, - dim3355KuoInit, - dim3356KuoInit, - dim3357KuoInit, - dim3358KuoInit, - dim3359KuoInit, - dim3360KuoInit, - dim3361KuoInit, - dim3362KuoInit, - dim3363KuoInit, - dim3364KuoInit, - dim3365KuoInit, - dim3366KuoInit, - dim3367KuoInit, - dim3368KuoInit, - dim3369KuoInit, - dim3370KuoInit, - dim3371KuoInit, - dim3372KuoInit, - dim3373KuoInit, - dim3374KuoInit, - dim3375KuoInit, - dim3376KuoInit, - dim3377KuoInit, - dim3378KuoInit, - dim3379KuoInit, - dim3380KuoInit, - dim3381KuoInit, - dim3382KuoInit, - dim3383KuoInit, - dim3384KuoInit, - dim3385KuoInit, - dim3386KuoInit, - dim3387KuoInit, - dim3388KuoInit, - dim3389KuoInit, - dim3390KuoInit, - dim3391KuoInit, - dim3392KuoInit, - dim3393KuoInit, - dim3394KuoInit, - dim3395KuoInit, - dim3396KuoInit, - dim3397KuoInit, - dim3398KuoInit, - dim3399KuoInit, - dim3400KuoInit, - dim3401KuoInit, - dim3402KuoInit, - dim3403KuoInit, - dim3404KuoInit, - dim3405KuoInit, - dim3406KuoInit, - dim3407KuoInit, - dim3408KuoInit, - dim3409KuoInit, - dim3410KuoInit, - dim3411KuoInit, - dim3412KuoInit, - dim3413KuoInit, - dim3414KuoInit, - dim3415KuoInit, - dim3416KuoInit, - dim3417KuoInit, - dim3418KuoInit, - dim3419KuoInit, - dim3420KuoInit, - dim3421KuoInit, - dim3422KuoInit, - dim3423KuoInit, - dim3424KuoInit, - dim3425KuoInit, - dim3426KuoInit, - dim3427KuoInit, - dim3428KuoInit, - dim3429KuoInit, - dim3430KuoInit, - dim3431KuoInit, - dim3432KuoInit, - dim3433KuoInit, - dim3434KuoInit, - dim3435KuoInit, - dim3436KuoInit, - dim3437KuoInit, - dim3438KuoInit, - dim3439KuoInit, - dim3440KuoInit, - dim3441KuoInit, - dim3442KuoInit, - dim3443KuoInit, - dim3444KuoInit, - dim3445KuoInit, - dim3446KuoInit, - dim3447KuoInit, - dim3448KuoInit, - dim3449KuoInit, - dim3450KuoInit, - dim3451KuoInit, - dim3452KuoInit, - dim3453KuoInit, - dim3454KuoInit, - dim3455KuoInit, - dim3456KuoInit, - dim3457KuoInit, - dim3458KuoInit, - dim3459KuoInit, - dim3460KuoInit, - dim3461KuoInit, - dim3462KuoInit, - dim3463KuoInit, - dim3464KuoInit, - dim3465KuoInit, - dim3466KuoInit, - dim3467KuoInit, - dim3468KuoInit, - dim3469KuoInit, - dim3470KuoInit, - dim3471KuoInit, - dim3472KuoInit, - dim3473KuoInit, - dim3474KuoInit, - dim3475KuoInit, - dim3476KuoInit, - dim3477KuoInit, - dim3478KuoInit, - dim3479KuoInit, - dim3480KuoInit, - dim3481KuoInit, - dim3482KuoInit, - dim3483KuoInit, - dim3484KuoInit, - dim3485KuoInit, - dim3486KuoInit, - dim3487KuoInit, - dim3488KuoInit, - dim3489KuoInit, - dim3490KuoInit, - dim3491KuoInit, - dim3492KuoInit, - dim3493KuoInit, - dim3494KuoInit, - dim3495KuoInit, - dim3496KuoInit, - dim3497KuoInit, - dim3498KuoInit, - dim3499KuoInit, - dim3500KuoInit, - dim3501KuoInit, - dim3502KuoInit, - dim3503KuoInit, - dim3504KuoInit, - dim3505KuoInit, - dim3506KuoInit, - dim3507KuoInit, - dim3508KuoInit, - dim3509KuoInit, - dim3510KuoInit, - dim3511KuoInit, - dim3512KuoInit, - dim3513KuoInit, - dim3514KuoInit, - dim3515KuoInit, - dim3516KuoInit, - dim3517KuoInit, - dim3518KuoInit, - dim3519KuoInit, - dim3520KuoInit, - dim3521KuoInit, - dim3522KuoInit, - dim3523KuoInit, - dim3524KuoInit, - dim3525KuoInit, - dim3526KuoInit, - dim3527KuoInit, - dim3528KuoInit, - dim3529KuoInit, - dim3530KuoInit, - dim3531KuoInit, - dim3532KuoInit, - dim3533KuoInit, - dim3534KuoInit, - dim3535KuoInit, - dim3536KuoInit, - dim3537KuoInit, - dim3538KuoInit, - dim3539KuoInit, - dim3540KuoInit, - dim3541KuoInit, - dim3542KuoInit, - dim3543KuoInit, - dim3544KuoInit, - dim3545KuoInit, - dim3546KuoInit, - dim3547KuoInit, - dim3548KuoInit, - dim3549KuoInit, - dim3550KuoInit, - dim3551KuoInit, - dim3552KuoInit, - dim3553KuoInit, - dim3554KuoInit, - dim3555KuoInit, - dim3556KuoInit, - dim3557KuoInit, - dim3558KuoInit, - dim3559KuoInit, - dim3560KuoInit, - dim3561KuoInit, - dim3562KuoInit, - dim3563KuoInit, - dim3564KuoInit, - dim3565KuoInit, - dim3566KuoInit, - dim3567KuoInit, - dim3568KuoInit, - dim3569KuoInit, - dim3570KuoInit, - dim3571KuoInit, - dim3572KuoInit, - dim3573KuoInit, - dim3574KuoInit, - dim3575KuoInit, - dim3576KuoInit, - dim3577KuoInit, - dim3578KuoInit, - dim3579KuoInit, - dim3580KuoInit, - dim3581KuoInit, - dim3582KuoInit, - dim3583KuoInit, - dim3584KuoInit, - dim3585KuoInit, - dim3586KuoInit, - dim3587KuoInit, - dim3588KuoInit, - dim3589KuoInit, - dim3590KuoInit, - dim3591KuoInit, - dim3592KuoInit, - dim3593KuoInit, - dim3594KuoInit, - dim3595KuoInit, - dim3596KuoInit, - dim3597KuoInit, - dim3598KuoInit, - dim3599KuoInit, - dim3600KuoInit, - dim3601KuoInit, - dim3602KuoInit, - dim3603KuoInit, - dim3604KuoInit, - dim3605KuoInit, - dim3606KuoInit, - dim3607KuoInit, - dim3608KuoInit, - dim3609KuoInit, - dim3610KuoInit, - dim3611KuoInit, - dim3612KuoInit, - dim3613KuoInit, - dim3614KuoInit, - dim3615KuoInit, - dim3616KuoInit, - dim3617KuoInit, - dim3618KuoInit, - dim3619KuoInit, - dim3620KuoInit, - dim3621KuoInit, - dim3622KuoInit, - dim3623KuoInit, - dim3624KuoInit, - dim3625KuoInit, - dim3626KuoInit, - dim3627KuoInit, - dim3628KuoInit, - dim3629KuoInit, - dim3630KuoInit, - dim3631KuoInit, - dim3632KuoInit, - dim3633KuoInit, - dim3634KuoInit, - dim3635KuoInit, - dim3636KuoInit, - dim3637KuoInit, - dim3638KuoInit, - dim3639KuoInit, - dim3640KuoInit, - dim3641KuoInit, - dim3642KuoInit, - dim3643KuoInit, - dim3644KuoInit, - dim3645KuoInit, - dim3646KuoInit, - dim3647KuoInit, - dim3648KuoInit, - dim3649KuoInit, - dim3650KuoInit, - dim3651KuoInit, - dim3652KuoInit, - dim3653KuoInit, - dim3654KuoInit, - dim3655KuoInit, - dim3656KuoInit, - dim3657KuoInit, - dim3658KuoInit, - dim3659KuoInit, - dim3660KuoInit, - dim3661KuoInit, - dim3662KuoInit, - dim3663KuoInit, - dim3664KuoInit, - dim3665KuoInit, - dim3666KuoInit, - dim3667KuoInit, - dim3668KuoInit, - dim3669KuoInit, - dim3670KuoInit, - dim3671KuoInit, - dim3672KuoInit, - dim3673KuoInit, - dim3674KuoInit, - dim3675KuoInit, - dim3676KuoInit, - dim3677KuoInit, - dim3678KuoInit, - dim3679KuoInit, - dim3680KuoInit, - dim3681KuoInit, - dim3682KuoInit, - dim3683KuoInit, - dim3684KuoInit, - dim3685KuoInit, - dim3686KuoInit, - dim3687KuoInit, - dim3688KuoInit, - dim3689KuoInit, - dim3690KuoInit, - dim3691KuoInit, - dim3692KuoInit, - dim3693KuoInit, - dim3694KuoInit, - dim3695KuoInit, - dim3696KuoInit, - dim3697KuoInit, - dim3698KuoInit, - dim3699KuoInit, - dim3700KuoInit, - dim3701KuoInit, - dim3702KuoInit, - dim3703KuoInit, - dim3704KuoInit, - dim3705KuoInit, - dim3706KuoInit, - dim3707KuoInit, - dim3708KuoInit, - dim3709KuoInit, - dim3710KuoInit, - dim3711KuoInit, - dim3712KuoInit, - dim3713KuoInit, - dim3714KuoInit, - dim3715KuoInit, - dim3716KuoInit, - dim3717KuoInit, - dim3718KuoInit, - dim3719KuoInit, - dim3720KuoInit, - dim3721KuoInit, - dim3722KuoInit, - dim3723KuoInit, - dim3724KuoInit, - dim3725KuoInit, - dim3726KuoInit, - dim3727KuoInit, - dim3728KuoInit, - dim3729KuoInit, - dim3730KuoInit, - dim3731KuoInit, - dim3732KuoInit, - dim3733KuoInit, - dim3734KuoInit, - dim3735KuoInit, - dim3736KuoInit, - dim3737KuoInit, - dim3738KuoInit, - dim3739KuoInit, - dim3740KuoInit, - dim3741KuoInit, - dim3742KuoInit, - dim3743KuoInit, - dim3744KuoInit, - dim3745KuoInit, - dim3746KuoInit, - dim3747KuoInit, - dim3748KuoInit, - dim3749KuoInit, - dim3750KuoInit, - dim3751KuoInit, - dim3752KuoInit, - dim3753KuoInit, - dim3754KuoInit, - dim3755KuoInit, - dim3756KuoInit, - dim3757KuoInit, - dim3758KuoInit, - dim3759KuoInit, - dim3760KuoInit, - dim3761KuoInit, - dim3762KuoInit, - dim3763KuoInit, - dim3764KuoInit, - dim3765KuoInit, - dim3766KuoInit, - dim3767KuoInit, - dim3768KuoInit, - dim3769KuoInit, - dim3770KuoInit, - dim3771KuoInit, - dim3772KuoInit, - dim3773KuoInit, - dim3774KuoInit, - dim3775KuoInit, - dim3776KuoInit, - dim3777KuoInit, - dim3778KuoInit, - dim3779KuoInit, - dim3780KuoInit, - dim3781KuoInit, - dim3782KuoInit, - dim3783KuoInit, - dim3784KuoInit, - dim3785KuoInit, - dim3786KuoInit, - dim3787KuoInit, - dim3788KuoInit, - dim3789KuoInit, - dim3790KuoInit, - dim3791KuoInit, - dim3792KuoInit, - dim3793KuoInit, - dim3794KuoInit, - dim3795KuoInit, - dim3796KuoInit, - dim3797KuoInit, - dim3798KuoInit, - dim3799KuoInit, - dim3800KuoInit, - dim3801KuoInit, - dim3802KuoInit, - dim3803KuoInit, - dim3804KuoInit, - dim3805KuoInit, - dim3806KuoInit, - dim3807KuoInit, - dim3808KuoInit, - dim3809KuoInit, - dim3810KuoInit, - dim3811KuoInit, - dim3812KuoInit, - dim3813KuoInit, - dim3814KuoInit, - dim3815KuoInit, - dim3816KuoInit, - dim3817KuoInit, - dim3818KuoInit, - dim3819KuoInit, - dim3820KuoInit, - dim3821KuoInit, - dim3822KuoInit, - dim3823KuoInit, - dim3824KuoInit, - dim3825KuoInit, - dim3826KuoInit, - dim3827KuoInit, - dim3828KuoInit, - dim3829KuoInit, - dim3830KuoInit, - dim3831KuoInit, - dim3832KuoInit, - dim3833KuoInit, - dim3834KuoInit, - dim3835KuoInit, - dim3836KuoInit, - dim3837KuoInit, - dim3838KuoInit, - dim3839KuoInit, - dim3840KuoInit, - dim3841KuoInit, - dim3842KuoInit, - dim3843KuoInit, - dim3844KuoInit, - dim3845KuoInit, - dim3846KuoInit, - dim3847KuoInit, - dim3848KuoInit, - dim3849KuoInit, - dim3850KuoInit, - dim3851KuoInit, - dim3852KuoInit, - dim3853KuoInit, - dim3854KuoInit, - dim3855KuoInit, - dim3856KuoInit, - dim3857KuoInit, - dim3858KuoInit, - dim3859KuoInit, - dim3860KuoInit, - dim3861KuoInit, - dim3862KuoInit, - dim3863KuoInit, - dim3864KuoInit, - dim3865KuoInit, - dim3866KuoInit, - dim3867KuoInit, - dim3868KuoInit, - dim3869KuoInit, - dim3870KuoInit, - dim3871KuoInit, - dim3872KuoInit, - dim3873KuoInit, - dim3874KuoInit, - dim3875KuoInit, - dim3876KuoInit, - dim3877KuoInit, - dim3878KuoInit, - dim3879KuoInit, - dim3880KuoInit, - dim3881KuoInit, - dim3882KuoInit, - dim3883KuoInit, - dim3884KuoInit, - dim3885KuoInit, - dim3886KuoInit, - dim3887KuoInit, - dim3888KuoInit, - dim3889KuoInit, - dim3890KuoInit, - dim3891KuoInit, - dim3892KuoInit, - dim3893KuoInit, - dim3894KuoInit, - dim3895KuoInit, - dim3896KuoInit, - dim3897KuoInit, - dim3898KuoInit, - dim3899KuoInit, - dim3900KuoInit, - dim3901KuoInit, - dim3902KuoInit, - dim3903KuoInit, - dim3904KuoInit, - dim3905KuoInit, - dim3906KuoInit, - dim3907KuoInit, - dim3908KuoInit, - dim3909KuoInit, - dim3910KuoInit, - dim3911KuoInit, - dim3912KuoInit, - dim3913KuoInit, - dim3914KuoInit, - dim3915KuoInit, - dim3916KuoInit, - dim3917KuoInit, - dim3918KuoInit, - dim3919KuoInit, - dim3920KuoInit, - dim3921KuoInit, - dim3922KuoInit, - dim3923KuoInit, - dim3924KuoInit, - dim3925KuoInit, - dim3926KuoInit, - dim3927KuoInit, - dim3928KuoInit, - dim3929KuoInit, - dim3930KuoInit, - dim3931KuoInit, - dim3932KuoInit, - dim3933KuoInit, - dim3934KuoInit, - dim3935KuoInit, - dim3936KuoInit, - dim3937KuoInit, - dim3938KuoInit, - dim3939KuoInit, - dim3940KuoInit, - dim3941KuoInit, - dim3942KuoInit, - dim3943KuoInit, - dim3944KuoInit, - dim3945KuoInit, - dim3946KuoInit, - dim3947KuoInit, - dim3948KuoInit, - dim3949KuoInit, - dim3950KuoInit, - dim3951KuoInit, - dim3952KuoInit, - dim3953KuoInit, - dim3954KuoInit, - dim3955KuoInit, - dim3956KuoInit, - dim3957KuoInit, - dim3958KuoInit, - dim3959KuoInit, - dim3960KuoInit, - dim3961KuoInit, - dim3962KuoInit, - dim3963KuoInit, - dim3964KuoInit, - dim3965KuoInit, - dim3966KuoInit, - dim3967KuoInit, - dim3968KuoInit, - dim3969KuoInit, - dim3970KuoInit, - dim3971KuoInit, - dim3972KuoInit, - dim3973KuoInit, - dim3974KuoInit, - dim3975KuoInit, - dim3976KuoInit, - dim3977KuoInit, - dim3978KuoInit, - dim3979KuoInit, - dim3980KuoInit, - dim3981KuoInit, - dim3982KuoInit, - dim3983KuoInit, - dim3984KuoInit, - dim3985KuoInit, - dim3986KuoInit, - dim3987KuoInit, - dim3988KuoInit, - dim3989KuoInit, - dim3990KuoInit, - dim3991KuoInit, - dim3992KuoInit, - dim3993KuoInit, - dim3994KuoInit, - dim3995KuoInit, - dim3996KuoInit, - dim3997KuoInit, - dim3998KuoInit, - dim3999KuoInit, - dim4000KuoInit, - dim4001KuoInit, - dim4002KuoInit, - dim4003KuoInit, - dim4004KuoInit, - dim4005KuoInit, - dim4006KuoInit, - dim4007KuoInit, - dim4008KuoInit, - dim4009KuoInit, - dim4010KuoInit, - dim4011KuoInit, - dim4012KuoInit, - dim4013KuoInit, - dim4014KuoInit, - dim4015KuoInit, - dim4016KuoInit, - dim4017KuoInit, - dim4018KuoInit, - dim4019KuoInit, - dim4020KuoInit, - dim4021KuoInit, - dim4022KuoInit, - dim4023KuoInit, - dim4024KuoInit, - dim4025KuoInit, - dim4026KuoInit, - dim4027KuoInit, - dim4028KuoInit, - dim4029KuoInit, - dim4030KuoInit, - dim4031KuoInit, - dim4032KuoInit, - dim4033KuoInit, - dim4034KuoInit, - dim4035KuoInit, - dim4036KuoInit, - dim4037KuoInit, - dim4038KuoInit, - dim4039KuoInit, - dim4040KuoInit, - dim4041KuoInit, - dim4042KuoInit, - dim4043KuoInit, - dim4044KuoInit, - dim4045KuoInit, - dim4046KuoInit, - dim4047KuoInit, - dim4048KuoInit, - dim4049KuoInit, - dim4050KuoInit, - dim4051KuoInit, - dim4052KuoInit, - dim4053KuoInit, - dim4054KuoInit, - dim4055KuoInit, - dim4056KuoInit, - dim4057KuoInit, - dim4058KuoInit, - dim4059KuoInit, - dim4060KuoInit, - dim4061KuoInit, - dim4062KuoInit, - dim4063KuoInit, - dim4064KuoInit, - dim4065KuoInit, - dim4066KuoInit, - dim4067KuoInit, - dim4068KuoInit, - dim4069KuoInit, - dim4070KuoInit, - dim4071KuoInit, - dim4072KuoInit, - dim4073KuoInit, - dim4074KuoInit, - dim4075KuoInit, - dim4076KuoInit, - dim4077KuoInit, - dim4078KuoInit, - dim4079KuoInit, - dim4080KuoInit, - dim4081KuoInit, - dim4082KuoInit, - dim4083KuoInit, - dim4084KuoInit, - dim4085KuoInit, - dim4086KuoInit, - dim4087KuoInit, - dim4088KuoInit, - dim4089KuoInit, - dim4090KuoInit, - dim4091KuoInit, - dim4092KuoInit, - dim4093KuoInit, - dim4094KuoInit, - dim4095KuoInit, - dim4096KuoInit, - dim4097KuoInit, - dim4098KuoInit, - dim4099KuoInit, - dim4100KuoInit, - dim4101KuoInit, - dim4102KuoInit, - dim4103KuoInit, - dim4104KuoInit, - dim4105KuoInit, - dim4106KuoInit, - dim4107KuoInit, - dim4108KuoInit, - dim4109KuoInit, - dim4110KuoInit, - dim4111KuoInit, - dim4112KuoInit, - dim4113KuoInit, - dim4114KuoInit, - dim4115KuoInit, - dim4116KuoInit, - dim4117KuoInit, - dim4118KuoInit, - dim4119KuoInit, - dim4120KuoInit, - dim4121KuoInit, - dim4122KuoInit, - dim4123KuoInit, - dim4124KuoInit, - dim4125KuoInit, - dim4126KuoInit, - dim4127KuoInit, - dim4128KuoInit, - dim4129KuoInit, - dim4130KuoInit, - dim4131KuoInit, - dim4132KuoInit, - dim4133KuoInit, - dim4134KuoInit, - dim4135KuoInit, - dim4136KuoInit, - dim4137KuoInit, - dim4138KuoInit, - dim4139KuoInit, - dim4140KuoInit, - dim4141KuoInit, - dim4142KuoInit, - dim4143KuoInit, - dim4144KuoInit, - dim4145KuoInit, - dim4146KuoInit, - dim4147KuoInit, - dim4148KuoInit, - dim4149KuoInit, - dim4150KuoInit, - dim4151KuoInit, - dim4152KuoInit, - dim4153KuoInit, - dim4154KuoInit, - dim4155KuoInit, - dim4156KuoInit, - dim4157KuoInit, - dim4158KuoInit, - dim4159KuoInit, - dim4160KuoInit, - dim4161KuoInit, - dim4162KuoInit, - dim4163KuoInit, - dim4164KuoInit, - dim4165KuoInit, - dim4166KuoInit, - dim4167KuoInit, - dim4168KuoInit, - dim4169KuoInit, - dim4170KuoInit, - dim4171KuoInit, - dim4172KuoInit, - dim4173KuoInit, - dim4174KuoInit, - dim4175KuoInit, - dim4176KuoInit, - dim4177KuoInit, - dim4178KuoInit, - dim4179KuoInit, - dim4180KuoInit, - dim4181KuoInit, - dim4182KuoInit, - dim4183KuoInit, - dim4184KuoInit, - dim4185KuoInit, - dim4186KuoInit, - dim4187KuoInit, - dim4188KuoInit, - dim4189KuoInit, - dim4190KuoInit, - dim4191KuoInit, - dim4192KuoInit, - dim4193KuoInit, - dim4194KuoInit, - dim4195KuoInit, - dim4196KuoInit, - dim4197KuoInit, - dim4198KuoInit, - dim4199KuoInit, - dim4200KuoInit, - dim4201KuoInit, - dim4202KuoInit, - dim4203KuoInit, - dim4204KuoInit, - dim4205KuoInit, - dim4206KuoInit, - dim4207KuoInit, - dim4208KuoInit, - dim4209KuoInit, - dim4210KuoInit, - dim4211KuoInit, - dim4212KuoInit, - dim4213KuoInit, - dim4214KuoInit, - dim4215KuoInit, - dim4216KuoInit, - dim4217KuoInit, - dim4218KuoInit, - dim4219KuoInit, - dim4220KuoInit, - dim4221KuoInit, - dim4222KuoInit, - dim4223KuoInit, - dim4224KuoInit, - dim4225KuoInit, - dim4226KuoInit, - dim4227KuoInit, - dim4228KuoInit, - dim4229KuoInit, - dim4230KuoInit, - dim4231KuoInit, - dim4232KuoInit, - dim4233KuoInit, - dim4234KuoInit, - dim4235KuoInit, - dim4236KuoInit, - dim4237KuoInit, - dim4238KuoInit, - dim4239KuoInit, - dim4240KuoInit, - dim4241KuoInit, - dim4242KuoInit, - dim4243KuoInit, - dim4244KuoInit, - dim4245KuoInit, - dim4246KuoInit, - dim4247KuoInit, - dim4248KuoInit, - dim4249KuoInit, - dim4250KuoInit, - dim4251KuoInit, - dim4252KuoInit, - dim4253KuoInit, - dim4254KuoInit, - dim4255KuoInit, - dim4256KuoInit, - dim4257KuoInit, - dim4258KuoInit, - dim4259KuoInit, - dim4260KuoInit, - dim4261KuoInit, - dim4262KuoInit, - dim4263KuoInit, - dim4264KuoInit, - dim4265KuoInit, - dim4266KuoInit, - dim4267KuoInit, - dim4268KuoInit, - dim4269KuoInit, - dim4270KuoInit, - dim4271KuoInit, - dim4272KuoInit, - dim4273KuoInit, - dim4274KuoInit, - dim4275KuoInit, - dim4276KuoInit, - dim4277KuoInit, - dim4278KuoInit, - dim4279KuoInit, - dim4280KuoInit, - dim4281KuoInit, - dim4282KuoInit, - dim4283KuoInit, - dim4284KuoInit, - dim4285KuoInit, - dim4286KuoInit, - dim4287KuoInit, - dim4288KuoInit, - dim4289KuoInit, - dim4290KuoInit, - dim4291KuoInit, - dim4292KuoInit, - dim4293KuoInit, - dim4294KuoInit, - dim4295KuoInit, - dim4296KuoInit, - dim4297KuoInit, - dim4298KuoInit, - dim4299KuoInit, - dim4300KuoInit, - dim4301KuoInit, - dim4302KuoInit, - dim4303KuoInit, - dim4304KuoInit, - dim4305KuoInit, - dim4306KuoInit, - dim4307KuoInit, - dim4308KuoInit, - dim4309KuoInit, - dim4310KuoInit, - dim4311KuoInit, - dim4312KuoInit, - dim4313KuoInit, - dim4314KuoInit, - dim4315KuoInit, - dim4316KuoInit, - dim4317KuoInit, - dim4318KuoInit, - dim4319KuoInit, - dim4320KuoInit, - dim4321KuoInit, - dim4322KuoInit, - dim4323KuoInit, - dim4324KuoInit, - dim4325KuoInit, - dim4326KuoInit, - dim4327KuoInit, - dim4328KuoInit, - dim4329KuoInit, - dim4330KuoInit, - dim4331KuoInit, - dim4332KuoInit, - dim4333KuoInit, - dim4334KuoInit, - dim4335KuoInit, - dim4336KuoInit, - dim4337KuoInit, - dim4338KuoInit, - dim4339KuoInit, - dim4340KuoInit, - dim4341KuoInit, - dim4342KuoInit, - dim4343KuoInit, - dim4344KuoInit, - dim4345KuoInit, - dim4346KuoInit, - dim4347KuoInit, - dim4348KuoInit, - dim4349KuoInit, - dim4350KuoInit, - dim4351KuoInit, - dim4352KuoInit, - dim4353KuoInit, - dim4354KuoInit, - dim4355KuoInit, - dim4356KuoInit, - dim4357KuoInit, - dim4358KuoInit, - dim4359KuoInit, - dim4360KuoInit, - dim4361KuoInit, - dim4362KuoInit, - dim4363KuoInit, - dim4364KuoInit, - dim4365KuoInit, - dim4366KuoInit, - dim4367KuoInit, - dim4368KuoInit, - dim4369KuoInit, - dim4370KuoInit, - dim4371KuoInit, - dim4372KuoInit, - dim4373KuoInit, - dim4374KuoInit, - dim4375KuoInit, - dim4376KuoInit, - dim4377KuoInit, - dim4378KuoInit, - dim4379KuoInit, - dim4380KuoInit, - dim4381KuoInit, - dim4382KuoInit, - dim4383KuoInit, - dim4384KuoInit, - dim4385KuoInit, - dim4386KuoInit, - dim4387KuoInit, - dim4388KuoInit, - dim4389KuoInit, - dim4390KuoInit, - dim4391KuoInit, - dim4392KuoInit, - dim4393KuoInit, - dim4394KuoInit, - dim4395KuoInit, - dim4396KuoInit, - dim4397KuoInit, - dim4398KuoInit, - dim4399KuoInit, - dim4400KuoInit, - dim4401KuoInit, - dim4402KuoInit, - dim4403KuoInit, - dim4404KuoInit, - dim4405KuoInit, - dim4406KuoInit, - dim4407KuoInit, - dim4408KuoInit, - dim4409KuoInit, - dim4410KuoInit, - dim4411KuoInit, - dim4412KuoInit, - dim4413KuoInit, - dim4414KuoInit, - dim4415KuoInit, - dim4416KuoInit, - dim4417KuoInit, - dim4418KuoInit, - dim4419KuoInit, - dim4420KuoInit, - dim4421KuoInit, - dim4422KuoInit, - dim4423KuoInit, - dim4424KuoInit, - dim4425KuoInit, - dim4426KuoInit, - dim4427KuoInit, - dim4428KuoInit, - dim4429KuoInit, - dim4430KuoInit, - dim4431KuoInit, - dim4432KuoInit, - dim4433KuoInit, - dim4434KuoInit, - dim4435KuoInit, - dim4436KuoInit, - dim4437KuoInit, - dim4438KuoInit, - dim4439KuoInit, - dim4440KuoInit, - dim4441KuoInit, - dim4442KuoInit, - dim4443KuoInit, - dim4444KuoInit, - dim4445KuoInit, - dim4446KuoInit, - dim4447KuoInit, - dim4448KuoInit, - dim4449KuoInit, - dim4450KuoInit, - dim4451KuoInit, - dim4452KuoInit, - dim4453KuoInit, - dim4454KuoInit, - dim4455KuoInit, - dim4456KuoInit, - dim4457KuoInit, - dim4458KuoInit, - dim4459KuoInit, - dim4460KuoInit, - dim4461KuoInit, - dim4462KuoInit, - dim4463KuoInit, - dim4464KuoInit, - dim4465KuoInit, - dim4466KuoInit, - dim4467KuoInit, - dim4468KuoInit, - dim4469KuoInit, - dim4470KuoInit, - dim4471KuoInit, - dim4472KuoInit, - dim4473KuoInit, - dim4474KuoInit, - dim4475KuoInit, - dim4476KuoInit, - dim4477KuoInit, - dim4478KuoInit, - dim4479KuoInit, - dim4480KuoInit, - dim4481KuoInit, - dim4482KuoInit, - dim4483KuoInit, - dim4484KuoInit, - dim4485KuoInit, - dim4486KuoInit, - dim4487KuoInit, - dim4488KuoInit, - dim4489KuoInit, - dim4490KuoInit, - dim4491KuoInit, - dim4492KuoInit, - dim4493KuoInit, - dim4494KuoInit, - dim4495KuoInit, - dim4496KuoInit, - dim4497KuoInit, - dim4498KuoInit, - dim4499KuoInit, - dim4500KuoInit, - dim4501KuoInit, - dim4502KuoInit, - dim4503KuoInit, - dim4504KuoInit, - dim4505KuoInit, - dim4506KuoInit, - dim4507KuoInit, - dim4508KuoInit, - dim4509KuoInit, - dim4510KuoInit, - dim4511KuoInit, - dim4512KuoInit, - dim4513KuoInit, - dim4514KuoInit, - dim4515KuoInit, - dim4516KuoInit, - dim4517KuoInit, - dim4518KuoInit, - dim4519KuoInit, - dim4520KuoInit, - dim4521KuoInit, - dim4522KuoInit, - dim4523KuoInit, - dim4524KuoInit, - dim4525KuoInit, - dim4526KuoInit, - dim4527KuoInit, - dim4528KuoInit, - dim4529KuoInit, - dim4530KuoInit, - dim4531KuoInit, - dim4532KuoInit, - dim4533KuoInit, - dim4534KuoInit, - dim4535KuoInit, - dim4536KuoInit, - dim4537KuoInit, - dim4538KuoInit, - dim4539KuoInit, - dim4540KuoInit, - dim4541KuoInit, - dim4542KuoInit, - dim4543KuoInit, - dim4544KuoInit, - dim4545KuoInit, - dim4546KuoInit, - dim4547KuoInit, - dim4548KuoInit, - dim4549KuoInit, - dim4550KuoInit, - dim4551KuoInit, - dim4552KuoInit, - dim4553KuoInit, - dim4554KuoInit, - dim4555KuoInit, - dim4556KuoInit, - dim4557KuoInit, - dim4558KuoInit, - dim4559KuoInit, - dim4560KuoInit, - dim4561KuoInit, - dim4562KuoInit, - dim4563KuoInit, - dim4564KuoInit, - dim4565KuoInit, - dim4566KuoInit, - dim4567KuoInit, - dim4568KuoInit, - dim4569KuoInit, - dim4570KuoInit, - dim4571KuoInit, - dim4572KuoInit, - dim4573KuoInit, - dim4574KuoInit, - dim4575KuoInit, - dim4576KuoInit, - dim4577KuoInit, - dim4578KuoInit, - dim4579KuoInit, - dim4580KuoInit, - dim4581KuoInit, - dim4582KuoInit, - dim4583KuoInit, - dim4584KuoInit, - dim4585KuoInit, - dim4586KuoInit, - dim4587KuoInit, - dim4588KuoInit, - dim4589KuoInit, - dim4590KuoInit, - dim4591KuoInit, - dim4592KuoInit, - dim4593KuoInit, - dim4594KuoInit, - dim4595KuoInit, - dim4596KuoInit, - dim4597KuoInit, - dim4598KuoInit, - dim4599KuoInit, - dim4600KuoInit, - dim4601KuoInit, - dim4602KuoInit, - dim4603KuoInit, - dim4604KuoInit, - dim4605KuoInit, - dim4606KuoInit, - dim4607KuoInit, - dim4608KuoInit, - dim4609KuoInit, - dim4610KuoInit, - dim4611KuoInit, - dim4612KuoInit, - dim4613KuoInit, - dim4614KuoInit, - dim4615KuoInit, - dim4616KuoInit, - dim4617KuoInit, - dim4618KuoInit, - dim4619KuoInit, - dim4620KuoInit, - dim4621KuoInit, - dim4622KuoInit, - dim4623KuoInit, - dim4624KuoInit, - dim4625KuoInit, - dim4626KuoInit, - dim4627KuoInit, - dim4628KuoInit, - dim4629KuoInit, - dim4630KuoInit, - dim4631KuoInit, - dim4632KuoInit, - dim4633KuoInit, - dim4634KuoInit, - dim4635KuoInit, - dim4636KuoInit, - dim4637KuoInit, - dim4638KuoInit, - dim4639KuoInit, - dim4640KuoInit, - dim4641KuoInit, - dim4642KuoInit, - dim4643KuoInit, - dim4644KuoInit, - dim4645KuoInit, - dim4646KuoInit, - dim4647KuoInit, - dim4648KuoInit, - dim4649KuoInit, - dim4650KuoInit, - dim4651KuoInit, - dim4652KuoInit, - dim4653KuoInit, - dim4654KuoInit, - dim4655KuoInit, - dim4656KuoInit, - dim4657KuoInit, - dim4658KuoInit, - dim4659KuoInit, - dim4660KuoInit, - dim4661KuoInit, - dim4662KuoInit, - dim4663KuoInit, - dim4664KuoInit, - dim4665KuoInit, - dim4666KuoInit, - dim4667KuoInit, - dim4668KuoInit, - dim4669KuoInit, - dim4670KuoInit, - dim4671KuoInit, - dim4672KuoInit, - dim4673KuoInit, - dim4674KuoInit, - dim4675KuoInit, - dim4676KuoInit, - dim4677KuoInit, - dim4678KuoInit, - dim4679KuoInit, - dim4680KuoInit, - dim4681KuoInit, - dim4682KuoInit, - dim4683KuoInit, - dim4684KuoInit, - dim4685KuoInit, - dim4686KuoInit, - dim4687KuoInit, - dim4688KuoInit, - dim4689KuoInit, - dim4690KuoInit, - dim4691KuoInit, - dim4692KuoInit, - dim4693KuoInit, - dim4694KuoInit, - dim4695KuoInit, - dim4696KuoInit, - dim4697KuoInit, - dim4698KuoInit, - dim4699KuoInit, - dim4700KuoInit, - dim4701KuoInit, - dim4702KuoInit, - dim4703KuoInit, - dim4704KuoInit, - dim4705KuoInit, - dim4706KuoInit, - dim4707KuoInit, - dim4708KuoInit, - dim4709KuoInit, - dim4710KuoInit, - dim4711KuoInit, - dim4712KuoInit, - dim4713KuoInit, - dim4714KuoInit, - dim4715KuoInit, - dim4716KuoInit, - dim4717KuoInit, - dim4718KuoInit, - dim4719KuoInit, - dim4720KuoInit, - dim4721KuoInit, - dim4722KuoInit, - dim4723KuoInit, - dim4724KuoInit, - dim4725KuoInit, - dim4726KuoInit, - dim4727KuoInit, - dim4728KuoInit, - dim4729KuoInit, - dim4730KuoInit, - dim4731KuoInit, - dim4732KuoInit, - dim4733KuoInit, - dim4734KuoInit, - dim4735KuoInit, - dim4736KuoInit, - dim4737KuoInit, - dim4738KuoInit, - dim4739KuoInit, - dim4740KuoInit, - dim4741KuoInit, - dim4742KuoInit, - dim4743KuoInit, - dim4744KuoInit, - dim4745KuoInit, - dim4746KuoInit, - dim4747KuoInit, - dim4748KuoInit, - dim4749KuoInit, - dim4750KuoInit, - dim4751KuoInit, - dim4752KuoInit, - dim4753KuoInit, - dim4754KuoInit, - dim4755KuoInit, - dim4756KuoInit, - dim4757KuoInit, - dim4758KuoInit, - dim4759KuoInit, - dim4760KuoInit, - dim4761KuoInit, - dim4762KuoInit, - dim4763KuoInit, - dim4764KuoInit, - dim4765KuoInit, - dim4766KuoInit, - dim4767KuoInit, - dim4768KuoInit, - dim4769KuoInit, - dim4770KuoInit, - dim4771KuoInit, - dim4772KuoInit, - dim4773KuoInit, - dim4774KuoInit, - dim4775KuoInit, - dim4776KuoInit, - dim4777KuoInit, - dim4778KuoInit, - dim4779KuoInit, - dim4780KuoInit, - dim4781KuoInit, - dim4782KuoInit, - dim4783KuoInit, - dim4784KuoInit, - dim4785KuoInit, - dim4786KuoInit, - dim4787KuoInit, - dim4788KuoInit, - dim4789KuoInit, - dim4790KuoInit, - dim4791KuoInit, - dim4792KuoInit, - dim4793KuoInit, - dim4794KuoInit, - dim4795KuoInit, - dim4796KuoInit, - dim4797KuoInit, - dim4798KuoInit, - dim4799KuoInit, - dim4800KuoInit, - dim4801KuoInit, - dim4802KuoInit, - dim4803KuoInit, - dim4804KuoInit, - dim4805KuoInit, - dim4806KuoInit, - dim4807KuoInit, - dim4808KuoInit, - dim4809KuoInit, - dim4810KuoInit, - dim4811KuoInit, - dim4812KuoInit, - dim4813KuoInit, - dim4814KuoInit, - dim4815KuoInit, - dim4816KuoInit, - dim4817KuoInit, - dim4818KuoInit, - dim4819KuoInit, - dim4820KuoInit, - dim4821KuoInit, - dim4822KuoInit, - dim4823KuoInit, - dim4824KuoInit, - dim4825KuoInit, - dim4826KuoInit, - dim4827KuoInit, - dim4828KuoInit, - dim4829KuoInit, - dim4830KuoInit, - dim4831KuoInit, - dim4832KuoInit, - dim4833KuoInit, - dim4834KuoInit, - dim4835KuoInit, - dim4836KuoInit, - dim4837KuoInit, - dim4838KuoInit, - dim4839KuoInit, - dim4840KuoInit, - dim4841KuoInit, - dim4842KuoInit, - dim4843KuoInit, - dim4844KuoInit, - dim4845KuoInit, - dim4846KuoInit, - dim4847KuoInit, - dim4848KuoInit, - dim4849KuoInit, - dim4850KuoInit, - dim4851KuoInit, - dim4852KuoInit, - dim4853KuoInit, - dim4854KuoInit, - dim4855KuoInit, - dim4856KuoInit, - dim4857KuoInit, - dim4858KuoInit, - dim4859KuoInit, - dim4860KuoInit, - dim4861KuoInit, - dim4862KuoInit, - dim4863KuoInit, - dim4864KuoInit, - dim4865KuoInit, - dim4866KuoInit, - dim4867KuoInit, - dim4868KuoInit, - dim4869KuoInit, - dim4870KuoInit, - dim4871KuoInit, - dim4872KuoInit, - dim4873KuoInit, - dim4874KuoInit, - dim4875KuoInit, - dim4876KuoInit, - dim4877KuoInit, - dim4878KuoInit, - dim4879KuoInit, - dim4880KuoInit, - dim4881KuoInit, - dim4882KuoInit, - dim4883KuoInit, - dim4884KuoInit, - dim4885KuoInit, - dim4886KuoInit, - dim4887KuoInit, - dim4888KuoInit, - dim4889KuoInit, - dim4890KuoInit, - dim4891KuoInit, - dim4892KuoInit, - dim4893KuoInit, - dim4894KuoInit, - dim4895KuoInit, - dim4896KuoInit, - dim4897KuoInit, - dim4898KuoInit, - dim4899KuoInit, - dim4900KuoInit, - dim4901KuoInit, - dim4902KuoInit, - dim4903KuoInit, - dim4904KuoInit, - dim4905KuoInit, - dim4906KuoInit, - dim4907KuoInit, - dim4908KuoInit, - dim4909KuoInit, - dim4910KuoInit, - dim4911KuoInit, - dim4912KuoInit, - dim4913KuoInit, - dim4914KuoInit, - dim4915KuoInit, - dim4916KuoInit, - dim4917KuoInit, - dim4918KuoInit, - dim4919KuoInit, - dim4920KuoInit, - dim4921KuoInit, - dim4922KuoInit, - dim4923KuoInit, - dim4924KuoInit, - dim4925KuoInit, - }; - - static ulong[] dim1Kuo3Init = { 1 ,0 }; - static ulong[] dim2Kuo3Init = { 1 , 1 ,0 }; - static ulong[] dim3Kuo3Init = { 1 , 1 , 1 ,0 }; - static ulong[] dim4Kuo3Init = { 1 , 3 , 1 ,0 }; - static ulong[] dim5Kuo3Init = { 1 , 3 , 7 , 1 ,0 }; - static ulong[] dim6Kuo3Init = { 1 , 1 , 3 , 7 ,0 }; - static ulong[] dim7Kuo3Init = { 1 , 3 , 1 , 7 , 23 ,0 }; - static ulong[] dim8Kuo3Init = { 1 , 3 , 1 , 1 , 13 ,0 }; - static ulong[] dim9Kuo3Init = { 1 , 1 , 7 , 7 , 9 ,0 }; - static ulong[] dim10Kuo3Init = { 1 , 1 , 5 , 15 , 21 ,0 }; - static ulong[] dim11Kuo3Init = { 1 , 3 , 5 , 3 , 23 ,0 }; - static ulong[] dim12Kuo3Init = { 1 , 1 , 1 , 15 , 27 ,0 }; - static ulong[] dim13Kuo3Init = { 1 , 3 , 7 , 9 , 1 , 9 ,0 }; - static ulong[] dim14Kuo3Init = { 1 , 1 , 7 , 15 , 31 , 37 ,0 }; - static ulong[] dim15Kuo3Init = { 1 , 1 , 5 , 5 , 31 , 9 ,0 }; - static ulong[] dim16Kuo3Init = { 1 , 3 , 1 , 13 , 3 , 49 ,0 }; - static ulong[] dim17Kuo3Init = { 1 , 1 , 7 , 15 , 1 , 13 ,0 }; - static ulong[] dim18Kuo3Init = { 1 , 3 , 3 , 13 , 29 , 37 ,0 }; - static ulong[] dim19Kuo3Init = { 1 , 1 , 1 , 5 , 13 , 51 , 45 ,0 }; - static ulong[] dim20Kuo3Init = { 1 , 3 , 1 , 7 , 19 , 23 , 51 ,0 }; - static ulong[] dim21Kuo3Init = { 1 , 3 , 7 , 1 , 27 , 45 , 61 ,0 }; - static ulong[] dim22Kuo3Init = { 1 , 3 , 7 , 3 , 9 , 51 , 1 ,0 }; - static ulong[] dim23Kuo3Init = { 1 , 3 , 1 , 11 , 27 , 3 , 23 ,0 }; - static ulong[] dim24Kuo3Init = { 1 , 3 , 7 , 9 , 5 , 35 , 105 ,0 }; - static ulong[] dim25Kuo3Init = { 1 , 1 , 1 , 1 , 19 , 21 , 69 ,0 }; - static ulong[] dim26Kuo3Init = { 1 , 3 , 3 , 5 , 11 , 61 , 41 ,0 }; - static ulong[] dim27Kuo3Init = { 1 , 1 , 3 , 13 , 15 , 17 , 25 ,0 }; - static ulong[] dim28Kuo3Init = { 1 , 1 , 1 , 13 , 19 , 47 , 19 ,0 }; - static ulong[] dim29Kuo3Init = { 1 , 1 , 7 , 1 , 31 , 23 , 127 ,0 }; - static ulong[] dim30Kuo3Init = { 1 , 1 , 7 , 1 , 31 , 59 , 123 ,0 }; - static ulong[] dim31Kuo3Init = { 1 , 1 , 5 , 5 , 13 , 39 , 109 ,0 }; - static ulong[] dim32Kuo3Init = { 1 , 3 , 7 , 15 , 23 , 19 , 127 ,0 }; - static ulong[] dim33Kuo3Init = { 1 , 1 , 5 , 3 , 1 , 47 , 15 ,0 }; - static ulong[] dim34Kuo3Init = { 1 , 1 , 3 , 13 , 23 , 1 , 61 ,0 }; - static ulong[] dim35Kuo3Init = { 1 , 3 , 3 , 3 , 3 , 35 , 83 ,0 }; - static ulong[] dim36Kuo3Init = { 1 , 1 , 5 , 5 , 13 , 5 , 19 ,0 }; - static ulong[] dim37Kuo3Init = { 1 , 1 , 5 , 9 , 13 , 51 , 25 , 117 ,0 }; - static ulong[] dim38Kuo3Init = { 1 , 1 , 5 , 11 , 19 , 33 , 111 , 71 ,0 }; - static ulong[] dim39Kuo3Init = { 1 , 3 , 1 , 9 , 5 , 63 , 33 , 27 ,0 }; - static ulong[] dim40Kuo3Init = { 1 , 3 , 1 , 5 , 19 , 57 , 15 , 181 ,0 }; - static ulong[] dim41Kuo3Init = { 1 , 3 , 7 , 5 , 5 , 41 , 115 , 15 ,0 }; - static ulong[] dim42Kuo3Init = { 1 , 3 , 1 , 9 , 9 , 23 , 45 , 43 ,0 }; - static ulong[] dim43Kuo3Init = { 1 , 1 , 1 , 1 , 13 , 1 , 109 , 29 ,0 }; - static ulong[] dim44Kuo3Init = { 1 , 1 , 5 , 13 , 31 , 29 , 95 , 111 ,0 }; - static ulong[] dim45Kuo3Init = { 1 , 1 , 1 , 3 , 9 , 39 , 109 , 17 ,0 }; - static ulong[] dim46Kuo3Init = { 1 , 1 , 1 , 5 , 17 , 17 , 47 , 153 ,0 }; - static ulong[] dim47Kuo3Init = { 1 , 1 , 1 , 3 , 31 , 57 , 43 , 17 ,0 }; - static ulong[] dim48Kuo3Init = { 1 , 3 , 7 , 3 , 29 , 17 , 91 , 153 ,0 }; - static ulong[] dim49Kuo3Init = { 1 , 3 , 3 , 5 , 21 , 7 , 73 , 91 ,0 }; - static ulong[] dim50Kuo3Init = { 1 , 1 , 7 , 11 , 13 , 9 , 83 , 213 ,0 }; - static ulong[] dim51Kuo3Init = { 1 , 1 , 7 , 3 , 17 , 55 , 37 , 189 ,0 }; - static ulong[] dim52Kuo3Init = { 1 , 3 , 7 , 5 , 7 , 15 , 39 , 247 ,0 }; - static ulong[] dim53Kuo3Init = { 1 , 3 , 1 , 9 , 27 , 41 , 83 , 63 , 89 ,0 }; - static ulong[] dim54Kuo3Init = { 1 , 3 , 7 , 11 , 9 , 51 , 59 , 89 , 11 ,0 }; - static ulong[] dim55Kuo3Init = { 1 , 3 , 5 , 13 , 29 , 21 , 55 , 65 , 45 ,0 }; - static ulong[] dim56Kuo3Init = { 1 , 3 , 7 , 5 , 29 , 33 , 83 , 229 , 287 ,0 }; - static ulong[] dim57Kuo3Init = { 1 , 3 , 5 , 15 , 13 , 7 , 89 , 151 , 391 ,0 }; - static ulong[] dim58Kuo3Init = { 1 , 3 , 3 , 9 , 29 , 3 , 111 , 177 , 475 ,0 }; - static ulong[] dim59Kuo3Init = { 1 , 3 , 1 , 1 , 5 , 11 , 23 , 33 , 337 ,0 }; - static ulong[] dim60Kuo3Init = { 1 , 1 , 1 , 15 , 1 , 23 , 111 , 175 , 125 ,0 }; - static ulong[] dim61Kuo3Init = { 1 , 3 , 7 , 15 , 27 , 47 , 31 , 103 , 245 ,0 }; - static ulong[] dim62Kuo3Init = { 1 , 3 , 5 , 7 , 7 , 3 , 127 , 187 , 245 ,0 }; - static ulong[] dim63Kuo3Init = { 1 , 1 , 1 , 13 , 13 , 33 , 33 , 249 , 381 ,0 }; - static ulong[] dim64Kuo3Init = { 1 , 1 , 3 , 11 , 27 , 45 , 95 , 31 , 419 ,0 }; - static ulong[] dim65Kuo3Init = { 1 , 1 , 1 , 13 , 17 , 53 , 35 , 197 , 455 ,0 }; - static ulong[] dim66Kuo3Init = { 1 , 1 , 5 , 7 , 21 , 43 , 93 , 237 , 467 ,0 }; - static ulong[] dim67Kuo3Init = { 1 , 3 , 5 , 15 , 1 , 19 , 43 , 245 , 193 ,0 }; - static ulong[] dim68Kuo3Init = { 1 , 1 , 7 , 11 , 21 , 21 , 23 , 147 , 429 ,0 }; - static ulong[] dim69Kuo3Init = { 1 , 3 , 3 , 7 , 27 , 33 , 99 , 127 , 97 ,0 }; - static ulong[] dim70Kuo3Init = { 1 , 1 , 5 , 11 , 13 , 21 , 101 , 73 , 17 ,0 }; - static ulong[] dim71Kuo3Init = { 1 , 3 , 1 , 13 , 3 , 41 , 7 , 237 , 311 ,0 }; - static ulong[] dim72Kuo3Init = { 1 , 3 , 7 , 1 , 1 , 43 , 115 , 215 , 499 ,0 }; - static ulong[] dim73Kuo3Init = { 1 , 3 , 1 , 13 , 1 , 9 , 113 , 121 , 473 ,0 }; - static ulong[] dim74Kuo3Init = { 1 , 1 , 5 , 5 , 21 , 7 , 5 , 171 , 41 ,0 }; - static ulong[] dim75Kuo3Init = { 1 , 3 , 7 , 15 , 31 , 11 , 87 , 89 , 495 ,0 }; - static ulong[] dim76Kuo3Init = { 1 , 1 , 5 , 1 , 9 , 9 , 19 , 161 , 325 ,0 }; - static ulong[] dim77Kuo3Init = { 1 , 3 , 3 , 11 , 15 , 35 , 75 , 99 , 331 ,0 }; - static ulong[] dim78Kuo3Init = { 1 , 3 , 1 , 1 , 9 , 27 , 103 , 93 , 187 ,0 }; - static ulong[] dim79Kuo3Init = { 1 , 1 , 3 , 11 , 19 , 43 , 123 , 169 , 325 ,0 }; - static ulong[] dim80Kuo3Init = { 1 , 1 , 7 , 9 , 17 , 59 , 65 , 139 , 89 ,0 }; - static ulong[] dim81Kuo3Init = { 1 , 1 , 5 , 15 , 19 , 57 , 29 , 151 , 131 ,0 }; - static ulong[] dim82Kuo3Init = { 1 , 1 , 1 , 1 , 23 , 49 , 75 , 85 , 365 ,0 }; - static ulong[] dim83Kuo3Init = { 1 , 1 , 5 , 13 , 11 , 45 , 31 , 245 , 311 ,0 }; - static ulong[] dim84Kuo3Init = { 1 , 3 , 7 , 5 , 5 , 13 , 23 , 1 , 461 ,0 }; - static ulong[] dim85Kuo3Init = { 1 , 3 , 1 , 11 , 17 , 23 , 19 , 43 , 393 ,0 }; - static ulong[] dim86Kuo3Init = { 1 , 1 , 3 , 5 , 27 , 9 , 37 , 105 , 491 ,0 }; - static ulong[] dim87Kuo3Init = { 1 , 3 , 3 , 1 , 15 , 51 , 107 , 231 , 39 ,0 }; - static ulong[] dim88Kuo3Init = { 1 , 1 , 1 , 5 , 21 , 57 , 59 , 143 , 47 ,0 }; - static ulong[] dim89Kuo3Init = { 1 , 1 , 7 , 7 , 23 , 45 , 29 , 33 , 403 ,0 }; - static ulong[] dim90Kuo3Init = { 1 , 3 , 7 , 5 , 31 , 7 , 91 , 5 , 355 ,0 }; - static ulong[] dim91Kuo3Init = { 1 , 3 , 5 , 1 , 25 , 7 , 15 , 191 , 45 ,0 }; - static ulong[] dim92Kuo3Init = { 1 , 1 , 7 , 5 , 9 , 33 , 63 , 75 , 45 ,0 }; - static ulong[] dim93Kuo3Init = { 1 , 3 , 5 , 7 , 27 , 39 , 83 , 121 , 495 ,0 }; - static ulong[] dim94Kuo3Init = { 1 , 1 , 7 , 5 , 1 , 25 , 71 , 31 , 33 ,0 }; - static ulong[] dim95Kuo3Init = { 1 , 1 , 7 , 13 , 13 , 63 , 85 , 203 , 491 ,0 }; - static ulong[] dim96Kuo3Init = { 1 , 3 , 3 , 11 , 21 , 39 , 25 , 213 , 423 ,0 }; - static ulong[] dim97Kuo3Init = { 1 , 3 , 5 , 11 , 3 , 7 , 115 , 3 , 191 ,0 }; - static ulong[] dim98Kuo3Init = { 1 , 1 , 1 , 9 , 19 , 1 , 51 , 247 , 301 ,0 }; - static ulong[] dim99Kuo3Init = { 1 , 1 , 1 , 7 , 13 , 15 , 45 , 243 , 453 ,0 }; - static ulong[] dim100Kuo3Init = { 1 , 1 , 1 , 7 , 25 , 1 , 113 , 153 , 105 ,0 }; - static ulong[] dim101Kuo3Init = { 1 , 3 , 5 , 11 , 19 , 15 , 3 , 245 , 443 , 651 ,0 }; - static ulong[] dim102Kuo3Init = { 1 , 3 , 7 , 15 , 13 , 35 , 5 , 167 , 233 , 9 ,0 }; - static ulong[] dim103Kuo3Init = { 1 , 3 , 5 , 11 , 21 , 63 , 95 , 45 , 411 , 189 ,0 }; - static ulong[] dim104Kuo3Init = { 1 , 1 , 7 , 7 , 31 , 11 , 81 , 87 , 15 , 677 ,0 }; - static ulong[] dim105Kuo3Init = { 1 , 3 , 3 , 9 , 13 , 21 , 27 , 215 , 459 , 923 ,0 }; - static ulong[] dim106Kuo3Init = { 1 , 1 , 1 , 9 , 13 , 49 , 23 , 7 , 441 , 31 ,0 }; - static ulong[] dim107Kuo3Init = { 1 , 3 , 1 , 7 , 27 , 19 , 5 , 71 , 391 , 159 ,0 }; - static ulong[] dim108Kuo3Init = { 1 , 3 , 7 , 9 , 9 , 55 , 77 , 95 , 353 , 519 ,0 }; - static ulong[] dim109Kuo3Init = { 1 , 3 , 1 , 1 , 23 , 51 , 51 , 113 , 33 , 725 ,0 }; - static ulong[] dim110Kuo3Init = { 1 , 3 , 3 , 1 , 21 , 3 , 107 , 223 , 261 , 913 ,0 }; - static ulong[] dim111Kuo3Init = { 1 , 1 , 1 , 7 , 9 , 31 , 83 , 219 , 285 , 695 ,0 }; - static ulong[] dim112Kuo3Init = { 1 , 1 , 3 , 15 , 1 , 1 , 23 , 49 , 39 , 485 ,0 }; - static ulong[] dim113Kuo3Init = { 1 , 1 , 1 , 9 , 5 , 61 , 71 , 121 , 427 , 83 ,0 }; - static ulong[] dim114Kuo3Init = { 1 , 1 , 3 , 3 , 5 , 45 , 111 , 227 , 261 , 957 ,0 }; - static ulong[] dim115Kuo3Init = { 1 , 3 , 7 , 7 , 17 , 51 , 61 , 85 , 183 , 831 ,0 }; - static ulong[] dim116Kuo3Init = { 1 , 3 , 3 , 5 , 13 , 35 , 27 , 135 , 189 , 743 ,0 }; - static ulong[] dim117Kuo3Init = { 1 , 3 , 1 , 5 , 7 , 5 , 7 , 149 , 333 , 287 ,0 }; - static ulong[] dim118Kuo3Init = { 1 , 3 , 1 , 13 , 19 , 57 , 127 , 201 , 365 , 359 ,0 }; - static ulong[] dim119Kuo3Init = { 1 , 1 , 5 , 9 , 27 , 23 , 79 , 173 , 227 , 299 ,0 }; - static ulong[] dim120Kuo3Init = { 1 , 1 , 7 , 7 , 9 , 35 , 123 , 1 , 289 , 43 ,0 }; - static ulong[] dim121Kuo3Init = { 1 , 1 , 5 , 15 , 15 , 17 , 57 , 175 , 97 , 585 ,0 }; - static ulong[] dim122Kuo3Init = { 1 , 1 , 3 , 13 , 9 , 23 , 123 , 45 , 463 , 137 ,0 }; - static ulong[] dim123Kuo3Init = { 1 , 3 , 1 , 9 , 19 , 3 , 81 , 35 , 221 , 75 ,0 }; - static ulong[] dim124Kuo3Init = { 1 , 3 , 7 , 13 , 31 , 41 , 53 , 207 , 253 , 957 ,0 }; - static ulong[] dim125Kuo3Init = { 1 , 1 , 1 , 5 , 1 , 35 , 51 , 67 , 289 , 417 ,0 }; - static ulong[] dim126Kuo3Init = { 1 , 1 , 1 , 11 , 27 , 21 , 121 , 235 , 49 , 3 ,0 }; - static ulong[] dim127Kuo3Init = { 1 , 3 , 7 , 5 , 15 , 59 , 25 , 43 , 141 , 965 ,0 }; - static ulong[] dim128Kuo3Init = { 1 , 1 , 5 , 3 , 7 , 23 , 121 , 161 , 223 , 245 ,0 }; - static ulong[] dim129Kuo3Init = { 1 , 3 , 7 , 15 , 5 , 5 , 49 , 235 , 329 , 777 ,0 }; - static ulong[] dim130Kuo3Init = { 1 , 3 , 1 , 11 , 7 , 49 , 41 , 187 , 221 , 639 ,0 }; - static ulong[] dim131Kuo3Init = { 1 , 1 , 5 , 9 , 1 , 11 , 41 , 39 , 319 , 203 ,0 }; - static ulong[] dim132Kuo3Init = { 1 , 3 , 3 , 3 , 21 , 61 , 23 , 233 , 397 , 251 ,0 }; - static ulong[] dim133Kuo3Init = { 1 , 1 , 1 , 1 , 27 , 49 , 87 , 251 , 371 , 973 ,0 }; - static ulong[] dim134Kuo3Init = { 1 , 1 , 5 , 11 , 11 , 43 , 57 , 59 , 153 , 695 ,0 }; - static ulong[] dim135Kuo3Init = { 1 , 1 , 3 , 7 , 29 , 57 , 87 , 17 , 129 , 511 ,0 }; - static ulong[] dim136Kuo3Init = { 1 , 3 , 7 , 7 , 5 , 39 , 71 , 27 , 59 , 49 ,0 }; - static ulong[] dim137Kuo3Init = { 1 , 3 , 3 , 5 , 1 , 49 , 65 , 87 , 453 , 515 ,0 }; - static ulong[] dim138Kuo3Init = { 1 , 3 , 3 , 9 , 19 , 3 , 3 , 167 , 85 , 653 ,0 }; - static ulong[] dim139Kuo3Init = { 1 , 1 , 7 , 15 , 7 , 51 , 67 , 37 , 245 , 943 ,0 }; - static ulong[] dim140Kuo3Init = { 1 , 1 , 5 , 7 , 1 , 7 , 21 , 5 , 135 , 999 ,0 }; - static ulong[] dim141Kuo3Init = { 1 , 3 , 3 , 5 , 19 , 1 , 7 , 179 , 405 , 589 ,0 }; - static ulong[] dim142Kuo3Init = { 1 , 1 , 3 , 15 , 3 , 3 , 43 , 79 , 501 , 287 ,0 }; - static ulong[] dim143Kuo3Init = { 1 , 1 , 3 , 9 , 21 , 39 , 59 , 181 , 99 , 737 ,0 }; - static ulong[] dim144Kuo3Init = { 1 , 3 , 7 , 1 , 3 , 11 , 91 , 33 , 273 , 651 ,0 }; - static ulong[] dim145Kuo3Init = { 1 , 1 , 5 , 11 , 23 , 47 , 97 , 253 , 465 , 741 ,0 }; - static ulong[] dim146Kuo3Init = { 1 , 1 , 5 , 1 , 7 , 45 , 33 , 203 , 297 , 193 ,0 }; - static ulong[] dim147Kuo3Init = { 1 , 1 , 5 , 3 , 31 , 55 , 63 , 41 , 243 , 953 ,0 }; - static ulong[] dim148Kuo3Init = { 1 , 3 , 5 , 9 , 9 , 53 , 51 , 71 , 281 , 447 ,0 }; - static ulong[] dim149Kuo3Init = { 1 , 3 , 3 , 9 , 5 , 63 , 77 , 89 , 213 , 527 ,0 }; - static ulong[] dim150Kuo3Init = { 1 , 1 , 3 , 11 , 31 , 15 , 3 , 91 , 321 , 997 ,0 }; - static ulong[] dim151Kuo3Init = { 1 , 3 , 5 , 7 , 31 , 27 , 117 , 179 , 389 , 645 ,0 }; - static ulong[] dim152Kuo3Init = { 1 , 3 , 3 , 9 , 21 , 37 , 41 , 49 , 143 , 401 ,0 }; - static ulong[] dim153Kuo3Init = { 1 , 3 , 1 , 3 , 31 , 57 , 77 , 129 , 49 , 245 ,0 }; - static ulong[] dim154Kuo3Init = { 1 , 3 , 1 , 15 , 27 , 7 , 23 , 69 , 177 , 1009 ,0 }; - static ulong[] dim155Kuo3Init = { 1 , 3 , 3 , 3 , 11 , 9 , 101 , 141 , 313 , 739 ,0 }; - static ulong[] dim156Kuo3Init = { 1 , 1 , 3 , 13 , 27 , 31 , 27 , 129 , 139 , 645 ,0 }; - static ulong[] dim157Kuo3Init = { 1 , 3 , 7 , 5 , 7 , 11 , 99 , 145 , 313 , 641 ,0 }; - static ulong[] dim158Kuo3Init = { 1 , 3 , 1 , 13 , 15 , 3 , 55 , 183 , 153 , 743 ,0 }; - static ulong[] dim159Kuo3Init = { 1 , 3 , 5 , 1 , 23 , 63 , 53 , 237 , 267 , 333 ,0 }; - static ulong[] dim160Kuo3Init = { 1 , 3 , 1 , 9 , 5 , 27 , 45 , 49 , 9 , 911 ,0 }; - static ulong[] dim161Kuo3Init = { 1 , 1 , 3 , 9 , 11 , 51 , 97 , 231 , 295 , 877 , 353 ,0 }; - static ulong[] dim162Kuo3Init = { 1 , 3 , 7 , 3 , 15 , 55 , 125 , 241 , 149 , 417 , 449 ,0 }; - static ulong[] dim163Kuo3Init = { 1 , 1 , 7 , 1 , 7 , 31 , 89 , 91 , 259 , 819 , 849 ,0 }; - static ulong[] dim164Kuo3Init = { 1 , 3 , 1 , 11 , 3 , 9 , 79 , 77 , 195 , 39 , 937 ,0 }; - static ulong[] dim165Kuo3Init = { 1 , 1 , 3 , 15 , 27 , 37 , 123 , 233 , 221 , 661 , 323 ,0 }; - static ulong[] dim166Kuo3Init = { 1 , 3 , 7 , 7 , 31 , 59 , 121 , 71 , 19 , 723 , 1713 ,0 }; - static ulong[] dim167Kuo3Init = { 1 , 1 , 5 , 5 , 23 , 43 , 75 , 201 , 7 , 565 , 293 ,0 }; - static ulong[] dim168Kuo3Init = { 1 , 1 , 1 , 3 , 13 , 39 , 115 , 209 , 239 , 439 , 1623 ,0 }; - static ulong[] dim169Kuo3Init = { 1 , 3 , 7 , 5 , 29 , 39 , 69 , 241 , 71 , 465 , 77 ,0 }; - static ulong[] dim170Kuo3Init = { 1 , 1 , 1 , 13 , 17 , 1 , 91 , 67 , 491 , 969 , 1709 ,0 }; - static ulong[] dim171Kuo3Init = { 1 , 3 , 1 , 3 , 7 , 37 , 17 , 185 , 365 , 571 , 757 ,0 }; - static ulong[] dim172Kuo3Init = { 1 , 1 , 5 , 1 , 29 , 47 , 87 , 65 , 171 , 893 , 1659 ,0 }; - static ulong[] dim173Kuo3Init = { 1 , 3 , 5 , 5 , 13 , 5 , 21 , 151 , 91 , 801 , 1415 ,0 }; - static ulong[] dim174Kuo3Init = { 1 , 3 , 3 , 13 , 27 , 35 , 81 , 49 , 417 , 315 , 1039 ,0 }; - static ulong[] dim175Kuo3Init = { 1 , 3 , 3 , 7 , 13 , 11 , 63 , 19 , 35 , 659 , 83 ,0 }; - static ulong[] dim176Kuo3Init = { 1 , 1 , 1 , 15 , 11 , 55 , 43 , 181 , 45 , 657 , 681 ,0 }; - static ulong[] dim177Kuo3Init = { 1 , 3 , 7 , 1 , 23 , 9 , 73 , 55 , 143 , 731 , 401 ,0 }; - static ulong[] dim178Kuo3Init = { 1 , 1 , 3 , 1 , 5 , 49 , 125 , 1 , 113 , 41 , 1733 ,0 }; - static ulong[] dim179Kuo3Init = { 1 , 1 , 3 , 5 , 21 , 63 , 45 , 119 , 67 , 499 , 141 ,0 }; - static ulong[] dim180Kuo3Init = { 1 , 3 , 5 , 11 , 29 , 39 , 45 , 93 , 415 , 515 , 413 ,0 }; - static ulong[] dim181Kuo3Init = { 1 , 1 , 7 , 15 , 5 , 3 , 79 , 201 , 5 , 473 , 55 ,0 }; - static ulong[] dim182Kuo3Init = { 1 , 1 , 3 , 7 , 25 , 31 , 55 , 61 , 175 , 919 , 2047 ,0 }; - static ulong[] dim183Kuo3Init = { 1 , 1 , 7 , 3 , 31 , 61 , 15 , 147 , 409 , 249 , 1677 ,0 }; - static ulong[] dim184Kuo3Init = { 1 , 3 , 3 , 9 , 11 , 37 , 9 , 65 , 383 , 689 , 111 ,0 }; - static ulong[] dim185Kuo3Init = { 1 , 1 , 5 , 1 , 31 , 23 , 93 , 15 , 327 , 973 , 765 ,0 }; - static ulong[] dim186Kuo3Init = { 1 , 3 , 7 , 15 , 25 , 17 , 115 , 245 , 205 , 169 , 13 ,0 }; - static ulong[] dim187Kuo3Init = { 1 , 1 , 5 , 15 , 15 , 27 , 109 , 39 , 289 , 135 , 693 ,0 }; - static ulong[] dim188Kuo3Init = { 1 , 1 , 7 , 3 , 23 , 1 , 119 , 199 , 1 , 661 , 1741 ,0 }; - static ulong[] dim189Kuo3Init = { 1 , 3 , 5 , 13 , 7 , 29 , 3 , 55 , 369 , 903 , 715 ,0 }; - static ulong[] dim190Kuo3Init = { 1 , 1 , 5 , 1 , 29 , 19 , 31 , 7 , 165 , 1019 , 467 ,0 }; - static ulong[] dim191Kuo3Init = { 1 , 1 , 7 , 11 , 27 , 33 , 105 , 27 , 271 , 55 , 475 ,0 }; - static ulong[] dim192Kuo3Init = { 1 , 1 , 5 , 1 , 27 , 9 , 63 , 157 , 507 , 491 , 1525 ,0 }; - static ulong[] dim193Kuo3Init = { 1 , 3 , 3 , 9 , 1 , 41 , 71 , 239 , 471 , 147 , 505 ,0 }; - static ulong[] dim194Kuo3Init = { 1 , 3 , 3 , 1 , 25 , 11 , 1 , 35 , 127 , 583 , 2043 ,0 }; - static ulong[] dim195Kuo3Init = { 1 , 3 , 7 , 15 , 1 , 13 , 119 , 183 , 89 , 555 , 1739 ,0 }; - static ulong[] dim196Kuo3Init = { 1 , 1 , 1 , 3 , 3 , 45 , 61 , 163 , 357 , 679 , 641 ,0 }; - static ulong[] dim197Kuo3Init = { 1 , 3 , 5 , 13 , 23 , 27 , 57 , 125 , 393 , 917 , 939 ,0 }; - static ulong[] dim198Kuo3Init = { 1 , 1 , 3 , 9 , 9 , 21 , 85 , 105 , 111 , 537 , 733 ,0 }; - static ulong[] dim199Kuo3Init = { 1 , 1 , 3 , 15 , 9 , 61 , 43 , 103 , 65 , 227 , 315 ,0 }; - static ulong[] dim200Kuo3Init = { 1 , 1 , 7 , 9 , 9 , 7 , 31 , 219 , 293 , 441 , 559 ,0 }; - static ulong[] dim201Kuo3Init = { 1 , 1 , 3 , 1 , 23 , 21 , 25 , 229 , 303 , 537 , 1655 ,0 }; - static ulong[] dim202Kuo3Init = { 1 , 3 , 7 , 7 , 31 , 5 , 21 , 177 , 435 , 899 , 1939 ,0 }; - static ulong[] dim203Kuo3Init = { 1 , 3 , 3 , 3 , 11 , 43 , 77 , 131 , 353 , 11 , 157 ,0 }; - static ulong[] dim204Kuo3Init = { 1 , 3 , 3 , 3 , 5 , 45 , 13 , 39 , 459 , 261 , 237 ,0 }; - static ulong[] dim205Kuo3Init = { 1 , 3 , 5 , 7 , 23 , 1 , 55 , 63 , 9 , 755 , 589 ,0 }; - static ulong[] dim206Kuo3Init = { 1 , 1 , 7 , 5 , 3 , 11 , 59 , 167 , 145 , 459 , 617 ,0 }; - static ulong[] dim207Kuo3Init = { 1 , 3 , 1 , 13 , 31 , 49 , 53 , 235 , 1 , 37 , 1373 ,0 }; - static ulong[] dim208Kuo3Init = { 1 , 1 , 7 , 11 , 27 , 63 , 21 , 59 , 183 , 297 , 15 ,0 }; - static ulong[] dim209Kuo3Init = { 1 , 3 , 7 , 15 , 3 , 61 , 57 , 205 , 359 , 799 , 1591 ,0 }; - static ulong[] dim210Kuo3Init = { 1 , 1 , 1 , 3 , 29 , 29 , 121 , 193 , 405 , 161 , 909 ,0 }; - static ulong[] dim211Kuo3Init = { 1 , 1 , 5 , 5 , 15 , 43 , 19 , 87 , 337 , 595 , 551 ,0 }; - static ulong[] dim212Kuo3Init = { 1 , 3 , 3 , 7 , 27 , 23 , 109 , 127 , 107 , 793 , 787 ,0 }; - static ulong[] dim213Kuo3Init = { 1 , 1 , 3 , 5 , 9 , 11 , 63 , 21 , 363 , 403 , 981 ,0 }; - static ulong[] dim214Kuo3Init = { 1 , 1 , 3 , 5 , 1 , 39 , 43 , 71 , 5 , 151 , 1535 ,0 }; - static ulong[] dim215Kuo3Init = { 1 , 1 , 7 , 3 , 1 , 33 , 65 , 249 , 81 , 889 , 1591 ,0 }; - static ulong[] dim216Kuo3Init = { 1 , 3 , 5 , 11 , 15 , 53 , 117 , 47 , 13 , 215 , 1953 ,0 }; - static ulong[] dim217Kuo3Init = { 1 , 1 , 3 , 13 , 15 , 13 , 49 , 209 , 137 , 403 , 1373 ,0 }; - static ulong[] dim218Kuo3Init = { 1 , 1 , 3 , 15 , 25 , 13 , 123 , 193 , 275 , 235 , 1975 ,0 }; - static ulong[] dim219Kuo3Init = { 1 , 3 , 1 , 3 , 21 , 55 , 109 , 115 , 411 , 413 , 2023 ,0 }; - static ulong[] dim220Kuo3Init = { 1 , 3 , 3 , 1 , 5 , 7 , 53 , 161 , 221 , 529 , 489 ,0 }; - static ulong[] dim221Kuo3Init = { 1 , 1 , 3 , 5 , 25 , 27 , 103 , 31 , 7 , 103 , 343 ,0 }; - static ulong[] dim222Kuo3Init = { 1 , 1 , 7 , 11 , 19 , 47 , 45 , 201 , 499 , 255 , 1501 ,0 }; - static ulong[] dim223Kuo3Init = { 1 , 3 , 1 , 1 , 5 , 7 , 79 , 113 , 445 , 515 , 287 ,0 }; - static ulong[] dim224Kuo3Init = { 1 , 1 , 7 , 11 , 7 , 35 , 87 , 145 , 115 , 773 , 1415 ,0 }; - static ulong[] dim225Kuo3Init = { 1 , 1 , 1 , 13 , 15 , 25 , 83 , 143 , 347 , 473 , 415 ,0 }; - static ulong[] dim226Kuo3Init = { 1 , 3 , 1 , 11 , 23 , 45 , 79 , 245 , 81 , 835 , 589 ,0 }; - static ulong[] dim227Kuo3Init = { 1 , 1 , 1 , 13 , 25 , 49 , 17 , 15 , 255 , 421 , 1195 ,0 }; - static ulong[] dim228Kuo3Init = { 1 , 1 , 3 , 1 , 13 , 31 , 103 , 189 , 43 , 389 , 1497 ,0 }; - static ulong[] dim229Kuo3Init = { 1 , 3 , 5 , 7 , 3 , 63 , 21 , 151 , 339 , 525 , 455 ,0 }; - static ulong[] dim230Kuo3Init = { 1 , 3 , 3 , 13 , 23 , 29 , 101 , 25 , 461 , 631 , 2017 ,0 }; - static ulong[] dim231Kuo3Init = { 1 , 1 , 5 , 13 , 7 , 57 , 11 , 181 , 215 , 911 , 463 ,0 }; - static ulong[] dim232Kuo3Init = { 1 , 3 , 7 , 1 , 1 , 45 , 41 , 101 , 263 , 835 , 1985 ,0 }; - static ulong[] dim233Kuo3Init = { 1 , 3 , 3 , 3 , 25 , 13 , 127 , 245 , 137 , 709 , 993 ,0 }; - static ulong[] dim234Kuo3Init = { 1 , 3 , 7 , 3 , 5 , 19 , 23 , 55 , 51 , 367 , 1513 ,0 }; - static ulong[] dim235Kuo3Init = { 1 , 1 , 5 , 3 , 13 , 39 , 101 , 119 , 119 , 835 , 875 ,0 }; - static ulong[] dim236Kuo3Init = { 1 , 1 , 7 , 13 , 17 , 27 , 103 , 31 , 223 , 461 , 1267 ,0 }; - static ulong[] dim237Kuo3Init = { 1 , 3 , 5 , 13 , 29 , 29 , 29 , 189 , 13 , 647 , 1931 ,0 }; - static ulong[] dim238Kuo3Init = { 1 , 3 , 5 , 15 , 9 , 27 , 127 , 43 , 341 , 939 , 1981 ,0 }; - static ulong[] dim239Kuo3Init = { 1 , 1 , 7 , 11 , 27 , 27 , 25 , 163 , 83 , 709 , 141 ,0 }; - static ulong[] dim240Kuo3Init = { 1 , 3 , 7 , 15 , 31 , 45 , 119 , 141 , 181 , 231 , 411 ,0 }; - static ulong[] dim241Kuo3Init = { 1 , 1 , 5 , 9 , 31 , 25 , 113 , 243 , 435 , 55 , 765 ,0 }; - static ulong[] dim242Kuo3Init = { 1 , 1 , 7 , 9 , 27 , 5 , 63 , 23 , 133 , 767 , 1963 ,0 }; - static ulong[] dim243Kuo3Init = { 1 , 3 , 7 , 9 , 9 , 55 , 97 , 159 , 371 , 1013 , 2013 ,0 }; - static ulong[] dim244Kuo3Init = { 1 , 1 , 3 , 7 , 3 , 17 , 13 , 215 , 15 , 281 , 291 ,0 }; - static ulong[] dim245Kuo3Init = { 1 , 3 , 5 , 9 , 29 , 7 , 71 , 9 , 181 , 763 , 1111 ,0 }; - static ulong[] dim246Kuo3Init = { 1 , 3 , 7 , 13 , 23 , 55 , 79 , 99 , 165 , 447 , 1947 ,0 }; - static ulong[] dim247Kuo3Init = { 1 , 3 , 7 , 7 , 29 , 59 , 25 , 41 , 313 , 665 , 1245 ,0 }; - static ulong[] dim248Kuo3Init = { 1 , 1 , 3 , 3 , 5 , 29 , 71 , 71 , 475 , 781 , 567 ,0 }; - static ulong[] dim249Kuo3Init = { 1 , 1 , 1 , 3 , 19 , 53 , 61 , 215 , 475 , 885 , 459 ,0 }; - static ulong[] dim250Kuo3Init = { 1 , 3 , 3 , 13 , 5 , 31 , 95 , 137 , 119 , 249 , 975 ,0 }; - static ulong[] dim251Kuo3Init = { 1 , 1 , 1 , 15 , 21 , 51 , 71 , 21 , 193 , 709 , 1167 ,0 }; - static ulong[] dim252Kuo3Init = { 1 , 3 , 7 , 9 , 29 , 61 , 45 , 153 , 351 , 867 , 995 ,0 }; - static ulong[] dim253Kuo3Init = { 1 , 1 , 1 , 15 , 7 , 37 , 65 , 51 , 45 , 497 , 1825 ,0 }; - static ulong[] dim254Kuo3Init = { 1 , 3 , 3 , 1 , 23 , 59 , 11 , 127 , 501 , 351 , 1525 ,0 }; - static ulong[] dim255Kuo3Init = { 1 , 1 , 3 , 15 , 31 , 29 , 47 , 105 , 179 , 159 , 991 ,0 }; - static ulong[] dim256Kuo3Init = { 1 , 3 , 3 , 15 , 27 , 23 , 93 , 163 , 169 , 1003 , 1369 ,0 }; - static ulong[] dim257Kuo3Init = { 1 , 3 , 1 , 5 , 31 , 51 , 85 , 221 , 87 , 941 , 317 ,0 }; - static ulong[] dim258Kuo3Init = { 1 , 3 , 7 , 15 , 21 , 19 , 71 , 205 , 385 , 371 , 1401 ,0 }; - static ulong[] dim259Kuo3Init = { 1 , 1 , 5 , 11 , 1 , 51 , 31 , 185 , 407 , 233 , 1171 ,0 }; - static ulong[] dim260Kuo3Init = { 1 , 3 , 3 , 9 , 19 , 11 , 93 , 253 , 373 , 679 , 69 ,0 }; - static ulong[] dim261Kuo3Init = { 1 , 1 , 7 , 15 , 23 , 45 , 87 , 61 , 113 , 541 , 1701 ,0 }; - static ulong[] dim262Kuo3Init = { 1 , 1 , 5 , 7 , 7 , 61 , 55 , 167 , 345 , 633 , 1699 ,0 }; - static ulong[] dim263Kuo3Init = { 1 , 3 , 7 , 7 , 1 , 23 , 121 , 33 , 507 , 361 , 1945 ,0 }; - static ulong[] dim264Kuo3Init = { 1 , 3 , 7 , 1 , 19 , 47 , 43 , 101 , 67 , 57 , 1685 ,0 }; - static ulong[] dim265Kuo3Init = { 1 , 3 , 3 , 3 , 25 , 63 , 53 , 149 , 483 , 551 , 1519 ,0 }; - static ulong[] dim266Kuo3Init = { 1 , 3 , 1 , 3 , 27 , 1 , 41 , 213 , 57 , 897 , 121 ,0 }; - static ulong[] dim267Kuo3Init = { 1 , 3 , 1 , 5 , 19 , 13 , 49 , 81 , 239 , 455 , 957 ,0 }; - static ulong[] dim268Kuo3Init = { 1 , 1 , 3 , 7 , 15 , 23 , 89 , 171 , 319 , 117 , 2041 ,0 }; - static ulong[] dim269Kuo3Init = { 1 , 1 , 3 , 13 , 3 , 13 , 41 , 15 , 145 , 659 , 973 ,0 }; - static ulong[] dim270Kuo3Init = { 1 , 3 , 7 , 1 , 15 , 17 , 69 , 53 , 245 , 179 , 159 ,0 }; - static ulong[] dim271Kuo3Init = { 1 , 3 , 3 , 5 , 5 , 3 , 113 , 183 , 219 , 469 , 1169 ,0 }; - static ulong[] dim272Kuo3Init = { 1 , 1 , 5 , 15 , 13 , 45 , 89 , 87 , 371 , 267 , 1643 ,0 }; - static ulong[] dim273Kuo3Init = { 1 , 3 , 5 , 5 , 1 , 25 , 3 , 247 , 309 , 401 , 2027 ,0 }; - static ulong[] dim274Kuo3Init = { 1 , 3 , 1 , 11 , 13 , 7 , 79 , 17 , 297 , 679 , 1699 ,0 }; - static ulong[] dim275Kuo3Init = { 1 , 3 , 1 , 5 , 13 , 19 , 123 , 255 , 343 , 393 , 1635 ,0 }; - static ulong[] dim276Kuo3Init = { 1 , 3 , 3 , 15 , 13 , 13 , 37 , 229 , 483 , 283 , 1423 ,0 }; - static ulong[] dim277Kuo3Init = { 1 , 3 , 1 , 1 , 7 , 37 , 65 , 67 , 77 , 247 , 1539 ,0 }; - static ulong[] dim278Kuo3Init = { 1 , 1 , 3 , 5 , 25 , 39 , 37 , 19 , 231 , 835 , 797 ,0 }; - static ulong[] dim279Kuo3Init = { 1 , 1 , 1 , 11 , 27 , 53 , 1 , 217 , 211 , 7 , 801 ,0 }; - static ulong[] dim280Kuo3Init = { 1 , 3 , 7 , 1 , 15 , 55 , 69 , 77 , 491 , 61 , 55 ,0 }; - static ulong[] dim281Kuo3Init = { 1 , 1 , 1 , 1 , 29 , 21 , 47 , 167 , 281 , 105 , 1363 ,0 }; - static ulong[] dim282Kuo3Init = { 1 , 3 , 1 , 15 , 15 , 55 , 57 , 207 , 479 , 709 , 867 ,0 }; - static ulong[] dim283Kuo3Init = { 1 , 1 , 1 , 9 , 7 , 13 , 115 , 237 , 47 , 127 , 1849 ,0 }; - static ulong[] dim284Kuo3Init = { 1 , 1 , 7 , 9 , 7 , 35 , 83 , 63 , 155 , 441 , 1105 ,0 }; - static ulong[] dim285Kuo3Init = { 1 , 3 , 3 , 9 , 17 , 39 , 19 , 231 , 491 , 593 , 1997 ,0 }; - static ulong[] dim286Kuo3Init = { 1 , 3 , 3 , 13 , 17 , 19 , 65 , 21 , 389 , 391 , 483 ,0 }; - static ulong[] dim287Kuo3Init = { 1 , 1 , 5 , 7 , 17 , 7 , 97 , 173 , 413 , 917 , 1691 ,0 }; - static ulong[] dim288Kuo3Init = { 1 , 1 , 3 , 3 , 29 , 49 , 3 , 127 , 337 , 713 , 1057 ,0 }; - static ulong[] dim289Kuo3Init = { 1 , 3 , 7 , 5 , 31 , 23 , 31 , 119 , 161 , 51 , 537 ,0 }; - static ulong[] dim290Kuo3Init = { 1 , 1 , 5 , 1 , 29 , 25 , 15 , 187 , 143 , 927 , 715 ,0 }; - static ulong[] dim291Kuo3Init = { 1 , 1 , 7 , 11 , 15 , 47 , 55 , 103 , 109 , 465 , 1439 ,0 }; - static ulong[] dim292Kuo3Init = { 1 , 1 , 3 , 13 , 31 , 47 , 115 , 177 , 355 , 163 , 833 ,0 }; - static ulong[] dim293Kuo3Init = { 1 , 3 , 5 , 5 , 31 , 13 , 15 , 163 , 57 , 937 , 1553 ,0 }; - static ulong[] dim294Kuo3Init = { 1 , 3 , 5 , 15 , 7 , 29 , 47 , 139 , 231 , 507 , 595 ,0 }; - static ulong[] dim295Kuo3Init = { 1 , 3 , 1 , 15 , 31 , 13 , 49 , 253 , 29 , 109 , 727 ,0 }; - static ulong[] dim296Kuo3Init = { 1 , 1 , 5 , 15 , 21 , 1 , 107 , 89 , 367 , 825 , 1297 ,0 }; - static ulong[] dim297Kuo3Init = { 1 , 3 , 3 , 9 , 31 , 21 , 31 , 247 , 375 , 767 , 1761 ,0 }; - static ulong[] dim298Kuo3Init = { 1 , 1 , 7 , 3 , 31 , 33 , 119 , 119 , 409 , 955 , 1411 ,0 }; - static ulong[] dim299Kuo3Init = { 1 , 1 , 7 , 1 , 17 , 57 , 101 , 37 , 147 , 367 , 265 ,0 }; - static ulong[] dim300Kuo3Init = { 1 , 3 , 3 , 3 , 25 , 53 , 91 , 43 , 351 , 1021 , 1243 ,0 }; - static ulong[] dim301Kuo3Init = { 1 , 3 , 3 , 5 , 11 , 47 , 107 , 209 , 251 , 765 , 1089 ,0 }; - static ulong[] dim302Kuo3Init = { 1 , 1 , 7 , 5 , 9 , 13 , 23 , 153 , 367 , 585 , 315 ,0 }; - static ulong[] dim303Kuo3Init = { 1 , 3 , 3 , 15 , 23 , 57 , 83 , 173 , 413 , 555 , 159 ,0 }; - static ulong[] dim304Kuo3Init = { 1 , 3 , 7 , 15 , 7 , 59 , 31 , 233 , 67 , 767 , 75 ,0 }; - static ulong[] dim305Kuo3Init = { 1 , 3 , 5 , 3 , 17 , 1 , 35 , 37 , 445 , 847 , 1853 ,0 }; - static ulong[] dim306Kuo3Init = { 1 , 3 , 5 , 13 , 3 , 1 , 75 , 113 , 83 , 467 , 1057 ,0 }; - static ulong[] dim307Kuo3Init = { 1 , 1 , 7 , 1 , 7 , 15 , 125 , 31 , 341 , 133 , 285 ,0 }; - static ulong[] dim308Kuo3Init = { 1 , 1 , 5 , 5 , 15 , 11 , 97 , 3 , 59 , 777 , 1125 ,0 }; - static ulong[] dim309Kuo3Init = { 1 , 3 , 7 , 9 , 17 , 55 , 117 , 255 , 429 , 239 , 1071 ,0 }; - static ulong[] dim310Kuo3Init = { 1 , 1 , 7 , 3 , 27 , 37 , 31 , 221 , 385 , 877 , 1767 ,0 }; - static ulong[] dim311Kuo3Init = { 1 , 1 , 5 , 1 , 5 , 31 , 43 , 23 , 77 , 497 , 1605 ,0 }; - static ulong[] dim312Kuo3Init = { 1 , 3 , 5 , 15 , 15 , 37 , 103 , 227 , 33 , 185 , 481 ,0 }; - static ulong[] dim313Kuo3Init = { 1 , 3 , 3 , 11 , 29 , 61 , 67 , 53 , 257 , 609 , 1581 ,0 }; - static ulong[] dim314Kuo3Init = { 1 , 1 , 3 , 15 , 31 , 25 , 123 , 59 , 395 , 107 , 587 ,0 }; - static ulong[] dim315Kuo3Init = { 1 , 3 , 1 , 7 , 29 , 19 , 51 , 135 , 503 , 71 , 33 ,0 }; - static ulong[] dim316Kuo3Init = { 1 , 3 , 1 , 15 , 21 , 31 , 23 , 85 , 17 , 227 , 657 ,0 }; - static ulong[] dim317Kuo3Init = { 1 , 1 , 1 , 3 , 9 , 63 , 61 , 205 , 61 , 699 , 599 ,0 }; - static ulong[] dim318Kuo3Init = { 1 , 3 , 1 , 15 , 1 , 39 , 45 , 133 , 1 , 391 , 255 ,0 }; - static ulong[] dim319Kuo3Init = { 1 , 3 , 5 , 13 , 17 , 13 , 107 , 245 , 55 , 619 , 1085 ,0 }; - static ulong[] dim320Kuo3Init = { 1 , 3 , 3 , 9 , 5 , 25 , 5 , 49 , 509 , 661 , 1225 ,0 }; - static ulong[] dim321Kuo3Init = { 1 , 3 , 7 , 9 , 29 , 61 , 13 , 247 , 341 , 257 , 1551 ,0 }; - static ulong[] dim322Kuo3Init = { 1 , 3 , 7 , 9 , 5 , 39 , 123 , 221 , 391 , 501 , 527 ,0 }; - static ulong[] dim323Kuo3Init = { 1 , 3 , 1 , 7 , 21 , 23 , 65 , 233 , 181 , 405 , 1297 ,0 }; - static ulong[] dim324Kuo3Init = { 1 , 1 , 1 , 3 , 23 , 23 , 15 , 253 , 37 , 679 , 1455 ,0 }; - static ulong[] dim325Kuo3Init = { 1 , 3 , 3 , 3 , 3 , 31 , 89 , 105 , 11 , 1015 , 1837 ,0 }; - static ulong[] dim326Kuo3Init = { 1 , 3 , 1 , 7 , 15 , 59 , 105 , 179 , 477 , 923 , 1189 ,0 }; - static ulong[] dim327Kuo3Init = { 1 , 3 , 5 , 9 , 1 , 9 , 21 , 71 , 145 , 409 , 1235 ,0 }; - static ulong[] dim328Kuo3Init = { 1 , 1 , 7 , 13 , 9 , 43 , 85 , 241 , 497 , 683 , 1169 ,0 }; - static ulong[] dim329Kuo3Init = { 1 , 3 , 3 , 13 , 29 , 41 , 23 , 51 , 1 , 563 , 905 ,0 }; - static ulong[] dim330Kuo3Init = { 1 , 3 , 5 , 9 , 25 , 51 , 1 , 71 , 25 , 195 , 363 ,0 }; - static ulong[] dim331Kuo3Init = { 1 , 3 , 7 , 7 , 31 , 49 , 13 , 255 , 471 , 653 , 1127 ,0 }; - static ulong[] dim332Kuo3Init = { 1 , 3 , 3 , 7 , 7 , 61 , 63 , 21 , 413 , 817 , 1369 ,0 }; - static ulong[] dim333Kuo3Init = { 1 , 3 , 5 , 1 , 7 , 53 , 43 , 167 , 173 , 261 , 633 ,0 }; - static ulong[] dim334Kuo3Init = { 1 , 1 , 1 , 13 , 21 , 59 , 49 , 135 , 351 , 187 , 447 ,0 }; - static ulong[] dim335Kuo3Init = { 1 , 1 , 3 , 7 , 5 , 35 , 103 , 5 , 247 , 555 , 1439 ,0 }; - static ulong[] dim336Kuo3Init = { 1 , 1 , 3 , 1 , 3 , 11 , 5 , 153 , 507 , 21 , 1331 ,0 }; - static ulong[] dim337Kuo3Init = { 1 , 3 , 7 , 15 , 25 , 11 , 29 , 51 , 353 , 447 , 337 , 3621 ,0 }; - static ulong[] dim338Kuo3Init = { 1 , 3 , 5 , 13 , 31 , 51 , 103 , 69 , 311 , 645 , 1373 , 1155 ,0 }; - static ulong[] dim339Kuo3Init = { 1 , 1 , 7 , 7 , 1 , 55 , 101 , 203 , 503 , 711 , 131 , 937 ,0 }; - static ulong[] dim340Kuo3Init = { 1 , 3 , 3 , 11 , 7 , 5 , 75 , 63 , 217 , 643 , 871 , 3511 ,0 }; - static ulong[] dim341Kuo3Init = { 1 , 1 , 3 , 15 , 21 , 23 , 75 , 3 , 113 , 203 , 13 , 2727 ,0 }; - static ulong[] dim342Kuo3Init = { 1 , 3 , 5 , 11 , 7 , 1 , 27 , 39 , 411 , 195 , 607 , 1705 ,0 }; - static ulong[] dim343Kuo3Init = { 1 , 1 , 7 , 11 , 23 , 21 , 11 , 113 , 437 , 947 , 1897 , 1249 ,0 }; - static ulong[] dim344Kuo3Init = { 1 , 1 , 7 , 5 , 23 , 45 , 41 , 169 , 33 , 981 , 1331 , 2013 ,0 }; - static ulong[] dim345Kuo3Init = { 1 , 3 , 1 , 7 , 11 , 5 , 11 , 121 , 239 , 269 , 1759 , 829 ,0 }; - static ulong[] dim346Kuo3Init = { 1 , 1 , 1 , 9 , 31 , 51 , 77 , 61 , 19 , 121 , 969 , 3627 ,0 }; - static ulong[] dim347Kuo3Init = { 1 , 3 , 1 , 13 , 23 , 45 , 39 , 183 , 21 , 787 , 967 , 1911 ,0 }; - static ulong[] dim348Kuo3Init = { 1 , 1 , 1 , 15 , 21 , 19 , 91 , 231 , 325 , 531 , 473 , 2543 ,0 }; - static ulong[] dim349Kuo3Init = { 1 , 3 , 5 , 3 , 7 , 25 , 91 , 193 , 387 , 181 , 493 , 1225 ,0 }; - static ulong[] dim350Kuo3Init = { 1 , 1 , 7 , 7 , 23 , 21 , 55 , 221 , 283 , 995 , 793 , 485 ,0 }; - static ulong[] dim351Kuo3Init = { 1 , 1 , 1 , 15 , 29 , 61 , 1 , 33 , 59 , 725 , 1053 , 55 ,0 }; - static ulong[] dim352Kuo3Init = { 1 , 3 , 3 , 5 , 15 , 43 , 85 , 87 , 425 , 39 , 1559 , 1403 ,0 }; - static ulong[] dim353Kuo3Init = { 1 , 1 , 5 , 9 , 3 , 7 , 65 , 3 , 177 , 491 , 121 , 2755 ,0 }; - static ulong[] dim354Kuo3Init = { 1 , 1 , 3 , 3 , 15 , 37 , 67 , 145 , 295 , 421 , 1849 , 2151 ,0 }; - static ulong[] dim355Kuo3Init = { 1 , 1 , 3 , 15 , 17 , 41 , 109 , 125 , 509 , 407 , 1927 , 2401 ,0 }; - static ulong[] dim356Kuo3Init = { 1 , 1 , 7 , 5 , 9 , 39 , 69 , 1 , 259 , 821 , 1837 , 947 ,0 }; - static ulong[] dim357Kuo3Init = { 1 , 1 , 7 , 9 , 25 , 55 , 127 , 185 , 143 , 211 , 1615 , 1949 ,0 }; - static ulong[] dim358Kuo3Init = { 1 , 3 , 3 , 13 , 15 , 25 , 25 , 231 , 197 , 329 , 1319 , 853 ,0 }; - static ulong[] dim359Kuo3Init = { 1 , 3 , 7 , 11 , 29 , 1 , 23 , 131 , 473 , 497 , 1147 , 3779 ,0 }; - static ulong[] dim360Kuo3Init = { 1 , 3 , 1 , 15 , 21 , 23 , 67 , 243 , 191 , 353 , 1091 , 2121 ,0 }; - static ulong[] dim361Kuo3Init = { 1 , 1 , 7 , 11 , 27 , 15 , 41 , 183 , 235 , 219 , 303 , 795 ,0 }; - static ulong[] dim362Kuo3Init = { 1 , 3 , 7 , 15 , 3 , 21 , 19 , 187 , 365 , 453 , 1069 , 1983 ,0 }; - static ulong[] dim363Kuo3Init = { 1 , 1 , 7 , 1 , 27 , 11 , 95 , 117 , 433 , 453 , 1839 , 3863 ,0 }; - static ulong[] dim364Kuo3Init = { 1 , 3 , 3 , 5 , 29 , 63 , 17 , 243 , 247 , 609 , 1999 , 785 ,0 }; - static ulong[] dim365Kuo3Init = { 1 , 1 , 1 , 7 , 21 , 17 , 57 , 99 , 227 , 217 , 585 , 397 ,0 }; - static ulong[] dim366Kuo3Init = { 1 , 1 , 1 , 13 , 13 , 41 , 75 , 153 , 355 , 175 , 313 , 2237 ,0 }; - static ulong[] dim367Kuo3Init = { 1 , 3 , 7 , 9 , 27 , 63 , 1 , 33 , 383 , 507 , 1315 , 1691 ,0 }; - static ulong[] dim368Kuo3Init = { 1 , 1 , 3 , 3 , 17 , 33 , 65 , 235 , 395 , 317 , 1769 , 2937 ,0 }; - static ulong[] dim369Kuo3Init = { 1 , 3 , 1 , 5 , 31 , 19 , 25 , 15 , 373 , 823 , 2003 , 1309 ,0 }; - static ulong[] dim370Kuo3Init = { 1 , 3 , 3 , 5 , 3 , 33 , 43 , 225 , 445 , 181 , 325 , 797 ,0 }; - static ulong[] dim371Kuo3Init = { 1 , 1 , 3 , 1 , 11 , 19 , 49 , 129 , 73 , 983 , 621 , 2381 ,0 }; - static ulong[] dim372Kuo3Init = { 1 , 3 , 3 , 15 , 1 , 33 , 109 , 33 , 363 , 925 , 589 , 3955 ,0 }; - static ulong[] dim373Kuo3Init = { 1 , 1 , 3 , 3 , 11 , 21 , 23 , 99 , 159 , 949 , 977 , 3103 ,0 }; - static ulong[] dim374Kuo3Init = { 1 , 1 , 5 , 3 , 3 , 15 , 41 , 45 , 325 , 703 , 907 , 2467 ,0 }; - static ulong[] dim375Kuo3Init = { 1 , 1 , 7 , 15 , 31 , 11 , 71 , 225 , 199 , 521 , 933 , 2777 ,0 }; - static ulong[] dim376Kuo3Init = { 1 , 3 , 5 , 9 , 13 , 55 , 23 , 199 , 293 , 297 , 2031 , 3815 ,0 }; - static ulong[] dim377Kuo3Init = { 1 , 1 , 3 , 13 , 25 , 5 , 25 , 229 , 301 , 301 , 1165 , 2229 ,0 }; - static ulong[] dim378Kuo3Init = { 1 , 1 , 1 , 11 , 1 , 39 , 25 , 211 , 233 , 233 , 355 , 3131 ,0 }; - static ulong[] dim379Kuo3Init = { 1 , 3 , 3 , 9 , 31 , 37 , 113 , 17 , 163 , 547 , 877 , 333 ,0 }; - static ulong[] dim380Kuo3Init = { 1 , 1 , 7 , 1 , 31 , 7 , 117 , 175 , 191 , 191 , 1185 , 2637 ,0 }; - static ulong[] dim381Kuo3Init = { 1 , 1 , 3 , 11 , 27 , 59 , 33 , 79 , 293 , 657 , 1899 , 1547 ,0 }; - static ulong[] dim382Kuo3Init = { 1 , 3 , 1 , 7 , 29 , 43 , 89 , 227 , 315 , 971 , 1175 , 693 ,0 }; - static ulong[] dim383Kuo3Init = { 1 , 1 , 1 , 5 , 9 , 43 , 17 , 37 , 321 , 907 , 441 , 21 ,0 }; - static ulong[] dim384Kuo3Init = { 1 , 3 , 1 , 15 , 25 , 47 , 21 , 11 , 385 , 353 , 1103 , 3445 ,0 }; - static ulong[] dim385Kuo3Init = { 1 , 1 , 7 , 9 , 21 , 63 , 9 , 147 , 79 , 627 , 471 , 1683 ,0 }; - static ulong[] dim386Kuo3Init = { 1 , 3 , 7 , 7 , 1 , 13 , 29 , 127 , 3 , 629 , 1213 , 2981 ,0 }; - static ulong[] dim387Kuo3Init = { 1 , 1 , 5 , 9 , 7 , 41 , 41 , 235 , 131 , 379 , 23 , 1251 ,0 }; - static ulong[] dim388Kuo3Init = { 1 , 3 , 5 , 3 , 17 , 31 , 101 , 193 , 271 , 189 , 1923 , 1849 ,0 }; - static ulong[] dim389Kuo3Init = { 1 , 1 , 1 , 5 , 21 , 43 , 35 , 209 , 359 , 185 , 1921 , 2773 ,0 }; - static ulong[] dim390Kuo3Init = { 1 , 1 , 7 , 5 , 31 , 5 , 41 , 127 , 415 , 151 , 1027 , 2171 ,0 }; - static ulong[] dim391Kuo3Init = { 1 , 1 , 1 , 3 , 31 , 53 , 127 , 37 , 273 , 415 , 1657 , 467 ,0 }; - static ulong[] dim392Kuo3Init = { 1 , 3 , 7 , 3 , 29 , 43 , 77 , 35 , 347 , 37 , 1265 , 1211 ,0 }; - static ulong[] dim393Kuo3Init = { 1 , 1 , 1 , 1 , 3 , 31 , 89 , 57 , 405 , 491 , 1685 , 2727 ,0 }; - static ulong[] dim394Kuo3Init = { 1 , 3 , 5 , 15 , 29 , 9 , 23 , 79 , 253 , 161 , 273 , 4001 ,0 }; - static ulong[] dim395Kuo3Init = { 1 , 3 , 3 , 13 , 29 , 49 , 73 , 145 , 203 , 215 , 423 , 3293 ,0 }; - static ulong[] dim396Kuo3Init = { 1 , 1 , 5 , 15 , 29 , 43 , 49 , 99 , 335 , 1017 , 315 , 2761 ,0 }; - static ulong[] dim397Kuo3Init = { 1 , 3 , 1 , 9 , 15 , 39 , 87 , 243 , 331 , 1015 , 1771 , 1303 ,0 }; - static ulong[] dim398Kuo3Init = { 1 , 1 , 1 , 5 , 5 , 1 , 15 , 19 , 277 , 699 , 1957 , 373 ,0 }; - static ulong[] dim399Kuo3Init = { 1 , 1 , 7 , 1 , 7 , 13 , 41 , 211 , 167 , 705 , 1011 , 2097 ,0 }; - static ulong[] dim400Kuo3Init = { 1 , 1 , 7 , 9 , 3 , 25 , 127 , 75 , 271 , 817 , 629 , 2027 ,0 }; - static ulong[] dim401Kuo3Init = { 1 , 3 , 1 , 5 , 31 , 49 , 17 , 113 , 71 , 233 , 443 , 3005 ,0 }; - static ulong[] dim402Kuo3Init = { 1 , 1 , 1 , 1 , 1 , 23 , 87 , 29 , 121 , 485 , 227 , 2981 ,0 }; - static ulong[] dim403Kuo3Init = { 1 , 1 , 1 , 1 , 19 , 3 , 127 , 31 , 57 , 567 , 375 , 1121 ,0 }; - static ulong[] dim404Kuo3Init = { 1 , 1 , 1 , 9 , 15 , 49 , 67 , 49 , 473 , 957 , 1955 , 29 ,0 }; - static ulong[] dim405Kuo3Init = { 1 , 1 , 1 , 1 , 15 , 49 , 71 , 241 , 43 , 611 , 953 , 4013 ,0 }; - static ulong[] dim406Kuo3Init = { 1 , 3 , 3 , 3 , 13 , 57 , 45 , 65 , 5 , 101 , 511 , 3317 ,0 }; - static ulong[] dim407Kuo3Init = { 1 , 3 , 3 , 7 , 25 , 9 , 97 , 35 , 495 , 791 , 223 , 1555 ,0 }; - static ulong[] dim408Kuo3Init = { 1 , 1 , 3 , 1 , 25 , 37 , 73 , 61 , 31 , 525 , 855 , 695 ,0 }; - static ulong[] dim409Kuo3Init = { 1 , 3 , 5 , 11 , 15 , 45 , 11 , 53 , 393 , 557 , 349 , 2507 ,0 }; - static ulong[] dim410Kuo3Init = { 1 , 1 , 5 , 11 , 1 , 43 , 77 , 215 , 149 , 81 , 1663 , 987 ,0 }; - static ulong[] dim411Kuo3Init = { 1 , 3 , 5 , 5 , 13 , 55 , 45 , 79 , 305 , 65 , 1721 , 605 ,0 }; - static ulong[] dim412Kuo3Init = { 1 , 1 , 1 , 3 , 15 , 19 , 103 , 249 , 253 , 935 , 1933 , 3809 ,0 }; - static ulong[] dim413Kuo3Init = { 1 , 1 , 1 , 11 , 1 , 43 , 119 , 233 , 79 , 539 , 1397 , 1669 ,0 }; - static ulong[] dim414Kuo3Init = { 1 , 1 , 7 , 15 , 9 , 27 , 29 , 125 , 335 , 573 , 1721 , 551 ,0 }; - static ulong[] dim415Kuo3Init = { 1 , 1 , 5 , 11 , 29 , 33 , 121 , 47 , 351 , 857 , 1155 , 2939 ,0 }; - static ulong[] dim416Kuo3Init = { 1 , 1 , 1 , 13 , 21 , 13 , 107 , 179 , 135 , 597 , 39 , 2129 ,0 }; - static ulong[] dim417Kuo3Init = { 1 , 3 , 5 , 15 , 11 , 5 , 101 , 227 , 457 , 773 , 1369 , 2229 ,0 }; - static ulong[] dim418Kuo3Init = { 1 , 1 , 7 , 3 , 9 , 47 , 53 , 47 , 315 , 221 , 369 , 2991 ,0 }; - static ulong[] dim419Kuo3Init = { 1 , 3 , 7 , 9 , 7 , 1 , 117 , 229 , 193 , 105 , 1591 , 875 ,0 }; - static ulong[] dim420Kuo3Init = { 1 , 3 , 1 , 13 , 5 , 49 , 47 , 95 , 431 , 37 , 2037 , 3793 ,0 }; - static ulong[] dim421Kuo3Init = { 1 , 1 , 3 , 11 , 17 , 39 , 91 , 225 , 109 , 375 , 1431 , 3689 ,0 }; - static ulong[] dim422Kuo3Init = { 1 , 3 , 5 , 7 , 27 , 39 , 23 , 215 , 55 , 573 , 965 , 321 ,0 }; - static ulong[] dim423Kuo3Init = { 1 , 1 , 3 , 13 , 1 , 51 , 23 , 181 , 399 , 471 , 429 , 2409 ,0 }; - static ulong[] dim424Kuo3Init = { 1 , 1 , 7 , 9 , 17 , 21 , 43 , 177 , 327 , 789 , 1581 , 3505 ,0 }; - static ulong[] dim425Kuo3Init = { 1 , 1 , 7 , 7 , 9 , 39 , 59 , 187 , 203 , 655 , 545 , 2107 ,0 }; - static ulong[] dim426Kuo3Init = { 1 , 1 , 7 , 3 , 15 , 13 , 83 , 189 , 213 , 575 , 255 , 1475 ,0 }; - static ulong[] dim427Kuo3Init = { 1 , 1 , 1 , 3 , 23 , 27 , 101 , 67 , 299 , 1003 , 1351 , 1799 ,0 }; - static ulong[] dim428Kuo3Init = { 1 , 3 , 3 , 9 , 13 , 29 , 83 , 251 , 151 , 607 , 2047 , 447 ,0 }; - static ulong[] dim429Kuo3Init = { 1 , 3 , 1 , 5 , 5 , 7 , 23 , 145 , 241 , 437 , 1215 , 489 ,0 }; - static ulong[] dim430Kuo3Init = { 1 , 3 , 1 , 11 , 3 , 63 , 55 , 53 , 187 , 179 , 1137 , 3923 ,0 }; - static ulong[] dim431Kuo3Init = { 1 , 3 , 7 , 11 , 31 , 29 , 127 , 37 , 509 , 835 , 1693 , 965 ,0 }; - static ulong[] dim432Kuo3Init = { 1 , 1 , 1 , 9 , 29 , 1 , 11 , 61 , 459 , 415 , 317 , 2981 ,0 }; - static ulong[] dim433Kuo3Init = { 1 , 3 , 7 , 3 , 1 , 61 , 31 , 77 , 55 , 301 , 1333 , 2803 ,0 }; - static ulong[] dim434Kuo3Init = { 1 , 1 , 7 , 13 , 3 , 1 , 117 , 185 , 385 , 771 , 409 , 3667 ,0 }; - static ulong[] dim435Kuo3Init = { 1 , 1 , 5 , 13 , 19 , 3 , 43 , 53 , 41 , 111 , 1617 , 95 ,0 }; - static ulong[] dim436Kuo3Init = { 1 , 3 , 7 , 13 , 25 , 25 , 125 , 91 , 85 , 99 , 461 , 3999 ,0 }; - static ulong[] dim437Kuo3Init = { 1 , 3 , 5 , 7 , 7 , 29 , 15 , 155 , 237 , 443 , 1187 , 623 ,0 }; - static ulong[] dim438Kuo3Init = { 1 , 3 , 3 , 1 , 11 , 3 , 35 , 169 , 449 , 917 , 141 , 1525 ,0 }; - static ulong[] dim439Kuo3Init = { 1 , 1 , 5 , 7 , 17 , 11 , 85 , 31 , 165 , 35 , 1069 , 3395 ,0 }; - static ulong[] dim440Kuo3Init = { 1 , 3 , 7 , 15 , 11 , 21 , 89 , 61 , 459 , 211 , 959 , 2411 ,0 }; - static ulong[] dim441Kuo3Init = { 1 , 1 , 5 , 11 , 25 , 35 , 1 , 137 , 491 , 955 , 1287 , 3955 ,0 }; - static ulong[] dim442Kuo3Init = { 1 , 3 , 3 , 11 , 13 , 47 , 105 , 69 , 119 , 455 , 769 , 1665 ,0 }; - static ulong[] dim443Kuo3Init = { 1 , 3 , 3 , 13 , 17 , 9 , 27 , 25 , 445 , 611 , 855 , 1273 ,0 }; - static ulong[] dim444Kuo3Init = { 1 , 1 , 3 , 9 , 3 , 5 , 107 , 89 , 443 , 991 , 727 , 871 ,0 }; - static ulong[] dim445Kuo3Init = { 1 , 1 , 5 , 3 , 19 , 43 , 93 , 163 , 193 , 395 , 99 , 1717 ,0 }; - static ulong[] dim446Kuo3Init = { 1 , 1 , 1 , 7 , 23 , 43 , 121 , 205 , 249 , 255 , 1763 , 1867 ,0 }; - static ulong[] dim447Kuo3Init = { 1 , 1 , 3 , 3 , 1 , 45 , 33 , 191 , 475 , 503 , 761 , 1845 ,0 }; - static ulong[] dim448Kuo3Init = { 1 , 1 , 3 , 3 , 31 , 39 , 11 , 203 , 9 , 183 , 407 , 3787 ,0 }; - static ulong[] dim449Kuo3Init = { 1 , 1 , 5 , 11 , 11 , 3 , 65 , 175 , 131 , 757 , 1717 , 1003 ,0 }; - static ulong[] dim450Kuo3Init = { 1 , 1 , 1 , 15 , 13 , 61 , 29 , 123 , 269 , 531 , 257 , 1399 ,0 }; - static ulong[] dim451Kuo3Init = { 1 , 3 , 5 , 5 , 13 , 23 , 23 , 1 , 293 , 921 , 79 , 479 ,0 }; - static ulong[] dim452Kuo3Init = { 1 , 1 , 3 , 13 , 9 , 55 , 21 , 15 , 47 , 685 , 829 , 2679 ,0 }; - static ulong[] dim453Kuo3Init = { 1 , 3 , 5 , 11 , 1 , 39 , 97 , 59 , 37 , 787 , 991 , 263 ,0 }; - static ulong[] dim454Kuo3Init = { 1 , 3 , 5 , 15 , 31 , 3 , 45 , 159 , 219 , 161 , 1025 , 665 ,0 }; - static ulong[] dim455Kuo3Init = { 1 , 3 , 7 , 15 , 11 , 51 , 51 , 19 , 181 , 125 , 1677 , 2125 ,0 }; - static ulong[] dim456Kuo3Init = { 1 , 1 , 3 , 5 , 27 , 23 , 79 , 161 , 97 , 581 , 405 , 2239 ,0 }; - static ulong[] dim457Kuo3Init = { 1 , 3 , 1 , 11 , 17 , 1 , 97 , 33 , 31 , 771 , 707 , 1053 ,0 }; - static ulong[] dim458Kuo3Init = { 1 , 1 , 1 , 11 , 11 , 51 , 113 , 47 , 51 , 827 , 385 , 3211 ,0 }; - static ulong[] dim459Kuo3Init = { 1 , 3 , 3 , 7 , 17 , 3 , 99 , 57 , 59 , 199 , 1359 , 2459 ,0 }; - static ulong[] dim460Kuo3Init = { 1 , 1 , 5 , 11 , 1 , 7 , 19 , 37 , 53 , 435 , 1095 , 495 ,0 }; - static ulong[] dim461Kuo3Init = { 1 , 1 , 5 , 13 , 19 , 5 , 95 , 109 , 245 , 737 , 1163 , 33 ,0 }; - static ulong[] dim462Kuo3Init = { 1 , 3 , 5 , 3 , 1 , 17 , 79 , 195 , 153 , 857 , 603 , 2905 ,0 }; - static ulong[] dim463Kuo3Init = { 1 , 3 , 5 , 5 , 31 , 51 , 71 , 103 , 121 , 5 , 931 , 217 ,0 }; - static ulong[] dim464Kuo3Init = { 1 , 1 , 5 , 7 , 31 , 39 , 11 , 9 , 223 , 365 , 1317 , 449 ,0 }; - static ulong[] dim465Kuo3Init = { 1 , 3 , 5 , 3 , 17 , 19 , 85 , 121 , 161 , 75 , 527 , 3941 ,0 }; - static ulong[] dim466Kuo3Init = { 1 , 3 , 5 , 9 , 17 , 53 , 41 , 255 , 207 , 251 , 925 , 2395 ,0 }; - static ulong[] dim467Kuo3Init = { 1 , 3 , 3 , 3 , 13 , 5 , 109 , 125 , 293 , 165 , 1715 , 1017 ,0 }; - static ulong[] dim468Kuo3Init = { 1 , 3 , 7 , 1 , 23 , 27 , 45 , 141 , 267 , 187 , 611 , 59 ,0 }; - static ulong[] dim469Kuo3Init = { 1 , 3 , 1 , 9 , 11 , 9 , 81 , 239 , 469 , 905 , 525 , 1549 ,0 }; - static ulong[] dim470Kuo3Init = { 1 , 1 , 1 , 15 , 13 , 21 , 71 , 87 , 199 , 389 , 139 , 3499 ,0 }; - static ulong[] dim471Kuo3Init = { 1 , 3 , 7 , 5 , 21 , 41 , 107 , 195 , 369 , 391 , 271 , 3351 ,0 }; - static ulong[] dim472Kuo3Init = { 1 , 3 , 3 , 1 , 17 , 19 , 75 , 219 , 415 , 241 , 1441 , 967 ,0 }; - static ulong[] dim473Kuo3Init = { 1 , 1 , 1 , 15 , 7 , 7 , 79 , 213 , 391 , 831 , 1649 , 3741 ,0 }; - static ulong[] dim474Kuo3Init = { 1 , 3 , 5 , 3 , 29 , 57 , 99 , 207 , 243 , 915 , 1969 , 2499 ,0 }; - static ulong[] dim475Kuo3Init = { 1 , 1 , 3 , 13 , 1 , 3 , 27 , 211 , 271 , 657 , 1251 , 3333 ,0 }; - static ulong[] dim476Kuo3Init = { 1 , 3 , 3 , 1 , 3 , 31 , 49 , 53 , 273 , 837 , 1771 , 1405 ,0 }; - static ulong[] dim477Kuo3Init = { 1 , 3 , 7 , 7 , 1 , 33 , 125 , 221 , 179 , 601 , 565 , 2709 ,0 }; - static ulong[] dim478Kuo3Init = { 1 , 1 , 1 , 7 , 31 , 19 , 81 , 173 , 413 , 849 , 579 , 2487 ,0 }; - static ulong[] dim479Kuo3Init = { 1 , 1 , 7 , 11 , 17 , 23 , 97 , 145 , 383 , 1015 , 547 , 483 ,0 }; - static ulong[] dim480Kuo3Init = { 1 , 3 , 1 , 3 , 11 , 63 , 41 , 175 , 43 , 283 , 1441 , 2695 ,0 }; - static ulong[] dim481Kuo3Init = { 1 , 1 , 7 , 9 , 5 , 23 , 61 , 161 , 149 , 49 , 1851 , 1281 , 4615 ,0 }; - static ulong[] dim482Kuo3Init = { 1 , 1 , 5 , 7 , 23 , 47 , 111 , 213 , 317 , 107 , 849 , 1563 , 6863 ,0 }; - static ulong[] dim483Kuo3Init = { 1 , 1 , 7 , 9 , 31 , 53 , 115 , 233 , 497 , 23 , 1395 , 327 , 551 ,0 }; - static ulong[] dim484Kuo3Init = { 1 , 1 , 7 , 13 , 21 , 51 , 17 , 109 , 29 , 1003 , 1221 , 2175 , 4645 ,0 }; - static ulong[] dim485Kuo3Init = { 1 , 3 , 3 , 15 , 7 , 57 , 103 , 131 , 63 , 217 , 607 , 2311 , 1237 ,0 }; - static ulong[] dim486Kuo3Init = { 1 , 3 , 5 , 3 , 19 , 27 , 107 , 223 , 15 , 149 , 1777 , 2211 , 2241 ,0 }; - static ulong[] dim487Kuo3Init = { 1 , 1 , 1 , 1 , 5 , 37 , 87 , 59 , 435 , 37 , 1771 , 1675 , 6241 ,0 }; - static ulong[] dim488Kuo3Init = { 1 , 3 , 1 , 7 , 29 , 51 , 83 , 41 , 11 , 545 , 995 , 1625 , 4883 ,0 }; - static ulong[] dim489Kuo3Init = { 1 , 1 , 1 , 5 , 15 , 43 , 57 , 111 , 55 , 921 , 567 , 1767 , 1849 ,0 }; - static ulong[] dim490Kuo3Init = { 1 , 1 , 5 , 15 , 5 , 49 , 3 , 23 , 307 , 691 , 1727 , 2297 , 6705 ,0 }; - static ulong[] dim491Kuo3Init = { 1 , 3 , 7 , 5 , 31 , 1 , 111 , 53 , 499 , 1017 , 1889 , 1955 , 1327 ,0 }; - static ulong[] dim492Kuo3Init = { 1 , 3 , 7 , 11 , 17 , 35 , 71 , 223 , 149 , 743 , 319 , 3157 , 5961 ,0 }; - static ulong[] dim493Kuo3Init = { 1 , 1 , 1 , 3 , 21 , 31 , 27 , 79 , 353 , 753 , 341 , 2121 , 5455 ,0 }; - static ulong[] dim494Kuo3Init = { 1 , 1 , 5 , 3 , 21 , 29 , 27 , 91 , 111 , 359 , 27 , 2383 , 7149 ,0 }; - static ulong[] dim495Kuo3Init = { 1 , 3 , 7 , 9 , 5 , 51 , 115 , 65 , 275 , 211 , 1519 , 2247 , 2065 ,0 }; - static ulong[] dim496Kuo3Init = { 1 , 1 , 1 , 15 , 27 , 7 , 21 , 173 , 79 , 357 , 693 , 873 , 879 ,0 }; - static ulong[] dim497Kuo3Init = { 1 , 3 , 1 , 7 , 25 , 47 , 53 , 123 , 491 , 707 , 1723 , 1139 , 3757 ,0 }; - static ulong[] dim498Kuo3Init = { 1 , 1 , 7 , 5 , 15 , 55 , 103 , 17 , 17 , 345 , 1477 , 3423 , 7527 ,0 }; - static ulong[] dim499Kuo3Init = { 1 , 3 , 1 , 13 , 1 , 3 , 55 , 85 , 251 , 389 , 631 , 117 , 4879 ,0 }; - static ulong[] dim500Kuo3Init = { 1 , 1 , 7 , 1 , 29 , 33 , 17 , 3 , 303 , 299 , 465 , 1709 , 1111 ,0 }; - static ulong[] dim501Kuo3Init = { 1 , 1 , 7 , 5 , 3 , 29 , 111 , 249 , 383 , 611 , 859 , 1555 , 7387 ,0 }; - static ulong[] dim502Kuo3Init = { 1 , 3 , 5 , 5 , 29 , 41 , 33 , 63 , 395 , 53 , 351 , 247 , 5317 ,0 }; - static ulong[] dim503Kuo3Init = { 1 , 1 , 5 , 7 , 11 , 63 , 121 , 131 , 249 , 451 , 619 , 2395 , 4575 ,0 }; - static ulong[] dim504Kuo3Init = { 1 , 3 , 7 , 3 , 3 , 43 , 37 , 211 , 385 , 289 , 791 , 735 , 4683 ,0 }; - static ulong[] dim505Kuo3Init = { 1 , 1 , 3 , 11 , 7 , 13 , 53 , 7 , 497 , 771 , 903 , 119 , 6601 ,0 }; - static ulong[] dim506Kuo3Init = { 1 , 3 , 7 , 1 , 3 , 61 , 117 , 237 , 427 , 335 , 1749 , 3105 , 6493 ,0 }; - static ulong[] dim507Kuo3Init = { 1 , 3 , 5 , 7 , 11 , 55 , 121 , 93 , 3 , 953 , 433 , 2663 , 1633 ,0 }; - static ulong[] dim508Kuo3Init = { 1 , 1 , 7 , 1 , 7 , 51 , 43 , 31 , 31 , 819 , 791 , 1071 , 569 ,0 }; - static ulong[] dim509Kuo3Init = { 1 , 3 , 5 , 11 , 17 , 37 , 71 , 97 , 69 , 681 , 1133 , 2425 , 3217 ,0 }; - static ulong[] dim510Kuo3Init = { 1 , 1 , 1 , 15 , 9 , 15 , 31 , 131 , 113 , 567 , 593 , 1781 , 6715 ,0 }; - static ulong[] dim511Kuo3Init = { 1 , 1 , 7 , 9 , 29 , 25 , 39 , 159 , 495 , 507 , 1253 , 409 , 6723 ,0 }; - static ulong[] dim512Kuo3Init = { 1 , 1 , 1 , 5 , 13 , 29 , 25 , 197 , 489 , 853 , 87 , 3173 , 6389 ,0 }; - static ulong[] dim513Kuo3Init = { 1 , 1 , 7 , 11 , 11 , 7 , 27 , 227 , 347 , 777 , 893 , 1007 , 1953 ,0 }; - static ulong[] dim514Kuo3Init = { 1 , 1 , 3 , 7 , 31 , 9 , 61 , 39 , 251 , 1 , 1297 , 2861 , 2593 ,0 }; - static ulong[] dim515Kuo3Init = { 1 , 1 , 5 , 1 , 15 , 45 , 3 , 147 , 143 , 279 , 2045 , 649 , 5579 ,0 }; - static ulong[] dim516Kuo3Init = { 1 , 1 , 5 , 5 , 9 , 51 , 3 , 249 , 253 , 533 , 1305 , 1749 , 1287 ,0 }; - static ulong[] dim517Kuo3Init = { 1 , 3 , 7 , 9 , 13 , 15 , 85 , 165 , 183 , 943 , 41 , 4061 , 5845 ,0 }; - static ulong[] dim518Kuo3Init = { 1 , 3 , 3 , 1 , 23 , 31 , 49 , 247 , 287 , 83 , 1833 , 1249 , 2789 ,0 }; - static ulong[] dim519Kuo3Init = { 1 , 3 , 3 , 7 , 7 , 53 , 125 , 211 , 145 , 837 , 515 , 1971 , 6201 ,0 }; - static ulong[] dim520Kuo3Init = { 1 , 3 , 3 , 11 , 13 , 11 , 87 , 11 , 33 , 355 , 1049 , 3053 , 4801 ,0 }; - static ulong[] dim521Kuo3Init = { 1 , 3 , 5 , 13 , 23 , 25 , 63 , 221 , 385 , 217 , 687 , 455 , 4083 ,0 }; - static ulong[] dim522Kuo3Init = { 1 , 1 , 5 , 1 , 3 , 21 , 119 , 79 , 207 , 693 , 925 , 1519 , 3981 ,0 }; - static ulong[] dim523Kuo3Init = { 1 , 1 , 3 , 11 , 21 , 35 , 21 , 21 , 297 , 461 , 793 , 1679 , 1285 ,0 }; - static ulong[] dim524Kuo3Init = { 1 , 3 , 5 , 13 , 31 , 23 , 11 , 129 , 189 , 933 , 283 , 3435 , 4593 ,0 }; - static ulong[] dim525Kuo3Init = { 1 , 3 , 1 , 1 , 13 , 11 , 113 , 35 , 199 , 149 , 181 , 3183 , 6205 ,0 }; - static ulong[] dim526Kuo3Init = { 1 , 3 , 1 , 9 , 7 , 59 , 105 , 161 , 63 , 821 , 13 , 2561 , 755 ,0 }; - static ulong[] dim527Kuo3Init = { 1 , 1 , 1 , 7 , 27 , 3 , 87 , 243 , 279 , 13 , 1341 , 2383 , 6005 ,0 }; - static ulong[] dim528Kuo3Init = { 1 , 3 , 3 , 13 , 27 , 25 , 91 , 205 , 275 , 663 , 1875 , 2399 , 4179 ,0 }; - static ulong[] dim529Kuo3Init = { 1 , 1 , 7 , 15 , 27 , 25 , 51 , 235 , 391 , 951 , 759 , 285 , 3443 ,0 }; - static ulong[] dim530Kuo3Init = { 1 , 3 , 3 , 5 , 1 , 33 , 57 , 107 , 137 , 851 , 1937 , 1003 , 2427 ,0 }; - static ulong[] dim531Kuo3Init = { 1 , 1 , 5 , 11 , 27 , 3 , 27 , 81 , 303 , 151 , 433 , 1893 , 587 ,0 }; - static ulong[] dim532Kuo3Init = { 1 , 1 , 1 , 9 , 25 , 45 , 113 , 173 , 471 , 191 , 1031 , 2119 , 4853 ,0 }; - static ulong[] dim533Kuo3Init = { 1 , 1 , 7 , 11 , 27 , 23 , 107 , 229 , 485 , 197 , 1925 , 1809 , 7775 ,0 }; - static ulong[] dim534Kuo3Init = { 1 , 1 , 1 , 3 , 31 , 61 , 91 , 47 , 3 , 643 , 1487 , 2563 , 3893 ,0 }; - static ulong[] dim535Kuo3Init = { 1 , 1 , 7 , 15 , 19 , 27 , 97 , 109 , 283 , 67 , 335 , 3707 , 1909 ,0 }; - static ulong[] dim536Kuo3Init = { 1 , 1 , 1 , 11 , 23 , 59 , 101 , 249 , 121 , 919 , 1385 , 2119 , 7389 ,0 }; - static ulong[] dim537Kuo3Init = { 1 , 1 , 7 , 11 , 7 , 29 , 33 , 111 , 243 , 617 , 125 , 3887 , 727 ,0 }; - static ulong[] dim538Kuo3Init = { 1 , 1 , 3 , 1 , 7 , 41 , 91 , 177 , 315 , 555 , 1653 , 1725 , 8069 ,0 }; - static ulong[] dim539Kuo3Init = { 1 , 1 , 5 , 15 , 3 , 63 , 53 , 31 , 177 , 451 , 141 , 3727 , 1695 ,0 }; - static ulong[] dim540Kuo3Init = { 1 , 1 , 3 , 15 , 25 , 37 , 17 , 229 , 75 , 705 , 327 , 1367 , 807 ,0 }; - static ulong[] dim541Kuo3Init = { 1 , 3 , 5 , 5 , 27 , 1 , 35 , 97 , 171 , 167 , 1077 , 25 , 5497 ,0 }; - static ulong[] dim542Kuo3Init = { 1 , 1 , 7 , 7 , 11 , 17 , 105 , 41 , 53 , 389 , 941 , 3273 , 967 ,0 }; - static ulong[] dim543Kuo3Init = { 1 , 3 , 3 , 15 , 11 , 61 , 125 , 155 , 361 , 229 , 1981 , 1647 , 5077 ,0 }; - static ulong[] dim544Kuo3Init = { 1 , 3 , 1 , 15 , 5 , 11 , 35 , 203 , 425 , 509 , 993 , 1861 , 1977 ,0 }; - static ulong[] dim545Kuo3Init = { 1 , 3 , 5 , 15 , 25 , 7 , 55 , 89 , 101 , 939 , 7 , 3535 , 7543 ,0 }; - static ulong[] dim546Kuo3Init = { 1 , 1 , 3 , 1 , 19 , 45 , 117 , 249 , 261 , 529 , 1299 , 597 , 7207 ,0 }; - static ulong[] dim547Kuo3Init = { 1 , 3 , 5 , 13 , 17 , 47 , 73 , 231 , 353 , 941 , 325 , 115 , 4005 ,0 }; - static ulong[] dim548Kuo3Init = { 1 , 3 , 1 , 9 , 5 , 29 , 11 , 161 , 461 , 793 , 813 , 3755 , 7017 ,0 }; - static ulong[] dim549Kuo3Init = { 1 , 3 , 3 , 15 , 23 , 21 , 83 , 47 , 143 , 279 , 1009 , 3315 , 3801 ,0 }; - static ulong[] dim550Kuo3Init = { 1 , 1 , 7 , 9 , 21 , 55 , 31 , 129 , 325 , 59 , 701 , 2227 , 1491 ,0 }; - static ulong[] dim551Kuo3Init = { 1 , 1 , 7 , 1 , 21 , 41 , 87 , 151 , 269 , 885 , 795 , 4087 , 2919 ,0 }; - static ulong[] dim552Kuo3Init = { 1 , 1 , 3 , 11 , 7 , 19 , 103 , 45 , 461 , 109 , 1921 , 2497 , 4969 ,0 }; - static ulong[] dim553Kuo3Init = { 1 , 1 , 3 , 7 , 7 , 49 , 9 , 185 , 95 , 277 , 1325 , 2393 , 7585 ,0 }; - static ulong[] dim554Kuo3Init = { 1 , 3 , 3 , 13 , 13 , 1 , 71 , 77 , 245 , 865 , 1693 , 2187 , 2589 ,0 }; - static ulong[] dim555Kuo3Init = { 1 , 3 , 1 , 15 , 19 , 59 , 17 , 189 , 101 , 511 , 23 , 677 , 4091 ,0 }; - static ulong[] dim556Kuo3Init = { 1 , 3 , 5 , 7 , 9 , 45 , 45 , 233 , 47 , 973 , 795 , 2339 , 595 ,0 }; - static ulong[] dim557Kuo3Init = { 1 , 3 , 1 , 7 , 15 , 35 , 79 , 53 , 429 , 299 , 389 , 237 , 2261 ,0 }; - static ulong[] dim558Kuo3Init = { 1 , 3 , 1 , 1 , 9 , 35 , 27 , 169 , 85 , 755 , 145 , 91 , 257 ,0 }; - static ulong[] dim559Kuo3Init = { 1 , 3 , 7 , 11 , 25 , 33 , 41 , 151 , 11 , 401 , 1335 , 2111 , 3309 ,0 }; - static ulong[] dim560Kuo3Init = { 1 , 1 , 7 , 3 , 17 , 1 , 61 , 253 , 289 , 917 , 1157 , 1513 , 4783 ,0 }; - static ulong[] dim561Kuo3Init = { 1 , 1 , 5 , 7 , 23 , 51 , 59 , 171 , 161 , 815 , 969 , 1199 , 4137 ,0 }; - static ulong[] dim562Kuo3Init = { 1 , 3 , 3 , 7 , 7 , 27 , 81 , 175 , 89 , 145 , 19 , 1469 , 3775 ,0 }; - static ulong[] dim563Kuo3Init = { 1 , 3 , 1 , 7 , 7 , 33 , 95 , 179 , 177 , 375 , 1077 , 3711 , 2903 ,0 }; - static ulong[] dim564Kuo3Init = { 1 , 3 , 1 , 15 , 15 , 27 , 127 , 245 , 307 , 949 , 1037 , 3753 , 4993 ,0 }; - static ulong[] dim565Kuo3Init = { 1 , 3 , 3 , 7 , 29 , 15 , 59 , 39 , 9 , 331 , 1877 , 3565 , 6483 ,0 }; - static ulong[] dim566Kuo3Init = { 1 , 1 , 5 , 3 , 1 , 41 , 29 , 185 , 351 , 837 , 747 , 3263 , 749 ,0 }; - static ulong[] dim567Kuo3Init = { 1 , 1 , 7 , 1 , 19 , 47 , 1 , 239 , 489 , 79 , 767 , 1123 , 8145 ,0 }; - static ulong[] dim568Kuo3Init = { 1 , 3 , 7 , 15 , 7 , 39 , 23 , 239 , 465 , 981 , 185 , 837 , 7837 ,0 }; - static ulong[] dim569Kuo3Init = { 1 , 3 , 5 , 5 , 23 , 15 , 21 , 221 , 259 , 663 , 185 , 1203 , 2857 ,0 }; - static ulong[] dim570Kuo3Init = { 1 , 1 , 3 , 5 , 31 , 43 , 107 , 199 , 117 , 161 , 403 , 2227 , 7969 ,0 }; - static ulong[] dim571Kuo3Init = { 1 , 1 , 3 , 5 , 5 , 5 , 105 , 153 , 349 , 601 , 815 , 939 , 3547 ,0 }; - static ulong[] dim572Kuo3Init = { 1 , 1 , 7 , 15 , 23 , 33 , 85 , 51 , 309 , 63 , 1799 , 1599 , 1711 ,0 }; - static ulong[] dim573Kuo3Init = { 1 , 1 , 7 , 3 , 15 , 41 , 71 , 169 , 87 , 381 , 1695 , 3189 , 3343 ,0 }; - static ulong[] dim574Kuo3Init = { 1 , 1 , 7 , 11 , 15 , 57 , 81 , 107 , 57 , 773 , 111 , 2741 , 6399 ,0 }; - static ulong[] dim575Kuo3Init = { 1 , 1 , 5 , 15 , 5 , 55 , 65 , 35 , 387 , 797 , 1093 , 4039 , 3041 ,0 }; - static ulong[] dim576Kuo3Init = { 1 , 1 , 5 , 3 , 29 , 5 , 87 , 235 , 503 , 539 , 483 , 2785 , 4211 ,0 }; - static ulong[] dim577Kuo3Init = { 1 , 1 , 3 , 5 , 11 , 53 , 101 , 83 , 61 , 97 , 411 , 2063 , 2951 ,0 }; - static ulong[] dim578Kuo3Init = { 1 , 1 , 1 , 5 , 25 , 33 , 45 , 253 , 183 , 251 , 1323 , 1891 , 5143 ,0 }; - static ulong[] dim579Kuo3Init = { 1 , 1 , 5 , 11 , 7 , 61 , 67 , 201 , 465 , 851 , 1 , 1533 , 2839 ,0 }; - static ulong[] dim580Kuo3Init = { 1 , 3 , 3 , 7 , 15 , 3 , 51 , 9 , 425 , 671 , 223 , 2203 , 481 ,0 }; - static ulong[] dim581Kuo3Init = { 1 , 1 , 1 , 7 , 25 , 5 , 45 , 153 , 479 , 437 , 221 , 1085 , 455 ,0 }; - static ulong[] dim582Kuo3Init = { 1 , 3 , 7 , 1 , 7 , 53 , 65 , 35 , 153 , 423 , 989 , 2779 , 4787 ,0 }; - static ulong[] dim583Kuo3Init = { 1 , 3 , 1 , 3 , 29 , 43 , 7 , 219 , 47 , 431 , 627 , 3735 , 383 ,0 }; - static ulong[] dim584Kuo3Init = { 1 , 1 , 5 , 13 , 31 , 49 , 121 , 29 , 235 , 325 , 1247 , 1765 , 7173 ,0 }; - static ulong[] dim585Kuo3Init = { 1 , 1 , 1 , 9 , 25 , 15 , 73 , 167 , 191 , 215 , 259 , 111 , 2289 ,0 }; - static ulong[] dim586Kuo3Init = { 1 , 3 , 7 , 9 , 23 , 1 , 119 , 15 , 155 , 153 , 1419 , 667 , 6309 ,0 }; - static ulong[] dim587Kuo3Init = { 1 , 1 , 5 , 13 , 7 , 53 , 91 , 161 , 445 , 283 , 571 , 3623 , 5737 ,0 }; - static ulong[] dim588Kuo3Init = { 1 , 3 , 3 , 5 , 3 , 39 , 29 , 47 , 393 , 871 , 345 , 805 , 8167 ,0 }; - static ulong[] dim589Kuo3Init = { 1 , 3 , 1 , 5 , 21 , 9 , 1 , 169 , 471 , 693 , 53 , 967 , 4145 ,0 }; - static ulong[] dim590Kuo3Init = { 1 , 3 , 7 , 11 , 17 , 19 , 123 , 133 , 511 , 15 , 675 , 3935 , 5465 ,0 }; - static ulong[] dim591Kuo3Init = { 1 , 3 , 5 , 13 , 25 , 51 , 63 , 87 , 503 , 61 , 907 , 105 , 7599 ,0 }; - static ulong[] dim592Kuo3Init = { 1 , 3 , 5 , 13 , 27 , 3 , 67 , 189 , 193 , 131 , 1227 , 227 , 1975 ,0 }; - static ulong[] dim593Kuo3Init = { 1 , 3 , 5 , 5 , 31 , 17 , 89 , 187 , 391 , 575 , 1715 , 2551 , 5371 ,0 }; - static ulong[] dim594Kuo3Init = { 1 , 3 , 1 , 9 , 11 , 63 , 9 , 251 , 399 , 703 , 1557 , 107 , 675 ,0 }; - static ulong[] dim595Kuo3Init = { 1 , 3 , 5 , 15 , 29 , 55 , 15 , 65 , 51 , 811 , 1387 , 3815 , 7973 ,0 }; - static ulong[] dim596Kuo3Init = { 1 , 3 , 1 , 13 , 19 , 33 , 87 , 7 , 183 , 97 , 2011 , 3849 , 3015 ,0 }; - static ulong[] dim597Kuo3Init = { 1 , 1 , 3 , 11 , 29 , 57 , 27 , 185 , 457 , 181 , 1341 , 2033 , 2181 ,0 }; - static ulong[] dim598Kuo3Init = { 1 , 3 , 7 , 5 , 25 , 19 , 19 , 147 , 101 , 73 , 499 , 897 , 3053 ,0 }; - static ulong[] dim599Kuo3Init = { 1 , 3 , 5 , 5 , 29 , 29 , 109 , 5 , 197 , 581 , 1829 , 3679 , 283 ,0 }; - static ulong[] dim600Kuo3Init = { 1 , 3 , 5 , 1 , 27 , 63 , 71 , 131 , 309 , 193 , 1663 , 3009 , 1041 ,0 }; - static ulong[] dim601Kuo3Init = { 1 , 3 , 3 , 5 , 19 , 29 , 95 , 173 , 195 , 205 , 207 , 3597 , 2223 ,0 }; - static ulong[] dim602Kuo3Init = { 1 , 1 , 5 , 1 , 3 , 45 , 127 , 251 , 175 , 663 , 415 , 1789 , 6577 ,0 }; - static ulong[] dim603Kuo3Init = { 1 , 3 , 1 , 9 , 1 , 51 , 73 , 165 , 377 , 525 , 381 , 2829 , 4619 ,0 }; - static ulong[] dim604Kuo3Init = { 1 , 3 , 1 , 15 , 23 , 19 , 79 , 115 , 297 , 75 , 1505 , 1407 , 5865 ,0 }; - static ulong[] dim605Kuo3Init = { 1 , 1 , 1 , 5 , 27 , 33 , 93 , 123 , 449 , 747 , 2027 , 51 , 4507 ,0 }; - static ulong[] dim606Kuo3Init = { 1 , 3 , 1 , 7 , 13 , 39 , 49 , 111 , 101 , 247 , 1375 , 3577 , 6769 ,0 }; - static ulong[] dim607Kuo3Init = { 1 , 1 , 7 , 9 , 19 , 49 , 35 , 139 , 57 , 527 , 1943 , 1781 , 1839 ,0 }; - static ulong[] dim608Kuo3Init = { 1 , 3 , 7 , 7 , 3 , 7 , 67 , 163 , 289 , 139 , 1415 , 2149 , 7501 ,0 }; - static ulong[] dim609Kuo3Init = { 1 , 3 , 5 , 5 , 13 , 47 , 21 , 47 , 3 , 105 , 473 , 2013 , 2443 ,0 }; - static ulong[] dim610Kuo3Init = { 1 , 1 , 3 , 13 , 31 , 25 , 21 , 75 , 505 , 795 , 1311 , 2467 , 5541 ,0 }; - static ulong[] dim611Kuo3Init = { 1 , 1 , 5 , 1 , 25 , 15 , 21 , 113 , 427 , 249 , 293 , 1089 , 1589 ,0 }; - static ulong[] dim612Kuo3Init = { 1 , 1 , 7 , 5 , 17 , 11 , 3 , 211 , 219 , 37 , 781 , 1299 , 3669 ,0 }; - static ulong[] dim613Kuo3Init = { 1 , 3 , 1 , 15 , 23 , 3 , 55 , 59 , 273 , 947 , 1647 , 3111 , 2615 ,0 }; - static ulong[] dim614Kuo3Init = { 1 , 1 , 3 , 7 , 21 , 33 , 81 , 253 , 267 , 499 , 299 , 4015 , 1669 ,0 }; - static ulong[] dim615Kuo3Init = { 1 , 3 , 7 , 5 , 5 , 17 , 75 , 205 , 53 , 237 , 1791 , 3671 , 4205 ,0 }; - static ulong[] dim616Kuo3Init = { 1 , 3 , 1 , 5 , 3 , 59 , 77 , 39 , 295 , 649 , 1219 , 3971 , 7675 ,0 }; - static ulong[] dim617Kuo3Init = { 1 , 3 , 5 , 15 , 1 , 1 , 13 , 207 , 445 , 91 , 571 , 869 , 359 ,0 }; - static ulong[] dim618Kuo3Init = { 1 , 3 , 5 , 5 , 15 , 35 , 79 , 175 , 313 , 745 , 1689 , 1499 , 5899 ,0 }; - static ulong[] dim619Kuo3Init = { 1 , 3 , 7 , 7 , 19 , 51 , 57 , 131 , 491 , 301 , 1405 , 3789 , 6081 ,0 }; - static ulong[] dim620Kuo3Init = { 1 , 1 , 3 , 9 , 27 , 53 , 55 , 193 , 413 , 535 , 715 , 2823 , 2063 ,0 }; - static ulong[] dim621Kuo3Init = { 1 , 1 , 7 , 13 , 31 , 47 , 47 , 99 , 441 , 125 , 999 , 3575 , 8007 ,0 }; - static ulong[] dim622Kuo3Init = { 1 , 1 , 1 , 11 , 17 , 45 , 67 , 27 , 329 , 267 , 773 , 565 , 5559 ,0 }; - static ulong[] dim623Kuo3Init = { 1 , 1 , 7 , 11 , 31 , 23 , 125 , 117 , 373 , 523 , 571 , 1385 , 3841 ,0 }; - static ulong[] dim624Kuo3Init = { 1 , 3 , 7 , 15 , 3 , 15 , 63 , 91 , 23 , 97 , 311 , 3045 , 2025 ,0 }; - static ulong[] dim625Kuo3Init = { 1 , 3 , 7 , 5 , 29 , 37 , 105 , 63 , 511 , 35 , 537 , 4047 , 7449 ,0 }; - static ulong[] dim626Kuo3Init = { 1 , 3 , 1 , 13 , 5 , 9 , 29 , 51 , 269 , 395 , 1737 , 2097 , 199 ,0 }; - static ulong[] dim627Kuo3Init = { 1 , 3 , 7 , 15 , 23 , 33 , 71 , 111 , 497 , 369 , 1265 , 2937 , 1883 ,0 }; - static ulong[] dim628Kuo3Init = { 1 , 1 , 3 , 3 , 3 , 49 , 117 , 243 , 57 , 83 , 3 , 3319 , 5711 ,0 }; - static ulong[] dim629Kuo3Init = { 1 , 1 , 5 , 11 , 25 , 41 , 29 , 123 , 405 , 623 , 1537 , 3467 , 699 ,0 }; - static ulong[] dim630Kuo3Init = { 1 , 3 , 7 , 13 , 17 , 5 , 87 , 103 , 501 , 581 , 713 , 1535 , 4637 ,0 }; - static ulong[] dim631Kuo3Init = { 1 , 3 , 3 , 3 , 25 , 59 , 91 , 241 , 163 , 537 , 1249 , 3427 , 6647 ,0 }; - static ulong[] dim632Kuo3Init = { 1 , 3 , 7 , 1 , 27 , 7 , 49 , 219 , 51 , 989 , 599 , 2593 , 6051 ,0 }; - static ulong[] dim633Kuo3Init = { 1 , 1 , 7 , 9 , 17 , 19 , 31 , 23 , 199 , 729 , 819 , 287 , 4689 ,0 }; - static ulong[] dim634Kuo3Init = { 1 , 1 , 1 , 11 , 13 , 49 , 97 , 229 , 411 , 29 , 1815 , 3761 , 3849 ,0 }; - static ulong[] dim635Kuo3Init = { 1 , 3 , 1 , 1 , 23 , 35 , 15 , 33 , 3 , 865 , 995 , 1263 , 3779 ,0 }; - static ulong[] dim636Kuo3Init = { 1 , 1 , 7 , 7 , 17 , 1 , 103 , 117 , 455 , 93 , 599 , 1075 , 4389 ,0 }; - static ulong[] dim637Kuo3Init = { 1 , 3 , 7 , 5 , 27 , 3 , 67 , 117 , 101 , 443 , 1773 , 3731 , 629 ,0 }; - static ulong[] dim638Kuo3Init = { 1 , 3 , 1 , 11 , 9 , 51 , 63 , 217 , 273 , 425 , 1889 , 1113 , 3799 ,0 }; - static ulong[] dim639Kuo3Init = { 1 , 1 , 3 , 3 , 25 , 13 , 37 , 89 , 429 , 493 , 637 , 3287 , 6733 ,0 }; - static ulong[] dim640Kuo3Init = { 1 , 1 , 1 , 9 , 17 , 29 , 45 , 89 , 141 , 633 , 243 , 4035 , 1835 ,0 }; - static ulong[] dim641Kuo3Init = { 1 , 1 , 1 , 9 , 15 , 41 , 61 , 239 , 349 , 3 , 1669 , 1767 , 6257 ,0 }; - static ulong[] dim642Kuo3Init = { 1 , 3 , 5 , 11 , 21 , 41 , 17 , 65 , 495 , 879 , 1891 , 667 , 3807 ,0 }; - static ulong[] dim643Kuo3Init = { 1 , 1 , 5 , 11 , 7 , 25 , 101 , 231 , 159 , 287 , 1125 , 3859 , 4331 ,0 }; - static ulong[] dim644Kuo3Init = { 1 , 1 , 1 , 9 , 13 , 59 , 23 , 85 , 393 , 611 , 1213 , 7 , 5707 ,0 }; - static ulong[] dim645Kuo3Init = { 1 , 3 , 5 , 15 , 13 , 33 , 61 , 255 , 163 , 465 , 641 , 703 , 6391 ,0 }; - static ulong[] dim646Kuo3Init = { 1 , 1 , 3 , 3 , 29 , 41 , 25 , 19 , 247 , 973 , 1815 , 235 , 7215 ,0 }; - static ulong[] dim647Kuo3Init = { 1 , 1 , 3 , 11 , 17 , 43 , 83 , 105 , 493 , 663 , 1395 , 1079 , 745 ,0 }; - static ulong[] dim648Kuo3Init = { 1 , 1 , 3 , 13 , 17 , 53 , 5 , 55 , 31 , 459 , 673 , 1253 , 5601 ,0 }; - static ulong[] dim649Kuo3Init = { 1 , 3 , 7 , 7 , 1 , 49 , 85 , 73 , 265 , 555 , 43 , 2235 , 6787 ,0 }; - static ulong[] dim650Kuo3Init = { 1 , 1 , 7 , 5 , 15 , 3 , 43 , 201 , 289 , 755 , 1605 , 1927 , 6179 ,0 }; - static ulong[] dim651Kuo3Init = { 1 , 1 , 7 , 9 , 15 , 5 , 101 , 19 , 17 , 879 , 1155 , 3845 , 3225 ,0 }; - static ulong[] dim652Kuo3Init = { 1 , 3 , 5 , 15 , 15 , 63 , 103 , 133 , 209 , 121 , 1865 , 4039 , 3335 ,0 }; - static ulong[] dim653Kuo3Init = { 1 , 3 , 7 , 11 , 15 , 51 , 87 , 241 , 455 , 431 , 1111 , 1319 , 1959 ,0 }; - static ulong[] dim654Kuo3Init = { 1 , 3 , 7 , 5 , 21 , 47 , 67 , 251 , 91 , 575 , 481 , 3269 , 1473 ,0 }; - static ulong[] dim655Kuo3Init = { 1 , 3 , 1 , 1 , 23 , 5 , 37 , 169 , 105 , 803 , 1765 , 1823 , 5081 ,0 }; - static ulong[] dim656Kuo3Init = { 1 , 1 , 7 , 9 , 1 , 37 , 55 , 175 , 431 , 77 , 171 , 3759 , 1227 ,0 }; - static ulong[] dim657Kuo3Init = { 1 , 3 , 7 , 9 , 3 , 61 , 111 , 139 , 87 , 649 , 243 , 1109 , 1303 ,0 }; - static ulong[] dim658Kuo3Init = { 1 , 3 , 1 , 11 , 17 , 25 , 9 , 117 , 227 , 821 , 1219 , 2567 , 5851 ,0 }; - static ulong[] dim659Kuo3Init = { 1 , 1 , 7 , 1 , 19 , 53 , 89 , 57 , 29 , 885 , 275 , 2289 , 4341 ,0 }; - static ulong[] dim660Kuo3Init = { 1 , 3 , 1 , 5 , 5 , 1 , 43 , 237 , 235 , 667 , 1433 , 2497 , 5535 ,0 }; - static ulong[] dim661Kuo3Init = { 1 , 1 , 1 , 11 , 21 , 9 , 29 , 165 , 153 , 157 , 1209 , 817 , 7819 ,0 }; - static ulong[] dim662Kuo3Init = { 1 , 3 , 1 , 5 , 1 , 37 , 33 , 9 , 493 , 497 , 1469 , 357 , 5929 ,0 }; - static ulong[] dim663Kuo3Init = { 1 , 3 , 3 , 9 , 25 , 55 , 5 , 157 , 397 , 461 , 537 , 1085 , 6737 ,0 }; - static ulong[] dim664Kuo3Init = { 1 , 3 , 3 , 13 , 3 , 61 , 83 , 5 , 5 , 243 , 1745 , 845 , 1965 ,0 }; - static ulong[] dim665Kuo3Init = { 1 , 3 , 1 , 3 , 31 , 63 , 3 , 75 , 355 , 799 , 417 , 791 , 2763 ,0 }; - static ulong[] dim666Kuo3Init = { 1 , 3 , 3 , 11 , 5 , 31 , 99 , 163 , 69 , 699 , 809 , 1651 , 7249 ,0 }; - static ulong[] dim667Kuo3Init = { 1 , 1 , 7 , 3 , 29 , 53 , 51 , 185 , 379 , 743 , 611 , 963 , 5631 ,0 }; - static ulong[] dim668Kuo3Init = { 1 , 1 , 5 , 11 , 21 , 15 , 59 , 75 , 121 , 247 , 307 , 2483 , 2861 ,0 }; - static ulong[] dim669Kuo3Init = { 1 , 1 , 1 , 5 , 21 , 5 , 33 , 43 , 225 , 675 , 213 , 3081 , 5047 ,0 }; - static ulong[] dim670Kuo3Init = { 1 , 3 , 3 , 15 , 29 , 45 , 19 , 19 , 15 , 605 , 1531 , 1305 , 7725 ,0 }; - static ulong[] dim671Kuo3Init = { 1 , 3 , 1 , 5 , 19 , 21 , 73 , 131 , 37 , 667 , 1953 , 1211 , 7499 ,0 }; - static ulong[] dim672Kuo3Init = { 1 , 3 , 1 , 5 , 13 , 3 , 105 , 151 , 131 , 965 , 1953 , 335 , 4991 ,0 }; - static ulong[] dim673Kuo3Init = { 1 , 3 , 1 , 13 , 23 , 37 , 81 , 147 , 353 , 125 , 141 , 4017 , 7543 ,0 }; - static ulong[] dim674Kuo3Init = { 1 , 1 , 1 , 7 , 15 , 13 , 25 , 107 , 431 , 327 , 1069 , 155 , 1729 ,0 }; - static ulong[] dim675Kuo3Init = { 1 , 1 , 5 , 1 , 19 , 3 , 51 , 113 , 349 , 845 , 1157 , 1771 , 4923 ,0 }; - static ulong[] dim676Kuo3Init = { 1 , 1 , 3 , 7 , 17 , 19 , 47 , 249 , 215 , 959 , 659 , 3989 , 3719 ,0 }; - static ulong[] dim677Kuo3Init = { 1 , 3 , 5 , 5 , 27 , 57 , 41 , 29 , 153 , 1007 , 1209 , 1373 , 2847 ,0 }; - static ulong[] dim678Kuo3Init = { 1 , 3 , 5 , 7 , 5 , 21 , 23 , 67 , 127 , 755 , 211 , 2517 , 8161 ,0 }; - static ulong[] dim679Kuo3Init = { 1 , 1 , 7 , 15 , 1 , 5 , 65 , 197 , 435 , 275 , 473 , 1333 , 3669 ,0 }; - static ulong[] dim680Kuo3Init = { 1 , 3 , 7 , 1 , 17 , 19 , 61 , 11 , 425 , 717 , 351 , 2323 , 6575 ,0 }; - static ulong[] dim681Kuo3Init = { 1 , 1 , 7 , 3 , 29 , 13 , 115 , 19 , 235 , 371 , 81 , 3107 , 3103 ,0 }; - static ulong[] dim682Kuo3Init = { 1 , 1 , 3 , 1 , 23 , 19 , 57 , 179 , 7 , 405 , 217 , 3159 , 6675 ,0 }; - static ulong[] dim683Kuo3Init = { 1 , 3 , 3 , 3 , 19 , 39 , 121 , 195 , 205 , 489 , 1959 , 3617 , 799 ,0 }; - static ulong[] dim684Kuo3Init = { 1 , 3 , 5 , 9 , 19 , 35 , 115 , 3 , 17 , 201 , 671 , 1847 , 597 ,0 }; - static ulong[] dim685Kuo3Init = { 1 , 3 , 1 , 3 , 7 , 1 , 121 , 77 , 163 , 769 , 977 , 1223 , 4215 ,0 }; - static ulong[] dim686Kuo3Init = { 1 , 1 , 1 , 15 , 9 , 13 , 33 , 57 , 271 , 733 , 1699 , 3083 , 813 ,0 }; - static ulong[] dim687Kuo3Init = { 1 , 1 , 7 , 7 , 15 , 49 , 101 , 183 , 339 , 129 , 1865 , 2697 , 3131 ,0 }; - static ulong[] dim688Kuo3Init = { 1 , 3 , 1 , 3 , 9 , 39 , 33 , 141 , 459 , 971 , 1621 , 3893 , 4393 ,0 }; - static ulong[] dim689Kuo3Init = { 1 , 1 , 3 , 3 , 27 , 61 , 53 , 79 , 375 , 613 , 663 , 2325 , 4707 ,0 }; - static ulong[] dim690Kuo3Init = { 1 , 1 , 7 , 1 , 27 , 59 , 59 , 179 , 173 , 333 , 649 , 1053 , 555 ,0 }; - static ulong[] dim691Kuo3Init = { 1 , 3 , 3 , 13 , 15 , 55 , 25 , 91 , 45 , 739 , 1769 , 1341 , 2007 ,0 }; - static ulong[] dim692Kuo3Init = { 1 , 1 , 3 , 15 , 9 , 59 , 27 , 45 , 133 , 941 , 1037 , 1559 , 7145 ,0 }; - static ulong[] dim693Kuo3Init = { 1 , 3 , 5 , 1 , 13 , 5 , 3 , 167 , 235 , 609 , 1023 , 1967 , 771 ,0 }; - static ulong[] dim694Kuo3Init = { 1 , 1 , 1 , 15 , 19 , 15 , 45 , 143 , 309 , 697 , 337 , 3399 , 3599 ,0 }; - static ulong[] dim695Kuo3Init = { 1 , 1 , 5 , 3 , 9 , 1 , 19 , 41 , 39 , 1003 , 997 , 1357 , 5849 ,0 }; - static ulong[] dim696Kuo3Init = { 1 , 3 , 3 , 7 , 29 , 37 , 9 , 165 , 9 , 855 , 337 , 2363 , 2633 ,0 }; - static ulong[] dim697Kuo3Init = { 1 , 3 , 5 , 1 , 23 , 19 , 97 , 55 , 411 , 623 , 287 , 3365 , 7675 ,0 }; - static ulong[] dim698Kuo3Init = { 1 , 3 , 3 , 3 , 11 , 1 , 47 , 81 , 377 , 85 , 859 , 3717 , 1979 ,0 }; - static ulong[] dim699Kuo3Init = { 1 , 1 , 3 , 1 , 11 , 3 , 125 , 43 , 471 , 127 , 341 , 2943 , 231 ,0 }; - static ulong[] dim700Kuo3Init = { 1 , 1 , 5 , 15 , 29 , 21 , 101 , 193 , 389 , 727 , 1397 , 2799 , 4387 ,0 }; - static ulong[] dim701Kuo3Init = { 1 , 3 , 5 , 15 , 27 , 19 , 13 , 195 , 105 , 5 , 985 , 767 , 4573 ,0 }; - static ulong[] dim702Kuo3Init = { 1 , 1 , 5 , 3 , 13 , 29 , 33 , 123 , 107 , 353 , 723 , 3821 , 5425 ,0 }; - static ulong[] dim703Kuo3Init = { 1 , 3 , 5 , 11 , 23 , 11 , 69 , 219 , 15 , 735 , 1015 , 431 , 6511 ,0 }; - static ulong[] dim704Kuo3Init = { 1 , 3 , 1 , 1 , 27 , 49 , 79 , 91 , 201 , 365 , 255 , 1309 , 7165 ,0 }; - static ulong[] dim705Kuo3Init = { 1 , 3 , 1 , 13 , 21 , 61 , 39 , 111 , 71 , 137 , 551 , 3237 , 6681 ,0 }; - static ulong[] dim706Kuo3Init = { 1 , 3 , 5 , 13 , 19 , 21 , 121 , 227 , 381 , 677 , 421 , 449 , 5375 ,0 }; - static ulong[] dim707Kuo3Init = { 1 , 1 , 7 , 5 , 1 , 23 , 95 , 199 , 509 , 197 , 829 , 941 , 2269 ,0 }; - static ulong[] dim708Kuo3Init = { 1 , 3 , 7 , 5 , 21 , 61 , 119 , 59 , 97 , 841 , 453 , 2439 , 7345 ,0 }; - static ulong[] dim709Kuo3Init = { 1 , 1 , 1 , 3 , 23 , 21 , 19 , 245 , 281 , 841 , 273 , 1967 , 2129 ,0 }; - static ulong[] dim710Kuo3Init = { 1 , 3 , 3 , 5 , 7 , 43 , 19 , 253 , 239 , 421 , 461 , 4023 , 6981 ,0 }; - static ulong[] dim711Kuo3Init = { 1 , 3 , 1 , 11 , 25 , 3 , 109 , 107 , 55 , 781 , 1109 , 101 , 889 ,0 }; - static ulong[] dim712Kuo3Init = { 1 , 3 , 7 , 13 , 1 , 21 , 27 , 3 , 303 , 557 , 1381 , 407 , 1849 ,0 }; - static ulong[] dim713Kuo3Init = { 1 , 1 , 3 , 13 , 3 , 61 , 121 , 119 , 453 , 137 , 2039 , 3333 , 333 ,0 }; - static ulong[] dim714Kuo3Init = { 1 , 3 , 5 , 1 , 21 , 9 , 113 , 9 , 413 , 301 , 1795 , 2827 , 1837 ,0 }; - static ulong[] dim715Kuo3Init = { 1 , 3 , 5 , 15 , 13 , 31 , 119 , 107 , 445 , 277 , 1555 , 2121 , 2173 ,0 }; - static ulong[] dim716Kuo3Init = { 1 , 1 , 1 , 5 , 9 , 5 , 5 , 97 , 191 , 949 , 1603 , 2181 , 6879 ,0 }; - static ulong[] dim717Kuo3Init = { 1 , 3 , 3 , 9 , 5 , 47 , 77 , 43 , 483 , 137 , 61 , 1811 , 5309 ,0 }; - static ulong[] dim718Kuo3Init = { 1 , 3 , 7 , 11 , 25 , 63 , 107 , 207 , 23 , 231 , 1685 , 4009 , 391 ,0 }; - static ulong[] dim719Kuo3Init = { 1 , 3 , 7 , 9 , 3 , 35 , 119 , 83 , 193 , 269 , 289 , 3051 , 8137 ,0 }; - static ulong[] dim720Kuo3Init = { 1 , 3 , 3 , 11 , 25 , 25 , 17 , 243 , 195 , 503 , 1797 , 1913 , 749 ,0 }; - static ulong[] dim721Kuo3Init = { 1 , 3 , 1 , 13 , 5 , 35 , 101 , 57 , 185 , 881 , 2005 , 3493 , 2715 ,0 }; - static ulong[] dim722Kuo3Init = { 1 , 3 , 1 , 11 , 25 , 51 , 113 , 177 , 175 , 855 , 1727 , 1901 , 8181 ,0 }; - static ulong[] dim723Kuo3Init = { 1 , 1 , 3 , 9 , 9 , 63 , 109 , 233 , 205 , 357 , 499 , 3367 , 1189 ,0 }; - static ulong[] dim724Kuo3Init = { 1 , 3 , 1 , 15 , 17 , 11 , 35 , 135 , 501 , 319 , 1465 , 2095 , 5269 ,0 }; - static ulong[] dim725Kuo3Init = { 1 , 1 , 3 , 9 , 1 , 27 , 99 , 201 , 67 , 269 , 135 , 3891 , 4067 ,0 }; - static ulong[] dim726Kuo3Init = { 1 , 1 , 1 , 9 , 15 , 37 , 83 , 135 , 3 , 645 , 499 , 2597 , 2705 ,0 }; - static ulong[] dim727Kuo3Init = { 1 , 3 , 1 , 7 , 17 , 33 , 89 , 51 , 295 , 809 , 743 , 27 , 2599 ,0 }; - static ulong[] dim728Kuo3Init = { 1 , 1 , 7 , 1 , 5 , 55 , 11 , 97 , 177 , 515 , 1651 , 1183 , 5803 ,0 }; - static ulong[] dim729Kuo3Init = { 1 , 1 , 3 , 11 , 21 , 3 , 39 , 249 , 55 , 891 , 1681 , 709 , 7833 ,0 }; - static ulong[] dim730Kuo3Init = { 1 , 3 , 5 , 13 , 11 , 21 , 81 , 21 , 99 , 223 , 355 , 2015 , 7195 ,0 }; - static ulong[] dim731Kuo3Init = { 1 , 3 , 7 , 11 , 25 , 23 , 9 , 131 , 417 , 583 , 1927 , 277 , 2923 ,0 }; - static ulong[] dim732Kuo3Init = { 1 , 1 , 5 , 5 , 1 , 43 , 35 , 87 , 471 , 499 , 1411 , 2867 , 2477 ,0 }; - static ulong[] dim733Kuo3Init = { 1 , 1 , 5 , 9 , 25 , 43 , 83 , 103 , 183 , 527 , 483 , 935 , 7097 ,0 }; - static ulong[] dim734Kuo3Init = { 1 , 1 , 5 , 7 , 31 , 13 , 49 , 169 , 135 , 885 , 1367 , 2627 , 5917 ,0 }; - static ulong[] dim735Kuo3Init = { 1 , 3 , 7 , 5 , 1 , 39 , 97 , 167 , 95 , 745 , 1067 , 805 , 2885 ,0 }; - static ulong[] dim736Kuo3Init = { 1 , 3 , 7 , 15 , 31 , 41 , 1 , 147 , 15 , 795 , 323 , 309 , 5075 ,0 }; - static ulong[] dim737Kuo3Init = { 1 , 3 , 7 , 5 , 23 , 3 , 65 , 143 , 183 , 671 , 993 , 547 , 5971 ,0 }; - static ulong[] dim738Kuo3Init = { 1 , 3 , 7 , 1 , 21 , 59 , 29 , 45 , 367 , 363 , 1707 , 541 , 7045 ,0 }; - static ulong[] dim739Kuo3Init = { 1 , 1 , 7 , 15 , 11 , 25 , 77 , 33 , 409 , 495 , 1713 , 1479 , 2857 ,0 }; - static ulong[] dim740Kuo3Init = { 1 , 1 , 3 , 1 , 11 , 59 , 113 , 217 , 313 , 79 , 379 , 627 , 3917 ,0 }; - static ulong[] dim741Kuo3Init = { 1 , 1 , 1 , 15 , 31 , 61 , 73 , 211 , 419 , 965 , 1817 , 3965 , 1425 ,0 }; - static ulong[] dim742Kuo3Init = { 1 , 1 , 7 , 13 , 9 , 9 , 61 , 119 , 223 , 387 , 595 , 191 , 1723 ,0 }; - static ulong[] dim743Kuo3Init = { 1 , 3 , 5 , 3 , 25 , 49 , 83 , 175 , 329 , 1003 , 729 , 1399 , 6553 ,0 }; - static ulong[] dim744Kuo3Init = { 1 , 1 , 5 , 9 , 5 , 37 , 31 , 43 , 365 , 403 , 1485 , 1621 , 3753 ,0 }; - static ulong[] dim745Kuo3Init = { 1 , 3 , 5 , 7 , 17 , 5 , 125 , 219 , 311 , 1 , 639 , 1939 , 4367 ,0 }; - static ulong[] dim746Kuo3Init = { 1 , 3 , 5 , 3 , 21 , 63 , 119 , 31 , 151 , 325 , 1063 , 2477 , 1223 ,0 }; - static ulong[] dim747Kuo3Init = { 1 , 1 , 5 , 13 , 15 , 23 , 1 , 141 , 105 , 21 , 747 , 161 , 3555 ,0 }; - static ulong[] dim748Kuo3Init = { 1 , 3 , 7 , 1 , 31 , 21 , 11 , 27 , 267 , 205 , 1569 , 765 , 1357 ,0 }; - static ulong[] dim749Kuo3Init = { 1 , 1 , 3 , 9 , 23 , 59 , 93 , 51 , 81 , 367 , 1545 , 1161 , 3481 ,0 }; - static ulong[] dim750Kuo3Init = { 1 , 3 , 7 , 11 , 15 , 51 , 43 , 205 , 237 , 617 , 1075 , 1051 , 5285 ,0 }; - static ulong[] dim751Kuo3Init = { 1 , 3 , 7 , 3 , 11 , 5 , 95 , 203 , 495 , 661 , 1119 , 1095 , 3391 ,0 }; - static ulong[] dim752Kuo3Init = { 1 , 3 , 3 , 1 , 25 , 39 , 59 , 159 , 273 , 101 , 1887 , 417 , 3423 ,0 }; - static ulong[] dim753Kuo3Init = { 1 , 3 , 5 , 13 , 23 , 45 , 13 , 87 , 139 , 313 , 1527 , 3739 , 7009 ,0 }; - static ulong[] dim754Kuo3Init = { 1 , 1 , 5 , 1 , 23 , 43 , 127 , 149 , 63 , 823 , 1075 , 3123 , 3079 ,0 }; - static ulong[] dim755Kuo3Init = { 1 , 1 , 7 , 3 , 11 , 1 , 29 , 127 , 313 , 971 , 1363 , 1765 , 6439 ,0 }; - static ulong[] dim756Kuo3Init = { 1 , 1 , 3 , 13 , 1 , 19 , 61 , 125 , 345 , 51 , 273 , 2783 , 5255 ,0 }; - static ulong[] dim757Kuo3Init = { 1 , 1 , 1 , 7 , 29 , 33 , 21 , 239 , 351 , 481 , 795 , 2865 , 2235 ,0 }; - static ulong[] dim758Kuo3Init = { 1 , 3 , 3 , 3 , 19 , 31 , 41 , 125 , 327 , 169 , 837 , 753 , 191 ,0 }; - static ulong[] dim759Kuo3Init = { 1 , 3 , 7 , 15 , 5 , 15 , 5 , 109 , 333 , 127 , 2021 , 441 , 6307 ,0 }; - static ulong[] dim760Kuo3Init = { 1 , 3 , 7 , 9 , 23 , 39 , 79 , 235 , 27 , 573 , 1989 , 1401 , 7597 ,0 }; - static ulong[] dim761Kuo3Init = { 1 , 1 , 7 , 3 , 23 , 29 , 119 , 53 , 105 , 609 , 1139 , 321 , 1111 ,0 }; - static ulong[] dim762Kuo3Init = { 1 , 1 , 7 , 13 , 13 , 43 , 3 , 211 , 389 , 563 , 1047 , 1373 , 4669 ,0 }; - static ulong[] dim763Kuo3Init = { 1 , 3 , 3 , 1 , 9 , 7 , 1 , 135 , 455 , 539 , 1681 , 1851 , 4585 ,0 }; - static ulong[] dim764Kuo3Init = { 1 , 3 , 1 , 13 , 19 , 45 , 65 , 109 , 391 , 563 , 753 , 2405 , 2623 ,0 }; - static ulong[] dim765Kuo3Init = { 1 , 3 , 1 , 13 , 31 , 41 , 29 , 153 , 507 , 559 , 877 , 125 , 4827 ,0 }; - static ulong[] dim766Kuo3Init = { 1 , 1 , 7 , 3 , 15 , 53 , 39 , 1 , 143 , 351 , 505 , 1213 , 4829 ,0 }; - static ulong[] dim767Kuo3Init = { 1 , 1 , 5 , 5 , 27 , 49 , 39 , 101 , 501 , 239 , 1233 , 1695 , 6929 ,0 }; - static ulong[] dim768Kuo3Init = { 1 , 1 , 5 , 9 , 13 , 29 , 103 , 185 , 343 , 943 , 1709 , 801 , 1227 ,0 }; - static ulong[] dim769Kuo3Init = { 1 , 1 , 1 , 3 , 3 , 1 , 63 , 23 , 199 , 53 , 1629 , 325 , 7609 ,0 }; - static ulong[] dim770Kuo3Init = { 1 , 3 , 7 , 1 , 11 , 47 , 61 , 171 , 71 , 493 , 2035 , 869 , 5925 ,0 }; - static ulong[] dim771Kuo3Init = { 1 , 1 , 7 , 7 , 5 , 3 , 95 , 163 , 89 , 395 , 1033 , 2051 , 5589 ,0 }; - static ulong[] dim772Kuo3Init = { 1 , 3 , 5 , 9 , 3 , 21 , 29 , 143 , 333 , 805 , 267 , 4077 , 383 ,0 }; - static ulong[] dim773Kuo3Init = { 1 , 1 , 3 , 13 , 9 , 17 , 87 , 163 , 107 , 1011 , 1099 , 3395 , 987 ,0 }; - static ulong[] dim774Kuo3Init = { 1 , 3 , 1 , 1 , 5 , 51 , 71 , 249 , 441 , 513 , 791 , 1831 , 2757 ,0 }; - static ulong[] dim775Kuo3Init = { 1 , 1 , 3 , 13 , 23 , 7 , 101 , 211 , 289 , 1001 , 1623 , 3239 , 1685 ,0 }; - static ulong[] dim776Kuo3Init = { 1 , 1 , 5 , 15 , 31 , 53 , 91 , 245 , 143 , 237 , 557 , 3099 , 3737 ,0 }; - static ulong[] dim777Kuo3Init = { 1 , 3 , 1 , 1 , 5 , 27 , 51 , 173 , 321 , 85 , 1385 , 9 , 1887 ,0 }; - static ulong[] dim778Kuo3Init = { 1 , 3 , 1 , 15 , 11 , 17 , 49 , 97 , 121 , 189 , 2031 , 565 , 7513 ,0 }; - static ulong[] dim779Kuo3Init = { 1 , 1 , 5 , 5 , 1 , 3 , 55 , 157 , 27 , 783 , 1543 , 2645 , 1079 ,0 }; - static ulong[] dim780Kuo3Init = { 1 , 1 , 5 , 11 , 27 , 9 , 83 , 155 , 17 , 147 , 1561 , 3213 , 4483 ,0 }; - static ulong[] dim781Kuo3Init = { 1 , 3 , 5 , 15 , 23 , 63 , 127 , 97 , 459 , 869 , 671 , 3287 , 995 ,0 }; - static ulong[] dim782Kuo3Init = { 1 , 3 , 3 , 1 , 5 , 1 , 89 , 229 , 269 , 493 , 709 , 2719 , 4803 ,0 }; - static ulong[] dim783Kuo3Init = { 1 , 1 , 3 , 3 , 27 , 5 , 85 , 55 , 491 , 781 , 711 , 3193 , 2051 ,0 }; - static ulong[] dim784Kuo3Init = { 1 , 1 , 5 , 13 , 21 , 9 , 31 , 107 , 381 , 613 , 991 , 2289 , 325 ,0 }; - static ulong[] dim785Kuo3Init = { 1 , 3 , 7 , 11 , 11 , 47 , 115 , 103 , 101 , 945 , 1993 , 1345 , 2031 ,0 }; - static ulong[] dim786Kuo3Init = { 1 , 3 , 7 , 11 , 27 , 59 , 123 , 73 , 85 , 975 , 397 , 2619 , 2095 ,0 }; - static ulong[] dim787Kuo3Init = { 1 , 1 , 1 , 13 , 19 , 31 , 87 , 45 , 39 , 43 , 1041 , 2015 , 5859 ,0 }; - static ulong[] dim788Kuo3Init = { 1 , 1 , 3 , 15 , 5 , 19 , 47 , 193 , 293 , 961 , 113 , 3013 , 889 ,0 }; - static ulong[] dim789Kuo3Init = { 1 , 1 , 1 , 3 , 31 , 61 , 61 , 209 , 493 , 785 , 1825 , 3779 , 8095 ,0 }; - static ulong[] dim790Kuo3Init = { 1 , 1 , 3 , 9 , 17 , 51 , 103 , 255 , 133 , 165 , 281 , 3945 , 2779 ,0 }; - static ulong[] dim791Kuo3Init = { 1 , 1 , 7 , 3 , 9 , 33 , 105 , 29 , 449 , 231 , 1393 , 1071 , 5043 ,0 }; - static ulong[] dim792Kuo3Init = { 1 , 1 , 7 , 5 , 29 , 35 , 115 , 1 , 467 , 969 , 343 , 2291 , 5099 ,0 }; - static ulong[] dim793Kuo3Init = { 1 , 1 , 3 , 5 , 13 , 21 , 99 , 151 , 13 , 861 , 189 , 1709 , 4943 ,0 }; - static ulong[] dim794Kuo3Init = { 1 , 1 , 7 , 15 , 5 , 41 , 53 , 89 , 235 , 515 , 1819 , 3907 , 4861 ,0 }; - static ulong[] dim795Kuo3Init = { 1 , 3 , 5 , 1 , 7 , 15 , 75 , 65 , 247 , 581 , 853 , 445 , 7623 ,0 }; - static ulong[] dim796Kuo3Init = { 1 , 1 , 3 , 5 , 25 , 29 , 27 , 73 , 359 , 729 , 1991 , 1075 , 8107 ,0 }; - static ulong[] dim797Kuo3Init = { 1 , 1 , 3 , 1 , 5 , 35 , 83 , 119 , 385 , 657 , 1085 , 2707 , 4403 ,0 }; - static ulong[] dim798Kuo3Init = { 1 , 3 , 5 , 5 , 25 , 55 , 51 , 205 , 257 , 887 , 827 , 2795 , 925 ,0 }; - static ulong[] dim799Kuo3Init = { 1 , 1 , 3 , 1 , 5 , 29 , 113 , 195 , 439 , 241 , 127 , 2783 , 2577 ,0 }; - static ulong[] dim800Kuo3Init = { 1 , 3 , 1 , 11 , 15 , 47 , 7 , 149 , 81 , 897 , 235 , 3935 , 6981 ,0 }; - static ulong[] dim801Kuo3Init = { 1 , 3 , 3 , 1 , 27 , 5 , 69 , 125 , 377 , 829 , 1549 , 3025 , 2319 ,0 }; - static ulong[] dim802Kuo3Init = { 1 , 1 , 7 , 15 , 15 , 19 , 3 , 205 , 291 , 209 , 1817 , 2439 , 1001 ,0 }; - static ulong[] dim803Kuo3Init = { 1 , 1 , 7 , 9 , 21 , 7 , 101 , 17 , 13 , 615 , 137 , 1821 , 1387 ,0 }; - static ulong[] dim804Kuo3Init = { 1 , 3 , 3 , 11 , 21 , 27 , 61 , 133 , 183 , 699 , 245 , 527 , 471 ,0 }; - static ulong[] dim805Kuo3Init = { 1 , 3 , 3 , 13 , 5 , 25 , 111 , 69 , 417 , 271 , 1545 , 2729 , 475 ,0 }; - static ulong[] dim806Kuo3Init = { 1 , 3 , 5 , 15 , 11 , 47 , 93 , 93 , 311 , 775 , 789 , 1163 , 1563 ,0 }; - static ulong[] dim807Kuo3Init = { 1 , 3 , 5 , 1 , 13 , 63 , 27 , 113 , 449 , 971 , 1021 , 73 , 1229 ,0 }; - static ulong[] dim808Kuo3Init = { 1 , 3 , 3 , 15 , 17 , 37 , 103 , 13 , 91 , 823 , 1767 , 1295 , 6941 ,0 }; - static ulong[] dim809Kuo3Init = { 1 , 1 , 3 , 9 , 15 , 59 , 125 , 91 , 195 , 409 , 65 , 2873 , 1921 ,0 }; - static ulong[] dim810Kuo3Init = { 1 , 3 , 1 , 7 , 17 , 31 , 21 , 251 , 145 , 385 , 1385 , 1505 , 5735 ,0 }; - static ulong[] dim811Kuo3Init = { 1 , 3 , 7 , 11 , 17 , 19 , 85 , 85 , 81 , 583 , 889 , 669 , 5187 ,0 }; - static ulong[] dim812Kuo3Init = { 1 , 1 , 5 , 9 , 23 , 53 , 97 , 217 , 129 , 517 , 271 , 2967 , 3937 ,0 }; - static ulong[] dim813Kuo3Init = { 1 , 1 , 1 , 13 , 3 , 45 , 49 , 193 , 35 , 671 , 1039 , 2841 , 4547 ,0 }; - static ulong[] dim814Kuo3Init = { 1 , 3 , 1 , 15 , 21 , 29 , 5 , 91 , 23 , 247 , 1701 , 1585 , 1493 ,0 }; - static ulong[] dim815Kuo3Init = { 1 , 3 , 3 , 11 , 15 , 31 , 21 , 165 , 153 , 607 , 221 , 2781 , 6159 ,0 }; - static ulong[] dim816Kuo3Init = { 1 , 3 , 7 , 15 , 15 , 27 , 107 , 25 , 457 , 995 , 849 , 877 , 407 ,0 }; - static ulong[] dim817Kuo3Init = { 1 , 3 , 1 , 15 , 7 , 17 , 37 , 31 , 203 , 585 , 369 , 609 , 2509 ,0 }; - static ulong[] dim818Kuo3Init = { 1 , 3 , 1 , 11 , 17 , 5 , 17 , 71 , 453 , 171 , 1317 , 1985 , 5817 ,0 }; - static ulong[] dim819Kuo3Init = { 1 , 1 , 5 , 5 , 23 , 39 , 123 , 179 , 49 , 19 , 1337 , 1051 , 5289 ,0 }; - static ulong[] dim820Kuo3Init = { 1 , 3 , 1 , 13 , 17 , 43 , 47 , 139 , 21 , 851 , 1253 , 1939 , 299 ,0 }; - static ulong[] dim821Kuo3Init = { 1 , 1 , 7 , 1 , 3 , 35 , 57 , 115 , 481 , 653 , 1975 , 1319 , 5225 ,0 }; - static ulong[] dim822Kuo3Init = { 1 , 3 , 7 , 15 , 5 , 13 , 3 , 249 , 21 , 791 , 1349 , 1961 , 6975 ,0 }; - static ulong[] dim823Kuo3Init = { 1 , 1 , 5 , 11 , 17 , 3 , 97 , 103 , 201 , 313 , 939 , 693 , 5397 ,0 }; - static ulong[] dim824Kuo3Init = { 1 , 1 , 7 , 9 , 29 , 59 , 35 , 91 , 135 , 19 , 1505 , 1715 , 3335 ,0 }; - static ulong[] dim825Kuo3Init = { 1 , 3 , 5 , 1 , 17 , 53 , 59 , 217 , 1 , 305 , 1257 , 3773 , 3509 ,0 }; - static ulong[] dim826Kuo3Init = { 1 , 3 , 7 , 7 , 5 , 29 , 47 , 245 , 487 , 525 , 1409 , 245 , 6427 ,0 }; - static ulong[] dim827Kuo3Init = { 1 , 3 , 5 , 15 , 25 , 39 , 49 , 153 , 461 , 1003 , 1527 , 2883 , 3499 ,0 }; - static ulong[] dim828Kuo3Init = { 1 , 1 , 7 , 13 , 23 , 11 , 15 , 163 , 9 , 77 , 1853 , 1679 , 1023 ,0 }; - static ulong[] dim829Kuo3Init = { 1 , 3 , 7 , 13 , 3 , 55 , 101 , 229 , 327 , 537 , 79 , 3947 , 6259 ,0 }; - static ulong[] dim830Kuo3Init = { 1 , 3 , 7 , 5 , 9 , 39 , 3 , 151 , 439 , 181 , 1473 , 3613 , 7425 ,0 }; - static ulong[] dim831Kuo3Init = { 1 , 3 , 7 , 11 , 21 , 5 , 53 , 11 , 39 , 455 , 1131 , 393 , 1525 ,0 }; - static ulong[] dim832Kuo3Init = { 1 , 1 , 1 , 7 , 5 , 45 , 49 , 229 , 173 , 567 , 1285 , 2317 , 2207 ,0 }; - static ulong[] dim833Kuo3Init = { 1 , 1 , 1 , 7 , 5 , 33 , 53 , 241 , 477 , 161 , 1607 , 1253 , 4497 ,0 }; - static ulong[] dim834Kuo3Init = { 1 , 1 , 7 , 15 , 11 , 3 , 107 , 187 , 249 , 529 , 905 , 2883 , 7777 ,0 }; - static ulong[] dim835Kuo3Init = { 1 , 1 , 5 , 7 , 17 , 13 , 123 , 7 , 449 , 627 , 1679 , 569 , 4145 ,0 }; - static ulong[] dim836Kuo3Init = { 1 , 1 , 1 , 1 , 3 , 29 , 57 , 219 , 209 , 51 , 1475 , 2989 , 7373 ,0 }; - static ulong[] dim837Kuo3Init = { 1 , 3 , 3 , 5 , 19 , 33 , 95 , 241 , 257 , 465 , 1305 , 189 , 269 ,0 }; - static ulong[] dim838Kuo3Init = { 1 , 1 , 3 , 1 , 13 , 11 , 67 , 53 , 157 , 693 , 1583 , 739 , 3827 ,0 }; - static ulong[] dim839Kuo3Init = { 1 , 1 , 3 , 9 , 17 , 9 , 5 , 7 , 421 , 425 , 1851 , 3847 , 5147 ,0 }; - static ulong[] dim840Kuo3Init = { 1 , 1 , 3 , 3 , 23 , 47 , 123 , 215 , 11 , 643 , 1543 , 1859 , 4073 ,0 }; - static ulong[] dim841Kuo3Init = { 1 , 1 , 1 , 11 , 5 , 35 , 79 , 55 , 225 , 773 , 1717 , 2891 , 563 ,0 }; - static ulong[] dim842Kuo3Init = { 1 , 1 , 1 , 15 , 5 , 17 , 115 , 3 , 107 , 33 , 1897 , 3677 , 4313 ,0 }; - static ulong[] dim843Kuo3Init = { 1 , 1 , 5 , 7 , 5 , 57 , 75 , 65 , 177 , 269 , 733 , 3837 , 1211 ,0 }; - static ulong[] dim844Kuo3Init = { 1 , 1 , 5 , 15 , 25 , 45 , 125 , 159 , 501 , 17 , 693 , 1083 , 1801 ,0 }; - static ulong[] dim845Kuo3Init = { 1 , 3 , 5 , 3 , 15 , 17 , 17 , 159 , 421 , 449 , 83 , 1367 , 7719 ,0 }; - static ulong[] dim846Kuo3Init = { 1 , 3 , 7 , 3 , 7 , 31 , 121 , 43 , 491 , 501 , 335 , 2731 , 1959 ,0 }; - static ulong[] dim847Kuo3Init = { 1 , 1 , 1 , 11 , 7 , 1 , 43 , 187 , 437 , 113 , 1205 , 1255 , 1319 ,0 }; - static ulong[] dim848Kuo3Init = { 1 , 1 , 5 , 15 , 15 , 49 , 103 , 139 , 187 , 697 , 907 , 1229 , 3205 ,0 }; - static ulong[] dim849Kuo3Init = { 1 , 1 , 5 , 13 , 9 , 19 , 25 , 89 , 345 , 229 , 1325 , 859 , 527 ,0 }; - static ulong[] dim850Kuo3Init = { 1 , 1 , 1 , 3 , 3 , 63 , 105 , 11 , 407 , 131 , 679 , 3069 , 4153 ,0 }; - static ulong[] dim851Kuo3Init = { 1 , 1 , 3 , 11 , 21 , 27 , 113 , 59 , 409 , 845 , 309 , 2639 , 129 ,0 }; - static ulong[] dim852Kuo3Init = { 1 , 1 , 5 , 15 , 21 , 47 , 55 , 237 , 201 , 103 , 331 , 3531 , 4965 ,0 }; - static ulong[] dim853Kuo3Init = { 1 , 1 , 5 , 11 , 9 , 11 , 85 , 49 , 209 , 333 , 1993 , 511 , 7347 ,0 }; - static ulong[] dim854Kuo3Init = { 1 , 1 , 5 , 13 , 25 , 49 , 109 , 241 , 297 , 677 , 313 , 657 , 4503 ,0 }; - static ulong[] dim855Kuo3Init = { 1 , 1 , 1 , 15 , 23 , 57 , 61 , 117 , 461 , 559 , 837 , 2781 , 709 ,0 }; - static ulong[] dim856Kuo3Init = { 1 , 1 , 3 , 3 , 31 , 13 , 109 , 167 , 389 , 1021 , 1437 , 31 , 811 ,0 }; - static ulong[] dim857Kuo3Init = { 1 , 1 , 1 , 9 , 21 , 17 , 19 , 61 , 241 , 445 , 1935 , 3161 , 4061 ,0 }; - static ulong[] dim858Kuo3Init = { 1 , 3 , 5 , 5 , 17 , 5 , 59 , 117 , 241 , 913 , 1315 , 1597 , 713 ,0 }; - static ulong[] dim859Kuo3Init = { 1 , 3 , 1 , 15 , 5 , 41 , 91 , 191 , 43 , 49 , 1491 , 4051 , 2317 ,0 }; - static ulong[] dim860Kuo3Init = { 1 , 1 , 1 , 3 , 13 , 33 , 53 , 39 , 341 , 341 , 617 , 2627 , 421 ,0 }; - static ulong[] dim861Kuo3Init = { 1 , 3 , 3 , 15 , 23 , 25 , 47 , 251 , 405 , 659 , 721 , 229 , 2269 ,0 }; - static ulong[] dim862Kuo3Init = { 1 , 1 , 3 , 3 , 25 , 19 , 123 , 53 , 59 , 805 , 2033 , 1693 , 6223 ,0 }; - static ulong[] dim863Kuo3Init = { 1 , 1 , 1 , 3 , 13 , 45 , 67 , 67 , 199 , 925 , 145 , 775 , 7923 ,0 }; - static ulong[] dim864Kuo3Init = { 1 , 1 , 5 , 7 , 17 , 23 , 49 , 37 , 185 , 253 , 1743 , 2771 , 6899 ,0 }; - static ulong[] dim865Kuo3Init = { 1 , 3 , 5 , 5 , 15 , 53 , 75 , 185 , 17 , 379 , 1091 , 4029 , 5399 ,0 }; - static ulong[] dim866Kuo3Init = { 1 , 1 , 1 , 9 , 13 , 37 , 101 , 33 , 499 , 723 , 57 , 467 , 7227 ,0 }; - static ulong[] dim867Kuo3Init = { 1 , 1 , 7 , 1 , 21 , 49 , 17 , 49 , 417 , 895 , 1099 , 3199 , 7059 ,0 }; - static ulong[] dim868Kuo3Init = { 1 , 1 , 5 , 13 , 27 , 35 , 49 , 35 , 213 , 799 , 197 , 3599 , 4135 ,0 }; - static ulong[] dim869Kuo3Init = { 1 , 3 , 5 , 3 , 31 , 33 , 61 , 127 , 87 , 343 , 845 , 1699 , 3897 ,0 }; - static ulong[] dim870Kuo3Init = { 1 , 3 , 1 , 11 , 7 , 59 , 19 , 161 , 119 , 377 , 1637 , 2025 , 849 ,0 }; - static ulong[] dim871Kuo3Init = { 1 , 1 , 3 , 3 , 3 , 51 , 3 , 67 , 77 , 357 , 295 , 2383 , 7423 ,0 }; - static ulong[] dim872Kuo3Init = { 1 , 3 , 1 , 3 , 23 , 25 , 67 , 29 , 433 , 49 , 901 , 1641 , 3021 ,0 }; - static ulong[] dim873Kuo3Init = { 1 , 3 , 7 , 3 , 25 , 59 , 15 , 181 , 193 , 809 , 1089 , 423 , 1629 ,0 }; - static ulong[] dim874Kuo3Init = { 1 , 3 , 5 , 1 , 3 , 19 , 53 , 45 , 277 , 411 , 455 , 9 , 3651 ,0 }; - static ulong[] dim875Kuo3Init = { 1 , 3 , 7 , 15 , 13 , 33 , 37 , 15 , 489 , 275 , 1113 , 3371 , 3915 ,0 }; - static ulong[] dim876Kuo3Init = { 1 , 1 , 5 , 11 , 3 , 3 , 97 , 47 , 471 , 713 , 1975 , 1679 , 7901 ,0 }; - static ulong[] dim877Kuo3Init = { 1 , 1 , 3 , 15 , 31 , 47 , 13 , 33 , 111 , 607 , 85 , 4049 , 2937 ,0 }; - static ulong[] dim878Kuo3Init = { 1 , 1 , 5 , 1 , 7 , 61 , 17 , 179 , 301 , 245 , 67 , 2823 , 4121 ,0 }; - static ulong[] dim879Kuo3Init = { 1 , 3 , 7 , 15 , 7 , 25 , 97 , 73 , 19 , 899 , 1357 , 2041 , 6493 ,0 }; - static ulong[] dim880Kuo3Init = { 1 , 1 , 1 , 3 , 3 , 63 , 117 , 231 , 125 , 527 , 1795 , 1807 , 7331 ,0 }; - static ulong[] dim881Kuo3Init = { 1 , 1 , 5 , 11 , 17 , 35 , 61 , 161 , 415 , 687 , 1015 , 1239 , 6925 ,0 }; - static ulong[] dim882Kuo3Init = { 1 , 3 , 3 , 5 , 15 , 19 , 1 , 5 , 209 , 545 , 1341 , 4019 , 6177 ,0 }; - static ulong[] dim883Kuo3Init = { 1 , 3 , 5 , 15 , 13 , 3 , 7 , 39 , 63 , 727 , 1033 , 2551 , 449 ,0 }; - static ulong[] dim884Kuo3Init = { 1 , 1 , 1 , 5 , 11 , 35 , 39 , 143 , 361 , 659 , 1407 , 2399 , 6421 ,0 }; - static ulong[] dim885Kuo3Init = { 1 , 1 , 7 , 13 , 3 , 23 , 21 , 161 , 153 , 595 , 1847 , 1339 , 1887 ,0 }; - static ulong[] dim886Kuo3Init = { 1 , 3 , 3 , 9 , 3 , 43 , 75 , 45 , 433 , 811 , 1045 , 2773 , 2415 ,0 }; - static ulong[] dim887Kuo3Init = { 1 , 1 , 3 , 5 , 23 , 29 , 73 , 167 , 211 , 403 , 539 , 13 , 4433 ,0 }; - static ulong[] dim888Kuo3Init = { 1 , 3 , 3 , 13 , 19 , 25 , 113 , 181 , 343 , 349 , 931 , 115 , 5687 ,0 }; - static ulong[] dim889Kuo3Init = { 1 , 3 , 1 , 11 , 25 , 39 , 23 , 91 , 359 , 221 , 37 , 575 , 3035 ,0 }; - static ulong[] dim890Kuo3Init = { 1 , 1 , 7 , 1 , 19 , 61 , 99 , 81 , 167 , 53 , 1493 , 2623 , 5797 ,0 }; - static ulong[] dim891Kuo3Init = { 1 , 1 , 3 , 5 , 13 , 13 , 105 , 53 , 449 , 1003 , 1405 , 1403 , 2557 ,0 }; - static ulong[] dim892Kuo3Init = { 1 , 1 , 3 , 15 , 1 , 37 , 51 , 69 , 13 , 5 , 1865 , 3585 , 3409 ,0 }; - static ulong[] dim893Kuo3Init = { 1 , 1 , 7 , 13 , 15 , 31 , 61 , 53 , 439 , 665 , 57 , 445 , 435 ,0 }; - static ulong[] dim894Kuo3Init = { 1 , 3 , 1 , 3 , 1 , 27 , 1 , 155 , 65 , 191 , 449 , 2185 , 1787 ,0 }; - static ulong[] dim895Kuo3Init = { 1 , 1 , 3 , 11 , 13 , 59 , 15 , 43 , 435 , 477 , 823 , 717 , 299 ,0 }; - static ulong[] dim896Kuo3Init = { 1 , 1 , 3 , 1 , 23 , 9 , 85 , 155 , 127 , 543 , 1081 , 221 , 7357 ,0 }; - static ulong[] dim897Kuo3Init = { 1 , 3 , 3 , 1 , 7 , 35 , 77 , 9 , 79 , 283 , 449 , 2729 , 4193 ,0 }; - static ulong[] dim898Kuo3Init = { 1 , 1 , 7 , 1 , 9 , 15 , 97 , 99 , 363 , 513 , 1063 , 3051 , 1529 ,0 }; - static ulong[] dim899Kuo3Init = { 1 , 1 , 5 , 3 , 1 , 17 , 101 , 19 , 425 , 377 , 1369 , 3071 , 6877 ,0 }; - static ulong[] dim900Kuo3Init = { 1 , 1 , 5 , 1 , 23 , 63 , 11 , 7 , 29 , 717 , 963 , 2205 , 7487 ,0 }; - static ulong[] dim901Kuo3Init = { 1 , 3 , 1 , 13 , 1 , 15 , 43 , 151 , 59 , 315 , 691 , 2765 , 7723 ,0 }; - static ulong[] dim902Kuo3Init = { 1 , 3 , 1 , 5 , 5 , 31 , 17 , 81 , 235 , 419 , 123 , 2983 , 1797 ,0 }; - static ulong[] dim903Kuo3Init = { 1 , 1 , 1 , 11 , 29 , 17 , 123 , 115 , 91 , 531 , 1393 , 3537 , 6387 ,0 }; - static ulong[] dim904Kuo3Init = { 1 , 3 , 5 , 11 , 31 , 5 , 107 , 61 , 463 , 507 , 1937 , 4075 , 4727 ,0 }; - static ulong[] dim905Kuo3Init = { 1 , 3 , 7 , 1 , 9 , 27 , 23 , 97 , 125 , 511 , 239 , 1031 , 153 ,0 }; - static ulong[] dim906Kuo3Init = { 1 , 3 , 5 , 9 , 13 , 55 , 53 , 195 , 265 , 217 , 357 , 567 , 1613 ,0 }; - static ulong[] dim907Kuo3Init = { 1 , 1 , 5 , 15 , 5 , 51 , 51 , 235 , 63 , 393 , 1915 , 2495 , 7067 ,0 }; - static ulong[] dim908Kuo3Init = { 1 , 1 , 7 , 1 , 15 , 35 , 97 , 65 , 115 , 819 , 1419 , 2313 , 6029 ,0 }; - static ulong[] dim909Kuo3Init = { 1 , 1 , 5 , 13 , 11 , 35 , 45 , 149 , 45 , 617 , 2001 , 1629 , 5611 ,0 }; - static ulong[] dim910Kuo3Init = { 1 , 3 , 5 , 11 , 15 , 17 , 39 , 155 , 143 , 473 , 1269 , 2537 , 2571 ,0 }; - static ulong[] dim911Kuo3Init = { 1 , 1 , 3 , 3 , 1 , 7 , 57 , 227 , 151 , 731 , 1871 , 245 , 7605 ,0 }; - static ulong[] dim912Kuo3Init = { 1 , 1 , 1 , 13 , 21 , 1 , 19 , 189 , 299 , 483 , 513 , 2235 , 3079 ,0 }; - static ulong[] dim913Kuo3Init = { 1 , 1 , 5 , 15 , 13 , 53 , 91 , 55 , 339 , 161 , 273 , 2759 , 7251 ,0 }; - static ulong[] dim914Kuo3Init = { 1 , 3 , 1 , 1 , 17 , 47 , 29 , 107 , 371 , 437 , 715 , 739 , 2195 ,0 }; - static ulong[] dim915Kuo3Init = { 1 , 3 , 5 , 11 , 27 , 1 , 35 , 105 , 443 , 623 , 1401 , 2683 , 4327 ,0 }; - static ulong[] dim916Kuo3Init = { 1 , 1 , 5 , 7 , 13 , 23 , 101 , 235 , 369 , 951 , 1983 , 1021 , 7835 ,0 }; - static ulong[] dim917Kuo3Init = { 1 , 1 , 1 , 5 , 21 , 57 , 45 , 67 , 89 , 209 , 1105 , 2161 , 2245 ,0 }; - static ulong[] dim918Kuo3Init = { 1 , 1 , 7 , 15 , 7 , 33 , 69 , 129 , 181 , 231 , 961 , 1621 , 7763 ,0 }; - static ulong[] dim919Kuo3Init = { 1 , 3 , 1 , 5 , 1 , 31 , 105 , 123 , 413 , 989 , 1311 , 199 , 5175 ,0 }; - static ulong[] dim920Kuo3Init = { 1 , 3 , 5 , 13 , 15 , 9 , 123 , 215 , 463 , 197 , 537 , 531 , 2331 ,0 }; - static ulong[] dim921Kuo3Init = { 1 , 1 , 3 , 13 , 13 , 45 , 61 , 189 , 91 , 445 , 1719 , 3335 , 5269 ,0 }; - static ulong[] dim922Kuo3Init = { 1 , 3 , 1 , 11 , 19 , 41 , 65 , 143 , 199 , 177 , 1695 , 3647 , 7169 ,0 }; - static ulong[] dim923Kuo3Init = { 1 , 1 , 3 , 13 , 13 , 25 , 37 , 89 , 175 , 551 , 1535 , 1401 , 1823 ,0 }; - static ulong[] dim924Kuo3Init = { 1 , 3 , 3 , 1 , 21 , 15 , 31 , 101 , 329 , 907 , 731 , 1493 , 451 ,0 }; - static ulong[] dim925Kuo3Init = { 1 , 1 , 3 , 9 , 5 , 61 , 85 , 247 , 289 , 547 , 1031 , 3567 , 1769 ,0 }; - static ulong[] dim926Kuo3Init = { 1 , 3 , 1 , 7 , 25 , 35 , 99 , 43 , 25 , 855 , 1451 , 617 , 2615 ,0 }; - static ulong[] dim927Kuo3Init = { 1 , 1 , 1 , 7 , 25 , 9 , 77 , 39 , 127 , 327 , 1501 , 57 , 1485 ,0 }; - static ulong[] dim928Kuo3Init = { 1 , 3 , 5 , 5 , 9 , 13 , 13 , 239 , 125 , 473 , 785 , 2853 , 5165 ,0 }; - static ulong[] dim929Kuo3Init = { 1 , 1 , 1 , 3 , 27 , 43 , 117 , 63 , 175 , 487 , 1505 , 157 , 6043 ,0 }; - static ulong[] dim930Kuo3Init = { 1 , 1 , 5 , 5 , 25 , 43 , 97 , 231 , 389 , 191 , 1795 , 2659 , 7409 ,0 }; - static ulong[] dim931Kuo3Init = { 1 , 1 , 7 , 7 , 11 , 25 , 47 , 131 , 363 , 311 , 523 , 2773 , 8015 ,0 }; - static ulong[] dim932Kuo3Init = { 1 , 1 , 5 , 11 , 25 , 61 , 123 , 83 , 265 , 995 , 613 , 1893 , 6341 ,0 }; - static ulong[] dim933Kuo3Init = { 1 , 1 , 3 , 3 , 27 , 45 , 41 , 143 , 173 , 1009 , 1963 , 4009 , 3675 ,0 }; - static ulong[] dim934Kuo3Init = { 1 , 3 , 3 , 9 , 5 , 11 , 95 , 253 , 415 , 307 , 501 , 3117 , 4621 ,0 }; - static ulong[] dim935Kuo3Init = { 1 , 3 , 5 , 1 , 31 , 41 , 95 , 39 , 473 , 565 , 1389 , 4049 , 5673 ,0 }; - static ulong[] dim936Kuo3Init = { 1 , 1 , 3 , 11 , 3 , 13 , 87 , 101 , 413 , 769 , 1223 , 549 , 4967 ,0 }; - static ulong[] dim937Kuo3Init = { 1 , 3 , 1 , 3 , 13 , 41 , 29 , 187 , 491 , 197 , 1685 , 3859 , 3799 ,0 }; - static ulong[] dim938Kuo3Init = { 1 , 3 , 1 , 3 , 17 , 55 , 91 , 131 , 429 , 899 , 29 , 1193 , 7323 ,0 }; - static ulong[] dim939Kuo3Init = { 1 , 1 , 3 , 1 , 11 , 17 , 107 , 113 , 71 , 185 , 1057 , 897 , 249 ,0 }; - static ulong[] dim940Kuo3Init = { 1 , 1 , 3 , 5 , 29 , 27 , 87 , 33 , 273 , 405 , 547 , 763 , 2195 ,0 }; - static ulong[] dim941Kuo3Init = { 1 , 3 , 1 , 11 , 7 , 43 , 39 , 103 , 475 , 515 , 1105 , 767 , 3881 ,0 }; - static ulong[] dim942Kuo3Init = { 1 , 3 , 3 , 1 , 13 , 21 , 93 , 141 , 407 , 1001 , 1939 , 2747 , 6479 ,0 }; - static ulong[] dim943Kuo3Init = { 1 , 3 , 1 , 15 , 1 , 31 , 15 , 69 , 313 , 547 , 987 , 3569 , 2795 ,0 }; - static ulong[] dim944Kuo3Init = { 1 , 3 , 5 , 7 , 1 , 17 , 105 , 113 , 253 , 453 , 1219 , 2769 , 197 ,0 }; - static ulong[] dim945Kuo3Init = { 1 , 3 , 7 , 7 , 29 , 55 , 77 , 169 , 227 , 471 , 1385 , 2689 , 7995 ,0 }; - static ulong[] dim946Kuo3Init = { 1 , 3 , 7 , 15 , 7 , 15 , 113 , 133 , 205 , 271 , 263 , 3141 , 5007 ,0 }; - static ulong[] dim947Kuo3Init = { 1 , 1 , 5 , 7 , 7 , 57 , 121 , 209 , 319 , 733 , 1689 , 2817 , 6621 ,0 }; - static ulong[] dim948Kuo3Init = { 1 , 3 , 7 , 9 , 23 , 37 , 101 , 229 , 269 , 429 , 157 , 515 , 6975 ,0 }; - static ulong[] dim949Kuo3Init = { 1 , 1 , 7 , 7 , 23 , 31 , 83 , 237 , 299 , 333 , 959 , 1467 , 419 ,0 }; - static ulong[] dim950Kuo3Init = { 1 , 3 , 7 , 3 , 23 , 45 , 17 , 33 , 293 , 679 , 625 , 3651 , 4205 ,0 }; - static ulong[] dim951Kuo3Init = { 1 , 3 , 1 , 13 , 17 , 19 , 87 , 237 , 219 , 119 , 841 , 1923 , 8141 ,0 }; - static ulong[] dim952Kuo3Init = { 1 , 1 , 1 , 15 , 15 , 49 , 21 , 189 , 287 , 759 , 695 , 913 , 5167 ,0 }; - static ulong[] dim953Kuo3Init = { 1 , 1 , 3 , 15 , 1 , 9 , 125 , 5 , 67 , 603 , 1691 , 2863 , 1299 ,0 }; - static ulong[] dim954Kuo3Init = { 1 , 3 , 7 , 3 , 5 , 35 , 105 , 27 , 51 , 889 , 1469 , 3203 , 6997 ,0 }; - static ulong[] dim955Kuo3Init = { 1 , 3 , 5 , 7 , 1 , 53 , 77 , 1 , 313 , 475 , 1515 , 2233 , 399 ,0 }; - static ulong[] dim956Kuo3Init = { 1 , 3 , 5 , 7 , 3 , 31 , 43 , 17 , 425 , 673 , 1817 , 1939 , 8027 ,0 }; - static ulong[] dim957Kuo3Init = { 1 , 1 , 5 , 5 , 31 , 31 , 119 , 179 , 157 , 635 , 1 , 315 , 1179 ,0 }; - static ulong[] dim958Kuo3Init = { 1 , 1 , 5 , 5 , 1 , 7 , 25 , 15 , 311 , 489 , 829 , 1929 , 623 ,0 }; - static ulong[] dim959Kuo3Init = { 1 , 1 , 5 , 11 , 1 , 17 , 43 , 205 , 347 , 713 , 2029 , 977 , 4345 ,0 }; - static ulong[] dim960Kuo3Init = { 1 , 1 , 3 , 9 , 17 , 3 , 109 , 253 , 427 , 333 , 203 , 1609 , 1851 ,0 }; - static ulong[] dim961Kuo3Init = { 1 , 3 , 1 , 9 , 21 , 55 , 107 , 203 , 483 , 869 , 1417 , 587 , 3965 ,0 }; - static ulong[] dim962Kuo3Init = { 1 , 3 , 3 , 13 , 27 , 21 , 103 , 109 , 313 , 797 , 723 , 683 , 349 ,0 }; - static ulong[] dim963Kuo3Init = { 1 , 3 , 5 , 3 , 1 , 35 , 43 , 19 , 367 , 487 , 703 , 2211 , 1199 ,0 }; - static ulong[] dim964Kuo3Init = { 1 , 3 , 1 , 3 , 19 , 33 , 13 , 135 , 329 , 621 , 843 , 407 , 6523 ,0 }; - static ulong[] dim965Kuo3Init = { 1 , 1 , 7 , 5 , 13 , 1 , 45 , 133 , 27 , 267 , 1975 , 2761 , 5061 ,0 }; - static ulong[] dim966Kuo3Init = { 1 , 1 , 3 , 3 , 19 , 59 , 13 , 35 , 489 , 391 , 1595 , 2983 , 3203 ,0 }; - static ulong[] dim967Kuo3Init = { 1 , 3 , 3 , 7 , 19 , 27 , 125 , 55 , 121 , 733 , 1437 , 51 , 4029 ,0 }; - static ulong[] dim968Kuo3Init = { 1 , 3 , 1 , 15 , 11 , 7 , 73 , 187 , 209 , 127 , 1259 , 1733 , 1897 ,0 }; - static ulong[] dim969Kuo3Init = { 1 , 3 , 7 , 1 , 27 , 19 , 87 , 189 , 91 , 113 , 237 , 2073 , 419 ,0 }; - static ulong[] dim970Kuo3Init = { 1 , 3 , 5 , 3 , 15 , 27 , 107 , 77 , 467 , 953 , 1317 , 877 , 6911 ,0 }; - static ulong[] dim971Kuo3Init = { 1 , 3 , 7 , 13 , 7 , 17 , 107 , 157 , 439 , 871 , 651 , 797 , 2095 ,0 }; - static ulong[] dim972Kuo3Init = { 1 , 1 , 3 , 9 , 13 , 19 , 19 , 75 , 13 , 267 , 435 , 1067 , 6603 ,0 }; - static ulong[] dim973Kuo3Init = { 1 , 1 , 7 , 13 , 25 , 7 , 81 , 207 , 149 , 587 , 1561 , 2025 , 2355 ,0 }; - static ulong[] dim974Kuo3Init = { 1 , 3 , 3 , 5 , 25 , 25 , 79 , 249 , 371 , 305 , 305 , 53 , 1051 ,0 }; - static ulong[] dim975Kuo3Init = { 1 , 1 , 3 , 9 , 19 , 63 , 57 , 237 , 39 , 349 , 1163 , 2443 , 1739 ,0 }; - static ulong[] dim976Kuo3Init = { 1 , 1 , 5 , 5 , 23 , 57 , 61 , 21 , 115 , 107 , 303 , 1451 , 2955 ,0 }; - static ulong[] dim977Kuo3Init = { 1 , 3 , 1 , 3 , 17 , 19 , 121 , 123 , 25 , 367 , 963 , 545 , 2885 ,0 }; - static ulong[] dim978Kuo3Init = { 1 , 3 , 3 , 5 , 15 , 57 , 123 , 1 , 193 , 861 , 1001 , 1457 , 4977 ,0 }; - static ulong[] dim979Kuo3Init = { 1 , 3 , 5 , 9 , 21 , 31 , 37 , 83 , 361 , 491 , 1933 , 407 , 1923 ,0 }; - static ulong[] dim980Kuo3Init = { 1 , 3 , 7 , 5 , 9 , 47 , 33 , 43 , 239 , 837 , 799 , 3731 , 5883 ,0 }; - static ulong[] dim981Kuo3Init = { 1 , 3 , 5 , 5 , 7 , 39 , 49 , 201 , 339 , 783 , 1937 , 1473 , 391 ,0 }; - static ulong[] dim982Kuo3Init = { 1 , 3 , 5 , 13 , 3 , 63 , 39 , 91 , 63 , 645 , 929 , 1543 , 577 ,0 }; - static ulong[] dim983Kuo3Init = { 1 , 3 , 3 , 3 , 9 , 59 , 107 , 129 , 455 , 259 , 1523 , 107 , 285 ,0 }; - static ulong[] dim984Kuo3Init = { 1 , 1 , 3 , 9 , 23 , 21 , 89 , 13 , 413 , 87 , 1703 , 1611 , 5667 ,0 }; - static ulong[] dim985Kuo3Init = { 1 , 1 , 3 , 9 , 21 , 9 , 83 , 187 , 159 , 757 , 1111 , 3619 , 3907 ,0 }; - static ulong[] dim986Kuo3Init = { 1 , 3 , 3 , 9 , 21 , 35 , 27 , 57 , 357 , 659 , 1243 , 2725 , 5769 ,0 }; - static ulong[] dim987Kuo3Init = { 1 , 1 , 7 , 1 , 3 , 7 , 75 , 145 , 119 , 1019 , 1169 , 953 , 2343 ,0 }; - static ulong[] dim988Kuo3Init = { 1 , 3 , 3 , 11 , 19 , 15 , 121 , 135 , 187 , 569 , 671 , 131 , 479 ,0 }; - static ulong[] dim989Kuo3Init = { 1 , 3 , 5 , 1 , 21 , 27 , 63 , 187 , 367 , 181 , 1885 , 2513 , 4499 ,0 }; - static ulong[] dim990Kuo3Init = { 1 , 3 , 3 , 5 , 27 , 13 , 107 , 183 , 345 , 855 , 123 , 1491 , 867 ,0 }; - static ulong[] dim991Kuo3Init = { 1 , 3 , 7 , 9 , 5 , 41 , 43 , 47 , 277 , 657 , 1227 , 2265 , 1777 ,0 }; - static ulong[] dim992Kuo3Init = { 1 , 1 , 5 , 5 , 31 , 37 , 119 , 5 , 395 , 399 , 787 , 2869 , 829 ,0 }; - static ulong[] dim993Kuo3Init = { 1 , 1 , 1 , 5 , 3 , 55 , 43 , 117 , 191 , 577 , 1185 , 3407 , 4673 ,0 }; - static ulong[] dim994Kuo3Init = { 1 , 3 , 5 , 11 , 15 , 63 , 103 , 127 , 505 , 53 , 297 , 3411 , 3919 ,0 }; - static ulong[] dim995Kuo3Init = { 1 , 3 , 7 , 13 , 15 , 57 , 45 , 17 , 253 , 261 , 767 , 1951 , 6599 ,0 }; - static ulong[] dim996Kuo3Init = { 1 , 3 , 1 , 13 , 3 , 55 , 11 , 113 , 223 , 403 , 249 , 633 , 3265 ,0 }; - static ulong[] dim997Kuo3Init = { 1 , 1 , 1 , 5 , 7 , 49 , 47 , 47 , 467 , 633 , 1991 , 361 , 8099 ,0 }; - static ulong[] dim998Kuo3Init = { 1 , 1 , 3 , 5 , 31 , 45 , 87 , 117 , 483 , 331 , 687 , 3393 , 7377 ,0 }; - static ulong[] dim999Kuo3Init = { 1 , 1 , 7 , 9 , 29 , 3 , 11 , 147 , 147 , 631 , 1131 , 2651 , 3141 ,0 }; - static ulong[] dim1000Kuo3Init = { 1 , 3 , 7 , 9 , 27 , 49 , 41 , 207 , 305 , 403 , 889 , 2947 , 5775 ,0 }; - static ulong[] dim1001Kuo3Init = { 1 , 3 , 1 , 13 , 1 , 63 , 25 , 127 , 401 , 375 , 727 , 2375 , 2945 ,0 }; - static ulong[] dim1002Kuo3Init = { 1 , 3 , 3 , 15 , 7 , 19 , 65 , 29 , 383 , 809 , 279 , 2081 , 1993 ,0 }; - static ulong[] dim1003Kuo3Init = { 1 , 1 , 7 , 7 , 29 , 9 , 39 , 159 , 457 , 435 , 947 , 2309 , 2219 ,0 }; - static ulong[] dim1004Kuo3Init = { 1 , 1 , 1 , 11 , 15 , 31 , 51 , 147 , 167 , 113 , 145 , 125 , 6997 ,0 }; - static ulong[] dim1005Kuo3Init = { 1 , 1 , 5 , 1 , 27 , 21 , 123 , 249 , 21 , 487 , 331 , 35 , 3101 ,0 }; - static ulong[] dim1006Kuo3Init = { 1 , 3 , 7 , 3 , 5 , 7 , 127 , 173 , 115 , 607 , 1061 , 2923 , 6869 ,0 }; - static ulong[] dim1007Kuo3Init = { 1 , 3 , 1 , 5 , 17 , 55 , 13 , 15 , 95 , 365 , 1419 , 1111 , 7561 ,0 }; - static ulong[] dim1008Kuo3Init = { 1 , 3 , 3 , 15 , 23 , 45 , 115 , 123 , 477 , 335 , 85 , 431 , 6893 ,0 }; - static ulong[] dim1009Kuo3Init = { 1 , 1 , 5 , 1 , 5 , 49 , 95 , 19 , 429 , 549 , 713 , 661 , 167 ,0 }; - static ulong[] dim1010Kuo3Init = { 1 , 1 , 3 , 15 , 3 , 13 , 127 , 189 , 385 , 649 , 67 , 499 , 5355 ,0 }; - static ulong[] dim1011Kuo3Init = { 1 , 1 , 1 , 5 , 9 , 31 , 17 , 21 , 419 , 655 , 287 , 1173 , 1023 ,0 }; - static ulong[] dim1012Kuo3Init = { 1 , 1 , 5 , 1 , 17 , 11 , 19 , 17 , 195 , 1015 , 1621 , 1197 , 3497 ,0 }; - static ulong[] dim1013Kuo3Init = { 1 , 3 , 1 , 5 , 29 , 55 , 85 , 43 , 381 , 59 , 149 , 391 , 2109 ,0 }; - static ulong[] dim1014Kuo3Init = { 1 , 1 , 7 , 9 , 11 , 43 , 115 , 57 , 211 , 463 , 787 , 3665 , 5619 ,0 }; - static ulong[] dim1015Kuo3Init = { 1 , 3 , 1 , 7 , 23 , 5 , 55 , 93 , 117 , 925 , 941 , 91 , 6221 ,0 }; - static ulong[] dim1016Kuo3Init = { 1 , 1 , 1 , 13 , 29 , 35 , 89 , 7 , 75 , 759 , 735 , 3011 , 1279 ,0 }; - static ulong[] dim1017Kuo3Init = { 1 , 1 , 1 , 15 , 13 , 17 , 13 , 175 , 167 , 965 , 1069 , 2215 , 6065 ,0 }; - static ulong[] dim1018Kuo3Init = { 1 , 1 , 3 , 15 , 1 , 11 , 109 , 205 , 501 , 419 , 1071 , 543 , 5377 ,0 }; - static ulong[] dim1019Kuo3Init = { 1 , 1 , 3 , 5 , 11 , 1 , 123 , 147 , 87 , 289 , 325 , 3693 , 4939 ,0 }; - static ulong[] dim1020Kuo3Init = { 1 , 1 , 3 , 1 , 9 , 21 , 29 , 215 , 365 , 995 , 1727 , 2515 , 5741 ,0 }; - static ulong[] dim1021Kuo3Init = { 1 , 1 , 3 , 5 , 3 , 7 , 5 , 147 , 413 , 505 , 661 , 3071 , 2521 ,0 }; - static ulong[] dim1022Kuo3Init = { 1 , 3 , 7 , 5 , 5 , 41 , 117 , 145 , 455 , 379 , 601 , 455 , 5377 ,0 }; - static ulong[] dim1023Kuo3Init = { 1 , 1 , 7 , 15 , 11 , 45 , 27 , 37 , 457 , 935 , 595 , 3883 , 1491 ,0 }; - static ulong[] dim1024Kuo3Init = { 1 , 3 , 5 , 9 , 15 , 7 , 49 , 95 , 225 , 837 , 805 , 2553 , 4891 ,0 }; - static ulong[] dim1025Kuo3Init = { 1 , 3 , 3 , 5 , 1 , 29 , 109 , 99 , 349 , 221 , 749 , 3499 , 4201 ,0 }; - static ulong[] dim1026Kuo3Init = { 1 , 1 , 1 , 11 , 27 , 35 , 47 , 253 , 151 , 129 , 927 , 4039 , 6133 ,0 }; - static ulong[] dim1027Kuo3Init = { 1 , 3 , 1 , 3 , 17 , 59 , 1 , 63 , 61 , 927 , 933 , 3645 , 3707 ,0 }; - static ulong[] dim1028Kuo3Init = { 1 , 3 , 1 , 3 , 29 , 33 , 45 , 59 , 183 , 459 , 903 , 747 , 1895 ,0 }; - static ulong[] dim1029Kuo3Init = { 1 , 1 , 5 , 3 , 19 , 53 , 71 , 199 , 91 , 807 , 507 , 3821 , 1815 ,0 }; - static ulong[] dim1030Kuo3Init = { 1 , 1 , 1 , 7 , 23 , 43 , 39 , 17 , 139 , 751 , 467 , 617 , 5237 ,0 }; - static ulong[] dim1031Kuo3Init = { 1 , 1 , 7 , 13 , 5 , 53 , 43 , 181 , 337 , 731 , 497 , 3189 , 4063 ,0 }; - static ulong[] dim1032Kuo3Init = { 1 , 1 , 7 , 9 , 1 , 45 , 103 , 151 , 265 , 897 , 1821 , 2957 , 5591 ,0 }; - static ulong[] dim1033Kuo3Init = { 1 , 3 , 7 , 5 , 13 , 43 , 65 , 49 , 233 , 1 , 1709 , 2641 , 5633 ,0 }; - static ulong[] dim1034Kuo3Init = { 1 , 1 , 1 , 7 , 15 , 15 , 95 , 223 , 447 , 967 , 1533 , 1969 , 6497 ,0 }; - static ulong[] dim1035Kuo3Init = { 1 , 1 , 7 , 9 , 29 , 5 , 55 , 57 , 377 , 487 , 443 , 2589 , 4735 ,0 }; - static ulong[] dim1036Kuo3Init = { 1 , 1 , 5 , 1 , 23 , 49 , 5 , 47 , 203 , 727 , 1955 , 3465 , 6691 ,0 }; - static ulong[] dim1037Kuo3Init = { 1 , 1 , 3 , 7 , 25 , 13 , 31 , 153 , 411 , 79 , 121 , 3815 , 2123 ,0 }; - static ulong[] dim1038Kuo3Init = { 1 , 1 , 3 , 1 , 3 , 57 , 11 , 141 , 465 , 713 , 659 , 2849 , 487 ,0 }; - static ulong[] dim1039Kuo3Init = { 1 , 3 , 7 , 5 , 29 , 49 , 91 , 249 , 353 , 247 , 1793 , 1617 , 3321 ,0 }; - static ulong[] dim1040Kuo3Init = { 1 , 1 , 7 , 13 , 31 , 3 , 59 , 213 , 265 , 3 , 543 , 2237 , 6617 ,0 }; - static ulong[] dim1041Kuo3Init = { 1 , 1 , 7 , 13 , 9 , 23 , 57 , 89 , 365 , 11 , 871 , 1343 , 7375 ,0 }; - static ulong[] dim1042Kuo3Init = { 1 , 3 , 7 , 11 , 7 , 19 , 15 , 101 , 239 , 341 , 1259 , 3607 , 3879 ,0 }; - static ulong[] dim1043Kuo3Init = { 1 , 1 , 5 , 7 , 29 , 25 , 117 , 183 , 131 , 705 , 1497 , 3537 , 1007 ,0 }; - static ulong[] dim1044Kuo3Init = { 1 , 1 , 1 , 3 , 11 , 41 , 113 , 127 , 95 , 417 , 1177 , 1939 , 1317 ,0 }; - static ulong[] dim1045Kuo3Init = { 1 , 1 , 5 , 11 , 1 , 37 , 1 , 141 , 417 , 157 , 993 , 671 , 4993 ,0 }; - static ulong[] dim1046Kuo3Init = { 1 , 1 , 7 , 11 , 23 , 15 , 41 , 171 , 389 , 261 , 1967 , 3009 , 2237 ,0 }; - static ulong[] dim1047Kuo3Init = { 1 , 3 , 5 , 15 , 31 , 41 , 49 , 39 , 73 , 201 , 495 , 3121 , 4247 ,0 }; - static ulong[] dim1048Kuo3Init = { 1 , 1 , 3 , 1 , 17 , 21 , 95 , 219 , 343 , 103 , 93 , 2907 , 1279 ,0 }; - static ulong[] dim1049Kuo3Init = { 1 , 3 , 3 , 1 , 7 , 31 , 79 , 139 , 347 , 437 , 1261 , 3425 , 6981 ,0 }; - static ulong[] dim1050Kuo3Init = { 1 , 1 , 5 , 7 , 9 , 19 , 55 , 185 , 425 , 145 , 1627 , 3045 , 8113 ,0 }; - static ulong[] dim1051Kuo3Init = { 1 , 1 , 5 , 1 , 15 , 33 , 99 , 185 , 485 , 859 , 481 , 3063 , 3209 ,0 }; - static ulong[] dim1052Kuo3Init = { 1 , 1 , 3 , 13 , 23 , 7 , 7 , 81 , 405 , 705 , 1933 , 315 , 5819 ,0 }; - static ulong[] dim1053Kuo3Init = { 1 , 3 , 1 , 3 , 9 , 55 , 95 , 101 , 391 , 299 , 185 , 3687 , 2833 ,0 }; - static ulong[] dim1054Kuo3Init = { 1 , 3 , 7 , 13 , 15 , 5 , 119 , 29 , 29 , 893 , 207 , 1789 , 3395 ,0 }; - static ulong[] dim1055Kuo3Init = { 1 , 3 , 3 , 5 , 1 , 59 , 49 , 81 , 391 , 95 , 289 , 3167 , 5417 ,0 }; - static ulong[] dim1056Kuo3Init = { 1 , 3 , 5 , 15 , 31 , 21 , 5 , 189 , 63 , 567 , 1515 , 297 , 5415 ,0 }; - static ulong[] dim1057Kuo3Init = { 1 , 3 , 3 , 15 , 3 , 23 , 105 , 113 , 403 , 799 , 591 , 1977 , 1117 ,0 }; - static ulong[] dim1058Kuo3Init = { 1 , 3 , 1 , 13 , 23 , 55 , 59 , 229 , 319 , 357 , 1703 , 585 , 3785 ,0 }; - static ulong[] dim1059Kuo3Init = { 1 , 3 , 7 , 13 , 7 , 1 , 97 , 247 , 451 , 897 , 137 , 3289 , 3621 ,0 }; - static ulong[] dim1060Kuo3Init = { 1 , 3 , 1 , 5 , 13 , 43 , 89 , 75 , 243 , 489 , 1999 , 1179 , 13 ,0 }; - static ulong[] dim1061Kuo3Init = { 1 , 3 , 7 , 9 , 11 , 21 , 51 , 199 , 15 , 859 , 83 , 613 , 5027 ,0 }; - static ulong[] dim1062Kuo3Init = { 1 , 3 , 1 , 13 , 15 , 15 , 81 , 87 , 311 , 681 , 1391 , 2123 , 6747 ,0 }; - static ulong[] dim1063Kuo3Init = { 1 , 3 , 1 , 1 , 5 , 45 , 5 , 123 , 19 , 831 , 1345 , 3313 , 7945 ,0 }; - static ulong[] dim1064Kuo3Init = { 1 , 1 , 7 , 3 , 5 , 9 , 93 , 39 , 221 , 601 , 315 , 2179 , 6573 ,0 }; - static ulong[] dim1065Kuo3Init = { 1 , 3 , 5 , 13 , 17 , 17 , 117 , 145 , 471 , 893 , 305 , 3065 , 7519 ,0 }; - static ulong[] dim1066Kuo3Init = { 1 , 3 , 1 , 9 , 1 , 55 , 119 , 235 , 417 , 167 , 467 , 2947 , 3235 ,0 }; - static ulong[] dim1067Kuo3Init = { 1 , 3 , 3 , 13 , 25 , 51 , 71 , 101 , 255 , 671 , 1929 , 2911 , 2837 ,0 }; - static ulong[] dim1068Kuo3Init = { 1 , 1 , 5 , 15 , 17 , 1 , 79 , 241 , 25 , 635 , 379 , 1701 , 7139 ,0 }; - static ulong[] dim1069Kuo3Init = { 1 , 1 , 7 , 13 , 1 , 1 , 119 , 121 , 469 , 51 , 939 , 2161 , 4247 ,0 }; - static ulong[] dim1070Kuo3Init = { 1 , 3 , 3 , 15 , 3 , 35 , 95 , 107 , 143 , 701 , 1843 , 301 , 6345 ,0 }; - static ulong[] dim1071Kuo3Init = { 1 , 3 , 5 , 3 , 27 , 13 , 117 , 143 , 49 , 875 , 1705 , 3005 , 3671 ,0 }; - static ulong[] dim1072Kuo3Init = { 1 , 1 , 7 , 7 , 5 , 49 , 111 , 33 , 169 , 189 , 1109 , 805 , 2753 ,0 }; - static ulong[] dim1073Kuo3Init = { 1 , 3 , 7 , 9 , 19 , 49 , 59 , 3 , 71 , 859 , 435 , 3417 , 1883 ,0 }; - static ulong[] dim1074Kuo3Init = { 1 , 3 , 5 , 9 , 9 , 51 , 35 , 79 , 385 , 83 , 1121 , 1421 , 7317 ,0 }; - static ulong[] dim1075Kuo3Init = { 1 , 3 , 7 , 5 , 13 , 29 , 49 , 41 , 219 , 23 , 1025 , 849 , 499 ,0 }; - static ulong[] dim1076Kuo3Init = { 1 , 3 , 3 , 11 , 3 , 15 , 13 , 167 , 441 , 753 , 1731 , 527 , 8099 ,0 }; - static ulong[] dim1077Kuo3Init = { 1 , 3 , 5 , 3 , 1 , 57 , 17 , 193 , 29 , 849 , 15 , 539 , 1713 ,0 }; - static ulong[] dim1078Kuo3Init = { 1 , 1 , 1 , 11 , 27 , 47 , 59 , 249 , 363 , 175 , 3 , 2485 , 3551 ,0 }; - static ulong[] dim1079Kuo3Init = { 1 , 1 , 3 , 3 , 25 , 45 , 79 , 45 , 141 , 13 , 1007 , 1235 , 5359 ,0 }; - static ulong[] dim1080Kuo3Init = { 1 , 3 , 1 , 7 , 29 , 31 , 111 , 173 , 281 , 287 , 173 , 2627 , 4125 ,0 }; - static ulong[] dim1081Kuo3Init = { 1 , 3 , 5 , 5 , 3 , 13 , 37 , 157 , 509 , 323 , 1695 , 765 , 6533 ,0 }; - static ulong[] dim1082Kuo3Init = { 1 , 3 , 5 , 11 , 7 , 33 , 77 , 237 , 377 , 351 , 205 , 183 , 5273 ,0 }; - static ulong[] dim1083Kuo3Init = { 1 , 3 , 7 , 5 , 11 , 1 , 123 , 251 , 3 , 207 , 1319 , 553 , 8143 ,0 }; - static ulong[] dim1084Kuo3Init = { 1 , 1 , 7 , 15 , 23 , 25 , 105 , 43 , 271 , 633 , 1331 , 2197 , 7229 ,0 }; - static ulong[] dim1085Kuo3Init = { 1 , 3 , 3 , 1 , 13 , 37 , 119 , 195 , 21 , 751 , 1809 , 4025 , 3037 ,0 }; - static ulong[] dim1086Kuo3Init = { 1 , 1 , 7 , 13 , 19 , 1 , 3 , 33 , 79 , 477 , 1203 , 3657 , 5573 ,0 }; - static ulong[] dim1087Kuo3Init = { 1 , 1 , 1 , 1 , 21 , 21 , 121 , 183 , 355 , 259 , 1033 , 1621 , 2843 ,0 }; - static ulong[] dim1088Kuo3Init = { 1 , 3 , 7 , 15 , 19 , 37 , 121 , 233 , 397 , 27 , 279 , 2891 , 4191 ,0 }; - static ulong[] dim1089Kuo3Init = { 1 , 3 , 1 , 3 , 13 , 5 , 31 , 237 , 453 , 913 , 1073 , 3573 , 7883 ,0 }; - static ulong[] dim1090Kuo3Init = { 1 , 1 , 1 , 1 , 1 , 11 , 57 , 103 , 453 , 605 , 1041 , 2975 , 4735 ,0 }; - static ulong[] dim1091Kuo3Init = { 1 , 1 , 5 , 9 , 29 , 33 , 119 , 241 , 27 , 491 , 341 , 1945 , 6599 ,0 }; - static ulong[] dim1092Kuo3Init = { 1 , 1 , 7 , 1 , 25 , 41 , 83 , 191 , 481 , 995 , 1819 , 1577 , 3837 ,0 }; - static ulong[] dim1093Kuo3Init = { 1 , 3 , 5 , 5 , 15 , 21 , 81 , 111 , 143 , 281 , 509 , 2905 , 177 ,0 }; - static ulong[] dim1094Kuo3Init = { 1 , 1 , 1 , 3 , 19 , 19 , 31 , 107 , 451 , 1007 , 2027 , 3947 , 3903 ,0 }; - static ulong[] dim1095Kuo3Init = { 1 , 3 , 3 , 1 , 27 , 41 , 23 , 147 , 299 , 315 , 895 , 407 , 4761 ,0 }; - static ulong[] dim1096Kuo3Init = { 1 , 3 , 7 , 15 , 27 , 1 , 105 , 103 , 507 , 897 , 1309 , 3979 , 5123 ,0 }; - static ulong[] dim1097Kuo3Init = { 1 , 3 , 1 , 11 , 7 , 41 , 99 , 67 , 183 , 495 , 1509 , 2733 , 6995 ,0 }; - static ulong[] dim1098Kuo3Init = { 1 , 1 , 1 , 11 , 13 , 5 , 69 , 239 , 95 , 211 , 691 , 323 , 7485 ,0 }; - static ulong[] dim1099Kuo3Init = { 1 , 3 , 5 , 11 , 23 , 57 , 5 , 113 , 417 , 893 , 1229 , 2109 , 7657 ,0 }; - static ulong[] dim1100Kuo3Init = { 1 , 1 , 5 , 15 , 19 , 59 , 111 , 181 , 61 , 743 , 227 , 831 , 3035 ,0 }; - static ulong[] dim1101Kuo3Init = { 1 , 1 , 5 , 7 , 19 , 13 , 107 , 63 , 127 , 17 , 1753 , 337 , 3403 ,0 }; - static ulong[] dim1102Kuo3Init = { 1 , 3 , 7 , 7 , 7 , 21 , 85 , 219 , 77 , 311 , 685 , 145 , 3451 ,0 }; - static ulong[] dim1103Kuo3Init = { 1 , 3 , 5 , 5 , 3 , 55 , 123 , 187 , 407 , 539 , 1167 , 2741 , 6885 ,0 }; - static ulong[] dim1104Kuo3Init = { 1 , 3 , 1 , 13 , 23 , 57 , 109 , 93 , 93 , 483 , 857 , 1895 , 7145 ,0 }; - static ulong[] dim1105Kuo3Init = { 1 , 1 , 1 , 15 , 19 , 43 , 37 , 129 , 487 , 523 , 1959 , 2053 , 6281 ,0 }; - static ulong[] dim1106Kuo3Init = { 1 , 3 , 1 , 11 , 9 , 1 , 105 , 123 , 483 , 511 , 1661 , 1065 , 7539 ,0 }; - static ulong[] dim1107Kuo3Init = { 1 , 3 , 3 , 1 , 27 , 33 , 87 , 191 , 89 , 697 , 1195 , 1699 , 2699 ,0 }; - static ulong[] dim1108Kuo3Init = { 1 , 3 , 7 , 5 , 21 , 57 , 5 , 109 , 343 , 721 , 1355 , 1155 , 4515 ,0 }; - static ulong[] dim1109Kuo3Init = { 1 , 3 , 3 , 15 , 27 , 43 , 47 , 167 , 457 , 93 , 221 , 3693 , 383 ,0 }; - static ulong[] dim1110Kuo3Init = { 1 , 3 , 1 , 7 , 13 , 13 , 55 , 75 , 113 , 577 , 397 , 2491 , 6871 ,0 }; - static ulong[] dim1111Kuo3Init = { 1 , 1 , 3 , 13 , 31 , 31 , 71 , 189 , 39 , 397 , 977 , 2645 , 1683 , 5081 ,0 }; - static ulong[] dim1112Kuo3Init = { 1 , 3 , 5 , 15 , 27 , 41 , 125 , 69 , 269 , 157 , 1827 , 41 , 3105 , 10615 ,0 }; - static ulong[] dim1113Kuo3Init = { 1 , 1 , 3 , 9 , 5 , 45 , 33 , 169 , 317 , 371 , 389 , 595 , 1071 , 5323 ,0 }; - static ulong[] dim1114Kuo3Init = { 1 , 1 , 5 , 5 , 25 , 25 , 69 , 45 , 313 , 105 , 795 , 3987 , 5181 , 155 ,0 }; - static ulong[] dim1115Kuo3Init = { 1 , 3 , 7 , 5 , 19 , 17 , 13 , 119 , 213 , 289 , 269 , 1561 , 6069 , 15631 ,0 }; - static ulong[] dim1116Kuo3Init = { 1 , 3 , 7 , 1 , 15 , 7 , 17 , 173 , 491 , 907 , 315 , 101 , 6205 , 4631 ,0 }; - static ulong[] dim1117Kuo3Init = { 1 , 1 , 5 , 11 , 17 , 13 , 9 , 67 , 267 , 719 , 1565 , 2157 , 5773 , 5167 ,0 }; - static ulong[] dim1118Kuo3Init = { 1 , 1 , 5 , 5 , 11 , 45 , 65 , 207 , 403 , 231 , 1019 , 3345 , 2779 , 3621 ,0 }; - static ulong[] dim1119Kuo3Init = { 1 , 3 , 5 , 13 , 13 , 59 , 65 , 225 , 307 , 581 , 1159 , 2041 , 3535 , 16381 ,0 }; - static ulong[] dim1120Kuo3Init = { 1 , 3 , 1 , 15 , 9 , 45 , 17 , 99 , 285 , 797 , 477 , 3041 , 3123 , 397 ,0 }; - static ulong[] dim1121Kuo3Init = { 1 , 3 , 1 , 15 , 3 , 57 , 99 , 115 , 105 , 877 , 9 , 1185 , 3147 , 6285 ,0 }; - static ulong[] dim1122Kuo3Init = { 1 , 1 , 1 , 1 , 25 , 31 , 37 , 13 , 119 , 935 , 1339 , 2147 , 2371 , 16107 ,0 }; - static ulong[] dim1123Kuo3Init = { 1 , 1 , 5 , 15 , 17 , 31 , 123 , 131 , 135 , 977 , 1943 , 3643 , 4457 , 15405 ,0 }; - static ulong[] dim1124Kuo3Init = { 1 , 3 , 3 , 1 , 3 , 57 , 29 , 33 , 1 , 519 , 535 , 681 , 6255 , 16263 ,0 }; - static ulong[] dim1125Kuo3Init = { 1 , 1 , 5 , 3 , 9 , 45 , 39 , 215 , 329 , 457 , 1341 , 3037 , 1631 , 15335 ,0 }; - static ulong[] dim1126Kuo3Init = { 1 , 1 , 7 , 13 , 3 , 27 , 23 , 73 , 465 , 771 , 1453 , 3821 , 3099 , 10075 ,0 }; - static ulong[] dim1127Kuo3Init = { 1 , 1 , 3 , 3 , 21 , 45 , 119 , 233 , 507 , 959 , 1743 , 2711 , 2465 , 4257 ,0 }; - static ulong[] dim1128Kuo3Init = { 1 , 1 , 7 , 5 , 31 , 37 , 113 , 207 , 239 , 305 , 1085 , 2447 , 743 , 15747 ,0 }; - static ulong[] dim1129Kuo3Init = { 1 , 3 , 5 , 5 , 27 , 25 , 83 , 255 , 93 , 149 , 627 , 1887 , 6913 , 5793 ,0 }; - static ulong[] dim1130Kuo3Init = { 1 , 1 , 5 , 11 , 17 , 61 , 91 , 75 , 469 , 503 , 1405 , 3609 , 421 , 10819 ,0 }; - static ulong[] dim1131Kuo3Init = { 1 , 1 , 5 , 1 , 13 , 47 , 53 , 221 , 351 , 621 , 1025 , 3729 , 367 , 16091 ,0 }; - static ulong[] dim1132Kuo3Init = { 1 , 1 , 1 , 5 , 7 , 41 , 3 , 177 , 127 , 71 , 753 , 1581 , 2227 , 257 ,0 }; - static ulong[] dim1133Kuo3Init = { 1 , 1 , 3 , 3 , 3 , 17 , 69 , 31 , 143 , 825 , 291 , 257 , 2147 , 4199 ,0 }; - static ulong[] dim1134Kuo3Init = { 1 , 1 , 5 , 9 , 29 , 21 , 49 , 1 , 35 , 321 , 383 , 1495 , 4201 , 7143 ,0 }; - static ulong[] dim1135Kuo3Init = { 1 , 3 , 7 , 13 , 5 , 27 , 31 , 143 , 117 , 487 , 585 , 809 , 2425 , 15681 ,0 }; - static ulong[] dim1136Kuo3Init = { 1 , 3 , 3 , 13 , 23 , 3 , 33 , 213 , 209 , 185 , 603 , 431 , 5519 , 5017 ,0 }; - static ulong[] dim1137Kuo3Init = { 1 , 3 , 7 , 9 , 21 , 61 , 3 , 53 , 303 , 793 , 759 , 3869 , 391 , 8395 ,0 }; - static ulong[] dim1138Kuo3Init = { 1 , 3 , 5 , 13 , 25 , 13 , 119 , 37 , 419 , 399 , 825 , 709 , 5351 , 1299 ,0 }; - static ulong[] dim1139Kuo3Init = { 1 , 3 , 7 , 11 , 17 , 11 , 93 , 205 , 33 , 493 , 1353 , 3777 , 2521 , 13405 ,0 }; - static ulong[] dim1140Kuo3Init = { 1 , 3 , 3 , 5 , 5 , 3 , 25 , 215 , 209 , 559 , 465 , 1809 , 6621 , 8733 ,0 }; - static ulong[] dim1141Kuo3Init = { 1 , 3 , 5 , 11 , 23 , 17 , 75 , 11 , 299 , 613 , 565 , 3487 , 5017 , 6187 ,0 }; - static ulong[] dim1142Kuo3Init = { 1 , 3 , 5 , 15 , 15 , 41 , 121 , 225 , 259 , 283 , 1119 , 3509 , 6663 , 241 ,0 }; - static ulong[] dim1143Kuo3Init = { 1 , 3 , 3 , 5 , 17 , 49 , 5 , 227 , 493 , 677 , 1365 , 3681 , 1651 , 5079 ,0 }; - static ulong[] dim1144Kuo3Init = { 1 , 3 , 5 , 11 , 3 , 13 , 43 , 219 , 247 , 223 , 1451 , 1449 , 605 , 5877 ,0 }; - static ulong[] dim1145Kuo3Init = { 1 , 1 , 7 , 7 , 21 , 47 , 7 , 197 , 387 , 59 , 7 , 3209 , 5623 , 1221 ,0 }; - static ulong[] dim1146Kuo3Init = { 1 , 3 , 3 , 5 , 25 , 5 , 97 , 1 , 105 , 801 , 815 , 1635 , 3567 , 5231 ,0 }; - static ulong[] dim1147Kuo3Init = { 1 , 3 , 7 , 15 , 17 , 21 , 101 , 167 , 265 , 407 , 1859 , 3359 , 1245 , 4153 ,0 }; - static ulong[] dim1148Kuo3Init = { 1 , 1 , 1 , 11 , 31 , 61 , 21 , 101 , 77 , 325 , 645 , 2059 , 3201 , 527 ,0 }; - static ulong[] dim1149Kuo3Init = { 1 , 3 , 7 , 15 , 29 , 55 , 107 , 135 , 55 , 433 , 1519 , 1049 , 6119 , 15877 ,0 }; - static ulong[] dim1150Kuo3Init = { 1 , 1 , 7 , 7 , 19 , 29 , 1 , 167 , 13 , 67 , 1703 , 1159 , 7145 , 4243 ,0 }; - static ulong[] dim1151Kuo3Init = { 1 , 3 , 5 , 11 , 1 , 33 , 7 , 21 , 407 , 695 , 345 , 425 , 7399 , 3847 ,0 }; - static ulong[] dim1152Kuo3Init = { 1 , 1 , 7 , 11 , 15 , 59 , 121 , 175 , 21 , 859 , 1311 , 1365 , 3823 , 3983 ,0 }; - static ulong[] dim1153Kuo3Init = { 1 , 1 , 7 , 5 , 29 , 21 , 111 , 221 , 429 , 739 , 985 , 1989 , 4947 , 8311 ,0 }; - static ulong[] dim1154Kuo3Init = { 1 , 3 , 3 , 15 , 29 , 17 , 103 , 39 , 475 , 193 , 253 , 1903 , 4073 , 15039 ,0 }; - static ulong[] dim1155Kuo3Init = { 1 , 3 , 7 , 11 , 1 , 57 , 35 , 197 , 89 , 475 , 283 , 2291 , 7129 , 14357 ,0 }; - static ulong[] dim1156Kuo3Init = { 1 , 1 , 3 , 11 , 15 , 63 , 29 , 157 , 211 , 517 , 1643 , 199 , 285 , 8621 ,0 }; - static ulong[] dim1157Kuo3Init = { 1 , 3 , 3 , 15 , 9 , 47 , 43 , 215 , 407 , 979 , 51 , 635 , 467 , 6365 ,0 }; - static ulong[] dim1158Kuo3Init = { 1 , 3 , 3 , 1 , 23 , 27 , 97 , 111 , 51 , 407 , 1037 , 1337 , 1475 , 1151 ,0 }; - static ulong[] dim1159Kuo3Init = { 1 , 3 , 3 , 15 , 13 , 45 , 67 , 51 , 331 , 691 , 1137 , 1967 , 5715 , 3125 ,0 }; - static ulong[] dim1160Kuo3Init = { 1 , 3 , 3 , 15 , 31 , 19 , 85 , 221 , 449 , 689 , 1817 , 1575 , 7429 , 12125 ,0 }; - static ulong[] dim1161Kuo3Init = { 1 , 3 , 1 , 9 , 21 , 61 , 77 , 55 , 65 , 591 , 9 , 2477 , 4081 , 4631 ,0 }; - static ulong[] dim1162Kuo3Init = { 1 , 3 , 5 , 9 , 27 , 45 , 29 , 159 , 21 , 931 , 1939 , 1297 , 5589 , 12635 ,0 }; - static ulong[] dim1163Kuo3Init = { 1 , 1 , 7 , 9 , 21 , 41 , 7 , 171 , 461 , 373 , 1655 , 3475 , 4073 , 4859 ,0 }; - static ulong[] dim1164Kuo3Init = { 1 , 3 , 1 , 13 , 17 , 35 , 3 , 41 , 45 , 37 , 1409 , 3939 , 5497 , 3501 ,0 }; - static ulong[] dim1165Kuo3Init = { 1 , 1 , 3 , 15 , 11 , 57 , 121 , 177 , 177 , 515 , 675 , 1943 , 2645 , 2469 ,0 }; - static ulong[] dim1166Kuo3Init = { 1 , 1 , 7 , 1 , 23 , 63 , 29 , 157 , 157 , 397 , 1131 , 1479 , 4683 , 10011 ,0 }; - static ulong[] dim1167Kuo3Init = { 1 , 3 , 7 , 9 , 15 , 35 , 75 , 99 , 195 , 589 , 19 , 3427 , 1623 , 12843 ,0 }; - static ulong[] dim1168Kuo3Init = { 1 , 3 , 7 , 3 , 21 , 19 , 101 , 135 , 351 , 549 , 223 , 517 , 4023 , 1863 ,0 }; - static ulong[] dim1169Kuo3Init = { 1 , 1 , 7 , 7 , 7 , 23 , 67 , 15 , 217 , 915 , 1617 , 1527 , 877 , 15061 ,0 }; - static ulong[] dim1170Kuo3Init = { 1 , 3 , 5 , 3 , 11 , 35 , 95 , 5 , 399 , 669 , 1185 , 167 , 7405 , 11169 ,0 }; - static ulong[] dim1171Kuo3Init = { 1 , 3 , 5 , 5 , 1 , 49 , 91 , 125 , 185 , 73 , 263 , 1139 , 3171 , 5427 ,0 }; - static ulong[] dim1172Kuo3Init = { 1 , 1 , 5 , 1 , 27 , 51 , 89 , 81 , 179 , 593 , 67 , 1495 , 3669 , 15981 ,0 }; - static ulong[] dim1173Kuo3Init = { 1 , 3 , 1 , 11 , 29 , 63 , 47 , 105 , 327 , 747 , 953 , 2399 , 6711 , 16313 ,0 }; - static ulong[] dim1174Kuo3Init = { 1 , 1 , 5 , 5 , 21 , 21 , 117 , 179 , 427 , 981 , 2029 , 1 , 495 , 4005 ,0 }; - static ulong[] dim1175Kuo3Init = { 1 , 1 , 3 , 5 , 23 , 21 , 59 , 99 , 459 , 217 , 1131 , 1853 , 3049 , 2247 ,0 }; - static ulong[] dim1176Kuo3Init = { 1 , 3 , 1 , 5 , 29 , 9 , 71 , 167 , 55 , 775 , 627 , 3967 , 45 , 11199 ,0 }; - static ulong[] dim1177Kuo3Init = { 1 , 3 , 5 , 3 , 29 , 25 , 1 , 69 , 317 , 649 , 1567 , 2587 , 2277 , 15675 ,0 }; - static ulong[] dim1178Kuo3Init = { 1 , 3 , 3 , 9 , 21 , 3 , 39 , 147 , 279 , 953 , 1207 , 333 , 2747 , 1717 ,0 }; - static ulong[] dim1179Kuo3Init = { 1 , 3 , 3 , 3 , 31 , 63 , 113 , 149 , 431 , 699 , 335 , 2475 , 6375 , 13061 ,0 }; - static ulong[] dim1180Kuo3Init = { 1 , 1 , 7 , 11 , 11 , 19 , 51 , 175 , 377 , 971 , 35 , 2749 , 6309 , 4755 ,0 }; - static ulong[] dim1181Kuo3Init = { 1 , 1 , 3 , 15 , 27 , 53 , 105 , 221 , 15 , 495 , 799 , 1717 , 6997 , 15949 ,0 }; - static ulong[] dim1182Kuo3Init = { 1 , 1 , 1 , 15 , 31 , 29 , 69 , 137 , 421 , 231 , 2021 , 1869 , 4533 , 1121 ,0 }; - static ulong[] dim1183Kuo3Init = { 1 , 1 , 7 , 11 , 15 , 49 , 17 , 121 , 285 , 303 , 1085 , 2463 , 357 , 2519 ,0 }; - static ulong[] dim1184Kuo3Init = { 1 , 1 , 1 , 5 , 29 , 47 , 109 , 95 , 339 , 15 , 1195 , 2171 , 4649 , 6517 ,0 }; - static ulong[] dim1185Kuo3Init = { 1 , 3 , 3 , 3 , 29 , 19 , 45 , 93 , 47 , 827 , 1113 , 4055 , 601 , 10807 ,0 }; - static ulong[] dim1186Kuo3Init = { 1 , 1 , 7 , 5 , 15 , 47 , 11 , 79 , 137 , 267 , 1443 , 1003 , 2475 , 147 ,0 }; - static ulong[] dim1187Kuo3Init = { 1 , 3 , 7 , 15 , 11 , 39 , 95 , 191 , 205 , 967 , 333 , 3371 , 4913 , 15231 ,0 }; - static ulong[] dim1188Kuo3Init = { 1 , 3 , 7 , 9 , 25 , 9 , 47 , 75 , 77 , 539 , 487 , 361 , 2293 , 7285 ,0 }; - static ulong[] dim1189Kuo3Init = { 1 , 3 , 7 , 7 , 27 , 11 , 93 , 181 , 455 , 277 , 1001 , 3313 , 7335 , 4593 ,0 }; - static ulong[] dim1190Kuo3Init = { 1 , 1 , 5 , 5 , 15 , 35 , 107 , 51 , 223 , 447 , 371 , 1739 , 1937 , 3589 ,0 }; - static ulong[] dim1191Kuo3Init = { 1 , 1 , 3 , 11 , 15 , 51 , 23 , 129 , 285 , 895 , 2015 , 1389 , 2043 , 1989 ,0 }; - static ulong[] dim1192Kuo3Init = { 1 , 1 , 5 , 7 , 21 , 57 , 107 , 149 , 285 , 825 , 959 , 827 , 2931 , 3207 ,0 }; - static ulong[] dim1193Kuo3Init = { 1 , 1 , 1 , 13 , 23 , 19 , 91 , 15 , 261 , 785 , 1031 , 2245 , 505 , 14891 ,0 }; - static ulong[] dim1194Kuo3Init = { 1 , 1 , 3 , 15 , 23 , 21 , 33 , 153 , 71 , 757 , 1131 , 3251 , 877 , 4533 ,0 }; - static ulong[] dim1195Kuo3Init = { 1 , 1 , 3 , 11 , 25 , 39 , 33 , 231 , 451 , 587 , 781 , 1145 , 4743 , 467 ,0 }; - static ulong[] dim1196Kuo3Init = { 1 , 1 , 7 , 11 , 23 , 7 , 35 , 45 , 397 , 41 , 1443 , 2087 , 587 , 14139 ,0 }; - static ulong[] dim1197Kuo3Init = { 1 , 3 , 3 , 3 , 19 , 57 , 61 , 225 , 197 , 263 , 1447 , 1929 , 2833 , 5325 ,0 }; - static ulong[] dim1198Kuo3Init = { 1 , 1 , 5 , 7 , 25 , 51 , 45 , 221 , 403 , 843 , 727 , 3099 , 3883 , 9151 ,0 }; - static ulong[] dim1199Kuo3Init = { 1 , 1 , 5 , 13 , 9 , 23 , 33 , 119 , 81 , 525 , 1527 , 567 , 2867 , 12907 ,0 }; - static ulong[] dim1200Kuo3Init = { 1 , 1 , 5 , 5 , 11 , 19 , 125 , 135 , 427 , 949 , 643 , 3403 , 6531 , 12607 ,0 }; - static ulong[] dim1201Kuo3Init = { 1 , 3 , 3 , 7 , 27 , 23 , 89 , 83 , 381 , 333 , 361 , 2773 , 4247 , 10233 ,0 }; - static ulong[] dim1202Kuo3Init = { 1 , 3 , 7 , 11 , 25 , 61 , 105 , 141 , 473 , 993 , 379 , 2949 , 5757 , 4003 ,0 }; - static ulong[] dim1203Kuo3Init = { 1 , 1 , 3 , 11 , 27 , 29 , 75 , 175 , 391 , 567 , 1017 , 1575 , 5287 , 16289 ,0 }; - static ulong[] dim1204Kuo3Init = { 1 , 3 , 7 , 15 , 7 , 33 , 23 , 137 , 299 , 19 , 599 , 2649 , 6141 , 3321 ,0 }; - static ulong[] dim1205Kuo3Init = { 1 , 1 , 3 , 1 , 3 , 19 , 101 , 95 , 499 , 261 , 51 , 43 , 5457 , 313 ,0 }; - static ulong[] dim1206Kuo3Init = { 1 , 3 , 5 , 11 , 27 , 5 , 7 , 85 , 419 , 983 , 1965 , 1639 , 6397 , 15823 ,0 }; - static ulong[] dim1207Kuo3Init = { 1 , 1 , 1 , 11 , 13 , 55 , 121 , 13 , 289 , 791 , 437 , 3279 , 7125 , 10473 ,0 }; - static ulong[] dim1208Kuo3Init = { 1 , 1 , 7 , 1 , 13 , 15 , 25 , 9 , 21 , 205 , 61 , 749 , 8005 , 9453 ,0 }; - static ulong[] dim1209Kuo3Init = { 1 , 1 , 3 , 9 , 19 , 47 , 55 , 113 , 325 , 165 , 771 , 3655 , 6265 , 11157 ,0 }; - static ulong[] dim1210Kuo3Init = { 1 , 1 , 5 , 13 , 19 , 45 , 107 , 37 , 205 , 677 , 1273 , 3817 , 559 , 11321 ,0 }; - static ulong[] dim1211Kuo3Init = { 1 , 3 , 7 , 15 , 31 , 57 , 87 , 31 , 431 , 383 , 327 , 2703 , 4197 , 7861 ,0 }; - static ulong[] dim1212Kuo3Init = { 1 , 1 , 3 , 9 , 3 , 33 , 39 , 253 , 215 , 903 , 447 , 2175 , 5249 , 3203 ,0 }; - static ulong[] dim1213Kuo3Init = { 1 , 3 , 7 , 5 , 15 , 5 , 27 , 145 , 391 , 869 , 1641 , 2497 , 4683 , 3111 ,0 }; - static ulong[] dim1214Kuo3Init = { 1 , 3 , 1 , 5 , 3 , 33 , 39 , 223 , 379 , 803 , 1833 , 1799 , 2617 , 2113 ,0 }; - static ulong[] dim1215Kuo3Init = { 1 , 3 , 1 , 15 , 29 , 37 , 57 , 227 , 425 , 943 , 311 , 2883 , 2973 , 1831 ,0 }; - static ulong[] dim1216Kuo3Init = { 1 , 3 , 3 , 5 , 17 , 63 , 113 , 139 , 453 , 871 , 1029 , 2705 , 3379 , 4503 ,0 }; - static ulong[] dim1217Kuo3Init = { 1 , 3 , 7 , 5 , 19 , 35 , 43 , 151 , 511 , 657 , 1885 , 1425 , 387 , 2165 ,0 }; - static ulong[] dim1218Kuo3Init = { 1 , 1 , 3 , 15 , 9 , 61 , 123 , 241 , 485 , 485 , 955 , 1215 , 87 , 3195 ,0 }; - static ulong[] dim1219Kuo3Init = { 1 , 3 , 5 , 9 , 23 , 45 , 51 , 15 , 23 , 49 , 2025 , 853 , 6609 , 12099 ,0 }; - static ulong[] dim1220Kuo3Init = { 1 , 3 , 7 , 7 , 23 , 35 , 95 , 67 , 131 , 281 , 1821 , 1951 , 1363 , 7477 ,0 }; - static ulong[] dim1221Kuo3Init = { 1 , 3 , 1 , 7 , 9 , 53 , 79 , 255 , 453 , 77 , 629 , 1207 , 4171 , 4415 ,0 }; - static ulong[] dim1222Kuo3Init = { 1 , 3 , 5 , 3 , 23 , 5 , 11 , 153 , 57 , 217 , 1177 , 2297 , 3515 , 15121 ,0 }; - static ulong[] dim1223Kuo3Init = { 1 , 1 , 1 , 9 , 31 , 57 , 93 , 35 , 177 , 449 , 1505 , 2715 , 1315 , 8953 ,0 }; - static ulong[] dim1224Kuo3Init = { 1 , 1 , 3 , 11 , 7 , 7 , 109 , 255 , 317 , 325 , 267 , 2573 , 1511 , 3371 ,0 }; - static ulong[] dim1225Kuo3Init = { 1 , 3 , 7 , 11 , 13 , 51 , 29 , 203 , 13 , 889 , 679 , 1981 , 5553 , 671 ,0 }; - static ulong[] dim1226Kuo3Init = { 1 , 1 , 3 , 5 , 29 , 11 , 29 , 249 , 289 , 817 , 1983 , 1865 , 6705 , 9667 ,0 }; - static ulong[] dim1227Kuo3Init = { 1 , 1 , 3 , 13 , 15 , 19 , 23 , 59 , 143 , 815 , 643 , 763 , 1437 , 2909 ,0 }; - static ulong[] dim1228Kuo3Init = { 1 , 3 , 7 , 5 , 15 , 61 , 121 , 73 , 367 , 13 , 1455 , 561 , 7475 , 8479 ,0 }; - static ulong[] dim1229Kuo3Init = { 1 , 3 , 1 , 15 , 17 , 19 , 105 , 223 , 481 , 49 , 217 , 2935 , 2731 , 9857 ,0 }; - static ulong[] dim1230Kuo3Init = { 1 , 3 , 1 , 7 , 3 , 41 , 3 , 195 , 245 , 969 , 139 , 2727 , 6957 , 2049 ,0 }; - static ulong[] dim1231Kuo3Init = { 1 , 1 , 5 , 1 , 13 , 39 , 55 , 247 , 279 , 991 , 875 , 1393 , 2649 , 14477 ,0 }; - static ulong[] dim1232Kuo3Init = { 1 , 1 , 7 , 3 , 19 , 1 , 83 , 87 , 277 , 939 , 105 , 681 , 5377 , 16067 ,0 }; - static ulong[] dim1233Kuo3Init = { 1 , 3 , 3 , 3 , 29 , 9 , 63 , 67 , 97 , 457 , 179 , 1137 , 5067 , 14541 ,0 }; - static ulong[] dim1234Kuo3Init = { 1 , 1 , 7 , 5 , 25 , 23 , 17 , 175 , 33 , 523 , 2023 , 649 , 6889 , 3481 ,0 }; - static ulong[] dim1235Kuo3Init = { 1 , 1 , 7 , 7 , 13 , 7 , 7 , 145 , 81 , 69 , 1029 , 1351 , 285 , 13007 ,0 }; - static ulong[] dim1236Kuo3Init = { 1 , 1 , 5 , 3 , 3 , 23 , 107 , 67 , 327 , 463 , 1123 , 1981 , 1189 , 6921 ,0 }; - static ulong[] dim1237Kuo3Init = { 1 , 1 , 7 , 3 , 15 , 31 , 15 , 51 , 421 , 191 , 1663 , 2257 , 2633 , 4685 ,0 }; - static ulong[] dim1238Kuo3Init = { 1 , 3 , 7 , 11 , 9 , 41 , 101 , 43 , 23 , 453 , 1399 , 2349 , 8013 , 15791 ,0 }; - static ulong[] dim1239Kuo3Init = { 1 , 3 , 3 , 11 , 27 , 47 , 15 , 193 , 99 , 355 , 1873 , 1541 , 5957 , 13079 ,0 }; - static ulong[] dim1240Kuo3Init = { 1 , 3 , 1 , 9 , 11 , 45 , 43 , 171 , 355 , 17 , 955 , 1153 , 1437 , 5477 ,0 }; - static ulong[] dim1241Kuo3Init = { 1 , 3 , 7 , 7 , 29 , 25 , 11 , 231 , 79 , 951 , 1619 , 69 , 2279 , 7249 ,0 }; - static ulong[] dim1242Kuo3Init = { 1 , 1 , 5 , 1 , 5 , 41 , 47 , 229 , 353 , 261 , 443 , 1181 , 1813 , 7929 ,0 }; - static ulong[] dim1243Kuo3Init = { 1 , 3 , 7 , 13 , 19 , 45 , 69 , 11 , 209 , 477 , 1623 , 429 , 1853 , 13571 ,0 }; - static ulong[] dim1244Kuo3Init = { 1 , 3 , 3 , 5 , 19 , 55 , 49 , 243 , 357 , 675 , 129 , 2801 , 2511 , 12965 ,0 }; - static ulong[] dim1245Kuo3Init = { 1 , 1 , 3 , 15 , 11 , 47 , 11 , 11 , 291 , 943 , 573 , 2257 , 1767 , 2547 ,0 }; - static ulong[] dim1246Kuo3Init = { 1 , 1 , 7 , 11 , 1 , 11 , 103 , 65 , 395 , 623 , 697 , 3375 , 7977 , 13449 ,0 }; - static ulong[] dim1247Kuo3Init = { 1 , 1 , 3 , 3 , 3 , 35 , 69 , 59 , 85 , 379 , 835 , 557 , 873 , 16281 ,0 }; - static ulong[] dim1248Kuo3Init = { 1 , 1 , 7 , 3 , 31 , 41 , 59 , 137 , 297 , 43 , 1111 , 2119 , 3109 , 1551 ,0 }; - static ulong[] dim1249Kuo3Init = { 1 , 3 , 7 , 13 , 11 , 11 , 87 , 199 , 283 , 461 , 951 , 2429 , 6739 , 11499 ,0 }; - static ulong[] dim1250Kuo3Init = { 1 , 3 , 7 , 7 , 31 , 13 , 89 , 75 , 117 , 755 , 1761 , 581 , 7233 , 8395 ,0 }; - static ulong[] dim1251Kuo3Init = { 1 , 3 , 7 , 7 , 1 , 29 , 117 , 213 , 81 , 901 , 357 , 27 , 127 , 10541 ,0 }; - static ulong[] dim1252Kuo3Init = { 1 , 1 , 7 , 5 , 31 , 1 , 11 , 243 , 321 , 973 , 1753 , 2363 , 6717 , 14861 ,0 }; - static ulong[] dim1253Kuo3Init = { 1 , 1 , 1 , 1 , 17 , 25 , 35 , 211 , 197 , 697 , 1389 , 1371 , 3687 , 11941 ,0 }; - static ulong[] dim1254Kuo3Init = { 1 , 3 , 5 , 11 , 15 , 35 , 27 , 179 , 367 , 891 , 483 , 3581 , 4343 , 9581 ,0 }; - static ulong[] dim1255Kuo3Init = { 1 , 3 , 5 , 1 , 13 , 41 , 67 , 75 , 309 , 601 , 247 , 1609 , 4365 , 3003 ,0 }; - static ulong[] dim1256Kuo3Init = { 1 , 1 , 7 , 11 , 1 , 59 , 55 , 213 , 415 , 445 , 1763 , 3615 , 6847 , 11931 ,0 }; - static ulong[] dim1257Kuo3Init = { 1 , 1 , 7 , 13 , 25 , 53 , 9 , 63 , 501 , 95 , 1745 , 3273 , 3551 , 12733 ,0 }; - static ulong[] dim1258Kuo3Init = { 1 , 3 , 7 , 7 , 13 , 23 , 117 , 75 , 169 , 11 , 1401 , 125 , 2127 , 15609 ,0 }; - static ulong[] dim1259Kuo3Init = { 1 , 3 , 3 , 9 , 21 , 53 , 113 , 247 , 495 , 39 , 1491 , 985 , 4943 , 3683 ,0 }; - static ulong[] dim1260Kuo3Init = { 1 , 1 , 1 , 7 , 5 , 49 , 23 , 207 , 43 , 863 , 749 , 3363 , 1191 , 1305 ,0 }; - static ulong[] dim1261Kuo3Init = { 1 , 1 , 5 , 15 , 3 , 13 , 19 , 123 , 377 , 803 , 319 , 2617 , 7781 , 5113 ,0 }; - static ulong[] dim1262Kuo3Init = { 1 , 3 , 3 , 13 , 23 , 53 , 19 , 223 , 63 , 729 , 599 , 2437 , 1023 , 13659 ,0 }; - static ulong[] dim1263Kuo3Init = { 1 , 3 , 7 , 13 , 7 , 31 , 101 , 227 , 53 , 933 , 405 , 1077 , 1341 , 12049 ,0 }; - static ulong[] dim1264Kuo3Init = { 1 , 1 , 3 , 11 , 21 , 31 , 65 , 191 , 175 , 735 , 593 , 805 , 4405 , 7893 ,0 }; - static ulong[] dim1265Kuo3Init = { 1 , 3 , 3 , 11 , 11 , 23 , 57 , 71 , 367 , 275 , 715 , 81 , 6455 , 9509 ,0 }; - static ulong[] dim1266Kuo3Init = { 1 , 1 , 5 , 9 , 7 , 5 , 99 , 19 , 193 , 501 , 243 , 1971 , 4685 , 455 ,0 }; - static ulong[] dim1267Kuo3Init = { 1 , 3 , 3 , 1 , 11 , 59 , 45 , 241 , 257 , 107 , 605 , 3885 , 813 , 15667 ,0 }; - static ulong[] dim1268Kuo3Init = { 1 , 3 , 7 , 9 , 17 , 63 , 93 , 129 , 191 , 839 , 535 , 271 , 1087 , 10393 ,0 }; - static ulong[] dim1269Kuo3Init = { 1 , 1 , 3 , 9 , 19 , 15 , 11 , 85 , 377 , 653 , 891 , 1909 , 5561 , 1289 ,0 }; - static ulong[] dim1270Kuo3Init = { 1 , 3 , 1 , 15 , 7 , 25 , 25 , 67 , 55 , 749 , 1541 , 1183 , 1563 , 5377 ,0 }; - static ulong[] dim1271Kuo3Init = { 1 , 3 , 1 , 5 , 11 , 57 , 121 , 173 , 317 , 777 , 749 , 4037 , 123 , 10707 ,0 }; - static ulong[] dim1272Kuo3Init = { 1 , 3 , 3 , 5 , 29 , 45 , 99 , 215 , 103 , 447 , 1743 , 991 , 7649 , 11773 ,0 }; - static ulong[] dim1273Kuo3Init = { 1 , 1 , 5 , 7 , 3 , 33 , 39 , 169 , 255 , 383 , 559 , 3635 , 5669 , 4267 ,0 }; - static ulong[] dim1274Kuo3Init = { 1 , 3 , 1 , 5 , 15 , 41 , 51 , 69 , 373 , 815 , 293 , 2125 , 4903 , 12429 ,0 }; - static ulong[] dim1275Kuo3Init = { 1 , 3 , 3 , 1 , 17 , 53 , 101 , 153 , 271 , 491 , 801 , 2811 , 619 , 2021 ,0 }; - static ulong[] dim1276Kuo3Init = { 1 , 1 , 3 , 5 , 25 , 37 , 33 , 139 , 385 , 323 , 601 , 1077 , 753 , 3925 ,0 }; - static ulong[] dim1277Kuo3Init = { 1 , 1 , 3 , 1 , 25 , 21 , 127 , 67 , 463 , 121 , 1765 , 1561 , 5 , 5161 ,0 }; - static ulong[] dim1278Kuo3Init = { 1 , 1 , 7 , 7 , 25 , 27 , 37 , 159 , 453 , 847 , 353 , 3051 , 4269 , 13981 ,0 }; - static ulong[] dim1279Kuo3Init = { 1 , 3 , 5 , 11 , 13 , 1 , 11 , 123 , 459 , 989 , 1459 , 3793 , 5915 , 8411 ,0 }; - static ulong[] dim1280Kuo3Init = { 1 , 3 , 1 , 15 , 5 , 21 , 37 , 41 , 399 , 471 , 1147 , 143 , 2737 , 9447 ,0 }; - static ulong[] dim1281Kuo3Init = { 1 , 3 , 1 , 5 , 27 , 5 , 121 , 77 , 183 , 209 , 49 , 3737 , 4317 , 11225 ,0 }; - static ulong[] dim1282Kuo3Init = { 1 , 1 , 3 , 7 , 5 , 9 , 65 , 25 , 237 , 21 , 139 , 1729 , 965 , 15419 ,0 }; - static ulong[] dim1283Kuo3Init = { 1 , 1 , 3 , 11 , 5 , 47 , 115 , 211 , 495 , 97 , 1439 , 127 , 4823 , 11643 ,0 }; - static ulong[] dim1284Kuo3Init = { 1 , 1 , 5 , 1 , 11 , 37 , 19 , 129 , 35 , 1017 , 1057 , 3501 , 4293 , 15271 ,0 }; - static ulong[] dim1285Kuo3Init = { 1 , 3 , 5 , 5 , 3 , 31 , 45 , 25 , 441 , 729 , 909 , 3519 , 5579 , 10341 ,0 }; - static ulong[] dim1286Kuo3Init = { 1 , 1 , 5 , 13 , 23 , 55 , 13 , 47 , 25 , 319 , 697 , 2839 , 209 , 5007 ,0 }; - static ulong[] dim1287Kuo3Init = { 1 , 3 , 1 , 13 , 31 , 7 , 81 , 239 , 305 , 667 , 233 , 3555 , 7385 , 10113 ,0 }; - static ulong[] dim1288Kuo3Init = { 1 , 3 , 3 , 13 , 23 , 7 , 101 , 193 , 343 , 435 , 1065 , 3399 , 1855 , 15231 ,0 }; - static ulong[] dim1289Kuo3Init = { 1 , 3 , 7 , 7 , 3 , 31 , 13 , 51 , 141 , 523 , 1545 , 31 , 3827 , 13871 ,0 }; - static ulong[] dim1290Kuo3Init = { 1 , 1 , 1 , 3 , 29 , 37 , 117 , 187 , 337 , 799 , 923 , 3919 , 5861 , 3167 ,0 }; - static ulong[] dim1291Kuo3Init = { 1 , 3 , 7 , 1 , 21 , 17 , 59 , 73 , 223 , 455 , 2025 , 2701 , 673 , 8333 ,0 }; - static ulong[] dim1292Kuo3Init = { 1 , 1 , 1 , 3 , 9 , 53 , 99 , 87 , 35 , 637 , 1553 , 1417 , 1233 , 855 ,0 }; - static ulong[] dim1293Kuo3Init = { 1 , 1 , 3 , 11 , 25 , 21 , 3 , 227 , 345 , 711 , 1347 , 437 , 7513 , 7731 ,0 }; - static ulong[] dim1294Kuo3Init = { 1 , 1 , 1 , 3 , 5 , 51 , 125 , 133 , 241 , 327 , 589 , 1895 , 1627 , 6945 ,0 }; - static ulong[] dim1295Kuo3Init = { 1 , 1 , 1 , 3 , 21 , 19 , 101 , 95 , 143 , 353 , 1783 , 2815 , 3691 , 11209 ,0 }; - static ulong[] dim1296Kuo3Init = { 1 , 1 , 3 , 1 , 31 , 29 , 95 , 121 , 253 , 925 , 277 , 2857 , 963 , 7701 ,0 }; - static ulong[] dim1297Kuo3Init = { 1 , 3 , 7 , 5 , 3 , 23 , 31 , 63 , 467 , 91 , 1235 , 1927 , 4347 , 9281 ,0 }; - static ulong[] dim1298Kuo3Init = { 1 , 1 , 5 , 15 , 21 , 23 , 113 , 219 , 69 , 13 , 1165 , 1043 , 6335 , 3499 ,0 }; - static ulong[] dim1299Kuo3Init = { 1 , 1 , 7 , 15 , 25 , 35 , 67 , 67 , 273 , 421 , 521 , 1169 , 1557 , 1523 ,0 }; - static ulong[] dim1300Kuo3Init = { 1 , 3 , 5 , 7 , 25 , 5 , 19 , 157 , 385 , 35 , 1701 , 1697 , 1425 , 12549 ,0 }; - static ulong[] dim1301Kuo3Init = { 1 , 1 , 3 , 1 , 15 , 13 , 31 , 219 , 159 , 831 , 909 , 1907 , 4251 , 4231 ,0 }; - static ulong[] dim1302Kuo3Init = { 1 , 3 , 5 , 7 , 27 , 51 , 19 , 205 , 177 , 769 , 1881 , 3961 , 7715 , 13351 ,0 }; - static ulong[] dim1303Kuo3Init = { 1 , 1 , 3 , 5 , 13 , 19 , 1 , 91 , 257 , 201 , 459 , 525 , 5093 , 7259 ,0 }; - static ulong[] dim1304Kuo3Init = { 1 , 3 , 7 , 9 , 3 , 37 , 87 , 117 , 209 , 9 , 1019 , 195 , 1531 , 14445 ,0 }; - static ulong[] dim1305Kuo3Init = { 1 , 1 , 1 , 5 , 23 , 35 , 21 , 27 , 455 , 665 , 455 , 1009 , 2315 , 11465 ,0 }; - static ulong[] dim1306Kuo3Init = { 1 , 3 , 7 , 1 , 17 , 55 , 3 , 71 , 239 , 183 , 889 , 2091 , 2853 , 12541 ,0 }; - static ulong[] dim1307Kuo3Init = { 1 , 1 , 3 , 15 , 5 , 7 , 67 , 127 , 411 , 719 , 835 , 2299 , 1339 , 12149 ,0 }; - static ulong[] dim1308Kuo3Init = { 1 , 1 , 3 , 3 , 7 , 21 , 113 , 199 , 17 , 161 , 1945 , 1141 , 4879 , 1579 ,0 }; - static ulong[] dim1309Kuo3Init = { 1 , 3 , 1 , 7 , 5 , 9 , 35 , 169 , 317 , 355 , 193 , 599 , 7653 , 7689 ,0 }; - static ulong[] dim1310Kuo3Init = { 1 , 1 , 1 , 13 , 29 , 35 , 59 , 85 , 139 , 199 , 1075 , 2799 , 6263 , 11133 ,0 }; - static ulong[] dim1311Kuo3Init = { 1 , 1 , 5 , 3 , 19 , 63 , 13 , 41 , 289 , 845 , 1455 , 633 , 4995 , 2037 ,0 }; - static ulong[] dim1312Kuo3Init = { 1 , 1 , 3 , 11 , 19 , 25 , 65 , 213 , 27 , 257 , 1151 , 4063 , 5587 , 2205 ,0 }; - static ulong[] dim1313Kuo3Init = { 1 , 1 , 7 , 7 , 9 , 53 , 103 , 49 , 187 , 579 , 801 , 263 , 2975 , 12013 ,0 }; - static ulong[] dim1314Kuo3Init = { 1 , 3 , 1 , 13 , 7 , 13 , 85 , 11 , 365 , 63 , 595 , 747 , 1565 , 1817 ,0 }; - static ulong[] dim1315Kuo3Init = { 1 , 3 , 7 , 15 , 11 , 1 , 45 , 3 , 181 , 357 , 447 , 821 , 6471 , 10121 ,0 }; - static ulong[] dim1316Kuo3Init = { 1 , 1 , 7 , 11 , 7 , 25 , 75 , 139 , 463 , 679 , 1327 , 2863 , 2373 , 10681 ,0 }; - static ulong[] dim1317Kuo3Init = { 1 , 3 , 5 , 5 , 17 , 7 , 103 , 157 , 241 , 781 , 399 , 3951 , 6587 , 35 ,0 }; - static ulong[] dim1318Kuo3Init = { 1 , 3 , 5 , 5 , 17 , 29 , 71 , 115 , 415 , 91 , 729 , 3055 , 5219 , 15271 ,0 }; - static ulong[] dim1319Kuo3Init = { 1 , 3 , 1 , 9 , 7 , 5 , 123 , 235 , 33 , 103 , 257 , 1151 , 3931 , 16257 ,0 }; - static ulong[] dim1320Kuo3Init = { 1 , 1 , 3 , 11 , 27 , 29 , 29 , 31 , 463 , 187 , 103 , 209 , 747 , 14311 ,0 }; - static ulong[] dim1321Kuo3Init = { 1 , 3 , 5 , 1 , 11 , 61 , 79 , 103 , 233 , 733 , 779 , 705 , 2377 , 12689 ,0 }; - static ulong[] dim1322Kuo3Init = { 1 , 3 , 1 , 9 , 31 , 11 , 123 , 239 , 227 , 81 , 525 , 2099 , 8149 , 5851 ,0 }; - static ulong[] dim1323Kuo3Init = { 1 , 3 , 7 , 5 , 1 , 37 , 9 , 199 , 313 , 875 , 975 , 777 , 5449 , 3075 ,0 }; - static ulong[] dim1324Kuo3Init = { 1 , 3 , 5 , 11 , 7 , 29 , 5 , 133 , 419 , 691 , 859 , 1089 , 4331 , 11079 ,0 }; - static ulong[] dim1325Kuo3Init = { 1 , 1 , 1 , 1 , 5 , 57 , 113 , 17 , 481 , 989 , 233 , 1523 , 3291 , 1665 ,0 }; - static ulong[] dim1326Kuo3Init = { 1 , 3 , 7 , 15 , 27 , 31 , 43 , 247 , 403 , 395 , 69 , 2561 , 7281 , 7291 ,0 }; - static ulong[] dim1327Kuo3Init = { 1 , 3 , 3 , 11 , 31 , 43 , 105 , 237 , 21 , 719 , 861 , 199 , 1045 , 7689 ,0 }; - static ulong[] dim1328Kuo3Init = { 1 , 3 , 1 , 13 , 1 , 15 , 3 , 35 , 219 , 993 , 891 , 3649 , 3795 , 11599 ,0 }; - static ulong[] dim1329Kuo3Init = { 1 , 3 , 7 , 7 , 7 , 15 , 125 , 243 , 449 , 173 , 1041 , 1433 , 6559 , 14285 ,0 }; - static ulong[] dim1330Kuo3Init = { 1 , 1 , 7 , 7 , 1 , 5 , 75 , 189 , 439 , 745 , 1361 , 3525 , 2913 , 10513 ,0 }; - static ulong[] dim1331Kuo3Init = { 1 , 1 , 5 , 1 , 31 , 7 , 49 , 41 , 413 , 347 , 881 , 2953 , 2173 , 8667 ,0 }; - static ulong[] dim1332Kuo3Init = { 1 , 3 , 3 , 1 , 27 , 33 , 75 , 99 , 451 , 207 , 1847 , 1285 , 3217 , 7899 ,0 }; - static ulong[] dim1333Kuo3Init = { 1 , 3 , 7 , 11 , 21 , 63 , 87 , 11 , 429 , 591 , 1471 , 3221 , 2441 , 2889 ,0 }; - static ulong[] dim1334Kuo3Init = { 1 , 3 , 1 , 15 , 3 , 47 , 103 , 219 , 317 , 605 , 1709 , 2473 , 3511 , 10035 ,0 }; - static ulong[] dim1335Kuo3Init = { 1 , 1 , 5 , 3 , 13 , 21 , 117 , 113 , 443 , 863 , 201 , 1293 , 1291 , 5537 ,0 }; - static ulong[] dim1336Kuo3Init = { 1 , 1 , 7 , 7 , 3 , 15 , 59 , 45 , 135 , 465 , 1033 , 605 , 2783 , 1001 ,0 }; - static ulong[] dim1337Kuo3Init = { 1 , 3 , 1 , 13 , 25 , 49 , 125 , 171 , 231 , 691 , 1759 , 3493 , 1703 , 4405 ,0 }; - static ulong[] dim1338Kuo3Init = { 1 , 1 , 5 , 11 , 3 , 31 , 73 , 31 , 189 , 533 , 1191 , 487 , 6233 , 5607 ,0 }; - static ulong[] dim1339Kuo3Init = { 1 , 3 , 7 , 5 , 11 , 23 , 91 , 207 , 337 , 225 , 339 , 2085 , 6223 , 16299 ,0 }; - static ulong[] dim1340Kuo3Init = { 1 , 1 , 5 , 13 , 21 , 35 , 47 , 81 , 229 , 815 , 767 , 1939 , 1335 , 1865 ,0 }; - static ulong[] dim1341Kuo3Init = { 1 , 1 , 5 , 9 , 3 , 11 , 19 , 253 , 499 , 13 , 1771 , 1461 , 2339 , 1217 ,0 }; - static ulong[] dim1342Kuo3Init = { 1 , 1 , 1 , 7 , 15 , 51 , 91 , 213 , 435 , 137 , 551 , 3483 , 1485 , 4061 ,0 }; - static ulong[] dim1343Kuo3Init = { 1 , 3 , 3 , 9 , 23 , 25 , 57 , 1 , 147 , 705 , 399 , 3061 , 5921 , 4201 ,0 }; - static ulong[] dim1344Kuo3Init = { 1 , 3 , 3 , 9 , 9 , 15 , 53 , 105 , 175 , 147 , 1077 , 2323 , 6041 , 9591 ,0 }; - static ulong[] dim1345Kuo3Init = { 1 , 1 , 5 , 9 , 5 , 17 , 125 , 243 , 5 , 329 , 161 , 795 , 8105 , 8385 ,0 }; - static ulong[] dim1346Kuo3Init = { 1 , 3 , 1 , 13 , 9 , 7 , 83 , 49 , 83 , 109 , 759 , 2197 , 2587 , 10715 ,0 }; - static ulong[] dim1347Kuo3Init = { 1 , 3 , 3 , 9 , 17 , 11 , 33 , 173 , 133 , 853 , 1005 , 3027 , 2137 , 14471 ,0 }; - static ulong[] dim1348Kuo3Init = { 1 , 3 , 7 , 9 , 23 , 19 , 29 , 169 , 73 , 405 , 1175 , 3179 , 2449 , 13447 ,0 }; - static ulong[] dim1349Kuo3Init = { 1 , 1 , 7 , 1 , 21 , 43 , 1 , 85 , 387 , 979 , 571 , 1849 , 3287 , 1201 ,0 }; - static ulong[] dim1350Kuo3Init = { 1 , 1 , 5 , 13 , 15 , 43 , 125 , 49 , 365 , 689 , 1569 , 719 , 3925 , 3781 ,0 }; - static ulong[] dim1351Kuo3Init = { 1 , 1 , 7 , 1 , 11 , 5 , 39 , 181 , 39 , 729 , 641 , 1983 , 7321 , 14747 ,0 }; - static ulong[] dim1352Kuo3Init = { 1 , 3 , 7 , 11 , 11 , 9 , 115 , 125 , 305 , 371 , 1647 , 463 , 2473 , 9029 ,0 }; - static ulong[] dim1353Kuo3Init = { 1 , 1 , 7 , 15 , 5 , 11 , 69 , 177 , 249 , 235 , 1843 , 695 , 7931 , 10891 ,0 }; - static ulong[] dim1354Kuo3Init = { 1 , 1 , 5 , 11 , 17 , 57 , 127 , 135 , 357 , 315 , 55 , 2867 , 4187 , 15803 ,0 }; - static ulong[] dim1355Kuo3Init = { 1 , 3 , 1 , 13 , 29 , 23 , 69 , 179 , 151 , 813 , 1317 , 1943 , 3995 , 13023 ,0 }; - static ulong[] dim1356Kuo3Init = { 1 , 1 , 7 , 11 , 9 , 55 , 39 , 65 , 3 , 127 , 1781 , 117 , 2651 , 16111 ,0 }; - static ulong[] dim1357Kuo3Init = { 1 , 3 , 5 , 15 , 31 , 19 , 89 , 185 , 351 , 623 , 1301 , 3123 , 5905 , 7231 ,0 }; - static ulong[] dim1358Kuo3Init = { 1 , 3 , 3 , 3 , 31 , 25 , 31 , 163 , 81 , 927 , 1171 , 2667 , 5699 , 7555 ,0 }; - static ulong[] dim1359Kuo3Init = { 1 , 1 , 3 , 13 , 17 , 55 , 83 , 217 , 97 , 795 , 1745 , 875 , 483 , 3271 ,0 }; - static ulong[] dim1360Kuo3Init = { 1 , 1 , 1 , 1 , 9 , 13 , 19 , 207 , 325 , 277 , 1393 , 2619 , 3055 , 8499 ,0 }; - static ulong[] dim1361Kuo3Init = { 1 , 1 , 7 , 5 , 1 , 11 , 113 , 181 , 411 , 55 , 505 , 3125 , 619 , 1749 ,0 }; - static ulong[] dim1362Kuo3Init = { 1 , 3 , 3 , 15 , 11 , 47 , 25 , 123 , 143 , 51 , 1075 , 715 , 4647 , 13995 ,0 }; - static ulong[] dim1363Kuo3Init = { 1 , 1 , 1 , 1 , 21 , 23 , 121 , 217 , 325 , 589 , 2017 , 3027 , 6175 , 1293 ,0 }; - static ulong[] dim1364Kuo3Init = { 1 , 3 , 1 , 9 , 3 , 47 , 35 , 233 , 381 , 905 , 1031 , 2229 , 2575 , 6891 ,0 }; - static ulong[] dim1365Kuo3Init = { 1 , 1 , 1 , 5 , 3 , 33 , 17 , 39 , 377 , 635 , 1281 , 2673 , 2101 , 2921 ,0 }; - static ulong[] dim1366Kuo3Init = { 1 , 1 , 7 , 7 , 13 , 21 , 43 , 55 , 353 , 643 , 533 , 57 , 5583 , 2189 ,0 }; - static ulong[] dim1367Kuo3Init = { 1 , 3 , 5 , 3 , 27 , 15 , 79 , 47 , 463 , 327 , 1231 , 171 , 4931 , 7549 ,0 }; - static ulong[] dim1368Kuo3Init = { 1 , 1 , 5 , 9 , 11 , 27 , 109 , 15 , 57 , 35 , 1347 , 3061 , 8179 , 5461 ,0 }; - static ulong[] dim1369Kuo3Init = { 1 , 3 , 3 , 7 , 29 , 57 , 103 , 221 , 409 , 437 , 1541 , 2591 , 4757 , 13735 ,0 }; - static ulong[] dim1370Kuo3Init = { 1 , 1 , 7 , 1 , 3 , 23 , 115 , 35 , 165 , 389 , 1399 , 2081 , 3169 , 1493 ,0 }; - static ulong[] dim1371Kuo3Init = { 1 , 1 , 3 , 3 , 25 , 27 , 93 , 253 , 83 , 557 , 957 , 2017 , 2005 , 10005 ,0 }; - static ulong[] dim1372Kuo3Init = { 1 , 3 , 7 , 7 , 1 , 33 , 55 , 227 , 427 , 595 , 1235 , 3815 , 5397 , 4827 ,0 }; - static ulong[] dim1373Kuo3Init = { 1 , 3 , 1 , 7 , 31 , 23 , 53 , 155 , 177 , 851 , 531 , 2441 , 2049 , 12209 ,0 }; - static ulong[] dim1374Kuo3Init = { 1 , 1 , 7 , 3 , 21 , 27 , 13 , 67 , 467 , 607 , 611 , 2565 , 5907 , 8441 ,0 }; - static ulong[] dim1375Kuo3Init = { 1 , 1 , 7 , 5 , 31 , 59 , 99 , 65 , 403 , 439 , 1407 , 2587 , 3111 , 8715 ,0 }; - static ulong[] dim1376Kuo3Init = { 1 , 1 , 5 , 13 , 7 , 3 , 35 , 69 , 177 , 591 , 449 , 369 , 5047 , 3435 ,0 }; - static ulong[] dim1377Kuo3Init = { 1 , 3 , 5 , 5 , 17 , 27 , 9 , 49 , 161 , 925 , 603 , 2555 , 3349 , 4913 ,0 }; - static ulong[] dim1378Kuo3Init = { 1 , 1 , 1 , 9 , 11 , 43 , 89 , 139 , 163 , 851 , 1991 , 3439 , 227 , 5875 ,0 }; - static ulong[] dim1379Kuo3Init = { 1 , 3 , 3 , 9 , 15 , 7 , 63 , 133 , 437 , 447 , 1227 , 3945 , 3467 , 14919 ,0 }; - static ulong[] dim1380Kuo3Init = { 1 , 1 , 1 , 7 , 13 , 49 , 113 , 39 , 77 , 773 , 127 , 3361 , 2325 , 987 ,0 }; - static ulong[] dim1381Kuo3Init = { 1 , 1 , 5 , 9 , 31 , 23 , 69 , 203 , 189 , 35 , 647 , 3507 , 6679 , 2097 ,0 }; - static ulong[] dim1382Kuo3Init = { 1 , 3 , 7 , 5 , 23 , 9 , 99 , 253 , 203 , 167 , 1073 , 435 , 1745 , 2155 ,0 }; - static ulong[] dim1383Kuo3Init = { 1 , 1 , 5 , 11 , 11 , 27 , 15 , 125 , 291 , 261 , 1953 , 3695 , 6345 , 8519 ,0 }; - static ulong[] dim1384Kuo3Init = { 1 , 1 , 7 , 11 , 3 , 39 , 23 , 143 , 401 , 587 , 1729 , 3083 , 4255 , 7427 ,0 }; - static ulong[] dim1385Kuo3Init = { 1 , 1 , 7 , 9 , 27 , 7 , 63 , 153 , 349 , 1003 , 1315 , 841 , 5991 , 15647 ,0 }; - static ulong[] dim1386Kuo3Init = { 1 , 3 , 5 , 1 , 27 , 45 , 91 , 245 , 297 , 485 , 647 , 91 , 231 , 5231 ,0 }; - static ulong[] dim1387Kuo3Init = { 1 , 1 , 5 , 15 , 29 , 43 , 53 , 79 , 387 , 977 , 247 , 371 , 5823 , 8335 ,0 }; - static ulong[] dim1388Kuo3Init = { 1 , 3 , 3 , 5 , 5 , 17 , 29 , 71 , 417 , 201 , 1495 , 277 , 2087 , 15421 ,0 }; - static ulong[] dim1389Kuo3Init = { 1 , 3 , 5 , 11 , 7 , 47 , 37 , 171 , 167 , 355 , 1845 , 1747 , 839 , 7213 ,0 }; - static ulong[] dim1390Kuo3Init = { 1 , 1 , 3 , 15 , 15 , 29 , 107 , 35 , 183 , 735 , 183 , 2993 , 6495 , 981 ,0 }; - static ulong[] dim1391Kuo3Init = { 1 , 3 , 1 , 3 , 3 , 25 , 25 , 195 , 461 , 739 , 861 , 3027 , 2007 , 7771 ,0 }; - static ulong[] dim1392Kuo3Init = { 1 , 3 , 7 , 5 , 29 , 55 , 115 , 57 , 67 , 913 , 1603 , 2397 , 949 , 14671 ,0 }; - static ulong[] dim1393Kuo3Init = { 1 , 1 , 1 , 7 , 27 , 15 , 51 , 201 , 127 , 459 , 1545 , 3415 , 1823 , 1673 ,0 }; - static ulong[] dim1394Kuo3Init = { 1 , 3 , 1 , 13 , 21 , 43 , 75 , 59 , 379 , 1007 , 1697 , 763 , 741 , 3801 ,0 }; - static ulong[] dim1395Kuo3Init = { 1 , 1 , 5 , 13 , 13 , 41 , 105 , 235 , 381 , 465 , 665 , 877 , 1025 , 9041 ,0 }; - static ulong[] dim1396Kuo3Init = { 1 , 3 , 3 , 3 , 3 , 63 , 65 , 151 , 167 , 683 , 327 , 3545 , 2531 , 13479 ,0 }; - static ulong[] dim1397Kuo3Init = { 1 , 3 , 5 , 1 , 7 , 25 , 61 , 137 , 155 , 5 , 623 , 649 , 7235 , 13495 ,0 }; - static ulong[] dim1398Kuo3Init = { 1 , 3 , 5 , 1 , 23 , 33 , 3 , 45 , 235 , 909 , 1619 , 2843 , 5307 , 14345 ,0 }; - static ulong[] dim1399Kuo3Init = { 1 , 3 , 3 , 3 , 29 , 1 , 67 , 161 , 237 , 229 , 1403 , 3289 , 399 , 237 ,0 }; - static ulong[] dim1400Kuo3Init = { 1 , 3 , 1 , 7 , 5 , 27 , 83 , 133 , 189 , 277 , 1975 , 1399 , 65 , 13645 ,0 }; - static ulong[] dim1401Kuo3Init = { 1 , 3 , 3 , 9 , 1 , 41 , 11 , 121 , 413 , 413 , 1817 , 1533 , 5299 , 9089 ,0 }; - static ulong[] dim1402Kuo3Init = { 1 , 1 , 1 , 7 , 15 , 59 , 75 , 255 , 419 , 441 , 1993 , 573 , 6025 , 16375 ,0 }; - static ulong[] dim1403Kuo3Init = { 1 , 1 , 1 , 9 , 3 , 35 , 117 , 69 , 473 , 53 , 1007 , 2229 , 1749 , 14795 ,0 }; - static ulong[] dim1404Kuo3Init = { 1 , 1 , 3 , 11 , 23 , 27 , 117 , 183 , 69 , 689 , 1903 , 1851 , 1143 , 11959 ,0 }; - static ulong[] dim1405Kuo3Init = { 1 , 3 , 7 , 13 , 3 , 9 , 125 , 173 , 365 , 393 , 1313 , 3937 , 1699 , 15667 ,0 }; - static ulong[] dim1406Kuo3Init = { 1 , 3 , 5 , 11 , 19 , 3 , 45 , 181 , 439 , 61 , 1139 , 149 , 1929 , 15617 ,0 }; - static ulong[] dim1407Kuo3Init = { 1 , 3 , 7 , 1 , 13 , 41 , 43 , 131 , 79 , 947 , 1579 , 2055 , 451 , 10875 ,0 }; - static ulong[] dim1408Kuo3Init = { 1 , 1 , 1 , 11 , 27 , 11 , 105 , 109 , 503 , 361 , 27 , 133 , 801 , 853 ,0 }; - static ulong[] dim1409Kuo3Init = { 1 , 3 , 5 , 11 , 11 , 43 , 3 , 233 , 449 , 557 , 2003 , 467 , 5617 , 7431 ,0 }; - static ulong[] dim1410Kuo3Init = { 1 , 1 , 3 , 9 , 5 , 31 , 121 , 13 , 301 , 433 , 1719 , 821 , 8107 , 13313 ,0 }; - static ulong[] dim1411Kuo3Init = { 1 , 1 , 5 , 15 , 25 , 17 , 117 , 81 , 239 , 219 , 195 , 2653 , 1287 , 11595 ,0 }; - static ulong[] dim1412Kuo3Init = { 1 , 1 , 3 , 9 , 31 , 37 , 123 , 35 , 507 , 91 , 1345 , 279 , 2369 , 1613 ,0 }; - static ulong[] dim1413Kuo3Init = { 1 , 3 , 3 , 11 , 23 , 9 , 83 , 91 , 257 , 977 , 697 , 3813 , 6839 , 2755 ,0 }; - static ulong[] dim1414Kuo3Init = { 1 , 3 , 5 , 5 , 21 , 23 , 65 , 63 , 407 , 515 , 1817 , 2893 , 7539 , 11803 ,0 }; - static ulong[] dim1415Kuo3Init = { 1 , 3 , 1 , 15 , 5 , 1 , 7 , 195 , 15 , 319 , 1177 , 3191 , 3489 , 6213 ,0 }; - static ulong[] dim1416Kuo3Init = { 1 , 1 , 7 , 5 , 29 , 11 , 97 , 125 , 89 , 1005 , 455 , 3397 , 7345 , 14481 ,0 }; - static ulong[] dim1417Kuo3Init = { 1 , 1 , 5 , 11 , 31 , 37 , 15 , 35 , 405 , 181 , 601 , 543 , 6639 , 16103 ,0 }; - static ulong[] dim1418Kuo3Init = { 1 , 3 , 3 , 1 , 1 , 33 , 127 , 177 , 277 , 681 , 2039 , 3109 , 4657 , 1303 ,0 }; - static ulong[] dim1419Kuo3Init = { 1 , 1 , 5 , 7 , 3 , 61 , 107 , 215 , 175 , 973 , 899 , 3655 , 823 , 7125 ,0 }; - static ulong[] dim1420Kuo3Init = { 1 , 1 , 3 , 1 , 3 , 47 , 87 , 179 , 387 , 987 , 1171 , 2767 , 6329 , 609 ,0 }; - static ulong[] dim1421Kuo3Init = { 1 , 3 , 3 , 11 , 7 , 25 , 33 , 109 , 485 , 789 , 979 , 659 , 2555 , 10175 ,0 }; - static ulong[] dim1422Kuo3Init = { 1 , 1 , 5 , 7 , 15 , 41 , 77 , 69 , 487 , 601 , 753 , 2785 , 1075 , 35 ,0 }; - static ulong[] dim1423Kuo3Init = { 1 , 1 , 1 , 7 , 23 , 3 , 125 , 143 , 463 , 981 , 499 , 1249 , 5461 , 43 ,0 }; - static ulong[] dim1424Kuo3Init = { 1 , 1 , 5 , 11 , 9 , 1 , 55 , 147 , 85 , 857 , 1995 , 3471 , 6115 , 5511 ,0 }; - static ulong[] dim1425Kuo3Init = { 1 , 3 , 3 , 11 , 11 , 25 , 27 , 201 , 497 , 533 , 643 , 2015 , 205 , 13535 ,0 }; - static ulong[] dim1426Kuo3Init = { 1 , 3 , 3 , 3 , 23 , 53 , 77 , 143 , 231 , 335 , 471 , 1821 , 739 , 4727 ,0 }; - static ulong[] dim1427Kuo3Init = { 1 , 3 , 1 , 3 , 13 , 25 , 53 , 61 , 155 , 1013 , 1439 , 1745 , 6393 , 13329 ,0 }; - static ulong[] dim1428Kuo3Init = { 1 , 3 , 7 , 1 , 5 , 11 , 111 , 21 , 357 , 599 , 1213 , 3581 , 1221 , 75 ,0 }; - static ulong[] dim1429Kuo3Init = { 1 , 3 , 7 , 7 , 23 , 45 , 79 , 83 , 97 , 191 , 53 , 2157 , 7737 , 1533 ,0 }; - static ulong[] dim1430Kuo3Init = { 1 , 3 , 1 , 9 , 25 , 17 , 123 , 179 , 151 , 77 , 1903 , 1457 , 1403 , 13557 ,0 }; - static ulong[] dim1431Kuo3Init = { 1 , 3 , 3 , 1 , 23 , 59 , 65 , 47 , 119 , 113 , 133 , 3601 , 7543 , 16289 ,0 }; - static ulong[] dim1432Kuo3Init = { 1 , 3 , 5 , 13 , 17 , 51 , 33 , 39 , 257 , 409 , 659 , 3907 , 7301 , 8893 ,0 }; - static ulong[] dim1433Kuo3Init = { 1 , 1 , 7 , 11 , 31 , 25 , 79 , 245 , 465 , 809 , 1317 , 1109 , 5983 , 4359 ,0 }; - static ulong[] dim1434Kuo3Init = { 1 , 1 , 7 , 7 , 5 , 25 , 83 , 239 , 199 , 497 , 521 , 1527 , 4509 , 12627 ,0 }; - static ulong[] dim1435Kuo3Init = { 1 , 1 , 1 , 11 , 25 , 33 , 97 , 171 , 443 , 75 , 1681 , 407 , 7669 , 14893 ,0 }; - static ulong[] dim1436Kuo3Init = { 1 , 1 , 3 , 13 , 17 , 31 , 53 , 113 , 97 , 653 , 917 , 11 , 5697 , 8083 ,0 }; - static ulong[] dim1437Kuo3Init = { 1 , 1 , 3 , 9 , 19 , 27 , 1 , 155 , 89 , 579 , 951 , 1779 , 343 , 12053 ,0 }; - static ulong[] dim1438Kuo3Init = { 1 , 3 , 7 , 7 , 23 , 29 , 33 , 143 , 181 , 25 , 109 , 3407 , 3255 , 15363 ,0 }; - static ulong[] dim1439Kuo3Init = { 1 , 3 , 3 , 7 , 5 , 47 , 119 , 111 , 315 , 225 , 1655 , 3019 , 4835 , 11641 ,0 }; - static ulong[] dim1440Kuo3Init = { 1 , 1 , 7 , 1 , 19 , 51 , 103 , 219 , 233 , 633 , 1923 , 1523 , 467 , 15363 ,0 }; - static ulong[] dim1441Kuo3Init = { 1 , 1 , 3 , 3 , 11 , 5 , 125 , 143 , 277 , 5 , 1597 , 2445 , 4261 , 12449 ,0 }; - static ulong[] dim1442Kuo3Init = { 1 , 3 , 1 , 1 , 7 , 1 , 103 , 63 , 23 , 65 , 1449 , 3097 , 601 , 12563 ,0 }; - static ulong[] dim1443Kuo3Init = { 1 , 1 , 7 , 13 , 31 , 51 , 23 , 251 , 193 , 227 , 1569 , 439 , 1037 , 8013 ,0 }; - static ulong[] dim1444Kuo3Init = { 1 , 3 , 5 , 5 , 17 , 9 , 45 , 241 , 197 , 787 , 555 , 1951 , 2697 , 725 ,0 }; - static ulong[] dim1445Kuo3Init = { 1 , 3 , 5 , 15 , 9 , 43 , 1 , 211 , 51 , 645 , 1977 , 3085 , 4003 , 10331 ,0 }; - static ulong[] dim1446Kuo3Init = { 1 , 1 , 3 , 11 , 7 , 31 , 89 , 209 , 505 , 753 , 641 , 3177 , 2791 , 10727 ,0 }; - static ulong[] dim1447Kuo3Init = { 1 , 3 , 1 , 1 , 31 , 13 , 53 , 223 , 435 , 51 , 571 , 2033 , 1689 , 67 ,0 }; - static ulong[] dim1448Kuo3Init = { 1 , 3 , 1 , 3 , 21 , 55 , 19 , 31 , 273 , 175 , 1657 , 3399 , 3031 , 10271 ,0 }; - static ulong[] dim1449Kuo3Init = { 1 , 1 , 7 , 9 , 27 , 51 , 87 , 157 , 395 , 57 , 1501 , 2547 , 5061 , 11325 ,0 }; - static ulong[] dim1450Kuo3Init = { 1 , 1 , 1 , 9 , 19 , 43 , 55 , 147 , 193 , 531 , 511 , 4019 , 2317 , 3727 ,0 }; - static ulong[] dim1451Kuo3Init = { 1 , 1 , 1 , 15 , 1 , 15 , 5 , 157 , 335 , 183 , 619 , 2483 , 5817 , 3247 ,0 }; - static ulong[] dim1452Kuo3Init = { 1 , 1 , 1 , 3 , 29 , 59 , 27 , 27 , 355 , 315 , 193 , 707 , 5897 , 4623 ,0 }; - static ulong[] dim1453Kuo3Init = { 1 , 1 , 7 , 1 , 23 , 29 , 33 , 123 , 413 , 317 , 1099 , 1633 , 1619 , 9141 ,0 }; - static ulong[] dim1454Kuo3Init = { 1 , 1 , 5 , 11 , 11 , 49 , 85 , 95 , 73 , 829 , 929 , 2013 , 4653 , 3045 ,0 }; - static ulong[] dim1455Kuo3Init = { 1 , 1 , 1 , 13 , 5 , 63 , 81 , 177 , 23 , 455 , 1527 , 2271 , 2523 , 3711 ,0 }; - static ulong[] dim1456Kuo3Init = { 1 , 3 , 3 , 13 , 9 , 13 , 1 , 241 , 225 , 191 , 933 , 657 , 4557 , 6903 ,0 }; - static ulong[] dim1457Kuo3Init = { 1 , 3 , 3 , 15 , 19 , 29 , 121 , 3 , 235 , 729 , 1705 , 4035 , 5429 , 15339 ,0 }; - static ulong[] dim1458Kuo3Init = { 1 , 1 , 7 , 5 , 3 , 63 , 79 , 89 , 363 , 407 , 325 , 3045 , 7761 , 8855 ,0 }; - static ulong[] dim1459Kuo3Init = { 1 , 3 , 3 , 1 , 13 , 39 , 69 , 119 , 45 , 259 , 577 , 269 , 2977 , 2093 ,0 }; - static ulong[] dim1460Kuo3Init = { 1 , 3 , 3 , 3 , 5 , 9 , 115 , 161 , 319 , 799 , 777 , 459 , 1823 , 10971 ,0 }; - static ulong[] dim1461Kuo3Init = { 1 , 3 , 7 , 9 , 1 , 45 , 31 , 223 , 421 , 389 , 1535 , 1701 , 3739 , 9301 ,0 }; - static ulong[] dim1462Kuo3Init = { 1 , 3 , 5 , 5 , 5 , 49 , 53 , 189 , 101 , 475 , 453 , 1921 , 7161 , 4529 ,0 }; - static ulong[] dim1463Kuo3Init = { 1 , 3 , 5 , 11 , 29 , 37 , 53 , 213 , 371 , 985 , 647 , 765 , 6303 , 10947 ,0 }; - static ulong[] dim1464Kuo3Init = { 1 , 3 , 3 , 15 , 5 , 23 , 51 , 199 , 463 , 11 , 709 , 2083 , 6337 , 1115 ,0 }; - static ulong[] dim1465Kuo3Init = { 1 , 1 , 1 , 1 , 17 , 57 , 1 , 91 , 159 , 1013 , 1229 , 2147 , 571 , 335 ,0 }; - static ulong[] dim1466Kuo3Init = { 1 , 3 , 1 , 11 , 21 , 53 , 119 , 221 , 203 , 467 , 845 , 645 , 7939 , 7257 ,0 }; - static ulong[] dim1467Kuo3Init = { 1 , 1 , 5 , 1 , 9 , 45 , 87 , 213 , 483 , 247 , 1423 , 1855 , 583 , 13339 ,0 }; - static ulong[] dim1468Kuo3Init = { 1 , 1 , 3 , 7 , 13 , 39 , 89 , 87 , 467 , 107 , 185 , 1507 , 755 , 12069 ,0 }; - static ulong[] dim1469Kuo3Init = { 1 , 1 , 5 , 5 , 5 , 49 , 17 , 61 , 483 , 877 , 1887 , 2973 , 6733 , 3241 ,0 }; - static ulong[] dim1470Kuo3Init = { 1 , 1 , 7 , 15 , 31 , 25 , 105 , 215 , 449 , 723 , 973 , 4011 , 1079 , 9713 ,0 }; - static ulong[] dim1471Kuo3Init = { 1 , 3 , 3 , 5 , 23 , 61 , 9 , 85 , 323 , 675 , 101 , 2451 , 5441 , 14371 ,0 }; - static ulong[] dim1472Kuo3Init = { 1 , 1 , 5 , 9 , 1 , 47 , 109 , 177 , 279 , 675 , 867 , 2053 , 6975 , 4829 ,0 }; - static ulong[] dim1473Kuo3Init = { 1 , 3 , 5 , 15 , 23 , 15 , 17 , 49 , 273 , 839 , 779 , 3899 , 3775 , 4289 ,0 }; - static ulong[] dim1474Kuo3Init = { 1 , 3 , 3 , 13 , 3 , 5 , 9 , 83 , 291 , 727 , 2041 , 2221 , 979 , 761 ,0 }; - static ulong[] dim1475Kuo3Init = { 1 , 1 , 5 , 5 , 7 , 5 , 23 , 187 , 293 , 159 , 847 , 697 , 7227 , 9549 ,0 }; - static ulong[] dim1476Kuo3Init = { 1 , 3 , 5 , 7 , 19 , 7 , 77 , 57 , 225 , 443 , 539 , 1531 , 857 , 12997 ,0 }; - static ulong[] dim1477Kuo3Init = { 1 , 3 , 3 , 9 , 9 , 33 , 79 , 137 , 15 , 927 , 1621 , 1241 , 5741 , 13507 ,0 }; - static ulong[] dim1478Kuo3Init = { 1 , 3 , 7 , 7 , 11 , 37 , 87 , 255 , 293 , 649 , 393 , 2549 , 8083 , 13417 ,0 }; - static ulong[] dim1479Kuo3Init = { 1 , 1 , 3 , 5 , 19 , 31 , 47 , 243 , 423 , 663 , 359 , 3293 , 7915 , 16351 ,0 }; - static ulong[] dim1480Kuo3Init = { 1 , 1 , 1 , 11 , 19 , 63 , 87 , 245 , 445 , 975 , 1047 , 935 , 4221 , 851 ,0 }; - static ulong[] dim1481Kuo3Init = { 1 , 3 , 5 , 1 , 19 , 43 , 11 , 85 , 257 , 875 , 369 , 1075 , 1343 , 8487 ,0 }; - static ulong[] dim1482Kuo3Init = { 1 , 1 , 7 , 13 , 29 , 35 , 37 , 201 , 473 , 853 , 185 , 3157 , 6135 , 7631 ,0 }; - static ulong[] dim1483Kuo3Init = { 1 , 1 , 1 , 13 , 13 , 53 , 43 , 55 , 65 , 999 , 729 , 857 , 3645 , 9793 ,0 }; - static ulong[] dim1484Kuo3Init = { 1 , 1 , 3 , 13 , 21 , 47 , 85 , 19 , 1 , 333 , 989 , 327 , 4693 , 3521 ,0 }; - static ulong[] dim1485Kuo3Init = { 1 , 3 , 1 , 13 , 11 , 39 , 101 , 209 , 51 , 53 , 631 , 1439 , 5909 , 9599 ,0 }; - static ulong[] dim1486Kuo3Init = { 1 , 1 , 7 , 15 , 29 , 57 , 21 , 181 , 293 , 807 , 1299 , 1001 , 4265 , 1811 ,0 }; - static ulong[] dim1487Kuo3Init = { 1 , 1 , 5 , 13 , 15 , 1 , 17 , 63 , 213 , 85 , 1025 , 3955 , 2371 , 9065 ,0 }; - static ulong[] dim1488Kuo3Init = { 1 , 1 , 5 , 15 , 13 , 57 , 23 , 169 , 93 , 501 , 7 , 2481 , 123 , 8985 ,0 }; - static ulong[] dim1489Kuo3Init = { 1 , 3 , 3 , 3 , 11 , 61 , 19 , 133 , 175 , 833 , 1753 , 3871 , 8169 , 2771 ,0 }; - static ulong[] dim1490Kuo3Init = { 1 , 3 , 5 , 1 , 11 , 13 , 57 , 55 , 385 , 463 , 785 , 2339 , 7117 , 12519 ,0 }; - static ulong[] dim1491Kuo3Init = { 1 , 1 , 1 , 13 , 15 , 35 , 27 , 179 , 375 , 477 , 1157 , 2067 , 6971 , 8269 ,0 }; - static ulong[] dim1492Kuo3Init = { 1 , 1 , 3 , 11 , 27 , 21 , 57 , 125 , 219 , 433 , 67 , 307 , 7327 , 2915 ,0 }; - static ulong[] dim1493Kuo3Init = { 1 , 3 , 5 , 7 , 21 , 7 , 111 , 21 , 85 , 295 , 1751 , 821 , 1175 , 3109 ,0 }; - static ulong[] dim1494Kuo3Init = { 1 , 1 , 7 , 1 , 7 , 51 , 43 , 119 , 89 , 751 , 835 , 3969 , 861 , 5775 ,0 }; - static ulong[] dim1495Kuo3Init = { 1 , 3 , 1 , 13 , 5 , 37 , 93 , 185 , 435 , 283 , 1221 , 2965 , 2845 , 6025 ,0 }; - static ulong[] dim1496Kuo3Init = { 1 , 1 , 7 , 7 , 31 , 27 , 99 , 143 , 507 , 461 , 1999 , 3743 , 4277 , 13729 ,0 }; - static ulong[] dim1497Kuo3Init = { 1 , 3 , 1 , 13 , 15 , 43 , 99 , 121 , 245 , 73 , 829 , 3887 , 3093 , 16183 ,0 }; - static ulong[] dim1498Kuo3Init = { 1 , 3 , 3 , 7 , 15 , 35 , 29 , 79 , 457 , 695 , 1469 , 1505 , 3891 , 14677 ,0 }; - static ulong[] dim1499Kuo3Init = { 1 , 3 , 7 , 7 , 5 , 59 , 71 , 179 , 305 , 9 , 2043 , 245 , 1291 , 14409 ,0 }; - static ulong[] dim1500Kuo3Init = { 1 , 1 , 3 , 1 , 13 , 7 , 17 , 43 , 367 , 163 , 1649 , 3671 , 2663 , 2277 ,0 }; - static ulong[] dim1501Kuo3Init = { 1 , 1 , 1 , 5 , 9 , 57 , 115 , 177 , 271 , 735 , 263 , 1137 , 2127 , 15367 ,0 }; - static ulong[] dim1502Kuo3Init = { 1 , 3 , 5 , 7 , 17 , 11 , 37 , 197 , 459 , 647 , 307 , 3617 , 3201 , 10293 ,0 }; - static ulong[] dim1503Kuo3Init = { 1 , 1 , 1 , 7 , 31 , 37 , 61 , 59 , 331 , 483 , 1849 , 1737 , 2617 , 5053 ,0 }; - static ulong[] dim1504Kuo3Init = { 1 , 3 , 5 , 13 , 31 , 43 , 31 , 185 , 261 , 249 , 1137 , 1285 , 2885 , 4289 ,0 }; - static ulong[] dim1505Kuo3Init = { 1 , 1 , 7 , 3 , 21 , 53 , 113 , 163 , 209 , 25 , 329 , 2963 , 7849 , 10933 ,0 }; - static ulong[] dim1506Kuo3Init = { 1 , 1 , 5 , 1 , 31 , 23 , 101 , 151 , 173 , 193 , 1267 , 487 , 4701 , 8543 ,0 }; - static ulong[] dim1507Kuo3Init = { 1 , 1 , 1 , 1 , 25 , 33 , 85 , 31 , 433 , 537 , 613 , 1675 , 6997 , 11975 ,0 }; - static ulong[] dim1508Kuo3Init = { 1 , 3 , 7 , 1 , 7 , 59 , 57 , 249 , 511 , 371 , 121 , 3435 , 8029 , 11785 ,0 }; - static ulong[] dim1509Kuo3Init = { 1 , 1 , 7 , 3 , 19 , 61 , 105 , 27 , 217 , 47 , 861 , 2571 , 6203 , 805 ,0 }; - static ulong[] dim1510Kuo3Init = { 1 , 1 , 7 , 13 , 27 , 33 , 41 , 217 , 39 , 917 , 355 , 3083 , 2803 , 747 ,0 }; - static ulong[] dim1511Kuo3Init = { 1 , 3 , 7 , 3 , 23 , 33 , 43 , 27 , 151 , 399 , 1307 , 3269 , 7941 , 195 ,0 }; - static ulong[] dim1512Kuo3Init = { 1 , 1 , 3 , 3 , 3 , 37 , 71 , 111 , 389 , 13 , 1147 , 3649 , 1497 , 10459 ,0 }; - static ulong[] dim1513Kuo3Init = { 1 , 1 , 5 , 5 , 25 , 23 , 19 , 251 , 87 , 347 , 711 , 3379 , 4677 , 5651 ,0 }; - static ulong[] dim1514Kuo3Init = { 1 , 1 , 5 , 3 , 9 , 21 , 51 , 85 , 491 , 67 , 485 , 2099 , 3081 , 11751 ,0 }; - static ulong[] dim1515Kuo3Init = { 1 , 1 , 3 , 15 , 27 , 37 , 75 , 71 , 41 , 823 , 1035 , 133 , 7537 , 129 ,0 }; - static ulong[] dim1516Kuo3Init = { 1 , 1 , 1 , 7 , 31 , 35 , 75 , 223 , 379 , 395 , 2011 , 1403 , 4923 , 391 ,0 }; - static ulong[] dim1517Kuo3Init = { 1 , 1 , 5 , 1 , 19 , 37 , 87 , 109 , 291 , 73 , 355 , 1427 , 741 , 7393 ,0 }; - static ulong[] dim1518Kuo3Init = { 1 , 3 , 3 , 11 , 23 , 1 , 109 , 81 , 319 , 1001 , 1173 , 2529 , 5859 , 3167 ,0 }; - static ulong[] dim1519Kuo3Init = { 1 , 1 , 1 , 7 , 17 , 23 , 121 , 223 , 49 , 203 , 1653 , 1567 , 7795 , 1631 ,0 }; - static ulong[] dim1520Kuo3Init = { 1 , 3 , 1 , 15 , 15 , 61 , 123 , 141 , 127 , 871 , 897 , 533 , 231 , 13767 ,0 }; - static ulong[] dim1521Kuo3Init = { 1 , 3 , 5 , 15 , 5 , 17 , 31 , 5 , 505 , 65 , 587 , 3721 , 5755 , 3865 ,0 }; - static ulong[] dim1522Kuo3Init = { 1 , 1 , 7 , 11 , 27 , 59 , 17 , 17 , 33 , 399 , 1963 , 3135 , 5807 , 2427 ,0 }; - static ulong[] dim1523Kuo3Init = { 1 , 3 , 1 , 3 , 29 , 19 , 77 , 55 , 511 , 569 , 729 , 2893 , 373 , 643 ,0 }; - static ulong[] dim1524Kuo3Init = { 1 , 1 , 5 , 13 , 17 , 17 , 101 , 107 , 449 , 581 , 905 , 3281 , 4487 , 9397 ,0 }; - static ulong[] dim1525Kuo3Init = { 1 , 1 , 7 , 9 , 23 , 3 , 103 , 29 , 291 , 437 , 1417 , 2289 , 3705 , 14439 ,0 }; - static ulong[] dim1526Kuo3Init = { 1 , 3 , 1 , 13 , 11 , 61 , 7 , 87 , 471 , 707 , 1823 , 3971 , 7255 , 14395 ,0 }; - static ulong[] dim1527Kuo3Init = { 1 , 3 , 7 , 13 , 21 , 25 , 125 , 19 , 221 , 885 , 1787 , 3825 , 7661 , 8839 ,0 }; - static ulong[] dim1528Kuo3Init = { 1 , 3 , 5 , 3 , 29 , 39 , 21 , 47 , 475 , 447 , 405 , 3365 , 5545 , 11759 ,0 }; - static ulong[] dim1529Kuo3Init = { 1 , 1 , 7 , 1 , 13 , 11 , 113 , 123 , 411 , 385 , 533 , 4091 , 6451 , 6021 ,0 }; - static ulong[] dim1530Kuo3Init = { 1 , 1 , 3 , 11 , 7 , 7 , 25 , 65 , 105 , 409 , 1837 , 2609 , 6417 , 16111 ,0 }; - static ulong[] dim1531Kuo3Init = { 1 , 3 , 7 , 15 , 25 , 11 , 101 , 151 , 91 , 305 , 865 , 2653 , 3031 , 2295 ,0 }; - static ulong[] dim1532Kuo3Init = { 1 , 1 , 1 , 15 , 11 , 53 , 87 , 203 , 275 , 915 , 281 , 687 , 5857 , 393 ,0 }; - static ulong[] dim1533Kuo3Init = { 1 , 3 , 3 , 5 , 15 , 11 , 97 , 169 , 175 , 325 , 285 , 2287 , 7095 , 5245 ,0 }; - static ulong[] dim1534Kuo3Init = { 1 , 1 , 5 , 13 , 25 , 3 , 31 , 79 , 49 , 637 , 1927 , 2361 , 2233 , 7935 ,0 }; - static ulong[] dim1535Kuo3Init = { 1 , 1 , 3 , 11 , 17 , 41 , 69 , 9 , 441 , 719 , 765 , 689 , 475 , 8613 ,0 }; - static ulong[] dim1536Kuo3Init = { 1 , 1 , 7 , 1 , 9 , 11 , 51 , 175 , 231 , 975 , 1983 , 1389 , 205 , 5051 ,0 }; - static ulong[] dim1537Kuo3Init = { 1 , 1 , 3 , 7 , 17 , 37 , 9 , 193 , 243 , 331 , 1545 , 3905 , 4601 , 7731 ,0 }; - static ulong[] dim1538Kuo3Init = { 1 , 1 , 5 , 9 , 9 , 41 , 27 , 29 , 231 , 775 , 1753 , 1915 , 7247 , 6821 ,0 }; - static ulong[] dim1539Kuo3Init = { 1 , 3 , 7 , 13 , 21 , 9 , 51 , 165 , 313 , 951 , 1897 , 2123 , 2999 , 3171 ,0 }; - static ulong[] dim1540Kuo3Init = { 1 , 1 , 1 , 11 , 25 , 43 , 81 , 249 , 309 , 523 , 373 , 3293 , 6607 , 9495 ,0 }; - static ulong[] dim1541Kuo3Init = { 1 , 1 , 3 , 1 , 15 , 63 , 11 , 139 , 319 , 665 , 1703 , 1669 , 4817 , 3645 ,0 }; - static ulong[] dim1542Kuo3Init = { 1 , 1 , 7 , 1 , 11 , 47 , 117 , 245 , 251 , 341 , 415 , 815 , 7335 , 14297 ,0 }; - static ulong[] dim1543Kuo3Init = { 1 , 1 , 5 , 13 , 19 , 33 , 109 , 191 , 253 , 867 , 1505 , 2629 , 6619 , 7913 ,0 }; - static ulong[] dim1544Kuo3Init = { 1 , 3 , 5 , 1 , 7 , 49 , 53 , 51 , 285 , 25 , 1783 , 2201 , 7603 , 11365 ,0 }; - static ulong[] dim1545Kuo3Init = { 1 , 1 , 3 , 11 , 1 , 49 , 9 , 89 , 365 , 909 , 1563 , 2719 , 6859 , 14135 ,0 }; - static ulong[] dim1546Kuo3Init = { 1 , 1 , 1 , 11 , 17 , 57 , 21 , 165 , 419 , 443 , 1207 , 3821 , 1151 , 14037 ,0 }; - static ulong[] dim1547Kuo3Init = { 1 , 1 , 1 , 3 , 1 , 31 , 97 , 133 , 423 , 993 , 745 , 3559 , 7725 , 2069 ,0 }; - static ulong[] dim1548Kuo3Init = { 1 , 1 , 1 , 7 , 31 , 1 , 65 , 3 , 63 , 255 , 313 , 515 , 455 , 4957 ,0 }; - static ulong[] dim1549Kuo3Init = { 1 , 1 , 1 , 5 , 5 , 31 , 37 , 121 , 201 , 493 , 55 , 3735 , 5019 , 5665 ,0 }; - static ulong[] dim1550Kuo3Init = { 1 , 3 , 3 , 9 , 9 , 57 , 55 , 155 , 171 , 687 , 1415 , 2017 , 7021 , 7409 ,0 }; - static ulong[] dim1551Kuo3Init = { 1 , 3 , 5 , 3 , 15 , 23 , 83 , 79 , 367 , 485 , 1933 , 315 , 2591 , 7609 ,0 }; - static ulong[] dim1552Kuo3Init = { 1 , 3 , 7 , 3 , 25 , 49 , 79 , 15 , 435 , 809 , 265 , 2215 , 7207 , 563 ,0 }; - static ulong[] dim1553Kuo3Init = { 1 , 3 , 7 , 1 , 19 , 61 , 103 , 101 , 51 , 637 , 639 , 55 , 4323 , 179 ,0 }; - static ulong[] dim1554Kuo3Init = { 1 , 3 , 1 , 3 , 23 , 27 , 33 , 79 , 215 , 849 , 331 , 2881 , 2109 , 10309 ,0 }; - static ulong[] dim1555Kuo3Init = { 1 , 3 , 5 , 7 , 21 , 63 , 113 , 237 , 63 , 769 , 63 , 391 , 1433 , 6913 ,0 }; - static ulong[] dim1556Kuo3Init = { 1 , 3 , 3 , 15 , 3 , 53 , 25 , 187 , 313 , 93 , 1499 , 3281 , 557 , 12441 ,0 }; - static ulong[] dim1557Kuo3Init = { 1 , 1 , 1 , 5 , 7 , 27 , 97 , 211 , 5 , 31 , 497 , 1659 , 7061 , 807 ,0 }; - static ulong[] dim1558Kuo3Init = { 1 , 3 , 1 , 9 , 23 , 3 , 39 , 55 , 369 , 197 , 299 , 2529 , 2703 , 247 ,0 }; - static ulong[] dim1559Kuo3Init = { 1 , 3 , 3 , 3 , 15 , 49 , 119 , 241 , 45 , 303 , 1741 , 1077 , 6735 , 8079 ,0 }; - static ulong[] dim1560Kuo3Init = { 1 , 3 , 5 , 5 , 21 , 55 , 91 , 17 , 341 , 123 , 1389 , 2557 , 3667 , 4891 ,0 }; - static ulong[] dim1561Kuo3Init = { 1 , 1 , 7 , 5 , 27 , 21 , 107 , 111 , 85 , 39 , 863 , 1965 , 5173 , 49 ,0 }; - static ulong[] dim1562Kuo3Init = { 1 , 1 , 1 , 5 , 11 , 5 , 15 , 185 , 269 , 711 , 557 , 2021 , 7481 , 4977 ,0 }; - static ulong[] dim1563Kuo3Init = { 1 , 1 , 5 , 9 , 5 , 1 , 93 , 139 , 323 , 915 , 549 , 1345 , 6031 , 3979 ,0 }; - static ulong[] dim1564Kuo3Init = { 1 , 3 , 3 , 7 , 19 , 9 , 57 , 177 , 135 , 65 , 27 , 795 , 4637 , 11977 ,0 }; - static ulong[] dim1565Kuo3Init = { 1 , 3 , 5 , 13 , 7 , 17 , 117 , 35 , 257 , 671 , 1741 , 1993 , 1887 , 8149 ,0 }; - static ulong[] dim1566Kuo3Init = { 1 , 1 , 7 , 13 , 3 , 45 , 5 , 199 , 29 , 227 , 1613 , 835 , 2451 , 13079 ,0 }; - static ulong[] dim1567Kuo3Init = { 1 , 1 , 5 , 15 , 23 , 45 , 87 , 15 , 349 , 843 , 159 , 3283 , 1017 , 15813 ,0 }; - static ulong[] dim1568Kuo3Init = { 1 , 3 , 3 , 3 , 21 , 21 , 31 , 51 , 481 , 49 , 1561 , 2171 , 6025 , 9955 ,0 }; - static ulong[] dim1569Kuo3Init = { 1 , 1 , 1 , 3 , 7 , 51 , 97 , 195 , 5 , 251 , 1509 , 1479 , 1165 , 16375 ,0 }; - static ulong[] dim1570Kuo3Init = { 1 , 3 , 5 , 7 , 7 , 17 , 43 , 101 , 281 , 807 , 2003 , 2821 , 6877 , 2457 ,0 }; - static ulong[] dim1571Kuo3Init = { 1 , 1 , 1 , 1 , 15 , 23 , 59 , 91 , 19 , 933 , 145 , 673 , 4729 , 10369 ,0 }; - static ulong[] dim1572Kuo3Init = { 1 , 3 , 5 , 13 , 31 , 37 , 9 , 219 , 343 , 907 , 1401 , 213 , 5149 , 14171 ,0 }; - static ulong[] dim1573Kuo3Init = { 1 , 3 , 1 , 3 , 17 , 17 , 61 , 181 , 281 , 707 , 113 , 3595 , 67 , 15423 ,0 }; - static ulong[] dim1574Kuo3Init = { 1 , 1 , 5 , 9 , 3 , 51 , 69 , 93 , 375 , 451 , 1181 , 1353 , 939 , 629 ,0 }; - static ulong[] dim1575Kuo3Init = { 1 , 3 , 5 , 11 , 13 , 33 , 113 , 85 , 397 , 823 , 1513 , 283 , 7167 , 4627 ,0 }; - static ulong[] dim1576Kuo3Init = { 1 , 3 , 7 , 9 , 25 , 31 , 5 , 17 , 377 , 429 , 1841 , 3915 , 6023 , 11791 ,0 }; - static ulong[] dim1577Kuo3Init = { 1 , 1 , 1 , 7 , 15 , 35 , 45 , 31 , 427 , 509 , 1827 , 1171 , 7001 , 6419 ,0 }; - static ulong[] dim1578Kuo3Init = { 1 , 1 , 5 , 5 , 7 , 37 , 41 , 35 , 349 , 73 , 171 , 35 , 2333 , 659 ,0 }; - static ulong[] dim1579Kuo3Init = { 1 , 1 , 5 , 15 , 13 , 61 , 53 , 87 , 463 , 143 , 257 , 3151 , 6149 , 10155 ,0 }; - static ulong[] dim1580Kuo3Init = { 1 , 1 , 3 , 9 , 3 , 17 , 29 , 151 , 259 , 881 , 2003 , 1057 , 1867 , 7773 ,0 }; - static ulong[] dim1581Kuo3Init = { 1 , 3 , 3 , 1 , 5 , 55 , 97 , 49 , 473 , 795 , 1545 , 1169 , 187 , 10475 ,0 }; - static ulong[] dim1582Kuo3Init = { 1 , 1 , 3 , 7 , 9 , 11 , 61 , 205 , 71 , 183 , 1551 , 621 , 5715 , 3401 ,0 }; - static ulong[] dim1583Kuo3Init = { 1 , 3 , 7 , 13 , 25 , 41 , 109 , 211 , 189 , 859 , 1681 , 3281 , 8153 , 13303 ,0 }; - static ulong[] dim1584Kuo3Init = { 1 , 1 , 5 , 3 , 13 , 17 , 81 , 151 , 189 , 419 , 1707 , 235 , 355 , 8295 ,0 }; - static ulong[] dim1585Kuo3Init = { 1 , 3 , 3 , 13 , 19 , 33 , 49 , 249 , 347 , 617 , 2037 , 537 , 755 , 5131 ,0 }; - static ulong[] dim1586Kuo3Init = { 1 , 1 , 1 , 13 , 23 , 17 , 93 , 35 , 357 , 523 , 355 , 1159 , 1329 , 7663 ,0 }; - static ulong[] dim1587Kuo3Init = { 1 , 1 , 5 , 15 , 15 , 17 , 81 , 197 , 479 , 405 , 55 , 4095 , 4931 , 7663 ,0 }; - static ulong[] dim1588Kuo3Init = { 1 , 3 , 5 , 13 , 1 , 1 , 17 , 173 , 259 , 191 , 1929 , 2063 , 6623 , 5065 ,0 }; - static ulong[] dim1589Kuo3Init = { 1 , 3 , 5 , 15 , 31 , 21 , 25 , 33 , 233 , 663 , 1687 , 495 , 5223 , 439 ,0 }; - static ulong[] dim1590Kuo3Init = { 1 , 3 , 3 , 5 , 31 , 47 , 43 , 119 , 491 , 893 , 1513 , 2453 , 6131 , 8675 ,0 }; - static ulong[] dim1591Kuo3Init = { 1 , 3 , 5 , 1 , 21 , 51 , 21 , 27 , 35 , 613 , 849 , 3679 , 4089 , 9671 ,0 }; - static ulong[] dim1592Kuo3Init = { 1 , 1 , 3 , 5 , 29 , 53 , 125 , 223 , 415 , 315 , 811 , 513 , 4833 , 10667 ,0 }; - static ulong[] dim1593Kuo3Init = { 1 , 1 , 7 , 11 , 5 , 49 , 87 , 47 , 85 , 115 , 757 , 567 , 3655 , 4009 ,0 }; - static ulong[] dim1594Kuo3Init = { 1 , 3 , 1 , 3 , 9 , 1 , 65 , 179 , 55 , 545 , 467 , 1615 , 4349 , 14745 ,0 }; - static ulong[] dim1595Kuo3Init = { 1 , 3 , 3 , 13 , 7 , 49 , 91 , 133 , 151 , 113 , 1373 , 203 , 2711 , 8045 ,0 }; - static ulong[] dim1596Kuo3Init = { 1 , 1 , 3 , 13 , 13 , 5 , 53 , 181 , 397 , 309 , 1653 , 2987 , 175 , 13419 ,0 }; - static ulong[] dim1597Kuo3Init = { 1 , 1 , 7 , 13 , 19 , 35 , 17 , 177 , 77 , 1011 , 1667 , 3083 , 7977 , 14925 ,0 }; - static ulong[] dim1598Kuo3Init = { 1 , 1 , 3 , 15 , 25 , 33 , 59 , 21 , 345 , 395 , 1575 , 2173 , 159 , 11799 ,0 }; - static ulong[] dim1599Kuo3Init = { 1 , 3 , 1 , 13 , 3 , 19 , 87 , 135 , 227 , 995 , 1965 , 3469 , 3801 , 1979 ,0 }; - static ulong[] dim1600Kuo3Init = { 1 , 1 , 1 , 15 , 11 , 1 , 51 , 235 , 37 , 695 , 1761 , 275 , 5793 , 4897 ,0 }; - static ulong[] dim1601Kuo3Init = { 1 , 1 , 7 , 5 , 13 , 37 , 123 , 23 , 363 , 377 , 2009 , 2897 , 207 , 15103 ,0 }; - static ulong[] dim1602Kuo3Init = { 1 , 1 , 1 , 15 , 3 , 43 , 49 , 23 , 351 , 429 , 1181 , 2003 , 1397 , 9489 ,0 }; - static ulong[] dim1603Kuo3Init = { 1 , 3 , 7 , 7 , 23 , 61 , 105 , 149 , 183 , 83 , 69 , 121 , 6719 , 4729 ,0 }; - static ulong[] dim1604Kuo3Init = { 1 , 1 , 5 , 11 , 27 , 9 , 119 , 59 , 115 , 207 , 1865 , 3953 , 45 , 9739 ,0 }; - static ulong[] dim1605Kuo3Init = { 1 , 1 , 5 , 5 , 7 , 29 , 81 , 75 , 361 , 589 , 1689 , 49 , 7125 , 10563 ,0 }; - static ulong[] dim1606Kuo3Init = { 1 , 1 , 7 , 7 , 11 , 21 , 43 , 31 , 43 , 991 , 357 , 3707 , 7679 , 4305 ,0 }; - static ulong[] dim1607Kuo3Init = { 1 , 1 , 1 , 3 , 23 , 41 , 33 , 167 , 207 , 1015 , 517 , 1039 , 4831 , 753 ,0 }; - static ulong[] dim1608Kuo3Init = { 1 , 3 , 7 , 9 , 1 , 29 , 25 , 227 , 5 , 935 , 1201 , 2781 , 6947 , 1597 ,0 }; - static ulong[] dim1609Kuo3Init = { 1 , 1 , 1 , 11 , 13 , 27 , 79 , 175 , 25 , 681 , 1805 , 1435 , 7325 , 10439 ,0 }; - static ulong[] dim1610Kuo3Init = { 1 , 3 , 5 , 15 , 25 , 21 , 105 , 175 , 501 , 43 , 19 , 965 , 255 , 4177 ,0 }; - static ulong[] dim1611Kuo3Init = { 1 , 3 , 7 , 9 , 1 , 27 , 115 , 105 , 43 , 181 , 181 , 3747 , 3827 , 13451 ,0 }; - static ulong[] dim1612Kuo3Init = { 1 , 1 , 5 , 1 , 15 , 27 , 49 , 57 , 361 , 911 , 1735 , 3815 , 5935 , 11793 ,0 }; - static ulong[] dim1613Kuo3Init = { 1 , 3 , 7 , 11 , 23 , 7 , 103 , 83 , 343 , 59 , 1383 , 945 , 4839 , 1475 ,0 }; - static ulong[] dim1614Kuo3Init = { 1 , 1 , 3 , 9 , 13 , 17 , 15 , 129 , 449 , 645 , 719 , 283 , 7911 , 14961 ,0 }; - static ulong[] dim1615Kuo3Init = { 1 , 3 , 1 , 13 , 1 , 35 , 27 , 15 , 177 , 983 , 1537 , 2439 , 7459 , 7107 ,0 }; - static ulong[] dim1616Kuo3Init = { 1 , 1 , 7 , 3 , 25 , 45 , 3 , 163 , 149 , 285 , 917 , 2233 , 7463 , 15869 ,0 }; - static ulong[] dim1617Kuo3Init = { 1 , 1 , 5 , 9 , 3 , 3 , 45 , 175 , 367 , 261 , 723 , 3273 , 5611 , 3323 ,0 }; - static ulong[] dim1618Kuo3Init = { 1 , 1 , 5 , 15 , 25 , 25 , 9 , 189 , 437 , 807 , 801 , 3655 , 5759 , 9099 ,0 }; - static ulong[] dim1619Kuo3Init = { 1 , 3 , 5 , 3 , 27 , 37 , 37 , 177 , 313 , 179 , 1897 , 1299 , 8041 , 10523 ,0 }; - static ulong[] dim1620Kuo3Init = { 1 , 1 , 3 , 13 , 7 , 61 , 105 , 125 , 343 , 201 , 1089 , 43 , 5645 , 7547 ,0 }; - static ulong[] dim1621Kuo3Init = { 1 , 1 , 3 , 9 , 17 , 9 , 69 , 199 , 333 , 791 , 1611 , 1273 , 7193 , 6575 ,0 }; - static ulong[] dim1622Kuo3Init = { 1 , 3 , 1 , 7 , 7 , 63 , 79 , 225 , 89 , 391 , 503 , 3199 , 1409 , 4669 ,0 }; - static ulong[] dim1623Kuo3Init = { 1 , 1 , 1 , 3 , 29 , 7 , 3 , 119 , 361 , 269 , 205 , 1253 , 113 , 9665 ,0 }; - static ulong[] dim1624Kuo3Init = { 1 , 3 , 7 , 13 , 13 , 59 , 53 , 75 , 467 , 317 , 815 , 3401 , 7223 , 8237 ,0 }; - static ulong[] dim1625Kuo3Init = { 1 , 1 , 7 , 1 , 7 , 15 , 49 , 191 , 333 , 1017 , 399 , 55 , 931 , 14979 ,0 }; - static ulong[] dim1626Kuo3Init = { 1 , 3 , 1 , 11 , 23 , 5 , 113 , 47 , 105 , 341 , 615 , 81 , 7393 , 1037 ,0 }; - static ulong[] dim1627Kuo3Init = { 1 , 3 , 5 , 11 , 3 , 29 , 95 , 3 , 275 , 257 , 613 , 1627 , 695 , 5929 ,0 }; - static ulong[] dim1628Kuo3Init = { 1 , 3 , 5 , 5 , 11 , 31 , 57 , 83 , 77 , 573 , 969 , 1237 , 7449 , 13959 ,0 }; - static ulong[] dim1629Kuo3Init = { 1 , 3 , 3 , 5 , 31 , 47 , 51 , 37 , 123 , 817 , 1293 , 771 , 4241 , 3007 ,0 }; - static ulong[] dim1630Kuo3Init = { 1 , 1 , 1 , 13 , 9 , 13 , 23 , 111 , 311 , 213 , 1217 , 2187 , 5709 , 6891 ,0 }; - static ulong[] dim1631Kuo3Init = { 1 , 1 , 3 , 1 , 7 , 37 , 29 , 67 , 109 , 747 , 723 , 2631 , 649 , 13007 ,0 }; - static ulong[] dim1632Kuo3Init = { 1 , 3 , 5 , 3 , 5 , 55 , 121 , 203 , 69 , 515 , 767 , 861 , 7189 , 3327 ,0 }; - static ulong[] dim1633Kuo3Init = { 1 , 3 , 7 , 13 , 27 , 53 , 91 , 65 , 247 , 257 , 799 , 3115 , 6301 , 15527 ,0 }; - static ulong[] dim1634Kuo3Init = { 1 , 3 , 1 , 7 , 27 , 29 , 19 , 95 , 343 , 265 , 53 , 3227 , 8011 , 10223 ,0 }; - static ulong[] dim1635Kuo3Init = { 1 , 3 , 1 , 7 , 23 , 31 , 89 , 43 , 455 , 581 , 2023 , 845 , 7765 , 4811 ,0 }; - static ulong[] dim1636Kuo3Init = { 1 , 3 , 3 , 15 , 31 , 37 , 117 , 173 , 343 , 971 , 491 , 1447 , 1547 , 6737 ,0 }; - static ulong[] dim1637Kuo3Init = { 1 , 3 , 1 , 1 , 7 , 43 , 75 , 67 , 407 , 697 , 51 , 207 , 2499 , 9681 ,0 }; - static ulong[] dim1638Kuo3Init = { 1 , 1 , 3 , 7 , 17 , 27 , 55 , 3 , 237 , 983 , 1 , 1227 , 2605 , 8441 ,0 }; - static ulong[] dim1639Kuo3Init = { 1 , 1 , 1 , 7 , 3 , 31 , 47 , 65 , 119 , 823 , 1055 , 1047 , 6067 , 4267 ,0 }; - static ulong[] dim1640Kuo3Init = { 1 , 3 , 1 , 15 , 9 , 11 , 41 , 211 , 249 , 739 , 953 , 1365 , 4749 , 3723 ,0 }; - static ulong[] dim1641Kuo3Init = { 1 , 1 , 5 , 5 , 25 , 29 , 31 , 75 , 207 , 395 , 1843 , 1737 , 387 , 11871 ,0 }; - static ulong[] dim1642Kuo3Init = { 1 , 1 , 5 , 15 , 21 , 5 , 3 , 221 , 223 , 975 , 743 , 2217 , 7743 , 4667 ,0 }; - static ulong[] dim1643Kuo3Init = { 1 , 1 , 5 , 1 , 23 , 63 , 113 , 149 , 427 , 499 , 1259 , 735 , 2839 , 503 ,0 }; - static ulong[] dim1644Kuo3Init = { 1 , 3 , 5 , 5 , 19 , 47 , 53 , 205 , 385 , 409 , 475 , 265 , 8183 , 11709 ,0 }; - static ulong[] dim1645Kuo3Init = { 1 , 3 , 7 , 7 , 21 , 25 , 91 , 143 , 373 , 967 , 1735 , 1149 , 3077 , 8809 ,0 }; - static ulong[] dim1646Kuo3Init = { 1 , 3 , 1 , 1 , 23 , 39 , 39 , 89 , 241 , 181 , 1819 , 3431 , 1605 , 2143 ,0 }; - static ulong[] dim1647Kuo3Init = { 1 , 1 , 7 , 13 , 27 , 21 , 69 , 35 , 327 , 233 , 495 , 157 , 5961 , 15785 ,0 }; - static ulong[] dim1648Kuo3Init = { 1 , 1 , 5 , 15 , 1 , 29 , 77 , 249 , 471 , 31 , 1805 , 1431 , 1703 , 3593 ,0 }; - static ulong[] dim1649Kuo3Init = { 1 , 3 , 1 , 13 , 13 , 31 , 15 , 89 , 35 , 143 , 487 , 4047 , 7681 , 1557 ,0 }; - static ulong[] dim1650Kuo3Init = { 1 , 1 , 5 , 3 , 21 , 3 , 81 , 1 , 15 , 531 , 1443 , 2421 , 4465 , 4431 ,0 }; - static ulong[] dim1651Kuo3Init = { 1 , 1 , 1 , 13 , 5 , 25 , 83 , 1 , 47 , 723 , 1427 , 1013 , 1525 , 8877 ,0 }; - static ulong[] dim1652Kuo3Init = { 1 , 1 , 5 , 15 , 25 , 23 , 71 , 87 , 13 , 543 , 1715 , 2449 , 4639 , 8339 ,0 }; - static ulong[] dim1653Kuo3Init = { 1 , 1 , 7 , 9 , 1 , 27 , 101 , 129 , 81 , 747 , 1745 , 2545 , 455 , 14103 ,0 }; - static ulong[] dim1654Kuo3Init = { 1 , 1 , 1 , 11 , 23 , 59 , 125 , 49 , 323 , 989 , 1959 , 2349 , 2835 , 115 ,0 }; - static ulong[] dim1655Kuo3Init = { 1 , 3 , 1 , 11 , 29 , 23 , 31 , 185 , 273 , 43 , 1093 , 323 , 751 , 7473 ,0 }; - static ulong[] dim1656Kuo3Init = { 1 , 1 , 5 , 7 , 3 , 51 , 65 , 231 , 147 , 69 , 1635 , 1593 , 7385 , 1251 ,0 }; - static ulong[] dim1657Kuo3Init = { 1 , 1 , 3 , 7 , 21 , 7 , 109 , 61 , 387 , 819 , 417 , 1393 , 5535 , 12201 ,0 }; - static ulong[] dim1658Kuo3Init = { 1 , 3 , 1 , 1 , 11 , 17 , 41 , 61 , 361 , 891 , 69 , 935 , 2793 , 1631 ,0 }; - static ulong[] dim1659Kuo3Init = { 1 , 3 , 3 , 13 , 25 , 31 , 43 , 47 , 247 , 723 , 1703 , 1499 , 139 , 8809 ,0 }; - static ulong[] dim1660Kuo3Init = { 1 , 3 , 5 , 1 , 9 , 47 , 45 , 117 , 95 , 345 , 1431 , 975 , 6575 , 1213 ,0 }; - static ulong[] dim1661Kuo3Init = { 1 , 3 , 1 , 13 , 29 , 37 , 45 , 91 , 443 , 471 , 1363 , 1839 , 6263 , 3289 ,0 }; - static ulong[] dim1662Kuo3Init = { 1 , 1 , 3 , 5 , 17 , 17 , 57 , 193 , 477 , 283 , 1307 , 967 , 1793 , 12551 ,0 }; - static ulong[] dim1663Kuo3Init = { 1 , 1 , 1 , 7 , 17 , 1 , 103 , 67 , 113 , 805 , 1993 , 3019 , 1911 , 11961 ,0 }; - static ulong[] dim1664Kuo3Init = { 1 , 1 , 3 , 1 , 23 , 47 , 19 , 137 , 511 , 685 , 1525 , 1703 , 2513 , 12541 ,0 }; - static ulong[] dim1665Kuo3Init = { 1 , 3 , 3 , 3 , 3 , 7 , 29 , 45 , 279 , 855 , 1931 , 2261 , 2097 , 2373 ,0 }; - static ulong[] dim1666Kuo3Init = { 1 , 3 , 7 , 13 , 13 , 23 , 105 , 119 , 473 , 809 , 925 , 3295 , 7547 , 4229 ,0 }; - static ulong[] dim1667Kuo3Init = { 1 , 1 , 1 , 9 , 27 , 37 , 3 , 109 , 257 , 743 , 1233 , 2973 , 3313 , 2949 ,0 }; - static ulong[] dim1668Kuo3Init = { 1 , 3 , 7 , 13 , 25 , 37 , 103 , 157 , 333 , 127 , 1893 , 649 , 7773 , 15639 ,0 }; - static ulong[] dim1669Kuo3Init = { 1 , 1 , 1 , 11 , 13 , 53 , 21 , 67 , 161 , 859 , 1715 , 3303 , 2527 , 9487 ,0 }; - static ulong[] dim1670Kuo3Init = { 1 , 1 , 7 , 3 , 7 , 27 , 47 , 173 , 103 , 413 , 719 , 2865 , 2337 , 2963 ,0 }; - static ulong[] dim1671Kuo3Init = { 1 , 1 , 5 , 11 , 25 , 17 , 3 , 105 , 85 , 731 , 933 , 3967 , 279 , 14649 ,0 }; - static ulong[] dim1672Kuo3Init = { 1 , 1 , 7 , 5 , 11 , 15 , 37 , 197 , 443 , 667 , 1373 , 2961 , 615 , 6011 ,0 }; - static ulong[] dim1673Kuo3Init = { 1 , 1 , 3 , 9 , 11 , 45 , 9 , 43 , 339 , 203 , 27 , 3047 , 6531 , 1071 ,0 }; - static ulong[] dim1674Kuo3Init = { 1 , 1 , 3 , 9 , 1 , 23 , 111 , 185 , 485 , 425 , 2043 , 3375 , 4037 , 8751 ,0 }; - static ulong[] dim1675Kuo3Init = { 1 , 1 , 7 , 7 , 21 , 35 , 37 , 87 , 393 , 149 , 1475 , 4027 , 8125 , 16021 ,0 }; - static ulong[] dim1676Kuo3Init = { 1 , 1 , 3 , 11 , 21 , 51 , 125 , 229 , 49 , 611 , 919 , 3103 , 7239 , 3553 ,0 }; - static ulong[] dim1677Kuo3Init = { 1 , 3 , 7 , 5 , 5 , 27 , 77 , 99 , 313 , 667 , 413 , 1933 , 7977 , 8903 ,0 }; - static ulong[] dim1678Kuo3Init = { 1 , 3 , 3 , 9 , 5 , 47 , 47 , 99 , 181 , 253 , 433 , 3385 , 5789 , 9043 ,0 }; - static ulong[] dim1679Kuo3Init = { 1 , 3 , 3 , 13 , 9 , 9 , 117 , 51 , 93 , 615 , 1159 , 251 , 3345 , 925 ,0 }; - static ulong[] dim1680Kuo3Init = { 1 , 3 , 1 , 7 , 21 , 27 , 75 , 201 , 489 , 901 , 643 , 2511 , 3803 , 11525 ,0 }; - static ulong[] dim1681Kuo3Init = { 1 , 3 , 3 , 1 , 15 , 27 , 117 , 1 , 69 , 1019 , 1853 , 3745 , 3549 , 5721 ,0 }; - static ulong[] dim1682Kuo3Init = { 1 , 3 , 7 , 7 , 23 , 63 , 113 , 235 , 315 , 613 , 1691 , 2725 , 2941 , 11339 ,0 }; - static ulong[] dim1683Kuo3Init = { 1 , 1 , 3 , 15 , 19 , 1 , 3 , 157 , 251 , 443 , 217 , 2229 , 6723 , 15045 ,0 }; - static ulong[] dim1684Kuo3Init = { 1 , 1 , 1 , 3 , 1 , 1 , 93 , 133 , 69 , 897 , 197 , 2241 , 1727 , 3645 ,0 }; - static ulong[] dim1685Kuo3Init = { 1 , 3 , 3 , 15 , 31 , 33 , 83 , 21 , 3 , 243 , 1857 , 1343 , 1359 , 2631 ,0 }; - static ulong[] dim1686Kuo3Init = { 1 , 1 , 5 , 13 , 27 , 17 , 1 , 147 , 113 , 849 , 1899 , 1037 , 5029 , 6829 ,0 }; - static ulong[] dim1687Kuo3Init = { 1 , 3 , 1 , 1 , 21 , 3 , 95 , 69 , 425 , 185 , 1983 , 3887 , 843 , 14881 ,0 }; - static ulong[] dim1688Kuo3Init = { 1 , 3 , 5 , 13 , 11 , 31 , 49 , 35 , 349 , 429 , 1173 , 3783 , 7979 , 13651 ,0 }; - static ulong[] dim1689Kuo3Init = { 1 , 1 , 5 , 11 , 25 , 13 , 49 , 97 , 293 , 661 , 387 , 79 , 5863 , 9315 ,0 }; - static ulong[] dim1690Kuo3Init = { 1 , 1 , 5 , 3 , 27 , 25 , 9 , 51 , 185 , 569 , 1129 , 2657 , 6609 , 8383 ,0 }; - static ulong[] dim1691Kuo3Init = { 1 , 1 , 1 , 11 , 29 , 7 , 67 , 77 , 77 , 661 , 259 , 2365 , 3649 , 9989 ,0 }; - static ulong[] dim1692Kuo3Init = { 1 , 1 , 5 , 9 , 29 , 59 , 43 , 241 , 279 , 177 , 721 , 1329 , 3709 , 8987 ,0 }; - static ulong[] dim1693Kuo3Init = { 1 , 3 , 5 , 7 , 25 , 35 , 51 , 213 , 367 , 735 , 11 , 1061 , 497 , 13593 ,0 }; - static ulong[] dim1694Kuo3Init = { 1 , 1 , 1 , 9 , 1 , 39 , 79 , 31 , 497 , 799 , 1575 , 2627 , 2821 , 4815 ,0 }; - static ulong[] dim1695Kuo3Init = { 1 , 3 , 7 , 7 , 15 , 31 , 99 , 199 , 369 , 829 , 721 , 3509 , 3973 , 9491 ,0 }; - static ulong[] dim1696Kuo3Init = { 1 , 1 , 1 , 15 , 7 , 49 , 125 , 249 , 295 , 907 , 1243 , 155 , 2519 , 2295 ,0 }; - static ulong[] dim1697Kuo3Init = { 1 , 3 , 7 , 9 , 7 , 1 , 63 , 141 , 505 , 865 , 1389 , 1041 , 191 , 4109 ,0 }; - static ulong[] dim1698Kuo3Init = { 1 , 3 , 5 , 13 , 5 , 45 , 5 , 53 , 77 , 525 , 579 , 3077 , 6737 , 6839 ,0 }; - static ulong[] dim1699Kuo3Init = { 1 , 1 , 3 , 5 , 23 , 5 , 127 , 61 , 421 , 353 , 589 , 4095 , 2841 , 8095 ,0 }; - static ulong[] dim1700Kuo3Init = { 1 , 1 , 7 , 9 , 3 , 11 , 49 , 103 , 75 , 403 , 441 , 3513 , 6535 , 7811 ,0 }; - static ulong[] dim1701Kuo3Init = { 1 , 3 , 7 , 13 , 21 , 57 , 115 , 59 , 341 , 673 , 759 , 81 , 6585 , 9727 ,0 }; - static ulong[] dim1702Kuo3Init = { 1 , 1 , 3 , 7 , 29 , 33 , 35 , 201 , 149 , 41 , 175 , 1355 , 5311 , 85 ,0 }; - static ulong[] dim1703Kuo3Init = { 1 , 3 , 1 , 1 , 31 , 5 , 51 , 83 , 225 , 123 , 1347 , 2017 , 6259 , 1553 ,0 }; - static ulong[] dim1704Kuo3Init = { 1 , 1 , 5 , 1 , 17 , 57 , 77 , 1 , 393 , 875 , 887 , 1 , 4007 , 6391 ,0 }; - static ulong[] dim1705Kuo3Init = { 1 , 1 , 3 , 5 , 3 , 31 , 83 , 167 , 511 , 19 , 525 , 323 , 6991 , 10411 ,0 }; - static ulong[] dim1706Kuo3Init = { 1 , 1 , 7 , 9 , 15 , 61 , 77 , 189 , 43 , 651 , 305 , 3107 , 6433 , 3035 ,0 }; - static ulong[] dim1707Kuo3Init = { 1 , 3 , 1 , 11 , 25 , 15 , 51 , 233 , 395 , 867 , 145 , 2215 , 917 , 13815 ,0 }; - static ulong[] dim1708Kuo3Init = { 1 , 3 , 1 , 13 , 23 , 15 , 3 , 103 , 439 , 691 , 283 , 3917 , 5525 , 11007 ,0 }; - static ulong[] dim1709Kuo3Init = { 1 , 3 , 7 , 11 , 11 , 49 , 39 , 31 , 127 , 521 , 1327 , 43 , 1509 , 679 ,0 }; - static ulong[] dim1710Kuo3Init = { 1 , 1 , 7 , 5 , 17 , 27 , 17 , 181 , 337 , 85 , 1687 , 3245 , 5315 , 5653 ,0 }; - static ulong[] dim1711Kuo3Init = { 1 , 3 , 5 , 15 , 31 , 33 , 3 , 229 , 103 , 337 , 1337 , 1961 , 6053 , 8661 ,0 }; - static ulong[] dim1712Kuo3Init = { 1 , 3 , 1 , 7 , 31 , 63 , 15 , 135 , 77 , 583 , 697 , 1353 , 6543 , 291 ,0 }; - static ulong[] dim1713Kuo3Init = { 1 , 3 , 7 , 9 , 17 , 53 , 55 , 59 , 149 , 995 , 1059 , 1829 , 7759 , 10901 ,0 }; - static ulong[] dim1714Kuo3Init = { 1 , 3 , 5 , 7 , 5 , 63 , 51 , 123 , 369 , 861 , 1835 , 3369 , 4555 , 1623 ,0 }; - static ulong[] dim1715Kuo3Init = { 1 , 1 , 3 , 11 , 23 , 31 , 21 , 247 , 417 , 565 , 689 , 1401 , 405 , 6657 ,0 }; - static ulong[] dim1716Kuo3Init = { 1 , 3 , 7 , 7 , 21 , 21 , 37 , 123 , 359 , 133 , 397 , 173 , 2135 , 12407 ,0 }; - static ulong[] dim1717Kuo3Init = { 1 , 1 , 1 , 3 , 1 , 23 , 91 , 97 , 421 , 531 , 975 , 2647 , 4337 , 7775 ,0 }; - static ulong[] dim1718Kuo3Init = { 1 , 1 , 3 , 13 , 5 , 9 , 57 , 149 , 243 , 225 , 79 , 2745 , 523 , 16133 ,0 }; - static ulong[] dim1719Kuo3Init = { 1 , 1 , 1 , 11 , 7 , 5 , 97 , 91 , 15 , 217 , 991 , 1465 , 3975 , 8467 ,0 }; - static ulong[] dim1720Kuo3Init = { 1 , 3 , 7 , 13 , 9 , 61 , 97 , 153 , 411 , 801 , 59 , 603 , 5919 , 9509 ,0 }; - static ulong[] dim1721Kuo3Init = { 1 , 3 , 5 , 7 , 29 , 11 , 71 , 111 , 473 , 985 , 931 , 1211 , 653 , 13933 ,0 }; - static ulong[] dim1722Kuo3Init = { 1 , 1 , 3 , 3 , 29 , 49 , 71 , 105 , 29 , 333 , 1261 , 3791 , 5349 , 15675 ,0 }; - static ulong[] dim1723Kuo3Init = { 1 , 1 , 7 , 13 , 3 , 53 , 73 , 77 , 451 , 547 , 51 , 669 , 7355 , 8325 ,0 }; - static ulong[] dim1724Kuo3Init = { 1 , 1 , 1 , 13 , 7 , 9 , 37 , 87 , 273 , 275 , 191 , 469 , 7529 , 1955 ,0 }; - static ulong[] dim1725Kuo3Init = { 1 , 3 , 5 , 3 , 21 , 5 , 121 , 195 , 327 , 477 , 1661 , 3499 , 7903 , 9053 ,0 }; - static ulong[] dim1726Kuo3Init = { 1 , 3 , 3 , 11 , 29 , 41 , 25 , 13 , 429 , 351 , 723 , 3901 , 5841 , 9783 ,0 }; - static ulong[] dim1727Kuo3Init = { 1 , 3 , 1 , 5 , 1 , 25 , 15 , 203 , 47 , 289 , 67 , 847 , 5547 , 15845 ,0 }; - static ulong[] dim1728Kuo3Init = { 1 , 3 , 3 , 11 , 21 , 7 , 53 , 39 , 461 , 153 , 1739 , 4021 , 307 , 1435 ,0 }; - static ulong[] dim1729Kuo3Init = { 1 , 3 , 5 , 5 , 7 , 17 , 87 , 23 , 47 , 839 , 1841 , 3877 , 2401 , 853 ,0 }; - static ulong[] dim1730Kuo3Init = { 1 , 3 , 3 , 9 , 31 , 37 , 15 , 49 , 171 , 757 , 499 , 1455 , 2151 , 6169 ,0 }; - static ulong[] dim1731Kuo3Init = { 1 , 1 , 5 , 1 , 31 , 19 , 33 , 87 , 507 , 685 , 1765 , 3109 , 7221 , 8047 ,0 }; - static ulong[] dim1732Kuo3Init = { 1 , 1 , 7 , 7 , 23 , 7 , 25 , 45 , 167 , 865 , 465 , 3377 , 7203 , 7825 ,0 }; - static ulong[] dim1733Kuo3Init = { 1 , 3 , 3 , 13 , 15 , 53 , 79 , 111 , 391 , 777 , 367 , 1445 , 5243 , 1929 ,0 }; - static ulong[] dim1734Kuo3Init = { 1 , 1 , 3 , 15 , 11 , 11 , 57 , 115 , 239 , 77 , 797 , 2073 , 831 , 11879 ,0 }; - static ulong[] dim1735Kuo3Init = { 1 , 1 , 7 , 5 , 23 , 11 , 91 , 153 , 29 , 729 , 241 , 2627 , 6447 , 13239 ,0 }; - static ulong[] dim1736Kuo3Init = { 1 , 1 , 7 , 9 , 31 , 11 , 59 , 243 , 105 , 83 , 363 , 3473 , 315 , 2371 ,0 }; - static ulong[] dim1737Kuo3Init = { 1 , 3 , 5 , 1 , 19 , 31 , 111 , 91 , 215 , 697 , 103 , 3323 , 7259 , 13625 ,0 }; - static ulong[] dim1738Kuo3Init = { 1 , 1 , 1 , 11 , 5 , 59 , 83 , 129 , 45 , 223 , 835 , 1965 , 3975 , 15233 ,0 }; - static ulong[] dim1739Kuo3Init = { 1 , 3 , 7 , 11 , 19 , 11 , 31 , 225 , 175 , 209 , 619 , 3127 , 4943 , 9701 ,0 }; - static ulong[] dim1740Kuo3Init = { 1 , 1 , 1 , 3 , 3 , 19 , 21 , 133 , 7 , 151 , 1017 , 3867 , 3699 , 13051 ,0 }; - static ulong[] dim1741Kuo3Init = { 1 , 1 , 5 , 9 , 27 , 17 , 81 , 139 , 439 , 11 , 265 , 659 , 1329 , 4259 ,0 }; - static ulong[] dim1742Kuo3Init = { 1 , 3 , 5 , 1 , 1 , 59 , 105 , 251 , 131 , 817 , 1215 , 3005 , 3417 , 5637 ,0 }; - static ulong[] dim1743Kuo3Init = { 1 , 3 , 3 , 15 , 31 , 37 , 27 , 243 , 225 , 631 , 2023 , 2509 , 249 , 593 ,0 }; - static ulong[] dim1744Kuo3Init = { 1 , 1 , 3 , 11 , 27 , 51 , 89 , 33 , 423 , 423 , 789 , 3627 , 2995 , 8477 ,0 }; - static ulong[] dim1745Kuo3Init = { 1 , 3 , 5 , 5 , 5 , 31 , 69 , 65 , 381 , 375 , 221 , 477 , 3311 , 12103 ,0 }; - static ulong[] dim1746Kuo3Init = { 1 , 3 , 1 , 15 , 31 , 1 , 75 , 97 , 143 , 749 , 581 , 4019 , 4655 , 15571 ,0 }; - static ulong[] dim1747Kuo3Init = { 1 , 3 , 7 , 3 , 1 , 31 , 51 , 151 , 127 , 917 , 975 , 2839 , 3815 , 7405 ,0 }; - static ulong[] dim1748Kuo3Init = { 1 , 3 , 1 , 3 , 9 , 61 , 93 , 49 , 41 , 881 , 1205 , 2425 , 7727 , 2687 ,0 }; - static ulong[] dim1749Kuo3Init = { 1 , 3 , 3 , 3 , 27 , 11 , 99 , 51 , 51 , 937 , 1511 , 3891 , 3955 , 6055 ,0 }; - static ulong[] dim1750Kuo3Init = { 1 , 3 , 3 , 3 , 3 , 27 , 81 , 107 , 409 , 895 , 1869 , 2721 , 1505 , 9877 ,0 }; - static ulong[] dim1751Kuo3Init = { 1 , 1 , 1 , 5 , 11 , 43 , 101 , 7 , 263 , 881 , 1029 , 1491 , 4147 , 10339 ,0 }; - static ulong[] dim1752Kuo3Init = { 1 , 1 , 3 , 11 , 25 , 21 , 85 , 145 , 489 , 335 , 643 , 4019 , 951 , 5885 ,0 }; - static ulong[] dim1753Kuo3Init = { 1 , 1 , 1 , 15 , 3 , 55 , 113 , 87 , 53 , 839 , 381 , 1961 , 3865 , 2841 ,0 }; - static ulong[] dim1754Kuo3Init = { 1 , 1 , 3 , 13 , 11 , 33 , 25 , 95 , 47 , 321 , 649 , 1641 , 1715 , 3815 ,0 }; - static ulong[] dim1755Kuo3Init = { 1 , 1 , 1 , 15 , 23 , 59 , 5 , 3 , 451 , 781 , 867 , 747 , 793 , 6147 ,0 }; - static ulong[] dim1756Kuo3Init = { 1 , 1 , 1 , 15 , 3 , 27 , 31 , 125 , 355 , 837 , 689 , 3599 , 1451 , 2167 ,0 }; - static ulong[] dim1757Kuo3Init = { 1 , 1 , 3 , 9 , 21 , 5 , 101 , 37 , 465 , 115 , 1607 , 2999 , 631 , 1435 ,0 }; - static ulong[] dim1758Kuo3Init = { 1 , 3 , 5 , 9 , 19 , 41 , 91 , 241 , 375 , 707 , 1573 , 105 , 863 , 11273 ,0 }; - static ulong[] dim1759Kuo3Init = { 1 , 1 , 5 , 15 , 17 , 63 , 95 , 83 , 273 , 617 , 1299 , 1259 , 7997 , 5225 ,0 }; - static ulong[] dim1760Kuo3Init = { 1 , 3 , 5 , 9 , 11 , 5 , 127 , 67 , 189 , 733 , 1175 , 3099 , 6561 , 7771 ,0 }; - static ulong[] dim1761Kuo3Init = { 1 , 1 , 7 , 11 , 13 , 45 , 75 , 101 , 279 , 147 , 177 , 225 , 557 , 9413 ,0 }; - static ulong[] dim1762Kuo3Init = { 1 , 3 , 1 , 13 , 11 , 53 , 49 , 71 , 451 , 327 , 567 , 531 , 589 , 15395 ,0 }; - static ulong[] dim1763Kuo3Init = { 1 , 1 , 7 , 13 , 29 , 51 , 95 , 227 , 87 , 171 , 1769 , 2799 , 2589 , 7255 ,0 }; - static ulong[] dim1764Kuo3Init = { 1 , 1 , 5 , 7 , 1 , 51 , 109 , 135 , 99 , 957 , 1681 , 2217 , 2247 , 6567 ,0 }; - static ulong[] dim1765Kuo3Init = { 1 , 1 , 3 , 7 , 27 , 57 , 101 , 51 , 237 , 835 , 1339 , 955 , 5969 , 12511 ,0 }; - static ulong[] dim1766Kuo3Init = { 1 , 1 , 5 , 1 , 21 , 9 , 95 , 247 , 309 , 413 , 17 , 3473 , 3961 , 8555 ,0 }; - static ulong[] dim1767Kuo3Init = { 1 , 1 , 1 , 1 , 21 , 47 , 29 , 33 , 135 , 447 , 1387 , 107 , 4781 , 10987 ,0 }; - static ulong[] dim1768Kuo3Init = { 1 , 1 , 3 , 11 , 5 , 17 , 41 , 103 , 83 , 829 , 1449 , 4047 , 4807 , 7277 ,0 }; - static ulong[] dim1769Kuo3Init = { 1 , 3 , 7 , 15 , 5 , 1 , 75 , 241 , 235 , 701 , 1529 , 1621 , 7995 , 6243 ,0 }; - static ulong[] dim1770Kuo3Init = { 1 , 1 , 3 , 5 , 23 , 49 , 31 , 173 , 83 , 961 , 1293 , 1279 , 2495 , 10805 ,0 }; - static ulong[] dim1771Kuo3Init = { 1 , 1 , 1 , 1 , 15 , 39 , 17 , 81 , 167 , 209 , 685 , 1089 , 7197 , 15773 ,0 }; - static ulong[] dim1772Kuo3Init = { 1 , 1 , 1 , 15 , 29 , 1 , 73 , 113 , 21 , 301 , 1087 , 2529 , 6835 , 8089 ,0 }; - static ulong[] dim1773Kuo3Init = { 1 , 1 , 5 , 15 , 1 , 7 , 99 , 87 , 177 , 537 , 283 , 205 , 6241 , 12489 ,0 }; - static ulong[] dim1774Kuo3Init = { 1 , 3 , 7 , 3 , 11 , 13 , 89 , 43 , 37 , 859 , 263 , 2623 , 6941 , 7433 ,0 }; - static ulong[] dim1775Kuo3Init = { 1 , 3 , 3 , 13 , 9 , 47 , 13 , 155 , 109 , 507 , 343 , 1049 , 4915 , 14873 ,0 }; - static ulong[] dim1776Kuo3Init = { 1 , 1 , 5 , 1 , 5 , 37 , 5 , 71 , 1 , 17 , 417 , 3137 , 3045 , 5835 ,0 }; - static ulong[] dim1777Kuo3Init = { 1 , 3 , 3 , 5 , 15 , 43 , 31 , 235 , 379 , 807 , 89 , 3375 , 123 , 9783 ,0 }; - static ulong[] dim1778Kuo3Init = { 1 , 3 , 5 , 3 , 19 , 23 , 53 , 129 , 493 , 393 , 91 , 2345 , 1959 , 745 ,0 }; - static ulong[] dim1779Kuo3Init = { 1 , 3 , 3 , 13 , 21 , 33 , 31 , 125 , 99 , 167 , 685 , 733 , 6479 , 10391 ,0 }; - static ulong[] dim1780Kuo3Init = { 1 , 1 , 1 , 11 , 1 , 17 , 9 , 245 , 75 , 281 , 1427 , 675 , 5393 , 8841 ,0 }; - static ulong[] dim1781Kuo3Init = { 1 , 1 , 3 , 7 , 15 , 63 , 31 , 83 , 359 , 643 , 77 , 3941 , 5477 , 3435 ,0 }; - static ulong[] dim1782Kuo3Init = { 1 , 1 , 3 , 9 , 31 , 21 , 3 , 111 , 233 , 745 , 1819 , 2617 , 5735 , 15237 ,0 }; - static ulong[] dim1783Kuo3Init = { 1 , 3 , 1 , 9 , 29 , 23 , 99 , 25 , 119 , 69 , 1063 , 651 , 4983 , 14079 ,0 }; - static ulong[] dim1784Kuo3Init = { 1 , 3 , 3 , 3 , 9 , 53 , 47 , 127 , 443 , 113 , 1651 , 2967 , 6633 , 10025 ,0 }; - static ulong[] dim1785Kuo3Init = { 1 , 3 , 7 , 7 , 19 , 11 , 5 , 49 , 23 , 567 , 1095 , 3815 , 4187 , 5305 ,0 }; - static ulong[] dim1786Kuo3Init = { 1 , 1 , 1 , 11 , 29 , 63 , 85 , 147 , 105 , 307 , 1829 , 27 , 7499 , 15661 ,0 }; - static ulong[] dim1787Kuo3Init = { 1 , 3 , 3 , 9 , 15 , 19 , 97 , 65 , 71 , 597 , 551 , 947 , 8047 , 8513 ,0 }; - static ulong[] dim1788Kuo3Init = { 1 , 1 , 5 , 1 , 29 , 31 , 1 , 135 , 159 , 769 , 997 , 3027 , 1485 , 12627 ,0 }; - static ulong[] dim1789Kuo3Init = { 1 , 1 , 3 , 15 , 29 , 47 , 37 , 43 , 45 , 649 , 719 , 1757 , 4619 , 11571 ,0 }; - static ulong[] dim1790Kuo3Init = { 1 , 1 , 1 , 5 , 9 , 9 , 117 , 207 , 107 , 651 , 1155 , 2047 , 7489 , 5959 ,0 }; - static ulong[] dim1791Kuo3Init = { 1 , 3 , 1 , 13 , 29 , 37 , 69 , 243 , 347 , 849 , 1503 , 3985 , 6081 , 1471 ,0 }; - static ulong[] dim1792Kuo3Init = { 1 , 1 , 1 , 11 , 1 , 21 , 107 , 9 , 377 , 147 , 925 , 3055 , 397 , 11337 ,0 }; - static ulong[] dim1793Kuo3Init = { 1 , 3 , 5 , 9 , 27 , 45 , 57 , 177 , 229 , 925 , 855 , 2203 , 8065 , 299 ,0 }; - static ulong[] dim1794Kuo3Init = { 1 , 3 , 1 , 11 , 5 , 1 , 77 , 149 , 339 , 1023 , 89 , 3509 , 4315 , 6571 ,0 }; - static ulong[] dim1795Kuo3Init = { 1 , 1 , 3 , 11 , 19 , 51 , 49 , 191 , 179 , 941 , 1409 , 1789 , 3363 , 11507 ,0 }; - static ulong[] dim1796Kuo3Init = { 1 , 3 , 3 , 13 , 29 , 25 , 47 , 61 , 121 , 243 , 1155 , 3915 , 5397 , 6289 ,0 }; - static ulong[] dim1797Kuo3Init = { 1 , 1 , 1 , 3 , 31 , 55 , 25 , 125 , 239 , 277 , 165 , 3631 , 3609 , 13607 ,0 }; - static ulong[] dim1798Kuo3Init = { 1 , 3 , 1 , 15 , 11 , 23 , 41 , 199 , 239 , 805 , 2021 , 3377 , 3103 , 10657 ,0 }; - static ulong[] dim1799Kuo3Init = { 1 , 1 , 7 , 1 , 27 , 49 , 9 , 219 , 383 , 523 , 1357 , 501 , 733 , 631 ,0 }; - static ulong[] dim1800Kuo3Init = { 1 , 3 , 5 , 13 , 1 , 51 , 125 , 185 , 205 , 231 , 247 , 2579 , 1283 , 3383 ,0 }; - static ulong[] dim1801Kuo3Init = { 1 , 1 , 7 , 13 , 13 , 49 , 81 , 243 , 111 , 219 , 409 , 3755 , 3783 , 8159 ,0 }; - static ulong[] dim1802Kuo3Init = { 1 , 3 , 7 , 5 , 13 , 33 , 109 , 245 , 141 , 391 , 101 , 2043 , 4091 , 379 ,0 }; - static ulong[] dim1803Kuo3Init = { 1 , 1 , 7 , 3 , 27 , 39 , 7 , 223 , 107 , 969 , 1117 , 3599 , 8063 , 7737 ,0 }; - static ulong[] dim1804Kuo3Init = { 1 , 1 , 5 , 5 , 11 , 19 , 9 , 47 , 41 , 571 , 1831 , 3 , 5721 , 14897 ,0 }; - static ulong[] dim1805Kuo3Init = { 1 , 1 , 7 , 5 , 11 , 25 , 75 , 159 , 77 , 843 , 61 , 2283 , 4033 , 15099 ,0 }; - static ulong[] dim1806Kuo3Init = { 1 , 3 , 7 , 1 , 5 , 23 , 57 , 117 , 45 , 373 , 831 , 3047 , 5829 , 3205 ,0 }; - static ulong[] dim1807Kuo3Init = { 1 , 3 , 5 , 11 , 31 , 29 , 45 , 129 , 25 , 519 , 661 , 2033 , 3003 , 12469 ,0 }; - static ulong[] dim1808Kuo3Init = { 1 , 3 , 1 , 15 , 5 , 37 , 55 , 247 , 129 , 299 , 1317 , 3543 , 421 , 12299 ,0 }; - static ulong[] dim1809Kuo3Init = { 1 , 3 , 1 , 9 , 23 , 63 , 5 , 117 , 425 , 883 , 1997 , 1701 , 415 , 3279 ,0 }; - static ulong[] dim1810Kuo3Init = { 1 , 3 , 3 , 5 , 1 , 21 , 23 , 109 , 55 , 377 , 1565 , 2821 , 4995 , 3151 ,0 }; - static ulong[] dim1811Kuo3Init = { 1 , 3 , 7 , 7 , 19 , 39 , 43 , 169 , 141 , 353 , 459 , 2509 , 1503 , 3597 ,0 }; - static ulong[] dim1812Kuo3Init = { 1 , 1 , 1 , 3 , 17 , 55 , 121 , 49 , 229 , 589 , 579 , 2935 , 4647 , 12887 ,0 }; - static ulong[] dim1813Kuo3Init = { 1 , 3 , 3 , 11 , 11 , 47 , 11 , 119 , 83 , 701 , 197 , 583 , 7997 , 11635 ,0 }; - static ulong[] dim1814Kuo3Init = { 1 , 1 , 3 , 5 , 25 , 47 , 85 , 21 , 317 , 887 , 1551 , 2309 , 4227 , 8115 ,0 }; - static ulong[] dim1815Kuo3Init = { 1 , 1 , 3 , 5 , 13 , 23 , 71 , 7 , 419 , 873 , 1423 , 2213 , 7485 , 13237 ,0 }; - static ulong[] dim1816Kuo3Init = { 1 , 3 , 7 , 7 , 25 , 55 , 43 , 141 , 125 , 583 , 451 , 3897 , 4059 , 7409 ,0 }; - static ulong[] dim1817Kuo3Init = { 1 , 1 , 7 , 5 , 19 , 55 , 13 , 61 , 461 , 353 , 981 , 2271 , 4881 , 12761 ,0 }; - static ulong[] dim1818Kuo3Init = { 1 , 3 , 3 , 9 , 31 , 61 , 105 , 105 , 497 , 173 , 1111 , 873 , 1869 , 9027 ,0 }; - static ulong[] dim1819Kuo3Init = { 1 , 1 , 1 , 3 , 31 , 31 , 93 , 119 , 399 , 617 , 1977 , 3913 , 8061 , 13017 ,0 }; - static ulong[] dim1820Kuo3Init = { 1 , 3 , 7 , 9 , 17 , 7 , 89 , 149 , 119 , 791 , 839 , 3643 , 7545 , 13329 ,0 }; - static ulong[] dim1821Kuo3Init = { 1 , 1 , 5 , 1 , 13 , 59 , 35 , 231 , 3 , 703 , 881 , 45 , 5979 , 3249 ,0 }; - static ulong[] dim1822Kuo3Init = { 1 , 1 , 1 , 7 , 1 , 21 , 117 , 105 , 3 , 791 , 1563 , 2303 , 3533 , 7853 ,0 }; - static ulong[] dim1823Kuo3Init = { 1 , 3 , 3 , 5 , 11 , 11 , 109 , 115 , 233 , 471 , 509 , 821 , 7209 , 15463 ,0 }; - static ulong[] dim1824Kuo3Init = { 1 , 1 , 5 , 5 , 13 , 1 , 83 , 99 , 21 , 369 , 751 , 277 , 881 , 8963 ,0 }; - static ulong[] dim1825Kuo3Init = { 1 , 3 , 1 , 1 , 27 , 57 , 3 , 219 , 509 , 337 , 1469 , 2881 , 7911 , 1983 ,0 }; - static ulong[] dim1826Kuo3Init = { 1 , 1 , 7 , 15 , 1 , 25 , 35 , 243 , 243 , 491 , 1031 , 2905 , 4293 , 8387 ,0 }; - static ulong[] dim1827Kuo3Init = { 1 , 1 , 1 , 15 , 5 , 1 , 121 , 71 , 129 , 333 , 1121 , 917 , 6627 , 3291 ,0 }; - static ulong[] dim1828Kuo3Init = { 1 , 3 , 5 , 3 , 7 , 37 , 13 , 7 , 115 , 863 , 345 , 603 , 1471 , 15843 ,0 }; - static ulong[] dim1829Kuo3Init = { 1 , 3 , 7 , 3 , 3 , 49 , 29 , 79 , 185 , 685 , 1691 , 3469 , 7111 , 915 ,0 }; - static ulong[] dim1830Kuo3Init = { 1 , 1 , 3 , 1 , 19 , 61 , 67 , 143 , 133 , 457 , 1865 , 3403 , 2557 , 2603 ,0 }; - static ulong[] dim1831Kuo3Init = { 1 , 1 , 1 , 15 , 27 , 25 , 9 , 87 , 489 , 23 , 1251 , 1995 , 4737 , 3099 ,0 }; - static ulong[] dim1832Kuo3Init = { 1 , 1 , 7 , 11 , 5 , 43 , 55 , 85 , 43 , 621 , 145 , 1507 , 4895 , 687 ,0 }; - static ulong[] dim1833Kuo3Init = { 1 , 3 , 7 , 15 , 7 , 35 , 101 , 19 , 35 , 609 , 1433 , 3877 , 3661 , 2517 ,0 }; - static ulong[] dim1834Kuo3Init = { 1 , 3 , 1 , 5 , 31 , 47 , 89 , 225 , 95 , 941 , 287 , 1163 , 6537 , 10907 ,0 }; - static ulong[] dim1835Kuo3Init = { 1 , 3 , 7 , 1 , 15 , 61 , 65 , 205 , 413 , 147 , 833 , 2097 , 5465 , 6309 ,0 }; - static ulong[] dim1836Kuo3Init = { 1 , 3 , 5 , 11 , 27 , 55 , 37 , 185 , 265 , 343 , 805 , 325 , 283 , 1935 ,0 }; - static ulong[] dim1837Kuo3Init = { 1 , 1 , 3 , 13 , 29 , 7 , 55 , 243 , 101 , 87 , 2015 , 2897 , 2087 , 47 ,0 }; - static ulong[] dim1838Kuo3Init = { 1 , 3 , 5 , 11 , 27 , 1 , 125 , 65 , 205 , 525 , 655 , 3881 , 993 , 3967 ,0 }; - static ulong[] dim1839Kuo3Init = { 1 , 3 , 3 , 9 , 3 , 61 , 85 , 31 , 257 , 257 , 1227 , 3329 , 731 , 7223 ,0 }; - static ulong[] dim1840Kuo3Init = { 1 , 1 , 7 , 15 , 29 , 49 , 49 , 171 , 95 , 475 , 601 , 1325 , 3995 , 14421 ,0 }; - static ulong[] dim1841Kuo3Init = { 1 , 1 , 1 , 11 , 21 , 23 , 97 , 65 , 53 , 417 , 181 , 551 , 6583 , 12835 ,0 }; - static ulong[] dim1842Kuo3Init = { 1 , 3 , 3 , 1 , 27 , 37 , 37 , 143 , 181 , 59 , 1011 , 97 , 2757 , 15537 ,0 }; - static ulong[] dim1843Kuo3Init = { 1 , 3 , 5 , 9 , 5 , 47 , 121 , 91 , 297 , 897 , 813 , 2563 , 1779 , 12675 ,0 }; - static ulong[] dim1844Kuo3Init = { 1 , 3 , 7 , 9 , 17 , 61 , 31 , 47 , 509 , 55 , 1401 , 2251 , 4327 , 10409 ,0 }; - static ulong[] dim1845Kuo3Init = { 1 , 3 , 1 , 3 , 15 , 29 , 97 , 37 , 295 , 271 , 893 , 1135 , 1651 , 9271 ,0 }; - static ulong[] dim1846Kuo3Init = { 1 , 3 , 5 , 15 , 29 , 37 , 65 , 247 , 247 , 341 , 865 , 2163 , 6827 , 1849 ,0 }; - static ulong[] dim1847Kuo3Init = { 1 , 3 , 3 , 11 , 27 , 27 , 105 , 67 , 283 , 221 , 1445 , 3283 , 865 , 3747 ,0 }; - static ulong[] dim1848Kuo3Init = { 1 , 3 , 5 , 7 , 7 , 33 , 63 , 193 , 219 , 357 , 1755 , 2521 , 5375 , 10049 ,0 }; - static ulong[] dim1849Kuo3Init = { 1 , 3 , 5 , 7 , 17 , 43 , 113 , 171 , 237 , 75 , 1257 , 251 , 4681 , 14793 ,0 }; - static ulong[] dim1850Kuo3Init = { 1 , 3 , 5 , 11 , 15 , 15 , 103 , 163 , 61 , 263 , 1165 , 4021 , 6833 , 2675 ,0 }; - static ulong[] dim1851Kuo3Init = { 1 , 3 , 1 , 5 , 21 , 63 , 69 , 29 , 237 , 473 , 1457 , 3545 , 1457 , 7595 ,0 }; - static ulong[] dim1852Kuo3Init = { 1 , 3 , 3 , 1 , 29 , 33 , 85 , 103 , 469 , 579 , 387 , 2113 , 5365 , 7955 ,0 }; - static ulong[] dim1853Kuo3Init = { 1 , 1 , 3 , 13 , 7 , 37 , 99 , 87 , 147 , 401 , 125 , 1233 , 1463 , 15067 ,0 }; - static ulong[] dim1854Kuo3Init = { 1 , 1 , 1 , 3 , 29 , 11 , 17 , 89 , 55 , 273 , 1069 , 203 , 941 , 13667 ,0 }; - static ulong[] dim1855Kuo3Init = { 1 , 3 , 7 , 3 , 3 , 53 , 75 , 163 , 79 , 63 , 1851 , 1495 , 6537 , 6329 ,0 }; - static ulong[] dim1856Kuo3Init = { 1 , 3 , 3 , 3 , 7 , 53 , 39 , 35 , 211 , 275 , 553 , 1247 , 3137 , 11513 ,0 }; - static ulong[] dim1857Kuo3Init = { 1 , 1 , 3 , 15 , 25 , 37 , 15 , 249 , 79 , 227 , 1297 , 277 , 7693 , 2431 ,0 }; - static ulong[] dim1858Kuo3Init = { 1 , 3 , 7 , 3 , 15 , 53 , 61 , 27 , 313 , 817 , 699 , 3743 , 6683 , 11909 ,0 }; - static ulong[] dim1859Kuo3Init = { 1 , 1 , 3 , 7 , 9 , 3 , 77 , 25 , 421 , 403 , 1729 , 1349 , 5995 , 7579 ,0 }; - static ulong[] dim1860Kuo3Init = { 1 , 1 , 7 , 5 , 29 , 25 , 1 , 3 , 69 , 479 , 699 , 1317 , 6729 , 7701 ,0 }; - static ulong[] dim1861Kuo3Init = { 1 , 1 , 1 , 9 , 15 , 51 , 41 , 227 , 195 , 101 , 1783 , 485 , 1157 , 1849 ,0 }; - static ulong[] dim1862Kuo3Init = { 1 , 3 , 3 , 11 , 1 , 31 , 111 , 149 , 361 , 291 , 1353 , 3531 , 473 , 8545 ,0 }; - static ulong[] dim1863Kuo3Init = { 1 , 1 , 1 , 3 , 9 , 35 , 31 , 165 , 175 , 617 , 1063 , 179 , 957 , 1395 ,0 }; - static ulong[] dim1864Kuo3Init = { 1 , 1 , 3 , 1 , 1 , 5 , 21 , 191 , 379 , 293 , 439 , 1575 , 243 , 5013 ,0 }; - static ulong[] dim1865Kuo3Init = { 1 , 3 , 3 , 1 , 1 , 21 , 107 , 91 , 473 , 809 , 993 , 2599 , 8151 , 10927 ,0 }; - static ulong[] dim1866Kuo3Init = { 1 , 1 , 1 , 13 , 13 , 35 , 71 , 37 , 173 , 545 , 1279 , 225 , 3275 , 8823 ,0 }; - static ulong[] dim1867Kuo3Init = { 1 , 3 , 1 , 7 , 3 , 21 , 97 , 23 , 197 , 535 , 741 , 3481 , 919 , 14675 , 14019 ,0 }; - static ulong[] dim1868Kuo3Init = { 1 , 3 , 1 , 3 , 23 , 25 , 73 , 203 , 405 , 287 , 1167 , 2313 , 3065 , 6385 , 16509 ,0 }; - static ulong[] dim1869Kuo3Init = { 1 , 1 , 7 , 15 , 9 , 23 , 59 , 241 , 245 , 865 , 97 , 931 , 3317 , 747 , 14415 ,0 }; - static ulong[] dim1870Kuo3Init = { 1 , 3 , 7 , 13 , 7 , 13 , 73 , 213 , 345 , 707 , 1223 , 517 , 4427 , 9539 , 2669 ,0 }; - static ulong[] dim1871Kuo3Init = { 1 , 1 , 5 , 15 , 29 , 41 , 75 , 149 , 445 , 933 , 1727 , 1967 , 1927 , 1205 , 30051 ,0 }; - static ulong[] dim1872Kuo3Init = { 1 , 1 , 7 , 9 , 17 , 57 , 119 , 115 , 39 , 957 , 309 , 3197 , 6849 , 7151 , 1771 ,0 }; - static ulong[] dim1873Kuo3Init = { 1 , 1 , 3 , 11 , 19 , 57 , 25 , 89 , 223 , 921 , 1741 , 2695 , 3571 , 11933 , 4973 ,0 }; - static ulong[] dim1874Kuo3Init = { 1 , 1 , 3 , 3 , 29 , 37 , 77 , 239 , 63 , 231 , 639 , 1311 , 725 , 5699 , 15709 ,0 }; - static ulong[] dim1875Kuo3Init = { 1 , 3 , 5 , 5 , 31 , 23 , 53 , 27 , 353 , 851 , 685 , 169 , 5325 , 13675 , 21493 ,0 }; - static ulong[] dim1876Kuo3Init = { 1 , 3 , 5 , 9 , 31 , 13 , 37 , 7 , 51 , 211 , 1807 , 3107 , 6485 , 12595 , 1097 ,0 }; - static ulong[] dim1877Kuo3Init = { 1 , 1 , 7 , 15 , 9 , 3 , 33 , 197 , 357 , 841 , 1233 , 2065 , 5009 , 5863 , 11287 ,0 }; - static ulong[] dim1878Kuo3Init = { 1 , 3 , 7 , 9 , 27 , 15 , 75 , 195 , 223 , 689 , 1181 , 1597 , 2553 , 7985 , 13593 ,0 }; - static ulong[] dim1879Kuo3Init = { 1 , 1 , 5 , 5 , 21 , 41 , 97 , 121 , 293 , 639 , 1799 , 689 , 6941 , 14179 , 11007 ,0 }; - static ulong[] dim1880Kuo3Init = { 1 , 1 , 3 , 7 , 21 , 61 , 91 , 177 , 213 , 757 , 123 , 2021 , 1493 , 2365 , 9713 ,0 }; - static ulong[] dim1881Kuo3Init = { 1 , 1 , 1 , 7 , 3 , 57 , 33 , 229 , 45 , 351 , 1671 , 2047 , 7685 , 14375 , 5773 ,0 }; - static ulong[] dim1882Kuo3Init = { 1 , 1 , 7 , 7 , 23 , 55 , 19 , 83 , 11 , 463 , 83 , 3071 , 5257 , 2741 , 31137 ,0 }; - static ulong[] dim1883Kuo3Init = { 1 , 3 , 3 , 5 , 5 , 31 , 53 , 135 , 255 , 711 , 1873 , 609 , 3395 , 16137 , 19947 ,0 }; - static ulong[] dim1884Kuo3Init = { 1 , 3 , 7 , 7 , 13 , 29 , 117 , 203 , 387 , 529 , 1301 , 3199 , 1843 , 5381 , 12491 ,0 }; - static ulong[] dim1885Kuo3Init = { 1 , 3 , 1 , 15 , 25 , 61 , 21 , 75 , 111 , 757 , 1611 , 2911 , 5805 , 5787 , 5099 ,0 }; - static ulong[] dim1886Kuo3Init = { 1 , 3 , 3 , 5 , 1 , 33 , 51 , 45 , 115 , 45 , 1155 , 951 , 6471 , 10233 , 8053 ,0 }; - static ulong[] dim1887Kuo3Init = { 1 , 3 , 7 , 1 , 11 , 13 , 17 , 167 , 391 , 219 , 277 , 3311 , 1761 , 6741 , 6253 ,0 }; - static ulong[] dim1888Kuo3Init = { 1 , 1 , 3 , 7 , 3 , 9 , 43 , 187 , 113 , 747 , 1207 , 3513 , 1055 , 15145 , 3793 ,0 }; - static ulong[] dim1889Kuo3Init = { 1 , 1 , 7 , 13 , 3 , 33 , 127 , 95 , 47 , 663 , 1581 , 489 , 2303 , 15183 , 21671 ,0 }; - static ulong[] dim1890Kuo3Init = { 1 , 3 , 7 , 9 , 15 , 7 , 53 , 143 , 313 , 167 , 425 , 3153 , 7241 , 3019 , 27323 ,0 }; - static ulong[] dim1891Kuo3Init = { 1 , 1 , 5 , 1 , 1 , 47 , 47 , 211 , 79 , 495 , 1383 , 2373 , 141 , 2933 , 11535 ,0 }; - static ulong[] dim1892Kuo3Init = { 1 , 3 , 1 , 11 , 13 , 35 , 79 , 105 , 329 , 235 , 667 , 2431 , 6427 , 15335 , 15013 ,0 }; - static ulong[] dim1893Kuo3Init = { 1 , 3 , 3 , 9 , 25 , 33 , 27 , 241 , 153 , 197 , 221 , 3149 , 2357 , 4485 , 17877 ,0 }; - static ulong[] dim1894Kuo3Init = { 1 , 1 , 1 , 7 , 31 , 29 , 43 , 39 , 439 , 799 , 293 , 727 , 6387 , 12257 , 15701 ,0 }; - static ulong[] dim1895Kuo3Init = { 1 , 3 , 1 , 1 , 17 , 47 , 105 , 33 , 275 , 269 , 259 , 2293 , 1829 , 13141 , 3015 ,0 }; - static ulong[] dim1896Kuo3Init = { 1 , 1 , 3 , 3 , 29 , 27 , 43 , 161 , 131 , 95 , 851 , 1269 , 491 , 4073 , 3481 ,0 }; - static ulong[] dim1897Kuo3Init = { 1 , 3 , 7 , 3 , 23 , 13 , 35 , 137 , 405 , 899 , 1521 , 2193 , 725 , 11967 , 16937 ,0 }; - static ulong[] dim1898Kuo3Init = { 1 , 3 , 1 , 15 , 5 , 15 , 113 , 139 , 307 , 125 , 635 , 477 , 493 , 9879 , 21125 ,0 }; - static ulong[] dim1899Kuo3Init = { 1 , 1 , 7 , 11 , 19 , 9 , 117 , 173 , 447 , 485 , 1073 , 2893 , 1767 , 10299 , 31449 ,0 }; - static ulong[] dim1900Kuo3Init = { 1 , 3 , 7 , 3 , 11 , 53 , 99 , 109 , 393 , 281 , 187 , 1557 , 3597 , 5215 , 4033 ,0 }; - static ulong[] dim1901Kuo3Init = { 1 , 1 , 1 , 3 , 5 , 15 , 33 , 33 , 37 , 445 , 1415 , 2885 , 2625 , 465 , 2745 ,0 }; - static ulong[] dim1902Kuo3Init = { 1 , 3 , 1 , 13 , 7 , 13 , 93 , 141 , 427 , 663 , 1863 , 991 , 2001 , 701 , 18287 ,0 }; - static ulong[] dim1903Kuo3Init = { 1 , 3 , 1 , 7 , 19 , 47 , 65 , 49 , 425 , 691 , 1487 , 2725 , 6145 , 4983 , 11871 ,0 }; - static ulong[] dim1904Kuo3Init = { 1 , 1 , 7 , 11 , 27 , 35 , 89 , 147 , 413 , 1007 , 755 , 3883 , 4737 , 10399 , 19073 ,0 }; - static ulong[] dim1905Kuo3Init = { 1 , 3 , 3 , 1 , 11 , 41 , 27 , 225 , 237 , 407 , 461 , 1881 , 3761 , 6587 , 28923 ,0 }; - static ulong[] dim1906Kuo3Init = { 1 , 3 , 5 , 9 , 1 , 3 , 93 , 179 , 157 , 227 , 571 , 1901 , 1407 , 12059 , 15281 ,0 }; - static ulong[] dim1907Kuo3Init = { 1 , 3 , 1 , 15 , 27 , 29 , 55 , 169 , 65 , 517 , 1801 , 177 , 5687 , 9597 , 5167 ,0 }; - static ulong[] dim1908Kuo3Init = { 1 , 1 , 3 , 5 , 25 , 47 , 57 , 15 , 491 , 631 , 1567 , 25 , 2087 , 7513 , 15107 ,0 }; - static ulong[] dim1909Kuo3Init = { 1 , 1 , 1 , 11 , 15 , 55 , 13 , 39 , 203 , 487 , 1235 , 389 , 281 , 499 , 20119 ,0 }; - static ulong[] dim1910Kuo3Init = { 1 , 3 , 3 , 15 , 29 , 53 , 127 , 211 , 301 , 509 , 611 , 1293 , 6495 , 10211 , 4905 ,0 }; - static ulong[] dim1911Kuo3Init = { 1 , 3 , 5 , 3 , 13 , 15 , 31 , 205 , 237 , 429 , 1721 , 3953 , 8153 , 16275 , 30421 ,0 }; - static ulong[] dim1912Kuo3Init = { 1 , 3 , 7 , 11 , 27 , 17 , 43 , 123 , 503 , 507 , 257 , 447 , 6315 , 5023 , 6995 ,0 }; - static ulong[] dim1913Kuo3Init = { 1 , 3 , 5 , 15 , 27 , 33 , 127 , 33 , 241 , 1001 , 1009 , 1263 , 4627 , 9329 , 29191 ,0 }; - static ulong[] dim1914Kuo3Init = { 1 , 1 , 1 , 13 , 13 , 45 , 125 , 77 , 247 , 123 , 1581 , 537 , 799 , 15417 , 30457 ,0 }; - static ulong[] dim1915Kuo3Init = { 1 , 3 , 5 , 5 , 9 , 29 , 39 , 211 , 243 , 871 , 1581 , 4029 , 4791 , 13393 , 25341 ,0 }; - static ulong[] dim1916Kuo3Init = { 1 , 3 , 1 , 5 , 15 , 17 , 123 , 123 , 303 , 207 , 1551 , 3633 , 5591 , 2725 , 5707 ,0 }; - static ulong[] dim1917Kuo3Init = { 1 , 1 , 7 , 11 , 29 , 41 , 111 , 73 , 163 , 511 , 1305 , 3235 , 4725 , 13589 , 9611 ,0 }; - static ulong[] dim1918Kuo3Init = { 1 , 1 , 1 , 1 , 19 , 51 , 17 , 225 , 499 , 1013 , 7 , 1793 , 7073 , 10115 , 18195 ,0 }; - static ulong[] dim1919Kuo3Init = { 1 , 1 , 7 , 9 , 17 , 35 , 107 , 87 , 251 , 19 , 959 , 1389 , 6725 , 8555 , 14571 ,0 }; - static ulong[] dim1920Kuo3Init = { 1 , 1 , 1 , 9 , 1 , 13 , 79 , 163 , 17 , 87 , 1121 , 1813 , 1213 , 3325 , 18083 ,0 }; - static ulong[] dim1921Kuo3Init = { 1 , 3 , 1 , 3 , 27 , 5 , 107 , 143 , 211 , 459 , 257 , 957 , 1183 , 2367 , 24687 ,0 }; - static ulong[] dim1922Kuo3Init = { 1 , 1 , 7 , 15 , 1 , 33 , 51 , 25 , 379 , 829 , 1657 , 273 , 4507 , 9609 , 879 ,0 }; - static ulong[] dim1923Kuo3Init = { 1 , 1 , 7 , 15 , 1 , 31 , 43 , 181 , 147 , 373 , 83 , 2179 , 6363 , 1871 , 10209 ,0 }; - static ulong[] dim1924Kuo3Init = { 1 , 1 , 1 , 15 , 9 , 29 , 105 , 255 , 483 , 573 , 1841 , 1101 , 2987 , 1619 , 18837 ,0 }; - static ulong[] dim1925Kuo3Init = { 1 , 3 , 5 , 11 , 17 , 19 , 67 , 109 , 13 , 247 , 1365 , 2153 , 5597 , 5785 , 25877 ,0 }; - static ulong[] dim1926Kuo3Init = { 1 , 1 , 3 , 7 , 17 , 49 , 121 , 163 , 49 , 689 , 1917 , 2161 , 7979 , 8153 , 12889 ,0 }; - static ulong[] dim1927Kuo3Init = { 1 , 1 , 3 , 7 , 5 , 49 , 39 , 251 , 311 , 69 , 553 , 2789 , 2415 , 6521 , 26847 ,0 }; - static ulong[] dim1928Kuo3Init = { 1 , 1 , 3 , 5 , 15 , 51 , 67 , 227 , 245 , 893 , 493 , 1191 , 3061 , 249 , 16603 ,0 }; - static ulong[] dim1929Kuo3Init = { 1 , 3 , 1 , 3 , 17 , 63 , 35 , 41 , 269 , 75 , 147 , 3229 , 7985 , 5789 , 6365 ,0 }; - static ulong[] dim1930Kuo3Init = { 1 , 3 , 1 , 13 , 21 , 33 , 125 , 39 , 343 , 133 , 389 , 2467 , 4079 , 14315 , 17047 ,0 }; - static ulong[] dim1931Kuo3Init = { 1 , 3 , 1 , 7 , 27 , 61 , 73 , 107 , 143 , 665 , 155 , 2865 , 3017 , 7307 , 8771 ,0 }; - static ulong[] dim1932Kuo3Init = { 1 , 1 , 5 , 7 , 25 , 57 , 57 , 39 , 195 , 405 , 1863 , 2985 , 5775 , 9609 , 24409 ,0 }; - static ulong[] dim1933Kuo3Init = { 1 , 3 , 3 , 5 , 11 , 27 , 91 , 169 , 343 , 673 , 1317 , 1763 , 1603 , 527 , 18945 ,0 }; - static ulong[] dim1934Kuo3Init = { 1 , 3 , 7 , 7 , 17 , 39 , 113 , 47 , 483 , 793 , 1295 , 1305 , 7025 , 14849 , 17703 ,0 }; - static ulong[] dim1935Kuo3Init = { 1 , 1 , 5 , 9 , 5 , 43 , 119 , 149 , 103 , 63 , 1369 , 3791 , 3081 , 10587 , 12711 ,0 }; - static ulong[] dim1936Kuo3Init = { 1 , 3 , 5 , 15 , 9 , 55 , 105 , 171 , 199 , 883 , 1113 , 3559 , 1979 , 8823 , 12407 ,0 }; - static ulong[] dim1937Kuo3Init = { 1 , 3 , 3 , 9 , 27 , 51 , 105 , 163 , 203 , 25 , 1579 , 351 , 8071 , 5921 , 28935 ,0 }; - static ulong[] dim1938Kuo3Init = { 1 , 1 , 5 , 15 , 15 , 43 , 115 , 115 , 5 , 283 , 1935 , 2619 , 2543 , 7603 , 2877 ,0 }; - static ulong[] dim1939Kuo3Init = { 1 , 3 , 7 , 9 , 31 , 29 , 17 , 67 , 121 , 187 , 563 , 377 , 3947 , 7699 , 8677 ,0 }; - static ulong[] dim1940Kuo3Init = { 1 , 1 , 5 , 1 , 5 , 1 , 121 , 211 , 109 , 955 , 1605 , 3681 , 5395 , 797 , 19243 ,0 }; - static ulong[] dim1941Kuo3Init = { 1 , 1 , 7 , 13 , 7 , 63 , 73 , 215 , 403 , 465 , 1317 , 3141 , 4511 , 12579 , 20839 ,0 }; - static ulong[] dim1942Kuo3Init = { 1 , 3 , 5 , 7 , 9 , 63 , 39 , 55 , 353 , 395 , 233 , 1189 , 1781 , 9167 , 887 ,0 }; - static ulong[] dim1943Kuo3Init = { 1 , 1 , 7 , 1 , 1 , 55 , 93 , 63 , 211 , 635 , 1767 , 827 , 7257 , 119 , 26333 ,0 }; - static ulong[] dim1944Kuo3Init = { 1 , 1 , 3 , 11 , 9 , 33 , 17 , 205 , 303 , 713 , 65 , 3539 , 5069 , 8895 , 3843 ,0 }; - static ulong[] dim1945Kuo3Init = { 1 , 1 , 3 , 15 , 3 , 59 , 45 , 135 , 103 , 293 , 731 , 359 , 3631 , 7967 , 30043 ,0 }; - static ulong[] dim1946Kuo3Init = { 1 , 3 , 3 , 7 , 25 , 7 , 27 , 161 , 9 , 509 , 1345 , 3759 , 7957 , 5975 , 17981 ,0 }; - static ulong[] dim1947Kuo3Init = { 1 , 3 , 1 , 7 , 13 , 41 , 105 , 241 , 331 , 437 , 2027 , 2589 , 5201 , 11373 , 22581 ,0 }; - static ulong[] dim1948Kuo3Init = { 1 , 3 , 7 , 13 , 5 , 3 , 37 , 43 , 125 , 521 , 1059 , 291 , 4421 , 5215 , 16835 ,0 }; - static ulong[] dim1949Kuo3Init = { 1 , 1 , 5 , 15 , 13 , 15 , 85 , 175 , 221 , 527 , 173 , 1333 , 7505 , 883 , 2215 ,0 }; - static ulong[] dim1950Kuo3Init = { 1 , 3 , 5 , 11 , 27 , 63 , 5 , 215 , 85 , 229 , 165 , 525 , 2693 , 15089 , 4907 ,0 }; - static ulong[] dim1951Kuo3Init = { 1 , 3 , 7 , 15 , 25 , 13 , 91 , 81 , 81 , 189 , 671 , 539 , 2393 , 9627 , 17667 ,0 }; - static ulong[] dim1952Kuo3Init = { 1 , 1 , 1 , 5 , 5 , 9 , 45 , 43 , 337 , 841 , 853 , 3969 , 5917 , 5837 , 17265 ,0 }; - static ulong[] dim1953Kuo3Init = { 1 , 1 , 7 , 9 , 1 , 57 , 33 , 29 , 235 , 69 , 815 , 147 , 7251 , 2933 , 32405 ,0 }; - static ulong[] dim1954Kuo3Init = { 1 , 3 , 1 , 3 , 29 , 1 , 3 , 13 , 483 , 825 , 31 , 2289 , 185 , 9075 , 15495 ,0 }; - static ulong[] dim1955Kuo3Init = { 1 , 3 , 3 , 3 , 1 , 33 , 127 , 53 , 229 , 975 , 91 , 3259 , 7969 , 4193 , 18433 ,0 }; - static ulong[] dim1956Kuo3Init = { 1 , 1 , 3 , 7 , 7 , 43 , 89 , 193 , 51 , 563 , 1961 , 3959 , 1901 , 10393 , 679 ,0 }; - static ulong[] dim1957Kuo3Init = { 1 , 1 , 5 , 9 , 29 , 11 , 57 , 227 , 163 , 169 , 1969 , 3087 , 3221 , 15499 , 12255 ,0 }; - static ulong[] dim1958Kuo3Init = { 1 , 3 , 7 , 5 , 31 , 47 , 45 , 37 , 257 , 383 , 1347 , 3923 , 7963 , 13459 , 8755 ,0 }; - static ulong[] dim1959Kuo3Init = { 1 , 1 , 1 , 3 , 5 , 53 , 19 , 219 , 261 , 313 , 1889 , 3185 , 5309 , 14049 , 5231 ,0 }; - static ulong[] dim1960Kuo3Init = { 1 , 3 , 3 , 13 , 29 , 19 , 49 , 221 , 443 , 125 , 929 , 2445 , 6713 , 5639 , 2657 ,0 }; - static ulong[] dim1961Kuo3Init = { 1 , 1 , 7 , 3 , 17 , 59 , 87 , 227 , 305 , 67 , 311 , 3473 , 4785 , 10761 , 2871 ,0 }; - static ulong[] dim1962Kuo3Init = { 1 , 1 , 5 , 7 , 31 , 63 , 103 , 127 , 49 , 839 , 1991 , 41 , 5019 , 12779 , 25489 ,0 }; - static ulong[] dim1963Kuo3Init = { 1 , 3 , 5 , 9 , 9 , 45 , 127 , 29 , 441 , 481 , 49 , 1975 , 1523 , 759 , 847 ,0 }; - static ulong[] dim1964Kuo3Init = { 1 , 3 , 5 , 13 , 1 , 25 , 89 , 19 , 53 , 17 , 1449 , 603 , 473 , 9965 , 14455 ,0 }; - static ulong[] dim1965Kuo3Init = { 1 , 3 , 1 , 7 , 19 , 9 , 27 , 97 , 321 , 1007 , 1283 , 3805 , 539 , 2979 , 4631 ,0 }; - static ulong[] dim1966Kuo3Init = { 1 , 3 , 1 , 5 , 9 , 3 , 9 , 237 , 349 , 277 , 1791 , 3325 , 865 , 4305 , 29293 ,0 }; - static ulong[] dim1967Kuo3Init = { 1 , 1 , 1 , 9 , 13 , 23 , 63 , 33 , 381 , 711 , 1921 , 1385 , 5949 , 8837 , 3589 ,0 }; - static ulong[] dim1968Kuo3Init = { 1 , 3 , 1 , 7 , 15 , 5 , 7 , 175 , 15 , 343 , 1587 , 2917 , 4189 , 14973 , 1691 ,0 }; - static ulong[] dim1969Kuo3Init = { 1 , 1 , 3 , 15 , 17 , 59 , 123 , 195 , 377 , 35 , 917 , 1045 , 721 , 9759 , 15287 ,0 }; - static ulong[] dim1970Kuo3Init = { 1 , 1 , 3 , 15 , 29 , 3 , 15 , 147 , 283 , 449 , 175 , 1771 , 2359 , 7541 , 11657 ,0 }; - static ulong[] dim1971Kuo3Init = { 1 , 3 , 1 , 3 , 1 , 11 , 45 , 117 , 235 , 75 , 247 , 917 , 6135 , 13817 , 27365 ,0 }; - static ulong[] dim1972Kuo3Init = { 1 , 1 , 7 , 3 , 1 , 45 , 31 , 97 , 281 , 739 , 829 , 1837 , 1709 , 877 , 25275 ,0 }; - static ulong[] dim1973Kuo3Init = { 1 , 3 , 7 , 11 , 3 , 35 , 11 , 55 , 233 , 471 , 1239 , 1345 , 2475 , 13391 , 25447 ,0 }; - static ulong[] dim1974Kuo3Init = { 1 , 1 , 5 , 7 , 27 , 33 , 111 , 89 , 173 , 361 , 1641 , 381 , 1629 , 5663 , 17715 ,0 }; - static ulong[] dim1975Kuo3Init = { 1 , 3 , 1 , 1 , 31 , 59 , 11 , 165 , 129 , 513 , 1729 , 2707 , 4665 , 3381 , 7915 ,0 }; - static ulong[] dim1976Kuo3Init = { 1 , 3 , 1 , 11 , 19 , 15 , 3 , 99 , 21 , 255 , 515 , 1619 , 1819 , 4143 , 24317 ,0 }; - static ulong[] dim1977Kuo3Init = { 1 , 3 , 1 , 9 , 11 , 33 , 13 , 143 , 39 , 557 , 901 , 187 , 2963 , 13413 , 5641 ,0 }; - static ulong[] dim1978Kuo3Init = { 1 , 3 , 3 , 13 , 5 , 27 , 87 , 63 , 41 , 57 , 2009 , 493 , 2565 , 14931 , 24071 ,0 }; - static ulong[] dim1979Kuo3Init = { 1 , 3 , 1 , 1 , 7 , 11 , 31 , 107 , 343 , 395 , 841 , 467 , 1019 , 3861 , 19595 ,0 }; - static ulong[] dim1980Kuo3Init = { 1 , 1 , 7 , 13 , 5 , 15 , 113 , 23 , 421 , 693 , 1421 , 2213 , 3589 , 3713 , 1353 ,0 }; - static ulong[] dim1981Kuo3Init = { 1 , 3 , 1 , 7 , 17 , 1 , 87 , 217 , 333 , 797 , 1971 , 917 , 3527 , 10061 , 19353 ,0 }; - static ulong[] dim1982Kuo3Init = { 1 , 3 , 1 , 5 , 5 , 51 , 17 , 239 , 275 , 221 , 1621 , 215 , 319 , 12041 , 15669 ,0 }; - static ulong[] dim1983Kuo3Init = { 1 , 1 , 7 , 11 , 27 , 33 , 31 , 19 , 365 , 951 , 1453 , 141 , 1249 , 16313 , 30607 ,0 }; - static ulong[] dim1984Kuo3Init = { 1 , 3 , 1 , 9 , 15 , 19 , 127 , 247 , 161 , 921 , 195 , 2857 , 1573 , 11077 , 15997 ,0 }; - static ulong[] dim1985Kuo3Init = { 1 , 1 , 1 , 1 , 9 , 43 , 57 , 103 , 215 , 337 , 1705 , 961 , 6895 , 2671 , 7157 ,0 }; - static ulong[] dim1986Kuo3Init = { 1 , 1 , 7 , 3 , 13 , 55 , 123 , 19 , 279 , 571 , 1039 , 2545 , 5961 , 12373 , 11479 ,0 }; - static ulong[] dim1987Kuo3Init = { 1 , 3 , 7 , 11 , 7 , 35 , 85 , 89 , 407 , 359 , 1897 , 231 , 7653 , 9215 , 9957 ,0 }; - static ulong[] dim1988Kuo3Init = { 1 , 3 , 7 , 5 , 23 , 53 , 13 , 153 , 221 , 363 , 1481 , 1069 , 1023 , 8573 , 29385 ,0 }; - static ulong[] dim1989Kuo3Init = { 1 , 1 , 1 , 3 , 15 , 63 , 1 , 57 , 373 , 35 , 725 , 135 , 5593 , 5593 , 8365 ,0 }; - static ulong[] dim1990Kuo3Init = { 1 , 1 , 5 , 3 , 7 , 35 , 25 , 69 , 441 , 451 , 1109 , 1723 , 1617 , 3947 , 22349 ,0 }; - static ulong[] dim1991Kuo3Init = { 1 , 3 , 5 , 3 , 27 , 55 , 75 , 231 , 245 , 831 , 1641 , 1475 , 51 , 2683 , 12489 ,0 }; - static ulong[] dim1992Kuo3Init = { 1 , 1 , 5 , 5 , 17 , 5 , 61 , 167 , 389 , 149 , 43 , 825 , 6079 , 12955 , 20121 ,0 }; - static ulong[] dim1993Kuo3Init = { 1 , 1 , 5 , 7 , 15 , 43 , 63 , 83 , 187 , 1005 , 1675 , 2907 , 2357 , 5459 , 18621 ,0 }; - static ulong[] dim1994Kuo3Init = { 1 , 1 , 5 , 13 , 27 , 53 , 49 , 93 , 9 , 629 , 1507 , 357 , 3207 , 9209 , 13697 ,0 }; - static ulong[] dim1995Kuo3Init = { 1 , 3 , 5 , 3 , 19 , 49 , 65 , 31 , 359 , 13 , 617 , 815 , 4673 , 2475 , 27491 ,0 }; - static ulong[] dim1996Kuo3Init = { 1 , 3 , 3 , 13 , 21 , 39 , 79 , 107 , 485 , 905 , 51 , 987 , 6579 , 3899 , 28785 ,0 }; - static ulong[] dim1997Kuo3Init = { 1 , 1 , 1 , 11 , 7 , 11 , 111 , 223 , 249 , 767 , 141 , 691 , 4711 , 583 , 7917 ,0 }; - static ulong[] dim1998Kuo3Init = { 1 , 1 , 5 , 1 , 9 , 43 , 115 , 179 , 313 , 783 , 2047 , 1773 , 2307 , 5011 , 7215 ,0 }; - static ulong[] dim1999Kuo3Init = { 1 , 3 , 3 , 5 , 23 , 23 , 85 , 193 , 83 , 809 , 1827 , 3375 , 5177 , 2041 , 19271 ,0 }; - static ulong[] dim2000Kuo3Init = { 1 , 1 , 1 , 9 , 23 , 17 , 31 , 111 , 75 , 265 , 1171 , 219 , 6309 , 2263 , 3807 ,0 }; - static ulong[] dim2001Kuo3Init = { 1 , 1 , 5 , 1 , 27 , 7 , 65 , 117 , 291 , 811 , 1797 , 3395 , 3495 , 829 , 23911 ,0 }; - static ulong[] dim2002Kuo3Init = { 1 , 1 , 3 , 11 , 19 , 31 , 43 , 229 , 361 , 219 , 1029 , 1407 , 5855 , 12411 , 16117 ,0 }; - static ulong[] dim2003Kuo3Init = { 1 , 3 , 3 , 3 , 5 , 1 , 99 , 245 , 21 , 925 , 1807 , 2529 , 627 , 3363 , 853 ,0 }; - static ulong[] dim2004Kuo3Init = { 1 , 1 , 3 , 15 , 17 , 41 , 83 , 31 , 207 , 615 , 851 , 1631 , 6789 , 12061 , 12327 ,0 }; - static ulong[] dim2005Kuo3Init = { 1 , 1 , 7 , 15 , 27 , 19 , 75 , 3 , 51 , 655 , 73 , 2433 , 7973 , 1425 , 31309 ,0 }; - static ulong[] dim2006Kuo3Init = { 1 , 3 , 1 , 7 , 25 , 47 , 73 , 119 , 91 , 981 , 1671 , 2145 , 3101 , 3765 , 8719 ,0 }; - static ulong[] dim2007Kuo3Init = { 1 , 1 , 1 , 7 , 31 , 37 , 51 , 181 , 289 , 273 , 1889 , 1017 , 2793 , 9513 , 32549 ,0 }; - static ulong[] dim2008Kuo3Init = { 1 , 1 , 3 , 5 , 5 , 39 , 57 , 51 , 135 , 689 , 1913 , 709 , 4759 , 12223 , 17377 ,0 }; - static ulong[] dim2009Kuo3Init = { 1 , 3 , 3 , 15 , 31 , 9 , 57 , 245 , 159 , 97 , 1485 , 2229 , 1393 , 9699 , 5807 ,0 }; - static ulong[] dim2010Kuo3Init = { 1 , 1 , 3 , 9 , 11 , 3 , 11 , 169 , 81 , 667 , 357 , 2307 , 7305 , 8631 , 2555 ,0 }; - static ulong[] dim2011Kuo3Init = { 1 , 3 , 7 , 7 , 15 , 17 , 119 , 143 , 15 , 567 , 1879 , 1363 , 1617 , 8231 , 23071 ,0 }; - static ulong[] dim2012Kuo3Init = { 1 , 1 , 5 , 9 , 5 , 39 , 49 , 45 , 371 , 641 , 943 , 1231 , 8139 , 14423 , 11057 ,0 }; - static ulong[] dim2013Kuo3Init = { 1 , 1 , 5 , 1 , 27 , 51 , 25 , 111 , 205 , 655 , 317 , 1381 , 2359 , 8785 , 31503 ,0 }; - static ulong[] dim2014Kuo3Init = { 1 , 3 , 3 , 3 , 9 , 13 , 127 , 211 , 423 , 147 , 735 , 1323 , 5801 , 9291 , 10059 ,0 }; - static ulong[] dim2015Kuo3Init = { 1 , 3 , 3 , 13 , 19 , 1 , 11 , 85 , 343 , 781 , 1661 , 1803 , 4541 , 2271 , 20541 ,0 }; - static ulong[] dim2016Kuo3Init = { 1 , 1 , 5 , 9 , 11 , 15 , 77 , 63 , 345 , 71 , 1311 , 3809 , 7535 , 1269 , 13949 ,0 }; - static ulong[] dim2017Kuo3Init = { 1 , 3 , 7 , 7 , 19 , 27 , 3 , 107 , 439 , 195 , 2007 , 4009 , 305 , 3111 , 17775 ,0 }; - static ulong[] dim2018Kuo3Init = { 1 , 1 , 3 , 7 , 27 , 31 , 25 , 123 , 177 , 161 , 287 , 3389 , 3013 , 11427 , 9165 ,0 }; - static ulong[] dim2019Kuo3Init = { 1 , 1 , 3 , 7 , 27 , 15 , 83 , 131 , 201 , 277 , 267 , 3557 , 1337 , 4427 , 2389 ,0 }; - static ulong[] dim2020Kuo3Init = { 1 , 1 , 5 , 7 , 25 , 27 , 75 , 211 , 147 , 37 , 491 , 3467 , 4525 , 13073 , 15289 ,0 }; - static ulong[] dim2021Kuo3Init = { 1 , 3 , 5 , 9 , 13 , 37 , 117 , 159 , 145 , 453 , 1451 , 667 , 1861 , 6855 , 25389 ,0 }; - static ulong[] dim2022Kuo3Init = { 1 , 1 , 5 , 7 , 19 , 37 , 3 , 157 , 251 , 901 , 433 , 3289 , 2723 , 11941 , 10103 ,0 }; - static ulong[] dim2023Kuo3Init = { 1 , 3 , 7 , 3 , 31 , 51 , 125 , 211 , 317 , 775 , 801 , 3887 , 2257 , 13947 , 2421 ,0 }; - static ulong[] dim2024Kuo3Init = { 1 , 3 , 3 , 13 , 11 , 21 , 67 , 223 , 203 , 409 , 1927 , 3565 , 679 , 14197 , 24987 ,0 }; - static ulong[] dim2025Kuo3Init = { 1 , 3 , 1 , 1 , 23 , 29 , 37 , 203 , 311 , 825 , 1957 , 3069 , 5295 , 4073 , 4407 ,0 }; - static ulong[] dim2026Kuo3Init = { 1 , 3 , 1 , 15 , 1 , 49 , 111 , 205 , 441 , 907 , 481 , 225 , 6589 , 7523 , 19807 ,0 }; - static ulong[] dim2027Kuo3Init = { 1 , 3 , 5 , 15 , 1 , 55 , 43 , 121 , 9 , 239 , 723 , 3109 , 5639 , 9547 , 20455 ,0 }; - static ulong[] dim2028Kuo3Init = { 1 , 1 , 1 , 15 , 29 , 17 , 121 , 61 , 233 , 873 , 1447 , 1313 , 5073 , 12259 , 32305 ,0 }; - static ulong[] dim2029Kuo3Init = { 1 , 1 , 5 , 7 , 25 , 57 , 15 , 45 , 243 , 297 , 219 , 2307 , 1459 , 16005 , 10041 ,0 }; - static ulong[] dim2030Kuo3Init = { 1 , 3 , 7 , 3 , 5 , 53 , 57 , 187 , 287 , 243 , 1223 , 1625 , 669 , 5165 , 8395 ,0 }; - static ulong[] dim2031Kuo3Init = { 1 , 3 , 7 , 15 , 23 , 23 , 25 , 225 , 471 , 661 , 905 , 2293 , 1131 , 8469 , 7929 ,0 }; - static ulong[] dim2032Kuo3Init = { 1 , 1 , 5 , 11 , 11 , 33 , 11 , 129 , 237 , 855 , 1417 , 3661 , 1561 , 9635 , 31905 ,0 }; - static ulong[] dim2033Kuo3Init = { 1 , 3 , 1 , 3 , 15 , 45 , 3 , 253 , 125 , 449 , 1675 , 1707 , 3917 , 11829 , 27439 ,0 }; - static ulong[] dim2034Kuo3Init = { 1 , 3 , 7 , 1 , 1 , 55 , 83 , 69 , 83 , 745 , 1225 , 977 , 7117 , 15045 , 28067 ,0 }; - static ulong[] dim2035Kuo3Init = { 1 , 1 , 7 , 9 , 3 , 51 , 23 , 205 , 5 , 625 , 531 , 3557 , 4101 , 5709 , 29487 ,0 }; - static ulong[] dim2036Kuo3Init = { 1 , 1 , 1 , 5 , 9 , 23 , 69 , 99 , 203 , 355 , 1935 , 3165 , 5701 , 15491 , 18151 ,0 }; - static ulong[] dim2037Kuo3Init = { 1 , 1 , 1 , 7 , 31 , 41 , 89 , 85 , 273 , 227 , 785 , 1057 , 4409 , 9155 , 11573 ,0 }; - static ulong[] dim2038Kuo3Init = { 1 , 3 , 7 , 15 , 17 , 49 , 117 , 31 , 181 , 799 , 417 , 3931 , 6069 , 1253 , 25793 ,0 }; - static ulong[] dim2039Kuo3Init = { 1 , 1 , 3 , 7 , 27 , 23 , 33 , 189 , 5 , 841 , 901 , 2023 , 331 , 10015 , 3781 ,0 }; - static ulong[] dim2040Kuo3Init = { 1 , 3 , 3 , 5 , 19 , 47 , 73 , 103 , 373 , 1011 , 1015 , 1657 , 6181 , 69 , 16243 ,0 }; - static ulong[] dim2041Kuo3Init = { 1 , 1 , 7 , 9 , 13 , 9 , 95 , 161 , 413 , 155 , 367 , 3519 , 1557 , 14897 , 31331 ,0 }; - static ulong[] dim2042Kuo3Init = { 1 , 1 , 7 , 3 , 15 , 25 , 105 , 145 , 157 , 525 , 1541 , 3361 , 1531 , 7473 , 28187 ,0 }; - static ulong[] dim2043Kuo3Init = { 1 , 1 , 7 , 7 , 15 , 7 , 119 , 135 , 395 , 441 , 1443 , 537 , 5185 , 793 , 13205 ,0 }; - static ulong[] dim2044Kuo3Init = { 1 , 1 , 1 , 9 , 15 , 7 , 101 , 43 , 437 , 761 , 1471 , 3843 , 6765 , 4135 , 7883 ,0 }; - static ulong[] dim2045Kuo3Init = { 1 , 1 , 5 , 5 , 23 , 31 , 125 , 119 , 361 , 65 , 1907 , 1335 , 1309 , 10591 , 11167 ,0 }; - static ulong[] dim2046Kuo3Init = { 1 , 3 , 1 , 7 , 21 , 9 , 29 , 149 , 371 , 201 , 1531 , 2955 , 1755 , 14047 , 5867 ,0 }; - static ulong[] dim2047Kuo3Init = { 1 , 1 , 5 , 1 , 19 , 9 , 13 , 13 , 313 , 621 , 595 , 2765 , 2963 , 13081 , 21795 ,0 }; - static ulong[] dim2048Kuo3Init = { 1 , 1 , 3 , 11 , 21 , 61 , 7 , 113 , 295 , 995 , 1649 , 1715 , 4737 , 4769 , 13945 ,0 }; - static ulong[] dim2049Kuo3Init = { 1 , 3 , 5 , 15 , 17 , 53 , 73 , 15 , 83 , 813 , 1757 , 471 , 6031 , 7871 , 32569 ,0 }; - static ulong[] dim2050Kuo3Init = { 1 , 3 , 1 , 13 , 29 , 55 , 45 , 173 , 231 , 167 , 415 , 1487 , 6403 , 13823 , 10121 ,0 }; - static ulong[] dim2051Kuo3Init = { 1 , 1 , 1 , 5 , 19 , 25 , 107 , 177 , 97 , 703 , 1349 , 2217 , 3863 , 11211 , 28875 ,0 }; - static ulong[] dim2052Kuo3Init = { 1 , 3 , 7 , 9 , 1 , 9 , 37 , 127 , 435 , 917 , 709 , 2227 , 7449 , 13927 , 1187 ,0 }; - static ulong[] dim2053Kuo3Init = { 1 , 1 , 3 , 15 , 19 , 17 , 19 , 127 , 343 , 235 , 931 , 589 , 6439 , 8839 , 18027 ,0 }; - static ulong[] dim2054Kuo3Init = { 1 , 3 , 5 , 7 , 25 , 25 , 71 , 141 , 343 , 35 , 15 , 1439 , 3163 , 8063 , 15337 ,0 }; - static ulong[] dim2055Kuo3Init = { 1 , 3 , 3 , 13 , 27 , 31 , 91 , 215 , 67 , 835 , 673 , 3355 , 7633 , 11711 , 31479 ,0 }; - static ulong[] dim2056Kuo3Init = { 1 , 3 , 5 , 3 , 5 , 9 , 35 , 23 , 415 , 341 , 1813 , 3761 , 5053 , 9497 , 10147 ,0 }; - static ulong[] dim2057Kuo3Init = { 1 , 1 , 3 , 5 , 25 , 59 , 107 , 57 , 43 , 955 , 1049 , 2613 , 7003 , 5749 , 28211 ,0 }; - static ulong[] dim2058Kuo3Init = { 1 , 3 , 5 , 5 , 5 , 61 , 25 , 17 , 41 , 477 , 131 , 3331 , 1193 , 14291 , 1467 ,0 }; - static ulong[] dim2059Kuo3Init = { 1 , 3 , 3 , 3 , 5 , 7 , 37 , 41 , 215 , 723 , 1735 , 3735 , 3981 , 13405 , 5837 ,0 }; - static ulong[] dim2060Kuo3Init = { 1 , 3 , 1 , 7 , 17 , 9 , 21 , 51 , 451 , 691 , 1853 , 779 , 635 , 15461 , 14789 ,0 }; - static ulong[] dim2061Kuo3Init = { 1 , 1 , 7 , 13 , 9 , 51 , 21 , 183 , 33 , 565 , 529 , 393 , 6847 , 10149 , 23807 ,0 }; - static ulong[] dim2062Kuo3Init = { 1 , 3 , 1 , 15 , 9 , 27 , 1 , 245 , 459 , 935 , 1219 , 2277 , 6309 , 13511 , 31255 ,0 }; - static ulong[] dim2063Kuo3Init = { 1 , 1 , 3 , 3 , 21 , 63 , 121 , 95 , 5 , 545 , 995 , 1011 , 2073 , 6145 , 4635 ,0 }; - static ulong[] dim2064Kuo3Init = { 1 , 1 , 3 , 15 , 11 , 1 , 61 , 53 , 445 , 33 , 153 , 2179 , 2899 , 7633 , 20417 ,0 }; - static ulong[] dim2065Kuo3Init = { 1 , 1 , 5 , 3 , 29 , 47 , 65 , 55 , 509 , 175 , 1875 , 2669 , 4583 , 775 , 27621 ,0 }; - static ulong[] dim2066Kuo3Init = { 1 , 3 , 1 , 1 , 5 , 21 , 43 , 37 , 349 , 89 , 1581 , 2105 , 6753 , 14577 , 14339 ,0 }; - static ulong[] dim2067Kuo3Init = { 1 , 1 , 1 , 11 , 21 , 17 , 55 , 11 , 87 , 323 , 647 , 955 , 1343 , 10799 , 15375 ,0 }; - static ulong[] dim2068Kuo3Init = { 1 , 3 , 7 , 13 , 11 , 43 , 23 , 25 , 327 , 797 , 1111 , 231 , 4423 , 5907 , 16191 ,0 }; - static ulong[] dim2069Kuo3Init = { 1 , 3 , 5 , 15 , 1 , 15 , 109 , 43 , 217 , 905 , 1295 , 2373 , 497 , 11643 , 14371 ,0 }; - static ulong[] dim2070Kuo3Init = { 1 , 1 , 3 , 5 , 3 , 43 , 125 , 249 , 343 , 947 , 1523 , 2393 , 3073 , 11301 , 18751 ,0 }; - static ulong[] dim2071Kuo3Init = { 1 , 3 , 1 , 13 , 31 , 27 , 23 , 241 , 103 , 503 , 1715 , 877 , 5269 , 10665 , 23927 ,0 }; - static ulong[] dim2072Kuo3Init = { 1 , 3 , 1 , 9 , 21 , 1 , 91 , 55 , 297 , 941 , 1419 , 3391 , 811 , 8399 , 8513 ,0 }; - static ulong[] dim2073Kuo3Init = { 1 , 1 , 5 , 1 , 7 , 3 , 17 , 139 , 461 , 1007 , 1835 , 165 , 1575 , 15075 , 18673 ,0 }; - static ulong[] dim2074Kuo3Init = { 1 , 3 , 7 , 11 , 21 , 63 , 11 , 123 , 229 , 767 , 201 , 3415 , 4997 , 14791 , 27193 ,0 }; - static ulong[] dim2075Kuo3Init = { 1 , 3 , 3 , 9 , 5 , 13 , 71 , 163 , 499 , 933 , 1829 , 2321 , 1773 , 5255 , 18219 ,0 }; - static ulong[] dim2076Kuo3Init = { 1 , 1 , 5 , 15 , 15 , 5 , 47 , 81 , 167 , 27 , 773 , 3607 , 25 , 12437 , 11525 ,0 }; - static ulong[] dim2077Kuo3Init = { 1 , 3 , 3 , 11 , 3 , 21 , 41 , 1 , 441 , 1013 , 1409 , 3097 , 5671 , 3953 , 51 ,0 }; - static ulong[] dim2078Kuo3Init = { 1 , 1 , 3 , 15 , 15 , 13 , 93 , 111 , 355 , 207 , 1653 , 2711 , 81 , 7801 , 14105 ,0 }; - static ulong[] dim2079Kuo3Init = { 1 , 1 , 5 , 9 , 15 , 57 , 47 , 53 , 79 , 255 , 517 , 4015 , 8123 , 5557 , 4245 ,0 }; - static ulong[] dim2080Kuo3Init = { 1 , 3 , 1 , 9 , 25 , 45 , 97 , 107 , 107 , 365 , 1647 , 3831 , 5567 , 167 , 26977 ,0 }; - static ulong[] dim2081Kuo3Init = { 1 , 1 , 1 , 7 , 31 , 21 , 79 , 155 , 391 , 347 , 1295 , 255 , 6439 , 8201 , 31975 ,0 }; - static ulong[] dim2082Kuo3Init = { 1 , 1 , 1 , 13 , 19 , 57 , 9 , 167 , 359 , 833 , 709 , 3437 , 5031 , 16221 , 18491 ,0 }; - static ulong[] dim2083Kuo3Init = { 1 , 3 , 3 , 11 , 17 , 37 , 39 , 167 , 271 , 801 , 601 , 461 , 3949 , 5237 , 3425 ,0 }; - static ulong[] dim2084Kuo3Init = { 1 , 3 , 3 , 13 , 29 , 47 , 51 , 161 , 427 , 421 , 671 , 2545 , 4793 , 10083 , 3499 ,0 }; - static ulong[] dim2085Kuo3Init = { 1 , 3 , 5 , 7 , 27 , 25 , 59 , 75 , 431 , 891 , 1557 , 3615 , 4759 , 11267 , 8473 ,0 }; - static ulong[] dim2086Kuo3Init = { 1 , 3 , 1 , 7 , 7 , 31 , 63 , 89 , 353 , 761 , 1333 , 1367 , 5963 , 12311 , 20717 ,0 }; - static ulong[] dim2087Kuo3Init = { 1 , 3 , 3 , 1 , 27 , 19 , 93 , 209 , 291 , 119 , 513 , 3757 , 3477 , 2541 , 4919 ,0 }; - static ulong[] dim2088Kuo3Init = { 1 , 3 , 7 , 1 , 15 , 9 , 109 , 41 , 401 , 365 , 907 , 3603 , 6401 , 12115 , 28691 ,0 }; - static ulong[] dim2089Kuo3Init = { 1 , 1 , 5 , 9 , 3 , 21 , 121 , 27 , 355 , 571 , 133 , 1073 , 4875 , 13351 , 13197 ,0 }; - static ulong[] dim2090Kuo3Init = { 1 , 3 , 1 , 3 , 1 , 31 , 35 , 171 , 201 , 617 , 1181 , 3621 , 823 , 8599 , 4407 ,0 }; - static ulong[] dim2091Kuo3Init = { 1 , 3 , 3 , 3 , 31 , 61 , 45 , 19 , 191 , 843 , 909 , 391 , 5899 , 14059 , 7879 ,0 }; - static ulong[] dim2092Kuo3Init = { 1 , 1 , 7 , 9 , 19 , 51 , 123 , 201 , 163 , 737 , 153 , 161 , 7949 , 2865 , 17357 ,0 }; - static ulong[] dim2093Kuo3Init = { 1 , 3 , 7 , 11 , 23 , 51 , 121 , 165 , 459 , 959 , 647 , 535 , 7903 , 2935 , 24895 ,0 }; - static ulong[] dim2094Kuo3Init = { 1 , 3 , 5 , 3 , 1 , 63 , 73 , 179 , 485 , 661 , 255 , 1423 , 7277 , 2109 , 25113 ,0 }; - static ulong[] dim2095Kuo3Init = { 1 , 3 , 5 , 11 , 27 , 51 , 79 , 151 , 389 , 251 , 277 , 1785 , 4073 , 1729 , 22705 ,0 }; - static ulong[] dim2096Kuo3Init = { 1 , 3 , 3 , 11 , 23 , 15 , 105 , 205 , 413 , 253 , 1181 , 2605 , 6181 , 1771 , 17869 ,0 }; - static ulong[] dim2097Kuo3Init = { 1 , 3 , 7 , 13 , 29 , 45 , 95 , 37 , 319 , 609 , 369 , 3311 , 5717 , 7219 , 25157 ,0 }; - static ulong[] dim2098Kuo3Init = { 1 , 1 , 7 , 15 , 23 , 3 , 61 , 125 , 429 , 29 , 479 , 1151 , 4479 , 8909 , 9763 ,0 }; - static ulong[] dim2099Kuo3Init = { 1 , 3 , 1 , 13 , 25 , 21 , 11 , 147 , 61 , 903 , 1719 , 3065 , 7089 , 15041 , 6387 ,0 }; - static ulong[] dim2100Kuo3Init = { 1 , 1 , 5 , 11 , 17 , 33 , 43 , 1 , 271 , 223 , 363 , 2799 , 1043 , 3929 , 25991 ,0 }; - static ulong[] dim2101Kuo3Init = { 1 , 1 , 7 , 11 , 3 , 15 , 115 , 245 , 383 , 881 , 221 , 2045 , 621 , 14543 , 1027 ,0 }; - static ulong[] dim2102Kuo3Init = { 1 , 3 , 1 , 7 , 1 , 45 , 19 , 133 , 339 , 883 , 1643 , 853 , 7141 , 6259 , 6373 ,0 }; - static ulong[] dim2103Kuo3Init = { 1 , 1 , 3 , 11 , 27 , 23 , 123 , 159 , 185 , 693 , 577 , 473 , 313 , 13579 , 19317 ,0 }; - static ulong[] dim2104Kuo3Init = { 1 , 3 , 3 , 15 , 27 , 19 , 43 , 23 , 183 , 925 , 1987 , 1945 , 6341 , 10771 , 9669 ,0 }; - static ulong[] dim2105Kuo3Init = { 1 , 1 , 1 , 3 , 15 , 27 , 49 , 117 , 347 , 149 , 23 , 103 , 3613 , 3123 , 32759 ,0 }; - static ulong[] dim2106Kuo3Init = { 1 , 3 , 7 , 13 , 1 , 37 , 13 , 111 , 407 , 319 , 563 , 1499 , 6551 , 13333 , 659 ,0 }; - static ulong[] dim2107Kuo3Init = { 1 , 3 , 3 , 3 , 23 , 21 , 9 , 109 , 393 , 115 , 415 , 351 , 6113 , 2417 , 14151 ,0 }; - static ulong[] dim2108Kuo3Init = { 1 , 3 , 5 , 7 , 25 , 7 , 35 , 41 , 43 , 663 , 1809 , 535 , 7437 , 12487 , 1059 ,0 }; - static ulong[] dim2109Kuo3Init = { 1 , 3 , 3 , 11 , 13 , 13 , 123 , 111 , 391 , 199 , 69 , 2357 , 4779 , 7461 , 5003 ,0 }; - static ulong[] dim2110Kuo3Init = { 1 , 1 , 1 , 13 , 17 , 63 , 5 , 163 , 107 , 609 , 1979 , 3389 , 499 , 13111 , 219 ,0 }; - static ulong[] dim2111Kuo3Init = { 1 , 3 , 7 , 1 , 19 , 41 , 43 , 29 , 35 , 371 , 1773 , 3563 , 2005 , 8217 , 5131 ,0 }; - static ulong[] dim2112Kuo3Init = { 1 , 3 , 7 , 15 , 13 , 53 , 43 , 167 , 201 , 259 , 1855 , 3971 , 1179 , 8591 , 21425 ,0 }; - static ulong[] dim2113Kuo3Init = { 1 , 1 , 1 , 11 , 27 , 21 , 45 , 47 , 185 , 753 , 531 , 2553 , 5515 , 11501 , 4623 ,0 }; - static ulong[] dim2114Kuo3Init = { 1 , 1 , 7 , 9 , 9 , 49 , 29 , 207 , 441 , 265 , 1059 , 1703 , 1625 , 9371 , 23045 ,0 }; - static ulong[] dim2115Kuo3Init = { 1 , 3 , 5 , 9 , 13 , 29 , 33 , 185 , 233 , 11 , 381 , 3917 , 4931 , 3497 , 24713 ,0 }; - static ulong[] dim2116Kuo3Init = { 1 , 3 , 1 , 11 , 13 , 61 , 43 , 147 , 505 , 251 , 1875 , 3009 , 4695 , 6793 , 3083 ,0 }; - static ulong[] dim2117Kuo3Init = { 1 , 3 , 3 , 3 , 31 , 17 , 119 , 35 , 111 , 767 , 211 , 3227 , 2539 , 10755 , 26177 ,0 }; - static ulong[] dim2118Kuo3Init = { 1 , 3 , 1 , 7 , 9 , 63 , 3 , 45 , 195 , 515 , 103 , 2327 , 5967 , 8087 , 9849 ,0 }; - static ulong[] dim2119Kuo3Init = { 1 , 3 , 7 , 13 , 31 , 51 , 55 , 231 , 451 , 259 , 1025 , 2671 , 5317 , 7087 , 7365 ,0 }; - static ulong[] dim2120Kuo3Init = { 1 , 3 , 5 , 3 , 5 , 41 , 33 , 255 , 305 , 831 , 1279 , 4013 , 3899 , 171 , 8543 ,0 }; - static ulong[] dim2121Kuo3Init = { 1 , 1 , 5 , 9 , 7 , 9 , 97 , 125 , 123 , 3 , 121 , 4041 , 3941 , 1655 , 25583 ,0 }; - static ulong[] dim2122Kuo3Init = { 1 , 1 , 3 , 3 , 9 , 63 , 99 , 53 , 85 , 57 , 1117 , 969 , 7067 , 1393 , 17497 ,0 }; - static ulong[] dim2123Kuo3Init = { 1 , 1 , 3 , 7 , 9 , 51 , 1 , 207 , 443 , 967 , 1387 , 2515 , 1789 , 1493 , 20941 ,0 }; - static ulong[] dim2124Kuo3Init = { 1 , 1 , 5 , 9 , 15 , 37 , 11 , 191 , 503 , 823 , 1789 , 4071 , 3355 , 9177 , 27281 ,0 }; - static ulong[] dim2125Kuo3Init = { 1 , 3 , 7 , 5 , 3 , 61 , 83 , 19 , 325 , 543 , 19 , 239 , 3513 , 16147 , 32395 ,0 }; - static ulong[] dim2126Kuo3Init = { 1 , 3 , 5 , 7 , 1 , 17 , 101 , 23 , 379 , 649 , 853 , 3045 , 1301 , 7215 , 18851 ,0 }; - static ulong[] dim2127Kuo3Init = { 1 , 3 , 5 , 13 , 25 , 11 , 41 , 213 , 137 , 705 , 1829 , 1055 , 3061 , 9335 , 5797 ,0 }; - static ulong[] dim2128Kuo3Init = { 1 , 3 , 1 , 13 , 11 , 21 , 17 , 117 , 473 , 687 , 125 , 4007 , 5283 , 11961 , 15365 ,0 }; - static ulong[] dim2129Kuo3Init = { 1 , 3 , 1 , 13 , 11 , 19 , 3 , 189 , 393 , 219 , 1229 , 1521 , 7137 , 1811 , 6745 ,0 }; - static ulong[] dim2130Kuo3Init = { 1 , 1 , 7 , 9 , 21 , 59 , 23 , 193 , 321 , 691 , 735 , 3731 , 593 , 9351 , 6571 ,0 }; - static ulong[] dim2131Kuo3Init = { 1 , 3 , 5 , 5 , 23 , 55 , 43 , 107 , 217 , 111 , 921 , 1017 , 7055 , 16059 , 8181 ,0 }; - static ulong[] dim2132Kuo3Init = { 1 , 3 , 3 , 3 , 29 , 57 , 93 , 91 , 9 , 453 , 1245 , 691 , 1571 , 5755 , 13387 ,0 }; - static ulong[] dim2133Kuo3Init = { 1 , 1 , 3 , 1 , 1 , 23 , 87 , 239 , 373 , 433 , 553 , 2205 , 4495 , 3975 , 25819 ,0 }; - static ulong[] dim2134Kuo3Init = { 1 , 1 , 3 , 1 , 23 , 7 , 9 , 227 , 503 , 87 , 819 , 3167 , 4135 , 9281 , 8443 ,0 }; - static ulong[] dim2135Kuo3Init = { 1 , 1 , 3 , 5 , 7 , 27 , 17 , 81 , 295 , 131 , 955 , 4065 , 797 , 16165 , 2385 ,0 }; - static ulong[] dim2136Kuo3Init = { 1 , 3 , 3 , 1 , 9 , 47 , 113 , 105 , 277 , 187 , 1983 , 2833 , 2749 , 4473 , 31275 ,0 }; - static ulong[] dim2137Kuo3Init = { 1 , 3 , 3 , 3 , 19 , 61 , 41 , 51 , 435 , 933 , 961 , 459 , 4187 , 6619 , 777 ,0 }; - static ulong[] dim2138Kuo3Init = { 1 , 3 , 3 , 9 , 11 , 25 , 51 , 219 , 203 , 897 , 777 , 3047 , 2601 , 4387 , 14185 ,0 }; - static ulong[] dim2139Kuo3Init = { 1 , 3 , 7 , 15 , 23 , 17 , 103 , 55 , 387 , 127 , 197 , 1045 , 3973 , 10503 , 23443 ,0 }; - static ulong[] dim2140Kuo3Init = { 1 , 1 , 5 , 9 , 13 , 59 , 87 , 253 , 7 , 879 , 1335 , 1349 , 6353 , 5897 , 10021 ,0 }; - static ulong[] dim2141Kuo3Init = { 1 , 1 , 3 , 5 , 19 , 49 , 107 , 65 , 229 , 317 , 169 , 509 , 1819 , 2267 , 13269 ,0 }; - static ulong[] dim2142Kuo3Init = { 1 , 3 , 5 , 13 , 21 , 25 , 11 , 143 , 511 , 107 , 637 , 3237 , 3985 , 15197 , 23343 ,0 }; - static ulong[] dim2143Kuo3Init = { 1 , 1 , 5 , 15 , 1 , 15 , 67 , 91 , 131 , 501 , 1803 , 699 , 2031 , 11015 , 17989 ,0 }; - static ulong[] dim2144Kuo3Init = { 1 , 1 , 7 , 13 , 3 , 55 , 103 , 245 , 229 , 121 , 245 , 1299 , 3357 , 3283 , 26181 ,0 }; - static ulong[] dim2145Kuo3Init = { 1 , 1 , 7 , 1 , 19 , 53 , 101 , 125 , 35 , 963 , 887 , 3119 , 1407 , 723 , 29169 ,0 }; - static ulong[] dim2146Kuo3Init = { 1 , 3 , 7 , 3 , 27 , 39 , 29 , 71 , 7 , 529 , 329 , 2811 , 4627 , 2865 , 26837 ,0 }; - static ulong[] dim2147Kuo3Init = { 1 , 3 , 5 , 7 , 29 , 55 , 71 , 129 , 455 , 465 , 1949 , 3895 , 6971 , 15621 , 26819 ,0 }; - static ulong[] dim2148Kuo3Init = { 1 , 1 , 3 , 15 , 5 , 63 , 95 , 15 , 425 , 347 , 835 , 1973 , 5171 , 3963 , 23691 ,0 }; - static ulong[] dim2149Kuo3Init = { 1 , 3 , 1 , 9 , 27 , 23 , 87 , 237 , 261 , 349 , 1777 , 287 , 3543 , 35 , 31891 ,0 }; - static ulong[] dim2150Kuo3Init = { 1 , 1 , 7 , 7 , 17 , 59 , 7 , 65 , 45 , 733 , 239 , 221 , 6419 , 9161 , 17499 ,0 }; - static ulong[] dim2151Kuo3Init = { 1 , 3 , 3 , 15 , 7 , 53 , 121 , 97 , 127 , 583 , 501 , 1667 , 6265 , 3233 , 19187 ,0 }; - static ulong[] dim2152Kuo3Init = { 1 , 1 , 3 , 1 , 29 , 17 , 121 , 89 , 107 , 787 , 1699 , 3389 , 6191 , 11503 , 2461 ,0 }; - static ulong[] dim2153Kuo3Init = { 1 , 1 , 1 , 9 , 13 , 27 , 97 , 49 , 447 , 851 , 147 , 439 , 277 , 11129 , 2201 ,0 }; - static ulong[] dim2154Kuo3Init = { 1 , 3 , 3 , 11 , 29 , 47 , 93 , 243 , 101 , 627 , 1607 , 459 , 27 , 10635 , 1345 ,0 }; - static ulong[] dim2155Kuo3Init = { 1 , 1 , 7 , 3 , 19 , 11 , 61 , 253 , 345 , 523 , 317 , 1599 , 5625 , 14385 , 3461 ,0 }; - static ulong[] dim2156Kuo3Init = { 1 , 1 , 5 , 13 , 27 , 59 , 33 , 251 , 29 , 787 , 1655 , 3383 , 2451 , 2499 , 10719 ,0 }; - static ulong[] dim2157Kuo3Init = { 1 , 3 , 7 , 7 , 1 , 29 , 97 , 233 , 193 , 459 , 1667 , 47 , 3059 , 8713 , 13259 ,0 }; - static ulong[] dim2158Kuo3Init = { 1 , 1 , 3 , 9 , 29 , 63 , 127 , 35 , 105 , 95 , 887 , 2337 , 5999 , 13553 , 30225 ,0 }; - static ulong[] dim2159Kuo3Init = { 1 , 1 , 7 , 7 , 17 , 43 , 47 , 205 , 497 , 835 , 1565 , 3863 , 785 , 6149 , 17595 ,0 }; - static ulong[] dim2160Kuo3Init = { 1 , 1 , 1 , 13 , 29 , 17 , 47 , 37 , 339 , 131 , 1219 , 3545 , 3499 , 2223 , 3107 ,0 }; - static ulong[] dim2161Kuo3Init = { 1 , 1 , 1 , 15 , 7 , 17 , 39 , 25 , 97 , 691 , 1645 , 3333 , 95 , 15593 , 11667 ,0 }; - static ulong[] dim2162Kuo3Init = { 1 , 3 , 5 , 7 , 13 , 21 , 61 , 147 , 115 , 249 , 981 , 665 , 1245 , 14397 , 9571 ,0 }; - static ulong[] dim2163Kuo3Init = { 1 , 1 , 3 , 13 , 15 , 5 , 7 , 129 , 151 , 947 , 375 , 1631 , 3247 , 1321 , 19495 ,0 }; - static ulong[] dim2164Kuo3Init = { 1 , 1 , 5 , 11 , 5 , 5 , 69 , 247 , 53 , 37 , 683 , 1581 , 2997 , 5897 , 4797 ,0 }; - static ulong[] dim2165Kuo3Init = { 1 , 1 , 5 , 15 , 5 , 45 , 115 , 65 , 509 , 557 , 1749 , 2167 , 4795 , 629 , 10749 ,0 }; - static ulong[] dim2166Kuo3Init = { 1 , 1 , 3 , 1 , 25 , 23 , 99 , 93 , 99 , 721 , 1235 , 1259 , 2739 , 11797 , 15985 ,0 }; - static ulong[] dim2167Kuo3Init = { 1 , 3 , 5 , 11 , 15 , 29 , 97 , 103 , 21 , 981 , 1717 , 1483 , 711 , 12419 , 14401 ,0 }; - static ulong[] dim2168Kuo3Init = { 1 , 3 , 1 , 1 , 5 , 5 , 125 , 159 , 301 , 733 , 1987 , 1679 , 7459 , 3493 , 29377 ,0 }; - static ulong[] dim2169Kuo3Init = { 1 , 1 , 7 , 7 , 29 , 45 , 53 , 197 , 303 , 303 , 931 , 1171 , 1771 , 14895 , 21525 ,0 }; - static ulong[] dim2170Kuo3Init = { 1 , 3 , 7 , 13 , 11 , 59 , 93 , 113 , 219 , 557 , 397 , 2639 , 5089 , 6833 , 20455 ,0 }; - static ulong[] dim2171Kuo3Init = { 1 , 3 , 1 , 3 , 11 , 33 , 117 , 163 , 359 , 431 , 915 , 3285 , 2443 , 8225 , 16341 ,0 }; - static ulong[] dim2172Kuo3Init = { 1 , 3 , 1 , 9 , 19 , 1 , 105 , 65 , 3 , 71 , 705 , 2047 , 2169 , 13129 , 8575 ,0 }; - static ulong[] dim2173Kuo3Init = { 1 , 1 , 1 , 9 , 23 , 63 , 67 , 203 , 429 , 897 , 1453 , 101 , 1445 , 8553 , 16355 ,0 }; - static ulong[] dim2174Kuo3Init = { 1 , 1 , 7 , 5 , 13 , 61 , 79 , 217 , 83 , 339 , 529 , 3573 , 4075 , 5929 , 2687 ,0 }; - static ulong[] dim2175Kuo3Init = { 1 , 1 , 7 , 11 , 27 , 9 , 93 , 105 , 179 , 479 , 1093 , 3551 , 5697 , 8989 , 1099 ,0 }; - static ulong[] dim2176Kuo3Init = { 1 , 1 , 1 , 11 , 15 , 9 , 21 , 59 , 193 , 231 , 1817 , 463 , 1945 , 13795 , 28655 ,0 }; - static ulong[] dim2177Kuo3Init = { 1 , 1 , 1 , 5 , 3 , 27 , 49 , 179 , 205 , 49 , 355 , 667 , 6573 , 4317 , 26599 ,0 }; - static ulong[] dim2178Kuo3Init = { 1 , 3 , 7 , 5 , 9 , 45 , 121 , 219 , 309 , 371 , 1119 , 1991 , 5889 , 14257 , 1105 ,0 }; - static ulong[] dim2179Kuo3Init = { 1 , 1 , 3 , 3 , 7 , 19 , 111 , 191 , 321 , 77 , 39 , 1921 , 563 , 1049 , 26623 ,0 }; - static ulong[] dim2180Kuo3Init = { 1 , 3 , 3 , 13 , 13 , 43 , 21 , 121 , 181 , 185 , 629 , 211 , 7897 , 9445 , 12679 ,0 }; - static ulong[] dim2181Kuo3Init = { 1 , 1 , 7 , 15 , 3 , 19 , 61 , 159 , 337 , 711 , 155 , 2099 , 2201 , 14337 , 21633 ,0 }; - static ulong[] dim2182Kuo3Init = { 1 , 1 , 3 , 9 , 27 , 63 , 43 , 209 , 17 , 565 , 225 , 2381 , 4577 , 15793 , 4861 ,0 }; - static ulong[] dim2183Kuo3Init = { 1 , 3 , 7 , 3 , 25 , 51 , 65 , 187 , 235 , 479 , 293 , 789 , 2453 , 4367 , 15835 ,0 }; - static ulong[] dim2184Kuo3Init = { 1 , 1 , 5 , 11 , 17 , 7 , 115 , 165 , 3 , 457 , 455 , 969 , 5859 , 2663 , 15337 ,0 }; - static ulong[] dim2185Kuo3Init = { 1 , 3 , 1 , 13 , 19 , 1 , 55 , 177 , 365 , 395 , 1043 , 1095 , 6531 , 8599 , 12867 ,0 }; - static ulong[] dim2186Kuo3Init = { 1 , 3 , 7 , 1 , 29 , 57 , 55 , 139 , 187 , 649 , 1899 , 355 , 6447 , 4521 , 31497 ,0 }; - static ulong[] dim2187Kuo3Init = { 1 , 3 , 5 , 1 , 19 , 55 , 73 , 163 , 127 , 893 , 1189 , 2425 , 5145 , 15965 , 5937 ,0 }; - static ulong[] dim2188Kuo3Init = { 1 , 3 , 1 , 1 , 21 , 33 , 91 , 81 , 75 , 39 , 1 , 397 , 2799 , 11987 , 27829 ,0 }; - static ulong[] dim2189Kuo3Init = { 1 , 3 , 7 , 5 , 25 , 15 , 95 , 61 , 351 , 377 , 1949 , 3141 , 6259 , 135 , 19307 ,0 }; - static ulong[] dim2190Kuo3Init = { 1 , 3 , 3 , 7 , 7 , 45 , 1 , 197 , 235 , 747 , 1333 , 3293 , 1439 , 7447 , 26119 ,0 }; - static ulong[] dim2191Kuo3Init = { 1 , 3 , 3 , 3 , 25 , 31 , 113 , 159 , 335 , 587 , 733 , 1045 , 5015 , 9677 , 21777 ,0 }; - static ulong[] dim2192Kuo3Init = { 1 , 1 , 5 , 3 , 15 , 55 , 91 , 181 , 465 , 409 , 995 , 3243 , 6165 , 1547 , 31785 ,0 }; - static ulong[] dim2193Kuo3Init = { 1 , 3 , 7 , 3 , 7 , 47 , 27 , 87 , 399 , 265 , 945 , 1675 , 5383 , 4847 , 27859 ,0 }; - static ulong[] dim2194Kuo3Init = { 1 , 1 , 7 , 3 , 21 , 53 , 69 , 107 , 121 , 855 , 629 , 1947 , 8149 , 10707 , 2981 ,0 }; - static ulong[] dim2195Kuo3Init = { 1 , 3 , 1 , 11 , 3 , 25 , 53 , 87 , 349 , 237 , 1745 , 3705 , 4273 , 4109 , 26059 ,0 }; - static ulong[] dim2196Kuo3Init = { 1 , 1 , 5 , 11 , 25 , 19 , 11 , 179 , 301 , 27 , 1343 , 79 , 2475 , 5581 , 27225 ,0 }; - static ulong[] dim2197Kuo3Init = { 1 , 3 , 7 , 9 , 29 , 55 , 119 , 107 , 431 , 943 , 1567 , 3727 , 7415 , 2565 , 24957 ,0 }; - static ulong[] dim2198Kuo3Init = { 1 , 3 , 3 , 1 , 15 , 27 , 91 , 159 , 285 , 781 , 357 , 643 , 7445 , 9931 , 11881 ,0 }; - static ulong[] dim2199Kuo3Init = { 1 , 3 , 7 , 9 , 5 , 53 , 65 , 195 , 273 , 37 , 1785 , 467 , 5211 , 25 , 1749 ,0 }; - static ulong[] dim2200Kuo3Init = { 1 , 1 , 1 , 11 , 7 , 11 , 43 , 143 , 305 , 825 , 1055 , 2995 , 3907 , 7581 , 9679 ,0 }; - static ulong[] dim2201Kuo3Init = { 1 , 3 , 1 , 9 , 31 , 29 , 93 , 3 , 299 , 1 , 1851 , 395 , 239 , 8323 , 18201 ,0 }; - static ulong[] dim2202Kuo3Init = { 1 , 1 , 1 , 5 , 29 , 29 , 75 , 3 , 273 , 759 , 801 , 2841 , 5789 , 6651 , 19351 ,0 }; - static ulong[] dim2203Kuo3Init = { 1 , 3 , 7 , 1 , 1 , 11 , 11 , 215 , 27 , 955 , 1397 , 3483 , 1317 , 223 , 20559 ,0 }; - static ulong[] dim2204Kuo3Init = { 1 , 3 , 5 , 13 , 21 , 23 , 39 , 189 , 295 , 255 , 1457 , 2821 , 3145 , 15437 , 26997 ,0 }; - static ulong[] dim2205Kuo3Init = { 1 , 1 , 3 , 5 , 9 , 43 , 13 , 97 , 259 , 23 , 933 , 3867 , 5921 , 4199 , 24721 ,0 }; - static ulong[] dim2206Kuo3Init = { 1 , 1 , 3 , 11 , 1 , 19 , 89 , 87 , 17 , 247 , 1535 , 2629 , 2893 , 12209 , 23739 ,0 }; - static ulong[] dim2207Kuo3Init = { 1 , 1 , 1 , 1 , 31 , 15 , 81 , 37 , 235 , 249 , 1437 , 1485 , 5889 , 10017 , 18593 ,0 }; - static ulong[] dim2208Kuo3Init = { 1 , 3 , 7 , 5 , 17 , 33 , 117 , 5 , 31 , 63 , 2015 , 3063 , 5139 , 14771 , 29107 ,0 }; - static ulong[] dim2209Kuo3Init = { 1 , 1 , 7 , 15 , 13 , 3 , 25 , 127 , 419 , 945 , 1739 , 175 , 1591 , 4443 , 27289 ,0 }; - static ulong[] dim2210Kuo3Init = { 1 , 1 , 1 , 7 , 11 , 59 , 99 , 119 , 307 , 857 , 1711 , 1201 , 1623 , 11429 , 5663 ,0 }; - static ulong[] dim2211Kuo3Init = { 1 , 3 , 1 , 13 , 17 , 45 , 65 , 225 , 131 , 279 , 587 , 3487 , 1123 , 2753 , 30789 ,0 }; - static ulong[] dim2212Kuo3Init = { 1 , 3 , 3 , 15 , 21 , 55 , 17 , 141 , 109 , 1021 , 1387 , 1407 , 8163 , 1983 , 25971 ,0 }; - static ulong[] dim2213Kuo3Init = { 1 , 3 , 3 , 9 , 21 , 51 , 103 , 243 , 435 , 481 , 857 , 3353 , 2717 , 2295 , 7999 ,0 }; - static ulong[] dim2214Kuo3Init = { 1 , 1 , 1 , 7 , 7 , 27 , 83 , 45 , 359 , 191 , 259 , 3229 , 7869 , 10729 , 28587 ,0 }; - static ulong[] dim2215Kuo3Init = { 1 , 3 , 7 , 5 , 19 , 25 , 51 , 103 , 37 , 429 , 995 , 415 , 2879 , 2283 , 29981 ,0 }; - static ulong[] dim2216Kuo3Init = { 1 , 1 , 3 , 3 , 21 , 19 , 29 , 35 , 401 , 19 , 1761 , 3735 , 7775 , 3365 , 31767 ,0 }; - static ulong[] dim2217Kuo3Init = { 1 , 1 , 7 , 1 , 29 , 1 , 9 , 195 , 279 , 1003 , 999 , 4043 , 3761 , 11341 , 7117 ,0 }; - static ulong[] dim2218Kuo3Init = { 1 , 1 , 5 , 11 , 19 , 7 , 97 , 181 , 37 , 929 , 667 , 993 , 2517 , 12683 , 24487 ,0 }; - static ulong[] dim2219Kuo3Init = { 1 , 1 , 3 , 1 , 31 , 15 , 47 , 143 , 511 , 525 , 1799 , 1743 , 3237 , 12839 , 2287 ,0 }; - static ulong[] dim2220Kuo3Init = { 1 , 3 , 3 , 15 , 31 , 59 , 59 , 205 , 99 , 233 , 1857 , 2469 , 2661 , 3675 , 391 ,0 }; - static ulong[] dim2221Kuo3Init = { 1 , 3 , 5 , 15 , 31 , 23 , 23 , 1 , 313 , 401 , 605 , 3771 , 2703 , 6037 , 7943 ,0 }; - static ulong[] dim2222Kuo3Init = { 1 , 1 , 3 , 13 , 21 , 19 , 55 , 139 , 273 , 725 , 1239 , 595 , 549 , 15279 , 20887 ,0 }; - static ulong[] dim2223Kuo3Init = { 1 , 1 , 5 , 3 , 13 , 9 , 39 , 83 , 257 , 323 , 1801 , 167 , 3747 , 2867 , 30151 ,0 }; - static ulong[] dim2224Kuo3Init = { 1 , 3 , 3 , 3 , 17 , 3 , 67 , 163 , 325 , 569 , 1099 , 4037 , 5003 , 6985 , 7445 ,0 }; - static ulong[] dim2225Kuo3Init = { 1 , 3 , 7 , 13 , 31 , 37 , 13 , 91 , 21 , 763 , 785 , 1461 , 5257 , 15307 , 16389 ,0 }; - static ulong[] dim2226Kuo3Init = { 1 , 3 , 5 , 13 , 1 , 35 , 27 , 179 , 429 , 21 , 865 , 775 , 4993 , 335 , 12479 ,0 }; - static ulong[] dim2227Kuo3Init = { 1 , 3 , 1 , 1 , 19 , 1 , 111 , 201 , 219 , 709 , 1539 , 1905 , 647 , 8605 , 14129 ,0 }; - static ulong[] dim2228Kuo3Init = { 1 , 3 , 5 , 7 , 21 , 7 , 117 , 251 , 311 , 689 , 1125 , 1931 , 6363 , 7409 , 4189 ,0 }; - static ulong[] dim2229Kuo3Init = { 1 , 1 , 3 , 7 , 1 , 27 , 93 , 5 , 395 , 117 , 113 , 1297 , 501 , 13073 , 30483 ,0 }; - static ulong[] dim2230Kuo3Init = { 1 , 1 , 3 , 11 , 19 , 57 , 65 , 67 , 13 , 893 , 551 , 539 , 2861 , 10635 , 16057 ,0 }; - static ulong[] dim2231Kuo3Init = { 1 , 3 , 3 , 11 , 19 , 5 , 41 , 43 , 161 , 1015 , 33 , 471 , 229 , 13315 , 10791 ,0 }; - static ulong[] dim2232Kuo3Init = { 1 , 3 , 1 , 7 , 1 , 13 , 97 , 149 , 321 , 131 , 1389 , 715 , 5421 , 343 , 4129 ,0 }; - static ulong[] dim2233Kuo3Init = { 1 , 1 , 3 , 11 , 15 , 51 , 91 , 57 , 229 , 1007 , 709 , 2745 , 147 , 10427 , 21151 ,0 }; - static ulong[] dim2234Kuo3Init = { 1 , 3 , 7 , 15 , 1 , 31 , 65 , 251 , 75 , 553 , 133 , 1027 , 4857 , 7139 , 10591 ,0 }; - static ulong[] dim2235Kuo3Init = { 1 , 3 , 5 , 15 , 13 , 11 , 49 , 183 , 263 , 121 , 981 , 1421 , 7781 , 5313 , 3245 ,0 }; - static ulong[] dim2236Kuo3Init = { 1 , 3 , 5 , 15 , 31 , 27 , 109 , 85 , 327 , 999 , 1063 , 705 , 6047 , 13227 , 5817 ,0 }; - static ulong[] dim2237Kuo3Init = { 1 , 1 , 5 , 15 , 9 , 5 , 99 , 69 , 91 , 637 , 1353 , 2471 , 7003 , 9429 , 25235 ,0 }; - static ulong[] dim2238Kuo3Init = { 1 , 3 , 3 , 11 , 1 , 25 , 77 , 67 , 173 , 929 , 1919 , 4021 , 5587 , 3333 , 12769 ,0 }; - static ulong[] dim2239Kuo3Init = { 1 , 1 , 5 , 15 , 15 , 9 , 11 , 71 , 465 , 831 , 1127 , 3439 , 6793 , 1269 , 1699 ,0 }; - static ulong[] dim2240Kuo3Init = { 1 , 3 , 1 , 1 , 17 , 43 , 45 , 181 , 147 , 501 , 283 , 3875 , 7221 , 14487 , 2549 ,0 }; - static ulong[] dim2241Kuo3Init = { 1 , 3 , 7 , 11 , 1 , 21 , 125 , 179 , 479 , 367 , 1961 , 607 , 255 , 913 , 16143 ,0 }; - static ulong[] dim2242Kuo3Init = { 1 , 3 , 3 , 15 , 7 , 49 , 117 , 97 , 45 , 729 , 1331 , 1373 , 2147 , 11673 , 9779 ,0 }; - static ulong[] dim2243Kuo3Init = { 1 , 3 , 5 , 11 , 1 , 11 , 105 , 231 , 237 , 449 , 1195 , 33 , 4531 , 11591 , 29539 ,0 }; - static ulong[] dim2244Kuo3Init = { 1 , 3 , 3 , 3 , 27 , 47 , 105 , 85 , 25 , 663 , 47 , 3213 , 6777 , 11947 , 28993 ,0 }; - static ulong[] dim2245Kuo3Init = { 1 , 1 , 5 , 15 , 11 , 57 , 121 , 107 , 327 , 631 , 285 , 921 , 3721 , 7983 , 9199 ,0 }; - static ulong[] dim2246Kuo3Init = { 1 , 1 , 1 , 13 , 3 , 61 , 49 , 101 , 415 , 187 , 1645 , 2139 , 143 , 12033 , 11409 ,0 }; - static ulong[] dim2247Kuo3Init = { 1 , 1 , 5 , 13 , 7 , 15 , 27 , 143 , 17 , 977 , 495 , 2479 , 1507 , 10621 , 2119 ,0 }; - static ulong[] dim2248Kuo3Init = { 1 , 1 , 5 , 13 , 11 , 9 , 53 , 159 , 479 , 333 , 1423 , 2559 , 5497 , 12611 , 22627 ,0 }; - static ulong[] dim2249Kuo3Init = { 1 , 1 , 5 , 9 , 7 , 55 , 3 , 137 , 421 , 661 , 113 , 925 , 1649 , 12405 , 30035 ,0 }; - static ulong[] dim2250Kuo3Init = { 1 , 3 , 1 , 13 , 9 , 31 , 25 , 233 , 241 , 239 , 505 , 2685 , 223 , 4389 , 28191 ,0 }; - static ulong[] dim2251Kuo3Init = { 1 , 1 , 3 , 3 , 23 , 59 , 5 , 181 , 491 , 111 , 1289 , 3717 , 4429 , 15091 , 25375 ,0 }; - static ulong[] dim2252Kuo3Init = { 1 , 3 , 1 , 3 , 25 , 3 , 3 , 7 , 163 , 247 , 1673 , 3061 , 2355 , 12779 , 20039 ,0 }; - static ulong[] dim2253Kuo3Init = { 1 , 1 , 1 , 5 , 3 , 35 , 5 , 107 , 387 , 99 , 1841 , 3607 , 2027 , 6353 , 15929 ,0 }; - static ulong[] dim2254Kuo3Init = { 1 , 1 , 7 , 7 , 29 , 45 , 43 , 207 , 383 , 681 , 769 , 3939 , 8161 , 10235 , 24209 ,0 }; - static ulong[] dim2255Kuo3Init = { 1 , 3 , 1 , 5 , 5 , 13 , 73 , 99 , 233 , 327 , 1429 , 487 , 3925 , 5169 , 5477 ,0 }; - static ulong[] dim2256Kuo3Init = { 1 , 1 , 1 , 5 , 21 , 63 , 39 , 17 , 227 , 455 , 1559 , 113 , 3993 , 7935 , 8995 ,0 }; - static ulong[] dim2257Kuo3Init = { 1 , 1 , 3 , 11 , 17 , 51 , 43 , 231 , 69 , 475 , 761 , 4011 , 4007 , 14829 , 29961 ,0 }; - static ulong[] dim2258Kuo3Init = { 1 , 3 , 1 , 5 , 19 , 37 , 49 , 197 , 277 , 391 , 583 , 2711 , 4041 , 6029 , 29559 ,0 }; - static ulong[] dim2259Kuo3Init = { 1 , 3 , 3 , 1 , 7 , 53 , 33 , 33 , 325 , 171 , 63 , 2929 , 641 , 7143 , 12585 ,0 }; - static ulong[] dim2260Kuo3Init = { 1 , 1 , 1 , 9 , 1 , 31 , 23 , 157 , 437 , 355 , 595 , 239 , 1275 , 4917 , 31055 ,0 }; - static ulong[] dim2261Kuo3Init = { 1 , 3 , 7 , 15 , 15 , 43 , 39 , 51 , 431 , 131 , 741 , 3473 , 1947 , 4223 , 27943 ,0 }; - static ulong[] dim2262Kuo3Init = { 1 , 1 , 7 , 1 , 27 , 49 , 5 , 197 , 33 , 611 , 1131 , 429 , 4931 , 1243 , 5787 ,0 }; - static ulong[] dim2263Kuo3Init = { 1 , 1 , 7 , 9 , 29 , 19 , 89 , 139 , 239 , 421 , 951 , 3749 , 1557 , 3803 , 7155 ,0 }; - static ulong[] dim2264Kuo3Init = { 1 , 1 , 7 , 13 , 15 , 53 , 121 , 123 , 99 , 677 , 1519 , 3051 , 5235 , 8061 , 21353 ,0 }; - static ulong[] dim2265Kuo3Init = { 1 , 1 , 3 , 7 , 21 , 53 , 65 , 35 , 389 , 141 , 253 , 2867 , 803 , 11525 , 9901 ,0 }; - static ulong[] dim2266Kuo3Init = { 1 , 1 , 7 , 7 , 21 , 37 , 81 , 53 , 121 , 15 , 1741 , 2225 , 183 , 7155 , 7597 ,0 }; - static ulong[] dim2267Kuo3Init = { 1 , 1 , 7 , 15 , 29 , 29 , 13 , 197 , 291 , 765 , 1479 , 2211 , 5949 , 5045 , 32519 ,0 }; - static ulong[] dim2268Kuo3Init = { 1 , 3 , 3 , 5 , 5 , 19 , 121 , 219 , 121 , 17 , 1223 , 2685 , 8179 , 391 , 31257 ,0 }; - static ulong[] dim2269Kuo3Init = { 1 , 1 , 5 , 7 , 13 , 27 , 29 , 71 , 7 , 95 , 255 , 9 , 2375 , 3325 , 29915 ,0 }; - static ulong[] dim2270Kuo3Init = { 1 , 3 , 3 , 1 , 1 , 3 , 11 , 43 , 233 , 663 , 715 , 585 , 3701 , 13559 , 3197 ,0 }; - static ulong[] dim2271Kuo3Init = { 1 , 1 , 7 , 5 , 17 , 45 , 103 , 209 , 61 , 923 , 517 , 249 , 5775 , 14537 , 15371 ,0 }; - static ulong[] dim2272Kuo3Init = { 1 , 1 , 5 , 1 , 7 , 5 , 123 , 99 , 137 , 277 , 1071 , 3371 , 7095 , 2765 , 28945 ,0 }; - static ulong[] dim2273Kuo3Init = { 1 , 1 , 3 , 15 , 1 , 59 , 85 , 5 , 475 , 855 , 1793 , 2479 , 4989 , 7155 , 6403 ,0 }; - static ulong[] dim2274Kuo3Init = { 1 , 1 , 5 , 5 , 3 , 29 , 41 , 129 , 373 , 839 , 1031 , 2845 , 6911 , 4793 , 25609 ,0 }; - static ulong[] dim2275Kuo3Init = { 1 , 1 , 3 , 5 , 23 , 55 , 79 , 209 , 131 , 893 , 1933 , 1391 , 6873 , 407 , 28823 ,0 }; - static ulong[] dim2276Kuo3Init = { 1 , 1 , 3 , 15 , 15 , 57 , 37 , 153 , 415 , 947 , 1959 , 1513 , 7961 , 4931 , 749 ,0 }; - static ulong[] dim2277Kuo3Init = { 1 , 1 , 3 , 3 , 21 , 5 , 27 , 169 , 349 , 541 , 533 , 3411 , 945 , 5275 , 665 ,0 }; - static ulong[] dim2278Kuo3Init = { 1 , 1 , 7 , 15 , 15 , 17 , 97 , 225 , 85 , 887 , 1251 , 1485 , 3987 , 10753 , 18013 ,0 }; - static ulong[] dim2279Kuo3Init = { 1 , 3 , 1 , 15 , 19 , 53 , 117 , 153 , 279 , 397 , 1929 , 3621 , 3887 , 7753 , 22075 ,0 }; - static ulong[] dim2280Kuo3Init = { 1 , 3 , 1 , 5 , 7 , 21 , 97 , 63 , 403 , 715 , 579 , 1645 , 2069 , 9279 , 14291 ,0 }; - static ulong[] dim2281Kuo3Init = { 1 , 1 , 1 , 3 , 21 , 17 , 63 , 61 , 207 , 795 , 737 , 4047 , 3559 , 6971 , 14903 ,0 }; - static ulong[] dim2282Kuo3Init = { 1 , 3 , 7 , 5 , 29 , 1 , 103 , 109 , 57 , 485 , 1373 , 3399 , 6351 , 13037 , 17193 ,0 }; - static ulong[] dim2283Kuo3Init = { 1 , 1 , 7 , 7 , 5 , 15 , 105 , 225 , 215 , 53 , 1125 , 3255 , 3277 , 2125 , 23359 ,0 }; - static ulong[] dim2284Kuo3Init = { 1 , 3 , 1 , 7 , 31 , 39 , 19 , 163 , 197 , 831 , 1959 , 1227 , 6515 , 8839 , 20105 ,0 }; - static ulong[] dim2285Kuo3Init = { 1 , 3 , 3 , 1 , 27 , 31 , 89 , 133 , 451 , 371 , 1513 , 1595 , 771 , 7637 , 32403 ,0 }; - static ulong[] dim2286Kuo3Init = { 1 , 3 , 3 , 13 , 29 , 45 , 29 , 157 , 117 , 461 , 913 , 3907 , 4225 , 5617 , 28917 ,0 }; - static ulong[] dim2287Kuo3Init = { 1 , 3 , 7 , 3 , 13 , 63 , 113 , 49 , 137 , 641 , 275 , 1179 , 8139 , 519 , 5851 ,0 }; - static ulong[] dim2288Kuo3Init = { 1 , 1 , 1 , 1 , 31 , 43 , 61 , 193 , 173 , 651 , 1491 , 1005 , 7559 , 1963 , 8323 ,0 }; - static ulong[] dim2289Kuo3Init = { 1 , 3 , 5 , 5 , 23 , 23 , 11 , 111 , 95 , 487 , 1091 , 175 , 25 , 10557 , 24493 ,0 }; - static ulong[] dim2290Kuo3Init = { 1 , 1 , 1 , 9 , 1 , 31 , 97 , 175 , 249 , 309 , 1005 , 3777 , 5551 , 2605 , 28071 ,0 }; - static ulong[] dim2291Kuo3Init = { 1 , 3 , 3 , 7 , 13 , 1 , 113 , 103 , 169 , 853 , 35 , 3645 , 6907 , 13713 , 12811 ,0 }; - static ulong[] dim2292Kuo3Init = { 1 , 1 , 7 , 3 , 25 , 49 , 53 , 23 , 33 , 967 , 2039 , 2057 , 799 , 1527 , 3427 ,0 }; - static ulong[] dim2293Kuo3Init = { 1 , 1 , 5 , 7 , 29 , 43 , 81 , 155 , 59 , 201 , 1571 , 1719 , 3343 , 3231 , 27929 ,0 }; - static ulong[] dim2294Kuo3Init = { 1 , 1 , 5 , 1 , 27 , 17 , 1 , 159 , 209 , 749 , 1883 , 1885 , 2511 , 15957 , 3471 ,0 }; - static ulong[] dim2295Kuo3Init = { 1 , 3 , 1 , 5 , 7 , 51 , 15 , 245 , 57 , 627 , 1315 , 673 , 5329 , 1043 , 555 ,0 }; - static ulong[] dim2296Kuo3Init = { 1 , 1 , 5 , 11 , 13 , 55 , 103 , 157 , 329 , 171 , 393 , 3967 , 373 , 7225 , 25133 ,0 }; - static ulong[] dim2297Kuo3Init = { 1 , 1 , 5 , 7 , 5 , 51 , 109 , 11 , 111 , 859 , 165 , 3991 , 7187 , 697 , 28035 ,0 }; - static ulong[] dim2298Kuo3Init = { 1 , 3 , 1 , 9 , 23 , 55 , 59 , 173 , 55 , 105 , 1103 , 1569 , 3099 , 10483 , 18821 ,0 }; - static ulong[] dim2299Kuo3Init = { 1 , 3 , 7 , 5 , 21 , 3 , 23 , 247 , 13 , 59 , 1327 , 2393 , 5023 , 11163 , 21443 ,0 }; - static ulong[] dim2300Kuo3Init = { 1 , 3 , 3 , 15 , 19 , 47 , 79 , 45 , 127 , 313 , 1609 , 273 , 4729 , 7363 , 13541 ,0 }; - static ulong[] dim2301Kuo3Init = { 1 , 3 , 7 , 15 , 21 , 61 , 91 , 247 , 477 , 539 , 1969 , 3541 , 3983 , 8339 , 32499 ,0 }; - static ulong[] dim2302Kuo3Init = { 1 , 3 , 7 , 11 , 13 , 7 , 47 , 57 , 299 , 907 , 701 , 2039 , 5509 , 7489 , 30175 ,0 }; - static ulong[] dim2303Kuo3Init = { 1 , 3 , 7 , 7 , 9 , 21 , 125 , 241 , 69 , 405 , 1989 , 3777 , 613 , 9827 , 19447 ,0 }; - static ulong[] dim2304Kuo3Init = { 1 , 3 , 7 , 3 , 19 , 39 , 19 , 43 , 1 , 1007 , 1829 , 3099 , 4001 , 2181 , 5849 ,0 }; - static ulong[] dim2305Kuo3Init = { 1 , 1 , 7 , 1 , 9 , 49 , 21 , 103 , 107 , 473 , 1913 , 2983 , 5669 , 977 , 21281 ,0 }; - static ulong[] dim2306Kuo3Init = { 1 , 3 , 5 , 3 , 3 , 37 , 79 , 239 , 425 , 949 , 1953 , 3867 , 2537 , 16117 , 945 ,0 }; - static ulong[] dim2307Kuo3Init = { 1 , 3 , 5 , 13 , 23 , 7 , 119 , 221 , 321 , 881 , 1505 , 3993 , 3677 , 4095 , 10501 ,0 }; - static ulong[] dim2308Kuo3Init = { 1 , 1 , 1 , 3 , 7 , 17 , 5 , 223 , 3 , 891 , 1699 , 823 , 3839 , 4113 , 16039 ,0 }; - static ulong[] dim2309Kuo3Init = { 1 , 1 , 7 , 5 , 27 , 35 , 67 , 89 , 291 , 521 , 411 , 3025 , 1427 , 12131 , 4449 ,0 }; - static ulong[] dim2310Kuo3Init = { 1 , 1 , 3 , 7 , 13 , 61 , 103 , 113 , 195 , 269 , 75 , 3879 , 7669 , 9403 , 13341 ,0 }; - static ulong[] dim2311Kuo3Init = { 1 , 3 , 7 , 13 , 21 , 17 , 101 , 135 , 153 , 615 , 755 , 2589 , 653 , 11187 , 2997 ,0 }; - static ulong[] dim2312Kuo3Init = { 1 , 3 , 1 , 9 , 11 , 53 , 61 , 171 , 423 , 857 , 465 , 819 , 4341 , 6377 , 21305 ,0 }; - static ulong[] dim2313Kuo3Init = { 1 , 3 , 5 , 3 , 17 , 37 , 63 , 91 , 157 , 877 , 1801 , 587 , 6183 , 12923 , 15991 ,0 }; - static ulong[] dim2314Kuo3Init = { 1 , 3 , 7 , 5 , 27 , 63 , 123 , 27 , 243 , 375 , 191 , 3333 , 965 , 889 , 15771 ,0 }; - static ulong[] dim2315Kuo3Init = { 1 , 3 , 7 , 15 , 23 , 51 , 49 , 187 , 201 , 861 , 1581 , 1045 , 493 , 9939 , 30893 ,0 }; - static ulong[] dim2316Kuo3Init = { 1 , 3 , 3 , 15 , 1 , 31 , 93 , 125 , 57 , 147 , 663 , 2733 , 4601 , 16043 , 6875 ,0 }; - static ulong[] dim2317Kuo3Init = { 1 , 3 , 7 , 11 , 15 , 1 , 45 , 251 , 173 , 807 , 1301 , 507 , 645 , 10383 , 14737 ,0 }; - static ulong[] dim2318Kuo3Init = { 1 , 3 , 7 , 7 , 27 , 3 , 3 , 127 , 153 , 151 , 1987 , 2255 , 5201 , 11095 , 20757 ,0 }; - static ulong[] dim2319Kuo3Init = { 1 , 1 , 5 , 1 , 13 , 49 , 69 , 55 , 205 , 547 , 701 , 1449 , 6689 , 3047 , 12025 ,0 }; - static ulong[] dim2320Kuo3Init = { 1 , 1 , 7 , 9 , 13 , 27 , 31 , 87 , 263 , 499 , 1573 , 619 , 6697 , 9797 , 7673 ,0 }; - static ulong[] dim2321Kuo3Init = { 1 , 1 , 3 , 3 , 1 , 43 , 45 , 81 , 241 , 143 , 2045 , 2847 , 7361 , 12253 , 27815 ,0 }; - static ulong[] dim2322Kuo3Init = { 1 , 1 , 3 , 11 , 27 , 13 , 71 , 119 , 365 , 245 , 113 , 2635 , 7157 , 4951 , 3381 ,0 }; - static ulong[] dim2323Kuo3Init = { 1 , 1 , 7 , 7 , 25 , 23 , 101 , 21 , 247 , 149 , 431 , 3165 , 4109 , 14305 , 22549 ,0 }; - static ulong[] dim2324Kuo3Init = { 1 , 1 , 5 , 1 , 3 , 51 , 79 , 7 , 473 , 337 , 709 , 127 , 555 , 12147 , 19843 ,0 }; - static ulong[] dim2325Kuo3Init = { 1 , 1 , 3 , 5 , 21 , 35 , 125 , 51 , 373 , 859 , 1429 , 2623 , 787 , 9669 , 14933 ,0 }; - static ulong[] dim2326Kuo3Init = { 1 , 1 , 1 , 9 , 25 , 45 , 47 , 251 , 475 , 823 , 1361 , 1393 , 6787 , 14571 , 11311 ,0 }; - static ulong[] dim2327Kuo3Init = { 1 , 3 , 3 , 13 , 1 , 27 , 75 , 153 , 19 , 373 , 209 , 3083 , 8071 , 15401 , 14619 ,0 }; - static ulong[] dim2328Kuo3Init = { 1 , 1 , 1 , 13 , 25 , 39 , 73 , 235 , 251 , 245 , 247 , 1909 , 2057 , 14937 , 16509 ,0 }; - static ulong[] dim2329Kuo3Init = { 1 , 1 , 5 , 11 , 31 , 15 , 117 , 167 , 79 , 911 , 403 , 3595 , 4633 , 11017 , 5021 ,0 }; - static ulong[] dim2330Kuo3Init = { 1 , 1 , 1 , 9 , 9 , 37 , 19 , 179 , 417 , 285 , 1237 , 2667 , 2131 , 5943 , 21265 ,0 }; - static ulong[] dim2331Kuo3Init = { 1 , 3 , 7 , 13 , 29 , 53 , 89 , 223 , 37 , 101 , 1255 , 97 , 3813 , 8543 , 17949 ,0 }; - static ulong[] dim2332Kuo3Init = { 1 , 1 , 1 , 13 , 25 , 61 , 33 , 145 , 271 , 639 , 1539 , 2967 , 1043 , 10259 , 27997 ,0 }; - static ulong[] dim2333Kuo3Init = { 1 , 1 , 3 , 7 , 11 , 17 , 21 , 21 , 159 , 485 , 1855 , 3139 , 6605 , 9567 , 21401 ,0 }; - static ulong[] dim2334Kuo3Init = { 1 , 3 , 7 , 9 , 27 , 23 , 23 , 121 , 17 , 45 , 537 , 3155 , 2409 , 15359 , 16105 ,0 }; - static ulong[] dim2335Kuo3Init = { 1 , 1 , 3 , 13 , 11 , 51 , 87 , 251 , 297 , 227 , 411 , 3737 , 3649 , 14697 , 665 ,0 }; - static ulong[] dim2336Kuo3Init = { 1 , 3 , 5 , 11 , 23 , 23 , 3 , 75 , 99 , 149 , 1505 , 1137 , 6495 , 12629 , 29339 ,0 }; - static ulong[] dim2337Kuo3Init = { 1 , 3 , 1 , 9 , 29 , 1 , 83 , 233 , 387 , 801 , 1387 , 2721 , 1399 , 2275 , 19865 ,0 }; - static ulong[] dim2338Kuo3Init = { 1 , 3 , 7 , 7 , 31 , 33 , 1 , 253 , 71 , 435 , 781 , 2991 , 6881 , 13183 , 10419 ,0 }; - static ulong[] dim2339Kuo3Init = { 1 , 1 , 5 , 11 , 19 , 61 , 25 , 167 , 79 , 173 , 447 , 911 , 6509 , 5531 , 9387 ,0 }; - static ulong[] dim2340Kuo3Init = { 1 , 1 , 1 , 15 , 31 , 23 , 117 , 1 , 119 , 939 , 1277 , 2517 , 2019 , 4979 , 4065 ,0 }; - static ulong[] dim2341Kuo3Init = { 1 , 3 , 3 , 9 , 5 , 49 , 87 , 187 , 159 , 941 , 303 , 217 , 5931 , 9065 , 20043 ,0 }; - static ulong[] dim2342Kuo3Init = { 1 , 3 , 1 , 11 , 31 , 43 , 25 , 45 , 61 , 361 , 2043 , 817 , 8023 , 14309 , 6781 ,0 }; - static ulong[] dim2343Kuo3Init = { 1 , 3 , 7 , 9 , 27 , 45 , 97 , 189 , 387 , 379 , 621 , 2449 , 39 , 10313 , 14603 ,0 }; - static ulong[] dim2344Kuo3Init = { 1 , 3 , 1 , 5 , 5 , 45 , 89 , 251 , 103 , 33 , 1141 , 2957 , 6511 , 8497 , 16609 ,0 }; - static ulong[] dim2345Kuo3Init = { 1 , 3 , 5 , 15 , 19 , 11 , 115 , 255 , 277 , 419 , 15 , 999 , 7509 , 14191 , 2749 ,0 }; - static ulong[] dim2346Kuo3Init = { 1 , 1 , 1 , 7 , 7 , 51 , 127 , 225 , 295 , 389 , 1039 , 2775 , 5531 , 10645 , 13391 ,0 }; - static ulong[] dim2347Kuo3Init = { 1 , 3 , 3 , 11 , 13 , 63 , 37 , 5 , 3 , 737 , 123 , 777 , 1469 , 4009 , 17037 ,0 }; - static ulong[] dim2348Kuo3Init = { 1 , 1 , 3 , 5 , 31 , 43 , 59 , 119 , 287 , 973 , 541 , 751 , 5697 , 7909 , 28673 ,0 }; - static ulong[] dim2349Kuo3Init = { 1 , 1 , 5 , 7 , 15 , 61 , 71 , 213 , 465 , 961 , 1399 , 3227 , 571 , 10759 , 13947 ,0 }; - static ulong[] dim2350Kuo3Init = { 1 , 1 , 5 , 9 , 17 , 53 , 85 , 11 , 185 , 397 , 567 , 3763 , 483 , 6243 , 31191 ,0 }; - static ulong[] dim2351Kuo3Init = { 1 , 3 , 7 , 1 , 31 , 57 , 13 , 255 , 495 , 315 , 763 , 3153 , 5543 , 5719 , 2235 ,0 }; - static ulong[] dim2352Kuo3Init = { 1 , 1 , 1 , 1 , 13 , 25 , 43 , 125 , 391 , 483 , 1029 , 3739 , 4991 , 891 , 24935 ,0 }; - static ulong[] dim2353Kuo3Init = { 1 , 3 , 7 , 3 , 21 , 3 , 79 , 205 , 87 , 3 , 1859 , 1467 , 6129 , 14431 , 18881 ,0 }; - static ulong[] dim2354Kuo3Init = { 1 , 1 , 1 , 11 , 15 , 21 , 79 , 145 , 253 , 595 , 1939 , 2195 , 5735 , 5383 , 5311 ,0 }; - static ulong[] dim2355Kuo3Init = { 1 , 1 , 7 , 3 , 13 , 61 , 89 , 3 , 231 , 867 , 1385 , 183 , 957 , 791 , 2879 ,0 }; - static ulong[] dim2356Kuo3Init = { 1 , 3 , 5 , 7 , 1 , 39 , 47 , 107 , 217 , 725 , 1707 , 2241 , 2813 , 5373 , 23191 ,0 }; - static ulong[] dim2357Kuo3Init = { 1 , 1 , 1 , 5 , 27 , 29 , 119 , 159 , 287 , 343 , 693 , 519 , 2127 , 6083 , 2991 ,0 }; - static ulong[] dim2358Kuo3Init = { 1 , 3 , 3 , 11 , 3 , 51 , 11 , 119 , 337 , 567 , 1175 , 235 , 6801 , 1643 , 26593 ,0 }; - static ulong[] dim2359Kuo3Init = { 1 , 1 , 5 , 3 , 27 , 49 , 91 , 249 , 489 , 257 , 1735 , 3227 , 1419 , 4401 , 12263 ,0 }; - static ulong[] dim2360Kuo3Init = { 1 , 1 , 3 , 13 , 27 , 37 , 101 , 43 , 289 , 313 , 1031 , 2921 , 3655 , 6781 , 29593 ,0 }; - static ulong[] dim2361Kuo3Init = { 1 , 1 , 5 , 5 , 17 , 23 , 117 , 129 , 261 , 919 , 265 , 1561 , 1297 , 815 , 4315 ,0 }; - static ulong[] dim2362Kuo3Init = { 1 , 1 , 3 , 13 , 23 , 31 , 95 , 231 , 99 , 909 , 1477 , 3385 , 5679 , 15319 , 28849 ,0 }; - static ulong[] dim2363Kuo3Init = { 1 , 1 , 5 , 11 , 25 , 27 , 69 , 83 , 15 , 31 , 1469 , 751 , 2339 , 3251 , 17343 ,0 }; - static ulong[] dim2364Kuo3Init = { 1 , 1 , 1 , 9 , 5 , 19 , 49 , 25 , 145 , 763 , 667 , 2003 , 6905 , 15623 , 3533 ,0 }; - static ulong[] dim2365Kuo3Init = { 1 , 1 , 1 , 5 , 5 , 17 , 65 , 151 , 333 , 639 , 1885 , 3561 , 1083 , 7875 , 22647 ,0 }; - static ulong[] dim2366Kuo3Init = { 1 , 3 , 5 , 7 , 25 , 45 , 79 , 175 , 87 , 305 , 1447 , 1935 , 3627 , 6007 , 27877 ,0 }; - static ulong[] dim2367Kuo3Init = { 1 , 3 , 7 , 1 , 11 , 37 , 63 , 37 , 323 , 405 , 1851 , 435 , 1501 , 1345 , 13729 ,0 }; - static ulong[] dim2368Kuo3Init = { 1 , 3 , 7 , 13 , 9 , 37 , 115 , 151 , 255 , 795 , 811 , 681 , 5631 , 489 , 21813 ,0 }; - static ulong[] dim2369Kuo3Init = { 1 , 1 , 1 , 11 , 13 , 25 , 61 , 91 , 367 , 289 , 1093 , 41 , 5073 , 1105 , 28059 ,0 }; - static ulong[] dim2370Kuo3Init = { 1 , 1 , 3 , 13 , 29 , 53 , 13 , 173 , 83 , 313 , 1223 , 719 , 517 , 11689 , 28719 ,0 }; - static ulong[] dim2371Kuo3Init = { 1 , 1 , 5 , 3 , 5 , 21 , 71 , 229 , 95 , 187 , 739 , 2607 , 601 , 2359 , 10603 ,0 }; - static ulong[] dim2372Kuo3Init = { 1 , 1 , 1 , 5 , 25 , 35 , 55 , 131 , 173 , 677 , 1887 , 3293 , 7641 , 13535 , 25561 ,0 }; - static ulong[] dim2373Kuo3Init = { 1 , 3 , 5 , 13 , 29 , 47 , 27 , 1 , 131 , 345 , 1751 , 1807 , 235 , 1891 , 5909 ,0 }; - static ulong[] dim2374Kuo3Init = { 1 , 1 , 3 , 3 , 15 , 41 , 55 , 201 , 263 , 831 , 401 , 2685 , 7403 , 11827 , 15353 ,0 }; - static ulong[] dim2375Kuo3Init = { 1 , 3 , 1 , 7 , 5 , 3 , 99 , 61 , 433 , 641 , 1817 , 891 , 1937 , 7179 , 14391 ,0 }; - static ulong[] dim2376Kuo3Init = { 1 , 1 , 5 , 15 , 19 , 33 , 37 , 223 , 329 , 5 , 1897 , 2737 , 4339 , 9325 , 12199 ,0 }; - static ulong[] dim2377Kuo3Init = { 1 , 1 , 5 , 3 , 3 , 23 , 47 , 125 , 85 , 61 , 1133 , 2467 , 1991 , 8059 , 153 ,0 }; - static ulong[] dim2378Kuo3Init = { 1 , 1 , 1 , 15 , 29 , 45 , 117 , 133 , 447 , 627 , 525 , 173 , 1165 , 11939 , 21807 ,0 }; - static ulong[] dim2379Kuo3Init = { 1 , 1 , 1 , 3 , 1 , 15 , 5 , 49 , 237 , 675 , 717 , 2783 , 4287 , 11485 , 3797 ,0 }; - static ulong[] dim2380Kuo3Init = { 1 , 3 , 5 , 15 , 19 , 63 , 23 , 79 , 313 , 1007 , 1321 , 229 , 7537 , 825 , 29127 ,0 }; - static ulong[] dim2381Kuo3Init = { 1 , 1 , 3 , 15 , 15 , 55 , 1 , 229 , 221 , 359 , 1021 , 3307 , 4993 , 8781 , 29275 ,0 }; - static ulong[] dim2382Kuo3Init = { 1 , 3 , 3 , 11 , 17 , 57 , 37 , 207 , 283 , 599 , 1867 , 31 , 6631 , 10605 , 29671 ,0 }; - static ulong[] dim2383Kuo3Init = { 1 , 3 , 3 , 9 , 25 , 9 , 111 , 87 , 325 , 515 , 1249 , 2027 , 7783 , 6473 , 23737 ,0 }; - static ulong[] dim2384Kuo3Init = { 1 , 3 , 3 , 3 , 31 , 11 , 39 , 161 , 65 , 259 , 1747 , 597 , 913 , 12397 , 25611 ,0 }; - static ulong[] dim2385Kuo3Init = { 1 , 3 , 5 , 11 , 31 , 37 , 27 , 157 , 411 , 785 , 1699 , 467 , 3993 , 6357 , 11039 ,0 }; - static ulong[] dim2386Kuo3Init = { 1 , 3 , 3 , 7 , 5 , 41 , 61 , 103 , 33 , 789 , 1861 , 319 , 7667 , 10169 , 10823 ,0 }; - static ulong[] dim2387Kuo3Init = { 1 , 1 , 7 , 5 , 31 , 37 , 45 , 175 , 453 , 423 , 291 , 3989 , 2215 , 11379 , 28713 ,0 }; - static ulong[] dim2388Kuo3Init = { 1 , 3 , 3 , 1 , 23 , 39 , 75 , 103 , 341 , 961 , 2039 , 1539 , 7831 , 1665 , 18579 ,0 }; - static ulong[] dim2389Kuo3Init = { 1 , 1 , 5 , 13 , 19 , 25 , 27 , 183 , 241 , 539 , 257 , 3 , 3709 , 8133 , 31081 ,0 }; - static ulong[] dim2390Kuo3Init = { 1 , 1 , 3 , 15 , 1 , 53 , 27 , 229 , 299 , 913 , 1277 , 2687 , 831 , 1065 , 4409 ,0 }; - static ulong[] dim2391Kuo3Init = { 1 , 1 , 7 , 9 , 13 , 47 , 127 , 145 , 481 , 751 , 1745 , 3645 , 2853 , 5601 , 14991 ,0 }; - static ulong[] dim2392Kuo3Init = { 1 , 3 , 7 , 3 , 3 , 39 , 31 , 191 , 69 , 707 , 1757 , 223 , 5055 , 14777 , 4433 ,0 }; - static ulong[] dim2393Kuo3Init = { 1 , 1 , 7 , 15 , 27 , 33 , 77 , 75 , 357 , 1007 , 1373 , 3445 , 2597 , 6085 , 19441 ,0 }; - static ulong[] dim2394Kuo3Init = { 1 , 1 , 1 , 9 , 13 , 53 , 77 , 61 , 425 , 245 , 1149 , 1239 , 1989 , 1293 , 12971 ,0 }; - static ulong[] dim2395Kuo3Init = { 1 , 1 , 1 , 7 , 23 , 43 , 29 , 89 , 349 , 411 , 2021 , 2075 , 4917 , 11387 , 27045 ,0 }; - static ulong[] dim2396Kuo3Init = { 1 , 1 , 5 , 11 , 27 , 63 , 71 , 19 , 363 , 289 , 1147 , 2541 , 4427 , 591 , 21287 ,0 }; - static ulong[] dim2397Kuo3Init = { 1 , 1 , 1 , 3 , 27 , 3 , 1 , 159 , 85 , 651 , 1109 , 1885 , 5639 , 11725 , 1527 ,0 }; - static ulong[] dim2398Kuo3Init = { 1 , 1 , 3 , 1 , 11 , 63 , 77 , 185 , 233 , 129 , 1721 , 2419 , 2043 , 3121 , 2159 ,0 }; - static ulong[] dim2399Kuo3Init = { 1 , 1 , 1 , 3 , 11 , 27 , 83 , 193 , 143 , 89 , 1927 , 3753 , 4041 , 10397 , 1973 ,0 }; - static ulong[] dim2400Kuo3Init = { 1 , 1 , 5 , 1 , 9 , 61 , 49 , 29 , 333 , 621 , 1555 , 4051 , 3011 , 12075 , 4699 ,0 }; - static ulong[] dim2401Kuo3Init = { 1 , 3 , 1 , 5 , 25 , 37 , 69 , 81 , 271 , 827 , 763 , 2973 , 3729 , 2339 , 4783 ,0 }; - static ulong[] dim2402Kuo3Init = { 1 , 3 , 1 , 7 , 23 , 1 , 95 , 143 , 417 , 517 , 1991 , 1423 , 7511 , 125 , 18675 ,0 }; - static ulong[] dim2403Kuo3Init = { 1 , 3 , 5 , 9 , 3 , 43 , 71 , 73 , 443 , 335 , 737 , 1121 , 8001 , 13165 , 11155 ,0 }; - static ulong[] dim2404Kuo3Init = { 1 , 3 , 1 , 11 , 1 , 21 , 39 , 149 , 261 , 963 , 117 , 3421 , 2603 , 4035 , 4801 ,0 }; - static ulong[] dim2405Kuo3Init = { 1 , 3 , 5 , 7 , 23 , 63 , 101 , 71 , 495 , 649 , 469 , 2559 , 541 , 4499 , 20357 ,0 }; - static ulong[] dim2406Kuo3Init = { 1 , 1 , 5 , 7 , 31 , 37 , 107 , 239 , 197 , 695 , 1403 , 2193 , 5583 , 16019 , 11599 ,0 }; - static ulong[] dim2407Kuo3Init = { 1 , 1 , 5 , 3 , 21 , 25 , 127 , 255 , 259 , 209 , 1491 , 349 , 737 , 9781 , 3697 ,0 }; - static ulong[] dim2408Kuo3Init = { 1 , 1 , 5 , 9 , 3 , 47 , 43 , 123 , 315 , 983 , 349 , 2139 , 6233 , 731 , 745 ,0 }; - static ulong[] dim2409Kuo3Init = { 1 , 1 , 1 , 1 , 25 , 63 , 95 , 101 , 483 , 439 , 1073 , 1813 , 3809 , 11987 , 4607 ,0 }; - static ulong[] dim2410Kuo3Init = { 1 , 1 , 3 , 5 , 23 , 11 , 11 , 101 , 9 , 599 , 931 , 39 , 6593 , 14875 , 13557 ,0 }; - static ulong[] dim2411Kuo3Init = { 1 , 3 , 3 , 3 , 21 , 59 , 107 , 131 , 221 , 351 , 1057 , 3689 , 7471 , 4659 , 27303 ,0 }; - static ulong[] dim2412Kuo3Init = { 1 , 1 , 5 , 5 , 19 , 59 , 79 , 81 , 169 , 927 , 1439 , 2305 , 2413 , 2935 , 28571 ,0 }; - static ulong[] dim2413Kuo3Init = { 1 , 3 , 7 , 5 , 17 , 37 , 81 , 125 , 347 , 81 , 1029 , 705 , 7321 , 4877 , 28743 ,0 }; - static ulong[] dim2414Kuo3Init = { 1 , 3 , 5 , 5 , 21 , 27 , 113 , 161 , 177 , 49 , 1655 , 4035 , 4987 , 5545 , 13137 ,0 }; - static ulong[] dim2415Kuo3Init = { 1 , 1 , 5 , 13 , 5 , 19 , 117 , 13 , 379 , 449 , 765 , 1395 , 1051 , 14783 , 22283 ,0 }; - static ulong[] dim2416Kuo3Init = { 1 , 1 , 7 , 13 , 25 , 57 , 59 , 47 , 15 , 425 , 1359 , 1019 , 4933 , 6289 , 2943 ,0 }; - static ulong[] dim2417Kuo3Init = { 1 , 3 , 7 , 15 , 7 , 31 , 95 , 245 , 243 , 515 , 893 , 2451 , 83 , 6561 , 20993 ,0 }; - static ulong[] dim2418Kuo3Init = { 1 , 3 , 1 , 13 , 7 , 45 , 39 , 227 , 245 , 793 , 1103 , 3279 , 6967 , 14771 , 23199 ,0 }; - static ulong[] dim2419Kuo3Init = { 1 , 3 , 5 , 9 , 21 , 5 , 103 , 27 , 509 , 187 , 1727 , 1281 , 923 , 8305 , 29315 ,0 }; - static ulong[] dim2420Kuo3Init = { 1 , 3 , 1 , 13 , 13 , 3 , 3 , 57 , 231 , 609 , 695 , 3461 , 6565 , 16003 , 12719 ,0 }; - static ulong[] dim2421Kuo3Init = { 1 , 1 , 5 , 7 , 13 , 55 , 49 , 111 , 111 , 947 , 1047 , 3745 , 8141 , 13181 , 25703 ,0 }; - static ulong[] dim2422Kuo3Init = { 1 , 3 , 7 , 15 , 17 , 51 , 37 , 253 , 97 , 363 , 1617 , 1201 , 3199 , 11871 , 29389 ,0 }; - static ulong[] dim2423Kuo3Init = { 1 , 3 , 3 , 5 , 23 , 13 , 73 , 85 , 53 , 699 , 1707 , 2137 , 4537 , 15375 , 28251 ,0 }; - static ulong[] dim2424Kuo3Init = { 1 , 3 , 3 , 7 , 17 , 35 , 29 , 251 , 455 , 153 , 1703 , 1535 , 4801 , 12889 , 5959 ,0 }; - static ulong[] dim2425Kuo3Init = { 1 , 3 , 1 , 1 , 15 , 61 , 75 , 21 , 211 , 425 , 1459 , 1347 , 7525 , 15465 , 28191 ,0 }; - static ulong[] dim2426Kuo3Init = { 1 , 1 , 5 , 15 , 3 , 1 , 7 , 163 , 317 , 85 , 385 , 3183 , 1901 , 6265 , 13773 ,0 }; - static ulong[] dim2427Kuo3Init = { 1 , 1 , 5 , 1 , 31 , 43 , 63 , 15 , 157 , 711 , 617 , 2283 , 1269 , 15661 , 28559 ,0 }; - static ulong[] dim2428Kuo3Init = { 1 , 3 , 5 , 1 , 19 , 57 , 1 , 149 , 183 , 9 , 1587 , 2711 , 6563 , 9291 , 287 ,0 }; - static ulong[] dim2429Kuo3Init = { 1 , 3 , 1 , 7 , 3 , 47 , 11 , 85 , 97 , 245 , 1673 , 1147 , 2187 , 2361 , 4417 ,0 }; - static ulong[] dim2430Kuo3Init = { 1 , 3 , 5 , 7 , 9 , 17 , 75 , 3 , 449 , 145 , 1695 , 597 , 6931 , 2281 , 27291 ,0 }; - static ulong[] dim2431Kuo3Init = { 1 , 1 , 1 , 7 , 7 , 51 , 53 , 53 , 463 , 669 , 677 , 3579 , 2609 , 4147 , 27567 ,0 }; - static ulong[] dim2432Kuo3Init = { 1 , 1 , 5 , 13 , 29 , 63 , 3 , 195 , 507 , 43 , 425 , 2121 , 8147 , 1287 , 15137 ,0 }; - static ulong[] dim2433Kuo3Init = { 1 , 1 , 7 , 9 , 17 , 7 , 3 , 139 , 301 , 647 , 817 , 3657 , 3217 , 4651 , 21497 ,0 }; - static ulong[] dim2434Kuo3Init = { 1 , 1 , 3 , 13 , 11 , 43 , 87 , 139 , 441 , 13 , 1555 , 2855 , 4891 , 3835 , 17465 ,0 }; - static ulong[] dim2435Kuo3Init = { 1 , 3 , 1 , 3 , 15 , 47 , 29 , 99 , 481 , 377 , 455 , 929 , 1977 , 7221 , 2517 ,0 }; - static ulong[] dim2436Kuo3Init = { 1 , 3 , 1 , 9 , 7 , 41 , 65 , 19 , 17 , 573 , 1007 , 2097 , 4251 , 4067 , 17217 ,0 }; - static ulong[] dim2437Kuo3Init = { 1 , 3 , 3 , 13 , 27 , 53 , 41 , 223 , 67 , 747 , 163 , 1483 , 1827 , 11977 , 17451 ,0 }; - static ulong[] dim2438Kuo3Init = { 1 , 3 , 5 , 13 , 17 , 51 , 109 , 11 , 105 , 481 , 239 , 787 , 5337 , 14103 , 10499 ,0 }; - static ulong[] dim2439Kuo3Init = { 1 , 1 , 3 , 11 , 31 , 25 , 13 , 139 , 37 , 307 , 331 , 633 , 7907 , 4705 , 26019 ,0 }; - static ulong[] dim2440Kuo3Init = { 1 , 1 , 7 , 5 , 25 , 27 , 11 , 33 , 463 , 141 , 1409 , 2449 , 2211 , 10729 , 28935 ,0 }; - static ulong[] dim2441Kuo3Init = { 1 , 3 , 3 , 13 , 1 , 39 , 53 , 81 , 117 , 79 , 563 , 3735 , 253 , 10483 , 28129 ,0 }; - static ulong[] dim2442Kuo3Init = { 1 , 1 , 3 , 3 , 7 , 7 , 103 , 233 , 341 , 765 , 11 , 3735 , 4011 , 8075 , 10239 ,0 }; - static ulong[] dim2443Kuo3Init = { 1 , 3 , 7 , 7 , 25 , 23 , 83 , 139 , 255 , 441 , 611 , 1583 , 733 , 673 , 21145 ,0 }; - static ulong[] dim2444Kuo3Init = { 1 , 1 , 3 , 5 , 29 , 7 , 49 , 31 , 417 , 41 , 133 , 2119 , 3871 , 16029 , 25649 ,0 }; - static ulong[] dim2445Kuo3Init = { 1 , 3 , 5 , 5 , 13 , 17 , 99 , 213 , 149 , 1015 , 987 , 2497 , 7419 , 183 , 27645 ,0 }; - static ulong[] dim2446Kuo3Init = { 1 , 3 , 3 , 1 , 25 , 13 , 107 , 211 , 113 , 909 , 1625 , 2893 , 3957 , 10657 , 16739 ,0 }; - static ulong[] dim2447Kuo3Init = { 1 , 1 , 5 , 11 , 5 , 3 , 97 , 61 , 189 , 779 , 1633 , 71 , 3751 , 4589 , 30795 ,0 }; - static ulong[] dim2448Kuo3Init = { 1 , 3 , 3 , 15 , 3 , 15 , 33 , 175 , 307 , 937 , 1713 , 833 , 2141 , 1019 , 26093 ,0 }; - static ulong[] dim2449Kuo3Init = { 1 , 1 , 7 , 9 , 15 , 31 , 9 , 45 , 197 , 905 , 1343 , 27 , 6835 , 4353 , 7229 ,0 }; - static ulong[] dim2450Kuo3Init = { 1 , 1 , 7 , 15 , 23 , 15 , 73 , 217 , 283 , 853 , 987 , 389 , 3875 , 4353 , 26667 ,0 }; - static ulong[] dim2451Kuo3Init = { 1 , 3 , 1 , 7 , 9 , 1 , 121 , 39 , 343 , 225 , 143 , 343 , 5573 , 14997 , 15723 ,0 }; - static ulong[] dim2452Kuo3Init = { 1 , 1 , 5 , 5 , 19 , 35 , 73 , 177 , 15 , 697 , 885 , 3917 , 6267 , 14557 , 30395 ,0 }; - static ulong[] dim2453Kuo3Init = { 1 , 1 , 3 , 5 , 3 , 47 , 59 , 253 , 107 , 251 , 1081 , 3115 , 1295 , 9261 , 22389 ,0 }; - static ulong[] dim2454Kuo3Init = { 1 , 1 , 5 , 15 , 29 , 47 , 113 , 153 , 205 , 5 , 507 , 1313 , 3329 , 3043 , 10135 ,0 }; - static ulong[] dim2455Kuo3Init = { 1 , 1 , 1 , 3 , 29 , 39 , 15 , 147 , 439 , 975 , 415 , 3385 , 5379 , 8957 , 3441 ,0 }; - static ulong[] dim2456Kuo3Init = { 1 , 1 , 1 , 11 , 23 , 35 , 97 , 251 , 399 , 653 , 1327 , 3805 , 6475 , 1729 , 29557 ,0 }; - static ulong[] dim2457Kuo3Init = { 1 , 1 , 3 , 13 , 1 , 5 , 63 , 67 , 209 , 1005 , 383 , 2279 , 509 , 7039 , 24973 ,0 }; - static ulong[] dim2458Kuo3Init = { 1 , 1 , 7 , 7 , 17 , 59 , 1 , 5 , 325 , 703 , 1937 , 2699 , 163 , 10115 , 8407 ,0 }; - static ulong[] dim2459Kuo3Init = { 1 , 3 , 1 , 3 , 25 , 27 , 73 , 183 , 41 , 373 , 909 , 3957 , 7135 , 2401 , 24963 ,0 }; - static ulong[] dim2460Kuo3Init = { 1 , 1 , 5 , 7 , 21 , 3 , 113 , 19 , 279 , 729 , 669 , 1403 , 881 , 3581 , 29297 ,0 }; - static ulong[] dim2461Kuo3Init = { 1 , 3 , 3 , 1 , 29 , 9 , 39 , 97 , 133 , 369 , 515 , 1279 , 2061 , 5785 , 29799 ,0 }; - static ulong[] dim2462Kuo3Init = { 1 , 1 , 1 , 7 , 15 , 9 , 33 , 227 , 13 , 117 , 1903 , 2437 , 451 , 10029 , 27469 ,0 }; - static ulong[] dim2463Kuo3Init = { 1 , 1 , 1 , 5 , 25 , 3 , 17 , 11 , 439 , 701 , 1319 , 3357 , 5487 , 11165 , 14077 ,0 }; - static ulong[] dim2464Kuo3Init = { 1 , 3 , 1 , 9 , 19 , 61 , 115 , 83 , 381 , 261 , 1025 , 3215 , 6889 , 6123 , 3761 ,0 }; - static ulong[] dim2465Kuo3Init = { 1 , 3 , 3 , 11 , 21 , 17 , 37 , 151 , 447 , 683 , 811 , 2551 , 6735 , 16189 , 13109 ,0 }; - static ulong[] dim2466Kuo3Init = { 1 , 1 , 1 , 5 , 5 , 61 , 11 , 223 , 221 , 755 , 65 , 913 , 6285 , 13337 , 27473 ,0 }; - static ulong[] dim2467Kuo3Init = { 1 , 1 , 1 , 13 , 15 , 37 , 93 , 7 , 249 , 809 , 1819 , 3297 , 4555 , 9013 , 16243 ,0 }; - static ulong[] dim2468Kuo3Init = { 1 , 1 , 1 , 9 , 3 , 1 , 13 , 45 , 407 , 203 , 963 , 1055 , 727 , 2269 , 18663 ,0 }; - static ulong[] dim2469Kuo3Init = { 1 , 3 , 7 , 13 , 3 , 19 , 95 , 87 , 341 , 337 , 557 , 307 , 7827 , 15479 , 24617 ,0 }; - static ulong[] dim2470Kuo3Init = { 1 , 1 , 1 , 3 , 31 , 3 , 125 , 163 , 439 , 971 , 815 , 1785 , 2637 , 2973 , 15405 ,0 }; - static ulong[] dim2471Kuo3Init = { 1 , 3 , 1 , 15 , 13 , 61 , 25 , 151 , 227 , 173 , 215 , 3151 , 4201 , 6011 , 13655 ,0 }; - static ulong[] dim2472Kuo3Init = { 1 , 3 , 1 , 9 , 27 , 7 , 13 , 95 , 511 , 373 , 2023 , 1019 , 3229 , 2513 , 20929 ,0 }; - static ulong[] dim2473Kuo3Init = { 1 , 3 , 7 , 13 , 11 , 19 , 93 , 159 , 461 , 209 , 549 , 119 , 7419 , 6969 , 29707 ,0 }; - static ulong[] dim2474Kuo3Init = { 1 , 3 , 1 , 7 , 17 , 41 , 53 , 239 , 121 , 529 , 27 , 2129 , 4675 , 5159 , 5767 ,0 }; - static ulong[] dim2475Kuo3Init = { 1 , 1 , 1 , 15 , 23 , 45 , 31 , 189 , 427 , 583 , 191 , 1123 , 3183 , 5499 , 25925 ,0 }; - static ulong[] dim2476Kuo3Init = { 1 , 3 , 7 , 1 , 3 , 17 , 39 , 15 , 257 , 567 , 459 , 3731 , 1315 , 10975 , 23725 ,0 }; - static ulong[] dim2477Kuo3Init = { 1 , 3 , 1 , 11 , 27 , 43 , 31 , 101 , 285 , 249 , 1467 , 3937 , 6413 , 611 , 10287 ,0 }; - static ulong[] dim2478Kuo3Init = { 1 , 1 , 5 , 7 , 19 , 35 , 5 , 225 , 211 , 57 , 1849 , 3915 , 5275 , 13909 , 18885 ,0 }; - static ulong[] dim2479Kuo3Init = { 1 , 1 , 5 , 3 , 17 , 45 , 45 , 197 , 311 , 777 , 2013 , 927 , 6209 , 15495 , 30027 ,0 }; - static ulong[] dim2480Kuo3Init = { 1 , 1 , 7 , 11 , 9 , 13 , 37 , 81 , 389 , 459 , 671 , 2567 , 7357 , 5339 , 13729 ,0 }; - static ulong[] dim2481Kuo3Init = { 1 , 3 , 1 , 3 , 29 , 31 , 63 , 189 , 271 , 543 , 229 , 1385 , 2031 , 8993 , 5665 ,0 }; - static ulong[] dim2482Kuo3Init = { 1 , 3 , 5 , 11 , 5 , 25 , 39 , 225 , 121 , 207 , 1161 , 1739 , 6627 , 11129 , 475 ,0 }; - static ulong[] dim2483Kuo3Init = { 1 , 1 , 7 , 7 , 19 , 7 , 29 , 83 , 25 , 707 , 197 , 335 , 2613 , 10035 , 20157 ,0 }; - static ulong[] dim2484Kuo3Init = { 1 , 3 , 3 , 7 , 7 , 63 , 99 , 169 , 221 , 125 , 563 , 1351 , 3867 , 14903 , 27469 ,0 }; - static ulong[] dim2485Kuo3Init = { 1 , 3 , 3 , 7 , 25 , 5 , 31 , 151 , 213 , 555 , 481 , 3955 , 4347 , 8811 , 30687 ,0 }; - static ulong[] dim2486Kuo3Init = { 1 , 1 , 5 , 13 , 23 , 9 , 59 , 149 , 351 , 819 , 311 , 233 , 4409 , 3539 , 6509 ,0 }; - static ulong[] dim2487Kuo3Init = { 1 , 3 , 3 , 7 , 1 , 11 , 3 , 161 , 473 , 65 , 1793 , 367 , 5115 , 15743 , 27175 ,0 }; - static ulong[] dim2488Kuo3Init = { 1 , 3 , 3 , 9 , 15 , 61 , 5 , 125 , 53 , 523 , 1365 , 1909 , 7689 , 10799 , 29199 ,0 }; - static ulong[] dim2489Kuo3Init = { 1 , 1 , 3 , 7 , 13 , 43 , 31 , 179 , 73 , 611 , 293 , 2349 , 4873 , 11271 , 29827 ,0 }; - static ulong[] dim2490Kuo3Init = { 1 , 1 , 5 , 5 , 27 , 31 , 107 , 197 , 409 , 405 , 789 , 1529 , 7793 , 5679 , 25127 ,0 }; - static ulong[] dim2491Kuo3Init = { 1 , 3 , 5 , 1 , 23 , 35 , 37 , 119 , 99 , 891 , 877 , 1799 , 5647 , 13983 , 22321 ,0 }; - static ulong[] dim2492Kuo3Init = { 1 , 3 , 3 , 13 , 9 , 49 , 29 , 245 , 447 , 963 , 211 , 3233 , 2883 , 5467 , 24057 ,0 }; - static ulong[] dim2493Kuo3Init = { 1 , 1 , 3 , 5 , 7 , 29 , 77 , 7 , 47 , 141 , 799 , 2009 , 7731 , 4371 , 24529 ,0 }; - static ulong[] dim2494Kuo3Init = { 1 , 1 , 7 , 7 , 19 , 31 , 65 , 21 , 417 , 395 , 653 , 1751 , 2989 , 6721 , 28155 ,0 }; - static ulong[] dim2495Kuo3Init = { 1 , 1 , 3 , 9 , 1 , 5 , 117 , 119 , 39 , 949 , 1081 , 1919 , 5689 , 8367 , 19043 ,0 }; - static ulong[] dim2496Kuo3Init = { 1 , 3 , 3 , 13 , 29 , 45 , 73 , 49 , 393 , 545 , 581 , 689 , 2597 , 5757 , 26953 ,0 }; - static ulong[] dim2497Kuo3Init = { 1 , 1 , 7 , 13 , 3 , 13 , 1 , 97 , 73 , 517 , 795 , 2755 , 5109 , 15771 , 19297 ,0 }; - static ulong[] dim2498Kuo3Init = { 1 , 3 , 1 , 7 , 11 , 5 , 117 , 179 , 507 , 483 , 143 , 1441 , 3247 , 7557 , 10939 ,0 }; - static ulong[] dim2499Kuo3Init = { 1 , 1 , 7 , 1 , 7 , 9 , 1 , 1 , 465 , 1019 , 37 , 2011 , 4065 , 725 , 10133 ,0 }; - static ulong[] dim2500Kuo3Init = { 1 , 1 , 7 , 13 , 15 , 39 , 69 , 167 , 399 , 571 , 1089 , 1787 , 8097 , 3209 , 25689 ,0 }; - static ulong[] dim2501Kuo3Init = { 1 , 1 , 7 , 3 , 7 , 23 , 17 , 197 , 43 , 727 , 543 , 1307 , 2701 , 4121 , 29165 ,0 }; - static ulong[] dim2502Kuo3Init = { 1 , 1 , 7 , 3 , 3 , 29 , 57 , 89 , 269 , 667 , 705 , 2427 , 47 , 5535 , 21861 ,0 }; - static ulong[] dim2503Kuo3Init = { 1 , 1 , 1 , 13 , 3 , 43 , 55 , 55 , 337 , 567 , 63 , 3061 , 5191 , 16365 , 24415 ,0 }; - static ulong[] dim2504Kuo3Init = { 1 , 1 , 5 , 9 , 3 , 31 , 123 , 101 , 149 , 131 , 1037 , 3925 , 861 , 12811 , 23787 ,0 }; - static ulong[] dim2505Kuo3Init = { 1 , 3 , 1 , 5 , 1 , 5 , 71 , 7 , 113 , 797 , 863 , 1199 , 1911 , 2551 , 12423 ,0 }; - static ulong[] dim2506Kuo3Init = { 1 , 3 , 1 , 11 , 19 , 17 , 25 , 231 , 7 , 137 , 127 , 2297 , 3345 , 729 , 909 ,0 }; - static ulong[] dim2507Kuo3Init = { 1 , 1 , 5 , 9 , 17 , 13 , 5 , 227 , 327 , 335 , 1463 , 2685 , 6301 , 15547 , 13151 ,0 }; - static ulong[] dim2508Kuo3Init = { 1 , 3 , 5 , 9 , 9 , 25 , 87 , 53 , 107 , 219 , 861 , 1615 , 371 , 4983 , 6445 ,0 }; - static ulong[] dim2509Kuo3Init = { 1 , 3 , 3 , 13 , 21 , 59 , 109 , 53 , 365 , 293 , 1373 , 147 , 4215 , 1007 , 20401 ,0 }; - static ulong[] dim2510Kuo3Init = { 1 , 3 , 3 , 5 , 5 , 25 , 113 , 233 , 317 , 121 , 427 , 3561 , 701 , 10169 , 23449 ,0 }; - static ulong[] dim2511Kuo3Init = { 1 , 3 , 5 , 9 , 9 , 41 , 123 , 199 , 305 , 639 , 1131 , 3635 , 8125 , 4007 , 6883 ,0 }; - static ulong[] dim2512Kuo3Init = { 1 , 3 , 1 , 13 , 23 , 5 , 105 , 25 , 281 , 301 , 1011 , 3647 , 263 , 3389 , 5527 ,0 }; - static ulong[] dim2513Kuo3Init = { 1 , 1 , 5 , 15 , 17 , 59 , 33 , 175 , 115 , 625 , 975 , 3189 , 6973 , 8291 , 14201 ,0 }; - static ulong[] dim2514Kuo3Init = { 1 , 3 , 3 , 5 , 1 , 41 , 39 , 231 , 57 , 95 , 623 , 2199 , 3821 , 1627 , 4035 ,0 }; - static ulong[] dim2515Kuo3Init = { 1 , 3 , 5 , 11 , 25 , 5 , 1 , 21 , 457 , 875 , 355 , 389 , 1623 , 9575 , 1283 ,0 }; - static ulong[] dim2516Kuo3Init = { 1 , 3 , 1 , 1 , 21 , 29 , 83 , 45 , 315 , 735 , 1253 , 3743 , 7163 , 5163 , 10833 ,0 }; - static ulong[] dim2517Kuo3Init = { 1 , 3 , 5 , 13 , 1 , 5 , 47 , 21 , 231 , 1019 , 1851 , 21 , 1699 , 851 , 11857 ,0 }; - static ulong[] dim2518Kuo3Init = { 1 , 3 , 5 , 7 , 19 , 9 , 61 , 241 , 175 , 191 , 415 , 1197 , 5643 , 9765 , 17375 ,0 }; - static ulong[] dim2519Kuo3Init = { 1 , 3 , 5 , 1 , 3 , 5 , 35 , 231 , 471 , 175 , 1715 , 487 , 2299 , 12355 , 5113 ,0 }; - static ulong[] dim2520Kuo3Init = { 1 , 1 , 3 , 9 , 15 , 45 , 33 , 93 , 289 , 371 , 275 , 1703 , 6925 , 5511 , 3203 ,0 }; - static ulong[] dim2521Kuo3Init = { 1 , 3 , 5 , 7 , 21 , 55 , 105 , 199 , 435 , 955 , 731 , 719 , 1571 , 7341 , 5255 ,0 }; - static ulong[] dim2522Kuo3Init = { 1 , 3 , 7 , 7 , 1 , 3 , 127 , 85 , 11 , 165 , 1423 , 3889 , 7509 , 14687 , 23383 ,0 }; - static ulong[] dim2523Kuo3Init = { 1 , 1 , 7 , 11 , 31 , 61 , 9 , 141 , 357 , 801 , 1785 , 3813 , 3437 , 10853 , 17191 ,0 }; - static ulong[] dim2524Kuo3Init = { 1 , 1 , 7 , 5 , 23 , 59 , 17 , 205 , 449 , 107 , 1123 , 1089 , 5499 , 12251 , 653 ,0 }; - static ulong[] dim2525Kuo3Init = { 1 , 3 , 1 , 5 , 3 , 25 , 71 , 229 , 263 , 423 , 1357 , 3709 , 1719 , 2799 , 10943 ,0 }; - static ulong[] dim2526Kuo3Init = { 1 , 1 , 5 , 13 , 1 , 23 , 97 , 209 , 401 , 809 , 783 , 2455 , 1137 , 13941 , 12751 ,0 }; - static ulong[] dim2527Kuo3Init = { 1 , 3 , 3 , 11 , 21 , 47 , 25 , 29 , 471 , 677 , 1129 , 2689 , 929 , 5635 , 26509 ,0 }; - static ulong[] dim2528Kuo3Init = { 1 , 3 , 1 , 5 , 7 , 27 , 5 , 195 , 435 , 255 , 395 , 2775 , 297 , 6909 , 2289 ,0 }; - static ulong[] dim2529Kuo3Init = { 1 , 1 , 1 , 9 , 7 , 53 , 109 , 85 , 141 , 243 , 1433 , 1531 , 5461 , 1111 , 7889 ,0 }; - static ulong[] dim2530Kuo3Init = { 1 , 3 , 7 , 11 , 13 , 47 , 91 , 51 , 489 , 433 , 1667 , 2955 , 5135 , 11949 , 14123 ,0 }; - static ulong[] dim2531Kuo3Init = { 1 , 1 , 7 , 15 , 5 , 57 , 57 , 147 , 97 , 709 , 1757 , 1493 , 2715 , 12583 , 18991 ,0 }; - static ulong[] dim2532Kuo3Init = { 1 , 3 , 1 , 15 , 7 , 17 , 79 , 75 , 397 , 555 , 787 , 1405 , 4749 , 6723 , 3749 ,0 }; - static ulong[] dim2533Kuo3Init = { 1 , 1 , 3 , 11 , 21 , 59 , 5 , 211 , 215 , 393 , 1445 , 4057 , 5115 , 821 , 7783 ,0 }; - static ulong[] dim2534Kuo3Init = { 1 , 1 , 3 , 5 , 29 , 1 , 97 , 201 , 21 , 287 , 1735 , 2397 , 3401 , 2017 , 32229 ,0 }; - static ulong[] dim2535Kuo3Init = { 1 , 1 , 3 , 13 , 17 , 43 , 71 , 25 , 243 , 423 , 733 , 1917 , 1235 , 3527 , 22695 ,0 }; - static ulong[] dim2536Kuo3Init = { 1 , 1 , 3 , 15 , 27 , 7 , 25 , 239 , 493 , 945 , 397 , 3837 , 5465 , 12273 , 26025 ,0 }; - static ulong[] dim2537Kuo3Init = { 1 , 3 , 1 , 7 , 17 , 17 , 61 , 7 , 487 , 439 , 1433 , 1761 , 6507 , 487 , 32633 ,0 }; - static ulong[] dim2538Kuo3Init = { 1 , 3 , 3 , 9 , 21 , 29 , 83 , 27 , 321 , 73 , 1247 , 2593 , 6935 , 7009 , 31617 ,0 }; - static ulong[] dim2539Kuo3Init = { 1 , 3 , 3 , 1 , 25 , 37 , 99 , 177 , 357 , 527 , 1259 , 3625 , 4277 , 15243 , 28615 ,0 }; - static ulong[] dim2540Kuo3Init = { 1 , 1 , 3 , 13 , 29 , 31 , 59 , 177 , 73 , 1007 , 1809 , 2143 , 7375 , 4321 , 3771 ,0 }; - static ulong[] dim2541Kuo3Init = { 1 , 3 , 3 , 3 , 21 , 7 , 123 , 253 , 87 , 995 , 103 , 561 , 7639 , 10087 , 4149 ,0 }; - static ulong[] dim2542Kuo3Init = { 1 , 1 , 5 , 13 , 11 , 31 , 53 , 249 , 435 , 361 , 367 , 783 , 7525 , 5361 , 21535 ,0 }; - static ulong[] dim2543Kuo3Init = { 1 , 3 , 7 , 5 , 15 , 25 , 31 , 9 , 29 , 907 , 77 , 2585 , 2929 , 12153 , 19401 ,0 }; - static ulong[] dim2544Kuo3Init = { 1 , 3 , 5 , 5 , 15 , 1 , 101 , 99 , 209 , 583 , 679 , 1005 , 2271 , 269 , 29527 ,0 }; - static ulong[] dim2545Kuo3Init = { 1 , 1 , 3 , 1 , 13 , 35 , 85 , 83 , 77 , 999 , 1485 , 2817 , 7001 , 13659 , 25061 ,0 }; - static ulong[] dim2546Kuo3Init = { 1 , 3 , 7 , 13 , 19 , 15 , 19 , 65 , 195 , 693 , 1399 , 2875 , 255 , 6617 , 7907 ,0 }; - static ulong[] dim2547Kuo3Init = { 1 , 1 , 5 , 5 , 13 , 25 , 67 , 195 , 131 , 481 , 1831 , 873 , 6281 , 4935 , 2311 ,0 }; - static ulong[] dim2548Kuo3Init = { 1 , 1 , 1 , 15 , 27 , 47 , 85 , 209 , 323 , 809 , 605 , 2087 , 1917 , 8061 , 13659 ,0 }; - static ulong[] dim2549Kuo3Init = { 1 , 3 , 1 , 13 , 5 , 63 , 69 , 197 , 241 , 349 , 813 , 3943 , 6267 , 16197 , 1417 ,0 }; - static ulong[] dim2550Kuo3Init = { 1 , 1 , 1 , 5 , 13 , 21 , 85 , 55 , 21 , 791 , 795 , 4087 , 2697 , 6545 , 30253 ,0 }; - static ulong[] dim2551Kuo3Init = { 1 , 3 , 5 , 15 , 31 , 13 , 117 , 237 , 99 , 803 , 1367 , 251 , 5143 , 12153 , 27565 ,0 }; - static ulong[] dim2552Kuo3Init = { 1 , 1 , 7 , 7 , 11 , 7 , 17 , 47 , 305 , 9 , 941 , 3529 , 6131 , 11027 , 20319 ,0 }; - static ulong[] dim2553Kuo3Init = { 1 , 3 , 1 , 5 , 19 , 51 , 1 , 113 , 277 , 573 , 1717 , 1757 , 4541 , 943 , 349 ,0 }; - static ulong[] dim2554Kuo3Init = { 1 , 3 , 1 , 1 , 21 , 23 , 11 , 143 , 413 , 171 , 355 , 2801 , 2431 , 11597 , 16833 ,0 }; - static ulong[] dim2555Kuo3Init = { 1 , 3 , 1 , 1 , 13 , 31 , 111 , 109 , 73 , 125 , 1011 , 2249 , 4039 , 8757 , 2765 ,0 }; - static ulong[] dim2556Kuo3Init = { 1 , 1 , 1 , 7 , 15 , 53 , 33 , 133 , 511 , 595 , 139 , 815 , 6093 , 10215 , 9507 ,0 }; - static ulong[] dim2557Kuo3Init = { 1 , 3 , 7 , 7 , 29 , 1 , 93 , 13 , 169 , 435 , 527 , 3861 , 3867 , 9337 , 26855 ,0 }; - static ulong[] dim2558Kuo3Init = { 1 , 1 , 5 , 3 , 13 , 29 , 91 , 73 , 257 , 645 , 679 , 3245 , 6467 , 5917 , 17891 ,0 }; - static ulong[] dim2559Kuo3Init = { 1 , 1 , 7 , 15 , 27 , 1 , 45 , 17 , 429 , 571 , 1127 , 3843 , 3801 , 4773 , 16577 ,0 }; - static ulong[] dim2560Kuo3Init = { 1 , 1 , 7 , 11 , 29 , 29 , 65 , 111 , 415 , 941 , 1411 , 3003 , 3945 , 15281 , 16851 ,0 }; - static ulong[] dim2561Kuo3Init = { 1 , 3 , 1 , 3 , 3 , 29 , 39 , 121 , 165 , 285 , 1895 , 283 , 4393 , 13281 , 3349 ,0 }; - static ulong[] dim2562Kuo3Init = { 1 , 3 , 1 , 9 , 27 , 1 , 35 , 119 , 91 , 445 , 1045 , 1427 , 6271 , 955 , 509 ,0 }; - static ulong[] dim2563Kuo3Init = { 1 , 1 , 7 , 1 , 11 , 15 , 3 , 181 , 17 , 3 , 1865 , 2465 , 357 , 12149 , 7359 ,0 }; - static ulong[] dim2564Kuo3Init = { 1 , 3 , 5 , 5 , 11 , 47 , 5 , 65 , 105 , 53 , 1341 , 3729 , 4883 , 5179 , 29353 ,0 }; - static ulong[] dim2565Kuo3Init = { 1 , 1 , 7 , 5 , 15 , 53 , 23 , 181 , 125 , 441 , 511 , 3933 , 2327 , 1305 , 14629 ,0 }; - static ulong[] dim2566Kuo3Init = { 1 , 1 , 3 , 5 , 3 , 11 , 91 , 187 , 177 , 649 , 1849 , 2545 , 3349 , 6563 , 8139 ,0 }; - static ulong[] dim2567Kuo3Init = { 1 , 3 , 1 , 11 , 31 , 35 , 71 , 51 , 235 , 295 , 521 , 3869 , 3083 , 1327 , 3277 ,0 }; - static ulong[] dim2568Kuo3Init = { 1 , 1 , 3 , 15 , 11 , 11 , 125 , 163 , 71 , 721 , 449 , 3443 , 1347 , 6221 , 19489 ,0 }; - static ulong[] dim2569Kuo3Init = { 1 , 1 , 7 , 3 , 25 , 13 , 13 , 149 , 115 , 563 , 311 , 1823 , 2687 , 5997 , 23063 ,0 }; - static ulong[] dim2570Kuo3Init = { 1 , 1 , 1 , 13 , 7 , 47 , 115 , 19 , 419 , 395 , 591 , 2413 , 7143 , 11235 , 25795 ,0 }; - static ulong[] dim2571Kuo3Init = { 1 , 1 , 1 , 7 , 17 , 37 , 63 , 57 , 175 , 301 , 493 , 1849 , 1903 , 13149 , 21429 ,0 }; - static ulong[] dim2572Kuo3Init = { 1 , 1 , 3 , 3 , 1 , 53 , 15 , 91 , 315 , 687 , 473 , 1639 , 7769 , 11621 , 24245 ,0 }; - static ulong[] dim2573Kuo3Init = { 1 , 1 , 5 , 11 , 13 , 35 , 13 , 235 , 365 , 677 , 611 , 3175 , 6349 , 445 , 13739 ,0 }; - static ulong[] dim2574Kuo3Init = { 1 , 1 , 1 , 15 , 17 , 49 , 49 , 15 , 205 , 755 , 665 , 3865 , 6499 , 6521 , 31925 ,0 }; - static ulong[] dim2575Kuo3Init = { 1 , 1 , 3 , 5 , 9 , 49 , 57 , 119 , 489 , 633 , 1407 , 957 , 4005 , 14503 , 2783 ,0 }; - static ulong[] dim2576Kuo3Init = { 1 , 1 , 3 , 13 , 17 , 41 , 73 , 137 , 195 , 457 , 1361 , 3209 , 3701 , 9675 , 26499 ,0 }; - static ulong[] dim2577Kuo3Init = { 1 , 3 , 7 , 3 , 31 , 49 , 71 , 83 , 141 , 1009 , 1503 , 3393 , 4653 , 8051 , 25861 ,0 }; - static ulong[] dim2578Kuo3Init = { 1 , 3 , 7 , 9 , 31 , 17 , 83 , 211 , 3 , 81 , 1579 , 387 , 4471 , 5407 , 28849 ,0 }; - static ulong[] dim2579Kuo3Init = { 1 , 1 , 5 , 9 , 3 , 51 , 45 , 157 , 197 , 195 , 1121 , 2451 , 3885 , 9317 , 29157 ,0 }; - static ulong[] dim2580Kuo3Init = { 1 , 3 , 7 , 5 , 23 , 19 , 49 , 89 , 107 , 369 , 129 , 2381 , 383 , 8279 , 29277 ,0 }; - static ulong[] dim2581Kuo3Init = { 1 , 3 , 3 , 13 , 21 , 7 , 123 , 221 , 85 , 819 , 1857 , 1211 , 7495 , 2921 , 9529 ,0 }; - static ulong[] dim2582Kuo3Init = { 1 , 3 , 3 , 13 , 19 , 13 , 63 , 47 , 465 , 739 , 1961 , 2779 , 7989 , 8419 , 19249 ,0 }; - static ulong[] dim2583Kuo3Init = { 1 , 3 , 5 , 15 , 25 , 49 , 65 , 39 , 333 , 193 , 443 , 1221 , 245 , 523 , 31885 ,0 }; - static ulong[] dim2584Kuo3Init = { 1 , 3 , 5 , 7 , 31 , 3 , 69 , 173 , 19 , 593 , 61 , 1545 , 415 , 14489 , 9723 ,0 }; - static ulong[] dim2585Kuo3Init = { 1 , 3 , 3 , 1 , 5 , 9 , 121 , 87 , 431 , 893 , 1031 , 3589 , 4263 , 11355 , 22725 ,0 }; - static ulong[] dim2586Kuo3Init = { 1 , 1 , 5 , 3 , 21 , 9 , 47 , 151 , 165 , 941 , 1369 , 3991 , 989 , 1515 , 12725 ,0 }; - static ulong[] dim2587Kuo3Init = { 1 , 3 , 7 , 1 , 7 , 47 , 57 , 153 , 239 , 397 , 1723 , 1681 , 521 , 8173 , 14567 ,0 }; - static ulong[] dim2588Kuo3Init = { 1 , 3 , 3 , 5 , 23 , 9 , 77 , 201 , 61 , 969 , 345 , 2817 , 4391 , 2193 , 18739 ,0 }; - static ulong[] dim2589Kuo3Init = { 1 , 1 , 5 , 13 , 15 , 45 , 83 , 165 , 421 , 967 , 449 , 3419 , 2475 , 7283 , 18199 ,0 }; - static ulong[] dim2590Kuo3Init = { 1 , 3 , 7 , 11 , 25 , 37 , 3 , 175 , 327 , 35 , 1179 , 927 , 5263 , 1723 , 32015 ,0 }; - static ulong[] dim2591Kuo3Init = { 1 , 1 , 5 , 15 , 29 , 17 , 63 , 45 , 495 , 107 , 459 , 2223 , 989 , 11823 , 6547 ,0 }; - static ulong[] dim2592Kuo3Init = { 1 , 3 , 1 , 13 , 17 , 15 , 127 , 223 , 369 , 409 , 303 , 2229 , 7349 , 10165 , 28327 ,0 }; - static ulong[] dim2593Kuo3Init = { 1 , 3 , 5 , 15 , 15 , 17 , 119 , 185 , 55 , 299 , 113 , 3585 , 2289 , 7793 , 26217 ,0 }; - static ulong[] dim2594Kuo3Init = { 1 , 3 , 7 , 13 , 21 , 33 , 3 , 5 , 169 , 615 , 1607 , 1069 , 1827 , 6165 , 16245 ,0 }; - static ulong[] dim2595Kuo3Init = { 1 , 1 , 5 , 13 , 21 , 59 , 119 , 253 , 181 , 1001 , 2001 , 887 , 4129 , 3953 , 29979 ,0 }; - static ulong[] dim2596Kuo3Init = { 1 , 3 , 3 , 9 , 29 , 17 , 33 , 3 , 375 , 973 , 989 , 1725 , 731 , 12845 , 21133 ,0 }; - static ulong[] dim2597Kuo3Init = { 1 , 1 , 3 , 13 , 21 , 25 , 65 , 41 , 379 , 693 , 1507 , 1601 , 2087 , 8181 , 12723 ,0 }; - static ulong[] dim2598Kuo3Init = { 1 , 1 , 7 , 1 , 21 , 37 , 117 , 187 , 483 , 779 , 1279 , 685 , 5479 , 12039 , 12559 ,0 }; - static ulong[] dim2599Kuo3Init = { 1 , 1 , 3 , 5 , 7 , 39 , 49 , 79 , 361 , 191 , 1749 , 507 , 19 , 10671 , 4745 ,0 }; - static ulong[] dim2600Kuo3Init = { 1 , 1 , 1 , 15 , 15 , 45 , 37 , 49 , 85 , 311 , 577 , 2417 , 4061 , 1409 , 19187 ,0 }; - static ulong[] dim2601Kuo3Init = { 1 , 3 , 5 , 11 , 5 , 1 , 41 , 73 , 313 , 741 , 1081 , 3325 , 977 , 1693 , 15249 ,0 }; - static ulong[] dim2602Kuo3Init = { 1 , 1 , 1 , 9 , 19 , 49 , 29 , 169 , 153 , 665 , 413 , 907 , 6129 , 4961 , 21295 ,0 }; - static ulong[] dim2603Kuo3Init = { 1 , 3 , 3 , 3 , 23 , 17 , 91 , 27 , 375 , 231 , 513 , 1459 , 7245 , 8117 , 19583 ,0 }; - static ulong[] dim2604Kuo3Init = { 1 , 1 , 7 , 13 , 19 , 57 , 111 , 195 , 491 , 771 , 1841 , 1339 , 5045 , 12901 , 17307 ,0 }; - static ulong[] dim2605Kuo3Init = { 1 , 1 , 1 , 7 , 1 , 61 , 61 , 11 , 151 , 403 , 173 , 3629 , 2157 , 6125 , 29233 ,0 }; - static ulong[] dim2606Kuo3Init = { 1 , 3 , 1 , 13 , 29 , 63 , 55 , 9 , 465 , 439 , 9 , 1527 , 4635 , 4533 , 13633 ,0 }; - static ulong[] dim2607Kuo3Init = { 1 , 3 , 5 , 1 , 15 , 57 , 113 , 137 , 483 , 753 , 1971 , 1141 , 2765 , 7865 , 32733 ,0 }; - static ulong[] dim2608Kuo3Init = { 1 , 3 , 5 , 15 , 9 , 23 , 125 , 81 , 471 , 457 , 1475 , 3419 , 6089 , 4899 , 19805 ,0 }; - static ulong[] dim2609Kuo3Init = { 1 , 1 , 5 , 3 , 25 , 29 , 1 , 115 , 273 , 281 , 899 , 3129 , 4877 , 15459 , 24615 ,0 }; - static ulong[] dim2610Kuo3Init = { 1 , 1 , 7 , 11 , 19 , 41 , 59 , 165 , 115 , 369 , 1173 , 2545 , 4285 , 10899 , 3823 ,0 }; - static ulong[] dim2611Kuo3Init = { 1 , 3 , 5 , 13 , 17 , 47 , 107 , 191 , 53 , 1003 , 747 , 583 , 6457 , 12141 , 2541 ,0 }; - static ulong[] dim2612Kuo3Init = { 1 , 3 , 7 , 1 , 9 , 51 , 33 , 201 , 399 , 209 , 271 , 679 , 2401 , 10521 , 9949 ,0 }; - static ulong[] dim2613Kuo3Init = { 1 , 1 , 5 , 9 , 5 , 53 , 117 , 157 , 137 , 757 , 257 , 1407 , 4831 , 11205 , 25075 ,0 }; - static ulong[] dim2614Kuo3Init = { 1 , 1 , 7 , 13 , 29 , 63 , 25 , 11 , 255 , 251 , 1393 , 2089 , 1701 , 11773 , 24011 ,0 }; - static ulong[] dim2615Kuo3Init = { 1 , 3 , 3 , 11 , 17 , 5 , 69 , 119 , 287 , 607 , 779 , 2369 , 55 , 12381 , 26051 ,0 }; - static ulong[] dim2616Kuo3Init = { 1 , 3 , 3 , 13 , 25 , 1 , 97 , 109 , 79 , 453 , 795 , 2821 , 4113 , 3085 , 30667 ,0 }; - static ulong[] dim2617Kuo3Init = { 1 , 1 , 1 , 9 , 25 , 17 , 87 , 163 , 483 , 803 , 315 , 2755 , 7147 , 12537 , 7707 ,0 }; - static ulong[] dim2618Kuo3Init = { 1 , 3 , 1 , 5 , 23 , 29 , 93 , 129 , 47 , 181 , 1577 , 2645 , 4103 , 10753 , 27119 ,0 }; - static ulong[] dim2619Kuo3Init = { 1 , 1 , 1 , 1 , 17 , 61 , 37 , 175 , 451 , 5 , 879 , 1625 , 7981 , 11249 , 12573 ,0 }; - static ulong[] dim2620Kuo3Init = { 1 , 1 , 3 , 5 , 9 , 17 , 85 , 131 , 111 , 621 , 903 , 3143 , 5951 , 6567 , 32227 ,0 }; - static ulong[] dim2621Kuo3Init = { 1 , 3 , 5 , 3 , 1 , 49 , 53 , 255 , 435 , 845 , 225 , 2535 , 7925 , 8043 , 17519 ,0 }; - static ulong[] dim2622Kuo3Init = { 1 , 3 , 3 , 5 , 23 , 7 , 63 , 117 , 79 , 637 , 1265 , 2747 , 6531 , 7327 , 17329 ,0 }; - static ulong[] dim2623Kuo3Init = { 1 , 3 , 7 , 3 , 27 , 35 , 69 , 253 , 489 , 495 , 561 , 3615 , 917 , 6595 , 10673 ,0 }; - static ulong[] dim2624Kuo3Init = { 1 , 1 , 1 , 5 , 25 , 7 , 99 , 99 , 499 , 251 , 1651 , 3603 , 689 , 5837 , 347 ,0 }; - static ulong[] dim2625Kuo3Init = { 1 , 1 , 3 , 5 , 1 , 27 , 55 , 91 , 137 , 291 , 517 , 2149 , 1097 , 2187 , 16191 ,0 }; - static ulong[] dim2626Kuo3Init = { 1 , 1 , 1 , 11 , 29 , 3 , 103 , 81 , 335 , 85 , 549 , 1667 , 5319 , 5929 , 15885 ,0 }; - static ulong[] dim2627Kuo3Init = { 1 , 1 , 3 , 9 , 7 , 41 , 103 , 141 , 103 , 655 , 179 , 1513 , 7105 , 1919 , 2245 ,0 }; - static ulong[] dim2628Kuo3Init = { 1 , 3 , 5 , 11 , 11 , 13 , 127 , 65 , 493 , 233 , 859 , 3179 , 5449 , 13255 , 14495 ,0 }; - static ulong[] dim2629Kuo3Init = { 1 , 3 , 1 , 5 , 27 , 49 , 119 , 29 , 55 , 717 , 1293 , 1193 , 7883 , 4475 , 13745 ,0 }; - static ulong[] dim2630Kuo3Init = { 1 , 3 , 7 , 3 , 21 , 9 , 1 , 43 , 425 , 385 , 447 , 3135 , 7671 , 12317 , 5649 ,0 }; - static ulong[] dim2631Kuo3Init = { 1 , 1 , 7 , 5 , 21 , 51 , 103 , 199 , 119 , 875 , 1457 , 461 , 6521 , 7849 , 7725 ,0 }; - static ulong[] dim2632Kuo3Init = { 1 , 1 , 1 , 15 , 9 , 25 , 89 , 125 , 395 , 269 , 1533 , 1545 , 2613 , 11175 , 17167 ,0 }; - static ulong[] dim2633Kuo3Init = { 1 , 3 , 5 , 9 , 17 , 41 , 113 , 37 , 253 , 407 , 795 , 2117 , 3041 , 9269 , 30097 ,0 }; - static ulong[] dim2634Kuo3Init = { 1 , 1 , 3 , 11 , 31 , 13 , 23 , 29 , 385 , 603 , 1721 , 3817 , 3453 , 2021 , 8829 ,0 }; - static ulong[] dim2635Kuo3Init = { 1 , 1 , 7 , 9 , 21 , 3 , 107 , 121 , 267 , 385 , 261 , 3967 , 5607 , 13991 , 8639 ,0 }; - static ulong[] dim2636Kuo3Init = { 1 , 3 , 5 , 15 , 17 , 19 , 99 , 195 , 415 , 19 , 865 , 4049 , 3819 , 7581 , 10779 ,0 }; - static ulong[] dim2637Kuo3Init = { 1 , 1 , 5 , 15 , 25 , 29 , 125 , 105 , 337 , 153 , 2023 , 1475 , 2741 , 7779 , 16929 ,0 }; - static ulong[] dim2638Kuo3Init = { 1 , 3 , 3 , 5 , 11 , 1 , 111 , 157 , 441 , 751 , 865 , 3499 , 6425 , 9567 , 6659 ,0 }; - static ulong[] dim2639Kuo3Init = { 1 , 1 , 5 , 3 , 23 , 41 , 57 , 91 , 413 , 81 , 1977 , 2227 , 2289 , 1291 , 19339 ,0 }; - static ulong[] dim2640Kuo3Init = { 1 , 1 , 3 , 15 , 15 , 49 , 47 , 115 , 153 , 593 , 1243 , 2029 , 1177 , 8121 , 14893 ,0 }; - static ulong[] dim2641Kuo3Init = { 1 , 1 , 5 , 15 , 29 , 11 , 55 , 23 , 173 , 145 , 143 , 2275 , 4537 , 13221 , 32575 ,0 }; - static ulong[] dim2642Kuo3Init = { 1 , 1 , 1 , 9 , 29 , 53 , 103 , 37 , 327 , 543 , 1327 , 899 , 6343 , 6707 , 1247 ,0 }; - static ulong[] dim2643Kuo3Init = { 1 , 3 , 1 , 13 , 21 , 49 , 113 , 205 , 349 , 451 , 1277 , 989 , 3387 , 9275 , 6629 ,0 }; - static ulong[] dim2644Kuo3Init = { 1 , 3 , 5 , 5 , 31 , 59 , 79 , 65 , 285 , 841 , 287 , 1453 , 1507 , 14813 , 14705 ,0 }; - static ulong[] dim2645Kuo3Init = { 1 , 1 , 3 , 5 , 9 , 11 , 79 , 109 , 313 , 339 , 1939 , 2399 , 5127 , 8747 , 11989 ,0 }; - static ulong[] dim2646Kuo3Init = { 1 , 3 , 3 , 9 , 9 , 27 , 83 , 135 , 249 , 101 , 1181 , 451 , 6063 , 609 , 15371 ,0 }; - static ulong[] dim2647Kuo3Init = { 1 , 1 , 5 , 5 , 15 , 61 , 77 , 221 , 19 , 643 , 1535 , 1223 , 7165 , 10969 , 10367 ,0 }; - static ulong[] dim2648Kuo3Init = { 1 , 1 , 7 , 13 , 5 , 9 , 61 , 95 , 493 , 709 , 71 , 1571 , 6805 , 9687 , 12217 ,0 }; - static ulong[] dim2649Kuo3Init = { 1 , 3 , 5 , 7 , 17 , 55 , 57 , 179 , 217 , 699 , 943 , 127 , 1603 , 6851 , 8579 ,0 }; - static ulong[] dim2650Kuo3Init = { 1 , 3 , 1 , 11 , 25 , 51 , 127 , 13 , 429 , 15 , 949 , 2337 , 5743 , 14255 , 15137 ,0 }; - static ulong[] dim2651Kuo3Init = { 1 , 3 , 7 , 15 , 5 , 39 , 39 , 105 , 119 , 355 , 1655 , 3819 , 1313 , 5173 , 7791 ,0 }; - static ulong[] dim2652Kuo3Init = { 1 , 3 , 7 , 5 , 3 , 47 , 93 , 85 , 19 , 399 , 303 , 1333 , 5435 , 9425 , 6503 ,0 }; - static ulong[] dim2653Kuo3Init = { 1 , 3 , 1 , 7 , 21 , 33 , 71 , 253 , 489 , 149 , 227 , 797 , 955 , 6839 , 23037 ,0 }; - static ulong[] dim2654Kuo3Init = { 1 , 1 , 7 , 1 , 27 , 59 , 15 , 47 , 249 , 557 , 1477 , 1837 , 4409 , 14723 , 14933 ,0 }; - static ulong[] dim2655Kuo3Init = { 1 , 3 , 5 , 13 , 1 , 47 , 11 , 205 , 131 , 17 , 373 , 2039 , 1873 , 3041 , 22869 ,0 }; - static ulong[] dim2656Kuo3Init = { 1 , 1 , 3 , 1 , 11 , 27 , 99 , 135 , 195 , 419 , 561 , 1027 , 1849 , 13533 , 7701 ,0 }; - static ulong[] dim2657Kuo3Init = { 1 , 1 , 7 , 15 , 27 , 23 , 77 , 111 , 157 , 417 , 591 , 3435 , 5999 , 9481 , 17073 ,0 }; - static ulong[] dim2658Kuo3Init = { 1 , 3 , 5 , 3 , 9 , 61 , 57 , 43 , 85 , 585 , 1861 , 703 , 2337 , 8565 , 16233 ,0 }; - static ulong[] dim2659Kuo3Init = { 1 , 1 , 3 , 11 , 7 , 17 , 41 , 213 , 145 , 325 , 1847 , 3205 , 3515 , 1117 , 285 ,0 }; - static ulong[] dim2660Kuo3Init = { 1 , 3 , 5 , 11 , 7 , 35 , 95 , 127 , 57 , 123 , 759 , 129 , 4335 , 15183 , 2107 ,0 }; - static ulong[] dim2661Kuo3Init = { 1 , 3 , 7 , 7 , 13 , 1 , 87 , 193 , 63 , 201 , 741 , 2087 , 1625 , 1677 , 31603 ,0 }; - static ulong[] dim2662Kuo3Init = { 1 , 1 , 7 , 11 , 13 , 53 , 127 , 235 , 489 , 173 , 1551 , 1897 , 5877 , 15559 , 24445 ,0 }; - static ulong[] dim2663Kuo3Init = { 1 , 1 , 7 , 7 , 9 , 53 , 59 , 247 , 83 , 521 , 2029 , 3677 , 2083 , 11635 , 30517 ,0 }; - static ulong[] dim2664Kuo3Init = { 1 , 1 , 1 , 5 , 9 , 19 , 71 , 99 , 213 , 663 , 947 , 1929 , 5275 , 9715 , 10033 ,0 }; - static ulong[] dim2665Kuo3Init = { 1 , 1 , 5 , 11 , 25 , 31 , 33 , 239 , 137 , 445 , 1227 , 1051 , 7405 , 7983 , 10079 ,0 }; - static ulong[] dim2666Kuo3Init = { 1 , 3 , 3 , 15 , 27 , 35 , 51 , 207 , 167 , 519 , 303 , 3399 , 4393 , 1623 , 21225 ,0 }; - static ulong[] dim2667Kuo3Init = { 1 , 3 , 1 , 11 , 17 , 13 , 41 , 229 , 441 , 879 , 1695 , 1351 , 5745 , 1907 , 15517 ,0 }; - static ulong[] dim2668Kuo3Init = { 1 , 3 , 7 , 1 , 3 , 1 , 95 , 105 , 333 , 11 , 1709 , 2783 , 3011 , 5579 , 14939 ,0 }; - static ulong[] dim2669Kuo3Init = { 1 , 3 , 1 , 1 , 5 , 33 , 67 , 103 , 71 , 707 , 325 , 315 , 567 , 11969 , 23071 ,0 }; - static ulong[] dim2670Kuo3Init = { 1 , 1 , 7 , 11 , 5 , 61 , 47 , 131 , 413 , 507 , 991 , 27 , 3873 , 13151 , 4115 ,0 }; - static ulong[] dim2671Kuo3Init = { 1 , 1 , 5 , 11 , 9 , 31 , 103 , 91 , 297 , 419 , 1251 , 1155 , 5539 , 10347 , 26811 ,0 }; - static ulong[] dim2672Kuo3Init = { 1 , 3 , 3 , 3 , 15 , 37 , 37 , 167 , 307 , 397 , 561 , 2431 , 6219 , 3401 , 23551 ,0 }; - static ulong[] dim2673Kuo3Init = { 1 , 3 , 7 , 7 , 29 , 11 , 33 , 7 , 177 , 625 , 853 , 2317 , 7371 , 7435 , 18135 ,0 }; - static ulong[] dim2674Kuo3Init = { 1 , 1 , 5 , 1 , 29 , 7 , 107 , 97 , 3 , 97 , 901 , 717 , 1911 , 3877 , 29583 ,0 }; - static ulong[] dim2675Kuo3Init = { 1 , 1 , 7 , 3 , 27 , 33 , 33 , 105 , 285 , 3 , 1427 , 13 , 3941 , 299 , 12025 ,0 }; - static ulong[] dim2676Kuo3Init = { 1 , 1 , 3 , 7 , 13 , 57 , 81 , 131 , 327 , 587 , 445 , 1313 , 4797 , 8587 , 5915 ,0 }; - static ulong[] dim2677Kuo3Init = { 1 , 1 , 3 , 13 , 21 , 29 , 43 , 89 , 499 , 893 , 501 , 2409 , 3145 , 9435 , 10831 ,0 }; - static ulong[] dim2678Kuo3Init = { 1 , 1 , 7 , 11 , 25 , 21 , 23 , 211 , 37 , 993 , 199 , 3791 , 291 , 465 , 32513 ,0 }; - static ulong[] dim2679Kuo3Init = { 1 , 1 , 5 , 11 , 15 , 53 , 123 , 91 , 407 , 925 , 1125 , 927 , 6793 , 1905 , 27477 ,0 }; - static ulong[] dim2680Kuo3Init = { 1 , 1 , 1 , 11 , 27 , 51 , 1 , 77 , 5 , 273 , 1363 , 3835 , 1627 , 14925 , 9431 ,0 }; - static ulong[] dim2681Kuo3Init = { 1 , 1 , 7 , 3 , 29 , 47 , 47 , 79 , 305 , 655 , 1171 , 899 , 95 , 9413 , 14371 ,0 }; - static ulong[] dim2682Kuo3Init = { 1 , 1 , 7 , 13 , 31 , 45 , 5 , 211 , 331 , 677 , 1045 , 929 , 975 , 2377 , 15407 ,0 }; - static ulong[] dim2683Kuo3Init = { 1 , 3 , 5 , 13 , 21 , 59 , 61 , 111 , 449 , 641 , 597 , 4023 , 6333 , 4439 , 605 ,0 }; - static ulong[] dim2684Kuo3Init = { 1 , 1 , 3 , 5 , 29 , 7 , 89 , 21 , 373 , 311 , 433 , 1091 , 4871 , 8951 , 22591 ,0 }; - static ulong[] dim2685Kuo3Init = { 1 , 1 , 1 , 7 , 27 , 17 , 81 , 77 , 119 , 1005 , 873 , 2299 , 6919 , 657 , 12479 ,0 }; - static ulong[] dim2686Kuo3Init = { 1 , 3 , 3 , 5 , 29 , 41 , 31 , 133 , 411 , 655 , 1753 , 1365 , 1807 , 15975 , 23783 ,0 }; - static ulong[] dim2687Kuo3Init = { 1 , 1 , 3 , 9 , 21 , 11 , 79 , 65 , 149 , 121 , 1393 , 983 , 885 , 6991 , 14943 ,0 }; - static ulong[] dim2688Kuo3Init = { 1 , 1 , 1 , 3 , 17 , 39 , 123 , 35 , 101 , 363 , 1991 , 3309 , 2117 , 16229 , 3017 ,0 }; - static ulong[] dim2689Kuo3Init = { 1 , 3 , 3 , 15 , 19 , 61 , 41 , 201 , 267 , 985 , 1635 , 2681 , 883 , 13343 , 22061 ,0 }; - static ulong[] dim2690Kuo3Init = { 1 , 1 , 7 , 7 , 9 , 13 , 15 , 139 , 25 , 989 , 1817 , 867 , 5913 , 16197 , 7521 ,0 }; - static ulong[] dim2691Kuo3Init = { 1 , 1 , 5 , 5 , 11 , 29 , 49 , 75 , 135 , 705 , 315 , 2769 , 3539 , 13655 , 11443 ,0 }; - static ulong[] dim2692Kuo3Init = { 1 , 1 , 7 , 1 , 25 , 9 , 53 , 81 , 217 , 391 , 1789 , 3837 , 1191 , 12359 , 21831 ,0 }; - static ulong[] dim2693Kuo3Init = { 1 , 1 , 5 , 9 , 3 , 39 , 1 , 81 , 367 , 893 , 1661 , 3693 , 9 , 4061 , 15321 ,0 }; - static ulong[] dim2694Kuo3Init = { 1 , 1 , 5 , 5 , 27 , 21 , 11 , 23 , 287 , 901 , 1695 , 469 , 1993 , 11435 , 12637 ,0 }; - static ulong[] dim2695Kuo3Init = { 1 , 1 , 3 , 7 , 21 , 25 , 113 , 161 , 361 , 583 , 2023 , 831 , 7161 , 5125 , 21097 ,0 }; - static ulong[] dim2696Kuo3Init = { 1 , 1 , 1 , 13 , 11 , 29 , 21 , 221 , 255 , 255 , 693 , 701 , 989 , 10323 , 3165 ,0 }; - static ulong[] dim2697Kuo3Init = { 1 , 1 , 5 , 15 , 5 , 27 , 107 , 213 , 85 , 325 , 1359 , 735 , 161 , 11505 , 24007 ,0 }; - static ulong[] dim2698Kuo3Init = { 1 , 3 , 1 , 9 , 1 , 47 , 17 , 241 , 53 , 563 , 635 , 3159 , 3231 , 12167 , 221 ,0 }; - static ulong[] dim2699Kuo3Init = { 1 , 1 , 1 , 9 , 21 , 51 , 15 , 1 , 491 , 283 , 1933 , 1455 , 6921 , 10547 , 29725 ,0 }; - static ulong[] dim2700Kuo3Init = { 1 , 3 , 3 , 3 , 31 , 43 , 123 , 103 , 291 , 479 , 1207 , 1703 , 5591 , 6555 , 37 ,0 }; - static ulong[] dim2701Kuo3Init = { 1 , 3 , 7 , 7 , 13 , 53 , 29 , 155 , 101 , 651 , 423 , 2705 , 6469 , 13795 , 9903 ,0 }; - static ulong[] dim2702Kuo3Init = { 1 , 1 , 7 , 3 , 23 , 27 , 39 , 181 , 47 , 297 , 353 , 327 , 6723 , 5981 , 8333 ,0 }; - static ulong[] dim2703Kuo3Init = { 1 , 1 , 1 , 1 , 29 , 41 , 55 , 177 , 459 , 933 , 675 , 177 , 1459 , 6371 , 8301 ,0 }; - static ulong[] dim2704Kuo3Init = { 1 , 3 , 5 , 1 , 11 , 29 , 45 , 119 , 145 , 793 , 1771 , 2295 , 2349 , 13825 , 10389 ,0 }; - static ulong[] dim2705Kuo3Init = { 1 , 3 , 7 , 7 , 13 , 9 , 85 , 201 , 509 , 285 , 1613 , 2571 , 3925 , 4303 , 14625 ,0 }; - static ulong[] dim2706Kuo3Init = { 1 , 3 , 5 , 1 , 17 , 53 , 89 , 93 , 401 , 429 , 865 , 679 , 1995 , 13567 , 32275 ,0 }; - static ulong[] dim2707Kuo3Init = { 1 , 1 , 1 , 3 , 17 , 23 , 97 , 39 , 309 , 67 , 1445 , 101 , 4305 , 12195 , 18559 ,0 }; - static ulong[] dim2708Kuo3Init = { 1 , 1 , 5 , 11 , 27 , 35 , 119 , 67 , 411 , 461 , 1149 , 1651 , 6149 , 1543 , 19747 ,0 }; - static ulong[] dim2709Kuo3Init = { 1 , 1 , 5 , 9 , 23 , 51 , 25 , 109 , 283 , 331 , 1651 , 691 , 7953 , 1979 , 7425 ,0 }; - static ulong[] dim2710Kuo3Init = { 1 , 3 , 3 , 1 , 31 , 63 , 113 , 191 , 481 , 467 , 589 , 2375 , 4619 , 3745 , 4343 ,0 }; - static ulong[] dim2711Kuo3Init = { 1 , 1 , 3 , 1 , 27 , 35 , 61 , 29 , 115 , 909 , 107 , 815 , 1579 , 8373 , 32657 ,0 }; - static ulong[] dim2712Kuo3Init = { 1 , 3 , 3 , 11 , 21 , 45 , 101 , 27 , 229 , 1011 , 497 , 841 , 7653 , 5429 , 17329 ,0 }; - static ulong[] dim2713Kuo3Init = { 1 , 3 , 7 , 9 , 27 , 5 , 105 , 171 , 75 , 45 , 865 , 4061 , 7947 , 4979 , 20577 ,0 }; - static ulong[] dim2714Kuo3Init = { 1 , 3 , 7 , 15 , 9 , 45 , 67 , 221 , 27 , 31 , 187 , 2063 , 4733 , 10087 , 23091 ,0 }; - static ulong[] dim2715Kuo3Init = { 1 , 3 , 5 , 15 , 3 , 51 , 79 , 117 , 379 , 687 , 721 , 3645 , 6639 , 14161 , 16187 ,0 }; - static ulong[] dim2716Kuo3Init = { 1 , 3 , 1 , 1 , 5 , 15 , 117 , 177 , 163 , 577 , 279 , 1549 , 2397 , 8099 , 2125 ,0 }; - static ulong[] dim2717Kuo3Init = { 1 , 3 , 3 , 5 , 17 , 11 , 121 , 89 , 313 , 541 , 47 , 1993 , 3313 , 159 , 3761 ,0 }; - static ulong[] dim2718Kuo3Init = { 1 , 3 , 5 , 7 , 11 , 43 , 7 , 165 , 283 , 7 , 1275 , 3391 , 417 , 11697 , 22357 ,0 }; - static ulong[] dim2719Kuo3Init = { 1 , 1 , 3 , 13 , 27 , 47 , 65 , 51 , 83 , 223 , 2015 , 2939 , 6121 , 3873 , 27573 ,0 }; - static ulong[] dim2720Kuo3Init = { 1 , 3 , 1 , 3 , 19 , 55 , 115 , 105 , 345 , 393 , 1609 , 3131 , 109 , 11443 , 23475 ,0 }; - static ulong[] dim2721Kuo3Init = { 1 , 3 , 3 , 15 , 21 , 61 , 39 , 69 , 381 , 279 , 1473 , 1239 , 661 , 781 , 21603 ,0 }; - static ulong[] dim2722Kuo3Init = { 1 , 1 , 7 , 1 , 3 , 7 , 7 , 129 , 229 , 233 , 77 , 845 , 7871 , 3013 , 14469 ,0 }; - static ulong[] dim2723Kuo3Init = { 1 , 1 , 7 , 1 , 17 , 9 , 3 , 17 , 375 , 27 , 473 , 945 , 4111 , 7645 , 7899 ,0 }; - static ulong[] dim2724Kuo3Init = { 1 , 1 , 7 , 3 , 25 , 31 , 71 , 157 , 269 , 1003 , 1875 , 3573 , 8121 , 14073 , 26019 ,0 }; - static ulong[] dim2725Kuo3Init = { 1 , 3 , 3 , 13 , 17 , 25 , 57 , 1 , 63 , 425 , 507 , 2341 , 4891 , 12643 , 32083 ,0 }; - static ulong[] dim2726Kuo3Init = { 1 , 1 , 3 , 13 , 23 , 47 , 55 , 145 , 269 , 417 , 559 , 2065 , 5801 , 13751 , 15617 ,0 }; - static ulong[] dim2727Kuo3Init = { 1 , 3 , 7 , 9 , 3 , 39 , 45 , 143 , 131 , 713 , 1549 , 779 , 1427 , 10819 , 10629 ,0 }; - static ulong[] dim2728Kuo3Init = { 1 , 1 , 5 , 3 , 13 , 61 , 99 , 145 , 293 , 393 , 1181 , 4011 , 6843 , 12667 , 21301 ,0 }; - static ulong[] dim2729Kuo3Init = { 1 , 3 , 7 , 1 , 19 , 29 , 105 , 109 , 391 , 569 , 1933 , 1799 , 8045 , 509 , 13251 ,0 }; - static ulong[] dim2730Kuo3Init = { 1 , 1 , 3 , 3 , 21 , 55 , 123 , 239 , 65 , 891 , 635 , 3107 , 2701 , 9041 , 28249 ,0 }; - static ulong[] dim2731Kuo3Init = { 1 , 1 , 3 , 7 , 1 , 11 , 9 , 49 , 51 , 243 , 51 , 3 , 6813 , 14995 , 27065 ,0 }; - static ulong[] dim2732Kuo3Init = { 1 , 1 , 3 , 11 , 29 , 35 , 107 , 19 , 415 , 273 , 881 , 49 , 3267 , 4791 , 9609 ,0 }; - static ulong[] dim2733Kuo3Init = { 1 , 1 , 5 , 3 , 5 , 39 , 59 , 127 , 267 , 215 , 375 , 133 , 8057 , 8497 , 23595 ,0 }; - static ulong[] dim2734Kuo3Init = { 1 , 3 , 7 , 9 , 1 , 41 , 81 , 199 , 287 , 907 , 743 , 2875 , 3873 , 2851 , 7385 ,0 }; - static ulong[] dim2735Kuo3Init = { 1 , 3 , 1 , 13 , 13 , 49 , 25 , 43 , 105 , 511 , 1483 , 3277 , 7561 , 7211 , 20671 ,0 }; - static ulong[] dim2736Kuo3Init = { 1 , 3 , 5 , 13 , 19 , 21 , 37 , 87 , 439 , 69 , 1145 , 141 , 6187 , 6329 , 26923 ,0 }; - static ulong[] dim2737Kuo3Init = { 1 , 3 , 1 , 13 , 13 , 59 , 123 , 155 , 189 , 803 , 1807 , 363 , 2239 , 547 , 30801 ,0 }; - static ulong[] dim2738Kuo3Init = { 1 , 3 , 7 , 7 , 1 , 61 , 93 , 25 , 205 , 275 , 1591 , 1575 , 3951 , 12313 , 9399 ,0 }; - static ulong[] dim2739Kuo3Init = { 1 , 1 , 1 , 9 , 11 , 49 , 43 , 241 , 435 , 515 , 283 , 3667 , 2089 , 4755 , 19427 ,0 }; - static ulong[] dim2740Kuo3Init = { 1 , 1 , 1 , 5 , 19 , 57 , 5 , 23 , 271 , 113 , 481 , 2619 , 4507 , 15191 , 2227 ,0 }; - static ulong[] dim2741Kuo3Init = { 1 , 1 , 1 , 11 , 11 , 15 , 49 , 51 , 121 , 463 , 1015 , 791 , 3993 , 14311 , 8723 ,0 }; - static ulong[] dim2742Kuo3Init = { 1 , 1 , 1 , 7 , 17 , 19 , 55 , 137 , 211 , 307 , 1647 , 2719 , 5231 , 13005 , 17527 ,0 }; - static ulong[] dim2743Kuo3Init = { 1 , 1 , 3 , 3 , 1 , 25 , 5 , 119 , 271 , 611 , 1799 , 3149 , 2159 , 9147 , 30765 ,0 }; - static ulong[] dim2744Kuo3Init = { 1 , 1 , 1 , 15 , 5 , 19 , 75 , 137 , 483 , 457 , 1913 , 31 , 9 , 8333 , 3315 ,0 }; - static ulong[] dim2745Kuo3Init = { 1 , 3 , 7 , 7 , 5 , 11 , 95 , 83 , 269 , 105 , 67 , 2021 , 6423 , 10315 , 28017 ,0 }; - static ulong[] dim2746Kuo3Init = { 1 , 3 , 1 , 7 , 27 , 49 , 7 , 45 , 297 , 899 , 665 , 2473 , 2863 , 2171 , 10693 ,0 }; - static ulong[] dim2747Kuo3Init = { 1 , 1 , 5 , 5 , 25 , 17 , 41 , 155 , 101 , 355 , 197 , 3853 , 2381 , 9663 , 25187 ,0 }; - static ulong[] dim2748Kuo3Init = { 1 , 3 , 7 , 15 , 15 , 53 , 119 , 233 , 79 , 545 , 1203 , 1535 , 3563 , 2469 , 29449 ,0 }; - static ulong[] dim2749Kuo3Init = { 1 , 1 , 5 , 5 , 27 , 57 , 113 , 189 , 3 , 253 , 1743 , 3735 , 5257 , 10521 , 18679 ,0 }; - static ulong[] dim2750Kuo3Init = { 1 , 3 , 7 , 1 , 5 , 29 , 117 , 207 , 101 , 293 , 615 , 401 , 7201 , 11451 , 13705 ,0 }; - static ulong[] dim2751Kuo3Init = { 1 , 1 , 5 , 11 , 13 , 59 , 55 , 101 , 253 , 801 , 1947 , 3509 , 655 , 5555 , 15517 ,0 }; - static ulong[] dim2752Kuo3Init = { 1 , 3 , 3 , 5 , 3 , 19 , 31 , 93 , 3 , 1009 , 1535 , 261 , 2259 , 9835 , 5797 ,0 }; - static ulong[] dim2753Kuo3Init = { 1 , 3 , 3 , 9 , 9 , 53 , 1 , 213 , 123 , 271 , 1137 , 11 , 6331 , 9907 , 13219 ,0 }; - static ulong[] dim2754Kuo3Init = { 1 , 1 , 7 , 5 , 17 , 9 , 83 , 153 , 231 , 3 , 1179 , 735 , 553 , 10627 , 4643 ,0 }; - static ulong[] dim2755Kuo3Init = { 1 , 1 , 1 , 11 , 25 , 21 , 127 , 85 , 17 , 541 , 535 , 1041 , 5071 , 15451 , 909 ,0 }; - static ulong[] dim2756Kuo3Init = { 1 , 3 , 1 , 7 , 29 , 31 , 75 , 91 , 67 , 253 , 971 , 327 , 7491 , 7627 , 31857 ,0 }; - static ulong[] dim2757Kuo3Init = { 1 , 3 , 1 , 5 , 23 , 19 , 79 , 197 , 25 , 83 , 1427 , 2023 , 1861 , 1617 , 10129 ,0 }; - static ulong[] dim2758Kuo3Init = { 1 , 1 , 5 , 13 , 27 , 55 , 113 , 191 , 119 , 301 , 1243 , 333 , 7609 , 4875 , 19035 ,0 }; - static ulong[] dim2759Kuo3Init = { 1 , 1 , 5 , 5 , 7 , 51 , 59 , 157 , 21 , 697 , 171 , 2857 , 3875 , 15413 , 28749 ,0 }; - static ulong[] dim2760Kuo3Init = { 1 , 1 , 1 , 11 , 13 , 45 , 49 , 161 , 389 , 715 , 991 , 839 , 2655 , 11399 , 5261 ,0 }; - static ulong[] dim2761Kuo3Init = { 1 , 1 , 7 , 5 , 17 , 51 , 87 , 75 , 65 , 67 , 1283 , 1991 , 7735 , 9063 , 313 ,0 }; - static ulong[] dim2762Kuo3Init = { 1 , 3 , 3 , 13 , 29 , 39 , 109 , 159 , 63 , 103 , 587 , 1941 , 3883 , 1119 , 4303 ,0 }; - static ulong[] dim2763Kuo3Init = { 1 , 3 , 3 , 1 , 15 , 27 , 69 , 49 , 417 , 281 , 1207 , 289 , 1873 , 12287 , 19321 ,0 }; - static ulong[] dim2764Kuo3Init = { 1 , 1 , 1 , 3 , 9 , 57 , 77 , 81 , 267 , 45 , 835 , 671 , 4569 , 12713 , 32657 ,0 }; - static ulong[] dim2765Kuo3Init = { 1 , 1 , 7 , 5 , 25 , 25 , 73 , 165 , 413 , 845 , 529 , 2987 , 2051 , 6155 , 29133 ,0 }; - static ulong[] dim2766Kuo3Init = { 1 , 3 , 1 , 13 , 3 , 41 , 107 , 85 , 429 , 323 , 1509 , 649 , 5897 , 10309 , 30927 ,0 }; - static ulong[] dim2767Kuo3Init = { 1 , 1 , 7 , 9 , 1 , 1 , 105 , 213 , 479 , 755 , 1863 , 1429 , 5927 , 9923 , 18531 ,0 }; - static ulong[] dim2768Kuo3Init = { 1 , 3 , 1 , 5 , 9 , 13 , 45 , 105 , 133 , 117 , 1837 , 3019 , 3809 , 8713 , 19865 ,0 }; - static ulong[] dim2769Kuo3Init = { 1 , 1 , 3 , 7 , 13 , 7 , 31 , 175 , 209 , 313 , 1095 , 1093 , 2707 , 11955 , 11137 ,0 }; - static ulong[] dim2770Kuo3Init = { 1 , 3 , 7 , 13 , 9 , 31 , 79 , 25 , 205 , 309 , 1977 , 1207 , 5629 , 6869 , 24269 ,0 }; - static ulong[] dim2771Kuo3Init = { 1 , 1 , 5 , 3 , 5 , 43 , 31 , 81 , 251 , 569 , 2033 , 299 , 345 , 7437 , 2183 ,0 }; - static ulong[] dim2772Kuo3Init = { 1 , 1 , 5 , 1 , 23 , 17 , 107 , 143 , 31 , 349 , 1501 , 2487 , 6911 , 12591 , 17599 ,0 }; - static ulong[] dim2773Kuo3Init = { 1 , 1 , 7 , 9 , 5 , 13 , 99 , 145 , 141 , 947 , 1587 , 3691 , 6029 , 13153 , 13971 ,0 }; - static ulong[] dim2774Kuo3Init = { 1 , 3 , 1 , 1 , 21 , 37 , 87 , 19 , 195 , 263 , 85 , 3285 , 1733 , 11057 , 6293 ,0 }; - static ulong[] dim2775Kuo3Init = { 1 , 1 , 3 , 3 , 31 , 29 , 97 , 81 , 479 , 879 , 2011 , 1041 , 8141 , 14891 , 175 ,0 }; - static ulong[] dim2776Kuo3Init = { 1 , 3 , 5 , 7 , 13 , 35 , 61 , 219 , 103 , 161 , 1187 , 3925 , 2041 , 2609 , 30195 ,0 }; - static ulong[] dim2777Kuo3Init = { 1 , 3 , 1 , 13 , 15 , 43 , 31 , 163 , 401 , 451 , 1881 , 1307 , 4201 , 6821 , 3717 ,0 }; - static ulong[] dim2778Kuo3Init = { 1 , 3 , 7 , 3 , 5 , 3 , 85 , 149 , 47 , 1003 , 405 , 1801 , 6695 , 897 , 28005 ,0 }; - static ulong[] dim2779Kuo3Init = { 1 , 1 , 3 , 11 , 19 , 37 , 81 , 41 , 315 , 729 , 303 , 501 , 7483 , 10841 , 12649 ,0 }; - static ulong[] dim2780Kuo3Init = { 1 , 1 , 1 , 1 , 1 , 51 , 121 , 129 , 49 , 511 , 719 , 2235 , 827 , 9331 , 22551 ,0 }; - static ulong[] dim2781Kuo3Init = { 1 , 3 , 3 , 9 , 21 , 41 , 47 , 17 , 157 , 771 , 867 , 3685 , 2387 , 7409 , 13889 ,0 }; - static ulong[] dim2782Kuo3Init = { 1 , 3 , 7 , 7 , 11 , 53 , 119 , 19 , 289 , 337 , 551 , 2529 , 321 , 2599 , 11153 ,0 }; - static ulong[] dim2783Kuo3Init = { 1 , 3 , 1 , 9 , 7 , 33 , 19 , 7 , 459 , 729 , 281 , 947 , 5469 , 7497 , 22893 ,0 }; - static ulong[] dim2784Kuo3Init = { 1 , 1 , 7 , 13 , 11 , 41 , 91 , 217 , 195 , 483 , 1659 , 1619 , 4201 , 15825 , 3357 ,0 }; - static ulong[] dim2785Kuo3Init = { 1 , 1 , 5 , 9 , 9 , 29 , 87 , 153 , 175 , 967 , 75 , 385 , 719 , 12269 , 28729 ,0 }; - static ulong[] dim2786Kuo3Init = { 1 , 3 , 3 , 9 , 13 , 21 , 115 , 55 , 303 , 853 , 1735 , 3763 , 31 , 2547 , 9735 ,0 }; - static ulong[] dim2787Kuo3Init = { 1 , 3 , 3 , 9 , 17 , 25 , 109 , 207 , 465 , 627 , 1171 , 557 , 2577 , 13873 , 30945 ,0 }; - static ulong[] dim2788Kuo3Init = { 1 , 1 , 1 , 1 , 27 , 25 , 65 , 131 , 373 , 297 , 1561 , 2481 , 3491 , 3175 , 12527 ,0 }; - static ulong[] dim2789Kuo3Init = { 1 , 1 , 7 , 11 , 13 , 33 , 81 , 81 , 337 , 249 , 739 , 1451 , 4479 , 10253 , 3585 ,0 }; - static ulong[] dim2790Kuo3Init = { 1 , 1 , 1 , 13 , 3 , 9 , 11 , 109 , 261 , 663 , 507 , 897 , 4081 , 12393 , 21621 ,0 }; - static ulong[] dim2791Kuo3Init = { 1 , 1 , 1 , 9 , 27 , 35 , 13 , 191 , 433 , 111 , 1567 , 851 , 6303 , 2411 , 25985 ,0 }; - static ulong[] dim2792Kuo3Init = { 1 , 3 , 3 , 1 , 7 , 41 , 91 , 217 , 203 , 821 , 883 , 1549 , 37 , 1837 , 19549 ,0 }; - static ulong[] dim2793Kuo3Init = { 1 , 3 , 3 , 11 , 23 , 49 , 27 , 81 , 475 , 251 , 985 , 2527 , 3857 , 4579 , 30231 ,0 }; - static ulong[] dim2794Kuo3Init = { 1 , 1 , 3 , 11 , 7 , 33 , 71 , 207 , 179 , 77 , 743 , 375 , 5649 , 3165 , 25063 ,0 }; - static ulong[] dim2795Kuo3Init = { 1 , 1 , 3 , 9 , 25 , 47 , 21 , 109 , 375 , 525 , 671 , 1117 , 5663 , 9835 , 19675 ,0 }; - static ulong[] dim2796Kuo3Init = { 1 , 3 , 7 , 11 , 19 , 31 , 9 , 167 , 501 , 477 , 1015 , 109 , 6233 , 14131 , 30015 ,0 }; - static ulong[] dim2797Kuo3Init = { 1 , 3 , 1 , 3 , 25 , 9 , 91 , 121 , 373 , 511 , 1925 , 3609 , 7681 , 7321 , 19931 ,0 }; - static ulong[] dim2798Kuo3Init = { 1 , 1 , 3 , 7 , 23 , 23 , 63 , 225 , 511 , 407 , 573 , 587 , 6877 , 4747 , 31503 ,0 }; - static ulong[] dim2799Kuo3Init = { 1 , 3 , 7 , 3 , 7 , 11 , 61 , 119 , 149 , 119 , 1497 , 165 , 5833 , 14727 , 21075 ,0 }; - static ulong[] dim2800Kuo3Init = { 1 , 3 , 7 , 5 , 23 , 27 , 113 , 99 , 97 , 385 , 563 , 1745 , 4321 , 2201 , 5707 ,0 }; - static ulong[] dim2801Kuo3Init = { 1 , 1 , 3 , 15 , 5 , 51 , 49 , 213 , 111 , 587 , 1433 , 1473 , 4673 , 369 , 31405 ,0 }; - static ulong[] dim2802Kuo3Init = { 1 , 1 , 5 , 11 , 25 , 49 , 67 , 163 , 109 , 679 , 975 , 3711 , 6627 , 2273 , 13451 ,0 }; - static ulong[] dim2803Kuo3Init = { 1 , 3 , 5 , 3 , 9 , 3 , 75 , 123 , 71 , 181 , 1007 , 2459 , 5671 , 2805 , 15839 ,0 }; - static ulong[] dim2804Kuo3Init = { 1 , 3 , 5 , 3 , 7 , 51 , 49 , 19 , 89 , 209 , 1097 , 359 , 2487 , 12969 , 24243 ,0 }; - static ulong[] dim2805Kuo3Init = { 1 , 1 , 7 , 11 , 1 , 47 , 61 , 65 , 161 , 801 , 511 , 3711 , 237 , 14741 , 14239 ,0 }; - static ulong[] dim2806Kuo3Init = { 1 , 3 , 7 , 13 , 31 , 25 , 11 , 175 , 151 , 79 , 1749 , 751 , 6129 , 12139 , 30837 ,0 }; - static ulong[] dim2807Kuo3Init = { 1 , 3 , 3 , 11 , 19 , 13 , 71 , 75 , 479 , 211 , 395 , 1935 , 7949 , 12049 , 31539 ,0 }; - static ulong[] dim2808Kuo3Init = { 1 , 3 , 5 , 3 , 19 , 9 , 93 , 79 , 69 , 1001 , 673 , 1963 , 8047 , 8023 , 8199 ,0 }; - static ulong[] dim2809Kuo3Init = { 1 , 3 , 7 , 3 , 11 , 9 , 107 , 39 , 319 , 835 , 1297 , 1667 , 393 , 5619 , 15019 ,0 }; - static ulong[] dim2810Kuo3Init = { 1 , 3 , 1 , 3 , 17 , 25 , 71 , 227 , 219 , 455 , 29 , 1503 , 4207 , 11523 , 13077 ,0 }; - static ulong[] dim2811Kuo3Init = { 1 , 3 , 7 , 1 , 11 , 11 , 91 , 203 , 483 , 959 , 911 , 979 , 4327 , 15113 , 23415 ,0 }; - static ulong[] dim2812Kuo3Init = { 1 , 3 , 7 , 15 , 5 , 63 , 57 , 253 , 369 , 609 , 1831 , 2895 , 1025 , 2567 , 14017 ,0 }; - static ulong[] dim2813Kuo3Init = { 1 , 3 , 5 , 1 , 19 , 39 , 107 , 169 , 107 , 863 , 591 , 4077 , 7441 , 3201 , 269 ,0 }; - static ulong[] dim2814Kuo3Init = { 1 , 1 , 3 , 1 , 7 , 45 , 19 , 103 , 119 , 539 , 9 , 2909 , 8135 , 7913 , 1403 ,0 }; - static ulong[] dim2815Kuo3Init = { 1 , 3 , 1 , 13 , 17 , 39 , 125 , 57 , 417 , 543 , 1067 , 3807 , 397 , 11947 , 7655 ,0 }; - static ulong[] dim2816Kuo3Init = { 1 , 3 , 5 , 7 , 31 , 49 , 65 , 23 , 197 , 777 , 1669 , 1373 , 773 , 6947 , 2835 ,0 }; - static ulong[] dim2817Kuo3Init = { 1 , 3 , 7 , 7 , 25 , 45 , 115 , 31 , 351 , 203 , 1791 , 2931 , 7127 , 12117 , 10781 ,0 }; - static ulong[] dim2818Kuo3Init = { 1 , 1 , 5 , 9 , 21 , 61 , 47 , 59 , 393 , 621 , 811 , 2321 , 7801 , 2255 , 13513 ,0 }; - static ulong[] dim2819Kuo3Init = { 1 , 1 , 5 , 9 , 27 , 15 , 85 , 53 , 379 , 597 , 19 , 267 , 5511 , 8167 , 14843 ,0 }; - static ulong[] dim2820Kuo3Init = { 1 , 1 , 7 , 9 , 19 , 11 , 43 , 101 , 309 , 125 , 2023 , 689 , 589 , 3621 , 10593 ,0 }; - static ulong[] dim2821Kuo3Init = { 1 , 3 , 1 , 1 , 25 , 57 , 55 , 57 , 111 , 743 , 1773 , 2223 , 6567 , 7401 , 14843 ,0 }; - static ulong[] dim2822Kuo3Init = { 1 , 3 , 1 , 11 , 17 , 43 , 1 , 11 , 155 , 287 , 519 , 4051 , 311 , 10079 , 29753 ,0 }; - static ulong[] dim2823Kuo3Init = { 1 , 3 , 7 , 1 , 15 , 33 , 47 , 117 , 343 , 667 , 1489 , 1985 , 5105 , 11887 , 29117 ,0 }; - static ulong[] dim2824Kuo3Init = { 1 , 3 , 3 , 13 , 9 , 33 , 115 , 211 , 7 , 391 , 475 , 1843 , 3277 , 11067 , 12857 ,0 }; - static ulong[] dim2825Kuo3Init = { 1 , 1 , 7 , 7 , 31 , 11 , 17 , 147 , 129 , 875 , 845 , 2999 , 6395 , 361 , 7395 ,0 }; - static ulong[] dim2826Kuo3Init = { 1 , 3 , 5 , 1 , 27 , 17 , 55 , 115 , 35 , 989 , 153 , 77 , 5713 , 14653 , 587 ,0 }; - static ulong[] dim2827Kuo3Init = { 1 , 3 , 3 , 5 , 3 , 37 , 107 , 57 , 201 , 631 , 1549 , 3709 , 3615 , 12567 , 21729 ,0 }; - static ulong[] dim2828Kuo3Init = { 1 , 3 , 3 , 1 , 15 , 19 , 21 , 205 , 253 , 431 , 915 , 1057 , 359 , 431 , 31417 ,0 }; - static ulong[] dim2829Kuo3Init = { 1 , 3 , 7 , 3 , 11 , 47 , 107 , 101 , 461 , 805 , 1569 , 1215 , 765 , 1547 , 32531 ,0 }; - static ulong[] dim2830Kuo3Init = { 1 , 3 , 3 , 3 , 21 , 55 , 61 , 171 , 75 , 337 , 231 , 1925 , 7415 , 1073 , 17519 ,0 }; - static ulong[] dim2831Kuo3Init = { 1 , 3 , 5 , 7 , 5 , 23 , 39 , 119 , 399 , 265 , 601 , 3487 , 1129 , 10731 , 14795 ,0 }; - static ulong[] dim2832Kuo3Init = { 1 , 1 , 5 , 3 , 11 , 57 , 33 , 99 , 283 , 581 , 1791 , 1723 , 411 , 5779 , 8989 ,0 }; - static ulong[] dim2833Kuo3Init = { 1 , 3 , 3 , 13 , 19 , 33 , 81 , 245 , 375 , 763 , 77 , 175 , 5417 , 12525 , 18197 ,0 }; - static ulong[] dim2834Kuo3Init = { 1 , 3 , 7 , 5 , 29 , 31 , 59 , 207 , 19 , 369 , 1449 , 165 , 6115 , 15417 , 14227 ,0 }; - static ulong[] dim2835Kuo3Init = { 1 , 3 , 5 , 11 , 7 , 15 , 109 , 171 , 179 , 541 , 1907 , 2545 , 5633 , 8039 , 23495 ,0 }; - static ulong[] dim2836Kuo3Init = { 1 , 3 , 5 , 7 , 5 , 5 , 51 , 5 , 347 , 351 , 177 , 965 , 6583 , 3631 , 26493 ,0 }; - static ulong[] dim2837Kuo3Init = { 1 , 1 , 1 , 15 , 21 , 55 , 101 , 137 , 165 , 947 , 1149 , 2615 , 3709 , 8231 , 2033 ,0 }; - static ulong[] dim2838Kuo3Init = { 1 , 3 , 5 , 1 , 1 , 11 , 29 , 5 , 353 , 675 , 2045 , 2111 , 2477 , 7803 , 18925 ,0 }; - static ulong[] dim2839Kuo3Init = { 1 , 3 , 3 , 7 , 11 , 5 , 43 , 241 , 103 , 87 , 1841 , 841 , 277 , 7647 , 6953 ,0 }; - static ulong[] dim2840Kuo3Init = { 1 , 1 , 3 , 9 , 23 , 15 , 77 , 199 , 457 , 183 , 1719 , 4077 , 2751 , 6285 , 2741 ,0 }; - static ulong[] dim2841Kuo3Init = { 1 , 3 , 5 , 13 , 11 , 7 , 119 , 207 , 89 , 415 , 1501 , 2333 , 2155 , 13559 , 9701 ,0 }; - static ulong[] dim2842Kuo3Init = { 1 , 1 , 7 , 1 , 9 , 29 , 119 , 171 , 259 , 849 , 493 , 3103 , 2559 , 4323 , 8993 ,0 }; - static ulong[] dim2843Kuo3Init = { 1 , 3 , 7 , 15 , 5 , 3 , 35 , 29 , 177 , 19 , 565 , 2111 , 4781 , 13603 , 10759 ,0 }; - static ulong[] dim2844Kuo3Init = { 1 , 1 , 3 , 13 , 7 , 41 , 45 , 181 , 55 , 575 , 685 , 2407 , 3499 , 10073 , 5717 ,0 }; - static ulong[] dim2845Kuo3Init = { 1 , 3 , 5 , 11 , 25 , 31 , 97 , 247 , 411 , 663 , 413 , 771 , 2325 , 4849 , 18605 ,0 }; - static ulong[] dim2846Kuo3Init = { 1 , 1 , 1 , 1 , 11 , 55 , 77 , 183 , 131 , 873 , 315 , 3403 , 7219 , 5419 , 9943 ,0 }; - static ulong[] dim2847Kuo3Init = { 1 , 1 , 5 , 11 , 17 , 49 , 125 , 1 , 379 , 995 , 1911 , 9 , 1201 , 14599 , 3237 ,0 }; - static ulong[] dim2848Kuo3Init = { 1 , 1 , 5 , 7 , 5 , 47 , 25 , 47 , 93 , 1009 , 361 , 3111 , 6221 , 15799 , 11049 ,0 }; - static ulong[] dim2849Kuo3Init = { 1 , 1 , 1 , 13 , 31 , 41 , 27 , 119 , 463 , 357 , 1399 , 3023 , 8145 , 7233 , 10461 ,0 }; - static ulong[] dim2850Kuo3Init = { 1 , 3 , 1 , 13 , 25 , 1 , 89 , 167 , 13 , 477 , 989 , 1109 , 3279 , 1893 , 22091 ,0 }; - static ulong[] dim2851Kuo3Init = { 1 , 1 , 3 , 11 , 27 , 27 , 127 , 85 , 135 , 975 , 557 , 2247 , 5675 , 7397 , 28829 ,0 }; - static ulong[] dim2852Kuo3Init = { 1 , 1 , 3 , 3 , 5 , 57 , 87 , 115 , 399 , 189 , 497 , 2525 , 323 , 2849 , 1539 ,0 }; - static ulong[] dim2853Kuo3Init = { 1 , 3 , 5 , 15 , 31 , 57 , 49 , 13 , 151 , 483 , 1117 , 2177 , 4011 , 2467 , 5465 ,0 }; - static ulong[] dim2854Kuo3Init = { 1 , 3 , 1 , 13 , 17 , 49 , 31 , 167 , 385 , 183 , 225 , 465 , 2099 , 475 , 28001 ,0 }; - static ulong[] dim2855Kuo3Init = { 1 , 1 , 3 , 3 , 23 , 39 , 37 , 63 , 419 , 95 , 1217 , 1147 , 7599 , 985 , 23455 ,0 }; - static ulong[] dim2856Kuo3Init = { 1 , 3 , 1 , 5 , 15 , 53 , 17 , 221 , 441 , 303 , 1595 , 3731 , 7833 , 14649 , 30843 ,0 }; - static ulong[] dim2857Kuo3Init = { 1 , 3 , 3 , 15 , 13 , 63 , 29 , 137 , 263 , 79 , 591 , 679 , 4681 , 4121 , 22733 ,0 }; - static ulong[] dim2858Kuo3Init = { 1 , 1 , 3 , 3 , 27 , 31 , 97 , 191 , 295 , 601 , 1353 , 3817 , 2305 , 427 , 5985 ,0 }; - static ulong[] dim2859Kuo3Init = { 1 , 3 , 5 , 7 , 29 , 27 , 27 , 249 , 441 , 415 , 489 , 779 , 5927 , 10569 , 7539 ,0 }; - static ulong[] dim2860Kuo3Init = { 1 , 3 , 7 , 1 , 1 , 59 , 21 , 115 , 25 , 715 , 697 , 3585 , 383 , 8043 , 21457 ,0 }; - static ulong[] dim2861Kuo3Init = { 1 , 1 , 7 , 1 , 3 , 37 , 25 , 239 , 25 , 213 , 1449 , 1975 , 1805 , 11867 , 24163 ,0 }; - static ulong[] dim2862Kuo3Init = { 1 , 3 , 5 , 7 , 9 , 37 , 95 , 19 , 105 , 787 , 249 , 2501 , 5073 , 2677 , 2871 ,0 }; - static ulong[] dim2863Kuo3Init = { 1 , 1 , 1 , 7 , 25 , 17 , 59 , 79 , 467 , 489 , 1981 , 169 , 7713 , 3035 , 6135 ,0 }; - static ulong[] dim2864Kuo3Init = { 1 , 1 , 1 , 11 , 21 , 41 , 75 , 59 , 495 , 475 , 803 , 3117 , 4999 , 5153 , 20541 ,0 }; - static ulong[] dim2865Kuo3Init = { 1 , 3 , 5 , 5 , 21 , 5 , 43 , 69 , 167 , 743 , 1395 , 3701 , 1329 , 12039 , 26595 ,0 }; - static ulong[] dim2866Kuo3Init = { 1 , 3 , 5 , 5 , 7 , 51 , 7 , 191 , 341 , 561 , 617 , 803 , 965 , 7995 , 7605 ,0 }; - static ulong[] dim2867Kuo3Init = { 1 , 3 , 5 , 1 , 25 , 21 , 21 , 141 , 461 , 353 , 1909 , 1089 , 4603 , 7285 , 30359 ,0 }; - static ulong[] dim2868Kuo3Init = { 1 , 3 , 1 , 7 , 13 , 17 , 47 , 173 , 151 , 1003 , 1823 , 1463 , 6441 , 8647 , 8671 ,0 }; - static ulong[] dim2869Kuo3Init = { 1 , 1 , 3 , 13 , 29 , 29 , 111 , 237 , 341 , 693 , 773 , 637 , 741 , 7737 , 12077 ,0 }; - static ulong[] dim2870Kuo3Init = { 1 , 1 , 5 , 9 , 1 , 27 , 71 , 177 , 379 , 289 , 1659 , 697 , 4765 , 15945 , 24463 ,0 }; - static ulong[] dim2871Kuo3Init = { 1 , 1 , 7 , 7 , 15 , 13 , 77 , 59 , 5 , 483 , 581 , 2193 , 7765 , 14443 , 21545 ,0 }; - static ulong[] dim2872Kuo3Init = { 1 , 3 , 5 , 11 , 9 , 17 , 111 , 13 , 427 , 405 , 1765 , 2029 , 4989 , 1995 , 18581 ,0 }; - static ulong[] dim2873Kuo3Init = { 1 , 1 , 1 , 1 , 17 , 15 , 9 , 43 , 177 , 277 , 217 , 1869 , 2847 , 11839 , 5483 ,0 }; - static ulong[] dim2874Kuo3Init = { 1 , 3 , 5 , 13 , 1 , 61 , 87 , 211 , 367 , 317 , 1681 , 3913 , 2635 , 5095 , 2993 ,0 }; - static ulong[] dim2875Kuo3Init = { 1 , 3 , 5 , 11 , 13 , 47 , 123 , 111 , 139 , 193 , 1575 , 3549 , 2113 , 2997 , 2319 ,0 }; - static ulong[] dim2876Kuo3Init = { 1 , 3 , 7 , 9 , 17 , 29 , 67 , 195 , 455 , 137 , 1159 , 367 , 469 , 4663 , 13811 ,0 }; - static ulong[] dim2877Kuo3Init = { 1 , 3 , 1 , 9 , 21 , 55 , 27 , 165 , 483 , 487 , 1199 , 2989 , 3195 , 8847 , 12465 ,0 }; - static ulong[] dim2878Kuo3Init = { 1 , 3 , 3 , 5 , 13 , 31 , 5 , 77 , 283 , 837 , 827 , 3477 , 5555 , 15411 , 803 ,0 }; - static ulong[] dim2879Kuo3Init = { 1 , 3 , 5 , 1 , 5 , 47 , 23 , 21 , 255 , 193 , 67 , 1489 , 5785 , 3247 , 18425 ,0 }; - static ulong[] dim2880Kuo3Init = { 1 , 1 , 5 , 11 , 3 , 41 , 1 , 37 , 281 , 767 , 419 , 1067 , 749 , 4985 , 18525 ,0 }; - static ulong[] dim2881Kuo3Init = { 1 , 1 , 3 , 7 , 29 , 47 , 37 , 195 , 359 , 517 , 1809 , 2111 , 419 , 1895 , 17813 ,0 }; - static ulong[] dim2882Kuo3Init = { 1 , 3 , 1 , 13 , 13 , 61 , 99 , 183 , 311 , 515 , 1359 , 1077 , 835 , 12945 , 27707 ,0 }; - static ulong[] dim2883Kuo3Init = { 1 , 3 , 7 , 15 , 5 , 25 , 77 , 7 , 249 , 325 , 929 , 3121 , 4183 , 9347 , 1209 ,0 }; - static ulong[] dim2884Kuo3Init = { 1 , 1 , 1 , 7 , 13 , 59 , 9 , 251 , 323 , 479 , 1791 , 555 , 2591 , 417 , 23821 ,0 }; - static ulong[] dim2885Kuo3Init = { 1 , 3 , 7 , 1 , 31 , 25 , 43 , 167 , 337 , 321 , 1223 , 3693 , 1945 , 4937 , 15613 ,0 }; - static ulong[] dim2886Kuo3Init = { 1 , 3 , 1 , 13 , 23 , 27 , 71 , 3 , 249 , 427 , 1259 , 2493 , 3463 , 8339 , 2361 ,0 }; - static ulong[] dim2887Kuo3Init = { 1 , 3 , 3 , 3 , 25 , 49 , 19 , 167 , 189 , 211 , 1247 , 2883 , 6983 , 14573 , 1021 ,0 }; - static ulong[] dim2888Kuo3Init = { 1 , 1 , 7 , 11 , 5 , 53 , 119 , 115 , 497 , 57 , 1255 , 2771 , 6055 , 865 , 2735 ,0 }; - static ulong[] dim2889Kuo3Init = { 1 , 1 , 7 , 11 , 25 , 63 , 83 , 115 , 185 , 615 , 1135 , 1577 , 3097 , 2955 , 7667 ,0 }; - static ulong[] dim2890Kuo3Init = { 1 , 3 , 7 , 7 , 19 , 33 , 61 , 121 , 339 , 153 , 89 , 1841 , 3219 , 10177 , 13655 ,0 }; - static ulong[] dim2891Kuo3Init = { 1 , 3 , 5 , 3 , 23 , 51 , 111 , 149 , 283 , 863 , 1687 , 813 , 951 , 10593 , 2491 ,0 }; - static ulong[] dim2892Kuo3Init = { 1 , 1 , 5 , 7 , 19 , 63 , 47 , 73 , 91 , 501 , 1837 , 4079 , 313 , 14141 , 7843 ,0 }; - static ulong[] dim2893Kuo3Init = { 1 , 3 , 1 , 9 , 9 , 15 , 49 , 195 , 433 , 289 , 1109 , 3929 , 5589 , 8943 , 6325 ,0 }; - static ulong[] dim2894Kuo3Init = { 1 , 3 , 5 , 13 , 13 , 1 , 97 , 111 , 379 , 963 , 837 , 3681 , 3281 , 153 , 9133 ,0 }; - static ulong[] dim2895Kuo3Init = { 1 , 3 , 5 , 1 , 19 , 37 , 7 , 81 , 443 , 555 , 1885 , 3123 , 7667 , 2579 , 3521 ,0 }; - static ulong[] dim2896Kuo3Init = { 1 , 3 , 1 , 1 , 21 , 17 , 77 , 121 , 157 , 993 , 627 , 893 , 7633 , 6421 , 7315 ,0 }; - static ulong[] dim2897Kuo3Init = { 1 , 1 , 3 , 15 , 25 , 21 , 105 , 187 , 17 , 239 , 1745 , 13 , 1021 , 13319 , 8511 ,0 }; - static ulong[] dim2898Kuo3Init = { 1 , 3 , 1 , 5 , 5 , 19 , 67 , 79 , 79 , 361 , 1189 , 3967 , 6643 , 2367 , 18247 ,0 }; - static ulong[] dim2899Kuo3Init = { 1 , 3 , 5 , 15 , 5 , 15 , 17 , 139 , 405 , 229 , 1819 , 369 , 4011 , 11369 , 5271 ,0 }; - static ulong[] dim2900Kuo3Init = { 1 , 3 , 1 , 3 , 19 , 3 , 97 , 121 , 345 , 917 , 1473 , 1439 , 1007 , 2535 , 17107 ,0 }; - static ulong[] dim2901Kuo3Init = { 1 , 3 , 7 , 3 , 3 , 55 , 117 , 183 , 65 , 589 , 107 , 3933 , 6911 , 6425 , 28363 ,0 }; - static ulong[] dim2902Kuo3Init = { 1 , 1 , 7 , 11 , 25 , 55 , 57 , 45 , 217 , 213 , 281 , 2211 , 6851 , 11553 , 30021 ,0 }; - static ulong[] dim2903Kuo3Init = { 1 , 3 , 7 , 11 , 29 , 5 , 1 , 15 , 477 , 233 , 677 , 311 , 3207 , 10527 , 5543 ,0 }; - static ulong[] dim2904Kuo3Init = { 1 , 3 , 3 , 15 , 21 , 57 , 43 , 9 , 145 , 369 , 1367 , 3241 , 2821 , 8753 , 18579 ,0 }; - static ulong[] dim2905Kuo3Init = { 1 , 1 , 3 , 1 , 13 , 15 , 99 , 237 , 101 , 983 , 657 , 1169 , 617 , 12859 , 32279 ,0 }; - static ulong[] dim2906Kuo3Init = { 1 , 3 , 3 , 3 , 11 , 61 , 53 , 39 , 487 , 967 , 1239 , 1899 , 7063 , 7943 , 6739 ,0 }; - static ulong[] dim2907Kuo3Init = { 1 , 1 , 7 , 15 , 1 , 17 , 27 , 121 , 13 , 519 , 1049 , 3613 , 2777 , 11077 , 28601 ,0 }; - static ulong[] dim2908Kuo3Init = { 1 , 3 , 7 , 13 , 27 , 47 , 39 , 71 , 179 , 899 , 1871 , 3783 , 2029 , 2653 , 5711 ,0 }; - static ulong[] dim2909Kuo3Init = { 1 , 3 , 3 , 13 , 15 , 13 , 67 , 113 , 321 , 1017 , 1615 , 1575 , 3879 , 6113 , 31893 ,0 }; - static ulong[] dim2910Kuo3Init = { 1 , 1 , 7 , 3 , 25 , 45 , 3 , 121 , 275 , 313 , 205 , 1743 , 5349 , 4535 , 22849 ,0 }; - static ulong[] dim2911Kuo3Init = { 1 , 1 , 3 , 1 , 3 , 19 , 21 , 97 , 455 , 1021 , 773 , 1825 , 6985 , 9389 , 21107 ,0 }; - static ulong[] dim2912Kuo3Init = { 1 , 3 , 5 , 9 , 5 , 3 , 29 , 9 , 261 , 575 , 1111 , 1983 , 7629 , 15743 , 11009 ,0 }; - static ulong[] dim2913Kuo3Init = { 1 , 3 , 1 , 3 , 25 , 25 , 79 , 181 , 417 , 109 , 29 , 777 , 4753 , 6131 , 4939 ,0 }; - static ulong[] dim2914Kuo3Init = { 1 , 1 , 3 , 1 , 1 , 1 , 73 , 175 , 377 , 531 , 1829 , 37 , 497 , 12055 , 24991 ,0 }; - static ulong[] dim2915Kuo3Init = { 1 , 1 , 5 , 9 , 27 , 7 , 63 , 115 , 381 , 525 , 1183 , 1035 , 5115 , 2943 , 2947 ,0 }; - static ulong[] dim2916Kuo3Init = { 1 , 3 , 7 , 11 , 13 , 17 , 25 , 203 , 479 , 887 , 1465 , 249 , 4347 , 12201 , 10365 ,0 }; - static ulong[] dim2917Kuo3Init = { 1 , 3 , 5 , 13 , 7 , 19 , 11 , 173 , 505 , 509 , 1311 , 3535 , 403 , 13245 , 25357 ,0 }; - static ulong[] dim2918Kuo3Init = { 1 , 1 , 5 , 1 , 11 , 53 , 111 , 243 , 509 , 17 , 1281 , 1149 , 4561 , 4705 , 5783 ,0 }; - static ulong[] dim2919Kuo3Init = { 1 , 3 , 7 , 5 , 29 , 7 , 39 , 75 , 385 , 921 , 147 , 3419 , 237 , 12609 , 10103 ,0 }; - static ulong[] dim2920Kuo3Init = { 1 , 1 , 5 , 3 , 5 , 21 , 75 , 109 , 451 , 371 , 743 , 3 , 5277 , 10917 , 2677 ,0 }; - static ulong[] dim2921Kuo3Init = { 1 , 3 , 5 , 5 , 21 , 29 , 85 , 79 , 359 , 607 , 191 , 2481 , 2089 , 13441 , 23575 ,0 }; - static ulong[] dim2922Kuo3Init = { 1 , 3 , 1 , 11 , 1 , 43 , 35 , 119 , 363 , 477 , 159 , 3999 , 7731 , 15279 , 20611 ,0 }; - static ulong[] dim2923Kuo3Init = { 1 , 1 , 5 , 5 , 1 , 9 , 111 , 19 , 191 , 899 , 2039 , 1153 , 7893 , 1627 , 32325 ,0 }; - static ulong[] dim2924Kuo3Init = { 1 , 1 , 1 , 11 , 1 , 1 , 43 , 199 , 329 , 245 , 1643 , 2869 , 5563 , 3911 , 21837 ,0 }; - static ulong[] dim2925Kuo3Init = { 1 , 1 , 5 , 15 , 11 , 15 , 35 , 153 , 489 , 383 , 1313 , 1881 , 5895 , 10085 , 2489 ,0 }; - static ulong[] dim2926Kuo3Init = { 1 , 3 , 1 , 5 , 27 , 29 , 15 , 209 , 27 , 291 , 77 , 1759 , 1565 , 5477 , 18701 ,0 }; - static ulong[] dim2927Kuo3Init = { 1 , 3 , 5 , 5 , 19 , 39 , 35 , 207 , 345 , 625 , 1797 , 2563 , 8043 , 1559 , 18415 ,0 }; - static ulong[] dim2928Kuo3Init = { 1 , 3 , 1 , 1 , 21 , 43 , 101 , 89 , 229 , 435 , 1445 , 2789 , 6903 , 11629 , 29933 ,0 }; - static ulong[] dim2929Kuo3Init = { 1 , 1 , 7 , 7 , 21 , 23 , 107 , 21 , 377 , 67 , 1007 , 2323 , 2957 , 6553 , 3225 ,0 }; - static ulong[] dim2930Kuo3Init = { 1 , 1 , 3 , 13 , 3 , 13 , 121 , 119 , 253 , 391 , 215 , 851 , 5047 , 4577 , 17691 ,0 }; - static ulong[] dim2931Kuo3Init = { 1 , 3 , 3 , 3 , 3 , 37 , 65 , 103 , 395 , 745 , 1897 , 3031 , 2321 , 5731 , 4657 ,0 }; - static ulong[] dim2932Kuo3Init = { 1 , 3 , 1 , 7 , 17 , 19 , 61 , 159 , 459 , 207 , 397 , 1101 , 5835 , 1947 , 28479 ,0 }; - static ulong[] dim2933Kuo3Init = { 1 , 1 , 7 , 7 , 23 , 13 , 63 , 7 , 231 , 15 , 855 , 375 , 673 , 12523 , 20981 ,0 }; - static ulong[] dim2934Kuo3Init = { 1 , 1 , 7 , 3 , 21 , 13 , 109 , 93 , 7 , 767 , 477 , 2301 , 3587 , 6053 , 427 ,0 }; - static ulong[] dim2935Kuo3Init = { 1 , 1 , 5 , 5 , 23 , 9 , 97 , 175 , 139 , 983 , 993 , 2447 , 2183 , 16143 , 10059 ,0 }; - static ulong[] dim2936Kuo3Init = { 1 , 1 , 1 , 1 , 17 , 61 , 9 , 13 , 241 , 825 , 707 , 3385 , 6551 , 7321 , 1825 ,0 }; - static ulong[] dim2937Kuo3Init = { 1 , 1 , 5 , 1 , 9 , 63 , 101 , 33 , 151 , 629 , 1903 , 3159 , 1083 , 11109 , 27679 ,0 }; - static ulong[] dim2938Kuo3Init = { 1 , 3 , 1 , 13 , 11 , 57 , 123 , 191 , 41 , 765 , 1039 , 2639 , 3793 , 1403 , 20745 ,0 }; - static ulong[] dim2939Kuo3Init = { 1 , 3 , 7 , 13 , 23 , 45 , 21 , 39 , 259 , 531 , 1205 , 3537 , 1927 , 4357 , 16185 ,0 }; - static ulong[] dim2940Kuo3Init = { 1 , 1 , 3 , 1 , 5 , 59 , 127 , 187 , 67 , 377 , 1577 , 401 , 4523 , 8433 , 20965 ,0 }; - static ulong[] dim2941Kuo3Init = { 1 , 3 , 3 , 7 , 9 , 37 , 9 , 221 , 459 , 301 , 1937 , 283 , 6973 , 3545 , 203 ,0 }; - static ulong[] dim2942Kuo3Init = { 1 , 1 , 3 , 5 , 27 , 29 , 59 , 47 , 11 , 791 , 1863 , 1725 , 2797 , 2673 , 9551 ,0 }; - static ulong[] dim2943Kuo3Init = { 1 , 1 , 5 , 3 , 9 , 17 , 75 , 167 , 31 , 879 , 1841 , 801 , 5659 , 10199 , 8639 ,0 }; - static ulong[] dim2944Kuo3Init = { 1 , 3 , 3 , 13 , 27 , 35 , 99 , 97 , 153 , 987 , 1847 , 2209 , 8139 , 647 , 30087 ,0 }; - static ulong[] dim2945Kuo3Init = { 1 , 1 , 5 , 5 , 3 , 9 , 85 , 105 , 503 , 279 , 1919 , 1407 , 8161 , 3601 , 26729 ,0 }; - static ulong[] dim2946Kuo3Init = { 1 , 3 , 7 , 1 , 23 , 37 , 71 , 131 , 315 , 401 , 389 , 547 , 7305 , 581 , 14619 ,0 }; - static ulong[] dim2947Kuo3Init = { 1 , 1 , 7 , 5 , 3 , 47 , 125 , 87 , 255 , 397 , 1561 , 433 , 7057 , 4595 , 17785 ,0 }; - static ulong[] dim2948Kuo3Init = { 1 , 1 , 5 , 7 , 17 , 59 , 107 , 141 , 437 , 335 , 397 , 3913 , 3777 , 8625 , 25539 ,0 }; - static ulong[] dim2949Kuo3Init = { 1 , 1 , 5 , 1 , 9 , 21 , 43 , 13 , 75 , 667 , 287 , 347 , 1503 , 15905 , 17281 ,0 }; - static ulong[] dim2950Kuo3Init = { 1 , 1 , 1 , 5 , 7 , 1 , 25 , 91 , 337 , 909 , 1555 , 1719 , 1169 , 8537 , 8859 ,0 }; - static ulong[] dim2951Kuo3Init = { 1 , 1 , 3 , 15 , 11 , 17 , 3 , 67 , 305 , 565 , 2023 , 1175 , 1135 , 4453 , 21431 ,0 }; - static ulong[] dim2952Kuo3Init = { 1 , 3 , 1 , 9 , 5 , 17 , 23 , 41 , 317 , 63 , 775 , 3699 , 3141 , 12917 , 1847 ,0 }; - static ulong[] dim2953Kuo3Init = { 1 , 1 , 5 , 5 , 13 , 41 , 27 , 229 , 113 , 223 , 1411 , 2733 , 7769 , 831 , 20447 ,0 }; - static ulong[] dim2954Kuo3Init = { 1 , 1 , 3 , 13 , 9 , 15 , 9 , 235 , 501 , 709 , 643 , 79 , 2163 , 10511 , 8763 ,0 }; - static ulong[] dim2955Kuo3Init = { 1 , 3 , 3 , 7 , 13 , 3 , 61 , 173 , 507 , 619 , 1169 , 3133 , 533 , 7989 , 14071 ,0 }; - static ulong[] dim2956Kuo3Init = { 1 , 1 , 5 , 11 , 9 , 11 , 63 , 147 , 73 , 501 , 371 , 489 , 5689 , 3289 , 23459 ,0 }; - static ulong[] dim2957Kuo3Init = { 1 , 1 , 1 , 1 , 23 , 21 , 83 , 127 , 507 , 395 , 445 , 4021 , 7401 , 14939 , 781 ,0 }; - static ulong[] dim2958Kuo3Init = { 1 , 1 , 5 , 11 , 21 , 15 , 57 , 9 , 223 , 603 , 271 , 2277 , 7509 , 5183 , 9645 ,0 }; - static ulong[] dim2959Kuo3Init = { 1 , 3 , 1 , 5 , 3 , 37 , 59 , 75 , 325 , 481 , 1503 , 2891 , 3333 , 5251 , 24987 ,0 }; - static ulong[] dim2960Kuo3Init = { 1 , 1 , 7 , 5 , 25 , 3 , 95 , 55 , 437 , 809 , 1459 , 957 , 4037 , 4139 , 22307 ,0 }; - static ulong[] dim2961Kuo3Init = { 1 , 3 , 5 , 5 , 7 , 43 , 111 , 183 , 321 , 475 , 633 , 3183 , 2885 , 2083 , 2515 ,0 }; - static ulong[] dim2962Kuo3Init = { 1 , 1 , 3 , 3 , 1 , 1 , 9 , 159 , 257 , 257 , 431 , 3433 , 6191 , 15379 , 29129 ,0 }; - static ulong[] dim2963Kuo3Init = { 1 , 1 , 3 , 9 , 19 , 7 , 69 , 119 , 391 , 381 , 1355 , 877 , 245 , 5287 , 451 ,0 }; - static ulong[] dim2964Kuo3Init = { 1 , 3 , 7 , 3 , 15 , 27 , 47 , 19 , 213 , 213 , 1435 , 3835 , 3639 , 16037 , 32613 ,0 }; - static ulong[] dim2965Kuo3Init = { 1 , 3 , 5 , 15 , 19 , 9 , 115 , 1 , 319 , 893 , 29 , 3363 , 2491 , 8091 , 29797 ,0 }; - static ulong[] dim2966Kuo3Init = { 1 , 3 , 3 , 11 , 19 , 9 , 111 , 181 , 37 , 819 , 843 , 3591 , 3617 , 11209 , 1731 ,0 }; - static ulong[] dim2967Kuo3Init = { 1 , 3 , 5 , 7 , 17 , 31 , 107 , 147 , 469 , 409 , 1391 , 927 , 4483 , 15859 , 11231 ,0 }; - static ulong[] dim2968Kuo3Init = { 1 , 3 , 7 , 15 , 17 , 37 , 37 , 165 , 289 , 857 , 243 , 3803 , 8131 , 7409 , 12197 ,0 }; - static ulong[] dim2969Kuo3Init = { 1 , 1 , 1 , 9 , 17 , 61 , 75 , 177 , 63 , 835 , 731 , 2015 , 7287 , 11803 , 11595 ,0 }; - static ulong[] dim2970Kuo3Init = { 1 , 3 , 1 , 15 , 17 , 43 , 33 , 151 , 259 , 951 , 73 , 2229 , 4851 , 7875 , 21497 ,0 }; - static ulong[] dim2971Kuo3Init = { 1 , 3 , 7 , 11 , 25 , 5 , 91 , 15 , 231 , 729 , 865 , 545 , 3043 , 8925 , 9111 ,0 }; - static ulong[] dim2972Kuo3Init = { 1 , 3 , 5 , 3 , 27 , 13 , 67 , 175 , 135 , 999 , 997 , 2237 , 617 , 14805 , 31347 ,0 }; - static ulong[] dim2973Kuo3Init = { 1 , 3 , 1 , 7 , 5 , 37 , 59 , 155 , 11 , 401 , 421 , 305 , 4727 , 7087 , 27231 ,0 }; - static ulong[] dim2974Kuo3Init = { 1 , 3 , 1 , 7 , 7 , 39 , 105 , 215 , 241 , 959 , 1065 , 2045 , 5807 , 1219 , 12545 ,0 }; - static ulong[] dim2975Kuo3Init = { 1 , 1 , 3 , 5 , 3 , 61 , 3 , 141 , 363 , 677 , 1149 , 1143 , 1697 , 11339 , 10503 ,0 }; - static ulong[] dim2976Kuo3Init = { 1 , 1 , 5 , 5 , 15 , 1 , 37 , 183 , 279 , 885 , 571 , 1537 , 5489 , 12111 , 4867 ,0 }; - static ulong[] dim2977Kuo3Init = { 1 , 1 , 3 , 15 , 7 , 49 , 49 , 37 , 323 , 407 , 1555 , 1209 , 8159 , 12171 , 4457 ,0 }; - static ulong[] dim2978Kuo3Init = { 1 , 3 , 3 , 9 , 9 , 17 , 111 , 19 , 353 , 273 , 1271 , 975 , 3935 , 9689 , 18355 ,0 }; - static ulong[] dim2979Kuo3Init = { 1 , 3 , 1 , 7 , 17 , 37 , 21 , 127 , 115 , 19 , 771 , 667 , 4219 , 1829 , 18899 ,0 }; - static ulong[] dim2980Kuo3Init = { 1 , 3 , 3 , 7 , 3 , 43 , 67 , 43 , 119 , 319 , 1165 , 2759 , 5389 , 10891 , 16529 ,0 }; - static ulong[] dim2981Kuo3Init = { 1 , 3 , 3 , 11 , 29 , 17 , 53 , 137 , 329 , 71 , 1499 , 3381 , 3533 , 15551 , 30561 ,0 }; - static ulong[] dim2982Kuo3Init = { 1 , 3 , 3 , 3 , 5 , 61 , 45 , 109 , 389 , 505 , 1803 , 1845 , 2165 , 267 , 14573 ,0 }; - static ulong[] dim2983Kuo3Init = { 1 , 3 , 7 , 5 , 25 , 55 , 47 , 17 , 421 , 711 , 613 , 1537 , 5255 , 13437 , 3425 ,0 }; - static ulong[] dim2984Kuo3Init = { 1 , 1 , 3 , 7 , 25 , 51 , 25 , 67 , 409 , 309 , 951 , 131 , 2781 , 7445 , 1487 ,0 }; - static ulong[] dim2985Kuo3Init = { 1 , 3 , 7 , 9 , 27 , 21 , 45 , 73 , 465 , 977 , 1327 , 837 , 1311 , 11167 , 21265 ,0 }; - static ulong[] dim2986Kuo3Init = { 1 , 1 , 3 , 11 , 17 , 61 , 27 , 83 , 271 , 245 , 187 , 1947 , 7989 , 13633 , 27023 ,0 }; - static ulong[] dim2987Kuo3Init = { 1 , 3 , 1 , 9 , 17 , 7 , 35 , 195 , 465 , 745 , 1833 , 3231 , 3061 , 1631 , 9081 ,0 }; - static ulong[] dim2988Kuo3Init = { 1 , 3 , 3 , 1 , 5 , 39 , 83 , 13 , 199 , 821 , 839 , 3509 , 3857 , 12389 , 28771 ,0 }; - static ulong[] dim2989Kuo3Init = { 1 , 3 , 3 , 3 , 5 , 15 , 91 , 199 , 239 , 97 , 1699 , 549 , 4735 , 15127 , 7407 ,0 }; - static ulong[] dim2990Kuo3Init = { 1 , 3 , 7 , 9 , 13 , 1 , 7 , 109 , 93 , 733 , 1221 , 3361 , 7765 , 11317 , 431 ,0 }; - static ulong[] dim2991Kuo3Init = { 1 , 3 , 7 , 15 , 31 , 23 , 17 , 97 , 477 , 497 , 1123 , 2731 , 3157 , 5217 , 23901 ,0 }; - static ulong[] dim2992Kuo3Init = { 1 , 1 , 5 , 1 , 1 , 41 , 63 , 11 , 507 , 55 , 1927 , 2193 , 6177 , 3013 , 24095 ,0 }; - static ulong[] dim2993Kuo3Init = { 1 , 1 , 7 , 3 , 25 , 57 , 113 , 99 , 383 , 831 , 1455 , 2603 , 4619 , 9495 , 5073 ,0 }; - static ulong[] dim2994Kuo3Init = { 1 , 1 , 5 , 11 , 25 , 35 , 67 , 83 , 125 , 909 , 227 , 1337 , 3729 , 7623 , 27899 ,0 }; - static ulong[] dim2995Kuo3Init = { 1 , 1 , 1 , 13 , 15 , 23 , 117 , 73 , 285 , 341 , 241 , 3569 , 7401 , 16185 , 18571 ,0 }; - static ulong[] dim2996Kuo3Init = { 1 , 1 , 7 , 11 , 23 , 9 , 123 , 93 , 287 , 881 , 1857 , 195 , 3999 , 81 , 26173 ,0 }; - static ulong[] dim2997Kuo3Init = { 1 , 1 , 3 , 9 , 21 , 27 , 57 , 251 , 321 , 109 , 811 , 3665 , 4575 , 15971 , 24111 ,0 }; - static ulong[] dim2998Kuo3Init = { 1 , 1 , 7 , 11 , 11 , 53 , 71 , 11 , 67 , 433 , 549 , 3121 , 193 , 13099 , 6635 ,0 }; - static ulong[] dim2999Kuo3Init = { 1 , 3 , 1 , 9 , 1 , 39 , 75 , 163 , 259 , 523 , 941 , 3025 , 3757 , 2589 , 15403 ,0 }; - static ulong[] dim3000Kuo3Init = { 1 , 3 , 5 , 1 , 1 , 15 , 47 , 83 , 33 , 881 , 215 , 1717 , 2255 , 7349 , 27345 ,0 }; - static ulong[] dim3001Kuo3Init = { 1 , 1 , 3 , 11 , 15 , 55 , 95 , 125 , 511 , 829 , 1021 , 2095 , 1107 , 13071 , 29279 ,0 }; - static ulong[] dim3002Kuo3Init = { 1 , 1 , 5 , 11 , 15 , 63 , 15 , 123 , 233 , 351 , 1687 , 3383 , 287 , 2721 , 20109 ,0 }; - static ulong[] dim3003Kuo3Init = { 1 , 1 , 1 , 7 , 7 , 19 , 103 , 29 , 349 , 875 , 1631 , 119 , 6095 , 7623 , 4063 ,0 }; - static ulong[] dim3004Kuo3Init = { 1 , 3 , 5 , 5 , 21 , 41 , 45 , 91 , 445 , 193 , 1077 , 3849 , 163 , 15123 , 9677 ,0 }; - static ulong[] dim3005Kuo3Init = { 1 , 1 , 3 , 1 , 7 , 39 , 127 , 75 , 53 , 233 , 531 , 635 , 8055 , 8789 , 6205 ,0 }; - static ulong[] dim3006Kuo3Init = { 1 , 3 , 7 , 5 , 21 , 19 , 53 , 197 , 207 , 791 , 1193 , 365 , 5747 , 12155 , 30361 ,0 }; - static ulong[] dim3007Kuo3Init = { 1 , 1 , 1 , 15 , 23 , 39 , 95 , 75 , 239 , 639 , 253 , 3329 , 6017 , 6647 , 16381 ,0 }; - static ulong[] dim3008Kuo3Init = { 1 , 3 , 3 , 7 , 5 , 37 , 85 , 45 , 473 , 299 , 767 , 3795 , 6895 , 16255 , 20411 ,0 }; - static ulong[] dim3009Kuo3Init = { 1 , 1 , 5 , 15 , 31 , 33 , 83 , 79 , 341 , 11 , 561 , 2051 , 485 , 8653 , 7751 ,0 }; - static ulong[] dim3010Kuo3Init = { 1 , 1 , 1 , 1 , 9 , 39 , 127 , 115 , 55 , 281 , 1439 , 2527 , 3975 , 9037 , 32221 ,0 }; - static ulong[] dim3011Kuo3Init = { 1 , 1 , 7 , 5 , 27 , 45 , 117 , 67 , 471 , 101 , 927 , 2391 , 4935 , 14477 , 17515 ,0 }; - static ulong[] dim3012Kuo3Init = { 1 , 3 , 1 , 1 , 5 , 1 , 45 , 93 , 169 , 181 , 609 , 3489 , 4779 , 11641 , 16535 ,0 }; - static ulong[] dim3013Kuo3Init = { 1 , 3 , 3 , 5 , 1 , 53 , 21 , 169 , 199 , 769 , 813 , 1799 , 5199 , 13499 , 25677 ,0 }; - static ulong[] dim3014Kuo3Init = { 1 , 1 , 3 , 7 , 13 , 43 , 127 , 169 , 503 , 935 , 1315 , 1449 , 1497 , 6173 , 20437 ,0 }; - static ulong[] dim3015Kuo3Init = { 1 , 1 , 5 , 3 , 19 , 31 , 83 , 167 , 23 , 1019 , 1223 , 2705 , 6471 , 11619 , 10589 ,0 }; - static ulong[] dim3016Kuo3Init = { 1 , 1 , 5 , 3 , 7 , 39 , 117 , 67 , 159 , 301 , 553 , 2005 , 5455 , 10049 , 3441 ,0 }; - static ulong[] dim3017Kuo3Init = { 1 , 3 , 5 , 5 , 7 , 45 , 59 , 73 , 105 , 507 , 387 , 2697 , 5679 , 9825 , 7689 ,0 }; - static ulong[] dim3018Kuo3Init = { 1 , 1 , 7 , 13 , 3 , 35 , 93 , 129 , 273 , 165 , 1615 , 3631 , 1391 , 10631 , 27157 ,0 }; - static ulong[] dim3019Kuo3Init = { 1 , 1 , 5 , 5 , 9 , 25 , 23 , 101 , 1 , 741 , 1539 , 1893 , 1573 , 10037 , 3079 ,0 }; - static ulong[] dim3020Kuo3Init = { 1 , 1 , 1 , 13 , 29 , 63 , 119 , 83 , 239 , 993 , 1663 , 391 , 1583 , 11393 , 8361 ,0 }; - static ulong[] dim3021Kuo3Init = { 1 , 1 , 5 , 5 , 11 , 55 , 41 , 155 , 439 , 631 , 1949 , 1529 , 5249 , 883 , 25125 ,0 }; - static ulong[] dim3022Kuo3Init = { 1 , 3 , 1 , 1 , 19 , 15 , 35 , 175 , 33 , 199 , 1979 , 4025 , 1543 , 6451 , 11485 ,0 }; - static ulong[] dim3023Kuo3Init = { 1 , 3 , 1 , 1 , 17 , 63 , 127 , 191 , 463 , 973 , 1509 , 1925 , 3469 , 15967 , 10661 ,0 }; - static ulong[] dim3024Kuo3Init = { 1 , 1 , 1 , 11 , 7 , 57 , 111 , 127 , 475 , 625 , 553 , 1941 , 2923 , 5203 , 16915 ,0 }; - static ulong[] dim3025Kuo3Init = { 1 , 1 , 1 , 5 , 15 , 23 , 61 , 93 , 251 , 865 , 2011 , 2607 , 1691 , 10359 , 4667 ,0 }; - static ulong[] dim3026Kuo3Init = { 1 , 3 , 1 , 13 , 29 , 19 , 5 , 101 , 205 , 515 , 1953 , 3543 , 929 , 8745 , 1773 ,0 }; - static ulong[] dim3027Kuo3Init = { 1 , 1 , 7 , 15 , 19 , 29 , 127 , 153 , 383 , 799 , 639 , 3271 , 6487 , 2989 , 8965 ,0 }; - static ulong[] dim3028Kuo3Init = { 1 , 1 , 5 , 15 , 7 , 7 , 73 , 239 , 117 , 261 , 1147 , 3761 , 1531 , 15613 , 13545 ,0 }; - static ulong[] dim3029Kuo3Init = { 1 , 3 , 1 , 11 , 17 , 29 , 53 , 161 , 47 , 933 , 1763 , 1543 , 3661 , 9369 , 14239 ,0 }; - static ulong[] dim3030Kuo3Init = { 1 , 1 , 5 , 9 , 13 , 47 , 19 , 139 , 115 , 239 , 799 , 2211 , 6205 , 5273 , 31205 ,0 }; - static ulong[] dim3031Kuo3Init = { 1 , 1 , 5 , 9 , 29 , 53 , 121 , 3 , 89 , 253 , 1201 , 89 , 297 , 11561 , 9655 ,0 }; - static ulong[] dim3032Kuo3Init = { 1 , 1 , 7 , 5 , 25 , 43 , 25 , 165 , 135 , 789 , 891 , 1711 , 711 , 269 , 17895 ,0 }; - static ulong[] dim3033Kuo3Init = { 1 , 3 , 1 , 3 , 27 , 57 , 63 , 89 , 33 , 897 , 691 , 3129 , 7253 , 2041 , 14341 ,0 }; - static ulong[] dim3034Kuo3Init = { 1 , 1 , 1 , 1 , 5 , 25 , 21 , 65 , 383 , 687 , 57 , 2267 , 1837 , 7091 , 5941 ,0 }; - static ulong[] dim3035Kuo3Init = { 1 , 3 , 7 , 13 , 9 , 37 , 75 , 113 , 243 , 419 , 387 , 3479 , 3295 , 3659 , 29215 ,0 }; - static ulong[] dim3036Kuo3Init = { 1 , 1 , 1 , 13 , 1 , 39 , 97 , 237 , 509 , 51 , 1239 , 1889 , 915 , 15313 , 3487 ,0 }; - static ulong[] dim3037Kuo3Init = { 1 , 1 , 3 , 1 , 1 , 5 , 81 , 153 , 83 , 977 , 1667 , 571 , 1161 , 9347 , 32353 ,0 }; - static ulong[] dim3038Kuo3Init = { 1 , 1 , 7 , 5 , 11 , 13 , 45 , 91 , 265 , 815 , 1141 , 1187 , 41 , 15723 , 5573 ,0 }; - static ulong[] dim3039Kuo3Init = { 1 , 1 , 7 , 13 , 31 , 29 , 27 , 23 , 163 , 605 , 1457 , 37 , 2075 , 4581 , 10571 ,0 }; - static ulong[] dim3040Kuo3Init = { 1 , 1 , 1 , 11 , 13 , 31 , 119 , 241 , 379 , 427 , 333 , 1299 , 3303 , 13049 , 15233 ,0 }; - static ulong[] dim3041Kuo3Init = { 1 , 3 , 7 , 13 , 23 , 35 , 69 , 195 , 149 , 273 , 41 , 289 , 3173 , 13177 , 10865 ,0 }; - static ulong[] dim3042Kuo3Init = { 1 , 3 , 3 , 7 , 1 , 5 , 85 , 245 , 417 , 887 , 1821 , 3623 , 1591 , 15871 , 10837 ,0 }; - static ulong[] dim3043Kuo3Init = { 1 , 1 , 3 , 13 , 19 , 55 , 11 , 65 , 227 , 273 , 1065 , 1937 , 5197 , 7695 , 24827 ,0 }; - static ulong[] dim3044Kuo3Init = { 1 , 1 , 3 , 15 , 11 , 55 , 11 , 49 , 141 , 607 , 509 , 3785 , 8009 , 4127 , 4757 ,0 }; - static ulong[] dim3045Kuo3Init = { 1 , 1 , 3 , 11 , 31 , 23 , 33 , 241 , 347 , 261 , 1609 , 3177 , 4065 , 13767 , 24607 ,0 }; - static ulong[] dim3046Kuo3Init = { 1 , 3 , 7 , 13 , 13 , 7 , 73 , 63 , 493 , 607 , 869 , 1599 , 7725 , 2405 , 12945 ,0 }; - static ulong[] dim3047Kuo3Init = { 1 , 3 , 1 , 9 , 9 , 57 , 85 , 173 , 259 , 749 , 1661 , 2911 , 7833 , 7577 , 21209 ,0 }; - static ulong[] dim3048Kuo3Init = { 1 , 3 , 5 , 7 , 7 , 27 , 61 , 91 , 417 , 369 , 1181 , 1385 , 2991 , 12503 , 13073 ,0 }; - static ulong[] dim3049Kuo3Init = { 1 , 3 , 5 , 13 , 17 , 11 , 51 , 101 , 45 , 45 , 1247 , 4069 , 3079 , 9081 , 12443 ,0 }; - static ulong[] dim3050Kuo3Init = { 1 , 1 , 3 , 7 , 13 , 57 , 63 , 43 , 451 , 743 , 1045 , 2967 , 6437 , 93 , 4589 ,0 }; - static ulong[] dim3051Kuo3Init = { 1 , 3 , 7 , 3 , 25 , 17 , 113 , 89 , 457 , 261 , 827 , 197 , 7177 , 4135 , 19733 ,0 }; - static ulong[] dim3052Kuo3Init = { 1 , 3 , 5 , 9 , 23 , 59 , 29 , 207 , 19 , 623 , 101 , 1675 , 579 , 3255 , 16259 ,0 }; - static ulong[] dim3053Kuo3Init = { 1 , 1 , 1 , 1 , 21 , 23 , 103 , 123 , 61 , 233 , 71 , 897 , 6147 , 3335 , 1027 ,0 }; - static ulong[] dim3054Kuo3Init = { 1 , 3 , 5 , 13 , 9 , 11 , 101 , 55 , 247 , 285 , 1387 , 2063 , 6853 , 409 , 10715 ,0 }; - static ulong[] dim3055Kuo3Init = { 1 , 1 , 7 , 7 , 11 , 41 , 5 , 157 , 325 , 975 , 1403 , 3187 , 4107 , 4093 , 18165 ,0 }; - static ulong[] dim3056Kuo3Init = { 1 , 3 , 1 , 3 , 25 , 15 , 69 , 93 , 87 , 711 , 1699 , 733 , 7703 , 2191 , 12293 ,0 }; - static ulong[] dim3057Kuo3Init = { 1 , 3 , 3 , 1 , 21 , 41 , 31 , 229 , 325 , 507 , 2019 , 2225 , 1733 , 4447 , 32477 ,0 }; - static ulong[] dim3058Kuo3Init = { 1 , 3 , 1 , 5 , 23 , 41 , 19 , 1 , 467 , 315 , 1513 , 1671 , 4159 , 12477 , 6199 ,0 }; - static ulong[] dim3059Kuo3Init = { 1 , 1 , 1 , 11 , 27 , 61 , 35 , 115 , 215 , 979 , 1887 , 1913 , 689 , 3847 , 11451 ,0 }; - static ulong[] dim3060Kuo3Init = { 1 , 3 , 3 , 7 , 25 , 29 , 65 , 233 , 433 , 113 , 1031 , 2455 , 6743 , 5227 , 7207 ,0 }; - static ulong[] dim3061Kuo3Init = { 1 , 1 , 3 , 9 , 5 , 9 , 85 , 103 , 185 , 699 , 663 , 441 , 8013 , 1227 , 12875 ,0 }; - static ulong[] dim3062Kuo3Init = { 1 , 3 , 5 , 11 , 9 , 59 , 35 , 223 , 131 , 409 , 125 , 3437 , 2015 , 217 , 16351 ,0 }; - static ulong[] dim3063Kuo3Init = { 1 , 3 , 7 , 3 , 9 , 27 , 43 , 211 , 365 , 855 , 1249 , 3127 , 3611 , 9339 , 16083 ,0 }; - static ulong[] dim3064Kuo3Init = { 1 , 1 , 1 , 9 , 29 , 11 , 61 , 27 , 195 , 963 , 1905 , 1679 , 1811 , 7 , 27243 ,0 }; - static ulong[] dim3065Kuo3Init = { 1 , 3 , 7 , 15 , 3 , 41 , 21 , 31 , 461 , 3 , 1033 , 459 , 1831 , 12289 , 19645 ,0 }; - static ulong[] dim3066Kuo3Init = { 1 , 1 , 7 , 7 , 15 , 7 , 25 , 207 , 37 , 177 , 973 , 3207 , 5329 , 8541 , 7929 ,0 }; - static ulong[] dim3067Kuo3Init = { 1 , 1 , 5 , 1 , 29 , 35 , 77 , 251 , 429 , 681 , 391 , 3789 , 5953 , 13339 , 16991 ,0 }; - static ulong[] dim3068Kuo3Init = { 1 , 1 , 5 , 5 , 5 , 39 , 21 , 131 , 511 , 11 , 921 , 3073 , 3239 , 561 , 28595 ,0 }; - static ulong[] dim3069Kuo3Init = { 1 , 3 , 1 , 11 , 3 , 11 , 71 , 231 , 439 , 523 , 209 , 3213 , 211 , 13449 , 23311 ,0 }; - static ulong[] dim3070Kuo3Init = { 1 , 1 , 1 , 5 , 31 , 27 , 59 , 161 , 71 , 619 , 1643 , 3687 , 753 , 7443 , 25743 ,0 }; - static ulong[] dim3071Kuo3Init = { 1 , 3 , 7 , 11 , 13 , 49 , 33 , 223 , 443 , 463 , 1833 , 3757 , 299 , 9633 , 16339 ,0 }; - static ulong[] dim3072Kuo3Init = { 1 , 3 , 7 , 1 , 21 , 57 , 63 , 31 , 491 , 53 , 75 , 3059 , 3013 , 965 , 6209 ,0 }; - static ulong[] dim3073Kuo3Init = { 1 , 1 , 5 , 9 , 3 , 45 , 63 , 25 , 511 , 501 , 1003 , 1499 , 887 , 5583 , 6329 ,0 }; - static ulong[] dim3074Kuo3Init = { 1 , 3 , 1 , 1 , 9 , 11 , 49 , 225 , 511 , 563 , 495 , 1697 , 7943 , 13561 , 16159 ,0 }; - static ulong[] dim3075Kuo3Init = { 1 , 3 , 7 , 9 , 11 , 1 , 95 , 255 , 437 , 979 , 1669 , 179 , 2189 , 14431 , 23919 ,0 }; - static ulong[] dim3076Kuo3Init = { 1 , 3 , 1 , 13 , 13 , 5 , 23 , 233 , 327 , 903 , 167 , 797 , 5205 , 2203 , 22137 ,0 }; - static ulong[] dim3077Kuo3Init = { 1 , 1 , 7 , 11 , 25 , 63 , 43 , 113 , 251 , 39 , 163 , 1631 , 2731 , 12241 , 32567 ,0 }; - static ulong[] dim3078Kuo3Init = { 1 , 1 , 5 , 11 , 3 , 35 , 9 , 21 , 477 , 139 , 1107 , 1975 , 6883 , 6651 , 20847 ,0 }; - static ulong[] dim3079Kuo3Init = { 1 , 3 , 5 , 13 , 25 , 39 , 89 , 217 , 95 , 457 , 1741 , 2725 , 5391 , 13381 , 2411 ,0 }; - static ulong[] dim3080Kuo3Init = { 1 , 3 , 5 , 5 , 1 , 27 , 9 , 51 , 3 , 915 , 1803 , 931 , 7651 , 6497 , 6635 ,0 }; - static ulong[] dim3081Kuo3Init = { 1 , 3 , 7 , 9 , 21 , 53 , 9 , 151 , 155 , 827 , 453 , 4071 , 3153 , 2711 , 25143 ,0 }; - static ulong[] dim3082Kuo3Init = { 1 , 1 , 3 , 7 , 21 , 15 , 5 , 169 , 27 , 479 , 911 , 3949 , 2819 , 387 , 2919 ,0 }; - static ulong[] dim3083Kuo3Init = { 1 , 1 , 3 , 3 , 27 , 59 , 27 , 225 , 507 , 403 , 1333 , 747 , 7731 , 13007 , 16283 ,0 }; - static ulong[] dim3084Kuo3Init = { 1 , 1 , 3 , 13 , 29 , 11 , 65 , 169 , 197 , 209 , 1703 , 3503 , 2661 , 14703 , 28529 ,0 }; - static ulong[] dim3085Kuo3Init = { 1 , 1 , 3 , 13 , 17 , 63 , 73 , 11 , 495 , 603 , 687 , 2773 , 3955 , 12761 , 13899 ,0 }; - static ulong[] dim3086Kuo3Init = { 1 , 1 , 1 , 11 , 7 , 31 , 55 , 133 , 197 , 619 , 1747 , 3531 , 1157 , 7143 , 19347 ,0 }; - static ulong[] dim3087Kuo3Init = { 1 , 3 , 1 , 13 , 15 , 47 , 5 , 117 , 329 , 169 , 2023 , 901 , 397 , 15681 , 8931 ,0 }; - static ulong[] dim3088Kuo3Init = { 1 , 1 , 5 , 1 , 29 , 5 , 79 , 73 , 463 , 125 , 1539 , 2149 , 4353 , 15123 , 27853 ,0 }; - static ulong[] dim3089Kuo3Init = { 1 , 1 , 5 , 7 , 13 , 55 , 59 , 151 , 105 , 79 , 1023 , 1839 , 3889 , 3843 , 6129 ,0 }; - static ulong[] dim3090Kuo3Init = { 1 , 1 , 3 , 15 , 9 , 15 , 109 , 63 , 95 , 573 , 385 , 3773 , 535 , 11307 , 4719 ,0 }; - static ulong[] dim3091Kuo3Init = { 1 , 3 , 7 , 11 , 9 , 9 , 91 , 245 , 403 , 841 , 1771 , 2121 , 6927 , 1029 , 26767 ,0 }; - static ulong[] dim3092Kuo3Init = { 1 , 3 , 1 , 11 , 25 , 55 , 21 , 173 , 327 , 327 , 1747 , 1771 , 6829 , 12155 , 29375 ,0 }; - static ulong[] dim3093Kuo3Init = { 1 , 3 , 7 , 11 , 17 , 15 , 31 , 189 , 179 , 849 , 1895 , 3333 , 7385 , 4473 , 18003 ,0 }; - static ulong[] dim3094Kuo3Init = { 1 , 1 , 7 , 3 , 29 , 37 , 11 , 81 , 181 , 197 , 1231 , 167 , 6611 , 3437 , 8857 ,0 }; - static ulong[] dim3095Kuo3Init = { 1 , 3 , 3 , 15 , 17 , 53 , 63 , 51 , 497 , 725 , 917 , 2661 , 2013 , 10887 , 29145 ,0 }; - static ulong[] dim3096Kuo3Init = { 1 , 1 , 3 , 11 , 15 , 53 , 75 , 209 , 429 , 927 , 1867 , 677 , 5305 , 15901 , 5079 ,0 }; - static ulong[] dim3097Kuo3Init = { 1 , 1 , 1 , 5 , 19 , 57 , 105 , 169 , 113 , 701 , 1123 , 2203 , 285 , 12447 , 18301 ,0 }; - static ulong[] dim3098Kuo3Init = { 1 , 3 , 1 , 7 , 25 , 53 , 51 , 35 , 245 , 173 , 1047 , 1905 , 1773 , 10699 , 32057 ,0 }; - static ulong[] dim3099Kuo3Init = { 1 , 1 , 1 , 7 , 31 , 33 , 15 , 233 , 105 , 943 , 201 , 2681 , 3121 , 14145 , 23741 ,0 }; - static ulong[] dim3100Kuo3Init = { 1 , 1 , 1 , 1 , 27 , 61 , 121 , 199 , 437 , 717 , 1481 , 2421 , 6681 , 2457 , 4411 ,0 }; - static ulong[] dim3101Kuo3Init = { 1 , 1 , 1 , 13 , 31 , 9 , 93 , 149 , 379 , 639 , 1889 , 1385 , 3513 , 10105 , 13933 ,0 }; - static ulong[] dim3102Kuo3Init = { 1 , 1 , 7 , 7 , 9 , 37 , 41 , 221 , 323 , 989 , 445 , 3083 , 6855 , 11577 , 29849 ,0 }; - static ulong[] dim3103Kuo3Init = { 1 , 1 , 7 , 7 , 27 , 55 , 53 , 171 , 87 , 529 , 1555 , 2065 , 1685 , 1953 , 20561 ,0 }; - static ulong[] dim3104Kuo3Init = { 1 , 3 , 7 , 13 , 1 , 15 , 11 , 91 , 81 , 217 , 7 , 1687 , 493 , 13345 , 14009 ,0 }; - static ulong[] dim3105Kuo3Init = { 1 , 3 , 1 , 9 , 5 , 31 , 89 , 33 , 39 , 747 , 753 , 2193 , 1937 , 9685 , 17689 ,0 }; - static ulong[] dim3106Kuo3Init = { 1 , 1 , 3 , 7 , 13 , 61 , 101 , 89 , 305 , 123 , 1773 , 411 , 595 , 10113 , 4725 ,0 }; - static ulong[] dim3107Kuo3Init = { 1 , 1 , 3 , 15 , 3 , 13 , 25 , 205 , 343 , 869 , 115 , 2413 , 4531 , 13185 , 15699 ,0 }; - static ulong[] dim3108Kuo3Init = { 1 , 3 , 5 , 3 , 25 , 37 , 71 , 125 , 85 , 995 , 769 , 2737 , 2495 , 7571 , 26825 ,0 }; - static ulong[] dim3109Kuo3Init = { 1 , 3 , 3 , 11 , 21 , 3 , 109 , 175 , 479 , 605 , 569 , 2753 , 2927 , 10529 , 28345 ,0 }; - static ulong[] dim3110Kuo3Init = { 1 , 3 , 7 , 1 , 5 , 57 , 75 , 79 , 383 , 637 , 1411 , 3955 , 5535 , 9403 , 10463 ,0 }; - static ulong[] dim3111Kuo3Init = { 1 , 1 , 7 , 5 , 27 , 25 , 67 , 35 , 95 , 25 , 1585 , 1725 , 7003 , 2261 , 3575 ,0 }; - static ulong[] dim3112Kuo3Init = { 1 , 3 , 7 , 13 , 11 , 11 , 85 , 141 , 389 , 903 , 995 , 2625 , 7163 , 7229 , 18205 ,0 }; - static ulong[] dim3113Kuo3Init = { 1 , 1 , 3 , 5 , 3 , 53 , 69 , 141 , 213 , 675 , 1799 , 235 , 3433 , 2305 , 29607 ,0 }; - static ulong[] dim3114Kuo3Init = { 1 , 1 , 7 , 5 , 21 , 45 , 119 , 229 , 493 , 691 , 1551 , 3801 , 663 , 9693 , 5255 ,0 }; - static ulong[] dim3115Kuo3Init = { 1 , 3 , 7 , 11 , 11 , 37 , 69 , 65 , 163 , 61 , 1567 , 1879 , 1853 , 11099 , 4523 ,0 }; - static ulong[] dim3116Kuo3Init = { 1 , 1 , 3 , 9 , 5 , 43 , 75 , 93 , 81 , 555 , 803 , 129 , 4391 , 3025 , 1013 ,0 }; - static ulong[] dim3117Kuo3Init = { 1 , 1 , 5 , 5 , 9 , 49 , 69 , 185 , 441 , 567 , 203 , 2641 , 4169 , 15585 , 10963 ,0 }; - static ulong[] dim3118Kuo3Init = { 1 , 3 , 7 , 9 , 9 , 35 , 121 , 117 , 509 , 93 , 1381 , 1329 , 751 , 2351 , 11079 ,0 }; - static ulong[] dim3119Kuo3Init = { 1 , 3 , 5 , 15 , 5 , 61 , 117 , 83 , 383 , 961 , 779 , 1499 , 4695 , 3679 , 20383 ,0 }; - static ulong[] dim3120Kuo3Init = { 1 , 3 , 5 , 5 , 21 , 63 , 105 , 15 , 297 , 923 , 1867 , 1667 , 3523 , 12387 , 14977 ,0 }; - static ulong[] dim3121Kuo3Init = { 1 , 1 , 5 , 5 , 7 , 37 , 123 , 161 , 343 , 959 , 1807 , 1695 , 6121 , 8415 , 5373 ,0 }; - static ulong[] dim3122Kuo3Init = { 1 , 3 , 5 , 15 , 29 , 51 , 107 , 151 , 5 , 715 , 3 , 3005 , 1917 , 12243 , 13903 ,0 }; - static ulong[] dim3123Kuo3Init = { 1 , 3 , 5 , 11 , 25 , 29 , 125 , 165 , 57 , 729 , 1187 , 2273 , 2869 , 13149 , 2831 ,0 }; - static ulong[] dim3124Kuo3Init = { 1 , 1 , 7 , 15 , 1 , 15 , 37 , 15 , 489 , 879 , 89 , 2399 , 547 , 1959 , 20073 ,0 }; - static ulong[] dim3125Kuo3Init = { 1 , 3 , 5 , 13 , 5 , 43 , 101 , 27 , 425 , 531 , 1681 , 3301 , 5741 , 7005 , 6607 ,0 }; - static ulong[] dim3126Kuo3Init = { 1 , 1 , 3 , 13 , 17 , 53 , 61 , 165 , 375 , 7 , 761 , 1891 , 1253 , 2431 , 15273 ,0 }; - static ulong[] dim3127Kuo3Init = { 1 , 1 , 1 , 5 , 13 , 23 , 27 , 229 , 215 , 729 , 9 , 779 , 3583 , 9109 , 19059 ,0 }; - static ulong[] dim3128Kuo3Init = { 1 , 1 , 3 , 9 , 3 , 45 , 99 , 193 , 203 , 57 , 147 , 3953 , 5263 , 14641 , 24729 ,0 }; - static ulong[] dim3129Kuo3Init = { 1 , 3 , 7 , 3 , 11 , 49 , 57 , 121 , 413 , 293 , 1251 , 3791 , 1803 , 12549 , 3743 ,0 }; - static ulong[] dim3130Kuo3Init = { 1 , 3 , 7 , 13 , 19 , 55 , 85 , 1 , 169 , 539 , 1565 , 2157 , 4493 , 9169 , 27583 ,0 }; - static ulong[] dim3131Kuo3Init = { 1 , 1 , 7 , 7 , 19 , 59 , 95 , 171 , 471 , 881 , 663 , 1489 , 8013 , 8981 , 11443 ,0 }; - static ulong[] dim3132Kuo3Init = { 1 , 1 , 3 , 7 , 17 , 59 , 25 , 115 , 439 , 967 , 1939 , 905 , 4141 , 4177 , 24827 ,0 }; - static ulong[] dim3133Kuo3Init = { 1 , 3 , 5 , 3 , 29 , 17 , 23 , 241 , 49 , 815 , 1409 , 3997 , 1073 , 2331 , 455 ,0 }; - static ulong[] dim3134Kuo3Init = { 1 , 1 , 5 , 13 , 27 , 53 , 51 , 67 , 405 , 853 , 1229 , 2647 , 4817 , 521 , 14343 ,0 }; - static ulong[] dim3135Kuo3Init = { 1 , 3 , 3 , 13 , 1 , 55 , 83 , 15 , 41 , 327 , 1501 , 1967 , 5787 , 3557 , 7461 ,0 }; - static ulong[] dim3136Kuo3Init = { 1 , 3 , 5 , 1 , 23 , 43 , 93 , 179 , 373 , 173 , 1625 , 487 , 6973 , 12479 , 24659 ,0 }; - static ulong[] dim3137Kuo3Init = { 1 , 3 , 7 , 15 , 3 , 27 , 9 , 69 , 501 , 287 , 945 , 681 , 3667 , 7499 , 24259 ,0 }; - static ulong[] dim3138Kuo3Init = { 1 , 3 , 7 , 3 , 21 , 55 , 55 , 13 , 191 , 25 , 1339 , 185 , 4345 , 13649 , 17793 ,0 }; - static ulong[] dim3139Kuo3Init = { 1 , 3 , 3 , 1 , 9 , 13 , 95 , 127 , 305 , 961 , 141 , 3071 , 683 , 2141 , 13757 ,0 }; - static ulong[] dim3140Kuo3Init = { 1 , 1 , 5 , 5 , 21 , 59 , 83 , 39 , 137 , 259 , 689 , 339 , 105 , 147 , 26143 ,0 }; - static ulong[] dim3141Kuo3Init = { 1 , 1 , 5 , 7 , 31 , 21 , 121 , 45 , 103 , 507 , 1243 , 3325 , 441 , 6743 , 31937 ,0 }; - static ulong[] dim3142Kuo3Init = { 1 , 1 , 5 , 3 , 7 , 35 , 5 , 117 , 433 , 47 , 261 , 2405 , 3361 , 4361 , 14397 ,0 }; - static ulong[] dim3143Kuo3Init = { 1 , 3 , 7 , 9 , 19 , 7 , 19 , 129 , 79 , 247 , 35 , 1483 , 285 , 4923 , 14255 ,0 }; - static ulong[] dim3144Kuo3Init = { 1 , 3 , 3 , 11 , 13 , 3 , 117 , 169 , 3 , 527 , 1295 , 295 , 2317 , 5391 , 27073 ,0 }; - static ulong[] dim3145Kuo3Init = { 1 , 1 , 7 , 3 , 3 , 53 , 9 , 175 , 157 , 917 , 1297 , 1917 , 5575 , 16183 , 20165 ,0 }; - static ulong[] dim3146Kuo3Init = { 1 , 3 , 3 , 9 , 25 , 47 , 61 , 71 , 129 , 923 , 367 , 1623 , 4281 , 11241 , 14759 ,0 }; - static ulong[] dim3147Kuo3Init = { 1 , 3 , 7 , 11 , 23 , 29 , 53 , 135 , 381 , 943 , 1611 , 1609 , 5897 , 393 , 24647 ,0 }; - static ulong[] dim3148Kuo3Init = { 1 , 1 , 7 , 1 , 3 , 55 , 5 , 191 , 305 , 385 , 1383 , 913 , 1017 , 6463 , 32323 ,0 }; - static ulong[] dim3149Kuo3Init = { 1 , 1 , 5 , 9 , 3 , 57 , 113 , 189 , 41 , 413 , 1685 , 2145 , 6071 , 7229 , 11413 ,0 }; - static ulong[] dim3150Kuo3Init = { 1 , 3 , 3 , 9 , 21 , 5 , 95 , 87 , 247 , 175 , 1265 , 83 , 511 , 2821 , 9881 ,0 }; - static ulong[] dim3151Kuo3Init = { 1 , 3 , 1 , 3 , 31 , 41 , 127 , 115 , 457 , 809 , 2017 , 3979 , 3425 , 159 , 15903 ,0 }; - static ulong[] dim3152Kuo3Init = { 1 , 1 , 7 , 7 , 29 , 9 , 85 , 109 , 299 , 607 , 1991 , 3717 , 4593 , 8529 , 10759 ,0 }; - static ulong[] dim3153Kuo3Init = { 1 , 3 , 1 , 9 , 15 , 49 , 123 , 61 , 49 , 413 , 1599 , 3697 , 2481 , 739 , 1641 ,0 }; - static ulong[] dim3154Kuo3Init = { 1 , 3 , 3 , 1 , 13 , 55 , 35 , 217 , 79 , 167 , 1215 , 2687 , 7303 , 10331 , 29985 ,0 }; - static ulong[] dim3155Kuo3Init = { 1 , 1 , 1 , 9 , 29 , 29 , 37 , 177 , 63 , 515 , 1551 , 1053 , 893 , 6831 , 18039 ,0 }; - static ulong[] dim3156Kuo3Init = { 1 , 1 , 7 , 5 , 25 , 47 , 57 , 209 , 345 , 805 , 999 , 307 , 3465 , 13411 , 17721 ,0 }; - static ulong[] dim3157Kuo3Init = { 1 , 1 , 5 , 11 , 3 , 63 , 95 , 243 , 163 , 923 , 1181 , 3319 , 5903 , 8195 , 21217 ,0 }; - static ulong[] dim3158Kuo3Init = { 1 , 3 , 7 , 11 , 15 , 51 , 75 , 237 , 25 , 907 , 395 , 3721 , 3371 , 12425 , 3795 ,0 }; - static ulong[] dim3159Kuo3Init = { 1 , 1 , 1 , 11 , 15 , 61 , 127 , 39 , 359 , 381 , 1879 , 2605 , 7511 , 4329 , 28251 ,0 }; - static ulong[] dim3160Kuo3Init = { 1 , 3 , 5 , 9 , 11 , 61 , 1 , 215 , 503 , 939 , 419 , 3353 , 3013 , 5391 , 12567 ,0 }; - static ulong[] dim3161Kuo3Init = { 1 , 3 , 1 , 9 , 7 , 57 , 123 , 5 , 473 , 931 , 759 , 571 , 2407 , 13057 , 7443 ,0 }; - static ulong[] dim3162Kuo3Init = { 1 , 1 , 3 , 7 , 31 , 17 , 55 , 181 , 359 , 913 , 271 , 935 , 5911 , 9767 , 23 ,0 }; - static ulong[] dim3163Kuo3Init = { 1 , 1 , 1 , 15 , 1 , 35 , 93 , 233 , 109 , 135 , 1793 , 2453 , 6547 , 15435 , 16227 ,0 }; - static ulong[] dim3164Kuo3Init = { 1 , 3 , 1 , 13 , 5 , 37 , 87 , 51 , 165 , 455 , 621 , 881 , 2377 , 7977 , 29763 ,0 }; - static ulong[] dim3165Kuo3Init = { 1 , 1 , 3 , 13 , 31 , 3 , 119 , 113 , 141 , 179 , 621 , 677 , 1047 , 2405 , 28777 ,0 }; - static ulong[] dim3166Kuo3Init = { 1 , 3 , 1 , 1 , 11 , 25 , 37 , 15 , 117 , 509 , 853 , 747 , 3065 , 11569 , 11731 ,0 }; - static ulong[] dim3167Kuo3Init = { 1 , 1 , 5 , 11 , 31 , 9 , 27 , 219 , 71 , 919 , 1553 , 3067 , 6315 , 17 , 18511 ,0 }; - static ulong[] dim3168Kuo3Init = { 1 , 1 , 7 , 1 , 27 , 39 , 111 , 127 , 315 , 671 , 845 , 179 , 8129 , 15409 , 21565 ,0 }; - static ulong[] dim3169Kuo3Init = { 1 , 1 , 5 , 13 , 31 , 37 , 105 , 67 , 37 , 725 , 1947 , 2743 , 6241 , 5465 , 15025 ,0 }; - static ulong[] dim3170Kuo3Init = { 1 , 1 , 7 , 13 , 7 , 63 , 63 , 209 , 431 , 171 , 845 , 2067 , 4829 , 5627 , 32333 ,0 }; - static ulong[] dim3171Kuo3Init = { 1 , 3 , 7 , 15 , 7 , 61 , 105 , 35 , 113 , 551 , 1227 , 867 , 5907 , 4389 , 13281 ,0 }; - static ulong[] dim3172Kuo3Init = { 1 , 1 , 1 , 13 , 31 , 13 , 123 , 255 , 497 , 365 , 921 , 2009 , 5365 , 15443 , 23455 ,0 }; - static ulong[] dim3173Kuo3Init = { 1 , 1 , 5 , 15 , 5 , 45 , 91 , 199 , 417 , 557 , 827 , 1911 , 4173 , 8705 , 19437 ,0 }; - static ulong[] dim3174Kuo3Init = { 1 , 3 , 3 , 9 , 31 , 51 , 69 , 247 , 407 , 791 , 1811 , 1127 , 6775 , 8343 , 19723 ,0 }; - static ulong[] dim3175Kuo3Init = { 1 , 3 , 3 , 3 , 21 , 43 , 71 , 191 , 339 , 219 , 1809 , 3735 , 151 , 3743 , 11803 ,0 }; - static ulong[] dim3176Kuo3Init = { 1 , 1 , 7 , 3 , 13 , 21 , 1 , 233 , 395 , 335 , 1929 , 547 , 2939 , 9205 , 22309 ,0 }; - static ulong[] dim3177Kuo3Init = { 1 , 1 , 1 , 13 , 7 , 5 , 97 , 189 , 195 , 191 , 833 , 269 , 3255 , 15301 , 11593 ,0 }; - static ulong[] dim3178Kuo3Init = { 1 , 1 , 3 , 1 , 31 , 35 , 53 , 193 , 143 , 241 , 763 , 3221 , 3217 , 14915 , 5603 ,0 }; - static ulong[] dim3179Kuo3Init = { 1 , 3 , 5 , 15 , 3 , 15 , 47 , 171 , 349 , 995 , 1803 , 2123 , 8009 , 10339 , 1827 ,0 }; - static ulong[] dim3180Kuo3Init = { 1 , 1 , 1 , 3 , 11 , 37 , 125 , 149 , 261 , 507 , 1603 , 683 , 137 , 353 , 26313 ,0 }; - static ulong[] dim3181Kuo3Init = { 1 , 3 , 3 , 11 , 5 , 19 , 7 , 97 , 257 , 439 , 825 , 265 , 2493 , 5567 , 8575 ,0 }; - static ulong[] dim3182Kuo3Init = { 1 , 1 , 5 , 5 , 9 , 25 , 101 , 207 , 345 , 823 , 1787 , 2449 , 4377 , 10581 , 19169 ,0 }; - static ulong[] dim3183Kuo3Init = { 1 , 3 , 1 , 9 , 19 , 5 , 15 , 19 , 405 , 665 , 715 , 3743 , 23 , 5061 , 21145 ,0 }; - static ulong[] dim3184Kuo3Init = { 1 , 1 , 3 , 9 , 11 , 7 , 73 , 39 , 77 , 763 , 1251 , 3533 , 6379 , 16101 , 8719 ,0 }; - static ulong[] dim3185Kuo3Init = { 1 , 3 , 3 , 1 , 15 , 55 , 89 , 249 , 475 , 641 , 511 , 111 , 5797 , 5627 , 2187 ,0 }; - static ulong[] dim3186Kuo3Init = { 1 , 1 , 5 , 5 , 7 , 27 , 117 , 153 , 387 , 295 , 309 , 3293 , 5197 , 8359 , 16643 ,0 }; - static ulong[] dim3187Kuo3Init = { 1 , 3 , 3 , 3 , 5 , 35 , 45 , 159 , 495 , 311 , 463 , 1249 , 5163 , 7939 , 21405 ,0 }; - static ulong[] dim3188Kuo3Init = { 1 , 3 , 3 , 7 , 31 , 39 , 125 , 167 , 43 , 41 , 589 , 3329 , 5511 , 7983 , 17329 ,0 }; - static ulong[] dim3189Kuo3Init = { 1 , 1 , 3 , 13 , 1 , 17 , 43 , 95 , 465 , 587 , 1189 , 2629 , 7613 , 15115 , 22299 ,0 }; - static ulong[] dim3190Kuo3Init = { 1 , 3 , 1 , 9 , 21 , 57 , 73 , 241 , 149 , 531 , 827 , 731 , 7431 , 14375 , 16307 ,0 }; - static ulong[] dim3191Kuo3Init = { 1 , 1 , 1 , 7 , 7 , 25 , 113 , 115 , 381 , 951 , 811 , 305 , 935 , 2927 , 18755 ,0 }; - static ulong[] dim3192Kuo3Init = { 1 , 3 , 5 , 13 , 11 , 53 , 91 , 197 , 497 , 9 , 1009 , 25 , 2473 , 2467 , 8827 ,0 }; - static ulong[] dim3193Kuo3Init = { 1 , 3 , 3 , 7 , 23 , 23 , 15 , 3 , 131 , 591 , 379 , 1227 , 3479 , 8409 , 20177 ,0 }; - static ulong[] dim3194Kuo3Init = { 1 , 3 , 5 , 9 , 17 , 47 , 91 , 107 , 17 , 175 , 1181 , 2097 , 457 , 10253 , 24291 ,0 }; - static ulong[] dim3195Kuo3Init = { 1 , 1 , 3 , 5 , 31 , 57 , 25 , 117 , 97 , 707 , 1875 , 4059 , 6997 , 3533 , 27781 ,0 }; - static ulong[] dim3196Kuo3Init = { 1 , 1 , 7 , 11 , 7 , 7 , 53 , 137 , 255 , 1017 , 501 , 847 , 4569 , 3665 , 21377 ,0 }; - static ulong[] dim3197Kuo3Init = { 1 , 1 , 3 , 9 , 19 , 57 , 39 , 213 , 67 , 221 , 149 , 357 , 1137 , 12625 , 13945 ,0 }; - static ulong[] dim3198Kuo3Init = { 1 , 1 , 7 , 11 , 19 , 53 , 75 , 67 , 71 , 811 , 837 , 3399 , 3993 , 3119 , 13459 ,0 }; - static ulong[] dim3199Kuo3Init = { 1 , 1 , 1 , 3 , 29 , 7 , 77 , 249 , 97 , 159 , 1097 , 161 , 1649 , 4663 , 8635 ,0 }; - static ulong[] dim3200Kuo3Init = { 1 , 1 , 5 , 9 , 9 , 11 , 69 , 151 , 419 , 11 , 1457 , 2357 , 7259 , 4059 , 6189 ,0 }; - static ulong[] dim3201Kuo3Init = { 1 , 3 , 5 , 7 , 29 , 1 , 109 , 103 , 129 , 561 , 1629 , 237 , 643 , 14519 , 22839 ,0 }; - static ulong[] dim3202Kuo3Init = { 1 , 3 , 3 , 15 , 17 , 25 , 109 , 213 , 253 , 427 , 849 , 4053 , 3845 , 8935 , 21233 ,0 }; - static ulong[] dim3203Kuo3Init = { 1 , 3 , 1 , 3 , 15 , 53 , 81 , 127 , 131 , 523 , 1303 , 451 , 3363 , 14105 , 28881 ,0 }; - static ulong[] dim3204Kuo3Init = { 1 , 1 , 1 , 13 , 1 , 29 , 105 , 75 , 235 , 407 , 1555 , 1247 , 2329 , 1259 , 8653 ,0 }; - static ulong[] dim3205Kuo3Init = { 1 , 1 , 1 , 3 , 31 , 45 , 9 , 199 , 315 , 375 , 205 , 3157 , 4247 , 11961 , 4039 ,0 }; - static ulong[] dim3206Kuo3Init = { 1 , 3 , 3 , 5 , 3 , 39 , 13 , 125 , 103 , 359 , 287 , 3529 , 2015 , 3187 , 26261 ,0 }; - static ulong[] dim3207Kuo3Init = { 1 , 3 , 3 , 7 , 3 , 63 , 81 , 157 , 169 , 1005 , 889 , 2271 , 7773 , 8739 , 11171 ,0 }; - static ulong[] dim3208Kuo3Init = { 1 , 1 , 1 , 3 , 11 , 63 , 61 , 67 , 1 , 919 , 349 , 1645 , 8155 , 219 , 357 ,0 }; - static ulong[] dim3209Kuo3Init = { 1 , 3 , 7 , 9 , 17 , 39 , 1 , 253 , 497 , 409 , 631 , 1425 , 7763 , 3239 , 5405 ,0 }; - static ulong[] dim3210Kuo3Init = { 1 , 3 , 3 , 3 , 21 , 57 , 97 , 231 , 445 , 417 , 1567 , 739 , 6413 , 13499 , 16947 ,0 }; - static ulong[] dim3211Kuo3Init = { 1 , 1 , 1 , 3 , 13 , 59 , 17 , 15 , 75 , 197 , 267 , 1295 , 3867 , 6607 , 31623 ,0 }; - static ulong[] dim3212Kuo3Init = { 1 , 1 , 3 , 5 , 27 , 1 , 83 , 97 , 381 , 931 , 1133 , 4091 , 341 , 7105 , 28761 ,0 }; - static ulong[] dim3213Kuo3Init = { 1 , 3 , 3 , 11 , 3 , 39 , 49 , 237 , 437 , 353 , 321 , 3609 , 4555 , 8987 , 28727 ,0 }; - static ulong[] dim3214Kuo3Init = { 1 , 3 , 1 , 13 , 15 , 49 , 101 , 255 , 409 , 231 , 355 , 2333 , 7277 , 2549 , 1613 ,0 }; - static ulong[] dim3215Kuo3Init = { 1 , 3 , 3 , 13 , 11 , 49 , 99 , 201 , 57 , 705 , 413 , 2791 , 5947 , 8533 , 22155 ,0 }; - static ulong[] dim3216Kuo3Init = { 1 , 3 , 1 , 15 , 13 , 51 , 91 , 47 , 165 , 995 , 1293 , 3601 , 5841 , 4671 , 27379 ,0 }; - static ulong[] dim3217Kuo3Init = { 1 , 1 , 3 , 11 , 15 , 47 , 43 , 97 , 151 , 75 , 1229 , 2525 , 5085 , 10969 , 5195 ,0 }; - static ulong[] dim3218Kuo3Init = { 1 , 1 , 5 , 3 , 7 , 15 , 65 , 161 , 423 , 773 , 291 , 1081 , 2127 , 15861 , 16051 ,0 }; - static ulong[] dim3219Kuo3Init = { 1 , 3 , 1 , 1 , 11 , 47 , 47 , 157 , 369 , 889 , 221 , 83 , 3165 , 12911 , 20687 ,0 }; - static ulong[] dim3220Kuo3Init = { 1 , 1 , 1 , 9 , 23 , 63 , 97 , 191 , 185 , 863 , 1611 , 241 , 4177 , 14965 , 22205 ,0 }; - static ulong[] dim3221Kuo3Init = { 1 , 3 , 3 , 15 , 13 , 11 , 85 , 109 , 13 , 401 , 1365 , 2637 , 2119 , 14673 , 28813 ,0 }; - static ulong[] dim3222Kuo3Init = { 1 , 1 , 5 , 7 , 23 , 13 , 11 , 9 , 105 , 891 , 1511 , 3969 , 2097 , 2089 , 18535 ,0 }; - static ulong[] dim3223Kuo3Init = { 1 , 1 , 3 , 15 , 3 , 23 , 67 , 197 , 309 , 883 , 1635 , 359 , 5023 , 10693 , 28537 ,0 }; - static ulong[] dim3224Kuo3Init = { 1 , 1 , 3 , 1 , 1 , 25 , 63 , 233 , 445 , 665 , 1971 , 1713 , 1827 , 14269 , 19539 ,0 }; - static ulong[] dim3225Kuo3Init = { 1 , 3 , 3 , 13 , 25 , 27 , 79 , 131 , 441 , 465 , 613 , 2027 , 2521 , 11109 , 14443 ,0 }; - static ulong[] dim3226Kuo3Init = { 1 , 3 , 5 , 13 , 27 , 1 , 27 , 123 , 405 , 567 , 159 , 2319 , 5625 , 4643 , 1185 ,0 }; - static ulong[] dim3227Kuo3Init = { 1 , 1 , 7 , 15 , 15 , 55 , 21 , 105 , 353 , 431 , 955 , 3341 , 2891 , 13667 , 17787 ,0 }; - static ulong[] dim3228Kuo3Init = { 1 , 1 , 1 , 5 , 25 , 61 , 11 , 251 , 459 , 985 , 1285 , 811 , 4279 , 4579 , 14313 ,0 }; - static ulong[] dim3229Kuo3Init = { 1 , 1 , 3 , 15 , 13 , 1 , 63 , 103 , 113 , 91 , 1241 , 2513 , 767 , 9037 , 29591 ,0 }; - static ulong[] dim3230Kuo3Init = { 1 , 3 , 7 , 15 , 31 , 39 , 87 , 215 , 421 , 875 , 913 , 3593 , 2215 , 4889 , 14595 ,0 }; - static ulong[] dim3231Kuo3Init = { 1 , 3 , 3 , 3 , 17 , 61 , 99 , 13 , 475 , 331 , 541 , 2363 , 5697 , 14867 , 11483 ,0 }; - static ulong[] dim3232Kuo3Init = { 1 , 1 , 5 , 3 , 17 , 15 , 7 , 217 , 219 , 327 , 1775 , 939 , 3953 , 2393 , 28241 ,0 }; - static ulong[] dim3233Kuo3Init = { 1 , 1 , 3 , 3 , 11 , 57 , 75 , 139 , 123 , 607 , 87 , 539 , 4955 , 6533 , 31827 ,0 }; - static ulong[] dim3234Kuo3Init = { 1 , 3 , 3 , 15 , 15 , 15 , 43 , 127 , 485 , 1009 , 1201 , 919 , 761 , 385 , 29889 ,0 }; - static ulong[] dim3235Kuo3Init = { 1 , 3 , 1 , 3 , 3 , 53 , 47 , 101 , 463 , 899 , 523 , 1009 , 3541 , 11191 , 2257 ,0 }; - static ulong[] dim3236Kuo3Init = { 1 , 1 , 1 , 3 , 31 , 43 , 9 , 39 , 201 , 469 , 839 , 2509 , 5645 , 2861 , 25533 ,0 }; - static ulong[] dim3237Kuo3Init = { 1 , 3 , 5 , 7 , 19 , 27 , 69 , 45 , 367 , 267 , 953 , 3711 , 603 , 3511 , 13419 ,0 }; - static ulong[] dim3238Kuo3Init = { 1 , 1 , 3 , 1 , 25 , 39 , 33 , 89 , 459 , 573 , 1643 , 3291 , 2371 , 1749 , 20693 ,0 }; - static ulong[] dim3239Kuo3Init = { 1 , 1 , 1 , 13 , 11 , 29 , 103 , 213 , 13 , 219 , 2023 , 1327 , 4315 , 13933 , 19559 ,0 }; - static ulong[] dim3240Kuo3Init = { 1 , 1 , 5 , 3 , 17 , 49 , 11 , 241 , 227 , 157 , 745 , 1377 , 5739 , 14285 , 26107 ,0 }; - static ulong[] dim3241Kuo3Init = { 1 , 1 , 7 , 3 , 23 , 11 , 5 , 213 , 405 , 415 , 1911 , 3763 , 3403 , 16079 , 10957 ,0 }; - static ulong[] dim3242Kuo3Init = { 1 , 3 , 5 , 15 , 31 , 27 , 79 , 153 , 403 , 747 , 269 , 4039 , 2791 , 4711 , 501 ,0 }; - static ulong[] dim3243Kuo3Init = { 1 , 1 , 7 , 15 , 1 , 29 , 105 , 29 , 131 , 913 , 265 , 871 , 2899 , 11547 , 20351 ,0 }; - static ulong[] dim3244Kuo3Init = { 1 , 1 , 1 , 3 , 9 , 47 , 55 , 121 , 487 , 349 , 233 , 1657 , 3015 , 12345 , 2213 ,0 }; - static ulong[] dim3245Kuo3Init = { 1 , 1 , 7 , 9 , 1 , 45 , 49 , 241 , 81 , 673 , 1933 , 3203 , 7433 , 14745 , 5811 ,0 }; - static ulong[] dim3246Kuo3Init = { 1 , 1 , 7 , 5 , 31 , 31 , 97 , 97 , 377 , 795 , 417 , 3851 , 4725 , 9803 , 16785 ,0 }; - static ulong[] dim3247Kuo3Init = { 1 , 3 , 1 , 1 , 9 , 5 , 45 , 141 , 361 , 523 , 297 , 2535 , 4433 , 16353 , 28191 ,0 }; - static ulong[] dim3248Kuo3Init = { 1 , 3 , 3 , 7 , 9 , 29 , 47 , 19 , 419 , 49 , 825 , 1771 , 5439 , 8611 , 12659 ,0 }; - static ulong[] dim3249Kuo3Init = { 1 , 1 , 1 , 9 , 19 , 3 , 89 , 107 , 407 , 567 , 807 , 623 , 7915 , 8083 , 6761 ,0 }; - static ulong[] dim3250Kuo3Init = { 1 , 1 , 5 , 3 , 23 , 35 , 109 , 23 , 461 , 401 , 713 , 965 , 7687 , 9729 , 17287 ,0 }; - static ulong[] dim3251Kuo3Init = { 1 , 3 , 5 , 11 , 11 , 43 , 79 , 197 , 249 , 423 , 953 , 1621 , 4045 , 3913 , 11143 ,0 }; - static ulong[] dim3252Kuo3Init = { 1 , 1 , 3 , 7 , 19 , 59 , 91 , 217 , 481 , 861 , 1915 , 1689 , 2061 , 5377 , 8535 ,0 }; - static ulong[] dim3253Kuo3Init = { 1 , 3 , 3 , 9 , 15 , 57 , 5 , 81 , 133 , 833 , 49 , 3231 , 6315 , 9771 , 5667 ,0 }; - static ulong[] dim3254Kuo3Init = { 1 , 1 , 1 , 11 , 27 , 15 , 83 , 11 , 483 , 799 , 1423 , 2121 , 5385 , 4541 , 597 ,0 }; - static ulong[] dim3255Kuo3Init = { 1 , 3 , 7 , 3 , 19 , 25 , 5 , 111 , 493 , 531 , 317 , 5 , 2601 , 6909 , 11515 ,0 }; - static ulong[] dim3256Kuo3Init = { 1 , 3 , 3 , 7 , 15 , 33 , 63 , 89 , 425 , 913 , 831 , 3881 , 2055 , 4285 , 13015 ,0 }; - static ulong[] dim3257Kuo3Init = { 1 , 3 , 1 , 1 , 11 , 5 , 87 , 255 , 17 , 731 , 1149 , 115 , 1223 , 413 , 579 ,0 }; - static ulong[] dim3258Kuo3Init = { 1 , 1 , 5 , 15 , 11 , 27 , 125 , 97 , 73 , 221 , 687 , 623 , 1617 , 13347 , 1369 ,0 }; - static ulong[] dim3259Kuo3Init = { 1 , 1 , 5 , 9 , 19 , 19 , 39 , 9 , 273 , 687 , 805 , 1105 , 267 , 8321 , 17899 ,0 }; - static ulong[] dim3260Kuo3Init = { 1 , 1 , 7 , 7 , 31 , 25 , 5 , 209 , 3 , 503 , 1757 , 2071 , 6251 , 12821 , 28241 ,0 }; - static ulong[] dim3261Kuo3Init = { 1 , 1 , 5 , 3 , 7 , 51 , 25 , 37 , 197 , 143 , 1261 , 1069 , 6559 , 5625 , 30631 ,0 }; - static ulong[] dim3262Kuo3Init = { 1 , 3 , 1 , 5 , 17 , 15 , 53 , 71 , 433 , 133 , 867 , 3883 , 3281 , 3785 , 11523 ,0 }; - static ulong[] dim3263Kuo3Init = { 1 , 3 , 1 , 7 , 1 , 31 , 89 , 165 , 239 , 525 , 507 , 3637 , 4423 , 1295 , 9441 ,0 }; - static ulong[] dim3264Kuo3Init = { 1 , 1 , 3 , 13 , 7 , 11 , 127 , 151 , 151 , 821 , 381 , 23 , 173 , 14027 , 8391 ,0 }; - static ulong[] dim3265Kuo3Init = { 1 , 3 , 5 , 15 , 1 , 51 , 85 , 67 , 321 , 797 , 1625 , 475 , 313 , 8189 , 13315 ,0 }; - static ulong[] dim3266Kuo3Init = { 1 , 3 , 5 , 7 , 25 , 49 , 1 , 155 , 497 , 771 , 457 , 2097 , 5997 , 11363 , 14715 ,0 }; - static ulong[] dim3267Kuo3Init = { 1 , 1 , 3 , 5 , 15 , 5 , 89 , 219 , 441 , 997 , 127 , 699 , 5245 , 3941 , 14083 ,0 }; - static ulong[] dim3268Kuo3Init = { 1 , 3 , 5 , 15 , 21 , 13 , 35 , 239 , 115 , 57 , 1479 , 2813 , 5249 , 7733 , 3135 ,0 }; - static ulong[] dim3269Kuo3Init = { 1 , 3 , 7 , 3 , 11 , 59 , 49 , 55 , 183 , 631 , 365 , 323 , 6891 , 3727 , 24231 ,0 }; - static ulong[] dim3270Kuo3Init = { 1 , 1 , 1 , 13 , 9 , 29 , 101 , 59 , 257 , 995 , 145 , 3037 , 7291 , 16021 , 31971 ,0 }; - static ulong[] dim3271Kuo3Init = { 1 , 1 , 1 , 1 , 19 , 5 , 51 , 21 , 207 , 767 , 1301 , 3111 , 7133 , 9555 , 24043 ,0 }; - static ulong[] dim3272Kuo3Init = { 1 , 1 , 3 , 5 , 23 , 45 , 25 , 149 , 225 , 141 , 827 , 37 , 3767 , 16305 , 30229 ,0 }; - static ulong[] dim3273Kuo3Init = { 1 , 1 , 3 , 9 , 21 , 15 , 51 , 155 , 185 , 551 , 243 , 2493 , 653 , 10615 , 28137 ,0 }; - static ulong[] dim3274Kuo3Init = { 1 , 1 , 1 , 5 , 13 , 55 , 77 , 71 , 383 , 605 , 957 , 1605 , 6905 , 12193 , 26729 ,0 }; - static ulong[] dim3275Kuo3Init = { 1 , 3 , 1 , 15 , 13 , 19 , 95 , 219 , 435 , 165 , 1531 , 2733 , 4213 , 3739 , 10943 ,0 }; - static ulong[] dim3276Kuo3Init = { 1 , 3 , 1 , 7 , 31 , 35 , 3 , 85 , 331 , 161 , 1167 , 3627 , 7075 , 16189 , 385 ,0 }; - static ulong[] dim3277Kuo3Init = { 1 , 1 , 3 , 11 , 3 , 17 , 103 , 205 , 299 , 917 , 105 , 1675 , 3461 , 895 , 3279 ,0 }; - static ulong[] dim3278Kuo3Init = { 1 , 1 , 1 , 7 , 25 , 11 , 47 , 77 , 91 , 263 , 1575 , 1337 , 5603 , 6561 , 4941 ,0 }; - static ulong[] dim3279Kuo3Init = { 1 , 1 , 1 , 5 , 15 , 17 , 77 , 69 , 413 , 343 , 1923 , 2013 , 269 , 12245 , 14611 ,0 }; - static ulong[] dim3280Kuo3Init = { 1 , 3 , 7 , 13 , 1 , 29 , 99 , 83 , 69 , 871 , 945 , 1271 , 5741 , 2505 , 4743 ,0 }; - static ulong[] dim3281Kuo3Init = { 1 , 3 , 5 , 13 , 23 , 55 , 95 , 17 , 321 , 929 , 1499 , 205 , 5529 , 3819 , 29763 ,0 }; - static ulong[] dim3282Kuo3Init = { 1 , 3 , 3 , 1 , 1 , 47 , 15 , 151 , 273 , 991 , 1993 , 2325 , 3633 , 9033 , 795 ,0 }; - static ulong[] dim3283Kuo3Init = { 1 , 3 , 1 , 5 , 19 , 59 , 115 , 79 , 51 , 585 , 253 , 1545 , 2871 , 2303 , 23189 ,0 }; - static ulong[] dim3284Kuo3Init = { 1 , 1 , 7 , 11 , 5 , 49 , 77 , 79 , 103 , 719 , 965 , 2115 , 2431 , 7761 , 7267 ,0 }; - static ulong[] dim3285Kuo3Init = { 1 , 1 , 7 , 13 , 1 , 33 , 13 , 121 , 297 , 217 , 1143 , 2185 , 6007 , 13233 , 4529 ,0 }; - static ulong[] dim3286Kuo3Init = { 1 , 3 , 7 , 3 , 1 , 15 , 17 , 155 , 321 , 19 , 1071 , 3195 , 3589 , 12159 , 30323 ,0 }; - static ulong[] dim3287Kuo3Init = { 1 , 3 , 5 , 7 , 3 , 57 , 35 , 197 , 247 , 449 , 557 , 809 , 909 , 9141 , 26613 ,0 }; - static ulong[] dim3288Kuo3Init = { 1 , 3 , 1 , 5 , 13 , 43 , 61 , 177 , 21 , 161 , 1823 , 1077 , 6523 , 10765 , 17427 ,0 }; - static ulong[] dim3289Kuo3Init = { 1 , 1 , 3 , 3 , 13 , 27 , 77 , 77 , 315 , 763 , 853 , 3801 , 1505 , 13801 , 28217 ,0 }; - static ulong[] dim3290Kuo3Init = { 1 , 1 , 1 , 9 , 15 , 27 , 45 , 131 , 271 , 703 , 1509 , 443 , 7739 , 3011 , 32463 ,0 }; - static ulong[] dim3291Kuo3Init = { 1 , 1 , 7 , 11 , 17 , 3 , 93 , 55 , 331 , 785 , 585 , 3451 , 283 , 2623 , 21459 ,0 }; - static ulong[] dim3292Kuo3Init = { 1 , 3 , 5 , 15 , 3 , 3 , 101 , 25 , 235 , 721 , 257 , 3961 , 7049 , 9861 , 21259 ,0 }; - static ulong[] dim3293Kuo3Init = { 1 , 1 , 7 , 7 , 9 , 31 , 17 , 17 , 473 , 155 , 677 , 603 , 7503 , 2845 , 21089 ,0 }; - static ulong[] dim3294Kuo3Init = { 1 , 3 , 3 , 9 , 11 , 29 , 5 , 135 , 141 , 587 , 1073 , 461 , 883 , 16191 , 16139 ,0 }; - static ulong[] dim3295Kuo3Init = { 1 , 3 , 1 , 15 , 25 , 17 , 87 , 231 , 63 , 563 , 1061 , 3207 , 2291 , 913 , 11871 ,0 }; - static ulong[] dim3296Kuo3Init = { 1 , 1 , 7 , 11 , 7 , 45 , 53 , 79 , 247 , 21 , 1203 , 1857 , 5095 , 7533 , 4427 ,0 }; - static ulong[] dim3297Kuo3Init = { 1 , 3 , 5 , 9 , 17 , 57 , 29 , 181 , 345 , 709 , 1889 , 2625 , 8157 , 4681 , 21681 ,0 }; - static ulong[] dim3298Kuo3Init = { 1 , 3 , 5 , 13 , 9 , 63 , 63 , 183 , 123 , 957 , 27 , 3113 , 1873 , 8917 , 8669 ,0 }; - static ulong[] dim3299Kuo3Init = { 1 , 3 , 5 , 9 , 29 , 59 , 31 , 211 , 459 , 679 , 259 , 1885 , 1895 , 12815 , 2437 ,0 }; - static ulong[] dim3300Kuo3Init = { 1 , 1 , 5 , 11 , 13 , 51 , 125 , 5 , 15 , 865 , 901 , 1803 , 3277 , 2879 , 13057 ,0 }; - static ulong[] dim3301Kuo3Init = { 1 , 1 , 7 , 9 , 27 , 39 , 115 , 67 , 389 , 1 , 649 , 639 , 7183 , 15929 , 12953 ,0 }; - static ulong[] dim3302Kuo3Init = { 1 , 1 , 5 , 13 , 3 , 7 , 21 , 219 , 241 , 977 , 1233 , 1717 , 7077 , 8657 , 1389 ,0 }; - static ulong[] dim3303Kuo3Init = { 1 , 1 , 5 , 15 , 9 , 51 , 101 , 127 , 383 , 801 , 657 , 2793 , 1037 , 11525 , 7195 ,0 }; - static ulong[] dim3304Kuo3Init = { 1 , 3 , 3 , 7 , 1 , 29 , 71 , 227 , 19 , 371 , 363 , 809 , 4241 , 5739 , 26497 ,0 }; - static ulong[] dim3305Kuo3Init = { 1 , 3 , 5 , 11 , 25 , 23 , 65 , 161 , 259 , 135 , 1047 , 3943 , 5749 , 2931 , 20647 ,0 }; - static ulong[] dim3306Kuo3Init = { 1 , 1 , 7 , 3 , 1 , 55 , 1 , 85 , 271 , 67 , 1813 , 77 , 5435 , 11867 , 28375 ,0 }; - static ulong[] dim3307Kuo3Init = { 1 , 1 , 7 , 11 , 31 , 53 , 43 , 47 , 285 , 901 , 901 , 977 , 733 , 5291 , 7043 ,0 }; - static ulong[] dim3308Kuo3Init = { 1 , 3 , 3 , 7 , 1 , 59 , 79 , 123 , 355 , 721 , 365 , 2871 , 6253 , 14511 , 4209 ,0 }; - static ulong[] dim3309Kuo3Init = { 1 , 1 , 5 , 15 , 5 , 49 , 77 , 107 , 237 , 257 , 703 , 1013 , 4563 , 8603 , 10469 ,0 }; - static ulong[] dim3310Kuo3Init = { 1 , 3 , 7 , 11 , 27 , 59 , 9 , 129 , 21 , 991 , 1283 , 2871 , 759 , 5435 , 30419 ,0 }; - static ulong[] dim3311Kuo3Init = { 1 , 3 , 5 , 1 , 19 , 5 , 5 , 215 , 91 , 117 , 939 , 3595 , 4331 , 16083 , 23279 ,0 }; - static ulong[] dim3312Kuo3Init = { 1 , 1 , 7 , 7 , 7 , 45 , 45 , 71 , 75 , 261 , 685 , 63 , 3553 , 16349 , 6803 ,0 }; - static ulong[] dim3313Kuo3Init = { 1 , 3 , 1 , 9 , 1 , 23 , 101 , 11 , 331 , 407 , 547 , 1553 , 7471 , 6125 , 3965 ,0 }; - static ulong[] dim3314Kuo3Init = { 1 , 3 , 7 , 11 , 19 , 29 , 1 , 53 , 125 , 775 , 1381 , 1885 , 2655 , 7199 , 24073 ,0 }; - static ulong[] dim3315Kuo3Init = { 1 , 3 , 5 , 7 , 27 , 21 , 79 , 211 , 433 , 993 , 143 , 2241 , 2607 , 15447 , 6121 ,0 }; - static ulong[] dim3316Kuo3Init = { 1 , 3 , 3 , 7 , 29 , 39 , 93 , 65 , 39 , 577 , 1471 , 3491 , 4413 , 10553 , 1339 ,0 }; - static ulong[] dim3317Kuo3Init = { 1 , 1 , 5 , 11 , 21 , 23 , 75 , 237 , 439 , 171 , 361 , 3283 , 4145 , 15267 , 19917 ,0 }; - static ulong[] dim3318Kuo3Init = { 1 , 1 , 1 , 5 , 9 , 55 , 39 , 171 , 423 , 211 , 43 , 2597 , 7135 , 2437 , 28965 ,0 }; - static ulong[] dim3319Kuo3Init = { 1 , 3 , 1 , 9 , 11 , 15 , 71 , 109 , 337 , 907 , 135 , 3557 , 7359 , 3539 , 26953 ,0 }; - static ulong[] dim3320Kuo3Init = { 1 , 1 , 1 , 15 , 15 , 63 , 9 , 47 , 153 , 157 , 457 , 857 , 6985 , 3559 , 23285 ,0 }; - static ulong[] dim3321Kuo3Init = { 1 , 3 , 3 , 9 , 21 , 21 , 3 , 223 , 67 , 429 , 497 , 1303 , 869 , 3909 , 17491 ,0 }; - static ulong[] dim3322Kuo3Init = { 1 , 1 , 1 , 3 , 23 , 37 , 7 , 197 , 223 , 597 , 421 , 845 , 1397 , 927 , 20621 ,0 }; - static ulong[] dim3323Kuo3Init = { 1 , 3 , 1 , 13 , 5 , 37 , 41 , 83 , 241 , 301 , 1157 , 1087 , 2365 , 10905 , 25195 ,0 }; - static ulong[] dim3324Kuo3Init = { 1 , 3 , 7 , 11 , 25 , 11 , 75 , 9 , 31 , 5 , 1909 , 681 , 2891 , 867 , 4661 ,0 }; - static ulong[] dim3325Kuo3Init = { 1 , 1 , 1 , 13 , 21 , 33 , 127 , 233 , 369 , 381 , 711 , 133 , 4463 , 14119 , 8877 ,0 }; - static ulong[] dim3326Kuo3Init = { 1 , 1 , 7 , 7 , 21 , 13 , 5 , 61 , 29 , 247 , 923 , 3533 , 2831 , 9645 , 1537 ,0 }; - static ulong[] dim3327Kuo3Init = { 1 , 1 , 1 , 9 , 29 , 13 , 29 , 177 , 195 , 299 , 445 , 3753 , 3699 , 9383 , 3249 ,0 }; - static ulong[] dim3328Kuo3Init = { 1 , 3 , 1 , 3 , 17 , 55 , 21 , 245 , 11 , 93 , 1097 , 1601 , 4431 , 5847 , 21521 ,0 }; - static ulong[] dim3329Kuo3Init = { 1 , 1 , 3 , 9 , 3 , 37 , 9 , 179 , 465 , 123 , 333 , 3765 , 1599 , 8709 , 11007 ,0 }; - static ulong[] dim3330Kuo3Init = { 1 , 3 , 3 , 11 , 15 , 25 , 23 , 217 , 193 , 767 , 1433 , 3435 , 4891 , 4109 , 32061 ,0 }; - static ulong[] dim3331Kuo3Init = { 1 , 3 , 7 , 11 , 21 , 25 , 123 , 111 , 377 , 951 , 1791 , 2173 , 569 , 12831 , 30045 ,0 }; - static ulong[] dim3332Kuo3Init = { 1 , 1 , 7 , 11 , 11 , 19 , 75 , 63 , 497 , 1005 , 1215 , 3957 , 4137 , 4851 , 23547 ,0 }; - static ulong[] dim3333Kuo3Init = { 1 , 1 , 1 , 15 , 15 , 9 , 59 , 143 , 27 , 941 , 117 , 3035 , 1201 , 4373 , 19291 ,0 }; - static ulong[] dim3334Kuo3Init = { 1 , 3 , 3 , 5 , 1 , 3 , 37 , 187 , 115 , 901 , 617 , 1959 , 2243 , 6563 , 3087 ,0 }; - static ulong[] dim3335Kuo3Init = { 1 , 1 , 1 , 9 , 17 , 31 , 67 , 243 , 35 , 667 , 1863 , 1017 , 6501 , 9279 , 18089 ,0 }; - static ulong[] dim3336Kuo3Init = { 1 , 1 , 5 , 11 , 25 , 19 , 25 , 255 , 371 , 27 , 763 , 2575 , 695 , 6155 , 27761 ,0 }; - static ulong[] dim3337Kuo3Init = { 1 , 3 , 1 , 1 , 5 , 49 , 79 , 149 , 331 , 601 , 199 , 2927 , 6293 , 12449 , 16397 ,0 }; - static ulong[] dim3338Kuo3Init = { 1 , 1 , 7 , 11 , 29 , 41 , 29 , 161 , 191 , 519 , 445 , 1159 , 3009 , 3413 , 21757 ,0 }; - static ulong[] dim3339Kuo3Init = { 1 , 3 , 7 , 5 , 23 , 57 , 93 , 211 , 57 , 269 , 1627 , 3393 , 873 , 8189 , 26059 ,0 }; - static ulong[] dim3340Kuo3Init = { 1 , 1 , 7 , 11 , 27 , 59 , 125 , 251 , 259 , 251 , 79 , 2693 , 1815 , 8759 , 15667 ,0 }; - static ulong[] dim3341Kuo3Init = { 1 , 1 , 3 , 15 , 31 , 47 , 15 , 51 , 17 , 761 , 589 , 537 , 3991 , 2883 , 6899 ,0 }; - static ulong[] dim3342Kuo3Init = { 1 , 1 , 3 , 7 , 19 , 39 , 95 , 143 , 37 , 183 , 1719 , 1819 , 1659 , 1043 , 31929 ,0 }; - static ulong[] dim3343Kuo3Init = { 1 , 1 , 3 , 7 , 15 , 47 , 105 , 45 , 67 , 665 , 1273 , 221 , 5423 , 679 , 8375 ,0 }; - static ulong[] dim3344Kuo3Init = { 1 , 3 , 1 , 15 , 23 , 37 , 123 , 233 , 117 , 743 , 785 , 3871 , 6031 , 14379 , 3339 ,0 }; - static ulong[] dim3345Kuo3Init = { 1 , 3 , 1 , 13 , 1 , 47 , 33 , 63 , 309 , 961 , 83 , 2539 , 5935 , 3121 , 27671 ,0 }; - static ulong[] dim3346Kuo3Init = { 1 , 3 , 7 , 13 , 21 , 11 , 103 , 87 , 433 , 39 , 293 , 3217 , 1533 , 4511 , 24493 ,0 }; - static ulong[] dim3347Kuo3Init = { 1 , 1 , 5 , 7 , 9 , 51 , 41 , 133 , 443 , 605 , 913 , 377 , 5969 , 8401 , 25427 ,0 }; - static ulong[] dim3348Kuo3Init = { 1 , 1 , 1 , 3 , 21 , 27 , 59 , 41 , 155 , 35 , 897 , 2317 , 6557 , 679 , 7863 ,0 }; - static ulong[] dim3349Kuo3Init = { 1 , 1 , 7 , 11 , 19 , 47 , 39 , 53 , 401 , 199 , 271 , 1385 , 3505 , 719 , 12963 ,0 }; - static ulong[] dim3350Kuo3Init = { 1 , 1 , 7 , 7 , 13 , 7 , 11 , 131 , 455 , 605 , 523 , 3435 , 2313 , 9861 , 22437 ,0 }; - static ulong[] dim3351Kuo3Init = { 1 , 3 , 7 , 3 , 19 , 5 , 125 , 71 , 425 , 321 , 1151 , 231 , 2585 , 12899 , 4789 ,0 }; - static ulong[] dim3352Kuo3Init = { 1 , 3 , 5 , 11 , 15 , 27 , 35 , 13 , 187 , 863 , 795 , 1005 , 6443 , 3011 , 5275 ,0 }; - static ulong[] dim3353Kuo3Init = { 1 , 3 , 7 , 5 , 25 , 61 , 33 , 201 , 343 , 337 , 1441 , 2647 , 3469 , 5537 , 30595 ,0 }; - static ulong[] dim3354Kuo3Init = { 1 , 1 , 7 , 11 , 17 , 13 , 73 , 209 , 121 , 411 , 1027 , 1879 , 845 , 14019 , 4269 ,0 }; - static ulong[] dim3355Kuo3Init = { 1 , 3 , 5 , 9 , 11 , 51 , 69 , 103 , 245 , 677 , 409 , 135 , 3775 , 15781 , 24159 ,0 }; - static ulong[] dim3356Kuo3Init = { 1 , 1 , 7 , 3 , 11 , 9 , 117 , 101 , 205 , 745 , 941 , 125 , 5915 , 16305 , 12547 ,0 }; - static ulong[] dim3357Kuo3Init = { 1 , 1 , 1 , 9 , 9 , 51 , 37 , 135 , 79 , 327 , 1695 , 2517 , 2685 , 1103 , 6035 ,0 }; - static ulong[] dim3358Kuo3Init = { 1 , 1 , 3 , 13 , 21 , 33 , 33 , 229 , 201 , 939 , 1625 , 2043 , 6661 , 11821 , 22881 ,0 }; - static ulong[] dim3359Kuo3Init = { 1 , 1 , 1 , 11 , 23 , 3 , 23 , 5 , 329 , 467 , 963 , 3833 , 7345 , 3225 , 3709 ,0 }; - static ulong[] dim3360Kuo3Init = { 1 , 3 , 1 , 11 , 27 , 21 , 35 , 159 , 255 , 707 , 353 , 3095 , 6701 , 14311 , 839 ,0 }; - static ulong[] dim3361Kuo3Init = { 1 , 1 , 5 , 7 , 7 , 63 , 107 , 227 , 233 , 303 , 1523 , 2019 , 227 , 14695 , 20253 ,0 }; - static ulong[] dim3362Kuo3Init = { 1 , 3 , 1 , 1 , 17 , 29 , 1 , 167 , 331 , 795 , 2027 , 2333 , 361 , 1841 , 4053 ,0 }; - static ulong[] dim3363Kuo3Init = { 1 , 1 , 7 , 9 , 1 , 41 , 71 , 173 , 103 , 43 , 635 , 3311 , 5883 , 6517 , 467 ,0 }; - static ulong[] dim3364Kuo3Init = { 1 , 3 , 7 , 1 , 3 , 15 , 101 , 197 , 449 , 393 , 889 , 1189 , 2665 , 3647 , 21977 ,0 }; - static ulong[] dim3365Kuo3Init = { 1 , 3 , 1 , 11 , 23 , 5 , 103 , 199 , 417 , 729 , 137 , 1667 , 5 , 4769 , 11981 ,0 }; - static ulong[] dim3366Kuo3Init = { 1 , 3 , 1 , 1 , 17 , 37 , 73 , 231 , 195 , 497 , 1835 , 1597 , 403 , 12569 , 24761 ,0 }; - static ulong[] dim3367Kuo3Init = { 1 , 3 , 3 , 7 , 31 , 37 , 33 , 39 , 359 , 961 , 1745 , 2353 , 827 , 6439 , 27419 ,0 }; - static ulong[] dim3368Kuo3Init = { 1 , 1 , 3 , 1 , 25 , 25 , 97 , 111 , 149 , 799 , 593 , 1011 , 5439 , 2613 , 3669 ,0 }; - static ulong[] dim3369Kuo3Init = { 1 , 1 , 3 , 5 , 5 , 21 , 55 , 37 , 483 , 407 , 1059 , 905 , 5225 , 9441 , 17461 ,0 }; - static ulong[] dim3370Kuo3Init = { 1 , 1 , 1 , 11 , 27 , 15 , 93 , 87 , 423 , 625 , 285 , 4051 , 7931 , 9005 , 4033 ,0 }; - static ulong[] dim3371Kuo3Init = { 1 , 1 , 1 , 7 , 13 , 17 , 13 , 221 , 29 , 179 , 645 , 2721 , 4781 , 6151 , 6435 ,0 }; - static ulong[] dim3372Kuo3Init = { 1 , 1 , 5 , 9 , 11 , 59 , 53 , 249 , 13 , 295 , 467 , 1781 , 2381 , 2897 , 11175 ,0 }; - static ulong[] dim3373Kuo3Init = { 1 , 3 , 5 , 3 , 5 , 41 , 111 , 129 , 159 , 363 , 1109 , 1547 , 1209 , 15035 , 17367 ,0 }; - static ulong[] dim3374Kuo3Init = { 1 , 1 , 7 , 13 , 23 , 51 , 55 , 129 , 435 , 671 , 947 , 349 , 1741 , 15317 , 28069 ,0 }; - static ulong[] dim3375Kuo3Init = { 1 , 3 , 5 , 7 , 13 , 9 , 17 , 111 , 309 , 987 , 1521 , 1243 , 1815 , 10055 , 4883 ,0 }; - static ulong[] dim3376Kuo3Init = { 1 , 1 , 5 , 5 , 21 , 9 , 19 , 179 , 315 , 547 , 1899 , 1421 , 589 , 2563 , 27523 ,0 }; - static ulong[] dim3377Kuo3Init = { 1 , 1 , 5 , 11 , 25 , 23 , 115 , 229 , 439 , 225 , 1957 , 3251 , 4377 , 12751 , 2983 ,0 }; - static ulong[] dim3378Kuo3Init = { 1 , 3 , 1 , 3 , 21 , 23 , 57 , 187 , 469 , 575 , 1587 , 1983 , 4353 , 8605 , 27269 ,0 }; - static ulong[] dim3379Kuo3Init = { 1 , 3 , 5 , 15 , 11 , 17 , 51 , 131 , 93 , 599 , 487 , 3397 , 761 , 11503 , 13405 ,0 }; - static ulong[] dim3380Kuo3Init = { 1 , 3 , 1 , 15 , 27 , 7 , 13 , 105 , 189 , 141 , 715 , 1571 , 8103 , 3233 , 10481 ,0 }; - static ulong[] dim3381Kuo3Init = { 1 , 1 , 7 , 3 , 21 , 17 , 103 , 121 , 229 , 865 , 1819 , 171 , 7281 , 14085 , 4483 ,0 }; - static ulong[] dim3382Kuo3Init = { 1 , 3 , 7 , 13 , 21 , 47 , 105 , 233 , 325 , 49 , 1305 , 2269 , 7717 , 2771 , 27583 ,0 }; - static ulong[] dim3383Kuo3Init = { 1 , 3 , 3 , 5 , 17 , 11 , 101 , 55 , 191 , 115 , 1749 , 3015 , 1493 , 15301 , 1629 ,0 }; - static ulong[] dim3384Kuo3Init = { 1 , 1 , 7 , 1 , 3 , 39 , 111 , 51 , 269 , 451 , 1327 , 3389 , 6461 , 7361 , 1311 ,0 }; - static ulong[] dim3385Kuo3Init = { 1 , 1 , 7 , 7 , 23 , 21 , 103 , 241 , 3 , 295 , 981 , 3969 , 1631 , 6301 , 9481 ,0 }; - static ulong[] dim3386Kuo3Init = { 1 , 3 , 7 , 3 , 17 , 63 , 49 , 163 , 89 , 183 , 555 , 597 , 3099 , 8057 , 28653 ,0 }; - static ulong[] dim3387Kuo3Init = { 1 , 1 , 7 , 15 , 9 , 29 , 35 , 255 , 173 , 295 , 2015 , 283 , 1179 , 1677 , 26417 ,0 }; - static ulong[] dim3388Kuo3Init = { 1 , 3 , 1 , 5 , 11 , 29 , 73 , 67 , 5 , 995 , 1563 , 2611 , 7605 , 13831 , 7405 ,0 }; - static ulong[] dim3389Kuo3Init = { 1 , 3 , 3 , 1 , 1 , 27 , 7 , 251 , 175 , 683 , 603 , 2895 , 6033 , 4133 , 2753 ,0 }; - static ulong[] dim3390Kuo3Init = { 1 , 1 , 7 , 15 , 23 , 47 , 45 , 179 , 289 , 317 , 1111 , 1241 , 7221 , 8661 , 31853 ,0 }; - static ulong[] dim3391Kuo3Init = { 1 , 1 , 3 , 15 , 19 , 19 , 35 , 139 , 145 , 469 , 1455 , 2335 , 8009 , 6609 , 14847 ,0 }; - static ulong[] dim3392Kuo3Init = { 1 , 1 , 7 , 11 , 17 , 59 , 115 , 71 , 197 , 143 , 1791 , 3515 , 3443 , 5065 , 22885 ,0 }; - static ulong[] dim3393Kuo3Init = { 1 , 3 , 7 , 11 , 25 , 19 , 47 , 223 , 469 , 745 , 107 , 2801 , 6279 , 16311 , 15699 ,0 }; - static ulong[] dim3394Kuo3Init = { 1 , 1 , 1 , 5 , 29 , 47 , 21 , 227 , 219 , 331 , 1179 , 3409 , 1787 , 9113 , 8359 ,0 }; - static ulong[] dim3395Kuo3Init = { 1 , 3 , 7 , 3 , 7 , 29 , 43 , 135 , 137 , 203 , 241 , 2421 , 3125 , 3883 , 23519 ,0 }; - static ulong[] dim3396Kuo3Init = { 1 , 3 , 5 , 3 , 3 , 63 , 5 , 5 , 425 , 863 , 1483 , 4049 , 2505 , 3173 , 3021 ,0 }; - static ulong[] dim3397Kuo3Init = { 1 , 1 , 1 , 1 , 31 , 11 , 37 , 133 , 349 , 33 , 1617 , 7 , 4945 , 8143 , 22027 ,0 }; - static ulong[] dim3398Kuo3Init = { 1 , 3 , 7 , 9 , 13 , 61 , 61 , 111 , 203 , 255 , 1107 , 425 , 4571 , 1537 , 2547 ,0 }; - static ulong[] dim3399Kuo3Init = { 1 , 3 , 1 , 13 , 19 , 35 , 5 , 99 , 33 , 271 , 203 , 545 , 1917 , 8645 , 30737 ,0 }; - static ulong[] dim3400Kuo3Init = { 1 , 1 , 5 , 1 , 31 , 33 , 125 , 119 , 475 , 497 , 1341 , 593 , 3497 , 2191 , 28715 ,0 }; - static ulong[] dim3401Kuo3Init = { 1 , 1 , 7 , 15 , 17 , 57 , 87 , 101 , 487 , 659 , 497 , 1243 , 3353 , 4803 , 11445 ,0 }; - static ulong[] dim3402Kuo3Init = { 1 , 3 , 1 , 3 , 31 , 13 , 55 , 79 , 233 , 327 , 1825 , 245 , 2693 , 11761 , 21155 ,0 }; - static ulong[] dim3403Kuo3Init = { 1 , 3 , 7 , 7 , 21 , 1 , 15 , 183 , 113 , 871 , 251 , 3573 , 517 , 9973 , 28567 ,0 }; - static ulong[] dim3404Kuo3Init = { 1 , 1 , 1 , 11 , 23 , 53 , 47 , 143 , 435 , 107 , 1091 , 2139 , 5985 , 12541 , 9857 ,0 }; - static ulong[] dim3405Kuo3Init = { 1 , 3 , 3 , 13 , 23 , 47 , 125 , 95 , 333 , 13 , 285 , 1691 , 1899 , 5625 , 29883 ,0 }; - static ulong[] dim3406Kuo3Init = { 1 , 1 , 7 , 1 , 1 , 3 , 21 , 69 , 425 , 179 , 1815 , 2231 , 6257 , 1387 , 26423 ,0 }; - static ulong[] dim3407Kuo3Init = { 1 , 1 , 1 , 13 , 23 , 11 , 37 , 223 , 259 , 767 , 1521 , 2445 , 7725 , 2013 , 8365 ,0 }; - static ulong[] dim3408Kuo3Init = { 1 , 1 , 7 , 7 , 13 , 25 , 125 , 167 , 423 , 457 , 1793 , 4043 , 913 , 14917 , 4577 ,0 }; - static ulong[] dim3409Kuo3Init = { 1 , 3 , 5 , 11 , 13 , 49 , 95 , 145 , 251 , 305 , 1883 , 3717 , 7927 , 6635 , 9647 ,0 }; - static ulong[] dim3410Kuo3Init = { 1 , 3 , 1 , 1 , 31 , 33 , 87 , 189 , 499 , 933 , 115 , 3407 , 1517 , 157 , 11815 ,0 }; - static ulong[] dim3411Kuo3Init = { 1 , 1 , 7 , 7 , 15 , 1 , 7 , 155 , 493 , 413 , 231 , 69 , 3433 , 13471 , 26705 ,0 }; - static ulong[] dim3412Kuo3Init = { 1 , 3 , 7 , 15 , 3 , 59 , 21 , 81 , 309 , 445 , 1467 , 2655 , 4871 , 1667 , 24557 ,0 }; - static ulong[] dim3413Kuo3Init = { 1 , 3 , 3 , 15 , 11 , 25 , 73 , 181 , 355 , 887 , 967 , 1131 , 5137 , 12695 , 8561 ,0 }; - static ulong[] dim3414Kuo3Init = { 1 , 3 , 3 , 11 , 27 , 51 , 19 , 95 , 165 , 991 , 2039 , 3269 , 2839 , 12065 , 26791 ,0 }; - static ulong[] dim3415Kuo3Init = { 1 , 1 , 5 , 15 , 29 , 15 , 47 , 89 , 251 , 149 , 7 , 447 , 1945 , 157 , 3865 ,0 }; - static ulong[] dim3416Kuo3Init = { 1 , 1 , 5 , 15 , 27 , 33 , 99 , 211 , 481 , 95 , 1361 , 2933 , 509 , 16383 , 11581 ,0 }; - static ulong[] dim3417Kuo3Init = { 1 , 1 , 3 , 1 , 29 , 43 , 103 , 141 , 117 , 505 , 733 , 2719 , 2281 , 4753 , 27511 ,0 }; - static ulong[] dim3418Kuo3Init = { 1 , 3 , 1 , 15 , 5 , 15 , 25 , 87 , 255 , 819 , 1589 , 2623 , 2043 , 7735 , 7813 ,0 }; - static ulong[] dim3419Kuo3Init = { 1 , 1 , 5 , 15 , 23 , 57 , 125 , 145 , 387 , 729 , 1845 , 2809 , 8067 , 3487 , 19919 ,0 }; - static ulong[] dim3420Kuo3Init = { 1 , 3 , 3 , 5 , 17 , 59 , 45 , 11 , 15 , 505 , 1859 , 2193 , 4581 , 15553 , 767 ,0 }; - static ulong[] dim3421Kuo3Init = { 1 , 1 , 1 , 3 , 27 , 47 , 95 , 147 , 493 , 259 , 759 , 4013 , 5611 , 1379 , 13017 ,0 }; - static ulong[] dim3422Kuo3Init = { 1 , 3 , 3 , 9 , 13 , 3 , 7 , 193 , 203 , 379 , 1445 , 1599 , 5915 , 6025 , 8037 ,0 }; - static ulong[] dim3423Kuo3Init = { 1 , 3 , 7 , 5 , 7 , 33 , 77 , 5 , 449 , 509 , 1409 , 2711 , 5603 , 9343 , 10613 ,0 }; - static ulong[] dim3424Kuo3Init = { 1 , 3 , 5 , 1 , 31 , 19 , 65 , 169 , 429 , 951 , 1659 , 3045 , 735 , 5089 , 27215 ,0 }; - static ulong[] dim3425Kuo3Init = { 1 , 1 , 7 , 1 , 13 , 43 , 73 , 67 , 449 , 357 , 285 , 2291 , 3493 , 1575 , 9281 ,0 }; - static ulong[] dim3426Kuo3Init = { 1 , 3 , 7 , 13 , 7 , 59 , 15 , 119 , 479 , 523 , 201 , 1381 , 3245 , 15591 , 18785 ,0 }; - static ulong[] dim3427Kuo3Init = { 1 , 3 , 1 , 13 , 13 , 13 , 29 , 105 , 65 , 231 , 161 , 375 , 3725 , 5097 , 23183 ,0 }; - static ulong[] dim3428Kuo3Init = { 1 , 3 , 5 , 7 , 7 , 21 , 103 , 155 , 357 , 661 , 1035 , 2421 , 5989 , 14613 , 11499 ,0 }; - static ulong[] dim3429Kuo3Init = { 1 , 3 , 3 , 3 , 13 , 7 , 45 , 221 , 189 , 405 , 1845 , 3791 , 2989 , 495 , 13899 ,0 }; - static ulong[] dim3430Kuo3Init = { 1 , 3 , 7 , 15 , 27 , 23 , 91 , 39 , 385 , 59 , 1367 , 3177 , 1945 , 15335 , 7543 ,0 }; - static ulong[] dim3431Kuo3Init = { 1 , 3 , 1 , 5 , 25 , 49 , 43 , 215 , 7 , 1003 , 831 , 611 , 183 , 4627 , 29423 ,0 }; - static ulong[] dim3432Kuo3Init = { 1 , 1 , 3 , 9 , 29 , 15 , 57 , 7 , 259 , 543 , 1313 , 449 , 2497 , 4337 , 20879 ,0 }; - static ulong[] dim3433Kuo3Init = { 1 , 3 , 1 , 3 , 17 , 23 , 111 , 99 , 185 , 183 , 1215 , 1775 , 8129 , 4487 , 7927 ,0 }; - static ulong[] dim3434Kuo3Init = { 1 , 1 , 1 , 1 , 21 , 23 , 55 , 195 , 219 , 595 , 703 , 97 , 7599 , 15673 , 25677 ,0 }; - static ulong[] dim3435Kuo3Init = { 1 , 3 , 1 , 11 , 19 , 11 , 121 , 145 , 237 , 719 , 201 , 1335 , 5147 , 2195 , 22909 ,0 }; - static ulong[] dim3436Kuo3Init = { 1 , 1 , 3 , 11 , 27 , 27 , 45 , 185 , 251 , 329 , 1253 , 1071 , 2097 , 9669 , 2999 ,0 }; - static ulong[] dim3437Kuo3Init = { 1 , 3 , 3 , 11 , 27 , 35 , 91 , 183 , 161 , 393 , 1269 , 1945 , 727 , 9985 , 9275 ,0 }; - static ulong[] dim3438Kuo3Init = { 1 , 1 , 1 , 9 , 15 , 43 , 109 , 25 , 431 , 641 , 1291 , 1169 , 649 , 16145 , 27663 ,0 }; - static ulong[] dim3439Kuo3Init = { 1 , 3 , 5 , 5 , 11 , 59 , 77 , 193 , 59 , 325 , 531 , 365 , 7285 , 5111 , 26647 ,0 }; - static ulong[] dim3440Kuo3Init = { 1 , 1 , 3 , 9 , 15 , 1 , 33 , 51 , 427 , 513 , 575 , 3739 , 4593 , 6669 , 25369 ,0 }; - static ulong[] dim3441Kuo3Init = { 1 , 3 , 1 , 13 , 5 , 31 , 109 , 155 , 83 , 405 , 657 , 1095 , 5087 , 13835 , 30395 ,0 }; - static ulong[] dim3442Kuo3Init = { 1 , 3 , 7 , 9 , 11 , 21 , 115 , 129 , 389 , 25 , 657 , 3455 , 1357 , 1501 , 10589 ,0 }; - static ulong[] dim3443Kuo3Init = { 1 , 3 , 5 , 9 , 29 , 21 , 67 , 153 , 197 , 703 , 123 , 1645 , 2175 , 5581 , 26465 ,0 }; - static ulong[] dim3444Kuo3Init = { 1 , 1 , 7 , 11 , 1 , 21 , 79 , 71 , 49 , 719 , 909 , 3783 , 5081 , 13235 , 19387 ,0 }; - static ulong[] dim3445Kuo3Init = { 1 , 1 , 1 , 5 , 11 , 47 , 93 , 213 , 305 , 673 , 191 , 2787 , 3293 , 6721 , 19105 ,0 }; - static ulong[] dim3446Kuo3Init = { 1 , 1 , 5 , 15 , 19 , 1 , 127 , 189 , 25 , 201 , 1867 , 3541 , 3215 , 14025 , 15823 ,0 }; - static ulong[] dim3447Kuo3Init = { 1 , 1 , 7 , 5 , 9 , 43 , 75 , 129 , 335 , 73 , 995 , 15 , 4423 , 6817 , 14311 ,0 }; - static ulong[] dim3448Kuo3Init = { 1 , 3 , 3 , 7 , 13 , 53 , 97 , 29 , 311 , 749 , 1025 , 5 , 6001 , 6831 , 24699 ,0 }; - static ulong[] dim3449Kuo3Init = { 1 , 3 , 7 , 3 , 29 , 21 , 117 , 245 , 389 , 785 , 405 , 1455 , 4249 , 9663 , 30027 ,0 }; - static ulong[] dim3450Kuo3Init = { 1 , 1 , 5 , 13 , 13 , 27 , 113 , 221 , 293 , 583 , 1329 , 3387 , 4233 , 11511 , 30005 ,0 }; - static ulong[] dim3451Kuo3Init = { 1 , 3 , 1 , 11 , 11 , 59 , 85 , 23 , 435 , 769 , 889 , 2993 , 8075 , 10831 , 23109 ,0 }; - static ulong[] dim3452Kuo3Init = { 1 , 1 , 7 , 13 , 31 , 9 , 59 , 247 , 387 , 27 , 791 , 1381 , 1881 , 15223 , 29481 ,0 }; - static ulong[] dim3453Kuo3Init = { 1 , 1 , 7 , 7 , 1 , 39 , 93 , 67 , 293 , 777 , 1463 , 1363 , 3159 , 6569 , 18361 ,0 }; - static ulong[] dim3454Kuo3Init = { 1 , 3 , 1 , 11 , 25 , 31 , 49 , 133 , 459 , 399 , 593 , 3907 , 701 , 9321 , 28589 ,0 }; - static ulong[] dim3455Kuo3Init = { 1 , 1 , 7 , 5 , 7 , 35 , 85 , 247 , 247 , 577 , 245 , 1615 , 337 , 11289 , 32149 ,0 }; - static ulong[] dim3456Kuo3Init = { 1 , 3 , 5 , 7 , 21 , 35 , 67 , 37 , 77 , 395 , 907 , 595 , 883 , 14931 , 21875 ,0 }; - static ulong[] dim3457Kuo3Init = { 1 , 1 , 1 , 9 , 5 , 25 , 1 , 69 , 307 , 419 , 1875 , 3075 , 15 , 5853 , 3177 ,0 }; - static ulong[] dim3458Kuo3Init = { 1 , 1 , 3 , 1 , 15 , 7 , 15 , 17 , 67 , 577 , 1525 , 1847 , 481 , 15451 , 21229 ,0 }; - static ulong[] dim3459Kuo3Init = { 1 , 1 , 1 , 11 , 23 , 35 , 79 , 179 , 397 , 403 , 1935 , 3371 , 3511 , 13593 , 30241 ,0 }; - static ulong[] dim3460Kuo3Init = { 1 , 3 , 5 , 3 , 13 , 11 , 79 , 215 , 409 , 577 , 1301 , 451 , 5171 , 1555 , 18445 ,0 }; - static ulong[] dim3461Kuo3Init = { 1 , 3 , 3 , 13 , 25 , 35 , 71 , 65 , 371 , 667 , 247 , 3815 , 4383 , 6429 , 4667 ,0 }; - static ulong[] dim3462Kuo3Init = { 1 , 1 , 3 , 1 , 17 , 45 , 115 , 217 , 353 , 501 , 1087 , 1521 , 2621 , 4847 , 12647 ,0 }; - static ulong[] dim3463Kuo3Init = { 1 , 1 , 7 , 7 , 5 , 25 , 75 , 33 , 421 , 39 , 1857 , 2189 , 2383 , 4401 , 11737 ,0 }; - static ulong[] dim3464Kuo3Init = { 1 , 1 , 7 , 7 , 7 , 23 , 123 , 155 , 343 , 85 , 879 , 595 , 6419 , 3789 , 31233 ,0 }; - static ulong[] dim3465Kuo3Init = { 1 , 1 , 7 , 5 , 29 , 55 , 75 , 203 , 319 , 465 , 1903 , 595 , 8127 , 9773 , 4083 ,0 }; - static ulong[] dim3466Kuo3Init = { 1 , 3 , 7 , 11 , 27 , 31 , 55 , 147 , 17 , 893 , 33 , 3239 , 1773 , 2111 , 19833 ,0 }; - static ulong[] dim3467Kuo3Init = { 1 , 3 , 7 , 5 , 27 , 39 , 3 , 131 , 401 , 843 , 1229 , 227 , 5221 , 5845 , 29029 ,0 }; - static ulong[] dim3468Kuo3Init = { 1 , 1 , 5 , 13 , 15 , 47 , 113 , 11 , 361 , 95 , 1303 , 333 , 5139 , 8393 , 2225 ,0 }; - static ulong[] dim3469Kuo3Init = { 1 , 3 , 5 , 11 , 27 , 53 , 45 , 111 , 377 , 41 , 985 , 931 , 3901 , 13921 , 25305 ,0 }; - static ulong[] dim3470Kuo3Init = { 1 , 3 , 7 , 3 , 23 , 23 , 95 , 227 , 207 , 71 , 525 , 3843 , 6025 , 16335 , 30519 ,0 }; - static ulong[] dim3471Kuo3Init = { 1 , 3 , 5 , 1 , 9 , 55 , 95 , 69 , 457 , 823 , 479 , 4073 , 3227 , 1355 , 12937 ,0 }; - static ulong[] dim3472Kuo3Init = { 1 , 1 , 1 , 5 , 7 , 17 , 67 , 143 , 189 , 79 , 653 , 2791 , 1193 , 9409 , 3561 ,0 }; - static ulong[] dim3473Kuo3Init = { 1 , 1 , 1 , 5 , 29 , 53 , 67 , 253 , 471 , 649 , 669 , 1621 , 1199 , 12889 , 27943 ,0 }; - static ulong[] dim3474Kuo3Init = { 1 , 1 , 3 , 11 , 15 , 3 , 93 , 33 , 335 , 899 , 1897 , 1689 , 2753 , 473 , 21935 ,0 }; - static ulong[] dim3475Kuo3Init = { 1 , 1 , 7 , 7 , 27 , 29 , 17 , 167 , 467 , 261 , 671 , 2449 , 7433 , 5669 , 77 ,0 }; - static ulong[] dim3476Kuo3Init = { 1 , 1 , 7 , 9 , 5 , 37 , 85 , 103 , 19 , 971 , 1851 , 231 , 7897 , 1783 , 12659 ,0 }; - static ulong[] dim3477Kuo3Init = { 1 , 3 , 7 , 7 , 17 , 57 , 1 , 7 , 491 , 887 , 341 , 3859 , 2783 , 9547 , 26867 ,0 }; - static ulong[] dim3478Kuo3Init = { 1 , 1 , 1 , 3 , 29 , 45 , 77 , 219 , 131 , 573 , 1015 , 765 , 6211 , 3243 , 32547 ,0 }; - static ulong[] dim3479Kuo3Init = { 1 , 3 , 1 , 5 , 19 , 51 , 61 , 27 , 415 , 125 , 69 , 2151 , 3385 , 1405 , 25509 ,0 }; - static ulong[] dim3480Kuo3Init = { 1 , 3 , 1 , 3 , 23 , 17 , 19 , 35 , 489 , 869 , 687 , 1047 , 6031 , 589 , 3611 ,0 }; - static ulong[] dim3481Kuo3Init = { 1 , 3 , 5 , 15 , 19 , 27 , 47 , 175 , 23 , 427 , 137 , 2733 , 1795 , 483 , 11083 ,0 }; - static ulong[] dim3482Kuo3Init = { 1 , 1 , 1 , 1 , 23 , 41 , 93 , 229 , 407 , 751 , 635 , 3125 , 831 , 2121 , 8463 ,0 }; - static ulong[] dim3483Kuo3Init = { 1 , 3 , 5 , 11 , 27 , 61 , 27 , 21 , 337 , 33 , 1373 , 37 , 89 , 7527 , 21165 ,0 }; - static ulong[] dim3484Kuo3Init = { 1 , 1 , 5 , 9 , 25 , 55 , 51 , 111 , 497 , 737 , 1097 , 165 , 7879 , 1509 , 5025 ,0 }; - static ulong[] dim3485Kuo3Init = { 1 , 3 , 5 , 11 , 3 , 51 , 61 , 19 , 75 , 1001 , 1535 , 2689 , 2903 , 9675 , 22209 ,0 }; - static ulong[] dim3486Kuo3Init = { 1 , 1 , 3 , 13 , 27 , 7 , 89 , 219 , 459 , 403 , 1963 , 979 , 3987 , 4165 , 5027 ,0 }; - static ulong[] dim3487Kuo3Init = { 1 , 1 , 1 , 13 , 15 , 51 , 113 , 37 , 105 , 57 , 589 , 3583 , 7205 , 107 , 29687 ,0 }; - static ulong[] dim3488Kuo3Init = { 1 , 1 , 7 , 7 , 1 , 57 , 125 , 131 , 265 , 957 , 461 , 1413 , 3961 , 10543 , 14951 ,0 }; - static ulong[] dim3489Kuo3Init = { 1 , 1 , 7 , 13 , 19 , 53 , 125 , 41 , 417 , 629 , 153 , 2531 , 5655 , 1919 , 14615 ,0 }; - static ulong[] dim3490Kuo3Init = { 1 , 1 , 7 , 1 , 1 , 21 , 19 , 123 , 3 , 601 , 1781 , 2237 , 705 , 14229 , 6739 ,0 }; - static ulong[] dim3491Kuo3Init = { 1 , 3 , 5 , 5 , 3 , 3 , 23 , 71 , 225 , 507 , 619 , 493 , 5917 , 1145 , 7303 ,0 }; - static ulong[] dim3492Kuo3Init = { 1 , 1 , 1 , 13 , 3 , 19 , 89 , 237 , 497 , 3 , 91 , 2559 , 6347 , 8925 , 9845 ,0 }; - static ulong[] dim3493Kuo3Init = { 1 , 3 , 5 , 7 , 11 , 47 , 85 , 147 , 339 , 499 , 511 , 731 , 3063 , 5363 , 19841 ,0 }; - static ulong[] dim3494Kuo3Init = { 1 , 3 , 7 , 7 , 19 , 41 , 105 , 225 , 37 , 181 , 127 , 2167 , 4247 , 915 , 14507 ,0 }; - static ulong[] dim3495Kuo3Init = { 1 , 1 , 5 , 11 , 31 , 7 , 23 , 229 , 165 , 485 , 693 , 3279 , 7407 , 9883 , 31803 ,0 }; - static ulong[] dim3496Kuo3Init = { 1 , 3 , 5 , 9 , 15 , 33 , 1 , 99 , 79 , 589 , 411 , 2783 , 3437 , 2151 , 11585 ,0 }; - static ulong[] dim3497Kuo3Init = { 1 , 3 , 1 , 5 , 25 , 15 , 95 , 221 , 399 , 793 , 617 , 2431 , 6859 , 2893 , 8919 ,0 }; - static ulong[] dim3498Kuo3Init = { 1 , 3 , 1 , 11 , 21 , 57 , 127 , 1 , 81 , 657 , 1935 , 1937 , 1635 , 4079 , 6677 ,0 }; - static ulong[] dim3499Kuo3Init = { 1 , 1 , 5 , 1 , 17 , 7 , 19 , 167 , 483 , 53 , 49 , 1187 , 789 , 1787 , 4103 ,0 }; - static ulong[] dim3500Kuo3Init = { 1 , 3 , 5 , 15 , 11 , 1 , 83 , 223 , 289 , 119 , 1263 , 2995 , 5697 , 5835 , 7127 ,0 }; - static ulong[] dim3501Kuo3Init = { 1 , 3 , 7 , 13 , 1 , 25 , 59 , 59 , 223 , 309 , 1133 , 773 , 8171 , 12881 , 21959 ,0 }; - static ulong[] dim3502Kuo3Init = { 1 , 3 , 7 , 15 , 7 , 43 , 63 , 99 , 503 , 527 , 1915 , 1147 , 2729 , 8311 , 13451 ,0 }; - static ulong[] dim3503Kuo3Init = { 1 , 1 , 1 , 7 , 25 , 37 , 61 , 41 , 25 , 681 , 1029 , 1715 , 63 , 6913 , 31299 ,0 }; - static ulong[] dim3504Kuo3Init = { 1 , 3 , 5 , 13 , 29 , 41 , 25 , 135 , 241 , 331 , 51 , 2305 , 5149 , 12295 , 8891 ,0 }; - static ulong[] dim3505Kuo3Init = { 1 , 1 , 3 , 7 , 7 , 53 , 25 , 127 , 227 , 711 , 1165 , 2563 , 2681 , 1331 , 8435 ,0 }; - static ulong[] dim3506Kuo3Init = { 1 , 3 , 3 , 15 , 29 , 43 , 27 , 105 , 371 , 691 , 77 , 1847 , 6097 , 1253 , 1163 ,0 }; - static ulong[] dim3507Kuo3Init = { 1 , 3 , 5 , 1 , 23 , 43 , 23 , 185 , 287 , 407 , 1523 , 1923 , 2121 , 3297 , 21549 ,0 }; - static ulong[] dim3508Kuo3Init = { 1 , 3 , 7 , 15 , 31 , 45 , 19 , 85 , 323 , 837 , 99 , 581 , 6607 , 3685 , 21853 ,0 }; - static ulong[] dim3509Kuo3Init = { 1 , 1 , 3 , 3 , 31 , 27 , 107 , 55 , 79 , 339 , 1739 , 2373 , 6393 , 6557 , 20651 ,0 }; - static ulong[] dim3510Kuo3Init = { 1 , 3 , 1 , 11 , 7 , 23 , 63 , 43 , 237 , 753 , 1347 , 1775 , 6663 , 2907 , 2905 ,0 }; - static ulong[] dim3511Kuo3Init = { 1 , 1 , 5 , 5 , 1 , 3 , 99 , 135 , 247 , 249 , 757 , 619 , 3497 , 2421 , 6601 ,0 }; - static ulong[] dim3512Kuo3Init = { 1 , 3 , 1 , 7 , 5 , 61 , 91 , 151 , 283 , 723 , 1931 , 3799 , 2737 , 14833 , 2363 ,0 }; - static ulong[] dim3513Kuo3Init = { 1 , 1 , 3 , 1 , 9 , 15 , 53 , 233 , 365 , 323 , 1141 , 3523 , 7771 , 707 , 1837 ,0 }; - static ulong[] dim3514Kuo3Init = { 1 , 1 , 1 , 7 , 11 , 43 , 87 , 63 , 425 , 149 , 1121 , 4051 , 5391 , 591 , 19849 ,0 }; - static ulong[] dim3515Kuo3Init = { 1 , 1 , 1 , 5 , 15 , 39 , 55 , 233 , 401 , 337 , 289 , 693 , 3659 , 10381 , 25723 ,0 }; - static ulong[] dim3516Kuo3Init = { 1 , 1 , 7 , 11 , 3 , 11 , 55 , 89 , 293 , 235 , 893 , 853 , 1281 , 13845 , 7123 ,0 }; - static ulong[] dim3517Kuo3Init = { 1 , 1 , 7 , 15 , 11 , 1 , 41 , 187 , 297 , 557 , 1951 , 4007 , 2429 , 493 , 31645 ,0 }; - static ulong[] dim3518Kuo3Init = { 1 , 1 , 1 , 1 , 31 , 39 , 113 , 3 , 11 , 217 , 1841 , 545 , 1953 , 1667 , 28317 ,0 }; - static ulong[] dim3519Kuo3Init = { 1 , 1 , 3 , 7 , 31 , 31 , 125 , 217 , 127 , 561 , 983 , 3651 , 6649 , 11859 , 3887 ,0 }; - static ulong[] dim3520Kuo3Init = { 1 , 1 , 1 , 3 , 17 , 51 , 107 , 25 , 511 , 777 , 771 , 2359 , 275 , 16351 , 15639 ,0 }; - static ulong[] dim3521Kuo3Init = { 1 , 3 , 5 , 1 , 11 , 13 , 9 , 167 , 505 , 667 , 155 , 2857 , 4043 , 12145 , 3369 ,0 }; - static ulong[] dim3522Kuo3Init = { 1 , 3 , 7 , 1 , 15 , 33 , 83 , 217 , 333 , 847 , 679 , 3981 , 925 , 3465 , 1217 ,0 }; - static ulong[] dim3523Kuo3Init = { 1 , 1 , 3 , 7 , 13 , 55 , 111 , 101 , 455 , 929 , 1755 , 2177 , 931 , 8083 , 1207 ,0 }; - static ulong[] dim3524Kuo3Init = { 1 , 1 , 1 , 3 , 21 , 29 , 25 , 213 , 113 , 51 , 1913 , 1131 , 1981 , 16221 , 32569 ,0 }; - static ulong[] dim3525Kuo3Init = { 1 , 1 , 3 , 13 , 13 , 9 , 105 , 153 , 317 , 755 , 363 , 2833 , 4463 , 2607 , 17587 ,0 }; - static ulong[] dim3526Kuo3Init = { 1 , 1 , 5 , 1 , 7 , 15 , 71 , 133 , 141 , 639 , 273 , 1445 , 4571 , 13313 , 319 ,0 }; - static ulong[] dim3527Kuo3Init = { 1 , 1 , 5 , 9 , 23 , 17 , 55 , 49 , 159 , 713 , 1127 , 2537 , 4927 , 4389 , 8361 ,0 }; - static ulong[] dim3528Kuo3Init = { 1 , 3 , 3 , 1 , 31 , 23 , 35 , 237 , 7 , 801 , 1939 , 2243 , 3891 , 12379 , 251 ,0 }; - static ulong[] dim3529Kuo3Init = { 1 , 1 , 7 , 15 , 17 , 11 , 33 , 89 , 39 , 87 , 1963 , 1591 , 7775 , 5091 , 23503 ,0 }; - static ulong[] dim3530Kuo3Init = { 1 , 1 , 7 , 1 , 31 , 63 , 93 , 55 , 197 , 627 , 1887 , 899 , 2491 , 7713 , 9921 ,0 }; - static ulong[] dim3531Kuo3Init = { 1 , 1 , 3 , 11 , 27 , 17 , 27 , 33 , 413 , 131 , 1713 , 615 , 1775 , 237 , 2775 ,0 }; - static ulong[] dim3532Kuo3Init = { 1 , 3 , 5 , 9 , 23 , 3 , 83 , 69 , 113 , 311 , 1199 , 2593 , 3745 , 14473 , 727 ,0 }; - static ulong[] dim3533Kuo3Init = { 1 , 3 , 3 , 3 , 3 , 57 , 111 , 195 , 303 , 713 , 1305 , 955 , 7415 , 15625 , 6491 ,0 }; - static ulong[] dim3534Kuo3Init = { 1 , 3 , 1 , 15 , 25 , 37 , 3 , 149 , 7 , 923 , 1367 , 3743 , 5887 , 5683 , 17437 ,0 }; - static ulong[] dim3535Kuo3Init = { 1 , 3 , 3 , 7 , 5 , 33 , 85 , 149 , 339 , 223 , 1359 , 1881 , 4383 , 8949 , 1331 ,0 }; - static ulong[] dim3536Kuo3Init = { 1 , 1 , 3 , 15 , 21 , 27 , 85 , 209 , 205 , 597 , 655 , 2759 , 109 , 4963 , 13055 ,0 }; - static ulong[] dim3537Kuo3Init = { 1 , 3 , 1 , 1 , 3 , 29 , 99 , 15 , 399 , 233 , 1697 , 2613 , 1819 , 9059 , 10329 ,0 }; - static ulong[] dim3538Kuo3Init = { 1 , 1 , 5 , 1 , 19 , 13 , 69 , 87 , 451 , 389 , 1065 , 665 , 7217 , 12907 , 32423 ,0 }; - static ulong[] dim3539Kuo3Init = { 1 , 1 , 3 , 11 , 23 , 57 , 127 , 107 , 181 , 231 , 1233 , 1593 , 6365 , 13919 , 29379 ,0 }; - static ulong[] dim3540Kuo3Init = { 1 , 1 , 7 , 13 , 29 , 43 , 11 , 119 , 165 , 835 , 323 , 3051 , 3641 , 13841 , 26399 ,0 }; - static ulong[] dim3541Kuo3Init = { 1 , 1 , 7 , 5 , 15 , 27 , 41 , 97 , 317 , 565 , 1589 , 2091 , 1213 , 12143 , 26777 ,0 }; - static ulong[] dim3542Kuo3Init = { 1 , 3 , 7 , 13 , 3 , 17 , 65 , 221 , 183 , 265 , 363 , 1013 , 7269 , 13731 , 25029 ,0 }; - static ulong[] dim3543Kuo3Init = { 1 , 1 , 3 , 3 , 13 , 13 , 123 , 59 , 193 , 95 , 1909 , 1701 , 6123 , 5599 , 17805 ,0 }; - static ulong[] dim3544Kuo3Init = { 1 , 1 , 1 , 1 , 3 , 51 , 1 , 155 , 59 , 199 , 1751 , 813 , 441 , 5615 , 28115 ,0 }; - static ulong[] dim3545Kuo3Init = { 1 , 1 , 5 , 3 , 13 , 33 , 37 , 245 , 343 , 21 , 1083 , 2177 , 4593 , 13995 , 12465 ,0 }; - static ulong[] dim3546Kuo3Init = { 1 , 1 , 7 , 3 , 21 , 57 , 31 , 65 , 15 , 427 , 981 , 1047 , 7731 , 763 , 26335 ,0 }; - static ulong[] dim3547Kuo3Init = { 1 , 3 , 3 , 11 , 1 , 15 , 19 , 207 , 127 , 623 , 949 , 663 , 2691 , 505 , 10667 ,0 }; - static ulong[] dim3548Kuo3Init = { 1 , 1 , 3 , 9 , 3 , 7 , 31 , 175 , 225 , 707 , 1393 , 1661 , 2761 , 4675 , 16195 ,0 }; - static ulong[] dim3549Kuo3Init = { 1 , 3 , 1 , 5 , 21 , 35 , 17 , 61 , 337 , 307 , 191 , 1077 , 7331 , 8965 , 18963 ,0 }; - static ulong[] dim3550Kuo3Init = { 1 , 3 , 3 , 7 , 23 , 53 , 37 , 95 , 229 , 125 , 813 , 2279 , 4915 , 10637 , 15533 ,0 }; - static ulong[] dim3551Kuo3Init = { 1 , 3 , 3 , 1 , 21 , 9 , 61 , 183 , 457 , 997 , 929 , 2245 , 6213 , 11179 , 1803 ,0 }; - static ulong[] dim3552Kuo3Init = { 1 , 1 , 5 , 15 , 11 , 63 , 21 , 235 , 259 , 161 , 1347 , 2807 , 3991 , 14205 , 26369 ,0 }; - static ulong[] dim3553Kuo3Init = { 1 , 1 , 7 , 5 , 13 , 3 , 33 , 237 , 473 , 167 , 1341 , 3617 , 3671 , 15041 , 29603 ,0 }; - static ulong[] dim3554Kuo3Init = { 1 , 1 , 5 , 9 , 17 , 1 , 105 , 169 , 25 , 825 , 1703 , 751 , 5461 , 13121 , 30917 ,0 }; - static ulong[] dim3555Kuo3Init = { 1 , 3 , 7 , 5 , 9 , 31 , 19 , 231 , 137 , 601 , 1177 , 327 , 3811 , 7553 , 13453 ,0 }; - static ulong[] dim3556Kuo3Init = { 1 , 1 , 7 , 7 , 7 , 43 , 7 , 231 , 171 , 695 , 331 , 1493 , 2437 , 12487 , 25451 ,0 }; - static ulong[] dim3557Kuo3Init = { 1 , 3 , 5 , 13 , 27 , 19 , 103 , 157 , 145 , 267 , 1417 , 3867 , 7477 , 15399 , 31311 ,0 }; - static ulong[] dim3558Kuo3Init = { 1 , 1 , 7 , 1 , 5 , 11 , 111 , 89 , 45 , 685 , 1283 , 2581 , 819 , 3675 , 25143 ,0 }; - static ulong[] dim3559Kuo3Init = { 1 , 1 , 1 , 5 , 31 , 5 , 85 , 143 , 113 , 693 , 529 , 321 , 5407 , 14411 , 27513 ,0 }; - static ulong[] dim3560Kuo3Init = { 1 , 1 , 1 , 9 , 19 , 5 , 103 , 79 , 439 , 327 , 1769 , 3371 , 7191 , 5827 , 10145 ,0 }; - static ulong[] dim3561Kuo3Init = { 1 , 3 , 1 , 15 , 1 , 3 , 63 , 57 , 331 , 525 , 239 , 307 , 4927 , 13525 , 26383 ,0 }; - static ulong[] dim3562Kuo3Init = { 1 , 1 , 1 , 11 , 11 , 31 , 49 , 137 , 407 , 335 , 905 , 3441 , 623 , 11301 , 8933 ,0 }; - static ulong[] dim3563Kuo3Init = { 1 , 3 , 7 , 13 , 29 , 59 , 41 , 143 , 103 , 255 , 1195 , 3033 , 6785 , 12717 , 5789 ,0 }; - static ulong[] dim3564Kuo3Init = { 1 , 3 , 7 , 5 , 11 , 3 , 107 , 121 , 173 , 481 , 3 , 1485 , 4557 , 11095 , 24611 ,0 }; - static ulong[] dim3565Kuo3Init = { 1 , 3 , 3 , 1 , 3 , 47 , 17 , 107 , 77 , 323 , 1349 , 2285 , 871 , 7301 , 27811 ,0 }; - static ulong[] dim3566Kuo3Init = { 1 , 3 , 3 , 13 , 9 , 49 , 95 , 53 , 337 , 323 , 1231 , 3825 , 7403 , 12851 , 31133 ,0 }; - static ulong[] dim3567Kuo3Init = { 1 , 3 , 1 , 1 , 29 , 59 , 123 , 239 , 251 , 513 , 259 , 529 , 1267 , 13323 , 15509 ,0 }; - static ulong[] dim3568Kuo3Init = { 1 , 1 , 1 , 7 , 25 , 61 , 91 , 75 , 83 , 575 , 671 , 2575 , 2871 , 11909 , 31371 ,0 }; - static ulong[] dim3569Kuo3Init = { 1 , 3 , 7 , 3 , 15 , 63 , 99 , 161 , 77 , 539 , 1069 , 1263 , 4173 , 12691 , 18091 ,0 }; - static ulong[] dim3570Kuo3Init = { 1 , 3 , 7 , 1 , 15 , 55 , 39 , 33 , 257 , 925 , 839 , 4091 , 2621 , 315 , 28153 ,0 }; - static ulong[] dim3571Kuo3Init = { 1 , 1 , 3 , 3 , 9 , 9 , 17 , 207 , 369 , 773 , 1661 , 3175 , 2367 , 6363 , 5363 ,0 }; - static ulong[] dim3572Kuo3Init = { 1 , 1 , 3 , 15 , 31 , 11 , 41 , 145 , 381 , 969 , 327 , 487 , 5545 , 16163 , 13891 ,0 }; - static ulong[] dim3573Kuo3Init = { 1 , 1 , 3 , 5 , 19 , 15 , 125 , 183 , 445 , 771 , 829 , 3653 , 7487 , 14429 , 14535 ,0 }; - static ulong[] dim3574Kuo3Init = { 1 , 1 , 1 , 13 , 5 , 55 , 41 , 171 , 163 , 677 , 1549 , 2769 , 3961 , 4051 , 25883 ,0 }; - static ulong[] dim3575Kuo3Init = { 1 , 3 , 5 , 5 , 15 , 5 , 121 , 113 , 423 , 607 , 1623 , 2899 , 7839 , 8107 , 13963 ,0 }; - static ulong[] dim3576Kuo3Init = { 1 , 1 , 7 , 11 , 17 , 55 , 85 , 139 , 93 , 453 , 75 , 2405 , 7601 , 15647 , 25349 ,0 }; - static ulong[] dim3577Kuo3Init = { 1 , 3 , 3 , 3 , 11 , 27 , 1 , 11 , 361 , 811 , 599 , 405 , 6981 , 5705 , 16427 ,0 }; - static ulong[] dim3578Kuo3Init = { 1 , 3 , 5 , 9 , 23 , 61 , 27 , 7 , 99 , 495 , 473 , 477 , 1733 , 8043 , 24843 ,0 }; - static ulong[] dim3579Kuo3Init = { 1 , 3 , 7 , 3 , 21 , 27 , 71 , 157 , 357 , 175 , 829 , 2411 , 2305 , 4669 , 24933 ,0 }; - static ulong[] dim3580Kuo3Init = { 1 , 3 , 5 , 9 , 21 , 13 , 121 , 123 , 119 , 59 , 429 , 3757 , 5833 , 11263 , 16013 ,0 }; - static ulong[] dim3581Kuo3Init = { 1 , 3 , 7 , 15 , 11 , 49 , 7 , 31 , 375 , 647 , 413 , 2979 , 7731 , 15953 , 13637 ,0 }; - static ulong[] dim3582Kuo3Init = { 1 , 1 , 1 , 7 , 9 , 59 , 121 , 115 , 239 , 739 , 121 , 791 , 769 , 14223 , 15127 ,0 }; - static ulong[] dim3583Kuo3Init = { 1 , 3 , 7 , 15 , 17 , 31 , 69 , 9 , 189 , 503 , 565 , 1373 , 6467 , 15291 , 20621 ,0 }; - static ulong[] dim3584Kuo3Init = { 1 , 1 , 5 , 13 , 31 , 13 , 71 , 15 , 197 , 855 , 1923 , 2923 , 2375 , 7201 , 29767 ,0 }; - static ulong[] dim3585Kuo3Init = { 1 , 1 , 7 , 7 , 17 , 13 , 53 , 131 , 447 , 337 , 1059 , 1365 , 1269 , 6035 , 32075 ,0 }; - static ulong[] dim3586Kuo3Init = { 1 , 3 , 5 , 1 , 15 , 13 , 43 , 151 , 207 , 591 , 717 , 971 , 5801 , 10975 , 3889 ,0 }; - static ulong[] dim3587Kuo3Init = { 1 , 3 , 5 , 7 , 15 , 45 , 125 , 193 , 17 , 605 , 651 , 1987 , 577 , 2835 , 6801 ,0 }; - static ulong[] dim3588Kuo3Init = { 1 , 3 , 5 , 7 , 31 , 53 , 83 , 137 , 399 , 781 , 135 , 2863 , 4901 , 2861 , 14025 ,0 }; - static ulong[] dim3589Kuo3Init = { 1 , 3 , 3 , 13 , 29 , 45 , 99 , 43 , 121 , 141 , 753 , 11 , 4033 , 2011 , 7493 ,0 }; - static ulong[] dim3590Kuo3Init = { 1 , 3 , 7 , 11 , 7 , 39 , 95 , 199 , 365 , 9 , 381 , 3923 , 3803 , 6607 , 30777 ,0 }; - static ulong[] dim3591Kuo3Init = { 1 , 3 , 5 , 13 , 13 , 49 , 17 , 25 , 195 , 269 , 83 , 2115 , 4013 , 8817 , 28017 ,0 }; - static ulong[] dim3592Kuo3Init = { 1 , 1 , 5 , 15 , 23 , 49 , 51 , 49 , 303 , 439 , 1353 , 2385 , 4547 , 14405 , 24115 ,0 }; - static ulong[] dim3593Kuo3Init = { 1 , 3 , 1 , 9 , 9 , 3 , 87 , 159 , 449 , 139 , 461 , 465 , 5585 , 9313 , 6337 ,0 }; - static ulong[] dim3594Kuo3Init = { 1 , 1 , 1 , 9 , 23 , 17 , 103 , 167 , 209 , 179 , 137 , 57 , 4265 , 1743 , 27575 ,0 }; - static ulong[] dim3595Kuo3Init = { 1 , 3 , 1 , 15 , 15 , 17 , 7 , 93 , 173 , 277 , 497 , 4047 , 2205 , 10403 , 6319 ,0 }; - static ulong[] dim3596Kuo3Init = { 1 , 3 , 1 , 9 , 13 , 55 , 37 , 153 , 69 , 989 , 1609 , 1939 , 1153 , 5671 , 16563 ,0 }; - static ulong[] dim3597Kuo3Init = { 1 , 1 , 3 , 15 , 3 , 41 , 67 , 41 , 253 , 293 , 1495 , 3935 , 271 , 12067 , 3891 ,0 }; - static ulong[] dim3598Kuo3Init = { 1 , 3 , 7 , 15 , 27 , 21 , 39 , 41 , 43 , 713 , 747 , 995 , 5389 , 9811 , 20489 ,0 }; - static ulong[] dim3599Kuo3Init = { 1 , 3 , 7 , 15 , 11 , 47 , 41 , 155 , 301 , 867 , 1467 , 1503 , 893 , 6819 , 6923 ,0 }; - static ulong[] dim3600Kuo3Init = { 1 , 1 , 1 , 11 , 29 , 15 , 57 , 25 , 219 , 65 , 997 , 2109 , 1921 , 1771 , 5997 ,0 }; - static ulong[] dim3601Kuo3Init = { 1 , 1 , 7 , 5 , 11 , 59 , 89 , 59 , 319 , 841 , 1 , 1339 , 5635 , 3141 , 8735 ,0 }; - static ulong[] dim3602Kuo3Init = { 1 , 3 , 3 , 3 , 17 , 25 , 13 , 201 , 37 , 561 , 1101 , 1407 , 3003 , 99 , 20189 ,0 }; - static ulong[] dim3603Kuo3Init = { 1 , 1 , 3 , 3 , 9 , 7 , 65 , 27 , 203 , 399 , 555 , 2605 , 7951 , 833 , 6103 ,0 }; - static ulong[] dim3604Kuo3Init = { 1 , 3 , 7 , 15 , 15 , 25 , 87 , 215 , 499 , 935 , 563 , 1091 , 6601 , 12097 , 22935 ,0 }; - static ulong[] dim3605Kuo3Init = { 1 , 3 , 5 , 9 , 3 , 21 , 63 , 51 , 353 , 187 , 1609 , 2321 , 1743 , 12665 , 9313 ,0 }; - static ulong[] dim3606Kuo3Init = { 1 , 1 , 3 , 13 , 21 , 7 , 101 , 27 , 15 , 467 , 833 , 2439 , 3559 , 10509 , 16327 ,0 }; - static ulong[] dim3607Kuo3Init = { 1 , 3 , 5 , 1 , 21 , 37 , 107 , 77 , 147 , 107 , 1493 , 969 , 7895 , 14293 , 14557 ,0 }; - static ulong[] dim3608Kuo3Init = { 1 , 1 , 3 , 13 , 1 , 13 , 57 , 183 , 303 , 93 , 1755 , 845 , 6857 , 11061 , 13661 ,0 }; - static ulong[] dim3609Kuo3Init = { 1 , 1 , 7 , 13 , 11 , 23 , 25 , 77 , 75 , 279 , 1375 , 1235 , 3225 , 8143 , 4055 ,0 }; - static ulong[] dim3610Kuo3Init = { 1 , 3 , 1 , 11 , 5 , 1 , 85 , 1 , 221 , 831 , 1673 , 633 , 4837 , 14409 , 28993 ,0 }; - static ulong[] dim3611Kuo3Init = { 1 , 1 , 7 , 7 , 23 , 33 , 51 , 181 , 201 , 947 , 697 , 3417 , 6169 , 757 , 9343 ,0 }; - static ulong[] dim3612Kuo3Init = { 1 , 1 , 3 , 11 , 21 , 51 , 45 , 81 , 447 , 17 , 789 , 3773 , 3647 , 5913 , 25419 ,0 }; - static ulong[] dim3613Kuo3Init = { 1 , 1 , 5 , 11 , 29 , 39 , 33 , 67 , 157 , 583 , 653 , 43 , 4441 , 9571 , 9895 ,0 }; - static ulong[] dim3614Kuo3Init = { 1 , 3 , 3 , 13 , 21 , 13 , 53 , 3 , 135 , 61 , 1975 , 2107 , 1395 , 11395 , 1741 ,0 }; - static ulong[] dim3615Kuo3Init = { 1 , 1 , 5 , 3 , 21 , 29 , 35 , 25 , 495 , 783 , 407 , 1765 , 1959 , 3975 , 23157 ,0 }; - static ulong[] dim3616Kuo3Init = { 1 , 1 , 7 , 7 , 1 , 57 , 107 , 73 , 483 , 945 , 73 , 2757 , 7211 , 1053 , 7625 ,0 }; - static ulong[] dim3617Kuo3Init = { 1 , 1 , 3 , 13 , 25 , 53 , 61 , 117 , 231 , 261 , 901 , 1823 , 3401 , 8399 , 17953 ,0 }; - static ulong[] dim3618Kuo3Init = { 1 , 1 , 7 , 15 , 29 , 13 , 55 , 51 , 469 , 457 , 1529 , 2381 , 6017 , 10953 , 18639 ,0 }; - static ulong[] dim3619Kuo3Init = { 1 , 1 , 1 , 9 , 21 , 17 , 45 , 1 , 457 , 821 , 367 , 453 , 1015 , 1017 , 21745 ,0 }; - static ulong[] dim3620Kuo3Init = { 1 , 3 , 1 , 9 , 15 , 21 , 121 , 149 , 417 , 287 , 897 , 2595 , 327 , 16157 , 11971 ,0 }; - static ulong[] dim3621Kuo3Init = { 1 , 3 , 7 , 15 , 17 , 29 , 41 , 191 , 475 , 457 , 1487 , 1885 , 6959 , 10869 , 7435 ,0 }; - static ulong[] dim3622Kuo3Init = { 1 , 1 , 5 , 3 , 9 , 57 , 29 , 41 , 81 , 179 , 1023 , 3683 , 4313 , 4849 , 14211 ,0 }; - static ulong[] dim3623Kuo3Init = { 1 , 3 , 1 , 15 , 15 , 3 , 123 , 5 , 201 , 387 , 1175 , 1285 , 4367 , 459 , 7771 ,0 }; - static ulong[] dim3624Kuo3Init = { 1 , 1 , 1 , 3 , 25 , 47 , 113 , 41 , 299 , 217 , 495 , 565 , 2337 , 9877 , 28731 ,0 }; - static ulong[] dim3625Kuo3Init = { 1 , 1 , 5 , 5 , 17 , 11 , 119 , 187 , 389 , 19 , 1947 , 2607 , 1119 , 7677 , 1561 ,0 }; - static ulong[] dim3626Kuo3Init = { 1 , 1 , 7 , 9 , 23 , 59 , 63 , 175 , 103 , 211 , 125 , 3465 , 2535 , 14899 , 1239 ,0 }; - static ulong[] dim3627Kuo3Init = { 1 , 1 , 3 , 11 , 17 , 37 , 111 , 225 , 51 , 455 , 1911 , 1579 , 841 , 11451 , 31521 ,0 }; - static ulong[] dim3628Kuo3Init = { 1 , 1 , 3 , 15 , 13 , 1 , 63 , 33 , 113 , 83 , 513 , 3903 , 5399 , 5855 , 11151 ,0 }; - static ulong[] dim3629Kuo3Init = { 1 , 3 , 7 , 7 , 1 , 15 , 55 , 181 , 453 , 15 , 333 , 185 , 2031 , 14809 , 6187 ,0 }; - static ulong[] dim3630Kuo3Init = { 1 , 1 , 5 , 13 , 27 , 37 , 41 , 197 , 191 , 365 , 1863 , 559 , 7731 , 821 , 8477 ,0 }; - static ulong[] dim3631Kuo3Init = { 1 , 1 , 1 , 15 , 19 , 53 , 91 , 119 , 185 , 515 , 1041 , 3933 , 601 , 2971 , 25445 ,0 }; - static ulong[] dim3632Kuo3Init = { 1 , 3 , 5 , 15 , 25 , 57 , 11 , 79 , 299 , 5 , 1433 , 2811 , 1807 , 4057 , 3283 ,0 }; - static ulong[] dim3633Kuo3Init = { 1 , 1 , 5 , 13 , 17 , 17 , 41 , 157 , 357 , 981 , 1323 , 1189 , 1249 , 2857 , 10163 ,0 }; - static ulong[] dim3634Kuo3Init = { 1 , 3 , 3 , 3 , 15 , 47 , 109 , 249 , 37 , 403 , 1611 , 281 , 2521 , 14179 , 3095 ,0 }; - static ulong[] dim3635Kuo3Init = { 1 , 3 , 5 , 7 , 23 , 25 , 5 , 83 , 503 , 203 , 1961 , 1915 , 5111 , 4265 , 27243 ,0 }; - static ulong[] dim3636Kuo3Init = { 1 , 1 , 3 , 1 , 7 , 29 , 43 , 19 , 139 , 487 , 1847 , 1569 , 643 , 15999 , 21539 ,0 }; - static ulong[] dim3637Kuo3Init = { 1 , 1 , 7 , 3 , 3 , 7 , 31 , 217 , 103 , 127 , 1389 , 87 , 7911 , 12751 , 11907 ,0 }; - static ulong[] dim3638Kuo3Init = { 1 , 3 , 1 , 9 , 31 , 25 , 27 , 69 , 477 , 471 , 1375 , 2485 , 4221 , 175 , 16841 ,0 }; - static ulong[] dim3639Kuo3Init = { 1 , 3 , 1 , 15 , 9 , 31 , 125 , 233 , 175 , 649 , 641 , 3751 , 7857 , 3849 , 8859 ,0 }; - static ulong[] dim3640Kuo3Init = { 1 , 1 , 1 , 3 , 25 , 7 , 31 , 197 , 435 , 453 , 1715 , 3187 , 6131 , 12375 , 29367 ,0 }; - static ulong[] dim3641Kuo3Init = { 1 , 3 , 5 , 15 , 9 , 41 , 75 , 107 , 205 , 919 , 1709 , 2515 , 7143 , 10433 , 6179 ,0 }; - static ulong[] dim3642Kuo3Init = { 1 , 1 , 5 , 1 , 27 , 11 , 107 , 177 , 17 , 675 , 677 , 547 , 7101 , 7789 , 29465 ,0 }; - static ulong[] dim3643Kuo3Init = { 1 , 3 , 5 , 3 , 9 , 7 , 123 , 209 , 443 , 221 , 35 , 4045 , 2871 , 16167 , 31745 ,0 }; - static ulong[] dim3644Kuo3Init = { 1 , 1 , 7 , 1 , 15 , 59 , 127 , 173 , 163 , 151 , 813 , 967 , 1165 , 4147 , 29355 ,0 }; - static ulong[] dim3645Kuo3Init = { 1 , 3 , 7 , 13 , 21 , 17 , 33 , 35 , 87 , 897 , 393 , 2205 , 2885 , 7327 , 28521 ,0 }; - static ulong[] dim3646Kuo3Init = { 1 , 1 , 5 , 1 , 1 , 47 , 67 , 87 , 371 , 217 , 1943 , 1277 , 27 , 7205 , 9751 ,0 }; - static ulong[] dim3647Kuo3Init = { 1 , 1 , 5 , 13 , 1 , 25 , 51 , 103 , 61 , 279 , 1151 , 3745 , 4159 , 1895 , 15869 ,0 }; - static ulong[] dim3648Kuo3Init = { 1 , 3 , 7 , 9 , 5 , 59 , 29 , 83 , 415 , 851 , 1415 , 3719 , 4345 , 13897 , 22409 ,0 }; - static ulong[] dim3649Kuo3Init = { 1 , 1 , 1 , 7 , 29 , 19 , 7 , 23 , 87 , 1 , 2035 , 2287 , 4985 , 1371 , 9323 ,0 }; - static ulong[] dim3650Kuo3Init = { 1 , 1 , 3 , 1 , 17 , 33 , 55 , 49 , 285 , 953 , 131 , 3679 , 3811 , 6125 , 18827 ,0 }; - static ulong[] dim3651Kuo3Init = { 1 , 1 , 3 , 3 , 9 , 51 , 61 , 119 , 163 , 829 , 1579 , 2047 , 909 , 3499 , 26535 ,0 }; - static ulong[] dim3652Kuo3Init = { 1 , 3 , 3 , 3 , 27 , 49 , 127 , 239 , 193 , 359 , 695 , 1471 , 6481 , 3549 , 22337 ,0 }; - static ulong[] dim3653Kuo3Init = { 1 , 3 , 1 , 5 , 29 , 7 , 83 , 57 , 509 , 15 , 391 , 2287 , 1023 , 13993 , 6073 ,0 }; - static ulong[] dim3654Kuo3Init = { 1 , 1 , 5 , 15 , 3 , 21 , 23 , 217 , 147 , 511 , 1817 , 2425 , 2347 , 1433 , 10625 ,0 }; - static ulong[] dim3655Kuo3Init = { 1 , 1 , 7 , 13 , 23 , 21 , 29 , 197 , 189 , 367 , 619 , 1305 , 5463 , 7099 , 3307 ,0 }; - static ulong[] dim3656Kuo3Init = { 1 , 3 , 1 , 1 , 27 , 7 , 33 , 221 , 107 , 85 , 633 , 3325 , 3109 , 16377 , 25633 ,0 }; - static ulong[] dim3657Kuo3Init = { 1 , 1 , 3 , 11 , 13 , 59 , 57 , 251 , 321 , 45 , 451 , 237 , 4499 , 10549 , 16473 ,0 }; - static ulong[] dim3658Kuo3Init = { 1 , 1 , 7 , 15 , 11 , 39 , 17 , 85 , 233 , 865 , 1285 , 1771 , 2913 , 7729 , 3815 ,0 }; - static ulong[] dim3659Kuo3Init = { 1 , 1 , 5 , 15 , 9 , 1 , 51 , 47 , 113 , 917 , 1007 , 1883 , 4087 , 4061 , 27965 ,0 }; - static ulong[] dim3660Kuo3Init = { 1 , 1 , 5 , 15 , 29 , 33 , 123 , 183 , 347 , 99 , 1215 , 893 , 7555 , 6835 , 1729 ,0 }; - static ulong[] dim3661Kuo3Init = { 1 , 1 , 5 , 13 , 5 , 25 , 7 , 255 , 315 , 559 , 51 , 899 , 7165 , 2021 , 17413 ,0 }; - static ulong[] dim3662Kuo3Init = { 1 , 3 , 3 , 7 , 3 , 19 , 7 , 89 , 77 , 599 , 1021 , 3269 , 3615 , 10023 , 31043 ,0 }; - static ulong[] dim3663Kuo3Init = { 1 , 1 , 7 , 3 , 9 , 7 , 119 , 199 , 315 , 835 , 1401 , 1547 , 609 , 9015 , 27589 ,0 }; - static ulong[] dim3664Kuo3Init = { 1 , 3 , 3 , 15 , 7 , 33 , 109 , 239 , 329 , 213 , 215 , 1989 , 1495 , 7765 , 3123 ,0 }; - static ulong[] dim3665Kuo3Init = { 1 , 1 , 1 , 13 , 31 , 23 , 79 , 181 , 211 , 189 , 1 , 2103 , 4247 , 7209 , 3733 ,0 }; - static ulong[] dim3666Kuo3Init = { 1 , 3 , 3 , 7 , 19 , 31 , 59 , 103 , 291 , 877 , 459 , 3893 , 4303 , 10033 , 31859 ,0 }; - static ulong[] dim3667Kuo3Init = { 1 , 3 , 5 , 11 , 11 , 1 , 11 , 163 , 477 , 925 , 659 , 143 , 3705 , 11335 , 23667 , 53273 ,0 }; - static ulong[] dim3668Kuo3Init = { 1 , 1 , 7 , 11 , 21 , 29 , 119 , 195 , 303 , 185 , 1353 , 1285 , 2525 , 11801 , 10663 , 49201 ,0 }; - static ulong[] dim3669Kuo3Init = { 1 , 1 , 7 , 3 , 29 , 41 , 115 , 115 , 389 , 763 , 1625 , 691 , 3425 , 6451 , 3355 , 26967 ,0 }; - static ulong[] dim3670Kuo3Init = { 1 , 1 , 1 , 9 , 1 , 3 , 71 , 129 , 25 , 231 , 1849 , 2087 , 3253 , 13151 , 17039 , 21893 ,0 }; - static ulong[] dim3671Kuo3Init = { 1 , 3 , 5 , 9 , 11 , 57 , 99 , 187 , 245 , 965 , 1437 , 3431 , 4657 , 12581 , 14883 , 54985 ,0 }; - static ulong[] dim3672Kuo3Init = { 1 , 3 , 5 , 3 , 27 , 55 , 41 , 203 , 261 , 271 , 327 , 71 , 3659 , 4517 , 24071 , 56297 ,0 }; - static ulong[] dim3673Kuo3Init = { 1 , 1 , 5 , 1 , 13 , 63 , 37 , 109 , 437 , 611 , 649 , 1123 , 4365 , 10259 , 26507 , 60715 ,0 }; - static ulong[] dim3674Kuo3Init = { 1 , 1 , 5 , 9 , 21 , 51 , 113 , 95 , 221 , 157 , 843 , 1429 , 781 , 13193 , 16453 , 26883 ,0 }; - static ulong[] dim3675Kuo3Init = { 1 , 3 , 3 , 9 , 29 , 15 , 13 , 5 , 441 , 7 , 139 , 773 , 1495 , 2283 , 31549 , 4105 ,0 }; - static ulong[] dim3676Kuo3Init = { 1 , 1 , 5 , 9 , 27 , 59 , 51 , 51 , 211 , 871 , 1971 , 1213 , 7459 , 14001 , 32175 , 53975 ,0 }; - static ulong[] dim3677Kuo3Init = { 1 , 3 , 5 , 3 , 3 , 29 , 47 , 131 , 263 , 879 , 731 , 1063 , 3647 , 8729 , 5407 , 4001 ,0 }; - static ulong[] dim3678Kuo3Init = { 1 , 1 , 3 , 5 , 21 , 45 , 93 , 143 , 443 , 295 , 1683 , 2335 , 4213 , 6297 , 26611 , 56661 ,0 }; - static ulong[] dim3679Kuo3Init = { 1 , 1 , 5 , 3 , 9 , 63 , 97 , 143 , 101 , 579 , 435 , 3339 , 7333 , 6267 , 1589 , 30997 ,0 }; - static ulong[] dim3680Kuo3Init = { 1 , 1 , 3 , 3 , 31 , 51 , 81 , 125 , 285 , 879 , 1377 , 107 , 827 , 7185 , 27265 , 54517 ,0 }; - static ulong[] dim3681Kuo3Init = { 1 , 1 , 3 , 11 , 9 , 9 , 121 , 167 , 195 , 625 , 1167 , 1533 , 3697 , 7545 , 27799 , 11613 ,0 }; - static ulong[] dim3682Kuo3Init = { 1 , 3 , 7 , 7 , 21 , 55 , 65 , 63 , 355 , 525 , 1441 , 3057 , 1779 , 1613 , 6277 , 37655 ,0 }; - static ulong[] dim3683Kuo3Init = { 1 , 1 , 7 , 15 , 9 , 61 , 7 , 211 , 11 , 955 , 499 , 2795 , 4017 , 1459 , 4323 , 1453 ,0 }; - static ulong[] dim3684Kuo3Init = { 1 , 1 , 1 , 9 , 25 , 17 , 75 , 219 , 383 , 721 , 1661 , 3325 , 5917 , 11423 , 19265 , 41063 ,0 }; - static ulong[] dim3685Kuo3Init = { 1 , 3 , 1 , 7 , 15 , 39 , 93 , 9 , 463 , 611 , 547 , 173 , 4179 , 4641 , 28201 , 32139 ,0 }; - static ulong[] dim3686Kuo3Init = { 1 , 1 , 5 , 7 , 29 , 51 , 41 , 157 , 93 , 289 , 935 , 3299 , 2103 , 4371 , 15485 , 62685 ,0 }; - static ulong[] dim3687Kuo3Init = { 1 , 3 , 3 , 15 , 31 , 49 , 93 , 205 , 13 , 551 , 1809 , 4051 , 5481 , 2693 , 6615 , 18123 ,0 }; - static ulong[] dim3688Kuo3Init = { 1 , 3 , 7 , 3 , 1 , 41 , 27 , 105 , 469 , 759 , 625 , 1579 , 4253 , 7435 , 20545 , 4365 ,0 }; - static ulong[] dim3689Kuo3Init = { 1 , 3 , 7 , 11 , 17 , 45 , 111 , 91 , 357 , 651 , 5 , 937 , 3199 , 6485 , 21145 , 35085 ,0 }; - static ulong[] dim3690Kuo3Init = { 1 , 3 , 5 , 1 , 7 , 21 , 33 , 213 , 399 , 735 , 1923 , 1047 , 2765 , 11057 , 19007 , 58345 ,0 }; - static ulong[] dim3691Kuo3Init = { 1 , 3 , 7 , 13 , 31 , 57 , 113 , 81 , 75 , 985 , 479 , 1353 , 1041 , 13489 , 12011 , 52749 ,0 }; - static ulong[] dim3692Kuo3Init = { 1 , 1 , 1 , 9 , 23 , 23 , 83 , 167 , 473 , 471 , 171 , 3303 , 7167 , 1109 , 29263 , 30047 ,0 }; - static ulong[] dim3693Kuo3Init = { 1 , 3 , 7 , 15 , 11 , 63 , 57 , 73 , 49 , 921 , 457 , 1683 , 4447 , 14549 , 5819 , 18291 ,0 }; - static ulong[] dim3694Kuo3Init = { 1 , 3 , 5 , 5 , 27 , 1 , 127 , 233 , 509 , 229 , 1553 , 3875 , 2243 , 16005 , 17985 , 28437 ,0 }; - static ulong[] dim3695Kuo3Init = { 1 , 1 , 1 , 15 , 7 , 27 , 75 , 191 , 433 , 585 , 1659 , 3373 , 4067 , 55 , 11095 , 37179 ,0 }; - static ulong[] dim3696Kuo3Init = { 1 , 1 , 7 , 15 , 27 , 31 , 21 , 105 , 95 , 357 , 2019 , 2193 , 741 , 8509 , 349 , 24797 ,0 }; - static ulong[] dim3697Kuo3Init = { 1 , 1 , 1 , 15 , 1 , 51 , 77 , 139 , 205 , 81 , 1849 , 1687 , 1597 , 1531 , 115 , 50163 ,0 }; - static ulong[] dim3698Kuo3Init = { 1 , 3 , 5 , 5 , 7 , 61 , 113 , 111 , 69 , 443 , 179 , 2955 , 7 , 13237 , 26787 , 33917 ,0 }; - static ulong[] dim3699Kuo3Init = { 1 , 3 , 5 , 5 , 21 , 37 , 11 , 209 , 177 , 433 , 1423 , 1629 , 5807 , 4655 , 19377 , 58963 ,0 }; - static ulong[] dim3700Kuo3Init = { 1 , 3 , 5 , 1 , 11 , 29 , 107 , 17 , 135 , 801 , 1441 , 3119 , 4573 , 8903 , 11267 , 2845 ,0 }; - static ulong[] dim3701Kuo3Init = { 1 , 1 , 3 , 3 , 21 , 41 , 115 , 19 , 473 , 447 , 1879 , 4095 , 2743 , 10007 , 5751 , 36845 ,0 }; - static ulong[] dim3702Kuo3Init = { 1 , 1 , 3 , 5 , 19 , 13 , 85 , 131 , 85 , 849 , 1179 , 1919 , 3631 , 13807 , 10467 , 24081 ,0 }; - static ulong[] dim3703Kuo3Init = { 1 , 1 , 5 , 13 , 5 , 17 , 21 , 125 , 169 , 369 , 761 , 1419 , 7795 , 9041 , 7613 , 6125 ,0 }; - static ulong[] dim3704Kuo3Init = { 1 , 3 , 7 , 9 , 21 , 53 , 119 , 55 , 97 , 563 , 1531 , 847 , 3709 , 10573 , 18469 , 29625 ,0 }; - static ulong[] dim3705Kuo3Init = { 1 , 1 , 5 , 7 , 23 , 15 , 99 , 251 , 415 , 55 , 563 , 3535 , 8017 , 7771 , 23601 , 52955 ,0 }; - static ulong[] dim3706Kuo3Init = { 1 , 3 , 5 , 15 , 29 , 11 , 73 , 251 , 139 , 215 , 825 , 1735 , 7859 , 10171 , 17351 , 24971 ,0 }; - static ulong[] dim3707Kuo3Init = { 1 , 3 , 1 , 1 , 21 , 21 , 21 , 21 , 107 , 901 , 1321 , 647 , 7521 , 5505 , 965 , 36217 ,0 }; - static ulong[] dim3708Kuo3Init = { 1 , 1 , 5 , 15 , 9 , 39 , 87 , 173 , 201 , 705 , 563 , 3479 , 437 , 1733 , 18001 , 39161 ,0 }; - static ulong[] dim3709Kuo3Init = { 1 , 3 , 7 , 15 , 31 , 31 , 89 , 119 , 471 , 633 , 249 , 187 , 3735 , 4045 , 1611 , 10045 ,0 }; - static ulong[] dim3710Kuo3Init = { 1 , 3 , 5 , 1 , 7 , 31 , 117 , 249 , 175 , 515 , 1825 , 3417 , 307 , 10909 , 4453 , 43833 ,0 }; - static ulong[] dim3711Kuo3Init = { 1 , 3 , 1 , 9 , 1 , 21 , 59 , 103 , 243 , 105 , 2037 , 1759 , 689 , 15389 , 16981 , 35545 ,0 }; - static ulong[] dim3712Kuo3Init = { 1 , 1 , 7 , 1 , 13 , 15 , 105 , 89 , 463 , 513 , 191 , 1489 , 5239 , 3723 , 20511 , 52139 ,0 }; - static ulong[] dim3713Kuo3Init = { 1 , 3 , 5 , 1 , 1 , 25 , 71 , 89 , 167 , 1009 , 829 , 2267 , 375 , 10217 , 31677 , 58309 ,0 }; - static ulong[] dim3714Kuo3Init = { 1 , 3 , 5 , 1 , 31 , 19 , 21 , 225 , 331 , 621 , 1047 , 3385 , 5247 , 1763 , 19985 , 9013 ,0 }; - static ulong[] dim3715Kuo3Init = { 1 , 3 , 1 , 1 , 5 , 19 , 69 , 11 , 15 , 361 , 617 , 823 , 2645 , 207 , 18775 , 60509 ,0 }; - static ulong[] dim3716Kuo3Init = { 1 , 3 , 3 , 13 , 15 , 1 , 37 , 3 , 249 , 277 , 1729 , 3599 , 115 , 9557 , 12865 , 6257 ,0 }; - static ulong[] dim3717Kuo3Init = { 1 , 3 , 7 , 11 , 15 , 51 , 21 , 147 , 23 , 527 , 167 , 1673 , 2299 , 923 , 22755 , 48627 ,0 }; - static ulong[] dim3718Kuo3Init = { 1 , 3 , 7 , 1 , 17 , 55 , 23 , 1 , 213 , 479 , 287 , 2741 , 7255 , 4571 , 6581 , 57509 ,0 }; - static ulong[] dim3719Kuo3Init = { 1 , 3 , 5 , 7 , 15 , 49 , 13 , 149 , 103 , 513 , 1977 , 2275 , 5535 , 7867 , 16305 , 24713 ,0 }; - static ulong[] dim3720Kuo3Init = { 1 , 1 , 7 , 1 , 29 , 41 , 69 , 211 , 131 , 87 , 859 , 3631 , 611 , 11463 , 18029 , 38771 ,0 }; - static ulong[] dim3721Kuo3Init = { 1 , 3 , 5 , 11 , 17 , 23 , 37 , 149 , 271 , 547 , 1129 , 3615 , 6647 , 7023 , 103 , 29257 ,0 }; - static ulong[] dim3722Kuo3Init = { 1 , 1 , 7 , 13 , 1 , 55 , 71 , 51 , 249 , 141 , 1937 , 3869 , 5897 , 13227 , 22279 , 11733 ,0 }; - static ulong[] dim3723Kuo3Init = { 1 , 1 , 5 , 13 , 1 , 29 , 85 , 255 , 93 , 741 , 687 , 2195 , 519 , 8235 , 21305 , 19681 ,0 }; - static ulong[] dim3724Kuo3Init = { 1 , 1 , 7 , 5 , 13 , 17 , 103 , 65 , 211 , 603 , 543 , 3629 , 235 , 7337 , 27477 , 2735 ,0 }; - static ulong[] dim3725Kuo3Init = { 1 , 3 , 1 , 1 , 17 , 63 , 75 , 183 , 107 , 583 , 1849 , 545 , 7987 , 13679 , 22797 , 40095 ,0 }; - static ulong[] dim3726Kuo3Init = { 1 , 1 , 5 , 1 , 31 , 13 , 33 , 21 , 479 , 879 , 1223 , 3925 , 3003 , 9975 , 23465 , 27775 ,0 }; - static ulong[] dim3727Kuo3Init = { 1 , 1 , 3 , 1 , 7 , 23 , 65 , 107 , 239 , 867 , 1245 , 1549 , 5981 , 4677 , 3761 , 61449 ,0 }; - static ulong[] dim3728Kuo3Init = { 1 , 3 , 7 , 9 , 5 , 31 , 25 , 53 , 59 , 79 , 1545 , 3721 , 6979 , 16351 , 7305 , 41653 ,0 }; - static ulong[] dim3729Kuo3Init = { 1 , 1 , 1 , 13 , 27 , 53 , 9 , 7 , 159 , 353 , 121 , 2525 , 8049 , 12997 , 3933 , 19835 ,0 }; - static ulong[] dim3730Kuo3Init = { 1 , 3 , 3 , 15 , 1 , 33 , 127 , 163 , 399 , 125 , 1869 , 569 , 3853 , 4819 , 4403 , 34367 ,0 }; - static ulong[] dim3731Kuo3Init = { 1 , 3 , 5 , 15 , 11 , 23 , 21 , 95 , 329 , 937 , 689 , 3731 , 1157 , 9613 , 12593 , 58609 ,0 }; - static ulong[] dim3732Kuo3Init = { 1 , 3 , 5 , 7 , 13 , 23 , 7 , 237 , 413 , 139 , 523 , 3517 , 6829 , 17 , 17673 , 57889 ,0 }; - static ulong[] dim3733Kuo3Init = { 1 , 1 , 3 , 3 , 3 , 49 , 63 , 87 , 147 , 359 , 2027 , 1513 , 3933 , 13911 , 25459 , 11391 ,0 }; - static ulong[] dim3734Kuo3Init = { 1 , 1 , 1 , 5 , 23 , 17 , 81 , 249 , 487 , 71 , 395 , 3635 , 4773 , 14909 , 13523 , 32617 ,0 }; - static ulong[] dim3735Kuo3Init = { 1 , 1 , 7 , 5 , 19 , 39 , 13 , 91 , 475 , 899 , 353 , 3275 , 4161 , 2203 , 20375 , 14795 ,0 }; - static ulong[] dim3736Kuo3Init = { 1 , 3 , 3 , 11 , 17 , 15 , 117 , 145 , 223 , 393 , 1267 , 1089 , 6745 , 10485 , 20385 , 25991 ,0 }; - static ulong[] dim3737Kuo3Init = { 1 , 1 , 7 , 7 , 27 , 21 , 57 , 237 , 405 , 513 , 1411 , 2791 , 1685 , 11529 , 2115 , 36631 ,0 }; - static ulong[] dim3738Kuo3Init = { 1 , 1 , 1 , 13 , 5 , 17 , 111 , 55 , 277 , 639 , 1541 , 2347 , 1119 , 10101 , 8533 , 15383 ,0 }; - static ulong[] dim3739Kuo3Init = { 1 , 3 , 5 , 9 , 1 , 47 , 123 , 39 , 473 , 471 , 299 , 3785 , 6589 , 9415 , 29193 , 24367 ,0 }; - static ulong[] dim3740Kuo3Init = { 1 , 3 , 3 , 9 , 13 , 17 , 9 , 131 , 9 , 309 , 1529 , 3721 , 5927 , 6699 , 17439 , 60313 ,0 }; - static ulong[] dim3741Kuo3Init = { 1 , 3 , 3 , 7 , 17 , 3 , 93 , 33 , 287 , 47 , 1295 , 1021 , 4267 , 403 , 31111 , 5399 ,0 }; - static ulong[] dim3742Kuo3Init = { 1 , 3 , 5 , 3 , 29 , 27 , 73 , 117 , 123 , 1007 , 2003 , 2921 , 4875 , 2043 , 12221 , 57865 ,0 }; - static ulong[] dim3743Kuo3Init = { 1 , 3 , 1 , 15 , 15 , 51 , 31 , 217 , 429 , 1009 , 1761 , 389 , 4859 , 13667 , 17955 , 29493 ,0 }; - static ulong[] dim3744Kuo3Init = { 1 , 3 , 3 , 7 , 25 , 11 , 65 , 109 , 241 , 421 , 363 , 2641 , 781 , 711 , 5363 , 9603 ,0 }; - static ulong[] dim3745Kuo3Init = { 1 , 3 , 1 , 11 , 1 , 41 , 99 , 181 , 103 , 503 , 1887 , 1917 , 4791 , 6405 , 27701 , 62353 ,0 }; - static ulong[] dim3746Kuo3Init = { 1 , 1 , 5 , 7 , 25 , 43 , 23 , 49 , 333 , 205 , 903 , 3915 , 2899 , 2719 , 7887 , 17313 ,0 }; - static ulong[] dim3747Kuo3Init = { 1 , 3 , 5 , 3 , 27 , 19 , 59 , 125 , 409 , 979 , 1203 , 1737 , 5269 , 14755 , 32173 , 2127 ,0 }; - static ulong[] dim3748Kuo3Init = { 1 , 1 , 7 , 11 , 29 , 19 , 73 , 63 , 81 , 717 , 933 , 2939 , 2863 , 5993 , 25953 , 31733 ,0 }; - static ulong[] dim3749Kuo3Init = { 1 , 3 , 7 , 5 , 11 , 19 , 55 , 223 , 51 , 661 , 547 , 4055 , 4849 , 3009 , 22303 , 25 ,0 }; - static ulong[] dim3750Kuo3Init = { 1 , 1 , 7 , 5 , 7 , 3 , 55 , 167 , 207 , 819 , 791 , 3813 , 2455 , 1305 , 4661 , 51189 ,0 }; - static ulong[] dim3751Kuo3Init = { 1 , 3 , 7 , 5 , 29 , 1 , 31 , 191 , 267 , 705 , 181 , 3091 , 4725 , 12351 , 31521 , 56163 ,0 }; - static ulong[] dim3752Kuo3Init = { 1 , 3 , 3 , 1 , 19 , 11 , 27 , 215 , 249 , 713 , 723 , 143 , 2179 , 11075 , 22059 , 62629 ,0 }; - static ulong[] dim3753Kuo3Init = { 1 , 1 , 3 , 3 , 23 , 45 , 101 , 25 , 115 , 353 , 565 , 3491 , 285 , 2133 , 27117 , 42699 ,0 }; - static ulong[] dim3754Kuo3Init = { 1 , 1 , 5 , 7 , 1 , 51 , 113 , 165 , 157 , 431 , 1043 , 3003 , 5971 , 15699 , 20799 , 13989 ,0 }; - static ulong[] dim3755Kuo3Init = { 1 , 3 , 7 , 5 , 23 , 21 , 121 , 85 , 69 , 169 , 1761 , 1023 , 5501 , 1255 , 25683 , 48699 ,0 }; - static ulong[] dim3756Kuo3Init = { 1 , 3 , 5 , 13 , 21 , 31 , 95 , 5 , 237 , 607 , 1525 , 763 , 4725 , 4221 , 22769 , 40899 ,0 }; - static ulong[] dim3757Kuo3Init = { 1 , 1 , 5 , 1 , 1 , 9 , 105 , 225 , 171 , 999 , 547 , 2331 , 4389 , 12847 , 18107 , 11939 ,0 }; - static ulong[] dim3758Kuo3Init = { 1 , 3 , 5 , 5 , 15 , 47 , 73 , 237 , 463 , 501 , 1611 , 2259 , 1679 , 1709 , 24527 , 53529 ,0 }; - static ulong[] dim3759Kuo3Init = { 1 , 3 , 1 , 7 , 21 , 27 , 27 , 25 , 463 , 73 , 2021 , 3899 , 487 , 667 , 5063 , 5017 ,0 }; - static ulong[] dim3760Kuo3Init = { 1 , 1 , 3 , 3 , 15 , 3 , 87 , 145 , 45 , 473 , 1455 , 1857 , 2379 , 4805 , 10557 , 27485 ,0 }; - static ulong[] dim3761Kuo3Init = { 1 , 1 , 3 , 13 , 17 , 15 , 13 , 237 , 177 , 835 , 1019 , 975 , 7085 , 2871 , 16473 , 23693 ,0 }; - static ulong[] dim3762Kuo3Init = { 1 , 1 , 1 , 1 , 13 , 61 , 31 , 197 , 127 , 213 , 173 , 3751 , 3819 , 2899 , 22675 , 23095 ,0 }; - static ulong[] dim3763Kuo3Init = { 1 , 3 , 1 , 15 , 7 , 63 , 89 , 95 , 497 , 1021 , 1751 , 1379 , 3809 , 9493 , 7941 , 35217 ,0 }; - static ulong[] dim3764Kuo3Init = { 1 , 3 , 7 , 3 , 7 , 63 , 33 , 155 , 171 , 651 , 773 , 1861 , 4225 , 1081 , 29141 , 53413 ,0 }; - static ulong[] dim3765Kuo3Init = { 1 , 1 , 3 , 7 , 15 , 27 , 31 , 183 , 377 , 341 , 205 , 1817 , 6185 , 13047 , 19585 , 1533 ,0 }; - static ulong[] dim3766Kuo3Init = { 1 , 1 , 1 , 7 , 27 , 23 , 23 , 117 , 463 , 73 , 529 , 1727 , 6989 , 15911 , 11783 , 1011 ,0 }; - static ulong[] dim3767Kuo3Init = { 1 , 1 , 3 , 7 , 9 , 43 , 55 , 191 , 203 , 471 , 515 , 1315 , 7911 , 14281 , 4767 , 15725 ,0 }; - static ulong[] dim3768Kuo3Init = { 1 , 1 , 1 , 15 , 23 , 13 , 61 , 231 , 423 , 79 , 421 , 1619 , 7951 , 15541 , 20985 , 42181 ,0 }; - static ulong[] dim3769Kuo3Init = { 1 , 1 , 7 , 3 , 31 , 29 , 81 , 125 , 217 , 643 , 449 , 477 , 4521 , 2973 , 13295 , 943 ,0 }; - static ulong[] dim3770Kuo3Init = { 1 , 3 , 5 , 3 , 15 , 37 , 81 , 167 , 11 , 53 , 1455 , 3719 , 1777 , 7253 , 16365 , 17021 ,0 }; - static ulong[] dim3771Kuo3Init = { 1 , 3 , 7 , 5 , 25 , 39 , 95 , 189 , 453 , 697 , 1761 , 3837 , 4697 , 8429 , 10455 , 17239 ,0 }; - static ulong[] dim3772Kuo3Init = { 1 , 1 , 3 , 5 , 13 , 43 , 127 , 251 , 497 , 475 , 105 , 3137 , 5927 , 7569 , 5645 , 25315 ,0 }; - static ulong[] dim3773Kuo3Init = { 1 , 3 , 7 , 9 , 1 , 23 , 15 , 129 , 165 , 887 , 1719 , 2343 , 1663 , 1153 , 25889 , 10961 ,0 }; - static ulong[] dim3774Kuo3Init = { 1 , 3 , 1 , 13 , 29 , 7 , 37 , 147 , 369 , 697 , 481 , 1845 , 4499 , 4885 , 3201 , 6773 ,0 }; - static ulong[] dim3775Kuo3Init = { 1 , 1 , 1 , 3 , 25 , 23 , 49 , 149 , 435 , 561 , 1233 , 2821 , 3121 , 2825 , 21237 , 47491 ,0 }; - static ulong[] dim3776Kuo3Init = { 1 , 1 , 3 , 3 , 3 , 59 , 85 , 205 , 89 , 423 , 701 , 1179 , 4875 , 3351 , 17863 , 35111 ,0 }; - static ulong[] dim3777Kuo3Init = { 1 , 1 , 3 , 1 , 5 , 51 , 105 , 85 , 411 , 561 , 155 , 2809 , 63 , 8711 , 12523 , 28827 ,0 }; - static ulong[] dim3778Kuo3Init = { 1 , 3 , 7 , 15 , 29 , 43 , 103 , 153 , 105 , 819 , 1861 , 1725 , 2225 , 1821 , 25551 , 65399 ,0 }; - static ulong[] dim3779Kuo3Init = { 1 , 1 , 1 , 13 , 7 , 51 , 71 , 177 , 49 , 605 , 1375 , 737 , 7325 , 9597 , 10239 , 64761 ,0 }; - static ulong[] dim3780Kuo3Init = { 1 , 3 , 1 , 3 , 5 , 15 , 117 , 187 , 19 , 149 , 119 , 3375 , 3203 , 6827 , 22073 , 35757 ,0 }; - static ulong[] dim3781Kuo3Init = { 1 , 1 , 1 , 5 , 13 , 25 , 7 , 157 , 23 , 741 , 465 , 2225 , 6697 , 14371 , 25115 , 29699 ,0 }; - static ulong[] dim3782Kuo3Init = { 1 , 3 , 7 , 13 , 5 , 29 , 95 , 209 , 123 , 947 , 1631 , 423 , 1217 , 12353 , 7561 , 1415 ,0 }; - static ulong[] dim3783Kuo3Init = { 1 , 3 , 7 , 11 , 3 , 17 , 63 , 65 , 371 , 355 , 1793 , 1197 , 2375 , 3629 , 13283 , 41727 ,0 }; - static ulong[] dim3784Kuo3Init = { 1 , 3 , 1 , 13 , 5 , 19 , 103 , 85 , 271 , 123 , 1939 , 2741 , 5105 , 8693 , 4291 , 49389 ,0 }; - static ulong[] dim3785Kuo3Init = { 1 , 3 , 3 , 1 , 31 , 1 , 57 , 13 , 265 , 941 , 1169 , 3639 , 5317 , 10565 , 30263 , 64329 ,0 }; - static ulong[] dim3786Kuo3Init = { 1 , 1 , 7 , 13 , 7 , 9 , 115 , 111 , 301 , 365 , 1 , 3093 , 3209 , 2607 , 5749 , 17047 ,0 }; - static ulong[] dim3787Kuo3Init = { 1 , 3 , 1 , 1 , 5 , 41 , 113 , 73 , 407 , 427 , 1271 , 1361 , 4869 , 14845 , 29515 , 38769 ,0 }; - static ulong[] dim3788Kuo3Init = { 1 , 3 , 5 , 13 , 19 , 47 , 77 , 27 , 57 , 43 , 1633 , 197 , 5465 , 14735 , 25187 , 38621 ,0 }; - static ulong[] dim3789Kuo3Init = { 1 , 3 , 1 , 5 , 11 , 55 , 23 , 213 , 495 , 929 , 697 , 2829 , 4185 , 8321 , 12673 , 22759 ,0 }; - static ulong[] dim3790Kuo3Init = { 1 , 1 , 3 , 9 , 17 , 29 , 7 , 41 , 75 , 139 , 1165 , 3387 , 6015 , 3679 , 8353 , 29981 ,0 }; - static ulong[] dim3791Kuo3Init = { 1 , 3 , 3 , 1 , 21 , 47 , 95 , 163 , 121 , 877 , 245 , 3947 , 3839 , 15097 , 4695 , 26037 ,0 }; - static ulong[] dim3792Kuo3Init = { 1 , 1 , 7 , 11 , 19 , 19 , 7 , 93 , 77 , 887 , 153 , 237 , 543 , 2631 , 22023 , 17207 ,0 }; - static ulong[] dim3793Kuo3Init = { 1 , 1 , 7 , 13 , 7 , 23 , 39 , 181 , 107 , 313 , 131 , 3799 , 981 , 11145 , 10969 , 28733 ,0 }; - static ulong[] dim3794Kuo3Init = { 1 , 3 , 1 , 11 , 15 , 45 , 105 , 187 , 457 , 41 , 1739 , 3229 , 4289 , 107 , 2685 , 15601 ,0 }; - static ulong[] dim3795Kuo3Init = { 1 , 1 , 1 , 9 , 15 , 53 , 11 , 87 , 421 , 733 , 1031 , 121 , 2413 , 3383 , 6525 , 35781 ,0 }; - static ulong[] dim3796Kuo3Init = { 1 , 3 , 3 , 11 , 23 , 15 , 81 , 13 , 215 , 573 , 1953 , 379 , 6857 , 2137 , 2599 , 29589 ,0 }; - static ulong[] dim3797Kuo3Init = { 1 , 3 , 3 , 9 , 29 , 17 , 25 , 121 , 291 , 317 , 81 , 4073 , 7111 , 5045 , 32685 , 21527 ,0 }; - static ulong[] dim3798Kuo3Init = { 1 , 1 , 3 , 11 , 31 , 53 , 115 , 179 , 81 , 919 , 955 , 2301 , 647 , 11433 , 17761 , 8187 ,0 }; - static ulong[] dim3799Kuo3Init = { 1 , 1 , 5 , 9 , 17 , 15 , 105 , 55 , 303 , 505 , 223 , 1757 , 3567 , 9079 , 29415 , 37845 ,0 }; - static ulong[] dim3800Kuo3Init = { 1 , 3 , 7 , 1 , 23 , 33 , 33 , 199 , 119 , 911 , 349 , 3641 , 5339 , 12803 , 27979 , 17951 ,0 }; - static ulong[] dim3801Kuo3Init = { 1 , 1 , 3 , 13 , 15 , 53 , 43 , 25 , 31 , 609 , 49 , 1307 , 6477 , 2173 , 32245 , 34123 ,0 }; - static ulong[] dim3802Kuo3Init = { 1 , 3 , 1 , 13 , 11 , 35 , 55 , 85 , 381 , 733 , 1407 , 2821 , 1547 , 9843 , 13861 , 13529 ,0 }; - static ulong[] dim3803Kuo3Init = { 1 , 1 , 1 , 5 , 13 , 11 , 35 , 255 , 421 , 673 , 387 , 3429 , 3137 , 13619 , 28689 , 11145 ,0 }; - static ulong[] dim3804Kuo3Init = { 1 , 3 , 3 , 9 , 23 , 61 , 81 , 25 , 163 , 595 , 769 , 3455 , 5371 , 9711 , 14937 , 34383 ,0 }; - static ulong[] dim3805Kuo3Init = { 1 , 3 , 7 , 13 , 11 , 11 , 115 , 93 , 307 , 807 , 1667 , 483 , 4815 , 6305 , 5197 , 281 ,0 }; - static ulong[] dim3806Kuo3Init = { 1 , 1 , 7 , 15 , 29 , 31 , 113 , 129 , 483 , 369 , 855 , 643 , 7503 , 1699 , 20681 , 51497 ,0 }; - static ulong[] dim3807Kuo3Init = { 1 , 1 , 3 , 9 , 3 , 41 , 7 , 255 , 171 , 1003 , 559 , 775 , 5333 , 11563 , 22473 , 44299 ,0 }; - static ulong[] dim3808Kuo3Init = { 1 , 1 , 5 , 15 , 23 , 51 , 101 , 161 , 433 , 757 , 713 , 403 , 1789 , 5353 , 28901 , 14249 ,0 }; - static ulong[] dim3809Kuo3Init = { 1 , 3 , 7 , 9 , 27 , 5 , 9 , 71 , 47 , 287 , 369 , 653 , 7595 , 10127 , 12547 , 34119 ,0 }; - static ulong[] dim3810Kuo3Init = { 1 , 1 , 3 , 7 , 5 , 33 , 19 , 183 , 497 , 209 , 1999 , 2897 , 2553 , 633 , 7413 , 7847 ,0 }; - static ulong[] dim3811Kuo3Init = { 1 , 3 , 3 , 13 , 27 , 19 , 73 , 181 , 15 , 297 , 1485 , 2167 , 5033 , 11191 , 24999 , 30177 ,0 }; - static ulong[] dim3812Kuo3Init = { 1 , 1 , 1 , 13 , 5 , 47 , 111 , 239 , 259 , 1019 , 241 , 2521 , 1599 , 4655 , 5725 , 56623 ,0 }; - static ulong[] dim3813Kuo3Init = { 1 , 3 , 1 , 7 , 29 , 37 , 29 , 223 , 413 , 307 , 939 , 2009 , 3961 , 9481 , 9121 , 23927 ,0 }; - static ulong[] dim3814Kuo3Init = { 1 , 1 , 3 , 13 , 17 , 37 , 7 , 121 , 387 , 573 , 1751 , 3431 , 7199 , 15041 , 14453 , 45757 ,0 }; - static ulong[] dim3815Kuo3Init = { 1 , 3 , 3 , 7 , 31 , 53 , 29 , 247 , 23 , 579 , 1919 , 2925 , 321 , 653 , 25925 , 49439 ,0 }; - static ulong[] dim3816Kuo3Init = { 1 , 3 , 5 , 5 , 5 , 55 , 109 , 193 , 125 , 823 , 1707 , 2389 , 4135 , 5197 , 12563 , 5977 ,0 }; - static ulong[] dim3817Kuo3Init = { 1 , 3 , 3 , 7 , 25 , 47 , 1 , 145 , 491 , 661 , 1125 , 2567 , 6783 , 15009 , 31871 , 46645 ,0 }; - static ulong[] dim3818Kuo3Init = { 1 , 3 , 3 , 7 , 13 , 43 , 105 , 69 , 25 , 157 , 923 , 1997 , 4383 , 14935 , 8821 , 6383 ,0 }; - static ulong[] dim3819Kuo3Init = { 1 , 1 , 7 , 1 , 23 , 41 , 51 , 215 , 509 , 117 , 1871 , 3025 , 4295 , 8327 , 23887 , 53039 ,0 }; - static ulong[] dim3820Kuo3Init = { 1 , 1 , 7 , 1 , 17 , 9 , 41 , 89 , 227 , 909 , 523 , 3755 , 3527 , 12117 , 12455 , 18087 ,0 }; - static ulong[] dim3821Kuo3Init = { 1 , 3 , 1 , 11 , 19 , 1 , 77 , 73 , 139 , 707 , 163 , 2715 , 819 , 8401 , 24751 , 24619 ,0 }; - static ulong[] dim3822Kuo3Init = { 1 , 3 , 3 , 15 , 11 , 55 , 31 , 89 , 383 , 429 , 269 , 1593 , 4929 , 12037 , 17279 , 6489 ,0 }; - static ulong[] dim3823Kuo3Init = { 1 , 1 , 7 , 13 , 5 , 19 , 65 , 43 , 257 , 711 , 349 , 3231 , 3169 , 11759 , 19069 , 29043 ,0 }; - static ulong[] dim3824Kuo3Init = { 1 , 3 , 7 , 15 , 5 , 51 , 31 , 245 , 197 , 685 , 1527 , 3409 , 4925 , 8923 , 10927 , 62873 ,0 }; - static ulong[] dim3825Kuo3Init = { 1 , 1 , 7 , 15 , 31 , 31 , 61 , 111 , 327 , 785 , 97 , 2659 , 4777 , 14187 , 19731 , 5195 ,0 }; - static ulong[] dim3826Kuo3Init = { 1 , 3 , 5 , 13 , 7 , 53 , 3 , 97 , 109 , 537 , 1395 , 1919 , 4447 , 4067 , 30137 , 60659 ,0 }; - static ulong[] dim3827Kuo3Init = { 1 , 3 , 7 , 11 , 19 , 45 , 51 , 107 , 161 , 269 , 1003 , 2363 , 311 , 7051 , 25943 , 20881 ,0 }; - static ulong[] dim3828Kuo3Init = { 1 , 3 , 7 , 11 , 27 , 49 , 79 , 187 , 265 , 903 , 1547 , 1147 , 8049 , 10451 , 15371 , 43705 ,0 }; - static ulong[] dim3829Kuo3Init = { 1 , 3 , 5 , 1 , 9 , 25 , 29 , 229 , 229 , 337 , 1821 , 2377 , 1325 , 15079 , 28661 , 46107 ,0 }; - static ulong[] dim3830Kuo3Init = { 1 , 3 , 7 , 9 , 29 , 13 , 121 , 121 , 229 , 523 , 707 , 2577 , 7637 , 9257 , 31031 , 56527 ,0 }; - static ulong[] dim3831Kuo3Init = { 1 , 1 , 5 , 9 , 11 , 41 , 111 , 59 , 347 , 295 , 895 , 3477 , 149 , 6747 , 14671 , 3405 ,0 }; - static ulong[] dim3832Kuo3Init = { 1 , 1 , 3 , 11 , 17 , 17 , 77 , 105 , 65 , 831 , 1969 , 41 , 1001 , 2753 , 4427 , 25655 ,0 }; - static ulong[] dim3833Kuo3Init = { 1 , 1 , 5 , 9 , 7 , 37 , 55 , 121 , 51 , 155 , 443 , 321 , 1845 , 11587 , 28855 , 13905 ,0 }; - static ulong[] dim3834Kuo3Init = { 1 , 3 , 3 , 15 , 9 , 51 , 1 , 1 , 453 , 193 , 1615 , 2085 , 3685 , 15933 , 18913 , 46073 ,0 }; - static ulong[] dim3835Kuo3Init = { 1 , 1 , 1 , 9 , 31 , 29 , 59 , 55 , 33 , 413 , 1261 , 1367 , 1895 , 10291 , 575 , 12241 ,0 }; - static ulong[] dim3836Kuo3Init = { 1 , 3 , 3 , 9 , 7 , 11 , 1 , 207 , 351 , 357 , 77 , 4059 , 3951 , 4589 , 11861 , 43855 ,0 }; - static ulong[] dim3837Kuo3Init = { 1 , 1 , 1 , 9 , 15 , 1 , 77 , 227 , 377 , 25 , 1665 , 3693 , 8129 , 10059 , 19517 , 51103 ,0 }; - static ulong[] dim3838Kuo3Init = { 1 , 3 , 5 , 15 , 25 , 43 , 103 , 3 , 477 , 87 , 1943 , 1163 , 7619 , 8345 , 25321 , 36191 ,0 }; - static ulong[] dim3839Kuo3Init = { 1 , 1 , 1 , 5 , 13 , 5 , 99 , 11 , 33 , 113 , 1905 , 2559 , 2679 , 15005 , 12859 , 19233 ,0 }; - static ulong[] dim3840Kuo3Init = { 1 , 3 , 5 , 3 , 9 , 61 , 79 , 95 , 71 , 963 , 1367 , 1843 , 3179 , 10633 , 5451 , 64379 ,0 }; - static ulong[] dim3841Kuo3Init = { 1 , 1 , 1 , 5 , 11 , 11 , 67 , 11 , 133 , 759 , 1823 , 3281 , 6741 , 4995 , 21753 , 17093 ,0 }; - static ulong[] dim3842Kuo3Init = { 1 , 1 , 7 , 5 , 29 , 41 , 31 , 17 , 381 , 741 , 567 , 1009 , 4781 , 8953 , 12397 , 51833 ,0 }; - static ulong[] dim3843Kuo3Init = { 1 , 3 , 3 , 7 , 9 , 61 , 35 , 203 , 69 , 633 , 477 , 2839 , 1917 , 12097 , 28693 , 42999 ,0 }; - static ulong[] dim3844Kuo3Init = { 1 , 1 , 3 , 11 , 29 , 25 , 1 , 219 , 343 , 249 , 1077 , 125 , 3197 , 5877 , 28407 , 59627 ,0 }; - static ulong[] dim3845Kuo3Init = { 1 , 1 , 3 , 1 , 25 , 37 , 113 , 125 , 253 , 947 , 1103 , 1283 , 3493 , 7129 , 17881 , 21279 ,0 }; - static ulong[] dim3846Kuo3Init = { 1 , 3 , 7 , 15 , 29 , 43 , 125 , 203 , 495 , 421 , 1725 , 1673 , 3635 , 8161 , 3753 , 46323 ,0 }; - static ulong[] dim3847Kuo3Init = { 1 , 1 , 5 , 1 , 9 , 7 , 73 , 117 , 397 , 521 , 1699 , 2715 , 6149 , 2337 , 30623 , 3943 ,0 }; - static ulong[] dim3848Kuo3Init = { 1 , 3 , 5 , 7 , 13 , 17 , 121 , 163 , 491 , 111 , 1589 , 351 , 303 , 7395 , 5731 , 65513 ,0 }; - static ulong[] dim3849Kuo3Init = { 1 , 1 , 1 , 3 , 11 , 1 , 19 , 179 , 295 , 595 , 897 , 1929 , 1379 , 13651 , 19067 , 43507 ,0 }; - static ulong[] dim3850Kuo3Init = { 1 , 3 , 5 , 15 , 29 , 51 , 19 , 221 , 67 , 507 , 213 , 1873 , 6051 , 11191 , 31475 , 23447 ,0 }; - static ulong[] dim3851Kuo3Init = { 1 , 3 , 5 , 3 , 13 , 35 , 97 , 75 , 195 , 569 , 1047 , 2607 , 1549 , 9495 , 5945 , 7581 ,0 }; - static ulong[] dim3852Kuo3Init = { 1 , 3 , 3 , 15 , 23 , 41 , 125 , 101 , 415 , 927 , 1421 , 2043 , 8035 , 4077 , 11133 , 17333 ,0 }; - static ulong[] dim3853Kuo3Init = { 1 , 3 , 7 , 3 , 5 , 51 , 111 , 129 , 29 , 469 , 991 , 2595 , 165 , 13987 , 30077 , 63491 ,0 }; - static ulong[] dim3854Kuo3Init = { 1 , 3 , 1 , 3 , 1 , 17 , 93 , 7 , 511 , 3 , 861 , 3979 , 2173 , 6571 , 30099 , 12907 ,0 }; - static ulong[] dim3855Kuo3Init = { 1 , 1 , 7 , 5 , 9 , 29 , 43 , 153 , 83 , 961 , 1585 , 3615 , 4409 , 1937 , 24107 , 45235 ,0 }; - static ulong[] dim3856Kuo3Init = { 1 , 1 , 3 , 1 , 19 , 29 , 81 , 183 , 197 , 565 , 1455 , 2993 , 6731 , 2749 , 1013 , 27777 ,0 }; - static ulong[] dim3857Kuo3Init = { 1 , 3 , 7 , 1 , 17 , 11 , 121 , 245 , 103 , 851 , 1367 , 141 , 1257 , 719 , 25581 , 48999 ,0 }; - static ulong[] dim3858Kuo3Init = { 1 , 1 , 5 , 15 , 15 , 17 , 33 , 255 , 113 , 715 , 1497 , 3137 , 1415 , 7791 , 28563 , 28415 ,0 }; - static ulong[] dim3859Kuo3Init = { 1 , 1 , 3 , 9 , 7 , 45 , 19 , 143 , 73 , 95 , 317 , 1777 , 7263 , 11833 , 25181 , 27137 ,0 }; - static ulong[] dim3860Kuo3Init = { 1 , 1 , 5 , 3 , 15 , 49 , 71 , 57 , 101 , 95 , 667 , 2745 , 6387 , 14167 , 661 , 31809 ,0 }; - static ulong[] dim3861Kuo3Init = { 1 , 1 , 7 , 3 , 7 , 11 , 119 , 5 , 3 , 383 , 933 , 293 , 5507 , 3025 , 18865 , 26577 ,0 }; - static ulong[] dim3862Kuo3Init = { 1 , 1 , 7 , 9 , 21 , 57 , 113 , 173 , 103 , 743 , 1573 , 2165 , 2909 , 14253 , 2303 , 51939 ,0 }; - static ulong[] dim3863Kuo3Init = { 1 , 3 , 3 , 9 , 11 , 29 , 85 , 239 , 501 , 123 , 1149 , 165 , 6341 , 10205 , 18829 , 32327 ,0 }; - static ulong[] dim3864Kuo3Init = { 1 , 3 , 1 , 15 , 21 , 15 , 63 , 117 , 217 , 701 , 299 , 2887 , 1341 , 1617 , 15163 , 45899 ,0 }; - static ulong[] dim3865Kuo3Init = { 1 , 3 , 3 , 13 , 25 , 63 , 91 , 225 , 399 , 765 , 1719 , 3169 , 1645 , 10445 , 1109 , 13021 ,0 }; - static ulong[] dim3866Kuo3Init = { 1 , 1 , 3 , 13 , 3 , 9 , 115 , 35 , 59 , 145 , 551 , 2601 , 1737 , 9753 , 7665 , 30995 ,0 }; - static ulong[] dim3867Kuo3Init = { 1 , 1 , 5 , 9 , 1 , 33 , 37 , 173 , 385 , 635 , 1419 , 1377 , 3161 , 1915 , 30933 , 46117 ,0 }; - static ulong[] dim3868Kuo3Init = { 1 , 1 , 7 , 9 , 21 , 35 , 65 , 227 , 329 , 797 , 61 , 3409 , 3911 , 751 , 21951 , 11969 ,0 }; - static ulong[] dim3869Kuo3Init = { 1 , 3 , 1 , 13 , 13 , 33 , 29 , 197 , 183 , 979 , 979 , 1629 , 6017 , 8645 , 4007 , 52377 ,0 }; - static ulong[] dim3870Kuo3Init = { 1 , 1 , 5 , 7 , 5 , 17 , 29 , 117 , 197 , 163 , 685 , 2561 , 2849 , 5441 , 32031 , 25761 ,0 }; - static ulong[] dim3871Kuo3Init = { 1 , 3 , 1 , 5 , 9 , 17 , 59 , 237 , 33 , 11 , 399 , 3543 , 7273 , 8239 , 15191 , 57529 ,0 }; - static ulong[] dim3872Kuo3Init = { 1 , 1 , 3 , 7 , 1 , 45 , 75 , 107 , 123 , 909 , 389 , 3549 , 4961 , 15671 , 14139 , 29273 ,0 }; - static ulong[] dim3873Kuo3Init = { 1 , 3 , 7 , 3 , 23 , 3 , 93 , 73 , 265 , 889 , 27 , 805 , 6021 , 5851 , 7181 , 35309 ,0 }; - static ulong[] dim3874Kuo3Init = { 1 , 3 , 1 , 9 , 23 , 61 , 17 , 89 , 495 , 813 , 1189 , 1137 , 7363 , 6075 , 3053 , 28313 ,0 }; - static ulong[] dim3875Kuo3Init = { 1 , 1 , 3 , 13 , 3 , 1 , 9 , 133 , 63 , 417 , 843 , 2481 , 5703 , 11095 , 867 , 28097 ,0 }; - static ulong[] dim3876Kuo3Init = { 1 , 1 , 5 , 9 , 23 , 15 , 113 , 23 , 199 , 863 , 1751 , 765 , 1917 , 2145 , 5391 , 4629 ,0 }; - static ulong[] dim3877Kuo3Init = { 1 , 3 , 3 , 11 , 13 , 59 , 127 , 115 , 341 , 311 , 677 , 2305 , 19 , 13871 , 9297 , 4023 ,0 }; - static ulong[] dim3878Kuo3Init = { 1 , 1 , 5 , 7 , 13 , 3 , 25 , 195 , 403 , 323 , 515 , 2809 , 983 , 8699 , 10205 , 14719 ,0 }; - static ulong[] dim3879Kuo3Init = { 1 , 1 , 1 , 13 , 5 , 33 , 123 , 213 , 99 , 889 , 1151 , 3339 , 4855 , 3677 , 30627 , 23225 ,0 }; - static ulong[] dim3880Kuo3Init = { 1 , 1 , 7 , 9 , 21 , 19 , 77 , 85 , 155 , 379 , 119 , 81 , 1937 , 3589 , 22645 , 51585 ,0 }; - static ulong[] dim3881Kuo3Init = { 1 , 1 , 3 , 1 , 5 , 11 , 121 , 111 , 423 , 927 , 1551 , 2207 , 3589 , 691 , 8519 , 61261 ,0 }; - static ulong[] dim3882Kuo3Init = { 1 , 3 , 5 , 3 , 1 , 59 , 25 , 111 , 415 , 41 , 623 , 2505 , 6075 , 973 , 10419 , 26877 ,0 }; - static ulong[] dim3883Kuo3Init = { 1 , 3 , 3 , 11 , 15 , 57 , 43 , 27 , 177 , 733 , 1521 , 3629 , 3003 , 15351 , 26327 , 32921 ,0 }; - static ulong[] dim3884Kuo3Init = { 1 , 3 , 3 , 13 , 1 , 37 , 3 , 183 , 349 , 731 , 1583 , 2787 , 6233 , 14787 , 16299 , 4663 ,0 }; - static ulong[] dim3885Kuo3Init = { 1 , 3 , 7 , 15 , 29 , 47 , 59 , 79 , 265 , 193 , 503 , 2393 , 643 , 14341 , 21055 , 43803 ,0 }; - static ulong[] dim3886Kuo3Init = { 1 , 3 , 1 , 9 , 11 , 43 , 75 , 77 , 493 , 411 , 145 , 227 , 3045 , 363 , 19879 , 41017 ,0 }; - static ulong[] dim3887Kuo3Init = { 1 , 1 , 5 , 3 , 1 , 49 , 87 , 3 , 377 , 795 , 1905 , 2959 , 3743 , 1459 , 32493 , 6283 ,0 }; - static ulong[] dim3888Kuo3Init = { 1 , 3 , 1 , 13 , 13 , 13 , 39 , 83 , 131 , 935 , 599 , 1871 , 7293 , 11749 , 6627 , 58295 ,0 }; - static ulong[] dim3889Kuo3Init = { 1 , 1 , 5 , 3 , 15 , 9 , 107 , 239 , 453 , 53 , 1825 , 1493 , 3611 , 9993 , 12535 , 38879 ,0 }; - static ulong[] dim3890Kuo3Init = { 1 , 3 , 5 , 7 , 1 , 21 , 93 , 189 , 477 , 923 , 13 , 3797 , 8147 , 8417 , 21473 , 62305 ,0 }; - static ulong[] dim3891Kuo3Init = { 1 , 3 , 3 , 15 , 21 , 47 , 75 , 183 , 425 , 281 , 813 , 571 , 1017 , 565 , 8541 , 52977 ,0 }; - static ulong[] dim3892Kuo3Init = { 1 , 1 , 5 , 13 , 29 , 53 , 25 , 217 , 111 , 605 , 1771 , 1827 , 7245 , 16063 , 10769 , 57483 ,0 }; - static ulong[] dim3893Kuo3Init = { 1 , 3 , 5 , 7 , 9 , 27 , 99 , 75 , 171 , 299 , 1751 , 841 , 4717 , 7373 , 14241 , 7435 ,0 }; - static ulong[] dim3894Kuo3Init = { 1 , 3 , 7 , 3 , 27 , 13 , 121 , 69 , 453 , 1009 , 1353 , 3289 , 3221 , 9127 , 29967 , 60919 ,0 }; - static ulong[] dim3895Kuo3Init = { 1 , 1 , 1 , 11 , 5 , 41 , 81 , 151 , 479 , 599 , 1751 , 2841 , 5721 , 1725 , 3465 , 23385 ,0 }; - static ulong[] dim3896Kuo3Init = { 1 , 1 , 3 , 11 , 7 , 7 , 35 , 169 , 35 , 255 , 1657 , 297 , 3855 , 2071 , 10929 , 15907 ,0 }; - static ulong[] dim3897Kuo3Init = { 1 , 1 , 1 , 3 , 25 , 1 , 43 , 139 , 165 , 535 , 95 , 2769 , 8105 , 6865 , 20297 , 64539 ,0 }; - static ulong[] dim3898Kuo3Init = { 1 , 3 , 7 , 7 , 21 , 27 , 11 , 209 , 279 , 769 , 1961 , 101 , 2103 , 4529 , 4987 , 29097 ,0 }; - static ulong[] dim3899Kuo3Init = { 1 , 1 , 1 , 11 , 29 , 37 , 45 , 65 , 75 , 729 , 1773 , 4023 , 7671 , 6259 , 22339 , 45735 ,0 }; - static ulong[] dim3900Kuo3Init = { 1 , 3 , 7 , 5 , 25 , 3 , 41 , 139 , 365 , 915 , 111 , 611 , 7609 , 6259 , 12247 , 58671 ,0 }; - static ulong[] dim3901Kuo3Init = { 1 , 1 , 7 , 15 , 11 , 45 , 95 , 121 , 3 , 491 , 1779 , 1055 , 7051 , 15499 , 17301 , 13081 ,0 }; - static ulong[] dim3902Kuo3Init = { 1 , 1 , 1 , 13 , 5 , 43 , 105 , 173 , 267 , 263 , 873 , 953 , 5945 , 11417 , 23799 , 54591 ,0 }; - static ulong[] dim3903Kuo3Init = { 1 , 1 , 1 , 9 , 1 , 55 , 15 , 73 , 87 , 49 , 1651 , 775 , 6485 , 9543 , 26199 , 30419 ,0 }; - static ulong[] dim3904Kuo3Init = { 1 , 3 , 1 , 3 , 11 , 5 , 35 , 37 , 451 , 85 , 943 , 4017 , 6795 , 8915 , 28551 , 45097 ,0 }; - static ulong[] dim3905Kuo3Init = { 1 , 3 , 7 , 11 , 11 , 51 , 93 , 237 , 487 , 515 , 1511 , 383 , 7571 , 4673 , 29395 , 21659 ,0 }; - static ulong[] dim3906Kuo3Init = { 1 , 1 , 3 , 1 , 11 , 63 , 113 , 253 , 99 , 733 , 2001 , 3767 , 7431 , 12131 , 25203 , 22251 ,0 }; - static ulong[] dim3907Kuo3Init = { 1 , 3 , 3 , 1 , 11 , 29 , 37 , 181 , 299 , 9 , 11 , 317 , 1079 , 13441 , 8925 , 15847 ,0 }; - static ulong[] dim3908Kuo3Init = { 1 , 1 , 5 , 5 , 5 , 9 , 77 , 67 , 165 , 273 , 1161 , 65 , 7157 , 13531 , 2987 , 1169 ,0 }; - static ulong[] dim3909Kuo3Init = { 1 , 3 , 5 , 7 , 9 , 57 , 17 , 209 , 357 , 901 , 1113 , 61 , 5751 , 2255 , 29677 , 56397 ,0 }; - static ulong[] dim3910Kuo3Init = { 1 , 1 , 5 , 11 , 7 , 5 , 7 , 53 , 397 , 279 , 1387 , 2447 , 115 , 2043 , 19287 , 45753 ,0 }; - static ulong[] dim3911Kuo3Init = { 1 , 3 , 3 , 15 , 25 , 41 , 45 , 33 , 167 , 801 , 1929 , 1173 , 1525 , 3725 , 22407 , 37077 ,0 }; - static ulong[] dim3912Kuo3Init = { 1 , 3 , 1 , 11 , 13 , 61 , 107 , 181 , 179 , 51 , 1379 , 3573 , 7319 , 4843 , 10023 , 28725 ,0 }; - static ulong[] dim3913Kuo3Init = { 1 , 1 , 5 , 3 , 11 , 61 , 61 , 1 , 211 , 557 , 417 , 899 , 4651 , 3375 , 19423 , 11719 ,0 }; - static ulong[] dim3914Kuo3Init = { 1 , 3 , 1 , 13 , 9 , 5 , 117 , 217 , 193 , 911 , 991 , 155 , 3011 , 4759 , 30953 , 63939 ,0 }; - static ulong[] dim3915Kuo3Init = { 1 , 3 , 1 , 13 , 21 , 7 , 77 , 29 , 457 , 923 , 871 , 147 , 5177 , 13949 , 1977 , 27515 ,0 }; - static ulong[] dim3916Kuo3Init = { 1 , 3 , 1 , 3 , 5 , 39 , 83 , 133 , 471 , 355 , 615 , 1627 , 2471 , 59 , 21449 , 52293 ,0 }; - static ulong[] dim3917Kuo3Init = { 1 , 3 , 7 , 13 , 23 , 57 , 97 , 3 , 385 , 255 , 1565 , 3479 , 5587 , 15101 , 27153 , 9239 ,0 }; - static ulong[] dim3918Kuo3Init = { 1 , 3 , 5 , 5 , 13 , 25 , 99 , 19 , 49 , 655 , 1823 , 641 , 619 , 5913 , 11379 , 23781 ,0 }; - static ulong[] dim3919Kuo3Init = { 1 , 1 , 1 , 5 , 21 , 1 , 91 , 3 , 31 , 19 , 19 , 3627 , 1575 , 1439 , 7473 , 36215 ,0 }; - static ulong[] dim3920Kuo3Init = { 1 , 3 , 5 , 13 , 29 , 61 , 1 , 151 , 291 , 315 , 965 , 3435 , 1849 , 13069 , 9785 , 41345 ,0 }; - static ulong[] dim3921Kuo3Init = { 1 , 3 , 3 , 15 , 17 , 9 , 97 , 69 , 233 , 925 , 1933 , 3861 , 89 , 7889 , 28853 , 64959 ,0 }; - static ulong[] dim3922Kuo3Init = { 1 , 3 , 3 , 3 , 5 , 51 , 67 , 175 , 341 , 191 , 1643 , 3327 , 763 , 327 , 28069 , 15317 ,0 }; - static ulong[] dim3923Kuo3Init = { 1 , 3 , 5 , 3 , 3 , 37 , 109 , 43 , 465 , 57 , 489 , 915 , 6943 , 7947 , 9229 , 5647 ,0 }; - static ulong[] dim3924Kuo3Init = { 1 , 1 , 7 , 7 , 27 , 1 , 85 , 171 , 185 , 615 , 1451 , 237 , 1597 , 4255 , 24429 , 34357 ,0 }; - static ulong[] dim3925Kuo3Init = { 1 , 3 , 1 , 7 , 29 , 35 , 69 , 237 , 117 , 841 , 1549 , 2093 , 105 , 10197 , 5229 , 59299 ,0 }; - static ulong[] dim3926Kuo3Init = { 1 , 3 , 5 , 3 , 7 , 33 , 73 , 81 , 385 , 177 , 1849 , 773 , 1085 , 5539 , 29213 , 30635 ,0 }; - static ulong[] dim3927Kuo3Init = { 1 , 3 , 7 , 15 , 15 , 47 , 53 , 207 , 337 , 479 , 775 , 2851 , 725 , 14779 , 29653 , 35949 ,0 }; - static ulong[] dim3928Kuo3Init = { 1 , 1 , 3 , 9 , 15 , 53 , 53 , 87 , 315 , 929 , 919 , 907 , 6893 , 4647 , 2019 , 57879 ,0 }; - static ulong[] dim3929Kuo3Init = { 1 , 3 , 5 , 11 , 5 , 31 , 21 , 9 , 215 , 599 , 617 , 3737 , 787 , 10513 , 17907 , 22221 ,0 }; - static ulong[] dim3930Kuo3Init = { 1 , 3 , 3 , 3 , 27 , 5 , 27 , 157 , 423 , 197 , 1757 , 2451 , 6317 , 1557 , 6641 , 12621 ,0 }; - static ulong[] dim3931Kuo3Init = { 1 , 1 , 5 , 9 , 19 , 17 , 109 , 37 , 329 , 217 , 1265 , 3073 , 6243 , 6179 , 25921 , 9001 ,0 }; - static ulong[] dim3932Kuo3Init = { 1 , 3 , 5 , 15 , 13 , 13 , 103 , 79 , 399 , 897 , 1241 , 2847 , 5913 , 2267 , 5367 , 26337 ,0 }; - static ulong[] dim3933Kuo3Init = { 1 , 1 , 3 , 1 , 17 , 41 , 19 , 213 , 123 , 123 , 1103 , 1125 , 2819 , 7643 , 26391 , 20935 ,0 }; - static ulong[] dim3934Kuo3Init = { 1 , 1 , 1 , 5 , 29 , 27 , 79 , 143 , 93 , 311 , 433 , 1945 , 2783 , 13787 , 4473 , 23279 ,0 }; - static ulong[] dim3935Kuo3Init = { 1 , 3 , 1 , 1 , 13 , 49 , 39 , 21 , 117 , 933 , 169 , 551 , 2871 , 9879 , 3715 , 25143 ,0 }; - static ulong[] dim3936Kuo3Init = { 1 , 3 , 1 , 3 , 29 , 15 , 5 , 89 , 255 , 779 , 495 , 2335 , 6029 , 8733 , 5687 , 40189 ,0 }; - static ulong[] dim3937Kuo3Init = { 1 , 1 , 5 , 3 , 5 , 61 , 37 , 231 , 395 , 175 , 711 , 1149 , 4819 , 10119 , 24929 , 37155 ,0 }; - static ulong[] dim3938Kuo3Init = { 1 , 1 , 7 , 3 , 7 , 49 , 81 , 221 , 193 , 685 , 2029 , 3979 , 5071 , 2965 , 18951 , 21497 ,0 }; - static ulong[] dim3939Kuo3Init = { 1 , 1 , 3 , 5 , 11 , 17 , 29 , 153 , 379 , 387 , 1271 , 1261 , 817 , 5913 , 22395 , 885 ,0 }; - static ulong[] dim3940Kuo3Init = { 1 , 1 , 1 , 1 , 3 , 37 , 89 , 255 , 337 , 135 , 535 , 1087 , 7987 , 8107 , 22953 , 18709 ,0 }; - static ulong[] dim3941Kuo3Init = { 1 , 1 , 5 , 11 , 25 , 29 , 15 , 223 , 181 , 879 , 1661 , 1605 , 3777 , 5221 , 7253 , 22951 ,0 }; - static ulong[] dim3942Kuo3Init = { 1 , 3 , 1 , 1 , 3 , 9 , 57 , 239 , 439 , 669 , 1069 , 2001 , 2689 , 9569 , 24151 , 54337 ,0 }; - static ulong[] dim3943Kuo3Init = { 1 , 1 , 1 , 11 , 7 , 47 , 21 , 31 , 35 , 739 , 1229 , 2929 , 5221 , 6715 , 32275 , 42743 ,0 }; - static ulong[] dim3944Kuo3Init = { 1 , 3 , 1 , 7 , 19 , 3 , 85 , 55 , 397 , 875 , 949 , 2835 , 6077 , 1069 , 13307 , 5897 ,0 }; - static ulong[] dim3945Kuo3Init = { 1 , 3 , 7 , 15 , 11 , 57 , 113 , 193 , 191 , 53 , 1319 , 1585 , 4797 , 13903 , 24875 , 50229 ,0 }; - static ulong[] dim3946Kuo3Init = { 1 , 3 , 7 , 7 , 15 , 17 , 29 , 125 , 387 , 775 , 411 , 1283 , 6069 , 10909 , 14221 , 52811 ,0 }; - static ulong[] dim3947Kuo3Init = { 1 , 3 , 7 , 15 , 17 , 47 , 73 , 143 , 133 , 1009 , 1671 , 2307 , 2991 , 10319 , 3161 , 665 ,0 }; - static ulong[] dim3948Kuo3Init = { 1 , 3 , 7 , 11 , 23 , 29 , 115 , 77 , 167 , 667 , 1983 , 3985 , 1449 , 10055 , 27947 , 63501 ,0 }; - static ulong[] dim3949Kuo3Init = { 1 , 1 , 3 , 11 , 27 , 61 , 83 , 173 , 427 , 161 , 1349 , 297 , 1579 , 9929 , 32663 , 44385 ,0 }; - static ulong[] dim3950Kuo3Init = { 1 , 1 , 7 , 9 , 19 , 31 , 73 , 233 , 109 , 991 , 1381 , 3223 , 4033 , 4447 , 4773 , 61631 ,0 }; - static ulong[] dim3951Kuo3Init = { 1 , 1 , 3 , 5 , 17 , 53 , 71 , 201 , 181 , 395 , 1305 , 2049 , 4317 , 12689 , 23133 , 13401 ,0 }; - static ulong[] dim3952Kuo3Init = { 1 , 3 , 1 , 1 , 13 , 63 , 17 , 107 , 149 , 739 , 1829 , 2441 , 3491 , 1649 , 15839 , 13021 ,0 }; - static ulong[] dim3953Kuo3Init = { 1 , 1 , 1 , 3 , 3 , 15 , 35 , 247 , 95 , 973 , 1625 , 3097 , 6075 , 14331 , 8345 , 12225 ,0 }; - static ulong[] dim3954Kuo3Init = { 1 , 3 , 3 , 7 , 9 , 21 , 5 , 85 , 431 , 317 , 1313 , 1981 , 7761 , 2857 , 18659 , 58677 ,0 }; - static ulong[] dim3955Kuo3Init = { 1 , 3 , 3 , 1 , 25 , 23 , 5 , 213 , 345 , 119 , 1979 , 1023 , 6849 , 9587 , 2519 , 57219 ,0 }; - static ulong[] dim3956Kuo3Init = { 1 , 1 , 5 , 11 , 17 , 1 , 15 , 213 , 21 , 435 , 1719 , 3065 , 6197 , 8993 , 8479 , 17383 ,0 }; - static ulong[] dim3957Kuo3Init = { 1 , 1 , 3 , 5 , 17 , 35 , 97 , 167 , 411 , 57 , 145 , 663 , 1319 , 16029 , 1649 , 13097 ,0 }; - static ulong[] dim3958Kuo3Init = { 1 , 3 , 3 , 9 , 13 , 1 , 89 , 179 , 355 , 655 , 1217 , 1421 , 4303 , 2705 , 30107 , 45801 ,0 }; - static ulong[] dim3959Kuo3Init = { 1 , 1 , 7 , 1 , 23 , 49 , 67 , 119 , 139 , 397 , 983 , 3537 , 1463 , 10395 , 4717 , 50885 ,0 }; - static ulong[] dim3960Kuo3Init = { 1 , 1 , 1 , 9 , 9 , 9 , 95 , 75 , 489 , 459 , 951 , 1829 , 5017 , 8703 , 6229 , 18921 ,0 }; - static ulong[] dim3961Kuo3Init = { 1 , 3 , 7 , 5 , 7 , 55 , 89 , 75 , 231 , 141 , 1611 , 2275 , 1953 , 6389 , 12899 , 45117 ,0 }; - static ulong[] dim3962Kuo3Init = { 1 , 3 , 1 , 1 , 25 , 53 , 91 , 25 , 425 , 275 , 189 , 863 , 5777 , 6179 , 12273 , 3473 ,0 }; - static ulong[] dim3963Kuo3Init = { 1 , 1 , 7 , 15 , 5 , 17 , 75 , 83 , 357 , 523 , 1075 , 1981 , 3993 , 13133 , 16441 , 53935 ,0 }; - static ulong[] dim3964Kuo3Init = { 1 , 3 , 7 , 5 , 15 , 13 , 103 , 89 , 309 , 961 , 771 , 1441 , 1449 , 15867 , 20019 , 22303 ,0 }; - static ulong[] dim3965Kuo3Init = { 1 , 3 , 5 , 9 , 7 , 47 , 33 , 117 , 151 , 77 , 893 , 867 , 2523 , 13975 , 20649 , 15673 ,0 }; - static ulong[] dim3966Kuo3Init = { 1 , 3 , 5 , 15 , 5 , 15 , 57 , 149 , 405 , 523 , 763 , 4071 , 5915 , 3255 , 22243 , 46779 ,0 }; - static ulong[] dim3967Kuo3Init = { 1 , 3 , 7 , 5 , 17 , 39 , 53 , 181 , 65 , 541 , 1995 , 3213 , 3837 , 3527 , 2433 , 23527 ,0 }; - static ulong[] dim3968Kuo3Init = { 1 , 3 , 5 , 3 , 17 , 9 , 5 , 79 , 299 , 441 , 1891 , 3607 , 5087 , 14629 , 31767 , 21443 ,0 }; - static ulong[] dim3969Kuo3Init = { 1 , 1 , 5 , 11 , 1 , 47 , 25 , 13 , 201 , 691 , 507 , 2041 , 3169 , 2909 , 5341 , 7643 ,0 }; - static ulong[] dim3970Kuo3Init = { 1 , 1 , 1 , 1 , 31 , 55 , 109 , 97 , 335 , 835 , 933 , 839 , 3271 , 14323 , 25319 , 18807 ,0 }; - static ulong[] dim3971Kuo3Init = { 1 , 3 , 7 , 9 , 19 , 21 , 19 , 79 , 449 , 1007 , 1559 , 3143 , 2633 , 11691 , 3273 , 17381 ,0 }; - static ulong[] dim3972Kuo3Init = { 1 , 1 , 3 , 9 , 3 , 61 , 105 , 255 , 327 , 649 , 11 , 715 , 2629 , 8425 , 165 , 6235 ,0 }; - static ulong[] dim3973Kuo3Init = { 1 , 3 , 5 , 11 , 9 , 39 , 45 , 161 , 421 , 243 , 1589 , 157 , 5309 , 9769 , 28229 , 12947 ,0 }; - static ulong[] dim3974Kuo3Init = { 1 , 3 , 3 , 13 , 15 , 17 , 75 , 23 , 189 , 601 , 737 , 687 , 3387 , 11913 , 17245 , 16073 ,0 }; - static ulong[] dim3975Kuo3Init = { 1 , 1 , 1 , 3 , 25 , 45 , 73 , 243 , 171 , 179 , 617 , 2039 , 4937 , 963 , 10791 , 48989 ,0 }; - static ulong[] dim3976Kuo3Init = { 1 , 1 , 7 , 3 , 3 , 61 , 123 , 27 , 3 , 385 , 1357 , 3773 , 1639 , 353 , 21277 , 52013 ,0 }; - static ulong[] dim3977Kuo3Init = { 1 , 3 , 5 , 9 , 27 , 19 , 49 , 255 , 213 , 753 , 297 , 601 , 4905 , 15889 , 18055 , 31511 ,0 }; - static ulong[] dim3978Kuo3Init = { 1 , 1 , 7 , 9 , 1 , 19 , 93 , 251 , 279 , 21 , 891 , 859 , 4637 , 2587 , 17659 , 19485 ,0 }; - static ulong[] dim3979Kuo3Init = { 1 , 3 , 3 , 11 , 29 , 55 , 69 , 151 , 445 , 947 , 719 , 3935 , 4625 , 9321 , 25645 , 39153 ,0 }; - static ulong[] dim3980Kuo3Init = { 1 , 3 , 7 , 5 , 23 , 57 , 79 , 21 , 353 , 7 , 295 , 3379 , 3505 , 15409 , 9117 , 19745 ,0 }; - static ulong[] dim3981Kuo3Init = { 1 , 1 , 5 , 13 , 7 , 5 , 41 , 249 , 429 , 999 , 1945 , 1097 , 795 , 8647 , 23297 , 60707 ,0 }; - static ulong[] dim3982Kuo3Init = { 1 , 1 , 5 , 13 , 3 , 57 , 105 , 175 , 345 , 53 , 455 , 1549 , 5291 , 6757 , 12637 , 45159 ,0 }; - static ulong[] dim3983Kuo3Init = { 1 , 3 , 3 , 11 , 5 , 31 , 5 , 69 , 373 , 453 , 1861 , 1061 , 6339 , 3857 , 13979 , 24015 ,0 }; - static ulong[] dim3984Kuo3Init = { 1 , 1 , 5 , 11 , 19 , 41 , 113 , 183 , 299 , 197 , 397 , 1597 , 6471 , 14855 , 26067 , 2705 ,0 }; - static ulong[] dim3985Kuo3Init = { 1 , 1 , 1 , 13 , 15 , 59 , 89 , 73 , 45 , 891 , 1285 , 1565 , 4675 , 10669 , 3067 , 40585 ,0 }; - static ulong[] dim3986Kuo3Init = { 1 , 1 , 5 , 7 , 1 , 51 , 59 , 27 , 275 , 961 , 765 , 3003 , 1677 , 2093 , 15083 , 51929 ,0 }; - static ulong[] dim3987Kuo3Init = { 1 , 1 , 5 , 15 , 19 , 37 , 101 , 247 , 223 , 39 , 2009 , 3155 , 6357 , 13513 , 30965 , 36485 ,0 }; - static ulong[] dim3988Kuo3Init = { 1 , 1 , 5 , 1 , 27 , 9 , 71 , 231 , 115 , 1 , 719 , 873 , 4895 , 4031 , 23581 , 17529 ,0 }; - static ulong[] dim3989Kuo3Init = { 1 , 1 , 3 , 9 , 1 , 63 , 13 , 187 , 325 , 199 , 1165 , 491 , 1361 , 15377 , 9463 , 5077 ,0 }; - static ulong[] dim3990Kuo3Init = { 1 , 3 , 3 , 7 , 9 , 13 , 71 , 17 , 213 , 915 , 1779 , 401 , 5315 , 2161 , 14765 , 11301 ,0 }; - static ulong[] dim3991Kuo3Init = { 1 , 3 , 7 , 15 , 5 , 5 , 3 , 137 , 17 , 197 , 1559 , 3077 , 4615 , 923 , 2143 , 16743 ,0 }; - static ulong[] dim3992Kuo3Init = { 1 , 1 , 3 , 5 , 13 , 19 , 77 , 155 , 285 , 209 , 1089 , 2213 , 3131 , 11685 , 13287 , 10439 ,0 }; - static ulong[] dim3993Kuo3Init = { 1 , 1 , 1 , 9 , 7 , 11 , 35 , 113 , 165 , 795 , 1657 , 483 , 4937 , 5209 , 19801 , 13831 ,0 }; - static ulong[] dim3994Kuo3Init = { 1 , 1 , 7 , 9 , 29 , 1 , 67 , 131 , 277 , 919 , 1267 , 3907 , 2561 , 2469 , 25321 , 17769 ,0 }; - static ulong[] dim3995Kuo3Init = { 1 , 3 , 5 , 3 , 25 , 39 , 93 , 5 , 151 , 905 , 201 , 1499 , 4069 , 4691 , 8293 , 945 ,0 }; - static ulong[] dim3996Kuo3Init = { 1 , 3 , 3 , 3 , 3 , 59 , 47 , 13 , 79 , 157 , 231 , 1105 , 5449 , 10889 , 2625 , 53303 ,0 }; - static ulong[] dim3997Kuo3Init = { 1 , 3 , 7 , 15 , 13 , 23 , 25 , 171 , 391 , 497 , 57 , 4089 , 3849 , 6121 , 1561 , 29977 ,0 }; - static ulong[] dim3998Kuo3Init = { 1 , 3 , 7 , 5 , 17 , 19 , 33 , 193 , 351 , 189 , 619 , 2091 , 7881 , 12689 , 3799 , 1199 ,0 }; - static ulong[] dim3999Kuo3Init = { 1 , 3 , 7 , 7 , 5 , 35 , 23 , 219 , 247 , 377 , 439 , 3421 , 2729 , 7169 , 24373 , 48533 ,0 }; - static ulong[] dim4000Kuo3Init = { 1 , 1 , 1 , 13 , 23 , 33 , 77 , 37 , 347 , 831 , 1525 , 2383 , 6483 , 15377 , 22761 , 51647 ,0 }; - static ulong[] dim4001Kuo3Init = { 1 , 1 , 3 , 9 , 5 , 51 , 89 , 207 , 131 , 969 , 463 , 3917 , 5985 , 10797 , 25183 , 35637 ,0 }; - static ulong[] dim4002Kuo3Init = { 1 , 1 , 1 , 15 , 9 , 45 , 99 , 25 , 7 , 279 , 541 , 879 , 6681 , 2591 , 31667 , 51957 ,0 }; - static ulong[] dim4003Kuo3Init = { 1 , 1 , 5 , 1 , 19 , 13 , 59 , 119 , 195 , 385 , 1715 , 823 , 7631 , 9547 , 27099 , 30967 ,0 }; - static ulong[] dim4004Kuo3Init = { 1 , 1 , 3 , 13 , 21 , 29 , 9 , 17 , 51 , 819 , 365 , 1855 , 1505 , 13923 , 27397 , 25347 ,0 }; - static ulong[] dim4005Kuo3Init = { 1 , 3 , 1 , 9 , 21 , 1 , 17 , 109 , 435 , 887 , 1951 , 923 , 181 , 8365 , 1531 , 5533 ,0 }; - static ulong[] dim4006Kuo3Init = { 1 , 3 , 1 , 15 , 7 , 29 , 101 , 221 , 151 , 49 , 1655 , 2889 , 7179 , 1019 , 10765 , 49489 ,0 }; - static ulong[] dim4007Kuo3Init = { 1 , 3 , 1 , 13 , 27 , 15 , 25 , 249 , 31 , 187 , 1875 , 2937 , 5831 , 13499 , 27997 , 8003 ,0 }; - static ulong[] dim4008Kuo3Init = { 1 , 3 , 1 , 5 , 13 , 55 , 111 , 231 , 71 , 245 , 479 , 2487 , 7967 , 10911 , 12853 , 56217 ,0 }; - static ulong[] dim4009Kuo3Init = { 1 , 1 , 7 , 7 , 15 , 13 , 77 , 37 , 497 , 899 , 1527 , 275 , 517 , 10323 , 2329 , 19267 ,0 }; - static ulong[] dim4010Kuo3Init = { 1 , 3 , 5 , 5 , 13 , 1 , 17 , 201 , 211 , 153 , 1377 , 347 , 3481 , 6785 , 23745 , 54849 ,0 }; - static ulong[] dim4011Kuo3Init = { 1 , 1 , 1 , 13 , 23 , 29 , 55 , 91 , 249 , 815 , 1375 , 3081 , 1445 , 13763 , 29983 , 24581 ,0 }; - static ulong[] dim4012Kuo3Init = { 1 , 1 , 5 , 15 , 23 , 19 , 65 , 31 , 105 , 797 , 957 , 1741 , 4189 , 3313 , 17183 , 34345 ,0 }; - static ulong[] dim4013Kuo3Init = { 1 , 1 , 7 , 13 , 23 , 51 , 13 , 119 , 19 , 901 , 1985 , 3269 , 3753 , 5365 , 3871 , 30099 ,0 }; - static ulong[] dim4014Kuo3Init = { 1 , 1 , 1 , 1 , 13 , 11 , 3 , 59 , 45 , 1007 , 121 , 1433 , 1559 , 15593 , 187 , 55939 ,0 }; - static ulong[] dim4015Kuo3Init = { 1 , 3 , 7 , 13 , 7 , 15 , 17 , 227 , 143 , 889 , 1011 , 1195 , 3849 , 12643 , 27303 , 10473 ,0 }; - static ulong[] dim4016Kuo3Init = { 1 , 3 , 7 , 11 , 9 , 63 , 35 , 181 , 301 , 945 , 853 , 877 , 2983 , 9945 , 31237 , 12011 ,0 }; - static ulong[] dim4017Kuo3Init = { 1 , 1 , 1 , 5 , 23 , 17 , 111 , 15 , 429 , 925 , 299 , 173 , 3379 , 2407 , 11999 , 44485 ,0 }; - static ulong[] dim4018Kuo3Init = { 1 , 1 , 5 , 5 , 31 , 55 , 103 , 227 , 93 , 15 , 399 , 1559 , 3107 , 5729 , 24069 , 55711 ,0 }; - static ulong[] dim4019Kuo3Init = { 1 , 3 , 7 , 7 , 25 , 5 , 107 , 57 , 23 , 1005 , 27 , 2881 , 2591 , 10939 , 8613 , 50351 ,0 }; - static ulong[] dim4020Kuo3Init = { 1 , 1 , 5 , 1 , 19 , 23 , 107 , 65 , 11 , 643 , 1337 , 3197 , 1583 , 8797 , 6047 , 55749 ,0 }; - static ulong[] dim4021Kuo3Init = { 1 , 1 , 1 , 9 , 3 , 61 , 31 , 67 , 369 , 755 , 1263 , 2711 , 1341 , 15465 , 25337 , 20607 ,0 }; - static ulong[] dim4022Kuo3Init = { 1 , 3 , 7 , 7 , 23 , 53 , 95 , 223 , 225 , 627 , 471 , 1203 , 7689 , 3211 , 24697 , 21153 ,0 }; - static ulong[] dim4023Kuo3Init = { 1 , 3 , 7 , 1 , 3 , 29 , 45 , 15 , 247 , 45 , 345 , 4063 , 3819 , 263 , 9705 , 27991 ,0 }; - static ulong[] dim4024Kuo3Init = { 1 , 3 , 3 , 1 , 3 , 55 , 127 , 247 , 87 , 969 , 1409 , 2105 , 4133 , 1213 , 2719 , 37043 ,0 }; - static ulong[] dim4025Kuo3Init = { 1 , 1 , 5 , 15 , 9 , 15 , 71 , 9 , 421 , 1 , 1367 , 2557 , 2121 , 2919 , 29167 , 7035 ,0 }; - static ulong[] dim4026Kuo3Init = { 1 , 3 , 7 , 5 , 21 , 35 , 7 , 1 , 429 , 491 , 1077 , 499 , 2915 , 13217 , 25153 , 327 ,0 }; - static ulong[] dim4027Kuo3Init = { 1 , 1 , 3 , 9 , 7 , 57 , 37 , 235 , 97 , 357 , 1171 , 705 , 7111 , 5217 , 13167 , 38395 ,0 }; - static ulong[] dim4028Kuo3Init = { 1 , 3 , 7 , 7 , 9 , 55 , 43 , 173 , 429 , 287 , 355 , 3009 , 1667 , 1845 , 11477 , 25437 ,0 }; - static ulong[] dim4029Kuo3Init = { 1 , 3 , 7 , 3 , 13 , 41 , 41 , 239 , 421 , 347 , 1423 , 797 , 7435 , 16195 , 3501 , 56213 ,0 }; - static ulong[] dim4030Kuo3Init = { 1 , 3 , 7 , 13 , 25 , 59 , 67 , 49 , 363 , 125 , 365 , 2517 , 915 , 2865 , 25361 , 24823 ,0 }; - static ulong[] dim4031Kuo3Init = { 1 , 3 , 7 , 1 , 31 , 55 , 109 , 213 , 19 , 843 , 1457 , 851 , 7245 , 13587 , 30111 , 58737 ,0 }; - static ulong[] dim4032Kuo3Init = { 1 , 1 , 5 , 5 , 7 , 29 , 111 , 121 , 511 , 401 , 411 , 3073 , 3617 , 4447 , 12443 , 49051 ,0 }; - static ulong[] dim4033Kuo3Init = { 1 , 3 , 3 , 9 , 5 , 55 , 89 , 231 , 343 , 869 , 465 , 1421 , 701 , 13565 , 12469 , 62381 ,0 }; - static ulong[] dim4034Kuo3Init = { 1 , 3 , 3 , 13 , 7 , 9 , 91 , 147 , 37 , 917 , 1717 , 2221 , 5795 , 7127 , 21599 , 28335 ,0 }; - static ulong[] dim4035Kuo3Init = { 1 , 3 , 1 , 3 , 9 , 51 , 109 , 43 , 411 , 477 , 549 , 1901 , 4295 , 2915 , 5701 , 29005 ,0 }; - static ulong[] dim4036Kuo3Init = { 1 , 1 , 3 , 9 , 11 , 51 , 5 , 81 , 413 , 461 , 143 , 2695 , 2091 , 8435 , 14217 , 60831 ,0 }; - static ulong[] dim4037Kuo3Init = { 1 , 3 , 5 , 13 , 1 , 15 , 17 , 239 , 219 , 75 , 339 , 1565 , 5029 , 6351 , 19429 , 21483 ,0 }; - static ulong[] dim4038Kuo3Init = { 1 , 1 , 3 , 5 , 13 , 7 , 101 , 215 , 395 , 387 , 1215 , 1967 , 4141 , 643 , 14623 , 58609 ,0 }; - static ulong[] dim4039Kuo3Init = { 1 , 3 , 5 , 13 , 17 , 29 , 85 , 201 , 327 , 855 , 1971 , 335 , 6201 , 5933 , 6131 , 3179 ,0 }; - static ulong[] dim4040Kuo3Init = { 1 , 3 , 3 , 13 , 3 , 49 , 25 , 223 , 207 , 477 , 671 , 1881 , 3639 , 10867 , 22953 , 58725 ,0 }; - static ulong[] dim4041Kuo3Init = { 1 , 1 , 1 , 5 , 21 , 23 , 31 , 57 , 387 , 881 , 343 , 1781 , 3241 , 10939 , 5569 , 37555 ,0 }; - static ulong[] dim4042Kuo3Init = { 1 , 1 , 3 , 1 , 25 , 3 , 117 , 153 , 155 , 61 , 127 , 3871 , 7883 , 11791 , 18529 , 55395 ,0 }; - static ulong[] dim4043Kuo3Init = { 1 , 1 , 7 , 9 , 15 , 15 , 89 , 197 , 109 , 221 , 317 , 2827 , 2159 , 847 , 2527 , 9463 ,0 }; - static ulong[] dim4044Kuo3Init = { 1 , 3 , 5 , 9 , 25 , 11 , 39 , 185 , 457 , 831 , 637 , 527 , 2829 , 4411 , 4713 , 53597 ,0 }; - static ulong[] dim4045Kuo3Init = { 1 , 3 , 7 , 15 , 5 , 27 , 45 , 123 , 385 , 217 , 907 , 2877 , 2703 , 15987 , 24963 , 41659 ,0 }; - static ulong[] dim4046Kuo3Init = { 1 , 3 , 1 , 13 , 9 , 31 , 7 , 225 , 77 , 227 , 175 , 1471 , 3305 , 4521 , 6345 , 55509 ,0 }; - static ulong[] dim4047Kuo3Init = { 1 , 3 , 1 , 5 , 21 , 33 , 37 , 3 , 121 , 605 , 1121 , 537 , 1771 , 14415 , 8323 , 21795 ,0 }; - static ulong[] dim4048Kuo3Init = { 1 , 3 , 7 , 5 , 23 , 23 , 45 , 231 , 97 , 535 , 861 , 1349 , 6611 , 7445 , 25231 , 50737 ,0 }; - static ulong[] dim4049Kuo3Init = { 1 , 3 , 1 , 9 , 11 , 13 , 61 , 155 , 483 , 391 , 615 , 899 , 5099 , 4895 , 2919 , 60239 ,0 }; - static ulong[] dim4050Kuo3Init = { 1 , 3 , 3 , 1 , 31 , 9 , 47 , 209 , 405 , 493 , 103 , 59 , 3609 , 12889 , 6501 , 32869 ,0 }; - static ulong[] dim4051Kuo3Init = { 1 , 1 , 7 , 13 , 15 , 57 , 23 , 153 , 57 , 369 , 1833 , 1287 , 4487 , 3195 , 19587 , 24373 ,0 }; - static ulong[] dim4052Kuo3Init = { 1 , 3 , 7 , 3 , 25 , 45 , 51 , 117 , 293 , 701 , 1909 , 659 , 637 , 3375 , 23223 , 29707 ,0 }; - static ulong[] dim4053Kuo3Init = { 1 , 3 , 7 , 15 , 1 , 27 , 13 , 227 , 369 , 143 , 1167 , 1787 , 4815 , 1143 , 7789 , 16467 ,0 }; - static ulong[] dim4054Kuo3Init = { 1 , 1 , 5 , 1 , 13 , 5 , 63 , 75 , 13 , 411 , 1123 , 459 , 6323 , 10445 , 1303 , 43103 ,0 }; - static ulong[] dim4055Kuo3Init = { 1 , 3 , 1 , 9 , 29 , 21 , 93 , 49 , 135 , 525 , 121 , 1299 , 5931 , 13115 , 32567 , 60605 ,0 }; - static ulong[] dim4056Kuo3Init = { 1 , 3 , 3 , 11 , 25 , 59 , 77 , 181 , 39 , 345 , 1375 , 2067 , 3909 , 8023 , 6409 , 12571 ,0 }; - static ulong[] dim4057Kuo3Init = { 1 , 3 , 5 , 15 , 15 , 55 , 95 , 183 , 269 , 931 , 285 , 1945 , 2105 , 10589 , 19787 , 64461 ,0 }; - static ulong[] dim4058Kuo3Init = { 1 , 1 , 1 , 5 , 31 , 19 , 51 , 109 , 455 , 877 , 905 , 2403 , 2021 , 573 , 29837 , 46871 ,0 }; - static ulong[] dim4059Kuo3Init = { 1 , 3 , 1 , 9 , 21 , 23 , 9 , 201 , 143 , 661 , 289 , 621 , 6729 , 9573 , 6359 , 14981 ,0 }; - static ulong[] dim4060Kuo3Init = { 1 , 3 , 5 , 5 , 15 , 53 , 41 , 57 , 201 , 37 , 2047 , 4045 , 6501 , 15641 , 22031 , 25851 ,0 }; - static ulong[] dim4061Kuo3Init = { 1 , 1 , 7 , 7 , 17 , 3 , 31 , 31 , 165 , 765 , 1101 , 1161 , 7247 , 16383 , 27715 , 20835 ,0 }; - static ulong[] dim4062Kuo3Init = { 1 , 3 , 3 , 13 , 7 , 41 , 81 , 55 , 345 , 913 , 1457 , 3801 , 6937 , 3781 , 21125 , 36899 ,0 }; - static ulong[] dim4063Kuo3Init = { 1 , 1 , 3 , 11 , 21 , 61 , 57 , 89 , 341 , 877 , 639 , 3051 , 6541 , 2133 , 11187 , 9613 ,0 }; - static ulong[] dim4064Kuo3Init = { 1 , 3 , 3 , 5 , 3 , 29 , 3 , 193 , 331 , 333 , 1613 , 3755 , 6489 , 4851 , 10421 , 11257 ,0 }; - static ulong[] dim4065Kuo3Init = { 1 , 3 , 3 , 13 , 15 , 29 , 115 , 135 , 283 , 363 , 905 , 3199 , 733 , 7785 , 5237 , 20657 ,0 }; - static ulong[] dim4066Kuo3Init = { 1 , 3 , 5 , 7 , 3 , 31 , 89 , 219 , 61 , 573 , 1773 , 677 , 7447 , 4625 , 17011 , 57851 ,0 }; - static ulong[] dim4067Kuo3Init = { 1 , 3 , 1 , 7 , 9 , 31 , 121 , 219 , 27 , 583 , 1769 , 3667 , 4415 , 6789 , 28069 , 11833 ,0 }; - static ulong[] dim4068Kuo3Init = { 1 , 1 , 3 , 1 , 29 , 11 , 63 , 201 , 33 , 153 , 1075 , 641 , 5923 , 10485 , 24573 , 29423 ,0 }; - static ulong[] dim4069Kuo3Init = { 1 , 1 , 3 , 13 , 17 , 5 , 87 , 237 , 243 , 231 , 915 , 1755 , 4021 , 2127 , 26147 , 28397 ,0 }; - static ulong[] dim4070Kuo3Init = { 1 , 3 , 3 , 3 , 21 , 49 , 53 , 163 , 415 , 553 , 505 , 3309 , 4987 , 16163 , 14439 , 30921 ,0 }; - static ulong[] dim4071Kuo3Init = { 1 , 3 , 1 , 13 , 9 , 59 , 89 , 113 , 203 , 485 , 177 , 2243 , 5267 , 7105 , 5297 , 23333 ,0 }; - static ulong[] dim4072Kuo3Init = { 1 , 3 , 1 , 1 , 13 , 21 , 107 , 183 , 243 , 985 , 499 , 385 , 2409 , 9317 , 17393 , 1913 ,0 }; - static ulong[] dim4073Kuo3Init = { 1 , 3 , 3 , 13 , 21 , 47 , 59 , 21 , 71 , 523 , 1843 , 3131 , 5907 , 15401 , 7957 , 51365 ,0 }; - static ulong[] dim4074Kuo3Init = { 1 , 3 , 1 , 3 , 17 , 19 , 75 , 195 , 171 , 11 , 57 , 303 , 6801 , 1825 , 25027 , 28587 ,0 }; - static ulong[] dim4075Kuo3Init = { 1 , 3 , 5 , 15 , 13 , 47 , 19 , 161 , 47 , 385 , 1227 , 261 , 5855 , 1439 , 18605 , 55645 ,0 }; - static ulong[] dim4076Kuo3Init = { 1 , 1 , 5 , 11 , 23 , 13 , 87 , 197 , 507 , 921 , 1813 , 579 , 3585 , 5117 , 30913 , 5739 ,0 }; - static ulong[] dim4077Kuo3Init = { 1 , 1 , 1 , 5 , 21 , 7 , 3 , 103 , 475 , 929 , 1189 , 1005 , 2933 , 1377 , 30183 , 58513 ,0 }; - static ulong[] dim4078Kuo3Init = { 1 , 1 , 3 , 11 , 27 , 51 , 25 , 139 , 431 , 275 , 1541 , 1459 , 5787 , 9865 , 15077 , 25965 ,0 }; - static ulong[] dim4079Kuo3Init = { 1 , 3 , 7 , 15 , 19 , 33 , 85 , 5 , 119 , 523 , 11 , 1459 , 3807 , 3959 , 31321 , 1905 ,0 }; - static ulong[] dim4080Kuo3Init = { 1 , 3 , 1 , 15 , 9 , 25 , 107 , 51 , 149 , 437 , 995 , 397 , 753 , 12421 , 30637 , 22865 ,0 }; - static ulong[] dim4081Kuo3Init = { 1 , 3 , 1 , 9 , 25 , 13 , 11 , 129 , 371 , 497 , 597 , 1257 , 7291 , 4021 , 16223 , 21489 ,0 }; - static ulong[] dim4082Kuo3Init = { 1 , 3 , 5 , 1 , 5 , 17 , 119 , 107 , 267 , 27 , 87 , 3641 , 593 , 4671 , 16129 , 25645 ,0 }; - static ulong[] dim4083Kuo3Init = { 1 , 3 , 1 , 7 , 19 , 55 , 39 , 159 , 283 , 551 , 321 , 1979 , 1259 , 10049 , 15195 , 62799 ,0 }; - static ulong[] dim4084Kuo3Init = { 1 , 3 , 7 , 3 , 23 , 43 , 63 , 187 , 399 , 725 , 419 , 1759 , 5477 , 4743 , 13397 , 21347 ,0 }; - static ulong[] dim4085Kuo3Init = { 1 , 1 , 1 , 7 , 3 , 45 , 55 , 207 , 33 , 695 , 1109 , 1427 , 5425 , 4743 , 28949 , 54665 ,0 }; - static ulong[] dim4086Kuo3Init = { 1 , 1 , 5 , 5 , 19 , 1 , 97 , 151 , 465 , 767 , 1931 , 1097 , 7001 , 5761 , 30323 , 17501 ,0 }; - static ulong[] dim4087Kuo3Init = { 1 , 3 , 1 , 9 , 9 , 11 , 9 , 165 , 181 , 711 , 45 , 1163 , 11 , 9127 , 31361 , 11259 ,0 }; - static ulong[] dim4088Kuo3Init = { 1 , 3 , 3 , 1 , 23 , 23 , 7 , 115 , 243 , 281 , 847 , 3091 , 6383 , 4593 , 13507 , 58001 ,0 }; - static ulong[] dim4089Kuo3Init = { 1 , 1 , 3 , 13 , 27 , 3 , 123 , 91 , 47 , 483 , 1913 , 2139 , 3877 , 16373 , 31969 , 42977 ,0 }; - static ulong[] dim4090Kuo3Init = { 1 , 1 , 1 , 3 , 11 , 9 , 35 , 3 , 155 , 585 , 1193 , 1887 , 1657 , 2479 , 18803 , 47309 ,0 }; - static ulong[] dim4091Kuo3Init = { 1 , 3 , 3 , 5 , 5 , 57 , 79 , 77 , 205 , 361 , 505 , 2505 , 2959 , 1345 , 8165 , 46001 ,0 }; - static ulong[] dim4092Kuo3Init = { 1 , 1 , 1 , 5 , 29 , 25 , 35 , 209 , 193 , 177 , 291 , 1095 , 7137 , 4323 , 673 , 37571 ,0 }; - static ulong[] dim4093Kuo3Init = { 1 , 3 , 5 , 5 , 27 , 29 , 107 , 161 , 93 , 585 , 1061 , 3281 , 5565 , 5093 , 4511 , 45327 ,0 }; - static ulong[] dim4094Kuo3Init = { 1 , 3 , 7 , 7 , 15 , 43 , 41 , 61 , 425 , 451 , 1775 , 345 , 7851 , 12907 , 9467 , 25705 ,0 }; - static ulong[] dim4095Kuo3Init = { 1 , 1 , 1 , 15 , 31 , 37 , 105 , 227 , 155 , 201 , 653 , 2343 , 4601 , 1331 , 9193 , 28423 ,0 }; - static ulong[] dim4096Kuo3Init = { 1 , 1 , 5 , 9 , 31 , 61 , 19 , 165 , 491 , 121 , 159 , 485 , 7847 , 4993 , 30405 , 22889 ,0 }; - static ulong[] dim4097Kuo3Init = { 1 , 3 , 1 , 5 , 27 , 35 , 81 , 231 , 345 , 519 , 849 , 539 , 627 , 16141 , 26509 , 8965 ,0 }; - static ulong[] dim4098Kuo3Init = { 1 , 1 , 3 , 3 , 7 , 33 , 81 , 51 , 415 , 785 , 1617 , 669 , 4749 , 737 , 15557 , 61779 ,0 }; - static ulong[] dim4099Kuo3Init = { 1 , 3 , 5 , 15 , 5 , 39 , 47 , 199 , 313 , 193 , 1797 , 2425 , 327 , 5111 , 275 , 45933 ,0 }; - static ulong[] dim4100Kuo3Init = { 1 , 3 , 1 , 5 , 1 , 27 , 61 , 1 , 435 , 1005 , 665 , 3099 , 1153 , 12721 , 25537 , 62559 ,0 }; - static ulong[] dim4101Kuo3Init = { 1 , 3 , 7 , 9 , 29 , 43 , 97 , 213 , 43 , 333 , 25 , 3085 , 2709 , 5917 , 5887 , 3847 ,0 }; - static ulong[] dim4102Kuo3Init = { 1 , 1 , 7 , 5 , 17 , 27 , 93 , 45 , 205 , 29 , 2035 , 4053 , 6525 , 12321 , 26175 , 43979 ,0 }; - static ulong[] dim4103Kuo3Init = { 1 , 1 , 3 , 3 , 9 , 41 , 23 , 215 , 163 , 531 , 1753 , 2377 , 5533 , 8681 , 12213 , 36789 ,0 }; - static ulong[] dim4104Kuo3Init = { 1 , 3 , 1 , 3 , 7 , 13 , 25 , 111 , 439 , 695 , 1855 , 2437 , 4477 , 10207 , 4089 , 43521 ,0 }; - static ulong[] dim4105Kuo3Init = { 1 , 1 , 3 , 9 , 23 , 7 , 85 , 123 , 361 , 913 , 1817 , 1547 , 7969 , 9731 , 10553 , 53879 ,0 }; - static ulong[] dim4106Kuo3Init = { 1 , 1 , 7 , 13 , 29 , 25 , 5 , 129 , 211 , 511 , 45 , 907 , 1997 , 15657 , 9003 , 47267 ,0 }; - static ulong[] dim4107Kuo3Init = { 1 , 3 , 1 , 9 , 15 , 49 , 13 , 131 , 43 , 295 , 1569 , 2675 , 7857 , 15515 , 9189 , 33061 ,0 }; - static ulong[] dim4108Kuo3Init = { 1 , 3 , 7 , 9 , 29 , 3 , 85 , 125 , 403 , 583 , 1507 , 73 , 4701 , 1117 , 12271 , 11387 ,0 }; - static ulong[] dim4109Kuo3Init = { 1 , 1 , 3 , 5 , 3 , 15 , 1 , 63 , 319 , 43 , 913 , 3029 , 557 , 3087 , 18605 , 39477 ,0 }; - static ulong[] dim4110Kuo3Init = { 1 , 1 , 7 , 13 , 31 , 51 , 99 , 103 , 343 , 835 , 313 , 2025 , 7109 , 5373 , 20821 , 55649 ,0 }; - static ulong[] dim4111Kuo3Init = { 1 , 1 , 3 , 7 , 7 , 21 , 53 , 123 , 189 , 1013 , 427 , 2773 , 6567 , 5241 , 29647 , 41591 ,0 }; - static ulong[] dim4112Kuo3Init = { 1 , 1 , 1 , 3 , 29 , 53 , 127 , 159 , 327 , 999 , 1357 , 989 , 4401 , 10949 , 32555 , 5097 ,0 }; - static ulong[] dim4113Kuo3Init = { 1 , 3 , 1 , 9 , 31 , 11 , 75 , 47 , 307 , 251 , 1845 , 1543 , 6901 , 3959 , 18371 , 40149 ,0 }; - static ulong[] dim4114Kuo3Init = { 1 , 1 , 7 , 11 , 31 , 47 , 81 , 17 , 17 , 21 , 807 , 3115 , 5447 , 11191 , 2357 , 2263 ,0 }; - static ulong[] dim4115Kuo3Init = { 1 , 1 , 5 , 13 , 25 , 41 , 93 , 135 , 251 , 165 , 805 , 1805 , 2895 , 11725 , 6389 , 21875 ,0 }; - static ulong[] dim4116Kuo3Init = { 1 , 1 , 5 , 5 , 19 , 37 , 19 , 247 , 25 , 241 , 767 , 2883 , 5951 , 531 , 22893 , 47493 ,0 }; - static ulong[] dim4117Kuo3Init = { 1 , 3 , 1 , 11 , 31 , 49 , 23 , 199 , 337 , 311 , 1929 , 2703 , 4339 , 6477 , 1821 , 4729 ,0 }; - static ulong[] dim4118Kuo3Init = { 1 , 1 , 3 , 11 , 7 , 59 , 119 , 3 , 289 , 951 , 1387 , 2999 , 6617 , 14551 , 22081 , 14187 ,0 }; - static ulong[] dim4119Kuo3Init = { 1 , 1 , 5 , 5 , 13 , 33 , 37 , 97 , 501 , 247 , 651 , 209 , 7517 , 2847 , 3549 , 16479 ,0 }; - static ulong[] dim4120Kuo3Init = { 1 , 1 , 3 , 1 , 25 , 45 , 83 , 207 , 115 , 1023 , 543 , 2851 , 3383 , 4177 , 25567 , 2797 ,0 }; - static ulong[] dim4121Kuo3Init = { 1 , 3 , 3 , 5 , 7 , 9 , 127 , 243 , 501 , 653 , 1071 , 2547 , 6995 , 10811 , 4791 , 50157 ,0 }; - static ulong[] dim4122Kuo3Init = { 1 , 1 , 1 , 11 , 27 , 61 , 65 , 117 , 373 , 191 , 1643 , 1057 , 6013 , 15167 , 18815 , 4225 ,0 }; - static ulong[] dim4123Kuo3Init = { 1 , 1 , 1 , 11 , 9 , 25 , 105 , 225 , 247 , 609 , 325 , 2761 , 515 , 9985 , 6977 , 57207 ,0 }; - static ulong[] dim4124Kuo3Init = { 1 , 1 , 7 , 15 , 5 , 43 , 33 , 45 , 301 , 1017 , 1881 , 83 , 95 , 10417 , 2307 , 6915 ,0 }; - static ulong[] dim4125Kuo3Init = { 1 , 3 , 1 , 3 , 25 , 43 , 27 , 81 , 249 , 239 , 1671 , 1215 , 3139 , 7961 , 28509 , 27099 ,0 }; - static ulong[] dim4126Kuo3Init = { 1 , 1 , 3 , 1 , 17 , 29 , 49 , 81 , 503 , 429 , 2037 , 2243 , 7509 , 12359 , 14681 , 21661 ,0 }; - static ulong[] dim4127Kuo3Init = { 1 , 3 , 5 , 3 , 3 , 63 , 71 , 71 , 375 , 999 , 11 , 2475 , 4491 , 7439 , 5915 , 63169 ,0 }; - static ulong[] dim4128Kuo3Init = { 1 , 1 , 7 , 13 , 31 , 35 , 91 , 27 , 151 , 893 , 525 , 1913 , 2795 , 10377 , 1173 , 44175 ,0 }; - static ulong[] dim4129Kuo3Init = { 1 , 1 , 7 , 15 , 23 , 11 , 69 , 77 , 133 , 307 , 1589 , 2795 , 1183 , 1491 , 4661 , 51315 ,0 }; - static ulong[] dim4130Kuo3Init = { 1 , 1 , 7 , 3 , 27 , 37 , 9 , 67 , 481 , 113 , 7 , 1679 , 217 , 6195 , 18147 , 50839 ,0 }; - static ulong[] dim4131Kuo3Init = { 1 , 1 , 5 , 1 , 3 , 37 , 53 , 127 , 19 , 177 , 1851 , 921 , 1009 , 9577 , 24637 , 2491 ,0 }; - static ulong[] dim4132Kuo3Init = { 1 , 3 , 7 , 5 , 19 , 33 , 65 , 25 , 333 , 749 , 1577 , 143 , 6731 , 2411 , 25579 , 57987 ,0 }; - static ulong[] dim4133Kuo3Init = { 1 , 1 , 5 , 3 , 29 , 45 , 89 , 179 , 147 , 411 , 1831 , 2209 , 499 , 3141 , 17357 , 23229 ,0 }; - static ulong[] dim4134Kuo3Init = { 1 , 1 , 5 , 1 , 25 , 41 , 105 , 165 , 369 , 241 , 299 , 875 , 1231 , 469 , 4203 , 27117 ,0 }; - static ulong[] dim4135Kuo3Init = { 1 , 3 , 1 , 5 , 29 , 35 , 95 , 235 , 229 , 797 , 411 , 71 , 4571 , 2341 , 4095 , 28185 ,0 }; - static ulong[] dim4136Kuo3Init = { 1 , 1 , 1 , 7 , 21 , 33 , 23 , 59 , 195 , 539 , 1131 , 3799 , 8093 , 8247 , 6283 , 44143 ,0 }; - static ulong[] dim4137Kuo3Init = { 1 , 1 , 5 , 15 , 11 , 15 , 45 , 99 , 73 , 983 , 1047 , 361 , 2925 , 1985 , 20379 , 63235 ,0 }; - static ulong[] dim4138Kuo3Init = { 1 , 3 , 7 , 5 , 25 , 7 , 29 , 129 , 257 , 1015 , 1823 , 23 , 5031 , 12153 , 13511 , 57897 ,0 }; - static ulong[] dim4139Kuo3Init = { 1 , 1 , 1 , 7 , 15 , 39 , 57 , 173 , 391 , 979 , 569 , 2051 , 3221 , 9561 , 24331 , 39791 ,0 }; - static ulong[] dim4140Kuo3Init = { 1 , 1 , 3 , 15 , 1 , 51 , 25 , 79 , 373 , 639 , 5 , 3237 , 2983 , 12491 , 15991 , 12467 ,0 }; - static ulong[] dim4141Kuo3Init = { 1 , 1 , 7 , 15 , 17 , 21 , 103 , 55 , 233 , 605 , 597 , 1867 , 2147 , 11047 , 1173 , 27237 ,0 }; - static ulong[] dim4142Kuo3Init = { 1 , 1 , 7 , 11 , 11 , 25 , 43 , 63 , 143 , 829 , 1357 , 2199 , 5219 , 15981 , 15615 , 22207 ,0 }; - static ulong[] dim4143Kuo3Init = { 1 , 1 , 3 , 13 , 17 , 53 , 121 , 131 , 501 , 355 , 533 , 2343 , 6515 , 9115 , 29065 , 64569 ,0 }; - static ulong[] dim4144Kuo3Init = { 1 , 3 , 5 , 15 , 27 , 57 , 5 , 105 , 327 , 861 , 931 , 3085 , 5051 , 12687 , 22409 , 57487 ,0 }; - static ulong[] dim4145Kuo3Init = { 1 , 1 , 5 , 15 , 1 , 53 , 65 , 97 , 315 , 413 , 37 , 2563 , 4805 , 2327 , 10261 , 7281 ,0 }; - static ulong[] dim4146Kuo3Init = { 1 , 3 , 5 , 9 , 19 , 57 , 15 , 75 , 161 , 245 , 1215 , 1735 , 4567 , 109 , 8467 , 43139 ,0 }; - static ulong[] dim4147Kuo3Init = { 1 , 3 , 1 , 11 , 21 , 55 , 95 , 11 , 193 , 959 , 793 , 3321 , 5865 , 301 , 7887 , 7389 ,0 }; - static ulong[] dim4148Kuo3Init = { 1 , 1 , 1 , 7 , 31 , 35 , 27 , 89 , 247 , 491 , 1087 , 3955 , 6317 , 1337 , 21619 , 11739 ,0 }; - static ulong[] dim4149Kuo3Init = { 1 , 1 , 7 , 13 , 21 , 59 , 53 , 211 , 403 , 851 , 887 , 1457 , 539 , 4493 , 16571 , 55429 ,0 }; - static ulong[] dim4150Kuo3Init = { 1 , 1 , 1 , 7 , 23 , 33 , 69 , 129 , 33 , 203 , 267 , 3261 , 4179 , 9653 , 22523 , 18779 ,0 }; - static ulong[] dim4151Kuo3Init = { 1 , 1 , 3 , 9 , 31 , 35 , 7 , 189 , 253 , 583 , 1475 , 939 , 2977 , 5573 , 20047 , 38915 ,0 }; - static ulong[] dim4152Kuo3Init = { 1 , 3 , 3 , 13 , 19 , 25 , 61 , 237 , 479 , 821 , 1173 , 599 , 7035 , 12695 , 433 , 26499 ,0 }; - static ulong[] dim4153Kuo3Init = { 1 , 3 , 7 , 3 , 27 , 47 , 29 , 31 , 327 , 687 , 495 , 987 , 1655 , 951 , 29265 , 28641 ,0 }; - static ulong[] dim4154Kuo3Init = { 1 , 1 , 3 , 1 , 25 , 29 , 15 , 139 , 417 , 837 , 2011 , 3703 , 7809 , 421 , 207 , 18961 ,0 }; - static ulong[] dim4155Kuo3Init = { 1 , 3 , 3 , 13 , 7 , 29 , 19 , 63 , 257 , 695 , 161 , 3023 , 149 , 10707 , 20873 , 61881 ,0 }; - static ulong[] dim4156Kuo3Init = { 1 , 3 , 3 , 7 , 5 , 9 , 69 , 31 , 487 , 525 , 1441 , 5 , 3891 , 14473 , 22123 , 40041 ,0 }; - static ulong[] dim4157Kuo3Init = { 1 , 3 , 7 , 15 , 13 , 37 , 75 , 181 , 431 , 753 , 1587 , 595 , 2567 , 8155 , 23199 , 50647 ,0 }; - static ulong[] dim4158Kuo3Init = { 1 , 1 , 5 , 1 , 21 , 63 , 39 , 245 , 171 , 217 , 1643 , 887 , 2349 , 2415 , 31673 , 51007 ,0 }; - static ulong[] dim4159Kuo3Init = { 1 , 3 , 5 , 9 , 19 , 33 , 107 , 227 , 187 , 163 , 1071 , 2385 , 2701 , 15969 , 18665 , 62089 ,0 }; - static ulong[] dim4160Kuo3Init = { 1 , 1 , 1 , 15 , 27 , 47 , 25 , 219 , 139 , 879 , 459 , 1521 , 2153 , 3429 , 28293 , 57703 ,0 }; - static ulong[] dim4161Kuo3Init = { 1 , 3 , 3 , 15 , 15 , 63 , 23 , 237 , 137 , 271 , 117 , 3047 , 3973 , 3379 , 11527 , 52555 ,0 }; - static ulong[] dim4162Kuo3Init = { 1 , 3 , 7 , 1 , 19 , 27 , 19 , 111 , 441 , 279 , 321 , 2015 , 4451 , 11841 , 17223 , 51691 ,0 }; - static ulong[] dim4163Kuo3Init = { 1 , 3 , 3 , 1 , 15 , 35 , 19 , 31 , 277 , 977 , 1125 , 2435 , 5171 , 81 , 31729 , 18883 ,0 }; - static ulong[] dim4164Kuo3Init = { 1 , 3 , 1 , 15 , 19 , 31 , 105 , 13 , 117 , 533 , 191 , 3651 , 6915 , 2423 , 31819 , 47709 ,0 }; - static ulong[] dim4165Kuo3Init = { 1 , 1 , 5 , 11 , 29 , 45 , 17 , 51 , 283 , 297 , 1605 , 3009 , 3137 , 2665 , 27799 , 2293 ,0 }; - static ulong[] dim4166Kuo3Init = { 1 , 3 , 5 , 13 , 29 , 61 , 91 , 7 , 23 , 835 , 1809 , 3283 , 1091 , 10443 , 26547 , 10685 ,0 }; - static ulong[] dim4167Kuo3Init = { 1 , 3 , 5 , 1 , 1 , 29 , 121 , 181 , 43 , 827 , 871 , 3547 , 4285 , 12551 , 2079 , 19385 ,0 }; - static ulong[] dim4168Kuo3Init = { 1 , 1 , 1 , 7 , 3 , 53 , 73 , 39 , 1 , 499 , 1905 , 3785 , 1597 , 1529 , 9423 , 11555 ,0 }; - static ulong[] dim4169Kuo3Init = { 1 , 1 , 5 , 5 , 27 , 25 , 33 , 59 , 327 , 419 , 1527 , 255 , 6877 , 3927 , 11877 , 21747 ,0 }; - static ulong[] dim4170Kuo3Init = { 1 , 1 , 3 , 11 , 27 , 37 , 99 , 161 , 213 , 321 , 1127 , 523 , 5327 , 7885 , 17403 , 2097 ,0 }; - static ulong[] dim4171Kuo3Init = { 1 , 1 , 1 , 3 , 5 , 11 , 119 , 153 , 503 , 1007 , 187 , 1705 , 7499 , 12739 , 16185 , 11121 ,0 }; - static ulong[] dim4172Kuo3Init = { 1 , 1 , 3 , 1 , 27 , 63 , 29 , 239 , 5 , 377 , 831 , 2883 , 2167 , 2551 , 29891 , 6165 ,0 }; - static ulong[] dim4173Kuo3Init = { 1 , 3 , 7 , 11 , 5 , 57 , 33 , 15 , 425 , 93 , 1435 , 1449 , 1629 , 999 , 27037 , 51171 ,0 }; - static ulong[] dim4174Kuo3Init = { 1 , 1 , 5 , 13 , 1 , 31 , 83 , 19 , 373 , 497 , 1173 , 775 , 439 , 5757 , 32143 , 52487 ,0 }; - static ulong[] dim4175Kuo3Init = { 1 , 1 , 5 , 11 , 15 , 43 , 73 , 19 , 259 , 145 , 1771 , 2133 , 6969 , 8571 , 29821 , 19581 ,0 }; - static ulong[] dim4176Kuo3Init = { 1 , 3 , 3 , 5 , 25 , 63 , 43 , 95 , 215 , 853 , 127 , 3737 , 4803 , 10089 , 3537 , 14671 ,0 }; - static ulong[] dim4177Kuo3Init = { 1 , 1 , 3 , 1 , 31 , 17 , 1 , 139 , 199 , 841 , 1859 , 1767 , 1545 , 4869 , 14501 , 11729 ,0 }; - static ulong[] dim4178Kuo3Init = { 1 , 3 , 5 , 13 , 29 , 57 , 43 , 143 , 55 , 893 , 1219 , 2415 , 7605 , 11091 , 3441 , 45749 ,0 }; - static ulong[] dim4179Kuo3Init = { 1 , 3 , 7 , 13 , 27 , 11 , 27 , 15 , 67 , 49 , 967 , 1919 , 1773 , 9135 , 4607 , 65495 ,0 }; - static ulong[] dim4180Kuo3Init = { 1 , 1 , 1 , 5 , 7 , 11 , 63 , 39 , 209 , 41 , 951 , 63 , 1537 , 9971 , 9659 , 17825 ,0 }; - static ulong[] dim4181Kuo3Init = { 1 , 3 , 7 , 7 , 27 , 25 , 57 , 53 , 91 , 1013 , 591 , 261 , 721 , 2061 , 629 , 37817 ,0 }; - static ulong[] dim4182Kuo3Init = { 1 , 1 , 5 , 15 , 23 , 35 , 71 , 43 , 343 , 329 , 295 , 3523 , 275 , 2119 , 15165 , 2809 ,0 }; - static ulong[] dim4183Kuo3Init = { 1 , 1 , 5 , 13 , 19 , 3 , 121 , 67 , 165 , 909 , 1731 , 437 , 8055 , 11683 , 12735 , 29129 ,0 }; - static ulong[] dim4184Kuo3Init = { 1 , 3 , 5 , 7 , 21 , 47 , 113 , 55 , 169 , 133 , 2029 , 825 , 4079 , 14651 , 22373 , 15009 ,0 }; - static ulong[] dim4185Kuo3Init = { 1 , 1 , 5 , 7 , 25 , 23 , 61 , 147 , 211 , 665 , 395 , 505 , 3757 , 14545 , 10683 , 53211 ,0 }; - static ulong[] dim4186Kuo3Init = { 1 , 1 , 1 , 3 , 17 , 25 , 111 , 171 , 493 , 815 , 847 , 2109 , 8013 , 751 , 26793 , 62903 ,0 }; - static ulong[] dim4187Kuo3Init = { 1 , 3 , 7 , 11 , 7 , 27 , 91 , 61 , 385 , 3 , 577 , 3515 , 4335 , 4261 , 6053 , 62513 ,0 }; - static ulong[] dim4188Kuo3Init = { 1 , 3 , 7 , 5 , 17 , 5 , 21 , 217 , 227 , 443 , 1479 , 2855 , 2581 , 6255 , 23363 , 37437 ,0 }; - static ulong[] dim4189Kuo3Init = { 1 , 1 , 5 , 5 , 5 , 51 , 5 , 213 , 233 , 787 , 719 , 463 , 2595 , 4019 , 16839 , 14671 ,0 }; - static ulong[] dim4190Kuo3Init = { 1 , 1 , 1 , 15 , 11 , 5 , 49 , 135 , 85 , 773 , 1719 , 2187 , 449 , 14913 , 19721 , 59583 ,0 }; - static ulong[] dim4191Kuo3Init = { 1 , 1 , 1 , 13 , 3 , 49 , 77 , 217 , 289 , 889 , 63 , 2547 , 5547 , 14005 , 18657 , 65109 ,0 }; - static ulong[] dim4192Kuo3Init = { 1 , 3 , 5 , 9 , 11 , 47 , 19 , 251 , 77 , 623 , 1253 , 635 , 1047 , 525 , 8573 , 25951 ,0 }; - static ulong[] dim4193Kuo3Init = { 1 , 1 , 1 , 13 , 5 , 21 , 35 , 187 , 395 , 547 , 2003 , 3189 , 4107 , 567 , 29239 , 32647 ,0 }; - static ulong[] dim4194Kuo3Init = { 1 , 1 , 3 , 13 , 13 , 61 , 59 , 57 , 91 , 881 , 1665 , 453 , 6313 , 2291 , 19523 , 60439 ,0 }; - static ulong[] dim4195Kuo3Init = { 1 , 1 , 3 , 3 , 7 , 7 , 7 , 127 , 411 , 643 , 1415 , 2933 , 6649 , 4219 , 31781 , 8733 ,0 }; - static ulong[] dim4196Kuo3Init = { 1 , 3 , 1 , 1 , 25 , 29 , 127 , 235 , 271 , 831 , 1909 , 2347 , 7085 , 8339 , 22459 , 48791 ,0 }; - static ulong[] dim4197Kuo3Init = { 1 , 3 , 7 , 11 , 21 , 19 , 31 , 5 , 509 , 713 , 767 , 1801 , 6937 , 1763 , 20703 , 10153 ,0 }; - static ulong[] dim4198Kuo3Init = { 1 , 3 , 5 , 3 , 9 , 35 , 55 , 215 , 75 , 733 , 1773 , 1373 , 43 , 5045 , 17675 , 29615 ,0 }; - static ulong[] dim4199Kuo3Init = { 1 , 3 , 5 , 13 , 25 , 27 , 33 , 167 , 277 , 231 , 449 , 1055 , 6227 , 1441 , 29535 , 30421 ,0 }; - static ulong[] dim4200Kuo3Init = { 1 , 1 , 5 , 15 , 31 , 63 , 69 , 137 , 41 , 67 , 965 , 3737 , 3191 , 2613 , 8229 , 47453 ,0 }; - static ulong[] dim4201Kuo3Init = { 1 , 1 , 3 , 7 , 9 , 13 , 97 , 31 , 279 , 525 , 185 , 1673 , 1269 , 8305 , 29745 , 5799 ,0 }; - static ulong[] dim4202Kuo3Init = { 1 , 3 , 3 , 13 , 27 , 47 , 97 , 185 , 483 , 787 , 1049 , 4073 , 1985 , 2129 , 15099 , 33307 ,0 }; - static ulong[] dim4203Kuo3Init = { 1 , 1 , 7 , 13 , 21 , 25 , 97 , 49 , 377 , 75 , 1875 , 2389 , 1381 , 6691 , 30447 , 23969 ,0 }; - static ulong[] dim4204Kuo3Init = { 1 , 1 , 7 , 1 , 3 , 55 , 111 , 185 , 371 , 331 , 1471 , 1211 , 1523 , 5393 , 21763 , 44333 ,0 }; - static ulong[] dim4205Kuo3Init = { 1 , 3 , 1 , 3 , 19 , 39 , 35 , 49 , 433 , 937 , 869 , 239 , 7775 , 9591 , 16969 , 43455 ,0 }; - static ulong[] dim4206Kuo3Init = { 1 , 3 , 3 , 11 , 21 , 11 , 11 , 201 , 187 , 409 , 1603 , 3471 , 1473 , 5283 , 7109 , 53219 ,0 }; - static ulong[] dim4207Kuo3Init = { 1 , 3 , 1 , 1 , 13 , 55 , 91 , 37 , 71 , 837 , 1779 , 1097 , 7433 , 5969 , 22781 , 28547 ,0 }; - static ulong[] dim4208Kuo3Init = { 1 , 3 , 3 , 11 , 9 , 41 , 29 , 125 , 151 , 51 , 667 , 1387 , 6695 , 7957 , 20469 , 20987 ,0 }; - static ulong[] dim4209Kuo3Init = { 1 , 3 , 1 , 7 , 23 , 17 , 91 , 79 , 249 , 123 , 1141 , 2201 , 7139 , 5749 , 20655 , 18111 ,0 }; - static ulong[] dim4210Kuo3Init = { 1 , 3 , 5 , 11 , 1 , 35 , 5 , 219 , 255 , 549 , 1159 , 1641 , 5063 , 457 , 24023 , 61667 ,0 }; - static ulong[] dim4211Kuo3Init = { 1 , 1 , 5 , 9 , 23 , 45 , 85 , 81 , 41 , 327 , 1923 , 2043 , 6737 , 13609 , 1833 , 30563 ,0 }; - static ulong[] dim4212Kuo3Init = { 1 , 3 , 3 , 1 , 9 , 15 , 81 , 137 , 353 , 509 , 799 , 787 , 5371 , 4863 , 29781 , 40405 ,0 }; - static ulong[] dim4213Kuo3Init = { 1 , 3 , 7 , 5 , 31 , 17 , 109 , 123 , 455 , 155 , 253 , 1541 , 2265 , 16015 , 32309 , 40837 ,0 }; - static ulong[] dim4214Kuo3Init = { 1 , 1 , 5 , 15 , 21 , 59 , 109 , 3 , 367 , 411 , 1601 , 3577 , 3155 , 1659 , 15193 , 32453 ,0 }; - static ulong[] dim4215Kuo3Init = { 1 , 3 , 5 , 3 , 3 , 21 , 123 , 125 , 163 , 233 , 125 , 947 , 1023 , 7435 , 30777 , 14615 ,0 }; - static ulong[] dim4216Kuo3Init = { 1 , 3 , 5 , 9 , 15 , 29 , 31 , 101 , 427 , 379 , 379 , 1123 , 1411 , 10523 , 24017 , 43629 ,0 }; - static ulong[] dim4217Kuo3Init = { 1 , 1 , 5 , 15 , 1 , 27 , 43 , 239 , 91 , 967 , 991 , 2827 , 6135 , 1035 , 25925 , 42605 ,0 }; - static ulong[] dim4218Kuo3Init = { 1 , 3 , 7 , 9 , 11 , 53 , 83 , 127 , 51 , 1021 , 2017 , 593 , 1445 , 14597 , 6517 , 19667 ,0 }; - static ulong[] dim4219Kuo3Init = { 1 , 3 , 7 , 15 , 9 , 1 , 17 , 235 , 321 , 571 , 1315 , 3993 , 5825 , 8065 , 13885 , 48815 ,0 }; - static ulong[] dim4220Kuo3Init = { 1 , 1 , 1 , 15 , 3 , 7 , 5 , 197 , 89 , 23 , 711 , 1601 , 3577 , 737 , 27565 , 43365 ,0 }; - static ulong[] dim4221Kuo3Init = { 1 , 1 , 5 , 3 , 19 , 35 , 15 , 99 , 177 , 1013 , 905 , 755 , 667 , 21 , 27039 , 56601 ,0 }; - static ulong[] dim4222Kuo3Init = { 1 , 1 , 3 , 9 , 13 , 37 , 37 , 73 , 75 , 827 , 169 , 2417 , 5457 , 13851 , 5443 , 15731 ,0 }; - static ulong[] dim4223Kuo3Init = { 1 , 1 , 3 , 11 , 11 , 23 , 21 , 159 , 59 , 633 , 1719 , 203 , 5655 , 15887 , 9067 , 33597 ,0 }; - static ulong[] dim4224Kuo3Init = { 1 , 1 , 7 , 7 , 27 , 11 , 55 , 139 , 309 , 721 , 99 , 3371 , 1411 , 4531 , 12751 , 37745 ,0 }; - static ulong[] dim4225Kuo3Init = { 1 , 1 , 1 , 13 , 31 , 33 , 37 , 43 , 125 , 11 , 1441 , 3947 , 7455 , 6097 , 15333 , 32601 ,0 }; - static ulong[] dim4226Kuo3Init = { 1 , 1 , 3 , 15 , 9 , 43 , 79 , 217 , 247 , 229 , 171 , 3607 , 4155 , 1675 , 3945 , 41499 ,0 }; - static ulong[] dim4227Kuo3Init = { 1 , 1 , 1 , 9 , 5 , 59 , 25 , 175 , 209 , 291 , 1419 , 2339 , 7039 , 1327 , 19653 , 11563 ,0 }; - static ulong[] dim4228Kuo3Init = { 1 , 1 , 3 , 11 , 5 , 1 , 103 , 197 , 111 , 891 , 163 , 361 , 2885 , 3443 , 25481 , 47399 ,0 }; - static ulong[] dim4229Kuo3Init = { 1 , 3 , 7 , 1 , 21 , 49 , 35 , 179 , 339 , 505 , 1121 , 2393 , 1181 , 11389 , 5851 , 30553 ,0 }; - static ulong[] dim4230Kuo3Init = { 1 , 3 , 7 , 15 , 31 , 3 , 23 , 205 , 3 , 861 , 1767 , 1971 , 2279 , 4901 , 22077 , 54183 ,0 }; - static ulong[] dim4231Kuo3Init = { 1 , 3 , 7 , 11 , 11 , 1 , 3 , 165 , 129 , 767 , 2007 , 1913 , 3701 , 5761 , 1985 , 42383 ,0 }; - static ulong[] dim4232Kuo3Init = { 1 , 3 , 3 , 5 , 3 , 39 , 31 , 73 , 55 , 805 , 545 , 1577 , 1409 , 5693 , 31995 , 58057 ,0 }; - static ulong[] dim4233Kuo3Init = { 1 , 3 , 1 , 15 , 21 , 9 , 69 , 17 , 497 , 1003 , 1123 , 4023 , 1921 , 723 , 19815 , 11583 ,0 }; - static ulong[] dim4234Kuo3Init = { 1 , 1 , 7 , 1 , 13 , 31 , 61 , 189 , 1 , 805 , 1321 , 1973 , 4133 , 7789 , 9735 , 50237 ,0 }; - static ulong[] dim4235Kuo3Init = { 1 , 3 , 7 , 5 , 1 , 39 , 67 , 189 , 139 , 891 , 171 , 693 , 5639 , 12841 , 12223 , 64009 ,0 }; - static ulong[] dim4236Kuo3Init = { 1 , 1 , 3 , 1 , 7 , 1 , 115 , 41 , 283 , 463 , 53 , 1349 , 3233 , 7247 , 28515 , 23931 ,0 }; - static ulong[] dim4237Kuo3Init = { 1 , 3 , 3 , 1 , 25 , 31 , 49 , 177 , 339 , 103 , 701 , 3059 , 6557 , 8669 , 13923 , 46913 ,0 }; - static ulong[] dim4238Kuo3Init = { 1 , 1 , 5 , 5 , 7 , 47 , 7 , 153 , 481 , 1005 , 615 , 2483 , 3519 , 5297 , 21749 , 55945 ,0 }; - static ulong[] dim4239Kuo3Init = { 1 , 3 , 5 , 15 , 15 , 43 , 105 , 121 , 419 , 181 , 1945 , 3501 , 3443 , 5555 , 27925 , 18357 ,0 }; - static ulong[] dim4240Kuo3Init = { 1 , 3 , 3 , 5 , 5 , 63 , 107 , 225 , 17 , 503 , 2033 , 2059 , 2621 , 12675 , 25015 , 15115 ,0 }; - static ulong[] dim4241Kuo3Init = { 1 , 3 , 5 , 13 , 5 , 33 , 39 , 143 , 293 , 793 , 159 , 1349 , 5483 , 9303 , 8269 , 58221 ,0 }; - static ulong[] dim4242Kuo3Init = { 1 , 1 , 1 , 3 , 13 , 21 , 15 , 11 , 489 , 921 , 47 , 7 , 7677 , 3281 , 1339 , 1447 ,0 }; - static ulong[] dim4243Kuo3Init = { 1 , 1 , 3 , 11 , 19 , 61 , 29 , 45 , 355 , 671 , 1029 , 455 , 5611 , 14655 , 22871 , 17303 ,0 }; - static ulong[] dim4244Kuo3Init = { 1 , 1 , 1 , 11 , 3 , 29 , 93 , 83 , 425 , 689 , 437 , 1943 , 457 , 2497 , 2573 , 56827 ,0 }; - static ulong[] dim4245Kuo3Init = { 1 , 3 , 7 , 1 , 3 , 39 , 17 , 243 , 475 , 13 , 199 , 413 , 5503 , 1559 , 8615 , 5339 ,0 }; - static ulong[] dim4246Kuo3Init = { 1 , 1 , 5 , 13 , 7 , 17 , 55 , 243 , 465 , 957 , 1347 , 3247 , 4613 , 10821 , 17377 , 21765 ,0 }; - static ulong[] dim4247Kuo3Init = { 1 , 1 , 3 , 5 , 15 , 49 , 109 , 113 , 19 , 1007 , 967 , 685 , 3195 , 467 , 1269 , 27705 ,0 }; - static ulong[] dim4248Kuo3Init = { 1 , 3 , 3 , 15 , 31 , 25 , 73 , 73 , 483 , 565 , 1739 , 641 , 4085 , 10481 , 30053 , 52773 ,0 }; - static ulong[] dim4249Kuo3Init = { 1 , 1 , 1 , 1 , 31 , 17 , 35 , 85 , 339 , 93 , 479 , 2833 , 681 , 3123 , 3753 , 63989 ,0 }; - static ulong[] dim4250Kuo3Init = { 1 , 3 , 7 , 5 , 25 , 17 , 23 , 47 , 83 , 59 , 1525 , 2445 , 4831 , 2605 , 20711 , 34129 ,0 }; - static ulong[] dim4251Kuo3Init = { 1 , 3 , 7 , 9 , 11 , 29 , 111 , 239 , 81 , 855 , 2039 , 4051 , 4619 , 14095 , 15765 , 17195 ,0 }; - static ulong[] dim4252Kuo3Init = { 1 , 1 , 5 , 9 , 17 , 29 , 105 , 175 , 497 , 741 , 1151 , 767 , 7211 , 14699 , 9351 , 22163 ,0 }; - static ulong[] dim4253Kuo3Init = { 1 , 1 , 3 , 9 , 23 , 17 , 23 , 193 , 25 , 883 , 347 , 2429 , 4023 , 5477 , 9365 , 30625 ,0 }; - static ulong[] dim4254Kuo3Init = { 1 , 1 , 7 , 13 , 31 , 57 , 115 , 119 , 413 , 733 , 1095 , 3877 , 4021 , 8415 , 16129 , 49425 ,0 }; - static ulong[] dim4255Kuo3Init = { 1 , 3 , 1 , 3 , 13 , 39 , 127 , 97 , 389 , 993 , 1941 , 847 , 5109 , 8499 , 18653 , 20615 ,0 }; - static ulong[] dim4256Kuo3Init = { 1 , 1 , 3 , 7 , 9 , 33 , 21 , 11 , 357 , 653 , 1423 , 3525 , 277 , 13085 , 2525 , 16547 ,0 }; - static ulong[] dim4257Kuo3Init = { 1 , 3 , 3 , 1 , 3 , 63 , 55 , 137 , 229 , 359 , 703 , 2555 , 3117 , 9323 , 3483 , 52999 ,0 }; - static ulong[] dim4258Kuo3Init = { 1 , 3 , 7 , 1 , 23 , 7 , 67 , 119 , 239 , 951 , 495 , 645 , 3047 , 12393 , 14837 , 33015 ,0 }; - static ulong[] dim4259Kuo3Init = { 1 , 1 , 5 , 15 , 23 , 33 , 19 , 75 , 365 , 419 , 905 , 3485 , 1097 , 10639 , 8627 , 57441 ,0 }; - static ulong[] dim4260Kuo3Init = { 1 , 1 , 3 , 3 , 5 , 37 , 83 , 163 , 483 , 403 , 1467 , 309 , 5113 , 3567 , 28425 , 63963 ,0 }; - static ulong[] dim4261Kuo3Init = { 1 , 3 , 3 , 15 , 21 , 63 , 59 , 103 , 261 , 355 , 1779 , 1589 , 7447 , 10909 , 23197 , 31539 ,0 }; - static ulong[] dim4262Kuo3Init = { 1 , 1 , 3 , 11 , 9 , 39 , 121 , 7 , 383 , 975 , 179 , 505 , 1551 , 15397 , 28277 , 53023 ,0 }; - static ulong[] dim4263Kuo3Init = { 1 , 1 , 5 , 3 , 31 , 15 , 29 , 81 , 291 , 843 , 507 , 1291 , 4533 , 5333 , 18841 , 58999 ,0 }; - static ulong[] dim4264Kuo3Init = { 1 , 3 , 1 , 3 , 3 , 15 , 107 , 93 , 15 , 349 , 1359 , 151 , 4859 , 10435 , 3669 , 31713 ,0 }; - static ulong[] dim4265Kuo3Init = { 1 , 3 , 5 , 1 , 21 , 1 , 45 , 167 , 25 , 123 , 905 , 115 , 2953 , 15029 , 31475 , 37235 ,0 }; - static ulong[] dim4266Kuo3Init = { 1 , 3 , 5 , 11 , 9 , 35 , 115 , 49 , 61 , 29 , 1529 , 1311 , 6293 , 13505 , 15033 , 31879 ,0 }; - static ulong[] dim4267Kuo3Init = { 1 , 3 , 1 , 1 , 1 , 19 , 21 , 199 , 489 , 463 , 1761 , 2295 , 2011 , 14179 , 22955 , 22451 ,0 }; - static ulong[] dim4268Kuo3Init = { 1 , 3 , 1 , 3 , 21 , 59 , 71 , 27 , 425 , 459 , 177 , 2301 , 4703 , 5589 , 12799 , 44729 ,0 }; - static ulong[] dim4269Kuo3Init = { 1 , 3 , 7 , 15 , 11 , 43 , 103 , 207 , 315 , 805 , 469 , 4009 , 4589 , 9627 , 13309 , 929 ,0 }; - static ulong[] dim4270Kuo3Init = { 1 , 3 , 5 , 15 , 3 , 45 , 49 , 59 , 25 , 371 , 859 , 2687 , 3767 , 7395 , 24579 , 2657 ,0 }; - static ulong[] dim4271Kuo3Init = { 1 , 3 , 3 , 1 , 13 , 1 , 39 , 115 , 497 , 291 , 1187 , 3109 , 6731 , 7591 , 2551 , 49121 ,0 }; - static ulong[] dim4272Kuo3Init = { 1 , 3 , 1 , 1 , 11 , 37 , 75 , 39 , 377 , 67 , 291 , 1275 , 7893 , 16261 , 27093 , 30007 ,0 }; - static ulong[] dim4273Kuo3Init = { 1 , 1 , 5 , 15 , 27 , 31 , 117 , 145 , 435 , 739 , 1855 , 2703 , 6125 , 16333 , 16209 , 11649 ,0 }; - static ulong[] dim4274Kuo3Init = { 1 , 3 , 5 , 7 , 5 , 37 , 3 , 173 , 461 , 535 , 295 , 3097 , 6275 , 15703 , 20079 , 45413 ,0 }; - static ulong[] dim4275Kuo3Init = { 1 , 1 , 5 , 13 , 9 , 39 , 39 , 113 , 113 , 315 , 697 , 2433 , 7637 , 9895 , 17979 , 13837 ,0 }; - static ulong[] dim4276Kuo3Init = { 1 , 1 , 7 , 11 , 7 , 35 , 113 , 255 , 309 , 389 , 757 , 1649 , 1871 , 311 , 3531 , 15617 ,0 }; - static ulong[] dim4277Kuo3Init = { 1 , 1 , 7 , 5 , 25 , 7 , 87 , 99 , 249 , 687 , 57 , 2291 , 3315 , 14677 , 15225 , 16859 ,0 }; - static ulong[] dim4278Kuo3Init = { 1 , 1 , 7 , 1 , 11 , 23 , 91 , 25 , 209 , 227 , 567 , 183 , 7419 , 9873 , 10653 , 41705 ,0 }; - static ulong[] dim4279Kuo3Init = { 1 , 1 , 1 , 13 , 19 , 17 , 47 , 79 , 187 , 185 , 187 , 3959 , 4221 , 389 , 1733 , 62413 ,0 }; - static ulong[] dim4280Kuo3Init = { 1 , 3 , 7 , 9 , 1 , 27 , 109 , 59 , 223 , 451 , 865 , 3623 , 2545 , 6531 , 14837 , 40749 ,0 }; - static ulong[] dim4281Kuo3Init = { 1 , 1 , 3 , 7 , 5 , 9 , 69 , 201 , 145 , 445 , 1787 , 1995 , 691 , 11387 , 21391 , 19185 ,0 }; - static ulong[] dim4282Kuo3Init = { 1 , 3 , 7 , 3 , 15 , 31 , 61 , 121 , 295 , 93 , 1157 , 2821 , 2907 , 6995 , 17563 , 4613 ,0 }; - static ulong[] dim4283Kuo3Init = { 1 , 3 , 5 , 3 , 3 , 41 , 43 , 199 , 319 , 903 , 1699 , 3599 , 6567 , 12851 , 21253 , 49715 ,0 }; - static ulong[] dim4284Kuo3Init = { 1 , 1 , 5 , 1 , 25 , 59 , 7 , 107 , 405 , 365 , 1159 , 2357 , 1645 , 16353 , 31521 , 13587 ,0 }; - static ulong[] dim4285Kuo3Init = { 1 , 3 , 3 , 1 , 29 , 25 , 109 , 181 , 475 , 117 , 809 , 2741 , 5113 , 9973 , 31763 , 20201 ,0 }; - static ulong[] dim4286Kuo3Init = { 1 , 3 , 3 , 9 , 29 , 43 , 51 , 239 , 359 , 137 , 419 , 43 , 4091 , 11107 , 2121 , 5057 ,0 }; - static ulong[] dim4287Kuo3Init = { 1 , 3 , 1 , 7 , 13 , 17 , 65 , 151 , 289 , 37 , 1321 , 3853 , 7513 , 3161 , 6517 , 27777 ,0 }; - static ulong[] dim4288Kuo3Init = { 1 , 1 , 3 , 13 , 13 , 31 , 125 , 13 , 507 , 491 , 669 , 2913 , 8067 , 4257 , 11413 , 8003 ,0 }; - static ulong[] dim4289Kuo3Init = { 1 , 1 , 7 , 1 , 23 , 57 , 125 , 227 , 341 , 647 , 907 , 1503 , 1541 , 14311 , 10591 , 49967 ,0 }; - static ulong[] dim4290Kuo3Init = { 1 , 3 , 1 , 15 , 25 , 29 , 83 , 39 , 141 , 545 , 1213 , 2001 , 6627 , 8701 , 19205 , 2859 ,0 }; - static ulong[] dim4291Kuo3Init = { 1 , 1 , 7 , 13 , 11 , 25 , 93 , 91 , 471 , 907 , 793 , 3045 , 8137 , 5095 , 12445 , 41967 ,0 }; - static ulong[] dim4292Kuo3Init = { 1 , 1 , 5 , 1 , 25 , 45 , 13 , 191 , 373 , 371 , 1321 , 3381 , 3945 , 9097 , 7785 , 44469 ,0 }; - static ulong[] dim4293Kuo3Init = { 1 , 3 , 3 , 13 , 13 , 19 , 53 , 189 , 183 , 115 , 1957 , 91 , 113 , 5839 , 23783 , 63959 ,0 }; - static ulong[] dim4294Kuo3Init = { 1 , 3 , 1 , 7 , 3 , 19 , 71 , 219 , 393 , 369 , 107 , 3729 , 7457 , 12379 , 28647 , 54159 ,0 }; - static ulong[] dim4295Kuo3Init = { 1 , 1 , 1 , 9 , 5 , 43 , 15 , 125 , 297 , 145 , 1837 , 2143 , 305 , 793 , 14663 , 313 ,0 }; - static ulong[] dim4296Kuo3Init = { 1 , 3 , 1 , 5 , 17 , 57 , 67 , 51 , 211 , 817 , 2023 , 1615 , 4379 , 12165 , 30433 , 44479 ,0 }; - static ulong[] dim4297Kuo3Init = { 1 , 1 , 7 , 1 , 9 , 49 , 71 , 231 , 159 , 179 , 2027 , 4043 , 1053 , 3679 , 9035 , 4173 ,0 }; - static ulong[] dim4298Kuo3Init = { 1 , 3 , 7 , 3 , 17 , 5 , 33 , 151 , 223 , 331 , 1777 , 2467 , 7949 , 2571 , 9099 , 58751 ,0 }; - static ulong[] dim4299Kuo3Init = { 1 , 3 , 1 , 15 , 5 , 23 , 85 , 113 , 369 , 607 , 505 , 1791 , 1597 , 12933 , 28853 , 13207 ,0 }; - static ulong[] dim4300Kuo3Init = { 1 , 1 , 5 , 15 , 11 , 39 , 107 , 81 , 345 , 815 , 2025 , 803 , 1779 , 15499 , 26197 , 6045 ,0 }; - static ulong[] dim4301Kuo3Init = { 1 , 3 , 1 , 9 , 1 , 3 , 41 , 29 , 213 , 295 , 1561 , 2631 , 6231 , 3255 , 11309 , 22853 ,0 }; - static ulong[] dim4302Kuo3Init = { 1 , 3 , 7 , 9 , 19 , 21 , 127 , 57 , 425 , 551 , 171 , 903 , 7747 , 5251 , 11457 , 57735 ,0 }; - static ulong[] dim4303Kuo3Init = { 1 , 1 , 1 , 11 , 29 , 5 , 33 , 221 , 91 , 435 , 1341 , 1627 , 4269 , 8689 , 19 , 9609 ,0 }; - static ulong[] dim4304Kuo3Init = { 1 , 3 , 1 , 9 , 11 , 1 , 101 , 219 , 45 , 317 , 793 , 823 , 2449 , 7911 , 3739 , 2441 ,0 }; - static ulong[] dim4305Kuo3Init = { 1 , 3 , 5 , 7 , 25 , 51 , 103 , 179 , 481 , 999 , 675 , 1693 , 193 , 9987 , 18519 , 16777 ,0 }; - static ulong[] dim4306Kuo3Init = { 1 , 3 , 5 , 5 , 15 , 59 , 83 , 61 , 329 , 537 , 1293 , 459 , 5059 , 7943 , 3569 , 34727 ,0 }; - static ulong[] dim4307Kuo3Init = { 1 , 3 , 3 , 9 , 29 , 17 , 41 , 171 , 303 , 123 , 1945 , 1383 , 5823 , 1569 , 10699 , 14585 ,0 }; - static ulong[] dim4308Kuo3Init = { 1 , 1 , 1 , 11 , 7 , 11 , 35 , 193 , 69 , 487 , 879 , 693 , 6367 , 7381 , 11463 , 50741 ,0 }; - static ulong[] dim4309Kuo3Init = { 1 , 3 , 1 , 11 , 9 , 17 , 5 , 155 , 443 , 543 , 643 , 1595 , 319 , 2877 , 27849 , 8365 ,0 }; - static ulong[] dim4310Kuo3Init = { 1 , 3 , 7 , 15 , 3 , 43 , 111 , 219 , 35 , 595 , 541 , 3299 , 4117 , 265 , 2817 , 60825 ,0 }; - static ulong[] dim4311Kuo3Init = { 1 , 3 , 5 , 5 , 13 , 15 , 45 , 211 , 21 , 1019 , 1015 , 1051 , 2879 , 15077 , 19851 , 6615 ,0 }; - static ulong[] dim4312Kuo3Init = { 1 , 1 , 7 , 13 , 15 , 59 , 7 , 201 , 215 , 217 , 967 , 2013 , 907 , 12073 , 9105 , 44873 ,0 }; - static ulong[] dim4313Kuo3Init = { 1 , 1 , 1 , 13 , 1 , 3 , 117 , 253 , 493 , 727 , 1997 , 3325 , 2757 , 11313 , 7439 , 18863 ,0 }; - static ulong[] dim4314Kuo3Init = { 1 , 1 , 7 , 11 , 5 , 23 , 97 , 169 , 63 , 243 , 419 , 3259 , 2521 , 13055 , 3223 , 36055 ,0 }; - static ulong[] dim4315Kuo3Init = { 1 , 1 , 5 , 9 , 9 , 9 , 63 , 69 , 305 , 391 , 1901 , 2785 , 7877 , 7219 , 10727 , 13115 ,0 }; - static ulong[] dim4316Kuo3Init = { 1 , 1 , 3 , 7 , 1 , 63 , 83 , 27 , 417 , 537 , 1969 , 3083 , 4267 , 11153 , 11205 , 61249 ,0 }; - static ulong[] dim4317Kuo3Init = { 1 , 3 , 3 , 1 , 11 , 47 , 79 , 201 , 449 , 569 , 809 , 1575 , 271 , 651 , 5459 , 24805 ,0 }; - static ulong[] dim4318Kuo3Init = { 1 , 3 , 7 , 15 , 29 , 25 , 103 , 95 , 57 , 209 , 1175 , 2579 , 3735 , 1969 , 29903 , 65397 ,0 }; - static ulong[] dim4319Kuo3Init = { 1 , 3 , 5 , 1 , 25 , 41 , 7 , 239 , 175 , 395 , 1261 , 2567 , 4875 , 279 , 25905 , 43603 ,0 }; - static ulong[] dim4320Kuo3Init = { 1 , 3 , 7 , 1 , 27 , 7 , 89 , 111 , 467 , 691 , 39 , 1213 , 5377 , 13247 , 31513 , 58015 ,0 }; - static ulong[] dim4321Kuo3Init = { 1 , 1 , 1 , 15 , 25 , 1 , 55 , 131 , 259 , 923 , 1623 , 125 , 2273 , 4221 , 21857 , 49621 ,0 }; - static ulong[] dim4322Kuo3Init = { 1 , 1 , 5 , 3 , 27 , 1 , 99 , 95 , 199 , 773 , 87 , 2981 , 8127 , 6493 , 27507 , 52789 ,0 }; - static ulong[] dim4323Kuo3Init = { 1 , 1 , 5 , 9 , 11 , 39 , 7 , 7 , 145 , 933 , 1301 , 2975 , 5237 , 11619 , 1423 , 46351 ,0 }; - static ulong[] dim4324Kuo3Init = { 1 , 1 , 7 , 5 , 17 , 3 , 29 , 233 , 195 , 727 , 1893 , 3709 , 1285 , 12877 , 30821 , 30383 ,0 }; - static ulong[] dim4325Kuo3Init = { 1 , 3 , 7 , 15 , 1 , 7 , 115 , 55 , 231 , 769 , 849 , 1043 , 3041 , 5187 , 14613 , 58821 ,0 }; - static ulong[] dim4326Kuo3Init = { 1 , 3 , 7 , 3 , 13 , 41 , 5 , 245 , 109 , 785 , 187 , 391 , 3333 , 8193 , 823 , 27985 ,0 }; - static ulong[] dim4327Kuo3Init = { 1 , 1 , 5 , 11 , 9 , 33 , 25 , 231 , 347 , 313 , 31 , 59 , 6189 , 4249 , 26963 , 56975 ,0 }; - static ulong[] dim4328Kuo3Init = { 1 , 1 , 5 , 5 , 27 , 57 , 87 , 77 , 209 , 231 , 173 , 3691 , 8095 , 10353 , 14217 , 3263 ,0 }; - static ulong[] dim4329Kuo3Init = { 1 , 3 , 1 , 7 , 1 , 55 , 115 , 63 , 13 , 705 , 865 , 1901 , 4209 , 8195 , 25245 , 2313 ,0 }; - static ulong[] dim4330Kuo3Init = { 1 , 3 , 5 , 1 , 13 , 3 , 53 , 215 , 345 , 635 , 1601 , 241 , 6491 , 911 , 5825 , 34247 ,0 }; - static ulong[] dim4331Kuo3Init = { 1 , 1 , 5 , 5 , 27 , 21 , 69 , 83 , 451 , 33 , 773 , 2663 , 5325 , 16207 , 15073 , 32259 ,0 }; - static ulong[] dim4332Kuo3Init = { 1 , 1 , 3 , 9 , 25 , 33 , 1 , 35 , 335 , 355 , 2005 , 3087 , 4577 , 10533 , 23641 , 45297 ,0 }; - static ulong[] dim4333Kuo3Init = { 1 , 3 , 3 , 7 , 21 , 43 , 103 , 223 , 269 , 781 , 1445 , 461 , 6777 , 5251 , 6483 , 14425 ,0 }; - static ulong[] dim4334Kuo3Init = { 1 , 3 , 7 , 7 , 21 , 55 , 113 , 227 , 227 , 173 , 575 , 3187 , 3965 , 13569 , 4809 , 16217 ,0 }; - static ulong[] dim4335Kuo3Init = { 1 , 1 , 5 , 5 , 23 , 23 , 67 , 99 , 257 , 651 , 495 , 3427 , 7653 , 505 , 2549 , 9283 ,0 }; - static ulong[] dim4336Kuo3Init = { 1 , 1 , 5 , 5 , 15 , 39 , 123 , 27 , 1 , 5 , 107 , 4055 , 7347 , 6411 , 28857 , 45591 ,0 }; - static ulong[] dim4337Kuo3Init = { 1 , 3 , 1 , 5 , 29 , 57 , 77 , 67 , 365 , 25 , 1475 , 3583 , 4315 , 6725 , 22635 , 62003 ,0 }; - static ulong[] dim4338Kuo3Init = { 1 , 3 , 1 , 1 , 11 , 9 , 19 , 25 , 399 , 467 , 501 , 2081 , 977 , 7695 , 12997 , 11841 ,0 }; - static ulong[] dim4339Kuo3Init = { 1 , 1 , 5 , 15 , 19 , 37 , 39 , 69 , 75 , 343 , 525 , 433 , 6771 , 8697 , 6041 , 49701 ,0 }; - static ulong[] dim4340Kuo3Init = { 1 , 1 , 3 , 1 , 21 , 31 , 5 , 193 , 467 , 161 , 929 , 3967 , 2629 , 3031 , 30715 , 45539 ,0 }; - static ulong[] dim4341Kuo3Init = { 1 , 3 , 3 , 9 , 25 , 17 , 87 , 179 , 385 , 491 , 965 , 2809 , 6937 , 2669 , 20963 , 13333 ,0 }; - static ulong[] dim4342Kuo3Init = { 1 , 3 , 1 , 7 , 25 , 1 , 83 , 47 , 99 , 425 , 1007 , 2903 , 2959 , 12403 , 19707 , 60863 ,0 }; - static ulong[] dim4343Kuo3Init = { 1 , 1 , 1 , 15 , 5 , 19 , 3 , 181 , 255 , 135 , 791 , 3473 , 3123 , 5247 , 28349 , 5581 ,0 }; - static ulong[] dim4344Kuo3Init = { 1 , 1 , 5 , 13 , 27 , 13 , 93 , 215 , 333 , 667 , 251 , 2027 , 6345 , 8985 , 22669 , 46509 ,0 }; - static ulong[] dim4345Kuo3Init = { 1 , 1 , 5 , 9 , 1 , 27 , 83 , 107 , 339 , 699 , 1197 , 635 , 2367 , 6791 , 9743 , 9685 ,0 }; - static ulong[] dim4346Kuo3Init = { 1 , 3 , 1 , 7 , 11 , 43 , 9 , 37 , 511 , 177 , 1957 , 2697 , 1879 , 8219 , 27525 , 17737 ,0 }; - static ulong[] dim4347Kuo3Init = { 1 , 3 , 1 , 5 , 3 , 35 , 81 , 137 , 193 , 439 , 35 , 3743 , 2973 , 10245 , 17111 , 12025 ,0 }; - static ulong[] dim4348Kuo3Init = { 1 , 3 , 3 , 9 , 3 , 51 , 7 , 103 , 65 , 787 , 1859 , 1217 , 8189 , 2917 , 2161 , 64559 ,0 }; - static ulong[] dim4349Kuo3Init = { 1 , 3 , 5 , 5 , 31 , 9 , 53 , 45 , 167 , 877 , 1169 , 2375 , 6631 , 9699 , 8345 , 27223 ,0 }; - static ulong[] dim4350Kuo3Init = { 1 , 3 , 5 , 9 , 1 , 33 , 113 , 205 , 153 , 255 , 63 , 1517 , 5225 , 14485 , 22053 , 53333 ,0 }; - static ulong[] dim4351Kuo3Init = { 1 , 1 , 1 , 1 , 7 , 45 , 95 , 211 , 13 , 769 , 1909 , 1049 , 2465 , 11581 , 2983 , 55267 ,0 }; - static ulong[] dim4352Kuo3Init = { 1 , 1 , 5 , 3 , 7 , 27 , 3 , 47 , 503 , 7 , 1223 , 1979 , 815 , 12593 , 4229 , 30539 ,0 }; - static ulong[] dim4353Kuo3Init = { 1 , 3 , 7 , 15 , 9 , 3 , 103 , 217 , 199 , 567 , 943 , 1527 , 7191 , 15243 , 26311 , 44263 ,0 }; - static ulong[] dim4354Kuo3Init = { 1 , 3 , 5 , 11 , 29 , 13 , 107 , 107 , 35 , 367 , 849 , 4047 , 6027 , 8155 , 10963 , 9941 ,0 }; - static ulong[] dim4355Kuo3Init = { 1 , 1 , 7 , 1 , 27 , 49 , 89 , 59 , 479 , 477 , 1351 , 2165 , 7611 , 9745 , 7023 , 22153 ,0 }; - static ulong[] dim4356Kuo3Init = { 1 , 1 , 3 , 1 , 5 , 7 , 21 , 91 , 13 , 547 , 493 , 813 , 4325 , 751 , 14753 , 52131 ,0 }; - static ulong[] dim4357Kuo3Init = { 1 , 3 , 1 , 3 , 23 , 7 , 55 , 69 , 335 , 127 , 1669 , 2171 , 6033 , 3713 , 16855 , 36479 ,0 }; - static ulong[] dim4358Kuo3Init = { 1 , 3 , 3 , 9 , 17 , 35 , 117 , 85 , 415 , 1019 , 15 , 3033 , 2933 , 2113 , 10909 , 107 ,0 }; - static ulong[] dim4359Kuo3Init = { 1 , 1 , 7 , 3 , 13 , 45 , 61 , 31 , 115 , 569 , 21 , 375 , 1955 , 10699 , 17307 , 20119 ,0 }; - static ulong[] dim4360Kuo3Init = { 1 , 1 , 1 , 13 , 29 , 29 , 101 , 137 , 457 , 845 , 39 , 461 , 5113 , 1429 , 25443 , 60127 ,0 }; - static ulong[] dim4361Kuo3Init = { 1 , 1 , 1 , 3 , 29 , 39 , 35 , 45 , 269 , 327 , 2023 , 2799 , 4893 , 3751 , 7579 , 56975 ,0 }; - static ulong[] dim4362Kuo3Init = { 1 , 1 , 3 , 3 , 3 , 49 , 45 , 219 , 133 , 279 , 2003 , 4007 , 409 , 3697 , 11629 , 19359 ,0 }; - static ulong[] dim4363Kuo3Init = { 1 , 3 , 5 , 9 , 25 , 21 , 85 , 61 , 131 , 69 , 1277 , 249 , 6265 , 10245 , 32575 , 59735 ,0 }; - static ulong[] dim4364Kuo3Init = { 1 , 3 , 5 , 7 , 1 , 11 , 63 , 125 , 57 , 17 , 111 , 3521 , 7397 , 10985 , 10193 , 45493 ,0 }; - static ulong[] dim4365Kuo3Init = { 1 , 3 , 5 , 13 , 31 , 37 , 115 , 139 , 203 , 199 , 559 , 67 , 7187 , 5825 , 6755 , 43 ,0 }; - static ulong[] dim4366Kuo3Init = { 1 , 3 , 3 , 15 , 7 , 33 , 41 , 59 , 487 , 711 , 247 , 1095 , 4113 , 11349 , 26331 , 33159 ,0 }; - static ulong[] dim4367Kuo3Init = { 1 , 3 , 7 , 15 , 25 , 61 , 57 , 129 , 409 , 589 , 1913 , 1293 , 7981 , 8027 , 789 , 19655 ,0 }; - static ulong[] dim4368Kuo3Init = { 1 , 1 , 5 , 11 , 29 , 33 , 55 , 165 , 315 , 757 , 1213 , 2071 , 4827 , 6905 , 7087 , 22317 ,0 }; - static ulong[] dim4369Kuo3Init = { 1 , 3 , 3 , 1 , 5 , 7 , 115 , 161 , 247 , 91 , 397 , 1889 , 2445 , 13407 , 20077 , 50953 ,0 }; - static ulong[] dim4370Kuo3Init = { 1 , 1 , 5 , 1 , 31 , 43 , 53 , 67 , 183 , 85 , 285 , 475 , 3345 , 7783 , 25383 , 26213 ,0 }; - static ulong[] dim4371Kuo3Init = { 1 , 1 , 1 , 3 , 21 , 27 , 127 , 229 , 135 , 795 , 287 , 937 , 5645 , 2271 , 26095 , 18407 ,0 }; - static ulong[] dim4372Kuo3Init = { 1 , 3 , 5 , 13 , 27 , 39 , 109 , 183 , 1 , 343 , 695 , 3825 , 4347 , 8399 , 30219 , 41839 ,0 }; - static ulong[] dim4373Kuo3Init = { 1 , 1 , 1 , 3 , 31 , 3 , 93 , 139 , 145 , 107 , 1311 , 1919 , 6631 , 16363 , 17473 , 38661 ,0 }; - static ulong[] dim4374Kuo3Init = { 1 , 3 , 3 , 1 , 23 , 7 , 17 , 131 , 505 , 335 , 19 , 1037 , 6985 , 15181 , 24857 , 37363 ,0 }; - static ulong[] dim4375Kuo3Init = { 1 , 3 , 7 , 13 , 5 , 17 , 51 , 243 , 221 , 149 , 801 , 3179 , 1929 , 14145 , 16541 , 36911 ,0 }; - static ulong[] dim4376Kuo3Init = { 1 , 3 , 1 , 7 , 15 , 5 , 19 , 93 , 117 , 21 , 1517 , 2041 , 5281 , 7579 , 23087 , 37619 ,0 }; - static ulong[] dim4377Kuo3Init = { 1 , 3 , 5 , 1 , 21 , 33 , 5 , 187 , 471 , 483 , 249 , 1075 , 4831 , 5467 , 2921 , 60803 ,0 }; - static ulong[] dim4378Kuo3Init = { 1 , 1 , 1 , 1 , 27 , 57 , 23 , 185 , 397 , 945 , 495 , 2097 , 7561 , 1111 , 30773 , 61855 ,0 }; - static ulong[] dim4379Kuo3Init = { 1 , 1 , 5 , 5 , 31 , 53 , 71 , 125 , 365 , 947 , 1685 , 2871 , 313 , 5199 , 11179 , 18717 ,0 }; - static ulong[] dim4380Kuo3Init = { 1 , 3 , 7 , 13 , 23 , 41 , 83 , 79 , 427 , 877 , 281 , 3205 , 865 , 8021 , 3423 , 28111 ,0 }; - static ulong[] dim4381Kuo3Init = { 1 , 1 , 3 , 1 , 29 , 39 , 11 , 247 , 45 , 339 , 1153 , 1179 , 6495 , 6861 , 15247 , 44515 ,0 }; - static ulong[] dim4382Kuo3Init = { 1 , 3 , 1 , 1 , 1 , 21 , 41 , 211 , 379 , 99 , 887 , 2035 , 847 , 4679 , 9941 , 49585 ,0 }; - static ulong[] dim4383Kuo3Init = { 1 , 3 , 1 , 11 , 17 , 59 , 29 , 23 , 355 , 393 , 323 , 1843 , 1373 , 1995 , 28417 , 12167 ,0 }; - static ulong[] dim4384Kuo3Init = { 1 , 3 , 7 , 1 , 31 , 55 , 105 , 239 , 509 , 709 , 415 , 4015 , 4597 , 13861 , 11553 , 87 ,0 }; - static ulong[] dim4385Kuo3Init = { 1 , 3 , 7 , 15 , 25 , 55 , 13 , 19 , 333 , 371 , 1829 , 3879 , 7199 , 2849 , 16885 , 52575 ,0 }; - static ulong[] dim4386Kuo3Init = { 1 , 3 , 5 , 9 , 27 , 23 , 55 , 109 , 465 , 923 , 905 , 197 , 4017 , 2079 , 10775 , 55543 ,0 }; - static ulong[] dim4387Kuo3Init = { 1 , 1 , 3 , 7 , 31 , 49 , 69 , 181 , 261 , 71 , 1727 , 2717 , 317 , 13397 , 26641 , 37783 ,0 }; - static ulong[] dim4388Kuo3Init = { 1 , 3 , 3 , 15 , 17 , 55 , 107 , 201 , 21 , 279 , 437 , 3267 , 999 , 14787 , 23727 , 2563 ,0 }; - static ulong[] dim4389Kuo3Init = { 1 , 3 , 1 , 13 , 27 , 41 , 19 , 153 , 435 , 577 , 327 , 965 , 7899 , 11799 , 4683 , 49651 ,0 }; - static ulong[] dim4390Kuo3Init = { 1 , 3 , 5 , 15 , 25 , 47 , 13 , 243 , 281 , 201 , 1455 , 2369 , 7947 , 10993 , 14715 , 30099 ,0 }; - static ulong[] dim4391Kuo3Init = { 1 , 1 , 3 , 11 , 17 , 1 , 49 , 205 , 303 , 85 , 823 , 3721 , 3155 , 5473 , 6019 , 24837 ,0 }; - static ulong[] dim4392Kuo3Init = { 1 , 3 , 1 , 7 , 5 , 27 , 65 , 177 , 405 , 841 , 1523 , 43 , 2309 , 14041 , 6705 , 18145 ,0 }; - static ulong[] dim4393Kuo3Init = { 1 , 1 , 7 , 3 , 25 , 35 , 53 , 177 , 233 , 287 , 1265 , 3305 , 4961 , 2751 , 8715 , 56605 ,0 }; - static ulong[] dim4394Kuo3Init = { 1 , 3 , 5 , 3 , 7 , 9 , 45 , 179 , 65 , 153 , 1861 , 111 , 5501 , 3671 , 25663 , 46493 ,0 }; - static ulong[] dim4395Kuo3Init = { 1 , 3 , 5 , 11 , 11 , 37 , 25 , 199 , 339 , 313 , 1823 , 2933 , 6459 , 3359 , 8577 , 64109 ,0 }; - static ulong[] dim4396Kuo3Init = { 1 , 3 , 1 , 11 , 5 , 3 , 127 , 53 , 77 , 431 , 931 , 3159 , 2267 , 8123 , 7581 , 52237 ,0 }; - static ulong[] dim4397Kuo3Init = { 1 , 1 , 5 , 3 , 1 , 51 , 41 , 147 , 481 , 243 , 2045 , 3239 , 8191 , 7533 , 25021 , 46359 ,0 }; - static ulong[] dim4398Kuo3Init = { 1 , 1 , 1 , 7 , 17 , 1 , 57 , 141 , 239 , 375 , 23 , 3695 , 827 , 10783 , 18109 , 54029 ,0 }; - static ulong[] dim4399Kuo3Init = { 1 , 3 , 1 , 1 , 13 , 39 , 35 , 251 , 271 , 461 , 313 , 2807 , 2927 , 4639 , 17175 , 65325 ,0 }; - static ulong[] dim4400Kuo3Init = { 1 , 1 , 7 , 15 , 1 , 9 , 123 , 243 , 451 , 433 , 1339 , 1223 , 3399 , 12669 , 20663 , 27505 ,0 }; - static ulong[] dim4401Kuo3Init = { 1 , 1 , 1 , 5 , 31 , 25 , 41 , 225 , 61 , 525 , 527 , 1559 , 5469 , 2299 , 3169 , 12435 ,0 }; - static ulong[] dim4402Kuo3Init = { 1 , 1 , 7 , 1 , 3 , 45 , 21 , 99 , 89 , 97 , 379 , 1815 , 5883 , 9437 , 32597 , 14795 ,0 }; - static ulong[] dim4403Kuo3Init = { 1 , 3 , 3 , 3 , 5 , 17 , 109 , 185 , 389 , 291 , 1041 , 847 , 957 , 13413 , 29763 , 39789 ,0 }; - static ulong[] dim4404Kuo3Init = { 1 , 3 , 5 , 7 , 31 , 39 , 63 , 181 , 297 , 71 , 199 , 1655 , 1497 , 8981 , 23785 , 40839 ,0 }; - static ulong[] dim4405Kuo3Init = { 1 , 3 , 5 , 13 , 23 , 15 , 25 , 9 , 361 , 151 , 1191 , 943 , 17 , 715 , 28593 , 22609 ,0 }; - static ulong[] dim4406Kuo3Init = { 1 , 3 , 7 , 3 , 27 , 13 , 99 , 109 , 97 , 415 , 1515 , 701 , 7153 , 14207 , 24417 , 52673 ,0 }; - static ulong[] dim4407Kuo3Init = { 1 , 1 , 1 , 9 , 15 , 15 , 15 , 251 , 23 , 717 , 219 , 1783 , 3657 , 10141 , 6525 , 37683 ,0 }; - static ulong[] dim4408Kuo3Init = { 1 , 1 , 1 , 1 , 5 , 55 , 19 , 213 , 99 , 73 , 227 , 2029 , 1225 , 14849 , 17073 , 30409 ,0 }; - static ulong[] dim4409Kuo3Init = { 1 , 1 , 3 , 3 , 15 , 49 , 49 , 11 , 289 , 287 , 999 , 743 , 1081 , 3185 , 30613 , 25163 ,0 }; - static ulong[] dim4410Kuo3Init = { 1 , 1 , 3 , 11 , 15 , 21 , 33 , 53 , 465 , 45 , 113 , 2865 , 2641 , 13797 , 27785 , 63159 ,0 }; - static ulong[] dim4411Kuo3Init = { 1 , 1 , 7 , 13 , 27 , 5 , 41 , 21 , 53 , 675 , 1217 , 239 , 7925 , 6659 , 15025 , 56589 ,0 }; - static ulong[] dim4412Kuo3Init = { 1 , 1 , 3 , 15 , 15 , 1 , 7 , 129 , 377 , 1017 , 1015 , 329 , 3153 , 5815 , 7929 , 62579 ,0 }; - static ulong[] dim4413Kuo3Init = { 1 , 1 , 7 , 7 , 19 , 37 , 23 , 115 , 29 , 813 , 1761 , 751 , 3461 , 13027 , 30853 , 51399 ,0 }; - static ulong[] dim4414Kuo3Init = { 1 , 3 , 1 , 15 , 1 , 37 , 125 , 143 , 117 , 33 , 321 , 1917 , 741 , 1281 , 4811 , 30907 ,0 }; - static ulong[] dim4415Kuo3Init = { 1 , 1 , 5 , 9 , 25 , 55 , 43 , 69 , 479 , 37 , 1891 , 325 , 7165 , 11707 , 11663 , 9 ,0 }; - static ulong[] dim4416Kuo3Init = { 1 , 1 , 1 , 7 , 13 , 1 , 37 , 5 , 195 , 959 , 1707 , 3099 , 2295 , 1363 , 14463 , 37013 ,0 }; - static ulong[] dim4417Kuo3Init = { 1 , 1 , 3 , 1 , 17 , 45 , 63 , 189 , 471 , 273 , 633 , 977 , 3377 , 15191 , 25127 , 38949 ,0 }; - static ulong[] dim4418Kuo3Init = { 1 , 3 , 7 , 11 , 11 , 49 , 107 , 237 , 365 , 813 , 841 , 215 , 5087 , 4661 , 8045 , 39713 ,0 }; - static ulong[] dim4419Kuo3Init = { 1 , 1 , 7 , 7 , 11 , 39 , 47 , 23 , 267 , 929 , 709 , 2593 , 3773 , 8435 , 15947 , 43873 ,0 }; - static ulong[] dim4420Kuo3Init = { 1 , 3 , 3 , 1 , 7 , 45 , 109 , 121 , 389 , 15 , 599 , 2887 , 4009 , 13557 , 6845 , 10149 ,0 }; - static ulong[] dim4421Kuo3Init = { 1 , 1 , 7 , 11 , 11 , 45 , 5 , 39 , 401 , 467 , 291 , 1807 , 3711 , 13831 , 11777 , 28543 ,0 }; - static ulong[] dim4422Kuo3Init = { 1 , 3 , 1 , 5 , 29 , 29 , 121 , 33 , 185 , 135 , 479 , 3681 , 4763 , 6915 , 6689 , 45981 ,0 }; - static ulong[] dim4423Kuo3Init = { 1 , 1 , 1 , 13 , 7 , 57 , 53 , 39 , 429 , 985 , 523 , 2245 , 8003 , 3385 , 31869 , 30589 ,0 }; - static ulong[] dim4424Kuo3Init = { 1 , 1 , 5 , 3 , 23 , 21 , 71 , 229 , 83 , 327 , 399 , 1413 , 5321 , 10593 , 19219 , 32837 ,0 }; - static ulong[] dim4425Kuo3Init = { 1 , 3 , 7 , 7 , 31 , 37 , 15 , 119 , 13 , 949 , 1589 , 3247 , 5671 , 2141 , 21189 , 6353 ,0 }; - static ulong[] dim4426Kuo3Init = { 1 , 1 , 1 , 11 , 13 , 25 , 77 , 19 , 261 , 237 , 1651 , 1165 , 4317 , 3265 , 13471 , 34163 ,0 }; - static ulong[] dim4427Kuo3Init = { 1 , 3 , 3 , 3 , 17 , 53 , 97 , 245 , 3 , 177 , 873 , 2273 , 3577 , 10233 , 3615 , 38189 ,0 }; - static ulong[] dim4428Kuo3Init = { 1 , 1 , 7 , 9 , 23 , 63 , 5 , 115 , 55 , 825 , 877 , 101 , 1167 , 10583 , 14171 , 42343 ,0 }; - static ulong[] dim4429Kuo3Init = { 1 , 3 , 7 , 5 , 3 , 25 , 119 , 185 , 295 , 349 , 587 , 2497 , 6103 , 5755 , 25191 , 50015 ,0 }; - static ulong[] dim4430Kuo3Init = { 1 , 1 , 7 , 13 , 11 , 55 , 55 , 37 , 229 , 803 , 911 , 3081 , 1543 , 297 , 187 , 51775 ,0 }; - static ulong[] dim4431Kuo3Init = { 1 , 3 , 1 , 3 , 31 , 53 , 105 , 17 , 219 , 145 , 1129 , 431 , 5651 , 1963 , 693 , 18177 ,0 }; - static ulong[] dim4432Kuo3Init = { 1 , 1 , 7 , 3 , 7 , 29 , 61 , 199 , 101 , 553 , 1765 , 1657 , 1843 , 12557 , 27261 , 4877 ,0 }; - static ulong[] dim4433Kuo3Init = { 1 , 3 , 1 , 13 , 19 , 57 , 33 , 233 , 179 , 437 , 1835 , 3081 , 7241 , 4227 , 18707 , 27027 ,0 }; - static ulong[] dim4434Kuo3Init = { 1 , 1 , 3 , 15 , 7 , 61 , 45 , 55 , 153 , 97 , 1081 , 2937 , 2911 , 3927 , 17915 , 275 ,0 }; - static ulong[] dim4435Kuo3Init = { 1 , 3 , 7 , 15 , 19 , 25 , 95 , 85 , 27 , 589 , 121 , 2003 , 4891 , 6737 , 4835 , 10443 ,0 }; - static ulong[] dim4436Kuo3Init = { 1 , 1 , 5 , 7 , 5 , 61 , 21 , 7 , 439 , 351 , 1119 , 937 , 5517 , 5001 , 18859 , 12427 ,0 }; - static ulong[] dim4437Kuo3Init = { 1 , 1 , 1 , 1 , 13 , 21 , 87 , 73 , 61 , 71 , 885 , 4029 , 2893 , 833 , 18813 , 18617 ,0 }; - static ulong[] dim4438Kuo3Init = { 1 , 1 , 5 , 7 , 23 , 63 , 111 , 159 , 39 , 937 , 719 , 1641 , 7901 , 7349 , 31397 , 38111 ,0 }; - static ulong[] dim4439Kuo3Init = { 1 , 1 , 5 , 9 , 9 , 9 , 105 , 33 , 205 , 829 , 1929 , 1925 , 1735 , 10217 , 1747 , 38351 ,0 }; - static ulong[] dim4440Kuo3Init = { 1 , 3 , 1 , 13 , 9 , 13 , 111 , 39 , 465 , 635 , 989 , 2079 , 7781 , 13229 , 1039 , 21061 ,0 }; - static ulong[] dim4441Kuo3Init = { 1 , 3 , 3 , 1 , 29 , 15 , 123 , 137 , 75 , 561 , 1699 , 57 , 8179 , 5693 , 6333 , 25581 ,0 }; - static ulong[] dim4442Kuo3Init = { 1 , 1 , 7 , 9 , 3 , 17 , 27 , 117 , 95 , 287 , 1313 , 1863 , 7119 , 16253 , 27931 , 42341 ,0 }; - static ulong[] dim4443Kuo3Init = { 1 , 1 , 1 , 11 , 21 , 47 , 83 , 79 , 451 , 535 , 1249 , 1125 , 5387 , 11309 , 12115 , 45877 ,0 }; - static ulong[] dim4444Kuo3Init = { 1 , 1 , 3 , 7 , 21 , 17 , 93 , 125 , 467 , 465 , 619 , 1899 , 5501 , 233 , 28371 , 7199 ,0 }; - static ulong[] dim4445Kuo3Init = { 1 , 3 , 7 , 9 , 3 , 5 , 5 , 111 , 107 , 95 , 2023 , 3529 , 5135 , 3377 , 22025 , 41931 ,0 }; - static ulong[] dim4446Kuo3Init = { 1 , 1 , 3 , 13 , 31 , 19 , 115 , 155 , 349 , 911 , 1893 , 3617 , 689 , 16323 , 13523 , 20373 ,0 }; - static ulong[] dim4447Kuo3Init = { 1 , 1 , 3 , 5 , 25 , 7 , 57 , 117 , 65 , 469 , 1669 , 407 , 3693 , 1743 , 16697 , 30749 ,0 }; - static ulong[] dim4448Kuo3Init = { 1 , 1 , 1 , 5 , 29 , 11 , 117 , 187 , 13 , 77 , 45 , 39 , 6237 , 9899 , 28805 , 9389 ,0 }; - static ulong[] dim4449Kuo3Init = { 1 , 3 , 1 , 5 , 5 , 33 , 43 , 45 , 331 , 615 , 961 , 2143 , 4403 , 543 , 22783 , 47063 ,0 }; - static ulong[] dim4450Kuo3Init = { 1 , 3 , 1 , 11 , 7 , 1 , 93 , 153 , 417 , 859 , 451 , 1211 , 6439 , 8043 , 5759 , 60265 ,0 }; - static ulong[] dim4451Kuo3Init = { 1 , 3 , 1 , 9 , 19 , 53 , 57 , 93 , 295 , 773 , 533 , 2685 , 7429 , 2855 , 7665 , 46257 ,0 }; - static ulong[] dim4452Kuo3Init = { 1 , 3 , 5 , 15 , 29 , 5 , 93 , 159 , 7 , 845 , 337 , 881 , 2529 , 15677 , 9795 , 31347 ,0 }; - static ulong[] dim4453Kuo3Init = { 1 , 1 , 3 , 3 , 11 , 49 , 97 , 59 , 157 , 695 , 65 , 1865 , 4107 , 15283 , 2309 , 13841 ,0 }; - static ulong[] dim4454Kuo3Init = { 1 , 3 , 3 , 15 , 21 , 31 , 61 , 85 , 361 , 893 , 1223 , 259 , 2771 , 4973 , 18661 , 16653 ,0 }; - static ulong[] dim4455Kuo3Init = { 1 , 1 , 1 , 7 , 19 , 31 , 3 , 223 , 151 , 785 , 447 , 2123 , 3377 , 14159 , 933 , 23357 ,0 }; - static ulong[] dim4456Kuo3Init = { 1 , 3 , 5 , 11 , 1 , 55 , 77 , 107 , 245 , 193 , 583 , 2729 , 831 , 11019 , 25433 , 6541 ,0 }; - static ulong[] dim4457Kuo3Init = { 1 , 3 , 3 , 9 , 3 , 35 , 19 , 127 , 419 , 203 , 1869 , 1477 , 5239 , 6113 , 4835 , 21131 ,0 }; - static ulong[] dim4458Kuo3Init = { 1 , 3 , 3 , 7 , 17 , 49 , 17 , 23 , 111 , 65 , 1603 , 157 , 6433 , 2965 , 19845 , 59041 ,0 }; - static ulong[] dim4459Kuo3Init = { 1 , 3 , 1 , 3 , 17 , 1 , 17 , 207 , 245 , 129 , 1309 , 413 , 6933 , 7575 , 17179 , 24075 ,0 }; - static ulong[] dim4460Kuo3Init = { 1 , 1 , 5 , 5 , 29 , 23 , 65 , 43 , 157 , 569 , 645 , 1821 , 605 , 3925 , 2863 , 55361 ,0 }; - static ulong[] dim4461Kuo3Init = { 1 , 3 , 3 , 5 , 15 , 43 , 1 , 149 , 253 , 529 , 37 , 2589 , 2851 , 2529 , 32689 , 49303 ,0 }; - static ulong[] dim4462Kuo3Init = { 1 , 3 , 1 , 15 , 3 , 29 , 19 , 241 , 153 , 189 , 161 , 797 , 5419 , 11269 , 2159 , 57893 ,0 }; - static ulong[] dim4463Kuo3Init = { 1 , 1 , 3 , 13 , 19 , 23 , 49 , 179 , 459 , 701 , 1003 , 2673 , 1729 , 1901 , 26003 , 51441 ,0 }; - static ulong[] dim4464Kuo3Init = { 1 , 1 , 3 , 9 , 23 , 19 , 47 , 85 , 281 , 371 , 773 , 2263 , 3235 , 647 , 23085 , 10053 ,0 }; - static ulong[] dim4465Kuo3Init = { 1 , 3 , 3 , 13 , 13 , 23 , 13 , 95 , 41 , 963 , 213 , 2317 , 3889 , 3981 , 4749 , 55409 ,0 }; - static ulong[] dim4466Kuo3Init = { 1 , 1 , 7 , 13 , 9 , 39 , 33 , 21 , 17 , 201 , 1789 , 2593 , 1373 , 14601 , 17025 , 31861 ,0 }; - static ulong[] dim4467Kuo3Init = { 1 , 1 , 5 , 9 , 5 , 43 , 107 , 169 , 247 , 361 , 1245 , 2371 , 119 , 4987 , 32661 , 19363 ,0 }; - static ulong[] dim4468Kuo3Init = { 1 , 3 , 7 , 5 , 29 , 35 , 81 , 13 , 419 , 1003 , 701 , 759 , 4415 , 11441 , 28985 , 46869 ,0 }; - static ulong[] dim4469Kuo3Init = { 1 , 3 , 7 , 7 , 9 , 57 , 3 , 39 , 457 , 455 , 29 , 2983 , 4879 , 14359 , 12913 , 64711 ,0 }; - static ulong[] dim4470Kuo3Init = { 1 , 1 , 7 , 3 , 9 , 31 , 57 , 47 , 55 , 525 , 2015 , 2053 , 7101 , 8487 , 26865 , 29149 ,0 }; - static ulong[] dim4471Kuo3Init = { 1 , 1 , 7 , 11 , 11 , 37 , 67 , 241 , 509 , 711 , 263 , 1565 , 6803 , 2095 , 3055 , 28847 ,0 }; - static ulong[] dim4472Kuo3Init = { 1 , 3 , 1 , 9 , 25 , 23 , 53 , 135 , 391 , 625 , 673 , 2807 , 6511 , 7465 , 21959 , 17561 ,0 }; - static ulong[] dim4473Kuo3Init = { 1 , 1 , 7 , 3 , 23 , 23 , 47 , 247 , 297 , 191 , 1137 , 3921 , 3669 , 4439 , 707 , 33529 ,0 }; - static ulong[] dim4474Kuo3Init = { 1 , 1 , 7 , 15 , 19 , 35 , 91 , 75 , 237 , 585 , 1047 , 1389 , 7147 , 9043 , 22363 , 14287 ,0 }; - static ulong[] dim4475Kuo3Init = { 1 , 3 , 1 , 15 , 17 , 35 , 45 , 181 , 439 , 307 , 709 , 2925 , 3397 , 4577 , 30645 , 25167 ,0 }; - static ulong[] dim4476Kuo3Init = { 1 , 1 , 5 , 9 , 25 , 1 , 127 , 173 , 397 , 477 , 821 , 2017 , 1363 , 8615 , 8833 , 12771 ,0 }; - static ulong[] dim4477Kuo3Init = { 1 , 1 , 5 , 9 , 9 , 1 , 33 , 137 , 383 , 465 , 1211 , 3563 , 5035 , 6609 , 31667 , 10853 ,0 }; - static ulong[] dim4478Kuo3Init = { 1 , 3 , 7 , 9 , 11 , 49 , 61 , 51 , 31 , 811 , 623 , 2213 , 7131 , 15679 , 5335 , 53001 ,0 }; - static ulong[] dim4479Kuo3Init = { 1 , 1 , 5 , 7 , 27 , 55 , 11 , 229 , 331 , 109 , 109 , 877 , 6087 , 10023 , 22627 , 64253 ,0 }; - static ulong[] dim4480Kuo3Init = { 1 , 1 , 5 , 3 , 11 , 13 , 105 , 31 , 357 , 589 , 869 , 1583 , 3441 , 15783 , 25579 , 25335 ,0 }; - static ulong[] dim4481Kuo3Init = { 1 , 3 , 7 , 7 , 7 , 9 , 35 , 29 , 153 , 425 , 1145 , 2021 , 115 , 15865 , 4305 , 62417 ,0 }; - static ulong[] dim4482Kuo3Init = { 1 , 3 , 5 , 3 , 27 , 17 , 3 , 57 , 111 , 393 , 711 , 2519 , 7223 , 10117 , 5509 , 63361 ,0 }; - static ulong[] dim4483Kuo3Init = { 1 , 1 , 5 , 7 , 9 , 55 , 101 , 199 , 441 , 141 , 1349 , 3017 , 7625 , 1457 , 27947 , 13269 ,0 }; - static ulong[] dim4484Kuo3Init = { 1 , 1 , 5 , 15 , 5 , 23 , 3 , 87 , 61 , 19 , 1449 , 2317 , 4049 , 3397 , 6271 , 53317 ,0 }; - static ulong[] dim4485Kuo3Init = { 1 , 3 , 5 , 3 , 11 , 35 , 95 , 141 , 355 , 749 , 1247 , 3495 , 5719 , 16201 , 9649 , 12395 ,0 }; - static ulong[] dim4486Kuo3Init = { 1 , 3 , 7 , 11 , 23 , 29 , 79 , 171 , 259 , 923 , 2035 , 783 , 3571 , 14987 , 30025 , 19185 ,0 }; - static ulong[] dim4487Kuo3Init = { 1 , 1 , 7 , 13 , 17 , 31 , 75 , 141 , 131 , 391 , 303 , 2641 , 5527 , 12629 , 1097 , 47589 ,0 }; - static ulong[] dim4488Kuo3Init = { 1 , 3 , 3 , 15 , 9 , 55 , 23 , 207 , 211 , 633 , 805 , 3079 , 5495 , 4651 , 26483 , 59323 ,0 }; - static ulong[] dim4489Kuo3Init = { 1 , 1 , 1 , 9 , 9 , 17 , 97 , 173 , 123 , 139 , 595 , 3859 , 4615 , 15565 , 9243 , 19933 ,0 }; - static ulong[] dim4490Kuo3Init = { 1 , 3 , 5 , 9 , 31 , 51 , 1 , 133 , 213 , 877 , 23 , 3661 , 3451 , 11705 , 27943 , 10995 ,0 }; - static ulong[] dim4491Kuo3Init = { 1 , 3 , 3 , 11 , 5 , 1 , 91 , 113 , 147 , 825 , 795 , 2871 , 5175 , 6843 , 17829 , 25375 ,0 }; - static ulong[] dim4492Kuo3Init = { 1 , 3 , 3 , 3 , 7 , 15 , 105 , 227 , 97 , 985 , 347 , 2833 , 1237 , 9419 , 17853 , 43467 ,0 }; - static ulong[] dim4493Kuo3Init = { 1 , 3 , 7 , 7 , 17 , 47 , 3 , 237 , 97 , 915 , 1463 , 477 , 2237 , 7755 , 11779 , 35897 ,0 }; - static ulong[] dim4494Kuo3Init = { 1 , 3 , 1 , 9 , 17 , 17 , 97 , 163 , 181 , 411 , 1145 , 623 , 3017 , 1335 , 6999 , 57149 ,0 }; - static ulong[] dim4495Kuo3Init = { 1 , 1 , 1 , 7 , 27 , 49 , 57 , 49 , 217 , 635 , 973 , 1153 , 8097 , 4669 , 30691 , 1949 ,0 }; - static ulong[] dim4496Kuo3Init = { 1 , 1 , 1 , 7 , 13 , 47 , 107 , 247 , 269 , 803 , 1919 , 3047 , 2967 , 63 , 12287 , 39925 ,0 }; - static ulong[] dim4497Kuo3Init = { 1 , 1 , 5 , 3 , 27 , 15 , 27 , 255 , 27 , 463 , 621 , 2443 , 5615 , 14589 , 10869 , 5013 ,0 }; - static ulong[] dim4498Kuo3Init = { 1 , 3 , 5 , 15 , 25 , 15 , 75 , 223 , 17 , 227 , 911 , 3069 , 2583 , 8811 , 14191 , 2819 ,0 }; - static ulong[] dim4499Kuo3Init = { 1 , 3 , 5 , 15 , 25 , 13 , 19 , 157 , 495 , 997 , 1997 , 3175 , 1515 , 15693 , 15585 , 2753 ,0 }; - static ulong[] dim4500Kuo3Init = { 1 , 1 , 7 , 7 , 7 , 5 , 67 , 95 , 337 , 539 , 2019 , 2009 , 7171 , 1089 , 7955 , 17557 ,0 }; - static ulong[] dim4501Kuo3Init = { 1 , 3 , 3 , 3 , 7 , 63 , 61 , 31 , 61 , 483 , 365 , 1153 , 495 , 7357 , 2831 , 23191 ,0 }; - static ulong[] dim4502Kuo3Init = { 1 , 1 , 7 , 1 , 17 , 35 , 121 , 143 , 411 , 895 , 1859 , 2205 , 6565 , 11611 , 20941 , 47151 ,0 }; - static ulong[] dim4503Kuo3Init = { 1 , 3 , 7 , 9 , 27 , 21 , 53 , 51 , 77 , 251 , 1355 , 175 , 3949 , 2903 , 26991 , 41571 ,0 }; - static ulong[] dim4504Kuo3Init = { 1 , 1 , 1 , 15 , 17 , 1 , 15 , 253 , 99 , 611 , 1949 , 1917 , 4363 , 2887 , 30421 , 42197 ,0 }; - static ulong[] dim4505Kuo3Init = { 1 , 3 , 3 , 11 , 29 , 45 , 111 , 49 , 389 , 171 , 1069 , 3061 , 6657 , 12097 , 533 , 9459 ,0 }; - static ulong[] dim4506Kuo3Init = { 1 , 1 , 3 , 1 , 5 , 27 , 39 , 15 , 381 , 119 , 137 , 3641 , 8047 , 1391 , 13093 , 50659 ,0 }; - static ulong[] dim4507Kuo3Init = { 1 , 1 , 7 , 9 , 27 , 59 , 123 , 235 , 301 , 933 , 335 , 3927 , 2811 , 16133 , 5999 , 19933 ,0 }; - static ulong[] dim4508Kuo3Init = { 1 , 3 , 3 , 13 , 15 , 55 , 69 , 199 , 353 , 131 , 753 , 2765 , 4005 , 13575 , 16607 , 51253 ,0 }; - static ulong[] dim4509Kuo3Init = { 1 , 1 , 7 , 1 , 19 , 53 , 31 , 233 , 289 , 939 , 31 , 1741 , 5467 , 1987 , 13923 , 49857 ,0 }; - static ulong[] dim4510Kuo3Init = { 1 , 1 , 7 , 7 , 31 , 45 , 45 , 237 , 427 , 305 , 1753 , 1237 , 3573 , 10813 , 10609 , 24187 ,0 }; - static ulong[] dim4511Kuo3Init = { 1 , 1 , 1 , 13 , 21 , 41 , 81 , 219 , 185 , 107 , 71 , 2017 , 6587 , 3351 , 10207 , 10545 ,0 }; - static ulong[] dim4512Kuo3Init = { 1 , 1 , 1 , 5 , 5 , 21 , 127 , 129 , 209 , 313 , 1273 , 3229 , 6733 , 4431 , 7297 , 41569 ,0 }; - static ulong[] dim4513Kuo3Init = { 1 , 1 , 3 , 15 , 17 , 61 , 55 , 127 , 85 , 913 , 1173 , 3837 , 5579 , 10309 , 24659 , 22697 ,0 }; - static ulong[] dim4514Kuo3Init = { 1 , 1 , 3 , 3 , 11 , 11 , 91 , 165 , 367 , 79 , 43 , 679 , 3285 , 15469 , 21511 , 57755 ,0 }; - static ulong[] dim4515Kuo3Init = { 1 , 1 , 1 , 13 , 15 , 1 , 125 , 47 , 101 , 999 , 521 , 543 , 5535 , 10191 , 7497 , 15677 ,0 }; - static ulong[] dim4516Kuo3Init = { 1 , 3 , 3 , 9 , 9 , 15 , 63 , 239 , 471 , 903 , 1473 , 717 , 6547 , 8445 , 20737 , 41457 ,0 }; - static ulong[] dim4517Kuo3Init = { 1 , 1 , 5 , 15 , 13 , 31 , 43 , 93 , 325 , 393 , 373 , 971 , 6045 , 14981 , 28011 , 35997 ,0 }; - static ulong[] dim4518Kuo3Init = { 1 , 3 , 1 , 15 , 11 , 45 , 41 , 35 , 381 , 779 , 443 , 3395 , 2495 , 14795 , 4695 , 22745 ,0 }; - static ulong[] dim4519Kuo3Init = { 1 , 3 , 3 , 7 , 21 , 9 , 89 , 173 , 233 , 935 , 683 , 1533 , 953 , 2627 , 30975 , 43449 ,0 }; - static ulong[] dim4520Kuo3Init = { 1 , 1 , 5 , 3 , 25 , 55 , 107 , 105 , 99 , 959 , 1935 , 3489 , 3671 , 14999 , 11707 , 10285 ,0 }; - static ulong[] dim4521Kuo3Init = { 1 , 3 , 5 , 3 , 31 , 17 , 123 , 119 , 63 , 169 , 1283 , 3691 , 1411 , 3437 , 27941 , 57089 ,0 }; - static ulong[] dim4522Kuo3Init = { 1 , 3 , 3 , 1 , 17 , 9 , 115 , 69 , 481 , 689 , 2007 , 3815 , 4419 , 11249 , 31469 , 55783 ,0 }; - static ulong[] dim4523Kuo3Init = { 1 , 3 , 7 , 15 , 9 , 39 , 65 , 125 , 253 , 413 , 1283 , 2073 , 6563 , 2111 , 22865 , 59393 ,0 }; - static ulong[] dim4524Kuo3Init = { 1 , 3 , 3 , 15 , 19 , 1 , 67 , 253 , 489 , 185 , 297 , 261 , 5203 , 8685 , 10515 , 58595 ,0 }; - static ulong[] dim4525Kuo3Init = { 1 , 1 , 1 , 13 , 23 , 39 , 95 , 233 , 171 , 653 , 2025 , 2285 , 4477 , 9275 , 9717 , 43321 ,0 }; - static ulong[] dim4526Kuo3Init = { 1 , 1 , 7 , 3 , 23 , 35 , 77 , 119 , 193 , 41 , 1057 , 4017 , 235 , 13819 , 7911 , 3981 ,0 }; - static ulong[] dim4527Kuo3Init = { 1 , 3 , 5 , 9 , 15 , 33 , 41 , 221 , 1 , 307 , 1325 , 2899 , 399 , 801 , 24611 , 31941 ,0 }; - static ulong[] dim4528Kuo3Init = { 1 , 1 , 1 , 15 , 1 , 7 , 91 , 27 , 247 , 667 , 483 , 573 , 481 , 11771 , 31139 , 31979 ,0 }; - static ulong[] dim4529Kuo3Init = { 1 , 3 , 5 , 1 , 3 , 23 , 39 , 73 , 101 , 367 , 1259 , 4053 , 3055 , 1231 , 27981 , 54287 ,0 }; - static ulong[] dim4530Kuo3Init = { 1 , 3 , 3 , 7 , 3 , 31 , 9 , 71 , 339 , 33 , 1255 , 1353 , 5575 , 12481 , 27881 , 17293 ,0 }; - static ulong[] dim4531Kuo3Init = { 1 , 3 , 5 , 13 , 5 , 57 , 123 , 193 , 443 , 185 , 851 , 539 , 4217 , 915 , 1247 , 20163 ,0 }; - static ulong[] dim4532Kuo3Init = { 1 , 3 , 7 , 5 , 11 , 13 , 99 , 141 , 439 , 259 , 1177 , 453 , 6037 , 5813 , 25147 , 20381 ,0 }; - static ulong[] dim4533Kuo3Init = { 1 , 1 , 1 , 5 , 25 , 17 , 105 , 91 , 33 , 15 , 2035 , 3693 , 2249 , 5825 , 29037 , 12529 ,0 }; - static ulong[] dim4534Kuo3Init = { 1 , 3 , 1 , 13 , 1 , 33 , 113 , 237 , 13 , 845 , 1127 , 4067 , 825 , 8391 , 1269 , 51473 ,0 }; - static ulong[] dim4535Kuo3Init = { 1 , 3 , 5 , 3 , 27 , 5 , 77 , 97 , 33 , 569 , 1327 , 751 , 2817 , 775 , 32275 , 55757 ,0 }; - static ulong[] dim4536Kuo3Init = { 1 , 1 , 1 , 7 , 25 , 1 , 73 , 105 , 19 , 1007 , 371 , 269 , 4833 , 13881 , 21503 , 35303 ,0 }; - static ulong[] dim4537Kuo3Init = { 1 , 3 , 1 , 3 , 23 , 39 , 27 , 203 , 351 , 433 , 399 , 405 , 39 , 7773 , 27345 , 57109 ,0 }; - static ulong[] dim4538Kuo3Init = { 1 , 1 , 5 , 13 , 7 , 7 , 21 , 33 , 481 , 201 , 7 , 2377 , 1009 , 7593 , 19381 , 10325 ,0 }; - static ulong[] dim4539Kuo3Init = { 1 , 1 , 1 , 13 , 15 , 61 , 29 , 59 , 255 , 213 , 1207 , 3783 , 4375 , 8137 , 6733 , 10809 ,0 }; - static ulong[] dim4540Kuo3Init = { 1 , 1 , 1 , 9 , 25 , 37 , 83 , 169 , 267 , 21 , 1211 , 3099 , 239 , 2489 , 12843 , 4395 ,0 }; - static ulong[] dim4541Kuo3Init = { 1 , 1 , 1 , 13 , 17 , 47 , 77 , 63 , 361 , 567 , 245 , 3569 , 7707 , 15463 , 29579 , 55017 ,0 }; - static ulong[] dim4542Kuo3Init = { 1 , 1 , 7 , 13 , 23 , 3 , 111 , 21 , 417 , 609 , 547 , 3297 , 7487 , 3285 , 16913 , 34005 ,0 }; - static ulong[] dim4543Kuo3Init = { 1 , 3 , 7 , 5 , 9 , 37 , 39 , 173 , 129 , 215 , 1939 , 2745 , 319 , 12707 , 4665 , 32065 ,0 }; - static ulong[] dim4544Kuo3Init = { 1 , 1 , 3 , 3 , 21 , 39 , 67 , 85 , 223 , 591 , 681 , 1655 , 6651 , 3547 , 22459 , 291 ,0 }; - static ulong[] dim4545Kuo3Init = { 1 , 1 , 7 , 11 , 17 , 9 , 61 , 121 , 489 , 129 , 489 , 1261 , 2377 , 9243 , 15123 , 59249 ,0 }; - static ulong[] dim4546Kuo3Init = { 1 , 1 , 5 , 9 , 1 , 31 , 1 , 171 , 331 , 233 , 1033 , 1975 , 1515 , 13295 , 9383 , 52107 ,0 }; - static ulong[] dim4547Kuo3Init = { 1 , 1 , 1 , 13 , 17 , 45 , 75 , 209 , 187 , 441 , 1227 , 4063 , 5699 , 3397 , 25793 , 58187 ,0 }; - static ulong[] dim4548Kuo3Init = { 1 , 3 , 1 , 3 , 17 , 13 , 67 , 73 , 141 , 451 , 1307 , 3115 , 1273 , 5275 , 32383 , 4663 ,0 }; - static ulong[] dim4549Kuo3Init = { 1 , 1 , 5 , 15 , 5 , 37 , 77 , 159 , 339 , 443 , 1663 , 345 , 1513 , 3195 , 15131 , 32473 ,0 }; - static ulong[] dim4550Kuo3Init = { 1 , 1 , 3 , 11 , 29 , 19 , 13 , 47 , 409 , 141 , 1907 , 3473 , 4799 , 213 , 341 , 45091 ,0 }; - static ulong[] dim4551Kuo3Init = { 1 , 3 , 1 , 1 , 15 , 29 , 27 , 179 , 367 , 439 , 1073 , 1783 , 735 , 11731 , 20101 , 7889 ,0 }; - static ulong[] dim4552Kuo3Init = { 1 , 1 , 3 , 15 , 23 , 35 , 107 , 53 , 325 , 51 , 831 , 1693 , 5161 , 13655 , 31957 , 60089 ,0 }; - static ulong[] dim4553Kuo3Init = { 1 , 1 , 5 , 11 , 31 , 13 , 103 , 109 , 71 , 237 , 1271 , 629 , 6813 , 10253 , 17161 , 58597 ,0 }; - static ulong[] dim4554Kuo3Init = { 1 , 3 , 3 , 1 , 29 , 37 , 47 , 173 , 131 , 787 , 39 , 879 , 215 , 13625 , 4031 , 56677 ,0 }; - static ulong[] dim4555Kuo3Init = { 1 , 1 , 7 , 5 , 29 , 3 , 61 , 227 , 23 , 699 , 1291 , 3909 , 6995 , 4085 , 8961 , 40275 ,0 }; - static ulong[] dim4556Kuo3Init = { 1 , 1 , 5 , 7 , 27 , 21 , 25 , 213 , 359 , 701 , 1453 , 3753 , 5493 , 5971 , 30375 , 54707 ,0 }; - static ulong[] dim4557Kuo3Init = { 1 , 3 , 7 , 7 , 7 , 63 , 67 , 47 , 341 , 451 , 1205 , 3125 , 1575 , 6229 , 13951 , 4539 ,0 }; - static ulong[] dim4558Kuo3Init = { 1 , 1 , 3 , 13 , 25 , 3 , 93 , 91 , 507 , 843 , 623 , 865 , 5873 , 10397 , 4135 , 11313 ,0 }; - static ulong[] dim4559Kuo3Init = { 1 , 3 , 7 , 15 , 11 , 39 , 111 , 149 , 439 , 519 , 1015 , 2777 , 1643 , 9703 , 13767 , 7351 ,0 }; - static ulong[] dim4560Kuo3Init = { 1 , 1 , 5 , 5 , 27 , 55 , 79 , 39 , 23 , 451 , 1507 , 2117 , 6881 , 4623 , 26289 , 23435 ,0 }; - static ulong[] dim4561Kuo3Init = { 1 , 3 , 3 , 11 , 27 , 29 , 21 , 63 , 229 , 173 , 1777 , 2163 , 5185 , 15487 , 19661 , 49185 ,0 }; - static ulong[] dim4562Kuo3Init = { 1 , 3 , 1 , 9 , 3 , 29 , 59 , 63 , 477 , 51 , 1257 , 2301 , 3495 , 9475 , 32201 , 47511 ,0 }; - static ulong[] dim4563Kuo3Init = { 1 , 1 , 1 , 7 , 29 , 45 , 115 , 235 , 201 , 847 , 57 , 1783 , 2203 , 13077 , 4917 , 6773 ,0 }; - static ulong[] dim4564Kuo3Init = { 1 , 1 , 5 , 9 , 13 , 49 , 77 , 1 , 105 , 747 , 1389 , 2461 , 3823 , 3315 , 25295 , 24761 ,0 }; - static ulong[] dim4565Kuo3Init = { 1 , 3 , 7 , 7 , 19 , 5 , 83 , 157 , 37 , 499 , 1893 , 2787 , 6427 , 8575 , 26547 , 28871 ,0 }; - static ulong[] dim4566Kuo3Init = { 1 , 1 , 3 , 9 , 29 , 47 , 109 , 151 , 125 , 1005 , 751 , 2059 , 7045 , 15483 , 5227 , 58193 ,0 }; - static ulong[] dim4567Kuo3Init = { 1 , 1 , 3 , 1 , 11 , 41 , 63 , 155 , 175 , 943 , 161 , 889 , 6001 , 3537 , 23609 , 23595 ,0 }; - static ulong[] dim4568Kuo3Init = { 1 , 3 , 1 , 11 , 5 , 51 , 121 , 11 , 81 , 175 , 1953 , 451 , 4723 , 11083 , 26527 , 41887 ,0 }; - static ulong[] dim4569Kuo3Init = { 1 , 1 , 3 , 7 , 13 , 59 , 47 , 205 , 503 , 249 , 1263 , 1767 , 2553 , 9755 , 909 , 27129 ,0 }; - static ulong[] dim4570Kuo3Init = { 1 , 1 , 5 , 13 , 11 , 19 , 123 , 1 , 429 , 455 , 85 , 1021 , 7119 , 8563 , 11115 , 24741 ,0 }; - static ulong[] dim4571Kuo3Init = { 1 , 1 , 1 , 1 , 5 , 55 , 1 , 1 , 17 , 221 , 1633 , 4065 , 9 , 4091 , 29557 , 33855 ,0 }; - static ulong[] dim4572Kuo3Init = { 1 , 3 , 3 , 11 , 9 , 3 , 15 , 159 , 243 , 245 , 1845 , 3841 , 3321 , 8631 , 1131 , 7327 ,0 }; - static ulong[] dim4573Kuo3Init = { 1 , 1 , 5 , 5 , 3 , 9 , 119 , 99 , 337 , 969 , 1313 , 4083 , 2053 , 10277 , 15941 , 16969 ,0 }; - static ulong[] dim4574Kuo3Init = { 1 , 1 , 7 , 13 , 15 , 35 , 25 , 239 , 345 , 785 , 747 , 233 , 7175 , 10319 , 23783 , 55803 ,0 }; - static ulong[] dim4575Kuo3Init = { 1 , 1 , 7 , 1 , 7 , 5 , 91 , 119 , 317 , 831 , 351 , 2149 , 7531 , 16373 , 23461 , 19863 ,0 }; - static ulong[] dim4576Kuo3Init = { 1 , 1 , 7 , 1 , 29 , 7 , 5 , 43 , 7 , 717 , 1459 , 713 , 5453 , 7471 , 12909 , 36941 ,0 }; - static ulong[] dim4577Kuo3Init = { 1 , 3 , 5 , 15 , 9 , 53 , 59 , 201 , 333 , 603 , 629 , 1819 , 3397 , 2823 , 6459 , 16213 ,0 }; - static ulong[] dim4578Kuo3Init = { 1 , 3 , 1 , 13 , 27 , 47 , 67 , 119 , 145 , 81 , 507 , 53 , 7407 , 6327 , 11387 , 45391 ,0 }; - static ulong[] dim4579Kuo3Init = { 1 , 1 , 7 , 13 , 7 , 63 , 53 , 171 , 381 , 523 , 825 , 2785 , 7077 , 13601 , 329 , 26677 ,0 }; - static ulong[] dim4580Kuo3Init = { 1 , 1 , 5 , 13 , 7 , 25 , 91 , 67 , 267 , 463 , 1869 , 2041 , 5949 , 1635 , 21551 , 37331 ,0 }; - static ulong[] dim4581Kuo3Init = { 1 , 1 , 1 , 5 , 25 , 1 , 17 , 113 , 445 , 685 , 1201 , 3299 , 8139 , 1463 , 26067 , 14613 ,0 }; - static ulong[] dim4582Kuo3Init = { 1 , 3 , 1 , 13 , 3 , 19 , 103 , 159 , 337 , 999 , 755 , 3935 , 5161 , 8681 , 17375 , 20163 ,0 }; - static ulong[] dim4583Kuo3Init = { 1 , 3 , 5 , 9 , 1 , 13 , 117 , 209 , 93 , 613 , 271 , 1321 , 2265 , 2739 , 5055 , 27581 ,0 }; - static ulong[] dim4584Kuo3Init = { 1 , 1 , 1 , 1 , 7 , 21 , 111 , 45 , 361 , 665 , 1243 , 1485 , 7833 , 15515 , 26437 , 55983 ,0 }; - static ulong[] dim4585Kuo3Init = { 1 , 1 , 5 , 7 , 1 , 31 , 123 , 199 , 347 , 235 , 1367 , 2451 , 7211 , 6095 , 19245 , 55993 ,0 }; - static ulong[] dim4586Kuo3Init = { 1 , 3 , 7 , 3 , 25 , 9 , 25 , 117 , 315 , 497 , 1235 , 1969 , 7981 , 9743 , 20951 , 30635 ,0 }; - - static ulong[][] Kuo3initializers = { - dim1Kuo3Init, - dim2Kuo3Init, - dim3Kuo3Init, - dim4Kuo3Init, - dim5Kuo3Init, - dim6Kuo3Init, - dim7Kuo3Init, - dim8Kuo3Init, - dim9Kuo3Init, - dim10Kuo3Init, - dim11Kuo3Init, - dim12Kuo3Init, - dim13Kuo3Init, - dim14Kuo3Init, - dim15Kuo3Init, - dim16Kuo3Init, - dim17Kuo3Init, - dim18Kuo3Init, - dim19Kuo3Init, - dim20Kuo3Init, - dim21Kuo3Init, - dim22Kuo3Init, - dim23Kuo3Init, - dim24Kuo3Init, - dim25Kuo3Init, - dim26Kuo3Init, - dim27Kuo3Init, - dim28Kuo3Init, - dim29Kuo3Init, - dim30Kuo3Init, - dim31Kuo3Init, - dim32Kuo3Init, - dim33Kuo3Init, - dim34Kuo3Init, - dim35Kuo3Init, - dim36Kuo3Init, - dim37Kuo3Init, - dim38Kuo3Init, - dim39Kuo3Init, - dim40Kuo3Init, - dim41Kuo3Init, - dim42Kuo3Init, - dim43Kuo3Init, - dim44Kuo3Init, - dim45Kuo3Init, - dim46Kuo3Init, - dim47Kuo3Init, - dim48Kuo3Init, - dim49Kuo3Init, - dim50Kuo3Init, - dim51Kuo3Init, - dim52Kuo3Init, - dim53Kuo3Init, - dim54Kuo3Init, - dim55Kuo3Init, - dim56Kuo3Init, - dim57Kuo3Init, - dim58Kuo3Init, - dim59Kuo3Init, - dim60Kuo3Init, - dim61Kuo3Init, - dim62Kuo3Init, - dim63Kuo3Init, - dim64Kuo3Init, - dim65Kuo3Init, - dim66Kuo3Init, - dim67Kuo3Init, - dim68Kuo3Init, - dim69Kuo3Init, - dim70Kuo3Init, - dim71Kuo3Init, - dim72Kuo3Init, - dim73Kuo3Init, - dim74Kuo3Init, - dim75Kuo3Init, - dim76Kuo3Init, - dim77Kuo3Init, - dim78Kuo3Init, - dim79Kuo3Init, - dim80Kuo3Init, - dim81Kuo3Init, - dim82Kuo3Init, - dim83Kuo3Init, - dim84Kuo3Init, - dim85Kuo3Init, - dim86Kuo3Init, - dim87Kuo3Init, - dim88Kuo3Init, - dim89Kuo3Init, - dim90Kuo3Init, - dim91Kuo3Init, - dim92Kuo3Init, - dim93Kuo3Init, - dim94Kuo3Init, - dim95Kuo3Init, - dim96Kuo3Init, - dim97Kuo3Init, - dim98Kuo3Init, - dim99Kuo3Init, - dim100Kuo3Init, - dim101Kuo3Init, - dim102Kuo3Init, - dim103Kuo3Init, - dim104Kuo3Init, - dim105Kuo3Init, - dim106Kuo3Init, - dim107Kuo3Init, - dim108Kuo3Init, - dim109Kuo3Init, - dim110Kuo3Init, - dim111Kuo3Init, - dim112Kuo3Init, - dim113Kuo3Init, - dim114Kuo3Init, - dim115Kuo3Init, - dim116Kuo3Init, - dim117Kuo3Init, - dim118Kuo3Init, - dim119Kuo3Init, - dim120Kuo3Init, - dim121Kuo3Init, - dim122Kuo3Init, - dim123Kuo3Init, - dim124Kuo3Init, - dim125Kuo3Init, - dim126Kuo3Init, - dim127Kuo3Init, - dim128Kuo3Init, - dim129Kuo3Init, - dim130Kuo3Init, - dim131Kuo3Init, - dim132Kuo3Init, - dim133Kuo3Init, - dim134Kuo3Init, - dim135Kuo3Init, - dim136Kuo3Init, - dim137Kuo3Init, - dim138Kuo3Init, - dim139Kuo3Init, - dim140Kuo3Init, - dim141Kuo3Init, - dim142Kuo3Init, - dim143Kuo3Init, - dim144Kuo3Init, - dim145Kuo3Init, - dim146Kuo3Init, - dim147Kuo3Init, - dim148Kuo3Init, - dim149Kuo3Init, - dim150Kuo3Init, - dim151Kuo3Init, - dim152Kuo3Init, - dim153Kuo3Init, - dim154Kuo3Init, - dim155Kuo3Init, - dim156Kuo3Init, - dim157Kuo3Init, - dim158Kuo3Init, - dim159Kuo3Init, - dim160Kuo3Init, - dim161Kuo3Init, - dim162Kuo3Init, - dim163Kuo3Init, - dim164Kuo3Init, - dim165Kuo3Init, - dim166Kuo3Init, - dim167Kuo3Init, - dim168Kuo3Init, - dim169Kuo3Init, - dim170Kuo3Init, - dim171Kuo3Init, - dim172Kuo3Init, - dim173Kuo3Init, - dim174Kuo3Init, - dim175Kuo3Init, - dim176Kuo3Init, - dim177Kuo3Init, - dim178Kuo3Init, - dim179Kuo3Init, - dim180Kuo3Init, - dim181Kuo3Init, - dim182Kuo3Init, - dim183Kuo3Init, - dim184Kuo3Init, - dim185Kuo3Init, - dim186Kuo3Init, - dim187Kuo3Init, - dim188Kuo3Init, - dim189Kuo3Init, - dim190Kuo3Init, - dim191Kuo3Init, - dim192Kuo3Init, - dim193Kuo3Init, - dim194Kuo3Init, - dim195Kuo3Init, - dim196Kuo3Init, - dim197Kuo3Init, - dim198Kuo3Init, - dim199Kuo3Init, - dim200Kuo3Init, - dim201Kuo3Init, - dim202Kuo3Init, - dim203Kuo3Init, - dim204Kuo3Init, - dim205Kuo3Init, - dim206Kuo3Init, - dim207Kuo3Init, - dim208Kuo3Init, - dim209Kuo3Init, - dim210Kuo3Init, - dim211Kuo3Init, - dim212Kuo3Init, - dim213Kuo3Init, - dim214Kuo3Init, - dim215Kuo3Init, - dim216Kuo3Init, - dim217Kuo3Init, - dim218Kuo3Init, - dim219Kuo3Init, - dim220Kuo3Init, - dim221Kuo3Init, - dim222Kuo3Init, - dim223Kuo3Init, - dim224Kuo3Init, - dim225Kuo3Init, - dim226Kuo3Init, - dim227Kuo3Init, - dim228Kuo3Init, - dim229Kuo3Init, - dim230Kuo3Init, - dim231Kuo3Init, - dim232Kuo3Init, - dim233Kuo3Init, - dim234Kuo3Init, - dim235Kuo3Init, - dim236Kuo3Init, - dim237Kuo3Init, - dim238Kuo3Init, - dim239Kuo3Init, - dim240Kuo3Init, - dim241Kuo3Init, - dim242Kuo3Init, - dim243Kuo3Init, - dim244Kuo3Init, - dim245Kuo3Init, - dim246Kuo3Init, - dim247Kuo3Init, - dim248Kuo3Init, - dim249Kuo3Init, - dim250Kuo3Init, - dim251Kuo3Init, - dim252Kuo3Init, - dim253Kuo3Init, - dim254Kuo3Init, - dim255Kuo3Init, - dim256Kuo3Init, - dim257Kuo3Init, - dim258Kuo3Init, - dim259Kuo3Init, - dim260Kuo3Init, - dim261Kuo3Init, - dim262Kuo3Init, - dim263Kuo3Init, - dim264Kuo3Init, - dim265Kuo3Init, - dim266Kuo3Init, - dim267Kuo3Init, - dim268Kuo3Init, - dim269Kuo3Init, - dim270Kuo3Init, - dim271Kuo3Init, - dim272Kuo3Init, - dim273Kuo3Init, - dim274Kuo3Init, - dim275Kuo3Init, - dim276Kuo3Init, - dim277Kuo3Init, - dim278Kuo3Init, - dim279Kuo3Init, - dim280Kuo3Init, - dim281Kuo3Init, - dim282Kuo3Init, - dim283Kuo3Init, - dim284Kuo3Init, - dim285Kuo3Init, - dim286Kuo3Init, - dim287Kuo3Init, - dim288Kuo3Init, - dim289Kuo3Init, - dim290Kuo3Init, - dim291Kuo3Init, - dim292Kuo3Init, - dim293Kuo3Init, - dim294Kuo3Init, - dim295Kuo3Init, - dim296Kuo3Init, - dim297Kuo3Init, - dim298Kuo3Init, - dim299Kuo3Init, - dim300Kuo3Init, - dim301Kuo3Init, - dim302Kuo3Init, - dim303Kuo3Init, - dim304Kuo3Init, - dim305Kuo3Init, - dim306Kuo3Init, - dim307Kuo3Init, - dim308Kuo3Init, - dim309Kuo3Init, - dim310Kuo3Init, - dim311Kuo3Init, - dim312Kuo3Init, - dim313Kuo3Init, - dim314Kuo3Init, - dim315Kuo3Init, - dim316Kuo3Init, - dim317Kuo3Init, - dim318Kuo3Init, - dim319Kuo3Init, - dim320Kuo3Init, - dim321Kuo3Init, - dim322Kuo3Init, - dim323Kuo3Init, - dim324Kuo3Init, - dim325Kuo3Init, - dim326Kuo3Init, - dim327Kuo3Init, - dim328Kuo3Init, - dim329Kuo3Init, - dim330Kuo3Init, - dim331Kuo3Init, - dim332Kuo3Init, - dim333Kuo3Init, - dim334Kuo3Init, - dim335Kuo3Init, - dim336Kuo3Init, - dim337Kuo3Init, - dim338Kuo3Init, - dim339Kuo3Init, - dim340Kuo3Init, - dim341Kuo3Init, - dim342Kuo3Init, - dim343Kuo3Init, - dim344Kuo3Init, - dim345Kuo3Init, - dim346Kuo3Init, - dim347Kuo3Init, - dim348Kuo3Init, - dim349Kuo3Init, - dim350Kuo3Init, - dim351Kuo3Init, - dim352Kuo3Init, - dim353Kuo3Init, - dim354Kuo3Init, - dim355Kuo3Init, - dim356Kuo3Init, - dim357Kuo3Init, - dim358Kuo3Init, - dim359Kuo3Init, - dim360Kuo3Init, - dim361Kuo3Init, - dim362Kuo3Init, - dim363Kuo3Init, - dim364Kuo3Init, - dim365Kuo3Init, - dim366Kuo3Init, - dim367Kuo3Init, - dim368Kuo3Init, - dim369Kuo3Init, - dim370Kuo3Init, - dim371Kuo3Init, - dim372Kuo3Init, - dim373Kuo3Init, - dim374Kuo3Init, - dim375Kuo3Init, - dim376Kuo3Init, - dim377Kuo3Init, - dim378Kuo3Init, - dim379Kuo3Init, - dim380Kuo3Init, - dim381Kuo3Init, - dim382Kuo3Init, - dim383Kuo3Init, - dim384Kuo3Init, - dim385Kuo3Init, - dim386Kuo3Init, - dim387Kuo3Init, - dim388Kuo3Init, - dim389Kuo3Init, - dim390Kuo3Init, - dim391Kuo3Init, - dim392Kuo3Init, - dim393Kuo3Init, - dim394Kuo3Init, - dim395Kuo3Init, - dim396Kuo3Init, - dim397Kuo3Init, - dim398Kuo3Init, - dim399Kuo3Init, - dim400Kuo3Init, - dim401Kuo3Init, - dim402Kuo3Init, - dim403Kuo3Init, - dim404Kuo3Init, - dim405Kuo3Init, - dim406Kuo3Init, - dim407Kuo3Init, - dim408Kuo3Init, - dim409Kuo3Init, - dim410Kuo3Init, - dim411Kuo3Init, - dim412Kuo3Init, - dim413Kuo3Init, - dim414Kuo3Init, - dim415Kuo3Init, - dim416Kuo3Init, - dim417Kuo3Init, - dim418Kuo3Init, - dim419Kuo3Init, - dim420Kuo3Init, - dim421Kuo3Init, - dim422Kuo3Init, - dim423Kuo3Init, - dim424Kuo3Init, - dim425Kuo3Init, - dim426Kuo3Init, - dim427Kuo3Init, - dim428Kuo3Init, - dim429Kuo3Init, - dim430Kuo3Init, - dim431Kuo3Init, - dim432Kuo3Init, - dim433Kuo3Init, - dim434Kuo3Init, - dim435Kuo3Init, - dim436Kuo3Init, - dim437Kuo3Init, - dim438Kuo3Init, - dim439Kuo3Init, - dim440Kuo3Init, - dim441Kuo3Init, - dim442Kuo3Init, - dim443Kuo3Init, - dim444Kuo3Init, - dim445Kuo3Init, - dim446Kuo3Init, - dim447Kuo3Init, - dim448Kuo3Init, - dim449Kuo3Init, - dim450Kuo3Init, - dim451Kuo3Init, - dim452Kuo3Init, - dim453Kuo3Init, - dim454Kuo3Init, - dim455Kuo3Init, - dim456Kuo3Init, - dim457Kuo3Init, - dim458Kuo3Init, - dim459Kuo3Init, - dim460Kuo3Init, - dim461Kuo3Init, - dim462Kuo3Init, - dim463Kuo3Init, - dim464Kuo3Init, - dim465Kuo3Init, - dim466Kuo3Init, - dim467Kuo3Init, - dim468Kuo3Init, - dim469Kuo3Init, - dim470Kuo3Init, - dim471Kuo3Init, - dim472Kuo3Init, - dim473Kuo3Init, - dim474Kuo3Init, - dim475Kuo3Init, - dim476Kuo3Init, - dim477Kuo3Init, - dim478Kuo3Init, - dim479Kuo3Init, - dim480Kuo3Init, - dim481Kuo3Init, - dim482Kuo3Init, - dim483Kuo3Init, - dim484Kuo3Init, - dim485Kuo3Init, - dim486Kuo3Init, - dim487Kuo3Init, - dim488Kuo3Init, - dim489Kuo3Init, - dim490Kuo3Init, - dim491Kuo3Init, - dim492Kuo3Init, - dim493Kuo3Init, - dim494Kuo3Init, - dim495Kuo3Init, - dim496Kuo3Init, - dim497Kuo3Init, - dim498Kuo3Init, - dim499Kuo3Init, - dim500Kuo3Init, - dim501Kuo3Init, - dim502Kuo3Init, - dim503Kuo3Init, - dim504Kuo3Init, - dim505Kuo3Init, - dim506Kuo3Init, - dim507Kuo3Init, - dim508Kuo3Init, - dim509Kuo3Init, - dim510Kuo3Init, - dim511Kuo3Init, - dim512Kuo3Init, - dim513Kuo3Init, - dim514Kuo3Init, - dim515Kuo3Init, - dim516Kuo3Init, - dim517Kuo3Init, - dim518Kuo3Init, - dim519Kuo3Init, - dim520Kuo3Init, - dim521Kuo3Init, - dim522Kuo3Init, - dim523Kuo3Init, - dim524Kuo3Init, - dim525Kuo3Init, - dim526Kuo3Init, - dim527Kuo3Init, - dim528Kuo3Init, - dim529Kuo3Init, - dim530Kuo3Init, - dim531Kuo3Init, - dim532Kuo3Init, - dim533Kuo3Init, - dim534Kuo3Init, - dim535Kuo3Init, - dim536Kuo3Init, - dim537Kuo3Init, - dim538Kuo3Init, - dim539Kuo3Init, - dim540Kuo3Init, - dim541Kuo3Init, - dim542Kuo3Init, - dim543Kuo3Init, - dim544Kuo3Init, - dim545Kuo3Init, - dim546Kuo3Init, - dim547Kuo3Init, - dim548Kuo3Init, - dim549Kuo3Init, - dim550Kuo3Init, - dim551Kuo3Init, - dim552Kuo3Init, - dim553Kuo3Init, - dim554Kuo3Init, - dim555Kuo3Init, - dim556Kuo3Init, - dim557Kuo3Init, - dim558Kuo3Init, - dim559Kuo3Init, - dim560Kuo3Init, - dim561Kuo3Init, - dim562Kuo3Init, - dim563Kuo3Init, - dim564Kuo3Init, - dim565Kuo3Init, - dim566Kuo3Init, - dim567Kuo3Init, - dim568Kuo3Init, - dim569Kuo3Init, - dim570Kuo3Init, - dim571Kuo3Init, - dim572Kuo3Init, - dim573Kuo3Init, - dim574Kuo3Init, - dim575Kuo3Init, - dim576Kuo3Init, - dim577Kuo3Init, - dim578Kuo3Init, - dim579Kuo3Init, - dim580Kuo3Init, - dim581Kuo3Init, - dim582Kuo3Init, - dim583Kuo3Init, - dim584Kuo3Init, - dim585Kuo3Init, - dim586Kuo3Init, - dim587Kuo3Init, - dim588Kuo3Init, - dim589Kuo3Init, - dim590Kuo3Init, - dim591Kuo3Init, - dim592Kuo3Init, - dim593Kuo3Init, - dim594Kuo3Init, - dim595Kuo3Init, - dim596Kuo3Init, - dim597Kuo3Init, - dim598Kuo3Init, - dim599Kuo3Init, - dim600Kuo3Init, - dim601Kuo3Init, - dim602Kuo3Init, - dim603Kuo3Init, - dim604Kuo3Init, - dim605Kuo3Init, - dim606Kuo3Init, - dim607Kuo3Init, - dim608Kuo3Init, - dim609Kuo3Init, - dim610Kuo3Init, - dim611Kuo3Init, - dim612Kuo3Init, - dim613Kuo3Init, - dim614Kuo3Init, - dim615Kuo3Init, - dim616Kuo3Init, - dim617Kuo3Init, - dim618Kuo3Init, - dim619Kuo3Init, - dim620Kuo3Init, - dim621Kuo3Init, - dim622Kuo3Init, - dim623Kuo3Init, - dim624Kuo3Init, - dim625Kuo3Init, - dim626Kuo3Init, - dim627Kuo3Init, - dim628Kuo3Init, - dim629Kuo3Init, - dim630Kuo3Init, - dim631Kuo3Init, - dim632Kuo3Init, - dim633Kuo3Init, - dim634Kuo3Init, - dim635Kuo3Init, - dim636Kuo3Init, - dim637Kuo3Init, - dim638Kuo3Init, - dim639Kuo3Init, - dim640Kuo3Init, - dim641Kuo3Init, - dim642Kuo3Init, - dim643Kuo3Init, - dim644Kuo3Init, - dim645Kuo3Init, - dim646Kuo3Init, - dim647Kuo3Init, - dim648Kuo3Init, - dim649Kuo3Init, - dim650Kuo3Init, - dim651Kuo3Init, - dim652Kuo3Init, - dim653Kuo3Init, - dim654Kuo3Init, - dim655Kuo3Init, - dim656Kuo3Init, - dim657Kuo3Init, - dim658Kuo3Init, - dim659Kuo3Init, - dim660Kuo3Init, - dim661Kuo3Init, - dim662Kuo3Init, - dim663Kuo3Init, - dim664Kuo3Init, - dim665Kuo3Init, - dim666Kuo3Init, - dim667Kuo3Init, - dim668Kuo3Init, - dim669Kuo3Init, - dim670Kuo3Init, - dim671Kuo3Init, - dim672Kuo3Init, - dim673Kuo3Init, - dim674Kuo3Init, - dim675Kuo3Init, - dim676Kuo3Init, - dim677Kuo3Init, - dim678Kuo3Init, - dim679Kuo3Init, - dim680Kuo3Init, - dim681Kuo3Init, - dim682Kuo3Init, - dim683Kuo3Init, - dim684Kuo3Init, - dim685Kuo3Init, - dim686Kuo3Init, - dim687Kuo3Init, - dim688Kuo3Init, - dim689Kuo3Init, - dim690Kuo3Init, - dim691Kuo3Init, - dim692Kuo3Init, - dim693Kuo3Init, - dim694Kuo3Init, - dim695Kuo3Init, - dim696Kuo3Init, - dim697Kuo3Init, - dim698Kuo3Init, - dim699Kuo3Init, - dim700Kuo3Init, - dim701Kuo3Init, - dim702Kuo3Init, - dim703Kuo3Init, - dim704Kuo3Init, - dim705Kuo3Init, - dim706Kuo3Init, - dim707Kuo3Init, - dim708Kuo3Init, - dim709Kuo3Init, - dim710Kuo3Init, - dim711Kuo3Init, - dim712Kuo3Init, - dim713Kuo3Init, - dim714Kuo3Init, - dim715Kuo3Init, - dim716Kuo3Init, - dim717Kuo3Init, - dim718Kuo3Init, - dim719Kuo3Init, - dim720Kuo3Init, - dim721Kuo3Init, - dim722Kuo3Init, - dim723Kuo3Init, - dim724Kuo3Init, - dim725Kuo3Init, - dim726Kuo3Init, - dim727Kuo3Init, - dim728Kuo3Init, - dim729Kuo3Init, - dim730Kuo3Init, - dim731Kuo3Init, - dim732Kuo3Init, - dim733Kuo3Init, - dim734Kuo3Init, - dim735Kuo3Init, - dim736Kuo3Init, - dim737Kuo3Init, - dim738Kuo3Init, - dim739Kuo3Init, - dim740Kuo3Init, - dim741Kuo3Init, - dim742Kuo3Init, - dim743Kuo3Init, - dim744Kuo3Init, - dim745Kuo3Init, - dim746Kuo3Init, - dim747Kuo3Init, - dim748Kuo3Init, - dim749Kuo3Init, - dim750Kuo3Init, - dim751Kuo3Init, - dim752Kuo3Init, - dim753Kuo3Init, - dim754Kuo3Init, - dim755Kuo3Init, - dim756Kuo3Init, - dim757Kuo3Init, - dim758Kuo3Init, - dim759Kuo3Init, - dim760Kuo3Init, - dim761Kuo3Init, - dim762Kuo3Init, - dim763Kuo3Init, - dim764Kuo3Init, - dim765Kuo3Init, - dim766Kuo3Init, - dim767Kuo3Init, - dim768Kuo3Init, - dim769Kuo3Init, - dim770Kuo3Init, - dim771Kuo3Init, - dim772Kuo3Init, - dim773Kuo3Init, - dim774Kuo3Init, - dim775Kuo3Init, - dim776Kuo3Init, - dim777Kuo3Init, - dim778Kuo3Init, - dim779Kuo3Init, - dim780Kuo3Init, - dim781Kuo3Init, - dim782Kuo3Init, - dim783Kuo3Init, - dim784Kuo3Init, - dim785Kuo3Init, - dim786Kuo3Init, - dim787Kuo3Init, - dim788Kuo3Init, - dim789Kuo3Init, - dim790Kuo3Init, - dim791Kuo3Init, - dim792Kuo3Init, - dim793Kuo3Init, - dim794Kuo3Init, - dim795Kuo3Init, - dim796Kuo3Init, - dim797Kuo3Init, - dim798Kuo3Init, - dim799Kuo3Init, - dim800Kuo3Init, - dim801Kuo3Init, - dim802Kuo3Init, - dim803Kuo3Init, - dim804Kuo3Init, - dim805Kuo3Init, - dim806Kuo3Init, - dim807Kuo3Init, - dim808Kuo3Init, - dim809Kuo3Init, - dim810Kuo3Init, - dim811Kuo3Init, - dim812Kuo3Init, - dim813Kuo3Init, - dim814Kuo3Init, - dim815Kuo3Init, - dim816Kuo3Init, - dim817Kuo3Init, - dim818Kuo3Init, - dim819Kuo3Init, - dim820Kuo3Init, - dim821Kuo3Init, - dim822Kuo3Init, - dim823Kuo3Init, - dim824Kuo3Init, - dim825Kuo3Init, - dim826Kuo3Init, - dim827Kuo3Init, - dim828Kuo3Init, - dim829Kuo3Init, - dim830Kuo3Init, - dim831Kuo3Init, - dim832Kuo3Init, - dim833Kuo3Init, - dim834Kuo3Init, - dim835Kuo3Init, - dim836Kuo3Init, - dim837Kuo3Init, - dim838Kuo3Init, - dim839Kuo3Init, - dim840Kuo3Init, - dim841Kuo3Init, - dim842Kuo3Init, - dim843Kuo3Init, - dim844Kuo3Init, - dim845Kuo3Init, - dim846Kuo3Init, - dim847Kuo3Init, - dim848Kuo3Init, - dim849Kuo3Init, - dim850Kuo3Init, - dim851Kuo3Init, - dim852Kuo3Init, - dim853Kuo3Init, - dim854Kuo3Init, - dim855Kuo3Init, - dim856Kuo3Init, - dim857Kuo3Init, - dim858Kuo3Init, - dim859Kuo3Init, - dim860Kuo3Init, - dim861Kuo3Init, - dim862Kuo3Init, - dim863Kuo3Init, - dim864Kuo3Init, - dim865Kuo3Init, - dim866Kuo3Init, - dim867Kuo3Init, - dim868Kuo3Init, - dim869Kuo3Init, - dim870Kuo3Init, - dim871Kuo3Init, - dim872Kuo3Init, - dim873Kuo3Init, - dim874Kuo3Init, - dim875Kuo3Init, - dim876Kuo3Init, - dim877Kuo3Init, - dim878Kuo3Init, - dim879Kuo3Init, - dim880Kuo3Init, - dim881Kuo3Init, - dim882Kuo3Init, - dim883Kuo3Init, - dim884Kuo3Init, - dim885Kuo3Init, - dim886Kuo3Init, - dim887Kuo3Init, - dim888Kuo3Init, - dim889Kuo3Init, - dim890Kuo3Init, - dim891Kuo3Init, - dim892Kuo3Init, - dim893Kuo3Init, - dim894Kuo3Init, - dim895Kuo3Init, - dim896Kuo3Init, - dim897Kuo3Init, - dim898Kuo3Init, - dim899Kuo3Init, - dim900Kuo3Init, - dim901Kuo3Init, - dim902Kuo3Init, - dim903Kuo3Init, - dim904Kuo3Init, - dim905Kuo3Init, - dim906Kuo3Init, - dim907Kuo3Init, - dim908Kuo3Init, - dim909Kuo3Init, - dim910Kuo3Init, - dim911Kuo3Init, - dim912Kuo3Init, - dim913Kuo3Init, - dim914Kuo3Init, - dim915Kuo3Init, - dim916Kuo3Init, - dim917Kuo3Init, - dim918Kuo3Init, - dim919Kuo3Init, - dim920Kuo3Init, - dim921Kuo3Init, - dim922Kuo3Init, - dim923Kuo3Init, - dim924Kuo3Init, - dim925Kuo3Init, - dim926Kuo3Init, - dim927Kuo3Init, - dim928Kuo3Init, - dim929Kuo3Init, - dim930Kuo3Init, - dim931Kuo3Init, - dim932Kuo3Init, - dim933Kuo3Init, - dim934Kuo3Init, - dim935Kuo3Init, - dim936Kuo3Init, - dim937Kuo3Init, - dim938Kuo3Init, - dim939Kuo3Init, - dim940Kuo3Init, - dim941Kuo3Init, - dim942Kuo3Init, - dim943Kuo3Init, - dim944Kuo3Init, - dim945Kuo3Init, - dim946Kuo3Init, - dim947Kuo3Init, - dim948Kuo3Init, - dim949Kuo3Init, - dim950Kuo3Init, - dim951Kuo3Init, - dim952Kuo3Init, - dim953Kuo3Init, - dim954Kuo3Init, - dim955Kuo3Init, - dim956Kuo3Init, - dim957Kuo3Init, - dim958Kuo3Init, - dim959Kuo3Init, - dim960Kuo3Init, - dim961Kuo3Init, - dim962Kuo3Init, - dim963Kuo3Init, - dim964Kuo3Init, - dim965Kuo3Init, - dim966Kuo3Init, - dim967Kuo3Init, - dim968Kuo3Init, - dim969Kuo3Init, - dim970Kuo3Init, - dim971Kuo3Init, - dim972Kuo3Init, - dim973Kuo3Init, - dim974Kuo3Init, - dim975Kuo3Init, - dim976Kuo3Init, - dim977Kuo3Init, - dim978Kuo3Init, - dim979Kuo3Init, - dim980Kuo3Init, - dim981Kuo3Init, - dim982Kuo3Init, - dim983Kuo3Init, - dim984Kuo3Init, - dim985Kuo3Init, - dim986Kuo3Init, - dim987Kuo3Init, - dim988Kuo3Init, - dim989Kuo3Init, - dim990Kuo3Init, - dim991Kuo3Init, - dim992Kuo3Init, - dim993Kuo3Init, - dim994Kuo3Init, - dim995Kuo3Init, - dim996Kuo3Init, - dim997Kuo3Init, - dim998Kuo3Init, - dim999Kuo3Init, - dim1000Kuo3Init, - dim1001Kuo3Init, - dim1002Kuo3Init, - dim1003Kuo3Init, - dim1004Kuo3Init, - dim1005Kuo3Init, - dim1006Kuo3Init, - dim1007Kuo3Init, - dim1008Kuo3Init, - dim1009Kuo3Init, - dim1010Kuo3Init, - dim1011Kuo3Init, - dim1012Kuo3Init, - dim1013Kuo3Init, - dim1014Kuo3Init, - dim1015Kuo3Init, - dim1016Kuo3Init, - dim1017Kuo3Init, - dim1018Kuo3Init, - dim1019Kuo3Init, - dim1020Kuo3Init, - dim1021Kuo3Init, - dim1022Kuo3Init, - dim1023Kuo3Init, - dim1024Kuo3Init, - dim1025Kuo3Init, - dim1026Kuo3Init, - dim1027Kuo3Init, - dim1028Kuo3Init, - dim1029Kuo3Init, - dim1030Kuo3Init, - dim1031Kuo3Init, - dim1032Kuo3Init, - dim1033Kuo3Init, - dim1034Kuo3Init, - dim1035Kuo3Init, - dim1036Kuo3Init, - dim1037Kuo3Init, - dim1038Kuo3Init, - dim1039Kuo3Init, - dim1040Kuo3Init, - dim1041Kuo3Init, - dim1042Kuo3Init, - dim1043Kuo3Init, - dim1044Kuo3Init, - dim1045Kuo3Init, - dim1046Kuo3Init, - dim1047Kuo3Init, - dim1048Kuo3Init, - dim1049Kuo3Init, - dim1050Kuo3Init, - dim1051Kuo3Init, - dim1052Kuo3Init, - dim1053Kuo3Init, - dim1054Kuo3Init, - dim1055Kuo3Init, - dim1056Kuo3Init, - dim1057Kuo3Init, - dim1058Kuo3Init, - dim1059Kuo3Init, - dim1060Kuo3Init, - dim1061Kuo3Init, - dim1062Kuo3Init, - dim1063Kuo3Init, - dim1064Kuo3Init, - dim1065Kuo3Init, - dim1066Kuo3Init, - dim1067Kuo3Init, - dim1068Kuo3Init, - dim1069Kuo3Init, - dim1070Kuo3Init, - dim1071Kuo3Init, - dim1072Kuo3Init, - dim1073Kuo3Init, - dim1074Kuo3Init, - dim1075Kuo3Init, - dim1076Kuo3Init, - dim1077Kuo3Init, - dim1078Kuo3Init, - dim1079Kuo3Init, - dim1080Kuo3Init, - dim1081Kuo3Init, - dim1082Kuo3Init, - dim1083Kuo3Init, - dim1084Kuo3Init, - dim1085Kuo3Init, - dim1086Kuo3Init, - dim1087Kuo3Init, - dim1088Kuo3Init, - dim1089Kuo3Init, - dim1090Kuo3Init, - dim1091Kuo3Init, - dim1092Kuo3Init, - dim1093Kuo3Init, - dim1094Kuo3Init, - dim1095Kuo3Init, - dim1096Kuo3Init, - dim1097Kuo3Init, - dim1098Kuo3Init, - dim1099Kuo3Init, - dim1100Kuo3Init, - dim1101Kuo3Init, - dim1102Kuo3Init, - dim1103Kuo3Init, - dim1104Kuo3Init, - dim1105Kuo3Init, - dim1106Kuo3Init, - dim1107Kuo3Init, - dim1108Kuo3Init, - dim1109Kuo3Init, - dim1110Kuo3Init, - dim1111Kuo3Init, - dim1112Kuo3Init, - dim1113Kuo3Init, - dim1114Kuo3Init, - dim1115Kuo3Init, - dim1116Kuo3Init, - dim1117Kuo3Init, - dim1118Kuo3Init, - dim1119Kuo3Init, - dim1120Kuo3Init, - dim1121Kuo3Init, - dim1122Kuo3Init, - dim1123Kuo3Init, - dim1124Kuo3Init, - dim1125Kuo3Init, - dim1126Kuo3Init, - dim1127Kuo3Init, - dim1128Kuo3Init, - dim1129Kuo3Init, - dim1130Kuo3Init, - dim1131Kuo3Init, - dim1132Kuo3Init, - dim1133Kuo3Init, - dim1134Kuo3Init, - dim1135Kuo3Init, - dim1136Kuo3Init, - dim1137Kuo3Init, - dim1138Kuo3Init, - dim1139Kuo3Init, - dim1140Kuo3Init, - dim1141Kuo3Init, - dim1142Kuo3Init, - dim1143Kuo3Init, - dim1144Kuo3Init, - dim1145Kuo3Init, - dim1146Kuo3Init, - dim1147Kuo3Init, - dim1148Kuo3Init, - dim1149Kuo3Init, - dim1150Kuo3Init, - dim1151Kuo3Init, - dim1152Kuo3Init, - dim1153Kuo3Init, - dim1154Kuo3Init, - dim1155Kuo3Init, - dim1156Kuo3Init, - dim1157Kuo3Init, - dim1158Kuo3Init, - dim1159Kuo3Init, - dim1160Kuo3Init, - dim1161Kuo3Init, - dim1162Kuo3Init, - dim1163Kuo3Init, - dim1164Kuo3Init, - dim1165Kuo3Init, - dim1166Kuo3Init, - dim1167Kuo3Init, - dim1168Kuo3Init, - dim1169Kuo3Init, - dim1170Kuo3Init, - dim1171Kuo3Init, - dim1172Kuo3Init, - dim1173Kuo3Init, - dim1174Kuo3Init, - dim1175Kuo3Init, - dim1176Kuo3Init, - dim1177Kuo3Init, - dim1178Kuo3Init, - dim1179Kuo3Init, - dim1180Kuo3Init, - dim1181Kuo3Init, - dim1182Kuo3Init, - dim1183Kuo3Init, - dim1184Kuo3Init, - dim1185Kuo3Init, - dim1186Kuo3Init, - dim1187Kuo3Init, - dim1188Kuo3Init, - dim1189Kuo3Init, - dim1190Kuo3Init, - dim1191Kuo3Init, - dim1192Kuo3Init, - dim1193Kuo3Init, - dim1194Kuo3Init, - dim1195Kuo3Init, - dim1196Kuo3Init, - dim1197Kuo3Init, - dim1198Kuo3Init, - dim1199Kuo3Init, - dim1200Kuo3Init, - dim1201Kuo3Init, - dim1202Kuo3Init, - dim1203Kuo3Init, - dim1204Kuo3Init, - dim1205Kuo3Init, - dim1206Kuo3Init, - dim1207Kuo3Init, - dim1208Kuo3Init, - dim1209Kuo3Init, - dim1210Kuo3Init, - dim1211Kuo3Init, - dim1212Kuo3Init, - dim1213Kuo3Init, - dim1214Kuo3Init, - dim1215Kuo3Init, - dim1216Kuo3Init, - dim1217Kuo3Init, - dim1218Kuo3Init, - dim1219Kuo3Init, - dim1220Kuo3Init, - dim1221Kuo3Init, - dim1222Kuo3Init, - dim1223Kuo3Init, - dim1224Kuo3Init, - dim1225Kuo3Init, - dim1226Kuo3Init, - dim1227Kuo3Init, - dim1228Kuo3Init, - dim1229Kuo3Init, - dim1230Kuo3Init, - dim1231Kuo3Init, - dim1232Kuo3Init, - dim1233Kuo3Init, - dim1234Kuo3Init, - dim1235Kuo3Init, - dim1236Kuo3Init, - dim1237Kuo3Init, - dim1238Kuo3Init, - dim1239Kuo3Init, - dim1240Kuo3Init, - dim1241Kuo3Init, - dim1242Kuo3Init, - dim1243Kuo3Init, - dim1244Kuo3Init, - dim1245Kuo3Init, - dim1246Kuo3Init, - dim1247Kuo3Init, - dim1248Kuo3Init, - dim1249Kuo3Init, - dim1250Kuo3Init, - dim1251Kuo3Init, - dim1252Kuo3Init, - dim1253Kuo3Init, - dim1254Kuo3Init, - dim1255Kuo3Init, - dim1256Kuo3Init, - dim1257Kuo3Init, - dim1258Kuo3Init, - dim1259Kuo3Init, - dim1260Kuo3Init, - dim1261Kuo3Init, - dim1262Kuo3Init, - dim1263Kuo3Init, - dim1264Kuo3Init, - dim1265Kuo3Init, - dim1266Kuo3Init, - dim1267Kuo3Init, - dim1268Kuo3Init, - dim1269Kuo3Init, - dim1270Kuo3Init, - dim1271Kuo3Init, - dim1272Kuo3Init, - dim1273Kuo3Init, - dim1274Kuo3Init, - dim1275Kuo3Init, - dim1276Kuo3Init, - dim1277Kuo3Init, - dim1278Kuo3Init, - dim1279Kuo3Init, - dim1280Kuo3Init, - dim1281Kuo3Init, - dim1282Kuo3Init, - dim1283Kuo3Init, - dim1284Kuo3Init, - dim1285Kuo3Init, - dim1286Kuo3Init, - dim1287Kuo3Init, - dim1288Kuo3Init, - dim1289Kuo3Init, - dim1290Kuo3Init, - dim1291Kuo3Init, - dim1292Kuo3Init, - dim1293Kuo3Init, - dim1294Kuo3Init, - dim1295Kuo3Init, - dim1296Kuo3Init, - dim1297Kuo3Init, - dim1298Kuo3Init, - dim1299Kuo3Init, - dim1300Kuo3Init, - dim1301Kuo3Init, - dim1302Kuo3Init, - dim1303Kuo3Init, - dim1304Kuo3Init, - dim1305Kuo3Init, - dim1306Kuo3Init, - dim1307Kuo3Init, - dim1308Kuo3Init, - dim1309Kuo3Init, - dim1310Kuo3Init, - dim1311Kuo3Init, - dim1312Kuo3Init, - dim1313Kuo3Init, - dim1314Kuo3Init, - dim1315Kuo3Init, - dim1316Kuo3Init, - dim1317Kuo3Init, - dim1318Kuo3Init, - dim1319Kuo3Init, - dim1320Kuo3Init, - dim1321Kuo3Init, - dim1322Kuo3Init, - dim1323Kuo3Init, - dim1324Kuo3Init, - dim1325Kuo3Init, - dim1326Kuo3Init, - dim1327Kuo3Init, - dim1328Kuo3Init, - dim1329Kuo3Init, - dim1330Kuo3Init, - dim1331Kuo3Init, - dim1332Kuo3Init, - dim1333Kuo3Init, - dim1334Kuo3Init, - dim1335Kuo3Init, - dim1336Kuo3Init, - dim1337Kuo3Init, - dim1338Kuo3Init, - dim1339Kuo3Init, - dim1340Kuo3Init, - dim1341Kuo3Init, - dim1342Kuo3Init, - dim1343Kuo3Init, - dim1344Kuo3Init, - dim1345Kuo3Init, - dim1346Kuo3Init, - dim1347Kuo3Init, - dim1348Kuo3Init, - dim1349Kuo3Init, - dim1350Kuo3Init, - dim1351Kuo3Init, - dim1352Kuo3Init, - dim1353Kuo3Init, - dim1354Kuo3Init, - dim1355Kuo3Init, - dim1356Kuo3Init, - dim1357Kuo3Init, - dim1358Kuo3Init, - dim1359Kuo3Init, - dim1360Kuo3Init, - dim1361Kuo3Init, - dim1362Kuo3Init, - dim1363Kuo3Init, - dim1364Kuo3Init, - dim1365Kuo3Init, - dim1366Kuo3Init, - dim1367Kuo3Init, - dim1368Kuo3Init, - dim1369Kuo3Init, - dim1370Kuo3Init, - dim1371Kuo3Init, - dim1372Kuo3Init, - dim1373Kuo3Init, - dim1374Kuo3Init, - dim1375Kuo3Init, - dim1376Kuo3Init, - dim1377Kuo3Init, - dim1378Kuo3Init, - dim1379Kuo3Init, - dim1380Kuo3Init, - dim1381Kuo3Init, - dim1382Kuo3Init, - dim1383Kuo3Init, - dim1384Kuo3Init, - dim1385Kuo3Init, - dim1386Kuo3Init, - dim1387Kuo3Init, - dim1388Kuo3Init, - dim1389Kuo3Init, - dim1390Kuo3Init, - dim1391Kuo3Init, - dim1392Kuo3Init, - dim1393Kuo3Init, - dim1394Kuo3Init, - dim1395Kuo3Init, - dim1396Kuo3Init, - dim1397Kuo3Init, - dim1398Kuo3Init, - dim1399Kuo3Init, - dim1400Kuo3Init, - dim1401Kuo3Init, - dim1402Kuo3Init, - dim1403Kuo3Init, - dim1404Kuo3Init, - dim1405Kuo3Init, - dim1406Kuo3Init, - dim1407Kuo3Init, - dim1408Kuo3Init, - dim1409Kuo3Init, - dim1410Kuo3Init, - dim1411Kuo3Init, - dim1412Kuo3Init, - dim1413Kuo3Init, - dim1414Kuo3Init, - dim1415Kuo3Init, - dim1416Kuo3Init, - dim1417Kuo3Init, - dim1418Kuo3Init, - dim1419Kuo3Init, - dim1420Kuo3Init, - dim1421Kuo3Init, - dim1422Kuo3Init, - dim1423Kuo3Init, - dim1424Kuo3Init, - dim1425Kuo3Init, - dim1426Kuo3Init, - dim1427Kuo3Init, - dim1428Kuo3Init, - dim1429Kuo3Init, - dim1430Kuo3Init, - dim1431Kuo3Init, - dim1432Kuo3Init, - dim1433Kuo3Init, - dim1434Kuo3Init, - dim1435Kuo3Init, - dim1436Kuo3Init, - dim1437Kuo3Init, - dim1438Kuo3Init, - dim1439Kuo3Init, - dim1440Kuo3Init, - dim1441Kuo3Init, - dim1442Kuo3Init, - dim1443Kuo3Init, - dim1444Kuo3Init, - dim1445Kuo3Init, - dim1446Kuo3Init, - dim1447Kuo3Init, - dim1448Kuo3Init, - dim1449Kuo3Init, - dim1450Kuo3Init, - dim1451Kuo3Init, - dim1452Kuo3Init, - dim1453Kuo3Init, - dim1454Kuo3Init, - dim1455Kuo3Init, - dim1456Kuo3Init, - dim1457Kuo3Init, - dim1458Kuo3Init, - dim1459Kuo3Init, - dim1460Kuo3Init, - dim1461Kuo3Init, - dim1462Kuo3Init, - dim1463Kuo3Init, - dim1464Kuo3Init, - dim1465Kuo3Init, - dim1466Kuo3Init, - dim1467Kuo3Init, - dim1468Kuo3Init, - dim1469Kuo3Init, - dim1470Kuo3Init, - dim1471Kuo3Init, - dim1472Kuo3Init, - dim1473Kuo3Init, - dim1474Kuo3Init, - dim1475Kuo3Init, - dim1476Kuo3Init, - dim1477Kuo3Init, - dim1478Kuo3Init, - dim1479Kuo3Init, - dim1480Kuo3Init, - dim1481Kuo3Init, - dim1482Kuo3Init, - dim1483Kuo3Init, - dim1484Kuo3Init, - dim1485Kuo3Init, - dim1486Kuo3Init, - dim1487Kuo3Init, - dim1488Kuo3Init, - dim1489Kuo3Init, - dim1490Kuo3Init, - dim1491Kuo3Init, - dim1492Kuo3Init, - dim1493Kuo3Init, - dim1494Kuo3Init, - dim1495Kuo3Init, - dim1496Kuo3Init, - dim1497Kuo3Init, - dim1498Kuo3Init, - dim1499Kuo3Init, - dim1500Kuo3Init, - dim1501Kuo3Init, - dim1502Kuo3Init, - dim1503Kuo3Init, - dim1504Kuo3Init, - dim1505Kuo3Init, - dim1506Kuo3Init, - dim1507Kuo3Init, - dim1508Kuo3Init, - dim1509Kuo3Init, - dim1510Kuo3Init, - dim1511Kuo3Init, - dim1512Kuo3Init, - dim1513Kuo3Init, - dim1514Kuo3Init, - dim1515Kuo3Init, - dim1516Kuo3Init, - dim1517Kuo3Init, - dim1518Kuo3Init, - dim1519Kuo3Init, - dim1520Kuo3Init, - dim1521Kuo3Init, - dim1522Kuo3Init, - dim1523Kuo3Init, - dim1524Kuo3Init, - dim1525Kuo3Init, - dim1526Kuo3Init, - dim1527Kuo3Init, - dim1528Kuo3Init, - dim1529Kuo3Init, - dim1530Kuo3Init, - dim1531Kuo3Init, - dim1532Kuo3Init, - dim1533Kuo3Init, - dim1534Kuo3Init, - dim1535Kuo3Init, - dim1536Kuo3Init, - dim1537Kuo3Init, - dim1538Kuo3Init, - dim1539Kuo3Init, - dim1540Kuo3Init, - dim1541Kuo3Init, - dim1542Kuo3Init, - dim1543Kuo3Init, - dim1544Kuo3Init, - dim1545Kuo3Init, - dim1546Kuo3Init, - dim1547Kuo3Init, - dim1548Kuo3Init, - dim1549Kuo3Init, - dim1550Kuo3Init, - dim1551Kuo3Init, - dim1552Kuo3Init, - dim1553Kuo3Init, - dim1554Kuo3Init, - dim1555Kuo3Init, - dim1556Kuo3Init, - dim1557Kuo3Init, - dim1558Kuo3Init, - dim1559Kuo3Init, - dim1560Kuo3Init, - dim1561Kuo3Init, - dim1562Kuo3Init, - dim1563Kuo3Init, - dim1564Kuo3Init, - dim1565Kuo3Init, - dim1566Kuo3Init, - dim1567Kuo3Init, - dim1568Kuo3Init, - dim1569Kuo3Init, - dim1570Kuo3Init, - dim1571Kuo3Init, - dim1572Kuo3Init, - dim1573Kuo3Init, - dim1574Kuo3Init, - dim1575Kuo3Init, - dim1576Kuo3Init, - dim1577Kuo3Init, - dim1578Kuo3Init, - dim1579Kuo3Init, - dim1580Kuo3Init, - dim1581Kuo3Init, - dim1582Kuo3Init, - dim1583Kuo3Init, - dim1584Kuo3Init, - dim1585Kuo3Init, - dim1586Kuo3Init, - dim1587Kuo3Init, - dim1588Kuo3Init, - dim1589Kuo3Init, - dim1590Kuo3Init, - dim1591Kuo3Init, - dim1592Kuo3Init, - dim1593Kuo3Init, - dim1594Kuo3Init, - dim1595Kuo3Init, - dim1596Kuo3Init, - dim1597Kuo3Init, - dim1598Kuo3Init, - dim1599Kuo3Init, - dim1600Kuo3Init, - dim1601Kuo3Init, - dim1602Kuo3Init, - dim1603Kuo3Init, - dim1604Kuo3Init, - dim1605Kuo3Init, - dim1606Kuo3Init, - dim1607Kuo3Init, - dim1608Kuo3Init, - dim1609Kuo3Init, - dim1610Kuo3Init, - dim1611Kuo3Init, - dim1612Kuo3Init, - dim1613Kuo3Init, - dim1614Kuo3Init, - dim1615Kuo3Init, - dim1616Kuo3Init, - dim1617Kuo3Init, - dim1618Kuo3Init, - dim1619Kuo3Init, - dim1620Kuo3Init, - dim1621Kuo3Init, - dim1622Kuo3Init, - dim1623Kuo3Init, - dim1624Kuo3Init, - dim1625Kuo3Init, - dim1626Kuo3Init, - dim1627Kuo3Init, - dim1628Kuo3Init, - dim1629Kuo3Init, - dim1630Kuo3Init, - dim1631Kuo3Init, - dim1632Kuo3Init, - dim1633Kuo3Init, - dim1634Kuo3Init, - dim1635Kuo3Init, - dim1636Kuo3Init, - dim1637Kuo3Init, - dim1638Kuo3Init, - dim1639Kuo3Init, - dim1640Kuo3Init, - dim1641Kuo3Init, - dim1642Kuo3Init, - dim1643Kuo3Init, - dim1644Kuo3Init, - dim1645Kuo3Init, - dim1646Kuo3Init, - dim1647Kuo3Init, - dim1648Kuo3Init, - dim1649Kuo3Init, - dim1650Kuo3Init, - dim1651Kuo3Init, - dim1652Kuo3Init, - dim1653Kuo3Init, - dim1654Kuo3Init, - dim1655Kuo3Init, - dim1656Kuo3Init, - dim1657Kuo3Init, - dim1658Kuo3Init, - dim1659Kuo3Init, - dim1660Kuo3Init, - dim1661Kuo3Init, - dim1662Kuo3Init, - dim1663Kuo3Init, - dim1664Kuo3Init, - dim1665Kuo3Init, - dim1666Kuo3Init, - dim1667Kuo3Init, - dim1668Kuo3Init, - dim1669Kuo3Init, - dim1670Kuo3Init, - dim1671Kuo3Init, - dim1672Kuo3Init, - dim1673Kuo3Init, - dim1674Kuo3Init, - dim1675Kuo3Init, - dim1676Kuo3Init, - dim1677Kuo3Init, - dim1678Kuo3Init, - dim1679Kuo3Init, - dim1680Kuo3Init, - dim1681Kuo3Init, - dim1682Kuo3Init, - dim1683Kuo3Init, - dim1684Kuo3Init, - dim1685Kuo3Init, - dim1686Kuo3Init, - dim1687Kuo3Init, - dim1688Kuo3Init, - dim1689Kuo3Init, - dim1690Kuo3Init, - dim1691Kuo3Init, - dim1692Kuo3Init, - dim1693Kuo3Init, - dim1694Kuo3Init, - dim1695Kuo3Init, - dim1696Kuo3Init, - dim1697Kuo3Init, - dim1698Kuo3Init, - dim1699Kuo3Init, - dim1700Kuo3Init, - dim1701Kuo3Init, - dim1702Kuo3Init, - dim1703Kuo3Init, - dim1704Kuo3Init, - dim1705Kuo3Init, - dim1706Kuo3Init, - dim1707Kuo3Init, - dim1708Kuo3Init, - dim1709Kuo3Init, - dim1710Kuo3Init, - dim1711Kuo3Init, - dim1712Kuo3Init, - dim1713Kuo3Init, - dim1714Kuo3Init, - dim1715Kuo3Init, - dim1716Kuo3Init, - dim1717Kuo3Init, - dim1718Kuo3Init, - dim1719Kuo3Init, - dim1720Kuo3Init, - dim1721Kuo3Init, - dim1722Kuo3Init, - dim1723Kuo3Init, - dim1724Kuo3Init, - dim1725Kuo3Init, - dim1726Kuo3Init, - dim1727Kuo3Init, - dim1728Kuo3Init, - dim1729Kuo3Init, - dim1730Kuo3Init, - dim1731Kuo3Init, - dim1732Kuo3Init, - dim1733Kuo3Init, - dim1734Kuo3Init, - dim1735Kuo3Init, - dim1736Kuo3Init, - dim1737Kuo3Init, - dim1738Kuo3Init, - dim1739Kuo3Init, - dim1740Kuo3Init, - dim1741Kuo3Init, - dim1742Kuo3Init, - dim1743Kuo3Init, - dim1744Kuo3Init, - dim1745Kuo3Init, - dim1746Kuo3Init, - dim1747Kuo3Init, - dim1748Kuo3Init, - dim1749Kuo3Init, - dim1750Kuo3Init, - dim1751Kuo3Init, - dim1752Kuo3Init, - dim1753Kuo3Init, - dim1754Kuo3Init, - dim1755Kuo3Init, - dim1756Kuo3Init, - dim1757Kuo3Init, - dim1758Kuo3Init, - dim1759Kuo3Init, - dim1760Kuo3Init, - dim1761Kuo3Init, - dim1762Kuo3Init, - dim1763Kuo3Init, - dim1764Kuo3Init, - dim1765Kuo3Init, - dim1766Kuo3Init, - dim1767Kuo3Init, - dim1768Kuo3Init, - dim1769Kuo3Init, - dim1770Kuo3Init, - dim1771Kuo3Init, - dim1772Kuo3Init, - dim1773Kuo3Init, - dim1774Kuo3Init, - dim1775Kuo3Init, - dim1776Kuo3Init, - dim1777Kuo3Init, - dim1778Kuo3Init, - dim1779Kuo3Init, - dim1780Kuo3Init, - dim1781Kuo3Init, - dim1782Kuo3Init, - dim1783Kuo3Init, - dim1784Kuo3Init, - dim1785Kuo3Init, - dim1786Kuo3Init, - dim1787Kuo3Init, - dim1788Kuo3Init, - dim1789Kuo3Init, - dim1790Kuo3Init, - dim1791Kuo3Init, - dim1792Kuo3Init, - dim1793Kuo3Init, - dim1794Kuo3Init, - dim1795Kuo3Init, - dim1796Kuo3Init, - dim1797Kuo3Init, - dim1798Kuo3Init, - dim1799Kuo3Init, - dim1800Kuo3Init, - dim1801Kuo3Init, - dim1802Kuo3Init, - dim1803Kuo3Init, - dim1804Kuo3Init, - dim1805Kuo3Init, - dim1806Kuo3Init, - dim1807Kuo3Init, - dim1808Kuo3Init, - dim1809Kuo3Init, - dim1810Kuo3Init, - dim1811Kuo3Init, - dim1812Kuo3Init, - dim1813Kuo3Init, - dim1814Kuo3Init, - dim1815Kuo3Init, - dim1816Kuo3Init, - dim1817Kuo3Init, - dim1818Kuo3Init, - dim1819Kuo3Init, - dim1820Kuo3Init, - dim1821Kuo3Init, - dim1822Kuo3Init, - dim1823Kuo3Init, - dim1824Kuo3Init, - dim1825Kuo3Init, - dim1826Kuo3Init, - dim1827Kuo3Init, - dim1828Kuo3Init, - dim1829Kuo3Init, - dim1830Kuo3Init, - dim1831Kuo3Init, - dim1832Kuo3Init, - dim1833Kuo3Init, - dim1834Kuo3Init, - dim1835Kuo3Init, - dim1836Kuo3Init, - dim1837Kuo3Init, - dim1838Kuo3Init, - dim1839Kuo3Init, - dim1840Kuo3Init, - dim1841Kuo3Init, - dim1842Kuo3Init, - dim1843Kuo3Init, - dim1844Kuo3Init, - dim1845Kuo3Init, - dim1846Kuo3Init, - dim1847Kuo3Init, - dim1848Kuo3Init, - dim1849Kuo3Init, - dim1850Kuo3Init, - dim1851Kuo3Init, - dim1852Kuo3Init, - dim1853Kuo3Init, - dim1854Kuo3Init, - dim1855Kuo3Init, - dim1856Kuo3Init, - dim1857Kuo3Init, - dim1858Kuo3Init, - dim1859Kuo3Init, - dim1860Kuo3Init, - dim1861Kuo3Init, - dim1862Kuo3Init, - dim1863Kuo3Init, - dim1864Kuo3Init, - dim1865Kuo3Init, - dim1866Kuo3Init, - dim1867Kuo3Init, - dim1868Kuo3Init, - dim1869Kuo3Init, - dim1870Kuo3Init, - dim1871Kuo3Init, - dim1872Kuo3Init, - dim1873Kuo3Init, - dim1874Kuo3Init, - dim1875Kuo3Init, - dim1876Kuo3Init, - dim1877Kuo3Init, - dim1878Kuo3Init, - dim1879Kuo3Init, - dim1880Kuo3Init, - dim1881Kuo3Init, - dim1882Kuo3Init, - dim1883Kuo3Init, - dim1884Kuo3Init, - dim1885Kuo3Init, - dim1886Kuo3Init, - dim1887Kuo3Init, - dim1888Kuo3Init, - dim1889Kuo3Init, - dim1890Kuo3Init, - dim1891Kuo3Init, - dim1892Kuo3Init, - dim1893Kuo3Init, - dim1894Kuo3Init, - dim1895Kuo3Init, - dim1896Kuo3Init, - dim1897Kuo3Init, - dim1898Kuo3Init, - dim1899Kuo3Init, - dim1900Kuo3Init, - dim1901Kuo3Init, - dim1902Kuo3Init, - dim1903Kuo3Init, - dim1904Kuo3Init, - dim1905Kuo3Init, - dim1906Kuo3Init, - dim1907Kuo3Init, - dim1908Kuo3Init, - dim1909Kuo3Init, - dim1910Kuo3Init, - dim1911Kuo3Init, - dim1912Kuo3Init, - dim1913Kuo3Init, - dim1914Kuo3Init, - dim1915Kuo3Init, - dim1916Kuo3Init, - dim1917Kuo3Init, - dim1918Kuo3Init, - dim1919Kuo3Init, - dim1920Kuo3Init, - dim1921Kuo3Init, - dim1922Kuo3Init, - dim1923Kuo3Init, - dim1924Kuo3Init, - dim1925Kuo3Init, - dim1926Kuo3Init, - dim1927Kuo3Init, - dim1928Kuo3Init, - dim1929Kuo3Init, - dim1930Kuo3Init, - dim1931Kuo3Init, - dim1932Kuo3Init, - dim1933Kuo3Init, - dim1934Kuo3Init, - dim1935Kuo3Init, - dim1936Kuo3Init, - dim1937Kuo3Init, - dim1938Kuo3Init, - dim1939Kuo3Init, - dim1940Kuo3Init, - dim1941Kuo3Init, - dim1942Kuo3Init, - dim1943Kuo3Init, - dim1944Kuo3Init, - dim1945Kuo3Init, - dim1946Kuo3Init, - dim1947Kuo3Init, - dim1948Kuo3Init, - dim1949Kuo3Init, - dim1950Kuo3Init, - dim1951Kuo3Init, - dim1952Kuo3Init, - dim1953Kuo3Init, - dim1954Kuo3Init, - dim1955Kuo3Init, - dim1956Kuo3Init, - dim1957Kuo3Init, - dim1958Kuo3Init, - dim1959Kuo3Init, - dim1960Kuo3Init, - dim1961Kuo3Init, - dim1962Kuo3Init, - dim1963Kuo3Init, - dim1964Kuo3Init, - dim1965Kuo3Init, - dim1966Kuo3Init, - dim1967Kuo3Init, - dim1968Kuo3Init, - dim1969Kuo3Init, - dim1970Kuo3Init, - dim1971Kuo3Init, - dim1972Kuo3Init, - dim1973Kuo3Init, - dim1974Kuo3Init, - dim1975Kuo3Init, - dim1976Kuo3Init, - dim1977Kuo3Init, - dim1978Kuo3Init, - dim1979Kuo3Init, - dim1980Kuo3Init, - dim1981Kuo3Init, - dim1982Kuo3Init, - dim1983Kuo3Init, - dim1984Kuo3Init, - dim1985Kuo3Init, - dim1986Kuo3Init, - dim1987Kuo3Init, - dim1988Kuo3Init, - dim1989Kuo3Init, - dim1990Kuo3Init, - dim1991Kuo3Init, - dim1992Kuo3Init, - dim1993Kuo3Init, - dim1994Kuo3Init, - dim1995Kuo3Init, - dim1996Kuo3Init, - dim1997Kuo3Init, - dim1998Kuo3Init, - dim1999Kuo3Init, - dim2000Kuo3Init, - dim2001Kuo3Init, - dim2002Kuo3Init, - dim2003Kuo3Init, - dim2004Kuo3Init, - dim2005Kuo3Init, - dim2006Kuo3Init, - dim2007Kuo3Init, - dim2008Kuo3Init, - dim2009Kuo3Init, - dim2010Kuo3Init, - dim2011Kuo3Init, - dim2012Kuo3Init, - dim2013Kuo3Init, - dim2014Kuo3Init, - dim2015Kuo3Init, - dim2016Kuo3Init, - dim2017Kuo3Init, - dim2018Kuo3Init, - dim2019Kuo3Init, - dim2020Kuo3Init, - dim2021Kuo3Init, - dim2022Kuo3Init, - dim2023Kuo3Init, - dim2024Kuo3Init, - dim2025Kuo3Init, - dim2026Kuo3Init, - dim2027Kuo3Init, - dim2028Kuo3Init, - dim2029Kuo3Init, - dim2030Kuo3Init, - dim2031Kuo3Init, - dim2032Kuo3Init, - dim2033Kuo3Init, - dim2034Kuo3Init, - dim2035Kuo3Init, - dim2036Kuo3Init, - dim2037Kuo3Init, - dim2038Kuo3Init, - dim2039Kuo3Init, - dim2040Kuo3Init, - dim2041Kuo3Init, - dim2042Kuo3Init, - dim2043Kuo3Init, - dim2044Kuo3Init, - dim2045Kuo3Init, - dim2046Kuo3Init, - dim2047Kuo3Init, - dim2048Kuo3Init, - dim2049Kuo3Init, - dim2050Kuo3Init, - dim2051Kuo3Init, - dim2052Kuo3Init, - dim2053Kuo3Init, - dim2054Kuo3Init, - dim2055Kuo3Init, - dim2056Kuo3Init, - dim2057Kuo3Init, - dim2058Kuo3Init, - dim2059Kuo3Init, - dim2060Kuo3Init, - dim2061Kuo3Init, - dim2062Kuo3Init, - dim2063Kuo3Init, - dim2064Kuo3Init, - dim2065Kuo3Init, - dim2066Kuo3Init, - dim2067Kuo3Init, - dim2068Kuo3Init, - dim2069Kuo3Init, - dim2070Kuo3Init, - dim2071Kuo3Init, - dim2072Kuo3Init, - dim2073Kuo3Init, - dim2074Kuo3Init, - dim2075Kuo3Init, - dim2076Kuo3Init, - dim2077Kuo3Init, - dim2078Kuo3Init, - dim2079Kuo3Init, - dim2080Kuo3Init, - dim2081Kuo3Init, - dim2082Kuo3Init, - dim2083Kuo3Init, - dim2084Kuo3Init, - dim2085Kuo3Init, - dim2086Kuo3Init, - dim2087Kuo3Init, - dim2088Kuo3Init, - dim2089Kuo3Init, - dim2090Kuo3Init, - dim2091Kuo3Init, - dim2092Kuo3Init, - dim2093Kuo3Init, - dim2094Kuo3Init, - dim2095Kuo3Init, - dim2096Kuo3Init, - dim2097Kuo3Init, - dim2098Kuo3Init, - dim2099Kuo3Init, - dim2100Kuo3Init, - dim2101Kuo3Init, - dim2102Kuo3Init, - dim2103Kuo3Init, - dim2104Kuo3Init, - dim2105Kuo3Init, - dim2106Kuo3Init, - dim2107Kuo3Init, - dim2108Kuo3Init, - dim2109Kuo3Init, - dim2110Kuo3Init, - dim2111Kuo3Init, - dim2112Kuo3Init, - dim2113Kuo3Init, - dim2114Kuo3Init, - dim2115Kuo3Init, - dim2116Kuo3Init, - dim2117Kuo3Init, - dim2118Kuo3Init, - dim2119Kuo3Init, - dim2120Kuo3Init, - dim2121Kuo3Init, - dim2122Kuo3Init, - dim2123Kuo3Init, - dim2124Kuo3Init, - dim2125Kuo3Init, - dim2126Kuo3Init, - dim2127Kuo3Init, - dim2128Kuo3Init, - dim2129Kuo3Init, - dim2130Kuo3Init, - dim2131Kuo3Init, - dim2132Kuo3Init, - dim2133Kuo3Init, - dim2134Kuo3Init, - dim2135Kuo3Init, - dim2136Kuo3Init, - dim2137Kuo3Init, - dim2138Kuo3Init, - dim2139Kuo3Init, - dim2140Kuo3Init, - dim2141Kuo3Init, - dim2142Kuo3Init, - dim2143Kuo3Init, - dim2144Kuo3Init, - dim2145Kuo3Init, - dim2146Kuo3Init, - dim2147Kuo3Init, - dim2148Kuo3Init, - dim2149Kuo3Init, - dim2150Kuo3Init, - dim2151Kuo3Init, - dim2152Kuo3Init, - dim2153Kuo3Init, - dim2154Kuo3Init, - dim2155Kuo3Init, - dim2156Kuo3Init, - dim2157Kuo3Init, - dim2158Kuo3Init, - dim2159Kuo3Init, - dim2160Kuo3Init, - dim2161Kuo3Init, - dim2162Kuo3Init, - dim2163Kuo3Init, - dim2164Kuo3Init, - dim2165Kuo3Init, - dim2166Kuo3Init, - dim2167Kuo3Init, - dim2168Kuo3Init, - dim2169Kuo3Init, - dim2170Kuo3Init, - dim2171Kuo3Init, - dim2172Kuo3Init, - dim2173Kuo3Init, - dim2174Kuo3Init, - dim2175Kuo3Init, - dim2176Kuo3Init, - dim2177Kuo3Init, - dim2178Kuo3Init, - dim2179Kuo3Init, - dim2180Kuo3Init, - dim2181Kuo3Init, - dim2182Kuo3Init, - dim2183Kuo3Init, - dim2184Kuo3Init, - dim2185Kuo3Init, - dim2186Kuo3Init, - dim2187Kuo3Init, - dim2188Kuo3Init, - dim2189Kuo3Init, - dim2190Kuo3Init, - dim2191Kuo3Init, - dim2192Kuo3Init, - dim2193Kuo3Init, - dim2194Kuo3Init, - dim2195Kuo3Init, - dim2196Kuo3Init, - dim2197Kuo3Init, - dim2198Kuo3Init, - dim2199Kuo3Init, - dim2200Kuo3Init, - dim2201Kuo3Init, - dim2202Kuo3Init, - dim2203Kuo3Init, - dim2204Kuo3Init, - dim2205Kuo3Init, - dim2206Kuo3Init, - dim2207Kuo3Init, - dim2208Kuo3Init, - dim2209Kuo3Init, - dim2210Kuo3Init, - dim2211Kuo3Init, - dim2212Kuo3Init, - dim2213Kuo3Init, - dim2214Kuo3Init, - dim2215Kuo3Init, - dim2216Kuo3Init, - dim2217Kuo3Init, - dim2218Kuo3Init, - dim2219Kuo3Init, - dim2220Kuo3Init, - dim2221Kuo3Init, - dim2222Kuo3Init, - dim2223Kuo3Init, - dim2224Kuo3Init, - dim2225Kuo3Init, - dim2226Kuo3Init, - dim2227Kuo3Init, - dim2228Kuo3Init, - dim2229Kuo3Init, - dim2230Kuo3Init, - dim2231Kuo3Init, - dim2232Kuo3Init, - dim2233Kuo3Init, - dim2234Kuo3Init, - dim2235Kuo3Init, - dim2236Kuo3Init, - dim2237Kuo3Init, - dim2238Kuo3Init, - dim2239Kuo3Init, - dim2240Kuo3Init, - dim2241Kuo3Init, - dim2242Kuo3Init, - dim2243Kuo3Init, - dim2244Kuo3Init, - dim2245Kuo3Init, - dim2246Kuo3Init, - dim2247Kuo3Init, - dim2248Kuo3Init, - dim2249Kuo3Init, - dim2250Kuo3Init, - dim2251Kuo3Init, - dim2252Kuo3Init, - dim2253Kuo3Init, - dim2254Kuo3Init, - dim2255Kuo3Init, - dim2256Kuo3Init, - dim2257Kuo3Init, - dim2258Kuo3Init, - dim2259Kuo3Init, - dim2260Kuo3Init, - dim2261Kuo3Init, - dim2262Kuo3Init, - dim2263Kuo3Init, - dim2264Kuo3Init, - dim2265Kuo3Init, - dim2266Kuo3Init, - dim2267Kuo3Init, - dim2268Kuo3Init, - dim2269Kuo3Init, - dim2270Kuo3Init, - dim2271Kuo3Init, - dim2272Kuo3Init, - dim2273Kuo3Init, - dim2274Kuo3Init, - dim2275Kuo3Init, - dim2276Kuo3Init, - dim2277Kuo3Init, - dim2278Kuo3Init, - dim2279Kuo3Init, - dim2280Kuo3Init, - dim2281Kuo3Init, - dim2282Kuo3Init, - dim2283Kuo3Init, - dim2284Kuo3Init, - dim2285Kuo3Init, - dim2286Kuo3Init, - dim2287Kuo3Init, - dim2288Kuo3Init, - dim2289Kuo3Init, - dim2290Kuo3Init, - dim2291Kuo3Init, - dim2292Kuo3Init, - dim2293Kuo3Init, - dim2294Kuo3Init, - dim2295Kuo3Init, - dim2296Kuo3Init, - dim2297Kuo3Init, - dim2298Kuo3Init, - dim2299Kuo3Init, - dim2300Kuo3Init, - dim2301Kuo3Init, - dim2302Kuo3Init, - dim2303Kuo3Init, - dim2304Kuo3Init, - dim2305Kuo3Init, - dim2306Kuo3Init, - dim2307Kuo3Init, - dim2308Kuo3Init, - dim2309Kuo3Init, - dim2310Kuo3Init, - dim2311Kuo3Init, - dim2312Kuo3Init, - dim2313Kuo3Init, - dim2314Kuo3Init, - dim2315Kuo3Init, - dim2316Kuo3Init, - dim2317Kuo3Init, - dim2318Kuo3Init, - dim2319Kuo3Init, - dim2320Kuo3Init, - dim2321Kuo3Init, - dim2322Kuo3Init, - dim2323Kuo3Init, - dim2324Kuo3Init, - dim2325Kuo3Init, - dim2326Kuo3Init, - dim2327Kuo3Init, - dim2328Kuo3Init, - dim2329Kuo3Init, - dim2330Kuo3Init, - dim2331Kuo3Init, - dim2332Kuo3Init, - dim2333Kuo3Init, - dim2334Kuo3Init, - dim2335Kuo3Init, - dim2336Kuo3Init, - dim2337Kuo3Init, - dim2338Kuo3Init, - dim2339Kuo3Init, - dim2340Kuo3Init, - dim2341Kuo3Init, - dim2342Kuo3Init, - dim2343Kuo3Init, - dim2344Kuo3Init, - dim2345Kuo3Init, - dim2346Kuo3Init, - dim2347Kuo3Init, - dim2348Kuo3Init, - dim2349Kuo3Init, - dim2350Kuo3Init, - dim2351Kuo3Init, - dim2352Kuo3Init, - dim2353Kuo3Init, - dim2354Kuo3Init, - dim2355Kuo3Init, - dim2356Kuo3Init, - dim2357Kuo3Init, - dim2358Kuo3Init, - dim2359Kuo3Init, - dim2360Kuo3Init, - dim2361Kuo3Init, - dim2362Kuo3Init, - dim2363Kuo3Init, - dim2364Kuo3Init, - dim2365Kuo3Init, - dim2366Kuo3Init, - dim2367Kuo3Init, - dim2368Kuo3Init, - dim2369Kuo3Init, - dim2370Kuo3Init, - dim2371Kuo3Init, - dim2372Kuo3Init, - dim2373Kuo3Init, - dim2374Kuo3Init, - dim2375Kuo3Init, - dim2376Kuo3Init, - dim2377Kuo3Init, - dim2378Kuo3Init, - dim2379Kuo3Init, - dim2380Kuo3Init, - dim2381Kuo3Init, - dim2382Kuo3Init, - dim2383Kuo3Init, - dim2384Kuo3Init, - dim2385Kuo3Init, - dim2386Kuo3Init, - dim2387Kuo3Init, - dim2388Kuo3Init, - dim2389Kuo3Init, - dim2390Kuo3Init, - dim2391Kuo3Init, - dim2392Kuo3Init, - dim2393Kuo3Init, - dim2394Kuo3Init, - dim2395Kuo3Init, - dim2396Kuo3Init, - dim2397Kuo3Init, - dim2398Kuo3Init, - dim2399Kuo3Init, - dim2400Kuo3Init, - dim2401Kuo3Init, - dim2402Kuo3Init, - dim2403Kuo3Init, - dim2404Kuo3Init, - dim2405Kuo3Init, - dim2406Kuo3Init, - dim2407Kuo3Init, - dim2408Kuo3Init, - dim2409Kuo3Init, - dim2410Kuo3Init, - dim2411Kuo3Init, - dim2412Kuo3Init, - dim2413Kuo3Init, - dim2414Kuo3Init, - dim2415Kuo3Init, - dim2416Kuo3Init, - dim2417Kuo3Init, - dim2418Kuo3Init, - dim2419Kuo3Init, - dim2420Kuo3Init, - dim2421Kuo3Init, - dim2422Kuo3Init, - dim2423Kuo3Init, - dim2424Kuo3Init, - dim2425Kuo3Init, - dim2426Kuo3Init, - dim2427Kuo3Init, - dim2428Kuo3Init, - dim2429Kuo3Init, - dim2430Kuo3Init, - dim2431Kuo3Init, - dim2432Kuo3Init, - dim2433Kuo3Init, - dim2434Kuo3Init, - dim2435Kuo3Init, - dim2436Kuo3Init, - dim2437Kuo3Init, - dim2438Kuo3Init, - dim2439Kuo3Init, - dim2440Kuo3Init, - dim2441Kuo3Init, - dim2442Kuo3Init, - dim2443Kuo3Init, - dim2444Kuo3Init, - dim2445Kuo3Init, - dim2446Kuo3Init, - dim2447Kuo3Init, - dim2448Kuo3Init, - dim2449Kuo3Init, - dim2450Kuo3Init, - dim2451Kuo3Init, - dim2452Kuo3Init, - dim2453Kuo3Init, - dim2454Kuo3Init, - dim2455Kuo3Init, - dim2456Kuo3Init, - dim2457Kuo3Init, - dim2458Kuo3Init, - dim2459Kuo3Init, - dim2460Kuo3Init, - dim2461Kuo3Init, - dim2462Kuo3Init, - dim2463Kuo3Init, - dim2464Kuo3Init, - dim2465Kuo3Init, - dim2466Kuo3Init, - dim2467Kuo3Init, - dim2468Kuo3Init, - dim2469Kuo3Init, - dim2470Kuo3Init, - dim2471Kuo3Init, - dim2472Kuo3Init, - dim2473Kuo3Init, - dim2474Kuo3Init, - dim2475Kuo3Init, - dim2476Kuo3Init, - dim2477Kuo3Init, - dim2478Kuo3Init, - dim2479Kuo3Init, - dim2480Kuo3Init, - dim2481Kuo3Init, - dim2482Kuo3Init, - dim2483Kuo3Init, - dim2484Kuo3Init, - dim2485Kuo3Init, - dim2486Kuo3Init, - dim2487Kuo3Init, - dim2488Kuo3Init, - dim2489Kuo3Init, - dim2490Kuo3Init, - dim2491Kuo3Init, - dim2492Kuo3Init, - dim2493Kuo3Init, - dim2494Kuo3Init, - dim2495Kuo3Init, - dim2496Kuo3Init, - dim2497Kuo3Init, - dim2498Kuo3Init, - dim2499Kuo3Init, - dim2500Kuo3Init, - dim2501Kuo3Init, - dim2502Kuo3Init, - dim2503Kuo3Init, - dim2504Kuo3Init, - dim2505Kuo3Init, - dim2506Kuo3Init, - dim2507Kuo3Init, - dim2508Kuo3Init, - dim2509Kuo3Init, - dim2510Kuo3Init, - dim2511Kuo3Init, - dim2512Kuo3Init, - dim2513Kuo3Init, - dim2514Kuo3Init, - dim2515Kuo3Init, - dim2516Kuo3Init, - dim2517Kuo3Init, - dim2518Kuo3Init, - dim2519Kuo3Init, - dim2520Kuo3Init, - dim2521Kuo3Init, - dim2522Kuo3Init, - dim2523Kuo3Init, - dim2524Kuo3Init, - dim2525Kuo3Init, - dim2526Kuo3Init, - dim2527Kuo3Init, - dim2528Kuo3Init, - dim2529Kuo3Init, - dim2530Kuo3Init, - dim2531Kuo3Init, - dim2532Kuo3Init, - dim2533Kuo3Init, - dim2534Kuo3Init, - dim2535Kuo3Init, - dim2536Kuo3Init, - dim2537Kuo3Init, - dim2538Kuo3Init, - dim2539Kuo3Init, - dim2540Kuo3Init, - dim2541Kuo3Init, - dim2542Kuo3Init, - dim2543Kuo3Init, - dim2544Kuo3Init, - dim2545Kuo3Init, - dim2546Kuo3Init, - dim2547Kuo3Init, - dim2548Kuo3Init, - dim2549Kuo3Init, - dim2550Kuo3Init, - dim2551Kuo3Init, - dim2552Kuo3Init, - dim2553Kuo3Init, - dim2554Kuo3Init, - dim2555Kuo3Init, - dim2556Kuo3Init, - dim2557Kuo3Init, - dim2558Kuo3Init, - dim2559Kuo3Init, - dim2560Kuo3Init, - dim2561Kuo3Init, - dim2562Kuo3Init, - dim2563Kuo3Init, - dim2564Kuo3Init, - dim2565Kuo3Init, - dim2566Kuo3Init, - dim2567Kuo3Init, - dim2568Kuo3Init, - dim2569Kuo3Init, - dim2570Kuo3Init, - dim2571Kuo3Init, - dim2572Kuo3Init, - dim2573Kuo3Init, - dim2574Kuo3Init, - dim2575Kuo3Init, - dim2576Kuo3Init, - dim2577Kuo3Init, - dim2578Kuo3Init, - dim2579Kuo3Init, - dim2580Kuo3Init, - dim2581Kuo3Init, - dim2582Kuo3Init, - dim2583Kuo3Init, - dim2584Kuo3Init, - dim2585Kuo3Init, - dim2586Kuo3Init, - dim2587Kuo3Init, - dim2588Kuo3Init, - dim2589Kuo3Init, - dim2590Kuo3Init, - dim2591Kuo3Init, - dim2592Kuo3Init, - dim2593Kuo3Init, - dim2594Kuo3Init, - dim2595Kuo3Init, - dim2596Kuo3Init, - dim2597Kuo3Init, - dim2598Kuo3Init, - dim2599Kuo3Init, - dim2600Kuo3Init, - dim2601Kuo3Init, - dim2602Kuo3Init, - dim2603Kuo3Init, - dim2604Kuo3Init, - dim2605Kuo3Init, - dim2606Kuo3Init, - dim2607Kuo3Init, - dim2608Kuo3Init, - dim2609Kuo3Init, - dim2610Kuo3Init, - dim2611Kuo3Init, - dim2612Kuo3Init, - dim2613Kuo3Init, - dim2614Kuo3Init, - dim2615Kuo3Init, - dim2616Kuo3Init, - dim2617Kuo3Init, - dim2618Kuo3Init, - dim2619Kuo3Init, - dim2620Kuo3Init, - dim2621Kuo3Init, - dim2622Kuo3Init, - dim2623Kuo3Init, - dim2624Kuo3Init, - dim2625Kuo3Init, - dim2626Kuo3Init, - dim2627Kuo3Init, - dim2628Kuo3Init, - dim2629Kuo3Init, - dim2630Kuo3Init, - dim2631Kuo3Init, - dim2632Kuo3Init, - dim2633Kuo3Init, - dim2634Kuo3Init, - dim2635Kuo3Init, - dim2636Kuo3Init, - dim2637Kuo3Init, - dim2638Kuo3Init, - dim2639Kuo3Init, - dim2640Kuo3Init, - dim2641Kuo3Init, - dim2642Kuo3Init, - dim2643Kuo3Init, - dim2644Kuo3Init, - dim2645Kuo3Init, - dim2646Kuo3Init, - dim2647Kuo3Init, - dim2648Kuo3Init, - dim2649Kuo3Init, - dim2650Kuo3Init, - dim2651Kuo3Init, - dim2652Kuo3Init, - dim2653Kuo3Init, - dim2654Kuo3Init, - dim2655Kuo3Init, - dim2656Kuo3Init, - dim2657Kuo3Init, - dim2658Kuo3Init, - dim2659Kuo3Init, - dim2660Kuo3Init, - dim2661Kuo3Init, - dim2662Kuo3Init, - dim2663Kuo3Init, - dim2664Kuo3Init, - dim2665Kuo3Init, - dim2666Kuo3Init, - dim2667Kuo3Init, - dim2668Kuo3Init, - dim2669Kuo3Init, - dim2670Kuo3Init, - dim2671Kuo3Init, - dim2672Kuo3Init, - dim2673Kuo3Init, - dim2674Kuo3Init, - dim2675Kuo3Init, - dim2676Kuo3Init, - dim2677Kuo3Init, - dim2678Kuo3Init, - dim2679Kuo3Init, - dim2680Kuo3Init, - dim2681Kuo3Init, - dim2682Kuo3Init, - dim2683Kuo3Init, - dim2684Kuo3Init, - dim2685Kuo3Init, - dim2686Kuo3Init, - dim2687Kuo3Init, - dim2688Kuo3Init, - dim2689Kuo3Init, - dim2690Kuo3Init, - dim2691Kuo3Init, - dim2692Kuo3Init, - dim2693Kuo3Init, - dim2694Kuo3Init, - dim2695Kuo3Init, - dim2696Kuo3Init, - dim2697Kuo3Init, - dim2698Kuo3Init, - dim2699Kuo3Init, - dim2700Kuo3Init, - dim2701Kuo3Init, - dim2702Kuo3Init, - dim2703Kuo3Init, - dim2704Kuo3Init, - dim2705Kuo3Init, - dim2706Kuo3Init, - dim2707Kuo3Init, - dim2708Kuo3Init, - dim2709Kuo3Init, - dim2710Kuo3Init, - dim2711Kuo3Init, - dim2712Kuo3Init, - dim2713Kuo3Init, - dim2714Kuo3Init, - dim2715Kuo3Init, - dim2716Kuo3Init, - dim2717Kuo3Init, - dim2718Kuo3Init, - dim2719Kuo3Init, - dim2720Kuo3Init, - dim2721Kuo3Init, - dim2722Kuo3Init, - dim2723Kuo3Init, - dim2724Kuo3Init, - dim2725Kuo3Init, - dim2726Kuo3Init, - dim2727Kuo3Init, - dim2728Kuo3Init, - dim2729Kuo3Init, - dim2730Kuo3Init, - dim2731Kuo3Init, - dim2732Kuo3Init, - dim2733Kuo3Init, - dim2734Kuo3Init, - dim2735Kuo3Init, - dim2736Kuo3Init, - dim2737Kuo3Init, - dim2738Kuo3Init, - dim2739Kuo3Init, - dim2740Kuo3Init, - dim2741Kuo3Init, - dim2742Kuo3Init, - dim2743Kuo3Init, - dim2744Kuo3Init, - dim2745Kuo3Init, - dim2746Kuo3Init, - dim2747Kuo3Init, - dim2748Kuo3Init, - dim2749Kuo3Init, - dim2750Kuo3Init, - dim2751Kuo3Init, - dim2752Kuo3Init, - dim2753Kuo3Init, - dim2754Kuo3Init, - dim2755Kuo3Init, - dim2756Kuo3Init, - dim2757Kuo3Init, - dim2758Kuo3Init, - dim2759Kuo3Init, - dim2760Kuo3Init, - dim2761Kuo3Init, - dim2762Kuo3Init, - dim2763Kuo3Init, - dim2764Kuo3Init, - dim2765Kuo3Init, - dim2766Kuo3Init, - dim2767Kuo3Init, - dim2768Kuo3Init, - dim2769Kuo3Init, - dim2770Kuo3Init, - dim2771Kuo3Init, - dim2772Kuo3Init, - dim2773Kuo3Init, - dim2774Kuo3Init, - dim2775Kuo3Init, - dim2776Kuo3Init, - dim2777Kuo3Init, - dim2778Kuo3Init, - dim2779Kuo3Init, - dim2780Kuo3Init, - dim2781Kuo3Init, - dim2782Kuo3Init, - dim2783Kuo3Init, - dim2784Kuo3Init, - dim2785Kuo3Init, - dim2786Kuo3Init, - dim2787Kuo3Init, - dim2788Kuo3Init, - dim2789Kuo3Init, - dim2790Kuo3Init, - dim2791Kuo3Init, - dim2792Kuo3Init, - dim2793Kuo3Init, - dim2794Kuo3Init, - dim2795Kuo3Init, - dim2796Kuo3Init, - dim2797Kuo3Init, - dim2798Kuo3Init, - dim2799Kuo3Init, - dim2800Kuo3Init, - dim2801Kuo3Init, - dim2802Kuo3Init, - dim2803Kuo3Init, - dim2804Kuo3Init, - dim2805Kuo3Init, - dim2806Kuo3Init, - dim2807Kuo3Init, - dim2808Kuo3Init, - dim2809Kuo3Init, - dim2810Kuo3Init, - dim2811Kuo3Init, - dim2812Kuo3Init, - dim2813Kuo3Init, - dim2814Kuo3Init, - dim2815Kuo3Init, - dim2816Kuo3Init, - dim2817Kuo3Init, - dim2818Kuo3Init, - dim2819Kuo3Init, - dim2820Kuo3Init, - dim2821Kuo3Init, - dim2822Kuo3Init, - dim2823Kuo3Init, - dim2824Kuo3Init, - dim2825Kuo3Init, - dim2826Kuo3Init, - dim2827Kuo3Init, - dim2828Kuo3Init, - dim2829Kuo3Init, - dim2830Kuo3Init, - dim2831Kuo3Init, - dim2832Kuo3Init, - dim2833Kuo3Init, - dim2834Kuo3Init, - dim2835Kuo3Init, - dim2836Kuo3Init, - dim2837Kuo3Init, - dim2838Kuo3Init, - dim2839Kuo3Init, - dim2840Kuo3Init, - dim2841Kuo3Init, - dim2842Kuo3Init, - dim2843Kuo3Init, - dim2844Kuo3Init, - dim2845Kuo3Init, - dim2846Kuo3Init, - dim2847Kuo3Init, - dim2848Kuo3Init, - dim2849Kuo3Init, - dim2850Kuo3Init, - dim2851Kuo3Init, - dim2852Kuo3Init, - dim2853Kuo3Init, - dim2854Kuo3Init, - dim2855Kuo3Init, - dim2856Kuo3Init, - dim2857Kuo3Init, - dim2858Kuo3Init, - dim2859Kuo3Init, - dim2860Kuo3Init, - dim2861Kuo3Init, - dim2862Kuo3Init, - dim2863Kuo3Init, - dim2864Kuo3Init, - dim2865Kuo3Init, - dim2866Kuo3Init, - dim2867Kuo3Init, - dim2868Kuo3Init, - dim2869Kuo3Init, - dim2870Kuo3Init, - dim2871Kuo3Init, - dim2872Kuo3Init, - dim2873Kuo3Init, - dim2874Kuo3Init, - dim2875Kuo3Init, - dim2876Kuo3Init, - dim2877Kuo3Init, - dim2878Kuo3Init, - dim2879Kuo3Init, - dim2880Kuo3Init, - dim2881Kuo3Init, - dim2882Kuo3Init, - dim2883Kuo3Init, - dim2884Kuo3Init, - dim2885Kuo3Init, - dim2886Kuo3Init, - dim2887Kuo3Init, - dim2888Kuo3Init, - dim2889Kuo3Init, - dim2890Kuo3Init, - dim2891Kuo3Init, - dim2892Kuo3Init, - dim2893Kuo3Init, - dim2894Kuo3Init, - dim2895Kuo3Init, - dim2896Kuo3Init, - dim2897Kuo3Init, - dim2898Kuo3Init, - dim2899Kuo3Init, - dim2900Kuo3Init, - dim2901Kuo3Init, - dim2902Kuo3Init, - dim2903Kuo3Init, - dim2904Kuo3Init, - dim2905Kuo3Init, - dim2906Kuo3Init, - dim2907Kuo3Init, - dim2908Kuo3Init, - dim2909Kuo3Init, - dim2910Kuo3Init, - dim2911Kuo3Init, - dim2912Kuo3Init, - dim2913Kuo3Init, - dim2914Kuo3Init, - dim2915Kuo3Init, - dim2916Kuo3Init, - dim2917Kuo3Init, - dim2918Kuo3Init, - dim2919Kuo3Init, - dim2920Kuo3Init, - dim2921Kuo3Init, - dim2922Kuo3Init, - dim2923Kuo3Init, - dim2924Kuo3Init, - dim2925Kuo3Init, - dim2926Kuo3Init, - dim2927Kuo3Init, - dim2928Kuo3Init, - dim2929Kuo3Init, - dim2930Kuo3Init, - dim2931Kuo3Init, - dim2932Kuo3Init, - dim2933Kuo3Init, - dim2934Kuo3Init, - dim2935Kuo3Init, - dim2936Kuo3Init, - dim2937Kuo3Init, - dim2938Kuo3Init, - dim2939Kuo3Init, - dim2940Kuo3Init, - dim2941Kuo3Init, - dim2942Kuo3Init, - dim2943Kuo3Init, - dim2944Kuo3Init, - dim2945Kuo3Init, - dim2946Kuo3Init, - dim2947Kuo3Init, - dim2948Kuo3Init, - dim2949Kuo3Init, - dim2950Kuo3Init, - dim2951Kuo3Init, - dim2952Kuo3Init, - dim2953Kuo3Init, - dim2954Kuo3Init, - dim2955Kuo3Init, - dim2956Kuo3Init, - dim2957Kuo3Init, - dim2958Kuo3Init, - dim2959Kuo3Init, - dim2960Kuo3Init, - dim2961Kuo3Init, - dim2962Kuo3Init, - dim2963Kuo3Init, - dim2964Kuo3Init, - dim2965Kuo3Init, - dim2966Kuo3Init, - dim2967Kuo3Init, - dim2968Kuo3Init, - dim2969Kuo3Init, - dim2970Kuo3Init, - dim2971Kuo3Init, - dim2972Kuo3Init, - dim2973Kuo3Init, - dim2974Kuo3Init, - dim2975Kuo3Init, - dim2976Kuo3Init, - dim2977Kuo3Init, - dim2978Kuo3Init, - dim2979Kuo3Init, - dim2980Kuo3Init, - dim2981Kuo3Init, - dim2982Kuo3Init, - dim2983Kuo3Init, - dim2984Kuo3Init, - dim2985Kuo3Init, - dim2986Kuo3Init, - dim2987Kuo3Init, - dim2988Kuo3Init, - dim2989Kuo3Init, - dim2990Kuo3Init, - dim2991Kuo3Init, - dim2992Kuo3Init, - dim2993Kuo3Init, - dim2994Kuo3Init, - dim2995Kuo3Init, - dim2996Kuo3Init, - dim2997Kuo3Init, - dim2998Kuo3Init, - dim2999Kuo3Init, - dim3000Kuo3Init, - dim3001Kuo3Init, - dim3002Kuo3Init, - dim3003Kuo3Init, - dim3004Kuo3Init, - dim3005Kuo3Init, - dim3006Kuo3Init, - dim3007Kuo3Init, - dim3008Kuo3Init, - dim3009Kuo3Init, - dim3010Kuo3Init, - dim3011Kuo3Init, - dim3012Kuo3Init, - dim3013Kuo3Init, - dim3014Kuo3Init, - dim3015Kuo3Init, - dim3016Kuo3Init, - dim3017Kuo3Init, - dim3018Kuo3Init, - dim3019Kuo3Init, - dim3020Kuo3Init, - dim3021Kuo3Init, - dim3022Kuo3Init, - dim3023Kuo3Init, - dim3024Kuo3Init, - dim3025Kuo3Init, - dim3026Kuo3Init, - dim3027Kuo3Init, - dim3028Kuo3Init, - dim3029Kuo3Init, - dim3030Kuo3Init, - dim3031Kuo3Init, - dim3032Kuo3Init, - dim3033Kuo3Init, - dim3034Kuo3Init, - dim3035Kuo3Init, - dim3036Kuo3Init, - dim3037Kuo3Init, - dim3038Kuo3Init, - dim3039Kuo3Init, - dim3040Kuo3Init, - dim3041Kuo3Init, - dim3042Kuo3Init, - dim3043Kuo3Init, - dim3044Kuo3Init, - dim3045Kuo3Init, - dim3046Kuo3Init, - dim3047Kuo3Init, - dim3048Kuo3Init, - dim3049Kuo3Init, - dim3050Kuo3Init, - dim3051Kuo3Init, - dim3052Kuo3Init, - dim3053Kuo3Init, - dim3054Kuo3Init, - dim3055Kuo3Init, - dim3056Kuo3Init, - dim3057Kuo3Init, - dim3058Kuo3Init, - dim3059Kuo3Init, - dim3060Kuo3Init, - dim3061Kuo3Init, - dim3062Kuo3Init, - dim3063Kuo3Init, - dim3064Kuo3Init, - dim3065Kuo3Init, - dim3066Kuo3Init, - dim3067Kuo3Init, - dim3068Kuo3Init, - dim3069Kuo3Init, - dim3070Kuo3Init, - dim3071Kuo3Init, - dim3072Kuo3Init, - dim3073Kuo3Init, - dim3074Kuo3Init, - dim3075Kuo3Init, - dim3076Kuo3Init, - dim3077Kuo3Init, - dim3078Kuo3Init, - dim3079Kuo3Init, - dim3080Kuo3Init, - dim3081Kuo3Init, - dim3082Kuo3Init, - dim3083Kuo3Init, - dim3084Kuo3Init, - dim3085Kuo3Init, - dim3086Kuo3Init, - dim3087Kuo3Init, - dim3088Kuo3Init, - dim3089Kuo3Init, - dim3090Kuo3Init, - dim3091Kuo3Init, - dim3092Kuo3Init, - dim3093Kuo3Init, - dim3094Kuo3Init, - dim3095Kuo3Init, - dim3096Kuo3Init, - dim3097Kuo3Init, - dim3098Kuo3Init, - dim3099Kuo3Init, - dim3100Kuo3Init, - dim3101Kuo3Init, - dim3102Kuo3Init, - dim3103Kuo3Init, - dim3104Kuo3Init, - dim3105Kuo3Init, - dim3106Kuo3Init, - dim3107Kuo3Init, - dim3108Kuo3Init, - dim3109Kuo3Init, - dim3110Kuo3Init, - dim3111Kuo3Init, - dim3112Kuo3Init, - dim3113Kuo3Init, - dim3114Kuo3Init, - dim3115Kuo3Init, - dim3116Kuo3Init, - dim3117Kuo3Init, - dim3118Kuo3Init, - dim3119Kuo3Init, - dim3120Kuo3Init, - dim3121Kuo3Init, - dim3122Kuo3Init, - dim3123Kuo3Init, - dim3124Kuo3Init, - dim3125Kuo3Init, - dim3126Kuo3Init, - dim3127Kuo3Init, - dim3128Kuo3Init, - dim3129Kuo3Init, - dim3130Kuo3Init, - dim3131Kuo3Init, - dim3132Kuo3Init, - dim3133Kuo3Init, - dim3134Kuo3Init, - dim3135Kuo3Init, - dim3136Kuo3Init, - dim3137Kuo3Init, - dim3138Kuo3Init, - dim3139Kuo3Init, - dim3140Kuo3Init, - dim3141Kuo3Init, - dim3142Kuo3Init, - dim3143Kuo3Init, - dim3144Kuo3Init, - dim3145Kuo3Init, - dim3146Kuo3Init, - dim3147Kuo3Init, - dim3148Kuo3Init, - dim3149Kuo3Init, - dim3150Kuo3Init, - dim3151Kuo3Init, - dim3152Kuo3Init, - dim3153Kuo3Init, - dim3154Kuo3Init, - dim3155Kuo3Init, - dim3156Kuo3Init, - dim3157Kuo3Init, - dim3158Kuo3Init, - dim3159Kuo3Init, - dim3160Kuo3Init, - dim3161Kuo3Init, - dim3162Kuo3Init, - dim3163Kuo3Init, - dim3164Kuo3Init, - dim3165Kuo3Init, - dim3166Kuo3Init, - dim3167Kuo3Init, - dim3168Kuo3Init, - dim3169Kuo3Init, - dim3170Kuo3Init, - dim3171Kuo3Init, - dim3172Kuo3Init, - dim3173Kuo3Init, - dim3174Kuo3Init, - dim3175Kuo3Init, - dim3176Kuo3Init, - dim3177Kuo3Init, - dim3178Kuo3Init, - dim3179Kuo3Init, - dim3180Kuo3Init, - dim3181Kuo3Init, - dim3182Kuo3Init, - dim3183Kuo3Init, - dim3184Kuo3Init, - dim3185Kuo3Init, - dim3186Kuo3Init, - dim3187Kuo3Init, - dim3188Kuo3Init, - dim3189Kuo3Init, - dim3190Kuo3Init, - dim3191Kuo3Init, - dim3192Kuo3Init, - dim3193Kuo3Init, - dim3194Kuo3Init, - dim3195Kuo3Init, - dim3196Kuo3Init, - dim3197Kuo3Init, - dim3198Kuo3Init, - dim3199Kuo3Init, - dim3200Kuo3Init, - dim3201Kuo3Init, - dim3202Kuo3Init, - dim3203Kuo3Init, - dim3204Kuo3Init, - dim3205Kuo3Init, - dim3206Kuo3Init, - dim3207Kuo3Init, - dim3208Kuo3Init, - dim3209Kuo3Init, - dim3210Kuo3Init, - dim3211Kuo3Init, - dim3212Kuo3Init, - dim3213Kuo3Init, - dim3214Kuo3Init, - dim3215Kuo3Init, - dim3216Kuo3Init, - dim3217Kuo3Init, - dim3218Kuo3Init, - dim3219Kuo3Init, - dim3220Kuo3Init, - dim3221Kuo3Init, - dim3222Kuo3Init, - dim3223Kuo3Init, - dim3224Kuo3Init, - dim3225Kuo3Init, - dim3226Kuo3Init, - dim3227Kuo3Init, - dim3228Kuo3Init, - dim3229Kuo3Init, - dim3230Kuo3Init, - dim3231Kuo3Init, - dim3232Kuo3Init, - dim3233Kuo3Init, - dim3234Kuo3Init, - dim3235Kuo3Init, - dim3236Kuo3Init, - dim3237Kuo3Init, - dim3238Kuo3Init, - dim3239Kuo3Init, - dim3240Kuo3Init, - dim3241Kuo3Init, - dim3242Kuo3Init, - dim3243Kuo3Init, - dim3244Kuo3Init, - dim3245Kuo3Init, - dim3246Kuo3Init, - dim3247Kuo3Init, - dim3248Kuo3Init, - dim3249Kuo3Init, - dim3250Kuo3Init, - dim3251Kuo3Init, - dim3252Kuo3Init, - dim3253Kuo3Init, - dim3254Kuo3Init, - dim3255Kuo3Init, - dim3256Kuo3Init, - dim3257Kuo3Init, - dim3258Kuo3Init, - dim3259Kuo3Init, - dim3260Kuo3Init, - dim3261Kuo3Init, - dim3262Kuo3Init, - dim3263Kuo3Init, - dim3264Kuo3Init, - dim3265Kuo3Init, - dim3266Kuo3Init, - dim3267Kuo3Init, - dim3268Kuo3Init, - dim3269Kuo3Init, - dim3270Kuo3Init, - dim3271Kuo3Init, - dim3272Kuo3Init, - dim3273Kuo3Init, - dim3274Kuo3Init, - dim3275Kuo3Init, - dim3276Kuo3Init, - dim3277Kuo3Init, - dim3278Kuo3Init, - dim3279Kuo3Init, - dim3280Kuo3Init, - dim3281Kuo3Init, - dim3282Kuo3Init, - dim3283Kuo3Init, - dim3284Kuo3Init, - dim3285Kuo3Init, - dim3286Kuo3Init, - dim3287Kuo3Init, - dim3288Kuo3Init, - dim3289Kuo3Init, - dim3290Kuo3Init, - dim3291Kuo3Init, - dim3292Kuo3Init, - dim3293Kuo3Init, - dim3294Kuo3Init, - dim3295Kuo3Init, - dim3296Kuo3Init, - dim3297Kuo3Init, - dim3298Kuo3Init, - dim3299Kuo3Init, - dim3300Kuo3Init, - dim3301Kuo3Init, - dim3302Kuo3Init, - dim3303Kuo3Init, - dim3304Kuo3Init, - dim3305Kuo3Init, - dim3306Kuo3Init, - dim3307Kuo3Init, - dim3308Kuo3Init, - dim3309Kuo3Init, - dim3310Kuo3Init, - dim3311Kuo3Init, - dim3312Kuo3Init, - dim3313Kuo3Init, - dim3314Kuo3Init, - dim3315Kuo3Init, - dim3316Kuo3Init, - dim3317Kuo3Init, - dim3318Kuo3Init, - dim3319Kuo3Init, - dim3320Kuo3Init, - dim3321Kuo3Init, - dim3322Kuo3Init, - dim3323Kuo3Init, - dim3324Kuo3Init, - dim3325Kuo3Init, - dim3326Kuo3Init, - dim3327Kuo3Init, - dim3328Kuo3Init, - dim3329Kuo3Init, - dim3330Kuo3Init, - dim3331Kuo3Init, - dim3332Kuo3Init, - dim3333Kuo3Init, - dim3334Kuo3Init, - dim3335Kuo3Init, - dim3336Kuo3Init, - dim3337Kuo3Init, - dim3338Kuo3Init, - dim3339Kuo3Init, - dim3340Kuo3Init, - dim3341Kuo3Init, - dim3342Kuo3Init, - dim3343Kuo3Init, - dim3344Kuo3Init, - dim3345Kuo3Init, - dim3346Kuo3Init, - dim3347Kuo3Init, - dim3348Kuo3Init, - dim3349Kuo3Init, - dim3350Kuo3Init, - dim3351Kuo3Init, - dim3352Kuo3Init, - dim3353Kuo3Init, - dim3354Kuo3Init, - dim3355Kuo3Init, - dim3356Kuo3Init, - dim3357Kuo3Init, - dim3358Kuo3Init, - dim3359Kuo3Init, - dim3360Kuo3Init, - dim3361Kuo3Init, - dim3362Kuo3Init, - dim3363Kuo3Init, - dim3364Kuo3Init, - dim3365Kuo3Init, - dim3366Kuo3Init, - dim3367Kuo3Init, - dim3368Kuo3Init, - dim3369Kuo3Init, - dim3370Kuo3Init, - dim3371Kuo3Init, - dim3372Kuo3Init, - dim3373Kuo3Init, - dim3374Kuo3Init, - dim3375Kuo3Init, - dim3376Kuo3Init, - dim3377Kuo3Init, - dim3378Kuo3Init, - dim3379Kuo3Init, - dim3380Kuo3Init, - dim3381Kuo3Init, - dim3382Kuo3Init, - dim3383Kuo3Init, - dim3384Kuo3Init, - dim3385Kuo3Init, - dim3386Kuo3Init, - dim3387Kuo3Init, - dim3388Kuo3Init, - dim3389Kuo3Init, - dim3390Kuo3Init, - dim3391Kuo3Init, - dim3392Kuo3Init, - dim3393Kuo3Init, - dim3394Kuo3Init, - dim3395Kuo3Init, - dim3396Kuo3Init, - dim3397Kuo3Init, - dim3398Kuo3Init, - dim3399Kuo3Init, - dim3400Kuo3Init, - dim3401Kuo3Init, - dim3402Kuo3Init, - dim3403Kuo3Init, - dim3404Kuo3Init, - dim3405Kuo3Init, - dim3406Kuo3Init, - dim3407Kuo3Init, - dim3408Kuo3Init, - dim3409Kuo3Init, - dim3410Kuo3Init, - dim3411Kuo3Init, - dim3412Kuo3Init, - dim3413Kuo3Init, - dim3414Kuo3Init, - dim3415Kuo3Init, - dim3416Kuo3Init, - dim3417Kuo3Init, - dim3418Kuo3Init, - dim3419Kuo3Init, - dim3420Kuo3Init, - dim3421Kuo3Init, - dim3422Kuo3Init, - dim3423Kuo3Init, - dim3424Kuo3Init, - dim3425Kuo3Init, - dim3426Kuo3Init, - dim3427Kuo3Init, - dim3428Kuo3Init, - dim3429Kuo3Init, - dim3430Kuo3Init, - dim3431Kuo3Init, - dim3432Kuo3Init, - dim3433Kuo3Init, - dim3434Kuo3Init, - dim3435Kuo3Init, - dim3436Kuo3Init, - dim3437Kuo3Init, - dim3438Kuo3Init, - dim3439Kuo3Init, - dim3440Kuo3Init, - dim3441Kuo3Init, - dim3442Kuo3Init, - dim3443Kuo3Init, - dim3444Kuo3Init, - dim3445Kuo3Init, - dim3446Kuo3Init, - dim3447Kuo3Init, - dim3448Kuo3Init, - dim3449Kuo3Init, - dim3450Kuo3Init, - dim3451Kuo3Init, - dim3452Kuo3Init, - dim3453Kuo3Init, - dim3454Kuo3Init, - dim3455Kuo3Init, - dim3456Kuo3Init, - dim3457Kuo3Init, - dim3458Kuo3Init, - dim3459Kuo3Init, - dim3460Kuo3Init, - dim3461Kuo3Init, - dim3462Kuo3Init, - dim3463Kuo3Init, - dim3464Kuo3Init, - dim3465Kuo3Init, - dim3466Kuo3Init, - dim3467Kuo3Init, - dim3468Kuo3Init, - dim3469Kuo3Init, - dim3470Kuo3Init, - dim3471Kuo3Init, - dim3472Kuo3Init, - dim3473Kuo3Init, - dim3474Kuo3Init, - dim3475Kuo3Init, - dim3476Kuo3Init, - dim3477Kuo3Init, - dim3478Kuo3Init, - dim3479Kuo3Init, - dim3480Kuo3Init, - dim3481Kuo3Init, - dim3482Kuo3Init, - dim3483Kuo3Init, - dim3484Kuo3Init, - dim3485Kuo3Init, - dim3486Kuo3Init, - dim3487Kuo3Init, - dim3488Kuo3Init, - dim3489Kuo3Init, - dim3490Kuo3Init, - dim3491Kuo3Init, - dim3492Kuo3Init, - dim3493Kuo3Init, - dim3494Kuo3Init, - dim3495Kuo3Init, - dim3496Kuo3Init, - dim3497Kuo3Init, - dim3498Kuo3Init, - dim3499Kuo3Init, - dim3500Kuo3Init, - dim3501Kuo3Init, - dim3502Kuo3Init, - dim3503Kuo3Init, - dim3504Kuo3Init, - dim3505Kuo3Init, - dim3506Kuo3Init, - dim3507Kuo3Init, - dim3508Kuo3Init, - dim3509Kuo3Init, - dim3510Kuo3Init, - dim3511Kuo3Init, - dim3512Kuo3Init, - dim3513Kuo3Init, - dim3514Kuo3Init, - dim3515Kuo3Init, - dim3516Kuo3Init, - dim3517Kuo3Init, - dim3518Kuo3Init, - dim3519Kuo3Init, - dim3520Kuo3Init, - dim3521Kuo3Init, - dim3522Kuo3Init, - dim3523Kuo3Init, - dim3524Kuo3Init, - dim3525Kuo3Init, - dim3526Kuo3Init, - dim3527Kuo3Init, - dim3528Kuo3Init, - dim3529Kuo3Init, - dim3530Kuo3Init, - dim3531Kuo3Init, - dim3532Kuo3Init, - dim3533Kuo3Init, - dim3534Kuo3Init, - dim3535Kuo3Init, - dim3536Kuo3Init, - dim3537Kuo3Init, - dim3538Kuo3Init, - dim3539Kuo3Init, - dim3540Kuo3Init, - dim3541Kuo3Init, - dim3542Kuo3Init, - dim3543Kuo3Init, - dim3544Kuo3Init, - dim3545Kuo3Init, - dim3546Kuo3Init, - dim3547Kuo3Init, - dim3548Kuo3Init, - dim3549Kuo3Init, - dim3550Kuo3Init, - dim3551Kuo3Init, - dim3552Kuo3Init, - dim3553Kuo3Init, - dim3554Kuo3Init, - dim3555Kuo3Init, - dim3556Kuo3Init, - dim3557Kuo3Init, - dim3558Kuo3Init, - dim3559Kuo3Init, - dim3560Kuo3Init, - dim3561Kuo3Init, - dim3562Kuo3Init, - dim3563Kuo3Init, - dim3564Kuo3Init, - dim3565Kuo3Init, - dim3566Kuo3Init, - dim3567Kuo3Init, - dim3568Kuo3Init, - dim3569Kuo3Init, - dim3570Kuo3Init, - dim3571Kuo3Init, - dim3572Kuo3Init, - dim3573Kuo3Init, - dim3574Kuo3Init, - dim3575Kuo3Init, - dim3576Kuo3Init, - dim3577Kuo3Init, - dim3578Kuo3Init, - dim3579Kuo3Init, - dim3580Kuo3Init, - dim3581Kuo3Init, - dim3582Kuo3Init, - dim3583Kuo3Init, - dim3584Kuo3Init, - dim3585Kuo3Init, - dim3586Kuo3Init, - dim3587Kuo3Init, - dim3588Kuo3Init, - dim3589Kuo3Init, - dim3590Kuo3Init, - dim3591Kuo3Init, - dim3592Kuo3Init, - dim3593Kuo3Init, - dim3594Kuo3Init, - dim3595Kuo3Init, - dim3596Kuo3Init, - dim3597Kuo3Init, - dim3598Kuo3Init, - dim3599Kuo3Init, - dim3600Kuo3Init, - dim3601Kuo3Init, - dim3602Kuo3Init, - dim3603Kuo3Init, - dim3604Kuo3Init, - dim3605Kuo3Init, - dim3606Kuo3Init, - dim3607Kuo3Init, - dim3608Kuo3Init, - dim3609Kuo3Init, - dim3610Kuo3Init, - dim3611Kuo3Init, - dim3612Kuo3Init, - dim3613Kuo3Init, - dim3614Kuo3Init, - dim3615Kuo3Init, - dim3616Kuo3Init, - dim3617Kuo3Init, - dim3618Kuo3Init, - dim3619Kuo3Init, - dim3620Kuo3Init, - dim3621Kuo3Init, - dim3622Kuo3Init, - dim3623Kuo3Init, - dim3624Kuo3Init, - dim3625Kuo3Init, - dim3626Kuo3Init, - dim3627Kuo3Init, - dim3628Kuo3Init, - dim3629Kuo3Init, - dim3630Kuo3Init, - dim3631Kuo3Init, - dim3632Kuo3Init, - dim3633Kuo3Init, - dim3634Kuo3Init, - dim3635Kuo3Init, - dim3636Kuo3Init, - dim3637Kuo3Init, - dim3638Kuo3Init, - dim3639Kuo3Init, - dim3640Kuo3Init, - dim3641Kuo3Init, - dim3642Kuo3Init, - dim3643Kuo3Init, - dim3644Kuo3Init, - dim3645Kuo3Init, - dim3646Kuo3Init, - dim3647Kuo3Init, - dim3648Kuo3Init, - dim3649Kuo3Init, - dim3650Kuo3Init, - dim3651Kuo3Init, - dim3652Kuo3Init, - dim3653Kuo3Init, - dim3654Kuo3Init, - dim3655Kuo3Init, - dim3656Kuo3Init, - dim3657Kuo3Init, - dim3658Kuo3Init, - dim3659Kuo3Init, - dim3660Kuo3Init, - dim3661Kuo3Init, - dim3662Kuo3Init, - dim3663Kuo3Init, - dim3664Kuo3Init, - dim3665Kuo3Init, - dim3666Kuo3Init, - dim3667Kuo3Init, - dim3668Kuo3Init, - dim3669Kuo3Init, - dim3670Kuo3Init, - dim3671Kuo3Init, - dim3672Kuo3Init, - dim3673Kuo3Init, - dim3674Kuo3Init, - dim3675Kuo3Init, - dim3676Kuo3Init, - dim3677Kuo3Init, - dim3678Kuo3Init, - dim3679Kuo3Init, - dim3680Kuo3Init, - dim3681Kuo3Init, - dim3682Kuo3Init, - dim3683Kuo3Init, - dim3684Kuo3Init, - dim3685Kuo3Init, - dim3686Kuo3Init, - dim3687Kuo3Init, - dim3688Kuo3Init, - dim3689Kuo3Init, - dim3690Kuo3Init, - dim3691Kuo3Init, - dim3692Kuo3Init, - dim3693Kuo3Init, - dim3694Kuo3Init, - dim3695Kuo3Init, - dim3696Kuo3Init, - dim3697Kuo3Init, - dim3698Kuo3Init, - dim3699Kuo3Init, - dim3700Kuo3Init, - dim3701Kuo3Init, - dim3702Kuo3Init, - dim3703Kuo3Init, - dim3704Kuo3Init, - dim3705Kuo3Init, - dim3706Kuo3Init, - dim3707Kuo3Init, - dim3708Kuo3Init, - dim3709Kuo3Init, - dim3710Kuo3Init, - dim3711Kuo3Init, - dim3712Kuo3Init, - dim3713Kuo3Init, - dim3714Kuo3Init, - dim3715Kuo3Init, - dim3716Kuo3Init, - dim3717Kuo3Init, - dim3718Kuo3Init, - dim3719Kuo3Init, - dim3720Kuo3Init, - dim3721Kuo3Init, - dim3722Kuo3Init, - dim3723Kuo3Init, - dim3724Kuo3Init, - dim3725Kuo3Init, - dim3726Kuo3Init, - dim3727Kuo3Init, - dim3728Kuo3Init, - dim3729Kuo3Init, - dim3730Kuo3Init, - dim3731Kuo3Init, - dim3732Kuo3Init, - dim3733Kuo3Init, - dim3734Kuo3Init, - dim3735Kuo3Init, - dim3736Kuo3Init, - dim3737Kuo3Init, - dim3738Kuo3Init, - dim3739Kuo3Init, - dim3740Kuo3Init, - dim3741Kuo3Init, - dim3742Kuo3Init, - dim3743Kuo3Init, - dim3744Kuo3Init, - dim3745Kuo3Init, - dim3746Kuo3Init, - dim3747Kuo3Init, - dim3748Kuo3Init, - dim3749Kuo3Init, - dim3750Kuo3Init, - dim3751Kuo3Init, - dim3752Kuo3Init, - dim3753Kuo3Init, - dim3754Kuo3Init, - dim3755Kuo3Init, - dim3756Kuo3Init, - dim3757Kuo3Init, - dim3758Kuo3Init, - dim3759Kuo3Init, - dim3760Kuo3Init, - dim3761Kuo3Init, - dim3762Kuo3Init, - dim3763Kuo3Init, - dim3764Kuo3Init, - dim3765Kuo3Init, - dim3766Kuo3Init, - dim3767Kuo3Init, - dim3768Kuo3Init, - dim3769Kuo3Init, - dim3770Kuo3Init, - dim3771Kuo3Init, - dim3772Kuo3Init, - dim3773Kuo3Init, - dim3774Kuo3Init, - dim3775Kuo3Init, - dim3776Kuo3Init, - dim3777Kuo3Init, - dim3778Kuo3Init, - dim3779Kuo3Init, - dim3780Kuo3Init, - dim3781Kuo3Init, - dim3782Kuo3Init, - dim3783Kuo3Init, - dim3784Kuo3Init, - dim3785Kuo3Init, - dim3786Kuo3Init, - dim3787Kuo3Init, - dim3788Kuo3Init, - dim3789Kuo3Init, - dim3790Kuo3Init, - dim3791Kuo3Init, - dim3792Kuo3Init, - dim3793Kuo3Init, - dim3794Kuo3Init, - dim3795Kuo3Init, - dim3796Kuo3Init, - dim3797Kuo3Init, - dim3798Kuo3Init, - dim3799Kuo3Init, - dim3800Kuo3Init, - dim3801Kuo3Init, - dim3802Kuo3Init, - dim3803Kuo3Init, - dim3804Kuo3Init, - dim3805Kuo3Init, - dim3806Kuo3Init, - dim3807Kuo3Init, - dim3808Kuo3Init, - dim3809Kuo3Init, - dim3810Kuo3Init, - dim3811Kuo3Init, - dim3812Kuo3Init, - dim3813Kuo3Init, - dim3814Kuo3Init, - dim3815Kuo3Init, - dim3816Kuo3Init, - dim3817Kuo3Init, - dim3818Kuo3Init, - dim3819Kuo3Init, - dim3820Kuo3Init, - dim3821Kuo3Init, - dim3822Kuo3Init, - dim3823Kuo3Init, - dim3824Kuo3Init, - dim3825Kuo3Init, - dim3826Kuo3Init, - dim3827Kuo3Init, - dim3828Kuo3Init, - dim3829Kuo3Init, - dim3830Kuo3Init, - dim3831Kuo3Init, - dim3832Kuo3Init, - dim3833Kuo3Init, - dim3834Kuo3Init, - dim3835Kuo3Init, - dim3836Kuo3Init, - dim3837Kuo3Init, - dim3838Kuo3Init, - dim3839Kuo3Init, - dim3840Kuo3Init, - dim3841Kuo3Init, - dim3842Kuo3Init, - dim3843Kuo3Init, - dim3844Kuo3Init, - dim3845Kuo3Init, - dim3846Kuo3Init, - dim3847Kuo3Init, - dim3848Kuo3Init, - dim3849Kuo3Init, - dim3850Kuo3Init, - dim3851Kuo3Init, - dim3852Kuo3Init, - dim3853Kuo3Init, - dim3854Kuo3Init, - dim3855Kuo3Init, - dim3856Kuo3Init, - dim3857Kuo3Init, - dim3858Kuo3Init, - dim3859Kuo3Init, - dim3860Kuo3Init, - dim3861Kuo3Init, - dim3862Kuo3Init, - dim3863Kuo3Init, - dim3864Kuo3Init, - dim3865Kuo3Init, - dim3866Kuo3Init, - dim3867Kuo3Init, - dim3868Kuo3Init, - dim3869Kuo3Init, - dim3870Kuo3Init, - dim3871Kuo3Init, - dim3872Kuo3Init, - dim3873Kuo3Init, - dim3874Kuo3Init, - dim3875Kuo3Init, - dim3876Kuo3Init, - dim3877Kuo3Init, - dim3878Kuo3Init, - dim3879Kuo3Init, - dim3880Kuo3Init, - dim3881Kuo3Init, - dim3882Kuo3Init, - dim3883Kuo3Init, - dim3884Kuo3Init, - dim3885Kuo3Init, - dim3886Kuo3Init, - dim3887Kuo3Init, - dim3888Kuo3Init, - dim3889Kuo3Init, - dim3890Kuo3Init, - dim3891Kuo3Init, - dim3892Kuo3Init, - dim3893Kuo3Init, - dim3894Kuo3Init, - dim3895Kuo3Init, - dim3896Kuo3Init, - dim3897Kuo3Init, - dim3898Kuo3Init, - dim3899Kuo3Init, - dim3900Kuo3Init, - dim3901Kuo3Init, - dim3902Kuo3Init, - dim3903Kuo3Init, - dim3904Kuo3Init, - dim3905Kuo3Init, - dim3906Kuo3Init, - dim3907Kuo3Init, - dim3908Kuo3Init, - dim3909Kuo3Init, - dim3910Kuo3Init, - dim3911Kuo3Init, - dim3912Kuo3Init, - dim3913Kuo3Init, - dim3914Kuo3Init, - dim3915Kuo3Init, - dim3916Kuo3Init, - dim3917Kuo3Init, - dim3918Kuo3Init, - dim3919Kuo3Init, - dim3920Kuo3Init, - dim3921Kuo3Init, - dim3922Kuo3Init, - dim3923Kuo3Init, - dim3924Kuo3Init, - dim3925Kuo3Init, - dim3926Kuo3Init, - dim3927Kuo3Init, - dim3928Kuo3Init, - dim3929Kuo3Init, - dim3930Kuo3Init, - dim3931Kuo3Init, - dim3932Kuo3Init, - dim3933Kuo3Init, - dim3934Kuo3Init, - dim3935Kuo3Init, - dim3936Kuo3Init, - dim3937Kuo3Init, - dim3938Kuo3Init, - dim3939Kuo3Init, - dim3940Kuo3Init, - dim3941Kuo3Init, - dim3942Kuo3Init, - dim3943Kuo3Init, - dim3944Kuo3Init, - dim3945Kuo3Init, - dim3946Kuo3Init, - dim3947Kuo3Init, - dim3948Kuo3Init, - dim3949Kuo3Init, - dim3950Kuo3Init, - dim3951Kuo3Init, - dim3952Kuo3Init, - dim3953Kuo3Init, - dim3954Kuo3Init, - dim3955Kuo3Init, - dim3956Kuo3Init, - dim3957Kuo3Init, - dim3958Kuo3Init, - dim3959Kuo3Init, - dim3960Kuo3Init, - dim3961Kuo3Init, - dim3962Kuo3Init, - dim3963Kuo3Init, - dim3964Kuo3Init, - dim3965Kuo3Init, - dim3966Kuo3Init, - dim3967Kuo3Init, - dim3968Kuo3Init, - dim3969Kuo3Init, - dim3970Kuo3Init, - dim3971Kuo3Init, - dim3972Kuo3Init, - dim3973Kuo3Init, - dim3974Kuo3Init, - dim3975Kuo3Init, - dim3976Kuo3Init, - dim3977Kuo3Init, - dim3978Kuo3Init, - dim3979Kuo3Init, - dim3980Kuo3Init, - dim3981Kuo3Init, - dim3982Kuo3Init, - dim3983Kuo3Init, - dim3984Kuo3Init, - dim3985Kuo3Init, - dim3986Kuo3Init, - dim3987Kuo3Init, - dim3988Kuo3Init, - dim3989Kuo3Init, - dim3990Kuo3Init, - dim3991Kuo3Init, - dim3992Kuo3Init, - dim3993Kuo3Init, - dim3994Kuo3Init, - dim3995Kuo3Init, - dim3996Kuo3Init, - dim3997Kuo3Init, - dim3998Kuo3Init, - dim3999Kuo3Init, - dim4000Kuo3Init, - dim4001Kuo3Init, - dim4002Kuo3Init, - dim4003Kuo3Init, - dim4004Kuo3Init, - dim4005Kuo3Init, - dim4006Kuo3Init, - dim4007Kuo3Init, - dim4008Kuo3Init, - dim4009Kuo3Init, - dim4010Kuo3Init, - dim4011Kuo3Init, - dim4012Kuo3Init, - dim4013Kuo3Init, - dim4014Kuo3Init, - dim4015Kuo3Init, - dim4016Kuo3Init, - dim4017Kuo3Init, - dim4018Kuo3Init, - dim4019Kuo3Init, - dim4020Kuo3Init, - dim4021Kuo3Init, - dim4022Kuo3Init, - dim4023Kuo3Init, - dim4024Kuo3Init, - dim4025Kuo3Init, - dim4026Kuo3Init, - dim4027Kuo3Init, - dim4028Kuo3Init, - dim4029Kuo3Init, - dim4030Kuo3Init, - dim4031Kuo3Init, - dim4032Kuo3Init, - dim4033Kuo3Init, - dim4034Kuo3Init, - dim4035Kuo3Init, - dim4036Kuo3Init, - dim4037Kuo3Init, - dim4038Kuo3Init, - dim4039Kuo3Init, - dim4040Kuo3Init, - dim4041Kuo3Init, - dim4042Kuo3Init, - dim4043Kuo3Init, - dim4044Kuo3Init, - dim4045Kuo3Init, - dim4046Kuo3Init, - dim4047Kuo3Init, - dim4048Kuo3Init, - dim4049Kuo3Init, - dim4050Kuo3Init, - dim4051Kuo3Init, - dim4052Kuo3Init, - dim4053Kuo3Init, - dim4054Kuo3Init, - dim4055Kuo3Init, - dim4056Kuo3Init, - dim4057Kuo3Init, - dim4058Kuo3Init, - dim4059Kuo3Init, - dim4060Kuo3Init, - dim4061Kuo3Init, - dim4062Kuo3Init, - dim4063Kuo3Init, - dim4064Kuo3Init, - dim4065Kuo3Init, - dim4066Kuo3Init, - dim4067Kuo3Init, - dim4068Kuo3Init, - dim4069Kuo3Init, - dim4070Kuo3Init, - dim4071Kuo3Init, - dim4072Kuo3Init, - dim4073Kuo3Init, - dim4074Kuo3Init, - dim4075Kuo3Init, - dim4076Kuo3Init, - dim4077Kuo3Init, - dim4078Kuo3Init, - dim4079Kuo3Init, - dim4080Kuo3Init, - dim4081Kuo3Init, - dim4082Kuo3Init, - dim4083Kuo3Init, - dim4084Kuo3Init, - dim4085Kuo3Init, - dim4086Kuo3Init, - dim4087Kuo3Init, - dim4088Kuo3Init, - dim4089Kuo3Init, - dim4090Kuo3Init, - dim4091Kuo3Init, - dim4092Kuo3Init, - dim4093Kuo3Init, - dim4094Kuo3Init, - dim4095Kuo3Init, - dim4096Kuo3Init, - dim4097Kuo3Init, - dim4098Kuo3Init, - dim4099Kuo3Init, - dim4100Kuo3Init, - dim4101Kuo3Init, - dim4102Kuo3Init, - dim4103Kuo3Init, - dim4104Kuo3Init, - dim4105Kuo3Init, - dim4106Kuo3Init, - dim4107Kuo3Init, - dim4108Kuo3Init, - dim4109Kuo3Init, - dim4110Kuo3Init, - dim4111Kuo3Init, - dim4112Kuo3Init, - dim4113Kuo3Init, - dim4114Kuo3Init, - dim4115Kuo3Init, - dim4116Kuo3Init, - dim4117Kuo3Init, - dim4118Kuo3Init, - dim4119Kuo3Init, - dim4120Kuo3Init, - dim4121Kuo3Init, - dim4122Kuo3Init, - dim4123Kuo3Init, - dim4124Kuo3Init, - dim4125Kuo3Init, - dim4126Kuo3Init, - dim4127Kuo3Init, - dim4128Kuo3Init, - dim4129Kuo3Init, - dim4130Kuo3Init, - dim4131Kuo3Init, - dim4132Kuo3Init, - dim4133Kuo3Init, - dim4134Kuo3Init, - dim4135Kuo3Init, - dim4136Kuo3Init, - dim4137Kuo3Init, - dim4138Kuo3Init, - dim4139Kuo3Init, - dim4140Kuo3Init, - dim4141Kuo3Init, - dim4142Kuo3Init, - dim4143Kuo3Init, - dim4144Kuo3Init, - dim4145Kuo3Init, - dim4146Kuo3Init, - dim4147Kuo3Init, - dim4148Kuo3Init, - dim4149Kuo3Init, - dim4150Kuo3Init, - dim4151Kuo3Init, - dim4152Kuo3Init, - dim4153Kuo3Init, - dim4154Kuo3Init, - dim4155Kuo3Init, - dim4156Kuo3Init, - dim4157Kuo3Init, - dim4158Kuo3Init, - dim4159Kuo3Init, - dim4160Kuo3Init, - dim4161Kuo3Init, - dim4162Kuo3Init, - dim4163Kuo3Init, - dim4164Kuo3Init, - dim4165Kuo3Init, - dim4166Kuo3Init, - dim4167Kuo3Init, - dim4168Kuo3Init, - dim4169Kuo3Init, - dim4170Kuo3Init, - dim4171Kuo3Init, - dim4172Kuo3Init, - dim4173Kuo3Init, - dim4174Kuo3Init, - dim4175Kuo3Init, - dim4176Kuo3Init, - dim4177Kuo3Init, - dim4178Kuo3Init, - dim4179Kuo3Init, - dim4180Kuo3Init, - dim4181Kuo3Init, - dim4182Kuo3Init, - dim4183Kuo3Init, - dim4184Kuo3Init, - dim4185Kuo3Init, - dim4186Kuo3Init, - dim4187Kuo3Init, - dim4188Kuo3Init, - dim4189Kuo3Init, - dim4190Kuo3Init, - dim4191Kuo3Init, - dim4192Kuo3Init, - dim4193Kuo3Init, - dim4194Kuo3Init, - dim4195Kuo3Init, - dim4196Kuo3Init, - dim4197Kuo3Init, - dim4198Kuo3Init, - dim4199Kuo3Init, - dim4200Kuo3Init, - dim4201Kuo3Init, - dim4202Kuo3Init, - dim4203Kuo3Init, - dim4204Kuo3Init, - dim4205Kuo3Init, - dim4206Kuo3Init, - dim4207Kuo3Init, - dim4208Kuo3Init, - dim4209Kuo3Init, - dim4210Kuo3Init, - dim4211Kuo3Init, - dim4212Kuo3Init, - dim4213Kuo3Init, - dim4214Kuo3Init, - dim4215Kuo3Init, - dim4216Kuo3Init, - dim4217Kuo3Init, - dim4218Kuo3Init, - dim4219Kuo3Init, - dim4220Kuo3Init, - dim4221Kuo3Init, - dim4222Kuo3Init, - dim4223Kuo3Init, - dim4224Kuo3Init, - dim4225Kuo3Init, - dim4226Kuo3Init, - dim4227Kuo3Init, - dim4228Kuo3Init, - dim4229Kuo3Init, - dim4230Kuo3Init, - dim4231Kuo3Init, - dim4232Kuo3Init, - dim4233Kuo3Init, - dim4234Kuo3Init, - dim4235Kuo3Init, - dim4236Kuo3Init, - dim4237Kuo3Init, - dim4238Kuo3Init, - dim4239Kuo3Init, - dim4240Kuo3Init, - dim4241Kuo3Init, - dim4242Kuo3Init, - dim4243Kuo3Init, - dim4244Kuo3Init, - dim4245Kuo3Init, - dim4246Kuo3Init, - dim4247Kuo3Init, - dim4248Kuo3Init, - dim4249Kuo3Init, - dim4250Kuo3Init, - dim4251Kuo3Init, - dim4252Kuo3Init, - dim4253Kuo3Init, - dim4254Kuo3Init, - dim4255Kuo3Init, - dim4256Kuo3Init, - dim4257Kuo3Init, - dim4258Kuo3Init, - dim4259Kuo3Init, - dim4260Kuo3Init, - dim4261Kuo3Init, - dim4262Kuo3Init, - dim4263Kuo3Init, - dim4264Kuo3Init, - dim4265Kuo3Init, - dim4266Kuo3Init, - dim4267Kuo3Init, - dim4268Kuo3Init, - dim4269Kuo3Init, - dim4270Kuo3Init, - dim4271Kuo3Init, - dim4272Kuo3Init, - dim4273Kuo3Init, - dim4274Kuo3Init, - dim4275Kuo3Init, - dim4276Kuo3Init, - dim4277Kuo3Init, - dim4278Kuo3Init, - dim4279Kuo3Init, - dim4280Kuo3Init, - dim4281Kuo3Init, - dim4282Kuo3Init, - dim4283Kuo3Init, - dim4284Kuo3Init, - dim4285Kuo3Init, - dim4286Kuo3Init, - dim4287Kuo3Init, - dim4288Kuo3Init, - dim4289Kuo3Init, - dim4290Kuo3Init, - dim4291Kuo3Init, - dim4292Kuo3Init, - dim4293Kuo3Init, - dim4294Kuo3Init, - dim4295Kuo3Init, - dim4296Kuo3Init, - dim4297Kuo3Init, - dim4298Kuo3Init, - dim4299Kuo3Init, - dim4300Kuo3Init, - dim4301Kuo3Init, - dim4302Kuo3Init, - dim4303Kuo3Init, - dim4304Kuo3Init, - dim4305Kuo3Init, - dim4306Kuo3Init, - dim4307Kuo3Init, - dim4308Kuo3Init, - dim4309Kuo3Init, - dim4310Kuo3Init, - dim4311Kuo3Init, - dim4312Kuo3Init, - dim4313Kuo3Init, - dim4314Kuo3Init, - dim4315Kuo3Init, - dim4316Kuo3Init, - dim4317Kuo3Init, - dim4318Kuo3Init, - dim4319Kuo3Init, - dim4320Kuo3Init, - dim4321Kuo3Init, - dim4322Kuo3Init, - dim4323Kuo3Init, - dim4324Kuo3Init, - dim4325Kuo3Init, - dim4326Kuo3Init, - dim4327Kuo3Init, - dim4328Kuo3Init, - dim4329Kuo3Init, - dim4330Kuo3Init, - dim4331Kuo3Init, - dim4332Kuo3Init, - dim4333Kuo3Init, - dim4334Kuo3Init, - dim4335Kuo3Init, - dim4336Kuo3Init, - dim4337Kuo3Init, - dim4338Kuo3Init, - dim4339Kuo3Init, - dim4340Kuo3Init, - dim4341Kuo3Init, - dim4342Kuo3Init, - dim4343Kuo3Init, - dim4344Kuo3Init, - dim4345Kuo3Init, - dim4346Kuo3Init, - dim4347Kuo3Init, - dim4348Kuo3Init, - dim4349Kuo3Init, - dim4350Kuo3Init, - dim4351Kuo3Init, - dim4352Kuo3Init, - dim4353Kuo3Init, - dim4354Kuo3Init, - dim4355Kuo3Init, - dim4356Kuo3Init, - dim4357Kuo3Init, - dim4358Kuo3Init, - dim4359Kuo3Init, - dim4360Kuo3Init, - dim4361Kuo3Init, - dim4362Kuo3Init, - dim4363Kuo3Init, - dim4364Kuo3Init, - dim4365Kuo3Init, - dim4366Kuo3Init, - dim4367Kuo3Init, - dim4368Kuo3Init, - dim4369Kuo3Init, - dim4370Kuo3Init, - dim4371Kuo3Init, - dim4372Kuo3Init, - dim4373Kuo3Init, - dim4374Kuo3Init, - dim4375Kuo3Init, - dim4376Kuo3Init, - dim4377Kuo3Init, - dim4378Kuo3Init, - dim4379Kuo3Init, - dim4380Kuo3Init, - dim4381Kuo3Init, - dim4382Kuo3Init, - dim4383Kuo3Init, - dim4384Kuo3Init, - dim4385Kuo3Init, - dim4386Kuo3Init, - dim4387Kuo3Init, - dim4388Kuo3Init, - dim4389Kuo3Init, - dim4390Kuo3Init, - dim4391Kuo3Init, - dim4392Kuo3Init, - dim4393Kuo3Init, - dim4394Kuo3Init, - dim4395Kuo3Init, - dim4396Kuo3Init, - dim4397Kuo3Init, - dim4398Kuo3Init, - dim4399Kuo3Init, - dim4400Kuo3Init, - dim4401Kuo3Init, - dim4402Kuo3Init, - dim4403Kuo3Init, - dim4404Kuo3Init, - dim4405Kuo3Init, - dim4406Kuo3Init, - dim4407Kuo3Init, - dim4408Kuo3Init, - dim4409Kuo3Init, - dim4410Kuo3Init, - dim4411Kuo3Init, - dim4412Kuo3Init, - dim4413Kuo3Init, - dim4414Kuo3Init, - dim4415Kuo3Init, - dim4416Kuo3Init, - dim4417Kuo3Init, - dim4418Kuo3Init, - dim4419Kuo3Init, - dim4420Kuo3Init, - dim4421Kuo3Init, - dim4422Kuo3Init, - dim4423Kuo3Init, - dim4424Kuo3Init, - dim4425Kuo3Init, - dim4426Kuo3Init, - dim4427Kuo3Init, - dim4428Kuo3Init, - dim4429Kuo3Init, - dim4430Kuo3Init, - dim4431Kuo3Init, - dim4432Kuo3Init, - dim4433Kuo3Init, - dim4434Kuo3Init, - dim4435Kuo3Init, - dim4436Kuo3Init, - dim4437Kuo3Init, - dim4438Kuo3Init, - dim4439Kuo3Init, - dim4440Kuo3Init, - dim4441Kuo3Init, - dim4442Kuo3Init, - dim4443Kuo3Init, - dim4444Kuo3Init, - dim4445Kuo3Init, - dim4446Kuo3Init, - dim4447Kuo3Init, - dim4448Kuo3Init, - dim4449Kuo3Init, - dim4450Kuo3Init, - dim4451Kuo3Init, - dim4452Kuo3Init, - dim4453Kuo3Init, - dim4454Kuo3Init, - dim4455Kuo3Init, - dim4456Kuo3Init, - dim4457Kuo3Init, - dim4458Kuo3Init, - dim4459Kuo3Init, - dim4460Kuo3Init, - dim4461Kuo3Init, - dim4462Kuo3Init, - dim4463Kuo3Init, - dim4464Kuo3Init, - dim4465Kuo3Init, - dim4466Kuo3Init, - dim4467Kuo3Init, - dim4468Kuo3Init, - dim4469Kuo3Init, - dim4470Kuo3Init, - dim4471Kuo3Init, - dim4472Kuo3Init, - dim4473Kuo3Init, - dim4474Kuo3Init, - dim4475Kuo3Init, - dim4476Kuo3Init, - dim4477Kuo3Init, - dim4478Kuo3Init, - dim4479Kuo3Init, - dim4480Kuo3Init, - dim4481Kuo3Init, - dim4482Kuo3Init, - dim4483Kuo3Init, - dim4484Kuo3Init, - dim4485Kuo3Init, - dim4486Kuo3Init, - dim4487Kuo3Init, - dim4488Kuo3Init, - dim4489Kuo3Init, - dim4490Kuo3Init, - dim4491Kuo3Init, - dim4492Kuo3Init, - dim4493Kuo3Init, - dim4494Kuo3Init, - dim4495Kuo3Init, - dim4496Kuo3Init, - dim4497Kuo3Init, - dim4498Kuo3Init, - dim4499Kuo3Init, - dim4500Kuo3Init, - dim4501Kuo3Init, - dim4502Kuo3Init, - dim4503Kuo3Init, - dim4504Kuo3Init, - dim4505Kuo3Init, - dim4506Kuo3Init, - dim4507Kuo3Init, - dim4508Kuo3Init, - dim4509Kuo3Init, - dim4510Kuo3Init, - dim4511Kuo3Init, - dim4512Kuo3Init, - dim4513Kuo3Init, - dim4514Kuo3Init, - dim4515Kuo3Init, - dim4516Kuo3Init, - dim4517Kuo3Init, - dim4518Kuo3Init, - dim4519Kuo3Init, - dim4520Kuo3Init, - dim4521Kuo3Init, - dim4522Kuo3Init, - dim4523Kuo3Init, - dim4524Kuo3Init, - dim4525Kuo3Init, - dim4526Kuo3Init, - dim4527Kuo3Init, - dim4528Kuo3Init, - dim4529Kuo3Init, - dim4530Kuo3Init, - dim4531Kuo3Init, - dim4532Kuo3Init, - dim4533Kuo3Init, - dim4534Kuo3Init, - dim4535Kuo3Init, - dim4536Kuo3Init, - dim4537Kuo3Init, - dim4538Kuo3Init, - dim4539Kuo3Init, - dim4540Kuo3Init, - dim4541Kuo3Init, - dim4542Kuo3Init, - dim4543Kuo3Init, - dim4544Kuo3Init, - dim4545Kuo3Init, - dim4546Kuo3Init, - dim4547Kuo3Init, - dim4548Kuo3Init, - dim4549Kuo3Init, - dim4550Kuo3Init, - dim4551Kuo3Init, - dim4552Kuo3Init, - dim4553Kuo3Init, - dim4554Kuo3Init, - dim4555Kuo3Init, - dim4556Kuo3Init, - dim4557Kuo3Init, - dim4558Kuo3Init, - dim4559Kuo3Init, - dim4560Kuo3Init, - dim4561Kuo3Init, - dim4562Kuo3Init, - dim4563Kuo3Init, - dim4564Kuo3Init, - dim4565Kuo3Init, - dim4566Kuo3Init, - dim4567Kuo3Init, - dim4568Kuo3Init, - dim4569Kuo3Init, - dim4570Kuo3Init, - dim4571Kuo3Init, - dim4572Kuo3Init, - dim4573Kuo3Init, - dim4574Kuo3Init, - dim4575Kuo3Init, - dim4576Kuo3Init, - dim4577Kuo3Init, - dim4578Kuo3Init, - dim4579Kuo3Init, - dim4580Kuo3Init, - dim4581Kuo3Init, - dim4582Kuo3Init, - dim4583Kuo3Init, - dim4584Kuo3Init, - dim4585Kuo3Init, - dim4586Kuo3Init - }; - - static ulong[] dim1JoeKuoD6Init = { 1, 0 }; - static ulong[] dim2JoeKuoD6Init = { 1, 3, 0 }; - static ulong[] dim3JoeKuoD6Init = { 1, 3, 1, 0 }; - static ulong[] dim4JoeKuoD6Init = { 1, 1, 1, 0 }; - static ulong[] dim5JoeKuoD6Init = { 1, 1, 3, 3, 0 }; - static ulong[] dim6JoeKuoD6Init = { 1, 3, 5, 13, 0 }; - static ulong[] dim7JoeKuoD6Init = { 1, 1, 5, 5, 17, 0 }; - static ulong[] dim8JoeKuoD6Init = { 1, 1, 5, 5, 5, 0 }; - static ulong[] dim9JoeKuoD6Init = { 1, 1, 7, 11, 19, 0 }; - static ulong[] dim10JoeKuoD6Init = { 1, 1, 5, 1, 1, 0 }; - static ulong[] dim11JoeKuoD6Init = { 1, 1, 1, 3, 11, 0 }; - static ulong[] dim12JoeKuoD6Init = { 1, 3, 5, 5, 31, 0 }; - static ulong[] dim13JoeKuoD6Init = { 1, 3, 3, 9, 7, 49, 0 }; - static ulong[] dim14JoeKuoD6Init = { 1, 1, 1, 15, 21, 21, 0 }; - static ulong[] dim15JoeKuoD6Init = { 1, 3, 1, 13, 27, 49, 0 }; - static ulong[] dim16JoeKuoD6Init = { 1, 1, 1, 15, 7, 5, 0 }; - static ulong[] dim17JoeKuoD6Init = { 1, 3, 1, 15, 13, 25, 0 }; - static ulong[] dim18JoeKuoD6Init = { 1, 1, 5, 5, 19, 61, 0 }; - static ulong[] dim19JoeKuoD6Init = { 1, 3, 7, 11, 23, 15, 103, 0 }; - static ulong[] dim20JoeKuoD6Init = { 1, 3, 7, 13, 13, 15, 69, 0 }; - static ulong[] dim21JoeKuoD6Init = { 1, 1, 3, 13, 7, 35, 63, 0 }; - static ulong[] dim22JoeKuoD6Init = { 1, 3, 5, 9, 1, 25, 53, 0 }; - static ulong[] dim23JoeKuoD6Init = { 1, 3, 1, 13, 9, 35, 107, 0 }; - static ulong[] dim24JoeKuoD6Init = { 1, 3, 1, 5, 27, 61, 31, 0 }; - static ulong[] dim25JoeKuoD6Init = { 1, 1, 5, 11, 19, 41, 61, 0 }; - static ulong[] dim26JoeKuoD6Init = { 1, 3, 5, 3, 3, 13, 69, 0 }; - static ulong[] dim27JoeKuoD6Init = { 1, 1, 7, 13, 1, 19, 1, 0 }; - static ulong[] dim28JoeKuoD6Init = { 1, 3, 7, 5, 13, 19, 59, 0 }; - static ulong[] dim29JoeKuoD6Init = { 1, 1, 3, 9, 25, 29, 41, 0 }; - static ulong[] dim30JoeKuoD6Init = { 1, 3, 5, 13, 23, 1, 55, 0 }; - static ulong[] dim31JoeKuoD6Init = { 1, 3, 7, 3, 13, 59, 17, 0 }; - static ulong[] dim32JoeKuoD6Init = { 1, 3, 1, 3, 5, 53, 69, 0 }; - static ulong[] dim33JoeKuoD6Init = { 1, 1, 5, 5, 23, 33, 13, 0 }; - static ulong[] dim34JoeKuoD6Init = { 1, 1, 7, 7, 1, 61, 123, 0 }; - static ulong[] dim35JoeKuoD6Init = { 1, 1, 7, 9, 13, 61, 49, 0 }; - static ulong[] dim36JoeKuoD6Init = { 1, 3, 3, 5, 3, 55, 33, 0 }; - static ulong[] dim37JoeKuoD6Init = { 1, 3, 1, 15, 31, 13, 49, 245, 0 }; - static ulong[] dim38JoeKuoD6Init = { 1, 3, 5, 15, 31, 59, 63, 97, 0 }; - static ulong[] dim39JoeKuoD6Init = { 1, 3, 1, 11, 11, 11, 77, 249, 0 }; - static ulong[] dim40JoeKuoD6Init = { 1, 3, 1, 11, 27, 43, 71, 9, 0 }; - static ulong[] dim41JoeKuoD6Init = { 1, 1, 7, 15, 21, 11, 81, 45, 0 }; - static ulong[] dim42JoeKuoD6Init = { 1, 3, 7, 3, 25, 31, 65, 79, 0 }; - static ulong[] dim43JoeKuoD6Init = { 1, 3, 1, 1, 19, 11, 3, 205, 0 }; - static ulong[] dim44JoeKuoD6Init = { 1, 1, 5, 9, 19, 21, 29, 157, 0 }; - static ulong[] dim45JoeKuoD6Init = { 1, 3, 7, 11, 1, 33, 89, 185, 0 }; - static ulong[] dim46JoeKuoD6Init = { 1, 3, 3, 3, 15, 9, 79, 71, 0 }; - static ulong[] dim47JoeKuoD6Init = { 1, 3, 7, 11, 15, 39, 119, 27, 0 }; - static ulong[] dim48JoeKuoD6Init = { 1, 1, 3, 1, 11, 31, 97, 225, 0 }; - static ulong[] dim49JoeKuoD6Init = { 1, 1, 1, 3, 23, 43, 57, 177, 0 }; - static ulong[] dim50JoeKuoD6Init = { 1, 3, 7, 7, 17, 17, 37, 71, 0 }; - static ulong[] dim51JoeKuoD6Init = { 1, 3, 1, 5, 27, 63, 123, 213, 0 }; - static ulong[] dim52JoeKuoD6Init = { 1, 1, 3, 5, 11, 43, 53, 133, 0 }; - static ulong[] dim53JoeKuoD6Init = { 1, 3, 5, 5, 29, 17, 47, 173, 479, 0 }; - static ulong[] dim54JoeKuoD6Init = { 1, 3, 3, 11, 3, 1, 109, 9, 69, 0 }; - static ulong[] dim55JoeKuoD6Init = { 1, 1, 1, 5, 17, 39, 23, 5, 343, 0 }; - static ulong[] dim56JoeKuoD6Init = { 1, 3, 1, 5, 25, 15, 31, 103, 499, 0 }; - static ulong[] dim57JoeKuoD6Init = { 1, 1, 1, 11, 11, 17, 63, 105, 183, 0 }; - static ulong[] dim58JoeKuoD6Init = { 1, 1, 5, 11, 9, 29, 97, 231, 363, 0 }; - static ulong[] dim59JoeKuoD6Init = { 1, 1, 5, 15, 19, 45, 41, 7, 383, 0 }; - static ulong[] dim60JoeKuoD6Init = { 1, 3, 7, 7, 31, 19, 83, 137, 221, 0 }; - static ulong[] dim61JoeKuoD6Init = { 1, 1, 1, 3, 23, 15, 111, 223, 83, 0 }; - static ulong[] dim62JoeKuoD6Init = { 1, 1, 5, 13, 31, 15, 55, 25, 161, 0 }; - static ulong[] dim63JoeKuoD6Init = { 1, 1, 3, 13, 25, 47, 39, 87, 257, 0 }; - static ulong[] dim64JoeKuoD6Init = { 1, 1, 1, 11, 21, 53, 125, 249, 293, 0 }; - static ulong[] dim65JoeKuoD6Init = { 1, 1, 7, 11, 11, 7, 57, 79, 323, 0 }; - static ulong[] dim66JoeKuoD6Init = { 1, 1, 5, 5, 17, 13, 81, 3, 131, 0 }; - static ulong[] dim67JoeKuoD6Init = { 1, 1, 7, 13, 23, 7, 65, 251, 475, 0 }; - static ulong[] dim68JoeKuoD6Init = { 1, 3, 5, 1, 9, 43, 3, 149, 11, 0 }; - static ulong[] dim69JoeKuoD6Init = { 1, 1, 3, 13, 31, 13, 13, 255, 487, 0 }; - static ulong[] dim70JoeKuoD6Init = { 1, 3, 3, 1, 5, 63, 89, 91, 127, 0 }; - static ulong[] dim71JoeKuoD6Init = { 1, 1, 3, 3, 1, 19, 123, 127, 237, 0 }; - static ulong[] dim72JoeKuoD6Init = { 1, 1, 5, 7, 23, 31, 37, 243, 289, 0 }; - static ulong[] dim73JoeKuoD6Init = { 1, 1, 5, 11, 17, 53, 117, 183, 491, 0 }; - static ulong[] dim74JoeKuoD6Init = { 1, 1, 1, 5, 1, 13, 13, 209, 345, 0 }; - static ulong[] dim75JoeKuoD6Init = { 1, 1, 3, 15, 1, 57, 115, 7, 33, 0 }; - static ulong[] dim76JoeKuoD6Init = { 1, 3, 1, 11, 7, 43, 81, 207, 175, 0 }; - static ulong[] dim77JoeKuoD6Init = { 1, 3, 1, 1, 15, 27, 63, 255, 49, 0 }; - static ulong[] dim78JoeKuoD6Init = { 1, 3, 5, 3, 27, 61, 105, 171, 305, 0 }; - static ulong[] dim79JoeKuoD6Init = { 1, 1, 5, 3, 1, 3, 57, 249, 149, 0 }; - static ulong[] dim80JoeKuoD6Init = { 1, 1, 3, 5, 5, 57, 15, 13, 159, 0 }; - static ulong[] dim81JoeKuoD6Init = { 1, 1, 1, 11, 7, 11, 105, 141, 225, 0 }; - static ulong[] dim82JoeKuoD6Init = { 1, 3, 3, 5, 27, 59, 121, 101, 271, 0 }; - static ulong[] dim83JoeKuoD6Init = { 1, 3, 5, 9, 11, 49, 51, 59, 115, 0 }; - static ulong[] dim84JoeKuoD6Init = { 1, 1, 7, 1, 23, 45, 125, 71, 419, 0 }; - static ulong[] dim85JoeKuoD6Init = { 1, 1, 3, 5, 23, 5, 105, 109, 75, 0 }; - static ulong[] dim86JoeKuoD6Init = { 1, 1, 7, 15, 7, 11, 67, 121, 453, 0 }; - static ulong[] dim87JoeKuoD6Init = { 1, 3, 7, 3, 9, 13, 31, 27, 449, 0 }; - static ulong[] dim88JoeKuoD6Init = { 1, 3, 1, 15, 19, 39, 39, 89, 15, 0 }; - static ulong[] dim89JoeKuoD6Init = { 1, 1, 1, 1, 1, 33, 73, 145, 379, 0 }; - static ulong[] dim90JoeKuoD6Init = { 1, 3, 1, 15, 15, 43, 29, 13, 483, 0 }; - static ulong[] dim91JoeKuoD6Init = { 1, 1, 7, 3, 19, 27, 85, 131, 431, 0 }; - static ulong[] dim92JoeKuoD6Init = { 1, 3, 3, 3, 5, 35, 23, 195, 349, 0 }; - static ulong[] dim93JoeKuoD6Init = { 1, 3, 3, 7, 9, 27, 39, 59, 297, 0 }; - static ulong[] dim94JoeKuoD6Init = { 1, 1, 3, 9, 11, 17, 13, 241, 157, 0 }; - static ulong[] dim95JoeKuoD6Init = { 1, 3, 7, 15, 25, 57, 33, 189, 213, 0 }; - static ulong[] dim96JoeKuoD6Init = { 1, 1, 7, 1, 9, 55, 73, 83, 217, 0 }; - static ulong[] dim97JoeKuoD6Init = { 1, 3, 3, 13, 19, 27, 23, 113, 249, 0 }; - static ulong[] dim98JoeKuoD6Init = { 1, 3, 5, 3, 23, 43, 3, 253, 479, 0 }; - static ulong[] dim99JoeKuoD6Init = { 1, 1, 5, 5, 11, 5, 45, 117, 217, 0 }; - static ulong[] dim100JoeKuoD6Init = { 1, 3, 3, 7, 29, 37, 33, 123, 147, 0 }; - static ulong[] dim101JoeKuoD6Init = { 1, 3, 1, 15, 5, 5, 37, 227, 223, 459, 0 }; - static ulong[] dim102JoeKuoD6Init = { 1, 1, 7, 5, 5, 39, 63, 255, 135, 487, 0 }; - static ulong[] dim103JoeKuoD6Init = { 1, 3, 1, 7, 9, 7, 87, 249, 217, 599, 0 }; - static ulong[] dim104JoeKuoD6Init = { 1, 1, 3, 13, 9, 47, 7, 225, 363, 247, 0 }; - static ulong[] dim105JoeKuoD6Init = { 1, 3, 7, 13, 19, 13, 9, 67, 9, 737, 0 }; - static ulong[] dim106JoeKuoD6Init = { 1, 3, 5, 5, 19, 59, 7, 41, 319, 677, 0 }; - static ulong[] dim107JoeKuoD6Init = { 1, 1, 5, 3, 31, 63, 15, 43, 207, 789, 0 }; - static ulong[] dim108JoeKuoD6Init = { 1, 1, 7, 9, 13, 39, 3, 47, 497, 169, 0 }; - static ulong[] dim109JoeKuoD6Init = { 1, 3, 1, 7, 21, 17, 97, 19, 415, 905, 0 }; - static ulong[] dim110JoeKuoD6Init = { 1, 3, 7, 1, 3, 31, 71, 111, 165, 127, 0 }; - static ulong[] dim111JoeKuoD6Init = { 1, 1, 5, 11, 1, 61, 83, 119, 203, 847, 0 }; - static ulong[] dim112JoeKuoD6Init = { 1, 3, 3, 13, 9, 61, 19, 97, 47, 35, 0 }; - static ulong[] dim113JoeKuoD6Init = { 1, 1, 7, 7, 15, 29, 63, 95, 417, 469, 0 }; - static ulong[] dim114JoeKuoD6Init = { 1, 3, 1, 9, 25, 9, 71, 57, 213, 385, 0 }; - static ulong[] dim115JoeKuoD6Init = { 1, 3, 5, 13, 31, 47, 101, 57, 39, 341, 0 }; - static ulong[] dim116JoeKuoD6Init = { 1, 1, 3, 3, 31, 57, 125, 173, 365, 551, 0 }; - static ulong[] dim117JoeKuoD6Init = { 1, 3, 7, 1, 13, 57, 67, 157, 451, 707, 0 }; - static ulong[] dim118JoeKuoD6Init = { 1, 1, 1, 7, 21, 13, 105, 89, 429, 965, 0 }; - static ulong[] dim119JoeKuoD6Init = { 1, 1, 5, 9, 17, 51, 45, 119, 157, 141, 0 }; - static ulong[] dim120JoeKuoD6Init = { 1, 3, 7, 7, 13, 45, 91, 9, 129, 741, 0 }; - static ulong[] dim121JoeKuoD6Init = { 1, 3, 7, 1, 23, 57, 67, 141, 151, 571, 0 }; - static ulong[] dim122JoeKuoD6Init = { 1, 1, 3, 11, 17, 47, 93, 107, 375, 157, 0 }; - static ulong[] dim123JoeKuoD6Init = { 1, 3, 3, 5, 11, 21, 43, 51, 169, 915, 0 }; - static ulong[] dim124JoeKuoD6Init = { 1, 1, 5, 3, 15, 55, 101, 67, 455, 625, 0 }; - static ulong[] dim125JoeKuoD6Init = { 1, 3, 5, 9, 1, 23, 29, 47, 345, 595, 0 }; - static ulong[] dim126JoeKuoD6Init = { 1, 3, 7, 7, 5, 49, 29, 155, 323, 589, 0 }; - static ulong[] dim127JoeKuoD6Init = { 1, 3, 3, 7, 5, 41, 127, 61, 261, 717, 0 }; - static ulong[] dim128JoeKuoD6Init = { 1, 3, 7, 7, 17, 23, 117, 67, 129, 1009, 0 }; - static ulong[] dim129JoeKuoD6Init = { 1, 1, 3, 13, 11, 39, 21, 207, 123, 305, 0 }; - static ulong[] dim130JoeKuoD6Init = { 1, 1, 3, 9, 29, 3, 95, 47, 231, 73, 0 }; - static ulong[] dim131JoeKuoD6Init = { 1, 3, 1, 9, 1, 29, 117, 21, 441, 259, 0 }; - static ulong[] dim132JoeKuoD6Init = { 1, 3, 1, 13, 21, 39, 125, 211, 439, 723, 0 }; - static ulong[] dim133JoeKuoD6Init = { 1, 1, 7, 3, 17, 63, 115, 89, 49, 773, 0 }; - static ulong[] dim134JoeKuoD6Init = { 1, 3, 7, 13, 11, 33, 101, 107, 63, 73, 0 }; - static ulong[] dim135JoeKuoD6Init = { 1, 1, 5, 5, 13, 57, 63, 135, 437, 177, 0 }; - static ulong[] dim136JoeKuoD6Init = { 1, 1, 3, 7, 27, 63, 93, 47, 417, 483, 0 }; - static ulong[] dim137JoeKuoD6Init = { 1, 1, 3, 1, 23, 29, 1, 191, 49, 23, 0 }; - static ulong[] dim138JoeKuoD6Init = { 1, 1, 3, 15, 25, 55, 9, 101, 219, 607, 0 }; - static ulong[] dim139JoeKuoD6Init = { 1, 3, 1, 7, 7, 19, 51, 251, 393, 307, 0 }; - static ulong[] dim140JoeKuoD6Init = { 1, 3, 3, 3, 25, 55, 17, 75, 337, 3, 0 }; - static ulong[] dim141JoeKuoD6Init = { 1, 1, 1, 13, 25, 17, 65, 45, 479, 413, 0 }; - static ulong[] dim142JoeKuoD6Init = { 1, 1, 7, 7, 27, 49, 99, 161, 213, 727, 0 }; - static ulong[] dim143JoeKuoD6Init = { 1, 3, 5, 1, 23, 5, 43, 41, 251, 857, 0 }; - static ulong[] dim144JoeKuoD6Init = { 1, 3, 3, 7, 11, 61, 39, 87, 383, 835, 0 }; - static ulong[] dim145JoeKuoD6Init = { 1, 1, 3, 15, 13, 7, 29, 7, 505, 923, 0 }; - static ulong[] dim146JoeKuoD6Init = { 1, 3, 7, 1, 5, 31, 47, 157, 445, 501, 0 }; - static ulong[] dim147JoeKuoD6Init = { 1, 1, 3, 7, 1, 43, 9, 147, 115, 605, 0 }; - static ulong[] dim148JoeKuoD6Init = { 1, 3, 3, 13, 5, 1, 119, 211, 455, 1001, 0 }; - static ulong[] dim149JoeKuoD6Init = { 1, 1, 3, 5, 13, 19, 3, 243, 75, 843, 0 }; - static ulong[] dim150JoeKuoD6Init = { 1, 3, 7, 7, 1, 19, 91, 249, 357, 589, 0 }; - static ulong[] dim151JoeKuoD6Init = { 1, 1, 1, 9, 1, 25, 109, 197, 279, 411, 0 }; - static ulong[] dim152JoeKuoD6Init = { 1, 3, 1, 15, 23, 57, 59, 135, 191, 75, 0 }; - static ulong[] dim153JoeKuoD6Init = { 1, 1, 5, 15, 29, 21, 39, 253, 383, 349, 0 }; - static ulong[] dim154JoeKuoD6Init = { 1, 3, 3, 5, 19, 45, 61, 151, 199, 981, 0 }; - static ulong[] dim155JoeKuoD6Init = { 1, 3, 5, 13, 9, 61, 107, 141, 141, 1, 0 }; - static ulong[] dim156JoeKuoD6Init = { 1, 3, 1, 11, 27, 25, 85, 105, 309, 979, 0 }; - static ulong[] dim157JoeKuoD6Init = { 1, 3, 3, 11, 19, 7, 115, 223, 349, 43, 0 }; - static ulong[] dim158JoeKuoD6Init = { 1, 1, 7, 9, 21, 39, 123, 21, 275, 927, 0 }; - static ulong[] dim159JoeKuoD6Init = { 1, 1, 7, 13, 15, 41, 47, 243, 303, 437, 0 }; - static ulong[] dim160JoeKuoD6Init = { 1, 1, 1, 7, 7, 3, 15, 99, 409, 719, 0 }; - static ulong[] dim161JoeKuoD6Init = { 1, 3, 3, 15, 27, 49, 113, 123, 113, 67, 469, 0 }; - static ulong[] dim162JoeKuoD6Init = { 1, 3, 7, 11, 3, 23, 87, 169, 119, 483, 199, 0 }; - static ulong[] dim163JoeKuoD6Init = { 1, 1, 5, 15, 7, 17, 109, 229, 179, 213, 741, 0 }; - static ulong[] dim164JoeKuoD6Init = { 1, 1, 5, 13, 11, 17, 25, 135, 403, 557, 1433, 0 }; - static ulong[] dim165JoeKuoD6Init = { 1, 3, 1, 1, 1, 61, 67, 215, 189, 945, 1243, 0 }; - static ulong[] dim166JoeKuoD6Init = { 1, 1, 7, 13, 17, 33, 9, 221, 429, 217, 1679, 0 }; - static ulong[] dim167JoeKuoD6Init = { 1, 1, 3, 11, 27, 3, 15, 93, 93, 865, 1049, 0 }; - static ulong[] dim168JoeKuoD6Init = { 1, 3, 7, 7, 25, 41, 121, 35, 373, 379, 1547, 0 }; - static ulong[] dim169JoeKuoD6Init = { 1, 3, 3, 9, 11, 35, 45, 205, 241, 9, 59, 0 }; - static ulong[] dim170JoeKuoD6Init = { 1, 3, 1, 7, 3, 51, 7, 177, 53, 975, 89, 0 }; - static ulong[] dim171JoeKuoD6Init = { 1, 1, 3, 5, 27, 1, 113, 231, 299, 759, 861, 0 }; - static ulong[] dim172JoeKuoD6Init = { 1, 3, 3, 15, 25, 29, 5, 255, 139, 891, 2031, 0 }; - static ulong[] dim173JoeKuoD6Init = { 1, 3, 1, 1, 13, 9, 109, 193, 419, 95, 17, 0 }; - static ulong[] dim174JoeKuoD6Init = { 1, 1, 7, 9, 3, 7, 29, 41, 135, 839, 867, 0 }; - static ulong[] dim175JoeKuoD6Init = { 1, 1, 7, 9, 25, 49, 123, 217, 113, 909, 215, 0 }; - static ulong[] dim176JoeKuoD6Init = { 1, 1, 7, 3, 23, 15, 43, 133, 217, 327, 901, 0 }; - static ulong[] dim177JoeKuoD6Init = { 1, 1, 3, 3, 13, 53, 63, 123, 477, 711, 1387, 0 }; - static ulong[] dim178JoeKuoD6Init = { 1, 1, 3, 15, 7, 29, 75, 119, 181, 957, 247, 0 }; - static ulong[] dim179JoeKuoD6Init = { 1, 1, 1, 11, 27, 25, 109, 151, 267, 99, 1461, 0 }; - static ulong[] dim180JoeKuoD6Init = { 1, 3, 7, 15, 5, 5, 53, 145, 11, 725, 1501, 0 }; - static ulong[] dim181JoeKuoD6Init = { 1, 3, 7, 1, 9, 43, 71, 229, 157, 607, 1835, 0 }; - static ulong[] dim182JoeKuoD6Init = { 1, 3, 3, 13, 25, 1, 5, 27, 471, 349, 127, 0 }; - static ulong[] dim183JoeKuoD6Init = { 1, 1, 1, 1, 23, 37, 9, 221, 269, 897, 1685, 0 }; - static ulong[] dim184JoeKuoD6Init = { 1, 1, 3, 3, 31, 29, 51, 19, 311, 553, 1969, 0 }; - static ulong[] dim185JoeKuoD6Init = { 1, 3, 7, 5, 5, 55, 17, 39, 475, 671, 1529, 0 }; - static ulong[] dim186JoeKuoD6Init = { 1, 1, 7, 1, 1, 35, 47, 27, 437, 395, 1635, 0 }; - static ulong[] dim187JoeKuoD6Init = { 1, 1, 7, 3, 13, 23, 43, 135, 327, 139, 389, 0 }; - static ulong[] dim188JoeKuoD6Init = { 1, 3, 7, 3, 9, 25, 91, 25, 429, 219, 513, 0 }; - static ulong[] dim189JoeKuoD6Init = { 1, 1, 3, 5, 13, 29, 119, 201, 277, 157, 2043, 0 }; - static ulong[] dim190JoeKuoD6Init = { 1, 3, 5, 3, 29, 57, 13, 17, 167, 739, 1031, 0 }; - static ulong[] dim191JoeKuoD6Init = { 1, 3, 3, 5, 29, 21, 95, 27, 255, 679, 1531, 0 }; - static ulong[] dim192JoeKuoD6Init = { 1, 3, 7, 15, 9, 5, 21, 71, 61, 961, 1201, 0 }; - static ulong[] dim193JoeKuoD6Init = { 1, 3, 5, 13, 15, 57, 33, 93, 459, 867, 223, 0 }; - static ulong[] dim194JoeKuoD6Init = { 1, 1, 1, 15, 17, 43, 127, 191, 67, 177, 1073, 0 }; - static ulong[] dim195JoeKuoD6Init = { 1, 1, 1, 15, 23, 7, 21, 199, 75, 293, 1611, 0 }; - static ulong[] dim196JoeKuoD6Init = { 1, 3, 7, 13, 15, 39, 21, 149, 65, 741, 319, 0 }; - static ulong[] dim197JoeKuoD6Init = { 1, 3, 7, 11, 23, 13, 101, 89, 277, 519, 711, 0 }; - static ulong[] dim198JoeKuoD6Init = { 1, 3, 7, 15, 19, 27, 85, 203, 441, 97, 1895, 0 }; - static ulong[] dim199JoeKuoD6Init = { 1, 3, 1, 3, 29, 25, 21, 155, 11, 191, 197, 0 }; - static ulong[] dim200JoeKuoD6Init = { 1, 1, 7, 5, 27, 11, 81, 101, 457, 675, 1687, 0 }; - static ulong[] dim201JoeKuoD6Init = { 1, 3, 1, 5, 25, 5, 65, 193, 41, 567, 781, 0 }; - static ulong[] dim202JoeKuoD6Init = { 1, 3, 1, 5, 11, 15, 113, 77, 411, 695, 1111, 0 }; - static ulong[] dim203JoeKuoD6Init = { 1, 1, 3, 9, 11, 53, 119, 171, 55, 297, 509, 0 }; - static ulong[] dim204JoeKuoD6Init = { 1, 1, 1, 1, 11, 39, 113, 139, 165, 347, 595, 0 }; - static ulong[] dim205JoeKuoD6Init = { 1, 3, 7, 11, 9, 17, 101, 13, 81, 325, 1733, 0 }; - static ulong[] dim206JoeKuoD6Init = { 1, 3, 1, 1, 21, 43, 115, 9, 113, 907, 645, 0 }; - static ulong[] dim207JoeKuoD6Init = { 1, 1, 7, 3, 9, 25, 117, 197, 159, 471, 475, 0 }; - static ulong[] dim208JoeKuoD6Init = { 1, 3, 1, 9, 11, 21, 57, 207, 485, 613, 1661, 0 }; - static ulong[] dim209JoeKuoD6Init = { 1, 1, 7, 7, 27, 55, 49, 223, 89, 85, 1523, 0 }; - static ulong[] dim210JoeKuoD6Init = { 1, 1, 5, 3, 19, 41, 45, 51, 447, 299, 1355, 0 }; - static ulong[] dim211JoeKuoD6Init = { 1, 3, 1, 15, 1, 35, 119, 135, 427, 93, 1311, 0 }; - static ulong[] dim212JoeKuoD6Init = { 1, 3, 1, 15, 31, 39, 121, 145, 129, 903, 333, 0 }; - static ulong[] dim213JoeKuoD6Init = { 1, 1, 5, 3, 29, 7, 9, 11, 395, 119, 873, 0 }; - static ulong[] dim214JoeKuoD6Init = { 1, 3, 5, 11, 27, 29, 5, 117, 469, 31, 1811, 0 }; - static ulong[] dim215JoeKuoD6Init = { 1, 1, 7, 15, 21, 25, 71, 15, 89, 1021, 679, 0 }; - static ulong[] dim216JoeKuoD6Init = { 1, 3, 7, 9, 21, 39, 51, 111, 327, 809, 845, 0 }; - static ulong[] dim217JoeKuoD6Init = { 1, 3, 3, 13, 3, 33, 79, 17, 183, 599, 1859, 0 }; - static ulong[] dim218JoeKuoD6Init = { 1, 1, 7, 9, 31, 9, 1, 5, 353, 395, 833, 0 }; - static ulong[] dim219JoeKuoD6Init = { 1, 3, 5, 7, 3, 53, 81, 133, 155, 355, 1559, 0 }; - static ulong[] dim220JoeKuoD6Init = { 1, 3, 5, 5, 31, 13, 89, 195, 357, 769, 889, 0 }; - static ulong[] dim221JoeKuoD6Init = { 1, 1, 7, 1, 9, 21, 77, 31, 269, 857, 923, 0 }; - static ulong[] dim222JoeKuoD6Init = { 1, 1, 1, 11, 11, 27, 61, 185, 329, 685, 325, 0 }; - static ulong[] dim223JoeKuoD6Init = { 1, 1, 1, 5, 11, 31, 71, 79, 293, 29, 17, 0 }; - static ulong[] dim224JoeKuoD6Init = { 1, 1, 7, 7, 7, 41, 65, 167, 67, 153, 1305, 0 }; - static ulong[] dim225JoeKuoD6Init = { 1, 3, 3, 5, 23, 45, 109, 205, 191, 649, 749, 0 }; - static ulong[] dim226JoeKuoD6Init = { 1, 1, 7, 7, 17, 1, 73, 211, 19, 797, 1009, 0 }; - static ulong[] dim227JoeKuoD6Init = { 1, 1, 5, 9, 23, 15, 117, 213, 183, 477, 1301, 0 }; - static ulong[] dim228JoeKuoD6Init = { 1, 1, 5, 13, 23, 35, 55, 151, 267, 883, 1479, 0 }; - static ulong[] dim229JoeKuoD6Init = { 1, 1, 1, 7, 5, 43, 77, 11, 149, 297, 329, 0 }; - static ulong[] dim230JoeKuoD6Init = { 1, 1, 7, 15, 3, 41, 55, 123, 219, 499, 377, 0 }; - static ulong[] dim231JoeKuoD6Init = { 1, 3, 3, 1, 27, 7, 113, 141, 173, 379, 1087, 0 }; - static ulong[] dim232JoeKuoD6Init = { 1, 3, 1, 9, 7, 25, 45, 49, 415, 329, 483, 0 }; - static ulong[] dim233JoeKuoD6Init = { 1, 1, 7, 7, 7, 15, 75, 191, 305, 757, 813, 0 }; - static ulong[] dim234JoeKuoD6Init = { 1, 3, 7, 5, 31, 15, 21, 247, 29, 297, 1015, 0 }; - static ulong[] dim235JoeKuoD6Init = { 1, 3, 1, 13, 3, 41, 69, 235, 431, 515, 1889, 0 }; - static ulong[] dim236JoeKuoD6Init = { 1, 1, 5, 7, 31, 5, 69, 193, 229, 439, 1043, 0 }; - static ulong[] dim237JoeKuoD6Init = { 1, 3, 5, 13, 31, 33, 45, 159, 477, 707, 1605, 0 }; - static ulong[] dim238JoeKuoD6Init = { 1, 1, 1, 7, 23, 49, 107, 223, 7, 429, 2047, 0 }; - static ulong[] dim239JoeKuoD6Init = { 1, 3, 5, 1, 31, 17, 117, 133, 331, 97, 833, 0 }; - static ulong[] dim240JoeKuoD6Init = { 1, 3, 1, 11, 7, 31, 103, 5, 299, 601, 981, 0 }; - static ulong[] dim241JoeKuoD6Init = { 1, 3, 5, 5, 15, 57, 87, 39, 217, 155, 361, 0 }; - static ulong[] dim242JoeKuoD6Init = { 1, 1, 7, 15, 29, 19, 125, 131, 37, 635, 1429, 0 }; - static ulong[] dim243JoeKuoD6Init = { 1, 3, 1, 9, 29, 3, 59, 107, 341, 809, 101, 0 }; - static ulong[] dim244JoeKuoD6Init = { 1, 1, 5, 15, 9, 37, 113, 225, 139, 165, 393, 0 }; - static ulong[] dim245JoeKuoD6Init = { 1, 3, 3, 13, 27, 21, 35, 255, 189, 45, 103, 0 }; - static ulong[] dim246JoeKuoD6Init = { 1, 1, 7, 5, 7, 59, 39, 87, 319, 723, 955, 0 }; - static ulong[] dim247JoeKuoD6Init = { 1, 3, 1, 1, 9, 23, 83, 47, 413, 445, 787, 0 }; - static ulong[] dim248JoeKuoD6Init = { 1, 3, 3, 3, 9, 27, 113, 135, 279, 915, 1221, 0 }; - static ulong[] dim249JoeKuoD6Init = { 1, 3, 7, 15, 3, 49, 99, 67, 11, 1017, 891, 0 }; - static ulong[] dim250JoeKuoD6Init = { 1, 3, 1, 9, 31, 41, 9, 205, 39, 993, 105, 0 }; - static ulong[] dim251JoeKuoD6Init = { 1, 3, 3, 7, 11, 45, 67, 123, 303, 87, 1943, 0 }; - static ulong[] dim252JoeKuoD6Init = { 1, 1, 1, 9, 1, 51, 101, 253, 499, 879, 833, 0 }; - static ulong[] dim253JoeKuoD6Init = { 1, 3, 7, 15, 19, 51, 97, 13, 499, 231, 829, 0 }; - static ulong[] dim254JoeKuoD6Init = { 1, 3, 5, 3, 25, 49, 29, 165, 43, 95, 779, 0 }; - static ulong[] dim255JoeKuoD6Init = { 1, 3, 5, 11, 13, 63, 1, 133, 207, 349, 221, 0 }; - static ulong[] dim256JoeKuoD6Init = { 1, 3, 7, 11, 23, 37, 51, 123, 399, 295, 1057, 0 }; - static ulong[] dim257JoeKuoD6Init = { 1, 1, 5, 11, 11, 43, 97, 163, 477, 777, 1217, 0 }; - static ulong[] dim258JoeKuoD6Init = { 1, 1, 7, 13, 3, 33, 65, 191, 25, 993, 291, 0 }; - static ulong[] dim259JoeKuoD6Init = { 1, 3, 5, 9, 25, 55, 101, 231, 219, 215, 517, 0 }; - static ulong[] dim260JoeKuoD6Init = { 1, 3, 1, 7, 17, 31, 87, 1, 475, 371, 771, 0 }; - static ulong[] dim261JoeKuoD6Init = { 1, 1, 1, 7, 3, 25, 35, 255, 211, 67, 447, 0 }; - static ulong[] dim262JoeKuoD6Init = { 1, 1, 1, 13, 9, 33, 103, 17, 369, 455, 265, 0 }; - static ulong[] dim263JoeKuoD6Init = { 1, 3, 5, 5, 29, 61, 61, 207, 345, 87, 1035, 0 }; - static ulong[] dim264JoeKuoD6Init = { 1, 3, 1, 7, 19, 21, 117, 49, 191, 133, 1889, 0 }; - static ulong[] dim265JoeKuoD6Init = { 1, 3, 3, 13, 5, 37, 63, 229, 53, 891, 1939, 0 }; - static ulong[] dim266JoeKuoD6Init = { 1, 1, 3, 5, 1, 43, 7, 1, 427, 155, 1587, 0 }; - static ulong[] dim267JoeKuoD6Init = { 1, 1, 7, 15, 15, 33, 33, 233, 481, 709, 905, 0 }; - static ulong[] dim268JoeKuoD6Init = { 1, 1, 7, 13, 7, 11, 125, 77, 39, 55, 1745, 0 }; - static ulong[] dim269JoeKuoD6Init = { 1, 3, 3, 3, 7, 49, 35, 123, 267, 229, 1873, 0 }; - static ulong[] dim270JoeKuoD6Init = { 1, 1, 7, 3, 17, 11, 35, 217, 215, 577, 1467, 0 }; - static ulong[] dim271JoeKuoD6Init = { 1, 3, 3, 5, 7, 11, 51, 27, 277, 113, 767, 0 }; - static ulong[] dim272JoeKuoD6Init = { 1, 3, 3, 3, 17, 1, 61, 151, 227, 841, 1421, 0 }; - static ulong[] dim273JoeKuoD6Init = { 1, 3, 7, 7, 7, 29, 95, 219, 407, 257, 417, 0 }; - static ulong[] dim274JoeKuoD6Init = { 1, 3, 5, 13, 5, 39, 63, 67, 467, 99, 457, 0 }; - static ulong[] dim275JoeKuoD6Init = { 1, 3, 3, 9, 15, 19, 107, 217, 371, 411, 867, 0 }; - static ulong[] dim276JoeKuoD6Init = { 1, 3, 3, 13, 13, 1, 101, 81, 69, 371, 415, 0 }; - static ulong[] dim277JoeKuoD6Init = { 1, 3, 1, 1, 5, 31, 103, 125, 147, 85, 1357, 0 }; - static ulong[] dim278JoeKuoD6Init = { 1, 3, 1, 5, 25, 61, 9, 83, 371, 691, 1189, 0 }; - static ulong[] dim279JoeKuoD6Init = { 1, 1, 5, 3, 3, 9, 1, 123, 333, 741, 961, 0 }; - static ulong[] dim280JoeKuoD6Init = { 1, 1, 3, 1, 7, 37, 73, 39, 101, 1005, 1361, 0 }; - static ulong[] dim281JoeKuoD6Init = { 1, 1, 3, 15, 11, 51, 29, 159, 361, 685, 1643, 0 }; - static ulong[] dim282JoeKuoD6Init = { 1, 1, 3, 3, 17, 51, 79, 143, 373, 425, 703, 0 }; - static ulong[] dim283JoeKuoD6Init = { 1, 1, 3, 15, 17, 21, 63, 97, 335, 591, 1697, 0 }; - static ulong[] dim284JoeKuoD6Init = { 1, 1, 7, 7, 1, 57, 21, 253, 199, 661, 77, 0 }; - static ulong[] dim285JoeKuoD6Init = { 1, 1, 3, 13, 27, 13, 101, 247, 497, 535, 273, 0 }; - static ulong[] dim286JoeKuoD6Init = { 1, 1, 1, 7, 25, 5, 83, 27, 107, 549, 1885, 0 }; - static ulong[] dim287JoeKuoD6Init = { 1, 1, 7, 5, 29, 45, 107, 159, 59, 303, 1941, 0 }; - static ulong[] dim288JoeKuoD6Init = { 1, 1, 7, 9, 5, 43, 85, 89, 151, 39, 221, 0 }; - static ulong[] dim289JoeKuoD6Init = { 1, 1, 3, 5, 5, 47, 65, 205, 141, 777, 1873, 0 }; - static ulong[] dim290JoeKuoD6Init = { 1, 1, 5, 15, 25, 41, 121, 133, 41, 171, 521, 0 }; - static ulong[] dim291JoeKuoD6Init = { 1, 3, 3, 9, 19, 25, 15, 161, 339, 155, 413, 0 }; - static ulong[] dim292JoeKuoD6Init = { 1, 3, 7, 1, 7, 1, 67, 23, 453, 625, 1375, 0 }; - static ulong[] dim293JoeKuoD6Init = { 1, 1, 1, 15, 5, 9, 87, 89, 209, 361, 1711, 0 }; - static ulong[] dim294JoeKuoD6Init = { 1, 3, 7, 11, 21, 39, 87, 21, 23, 727, 15, 0 }; - static ulong[] dim295JoeKuoD6Init = { 1, 3, 5, 13, 15, 15, 9, 247, 73, 9, 319, 0 }; - static ulong[] dim296JoeKuoD6Init = { 1, 1, 5, 7, 29, 21, 13, 121, 359, 679, 1659, 0 }; - static ulong[] dim297JoeKuoD6Init = { 1, 1, 7, 13, 19, 63, 79, 99, 107, 13, 137, 0 }; - static ulong[] dim298JoeKuoD6Init = { 1, 1, 7, 15, 1, 43, 117, 79, 305, 285, 1151, 0 }; - static ulong[] dim299JoeKuoD6Init = { 1, 1, 7, 9, 23, 9, 53, 105, 205, 121, 1451, 0 }; - static ulong[] dim300JoeKuoD6Init = { 1, 1, 7, 3, 3, 63, 99, 71, 495, 233, 1633, 0 }; - static ulong[] dim301JoeKuoD6Init = { 1, 3, 7, 11, 17, 5, 99, 211, 409, 911, 1743, 0 }; - static ulong[] dim302JoeKuoD6Init = { 1, 1, 3, 3, 1, 61, 81, 107, 493, 625, 847, 0 }; - static ulong[] dim303JoeKuoD6Init = { 1, 1, 3, 13, 15, 29, 13, 57, 305, 409, 1267, 0 }; - static ulong[] dim304JoeKuoD6Init = { 1, 3, 5, 13, 11, 3, 121, 253, 161, 891, 1463, 0 }; - static ulong[] dim305JoeKuoD6Init = { 1, 1, 7, 13, 23, 1, 125, 7, 273, 221, 2001, 0 }; - static ulong[] dim306JoeKuoD6Init = { 1, 3, 3, 5, 3, 49, 115, 205, 11, 45, 1563, 0 }; - static ulong[] dim307JoeKuoD6Init = { 1, 3, 7, 5, 21, 59, 81, 191, 31, 485, 743, 0 }; - static ulong[] dim308JoeKuoD6Init = { 1, 1, 5, 13, 9, 9, 21, 77, 487, 615, 423, 0 }; - static ulong[] dim309JoeKuoD6Init = { 1, 1, 1, 3, 27, 43, 53, 53, 345, 605, 949, 0 }; - static ulong[] dim310JoeKuoD6Init = { 1, 3, 1, 7, 31, 49, 97, 39, 279, 597, 189, 0 }; - static ulong[] dim311JoeKuoD6Init = { 1, 3, 5, 3, 17, 23, 87, 89, 457, 103, 1969, 0 }; - static ulong[] dim312JoeKuoD6Init = { 1, 1, 7, 3, 21, 45, 19, 127, 49, 231, 273, 0 }; - static ulong[] dim313JoeKuoD6Init = { 1, 3, 5, 11, 13, 15, 127, 83, 185, 553, 537, 0 }; - static ulong[] dim314JoeKuoD6Init = { 1, 3, 7, 11, 19, 45, 77, 123, 471, 731, 605, 0 }; - static ulong[] dim315JoeKuoD6Init = { 1, 1, 7, 5, 11, 25, 123, 25, 51, 501, 2025, 0 }; - static ulong[] dim316JoeKuoD6Init = { 1, 3, 3, 9, 15, 17, 67, 173, 93, 217, 1507, 0 }; - static ulong[] dim317JoeKuoD6Init = { 1, 3, 5, 1, 29, 7, 29, 211, 369, 983, 1331, 0 }; - static ulong[] dim318JoeKuoD6Init = { 1, 1, 5, 7, 17, 63, 1, 9, 493, 1009, 1275, 0 }; - static ulong[] dim319JoeKuoD6Init = { 1, 1, 1, 7, 31, 37, 51, 255, 253, 387, 591, 0 }; - static ulong[] dim320JoeKuoD6Init = { 1, 1, 7, 1, 11, 25, 41, 245, 215, 329, 1877, 0 }; - static ulong[] dim321JoeKuoD6Init = { 1, 1, 5, 7, 17, 21, 115, 63, 31, 435, 39, 0 }; - static ulong[] dim322JoeKuoD6Init = { 1, 1, 7, 9, 1, 17, 95, 139, 505, 365, 825, 0 }; - static ulong[] dim323JoeKuoD6Init = { 1, 3, 7, 7, 13, 31, 105, 167, 203, 337, 813, 0 }; - static ulong[] dim324JoeKuoD6Init = { 1, 3, 5, 11, 3, 7, 111, 91, 491, 93, 1473, 0 }; - static ulong[] dim325JoeKuoD6Init = { 1, 1, 3, 7, 29, 55, 103, 193, 219, 693, 1241, 0 }; - static ulong[] dim326JoeKuoD6Init = { 1, 3, 7, 9, 27, 7, 37, 135, 455, 87, 257, 0 }; - static ulong[] dim327JoeKuoD6Init = { 1, 1, 3, 5, 23, 19, 23, 33, 417, 263, 1693, 0 }; - static ulong[] dim328JoeKuoD6Init = { 1, 3, 3, 7, 29, 39, 127, 221, 305, 717, 989, 0 }; - static ulong[] dim329JoeKuoD6Init = { 1, 3, 3, 1, 27, 21, 49, 51, 355, 241, 1853, 0 }; - static ulong[] dim330JoeKuoD6Init = { 1, 1, 1, 15, 21, 3, 51, 137, 257, 431, 1641, 0 }; - static ulong[] dim331JoeKuoD6Init = { 1, 3, 7, 13, 25, 3, 69, 111, 163, 955, 459, 0 }; - static ulong[] dim332JoeKuoD6Init = { 1, 3, 7, 5, 5, 43, 111, 53, 463, 177, 605, 0 }; - static ulong[] dim333JoeKuoD6Init = { 1, 1, 3, 11, 23, 11, 79, 105, 419, 645, 423, 0 }; - static ulong[] dim334JoeKuoD6Init = { 1, 1, 3, 3, 15, 5, 105, 31, 117, 961, 325, 0 }; - static ulong[] dim335JoeKuoD6Init = { 1, 3, 5, 15, 21, 55, 81, 199, 231, 973, 373, 0 }; - static ulong[] dim336JoeKuoD6Init = { 1, 3, 3, 15, 23, 17, 71, 63, 59, 719, 405, 0 }; - static ulong[] dim337JoeKuoD6Init = { 1, 3, 5, 3, 9, 37, 45, 205, 267, 261, 1173, 3681, 0 }; - static ulong[] dim338JoeKuoD6Init = { 1, 3, 7, 11, 1, 53, 91, 207, 487, 593, 1397, 1255, 0 }; - static ulong[] dim339JoeKuoD6Init = { 1, 1, 3, 7, 17, 3, 111, 145, 237, 667, 1199, 3793, 0 }; - static ulong[] dim340JoeKuoD6Init = { 1, 3, 7, 3, 15, 59, 69, 223, 509, 211, 1431, 2455, 0 }; - static ulong[] dim341JoeKuoD6Init = { 1, 3, 7, 1, 27, 47, 75, 123, 455, 553, 1153, 1675, 0 }; - static ulong[] dim342JoeKuoD6Init = { 1, 1, 7, 13, 17, 3, 85, 103, 205, 443, 1093, 4083, 0 }; - static ulong[] dim343JoeKuoD6Init = { 1, 3, 7, 13, 13, 63, 13, 103, 223, 473, 1125, 1565, 0 }; - static ulong[] dim344JoeKuoD6Init = { 1, 1, 1, 13, 21, 55, 21, 39, 385, 809, 457, 1991, 0 }; - static ulong[] dim345JoeKuoD6Init = { 1, 1, 3, 5, 29, 57, 81, 1, 165, 181, 57, 1463, 0 }; - static ulong[] dim346JoeKuoD6Init = { 1, 3, 7, 7, 21, 29, 59, 127, 393, 981, 577, 2707, 0 }; - static ulong[] dim347JoeKuoD6Init = { 1, 1, 3, 11, 17, 47, 123, 149, 273, 825, 1843, 479, 0 }; - static ulong[] dim348JoeKuoD6Init = { 1, 1, 5, 7, 1, 33, 91, 251, 371, 655, 383, 3123, 0 }; - static ulong[] dim349JoeKuoD6Init = { 1, 3, 1, 7, 3, 55, 15, 195, 345, 1017, 385, 1869, 0 }; - static ulong[] dim350JoeKuoD6Init = { 1, 1, 3, 7, 15, 25, 25, 67, 223, 935, 905, 923, 0 }; - static ulong[] dim351JoeKuoD6Init = { 1, 1, 1, 13, 29, 5, 23, 81, 227, 175, 1025, 355, 0 }; - static ulong[] dim352JoeKuoD6Init = { 1, 1, 7, 9, 25, 27, 43, 85, 401, 955, 989, 3117, 0 }; - static ulong[] dim353JoeKuoD6Init = { 1, 1, 7, 13, 27, 31, 27, 235, 99, 539, 1093, 2821, 0 }; - static ulong[] dim354JoeKuoD6Init = { 1, 3, 5, 7, 13, 19, 45, 231, 203, 489, 1929, 3615, 0 }; - static ulong[] dim355JoeKuoD6Init = { 1, 3, 1, 3, 3, 15, 3, 191, 181, 463, 1247, 2229, 0 }; - static ulong[] dim356JoeKuoD6Init = { 1, 3, 7, 3, 1, 37, 1, 59, 29, 283, 679, 429, 0 }; - static ulong[] dim357JoeKuoD6Init = { 1, 3, 1, 15, 17, 25, 5, 113, 191, 505, 365, 3943, 0 }; - static ulong[] dim358JoeKuoD6Init = { 1, 1, 3, 3, 13, 31, 95, 141, 29, 353, 661, 3637, 0 }; - static ulong[] dim359JoeKuoD6Init = { 1, 3, 1, 1, 5, 53, 19, 9, 81, 497, 1915, 2997, 0 }; - static ulong[] dim360JoeKuoD6Init = { 1, 3, 7, 15, 5, 13, 35, 163, 293, 309, 503, 2387, 0 }; - static ulong[] dim361JoeKuoD6Init = { 1, 1, 5, 3, 11, 25, 127, 27, 435, 247, 1485, 3917, 0 }; - static ulong[] dim362JoeKuoD6Init = { 1, 1, 7, 5, 21, 7, 15, 213, 355, 209, 1107, 1317, 0 }; - static ulong[] dim363JoeKuoD6Init = { 1, 3, 3, 11, 25, 29, 73, 203, 445, 849, 291, 1567, 0 }; - static ulong[] dim364JoeKuoD6Init = { 1, 3, 3, 15, 15, 31, 5, 15, 19, 345, 635, 1815, 0 }; - static ulong[] dim365JoeKuoD6Init = { 1, 1, 3, 3, 19, 21, 15, 95, 111, 167, 1051, 479, 0 }; - static ulong[] dim366JoeKuoD6Init = { 1, 3, 1, 13, 15, 61, 125, 237, 11, 789, 1681, 437, 0 }; - static ulong[] dim367JoeKuoD6Init = { 1, 3, 3, 15, 21, 23, 105, 145, 145, 453, 917, 1727, 0 }; - static ulong[] dim368JoeKuoD6Init = { 1, 1, 7, 11, 9, 37, 27, 91, 199, 561, 1705, 3849, 0 }; - static ulong[] dim369JoeKuoD6Init = { 1, 1, 3, 5, 11, 53, 1, 21, 63, 879, 629, 3219, 0 }; - static ulong[] dim370JoeKuoD6Init = { 1, 1, 3, 13, 3, 5, 121, 17, 511, 809, 627, 2627, 0 }; - static ulong[] dim371JoeKuoD6Init = { 1, 3, 5, 3, 27, 21, 115, 117, 193, 185, 1855, 2473, 0 }; - static ulong[] dim372JoeKuoD6Init = { 1, 3, 1, 9, 11, 37, 79, 123, 391, 715, 573, 699, 0 }; - static ulong[] dim373JoeKuoD6Init = { 1, 3, 1, 9, 5, 35, 105, 5, 55, 347, 1217, 3483, 0 }; - static ulong[] dim374JoeKuoD6Init = { 1, 3, 1, 11, 19, 59, 21, 221, 329, 873, 943, 3679, 0 }; - static ulong[] dim375JoeKuoD6Init = { 1, 3, 1, 13, 21, 57, 119, 33, 111, 581, 1133, 131, 0 }; - static ulong[] dim376JoeKuoD6Init = { 1, 3, 3, 7, 13, 31, 67, 205, 211, 143, 1117, 4067, 0 }; - static ulong[] dim377JoeKuoD6Init = { 1, 3, 7, 9, 9, 53, 71, 251, 41, 875, 691, 3681, 0 }; - static ulong[] dim378JoeKuoD6Init = { 1, 3, 1, 9, 23, 55, 57, 29, 123, 453, 523, 3237, 0 }; - static ulong[] dim379JoeKuoD6Init = { 1, 1, 5, 11, 15, 19, 91, 105, 221, 1005, 169, 461, 0 }; - static ulong[] dim380JoeKuoD6Init = { 1, 1, 1, 11, 7, 61, 49, 41, 337, 739, 699, 2379, 0 }; - static ulong[] dim381JoeKuoD6Init = { 1, 1, 3, 13, 21, 31, 103, 247, 87, 537, 757, 785, 0 }; - static ulong[] dim382JoeKuoD6Init = { 1, 1, 5, 9, 7, 49, 127, 149, 277, 87, 475, 127, 0 }; - static ulong[] dim383JoeKuoD6Init = { 1, 3, 5, 15, 5, 25, 95, 229, 389, 121, 95, 2787, 0 }; - static ulong[] dim384JoeKuoD6Init = { 1, 1, 1, 5, 9, 27, 29, 23, 419, 371, 127, 961, 0 }; - static ulong[] dim385JoeKuoD6Init = { 1, 1, 1, 15, 25, 19, 123, 35, 41, 785, 605, 711, 0 }; - static ulong[] dim386JoeKuoD6Init = { 1, 1, 7, 3, 1, 13, 69, 161, 449, 225, 1795, 2083, 0 }; - static ulong[] dim387JoeKuoD6Init = { 1, 1, 3, 5, 21, 1, 19, 211, 191, 697, 89, 177, 0 }; - static ulong[] dim388JoeKuoD6Init = { 1, 1, 3, 3, 19, 29, 49, 151, 365, 541, 1681, 1943, 0 }; - static ulong[] dim389JoeKuoD6Init = { 1, 3, 7, 7, 9, 5, 75, 109, 243, 769, 755, 2733, 0 }; - static ulong[] dim390JoeKuoD6Init = { 1, 3, 1, 11, 11, 41, 7, 87, 363, 893, 1799, 1303, 0 }; - static ulong[] dim391JoeKuoD6Init = { 1, 1, 1, 9, 11, 5, 19, 101, 41, 401, 1863, 965, 0 }; - static ulong[] dim392JoeKuoD6Init = { 1, 1, 3, 11, 13, 15, 71, 249, 511, 625, 1101, 2615, 0 }; - static ulong[] dim393JoeKuoD6Init = { 1, 3, 3, 9, 31, 35, 85, 107, 383, 201, 1163, 981, 0 }; - static ulong[] dim394JoeKuoD6Init = { 1, 3, 5, 9, 21, 13, 33, 9, 243, 93, 461, 741, 0 }; - static ulong[] dim395JoeKuoD6Init = { 1, 1, 1, 9, 1, 55, 85, 179, 321, 163, 1807, 339, 0 }; - static ulong[] dim396JoeKuoD6Init = { 1, 3, 7, 11, 29, 7, 57, 133, 245, 87, 917, 109, 0 }; - static ulong[] dim397JoeKuoD6Init = { 1, 1, 7, 9, 11, 13, 93, 81, 361, 343, 647, 1113, 0 }; - static ulong[] dim398JoeKuoD6Init = { 1, 3, 7, 5, 23, 57, 117, 105, 221, 697, 1159, 1307, 0 }; - static ulong[] dim399JoeKuoD6Init = { 1, 3, 1, 7, 27, 55, 15, 235, 279, 941, 655, 3975, 0 }; - static ulong[] dim400JoeKuoD6Init = { 1, 3, 1, 9, 27, 47, 45, 41, 361, 135, 379, 2121, 0 }; - static ulong[] dim401JoeKuoD6Init = { 1, 1, 7, 15, 19, 51, 31, 39, 187, 573, 273, 383, 0 }; - static ulong[] dim402JoeKuoD6Init = { 1, 1, 7, 11, 9, 47, 107, 29, 435, 989, 1315, 2815, 0 }; - static ulong[] dim403JoeKuoD6Init = { 1, 3, 1, 3, 21, 31, 7, 41, 45, 115, 1639, 1861, 0 }; - static ulong[] dim404JoeKuoD6Init = { 1, 1, 1, 15, 1, 21, 57, 233, 51, 149, 1251, 1809, 0 }; - static ulong[] dim405JoeKuoD6Init = { 1, 1, 3, 11, 1, 53, 111, 35, 447, 657, 1557, 349, 0 }; - static ulong[] dim406JoeKuoD6Init = { 1, 1, 7, 11, 25, 33, 39, 209, 127, 913, 659, 177, 0 }; - static ulong[] dim407JoeKuoD6Init = { 1, 3, 5, 9, 13, 53, 25, 191, 373, 997, 1413, 2859, 0 }; - static ulong[] dim408JoeKuoD6Init = { 1, 1, 7, 3, 31, 51, 17, 253, 149, 719, 1681, 2713, 0 }; - static ulong[] dim409JoeKuoD6Init = { 1, 1, 7, 1, 23, 49, 9, 211, 381, 321, 2033, 361, 0 }; - static ulong[] dim410JoeKuoD6Init = { 1, 3, 1, 15, 31, 3, 121, 21, 465, 417, 1023, 3921, 0 }; - static ulong[] dim411JoeKuoD6Init = { 1, 1, 7, 1, 17, 49, 101, 37, 429, 877, 505, 821, 0 }; - static ulong[] dim412JoeKuoD6Init = { 1, 3, 1, 7, 23, 59, 33, 127, 43, 987, 1065, 2675, 0 }; - static ulong[] dim413JoeKuoD6Init = { 1, 3, 1, 9, 7, 19, 45, 157, 475, 53, 1223, 523, 0 }; - static ulong[] dim414JoeKuoD6Init = { 1, 3, 7, 9, 23, 61, 31, 133, 85, 623, 871, 965, 0 }; - static ulong[] dim415JoeKuoD6Init = { 1, 3, 1, 7, 3, 17, 21, 197, 377, 819, 661, 1803, 0 }; - static ulong[] dim416JoeKuoD6Init = { 1, 1, 7, 3, 11, 37, 1, 135, 509, 927, 23, 1657, 0 }; - static ulong[] dim417JoeKuoD6Init = { 1, 1, 3, 5, 15, 57, 55, 179, 317, 31, 611, 4057, 0 }; - static ulong[] dim418JoeKuoD6Init = { 1, 1, 5, 5, 29, 57, 93, 105, 103, 157, 701, 249, 0 }; - static ulong[] dim419JoeKuoD6Init = { 1, 1, 3, 13, 27, 41, 23, 213, 363, 911, 85, 2733, 0 }; - static ulong[] dim420JoeKuoD6Init = { 1, 1, 5, 15, 15, 15, 93, 203, 61, 759, 1735, 459, 0 }; - static ulong[] dim421JoeKuoD6Init = { 1, 1, 5, 13, 1, 59, 27, 203, 165, 87, 835, 3647, 0 }; - static ulong[] dim422JoeKuoD6Init = { 1, 3, 3, 5, 25, 57, 43, 209, 71, 35, 1985, 1521, 0 }; - static ulong[] dim423JoeKuoD6Init = { 1, 1, 7, 5, 15, 19, 49, 103, 195, 17, 2041, 1267, 0 }; - static ulong[] dim424JoeKuoD6Init = { 1, 1, 5, 5, 5, 19, 91, 131, 157, 625, 1851, 3691, 0 }; - static ulong[] dim425JoeKuoD6Init = { 1, 1, 1, 9, 9, 47, 3, 195, 25, 1003, 533, 833, 0 }; - static ulong[] dim426JoeKuoD6Init = { 1, 1, 1, 15, 21, 33, 27, 193, 65, 545, 261, 3095, 0 }; - static ulong[] dim427JoeKuoD6Init = { 1, 3, 7, 5, 7, 39, 35, 9, 387, 241, 1015, 1557, 0 }; - static ulong[] dim428JoeKuoD6Init = { 1, 3, 7, 7, 13, 29, 43, 101, 457, 363, 115, 915, 0 }; - static ulong[] dim429JoeKuoD6Init = { 1, 1, 3, 13, 17, 57, 79, 11, 155, 39, 215, 157, 0 }; - static ulong[] dim430JoeKuoD6Init = { 1, 3, 7, 9, 23, 33, 69, 189, 59, 823, 1941, 423, 0 }; - static ulong[] dim431JoeKuoD6Init = { 1, 3, 5, 11, 9, 39, 79, 43, 431, 227, 163, 2653, 0 }; - static ulong[] dim432JoeKuoD6Init = { 1, 3, 1, 3, 5, 63, 55, 141, 207, 349, 1873, 773, 0 }; - static ulong[] dim433JoeKuoD6Init = { 1, 1, 5, 7, 21, 59, 89, 111, 53, 217, 1897, 1619, 0 }; - static ulong[] dim434JoeKuoD6Init = { 1, 1, 5, 9, 7, 27, 127, 247, 183, 925, 989, 1059, 0 }; - static ulong[] dim435JoeKuoD6Init = { 1, 3, 5, 3, 21, 47, 39, 71, 343, 285, 1053, 3007, 0 }; - static ulong[] dim436JoeKuoD6Init = { 1, 1, 3, 11, 1, 7, 27, 109, 19, 325, 157, 2779, 0 }; - static ulong[] dim437JoeKuoD6Init = { 1, 3, 5, 9, 23, 27, 63, 115, 415, 1005, 1159, 3699, 0 }; - static ulong[] dim438JoeKuoD6Init = { 1, 1, 5, 13, 27, 27, 5, 245, 95, 1021, 641, 3875, 0 }; - static ulong[] dim439JoeKuoD6Init = { 1, 3, 5, 9, 5, 9, 53, 183, 379, 251, 1747, 969, 0 }; - static ulong[] dim440JoeKuoD6Init = { 1, 1, 5, 13, 7, 23, 53, 195, 353, 225, 1871, 2131, 0 }; - static ulong[] dim441JoeKuoD6Init = { 1, 3, 7, 3, 21, 5, 25, 253, 59, 821, 1699, 1911, 0 }; - static ulong[] dim442JoeKuoD6Init = { 1, 3, 3, 7, 9, 53, 121, 155, 281, 969, 1943, 2291, 0 }; - static ulong[] dim443JoeKuoD6Init = { 1, 1, 1, 1, 27, 25, 65, 111, 295, 213, 81, 415, 0 }; - static ulong[] dim444JoeKuoD6Init = { 1, 1, 7, 7, 29, 51, 39, 201, 133, 987, 243, 3369, 0 }; - static ulong[] dim445JoeKuoD6Init = { 1, 1, 1, 7, 27, 5, 57, 205, 395, 813, 125, 1293, 0 }; - static ulong[] dim446JoeKuoD6Init = { 1, 1, 7, 13, 15, 19, 57, 11, 151, 405, 2013, 2607, 0 }; - static ulong[] dim447JoeKuoD6Init = { 1, 3, 1, 1, 9, 53, 17, 25, 7, 483, 525, 967, 0 }; - static ulong[] dim448JoeKuoD6Init = { 1, 3, 7, 13, 11, 31, 111, 253, 439, 689, 919, 3563, 0 }; - static ulong[] dim449JoeKuoD6Init = { 1, 1, 5, 9, 13, 59, 123, 69, 339, 17, 297, 2511, 0 }; - static ulong[] dim450JoeKuoD6Init = { 1, 1, 7, 5, 13, 1, 85, 113, 45, 107, 565, 795, 0 }; - static ulong[] dim451JoeKuoD6Init = { 1, 3, 1, 11, 15, 5, 109, 163, 73, 103, 195, 639, 0 }; - static ulong[] dim452JoeKuoD6Init = { 1, 1, 5, 9, 21, 11, 93, 23, 217, 275, 139, 1159, 0 }; - static ulong[] dim453JoeKuoD6Init = { 1, 1, 1, 3, 31, 63, 73, 61, 63, 923, 1237, 3887, 0 }; - static ulong[] dim454JoeKuoD6Init = { 1, 3, 5, 9, 27, 45, 5, 93, 3, 303, 357, 2973, 0 }; - static ulong[] dim455JoeKuoD6Init = { 1, 1, 1, 11, 7, 51, 41, 27, 83, 357, 1679, 2015, 0 }; - static ulong[] dim456JoeKuoD6Init = { 1, 3, 3, 13, 9, 53, 1, 193, 343, 59, 451, 1579, 0 }; - static ulong[] dim457JoeKuoD6Init = { 1, 3, 5, 3, 9, 37, 37, 131, 207, 29, 2027, 733, 0 }; - static ulong[] dim458JoeKuoD6Init = { 1, 1, 5, 7, 3, 61, 51, 221, 71, 659, 1955, 1289, 0 }; - static ulong[] dim459JoeKuoD6Init = { 1, 3, 1, 15, 5, 19, 3, 205, 319, 155, 325, 2643, 0 }; - static ulong[] dim460JoeKuoD6Init = { 1, 1, 5, 9, 3, 15, 1, 247, 323, 143, 37, 2069, 0 }; - static ulong[] dim461JoeKuoD6Init = { 1, 1, 5, 15, 23, 43, 35, 59, 285, 779, 605, 1739, 0 }; - static ulong[] dim462JoeKuoD6Init = { 1, 3, 3, 5, 29, 31, 57, 225, 417, 521, 1337, 3051, 0 }; - static ulong[] dim463JoeKuoD6Init = { 1, 3, 1, 7, 23, 57, 41, 165, 437, 669, 1087, 1275, 0 }; - static ulong[] dim464JoeKuoD6Init = { 1, 1, 3, 5, 1, 51, 25, 233, 449, 503, 1237, 1303, 0 }; - static ulong[] dim465JoeKuoD6Init = { 1, 1, 1, 11, 9, 45, 79, 149, 229, 991, 1725, 395, 0 }; - static ulong[] dim466JoeKuoD6Init = { 1, 1, 5, 11, 31, 37, 13, 117, 19, 939, 1347, 2251, 0 }; - static ulong[] dim467JoeKuoD6Init = { 1, 1, 5, 5, 1, 29, 25, 251, 493, 793, 649, 1197, 0 }; - static ulong[] dim468JoeKuoD6Init = { 1, 3, 3, 11, 5, 53, 49, 33, 37, 937, 497, 361, 0 }; - static ulong[] dim469JoeKuoD6Init = { 1, 1, 1, 1, 5, 57, 19, 141, 115, 371, 1341, 3335, 0 }; - static ulong[] dim470JoeKuoD6Init = { 1, 3, 5, 5, 23, 47, 77, 31, 225, 589, 551, 2625, 0 }; - static ulong[] dim471JoeKuoD6Init = { 1, 1, 3, 1, 25, 37, 29, 213, 283, 207, 385, 2019, 0 }; - static ulong[] dim472JoeKuoD6Init = { 1, 3, 5, 11, 5, 17, 21, 37, 167, 49, 1595, 1647, 0 }; - static ulong[] dim473JoeKuoD6Init = { 1, 1, 3, 15, 29, 15, 79, 203, 329, 627, 1799, 895, 0 }; - static ulong[] dim474JoeKuoD6Init = { 1, 1, 5, 7, 23, 53, 69, 45, 271, 661, 1437, 2429, 0 }; - static ulong[] dim475JoeKuoD6Init = { 1, 3, 1, 1, 21, 7, 115, 233, 267, 873, 2023, 3431, 0 }; - static ulong[] dim476JoeKuoD6Init = { 1, 1, 5, 5, 7, 63, 7, 125, 129, 815, 771, 1233, 0 }; - static ulong[] dim477JoeKuoD6Init = { 1, 3, 5, 9, 5, 29, 121, 203, 373, 137, 1181, 3773, 0 }; - static ulong[] dim478JoeKuoD6Init = { 1, 1, 5, 1, 15, 47, 25, 137, 329, 531, 1957, 1933, 0 }; - static ulong[] dim479JoeKuoD6Init = { 1, 3, 1, 11, 23, 37, 67, 123, 181, 567, 893, 2307, 0 }; - static ulong[] dim480JoeKuoD6Init = { 1, 3, 5, 3, 5, 23, 41, 227, 9, 213, 821, 1689, 0 }; - static ulong[] dim481JoeKuoD6Init = { 1, 1, 1, 13, 29, 33, 23, 241, 199, 753, 1759, 833, 5261, 0 }; - static ulong[] dim482JoeKuoD6Init = { 1, 3, 5, 15, 31, 7, 61, 225, 209, 117, 1983, 395, 3583, 0 }; - static ulong[] dim483JoeKuoD6Init = { 1, 1, 7, 5, 27, 49, 7, 125, 365, 513, 1001, 283, 627, 0 }; - static ulong[] dim484JoeKuoD6Init = { 1, 3, 1, 3, 7, 53, 99, 123, 493, 481, 173, 1483, 805, 0 }; - static ulong[] dim485JoeKuoD6Init = { 1, 1, 5, 7, 15, 1, 57, 19, 391, 847, 1641, 3497, 2807, 0 }; - static ulong[] dim486JoeKuoD6Init = { 1, 1, 7, 11, 19, 49, 77, 139, 275, 115, 1401, 2541, 7239, 0 }; - static ulong[] dim487JoeKuoD6Init = { 1, 1, 1, 15, 11, 13, 13, 211, 119, 317, 271, 1867, 4299, 0 }; - static ulong[] dim488JoeKuoD6Init = { 1, 1, 1, 13, 15, 37, 121, 197, 485, 605, 1025, 3235, 6205, 0 }; - static ulong[] dim489JoeKuoD6Init = { 1, 3, 5, 7, 25, 39, 31, 3, 465, 33, 625, 1069, 6043, 0 }; - static ulong[] dim490JoeKuoD6Init = { 1, 1, 3, 9, 7, 37, 115, 169, 27, 967, 505, 1493, 4333, 0 }; - static ulong[] dim491JoeKuoD6Init = { 1, 1, 3, 13, 1, 51, 19, 117, 365, 587, 1597, 279, 99, 0 }; - static ulong[] dim492JoeKuoD6Init = { 1, 3, 5, 9, 15, 57, 89, 153, 495, 535, 775, 4063, 6049, 0 }; - static ulong[] dim493JoeKuoD6Init = { 1, 1, 3, 1, 9, 7, 111, 43, 225, 677, 1379, 481, 5003, 0 }; - static ulong[] dim494JoeKuoD6Init = { 1, 1, 1, 15, 11, 47, 63, 37, 41, 833, 467, 3795, 5643, 0 }; - static ulong[] dim495JoeKuoD6Init = { 1, 3, 3, 7, 25, 49, 21, 91, 191, 579, 507, 3001, 6549, 0 }; - static ulong[] dim496JoeKuoD6Init = { 1, 3, 5, 9, 25, 17, 17, 153, 467, 359, 1523, 3175, 7307, 0 }; - static ulong[] dim497JoeKuoD6Init = { 1, 3, 7, 7, 29, 57, 51, 145, 71, 515, 495, 1091, 7911, 0 }; - static ulong[] dim498JoeKuoD6Init = { 1, 3, 1, 7, 31, 31, 53, 149, 303, 969, 383, 939, 2659, 0 }; - static ulong[] dim499JoeKuoD6Init = { 1, 1, 7, 9, 1, 21, 15, 145, 9, 199, 695, 2967, 1179, 0 }; - static ulong[] dim500JoeKuoD6Init = { 1, 3, 1, 3, 23, 33, 89, 23, 387, 591, 1543, 3941, 7021, 0 }; - static ulong[] dim501JoeKuoD6Init = { 1, 1, 3, 7, 27, 17, 25, 71, 43, 761, 803, 833, 1023, 0 }; - static ulong[] dim502JoeKuoD6Init = { 1, 1, 1, 3, 11, 25, 3, 171, 377, 843, 1147, 1469, 1773, 0 }; - static ulong[] dim503JoeKuoD6Init = { 1, 1, 3, 15, 1, 13, 65, 197, 381, 683, 895, 2181, 1973, 0 }; - static ulong[] dim504JoeKuoD6Init = { 1, 1, 5, 7, 19, 25, 109, 49, 451, 277, 1417, 2965, 7677, 0 }; - static ulong[] dim505JoeKuoD6Init = { 1, 3, 3, 7, 25, 51, 115, 43, 175, 317, 953, 81, 2533, 0 }; - static ulong[] dim506JoeKuoD6Init = { 1, 3, 7, 15, 27, 57, 5, 181, 489, 369, 1339, 3643, 7911, 0 }; - static ulong[] dim507JoeKuoD6Init = { 1, 3, 1, 5, 21, 11, 87, 81, 85, 5, 867, 3541, 3071, 0 }; - static ulong[] dim508JoeKuoD6Init = { 1, 1, 3, 3, 19, 37, 111, 43, 27, 549, 367, 3021, 6563, 0 }; - static ulong[] dim509JoeKuoD6Init = { 1, 1, 1, 13, 3, 63, 83, 107, 327, 599, 425, 3941, 4319, 0 }; - static ulong[] dim510JoeKuoD6Init = { 1, 3, 7, 15, 5, 37, 127, 169, 117, 987, 1821, 997, 63, 0 }; - static ulong[] dim511JoeKuoD6Init = { 1, 1, 7, 15, 17, 41, 103, 129, 449, 373, 733, 55, 5987, 0 }; - static ulong[] dim512JoeKuoD6Init = { 1, 1, 1, 15, 13, 61, 15, 117, 249, 149, 885, 3723, 5525, 0 }; - static ulong[] dim513JoeKuoD6Init = { 1, 1, 1, 1, 7, 3, 39, 47, 367, 355, 1943, 1035, 2367, 0 }; - static ulong[] dim514JoeKuoD6Init = { 1, 1, 7, 11, 19, 49, 21, 239, 403, 921, 693, 2123, 7387, 0 }; - static ulong[] dim515JoeKuoD6Init = { 1, 3, 5, 5, 23, 45, 13, 81, 105, 91, 1173, 3059, 5969, 0 }; - static ulong[] dim516JoeKuoD6Init = { 1, 1, 1, 5, 1, 31, 73, 253, 395, 941, 1949, 455, 453, 0 }; - static ulong[] dim517JoeKuoD6Init = { 1, 1, 3, 15, 27, 57, 115, 17, 269, 819, 145, 1219, 6471, 0 }; - static ulong[] dim518JoeKuoD6Init = { 1, 3, 3, 7, 29, 19, 9, 67, 501, 87, 883, 1985, 4859, 0 }; - static ulong[] dim519JoeKuoD6Init = { 1, 1, 1, 3, 29, 3, 55, 107, 79, 941, 1437, 3607, 6221, 0 }; - static ulong[] dim520JoeKuoD6Init = { 1, 3, 3, 15, 9, 63, 59, 113, 319, 825, 641, 491, 4015, 0 }; - static ulong[] dim521JoeKuoD6Init = { 1, 1, 1, 3, 21, 59, 55, 107, 215, 167, 315, 81, 3491, 0 }; - static ulong[] dim522JoeKuoD6Init = { 1, 3, 7, 11, 15, 7, 71, 145, 481, 843, 1437, 3809, 7729, 0 }; - static ulong[] dim523JoeKuoD6Init = { 1, 3, 1, 11, 23, 59, 65, 45, 397, 117, 325, 2933, 541, 0 }; - static ulong[] dim524JoeKuoD6Init = { 1, 3, 3, 15, 15, 47, 77, 35, 143, 327, 965, 3409, 1817, 0 }; - static ulong[] dim525JoeKuoD6Init = { 1, 1, 1, 9, 31, 7, 31, 57, 331, 615, 645, 605, 2185, 0 }; - static ulong[] dim526JoeKuoD6Init = { 1, 1, 5, 1, 15, 53, 109, 135, 259, 591, 1419, 3349, 5541, 0 }; - static ulong[] dim527JoeKuoD6Init = { 1, 1, 5, 13, 21, 23, 87, 115, 211, 737, 1433, 3247, 6899, 0 }; - static ulong[] dim528JoeKuoD6Init = { 1, 3, 3, 7, 23, 5, 43, 43, 253, 753, 1305, 2179, 1375, 0 }; - static ulong[] dim529JoeKuoD6Init = { 1, 3, 3, 7, 21, 49, 127, 129, 229, 415, 1593, 2315, 3273, 0 }; - static ulong[] dim530JoeKuoD6Init = { 1, 3, 5, 9, 15, 61, 97, 101, 199, 651, 1421, 2471, 6109, 0 }; - static ulong[] dim531JoeKuoD6Init = { 1, 3, 1, 11, 13, 27, 19, 243, 185, 707, 559, 1687, 981, 0 }; - static ulong[] dim532JoeKuoD6Init = { 1, 3, 7, 3, 5, 9, 101, 55, 39, 811, 1491, 3725, 6691, 0 }; - static ulong[] dim533JoeKuoD6Init = { 1, 1, 5, 9, 27, 33, 41, 61, 271, 695, 1563, 547, 1569, 0 }; - static ulong[] dim534JoeKuoD6Init = { 1, 3, 5, 1, 29, 21, 9, 83, 131, 287, 1505, 2711, 1617, 0 }; - static ulong[] dim535JoeKuoD6Init = { 1, 1, 1, 7, 29, 57, 19, 99, 303, 609, 1397, 3241, 3463, 0 }; - static ulong[] dim536JoeKuoD6Init = { 1, 3, 1, 9, 13, 33, 45, 101, 195, 615, 2017, 2473, 1251, 0 }; - static ulong[] dim537JoeKuoD6Init = { 1, 1, 3, 7, 31, 7, 121, 67, 275, 153, 1189, 2343, 5593, 0 }; - static ulong[] dim538JoeKuoD6Init = { 1, 1, 3, 15, 19, 37, 79, 207, 473, 927, 915, 1971, 8033, 0 }; - static ulong[] dim539JoeKuoD6Init = { 1, 3, 3, 13, 7, 55, 123, 163, 47, 599, 209, 2235, 7643, 0 }; - static ulong[] dim540JoeKuoD6Init = { 1, 1, 3, 11, 31, 3, 31, 69, 61, 257, 11, 845, 2659, 0 }; - static ulong[] dim541JoeKuoD6Init = { 1, 3, 5, 9, 27, 15, 73, 237, 79, 517, 1905, 1595, 6337, 0 }; - static ulong[] dim542JoeKuoD6Init = { 1, 1, 5, 15, 11, 19, 95, 213, 321, 303, 1957, 2291, 5991, 0 }; - static ulong[] dim543JoeKuoD6Init = { 1, 1, 1, 11, 15, 17, 85, 45, 143, 425, 55, 3595, 685, 0 }; - static ulong[] dim544JoeKuoD6Init = { 1, 1, 7, 3, 25, 5, 25, 203, 353, 537, 1921, 1885, 1157, 0 }; - static ulong[] dim545JoeKuoD6Init = { 1, 1, 1, 7, 29, 23, 117, 141, 257, 81, 25, 3237, 7223, 0 }; - static ulong[] dim546JoeKuoD6Init = { 1, 3, 5, 11, 27, 23, 47, 29, 143, 341, 1855, 3973, 5977, 0 }; - static ulong[] dim547JoeKuoD6Init = { 1, 3, 5, 7, 7, 45, 11, 95, 135, 261, 1475, 3723, 6999, 0 }; - static ulong[] dim548JoeKuoD6Init = { 1, 1, 3, 13, 19, 39, 89, 93, 187, 1011, 1319, 67, 399, 0 }; - static ulong[] dim549JoeKuoD6Init = { 1, 1, 5, 5, 17, 1, 91, 69, 405, 815, 225, 2469, 6287, 0 }; - static ulong[] dim550JoeKuoD6Init = { 1, 1, 7, 7, 3, 19, 41, 37, 125, 221, 1011, 3603, 4881, 0 }; - static ulong[] dim551JoeKuoD6Init = { 1, 3, 5, 11, 15, 13, 45, 235, 141, 17, 1991, 2581, 4965, 0 }; - static ulong[] dim552JoeKuoD6Init = { 1, 3, 3, 13, 5, 41, 117, 143, 261, 717, 111, 395, 4381, 0 }; - static ulong[] dim553JoeKuoD6Init = { 1, 3, 7, 5, 15, 47, 117, 197, 147, 117, 295, 2005, 4081, 0 }; - static ulong[] dim554JoeKuoD6Init = { 1, 3, 5, 3, 29, 61, 93, 245, 59, 119, 1121, 2549, 6471, 0 }; - static ulong[] dim555JoeKuoD6Init = { 1, 3, 1, 5, 13, 43, 93, 133, 313, 923, 295, 1239, 6355, 0 }; - static ulong[] dim556JoeKuoD6Init = { 1, 3, 3, 11, 5, 47, 99, 115, 107, 585, 671, 2077, 7005, 0 }; - static ulong[] dim557JoeKuoD6Init = { 1, 1, 1, 9, 13, 31, 79, 253, 245, 597, 1071, 2273, 2481, 0 }; - static ulong[] dim558JoeKuoD6Init = { 1, 1, 7, 1, 25, 3, 39, 47, 201, 187, 419, 3881, 4031, 0 }; - static ulong[] dim559JoeKuoD6Init = { 1, 3, 1, 11, 17, 47, 119, 243, 217, 321, 727, 3227, 6041, 0 }; - static ulong[] dim560JoeKuoD6Init = { 1, 1, 5, 11, 9, 3, 85, 121, 161, 663, 2035, 4073, 7401, 0 }; - static ulong[] dim561JoeKuoD6Init = { 1, 1, 3, 5, 11, 45, 51, 99, 431, 307, 157, 2941, 1645, 0 }; - static ulong[] dim562JoeKuoD6Init = { 1, 3, 3, 7, 7, 43, 77, 19, 169, 535, 1797, 2907, 531, 0 }; - static ulong[] dim563JoeKuoD6Init = { 1, 1, 7, 9, 19, 11, 45, 51, 169, 175, 995, 2231, 147, 0 }; - static ulong[] dim564JoeKuoD6Init = { 1, 1, 5, 1, 3, 25, 123, 11, 387, 757, 1067, 1359, 2227, 0 }; - static ulong[] dim565JoeKuoD6Init = { 1, 1, 5, 15, 13, 41, 45, 135, 49, 391, 1551, 1729, 4799, 0 }; - static ulong[] dim566JoeKuoD6Init = { 1, 1, 7, 9, 3, 11, 109, 59, 217, 507, 47, 1609, 7145, 0 }; - static ulong[] dim567JoeKuoD6Init = { 1, 1, 5, 15, 13, 35, 7, 213, 495, 811, 1403, 3423, 8139, 0 }; - static ulong[] dim568JoeKuoD6Init = { 1, 3, 5, 15, 3, 55, 107, 47, 337, 305, 1869, 943, 7533, 0 }; - static ulong[] dim569JoeKuoD6Init = { 1, 1, 7, 15, 15, 51, 9, 209, 477, 173, 1921, 3295, 4283, 0 }; - static ulong[] dim570JoeKuoD6Init = { 1, 3, 7, 13, 17, 31, 111, 73, 143, 773, 1499, 651, 6659, 0 }; - static ulong[] dim571JoeKuoD6Init = { 1, 1, 1, 1, 17, 5, 1, 95, 347, 613, 49, 7, 2373, 0 }; - static ulong[] dim572JoeKuoD6Init = { 1, 1, 7, 13, 5, 21, 33, 227, 375, 635, 149, 1585, 6159, 0 }; - static ulong[] dim573JoeKuoD6Init = { 1, 3, 7, 5, 25, 7, 121, 185, 129, 1021, 167, 873, 949, 0 }; - static ulong[] dim574JoeKuoD6Init = { 1, 1, 3, 11, 29, 23, 25, 219, 203, 651, 629, 155, 5385, 0 }; - static ulong[] dim575JoeKuoD6Init = { 1, 3, 5, 9, 25, 1, 91, 213, 87, 807, 599, 2527, 6971, 0 }; - static ulong[] dim576JoeKuoD6Init = { 1, 3, 1, 11, 19, 13, 91, 11, 73, 617, 1721, 1803, 3005, 0 }; - static ulong[] dim577JoeKuoD6Init = { 1, 1, 5, 9, 25, 33, 19, 167, 195, 861, 1209, 1887, 3165, 0 }; - static ulong[] dim578JoeKuoD6Init = { 1, 1, 5, 1, 5, 21, 57, 253, 325, 907, 1237, 1037, 3639, 0 }; - static ulong[] dim579JoeKuoD6Init = { 1, 3, 1, 1, 5, 17, 35, 65, 193, 57, 1045, 2117, 7433, 0 }; - static ulong[] dim580JoeKuoD6Init = { 1, 3, 5, 1, 3, 23, 89, 157, 379, 831, 479, 3285, 5107, 0 }; - static ulong[] dim581JoeKuoD6Init = { 1, 3, 3, 1, 5, 35, 57, 107, 465, 81, 387, 1035, 7231, 0 }; - static ulong[] dim582JoeKuoD6Init = { 1, 3, 3, 9, 13, 25, 23, 39, 439, 89, 1651, 781, 6167, 0 }; - static ulong[] dim583JoeKuoD6Init = { 1, 1, 3, 1, 19, 33, 103, 139, 259, 201, 1569, 3453, 5143, 0 }; - static ulong[] dim584JoeKuoD6Init = { 1, 3, 1, 1, 5, 51, 33, 199, 509, 593, 1671, 243, 3455, 0 }; - static ulong[] dim585JoeKuoD6Init = { 1, 1, 5, 15, 31, 15, 81, 173, 357, 447, 595, 1177, 2435, 0 }; - static ulong[] dim586JoeKuoD6Init = { 1, 3, 5, 1, 9, 35, 53, 111, 277, 143, 1837, 385, 7057, 0 }; - static ulong[] dim587JoeKuoD6Init = { 1, 3, 3, 1, 7, 25, 115, 117, 1, 97, 51, 3459, 3057, 0 }; - static ulong[] dim588JoeKuoD6Init = { 1, 1, 3, 5, 11, 63, 85, 69, 1, 943, 279, 4091, 7753, 0 }; - static ulong[] dim589JoeKuoD6Init = { 1, 3, 7, 9, 7, 59, 19, 17, 435, 779, 1049, 2125, 3295, 0 }; - static ulong[] dim590JoeKuoD6Init = { 1, 1, 7, 13, 29, 45, 95, 37, 179, 463, 1503, 417, 1959, 0 }; - static ulong[] dim591JoeKuoD6Init = { 1, 3, 1, 9, 21, 27, 27, 53, 359, 781, 1387, 997, 2123, 0 }; - static ulong[] dim592JoeKuoD6Init = { 1, 3, 3, 13, 17, 39, 103, 175, 131, 973, 1055, 2935, 5671, 0 }; - static ulong[] dim593JoeKuoD6Init = { 1, 1, 3, 9, 7, 41, 55, 133, 223, 1019, 1341, 2559, 4225, 0 }; - static ulong[] dim594JoeKuoD6Init = { 1, 3, 5, 9, 13, 7, 85, 101, 161, 461, 227, 2073, 6483, 0 }; - static ulong[] dim595JoeKuoD6Init = { 1, 3, 3, 1, 11, 27, 67, 125, 287, 229, 1945, 2461, 7111, 0 }; - static ulong[] dim596JoeKuoD6Init = { 1, 1, 7, 3, 23, 59, 39, 137, 421, 245, 955, 1941, 3743, 0 }; - static ulong[] dim597JoeKuoD6Init = { 1, 1, 1, 9, 19, 55, 45, 93, 101, 777, 729, 867, 7123, 0 }; - static ulong[] dim598JoeKuoD6Init = { 1, 1, 5, 5, 21, 27, 49, 125, 245, 271, 1643, 3995, 1845, 0 }; - static ulong[] dim599JoeKuoD6Init = { 1, 1, 3, 15, 21, 63, 113, 157, 123, 347, 333, 2445, 3401, 0 }; - static ulong[] dim600JoeKuoD6Init = { 1, 3, 5, 5, 25, 7, 113, 13, 167, 935, 329, 3483, 4237, 0 }; - static ulong[] dim601JoeKuoD6Init = { 1, 1, 3, 9, 25, 43, 101, 115, 439, 633, 2001, 283, 4415, 0 }; - static ulong[] dim602JoeKuoD6Init = { 1, 3, 1, 7, 7, 39, 41, 201, 423, 351, 563, 653, 6769, 0 }; - static ulong[] dim603JoeKuoD6Init = { 1, 3, 7, 11, 3, 55, 29, 75, 17, 283, 837, 1303, 7917, 0 }; - static ulong[] dim604JoeKuoD6Init = { 1, 3, 1, 11, 9, 17, 47, 39, 399, 645, 575, 805, 5751, 0 }; - static ulong[] dim605JoeKuoD6Init = { 1, 3, 1, 11, 7, 9, 99, 239, 503, 995, 1265, 1651, 2095, 0 }; - static ulong[] dim606JoeKuoD6Init = { 1, 1, 3, 15, 17, 13, 107, 165, 341, 337, 51, 1619, 7801, 0 }; - static ulong[] dim607JoeKuoD6Init = { 1, 3, 1, 3, 19, 55, 73, 105, 97, 557, 1701, 799, 5591, 0 }; - static ulong[] dim608JoeKuoD6Init = { 1, 1, 5, 13, 15, 21, 35, 39, 215, 357, 171, 161, 4527, 0 }; - static ulong[] dim609JoeKuoD6Init = { 1, 3, 3, 15, 19, 7, 27, 153, 399, 415, 2031, 627, 8169, 0 }; - static ulong[] dim610JoeKuoD6Init = { 1, 3, 1, 11, 27, 37, 21, 217, 413, 787, 1637, 1199, 1735, 0 }; - static ulong[] dim611JoeKuoD6Init = { 1, 1, 7, 7, 25, 21, 95, 13, 159, 195, 1493, 1395, 7453, 0 }; - static ulong[] dim612JoeKuoD6Init = { 1, 3, 5, 1, 3, 17, 47, 95, 327, 493, 1501, 2857, 7215, 0 }; - static ulong[] dim613JoeKuoD6Init = { 1, 3, 1, 3, 19, 25, 67, 89, 243, 913, 815, 2471, 6537, 0 }; - static ulong[] dim614JoeKuoD6Init = { 1, 1, 3, 1, 29, 53, 13, 21, 131, 893, 1113, 525, 6723, 0 }; - static ulong[] dim615JoeKuoD6Init = { 1, 1, 5, 1, 25, 45, 97, 167, 465, 65, 1923, 3971, 6365, 0 }; - static ulong[] dim616JoeKuoD6Init = { 1, 1, 7, 7, 3, 7, 113, 85, 371, 143, 201, 1023, 2827, 0 }; - static ulong[] dim617JoeKuoD6Init = { 1, 3, 3, 1, 5, 31, 5, 37, 57, 203, 241, 2473, 593, 0 }; - static ulong[] dim618JoeKuoD6Init = { 1, 3, 1, 5, 25, 59, 87, 207, 227, 103, 491, 1299, 4173, 0 }; - static ulong[] dim619JoeKuoD6Init = { 1, 1, 7, 9, 15, 61, 75, 171, 421, 651, 375, 511, 2723, 0 }; - static ulong[] dim620JoeKuoD6Init = { 1, 3, 7, 11, 9, 19, 55, 5, 365, 7, 1401, 3049, 6669, 0 }; - static ulong[] dim621JoeKuoD6Init = { 1, 1, 1, 5, 31, 37, 97, 105, 343, 999, 1641, 1951, 1395, 0 }; - static ulong[] dim622JoeKuoD6Init = { 1, 3, 5, 1, 5, 13, 83, 189, 395, 335, 1767, 887, 3431, 0 }; - static ulong[] dim623JoeKuoD6Init = { 1, 1, 1, 13, 17, 45, 71, 227, 171, 831, 617, 1203, 6477, 0 }; - static ulong[] dim624JoeKuoD6Init = { 1, 1, 7, 13, 15, 49, 91, 61, 155, 951, 1031, 1153, 5201, 0 }; - static ulong[] dim625JoeKuoD6Init = { 1, 1, 1, 13, 23, 51, 75, 89, 359, 257, 1695, 1739, 5439, 0 }; - static ulong[] dim626JoeKuoD6Init = { 1, 3, 3, 13, 9, 47, 31, 225, 191, 787, 355, 2013, 5897, 0 }; - static ulong[] dim627JoeKuoD6Init = { 1, 1, 7, 3, 7, 41, 91, 83, 9, 643, 1589, 3491, 135, 0 }; - static ulong[] dim628JoeKuoD6Init = { 1, 3, 5, 9, 5, 29, 29, 249, 181, 641, 17, 3187, 6767, 0 }; - static ulong[] dim629JoeKuoD6Init = { 1, 1, 7, 13, 25, 17, 91, 187, 61, 305, 199, 2397, 2287, 0 }; - static ulong[] dim630JoeKuoD6Init = { 1, 1, 7, 1, 25, 45, 85, 35, 361, 353, 631, 1113, 135, 0 }; - static ulong[] dim631JoeKuoD6Init = { 1, 3, 7, 9, 13, 11, 107, 67, 127, 523, 1129, 81, 7627, 0 }; - static ulong[] dim632JoeKuoD6Init = { 1, 3, 1, 7, 17, 43, 89, 225, 45, 597, 1683, 943, 3801, 0 }; - static ulong[] dim633JoeKuoD6Init = { 1, 3, 7, 1, 31, 47, 37, 31, 269, 731, 1817, 3977, 7107, 0 }; - static ulong[] dim634JoeKuoD6Init = { 1, 1, 5, 5, 21, 37, 93, 219, 117, 369, 561, 4031, 365, 0 }; - static ulong[] dim635JoeKuoD6Init = { 1, 1, 5, 13, 31, 21, 65, 237, 157, 775, 843, 1725, 583, 0 }; - static ulong[] dim636JoeKuoD6Init = { 1, 1, 1, 11, 11, 31, 15, 217, 377, 395, 1633, 3841, 4417, 0 }; - static ulong[] dim637JoeKuoD6Init = { 1, 3, 7, 9, 23, 23, 93, 109, 265, 379, 1341, 1857, 5567, 0 }; - static ulong[] dim638JoeKuoD6Init = { 1, 1, 7, 1, 13, 37, 109, 121, 7, 157, 1639, 483, 1433, 0 }; - static ulong[] dim639JoeKuoD6Init = { 1, 1, 1, 3, 5, 37, 29, 107, 77, 771, 1631, 3051, 8097, 0 }; - static ulong[] dim640JoeKuoD6Init = { 1, 3, 7, 13, 27, 5, 59, 89, 401, 223, 1013, 1089, 3407, 0 }; - static ulong[] dim641JoeKuoD6Init = { 1, 1, 5, 5, 11, 47, 113, 237, 69, 833, 845, 179, 3687, 0 }; - static ulong[] dim642JoeKuoD6Init = { 1, 3, 7, 3, 19, 43, 117, 223, 373, 145, 463, 1719, 3621, 0 }; - static ulong[] dim643JoeKuoD6Init = { 1, 1, 3, 7, 5, 53, 5, 53, 385, 723, 809, 1785, 6495, 0 }; - static ulong[] dim644JoeKuoD6Init = { 1, 3, 7, 5, 3, 63, 125, 63, 275, 575, 1461, 821, 5607, 0 }; - static ulong[] dim645JoeKuoD6Init = { 1, 1, 5, 9, 17, 33, 71, 145, 215, 741, 1843, 1987, 4263, 0 }; - static ulong[] dim646JoeKuoD6Init = { 1, 3, 5, 3, 31, 63, 29, 233, 441, 447, 853, 3937, 4747, 0 }; - static ulong[] dim647JoeKuoD6Init = { 1, 3, 3, 15, 21, 35, 15, 221, 63, 481, 403, 2795, 5533, 0 }; - static ulong[] dim648JoeKuoD6Init = { 1, 3, 7, 9, 1, 47, 123, 129, 365, 23, 1975, 1179, 7957, 0 }; - static ulong[] dim649JoeKuoD6Init = { 1, 3, 1, 3, 11, 23, 119, 229, 141, 687, 1639, 2105, 319, 0 }; - static ulong[] dim650JoeKuoD6Init = { 1, 3, 1, 11, 17, 49, 3, 113, 297, 727, 1135, 2657, 187, 0 }; - static ulong[] dim651JoeKuoD6Init = { 1, 3, 7, 5, 5, 31, 83, 173, 159, 389, 1373, 3049, 827, 0 }; - static ulong[] dim652JoeKuoD6Init = { 1, 1, 1, 15, 27, 51, 107, 97, 119, 831, 247, 2613, 7125, 0 }; - static ulong[] dim653JoeKuoD6Init = { 1, 1, 3, 7, 23, 53, 35, 181, 81, 213, 1135, 2901, 1555, 0 }; - static ulong[] dim654JoeKuoD6Init = { 1, 3, 5, 7, 9, 45, 25, 137, 399, 345, 339, 1869, 3469, 0 }; - static ulong[] dim655JoeKuoD6Init = { 1, 1, 3, 5, 25, 49, 71, 139, 473, 883, 677, 1229, 6661, 0 }; - static ulong[] dim656JoeKuoD6Init = { 1, 3, 5, 13, 1, 55, 31, 67, 321, 221, 1425, 1335, 3805, 0 }; - static ulong[] dim657JoeKuoD6Init = { 1, 1, 5, 9, 7, 31, 53, 169, 67, 509, 1155, 1739, 615, 0 }; - static ulong[] dim658JoeKuoD6Init = { 1, 3, 7, 9, 1, 13, 49, 39, 263, 215, 767, 2881, 1517, 0 }; - static ulong[] dim659JoeKuoD6Init = { 1, 1, 5, 5, 27, 41, 15, 5, 203, 539, 463, 1983, 1949, 0 }; - static ulong[] dim660JoeKuoD6Init = { 1, 3, 3, 1, 21, 3, 101, 225, 255, 805, 1035, 813, 8125, 0 }; - static ulong[] dim661JoeKuoD6Init = { 1, 3, 1, 1, 17, 59, 55, 107, 117, 489, 541, 689, 581, 0 }; - static ulong[] dim662JoeKuoD6Init = { 1, 3, 7, 15, 17, 57, 75, 135, 295, 11, 1415, 1843, 7079, 0 }; - static ulong[] dim663JoeKuoD6Init = { 1, 1, 5, 5, 17, 49, 49, 91, 227, 295, 1501, 3723, 5879, 0 }; - static ulong[] dim664JoeKuoD6Init = { 1, 3, 5, 9, 27, 17, 63, 127, 503, 869, 53, 627, 5085, 0 }; - static ulong[] dim665JoeKuoD6Init = { 1, 3, 7, 3, 25, 25, 1, 83, 461, 1019, 1737, 1901, 2611, 0 }; - static ulong[] dim666JoeKuoD6Init = { 1, 3, 1, 11, 23, 59, 59, 235, 33, 747, 1141, 2429, 3833, 0 }; - static ulong[] dim667JoeKuoD6Init = { 1, 1, 7, 9, 29, 55, 85, 179, 385, 645, 1009, 1193, 5643, 0 }; - static ulong[] dim668JoeKuoD6Init = { 1, 1, 5, 15, 29, 11, 77, 147, 453, 655, 469, 2727, 6205, 0 }; - static ulong[] dim669JoeKuoD6Init = { 1, 3, 5, 3, 5, 13, 103, 115, 445, 87, 1803, 601, 5159, 0 }; - static ulong[] dim670JoeKuoD6Init = { 1, 1, 7, 5, 1, 37, 55, 129, 5, 387, 51, 3585, 6771, 0 }; - static ulong[] dim671JoeKuoD6Init = { 1, 3, 3, 15, 15, 15, 21, 13, 67, 391, 1745, 1137, 7039, 0 }; - static ulong[] dim672JoeKuoD6Init = { 1, 3, 7, 9, 25, 1, 83, 135, 275, 11, 339, 269, 6121, 0 }; - static ulong[] dim673JoeKuoD6Init = { 1, 1, 5, 3, 27, 11, 109, 15, 499, 489, 615, 1713, 7713, 0 }; - static ulong[] dim674JoeKuoD6Init = { 1, 3, 7, 15, 25, 53, 1, 169, 275, 623, 411, 195, 6331, 0 }; - static ulong[] dim675JoeKuoD6Init = { 1, 1, 3, 7, 3, 5, 73, 97, 407, 687, 311, 2141, 6687, 0 }; - static ulong[] dim676JoeKuoD6Init = { 1, 3, 5, 3, 27, 43, 123, 143, 99, 963, 2029, 3759, 1483, 0 }; - static ulong[] dim677JoeKuoD6Init = { 1, 1, 5, 3, 5, 43, 11, 51, 423, 111, 875, 3605, 4023, 0 }; - static ulong[] dim678JoeKuoD6Init = { 1, 1, 1, 15, 25, 11, 89, 21, 425, 585, 1983, 3481, 7329, 0 }; - static ulong[] dim679JoeKuoD6Init = { 1, 3, 7, 3, 1, 5, 107, 29, 285, 929, 663, 319, 3139, 0 }; - static ulong[] dim680JoeKuoD6Init = { 1, 3, 3, 7, 7, 37, 21, 51, 385, 539, 59, 1595, 9, 0 }; - static ulong[] dim681JoeKuoD6Init = { 1, 3, 3, 1, 9, 21, 87, 149, 21, 211, 787, 351, 5597, 0 }; - static ulong[] dim682JoeKuoD6Init = { 1, 3, 1, 11, 1, 41, 21, 65, 7, 83, 693, 1905, 5935, 0 }; - static ulong[] dim683JoeKuoD6Init = { 1, 3, 3, 11, 17, 3, 55, 205, 461, 897, 273, 2849, 1685, 0 }; - static ulong[] dim684JoeKuoD6Init = { 1, 3, 7, 5, 23, 15, 121, 129, 387, 967, 1131, 3451, 3545, 0 }; - static ulong[] dim685JoeKuoD6Init = { 1, 1, 7, 11, 5, 29, 59, 69, 27, 699, 1639, 2137, 6305, 0 }; - static ulong[] dim686JoeKuoD6Init = { 1, 3, 7, 7, 23, 23, 69, 205, 399, 661, 1187, 1639, 5099, 0 }; - static ulong[] dim687JoeKuoD6Init = { 1, 3, 5, 5, 31, 17, 37, 173, 371, 649, 449, 243, 3665, 0 }; - static ulong[] dim688JoeKuoD6Init = { 1, 3, 5, 1, 21, 5, 51, 105, 173, 699, 475, 3489, 7411, 0 }; - static ulong[] dim689JoeKuoD6Init = { 1, 1, 3, 13, 17, 41, 55, 131, 359, 461, 1885, 4045, 3615, 0 }; - static ulong[] dim690JoeKuoD6Init = { 1, 3, 7, 11, 27, 33, 79, 127, 227, 293, 607, 1713, 167, 0 }; - static ulong[] dim691JoeKuoD6Init = { 1, 3, 3, 1, 5, 9, 13, 59, 425, 319, 1813, 2905, 4647, 0 }; - static ulong[] dim692JoeKuoD6Init = { 1, 3, 5, 5, 13, 59, 69, 95, 379, 119, 1175, 1853, 7573, 0 }; - static ulong[] dim693JoeKuoD6Init = { 1, 3, 5, 3, 3, 47, 51, 203, 395, 623, 13, 3369, 663, 0 }; - static ulong[] dim694JoeKuoD6Init = { 1, 1, 5, 3, 3, 39, 107, 203, 125, 627, 1817, 1101, 935, 0 }; - static ulong[] dim695JoeKuoD6Init = { 1, 1, 1, 5, 7, 31, 71, 141, 507, 101, 913, 567, 753, 0 }; - static ulong[] dim696JoeKuoD6Init = { 1, 3, 5, 11, 1, 25, 81, 211, 79, 277, 1445, 783, 5, 0 }; - static ulong[] dim697JoeKuoD6Init = { 1, 1, 7, 3, 7, 9, 63, 87, 335, 413, 1595, 2313, 5883, 0 }; - static ulong[] dim698JoeKuoD6Init = { 1, 1, 1, 11, 21, 61, 87, 119, 155, 259, 1629, 2565, 5975, 0 }; - static ulong[] dim699JoeKuoD6Init = { 1, 3, 1, 3, 29, 59, 57, 205, 65, 779, 1433, 2845, 1311, 0 }; - static ulong[] dim700JoeKuoD6Init = { 1, 3, 3, 3, 29, 59, 1, 125, 493, 25, 315, 1171, 4837, 0 }; - static ulong[] dim701JoeKuoD6Init = { 1, 1, 1, 11, 1, 47, 119, 141, 95, 87, 1497, 3613, 5009, 0 }; - static ulong[] dim702JoeKuoD6Init = { 1, 3, 5, 5, 7, 19, 61, 233, 321, 585, 547, 179, 6787, 0 }; - static ulong[] dim703JoeKuoD6Init = { 1, 3, 1, 7, 15, 29, 51, 177, 189, 435, 89, 2507, 4975, 0 }; - static ulong[] dim704JoeKuoD6Init = { 1, 3, 7, 5, 19, 49, 125, 145, 329, 975, 717, 161, 1099, 0 }; - static ulong[] dim705JoeKuoD6Init = { 1, 3, 3, 13, 1, 21, 81, 63, 263, 597, 1713, 1759, 1745, 0 }; - static ulong[] dim706JoeKuoD6Init = { 1, 1, 3, 9, 17, 61, 19, 119, 229, 25, 1759, 343, 7925, 0 }; - static ulong[] dim707JoeKuoD6Init = { 1, 1, 1, 9, 27, 49, 51, 149, 453, 717, 1791, 2529, 331, 0 }; - static ulong[] dim708JoeKuoD6Init = { 1, 3, 1, 7, 11, 15, 125, 237, 291, 111, 1051, 3739, 3805, 0 }; - static ulong[] dim709JoeKuoD6Init = { 1, 1, 7, 9, 7, 63, 49, 73, 53, 429, 1167, 2019, 911, 0 }; - static ulong[] dim710JoeKuoD6Init = { 1, 3, 5, 5, 29, 17, 3, 193, 243, 29, 2007, 1881, 7143, 0 }; - static ulong[] dim711JoeKuoD6Init = { 1, 3, 3, 3, 5, 19, 127, 149, 57, 601, 1263, 1909, 3835, 0 }; - static ulong[] dim712JoeKuoD6Init = { 1, 1, 1, 5, 25, 43, 21, 115, 193, 735, 571, 401, 1573, 0 }; - static ulong[] dim713JoeKuoD6Init = { 1, 3, 5, 9, 25, 41, 53, 165, 5, 575, 1381, 995, 5851, 0 }; - static ulong[] dim714JoeKuoD6Init = { 1, 1, 5, 15, 21, 43, 25, 125, 49, 207, 345, 2981, 709, 0 }; - static ulong[] dim715JoeKuoD6Init = { 1, 1, 3, 5, 29, 37, 89, 145, 123, 771, 631, 3259, 1431, 0 }; - static ulong[] dim716JoeKuoD6Init = { 1, 1, 3, 3, 1, 37, 67, 243, 335, 913, 1927, 3027, 6059, 0 }; - static ulong[] dim717JoeKuoD6Init = { 1, 1, 5, 15, 11, 31, 61, 59, 511, 543, 1747, 3329, 599, 0 }; - static ulong[] dim718JoeKuoD6Init = { 1, 1, 7, 13, 17, 31, 9, 143, 381, 713, 135, 1037, 5981, 0 }; - static ulong[] dim719JoeKuoD6Init = { 1, 1, 7, 11, 25, 7, 79, 3, 403, 979, 1021, 457, 999, 0 }; - static ulong[] dim720JoeKuoD6Init = { 1, 3, 3, 11, 3, 19, 127, 135, 255, 645, 437, 3793, 5809, 0 }; - static ulong[] dim721JoeKuoD6Init = { 1, 3, 7, 1, 5, 59, 69, 135, 307, 769, 307, 3225, 2869, 0 }; - static ulong[] dim722JoeKuoD6Init = { 1, 3, 5, 3, 9, 33, 121, 41, 245, 1009, 2039, 925, 3341, 0 }; - static ulong[] dim723JoeKuoD6Init = { 1, 3, 3, 15, 19, 23, 55, 155, 389, 817, 475, 1005, 1971, 0 }; - static ulong[] dim724JoeKuoD6Init = { 1, 3, 5, 7, 11, 17, 7, 113, 249, 241, 1149, 2359, 8037, 0 }; - static ulong[] dim725JoeKuoD6Init = { 1, 3, 5, 5, 23, 59, 115, 5, 503, 221, 485, 3857, 4399, 0 }; - static ulong[] dim726JoeKuoD6Init = { 1, 3, 7, 3, 5, 53, 119, 107, 103, 99, 1313, 623, 3073, 0 }; - static ulong[] dim727JoeKuoD6Init = { 1, 3, 1, 13, 7, 21, 85, 47, 345, 355, 607, 2213, 2489, 0 }; - static ulong[] dim728JoeKuoD6Init = { 1, 1, 5, 11, 7, 51, 43, 53, 281, 311, 1221, 3919, 4821, 0 }; - static ulong[] dim729JoeKuoD6Init = { 1, 1, 7, 9, 21, 15, 105, 251, 367, 311, 1247, 2357, 5411, 0 }; - static ulong[] dim730JoeKuoD6Init = { 1, 3, 5, 5, 17, 21, 1, 213, 505, 97, 603, 4057, 6853, 0 }; - static ulong[] dim731JoeKuoD6Init = { 1, 3, 7, 5, 21, 3, 105, 61, 5, 39, 461, 351, 4379, 0 }; - static ulong[] dim732JoeKuoD6Init = { 1, 3, 3, 9, 15, 39, 87, 21, 393, 525, 1699, 2427, 211, 0 }; - static ulong[] dim733JoeKuoD6Init = { 1, 1, 5, 9, 21, 25, 53, 175, 387, 83, 1155, 1225, 5681, 0 }; - static ulong[] dim734JoeKuoD6Init = { 1, 3, 1, 15, 7, 49, 43, 127, 257, 499, 79, 33, 2843, 0 }; - static ulong[] dim735JoeKuoD6Init = { 1, 3, 7, 15, 21, 17, 89, 175, 161, 371, 389, 2289, 7751, 0 }; - static ulong[] dim736JoeKuoD6Init = { 1, 1, 7, 3, 19, 23, 65, 5, 149, 563, 1237, 3445, 6817, 0 }; - static ulong[] dim737JoeKuoD6Init = { 1, 3, 5, 11, 23, 21, 65, 11, 329, 323, 551, 3859, 749, 0 }; - static ulong[] dim738JoeKuoD6Init = { 1, 3, 1, 9, 13, 23, 11, 169, 203, 349, 1733, 2537, 3777, 0 }; - static ulong[] dim739JoeKuoD6Init = { 1, 3, 7, 7, 5, 19, 47, 81, 215, 677, 1861, 2703, 6373, 0 }; - static ulong[] dim740JoeKuoD6Init = { 1, 1, 5, 5, 11, 5, 19, 151, 215, 695, 1347, 1359, 1979, 0 }; - static ulong[] dim741JoeKuoD6Init = { 1, 1, 7, 3, 1, 59, 11, 185, 379, 247, 1885, 1819, 637, 0 }; - static ulong[] dim742JoeKuoD6Init = { 1, 3, 7, 3, 21, 3, 53, 161, 49, 697, 113, 3561, 95, 0 }; - static ulong[] dim743JoeKuoD6Init = { 1, 3, 7, 7, 29, 15, 85, 123, 415, 41, 703, 1501, 6939, 0 }; - static ulong[] dim744JoeKuoD6Init = { 1, 1, 7, 5, 7, 37, 75, 185, 115, 423, 625, 3557, 7851, 0 }; - static ulong[] dim745JoeKuoD6Init = { 1, 1, 1, 7, 11, 35, 119, 131, 331, 197, 1939, 1951, 7957, 0 }; - static ulong[] dim746JoeKuoD6Init = { 1, 1, 5, 3, 9, 43, 93, 11, 97, 483, 131, 1095, 601, 0 }; - static ulong[] dim747JoeKuoD6Init = { 1, 1, 1, 15, 11, 43, 49, 205, 393, 921, 625, 359, 3997, 0 }; - static ulong[] dim748JoeKuoD6Init = { 1, 1, 3, 7, 31, 21, 27, 231, 159, 67, 1127, 2153, 6291, 0 }; - static ulong[] dim749JoeKuoD6Init = { 1, 3, 1, 1, 13, 15, 45, 85, 155, 763, 1341, 9, 6229, 0 }; - static ulong[] dim750JoeKuoD6Init = { 1, 3, 7, 15, 9, 21, 47, 67, 207, 385, 401, 1665, 7849, 0 }; - static ulong[] dim751JoeKuoD6Init = { 1, 1, 5, 9, 13, 59, 89, 163, 19, 997, 2021, 3301, 2945, 0 }; - static ulong[] dim752JoeKuoD6Init = { 1, 1, 3, 15, 17, 9, 33, 117, 33, 701, 73, 2955, 1781, 0 }; - static ulong[] dim753JoeKuoD6Init = { 1, 1, 3, 7, 3, 11, 81, 209, 131, 247, 1927, 3997, 1709, 0 }; - static ulong[] dim754JoeKuoD6Init = { 1, 1, 3, 5, 21, 47, 85, 163, 247, 273, 545, 3477, 4565, 0 }; - static ulong[] dim755JoeKuoD6Init = { 1, 1, 1, 15, 3, 5, 55, 171, 501, 149, 121, 2317, 2023, 0 }; - static ulong[] dim756JoeKuoD6Init = { 1, 1, 5, 1, 25, 31, 25, 171, 471, 149, 49, 3059, 7871, 0 }; - static ulong[] dim757JoeKuoD6Init = { 1, 3, 3, 1, 3, 39, 91, 75, 183, 115, 869, 4005, 1443, 0 }; - static ulong[] dim758JoeKuoD6Init = { 1, 1, 1, 13, 31, 37, 3, 23, 443, 177, 219, 1683, 7063, 0 }; - static ulong[] dim759JoeKuoD6Init = { 1, 1, 1, 11, 17, 51, 111, 157, 455, 415, 1171, 531, 7289, 0 }; - static ulong[] dim760JoeKuoD6Init = { 1, 1, 7, 13, 3, 45, 103, 185, 63, 299, 1471, 3579, 3751, 0 }; - static ulong[] dim761JoeKuoD6Init = { 1, 1, 7, 7, 25, 45, 91, 145, 285, 525, 1675, 665, 883, 0 }; - static ulong[] dim762JoeKuoD6Init = { 1, 3, 7, 5, 23, 23, 33, 47, 271, 65, 1009, 2363, 7231, 0 }; - static ulong[] dim763JoeKuoD6Init = { 1, 3, 1, 11, 25, 3, 13, 105, 105, 649, 531, 535, 6019, 0 }; - static ulong[] dim764JoeKuoD6Init = { 1, 3, 3, 5, 9, 1, 9, 15, 131, 793, 1841, 2249, 5775, 0 }; - static ulong[] dim765JoeKuoD6Init = { 1, 1, 7, 7, 27, 35, 125, 249, 125, 973, 233, 229, 8165, 0 }; - static ulong[] dim766JoeKuoD6Init = { 1, 3, 1, 7, 19, 1, 39, 239, 159, 627, 601, 1537, 7473, 0 }; - static ulong[] dim767JoeKuoD6Init = { 1, 1, 3, 3, 1, 45, 99, 149, 205, 277, 1701, 121, 1577, 0 }; - static ulong[] dim768JoeKuoD6Init = { 1, 3, 7, 15, 9, 43, 7, 139, 331, 995, 647, 2707, 4493, 0 }; - static ulong[] dim769JoeKuoD6Init = { 1, 3, 3, 13, 19, 31, 67, 213, 355, 85, 1829, 2897, 6799, 0 }; - static ulong[] dim770JoeKuoD6Init = { 1, 3, 7, 1, 29, 51, 49, 209, 257, 913, 811, 895, 8051, 0 }; - static ulong[] dim771JoeKuoD6Init = { 1, 1, 3, 3, 31, 33, 19, 37, 297, 473, 1987, 3433, 1981, 0 }; - static ulong[] dim772JoeKuoD6Init = { 1, 1, 1, 13, 1, 3, 127, 183, 241, 941, 973, 577, 6891, 0 }; - static ulong[] dim773JoeKuoD6Init = { 1, 1, 7, 15, 31, 21, 125, 193, 23, 731, 493, 3173, 4381, 0 }; - static ulong[] dim774JoeKuoD6Init = { 1, 3, 3, 13, 23, 31, 65, 59, 63, 285, 1191, 3005, 2211, 0 }; - static ulong[] dim775JoeKuoD6Init = { 1, 1, 3, 3, 13, 11, 121, 153, 199, 359, 1159, 363, 3477, 0 }; - static ulong[] dim776JoeKuoD6Init = { 1, 1, 3, 3, 29, 27, 105, 215, 143, 365, 369, 3341, 5017, 0 }; - static ulong[] dim777JoeKuoD6Init = { 1, 1, 5, 9, 23, 43, 119, 89, 307, 607, 1087, 287, 7305, 0 }; - static ulong[] dim778JoeKuoD6Init = { 1, 1, 7, 3, 19, 9, 115, 133, 387, 717, 687, 3447, 201, 0 }; - static ulong[] dim779JoeKuoD6Init = { 1, 3, 1, 1, 23, 7, 81, 77, 483, 725, 1499, 1565, 8073, 0 }; - static ulong[] dim780JoeKuoD6Init = { 1, 3, 1, 9, 23, 25, 119, 247, 195, 205, 1851, 2463, 6827, 0 }; - static ulong[] dim781JoeKuoD6Init = { 1, 3, 5, 9, 17, 51, 11, 233, 115, 719, 1333, 3829, 4941, 0 }; - static ulong[] dim782JoeKuoD6Init = { 1, 1, 3, 13, 25, 17, 103, 241, 133, 237, 1375, 4005, 7853, 0 }; - static ulong[] dim783JoeKuoD6Init = { 1, 3, 7, 1, 19, 31, 115, 193, 305, 1, 1167, 325, 985, 0 }; - static ulong[] dim784JoeKuoD6Init = { 1, 1, 3, 15, 13, 11, 33, 27, 453, 941, 293, 2819, 3247, 0 }; - static ulong[] dim785JoeKuoD6Init = { 1, 3, 3, 3, 11, 27, 37, 95, 371, 441, 1347, 13, 4219, 0 }; - static ulong[] dim786JoeKuoD6Init = { 1, 3, 1, 11, 31, 39, 17, 63, 323, 1013, 479, 4077, 313, 0 }; - static ulong[] dim787JoeKuoD6Init = { 1, 3, 7, 15, 3, 59, 121, 19, 43, 351, 285, 2239, 8117, 0 }; - static ulong[] dim788JoeKuoD6Init = { 1, 1, 3, 3, 7, 7, 13, 31, 403, 925, 789, 275, 6959, 0 }; - static ulong[] dim789JoeKuoD6Init = { 1, 1, 1, 9, 3, 11, 89, 195, 393, 301, 517, 1675, 963, 0 }; - static ulong[] dim790JoeKuoD6Init = { 1, 3, 1, 13, 17, 63, 79, 17, 127, 119, 1127, 2121, 7545, 0 }; - static ulong[] dim791JoeKuoD6Init = { 1, 3, 5, 5, 29, 15, 97, 183, 157, 319, 1047, 895, 7297, 0 }; - static ulong[] dim792JoeKuoD6Init = { 1, 3, 1, 3, 25, 37, 101, 233, 275, 705, 1147, 1511, 231, 0 }; - static ulong[] dim793JoeKuoD6Init = { 1, 3, 1, 11, 3, 63, 45, 219, 315, 905, 9, 3105, 785, 0 }; - static ulong[] dim794JoeKuoD6Init = { 1, 1, 3, 1, 17, 27, 89, 15, 337, 981, 403, 1609, 349, 0 }; - static ulong[] dim795JoeKuoD6Init = { 1, 3, 1, 5, 27, 21, 39, 209, 461, 211, 71, 1413, 1185, 0 }; - static ulong[] dim796JoeKuoD6Init = { 1, 1, 3, 1, 11, 9, 19, 229, 403, 323, 1651, 475, 1207, 0 }; - static ulong[] dim797JoeKuoD6Init = { 1, 3, 7, 5, 31, 13, 39, 9, 365, 857, 1715, 3831, 2467, 0 }; - static ulong[] dim798JoeKuoD6Init = { 1, 1, 7, 1, 31, 41, 25, 101, 297, 143, 345, 2097, 1679, 0 }; - static ulong[] dim799JoeKuoD6Init = { 1, 3, 5, 7, 27, 61, 77, 107, 291, 265, 759, 933, 2529, 0 }; - static ulong[] dim800JoeKuoD6Init = { 1, 3, 7, 11, 15, 51, 31, 191, 39, 469, 1711, 1215, 7603, 0 }; - static ulong[] dim801JoeKuoD6Init = { 1, 1, 5, 13, 19, 27, 121, 235, 475, 11, 1193, 543, 5689, 0 }; - static ulong[] dim802JoeKuoD6Init = { 1, 3, 5, 11, 19, 1, 97, 85, 393, 971, 1915, 3487, 7569, 0 }; - static ulong[] dim803JoeKuoD6Init = { 1, 3, 7, 9, 21, 25, 81, 197, 9, 403, 1305, 2977, 6261, 0 }; - static ulong[] dim804JoeKuoD6Init = { 1, 3, 3, 15, 5, 3, 5, 91, 133, 957, 437, 3821, 4395, 0 }; - static ulong[] dim805JoeKuoD6Init = { 1, 3, 7, 7, 23, 47, 85, 139, 511, 389, 461, 2967, 7305, 0 }; - static ulong[] dim806JoeKuoD6Init = { 1, 3, 5, 5, 13, 3, 33, 171, 391, 109, 197, 2097, 5357, 0 }; - static ulong[] dim807JoeKuoD6Init = { 1, 3, 7, 15, 31, 61, 7, 61, 175, 455, 1867, 2829, 197, 0 }; - static ulong[] dim808JoeKuoD6Init = { 1, 3, 7, 13, 21, 33, 119, 97, 297, 69, 1503, 2887, 3785, 0 }; - static ulong[] dim809JoeKuoD6Init = { 1, 3, 3, 7, 1, 63, 105, 53, 443, 775, 1855, 2635, 4453, 0 }; - static ulong[] dim810JoeKuoD6Init = { 1, 1, 7, 11, 1, 13, 99, 227, 421, 739, 583, 4011, 2095, 0 }; - static ulong[] dim811JoeKuoD6Init = { 1, 1, 7, 11, 7, 21, 125, 45, 411, 621, 137, 259, 3401, 0 }; - static ulong[] dim812JoeKuoD6Init = { 1, 3, 3, 7, 9, 15, 47, 213, 71, 725, 2015, 3119, 3295, 0 }; - static ulong[] dim813JoeKuoD6Init = { 1, 1, 7, 7, 21, 63, 83, 63, 29, 969, 119, 3535, 989, 0 }; - static ulong[] dim814JoeKuoD6Init = { 1, 3, 3, 9, 13, 15, 71, 83, 209, 191, 1049, 3423, 5829, 0 }; - static ulong[] dim815JoeKuoD6Init = { 1, 3, 1, 11, 27, 7, 65, 107, 387, 853, 919, 1257, 719, 0 }; - static ulong[] dim816JoeKuoD6Init = { 1, 3, 1, 9, 29, 63, 115, 91, 181, 217, 1097, 1023, 3641, 0 }; - static ulong[] dim817JoeKuoD6Init = { 1, 1, 3, 7, 7, 57, 37, 209, 99, 959, 693, 1573, 3407, 0 }; - static ulong[] dim818JoeKuoD6Init = { 1, 3, 7, 7, 9, 51, 51, 127, 153, 977, 1565, 1329, 4603, 0 }; - static ulong[] dim819JoeKuoD6Init = { 1, 3, 5, 3, 9, 57, 7, 225, 139, 515, 1355, 191, 659, 0 }; - static ulong[] dim820JoeKuoD6Init = { 1, 3, 3, 3, 7, 45, 85, 231, 153, 93, 371, 2753, 5331, 0 }; - static ulong[] dim821JoeKuoD6Init = { 1, 1, 5, 5, 1, 9, 45, 29, 131, 203, 31, 1219, 1635, 0 }; - static ulong[] dim822JoeKuoD6Init = { 1, 1, 1, 11, 5, 13, 115, 51, 471, 987, 1937, 3921, 7885, 0 }; - static ulong[] dim823JoeKuoD6Init = { 1, 1, 7, 3, 1, 23, 49, 183, 495, 427, 1397, 3383, 3459, 0 }; - static ulong[] dim824JoeKuoD6Init = { 1, 1, 7, 1, 23, 39, 3, 205, 447, 603, 1213, 667, 1039, 0 }; - static ulong[] dim825JoeKuoD6Init = { 1, 1, 1, 5, 7, 63, 27, 169, 403, 775, 241, 3951, 3411, 0 }; - static ulong[] dim826JoeKuoD6Init = { 1, 1, 3, 1, 7, 1, 63, 185, 197, 813, 1757, 2687, 7289, 0 }; - static ulong[] dim827JoeKuoD6Init = { 1, 1, 7, 3, 21, 21, 97, 73, 73, 147, 1905, 2391, 3743, 0 }; - static ulong[] dim828JoeKuoD6Init = { 1, 3, 7, 1, 29, 45, 27, 93, 71, 749, 337, 7, 3959, 0 }; - static ulong[] dim829JoeKuoD6Init = { 1, 3, 3, 9, 25, 13, 61, 131, 183, 409, 1547, 1261, 5541, 0 }; - static ulong[] dim830JoeKuoD6Init = { 1, 1, 7, 9, 9, 13, 13, 115, 87, 587, 1561, 1845, 2383, 0 }; - static ulong[] dim831JoeKuoD6Init = { 1, 3, 3, 3, 13, 19, 99, 75, 435, 815, 251, 1639, 2157, 0 }; - static ulong[] dim832JoeKuoD6Init = { 1, 1, 7, 9, 19, 61, 49, 237, 325, 429, 1019, 2649, 6671, 0 }; - static ulong[] dim833JoeKuoD6Init = { 1, 3, 3, 11, 1, 59, 71, 143, 37, 445, 1289, 2089, 5693, 0 }; - static ulong[] dim834JoeKuoD6Init = { 1, 3, 3, 7, 13, 13, 119, 83, 111, 497, 739, 863, 2009, 0 }; - static ulong[] dim835JoeKuoD6Init = { 1, 3, 5, 1, 3, 21, 89, 27, 171, 121, 1453, 3273, 2891, 0 }; - static ulong[] dim836JoeKuoD6Init = { 1, 3, 5, 5, 29, 19, 79, 77, 343, 969, 1759, 1921, 4189, 0 }; - static ulong[] dim837JoeKuoD6Init = { 1, 1, 1, 3, 21, 55, 99, 49, 435, 697, 559, 3475, 6905, 0 }; - static ulong[] dim838JoeKuoD6Init = { 1, 3, 1, 5, 9, 37, 83, 79, 171, 935, 751, 3293, 299, 0 }; - static ulong[] dim839JoeKuoD6Init = { 1, 1, 3, 13, 13, 45, 35, 159, 283, 451, 495, 3239, 4429, 0 }; - static ulong[] dim840JoeKuoD6Init = { 1, 1, 3, 1, 13, 43, 107, 189, 475, 679, 1843, 33, 6895, 0 }; - static ulong[] dim841JoeKuoD6Init = { 1, 3, 5, 9, 17, 13, 107, 245, 415, 531, 265, 3165, 3189, 0 }; - static ulong[] dim842JoeKuoD6Init = { 1, 3, 1, 3, 31, 29, 103, 233, 31, 445, 649, 3377, 3207, 0 }; - static ulong[] dim843JoeKuoD6Init = { 1, 1, 3, 9, 19, 3, 1, 75, 423, 445, 1351, 2889, 5785, 0 }; - static ulong[] dim844JoeKuoD6Init = { 1, 1, 3, 3, 21, 19, 113, 35, 173, 871, 275, 1901, 6725, 0 }; - static ulong[] dim845JoeKuoD6Init = { 1, 1, 3, 7, 27, 45, 41, 93, 463, 209, 1721, 1863, 7893, 0 }; - static ulong[] dim846JoeKuoD6Init = { 1, 1, 1, 13, 25, 63, 17, 171, 403, 645, 1669, 1663, 4335, 0 }; - static ulong[] dim847JoeKuoD6Init = { 1, 3, 3, 7, 17, 15, 103, 5, 375, 7, 1117, 3851, 651, 0 }; - static ulong[] dim848JoeKuoD6Init = { 1, 1, 1, 15, 29, 43, 13, 241, 403, 349, 685, 987, 4177, 0 }; - static ulong[] dim849JoeKuoD6Init = { 1, 3, 5, 15, 31, 37, 111, 91, 391, 513, 1701, 2861, 4713, 0 }; - static ulong[] dim850JoeKuoD6Init = { 1, 1, 5, 9, 23, 59, 125, 117, 375, 461, 1697, 1283, 7395, 0 }; - static ulong[] dim851JoeKuoD6Init = { 1, 1, 3, 7, 21, 35, 101, 131, 129, 757, 199, 1881, 737, 0 }; - static ulong[] dim852JoeKuoD6Init = { 1, 1, 7, 3, 31, 15, 121, 143, 67, 593, 1143, 3761, 3441, 0 }; - static ulong[] dim853JoeKuoD6Init = { 1, 1, 3, 9, 11, 43, 7, 159, 25, 725, 1169, 1757, 3499, 0 }; - static ulong[] dim854JoeKuoD6Init = { 1, 1, 3, 9, 5, 55, 77, 85, 309, 113, 1419, 1255, 4777, 0 }; - static ulong[] dim855JoeKuoD6Init = { 1, 3, 3, 15, 19, 41, 75, 163, 51, 511, 1785, 4033, 7791, 0 }; - static ulong[] dim856JoeKuoD6Init = { 1, 3, 7, 15, 29, 45, 81, 189, 401, 71, 1597, 3671, 2133, 0 }; - static ulong[] dim857JoeKuoD6Init = { 1, 1, 3, 1, 3, 17, 119, 55, 217, 485, 1217, 1475, 5791, 0 }; - static ulong[] dim858JoeKuoD6Init = { 1, 1, 7, 9, 21, 61, 71, 175, 205, 413, 1645, 2375, 89, 0 }; - static ulong[] dim859JoeKuoD6Init = { 1, 3, 3, 7, 25, 35, 23, 49, 395, 675, 341, 959, 4665, 0 }; - static ulong[] dim860JoeKuoD6Init = { 1, 3, 5, 15, 21, 37, 99, 151, 197, 145, 2043, 755, 2523, 0 }; - static ulong[] dim861JoeKuoD6Init = { 1, 1, 1, 7, 1, 61, 75, 131, 65, 891, 349, 2767, 3855, 0 }; - static ulong[] dim862JoeKuoD6Init = { 1, 3, 5, 9, 29, 57, 61, 79, 303, 997, 1053, 1973, 1547, 0 }; - static ulong[] dim863JoeKuoD6Init = { 1, 1, 3, 7, 19, 9, 57, 197, 253, 597, 1971, 1831, 8097, 0 }; - static ulong[] dim864JoeKuoD6Init = { 1, 3, 1, 9, 3, 13, 29, 169, 25, 957, 1575, 2955, 3549, 0 }; - static ulong[] dim865JoeKuoD6Init = { 1, 1, 5, 11, 17, 37, 79, 91, 11, 687, 1511, 1065, 1539, 0 }; - static ulong[] dim866JoeKuoD6Init = { 1, 1, 1, 7, 1, 59, 1, 49, 23, 73, 881, 1661, 3841, 0 }; - static ulong[] dim867JoeKuoD6Init = { 1, 1, 1, 1, 13, 57, 111, 67, 511, 833, 1095, 15, 569, 0 }; - static ulong[] dim868JoeKuoD6Init = { 1, 3, 1, 5, 17, 33, 1, 161, 311, 29, 685, 729, 5981, 0 }; - static ulong[] dim869JoeKuoD6Init = { 1, 1, 7, 1, 7, 13, 49, 55, 251, 825, 709, 445, 7439, 0 }; - static ulong[] dim870JoeKuoD6Init = { 1, 3, 1, 5, 13, 55, 101, 89, 239, 907, 1559, 1421, 87, 0 }; - static ulong[] dim871JoeKuoD6Init = { 1, 1, 3, 9, 23, 27, 41, 189, 35, 155, 683, 2491, 7495, 0 }; - static ulong[] dim872JoeKuoD6Init = { 1, 3, 5, 3, 5, 47, 39, 161, 279, 945, 365, 15, 4643, 0 }; - static ulong[] dim873JoeKuoD6Init = { 1, 1, 1, 11, 21, 7, 125, 195, 23, 635, 1949, 2237, 1885, 0 }; - static ulong[] dim874JoeKuoD6Init = { 1, 1, 3, 7, 13, 25, 105, 145, 203, 701, 1525, 1391, 1637, 0 }; - static ulong[] dim875JoeKuoD6Init = { 1, 3, 3, 13, 7, 43, 13, 39, 301, 507, 405, 2333, 2405, 0 }; - static ulong[] dim876JoeKuoD6Init = { 1, 1, 5, 15, 25, 19, 31, 67, 81, 781, 1541, 3743, 2787, 0 }; - static ulong[] dim877JoeKuoD6Init = { 1, 1, 1, 11, 15, 7, 87, 129, 151, 225, 655, 1569, 5299, 0 }; - static ulong[] dim878JoeKuoD6Init = { 1, 1, 5, 3, 3, 33, 97, 255, 9, 667, 787, 3557, 5273, 0 }; - static ulong[] dim879JoeKuoD6Init = { 1, 1, 3, 3, 1, 7, 13, 31, 31, 1021, 1863, 2897, 6389, 0 }; - static ulong[] dim880JoeKuoD6Init = { 1, 3, 1, 15, 13, 29, 93, 27, 229, 599, 521, 1631, 3683, 0 }; - static ulong[] dim881JoeKuoD6Init = { 1, 1, 7, 9, 11, 27, 43, 95, 149, 159, 495, 2711, 2189, 0 }; - static ulong[] dim882JoeKuoD6Init = { 1, 1, 7, 9, 11, 51, 43, 121, 299, 73, 1991, 561, 6781, 0 }; - static ulong[] dim883JoeKuoD6Init = { 1, 1, 3, 3, 7, 61, 125, 13, 415, 11, 15, 2463, 385, 0 }; - static ulong[] dim884JoeKuoD6Init = { 1, 3, 5, 1, 27, 23, 1, 47, 149, 371, 1599, 341, 1595, 0 }; - static ulong[] dim885JoeKuoD6Init = { 1, 1, 1, 15, 3, 39, 65, 5, 33, 713, 399, 2935, 3825, 0 }; - static ulong[] dim886JoeKuoD6Init = { 1, 1, 7, 7, 17, 39, 3, 235, 227, 231, 323, 2869, 4747, 0 }; - static ulong[] dim887JoeKuoD6Init = { 1, 1, 5, 9, 13, 11, 41, 155, 393, 701, 909, 2999, 5053, 0 }; - static ulong[] dim888JoeKuoD6Init = { 1, 1, 3, 7, 5, 41, 105, 13, 123, 429, 1455, 2501, 1065, 0 }; - static ulong[] dim889JoeKuoD6Init = { 1, 1, 1, 7, 17, 21, 95, 141, 305, 951, 1305, 3639, 3797, 0 }; - static ulong[] dim890JoeKuoD6Init = { 1, 3, 5, 9, 7, 59, 29, 129, 265, 889, 993, 1411, 2069, 0 }; - static ulong[] dim891JoeKuoD6Init = { 1, 1, 1, 11, 3, 51, 9, 35, 355, 131, 1307, 1547, 701, 0 }; - static ulong[] dim892JoeKuoD6Init = { 1, 1, 7, 3, 17, 57, 113, 197, 483, 831, 1741, 3897, 3649, 0 }; - static ulong[] dim893JoeKuoD6Init = { 1, 1, 5, 11, 1, 33, 7, 243, 95, 905, 1933, 2123, 7381, 0 }; - static ulong[] dim894JoeKuoD6Init = { 1, 3, 3, 15, 5, 37, 1, 235, 77, 375, 1231, 1029, 1839, 0 }; - static ulong[] dim895JoeKuoD6Init = { 1, 1, 5, 3, 31, 11, 103, 245, 373, 103, 25, 1283, 6155, 0 }; - static ulong[] dim896JoeKuoD6Init = { 1, 3, 5, 1, 25, 25, 51, 159, 381, 97, 799, 565, 5165, 0 }; - static ulong[] dim897JoeKuoD6Init = { 1, 1, 7, 13, 25, 21, 109, 3, 253, 459, 623, 2817, 7815, 0 }; - static ulong[] dim898JoeKuoD6Init = { 1, 3, 5, 1, 23, 5, 127, 157, 187, 187, 1383, 2777, 2413, 0 }; - static ulong[] dim899JoeKuoD6Init = { 1, 1, 5, 3, 29, 47, 97, 197, 215, 725, 445, 2111, 1701, 0 }; - static ulong[] dim900JoeKuoD6Init = { 1, 3, 1, 9, 27, 25, 105, 59, 333, 79, 1099, 3695, 5725, 0 }; - static ulong[] dim901JoeKuoD6Init = { 1, 1, 7, 3, 11, 15, 127, 151, 163, 967, 665, 733, 509, 0 }; - static ulong[] dim902JoeKuoD6Init = { 1, 3, 3, 3, 15, 5, 51, 17, 409, 679, 229, 1037, 353, 0 }; - static ulong[] dim903JoeKuoD6Init = { 1, 3, 7, 15, 7, 9, 17, 115, 205, 105, 597, 2913, 1941, 0 }; - static ulong[] dim904JoeKuoD6Init = { 1, 1, 5, 11, 31, 1, 99, 213, 33, 319, 617, 1493, 7287, 0 }; - static ulong[] dim905JoeKuoD6Init = { 1, 3, 5, 5, 21, 31, 115, 43, 309, 217, 1, 3363, 6673, 0 }; - static ulong[] dim906JoeKuoD6Init = { 1, 3, 7, 7, 11, 29, 125, 75, 209, 217, 1749, 1565, 4431, 0 }; - static ulong[] dim907JoeKuoD6Init = { 1, 3, 5, 1, 5, 37, 103, 237, 19, 763, 915, 753, 7479, 0 }; - static ulong[] dim908JoeKuoD6Init = { 1, 3, 3, 9, 11, 59, 9, 133, 455, 683, 251, 963, 3743, 0 }; - static ulong[] dim909JoeKuoD6Init = { 1, 3, 5, 9, 7, 41, 97, 185, 117, 367, 2045, 3013, 6249, 0 }; - static ulong[] dim910JoeKuoD6Init = { 1, 1, 1, 5, 29, 51, 53, 147, 379, 769, 865, 2273, 1755, 0 }; - static ulong[] dim911JoeKuoD6Init = { 1, 3, 1, 7, 13, 61, 125, 153, 297, 385, 1981, 2221, 4209, 0 }; - static ulong[] dim912JoeKuoD6Init = { 1, 1, 7, 15, 7, 33, 41, 43, 201, 819, 129, 757, 4087, 0 }; - static ulong[] dim913JoeKuoD6Init = { 1, 1, 5, 7, 31, 15, 19, 15, 197, 921, 1967, 491, 4911, 0 }; - static ulong[] dim914JoeKuoD6Init = { 1, 1, 1, 13, 21, 25, 119, 123, 255, 155, 1765, 2895, 4201, 0 }; - static ulong[] dim915JoeKuoD6Init = { 1, 3, 5, 9, 1, 63, 57, 193, 327, 455, 1729, 1259, 7483, 0 }; - static ulong[] dim916JoeKuoD6Init = { 1, 3, 5, 1, 5, 19, 71, 255, 257, 477, 1799, 3855, 955, 0 }; - static ulong[] dim917JoeKuoD6Init = { 1, 1, 3, 1, 29, 27, 7, 151, 327, 311, 235, 3599, 6165, 0 }; - static ulong[] dim918JoeKuoD6Init = { 1, 3, 3, 3, 7, 29, 113, 87, 339, 271, 1141, 1111, 7971, 0 }; - static ulong[] dim919JoeKuoD6Init = { 1, 3, 5, 15, 23, 51, 57, 233, 179, 397, 1059, 123, 697, 0 }; - static ulong[] dim920JoeKuoD6Init = { 1, 3, 3, 13, 17, 11, 15, 189, 437, 449, 1533, 2209, 1849, 0 }; - static ulong[] dim921JoeKuoD6Init = { 1, 3, 5, 9, 9, 19, 53, 165, 279, 875, 1223, 1585, 6647, 0 }; - static ulong[] dim922JoeKuoD6Init = { 1, 1, 7, 5, 5, 49, 119, 31, 273, 919, 413, 1531, 6233, 0 }; - static ulong[] dim923JoeKuoD6Init = { 1, 3, 5, 5, 1, 19, 27, 213, 413, 271, 223, 299, 5635, 0 }; - static ulong[] dim924JoeKuoD6Init = { 1, 1, 7, 3, 11, 55, 25, 43, 147, 53, 95, 1849, 7701, 0 }; - static ulong[] dim925JoeKuoD6Init = { 1, 3, 5, 11, 17, 35, 9, 3, 117, 729, 21, 3379, 5963, 0 }; - static ulong[] dim926JoeKuoD6Init = { 1, 3, 1, 7, 23, 25, 45, 103, 181, 677, 1155, 205, 1967, 0 }; - static ulong[] dim927JoeKuoD6Init = { 1, 1, 3, 9, 19, 53, 41, 243, 97, 199, 407, 3299, 5309, 0 }; - static ulong[] dim928JoeKuoD6Init = { 1, 3, 5, 11, 27, 27, 59, 153, 501, 855, 1235, 2295, 5535, 0 }; - static ulong[] dim929JoeKuoD6Init = { 1, 1, 3, 7, 11, 37, 1, 179, 289, 895, 511, 697, 5067, 0 }; - static ulong[] dim930JoeKuoD6Init = { 1, 3, 7, 15, 25, 27, 33, 37, 351, 351, 813, 2239, 1561, 0 }; - static ulong[] dim931JoeKuoD6Init = { 1, 3, 1, 7, 25, 51, 79, 65, 427, 293, 1031, 685, 533, 0 }; - static ulong[] dim932JoeKuoD6Init = { 1, 3, 3, 15, 21, 21, 77, 31, 299, 643, 161, 2991, 7911, 0 }; - static ulong[] dim933JoeKuoD6Init = { 1, 3, 3, 7, 7, 61, 99, 19, 43, 35, 687, 1449, 5211, 0 }; - static ulong[] dim934JoeKuoD6Init = { 1, 3, 1, 5, 5, 59, 101, 175, 149, 799, 439, 19, 7565, 0 }; - static ulong[] dim935JoeKuoD6Init = { 1, 3, 7, 9, 31, 13, 75, 227, 337, 207, 609, 2119, 3539, 0 }; - static ulong[] dim936JoeKuoD6Init = { 1, 1, 1, 11, 3, 59, 1, 139, 425, 583, 263, 2687, 4445, 0 }; - static ulong[] dim937JoeKuoD6Init = { 1, 1, 5, 7, 21, 31, 55, 117, 377, 469, 1907, 3091, 3221, 0 }; - static ulong[] dim938JoeKuoD6Init = { 1, 1, 5, 1, 7, 63, 89, 197, 271, 425, 1493, 2337, 6397, 0 }; - static ulong[] dim939JoeKuoD6Init = { 1, 1, 1, 7, 9, 35, 17, 237, 215, 211, 523, 3095, 1771, 0 }; - static ulong[] dim940JoeKuoD6Init = { 1, 1, 5, 5, 19, 23, 119, 31, 331, 533, 71, 319, 7567, 0 }; - static ulong[] dim941JoeKuoD6Init = { 1, 1, 5, 7, 1, 33, 41, 9, 421, 789, 1305, 3775, 6545, 0 }; - static ulong[] dim942JoeKuoD6Init = { 1, 3, 1, 11, 17, 9, 47, 237, 227, 859, 113, 429, 5399, 0 }; - static ulong[] dim943JoeKuoD6Init = { 1, 3, 5, 11, 25, 29, 15, 1, 73, 1015, 2023, 367, 1523, 0 }; - static ulong[] dim944JoeKuoD6Init = { 1, 1, 5, 11, 19, 31, 121, 243, 411, 717, 671, 1329, 2669, 0 }; - static ulong[] dim945JoeKuoD6Init = { 1, 1, 1, 11, 27, 41, 23, 13, 353, 533, 1627, 1625, 3705, 0 }; - static ulong[] dim946JoeKuoD6Init = { 1, 1, 7, 11, 31, 41, 17, 3, 163, 207, 407, 1475, 5911, 0 }; - static ulong[] dim947JoeKuoD6Init = { 1, 1, 7, 3, 3, 19, 87, 199, 77, 207, 1957, 1691, 5045, 0 }; - static ulong[] dim948JoeKuoD6Init = { 1, 1, 1, 3, 19, 57, 107, 37, 419, 943, 133, 519, 4391, 0 }; - static ulong[] dim949JoeKuoD6Init = { 1, 3, 5, 11, 7, 5, 85, 1, 265, 801, 2025, 2655, 4635, 0 }; - static ulong[] dim950JoeKuoD6Init = { 1, 3, 3, 3, 7, 13, 15, 155, 283, 97, 1311, 607, 2879, 0 }; - static ulong[] dim951JoeKuoD6Init = { 1, 1, 5, 9, 21, 31, 3, 237, 323, 749, 1879, 611, 6763, 0 }; - static ulong[] dim952JoeKuoD6Init = { 1, 3, 5, 9, 19, 51, 25, 39, 7, 973, 837, 105, 1987, 0 }; - static ulong[] dim953JoeKuoD6Init = { 1, 1, 5, 13, 9, 63, 39, 233, 391, 93, 1741, 425, 901, 0 }; - static ulong[] dim954JoeKuoD6Init = { 1, 3, 7, 13, 13, 23, 95, 195, 263, 71, 255, 1839, 4301, 0 }; - static ulong[] dim955JoeKuoD6Init = { 1, 3, 1, 3, 29, 35, 123, 145, 377, 1021, 1361, 2319, 1487, 0 }; - static ulong[] dim956JoeKuoD6Init = { 1, 3, 7, 15, 9, 27, 61, 85, 81, 371, 1803, 3683, 4771, 0 }; - static ulong[] dim957JoeKuoD6Init = { 1, 3, 7, 15, 9, 35, 51, 137, 3, 721, 1269, 2667, 7293, 0 }; - static ulong[] dim958JoeKuoD6Init = { 1, 1, 3, 15, 3, 53, 121, 227, 55, 937, 1623, 2691, 2353, 0 }; - static ulong[] dim959JoeKuoD6Init = { 1, 3, 1, 5, 7, 53, 53, 121, 299, 633, 263, 3651, 3187, 0 }; - static ulong[] dim960JoeKuoD6Init = { 1, 3, 1, 9, 31, 59, 73, 5, 475, 763, 115, 2263, 2475, 0 }; - static ulong[] dim961JoeKuoD6Init = { 1, 3, 3, 7, 13, 15, 49, 227, 285, 41, 1817, 2573, 4991, 0 }; - static ulong[] dim962JoeKuoD6Init = { 1, 3, 5, 3, 17, 7, 29, 93, 253, 527, 657, 1859, 763, 0 }; - static ulong[] dim963JoeKuoD6Init = { 1, 1, 5, 11, 9, 11, 75, 47, 469, 119, 1505, 3807, 2769, 0 }; - static ulong[] dim964JoeKuoD6Init = { 1, 1, 3, 11, 1, 37, 65, 135, 345, 307, 305, 1167, 1767, 0 }; - static ulong[] dim965JoeKuoD6Init = { 1, 3, 3, 13, 5, 33, 9, 245, 271, 123, 1865, 2215, 2791, 0 }; - static ulong[] dim966JoeKuoD6Init = { 1, 1, 3, 1, 9, 23, 3, 21, 149, 923, 1335, 1015, 45, 0 }; - static ulong[] dim967JoeKuoD6Init = { 1, 3, 1, 15, 11, 3, 65, 219, 233, 353, 771, 3961, 1515, 0 }; - static ulong[] dim968JoeKuoD6Init = { 1, 3, 1, 5, 15, 41, 87, 141, 19, 905, 449, 3727, 1875, 0 }; - static ulong[] dim969JoeKuoD6Init = { 1, 1, 7, 9, 11, 15, 53, 151, 243, 279, 1695, 2317, 6661, 0 }; - static ulong[] dim970JoeKuoD6Init = { 1, 3, 3, 7, 19, 51, 31, 157, 79, 399, 465, 661, 1029, 0 }; - static ulong[] dim971JoeKuoD6Init = { 1, 3, 5, 1, 5, 41, 3, 33, 157, 385, 1943, 1851, 3121, 0 }; - static ulong[] dim972JoeKuoD6Init = { 1, 3, 1, 11, 25, 59, 105, 191, 151, 285, 801, 201, 6871, 0 }; - static ulong[] dim973JoeKuoD6Init = { 1, 3, 1, 15, 27, 35, 17, 195, 387, 907, 1905, 2177, 2597, 0 }; - static ulong[] dim974JoeKuoD6Init = { 1, 3, 1, 9, 31, 43, 71, 185, 469, 809, 541, 571, 107, 0 }; - static ulong[] dim975JoeKuoD6Init = { 1, 3, 7, 13, 5, 15, 55, 211, 305, 645, 1317, 2751, 603, 0 }; - static ulong[] dim976JoeKuoD6Init = { 1, 1, 3, 15, 19, 59, 45, 147, 165, 223, 259, 1205, 431, 0 }; - static ulong[] dim977JoeKuoD6Init = { 1, 1, 5, 13, 5, 53, 115, 57, 203, 151, 1039, 871, 3881, 0 }; - static ulong[] dim978JoeKuoD6Init = { 1, 3, 5, 15, 1, 29, 115, 249, 79, 957, 143, 3425, 5769, 0 }; - static ulong[] dim979JoeKuoD6Init = { 1, 1, 7, 15, 15, 15, 117, 181, 363, 17, 1871, 1049, 2997, 0 }; - static ulong[] dim980JoeKuoD6Init = { 1, 1, 3, 7, 23, 11, 77, 123, 149, 1019, 93, 3637, 6975, 0 }; - static ulong[] dim981JoeKuoD6Init = { 1, 1, 1, 7, 5, 51, 77, 89, 121, 155, 1839, 1301, 2771, 0 }; - static ulong[] dim982JoeKuoD6Init = { 1, 3, 7, 7, 7, 39, 33, 69, 169, 535, 1699, 2117, 3233, 0 }; - static ulong[] dim983JoeKuoD6Init = { 1, 3, 5, 7, 3, 59, 81, 113, 261, 627, 79, 227, 7623, 0 }; - static ulong[] dim984JoeKuoD6Init = { 1, 3, 5, 5, 13, 57, 121, 41, 11, 111, 1055, 3313, 3371, 0 }; - static ulong[] dim985JoeKuoD6Init = { 1, 1, 3, 13, 13, 9, 47, 197, 303, 987, 1125, 2461, 5007, 0 }; - static ulong[] dim986JoeKuoD6Init = { 1, 3, 1, 5, 1, 59, 109, 49, 453, 673, 2017, 205, 4673, 0 }; - static ulong[] dim987JoeKuoD6Init = { 1, 3, 1, 13, 19, 43, 95, 247, 475, 193, 1513, 885, 5391, 0 }; - static ulong[] dim988JoeKuoD6Init = { 1, 1, 1, 11, 29, 57, 77, 101, 433, 537, 1681, 2463, 6623, 0 }; - static ulong[] dim989JoeKuoD6Init = { 1, 3, 7, 13, 3, 61, 29, 53, 29, 673, 1037, 3877, 7421, 0 }; - static ulong[] dim990JoeKuoD6Init = { 1, 3, 3, 11, 5, 59, 61, 91, 13, 949, 1093, 1291, 7395, 0 }; - static ulong[] dim991JoeKuoD6Init = { 1, 3, 3, 13, 21, 27, 49, 37, 429, 877, 1247, 2375, 737, 0 }; - static ulong[] dim992JoeKuoD6Init = { 1, 3, 5, 3, 25, 19, 75, 187, 239, 971, 859, 2519, 7323, 0 }; - static ulong[] dim993JoeKuoD6Init = { 1, 3, 3, 7, 25, 19, 11, 223, 75, 801, 313, 2875, 6857, 0 }; - static ulong[] dim994JoeKuoD6Init = { 1, 1, 7, 3, 13, 63, 49, 125, 65, 1005, 1757, 3685, 4385, 0 }; - static ulong[] dim995JoeKuoD6Init = { 1, 3, 1, 15, 5, 41, 95, 231, 505, 907, 751, 3207, 4115, 0 }; - static ulong[] dim996JoeKuoD6Init = { 1, 1, 7, 11, 31, 7, 29, 51, 449, 151, 1821, 3317, 931, 0 }; - static ulong[] dim997JoeKuoD6Init = { 1, 3, 1, 11, 19, 11, 19, 47, 111, 637, 37, 3707, 2599, 0 }; - static ulong[] dim998JoeKuoD6Init = { 1, 3, 7, 5, 23, 27, 65, 217, 491, 129, 1715, 2479, 2015, 0 }; - static ulong[] dim999JoeKuoD6Init = { 1, 1, 5, 3, 5, 51, 43, 253, 495, 105, 1183, 3409, 1469, 0 }; - static ulong[] dim1000JoeKuoD6Init = { 1, 3, 7, 9, 21, 5, 87, 67, 481, 405, 1967, 2837, 5161, 0 }; - static ulong[] dim1001JoeKuoD6Init = { 1, 1, 7, 3, 29, 25, 15, 211, 233, 301, 1037, 3853, 7115, 0 }; - static ulong[] dim1002JoeKuoD6Init = { 1, 3, 5, 9, 3, 15, 85, 81, 141, 395, 845, 17, 7485, 0 }; - static ulong[] dim1003JoeKuoD6Init = { 1, 3, 5, 3, 21, 37, 39, 93, 461, 615, 1725, 1745, 5137, 0 }; - static ulong[] dim1004JoeKuoD6Init = { 1, 1, 3, 1, 1, 21, 21, 207, 271, 447, 1415, 2507, 3291, 0 }; - static ulong[] dim1005JoeKuoD6Init = { 1, 3, 7, 11, 23, 3, 115, 191, 257, 1015, 463, 1501, 7439, 0 }; - static ulong[] dim1006JoeKuoD6Init = { 1, 1, 7, 11, 3, 53, 101, 221, 9, 225, 1799, 1701, 5669, 0 }; - static ulong[] dim1007JoeKuoD6Init = { 1, 1, 7, 13, 17, 27, 7, 115, 67, 645, 1283, 75, 1881, 0 }; - static ulong[] dim1008JoeKuoD6Init = { 1, 1, 3, 15, 7, 39, 75, 85, 127, 379, 1509, 2215, 5697, 0 }; - static ulong[] dim1009JoeKuoD6Init = { 1, 1, 7, 1, 19, 31, 11, 67, 263, 877, 337, 1655, 1855, 0 }; - static ulong[] dim1010JoeKuoD6Init = { 1, 3, 5, 9, 11, 47, 125, 89, 235, 331, 159, 685, 999, 0 }; - static ulong[] dim1011JoeKuoD6Init = { 1, 3, 7, 3, 23, 39, 59, 69, 221, 291, 725, 2831, 4743, 0 }; - static ulong[] dim1012JoeKuoD6Init = { 1, 3, 7, 11, 1, 43, 127, 235, 143, 329, 1823, 21, 73, 0 }; - static ulong[] dim1013JoeKuoD6Init = { 1, 3, 1, 3, 27, 23, 33, 29, 493, 775, 1873, 1005, 2869, 0 }; - static ulong[] dim1014JoeKuoD6Init = { 1, 3, 3, 9, 3, 31, 63, 249, 353, 849, 5, 2787, 4759, 0 }; - static ulong[] dim1015JoeKuoD6Init = { 1, 3, 3, 11, 15, 15, 73, 159, 433, 35, 1203, 2541, 6713, 0 }; - static ulong[] dim1016JoeKuoD6Init = { 1, 1, 5, 1, 13, 17, 107, 101, 411, 861, 1075, 2161, 3923, 0 }; - static ulong[] dim1017JoeKuoD6Init = { 1, 1, 3, 5, 29, 29, 55, 205, 235, 685, 1445, 2413, 6837, 0 }; - static ulong[] dim1018JoeKuoD6Init = { 1, 1, 1, 13, 13, 1, 125, 37, 331, 33, 47, 2761, 3449, 0 }; - static ulong[] dim1019JoeKuoD6Init = { 1, 1, 7, 3, 17, 21, 21, 93, 145, 423, 1057, 997, 6117, 0 }; - static ulong[] dim1020JoeKuoD6Init = { 1, 3, 3, 13, 25, 47, 13, 159, 41, 907, 1543, 1919, 5547, 0 }; - static ulong[] dim1021JoeKuoD6Init = { 1, 1, 3, 9, 29, 53, 83, 45, 133, 453, 183, 2939, 4945, 0 }; - static ulong[] dim1022JoeKuoD6Init = { 1, 1, 1, 7, 9, 7, 89, 71, 315, 983, 1471, 2475, 7077, 0 }; - static ulong[] dim1023JoeKuoD6Init = { 1, 1, 3, 3, 31, 21, 55, 37, 337, 63, 299, 2415, 153, 0 }; - static ulong[] dim1024JoeKuoD6Init = { 1, 1, 7, 3, 27, 59, 85, 109, 405, 337, 393, 2291, 5423, 0 }; - static ulong[] dim1025JoeKuoD6Init = { 1, 1, 1, 1, 5, 31, 33, 43, 141, 9, 1271, 1749, 6281, 0 }; - static ulong[] dim1026JoeKuoD6Init = { 1, 1, 3, 9, 23, 35, 25, 17, 49, 119, 883, 2907, 3573, 0 }; - static ulong[] dim1027JoeKuoD6Init = { 1, 3, 1, 15, 25, 61, 89, 15, 315, 1015, 563, 1895, 4123, 0 }; - static ulong[] dim1028JoeKuoD6Init = { 1, 3, 3, 7, 15, 53, 61, 225, 381, 217, 163, 4005, 7269, 0 }; - static ulong[] dim1029JoeKuoD6Init = { 1, 3, 7, 5, 1, 59, 13, 201, 53, 629, 1917, 3105, 3047, 0 }; - static ulong[] dim1030JoeKuoD6Init = { 1, 3, 1, 1, 19, 45, 71, 11, 15, 365, 1223, 3861, 5005, 0 }; - static ulong[] dim1031JoeKuoD6Init = { 1, 1, 5, 11, 15, 15, 31, 245, 105, 609, 1051, 1911, 7531, 0 }; - static ulong[] dim1032JoeKuoD6Init = { 1, 3, 7, 11, 27, 5, 79, 31, 201, 347, 1295, 2589, 5179, 0 }; - static ulong[] dim1033JoeKuoD6Init = { 1, 1, 3, 1, 31, 23, 65, 203, 359, 591, 1459, 1941, 2307, 0 }; - static ulong[] dim1034JoeKuoD6Init = { 1, 1, 5, 5, 3, 55, 79, 179, 147, 223, 1011, 1437, 3715, 0 }; - static ulong[] dim1035JoeKuoD6Init = { 1, 1, 5, 11, 23, 19, 57, 241, 363, 729, 1647, 2395, 3237, 0 }; - static ulong[] dim1036JoeKuoD6Init = { 1, 3, 7, 7, 7, 63, 115, 53, 485, 965, 551, 3945, 1535, 0 }; - static ulong[] dim1037JoeKuoD6Init = { 1, 1, 1, 15, 5, 61, 33, 213, 451, 363, 95, 1185, 3633, 0 }; - static ulong[] dim1038JoeKuoD6Init = { 1, 3, 5, 1, 17, 49, 39, 159, 327, 1021, 289, 3375, 8055, 0 }; - static ulong[] dim1039JoeKuoD6Init = { 1, 3, 3, 5, 11, 1, 73, 3, 121, 561, 209, 1913, 4549, 0 }; - static ulong[] dim1040JoeKuoD6Init = { 1, 3, 1, 3, 23, 39, 101, 231, 317, 397, 693, 1579, 3585, 0 }; - static ulong[] dim1041JoeKuoD6Init = { 1, 1, 1, 1, 1, 5, 81, 209, 373, 689, 259, 3167, 1665, 0 }; - static ulong[] dim1042JoeKuoD6Init = { 1, 1, 1, 11, 21, 19, 83, 201, 7, 573, 1563, 1649, 5827, 0 }; - static ulong[] dim1043JoeKuoD6Init = { 1, 3, 5, 1, 31, 35, 53, 149, 185, 925, 701, 3727, 4425, 0 }; - static ulong[] dim1044JoeKuoD6Init = { 1, 1, 5, 7, 19, 11, 67, 47, 19, 789, 1855, 293, 7569, 0 }; - static ulong[] dim1045JoeKuoD6Init = { 1, 1, 5, 13, 25, 55, 25, 187, 405, 1013, 493, 1645, 6753, 0 }; - static ulong[] dim1046JoeKuoD6Init = { 1, 1, 3, 11, 13, 23, 35, 219, 247, 723, 1079, 1523, 7383, 0 }; - static ulong[] dim1047JoeKuoD6Init = { 1, 1, 3, 13, 5, 1, 27, 151, 61, 889, 1911, 3859, 4661, 0 }; - static ulong[] dim1048JoeKuoD6Init = { 1, 3, 1, 7, 15, 59, 57, 157, 333, 367, 245, 3043, 1683, 0 }; - static ulong[] dim1049JoeKuoD6Init = { 1, 3, 7, 11, 15, 53, 107, 81, 287, 637, 557, 315, 4361, 0 }; - static ulong[] dim1050JoeKuoD6Init = { 1, 1, 5, 11, 11, 21, 35, 59, 429, 459, 1439, 639, 6907, 0 }; - static ulong[] dim1051JoeKuoD6Init = { 1, 3, 3, 11, 13, 51, 101, 121, 437, 9, 889, 1907, 5217, 0 }; - static ulong[] dim1052JoeKuoD6Init = { 1, 1, 7, 13, 7, 5, 99, 161, 207, 237, 1547, 403, 2269, 0 }; - static ulong[] dim1053JoeKuoD6Init = { 1, 1, 5, 9, 23, 17, 43, 113, 119, 213, 977, 1197, 1039, 0 }; - static ulong[] dim1054JoeKuoD6Init = { 1, 3, 3, 9, 25, 51, 79, 5, 355, 279, 875, 1947, 1261, 0 }; - static ulong[] dim1055JoeKuoD6Init = { 1, 1, 7, 3, 5, 15, 85, 137, 361, 509, 959, 3227, 3755, 0 }; - static ulong[] dim1056JoeKuoD6Init = { 1, 1, 7, 3, 29, 31, 45, 139, 143, 891, 877, 2195, 4405, 0 }; - static ulong[] dim1057JoeKuoD6Init = { 1, 1, 1, 7, 17, 7, 81, 19, 469, 713, 57, 3559, 4925, 0 }; - static ulong[] dim1058JoeKuoD6Init = { 1, 1, 1, 9, 13, 43, 69, 77, 225, 497, 1263, 1153, 7375, 0 }; - static ulong[] dim1059JoeKuoD6Init = { 1, 1, 5, 7, 15, 19, 67, 75, 207, 851, 1827, 3523, 2159, 0 }; - static ulong[] dim1060JoeKuoD6Init = { 1, 3, 7, 3, 25, 63, 71, 157, 509, 219, 1529, 2513, 1697, 0 }; - static ulong[] dim1061JoeKuoD6Init = { 1, 3, 1, 5, 9, 9, 13, 147, 363, 561, 1707, 2991, 1671, 0 }; - static ulong[] dim1062JoeKuoD6Init = { 1, 3, 1, 15, 13, 55, 77, 27, 427, 277, 725, 2861, 4841, 0 }; - static ulong[] dim1063JoeKuoD6Init = { 1, 1, 5, 15, 25, 55, 21, 135, 221, 965, 1723, 2097, 1277, 0 }; - static ulong[] dim1064JoeKuoD6Init = { 1, 1, 5, 3, 1, 11, 45, 179, 503, 283, 1075, 1283, 7603, 0 }; - static ulong[] dim1065JoeKuoD6Init = { 1, 3, 1, 1, 1, 39, 61, 107, 183, 817, 1577, 1143, 783, 0 }; - static ulong[] dim1066JoeKuoD6Init = { 1, 1, 5, 13, 9, 59, 51, 89, 397, 705, 1081, 3053, 4001, 0 }; - static ulong[] dim1067JoeKuoD6Init = { 1, 3, 3, 11, 25, 53, 3, 125, 419, 827, 1907, 903, 3169, 0 }; - static ulong[] dim1068JoeKuoD6Init = { 1, 3, 5, 9, 1, 3, 119, 153, 353, 315, 1555, 1273, 6605, 0 }; - static ulong[] dim1069JoeKuoD6Init = { 1, 1, 3, 13, 13, 39, 117, 59, 225, 735, 1297, 1281, 8049, 0 }; - static ulong[] dim1070JoeKuoD6Init = { 1, 3, 1, 3, 27, 53, 57, 95, 303, 803, 343, 4021, 5047, 0 }; - static ulong[] dim1071JoeKuoD6Init = { 1, 3, 1, 11, 25, 1, 91, 107, 181, 839, 1691, 3859, 2363, 0 }; - static ulong[] dim1072JoeKuoD6Init = { 1, 1, 7, 1, 19, 45, 23, 37, 345, 675, 5, 3731, 2961, 0 }; - static ulong[] dim1073JoeKuoD6Init = { 1, 3, 1, 11, 13, 47, 19, 43, 221, 1007, 1021, 2967, 6931, 0 }; - static ulong[] dim1074JoeKuoD6Init = { 1, 3, 7, 5, 27, 21, 19, 57, 59, 485, 967, 983, 4989, 0 }; - static ulong[] dim1075JoeKuoD6Init = { 1, 3, 7, 3, 11, 23, 1, 221, 223, 535, 155, 2805, 661, 0 }; - static ulong[] dim1076JoeKuoD6Init = { 1, 1, 7, 5, 3, 49, 127, 75, 215, 517, 1391, 589, 493, 0 }; - static ulong[] dim1077JoeKuoD6Init = { 1, 1, 7, 5, 23, 29, 79, 171, 319, 811, 191, 1131, 7689, 0 }; - static ulong[] dim1078JoeKuoD6Init = { 1, 1, 1, 7, 21, 9, 23, 21, 171, 631, 299, 2295, 5691, 0 }; - static ulong[] dim1079JoeKuoD6Init = { 1, 1, 3, 7, 17, 59, 47, 205, 39, 407, 1107, 1323, 6769, 0 }; - static ulong[] dim1080JoeKuoD6Init = { 1, 3, 7, 1, 9, 33, 117, 249, 167, 631, 717, 3901, 6125, 0 }; - static ulong[] dim1081JoeKuoD6Init = { 1, 3, 7, 9, 31, 11, 75, 125, 417, 803, 1117, 1609, 3263, 0 }; - static ulong[] dim1082JoeKuoD6Init = { 1, 3, 1, 3, 15, 33, 35, 205, 477, 939, 1891, 2579, 2035, 0 }; - static ulong[] dim1083JoeKuoD6Init = { 1, 3, 5, 1, 5, 21, 5, 221, 105, 103, 587, 2111, 5891, 0 }; - static ulong[] dim1084JoeKuoD6Init = { 1, 3, 1, 11, 3, 45, 91, 113, 311, 617, 1629, 1677, 2349, 0 }; - static ulong[] dim1085JoeKuoD6Init = { 1, 1, 7, 13, 27, 17, 69, 11, 75, 545, 1245, 785, 645, 0 }; - static ulong[] dim1086JoeKuoD6Init = { 1, 3, 3, 5, 23, 13, 87, 193, 407, 445, 1299, 81, 2679, 0 }; - static ulong[] dim1087JoeKuoD6Init = { 1, 1, 7, 15, 17, 43, 13, 233, 255, 51, 1277, 965, 1615, 0 }; - static ulong[] dim1088JoeKuoD6Init = { 1, 3, 7, 1, 31, 49, 21, 61, 269, 265, 25, 3141, 7687, 0 }; - static ulong[] dim1089JoeKuoD6Init = { 1, 3, 3, 13, 27, 39, 65, 69, 453, 203, 461, 1585, 5681, 0 }; - static ulong[] dim1090JoeKuoD6Init = { 1, 1, 3, 3, 23, 19, 63, 97, 339, 83, 671, 433, 5285, 0 }; - static ulong[] dim1091JoeKuoD6Init = { 1, 3, 7, 11, 9, 3, 119, 157, 385, 847, 1159, 1389, 5833, 0 }; - static ulong[] dim1092JoeKuoD6Init = { 1, 1, 5, 5, 31, 51, 39, 247, 71, 815, 1807, 1973, 1841, 0 }; - static ulong[] dim1093JoeKuoD6Init = { 1, 1, 3, 3, 31, 39, 121, 75, 343, 25, 59, 575, 3503, 0 }; - static ulong[] dim1094JoeKuoD6Init = { 1, 1, 5, 11, 23, 17, 35, 33, 437, 1001, 1941, 351, 2949, 0 }; - static ulong[] dim1095JoeKuoD6Init = { 1, 1, 3, 7, 9, 51, 125, 3, 279, 373, 157, 1537, 5547, 0 }; - static ulong[] dim1096JoeKuoD6Init = { 1, 3, 1, 11, 11, 23, 63, 91, 139, 911, 463, 1831, 7325, 0 }; - static ulong[] dim1097JoeKuoD6Init = { 1, 3, 7, 1, 9, 11, 33, 125, 471, 583, 881, 2533, 7173, 0 }; - static ulong[] dim1098JoeKuoD6Init = { 1, 1, 5, 1, 15, 41, 53, 77, 43, 237, 787, 3299, 5131, 0 }; - static ulong[] dim1099JoeKuoD6Init = { 1, 1, 7, 7, 17, 19, 115, 145, 231, 555, 1279, 605, 2977, 0 }; - static ulong[] dim1100JoeKuoD6Init = { 1, 1, 3, 7, 21, 47, 61, 171, 337, 441, 1961, 2815, 4565, 0 }; - static ulong[] dim1101JoeKuoD6Init = { 1, 1, 7, 9, 25, 25, 3, 199, 85, 129, 1853, 3293, 71, 0 }; - static ulong[] dim1102JoeKuoD6Init = { 1, 1, 3, 1, 25, 25, 113, 9, 453, 353, 1955, 1443, 7027, 0 }; - static ulong[] dim1103JoeKuoD6Init = { 1, 3, 3, 11, 9, 35, 89, 149, 335, 485, 37, 1519, 7341, 0 }; - static ulong[] dim1104JoeKuoD6Init = { 1, 3, 7, 15, 27, 1, 119, 175, 181, 353, 1667, 2023, 3239, 0 }; - static ulong[] dim1105JoeKuoD6Init = { 1, 1, 1, 5, 27, 11, 39, 255, 283, 101, 603, 541, 2429, 0 }; - static ulong[] dim1106JoeKuoD6Init = { 1, 1, 7, 11, 27, 51, 87, 187, 183, 1013, 1207, 3431, 3321, 0 }; - static ulong[] dim1107JoeKuoD6Init = { 1, 1, 5, 3, 5, 15, 107, 171, 139, 919, 235, 3047, 3401, 0 }; - static ulong[] dim1108JoeKuoD6Init = { 1, 3, 3, 1, 17, 49, 35, 37, 59, 61, 227, 3175, 4093, 0 }; - static ulong[] dim1109JoeKuoD6Init = { 1, 1, 3, 1, 23, 51, 43, 143, 389, 559, 349, 1933, 6149, 0 }; - static ulong[] dim1110JoeKuoD6Init = { 1, 3, 5, 13, 9, 19, 111, 233, 373, 883, 1653, 1591, 2971, 0 }; - static ulong[] dim1111JoeKuoD6Init = { 1, 3, 3, 13, 7, 63, 95, 29, 173, 175, 355, 877, 5819, 15873, 0 }; - static ulong[] dim1112JoeKuoD6Init = { 1, 1, 1, 7, 1, 63, 23, 73, 469, 893, 773, 3647, 1191, 8731, 0 }; - static ulong[] dim1113JoeKuoD6Init = { 1, 3, 3, 9, 17, 9, 85, 137, 53, 793, 439, 2097, 4257, 8439, 0 }; - static ulong[] dim1114JoeKuoD6Init = { 1, 1, 7, 15, 3, 57, 83, 83, 123, 399, 1659, 2621, 3355, 255, 0 }; - static ulong[] dim1115JoeKuoD6Init = { 1, 1, 5, 13, 9, 55, 21, 55, 391, 765, 2023, 1211, 1265, 5391, 0 }; - static ulong[] dim1116JoeKuoD6Init = { 1, 1, 1, 11, 31, 63, 43, 153, 423, 969, 931, 531, 1635, 4695, 0 }; - static ulong[] dim1117JoeKuoD6Init = { 1, 1, 5, 11, 19, 11, 115, 213, 473, 13, 853, 3771, 7841, 1249, 0 }; - static ulong[] dim1118JoeKuoD6Init = { 1, 1, 1, 5, 31, 51, 121, 97, 483, 511, 299, 3307, 3363, 12639, 0 }; - static ulong[] dim1119JoeKuoD6Init = { 1, 3, 3, 1, 31, 31, 89, 221, 451, 253, 1371, 2457, 573, 4359, 0 }; - static ulong[] dim1120JoeKuoD6Init = { 1, 1, 7, 5, 5, 21, 59, 151, 275, 937, 1603, 3337, 3157, 15289, 0 }; - static ulong[] dim1121JoeKuoD6Init = { 1, 3, 1, 3, 19, 11, 27, 5, 405, 899, 1315, 3299, 945, 1421, 0 }; - static ulong[] dim1122JoeKuoD6Init = { 1, 3, 7, 3, 31, 55, 85, 49, 303, 859, 469, 723, 2221, 4099, 0 }; - static ulong[] dim1123JoeKuoD6Init = { 1, 1, 5, 13, 31, 27, 57, 37, 493, 883, 1781, 2915, 6435, 6905, 0 }; - static ulong[] dim1124JoeKuoD6Init = { 1, 1, 1, 7, 21, 49, 111, 69, 221, 845, 219, 1257, 7909, 15225, 0 }; - static ulong[] dim1125JoeKuoD6Init = { 1, 3, 1, 3, 3, 1, 89, 143, 359, 717, 327, 1063, 3845, 8963, 0 }; - static ulong[] dim1126JoeKuoD6Init = { 1, 1, 3, 7, 31, 3, 5, 79, 241, 877, 309, 3735, 1409, 11947, 0 }; - static ulong[] dim1127JoeKuoD6Init = { 1, 1, 1, 7, 13, 63, 89, 69, 417, 809, 1251, 3213, 1107, 9143, 0 }; - static ulong[] dim1128JoeKuoD6Init = { 1, 3, 7, 9, 21, 3, 17, 231, 273, 545, 1385, 1367, 5491, 7497, 0 }; - static ulong[] dim1129JoeKuoD6Init = { 1, 1, 7, 1, 31, 35, 117, 31, 173, 711, 555, 1551, 443, 10469, 0 }; - static ulong[] dim1130JoeKuoD6Init = { 1, 1, 5, 9, 3, 61, 55, 31, 321, 517, 47, 1379, 4329, 2305, 0 }; - static ulong[] dim1131JoeKuoD6Init = { 1, 1, 5, 15, 15, 13, 23, 153, 209, 115, 913, 2013, 841, 2015, 0 }; - static ulong[] dim1132JoeKuoD6Init = { 1, 3, 1, 5, 15, 43, 31, 103, 55, 489, 1003, 2723, 2613, 15743, 0 }; - static ulong[] dim1133JoeKuoD6Init = { 1, 3, 5, 3, 31, 45, 21, 37, 453, 99, 1047, 235, 1133, 11199, 0 }; - static ulong[] dim1134JoeKuoD6Init = { 1, 1, 1, 9, 13, 25, 109, 129, 25, 291, 445, 2775, 1011, 4645, 0 }; - static ulong[] dim1135JoeKuoD6Init = { 1, 1, 3, 9, 9, 45, 7, 161, 217, 645, 421, 3429, 2941, 5319, 0 }; - static ulong[] dim1136JoeKuoD6Init = { 1, 1, 3, 15, 13, 57, 13, 63, 89, 739, 1989, 1679, 2031, 265, 0 }; - static ulong[] dim1137JoeKuoD6Init = { 1, 3, 7, 9, 21, 63, 117, 21, 345, 19, 1357, 611, 6591, 8075, 0 }; - static ulong[] dim1138JoeKuoD6Init = { 1, 1, 7, 13, 29, 37, 37, 219, 81, 143, 1505, 2921, 1497, 4359, 0 }; - static ulong[] dim1139JoeKuoD6Init = { 1, 3, 5, 9, 25, 23, 39, 145, 121, 877, 1491, 2687, 865, 3417, 0 }; - static ulong[] dim1140JoeKuoD6Init = { 1, 1, 1, 13, 25, 7, 45, 143, 61, 591, 455, 3039, 4147, 1695, 0 }; - static ulong[] dim1141JoeKuoD6Init = { 1, 1, 1, 9, 27, 7, 61, 139, 509, 843, 1175, 3787, 4695, 13851, 0 }; - static ulong[] dim1142JoeKuoD6Init = { 1, 3, 1, 5, 15, 19, 73, 109, 263, 791, 455, 3503, 1203, 4993, 0 }; - static ulong[] dim1143JoeKuoD6Init = { 1, 1, 1, 11, 21, 59, 51, 101, 407, 25, 355, 2817, 3323, 14641, 0 }; - static ulong[] dim1144JoeKuoD6Init = { 1, 3, 1, 13, 3, 45, 73, 241, 511, 763, 189, 2913, 489, 10441, 0 }; - static ulong[] dim1145JoeKuoD6Init = { 1, 1, 7, 9, 15, 9, 113, 103, 375, 773, 621, 3035, 4359, 13259, 0 }; - static ulong[] dim1146JoeKuoD6Init = { 1, 3, 1, 1, 17, 13, 81, 207, 493, 737, 427, 2895, 539, 4125, 0 }; - static ulong[] dim1147JoeKuoD6Init = { 1, 1, 1, 11, 9, 5, 89, 209, 175, 105, 293, 3337, 7235, 6481, 0 }; - static ulong[] dim1148JoeKuoD6Init = { 1, 3, 1, 13, 5, 19, 3, 245, 25, 733, 885, 3747, 3997, 7945, 0 }; - static ulong[] dim1149JoeKuoD6Init = { 1, 3, 3, 11, 13, 7, 29, 169, 239, 205, 1399, 1447, 5211, 11789, 0 }; - static ulong[] dim1150JoeKuoD6Init = { 1, 3, 1, 15, 7, 19, 65, 23, 183, 547, 671, 2873, 5101, 4187, 0 }; - static ulong[] dim1151JoeKuoD6Init = { 1, 3, 5, 13, 15, 35, 119, 75, 53, 773, 1769, 1945, 7781, 11349, 0 }; - static ulong[] dim1152JoeKuoD6Init = { 1, 3, 7, 9, 31, 37, 39, 55, 333, 567, 1095, 3707, 4265, 117, 0 }; - static ulong[] dim1153JoeKuoD6Init = { 1, 3, 1, 3, 1, 61, 9, 7, 253, 737, 1441, 2591, 2807, 13685, 0 }; - static ulong[] dim1154JoeKuoD6Init = { 1, 1, 3, 11, 21, 41, 81, 61, 497, 827, 783, 3799, 4803, 141, 0 }; - static ulong[] dim1155JoeKuoD6Init = { 1, 3, 7, 13, 11, 15, 3, 165, 401, 747, 1961, 3265, 8123, 2151, 0 }; - static ulong[] dim1156JoeKuoD6Init = { 1, 3, 3, 15, 21, 39, 47, 135, 61, 803, 1447, 1763, 2033, 12907, 0 }; - static ulong[] dim1157JoeKuoD6Init = { 1, 1, 1, 9, 25, 21, 15, 233, 493, 115, 921, 2047, 3715, 9089, 0 }; - static ulong[] dim1158JoeKuoD6Init = { 1, 3, 5, 5, 11, 17, 43, 49, 249, 873, 771, 47, 5357, 12459, 0 }; - static ulong[] dim1159JoeKuoD6Init = { 1, 3, 3, 13, 31, 39, 85, 97, 241, 529, 65, 1995, 2411, 761, 0 }; - static ulong[] dim1160JoeKuoD6Init = { 1, 3, 5, 15, 3, 1, 63, 229, 11, 733, 901, 63, 3585, 10273, 0 }; - static ulong[] dim1161JoeKuoD6Init = { 1, 1, 1, 13, 23, 39, 123, 187, 27, 893, 1127, 2781, 5977, 13797, 0 }; - static ulong[] dim1162JoeKuoD6Init = { 1, 1, 5, 13, 15, 35, 97, 29, 345, 447, 897, 793, 5155, 15939, 0 }; - static ulong[] dim1163JoeKuoD6Init = { 1, 1, 3, 3, 1, 15, 19, 189, 183, 137, 1059, 2135, 6891, 10319, 0 }; - static ulong[] dim1164JoeKuoD6Init = { 1, 1, 1, 11, 29, 27, 83, 111, 113, 225, 1527, 1071, 635, 3471, 0 }; - static ulong[] dim1165JoeKuoD6Init = { 1, 3, 1, 3, 27, 9, 43, 19, 409, 579, 1983, 811, 5477, 559, 0 }; - static ulong[] dim1166JoeKuoD6Init = { 1, 3, 7, 9, 1, 39, 121, 249, 355, 677, 899, 729, 2611, 9463, 0 }; - static ulong[] dim1167JoeKuoD6Init = { 1, 1, 1, 11, 31, 43, 47, 157, 309, 529, 787, 1935, 5679, 1553, 0 }; - static ulong[] dim1168JoeKuoD6Init = { 1, 1, 5, 15, 19, 53, 63, 71, 371, 455, 1943, 477, 6227, 1033, 0 }; - static ulong[] dim1169JoeKuoD6Init = { 1, 1, 3, 15, 9, 55, 45, 247, 189, 57, 1573, 591, 2831, 14273, 0 }; - static ulong[] dim1170JoeKuoD6Init = { 1, 3, 5, 7, 3, 37, 33, 219, 13, 163, 763, 3921, 7617, 15439, 0 }; - static ulong[] dim1171JoeKuoD6Init = { 1, 3, 1, 13, 21, 41, 85, 151, 117, 587, 1513, 17, 7695, 4135, 0 }; - static ulong[] dim1172JoeKuoD6Init = { 1, 3, 1, 5, 21, 51, 107, 209, 107, 459, 243, 3043, 473, 1357, 0 }; - static ulong[] dim1173JoeKuoD6Init = { 1, 3, 1, 1, 5, 49, 87, 203, 261, 935, 765, 2879, 7677, 607, 0 }; - static ulong[] dim1174JoeKuoD6Init = { 1, 3, 7, 15, 25, 31, 7, 53, 391, 569, 187, 2761, 1369, 8871, 0 }; - static ulong[] dim1175JoeKuoD6Init = { 1, 1, 1, 15, 9, 25, 31, 59, 485, 253, 381, 1239, 4797, 4691, 0 }; - static ulong[] dim1176JoeKuoD6Init = { 1, 3, 5, 9, 13, 17, 35, 97, 339, 47, 1053, 293, 8103, 8489, 0 }; - static ulong[] dim1177JoeKuoD6Init = { 1, 1, 1, 11, 13, 7, 43, 33, 187, 135, 277, 1011, 297, 8443, 0 }; - static ulong[] dim1178JoeKuoD6Init = { 1, 3, 5, 1, 13, 45, 125, 185, 369, 643, 791, 119, 7205, 6785, 0 }; - static ulong[] dim1179JoeKuoD6Init = { 1, 1, 3, 15, 15, 39, 89, 33, 47, 801, 1451, 2583, 445, 14029, 0 }; - static ulong[] dim1180JoeKuoD6Init = { 1, 3, 1, 13, 27, 53, 113, 159, 395, 835, 655, 3503, 3733, 1547, 0 }; - static ulong[] dim1181JoeKuoD6Init = { 1, 1, 7, 5, 29, 61, 43, 181, 127, 839, 755, 579, 6805, 4591, 0 }; - static ulong[] dim1182JoeKuoD6Init = { 1, 3, 1, 1, 29, 63, 71, 145, 149, 571, 1129, 2503, 5761, 6251, 0 }; - static ulong[] dim1183JoeKuoD6Init = { 1, 3, 5, 7, 7, 21, 73, 101, 29, 517, 235, 195, 3561, 15347, 0 }; - static ulong[] dim1184JoeKuoD6Init = { 1, 3, 5, 9, 11, 11, 109, 81, 483, 183, 753, 1635, 3763, 8141, 0 }; - static ulong[] dim1185JoeKuoD6Init = { 1, 3, 5, 1, 21, 35, 111, 251, 255, 605, 1613, 283, 3035, 11681, 0 }; - static ulong[] dim1186JoeKuoD6Init = { 1, 3, 7, 3, 29, 49, 43, 255, 217, 791, 1281, 2327, 5115, 10261, 0 }; - static ulong[] dim1187JoeKuoD6Init = { 1, 3, 7, 9, 19, 23, 93, 105, 69, 429, 1729, 3547, 217, 15075, 0 }; - static ulong[] dim1188JoeKuoD6Init = { 1, 3, 1, 9, 7, 21, 13, 81, 395, 997, 399, 3925, 7277, 1733, 0 }; - static ulong[] dim1189JoeKuoD6Init = { 1, 3, 7, 13, 11, 51, 65, 29, 489, 489, 1639, 3949, 6271, 2015, 0 }; - static ulong[] dim1190JoeKuoD6Init = { 1, 1, 7, 1, 15, 39, 23, 67, 121, 617, 1689, 1887, 3485, 7913, 0 }; - static ulong[] dim1191JoeKuoD6Init = { 1, 3, 7, 3, 25, 23, 81, 59, 87, 457, 937, 3229, 2731, 5003, 0 }; - static ulong[] dim1192JoeKuoD6Init = { 1, 1, 5, 11, 29, 41, 21, 67, 475, 127, 1113, 1693, 3705, 1051, 0 }; - static ulong[] dim1193JoeKuoD6Init = { 1, 3, 7, 3, 13, 7, 33, 95, 123, 65, 2039, 1011, 5175, 10459, 0 }; - static ulong[] dim1194JoeKuoD6Init = { 1, 1, 7, 9, 29, 53, 113, 57, 323, 309, 501, 3971, 5999, 16335, 0 }; - static ulong[] dim1195JoeKuoD6Init = { 1, 1, 1, 13, 29, 9, 17, 49, 173, 473, 555, 3753, 7471, 10099, 0 }; - static ulong[] dim1196JoeKuoD6Init = { 1, 3, 3, 3, 23, 3, 101, 199, 351, 435, 1919, 1175, 8037, 2259, 0 }; - static ulong[] dim1197JoeKuoD6Init = { 1, 3, 1, 7, 29, 27, 23, 61, 197, 883, 153, 683, 2109, 14991, 0 }; - static ulong[] dim1198JoeKuoD6Init = { 1, 1, 5, 11, 15, 21, 23, 9, 341, 391, 1537, 3483, 4641, 12489, 0 }; - static ulong[] dim1199JoeKuoD6Init = { 1, 3, 7, 1, 1, 9, 3, 7, 485, 377, 597, 2277, 7811, 1303, 0 }; - static ulong[] dim1200JoeKuoD6Init = { 1, 3, 3, 9, 13, 23, 13, 1, 353, 517, 1787, 2095, 3095, 4999, 0 }; - static ulong[] dim1201JoeKuoD6Init = { 1, 3, 5, 13, 17, 13, 55, 165, 487, 387, 839, 2867, 3939, 7945, 0 }; - static ulong[] dim1202JoeKuoD6Init = { 1, 3, 5, 3, 15, 25, 103, 225, 275, 571, 441, 567, 4759, 12965, 0 }; - static ulong[] dim1203JoeKuoD6Init = { 1, 1, 3, 5, 19, 31, 121, 109, 89, 315, 1517, 187, 1645, 2331, 0 }; - static ulong[] dim1204JoeKuoD6Init = { 1, 1, 7, 3, 17, 49, 87, 241, 491, 99, 1559, 843, 5627, 2383, 0 }; - static ulong[] dim1205JoeKuoD6Init = { 1, 3, 7, 7, 21, 55, 69, 27, 461, 663, 1609, 4059, 4097, 2299, 0 }; - static ulong[] dim1206JoeKuoD6Init = { 1, 1, 1, 13, 1, 27, 35, 63, 125, 293, 721, 1433, 4813, 15439, 0 }; - static ulong[] dim1207JoeKuoD6Init = { 1, 1, 1, 15, 19, 13, 65, 55, 101, 981, 989, 3501, 8125, 8849, 0 }; - static ulong[] dim1208JoeKuoD6Init = { 1, 1, 5, 13, 25, 45, 23, 157, 165, 581, 1613, 3721, 7569, 9347, 0 }; - static ulong[] dim1209JoeKuoD6Init = { 1, 1, 1, 5, 29, 47, 51, 43, 221, 809, 469, 2089, 2721, 3799, 0 }; - static ulong[] dim1210JoeKuoD6Init = { 1, 3, 7, 9, 11, 63, 107, 33, 433, 381, 819, 739, 7861, 12219, 0 }; - static ulong[] dim1211JoeKuoD6Init = { 1, 3, 5, 7, 29, 27, 105, 219, 227, 851, 1287, 1825, 1861, 8171, 0 }; - static ulong[] dim1212JoeKuoD6Init = { 1, 3, 1, 11, 1, 31, 77, 183, 81, 781, 541, 1663, 3, 12533, 0 }; - static ulong[] dim1213JoeKuoD6Init = { 1, 3, 3, 1, 7, 59, 107, 49, 147, 625, 593, 729, 4335, 12651, 0 }; - static ulong[] dim1214JoeKuoD6Init = { 1, 3, 1, 11, 25, 45, 55, 117, 247, 499, 1403, 3321, 6769, 15183, 0 }; - static ulong[] dim1215JoeKuoD6Init = { 1, 1, 3, 13, 15, 51, 41, 111, 297, 283, 1943, 2741, 5087, 12203, 0 }; - static ulong[] dim1216JoeKuoD6Init = { 1, 3, 1, 13, 19, 37, 59, 149, 481, 211, 69, 1253, 8019, 10607, 0 }; - static ulong[] dim1217JoeKuoD6Init = { 1, 3, 1, 1, 21, 61, 103, 93, 75, 91, 1695, 3683, 679, 14789, 0 }; - static ulong[] dim1218JoeKuoD6Init = { 1, 3, 1, 3, 27, 19, 101, 215, 165, 887, 1647, 4033, 7709, 15581, 0 }; - static ulong[] dim1219JoeKuoD6Init = { 1, 1, 1, 9, 17, 9, 15, 231, 335, 227, 661, 2505, 6525, 15019, 0 }; - static ulong[] dim1220JoeKuoD6Init = { 1, 3, 3, 13, 15, 63, 81, 221, 117, 893, 875, 485, 7323, 11105, 0 }; - static ulong[] dim1221JoeKuoD6Init = { 1, 3, 1, 3, 7, 57, 115, 159, 457, 235, 1245, 973, 7801, 4753, 0 }; - static ulong[] dim1222JoeKuoD6Init = { 1, 3, 5, 7, 7, 21, 3, 49, 455, 733, 323, 261, 7809, 4699, 0 }; - static ulong[] dim1223JoeKuoD6Init = { 1, 1, 7, 3, 17, 31, 15, 105, 81, 901, 1107, 2161, 6631, 14523, 0 }; - static ulong[] dim1224JoeKuoD6Init = { 1, 1, 7, 15, 21, 51, 125, 227, 321, 665, 13, 3203, 6117, 15401, 0 }; - static ulong[] dim1225JoeKuoD6Init = { 1, 1, 5, 11, 23, 23, 27, 31, 489, 625, 1973, 2005, 7097, 11557, 0 }; - static ulong[] dim1226JoeKuoD6Init = { 1, 1, 7, 11, 27, 37, 41, 79, 373, 207, 1399, 2629, 953, 8649, 0 }; - static ulong[] dim1227JoeKuoD6Init = { 1, 1, 5, 5, 27, 15, 73, 37, 277, 301, 207, 2283, 2787, 8475, 0 }; - static ulong[] dim1228JoeKuoD6Init = { 1, 3, 5, 11, 7, 47, 3, 169, 201, 573, 1953, 915, 4509, 7767, 0 }; - static ulong[] dim1229JoeKuoD6Init = { 1, 3, 3, 7, 21, 21, 97, 69, 501, 491, 1471, 657, 5661, 2315, 0 }; - static ulong[] dim1230JoeKuoD6Init = { 1, 1, 1, 1, 21, 17, 127, 207, 255, 357, 59, 1035, 4497, 7397, 0 }; - static ulong[] dim1231JoeKuoD6Init = { 1, 3, 7, 1, 17, 55, 71, 35, 85, 5, 507, 1445, 2201, 14137, 0 }; - static ulong[] dim1232JoeKuoD6Init = { 1, 1, 1, 9, 23, 11, 21, 67, 347, 845, 443, 2461, 2767, 1603, 0 }; - static ulong[] dim1233JoeKuoD6Init = { 1, 3, 3, 11, 25, 11, 97, 225, 301, 111, 1163, 1783, 7879, 15191, 0 }; - static ulong[] dim1234JoeKuoD6Init = { 1, 3, 5, 11, 29, 55, 9, 137, 233, 51, 1957, 3807, 2631, 2255, 0 }; - static ulong[] dim1235JoeKuoD6Init = { 1, 1, 7, 1, 19, 41, 83, 121, 283, 839, 179, 3307, 4679, 1163, 0 }; - static ulong[] dim1236JoeKuoD6Init = { 1, 1, 3, 9, 17, 1, 11, 47, 295, 189, 1863, 1145, 367, 41, 0 }; - static ulong[] dim1237JoeKuoD6Init = { 1, 3, 1, 5, 7, 29, 85, 169, 479, 27, 1681, 917, 3983, 5041, 0 }; - static ulong[] dim1238JoeKuoD6Init = { 1, 1, 7, 15, 13, 29, 39, 131, 491, 361, 565, 271, 6255, 10815, 0 }; - static ulong[] dim1239JoeKuoD6Init = { 1, 1, 3, 3, 5, 63, 23, 201, 377, 593, 825, 339, 1065, 8989, 0 }; - static ulong[] dim1240JoeKuoD6Init = { 1, 3, 1, 1, 19, 33, 103, 187, 327, 85, 55, 2561, 6833, 3889, 0 }; - static ulong[] dim1241JoeKuoD6Init = { 1, 1, 5, 5, 5, 7, 85, 103, 463, 279, 47, 2479, 2149, 1421, 0 }; - static ulong[] dim1242JoeKuoD6Init = { 1, 1, 3, 13, 17, 31, 61, 247, 59, 869, 1513, 2405, 2129, 15647, 0 }; - static ulong[] dim1243JoeKuoD6Init = { 1, 1, 3, 13, 7, 31, 99, 63, 289, 123, 617, 3263, 6445, 14101, 0 }; - static ulong[] dim1244JoeKuoD6Init = { 1, 3, 7, 5, 13, 23, 107, 73, 19, 595, 1623, 1583, 15, 10907, 0 }; - static ulong[] dim1245JoeKuoD6Init = { 1, 1, 5, 15, 19, 33, 113, 45, 435, 99, 1909, 3317, 1733, 3629, 0 }; - static ulong[] dim1246JoeKuoD6Init = { 1, 1, 7, 13, 3, 9, 107, 59, 69, 781, 1861, 393, 7143, 4465, 0 }; - static ulong[] dim1247JoeKuoD6Init = { 1, 3, 5, 3, 23, 49, 3, 173, 483, 353, 783, 717, 2903, 11101, 0 }; - static ulong[] dim1248JoeKuoD6Init = { 1, 3, 7, 15, 27, 25, 105, 47, 387, 103, 323, 455, 1607, 3673, 0 }; - static ulong[] dim1249JoeKuoD6Init = { 1, 1, 7, 5, 19, 49, 59, 159, 5, 595, 75, 1963, 313, 5593, 0 }; - static ulong[] dim1250JoeKuoD6Init = { 1, 3, 3, 15, 27, 35, 51, 135, 347, 375, 493, 589, 507, 4661, 0 }; - static ulong[] dim1251JoeKuoD6Init = { 1, 1, 1, 5, 5, 59, 103, 249, 473, 503, 1401, 3219, 4337, 3607, 0 }; - static ulong[] dim1252JoeKuoD6Init = { 1, 3, 1, 15, 29, 15, 123, 165, 55, 515, 1009, 3231, 3567, 7871, 0 }; - static ulong[] dim1253JoeKuoD6Init = { 1, 3, 5, 7, 5, 11, 45, 87, 67, 359, 43, 457, 6483, 5165, 0 }; - static ulong[] dim1254JoeKuoD6Init = { 1, 1, 1, 15, 13, 55, 85, 51, 127, 937, 1505, 1445, 889, 789, 0 }; - static ulong[] dim1255JoeKuoD6Init = { 1, 1, 5, 1, 31, 27, 5, 225, 209, 291, 1047, 3417, 2899, 9691, 0 }; - static ulong[] dim1256JoeKuoD6Init = { 1, 1, 1, 5, 23, 9, 83, 201, 511, 805, 1341, 2791, 4803, 13523, 0 }; - static ulong[] dim1257JoeKuoD6Init = { 1, 3, 5, 7, 29, 29, 31, 239, 175, 1005, 1443, 2543, 6235, 15409, 0 }; - static ulong[] dim1258JoeKuoD6Init = { 1, 3, 5, 5, 31, 7, 17, 195, 15, 65, 1297, 2707, 3097, 2281, 0 }; - static ulong[] dim1259JoeKuoD6Init = { 1, 1, 3, 1, 25, 43, 57, 219, 419, 9, 1121, 593, 4403, 147, 0 }; - static ulong[] dim1260JoeKuoD6Init = { 1, 1, 3, 7, 5, 31, 27, 43, 343, 95, 1917, 2425, 4939, 2937, 0 }; - static ulong[] dim1261JoeKuoD6Init = { 1, 3, 1, 1, 31, 35, 19, 151, 339, 411, 77, 3881, 7401, 927, 0 }; - static ulong[] dim1262JoeKuoD6Init = { 1, 3, 1, 7, 3, 61, 37, 135, 159, 81, 157, 2945, 6371, 3583, 0 }; - static ulong[] dim1263JoeKuoD6Init = { 1, 1, 7, 1, 15, 27, 113, 213, 127, 141, 1431, 2163, 2527, 4027, 0 }; - static ulong[] dim1264JoeKuoD6Init = { 1, 3, 1, 13, 1, 39, 103, 187, 395, 283, 907, 3977, 5901, 6043, 0 }; - static ulong[] dim1265JoeKuoD6Init = { 1, 3, 7, 1, 31, 47, 45, 95, 53, 165, 357, 3893, 1555, 2263, 0 }; - static ulong[] dim1266JoeKuoD6Init = { 1, 1, 1, 7, 1, 57, 39, 39, 365, 193, 887, 815, 7309, 15089, 0 }; - static ulong[] dim1267JoeKuoD6Init = { 1, 1, 3, 11, 25, 61, 21, 139, 241, 167, 843, 299, 7737, 4625, 0 }; - static ulong[] dim1268JoeKuoD6Init = { 1, 3, 5, 3, 29, 49, 115, 55, 185, 157, 515, 1985, 5891, 11189, 0 }; - static ulong[] dim1269JoeKuoD6Init = { 1, 1, 1, 1, 1, 9, 41, 227, 267, 581, 5, 2677, 1231, 6989, 0 }; - static ulong[] dim1270JoeKuoD6Init = { 1, 1, 3, 5, 13, 57, 33, 211, 333, 277, 1387, 2673, 5923, 15623, 0 }; - static ulong[] dim1271JoeKuoD6Init = { 1, 1, 1, 9, 5, 57, 123, 93, 387, 975, 251, 677, 2843, 2237, 0 }; - static ulong[] dim1272JoeKuoD6Init = { 1, 1, 7, 1, 5, 15, 19, 241, 171, 713, 1761, 3363, 2707, 7629, 0 }; - static ulong[] dim1273JoeKuoD6Init = { 1, 1, 1, 13, 13, 25, 125, 233, 377, 1005, 1591, 1327, 7661, 15701, 0 }; - static ulong[] dim1274JoeKuoD6Init = { 1, 1, 5, 15, 23, 39, 77, 121, 255, 105, 1739, 3511, 2369, 2209, 0 }; - static ulong[] dim1275JoeKuoD6Init = { 1, 3, 5, 11, 5, 23, 11, 29, 501, 753, 1317, 1927, 2127, 7753, 0 }; - static ulong[] dim1276JoeKuoD6Init = { 1, 3, 1, 1, 31, 25, 45, 197, 483, 787, 721, 2227, 4237, 1985, 0 }; - static ulong[] dim1277JoeKuoD6Init = { 1, 3, 7, 7, 1, 53, 51, 235, 255, 517, 1389, 2381, 7845, 8707, 0 }; - static ulong[] dim1278JoeKuoD6Init = { 1, 1, 1, 5, 27, 9, 19, 251, 29, 211, 1665, 1181, 983, 16139, 0 }; - static ulong[] dim1279JoeKuoD6Init = { 1, 1, 5, 11, 21, 35, 39, 47, 445, 685, 773, 3563, 3339, 14855, 0 }; - static ulong[] dim1280JoeKuoD6Init = { 1, 3, 7, 7, 29, 61, 89, 203, 239, 11, 1407, 1529, 3581, 11443, 0 }; - static ulong[] dim1281JoeKuoD6Init = { 1, 3, 3, 5, 19, 21, 3, 253, 437, 755, 1409, 1449, 623, 10533, 0 }; - static ulong[] dim1282JoeKuoD6Init = { 1, 3, 3, 15, 13, 25, 65, 123, 273, 611, 1305, 2751, 5123, 1515, 0 }; - static ulong[] dim1283JoeKuoD6Init = { 1, 1, 3, 5, 13, 63, 79, 139, 253, 917, 19, 1129, 7801, 14215, 0 }; - static ulong[] dim1284JoeKuoD6Init = { 1, 1, 5, 9, 5, 21, 29, 179, 79, 803, 1163, 2481, 3537, 11015, 0 }; - static ulong[] dim1285JoeKuoD6Init = { 1, 3, 5, 1, 9, 51, 35, 241, 473, 291, 147, 3021, 2147, 4437, 0 }; - static ulong[] dim1286JoeKuoD6Init = { 1, 1, 7, 15, 7, 19, 81, 215, 205, 19, 1713, 1347, 7519, 9851, 0 }; - static ulong[] dim1287JoeKuoD6Init = { 1, 1, 7, 1, 9, 49, 35, 219, 73, 479, 559, 1619, 7891, 1221, 0 }; - static ulong[] dim1288JoeKuoD6Init = { 1, 1, 3, 1, 9, 39, 17, 67, 139, 287, 703, 3797, 4263, 10847, 0 }; - static ulong[] dim1289JoeKuoD6Init = { 1, 3, 7, 9, 23, 23, 17, 221, 185, 209, 1827, 3117, 8183, 15405, 0 }; - static ulong[] dim1290JoeKuoD6Init = { 1, 3, 5, 9, 9, 9, 95, 1, 225, 727, 1577, 3947, 7995, 2587, 0 }; - static ulong[] dim1291JoeKuoD6Init = { 1, 1, 5, 7, 5, 29, 89, 193, 427, 1009, 1123, 717, 3191, 14381, 0 }; - static ulong[] dim1292JoeKuoD6Init = { 1, 3, 1, 9, 7, 53, 57, 147, 511, 887, 501, 431, 7537, 363, 0 }; - static ulong[] dim1293JoeKuoD6Init = { 1, 1, 3, 7, 3, 21, 127, 157, 45, 773, 1973, 2577, 6057, 8153, 0 }; - static ulong[] dim1294JoeKuoD6Init = { 1, 3, 3, 9, 31, 63, 23, 47, 365, 369, 97, 1627, 831, 12769, 0 }; - static ulong[] dim1295JoeKuoD6Init = { 1, 3, 5, 9, 5, 61, 53, 131, 447, 281, 1115, 2523, 3789, 11581, 0 }; - static ulong[] dim1296JoeKuoD6Init = { 1, 1, 3, 5, 19, 39, 95, 243, 95, 601, 1385, 2523, 2973, 2759, 0 }; - static ulong[] dim1297JoeKuoD6Init = { 1, 3, 1, 15, 25, 15, 19, 133, 1, 197, 1259, 2501, 2513, 9417, 0 }; - static ulong[] dim1298JoeKuoD6Init = { 1, 1, 7, 1, 13, 49, 47, 61, 167, 971, 835, 2259, 3747, 13077, 0 }; - static ulong[] dim1299JoeKuoD6Init = { 1, 1, 5, 9, 17, 35, 33, 223, 173, 691, 855, 2743, 5383, 2017, 0 }; - static ulong[] dim1300JoeKuoD6Init = { 1, 3, 1, 5, 11, 35, 19, 255, 201, 801, 1921, 2511, 2497, 13317, 0 }; - static ulong[] dim1301JoeKuoD6Init = { 1, 1, 7, 9, 17, 1, 47, 187, 63, 641, 1395, 1591, 6145, 4549, 0 }; - static ulong[] dim1302JoeKuoD6Init = { 1, 1, 1, 1, 11, 35, 55, 167, 75, 801, 257, 2531, 1821, 11325, 0 }; - static ulong[] dim1303JoeKuoD6Init = { 1, 1, 1, 11, 21, 27, 117, 131, 167, 461, 1459, 1, 4847, 4347, 0 }; - static ulong[] dim1304JoeKuoD6Init = { 1, 1, 5, 15, 7, 19, 103, 233, 509, 397, 1147, 1325, 6173, 9643, 0 }; - static ulong[] dim1305JoeKuoD6Init = { 1, 3, 1, 11, 31, 37, 51, 43, 173, 575, 7, 3595, 5865, 7539, 0 }; - static ulong[] dim1306JoeKuoD6Init = { 1, 1, 5, 15, 17, 63, 109, 29, 325, 57, 889, 1197, 7839, 13931, 0 }; - static ulong[] dim1307JoeKuoD6Init = { 1, 1, 5, 15, 3, 19, 105, 251, 447, 451, 925, 1857, 4343, 14273, 0 }; - static ulong[] dim1308JoeKuoD6Init = { 1, 3, 1, 9, 27, 29, 97, 113, 155, 591, 1435, 2175, 4197, 10661, 0 }; - static ulong[] dim1309JoeKuoD6Init = { 1, 3, 1, 3, 9, 11, 33, 107, 187, 463, 1479, 1127, 6699, 2183, 0 }; - static ulong[] dim1310JoeKuoD6Init = { 1, 3, 3, 1, 5, 15, 73, 231, 73, 161, 525, 2265, 619, 8085, 0 }; - static ulong[] dim1311JoeKuoD6Init = { 1, 1, 1, 1, 1, 43, 7, 137, 163, 953, 775, 3839, 7377, 12321, 0 }; - static ulong[] dim1312JoeKuoD6Init = { 1, 1, 3, 3, 27, 57, 11, 131, 407, 41, 173, 2595, 5179, 1455, 0 }; - static ulong[] dim1313JoeKuoD6Init = { 1, 3, 5, 3, 31, 9, 93, 233, 61, 149, 1973, 3493, 5535, 9595, 0 }; - static ulong[] dim1314JoeKuoD6Init = { 1, 1, 5, 9, 1, 37, 13, 71, 451, 645, 51, 3663, 1917, 10641, 0 }; - static ulong[] dim1315JoeKuoD6Init = { 1, 3, 1, 11, 13, 53, 111, 71, 61, 539, 319, 1951, 6763, 751, 0 }; - static ulong[] dim1316JoeKuoD6Init = { 1, 1, 7, 1, 27, 27, 53, 189, 39, 29, 1645, 235, 7643, 15621, 0 }; - static ulong[] dim1317JoeKuoD6Init = { 1, 1, 7, 1, 13, 13, 115, 125, 109, 377, 463, 3819, 7397, 5205, 0 }; - static ulong[] dim1318JoeKuoD6Init = { 1, 1, 3, 9, 29, 59, 61, 145, 187, 875, 1571, 4035, 2861, 10897, 0 }; - static ulong[] dim1319JoeKuoD6Init = { 1, 1, 7, 1, 11, 5, 9, 19, 477, 201, 1061, 1483, 7597, 7161, 0 }; - static ulong[] dim1320JoeKuoD6Init = { 1, 3, 1, 13, 17, 35, 55, 211, 285, 161, 385, 4093, 3685, 3635, 0 }; - static ulong[] dim1321JoeKuoD6Init = { 1, 3, 1, 9, 19, 43, 95, 253, 453, 829, 857, 3913, 4949, 9057, 0 }; - static ulong[] dim1322JoeKuoD6Init = { 1, 1, 1, 13, 3, 45, 57, 185, 7, 457, 1805, 3947, 1515, 4863, 0 }; - static ulong[] dim1323JoeKuoD6Init = { 1, 1, 5, 1, 9, 27, 75, 243, 401, 593, 1669, 3315, 3023, 14677, 0 }; - static ulong[] dim1324JoeKuoD6Init = { 1, 1, 3, 13, 29, 57, 37, 11, 153, 255, 1039, 2067, 2033, 7927, 0 }; - static ulong[] dim1325JoeKuoD6Init = { 1, 3, 3, 13, 27, 63, 23, 73, 355, 913, 327, 43, 2095, 433, 0 }; - static ulong[] dim1326JoeKuoD6Init = { 1, 3, 3, 7, 13, 1, 61, 193, 73, 465, 1483, 1359, 7459, 6855, 0 }; - static ulong[] dim1327JoeKuoD6Init = { 1, 1, 7, 3, 15, 39, 85, 165, 285, 713, 1455, 403, 7723, 6595, 0 }; - static ulong[] dim1328JoeKuoD6Init = { 1, 1, 3, 9, 11, 39, 67, 43, 47, 85, 1831, 1387, 1423, 12473, 0 }; - static ulong[] dim1329JoeKuoD6Init = { 1, 3, 5, 3, 23, 11, 49, 195, 207, 403, 1761, 3633, 8069, 12455, 0 }; - static ulong[] dim1330JoeKuoD6Init = { 1, 1, 3, 7, 19, 11, 27, 131, 123, 685, 931, 2433, 7133, 1997, 0 }; - static ulong[] dim1331JoeKuoD6Init = { 1, 3, 3, 7, 27, 3, 69, 77, 227, 227, 213, 1277, 6597, 8343, 0 }; - static ulong[] dim1332JoeKuoD6Init = { 1, 3, 7, 5, 13, 61, 69, 63, 59, 949, 2019, 2723, 451, 9641, 0 }; - static ulong[] dim1333JoeKuoD6Init = { 1, 1, 7, 11, 19, 29, 75, 149, 481, 583, 861, 1353, 7525, 115, 0 }; - static ulong[] dim1334JoeKuoD6Init = { 1, 3, 5, 13, 19, 3, 27, 155, 81, 907, 683, 1997, 189, 12139, 0 }; - static ulong[] dim1335JoeKuoD6Init = { 1, 1, 5, 9, 19, 1, 61, 97, 433, 289, 1191, 2347, 5533, 14327, 0 }; - static ulong[] dim1336JoeKuoD6Init = { 1, 3, 1, 5, 13, 9, 7, 91, 49, 75, 1839, 415, 795, 9127, 0 }; - static ulong[] dim1337JoeKuoD6Init = { 1, 1, 1, 11, 13, 11, 123, 31, 261, 159, 681, 231, 117, 14923, 0 }; - static ulong[] dim1338JoeKuoD6Init = { 1, 1, 7, 1, 21, 35, 93, 17, 251, 229, 553, 3413, 7717, 891, 0 }; - static ulong[] dim1339JoeKuoD6Init = { 1, 3, 5, 3, 7, 47, 85, 155, 63, 785, 939, 3135, 3319, 1997, 0 }; - static ulong[] dim1340JoeKuoD6Init = { 1, 3, 7, 1, 21, 19, 7, 69, 505, 327, 1015, 1821, 2583, 15031, 0 }; - static ulong[] dim1341JoeKuoD6Init = { 1, 3, 5, 15, 3, 55, 87, 111, 499, 845, 375, 2735, 6895, 291, 0 }; - static ulong[] dim1342JoeKuoD6Init = { 1, 1, 3, 3, 15, 5, 51, 105, 369, 91, 945, 3633, 7847, 13811, 0 }; - static ulong[] dim1343JoeKuoD6Init = { 1, 1, 1, 5, 21, 57, 79, 213, 225, 71, 881, 391, 4329, 2481, 0 }; - static ulong[] dim1344JoeKuoD6Init = { 1, 1, 7, 11, 19, 49, 39, 193, 271, 463, 1009, 137, 3751, 8439, 0 }; - static ulong[] dim1345JoeKuoD6Init = { 1, 3, 1, 3, 17, 37, 51, 211, 103, 929, 1323, 1175, 5465, 12229, 0 }; - static ulong[] dim1346JoeKuoD6Init = { 1, 1, 3, 9, 21, 9, 123, 221, 201, 769, 723, 2627, 2367, 13169, 0 }; - static ulong[] dim1347JoeKuoD6Init = { 1, 1, 1, 11, 31, 23, 93, 103, 257, 263, 1771, 801, 4735, 13557, 0 }; - static ulong[] dim1348JoeKuoD6Init = { 1, 3, 1, 9, 21, 29, 67, 225, 367, 909, 1333, 655, 7691, 1251, 0 }; - static ulong[] dim1349JoeKuoD6Init = { 1, 1, 3, 7, 19, 11, 75, 175, 383, 121, 1917, 2371, 4191, 16111, 0 }; - static ulong[] dim1350JoeKuoD6Init = { 1, 1, 3, 13, 17, 5, 103, 53, 173, 981, 1185, 3071, 179, 9197, 0 }; - static ulong[] dim1351JoeKuoD6Init = { 1, 1, 3, 9, 5, 41, 25, 219, 211, 291, 1735, 397, 6317, 11209, 0 }; - static ulong[] dim1352JoeKuoD6Init = { 1, 3, 7, 5, 5, 1, 11, 125, 405, 583, 773, 1711, 757, 5187, 0 }; - static ulong[] dim1353JoeKuoD6Init = { 1, 1, 1, 7, 1, 45, 127, 11, 157, 255, 1167, 3315, 5059, 8219, 0 }; - static ulong[] dim1354JoeKuoD6Init = { 1, 1, 1, 5, 15, 55, 49, 81, 451, 887, 309, 2321, 5759, 4673, 0 }; - static ulong[] dim1355JoeKuoD6Init = { 1, 1, 3, 3, 29, 51, 15, 113, 245, 77, 109, 2813, 225, 5479, 0 }; - static ulong[] dim1356JoeKuoD6Init = { 1, 1, 3, 13, 13, 43, 5, 99, 89, 559, 903, 1003, 5401, 1839, 0 }; - static ulong[] dim1357JoeKuoD6Init = { 1, 1, 1, 5, 25, 11, 3, 225, 341, 439, 521, 545, 5529, 5365, 0 }; - static ulong[] dim1358JoeKuoD6Init = { 1, 1, 7, 7, 13, 41, 41, 183, 319, 593, 1961, 2211, 7155, 1683, 0 }; - static ulong[] dim1359JoeKuoD6Init = { 1, 1, 3, 1, 9, 27, 115, 119, 289, 935, 1173, 1783, 7151, 7157, 0 }; - static ulong[] dim1360JoeKuoD6Init = { 1, 3, 3, 7, 17, 33, 31, 109, 245, 785, 1563, 999, 7989, 3493, 0 }; - static ulong[] dim1361JoeKuoD6Init = { 1, 1, 7, 7, 9, 3, 85, 91, 21, 831, 1669, 1857, 1737, 12513, 0 }; - static ulong[] dim1362JoeKuoD6Init = { 1, 3, 3, 5, 17, 51, 37, 175, 325, 581, 1809, 2669, 6179, 2187, 0 }; - static ulong[] dim1363JoeKuoD6Init = { 1, 3, 5, 9, 9, 39, 53, 87, 47, 677, 1081, 171, 4885, 2311, 0 }; - static ulong[] dim1364JoeKuoD6Init = { 1, 1, 5, 9, 29, 3, 79, 13, 433, 891, 131, 3559, 797, 3405, 0 }; - static ulong[] dim1365JoeKuoD6Init = { 1, 3, 7, 11, 25, 5, 73, 189, 251, 927, 2001, 3179, 859, 15931, 0 }; - static ulong[] dim1366JoeKuoD6Init = { 1, 1, 1, 7, 15, 61, 67, 149, 99, 795, 53, 2417, 4943, 7367, 0 }; - static ulong[] dim1367JoeKuoD6Init = { 1, 3, 1, 3, 25, 61, 79, 145, 283, 161, 887, 137, 6027, 12585, 0 }; - static ulong[] dim1368JoeKuoD6Init = { 1, 3, 3, 3, 31, 5, 117, 33, 21, 883, 117, 1609, 7219, 2511, 0 }; - static ulong[] dim1369JoeKuoD6Init = { 1, 3, 3, 13, 1, 59, 29, 177, 419, 287, 973, 3649, 3333, 9779, 0 }; - static ulong[] dim1370JoeKuoD6Init = { 1, 3, 5, 5, 11, 51, 11, 125, 237, 305, 37, 3137, 7645, 6317, 0 }; - static ulong[] dim1371JoeKuoD6Init = { 1, 1, 3, 3, 29, 39, 127, 43, 113, 437, 1501, 13, 1915, 7561, 0 }; - static ulong[] dim1372JoeKuoD6Init = { 1, 3, 5, 13, 9, 55, 7, 209, 381, 725, 1867, 637, 6335, 6057, 0 }; - static ulong[] dim1373JoeKuoD6Init = { 1, 3, 3, 5, 1, 57, 57, 45, 247, 23, 1663, 489, 2503, 9033, 0 }; - static ulong[] dim1374JoeKuoD6Init = { 1, 3, 1, 3, 23, 7, 57, 157, 291, 523, 313, 2501, 1197, 3353, 0 }; - static ulong[] dim1375JoeKuoD6Init = { 1, 3, 5, 11, 31, 13, 35, 253, 349, 393, 1531, 159, 5311, 9225, 0 }; - static ulong[] dim1376JoeKuoD6Init = { 1, 1, 7, 1, 1, 47, 75, 187, 41, 713, 1933, 2139, 2211, 7425, 0 }; - static ulong[] dim1377JoeKuoD6Init = { 1, 1, 3, 5, 7, 21, 67, 27, 303, 617, 1943, 3173, 3081, 10977, 0 }; - static ulong[] dim1378JoeKuoD6Init = { 1, 1, 7, 7, 27, 57, 103, 65, 195, 267, 1347, 3831, 5335, 435, 0 }; - static ulong[] dim1379JoeKuoD6Init = { 1, 1, 7, 13, 11, 35, 83, 21, 273, 227, 1523, 3565, 7221, 3105, 0 }; - static ulong[] dim1380JoeKuoD6Init = { 1, 1, 5, 15, 7, 29, 123, 207, 63, 535, 1355, 2751, 4791, 10285, 0 }; - static ulong[] dim1381JoeKuoD6Init = { 1, 1, 3, 5, 3, 19, 79, 91, 481, 205, 1741, 319, 4651, 12631, 0 }; - static ulong[] dim1382JoeKuoD6Init = { 1, 3, 3, 7, 25, 61, 39, 181, 377, 243, 593, 1383, 1427, 11865, 0 }; - static ulong[] dim1383JoeKuoD6Init = { 1, 1, 3, 9, 13, 13, 97, 27, 335, 973, 1857, 425, 2729, 12013, 0 }; - static ulong[] dim1384JoeKuoD6Init = { 1, 1, 5, 7, 23, 57, 99, 37, 117, 337, 751, 2471, 1105, 1415, 0 }; - static ulong[] dim1385JoeKuoD6Init = { 1, 3, 5, 1, 17, 33, 117, 87, 211, 899, 825, 1043, 4273, 9093, 0 }; - static ulong[] dim1386JoeKuoD6Init = { 1, 1, 3, 13, 11, 7, 81, 251, 421, 643, 1931, 1205, 1033, 8741, 0 }; - static ulong[] dim1387JoeKuoD6Init = { 1, 3, 7, 5, 17, 27, 113, 43, 63, 819, 503, 1427, 5787, 1133, 0 }; - static ulong[] dim1388JoeKuoD6Init = { 1, 1, 1, 13, 7, 31, 85, 123, 17, 243, 749, 1447, 6045, 729, 0 }; - static ulong[] dim1389JoeKuoD6Init = { 1, 1, 1, 3, 19, 15, 97, 49, 101, 37, 1123, 1565, 6957, 1209, 0 }; - static ulong[] dim1390JoeKuoD6Init = { 1, 3, 1, 5, 1, 39, 23, 47, 387, 727, 81, 4023, 7635, 8691, 0 }; - static ulong[] dim1391JoeKuoD6Init = { 1, 3, 7, 11, 19, 27, 71, 37, 281, 981, 1777, 1751, 7387, 8391, 0 }; - static ulong[] dim1392JoeKuoD6Init = { 1, 3, 7, 11, 21, 55, 55, 35, 205, 277, 1573, 327, 7643, 4901, 0 }; - static ulong[] dim1393JoeKuoD6Init = { 1, 1, 5, 11, 15, 45, 91, 157, 339, 489, 1871, 2841, 6839, 4067, 0 }; - static ulong[] dim1394JoeKuoD6Init = { 1, 1, 7, 3, 11, 13, 57, 193, 499, 729, 603, 2235, 6323, 16307, 0 }; - static ulong[] dim1395JoeKuoD6Init = { 1, 1, 5, 9, 13, 41, 127, 117, 115, 159, 1335, 1473, 6509, 8165, 0 }; - static ulong[] dim1396JoeKuoD6Init = { 1, 3, 7, 15, 29, 39, 57, 161, 71, 97, 1201, 649, 5863, 4765, 0 }; - static ulong[] dim1397JoeKuoD6Init = { 1, 3, 1, 1, 21, 3, 3, 129, 421, 575, 1693, 337, 7313, 4801, 0 }; - static ulong[] dim1398JoeKuoD6Init = { 1, 3, 3, 15, 27, 51, 105, 91, 51, 683, 795, 603, 7759, 251, 0 }; - static ulong[] dim1399JoeKuoD6Init = { 1, 1, 5, 7, 9, 45, 55, 199, 83, 575, 521, 2169, 5741, 1579, 0 }; - static ulong[] dim1400JoeKuoD6Init = { 1, 3, 1, 7, 13, 47, 125, 227, 45, 355, 127, 1841, 727, 8555, 0 }; - static ulong[] dim1401JoeKuoD6Init = { 1, 3, 7, 11, 27, 9, 57, 133, 393, 315, 1411, 453, 3787, 7651, 0 }; - static ulong[] dim1402JoeKuoD6Init = { 1, 1, 1, 15, 11, 35, 77, 15, 223, 1009, 291, 2645, 4585, 5839, 0 }; - static ulong[] dim1403JoeKuoD6Init = { 1, 3, 1, 7, 7, 61, 89, 55, 399, 651, 1847, 1901, 1887, 5841, 0 }; - static ulong[] dim1404JoeKuoD6Init = { 1, 3, 3, 3, 17, 29, 41, 19, 353, 475, 1193, 949, 3351, 5073, 0 }; - static ulong[] dim1405JoeKuoD6Init = { 1, 1, 1, 5, 29, 45, 37, 39, 343, 661, 1405, 229, 493, 471, 0 }; - static ulong[] dim1406JoeKuoD6Init = { 1, 3, 5, 5, 25, 27, 37, 33, 33, 139, 1537, 1125, 4331, 253, 0 }; - static ulong[] dim1407JoeKuoD6Init = { 1, 3, 3, 7, 19, 31, 111, 243, 201, 563, 1913, 2153, 749, 3521, 0 }; - static ulong[] dim1408JoeKuoD6Init = { 1, 3, 5, 1, 9, 41, 19, 163, 185, 435, 1997, 3383, 1721, 11137, 0 }; - static ulong[] dim1409JoeKuoD6Init = { 1, 3, 3, 15, 25, 1, 67, 231, 11, 197, 1431, 1697, 3337, 8791, 0 }; - static ulong[] dim1410JoeKuoD6Init = { 1, 1, 1, 1, 13, 59, 11, 199, 243, 105, 751, 811, 345, 8183, 0 }; - static ulong[] dim1411JoeKuoD6Init = { 1, 1, 3, 1, 29, 35, 123, 187, 411, 523, 989, 2545, 4969, 14489, 0 }; - static ulong[] dim1412JoeKuoD6Init = { 1, 3, 7, 5, 29, 23, 51, 83, 335, 769, 171, 1631, 1651, 10549, 0 }; - static ulong[] dim1413JoeKuoD6Init = { 1, 1, 3, 9, 13, 29, 57, 167, 113, 703, 1027, 163, 1327, 5649, 0 }; - static ulong[] dim1414JoeKuoD6Init = { 1, 3, 5, 11, 1, 47, 101, 251, 377, 421, 1825, 3153, 3425, 10447, 0 }; - static ulong[] dim1415JoeKuoD6Init = { 1, 3, 1, 1, 11, 49, 17, 215, 261, 899, 811, 3451, 3955, 791, 0 }; - static ulong[] dim1416JoeKuoD6Init = { 1, 1, 1, 11, 19, 23, 41, 239, 203, 321, 993, 1201, 5073, 8329, 0 }; - static ulong[] dim1417JoeKuoD6Init = { 1, 3, 3, 7, 23, 55, 81, 227, 379, 571, 1869, 2159, 8181, 12901, 0 }; - static ulong[] dim1418JoeKuoD6Init = { 1, 1, 7, 3, 31, 55, 13, 57, 413, 927, 873, 3649, 7167, 3985, 0 }; - static ulong[] dim1419JoeKuoD6Init = { 1, 1, 7, 1, 9, 49, 7, 41, 461, 959, 1477, 4037, 1119, 3525, 0 }; - static ulong[] dim1420JoeKuoD6Init = { 1, 3, 5, 9, 9, 31, 67, 245, 57, 395, 1035, 3005, 4211, 7155, 0 }; - static ulong[] dim1421JoeKuoD6Init = { 1, 1, 7, 9, 5, 59, 55, 7, 97, 707, 1755, 1921, 6239, 233, 0 }; - static ulong[] dim1422JoeKuoD6Init = { 1, 1, 7, 5, 11, 11, 47, 195, 197, 37, 501, 2013, 6579, 15115, 0 }; - static ulong[] dim1423JoeKuoD6Init = { 1, 1, 3, 15, 23, 61, 27, 199, 41, 479, 871, 2365, 1589, 13, 0 }; - static ulong[] dim1424JoeKuoD6Init = { 1, 1, 3, 3, 11, 9, 1, 225, 295, 403, 1065, 3039, 6025, 963, 0 }; - static ulong[] dim1425JoeKuoD6Init = { 1, 3, 7, 13, 9, 61, 29, 253, 371, 527, 1697, 571, 2865, 15967, 0 }; - static ulong[] dim1426JoeKuoD6Init = { 1, 1, 3, 1, 13, 33, 55, 67, 441, 451, 379, 1365, 2111, 6169, 0 }; - static ulong[] dim1427JoeKuoD6Init = { 1, 1, 7, 1, 23, 39, 127, 43, 205, 391, 1463, 2227, 6877, 11483, 0 }; - static ulong[] dim1428JoeKuoD6Init = { 1, 3, 3, 9, 31, 41, 5, 65, 245, 405, 633, 1379, 4111, 13129, 0 }; - static ulong[] dim1429JoeKuoD6Init = { 1, 3, 5, 1, 1, 3, 57, 179, 23, 615, 761, 2339, 8191, 1995, 0 }; - static ulong[] dim1430JoeKuoD6Init = { 1, 3, 3, 5, 11, 53, 67, 119, 169, 313, 873, 531, 63, 10827, 0 }; - static ulong[] dim1431JoeKuoD6Init = { 1, 1, 5, 7, 31, 3, 53, 139, 33, 639, 855, 43, 7895, 495, 0 }; - static ulong[] dim1432JoeKuoD6Init = { 1, 3, 3, 15, 15, 15, 13, 237, 427, 257, 1973, 2287, 7597, 13397, 0 }; - static ulong[] dim1433JoeKuoD6Init = { 1, 1, 3, 11, 31, 5, 29, 97, 99, 1003, 333, 773, 4457, 8629, 0 }; - static ulong[] dim1434JoeKuoD6Init = { 1, 1, 5, 9, 11, 55, 59, 201, 25, 559, 1647, 485, 7041, 4965, 0 }; - static ulong[] dim1435JoeKuoD6Init = { 1, 1, 3, 5, 7, 37, 117, 159, 319, 431, 341, 2497, 755, 5363, 0 }; - static ulong[] dim1436JoeKuoD6Init = { 1, 3, 5, 15, 25, 29, 99, 61, 5, 643, 1605, 2273, 3189, 5505, 0 }; - static ulong[] dim1437JoeKuoD6Init = { 1, 1, 1, 1, 29, 47, 79, 177, 473, 361, 1337, 1199, 2395, 1079, 0 }; - static ulong[] dim1438JoeKuoD6Init = { 1, 3, 5, 3, 7, 31, 101, 189, 223, 719, 1815, 1383, 7233, 11693, 0 }; - static ulong[] dim1439JoeKuoD6Init = { 1, 1, 1, 5, 29, 39, 109, 211, 485, 659, 683, 3331, 4277, 809, 0 }; - static ulong[] dim1440JoeKuoD6Init = { 1, 1, 3, 7, 23, 49, 37, 163, 127, 389, 367, 2223, 1175, 12717, 0 }; - static ulong[] dim1441JoeKuoD6Init = { 1, 3, 3, 7, 27, 27, 51, 57, 115, 941, 243, 2741, 245, 341, 0 }; - static ulong[] dim1442JoeKuoD6Init = { 1, 1, 5, 5, 15, 33, 113, 3, 267, 343, 563, 1769, 4095, 11557, 0 }; - static ulong[] dim1443JoeKuoD6Init = { 1, 3, 3, 13, 13, 11, 105, 161, 145, 125, 1509, 1459, 843, 4553, 0 }; - static ulong[] dim1444JoeKuoD6Init = { 1, 1, 1, 3, 11, 7, 67, 205, 335, 595, 1553, 2319, 6565, 14473, 0 }; - static ulong[] dim1445JoeKuoD6Init = { 1, 3, 5, 15, 23, 13, 119, 117, 263, 463, 1919, 2089, 2809, 9957, 0 }; - static ulong[] dim1446JoeKuoD6Init = { 1, 3, 7, 1, 27, 41, 5, 155, 31, 261, 1383, 1271, 2557, 6041, 0 }; - static ulong[] dim1447JoeKuoD6Init = { 1, 3, 3, 13, 13, 43, 89, 45, 443, 13, 465, 703, 3405, 6471, 0 }; - static ulong[] dim1448JoeKuoD6Init = { 1, 3, 1, 7, 31, 49, 49, 57, 97, 987, 187, 141, 7537, 11021, 0 }; - static ulong[] dim1449JoeKuoD6Init = { 1, 1, 5, 15, 29, 43, 103, 89, 113, 729, 1523, 2893, 1143, 9049, 0 }; - static ulong[] dim1450JoeKuoD6Init = { 1, 1, 3, 3, 29, 49, 43, 255, 371, 903, 661, 3355, 5981, 861, 0 }; - static ulong[] dim1451JoeKuoD6Init = { 1, 3, 7, 11, 29, 13, 75, 5, 239, 983, 733, 2949, 4635, 6789, 0 }; - static ulong[] dim1452JoeKuoD6Init = { 1, 1, 5, 3, 17, 51, 17, 49, 349, 73, 111, 897, 2757, 9817, 0 }; - static ulong[] dim1453JoeKuoD6Init = { 1, 1, 1, 9, 17, 31, 73, 125, 207, 951, 681, 3685, 893, 13725, 0 }; - static ulong[] dim1454JoeKuoD6Init = { 1, 1, 3, 1, 29, 13, 51, 181, 27, 807, 59, 3781, 263, 13865, 0 }; - static ulong[] dim1455JoeKuoD6Init = { 1, 1, 7, 5, 15, 29, 55, 159, 341, 365, 1101, 3139, 4795, 4305, 0 }; - static ulong[] dim1456JoeKuoD6Init = { 1, 3, 7, 15, 19, 35, 99, 251, 241, 115, 1197, 1167, 4663, 5523, 0 }; - static ulong[] dim1457JoeKuoD6Init = { 1, 1, 7, 5, 13, 43, 59, 251, 455, 601, 891, 2279, 3447, 7787, 0 }; - static ulong[] dim1458JoeKuoD6Init = { 1, 3, 3, 9, 31, 17, 97, 27, 373, 183, 7, 1729, 4513, 9763, 0 }; - static ulong[] dim1459JoeKuoD6Init = { 1, 1, 3, 15, 29, 15, 57, 75, 211, 551, 141, 811, 27, 15107, 0 }; - static ulong[] dim1460JoeKuoD6Init = { 1, 3, 1, 15, 31, 9, 57, 73, 431, 375, 1269, 2589, 1567, 9293, 0 }; - static ulong[] dim1461JoeKuoD6Init = { 1, 1, 3, 13, 21, 13, 41, 211, 301, 177, 1667, 3957, 6261, 3275, 0 }; - static ulong[] dim1462JoeKuoD6Init = { 1, 1, 5, 5, 15, 3, 33, 101, 119, 345, 1853, 2807, 337, 10163, 0 }; - static ulong[] dim1463JoeKuoD6Init = { 1, 3, 3, 5, 27, 61, 11, 161, 25, 159, 1775, 3039, 3807, 9373, 0 }; - static ulong[] dim1464JoeKuoD6Init = { 1, 1, 1, 15, 19, 35, 15, 191, 87, 735, 1079, 2373, 7087, 7505, 0 }; - static ulong[] dim1465JoeKuoD6Init = { 1, 1, 5, 15, 29, 37, 43, 25, 161, 925, 259, 3281, 2643, 2359, 0 }; - static ulong[] dim1466JoeKuoD6Init = { 1, 3, 1, 11, 3, 21, 13, 169, 17, 637, 1711, 1877, 6081, 5115, 0 }; - static ulong[] dim1467JoeKuoD6Init = { 1, 3, 5, 1, 25, 5, 125, 103, 277, 533, 1485, 3263, 4899, 11851, 0 }; - static ulong[] dim1468JoeKuoD6Init = { 1, 3, 7, 9, 23, 13, 61, 59, 405, 73, 817, 3831, 5059, 7671, 0 }; - static ulong[] dim1469JoeKuoD6Init = { 1, 1, 7, 3, 1, 53, 113, 135, 481, 861, 1041, 931, 2973, 7957, 0 }; - static ulong[] dim1470JoeKuoD6Init = { 1, 1, 7, 11, 9, 9, 123, 175, 65, 447, 1709, 4083, 6089, 7869, 0 }; - static ulong[] dim1471JoeKuoD6Init = { 1, 3, 7, 7, 5, 11, 43, 59, 439, 539, 283, 3221, 2631, 13025, 0 }; - static ulong[] dim1472JoeKuoD6Init = { 1, 3, 7, 7, 27, 1, 93, 51, 361, 441, 2005, 127, 6763, 12699, 0 }; - static ulong[] dim1473JoeKuoD6Init = { 1, 3, 5, 15, 27, 29, 49, 49, 115, 167, 445, 2811, 1809, 11141, 0 }; - static ulong[] dim1474JoeKuoD6Init = { 1, 1, 7, 5, 1, 57, 69, 49, 197, 459, 1613, 2891, 4437, 1621, 0 }; - static ulong[] dim1475JoeKuoD6Init = { 1, 1, 1, 5, 25, 51, 33, 47, 115, 349, 1373, 1985, 5339, 4331, 0 }; - static ulong[] dim1476JoeKuoD6Init = { 1, 3, 7, 11, 21, 55, 113, 183, 91, 955, 835, 2277, 5989, 1383, 0 }; - static ulong[] dim1477JoeKuoD6Init = { 1, 3, 5, 1, 1, 11, 113, 121, 207, 897, 125, 393, 6281, 15003, 0 }; - static ulong[] dim1478JoeKuoD6Init = { 1, 3, 7, 15, 13, 37, 89, 169, 437, 787, 1253, 2835, 4923, 15271, 0 }; - static ulong[] dim1479JoeKuoD6Init = { 1, 3, 5, 9, 23, 37, 65, 135, 271, 381, 551, 3819, 5683, 3689, 0 }; - static ulong[] dim1480JoeKuoD6Init = { 1, 1, 1, 9, 27, 29, 61, 147, 347, 745, 1793, 611, 7415, 4927, 0 }; - static ulong[] dim1481JoeKuoD6Init = { 1, 1, 3, 5, 23, 59, 35, 5, 179, 247, 1265, 2503, 1705, 10011, 0 }; - static ulong[] dim1482JoeKuoD6Init = { 1, 3, 5, 7, 11, 19, 57, 175, 93, 777, 353, 371, 6655, 10271, 0 }; - static ulong[] dim1483JoeKuoD6Init = { 1, 3, 7, 13, 15, 51, 29, 213, 113, 143, 2011, 2223, 2099, 4103, 0 }; - static ulong[] dim1484JoeKuoD6Init = { 1, 1, 7, 13, 19, 31, 75, 99, 89, 219, 2019, 1739, 3813, 5619, 0 }; - static ulong[] dim1485JoeKuoD6Init = { 1, 1, 3, 7, 27, 53, 69, 215, 299, 401, 719, 3123, 3463, 13967, 0 }; - static ulong[] dim1486JoeKuoD6Init = { 1, 3, 5, 3, 29, 63, 5, 247, 21, 651, 879, 3033, 117, 11511, 0 }; - static ulong[] dim1487JoeKuoD6Init = { 1, 1, 5, 1, 5, 47, 63, 45, 145, 905, 885, 2367, 6721, 3869, 0 }; - static ulong[] dim1488JoeKuoD6Init = { 1, 1, 3, 3, 25, 13, 117, 17, 367, 425, 367, 2863, 3087, 9115, 0 }; - static ulong[] dim1489JoeKuoD6Init = { 1, 3, 5, 1, 1, 31, 13, 65, 255, 873, 831, 3439, 7459, 7713, 0 }; - static ulong[] dim1490JoeKuoD6Init = { 1, 1, 7, 11, 19, 53, 93, 33, 505, 1007, 1331, 2317, 2817, 2549, 0 }; - static ulong[] dim1491JoeKuoD6Init = { 1, 1, 1, 11, 9, 1, 67, 109, 397, 831, 1371, 3277, 151, 6523, 0 }; - static ulong[] dim1492JoeKuoD6Init = { 1, 3, 1, 3, 25, 11, 35, 233, 231, 89, 1029, 1053, 6579, 455, 0 }; - static ulong[] dim1493JoeKuoD6Init = { 1, 1, 5, 13, 11, 7, 117, 203, 125, 863, 1927, 2081, 1229, 6373, 0 }; - static ulong[] dim1494JoeKuoD6Init = { 1, 1, 1, 7, 23, 53, 27, 207, 189, 287, 635, 3483, 4551, 15085, 0 }; - static ulong[] dim1495JoeKuoD6Init = { 1, 1, 3, 3, 23, 45, 99, 177, 59, 835, 1123, 3397, 4237, 11895, 0 }; - static ulong[] dim1496JoeKuoD6Init = { 1, 1, 7, 3, 31, 59, 37, 7, 387, 849, 1857, 3469, 3663, 1465, 0 }; - static ulong[] dim1497JoeKuoD6Init = { 1, 1, 5, 9, 13, 7, 73, 211, 83, 831, 1069, 3103, 2355, 8817, 0 }; - static ulong[] dim1498JoeKuoD6Init = { 1, 3, 7, 1, 1, 7, 63, 195, 69, 945, 39, 1417, 879, 9223, 0 }; - static ulong[] dim1499JoeKuoD6Init = { 1, 1, 7, 9, 3, 53, 111, 41, 29, 597, 1667, 3903, 7401, 6939, 0 }; - static ulong[] dim1500JoeKuoD6Init = { 1, 3, 5, 7, 9, 35, 55, 61, 509, 729, 25, 2357, 3607, 2215, 0 }; - static ulong[] dim1501JoeKuoD6Init = { 1, 3, 7, 7, 19, 49, 47, 241, 79, 363, 1987, 3269, 5161, 1379, 0 }; - static ulong[] dim1502JoeKuoD6Init = { 1, 3, 5, 5, 1, 33, 21, 249, 321, 281, 2025, 425, 4955, 5799, 0 }; - static ulong[] dim1503JoeKuoD6Init = { 1, 1, 7, 5, 19, 21, 93, 69, 487, 619, 839, 1359, 3219, 8303, 0 }; - static ulong[] dim1504JoeKuoD6Init = { 1, 3, 5, 15, 27, 33, 3, 55, 149, 361, 887, 1341, 1219, 4769, 0 }; - static ulong[] dim1505JoeKuoD6Init = { 1, 1, 1, 15, 5, 13, 65, 53, 181, 923, 1643, 3853, 3067, 4281, 0 }; - static ulong[] dim1506JoeKuoD6Init = { 1, 1, 1, 1, 13, 5, 23, 27, 211, 377, 1421, 3085, 509, 509, 0 }; - static ulong[] dim1507JoeKuoD6Init = { 1, 1, 7, 9, 21, 13, 3, 193, 19, 497, 1989, 885, 1157, 7213, 0 }; - static ulong[] dim1508JoeKuoD6Init = { 1, 3, 7, 11, 1, 5, 105, 57, 245, 25, 153, 795, 3781, 11735, 0 }; - static ulong[] dim1509JoeKuoD6Init = { 1, 1, 1, 13, 5, 7, 87, 63, 81, 491, 971, 805, 2349, 15627, 0 }; - static ulong[] dim1510JoeKuoD6Init = { 1, 1, 5, 1, 27, 41, 31, 165, 383, 85, 1713, 2427, 5329, 15169, 0 }; - static ulong[] dim1511JoeKuoD6Init = { 1, 1, 5, 7, 9, 47, 75, 51, 329, 651, 481, 2469, 1761, 1367, 0 }; - static ulong[] dim1512JoeKuoD6Init = { 1, 1, 1, 11, 13, 51, 89, 163, 431, 117, 1909, 2685, 7197, 1537, 0 }; - static ulong[] dim1513JoeKuoD6Init = { 1, 1, 1, 15, 29, 47, 19, 231, 35, 597, 997, 105, 7701, 899, 0 }; - static ulong[] dim1514JoeKuoD6Init = { 1, 3, 7, 15, 5, 19, 63, 87, 49, 685, 525, 3709, 4461, 15697, 0 }; - static ulong[] dim1515JoeKuoD6Init = { 1, 3, 1, 13, 31, 63, 65, 91, 169, 857, 1143, 2831, 7307, 11755, 0 }; - static ulong[] dim1516JoeKuoD6Init = { 1, 3, 1, 13, 27, 61, 105, 191, 325, 71, 1155, 2291, 8023, 1281, 0 }; - static ulong[] dim1517JoeKuoD6Init = { 1, 1, 3, 11, 21, 45, 45, 19, 453, 527, 75, 3489, 3011, 12687, 0 }; - static ulong[] dim1518JoeKuoD6Init = { 1, 1, 5, 7, 23, 15, 27, 105, 335, 549, 737, 3671, 5071, 10957, 0 }; - static ulong[] dim1519JoeKuoD6Init = { 1, 1, 7, 9, 9, 13, 121, 169, 87, 871, 917, 3071, 7817, 14493, 0 }; - static ulong[] dim1520JoeKuoD6Init = { 1, 1, 3, 9, 3, 1, 63, 195, 67, 123, 175, 3779, 2681, 15967, 0 }; - static ulong[] dim1521JoeKuoD6Init = { 1, 3, 7, 9, 11, 31, 111, 147, 203, 205, 1591, 3003, 631, 15567, 0 }; - static ulong[] dim1522JoeKuoD6Init = { 1, 1, 3, 5, 23, 11, 43, 117, 37, 413, 1657, 4061, 5491, 10329, 0 }; - static ulong[] dim1523JoeKuoD6Init = { 1, 1, 1, 11, 31, 35, 107, 105, 107, 117, 2041, 1415, 2153, 9063, 0 }; - static ulong[] dim1524JoeKuoD6Init = { 1, 3, 5, 13, 9, 35, 77, 1, 343, 341, 1841, 2963, 1105, 4103, 0 }; - static ulong[] dim1525JoeKuoD6Init = { 1, 1, 7, 3, 25, 21, 45, 63, 429, 843, 585, 741, 6641, 6327, 0 }; - static ulong[] dim1526JoeKuoD6Init = { 1, 1, 1, 5, 19, 23, 3, 63, 273, 1009, 131, 3541, 3769, 13045, 0 }; - static ulong[] dim1527JoeKuoD6Init = { 1, 3, 5, 15, 11, 41, 127, 139, 105, 15, 1311, 2995, 3151, 12913, 0 }; - static ulong[] dim1528JoeKuoD6Init = { 1, 3, 1, 3, 1, 37, 71, 55, 17, 155, 397, 121, 2917, 3943, 0 }; - static ulong[] dim1529JoeKuoD6Init = { 1, 3, 7, 11, 5, 1, 23, 29, 233, 947, 893, 269, 6487, 13831, 0 }; - static ulong[] dim1530JoeKuoD6Init = { 1, 3, 1, 5, 7, 17, 63, 177, 153, 595, 1217, 2225, 5973, 15853, 0 }; - static ulong[] dim1531JoeKuoD6Init = { 1, 3, 7, 9, 19, 9, 45, 197, 285, 85, 1533, 673, 5969, 501, 0 }; - static ulong[] dim1532JoeKuoD6Init = { 1, 3, 5, 15, 15, 23, 123, 151, 49, 583, 385, 3671, 3617, 16285, 0 }; - static ulong[] dim1533JoeKuoD6Init = { 1, 3, 7, 13, 11, 55, 111, 57, 51, 249, 13, 1929, 4711, 9847, 0 }; - static ulong[] dim1534JoeKuoD6Init = { 1, 1, 1, 3, 17, 13, 101, 117, 433, 327, 151, 2137, 4885, 12775, 0 }; - static ulong[] dim1535JoeKuoD6Init = { 1, 3, 3, 11, 13, 39, 113, 35, 99, 985, 765, 1239, 1311, 4591, 0 }; - static ulong[] dim1536JoeKuoD6Init = { 1, 1, 1, 11, 11, 31, 41, 205, 339, 773, 1291, 1665, 4345, 4139, 0 }; - static ulong[] dim1537JoeKuoD6Init = { 1, 1, 1, 1, 27, 41, 27, 139, 109, 555, 691, 2263, 5321, 12865, 0 }; - static ulong[] dim1538JoeKuoD6Init = { 1, 1, 3, 11, 23, 13, 41, 73, 253, 481, 1345, 3339, 1121, 665, 0 }; - static ulong[] dim1539JoeKuoD6Init = { 1, 1, 7, 7, 23, 57, 109, 161, 35, 911, 411, 3117, 5997, 6843, 0 }; - static ulong[] dim1540JoeKuoD6Init = { 1, 3, 7, 13, 3, 39, 97, 85, 399, 733, 43, 2437, 2755, 10693, 0 }; - static ulong[] dim1541JoeKuoD6Init = { 1, 3, 5, 15, 15, 47, 121, 157, 379, 805, 1483, 4013, 79, 10943, 0 }; - static ulong[] dim1542JoeKuoD6Init = { 1, 1, 3, 3, 23, 51, 39, 61, 157, 139, 273, 2385, 2451, 12437, 0 }; - static ulong[] dim1543JoeKuoD6Init = { 1, 1, 5, 1, 21, 7, 77, 197, 469, 391, 1665, 1241, 1847, 14129, 0 }; - static ulong[] dim1544JoeKuoD6Init = { 1, 1, 5, 5, 27, 23, 83, 245, 319, 247, 1345, 1229, 1119, 5749, 0 }; - static ulong[] dim1545JoeKuoD6Init = { 1, 1, 5, 3, 31, 63, 121, 245, 371, 359, 1929, 817, 2603, 5135, 0 }; - static ulong[] dim1546JoeKuoD6Init = { 1, 3, 1, 15, 21, 17, 15, 11, 425, 115, 1773, 1491, 2295, 11883, 0 }; - static ulong[] dim1547JoeKuoD6Init = { 1, 1, 5, 1, 7, 21, 91, 203, 435, 119, 819, 707, 3567, 517, 0 }; - static ulong[] dim1548JoeKuoD6Init = { 1, 1, 5, 3, 7, 7, 101, 41, 475, 539, 1059, 2245, 6731, 6635, 0 }; - static ulong[] dim1549JoeKuoD6Init = { 1, 3, 5, 1, 11, 25, 91, 89, 193, 463, 1667, 661, 801, 7087, 0 }; - static ulong[] dim1550JoeKuoD6Init = { 1, 3, 7, 15, 1, 43, 17, 97, 129, 843, 1319, 723, 2725, 10743, 0 }; - static ulong[] dim1551JoeKuoD6Init = { 1, 1, 3, 11, 19, 27, 119, 113, 85, 385, 1841, 2821, 2867, 6199, 0 }; - static ulong[] dim1552JoeKuoD6Init = { 1, 1, 7, 1, 23, 27, 95, 175, 99, 839, 1039, 735, 6355, 1651, 0 }; - static ulong[] dim1553JoeKuoD6Init = { 1, 3, 3, 1, 11, 13, 71, 91, 7, 959, 979, 2571, 117, 11479, 0 }; - static ulong[] dim1554JoeKuoD6Init = { 1, 1, 7, 11, 21, 45, 113, 205, 107, 881, 2039, 3181, 4125, 13801, 0 }; - static ulong[] dim1555JoeKuoD6Init = { 1, 1, 1, 13, 3, 63, 123, 53, 427, 469, 685, 3685, 1019, 7069, 0 }; - static ulong[] dim1556JoeKuoD6Init = { 1, 1, 1, 13, 31, 33, 39, 155, 19, 975, 659, 11, 6873, 10105, 0 }; - static ulong[] dim1557JoeKuoD6Init = { 1, 3, 5, 3, 31, 33, 91, 3, 207, 63, 559, 3745, 637, 6869, 0 }; - static ulong[] dim1558JoeKuoD6Init = { 1, 3, 1, 11, 1, 11, 41, 51, 439, 273, 1977, 2987, 5265, 11779, 0 }; - static ulong[] dim1559JoeKuoD6Init = { 1, 1, 5, 7, 13, 63, 111, 125, 65, 1003, 2045, 1823, 6799, 2847, 0 }; - static ulong[] dim1560JoeKuoD6Init = { 1, 1, 1, 1, 11, 9, 59, 187, 431, 773, 1817, 2891, 2927, 1145, 0 }; - static ulong[] dim1561JoeKuoD6Init = { 1, 1, 1, 15, 25, 19, 101, 231, 371, 857, 261, 1901, 2165, 7275, 0 }; - static ulong[] dim1562JoeKuoD6Init = { 1, 3, 1, 15, 31, 57, 125, 77, 447, 417, 1503, 3003, 7229, 14275, 0 }; - static ulong[] dim1563JoeKuoD6Init = { 1, 1, 1, 11, 23, 63, 17, 251, 237, 755, 641, 1875, 1537, 2465, 0 }; - static ulong[] dim1564JoeKuoD6Init = { 1, 3, 7, 3, 25, 59, 45, 97, 173, 179, 421, 1269, 2933, 337, 0 }; - static ulong[] dim1565JoeKuoD6Init = { 1, 3, 5, 5, 15, 25, 81, 191, 475, 723, 107, 277, 681, 15147, 0 }; - static ulong[] dim1566JoeKuoD6Init = { 1, 1, 5, 15, 3, 17, 65, 39, 281, 831, 85, 1445, 4779, 5559, 0 }; - static ulong[] dim1567JoeKuoD6Init = { 1, 3, 1, 13, 21, 1, 7, 5, 141, 65, 745, 1389, 1935, 9317, 0 }; - static ulong[] dim1568JoeKuoD6Init = { 1, 1, 5, 11, 27, 31, 33, 27, 185, 625, 1723, 3499, 6225, 7993, 0 }; - static ulong[] dim1569JoeKuoD6Init = { 1, 1, 5, 7, 5, 51, 19, 27, 301, 845, 949, 1963, 7201, 5399, 0 }; - static ulong[] dim1570JoeKuoD6Init = { 1, 3, 3, 9, 1, 59, 113, 87, 237, 83, 815, 161, 1685, 1155, 0 }; - static ulong[] dim1571JoeKuoD6Init = { 1, 3, 3, 15, 3, 47, 105, 77, 343, 997, 647, 3051, 4877, 11519, 0 }; - static ulong[] dim1572JoeKuoD6Init = { 1, 1, 5, 7, 15, 13, 123, 253, 343, 701, 1231, 3997, 3203, 7411, 0 }; - static ulong[] dim1573JoeKuoD6Init = { 1, 3, 3, 7, 21, 53, 103, 49, 511, 535, 1159, 747, 4859, 2733, 0 }; - static ulong[] dim1574JoeKuoD6Init = { 1, 3, 3, 13, 19, 13, 113, 93, 61, 1007, 219, 3817, 4819, 9959, 0 }; - static ulong[] dim1575JoeKuoD6Init = { 1, 3, 1, 7, 1, 57, 45, 167, 209, 757, 1861, 1863, 3495, 4295, 0 }; - static ulong[] dim1576JoeKuoD6Init = { 1, 1, 3, 13, 25, 53, 63, 187, 27, 663, 1697, 2477, 1685, 6609, 0 }; - static ulong[] dim1577JoeKuoD6Init = { 1, 3, 7, 1, 19, 51, 91, 125, 275, 737, 61, 685, 5739, 12795, 0 }; - static ulong[] dim1578JoeKuoD6Init = { 1, 1, 7, 15, 1, 63, 21, 253, 247, 399, 1207, 3357, 1029, 4719, 0 }; - static ulong[] dim1579JoeKuoD6Init = { 1, 1, 5, 13, 21, 1, 45, 223, 511, 963, 1099, 2913, 7385, 13903, 0 }; - static ulong[] dim1580JoeKuoD6Init = { 1, 3, 7, 7, 1, 33, 123, 81, 431, 947, 1821, 3763, 1679, 2391, 0 }; - static ulong[] dim1581JoeKuoD6Init = { 1, 1, 5, 1, 9, 9, 9, 55, 425, 539, 221, 409, 4967, 8239, 0 }; - static ulong[] dim1582JoeKuoD6Init = { 1, 3, 7, 11, 19, 5, 97, 77, 95, 955, 705, 3627, 3743, 8687, 0 }; - static ulong[] dim1583JoeKuoD6Init = { 1, 3, 1, 11, 27, 51, 37, 177, 109, 343, 35, 1361, 1557, 13487, 0 }; - static ulong[] dim1584JoeKuoD6Init = { 1, 1, 1, 11, 19, 25, 93, 155, 421, 765, 1529, 2685, 2729, 4763, 0 }; - static ulong[] dim1585JoeKuoD6Init = { 1, 3, 3, 11, 7, 21, 99, 179, 205, 473, 1435, 711, 6975, 10497, 0 }; - static ulong[] dim1586JoeKuoD6Init = { 1, 1, 5, 3, 1, 55, 29, 113, 201, 123, 201, 2749, 75, 5839, 0 }; - static ulong[] dim1587JoeKuoD6Init = { 1, 3, 1, 9, 13, 9, 19, 55, 57, 99, 811, 3143, 5143, 5149, 0 }; - static ulong[] dim1588JoeKuoD6Init = { 1, 3, 5, 1, 5, 49, 89, 229, 351, 93, 951, 3587, 6819, 119, 0 }; - static ulong[] dim1589JoeKuoD6Init = { 1, 1, 5, 5, 17, 1, 95, 129, 79, 165, 209, 2859, 4269, 7613, 0 }; - static ulong[] dim1590JoeKuoD6Init = { 1, 3, 5, 11, 3, 1, 115, 215, 215, 449, 1365, 3429, 5711, 10053, 0 }; - static ulong[] dim1591JoeKuoD6Init = { 1, 1, 1, 9, 17, 59, 11, 121, 229, 37, 781, 421, 145, 1359, 0 }; - static ulong[] dim1592JoeKuoD6Init = { 1, 1, 3, 9, 31, 31, 73, 255, 451, 337, 617, 3169, 7275, 4783, 0 }; - static ulong[] dim1593JoeKuoD6Init = { 1, 1, 7, 15, 3, 31, 17, 163, 243, 695, 1073, 2625, 6237, 4011, 0 }; - static ulong[] dim1594JoeKuoD6Init = { 1, 1, 5, 5, 27, 17, 45, 167, 363, 741, 1873, 3699, 7577, 7389, 0 }; - static ulong[] dim1595JoeKuoD6Init = { 1, 1, 7, 9, 5, 61, 43, 99, 175, 645, 1351, 1405, 2443, 15481, 0 }; - static ulong[] dim1596JoeKuoD6Init = { 1, 3, 7, 11, 7, 19, 11, 27, 481, 271, 881, 143, 1087, 7443, 0 }; - static ulong[] dim1597JoeKuoD6Init = { 1, 1, 3, 15, 11, 59, 47, 165, 421, 211, 451, 3957, 1715, 5045, 0 }; - static ulong[] dim1598JoeKuoD6Init = { 1, 1, 1, 3, 1, 55, 121, 71, 483, 79, 61, 3107, 6367, 8787, 0 }; - static ulong[] dim1599JoeKuoD6Init = { 1, 1, 5, 11, 5, 35, 7, 197, 269, 437, 1529, 1757, 8165, 10897, 0 }; - static ulong[] dim1600JoeKuoD6Init = { 1, 1, 3, 13, 25, 41, 121, 115, 177, 435, 839, 2701, 2813, 5055, 0 }; - static ulong[] dim1601JoeKuoD6Init = { 1, 1, 3, 15, 5, 57, 17, 99, 31, 415, 1391, 3077, 4317, 12963, 0 }; - static ulong[] dim1602JoeKuoD6Init = { 1, 3, 1, 7, 31, 45, 95, 97, 43, 601, 2033, 2967, 3985, 10845, 0 }; - static ulong[] dim1603JoeKuoD6Init = { 1, 3, 1, 15, 19, 55, 99, 125, 391, 339, 1277, 2669, 359, 3983, 0 }; - static ulong[] dim1604JoeKuoD6Init = { 1, 3, 7, 11, 11, 47, 79, 197, 157, 959, 777, 133, 337, 14891, 0 }; - static ulong[] dim1605JoeKuoD6Init = { 1, 1, 5, 7, 9, 3, 95, 77, 217, 399, 1269, 2505, 1055, 5483, 0 }; - static ulong[] dim1606JoeKuoD6Init = { 1, 1, 5, 3, 27, 5, 3, 109, 481, 169, 1787, 725, 2827, 13599, 0 }; - static ulong[] dim1607JoeKuoD6Init = { 1, 3, 1, 5, 7, 11, 127, 119, 141, 999, 295, 2727, 7329, 11371, 0 }; - static ulong[] dim1608JoeKuoD6Init = { 1, 3, 3, 7, 31, 17, 105, 139, 287, 333, 1149, 3373, 5165, 9555, 0 }; - static ulong[] dim1609JoeKuoD6Init = { 1, 3, 5, 5, 5, 13, 53, 25, 125, 953, 511, 3695, 7935, 10901, 0 }; - static ulong[] dim1610JoeKuoD6Init = { 1, 1, 5, 15, 5, 37, 73, 29, 471, 423, 2025, 3759, 4271, 9589, 0 }; - static ulong[] dim1611JoeKuoD6Init = { 1, 1, 1, 5, 9, 35, 105, 207, 245, 935, 801, 2115, 7935, 11439, 0 }; - static ulong[] dim1612JoeKuoD6Init = { 1, 3, 7, 15, 23, 39, 67, 187, 333, 823, 1015, 1463, 6445, 5079, 0 }; - static ulong[] dim1613JoeKuoD6Init = { 1, 1, 7, 7, 15, 43, 41, 243, 493, 703, 3, 3585, 6775, 2169, 0 }; - static ulong[] dim1614JoeKuoD6Init = { 1, 3, 7, 9, 7, 53, 29, 225, 399, 885, 1051, 665, 1447, 5913, 0 }; - static ulong[] dim1615JoeKuoD6Init = { 1, 1, 1, 7, 3, 19, 47, 219, 203, 903, 1399, 1793, 5949, 4311, 0 }; - static ulong[] dim1616JoeKuoD6Init = { 1, 1, 1, 5, 9, 9, 117, 207, 107, 651, 1155, 2047, 7489, 5959, 0 }; - static ulong[] dim1617JoeKuoD6Init = { 1, 3, 7, 9, 31, 59, 105, 73, 251, 209, 515, 3467, 721, 13423, 0 }; - static ulong[] dim1618JoeKuoD6Init = { 1, 1, 7, 13, 13, 45, 75, 171, 61, 249, 1641, 289, 201, 6185, 0 }; - static ulong[] dim1619JoeKuoD6Init = { 1, 1, 1, 11, 13, 37, 91, 225, 241, 899, 1471, 3553, 6741, 11623, 0 }; - static ulong[] dim1620JoeKuoD6Init = { 1, 3, 7, 15, 19, 61, 79, 81, 75, 343, 145, 3975, 4807, 4887, 0 }; - static ulong[] dim1621JoeKuoD6Init = { 1, 1, 3, 9, 17, 15, 29, 1, 331, 649, 1455, 2365, 6309, 6701, 0 }; - static ulong[] dim1622JoeKuoD6Init = { 1, 1, 1, 1, 15, 19, 37, 5, 417, 933, 269, 2391, 8063, 14231, 0 }; - static ulong[] dim1623JoeKuoD6Init = { 1, 1, 7, 3, 17, 49, 21, 41, 127, 507, 1927, 1971, 7057, 12047, 0 }; - static ulong[] dim1624JoeKuoD6Init = { 1, 1, 7, 15, 31, 53, 33, 225, 105, 907, 775, 3699, 439, 10087, 0 }; - static ulong[] dim1625JoeKuoD6Init = { 1, 1, 5, 3, 23, 5, 3, 19, 387, 811, 865, 2817, 3757, 12849, 0 }; - static ulong[] dim1626JoeKuoD6Init = { 1, 3, 5, 3, 3, 23, 51, 239, 489, 667, 301, 3879, 4141, 1131, 0 }; - static ulong[] dim1627JoeKuoD6Init = { 1, 3, 3, 1, 21, 59, 115, 89, 235, 1009, 1371, 2141, 2489, 763, 0 }; - static ulong[] dim1628JoeKuoD6Init = { 1, 1, 7, 1, 5, 7, 75, 83, 491, 233, 1027, 1421, 5111, 445, 0 }; - static ulong[] dim1629JoeKuoD6Init = { 1, 3, 3, 3, 19, 27, 1, 181, 193, 949, 69, 2689, 3421, 13921, 0 }; - static ulong[] dim1630JoeKuoD6Init = { 1, 3, 7, 3, 9, 35, 109, 203, 123, 217, 225, 3355, 2331, 11853, 0 }; - static ulong[] dim1631JoeKuoD6Init = { 1, 1, 5, 13, 1, 55, 41, 225, 425, 801, 353, 2851, 4403, 7885, 0 }; - static ulong[] dim1632JoeKuoD6Init = { 1, 3, 5, 11, 19, 47, 83, 17, 91, 875, 1739, 971, 8157, 11047, 0 }; - static ulong[] dim1633JoeKuoD6Init = { 1, 3, 1, 15, 29, 47, 123, 209, 183, 473, 1019, 537, 1035, 4473, 0 }; - static ulong[] dim1634JoeKuoD6Init = { 1, 3, 7, 7, 25, 9, 5, 115, 297, 411, 563, 883, 3509, 1637, 0 }; - static ulong[] dim1635JoeKuoD6Init = { 1, 1, 1, 15, 3, 17, 55, 31, 123, 931, 1239, 2137, 3673, 10325, 0 }; - static ulong[] dim1636JoeKuoD6Init = { 1, 1, 5, 1, 31, 49, 35, 51, 223, 65, 925, 2133, 3849, 2243, 0 }; - static ulong[] dim1637JoeKuoD6Init = { 1, 1, 5, 15, 1, 27, 73, 111, 237, 877, 13, 3147, 7115, 13467, 0 }; - static ulong[] dim1638JoeKuoD6Init = { 1, 3, 5, 7, 9, 53, 123, 189, 459, 383, 1259, 297, 3307, 3305, 0 }; - static ulong[] dim1639JoeKuoD6Init = { 1, 3, 5, 15, 27, 45, 65, 175, 417, 377, 195, 1419, 1013, 8419, 0 }; - static ulong[] dim1640JoeKuoD6Init = { 1, 3, 7, 3, 29, 13, 19, 37, 339, 515, 981, 335, 3965, 7577, 0 }; - static ulong[] dim1641JoeKuoD6Init = { 1, 1, 1, 5, 27, 37, 85, 217, 463, 173, 1723, 493, 6847, 12253, 0 }; - static ulong[] dim1642JoeKuoD6Init = { 1, 1, 3, 9, 19, 35, 53, 123, 365, 771, 961, 2545, 3191, 7891, 0 }; - static ulong[] dim1643JoeKuoD6Init = { 1, 3, 7, 3, 27, 47, 81, 243, 89, 79, 13, 1733, 965, 39, 0 }; - static ulong[] dim1644JoeKuoD6Init = { 1, 3, 1, 7, 21, 1, 57, 137, 211, 491, 1071, 2425, 5225, 16141, 0 }; - static ulong[] dim1645JoeKuoD6Init = { 1, 3, 7, 1, 5, 23, 57, 117, 45, 373, 831, 3047, 5829, 3205, 0 }; - static ulong[] dim1646JoeKuoD6Init = { 1, 3, 1, 7, 3, 59, 17, 171, 263, 723, 535, 3791, 4969, 4325, 0 }; - static ulong[] dim1647JoeKuoD6Init = { 1, 1, 5, 7, 19, 5, 75, 169, 231, 25, 1925, 161, 8051, 13051, 0 }; - static ulong[] dim1648JoeKuoD6Init = { 1, 1, 1, 9, 29, 5, 5, 197, 135, 713, 1895, 533, 6703, 9307, 0 }; - static ulong[] dim1649JoeKuoD6Init = { 1, 3, 7, 3, 1, 47, 69, 247, 49, 15, 1533, 3051, 8097, 4881, 0 }; - static ulong[] dim1650JoeKuoD6Init = { 1, 3, 1, 3, 21, 29, 81, 147, 123, 983, 1925, 3959, 3803, 13461, 0 }; - static ulong[] dim1651JoeKuoD6Init = { 1, 1, 5, 11, 25, 59, 99, 253, 85, 37, 1821, 93, 1813, 6001, 0 }; - static ulong[] dim1652JoeKuoD6Init = { 1, 1, 1, 15, 7, 53, 69, 129, 273, 5, 837, 441, 7573, 1803, 0 }; - static ulong[] dim1653JoeKuoD6Init = { 1, 1, 5, 15, 25, 13, 125, 113, 405, 41, 1151, 3659, 3947, 12983, 0 }; - static ulong[] dim1654JoeKuoD6Init = { 1, 1, 3, 15, 19, 1, 63, 223, 343, 523, 1857, 1273, 5251, 13665, 0 }; - static ulong[] dim1655JoeKuoD6Init = { 1, 3, 1, 9, 3, 39, 45, 161, 483, 421, 159, 3257, 7749, 4481, 0 }; - static ulong[] dim1656JoeKuoD6Init = { 1, 1, 5, 15, 13, 53, 25, 213, 179, 753, 1195, 343, 5803, 15289, 0 }; - static ulong[] dim1657JoeKuoD6Init = { 1, 1, 3, 3, 21, 41, 67, 149, 225, 103, 1567, 2681, 3731, 9779, 0 }; - static ulong[] dim1658JoeKuoD6Init = { 1, 3, 7, 3, 1, 25, 9, 185, 373, 851, 1245, 1635, 2255, 8411, 0 }; - static ulong[] dim1659JoeKuoD6Init = { 1, 1, 7, 9, 1, 39, 99, 193, 115, 763, 1079, 1923, 6111, 2327, 0 }; - static ulong[] dim1660JoeKuoD6Init = { 1, 1, 5, 13, 29, 51, 73, 91, 427, 959, 1321, 3105, 5093, 8935, 0 }; - static ulong[] dim1661JoeKuoD6Init = { 1, 3, 3, 7, 3, 37, 19, 187, 341, 907, 119, 2177, 7459, 14047, 0 }; - static ulong[] dim1662JoeKuoD6Init = { 1, 1, 7, 11, 29, 39, 95, 29, 17, 833, 1657, 2867, 4945, 6435, 0 }; - static ulong[] dim1663JoeKuoD6Init = { 1, 3, 7, 9, 15, 51, 123, 201, 161, 239, 1937, 627, 7529, 15029, 0 }; - static ulong[] dim1664JoeKuoD6Init = { 1, 1, 1, 1, 11, 57, 95, 155, 459, 157, 477, 1751, 4569, 13395, 0 }; - static ulong[] dim1665JoeKuoD6Init = { 1, 1, 1, 13, 13, 51, 1, 33, 47, 781, 1527, 2471, 7245, 8565, 0 }; - static ulong[] dim1666JoeKuoD6Init = { 1, 1, 3, 15, 1, 51, 81, 113, 317, 323, 1255, 2387, 6913, 2587, 0 }; - static ulong[] dim1667JoeKuoD6Init = { 1, 1, 5, 3, 25, 9, 73, 163, 31, 367, 477, 3427, 7957, 12235, 0 }; - static ulong[] dim1668JoeKuoD6Init = { 1, 1, 5, 15, 19, 31, 31, 93, 307, 371, 961, 3967, 4205, 12459, 0 }; - static ulong[] dim1669JoeKuoD6Init = { 1, 1, 7, 3, 7, 13, 29, 75, 31, 583, 923, 2993, 5707, 715, 0 }; - static ulong[] dim1670JoeKuoD6Init = { 1, 1, 1, 13, 21, 1, 103, 171, 469, 373, 415, 3031, 1411, 14589, 0 }; - static ulong[] dim1671JoeKuoD6Init = { 1, 1, 7, 3, 17, 11, 57, 89, 441, 709, 1339, 47, 759, 8273, 0 }; - static ulong[] dim1672JoeKuoD6Init = { 1, 3, 1, 11, 13, 61, 73, 31, 503, 619, 371, 3533, 4173, 5011, 0 }; - static ulong[] dim1673JoeKuoD6Init = { 1, 1, 3, 11, 23, 1, 79, 7, 363, 919, 495, 15, 2595, 2691, 0 }; - static ulong[] dim1674JoeKuoD6Init = { 1, 3, 1, 11, 25, 5, 57, 241, 23, 907, 43, 2895, 3697, 11003, 0 }; - static ulong[] dim1675JoeKuoD6Init = { 1, 3, 3, 1, 3, 7, 57, 133, 491, 365, 1793, 3765, 3623, 11377, 0 }; - static ulong[] dim1676JoeKuoD6Init = { 1, 3, 1, 13, 7, 37, 101, 133, 29, 689, 1997, 3011, 2321, 3139, 0 }; - static ulong[] dim1677JoeKuoD6Init = { 1, 1, 5, 13, 17, 21, 119, 253, 323, 469, 1959, 537, 675, 4933, 0 }; - static ulong[] dim1678JoeKuoD6Init = { 1, 1, 7, 11, 19, 19, 29, 7, 451, 111, 1743, 379, 5223, 3477, 0 }; - static ulong[] dim1679JoeKuoD6Init = { 1, 1, 5, 15, 31, 35, 71, 217, 185, 599, 1233, 2079, 7127, 4785, 0 }; - static ulong[] dim1680JoeKuoD6Init = { 1, 1, 7, 11, 1, 33, 41, 239, 429, 987, 1453, 81, 705, 6347, 0 }; - static ulong[] dim1681JoeKuoD6Init = { 1, 3, 7, 13, 29, 49, 107, 217, 295, 797, 563, 1917, 537, 4355, 0 }; - static ulong[] dim1682JoeKuoD6Init = { 1, 3, 1, 13, 17, 49, 27, 67, 5, 239, 53, 1759, 3235, 1321, 0 }; - static ulong[] dim1683JoeKuoD6Init = { 1, 1, 7, 13, 11, 33, 85, 47, 285, 669, 341, 3011, 287, 9693, 0 }; - static ulong[] dim1684JoeKuoD6Init = { 1, 3, 7, 7, 19, 57, 99, 97, 249, 567, 1709, 2053, 7603, 4011, 0 }; - static ulong[] dim1685JoeKuoD6Init = { 1, 1, 3, 1, 3, 55, 105, 245, 167, 785, 1409, 3395, 6503, 14809, 0 }; - static ulong[] dim1686JoeKuoD6Init = { 1, 3, 5, 13, 9, 63, 91, 49, 125, 123, 861, 1327, 5517, 3319, 0 }; - static ulong[] dim1687JoeKuoD6Init = { 1, 3, 5, 7, 3, 63, 101, 167, 403, 43, 1767, 1365, 4577, 15423, 0 }; - static ulong[] dim1688JoeKuoD6Init = { 1, 3, 3, 1, 3, 31, 81, 189, 273, 935, 1195, 3075, 4703, 7855, 0 }; - static ulong[] dim1689JoeKuoD6Init = { 1, 1, 7, 9, 11, 21, 57, 69, 405, 865, 281, 3813, 2543, 4281, 0 }; - static ulong[] dim1690JoeKuoD6Init = { 1, 3, 7, 11, 19, 49, 117, 21, 507, 481, 1961, 2893, 6627, 13545, 0 }; - static ulong[] dim1691JoeKuoD6Init = { 1, 1, 1, 5, 7, 41, 57, 39, 233, 85, 35, 539, 8009, 7223, 0 }; - static ulong[] dim1692JoeKuoD6Init = { 1, 1, 3, 11, 17, 51, 47, 219, 319, 141, 1993, 1473, 2403, 13697, 0 }; - static ulong[] dim1693JoeKuoD6Init = { 1, 1, 5, 1, 5, 61, 69, 251, 499, 813, 123, 925, 2093, 3253, 0 }; - static ulong[] dim1694JoeKuoD6Init = { 1, 1, 3, 11, 23, 19, 97, 19, 345, 127, 1571, 27, 2915, 1497, 0 }; - static ulong[] dim1695JoeKuoD6Init = { 1, 3, 5, 7, 25, 23, 41, 41, 75, 571, 527, 517, 7057, 2737, 0 }; - static ulong[] dim1696JoeKuoD6Init = { 1, 3, 7, 3, 1, 59, 27, 177, 253, 21, 2023, 3393, 3195, 879, 0 }; - static ulong[] dim1697JoeKuoD6Init = { 1, 3, 3, 9, 7, 37, 1, 185, 381, 211, 2033, 1415, 3275, 15281, 0 }; - static ulong[] dim1698JoeKuoD6Init = { 1, 1, 1, 15, 3, 49, 101, 89, 495, 683, 1945, 3017, 5209, 9879, 0 }; - static ulong[] dim1699JoeKuoD6Init = { 1, 3, 3, 7, 17, 63, 55, 243, 215, 289, 1119, 4087, 3513, 2961, 0 }; - static ulong[] dim1700JoeKuoD6Init = { 1, 1, 7, 13, 11, 49, 17, 103, 151, 725, 1433, 967, 4127, 14955, 0 }; - static ulong[] dim1701JoeKuoD6Init = { 1, 3, 5, 9, 11, 5, 69, 179, 163, 565, 245, 2013, 699, 7109, 0 }; - static ulong[] dim1702JoeKuoD6Init = { 1, 3, 7, 15, 29, 23, 39, 93, 211, 1017, 1677, 3883, 6157, 11339, 0 }; - static ulong[] dim1703JoeKuoD6Init = { 1, 1, 7, 9, 7, 15, 27, 109, 449, 165, 1785, 1945, 2095, 14831, 0 }; - static ulong[] dim1704JoeKuoD6Init = { 1, 1, 5, 13, 17, 43, 71, 49, 9, 305, 561, 2309, 6409, 2097, 0 }; - static ulong[] dim1705JoeKuoD6Init = { 1, 1, 7, 5, 9, 63, 77, 149, 119, 727, 1781, 3429, 141, 13329, 0 }; - static ulong[] dim1706JoeKuoD6Init = { 1, 1, 1, 7, 23, 27, 111, 193, 97, 727, 425, 2665, 2217, 7463, 0 }; - static ulong[] dim1707JoeKuoD6Init = { 1, 3, 3, 5, 15, 45, 85, 237, 207, 759, 1007, 2545, 7897, 10953, 0 }; - static ulong[] dim1708JoeKuoD6Init = { 1, 1, 1, 3, 7, 47, 81, 57, 369, 777, 155, 1341, 6679, 5877, 0 }; - static ulong[] dim1709JoeKuoD6Init = { 1, 1, 3, 9, 9, 31, 47, 135, 31, 275, 1779, 2537, 2157, 7347, 0 }; - static ulong[] dim1710JoeKuoD6Init = { 1, 1, 5, 9, 23, 51, 59, 107, 43, 639, 1893, 1713, 2409, 6301, 0 }; - static ulong[] dim1711JoeKuoD6Init = { 1, 3, 5, 13, 9, 13, 13, 231, 419, 373, 1071, 2903, 3565, 15075, 0 }; - static ulong[] dim1712JoeKuoD6Init = { 1, 3, 5, 5, 1, 3, 33, 123, 53, 273, 731, 2049, 4617, 12341, 0 }; - static ulong[] dim1713JoeKuoD6Init = { 1, 3, 1, 1, 17, 49, 75, 141, 499, 863, 635, 2967, 3483, 5087, 0 }; - static ulong[] dim1714JoeKuoD6Init = { 1, 3, 1, 9, 17, 7, 33, 247, 143, 73, 551, 65, 1261, 10177, 0 }; - static ulong[] dim1715JoeKuoD6Init = { 1, 3, 7, 3, 11, 13, 123, 137, 29, 175, 1353, 627, 1223, 191, 0 }; - static ulong[] dim1716JoeKuoD6Init = { 1, 3, 5, 15, 29, 23, 89, 183, 427, 629, 1747, 141, 95, 8319, 0 }; - static ulong[] dim1717JoeKuoD6Init = { 1, 1, 1, 5, 17, 45, 53, 95, 433, 523, 1175, 1227, 6893, 2081, 0 }; - static ulong[] dim1718JoeKuoD6Init = { 1, 3, 3, 15, 29, 21, 107, 117, 407, 937, 301, 1443, 6841, 5673, 0 }; - static ulong[] dim1719JoeKuoD6Init = { 1, 3, 5, 11, 15, 13, 81, 213, 259, 619, 375, 1777, 455, 8185, 0 }; - static ulong[] dim1720JoeKuoD6Init = { 1, 1, 5, 7, 13, 25, 113, 175, 31, 265, 1901, 1779, 1787, 14551, 0 }; - static ulong[] dim1721JoeKuoD6Init = { 1, 3, 1, 9, 17, 59, 41, 183, 405, 477, 133, 3993, 7217, 9373, 0 }; - static ulong[] dim1722JoeKuoD6Init = { 1, 1, 1, 13, 7, 27, 85, 133, 165, 1023, 443, 2549, 1923, 6561, 0 }; - static ulong[] dim1723JoeKuoD6Init = { 1, 3, 7, 3, 15, 51, 11, 167, 321, 37, 1299, 1953, 5365, 8423, 0 }; - static ulong[] dim1724JoeKuoD6Init = { 1, 1, 3, 1, 7, 45, 41, 219, 149, 355, 1975, 1711, 1643, 13669, 0 }; - static ulong[] dim1725JoeKuoD6Init = { 1, 1, 7, 7, 11, 9, 105, 221, 275, 845, 1651, 483, 7463, 7729, 0 }; - static ulong[] dim1726JoeKuoD6Init = { 1, 3, 3, 9, 7, 29, 81, 141, 503, 321, 2039, 405, 7503, 3751, 0 }; - static ulong[] dim1727JoeKuoD6Init = { 1, 1, 1, 7, 21, 31, 19, 71, 299, 301, 1101, 2821, 6005, 5361, 0 }; - static ulong[] dim1728JoeKuoD6Init = { 1, 1, 7, 15, 11, 61, 37, 67, 151, 175, 1815, 2779, 5507, 153, 0 }; - static ulong[] dim1729JoeKuoD6Init = { 1, 1, 5, 11, 9, 41, 83, 225, 109, 23, 563, 1021, 3523, 14027, 0 }; - static ulong[] dim1730JoeKuoD6Init = { 1, 3, 3, 7, 3, 19, 33, 251, 337, 925, 1309, 1895, 4113, 14017, 0 }; - static ulong[] dim1731JoeKuoD6Init = { 1, 3, 7, 9, 15, 57, 15, 121, 311, 929, 1697, 1877, 803, 3361, 0 }; - static ulong[] dim1732JoeKuoD6Init = { 1, 3, 5, 1, 11, 29, 19, 173, 497, 879, 249, 3111, 4227, 14681, 0 }; - static ulong[] dim1733JoeKuoD6Init = { 1, 3, 7, 13, 13, 41, 51, 99, 137, 867, 1207, 3343, 613, 15047, 0 }; - static ulong[] dim1734JoeKuoD6Init = { 1, 3, 3, 15, 11, 41, 57, 7, 203, 569, 669, 3185, 1233, 527, 0 }; - static ulong[] dim1735JoeKuoD6Init = { 1, 3, 5, 5, 27, 45, 83, 49, 335, 747, 1075, 2639, 3057, 4137, 0 }; - static ulong[] dim1736JoeKuoD6Init = { 1, 3, 7, 15, 3, 11, 9, 177, 153, 401, 61, 3689, 3853, 15605, 0 }; - static ulong[] dim1737JoeKuoD6Init = { 1, 3, 3, 7, 27, 13, 79, 51, 213, 465, 1917, 3353, 3553, 14853, 0 }; - static ulong[] dim1738JoeKuoD6Init = { 1, 3, 1, 9, 25, 27, 67, 253, 29, 635, 239, 679, 3653, 15435, 0 }; - static ulong[] dim1739JoeKuoD6Init = { 1, 1, 1, 7, 23, 9, 77, 167, 373, 295, 1423, 1895, 1541, 14563, 0 }; - static ulong[] dim1740JoeKuoD6Init = { 1, 3, 3, 1, 9, 37, 117, 223, 109, 969, 149, 1611, 3511, 11357, 0 }; - static ulong[] dim1741JoeKuoD6Init = { 1, 3, 5, 11, 19, 61, 105, 137, 113, 443, 359, 1705, 6893, 11371, 0 }; - static ulong[] dim1742JoeKuoD6Init = { 1, 3, 1, 13, 21, 11, 65, 3, 275, 311, 1157, 87, 4841, 2995, 0 }; - static ulong[] dim1743JoeKuoD6Init = { 1, 1, 7, 3, 17, 41, 15, 203, 249, 353, 861, 2519, 537, 15203, 0 }; - static ulong[] dim1744JoeKuoD6Init = { 1, 3, 3, 13, 29, 7, 87, 121, 69, 733, 1035, 2731, 8079, 7243, 0 }; - static ulong[] dim1745JoeKuoD6Init = { 1, 1, 1, 3, 13, 3, 109, 47, 161, 313, 1641, 2621, 7629, 13713, 0 }; - static ulong[] dim1746JoeKuoD6Init = { 1, 1, 3, 1, 5, 5, 85, 99, 463, 1005, 89, 1209, 8013, 14393, 0 }; - static ulong[] dim1747JoeKuoD6Init = { 1, 1, 3, 1, 27, 1, 127, 185, 193, 275, 891, 763, 3775, 2569, 0 }; - static ulong[] dim1748JoeKuoD6Init = { 1, 3, 7, 1, 7, 43, 123, 3, 131, 441, 771, 3413, 6641, 2363, 0 }; - static ulong[] dim1749JoeKuoD6Init = { 1, 3, 3, 9, 21, 39, 81, 243, 179, 765, 181, 417, 8027, 1025, 0 }; - static ulong[] dim1750JoeKuoD6Init = { 1, 1, 3, 11, 11, 37, 23, 167, 257, 103, 305, 1097, 6099, 11321, 0 }; - static ulong[] dim1751JoeKuoD6Init = { 1, 3, 1, 7, 27, 29, 71, 207, 83, 367, 1575, 3171, 759, 10981, 0 }; - static ulong[] dim1752JoeKuoD6Init = { 1, 1, 7, 1, 23, 29, 93, 89, 41, 577, 1657, 415, 655, 2501, 0 }; - static ulong[] dim1753JoeKuoD6Init = { 1, 1, 1, 11, 27, 39, 111, 139, 425, 513, 1341, 2059, 2187, 6047, 0 }; - static ulong[] dim1754JoeKuoD6Init = { 1, 1, 1, 13, 25, 55, 63, 193, 183, 429, 611, 2119, 2495, 15361, 0 }; - static ulong[] dim1755JoeKuoD6Init = { 1, 1, 1, 3, 9, 31, 15, 185, 139, 603, 1159, 2065, 1159, 14869, 0 }; - static ulong[] dim1756JoeKuoD6Init = { 1, 1, 3, 5, 21, 5, 117, 191, 357, 61, 1517, 2075, 2041, 14485, 0 }; - static ulong[] dim1757JoeKuoD6Init = { 1, 1, 3, 15, 21, 59, 13, 67, 393, 809, 1539, 3631, 5437, 7787, 0 }; - static ulong[] dim1758JoeKuoD6Init = { 1, 3, 1, 5, 23, 19, 53, 237, 123, 123, 351, 1797, 3415, 4721, 0 }; - static ulong[] dim1759JoeKuoD6Init = { 1, 1, 3, 1, 13, 39, 75, 41, 425, 557, 985, 1485, 7613, 11109, 0 }; - static ulong[] dim1760JoeKuoD6Init = { 1, 3, 1, 11, 25, 29, 23, 117, 411, 721, 21, 1707, 7685, 11979, 0 }; - static ulong[] dim1761JoeKuoD6Init = { 1, 3, 1, 5, 25, 55, 1, 221, 339, 705, 641, 515, 5883, 10709, 0 }; - static ulong[] dim1762JoeKuoD6Init = { 1, 1, 3, 9, 13, 63, 69, 121, 371, 643, 597, 1977, 1295, 10941, 0 }; - static ulong[] dim1763JoeKuoD6Init = { 1, 3, 5, 5, 21, 49, 91, 37, 53, 549, 905, 1707, 7371, 7539, 0 }; - static ulong[] dim1764JoeKuoD6Init = { 1, 1, 5, 9, 9, 43, 45, 205, 49, 1001, 1617, 2307, 3359, 5871, 0 }; - static ulong[] dim1765JoeKuoD6Init = { 1, 3, 5, 7, 7, 43, 73, 129, 381, 97, 529, 607, 2505, 5171, 0 }; - static ulong[] dim1766JoeKuoD6Init = { 1, 1, 5, 9, 3, 31, 81, 63, 185, 443, 1215, 3123, 7973, 8457, 0 }; - static ulong[] dim1767JoeKuoD6Init = { 1, 1, 5, 5, 13, 31, 59, 141, 93, 509, 149, 3039, 6011, 11489, 0 }; - static ulong[] dim1768JoeKuoD6Init = { 1, 1, 5, 5, 17, 13, 93, 221, 23, 325, 415, 829, 7611, 2183, 0 }; - static ulong[] dim1769JoeKuoD6Init = { 1, 3, 3, 3, 13, 55, 47, 77, 375, 41, 1821, 2599, 843, 13411, 0 }; - static ulong[] dim1770JoeKuoD6Init = { 1, 3, 1, 15, 17, 15, 101, 225, 47, 217, 137, 2637, 895, 10679, 0 }; - static ulong[] dim1771JoeKuoD6Init = { 1, 1, 7, 3, 27, 37, 123, 173, 83, 119, 599, 17, 89, 15621, 0 }; - static ulong[] dim1772JoeKuoD6Init = { 1, 3, 7, 11, 25, 41, 105, 43, 247, 841, 1331, 2323, 3499, 5443, 0 }; - static ulong[] dim1773JoeKuoD6Init = { 1, 1, 1, 7, 23, 49, 101, 179, 233, 463, 443, 2825, 3431, 12585, 0 }; - static ulong[] dim1774JoeKuoD6Init = { 1, 3, 7, 13, 31, 49, 115, 173, 193, 615, 663, 2167, 5655, 15331, 0 }; - static ulong[] dim1775JoeKuoD6Init = { 1, 3, 7, 1, 1, 55, 73, 145, 345, 475, 871, 3809, 5329, 15785, 0 }; - static ulong[] dim1776JoeKuoD6Init = { 1, 1, 1, 3, 7, 7, 45, 3, 9, 753, 703, 3381, 4831, 5145, 0 }; - static ulong[] dim1777JoeKuoD6Init = { 1, 3, 1, 15, 21, 51, 93, 181, 275, 127, 1743, 509, 2231, 13423, 0 }; - static ulong[] dim1778JoeKuoD6Init = { 1, 1, 3, 11, 31, 29, 33, 49, 495, 645, 49, 3139, 5281, 12193, 0 }; - static ulong[] dim1779JoeKuoD6Init = { 1, 3, 3, 3, 3, 49, 41, 31, 101, 681, 1331, 1001, 6679, 4525, 0 }; - static ulong[] dim1780JoeKuoD6Init = { 1, 3, 5, 11, 7, 51, 49, 197, 43, 419, 965, 3105, 1325, 3137, 0 }; - static ulong[] dim1781JoeKuoD6Init = { 1, 1, 5, 3, 15, 31, 73, 147, 1, 471, 1569, 3647, 7251, 6261, 0 }; - static ulong[] dim1782JoeKuoD6Init = { 1, 3, 3, 1, 5, 43, 41, 215, 161, 521, 1349, 1627, 1177, 11719, 0 }; - static ulong[] dim1783JoeKuoD6Init = { 1, 1, 3, 11, 31, 5, 125, 79, 199, 581, 1153, 2937, 7875, 16361, 0 }; - static ulong[] dim1784JoeKuoD6Init = { 1, 1, 5, 1, 1, 31, 7, 7, 475, 807, 1249, 811, 6865, 13897, 0 }; - static ulong[] dim1785JoeKuoD6Init = { 1, 3, 1, 9, 5, 7, 11, 203, 215, 669, 1963, 1255, 4785, 11215, 0 }; - static ulong[] dim1786JoeKuoD6Init = { 1, 1, 5, 13, 19, 57, 89, 133, 287, 469, 191, 3177, 1425, 14149, 0 }; - static ulong[] dim1787JoeKuoD6Init = { 1, 3, 5, 15, 9, 9, 13, 229, 477, 261, 1015, 1669, 7685, 3337, 0 }; - static ulong[] dim1788JoeKuoD6Init = { 1, 1, 1, 13, 21, 7, 117, 35, 233, 347, 1347, 2171, 2419, 11555, 0 }; - static ulong[] dim1789JoeKuoD6Init = { 1, 3, 7, 5, 17, 55, 37, 243, 159, 605, 1079, 111, 3149, 3973, 0 }; - static ulong[] dim1790JoeKuoD6Init = { 1, 3, 5, 7, 29, 29, 111, 49, 445, 241, 875, 3895, 3915, 6337, 0 }; - static ulong[] dim1791JoeKuoD6Init = { 1, 3, 1, 3, 13, 7, 21, 185, 121, 319, 1391, 1303, 3123, 7699, 0 }; - static ulong[] dim1792JoeKuoD6Init = { 1, 1, 5, 5, 3, 9, 69, 205, 423, 189, 687, 1453, 2427, 11231, 0 }; - static ulong[] dim1793JoeKuoD6Init = { 1, 3, 3, 7, 5, 31, 91, 235, 287, 185, 1439, 2011, 7429, 4313, 0 }; - static ulong[] dim1794JoeKuoD6Init = { 1, 1, 7, 1, 3, 57, 11, 11, 377, 699, 883, 221, 4849, 11373, 0 }; - static ulong[] dim1795JoeKuoD6Init = { 1, 1, 1, 11, 3, 15, 51, 79, 83, 915, 1429, 811, 2651, 829, 0 }; - static ulong[] dim1796JoeKuoD6Init = { 1, 1, 1, 5, 21, 17, 5, 227, 379, 383, 745, 2761, 323, 753, 0 }; - static ulong[] dim1797JoeKuoD6Init = { 1, 1, 3, 9, 11, 33, 123, 59, 241, 829, 879, 3339, 5315, 10777, 0 }; - static ulong[] dim1798JoeKuoD6Init = { 1, 3, 7, 13, 25, 27, 117, 5, 11, 793, 243, 2571, 369, 1371, 0 }; - static ulong[] dim1799JoeKuoD6Init = { 1, 1, 1, 3, 21, 31, 95, 217, 175, 837, 583, 1149, 8073, 12751, 0 }; - - static ulong[][] JoeKuoD6initializers = { - dim1JoeKuoD6Init, - dim2JoeKuoD6Init, - dim3JoeKuoD6Init, - dim4JoeKuoD6Init, - dim5JoeKuoD6Init, - dim6JoeKuoD6Init, - dim7JoeKuoD6Init, - dim8JoeKuoD6Init, - dim9JoeKuoD6Init, - dim10JoeKuoD6Init, - dim11JoeKuoD6Init, - dim12JoeKuoD6Init, - dim13JoeKuoD6Init, - dim14JoeKuoD6Init, - dim15JoeKuoD6Init, - dim16JoeKuoD6Init, - dim17JoeKuoD6Init, - dim18JoeKuoD6Init, - dim19JoeKuoD6Init, - dim20JoeKuoD6Init, - dim21JoeKuoD6Init, - dim22JoeKuoD6Init, - dim23JoeKuoD6Init, - dim24JoeKuoD6Init, - dim25JoeKuoD6Init, - dim26JoeKuoD6Init, - dim27JoeKuoD6Init, - dim28JoeKuoD6Init, - dim29JoeKuoD6Init, - dim30JoeKuoD6Init, - dim31JoeKuoD6Init, - dim32JoeKuoD6Init, - dim33JoeKuoD6Init, - dim34JoeKuoD6Init, - dim35JoeKuoD6Init, - dim36JoeKuoD6Init, - dim37JoeKuoD6Init, - dim38JoeKuoD6Init, - dim39JoeKuoD6Init, - dim40JoeKuoD6Init, - dim41JoeKuoD6Init, - dim42JoeKuoD6Init, - dim43JoeKuoD6Init, - dim44JoeKuoD6Init, - dim45JoeKuoD6Init, - dim46JoeKuoD6Init, - dim47JoeKuoD6Init, - dim48JoeKuoD6Init, - dim49JoeKuoD6Init, - dim50JoeKuoD6Init, - dim51JoeKuoD6Init, - dim52JoeKuoD6Init, - dim53JoeKuoD6Init, - dim54JoeKuoD6Init, - dim55JoeKuoD6Init, - dim56JoeKuoD6Init, - dim57JoeKuoD6Init, - dim58JoeKuoD6Init, - dim59JoeKuoD6Init, - dim60JoeKuoD6Init, - dim61JoeKuoD6Init, - dim62JoeKuoD6Init, - dim63JoeKuoD6Init, - dim64JoeKuoD6Init, - dim65JoeKuoD6Init, - dim66JoeKuoD6Init, - dim67JoeKuoD6Init, - dim68JoeKuoD6Init, - dim69JoeKuoD6Init, - dim70JoeKuoD6Init, - dim71JoeKuoD6Init, - dim72JoeKuoD6Init, - dim73JoeKuoD6Init, - dim74JoeKuoD6Init, - dim75JoeKuoD6Init, - dim76JoeKuoD6Init, - dim77JoeKuoD6Init, - dim78JoeKuoD6Init, - dim79JoeKuoD6Init, - dim80JoeKuoD6Init, - dim81JoeKuoD6Init, - dim82JoeKuoD6Init, - dim83JoeKuoD6Init, - dim84JoeKuoD6Init, - dim85JoeKuoD6Init, - dim86JoeKuoD6Init, - dim87JoeKuoD6Init, - dim88JoeKuoD6Init, - dim89JoeKuoD6Init, - dim90JoeKuoD6Init, - dim91JoeKuoD6Init, - dim92JoeKuoD6Init, - dim93JoeKuoD6Init, - dim94JoeKuoD6Init, - dim95JoeKuoD6Init, - dim96JoeKuoD6Init, - dim97JoeKuoD6Init, - dim98JoeKuoD6Init, - dim99JoeKuoD6Init, - dim100JoeKuoD6Init, - dim101JoeKuoD6Init, - dim102JoeKuoD6Init, - dim103JoeKuoD6Init, - dim104JoeKuoD6Init, - dim105JoeKuoD6Init, - dim106JoeKuoD6Init, - dim107JoeKuoD6Init, - dim108JoeKuoD6Init, - dim109JoeKuoD6Init, - dim110JoeKuoD6Init, - dim111JoeKuoD6Init, - dim112JoeKuoD6Init, - dim113JoeKuoD6Init, - dim114JoeKuoD6Init, - dim115JoeKuoD6Init, - dim116JoeKuoD6Init, - dim117JoeKuoD6Init, - dim118JoeKuoD6Init, - dim119JoeKuoD6Init, - dim120JoeKuoD6Init, - dim121JoeKuoD6Init, - dim122JoeKuoD6Init, - dim123JoeKuoD6Init, - dim124JoeKuoD6Init, - dim125JoeKuoD6Init, - dim126JoeKuoD6Init, - dim127JoeKuoD6Init, - dim128JoeKuoD6Init, - dim129JoeKuoD6Init, - dim130JoeKuoD6Init, - dim131JoeKuoD6Init, - dim132JoeKuoD6Init, - dim133JoeKuoD6Init, - dim134JoeKuoD6Init, - dim135JoeKuoD6Init, - dim136JoeKuoD6Init, - dim137JoeKuoD6Init, - dim138JoeKuoD6Init, - dim139JoeKuoD6Init, - dim140JoeKuoD6Init, - dim141JoeKuoD6Init, - dim142JoeKuoD6Init, - dim143JoeKuoD6Init, - dim144JoeKuoD6Init, - dim145JoeKuoD6Init, - dim146JoeKuoD6Init, - dim147JoeKuoD6Init, - dim148JoeKuoD6Init, - dim149JoeKuoD6Init, - dim150JoeKuoD6Init, - dim151JoeKuoD6Init, - dim152JoeKuoD6Init, - dim153JoeKuoD6Init, - dim154JoeKuoD6Init, - dim155JoeKuoD6Init, - dim156JoeKuoD6Init, - dim157JoeKuoD6Init, - dim158JoeKuoD6Init, - dim159JoeKuoD6Init, - dim160JoeKuoD6Init, - dim161JoeKuoD6Init, - dim162JoeKuoD6Init, - dim163JoeKuoD6Init, - dim164JoeKuoD6Init, - dim165JoeKuoD6Init, - dim166JoeKuoD6Init, - dim167JoeKuoD6Init, - dim168JoeKuoD6Init, - dim169JoeKuoD6Init, - dim170JoeKuoD6Init, - dim171JoeKuoD6Init, - dim172JoeKuoD6Init, - dim173JoeKuoD6Init, - dim174JoeKuoD6Init, - dim175JoeKuoD6Init, - dim176JoeKuoD6Init, - dim177JoeKuoD6Init, - dim178JoeKuoD6Init, - dim179JoeKuoD6Init, - dim180JoeKuoD6Init, - dim181JoeKuoD6Init, - dim182JoeKuoD6Init, - dim183JoeKuoD6Init, - dim184JoeKuoD6Init, - dim185JoeKuoD6Init, - dim186JoeKuoD6Init, - dim187JoeKuoD6Init, - dim188JoeKuoD6Init, - dim189JoeKuoD6Init, - dim190JoeKuoD6Init, - dim191JoeKuoD6Init, - dim192JoeKuoD6Init, - dim193JoeKuoD6Init, - dim194JoeKuoD6Init, - dim195JoeKuoD6Init, - dim196JoeKuoD6Init, - dim197JoeKuoD6Init, - dim198JoeKuoD6Init, - dim199JoeKuoD6Init, - dim200JoeKuoD6Init, - dim201JoeKuoD6Init, - dim202JoeKuoD6Init, - dim203JoeKuoD6Init, - dim204JoeKuoD6Init, - dim205JoeKuoD6Init, - dim206JoeKuoD6Init, - dim207JoeKuoD6Init, - dim208JoeKuoD6Init, - dim209JoeKuoD6Init, - dim210JoeKuoD6Init, - dim211JoeKuoD6Init, - dim212JoeKuoD6Init, - dim213JoeKuoD6Init, - dim214JoeKuoD6Init, - dim215JoeKuoD6Init, - dim216JoeKuoD6Init, - dim217JoeKuoD6Init, - dim218JoeKuoD6Init, - dim219JoeKuoD6Init, - dim220JoeKuoD6Init, - dim221JoeKuoD6Init, - dim222JoeKuoD6Init, - dim223JoeKuoD6Init, - dim224JoeKuoD6Init, - dim225JoeKuoD6Init, - dim226JoeKuoD6Init, - dim227JoeKuoD6Init, - dim228JoeKuoD6Init, - dim229JoeKuoD6Init, - dim230JoeKuoD6Init, - dim231JoeKuoD6Init, - dim232JoeKuoD6Init, - dim233JoeKuoD6Init, - dim234JoeKuoD6Init, - dim235JoeKuoD6Init, - dim236JoeKuoD6Init, - dim237JoeKuoD6Init, - dim238JoeKuoD6Init, - dim239JoeKuoD6Init, - dim240JoeKuoD6Init, - dim241JoeKuoD6Init, - dim242JoeKuoD6Init, - dim243JoeKuoD6Init, - dim244JoeKuoD6Init, - dim245JoeKuoD6Init, - dim246JoeKuoD6Init, - dim247JoeKuoD6Init, - dim248JoeKuoD6Init, - dim249JoeKuoD6Init, - dim250JoeKuoD6Init, - dim251JoeKuoD6Init, - dim252JoeKuoD6Init, - dim253JoeKuoD6Init, - dim254JoeKuoD6Init, - dim255JoeKuoD6Init, - dim256JoeKuoD6Init, - dim257JoeKuoD6Init, - dim258JoeKuoD6Init, - dim259JoeKuoD6Init, - dim260JoeKuoD6Init, - dim261JoeKuoD6Init, - dim262JoeKuoD6Init, - dim263JoeKuoD6Init, - dim264JoeKuoD6Init, - dim265JoeKuoD6Init, - dim266JoeKuoD6Init, - dim267JoeKuoD6Init, - dim268JoeKuoD6Init, - dim269JoeKuoD6Init, - dim270JoeKuoD6Init, - dim271JoeKuoD6Init, - dim272JoeKuoD6Init, - dim273JoeKuoD6Init, - dim274JoeKuoD6Init, - dim275JoeKuoD6Init, - dim276JoeKuoD6Init, - dim277JoeKuoD6Init, - dim278JoeKuoD6Init, - dim279JoeKuoD6Init, - dim280JoeKuoD6Init, - dim281JoeKuoD6Init, - dim282JoeKuoD6Init, - dim283JoeKuoD6Init, - dim284JoeKuoD6Init, - dim285JoeKuoD6Init, - dim286JoeKuoD6Init, - dim287JoeKuoD6Init, - dim288JoeKuoD6Init, - dim289JoeKuoD6Init, - dim290JoeKuoD6Init, - dim291JoeKuoD6Init, - dim292JoeKuoD6Init, - dim293JoeKuoD6Init, - dim294JoeKuoD6Init, - dim295JoeKuoD6Init, - dim296JoeKuoD6Init, - dim297JoeKuoD6Init, - dim298JoeKuoD6Init, - dim299JoeKuoD6Init, - dim300JoeKuoD6Init, - dim301JoeKuoD6Init, - dim302JoeKuoD6Init, - dim303JoeKuoD6Init, - dim304JoeKuoD6Init, - dim305JoeKuoD6Init, - dim306JoeKuoD6Init, - dim307JoeKuoD6Init, - dim308JoeKuoD6Init, - dim309JoeKuoD6Init, - dim310JoeKuoD6Init, - dim311JoeKuoD6Init, - dim312JoeKuoD6Init, - dim313JoeKuoD6Init, - dim314JoeKuoD6Init, - dim315JoeKuoD6Init, - dim316JoeKuoD6Init, - dim317JoeKuoD6Init, - dim318JoeKuoD6Init, - dim319JoeKuoD6Init, - dim320JoeKuoD6Init, - dim321JoeKuoD6Init, - dim322JoeKuoD6Init, - dim323JoeKuoD6Init, - dim324JoeKuoD6Init, - dim325JoeKuoD6Init, - dim326JoeKuoD6Init, - dim327JoeKuoD6Init, - dim328JoeKuoD6Init, - dim329JoeKuoD6Init, - dim330JoeKuoD6Init, - dim331JoeKuoD6Init, - dim332JoeKuoD6Init, - dim333JoeKuoD6Init, - dim334JoeKuoD6Init, - dim335JoeKuoD6Init, - dim336JoeKuoD6Init, - dim337JoeKuoD6Init, - dim338JoeKuoD6Init, - dim339JoeKuoD6Init, - dim340JoeKuoD6Init, - dim341JoeKuoD6Init, - dim342JoeKuoD6Init, - dim343JoeKuoD6Init, - dim344JoeKuoD6Init, - dim345JoeKuoD6Init, - dim346JoeKuoD6Init, - dim347JoeKuoD6Init, - dim348JoeKuoD6Init, - dim349JoeKuoD6Init, - dim350JoeKuoD6Init, - dim351JoeKuoD6Init, - dim352JoeKuoD6Init, - dim353JoeKuoD6Init, - dim354JoeKuoD6Init, - dim355JoeKuoD6Init, - dim356JoeKuoD6Init, - dim357JoeKuoD6Init, - dim358JoeKuoD6Init, - dim359JoeKuoD6Init, - dim360JoeKuoD6Init, - dim361JoeKuoD6Init, - dim362JoeKuoD6Init, - dim363JoeKuoD6Init, - dim364JoeKuoD6Init, - dim365JoeKuoD6Init, - dim366JoeKuoD6Init, - dim367JoeKuoD6Init, - dim368JoeKuoD6Init, - dim369JoeKuoD6Init, - dim370JoeKuoD6Init, - dim371JoeKuoD6Init, - dim372JoeKuoD6Init, - dim373JoeKuoD6Init, - dim374JoeKuoD6Init, - dim375JoeKuoD6Init, - dim376JoeKuoD6Init, - dim377JoeKuoD6Init, - dim378JoeKuoD6Init, - dim379JoeKuoD6Init, - dim380JoeKuoD6Init, - dim381JoeKuoD6Init, - dim382JoeKuoD6Init, - dim383JoeKuoD6Init, - dim384JoeKuoD6Init, - dim385JoeKuoD6Init, - dim386JoeKuoD6Init, - dim387JoeKuoD6Init, - dim388JoeKuoD6Init, - dim389JoeKuoD6Init, - dim390JoeKuoD6Init, - dim391JoeKuoD6Init, - dim392JoeKuoD6Init, - dim393JoeKuoD6Init, - dim394JoeKuoD6Init, - dim395JoeKuoD6Init, - dim396JoeKuoD6Init, - dim397JoeKuoD6Init, - dim398JoeKuoD6Init, - dim399JoeKuoD6Init, - dim400JoeKuoD6Init, - dim401JoeKuoD6Init, - dim402JoeKuoD6Init, - dim403JoeKuoD6Init, - dim404JoeKuoD6Init, - dim405JoeKuoD6Init, - dim406JoeKuoD6Init, - dim407JoeKuoD6Init, - dim408JoeKuoD6Init, - dim409JoeKuoD6Init, - dim410JoeKuoD6Init, - dim411JoeKuoD6Init, - dim412JoeKuoD6Init, - dim413JoeKuoD6Init, - dim414JoeKuoD6Init, - dim415JoeKuoD6Init, - dim416JoeKuoD6Init, - dim417JoeKuoD6Init, - dim418JoeKuoD6Init, - dim419JoeKuoD6Init, - dim420JoeKuoD6Init, - dim421JoeKuoD6Init, - dim422JoeKuoD6Init, - dim423JoeKuoD6Init, - dim424JoeKuoD6Init, - dim425JoeKuoD6Init, - dim426JoeKuoD6Init, - dim427JoeKuoD6Init, - dim428JoeKuoD6Init, - dim429JoeKuoD6Init, - dim430JoeKuoD6Init, - dim431JoeKuoD6Init, - dim432JoeKuoD6Init, - dim433JoeKuoD6Init, - dim434JoeKuoD6Init, - dim435JoeKuoD6Init, - dim436JoeKuoD6Init, - dim437JoeKuoD6Init, - dim438JoeKuoD6Init, - dim439JoeKuoD6Init, - dim440JoeKuoD6Init, - dim441JoeKuoD6Init, - dim442JoeKuoD6Init, - dim443JoeKuoD6Init, - dim444JoeKuoD6Init, - dim445JoeKuoD6Init, - dim446JoeKuoD6Init, - dim447JoeKuoD6Init, - dim448JoeKuoD6Init, - dim449JoeKuoD6Init, - dim450JoeKuoD6Init, - dim451JoeKuoD6Init, - dim452JoeKuoD6Init, - dim453JoeKuoD6Init, - dim454JoeKuoD6Init, - dim455JoeKuoD6Init, - dim456JoeKuoD6Init, - dim457JoeKuoD6Init, - dim458JoeKuoD6Init, - dim459JoeKuoD6Init, - dim460JoeKuoD6Init, - dim461JoeKuoD6Init, - dim462JoeKuoD6Init, - dim463JoeKuoD6Init, - dim464JoeKuoD6Init, - dim465JoeKuoD6Init, - dim466JoeKuoD6Init, - dim467JoeKuoD6Init, - dim468JoeKuoD6Init, - dim469JoeKuoD6Init, - dim470JoeKuoD6Init, - dim471JoeKuoD6Init, - dim472JoeKuoD6Init, - dim473JoeKuoD6Init, - dim474JoeKuoD6Init, - dim475JoeKuoD6Init, - dim476JoeKuoD6Init, - dim477JoeKuoD6Init, - dim478JoeKuoD6Init, - dim479JoeKuoD6Init, - dim480JoeKuoD6Init, - dim481JoeKuoD6Init, - dim482JoeKuoD6Init, - dim483JoeKuoD6Init, - dim484JoeKuoD6Init, - dim485JoeKuoD6Init, - dim486JoeKuoD6Init, - dim487JoeKuoD6Init, - dim488JoeKuoD6Init, - dim489JoeKuoD6Init, - dim490JoeKuoD6Init, - dim491JoeKuoD6Init, - dim492JoeKuoD6Init, - dim493JoeKuoD6Init, - dim494JoeKuoD6Init, - dim495JoeKuoD6Init, - dim496JoeKuoD6Init, - dim497JoeKuoD6Init, - dim498JoeKuoD6Init, - dim499JoeKuoD6Init, - dim500JoeKuoD6Init, - dim501JoeKuoD6Init, - dim502JoeKuoD6Init, - dim503JoeKuoD6Init, - dim504JoeKuoD6Init, - dim505JoeKuoD6Init, - dim506JoeKuoD6Init, - dim507JoeKuoD6Init, - dim508JoeKuoD6Init, - dim509JoeKuoD6Init, - dim510JoeKuoD6Init, - dim511JoeKuoD6Init, - dim512JoeKuoD6Init, - dim513JoeKuoD6Init, - dim514JoeKuoD6Init, - dim515JoeKuoD6Init, - dim516JoeKuoD6Init, - dim517JoeKuoD6Init, - dim518JoeKuoD6Init, - dim519JoeKuoD6Init, - dim520JoeKuoD6Init, - dim521JoeKuoD6Init, - dim522JoeKuoD6Init, - dim523JoeKuoD6Init, - dim524JoeKuoD6Init, - dim525JoeKuoD6Init, - dim526JoeKuoD6Init, - dim527JoeKuoD6Init, - dim528JoeKuoD6Init, - dim529JoeKuoD6Init, - dim530JoeKuoD6Init, - dim531JoeKuoD6Init, - dim532JoeKuoD6Init, - dim533JoeKuoD6Init, - dim534JoeKuoD6Init, - dim535JoeKuoD6Init, - dim536JoeKuoD6Init, - dim537JoeKuoD6Init, - dim538JoeKuoD6Init, - dim539JoeKuoD6Init, - dim540JoeKuoD6Init, - dim541JoeKuoD6Init, - dim542JoeKuoD6Init, - dim543JoeKuoD6Init, - dim544JoeKuoD6Init, - dim545JoeKuoD6Init, - dim546JoeKuoD6Init, - dim547JoeKuoD6Init, - dim548JoeKuoD6Init, - dim549JoeKuoD6Init, - dim550JoeKuoD6Init, - dim551JoeKuoD6Init, - dim552JoeKuoD6Init, - dim553JoeKuoD6Init, - dim554JoeKuoD6Init, - dim555JoeKuoD6Init, - dim556JoeKuoD6Init, - dim557JoeKuoD6Init, - dim558JoeKuoD6Init, - dim559JoeKuoD6Init, - dim560JoeKuoD6Init, - dim561JoeKuoD6Init, - dim562JoeKuoD6Init, - dim563JoeKuoD6Init, - dim564JoeKuoD6Init, - dim565JoeKuoD6Init, - dim566JoeKuoD6Init, - dim567JoeKuoD6Init, - dim568JoeKuoD6Init, - dim569JoeKuoD6Init, - dim570JoeKuoD6Init, - dim571JoeKuoD6Init, - dim572JoeKuoD6Init, - dim573JoeKuoD6Init, - dim574JoeKuoD6Init, - dim575JoeKuoD6Init, - dim576JoeKuoD6Init, - dim577JoeKuoD6Init, - dim578JoeKuoD6Init, - dim579JoeKuoD6Init, - dim580JoeKuoD6Init, - dim581JoeKuoD6Init, - dim582JoeKuoD6Init, - dim583JoeKuoD6Init, - dim584JoeKuoD6Init, - dim585JoeKuoD6Init, - dim586JoeKuoD6Init, - dim587JoeKuoD6Init, - dim588JoeKuoD6Init, - dim589JoeKuoD6Init, - dim590JoeKuoD6Init, - dim591JoeKuoD6Init, - dim592JoeKuoD6Init, - dim593JoeKuoD6Init, - dim594JoeKuoD6Init, - dim595JoeKuoD6Init, - dim596JoeKuoD6Init, - dim597JoeKuoD6Init, - dim598JoeKuoD6Init, - dim599JoeKuoD6Init, - dim600JoeKuoD6Init, - dim601JoeKuoD6Init, - dim602JoeKuoD6Init, - dim603JoeKuoD6Init, - dim604JoeKuoD6Init, - dim605JoeKuoD6Init, - dim606JoeKuoD6Init, - dim607JoeKuoD6Init, - dim608JoeKuoD6Init, - dim609JoeKuoD6Init, - dim610JoeKuoD6Init, - dim611JoeKuoD6Init, - dim612JoeKuoD6Init, - dim613JoeKuoD6Init, - dim614JoeKuoD6Init, - dim615JoeKuoD6Init, - dim616JoeKuoD6Init, - dim617JoeKuoD6Init, - dim618JoeKuoD6Init, - dim619JoeKuoD6Init, - dim620JoeKuoD6Init, - dim621JoeKuoD6Init, - dim622JoeKuoD6Init, - dim623JoeKuoD6Init, - dim624JoeKuoD6Init, - dim625JoeKuoD6Init, - dim626JoeKuoD6Init, - dim627JoeKuoD6Init, - dim628JoeKuoD6Init, - dim629JoeKuoD6Init, - dim630JoeKuoD6Init, - dim631JoeKuoD6Init, - dim632JoeKuoD6Init, - dim633JoeKuoD6Init, - dim634JoeKuoD6Init, - dim635JoeKuoD6Init, - dim636JoeKuoD6Init, - dim637JoeKuoD6Init, - dim638JoeKuoD6Init, - dim639JoeKuoD6Init, - dim640JoeKuoD6Init, - dim641JoeKuoD6Init, - dim642JoeKuoD6Init, - dim643JoeKuoD6Init, - dim644JoeKuoD6Init, - dim645JoeKuoD6Init, - dim646JoeKuoD6Init, - dim647JoeKuoD6Init, - dim648JoeKuoD6Init, - dim649JoeKuoD6Init, - dim650JoeKuoD6Init, - dim651JoeKuoD6Init, - dim652JoeKuoD6Init, - dim653JoeKuoD6Init, - dim654JoeKuoD6Init, - dim655JoeKuoD6Init, - dim656JoeKuoD6Init, - dim657JoeKuoD6Init, - dim658JoeKuoD6Init, - dim659JoeKuoD6Init, - dim660JoeKuoD6Init, - dim661JoeKuoD6Init, - dim662JoeKuoD6Init, - dim663JoeKuoD6Init, - dim664JoeKuoD6Init, - dim665JoeKuoD6Init, - dim666JoeKuoD6Init, - dim667JoeKuoD6Init, - dim668JoeKuoD6Init, - dim669JoeKuoD6Init, - dim670JoeKuoD6Init, - dim671JoeKuoD6Init, - dim672JoeKuoD6Init, - dim673JoeKuoD6Init, - dim674JoeKuoD6Init, - dim675JoeKuoD6Init, - dim676JoeKuoD6Init, - dim677JoeKuoD6Init, - dim678JoeKuoD6Init, - dim679JoeKuoD6Init, - dim680JoeKuoD6Init, - dim681JoeKuoD6Init, - dim682JoeKuoD6Init, - dim683JoeKuoD6Init, - dim684JoeKuoD6Init, - dim685JoeKuoD6Init, - dim686JoeKuoD6Init, - dim687JoeKuoD6Init, - dim688JoeKuoD6Init, - dim689JoeKuoD6Init, - dim690JoeKuoD6Init, - dim691JoeKuoD6Init, - dim692JoeKuoD6Init, - dim693JoeKuoD6Init, - dim694JoeKuoD6Init, - dim695JoeKuoD6Init, - dim696JoeKuoD6Init, - dim697JoeKuoD6Init, - dim698JoeKuoD6Init, - dim699JoeKuoD6Init, - dim700JoeKuoD6Init, - dim701JoeKuoD6Init, - dim702JoeKuoD6Init, - dim703JoeKuoD6Init, - dim704JoeKuoD6Init, - dim705JoeKuoD6Init, - dim706JoeKuoD6Init, - dim707JoeKuoD6Init, - dim708JoeKuoD6Init, - dim709JoeKuoD6Init, - dim710JoeKuoD6Init, - dim711JoeKuoD6Init, - dim712JoeKuoD6Init, - dim713JoeKuoD6Init, - dim714JoeKuoD6Init, - dim715JoeKuoD6Init, - dim716JoeKuoD6Init, - dim717JoeKuoD6Init, - dim718JoeKuoD6Init, - dim719JoeKuoD6Init, - dim720JoeKuoD6Init, - dim721JoeKuoD6Init, - dim722JoeKuoD6Init, - dim723JoeKuoD6Init, - dim724JoeKuoD6Init, - dim725JoeKuoD6Init, - dim726JoeKuoD6Init, - dim727JoeKuoD6Init, - dim728JoeKuoD6Init, - dim729JoeKuoD6Init, - dim730JoeKuoD6Init, - dim731JoeKuoD6Init, - dim732JoeKuoD6Init, - dim733JoeKuoD6Init, - dim734JoeKuoD6Init, - dim735JoeKuoD6Init, - dim736JoeKuoD6Init, - dim737JoeKuoD6Init, - dim738JoeKuoD6Init, - dim739JoeKuoD6Init, - dim740JoeKuoD6Init, - dim741JoeKuoD6Init, - dim742JoeKuoD6Init, - dim743JoeKuoD6Init, - dim744JoeKuoD6Init, - dim745JoeKuoD6Init, - dim746JoeKuoD6Init, - dim747JoeKuoD6Init, - dim748JoeKuoD6Init, - dim749JoeKuoD6Init, - dim750JoeKuoD6Init, - dim751JoeKuoD6Init, - dim752JoeKuoD6Init, - dim753JoeKuoD6Init, - dim754JoeKuoD6Init, - dim755JoeKuoD6Init, - dim756JoeKuoD6Init, - dim757JoeKuoD6Init, - dim758JoeKuoD6Init, - dim759JoeKuoD6Init, - dim760JoeKuoD6Init, - dim761JoeKuoD6Init, - dim762JoeKuoD6Init, - dim763JoeKuoD6Init, - dim764JoeKuoD6Init, - dim765JoeKuoD6Init, - dim766JoeKuoD6Init, - dim767JoeKuoD6Init, - dim768JoeKuoD6Init, - dim769JoeKuoD6Init, - dim770JoeKuoD6Init, - dim771JoeKuoD6Init, - dim772JoeKuoD6Init, - dim773JoeKuoD6Init, - dim774JoeKuoD6Init, - dim775JoeKuoD6Init, - dim776JoeKuoD6Init, - dim777JoeKuoD6Init, - dim778JoeKuoD6Init, - dim779JoeKuoD6Init, - dim780JoeKuoD6Init, - dim781JoeKuoD6Init, - dim782JoeKuoD6Init, - dim783JoeKuoD6Init, - dim784JoeKuoD6Init, - dim785JoeKuoD6Init, - dim786JoeKuoD6Init, - dim787JoeKuoD6Init, - dim788JoeKuoD6Init, - dim789JoeKuoD6Init, - dim790JoeKuoD6Init, - dim791JoeKuoD6Init, - dim792JoeKuoD6Init, - dim793JoeKuoD6Init, - dim794JoeKuoD6Init, - dim795JoeKuoD6Init, - dim796JoeKuoD6Init, - dim797JoeKuoD6Init, - dim798JoeKuoD6Init, - dim799JoeKuoD6Init, - dim800JoeKuoD6Init, - dim801JoeKuoD6Init, - dim802JoeKuoD6Init, - dim803JoeKuoD6Init, - dim804JoeKuoD6Init, - dim805JoeKuoD6Init, - dim806JoeKuoD6Init, - dim807JoeKuoD6Init, - dim808JoeKuoD6Init, - dim809JoeKuoD6Init, - dim810JoeKuoD6Init, - dim811JoeKuoD6Init, - dim812JoeKuoD6Init, - dim813JoeKuoD6Init, - dim814JoeKuoD6Init, - dim815JoeKuoD6Init, - dim816JoeKuoD6Init, - dim817JoeKuoD6Init, - dim818JoeKuoD6Init, - dim819JoeKuoD6Init, - dim820JoeKuoD6Init, - dim821JoeKuoD6Init, - dim822JoeKuoD6Init, - dim823JoeKuoD6Init, - dim824JoeKuoD6Init, - dim825JoeKuoD6Init, - dim826JoeKuoD6Init, - dim827JoeKuoD6Init, - dim828JoeKuoD6Init, - dim829JoeKuoD6Init, - dim830JoeKuoD6Init, - dim831JoeKuoD6Init, - dim832JoeKuoD6Init, - dim833JoeKuoD6Init, - dim834JoeKuoD6Init, - dim835JoeKuoD6Init, - dim836JoeKuoD6Init, - dim837JoeKuoD6Init, - dim838JoeKuoD6Init, - dim839JoeKuoD6Init, - dim840JoeKuoD6Init, - dim841JoeKuoD6Init, - dim842JoeKuoD6Init, - dim843JoeKuoD6Init, - dim844JoeKuoD6Init, - dim845JoeKuoD6Init, - dim846JoeKuoD6Init, - dim847JoeKuoD6Init, - dim848JoeKuoD6Init, - dim849JoeKuoD6Init, - dim850JoeKuoD6Init, - dim851JoeKuoD6Init, - dim852JoeKuoD6Init, - dim853JoeKuoD6Init, - dim854JoeKuoD6Init, - dim855JoeKuoD6Init, - dim856JoeKuoD6Init, - dim857JoeKuoD6Init, - dim858JoeKuoD6Init, - dim859JoeKuoD6Init, - dim860JoeKuoD6Init, - dim861JoeKuoD6Init, - dim862JoeKuoD6Init, - dim863JoeKuoD6Init, - dim864JoeKuoD6Init, - dim865JoeKuoD6Init, - dim866JoeKuoD6Init, - dim867JoeKuoD6Init, - dim868JoeKuoD6Init, - dim869JoeKuoD6Init, - dim870JoeKuoD6Init, - dim871JoeKuoD6Init, - dim872JoeKuoD6Init, - dim873JoeKuoD6Init, - dim874JoeKuoD6Init, - dim875JoeKuoD6Init, - dim876JoeKuoD6Init, - dim877JoeKuoD6Init, - dim878JoeKuoD6Init, - dim879JoeKuoD6Init, - dim880JoeKuoD6Init, - dim881JoeKuoD6Init, - dim882JoeKuoD6Init, - dim883JoeKuoD6Init, - dim884JoeKuoD6Init, - dim885JoeKuoD6Init, - dim886JoeKuoD6Init, - dim887JoeKuoD6Init, - dim888JoeKuoD6Init, - dim889JoeKuoD6Init, - dim890JoeKuoD6Init, - dim891JoeKuoD6Init, - dim892JoeKuoD6Init, - dim893JoeKuoD6Init, - dim894JoeKuoD6Init, - dim895JoeKuoD6Init, - dim896JoeKuoD6Init, - dim897JoeKuoD6Init, - dim898JoeKuoD6Init, - dim899JoeKuoD6Init, - dim900JoeKuoD6Init, - dim901JoeKuoD6Init, - dim902JoeKuoD6Init, - dim903JoeKuoD6Init, - dim904JoeKuoD6Init, - dim905JoeKuoD6Init, - dim906JoeKuoD6Init, - dim907JoeKuoD6Init, - dim908JoeKuoD6Init, - dim909JoeKuoD6Init, - dim910JoeKuoD6Init, - dim911JoeKuoD6Init, - dim912JoeKuoD6Init, - dim913JoeKuoD6Init, - dim914JoeKuoD6Init, - dim915JoeKuoD6Init, - dim916JoeKuoD6Init, - dim917JoeKuoD6Init, - dim918JoeKuoD6Init, - dim919JoeKuoD6Init, - dim920JoeKuoD6Init, - dim921JoeKuoD6Init, - dim922JoeKuoD6Init, - dim923JoeKuoD6Init, - dim924JoeKuoD6Init, - dim925JoeKuoD6Init, - dim926JoeKuoD6Init, - dim927JoeKuoD6Init, - dim928JoeKuoD6Init, - dim929JoeKuoD6Init, - dim930JoeKuoD6Init, - dim931JoeKuoD6Init, - dim932JoeKuoD6Init, - dim933JoeKuoD6Init, - dim934JoeKuoD6Init, - dim935JoeKuoD6Init, - dim936JoeKuoD6Init, - dim937JoeKuoD6Init, - dim938JoeKuoD6Init, - dim939JoeKuoD6Init, - dim940JoeKuoD6Init, - dim941JoeKuoD6Init, - dim942JoeKuoD6Init, - dim943JoeKuoD6Init, - dim944JoeKuoD6Init, - dim945JoeKuoD6Init, - dim946JoeKuoD6Init, - dim947JoeKuoD6Init, - dim948JoeKuoD6Init, - dim949JoeKuoD6Init, - dim950JoeKuoD6Init, - dim951JoeKuoD6Init, - dim952JoeKuoD6Init, - dim953JoeKuoD6Init, - dim954JoeKuoD6Init, - dim955JoeKuoD6Init, - dim956JoeKuoD6Init, - dim957JoeKuoD6Init, - dim958JoeKuoD6Init, - dim959JoeKuoD6Init, - dim960JoeKuoD6Init, - dim961JoeKuoD6Init, - dim962JoeKuoD6Init, - dim963JoeKuoD6Init, - dim964JoeKuoD6Init, - dim965JoeKuoD6Init, - dim966JoeKuoD6Init, - dim967JoeKuoD6Init, - dim968JoeKuoD6Init, - dim969JoeKuoD6Init, - dim970JoeKuoD6Init, - dim971JoeKuoD6Init, - dim972JoeKuoD6Init, - dim973JoeKuoD6Init, - dim974JoeKuoD6Init, - dim975JoeKuoD6Init, - dim976JoeKuoD6Init, - dim977JoeKuoD6Init, - dim978JoeKuoD6Init, - dim979JoeKuoD6Init, - dim980JoeKuoD6Init, - dim981JoeKuoD6Init, - dim982JoeKuoD6Init, - dim983JoeKuoD6Init, - dim984JoeKuoD6Init, - dim985JoeKuoD6Init, - dim986JoeKuoD6Init, - dim987JoeKuoD6Init, - dim988JoeKuoD6Init, - dim989JoeKuoD6Init, - dim990JoeKuoD6Init, - dim991JoeKuoD6Init, - dim992JoeKuoD6Init, - dim993JoeKuoD6Init, - dim994JoeKuoD6Init, - dim995JoeKuoD6Init, - dim996JoeKuoD6Init, - dim997JoeKuoD6Init, - dim998JoeKuoD6Init, - dim999JoeKuoD6Init, - dim1000JoeKuoD6Init, - dim1001JoeKuoD6Init, - dim1002JoeKuoD6Init, - dim1003JoeKuoD6Init, - dim1004JoeKuoD6Init, - dim1005JoeKuoD6Init, - dim1006JoeKuoD6Init, - dim1007JoeKuoD6Init, - dim1008JoeKuoD6Init, - dim1009JoeKuoD6Init, - dim1010JoeKuoD6Init, - dim1011JoeKuoD6Init, - dim1012JoeKuoD6Init, - dim1013JoeKuoD6Init, - dim1014JoeKuoD6Init, - dim1015JoeKuoD6Init, - dim1016JoeKuoD6Init, - dim1017JoeKuoD6Init, - dim1018JoeKuoD6Init, - dim1019JoeKuoD6Init, - dim1020JoeKuoD6Init, - dim1021JoeKuoD6Init, - dim1022JoeKuoD6Init, - dim1023JoeKuoD6Init, - dim1024JoeKuoD6Init, - dim1025JoeKuoD6Init, - dim1026JoeKuoD6Init, - dim1027JoeKuoD6Init, - dim1028JoeKuoD6Init, - dim1029JoeKuoD6Init, - dim1030JoeKuoD6Init, - dim1031JoeKuoD6Init, - dim1032JoeKuoD6Init, - dim1033JoeKuoD6Init, - dim1034JoeKuoD6Init, - dim1035JoeKuoD6Init, - dim1036JoeKuoD6Init, - dim1037JoeKuoD6Init, - dim1038JoeKuoD6Init, - dim1039JoeKuoD6Init, - dim1040JoeKuoD6Init, - dim1041JoeKuoD6Init, - dim1042JoeKuoD6Init, - dim1043JoeKuoD6Init, - dim1044JoeKuoD6Init, - dim1045JoeKuoD6Init, - dim1046JoeKuoD6Init, - dim1047JoeKuoD6Init, - dim1048JoeKuoD6Init, - dim1049JoeKuoD6Init, - dim1050JoeKuoD6Init, - dim1051JoeKuoD6Init, - dim1052JoeKuoD6Init, - dim1053JoeKuoD6Init, - dim1054JoeKuoD6Init, - dim1055JoeKuoD6Init, - dim1056JoeKuoD6Init, - dim1057JoeKuoD6Init, - dim1058JoeKuoD6Init, - dim1059JoeKuoD6Init, - dim1060JoeKuoD6Init, - dim1061JoeKuoD6Init, - dim1062JoeKuoD6Init, - dim1063JoeKuoD6Init, - dim1064JoeKuoD6Init, - dim1065JoeKuoD6Init, - dim1066JoeKuoD6Init, - dim1067JoeKuoD6Init, - dim1068JoeKuoD6Init, - dim1069JoeKuoD6Init, - dim1070JoeKuoD6Init, - dim1071JoeKuoD6Init, - dim1072JoeKuoD6Init, - dim1073JoeKuoD6Init, - dim1074JoeKuoD6Init, - dim1075JoeKuoD6Init, - dim1076JoeKuoD6Init, - dim1077JoeKuoD6Init, - dim1078JoeKuoD6Init, - dim1079JoeKuoD6Init, - dim1080JoeKuoD6Init, - dim1081JoeKuoD6Init, - dim1082JoeKuoD6Init, - dim1083JoeKuoD6Init, - dim1084JoeKuoD6Init, - dim1085JoeKuoD6Init, - dim1086JoeKuoD6Init, - dim1087JoeKuoD6Init, - dim1088JoeKuoD6Init, - dim1089JoeKuoD6Init, - dim1090JoeKuoD6Init, - dim1091JoeKuoD6Init, - dim1092JoeKuoD6Init, - dim1093JoeKuoD6Init, - dim1094JoeKuoD6Init, - dim1095JoeKuoD6Init, - dim1096JoeKuoD6Init, - dim1097JoeKuoD6Init, - dim1098JoeKuoD6Init, - dim1099JoeKuoD6Init, - dim1100JoeKuoD6Init, - dim1101JoeKuoD6Init, - dim1102JoeKuoD6Init, - dim1103JoeKuoD6Init, - dim1104JoeKuoD6Init, - dim1105JoeKuoD6Init, - dim1106JoeKuoD6Init, - dim1107JoeKuoD6Init, - dim1108JoeKuoD6Init, - dim1109JoeKuoD6Init, - dim1110JoeKuoD6Init, - dim1111JoeKuoD6Init, - dim1112JoeKuoD6Init, - dim1113JoeKuoD6Init, - dim1114JoeKuoD6Init, - dim1115JoeKuoD6Init, - dim1116JoeKuoD6Init, - dim1117JoeKuoD6Init, - dim1118JoeKuoD6Init, - dim1119JoeKuoD6Init, - dim1120JoeKuoD6Init, - dim1121JoeKuoD6Init, - dim1122JoeKuoD6Init, - dim1123JoeKuoD6Init, - dim1124JoeKuoD6Init, - dim1125JoeKuoD6Init, - dim1126JoeKuoD6Init, - dim1127JoeKuoD6Init, - dim1128JoeKuoD6Init, - dim1129JoeKuoD6Init, - dim1130JoeKuoD6Init, - dim1131JoeKuoD6Init, - dim1132JoeKuoD6Init, - dim1133JoeKuoD6Init, - dim1134JoeKuoD6Init, - dim1135JoeKuoD6Init, - dim1136JoeKuoD6Init, - dim1137JoeKuoD6Init, - dim1138JoeKuoD6Init, - dim1139JoeKuoD6Init, - dim1140JoeKuoD6Init, - dim1141JoeKuoD6Init, - dim1142JoeKuoD6Init, - dim1143JoeKuoD6Init, - dim1144JoeKuoD6Init, - dim1145JoeKuoD6Init, - dim1146JoeKuoD6Init, - dim1147JoeKuoD6Init, - dim1148JoeKuoD6Init, - dim1149JoeKuoD6Init, - dim1150JoeKuoD6Init, - dim1151JoeKuoD6Init, - dim1152JoeKuoD6Init, - dim1153JoeKuoD6Init, - dim1154JoeKuoD6Init, - dim1155JoeKuoD6Init, - dim1156JoeKuoD6Init, - dim1157JoeKuoD6Init, - dim1158JoeKuoD6Init, - dim1159JoeKuoD6Init, - dim1160JoeKuoD6Init, - dim1161JoeKuoD6Init, - dim1162JoeKuoD6Init, - dim1163JoeKuoD6Init, - dim1164JoeKuoD6Init, - dim1165JoeKuoD6Init, - dim1166JoeKuoD6Init, - dim1167JoeKuoD6Init, - dim1168JoeKuoD6Init, - dim1169JoeKuoD6Init, - dim1170JoeKuoD6Init, - dim1171JoeKuoD6Init, - dim1172JoeKuoD6Init, - dim1173JoeKuoD6Init, - dim1174JoeKuoD6Init, - dim1175JoeKuoD6Init, - dim1176JoeKuoD6Init, - dim1177JoeKuoD6Init, - dim1178JoeKuoD6Init, - dim1179JoeKuoD6Init, - dim1180JoeKuoD6Init, - dim1181JoeKuoD6Init, - dim1182JoeKuoD6Init, - dim1183JoeKuoD6Init, - dim1184JoeKuoD6Init, - dim1185JoeKuoD6Init, - dim1186JoeKuoD6Init, - dim1187JoeKuoD6Init, - dim1188JoeKuoD6Init, - dim1189JoeKuoD6Init, - dim1190JoeKuoD6Init, - dim1191JoeKuoD6Init, - dim1192JoeKuoD6Init, - dim1193JoeKuoD6Init, - dim1194JoeKuoD6Init, - dim1195JoeKuoD6Init, - dim1196JoeKuoD6Init, - dim1197JoeKuoD6Init, - dim1198JoeKuoD6Init, - dim1199JoeKuoD6Init, - dim1200JoeKuoD6Init, - dim1201JoeKuoD6Init, - dim1202JoeKuoD6Init, - dim1203JoeKuoD6Init, - dim1204JoeKuoD6Init, - dim1205JoeKuoD6Init, - dim1206JoeKuoD6Init, - dim1207JoeKuoD6Init, - dim1208JoeKuoD6Init, - dim1209JoeKuoD6Init, - dim1210JoeKuoD6Init, - dim1211JoeKuoD6Init, - dim1212JoeKuoD6Init, - dim1213JoeKuoD6Init, - dim1214JoeKuoD6Init, - dim1215JoeKuoD6Init, - dim1216JoeKuoD6Init, - dim1217JoeKuoD6Init, - dim1218JoeKuoD6Init, - dim1219JoeKuoD6Init, - dim1220JoeKuoD6Init, - dim1221JoeKuoD6Init, - dim1222JoeKuoD6Init, - dim1223JoeKuoD6Init, - dim1224JoeKuoD6Init, - dim1225JoeKuoD6Init, - dim1226JoeKuoD6Init, - dim1227JoeKuoD6Init, - dim1228JoeKuoD6Init, - dim1229JoeKuoD6Init, - dim1230JoeKuoD6Init, - dim1231JoeKuoD6Init, - dim1232JoeKuoD6Init, - dim1233JoeKuoD6Init, - dim1234JoeKuoD6Init, - dim1235JoeKuoD6Init, - dim1236JoeKuoD6Init, - dim1237JoeKuoD6Init, - dim1238JoeKuoD6Init, - dim1239JoeKuoD6Init, - dim1240JoeKuoD6Init, - dim1241JoeKuoD6Init, - dim1242JoeKuoD6Init, - dim1243JoeKuoD6Init, - dim1244JoeKuoD6Init, - dim1245JoeKuoD6Init, - dim1246JoeKuoD6Init, - dim1247JoeKuoD6Init, - dim1248JoeKuoD6Init, - dim1249JoeKuoD6Init, - dim1250JoeKuoD6Init, - dim1251JoeKuoD6Init, - dim1252JoeKuoD6Init, - dim1253JoeKuoD6Init, - dim1254JoeKuoD6Init, - dim1255JoeKuoD6Init, - dim1256JoeKuoD6Init, - dim1257JoeKuoD6Init, - dim1258JoeKuoD6Init, - dim1259JoeKuoD6Init, - dim1260JoeKuoD6Init, - dim1261JoeKuoD6Init, - dim1262JoeKuoD6Init, - dim1263JoeKuoD6Init, - dim1264JoeKuoD6Init, - dim1265JoeKuoD6Init, - dim1266JoeKuoD6Init, - dim1267JoeKuoD6Init, - dim1268JoeKuoD6Init, - dim1269JoeKuoD6Init, - dim1270JoeKuoD6Init, - dim1271JoeKuoD6Init, - dim1272JoeKuoD6Init, - dim1273JoeKuoD6Init, - dim1274JoeKuoD6Init, - dim1275JoeKuoD6Init, - dim1276JoeKuoD6Init, - dim1277JoeKuoD6Init, - dim1278JoeKuoD6Init, - dim1279JoeKuoD6Init, - dim1280JoeKuoD6Init, - dim1281JoeKuoD6Init, - dim1282JoeKuoD6Init, - dim1283JoeKuoD6Init, - dim1284JoeKuoD6Init, - dim1285JoeKuoD6Init, - dim1286JoeKuoD6Init, - dim1287JoeKuoD6Init, - dim1288JoeKuoD6Init, - dim1289JoeKuoD6Init, - dim1290JoeKuoD6Init, - dim1291JoeKuoD6Init, - dim1292JoeKuoD6Init, - dim1293JoeKuoD6Init, - dim1294JoeKuoD6Init, - dim1295JoeKuoD6Init, - dim1296JoeKuoD6Init, - dim1297JoeKuoD6Init, - dim1298JoeKuoD6Init, - dim1299JoeKuoD6Init, - dim1300JoeKuoD6Init, - dim1301JoeKuoD6Init, - dim1302JoeKuoD6Init, - dim1303JoeKuoD6Init, - dim1304JoeKuoD6Init, - dim1305JoeKuoD6Init, - dim1306JoeKuoD6Init, - dim1307JoeKuoD6Init, - dim1308JoeKuoD6Init, - dim1309JoeKuoD6Init, - dim1310JoeKuoD6Init, - dim1311JoeKuoD6Init, - dim1312JoeKuoD6Init, - dim1313JoeKuoD6Init, - dim1314JoeKuoD6Init, - dim1315JoeKuoD6Init, - dim1316JoeKuoD6Init, - dim1317JoeKuoD6Init, - dim1318JoeKuoD6Init, - dim1319JoeKuoD6Init, - dim1320JoeKuoD6Init, - dim1321JoeKuoD6Init, - dim1322JoeKuoD6Init, - dim1323JoeKuoD6Init, - dim1324JoeKuoD6Init, - dim1325JoeKuoD6Init, - dim1326JoeKuoD6Init, - dim1327JoeKuoD6Init, - dim1328JoeKuoD6Init, - dim1329JoeKuoD6Init, - dim1330JoeKuoD6Init, - dim1331JoeKuoD6Init, - dim1332JoeKuoD6Init, - dim1333JoeKuoD6Init, - dim1334JoeKuoD6Init, - dim1335JoeKuoD6Init, - dim1336JoeKuoD6Init, - dim1337JoeKuoD6Init, - dim1338JoeKuoD6Init, - dim1339JoeKuoD6Init, - dim1340JoeKuoD6Init, - dim1341JoeKuoD6Init, - dim1342JoeKuoD6Init, - dim1343JoeKuoD6Init, - dim1344JoeKuoD6Init, - dim1345JoeKuoD6Init, - dim1346JoeKuoD6Init, - dim1347JoeKuoD6Init, - dim1348JoeKuoD6Init, - dim1349JoeKuoD6Init, - dim1350JoeKuoD6Init, - dim1351JoeKuoD6Init, - dim1352JoeKuoD6Init, - dim1353JoeKuoD6Init, - dim1354JoeKuoD6Init, - dim1355JoeKuoD6Init, - dim1356JoeKuoD6Init, - dim1357JoeKuoD6Init, - dim1358JoeKuoD6Init, - dim1359JoeKuoD6Init, - dim1360JoeKuoD6Init, - dim1361JoeKuoD6Init, - dim1362JoeKuoD6Init, - dim1363JoeKuoD6Init, - dim1364JoeKuoD6Init, - dim1365JoeKuoD6Init, - dim1366JoeKuoD6Init, - dim1367JoeKuoD6Init, - dim1368JoeKuoD6Init, - dim1369JoeKuoD6Init, - dim1370JoeKuoD6Init, - dim1371JoeKuoD6Init, - dim1372JoeKuoD6Init, - dim1373JoeKuoD6Init, - dim1374JoeKuoD6Init, - dim1375JoeKuoD6Init, - dim1376JoeKuoD6Init, - dim1377JoeKuoD6Init, - dim1378JoeKuoD6Init, - dim1379JoeKuoD6Init, - dim1380JoeKuoD6Init, - dim1381JoeKuoD6Init, - dim1382JoeKuoD6Init, - dim1383JoeKuoD6Init, - dim1384JoeKuoD6Init, - dim1385JoeKuoD6Init, - dim1386JoeKuoD6Init, - dim1387JoeKuoD6Init, - dim1388JoeKuoD6Init, - dim1389JoeKuoD6Init, - dim1390JoeKuoD6Init, - dim1391JoeKuoD6Init, - dim1392JoeKuoD6Init, - dim1393JoeKuoD6Init, - dim1394JoeKuoD6Init, - dim1395JoeKuoD6Init, - dim1396JoeKuoD6Init, - dim1397JoeKuoD6Init, - dim1398JoeKuoD6Init, - dim1399JoeKuoD6Init, - dim1400JoeKuoD6Init, - dim1401JoeKuoD6Init, - dim1402JoeKuoD6Init, - dim1403JoeKuoD6Init, - dim1404JoeKuoD6Init, - dim1405JoeKuoD6Init, - dim1406JoeKuoD6Init, - dim1407JoeKuoD6Init, - dim1408JoeKuoD6Init, - dim1409JoeKuoD6Init, - dim1410JoeKuoD6Init, - dim1411JoeKuoD6Init, - dim1412JoeKuoD6Init, - dim1413JoeKuoD6Init, - dim1414JoeKuoD6Init, - dim1415JoeKuoD6Init, - dim1416JoeKuoD6Init, - dim1417JoeKuoD6Init, - dim1418JoeKuoD6Init, - dim1419JoeKuoD6Init, - dim1420JoeKuoD6Init, - dim1421JoeKuoD6Init, - dim1422JoeKuoD6Init, - dim1423JoeKuoD6Init, - dim1424JoeKuoD6Init, - dim1425JoeKuoD6Init, - dim1426JoeKuoD6Init, - dim1427JoeKuoD6Init, - dim1428JoeKuoD6Init, - dim1429JoeKuoD6Init, - dim1430JoeKuoD6Init, - dim1431JoeKuoD6Init, - dim1432JoeKuoD6Init, - dim1433JoeKuoD6Init, - dim1434JoeKuoD6Init, - dim1435JoeKuoD6Init, - dim1436JoeKuoD6Init, - dim1437JoeKuoD6Init, - dim1438JoeKuoD6Init, - dim1439JoeKuoD6Init, - dim1440JoeKuoD6Init, - dim1441JoeKuoD6Init, - dim1442JoeKuoD6Init, - dim1443JoeKuoD6Init, - dim1444JoeKuoD6Init, - dim1445JoeKuoD6Init, - dim1446JoeKuoD6Init, - dim1447JoeKuoD6Init, - dim1448JoeKuoD6Init, - dim1449JoeKuoD6Init, - dim1450JoeKuoD6Init, - dim1451JoeKuoD6Init, - dim1452JoeKuoD6Init, - dim1453JoeKuoD6Init, - dim1454JoeKuoD6Init, - dim1455JoeKuoD6Init, - dim1456JoeKuoD6Init, - dim1457JoeKuoD6Init, - dim1458JoeKuoD6Init, - dim1459JoeKuoD6Init, - dim1460JoeKuoD6Init, - dim1461JoeKuoD6Init, - dim1462JoeKuoD6Init, - dim1463JoeKuoD6Init, - dim1464JoeKuoD6Init, - dim1465JoeKuoD6Init, - dim1466JoeKuoD6Init, - dim1467JoeKuoD6Init, - dim1468JoeKuoD6Init, - dim1469JoeKuoD6Init, - dim1470JoeKuoD6Init, - dim1471JoeKuoD6Init, - dim1472JoeKuoD6Init, - dim1473JoeKuoD6Init, - dim1474JoeKuoD6Init, - dim1475JoeKuoD6Init, - dim1476JoeKuoD6Init, - dim1477JoeKuoD6Init, - dim1478JoeKuoD6Init, - dim1479JoeKuoD6Init, - dim1480JoeKuoD6Init, - dim1481JoeKuoD6Init, - dim1482JoeKuoD6Init, - dim1483JoeKuoD6Init, - dim1484JoeKuoD6Init, - dim1485JoeKuoD6Init, - dim1486JoeKuoD6Init, - dim1487JoeKuoD6Init, - dim1488JoeKuoD6Init, - dim1489JoeKuoD6Init, - dim1490JoeKuoD6Init, - dim1491JoeKuoD6Init, - dim1492JoeKuoD6Init, - dim1493JoeKuoD6Init, - dim1494JoeKuoD6Init, - dim1495JoeKuoD6Init, - dim1496JoeKuoD6Init, - dim1497JoeKuoD6Init, - dim1498JoeKuoD6Init, - dim1499JoeKuoD6Init, - dim1500JoeKuoD6Init, - dim1501JoeKuoD6Init, - dim1502JoeKuoD6Init, - dim1503JoeKuoD6Init, - dim1504JoeKuoD6Init, - dim1505JoeKuoD6Init, - dim1506JoeKuoD6Init, - dim1507JoeKuoD6Init, - dim1508JoeKuoD6Init, - dim1509JoeKuoD6Init, - dim1510JoeKuoD6Init, - dim1511JoeKuoD6Init, - dim1512JoeKuoD6Init, - dim1513JoeKuoD6Init, - dim1514JoeKuoD6Init, - dim1515JoeKuoD6Init, - dim1516JoeKuoD6Init, - dim1517JoeKuoD6Init, - dim1518JoeKuoD6Init, - dim1519JoeKuoD6Init, - dim1520JoeKuoD6Init, - dim1521JoeKuoD6Init, - dim1522JoeKuoD6Init, - dim1523JoeKuoD6Init, - dim1524JoeKuoD6Init, - dim1525JoeKuoD6Init, - dim1526JoeKuoD6Init, - dim1527JoeKuoD6Init, - dim1528JoeKuoD6Init, - dim1529JoeKuoD6Init, - dim1530JoeKuoD6Init, - dim1531JoeKuoD6Init, - dim1532JoeKuoD6Init, - dim1533JoeKuoD6Init, - dim1534JoeKuoD6Init, - dim1535JoeKuoD6Init, - dim1536JoeKuoD6Init, - dim1537JoeKuoD6Init, - dim1538JoeKuoD6Init, - dim1539JoeKuoD6Init, - dim1540JoeKuoD6Init, - dim1541JoeKuoD6Init, - dim1542JoeKuoD6Init, - dim1543JoeKuoD6Init, - dim1544JoeKuoD6Init, - dim1545JoeKuoD6Init, - dim1546JoeKuoD6Init, - dim1547JoeKuoD6Init, - dim1548JoeKuoD6Init, - dim1549JoeKuoD6Init, - dim1550JoeKuoD6Init, - dim1551JoeKuoD6Init, - dim1552JoeKuoD6Init, - dim1553JoeKuoD6Init, - dim1554JoeKuoD6Init, - dim1555JoeKuoD6Init, - dim1556JoeKuoD6Init, - dim1557JoeKuoD6Init, - dim1558JoeKuoD6Init, - dim1559JoeKuoD6Init, - dim1560JoeKuoD6Init, - dim1561JoeKuoD6Init, - dim1562JoeKuoD6Init, - dim1563JoeKuoD6Init, - dim1564JoeKuoD6Init, - dim1565JoeKuoD6Init, - dim1566JoeKuoD6Init, - dim1567JoeKuoD6Init, - dim1568JoeKuoD6Init, - dim1569JoeKuoD6Init, - dim1570JoeKuoD6Init, - dim1571JoeKuoD6Init, - dim1572JoeKuoD6Init, - dim1573JoeKuoD6Init, - dim1574JoeKuoD6Init, - dim1575JoeKuoD6Init, - dim1576JoeKuoD6Init, - dim1577JoeKuoD6Init, - dim1578JoeKuoD6Init, - dim1579JoeKuoD6Init, - dim1580JoeKuoD6Init, - dim1581JoeKuoD6Init, - dim1582JoeKuoD6Init, - dim1583JoeKuoD6Init, - dim1584JoeKuoD6Init, - dim1585JoeKuoD6Init, - dim1586JoeKuoD6Init, - dim1587JoeKuoD6Init, - dim1588JoeKuoD6Init, - dim1589JoeKuoD6Init, - dim1590JoeKuoD6Init, - dim1591JoeKuoD6Init, - dim1592JoeKuoD6Init, - dim1593JoeKuoD6Init, - dim1594JoeKuoD6Init, - dim1595JoeKuoD6Init, - dim1596JoeKuoD6Init, - dim1597JoeKuoD6Init, - dim1598JoeKuoD6Init, - dim1599JoeKuoD6Init, - dim1600JoeKuoD6Init, - dim1601JoeKuoD6Init, - dim1602JoeKuoD6Init, - dim1603JoeKuoD6Init, - dim1604JoeKuoD6Init, - dim1605JoeKuoD6Init, - dim1606JoeKuoD6Init, - dim1607JoeKuoD6Init, - dim1608JoeKuoD6Init, - dim1609JoeKuoD6Init, - dim1610JoeKuoD6Init, - dim1611JoeKuoD6Init, - dim1612JoeKuoD6Init, - dim1613JoeKuoD6Init, - dim1614JoeKuoD6Init, - dim1615JoeKuoD6Init, - dim1616JoeKuoD6Init, - dim1617JoeKuoD6Init, - dim1618JoeKuoD6Init, - dim1619JoeKuoD6Init, - dim1620JoeKuoD6Init, - dim1621JoeKuoD6Init, - dim1622JoeKuoD6Init, - dim1623JoeKuoD6Init, - dim1624JoeKuoD6Init, - dim1625JoeKuoD6Init, - dim1626JoeKuoD6Init, - dim1627JoeKuoD6Init, - dim1628JoeKuoD6Init, - dim1629JoeKuoD6Init, - dim1630JoeKuoD6Init, - dim1631JoeKuoD6Init, - dim1632JoeKuoD6Init, - dim1633JoeKuoD6Init, - dim1634JoeKuoD6Init, - dim1635JoeKuoD6Init, - dim1636JoeKuoD6Init, - dim1637JoeKuoD6Init, - dim1638JoeKuoD6Init, - dim1639JoeKuoD6Init, - dim1640JoeKuoD6Init, - dim1641JoeKuoD6Init, - dim1642JoeKuoD6Init, - dim1643JoeKuoD6Init, - dim1644JoeKuoD6Init, - dim1645JoeKuoD6Init, - dim1646JoeKuoD6Init, - dim1647JoeKuoD6Init, - dim1648JoeKuoD6Init, - dim1649JoeKuoD6Init, - dim1650JoeKuoD6Init, - dim1651JoeKuoD6Init, - dim1652JoeKuoD6Init, - dim1653JoeKuoD6Init, - dim1654JoeKuoD6Init, - dim1655JoeKuoD6Init, - dim1656JoeKuoD6Init, - dim1657JoeKuoD6Init, - dim1658JoeKuoD6Init, - dim1659JoeKuoD6Init, - dim1660JoeKuoD6Init, - dim1661JoeKuoD6Init, - dim1662JoeKuoD6Init, - dim1663JoeKuoD6Init, - dim1664JoeKuoD6Init, - dim1665JoeKuoD6Init, - dim1666JoeKuoD6Init, - dim1667JoeKuoD6Init, - dim1668JoeKuoD6Init, - dim1669JoeKuoD6Init, - dim1670JoeKuoD6Init, - dim1671JoeKuoD6Init, - dim1672JoeKuoD6Init, - dim1673JoeKuoD6Init, - dim1674JoeKuoD6Init, - dim1675JoeKuoD6Init, - dim1676JoeKuoD6Init, - dim1677JoeKuoD6Init, - dim1678JoeKuoD6Init, - dim1679JoeKuoD6Init, - dim1680JoeKuoD6Init, - dim1681JoeKuoD6Init, - dim1682JoeKuoD6Init, - dim1683JoeKuoD6Init, - dim1684JoeKuoD6Init, - dim1685JoeKuoD6Init, - dim1686JoeKuoD6Init, - dim1687JoeKuoD6Init, - dim1688JoeKuoD6Init, - dim1689JoeKuoD6Init, - dim1690JoeKuoD6Init, - dim1691JoeKuoD6Init, - dim1692JoeKuoD6Init, - dim1693JoeKuoD6Init, - dim1694JoeKuoD6Init, - dim1695JoeKuoD6Init, - dim1696JoeKuoD6Init, - dim1697JoeKuoD6Init, - dim1698JoeKuoD6Init, - dim1699JoeKuoD6Init, - dim1700JoeKuoD6Init, - dim1701JoeKuoD6Init, - dim1702JoeKuoD6Init, - dim1703JoeKuoD6Init, - dim1704JoeKuoD6Init, - dim1705JoeKuoD6Init, - dim1706JoeKuoD6Init, - dim1707JoeKuoD6Init, - dim1708JoeKuoD6Init, - dim1709JoeKuoD6Init, - dim1710JoeKuoD6Init, - dim1711JoeKuoD6Init, - dim1712JoeKuoD6Init, - dim1713JoeKuoD6Init, - dim1714JoeKuoD6Init, - dim1715JoeKuoD6Init, - dim1716JoeKuoD6Init, - dim1717JoeKuoD6Init, - dim1718JoeKuoD6Init, - dim1719JoeKuoD6Init, - dim1720JoeKuoD6Init, - dim1721JoeKuoD6Init, - dim1722JoeKuoD6Init, - dim1723JoeKuoD6Init, - dim1724JoeKuoD6Init, - dim1725JoeKuoD6Init, - dim1726JoeKuoD6Init, - dim1727JoeKuoD6Init, - dim1728JoeKuoD6Init, - dim1729JoeKuoD6Init, - dim1730JoeKuoD6Init, - dim1731JoeKuoD6Init, - dim1732JoeKuoD6Init, - dim1733JoeKuoD6Init, - dim1734JoeKuoD6Init, - dim1735JoeKuoD6Init, - dim1736JoeKuoD6Init, - dim1737JoeKuoD6Init, - dim1738JoeKuoD6Init, - dim1739JoeKuoD6Init, - dim1740JoeKuoD6Init, - dim1741JoeKuoD6Init, - dim1742JoeKuoD6Init, - dim1743JoeKuoD6Init, - dim1744JoeKuoD6Init, - dim1745JoeKuoD6Init, - dim1746JoeKuoD6Init, - dim1747JoeKuoD6Init, - dim1748JoeKuoD6Init, - dim1749JoeKuoD6Init, - dim1750JoeKuoD6Init, - dim1751JoeKuoD6Init, - dim1752JoeKuoD6Init, - dim1753JoeKuoD6Init, - dim1754JoeKuoD6Init, - dim1755JoeKuoD6Init, - dim1756JoeKuoD6Init, - dim1757JoeKuoD6Init, - dim1758JoeKuoD6Init, - dim1759JoeKuoD6Init, - dim1760JoeKuoD6Init, - dim1761JoeKuoD6Init, - dim1762JoeKuoD6Init, - dim1763JoeKuoD6Init, - dim1764JoeKuoD6Init, - dim1765JoeKuoD6Init, - dim1766JoeKuoD6Init, - dim1767JoeKuoD6Init, - dim1768JoeKuoD6Init, - dim1769JoeKuoD6Init, - dim1770JoeKuoD6Init, - dim1771JoeKuoD6Init, - dim1772JoeKuoD6Init, - dim1773JoeKuoD6Init, - dim1774JoeKuoD6Init, - dim1775JoeKuoD6Init, - dim1776JoeKuoD6Init, - dim1777JoeKuoD6Init, - dim1778JoeKuoD6Init, - dim1779JoeKuoD6Init, - dim1780JoeKuoD6Init, - dim1781JoeKuoD6Init, - dim1782JoeKuoD6Init, - dim1783JoeKuoD6Init, - dim1784JoeKuoD6Init, - dim1785JoeKuoD6Init, - dim1786JoeKuoD6Init, - dim1787JoeKuoD6Init, - dim1788JoeKuoD6Init, - dim1789JoeKuoD6Init, - dim1790JoeKuoD6Init, - dim1791JoeKuoD6Init, - dim1792JoeKuoD6Init, - dim1793JoeKuoD6Init, - dim1794JoeKuoD6Init, - dim1795JoeKuoD6Init, - dim1796JoeKuoD6Init, - dim1797JoeKuoD6Init, - dim1798JoeKuoD6Init, - dim1799JoeKuoD6Init - }; - - static ulong[] dim1JoeKuoD7Init = { 1, 0 }; - static ulong[] dim2JoeKuoD7Init = { 1, 3, 0 }; - static ulong[] dim3JoeKuoD7Init = { 1, 3, 1, 0 }; - static ulong[] dim4JoeKuoD7Init = { 1, 1, 1, 0 }; - static ulong[] dim5JoeKuoD7Init = { 1, 1, 3, 3, 0 }; - static ulong[] dim6JoeKuoD7Init = { 1, 3, 5, 13, 0 }; - static ulong[] dim7JoeKuoD7Init = { 1, 1, 5, 5, 17, 0 }; - static ulong[] dim8JoeKuoD7Init = { 1, 1, 5, 5, 5, 0 }; - static ulong[] dim9JoeKuoD7Init = { 1, 1, 7, 11, 19, 0 }; - static ulong[] dim10JoeKuoD7Init = { 1, 1, 5, 1, 1, 0 }; - static ulong[] dim11JoeKuoD7Init = { 1, 1, 1, 3, 11, 0 }; - static ulong[] dim12JoeKuoD7Init = { 1, 3, 5, 5, 31, 0 }; - static ulong[] dim13JoeKuoD7Init = { 1, 3, 3, 9, 7, 49, 0 }; - static ulong[] dim14JoeKuoD7Init = { 1, 1, 1, 15, 23, 17, 0 }; - static ulong[] dim15JoeKuoD7Init = { 1, 3, 1, 13, 27, 49, 0 }; - static ulong[] dim16JoeKuoD7Init = { 1, 1, 1, 15, 7, 5, 0 }; - static ulong[] dim17JoeKuoD7Init = { 1, 3, 7, 7, 19, 13, 0 }; - static ulong[] dim18JoeKuoD7Init = { 1, 1, 5, 5, 19, 59, 0 }; - static ulong[] dim19JoeKuoD7Init = { 1, 3, 7, 11, 23, 7, 121, 0 }; - static ulong[] dim20JoeKuoD7Init = { 1, 3, 5, 13, 9, 19, 113, 0 }; - static ulong[] dim21JoeKuoD7Init = { 1, 1, 7, 15, 3, 53, 87, 0 }; - static ulong[] dim22JoeKuoD7Init = { 1, 3, 7, 7, 25, 33, 41, 0 }; - static ulong[] dim23JoeKuoD7Init = { 1, 3, 1, 9, 15, 47, 85, 0 }; - static ulong[] dim24JoeKuoD7Init = { 1, 1, 7, 3, 5, 25, 37, 0 }; - static ulong[] dim25JoeKuoD7Init = { 1, 3, 7, 9, 31, 11, 27, 0 }; - static ulong[] dim26JoeKuoD7Init = { 1, 1, 7, 15, 1, 17, 121, 0 }; - static ulong[] dim27JoeKuoD7Init = { 1, 3, 7, 13, 17, 49, 5, 0 }; - static ulong[] dim28JoeKuoD7Init = { 1, 3, 5, 9, 7, 9, 31, 0 }; - static ulong[] dim29JoeKuoD7Init = { 1, 3, 1, 9, 7, 29, 15, 0 }; - static ulong[] dim30JoeKuoD7Init = { 1, 3, 1, 1, 23, 43, 37, 0 }; - static ulong[] dim31JoeKuoD7Init = { 1, 3, 7, 5, 3, 43, 95, 0 }; - static ulong[] dim32JoeKuoD7Init = { 1, 1, 7, 9, 31, 25, 91, 0 }; - static ulong[] dim33JoeKuoD7Init = { 1, 3, 1, 11, 15, 17, 91, 0 }; - static ulong[] dim34JoeKuoD7Init = { 1, 1, 1, 1, 21, 29, 71, 0 }; - static ulong[] dim35JoeKuoD7Init = { 1, 1, 5, 13, 27, 3, 27, 0 }; - static ulong[] dim36JoeKuoD7Init = { 1, 3, 1, 9, 31, 25, 3, 0 }; - static ulong[] dim37JoeKuoD7Init = { 1, 3, 3, 1, 25, 23, 51, 45, 0 }; - static ulong[] dim38JoeKuoD7Init = { 1, 1, 5, 13, 9, 25, 17, 227, 0 }; - static ulong[] dim39JoeKuoD7Init = { 1, 1, 1, 1, 15, 9, 91, 45, 0 }; - static ulong[] dim40JoeKuoD7Init = { 1, 1, 7, 7, 9, 35, 87, 31, 0 }; - static ulong[] dim41JoeKuoD7Init = { 1, 1, 5, 13, 29, 33, 13, 119, 0 }; - static ulong[] dim42JoeKuoD7Init = { 1, 3, 5, 3, 17, 9, 73, 85, 0 }; - static ulong[] dim43JoeKuoD7Init = { 1, 3, 7, 5, 13, 33, 11, 17, 0 }; - static ulong[] dim44JoeKuoD7Init = { 1, 1, 3, 13, 29, 25, 15, 75, 0 }; - static ulong[] dim45JoeKuoD7Init = { 1, 3, 7, 9, 3, 11, 11, 59, 0 }; - static ulong[] dim46JoeKuoD7Init = { 1, 3, 1, 13, 5, 27, 19, 71, 0 }; - static ulong[] dim47JoeKuoD7Init = { 1, 1, 7, 3, 13, 41, 79, 137, 0 }; - static ulong[] dim48JoeKuoD7Init = { 1, 3, 3, 7, 9, 41, 89, 63, 0 }; - static ulong[] dim49JoeKuoD7Init = { 1, 1, 1, 5, 29, 57, 53, 103, 0 }; - static ulong[] dim50JoeKuoD7Init = { 1, 1, 3, 9, 3, 41, 71, 119, 0 }; - static ulong[] dim51JoeKuoD7Init = { 1, 3, 5, 5, 3, 1, 39, 185, 0 }; - static ulong[] dim52JoeKuoD7Init = { 1, 3, 3, 15, 23, 3, 43, 95, 0 }; - static ulong[] dim53JoeKuoD7Init = { 1, 1, 3, 7, 1, 35, 19, 19, 127, 0 }; - static ulong[] dim54JoeKuoD7Init = { 1, 1, 3, 9, 9, 31, 9, 157, 105, 0 }; - static ulong[] dim55JoeKuoD7Init = { 1, 3, 1, 1, 7, 49, 13, 125, 471, 0 }; - static ulong[] dim56JoeKuoD7Init = { 1, 3, 3, 1, 17, 25, 111, 73, 41, 0 }; - static ulong[] dim57JoeKuoD7Init = { 1, 3, 5, 11, 3, 61, 117, 93, 325, 0 }; - static ulong[] dim58JoeKuoD7Init = { 1, 1, 7, 15, 21, 63, 103, 145, 61, 0 }; - static ulong[] dim59JoeKuoD7Init = { 1, 3, 7, 7, 27, 49, 101, 227, 55, 0 }; - static ulong[] dim60JoeKuoD7Init = { 1, 1, 7, 5, 1, 1, 33, 225, 501, 0 }; - static ulong[] dim61JoeKuoD7Init = { 1, 3, 5, 5, 1, 17, 113, 149, 71, 0 }; - static ulong[] dim62JoeKuoD7Init = { 1, 1, 5, 9, 27, 9, 97, 7, 35, 0 }; - static ulong[] dim63JoeKuoD7Init = { 1, 3, 1, 7, 13, 39, 49, 213, 483, 0 }; - static ulong[] dim64JoeKuoD7Init = { 1, 3, 3, 11, 13, 47, 43, 89, 329, 0 }; - static ulong[] dim65JoeKuoD7Init = { 1, 3, 1, 1, 19, 61, 97, 205, 285, 0 }; - static ulong[] dim66JoeKuoD7Init = { 1, 1, 3, 11, 11, 3, 105, 151, 469, 0 }; - static ulong[] dim67JoeKuoD7Init = { 1, 1, 1, 1, 5, 39, 89, 137, 409, 0 }; - static ulong[] dim68JoeKuoD7Init = { 1, 1, 3, 11, 23, 39, 85, 251, 141, 0 }; - static ulong[] dim69JoeKuoD7Init = { 1, 1, 3, 5, 23, 23, 59, 111, 19, 0 }; - static ulong[] dim70JoeKuoD7Init = { 1, 3, 5, 9, 19, 63, 1, 251, 305, 0 }; - static ulong[] dim71JoeKuoD7Init = { 1, 3, 1, 1, 3, 35, 65, 153, 387, 0 }; - static ulong[] dim72JoeKuoD7Init = { 1, 1, 5, 13, 21, 45, 37, 255, 295, 0 }; - static ulong[] dim73JoeKuoD7Init = { 1, 1, 5, 1, 21, 5, 39, 143, 293, 0 }; - static ulong[] dim74JoeKuoD7Init = { 1, 1, 1, 5, 21, 45, 91, 211, 347, 0 }; - static ulong[] dim75JoeKuoD7Init = { 1, 3, 5, 11, 17, 21, 73, 185, 259, 0 }; - static ulong[] dim76JoeKuoD7Init = { 1, 3, 1, 11, 29, 25, 85, 103, 97, 0 }; - static ulong[] dim77JoeKuoD7Init = { 1, 3, 5, 5, 27, 37, 43, 243, 257, 0 }; - static ulong[] dim78JoeKuoD7Init = { 1, 3, 5, 11, 31, 63, 105, 41, 229, 0 }; - static ulong[] dim79JoeKuoD7Init = { 1, 3, 3, 15, 21, 55, 29, 39, 279, 0 }; - static ulong[] dim80JoeKuoD7Init = { 1, 3, 5, 7, 1, 47, 97, 15, 173, 0 }; - static ulong[] dim81JoeKuoD7Init = { 1, 1, 5, 7, 21, 55, 29, 93, 97, 0 }; - static ulong[] dim82JoeKuoD7Init = { 1, 3, 3, 3, 7, 29, 27, 179, 105, 0 }; - static ulong[] dim83JoeKuoD7Init = { 1, 1, 3, 3, 1, 43, 37, 221, 259, 0 }; - static ulong[] dim84JoeKuoD7Init = { 1, 1, 7, 9, 31, 25, 1, 47, 71, 0 }; - static ulong[] dim85JoeKuoD7Init = { 1, 3, 7, 7, 7, 25, 37, 1, 487, 0 }; - static ulong[] dim86JoeKuoD7Init = { 1, 3, 1, 1, 31, 43, 25, 117, 147, 0 }; - static ulong[] dim87JoeKuoD7Init = { 1, 3, 7, 3, 27, 7, 103, 241, 173, 0 }; - static ulong[] dim88JoeKuoD7Init = { 1, 1, 5, 1, 27, 25, 91, 189, 53, 0 }; - static ulong[] dim89JoeKuoD7Init = { 1, 1, 3, 3, 29, 39, 79, 125, 281, 0 }; - static ulong[] dim90JoeKuoD7Init = { 1, 1, 5, 11, 13, 57, 15, 219, 407, 0 }; - static ulong[] dim91JoeKuoD7Init = { 1, 3, 3, 5, 15, 9, 65, 111, 1, 0 }; - static ulong[] dim92JoeKuoD7Init = { 1, 1, 5, 3, 31, 45, 17, 227, 67, 0 }; - static ulong[] dim93JoeKuoD7Init = { 1, 1, 3, 1, 31, 59, 63, 205, 27, 0 }; - static ulong[] dim94JoeKuoD7Init = { 1, 1, 1, 9, 27, 9, 49, 187, 451, 0 }; - static ulong[] dim95JoeKuoD7Init = { 1, 1, 5, 15, 11, 43, 93, 49, 129, 0 }; - static ulong[] dim96JoeKuoD7Init = { 1, 3, 7, 7, 5, 63, 31, 239, 11, 0 }; - static ulong[] dim97JoeKuoD7Init = { 1, 1, 1, 11, 7, 59, 37, 157, 505, 0 }; - static ulong[] dim98JoeKuoD7Init = { 1, 3, 5, 9, 3, 41, 87, 229, 269, 0 }; - static ulong[] dim99JoeKuoD7Init = { 1, 1, 5, 3, 25, 11, 69, 125, 35, 0 }; - static ulong[] dim100JoeKuoD7Init = { 1, 3, 5, 13, 11, 53, 47, 21, 79, 0 }; - static ulong[] dim101JoeKuoD7Init = { 1, 3, 3, 7, 11, 23, 1, 99, 417, 35, 0 }; - static ulong[] dim102JoeKuoD7Init = { 1, 1, 7, 7, 7, 53, 57, 229, 473, 533, 0 }; - static ulong[] dim103JoeKuoD7Init = { 1, 1, 3, 9, 23, 31, 87, 27, 313, 853, 0 }; - static ulong[] dim104JoeKuoD7Init = { 1, 3, 3, 1, 13, 43, 27, 227, 231, 91, 0 }; - static ulong[] dim105JoeKuoD7Init = { 1, 3, 7, 5, 11, 17, 109, 29, 417, 597, 0 }; - static ulong[] dim106JoeKuoD7Init = { 1, 3, 7, 7, 31, 5, 23, 137, 35, 583, 0 }; - static ulong[] dim107JoeKuoD7Init = { 1, 3, 1, 5, 15, 23, 87, 171, 171, 889, 0 }; - static ulong[] dim108JoeKuoD7Init = { 1, 3, 3, 7, 17, 21, 19, 233, 275, 651, 0 }; - static ulong[] dim109JoeKuoD7Init = { 1, 1, 3, 5, 31, 19, 127, 115, 211, 715, 0 }; - static ulong[] dim110JoeKuoD7Init = { 1, 1, 5, 3, 13, 5, 37, 83, 123, 567, 0 }; - static ulong[] dim111JoeKuoD7Init = { 1, 3, 1, 7, 3, 41, 123, 61, 311, 45, 0 }; - static ulong[] dim112JoeKuoD7Init = { 1, 1, 5, 5, 19, 27, 1, 159, 87, 155, 0 }; - static ulong[] dim113JoeKuoD7Init = { 1, 3, 3, 15, 31, 17, 29, 105, 293, 205, 0 }; - static ulong[] dim114JoeKuoD7Init = { 1, 1, 1, 13, 15, 11, 125, 241, 1, 755, 0 }; - static ulong[] dim115JoeKuoD7Init = { 1, 1, 7, 7, 27, 47, 59, 143, 451, 1005, 0 }; - static ulong[] dim116JoeKuoD7Init = { 1, 3, 1, 11, 19, 37, 49, 105, 127, 683, 0 }; - static ulong[] dim117JoeKuoD7Init = { 1, 1, 1, 1, 11, 31, 9, 15, 355, 951, 0 }; - static ulong[] dim118JoeKuoD7Init = { 1, 1, 7, 15, 5, 19, 69, 51, 121, 695, 0 }; - static ulong[] dim119JoeKuoD7Init = { 1, 3, 1, 9, 15, 33, 125, 63, 191, 773, 0 }; - static ulong[] dim120JoeKuoD7Init = { 1, 1, 3, 1, 11, 13, 67, 123, 143, 427, 0 }; - static ulong[] dim121JoeKuoD7Init = { 1, 3, 7, 7, 17, 45, 73, 209, 501, 781, 0 }; - static ulong[] dim122JoeKuoD7Init = { 1, 1, 3, 5, 21, 25, 31, 229, 107, 447, 0 }; - static ulong[] dim123JoeKuoD7Init = { 1, 3, 3, 5, 15, 39, 19, 111, 221, 35, 0 }; - static ulong[] dim124JoeKuoD7Init = { 1, 3, 5, 7, 7, 23, 111, 201, 469, 859, 0 }; - static ulong[] dim125JoeKuoD7Init = { 1, 3, 1, 9, 7, 55, 1, 57, 245, 865, 0 }; - static ulong[] dim126JoeKuoD7Init = { 1, 1, 5, 11, 19, 17, 63, 107, 423, 977, 0 }; - static ulong[] dim127JoeKuoD7Init = { 1, 1, 3, 5, 23, 35, 59, 143, 403, 469, 0 }; - static ulong[] dim128JoeKuoD7Init = { 1, 3, 3, 9, 29, 11, 11, 137, 341, 669, 0 }; - static ulong[] dim129JoeKuoD7Init = { 1, 3, 5, 5, 31, 29, 73, 25, 21, 543, 0 }; - static ulong[] dim130JoeKuoD7Init = { 1, 1, 5, 3, 17, 47, 69, 103, 49, 869, 0 }; - static ulong[] dim131JoeKuoD7Init = { 1, 1, 3, 9, 1, 5, 69, 45, 73, 533, 0 }; - static ulong[] dim132JoeKuoD7Init = { 1, 1, 1, 11, 13, 11, 61, 71, 397, 919, 0 }; - static ulong[] dim133JoeKuoD7Init = { 1, 1, 7, 11, 1, 3, 21, 127, 263, 597, 0 }; - static ulong[] dim134JoeKuoD7Init = { 1, 3, 1, 9, 3, 31, 41, 179, 499, 313, 0 }; - static ulong[] dim135JoeKuoD7Init = { 1, 1, 7, 11, 5, 43, 33, 41, 53, 917, 0 }; - static ulong[] dim136JoeKuoD7Init = { 1, 3, 3, 9, 1, 63, 35, 139, 169, 945, 0 }; - static ulong[] dim137JoeKuoD7Init = { 1, 1, 7, 3, 31, 13, 51, 105, 333, 703, 0 }; - static ulong[] dim138JoeKuoD7Init = { 1, 1, 5, 3, 5, 5, 127, 103, 465, 989, 0 }; - static ulong[] dim139JoeKuoD7Init = { 1, 1, 3, 1, 31, 3, 87, 41, 511, 713, 0 }; - static ulong[] dim140JoeKuoD7Init = { 1, 1, 7, 1, 7, 29, 19, 237, 235, 531, 0 }; - static ulong[] dim141JoeKuoD7Init = { 1, 1, 7, 13, 21, 11, 111, 51, 461, 525, 0 }; - static ulong[] dim142JoeKuoD7Init = { 1, 3, 3, 13, 27, 49, 123, 241, 365, 137, 0 }; - static ulong[] dim143JoeKuoD7Init = { 1, 1, 7, 13, 17, 43, 43, 115, 483, 291, 0 }; - static ulong[] dim144JoeKuoD7Init = { 1, 1, 3, 7, 5, 17, 127, 167, 371, 417, 0 }; - static ulong[] dim145JoeKuoD7Init = { 1, 3, 7, 9, 11, 21, 123, 29, 133, 9, 0 }; - static ulong[] dim146JoeKuoD7Init = { 1, 3, 1, 7, 13, 35, 99, 161, 45, 347, 0 }; - static ulong[] dim147JoeKuoD7Init = { 1, 1, 1, 7, 15, 21, 31, 131, 441, 635, 0 }; - static ulong[] dim148JoeKuoD7Init = { 1, 1, 3, 7, 21, 63, 119, 175, 183, 189, 0 }; - static ulong[] dim149JoeKuoD7Init = { 1, 3, 7, 3, 17, 39, 21, 201, 31, 747, 0 }; - static ulong[] dim150JoeKuoD7Init = { 1, 1, 5, 15, 7, 23, 127, 169, 341, 975, 0 }; - static ulong[] dim151JoeKuoD7Init = { 1, 3, 3, 15, 27, 39, 67, 111, 501, 343, 0 }; - static ulong[] dim152JoeKuoD7Init = { 1, 3, 7, 15, 13, 3, 99, 145, 259, 579, 0 }; - static ulong[] dim153JoeKuoD7Init = { 1, 1, 5, 13, 27, 45, 9, 229, 139, 1015, 0 }; - static ulong[] dim154JoeKuoD7Init = { 1, 1, 3, 11, 1, 61, 35, 77, 423, 987, 0 }; - static ulong[] dim155JoeKuoD7Init = { 1, 1, 7, 11, 13, 53, 99, 165, 329, 191, 0 }; - static ulong[] dim156JoeKuoD7Init = { 1, 1, 1, 11, 13, 31, 15, 237, 359, 337, 0 }; - static ulong[] dim157JoeKuoD7Init = { 1, 3, 1, 1, 1, 15, 35, 175, 347, 485, 0 }; - static ulong[] dim158JoeKuoD7Init = { 1, 1, 5, 9, 3, 15, 63, 19, 123, 633, 0 }; - static ulong[] dim159JoeKuoD7Init = { 1, 3, 5, 3, 9, 5, 51, 123, 239, 829, 0 }; - static ulong[] dim160JoeKuoD7Init = { 1, 1, 3, 15, 27, 49, 1, 177, 433, 237, 0 }; - static ulong[] dim161JoeKuoD7Init = { 1, 3, 3, 1, 25, 1, 71, 187, 3, 455, 1559, 0 }; - static ulong[] dim162JoeKuoD7Init = { 1, 1, 1, 5, 17, 53, 71, 115, 87, 811, 1559, 0 }; - static ulong[] dim163JoeKuoD7Init = { 1, 3, 3, 9, 3, 5, 93, 233, 413, 105, 335, 0 }; - static ulong[] dim164JoeKuoD7Init = { 1, 3, 7, 5, 13, 33, 45, 45, 255, 691, 1827, 0 }; - static ulong[] dim165JoeKuoD7Init = { 1, 1, 5, 7, 3, 51, 57, 119, 355, 151, 297, 0 }; - static ulong[] dim166JoeKuoD7Init = { 1, 1, 1, 13, 17, 11, 19, 5, 369, 661, 877, 0 }; - static ulong[] dim167JoeKuoD7Init = { 1, 1, 7, 3, 3, 61, 15, 207, 161, 811, 1585, 0 }; - static ulong[] dim168JoeKuoD7Init = { 1, 3, 7, 9, 11, 63, 105, 45, 209, 605, 835, 0 }; - static ulong[] dim169JoeKuoD7Init = { 1, 1, 1, 7, 11, 47, 35, 73, 303, 809, 1813, 0 }; - static ulong[] dim170JoeKuoD7Init = { 1, 1, 1, 1, 9, 35, 69, 219, 5, 281, 1263, 0 }; - static ulong[] dim171JoeKuoD7Init = { 1, 1, 5, 1, 9, 25, 85, 159, 415, 471, 345, 0 }; - static ulong[] dim172JoeKuoD7Init = { 1, 3, 7, 11, 11, 61, 43, 109, 327, 865, 1635, 0 }; - static ulong[] dim173JoeKuoD7Init = { 1, 1, 3, 13, 21, 39, 123, 211, 355, 91, 1481, 0 }; - static ulong[] dim174JoeKuoD7Init = { 1, 3, 1, 15, 17, 39, 69, 149, 133, 779, 575, 0 }; - static ulong[] dim175JoeKuoD7Init = { 1, 3, 5, 9, 15, 49, 7, 183, 25, 823, 971, 0 }; - static ulong[] dim176JoeKuoD7Init = { 1, 3, 1, 7, 31, 63, 9, 187, 211, 473, 485, 0 }; - static ulong[] dim177JoeKuoD7Init = { 1, 3, 7, 11, 9, 1, 35, 177, 435, 307, 1493, 0 }; - static ulong[] dim178JoeKuoD7Init = { 1, 1, 7, 3, 27, 51, 91, 63, 511, 179, 251, 0 }; - static ulong[] dim179JoeKuoD7Init = { 1, 1, 5, 11, 27, 49, 125, 111, 283, 577, 397, 0 }; - static ulong[] dim180JoeKuoD7Init = { 1, 3, 7, 15, 11, 7, 19, 85, 111, 629, 435, 0 }; - static ulong[] dim181JoeKuoD7Init = { 1, 3, 3, 9, 7, 11, 127, 25, 139, 271, 263, 0 }; - static ulong[] dim182JoeKuoD7Init = { 1, 1, 1, 15, 21, 25, 55, 129, 211, 755, 1695, 0 }; - static ulong[] dim183JoeKuoD7Init = { 1, 1, 7, 15, 13, 23, 107, 241, 231, 319, 385, 0 }; - static ulong[] dim184JoeKuoD7Init = { 1, 1, 5, 11, 31, 31, 97, 141, 93, 759, 1199, 0 }; - static ulong[] dim185JoeKuoD7Init = { 1, 3, 5, 9, 25, 15, 63, 79, 321, 53, 1877, 0 }; - static ulong[] dim186JoeKuoD7Init = { 1, 1, 7, 5, 11, 59, 113, 77, 75, 453, 1617, 0 }; - static ulong[] dim187JoeKuoD7Init = { 1, 3, 1, 15, 19, 33, 65, 141, 109, 211, 213, 0 }; - static ulong[] dim188JoeKuoD7Init = { 1, 3, 3, 13, 17, 1, 123, 1, 305, 271, 1835, 0 }; - static ulong[] dim189JoeKuoD7Init = { 1, 3, 7, 7, 9, 61, 83, 75, 355, 595, 773, 0 }; - static ulong[] dim190JoeKuoD7Init = { 1, 3, 5, 13, 31, 53, 97, 193, 95, 933, 535, 0 }; - static ulong[] dim191JoeKuoD7Init = { 1, 1, 3, 11, 21, 47, 95, 31, 399, 115, 265, 0 }; - static ulong[] dim192JoeKuoD7Init = { 1, 3, 3, 3, 19, 43, 97, 29, 259, 671, 1789, 0 }; - static ulong[] dim193JoeKuoD7Init = { 1, 1, 1, 7, 11, 3, 1, 167, 73, 21, 587, 0 }; - static ulong[] dim194JoeKuoD7Init = { 1, 1, 7, 1, 7, 29, 113, 243, 389, 605, 1267, 0 }; - static ulong[] dim195JoeKuoD7Init = { 1, 3, 3, 1, 19, 17, 43, 89, 467, 501, 137, 0 }; - static ulong[] dim196JoeKuoD7Init = { 1, 1, 1, 7, 13, 41, 97, 123, 153, 603, 1469, 0 }; - static ulong[] dim197JoeKuoD7Init = { 1, 3, 5, 3, 25, 29, 45, 231, 489, 305, 1071, 0 }; - static ulong[] dim198JoeKuoD7Init = { 1, 1, 7, 3, 31, 51, 59, 113, 309, 923, 1171, 0 }; - static ulong[] dim199JoeKuoD7Init = { 1, 1, 5, 11, 7, 41, 55, 207, 181, 565, 913, 0 }; - static ulong[] dim200JoeKuoD7Init = { 1, 1, 3, 9, 9, 45, 25, 49, 135, 777, 593, 0 }; - static ulong[] dim201JoeKuoD7Init = { 1, 3, 5, 3, 31, 3, 51, 253, 369, 853, 1985, 0 }; - static ulong[] dim202JoeKuoD7Init = { 1, 3, 1, 3, 25, 7, 89, 193, 153, 835, 341, 0 }; - static ulong[] dim203JoeKuoD7Init = { 1, 3, 1, 15, 29, 51, 1, 159, 77, 423, 1319, 0 }; - static ulong[] dim204JoeKuoD7Init = { 1, 1, 5, 11, 31, 51, 93, 249, 321, 841, 619, 0 }; - static ulong[] dim205JoeKuoD7Init = { 1, 3, 1, 7, 17, 11, 99, 45, 407, 123, 1363, 0 }; - static ulong[] dim206JoeKuoD7Init = { 1, 3, 5, 5, 13, 39, 65, 195, 55, 991, 1105, 0 }; - static ulong[] dim207JoeKuoD7Init = { 1, 1, 5, 11, 13, 11, 79, 239, 93, 683, 1459, 0 }; - static ulong[] dim208JoeKuoD7Init = { 1, 1, 5, 11, 23, 5, 29, 73, 197, 17, 953, 0 }; - static ulong[] dim209JoeKuoD7Init = { 1, 1, 5, 3, 27, 13, 109, 193, 447, 271, 429, 0 }; - static ulong[] dim210JoeKuoD7Init = { 1, 3, 5, 15, 17, 41, 45, 205, 235, 1015, 1129, 0 }; - static ulong[] dim211JoeKuoD7Init = { 1, 3, 7, 7, 5, 33, 121, 23, 265, 199, 525, 0 }; - static ulong[] dim212JoeKuoD7Init = { 1, 1, 3, 5, 19, 35, 17, 177, 351, 935, 1769, 0 }; - static ulong[] dim213JoeKuoD7Init = { 1, 1, 5, 5, 1, 39, 71, 89, 27, 695, 289, 0 }; - static ulong[] dim214JoeKuoD7Init = { 1, 3, 5, 5, 27, 9, 27, 239, 83, 349, 1989, 0 }; - static ulong[] dim215JoeKuoD7Init = { 1, 3, 1, 11, 13, 63, 99, 177, 91, 899, 987, 0 }; - static ulong[] dim216JoeKuoD7Init = { 1, 3, 1, 1, 5, 23, 85, 61, 307, 491, 663, 0 }; - static ulong[] dim217JoeKuoD7Init = { 1, 1, 7, 7, 19, 27, 127, 205, 489, 857, 1077, 0 }; - static ulong[] dim218JoeKuoD7Init = { 1, 1, 3, 1, 1, 45, 43, 93, 445, 391, 1703, 0 }; - static ulong[] dim219JoeKuoD7Init = { 1, 1, 7, 9, 31, 55, 85, 103, 439, 123, 3, 0 }; - static ulong[] dim220JoeKuoD7Init = { 1, 1, 5, 15, 9, 51, 51, 213, 119, 245, 417, 0 }; - static ulong[] dim221JoeKuoD7Init = { 1, 3, 7, 1, 31, 49, 49, 227, 279, 891, 69, 0 }; - static ulong[] dim222JoeKuoD7Init = { 1, 3, 1, 13, 7, 49, 19, 147, 69, 451, 669, 0 }; - static ulong[] dim223JoeKuoD7Init = { 1, 3, 7, 9, 27, 27, 67, 131, 191, 497, 1189, 0 }; - static ulong[] dim224JoeKuoD7Init = { 1, 3, 5, 1, 13, 49, 93, 1, 161, 725, 709, 0 }; - static ulong[] dim225JoeKuoD7Init = { 1, 1, 1, 1, 13, 49, 67, 37, 153, 31, 409, 0 }; - static ulong[] dim226JoeKuoD7Init = { 1, 3, 1, 7, 19, 55, 103, 111, 381, 209, 271, 0 }; - static ulong[] dim227JoeKuoD7Init = { 1, 1, 5, 13, 17, 29, 15, 155, 81, 737, 565, 0 }; - static ulong[] dim228JoeKuoD7Init = { 1, 3, 7, 11, 29, 17, 119, 247, 189, 897, 1385, 0 }; - static ulong[] dim229JoeKuoD7Init = { 1, 1, 7, 13, 15, 51, 71, 85, 211, 839, 1085, 0 }; - static ulong[] dim230JoeKuoD7Init = { 1, 1, 3, 9, 15, 37, 93, 155, 357, 475, 175, 0 }; - static ulong[] dim231JoeKuoD7Init = { 1, 3, 7, 7, 1, 31, 125, 181, 339, 275, 301, 0 }; - static ulong[] dim232JoeKuoD7Init = { 1, 1, 3, 7, 27, 33, 3, 125, 153, 343, 577, 0 }; - static ulong[] dim233JoeKuoD7Init = { 1, 1, 3, 1, 17, 17, 51, 87, 409, 845, 1857, 0 }; - static ulong[] dim234JoeKuoD7Init = { 1, 1, 3, 11, 5, 47, 101, 45, 425, 721, 1303, 0 }; - static ulong[] dim235JoeKuoD7Init = { 1, 3, 1, 15, 9, 57, 15, 7, 479, 611, 1837, 0 }; - static ulong[] dim236JoeKuoD7Init = { 1, 3, 3, 13, 21, 57, 89, 145, 401, 1007, 753, 0 }; - static ulong[] dim237JoeKuoD7Init = { 1, 3, 3, 15, 19, 63, 5, 243, 111, 999, 435, 0 }; - static ulong[] dim238JoeKuoD7Init = { 1, 3, 7, 13, 31, 27, 27, 217, 71, 145, 695, 0 }; - static ulong[] dim239JoeKuoD7Init = { 1, 3, 7, 7, 11, 61, 113, 145, 481, 487, 1609, 0 }; - static ulong[] dim240JoeKuoD7Init = { 1, 1, 5, 13, 7, 51, 55, 1, 307, 219, 475, 0 }; - static ulong[] dim241JoeKuoD7Init = { 1, 3, 5, 5, 21, 27, 77, 193, 263, 37, 1421, 0 }; - static ulong[] dim242JoeKuoD7Init = { 1, 1, 5, 11, 5, 23, 101, 85, 41, 179, 1311, 0 }; - static ulong[] dim243JoeKuoD7Init = { 1, 1, 3, 9, 27, 5, 49, 227, 317, 695, 581, 0 }; - static ulong[] dim244JoeKuoD7Init = { 1, 1, 1, 15, 9, 23, 119, 145, 231, 15, 1349, 0 }; - static ulong[] dim245JoeKuoD7Init = { 1, 3, 1, 5, 1, 17, 37, 247, 261, 993, 173, 0 }; - static ulong[] dim246JoeKuoD7Init = { 1, 3, 1, 15, 31, 19, 23, 189, 353, 445, 1145, 0 }; - static ulong[] dim247JoeKuoD7Init = { 1, 3, 7, 11, 9, 1, 65, 211, 119, 531, 1389, 0 }; - static ulong[] dim248JoeKuoD7Init = { 1, 3, 7, 1, 31, 49, 31, 239, 131, 159, 55, 0 }; - static ulong[] dim249JoeKuoD7Init = { 1, 1, 7, 7, 3, 13, 85, 89, 459, 293, 1621, 0 }; - static ulong[] dim250JoeKuoD7Init = { 1, 1, 7, 7, 23, 55, 79, 61, 499, 915, 1641, 0 }; - static ulong[] dim251JoeKuoD7Init = { 1, 3, 1, 7, 17, 47, 69, 91, 157, 171, 1827, 0 }; - static ulong[] dim252JoeKuoD7Init = { 1, 3, 5, 5, 29, 55, 105, 31, 467, 3, 241, 0 }; - static ulong[] dim253JoeKuoD7Init = { 1, 1, 5, 11, 19, 27, 87, 199, 295, 949, 323, 0 }; - static ulong[] dim254JoeKuoD7Init = { 1, 1, 1, 1, 25, 59, 125, 33, 35, 75, 603, 0 }; - static ulong[] dim255JoeKuoD7Init = { 1, 3, 5, 5, 25, 63, 19, 87, 475, 711, 1549, 0 }; - static ulong[] dim256JoeKuoD7Init = { 1, 3, 3, 7, 11, 35, 29, 193, 27, 757, 133, 0 }; - static ulong[] dim257JoeKuoD7Init = { 1, 1, 5, 13, 9, 29, 21, 229, 137, 111, 1827, 0 }; - static ulong[] dim258JoeKuoD7Init = { 1, 3, 5, 7, 7, 5, 35, 217, 511, 309, 2013, 0 }; - static ulong[] dim259JoeKuoD7Init = { 1, 1, 1, 1, 3, 25, 99, 187, 141, 599, 223, 0 }; - static ulong[] dim260JoeKuoD7Init = { 1, 1, 7, 9, 23, 9, 3, 223, 357, 261, 393, 0 }; - static ulong[] dim261JoeKuoD7Init = { 1, 3, 5, 9, 3, 47, 73, 75, 153, 249, 149, 0 }; - static ulong[] dim262JoeKuoD7Init = { 1, 3, 7, 13, 5, 31, 25, 77, 501, 221, 941, 0 }; - static ulong[] dim263JoeKuoD7Init = { 1, 1, 7, 1, 21, 41, 107, 95, 245, 35, 1843, 0 }; - static ulong[] dim264JoeKuoD7Init = { 1, 3, 3, 3, 19, 59, 95, 51, 211, 647, 61, 0 }; - static ulong[] dim265JoeKuoD7Init = { 1, 3, 3, 15, 31, 9, 91, 191, 395, 161, 601, 0 }; - static ulong[] dim266JoeKuoD7Init = { 1, 3, 1, 7, 25, 11, 45, 147, 457, 457, 1331, 0 }; - static ulong[] dim267JoeKuoD7Init = { 1, 1, 5, 15, 31, 13, 49, 87, 481, 155, 745, 0 }; - static ulong[] dim268JoeKuoD7Init = { 1, 1, 5, 11, 17, 31, 93, 39, 195, 957, 877, 0 }; - static ulong[] dim269JoeKuoD7Init = { 1, 3, 3, 1, 1, 9, 1, 175, 63, 715, 887, 0 }; - static ulong[] dim270JoeKuoD7Init = { 1, 1, 7, 3, 11, 55, 15, 221, 103, 169, 1961, 0 }; - static ulong[] dim271JoeKuoD7Init = { 1, 1, 5, 15, 21, 41, 87, 141, 233, 879, 1869, 0 }; - static ulong[] dim272JoeKuoD7Init = { 1, 3, 5, 13, 13, 15, 127, 29, 103, 533, 925, 0 }; - static ulong[] dim273JoeKuoD7Init = { 1, 3, 1, 5, 23, 59, 1, 93, 97, 979, 1123, 0 }; - static ulong[] dim274JoeKuoD7Init = { 1, 3, 1, 7, 31, 29, 55, 185, 27, 759, 1037, 0 }; - static ulong[] dim275JoeKuoD7Init = { 1, 3, 7, 9, 9, 21, 95, 111, 291, 331, 889, 0 }; - static ulong[] dim276JoeKuoD7Init = { 1, 1, 3, 3, 15, 17, 113, 21, 97, 653, 769, 0 }; - static ulong[] dim277JoeKuoD7Init = { 1, 3, 1, 9, 19, 9, 67, 43, 9, 7, 1751, 0 }; - static ulong[] dim278JoeKuoD7Init = { 1, 1, 3, 9, 29, 15, 103, 69, 249, 465, 1747, 0 }; - static ulong[] dim279JoeKuoD7Init = { 1, 1, 3, 15, 17, 13, 81, 149, 253, 993, 25, 0 }; - static ulong[] dim280JoeKuoD7Init = { 1, 1, 3, 7, 27, 19, 63, 95, 165, 641, 1141, 0 }; - static ulong[] dim281JoeKuoD7Init = { 1, 3, 3, 1, 13, 39, 101, 131, 359, 825, 41, 0 }; - static ulong[] dim282JoeKuoD7Init = { 1, 1, 5, 7, 31, 31, 43, 83, 147, 427, 2031, 0 }; - static ulong[] dim283JoeKuoD7Init = { 1, 3, 5, 9, 27, 33, 109, 45, 123, 121, 485, 0 }; - static ulong[] dim284JoeKuoD7Init = { 1, 1, 3, 9, 27, 35, 13, 161, 363, 651, 1865, 0 }; - static ulong[] dim285JoeKuoD7Init = { 1, 1, 1, 11, 11, 45, 11, 127, 19, 459, 605, 0 }; - static ulong[] dim286JoeKuoD7Init = { 1, 3, 7, 15, 13, 37, 105, 159, 61, 157, 157, 0 }; - static ulong[] dim287JoeKuoD7Init = { 1, 3, 1, 15, 5, 39, 121, 85, 383, 579, 2001, 0 }; - static ulong[] dim288JoeKuoD7Init = { 1, 3, 1, 13, 13, 7, 101, 213, 455, 961, 1327, 0 }; - static ulong[] dim289JoeKuoD7Init = { 1, 3, 5, 13, 31, 39, 49, 33, 267, 783, 67, 0 }; - static ulong[] dim290JoeKuoD7Init = { 1, 1, 3, 9, 31, 43, 45, 85, 1, 187, 899, 0 }; - static ulong[] dim291JoeKuoD7Init = { 1, 1, 7, 1, 23, 11, 93, 227, 41, 1013, 1689, 0 }; - static ulong[] dim292JoeKuoD7Init = { 1, 1, 1, 15, 17, 31, 33, 67, 79, 113, 803, 0 }; - static ulong[] dim293JoeKuoD7Init = { 1, 1, 1, 9, 13, 53, 27, 203, 143, 469, 1435, 0 }; - static ulong[] dim294JoeKuoD7Init = { 1, 1, 5, 1, 19, 1, 119, 37, 135, 797, 1935, 0 }; - static ulong[] dim295JoeKuoD7Init = { 1, 1, 3, 11, 29, 29, 111, 79, 81, 973, 899, 0 }; - static ulong[] dim296JoeKuoD7Init = { 1, 3, 7, 1, 21, 3, 83, 43, 95, 445, 1529, 0 }; - static ulong[] dim297JoeKuoD7Init = { 1, 1, 3, 9, 11, 5, 27, 67, 101, 395, 195, 0 }; - static ulong[] dim298JoeKuoD7Init = { 1, 3, 1, 3, 29, 13, 41, 219, 157, 325, 955, 0 }; - static ulong[] dim299JoeKuoD7Init = { 1, 3, 3, 13, 27, 29, 113, 209, 323, 747, 759, 0 }; - static ulong[] dim300JoeKuoD7Init = { 1, 3, 1, 13, 1, 57, 113, 133, 363, 57, 715, 0 }; - static ulong[] dim301JoeKuoD7Init = { 1, 1, 3, 3, 25, 43, 123, 27, 483, 1023, 739, 0 }; - static ulong[] dim302JoeKuoD7Init = { 1, 1, 3, 13, 27, 43, 117, 217, 55, 977, 487, 0 }; - static ulong[] dim303JoeKuoD7Init = { 1, 1, 1, 3, 25, 31, 95, 67, 7, 19, 321, 0 }; - static ulong[] dim304JoeKuoD7Init = { 1, 3, 1, 3, 25, 7, 17, 123, 487, 709, 971, 0 }; - static ulong[] dim305JoeKuoD7Init = { 1, 3, 5, 11, 15, 9, 127, 129, 35, 123, 1217, 0 }; - static ulong[] dim306JoeKuoD7Init = { 1, 1, 3, 5, 17, 63, 67, 137, 253, 691, 447, 0 }; - static ulong[] dim307JoeKuoD7Init = { 1, 3, 3, 1, 27, 53, 25, 205, 75, 827, 1609, 0 }; - static ulong[] dim308JoeKuoD7Init = { 1, 1, 7, 13, 3, 49, 59, 207, 357, 269, 309, 0 }; - static ulong[] dim309JoeKuoD7Init = { 1, 3, 1, 5, 25, 57, 9, 117, 359, 9, 405, 0 }; - static ulong[] dim310JoeKuoD7Init = { 1, 3, 7, 15, 15, 21, 53, 163, 91, 35, 277, 0 }; - static ulong[] dim311JoeKuoD7Init = { 1, 3, 1, 1, 23, 5, 69, 83, 11, 161, 141, 0 }; - static ulong[] dim312JoeKuoD7Init = { 1, 1, 5, 13, 13, 25, 15, 209, 385, 389, 817, 0 }; - static ulong[] dim313JoeKuoD7Init = { 1, 3, 1, 13, 11, 11, 17, 191, 327, 731, 973, 0 }; - static ulong[] dim314JoeKuoD7Init = { 1, 3, 7, 15, 1, 63, 55, 51, 379, 359, 305, 0 }; - static ulong[] dim315JoeKuoD7Init = { 1, 3, 7, 11, 17, 19, 81, 123, 335, 391, 647, 0 }; - static ulong[] dim316JoeKuoD7Init = { 1, 3, 3, 13, 27, 15, 53, 243, 115, 733, 1095, 0 }; - static ulong[] dim317JoeKuoD7Init = { 1, 1, 1, 3, 5, 47, 111, 153, 479, 133, 723, 0 }; - static ulong[] dim318JoeKuoD7Init = { 1, 1, 3, 1, 15, 47, 85, 27, 449, 673, 931, 0 }; - static ulong[] dim319JoeKuoD7Init = { 1, 3, 1, 5, 23, 23, 15, 21, 113, 1003, 1077, 0 }; - static ulong[] dim320JoeKuoD7Init = { 1, 3, 7, 9, 27, 55, 29, 95, 21, 29, 1409, 0 }; - static ulong[] dim321JoeKuoD7Init = { 1, 1, 5, 5, 19, 53, 5, 135, 219, 607, 151, 0 }; - static ulong[] dim322JoeKuoD7Init = { 1, 1, 5, 1, 29, 31, 83, 103, 493, 227, 423, 0 }; - static ulong[] dim323JoeKuoD7Init = { 1, 3, 5, 13, 23, 3, 111, 147, 333, 159, 983, 0 }; - static ulong[] dim324JoeKuoD7Init = { 1, 3, 5, 7, 13, 1, 45, 57, 111, 459, 1503, 0 }; - static ulong[] dim325JoeKuoD7Init = { 1, 3, 7, 9, 9, 21, 27, 155, 377, 617, 1429, 0 }; - static ulong[] dim326JoeKuoD7Init = { 1, 3, 1, 15, 3, 7, 113, 11, 349, 961, 749, 0 }; - static ulong[] dim327JoeKuoD7Init = { 1, 3, 5, 15, 31, 13, 51, 63, 315, 691, 1351, 0 }; - static ulong[] dim328JoeKuoD7Init = { 1, 1, 5, 1, 21, 51, 5, 53, 215, 199, 891, 0 }; - static ulong[] dim329JoeKuoD7Init = { 1, 1, 3, 1, 23, 19, 37, 29, 263, 341, 453, 0 }; - static ulong[] dim330JoeKuoD7Init = { 1, 3, 3, 1, 13, 37, 113, 121, 483, 879, 1749, 0 }; - static ulong[] dim331JoeKuoD7Init = { 1, 3, 3, 7, 13, 41, 19, 69, 323, 547, 297, 0 }; - static ulong[] dim332JoeKuoD7Init = { 1, 3, 5, 9, 23, 13, 21, 179, 377, 217, 559, 0 }; - static ulong[] dim333JoeKuoD7Init = { 1, 3, 5, 15, 15, 5, 17, 41, 3, 391, 1241, 0 }; - static ulong[] dim334JoeKuoD7Init = { 1, 1, 1, 15, 31, 57, 97, 57, 183, 415, 917, 0 }; - static ulong[] dim335JoeKuoD7Init = { 1, 1, 7, 9, 17, 31, 121, 15, 425, 9, 655, 0 }; - static ulong[] dim336JoeKuoD7Init = { 1, 1, 7, 15, 3, 55, 53, 73, 463, 887, 1999, 0 }; - static ulong[] dim337JoeKuoD7Init = { 1, 1, 1, 7, 3, 25, 17, 5, 55, 833, 1899, 4077, 0 }; - static ulong[] dim338JoeKuoD7Init = { 1, 1, 5, 11, 23, 47, 67, 45, 9, 41, 835, 373, 0 }; - static ulong[] dim339JoeKuoD7Init = { 1, 3, 7, 11, 5, 55, 25, 137, 11, 119, 967, 3969, 0 }; - static ulong[] dim340JoeKuoD7Init = { 1, 3, 3, 13, 3, 5, 17, 11, 259, 7, 1587, 3919, 0 }; - static ulong[] dim341JoeKuoD7Init = { 1, 1, 7, 3, 29, 57, 113, 207, 187, 173, 575, 935, 0 }; - static ulong[] dim342JoeKuoD7Init = { 1, 3, 1, 9, 25, 31, 89, 29, 345, 753, 1675, 85, 0 }; - static ulong[] dim343JoeKuoD7Init = { 1, 1, 3, 1, 9, 41, 91, 245, 63, 995, 1751, 2881, 0 }; - static ulong[] dim344JoeKuoD7Init = { 1, 1, 7, 3, 21, 63, 121, 237, 243, 815, 1507, 265, 0 }; - static ulong[] dim345JoeKuoD7Init = { 1, 1, 1, 1, 23, 27, 121, 215, 381, 317, 669, 357, 0 }; - static ulong[] dim346JoeKuoD7Init = { 1, 3, 1, 3, 1, 45, 87, 19, 43, 915, 1083, 3259, 0 }; - static ulong[] dim347JoeKuoD7Init = { 1, 3, 7, 5, 15, 31, 15, 229, 489, 897, 791, 3019, 0 }; - static ulong[] dim348JoeKuoD7Init = { 1, 3, 3, 5, 25, 19, 89, 211, 413, 839, 2029, 1785, 0 }; - static ulong[] dim349JoeKuoD7Init = { 1, 3, 7, 1, 19, 29, 67, 11, 483, 303, 469, 795, 0 }; - static ulong[] dim350JoeKuoD7Init = { 1, 3, 5, 5, 19, 15, 81, 147, 337, 641, 1863, 2497, 0 }; - static ulong[] dim351JoeKuoD7Init = { 1, 1, 7, 5, 17, 43, 83, 173, 307, 397, 1231, 2275, 0 }; - static ulong[] dim352JoeKuoD7Init = { 1, 1, 1, 9, 27, 49, 61, 29, 169, 811, 171, 1373, 0 }; - static ulong[] dim353JoeKuoD7Init = { 1, 1, 1, 1, 13, 63, 11, 197, 145, 987, 1709, 895, 0 }; - static ulong[] dim354JoeKuoD7Init = { 1, 1, 7, 3, 15, 3, 5, 213, 155, 271, 867, 1665, 0 }; - static ulong[] dim355JoeKuoD7Init = { 1, 1, 3, 1, 23, 51, 99, 49, 83, 159, 1589, 3961, 0 }; - static ulong[] dim356JoeKuoD7Init = { 1, 3, 3, 9, 21, 13, 1, 91, 187, 615, 293, 3791, 0 }; - static ulong[] dim357JoeKuoD7Init = { 1, 3, 1, 5, 19, 43, 107, 235, 339, 65, 579, 2529, 0 }; - static ulong[] dim358JoeKuoD7Init = { 1, 3, 1, 1, 17, 39, 63, 67, 289, 593, 959, 1503, 0 }; - static ulong[] dim359JoeKuoD7Init = { 1, 1, 1, 11, 3, 15, 87, 153, 487, 537, 849, 385, 0 }; - static ulong[] dim360JoeKuoD7Init = { 1, 1, 3, 3, 5, 11, 99, 239, 241, 251, 793, 3677, 0 }; - static ulong[] dim361JoeKuoD7Init = { 1, 3, 7, 7, 13, 21, 111, 113, 69, 861, 1455, 3655, 0 }; - static ulong[] dim362JoeKuoD7Init = { 1, 1, 7, 11, 9, 21, 33, 29, 505, 81, 713, 2545, 0 }; - static ulong[] dim363JoeKuoD7Init = { 1, 3, 1, 11, 5, 29, 83, 73, 377, 611, 1099, 3225, 0 }; - static ulong[] dim364JoeKuoD7Init = { 1, 3, 7, 3, 25, 53, 75, 75, 235, 877, 609, 1535, 0 }; - static ulong[] dim365JoeKuoD7Init = { 1, 1, 1, 1, 29, 45, 27, 13, 437, 317, 581, 1179, 0 }; - static ulong[] dim366JoeKuoD7Init = { 1, 3, 3, 1, 3, 25, 127, 157, 443, 229, 277, 4059, 0 }; - static ulong[] dim367JoeKuoD7Init = { 1, 1, 1, 13, 17, 61, 31, 1, 483, 915, 1085, 1497, 0 }; - static ulong[] dim368JoeKuoD7Init = { 1, 3, 7, 11, 13, 57, 5, 49, 181, 881, 765, 1767, 0 }; - static ulong[] dim369JoeKuoD7Init = { 1, 1, 3, 1, 29, 17, 91, 95, 319, 339, 187, 2427, 0 }; - static ulong[] dim370JoeKuoD7Init = { 1, 3, 7, 5, 1, 17, 33, 181, 165, 237, 815, 3387, 0 }; - static ulong[] dim371JoeKuoD7Init = { 1, 1, 7, 1, 5, 17, 81, 193, 61, 411, 457, 2367, 0 }; - static ulong[] dim372JoeKuoD7Init = { 1, 1, 1, 7, 23, 17, 73, 185, 269, 1017, 299, 1879, 0 }; - static ulong[] dim373JoeKuoD7Init = { 1, 3, 5, 11, 7, 33, 75, 57, 275, 355, 1157, 2297, 0 }; - static ulong[] dim374JoeKuoD7Init = { 1, 3, 5, 7, 13, 7, 69, 25, 411, 319, 1385, 2081, 0 }; - static ulong[] dim375JoeKuoD7Init = { 1, 1, 7, 15, 27, 55, 35, 51, 71, 759, 1071, 51, 0 }; - static ulong[] dim376JoeKuoD7Init = { 1, 3, 5, 7, 29, 3, 25, 19, 123, 717, 1071, 257, 0 }; - static ulong[] dim377JoeKuoD7Init = { 1, 3, 7, 1, 7, 37, 51, 175, 19, 511, 469, 3757, 0 }; - static ulong[] dim378JoeKuoD7Init = { 1, 1, 5, 5, 19, 45, 107, 207, 369, 479, 853, 195, 0 }; - static ulong[] dim379JoeKuoD7Init = { 1, 3, 1, 9, 11, 11, 89, 115, 149, 789, 523, 2949, 0 }; - static ulong[] dim380JoeKuoD7Init = { 1, 3, 1, 11, 15, 53, 123, 167, 471, 355, 1515, 2291, 0 }; - static ulong[] dim381JoeKuoD7Init = { 1, 3, 7, 1, 23, 1, 5, 21, 315, 45, 1901, 3351, 0 }; - static ulong[] dim382JoeKuoD7Init = { 1, 1, 7, 5, 3, 49, 31, 89, 11, 777, 1003, 389, 0 }; - static ulong[] dim383JoeKuoD7Init = { 1, 1, 5, 3, 23, 3, 55, 213, 333, 257, 309, 4079, 0 }; - static ulong[] dim384JoeKuoD7Init = { 1, 3, 3, 7, 9, 29, 103, 41, 161, 253, 681, 1971, 0 }; - static ulong[] dim385JoeKuoD7Init = { 1, 1, 7, 13, 13, 33, 71, 121, 325, 423, 1485, 3205, 0 }; - static ulong[] dim386JoeKuoD7Init = { 1, 3, 1, 7, 9, 55, 69, 201, 111, 561, 1733, 1881, 0 }; - static ulong[] dim387JoeKuoD7Init = { 1, 1, 1, 7, 9, 41, 31, 113, 79, 193, 757, 329, 0 }; - static ulong[] dim388JoeKuoD7Init = { 1, 1, 7, 5, 3, 23, 27, 99, 179, 7, 1087, 27, 0 }; - static ulong[] dim389JoeKuoD7Init = { 1, 3, 3, 7, 13, 23, 9, 61, 157, 641, 299, 2077, 0 }; - static ulong[] dim390JoeKuoD7Init = { 1, 1, 5, 5, 29, 59, 63, 67, 493, 119, 959, 2683, 0 }; - static ulong[] dim391JoeKuoD7Init = { 1, 1, 3, 1, 19, 25, 117, 161, 249, 545, 997, 17, 0 }; - static ulong[] dim392JoeKuoD7Init = { 1, 3, 5, 5, 5, 31, 107, 181, 191, 913, 1911, 2329, 0 }; - static ulong[] dim393JoeKuoD7Init = { 1, 3, 1, 13, 31, 11, 109, 229, 159, 235, 975, 717, 0 }; - static ulong[] dim394JoeKuoD7Init = { 1, 1, 5, 3, 5, 7, 117, 233, 83, 31, 1641, 251, 0 }; - static ulong[] dim395JoeKuoD7Init = { 1, 1, 1, 1, 3, 45, 53, 179, 113, 353, 1805, 1097, 0 }; - static ulong[] dim396JoeKuoD7Init = { 1, 3, 3, 5, 17, 15, 83, 177, 399, 831, 231, 2307, 0 }; - static ulong[] dim397JoeKuoD7Init = { 1, 3, 7, 15, 19, 37, 19, 119, 243, 703, 1813, 2415, 0 }; - static ulong[] dim398JoeKuoD7Init = { 1, 3, 7, 9, 19, 25, 119, 123, 235, 817, 871, 763, 0 }; - static ulong[] dim399JoeKuoD7Init = { 1, 1, 5, 3, 7, 49, 97, 207, 297, 283, 467, 1843, 0 }; - static ulong[] dim400JoeKuoD7Init = { 1, 3, 5, 1, 21, 25, 103, 227, 239, 683, 797, 1763, 0 }; - static ulong[] dim401JoeKuoD7Init = { 1, 1, 5, 11, 27, 27, 127, 185, 137, 449, 1549, 3561, 0 }; - static ulong[] dim402JoeKuoD7Init = { 1, 1, 5, 5, 3, 45, 113, 35, 427, 847, 1761, 1721, 0 }; - static ulong[] dim403JoeKuoD7Init = { 1, 1, 3, 7, 25, 63, 33, 197, 183, 803, 963, 2179, 0 }; - static ulong[] dim404JoeKuoD7Init = { 1, 1, 3, 9, 19, 1, 3, 229, 225, 479, 593, 597, 0 }; - static ulong[] dim405JoeKuoD7Init = { 1, 3, 1, 5, 19, 35, 105, 245, 1, 249, 217, 2917, 0 }; - static ulong[] dim406JoeKuoD7Init = { 1, 3, 1, 1, 11, 3, 59, 51, 249, 135, 419, 3411, 0 }; - static ulong[] dim407JoeKuoD7Init = { 1, 3, 3, 15, 27, 45, 51, 15, 17, 473, 557, 2679, 0 }; - static ulong[] dim408JoeKuoD7Init = { 1, 3, 7, 11, 31, 43, 45, 163, 289, 723, 337, 2817, 0 }; - static ulong[] dim409JoeKuoD7Init = { 1, 1, 3, 11, 11, 51, 73, 101, 217, 255, 1547, 925, 0 }; - static ulong[] dim410JoeKuoD7Init = { 1, 3, 7, 5, 7, 53, 5, 163, 323, 757, 1443, 2703, 0 }; - static ulong[] dim411JoeKuoD7Init = { 1, 1, 5, 15, 19, 35, 23, 129, 199, 303, 1801, 1999, 0 }; - static ulong[] dim412JoeKuoD7Init = { 1, 1, 5, 15, 23, 37, 25, 61, 307, 901, 1117, 1301, 0 }; - static ulong[] dim413JoeKuoD7Init = { 1, 1, 5, 11, 15, 59, 71, 163, 93, 471, 341, 1825, 0 }; - static ulong[] dim414JoeKuoD7Init = { 1, 3, 7, 11, 27, 63, 73, 209, 453, 49, 1161, 1399, 0 }; - static ulong[] dim415JoeKuoD7Init = { 1, 3, 5, 3, 9, 5, 101, 47, 225, 451, 2005, 223, 0 }; - static ulong[] dim416JoeKuoD7Init = { 1, 3, 3, 3, 25, 43, 33, 171, 413, 371, 1133, 1057, 0 }; - static ulong[] dim417JoeKuoD7Init = { 1, 3, 3, 9, 5, 35, 39, 219, 319, 301, 1475, 3155, 0 }; - static ulong[] dim418JoeKuoD7Init = { 1, 3, 5, 15, 17, 39, 123, 165, 337, 17, 679, 3155, 0 }; - static ulong[] dim419JoeKuoD7Init = { 1, 1, 5, 3, 29, 33, 13, 165, 57, 723, 1201, 3523, 0 }; - static ulong[] dim420JoeKuoD7Init = { 1, 1, 1, 9, 25, 23, 67, 139, 321, 555, 723, 1017, 0 }; - static ulong[] dim421JoeKuoD7Init = { 1, 1, 3, 9, 17, 59, 25, 29, 473, 473, 1425, 965, 0 }; - static ulong[] dim422JoeKuoD7Init = { 1, 1, 5, 3, 13, 53, 29, 239, 321, 455, 1539, 1279, 0 }; - static ulong[] dim423JoeKuoD7Init = { 1, 3, 7, 3, 3, 37, 127, 149, 205, 313, 827, 1713, 0 }; - static ulong[] dim424JoeKuoD7Init = { 1, 1, 7, 5, 11, 41, 25, 73, 279, 539, 1761, 2565, 0 }; - static ulong[] dim425JoeKuoD7Init = { 1, 1, 5, 9, 21, 7, 75, 209, 83, 885, 821, 3887, 0 }; - static ulong[] dim426JoeKuoD7Init = { 1, 1, 3, 1, 21, 1, 13, 245, 291, 615, 1747, 1477, 0 }; - static ulong[] dim427JoeKuoD7Init = { 1, 1, 5, 1, 1, 11, 107, 105, 19, 263, 1497, 2311, 0 }; - static ulong[] dim428JoeKuoD7Init = { 1, 1, 5, 5, 15, 15, 105, 171, 143, 879, 1611, 277, 0 }; - static ulong[] dim429JoeKuoD7Init = { 1, 3, 1, 15, 15, 51, 15, 15, 25, 309, 1531, 977, 0 }; - static ulong[] dim430JoeKuoD7Init = { 1, 1, 7, 11, 29, 63, 65, 209, 155, 975, 107, 611, 0 }; - static ulong[] dim431JoeKuoD7Init = { 1, 3, 3, 15, 11, 55, 21, 149, 291, 221, 449, 133, 0 }; - static ulong[] dim432JoeKuoD7Init = { 1, 1, 3, 13, 3, 59, 41, 167, 37, 951, 1561, 2087, 0 }; - static ulong[] dim433JoeKuoD7Init = { 1, 3, 3, 15, 31, 59, 97, 49, 319, 935, 1419, 3215, 0 }; - static ulong[] dim434JoeKuoD7Init = { 1, 1, 3, 1, 27, 17, 91, 91, 327, 395, 1553, 201, 0 }; - static ulong[] dim435JoeKuoD7Init = { 1, 3, 1, 7, 5, 59, 51, 77, 207, 697, 521, 635, 0 }; - static ulong[] dim436JoeKuoD7Init = { 1, 3, 7, 5, 5, 37, 95, 91, 399, 151, 1795, 905, 0 }; - static ulong[] dim437JoeKuoD7Init = { 1, 3, 5, 5, 19, 29, 49, 55, 377, 793, 1429, 3393, 0 }; - static ulong[] dim438JoeKuoD7Init = { 1, 1, 5, 9, 9, 43, 127, 203, 355, 951, 711, 563, 0 }; - static ulong[] dim439JoeKuoD7Init = { 1, 1, 1, 13, 23, 21, 123, 41, 465, 33, 855, 1685, 0 }; - static ulong[] dim440JoeKuoD7Init = { 1, 1, 5, 7, 7, 11, 65, 195, 235, 823, 23, 2723, 0 }; - static ulong[] dim441JoeKuoD7Init = { 1, 1, 7, 7, 9, 41, 93, 109, 475, 587, 27, 1061, 0 }; - static ulong[] dim442JoeKuoD7Init = { 1, 3, 7, 13, 5, 45, 29, 87, 75, 853, 2023, 795, 0 }; - static ulong[] dim443JoeKuoD7Init = { 1, 1, 1, 3, 3, 7, 59, 235, 139, 457, 1855, 3739, 0 }; - static ulong[] dim444JoeKuoD7Init = { 1, 1, 7, 11, 23, 57, 25, 11, 473, 699, 887, 805, 0 }; - static ulong[] dim445JoeKuoD7Init = { 1, 1, 5, 1, 27, 3, 23, 115, 499, 287, 531, 1115, 0 }; - static ulong[] dim446JoeKuoD7Init = { 1, 3, 7, 15, 7, 7, 33, 83, 29, 477, 727, 3037, 0 }; - static ulong[] dim447JoeKuoD7Init = { 1, 1, 1, 9, 27, 43, 113, 203, 413, 649, 869, 3351, 0 }; - static ulong[] dim448JoeKuoD7Init = { 1, 1, 3, 9, 27, 15, 105, 167, 431, 87, 931, 4017, 0 }; - static ulong[] dim449JoeKuoD7Init = { 1, 3, 3, 1, 15, 23, 85, 145, 349, 291, 1137, 605, 0 }; - static ulong[] dim450JoeKuoD7Init = { 1, 3, 3, 15, 31, 53, 127, 25, 15, 277, 575, 1327, 0 }; - static ulong[] dim451JoeKuoD7Init = { 1, 3, 1, 15, 17, 29, 125, 251, 469, 15, 1803, 237, 0 }; - static ulong[] dim452JoeKuoD7Init = { 1, 3, 5, 13, 9, 21, 23, 111, 103, 861, 1137, 3843, 0 }; - static ulong[] dim453JoeKuoD7Init = { 1, 1, 5, 5, 29, 49, 101, 237, 187, 825, 137, 957, 0 }; - static ulong[] dim454JoeKuoD7Init = { 1, 1, 3, 13, 13, 9, 101, 171, 15, 245, 107, 2179, 0 }; - static ulong[] dim455JoeKuoD7Init = { 1, 1, 3, 11, 21, 33, 51, 211, 113, 569, 295, 3593, 0 }; - static ulong[] dim456JoeKuoD7Init = { 1, 3, 1, 5, 9, 5, 119, 159, 211, 121, 1547, 2267, 0 }; - static ulong[] dim457JoeKuoD7Init = { 1, 1, 3, 9, 7, 19, 53, 39, 271, 437, 765, 1511, 0 }; - static ulong[] dim458JoeKuoD7Init = { 1, 1, 1, 9, 3, 5, 119, 83, 161, 275, 1443, 465, 0 }; - static ulong[] dim459JoeKuoD7Init = { 1, 3, 7, 1, 27, 61, 103, 207, 249, 479, 651, 1793, 0 }; - static ulong[] dim460JoeKuoD7Init = { 1, 3, 5, 9, 11, 53, 43, 41, 271, 859, 25, 1401, 0 }; - static ulong[] dim461JoeKuoD7Init = { 1, 3, 1, 5, 9, 39, 87, 21, 425, 561, 861, 2801, 0 }; - static ulong[] dim462JoeKuoD7Init = { 1, 3, 7, 1, 1, 25, 21, 199, 315, 355, 429, 3093, 0 }; - static ulong[] dim463JoeKuoD7Init = { 1, 1, 7, 9, 11, 63, 123, 253, 483, 781, 1685, 977, 0 }; - static ulong[] dim464JoeKuoD7Init = { 1, 1, 1, 15, 17, 57, 19, 251, 173, 519, 1523, 749, 0 }; - static ulong[] dim465JoeKuoD7Init = { 1, 1, 1, 11, 23, 5, 119, 7, 327, 507, 1777, 951, 0 }; - static ulong[] dim466JoeKuoD7Init = { 1, 3, 7, 5, 1, 37, 41, 99, 273, 241, 293, 2289, 0 }; - static ulong[] dim467JoeKuoD7Init = { 1, 3, 3, 9, 3, 51, 65, 115, 159, 341, 1603, 3769, 0 }; - static ulong[] dim468JoeKuoD7Init = { 1, 3, 7, 3, 15, 61, 105, 103, 113, 435, 415, 161, 0 }; - static ulong[] dim469JoeKuoD7Init = { 1, 1, 1, 7, 9, 9, 17, 13, 135, 923, 951, 3603, 0 }; - static ulong[] dim470JoeKuoD7Init = { 1, 1, 3, 13, 9, 31, 25, 175, 449, 541, 745, 2771, 0 }; - static ulong[] dim471JoeKuoD7Init = { 1, 3, 3, 9, 5, 5, 61, 17, 357, 623, 873, 975, 0 }; - static ulong[] dim472JoeKuoD7Init = { 1, 1, 3, 9, 9, 31, 11, 225, 81, 965, 1837, 1975, 0 }; - static ulong[] dim473JoeKuoD7Init = { 1, 1, 7, 1, 3, 57, 69, 169, 11, 633, 885, 535, 0 }; - static ulong[] dim474JoeKuoD7Init = { 1, 1, 1, 9, 21, 63, 73, 233, 151, 519, 1319, 1485, 0 }; - static ulong[] dim475JoeKuoD7Init = { 1, 1, 3, 11, 23, 5, 51, 115, 501, 627, 1875, 3003, 0 }; - static ulong[] dim476JoeKuoD7Init = { 1, 1, 5, 1, 9, 3, 91, 177, 305, 897, 317, 3231, 0 }; - static ulong[] dim477JoeKuoD7Init = { 1, 3, 3, 3, 9, 13, 121, 93, 303, 551, 1087, 905, 0 }; - static ulong[] dim478JoeKuoD7Init = { 1, 1, 5, 7, 1, 63, 123, 177, 87, 489, 1247, 1831, 0 }; - static ulong[] dim479JoeKuoD7Init = { 1, 3, 3, 5, 25, 61, 1, 225, 247, 991, 231, 657, 0 }; - static ulong[] dim480JoeKuoD7Init = { 1, 3, 5, 5, 19, 23, 113, 101, 427, 327, 1859, 3115, 0 }; - static ulong[] dim481JoeKuoD7Init = { 1, 1, 5, 13, 11, 5, 125, 133, 131, 441, 1277, 2583, 7133, 0 }; - static ulong[] dim482JoeKuoD7Init = { 1, 3, 7, 3, 29, 45, 21, 45, 477, 135, 13, 2531, 7657, 0 }; - static ulong[] dim483JoeKuoD7Init = { 1, 1, 7, 9, 19, 3, 47, 37, 491, 237, 1493, 4053, 6025, 0 }; - static ulong[] dim484JoeKuoD7Init = { 1, 1, 5, 7, 15, 51, 23, 181, 63, 755, 761, 3215, 3547, 0 }; - static ulong[] dim485JoeKuoD7Init = { 1, 1, 7, 5, 11, 3, 27, 187, 221, 305, 1941, 1443, 5161, 0 }; - static ulong[] dim486JoeKuoD7Init = { 1, 1, 7, 13, 13, 53, 63, 19, 5, 273, 1305, 919, 3335, 0 }; - static ulong[] dim487JoeKuoD7Init = { 1, 3, 1, 5, 15, 19, 85, 35, 41, 117, 1269, 289, 7433, 0 }; - static ulong[] dim488JoeKuoD7Init = { 1, 3, 7, 9, 27, 49, 119, 101, 57, 267, 1225, 3779, 3357, 0 }; - static ulong[] dim489JoeKuoD7Init = { 1, 3, 5, 11, 5, 1, 9, 251, 411, 19, 763, 1297, 5309, 0 }; - static ulong[] dim490JoeKuoD7Init = { 1, 3, 3, 13, 31, 55, 67, 63, 23, 1021, 199, 2885, 1777, 0 }; - static ulong[] dim491JoeKuoD7Init = { 1, 3, 7, 9, 29, 27, 123, 191, 125, 295, 891, 3507, 2895, 0 }; - static ulong[] dim492JoeKuoD7Init = { 1, 1, 5, 7, 15, 41, 35, 119, 343, 603, 819, 41, 8131, 0 }; - static ulong[] dim493JoeKuoD7Init = { 1, 3, 3, 9, 21, 61, 43, 199, 359, 607, 623, 1579, 7899, 0 }; - static ulong[] dim494JoeKuoD7Init = { 1, 1, 1, 15, 25, 59, 47, 47, 365, 125, 921, 3081, 2081, 0 }; - static ulong[] dim495JoeKuoD7Init = { 1, 3, 3, 1, 23, 23, 111, 53, 395, 945, 59, 3345, 1671, 0 }; - static ulong[] dim496JoeKuoD7Init = { 1, 1, 1, 15, 15, 57, 31, 15, 235, 247, 1645, 3085, 4381, 0 }; - static ulong[] dim497JoeKuoD7Init = { 1, 1, 3, 11, 23, 21, 9, 89, 61, 347, 1423, 3613, 697, 0 }; - static ulong[] dim498JoeKuoD7Init = { 1, 1, 5, 13, 21, 37, 5, 159, 409, 131, 559, 3505, 6631, 0 }; - static ulong[] dim499JoeKuoD7Init = { 1, 3, 3, 11, 23, 51, 97, 247, 137, 183, 1775, 2169, 2869, 0 }; - static ulong[] dim500JoeKuoD7Init = { 1, 1, 7, 7, 29, 53, 109, 75, 327, 755, 825, 329, 5795, 0 }; - static ulong[] dim501JoeKuoD7Init = { 1, 3, 1, 5, 17, 63, 109, 199, 215, 869, 2009, 1153, 1233, 0 }; - static ulong[] dim502JoeKuoD7Init = { 1, 1, 7, 15, 15, 37, 63, 93, 151, 621, 1749, 2211, 5437, 0 }; - static ulong[] dim503JoeKuoD7Init = { 1, 3, 5, 15, 13, 63, 57, 17, 323, 271, 1451, 459, 1187, 0 }; - static ulong[] dim504JoeKuoD7Init = { 1, 1, 5, 5, 31, 47, 15, 83, 389, 857, 505, 635, 7341, 0 }; - static ulong[] dim505JoeKuoD7Init = { 1, 3, 5, 3, 19, 7, 83, 17, 51, 947, 1193, 163, 3895, 0 }; - static ulong[] dim506JoeKuoD7Init = { 1, 1, 7, 1, 23, 5, 115, 113, 445, 703, 747, 963, 7483, 0 }; - static ulong[] dim507JoeKuoD7Init = { 1, 3, 7, 5, 27, 31, 41, 221, 313, 317, 517, 3901, 3937, 0 }; - static ulong[] dim508JoeKuoD7Init = { 1, 3, 5, 11, 29, 41, 23, 249, 169, 51, 1783, 2493, 6109, 0 }; - static ulong[] dim509JoeKuoD7Init = { 1, 1, 5, 13, 23, 23, 85, 71, 321, 623, 207, 3027, 319, 0 }; - static ulong[] dim510JoeKuoD7Init = { 1, 1, 7, 3, 3, 19, 63, 233, 377, 509, 1969, 67, 5059, 0 }; - static ulong[] dim511JoeKuoD7Init = { 1, 1, 3, 7, 13, 27, 39, 67, 483, 587, 1581, 177, 5213, 0 }; - static ulong[] dim512JoeKuoD7Init = { 1, 1, 3, 1, 23, 55, 3, 177, 97, 551, 1733, 1943, 6607, 0 }; - static ulong[] dim513JoeKuoD7Init = { 1, 3, 3, 5, 5, 9, 39, 189, 473, 5, 19, 2793, 6937, 0 }; - static ulong[] dim514JoeKuoD7Init = { 1, 1, 3, 13, 31, 35, 105, 19, 279, 749, 523, 1503, 6231, 0 }; - static ulong[] dim515JoeKuoD7Init = { 1, 3, 1, 9, 11, 59, 89, 153, 155, 219, 549, 2263, 8101, 0 }; - static ulong[] dim516JoeKuoD7Init = { 1, 1, 7, 13, 29, 9, 9, 61, 43, 165, 1395, 91, 2871, 0 }; - static ulong[] dim517JoeKuoD7Init = { 1, 1, 1, 1, 27, 63, 63, 97, 47, 969, 991, 111, 2267, 0 }; - static ulong[] dim518JoeKuoD7Init = { 1, 1, 3, 7, 5, 13, 51, 195, 369, 551, 961, 1123, 7001, 0 }; - static ulong[] dim519JoeKuoD7Init = { 1, 1, 5, 7, 27, 57, 49, 51, 321, 187, 1869, 1181, 6333, 0 }; - static ulong[] dim520JoeKuoD7Init = { 1, 3, 1, 3, 25, 63, 15, 165, 175, 401, 1659, 2345, 683, 0 }; - static ulong[] dim521JoeKuoD7Init = { 1, 1, 7, 1, 9, 41, 121, 123, 49, 303, 229, 2799, 3247, 0 }; - static ulong[] dim522JoeKuoD7Init = { 1, 1, 1, 15, 29, 11, 113, 137, 221, 859, 1601, 215, 6257, 0 }; - static ulong[] dim523JoeKuoD7Init = { 1, 1, 5, 9, 9, 21, 91, 179, 369, 389, 1737, 1235, 3033, 0 }; - static ulong[] dim524JoeKuoD7Init = { 1, 3, 7, 7, 21, 53, 85, 217, 505, 299, 1505, 3289, 3811, 0 }; - static ulong[] dim525JoeKuoD7Init = { 1, 1, 3, 15, 25, 25, 109, 229, 511, 733, 1047, 3295, 307, 0 }; - static ulong[] dim526JoeKuoD7Init = { 1, 1, 3, 15, 29, 25, 21, 201, 353, 97, 231, 3791, 3019, 0 }; - static ulong[] dim527JoeKuoD7Init = { 1, 3, 1, 5, 1, 7, 75, 57, 501, 217, 1647, 1539, 2961, 0 }; - static ulong[] dim528JoeKuoD7Init = { 1, 3, 3, 5, 21, 13, 123, 153, 83, 253, 19, 2469, 5239, 0 }; - static ulong[] dim529JoeKuoD7Init = { 1, 3, 1, 3, 31, 13, 103, 107, 91, 3, 1795, 3587, 3345, 0 }; - static ulong[] dim530JoeKuoD7Init = { 1, 3, 7, 13, 1, 47, 71, 61, 335, 347, 753, 3685, 3895, 0 }; - static ulong[] dim531JoeKuoD7Init = { 1, 1, 1, 11, 25, 53, 73, 65, 203, 923, 661, 1349, 8089, 0 }; - static ulong[] dim532JoeKuoD7Init = { 1, 1, 1, 5, 11, 23, 93, 149, 367, 577, 1095, 993, 5279, 0 }; - static ulong[] dim533JoeKuoD7Init = { 1, 3, 3, 7, 11, 33, 23, 117, 457, 1023, 1789, 3103, 2979, 0 }; - static ulong[] dim534JoeKuoD7Init = { 1, 3, 3, 11, 3, 3, 3, 177, 9, 11, 1753, 3291, 7617, 0 }; - static ulong[] dim535JoeKuoD7Init = { 1, 1, 1, 7, 1, 27, 105, 199, 465, 505, 427, 2605, 7215, 0 }; - static ulong[] dim536JoeKuoD7Init = { 1, 3, 7, 1, 19, 23, 21, 167, 205, 561, 175, 677, 117, 0 }; - static ulong[] dim537JoeKuoD7Init = { 1, 1, 1, 7, 31, 23, 83, 219, 391, 101, 1433, 3973, 4217, 0 }; - static ulong[] dim538JoeKuoD7Init = { 1, 1, 1, 3, 9, 41, 21, 189, 437, 187, 1973, 445, 7439, 0 }; - static ulong[] dim539JoeKuoD7Init = { 1, 1, 5, 7, 21, 3, 53, 9, 295, 331, 2029, 3063, 6095, 0 }; - static ulong[] dim540JoeKuoD7Init = { 1, 1, 1, 7, 19, 9, 119, 247, 371, 635, 1411, 419, 3297, 0 }; - static ulong[] dim541JoeKuoD7Init = { 1, 1, 3, 1, 3, 31, 113, 235, 57, 923, 2033, 1523, 6381, 0 }; - static ulong[] dim542JoeKuoD7Init = { 1, 1, 1, 3, 17, 51, 115, 215, 271, 411, 573, 1761, 1793, 0 }; - static ulong[] dim543JoeKuoD7Init = { 1, 3, 1, 11, 5, 15, 69, 193, 107, 577, 909, 1997, 4503, 0 }; - static ulong[] dim544JoeKuoD7Init = { 1, 3, 5, 3, 1, 3, 17, 227, 381, 931, 1933, 807, 3295, 0 }; - static ulong[] dim545JoeKuoD7Init = { 1, 1, 7, 15, 15, 23, 15, 183, 247, 167, 193, 1643, 4139, 0 }; - static ulong[] dim546JoeKuoD7Init = { 1, 3, 7, 13, 31, 39, 13, 213, 45, 643, 515, 1167, 6991, 0 }; - static ulong[] dim547JoeKuoD7Init = { 1, 3, 1, 9, 15, 7, 5, 223, 53, 413, 403, 3003, 4135, 0 }; - static ulong[] dim548JoeKuoD7Init = { 1, 3, 3, 5, 25, 25, 31, 209, 113, 971, 629, 189, 2309, 0 }; - static ulong[] dim549JoeKuoD7Init = { 1, 3, 3, 3, 23, 29, 37, 39, 73, 797, 589, 1351, 4495, 0 }; - static ulong[] dim550JoeKuoD7Init = { 1, 3, 1, 13, 31, 25, 15, 147, 351, 541, 493, 1361, 3151, 0 }; - static ulong[] dim551JoeKuoD7Init = { 1, 3, 5, 9, 31, 45, 43, 125, 503, 987, 1485, 521, 957, 0 }; - static ulong[] dim552JoeKuoD7Init = { 1, 1, 1, 5, 1, 51, 7, 189, 111, 735, 993, 2313, 7027, 0 }; - static ulong[] dim553JoeKuoD7Init = { 1, 1, 7, 1, 5, 11, 123, 241, 325, 337, 1369, 3515, 8077, 0 }; - static ulong[] dim554JoeKuoD7Init = { 1, 3, 3, 13, 9, 57, 89, 89, 439, 803, 545, 1097, 2443, 0 }; - static ulong[] dim555JoeKuoD7Init = { 1, 3, 5, 7, 1, 31, 23, 121, 19, 469, 887, 3925, 6591, 0 }; - static ulong[] dim556JoeKuoD7Init = { 1, 1, 3, 7, 11, 39, 95, 65, 39, 407, 1187, 2803, 643, 0 }; - static ulong[] dim557JoeKuoD7Init = { 1, 3, 7, 3, 23, 43, 97, 39, 463, 929, 469, 255, 7219, 0 }; - static ulong[] dim558JoeKuoD7Init = { 1, 1, 5, 5, 21, 47, 99, 117, 233, 921, 801, 1105, 2993, 0 }; - static ulong[] dim559JoeKuoD7Init = { 1, 3, 7, 5, 7, 1, 33, 61, 389, 969, 389, 2081, 4215, 0 }; - static ulong[] dim560JoeKuoD7Init = { 1, 1, 1, 7, 15, 5, 103, 115, 59, 699, 1287, 3023, 7599, 0 }; - static ulong[] dim561JoeKuoD7Init = { 1, 3, 7, 15, 23, 49, 19, 85, 219, 837, 15, 1213, 1011, 0 }; - static ulong[] dim562JoeKuoD7Init = { 1, 3, 7, 3, 9, 19, 55, 247, 97, 125, 1377, 3107, 1787, 0 }; - static ulong[] dim563JoeKuoD7Init = { 1, 3, 5, 7, 31, 13, 35, 53, 269, 603, 729, 1827, 1083, 0 }; - static ulong[] dim564JoeKuoD7Init = { 1, 1, 5, 11, 7, 55, 81, 61, 3, 119, 995, 1721, 3205, 0 }; - static ulong[] dim565JoeKuoD7Init = { 1, 1, 7, 13, 11, 57, 81, 63, 271, 1001, 1901, 471, 2217, 0 }; - static ulong[] dim566JoeKuoD7Init = { 1, 1, 5, 1, 1, 47, 79, 175, 145, 615, 1393, 137, 589, 0 }; - static ulong[] dim567JoeKuoD7Init = { 1, 1, 7, 11, 25, 47, 93, 81, 157, 913, 1117, 819, 8079, 0 }; - static ulong[] dim568JoeKuoD7Init = { 1, 1, 7, 1, 23, 51, 85, 101, 41, 115, 303, 1721, 6515, 0 }; - static ulong[] dim569JoeKuoD7Init = { 1, 3, 5, 13, 23, 31, 1, 31, 63, 595, 611, 3153, 7865, 0 }; - static ulong[] dim570JoeKuoD7Init = { 1, 1, 1, 9, 17, 35, 53, 53, 421, 537, 557, 2735, 7813, 0 }; - static ulong[] dim571JoeKuoD7Init = { 1, 3, 3, 11, 7, 17, 105, 1, 201, 45, 1517, 3303, 3287, 0 }; - static ulong[] dim572JoeKuoD7Init = { 1, 1, 7, 15, 15, 63, 45, 129, 81, 901, 1735, 3551, 2885, 0 }; - static ulong[] dim573JoeKuoD7Init = { 1, 1, 5, 15, 21, 9, 63, 133, 245, 807, 1425, 961, 7425, 0 }; - static ulong[] dim574JoeKuoD7Init = { 1, 3, 7, 15, 27, 25, 41, 93, 253, 345, 875, 1663, 5713, 0 }; - static ulong[] dim575JoeKuoD7Init = { 1, 3, 1, 1, 9, 61, 117, 183, 381, 739, 1739, 3285, 747, 0 }; - static ulong[] dim576JoeKuoD7Init = { 1, 3, 5, 15, 7, 49, 39, 233, 465, 511, 1853, 637, 6823, 0 }; - static ulong[] dim577JoeKuoD7Init = { 1, 3, 3, 15, 29, 19, 1, 71, 109, 959, 1575, 3225, 3951, 0 }; - static ulong[] dim578JoeKuoD7Init = { 1, 3, 5, 7, 3, 21, 23, 25, 423, 507, 617, 2175, 7331, 0 }; - static ulong[] dim579JoeKuoD7Init = { 1, 1, 5, 5, 31, 19, 111, 139, 217, 301, 1845, 1789, 5935, 0 }; - static ulong[] dim580JoeKuoD7Init = { 1, 3, 1, 11, 19, 63, 53, 47, 493, 181, 709, 3601, 6163, 0 }; - static ulong[] dim581JoeKuoD7Init = { 1, 3, 3, 9, 7, 57, 57, 89, 25, 757, 1959, 285, 2121, 0 }; - static ulong[] dim582JoeKuoD7Init = { 1, 3, 5, 13, 13, 23, 25, 61, 481, 473, 1933, 1861, 881, 0 }; - static ulong[] dim583JoeKuoD7Init = { 1, 3, 1, 15, 11, 27, 53, 243, 439, 221, 1281, 1129, 6685, 0 }; - static ulong[] dim584JoeKuoD7Init = { 1, 1, 3, 7, 11, 55, 11, 99, 153, 517, 985, 3533, 1363, 0 }; - static ulong[] dim585JoeKuoD7Init = { 1, 1, 3, 3, 11, 7, 95, 193, 161, 183, 1417, 187, 4787, 0 }; - static ulong[] dim586JoeKuoD7Init = { 1, 1, 3, 13, 13, 21, 1, 183, 257, 393, 831, 2149, 2219, 0 }; - static ulong[] dim587JoeKuoD7Init = { 1, 1, 3, 9, 1, 19, 9, 95, 65, 57, 1999, 125, 2181, 0 }; - static ulong[] dim588JoeKuoD7Init = { 1, 1, 3, 11, 3, 29, 57, 249, 93, 143, 1163, 2635, 837, 0 }; - static ulong[] dim589JoeKuoD7Init = { 1, 1, 1, 3, 19, 3, 61, 151, 115, 601, 1085, 2505, 4171, 0 }; - static ulong[] dim590JoeKuoD7Init = { 1, 1, 5, 11, 19, 35, 89, 117, 5, 197, 1763, 415, 5455, 0 }; - static ulong[] dim591JoeKuoD7Init = { 1, 3, 3, 13, 1, 41, 77, 127, 93, 785, 269, 915, 5723, 0 }; - static ulong[] dim592JoeKuoD7Init = { 1, 3, 7, 5, 25, 39, 77, 77, 499, 931, 1707, 3401, 5707, 0 }; - static ulong[] dim593JoeKuoD7Init = { 1, 1, 7, 13, 7, 41, 99, 3, 463, 433, 651, 4079, 409, 0 }; - static ulong[] dim594JoeKuoD7Init = { 1, 1, 5, 3, 25, 25, 51, 211, 269, 867, 1403, 517, 4371, 0 }; - static ulong[] dim595JoeKuoD7Init = { 1, 3, 1, 15, 23, 53, 53, 41, 269, 571, 525, 2309, 431, 0 }; - static ulong[] dim596JoeKuoD7Init = { 1, 1, 5, 5, 19, 25, 125, 133, 249, 555, 781, 2853, 2185, 0 }; - static ulong[] dim597JoeKuoD7Init = { 1, 3, 1, 13, 27, 59, 47, 67, 197, 865, 101, 2291, 6219, 0 }; - static ulong[] dim598JoeKuoD7Init = { 1, 1, 7, 7, 5, 43, 95, 209, 407, 821, 215, 2371, 5059, 0 }; - static ulong[] dim599JoeKuoD7Init = { 1, 3, 7, 1, 7, 25, 75, 239, 327, 969, 575, 2519, 3515, 0 }; - static ulong[] dim600JoeKuoD7Init = { 1, 3, 7, 3, 3, 13, 105, 1, 319, 549, 1003, 3441, 185, 0 }; - static ulong[] dim601JoeKuoD7Init = { 1, 3, 7, 9, 29, 17, 75, 95, 407, 199, 1609, 3537, 7293, 0 }; - static ulong[] dim602JoeKuoD7Init = { 1, 1, 5, 7, 15, 27, 39, 175, 431, 905, 925, 3277, 8029, 0 }; - static ulong[] dim603JoeKuoD7Init = { 1, 3, 1, 3, 3, 19, 73, 87, 107, 605, 45, 3267, 3033, 0 }; - static ulong[] dim604JoeKuoD7Init = { 1, 3, 1, 1, 31, 9, 73, 151, 71, 929, 1995, 739, 1483, 0 }; - static ulong[] dim605JoeKuoD7Init = { 1, 1, 7, 3, 7, 55, 27, 177, 225, 333, 663, 4065, 2559, 0 }; - static ulong[] dim606JoeKuoD7Init = { 1, 3, 3, 5, 21, 61, 121, 159, 269, 267, 1307, 1213, 5057, 0 }; - static ulong[] dim607JoeKuoD7Init = { 1, 3, 3, 15, 3, 35, 29, 243, 199, 695, 1225, 3437, 7451, 0 }; - static ulong[] dim608JoeKuoD7Init = { 1, 3, 3, 9, 15, 23, 15, 43, 383, 95, 239, 945, 5339, 0 }; - static ulong[] dim609JoeKuoD7Init = { 1, 1, 5, 9, 23, 11, 81, 93, 493, 435, 1291, 873, 5101, 0 }; - static ulong[] dim610JoeKuoD7Init = { 1, 1, 5, 7, 23, 11, 89, 95, 203, 533, 583, 981, 2029, 0 }; - static ulong[] dim611JoeKuoD7Init = { 1, 1, 7, 3, 27, 57, 59, 161, 361, 511, 1723, 1893, 4113, 0 }; - static ulong[] dim612JoeKuoD7Init = { 1, 3, 7, 15, 27, 5, 7, 213, 509, 483, 1645, 3487, 2927, 0 }; - static ulong[] dim613JoeKuoD7Init = { 1, 3, 5, 13, 17, 47, 87, 25, 331, 793, 1467, 875, 7147, 0 }; - static ulong[] dim614JoeKuoD7Init = { 1, 3, 5, 1, 29, 51, 21, 223, 289, 461, 1153, 579, 2621, 0 }; - static ulong[] dim615JoeKuoD7Init = { 1, 1, 1, 5, 9, 9, 69, 21, 257, 679, 1031, 809, 1633, 0 }; - static ulong[] dim616JoeKuoD7Init = { 1, 1, 3, 13, 3, 59, 27, 193, 507, 407, 831, 1921, 4411, 0 }; - static ulong[] dim617JoeKuoD7Init = { 1, 1, 1, 9, 19, 61, 77, 163, 103, 35, 803, 2327, 7349, 0 }; - static ulong[] dim618JoeKuoD7Init = { 1, 1, 7, 1, 5, 19, 49, 79, 469, 595, 625, 333, 4861, 0 }; - static ulong[] dim619JoeKuoD7Init = { 1, 1, 3, 13, 9, 17, 97, 229, 263, 63, 1907, 2493, 1001, 0 }; - static ulong[] dim620JoeKuoD7Init = { 1, 3, 3, 11, 25, 23, 111, 51, 7, 551, 1669, 2495, 3409, 0 }; - static ulong[] dim621JoeKuoD7Init = { 1, 1, 3, 13, 5, 39, 115, 179, 473, 179, 2047, 467, 5797, 0 }; - static ulong[] dim622JoeKuoD7Init = { 1, 1, 7, 9, 21, 3, 9, 245, 29, 457, 101, 253, 5757, 0 }; - static ulong[] dim623JoeKuoD7Init = { 1, 1, 3, 5, 1, 11, 123, 29, 43, 259, 1387, 2973, 2509, 0 }; - static ulong[] dim624JoeKuoD7Init = { 1, 3, 7, 9, 15, 35, 85, 165, 91, 793, 1963, 595, 1721, 0 }; - static ulong[] dim625JoeKuoD7Init = { 1, 3, 7, 11, 29, 29, 79, 33, 439, 635, 1639, 803, 847, 0 }; - static ulong[] dim626JoeKuoD7Init = { 1, 1, 3, 5, 29, 9, 121, 239, 33, 535, 1957, 1459, 7997, 0 }; - static ulong[] dim627JoeKuoD7Init = { 1, 3, 1, 9, 7, 15, 11, 91, 495, 939, 1597, 4011, 97, 0 }; - static ulong[] dim628JoeKuoD7Init = { 1, 3, 5, 7, 27, 1, 115, 29, 345, 665, 1433, 3291, 1431, 0 }; - static ulong[] dim629JoeKuoD7Init = { 1, 3, 5, 11, 21, 27, 127, 55, 401, 787, 405, 715, 5385, 0 }; - static ulong[] dim630JoeKuoD7Init = { 1, 3, 5, 7, 7, 59, 109, 221, 179, 217, 1045, 1979, 4003, 0 }; - static ulong[] dim631JoeKuoD7Init = { 1, 1, 5, 9, 17, 57, 73, 219, 369, 235, 43, 65, 919, 0 }; - static ulong[] dim632JoeKuoD7Init = { 1, 3, 3, 13, 19, 29, 73, 7, 405, 691, 1007, 341, 7153, 0 }; - static ulong[] dim633JoeKuoD7Init = { 1, 1, 1, 9, 1, 17, 67, 101, 33, 851, 1227, 41, 8057, 0 }; - static ulong[] dim634JoeKuoD7Init = { 1, 1, 3, 15, 21, 37, 43, 161, 63, 27, 855, 3983, 7661, 0 }; - static ulong[] dim635JoeKuoD7Init = { 1, 3, 3, 3, 25, 11, 85, 127, 309, 979, 1071, 3485, 3513, 0 }; - static ulong[] dim636JoeKuoD7Init = { 1, 1, 1, 1, 21, 51, 37, 87, 71, 923, 1983, 1013, 4677, 0 }; - static ulong[] dim637JoeKuoD7Init = { 1, 1, 1, 3, 29, 13, 93, 193, 207, 229, 185, 2109, 8085, 0 }; - static ulong[] dim638JoeKuoD7Init = { 1, 3, 5, 5, 15, 43, 101, 27, 185, 541, 1371, 1487, 11, 0 }; - static ulong[] dim639JoeKuoD7Init = { 1, 1, 7, 7, 11, 35, 83, 163, 3, 391, 343, 2931, 1183, 0 }; - static ulong[] dim640JoeKuoD7Init = { 1, 1, 1, 7, 5, 1, 109, 195, 389, 679, 571, 121, 2669, 0 }; - static ulong[] dim641JoeKuoD7Init = { 1, 1, 5, 13, 11, 11, 47, 105, 389, 661, 113, 2849, 2861, 0 }; - static ulong[] dim642JoeKuoD7Init = { 1, 3, 7, 7, 27, 3, 33, 105, 81, 817, 691, 1017, 4477, 0 }; - static ulong[] dim643JoeKuoD7Init = { 1, 3, 7, 15, 19, 63, 11, 179, 473, 695, 1033, 363, 1479, 0 }; - static ulong[] dim644JoeKuoD7Init = { 1, 1, 1, 5, 23, 33, 121, 101, 349, 599, 1821, 3975, 263, 0 }; - static ulong[] dim645JoeKuoD7Init = { 1, 3, 1, 11, 21, 1, 115, 123, 367, 497, 609, 1473, 515, 0 }; - static ulong[] dim646JoeKuoD7Init = { 1, 3, 5, 5, 13, 49, 63, 63, 137, 39, 1281, 1289, 6687, 0 }; - static ulong[] dim647JoeKuoD7Init = { 1, 3, 3, 3, 9, 49, 11, 205, 451, 163, 125, 2639, 1921, 0 }; - static ulong[] dim648JoeKuoD7Init = { 1, 1, 7, 5, 5, 29, 67, 33, 169, 133, 599, 2559, 6495, 0 }; - static ulong[] dim649JoeKuoD7Init = { 1, 3, 5, 13, 21, 47, 119, 39, 389, 695, 717, 1003, 4107, 0 }; - static ulong[] dim650JoeKuoD7Init = { 1, 1, 1, 7, 23, 49, 113, 245, 485, 291, 1431, 3577, 1787, 0 }; - static ulong[] dim651JoeKuoD7Init = { 1, 1, 5, 11, 27, 59, 127, 205, 177, 73, 935, 2041, 6899, 0 }; - static ulong[] dim652JoeKuoD7Init = { 1, 3, 7, 13, 27, 41, 115, 121, 239, 939, 1963, 2045, 2457, 0 }; - static ulong[] dim653JoeKuoD7Init = { 1, 3, 1, 11, 23, 51, 13, 177, 51, 145, 651, 3817, 2399, 0 }; - static ulong[] dim654JoeKuoD7Init = { 1, 3, 1, 3, 11, 35, 119, 251, 303, 673, 1475, 1415, 3809, 0 }; - static ulong[] dim655JoeKuoD7Init = { 1, 1, 3, 3, 31, 25, 117, 87, 19, 491, 1681, 2291, 3559, 0 }; - static ulong[] dim656JoeKuoD7Init = { 1, 1, 3, 15, 25, 13, 83, 243, 499, 77, 1809, 81, 4211, 0 }; - static ulong[] dim657JoeKuoD7Init = { 1, 1, 7, 3, 27, 7, 119, 141, 305, 323, 1679, 1143, 2277, 0 }; - static ulong[] dim658JoeKuoD7Init = { 1, 3, 1, 7, 27, 31, 31, 219, 55, 437, 1113, 2801, 1409, 0 }; - static ulong[] dim659JoeKuoD7Init = { 1, 3, 5, 7, 25, 51, 77, 255, 211, 265, 1597, 3883, 5913, 0 }; - static ulong[] dim660JoeKuoD7Init = { 1, 3, 3, 1, 23, 55, 21, 243, 329, 221, 901, 1363, 1449, 0 }; - static ulong[] dim661JoeKuoD7Init = { 1, 1, 7, 3, 7, 53, 63, 143, 503, 295, 135, 4037, 6363, 0 }; - static ulong[] dim662JoeKuoD7Init = { 1, 3, 1, 7, 7, 35, 7, 19, 437, 361, 807, 277, 6335, 0 }; - static ulong[] dim663JoeKuoD7Init = { 1, 3, 5, 5, 5, 53, 121, 219, 447, 453, 1001, 339, 3959, 0 }; - static ulong[] dim664JoeKuoD7Init = { 1, 1, 7, 13, 27, 29, 107, 255, 385, 539, 1787, 3091, 6319, 0 }; - static ulong[] dim665JoeKuoD7Init = { 1, 1, 3, 5, 1, 57, 15, 93, 331, 155, 107, 3295, 7081, 0 }; - static ulong[] dim666JoeKuoD7Init = { 1, 1, 5, 15, 1, 35, 57, 249, 171, 309, 1413, 2677, 1593, 0 }; - static ulong[] dim667JoeKuoD7Init = { 1, 1, 7, 7, 27, 51, 107, 233, 163, 317, 1815, 2443, 3431, 0 }; - static ulong[] dim668JoeKuoD7Init = { 1, 1, 3, 5, 13, 31, 119, 25, 339, 671, 1143, 2317, 1963, 0 }; - static ulong[] dim669JoeKuoD7Init = { 1, 3, 7, 11, 15, 39, 15, 135, 183, 445, 1607, 2397, 7609, 0 }; - static ulong[] dim670JoeKuoD7Init = { 1, 3, 5, 7, 13, 61, 29, 5, 309, 1009, 1241, 3471, 4505, 0 }; - static ulong[] dim671JoeKuoD7Init = { 1, 1, 7, 9, 7, 39, 13, 67, 421, 169, 1751, 2939, 3315, 0 }; - static ulong[] dim672JoeKuoD7Init = { 1, 1, 7, 9, 5, 35, 91, 59, 195, 621, 449, 2245, 3379, 0 }; - static ulong[] dim673JoeKuoD7Init = { 1, 1, 3, 9, 27, 23, 87, 181, 171, 37, 1137, 597, 7443, 0 }; - static ulong[] dim674JoeKuoD7Init = { 1, 1, 1, 13, 15, 41, 109, 81, 149, 709, 1537, 2349, 3999, 0 }; - static ulong[] dim675JoeKuoD7Init = { 1, 3, 1, 3, 9, 27, 93, 211, 239, 391, 411, 1329, 4213, 0 }; - static ulong[] dim676JoeKuoD7Init = { 1, 3, 5, 15, 9, 33, 19, 105, 89, 181, 157, 461, 6505, 0 }; - static ulong[] dim677JoeKuoD7Init = { 1, 3, 5, 15, 15, 3, 113, 79, 49, 463, 299, 1621, 2719, 0 }; - static ulong[] dim678JoeKuoD7Init = { 1, 1, 5, 13, 23, 13, 57, 161, 347, 483, 1521, 3611, 4111, 0 }; - static ulong[] dim679JoeKuoD7Init = { 1, 1, 7, 13, 15, 21, 79, 145, 329, 649, 1809, 1925, 7157, 0 }; - static ulong[] dim680JoeKuoD7Init = { 1, 1, 3, 1, 29, 5, 35, 229, 375, 789, 481, 1863, 6467, 0 }; - static ulong[] dim681JoeKuoD7Init = { 1, 3, 7, 15, 1, 19, 39, 3, 327, 721, 1763, 963, 4397, 0 }; - static ulong[] dim682JoeKuoD7Init = { 1, 3, 1, 3, 3, 51, 97, 1, 109, 337, 535, 2795, 1155, 0 }; - static ulong[] dim683JoeKuoD7Init = { 1, 3, 5, 13, 5, 55, 91, 147, 395, 141, 947, 2647, 1193, 0 }; - static ulong[] dim684JoeKuoD7Init = { 1, 1, 7, 11, 31, 49, 71, 175, 231, 81, 155, 3257, 173, 0 }; - static ulong[] dim685JoeKuoD7Init = { 1, 3, 5, 13, 15, 27, 71, 43, 267, 611, 2041, 1127, 3905, 0 }; - static ulong[] dim686JoeKuoD7Init = { 1, 1, 7, 15, 3, 63, 25, 129, 409, 837, 1601, 2387, 5063, 0 }; - static ulong[] dim687JoeKuoD7Init = { 1, 3, 3, 7, 19, 63, 27, 141, 423, 751, 669, 1945, 3015, 0 }; - static ulong[] dim688JoeKuoD7Init = { 1, 1, 3, 11, 15, 59, 103, 123, 49, 71, 929, 3495, 3591, 0 }; - static ulong[] dim689JoeKuoD7Init = { 1, 1, 3, 5, 9, 17, 49, 3, 67, 63, 1645, 585, 83, 0 }; - static ulong[] dim690JoeKuoD7Init = { 1, 3, 3, 3, 25, 7, 103, 109, 241, 501, 2043, 139, 3865, 0 }; - static ulong[] dim691JoeKuoD7Init = { 1, 3, 1, 5, 19, 41, 35, 223, 351, 853, 961, 2963, 3315, 0 }; - static ulong[] dim692JoeKuoD7Init = { 1, 1, 3, 11, 9, 61, 103, 95, 393, 131, 611, 177, 635, 0 }; - static ulong[] dim693JoeKuoD7Init = { 1, 1, 7, 9, 15, 27, 107, 35, 211, 299, 923, 2629, 2585, 0 }; - static ulong[] dim694JoeKuoD7Init = { 1, 1, 3, 3, 9, 57, 89, 161, 323, 123, 1969, 3545, 5149, 0 }; - static ulong[] dim695JoeKuoD7Init = { 1, 3, 7, 9, 25, 15, 39, 7, 81, 503, 1549, 227, 7267, 0 }; - static ulong[] dim696JoeKuoD7Init = { 1, 1, 1, 1, 29, 41, 77, 131, 181, 555, 1165, 563, 5197, 0 }; - static ulong[] dim697JoeKuoD7Init = { 1, 3, 3, 11, 15, 11, 69, 183, 113, 651, 1265, 1741, 8025, 0 }; - static ulong[] dim698JoeKuoD7Init = { 1, 3, 7, 13, 15, 61, 113, 181, 305, 669, 1903, 575, 6561, 0 }; - static ulong[] dim699JoeKuoD7Init = { 1, 1, 3, 1, 27, 63, 103, 21, 387, 803, 1611, 1793, 1011, 0 }; - static ulong[] dim700JoeKuoD7Init = { 1, 1, 1, 9, 19, 41, 61, 153, 387, 509, 1771, 1715, 4643, 0 }; - static ulong[] dim701JoeKuoD7Init = { 1, 3, 1, 9, 9, 23, 99, 157, 185, 457, 1485, 3153, 6361, 0 }; - static ulong[] dim702JoeKuoD7Init = { 1, 1, 3, 9, 15, 3, 71, 95, 353, 549, 1269, 3451, 403, 0 }; - static ulong[] dim703JoeKuoD7Init = { 1, 3, 5, 5, 17, 45, 49, 249, 185, 367, 1499, 2921, 7485, 0 }; - static ulong[] dim704JoeKuoD7Init = { 1, 3, 1, 13, 1, 61, 57, 95, 213, 333, 603, 697, 6737, 0 }; - static ulong[] dim705JoeKuoD7Init = { 1, 1, 1, 7, 31, 37, 45, 71, 339, 629, 1181, 979, 1473, 0 }; - static ulong[] dim706JoeKuoD7Init = { 1, 3, 7, 5, 7, 5, 9, 139, 89, 683, 569, 1887, 2173, 0 }; - static ulong[] dim707JoeKuoD7Init = { 1, 3, 1, 11, 19, 7, 33, 65, 299, 791, 1281, 3793, 7019, 0 }; - static ulong[] dim708JoeKuoD7Init = { 1, 3, 7, 7, 5, 45, 11, 247, 335, 199, 17, 2829, 2811, 0 }; - static ulong[] dim709JoeKuoD7Init = { 1, 1, 7, 7, 9, 37, 17, 37, 385, 81, 1455, 1921, 6957, 0 }; - static ulong[] dim710JoeKuoD7Init = { 1, 1, 1, 1, 23, 53, 13, 7, 475, 167, 1573, 2235, 4097, 0 }; - static ulong[] dim711JoeKuoD7Init = { 1, 3, 3, 9, 23, 53, 107, 63, 457, 723, 53, 3025, 3153, 0 }; - static ulong[] dim712JoeKuoD7Init = { 1, 3, 1, 5, 21, 39, 1, 123, 293, 275, 1441, 2897, 4645, 0 }; - static ulong[] dim713JoeKuoD7Init = { 1, 3, 3, 7, 21, 5, 93, 63, 427, 47, 559, 2383, 4137, 0 }; - static ulong[] dim714JoeKuoD7Init = { 1, 3, 3, 1, 13, 39, 81, 63, 353, 937, 679, 79, 3319, 0 }; - static ulong[] dim715JoeKuoD7Init = { 1, 1, 7, 3, 19, 3, 57, 207, 115, 439, 835, 389, 4413, 0 }; - static ulong[] dim716JoeKuoD7Init = { 1, 3, 5, 7, 21, 57, 81, 137, 265, 845, 843, 3083, 4453, 0 }; - static ulong[] dim717JoeKuoD7Init = { 1, 1, 1, 13, 13, 29, 77, 181, 483, 871, 1739, 3859, 5005, 0 }; - static ulong[] dim718JoeKuoD7Init = { 1, 1, 1, 13, 9, 45, 73, 73, 427, 783, 617, 1771, 5953, 0 }; - static ulong[] dim719JoeKuoD7Init = { 1, 1, 5, 13, 31, 39, 83, 17, 275, 419, 1405, 3189, 7751, 0 }; - static ulong[] dim720JoeKuoD7Init = { 1, 1, 5, 13, 15, 17, 15, 67, 455, 477, 1911, 2225, 4095, 0 }; - static ulong[] dim721JoeKuoD7Init = { 1, 1, 1, 1, 5, 39, 73, 205, 331, 819, 1499, 1243, 7369, 0 }; - static ulong[] dim722JoeKuoD7Init = { 1, 1, 1, 1, 1, 49, 11, 167, 489, 169, 1683, 2999, 4371, 0 }; - static ulong[] dim723JoeKuoD7Init = { 1, 1, 7, 9, 13, 7, 29, 105, 155, 85, 1311, 617, 1793, 0 }; - static ulong[] dim724JoeKuoD7Init = { 1, 1, 5, 5, 13, 3, 71, 27, 83, 145, 89, 691, 1081, 0 }; - static ulong[] dim725JoeKuoD7Init = { 1, 1, 1, 1, 9, 43, 23, 63, 43, 263, 1849, 1963, 1043, 0 }; - static ulong[] dim726JoeKuoD7Init = { 1, 3, 3, 1, 25, 15, 17, 211, 453, 385, 349, 789, 787, 0 }; - static ulong[] dim727JoeKuoD7Init = { 1, 3, 5, 11, 1, 63, 83, 63, 317, 841, 1779, 669, 253, 0 }; - static ulong[] dim728JoeKuoD7Init = { 1, 3, 3, 5, 7, 49, 67, 69, 167, 29, 217, 1759, 6167, 0 }; - static ulong[] dim729JoeKuoD7Init = { 1, 1, 7, 1, 15, 63, 43, 3, 183, 577, 1301, 1479, 4189, 0 }; - static ulong[] dim730JoeKuoD7Init = { 1, 3, 1, 13, 29, 57, 103, 253, 45, 661, 1593, 1993, 523, 0 }; - static ulong[] dim731JoeKuoD7Init = { 1, 3, 3, 15, 25, 17, 11, 71, 213, 287, 627, 2699, 4909, 0 }; - static ulong[] dim732JoeKuoD7Init = { 1, 1, 3, 9, 11, 53, 117, 59, 225, 469, 109, 583, 4677, 0 }; - static ulong[] dim733JoeKuoD7Init = { 1, 3, 7, 15, 27, 41, 109, 37, 153, 885, 1339, 2783, 7833, 0 }; - static ulong[] dim734JoeKuoD7Init = { 1, 3, 1, 7, 5, 47, 5, 233, 507, 953, 1359, 2505, 6943, 0 }; - static ulong[] dim735JoeKuoD7Init = { 1, 1, 7, 5, 11, 21, 33, 207, 17, 621, 1943, 597, 3993, 0 }; - static ulong[] dim736JoeKuoD7Init = { 1, 3, 5, 3, 13, 55, 11, 247, 321, 533, 715, 2941, 6435, 0 }; - static ulong[] dim737JoeKuoD7Init = { 1, 3, 7, 15, 19, 3, 59, 1, 473, 17, 691, 747, 3917, 0 }; - static ulong[] dim738JoeKuoD7Init = { 1, 3, 7, 1, 25, 49, 11, 185, 185, 821, 1857, 3927, 2641, 0 }; - static ulong[] dim739JoeKuoD7Init = { 1, 1, 1, 11, 27, 31, 47, 33, 63, 935, 1709, 1495, 3869, 0 }; - static ulong[] dim740JoeKuoD7Init = { 1, 3, 3, 3, 23, 35, 73, 171, 207, 535, 751, 3693, 3015, 0 }; - static ulong[] dim741JoeKuoD7Init = { 1, 3, 5, 9, 11, 9, 101, 183, 83, 507, 15, 3993, 3631, 0 }; - static ulong[] dim742JoeKuoD7Init = { 1, 1, 3, 1, 5, 13, 41, 239, 355, 463, 997, 1163, 651, 0 }; - static ulong[] dim743JoeKuoD7Init = { 1, 1, 1, 11, 19, 25, 21, 233, 315, 1009, 1433, 2281, 4685, 0 }; - static ulong[] dim744JoeKuoD7Init = { 1, 1, 5, 5, 17, 11, 31, 47, 47, 873, 1957, 2307, 1757, 0 }; - static ulong[] dim745JoeKuoD7Init = { 1, 1, 3, 15, 1, 43, 93, 27, 315, 357, 787, 3843, 4615, 0 }; - static ulong[] dim746JoeKuoD7Init = { 1, 3, 1, 13, 13, 41, 67, 137, 241, 707, 1207, 1923, 2753, 0 }; - static ulong[] dim747JoeKuoD7Init = { 1, 1, 1, 3, 1, 15, 21, 175, 21, 917, 625, 543, 7235, 0 }; - static ulong[] dim748JoeKuoD7Init = { 1, 1, 7, 15, 3, 49, 97, 195, 443, 689, 1393, 2385, 4111, 0 }; - static ulong[] dim749JoeKuoD7Init = { 1, 1, 1, 3, 19, 53, 55, 243, 491, 213, 1371, 3867, 5323, 0 }; - static ulong[] dim750JoeKuoD7Init = { 1, 3, 1, 1, 9, 47, 7, 169, 151, 53, 1481, 3689, 2539, 0 }; - static ulong[] dim751JoeKuoD7Init = { 1, 1, 7, 9, 31, 7, 49, 27, 57, 769, 687, 1007, 3619, 0 }; - static ulong[] dim752JoeKuoD7Init = { 1, 3, 3, 9, 1, 49, 29, 153, 273, 965, 719, 4023, 1755, 0 }; - static ulong[] dim753JoeKuoD7Init = { 1, 3, 7, 1, 23, 29, 85, 179, 137, 237, 1639, 3759, 5533, 0 }; - static ulong[] dim754JoeKuoD7Init = { 1, 3, 1, 3, 7, 3, 1, 107, 259, 827, 799, 2677, 1677, 0 }; - static ulong[] dim755JoeKuoD7Init = { 1, 1, 1, 5, 9, 51, 89, 255, 97, 419, 703, 3903, 833, 0 }; - static ulong[] dim756JoeKuoD7Init = { 1, 3, 5, 3, 21, 27, 115, 75, 329, 747, 1949, 1309, 3611, 0 }; - static ulong[] dim757JoeKuoD7Init = { 1, 3, 1, 3, 13, 3, 21, 5, 337, 757, 1765, 667, 5607, 0 }; - static ulong[] dim758JoeKuoD7Init = { 1, 1, 5, 1, 19, 29, 113, 7, 51, 283, 1987, 3939, 583, 0 }; - static ulong[] dim759JoeKuoD7Init = { 1, 1, 3, 3, 23, 13, 9, 187, 251, 899, 85, 701, 2597, 0 }; - static ulong[] dim760JoeKuoD7Init = { 1, 3, 3, 7, 1, 15, 83, 183, 471, 533, 1119, 3157, 827, 0 }; - static ulong[] dim761JoeKuoD7Init = { 1, 3, 7, 11, 27, 49, 117, 57, 337, 603, 1247, 3957, 1739, 0 }; - static ulong[] dim762JoeKuoD7Init = { 1, 1, 1, 9, 29, 23, 123, 215, 479, 459, 361, 305, 237, 0 }; - static ulong[] dim763JoeKuoD7Init = { 1, 3, 5, 11, 1, 27, 103, 241, 493, 441, 1171, 3625, 3369, 0 }; - static ulong[] dim764JoeKuoD7Init = { 1, 3, 3, 9, 15, 59, 13, 225, 485, 493, 97, 2705, 7077, 0 }; - static ulong[] dim765JoeKuoD7Init = { 1, 3, 3, 1, 5, 27, 85, 135, 451, 745, 613, 1443, 6047, 0 }; - static ulong[] dim766JoeKuoD7Init = { 1, 1, 5, 7, 5, 41, 57, 167, 105, 721, 365, 833, 4485, 0 }; - static ulong[] dim767JoeKuoD7Init = { 1, 1, 3, 1, 19, 13, 119, 161, 475, 935, 1707, 2971, 6797, 0 }; - static ulong[] dim768JoeKuoD7Init = { 1, 3, 1, 15, 19, 59, 23, 29, 339, 671, 2027, 545, 6197, 0 }; - static ulong[] dim769JoeKuoD7Init = { 1, 1, 7, 3, 7, 41, 3, 169, 479, 567, 865, 2481, 3979, 0 }; - static ulong[] dim770JoeKuoD7Init = { 1, 3, 1, 13, 25, 23, 59, 175, 17, 291, 1283, 1405, 4939, 0 }; - static ulong[] dim771JoeKuoD7Init = { 1, 1, 1, 13, 13, 21, 127, 75, 275, 549, 971, 2019, 199, 0 }; - static ulong[] dim772JoeKuoD7Init = { 1, 1, 3, 3, 9, 61, 47, 23, 51, 589, 73, 265, 7315, 0 }; - static ulong[] dim773JoeKuoD7Init = { 1, 1, 5, 1, 3, 21, 15, 33, 443, 831, 375, 3045, 4215, 0 }; - static ulong[] dim774JoeKuoD7Init = { 1, 1, 7, 1, 27, 47, 123, 9, 131, 487, 393, 2959, 1509, 0 }; - static ulong[] dim775JoeKuoD7Init = { 1, 3, 7, 9, 15, 49, 61, 77, 65, 411, 293, 3827, 5723, 0 }; - static ulong[] dim776JoeKuoD7Init = { 1, 3, 7, 9, 17, 33, 97, 207, 227, 679, 1157, 1237, 2203, 0 }; - static ulong[] dim777JoeKuoD7Init = { 1, 1, 5, 1, 31, 31, 23, 59, 363, 225, 827, 2757, 1979, 0 }; - static ulong[] dim778JoeKuoD7Init = { 1, 1, 1, 11, 13, 31, 19, 27, 225, 901, 727, 2491, 3075, 0 }; - static ulong[] dim779JoeKuoD7Init = { 1, 3, 7, 9, 17, 9, 63, 117, 331, 887, 407, 111, 125, 0 }; - static ulong[] dim780JoeKuoD7Init = { 1, 3, 3, 13, 5, 25, 37, 61, 241, 15, 559, 1981, 3585, 0 }; - static ulong[] dim781JoeKuoD7Init = { 1, 1, 3, 9, 13, 57, 9, 189, 135, 485, 105, 327, 7233, 0 }; - static ulong[] dim782JoeKuoD7Init = { 1, 3, 7, 11, 11, 37, 13, 139, 93, 233, 1171, 165, 4151, 0 }; - static ulong[] dim783JoeKuoD7Init = { 1, 1, 3, 9, 7, 61, 81, 243, 111, 681, 859, 2163, 7019, 0 }; - static ulong[] dim784JoeKuoD7Init = { 1, 3, 1, 5, 31, 57, 85, 105, 323, 729, 131, 2055, 1893, 0 }; - static ulong[] dim785JoeKuoD7Init = { 1, 3, 7, 15, 17, 55, 35, 211, 341, 281, 613, 697, 6479, 0 }; - static ulong[] dim786JoeKuoD7Init = { 1, 1, 1, 1, 9, 35, 107, 47, 243, 917, 683, 1333, 7797, 0 }; - static ulong[] dim787JoeKuoD7Init = { 1, 3, 5, 7, 31, 15, 9, 11, 109, 509, 973, 3817, 2877, 0 }; - static ulong[] dim788JoeKuoD7Init = { 1, 1, 3, 15, 31, 21, 43, 79, 367, 201, 549, 1335, 7231, 0 }; - static ulong[] dim789JoeKuoD7Init = { 1, 1, 3, 5, 23, 21, 63, 207, 333, 395, 925, 705, 8143, 0 }; - static ulong[] dim790JoeKuoD7Init = { 1, 3, 7, 5, 13, 23, 93, 123, 317, 511, 867, 1791, 5621, 0 }; - static ulong[] dim791JoeKuoD7Init = { 1, 3, 3, 3, 1, 1, 61, 133, 23, 885, 1281, 3115, 2717, 0 }; - static ulong[] dim792JoeKuoD7Init = { 1, 3, 7, 13, 5, 3, 59, 59, 453, 787, 1933, 2813, 6405, 0 }; - static ulong[] dim793JoeKuoD7Init = { 1, 3, 7, 9, 7, 39, 85, 65, 33, 85, 1597, 17, 3779, 0 }; - static ulong[] dim794JoeKuoD7Init = { 1, 1, 7, 1, 3, 33, 85, 129, 249, 845, 1481, 3249, 7207, 0 }; - static ulong[] dim795JoeKuoD7Init = { 1, 1, 7, 3, 9, 5, 51, 79, 241, 173, 567, 3047, 6779, 0 }; - static ulong[] dim796JoeKuoD7Init = { 1, 3, 1, 1, 1, 49, 29, 243, 95, 609, 1887, 407, 7875, 0 }; - static ulong[] dim797JoeKuoD7Init = { 1, 1, 1, 15, 29, 55, 69, 171, 337, 701, 1255, 1889, 3365, 0 }; - static ulong[] dim798JoeKuoD7Init = { 1, 1, 1, 5, 11, 27, 3, 167, 325, 397, 545, 2097, 1323, 0 }; - static ulong[] dim799JoeKuoD7Init = { 1, 1, 1, 11, 7, 3, 17, 47, 227, 573, 713, 975, 5991, 0 }; - static ulong[] dim800JoeKuoD7Init = { 1, 3, 1, 15, 7, 55, 71, 41, 195, 227, 821, 3209, 1363, 0 }; - static ulong[] dim801JoeKuoD7Init = { 1, 1, 1, 9, 7, 49, 105, 5, 441, 629, 201, 2951, 5757, 0 }; - static ulong[] dim802JoeKuoD7Init = { 1, 1, 1, 7, 13, 5, 5, 31, 355, 107, 1937, 3553, 697, 0 }; - static ulong[] dim803JoeKuoD7Init = { 1, 3, 3, 7, 23, 59, 109, 185, 289, 257, 1055, 3221, 6445, 0 }; - static ulong[] dim804JoeKuoD7Init = { 1, 3, 7, 7, 3, 27, 61, 85, 383, 93, 639, 1113, 1511, 0 }; - static ulong[] dim805JoeKuoD7Init = { 1, 3, 3, 7, 17, 29, 31, 255, 57, 557, 721, 4015, 7587, 0 }; - static ulong[] dim806JoeKuoD7Init = { 1, 1, 7, 9, 23, 15, 89, 85, 201, 177, 571, 2691, 4521, 0 }; - static ulong[] dim807JoeKuoD7Init = { 1, 1, 5, 9, 9, 25, 91, 75, 405, 13, 587, 2299, 7879, 0 }; - static ulong[] dim808JoeKuoD7Init = { 1, 1, 5, 15, 3, 59, 109, 175, 411, 309, 787, 2979, 5385, 0 }; - static ulong[] dim809JoeKuoD7Init = { 1, 3, 5, 1, 9, 21, 109, 109, 179, 955, 423, 3637, 3283, 0 }; - static ulong[] dim810JoeKuoD7Init = { 1, 3, 1, 1, 7, 51, 31, 83, 273, 545, 1063, 1463, 1857, 0 }; - static ulong[] dim811JoeKuoD7Init = { 1, 3, 5, 9, 1, 51, 49, 241, 365, 423, 1299, 3533, 1771, 0 }; - static ulong[] dim812JoeKuoD7Init = { 1, 1, 7, 15, 25, 21, 95, 221, 65, 335, 697, 759, 4331, 0 }; - static ulong[] dim813JoeKuoD7Init = { 1, 1, 5, 11, 15, 53, 17, 7, 461, 543, 233, 3993, 725, 0 }; - static ulong[] dim814JoeKuoD7Init = { 1, 3, 5, 1, 13, 3, 53, 213, 5, 709, 883, 3261, 855, 0 }; - static ulong[] dim815JoeKuoD7Init = { 1, 3, 1, 13, 1, 33, 61, 255, 385, 793, 525, 929, 4263, 0 }; - static ulong[] dim816JoeKuoD7Init = { 1, 1, 1, 11, 1, 33, 97, 235, 427, 1021, 1683, 2821, 1347, 0 }; - static ulong[] dim817JoeKuoD7Init = { 1, 3, 1, 9, 15, 7, 39, 163, 13, 535, 1259, 653, 7359, 0 }; - static ulong[] dim818JoeKuoD7Init = { 1, 3, 5, 15, 31, 27, 19, 255, 341, 509, 1775, 1493, 6977, 0 }; - static ulong[] dim819JoeKuoD7Init = { 1, 1, 5, 15, 3, 23, 53, 221, 271, 729, 1013, 101, 2837, 0 }; - static ulong[] dim820JoeKuoD7Init = { 1, 1, 7, 3, 19, 63, 83, 149, 385, 813, 1783, 4021, 3645, 0 }; - static ulong[] dim821JoeKuoD7Init = { 1, 1, 5, 7, 11, 57, 121, 97, 479, 33, 579, 1009, 1821, 0 }; - static ulong[] dim822JoeKuoD7Init = { 1, 3, 5, 15, 5, 25, 69, 159, 441, 661, 151, 103, 2659, 0 }; - static ulong[] dim823JoeKuoD7Init = { 1, 1, 5, 7, 11, 7, 15, 159, 19, 457, 1873, 3017, 3927, 0 }; - static ulong[] dim824JoeKuoD7Init = { 1, 1, 5, 11, 9, 43, 73, 187, 107, 603, 387, 3713, 853, 0 }; - static ulong[] dim825JoeKuoD7Init = { 1, 1, 1, 15, 29, 55, 87, 247, 283, 11, 927, 3313, 5147, 0 }; - static ulong[] dim826JoeKuoD7Init = { 1, 1, 1, 5, 27, 25, 1, 123, 19, 237, 1171, 1731, 7079, 0 }; - static ulong[] dim827JoeKuoD7Init = { 1, 1, 5, 7, 29, 43, 15, 91, 61, 329, 1343, 1349, 471, 0 }; - static ulong[] dim828JoeKuoD7Init = { 1, 3, 7, 11, 11, 7, 25, 143, 277, 791, 775, 3711, 7115, 0 }; - static ulong[] dim829JoeKuoD7Init = { 1, 1, 5, 5, 29, 27, 53, 241, 399, 165, 1347, 1661, 4495, 0 }; - static ulong[] dim830JoeKuoD7Init = { 1, 3, 7, 3, 21, 7, 73, 61, 155, 635, 1095, 3295, 7109, 0 }; - static ulong[] dim831JoeKuoD7Init = { 1, 1, 3, 11, 5, 39, 11, 167, 317, 317, 161, 2141, 1327, 0 }; - static ulong[] dim832JoeKuoD7Init = { 1, 1, 1, 7, 23, 45, 59, 13, 107, 47, 2001, 1491, 4463, 0 }; - static ulong[] dim833JoeKuoD7Init = { 1, 3, 3, 15, 27, 63, 41, 143, 503, 711, 277, 2523, 6331, 0 }; - static ulong[] dim834JoeKuoD7Init = { 1, 1, 1, 15, 13, 49, 121, 107, 145, 769, 699, 3793, 2333, 0 }; - static ulong[] dim835JoeKuoD7Init = { 1, 1, 1, 11, 17, 7, 57, 139, 17, 433, 1053, 1279, 833, 0 }; - static ulong[] dim836JoeKuoD7Init = { 1, 3, 7, 3, 21, 19, 61, 229, 271, 831, 495, 1663, 2109, 0 }; - static ulong[] dim837JoeKuoD7Init = { 1, 3, 3, 11, 17, 27, 23, 153, 151, 309, 1935, 3993, 4149, 0 }; - static ulong[] dim838JoeKuoD7Init = { 1, 3, 1, 1, 11, 29, 33, 77, 357, 543, 217, 893, 2989, 0 }; - static ulong[] dim839JoeKuoD7Init = { 1, 3, 3, 13, 21, 25, 121, 211, 491, 983, 1395, 2879, 1173, 0 }; - static ulong[] dim840JoeKuoD7Init = { 1, 1, 1, 11, 31, 61, 45, 125, 21, 175, 1869, 403, 579, 0 }; - static ulong[] dim841JoeKuoD7Init = { 1, 3, 1, 11, 27, 5, 47, 211, 149, 753, 301, 933, 3339, 0 }; - static ulong[] dim842JoeKuoD7Init = { 1, 1, 5, 15, 7, 57, 105, 243, 27, 629, 337, 1917, 2653, 0 }; - static ulong[] dim843JoeKuoD7Init = { 1, 1, 1, 1, 27, 27, 45, 39, 249, 167, 2031, 3427, 6051, 0 }; - static ulong[] dim844JoeKuoD7Init = { 1, 1, 5, 5, 9, 13, 55, 167, 473, 371, 677, 2171, 1859, 0 }; - static ulong[] dim845JoeKuoD7Init = { 1, 3, 7, 13, 21, 49, 25, 193, 507, 531, 1639, 3181, 2763, 0 }; - static ulong[] dim846JoeKuoD7Init = { 1, 3, 3, 11, 15, 3, 115, 163, 63, 383, 835, 2507, 5525, 0 }; - static ulong[] dim847JoeKuoD7Init = { 1, 1, 1, 1, 1, 63, 59, 75, 293, 609, 59, 1729, 4909, 0 }; - static ulong[] dim848JoeKuoD7Init = { 1, 1, 1, 15, 11, 57, 59, 109, 465, 285, 1973, 505, 4447, 0 }; - static ulong[] dim849JoeKuoD7Init = { 1, 1, 1, 13, 11, 63, 87, 149, 185, 493, 831, 2927, 11, 0 }; - static ulong[] dim850JoeKuoD7Init = { 1, 1, 3, 3, 3, 19, 111, 199, 371, 411, 659, 1191, 6279, 0 }; - static ulong[] dim851JoeKuoD7Init = { 1, 1, 5, 9, 21, 57, 73, 189, 307, 515, 1797, 2073, 1085, 0 }; - static ulong[] dim852JoeKuoD7Init = { 1, 1, 5, 9, 23, 21, 21, 23, 487, 715, 449, 2157, 5063, 0 }; - static ulong[] dim853JoeKuoD7Init = { 1, 1, 1, 11, 27, 27, 121, 61, 281, 805, 55, 2111, 2193, 0 }; - static ulong[] dim854JoeKuoD7Init = { 1, 3, 7, 3, 5, 45, 23, 71, 369, 875, 1185, 1611, 2009, 0 }; - static ulong[] dim855JoeKuoD7Init = { 1, 3, 1, 15, 17, 59, 17, 99, 403, 103, 847, 849, 569, 0 }; - static ulong[] dim856JoeKuoD7Init = { 1, 3, 5, 7, 7, 13, 47, 125, 35, 615, 281, 1443, 1199, 0 }; - static ulong[] dim857JoeKuoD7Init = { 1, 3, 3, 15, 13, 63, 73, 191, 137, 257, 1609, 409, 5135, 0 }; - static ulong[] dim858JoeKuoD7Init = { 1, 3, 3, 11, 13, 57, 63, 189, 367, 7, 1261, 211, 2223, 0 }; - static ulong[] dim859JoeKuoD7Init = { 1, 1, 1, 3, 31, 21, 117, 135, 231, 981, 857, 3737, 1631, 0 }; - static ulong[] dim860JoeKuoD7Init = { 1, 1, 3, 5, 11, 13, 55, 193, 99, 969, 1093, 1575, 2367, 0 }; - static ulong[] dim861JoeKuoD7Init = { 1, 3, 5, 9, 9, 45, 81, 139, 479, 561, 1983, 3117, 2539, 0 }; - static ulong[] dim862JoeKuoD7Init = { 1, 1, 3, 11, 19, 37, 107, 125, 415, 653, 517, 2191, 415, 0 }; - static ulong[] dim863JoeKuoD7Init = { 1, 3, 3, 9, 13, 41, 59, 193, 205, 485, 1439, 1333, 2519, 0 }; - static ulong[] dim864JoeKuoD7Init = { 1, 3, 7, 13, 9, 41, 95, 141, 21, 953, 1453, 3585, 2521, 0 }; - static ulong[] dim865JoeKuoD7Init = { 1, 3, 7, 11, 25, 21, 43, 221, 201, 761, 1457, 1597, 2147, 0 }; - static ulong[] dim866JoeKuoD7Init = { 1, 1, 3, 9, 27, 63, 35, 229, 147, 293, 699, 673, 4779, 0 }; - static ulong[] dim867JoeKuoD7Init = { 1, 3, 5, 13, 15, 57, 57, 197, 23, 925, 1433, 681, 1721, 0 }; - static ulong[] dim868JoeKuoD7Init = { 1, 1, 5, 11, 17, 25, 127, 195, 487, 679, 1529, 453, 3955, 0 }; - static ulong[] dim869JoeKuoD7Init = { 1, 3, 7, 1, 29, 17, 49, 13, 299, 305, 11, 3913, 1633, 0 }; - static ulong[] dim870JoeKuoD7Init = { 1, 3, 5, 3, 15, 15, 79, 233, 183, 515, 773, 1761, 5439, 0 }; - static ulong[] dim871JoeKuoD7Init = { 1, 1, 5, 7, 23, 43, 3, 59, 37, 985, 1957, 2373, 7823, 0 }; - static ulong[] dim872JoeKuoD7Init = { 1, 1, 5, 5, 21, 59, 47, 205, 69, 435, 1567, 2661, 3589, 0 }; - static ulong[] dim873JoeKuoD7Init = { 1, 1, 1, 1, 7, 29, 15, 61, 197, 339, 1955, 2815, 4343, 0 }; - static ulong[] dim874JoeKuoD7Init = { 1, 3, 5, 5, 13, 33, 109, 33, 475, 219, 1707, 3747, 7359, 0 }; - static ulong[] dim875JoeKuoD7Init = { 1, 3, 7, 3, 21, 15, 53, 29, 493, 729, 1847, 1387, 1221, 0 }; - static ulong[] dim876JoeKuoD7Init = { 1, 1, 1, 11, 19, 27, 107, 29, 217, 19, 337, 2621, 1199, 0 }; - static ulong[] dim877JoeKuoD7Init = { 1, 1, 5, 11, 11, 39, 111, 195, 373, 239, 355, 359, 1187, 0 }; - static ulong[] dim878JoeKuoD7Init = { 1, 1, 3, 15, 29, 63, 13, 235, 413, 67, 1437, 3227, 5067, 0 }; - static ulong[] dim879JoeKuoD7Init = { 1, 3, 3, 3, 29, 35, 11, 189, 15, 181, 1807, 1711, 3317, 0 }; - static ulong[] dim880JoeKuoD7Init = { 1, 3, 5, 5, 25, 21, 93, 101, 65, 495, 375, 2873, 5253, 0 }; - static ulong[] dim881JoeKuoD7Init = { 1, 1, 7, 3, 19, 47, 13, 229, 3, 377, 1769, 673, 5713, 0 }; - static ulong[] dim882JoeKuoD7Init = { 1, 1, 1, 15, 11, 19, 25, 249, 95, 777, 1763, 2607, 6439, 0 }; - static ulong[] dim883JoeKuoD7Init = { 1, 1, 5, 1, 31, 47, 101, 155, 139, 201, 1687, 1503, 4783, 0 }; - static ulong[] dim884JoeKuoD7Init = { 1, 1, 5, 13, 27, 11, 53, 199, 305, 481, 1071, 143, 3667, 0 }; - static ulong[] dim885JoeKuoD7Init = { 1, 3, 5, 11, 15, 29, 95, 201, 271, 607, 511, 4029, 4269, 0 }; - static ulong[] dim886JoeKuoD7Init = { 1, 1, 1, 3, 29, 13, 99, 161, 55, 997, 1123, 3107, 4255, 0 }; - static ulong[] dim887JoeKuoD7Init = { 1, 3, 5, 11, 13, 5, 121, 253, 315, 465, 851, 3147, 5415, 0 }; - static ulong[] dim888JoeKuoD7Init = { 1, 3, 3, 13, 29, 15, 39, 7, 439, 787, 895, 1859, 5139, 0 }; - static ulong[] dim889JoeKuoD7Init = { 1, 3, 5, 9, 29, 37, 61, 61, 321, 307, 1741, 3143, 1977, 0 }; - static ulong[] dim890JoeKuoD7Init = { 1, 3, 3, 5, 19, 5, 105, 89, 189, 723, 407, 2557, 3817, 0 }; - static ulong[] dim891JoeKuoD7Init = { 1, 1, 1, 7, 15, 9, 93, 15, 461, 337, 1157, 531, 797, 0 }; - static ulong[] dim892JoeKuoD7Init = { 1, 3, 1, 1, 15, 33, 49, 87, 185, 581, 1449, 735, 4891, 0 }; - static ulong[] dim893JoeKuoD7Init = { 1, 1, 3, 7, 31, 49, 125, 99, 237, 655, 825, 2769, 4589, 0 }; - static ulong[] dim894JoeKuoD7Init = { 1, 3, 3, 15, 1, 51, 97, 205, 15, 47, 1453, 3399, 5539, 0 }; - static ulong[] dim895JoeKuoD7Init = { 1, 3, 5, 13, 29, 43, 105, 39, 329, 719, 563, 3817, 2901, 0 }; - static ulong[] dim896JoeKuoD7Init = { 1, 1, 3, 5, 25, 19, 7, 209, 89, 455, 2019, 1481, 7409, 0 }; - static ulong[] dim897JoeKuoD7Init = { 1, 3, 7, 1, 25, 47, 53, 115, 263, 547, 565, 3495, 3759, 0 }; - static ulong[] dim898JoeKuoD7Init = { 1, 3, 7, 15, 25, 47, 121, 193, 99, 45, 1251, 1221, 6425, 0 }; - static ulong[] dim899JoeKuoD7Init = { 1, 1, 1, 9, 3, 47, 91, 231, 189, 39, 1811, 3215, 6593, 0 }; - static ulong[] dim900JoeKuoD7Init = { 1, 3, 7, 5, 3, 57, 67, 63, 23, 627, 2045, 2377, 3805, 0 }; - static ulong[] dim901JoeKuoD7Init = { 1, 1, 1, 13, 7, 47, 29, 99, 481, 923, 119, 1911, 5187, 0 }; - static ulong[] dim902JoeKuoD7Init = { 1, 1, 5, 7, 1, 57, 7, 197, 451, 531, 29, 1851, 7069, 0 }; - static ulong[] dim903JoeKuoD7Init = { 1, 1, 1, 5, 31, 43, 3, 207, 67, 279, 37, 2381, 5997, 0 }; - static ulong[] dim904JoeKuoD7Init = { 1, 3, 5, 7, 23, 57, 91, 109, 165, 549, 837, 3135, 2251, 0 }; - static ulong[] dim905JoeKuoD7Init = { 1, 1, 7, 1, 3, 41, 67, 127, 273, 385, 995, 3263, 5211, 0 }; - static ulong[] dim906JoeKuoD7Init = { 1, 3, 7, 9, 21, 9, 101, 105, 43, 291, 1909, 1641, 7965, 0 }; - static ulong[] dim907JoeKuoD7Init = { 1, 3, 5, 11, 19, 21, 117, 141, 197, 83, 203, 393, 7995, 0 }; - static ulong[] dim908JoeKuoD7Init = { 1, 1, 5, 13, 11, 33, 21, 207, 421, 91, 1233, 1239, 5683, 0 }; - static ulong[] dim909JoeKuoD7Init = { 1, 1, 3, 15, 5, 1, 127, 119, 349, 953, 1297, 1805, 2385, 0 }; - static ulong[] dim910JoeKuoD7Init = { 1, 1, 1, 1, 19, 17, 17, 37, 217, 857, 859, 53, 2091, 0 }; - static ulong[] dim911JoeKuoD7Init = { 1, 3, 1, 15, 27, 37, 69, 121, 101, 1011, 1859, 3297, 5755, 0 }; - static ulong[] dim912JoeKuoD7Init = { 1, 3, 7, 13, 21, 13, 107, 105, 17, 743, 1849, 3169, 5901, 0 }; - static ulong[] dim913JoeKuoD7Init = { 1, 3, 3, 13, 31, 37, 125, 83, 127, 687, 1593, 1257, 4729, 0 }; - static ulong[] dim914JoeKuoD7Init = { 1, 3, 5, 3, 23, 21, 51, 157, 469, 349, 213, 1303, 123, 0 }; - static ulong[] dim915JoeKuoD7Init = { 1, 3, 1, 15, 17, 23, 45, 157, 313, 241, 361, 3967, 3635, 0 }; - static ulong[] dim916JoeKuoD7Init = { 1, 1, 7, 7, 25, 41, 65, 25, 97, 787, 951, 2471, 4621, 0 }; - static ulong[] dim917JoeKuoD7Init = { 1, 1, 7, 3, 31, 29, 75, 173, 55, 613, 283, 195, 5009, 0 }; - static ulong[] dim918JoeKuoD7Init = { 1, 1, 5, 3, 9, 47, 115, 149, 501, 199, 1957, 785, 3391, 0 }; - static ulong[] dim919JoeKuoD7Init = { 1, 1, 7, 11, 31, 57, 71, 191, 333, 157, 809, 3039, 7471, 0 }; - static ulong[] dim920JoeKuoD7Init = { 1, 3, 7, 9, 19, 17, 103, 243, 411, 449, 1495, 3843, 5361, 0 }; - static ulong[] dim921JoeKuoD7Init = { 1, 1, 1, 1, 11, 13, 99, 229, 365, 909, 87, 3669, 6609, 0 }; - static ulong[] dim922JoeKuoD7Init = { 1, 1, 1, 15, 7, 61, 95, 95, 147, 959, 971, 649, 5047, 0 }; - static ulong[] dim923JoeKuoD7Init = { 1, 3, 1, 15, 15, 37, 113, 29, 373, 379, 151, 2741, 1259, 0 }; - static ulong[] dim924JoeKuoD7Init = { 1, 3, 3, 7, 1, 7, 91, 61, 213, 131, 1607, 3957, 4197, 0 }; - static ulong[] dim925JoeKuoD7Init = { 1, 1, 7, 15, 11, 41, 79, 25, 267, 511, 111, 1779, 351, 0 }; - static ulong[] dim926JoeKuoD7Init = { 1, 3, 5, 5, 17, 9, 29, 117, 207, 655, 221, 3567, 6069, 0 }; - static ulong[] dim927JoeKuoD7Init = { 1, 1, 1, 13, 31, 47, 3, 51, 451, 675, 91, 1529, 5729, 0 }; - static ulong[] dim928JoeKuoD7Init = { 1, 1, 7, 15, 27, 37, 27, 189, 183, 619, 509, 2421, 5903, 0 }; - static ulong[] dim929JoeKuoD7Init = { 1, 1, 3, 7, 1, 31, 79, 233, 41, 949, 1313, 3807, 171, 0 }; - static ulong[] dim930JoeKuoD7Init = { 1, 1, 3, 5, 31, 39, 29, 43, 309, 11, 1041, 1893, 4443, 0 }; - static ulong[] dim931JoeKuoD7Init = { 1, 1, 1, 11, 13, 51, 5, 199, 51, 563, 819, 3467, 7003, 0 }; - static ulong[] dim932JoeKuoD7Init = { 1, 1, 3, 15, 19, 27, 1, 3, 393, 901, 1603, 1949, 7119, 0 }; - static ulong[] dim933JoeKuoD7Init = { 1, 1, 1, 3, 13, 39, 35, 53, 437, 263, 783, 1669, 7271, 0 }; - static ulong[] dim934JoeKuoD7Init = { 1, 1, 5, 11, 23, 11, 17, 187, 303, 833, 805, 3395, 181, 0 }; - static ulong[] dim935JoeKuoD7Init = { 1, 3, 5, 9, 15, 23, 113, 37, 131, 89, 923, 2265, 1621, 0 }; - static ulong[] dim936JoeKuoD7Init = { 1, 3, 1, 5, 3, 35, 53, 139, 21, 547, 1765, 3993, 2617, 0 }; - static ulong[] dim937JoeKuoD7Init = { 1, 3, 5, 1, 3, 35, 17, 185, 291, 973, 1267, 301, 7443, 0 }; - static ulong[] dim938JoeKuoD7Init = { 1, 3, 5, 1, 5, 45, 107, 209, 345, 821, 173, 1777, 4215, 0 }; - static ulong[] dim939JoeKuoD7Init = { 1, 1, 5, 3, 13, 11, 17, 5, 445, 411, 825, 3031, 4295, 0 }; - static ulong[] dim940JoeKuoD7Init = { 1, 3, 5, 1, 15, 45, 57, 243, 263, 167, 1889, 2901, 2315, 0 }; - static ulong[] dim941JoeKuoD7Init = { 1, 1, 5, 13, 27, 37, 27, 39, 89, 571, 775, 269, 2633, 0 }; - static ulong[] dim942JoeKuoD7Init = { 1, 3, 1, 15, 5, 41, 59, 89, 475, 745, 431, 489, 2121, 0 }; - static ulong[] dim943JoeKuoD7Init = { 1, 3, 1, 11, 3, 53, 65, 107, 475, 529, 169, 2555, 5189, 0 }; - static ulong[] dim944JoeKuoD7Init = { 1, 1, 1, 7, 27, 7, 55, 11, 493, 687, 365, 3105, 8067, 0 }; - static ulong[] dim945JoeKuoD7Init = { 1, 3, 7, 7, 13, 7, 101, 139, 387, 289, 1157, 785, 1457, 0 }; - static ulong[] dim946JoeKuoD7Init = { 1, 3, 7, 7, 1, 23, 81, 147, 509, 241, 1507, 3947, 795, 0 }; - static ulong[] dim947JoeKuoD7Init = { 1, 3, 1, 3, 3, 3, 39, 205, 67, 409, 1463, 2503, 7003, 0 }; - static ulong[] dim948JoeKuoD7Init = { 1, 3, 5, 7, 13, 3, 49, 157, 271, 813, 1793, 2059, 7233, 0 }; - static ulong[] dim949JoeKuoD7Init = { 1, 1, 1, 11, 17, 7, 35, 251, 91, 725, 157, 2503, 7007, 0 }; - static ulong[] dim950JoeKuoD7Init = { 1, 1, 1, 7, 31, 59, 115, 1, 421, 181, 809, 1739, 5641, 0 }; - static ulong[] dim951JoeKuoD7Init = { 1, 1, 7, 1, 3, 53, 29, 37, 181, 187, 11, 1829, 5031, 0 }; - static ulong[] dim952JoeKuoD7Init = { 1, 3, 3, 3, 5, 49, 11, 69, 109, 11, 1825, 2119, 4697, 0 }; - static ulong[] dim953JoeKuoD7Init = { 1, 3, 3, 7, 7, 31, 115, 197, 39, 177, 1263, 1173, 3845, 0 }; - static ulong[] dim954JoeKuoD7Init = { 1, 3, 7, 1, 15, 61, 49, 3, 141, 599, 809, 2827, 6349, 0 }; - static ulong[] dim955JoeKuoD7Init = { 1, 3, 1, 9, 23, 29, 121, 175, 507, 273, 1945, 2991, 885, 0 }; - static ulong[] dim956JoeKuoD7Init = { 1, 1, 1, 1, 3, 55, 125, 37, 57, 901, 85, 3319, 3477, 0 }; - static ulong[] dim957JoeKuoD7Init = { 1, 1, 7, 15, 3, 27, 69, 143, 431, 47, 603, 1321, 5053, 0 }; - static ulong[] dim958JoeKuoD7Init = { 1, 3, 1, 3, 3, 37, 65, 163, 391, 509, 87, 747, 4301, 0 }; - static ulong[] dim959JoeKuoD7Init = { 1, 3, 7, 9, 5, 53, 75, 179, 389, 97, 373, 963, 3647, 0 }; - static ulong[] dim960JoeKuoD7Init = { 1, 3, 1, 5, 13, 21, 49, 211, 5, 469, 1807, 891, 1543, 0 }; - static ulong[] dim961JoeKuoD7Init = { 1, 3, 1, 9, 13, 29, 39, 55, 39, 667, 1967, 1887, 2619, 0 }; - static ulong[] dim962JoeKuoD7Init = { 1, 1, 7, 9, 25, 47, 1, 221, 421, 175, 461, 1931, 3525, 0 }; - static ulong[] dim963JoeKuoD7Init = { 1, 3, 1, 9, 11, 35, 23, 121, 493, 675, 857, 2989, 4863, 0 }; - static ulong[] dim964JoeKuoD7Init = { 1, 3, 7, 9, 5, 39, 121, 9, 249, 507, 1637, 2991, 4545, 0 }; - static ulong[] dim965JoeKuoD7Init = { 1, 1, 5, 9, 5, 9, 27, 135, 299, 713, 1385, 729, 29, 0 }; - static ulong[] dim966JoeKuoD7Init = { 1, 3, 1, 11, 3, 3, 67, 17, 163, 535, 1731, 1401, 4495, 0 }; - static ulong[] dim967JoeKuoD7Init = { 1, 1, 1, 5, 31, 29, 81, 251, 471, 461, 1151, 1037, 4069, 0 }; - static ulong[] dim968JoeKuoD7Init = { 1, 3, 7, 5, 11, 29, 13, 157, 329, 237, 691, 1895, 653, 0 }; - static ulong[] dim969JoeKuoD7Init = { 1, 3, 5, 13, 23, 23, 57, 149, 111, 607, 1835, 3129, 1827, 0 }; - static ulong[] dim970JoeKuoD7Init = { 1, 3, 1, 5, 11, 11, 95, 143, 495, 805, 1163, 1853, 1017, 0 }; - static ulong[] dim971JoeKuoD7Init = { 1, 1, 1, 9, 15, 19, 89, 143, 305, 121, 1217, 807, 5003, 0 }; - static ulong[] dim972JoeKuoD7Init = { 1, 1, 1, 13, 27, 39, 117, 65, 473, 191, 1863, 3533, 243, 0 }; - static ulong[] dim973JoeKuoD7Init = { 1, 3, 3, 9, 31, 5, 91, 245, 175, 635, 257, 1197, 5965, 0 }; - static ulong[] dim974JoeKuoD7Init = { 1, 3, 5, 1, 9, 13, 37, 19, 177, 949, 49, 3855, 5105, 0 }; - static ulong[] dim975JoeKuoD7Init = { 1, 1, 3, 3, 1, 41, 33, 65, 295, 917, 503, 2665, 1485, 0 }; - static ulong[] dim976JoeKuoD7Init = { 1, 1, 3, 5, 3, 25, 11, 9, 439, 293, 1919, 693, 5797, 0 }; - static ulong[] dim977JoeKuoD7Init = { 1, 3, 7, 15, 17, 51, 7, 17, 153, 105, 807, 1029, 4649, 0 }; - static ulong[] dim978JoeKuoD7Init = { 1, 1, 5, 11, 27, 25, 37, 49, 481, 599, 655, 1497, 6455, 0 }; - static ulong[] dim979JoeKuoD7Init = { 1, 1, 7, 5, 25, 23, 127, 203, 381, 61, 1651, 3535, 6345, 0 }; - static ulong[] dim980JoeKuoD7Init = { 1, 1, 1, 5, 27, 13, 93, 151, 421, 713, 305, 3541, 6741, 0 }; - static ulong[] dim981JoeKuoD7Init = { 1, 1, 5, 5, 3, 1, 93, 55, 65, 437, 1283, 55, 861, 0 }; - static ulong[] dim982JoeKuoD7Init = { 1, 3, 7, 9, 27, 59, 15, 195, 303, 705, 143, 1423, 6793, 0 }; - static ulong[] dim983JoeKuoD7Init = { 1, 1, 7, 13, 3, 21, 81, 89, 325, 103, 573, 1891, 3023, 0 }; - static ulong[] dim984JoeKuoD7Init = { 1, 3, 3, 7, 15, 47, 23, 139, 437, 701, 1453, 1419, 1487, 0 }; - static ulong[] dim985JoeKuoD7Init = { 1, 3, 3, 1, 13, 35, 49, 127, 335, 185, 393, 2239, 2039, 0 }; - static ulong[] dim986JoeKuoD7Init = { 1, 1, 3, 5, 29, 3, 83, 179, 487, 381, 1477, 1849, 7593, 0 }; - static ulong[] dim987JoeKuoD7Init = { 1, 1, 3, 3, 15, 61, 75, 115, 487, 237, 615, 1011, 4725, 0 }; - static ulong[] dim988JoeKuoD7Init = { 1, 3, 7, 5, 25, 39, 105, 81, 401, 939, 343, 3281, 3907, 0 }; - static ulong[] dim989JoeKuoD7Init = { 1, 3, 5, 9, 31, 31, 43, 131, 275, 575, 727, 3035, 363, 0 }; - static ulong[] dim990JoeKuoD7Init = { 1, 3, 7, 11, 31, 9, 27, 145, 99, 261, 1927, 2619, 5853, 0 }; - static ulong[] dim991JoeKuoD7Init = { 1, 3, 7, 5, 25, 33, 85, 77, 435, 453, 1115, 1025, 2477, 0 }; - static ulong[] dim992JoeKuoD7Init = { 1, 3, 7, 13, 19, 55, 85, 155, 455, 385, 1033, 3789, 709, 0 }; - static ulong[] dim993JoeKuoD7Init = { 1, 3, 1, 11, 31, 47, 61, 45, 247, 557, 929, 1579, 3927, 0 }; - static ulong[] dim994JoeKuoD7Init = { 1, 1, 3, 7, 13, 41, 121, 249, 393, 527, 1807, 2493, 67, 0 }; - static ulong[] dim995JoeKuoD7Init = { 1, 3, 7, 13, 3, 17, 9, 215, 181, 841, 1381, 1573, 1531, 0 }; - static ulong[] dim996JoeKuoD7Init = { 1, 1, 7, 3, 21, 39, 119, 89, 267, 395, 1263, 3927, 5419, 0 }; - static ulong[] dim997JoeKuoD7Init = { 1, 1, 1, 5, 17, 21, 35, 217, 165, 837, 1093, 1347, 6361, 0 }; - static ulong[] dim998JoeKuoD7Init = { 1, 3, 3, 9, 9, 1, 59, 31, 41, 229, 925, 2703, 6597, 0 }; - static ulong[] dim999JoeKuoD7Init = { 1, 3, 1, 9, 13, 21, 35, 159, 329, 981, 955, 1871, 3571, 0 }; - static ulong[] dim1000JoeKuoD7Init = { 1, 3, 1, 11, 31, 47, 121, 201, 339, 1021, 1413, 1405, 1261, 0 }; - static ulong[] dim1001JoeKuoD7Init = { 1, 1, 3, 11, 15, 23, 115, 247, 333, 757, 369, 3839, 5217, 0 }; - static ulong[] dim1002JoeKuoD7Init = { 1, 1, 1, 15, 1, 37, 47, 67, 461, 333, 837, 2831, 2293, 0 }; - static ulong[] dim1003JoeKuoD7Init = { 1, 1, 5, 11, 31, 29, 75, 9, 287, 17, 1771, 3523, 7321, 0 }; - static ulong[] dim1004JoeKuoD7Init = { 1, 3, 7, 5, 29, 47, 37, 25, 497, 455, 1929, 2711, 777, 0 }; - static ulong[] dim1005JoeKuoD7Init = { 1, 3, 1, 15, 17, 21, 121, 205, 133, 139, 1343, 2181, 6281, 0 }; - static ulong[] dim1006JoeKuoD7Init = { 1, 3, 5, 3, 17, 59, 93, 105, 359, 27, 1515, 115, 7585, 0 }; - static ulong[] dim1007JoeKuoD7Init = { 1, 3, 1, 3, 25, 43, 71, 71, 315, 137, 1245, 1751, 1589, 0 }; - static ulong[] dim1008JoeKuoD7Init = { 1, 1, 7, 1, 23, 51, 61, 247, 317, 125, 859, 3807, 1175, 0 }; - static ulong[] dim1009JoeKuoD7Init = { 1, 1, 5, 9, 31, 33, 25, 41, 21, 1001, 63, 2105, 1929, 0 }; - static ulong[] dim1010JoeKuoD7Init = { 1, 1, 3, 15, 29, 61, 59, 173, 265, 661, 115, 3127, 4431, 0 }; - static ulong[] dim1011JoeKuoD7Init = { 1, 1, 1, 15, 7, 63, 55, 253, 131, 425, 735, 2917, 5311, 0 }; - static ulong[] dim1012JoeKuoD7Init = { 1, 3, 1, 3, 9, 7, 81, 39, 261, 633, 485, 2091, 3763, 0 }; - static ulong[] dim1013JoeKuoD7Init = { 1, 3, 1, 11, 27, 19, 99, 99, 27, 225, 1007, 1089, 921, 0 }; - static ulong[] dim1014JoeKuoD7Init = { 1, 1, 3, 13, 21, 7, 85, 105, 379, 223, 955, 3533, 3879, 0 }; - static ulong[] dim1015JoeKuoD7Init = { 1, 3, 3, 9, 13, 45, 55, 57, 315, 255, 141, 3255, 5185, 0 }; - static ulong[] dim1016JoeKuoD7Init = { 1, 3, 7, 15, 9, 27, 53, 15, 25, 547, 1573, 1387, 7243, 0 }; - static ulong[] dim1017JoeKuoD7Init = { 1, 1, 3, 15, 19, 17, 77, 253, 105, 1009, 1331, 2773, 7563, 0 }; - static ulong[] dim1018JoeKuoD7Init = { 1, 1, 5, 5, 3, 19, 103, 63, 491, 709, 1299, 1245, 3879, 0 }; - static ulong[] dim1019JoeKuoD7Init = { 1, 3, 1, 1, 13, 43, 37, 41, 167, 349, 1821, 2741, 3025, 0 }; - static ulong[] dim1020JoeKuoD7Init = { 1, 1, 1, 5, 29, 39, 25, 221, 259, 939, 471, 2547, 7119, 0 }; - static ulong[] dim1021JoeKuoD7Init = { 1, 3, 3, 3, 25, 59, 53, 105, 39, 737, 987, 2961, 7703, 0 }; - static ulong[] dim1022JoeKuoD7Init = { 1, 3, 5, 3, 29, 11, 109, 233, 221, 515, 1463, 1233, 7591, 0 }; - static ulong[] dim1023JoeKuoD7Init = { 1, 1, 1, 3, 17, 17, 113, 91, 253, 547, 1203, 2327, 6933, 0 }; - static ulong[] dim1024JoeKuoD7Init = { 1, 1, 3, 11, 25, 3, 17, 27, 239, 723, 1751, 3907, 1199, 0 }; - static ulong[] dim1025JoeKuoD7Init = { 1, 1, 5, 15, 13, 35, 93, 9, 501, 949, 659, 1863, 5319, 0 }; - static ulong[] dim1026JoeKuoD7Init = { 1, 3, 7, 1, 1, 55, 99, 73, 185, 299, 181, 4005, 7239, 0 }; - static ulong[] dim1027JoeKuoD7Init = { 1, 1, 1, 5, 13, 57, 21, 41, 461, 445, 199, 689, 2005, 0 }; - static ulong[] dim1028JoeKuoD7Init = { 1, 1, 1, 9, 11, 39, 45, 157, 295, 907, 1839, 3313, 6397, 0 }; - static ulong[] dim1029JoeKuoD7Init = { 1, 1, 5, 15, 21, 49, 39, 147, 325, 437, 1773, 2533, 8183, 0 }; - static ulong[] dim1030JoeKuoD7Init = { 1, 1, 7, 11, 11, 45, 9, 149, 439, 403, 1717, 3141, 7259, 0 }; - static ulong[] dim1031JoeKuoD7Init = { 1, 1, 7, 3, 13, 41, 79, 93, 123, 135, 541, 1133, 4389, 0 }; - static ulong[] dim1032JoeKuoD7Init = { 1, 3, 1, 11, 17, 45, 3, 49, 117, 193, 1737, 2995, 6821, 0 }; - static ulong[] dim1033JoeKuoD7Init = { 1, 3, 7, 9, 19, 53, 77, 119, 83, 161, 1029, 95, 7065, 0 }; - static ulong[] dim1034JoeKuoD7Init = { 1, 3, 7, 5, 19, 33, 13, 85, 63, 1011, 1857, 2657, 7513, 0 }; - static ulong[] dim1035JoeKuoD7Init = { 1, 1, 5, 13, 15, 31, 121, 75, 343, 915, 1571, 1291, 965, 0 }; - static ulong[] dim1036JoeKuoD7Init = { 1, 1, 1, 15, 17, 27, 31, 183, 79, 219, 341, 2491, 7329, 0 }; - static ulong[] dim1037JoeKuoD7Init = { 1, 3, 3, 15, 5, 5, 53, 151, 149, 471, 413, 967, 4207, 0 }; - static ulong[] dim1038JoeKuoD7Init = { 1, 1, 7, 15, 21, 17, 97, 107, 51, 533, 1195, 1495, 3843, 0 }; - static ulong[] dim1039JoeKuoD7Init = { 1, 1, 3, 7, 3, 5, 109, 19, 401, 179, 1595, 3147, 3847, 0 }; - static ulong[] dim1040JoeKuoD7Init = { 1, 1, 3, 9, 11, 49, 9, 245, 417, 933, 627, 551, 3643, 0 }; - static ulong[] dim1041JoeKuoD7Init = { 1, 1, 1, 11, 5, 33, 101, 247, 57, 597, 377, 7, 7117, 0 }; - static ulong[] dim1042JoeKuoD7Init = { 1, 3, 7, 11, 7, 47, 113, 29, 503, 385, 743, 563, 4775, 0 }; - static ulong[] dim1043JoeKuoD7Init = { 1, 3, 3, 15, 7, 63, 57, 171, 77, 663, 1113, 1901, 5361, 0 }; - static ulong[] dim1044JoeKuoD7Init = { 1, 3, 1, 11, 1, 1, 39, 83, 497, 725, 1105, 863, 113, 0 }; - static ulong[] dim1045JoeKuoD7Init = { 1, 1, 7, 1, 1, 23, 95, 137, 447, 593, 561, 1665, 7565, 0 }; - static ulong[] dim1046JoeKuoD7Init = { 1, 1, 1, 5, 19, 15, 25, 185, 33, 747, 641, 3205, 1373, 0 }; - static ulong[] dim1047JoeKuoD7Init = { 1, 1, 3, 1, 15, 17, 65, 77, 1, 689, 1751, 1885, 3873, 0 }; - static ulong[] dim1048JoeKuoD7Init = { 1, 3, 7, 15, 23, 23, 9, 97, 129, 185, 1527, 3721, 5161, 0 }; - static ulong[] dim1049JoeKuoD7Init = { 1, 1, 1, 5, 23, 33, 33, 131, 99, 929, 1077, 3129, 8153, 0 }; - static ulong[] dim1050JoeKuoD7Init = { 1, 1, 3, 1, 1, 37, 69, 155, 69, 121, 395, 717, 841, 0 }; - static ulong[] dim1051JoeKuoD7Init = { 1, 1, 5, 7, 17, 63, 101, 109, 323, 559, 427, 2279, 5345, 0 }; - static ulong[] dim1052JoeKuoD7Init = { 1, 1, 1, 1, 9, 27, 77, 19, 375, 313, 855, 65, 1359, 0 }; - static ulong[] dim1053JoeKuoD7Init = { 1, 3, 7, 5, 23, 11, 5, 57, 69, 267, 895, 1279, 5083, 0 }; - static ulong[] dim1054JoeKuoD7Init = { 1, 3, 7, 9, 17, 5, 13, 27, 299, 279, 389, 3161, 4633, 0 }; - static ulong[] dim1055JoeKuoD7Init = { 1, 3, 7, 1, 19, 47, 31, 93, 503, 473, 1501, 617, 1621, 0 }; - static ulong[] dim1056JoeKuoD7Init = { 1, 3, 1, 15, 17, 31, 35, 75, 41, 113, 149, 861, 5845, 0 }; - static ulong[] dim1057JoeKuoD7Init = { 1, 3, 7, 1, 7, 21, 31, 77, 307, 709, 531, 1133, 5887, 0 }; - static ulong[] dim1058JoeKuoD7Init = { 1, 1, 7, 7, 25, 37, 23, 233, 339, 705, 123, 79, 3827, 0 }; - static ulong[] dim1059JoeKuoD7Init = { 1, 1, 5, 9, 15, 61, 13, 215, 175, 999, 1147, 523, 7831, 0 }; - static ulong[] dim1060JoeKuoD7Init = { 1, 1, 1, 7, 15, 31, 117, 41, 43, 851, 1657, 669, 7243, 0 }; - static ulong[] dim1061JoeKuoD7Init = { 1, 1, 1, 1, 29, 47, 29, 179, 151, 833, 1911, 3031, 3835, 0 }; - static ulong[] dim1062JoeKuoD7Init = { 1, 1, 1, 13, 27, 41, 127, 203, 381, 395, 201, 1713, 4781, 0 }; - static ulong[] dim1063JoeKuoD7Init = { 1, 1, 3, 7, 11, 11, 127, 13, 257, 1, 1285, 2829, 8077, 0 }; - static ulong[] dim1064JoeKuoD7Init = { 1, 3, 3, 5, 15, 1, 35, 105, 183, 543, 1865, 675, 7747, 0 }; - static ulong[] dim1065JoeKuoD7Init = { 1, 1, 3, 1, 15, 47, 111, 147, 373, 445, 1273, 1989, 2057, 0 }; - static ulong[] dim1066JoeKuoD7Init = { 1, 1, 5, 9, 5, 31, 63, 127, 33, 323, 477, 213, 8137, 0 }; - static ulong[] dim1067JoeKuoD7Init = { 1, 1, 5, 9, 13, 1, 9, 135, 113, 395, 127, 3561, 5903, 0 }; - static ulong[] dim1068JoeKuoD7Init = { 1, 1, 3, 15, 1, 31, 85, 181, 49, 585, 1515, 2105, 541, 0 }; - static ulong[] dim1069JoeKuoD7Init = { 1, 1, 1, 15, 9, 1, 121, 31, 221, 445, 735, 1107, 4073, 0 }; - static ulong[] dim1070JoeKuoD7Init = { 1, 3, 1, 15, 3, 13, 13, 247, 509, 199, 1575, 2721, 2303, 0 }; - static ulong[] dim1071JoeKuoD7Init = { 1, 1, 3, 7, 25, 17, 63, 59, 409, 69, 1947, 427, 5357, 0 }; - static ulong[] dim1072JoeKuoD7Init = { 1, 1, 3, 3, 13, 5, 99, 161, 163, 437, 1467, 2215, 3321, 0 }; - static ulong[] dim1073JoeKuoD7Init = { 1, 3, 1, 3, 15, 55, 101, 207, 75, 601, 1327, 3901, 5773, 0 }; - static ulong[] dim1074JoeKuoD7Init = { 1, 1, 3, 3, 13, 45, 115, 119, 431, 5, 563, 3255, 5077, 0 }; - static ulong[] dim1075JoeKuoD7Init = { 1, 1, 7, 3, 21, 51, 41, 3, 375, 203, 1117, 3921, 387, 0 }; - static ulong[] dim1076JoeKuoD7Init = { 1, 3, 7, 7, 9, 5, 15, 133, 179, 37, 1593, 193, 4975, 0 }; - static ulong[] dim1077JoeKuoD7Init = { 1, 3, 3, 7, 31, 37, 89, 1, 241, 445, 381, 3283, 3851, 0 }; - static ulong[] dim1078JoeKuoD7Init = { 1, 3, 5, 1, 5, 45, 21, 123, 377, 83, 2029, 1913, 659, 0 }; - static ulong[] dim1079JoeKuoD7Init = { 1, 1, 7, 3, 5, 5, 35, 85, 173, 397, 1695, 3517, 175, 0 }; - static ulong[] dim1080JoeKuoD7Init = { 1, 3, 7, 13, 25, 51, 93, 177, 371, 507, 1777, 3335, 5953, 0 }; - static ulong[] dim1081JoeKuoD7Init = { 1, 3, 5, 15, 13, 41, 103, 105, 303, 401, 1339, 21, 5723, 0 }; - static ulong[] dim1082JoeKuoD7Init = { 1, 1, 7, 15, 7, 57, 63, 79, 35, 363, 831, 3911, 5777, 0 }; - static ulong[] dim1083JoeKuoD7Init = { 1, 1, 5, 11, 13, 15, 127, 141, 231, 619, 835, 691, 525, 0 }; - static ulong[] dim1084JoeKuoD7Init = { 1, 1, 3, 5, 7, 33, 81, 83, 497, 459, 493, 725, 2137, 0 }; - static ulong[] dim1085JoeKuoD7Init = { 1, 3, 3, 5, 25, 7, 77, 163, 47, 445, 629, 463, 3597, 0 }; - static ulong[] dim1086JoeKuoD7Init = { 1, 1, 3, 11, 19, 13, 67, 117, 351, 169, 1905, 3105, 93, 0 }; - static ulong[] dim1087JoeKuoD7Init = { 1, 3, 1, 13, 17, 17, 67, 135, 111, 649, 495, 425, 1621, 0 }; - static ulong[] dim1088JoeKuoD7Init = { 1, 3, 5, 1, 19, 59, 11, 227, 137, 525, 1751, 915, 4397, 0 }; - static ulong[] dim1089JoeKuoD7Init = { 1, 1, 3, 3, 15, 53, 87, 153, 69, 867, 833, 2363, 4363, 0 }; - static ulong[] dim1090JoeKuoD7Init = { 1, 3, 5, 13, 13, 19, 35, 103, 441, 23, 1049, 2469, 6595, 0 }; - static ulong[] dim1091JoeKuoD7Init = { 1, 1, 7, 7, 23, 55, 57, 25, 3, 157, 523, 1029, 4177, 0 }; - static ulong[] dim1092JoeKuoD7Init = { 1, 1, 3, 5, 9, 13, 1, 109, 219, 703, 237, 435, 2607, 0 }; - static ulong[] dim1093JoeKuoD7Init = { 1, 1, 1, 13, 21, 23, 5, 109, 467, 197, 1467, 3625, 4997, 0 }; - static ulong[] dim1094JoeKuoD7Init = { 1, 3, 7, 3, 25, 53, 119, 163, 117, 721, 1017, 2499, 4139, 0 }; - static ulong[] dim1095JoeKuoD7Init = { 1, 1, 1, 9, 9, 13, 33, 5, 263, 21, 1393, 3181, 4785, 0 }; - static ulong[] dim1096JoeKuoD7Init = { 1, 1, 5, 13, 15, 5, 57, 233, 99, 305, 745, 2327, 2259, 0 }; - static ulong[] dim1097JoeKuoD7Init = { 1, 1, 3, 3, 15, 39, 99, 115, 395, 99, 947, 3171, 711, 0 }; - static ulong[] dim1098JoeKuoD7Init = { 1, 1, 7, 13, 17, 33, 29, 37, 399, 479, 1083, 285, 6897, 0 }; - static ulong[] dim1099JoeKuoD7Init = { 1, 1, 7, 5, 7, 1, 9, 239, 479, 265, 1129, 3615, 4865, 0 }; - static ulong[] dim1100JoeKuoD7Init = { 1, 3, 3, 15, 31, 45, 7, 179, 467, 675, 1257, 1729, 7879, 0 }; - static ulong[] dim1101JoeKuoD7Init = { 1, 3, 5, 13, 5, 23, 11, 219, 503, 613, 1383, 1733, 3269, 0 }; - static ulong[] dim1102JoeKuoD7Init = { 1, 1, 3, 13, 25, 5, 81, 205, 389, 925, 735, 2981, 4271, 0 }; - static ulong[] dim1103JoeKuoD7Init = { 1, 1, 3, 7, 19, 47, 107, 15, 87, 889, 725, 1123, 2883, 0 }; - static ulong[] dim1104JoeKuoD7Init = { 1, 1, 3, 13, 31, 9, 45, 129, 353, 919, 1529, 827, 3645, 0 }; - static ulong[] dim1105JoeKuoD7Init = { 1, 3, 5, 5, 13, 45, 17, 219, 23, 873, 1127, 1757, 1103, 0 }; - static ulong[] dim1106JoeKuoD7Init = { 1, 3, 3, 11, 31, 45, 33, 215, 107, 941, 1785, 4039, 3393, 0 }; - static ulong[] dim1107JoeKuoD7Init = { 1, 3, 3, 7, 15, 61, 107, 189, 31, 457, 881, 1449, 7351, 0 }; - static ulong[] dim1108JoeKuoD7Init = { 1, 3, 1, 15, 13, 63, 95, 27, 3, 771, 363, 2569, 2195, 0 }; - static ulong[] dim1109JoeKuoD7Init = { 1, 1, 7, 9, 15, 11, 5, 193, 439, 745, 1705, 1249, 7319, 0 }; - static ulong[] dim1110JoeKuoD7Init = { 1, 1, 3, 11, 29, 19, 111, 73, 149, 707, 1337, 1417, 761, 0 }; - static ulong[] dim1111JoeKuoD7Init = { 1, 3, 7, 9, 17, 7, 127, 113, 353, 575, 1979, 3589, 3221, 1801, 0 }; - static ulong[] dim1112JoeKuoD7Init = { 1, 1, 5, 13, 29, 21, 31, 135, 45, 571, 229, 791, 2017, 1023, 0 }; - static ulong[] dim1113JoeKuoD7Init = { 1, 1, 1, 1, 3, 37, 29, 233, 379, 579, 1895, 2359, 5511, 15901, 0 }; - static ulong[] dim1114JoeKuoD7Init = { 1, 3, 1, 3, 11, 63, 83, 219, 275, 441, 581, 3735, 6845, 12669, 0 }; - static ulong[] dim1115JoeKuoD7Init = { 1, 3, 3, 9, 3, 5, 87, 143, 207, 211, 1123, 443, 3139, 15123, 0 }; - static ulong[] dim1116JoeKuoD7Init = { 1, 3, 3, 11, 11, 21, 69, 69, 307, 935, 1353, 163, 1535, 4821, 0 }; - static ulong[] dim1117JoeKuoD7Init = { 1, 1, 7, 13, 11, 47, 41, 107, 463, 1003, 457, 1019, 1699, 4425, 0 }; - static ulong[] dim1118JoeKuoD7Init = { 1, 3, 7, 7, 9, 5, 99, 95, 207, 697, 9, 771, 6895, 9157, 0 }; - static ulong[] dim1119JoeKuoD7Init = { 1, 1, 7, 11, 13, 5, 15, 107, 3, 319, 1187, 3357, 295, 2863, 0 }; - static ulong[] dim1120JoeKuoD7Init = { 1, 3, 3, 1, 13, 23, 89, 149, 337, 435, 633, 885, 1361, 3795, 0 }; - static ulong[] dim1121JoeKuoD7Init = { 1, 3, 1, 13, 1, 9, 63, 203, 377, 305, 1471, 3193, 5507, 2219, 0 }; - static ulong[] dim1122JoeKuoD7Init = { 1, 1, 3, 9, 9, 9, 63, 31, 35, 551, 1379, 135, 4949, 10345, 0 }; - static ulong[] dim1123JoeKuoD7Init = { 1, 3, 1, 3, 7, 61, 121, 27, 127, 901, 1935, 1347, 3179, 13785, 0 }; - static ulong[] dim1124JoeKuoD7Init = { 1, 1, 7, 11, 13, 17, 57, 73, 219, 73, 335, 3705, 591, 3547, 0 }; - static ulong[] dim1125JoeKuoD7Init = { 1, 1, 1, 7, 13, 7, 127, 153, 503, 99, 187, 1697, 3497, 11913, 0 }; - static ulong[] dim1126JoeKuoD7Init = { 1, 1, 7, 5, 3, 21, 99, 125, 87, 889, 1471, 625, 2671, 11729, 0 }; - static ulong[] dim1127JoeKuoD7Init = { 1, 3, 5, 7, 9, 55, 127, 201, 383, 769, 769, 3907, 7087, 1933, 0 }; - static ulong[] dim1128JoeKuoD7Init = { 1, 3, 7, 5, 9, 47, 5, 29, 155, 327, 1413, 2761, 7699, 9129, 0 }; - static ulong[] dim1129JoeKuoD7Init = { 1, 1, 7, 15, 9, 11, 7, 91, 71, 563, 535, 3387, 4769, 4875, 0 }; - static ulong[] dim1130JoeKuoD7Init = { 1, 1, 7, 11, 17, 47, 29, 201, 299, 947, 39, 583, 1723, 877, 0 }; - static ulong[] dim1131JoeKuoD7Init = { 1, 3, 1, 5, 27, 49, 105, 31, 91, 39, 1355, 2729, 6965, 14081, 0 }; - static ulong[] dim1132JoeKuoD7Init = { 1, 1, 7, 7, 17, 63, 65, 229, 497, 431, 1167, 1299, 4641, 10975, 0 }; - static ulong[] dim1133JoeKuoD7Init = { 1, 1, 5, 9, 17, 3, 101, 191, 187, 87, 1229, 369, 2633, 13765, 0 }; - static ulong[] dim1134JoeKuoD7Init = { 1, 1, 1, 7, 29, 7, 57, 17, 319, 839, 799, 151, 431, 9513, 0 }; - static ulong[] dim1135JoeKuoD7Init = { 1, 1, 1, 11, 25, 47, 15, 29, 71, 617, 697, 2633, 1787, 10343, 0 }; - static ulong[] dim1136JoeKuoD7Init = { 1, 1, 3, 3, 13, 1, 41, 211, 265, 501, 1619, 3781, 4091, 7785, 0 }; - static ulong[] dim1137JoeKuoD7Init = { 1, 3, 3, 9, 11, 37, 69, 45, 107, 69, 1227, 311, 187, 10379, 0 }; - static ulong[] dim1138JoeKuoD7Init = { 1, 1, 7, 1, 31, 37, 85, 135, 283, 869, 1159, 3971, 6339, 5511, 0 }; - static ulong[] dim1139JoeKuoD7Init = { 1, 1, 7, 3, 19, 43, 75, 59, 365, 763, 323, 3513, 437, 2371, 0 }; - static ulong[] dim1140JoeKuoD7Init = { 1, 3, 3, 13, 31, 39, 81, 199, 43, 863, 1563, 2811, 4551, 7469, 0 }; - static ulong[] dim1141JoeKuoD7Init = { 1, 1, 3, 5, 17, 59, 17, 9, 53, 527, 1689, 2365, 7673, 14581, 0 }; - static ulong[] dim1142JoeKuoD7Init = { 1, 3, 7, 5, 5, 5, 59, 21, 303, 43, 1379, 3297, 3053, 11115, 0 }; - static ulong[] dim1143JoeKuoD7Init = { 1, 1, 5, 15, 3, 33, 5, 253, 409, 321, 1487, 2083, 405, 15075, 0 }; - static ulong[] dim1144JoeKuoD7Init = { 1, 1, 3, 15, 11, 53, 99, 151, 33, 675, 1781, 1475, 2193, 6073, 0 }; - static ulong[] dim1145JoeKuoD7Init = { 1, 1, 3, 13, 27, 49, 83, 15, 335, 35, 1999, 237, 7359, 12173, 0 }; - static ulong[] dim1146JoeKuoD7Init = { 1, 3, 1, 15, 15, 61, 85, 243, 347, 745, 637, 1057, 5475, 15039, 0 }; - static ulong[] dim1147JoeKuoD7Init = { 1, 1, 3, 7, 1, 1, 31, 197, 499, 741, 191, 3799, 5485, 10129, 0 }; - static ulong[] dim1148JoeKuoD7Init = { 1, 1, 5, 5, 29, 15, 15, 185, 55, 685, 329, 605, 3365, 10203, 0 }; - static ulong[] dim1149JoeKuoD7Init = { 1, 3, 1, 13, 5, 1, 1, 169, 349, 591, 1961, 2989, 131, 2647, 0 }; - static ulong[] dim1150JoeKuoD7Init = { 1, 1, 7, 9, 17, 49, 95, 7, 57, 881, 1065, 3759, 5851, 7439, 0 }; - static ulong[] dim1151JoeKuoD7Init = { 1, 1, 3, 5, 27, 49, 65, 1, 177, 477, 453, 1823, 7615, 1285, 0 }; - static ulong[] dim1152JoeKuoD7Init = { 1, 1, 5, 9, 23, 25, 17, 149, 85, 373, 1585, 1227, 6127, 6003, 0 }; - static ulong[] dim1153JoeKuoD7Init = { 1, 1, 7, 13, 15, 61, 41, 141, 507, 391, 587, 2819, 3311, 853, 0 }; - static ulong[] dim1154JoeKuoD7Init = { 1, 1, 7, 13, 13, 23, 67, 171, 381, 285, 619, 457, 2751, 435, 0 }; - static ulong[] dim1155JoeKuoD7Init = { 1, 1, 5, 15, 13, 9, 21, 197, 385, 511, 1683, 2965, 1367, 7523, 0 }; - static ulong[] dim1156JoeKuoD7Init = { 1, 3, 7, 1, 23, 13, 21, 55, 415, 503, 1765, 1745, 5329, 4665, 0 }; - static ulong[] dim1157JoeKuoD7Init = { 1, 1, 1, 1, 21, 51, 49, 31, 195, 243, 1825, 2831, 467, 6527, 0 }; - static ulong[] dim1158JoeKuoD7Init = { 1, 1, 3, 3, 31, 37, 41, 139, 63, 517, 717, 415, 1137, 1855, 0 }; - static ulong[] dim1159JoeKuoD7Init = { 1, 1, 3, 15, 1, 45, 39, 9, 441, 809, 801, 3133, 2283, 8947, 0 }; - static ulong[] dim1160JoeKuoD7Init = { 1, 1, 3, 13, 13, 47, 55, 115, 155, 347, 1597, 415, 271, 4543, 0 }; - static ulong[] dim1161JoeKuoD7Init = { 1, 1, 1, 1, 1, 45, 5, 239, 187, 293, 59, 1319, 3839, 9945, 0 }; - static ulong[] dim1162JoeKuoD7Init = { 1, 1, 1, 15, 1, 41, 13, 19, 455, 881, 451, 1795, 239, 2695, 0 }; - static ulong[] dim1163JoeKuoD7Init = { 1, 3, 3, 9, 5, 25, 3, 19, 189, 377, 1017, 2501, 2707, 15333, 0 }; - static ulong[] dim1164JoeKuoD7Init = { 1, 1, 5, 5, 29, 57, 45, 35, 297, 663, 359, 2597, 7223, 6265, 0 }; - static ulong[] dim1165JoeKuoD7Init = { 1, 3, 1, 7, 1, 47, 125, 209, 65, 129, 211, 2535, 3617, 16229, 0 }; - static ulong[] dim1166JoeKuoD7Init = { 1, 1, 3, 11, 19, 29, 39, 177, 39, 807, 975, 835, 5509, 791, 0 }; - static ulong[] dim1167JoeKuoD7Init = { 1, 3, 3, 13, 31, 49, 69, 169, 433, 833, 1743, 3187, 8111, 15475, 0 }; - static ulong[] dim1168JoeKuoD7Init = { 1, 1, 5, 7, 31, 9, 27, 73, 335, 363, 1707, 1227, 6459, 12513, 0 }; - static ulong[] dim1169JoeKuoD7Init = { 1, 1, 7, 1, 1, 47, 109, 115, 429, 551, 1805, 3235, 579, 10039, 0 }; - static ulong[] dim1170JoeKuoD7Init = { 1, 1, 1, 7, 17, 61, 61, 1, 35, 917, 1513, 2141, 3939, 15755, 0 }; - static ulong[] dim1171JoeKuoD7Init = { 1, 1, 5, 1, 3, 27, 7, 219, 473, 875, 711, 703, 129, 16359, 0 }; - static ulong[] dim1172JoeKuoD7Init = { 1, 3, 5, 3, 27, 33, 97, 137, 19, 893, 233, 2605, 13, 875, 0 }; - static ulong[] dim1173JoeKuoD7Init = { 1, 3, 7, 11, 31, 43, 77, 225, 403, 861, 141, 2121, 707, 15753, 0 }; - static ulong[] dim1174JoeKuoD7Init = { 1, 1, 1, 3, 17, 33, 29, 103, 381, 179, 735, 2939, 7213, 12679, 0 }; - static ulong[] dim1175JoeKuoD7Init = { 1, 1, 1, 7, 5, 41, 43, 215, 239, 19, 625, 579, 5157, 12457, 0 }; - static ulong[] dim1176JoeKuoD7Init = { 1, 3, 1, 7, 15, 29, 93, 37, 241, 141, 1035, 3283, 193, 9873, 0 }; - static ulong[] dim1177JoeKuoD7Init = { 1, 1, 3, 13, 23, 11, 113, 153, 271, 515, 197, 3723, 1827, 11941, 0 }; - static ulong[] dim1178JoeKuoD7Init = { 1, 3, 7, 1, 29, 13, 45, 23, 421, 957, 1819, 1287, 5615, 4253, 0 }; - static ulong[] dim1179JoeKuoD7Init = { 1, 1, 3, 3, 11, 55, 47, 211, 85, 481, 1199, 3225, 5233, 4295, 0 }; - static ulong[] dim1180JoeKuoD7Init = { 1, 3, 3, 13, 11, 51, 93, 139, 271, 929, 863, 3227, 3075, 3587, 0 }; - static ulong[] dim1181JoeKuoD7Init = { 1, 1, 5, 11, 19, 59, 9, 221, 275, 171, 1703, 1495, 523, 5993, 0 }; - static ulong[] dim1182JoeKuoD7Init = { 1, 3, 1, 13, 15, 11, 21, 147, 291, 639, 1411, 33, 6845, 1431, 0 }; - static ulong[] dim1183JoeKuoD7Init = { 1, 3, 5, 1, 11, 11, 39, 195, 261, 19, 1803, 2869, 4507, 1131, 0 }; - static ulong[] dim1184JoeKuoD7Init = { 1, 3, 3, 11, 15, 27, 125, 5, 309, 569, 361, 4061, 2559, 1631, 0 }; - static ulong[] dim1185JoeKuoD7Init = { 1, 1, 5, 7, 23, 57, 37, 175, 35, 753, 755, 519, 5617, 1419, 0 }; - static ulong[] dim1186JoeKuoD7Init = { 1, 1, 5, 11, 21, 9, 107, 37, 121, 767, 1005, 2609, 2531, 14811, 0 }; - static ulong[] dim1187JoeKuoD7Init = { 1, 3, 7, 7, 3, 9, 91, 203, 219, 523, 319, 3021, 3465, 15579, 0 }; - static ulong[] dim1188JoeKuoD7Init = { 1, 3, 5, 1, 3, 29, 97, 249, 429, 665, 283, 595, 1527, 4559, 0 }; - static ulong[] dim1189JoeKuoD7Init = { 1, 1, 7, 15, 19, 23, 9, 169, 427, 171, 897, 3099, 7339, 13237, 0 }; - static ulong[] dim1190JoeKuoD7Init = { 1, 3, 5, 13, 11, 25, 11, 123, 229, 197, 1395, 2999, 3591, 5017, 0 }; - static ulong[] dim1191JoeKuoD7Init = { 1, 1, 7, 15, 3, 11, 49, 5, 217, 575, 445, 1381, 4407, 9777, 0 }; - static ulong[] dim1192JoeKuoD7Init = { 1, 1, 1, 13, 23, 43, 55, 19, 129, 925, 1623, 4037, 2535, 871, 0 }; - static ulong[] dim1193JoeKuoD7Init = { 1, 3, 3, 15, 3, 7, 29, 109, 251, 627, 1751, 3613, 5741, 7859, 0 }; - static ulong[] dim1194JoeKuoD7Init = { 1, 3, 5, 3, 23, 61, 115, 127, 157, 725, 1321, 1143, 3737, 12559, 0 }; - static ulong[] dim1195JoeKuoD7Init = { 1, 1, 7, 11, 25, 41, 117, 217, 389, 839, 1029, 547, 6149, 8335, 0 }; - static ulong[] dim1196JoeKuoD7Init = { 1, 3, 5, 1, 29, 61, 101, 81, 137, 547, 1989, 3907, 4855, 15949, 0 }; - static ulong[] dim1197JoeKuoD7Init = { 1, 3, 1, 3, 5, 9, 15, 33, 415, 725, 1183, 4091, 411, 4541, 0 }; - static ulong[] dim1198JoeKuoD7Init = { 1, 3, 3, 7, 31, 61, 53, 205, 157, 861, 989, 3265, 2943, 12941, 0 }; - static ulong[] dim1199JoeKuoD7Init = { 1, 3, 5, 11, 11, 13, 89, 39, 241, 153, 439, 2087, 5161, 5705, 0 }; - static ulong[] dim1200JoeKuoD7Init = { 1, 3, 3, 11, 15, 49, 39, 101, 1, 793, 1429, 2109, 1233, 3717, 0 }; - static ulong[] dim1201JoeKuoD7Init = { 1, 3, 7, 9, 29, 59, 45, 111, 157, 421, 853, 273, 1595, 1799, 0 }; - static ulong[] dim1202JoeKuoD7Init = { 1, 3, 7, 11, 3, 45, 31, 89, 475, 887, 563, 3985, 3011, 6903, 0 }; - static ulong[] dim1203JoeKuoD7Init = { 1, 3, 5, 15, 25, 13, 69, 3, 249, 435, 1333, 4079, 2259, 1971, 0 }; - static ulong[] dim1204JoeKuoD7Init = { 1, 3, 3, 11, 9, 51, 7, 203, 231, 155, 375, 2079, 6821, 12973, 0 }; - static ulong[] dim1205JoeKuoD7Init = { 1, 1, 1, 9, 5, 23, 115, 1, 307, 553, 1005, 2113, 6443, 8545, 0 }; - static ulong[] dim1206JoeKuoD7Init = { 1, 1, 3, 11, 7, 49, 49, 255, 73, 373, 413, 2997, 1403, 9501, 0 }; - static ulong[] dim1207JoeKuoD7Init = { 1, 3, 1, 15, 11, 31, 29, 43, 341, 119, 1209, 1471, 5785, 9809, 0 }; - static ulong[] dim1208JoeKuoD7Init = { 1, 1, 3, 15, 3, 35, 75, 187, 421, 911, 169, 1427, 7243, 10511, 0 }; - static ulong[] dim1209JoeKuoD7Init = { 1, 1, 1, 9, 3, 25, 21, 137, 437, 737, 1373, 3417, 2951, 7623, 0 }; - static ulong[] dim1210JoeKuoD7Init = { 1, 3, 1, 15, 27, 19, 97, 237, 341, 679, 473, 2775, 7195, 8093, 0 }; - static ulong[] dim1211JoeKuoD7Init = { 1, 3, 7, 3, 7, 45, 19, 109, 499, 883, 1473, 1907, 7229, 8063, 0 }; - static ulong[] dim1212JoeKuoD7Init = { 1, 3, 1, 1, 5, 49, 65, 213, 49, 941, 833, 3859, 3423, 5723, 0 }; - static ulong[] dim1213JoeKuoD7Init = { 1, 3, 3, 1, 27, 43, 53, 21, 379, 139, 1811, 133, 3641, 3021, 0 }; - static ulong[] dim1214JoeKuoD7Init = { 1, 3, 7, 9, 31, 49, 13, 17, 99, 773, 1127, 1237, 3593, 13233, 0 }; - static ulong[] dim1215JoeKuoD7Init = { 1, 1, 1, 9, 13, 21, 117, 29, 105, 671, 1423, 2449, 1979, 3717, 0 }; - static ulong[] dim1216JoeKuoD7Init = { 1, 3, 1, 13, 17, 55, 37, 45, 163, 475, 665, 115, 2175, 10065, 0 }; - static ulong[] dim1217JoeKuoD7Init = { 1, 1, 7, 9, 7, 31, 67, 215, 153, 981, 569, 2911, 6111, 12189, 0 }; - static ulong[] dim1218JoeKuoD7Init = { 1, 1, 3, 11, 19, 19, 101, 27, 131, 153, 505, 2897, 4573, 13713, 0 }; - static ulong[] dim1219JoeKuoD7Init = { 1, 1, 1, 9, 15, 21, 99, 187, 155, 135, 1421, 1421, 843, 3271, 0 }; - static ulong[] dim1220JoeKuoD7Init = { 1, 3, 1, 5, 1, 9, 17, 243, 111, 223, 1343, 3765, 2439, 717, 0 }; - static ulong[] dim1221JoeKuoD7Init = { 1, 1, 5, 3, 21, 9, 83, 191, 45, 813, 1047, 1483, 209, 2895, 0 }; - static ulong[] dim1222JoeKuoD7Init = { 1, 3, 5, 11, 29, 41, 119, 11, 245, 145, 969, 3017, 6403, 11387, 0 }; - static ulong[] dim1223JoeKuoD7Init = { 1, 1, 1, 13, 1, 19, 107, 35, 49, 381, 225, 595, 7145, 697, 0 }; - static ulong[] dim1224JoeKuoD7Init = { 1, 1, 1, 11, 5, 15, 37, 31, 117, 649, 1263, 1045, 3749, 16177, 0 }; - static ulong[] dim1225JoeKuoD7Init = { 1, 3, 7, 3, 7, 7, 91, 45, 395, 403, 1953, 743, 2207, 12887, 0 }; - static ulong[] dim1226JoeKuoD7Init = { 1, 1, 1, 11, 13, 31, 67, 7, 279, 389, 775, 301, 87, 6705, 0 }; - static ulong[] dim1227JoeKuoD7Init = { 1, 3, 1, 5, 27, 7, 85, 183, 325, 103, 1943, 2421, 4399, 7339, 0 }; - static ulong[] dim1228JoeKuoD7Init = { 1, 1, 7, 7, 21, 13, 69, 1, 289, 727, 1587, 3033, 2921, 12035, 0 }; - static ulong[] dim1229JoeKuoD7Init = { 1, 1, 7, 11, 31, 35, 103, 239, 89, 983, 433, 3027, 3089, 14439, 0 }; - static ulong[] dim1230JoeKuoD7Init = { 1, 3, 5, 9, 11, 9, 107, 207, 87, 563, 129, 2647, 3163, 11327, 0 }; - static ulong[] dim1231JoeKuoD7Init = { 1, 3, 7, 11, 9, 35, 115, 189, 293, 637, 213, 1111, 331, 10115, 0 }; - static ulong[] dim1232JoeKuoD7Init = { 1, 3, 5, 7, 21, 59, 127, 145, 157, 431, 295, 4055, 6207, 5353, 0 }; - static ulong[] dim1233JoeKuoD7Init = { 1, 1, 7, 5, 9, 53, 13, 249, 275, 841, 987, 3243, 7229, 6215, 0 }; - static ulong[] dim1234JoeKuoD7Init = { 1, 3, 5, 9, 11, 5, 47, 247, 57, 799, 1787, 2667, 3615, 4343, 0 }; - static ulong[] dim1235JoeKuoD7Init = { 1, 1, 1, 11, 31, 37, 73, 77, 181, 591, 445, 3081, 5337, 14259, 0 }; - static ulong[] dim1236JoeKuoD7Init = { 1, 3, 3, 11, 11, 49, 59, 229, 159, 139, 1435, 313, 7995, 5623, 0 }; - static ulong[] dim1237JoeKuoD7Init = { 1, 1, 7, 13, 17, 39, 53, 39, 413, 451, 2029, 1549, 485, 1311, 0 }; - static ulong[] dim1238JoeKuoD7Init = { 1, 1, 5, 11, 15, 57, 9, 245, 397, 587, 1733, 459, 2127, 16085, 0 }; - static ulong[] dim1239JoeKuoD7Init = { 1, 3, 3, 3, 17, 5, 17, 231, 439, 355, 1899, 1613, 1529, 12557, 0 }; - static ulong[] dim1240JoeKuoD7Init = { 1, 1, 1, 1, 5, 55, 113, 209, 441, 813, 1025, 191, 853, 2039, 0 }; - static ulong[] dim1241JoeKuoD7Init = { 1, 3, 3, 11, 9, 47, 89, 137, 187, 457, 1169, 3607, 3799, 15121, 0 }; - static ulong[] dim1242JoeKuoD7Init = { 1, 1, 3, 15, 15, 27, 93, 211, 137, 809, 1723, 1865, 6291, 13209, 0 }; - static ulong[] dim1243JoeKuoD7Init = { 1, 1, 5, 15, 5, 15, 67, 55, 445, 781, 829, 3237, 4031, 5147, 0 }; - static ulong[] dim1244JoeKuoD7Init = { 1, 3, 1, 3, 17, 59, 65, 35, 103, 515, 1409, 395, 711, 11773, 0 }; - static ulong[] dim1245JoeKuoD7Init = { 1, 1, 7, 11, 29, 5, 21, 117, 269, 963, 337, 3149, 2569, 9881, 0 }; - static ulong[] dim1246JoeKuoD7Init = { 1, 1, 5, 7, 1, 57, 61, 185, 431, 977, 661, 1285, 2607, 13465, 0 }; - static ulong[] dim1247JoeKuoD7Init = { 1, 3, 7, 5, 25, 35, 61, 227, 437, 75, 1677, 3337, 4601, 10447, 0 }; - static ulong[] dim1248JoeKuoD7Init = { 1, 3, 7, 1, 29, 29, 5, 163, 237, 217, 97, 1607, 911, 6195, 0 }; - static ulong[] dim1249JoeKuoD7Init = { 1, 1, 7, 3, 17, 7, 101, 31, 323, 191, 871, 1691, 3535, 8935, 0 }; - static ulong[] dim1250JoeKuoD7Init = { 1, 3, 5, 3, 11, 47, 117, 179, 25, 735, 989, 1623, 5321, 12603, 0 }; - static ulong[] dim1251JoeKuoD7Init = { 1, 1, 5, 11, 1, 55, 121, 221, 383, 969, 777, 3419, 2621, 1651, 0 }; - static ulong[] dim1252JoeKuoD7Init = { 1, 1, 7, 7, 21, 9, 95, 239, 221, 577, 1479, 1649, 6765, 5601, 0 }; - static ulong[] dim1253JoeKuoD7Init = { 1, 3, 3, 15, 29, 43, 49, 71, 255, 1011, 115, 1859, 7369, 16233, 0 }; - static ulong[] dim1254JoeKuoD7Init = { 1, 1, 3, 1, 13, 9, 21, 193, 255, 315, 1295, 1413, 6851, 4395, 0 }; - static ulong[] dim1255JoeKuoD7Init = { 1, 3, 1, 13, 21, 11, 75, 87, 453, 39, 503, 2937, 5089, 14211, 0 }; - static ulong[] dim1256JoeKuoD7Init = { 1, 1, 7, 13, 1, 17, 121, 153, 89, 113, 1969, 65, 4907, 10165, 0 }; - static ulong[] dim1257JoeKuoD7Init = { 1, 3, 5, 1, 17, 49, 75, 25, 147, 357, 617, 3245, 7313, 753, 0 }; - static ulong[] dim1258JoeKuoD7Init = { 1, 1, 7, 15, 25, 3, 71, 97, 463, 515, 989, 69, 687, 15151, 0 }; - static ulong[] dim1259JoeKuoD7Init = { 1, 3, 3, 3, 25, 61, 95, 219, 429, 143, 565, 463, 4165, 2619, 0 }; - static ulong[] dim1260JoeKuoD7Init = { 1, 1, 5, 13, 3, 45, 11, 59, 237, 387, 109, 253, 651, 13061, 0 }; - static ulong[] dim1261JoeKuoD7Init = { 1, 3, 7, 1, 25, 41, 111, 179, 321, 139, 453, 1061, 6395, 6391, 0 }; - static ulong[] dim1262JoeKuoD7Init = { 1, 3, 3, 1, 5, 11, 73, 131, 469, 839, 459, 2237, 2481, 10087, 0 }; - static ulong[] dim1263JoeKuoD7Init = { 1, 3, 7, 3, 13, 55, 75, 111, 411, 1007, 1303, 1613, 2449, 11337, 0 }; - static ulong[] dim1264JoeKuoD7Init = { 1, 1, 3, 1, 11, 39, 3, 193, 113, 927, 1345, 2747, 4951, 10543, 0 }; - static ulong[] dim1265JoeKuoD7Init = { 1, 3, 1, 15, 23, 39, 47, 115, 129, 51, 921, 1021, 6907, 8139, 0 }; - static ulong[] dim1266JoeKuoD7Init = { 1, 3, 1, 7, 31, 13, 75, 79, 331, 773, 1147, 335, 1729, 4015, 0 }; - static ulong[] dim1267JoeKuoD7Init = { 1, 3, 1, 7, 1, 47, 15, 183, 243, 525, 1515, 3209, 6597, 1895, 0 }; - static ulong[] dim1268JoeKuoD7Init = { 1, 1, 7, 3, 7, 59, 115, 223, 161, 181, 533, 1085, 3405, 2565, 0 }; - static ulong[] dim1269JoeKuoD7Init = { 1, 1, 5, 1, 9, 23, 57, 135, 113, 57, 143, 2949, 2703, 1813, 0 }; - static ulong[] dim1270JoeKuoD7Init = { 1, 3, 1, 9, 25, 43, 103, 7, 167, 393, 1515, 2871, 5167, 9943, 0 }; - static ulong[] dim1271JoeKuoD7Init = { 1, 1, 5, 1, 25, 1, 61, 49, 137, 157, 693, 3615, 1655, 14975, 0 }; - static ulong[] dim1272JoeKuoD7Init = { 1, 1, 7, 11, 21, 41, 89, 7, 171, 49, 1021, 3227, 3989, 11739, 0 }; - static ulong[] dim1273JoeKuoD7Init = { 1, 1, 3, 5, 31, 49, 13, 109, 435, 99, 1435, 709, 4085, 1233, 0 }; - static ulong[] dim1274JoeKuoD7Init = { 1, 1, 7, 1, 1, 55, 5, 107, 435, 663, 441, 3503, 5313, 159, 0 }; - static ulong[] dim1275JoeKuoD7Init = { 1, 1, 7, 13, 19, 57, 17, 13, 25, 1021, 2005, 3445, 4263, 3185, 0 }; - static ulong[] dim1276JoeKuoD7Init = { 1, 3, 1, 7, 5, 5, 37, 99, 237, 563, 483, 1991, 7217, 5433, 0 }; - static ulong[] dim1277JoeKuoD7Init = { 1, 3, 5, 9, 13, 13, 123, 51, 31, 957, 1125, 2125, 2157, 11437, 0 }; - static ulong[] dim1278JoeKuoD7Init = { 1, 1, 7, 11, 5, 59, 53, 193, 337, 5, 1037, 1573, 1147, 7055, 0 }; - static ulong[] dim1279JoeKuoD7Init = { 1, 3, 1, 9, 27, 47, 53, 121, 421, 551, 23, 1603, 1815, 2741, 0 }; - static ulong[] dim1280JoeKuoD7Init = { 1, 3, 3, 13, 27, 7, 79, 255, 209, 441, 1761, 1755, 7077, 3581, 0 }; - static ulong[] dim1281JoeKuoD7Init = { 1, 1, 7, 13, 3, 43, 113, 227, 43, 387, 1255, 1117, 6849, 11715, 0 }; - static ulong[] dim1282JoeKuoD7Init = { 1, 1, 7, 13, 15, 19, 59, 159, 265, 283, 615, 3745, 539, 15195, 0 }; - static ulong[] dim1283JoeKuoD7Init = { 1, 3, 1, 3, 7, 21, 29, 135, 203, 887, 549, 85, 8093, 12527, 0 }; - static ulong[] dim1284JoeKuoD7Init = { 1, 3, 7, 11, 5, 35, 41, 61, 273, 187, 1655, 2449, 2173, 14737, 0 }; - static ulong[] dim1285JoeKuoD7Init = { 1, 3, 1, 9, 29, 49, 11, 33, 477, 671, 1455, 2577, 5239, 5025, 0 }; - static ulong[] dim1286JoeKuoD7Init = { 1, 1, 7, 5, 23, 15, 67, 73, 73, 45, 1727, 645, 2623, 10859, 0 }; - static ulong[] dim1287JoeKuoD7Init = { 1, 1, 7, 15, 29, 37, 45, 183, 97, 297, 593, 833, 5833, 4777, 0 }; - static ulong[] dim1288JoeKuoD7Init = { 1, 1, 7, 5, 27, 21, 5, 253, 243, 993, 1701, 1695, 4037, 1891, 0 }; - static ulong[] dim1289JoeKuoD7Init = { 1, 3, 7, 1, 17, 37, 123, 21, 95, 533, 111, 2605, 7011, 7957, 0 }; - static ulong[] dim1290JoeKuoD7Init = { 1, 3, 1, 1, 5, 43, 11, 143, 457, 607, 469, 1479, 6181, 7579, 0 }; - static ulong[] dim1291JoeKuoD7Init = { 1, 3, 3, 15, 5, 59, 105, 111, 47, 53, 215, 1601, 8057, 4233, 0 }; - static ulong[] dim1292JoeKuoD7Init = { 1, 3, 1, 15, 7, 5, 17, 157, 47, 541, 1487, 2623, 1705, 5565, 0 }; - static ulong[] dim1293JoeKuoD7Init = { 1, 1, 1, 7, 21, 27, 63, 117, 323, 379, 1407, 4043, 3763, 10367, 0 }; - static ulong[] dim1294JoeKuoD7Init = { 1, 1, 3, 7, 27, 11, 35, 81, 447, 279, 811, 1355, 4185, 8281, 0 }; - static ulong[] dim1295JoeKuoD7Init = { 1, 3, 5, 15, 19, 41, 111, 225, 133, 79, 347, 3595, 7863, 5239, 0 }; - static ulong[] dim1296JoeKuoD7Init = { 1, 3, 1, 5, 17, 41, 77, 125, 221, 93, 551, 1263, 1973, 12081, 0 }; - static ulong[] dim1297JoeKuoD7Init = { 1, 3, 5, 3, 17, 55, 9, 149, 203, 217, 1235, 1905, 6139, 7223, 0 }; - static ulong[] dim1298JoeKuoD7Init = { 1, 3, 1, 9, 1, 3, 17, 5, 157, 739, 691, 1471, 709, 1355, 0 }; - static ulong[] dim1299JoeKuoD7Init = { 1, 1, 1, 9, 3, 13, 87, 153, 49, 391, 47, 1703, 1913, 12885, 0 }; - static ulong[] dim1300JoeKuoD7Init = { 1, 1, 7, 3, 19, 49, 91, 47, 263, 287, 1885, 3137, 3709, 8895, 0 }; - static ulong[] dim1301JoeKuoD7Init = { 1, 1, 5, 5, 19, 55, 59, 63, 229, 705, 1791, 1789, 4083, 11827, 0 }; - static ulong[] dim1302JoeKuoD7Init = { 1, 1, 3, 13, 21, 31, 127, 143, 57, 933, 125, 813, 6121, 5883, 0 }; - static ulong[] dim1303JoeKuoD7Init = { 1, 3, 5, 7, 7, 45, 39, 137, 219, 249, 791, 751, 4877, 6935, 0 }; - static ulong[] dim1304JoeKuoD7Init = { 1, 3, 1, 5, 31, 21, 11, 191, 399, 339, 815, 2459, 7621, 1279, 0 }; - static ulong[] dim1305JoeKuoD7Init = { 1, 1, 5, 13, 11, 49, 111, 101, 367, 645, 99, 1759, 2275, 8289, 0 }; - static ulong[] dim1306JoeKuoD7Init = { 1, 1, 1, 9, 15, 23, 17, 93, 339, 705, 1487, 3325, 6585, 13281, 0 }; - static ulong[] dim1307JoeKuoD7Init = { 1, 1, 3, 1, 17, 25, 69, 115, 339, 241, 777, 1585, 2565, 14843, 0 }; - static ulong[] dim1308JoeKuoD7Init = { 1, 3, 5, 7, 5, 45, 99, 161, 505, 511, 591, 2109, 5885, 12547, 0 }; - static ulong[] dim1309JoeKuoD7Init = { 1, 3, 5, 11, 13, 45, 87, 105, 387, 339, 1079, 705, 2385, 9375, 0 }; - static ulong[] dim1310JoeKuoD7Init = { 1, 3, 3, 1, 5, 19, 111, 155, 147, 897, 1879, 243, 3745, 2309, 0 }; - static ulong[] dim1311JoeKuoD7Init = { 1, 3, 3, 1, 1, 1, 123, 153, 409, 101, 105, 1713, 5161, 8915, 0 }; - static ulong[] dim1312JoeKuoD7Init = { 1, 3, 3, 11, 17, 5, 53, 145, 243, 811, 1413, 3735, 6857, 1151, 0 }; - static ulong[] dim1313JoeKuoD7Init = { 1, 1, 3, 13, 9, 35, 127, 245, 479, 691, 281, 845, 4017, 14011, 0 }; - static ulong[] dim1314JoeKuoD7Init = { 1, 1, 1, 15, 3, 27, 11, 231, 47, 1023, 1785, 4039, 137, 3429, 0 }; - static ulong[] dim1315JoeKuoD7Init = { 1, 1, 5, 5, 19, 45, 7, 251, 191, 387, 1853, 3851, 6237, 6475, 0 }; - static ulong[] dim1316JoeKuoD7Init = { 1, 1, 3, 15, 27, 19, 71, 13, 65, 679, 281, 2141, 1211, 4063, 0 }; - static ulong[] dim1317JoeKuoD7Init = { 1, 3, 5, 15, 7, 31, 73, 103, 393, 177, 1929, 809, 3389, 5673, 0 }; - static ulong[] dim1318JoeKuoD7Init = { 1, 1, 5, 7, 1, 45, 35, 247, 485, 25, 1079, 4019, 6101, 4715, 0 }; - static ulong[] dim1319JoeKuoD7Init = { 1, 3, 7, 7, 27, 13, 121, 177, 377, 585, 1503, 1249, 715, 309, 0 }; - static ulong[] dim1320JoeKuoD7Init = { 1, 1, 7, 7, 23, 19, 37, 19, 243, 261, 139, 1261, 3775, 10299, 0 }; - static ulong[] dim1321JoeKuoD7Init = { 1, 1, 1, 11, 23, 1, 123, 225, 497, 131, 1863, 4061, 1247, 12511, 0 }; - static ulong[] dim1322JoeKuoD7Init = { 1, 1, 7, 15, 5, 25, 59, 213, 157, 697, 671, 1431, 2891, 6881, 0 }; - static ulong[] dim1323JoeKuoD7Init = { 1, 1, 5, 9, 1, 33, 67, 121, 165, 867, 393, 1439, 1255, 11839, 0 }; - static ulong[] dim1324JoeKuoD7Init = { 1, 3, 5, 11, 23, 43, 11, 23, 507, 585, 277, 1077, 2697, 4901, 0 }; - static ulong[] dim1325JoeKuoD7Init = { 1, 3, 5, 15, 17, 35, 75, 177, 373, 113, 401, 1999, 1595, 10635, 0 }; - static ulong[] dim1326JoeKuoD7Init = { 1, 3, 7, 11, 31, 49, 65, 225, 217, 783, 787, 1421, 5701, 2185, 0 }; - static ulong[] dim1327JoeKuoD7Init = { 1, 1, 7, 15, 13, 45, 111, 23, 89, 263, 699, 4037, 6937, 6265, 0 }; - static ulong[] dim1328JoeKuoD7Init = { 1, 1, 1, 1, 15, 51, 49, 9, 221, 85, 1983, 2865, 2841, 3105, 0 }; - static ulong[] dim1329JoeKuoD7Init = { 1, 1, 7, 9, 5, 35, 75, 213, 177, 131, 1227, 4069, 5035, 4371, 0 }; - static ulong[] dim1330JoeKuoD7Init = { 1, 1, 7, 5, 1, 33, 75, 125, 5, 283, 667, 1521, 3267, 9641, 0 }; - static ulong[] dim1331JoeKuoD7Init = { 1, 3, 3, 11, 11, 49, 75, 125, 349, 887, 269, 2295, 4049, 1217, 0 }; - static ulong[] dim1332JoeKuoD7Init = { 1, 1, 3, 13, 17, 23, 19, 141, 213, 33, 475, 2543, 3617, 5791, 0 }; - static ulong[] dim1333JoeKuoD7Init = { 1, 3, 3, 11, 3, 39, 95, 139, 277, 109, 601, 2011, 2459, 5915, 0 }; - static ulong[] dim1334JoeKuoD7Init = { 1, 1, 5, 5, 27, 61, 35, 221, 329, 411, 1811, 3397, 1545, 10615, 0 }; - static ulong[] dim1335JoeKuoD7Init = { 1, 3, 5, 3, 3, 55, 71, 187, 371, 223, 1711, 3279, 5541, 4203, 0 }; - static ulong[] dim1336JoeKuoD7Init = { 1, 3, 7, 3, 27, 61, 23, 143, 475, 693, 1717, 353, 4381, 11355, 0 }; - static ulong[] dim1337JoeKuoD7Init = { 1, 1, 7, 13, 9, 23, 109, 11, 483, 1005, 1709, 2883, 5021, 10079, 0 }; - static ulong[] dim1338JoeKuoD7Init = { 1, 1, 5, 9, 25, 19, 79, 169, 433, 177, 1071, 3413, 2071, 3565, 0 }; - static ulong[] dim1339JoeKuoD7Init = { 1, 1, 5, 7, 7, 47, 105, 225, 153, 949, 9, 2383, 3947, 2711, 0 }; - static ulong[] dim1340JoeKuoD7Init = { 1, 3, 7, 9, 1, 17, 87, 159, 107, 41, 1459, 2133, 6261, 15637, 0 }; - static ulong[] dim1341JoeKuoD7Init = { 1, 3, 3, 3, 1, 7, 45, 255, 377, 811, 1911, 2727, 7223, 3825, 0 }; - static ulong[] dim1342JoeKuoD7Init = { 1, 1, 1, 13, 13, 13, 5, 59, 421, 585, 1651, 55, 2877, 11643, 0 }; - static ulong[] dim1343JoeKuoD7Init = { 1, 1, 3, 11, 15, 57, 1, 173, 189, 485, 1881, 3449, 1831, 2501, 0 }; - static ulong[] dim1344JoeKuoD7Init = { 1, 3, 3, 7, 21, 29, 49, 255, 313, 137, 51, 2281, 973, 16053, 0 }; - static ulong[] dim1345JoeKuoD7Init = { 1, 1, 1, 11, 23, 61, 99, 77, 399, 649, 1567, 1701, 4747, 1301, 0 }; - static ulong[] dim1346JoeKuoD7Init = { 1, 3, 7, 3, 11, 57, 45, 169, 247, 73, 1685, 341, 6791, 2833, 0 }; - static ulong[] dim1347JoeKuoD7Init = { 1, 1, 5, 13, 9, 5, 17, 209, 329, 379, 1787, 737, 7271, 7357, 0 }; - static ulong[] dim1348JoeKuoD7Init = { 1, 3, 1, 9, 13, 7, 97, 165, 99, 599, 471, 2945, 3125, 10413, 0 }; - static ulong[] dim1349JoeKuoD7Init = { 1, 3, 1, 11, 31, 29, 45, 3, 457, 673, 589, 2521, 5655, 13973, 0 }; - static ulong[] dim1350JoeKuoD7Init = { 1, 1, 7, 1, 15, 15, 61, 77, 321, 317, 993, 1101, 5885, 5105, 0 }; - static ulong[] dim1351JoeKuoD7Init = { 1, 1, 1, 5, 7, 45, 111, 129, 407, 117, 93, 2399, 1049, 12435, 0 }; - static ulong[] dim1352JoeKuoD7Init = { 1, 3, 7, 3, 11, 29, 103, 189, 29, 899, 1141, 1799, 4439, 2907, 0 }; - static ulong[] dim1353JoeKuoD7Init = { 1, 1, 1, 5, 3, 39, 25, 255, 97, 1015, 727, 377, 8015, 12617, 0 }; - static ulong[] dim1354JoeKuoD7Init = { 1, 3, 3, 11, 29, 23, 103, 51, 95, 333, 171, 3019, 1373, 13379, 0 }; - static ulong[] dim1355JoeKuoD7Init = { 1, 3, 1, 9, 21, 49, 57, 157, 337, 141, 307, 2333, 1857, 8739, 0 }; - static ulong[] dim1356JoeKuoD7Init = { 1, 1, 1, 11, 9, 35, 33, 93, 211, 969, 1093, 4053, 1313, 12771, 0 }; - static ulong[] dim1357JoeKuoD7Init = { 1, 3, 1, 9, 27, 7, 77, 65, 425, 603, 261, 2321, 579, 1249, 0 }; - static ulong[] dim1358JoeKuoD7Init = { 1, 3, 5, 13, 29, 39, 21, 243, 115, 201, 749, 3049, 3113, 1485, 0 }; - static ulong[] dim1359JoeKuoD7Init = { 1, 1, 5, 15, 23, 53, 27, 189, 193, 281, 149, 2205, 6149, 2669, 0 }; - static ulong[] dim1360JoeKuoD7Init = { 1, 1, 5, 13, 9, 13, 65, 37, 161, 59, 1691, 435, 6077, 14827, 0 }; - static ulong[] dim1361JoeKuoD7Init = { 1, 1, 3, 15, 5, 35, 41, 239, 177, 265, 389, 1829, 1229, 14351, 0 }; - static ulong[] dim1362JoeKuoD7Init = { 1, 1, 5, 3, 7, 27, 61, 107, 171, 411, 685, 455, 5175, 4981, 0 }; - static ulong[] dim1363JoeKuoD7Init = { 1, 1, 3, 7, 13, 23, 107, 63, 71, 755, 535, 1819, 1545, 2075, 0 }; - static ulong[] dim1364JoeKuoD7Init = { 1, 1, 5, 15, 1, 27, 61, 247, 333, 549, 981, 3201, 919, 1505, 0 }; - static ulong[] dim1365JoeKuoD7Init = { 1, 1, 3, 5, 29, 27, 93, 147, 105, 83, 209, 61, 3045, 4639, 0 }; - static ulong[] dim1366JoeKuoD7Init = { 1, 1, 7, 7, 25, 35, 77, 59, 157, 993, 325, 3085, 671, 3573, 0 }; - static ulong[] dim1367JoeKuoD7Init = { 1, 3, 1, 15, 15, 45, 31, 93, 367, 747, 969, 3443, 3825, 2997, 0 }; - static ulong[] dim1368JoeKuoD7Init = { 1, 1, 1, 5, 27, 21, 23, 63, 271, 515, 261, 1947, 6257, 12861, 0 }; - static ulong[] dim1369JoeKuoD7Init = { 1, 3, 7, 7, 27, 51, 31, 229, 225, 283, 947, 759, 5431, 2161, 0 }; - static ulong[] dim1370JoeKuoD7Init = { 1, 1, 3, 13, 7, 39, 5, 223, 55, 999, 697, 3383, 1605, 15315, 0 }; - static ulong[] dim1371JoeKuoD7Init = { 1, 1, 3, 3, 29, 13, 103, 215, 73, 715, 1117, 3399, 1867, 8049, 0 }; - static ulong[] dim1372JoeKuoD7Init = { 1, 3, 3, 3, 1, 33, 121, 135, 105, 335, 105, 815, 1601, 15785, 0 }; - static ulong[] dim1373JoeKuoD7Init = { 1, 1, 3, 13, 13, 27, 39, 119, 271, 75, 1531, 649, 8035, 5533, 0 }; - static ulong[] dim1374JoeKuoD7Init = { 1, 3, 7, 3, 9, 47, 109, 85, 135, 553, 1091, 3077, 5527, 15225, 0 }; - static ulong[] dim1375JoeKuoD7Init = { 1, 3, 3, 5, 31, 11, 127, 197, 257, 281, 1939, 3711, 2871, 11953, 0 }; - static ulong[] dim1376JoeKuoD7Init = { 1, 1, 1, 15, 21, 51, 57, 159, 445, 521, 27, 1313, 6031, 2891, 0 }; - static ulong[] dim1377JoeKuoD7Init = { 1, 1, 7, 15, 21, 57, 53, 29, 39, 547, 1995, 3605, 3899, 1199, 0 }; - static ulong[] dim1378JoeKuoD7Init = { 1, 1, 5, 3, 1, 59, 69, 21, 383, 743, 87, 3369, 2309, 9651, 0 }; - static ulong[] dim1379JoeKuoD7Init = { 1, 3, 7, 13, 3, 9, 41, 77, 201, 331, 1007, 1503, 5771, 567, 0 }; - static ulong[] dim1380JoeKuoD7Init = { 1, 1, 3, 15, 19, 19, 61, 221, 257, 903, 83, 1923, 6453, 11275, 0 }; - static ulong[] dim1381JoeKuoD7Init = { 1, 1, 5, 13, 21, 21, 101, 109, 419, 409, 125, 3337, 5763, 4945, 0 }; - static ulong[] dim1382JoeKuoD7Init = { 1, 1, 5, 11, 27, 21, 39, 63, 475, 285, 917, 4017, 1491, 9479, 0 }; - static ulong[] dim1383JoeKuoD7Init = { 1, 1, 7, 1, 23, 59, 119, 89, 309, 567, 1781, 2369, 4311, 16033, 0 }; - static ulong[] dim1384JoeKuoD7Init = { 1, 1, 1, 3, 13, 51, 69, 71, 89, 1013, 329, 69, 1107, 14509, 0 }; - static ulong[] dim1385JoeKuoD7Init = { 1, 1, 3, 7, 23, 39, 9, 137, 65, 83, 1001, 271, 2127, 9715, 0 }; - static ulong[] dim1386JoeKuoD7Init = { 1, 3, 3, 9, 13, 1, 67, 233, 333, 365, 1717, 77, 7173, 1271, 0 }; - static ulong[] dim1387JoeKuoD7Init = { 1, 3, 7, 7, 15, 3, 115, 237, 467, 827, 389, 1901, 6767, 7809, 0 }; - static ulong[] dim1388JoeKuoD7Init = { 1, 3, 1, 15, 23, 27, 117, 99, 49, 863, 1775, 1729, 8069, 9917, 0 }; - static ulong[] dim1389JoeKuoD7Init = { 1, 3, 1, 11, 23, 47, 75, 91, 47, 99, 1187, 1911, 2453, 5055, 0 }; - static ulong[] dim1390JoeKuoD7Init = { 1, 1, 7, 11, 15, 51, 43, 133, 175, 647, 1053, 439, 1933, 7339, 0 }; - static ulong[] dim1391JoeKuoD7Init = { 1, 1, 5, 13, 5, 37, 105, 243, 467, 255, 715, 1023, 4331, 8943, 0 }; - static ulong[] dim1392JoeKuoD7Init = { 1, 1, 1, 15, 15, 55, 59, 111, 351, 345, 1517, 3009, 4149, 8511, 0 }; - static ulong[] dim1393JoeKuoD7Init = { 1, 1, 7, 5, 3, 55, 123, 61, 405, 719, 245, 2745, 7471, 2205, 0 }; - static ulong[] dim1394JoeKuoD7Init = { 1, 1, 1, 9, 19, 25, 43, 105, 215, 117, 563, 513, 4609, 13307, 0 }; - static ulong[] dim1395JoeKuoD7Init = { 1, 3, 5, 5, 21, 27, 107, 131, 329, 519, 369, 2523, 4099, 13943, 0 }; - static ulong[] dim1396JoeKuoD7Init = { 1, 1, 3, 13, 27, 15, 25, 63, 5, 513, 1641, 3955, 4233, 12263, 0 }; - static ulong[] dim1397JoeKuoD7Init = { 1, 3, 5, 5, 3, 51, 49, 49, 197, 919, 281, 3713, 2179, 4573, 0 }; - static ulong[] dim1398JoeKuoD7Init = { 1, 1, 7, 5, 25, 15, 49, 159, 53, 609, 573, 1533, 4589, 10593, 0 }; - static ulong[] dim1399JoeKuoD7Init = { 1, 3, 5, 15, 7, 21, 61, 129, 53, 95, 1107, 57, 2559, 11977, 0 }; - static ulong[] dim1400JoeKuoD7Init = { 1, 1, 5, 5, 5, 5, 75, 153, 359, 345, 1739, 2047, 6355, 5801, 0 }; - static ulong[] dim1401JoeKuoD7Init = { 1, 3, 1, 13, 17, 5, 39, 209, 399, 127, 1215, 2377, 7707, 5191, 0 }; - static ulong[] dim1402JoeKuoD7Init = { 1, 1, 7, 3, 25, 31, 33, 93, 1, 229, 1379, 1587, 2245, 16041, 0 }; - static ulong[] dim1403JoeKuoD7Init = { 1, 3, 5, 13, 25, 51, 5, 1, 237, 471, 637, 3205, 4629, 15929, 0 }; - static ulong[] dim1404JoeKuoD7Init = { 1, 3, 5, 11, 27, 57, 45, 141, 167, 949, 1839, 289, 2637, 2041, 0 }; - static ulong[] dim1405JoeKuoD7Init = { 1, 1, 3, 7, 9, 57, 69, 93, 301, 805, 1265, 3415, 2395, 2949, 0 }; - static ulong[] dim1406JoeKuoD7Init = { 1, 1, 3, 15, 9, 61, 17, 185, 201, 743, 1903, 1161, 1693, 15125, 0 }; - static ulong[] dim1407JoeKuoD7Init = { 1, 3, 3, 3, 21, 47, 125, 117, 213, 761, 1357, 2455, 7065, 7335, 0 }; - static ulong[] dim1408JoeKuoD7Init = { 1, 3, 5, 7, 23, 15, 39, 17, 373, 777, 761, 3853, 3607, 2119, 0 }; - static ulong[] dim1409JoeKuoD7Init = { 1, 3, 1, 1, 31, 9, 45, 109, 209, 797, 777, 2381, 5047, 12453, 0 }; - static ulong[] dim1410JoeKuoD7Init = { 1, 3, 1, 1, 1, 9, 13, 171, 223, 987, 1815, 1953, 4439, 3973, 0 }; - static ulong[] dim1411JoeKuoD7Init = { 1, 1, 7, 9, 19, 11, 37, 87, 117, 399, 705, 2839, 3699, 13249, 0 }; - static ulong[] dim1412JoeKuoD7Init = { 1, 3, 3, 1, 21, 45, 25, 41, 133, 721, 289, 727, 7835, 9811, 0 }; - static ulong[] dim1413JoeKuoD7Init = { 1, 1, 7, 9, 23, 7, 75, 233, 113, 945, 1447, 4031, 6791, 6285, 0 }; - static ulong[] dim1414JoeKuoD7Init = { 1, 1, 3, 9, 3, 1, 127, 139, 391, 745, 807, 3229, 1809, 7587, 0 }; - static ulong[] dim1415JoeKuoD7Init = { 1, 1, 5, 3, 29, 47, 99, 115, 37, 487, 1897, 2433, 4925, 9747, 0 }; - static ulong[] dim1416JoeKuoD7Init = { 1, 1, 7, 15, 23, 25, 95, 165, 257, 67, 1445, 4055, 3761, 10411, 0 }; - static ulong[] dim1417JoeKuoD7Init = { 1, 3, 3, 11, 5, 27, 77, 197, 9, 679, 1259, 3289, 621, 2733, 0 }; - static ulong[] dim1418JoeKuoD7Init = { 1, 3, 7, 9, 27, 51, 57, 189, 511, 633, 431, 43, 2613, 5863, 0 }; - static ulong[] dim1419JoeKuoD7Init = { 1, 1, 1, 11, 29, 53, 79, 237, 15, 377, 45, 347, 5733, 3531, 0 }; - static ulong[] dim1420JoeKuoD7Init = { 1, 1, 1, 1, 25, 7, 87, 211, 429, 745, 673, 3967, 2059, 785, 0 }; - static ulong[] dim1421JoeKuoD7Init = { 1, 3, 1, 5, 21, 31, 7, 43, 381, 635, 35, 1247, 8061, 3907, 0 }; - static ulong[] dim1422JoeKuoD7Init = { 1, 3, 1, 9, 11, 39, 79, 9, 395, 611, 1087, 2837, 6979, 7651, 0 }; - static ulong[] dim1423JoeKuoD7Init = { 1, 3, 3, 13, 11, 37, 35, 61, 373, 1001, 1849, 2169, 903, 10993, 0 }; - static ulong[] dim1424JoeKuoD7Init = { 1, 1, 3, 3, 29, 3, 43, 155, 403, 597, 1437, 4031, 7169, 15333, 0 }; - static ulong[] dim1425JoeKuoD7Init = { 1, 3, 5, 1, 17, 29, 57, 245, 505, 915, 933, 1313, 7295, 12105, 0 }; - static ulong[] dim1426JoeKuoD7Init = { 1, 1, 3, 9, 29, 13, 49, 89, 377, 131, 31, 1869, 1717, 7679, 0 }; - static ulong[] dim1427JoeKuoD7Init = { 1, 1, 1, 7, 27, 43, 1, 107, 167, 851, 743, 2837, 6705, 2913, 0 }; - static ulong[] dim1428JoeKuoD7Init = { 1, 1, 3, 13, 5, 27, 77, 91, 305, 941, 1293, 2343, 5397, 6487, 0 }; - static ulong[] dim1429JoeKuoD7Init = { 1, 1, 7, 5, 11, 29, 25, 233, 391, 221, 1285, 3995, 2713, 9125, 0 }; - static ulong[] dim1430JoeKuoD7Init = { 1, 1, 7, 3, 11, 47, 77, 31, 233, 775, 1399, 1519, 3427, 10027, 0 }; - static ulong[] dim1431JoeKuoD7Init = { 1, 3, 3, 3, 5, 7, 37, 111, 265, 541, 77, 3327, 8115, 5541, 0 }; - static ulong[] dim1432JoeKuoD7Init = { 1, 1, 1, 5, 25, 27, 91, 185, 447, 225, 615, 2141, 2813, 9509, 0 }; - static ulong[] dim1433JoeKuoD7Init = { 1, 1, 7, 5, 15, 21, 107, 61, 259, 651, 1401, 3733, 6255, 5995, 0 }; - static ulong[] dim1434JoeKuoD7Init = { 1, 1, 7, 11, 21, 5, 121, 229, 497, 267, 1077, 3835, 4619, 8791, 0 }; - static ulong[] dim1435JoeKuoD7Init = { 1, 1, 3, 3, 19, 59, 85, 115, 19, 69, 1937, 711, 7911, 2615, 0 }; - static ulong[] dim1436JoeKuoD7Init = { 1, 3, 5, 11, 1, 9, 117, 229, 307, 355, 1635, 863, 4931, 5997, 0 }; - static ulong[] dim1437JoeKuoD7Init = { 1, 3, 5, 11, 21, 17, 119, 163, 297, 641, 291, 2287, 4611, 4419, 0 }; - static ulong[] dim1438JoeKuoD7Init = { 1, 1, 5, 7, 13, 59, 53, 17, 321, 263, 1929, 3277, 6209, 2649, 0 }; - static ulong[] dim1439JoeKuoD7Init = { 1, 3, 5, 13, 3, 35, 35, 249, 359, 479, 1067, 2507, 4809, 7427, 0 }; - static ulong[] dim1440JoeKuoD7Init = { 1, 3, 3, 1, 27, 57, 101, 47, 383, 937, 969, 307, 7617, 9579, 0 }; - static ulong[] dim1441JoeKuoD7Init = { 1, 1, 7, 13, 27, 61, 39, 177, 413, 435, 1529, 2773, 2267, 12597, 0 }; - static ulong[] dim1442JoeKuoD7Init = { 1, 3, 3, 5, 25, 61, 57, 175, 407, 341, 1979, 2237, 3557, 6841, 0 }; - static ulong[] dim1443JoeKuoD7Init = { 1, 3, 7, 5, 11, 23, 97, 247, 187, 555, 1603, 1871, 7427, 10605, 0 }; - static ulong[] dim1444JoeKuoD7Init = { 1, 1, 7, 15, 7, 21, 23, 165, 235, 937, 739, 2579, 6621, 12661, 0 }; - static ulong[] dim1445JoeKuoD7Init = { 1, 1, 5, 1, 13, 47, 103, 107, 87, 941, 563, 1007, 7483, 11721, 0 }; - static ulong[] dim1446JoeKuoD7Init = { 1, 1, 1, 15, 29, 63, 55, 215, 95, 991, 1017, 921, 8113, 11747, 0 }; - static ulong[] dim1447JoeKuoD7Init = { 1, 1, 3, 15, 3, 25, 79, 5, 401, 473, 125, 2135, 6443, 10773, 0 }; - static ulong[] dim1448JoeKuoD7Init = { 1, 3, 1, 9, 31, 21, 71, 185, 75, 43, 1131, 3885, 3879, 2695, 0 }; - static ulong[] dim1449JoeKuoD7Init = { 1, 1, 5, 13, 13, 41, 117, 109, 429, 473, 35, 123, 5545, 7015, 0 }; - static ulong[] dim1450JoeKuoD7Init = { 1, 1, 7, 13, 21, 57, 55, 241, 107, 689, 707, 45, 8175, 15185, 0 }; - static ulong[] dim1451JoeKuoD7Init = { 1, 3, 3, 7, 25, 5, 123, 173, 57, 517, 1605, 2355, 411, 14485, 0 }; - static ulong[] dim1452JoeKuoD7Init = { 1, 1, 3, 13, 11, 17, 95, 129, 9, 1013, 1683, 461, 697, 8089, 0 }; - static ulong[] dim1453JoeKuoD7Init = { 1, 1, 1, 3, 19, 49, 49, 247, 371, 175, 1803, 119, 365, 10281, 0 }; - static ulong[] dim1454JoeKuoD7Init = { 1, 1, 7, 15, 13, 57, 93, 245, 469, 933, 225, 2645, 6325, 9545, 0 }; - static ulong[] dim1455JoeKuoD7Init = { 1, 3, 1, 9, 11, 37, 1, 203, 227, 809, 2035, 99, 2693, 13591, 0 }; - static ulong[] dim1456JoeKuoD7Init = { 1, 3, 1, 3, 29, 7, 71, 7, 295, 203, 401, 461, 5351, 8223, 0 }; - static ulong[] dim1457JoeKuoD7Init = { 1, 1, 7, 1, 25, 31, 57, 35, 131, 411, 945, 1441, 4487, 2659, 0 }; - static ulong[] dim1458JoeKuoD7Init = { 1, 3, 7, 15, 15, 19, 89, 253, 141, 549, 751, 1267, 717, 7185, 0 }; - static ulong[] dim1459JoeKuoD7Init = { 1, 3, 5, 13, 1, 15, 61, 19, 331, 347, 1019, 1913, 6233, 8913, 0 }; - static ulong[] dim1460JoeKuoD7Init = { 1, 3, 7, 15, 7, 25, 59, 75, 455, 411, 325, 553, 5861, 915, 0 }; - static ulong[] dim1461JoeKuoD7Init = { 1, 1, 3, 5, 31, 49, 91, 107, 279, 405, 517, 55, 2121, 6971, 0 }; - static ulong[] dim1462JoeKuoD7Init = { 1, 3, 5, 7, 5, 39, 29, 205, 33, 827, 1593, 3503, 5461, 16147, 0 }; - static ulong[] dim1463JoeKuoD7Init = { 1, 1, 1, 13, 11, 13, 83, 99, 369, 283, 873, 1247, 6159, 15495, 0 }; - static ulong[] dim1464JoeKuoD7Init = { 1, 3, 1, 15, 25, 61, 71, 63, 333, 183, 1317, 3467, 5483, 11591, 0 }; - static ulong[] dim1465JoeKuoD7Init = { 1, 1, 1, 15, 27, 23, 1, 173, 407, 525, 1841, 347, 6103, 6449, 0 }; - static ulong[] dim1466JoeKuoD7Init = { 1, 1, 5, 3, 9, 45, 39, 215, 329, 457, 1341, 3037, 1631, 15335, 0 }; - static ulong[] dim1467JoeKuoD7Init = { 1, 3, 5, 3, 13, 53, 65, 177, 105, 21, 685, 3111, 7487, 1463, 0 }; - static ulong[] dim1468JoeKuoD7Init = { 1, 3, 5, 5, 5, 31, 69, 65, 381, 375, 221, 477, 3311, 12103, 0 }; - static ulong[] dim1469JoeKuoD7Init = { 1, 1, 7, 9, 25, 59, 57, 221, 293, 237, 429, 503, 6539, 14773, 0 }; - static ulong[] dim1470JoeKuoD7Init = { 1, 3, 7, 13, 9, 3, 47, 21, 115, 321, 389, 1631, 2715, 6607, 0 }; - static ulong[] dim1471JoeKuoD7Init = { 1, 3, 7, 15, 7, 31, 105, 5, 449, 195, 65, 3895, 7093, 3229, 0 }; - static ulong[] dim1472JoeKuoD7Init = { 1, 3, 7, 1, 1, 55, 119, 5, 39, 143, 905, 2813, 1723, 3705, 0 }; - static ulong[] dim1473JoeKuoD7Init = { 1, 3, 7, 3, 23, 47, 61, 239, 369, 485, 1857, 2105, 2681, 13723, 0 }; - static ulong[] dim1474JoeKuoD7Init = { 1, 3, 3, 5, 19, 5, 43, 155, 445, 597, 1201, 1625, 5273, 13569, 0 }; - static ulong[] dim1475JoeKuoD7Init = { 1, 1, 3, 9, 3, 63, 35, 103, 67, 259, 493, 2847, 1149, 8367, 0 }; - static ulong[] dim1476JoeKuoD7Init = { 1, 3, 7, 11, 19, 35, 15, 245, 59, 65, 75, 1297, 1637, 9081, 0 }; - static ulong[] dim1477JoeKuoD7Init = { 1, 1, 7, 11, 3, 23, 73, 163, 323, 857, 441, 399, 5447, 16365, 0 }; - static ulong[] dim1478JoeKuoD7Init = { 1, 3, 1, 7, 31, 55, 125, 255, 173, 203, 1537, 475, 2955, 12461, 0 }; - static ulong[] dim1479JoeKuoD7Init = { 1, 3, 5, 9, 27, 37, 69, 183, 319, 435, 807, 557, 7093, 2935, 0 }; - static ulong[] dim1480JoeKuoD7Init = { 1, 1, 3, 5, 23, 53, 105, 211, 49, 815, 97, 915, 7607, 8847, 0 }; - static ulong[] dim1481JoeKuoD7Init = { 1, 1, 1, 13, 13, 49, 43, 203, 293, 771, 1021, 535, 4655, 14727, 0 }; - static ulong[] dim1482JoeKuoD7Init = { 1, 3, 3, 5, 13, 49, 89, 75, 227, 821, 7, 2539, 7627, 6301, 0 }; - static ulong[] dim1483JoeKuoD7Init = { 1, 1, 3, 9, 5, 11, 35, 71, 187, 739, 1191, 2255, 2131, 13649, 0 }; - static ulong[] dim1484JoeKuoD7Init = { 1, 3, 1, 5, 5, 37, 105, 29, 453, 251, 1111, 2345, 6297, 14701, 0 }; - static ulong[] dim1485JoeKuoD7Init = { 1, 3, 1, 7, 31, 21, 5, 33, 245, 1007, 1981, 3775, 8169, 955, 0 }; - static ulong[] dim1486JoeKuoD7Init = { 1, 1, 3, 11, 11, 51, 45, 35, 351, 479, 1307, 3009, 7285, 5261, 0 }; - static ulong[] dim1487JoeKuoD7Init = { 1, 3, 3, 13, 5, 13, 119, 41, 175, 995, 1461, 2739, 7281, 7533, 0 }; - static ulong[] dim1488JoeKuoD7Init = { 1, 3, 5, 9, 7, 5, 7, 153, 233, 209, 1235, 3457, 3113, 13215, 0 }; - static ulong[] dim1489JoeKuoD7Init = { 1, 1, 3, 15, 9, 29, 41, 103, 389, 541, 1697, 893, 6507, 10805, 0 }; - static ulong[] dim1490JoeKuoD7Init = { 1, 1, 3, 3, 19, 11, 73, 73, 439, 985, 1215, 1481, 617, 5343, 0 }; - static ulong[] dim1491JoeKuoD7Init = { 1, 3, 7, 11, 7, 15, 81, 203, 41, 789, 283, 691, 3495, 12143, 0 }; - static ulong[] dim1492JoeKuoD7Init = { 1, 3, 7, 9, 21, 61, 101, 185, 193, 159, 13, 2571, 545, 3043, 0 }; - static ulong[] dim1493JoeKuoD7Init = { 1, 3, 7, 1, 11, 29, 107, 179, 69, 899, 1275, 1647, 1061, 12283, 0 }; - static ulong[] dim1494JoeKuoD7Init = { 1, 3, 1, 7, 15, 43, 3, 207, 75, 669, 1239, 1339, 571, 5483, 0 }; - static ulong[] dim1495JoeKuoD7Init = { 1, 3, 1, 1, 7, 23, 49, 183, 305, 309, 657, 1951, 6377, 4165, 0 }; - static ulong[] dim1496JoeKuoD7Init = { 1, 1, 1, 3, 5, 21, 51, 177, 101, 95, 1331, 357, 6777, 13199, 0 }; - static ulong[] dim1497JoeKuoD7Init = { 1, 3, 7, 3, 31, 3, 11, 179, 95, 219, 395, 603, 7397, 12045, 0 }; - static ulong[] dim1498JoeKuoD7Init = { 1, 3, 7, 1, 21, 35, 79, 255, 443, 123, 551, 1113, 8133, 11621, 0 }; - static ulong[] dim1499JoeKuoD7Init = { 1, 3, 7, 1, 11, 7, 125, 133, 429, 81, 91, 1135, 5165, 14953, 0 }; - static ulong[] dim1500JoeKuoD7Init = { 1, 3, 5, 9, 25, 17, 103, 39, 167, 459, 703, 759, 1771, 723, 0 }; - static ulong[] dim1501JoeKuoD7Init = { 1, 3, 5, 5, 7, 21, 113, 121, 97, 231, 59, 1679, 1409, 5045, 0 }; - static ulong[] dim1502JoeKuoD7Init = { 1, 3, 1, 9, 19, 17, 117, 225, 163, 183, 89, 2251, 4777, 14553, 0 }; - static ulong[] dim1503JoeKuoD7Init = { 1, 3, 1, 7, 7, 61, 25, 211, 65, 273, 1427, 585, 5907, 1031, 0 }; - static ulong[] dim1504JoeKuoD7Init = { 1, 1, 7, 3, 25, 27, 69, 113, 29, 67, 2025, 37, 7357, 14879, 0 }; - static ulong[] dim1505JoeKuoD7Init = { 1, 1, 5, 11, 23, 59, 107, 179, 187, 989, 1043, 409, 489, 3289, 0 }; - static ulong[] dim1506JoeKuoD7Init = { 1, 1, 1, 7, 5, 39, 79, 23, 443, 701, 789, 1723, 7595, 8003, 0 }; - static ulong[] dim1507JoeKuoD7Init = { 1, 3, 1, 11, 13, 25, 29, 167, 143, 735, 1623, 2005, 3731, 1413, 0 }; - static ulong[] dim1508JoeKuoD7Init = { 1, 1, 7, 13, 23, 19, 3, 143, 69, 331, 71, 3233, 4187, 13927, 0 }; - static ulong[] dim1509JoeKuoD7Init = { 1, 3, 3, 5, 23, 21, 121, 47, 291, 883, 43, 419, 297, 8385, 0 }; - static ulong[] dim1510JoeKuoD7Init = { 1, 1, 3, 5, 19, 63, 57, 127, 59, 539, 207, 3805, 4741, 12519, 0 }; - static ulong[] dim1511JoeKuoD7Init = { 1, 3, 3, 5, 5, 23, 117, 45, 501, 903, 1241, 3853, 989, 7997, 0 }; - static ulong[] dim1512JoeKuoD7Init = { 1, 1, 3, 5, 11, 27, 17, 21, 373, 755, 1149, 3443, 3489, 11701, 0 }; - static ulong[] dim1513JoeKuoD7Init = { 1, 1, 5, 7, 7, 55, 75, 29, 241, 707, 555, 1683, 1311, 14769, 0 }; - static ulong[] dim1514JoeKuoD7Init = { 1, 3, 5, 13, 19, 55, 87, 145, 27, 935, 519, 1083, 1115, 10963, 0 }; - static ulong[] dim1515JoeKuoD7Init = { 1, 1, 3, 13, 5, 11, 25, 215, 483, 817, 101, 981, 5125, 15257, 0 }; - static ulong[] dim1516JoeKuoD7Init = { 1, 3, 1, 11, 21, 59, 93, 55, 447, 5, 1225, 827, 1539, 4035, 0 }; - static ulong[] dim1517JoeKuoD7Init = { 1, 1, 1, 13, 3, 53, 5, 39, 475, 475, 905, 355, 6319, 415, 0 }; - static ulong[] dim1518JoeKuoD7Init = { 1, 1, 7, 9, 21, 49, 69, 109, 3, 441, 1533, 2359, 4025, 15949, 0 }; - static ulong[] dim1519JoeKuoD7Init = { 1, 1, 3, 13, 3, 59, 67, 147, 151, 27, 1039, 2331, 2839, 15939, 0 }; - static ulong[] dim1520JoeKuoD7Init = { 1, 3, 7, 9, 7, 17, 13, 153, 415, 147, 181, 3441, 7997, 3175, 0 }; - static ulong[] dim1521JoeKuoD7Init = { 1, 3, 5, 13, 9, 61, 123, 177, 497, 989, 525, 1819, 5963, 2051, 0 }; - static ulong[] dim1522JoeKuoD7Init = { 1, 1, 1, 1, 11, 13, 17, 147, 57, 367, 477, 1009, 4613, 16357, 0 }; - static ulong[] dim1523JoeKuoD7Init = { 1, 3, 7, 9, 27, 27, 29, 61, 499, 191, 43, 1109, 5805, 12799, 0 }; - static ulong[] dim1524JoeKuoD7Init = { 1, 3, 5, 9, 11, 61, 57, 139, 173, 725, 1879, 1861, 7123, 9505, 0 }; - static ulong[] dim1525JoeKuoD7Init = { 1, 3, 1, 5, 11, 1, 93, 179, 3, 893, 1917, 2293, 5105, 12093, 0 }; - static ulong[] dim1526JoeKuoD7Init = { 1, 1, 5, 9, 31, 45, 107, 19, 285, 81, 339, 3051, 1369, 10841, 0 }; - static ulong[] dim1527JoeKuoD7Init = { 1, 1, 7, 9, 27, 49, 19, 29, 155, 389, 1287, 3, 2311, 7561, 0 }; - static ulong[] dim1528JoeKuoD7Init = { 1, 3, 3, 9, 9, 1, 45, 171, 245, 897, 1881, 2683, 4185, 14049, 0 }; - static ulong[] dim1529JoeKuoD7Init = { 1, 3, 1, 15, 19, 37, 19, 227, 133, 573, 1897, 1231, 1649, 8481, 0 }; - static ulong[] dim1530JoeKuoD7Init = { 1, 3, 1, 15, 5, 19, 27, 85, 281, 471, 3, 2149, 4785, 12391, 0 }; - static ulong[] dim1531JoeKuoD7Init = { 1, 1, 7, 3, 17, 5, 127, 37, 299, 467, 1523, 3421, 4119, 11151, 0 }; - static ulong[] dim1532JoeKuoD7Init = { 1, 3, 3, 13, 11, 5, 15, 137, 459, 553, 785, 1149, 6107, 321, 0 }; - static ulong[] dim1533JoeKuoD7Init = { 1, 1, 3, 3, 7, 19, 85, 133, 7, 753, 65, 3341, 5859, 3829, 0 }; - static ulong[] dim1534JoeKuoD7Init = { 1, 3, 3, 11, 19, 13, 17, 191, 121, 895, 761, 2431, 5887, 10961, 0 }; - static ulong[] dim1535JoeKuoD7Init = { 1, 3, 5, 7, 1, 63, 47, 43, 119, 311, 935, 2299, 1509, 4821, 0 }; - static ulong[] dim1536JoeKuoD7Init = { 1, 1, 7, 7, 27, 51, 93, 195, 397, 155, 471, 2547, 8007, 15575, 0 }; - static ulong[] dim1537JoeKuoD7Init = { 1, 3, 3, 5, 25, 13, 125, 239, 93, 983, 293, 1317, 115, 6417, 0 }; - static ulong[] dim1538JoeKuoD7Init = { 1, 3, 3, 3, 9, 61, 93, 15, 495, 295, 1391, 2833, 45, 9039, 0 }; - static ulong[] dim1539JoeKuoD7Init = { 1, 1, 1, 9, 11, 31, 125, 5, 65, 173, 1189, 2363, 6603, 15891, 0 }; - static ulong[] dim1540JoeKuoD7Init = { 1, 1, 7, 5, 5, 63, 53, 35, 311, 935, 1591, 309, 7829, 1495, 0 }; - static ulong[] dim1541JoeKuoD7Init = { 1, 3, 5, 5, 29, 21, 121, 199, 153, 933, 1577, 1681, 1883, 7697, 0 }; - static ulong[] dim1542JoeKuoD7Init = { 1, 1, 1, 11, 19, 23, 111, 113, 73, 99, 1385, 591, 6977, 11995, 0 }; - static ulong[] dim1543JoeKuoD7Init = { 1, 1, 1, 13, 27, 11, 23, 79, 429, 505, 1693, 919, 3699, 3815, 0 }; - static ulong[] dim1544JoeKuoD7Init = { 1, 1, 3, 9, 7, 23, 29, 197, 465, 267, 915, 1455, 2155, 15105, 0 }; - static ulong[] dim1545JoeKuoD7Init = { 1, 1, 7, 9, 17, 3, 7, 73, 417, 841, 1123, 3425, 4691, 14703, 0 }; - static ulong[] dim1546JoeKuoD7Init = { 1, 3, 5, 15, 15, 7, 75, 85, 441, 5, 1593, 43, 1207, 12117, 0 }; - static ulong[] dim1547JoeKuoD7Init = { 1, 1, 1, 7, 21, 45, 93, 133, 31, 249, 701, 97, 1033, 15359, 0 }; - static ulong[] dim1548JoeKuoD7Init = { 1, 1, 3, 7, 3, 5, 9, 21, 339, 661, 1841, 2209, 5869, 10291, 0 }; - static ulong[] dim1549JoeKuoD7Init = { 1, 1, 5, 11, 13, 3, 67, 135, 69, 117, 43, 2885, 5719, 427, 0 }; - static ulong[] dim1550JoeKuoD7Init = { 1, 3, 1, 9, 15, 55, 45, 85, 423, 351, 169, 2693, 3063, 13471, 0 }; - static ulong[] dim1551JoeKuoD7Init = { 1, 1, 1, 7, 21, 17, 51, 59, 251, 697, 787, 3331, 7567, 15413, 0 }; - static ulong[] dim1552JoeKuoD7Init = { 1, 1, 7, 7, 29, 29, 113, 37, 347, 21, 223, 427, 4163, 6773, 0 }; - static ulong[] dim1553JoeKuoD7Init = { 1, 3, 5, 9, 25, 55, 89, 101, 327, 483, 1197, 1377, 3367, 15363, 0 }; - static ulong[] dim1554JoeKuoD7Init = { 1, 3, 3, 5, 15, 37, 87, 131, 279, 981, 623, 105, 3537, 6021, 0 }; - static ulong[] dim1555JoeKuoD7Init = { 1, 3, 5, 13, 19, 27, 49, 187, 249, 17, 1499, 3559, 1691, 525, 0 }; - static ulong[] dim1556JoeKuoD7Init = { 1, 1, 3, 11, 25, 55, 7, 145, 335, 975, 1007, 1853, 2509, 12895, 0 }; - static ulong[] dim1557JoeKuoD7Init = { 1, 1, 7, 15, 31, 29, 43, 91, 51, 543, 251, 3137, 1449, 2465, 0 }; - static ulong[] dim1558JoeKuoD7Init = { 1, 3, 7, 1, 25, 33, 107, 117, 439, 851, 1853, 1309, 7329, 6953, 0 }; - static ulong[] dim1559JoeKuoD7Init = { 1, 1, 7, 9, 13, 13, 105, 113, 161, 307, 939, 579, 6945, 3275, 0 }; - static ulong[] dim1560JoeKuoD7Init = { 1, 3, 3, 3, 19, 61, 85, 247, 31, 781, 599, 1731, 7907, 10855, 0 }; - static ulong[] dim1561JoeKuoD7Init = { 1, 3, 7, 15, 23, 13, 111, 197, 399, 273, 1339, 717, 6365, 11211, 0 }; - static ulong[] dim1562JoeKuoD7Init = { 1, 1, 1, 1, 7, 37, 83, 217, 351, 325, 787, 2735, 6797, 649, 0 }; - static ulong[] dim1563JoeKuoD7Init = { 1, 1, 7, 5, 25, 9, 29, 3, 305, 773, 933, 4091, 7515, 13513, 0 }; - static ulong[] dim1564JoeKuoD7Init = { 1, 1, 1, 7, 5, 9, 53, 79, 509, 101, 187, 4087, 5473, 8581, 0 }; - static ulong[] dim1565JoeKuoD7Init = { 1, 1, 3, 3, 9, 7, 59, 235, 219, 85, 1275, 329, 3661, 2135, 0 }; - static ulong[] dim1566JoeKuoD7Init = { 1, 1, 7, 15, 7, 43, 39, 153, 59, 91, 755, 827, 2399, 5395, 0 }; - static ulong[] dim1567JoeKuoD7Init = { 1, 3, 7, 3, 11, 29, 75, 195, 249, 789, 489, 1297, 1465, 449, 0 }; - static ulong[] dim1568JoeKuoD7Init = { 1, 3, 5, 13, 29, 13, 61, 111, 85, 335, 1835, 4025, 3433, 12839, 0 }; - static ulong[] dim1569JoeKuoD7Init = { 1, 1, 3, 1, 9, 45, 13, 179, 145, 161, 459, 3011, 7809, 11047, 0 }; - static ulong[] dim1570JoeKuoD7Init = { 1, 1, 5, 15, 27, 1, 81, 241, 89, 159, 681, 3525, 4487, 9129, 0 }; - static ulong[] dim1571JoeKuoD7Init = { 1, 3, 7, 15, 7, 1, 15, 103, 81, 59, 1953, 3729, 6451, 15051, 0 }; - static ulong[] dim1572JoeKuoD7Init = { 1, 3, 1, 1, 29, 7, 77, 77, 279, 1007, 1315, 1149, 301, 14183, 0 }; - static ulong[] dim1573JoeKuoD7Init = { 1, 1, 5, 11, 1, 1, 85, 23, 27, 211, 2023, 591, 2949, 10741, 0 }; - static ulong[] dim1574JoeKuoD7Init = { 1, 3, 1, 11, 31, 63, 49, 87, 291, 701, 531, 287, 6117, 16303, 0 }; - static ulong[] dim1575JoeKuoD7Init = { 1, 3, 3, 9, 27, 19, 19, 143, 95, 65, 1027, 2765, 2483, 14347, 0 }; - static ulong[] dim1576JoeKuoD7Init = { 1, 1, 7, 9, 3, 31, 31, 243, 45, 195, 1997, 3361, 7151, 12021, 0 }; - static ulong[] dim1577JoeKuoD7Init = { 1, 3, 3, 9, 11, 43, 83, 1, 389, 843, 1635, 3405, 2497, 4473, 0 }; - static ulong[] dim1578JoeKuoD7Init = { 1, 3, 5, 5, 15, 9, 65, 187, 107, 271, 1049, 1657, 1831, 12291, 0 }; - static ulong[] dim1579JoeKuoD7Init = { 1, 3, 7, 3, 29, 17, 107, 17, 253, 399, 481, 83, 3905, 5817, 0 }; - static ulong[] dim1580JoeKuoD7Init = { 1, 3, 5, 5, 21, 1, 93, 189, 451, 183, 1489, 379, 4673, 9323, 0 }; - static ulong[] dim1581JoeKuoD7Init = { 1, 3, 1, 9, 19, 25, 105, 97, 505, 569, 773, 3155, 3275, 11389, 0 }; - static ulong[] dim1582JoeKuoD7Init = { 1, 3, 3, 11, 29, 25, 87, 205, 321, 187, 239, 2217, 1063, 13323, 0 }; - static ulong[] dim1583JoeKuoD7Init = { 1, 1, 7, 13, 19, 47, 17, 243, 103, 515, 1049, 2119, 2185, 3137, 0 }; - static ulong[] dim1584JoeKuoD7Init = { 1, 3, 1, 15, 17, 19, 45, 191, 257, 453, 779, 3759, 6825, 5711, 0 }; - static ulong[] dim1585JoeKuoD7Init = { 1, 3, 3, 15, 15, 41, 41, 181, 185, 91, 375, 2825, 3841, 14179, 0 }; - static ulong[] dim1586JoeKuoD7Init = { 1, 1, 5, 13, 23, 11, 93, 117, 135, 333, 1985, 3355, 2119, 10511, 0 }; - static ulong[] dim1587JoeKuoD7Init = { 1, 3, 7, 15, 5, 59, 17, 141, 291, 897, 657, 2805, 4423, 559, 0 }; - static ulong[] dim1588JoeKuoD7Init = { 1, 3, 7, 1, 19, 55, 33, 77, 321, 989, 1713, 1553, 5541, 12995, 0 }; - static ulong[] dim1589JoeKuoD7Init = { 1, 1, 3, 5, 11, 9, 69, 123, 223, 201, 1505, 1119, 381, 12361, 0 }; - static ulong[] dim1590JoeKuoD7Init = { 1, 1, 7, 7, 13, 13, 15, 107, 143, 925, 1741, 3697, 5379, 10661, 0 }; - static ulong[] dim1591JoeKuoD7Init = { 1, 1, 5, 1, 25, 43, 47, 209, 57, 1015, 1721, 1707, 3675, 2651, 0 }; - static ulong[] dim1592JoeKuoD7Init = { 1, 3, 3, 3, 21, 27, 101, 41, 309, 585, 159, 2029, 5307, 5919, 0 }; - static ulong[] dim1593JoeKuoD7Init = { 1, 1, 5, 7, 13, 53, 43, 71, 259, 331, 1317, 3367, 2593, 4667, 0 }; - static ulong[] dim1594JoeKuoD7Init = { 1, 3, 7, 13, 1, 31, 115, 159, 203, 39, 19, 1939, 2601, 14819, 0 }; - static ulong[] dim1595JoeKuoD7Init = { 1, 3, 7, 9, 1, 33, 101, 145, 401, 655, 543, 2063, 425, 6397, 0 }; - static ulong[] dim1596JoeKuoD7Init = { 1, 3, 3, 1, 1, 13, 15, 19, 347, 679, 107, 933, 8097, 16213, 0 }; - static ulong[] dim1597JoeKuoD7Init = { 1, 3, 1, 5, 9, 47, 15, 95, 191, 887, 69, 3775, 7839, 767, 0 }; - static ulong[] dim1598JoeKuoD7Init = { 1, 1, 5, 13, 17, 37, 43, 241, 401, 273, 1819, 2437, 2027, 5763, 0 }; - static ulong[] dim1599JoeKuoD7Init = { 1, 1, 3, 11, 25, 49, 31, 17, 153, 771, 1151, 1575, 1719, 12567, 0 }; - static ulong[] dim1600JoeKuoD7Init = { 1, 3, 7, 9, 19, 31, 33, 227, 15, 645, 1499, 967, 6459, 975, 0 }; - static ulong[] dim1601JoeKuoD7Init = { 1, 3, 1, 1, 5, 23, 31, 105, 47, 761, 1911, 3889, 67, 5543, 0 }; - static ulong[] dim1602JoeKuoD7Init = { 1, 1, 5, 3, 15, 1, 7, 119, 247, 759, 1277, 1233, 1055, 15651, 0 }; - static ulong[] dim1603JoeKuoD7Init = { 1, 1, 1, 1, 15, 33, 117, 189, 93, 511, 1709, 3329, 619, 3561, 0 }; - static ulong[] dim1604JoeKuoD7Init = { 1, 1, 7, 9, 21, 39, 35, 59, 121, 149, 2015, 1127, 8035, 8197, 0 }; - static ulong[] dim1605JoeKuoD7Init = { 1, 3, 7, 9, 25, 3, 43, 189, 257, 343, 607, 285, 6003, 1119, 0 }; - static ulong[] dim1606JoeKuoD7Init = { 1, 1, 5, 11, 7, 41, 53, 193, 343, 353, 1743, 1877, 2207, 10765, 0 }; - static ulong[] dim1607JoeKuoD7Init = { 1, 1, 3, 1, 3, 59, 117, 15, 199, 639, 1597, 3833, 7167, 9437, 0 }; - static ulong[] dim1608JoeKuoD7Init = { 1, 3, 7, 13, 15, 49, 79, 19, 131, 1021, 1881, 1113, 6191, 7549, 0 }; - static ulong[] dim1609JoeKuoD7Init = { 1, 1, 5, 5, 29, 57, 69, 181, 167, 179, 317, 4069, 3885, 2641, 0 }; - static ulong[] dim1610JoeKuoD7Init = { 1, 3, 3, 7, 1, 15, 13, 69, 425, 491, 327, 1387, 5333, 14555, 0 }; - static ulong[] dim1611JoeKuoD7Init = { 1, 1, 7, 3, 3, 33, 99, 169, 245, 155, 1843, 2435, 2853, 8871, 0 }; - static ulong[] dim1612JoeKuoD7Init = { 1, 1, 1, 11, 27, 37, 107, 163, 399, 933, 1867, 3321, 2737, 4941, 0 }; - static ulong[] dim1613JoeKuoD7Init = { 1, 3, 5, 11, 27, 25, 31, 193, 219, 21, 1811, 2515, 1027, 10337, 0 }; - static ulong[] dim1614JoeKuoD7Init = { 1, 3, 7, 1, 13, 23, 75, 175, 265, 71, 597, 521, 5343, 5615, 0 }; - static ulong[] dim1615JoeKuoD7Init = { 1, 3, 1, 11, 27, 13, 23, 187, 281, 593, 1559, 1355, 637, 15835, 0 }; - static ulong[] dim1616JoeKuoD7Init = { 1, 3, 5, 15, 25, 7, 29, 1, 403, 175, 401, 3521, 1077, 8699, 0 }; - static ulong[] dim1617JoeKuoD7Init = { 1, 1, 7, 5, 31, 27, 79, 135, 439, 935, 783, 2981, 3747, 10697, 0 }; - static ulong[] dim1618JoeKuoD7Init = { 1, 3, 1, 3, 25, 1, 119, 53, 107, 841, 909, 265, 3845, 8613, 0 }; - static ulong[] dim1619JoeKuoD7Init = { 1, 3, 3, 7, 13, 53, 3, 159, 453, 711, 399, 3267, 1245, 8747, 0 }; - static ulong[] dim1620JoeKuoD7Init = { 1, 1, 1, 9, 15, 59, 99, 255, 331, 241, 1389, 3885, 7497, 13169, 0 }; - static ulong[] dim1621JoeKuoD7Init = { 1, 3, 5, 9, 11, 23, 49, 77, 239, 341, 453, 763, 3241, 13097, 0 }; - static ulong[] dim1622JoeKuoD7Init = { 1, 3, 7, 15, 21, 15, 65, 221, 167, 17, 1621, 4043, 1643, 13481, 0 }; - static ulong[] dim1623JoeKuoD7Init = { 1, 3, 1, 9, 1, 35, 125, 157, 437, 49, 1145, 861, 4323, 11839, 0 }; - static ulong[] dim1624JoeKuoD7Init = { 1, 1, 3, 5, 27, 27, 125, 61, 401, 251, 1171, 2409, 63, 11279, 0 }; - static ulong[] dim1625JoeKuoD7Init = { 1, 3, 3, 5, 27, 57, 39, 37, 337, 999, 549, 2071, 5547, 315, 0 }; - static ulong[] dim1626JoeKuoD7Init = { 1, 1, 1, 15, 29, 29, 119, 89, 325, 665, 783, 1683, 6185, 4301, 0 }; - static ulong[] dim1627JoeKuoD7Init = { 1, 3, 7, 7, 7, 25, 111, 99, 411, 549, 949, 735, 6881, 4681, 0 }; - static ulong[] dim1628JoeKuoD7Init = { 1, 3, 5, 15, 21, 3, 117, 83, 473, 595, 1061, 3905, 4985, 6149, 0 }; - static ulong[] dim1629JoeKuoD7Init = { 1, 3, 7, 1, 17, 13, 27, 101, 95, 773, 1095, 2813, 6253, 2817, 0 }; - static ulong[] dim1630JoeKuoD7Init = { 1, 1, 5, 9, 1, 9, 91, 43, 153, 627, 49, 1109, 1395, 2971, 0 }; - static ulong[] dim1631JoeKuoD7Init = { 1, 3, 7, 11, 25, 57, 1, 141, 227, 161, 3, 2509, 2675, 14093, 0 }; - static ulong[] dim1632JoeKuoD7Init = { 1, 1, 7, 7, 27, 35, 85, 103, 321, 331, 351, 2831, 911, 13259, 0 }; - static ulong[] dim1633JoeKuoD7Init = { 1, 1, 1, 9, 29, 59, 57, 199, 27, 303, 1001, 1393, 3345, 11169, 0 }; - static ulong[] dim1634JoeKuoD7Init = { 1, 3, 5, 15, 11, 37, 83, 127, 79, 683, 669, 1793, 2271, 1643, 0 }; - static ulong[] dim1635JoeKuoD7Init = { 1, 1, 7, 5, 9, 45, 65, 143, 489, 91, 1819, 2679, 4003, 13961, 0 }; - static ulong[] dim1636JoeKuoD7Init = { 1, 3, 1, 1, 5, 9, 127, 61, 209, 597, 463, 961, 1739, 13955, 0 }; - static ulong[] dim1637JoeKuoD7Init = { 1, 3, 5, 11, 29, 13, 73, 61, 233, 891, 1477, 501, 7781, 15911, 0 }; - static ulong[] dim1638JoeKuoD7Init = { 1, 3, 5, 3, 23, 23, 99, 227, 385, 503, 405, 3825, 535, 5997, 0 }; - static ulong[] dim1639JoeKuoD7Init = { 1, 1, 7, 7, 11, 31, 105, 103, 383, 897, 1049, 2757, 7687, 13175, 0 }; - static ulong[] dim1640JoeKuoD7Init = { 1, 1, 3, 15, 7, 55, 43, 205, 451, 195, 1973, 1963, 5791, 14413, 0 }; - static ulong[] dim1641JoeKuoD7Init = { 1, 1, 7, 13, 7, 5, 35, 215, 415, 221, 1245, 399, 1471, 9559, 0 }; - static ulong[] dim1642JoeKuoD7Init = { 1, 3, 1, 13, 3, 27, 119, 245, 291, 633, 641, 779, 533, 12031, 0 }; - static ulong[] dim1643JoeKuoD7Init = { 1, 1, 1, 11, 21, 41, 83, 93, 91, 671, 1579, 3375, 7109, 12321, 0 }; - static ulong[] dim1644JoeKuoD7Init = { 1, 1, 5, 1, 27, 47, 19, 161, 103, 455, 2027, 1461, 633, 5815, 0 }; - static ulong[] dim1645JoeKuoD7Init = { 1, 3, 5, 11, 25, 11, 115, 95, 15, 979, 89, 2489, 255, 13683, 0 }; - static ulong[] dim1646JoeKuoD7Init = { 1, 1, 5, 5, 31, 55, 85, 223, 231, 9, 493, 3117, 3431, 12139, 0 }; - static ulong[] dim1647JoeKuoD7Init = { 1, 1, 1, 13, 1, 59, 5, 33, 111, 711, 1111, 3337, 6595, 15149, 0 }; - static ulong[] dim1648JoeKuoD7Init = { 1, 3, 3, 5, 27, 9, 85, 243, 141, 155, 2007, 673, 3613, 9837, 0 }; - static ulong[] dim1649JoeKuoD7Init = { 1, 3, 1, 13, 17, 53, 105, 125, 295, 467, 29, 1501, 2841, 1531, 0 }; - static ulong[] dim1650JoeKuoD7Init = { 1, 3, 1, 1, 15, 35, 95, 73, 273, 5, 515, 185, 5845, 15793, 0 }; - static ulong[] dim1651JoeKuoD7Init = { 1, 3, 7, 15, 1, 9, 117, 229, 219, 723, 1641, 2639, 5711, 10337, 0 }; - static ulong[] dim1652JoeKuoD7Init = { 1, 1, 5, 1, 9, 47, 13, 179, 353, 167, 1255, 4053, 1279, 6181, 0 }; - static ulong[] dim1653JoeKuoD7Init = { 1, 1, 5, 11, 3, 29, 47, 63, 127, 355, 1459, 441, 6849, 12995, 0 }; - static ulong[] dim1654JoeKuoD7Init = { 1, 1, 5, 5, 15, 27, 99, 11, 63, 405, 1025, 2047, 7239, 13019, 0 }; - static ulong[] dim1655JoeKuoD7Init = { 1, 3, 3, 15, 31, 1, 17, 109, 7, 251, 517, 2923, 2967, 15609, 0 }; - static ulong[] dim1656JoeKuoD7Init = { 1, 3, 5, 5, 5, 9, 89, 77, 77, 619, 793, 195, 3507, 4203, 0 }; - static ulong[] dim1657JoeKuoD7Init = { 1, 3, 1, 1, 29, 47, 83, 117, 387, 601, 35, 1327, 6381, 7673, 0 }; - static ulong[] dim1658JoeKuoD7Init = { 1, 1, 7, 3, 21, 7, 33, 41, 161, 53, 1635, 787, 6197, 4841, 0 }; - static ulong[] dim1659JoeKuoD7Init = { 1, 3, 7, 11, 5, 33, 29, 43, 289, 805, 109, 2099, 7851, 809, 0 }; - static ulong[] dim1660JoeKuoD7Init = { 1, 3, 7, 7, 7, 39, 79, 147, 129, 307, 93, 3349, 7329, 14213, 0 }; - static ulong[] dim1661JoeKuoD7Init = { 1, 3, 5, 13, 27, 59, 35, 235, 413, 631, 1201, 1317, 5489, 13277, 0 }; - static ulong[] dim1662JoeKuoD7Init = { 1, 3, 5, 7, 27, 57, 57, 83, 273, 973, 767, 3993, 5337, 15679, 0 }; - static ulong[] dim1663JoeKuoD7Init = { 1, 1, 1, 11, 29, 49, 63, 211, 253, 947, 21, 1993, 6775, 1551, 0 }; - static ulong[] dim1664JoeKuoD7Init = { 1, 3, 5, 15, 27, 17, 37, 81, 83, 991, 1509, 1931, 7389, 6053, 0 }; - static ulong[] dim1665JoeKuoD7Init = { 1, 3, 3, 15, 19, 23, 53, 225, 131, 935, 333, 577, 7893, 13339, 0 }; - static ulong[] dim1666JoeKuoD7Init = { 1, 1, 7, 1, 27, 41, 97, 131, 135, 857, 89, 2285, 223, 15595, 0 }; - static ulong[] dim1667JoeKuoD7Init = { 1, 1, 5, 13, 13, 29, 47, 179, 63, 261, 1409, 3921, 653, 12425, 0 }; - static ulong[] dim1668JoeKuoD7Init = { 1, 3, 1, 7, 15, 53, 121, 7, 287, 251, 579, 1415, 453, 15615, 0 }; - static ulong[] dim1669JoeKuoD7Init = { 1, 3, 1, 5, 3, 9, 41, 105, 505, 37, 665, 3323, 3613, 4533, 0 }; - static ulong[] dim1670JoeKuoD7Init = { 1, 1, 3, 1, 5, 57, 53, 107, 279, 169, 1797, 3395, 7325, 5825, 0 }; - static ulong[] dim1671JoeKuoD7Init = { 1, 3, 3, 13, 19, 23, 33, 145, 15, 459, 711, 2883, 2879, 7437, 0 }; - static ulong[] dim1672JoeKuoD7Init = { 1, 1, 1, 1, 23, 17, 81, 233, 85, 435, 169, 287, 5913, 11063, 0 }; - static ulong[] dim1673JoeKuoD7Init = { 1, 3, 1, 9, 23, 5, 7, 9, 393, 243, 1301, 365, 7529, 13875, 0 }; - static ulong[] dim1674JoeKuoD7Init = { 1, 1, 1, 1, 9, 43, 127, 81, 49, 783, 1079, 4059, 5829, 7873, 0 }; - static ulong[] dim1675JoeKuoD7Init = { 1, 3, 7, 7, 29, 49, 123, 81, 73, 137, 895, 791, 6801, 1209, 0 }; - static ulong[] dim1676JoeKuoD7Init = { 1, 1, 5, 13, 7, 63, 93, 177, 263, 373, 39, 1713, 6793, 215, 0 }; - static ulong[] dim1677JoeKuoD7Init = { 1, 3, 5, 9, 31, 19, 105, 187, 55, 715, 505, 2597, 2923, 16351, 0 }; - static ulong[] dim1678JoeKuoD7Init = { 1, 3, 1, 15, 9, 29, 113, 41, 83, 667, 605, 1033, 1525, 2781, 0 }; - static ulong[] dim1679JoeKuoD7Init = { 1, 3, 3, 5, 29, 27, 123, 159, 3, 659, 1757, 3603, 6419, 10125, 0 }; - static ulong[] dim1680JoeKuoD7Init = { 1, 3, 3, 3, 17, 19, 1, 19, 459, 833, 1149, 413, 1835, 12449, 0 }; - static ulong[] dim1681JoeKuoD7Init = { 1, 3, 3, 15, 27, 13, 109, 233, 341, 943, 173, 2491, 445, 5669, 0 }; - static ulong[] dim1682JoeKuoD7Init = { 1, 1, 7, 13, 17, 37, 53, 79, 107, 263, 353, 1193, 4445, 13969, 0 }; - static ulong[] dim1683JoeKuoD7Init = { 1, 1, 5, 7, 17, 55, 49, 53, 9, 831, 1551, 1105, 7797, 10667, 0 }; - static ulong[] dim1684JoeKuoD7Init = { 1, 3, 3, 13, 23, 9, 77, 85, 297, 875, 1339, 3019, 7211, 363, 0 }; - static ulong[] dim1685JoeKuoD7Init = { 1, 1, 7, 3, 13, 11, 13, 239, 235, 299, 1433, 3913, 6793, 8471, 0 }; - static ulong[] dim1686JoeKuoD7Init = { 1, 3, 7, 15, 15, 43, 109, 33, 221, 543, 1067, 559, 2541, 5601, 0 }; - static ulong[] dim1687JoeKuoD7Init = { 1, 1, 7, 11, 15, 51, 77, 125, 195, 435, 1769, 1047, 2509, 11143, 0 }; - static ulong[] dim1688JoeKuoD7Init = { 1, 1, 5, 13, 19, 43, 31, 115, 357, 197, 119, 1709, 1851, 5625, 0 }; - static ulong[] dim1689JoeKuoD7Init = { 1, 1, 1, 15, 25, 19, 127, 165, 241, 255, 1737, 4053, 5987, 2573, 0 }; - static ulong[] dim1690JoeKuoD7Init = { 1, 3, 3, 1, 5, 5, 21, 203, 379, 147, 1793, 461, 4863, 14659, 0 }; - static ulong[] dim1691JoeKuoD7Init = { 1, 1, 3, 13, 15, 41, 125, 191, 471, 863, 485, 1029, 6375, 7825, 0 }; - static ulong[] dim1692JoeKuoD7Init = { 1, 1, 5, 1, 13, 47, 53, 221, 351, 621, 1025, 3729, 367, 16091, 0 }; - static ulong[] dim1693JoeKuoD7Init = { 1, 1, 7, 11, 1, 47, 11, 91, 485, 601, 235, 241, 6631, 3159, 0 }; - static ulong[] dim1694JoeKuoD7Init = { 1, 1, 7, 11, 9, 59, 41, 121, 87, 969, 667, 3845, 3317, 14095, 0 }; - static ulong[] dim1695JoeKuoD7Init = { 1, 3, 3, 9, 17, 43, 95, 111, 253, 497, 1263, 1323, 2669, 11567, 0 }; - static ulong[] dim1696JoeKuoD7Init = { 1, 3, 1, 5, 17, 45, 15, 231, 7, 125, 67, 27, 5397, 15347, 0 }; - static ulong[] dim1697JoeKuoD7Init = { 1, 1, 7, 13, 15, 59, 119, 203, 89, 987, 337, 3313, 5533, 13157, 0 }; - static ulong[] dim1698JoeKuoD7Init = { 1, 3, 1, 5, 31, 21, 11, 79, 485, 431, 1333, 3111, 2081, 4327, 0 }; - static ulong[] dim1699JoeKuoD7Init = { 1, 1, 7, 7, 1, 19, 111, 127, 23, 597, 1049, 2337, 6891, 7421, 0 }; - static ulong[] dim1700JoeKuoD7Init = { 1, 3, 7, 7, 23, 3, 121, 171, 41, 3, 147, 397, 5413, 15457, 0 }; - static ulong[] dim1701JoeKuoD7Init = { 1, 1, 1, 9, 11, 9, 107, 55, 303, 285, 599, 2507, 699, 8593, 0 }; - static ulong[] dim1702JoeKuoD7Init = { 1, 3, 5, 3, 19, 61, 9, 33, 385, 761, 1185, 1163, 2251, 8497, 0 }; - static ulong[] dim1703JoeKuoD7Init = { 1, 3, 5, 3, 5, 35, 31, 19, 173, 425, 833, 119, 6691, 11103, 0 }; - static ulong[] dim1704JoeKuoD7Init = { 1, 3, 7, 3, 11, 15, 105, 239, 21, 477, 1303, 3437, 5511, 2469, 0 }; - static ulong[] dim1705JoeKuoD7Init = { 1, 3, 7, 5, 13, 11, 49, 81, 505, 527, 1799, 403, 6849, 4551, 0 }; - static ulong[] dim1706JoeKuoD7Init = { 1, 1, 7, 1, 5, 1, 21, 83, 273, 477, 1281, 3173, 2065, 1559, 0 }; - static ulong[] dim1707JoeKuoD7Init = { 1, 1, 7, 5, 19, 43, 33, 191, 411, 879, 83, 2653, 1271, 10557, 0 }; - static ulong[] dim1708JoeKuoD7Init = { 1, 3, 5, 1, 25, 27, 81, 81, 23, 575, 787, 1715, 7983, 14397, 0 }; - static ulong[] dim1709JoeKuoD7Init = { 1, 1, 7, 11, 27, 57, 31, 139, 65, 445, 1993, 3693, 2627, 941, 0 }; - static ulong[] dim1710JoeKuoD7Init = { 1, 1, 1, 9, 5, 55, 23, 235, 103, 451, 1299, 3901, 2705, 12485, 0 }; - static ulong[] dim1711JoeKuoD7Init = { 1, 1, 1, 11, 9, 57, 57, 129, 269, 841, 1859, 1149, 531, 11977, 0 }; - static ulong[] dim1712JoeKuoD7Init = { 1, 3, 3, 7, 17, 11, 9, 89, 205, 3, 437, 475, 313, 7593, 0 }; - static ulong[] dim1713JoeKuoD7Init = { 1, 3, 5, 13, 9, 37, 9, 109, 453, 965, 1259, 2713, 7301, 15453, 0 }; - static ulong[] dim1714JoeKuoD7Init = { 1, 1, 1, 7, 25, 57, 53, 149, 291, 45, 783, 2327, 7439, 6567, 0 }; - static ulong[] dim1715JoeKuoD7Init = { 1, 1, 1, 13, 5, 17, 65, 15, 279, 435, 1015, 3157, 1411, 3259, 0 }; - static ulong[] dim1716JoeKuoD7Init = { 1, 3, 5, 1, 27, 9, 119, 11, 159, 829, 1499, 3797, 3059, 675, 0 }; - static ulong[] dim1717JoeKuoD7Init = { 1, 1, 3, 7, 27, 5, 65, 141, 403, 431, 645, 3547, 7779, 12565, 0 }; - static ulong[] dim1718JoeKuoD7Init = { 1, 1, 3, 15, 7, 11, 3, 53, 479, 841, 541, 2041, 631, 13969, 0 }; - static ulong[] dim1719JoeKuoD7Init = { 1, 3, 7, 9, 19, 29, 15, 137, 317, 929, 509, 2231, 6273, 305, 0 }; - static ulong[] dim1720JoeKuoD7Init = { 1, 1, 7, 1, 19, 43, 99, 221, 429, 293, 133, 3233, 5097, 7521, 0 }; - static ulong[] dim1721JoeKuoD7Init = { 1, 3, 3, 7, 5, 19, 11, 253, 375, 33, 941, 573, 1855, 13119, 0 }; - static ulong[] dim1722JoeKuoD7Init = { 1, 1, 7, 5, 27, 59, 61, 195, 197, 635, 889, 777, 2559, 3013, 0 }; - static ulong[] dim1723JoeKuoD7Init = { 1, 1, 1, 7, 21, 45, 95, 61, 253, 239, 585, 75, 3737, 2199, 0 }; - static ulong[] dim1724JoeKuoD7Init = { 1, 1, 1, 5, 1, 17, 61, 21, 485, 199, 7, 431, 1117, 2039, 0 }; - static ulong[] dim1725JoeKuoD7Init = { 1, 1, 5, 7, 13, 23, 53, 211, 319, 47, 299, 2681, 6913, 5265, 0 }; - static ulong[] dim1726JoeKuoD7Init = { 1, 1, 3, 1, 21, 49, 1, 197, 413, 475, 79, 3761, 6379, 10689, 0 }; - static ulong[] dim1727JoeKuoD7Init = { 1, 3, 1, 11, 15, 37, 51, 81, 319, 985, 129, 3105, 1321, 9749, 0 }; - static ulong[] dim1728JoeKuoD7Init = { 1, 1, 5, 13, 23, 31, 61, 49, 497, 987, 1401, 2609, 307, 4839, 0 }; - static ulong[] dim1729JoeKuoD7Init = { 1, 3, 5, 7, 11, 25, 9, 97, 337, 535, 543, 145, 241, 1481, 0 }; - static ulong[] dim1730JoeKuoD7Init = { 1, 3, 1, 11, 17, 55, 81, 161, 367, 825, 879, 301, 13, 7089, 0 }; - static ulong[] dim1731JoeKuoD7Init = { 1, 3, 3, 3, 13, 11, 43, 237, 485, 3, 1191, 223, 767, 10297, 0 }; - static ulong[] dim1732JoeKuoD7Init = { 1, 3, 3, 13, 21, 21, 93, 241, 119, 647, 921, 2847, 6889, 7055, 0 }; - static ulong[] dim1733JoeKuoD7Init = { 1, 3, 5, 5, 5, 29, 3, 225, 307, 257, 1961, 2455, 2239, 3405, 0 }; - static ulong[] dim1734JoeKuoD7Init = { 1, 3, 7, 11, 15, 33, 17, 179, 469, 5, 1577, 3539, 7123, 16093, 0 }; - static ulong[] dim1735JoeKuoD7Init = { 1, 1, 3, 7, 27, 43, 45, 115, 507, 657, 1531, 2221, 3175, 1877, 0 }; - static ulong[] dim1736JoeKuoD7Init = { 1, 3, 5, 1, 11, 25, 49, 155, 441, 703, 813, 1143, 219, 12675, 0 }; - static ulong[] dim1737JoeKuoD7Init = { 1, 1, 1, 3, 15, 55, 15, 83, 333, 573, 1527, 3421, 6225, 3115, 0 }; - static ulong[] dim1738JoeKuoD7Init = { 1, 3, 5, 1, 27, 3, 117, 149, 35, 587, 1123, 3037, 8083, 113, 0 }; - static ulong[] dim1739JoeKuoD7Init = { 1, 3, 1, 5, 1, 23, 79, 99, 287, 505, 807, 4003, 4551, 2093, 0 }; - static ulong[] dim1740JoeKuoD7Init = { 1, 3, 7, 9, 29, 5, 59, 111, 401, 179, 1263, 749, 689, 8905, 0 }; - static ulong[] dim1741JoeKuoD7Init = { 1, 3, 7, 3, 17, 41, 81, 191, 313, 343, 809, 83, 405, 10665, 0 }; - static ulong[] dim1742JoeKuoD7Init = { 1, 3, 5, 9, 7, 19, 59, 157, 169, 273, 935, 1435, 4725, 14049, 0 }; - static ulong[] dim1743JoeKuoD7Init = { 1, 1, 5, 7, 11, 41, 61, 47, 43, 13, 783, 3685, 6417, 7859, 0 }; - static ulong[] dim1744JoeKuoD7Init = { 1, 1, 3, 3, 13, 37, 127, 107, 439, 855, 1969, 1257, 1459, 3617, 0 }; - static ulong[] dim1745JoeKuoD7Init = { 1, 3, 5, 1, 5, 7, 41, 77, 175, 679, 353, 2899, 1513, 9241, 0 }; - static ulong[] dim1746JoeKuoD7Init = { 1, 1, 5, 1, 31, 41, 75, 217, 131, 261, 1659, 509, 3327, 14651, 0 }; - static ulong[] dim1747JoeKuoD7Init = { 1, 1, 7, 15, 15, 1, 111, 131, 19, 123, 701, 2633, 5125, 15109, 0 }; - static ulong[] dim1748JoeKuoD7Init = { 1, 3, 3, 3, 15, 51, 19, 133, 41, 561, 869, 447, 1421, 8659, 0 }; - static ulong[] dim1749JoeKuoD7Init = { 1, 1, 3, 9, 15, 47, 103, 5, 23, 97, 1413, 3307, 407, 6943, 0 }; - static ulong[] dim1750JoeKuoD7Init = { 1, 1, 7, 15, 19, 37, 113, 217, 451, 733, 1407, 2805, 6121, 12471, 0 }; - static ulong[] dim1751JoeKuoD7Init = { 1, 1, 3, 13, 7, 53, 1, 159, 503, 603, 1523, 2327, 909, 3685, 0 }; - static ulong[] dim1752JoeKuoD7Init = { 1, 3, 1, 13, 11, 47, 79, 69, 459, 761, 1181, 3369, 7983, 8561, 0 }; - static ulong[] dim1753JoeKuoD7Init = { 1, 1, 5, 9, 3, 51, 69, 93, 375, 451, 1181, 1353, 939, 629, 0 }; - static ulong[] dim1754JoeKuoD7Init = { 1, 1, 5, 9, 29, 57, 89, 145, 477, 17, 55, 2073, 1805, 5389, 0 }; - static ulong[] dim1755JoeKuoD7Init = { 1, 3, 3, 7, 1, 59, 85, 69, 369, 191, 1419, 1331, 7451, 8769, 0 }; - static ulong[] dim1756JoeKuoD7Init = { 1, 3, 3, 11, 11, 49, 31, 249, 285, 29, 633, 3387, 1197, 6363, 0 }; - static ulong[] dim1757JoeKuoD7Init = { 1, 3, 7, 7, 15, 33, 3, 253, 247, 573, 2029, 3419, 8037, 2889, 0 }; - static ulong[] dim1758JoeKuoD7Init = { 1, 3, 5, 1, 23, 31, 35, 113, 221, 659, 755, 2777, 3709, 7511, 0 }; - static ulong[] dim1759JoeKuoD7Init = { 1, 1, 5, 7, 7, 29, 113, 81, 203, 711, 1427, 2233, 6049, 11417, 0 }; - static ulong[] dim1760JoeKuoD7Init = { 1, 3, 3, 1, 19, 55, 107, 87, 383, 25, 935, 1287, 1867, 2133, 0 }; - static ulong[] dim1761JoeKuoD7Init = { 1, 3, 7, 11, 9, 45, 15, 171, 293, 533, 1393, 759, 3009, 7879, 0 }; - static ulong[] dim1762JoeKuoD7Init = { 1, 1, 1, 1, 1, 59, 51, 15, 471, 377, 1031, 3427, 6447, 10465, 0 }; - static ulong[] dim1763JoeKuoD7Init = { 1, 3, 5, 15, 7, 15, 3, 1, 359, 331, 1295, 2777, 373, 4043, 0 }; - static ulong[] dim1764JoeKuoD7Init = { 1, 1, 3, 9, 21, 41, 123, 61, 225, 305, 149, 2041, 7569, 14055, 0 }; - static ulong[] dim1765JoeKuoD7Init = { 1, 3, 5, 3, 27, 15, 79, 47, 463, 327, 1231, 171, 4931, 7549, 0 }; - static ulong[] dim1766JoeKuoD7Init = { 1, 3, 3, 15, 27, 11, 35, 179, 205, 579, 1297, 3149, 1253, 3067, 0 }; - static ulong[] dim1767JoeKuoD7Init = { 1, 3, 1, 5, 15, 41, 17, 69, 369, 57, 779, 3055, 7799, 10755, 0 }; - static ulong[] dim1768JoeKuoD7Init = { 1, 1, 7, 11, 1, 11, 121, 177, 297, 933, 1319, 3123, 1233, 15521, 0 }; - static ulong[] dim1769JoeKuoD7Init = { 1, 1, 7, 7, 27, 59, 17, 155, 17, 109, 1623, 3527, 6227, 14295, 0 }; - static ulong[] dim1770JoeKuoD7Init = { 1, 3, 1, 13, 27, 19, 47, 35, 403, 647, 1257, 1661, 7011, 11981, 0 }; - static ulong[] dim1771JoeKuoD7Init = { 1, 1, 1, 13, 27, 47, 73, 53, 355, 857, 1091, 3165, 2729, 7685, 0 }; - static ulong[] dim1772JoeKuoD7Init = { 1, 3, 1, 9, 7, 55, 53, 183, 109, 655, 1143, 975, 2809, 2709, 0 }; - static ulong[] dim1773JoeKuoD7Init = { 1, 3, 3, 9, 11, 5, 121, 63, 221, 247, 1649, 709, 5215, 12159, 0 }; - static ulong[] dim1774JoeKuoD7Init = { 1, 1, 3, 5, 5, 37, 83, 89, 475, 513, 563, 1965, 2335, 7921, 0 }; - static ulong[] dim1775JoeKuoD7Init = { 1, 1, 3, 3, 15, 23, 79, 79, 499, 343, 917, 3495, 7685, 5939, 0 }; - static ulong[] dim1776JoeKuoD7Init = { 1, 1, 1, 13, 5, 59, 87, 7, 469, 979, 683, 3397, 3787, 5063, 0 }; - static ulong[] dim1777JoeKuoD7Init = { 1, 1, 7, 5, 1, 27, 73, 85, 427, 619, 989, 2323, 4069, 13721, 0 }; - static ulong[] dim1778JoeKuoD7Init = { 1, 3, 5, 3, 3, 39, 55, 153, 293, 483, 235, 2041, 549, 15519, 0 }; - static ulong[] dim1779JoeKuoD7Init = { 1, 3, 1, 9, 17, 13, 61, 227, 435, 383, 513, 1169, 3335, 11257, 0 }; - static ulong[] dim1780JoeKuoD7Init = { 1, 3, 3, 7, 1, 47, 61, 117, 483, 979, 163, 2621, 1701, 13331, 0 }; - static ulong[] dim1781JoeKuoD7Init = { 1, 3, 3, 1, 17, 49, 115, 235, 511, 681, 1493, 137, 539, 5429, 0 }; - static ulong[] dim1782JoeKuoD7Init = { 1, 3, 3, 13, 13, 61, 3, 1, 291, 101, 363, 1677, 2133, 3629, 0 }; - static ulong[] dim1783JoeKuoD7Init = { 1, 1, 7, 3, 1, 11, 83, 127, 291, 599, 819, 2637, 1197, 7435, 0 }; - static ulong[] dim1784JoeKuoD7Init = { 1, 1, 7, 1, 1, 23, 115, 47, 403, 377, 833, 3241, 6843, 10279, 0 }; - static ulong[] dim1785JoeKuoD7Init = { 1, 1, 1, 15, 7, 51, 81, 215, 43, 445, 203, 3375, 6479, 3745, 0 }; - static ulong[] dim1786JoeKuoD7Init = { 1, 1, 7, 5, 7, 13, 25, 43, 233, 725, 267, 1875, 6481, 9685, 0 }; - static ulong[] dim1787JoeKuoD7Init = { 1, 1, 1, 7, 23, 9, 37, 1, 51, 861, 1509, 11, 8119, 9171, 0 }; - static ulong[] dim1788JoeKuoD7Init = { 1, 1, 5, 9, 17, 41, 69, 51, 445, 727, 159, 3317, 4951, 7519, 0 }; - static ulong[] dim1789JoeKuoD7Init = { 1, 1, 3, 13, 11, 3, 9, 211, 453, 957, 1499, 953, 403, 10715, 0 }; - static ulong[] dim1790JoeKuoD7Init = { 1, 3, 7, 7, 19, 1, 13, 255, 351, 325, 1055, 3719, 2343, 12693, 0 }; - static ulong[] dim1791JoeKuoD7Init = { 1, 1, 7, 3, 25, 29, 77, 185, 421, 33, 911, 2791, 4865, 4591, 0 }; - static ulong[] dim1792JoeKuoD7Init = { 1, 3, 7, 1, 5, 53, 77, 25, 359, 69, 169, 225, 237, 2059, 0 }; - static ulong[] dim1793JoeKuoD7Init = { 1, 3, 3, 3, 25, 63, 21, 111, 83, 21, 1513, 565, 1097, 7331, 0 }; - static ulong[] dim1794JoeKuoD7Init = { 1, 3, 5, 15, 23, 33, 127, 221, 121, 95, 909, 1207, 2957, 3367, 0 }; - static ulong[] dim1795JoeKuoD7Init = { 1, 1, 7, 15, 11, 49, 35, 147, 265, 517, 2011, 3585, 3877, 2907, 0 }; - static ulong[] dim1796JoeKuoD7Init = { 1, 3, 3, 1, 11, 37, 53, 47, 35, 323, 1283, 399, 7785, 8341, 0 }; - static ulong[] dim1797JoeKuoD7Init = { 1, 1, 7, 15, 5, 51, 83, 255, 231, 141, 1005, 3681, 3155, 11815, 0 }; - static ulong[] dim1798JoeKuoD7Init = { 1, 1, 3, 7, 3, 15, 75, 81, 23, 137, 897, 2439, 5277, 6377, 0 }; - static ulong[] dim1799JoeKuoD7Init = { 1, 1, 5, 1, 3, 11, 69, 231, 483, 797, 133, 497, 3973, 14993, 0 }; - static ulong[] dim1800JoeKuoD7Init = { 1, 1, 3, 15, 23, 17, 89, 207, 111, 157, 1689, 3165, 7147, 15265, 0 }; - static ulong[] dim1801JoeKuoD7Init = { 1, 3, 1, 5, 9, 31, 45, 131, 423, 53, 1723, 2009, 485, 15329, 0 }; - static ulong[] dim1802JoeKuoD7Init = { 1, 1, 3, 3, 25, 5, 97, 81, 431, 701, 1799, 3595, 3147, 8919, 0 }; - static ulong[] dim1803JoeKuoD7Init = { 1, 3, 7, 3, 3, 37, 3, 219, 291, 553, 1879, 15, 3357, 8479, 0 }; - static ulong[] dim1804JoeKuoD7Init = { 1, 3, 7, 3, 3, 21, 55, 253, 49, 191, 951, 13, 5163, 12243, 0 }; - static ulong[] dim1805JoeKuoD7Init = { 1, 1, 1, 1, 29, 39, 93, 123, 133, 465, 1665, 2023, 6773, 10521, 0 }; - static ulong[] dim1806JoeKuoD7Init = { 1, 1, 1, 15, 15, 15, 107, 209, 103, 59, 33, 1927, 6517, 8479, 0 }; - static ulong[] dim1807JoeKuoD7Init = { 1, 3, 3, 15, 3, 37, 19, 3, 43, 193, 1907, 2579, 7415, 9165, 0 }; - static ulong[] dim1808JoeKuoD7Init = { 1, 3, 5, 11, 29, 63, 47, 79, 227, 569, 67, 4015, 1275, 11963, 0 }; - static ulong[] dim1809JoeKuoD7Init = { 1, 3, 7, 1, 1, 33, 103, 111, 129, 189, 837, 3741, 699, 14433, 0 }; - static ulong[] dim1810JoeKuoD7Init = { 1, 3, 7, 11, 19, 15, 43, 35, 367, 535, 913, 2109, 1397, 12199, 0 }; - static ulong[] dim1811JoeKuoD7Init = { 1, 3, 7, 15, 27, 15, 41, 59, 429, 423, 377, 905, 7403, 6175, 0 }; - static ulong[] dim1812JoeKuoD7Init = { 1, 1, 5, 5, 27, 55, 49, 247, 353, 773, 707, 2501, 7567, 1821, 0 }; - static ulong[] dim1813JoeKuoD7Init = { 1, 1, 7, 15, 5, 11, 31, 49, 331, 1017, 909, 967, 5557, 7279, 0 }; - static ulong[] dim1814JoeKuoD7Init = { 1, 1, 5, 5, 13, 55, 127, 111, 193, 77, 1353, 349, 5785, 16325, 0 }; - static ulong[] dim1815JoeKuoD7Init = { 1, 1, 5, 11, 23, 61, 83, 79, 409, 877, 1625, 705, 6159, 1701, 0 }; - static ulong[] dim1816JoeKuoD7Init = { 1, 1, 5, 1, 29, 39, 69, 221, 29, 83, 21, 3525, 7387, 9249, 0 }; - static ulong[] dim1817JoeKuoD7Init = { 1, 3, 7, 3, 13, 57, 63, 159, 25, 151, 1749, 3191, 4805, 6003, 0 }; - static ulong[] dim1818JoeKuoD7Init = { 1, 1, 3, 15, 11, 49, 71, 241, 421, 859, 1923, 539, 1721, 2903, 0 }; - static ulong[] dim1819JoeKuoD7Init = { 1, 3, 1, 1, 15, 33, 123, 133, 323, 173, 271, 2641, 2649, 5485, 0 }; - static ulong[] dim1820JoeKuoD7Init = { 1, 1, 3, 13, 13, 31, 39, 147, 313, 497, 2019, 3269, 2671, 6599, 0 }; - static ulong[] dim1821JoeKuoD7Init = { 1, 3, 7, 9, 13, 37, 111, 87, 3, 417, 923, 1833, 5383, 12045, 0 }; - static ulong[] dim1822JoeKuoD7Init = { 1, 3, 3, 13, 25, 27, 91, 121, 151, 407, 899, 469, 6647, 2799, 0 }; - static ulong[] dim1823JoeKuoD7Init = { 1, 3, 1, 7, 19, 39, 29, 43, 195, 439, 1065, 2035, 749, 14013, 0 }; - static ulong[] dim1824JoeKuoD7Init = { 1, 1, 5, 13, 21, 1, 69, 223, 83, 457, 1589, 1199, 7635, 1987, 0 }; - static ulong[] dim1825JoeKuoD7Init = { 1, 1, 7, 13, 5, 21, 35, 169, 71, 855, 497, 1119, 6681, 3905, 0 }; - static ulong[] dim1826JoeKuoD7Init = { 1, 3, 1, 13, 25, 55, 109, 113, 41, 461, 185, 3677, 1807, 13773, 0 }; - static ulong[] dim1827JoeKuoD7Init = { 1, 3, 1, 5, 15, 61, 91, 219, 365, 399, 505, 1207, 2237, 9267, 0 }; - static ulong[] dim1828JoeKuoD7Init = { 1, 1, 7, 3, 7, 1, 29, 151, 215, 587, 1499, 355, 5121, 14963, 0 }; - static ulong[] dim1829JoeKuoD7Init = { 1, 3, 1, 1, 3, 23, 127, 189, 139, 987, 1291, 3583, 2881, 1927, 0 }; - static ulong[] dim1830JoeKuoD7Init = { 1, 1, 1, 11, 19, 51, 25, 179, 35, 517, 1531, 3657, 7025, 7079, 0 }; - static ulong[] dim1831JoeKuoD7Init = { 1, 1, 5, 7, 23, 51, 35, 157, 113, 993, 265, 1119, 2639, 14475, 0 }; - static ulong[] dim1832JoeKuoD7Init = { 1, 3, 7, 1, 23, 19, 111, 83, 413, 205, 87, 2389, 7593, 9189, 0 }; - static ulong[] dim1833JoeKuoD7Init = { 1, 3, 5, 11, 25, 25, 39, 59, 419, 477, 1189, 807, 7679, 9867, 0 }; - static ulong[] dim1834JoeKuoD7Init = { 1, 1, 5, 1, 9, 59, 99, 183, 493, 811, 441, 1039, 1099, 10229, 0 }; - static ulong[] dim1835JoeKuoD7Init = { 1, 1, 5, 9, 31, 27, 51, 179, 277, 549, 153, 1785, 5227, 13695, 0 }; - static ulong[] dim1836JoeKuoD7Init = { 1, 3, 7, 11, 29, 43, 9, 205, 499, 55, 745, 2217, 793, 14517, 0 }; - static ulong[] dim1837JoeKuoD7Init = { 1, 3, 5, 7, 29, 47, 15, 153, 73, 971, 149, 2579, 1699, 14849, 0 }; - static ulong[] dim1838JoeKuoD7Init = { 1, 3, 3, 7, 31, 33, 61, 103, 503, 531, 2033, 2415, 4151, 4937, 0 }; - static ulong[] dim1839JoeKuoD7Init = { 1, 3, 1, 15, 15, 53, 27, 67, 351, 273, 637, 4085, 3445, 2085, 0 }; - static ulong[] dim1840JoeKuoD7Init = { 1, 3, 5, 15, 7, 57, 121, 23, 73, 765, 1949, 67, 8061, 11167, 0 }; - static ulong[] dim1841JoeKuoD7Init = { 1, 1, 7, 1, 25, 7, 107, 13, 409, 115, 1451, 1215, 39, 11577, 0 }; - static ulong[] dim1842JoeKuoD7Init = { 1, 1, 5, 15, 3, 15, 71, 1, 337, 929, 1435, 2847, 3257, 12233, 0 }; - static ulong[] dim1843JoeKuoD7Init = { 1, 1, 5, 11, 31, 37, 61, 243, 255, 79, 1735, 3769, 4893, 15103, 0 }; - static ulong[] dim1844JoeKuoD7Init = { 1, 1, 7, 11, 5, 63, 49, 197, 301, 883, 951, 2357, 7501, 15499, 0 }; - static ulong[] dim1845JoeKuoD7Init = { 1, 3, 7, 3, 13, 53, 71, 235, 183, 951, 845, 3361, 4757, 7745, 0 }; - static ulong[] dim1846JoeKuoD7Init = { 1, 1, 7, 3, 25, 61, 119, 3, 487, 503, 179, 2085, 4093, 1339, 0 }; - static ulong[] dim1847JoeKuoD7Init = { 1, 1, 5, 3, 21, 15, 113, 175, 61, 789, 1369, 109, 5963, 9401, 0 }; - static ulong[] dim1848JoeKuoD7Init = { 1, 1, 5, 5, 21, 35, 103, 33, 147, 561, 1033, 1497, 309, 12505, 0 }; - static ulong[] dim1849JoeKuoD7Init = { 1, 3, 3, 13, 25, 17, 29, 101, 103, 719, 329, 1317, 4487, 9115, 0 }; - static ulong[] dim1850JoeKuoD7Init = { 1, 1, 3, 13, 5, 61, 25, 79, 161, 673, 47, 2485, 7711, 4959, 0 }; - static ulong[] dim1851JoeKuoD7Init = { 1, 1, 7, 13, 19, 13, 1, 27, 443, 369, 669, 2555, 3003, 5117, 0 }; - static ulong[] dim1852JoeKuoD7Init = { 1, 3, 3, 5, 21, 29, 65, 211, 343, 717, 949, 1987, 6571, 11299, 0 }; - static ulong[] dim1853JoeKuoD7Init = { 1, 3, 3, 9, 19, 7, 115, 119, 369, 247, 1165, 4033, 861, 5667, 0 }; - static ulong[] dim1854JoeKuoD7Init = { 1, 3, 5, 3, 3, 53, 15, 219, 223, 873, 1145, 2781, 3297, 10551, 0 }; - static ulong[] dim1855JoeKuoD7Init = { 1, 3, 1, 15, 5, 61, 15, 121, 201, 89, 647, 3079, 1505, 10003, 0 }; - static ulong[] dim1856JoeKuoD7Init = { 1, 3, 1, 13, 17, 55, 27, 215, 67, 461, 1955, 765, 483, 11695, 0 }; - static ulong[] dim1857JoeKuoD7Init = { 1, 3, 1, 1, 1, 21, 59, 19, 339, 157, 2019, 971, 1797, 5237, 0 }; - static ulong[] dim1858JoeKuoD7Init = { 1, 3, 7, 9, 15, 1, 67, 119, 63, 59, 1107, 2201, 5499, 3757, 0 }; - static ulong[] dim1859JoeKuoD7Init = { 1, 3, 3, 13, 29, 59, 73, 89, 469, 335, 53, 315, 4371, 6417, 0 }; - static ulong[] dim1860JoeKuoD7Init = { 1, 1, 5, 3, 21, 7, 11, 205, 485, 695, 1959, 2407, 5423, 15359, 0 }; - static ulong[] dim1861JoeKuoD7Init = { 1, 1, 7, 1, 1, 43, 61, 103, 65, 747, 695, 3855, 7765, 13299, 0 }; - static ulong[] dim1862JoeKuoD7Init = { 1, 1, 3, 11, 9, 11, 47, 59, 287, 363, 1677, 613, 4181, 16221, 0 }; - static ulong[] dim1863JoeKuoD7Init = { 1, 1, 1, 3, 9, 43, 1, 107, 291, 493, 571, 2329, 2707, 13683, 0 }; - static ulong[] dim1864JoeKuoD7Init = { 1, 1, 5, 1, 13, 27, 29, 159, 357, 187, 613, 1803, 5563, 14913, 0 }; - static ulong[] dim1865JoeKuoD7Init = { 1, 3, 5, 13, 1, 5, 69, 69, 17, 527, 1019, 2565, 1383, 3695, 0 }; - static ulong[] dim1866JoeKuoD7Init = { 1, 1, 7, 3, 9, 21, 9, 151, 145, 891, 1961, 257, 5885, 5201, 0 }; - static ulong[] dim1867JoeKuoD7Init = { 1, 1, 3, 15, 9, 7, 31, 3, 115, 697, 369, 1531, 3581, 5681, 27421, 0 }; - static ulong[] dim1868JoeKuoD7Init = { 1, 1, 5, 9, 13, 33, 19, 191, 433, 651, 2023, 373, 4665, 15147, 28277, 0 }; - static ulong[] dim1869JoeKuoD7Init = { 1, 3, 5, 7, 27, 3, 15, 57, 137, 903, 355, 503, 3, 13015, 32415, 0 }; - static ulong[] dim1870JoeKuoD7Init = { 1, 3, 5, 1, 13, 57, 69, 55, 75, 633, 1271, 189, 4279, 1293, 5719, 0 }; - static ulong[] dim1871JoeKuoD7Init = { 1, 3, 5, 15, 27, 9, 13, 185, 211, 593, 723, 3725, 5165, 15375, 1055, 0 }; - static ulong[] dim1872JoeKuoD7Init = { 1, 3, 7, 13, 21, 11, 67, 11, 279, 503, 1839, 3509, 1285, 5251, 27835, 0 }; - static ulong[] dim1873JoeKuoD7Init = { 1, 1, 3, 15, 5, 45, 35, 145, 383, 227, 327, 2419, 5207, 15897, 20869, 0 }; - static ulong[] dim1874JoeKuoD7Init = { 1, 1, 7, 11, 31, 25, 69, 169, 363, 819, 1855, 61, 5613, 11835, 24761, 0 }; - static ulong[] dim1875JoeKuoD7Init = { 1, 3, 7, 9, 15, 41, 123, 61, 359, 29, 369, 1167, 489, 12947, 14765, 0 }; - static ulong[] dim1876JoeKuoD7Init = { 1, 3, 3, 5, 7, 33, 115, 193, 427, 123, 1795, 3153, 2771, 6761, 719, 0 }; - static ulong[] dim1877JoeKuoD7Init = { 1, 1, 1, 13, 31, 39, 5, 179, 181, 787, 1891, 2287, 2085, 15081, 2035, 0 }; - static ulong[] dim1878JoeKuoD7Init = { 1, 1, 5, 15, 1, 47, 15, 235, 431, 687, 1787, 225, 7749, 1179, 29243, 0 }; - static ulong[] dim1879JoeKuoD7Init = { 1, 1, 1, 13, 19, 53, 119, 131, 417, 505, 1179, 2291, 4795, 10475, 6307, 0 }; - static ulong[] dim1880JoeKuoD7Init = { 1, 1, 5, 13, 15, 43, 73, 3, 193, 5, 1843, 1617, 7557, 4165, 4089, 0 }; - static ulong[] dim1881JoeKuoD7Init = { 1, 1, 1, 5, 3, 35, 121, 183, 197, 605, 1775, 1647, 4929, 365, 43, 0 }; - static ulong[] dim1882JoeKuoD7Init = { 1, 1, 7, 7, 13, 31, 69, 157, 309, 99, 705, 1705, 2093, 13055, 6727, 0 }; - static ulong[] dim1883JoeKuoD7Init = { 1, 1, 1, 3, 29, 41, 109, 129, 223, 755, 595, 1931, 3967, 8249, 9439, 0 }; - static ulong[] dim1884JoeKuoD7Init = { 1, 3, 5, 1, 21, 45, 101, 229, 343, 455, 125, 1335, 749, 3967, 22777, 0 }; - static ulong[] dim1885JoeKuoD7Init = { 1, 1, 7, 13, 31, 49, 125, 199, 37, 685, 1171, 1793, 1057, 10041, 12693, 0 }; - static ulong[] dim1886JoeKuoD7Init = { 1, 3, 7, 5, 19, 33, 35, 115, 269, 151, 731, 1803, 5241, 3667, 25371, 0 }; - static ulong[] dim1887JoeKuoD7Init = { 1, 3, 5, 3, 7, 27, 25, 249, 275, 331, 1579, 2911, 5859, 9893, 27807, 0 }; - static ulong[] dim1888JoeKuoD7Init = { 1, 3, 1, 7, 21, 41, 81, 239, 141, 861, 827, 1261, 6873, 6413, 19313, 0 }; - static ulong[] dim1889JoeKuoD7Init = { 1, 1, 7, 1, 9, 51, 39, 123, 145, 929, 1101, 2505, 6493, 95, 17247, 0 }; - static ulong[] dim1890JoeKuoD7Init = { 1, 1, 5, 5, 11, 3, 47, 167, 5, 229, 1603, 3541, 5505, 1221, 899, 0 }; - static ulong[] dim1891JoeKuoD7Init = { 1, 1, 1, 9, 5, 17, 7, 21, 499, 597, 1775, 3187, 831, 10995, 7721, 0 }; - static ulong[] dim1892JoeKuoD7Init = { 1, 3, 3, 15, 27, 25, 7, 205, 341, 965, 519, 2907, 373, 5827, 14243, 0 }; - static ulong[] dim1893JoeKuoD7Init = { 1, 3, 1, 3, 19, 27, 13, 207, 287, 983, 575, 891, 3869, 11213, 11377, 0 }; - static ulong[] dim1894JoeKuoD7Init = { 1, 1, 3, 9, 1, 5, 53, 7, 507, 505, 133, 3567, 6601, 7985, 10461, 0 }; - static ulong[] dim1895JoeKuoD7Init = { 1, 1, 3, 9, 15, 9, 87, 231, 39, 701, 625, 2783, 6163, 6945, 4521, 0 }; - static ulong[] dim1896JoeKuoD7Init = { 1, 3, 5, 7, 25, 39, 63, 215, 89, 775, 283, 2919, 151, 7233, 32163, 0 }; - static ulong[] dim1897JoeKuoD7Init = { 1, 3, 3, 13, 31, 31, 55, 125, 433, 77, 1123, 3151, 6421, 6343, 14893, 0 }; - static ulong[] dim1898JoeKuoD7Init = { 1, 1, 5, 9, 17, 55, 63, 31, 331, 945, 1953, 4093, 6875, 3519, 23329, 0 }; - static ulong[] dim1899JoeKuoD7Init = { 1, 1, 1, 3, 23, 17, 17, 39, 173, 1013, 527, 2563, 3623, 10049, 10919, 0 }; - - static ulong[][] JoeKuoD7initializers = { - dim1JoeKuoD7Init, - dim2JoeKuoD7Init, - dim3JoeKuoD7Init, - dim4JoeKuoD7Init, - dim5JoeKuoD7Init, - dim6JoeKuoD7Init, - dim7JoeKuoD7Init, - dim8JoeKuoD7Init, - dim9JoeKuoD7Init, - dim10JoeKuoD7Init, - dim11JoeKuoD7Init, - dim12JoeKuoD7Init, - dim13JoeKuoD7Init, - dim14JoeKuoD7Init, - dim15JoeKuoD7Init, - dim16JoeKuoD7Init, - dim17JoeKuoD7Init, - dim18JoeKuoD7Init, - dim19JoeKuoD7Init, - dim20JoeKuoD7Init, - dim21JoeKuoD7Init, - dim22JoeKuoD7Init, - dim23JoeKuoD7Init, - dim24JoeKuoD7Init, - dim25JoeKuoD7Init, - dim26JoeKuoD7Init, - dim27JoeKuoD7Init, - dim28JoeKuoD7Init, - dim29JoeKuoD7Init, - dim30JoeKuoD7Init, - dim31JoeKuoD7Init, - dim32JoeKuoD7Init, - dim33JoeKuoD7Init, - dim34JoeKuoD7Init, - dim35JoeKuoD7Init, - dim36JoeKuoD7Init, - dim37JoeKuoD7Init, - dim38JoeKuoD7Init, - dim39JoeKuoD7Init, - dim40JoeKuoD7Init, - dim41JoeKuoD7Init, - dim42JoeKuoD7Init, - dim43JoeKuoD7Init, - dim44JoeKuoD7Init, - dim45JoeKuoD7Init, - dim46JoeKuoD7Init, - dim47JoeKuoD7Init, - dim48JoeKuoD7Init, - dim49JoeKuoD7Init, - dim50JoeKuoD7Init, - dim51JoeKuoD7Init, - dim52JoeKuoD7Init, - dim53JoeKuoD7Init, - dim54JoeKuoD7Init, - dim55JoeKuoD7Init, - dim56JoeKuoD7Init, - dim57JoeKuoD7Init, - dim58JoeKuoD7Init, - dim59JoeKuoD7Init, - dim60JoeKuoD7Init, - dim61JoeKuoD7Init, - dim62JoeKuoD7Init, - dim63JoeKuoD7Init, - dim64JoeKuoD7Init, - dim65JoeKuoD7Init, - dim66JoeKuoD7Init, - dim67JoeKuoD7Init, - dim68JoeKuoD7Init, - dim69JoeKuoD7Init, - dim70JoeKuoD7Init, - dim71JoeKuoD7Init, - dim72JoeKuoD7Init, - dim73JoeKuoD7Init, - dim74JoeKuoD7Init, - dim75JoeKuoD7Init, - dim76JoeKuoD7Init, - dim77JoeKuoD7Init, - dim78JoeKuoD7Init, - dim79JoeKuoD7Init, - dim80JoeKuoD7Init, - dim81JoeKuoD7Init, - dim82JoeKuoD7Init, - dim83JoeKuoD7Init, - dim84JoeKuoD7Init, - dim85JoeKuoD7Init, - dim86JoeKuoD7Init, - dim87JoeKuoD7Init, - dim88JoeKuoD7Init, - dim89JoeKuoD7Init, - dim90JoeKuoD7Init, - dim91JoeKuoD7Init, - dim92JoeKuoD7Init, - dim93JoeKuoD7Init, - dim94JoeKuoD7Init, - dim95JoeKuoD7Init, - dim96JoeKuoD7Init, - dim97JoeKuoD7Init, - dim98JoeKuoD7Init, - dim99JoeKuoD7Init, - dim100JoeKuoD7Init, - dim101JoeKuoD7Init, - dim102JoeKuoD7Init, - dim103JoeKuoD7Init, - dim104JoeKuoD7Init, - dim105JoeKuoD7Init, - dim106JoeKuoD7Init, - dim107JoeKuoD7Init, - dim108JoeKuoD7Init, - dim109JoeKuoD7Init, - dim110JoeKuoD7Init, - dim111JoeKuoD7Init, - dim112JoeKuoD7Init, - dim113JoeKuoD7Init, - dim114JoeKuoD7Init, - dim115JoeKuoD7Init, - dim116JoeKuoD7Init, - dim117JoeKuoD7Init, - dim118JoeKuoD7Init, - dim119JoeKuoD7Init, - dim120JoeKuoD7Init, - dim121JoeKuoD7Init, - dim122JoeKuoD7Init, - dim123JoeKuoD7Init, - dim124JoeKuoD7Init, - dim125JoeKuoD7Init, - dim126JoeKuoD7Init, - dim127JoeKuoD7Init, - dim128JoeKuoD7Init, - dim129JoeKuoD7Init, - dim130JoeKuoD7Init, - dim131JoeKuoD7Init, - dim132JoeKuoD7Init, - dim133JoeKuoD7Init, - dim134JoeKuoD7Init, - dim135JoeKuoD7Init, - dim136JoeKuoD7Init, - dim137JoeKuoD7Init, - dim138JoeKuoD7Init, - dim139JoeKuoD7Init, - dim140JoeKuoD7Init, - dim141JoeKuoD7Init, - dim142JoeKuoD7Init, - dim143JoeKuoD7Init, - dim144JoeKuoD7Init, - dim145JoeKuoD7Init, - dim146JoeKuoD7Init, - dim147JoeKuoD7Init, - dim148JoeKuoD7Init, - dim149JoeKuoD7Init, - dim150JoeKuoD7Init, - dim151JoeKuoD7Init, - dim152JoeKuoD7Init, - dim153JoeKuoD7Init, - dim154JoeKuoD7Init, - dim155JoeKuoD7Init, - dim156JoeKuoD7Init, - dim157JoeKuoD7Init, - dim158JoeKuoD7Init, - dim159JoeKuoD7Init, - dim160JoeKuoD7Init, - dim161JoeKuoD7Init, - dim162JoeKuoD7Init, - dim163JoeKuoD7Init, - dim164JoeKuoD7Init, - dim165JoeKuoD7Init, - dim166JoeKuoD7Init, - dim167JoeKuoD7Init, - dim168JoeKuoD7Init, - dim169JoeKuoD7Init, - dim170JoeKuoD7Init, - dim171JoeKuoD7Init, - dim172JoeKuoD7Init, - dim173JoeKuoD7Init, - dim174JoeKuoD7Init, - dim175JoeKuoD7Init, - dim176JoeKuoD7Init, - dim177JoeKuoD7Init, - dim178JoeKuoD7Init, - dim179JoeKuoD7Init, - dim180JoeKuoD7Init, - dim181JoeKuoD7Init, - dim182JoeKuoD7Init, - dim183JoeKuoD7Init, - dim184JoeKuoD7Init, - dim185JoeKuoD7Init, - dim186JoeKuoD7Init, - dim187JoeKuoD7Init, - dim188JoeKuoD7Init, - dim189JoeKuoD7Init, - dim190JoeKuoD7Init, - dim191JoeKuoD7Init, - dim192JoeKuoD7Init, - dim193JoeKuoD7Init, - dim194JoeKuoD7Init, - dim195JoeKuoD7Init, - dim196JoeKuoD7Init, - dim197JoeKuoD7Init, - dim198JoeKuoD7Init, - dim199JoeKuoD7Init, - dim200JoeKuoD7Init, - dim201JoeKuoD7Init, - dim202JoeKuoD7Init, - dim203JoeKuoD7Init, - dim204JoeKuoD7Init, - dim205JoeKuoD7Init, - dim206JoeKuoD7Init, - dim207JoeKuoD7Init, - dim208JoeKuoD7Init, - dim209JoeKuoD7Init, - dim210JoeKuoD7Init, - dim211JoeKuoD7Init, - dim212JoeKuoD7Init, - dim213JoeKuoD7Init, - dim214JoeKuoD7Init, - dim215JoeKuoD7Init, - dim216JoeKuoD7Init, - dim217JoeKuoD7Init, - dim218JoeKuoD7Init, - dim219JoeKuoD7Init, - dim220JoeKuoD7Init, - dim221JoeKuoD7Init, - dim222JoeKuoD7Init, - dim223JoeKuoD7Init, - dim224JoeKuoD7Init, - dim225JoeKuoD7Init, - dim226JoeKuoD7Init, - dim227JoeKuoD7Init, - dim228JoeKuoD7Init, - dim229JoeKuoD7Init, - dim230JoeKuoD7Init, - dim231JoeKuoD7Init, - dim232JoeKuoD7Init, - dim233JoeKuoD7Init, - dim234JoeKuoD7Init, - dim235JoeKuoD7Init, - dim236JoeKuoD7Init, - dim237JoeKuoD7Init, - dim238JoeKuoD7Init, - dim239JoeKuoD7Init, - dim240JoeKuoD7Init, - dim241JoeKuoD7Init, - dim242JoeKuoD7Init, - dim243JoeKuoD7Init, - dim244JoeKuoD7Init, - dim245JoeKuoD7Init, - dim246JoeKuoD7Init, - dim247JoeKuoD7Init, - dim248JoeKuoD7Init, - dim249JoeKuoD7Init, - dim250JoeKuoD7Init, - dim251JoeKuoD7Init, - dim252JoeKuoD7Init, - dim253JoeKuoD7Init, - dim254JoeKuoD7Init, - dim255JoeKuoD7Init, - dim256JoeKuoD7Init, - dim257JoeKuoD7Init, - dim258JoeKuoD7Init, - dim259JoeKuoD7Init, - dim260JoeKuoD7Init, - dim261JoeKuoD7Init, - dim262JoeKuoD7Init, - dim263JoeKuoD7Init, - dim264JoeKuoD7Init, - dim265JoeKuoD7Init, - dim266JoeKuoD7Init, - dim267JoeKuoD7Init, - dim268JoeKuoD7Init, - dim269JoeKuoD7Init, - dim270JoeKuoD7Init, - dim271JoeKuoD7Init, - dim272JoeKuoD7Init, - dim273JoeKuoD7Init, - dim274JoeKuoD7Init, - dim275JoeKuoD7Init, - dim276JoeKuoD7Init, - dim277JoeKuoD7Init, - dim278JoeKuoD7Init, - dim279JoeKuoD7Init, - dim280JoeKuoD7Init, - dim281JoeKuoD7Init, - dim282JoeKuoD7Init, - dim283JoeKuoD7Init, - dim284JoeKuoD7Init, - dim285JoeKuoD7Init, - dim286JoeKuoD7Init, - dim287JoeKuoD7Init, - dim288JoeKuoD7Init, - dim289JoeKuoD7Init, - dim290JoeKuoD7Init, - dim291JoeKuoD7Init, - dim292JoeKuoD7Init, - dim293JoeKuoD7Init, - dim294JoeKuoD7Init, - dim295JoeKuoD7Init, - dim296JoeKuoD7Init, - dim297JoeKuoD7Init, - dim298JoeKuoD7Init, - dim299JoeKuoD7Init, - dim300JoeKuoD7Init, - dim301JoeKuoD7Init, - dim302JoeKuoD7Init, - dim303JoeKuoD7Init, - dim304JoeKuoD7Init, - dim305JoeKuoD7Init, - dim306JoeKuoD7Init, - dim307JoeKuoD7Init, - dim308JoeKuoD7Init, - dim309JoeKuoD7Init, - dim310JoeKuoD7Init, - dim311JoeKuoD7Init, - dim312JoeKuoD7Init, - dim313JoeKuoD7Init, - dim314JoeKuoD7Init, - dim315JoeKuoD7Init, - dim316JoeKuoD7Init, - dim317JoeKuoD7Init, - dim318JoeKuoD7Init, - dim319JoeKuoD7Init, - dim320JoeKuoD7Init, - dim321JoeKuoD7Init, - dim322JoeKuoD7Init, - dim323JoeKuoD7Init, - dim324JoeKuoD7Init, - dim325JoeKuoD7Init, - dim326JoeKuoD7Init, - dim327JoeKuoD7Init, - dim328JoeKuoD7Init, - dim329JoeKuoD7Init, - dim330JoeKuoD7Init, - dim331JoeKuoD7Init, - dim332JoeKuoD7Init, - dim333JoeKuoD7Init, - dim334JoeKuoD7Init, - dim335JoeKuoD7Init, - dim336JoeKuoD7Init, - dim337JoeKuoD7Init, - dim338JoeKuoD7Init, - dim339JoeKuoD7Init, - dim340JoeKuoD7Init, - dim341JoeKuoD7Init, - dim342JoeKuoD7Init, - dim343JoeKuoD7Init, - dim344JoeKuoD7Init, - dim345JoeKuoD7Init, - dim346JoeKuoD7Init, - dim347JoeKuoD7Init, - dim348JoeKuoD7Init, - dim349JoeKuoD7Init, - dim350JoeKuoD7Init, - dim351JoeKuoD7Init, - dim352JoeKuoD7Init, - dim353JoeKuoD7Init, - dim354JoeKuoD7Init, - dim355JoeKuoD7Init, - dim356JoeKuoD7Init, - dim357JoeKuoD7Init, - dim358JoeKuoD7Init, - dim359JoeKuoD7Init, - dim360JoeKuoD7Init, - dim361JoeKuoD7Init, - dim362JoeKuoD7Init, - dim363JoeKuoD7Init, - dim364JoeKuoD7Init, - dim365JoeKuoD7Init, - dim366JoeKuoD7Init, - dim367JoeKuoD7Init, - dim368JoeKuoD7Init, - dim369JoeKuoD7Init, - dim370JoeKuoD7Init, - dim371JoeKuoD7Init, - dim372JoeKuoD7Init, - dim373JoeKuoD7Init, - dim374JoeKuoD7Init, - dim375JoeKuoD7Init, - dim376JoeKuoD7Init, - dim377JoeKuoD7Init, - dim378JoeKuoD7Init, - dim379JoeKuoD7Init, - dim380JoeKuoD7Init, - dim381JoeKuoD7Init, - dim382JoeKuoD7Init, - dim383JoeKuoD7Init, - dim384JoeKuoD7Init, - dim385JoeKuoD7Init, - dim386JoeKuoD7Init, - dim387JoeKuoD7Init, - dim388JoeKuoD7Init, - dim389JoeKuoD7Init, - dim390JoeKuoD7Init, - dim391JoeKuoD7Init, - dim392JoeKuoD7Init, - dim393JoeKuoD7Init, - dim394JoeKuoD7Init, - dim395JoeKuoD7Init, - dim396JoeKuoD7Init, - dim397JoeKuoD7Init, - dim398JoeKuoD7Init, - dim399JoeKuoD7Init, - dim400JoeKuoD7Init, - dim401JoeKuoD7Init, - dim402JoeKuoD7Init, - dim403JoeKuoD7Init, - dim404JoeKuoD7Init, - dim405JoeKuoD7Init, - dim406JoeKuoD7Init, - dim407JoeKuoD7Init, - dim408JoeKuoD7Init, - dim409JoeKuoD7Init, - dim410JoeKuoD7Init, - dim411JoeKuoD7Init, - dim412JoeKuoD7Init, - dim413JoeKuoD7Init, - dim414JoeKuoD7Init, - dim415JoeKuoD7Init, - dim416JoeKuoD7Init, - dim417JoeKuoD7Init, - dim418JoeKuoD7Init, - dim419JoeKuoD7Init, - dim420JoeKuoD7Init, - dim421JoeKuoD7Init, - dim422JoeKuoD7Init, - dim423JoeKuoD7Init, - dim424JoeKuoD7Init, - dim425JoeKuoD7Init, - dim426JoeKuoD7Init, - dim427JoeKuoD7Init, - dim428JoeKuoD7Init, - dim429JoeKuoD7Init, - dim430JoeKuoD7Init, - dim431JoeKuoD7Init, - dim432JoeKuoD7Init, - dim433JoeKuoD7Init, - dim434JoeKuoD7Init, - dim435JoeKuoD7Init, - dim436JoeKuoD7Init, - dim437JoeKuoD7Init, - dim438JoeKuoD7Init, - dim439JoeKuoD7Init, - dim440JoeKuoD7Init, - dim441JoeKuoD7Init, - dim442JoeKuoD7Init, - dim443JoeKuoD7Init, - dim444JoeKuoD7Init, - dim445JoeKuoD7Init, - dim446JoeKuoD7Init, - dim447JoeKuoD7Init, - dim448JoeKuoD7Init, - dim449JoeKuoD7Init, - dim450JoeKuoD7Init, - dim451JoeKuoD7Init, - dim452JoeKuoD7Init, - dim453JoeKuoD7Init, - dim454JoeKuoD7Init, - dim455JoeKuoD7Init, - dim456JoeKuoD7Init, - dim457JoeKuoD7Init, - dim458JoeKuoD7Init, - dim459JoeKuoD7Init, - dim460JoeKuoD7Init, - dim461JoeKuoD7Init, - dim462JoeKuoD7Init, - dim463JoeKuoD7Init, - dim464JoeKuoD7Init, - dim465JoeKuoD7Init, - dim466JoeKuoD7Init, - dim467JoeKuoD7Init, - dim468JoeKuoD7Init, - dim469JoeKuoD7Init, - dim470JoeKuoD7Init, - dim471JoeKuoD7Init, - dim472JoeKuoD7Init, - dim473JoeKuoD7Init, - dim474JoeKuoD7Init, - dim475JoeKuoD7Init, - dim476JoeKuoD7Init, - dim477JoeKuoD7Init, - dim478JoeKuoD7Init, - dim479JoeKuoD7Init, - dim480JoeKuoD7Init, - dim481JoeKuoD7Init, - dim482JoeKuoD7Init, - dim483JoeKuoD7Init, - dim484JoeKuoD7Init, - dim485JoeKuoD7Init, - dim486JoeKuoD7Init, - dim487JoeKuoD7Init, - dim488JoeKuoD7Init, - dim489JoeKuoD7Init, - dim490JoeKuoD7Init, - dim491JoeKuoD7Init, - dim492JoeKuoD7Init, - dim493JoeKuoD7Init, - dim494JoeKuoD7Init, - dim495JoeKuoD7Init, - dim496JoeKuoD7Init, - dim497JoeKuoD7Init, - dim498JoeKuoD7Init, - dim499JoeKuoD7Init, - dim500JoeKuoD7Init, - dim501JoeKuoD7Init, - dim502JoeKuoD7Init, - dim503JoeKuoD7Init, - dim504JoeKuoD7Init, - dim505JoeKuoD7Init, - dim506JoeKuoD7Init, - dim507JoeKuoD7Init, - dim508JoeKuoD7Init, - dim509JoeKuoD7Init, - dim510JoeKuoD7Init, - dim511JoeKuoD7Init, - dim512JoeKuoD7Init, - dim513JoeKuoD7Init, - dim514JoeKuoD7Init, - dim515JoeKuoD7Init, - dim516JoeKuoD7Init, - dim517JoeKuoD7Init, - dim518JoeKuoD7Init, - dim519JoeKuoD7Init, - dim520JoeKuoD7Init, - dim521JoeKuoD7Init, - dim522JoeKuoD7Init, - dim523JoeKuoD7Init, - dim524JoeKuoD7Init, - dim525JoeKuoD7Init, - dim526JoeKuoD7Init, - dim527JoeKuoD7Init, - dim528JoeKuoD7Init, - dim529JoeKuoD7Init, - dim530JoeKuoD7Init, - dim531JoeKuoD7Init, - dim532JoeKuoD7Init, - dim533JoeKuoD7Init, - dim534JoeKuoD7Init, - dim535JoeKuoD7Init, - dim536JoeKuoD7Init, - dim537JoeKuoD7Init, - dim538JoeKuoD7Init, - dim539JoeKuoD7Init, - dim540JoeKuoD7Init, - dim541JoeKuoD7Init, - dim542JoeKuoD7Init, - dim543JoeKuoD7Init, - dim544JoeKuoD7Init, - dim545JoeKuoD7Init, - dim546JoeKuoD7Init, - dim547JoeKuoD7Init, - dim548JoeKuoD7Init, - dim549JoeKuoD7Init, - dim550JoeKuoD7Init, - dim551JoeKuoD7Init, - dim552JoeKuoD7Init, - dim553JoeKuoD7Init, - dim554JoeKuoD7Init, - dim555JoeKuoD7Init, - dim556JoeKuoD7Init, - dim557JoeKuoD7Init, - dim558JoeKuoD7Init, - dim559JoeKuoD7Init, - dim560JoeKuoD7Init, - dim561JoeKuoD7Init, - dim562JoeKuoD7Init, - dim563JoeKuoD7Init, - dim564JoeKuoD7Init, - dim565JoeKuoD7Init, - dim566JoeKuoD7Init, - dim567JoeKuoD7Init, - dim568JoeKuoD7Init, - dim569JoeKuoD7Init, - dim570JoeKuoD7Init, - dim571JoeKuoD7Init, - dim572JoeKuoD7Init, - dim573JoeKuoD7Init, - dim574JoeKuoD7Init, - dim575JoeKuoD7Init, - dim576JoeKuoD7Init, - dim577JoeKuoD7Init, - dim578JoeKuoD7Init, - dim579JoeKuoD7Init, - dim580JoeKuoD7Init, - dim581JoeKuoD7Init, - dim582JoeKuoD7Init, - dim583JoeKuoD7Init, - dim584JoeKuoD7Init, - dim585JoeKuoD7Init, - dim586JoeKuoD7Init, - dim587JoeKuoD7Init, - dim588JoeKuoD7Init, - dim589JoeKuoD7Init, - dim590JoeKuoD7Init, - dim591JoeKuoD7Init, - dim592JoeKuoD7Init, - dim593JoeKuoD7Init, - dim594JoeKuoD7Init, - dim595JoeKuoD7Init, - dim596JoeKuoD7Init, - dim597JoeKuoD7Init, - dim598JoeKuoD7Init, - dim599JoeKuoD7Init, - dim600JoeKuoD7Init, - dim601JoeKuoD7Init, - dim602JoeKuoD7Init, - dim603JoeKuoD7Init, - dim604JoeKuoD7Init, - dim605JoeKuoD7Init, - dim606JoeKuoD7Init, - dim607JoeKuoD7Init, - dim608JoeKuoD7Init, - dim609JoeKuoD7Init, - dim610JoeKuoD7Init, - dim611JoeKuoD7Init, - dim612JoeKuoD7Init, - dim613JoeKuoD7Init, - dim614JoeKuoD7Init, - dim615JoeKuoD7Init, - dim616JoeKuoD7Init, - dim617JoeKuoD7Init, - dim618JoeKuoD7Init, - dim619JoeKuoD7Init, - dim620JoeKuoD7Init, - dim621JoeKuoD7Init, - dim622JoeKuoD7Init, - dim623JoeKuoD7Init, - dim624JoeKuoD7Init, - dim625JoeKuoD7Init, - dim626JoeKuoD7Init, - dim627JoeKuoD7Init, - dim628JoeKuoD7Init, - dim629JoeKuoD7Init, - dim630JoeKuoD7Init, - dim631JoeKuoD7Init, - dim632JoeKuoD7Init, - dim633JoeKuoD7Init, - dim634JoeKuoD7Init, - dim635JoeKuoD7Init, - dim636JoeKuoD7Init, - dim637JoeKuoD7Init, - dim638JoeKuoD7Init, - dim639JoeKuoD7Init, - dim640JoeKuoD7Init, - dim641JoeKuoD7Init, - dim642JoeKuoD7Init, - dim643JoeKuoD7Init, - dim644JoeKuoD7Init, - dim645JoeKuoD7Init, - dim646JoeKuoD7Init, - dim647JoeKuoD7Init, - dim648JoeKuoD7Init, - dim649JoeKuoD7Init, - dim650JoeKuoD7Init, - dim651JoeKuoD7Init, - dim652JoeKuoD7Init, - dim653JoeKuoD7Init, - dim654JoeKuoD7Init, - dim655JoeKuoD7Init, - dim656JoeKuoD7Init, - dim657JoeKuoD7Init, - dim658JoeKuoD7Init, - dim659JoeKuoD7Init, - dim660JoeKuoD7Init, - dim661JoeKuoD7Init, - dim662JoeKuoD7Init, - dim663JoeKuoD7Init, - dim664JoeKuoD7Init, - dim665JoeKuoD7Init, - dim666JoeKuoD7Init, - dim667JoeKuoD7Init, - dim668JoeKuoD7Init, - dim669JoeKuoD7Init, - dim670JoeKuoD7Init, - dim671JoeKuoD7Init, - dim672JoeKuoD7Init, - dim673JoeKuoD7Init, - dim674JoeKuoD7Init, - dim675JoeKuoD7Init, - dim676JoeKuoD7Init, - dim677JoeKuoD7Init, - dim678JoeKuoD7Init, - dim679JoeKuoD7Init, - dim680JoeKuoD7Init, - dim681JoeKuoD7Init, - dim682JoeKuoD7Init, - dim683JoeKuoD7Init, - dim684JoeKuoD7Init, - dim685JoeKuoD7Init, - dim686JoeKuoD7Init, - dim687JoeKuoD7Init, - dim688JoeKuoD7Init, - dim689JoeKuoD7Init, - dim690JoeKuoD7Init, - dim691JoeKuoD7Init, - dim692JoeKuoD7Init, - dim693JoeKuoD7Init, - dim694JoeKuoD7Init, - dim695JoeKuoD7Init, - dim696JoeKuoD7Init, - dim697JoeKuoD7Init, - dim698JoeKuoD7Init, - dim699JoeKuoD7Init, - dim700JoeKuoD7Init, - dim701JoeKuoD7Init, - dim702JoeKuoD7Init, - dim703JoeKuoD7Init, - dim704JoeKuoD7Init, - dim705JoeKuoD7Init, - dim706JoeKuoD7Init, - dim707JoeKuoD7Init, - dim708JoeKuoD7Init, - dim709JoeKuoD7Init, - dim710JoeKuoD7Init, - dim711JoeKuoD7Init, - dim712JoeKuoD7Init, - dim713JoeKuoD7Init, - dim714JoeKuoD7Init, - dim715JoeKuoD7Init, - dim716JoeKuoD7Init, - dim717JoeKuoD7Init, - dim718JoeKuoD7Init, - dim719JoeKuoD7Init, - dim720JoeKuoD7Init, - dim721JoeKuoD7Init, - dim722JoeKuoD7Init, - dim723JoeKuoD7Init, - dim724JoeKuoD7Init, - dim725JoeKuoD7Init, - dim726JoeKuoD7Init, - dim727JoeKuoD7Init, - dim728JoeKuoD7Init, - dim729JoeKuoD7Init, - dim730JoeKuoD7Init, - dim731JoeKuoD7Init, - dim732JoeKuoD7Init, - dim733JoeKuoD7Init, - dim734JoeKuoD7Init, - dim735JoeKuoD7Init, - dim736JoeKuoD7Init, - dim737JoeKuoD7Init, - dim738JoeKuoD7Init, - dim739JoeKuoD7Init, - dim740JoeKuoD7Init, - dim741JoeKuoD7Init, - dim742JoeKuoD7Init, - dim743JoeKuoD7Init, - dim744JoeKuoD7Init, - dim745JoeKuoD7Init, - dim746JoeKuoD7Init, - dim747JoeKuoD7Init, - dim748JoeKuoD7Init, - dim749JoeKuoD7Init, - dim750JoeKuoD7Init, - dim751JoeKuoD7Init, - dim752JoeKuoD7Init, - dim753JoeKuoD7Init, - dim754JoeKuoD7Init, - dim755JoeKuoD7Init, - dim756JoeKuoD7Init, - dim757JoeKuoD7Init, - dim758JoeKuoD7Init, - dim759JoeKuoD7Init, - dim760JoeKuoD7Init, - dim761JoeKuoD7Init, - dim762JoeKuoD7Init, - dim763JoeKuoD7Init, - dim764JoeKuoD7Init, - dim765JoeKuoD7Init, - dim766JoeKuoD7Init, - dim767JoeKuoD7Init, - dim768JoeKuoD7Init, - dim769JoeKuoD7Init, - dim770JoeKuoD7Init, - dim771JoeKuoD7Init, - dim772JoeKuoD7Init, - dim773JoeKuoD7Init, - dim774JoeKuoD7Init, - dim775JoeKuoD7Init, - dim776JoeKuoD7Init, - dim777JoeKuoD7Init, - dim778JoeKuoD7Init, - dim779JoeKuoD7Init, - dim780JoeKuoD7Init, - dim781JoeKuoD7Init, - dim782JoeKuoD7Init, - dim783JoeKuoD7Init, - dim784JoeKuoD7Init, - dim785JoeKuoD7Init, - dim786JoeKuoD7Init, - dim787JoeKuoD7Init, - dim788JoeKuoD7Init, - dim789JoeKuoD7Init, - dim790JoeKuoD7Init, - dim791JoeKuoD7Init, - dim792JoeKuoD7Init, - dim793JoeKuoD7Init, - dim794JoeKuoD7Init, - dim795JoeKuoD7Init, - dim796JoeKuoD7Init, - dim797JoeKuoD7Init, - dim798JoeKuoD7Init, - dim799JoeKuoD7Init, - dim800JoeKuoD7Init, - dim801JoeKuoD7Init, - dim802JoeKuoD7Init, - dim803JoeKuoD7Init, - dim804JoeKuoD7Init, - dim805JoeKuoD7Init, - dim806JoeKuoD7Init, - dim807JoeKuoD7Init, - dim808JoeKuoD7Init, - dim809JoeKuoD7Init, - dim810JoeKuoD7Init, - dim811JoeKuoD7Init, - dim812JoeKuoD7Init, - dim813JoeKuoD7Init, - dim814JoeKuoD7Init, - dim815JoeKuoD7Init, - dim816JoeKuoD7Init, - dim817JoeKuoD7Init, - dim818JoeKuoD7Init, - dim819JoeKuoD7Init, - dim820JoeKuoD7Init, - dim821JoeKuoD7Init, - dim822JoeKuoD7Init, - dim823JoeKuoD7Init, - dim824JoeKuoD7Init, - dim825JoeKuoD7Init, - dim826JoeKuoD7Init, - dim827JoeKuoD7Init, - dim828JoeKuoD7Init, - dim829JoeKuoD7Init, - dim830JoeKuoD7Init, - dim831JoeKuoD7Init, - dim832JoeKuoD7Init, - dim833JoeKuoD7Init, - dim834JoeKuoD7Init, - dim835JoeKuoD7Init, - dim836JoeKuoD7Init, - dim837JoeKuoD7Init, - dim838JoeKuoD7Init, - dim839JoeKuoD7Init, - dim840JoeKuoD7Init, - dim841JoeKuoD7Init, - dim842JoeKuoD7Init, - dim843JoeKuoD7Init, - dim844JoeKuoD7Init, - dim845JoeKuoD7Init, - dim846JoeKuoD7Init, - dim847JoeKuoD7Init, - dim848JoeKuoD7Init, - dim849JoeKuoD7Init, - dim850JoeKuoD7Init, - dim851JoeKuoD7Init, - dim852JoeKuoD7Init, - dim853JoeKuoD7Init, - dim854JoeKuoD7Init, - dim855JoeKuoD7Init, - dim856JoeKuoD7Init, - dim857JoeKuoD7Init, - dim858JoeKuoD7Init, - dim859JoeKuoD7Init, - dim860JoeKuoD7Init, - dim861JoeKuoD7Init, - dim862JoeKuoD7Init, - dim863JoeKuoD7Init, - dim864JoeKuoD7Init, - dim865JoeKuoD7Init, - dim866JoeKuoD7Init, - dim867JoeKuoD7Init, - dim868JoeKuoD7Init, - dim869JoeKuoD7Init, - dim870JoeKuoD7Init, - dim871JoeKuoD7Init, - dim872JoeKuoD7Init, - dim873JoeKuoD7Init, - dim874JoeKuoD7Init, - dim875JoeKuoD7Init, - dim876JoeKuoD7Init, - dim877JoeKuoD7Init, - dim878JoeKuoD7Init, - dim879JoeKuoD7Init, - dim880JoeKuoD7Init, - dim881JoeKuoD7Init, - dim882JoeKuoD7Init, - dim883JoeKuoD7Init, - dim884JoeKuoD7Init, - dim885JoeKuoD7Init, - dim886JoeKuoD7Init, - dim887JoeKuoD7Init, - dim888JoeKuoD7Init, - dim889JoeKuoD7Init, - dim890JoeKuoD7Init, - dim891JoeKuoD7Init, - dim892JoeKuoD7Init, - dim893JoeKuoD7Init, - dim894JoeKuoD7Init, - dim895JoeKuoD7Init, - dim896JoeKuoD7Init, - dim897JoeKuoD7Init, - dim898JoeKuoD7Init, - dim899JoeKuoD7Init, - dim900JoeKuoD7Init, - dim901JoeKuoD7Init, - dim902JoeKuoD7Init, - dim903JoeKuoD7Init, - dim904JoeKuoD7Init, - dim905JoeKuoD7Init, - dim906JoeKuoD7Init, - dim907JoeKuoD7Init, - dim908JoeKuoD7Init, - dim909JoeKuoD7Init, - dim910JoeKuoD7Init, - dim911JoeKuoD7Init, - dim912JoeKuoD7Init, - dim913JoeKuoD7Init, - dim914JoeKuoD7Init, - dim915JoeKuoD7Init, - dim916JoeKuoD7Init, - dim917JoeKuoD7Init, - dim918JoeKuoD7Init, - dim919JoeKuoD7Init, - dim920JoeKuoD7Init, - dim921JoeKuoD7Init, - dim922JoeKuoD7Init, - dim923JoeKuoD7Init, - dim924JoeKuoD7Init, - dim925JoeKuoD7Init, - dim926JoeKuoD7Init, - dim927JoeKuoD7Init, - dim928JoeKuoD7Init, - dim929JoeKuoD7Init, - dim930JoeKuoD7Init, - dim931JoeKuoD7Init, - dim932JoeKuoD7Init, - dim933JoeKuoD7Init, - dim934JoeKuoD7Init, - dim935JoeKuoD7Init, - dim936JoeKuoD7Init, - dim937JoeKuoD7Init, - dim938JoeKuoD7Init, - dim939JoeKuoD7Init, - dim940JoeKuoD7Init, - dim941JoeKuoD7Init, - dim942JoeKuoD7Init, - dim943JoeKuoD7Init, - dim944JoeKuoD7Init, - dim945JoeKuoD7Init, - dim946JoeKuoD7Init, - dim947JoeKuoD7Init, - dim948JoeKuoD7Init, - dim949JoeKuoD7Init, - dim950JoeKuoD7Init, - dim951JoeKuoD7Init, - dim952JoeKuoD7Init, - dim953JoeKuoD7Init, - dim954JoeKuoD7Init, - dim955JoeKuoD7Init, - dim956JoeKuoD7Init, - dim957JoeKuoD7Init, - dim958JoeKuoD7Init, - dim959JoeKuoD7Init, - dim960JoeKuoD7Init, - dim961JoeKuoD7Init, - dim962JoeKuoD7Init, - dim963JoeKuoD7Init, - dim964JoeKuoD7Init, - dim965JoeKuoD7Init, - dim966JoeKuoD7Init, - dim967JoeKuoD7Init, - dim968JoeKuoD7Init, - dim969JoeKuoD7Init, - dim970JoeKuoD7Init, - dim971JoeKuoD7Init, - dim972JoeKuoD7Init, - dim973JoeKuoD7Init, - dim974JoeKuoD7Init, - dim975JoeKuoD7Init, - dim976JoeKuoD7Init, - dim977JoeKuoD7Init, - dim978JoeKuoD7Init, - dim979JoeKuoD7Init, - dim980JoeKuoD7Init, - dim981JoeKuoD7Init, - dim982JoeKuoD7Init, - dim983JoeKuoD7Init, - dim984JoeKuoD7Init, - dim985JoeKuoD7Init, - dim986JoeKuoD7Init, - dim987JoeKuoD7Init, - dim988JoeKuoD7Init, - dim989JoeKuoD7Init, - dim990JoeKuoD7Init, - dim991JoeKuoD7Init, - dim992JoeKuoD7Init, - dim993JoeKuoD7Init, - dim994JoeKuoD7Init, - dim995JoeKuoD7Init, - dim996JoeKuoD7Init, - dim997JoeKuoD7Init, - dim998JoeKuoD7Init, - dim999JoeKuoD7Init, - dim1000JoeKuoD7Init, - dim1001JoeKuoD7Init, - dim1002JoeKuoD7Init, - dim1003JoeKuoD7Init, - dim1004JoeKuoD7Init, - dim1005JoeKuoD7Init, - dim1006JoeKuoD7Init, - dim1007JoeKuoD7Init, - dim1008JoeKuoD7Init, - dim1009JoeKuoD7Init, - dim1010JoeKuoD7Init, - dim1011JoeKuoD7Init, - dim1012JoeKuoD7Init, - dim1013JoeKuoD7Init, - dim1014JoeKuoD7Init, - dim1015JoeKuoD7Init, - dim1016JoeKuoD7Init, - dim1017JoeKuoD7Init, - dim1018JoeKuoD7Init, - dim1019JoeKuoD7Init, - dim1020JoeKuoD7Init, - dim1021JoeKuoD7Init, - dim1022JoeKuoD7Init, - dim1023JoeKuoD7Init, - dim1024JoeKuoD7Init, - dim1025JoeKuoD7Init, - dim1026JoeKuoD7Init, - dim1027JoeKuoD7Init, - dim1028JoeKuoD7Init, - dim1029JoeKuoD7Init, - dim1030JoeKuoD7Init, - dim1031JoeKuoD7Init, - dim1032JoeKuoD7Init, - dim1033JoeKuoD7Init, - dim1034JoeKuoD7Init, - dim1035JoeKuoD7Init, - dim1036JoeKuoD7Init, - dim1037JoeKuoD7Init, - dim1038JoeKuoD7Init, - dim1039JoeKuoD7Init, - dim1040JoeKuoD7Init, - dim1041JoeKuoD7Init, - dim1042JoeKuoD7Init, - dim1043JoeKuoD7Init, - dim1044JoeKuoD7Init, - dim1045JoeKuoD7Init, - dim1046JoeKuoD7Init, - dim1047JoeKuoD7Init, - dim1048JoeKuoD7Init, - dim1049JoeKuoD7Init, - dim1050JoeKuoD7Init, - dim1051JoeKuoD7Init, - dim1052JoeKuoD7Init, - dim1053JoeKuoD7Init, - dim1054JoeKuoD7Init, - dim1055JoeKuoD7Init, - dim1056JoeKuoD7Init, - dim1057JoeKuoD7Init, - dim1058JoeKuoD7Init, - dim1059JoeKuoD7Init, - dim1060JoeKuoD7Init, - dim1061JoeKuoD7Init, - dim1062JoeKuoD7Init, - dim1063JoeKuoD7Init, - dim1064JoeKuoD7Init, - dim1065JoeKuoD7Init, - dim1066JoeKuoD7Init, - dim1067JoeKuoD7Init, - dim1068JoeKuoD7Init, - dim1069JoeKuoD7Init, - dim1070JoeKuoD7Init, - dim1071JoeKuoD7Init, - dim1072JoeKuoD7Init, - dim1073JoeKuoD7Init, - dim1074JoeKuoD7Init, - dim1075JoeKuoD7Init, - dim1076JoeKuoD7Init, - dim1077JoeKuoD7Init, - dim1078JoeKuoD7Init, - dim1079JoeKuoD7Init, - dim1080JoeKuoD7Init, - dim1081JoeKuoD7Init, - dim1082JoeKuoD7Init, - dim1083JoeKuoD7Init, - dim1084JoeKuoD7Init, - dim1085JoeKuoD7Init, - dim1086JoeKuoD7Init, - dim1087JoeKuoD7Init, - dim1088JoeKuoD7Init, - dim1089JoeKuoD7Init, - dim1090JoeKuoD7Init, - dim1091JoeKuoD7Init, - dim1092JoeKuoD7Init, - dim1093JoeKuoD7Init, - dim1094JoeKuoD7Init, - dim1095JoeKuoD7Init, - dim1096JoeKuoD7Init, - dim1097JoeKuoD7Init, - dim1098JoeKuoD7Init, - dim1099JoeKuoD7Init, - dim1100JoeKuoD7Init, - dim1101JoeKuoD7Init, - dim1102JoeKuoD7Init, - dim1103JoeKuoD7Init, - dim1104JoeKuoD7Init, - dim1105JoeKuoD7Init, - dim1106JoeKuoD7Init, - dim1107JoeKuoD7Init, - dim1108JoeKuoD7Init, - dim1109JoeKuoD7Init, - dim1110JoeKuoD7Init, - dim1111JoeKuoD7Init, - dim1112JoeKuoD7Init, - dim1113JoeKuoD7Init, - dim1114JoeKuoD7Init, - dim1115JoeKuoD7Init, - dim1116JoeKuoD7Init, - dim1117JoeKuoD7Init, - dim1118JoeKuoD7Init, - dim1119JoeKuoD7Init, - dim1120JoeKuoD7Init, - dim1121JoeKuoD7Init, - dim1122JoeKuoD7Init, - dim1123JoeKuoD7Init, - dim1124JoeKuoD7Init, - dim1125JoeKuoD7Init, - dim1126JoeKuoD7Init, - dim1127JoeKuoD7Init, - dim1128JoeKuoD7Init, - dim1129JoeKuoD7Init, - dim1130JoeKuoD7Init, - dim1131JoeKuoD7Init, - dim1132JoeKuoD7Init, - dim1133JoeKuoD7Init, - dim1134JoeKuoD7Init, - dim1135JoeKuoD7Init, - dim1136JoeKuoD7Init, - dim1137JoeKuoD7Init, - dim1138JoeKuoD7Init, - dim1139JoeKuoD7Init, - dim1140JoeKuoD7Init, - dim1141JoeKuoD7Init, - dim1142JoeKuoD7Init, - dim1143JoeKuoD7Init, - dim1144JoeKuoD7Init, - dim1145JoeKuoD7Init, - dim1146JoeKuoD7Init, - dim1147JoeKuoD7Init, - dim1148JoeKuoD7Init, - dim1149JoeKuoD7Init, - dim1150JoeKuoD7Init, - dim1151JoeKuoD7Init, - dim1152JoeKuoD7Init, - dim1153JoeKuoD7Init, - dim1154JoeKuoD7Init, - dim1155JoeKuoD7Init, - dim1156JoeKuoD7Init, - dim1157JoeKuoD7Init, - dim1158JoeKuoD7Init, - dim1159JoeKuoD7Init, - dim1160JoeKuoD7Init, - dim1161JoeKuoD7Init, - dim1162JoeKuoD7Init, - dim1163JoeKuoD7Init, - dim1164JoeKuoD7Init, - dim1165JoeKuoD7Init, - dim1166JoeKuoD7Init, - dim1167JoeKuoD7Init, - dim1168JoeKuoD7Init, - dim1169JoeKuoD7Init, - dim1170JoeKuoD7Init, - dim1171JoeKuoD7Init, - dim1172JoeKuoD7Init, - dim1173JoeKuoD7Init, - dim1174JoeKuoD7Init, - dim1175JoeKuoD7Init, - dim1176JoeKuoD7Init, - dim1177JoeKuoD7Init, - dim1178JoeKuoD7Init, - dim1179JoeKuoD7Init, - dim1180JoeKuoD7Init, - dim1181JoeKuoD7Init, - dim1182JoeKuoD7Init, - dim1183JoeKuoD7Init, - dim1184JoeKuoD7Init, - dim1185JoeKuoD7Init, - dim1186JoeKuoD7Init, - dim1187JoeKuoD7Init, - dim1188JoeKuoD7Init, - dim1189JoeKuoD7Init, - dim1190JoeKuoD7Init, - dim1191JoeKuoD7Init, - dim1192JoeKuoD7Init, - dim1193JoeKuoD7Init, - dim1194JoeKuoD7Init, - dim1195JoeKuoD7Init, - dim1196JoeKuoD7Init, - dim1197JoeKuoD7Init, - dim1198JoeKuoD7Init, - dim1199JoeKuoD7Init, - dim1200JoeKuoD7Init, - dim1201JoeKuoD7Init, - dim1202JoeKuoD7Init, - dim1203JoeKuoD7Init, - dim1204JoeKuoD7Init, - dim1205JoeKuoD7Init, - dim1206JoeKuoD7Init, - dim1207JoeKuoD7Init, - dim1208JoeKuoD7Init, - dim1209JoeKuoD7Init, - dim1210JoeKuoD7Init, - dim1211JoeKuoD7Init, - dim1212JoeKuoD7Init, - dim1213JoeKuoD7Init, - dim1214JoeKuoD7Init, - dim1215JoeKuoD7Init, - dim1216JoeKuoD7Init, - dim1217JoeKuoD7Init, - dim1218JoeKuoD7Init, - dim1219JoeKuoD7Init, - dim1220JoeKuoD7Init, - dim1221JoeKuoD7Init, - dim1222JoeKuoD7Init, - dim1223JoeKuoD7Init, - dim1224JoeKuoD7Init, - dim1225JoeKuoD7Init, - dim1226JoeKuoD7Init, - dim1227JoeKuoD7Init, - dim1228JoeKuoD7Init, - dim1229JoeKuoD7Init, - dim1230JoeKuoD7Init, - dim1231JoeKuoD7Init, - dim1232JoeKuoD7Init, - dim1233JoeKuoD7Init, - dim1234JoeKuoD7Init, - dim1235JoeKuoD7Init, - dim1236JoeKuoD7Init, - dim1237JoeKuoD7Init, - dim1238JoeKuoD7Init, - dim1239JoeKuoD7Init, - dim1240JoeKuoD7Init, - dim1241JoeKuoD7Init, - dim1242JoeKuoD7Init, - dim1243JoeKuoD7Init, - dim1244JoeKuoD7Init, - dim1245JoeKuoD7Init, - dim1246JoeKuoD7Init, - dim1247JoeKuoD7Init, - dim1248JoeKuoD7Init, - dim1249JoeKuoD7Init, - dim1250JoeKuoD7Init, - dim1251JoeKuoD7Init, - dim1252JoeKuoD7Init, - dim1253JoeKuoD7Init, - dim1254JoeKuoD7Init, - dim1255JoeKuoD7Init, - dim1256JoeKuoD7Init, - dim1257JoeKuoD7Init, - dim1258JoeKuoD7Init, - dim1259JoeKuoD7Init, - dim1260JoeKuoD7Init, - dim1261JoeKuoD7Init, - dim1262JoeKuoD7Init, - dim1263JoeKuoD7Init, - dim1264JoeKuoD7Init, - dim1265JoeKuoD7Init, - dim1266JoeKuoD7Init, - dim1267JoeKuoD7Init, - dim1268JoeKuoD7Init, - dim1269JoeKuoD7Init, - dim1270JoeKuoD7Init, - dim1271JoeKuoD7Init, - dim1272JoeKuoD7Init, - dim1273JoeKuoD7Init, - dim1274JoeKuoD7Init, - dim1275JoeKuoD7Init, - dim1276JoeKuoD7Init, - dim1277JoeKuoD7Init, - dim1278JoeKuoD7Init, - dim1279JoeKuoD7Init, - dim1280JoeKuoD7Init, - dim1281JoeKuoD7Init, - dim1282JoeKuoD7Init, - dim1283JoeKuoD7Init, - dim1284JoeKuoD7Init, - dim1285JoeKuoD7Init, - dim1286JoeKuoD7Init, - dim1287JoeKuoD7Init, - dim1288JoeKuoD7Init, - dim1289JoeKuoD7Init, - dim1290JoeKuoD7Init, - dim1291JoeKuoD7Init, - dim1292JoeKuoD7Init, - dim1293JoeKuoD7Init, - dim1294JoeKuoD7Init, - dim1295JoeKuoD7Init, - dim1296JoeKuoD7Init, - dim1297JoeKuoD7Init, - dim1298JoeKuoD7Init, - dim1299JoeKuoD7Init, - dim1300JoeKuoD7Init, - dim1301JoeKuoD7Init, - dim1302JoeKuoD7Init, - dim1303JoeKuoD7Init, - dim1304JoeKuoD7Init, - dim1305JoeKuoD7Init, - dim1306JoeKuoD7Init, - dim1307JoeKuoD7Init, - dim1308JoeKuoD7Init, - dim1309JoeKuoD7Init, - dim1310JoeKuoD7Init, - dim1311JoeKuoD7Init, - dim1312JoeKuoD7Init, - dim1313JoeKuoD7Init, - dim1314JoeKuoD7Init, - dim1315JoeKuoD7Init, - dim1316JoeKuoD7Init, - dim1317JoeKuoD7Init, - dim1318JoeKuoD7Init, - dim1319JoeKuoD7Init, - dim1320JoeKuoD7Init, - dim1321JoeKuoD7Init, - dim1322JoeKuoD7Init, - dim1323JoeKuoD7Init, - dim1324JoeKuoD7Init, - dim1325JoeKuoD7Init, - dim1326JoeKuoD7Init, - dim1327JoeKuoD7Init, - dim1328JoeKuoD7Init, - dim1329JoeKuoD7Init, - dim1330JoeKuoD7Init, - dim1331JoeKuoD7Init, - dim1332JoeKuoD7Init, - dim1333JoeKuoD7Init, - dim1334JoeKuoD7Init, - dim1335JoeKuoD7Init, - dim1336JoeKuoD7Init, - dim1337JoeKuoD7Init, - dim1338JoeKuoD7Init, - dim1339JoeKuoD7Init, - dim1340JoeKuoD7Init, - dim1341JoeKuoD7Init, - dim1342JoeKuoD7Init, - dim1343JoeKuoD7Init, - dim1344JoeKuoD7Init, - dim1345JoeKuoD7Init, - dim1346JoeKuoD7Init, - dim1347JoeKuoD7Init, - dim1348JoeKuoD7Init, - dim1349JoeKuoD7Init, - dim1350JoeKuoD7Init, - dim1351JoeKuoD7Init, - dim1352JoeKuoD7Init, - dim1353JoeKuoD7Init, - dim1354JoeKuoD7Init, - dim1355JoeKuoD7Init, - dim1356JoeKuoD7Init, - dim1357JoeKuoD7Init, - dim1358JoeKuoD7Init, - dim1359JoeKuoD7Init, - dim1360JoeKuoD7Init, - dim1361JoeKuoD7Init, - dim1362JoeKuoD7Init, - dim1363JoeKuoD7Init, - dim1364JoeKuoD7Init, - dim1365JoeKuoD7Init, - dim1366JoeKuoD7Init, - dim1367JoeKuoD7Init, - dim1368JoeKuoD7Init, - dim1369JoeKuoD7Init, - dim1370JoeKuoD7Init, - dim1371JoeKuoD7Init, - dim1372JoeKuoD7Init, - dim1373JoeKuoD7Init, - dim1374JoeKuoD7Init, - dim1375JoeKuoD7Init, - dim1376JoeKuoD7Init, - dim1377JoeKuoD7Init, - dim1378JoeKuoD7Init, - dim1379JoeKuoD7Init, - dim1380JoeKuoD7Init, - dim1381JoeKuoD7Init, - dim1382JoeKuoD7Init, - dim1383JoeKuoD7Init, - dim1384JoeKuoD7Init, - dim1385JoeKuoD7Init, - dim1386JoeKuoD7Init, - dim1387JoeKuoD7Init, - dim1388JoeKuoD7Init, - dim1389JoeKuoD7Init, - dim1390JoeKuoD7Init, - dim1391JoeKuoD7Init, - dim1392JoeKuoD7Init, - dim1393JoeKuoD7Init, - dim1394JoeKuoD7Init, - dim1395JoeKuoD7Init, - dim1396JoeKuoD7Init, - dim1397JoeKuoD7Init, - dim1398JoeKuoD7Init, - dim1399JoeKuoD7Init, - dim1400JoeKuoD7Init, - dim1401JoeKuoD7Init, - dim1402JoeKuoD7Init, - dim1403JoeKuoD7Init, - dim1404JoeKuoD7Init, - dim1405JoeKuoD7Init, - dim1406JoeKuoD7Init, - dim1407JoeKuoD7Init, - dim1408JoeKuoD7Init, - dim1409JoeKuoD7Init, - dim1410JoeKuoD7Init, - dim1411JoeKuoD7Init, - dim1412JoeKuoD7Init, - dim1413JoeKuoD7Init, - dim1414JoeKuoD7Init, - dim1415JoeKuoD7Init, - dim1416JoeKuoD7Init, - dim1417JoeKuoD7Init, - dim1418JoeKuoD7Init, - dim1419JoeKuoD7Init, - dim1420JoeKuoD7Init, - dim1421JoeKuoD7Init, - dim1422JoeKuoD7Init, - dim1423JoeKuoD7Init, - dim1424JoeKuoD7Init, - dim1425JoeKuoD7Init, - dim1426JoeKuoD7Init, - dim1427JoeKuoD7Init, - dim1428JoeKuoD7Init, - dim1429JoeKuoD7Init, - dim1430JoeKuoD7Init, - dim1431JoeKuoD7Init, - dim1432JoeKuoD7Init, - dim1433JoeKuoD7Init, - dim1434JoeKuoD7Init, - dim1435JoeKuoD7Init, - dim1436JoeKuoD7Init, - dim1437JoeKuoD7Init, - dim1438JoeKuoD7Init, - dim1439JoeKuoD7Init, - dim1440JoeKuoD7Init, - dim1441JoeKuoD7Init, - dim1442JoeKuoD7Init, - dim1443JoeKuoD7Init, - dim1444JoeKuoD7Init, - dim1445JoeKuoD7Init, - dim1446JoeKuoD7Init, - dim1447JoeKuoD7Init, - dim1448JoeKuoD7Init, - dim1449JoeKuoD7Init, - dim1450JoeKuoD7Init, - dim1451JoeKuoD7Init, - dim1452JoeKuoD7Init, - dim1453JoeKuoD7Init, - dim1454JoeKuoD7Init, - dim1455JoeKuoD7Init, - dim1456JoeKuoD7Init, - dim1457JoeKuoD7Init, - dim1458JoeKuoD7Init, - dim1459JoeKuoD7Init, - dim1460JoeKuoD7Init, - dim1461JoeKuoD7Init, - dim1462JoeKuoD7Init, - dim1463JoeKuoD7Init, - dim1464JoeKuoD7Init, - dim1465JoeKuoD7Init, - dim1466JoeKuoD7Init, - dim1467JoeKuoD7Init, - dim1468JoeKuoD7Init, - dim1469JoeKuoD7Init, - dim1470JoeKuoD7Init, - dim1471JoeKuoD7Init, - dim1472JoeKuoD7Init, - dim1473JoeKuoD7Init, - dim1474JoeKuoD7Init, - dim1475JoeKuoD7Init, - dim1476JoeKuoD7Init, - dim1477JoeKuoD7Init, - dim1478JoeKuoD7Init, - dim1479JoeKuoD7Init, - dim1480JoeKuoD7Init, - dim1481JoeKuoD7Init, - dim1482JoeKuoD7Init, - dim1483JoeKuoD7Init, - dim1484JoeKuoD7Init, - dim1485JoeKuoD7Init, - dim1486JoeKuoD7Init, - dim1487JoeKuoD7Init, - dim1488JoeKuoD7Init, - dim1489JoeKuoD7Init, - dim1490JoeKuoD7Init, - dim1491JoeKuoD7Init, - dim1492JoeKuoD7Init, - dim1493JoeKuoD7Init, - dim1494JoeKuoD7Init, - dim1495JoeKuoD7Init, - dim1496JoeKuoD7Init, - dim1497JoeKuoD7Init, - dim1498JoeKuoD7Init, - dim1499JoeKuoD7Init, - dim1500JoeKuoD7Init, - dim1501JoeKuoD7Init, - dim1502JoeKuoD7Init, - dim1503JoeKuoD7Init, - dim1504JoeKuoD7Init, - dim1505JoeKuoD7Init, - dim1506JoeKuoD7Init, - dim1507JoeKuoD7Init, - dim1508JoeKuoD7Init, - dim1509JoeKuoD7Init, - dim1510JoeKuoD7Init, - dim1511JoeKuoD7Init, - dim1512JoeKuoD7Init, - dim1513JoeKuoD7Init, - dim1514JoeKuoD7Init, - dim1515JoeKuoD7Init, - dim1516JoeKuoD7Init, - dim1517JoeKuoD7Init, - dim1518JoeKuoD7Init, - dim1519JoeKuoD7Init, - dim1520JoeKuoD7Init, - dim1521JoeKuoD7Init, - dim1522JoeKuoD7Init, - dim1523JoeKuoD7Init, - dim1524JoeKuoD7Init, - dim1525JoeKuoD7Init, - dim1526JoeKuoD7Init, - dim1527JoeKuoD7Init, - dim1528JoeKuoD7Init, - dim1529JoeKuoD7Init, - dim1530JoeKuoD7Init, - dim1531JoeKuoD7Init, - dim1532JoeKuoD7Init, - dim1533JoeKuoD7Init, - dim1534JoeKuoD7Init, - dim1535JoeKuoD7Init, - dim1536JoeKuoD7Init, - dim1537JoeKuoD7Init, - dim1538JoeKuoD7Init, - dim1539JoeKuoD7Init, - dim1540JoeKuoD7Init, - dim1541JoeKuoD7Init, - dim1542JoeKuoD7Init, - dim1543JoeKuoD7Init, - dim1544JoeKuoD7Init, - dim1545JoeKuoD7Init, - dim1546JoeKuoD7Init, - dim1547JoeKuoD7Init, - dim1548JoeKuoD7Init, - dim1549JoeKuoD7Init, - dim1550JoeKuoD7Init, - dim1551JoeKuoD7Init, - dim1552JoeKuoD7Init, - dim1553JoeKuoD7Init, - dim1554JoeKuoD7Init, - dim1555JoeKuoD7Init, - dim1556JoeKuoD7Init, - dim1557JoeKuoD7Init, - dim1558JoeKuoD7Init, - dim1559JoeKuoD7Init, - dim1560JoeKuoD7Init, - dim1561JoeKuoD7Init, - dim1562JoeKuoD7Init, - dim1563JoeKuoD7Init, - dim1564JoeKuoD7Init, - dim1565JoeKuoD7Init, - dim1566JoeKuoD7Init, - dim1567JoeKuoD7Init, - dim1568JoeKuoD7Init, - dim1569JoeKuoD7Init, - dim1570JoeKuoD7Init, - dim1571JoeKuoD7Init, - dim1572JoeKuoD7Init, - dim1573JoeKuoD7Init, - dim1574JoeKuoD7Init, - dim1575JoeKuoD7Init, - dim1576JoeKuoD7Init, - dim1577JoeKuoD7Init, - dim1578JoeKuoD7Init, - dim1579JoeKuoD7Init, - dim1580JoeKuoD7Init, - dim1581JoeKuoD7Init, - dim1582JoeKuoD7Init, - dim1583JoeKuoD7Init, - dim1584JoeKuoD7Init, - dim1585JoeKuoD7Init, - dim1586JoeKuoD7Init, - dim1587JoeKuoD7Init, - dim1588JoeKuoD7Init, - dim1589JoeKuoD7Init, - dim1590JoeKuoD7Init, - dim1591JoeKuoD7Init, - dim1592JoeKuoD7Init, - dim1593JoeKuoD7Init, - dim1594JoeKuoD7Init, - dim1595JoeKuoD7Init, - dim1596JoeKuoD7Init, - dim1597JoeKuoD7Init, - dim1598JoeKuoD7Init, - dim1599JoeKuoD7Init, - dim1600JoeKuoD7Init, - dim1601JoeKuoD7Init, - dim1602JoeKuoD7Init, - dim1603JoeKuoD7Init, - dim1604JoeKuoD7Init, - dim1605JoeKuoD7Init, - dim1606JoeKuoD7Init, - dim1607JoeKuoD7Init, - dim1608JoeKuoD7Init, - dim1609JoeKuoD7Init, - dim1610JoeKuoD7Init, - dim1611JoeKuoD7Init, - dim1612JoeKuoD7Init, - dim1613JoeKuoD7Init, - dim1614JoeKuoD7Init, - dim1615JoeKuoD7Init, - dim1616JoeKuoD7Init, - dim1617JoeKuoD7Init, - dim1618JoeKuoD7Init, - dim1619JoeKuoD7Init, - dim1620JoeKuoD7Init, - dim1621JoeKuoD7Init, - dim1622JoeKuoD7Init, - dim1623JoeKuoD7Init, - dim1624JoeKuoD7Init, - dim1625JoeKuoD7Init, - dim1626JoeKuoD7Init, - dim1627JoeKuoD7Init, - dim1628JoeKuoD7Init, - dim1629JoeKuoD7Init, - dim1630JoeKuoD7Init, - dim1631JoeKuoD7Init, - dim1632JoeKuoD7Init, - dim1633JoeKuoD7Init, - dim1634JoeKuoD7Init, - dim1635JoeKuoD7Init, - dim1636JoeKuoD7Init, - dim1637JoeKuoD7Init, - dim1638JoeKuoD7Init, - dim1639JoeKuoD7Init, - dim1640JoeKuoD7Init, - dim1641JoeKuoD7Init, - dim1642JoeKuoD7Init, - dim1643JoeKuoD7Init, - dim1644JoeKuoD7Init, - dim1645JoeKuoD7Init, - dim1646JoeKuoD7Init, - dim1647JoeKuoD7Init, - dim1648JoeKuoD7Init, - dim1649JoeKuoD7Init, - dim1650JoeKuoD7Init, - dim1651JoeKuoD7Init, - dim1652JoeKuoD7Init, - dim1653JoeKuoD7Init, - dim1654JoeKuoD7Init, - dim1655JoeKuoD7Init, - dim1656JoeKuoD7Init, - dim1657JoeKuoD7Init, - dim1658JoeKuoD7Init, - dim1659JoeKuoD7Init, - dim1660JoeKuoD7Init, - dim1661JoeKuoD7Init, - dim1662JoeKuoD7Init, - dim1663JoeKuoD7Init, - dim1664JoeKuoD7Init, - dim1665JoeKuoD7Init, - dim1666JoeKuoD7Init, - dim1667JoeKuoD7Init, - dim1668JoeKuoD7Init, - dim1669JoeKuoD7Init, - dim1670JoeKuoD7Init, - dim1671JoeKuoD7Init, - dim1672JoeKuoD7Init, - dim1673JoeKuoD7Init, - dim1674JoeKuoD7Init, - dim1675JoeKuoD7Init, - dim1676JoeKuoD7Init, - dim1677JoeKuoD7Init, - dim1678JoeKuoD7Init, - dim1679JoeKuoD7Init, - dim1680JoeKuoD7Init, - dim1681JoeKuoD7Init, - dim1682JoeKuoD7Init, - dim1683JoeKuoD7Init, - dim1684JoeKuoD7Init, - dim1685JoeKuoD7Init, - dim1686JoeKuoD7Init, - dim1687JoeKuoD7Init, - dim1688JoeKuoD7Init, - dim1689JoeKuoD7Init, - dim1690JoeKuoD7Init, - dim1691JoeKuoD7Init, - dim1692JoeKuoD7Init, - dim1693JoeKuoD7Init, - dim1694JoeKuoD7Init, - dim1695JoeKuoD7Init, - dim1696JoeKuoD7Init, - dim1697JoeKuoD7Init, - dim1698JoeKuoD7Init, - dim1699JoeKuoD7Init, - dim1700JoeKuoD7Init, - dim1701JoeKuoD7Init, - dim1702JoeKuoD7Init, - dim1703JoeKuoD7Init, - dim1704JoeKuoD7Init, - dim1705JoeKuoD7Init, - dim1706JoeKuoD7Init, - dim1707JoeKuoD7Init, - dim1708JoeKuoD7Init, - dim1709JoeKuoD7Init, - dim1710JoeKuoD7Init, - dim1711JoeKuoD7Init, - dim1712JoeKuoD7Init, - dim1713JoeKuoD7Init, - dim1714JoeKuoD7Init, - dim1715JoeKuoD7Init, - dim1716JoeKuoD7Init, - dim1717JoeKuoD7Init, - dim1718JoeKuoD7Init, - dim1719JoeKuoD7Init, - dim1720JoeKuoD7Init, - dim1721JoeKuoD7Init, - dim1722JoeKuoD7Init, - dim1723JoeKuoD7Init, - dim1724JoeKuoD7Init, - dim1725JoeKuoD7Init, - dim1726JoeKuoD7Init, - dim1727JoeKuoD7Init, - dim1728JoeKuoD7Init, - dim1729JoeKuoD7Init, - dim1730JoeKuoD7Init, - dim1731JoeKuoD7Init, - dim1732JoeKuoD7Init, - dim1733JoeKuoD7Init, - dim1734JoeKuoD7Init, - dim1735JoeKuoD7Init, - dim1736JoeKuoD7Init, - dim1737JoeKuoD7Init, - dim1738JoeKuoD7Init, - dim1739JoeKuoD7Init, - dim1740JoeKuoD7Init, - dim1741JoeKuoD7Init, - dim1742JoeKuoD7Init, - dim1743JoeKuoD7Init, - dim1744JoeKuoD7Init, - dim1745JoeKuoD7Init, - dim1746JoeKuoD7Init, - dim1747JoeKuoD7Init, - dim1748JoeKuoD7Init, - dim1749JoeKuoD7Init, - dim1750JoeKuoD7Init, - dim1751JoeKuoD7Init, - dim1752JoeKuoD7Init, - dim1753JoeKuoD7Init, - dim1754JoeKuoD7Init, - dim1755JoeKuoD7Init, - dim1756JoeKuoD7Init, - dim1757JoeKuoD7Init, - dim1758JoeKuoD7Init, - dim1759JoeKuoD7Init, - dim1760JoeKuoD7Init, - dim1761JoeKuoD7Init, - dim1762JoeKuoD7Init, - dim1763JoeKuoD7Init, - dim1764JoeKuoD7Init, - dim1765JoeKuoD7Init, - dim1766JoeKuoD7Init, - dim1767JoeKuoD7Init, - dim1768JoeKuoD7Init, - dim1769JoeKuoD7Init, - dim1770JoeKuoD7Init, - dim1771JoeKuoD7Init, - dim1772JoeKuoD7Init, - dim1773JoeKuoD7Init, - dim1774JoeKuoD7Init, - dim1775JoeKuoD7Init, - dim1776JoeKuoD7Init, - dim1777JoeKuoD7Init, - dim1778JoeKuoD7Init, - dim1779JoeKuoD7Init, - dim1780JoeKuoD7Init, - dim1781JoeKuoD7Init, - dim1782JoeKuoD7Init, - dim1783JoeKuoD7Init, - dim1784JoeKuoD7Init, - dim1785JoeKuoD7Init, - dim1786JoeKuoD7Init, - dim1787JoeKuoD7Init, - dim1788JoeKuoD7Init, - dim1789JoeKuoD7Init, - dim1790JoeKuoD7Init, - dim1791JoeKuoD7Init, - dim1792JoeKuoD7Init, - dim1793JoeKuoD7Init, - dim1794JoeKuoD7Init, - dim1795JoeKuoD7Init, - dim1796JoeKuoD7Init, - dim1797JoeKuoD7Init, - dim1798JoeKuoD7Init, - dim1799JoeKuoD7Init, - dim1800JoeKuoD7Init, - dim1801JoeKuoD7Init, - dim1802JoeKuoD7Init, - dim1803JoeKuoD7Init, - dim1804JoeKuoD7Init, - dim1805JoeKuoD7Init, - dim1806JoeKuoD7Init, - dim1807JoeKuoD7Init, - dim1808JoeKuoD7Init, - dim1809JoeKuoD7Init, - dim1810JoeKuoD7Init, - dim1811JoeKuoD7Init, - dim1812JoeKuoD7Init, - dim1813JoeKuoD7Init, - dim1814JoeKuoD7Init, - dim1815JoeKuoD7Init, - dim1816JoeKuoD7Init, - dim1817JoeKuoD7Init, - dim1818JoeKuoD7Init, - dim1819JoeKuoD7Init, - dim1820JoeKuoD7Init, - dim1821JoeKuoD7Init, - dim1822JoeKuoD7Init, - dim1823JoeKuoD7Init, - dim1824JoeKuoD7Init, - dim1825JoeKuoD7Init, - dim1826JoeKuoD7Init, - dim1827JoeKuoD7Init, - dim1828JoeKuoD7Init, - dim1829JoeKuoD7Init, - dim1830JoeKuoD7Init, - dim1831JoeKuoD7Init, - dim1832JoeKuoD7Init, - dim1833JoeKuoD7Init, - dim1834JoeKuoD7Init, - dim1835JoeKuoD7Init, - dim1836JoeKuoD7Init, - dim1837JoeKuoD7Init, - dim1838JoeKuoD7Init, - dim1839JoeKuoD7Init, - dim1840JoeKuoD7Init, - dim1841JoeKuoD7Init, - dim1842JoeKuoD7Init, - dim1843JoeKuoD7Init, - dim1844JoeKuoD7Init, - dim1845JoeKuoD7Init, - dim1846JoeKuoD7Init, - dim1847JoeKuoD7Init, - dim1848JoeKuoD7Init, - dim1849JoeKuoD7Init, - dim1850JoeKuoD7Init, - dim1851JoeKuoD7Init, - dim1852JoeKuoD7Init, - dim1853JoeKuoD7Init, - dim1854JoeKuoD7Init, - dim1855JoeKuoD7Init, - dim1856JoeKuoD7Init, - dim1857JoeKuoD7Init, - dim1858JoeKuoD7Init, - dim1859JoeKuoD7Init, - dim1860JoeKuoD7Init, - dim1861JoeKuoD7Init, - dim1862JoeKuoD7Init, - dim1863JoeKuoD7Init, - dim1864JoeKuoD7Init, - dim1865JoeKuoD7Init, - dim1866JoeKuoD7Init, - dim1867JoeKuoD7Init, - dim1868JoeKuoD7Init, - dim1869JoeKuoD7Init, - dim1870JoeKuoD7Init, - dim1871JoeKuoD7Init, - dim1872JoeKuoD7Init, - dim1873JoeKuoD7Init, - dim1874JoeKuoD7Init, - dim1875JoeKuoD7Init, - dim1876JoeKuoD7Init, - dim1877JoeKuoD7Init, - dim1878JoeKuoD7Init, - dim1879JoeKuoD7Init, - dim1880JoeKuoD7Init, - dim1881JoeKuoD7Init, - dim1882JoeKuoD7Init, - dim1883JoeKuoD7Init, - dim1884JoeKuoD7Init, - dim1885JoeKuoD7Init, - dim1886JoeKuoD7Init, - dim1887JoeKuoD7Init, - dim1888JoeKuoD7Init, - dim1889JoeKuoD7Init, - dim1890JoeKuoD7Init, - dim1891JoeKuoD7Init, - dim1892JoeKuoD7Init, - dim1893JoeKuoD7Init, - dim1894JoeKuoD7Init, - dim1895JoeKuoD7Init, - dim1896JoeKuoD7Init, - dim1897JoeKuoD7Init, - dim1898JoeKuoD7Init, - dim1899JoeKuoD7Init - }; - - static ulong[] dim1JoeKuoD5Init = { 1, 0 }; - static ulong[] dim2JoeKuoD5Init = { 1, 3, 0 }; - static ulong[] dim3JoeKuoD5Init = { 1, 3, 1, 0 }; - static ulong[] dim4JoeKuoD5Init = { 1, 1, 1, 0 }; - static ulong[] dim5JoeKuoD5Init = { 1, 1, 3, 3, 0 }; - static ulong[] dim6JoeKuoD5Init = { 1, 3, 5, 13, 0 }; - static ulong[] dim7JoeKuoD5Init = { 1, 1, 5, 5, 17, 0 }; - static ulong[] dim8JoeKuoD5Init = { 1, 1, 5, 5, 5, 0 }; - static ulong[] dim9JoeKuoD5Init = { 1, 1, 7, 11, 19, 0 }; - static ulong[] dim10JoeKuoD5Init = { 1, 1, 5, 1, 1, 0 }; - static ulong[] dim11JoeKuoD5Init = { 1, 3, 7, 1, 19, 0 }; - static ulong[] dim12JoeKuoD5Init = { 1, 3, 3, 5, 7, 0 }; - static ulong[] dim13JoeKuoD5Init = { 1, 3, 3, 13, 9, 53, 0 }; - static ulong[] dim14JoeKuoD5Init = { 1, 1, 5, 11, 1, 1, 0 }; - static ulong[] dim15JoeKuoD5Init = { 1, 1, 3, 7, 21, 51, 0 }; - static ulong[] dim16JoeKuoD5Init = { 1, 1, 1, 15, 1, 5, 0 }; - static ulong[] dim17JoeKuoD5Init = { 1, 3, 1, 9, 9, 1, 0 }; - static ulong[] dim18JoeKuoD5Init = { 1, 1, 5, 5, 17, 61, 0 }; - static ulong[] dim19JoeKuoD5Init = { 1, 3, 1, 15, 29, 57, 87, 0 }; - static ulong[] dim20JoeKuoD5Init = { 1, 3, 5, 15, 3, 11, 17, 0 }; - static ulong[] dim21JoeKuoD5Init = { 1, 3, 3, 7, 5, 17, 65, 0 }; - static ulong[] dim22JoeKuoD5Init = { 1, 3, 5, 1, 25, 29, 49, 0 }; - static ulong[] dim23JoeKuoD5Init = { 1, 1, 3, 7, 15, 39, 119, 0 }; - static ulong[] dim24JoeKuoD5Init = { 1, 3, 3, 5, 19, 51, 61, 0 }; - static ulong[] dim25JoeKuoD5Init = { 1, 1, 5, 15, 11, 47, 15, 0 }; - static ulong[] dim26JoeKuoD5Init = { 1, 1, 7, 3, 29, 51, 51, 0 }; - static ulong[] dim27JoeKuoD5Init = { 1, 1, 3, 15, 19, 17, 13, 0 }; - static ulong[] dim28JoeKuoD5Init = { 1, 3, 7, 3, 17, 9, 93, 0 }; - static ulong[] dim29JoeKuoD5Init = { 1, 3, 7, 5, 7, 29, 111, 0 }; - static ulong[] dim30JoeKuoD5Init = { 1, 1, 7, 9, 25, 19, 105, 0 }; - static ulong[] dim31JoeKuoD5Init = { 1, 1, 1, 11, 21, 35, 107, 0 }; - static ulong[] dim32JoeKuoD5Init = { 1, 1, 5, 11, 19, 53, 25, 0 }; - static ulong[] dim33JoeKuoD5Init = { 1, 3, 1, 3, 27, 29, 31, 0 }; - static ulong[] dim34JoeKuoD5Init = { 1, 1, 5, 13, 27, 19, 61, 0 }; - static ulong[] dim35JoeKuoD5Init = { 1, 3, 1, 3, 25, 33, 105, 0 }; - static ulong[] dim36JoeKuoD5Init = { 1, 3, 7, 11, 27, 55, 1, 0 }; - static ulong[] dim37JoeKuoD5Init = { 1, 1, 7, 1, 9, 45, 97, 63, 0 }; - static ulong[] dim38JoeKuoD5Init = { 1, 1, 7, 9, 3, 17, 85, 213, 0 }; - static ulong[] dim39JoeKuoD5Init = { 1, 1, 1, 3, 31, 35, 93, 35, 0 }; - static ulong[] dim40JoeKuoD5Init = { 1, 3, 5, 9, 1, 63, 117, 35, 0 }; - static ulong[] dim41JoeKuoD5Init = { 1, 3, 1, 9, 21, 3, 53, 29, 0 }; - static ulong[] dim42JoeKuoD5Init = { 1, 3, 1, 9, 29, 33, 43, 181, 0 }; - static ulong[] dim43JoeKuoD5Init = { 1, 3, 7, 3, 21, 45, 121, 141, 0 }; - static ulong[] dim44JoeKuoD5Init = { 1, 1, 1, 13, 5, 49, 45, 77, 0 }; - static ulong[] dim45JoeKuoD5Init = { 1, 1, 3, 3, 1, 47, 37, 151, 0 }; - static ulong[] dim46JoeKuoD5Init = { 1, 3, 7, 5, 9, 51, 61, 95, 0 }; - static ulong[] dim47JoeKuoD5Init = { 1, 1, 1, 7, 31, 23, 81, 105, 0 }; - static ulong[] dim48JoeKuoD5Init = { 1, 3, 5, 15, 15, 9, 115, 55, 0 }; - static ulong[] dim49JoeKuoD5Init = { 1, 3, 3, 13, 15, 1, 87, 11, 0 }; - static ulong[] dim50JoeKuoD5Init = { 1, 3, 5, 1, 5, 9, 29, 241, 0 }; - static ulong[] dim51JoeKuoD5Init = { 1, 1, 1, 9, 19, 5, 115, 191, 0 }; - static ulong[] dim52JoeKuoD5Init = { 1, 1, 1, 15, 1, 57, 107, 49, 0 }; - static ulong[] dim53JoeKuoD5Init = { 1, 1, 7, 7, 23, 21, 71, 187, 207, 0 }; - static ulong[] dim54JoeKuoD5Init = { 1, 3, 3, 5, 11, 35, 101, 7, 501, 0 }; - static ulong[] dim55JoeKuoD5Init = { 1, 3, 5, 15, 29, 5, 61, 205, 301, 0 }; - static ulong[] dim56JoeKuoD5Init = { 1, 1, 7, 13, 7, 39, 127, 243, 307, 0 }; - static ulong[] dim57JoeKuoD5Init = { 1, 3, 7, 13, 29, 9, 93, 187, 429, 0 }; - static ulong[] dim58JoeKuoD5Init = { 1, 3, 3, 11, 15, 35, 85, 159, 223, 0 }; - static ulong[] dim59JoeKuoD5Init = { 1, 1, 3, 1, 13, 3, 111, 17, 411, 0 }; - static ulong[] dim60JoeKuoD5Init = { 1, 1, 1, 7, 31, 21, 103, 175, 97, 0 }; - static ulong[] dim61JoeKuoD5Init = { 1, 1, 1, 15, 11, 21, 63, 45, 29, 0 }; - static ulong[] dim62JoeKuoD5Init = { 1, 3, 5, 3, 13, 45, 53, 191, 455, 0 }; - static ulong[] dim63JoeKuoD5Init = { 1, 3, 3, 13, 11, 37, 65, 45, 371, 0 }; - static ulong[] dim64JoeKuoD5Init = { 1, 1, 1, 15, 23, 9, 123, 97, 497, 0 }; - static ulong[] dim65JoeKuoD5Init = { 1, 1, 7, 7, 5, 13, 33, 169, 411, 0 }; - static ulong[] dim66JoeKuoD5Init = { 1, 1, 3, 13, 29, 61, 67, 1, 167, 0 }; - static ulong[] dim67JoeKuoD5Init = { 1, 1, 7, 3, 11, 21, 25, 87, 507, 0 }; - static ulong[] dim68JoeKuoD5Init = { 1, 3, 1, 9, 31, 37, 3, 89, 113, 0 }; - static ulong[] dim69JoeKuoD5Init = { 1, 1, 5, 11, 5, 11, 83, 85, 421, 0 }; - static ulong[] dim70JoeKuoD5Init = { 1, 3, 5, 7, 23, 9, 111, 135, 337, 0 }; - static ulong[] dim71JoeKuoD5Init = { 1, 3, 5, 15, 3, 39, 81, 249, 363, 0 }; - static ulong[] dim72JoeKuoD5Init = { 1, 1, 7, 15, 9, 49, 79, 103, 19, 0 }; - static ulong[] dim73JoeKuoD5Init = { 1, 3, 1, 1, 17, 31, 45, 205, 381, 0 }; - static ulong[] dim74JoeKuoD5Init = { 1, 1, 1, 1, 11, 45, 89, 1, 365, 0 }; - static ulong[] dim75JoeKuoD5Init = { 1, 1, 1, 15, 7, 63, 55, 185, 373, 0 }; - static ulong[] dim76JoeKuoD5Init = { 1, 1, 1, 3, 17, 19, 23, 7, 265, 0 }; - static ulong[] dim77JoeKuoD5Init = { 1, 1, 3, 15, 13, 31, 53, 235, 309, 0 }; - static ulong[] dim78JoeKuoD5Init = { 1, 3, 1, 5, 1, 63, 73, 155, 33, 0 }; - static ulong[] dim79JoeKuoD5Init = { 1, 1, 1, 15, 19, 57, 21, 45, 203, 0 }; - static ulong[] dim80JoeKuoD5Init = { 1, 3, 5, 9, 13, 27, 55, 215, 181, 0 }; - static ulong[] dim81JoeKuoD5Init = { 1, 1, 7, 3, 11, 39, 55, 219, 401, 0 }; - static ulong[] dim82JoeKuoD5Init = { 1, 1, 1, 7, 9, 13, 3, 181, 395, 0 }; - static ulong[] dim83JoeKuoD5Init = { 1, 3, 1, 15, 13, 19, 23, 145, 97, 0 }; - static ulong[] dim84JoeKuoD5Init = { 1, 1, 1, 15, 23, 15, 55, 3, 243, 0 }; - static ulong[] dim85JoeKuoD5Init = { 1, 1, 3, 15, 15, 5, 115, 169, 415, 0 }; - static ulong[] dim86JoeKuoD5Init = { 1, 1, 7, 15, 31, 15, 119, 89, 37, 0 }; - static ulong[] dim87JoeKuoD5Init = { 1, 1, 5, 3, 25, 23, 23, 133, 467, 0 }; - static ulong[] dim88JoeKuoD5Init = { 1, 3, 5, 15, 11, 7, 73, 209, 331, 0 }; - static ulong[] dim89JoeKuoD5Init = { 1, 3, 7, 11, 29, 51, 119, 105, 63, 0 }; - static ulong[] dim90JoeKuoD5Init = { 1, 1, 5, 9, 19, 21, 53, 211, 231, 0 }; - static ulong[] dim91JoeKuoD5Init = { 1, 3, 5, 1, 7, 23, 27, 67, 445, 0 }; - static ulong[] dim92JoeKuoD5Init = { 1, 1, 5, 15, 21, 53, 117, 229, 13, 0 }; - static ulong[] dim93JoeKuoD5Init = { 1, 3, 5, 11, 19, 55, 53, 13, 349, 0 }; - static ulong[] dim94JoeKuoD5Init = { 1, 3, 1, 9, 19, 25, 79, 55, 355, 0 }; - static ulong[] dim95JoeKuoD5Init = { 1, 3, 3, 5, 31, 27, 105, 63, 21, 0 }; - static ulong[] dim96JoeKuoD5Init = { 1, 3, 3, 15, 13, 37, 39, 13, 459, 0 }; - static ulong[] dim97JoeKuoD5Init = { 1, 1, 1, 7, 25, 61, 93, 195, 441, 0 }; - static ulong[] dim98JoeKuoD5Init = { 1, 3, 3, 3, 7, 35, 55, 103, 159, 0 }; - static ulong[] dim99JoeKuoD5Init = { 1, 1, 7, 11, 7, 33, 49, 113, 331, 0 }; - static ulong[] dim100JoeKuoD5Init = { 1, 3, 1, 1, 1, 31, 35, 63, 465, 0 }; - static ulong[] dim101JoeKuoD5Init = { 1, 3, 5, 1, 13, 43, 83, 177, 461, 747, 0 }; - static ulong[] dim102JoeKuoD5Init = { 1, 3, 7, 3, 21, 5, 19, 135, 483, 181, 0 }; - static ulong[] dim103JoeKuoD5Init = { 1, 3, 1, 9, 25, 3, 37, 147, 483, 743, 0 }; - static ulong[] dim104JoeKuoD5Init = { 1, 1, 5, 3, 1, 1, 101, 163, 165, 957, 0 }; - static ulong[] dim105JoeKuoD5Init = { 1, 3, 5, 1, 15, 41, 117, 7, 71, 357, 0 }; - static ulong[] dim106JoeKuoD5Init = { 1, 3, 5, 9, 27, 11, 55, 5, 11, 863, 0 }; - static ulong[] dim107JoeKuoD5Init = { 1, 1, 1, 1, 27, 43, 51, 211, 265, 403, 0 }; - static ulong[] dim108JoeKuoD5Init = { 1, 1, 7, 3, 31, 35, 61, 43, 223, 441, 0 }; - static ulong[] dim109JoeKuoD5Init = { 1, 3, 1, 7, 19, 61, 59, 63, 401, 767, 0 }; - static ulong[] dim110JoeKuoD5Init = { 1, 3, 1, 9, 23, 39, 83, 249, 129, 843, 0 }; - static ulong[] dim111JoeKuoD5Init = { 1, 3, 7, 13, 1, 49, 61, 115, 289, 85, 0 }; - static ulong[] dim112JoeKuoD5Init = { 1, 1, 5, 13, 7, 17, 35, 95, 235, 49, 0 }; - static ulong[] dim113JoeKuoD5Init = { 1, 3, 3, 11, 9, 9, 91, 141, 305, 955, 0 }; - static ulong[] dim114JoeKuoD5Init = { 1, 3, 7, 11, 17, 3, 77, 95, 507, 627, 0 }; - static ulong[] dim115JoeKuoD5Init = { 1, 3, 7, 1, 31, 43, 31, 217, 67, 853, 0 }; - static ulong[] dim116JoeKuoD5Init = { 1, 1, 7, 15, 17, 33, 31, 91, 465, 209, 0 }; - static ulong[] dim117JoeKuoD5Init = { 1, 1, 7, 7, 31, 41, 101, 95, 431, 203, 0 }; - static ulong[] dim118JoeKuoD5Init = { 1, 3, 7, 1, 23, 45, 123, 111, 457, 655, 0 }; - static ulong[] dim119JoeKuoD5Init = { 1, 3, 3, 5, 9, 27, 37, 195, 11, 99, 0 }; - static ulong[] dim120JoeKuoD5Init = { 1, 1, 3, 9, 7, 39, 81, 171, 97, 775, 0 }; - static ulong[] dim121JoeKuoD5Init = { 1, 1, 1, 3, 3, 27, 93, 149, 321, 537, 0 }; - static ulong[] dim122JoeKuoD5Init = { 1, 3, 1, 3, 13, 3, 59, 137, 505, 395, 0 }; - static ulong[] dim123JoeKuoD5Init = { 1, 1, 1, 11, 15, 53, 77, 235, 439, 829, 0 }; - static ulong[] dim124JoeKuoD5Init = { 1, 3, 3, 1, 25, 61, 65, 53, 207, 891, 0 }; - static ulong[] dim125JoeKuoD5Init = { 1, 3, 3, 15, 29, 39, 67, 203, 495, 795, 0 }; - static ulong[] dim126JoeKuoD5Init = { 1, 3, 7, 1, 15, 17, 119, 83, 411, 1015, 0 }; - static ulong[] dim127JoeKuoD5Init = { 1, 1, 7, 1, 13, 37, 69, 147, 141, 229, 0 }; - static ulong[] dim128JoeKuoD5Init = { 1, 3, 5, 1, 11, 31, 73, 99, 133, 45, 0 }; - static ulong[] dim129JoeKuoD5Init = { 1, 1, 5, 11, 31, 49, 51, 45, 27, 415, 0 }; - static ulong[] dim130JoeKuoD5Init = { 1, 3, 1, 11, 23, 19, 85, 17, 41, 625, 0 }; - static ulong[] dim131JoeKuoD5Init = { 1, 3, 5, 9, 3, 37, 9, 57, 59, 383, 0 }; - static ulong[] dim132JoeKuoD5Init = { 1, 3, 7, 3, 19, 53, 11, 215, 391, 51, 0 }; - static ulong[] dim133JoeKuoD5Init = { 1, 3, 7, 15, 17, 1, 53, 89, 291, 91, 0 }; - static ulong[] dim134JoeKuoD5Init = { 1, 3, 5, 1, 5, 33, 69, 29, 281, 13, 0 }; - static ulong[] dim135JoeKuoD5Init = { 1, 1, 3, 15, 21, 61, 61, 69, 395, 785, 0 }; - static ulong[] dim136JoeKuoD5Init = { 1, 1, 7, 7, 25, 51, 27, 11, 375, 865, 0 }; - static ulong[] dim137JoeKuoD5Init = { 1, 1, 3, 1, 11, 47, 45, 85, 507, 11, 0 }; - static ulong[] dim138JoeKuoD5Init = { 1, 3, 5, 5, 17, 53, 101, 57, 213, 795, 0 }; - static ulong[] dim139JoeKuoD5Init = { 1, 1, 7, 7, 15, 19, 117, 213, 397, 343, 0 }; - static ulong[] dim140JoeKuoD5Init = { 1, 3, 3, 7, 9, 19, 27, 23, 205, 707, 0 }; - static ulong[] dim141JoeKuoD5Init = { 1, 3, 1, 13, 11, 51, 1, 3, 63, 483, 0 }; - static ulong[] dim142JoeKuoD5Init = { 1, 1, 7, 13, 27, 49, 97, 247, 273, 785, 0 }; - static ulong[] dim143JoeKuoD5Init = { 1, 3, 1, 15, 31, 3, 43, 199, 81, 317, 0 }; - static ulong[] dim144JoeKuoD5Init = { 1, 3, 5, 15, 17, 3, 101, 13, 131, 631, 0 }; - static ulong[] dim145JoeKuoD5Init = { 1, 3, 5, 1, 25, 23, 17, 145, 247, 889, 0 }; - static ulong[] dim146JoeKuoD5Init = { 1, 1, 7, 7, 17, 5, 11, 133, 19, 507, 0 }; - static ulong[] dim147JoeKuoD5Init = { 1, 3, 1, 7, 31, 53, 39, 107, 183, 335, 0 }; - static ulong[] dim148JoeKuoD5Init = { 1, 3, 7, 15, 3, 19, 39, 155, 477, 833, 0 }; - static ulong[] dim149JoeKuoD5Init = { 1, 1, 1, 9, 31, 7, 5, 5, 399, 831, 0 }; - static ulong[] dim150JoeKuoD5Init = { 1, 1, 3, 1, 19, 37, 89, 243, 131, 901, 0 }; - static ulong[] dim151JoeKuoD5Init = { 1, 1, 3, 13, 23, 3, 127, 213, 97, 325, 0 }; - static ulong[] dim152JoeKuoD5Init = { 1, 1, 7, 9, 23, 27, 7, 161, 307, 451, 0 }; - static ulong[] dim153JoeKuoD5Init = { 1, 1, 5, 1, 5, 25, 23, 103, 59, 431, 0 }; - static ulong[] dim154JoeKuoD5Init = { 1, 1, 3, 7, 3, 43, 121, 117, 33, 231, 0 }; - static ulong[] dim155JoeKuoD5Init = { 1, 3, 7, 7, 11, 61, 73, 231, 225, 97, 0 }; - static ulong[] dim156JoeKuoD5Init = { 1, 1, 5, 11, 1, 9, 61, 3, 407, 425, 0 }; - static ulong[] dim157JoeKuoD5Init = { 1, 3, 3, 7, 1, 25, 95, 161, 387, 379, 0 }; - static ulong[] dim158JoeKuoD5Init = { 1, 3, 1, 1, 15, 53, 55, 107, 425, 629, 0 }; - static ulong[] dim159JoeKuoD5Init = { 1, 3, 7, 11, 31, 59, 97, 99, 339, 417, 0 }; - static ulong[] dim160JoeKuoD5Init = { 1, 3, 1, 9, 9, 5, 7, 157, 401, 155, 0 }; - static ulong[] dim161JoeKuoD5Init = { 1, 3, 1, 7, 31, 15, 37, 253, 93, 149, 1255, 0 }; - static ulong[] dim162JoeKuoD5Init = { 1, 1, 1, 9, 11, 61, 65, 71, 53, 929, 1153, 0 }; - static ulong[] dim163JoeKuoD5Init = { 1, 1, 7, 15, 13, 25, 93, 55, 55, 923, 601, 0 }; - static ulong[] dim164JoeKuoD5Init = { 1, 1, 7, 7, 21, 43, 71, 115, 253, 953, 1455, 0 }; - static ulong[] dim165JoeKuoD5Init = { 1, 3, 5, 7, 3, 31, 115, 213, 39, 589, 1029, 0 }; - static ulong[] dim166JoeKuoD5Init = { 1, 3, 5, 1, 7, 59, 31, 87, 233, 75, 365, 0 }; - static ulong[] dim167JoeKuoD5Init = { 1, 1, 1, 15, 13, 27, 55, 117, 327, 465, 1735, 0 }; - static ulong[] dim168JoeKuoD5Init = { 1, 3, 5, 9, 25, 9, 125, 247, 81, 437, 483, 0 }; - static ulong[] dim169JoeKuoD5Init = { 1, 3, 5, 15, 27, 39, 27, 57, 45, 263, 281, 0 }; - static ulong[] dim170JoeKuoD5Init = { 1, 3, 1, 5, 29, 5, 73, 231, 97, 773, 1349, 0 }; - static ulong[] dim171JoeKuoD5Init = { 1, 3, 5, 5, 25, 27, 81, 87, 91, 169, 235, 0 }; - static ulong[] dim172JoeKuoD5Init = { 1, 3, 1, 11, 19, 61, 17, 175, 253, 673, 175, 0 }; - static ulong[] dim173JoeKuoD5Init = { 1, 1, 7, 7, 17, 43, 65, 245, 125, 137, 1475, 0 }; - static ulong[] dim174JoeKuoD5Init = { 1, 1, 7, 5, 15, 57, 39, 151, 197, 529, 393, 0 }; - static ulong[] dim175JoeKuoD5Init = { 1, 3, 3, 3, 29, 41, 93, 47, 375, 729, 709, 0 }; - static ulong[] dim176JoeKuoD5Init = { 1, 1, 7, 9, 13, 35, 49, 197, 107, 381, 1531, 0 }; - static ulong[] dim177JoeKuoD5Init = { 1, 1, 5, 9, 15, 35, 105, 105, 259, 201, 317, 0 }; - static ulong[] dim178JoeKuoD5Init = { 1, 1, 7, 15, 13, 23, 89, 203, 335, 1003, 107, 0 }; - static ulong[] dim179JoeKuoD5Init = { 1, 3, 7, 15, 25, 25, 7, 145, 213, 845, 949, 0 }; - static ulong[] dim180JoeKuoD5Init = { 1, 1, 5, 1, 23, 11, 101, 59, 57, 261, 1627, 0 }; - static ulong[] dim181JoeKuoD5Init = { 1, 3, 5, 11, 23, 63, 43, 137, 49, 249, 1369, 0 }; - static ulong[] dim182JoeKuoD5Init = { 1, 1, 7, 13, 25, 3, 81, 157, 511, 725, 2027, 0 }; - static ulong[] dim183JoeKuoD5Init = { 1, 1, 7, 7, 5, 37, 33, 7, 287, 307, 147, 0 }; - static ulong[] dim184JoeKuoD5Init = { 1, 3, 7, 5, 27, 19, 93, 173, 145, 821, 139, 0 }; - static ulong[] dim185JoeKuoD5Init = { 1, 1, 1, 15, 23, 61, 123, 85, 375, 699, 229, 0 }; - static ulong[] dim186JoeKuoD5Init = { 1, 1, 3, 3, 25, 21, 127, 53, 247, 1005, 831, 0 }; - static ulong[] dim187JoeKuoD5Init = { 1, 1, 5, 7, 25, 39, 27, 247, 319, 659, 1453, 0 }; - static ulong[] dim188JoeKuoD5Init = { 1, 1, 3, 11, 31, 45, 67, 195, 11, 481, 83, 0 }; - static ulong[] dim189JoeKuoD5Init = { 1, 1, 5, 13, 27, 61, 5, 173, 353, 733, 1189, 0 }; - static ulong[] dim190JoeKuoD5Init = { 1, 3, 7, 7, 23, 49, 119, 145, 285, 873, 641, 0 }; - static ulong[] dim191JoeKuoD5Init = { 1, 3, 3, 9, 1, 17, 119, 121, 203, 483, 1601, 0 }; - static ulong[] dim192JoeKuoD5Init = { 1, 3, 1, 11, 21, 35, 121, 11, 213, 93, 77, 0 }; - static ulong[] dim193JoeKuoD5Init = { 1, 1, 3, 7, 7, 5, 27, 153, 223, 831, 679, 0 }; - static ulong[] dim194JoeKuoD5Init = { 1, 3, 3, 5, 1, 39, 39, 233, 483, 667, 1367, 0 }; - static ulong[] dim195JoeKuoD5Init = { 1, 1, 3, 13, 19, 51, 21, 209, 381, 787, 1451, 0 }; - static ulong[] dim196JoeKuoD5Init = { 1, 1, 7, 3, 15, 9, 29, 225, 225, 389, 1075, 0 }; - static ulong[] dim197JoeKuoD5Init = { 1, 1, 3, 5, 13, 57, 55, 229, 279, 1019, 1491, 0 }; - static ulong[] dim198JoeKuoD5Init = { 1, 3, 3, 9, 19, 19, 35, 15, 335, 685, 1987, 0 }; - static ulong[] dim199JoeKuoD5Init = { 1, 3, 7, 11, 1, 5, 3, 29, 19, 363, 247, 0 }; - static ulong[] dim200JoeKuoD5Init = { 1, 1, 5, 11, 13, 17, 17, 253, 365, 397, 1643, 0 }; - static ulong[] dim201JoeKuoD5Init = { 1, 3, 3, 15, 25, 23, 81, 243, 343, 441, 1675, 0 }; - static ulong[] dim202JoeKuoD5Init = { 1, 3, 5, 11, 15, 51, 23, 213, 235, 997, 1205, 0 }; - static ulong[] dim203JoeKuoD5Init = { 1, 1, 7, 7, 5, 39, 99, 165, 331, 795, 803, 0 }; - static ulong[] dim204JoeKuoD5Init = { 1, 3, 7, 13, 31, 63, 109, 171, 151, 269, 581, 0 }; - static ulong[] dim205JoeKuoD5Init = { 1, 3, 1, 7, 25, 13, 41, 75, 411, 425, 267, 0 }; - static ulong[] dim206JoeKuoD5Init = { 1, 1, 3, 7, 1, 31, 49, 113, 473, 677, 395, 0 }; - static ulong[] dim207JoeKuoD5Init = { 1, 3, 3, 5, 23, 43, 111, 171, 489, 949, 1681, 0 }; - static ulong[] dim208JoeKuoD5Init = { 1, 3, 1, 5, 5, 37, 67, 23, 115, 909, 853, 0 }; - static ulong[] dim209JoeKuoD5Init = { 1, 1, 3, 3, 27, 35, 63, 45, 481, 571, 793, 0 }; - static ulong[] dim210JoeKuoD5Init = { 1, 1, 3, 15, 11, 45, 53, 225, 147, 935, 1189, 0 }; - static ulong[] dim211JoeKuoD5Init = { 1, 1, 1, 5, 15, 17, 77, 59, 169, 831, 163, 0 }; - static ulong[] dim212JoeKuoD5Init = { 1, 3, 7, 15, 7, 29, 85, 19, 313, 35, 401, 0 }; - static ulong[] dim213JoeKuoD5Init = { 1, 1, 3, 13, 3, 1, 45, 139, 17, 847, 1309, 0 }; - static ulong[] dim214JoeKuoD5Init = { 1, 1, 3, 3, 25, 1, 117, 185, 291, 251, 1049, 0 }; - static ulong[] dim215JoeKuoD5Init = { 1, 3, 3, 1, 27, 63, 33, 161, 181, 79, 667, 0 }; - static ulong[] dim216JoeKuoD5Init = { 1, 3, 1, 11, 9, 63, 91, 207, 329, 3, 1155, 0 }; - static ulong[] dim217JoeKuoD5Init = { 1, 1, 1, 5, 3, 59, 39, 37, 231, 993, 1147, 0 }; - static ulong[] dim218JoeKuoD5Init = { 1, 3, 1, 3, 7, 41, 85, 223, 407, 403, 573, 0 }; - static ulong[] dim219JoeKuoD5Init = { 1, 3, 7, 3, 15, 51, 1, 191, 123, 103, 1201, 0 }; - static ulong[] dim220JoeKuoD5Init = { 1, 1, 5, 3, 31, 9, 83, 231, 419, 109, 1455, 0 }; - static ulong[] dim221JoeKuoD5Init = { 1, 3, 3, 11, 13, 39, 89, 9, 237, 185, 1113, 0 }; - static ulong[] dim222JoeKuoD5Init = { 1, 1, 7, 9, 1, 43, 121, 241, 165, 263, 1205, 0 }; - static ulong[] dim223JoeKuoD5Init = { 1, 1, 1, 3, 21, 3, 61, 219, 49, 733, 25, 0 }; - static ulong[] dim224JoeKuoD5Init = { 1, 3, 1, 7, 31, 27, 121, 61, 447, 401, 529, 0 }; - static ulong[] dim225JoeKuoD5Init = { 1, 1, 7, 11, 27, 47, 85, 5, 305, 763, 1255, 0 }; - static ulong[] dim226JoeKuoD5Init = { 1, 1, 1, 9, 13, 41, 9, 51, 195, 103, 983, 0 }; - static ulong[] dim227JoeKuoD5Init = { 1, 1, 1, 15, 1, 27, 65, 91, 61, 591, 2039, 0 }; - static ulong[] dim228JoeKuoD5Init = { 1, 1, 1, 1, 15, 19, 107, 197, 121, 879, 771, 0 }; - static ulong[] dim229JoeKuoD5Init = { 1, 3, 7, 7, 19, 53, 9, 3, 67, 893, 1817, 0 }; - static ulong[] dim230JoeKuoD5Init = { 1, 3, 3, 9, 11, 63, 53, 247, 65, 681, 1721, 0 }; - static ulong[] dim231JoeKuoD5Init = { 1, 1, 3, 3, 25, 47, 91, 55, 471, 731, 939, 0 }; - static ulong[] dim232JoeKuoD5Init = { 1, 3, 5, 9, 7, 45, 121, 69, 423, 599, 2027, 0 }; - static ulong[] dim233JoeKuoD5Init = { 1, 1, 3, 11, 23, 7, 43, 179, 511, 571, 1707, 0 }; - static ulong[] dim234JoeKuoD5Init = { 1, 1, 7, 9, 17, 11, 69, 13, 303, 299, 653, 0 }; - static ulong[] dim235JoeKuoD5Init = { 1, 1, 1, 7, 7, 29, 69, 237, 237, 425, 1413, 0 }; - static ulong[] dim236JoeKuoD5Init = { 1, 3, 7, 3, 19, 31, 55, 55, 225, 943, 1027, 0 }; - static ulong[] dim237JoeKuoD5Init = { 1, 1, 5, 7, 25, 9, 9, 29, 485, 885, 1229, 0 }; - static ulong[] dim238JoeKuoD5Init = { 1, 3, 3, 9, 7, 11, 73, 151, 17, 669, 773, 0 }; - static ulong[] dim239JoeKuoD5Init = { 1, 1, 5, 13, 25, 13, 51, 53, 411, 555, 795, 0 }; - static ulong[] dim240JoeKuoD5Init = { 1, 3, 3, 9, 21, 33, 7, 113, 325, 593, 1647, 0 }; - static ulong[] dim241JoeKuoD5Init = { 1, 3, 5, 15, 3, 13, 83, 205, 153, 7, 1181, 0 }; - static ulong[] dim242JoeKuoD5Init = { 1, 1, 5, 5, 1, 55, 91, 17, 383, 453, 1749, 0 }; - static ulong[] dim243JoeKuoD5Init = { 1, 3, 3, 1, 5, 13, 91, 19, 241, 569, 291, 0 }; - static ulong[] dim244JoeKuoD5Init = { 1, 1, 1, 9, 13, 19, 109, 195, 17, 203, 473, 0 }; - static ulong[] dim245JoeKuoD5Init = { 1, 1, 1, 11, 17, 17, 43, 201, 297, 159, 685, 0 }; - static ulong[] dim246JoeKuoD5Init = { 1, 3, 5, 15, 15, 33, 91, 53, 337, 237, 1063, 0 }; - static ulong[] dim247JoeKuoD5Init = { 1, 3, 3, 9, 13, 15, 59, 115, 457, 169, 29, 0 }; - static ulong[] dim248JoeKuoD5Init = { 1, 1, 1, 7, 21, 51, 41, 49, 467, 171, 301, 0 }; - static ulong[] dim249JoeKuoD5Init = { 1, 3, 7, 5, 19, 57, 27, 57, 119, 183, 1519, 0 }; - static ulong[] dim250JoeKuoD5Init = { 1, 1, 1, 9, 19, 21, 117, 35, 43, 829, 1817, 0 }; - static ulong[] dim251JoeKuoD5Init = { 1, 3, 1, 7, 9, 27, 127, 233, 229, 467, 2033, 0 }; - static ulong[] dim252JoeKuoD5Init = { 1, 3, 1, 1, 7, 21, 113, 23, 15, 43, 375, 0 }; - static ulong[] dim253JoeKuoD5Init = { 1, 3, 7, 3, 11, 21, 13, 87, 57, 805, 1529, 0 }; - static ulong[] dim254JoeKuoD5Init = { 1, 3, 5, 15, 3, 39, 115, 179, 199, 907, 1487, 0 }; - static ulong[] dim255JoeKuoD5Init = { 1, 3, 3, 1, 17, 17, 83, 23, 421, 813, 29, 0 }; - static ulong[] dim256JoeKuoD5Init = { 1, 1, 3, 3, 29, 39, 81, 69, 339, 495, 281, 0 }; - static ulong[] dim257JoeKuoD5Init = { 1, 3, 3, 5, 27, 39, 9, 233, 19, 663, 57, 0 }; - static ulong[] dim258JoeKuoD5Init = { 1, 3, 3, 15, 17, 7, 17, 39, 299, 97, 1329, 0 }; - static ulong[] dim259JoeKuoD5Init = { 1, 3, 7, 7, 9, 27, 5, 245, 477, 591, 1021, 0 }; - static ulong[] dim260JoeKuoD5Init = { 1, 3, 3, 13, 9, 37, 19, 141, 201, 57, 1117, 0 }; - static ulong[] dim261JoeKuoD5Init = { 1, 1, 7, 1, 7, 27, 33, 235, 247, 701, 1293, 0 }; - static ulong[] dim262JoeKuoD5Init = { 1, 1, 5, 3, 17, 25, 81, 213, 457, 877, 741, 0 }; - static ulong[] dim263JoeKuoD5Init = { 1, 3, 3, 13, 15, 47, 113, 29, 111, 913, 1695, 0 }; - static ulong[] dim264JoeKuoD5Init = { 1, 1, 1, 3, 5, 53, 119, 215, 163, 933, 1447, 0 }; - static ulong[] dim265JoeKuoD5Init = { 1, 1, 3, 7, 15, 27, 111, 19, 231, 287, 1439, 0 }; - static ulong[] dim266JoeKuoD5Init = { 1, 1, 3, 5, 27, 29, 35, 109, 249, 989, 1837, 0 }; - static ulong[] dim267JoeKuoD5Init = { 1, 1, 3, 9, 29, 35, 51, 241, 509, 163, 831, 0 }; - static ulong[] dim268JoeKuoD5Init = { 1, 1, 3, 9, 7, 59, 43, 111, 119, 639, 899, 0 }; - static ulong[] dim269JoeKuoD5Init = { 1, 3, 1, 3, 15, 47, 95, 219, 377, 899, 535, 0 }; - static ulong[] dim270JoeKuoD5Init = { 1, 1, 1, 11, 3, 19, 115, 59, 143, 13, 701, 0 }; - static ulong[] dim271JoeKuoD5Init = { 1, 3, 5, 11, 5, 17, 17, 91, 223, 923, 1299, 0 }; - static ulong[] dim272JoeKuoD5Init = { 1, 1, 3, 15, 21, 21, 85, 127, 253, 271, 725, 0 }; - static ulong[] dim273JoeKuoD5Init = { 1, 3, 5, 15, 9, 11, 113, 67, 509, 697, 1163, 0 }; - static ulong[] dim274JoeKuoD5Init = { 1, 3, 7, 11, 13, 53, 15, 221, 253, 219, 1839, 0 }; - static ulong[] dim275JoeKuoD5Init = { 1, 3, 3, 3, 31, 63, 85, 171, 345, 243, 711, 0 }; - static ulong[] dim276JoeKuoD5Init = { 1, 1, 5, 1, 25, 13, 65, 91, 441, 609, 1751, 0 }; - static ulong[] dim277JoeKuoD5Init = { 1, 1, 1, 5, 23, 1, 15, 83, 115, 367, 735, 0 }; - static ulong[] dim278JoeKuoD5Init = { 1, 1, 1, 3, 11, 15, 41, 1, 437, 231, 1529, 0 }; - static ulong[] dim279JoeKuoD5Init = { 1, 1, 3, 3, 29, 11, 89, 133, 473, 811, 87, 0 }; - static ulong[] dim280JoeKuoD5Init = { 1, 1, 7, 1, 15, 39, 97, 197, 475, 105, 527, 0 }; - static ulong[] dim281JoeKuoD5Init = { 1, 1, 1, 1, 9, 17, 21, 167, 255, 341, 765, 0 }; - static ulong[] dim282JoeKuoD5Init = { 1, 3, 7, 7, 23, 47, 121, 219, 343, 169, 1147, 0 }; - static ulong[] dim283JoeKuoD5Init = { 1, 3, 1, 7, 3, 57, 27, 147, 383, 157, 1851, 0 }; - static ulong[] dim284JoeKuoD5Init = { 1, 1, 7, 1, 25, 17, 35, 123, 371, 281, 881, 0 }; - static ulong[] dim285JoeKuoD5Init = { 1, 3, 7, 7, 11, 11, 21, 5, 53, 155, 1811, 0 }; - static ulong[] dim286JoeKuoD5Init = { 1, 3, 3, 15, 31, 27, 117, 169, 389, 651, 1513, 0 }; - static ulong[] dim287JoeKuoD5Init = { 1, 1, 7, 5, 31, 15, 103, 59, 73, 575, 1597, 0 }; - static ulong[] dim288JoeKuoD5Init = { 1, 1, 7, 9, 15, 5, 17, 183, 471, 561, 607, 0 }; - static ulong[] dim289JoeKuoD5Init = { 1, 3, 7, 5, 9, 39, 25, 87, 171, 559, 481, 0 }; - static ulong[] dim290JoeKuoD5Init = { 1, 1, 3, 5, 17, 61, 101, 255, 147, 481, 661, 0 }; - static ulong[] dim291JoeKuoD5Init = { 1, 1, 3, 1, 17, 9, 119, 31, 177, 475, 1243, 0 }; - static ulong[] dim292JoeKuoD5Init = { 1, 1, 1, 13, 27, 45, 111, 229, 201, 927, 339, 0 }; - static ulong[] dim293JoeKuoD5Init = { 1, 3, 3, 15, 9, 25, 23, 91, 453, 861, 1919, 0 }; - static ulong[] dim294JoeKuoD5Init = { 1, 3, 1, 3, 7, 57, 93, 75, 223, 63, 7, 0 }; - static ulong[] dim295JoeKuoD5Init = { 1, 1, 5, 13, 7, 29, 71, 197, 405, 401, 585, 0 }; - static ulong[] dim296JoeKuoD5Init = { 1, 1, 3, 13, 11, 11, 7, 157, 1, 105, 473, 0 }; - static ulong[] dim297JoeKuoD5Init = { 1, 3, 7, 1, 29, 3, 127, 243, 93, 123, 1041, 0 }; - static ulong[] dim298JoeKuoD5Init = { 1, 3, 7, 9, 25, 55, 13, 243, 37, 565, 1167, 0 }; - static ulong[] dim299JoeKuoD5Init = { 1, 3, 7, 15, 31, 29, 75, 61, 43, 159, 443, 0 }; - static ulong[] dim300JoeKuoD5Init = { 1, 1, 3, 9, 15, 63, 43, 251, 97, 141, 791, 0 }; - static ulong[] dim301JoeKuoD5Init = { 1, 3, 1, 3, 27, 43, 17, 49, 109, 777, 1999, 0 }; - static ulong[] dim302JoeKuoD5Init = { 1, 3, 1, 1, 25, 5, 15, 145, 75, 855, 771, 0 }; - static ulong[] dim303JoeKuoD5Init = { 1, 3, 3, 13, 7, 27, 3, 221, 451, 533, 1059, 0 }; - static ulong[] dim304JoeKuoD5Init = { 1, 3, 5, 13, 11, 61, 53, 33, 217, 967, 177, 0 }; - static ulong[] dim305JoeKuoD5Init = { 1, 1, 7, 7, 1, 7, 85, 105, 417, 87, 417, 0 }; - static ulong[] dim306JoeKuoD5Init = { 1, 1, 1, 3, 13, 59, 11, 219, 363, 481, 893, 0 }; - static ulong[] dim307JoeKuoD5Init = { 1, 1, 5, 11, 27, 23, 85, 239, 343, 43, 1597, 0 }; - static ulong[] dim308JoeKuoD5Init = { 1, 3, 7, 3, 29, 5, 127, 49, 223, 797, 2003, 0 }; - static ulong[] dim309JoeKuoD5Init = { 1, 3, 1, 9, 29, 61, 21, 191, 157, 355, 2033, 0 }; - static ulong[] dim310JoeKuoD5Init = { 1, 1, 7, 5, 5, 49, 53, 207, 121, 451, 319, 0 }; - static ulong[] dim311JoeKuoD5Init = { 1, 3, 3, 11, 9, 7, 111, 153, 151, 395, 1389, 0 }; - static ulong[] dim312JoeKuoD5Init = { 1, 3, 5, 11, 25, 45, 113, 99, 263, 561, 1181, 0 }; - static ulong[] dim313JoeKuoD5Init = { 1, 3, 5, 1, 13, 27, 77, 1, 109, 741, 59, 0 }; - static ulong[] dim314JoeKuoD5Init = { 1, 1, 3, 1, 15, 57, 43, 7, 507, 885, 747, 0 }; - static ulong[] dim315JoeKuoD5Init = { 1, 3, 5, 5, 25, 7, 45, 147, 375, 975, 619, 0 }; - static ulong[] dim316JoeKuoD5Init = { 1, 1, 5, 11, 13, 11, 107, 81, 199, 11, 1267, 0 }; - static ulong[] dim317JoeKuoD5Init = { 1, 3, 5, 3, 15, 11, 113, 61, 425, 43, 1889, 0 }; - static ulong[] dim318JoeKuoD5Init = { 1, 3, 3, 7, 29, 11, 123, 237, 173, 249, 1091, 0 }; - static ulong[] dim319JoeKuoD5Init = { 1, 3, 7, 15, 29, 13, 21, 159, 149, 379, 1665, 0 }; - static ulong[] dim320JoeKuoD5Init = { 1, 1, 7, 15, 13, 53, 23, 47, 115, 183, 577, 0 }; - static ulong[] dim321JoeKuoD5Init = { 1, 1, 3, 9, 11, 49, 77, 81, 193, 133, 489, 0 }; - static ulong[] dim322JoeKuoD5Init = { 1, 3, 7, 15, 7, 27, 53, 187, 347, 211, 233, 0 }; - static ulong[] dim323JoeKuoD5Init = { 1, 1, 5, 9, 15, 17, 45, 75, 449, 971, 1123, 0 }; - static ulong[] dim324JoeKuoD5Init = { 1, 3, 3, 11, 25, 21, 109, 71, 439, 439, 1397, 0 }; - static ulong[] dim325JoeKuoD5Init = { 1, 1, 1, 7, 9, 47, 117, 117, 165, 531, 271, 0 }; - static ulong[] dim326JoeKuoD5Init = { 1, 3, 5, 9, 11, 5, 31, 199, 159, 87, 1729, 0 }; - static ulong[] dim327JoeKuoD5Init = { 1, 1, 7, 5, 27, 29, 17, 237, 175, 881, 989, 0 }; - static ulong[] dim328JoeKuoD5Init = { 1, 1, 5, 13, 25, 63, 19, 159, 409, 247, 683, 0 }; - static ulong[] dim329JoeKuoD5Init = { 1, 1, 3, 15, 15, 39, 101, 129, 253, 487, 719, 0 }; - static ulong[] dim330JoeKuoD5Init = { 1, 3, 1, 1, 7, 13, 107, 249, 331, 553, 1199, 0 }; - static ulong[] dim331JoeKuoD5Init = { 1, 3, 7, 1, 5, 51, 81, 37, 349, 561, 295, 0 }; - static ulong[] dim332JoeKuoD5Init = { 1, 3, 1, 5, 27, 61, 49, 89, 379, 67, 1063, 0 }; - static ulong[] dim333JoeKuoD5Init = { 1, 3, 7, 9, 15, 37, 119, 141, 81, 341, 2003, 0 }; - static ulong[] dim334JoeKuoD5Init = { 1, 3, 1, 13, 29, 31, 29, 143, 463, 399, 1345, 0 }; - static ulong[] dim335JoeKuoD5Init = { 1, 1, 7, 3, 29, 35, 29, 233, 499, 503, 903, 0 }; - static ulong[] dim336JoeKuoD5Init = { 1, 3, 7, 13, 29, 23, 127, 185, 77, 555, 1311, 0 }; - static ulong[] dim337JoeKuoD5Init = { 1, 1, 3, 11, 23, 3, 111, 159, 503, 889, 1043, 1153, 0 }; - static ulong[] dim338JoeKuoD5Init = { 1, 3, 7, 1, 13, 41, 109, 133, 81, 525, 2027, 3059, 0 }; - static ulong[] dim339JoeKuoD5Init = { 1, 1, 7, 11, 29, 53, 111, 129, 399, 479, 467, 363, 0 }; - static ulong[] dim340JoeKuoD5Init = { 1, 1, 7, 3, 5, 7, 9, 21, 391, 851, 575, 1317, 0 }; - static ulong[] dim341JoeKuoD5Init = { 1, 1, 1, 5, 19, 59, 91, 133, 403, 71, 1895, 3029, 0 }; - static ulong[] dim342JoeKuoD5Init = { 1, 3, 7, 11, 21, 29, 113, 109, 463, 251, 393, 3169, 0 }; - static ulong[] dim343JoeKuoD5Init = { 1, 1, 7, 11, 25, 3, 47, 195, 223, 1003, 947, 121, 0 }; - static ulong[] dim344JoeKuoD5Init = { 1, 1, 7, 9, 31, 61, 63, 31, 49, 907, 389, 3713, 0 }; - static ulong[] dim345JoeKuoD5Init = { 1, 1, 1, 13, 13, 19, 55, 87, 489, 665, 945, 2081, 0 }; - static ulong[] dim346JoeKuoD5Init = { 1, 1, 1, 7, 23, 5, 39, 19, 355, 399, 929, 3077, 0 }; - static ulong[] dim347JoeKuoD5Init = { 1, 3, 1, 11, 7, 59, 43, 69, 285, 753, 75, 2261, 0 }; - static ulong[] dim348JoeKuoD5Init = { 1, 1, 3, 3, 27, 45, 29, 181, 347, 863, 1421, 2077, 0 }; - static ulong[] dim349JoeKuoD5Init = { 1, 1, 1, 3, 7, 27, 77, 67, 399, 919, 917, 1465, 0 }; - static ulong[] dim350JoeKuoD5Init = { 1, 1, 5, 5, 11, 41, 17, 65, 495, 643, 1641, 323, 0 }; - static ulong[] dim351JoeKuoD5Init = { 1, 1, 3, 1, 9, 37, 107, 171, 189, 405, 2005, 2811, 0 }; - static ulong[] dim352JoeKuoD5Init = { 1, 1, 5, 11, 3, 63, 51, 27, 479, 571, 575, 2859, 0 }; - static ulong[] dim353JoeKuoD5Init = { 1, 1, 3, 9, 29, 23, 89, 7, 265, 41, 481, 2177, 0 }; - static ulong[] dim354JoeKuoD5Init = { 1, 3, 5, 7, 29, 15, 79, 217, 411, 867, 49, 469, 0 }; - static ulong[] dim355JoeKuoD5Init = { 1, 1, 7, 3, 3, 27, 69, 177, 291, 965, 637, 3629, 0 }; - static ulong[] dim356JoeKuoD5Init = { 1, 1, 1, 13, 11, 45, 83, 63, 275, 851, 779, 2615, 0 }; - static ulong[] dim357JoeKuoD5Init = { 1, 1, 3, 13, 1, 27, 89, 153, 355, 811, 515, 1541, 0 }; - static ulong[] dim358JoeKuoD5Init = { 1, 3, 1, 13, 1, 21, 75, 5, 255, 813, 1347, 2301, 0 }; - static ulong[] dim359JoeKuoD5Init = { 1, 1, 1, 15, 9, 49, 3, 203, 505, 591, 713, 2893, 0 }; - static ulong[] dim360JoeKuoD5Init = { 1, 3, 3, 3, 1, 51, 11, 161, 41, 17, 435, 3045, 0 }; - static ulong[] dim361JoeKuoD5Init = { 1, 1, 5, 9, 15, 23, 115, 73, 343, 985, 1559, 1615, 0 }; - static ulong[] dim362JoeKuoD5Init = { 1, 3, 5, 5, 9, 43, 17, 187, 311, 749, 1841, 609, 0 }; - static ulong[] dim363JoeKuoD5Init = { 1, 3, 1, 15, 13, 3, 113, 83, 287, 931, 399, 2143, 0 }; - static ulong[] dim364JoeKuoD5Init = { 1, 3, 5, 13, 17, 11, 99, 235, 313, 293, 2005, 2557, 0 }; - static ulong[] dim365JoeKuoD5Init = { 1, 3, 5, 13, 7, 57, 79, 225, 415, 749, 1243, 1303, 0 }; - static ulong[] dim366JoeKuoD5Init = { 1, 1, 5, 5, 21, 37, 55, 53, 389, 141, 1231, 1639, 0 }; - static ulong[] dim367JoeKuoD5Init = { 1, 3, 1, 13, 15, 37, 83, 219, 471, 751, 1241, 269, 0 }; - static ulong[] dim368JoeKuoD5Init = { 1, 3, 1, 11, 7, 51, 37, 81, 97, 857, 1431, 883, 0 }; - static ulong[] dim369JoeKuoD5Init = { 1, 1, 7, 7, 27, 31, 29, 223, 439, 25, 379, 3721, 0 }; - static ulong[] dim370JoeKuoD5Init = { 1, 3, 7, 7, 13, 11, 55, 127, 493, 493, 143, 1595, 0 }; - static ulong[] dim371JoeKuoD5Init = { 1, 3, 3, 15, 27, 55, 93, 91, 49, 931, 99, 1887, 0 }; - static ulong[] dim372JoeKuoD5Init = { 1, 1, 7, 1, 13, 11, 81, 175, 171, 203, 679, 239, 0 }; - static ulong[] dim373JoeKuoD5Init = { 1, 1, 3, 9, 19, 35, 79, 51, 163, 571, 363, 3903, 0 }; - static ulong[] dim374JoeKuoD5Init = { 1, 3, 3, 5, 3, 11, 99, 57, 479, 571, 487, 2141, 0 }; - static ulong[] dim375JoeKuoD5Init = { 1, 3, 7, 13, 1, 3, 123, 191, 349, 523, 53, 2991, 0 }; - static ulong[] dim376JoeKuoD5Init = { 1, 1, 3, 5, 17, 1, 5, 131, 279, 717, 1725, 35, 0 }; - static ulong[] dim377JoeKuoD5Init = { 1, 3, 5, 1, 9, 43, 29, 9, 487, 349, 457, 2551, 0 }; - static ulong[] dim378JoeKuoD5Init = { 1, 1, 5, 5, 7, 55, 75, 245, 249, 623, 1681, 2345, 0 }; - static ulong[] dim379JoeKuoD5Init = { 1, 1, 7, 11, 15, 35, 111, 185, 269, 913, 1899, 4059, 0 }; - static ulong[] dim380JoeKuoD5Init = { 1, 1, 5, 3, 1, 51, 43, 159, 273, 329, 863, 831, 0 }; - static ulong[] dim381JoeKuoD5Init = { 1, 1, 5, 15, 31, 35, 23, 135, 223, 333, 1265, 1183, 0 }; - static ulong[] dim382JoeKuoD5Init = { 1, 1, 3, 9, 9, 21, 93, 33, 341, 649, 1707, 1995, 0 }; - static ulong[] dim383JoeKuoD5Init = { 1, 3, 3, 5, 9, 9, 9, 175, 331, 709, 927, 423, 0 }; - static ulong[] dim384JoeKuoD5Init = { 1, 3, 1, 1, 5, 41, 31, 105, 223, 17, 1485, 2133, 0 }; - static ulong[] dim385JoeKuoD5Init = { 1, 1, 5, 11, 23, 7, 95, 87, 303, 817, 1019, 3335, 0 }; - static ulong[] dim386JoeKuoD5Init = { 1, 3, 7, 1, 21, 3, 7, 133, 23, 235, 1311, 531, 0 }; - static ulong[] dim387JoeKuoD5Init = { 1, 1, 7, 15, 25, 35, 69, 251, 37, 5, 1147, 2593, 0 }; - static ulong[] dim388JoeKuoD5Init = { 1, 1, 1, 9, 21, 55, 27, 129, 239, 887, 1759, 3211, 0 }; - static ulong[] dim389JoeKuoD5Init = { 1, 3, 5, 15, 3, 41, 13, 141, 339, 921, 1081, 4047, 0 }; - static ulong[] dim390JoeKuoD5Init = { 1, 3, 3, 5, 1, 49, 51, 91, 357, 259, 547, 189, 0 }; - static ulong[] dim391JoeKuoD5Init = { 1, 3, 1, 13, 15, 29, 43, 165, 213, 59, 429, 1831, 0 }; - static ulong[] dim392JoeKuoD5Init = { 1, 3, 1, 9, 25, 11, 37, 67, 5, 77, 915, 3865, 0 }; - static ulong[] dim393JoeKuoD5Init = { 1, 3, 5, 9, 31, 63, 61, 209, 283, 223, 1253, 2137, 0 }; - static ulong[] dim394JoeKuoD5Init = { 1, 1, 7, 11, 13, 45, 65, 105, 419, 909, 1943, 2201, 0 }; - static ulong[] dim395JoeKuoD5Init = { 1, 3, 7, 7, 9, 27, 21, 233, 37, 23, 921, 969, 0 }; - static ulong[] dim396JoeKuoD5Init = { 1, 3, 7, 3, 31, 55, 39, 127, 455, 397, 65, 2381, 0 }; - static ulong[] dim397JoeKuoD5Init = { 1, 3, 1, 3, 27, 57, 39, 137, 263, 519, 427, 3289, 0 }; - static ulong[] dim398JoeKuoD5Init = { 1, 1, 1, 5, 9, 29, 21, 99, 21, 807, 1871, 2875, 0 }; - static ulong[] dim399JoeKuoD5Init = { 1, 3, 3, 15, 27, 59, 3, 15, 189, 681, 305, 2969, 0 }; - static ulong[] dim400JoeKuoD5Init = { 1, 3, 5, 13, 25, 43, 111, 179, 281, 377, 1885, 815, 0 }; - static ulong[] dim401JoeKuoD5Init = { 1, 3, 3, 1, 15, 13, 17, 99, 53, 269, 1199, 1771, 0 }; - static ulong[] dim402JoeKuoD5Init = { 1, 1, 1, 7, 7, 59, 115, 209, 327, 913, 715, 279, 0 }; - static ulong[] dim403JoeKuoD5Init = { 1, 1, 5, 5, 11, 29, 81, 69, 191, 453, 379, 1379, 0 }; - static ulong[] dim404JoeKuoD5Init = { 1, 3, 1, 13, 1, 29, 85, 181, 281, 463, 137, 2779, 0 }; - static ulong[] dim405JoeKuoD5Init = { 1, 3, 5, 7, 25, 39, 45, 241, 87, 11, 511, 1919, 0 }; - static ulong[] dim406JoeKuoD5Init = { 1, 1, 3, 13, 21, 17, 57, 249, 91, 165, 1867, 615, 0 }; - static ulong[] dim407JoeKuoD5Init = { 1, 1, 3, 3, 29, 47, 79, 83, 3, 765, 1803, 2741, 0 }; - static ulong[] dim408JoeKuoD5Init = { 1, 1, 1, 15, 29, 41, 23, 9, 205, 657, 721, 2877, 0 }; - static ulong[] dim409JoeKuoD5Init = { 1, 1, 5, 5, 31, 21, 71, 217, 19, 589, 281, 719, 0 }; - static ulong[] dim410JoeKuoD5Init = { 1, 1, 7, 9, 11, 37, 3, 159, 41, 823, 1519, 3395, 0 }; - static ulong[] dim411JoeKuoD5Init = { 1, 1, 3, 3, 7, 51, 49, 193, 37, 981, 687, 3219, 0 }; - static ulong[] dim412JoeKuoD5Init = { 1, 1, 7, 15, 3, 27, 79, 195, 155, 613, 1933, 2083, 0 }; - static ulong[] dim413JoeKuoD5Init = { 1, 3, 1, 11, 13, 39, 75, 109, 395, 809, 545, 499, 0 }; - static ulong[] dim414JoeKuoD5Init = { 1, 3, 7, 11, 1, 63, 47, 77, 455, 617, 739, 2885, 0 }; - static ulong[] dim415JoeKuoD5Init = { 1, 1, 5, 9, 23, 59, 117, 47, 379, 349, 1967, 1895, 0 }; - static ulong[] dim416JoeKuoD5Init = { 1, 1, 1, 15, 1, 3, 7, 7, 105, 703, 1777, 113, 0 }; - static ulong[] dim417JoeKuoD5Init = { 1, 1, 5, 7, 7, 25, 69, 123, 257, 513, 41, 2689, 0 }; - static ulong[] dim418JoeKuoD5Init = { 1, 3, 1, 15, 7, 9, 11, 67, 27, 283, 1139, 1961, 0 }; - static ulong[] dim419JoeKuoD5Init = { 1, 1, 7, 13, 3, 5, 53, 251, 139, 913, 267, 1931, 0 }; - static ulong[] dim420JoeKuoD5Init = { 1, 1, 1, 13, 3, 11, 79, 211, 27, 551, 339, 3383, 0 }; - static ulong[] dim421JoeKuoD5Init = { 1, 1, 1, 1, 9, 47, 111, 47, 399, 353, 1707, 603, 0 }; - static ulong[] dim422JoeKuoD5Init = { 1, 1, 3, 15, 1, 43, 17, 19, 335, 713, 645, 3227, 0 }; - static ulong[] dim423JoeKuoD5Init = { 1, 1, 3, 9, 5, 27, 17, 209, 363, 821, 1365, 143, 0 }; - static ulong[] dim424JoeKuoD5Init = { 1, 3, 3, 7, 29, 11, 47, 253, 421, 599, 465, 2413, 0 }; - static ulong[] dim425JoeKuoD5Init = { 1, 1, 5, 9, 17, 39, 5, 47, 315, 645, 713, 4023, 0 }; - static ulong[] dim426JoeKuoD5Init = { 1, 1, 7, 9, 9, 3, 11, 45, 9, 831, 1513, 2655, 0 }; - static ulong[] dim427JoeKuoD5Init = { 1, 1, 5, 3, 29, 55, 113, 181, 281, 329, 193, 2969, 0 }; - static ulong[] dim428JoeKuoD5Init = { 1, 1, 7, 7, 9, 15, 29, 77, 11, 627, 1191, 3589, 0 }; - static ulong[] dim429JoeKuoD5Init = { 1, 1, 7, 3, 27, 53, 83, 13, 409, 931, 1581, 371, 0 }; - static ulong[] dim430JoeKuoD5Init = { 1, 3, 7, 3, 11, 7, 89, 143, 369, 519, 947, 2047, 0 }; - static ulong[] dim431JoeKuoD5Init = { 1, 3, 5, 11, 27, 59, 27, 75, 199, 965, 1669, 1713, 0 }; - static ulong[] dim432JoeKuoD5Init = { 1, 3, 1, 1, 23, 63, 91, 159, 193, 355, 653, 2659, 0 }; - static ulong[] dim433JoeKuoD5Init = { 1, 3, 5, 11, 23, 37, 15, 73, 457, 789, 1207, 2573, 0 }; - static ulong[] dim434JoeKuoD5Init = { 1, 1, 3, 7, 13, 23, 71, 171, 479, 183, 1285, 1649, 0 }; - static ulong[] dim435JoeKuoD5Init = { 1, 1, 7, 1, 19, 13, 89, 5, 319, 15, 857, 3175, 0 }; - static ulong[] dim436JoeKuoD5Init = { 1, 1, 3, 7, 29, 7, 1, 249, 191, 237, 683, 1261, 0 }; - static ulong[] dim437JoeKuoD5Init = { 1, 3, 7, 7, 17, 53, 99, 119, 35, 63, 1845, 2681, 0 }; - static ulong[] dim438JoeKuoD5Init = { 1, 3, 7, 7, 23, 53, 39, 157, 323, 537, 1989, 1233, 0 }; - static ulong[] dim439JoeKuoD5Init = { 1, 3, 7, 7, 25, 19, 9, 67, 315, 499, 919, 2299, 0 }; - static ulong[] dim440JoeKuoD5Init = { 1, 3, 3, 9, 21, 49, 109, 185, 403, 179, 1967, 1185, 0 }; - static ulong[] dim441JoeKuoD5Init = { 1, 1, 3, 1, 27, 53, 33, 203, 179, 515, 1867, 1775, 0 }; - static ulong[] dim442JoeKuoD5Init = { 1, 1, 7, 15, 19, 25, 23, 77, 51, 467, 143, 1585, 0 }; - static ulong[] dim443JoeKuoD5Init = { 1, 1, 1, 15, 19, 35, 41, 97, 407, 319, 1175, 241, 0 }; - static ulong[] dim444JoeKuoD5Init = { 1, 1, 3, 3, 29, 51, 41, 91, 223, 671, 729, 2009, 0 }; - static ulong[] dim445JoeKuoD5Init = { 1, 1, 5, 7, 7, 55, 125, 75, 425, 699, 1837, 1515, 0 }; - static ulong[] dim446JoeKuoD5Init = { 1, 1, 5, 1, 27, 59, 59, 235, 43, 77, 1433, 3689, 0 }; - static ulong[] dim447JoeKuoD5Init = { 1, 1, 7, 9, 19, 59, 69, 85, 199, 173, 1947, 1383, 0 }; - static ulong[] dim448JoeKuoD5Init = { 1, 3, 1, 13, 29, 47, 121, 131, 45, 341, 85, 257, 0 }; - static ulong[] dim449JoeKuoD5Init = { 1, 1, 3, 1, 17, 17, 113, 103, 407, 815, 225, 2267, 0 }; - static ulong[] dim450JoeKuoD5Init = { 1, 3, 1, 3, 23, 19, 65, 173, 475, 527, 271, 261, 0 }; - static ulong[] dim451JoeKuoD5Init = { 1, 3, 1, 9, 23, 51, 5, 75, 403, 277, 1897, 353, 0 }; - static ulong[] dim452JoeKuoD5Init = { 1, 1, 5, 3, 31, 49, 73, 93, 55, 99, 403, 659, 0 }; - static ulong[] dim453JoeKuoD5Init = { 1, 3, 1, 11, 29, 17, 57, 141, 209, 907, 431, 2265, 0 }; - static ulong[] dim454JoeKuoD5Init = { 1, 1, 3, 15, 25, 55, 105, 61, 273, 201, 23, 1211, 0 }; - static ulong[] dim455JoeKuoD5Init = { 1, 1, 5, 5, 3, 63, 41, 121, 161, 713, 1885, 225, 0 }; - static ulong[] dim456JoeKuoD5Init = { 1, 3, 3, 11, 11, 53, 63, 175, 439, 1, 953, 481, 0 }; - static ulong[] dim457JoeKuoD5Init = { 1, 3, 1, 7, 1, 27, 65, 189, 223, 659, 413, 3677, 0 }; - static ulong[] dim458JoeKuoD5Init = { 1, 3, 3, 5, 17, 9, 51, 39, 307, 811, 941, 2297, 0 }; - static ulong[] dim459JoeKuoD5Init = { 1, 3, 1, 3, 1, 41, 77, 237, 47, 533, 1783, 1385, 0 }; - static ulong[] dim460JoeKuoD5Init = { 1, 3, 3, 13, 19, 39, 31, 249, 449, 639, 1789, 3479, 0 }; - static ulong[] dim461JoeKuoD5Init = { 1, 3, 7, 11, 9, 9, 9, 19, 481, 411, 1669, 863, 0 }; - static ulong[] dim462JoeKuoD5Init = { 1, 3, 7, 7, 15, 15, 89, 161, 171, 377, 2031, 389, 0 }; - static ulong[] dim463JoeKuoD5Init = { 1, 1, 5, 5, 7, 49, 83, 81, 181, 395, 1197, 2455, 0 }; - static ulong[] dim464JoeKuoD5Init = { 1, 3, 5, 9, 15, 25, 21, 35, 287, 369, 693, 1753, 0 }; - static ulong[] dim465JoeKuoD5Init = { 1, 3, 5, 7, 5, 19, 41, 241, 459, 427, 631, 1109, 0 }; - static ulong[] dim466JoeKuoD5Init = { 1, 3, 3, 3, 23, 13, 115, 55, 145, 933, 1985, 753, 0 }; - static ulong[] dim467JoeKuoD5Init = { 1, 3, 5, 5, 19, 15, 73, 67, 335, 583, 315, 1559, 0 }; - static ulong[] dim468JoeKuoD5Init = { 1, 1, 5, 5, 23, 41, 65, 155, 171, 1017, 1283, 1989, 0 }; - static ulong[] dim469JoeKuoD5Init = { 1, 1, 5, 13, 23, 53, 75, 91, 253, 41, 101, 1943, 0 }; - static ulong[] dim470JoeKuoD5Init = { 1, 3, 7, 13, 25, 13, 5, 71, 437, 553, 701, 805, 0 }; - static ulong[] dim471JoeKuoD5Init = { 1, 1, 3, 5, 3, 3, 61, 255, 409, 753, 1265, 2739, 0 }; - static ulong[] dim472JoeKuoD5Init = { 1, 3, 1, 11, 25, 33, 69, 41, 367, 133, 809, 1421, 0 }; - static ulong[] dim473JoeKuoD5Init = { 1, 1, 7, 9, 3, 59, 15, 229, 313, 667, 45, 1485, 0 }; - static ulong[] dim474JoeKuoD5Init = { 1, 3, 3, 11, 3, 45, 73, 245, 47, 489, 1715, 3167, 0 }; - static ulong[] dim475JoeKuoD5Init = { 1, 1, 7, 15, 23, 23, 107, 1, 171, 993, 1617, 3665, 0 }; - static ulong[] dim476JoeKuoD5Init = { 1, 3, 7, 5, 5, 41, 9, 221, 91, 611, 639, 3709, 0 }; - static ulong[] dim477JoeKuoD5Init = { 1, 3, 7, 1, 17, 31, 55, 23, 75, 501, 1605, 2361, 0 }; - static ulong[] dim478JoeKuoD5Init = { 1, 1, 3, 11, 19, 27, 37, 111, 393, 75, 523, 2079, 0 }; - static ulong[] dim479JoeKuoD5Init = { 1, 1, 3, 1, 13, 17, 103, 177, 331, 431, 419, 2781, 0 }; - static ulong[] dim480JoeKuoD5Init = { 1, 1, 5, 1, 31, 57, 9, 87, 111, 761, 1259, 3645, 0 }; - static ulong[] dim481JoeKuoD5Init = { 1, 3, 1, 1, 29, 39, 117, 207, 25, 263, 1875, 3325, 1773, 0 }; - static ulong[] dim482JoeKuoD5Init = { 1, 3, 5, 11, 21, 55, 105, 43, 155, 933, 585, 1617, 1705, 0 }; - static ulong[] dim483JoeKuoD5Init = { 1, 1, 5, 5, 29, 37, 67, 165, 229, 517, 71, 3927, 1131, 0 }; - static ulong[] dim484JoeKuoD5Init = { 1, 1, 1, 3, 1, 15, 7, 139, 431, 599, 101, 1167, 55, 0 }; - static ulong[] dim485JoeKuoD5Init = { 1, 3, 1, 3, 5, 31, 15, 99, 375, 491, 293, 2521, 1599, 0 }; - static ulong[] dim486JoeKuoD5Init = { 1, 1, 1, 13, 29, 59, 99, 155, 295, 21, 1459, 2263, 1997, 0 }; - static ulong[] dim487JoeKuoD5Init = { 1, 3, 7, 5, 29, 61, 103, 151, 37, 431, 1893, 2835, 6509, 0 }; - static ulong[] dim488JoeKuoD5Init = { 1, 1, 3, 7, 17, 15, 1, 163, 481, 547, 701, 2957, 7071, 0 }; - static ulong[] dim489JoeKuoD5Init = { 1, 1, 5, 5, 29, 41, 51, 223, 133, 49, 753, 3769, 8139, 0 }; - static ulong[] dim490JoeKuoD5Init = { 1, 3, 3, 1, 23, 23, 21, 107, 9, 445, 215, 857, 7913, 0 }; - static ulong[] dim491JoeKuoD5Init = { 1, 3, 5, 5, 17, 13, 11, 111, 419, 433, 1289, 2855, 2157, 0 }; - static ulong[] dim492JoeKuoD5Init = { 1, 1, 5, 11, 31, 3, 97, 223, 143, 117, 563, 2179, 1053, 0 }; - static ulong[] dim493JoeKuoD5Init = { 1, 3, 7, 13, 7, 25, 115, 151, 181, 999, 1027, 795, 679, 0 }; - static ulong[] dim494JoeKuoD5Init = { 1, 1, 5, 15, 31, 23, 85, 125, 135, 1001, 909, 339, 5693, 0 }; - static ulong[] dim495JoeKuoD5Init = { 1, 3, 3, 3, 29, 17, 105, 239, 467, 875, 1135, 1859, 6399, 0 }; - static ulong[] dim496JoeKuoD5Init = { 1, 3, 5, 13, 19, 59, 99, 29, 177, 879, 1817, 3747, 1855, 0 }; - static ulong[] dim497JoeKuoD5Init = { 1, 1, 7, 1, 23, 5, 29, 53, 111, 341, 1713, 2285, 7033, 0 }; - static ulong[] dim498JoeKuoD5Init = { 1, 1, 3, 5, 7, 55, 67, 173, 273, 881, 1405, 1663, 2135, 0 }; - static ulong[] dim499JoeKuoD5Init = { 1, 3, 1, 9, 1, 39, 11, 63, 107, 905, 629, 1773, 1059, 0 }; - static ulong[] dim500JoeKuoD5Init = { 1, 1, 3, 15, 29, 51, 111, 189, 337, 505, 453, 1549, 3697, 0 }; - static ulong[] dim501JoeKuoD5Init = { 1, 3, 1, 9, 23, 57, 21, 61, 161, 695, 1097, 809, 5737, 0 }; - static ulong[] dim502JoeKuoD5Init = { 1, 3, 7, 15, 15, 55, 93, 65, 101, 521, 1273, 1949, 7325, 0 }; - static ulong[] dim503JoeKuoD5Init = { 1, 3, 7, 3, 23, 31, 37, 51, 205, 261, 647, 1905, 4407, 0 }; - static ulong[] dim504JoeKuoD5Init = { 1, 1, 7, 3, 3, 9, 91, 51, 271, 623, 1611, 563, 4687, 0 }; - static ulong[] dim505JoeKuoD5Init = { 1, 3, 7, 3, 11, 61, 95, 215, 347, 171, 519, 2331, 2189, 0 }; - static ulong[] dim506JoeKuoD5Init = { 1, 1, 3, 1, 25, 13, 87, 159, 87, 915, 463, 1345, 5901, 0 }; - static ulong[] dim507JoeKuoD5Init = { 1, 3, 3, 11, 31, 21, 81, 75, 153, 337, 2025, 233, 4999, 0 }; - static ulong[] dim508JoeKuoD5Init = { 1, 1, 1, 11, 23, 25, 81, 149, 225, 799, 159, 799, 687, 0 }; - static ulong[] dim509JoeKuoD5Init = { 1, 1, 7, 5, 23, 55, 67, 47, 375, 657, 877, 1505, 1757, 0 }; - static ulong[] dim510JoeKuoD5Init = { 1, 3, 3, 9, 17, 7, 123, 71, 203, 457, 201, 9, 6671, 0 }; - static ulong[] dim511JoeKuoD5Init = { 1, 3, 7, 3, 1, 55, 7, 133, 65, 891, 1705, 389, 4601, 0 }; - static ulong[] dim512JoeKuoD5Init = { 1, 3, 3, 3, 21, 59, 101, 105, 241, 231, 363, 4029, 1279, 0 }; - static ulong[] dim513JoeKuoD5Init = { 1, 3, 7, 11, 31, 61, 115, 219, 249, 575, 201, 547, 5315, 0 }; - static ulong[] dim514JoeKuoD5Init = { 1, 1, 5, 11, 11, 3, 75, 219, 183, 771, 725, 2175, 4077, 0 }; - static ulong[] dim515JoeKuoD5Init = { 1, 3, 1, 13, 1, 37, 1, 165, 431, 423, 2021, 475, 5151, 0 }; - static ulong[] dim516JoeKuoD5Init = { 1, 3, 7, 7, 15, 59, 25, 133, 377, 747, 23, 1195, 3303, 0 }; - static ulong[] dim517JoeKuoD5Init = { 1, 3, 5, 15, 23, 63, 121, 159, 403, 143, 187, 1481, 4755, 0 }; - static ulong[] dim518JoeKuoD5Init = { 1, 3, 7, 13, 21, 29, 55, 165, 483, 495, 579, 1197, 4841, 0 }; - static ulong[] dim519JoeKuoD5Init = { 1, 3, 5, 3, 27, 7, 111, 57, 353, 1023, 1593, 1447, 5819, 0 }; - static ulong[] dim520JoeKuoD5Init = { 1, 3, 7, 3, 13, 37, 115, 65, 23, 707, 603, 1805, 6011, 0 }; - static ulong[] dim521JoeKuoD5Init = { 1, 1, 5, 15, 9, 47, 87, 195, 125, 515, 1885, 89, 1377, 0 }; - static ulong[] dim522JoeKuoD5Init = { 1, 1, 3, 11, 1, 25, 11, 73, 183, 897, 981, 275, 331, 0 }; - static ulong[] dim523JoeKuoD5Init = { 1, 1, 5, 15, 13, 53, 125, 37, 145, 763, 1991, 1971, 4385, 0 }; - static ulong[] dim524JoeKuoD5Init = { 1, 3, 7, 1, 29, 53, 69, 97, 415, 151, 1389, 2867, 3085, 0 }; - static ulong[] dim525JoeKuoD5Init = { 1, 3, 7, 7, 21, 51, 77, 115, 81, 197, 91, 3417, 2357, 0 }; - static ulong[] dim526JoeKuoD5Init = { 1, 3, 7, 11, 31, 31, 21, 21, 93, 221, 1401, 3253, 6875, 0 }; - static ulong[] dim527JoeKuoD5Init = { 1, 3, 3, 9, 11, 17, 87, 75, 333, 871, 1679, 2943, 4803, 0 }; - static ulong[] dim528JoeKuoD5Init = { 1, 1, 7, 11, 11, 61, 67, 141, 79, 757, 965, 1999, 6363, 0 }; - static ulong[] dim529JoeKuoD5Init = { 1, 1, 5, 5, 27, 13, 109, 137, 235, 1007, 1307, 341, 3957, 0 }; - static ulong[] dim530JoeKuoD5Init = { 1, 1, 7, 9, 15, 37, 47, 247, 295, 867, 1433, 553, 5365, 0 }; - static ulong[] dim531JoeKuoD5Init = { 1, 1, 7, 3, 13, 29, 77, 155, 423, 823, 1117, 3939, 1423, 0 }; - static ulong[] dim532JoeKuoD5Init = { 1, 1, 3, 9, 17, 27, 47, 73, 79, 329, 1473, 3241, 697, 0 }; - static ulong[] dim533JoeKuoD5Init = { 1, 3, 5, 9, 23, 5, 47, 89, 427, 893, 2031, 3415, 6367, 0 }; - static ulong[] dim534JoeKuoD5Init = { 1, 3, 5, 1, 17, 47, 31, 113, 461, 417, 2017, 41, 2417, 0 }; - static ulong[] dim535JoeKuoD5Init = { 1, 1, 3, 5, 11, 35, 119, 95, 389, 31, 871, 563, 7547, 0 }; - static ulong[] dim536JoeKuoD5Init = { 1, 3, 5, 9, 3, 49, 63, 237, 511, 619, 589, 3571, 1883, 0 }; - static ulong[] dim537JoeKuoD5Init = { 1, 3, 3, 1, 1, 29, 17, 117, 173, 399, 443, 2625, 2009, 0 }; - static ulong[] dim538JoeKuoD5Init = { 1, 3, 3, 9, 23, 47, 5, 167, 413, 513, 509, 853, 3509, 0 }; - static ulong[] dim539JoeKuoD5Init = { 1, 1, 3, 5, 13, 15, 33, 165, 21, 163, 1613, 3387, 645, 0 }; - static ulong[] dim540JoeKuoD5Init = { 1, 1, 1, 3, 7, 33, 59, 25, 65, 243, 1253, 1893, 1637, 0 }; - static ulong[] dim541JoeKuoD5Init = { 1, 1, 5, 15, 21, 63, 51, 167, 131, 171, 651, 295, 5775, 0 }; - static ulong[] dim542JoeKuoD5Init = { 1, 1, 5, 9, 7, 23, 31, 171, 85, 859, 1691, 2757, 1351, 0 }; - static ulong[] dim543JoeKuoD5Init = { 1, 1, 5, 3, 31, 7, 25, 69, 183, 417, 39, 2671, 5197, 0 }; - static ulong[] dim544JoeKuoD5Init = { 1, 1, 5, 9, 17, 21, 57, 145, 23, 933, 2031, 65, 4583, 0 }; - static ulong[] dim545JoeKuoD5Init = { 1, 3, 3, 5, 1, 59, 117, 191, 197, 627, 659, 2873, 3865, 0 }; - static ulong[] dim546JoeKuoD5Init = { 1, 1, 5, 15, 23, 51, 45, 47, 147, 779, 1619, 1017, 3769, 0 }; - static ulong[] dim547JoeKuoD5Init = { 1, 1, 7, 3, 9, 1, 75, 151, 117, 483, 1499, 2143, 5873, 0 }; - static ulong[] dim548JoeKuoD5Init = { 1, 1, 7, 1, 13, 31, 105, 115, 199, 111, 1403, 1833, 7923, 0 }; - static ulong[] dim549JoeKuoD5Init = { 1, 1, 7, 7, 29, 53, 121, 149, 419, 107, 1299, 1925, 4409, 0 }; - static ulong[] dim550JoeKuoD5Init = { 1, 1, 7, 11, 21, 25, 63, 97, 145, 71, 1693, 465, 5607, 0 }; - static ulong[] dim551JoeKuoD5Init = { 1, 3, 3, 15, 25, 43, 77, 177, 53, 495, 1983, 4083, 2107, 0 }; - static ulong[] dim552JoeKuoD5Init = { 1, 1, 7, 11, 7, 51, 109, 29, 171, 847, 673, 2929, 3887, 0 }; - static ulong[] dim553JoeKuoD5Init = { 1, 1, 5, 9, 31, 47, 63, 225, 371, 453, 1075, 2293, 3323, 0 }; - static ulong[] dim554JoeKuoD5Init = { 1, 3, 1, 9, 31, 29, 67, 227, 135, 369, 481, 187, 3237, 0 }; - static ulong[] dim555JoeKuoD5Init = { 1, 3, 1, 7, 1, 29, 49, 157, 99, 741, 279, 1963, 7881, 0 }; - static ulong[] dim556JoeKuoD5Init = { 1, 3, 5, 13, 17, 49, 33, 73, 103, 941, 209, 1329, 3, 0 }; - static ulong[] dim557JoeKuoD5Init = { 1, 1, 1, 1, 17, 41, 53, 57, 163, 761, 1855, 3423, 5317, 0 }; - static ulong[] dim558JoeKuoD5Init = { 1, 1, 5, 1, 11, 13, 59, 37, 351, 561, 1213, 2355, 8095, 0 }; - static ulong[] dim559JoeKuoD5Init = { 1, 3, 5, 3, 3, 31, 47, 237, 101, 167, 1623, 645, 4787, 0 }; - static ulong[] dim560JoeKuoD5Init = { 1, 1, 3, 9, 21, 33, 55, 15, 433, 129, 279, 2131, 2943, 0 }; - static ulong[] dim561JoeKuoD5Init = { 1, 1, 7, 13, 9, 55, 71, 151, 273, 901, 427, 3749, 8163, 0 }; - static ulong[] dim562JoeKuoD5Init = { 1, 1, 1, 13, 13, 63, 11, 63, 477, 743, 1391, 2045, 6985, 0 }; - static ulong[] dim563JoeKuoD5Init = { 1, 3, 3, 11, 31, 25, 93, 217, 39, 263, 1411, 3, 7313, 0 }; - static ulong[] dim564JoeKuoD5Init = { 1, 1, 7, 1, 21, 13, 3, 255, 107, 851, 1281, 959, 3955, 0 }; - static ulong[] dim565JoeKuoD5Init = { 1, 3, 3, 9, 19, 55, 53, 201, 199, 361, 805, 579, 1459, 0 }; - static ulong[] dim566JoeKuoD5Init = { 1, 3, 3, 15, 9, 59, 109, 245, 29, 21, 137, 717, 607, 0 }; - static ulong[] dim567JoeKuoD5Init = { 1, 3, 3, 11, 15, 23, 49, 3, 195, 185, 85, 3885, 5859, 0 }; - static ulong[] dim568JoeKuoD5Init = { 1, 1, 3, 3, 13, 21, 7, 65, 185, 541, 305, 79, 3125, 0 }; - static ulong[] dim569JoeKuoD5Init = { 1, 3, 3, 3, 7, 59, 11, 125, 127, 283, 943, 3545, 1617, 0 }; - static ulong[] dim570JoeKuoD5Init = { 1, 1, 3, 3, 19, 39, 73, 167, 431, 147, 3, 1099, 6311, 0 }; - static ulong[] dim571JoeKuoD5Init = { 1, 1, 7, 13, 29, 57, 109, 169, 49, 457, 469, 3093, 7505, 0 }; - static ulong[] dim572JoeKuoD5Init = { 1, 3, 1, 1, 15, 29, 69, 133, 423, 737, 673, 2529, 2065, 0 }; - static ulong[] dim573JoeKuoD5Init = { 1, 3, 7, 7, 21, 47, 15, 175, 17, 419, 1917, 1183, 429, 0 }; - static ulong[] dim574JoeKuoD5Init = { 1, 3, 3, 9, 31, 43, 19, 63, 395, 331, 385, 3879, 3233, 0 }; - static ulong[] dim575JoeKuoD5Init = { 1, 1, 1, 9, 5, 11, 101, 65, 315, 805, 719, 641, 343, 0 }; - static ulong[] dim576JoeKuoD5Init = { 1, 1, 3, 1, 15, 5, 17, 115, 503, 395, 531, 1201, 7225, 0 }; - static ulong[] dim577JoeKuoD5Init = { 1, 3, 1, 7, 3, 35, 29, 1, 297, 421, 1365, 1491, 7973, 0 }; - static ulong[] dim578JoeKuoD5Init = { 1, 1, 1, 13, 1, 59, 79, 13, 337, 717, 1229, 2587, 5659, 0 }; - static ulong[] dim579JoeKuoD5Init = { 1, 3, 7, 9, 21, 15, 27, 19, 195, 27, 267, 381, 1969, 0 }; - static ulong[] dim580JoeKuoD5Init = { 1, 3, 7, 7, 25, 63, 119, 155, 243, 229, 897, 629, 7515, 0 }; - static ulong[] dim581JoeKuoD5Init = { 1, 1, 7, 1, 13, 37, 35, 31, 485, 729, 123, 1645, 457, 0 }; - static ulong[] dim582JoeKuoD5Init = { 1, 3, 5, 11, 17, 15, 47, 149, 311, 189, 1925, 9, 7639, 0 }; - static ulong[] dim583JoeKuoD5Init = { 1, 1, 1, 3, 1, 1, 127, 197, 109, 49, 265, 3643, 3629, 0 }; - static ulong[] dim584JoeKuoD5Init = { 1, 1, 3, 15, 21, 49, 71, 187, 189, 631, 1449, 775, 5973, 0 }; - static ulong[] dim585JoeKuoD5Init = { 1, 3, 5, 5, 27, 15, 17, 137, 393, 807, 1189, 2731, 6337, 0 }; - static ulong[] dim586JoeKuoD5Init = { 1, 3, 1, 11, 3, 43, 3, 77, 487, 539, 1781, 3261, 2775, 0 }; - static ulong[] dim587JoeKuoD5Init = { 1, 1, 1, 13, 29, 31, 83, 225, 159, 971, 1899, 1035, 5383, 0 }; - static ulong[] dim588JoeKuoD5Init = { 1, 3, 1, 7, 27, 1, 15, 141, 485, 639, 1895, 3129, 4489, 0 }; - static ulong[] dim589JoeKuoD5Init = { 1, 3, 3, 5, 9, 17, 21, 231, 363, 637, 1851, 3675, 5371, 0 }; - static ulong[] dim590JoeKuoD5Init = { 1, 3, 7, 11, 9, 17, 91, 243, 51, 565, 491, 3333, 3329, 0 }; - static ulong[] dim591JoeKuoD5Init = { 1, 1, 5, 3, 13, 9, 19, 227, 353, 111, 1805, 3917, 6849, 0 }; - static ulong[] dim592JoeKuoD5Init = { 1, 1, 1, 1, 29, 31, 27, 57, 421, 155, 1385, 999, 1581, 0 }; - static ulong[] dim593JoeKuoD5Init = { 1, 3, 5, 7, 1, 55, 35, 35, 311, 357, 1569, 2693, 2251, 0 }; - static ulong[] dim594JoeKuoD5Init = { 1, 3, 1, 9, 27, 41, 111, 119, 265, 165, 1999, 2067, 7801, 0 }; - static ulong[] dim595JoeKuoD5Init = { 1, 3, 5, 15, 31, 55, 31, 39, 305, 581, 373, 2523, 2153, 0 }; - static ulong[] dim596JoeKuoD5Init = { 1, 3, 5, 7, 9, 19, 115, 41, 261, 209, 897, 409, 5201, 0 }; - static ulong[] dim597JoeKuoD5Init = { 1, 3, 7, 13, 3, 15, 95, 143, 407, 719, 1763, 1763, 1173, 0 }; - static ulong[] dim598JoeKuoD5Init = { 1, 1, 5, 11, 17, 13, 69, 17, 293, 815, 1361, 259, 6751, 0 }; - static ulong[] dim599JoeKuoD5Init = { 1, 1, 3, 15, 11, 53, 13, 195, 153, 445, 1873, 1159, 4739, 0 }; - static ulong[] dim600JoeKuoD5Init = { 1, 3, 5, 7, 3, 25, 57, 229, 269, 299, 1687, 2707, 7049, 0 }; - static ulong[] dim601JoeKuoD5Init = { 1, 3, 3, 1, 5, 23, 89, 171, 207, 523, 2031, 2513, 2475, 0 }; - static ulong[] dim602JoeKuoD5Init = { 1, 1, 1, 7, 25, 57, 125, 109, 203, 671, 781, 295, 4001, 0 }; - static ulong[] dim603JoeKuoD5Init = { 1, 1, 1, 3, 17, 37, 51, 169, 441, 797, 871, 3267, 5695, 0 }; - static ulong[] dim604JoeKuoD5Init = { 1, 1, 3, 5, 17, 25, 97, 41, 377, 643, 1463, 141, 3961, 0 }; - static ulong[] dim605JoeKuoD5Init = { 1, 1, 5, 1, 17, 35, 111, 91, 253, 237, 1491, 2839, 2265, 0 }; - static ulong[] dim606JoeKuoD5Init = { 1, 1, 7, 13, 23, 7, 47, 61, 263, 591, 1365, 2371, 4209, 0 }; - static ulong[] dim607JoeKuoD5Init = { 1, 3, 3, 5, 7, 51, 117, 161, 383, 303, 1765, 3105, 3961, 0 }; - static ulong[] dim608JoeKuoD5Init = { 1, 1, 5, 11, 11, 55, 111, 55, 417, 713, 305, 1781, 5283, 0 }; - static ulong[] dim609JoeKuoD5Init = { 1, 1, 3, 11, 25, 51, 17, 215, 335, 47, 1789, 2049, 5349, 0 }; - static ulong[] dim610JoeKuoD5Init = { 1, 3, 3, 3, 1, 9, 71, 105, 397, 517, 1093, 765, 5301, 0 }; - static ulong[] dim611JoeKuoD5Init = { 1, 1, 7, 9, 31, 41, 95, 153, 383, 91, 1649, 3059, 6135, 0 }; - static ulong[] dim612JoeKuoD5Init = { 1, 1, 5, 11, 19, 51, 67, 119, 507, 179, 571, 2767, 5517, 0 }; - static ulong[] dim613JoeKuoD5Init = { 1, 3, 5, 9, 13, 19, 35, 249, 39, 425, 233, 1635, 5915, 0 }; - static ulong[] dim614JoeKuoD5Init = { 1, 1, 1, 11, 17, 15, 43, 29, 351, 25, 1879, 3941, 189, 0 }; - static ulong[] dim615JoeKuoD5Init = { 1, 3, 5, 5, 13, 55, 9, 7, 91, 951, 1681, 2723, 4349, 0 }; - static ulong[] dim616JoeKuoD5Init = { 1, 3, 1, 9, 27, 31, 49, 33, 287, 629, 851, 1353, 6391, 0 }; - static ulong[] dim617JoeKuoD5Init = { 1, 1, 5, 7, 19, 27, 45, 209, 257, 141, 1771, 931, 7839, 0 }; - static ulong[] dim618JoeKuoD5Init = { 1, 1, 5, 1, 9, 47, 87, 71, 183, 249, 311, 1989, 1753, 0 }; - static ulong[] dim619JoeKuoD5Init = { 1, 3, 5, 5, 7, 35, 45, 199, 207, 203, 831, 2643, 1155, 0 }; - static ulong[] dim620JoeKuoD5Init = { 1, 1, 1, 11, 5, 11, 27, 187, 405, 747, 261, 1279, 6153, 0 }; - static ulong[] dim621JoeKuoD5Init = { 1, 1, 5, 9, 7, 43, 23, 117, 421, 775, 1657, 1071, 4551, 0 }; - static ulong[] dim622JoeKuoD5Init = { 1, 1, 7, 9, 1, 51, 5, 27, 121, 459, 1251, 901, 2301, 0 }; - static ulong[] dim623JoeKuoD5Init = { 1, 3, 3, 11, 15, 47, 107, 93, 79, 719, 571, 65, 7589, 0 }; - static ulong[] dim624JoeKuoD5Init = { 1, 3, 5, 3, 19, 33, 103, 253, 469, 109, 913, 2251, 4737, 0 }; - static ulong[] dim625JoeKuoD5Init = { 1, 3, 3, 5, 23, 29, 89, 79, 253, 513, 723, 3823, 5769, 0 }; - static ulong[] dim626JoeKuoD5Init = { 1, 1, 7, 1, 27, 3, 103, 171, 353, 673, 1147, 529, 4737, 0 }; - static ulong[] dim627JoeKuoD5Init = { 1, 3, 7, 7, 27, 5, 103, 61, 101, 759, 443, 2003, 5537, 0 }; - static ulong[] dim628JoeKuoD5Init = { 1, 1, 1, 5, 11, 15, 109, 119, 473, 585, 1759, 319, 5461, 0 }; - static ulong[] dim629JoeKuoD5Init = { 1, 3, 7, 9, 19, 61, 5, 255, 171, 843, 823, 2713, 5313, 0 }; - static ulong[] dim630JoeKuoD5Init = { 1, 3, 7, 3, 9, 11, 57, 3, 365, 471, 1179, 1999, 3333, 0 }; - static ulong[] dim631JoeKuoD5Init = { 1, 3, 7, 9, 1, 3, 3, 195, 441, 193, 1905, 1753, 1839, 0 }; - static ulong[] dim632JoeKuoD5Init = { 1, 3, 1, 3, 1, 49, 99, 85, 175, 603, 1569, 2201, 1979, 0 }; - static ulong[] dim633JoeKuoD5Init = { 1, 1, 3, 5, 27, 37, 61, 137, 219, 469, 973, 1979, 1135, 0 }; - static ulong[] dim634JoeKuoD5Init = { 1, 1, 3, 13, 3, 59, 11, 203, 415, 513, 1469, 1655, 5913, 0 }; - static ulong[] dim635JoeKuoD5Init = { 1, 1, 3, 7, 21, 23, 87, 83, 21, 351, 899, 1633, 6589, 0 }; - static ulong[] dim636JoeKuoD5Init = { 1, 1, 7, 5, 5, 63, 45, 201, 193, 27, 1365, 1197, 1729, 0 }; - static ulong[] dim637JoeKuoD5Init = { 1, 3, 3, 5, 1, 35, 59, 157, 295, 359, 383, 3191, 7019, 0 }; - static ulong[] dim638JoeKuoD5Init = { 1, 1, 1, 13, 3, 23, 17, 149, 59, 115, 1101, 1879, 4243, 0 }; - static ulong[] dim639JoeKuoD5Init = { 1, 3, 3, 5, 3, 21, 71, 31, 85, 93, 1691, 379, 7901, 0 }; - static ulong[] dim640JoeKuoD5Init = { 1, 1, 7, 13, 15, 7, 29, 59, 191, 817, 439, 453, 5073, 0 }; - static ulong[] dim641JoeKuoD5Init = { 1, 3, 3, 9, 29, 7, 119, 35, 393, 9, 509, 3907, 7031, 0 }; - static ulong[] dim642JoeKuoD5Init = { 1, 3, 1, 3, 29, 51, 19, 127, 399, 309, 117, 3491, 5417, 0 }; - static ulong[] dim643JoeKuoD5Init = { 1, 1, 7, 5, 31, 33, 17, 119, 365, 301, 527, 3341, 779, 0 }; - static ulong[] dim644JoeKuoD5Init = { 1, 3, 5, 1, 29, 41, 43, 85, 133, 191, 229, 3407, 3147, 0 }; - static ulong[] dim645JoeKuoD5Init = { 1, 1, 7, 3, 7, 9, 49, 121, 193, 569, 467, 999, 6813, 0 }; - static ulong[] dim646JoeKuoD5Init = { 1, 1, 3, 13, 7, 23, 121, 43, 173, 761, 525, 3221, 5435, 0 }; - static ulong[] dim647JoeKuoD5Init = { 1, 3, 3, 3, 15, 43, 47, 149, 227, 357, 1219, 4087, 1215, 0 }; - static ulong[] dim648JoeKuoD5Init = { 1, 1, 3, 15, 1, 33, 81, 195, 201, 307, 1081, 3201, 4293, 0 }; - static ulong[] dim649JoeKuoD5Init = { 1, 3, 5, 11, 11, 1, 125, 119, 105, 783, 117, 3465, 5713, 0 }; - static ulong[] dim650JoeKuoD5Init = { 1, 1, 3, 1, 1, 51, 17, 141, 107, 875, 1135, 1213, 7113, 0 }; - static ulong[] dim651JoeKuoD5Init = { 1, 1, 1, 1, 7, 41, 63, 91, 465, 893, 1663, 2717, 6313, 0 }; - static ulong[] dim652JoeKuoD5Init = { 1, 3, 1, 15, 23, 43, 77, 49, 131, 953, 1591, 869, 3779, 0 }; - static ulong[] dim653JoeKuoD5Init = { 1, 1, 7, 15, 5, 9, 41, 183, 403, 775, 1163, 2963, 861, 0 }; - static ulong[] dim654JoeKuoD5Init = { 1, 3, 7, 11, 27, 19, 51, 139, 87, 315, 831, 2587, 4847, 0 }; - static ulong[] dim655JoeKuoD5Init = { 1, 3, 3, 13, 23, 23, 117, 189, 405, 735, 681, 457, 337, 0 }; - static ulong[] dim656JoeKuoD5Init = { 1, 1, 7, 5, 13, 21, 25, 207, 179, 715, 629, 593, 6351, 0 }; - static ulong[] dim657JoeKuoD5Init = { 1, 3, 3, 3, 25, 13, 31, 245, 147, 953, 1061, 3749, 6927, 0 }; - static ulong[] dim658JoeKuoD5Init = { 1, 3, 3, 9, 29, 27, 57, 5, 345, 471, 599, 3677, 1801, 0 }; - static ulong[] dim659JoeKuoD5Init = { 1, 1, 3, 5, 21, 47, 27, 21, 473, 881, 1973, 995, 6513, 0 }; - static ulong[] dim660JoeKuoD5Init = { 1, 1, 3, 7, 23, 1, 19, 197, 43, 955, 1503, 2825, 7241, 0 }; - static ulong[] dim661JoeKuoD5Init = { 1, 3, 7, 13, 5, 51, 51, 33, 349, 835, 1367, 1913, 1963, 0 }; - static ulong[] dim662JoeKuoD5Init = { 1, 1, 5, 5, 19, 63, 9, 145, 335, 843, 655, 1049, 3421, 0 }; - static ulong[] dim663JoeKuoD5Init = { 1, 1, 7, 1, 1, 33, 1, 9, 35, 833, 629, 3453, 6341, 0 }; - static ulong[] dim664JoeKuoD5Init = { 1, 3, 5, 11, 3, 55, 119, 87, 441, 43, 169, 761, 753, 0 }; - static ulong[] dim665JoeKuoD5Init = { 1, 3, 7, 5, 17, 11, 87, 165, 421, 1005, 1227, 3381, 1005, 0 }; - static ulong[] dim666JoeKuoD5Init = { 1, 3, 3, 13, 17, 19, 63, 71, 251, 355, 1127, 2575, 1193, 0 }; - static ulong[] dim667JoeKuoD5Init = { 1, 1, 7, 13, 9, 23, 71, 173, 421, 179, 1899, 2507, 8083, 0 }; - static ulong[] dim668JoeKuoD5Init = { 1, 1, 3, 15, 1, 13, 81, 169, 85, 957, 1109, 2767, 447, 0 }; - static ulong[] dim669JoeKuoD5Init = { 1, 3, 7, 15, 19, 41, 61, 247, 325, 273, 469, 1859, 6869, 0 }; - static ulong[] dim670JoeKuoD5Init = { 1, 1, 1, 9, 15, 3, 3, 119, 377, 579, 1155, 325, 143, 0 }; - static ulong[] dim671JoeKuoD5Init = { 1, 1, 3, 11, 31, 1, 43, 135, 375, 383, 1497, 2759, 43, 0 }; - static ulong[] dim672JoeKuoD5Init = { 1, 1, 5, 5, 1, 63, 75, 179, 447, 113, 1037, 631, 4969, 0 }; - static ulong[] dim673JoeKuoD5Init = { 1, 3, 3, 13, 13, 61, 63, 229, 85, 223, 153, 3987, 4685, 0 }; - static ulong[] dim674JoeKuoD5Init = { 1, 1, 7, 13, 17, 33, 17, 247, 399, 559, 369, 1525, 4923, 0 }; - static ulong[] dim675JoeKuoD5Init = { 1, 3, 3, 13, 1, 63, 69, 167, 407, 191, 499, 1697, 3267, 0 }; - static ulong[] dim676JoeKuoD5Init = { 1, 1, 5, 9, 31, 15, 97, 183, 165, 271, 1465, 931, 4061, 0 }; - static ulong[] dim677JoeKuoD5Init = { 1, 3, 3, 1, 31, 7, 121, 37, 429, 375, 1539, 1383, 7317, 0 }; - static ulong[] dim678JoeKuoD5Init = { 1, 1, 5, 9, 13, 41, 49, 205, 233, 847, 187, 359, 2341, 0 }; - static ulong[] dim679JoeKuoD5Init = { 1, 1, 3, 5, 25, 5, 57, 119, 79, 131, 1707, 1601, 1657, 0 }; - static ulong[] dim680JoeKuoD5Init = { 1, 1, 5, 9, 21, 11, 89, 149, 369, 401, 623, 3001, 85, 0 }; - static ulong[] dim681JoeKuoD5Init = { 1, 3, 5, 15, 31, 9, 109, 33, 31, 93, 2035, 3785, 5893, 0 }; - static ulong[] dim682JoeKuoD5Init = { 1, 3, 3, 3, 31, 57, 15, 161, 333, 559, 1487, 1037, 1055, 0 }; - static ulong[] dim683JoeKuoD5Init = { 1, 3, 5, 13, 7, 9, 7, 109, 151, 629, 295, 105, 1121, 0 }; - static ulong[] dim684JoeKuoD5Init = { 1, 3, 7, 3, 7, 25, 49, 5, 95, 321, 303, 2571, 6967, 0 }; - static ulong[] dim685JoeKuoD5Init = { 1, 1, 5, 3, 27, 13, 65, 27, 507, 847, 155, 3183, 5985, 0 }; - static ulong[] dim686JoeKuoD5Init = { 1, 3, 7, 9, 17, 29, 69, 23, 181, 855, 1659, 889, 1273, 0 }; - static ulong[] dim687JoeKuoD5Init = { 1, 1, 3, 5, 19, 41, 109, 97, 373, 591, 1715, 3927, 3101, 0 }; - static ulong[] dim688JoeKuoD5Init = { 1, 1, 3, 3, 9, 9, 75, 63, 1, 39, 941, 3677, 7253, 0 }; - static ulong[] dim689JoeKuoD5Init = { 1, 1, 1, 11, 27, 37, 25, 33, 213, 917, 2037, 145, 4395, 0 }; - static ulong[] dim690JoeKuoD5Init = { 1, 3, 7, 11, 23, 21, 15, 195, 87, 699, 1475, 429, 1641, 0 }; - static ulong[] dim691JoeKuoD5Init = { 1, 3, 3, 1, 1, 51, 117, 13, 369, 711, 625, 3171, 1867, 0 }; - static ulong[] dim692JoeKuoD5Init = { 1, 1, 1, 15, 23, 11, 47, 177, 511, 709, 255, 2355, 71, 0 }; - static ulong[] dim693JoeKuoD5Init = { 1, 1, 1, 9, 7, 21, 21, 35, 303, 105, 525, 589, 5449, 0 }; - static ulong[] dim694JoeKuoD5Init = { 1, 3, 7, 7, 21, 27, 71, 177, 205, 143, 385, 2949, 8169, 0 }; - static ulong[] dim695JoeKuoD5Init = { 1, 1, 3, 9, 19, 39, 79, 241, 103, 489, 1399, 2781, 5533, 0 }; - static ulong[] dim696JoeKuoD5Init = { 1, 1, 3, 5, 23, 9, 121, 51, 145, 927, 1457, 1891, 7475, 0 }; - static ulong[] dim697JoeKuoD5Init = { 1, 3, 7, 1, 7, 23, 67, 145, 161, 63, 569, 395, 6719, 0 }; - static ulong[] dim698JoeKuoD5Init = { 1, 3, 7, 11, 5, 31, 13, 9, 135, 367, 1591, 1963, 7249, 0 }; - static ulong[] dim699JoeKuoD5Init = { 1, 3, 5, 13, 7, 47, 119, 195, 439, 619, 551, 1955, 6913, 0 }; - static ulong[] dim700JoeKuoD5Init = { 1, 3, 1, 1, 29, 57, 43, 213, 113, 339, 1943, 183, 3063, 0 }; - static ulong[] dim701JoeKuoD5Init = { 1, 3, 1, 11, 1, 3, 57, 149, 495, 547, 603, 907, 1349, 0 }; - static ulong[] dim702JoeKuoD5Init = { 1, 3, 1, 7, 7, 31, 87, 49, 239, 827, 1451, 3171, 287, 0 }; - static ulong[] dim703JoeKuoD5Init = { 1, 3, 1, 15, 11, 41, 29, 233, 101, 573, 737, 3813, 7739, 0 }; - static ulong[] dim704JoeKuoD5Init = { 1, 1, 7, 9, 19, 13, 57, 177, 259, 595, 263, 2851, 5771, 0 }; - static ulong[] dim705JoeKuoD5Init = { 1, 1, 3, 13, 13, 5, 27, 133, 17, 725, 417, 2277, 5649, 0 }; - static ulong[] dim706JoeKuoD5Init = { 1, 1, 3, 13, 25, 57, 35, 229, 253, 761, 275, 2519, 7061, 0 }; - static ulong[] dim707JoeKuoD5Init = { 1, 3, 1, 13, 9, 31, 61, 181, 129, 259, 1569, 817, 4665, 0 }; - static ulong[] dim708JoeKuoD5Init = { 1, 1, 1, 5, 23, 3, 69, 161, 429, 143, 455, 905, 3337, 0 }; - static ulong[] dim709JoeKuoD5Init = { 1, 3, 3, 3, 21, 33, 81, 187, 481, 481, 1947, 3563, 4797, 0 }; - static ulong[] dim710JoeKuoD5Init = { 1, 1, 3, 7, 15, 35, 23, 187, 455, 535, 85, 1067, 1793, 0 }; - static ulong[] dim711JoeKuoD5Init = { 1, 3, 5, 3, 11, 17, 89, 255, 443, 791, 1617, 2979, 1357, 0 }; - static ulong[] dim712JoeKuoD5Init = { 1, 3, 3, 15, 17, 49, 1, 233, 3, 587, 1203, 3185, 1173, 0 }; - static ulong[] dim713JoeKuoD5Init = { 1, 1, 3, 9, 5, 53, 37, 13, 47, 1011, 1589, 1073, 5445, 0 }; - static ulong[] dim714JoeKuoD5Init = { 1, 1, 5, 1, 15, 43, 85, 167, 347, 935, 1681, 261, 3623, 0 }; - static ulong[] dim715JoeKuoD5Init = { 1, 1, 3, 3, 3, 31, 121, 241, 129, 555, 1737, 3557, 6515, 0 }; - static ulong[] dim716JoeKuoD5Init = { 1, 3, 1, 15, 25, 7, 125, 105, 13, 927, 1929, 3869, 7429, 0 }; - static ulong[] dim717JoeKuoD5Init = { 1, 3, 5, 1, 31, 47, 3, 29, 149, 827, 771, 2113, 1607, 0 }; - static ulong[] dim718JoeKuoD5Init = { 1, 3, 5, 1, 17, 17, 65, 247, 109, 613, 1975, 2393, 6057, 0 }; - static ulong[] dim719JoeKuoD5Init = { 1, 3, 1, 7, 9, 43, 41, 119, 335, 533, 1053, 1343, 6529, 0 }; - static ulong[] dim720JoeKuoD5Init = { 1, 3, 3, 1, 31, 59, 85, 247, 485, 811, 749, 89, 6677, 0 }; - static ulong[] dim721JoeKuoD5Init = { 1, 1, 7, 13, 7, 47, 77, 193, 25, 27, 639, 109, 6455, 0 }; - static ulong[] dim722JoeKuoD5Init = { 1, 1, 7, 1, 15, 63, 17, 81, 425, 403, 1537, 3205, 6237, 0 }; - static ulong[] dim723JoeKuoD5Init = { 1, 3, 5, 9, 21, 29, 105, 135, 407, 119, 793, 559, 973, 0 }; - static ulong[] dim724JoeKuoD5Init = { 1, 3, 3, 15, 1, 31, 45, 97, 511, 463, 1923, 2487, 1311, 0 }; - static ulong[] dim725JoeKuoD5Init = { 1, 1, 3, 11, 13, 53, 91, 149, 441, 841, 1121, 3305, 975, 0 }; - static ulong[] dim726JoeKuoD5Init = { 1, 1, 3, 15, 5, 55, 81, 181, 333, 63, 1157, 2831, 6231, 0 }; - static ulong[] dim727JoeKuoD5Init = { 1, 1, 3, 15, 29, 21, 69, 87, 41, 623, 475, 723, 5693, 0 }; - static ulong[] dim728JoeKuoD5Init = { 1, 3, 1, 5, 23, 19, 15, 25, 269, 79, 1699, 691, 525, 0 }; - static ulong[] dim729JoeKuoD5Init = { 1, 3, 1, 1, 29, 23, 85, 5, 431, 649, 1187, 3503, 105, 0 }; - static ulong[] dim730JoeKuoD5Init = { 1, 1, 1, 1, 27, 59, 1, 81, 351, 383, 1167, 3747, 5935, 0 }; - static ulong[] dim731JoeKuoD5Init = { 1, 1, 1, 13, 21, 49, 93, 5, 471, 231, 1469, 1089, 5059, 0 }; - static ulong[] dim732JoeKuoD5Init = { 1, 3, 1, 11, 31, 61, 117, 161, 307, 621, 1713, 1325, 283, 0 }; - static ulong[] dim733JoeKuoD5Init = { 1, 3, 1, 7, 21, 35, 7, 79, 157, 723, 57, 25, 2789, 0 }; - static ulong[] dim734JoeKuoD5Init = { 1, 3, 5, 13, 9, 47, 97, 1, 257, 941, 553, 3811, 3775, 0 }; - static ulong[] dim735JoeKuoD5Init = { 1, 3, 3, 13, 19, 5, 73, 233, 289, 241, 175, 2831, 4613, 0 }; - static ulong[] dim736JoeKuoD5Init = { 1, 1, 1, 9, 11, 61, 1, 245, 223, 641, 77, 1811, 3459, 0 }; - static ulong[] dim737JoeKuoD5Init = { 1, 1, 7, 1, 21, 41, 9, 175, 377, 331, 1615, 325, 5413, 0 }; - static ulong[] dim738JoeKuoD5Init = { 1, 1, 1, 3, 23, 57, 99, 161, 127, 47, 1923, 165, 2123, 0 }; - static ulong[] dim739JoeKuoD5Init = { 1, 1, 5, 15, 11, 15, 77, 15, 323, 919, 1001, 377, 6095, 0 }; - static ulong[] dim740JoeKuoD5Init = { 1, 1, 7, 7, 25, 47, 5, 25, 197, 811, 179, 215, 5393, 0 }; - static ulong[] dim741JoeKuoD5Init = { 1, 3, 5, 11, 29, 37, 7, 125, 3, 7, 1881, 3823, 2117, 0 }; - static ulong[] dim742JoeKuoD5Init = { 1, 3, 7, 3, 9, 61, 97, 233, 233, 603, 511, 17, 2081, 0 }; - static ulong[] dim743JoeKuoD5Init = { 1, 3, 5, 9, 15, 35, 73, 199, 113, 575, 537, 883, 6897, 0 }; - static ulong[] dim744JoeKuoD5Init = { 1, 1, 3, 9, 17, 63, 7, 181, 261, 719, 591, 2575, 1065, 0 }; - static ulong[] dim745JoeKuoD5Init = { 1, 1, 7, 1, 13, 15, 1, 207, 385, 277, 547, 1069, 6421, 0 }; - static ulong[] dim746JoeKuoD5Init = { 1, 3, 7, 3, 5, 3, 43, 213, 509, 969, 1799, 3519, 7759, 0 }; - static ulong[] dim747JoeKuoD5Init = { 1, 3, 7, 15, 29, 51, 87, 63, 257, 1001, 741, 1747, 975, 0 }; - static ulong[] dim748JoeKuoD5Init = { 1, 3, 1, 15, 5, 27, 7, 27, 493, 817, 319, 1435, 3243, 0 }; - static ulong[] dim749JoeKuoD5Init = { 1, 3, 3, 15, 5, 9, 113, 153, 397, 63, 2037, 3319, 6355, 0 }; - static ulong[] dim750JoeKuoD5Init = { 1, 1, 1, 1, 29, 9, 97, 171, 113, 729, 1939, 2741, 4699, 0 }; - static ulong[] dim751JoeKuoD5Init = { 1, 1, 1, 11, 29, 3, 49, 183, 69, 313, 153, 2757, 3353, 0 }; - static ulong[] dim752JoeKuoD5Init = { 1, 1, 7, 7, 5, 39, 65, 65, 405, 301, 849, 1211, 3627, 0 }; - static ulong[] dim753JoeKuoD5Init = { 1, 1, 5, 13, 19, 11, 81, 181, 471, 669, 139, 4019, 4057, 0 }; - static ulong[] dim754JoeKuoD5Init = { 1, 3, 3, 13, 3, 31, 125, 229, 181, 913, 2035, 2081, 6573, 0 }; - static ulong[] dim755JoeKuoD5Init = { 1, 1, 1, 5, 13, 25, 37, 209, 255, 761, 1485, 2833, 6617, 0 }; - static ulong[] dim756JoeKuoD5Init = { 1, 1, 5, 7, 29, 17, 55, 59, 337, 953, 775, 3865, 5671, 0 }; - static ulong[] dim757JoeKuoD5Init = { 1, 1, 7, 13, 15, 37, 109, 93, 303, 57, 1727, 615, 3337, 0 }; - static ulong[] dim758JoeKuoD5Init = { 1, 1, 1, 13, 31, 57, 119, 57, 295, 707, 1409, 3769, 6359, 0 }; - static ulong[] dim759JoeKuoD5Init = { 1, 3, 1, 5, 31, 25, 35, 191, 27, 463, 875, 129, 3829, 0 }; - static ulong[] dim760JoeKuoD5Init = { 1, 1, 5, 13, 19, 29, 95, 227, 487, 519, 289, 965, 2121, 0 }; - static ulong[] dim761JoeKuoD5Init = { 1, 3, 5, 5, 21, 37, 7, 43, 213, 673, 25, 1911, 7229, 0 }; - static ulong[] dim762JoeKuoD5Init = { 1, 1, 1, 5, 9, 55, 115, 155, 119, 49, 653, 3425, 299, 0 }; - static ulong[] dim763JoeKuoD5Init = { 1, 1, 1, 11, 7, 55, 65, 21, 93, 295, 1097, 145, 3401, 0 }; - static ulong[] dim764JoeKuoD5Init = { 1, 3, 3, 3, 1, 19, 109, 247, 499, 391, 309, 59, 695, 0 }; - static ulong[] dim765JoeKuoD5Init = { 1, 1, 5, 5, 9, 37, 113, 233, 57, 955, 437, 775, 2673, 0 }; - static ulong[] dim766JoeKuoD5Init = { 1, 3, 7, 3, 5, 27, 57, 53, 149, 929, 41, 1473, 4751, 0 }; - static ulong[] dim767JoeKuoD5Init = { 1, 1, 7, 11, 5, 3, 107, 57, 3, 727, 2001, 3463, 4753, 0 }; - static ulong[] dim768JoeKuoD5Init = { 1, 1, 1, 11, 3, 37, 111, 97, 225, 809, 135, 2049, 2373, 0 }; - static ulong[] dim769JoeKuoD5Init = { 1, 3, 5, 15, 3, 37, 57, 153, 175, 851, 137, 495, 4423, 0 }; - static ulong[] dim770JoeKuoD5Init = { 1, 3, 3, 7, 25, 31, 53, 51, 421, 33, 1241, 2157, 867, 0 }; - static ulong[] dim771JoeKuoD5Init = { 1, 1, 1, 13, 3, 33, 15, 77, 73, 51, 1131, 3387, 7935, 0 }; - static ulong[] dim772JoeKuoD5Init = { 1, 1, 5, 9, 11, 25, 27, 235, 341, 133, 261, 2087, 4079, 0 }; - static ulong[] dim773JoeKuoD5Init = { 1, 3, 3, 13, 11, 63, 33, 99, 65, 485, 561, 2269, 8143, 0 }; - static ulong[] dim774JoeKuoD5Init = { 1, 3, 3, 5, 13, 25, 53, 65, 59, 861, 1705, 627, 1097, 0 }; - static ulong[] dim775JoeKuoD5Init = { 1, 3, 1, 3, 25, 15, 67, 187, 161, 747, 947, 4029, 7547, 0 }; - static ulong[] dim776JoeKuoD5Init = { 1, 3, 3, 5, 7, 27, 119, 239, 197, 165, 457, 1927, 6195, 0 }; - static ulong[] dim777JoeKuoD5Init = { 1, 3, 3, 7, 27, 21, 23, 93, 319, 551, 1317, 69, 6735, 0 }; - static ulong[] dim778JoeKuoD5Init = { 1, 1, 5, 11, 25, 45, 23, 127, 327, 949, 1451, 2245, 6705, 0 }; - static ulong[] dim779JoeKuoD5Init = { 1, 1, 1, 15, 19, 23, 69, 113, 53, 215, 1505, 1255, 5063, 0 }; - static ulong[] dim780JoeKuoD5Init = { 1, 3, 3, 9, 7, 19, 39, 135, 437, 251, 1947, 2219, 4015, 0 }; - static ulong[] dim781JoeKuoD5Init = { 1, 3, 7, 3, 23, 39, 91, 111, 395, 545, 179, 937, 2531, 0 }; - static ulong[] dim782JoeKuoD5Init = { 1, 3, 7, 11, 1, 53, 113, 137, 131, 461, 151, 1617, 6399, 0 }; - static ulong[] dim783JoeKuoD5Init = { 1, 1, 3, 3, 13, 3, 75, 31, 175, 773, 1293, 625, 6563, 0 }; - static ulong[] dim784JoeKuoD5Init = { 1, 1, 3, 15, 9, 51, 87, 223, 405, 751, 1053, 1431, 4701, 0 }; - static ulong[] dim785JoeKuoD5Init = { 1, 1, 3, 13, 21, 21, 111, 145, 311, 733, 635, 1369, 297, 0 }; - static ulong[] dim786JoeKuoD5Init = { 1, 1, 1, 7, 25, 5, 23, 201, 179, 593, 1531, 1197, 3525, 0 }; - static ulong[] dim787JoeKuoD5Init = { 1, 1, 5, 13, 7, 17, 19, 247, 401, 15, 93, 245, 5987, 0 }; - static ulong[] dim788JoeKuoD5Init = { 1, 3, 3, 11, 7, 45, 119, 99, 197, 163, 637, 3143, 1775, 0 }; - static ulong[] dim789JoeKuoD5Init = { 1, 1, 3, 3, 17, 7, 35, 121, 155, 925, 1001, 2941, 107, 0 }; - static ulong[] dim790JoeKuoD5Init = { 1, 3, 7, 15, 15, 3, 89, 205, 171, 279, 763, 2343, 7825, 0 }; - static ulong[] dim791JoeKuoD5Init = { 1, 3, 1, 15, 15, 3, 113, 135, 159, 217, 139, 167, 589, 0 }; - static ulong[] dim792JoeKuoD5Init = { 1, 3, 3, 1, 31, 59, 89, 3, 261, 953, 1527, 447, 1211, 0 }; - static ulong[] dim793JoeKuoD5Init = { 1, 1, 5, 9, 31, 39, 93, 171, 497, 657, 809, 2905, 2399, 0 }; - static ulong[] dim794JoeKuoD5Init = { 1, 1, 5, 15, 27, 19, 25, 179, 293, 829, 1197, 3077, 6631, 0 }; - static ulong[] dim795JoeKuoD5Init = { 1, 1, 1, 7, 31, 55, 53, 177, 157, 619, 197, 3675, 4691, 0 }; - static ulong[] dim796JoeKuoD5Init = { 1, 3, 7, 5, 7, 33, 85, 59, 435, 653, 1363, 731, 3923, 0 }; - static ulong[] dim797JoeKuoD5Init = { 1, 3, 3, 3, 15, 35, 15, 217, 333, 717, 143, 4071, 4769, 0 }; - static ulong[] dim798JoeKuoD5Init = { 1, 1, 5, 7, 23, 31, 65, 77, 261, 389, 1733, 4077, 3387, 0 }; - static ulong[] dim799JoeKuoD5Init = { 1, 1, 7, 9, 21, 45, 21, 103, 163, 237, 1447, 141, 3995, 0 }; - static ulong[] dim800JoeKuoD5Init = { 1, 1, 3, 3, 27, 35, 61, 149, 359, 131, 1309, 3283, 5905, 0 }; - static ulong[] dim801JoeKuoD5Init = { 1, 3, 1, 15, 9, 15, 99, 43, 115, 871, 419, 2787, 7741, 0 }; - static ulong[] dim802JoeKuoD5Init = { 1, 3, 7, 5, 1, 45, 31, 87, 165, 103, 2041, 1529, 5721, 0 }; - static ulong[] dim803JoeKuoD5Init = { 1, 3, 5, 15, 3, 11, 107, 9, 367, 401, 1571, 2657, 4745, 0 }; - static ulong[] dim804JoeKuoD5Init = { 1, 1, 5, 13, 31, 51, 35, 53, 131, 441, 1421, 2367, 7713, 0 }; - static ulong[] dim805JoeKuoD5Init = { 1, 3, 1, 5, 21, 49, 109, 117, 263, 827, 1975, 2639, 1249, 0 }; - static ulong[] dim806JoeKuoD5Init = { 1, 1, 5, 13, 7, 3, 87, 185, 493, 721, 1363, 2201, 1067, 0 }; - static ulong[] dim807JoeKuoD5Init = { 1, 1, 3, 5, 13, 41, 113, 105, 111, 65, 705, 4079, 2461, 0 }; - static ulong[] dim808JoeKuoD5Init = { 1, 1, 7, 13, 9, 1, 75, 103, 181, 587, 1531, 461, 6551, 0 }; - static ulong[] dim809JoeKuoD5Init = { 1, 1, 7, 11, 13, 43, 19, 131, 233, 209, 175, 625, 985, 0 }; - static ulong[] dim810JoeKuoD5Init = { 1, 1, 1, 11, 23, 1, 87, 233, 355, 765, 869, 2569, 5919, 0 }; - static ulong[] dim811JoeKuoD5Init = { 1, 1, 7, 5, 13, 27, 41, 127, 105, 299, 189, 3801, 4677, 0 }; - static ulong[] dim812JoeKuoD5Init = { 1, 3, 3, 13, 21, 49, 111, 95, 27, 433, 1715, 1167, 4943, 0 }; - static ulong[] dim813JoeKuoD5Init = { 1, 3, 1, 11, 5, 17, 93, 91, 79, 355, 111, 1159, 4629, 0 }; - static ulong[] dim814JoeKuoD5Init = { 1, 1, 7, 1, 29, 43, 107, 91, 111, 813, 537, 97, 5337, 0 }; - static ulong[] dim815JoeKuoD5Init = { 1, 3, 3, 5, 27, 1, 69, 181, 247, 51, 409, 1965, 4709, 0 }; - static ulong[] dim816JoeKuoD5Init = { 1, 3, 5, 1, 7, 53, 119, 109, 331, 189, 761, 385, 5227, 0 }; - static ulong[] dim817JoeKuoD5Init = { 1, 3, 5, 15, 5, 61, 57, 3, 157, 737, 1605, 3701, 1069, 0 }; - static ulong[] dim818JoeKuoD5Init = { 1, 3, 5, 1, 17, 27, 89, 235, 53, 521, 1975, 1383, 467, 0 }; - static ulong[] dim819JoeKuoD5Init = { 1, 1, 3, 7, 25, 25, 39, 149, 157, 385, 1651, 105, 1487, 0 }; - static ulong[] dim820JoeKuoD5Init = { 1, 3, 3, 7, 15, 43, 37, 167, 303, 655, 331, 1595, 5405, 0 }; - static ulong[] dim821JoeKuoD5Init = { 1, 3, 7, 9, 13, 29, 13, 163, 405, 903, 1277, 985, 1479, 0 }; - static ulong[] dim822JoeKuoD5Init = { 1, 1, 7, 13, 1, 7, 61, 9, 163, 67, 209, 1923, 6587, 0 }; - static ulong[] dim823JoeKuoD5Init = { 1, 1, 5, 15, 13, 3, 99, 177, 507, 1017, 1565, 757, 5829, 0 }; - static ulong[] dim824JoeKuoD5Init = { 1, 3, 5, 11, 7, 49, 51, 71, 177, 1015, 1321, 187, 875, 0 }; - static ulong[] dim825JoeKuoD5Init = { 1, 1, 7, 1, 29, 49, 111, 143, 99, 297, 659, 3147, 7531, 0 }; - static ulong[] dim826JoeKuoD5Init = { 1, 1, 5, 3, 15, 21, 11, 229, 249, 185, 147, 173, 7895, 0 }; - static ulong[] dim827JoeKuoD5Init = { 1, 1, 7, 1, 17, 23, 123, 157, 373, 501, 411, 2487, 4873, 0 }; - static ulong[] dim828JoeKuoD5Init = { 1, 3, 7, 11, 21, 61, 83, 65, 345, 105, 1533, 981, 1635, 0 }; - static ulong[] dim829JoeKuoD5Init = { 1, 3, 3, 1, 15, 15, 19, 119, 59, 1003, 1595, 2871, 627, 0 }; - static ulong[] dim830JoeKuoD5Init = { 1, 1, 7, 3, 7, 47, 43, 3, 359, 175, 1149, 213, 79, 0 }; - static ulong[] dim831JoeKuoD5Init = { 1, 1, 1, 1, 5, 19, 7, 93, 335, 809, 1867, 1359, 1017, 0 }; - static ulong[] dim832JoeKuoD5Init = { 1, 1, 1, 11, 31, 25, 75, 139, 125, 479, 101, 3969, 1173, 0 }; - static ulong[] dim833JoeKuoD5Init = { 1, 3, 1, 3, 5, 17, 33, 145, 57, 31, 1033, 3975, 5561, 0 }; - static ulong[] dim834JoeKuoD5Init = { 1, 3, 7, 3, 31, 37, 47, 149, 341, 663, 303, 3395, 4327, 0 }; - static ulong[] dim835JoeKuoD5Init = { 1, 3, 5, 1, 31, 31, 37, 207, 189, 435, 347, 2791, 2203, 0 }; - static ulong[] dim836JoeKuoD5Init = { 1, 1, 7, 5, 3, 61, 71, 199, 207, 261, 27, 2281, 6215, 0 }; - static ulong[] dim837JoeKuoD5Init = { 1, 3, 3, 13, 19, 61, 51, 99, 279, 535, 473, 2233, 5637, 0 }; - static ulong[] dim838JoeKuoD5Init = { 1, 3, 5, 15, 7, 51, 25, 159, 63, 611, 1015, 3561, 5763, 0 }; - static ulong[] dim839JoeKuoD5Init = { 1, 3, 1, 7, 9, 13, 101, 13, 203, 733, 1657, 919, 7857, 0 }; - static ulong[] dim840JoeKuoD5Init = { 1, 3, 1, 9, 5, 7, 105, 137, 321, 817, 467, 4043, 603, 0 }; - static ulong[] dim841JoeKuoD5Init = { 1, 1, 7, 9, 5, 7, 105, 93, 295, 617, 713, 3075, 1839, 0 }; - static ulong[] dim842JoeKuoD5Init = { 1, 3, 3, 5, 11, 17, 89, 229, 417, 53, 693, 2101, 1293, 0 }; - static ulong[] dim843JoeKuoD5Init = { 1, 3, 7, 5, 3, 57, 95, 175, 161, 291, 219, 3101, 3387, 0 }; - static ulong[] dim844JoeKuoD5Init = { 1, 3, 1, 3, 25, 53, 89, 7, 9, 863, 675, 1011, 1753, 0 }; - static ulong[] dim845JoeKuoD5Init = { 1, 1, 5, 15, 13, 41, 57, 141, 109, 541, 387, 3805, 2219, 0 }; - static ulong[] dim846JoeKuoD5Init = { 1, 3, 7, 11, 19, 45, 45, 63, 283, 277, 1503, 3909, 4825, 0 }; - static ulong[] dim847JoeKuoD5Init = { 1, 3, 5, 13, 11, 27, 33, 245, 335, 785, 1651, 2503, 7247, 0 }; - static ulong[] dim848JoeKuoD5Init = { 1, 1, 3, 5, 19, 3, 29, 9, 259, 1023, 71, 3659, 3615, 0 }; - static ulong[] dim849JoeKuoD5Init = { 1, 3, 7, 9, 29, 41, 59, 137, 139, 193, 267, 3293, 4769, 0 }; - static ulong[] dim850JoeKuoD5Init = { 1, 3, 1, 5, 21, 29, 107, 227, 107, 929, 1009, 2013, 2791, 0 }; - static ulong[] dim851JoeKuoD5Init = { 1, 1, 3, 7, 25, 61, 105, 159, 125, 873, 293, 1475, 1745, 0 }; - static ulong[] dim852JoeKuoD5Init = { 1, 3, 1, 5, 13, 11, 63, 109, 329, 847, 521, 3045, 2673, 0 }; - static ulong[] dim853JoeKuoD5Init = { 1, 3, 7, 1, 21, 1, 15, 161, 369, 339, 417, 3165, 5047, 0 }; - static ulong[] dim854JoeKuoD5Init = { 1, 1, 1, 9, 31, 61, 109, 25, 491, 969, 1369, 403, 835, 0 }; - static ulong[] dim855JoeKuoD5Init = { 1, 1, 1, 9, 29, 29, 27, 55, 395, 979, 27, 3091, 2383, 0 }; - static ulong[] dim856JoeKuoD5Init = { 1, 1, 7, 1, 25, 17, 73, 117, 55, 381, 641, 2549, 7049, 0 }; - static ulong[] dim857JoeKuoD5Init = { 1, 3, 7, 11, 17, 5, 97, 89, 187, 973, 1343, 3777, 3549, 0 }; - static ulong[] dim858JoeKuoD5Init = { 1, 1, 7, 1, 9, 51, 49, 169, 135, 827, 1941, 3421, 2351, 0 }; - static ulong[] dim859JoeKuoD5Init = { 1, 1, 1, 11, 25, 59, 9, 63, 259, 551, 983, 2743, 3439, 0 }; - static ulong[] dim860JoeKuoD5Init = { 1, 3, 1, 5, 1, 55, 19, 35, 39, 629, 1601, 773, 3697, 0 }; - static ulong[] dim861JoeKuoD5Init = { 1, 1, 7, 7, 17, 59, 55, 201, 467, 945, 707, 2197, 6907, 0 }; - static ulong[] dim862JoeKuoD5Init = { 1, 1, 1, 15, 11, 9, 1, 87, 299, 509, 117, 3249, 3811, 0 }; - static ulong[] dim863JoeKuoD5Init = { 1, 3, 5, 7, 23, 35, 43, 129, 357, 501, 837, 305, 7967, 0 }; - static ulong[] dim864JoeKuoD5Init = { 1, 1, 5, 1, 23, 45, 85, 245, 157, 193, 215, 1021, 5115, 0 }; - static ulong[] dim865JoeKuoD5Init = { 1, 3, 1, 9, 5, 47, 125, 27, 295, 407, 1601, 859, 1203, 0 }; - static ulong[] dim866JoeKuoD5Init = { 1, 3, 5, 7, 21, 3, 23, 141, 75, 841, 199, 2719, 2131, 0 }; - static ulong[] dim867JoeKuoD5Init = { 1, 3, 1, 1, 3, 7, 35, 227, 275, 37, 523, 2849, 4363, 0 }; - static ulong[] dim868JoeKuoD5Init = { 1, 3, 7, 9, 5, 39, 95, 77, 201, 891, 339, 375, 7115, 0 }; - static ulong[] dim869JoeKuoD5Init = { 1, 1, 3, 3, 3, 57, 57, 49, 305, 141, 1149, 3909, 6981, 0 }; - static ulong[] dim870JoeKuoD5Init = { 1, 3, 3, 7, 19, 17, 53, 31, 233, 317, 1541, 235, 1831, 0 }; - static ulong[] dim871JoeKuoD5Init = { 1, 1, 7, 5, 7, 63, 125, 169, 141, 399, 277, 1417, 7989, 0 }; - static ulong[] dim872JoeKuoD5Init = { 1, 1, 1, 1, 17, 61, 89, 11, 411, 505, 1191, 2651, 1175, 0 }; - static ulong[] dim873JoeKuoD5Init = { 1, 1, 3, 1, 11, 41, 39, 69, 279, 229, 1247, 1001, 7163, 0 }; - static ulong[] dim874JoeKuoD5Init = { 1, 1, 1, 5, 13, 29, 115, 51, 79, 57, 315, 173, 5875, 0 }; - static ulong[] dim875JoeKuoD5Init = { 1, 3, 5, 5, 1, 43, 121, 5, 99, 451, 1121, 425, 4581, 0 }; - static ulong[] dim876JoeKuoD5Init = { 1, 3, 5, 5, 19, 5, 101, 33, 19, 5, 1325, 3527, 1733, 0 }; - static ulong[] dim877JoeKuoD5Init = { 1, 1, 7, 7, 15, 35, 91, 141, 127, 1005, 459, 3707, 6551, 0 }; - static ulong[] dim878JoeKuoD5Init = { 1, 3, 5, 11, 15, 27, 31, 49, 153, 337, 1235, 2063, 211, 0 }; - static ulong[] dim879JoeKuoD5Init = { 1, 3, 5, 3, 25, 45, 17, 233, 161, 559, 1687, 3833, 5451, 0 }; - static ulong[] dim880JoeKuoD5Init = { 1, 1, 7, 13, 23, 39, 127, 183, 379, 655, 129, 37, 2283, 0 }; - static ulong[] dim881JoeKuoD5Init = { 1, 3, 5, 13, 23, 33, 35, 111, 491, 343, 1771, 509, 937, 0 }; - static ulong[] dim882JoeKuoD5Init = { 1, 1, 1, 3, 19, 59, 59, 79, 327, 911, 1103, 2695, 3673, 0 }; - static ulong[] dim883JoeKuoD5Init = { 1, 1, 3, 5, 11, 23, 43, 31, 455, 843, 1515, 3059, 505, 0 }; - static ulong[] dim884JoeKuoD5Init = { 1, 3, 3, 7, 15, 1, 63, 35, 327, 801, 237, 1137, 3447, 0 }; - static ulong[] dim885JoeKuoD5Init = { 1, 3, 5, 1, 7, 35, 105, 113, 281, 153, 461, 3165, 659, 0 }; - static ulong[] dim886JoeKuoD5Init = { 1, 1, 3, 13, 29, 5, 119, 45, 313, 713, 1989, 99, 883, 0 }; - static ulong[] dim887JoeKuoD5Init = { 1, 1, 7, 15, 17, 43, 115, 201, 51, 947, 1271, 2465, 5319, 0 }; - static ulong[] dim888JoeKuoD5Init = { 1, 3, 5, 11, 25, 39, 49, 103, 99, 469, 1777, 33, 7115, 0 }; - static ulong[] dim889JoeKuoD5Init = { 1, 1, 3, 1, 17, 43, 53, 97, 473, 231, 1035, 19, 995, 0 }; - static ulong[] dim890JoeKuoD5Init = { 1, 1, 7, 1, 5, 1, 89, 255, 201, 945, 2017, 3181, 3961, 0 }; - static ulong[] dim891JoeKuoD5Init = { 1, 3, 7, 7, 9, 9, 45, 91, 451, 671, 613, 4051, 1233, 0 }; - static ulong[] dim892JoeKuoD5Init = { 1, 3, 5, 11, 27, 49, 37, 151, 59, 489, 341, 507, 5839, 0 }; - static ulong[] dim893JoeKuoD5Init = { 1, 1, 1, 3, 1, 41, 11, 165, 509, 615, 793, 2741, 7269, 0 }; - static ulong[] dim894JoeKuoD5Init = { 1, 1, 3, 13, 11, 33, 115, 87, 131, 653, 995, 1903, 4449, 0 }; - static ulong[] dim895JoeKuoD5Init = { 1, 1, 3, 11, 27, 41, 49, 211, 229, 797, 469, 839, 5047, 0 }; - static ulong[] dim896JoeKuoD5Init = { 1, 1, 3, 3, 9, 43, 57, 13, 77, 623, 245, 2349, 3611, 0 }; - static ulong[] dim897JoeKuoD5Init = { 1, 3, 5, 11, 23, 31, 101, 3, 355, 739, 1287, 3973, 6923, 0 }; - static ulong[] dim898JoeKuoD5Init = { 1, 3, 5, 5, 17, 61, 83, 75, 329, 849, 645, 3125, 8159, 0 }; - static ulong[] dim899JoeKuoD5Init = { 1, 3, 3, 11, 15, 31, 91, 149, 195, 585, 1415, 119, 6737, 0 }; - static ulong[] dim900JoeKuoD5Init = { 1, 1, 7, 13, 7, 3, 41, 25, 481, 175, 1147, 153, 6483, 0 }; - static ulong[] dim901JoeKuoD5Init = { 1, 1, 3, 1, 29, 59, 11, 225, 275, 299, 1083, 401, 6809, 0 }; - static ulong[] dim902JoeKuoD5Init = { 1, 1, 3, 11, 7, 19, 119, 145, 299, 273, 1571, 627, 6597, 0 }; - static ulong[] dim903JoeKuoD5Init = { 1, 1, 1, 13, 17, 7, 63, 19, 141, 359, 879, 2741, 3139, 0 }; - static ulong[] dim904JoeKuoD5Init = { 1, 1, 7, 15, 9, 19, 45, 127, 511, 767, 47, 2389, 7691, 0 }; - static ulong[] dim905JoeKuoD5Init = { 1, 1, 7, 15, 11, 53, 15, 207, 31, 215, 183, 2745, 4703, 0 }; - static ulong[] dim906JoeKuoD5Init = { 1, 3, 7, 7, 13, 43, 13, 65, 165, 157, 1139, 2417, 547, 0 }; - static ulong[] dim907JoeKuoD5Init = { 1, 3, 7, 7, 29, 29, 45, 165, 401, 327, 119, 1449, 1281, 0 }; - static ulong[] dim908JoeKuoD5Init = { 1, 3, 7, 11, 27, 25, 35, 5, 447, 205, 1487, 4089, 4929, 0 }; - static ulong[] dim909JoeKuoD5Init = { 1, 3, 5, 13, 3, 45, 73, 19, 349, 657, 771, 1029, 5047, 0 }; - static ulong[] dim910JoeKuoD5Init = { 1, 1, 5, 7, 29, 63, 23, 69, 425, 997, 9, 2365, 3279, 0 }; - static ulong[] dim911JoeKuoD5Init = { 1, 1, 1, 1, 7, 31, 47, 205, 29, 851, 1735, 1641, 2623, 0 }; - static ulong[] dim912JoeKuoD5Init = { 1, 3, 5, 11, 25, 33, 73, 109, 183, 357, 1585, 3323, 4993, 0 }; - static ulong[] dim913JoeKuoD5Init = { 1, 3, 5, 15, 13, 53, 43, 61, 137, 127, 1769, 2107, 4025, 0 }; - static ulong[] dim914JoeKuoD5Init = { 1, 3, 3, 7, 25, 59, 93, 57, 391, 155, 1367, 4093, 625, 0 }; - static ulong[] dim915JoeKuoD5Init = { 1, 3, 5, 1, 25, 27, 53, 217, 75, 961, 371, 1281, 6553, 0 }; - static ulong[] dim916JoeKuoD5Init = { 1, 3, 3, 5, 19, 5, 89, 87, 377, 199, 1533, 2219, 2705, 0 }; - static ulong[] dim917JoeKuoD5Init = { 1, 3, 1, 7, 15, 1, 61, 143, 137, 379, 1443, 355, 971, 0 }; - static ulong[] dim918JoeKuoD5Init = { 1, 3, 7, 11, 17, 57, 85, 225, 37, 345, 1509, 597, 5731, 0 }; - static ulong[] dim919JoeKuoD5Init = { 1, 1, 3, 11, 29, 55, 69, 27, 155, 481, 925, 3391, 5277, 0 }; - static ulong[] dim920JoeKuoD5Init = { 1, 1, 7, 9, 15, 19, 25, 5, 109, 83, 635, 3073, 3531, 0 }; - static ulong[] dim921JoeKuoD5Init = { 1, 3, 5, 15, 23, 5, 13, 7, 19, 625, 1481, 1827, 3991, 0 }; - static ulong[] dim922JoeKuoD5Init = { 1, 1, 3, 9, 7, 35, 123, 161, 303, 423, 25, 2467, 3411, 0 }; - static ulong[] dim923JoeKuoD5Init = { 1, 1, 1, 1, 9, 47, 27, 159, 249, 573, 1987, 3449, 7639, 0 }; - static ulong[] dim924JoeKuoD5Init = { 1, 1, 3, 5, 19, 59, 7, 209, 27, 495, 1491, 3217, 1321, 0 }; - static ulong[] dim925JoeKuoD5Init = { 1, 3, 1, 11, 17, 11, 109, 87, 315, 917, 1105, 215, 1295, 0 }; - static ulong[] dim926JoeKuoD5Init = { 1, 3, 5, 9, 25, 11, 77, 81, 453, 871, 1541, 141, 1625, 0 }; - static ulong[] dim927JoeKuoD5Init = { 1, 1, 3, 3, 1, 37, 11, 149, 45, 213, 975, 2557, 4263, 0 }; - static ulong[] dim928JoeKuoD5Init = { 1, 1, 3, 13, 17, 55, 59, 33, 39, 285, 1767, 3687, 7087, 0 }; - static ulong[] dim929JoeKuoD5Init = { 1, 1, 5, 7, 27, 9, 103, 191, 405, 25, 595, 1765, 5695, 0 }; - static ulong[] dim930JoeKuoD5Init = { 1, 3, 1, 7, 31, 27, 29, 195, 355, 199, 1297, 3195, 683, 0 }; - static ulong[] dim931JoeKuoD5Init = { 1, 3, 1, 1, 21, 3, 19, 227, 325, 279, 1593, 613, 7527, 0 }; - static ulong[] dim932JoeKuoD5Init = { 1, 3, 7, 15, 27, 17, 91, 179, 385, 133, 823, 3731, 2957, 0 }; - static ulong[] dim933JoeKuoD5Init = { 1, 1, 1, 7, 13, 9, 1, 137, 347, 67, 287, 1403, 5233, 0 }; - static ulong[] dim934JoeKuoD5Init = { 1, 3, 3, 7, 17, 15, 25, 95, 225, 469, 1585, 2513, 1489, 0 }; - static ulong[] dim935JoeKuoD5Init = { 1, 1, 7, 13, 31, 33, 81, 121, 435, 971, 877, 1603, 373, 0 }; - static ulong[] dim936JoeKuoD5Init = { 1, 1, 3, 9, 7, 31, 29, 27, 135, 181, 549, 1901, 813, 0 }; - static ulong[] dim937JoeKuoD5Init = { 1, 3, 3, 3, 3, 5, 11, 229, 255, 981, 1843, 2785, 2573, 0 }; - static ulong[] dim938JoeKuoD5Init = { 1, 1, 7, 13, 25, 29, 13, 87, 361, 431, 969, 1893, 5257, 0 }; - static ulong[] dim939JoeKuoD5Init = { 1, 1, 3, 3, 21, 53, 99, 243, 313, 681, 655, 2733, 4329, 0 }; - static ulong[] dim940JoeKuoD5Init = { 1, 3, 7, 7, 13, 3, 107, 61, 285, 687, 213, 551, 5039, 0 }; - static ulong[] dim941JoeKuoD5Init = { 1, 3, 1, 3, 9, 47, 99, 239, 313, 975, 1403, 3641, 1951, 0 }; - static ulong[] dim942JoeKuoD5Init = { 1, 1, 1, 3, 19, 43, 77, 139, 357, 973, 977, 369, 2775, 0 }; - static ulong[] dim943JoeKuoD5Init = { 1, 3, 5, 15, 23, 43, 109, 91, 321, 1, 1917, 3341, 1441, 0 }; - static ulong[] dim944JoeKuoD5Init = { 1, 1, 1, 9, 7, 19, 61, 255, 25, 729, 479, 837, 13, 0 }; - static ulong[] dim945JoeKuoD5Init = { 1, 1, 5, 9, 27, 29, 123, 101, 349, 443, 1759, 3, 4685, 0 }; - static ulong[] dim946JoeKuoD5Init = { 1, 3, 3, 1, 29, 47, 33, 183, 223, 927, 1341, 797, 8007, 0 }; - static ulong[] dim947JoeKuoD5Init = { 1, 3, 5, 15, 27, 33, 71, 195, 57, 897, 1337, 3455, 5201, 0 }; - static ulong[] dim948JoeKuoD5Init = { 1, 3, 3, 7, 31, 55, 121, 49, 343, 501, 1511, 113, 1549, 0 }; - static ulong[] dim949JoeKuoD5Init = { 1, 1, 7, 3, 9, 61, 19, 215, 323, 427, 1777, 685, 63, 0 }; - static ulong[] dim950JoeKuoD5Init = { 1, 3, 7, 15, 17, 23, 33, 129, 257, 527, 825, 3611, 2123, 0 }; - static ulong[] dim951JoeKuoD5Init = { 1, 3, 5, 1, 5, 45, 79, 9, 211, 493, 1095, 3031, 4093, 0 }; - static ulong[] dim952JoeKuoD5Init = { 1, 1, 5, 9, 21, 29, 29, 247, 489, 735, 11, 1723, 4459, 0 }; - static ulong[] dim953JoeKuoD5Init = { 1, 1, 7, 5, 21, 41, 59, 65, 151, 113, 851, 1213, 6367, 0 }; - static ulong[] dim954JoeKuoD5Init = { 1, 3, 7, 5, 9, 17, 85, 207, 219, 45, 85, 2433, 2219, 0 }; - static ulong[] dim955JoeKuoD5Init = { 1, 1, 3, 5, 7, 9, 39, 201, 369, 369, 113, 2667, 5137, 0 }; - static ulong[] dim956JoeKuoD5Init = { 1, 3, 7, 3, 27, 59, 127, 189, 289, 683, 1285, 2713, 7037, 0 }; - static ulong[] dim957JoeKuoD5Init = { 1, 3, 5, 3, 5, 19, 51, 23, 139, 379, 651, 19, 7705, 0 }; - static ulong[] dim958JoeKuoD5Init = { 1, 3, 3, 11, 31, 23, 11, 37, 161, 679, 1581, 217, 7973, 0 }; - static ulong[] dim959JoeKuoD5Init = { 1, 3, 1, 5, 9, 49, 23, 177, 475, 261, 403, 1415, 2299, 0 }; - static ulong[] dim960JoeKuoD5Init = { 1, 3, 5, 15, 19, 35, 117, 223, 159, 805, 1039, 1359, 6635, 0 }; - static ulong[] dim961JoeKuoD5Init = { 1, 3, 5, 15, 19, 1, 121, 223, 123, 161, 1631, 1161, 6997, 0 }; - static ulong[] dim962JoeKuoD5Init = { 1, 3, 5, 15, 5, 31, 41, 133, 121, 523, 1941, 2583, 6231, 0 }; - static ulong[] dim963JoeKuoD5Init = { 1, 1, 1, 15, 7, 31, 95, 49, 501, 737, 363, 2879, 6561, 0 }; - static ulong[] dim964JoeKuoD5Init = { 1, 1, 7, 11, 31, 47, 61, 17, 399, 3, 605, 907, 4605, 0 }; - static ulong[] dim965JoeKuoD5Init = { 1, 1, 5, 1, 23, 61, 47, 93, 25, 643, 881, 3559, 5251, 0 }; - static ulong[] dim966JoeKuoD5Init = { 1, 3, 3, 5, 27, 63, 1, 147, 425, 639, 1229, 3131, 5833, 0 }; - static ulong[] dim967JoeKuoD5Init = { 1, 3, 3, 15, 31, 31, 57, 121, 183, 39, 1067, 1915, 7321, 0 }; - static ulong[] dim968JoeKuoD5Init = { 1, 1, 5, 9, 21, 25, 125, 29, 53, 433, 189, 3465, 3847, 0 }; - static ulong[] dim969JoeKuoD5Init = { 1, 1, 1, 1, 11, 13, 99, 229, 365, 909, 87, 3669, 6609, 0 }; - static ulong[] dim970JoeKuoD5Init = { 1, 3, 3, 1, 29, 3, 43, 13, 19, 897, 1269, 1091, 3207, 0 }; - static ulong[] dim971JoeKuoD5Init = { 1, 3, 5, 13, 11, 33, 69, 251, 337, 235, 523, 2053, 3655, 0 }; - static ulong[] dim972JoeKuoD5Init = { 1, 3, 5, 15, 1, 11, 75, 169, 507, 391, 1009, 3165, 3691, 0 }; - static ulong[] dim973JoeKuoD5Init = { 1, 3, 1, 13, 3, 39, 119, 193, 169, 661, 813, 143, 7825, 0 }; - static ulong[] dim974JoeKuoD5Init = { 1, 3, 7, 11, 13, 33, 91, 209, 469, 141, 391, 1037, 6591, 0 }; - static ulong[] dim975JoeKuoD5Init = { 1, 3, 3, 7, 17, 45, 39, 19, 449, 691, 187, 2739, 7671, 0 }; - static ulong[] dim976JoeKuoD5Init = { 1, 1, 3, 15, 13, 57, 7, 75, 435, 287, 1479, 2143, 6501, 0 }; - static ulong[] dim977JoeKuoD5Init = { 1, 1, 1, 11, 11, 29, 111, 223, 505, 139, 1587, 3769, 5839, 0 }; - static ulong[] dim978JoeKuoD5Init = { 1, 3, 7, 7, 5, 61, 7, 209, 461, 37, 1771, 3683, 4283, 0 }; - static ulong[] dim979JoeKuoD5Init = { 1, 3, 3, 9, 1, 5, 123, 69, 75, 451, 963, 3273, 2785, 0 }; - static ulong[] dim980JoeKuoD5Init = { 1, 1, 1, 3, 7, 17, 87, 63, 505, 863, 1955, 3253, 463, 0 }; - static ulong[] dim981JoeKuoD5Init = { 1, 3, 5, 15, 15, 55, 127, 213, 277, 829, 165, 2885, 6693, 0 }; - static ulong[] dim982JoeKuoD5Init = { 1, 1, 7, 1, 9, 35, 5, 233, 329, 827, 531, 1435, 899, 0 }; - static ulong[] dim983JoeKuoD5Init = { 1, 1, 3, 11, 15, 25, 19, 233, 375, 327, 241, 3519, 4511, 0 }; - static ulong[] dim984JoeKuoD5Init = { 1, 1, 3, 11, 1, 1, 117, 29, 185, 529, 873, 1769, 6857, 0 }; - static ulong[] dim985JoeKuoD5Init = { 1, 3, 5, 11, 1, 31, 125, 27, 77, 295, 43, 205, 3349, 0 }; - static ulong[] dim986JoeKuoD5Init = { 1, 1, 3, 13, 1, 59, 11, 195, 483, 391, 381, 1251, 205, 0 }; - static ulong[] dim987JoeKuoD5Init = { 1, 3, 5, 1, 5, 51, 33, 159, 143, 213, 573, 1329, 2327, 0 }; - static ulong[] dim988JoeKuoD5Init = { 1, 3, 3, 15, 25, 5, 11, 203, 217, 397, 819, 949, 3987, 0 }; - static ulong[] dim989JoeKuoD5Init = { 1, 1, 5, 13, 17, 1, 29, 219, 161, 437, 685, 2743, 7509, 0 }; - static ulong[] dim990JoeKuoD5Init = { 1, 1, 3, 13, 3, 31, 29, 51, 41, 217, 997, 2581, 4273, 0 }; - static ulong[] dim991JoeKuoD5Init = { 1, 1, 7, 5, 31, 33, 45, 113, 463, 537, 237, 1501, 315, 0 }; - static ulong[] dim992JoeKuoD5Init = { 1, 3, 7, 5, 13, 3, 49, 155, 175, 655, 1995, 2131, 6105, 0 }; - static ulong[] dim993JoeKuoD5Init = { 1, 3, 3, 15, 23, 3, 17, 165, 67, 137, 337, 3805, 257, 0 }; - static ulong[] dim994JoeKuoD5Init = { 1, 1, 5, 13, 31, 11, 39, 111, 79, 585, 1911, 2395, 6239, 0 }; - static ulong[] dim995JoeKuoD5Init = { 1, 3, 5, 13, 5, 13, 61, 87, 309, 571, 321, 2485, 807, 0 }; - static ulong[] dim996JoeKuoD5Init = { 1, 3, 5, 13, 31, 21, 9, 177, 9, 395, 351, 529, 4977, 0 }; - static ulong[] dim997JoeKuoD5Init = { 1, 3, 1, 5, 5, 41, 95, 145, 319, 339, 1559, 203, 2883, 0 }; - static ulong[] dim998JoeKuoD5Init = { 1, 3, 3, 7, 9, 13, 121, 111, 107, 421, 1763, 2671, 259, 0 }; - static ulong[] dim999JoeKuoD5Init = { 1, 3, 7, 13, 25, 47, 71, 249, 119, 83, 1651, 2715, 4819, 0 }; - static ulong[] dim1000JoeKuoD5Init = { 1, 3, 5, 3, 5, 59, 99, 139, 435, 653, 153, 3605, 753, 0 }; - static ulong[] dim1001JoeKuoD5Init = { 1, 3, 5, 13, 19, 13, 3, 17, 215, 1017, 1685, 3795, 2363, 0 }; - static ulong[] dim1002JoeKuoD5Init = { 1, 3, 5, 11, 15, 13, 97, 145, 383, 39, 667, 1217, 1473, 0 }; - static ulong[] dim1003JoeKuoD5Init = { 1, 3, 5, 3, 11, 25, 107, 149, 11, 835, 1013, 1587, 1485, 0 }; - static ulong[] dim1004JoeKuoD5Init = { 1, 1, 5, 7, 15, 33, 15, 251, 473, 723, 959, 3991, 7145, 0 }; - static ulong[] dim1005JoeKuoD5Init = { 1, 1, 3, 13, 1, 49, 73, 195, 139, 893, 1677, 707, 667, 0 }; - static ulong[] dim1006JoeKuoD5Init = { 1, 3, 7, 11, 23, 3, 79, 255, 371, 885, 469, 3673, 5477, 0 }; - static ulong[] dim1007JoeKuoD5Init = { 1, 3, 3, 15, 21, 1, 45, 65, 403, 129, 123, 1171, 8177, 0 }; - static ulong[] dim1008JoeKuoD5Init = { 1, 1, 1, 3, 29, 25, 89, 231, 81, 503, 629, 1925, 2853, 0 }; - static ulong[] dim1009JoeKuoD5Init = { 1, 1, 7, 13, 9, 15, 107, 81, 479, 235, 1483, 3593, 2289, 0 }; - static ulong[] dim1010JoeKuoD5Init = { 1, 3, 1, 5, 9, 49, 119, 161, 233, 321, 1505, 3969, 3131, 0 }; - static ulong[] dim1011JoeKuoD5Init = { 1, 1, 5, 15, 9, 5, 91, 57, 13, 271, 999, 747, 3399, 0 }; - static ulong[] dim1012JoeKuoD5Init = { 1, 1, 7, 1, 1, 21, 1, 179, 449, 963, 33, 2259, 259, 0 }; - static ulong[] dim1013JoeKuoD5Init = { 1, 3, 5, 13, 7, 11, 81, 53, 157, 373, 767, 2489, 2275, 0 }; - static ulong[] dim1014JoeKuoD5Init = { 1, 3, 7, 3, 9, 55, 123, 135, 9, 499, 3, 2039, 2387, 0 }; - static ulong[] dim1015JoeKuoD5Init = { 1, 3, 3, 13, 7, 47, 119, 81, 351, 949, 1159, 859, 99, 0 }; - static ulong[] dim1016JoeKuoD5Init = { 1, 1, 7, 9, 1, 5, 83, 3, 387, 455, 1997, 1253, 77, 0 }; - static ulong[] dim1017JoeKuoD5Init = { 1, 1, 3, 13, 13, 49, 111, 133, 193, 893, 1549, 4003, 3461, 0 }; - static ulong[] dim1018JoeKuoD5Init = { 1, 1, 5, 13, 21, 3, 63, 209, 491, 447, 1635, 2297, 7667, 0 }; - static ulong[] dim1019JoeKuoD5Init = { 1, 3, 1, 1, 3, 61, 93, 115, 417, 465, 1075, 2157, 861, 0 }; - static ulong[] dim1020JoeKuoD5Init = { 1, 3, 1, 1, 7, 33, 7, 61, 509, 539, 1579, 2089, 5633, 0 }; - static ulong[] dim1021JoeKuoD5Init = { 1, 1, 7, 1, 9, 5, 75, 125, 345, 133, 1699, 3183, 5403, 0 }; - static ulong[] dim1022JoeKuoD5Init = { 1, 3, 3, 15, 17, 9, 115, 213, 417, 713, 989, 3987, 3043, 0 }; - static ulong[] dim1023JoeKuoD5Init = { 1, 3, 3, 3, 25, 9, 115, 83, 255, 695, 471, 1819, 2661, 0 }; - static ulong[] dim1024JoeKuoD5Init = { 1, 1, 7, 9, 31, 35, 33, 197, 335, 543, 323, 3241, 7039, 0 }; - static ulong[] dim1025JoeKuoD5Init = { 1, 1, 7, 7, 23, 5, 23, 193, 327, 3, 1425, 2787, 5659, 0 }; - static ulong[] dim1026JoeKuoD5Init = { 1, 3, 3, 9, 27, 25, 37, 241, 373, 411, 783, 621, 2129, 0 }; - static ulong[] dim1027JoeKuoD5Init = { 1, 1, 3, 5, 13, 19, 119, 39, 303, 383, 1965, 725, 1909, 0 }; - static ulong[] dim1028JoeKuoD5Init = { 1, 3, 7, 15, 25, 27, 121, 245, 165, 985, 595, 3325, 7319, 0 }; - static ulong[] dim1029JoeKuoD5Init = { 1, 1, 1, 5, 25, 7, 109, 75, 277, 25, 715, 495, 3911, 0 }; - static ulong[] dim1030JoeKuoD5Init = { 1, 1, 3, 9, 21, 37, 13, 23, 161, 907, 1551, 2453, 5323, 0 }; - static ulong[] dim1031JoeKuoD5Init = { 1, 1, 5, 9, 17, 11, 101, 237, 219, 735, 1865, 209, 5605, 0 }; - static ulong[] dim1032JoeKuoD5Init = { 1, 3, 3, 15, 5, 63, 87, 173, 299, 739, 617, 1883, 2525, 0 }; - static ulong[] dim1033JoeKuoD5Init = { 1, 1, 5, 1, 11, 5, 25, 207, 271, 471, 921, 3819, 5627, 0 }; - static ulong[] dim1034JoeKuoD5Init = { 1, 3, 7, 13, 1, 7, 27, 185, 245, 629, 1329, 611, 7183, 0 }; - static ulong[] dim1035JoeKuoD5Init = { 1, 3, 5, 15, 9, 21, 55, 17, 157, 987, 553, 3823, 6923, 0 }; - static ulong[] dim1036JoeKuoD5Init = { 1, 3, 3, 11, 19, 47, 113, 149, 495, 891, 1885, 2699, 6019, 0 }; - static ulong[] dim1037JoeKuoD5Init = { 1, 1, 3, 9, 23, 53, 27, 241, 453, 103, 1879, 289, 5195, 0 }; - static ulong[] dim1038JoeKuoD5Init = { 1, 1, 1, 3, 13, 37, 125, 83, 341, 793, 193, 297, 3337, 0 }; - static ulong[] dim1039JoeKuoD5Init = { 1, 1, 5, 7, 13, 43, 101, 121, 319, 845, 601, 3357, 3037, 0 }; - static ulong[] dim1040JoeKuoD5Init = { 1, 3, 1, 1, 27, 3, 53, 111, 287, 791, 2017, 3869, 5105, 0 }; - static ulong[] dim1041JoeKuoD5Init = { 1, 3, 7, 1, 19, 33, 107, 203, 135, 783, 497, 1007, 4587, 0 }; - static ulong[] dim1042JoeKuoD5Init = { 1, 1, 3, 13, 7, 41, 101, 59, 407, 525, 1941, 961, 7059, 0 }; - static ulong[] dim1043JoeKuoD5Init = { 1, 3, 5, 5, 17, 33, 9, 217, 31, 695, 1111, 391, 5617, 0 }; - static ulong[] dim1044JoeKuoD5Init = { 1, 3, 5, 5, 15, 13, 107, 223, 477, 91, 449, 901, 3075, 0 }; - static ulong[] dim1045JoeKuoD5Init = { 1, 1, 3, 13, 31, 47, 97, 49, 47, 301, 305, 1159, 6977, 0 }; - static ulong[] dim1046JoeKuoD5Init = { 1, 3, 5, 9, 29, 9, 17, 237, 461, 593, 495, 1099, 5135, 0 }; - static ulong[] dim1047JoeKuoD5Init = { 1, 3, 5, 7, 3, 51, 5, 113, 409, 777, 1323, 2719, 3647, 0 }; - static ulong[] dim1048JoeKuoD5Init = { 1, 3, 3, 5, 15, 45, 33, 49, 167, 933, 1831, 3195, 3121, 0 }; - static ulong[] dim1049JoeKuoD5Init = { 1, 1, 5, 15, 3, 33, 123, 19, 173, 69, 593, 3709, 7193, 0 }; - static ulong[] dim1050JoeKuoD5Init = { 1, 1, 7, 15, 9, 9, 63, 81, 325, 473, 1517, 3483, 7585, 0 }; - static ulong[] dim1051JoeKuoD5Init = { 1, 1, 5, 9, 31, 47, 77, 67, 55, 673, 1963, 111, 839, 0 }; - static ulong[] dim1052JoeKuoD5Init = { 1, 3, 3, 15, 23, 45, 5, 159, 225, 595, 1573, 1891, 301, 0 }; - static ulong[] dim1053JoeKuoD5Init = { 1, 3, 1, 1, 3, 21, 123, 29, 331, 793, 1885, 3299, 3433, 0 }; - static ulong[] dim1054JoeKuoD5Init = { 1, 3, 5, 1, 23, 51, 21, 23, 265, 919, 853, 3969, 2043, 0 }; - static ulong[] dim1055JoeKuoD5Init = { 1, 3, 7, 3, 25, 59, 111, 13, 217, 893, 1005, 3795, 3233, 0 }; - static ulong[] dim1056JoeKuoD5Init = { 1, 3, 5, 7, 7, 11, 69, 183, 509, 51, 727, 2093, 2615, 0 }; - static ulong[] dim1057JoeKuoD5Init = { 1, 1, 1, 11, 3, 13, 119, 209, 365, 895, 1563, 427, 5519, 0 }; - static ulong[] dim1058JoeKuoD5Init = { 1, 3, 7, 5, 23, 9, 87, 29, 19, 519, 763, 3553, 575, 0 }; - static ulong[] dim1059JoeKuoD5Init = { 1, 3, 5, 1, 3, 21, 15, 237, 501, 627, 1557, 545, 2415, 0 }; - static ulong[] dim1060JoeKuoD5Init = { 1, 3, 3, 3, 7, 53, 83, 19, 385, 425, 1145, 1039, 6667, 0 }; - static ulong[] dim1061JoeKuoD5Init = { 1, 1, 5, 15, 31, 31, 39, 51, 233, 755, 1105, 925, 6113, 0 }; - static ulong[] dim1062JoeKuoD5Init = { 1, 3, 3, 13, 17, 25, 45, 135, 347, 707, 1035, 1405, 7105, 0 }; - static ulong[] dim1063JoeKuoD5Init = { 1, 3, 3, 9, 17, 25, 119, 77, 279, 467, 195, 1919, 4959, 0 }; - static ulong[] dim1064JoeKuoD5Init = { 1, 3, 1, 7, 31, 41, 5, 21, 349, 607, 737, 2033, 2323, 0 }; - static ulong[] dim1065JoeKuoD5Init = { 1, 1, 7, 9, 29, 19, 45, 223, 391, 495, 1905, 735, 6309, 0 }; - static ulong[] dim1066JoeKuoD5Init = { 1, 1, 7, 15, 19, 9, 93, 89, 43, 297, 653, 1343, 5897, 0 }; - static ulong[] dim1067JoeKuoD5Init = { 1, 1, 1, 1, 21, 7, 29, 187, 115, 279, 1029, 2817, 1349, 0 }; - static ulong[] dim1068JoeKuoD5Init = { 1, 3, 7, 9, 5, 61, 35, 33, 151, 119, 1713, 1713, 1645, 0 }; - static ulong[] dim1069JoeKuoD5Init = { 1, 3, 5, 1, 23, 21, 101, 131, 355, 75, 1233, 1677, 2463, 0 }; - static ulong[] dim1070JoeKuoD5Init = { 1, 3, 1, 15, 5, 57, 79, 51, 299, 307, 1977, 3473, 6153, 0 }; - static ulong[] dim1071JoeKuoD5Init = { 1, 1, 1, 15, 19, 1, 59, 69, 175, 189, 303, 43, 7561, 0 }; - static ulong[] dim1072JoeKuoD5Init = { 1, 1, 7, 1, 31, 37, 117, 9, 373, 279, 1187, 3501, 715, 0 }; - static ulong[] dim1073JoeKuoD5Init = { 1, 1, 7, 13, 1, 29, 79, 161, 223, 437, 577, 921, 5535, 0 }; - static ulong[] dim1074JoeKuoD5Init = { 1, 3, 5, 1, 31, 27, 93, 63, 281, 187, 1739, 4085, 5669, 0 }; - static ulong[] dim1075JoeKuoD5Init = { 1, 1, 3, 7, 11, 25, 87, 245, 339, 741, 927, 1279, 3889, 0 }; - static ulong[] dim1076JoeKuoD5Init = { 1, 1, 5, 7, 31, 5, 45, 205, 289, 999, 361, 3595, 569, 0 }; - static ulong[] dim1077JoeKuoD5Init = { 1, 1, 1, 13, 19, 23, 103, 73, 403, 85, 1623, 325, 5369, 0 }; - static ulong[] dim1078JoeKuoD5Init = { 1, 1, 7, 15, 13, 23, 27, 155, 359, 777, 1751, 915, 949, 0 }; - static ulong[] dim1079JoeKuoD5Init = { 1, 3, 5, 11, 23, 59, 57, 215, 77, 581, 369, 953, 6987, 0 }; - static ulong[] dim1080JoeKuoD5Init = { 1, 1, 1, 15, 27, 55, 103, 173, 485, 771, 1693, 1227, 3257, 0 }; - static ulong[] dim1081JoeKuoD5Init = { 1, 1, 1, 9, 5, 23, 95, 121, 81, 107, 1897, 1647, 3047, 0 }; - static ulong[] dim1082JoeKuoD5Init = { 1, 1, 3, 11, 17, 47, 119, 83, 137, 897, 1893, 653, 5031, 0 }; - static ulong[] dim1083JoeKuoD5Init = { 1, 1, 7, 13, 31, 3, 73, 129, 159, 529, 1433, 2313, 6143, 0 }; - static ulong[] dim1084JoeKuoD5Init = { 1, 3, 1, 15, 29, 19, 123, 141, 51, 427, 935, 2831, 5799, 0 }; - static ulong[] dim1085JoeKuoD5Init = { 1, 1, 3, 1, 31, 3, 119, 227, 37, 435, 921, 3313, 2129, 0 }; - static ulong[] dim1086JoeKuoD5Init = { 1, 1, 3, 13, 1, 19, 75, 35, 307, 419, 813, 2217, 6603, 0 }; - static ulong[] dim1087JoeKuoD5Init = { 1, 1, 1, 3, 17, 47, 79, 75, 47, 835, 287, 3361, 5875, 0 }; - static ulong[] dim1088JoeKuoD5Init = { 1, 3, 7, 9, 5, 5, 3, 19, 341, 717, 45, 1169, 1305, 0 }; - static ulong[] dim1089JoeKuoD5Init = { 1, 3, 5, 1, 3, 11, 81, 233, 195, 987, 593, 2495, 5213, 0 }; - static ulong[] dim1090JoeKuoD5Init = { 1, 1, 5, 1, 27, 1, 29, 251, 221, 267, 593, 361, 5629, 0 }; - static ulong[] dim1091JoeKuoD5Init = { 1, 1, 7, 15, 21, 33, 15, 37, 341, 301, 293, 2787, 3531, 0 }; - static ulong[] dim1092JoeKuoD5Init = { 1, 3, 3, 7, 3, 3, 9, 7, 257, 509, 1545, 4095, 3309, 0 }; - static ulong[] dim1093JoeKuoD5Init = { 1, 1, 5, 5, 11, 7, 27, 71, 317, 221, 391, 1257, 5885, 0 }; - static ulong[] dim1094JoeKuoD5Init = { 1, 1, 5, 7, 15, 51, 29, 107, 461, 597, 961, 3589, 2325, 0 }; - static ulong[] dim1095JoeKuoD5Init = { 1, 3, 3, 3, 29, 1, 91, 181, 477, 125, 1869, 3209, 3513, 0 }; - static ulong[] dim1096JoeKuoD5Init = { 1, 3, 5, 7, 13, 17, 49, 145, 215, 1003, 1053, 1413, 8011, 0 }; - static ulong[] dim1097JoeKuoD5Init = { 1, 1, 7, 5, 23, 63, 9, 175, 159, 627, 705, 2769, 2469, 0 }; - static ulong[] dim1098JoeKuoD5Init = { 1, 1, 1, 11, 27, 21, 5, 61, 249, 581, 829, 2195, 4241, 0 }; - static ulong[] dim1099JoeKuoD5Init = { 1, 1, 3, 11, 27, 39, 67, 3, 23, 819, 1879, 3775, 6949, 0 }; - static ulong[] dim1100JoeKuoD5Init = { 1, 3, 3, 5, 19, 35, 93, 113, 371, 511, 811, 577, 1121, 0 }; - static ulong[] dim1101JoeKuoD5Init = { 1, 1, 5, 9, 9, 25, 103, 139, 151, 177, 557, 2123, 6677, 0 }; - static ulong[] dim1102JoeKuoD5Init = { 1, 1, 7, 5, 17, 63, 61, 241, 351, 371, 1745, 3133, 7663, 0 }; - static ulong[] dim1103JoeKuoD5Init = { 1, 3, 7, 11, 19, 39, 105, 93, 77, 445, 1433, 1793, 2957, 0 }; - static ulong[] dim1104JoeKuoD5Init = { 1, 3, 1, 15, 5, 15, 29, 211, 229, 887, 413, 701, 737, 0 }; - static ulong[] dim1105JoeKuoD5Init = { 1, 1, 5, 13, 17, 7, 69, 213, 49, 91, 1143, 3743, 4385, 0 }; - static ulong[] dim1106JoeKuoD5Init = { 1, 3, 3, 7, 21, 47, 41, 157, 299, 29, 751, 2427, 1521, 0 }; - static ulong[] dim1107JoeKuoD5Init = { 1, 1, 1, 1, 29, 45, 119, 79, 141, 477, 1289, 515, 8143, 0 }; - static ulong[] dim1108JoeKuoD5Init = { 1, 1, 7, 7, 3, 7, 123, 197, 441, 233, 1841, 267, 6553, 0 }; - static ulong[] dim1109JoeKuoD5Init = { 1, 3, 7, 15, 3, 41, 33, 95, 271, 461, 1505, 2989, 5503, 0 }; - static ulong[] dim1110JoeKuoD5Init = { 1, 1, 1, 11, 19, 15, 1, 23, 13, 737, 51, 289, 6731, 0 }; - static ulong[] dim1111JoeKuoD5Init = { 1, 3, 5, 1, 15, 11, 53, 241, 17, 107, 1931, 3759, 5421, 1889, 0 }; - static ulong[] dim1112JoeKuoD5Init = { 1, 3, 1, 13, 15, 29, 107, 163, 395, 645, 299, 799, 4331, 335, 0 }; - static ulong[] dim1113JoeKuoD5Init = { 1, 1, 3, 13, 5, 47, 91, 41, 439, 319, 1213, 763, 6101, 1543, 0 }; - static ulong[] dim1114JoeKuoD5Init = { 1, 1, 3, 15, 19, 51, 117, 159, 315, 767, 1957, 3655, 6573, 5419, 0 }; - static ulong[] dim1115JoeKuoD5Init = { 1, 3, 1, 11, 23, 51, 115, 223, 125, 633, 637, 3443, 1993, 1887, 0 }; - static ulong[] dim1116JoeKuoD5Init = { 1, 3, 3, 15, 27, 59, 49, 123, 49, 187, 963, 3893, 3921, 14411, 0 }; - static ulong[] dim1117JoeKuoD5Init = { 1, 3, 1, 7, 29, 3, 77, 3, 79, 409, 1151, 3547, 3693, 8367, 0 }; - static ulong[] dim1118JoeKuoD5Init = { 1, 3, 1, 9, 23, 31, 123, 133, 215, 921, 329, 1449, 5535, 9725, 0 }; - static ulong[] dim1119JoeKuoD5Init = { 1, 3, 1, 5, 11, 45, 109, 117, 493, 743, 1473, 2073, 4771, 16321, 0 }; - static ulong[] dim1120JoeKuoD5Init = { 1, 1, 3, 9, 27, 29, 25, 223, 371, 113, 1183, 1723, 6127, 9949, 0 }; - static ulong[] dim1121JoeKuoD5Init = { 1, 1, 7, 15, 27, 55, 119, 31, 21, 849, 2001, 2541, 2611, 15429, 0 }; - static ulong[] dim1122JoeKuoD5Init = { 1, 1, 3, 7, 17, 1, 93, 243, 311, 175, 559, 2177, 5641, 15293, 0 }; - static ulong[] dim1123JoeKuoD5Init = { 1, 3, 5, 15, 25, 31, 121, 179, 169, 61, 1837, 2233, 1735, 6597, 0 }; - static ulong[] dim1124JoeKuoD5Init = { 1, 3, 5, 13, 21, 59, 61, 239, 501, 523, 257, 573, 893, 7275, 0 }; - static ulong[] dim1125JoeKuoD5Init = { 1, 1, 1, 13, 29, 33, 77, 225, 81, 879, 1403, 3279, 2225, 11571, 0 }; - static ulong[] dim1126JoeKuoD5Init = { 1, 3, 5, 5, 15, 5, 29, 7, 157, 717, 397, 2079, 5839, 13297, 0 }; - static ulong[] dim1127JoeKuoD5Init = { 1, 3, 5, 7, 17, 3, 93, 241, 301, 433, 2003, 2089, 5781, 15223, 0 }; - static ulong[] dim1128JoeKuoD5Init = { 1, 1, 5, 13, 5, 19, 53, 189, 41, 17, 897, 2327, 3481, 7185, 0 }; - static ulong[] dim1129JoeKuoD5Init = { 1, 1, 3, 3, 25, 23, 23, 155, 367, 391, 1001, 1179, 3781, 14225, 0 }; - static ulong[] dim1130JoeKuoD5Init = { 1, 1, 5, 7, 9, 23, 63, 73, 439, 361, 233, 3387, 887, 5425, 0 }; - static ulong[] dim1131JoeKuoD5Init = { 1, 3, 3, 13, 5, 57, 55, 35, 369, 85, 1585, 2267, 2927, 13997, 0 }; - static ulong[] dim1132JoeKuoD5Init = { 1, 3, 7, 1, 7, 7, 55, 109, 401, 443, 1777, 3831, 6933, 3661, 0 }; - static ulong[] dim1133JoeKuoD5Init = { 1, 1, 7, 15, 17, 27, 5, 17, 419, 949, 1483, 791, 7353, 1425, 0 }; - static ulong[] dim1134JoeKuoD5Init = { 1, 1, 3, 9, 27, 41, 67, 135, 129, 863, 1679, 4001, 6841, 13561, 0 }; - static ulong[] dim1135JoeKuoD5Init = { 1, 3, 3, 3, 21, 43, 45, 65, 103, 141, 1261, 2865, 5621, 5131, 0 }; - static ulong[] dim1136JoeKuoD5Init = { 1, 1, 1, 15, 19, 3, 97, 159, 465, 31, 1757, 2765, 667, 6943, 0 }; - static ulong[] dim1137JoeKuoD5Init = { 1, 3, 7, 3, 3, 5, 111, 203, 313, 495, 123, 1899, 7765, 2737, 0 }; - static ulong[] dim1138JoeKuoD5Init = { 1, 3, 1, 15, 19, 63, 19, 233, 283, 25, 1009, 2117, 6233, 5059, 0 }; - static ulong[] dim1139JoeKuoD5Init = { 1, 1, 7, 9, 29, 11, 35, 111, 111, 49, 1681, 3483, 2449, 13877, 0 }; - static ulong[] dim1140JoeKuoD5Init = { 1, 3, 5, 13, 7, 61, 27, 217, 275, 137, 2025, 2745, 5565, 7999, 0 }; - static ulong[] dim1141JoeKuoD5Init = { 1, 1, 5, 1, 13, 19, 113, 169, 425, 691, 1425, 1645, 1045, 9237, 0 }; - static ulong[] dim1142JoeKuoD5Init = { 1, 3, 1, 11, 23, 19, 67, 5, 225, 523, 1809, 341, 7919, 3675, 0 }; - static ulong[] dim1143JoeKuoD5Init = { 1, 3, 5, 7, 3, 33, 25, 229, 393, 141, 1953, 1433, 1593, 11569, 0 }; - static ulong[] dim1144JoeKuoD5Init = { 1, 1, 1, 1, 5, 23, 53, 59, 141, 385, 1765, 4079, 2901, 593, 0 }; - static ulong[] dim1145JoeKuoD5Init = { 1, 3, 7, 9, 15, 43, 115, 93, 121, 209, 1797, 633, 2595, 5539, 0 }; - static ulong[] dim1146JoeKuoD5Init = { 1, 3, 3, 15, 5, 25, 9, 141, 37, 313, 1937, 2259, 1051, 8251, 0 }; - static ulong[] dim1147JoeKuoD5Init = { 1, 1, 5, 5, 17, 1, 89, 173, 169, 463, 2003, 4005, 6009, 4373, 0 }; - static ulong[] dim1148JoeKuoD5Init = { 1, 3, 1, 7, 17, 21, 59, 207, 333, 741, 1847, 683, 2847, 11007, 0 }; - static ulong[] dim1149JoeKuoD5Init = { 1, 3, 1, 5, 5, 39, 111, 91, 49, 559, 1937, 1311, 6157, 517, 0 }; - static ulong[] dim1150JoeKuoD5Init = { 1, 1, 1, 15, 29, 1, 113, 125, 343, 939, 1989, 2569, 7215, 5099, 0 }; - static ulong[] dim1151JoeKuoD5Init = { 1, 1, 1, 5, 5, 55, 103, 237, 313, 43, 909, 201, 175, 16025, 0 }; - static ulong[] dim1152JoeKuoD5Init = { 1, 1, 7, 3, 25, 29, 33, 59, 127, 865, 1753, 3649, 5517, 5001, 0 }; - static ulong[] dim1153JoeKuoD5Init = { 1, 3, 1, 15, 27, 31, 97, 153, 451, 241, 59, 515, 2869, 12909, 0 }; - static ulong[] dim1154JoeKuoD5Init = { 1, 3, 3, 3, 13, 51, 3, 55, 105, 497, 701, 483, 5165, 4721, 0 }; - static ulong[] dim1155JoeKuoD5Init = { 1, 3, 5, 3, 19, 57, 39, 55, 197, 409, 199, 1635, 1965, 2489, 0 }; - static ulong[] dim1156JoeKuoD5Init = { 1, 3, 1, 9, 1, 13, 123, 125, 341, 981, 1957, 1619, 1973, 8641, 0 }; - static ulong[] dim1157JoeKuoD5Init = { 1, 3, 7, 1, 29, 13, 31, 71, 443, 867, 1755, 843, 7349, 6015, 0 }; - static ulong[] dim1158JoeKuoD5Init = { 1, 3, 5, 13, 15, 39, 81, 123, 9, 991, 803, 3281, 7859, 15455, 0 }; - static ulong[] dim1159JoeKuoD5Init = { 1, 1, 7, 1, 3, 33, 87, 81, 111, 595, 483, 3273, 847, 2061, 0 }; - static ulong[] dim1160JoeKuoD5Init = { 1, 1, 1, 11, 9, 21, 79, 49, 453, 125, 603, 1733, 7213, 7309, 0 }; - static ulong[] dim1161JoeKuoD5Init = { 1, 1, 7, 3, 29, 47, 21, 99, 35, 275, 69, 3773, 389, 10615, 0 }; - static ulong[] dim1162JoeKuoD5Init = { 1, 3, 7, 5, 15, 21, 9, 55, 293, 639, 135, 903, 973, 9467, 0 }; - static ulong[] dim1163JoeKuoD5Init = { 1, 1, 1, 15, 19, 63, 73, 71, 397, 387, 1859, 2741, 7323, 369, 0 }; - static ulong[] dim1164JoeKuoD5Init = { 1, 1, 5, 9, 21, 23, 55, 129, 183, 721, 1293, 3579, 3629, 13303, 0 }; - static ulong[] dim1165JoeKuoD5Init = { 1, 3, 7, 1, 21, 35, 79, 255, 443, 123, 551, 1113, 8133, 11621, 0 }; - static ulong[] dim1166JoeKuoD5Init = { 1, 3, 3, 7, 19, 61, 35, 161, 145, 291, 1503, 3085, 4589, 7971, 0 }; - static ulong[] dim1167JoeKuoD5Init = { 1, 1, 5, 15, 9, 59, 119, 133, 69, 413, 335, 2089, 8085, 12727, 0 }; - static ulong[] dim1168JoeKuoD5Init = { 1, 1, 7, 11, 17, 5, 83, 125, 161, 745, 1889, 345, 8107, 10693, 0 }; - static ulong[] dim1169JoeKuoD5Init = { 1, 3, 1, 9, 5, 29, 59, 69, 113, 529, 199, 1565, 1611, 12297, 0 }; - static ulong[] dim1170JoeKuoD5Init = { 1, 1, 3, 15, 27, 61, 49, 59, 249, 121, 1569, 407, 1443, 5705, 0 }; - static ulong[] dim1171JoeKuoD5Init = { 1, 3, 3, 13, 5, 3, 93, 99, 417, 499, 1867, 1269, 4293, 14633, 0 }; - static ulong[] dim1172JoeKuoD5Init = { 1, 1, 3, 5, 15, 37, 29, 75, 191, 41, 11, 339, 485, 13635, 0 }; - static ulong[] dim1173JoeKuoD5Init = { 1, 3, 7, 7, 27, 53, 13, 121, 209, 411, 51, 1003, 6587, 8247, 0 }; - static ulong[] dim1174JoeKuoD5Init = { 1, 1, 7, 5, 13, 7, 43, 155, 467, 491, 1181, 1105, 2165, 16347, 0 }; - static ulong[] dim1175JoeKuoD5Init = { 1, 3, 5, 3, 21, 19, 89, 25, 353, 223, 1063, 111, 611, 2225, 0 }; - static ulong[] dim1176JoeKuoD5Init = { 1, 3, 1, 9, 3, 41, 95, 183, 135, 919, 861, 2929, 7189, 5505, 0 }; - static ulong[] dim1177JoeKuoD5Init = { 1, 1, 7, 13, 13, 39, 85, 135, 403, 39, 1893, 3667, 2609, 9251, 0 }; - static ulong[] dim1178JoeKuoD5Init = { 1, 1, 1, 11, 25, 5, 1, 179, 491, 953, 393, 2005, 1401, 12589, 0 }; - static ulong[] dim1179JoeKuoD5Init = { 1, 3, 5, 7, 25, 19, 25, 73, 63, 897, 701, 345, 4995, 2411, 0 }; - static ulong[] dim1180JoeKuoD5Init = { 1, 1, 7, 3, 31, 15, 121, 161, 127, 847, 1547, 3379, 4763, 8349, 0 }; - static ulong[] dim1181JoeKuoD5Init = { 1, 3, 7, 7, 25, 61, 87, 235, 117, 861, 977, 2979, 3333, 10911, 0 }; - static ulong[] dim1182JoeKuoD5Init = { 1, 1, 5, 9, 5, 57, 33, 129, 295, 225, 1497, 2367, 5379, 12721, 0 }; - static ulong[] dim1183JoeKuoD5Init = { 1, 1, 7, 11, 19, 43, 43, 217, 139, 637, 567, 3661, 2807, 11061, 0 }; - static ulong[] dim1184JoeKuoD5Init = { 1, 3, 1, 7, 27, 41, 97, 89, 53, 375, 1871, 2575, 1545, 455, 0 }; - static ulong[] dim1185JoeKuoD5Init = { 1, 1, 5, 3, 13, 15, 77, 229, 329, 663, 1943, 1411, 5755, 16279, 0 }; - static ulong[] dim1186JoeKuoD5Init = { 1, 3, 7, 9, 1, 3, 65, 21, 239, 619, 1801, 233, 3441, 12777, 0 }; - static ulong[] dim1187JoeKuoD5Init = { 1, 3, 1, 5, 9, 63, 9, 19, 65, 759, 1871, 3537, 4453, 15443, 0 }; - static ulong[] dim1188JoeKuoD5Init = { 1, 1, 3, 5, 17, 35, 43, 199, 167, 507, 669, 3593, 1645, 11791, 0 }; - static ulong[] dim1189JoeKuoD5Init = { 1, 3, 1, 7, 25, 21, 111, 171, 349, 423, 1793, 659, 5211, 3547, 0 }; - static ulong[] dim1190JoeKuoD5Init = { 1, 3, 3, 13, 23, 53, 95, 81, 383, 639, 1113, 2021, 7897, 4803, 0 }; - static ulong[] dim1191JoeKuoD5Init = { 1, 1, 5, 9, 19, 63, 61, 165, 3, 565, 829, 3071, 6605, 3625, 0 }; - static ulong[] dim1192JoeKuoD5Init = { 1, 3, 1, 15, 13, 53, 89, 97, 307, 555, 2039, 2753, 169, 941, 0 }; - static ulong[] dim1193JoeKuoD5Init = { 1, 1, 7, 3, 9, 41, 45, 89, 155, 269, 51, 3791, 5563, 4757, 0 }; - static ulong[] dim1194JoeKuoD5Init = { 1, 1, 1, 7, 23, 35, 19, 93, 205, 51, 375, 2107, 6357, 16257, 0 }; - static ulong[] dim1195JoeKuoD5Init = { 1, 1, 1, 5, 3, 45, 107, 141, 315, 107, 219, 51, 7629, 6865, 0 }; - static ulong[] dim1196JoeKuoD5Init = { 1, 1, 7, 1, 19, 23, 17, 77, 409, 59, 1649, 4029, 6541, 1075, 0 }; - static ulong[] dim1197JoeKuoD5Init = { 1, 1, 5, 11, 1, 37, 13, 221, 277, 61, 1509, 1713, 4597, 5907, 0 }; - static ulong[] dim1198JoeKuoD5Init = { 1, 1, 5, 1, 19, 53, 109, 123, 243, 1001, 291, 2265, 45, 437, 0 }; - static ulong[] dim1199JoeKuoD5Init = { 1, 3, 1, 1, 17, 63, 65, 67, 359, 139, 699, 3037, 6123, 11885, 0 }; - static ulong[] dim1200JoeKuoD5Init = { 1, 1, 5, 1, 3, 45, 125, 107, 75, 631, 769, 1431, 2089, 4919, 0 }; - static ulong[] dim1201JoeKuoD5Init = { 1, 3, 7, 5, 27, 31, 63, 75, 265, 727, 1197, 3549, 7677, 10831, 0 }; - static ulong[] dim1202JoeKuoD5Init = { 1, 3, 5, 15, 17, 61, 67, 169, 325, 627, 489, 729, 3585, 14253, 0 }; - static ulong[] dim1203JoeKuoD5Init = { 1, 1, 1, 5, 1, 39, 23, 11, 23, 3, 973, 2161, 5613, 5711, 0 }; - static ulong[] dim1204JoeKuoD5Init = { 1, 1, 7, 11, 3, 33, 31, 139, 275, 391, 1625, 2037, 389, 3853, 0 }; - static ulong[] dim1205JoeKuoD5Init = { 1, 3, 5, 1, 17, 47, 19, 171, 219, 959, 1623, 1069, 1833, 4467, 0 }; - static ulong[] dim1206JoeKuoD5Init = { 1, 3, 1, 11, 3, 29, 59, 159, 385, 183, 1091, 491, 8087, 4047, 0 }; - static ulong[] dim1207JoeKuoD5Init = { 1, 3, 3, 5, 19, 3, 121, 29, 97, 345, 1573, 2993, 7987, 5397, 0 }; - static ulong[] dim1208JoeKuoD5Init = { 1, 1, 1, 1, 31, 9, 57, 33, 489, 389, 1065, 2715, 5955, 11267, 0 }; - static ulong[] dim1209JoeKuoD5Init = { 1, 1, 1, 1, 25, 7, 67, 245, 159, 987, 1297, 277, 2223, 9865, 0 }; - static ulong[] dim1210JoeKuoD5Init = { 1, 1, 7, 1, 5, 11, 109, 171, 181, 303, 1875, 1915, 5007, 15563, 0 }; - static ulong[] dim1211JoeKuoD5Init = { 1, 3, 3, 1, 21, 7, 67, 155, 503, 751, 1721, 3405, 4717, 12567, 0 }; - static ulong[] dim1212JoeKuoD5Init = { 1, 1, 1, 1, 1, 51, 67, 57, 373, 835, 911, 3899, 7235, 5943, 0 }; - static ulong[] dim1213JoeKuoD5Init = { 1, 3, 7, 1, 21, 63, 21, 209, 321, 75, 551, 2741, 535, 14693, 0 }; - static ulong[] dim1214JoeKuoD5Init = { 1, 3, 5, 11, 21, 53, 23, 189, 463, 707, 637, 4055, 851, 12377, 0 }; - static ulong[] dim1215JoeKuoD5Init = { 1, 3, 7, 3, 13, 39, 17, 7, 487, 731, 1965, 2395, 5129, 6677, 0 }; - static ulong[] dim1216JoeKuoD5Init = { 1, 1, 1, 9, 5, 57, 15, 247, 325, 789, 1771, 2811, 6453, 7031, 0 }; - static ulong[] dim1217JoeKuoD5Init = { 1, 3, 3, 13, 21, 21, 27, 113, 345, 999, 7, 3241, 2569, 9175, 0 }; - static ulong[] dim1218JoeKuoD5Init = { 1, 3, 7, 5, 19, 41, 51, 37, 409, 553, 693, 1877, 4015, 1749, 0 }; - static ulong[] dim1219JoeKuoD5Init = { 1, 3, 1, 11, 3, 7, 11, 197, 5, 601, 451, 2117, 4519, 5913, 0 }; - static ulong[] dim1220JoeKuoD5Init = { 1, 1, 3, 7, 11, 53, 81, 187, 169, 419, 175, 2041, 2537, 16333, 0 }; - static ulong[] dim1221JoeKuoD5Init = { 1, 1, 7, 1, 1, 9, 117, 33, 233, 581, 1575, 2131, 2065, 6597, 0 }; - static ulong[] dim1222JoeKuoD5Init = { 1, 3, 5, 3, 27, 7, 111, 51, 311, 297, 1773, 193, 5599, 271, 0 }; - static ulong[] dim1223JoeKuoD5Init = { 1, 3, 1, 7, 17, 49, 85, 247, 7, 1005, 1191, 399, 7775, 5635, 0 }; - static ulong[] dim1224JoeKuoD5Init = { 1, 1, 1, 9, 31, 23, 9, 251, 97, 835, 813, 1335, 7955, 3977, 0 }; - static ulong[] dim1225JoeKuoD5Init = { 1, 1, 1, 15, 3, 39, 5, 19, 111, 523, 1475, 2169, 4121, 1171, 0 }; - static ulong[] dim1226JoeKuoD5Init = { 1, 3, 7, 9, 3, 19, 73, 43, 45, 57, 165, 3659, 7585, 8549, 0 }; - static ulong[] dim1227JoeKuoD5Init = { 1, 3, 3, 11, 25, 57, 117, 15, 289, 953, 1123, 2327, 7957, 6043, 0 }; - static ulong[] dim1228JoeKuoD5Init = { 1, 1, 5, 13, 7, 45, 63, 39, 349, 871, 1215, 2915, 1061, 7633, 0 }; - static ulong[] dim1229JoeKuoD5Init = { 1, 3, 5, 15, 1, 33, 55, 213, 245, 221, 259, 1679, 1507, 14275, 0 }; - static ulong[] dim1230JoeKuoD5Init = { 1, 3, 7, 3, 5, 15, 59, 55, 349, 121, 1471, 2119, 2559, 6379, 0 }; - static ulong[] dim1231JoeKuoD5Init = { 1, 1, 5, 3, 7, 23, 125, 137, 171, 775, 1069, 605, 2945, 16089, 0 }; - static ulong[] dim1232JoeKuoD5Init = { 1, 1, 7, 7, 9, 9, 43, 131, 385, 527, 757, 1263, 5285, 16309, 0 }; - static ulong[] dim1233JoeKuoD5Init = { 1, 3, 5, 3, 3, 39, 5, 163, 459, 697, 715, 3827, 3295, 9163, 0 }; - static ulong[] dim1234JoeKuoD5Init = { 1, 1, 7, 15, 7, 29, 7, 177, 207, 465, 59, 1485, 7731, 9843, 0 }; - static ulong[] dim1235JoeKuoD5Init = { 1, 3, 7, 13, 21, 57, 87, 191, 399, 689, 935, 2771, 1025, 715, 0 }; - static ulong[] dim1236JoeKuoD5Init = { 1, 3, 3, 1, 29, 19, 107, 253, 155, 163, 659, 3711, 2127, 10465, 0 }; - static ulong[] dim1237JoeKuoD5Init = { 1, 3, 3, 13, 7, 43, 27, 211, 407, 153, 1939, 3243, 6655, 15983, 0 }; - static ulong[] dim1238JoeKuoD5Init = { 1, 1, 1, 5, 27, 21, 23, 63, 271, 515, 261, 1947, 6257, 12861, 0 }; - static ulong[] dim1239JoeKuoD5Init = { 1, 3, 3, 1, 19, 57, 67, 221, 179, 725, 1179, 3983, 1585, 5899, 0 }; - static ulong[] dim1240JoeKuoD5Init = { 1, 3, 3, 15, 7, 61, 97, 131, 145, 637, 733, 2533, 1993, 14399, 0 }; - static ulong[] dim1241JoeKuoD5Init = { 1, 1, 5, 15, 13, 39, 83, 247, 235, 621, 1557, 3075, 3165, 16027, 0 }; - static ulong[] dim1242JoeKuoD5Init = { 1, 1, 1, 15, 9, 11, 111, 153, 437, 687, 1845, 3547, 2097, 2219, 0 }; - static ulong[] dim1243JoeKuoD5Init = { 1, 1, 7, 13, 21, 13, 43, 33, 51, 1021, 1883, 1261, 2823, 12771, 0 }; - static ulong[] dim1244JoeKuoD5Init = { 1, 3, 3, 9, 3, 35, 19, 127, 419, 203, 1869, 1477, 5239, 6113, 0 }; - static ulong[] dim1245JoeKuoD5Init = { 1, 1, 5, 13, 31, 63, 75, 185, 507, 401, 1079, 67, 1621, 2849, 0 }; - static ulong[] dim1246JoeKuoD5Init = { 1, 1, 1, 1, 31, 61, 125, 77, 169, 51, 1115, 1625, 3533, 5953, 0 }; - static ulong[] dim1247JoeKuoD5Init = { 1, 1, 3, 15, 29, 51, 23, 43, 505, 313, 887, 551, 4401, 2133, 0 }; - static ulong[] dim1248JoeKuoD5Init = { 1, 3, 7, 15, 11, 37, 55, 161, 353, 347, 1991, 4009, 2073, 12169, 0 }; - static ulong[] dim1249JoeKuoD5Init = { 1, 3, 3, 11, 29, 51, 15, 13, 391, 677, 225, 1467, 6615, 1895, 0 }; - static ulong[] dim1250JoeKuoD5Init = { 1, 1, 7, 3, 29, 15, 93, 103, 147, 323, 837, 1983, 1613, 10667, 0 }; - static ulong[] dim1251JoeKuoD5Init = { 1, 1, 5, 9, 21, 11, 39, 95, 473, 591, 1645, 67, 2793, 11217, 0 }; - static ulong[] dim1252JoeKuoD5Init = { 1, 3, 7, 5, 9, 51, 1, 243, 445, 583, 375, 2289, 4911, 10511, 0 }; - static ulong[] dim1253JoeKuoD5Init = { 1, 1, 7, 7, 23, 15, 111, 239, 247, 511, 1723, 2911, 2627, 10549, 0 }; - static ulong[] dim1254JoeKuoD5Init = { 1, 3, 1, 9, 15, 37, 31, 135, 347, 599, 765, 2561, 4635, 10659, 0 }; - static ulong[] dim1255JoeKuoD5Init = { 1, 1, 5, 11, 9, 49, 93, 187, 415, 247, 1871, 617, 6711, 3283, 0 }; - static ulong[] dim1256JoeKuoD5Init = { 1, 3, 7, 11, 25, 25, 37, 97, 365, 477, 1383, 1357, 693, 14743, 0 }; - static ulong[] dim1257JoeKuoD5Init = { 1, 1, 3, 11, 25, 19, 109, 99, 471, 661, 1633, 3773, 921, 4113, 0 }; - static ulong[] dim1258JoeKuoD5Init = { 1, 1, 3, 11, 13, 61, 21, 255, 161, 233, 1181, 3003, 1465, 9299, 0 }; - static ulong[] dim1259JoeKuoD5Init = { 1, 3, 7, 5, 7, 59, 53, 129, 127, 961, 893, 499, 5265, 2299, 0 }; - static ulong[] dim1260JoeKuoD5Init = { 1, 1, 5, 9, 29, 45, 85, 173, 131, 775, 1527, 1899, 4833, 12763, 0 }; - static ulong[] dim1261JoeKuoD5Init = { 1, 1, 7, 3, 1, 1, 115, 245, 205, 609, 1729, 915, 5965, 11001, 0 }; - static ulong[] dim1262JoeKuoD5Init = { 1, 1, 3, 15, 3, 61, 91, 93, 363, 457, 1497, 2539, 553, 7581, 0 }; - static ulong[] dim1263JoeKuoD5Init = { 1, 1, 3, 1, 29, 5, 7, 171, 393, 381, 935, 3467, 6199, 6625, 0 }; - static ulong[] dim1264JoeKuoD5Init = { 1, 1, 7, 13, 15, 25, 65, 137, 349, 61, 1035, 591, 4317, 13949, 0 }; - static ulong[] dim1265JoeKuoD5Init = { 1, 1, 3, 9, 27, 17, 87, 233, 227, 341, 639, 1813, 871, 12871, 0 }; - static ulong[] dim1266JoeKuoD5Init = { 1, 3, 1, 13, 29, 15, 31, 81, 61, 857, 1305, 3631, 2919, 2093, 0 }; - static ulong[] dim1267JoeKuoD5Init = { 1, 1, 1, 3, 27, 5, 49, 1, 49, 745, 543, 847, 2469, 3513, 0 }; - static ulong[] dim1268JoeKuoD5Init = { 1, 1, 1, 3, 15, 39, 47, 73, 33, 469, 1809, 2105, 7995, 11285, 0 }; - static ulong[] dim1269JoeKuoD5Init = { 1, 3, 5, 15, 9, 9, 81, 211, 295, 791, 1267, 2945, 5639, 6967, 0 }; - static ulong[] dim1270JoeKuoD5Init = { 1, 1, 7, 9, 13, 11, 43, 221, 161, 263, 905, 2767, 4491, 7605, 0 }; - static ulong[] dim1271JoeKuoD5Init = { 1, 1, 3, 15, 13, 9, 91, 123, 449, 21, 941, 1391, 3469, 16027, 0 }; - static ulong[] dim1272JoeKuoD5Init = { 1, 1, 3, 11, 5, 13, 77, 69, 245, 905, 231, 547, 2933, 4307, 0 }; - static ulong[] dim1273JoeKuoD5Init = { 1, 1, 3, 1, 25, 59, 49, 49, 183, 213, 29, 1801, 6271, 16283, 0 }; - static ulong[] dim1274JoeKuoD5Init = { 1, 1, 3, 11, 3, 15, 35, 157, 87, 453, 1939, 2697, 3325, 8679, 0 }; - static ulong[] dim1275JoeKuoD5Init = { 1, 1, 7, 13, 7, 45, 77, 73, 203, 321, 425, 581, 481, 15367, 0 }; - static ulong[] dim1276JoeKuoD5Init = { 1, 3, 1, 15, 11, 51, 11, 59, 355, 677, 1565, 123, 2403, 12835, 0 }; - static ulong[] dim1277JoeKuoD5Init = { 1, 1, 3, 5, 7, 27, 17, 81, 295, 131, 955, 4065, 797, 16165, 0 }; - static ulong[] dim1278JoeKuoD5Init = { 1, 1, 1, 5, 29, 63, 51, 215, 269, 1013, 517, 1857, 141, 4495, 0 }; - static ulong[] dim1279JoeKuoD5Init = { 1, 3, 7, 5, 17, 47, 121, 199, 177, 1023, 1009, 3535, 4825, 16349, 0 }; - static ulong[] dim1280JoeKuoD5Init = { 1, 1, 5, 1, 21, 25, 107, 165, 43, 213, 1847, 1945, 3463, 2259, 0 }; - static ulong[] dim1281JoeKuoD5Init = { 1, 3, 5, 7, 5, 5, 5, 65, 493, 725, 755, 111, 6673, 213, 0 }; - static ulong[] dim1282JoeKuoD5Init = { 1, 1, 3, 1, 3, 29, 17, 87, 207, 793, 873, 2341, 3505, 5751, 0 }; - static ulong[] dim1283JoeKuoD5Init = { 1, 1, 3, 7, 27, 47, 123, 157, 427, 273, 139, 4043, 4083, 14121, 0 }; - static ulong[] dim1284JoeKuoD5Init = { 1, 3, 7, 9, 25, 17, 41, 245, 441, 47, 1, 2393, 405, 4021, 0 }; - static ulong[] dim1285JoeKuoD5Init = { 1, 3, 3, 13, 31, 9, 115, 165, 93, 701, 255, 895, 995, 12371, 0 }; - static ulong[] dim1286JoeKuoD5Init = { 1, 1, 1, 11, 23, 13, 9, 141, 31, 973, 441, 3335, 2567, 6993, 0 }; - static ulong[] dim1287JoeKuoD5Init = { 1, 1, 1, 13, 19, 25, 61, 139, 39, 987, 385, 2199, 7675, 13301, 0 }; - static ulong[] dim1288JoeKuoD5Init = { 1, 3, 5, 3, 1, 35, 121, 187, 273, 905, 245, 1031, 6203, 8165, 0 }; - static ulong[] dim1289JoeKuoD5Init = { 1, 1, 5, 13, 31, 59, 97, 45, 25, 803, 1245, 2659, 7471, 8367, 0 }; - static ulong[] dim1290JoeKuoD5Init = { 1, 1, 5, 11, 21, 41, 47, 183, 419, 279, 1901, 1081, 3575, 8591, 0 }; - static ulong[] dim1291JoeKuoD5Init = { 1, 3, 3, 5, 11, 39, 119, 245, 403, 703, 1547, 743, 7957, 15123, 0 }; - static ulong[] dim1292JoeKuoD5Init = { 1, 3, 5, 11, 11, 31, 71, 55, 3, 961, 991, 1665, 5539, 8187, 0 }; - static ulong[] dim1293JoeKuoD5Init = { 1, 1, 3, 3, 19, 7, 1, 35, 463, 1003, 555, 669, 2119, 10939, 0 }; - static ulong[] dim1294JoeKuoD5Init = { 1, 3, 3, 13, 17, 29, 99, 133, 107, 907, 7, 3047, 1263, 7497, 0 }; - static ulong[] dim1295JoeKuoD5Init = { 1, 3, 3, 15, 1, 53, 39, 191, 201, 189, 465, 453, 1967, 1033, 0 }; - static ulong[] dim1296JoeKuoD5Init = { 1, 3, 7, 13, 25, 19, 5, 155, 105, 923, 2045, 2889, 7685, 13847, 0 }; - static ulong[] dim1297JoeKuoD5Init = { 1, 3, 7, 13, 7, 61, 93, 41, 183, 783, 2011, 2967, 2949, 10247, 0 }; - static ulong[] dim1298JoeKuoD5Init = { 1, 1, 7, 9, 3, 53, 105, 63, 9, 131, 897, 347, 7683, 16027, 0 }; - static ulong[] dim1299JoeKuoD5Init = { 1, 1, 1, 9, 19, 37, 37, 143, 37, 493, 533, 733, 2295, 4203, 0 }; - static ulong[] dim1300JoeKuoD5Init = { 1, 3, 7, 5, 15, 23, 83, 185, 495, 1023, 1473, 1501, 373, 201, 0 }; - static ulong[] dim1301JoeKuoD5Init = { 1, 1, 3, 13, 31, 51, 115, 233, 289, 201, 869, 3177, 4649, 16111, 0 }; - static ulong[] dim1302JoeKuoD5Init = { 1, 3, 5, 5, 23, 7, 59, 233, 447, 781, 1249, 71, 5857, 15481, 0 }; - static ulong[] dim1303JoeKuoD5Init = { 1, 1, 3, 11, 31, 1, 67, 243, 129, 737, 1443, 3647, 2391, 3635, 0 }; - static ulong[] dim1304JoeKuoD5Init = { 1, 3, 7, 1, 17, 39, 117, 81, 395, 119, 413, 1295, 7889, 13569, 0 }; - static ulong[] dim1305JoeKuoD5Init = { 1, 3, 3, 5, 29, 5, 123, 89, 143, 779, 1173, 3211, 3027, 10145, 0 }; - static ulong[] dim1306JoeKuoD5Init = { 1, 1, 1, 7, 19, 53, 39, 199, 487, 797, 123, 871, 6335, 7957, 0 }; - static ulong[] dim1307JoeKuoD5Init = { 1, 3, 1, 7, 13, 11, 105, 121, 403, 283, 413, 1957, 6557, 8429, 0 }; - static ulong[] dim1308JoeKuoD5Init = { 1, 1, 5, 3, 23, 21, 109, 37, 463, 613, 927, 1857, 7003, 3477, 0 }; - static ulong[] dim1309JoeKuoD5Init = { 1, 3, 1, 1, 15, 37, 81, 27, 259, 661, 287, 615, 6151, 13759, 0 }; - static ulong[] dim1310JoeKuoD5Init = { 1, 1, 7, 7, 27, 59, 85, 223, 499, 571, 1853, 1419, 7761, 8385, 0 }; - static ulong[] dim1311JoeKuoD5Init = { 1, 3, 7, 9, 23, 57, 53, 163, 437, 657, 851, 3177, 6477, 13003, 0 }; - static ulong[] dim1312JoeKuoD5Init = { 1, 3, 7, 13, 3, 7, 37, 167, 49, 595, 1493, 369, 687, 13463, 0 }; - static ulong[] dim1313JoeKuoD5Init = { 1, 3, 1, 11, 27, 63, 49, 157, 379, 779, 99, 3457, 4477, 6531, 0 }; - static ulong[] dim1314JoeKuoD5Init = { 1, 1, 1, 1, 5, 55, 77, 159, 371, 369, 743, 3571, 1877, 14767, 0 }; - static ulong[] dim1315JoeKuoD5Init = { 1, 3, 1, 15, 25, 11, 65, 187, 253, 437, 1301, 2871, 6219, 817, 0 }; - static ulong[] dim1316JoeKuoD5Init = { 1, 1, 7, 13, 23, 33, 25, 49, 491, 315, 11, 2163, 6155, 23, 0 }; - static ulong[] dim1317JoeKuoD5Init = { 1, 3, 5, 7, 27, 31, 81, 7, 355, 289, 1481, 2969, 1067, 7399, 0 }; - static ulong[] dim1318JoeKuoD5Init = { 1, 1, 1, 7, 1, 57, 39, 201, 271, 223, 1117, 727, 7491, 4043, 0 }; - static ulong[] dim1319JoeKuoD5Init = { 1, 3, 1, 7, 9, 57, 17, 161, 221, 385, 2027, 1195, 2489, 12377, 0 }; - static ulong[] dim1320JoeKuoD5Init = { 1, 3, 1, 3, 27, 59, 101, 27, 177, 1005, 63, 3029, 7345, 14429, 0 }; - static ulong[] dim1321JoeKuoD5Init = { 1, 1, 7, 7, 17, 5, 111, 239, 85, 57, 1625, 657, 5931, 4929, 0 }; - static ulong[] dim1322JoeKuoD5Init = { 1, 3, 7, 3, 7, 41, 29, 9, 73, 875, 1665, 325, 27, 997, 0 }; - static ulong[] dim1323JoeKuoD5Init = { 1, 1, 5, 7, 21, 61, 119, 247, 307, 1011, 1489, 2361, 5781, 2465, 0 }; - static ulong[] dim1324JoeKuoD5Init = { 1, 3, 7, 3, 1, 21, 105, 77, 57, 983, 1519, 3543, 5025, 14051, 0 }; - static ulong[] dim1325JoeKuoD5Init = { 1, 1, 3, 5, 13, 39, 113, 69, 81, 155, 101, 427, 733, 10085, 0 }; - static ulong[] dim1326JoeKuoD5Init = { 1, 3, 1, 3, 1, 25, 109, 109, 303, 323, 565, 2267, 2755, 9165, 0 }; - static ulong[] dim1327JoeKuoD5Init = { 1, 1, 5, 3, 15, 43, 103, 163, 265, 849, 1969, 2247, 4495, 7301, 0 }; - static ulong[] dim1328JoeKuoD5Init = { 1, 1, 3, 3, 23, 9, 81, 103, 193, 845, 1603, 2493, 4919, 10649, 0 }; - static ulong[] dim1329JoeKuoD5Init = { 1, 1, 5, 1, 9, 23, 91, 33, 115, 599, 1755, 53, 1757, 145, 0 }; - static ulong[] dim1330JoeKuoD5Init = { 1, 3, 1, 11, 1, 39, 5, 233, 399, 187, 943, 2325, 437, 4421, 0 }; - static ulong[] dim1331JoeKuoD5Init = { 1, 1, 5, 13, 11, 39, 29, 131, 363, 885, 1921, 3703, 4197, 9703, 0 }; - static ulong[] dim1332JoeKuoD5Init = { 1, 3, 7, 5, 21, 43, 27, 151, 193, 211, 1229, 4031, 681, 5103, 0 }; - static ulong[] dim1333JoeKuoD5Init = { 1, 3, 7, 3, 19, 23, 41, 47, 315, 169, 271, 1877, 6357, 7709, 0 }; - static ulong[] dim1334JoeKuoD5Init = { 1, 3, 5, 1, 11, 27, 123, 33, 287, 293, 335, 2331, 141, 10095, 0 }; - static ulong[] dim1335JoeKuoD5Init = { 1, 1, 3, 5, 15, 33, 93, 123, 277, 833, 115, 3799, 1519, 153, 0 }; - static ulong[] dim1336JoeKuoD5Init = { 1, 1, 7, 15, 11, 3, 97, 225, 179, 601, 687, 253, 2839, 10985, 0 }; - static ulong[] dim1337JoeKuoD5Init = { 1, 3, 5, 3, 11, 51, 5, 141, 487, 325, 1691, 1291, 4677, 9087, 0 }; - static ulong[] dim1338JoeKuoD5Init = { 1, 3, 5, 9, 5, 11, 99, 195, 459, 171, 361, 1621, 5377, 4651, 0 }; - static ulong[] dim1339JoeKuoD5Init = { 1, 3, 3, 3, 29, 47, 5, 29, 107, 751, 739, 2815, 3709, 15493, 0 }; - static ulong[] dim1340JoeKuoD5Init = { 1, 3, 7, 1, 3, 63, 47, 15, 433, 501, 1687, 2035, 6263, 12681, 0 }; - static ulong[] dim1341JoeKuoD5Init = { 1, 3, 7, 13, 1, 57, 91, 33, 217, 141, 2005, 2405, 1987, 14957, 0 }; - static ulong[] dim1342JoeKuoD5Init = { 1, 3, 3, 13, 25, 23, 93, 37, 129, 747, 1607, 849, 2119, 11855, 0 }; - static ulong[] dim1343JoeKuoD5Init = { 1, 3, 5, 9, 15, 55, 55, 125, 235, 455, 2027, 1709, 7217, 10341, 0 }; - static ulong[] dim1344JoeKuoD5Init = { 1, 3, 5, 7, 1, 3, 69, 167, 373, 87, 901, 2333, 6751, 5809, 0 }; - static ulong[] dim1345JoeKuoD5Init = { 1, 3, 5, 9, 19, 25, 67, 197, 395, 735, 941, 1753, 3923, 8805, 0 }; - static ulong[] dim1346JoeKuoD5Init = { 1, 1, 7, 9, 17, 29, 1, 205, 511, 179, 1191, 17, 3179, 6891, 0 }; - static ulong[] dim1347JoeKuoD5Init = { 1, 1, 1, 9, 9, 31, 99, 133, 253, 239, 1729, 4093, 5759, 15357, 0 }; - static ulong[] dim1348JoeKuoD5Init = { 1, 1, 7, 3, 31, 35, 125, 167, 417, 431, 709, 415, 1093, 11361, 0 }; - static ulong[] dim1349JoeKuoD5Init = { 1, 1, 7, 11, 7, 59, 57, 89, 119, 537, 1157, 2539, 5783, 15093, 0 }; - static ulong[] dim1350JoeKuoD5Init = { 1, 1, 5, 7, 17, 41, 105, 33, 301, 601, 537, 3877, 797, 1319, 0 }; - static ulong[] dim1351JoeKuoD5Init = { 1, 1, 7, 7, 3, 59, 79, 47, 191, 985, 83, 3535, 4135, 16165, 0 }; - static ulong[] dim1352JoeKuoD5Init = { 1, 3, 7, 3, 13, 61, 35, 193, 141, 961, 1733, 4051, 2657, 9183, 0 }; - static ulong[] dim1353JoeKuoD5Init = { 1, 3, 3, 9, 25, 49, 127, 233, 291, 445, 1639, 4023, 4791, 279, 0 }; - static ulong[] dim1354JoeKuoD5Init = { 1, 1, 7, 11, 15, 39, 91, 81, 433, 7, 1897, 2659, 7877, 15733, 0 }; - static ulong[] dim1355JoeKuoD5Init = { 1, 3, 3, 5, 19, 5, 125, 181, 305, 377, 1699, 2157, 4617, 7165, 0 }; - static ulong[] dim1356JoeKuoD5Init = { 1, 3, 5, 13, 11, 27, 19, 217, 171, 343, 61, 3799, 4923, 14279, 0 }; - static ulong[] dim1357JoeKuoD5Init = { 1, 1, 1, 15, 13, 41, 19, 19, 359, 101, 1795, 127, 7067, 4327, 0 }; - static ulong[] dim1358JoeKuoD5Init = { 1, 3, 5, 15, 15, 5, 43, 47, 103, 549, 767, 2695, 1689, 5569, 0 }; - static ulong[] dim1359JoeKuoD5Init = { 1, 1, 7, 9, 7, 33, 35, 105, 283, 957, 1255, 2085, 6263, 4537, 0 }; - static ulong[] dim1360JoeKuoD5Init = { 1, 3, 7, 9, 27, 23, 49, 169, 455, 163, 301, 3107, 6859, 14477, 0 }; - static ulong[] dim1361JoeKuoD5Init = { 1, 1, 5, 15, 13, 11, 25, 231, 171, 173, 661, 1921, 3535, 10157, 0 }; - static ulong[] dim1362JoeKuoD5Init = { 1, 1, 7, 11, 27, 19, 23, 97, 409, 347, 1413, 2273, 7305, 12597, 0 }; - static ulong[] dim1363JoeKuoD5Init = { 1, 3, 7, 15, 11, 63, 49, 247, 459, 195, 1579, 539, 6283, 14829, 0 }; - static ulong[] dim1364JoeKuoD5Init = { 1, 3, 3, 5, 19, 37, 105, 31, 87, 413, 511, 271, 6265, 9499, 0 }; - static ulong[] dim1365JoeKuoD5Init = { 1, 1, 3, 13, 23, 39, 97, 239, 397, 975, 1369, 2397, 409, 3495, 0 }; - static ulong[] dim1366JoeKuoD5Init = { 1, 3, 1, 1, 25, 45, 11, 81, 233, 299, 1269, 1129, 1679, 10195, 0 }; - static ulong[] dim1367JoeKuoD5Init = { 1, 3, 3, 5, 13, 29, 3, 189, 231, 535, 1201, 1215, 1889, 6169, 0 }; - static ulong[] dim1368JoeKuoD5Init = { 1, 3, 1, 15, 31, 53, 17, 197, 453, 13, 181, 2663, 3869, 7269, 0 }; - static ulong[] dim1369JoeKuoD5Init = { 1, 1, 1, 5, 27, 37, 71, 89, 505, 769, 1359, 295, 6061, 8363, 0 }; - static ulong[] dim1370JoeKuoD5Init = { 1, 3, 3, 1, 9, 1, 111, 157, 89, 777, 1713, 117, 285, 6353, 0 }; - static ulong[] dim1371JoeKuoD5Init = { 1, 1, 7, 11, 29, 53, 57, 3, 225, 885, 1445, 3673, 7857, 3843, 0 }; - static ulong[] dim1372JoeKuoD5Init = { 1, 3, 3, 11, 29, 23, 43, 19, 175, 573, 1709, 2303, 5607, 4347, 0 }; - static ulong[] dim1373JoeKuoD5Init = { 1, 1, 5, 7, 19, 41, 93, 13, 3, 483, 1365, 411, 5147, 10505, 0 }; - static ulong[] dim1374JoeKuoD5Init = { 1, 1, 7, 7, 3, 17, 51, 23, 19, 411, 741, 877, 7121, 7639, 0 }; - static ulong[] dim1375JoeKuoD5Init = { 1, 1, 5, 3, 7, 45, 103, 69, 387, 803, 29, 1469, 2139, 6397, 0 }; - static ulong[] dim1376JoeKuoD5Init = { 1, 3, 1, 3, 11, 43, 5, 19, 441, 285, 1657, 2133, 6343, 11817, 0 }; - static ulong[] dim1377JoeKuoD5Init = { 1, 3, 5, 1, 31, 31, 19, 15, 475, 131, 1687, 1647, 4685, 1135, 0 }; - static ulong[] dim1378JoeKuoD5Init = { 1, 1, 7, 7, 17, 59, 125, 127, 63, 451, 949, 4041, 6649, 12187, 0 }; - static ulong[] dim1379JoeKuoD5Init = { 1, 3, 3, 1, 25, 13, 59, 159, 107, 509, 787, 2517, 6679, 2809, 0 }; - static ulong[] dim1380JoeKuoD5Init = { 1, 3, 7, 5, 17, 5, 87, 235, 379, 599, 1971, 969, 853, 10481, 0 }; - static ulong[] dim1381JoeKuoD5Init = { 1, 1, 3, 15, 7, 35, 47, 113, 349, 451, 1827, 2647, 367, 2581, 0 }; - static ulong[] dim1382JoeKuoD5Init = { 1, 1, 7, 9, 1, 39, 29, 45, 365, 317, 129, 137, 5975, 3353, 0 }; - static ulong[] dim1383JoeKuoD5Init = { 1, 1, 1, 15, 17, 3, 5, 61, 11, 587, 769, 2127, 2625, 12545, 0 }; - static ulong[] dim1384JoeKuoD5Init = { 1, 3, 1, 7, 21, 1, 127, 235, 343, 807, 147, 3517, 3471, 4625, 0 }; - static ulong[] dim1385JoeKuoD5Init = { 1, 1, 3, 15, 31, 23, 81, 23, 171, 403, 1083, 4049, 1959, 16307, 0 }; - static ulong[] dim1386JoeKuoD5Init = { 1, 3, 7, 9, 21, 37, 99, 83, 33, 705, 369, 2445, 3253, 16171, 0 }; - static ulong[] dim1387JoeKuoD5Init = { 1, 3, 5, 9, 17, 61, 121, 75, 89, 823, 1519, 1997, 6433, 5013, 0 }; - static ulong[] dim1388JoeKuoD5Init = { 1, 1, 3, 11, 7, 47, 7, 71, 475, 517, 1271, 3815, 5969, 607, 0 }; - static ulong[] dim1389JoeKuoD5Init = { 1, 1, 3, 3, 13, 15, 37, 89, 43, 489, 1853, 1195, 3097, 10297, 0 }; - static ulong[] dim1390JoeKuoD5Init = { 1, 3, 3, 11, 25, 39, 95, 43, 145, 231, 1859, 3201, 1377, 7091, 0 }; - static ulong[] dim1391JoeKuoD5Init = { 1, 1, 7, 3, 13, 43, 117, 111, 231, 101, 1801, 739, 945, 15585, 0 }; - static ulong[] dim1392JoeKuoD5Init = { 1, 3, 5, 7, 23, 3, 35, 167, 485, 951, 1729, 1831, 2639, 6561, 0 }; - static ulong[] dim1393JoeKuoD5Init = { 1, 3, 3, 15, 5, 31, 103, 85, 111, 545, 789, 945, 2691, 327, 0 }; - static ulong[] dim1394JoeKuoD5Init = { 1, 1, 5, 11, 29, 61, 127, 59, 137, 485, 1673, 3295, 4185, 6489, 0 }; - static ulong[] dim1395JoeKuoD5Init = { 1, 1, 5, 9, 31, 9, 115, 11, 73, 267, 195, 1445, 873, 7285, 0 }; - static ulong[] dim1396JoeKuoD5Init = { 1, 3, 3, 7, 3, 19, 9, 71, 287, 89, 329, 953, 2237, 16341, 0 }; - static ulong[] dim1397JoeKuoD5Init = { 1, 3, 1, 13, 19, 31, 5, 49, 293, 65, 291, 93, 2553, 8407, 0 }; - static ulong[] dim1398JoeKuoD5Init = { 1, 1, 5, 15, 17, 13, 15, 111, 211, 935, 1165, 2975, 339, 16333, 0 }; - static ulong[] dim1399JoeKuoD5Init = { 1, 1, 1, 3, 17, 57, 9, 63, 243, 431, 289, 3493, 2879, 4801, 0 }; - static ulong[] dim1400JoeKuoD5Init = { 1, 1, 7, 3, 17, 15, 53, 191, 439, 981, 751, 4025, 7177, 4887, 0 }; - static ulong[] dim1401JoeKuoD5Init = { 1, 1, 5, 3, 11, 61, 43, 103, 151, 33, 421, 1949, 5915, 5515, 0 }; - static ulong[] dim1402JoeKuoD5Init = { 1, 1, 5, 3, 1, 55, 45, 227, 27, 491, 1479, 3323, 5485, 5493, 0 }; - static ulong[] dim1403JoeKuoD5Init = { 1, 1, 7, 1, 9, 11, 1, 249, 113, 415, 295, 3437, 3877, 6675, 0 }; - static ulong[] dim1404JoeKuoD5Init = { 1, 1, 5, 11, 9, 43, 127, 57, 115, 685, 165, 973, 2707, 2503, 0 }; - static ulong[] dim1405JoeKuoD5Init = { 1, 1, 5, 7, 1, 29, 125, 45, 307, 625, 1477, 2565, 2949, 1729, 0 }; - static ulong[] dim1406JoeKuoD5Init = { 1, 3, 1, 1, 23, 7, 45, 245, 301, 531, 1419, 1795, 5757, 15219, 0 }; - static ulong[] dim1407JoeKuoD5Init = { 1, 3, 3, 7, 15, 49, 71, 109, 145, 79, 1333, 1589, 3851, 2879, 0 }; - static ulong[] dim1408JoeKuoD5Init = { 1, 1, 3, 5, 11, 15, 37, 239, 217, 193, 1687, 1721, 8059, 9027, 0 }; - static ulong[] dim1409JoeKuoD5Init = { 1, 3, 5, 13, 13, 49, 57, 189, 433, 569, 1285, 1891, 6079, 13469, 0 }; - static ulong[] dim1410JoeKuoD5Init = { 1, 3, 1, 1, 19, 61, 27, 181, 365, 121, 883, 1611, 1521, 11437, 0 }; - static ulong[] dim1411JoeKuoD5Init = { 1, 1, 5, 3, 17, 37, 71, 71, 495, 519, 879, 2993, 6275, 14345, 0 }; - static ulong[] dim1412JoeKuoD5Init = { 1, 1, 1, 5, 29, 5, 121, 29, 293, 745, 1839, 2061, 2721, 11741, 0 }; - static ulong[] dim1413JoeKuoD5Init = { 1, 3, 1, 13, 23, 61, 55, 99, 409, 211, 783, 1841, 193, 1941, 0 }; - static ulong[] dim1414JoeKuoD5Init = { 1, 1, 5, 7, 11, 49, 87, 81, 225, 211, 1263, 1403, 6169, 6235, 0 }; - static ulong[] dim1415JoeKuoD5Init = { 1, 1, 7, 9, 11, 35, 71, 145, 417, 485, 1565, 2101, 4153, 5239, 0 }; - static ulong[] dim1416JoeKuoD5Init = { 1, 1, 5, 1, 13, 41, 45, 79, 157, 477, 677, 3961, 1127, 1139, 0 }; - static ulong[] dim1417JoeKuoD5Init = { 1, 3, 1, 13, 27, 39, 23, 197, 123, 431, 273, 2723, 1303, 13271, 0 }; - static ulong[] dim1418JoeKuoD5Init = { 1, 3, 5, 9, 13, 21, 59, 109, 267, 173, 997, 2701, 3719, 3703, 0 }; - static ulong[] dim1419JoeKuoD5Init = { 1, 3, 3, 1, 1, 5, 57, 181, 241, 1, 1063, 199, 8181, 12721, 0 }; - static ulong[] dim1420JoeKuoD5Init = { 1, 1, 7, 9, 15, 61, 107, 231, 65, 933, 677, 3883, 2621, 8821, 0 }; - static ulong[] dim1421JoeKuoD5Init = { 1, 1, 7, 1, 9, 33, 41, 55, 503, 683, 747, 3619, 7885, 851, 0 }; - static ulong[] dim1422JoeKuoD5Init = { 1, 1, 5, 5, 9, 25, 27, 123, 97, 731, 583, 2535, 1267, 5921, 0 }; - static ulong[] dim1423JoeKuoD5Init = { 1, 3, 1, 15, 27, 63, 69, 99, 475, 709, 1239, 861, 1229, 11369, 0 }; - static ulong[] dim1424JoeKuoD5Init = { 1, 3, 3, 13, 17, 47, 123, 159, 57, 871, 465, 783, 4093, 15277, 0 }; - static ulong[] dim1425JoeKuoD5Init = { 1, 3, 7, 9, 17, 47, 89, 139, 301, 45, 627, 4073, 3187, 9633, 0 }; - static ulong[] dim1426JoeKuoD5Init = { 1, 3, 5, 11, 21, 43, 19, 25, 457, 879, 113, 847, 201, 15683, 0 }; - static ulong[] dim1427JoeKuoD5Init = { 1, 3, 3, 15, 9, 47, 43, 215, 407, 979, 51, 635, 467, 6365, 0 }; - static ulong[] dim1428JoeKuoD5Init = { 1, 3, 3, 5, 7, 11, 53, 5, 471, 317, 1719, 755, 5211, 7599, 0 }; - static ulong[] dim1429JoeKuoD5Init = { 1, 3, 1, 3, 11, 43, 67, 203, 15, 75, 1063, 1763, 3537, 13511, 0 }; - static ulong[] dim1430JoeKuoD5Init = { 1, 3, 7, 1, 17, 37, 91, 55, 95, 843, 751, 3501, 6203, 2999, 0 }; - static ulong[] dim1431JoeKuoD5Init = { 1, 3, 7, 13, 19, 61, 37, 157, 309, 361, 1499, 1845, 3675, 6221, 0 }; - static ulong[] dim1432JoeKuoD5Init = { 1, 3, 1, 11, 15, 9, 25, 123, 25, 525, 227, 3429, 1573, 12321, 0 }; - static ulong[] dim1433JoeKuoD5Init = { 1, 3, 7, 11, 9, 17, 91, 61, 263, 129, 1853, 1911, 5065, 775, 0 }; - static ulong[] dim1434JoeKuoD5Init = { 1, 1, 3, 3, 31, 15, 3, 207, 505, 123, 477, 1285, 7007, 2873, 0 }; - static ulong[] dim1435JoeKuoD5Init = { 1, 1, 1, 7, 7, 15, 123, 249, 467, 229, 845, 1913, 461, 6235, 0 }; - static ulong[] dim1436JoeKuoD5Init = { 1, 3, 3, 9, 15, 9, 121, 211, 231, 491, 521, 3621, 7285, 3165, 0 }; - static ulong[] dim1437JoeKuoD5Init = { 1, 1, 7, 15, 21, 43, 1, 35, 339, 671, 719, 1739, 501, 9573, 0 }; - static ulong[] dim1438JoeKuoD5Init = { 1, 1, 1, 5, 13, 37, 81, 1, 281, 785, 831, 991, 7485, 15619, 0 }; - static ulong[] dim1439JoeKuoD5Init = { 1, 3, 7, 1, 29, 47, 29, 99, 311, 519, 545, 1115, 6651, 793, 0 }; - static ulong[] dim1440JoeKuoD5Init = { 1, 3, 5, 11, 17, 15, 17, 65, 101, 411, 231, 2959, 8077, 673, 0 }; - static ulong[] dim1441JoeKuoD5Init = { 1, 3, 5, 9, 27, 47, 127, 237, 319, 293, 1109, 3863, 213, 2149, 0 }; - static ulong[] dim1442JoeKuoD5Init = { 1, 1, 3, 13, 11, 61, 27, 129, 57, 743, 889, 3707, 469, 11949, 0 }; - static ulong[] dim1443JoeKuoD5Init = { 1, 1, 7, 13, 23, 13, 119, 125, 75, 753, 1951, 1181, 291, 11737, 0 }; - static ulong[] dim1444JoeKuoD5Init = { 1, 3, 3, 5, 31, 19, 43, 113, 309, 721, 175, 1041, 7123, 103, 0 }; - static ulong[] dim1445JoeKuoD5Init = { 1, 3, 3, 9, 21, 19, 71, 175, 309, 9, 807, 961, 6741, 5075, 0 }; - static ulong[] dim1446JoeKuoD5Init = { 1, 3, 1, 9, 15, 27, 83, 207, 67, 71, 289, 2901, 7637, 9525, 0 }; - static ulong[] dim1447JoeKuoD5Init = { 1, 1, 7, 15, 21, 9, 19, 67, 401, 165, 1297, 3159, 2881, 15979, 0 }; - static ulong[] dim1448JoeKuoD5Init = { 1, 1, 5, 1, 11, 21, 27, 33, 95, 853, 1699, 875, 6519, 9109, 0 }; - static ulong[] dim1449JoeKuoD5Init = { 1, 3, 7, 3, 31, 5, 123, 215, 165, 405, 623, 845, 4149, 5015, 0 }; - static ulong[] dim1450JoeKuoD5Init = { 1, 3, 7, 7, 31, 13, 23, 55, 129, 789, 803, 2077, 1885, 1669, 0 }; - static ulong[] dim1451JoeKuoD5Init = { 1, 1, 5, 11, 31, 39, 93, 7, 485, 571, 417, 3839, 1289, 4127, 0 }; - static ulong[] dim1452JoeKuoD5Init = { 1, 1, 7, 11, 23, 63, 123, 249, 75, 515, 2009, 949, 3291, 727, 0 }; - static ulong[] dim1453JoeKuoD5Init = { 1, 1, 3, 13, 21, 15, 57, 235, 25, 507, 1055, 3161, 4351, 8855, 0 }; - static ulong[] dim1454JoeKuoD5Init = { 1, 3, 5, 7, 23, 39, 71, 151, 377, 469, 665, 1197, 3503, 655, 0 }; - static ulong[] dim1455JoeKuoD5Init = { 1, 3, 5, 3, 5, 35, 67, 203, 33, 319, 925, 1021, 6869, 5145, 0 }; - static ulong[] dim1456JoeKuoD5Init = { 1, 1, 3, 3, 21, 61, 119, 195, 383, 573, 135, 2371, 1665, 4957, 0 }; - static ulong[] dim1457JoeKuoD5Init = { 1, 3, 7, 1, 7, 47, 93, 201, 269, 329, 209, 1659, 1547, 4605, 0 }; - static ulong[] dim1458JoeKuoD5Init = { 1, 3, 1, 1, 9, 47, 71, 13, 451, 51, 1073, 3691, 6881, 14801, 0 }; - static ulong[] dim1459JoeKuoD5Init = { 1, 3, 5, 3, 13, 33, 75, 155, 283, 599, 517, 2251, 6217, 10487, 0 }; - static ulong[] dim1460JoeKuoD5Init = { 1, 1, 1, 3, 7, 49, 65, 235, 159, 733, 939, 283, 6935, 14367, 0 }; - static ulong[] dim1461JoeKuoD5Init = { 1, 1, 3, 13, 7, 19, 71, 227, 307, 515, 1701, 747, 3475, 8165, 0 }; - static ulong[] dim1462JoeKuoD5Init = { 1, 3, 1, 11, 13, 19, 1, 97, 425, 739, 451, 3789, 5337, 2023, 0 }; - static ulong[] dim1463JoeKuoD5Init = { 1, 1, 7, 9, 7, 27, 23, 169, 137, 537, 61, 2207, 917, 1209, 0 }; - static ulong[] dim1464JoeKuoD5Init = { 1, 1, 3, 3, 29, 5, 121, 197, 159, 467, 581, 1679, 6605, 1989, 0 }; - static ulong[] dim1465JoeKuoD5Init = { 1, 1, 1, 13, 5, 33, 61, 77, 383, 977, 781, 175, 8151, 7979, 0 }; - static ulong[] dim1466JoeKuoD5Init = { 1, 3, 1, 13, 1, 1, 3, 95, 193, 453, 649, 1137, 485, 14345, 0 }; - static ulong[] dim1467JoeKuoD5Init = { 1, 3, 7, 7, 1, 13, 41, 159, 327, 105, 1569, 475, 1295, 3767, 0 }; - static ulong[] dim1468JoeKuoD5Init = { 1, 3, 5, 3, 25, 7, 73, 235, 271, 491, 1385, 2567, 1463, 12731, 0 }; - static ulong[] dim1469JoeKuoD5Init = { 1, 3, 5, 1, 9, 9, 37, 199, 249, 9, 299, 3891, 2373, 11553, 0 }; - static ulong[] dim1470JoeKuoD5Init = { 1, 1, 7, 13, 19, 47, 81, 25, 125, 933, 1637, 469, 6351, 4219, 0 }; - static ulong[] dim1471JoeKuoD5Init = { 1, 1, 3, 7, 31, 5, 67, 13, 63, 615, 1089, 2291, 3105, 7009, 0 }; - static ulong[] dim1472JoeKuoD5Init = { 1, 1, 5, 1, 1, 43, 49, 141, 189, 1015, 1527, 1511, 3093, 5497, 0 }; - static ulong[] dim1473JoeKuoD5Init = { 1, 3, 5, 1, 3, 51, 121, 89, 161, 517, 467, 2837, 2275, 4987, 0 }; - static ulong[] dim1474JoeKuoD5Init = { 1, 3, 7, 13, 9, 63, 31, 109, 331, 607, 1271, 3639, 617, 13177, 0 }; - static ulong[] dim1475JoeKuoD5Init = { 1, 1, 1, 15, 9, 25, 73, 237, 145, 885, 1945, 1871, 5401, 15403, 0 }; - static ulong[] dim1476JoeKuoD5Init = { 1, 1, 3, 5, 1, 63, 29, 145, 377, 429, 1663, 1643, 2713, 6621, 0 }; - static ulong[] dim1477JoeKuoD5Init = { 1, 1, 1, 5, 29, 7, 87, 53, 129, 503, 961, 3535, 3255, 7621, 0 }; - static ulong[] dim1478JoeKuoD5Init = { 1, 3, 3, 1, 5, 47, 13, 243, 155, 863, 103, 1699, 5063, 8221, 0 }; - static ulong[] dim1479JoeKuoD5Init = { 1, 1, 1, 9, 31, 61, 1, 253, 67, 369, 521, 3429, 6935, 3383, 0 }; - static ulong[] dim1480JoeKuoD5Init = { 1, 1, 1, 3, 11, 61, 11, 187, 145, 7, 535, 831, 933, 7779, 0 }; - static ulong[] dim1481JoeKuoD5Init = { 1, 3, 7, 1, 25, 33, 117, 161, 169, 33, 1415, 1493, 1599, 1109, 0 }; - static ulong[] dim1482JoeKuoD5Init = { 1, 3, 1, 3, 29, 19, 75, 143, 467, 785, 455, 2593, 7539, 6283, 0 }; - static ulong[] dim1483JoeKuoD5Init = { 1, 3, 3, 15, 11, 5, 19, 187, 357, 955, 631, 3697, 4641, 14353, 0 }; - static ulong[] dim1484JoeKuoD5Init = { 1, 3, 7, 15, 3, 21, 25, 79, 375, 611, 915, 2491, 5691, 773, 0 }; - static ulong[] dim1485JoeKuoD5Init = { 1, 3, 3, 7, 29, 23, 7, 27, 207, 157, 1021, 2411, 5061, 7493, 0 }; - static ulong[] dim1486JoeKuoD5Init = { 1, 3, 7, 5, 13, 7, 7, 159, 393, 51, 1573, 1353, 2373, 12721, 0 }; - static ulong[] dim1487JoeKuoD5Init = { 1, 1, 7, 13, 5, 55, 43, 7, 411, 353, 379, 2213, 6257, 5825, 0 }; - static ulong[] dim1488JoeKuoD5Init = { 1, 1, 3, 1, 5, 37, 65, 69, 251, 893, 1747, 4065, 3937, 1855, 0 }; - static ulong[] dim1489JoeKuoD5Init = { 1, 3, 7, 1, 3, 11, 97, 111, 509, 569, 839, 2431, 3475, 12283, 0 }; - static ulong[] dim1490JoeKuoD5Init = { 1, 1, 3, 11, 13, 63, 85, 193, 351, 491, 205, 1051, 403, 1749, 0 }; - static ulong[] dim1491JoeKuoD5Init = { 1, 3, 3, 1, 27, 61, 61, 169, 189, 549, 1589, 3567, 7301, 12723, 0 }; - static ulong[] dim1492JoeKuoD5Init = { 1, 3, 1, 7, 13, 39, 121, 75, 261, 919, 1557, 635, 2123, 3771, 0 }; - static ulong[] dim1493JoeKuoD5Init = { 1, 1, 3, 13, 7, 39, 107, 109, 165, 91, 1049, 3897, 1395, 9573, 0 }; - static ulong[] dim1494JoeKuoD5Init = { 1, 1, 3, 5, 19, 9, 61, 209, 205, 363, 823, 2445, 7301, 7141, 0 }; - static ulong[] dim1495JoeKuoD5Init = { 1, 1, 1, 15, 5, 31, 13, 61, 153, 847, 67, 2227, 4119, 9231, 0 }; - static ulong[] dim1496JoeKuoD5Init = { 1, 3, 5, 9, 13, 63, 93, 199, 437, 319, 735, 2015, 1719, 3253, 0 }; - static ulong[] dim1497JoeKuoD5Init = { 1, 1, 3, 5, 31, 19, 27, 141, 357, 647, 895, 345, 5937, 15711, 0 }; - static ulong[] dim1498JoeKuoD5Init = { 1, 3, 7, 1, 15, 35, 73, 69, 205, 545, 387, 3487, 7391, 3337, 0 }; - static ulong[] dim1499JoeKuoD5Init = { 1, 1, 7, 5, 27, 55, 51, 179, 125, 1013, 35, 2741, 7793, 4347, 0 }; - static ulong[] dim1500JoeKuoD5Init = { 1, 1, 3, 9, 31, 57, 55, 3, 385, 421, 1543, 2809, 1887, 13709, 0 }; - static ulong[] dim1501JoeKuoD5Init = { 1, 1, 3, 7, 29, 23, 115, 25, 295, 267, 101, 3005, 2601, 4959, 0 }; - static ulong[] dim1502JoeKuoD5Init = { 1, 3, 7, 13, 27, 11, 11, 35, 257, 23, 2013, 1369, 6503, 2589, 0 }; - static ulong[] dim1503JoeKuoD5Init = { 1, 3, 7, 15, 5, 43, 101, 87, 231, 761, 1991, 3167, 5689, 9565, 0 }; - static ulong[] dim1504JoeKuoD5Init = { 1, 3, 1, 11, 17, 37, 65, 249, 119, 727, 793, 929, 6275, 12173, 0 }; - static ulong[] dim1505JoeKuoD5Init = { 1, 1, 7, 9, 1, 11, 93, 27, 291, 411, 1069, 1283, 7593, 4335, 0 }; - static ulong[] dim1506JoeKuoD5Init = { 1, 1, 5, 1, 23, 45, 51, 93, 401, 515, 749, 1293, 8155, 15123, 0 }; - static ulong[] dim1507JoeKuoD5Init = { 1, 1, 1, 3, 21, 17, 67, 69, 371, 507, 143, 2393, 6267, 7143, 0 }; - static ulong[] dim1508JoeKuoD5Init = { 1, 3, 5, 11, 1, 5, 79, 75, 361, 689, 339, 1855, 6863, 15841, 0 }; - static ulong[] dim1509JoeKuoD5Init = { 1, 3, 1, 13, 23, 3, 43, 57, 233, 927, 1095, 1827, 401, 825, 0 }; - static ulong[] dim1510JoeKuoD5Init = { 1, 3, 3, 9, 31, 7, 67, 201, 27, 699, 535, 3073, 6895, 3021, 0 }; - static ulong[] dim1511JoeKuoD5Init = { 1, 3, 1, 13, 1, 19, 13, 83, 221, 727, 745, 2131, 3757, 1493, 0 }; - static ulong[] dim1512JoeKuoD5Init = { 1, 3, 7, 9, 13, 29, 101, 255, 243, 763, 535, 169, 1987, 4071, 0 }; - static ulong[] dim1513JoeKuoD5Init = { 1, 3, 7, 3, 21, 33, 117, 213, 143, 351, 1735, 1651, 5781, 8803, 0 }; - static ulong[] dim1514JoeKuoD5Init = { 1, 1, 3, 7, 17, 39, 57, 209, 141, 865, 1731, 3349, 7107, 15983, 0 }; - static ulong[] dim1515JoeKuoD5Init = { 1, 3, 5, 3, 21, 33, 117, 201, 481, 711, 1207, 1971, 3353, 5827, 0 }; - static ulong[] dim1516JoeKuoD5Init = { 1, 1, 7, 13, 13, 1, 121, 115, 449, 801, 1507, 2323, 6709, 5533, 0 }; - static ulong[] dim1517JoeKuoD5Init = { 1, 3, 3, 7, 5, 5, 35, 81, 469, 691, 443, 501, 6745, 421, 0 }; - static ulong[] dim1518JoeKuoD5Init = { 1, 1, 5, 13, 27, 41, 83, 39, 349, 585, 551, 643, 6659, 61, 0 }; - static ulong[] dim1519JoeKuoD5Init = { 1, 1, 1, 3, 25, 41, 45, 203, 89, 305, 1433, 1879, 6703, 14323, 0 }; - static ulong[] dim1520JoeKuoD5Init = { 1, 1, 5, 15, 27, 37, 97, 117, 431, 197, 807, 1841, 8075, 4613, 0 }; - static ulong[] dim1521JoeKuoD5Init = { 1, 1, 5, 3, 23, 47, 69, 129, 451, 113, 1397, 3005, 7599, 101, 0 }; - static ulong[] dim1522JoeKuoD5Init = { 1, 1, 3, 1, 11, 47, 117, 181, 85, 545, 571, 3227, 4097, 7937, 0 }; - static ulong[] dim1523JoeKuoD5Init = { 1, 1, 3, 9, 27, 53, 11, 181, 177, 121, 363, 2751, 4799, 14215, 0 }; - static ulong[] dim1524JoeKuoD5Init = { 1, 3, 5, 15, 27, 15, 101, 229, 411, 947, 189, 119, 6707, 5177, 0 }; - static ulong[] dim1525JoeKuoD5Init = { 1, 1, 5, 7, 29, 39, 65, 149, 185, 915, 889, 1651, 5977, 273, 0 }; - static ulong[] dim1526JoeKuoD5Init = { 1, 1, 1, 7, 7, 45, 113, 203, 459, 747, 1577, 2247, 5005, 2375, 0 }; - static ulong[] dim1527JoeKuoD5Init = { 1, 1, 7, 9, 9, 5, 63, 83, 193, 363, 257, 4075, 7497, 4579, 0 }; - static ulong[] dim1528JoeKuoD5Init = { 1, 1, 7, 15, 1, 55, 107, 161, 471, 245, 1303, 1821, 3395, 8957, 0 }; - static ulong[] dim1529JoeKuoD5Init = { 1, 3, 3, 15, 5, 17, 83, 215, 467, 489, 827, 1951, 3753, 13333, 0 }; - static ulong[] dim1530JoeKuoD5Init = { 1, 1, 5, 11, 27, 31, 89, 55, 445, 489, 1171, 107, 1479, 1389, 0 }; - static ulong[] dim1531JoeKuoD5Init = { 1, 1, 5, 15, 21, 23, 51, 21, 129, 349, 195, 2177, 529, 5479, 0 }; - static ulong[] dim1532JoeKuoD5Init = { 1, 1, 3, 5, 15, 31, 99, 169, 299, 21, 1379, 3845, 4991, 8755, 0 }; - static ulong[] dim1533JoeKuoD5Init = { 1, 1, 3, 3, 23, 29, 47, 219, 289, 559, 393, 793, 3217, 12103, 0 }; - static ulong[] dim1534JoeKuoD5Init = { 1, 1, 7, 15, 5, 13, 107, 119, 159, 421, 243, 3231, 5331, 14511, 0 }; - static ulong[] dim1535JoeKuoD5Init = { 1, 1, 3, 13, 13, 9, 1, 99, 7, 743, 1125, 2969, 1205, 2963, 0 }; - static ulong[] dim1536JoeKuoD5Init = { 1, 3, 7, 15, 5, 1, 25, 101, 397, 75, 141, 3503, 3003, 11363, 0 }; - static ulong[] dim1537JoeKuoD5Init = { 1, 1, 7, 1, 21, 25, 55, 7, 189, 599, 1071, 343, 2877, 5131, 0 }; - static ulong[] dim1538JoeKuoD5Init = { 1, 1, 5, 7, 13, 25, 113, 175, 31, 265, 1901, 1779, 1787, 14551, 0 }; - static ulong[] dim1539JoeKuoD5Init = { 1, 1, 5, 13, 31, 53, 69, 49, 281, 57, 1865, 3211, 5545, 12597, 0 }; - static ulong[] dim1540JoeKuoD5Init = { 1, 3, 3, 11, 3, 51, 99, 23, 303, 455, 2021, 2903, 2521, 10211, 0 }; - static ulong[] dim1541JoeKuoD5Init = { 1, 3, 1, 3, 17, 49, 55, 147, 177, 515, 1333, 3357, 6483, 4599, 0 }; - static ulong[] dim1542JoeKuoD5Init = { 1, 3, 7, 1, 31, 3, 1, 15, 263, 1007, 1377, 1245, 313, 10227, 0 }; - static ulong[] dim1543JoeKuoD5Init = { 1, 3, 1, 3, 21, 7, 61, 201, 95, 407, 661, 2159, 3255, 5749, 0 }; - static ulong[] dim1544JoeKuoD5Init = { 1, 3, 5, 9, 13, 31, 65, 135, 117, 737, 1165, 2305, 5347, 2739, 0 }; - static ulong[] dim1545JoeKuoD5Init = { 1, 1, 7, 3, 25, 49, 63, 115, 65, 693, 1211, 763, 6949, 11655, 0 }; - static ulong[] dim1546JoeKuoD5Init = { 1, 3, 1, 5, 13, 37, 15, 61, 175, 377, 765, 269, 1363, 8199, 0 }; - static ulong[] dim1547JoeKuoD5Init = { 1, 1, 7, 7, 27, 27, 113, 131, 207, 921, 1051, 2205, 1197, 16233, 0 }; - static ulong[] dim1548JoeKuoD5Init = { 1, 3, 5, 7, 5, 19, 115, 95, 93, 87, 1379, 3295, 5211, 9113, 0 }; - static ulong[] dim1549JoeKuoD5Init = { 1, 1, 3, 11, 21, 19, 9, 39, 101, 5, 1903, 1067, 2845, 2025, 0 }; - static ulong[] dim1550JoeKuoD5Init = { 1, 3, 5, 9, 31, 5, 39, 23, 505, 563, 1445, 1177, 1485, 13551, 0 }; - static ulong[] dim1551JoeKuoD5Init = { 1, 1, 7, 3, 31, 57, 107, 241, 361, 353, 699, 171, 5211, 2235, 0 }; - static ulong[] dim1552JoeKuoD5Init = { 1, 1, 5, 5, 15, 7, 115, 119, 157, 293, 827, 3249, 3463, 11873, 0 }; - static ulong[] dim1553JoeKuoD5Init = { 1, 1, 7, 3, 11, 15, 17, 195, 257, 31, 1207, 549, 7807, 14135, 0 }; - static ulong[] dim1554JoeKuoD5Init = { 1, 3, 7, 7, 25, 59, 37, 205, 507, 855, 303, 683, 4277, 9387, 0 }; - static ulong[] dim1555JoeKuoD5Init = { 1, 3, 5, 1, 25, 1, 121, 29, 485, 707, 319, 3717, 2741, 5241, 0 }; - static ulong[] dim1556JoeKuoD5Init = { 1, 3, 3, 3, 15, 55, 107, 227, 129, 1011, 319, 713, 5263, 7865, 0 }; - static ulong[] dim1557JoeKuoD5Init = { 1, 1, 3, 5, 17, 11, 7, 107, 21, 349, 1101, 3279, 5541, 12485, 0 }; - static ulong[] dim1558JoeKuoD5Init = { 1, 3, 3, 13, 25, 9, 45, 149, 187, 229, 671, 1219, 5171, 2073, 0 }; - static ulong[] dim1559JoeKuoD5Init = { 1, 3, 7, 11, 17, 49, 23, 7, 219, 639, 1497, 3103, 3047, 7723, 0 }; - static ulong[] dim1560JoeKuoD5Init = { 1, 1, 1, 5, 13, 5, 3, 249, 429, 289, 625, 325, 1257, 16251, 0 }; - static ulong[] dim1561JoeKuoD5Init = { 1, 3, 5, 1, 17, 21, 31, 11, 189, 73, 583, 2843, 1873, 1215, 0 }; - static ulong[] dim1562JoeKuoD5Init = { 1, 3, 1, 9, 25, 61, 123, 251, 485, 543, 1851, 2827, 397, 7313, 0 }; - static ulong[] dim1563JoeKuoD5Init = { 1, 1, 1, 9, 29, 59, 103, 159, 295, 227, 1127, 1905, 4121, 3233, 0 }; - static ulong[] dim1564JoeKuoD5Init = { 1, 1, 5, 15, 17, 55, 7, 1, 381, 33, 39, 485, 3967, 4401, 0 }; - static ulong[] dim1565JoeKuoD5Init = { 1, 1, 1, 3, 5, 29, 7, 95, 191, 23, 1205, 2427, 5439, 12585, 0 }; - static ulong[] dim1566JoeKuoD5Init = { 1, 3, 3, 9, 27, 9, 73, 195, 225, 597, 683, 3335, 6341, 10527, 0 }; - static ulong[] dim1567JoeKuoD5Init = { 1, 1, 3, 5, 13, 15, 83, 41, 241, 833, 1253, 3389, 2927, 2629, 0 }; - static ulong[] dim1568JoeKuoD5Init = { 1, 1, 3, 11, 25, 55, 23, 249, 151, 123, 667, 3835, 2215, 6189, 0 }; - static ulong[] dim1569JoeKuoD5Init = { 1, 1, 3, 13, 31, 43, 91, 181, 509, 453, 171, 2883, 1247, 5105, 0 }; - static ulong[] dim1570JoeKuoD5Init = { 1, 1, 7, 15, 3, 17, 59, 127, 173, 343, 901, 3419, 4755, 12367, 0 }; - static ulong[] dim1571JoeKuoD5Init = { 1, 3, 3, 9, 15, 49, 119, 1, 183, 1021, 561, 2405, 4093, 963, 0 }; - static ulong[] dim1572JoeKuoD5Init = { 1, 3, 5, 15, 21, 61, 63, 119, 11, 695, 1591, 2175, 5143, 10491, 0 }; - static ulong[] dim1573JoeKuoD5Init = { 1, 1, 7, 15, 27, 23, 91, 131, 23, 891, 1033, 1341, 1747, 12085, 0 }; - static ulong[] dim1574JoeKuoD5Init = { 1, 3, 1, 9, 11, 1, 35, 189, 131, 617, 417, 3347, 3995, 11723, 0 }; - static ulong[] dim1575JoeKuoD5Init = { 1, 3, 5, 3, 31, 35, 113, 83, 27, 399, 1615, 47, 1455, 4163, 0 }; - static ulong[] dim1576JoeKuoD5Init = { 1, 3, 3, 5, 29, 61, 103, 105, 495, 495, 1751, 2035, 7827, 11193, 0 }; - static ulong[] dim1577JoeKuoD5Init = { 1, 1, 1, 11, 29, 35, 125, 193, 59, 15, 1319, 1169, 3789, 2003, 0 }; - static ulong[] dim1578JoeKuoD5Init = { 1, 3, 3, 9, 27, 9, 33, 197, 65, 191, 783, 3685, 7505, 13407, 0 }; - static ulong[] dim1579JoeKuoD5Init = { 1, 1, 1, 1, 1, 35, 97, 55, 259, 477, 1835, 3083, 7879, 4701, 0 }; - static ulong[] dim1580JoeKuoD5Init = { 1, 1, 5, 11, 5, 31, 5, 125, 393, 317, 1577, 3741, 3823, 12447, 0 }; - static ulong[] dim1581JoeKuoD5Init = { 1, 3, 1, 13, 9, 59, 81, 85, 233, 465, 239, 1525, 3095, 5793, 0 }; - static ulong[] dim1582JoeKuoD5Init = { 1, 1, 1, 1, 9, 49, 49, 239, 81, 475, 799, 2999, 2985, 11587, 0 }; - static ulong[] dim1583JoeKuoD5Init = { 1, 1, 7, 5, 27, 55, 43, 149, 191, 325, 2035, 1645, 2153, 13237, 0 }; - static ulong[] dim1584JoeKuoD5Init = { 1, 1, 1, 15, 27, 59, 5, 49, 277, 75, 1759, 2753, 95, 2959, 0 }; - static ulong[] dim1585JoeKuoD5Init = { 1, 1, 7, 1, 21, 57, 119, 35, 457, 137, 1877, 2613, 4209, 9669, 0 }; - static ulong[] dim1586JoeKuoD5Init = { 1, 3, 3, 1, 25, 21, 51, 65, 155, 37, 783, 3427, 2763, 14361, 0 }; - static ulong[] dim1587JoeKuoD5Init = { 1, 1, 5, 7, 23, 11, 53, 181, 267, 285, 1927, 3591, 3735, 11471, 0 }; - static ulong[] dim1588JoeKuoD5Init = { 1, 3, 7, 1, 5, 25, 51, 31, 201, 851, 871, 3665, 193, 10929, 0 }; - static ulong[] dim1589JoeKuoD5Init = { 1, 3, 1, 5, 1, 25, 35, 133, 459, 45, 525, 3171, 1123, 5679, 0 }; - static ulong[] dim1590JoeKuoD5Init = { 1, 3, 1, 5, 29, 47, 123, 75, 101, 89, 1949, 1801, 3859, 6557, 0 }; - static ulong[] dim1591JoeKuoD5Init = { 1, 3, 3, 3, 25, 1, 93, 205, 447, 865, 1309, 3009, 945, 6961, 0 }; - static ulong[] dim1592JoeKuoD5Init = { 1, 3, 3, 11, 21, 47, 91, 9, 23, 607, 1905, 2291, 5315, 6673, 0 }; - static ulong[] dim1593JoeKuoD5Init = { 1, 3, 1, 13, 3, 33, 83, 27, 491, 467, 1819, 3295, 1589, 4771, 0 }; - static ulong[] dim1594JoeKuoD5Init = { 1, 1, 7, 15, 17, 57, 73, 49, 69, 821, 1773, 459, 7945, 14471, 0 }; - static ulong[] dim1595JoeKuoD5Init = { 1, 3, 1, 1, 19, 29, 9, 181, 311, 353, 2045, 2873, 7417, 15243, 0 }; - static ulong[] dim1596JoeKuoD5Init = { 1, 1, 1, 7, 29, 45, 43, 17, 237, 915, 1069, 1429, 5629, 4501, 0 }; - static ulong[] dim1597JoeKuoD5Init = { 1, 3, 5, 9, 9, 53, 57, 55, 275, 233, 1697, 2857, 919, 4507, 0 }; - static ulong[] dim1598JoeKuoD5Init = { 1, 1, 3, 13, 17, 45, 81, 101, 209, 769, 783, 1949, 5933, 137, 0 }; - static ulong[] dim1599JoeKuoD5Init = { 1, 1, 7, 7, 1, 33, 17, 87, 35, 927, 1595, 2443, 285, 12821, 0 }; - static ulong[] dim1600JoeKuoD5Init = { 1, 3, 1, 9, 3, 33, 113, 243, 51, 203, 1683, 389, 2789, 9255, 0 }; - static ulong[] dim1601JoeKuoD5Init = { 1, 3, 1, 3, 9, 1, 7, 227, 27, 773, 621, 3743, 6591, 407, 0 }; - static ulong[] dim1602JoeKuoD5Init = { 1, 3, 5, 5, 29, 51, 113, 99, 305, 267, 907, 3861, 5335, 10851, 0 }; - static ulong[] dim1603JoeKuoD5Init = { 1, 3, 1, 9, 27, 63, 65, 249, 87, 105, 2023, 1383, 4267, 8995, 0 }; - static ulong[] dim1604JoeKuoD5Init = { 1, 1, 1, 13, 15, 11, 77, 9, 365, 711, 1367, 2101, 5833, 9799, 0 }; - static ulong[] dim1605JoeKuoD5Init = { 1, 3, 7, 3, 7, 29, 13, 157, 259, 455, 389, 3177, 4243, 7615, 0 }; - static ulong[] dim1606JoeKuoD5Init = { 1, 1, 5, 3, 25, 27, 31, 91, 195, 109, 1767, 987, 2715, 7613, 0 }; - static ulong[] dim1607JoeKuoD5Init = { 1, 3, 5, 7, 23, 51, 89, 127, 485, 361, 1555, 441, 4963, 3371, 0 }; - static ulong[] dim1608JoeKuoD5Init = { 1, 3, 5, 7, 27, 31, 25, 249, 35, 115, 1021, 1051, 3449, 3395, 0 }; - static ulong[] dim1609JoeKuoD5Init = { 1, 1, 7, 3, 17, 41, 117, 173, 491, 281, 885, 471, 6665, 10041, 0 }; - static ulong[] dim1610JoeKuoD5Init = { 1, 1, 5, 3, 7, 53, 117, 117, 479, 449, 569, 4049, 2747, 12963, 0 }; - static ulong[] dim1611JoeKuoD5Init = { 1, 1, 3, 7, 11, 13, 107, 171, 7, 547, 1635, 1697, 1005, 11137, 0 }; - static ulong[] dim1612JoeKuoD5Init = { 1, 1, 1, 13, 17, 51, 109, 81, 111, 395, 349, 1467, 1399, 15545, 0 }; - static ulong[] dim1613JoeKuoD5Init = { 1, 3, 1, 9, 13, 47, 79, 119, 31, 239, 41, 2043, 2849, 16079, 0 }; - static ulong[] dim1614JoeKuoD5Init = { 1, 1, 7, 1, 17, 41, 95, 193, 511, 879, 1223, 3133, 1675, 3929, 0 }; - static ulong[] dim1615JoeKuoD5Init = { 1, 1, 7, 3, 15, 55, 21, 143, 279, 11, 717, 3021, 6207, 4499, 0 }; - static ulong[] dim1616JoeKuoD5Init = { 1, 1, 7, 3, 3, 25, 37, 91, 227, 619, 1873, 1991, 793, 10021, 0 }; - static ulong[] dim1617JoeKuoD5Init = { 1, 3, 3, 11, 17, 39, 75, 191, 117, 997, 735, 3771, 4243, 2491, 0 }; - static ulong[] dim1618JoeKuoD5Init = { 1, 1, 1, 7, 19, 9, 71, 89, 427, 791, 623, 903, 6685, 9029, 0 }; - static ulong[] dim1619JoeKuoD5Init = { 1, 1, 3, 3, 13, 49, 13, 151, 389, 677, 727, 3135, 1029, 12669, 0 }; - static ulong[] dim1620JoeKuoD5Init = { 1, 3, 5, 11, 27, 31, 119, 219, 491, 819, 755, 3529, 3071, 16095, 0 }; - static ulong[] dim1621JoeKuoD5Init = { 1, 1, 7, 9, 1, 57, 127, 171, 481, 467, 1131, 1481, 2491, 2717, 0 }; - static ulong[] dim1622JoeKuoD5Init = { 1, 1, 1, 15, 7, 25, 55, 87, 225, 363, 843, 3581, 2511, 6685, 0 }; - static ulong[] dim1623JoeKuoD5Init = { 1, 3, 3, 3, 29, 21, 91, 251, 403, 1007, 307, 2869, 6033, 14169, 0 }; - static ulong[] dim1624JoeKuoD5Init = { 1, 3, 5, 13, 31, 43, 77, 71, 101, 995, 625, 2763, 7537, 1213, 0 }; - static ulong[] dim1625JoeKuoD5Init = { 1, 3, 3, 5, 9, 45, 11, 235, 59, 561, 547, 815, 6123, 8173, 0 }; - static ulong[] dim1626JoeKuoD5Init = { 1, 3, 1, 3, 25, 19, 107, 47, 103, 467, 1889, 2021, 2861, 7617, 0 }; - static ulong[] dim1627JoeKuoD5Init = { 1, 3, 1, 9, 9, 3, 11, 231, 217, 213, 1497, 3125, 7421, 6221, 0 }; - static ulong[] dim1628JoeKuoD5Init = { 1, 1, 5, 7, 27, 57, 27, 9, 507, 191, 1297, 3307, 4687, 13299, 0 }; - static ulong[] dim1629JoeKuoD5Init = { 1, 3, 3, 1, 25, 17, 109, 57, 231, 123, 1297, 77, 785, 13731, 0 }; - static ulong[] dim1630JoeKuoD5Init = { 1, 1, 7, 3, 25, 5, 85, 177, 365, 301, 655, 1743, 2009, 7759, 0 }; - static ulong[] dim1631JoeKuoD5Init = { 1, 3, 7, 7, 19, 29, 105, 57, 469, 735, 875, 3749, 619, 15569, 0 }; - static ulong[] dim1632JoeKuoD5Init = { 1, 3, 7, 1, 19, 21, 105, 19, 83, 117, 1599, 655, 63, 12143, 0 }; - static ulong[] dim1633JoeKuoD5Init = { 1, 3, 3, 7, 9, 35, 123, 195, 109, 321, 1713, 793, 8067, 6903, 0 }; - static ulong[] dim1634JoeKuoD5Init = { 1, 1, 7, 9, 1, 41, 43, 41, 51, 711, 1713, 3063, 6427, 3577, 0 }; - static ulong[] dim1635JoeKuoD5Init = { 1, 1, 5, 11, 17, 3, 95, 159, 23, 605, 1431, 1289, 2225, 1689, 0 }; - static ulong[] dim1636JoeKuoD5Init = { 1, 1, 7, 15, 19, 3, 83, 61, 133, 707, 453, 2487, 551, 13605, 0 }; - static ulong[] dim1637JoeKuoD5Init = { 1, 1, 7, 5, 31, 37, 51, 157, 51, 423, 2021, 1837, 1873, 2919, 0 }; - static ulong[] dim1638JoeKuoD5Init = { 1, 3, 1, 13, 3, 17, 19, 19, 181, 961, 669, 47, 7513, 7551, 0 }; - static ulong[] dim1639JoeKuoD5Init = { 1, 3, 1, 1, 9, 7, 61, 219, 347, 21, 467, 955, 3255, 275, 0 }; - static ulong[] dim1640JoeKuoD5Init = { 1, 1, 3, 1, 31, 57, 51, 9, 49, 491, 119, 1155, 3641, 16095, 0 }; - static ulong[] dim1641JoeKuoD5Init = { 1, 3, 1, 1, 15, 37, 93, 27, 205, 889, 1463, 1567, 453, 13757, 0 }; - static ulong[] dim1642JoeKuoD5Init = { 1, 3, 3, 15, 27, 51, 43, 189, 357, 591, 1783, 549, 761, 8683, 0 }; - static ulong[] dim1643JoeKuoD5Init = { 1, 3, 1, 15, 13, 27, 25, 67, 145, 471, 1589, 2395, 6625, 3837, 0 }; - static ulong[] dim1644JoeKuoD5Init = { 1, 3, 3, 15, 25, 61, 111, 125, 475, 489, 15, 3835, 5077, 14487, 0 }; - static ulong[] dim1645JoeKuoD5Init = { 1, 1, 1, 9, 15, 55, 35, 169, 267, 135, 383, 733, 6913, 14153, 0 }; - static ulong[] dim1646JoeKuoD5Init = { 1, 3, 3, 1, 19, 55, 89, 61, 175, 467, 1243, 1431, 1743, 8641, 0 }; - static ulong[] dim1647JoeKuoD5Init = { 1, 1, 3, 7, 19, 41, 13, 45, 503, 285, 1727, 587, 5073, 13053, 0 }; - static ulong[] dim1648JoeKuoD5Init = { 1, 3, 7, 3, 11, 39, 93, 167, 385, 165, 881, 1037, 1471, 14527, 0 }; - static ulong[] dim1649JoeKuoD5Init = { 1, 3, 7, 15, 9, 7, 49, 163, 219, 955, 1083, 2723, 3749, 15415, 0 }; - static ulong[] dim1650JoeKuoD5Init = { 1, 3, 1, 3, 7, 43, 67, 87, 375, 405, 1663, 1263, 1895, 2229, 0 }; - static ulong[] dim1651JoeKuoD5Init = { 1, 3, 5, 1, 27, 47, 77, 147, 417, 843, 1829, 3451, 2973, 7313, 0 }; - static ulong[] dim1652JoeKuoD5Init = { 1, 1, 3, 1, 3, 25, 69, 255, 413, 43, 837, 957, 261, 8663, 0 }; - static ulong[] dim1653JoeKuoD5Init = { 1, 3, 3, 7, 29, 35, 9, 57, 421, 751, 593, 3745, 3203, 14179, 0 }; - static ulong[] dim1654JoeKuoD5Init = { 1, 3, 5, 3, 13, 25, 109, 169, 331, 537, 69, 2089, 7263, 15133, 0 }; - static ulong[] dim1655JoeKuoD5Init = { 1, 3, 5, 5, 21, 21, 21, 145, 223, 167, 1297, 3257, 7465, 1557, 0 }; - static ulong[] dim1656JoeKuoD5Init = { 1, 1, 5, 3, 11, 7, 31, 205, 97, 737, 79, 4083, 5601, 8411, 0 }; - static ulong[] dim1657JoeKuoD5Init = { 1, 1, 3, 3, 7, 39, 117, 203, 225, 801, 741, 1861, 8091, 3169, 0 }; - static ulong[] dim1658JoeKuoD5Init = { 1, 3, 3, 3, 15, 49, 109, 171, 109, 845, 1757, 2687, 5643, 3967, 0 }; - static ulong[] dim1659JoeKuoD5Init = { 1, 3, 3, 13, 7, 41, 93, 165, 127, 629, 959, 1483, 3837, 2093, 0 }; - static ulong[] dim1660JoeKuoD5Init = { 1, 1, 1, 5, 9, 39, 115, 153, 395, 777, 1601, 3443, 3581, 1419, 0 }; - static ulong[] dim1661JoeKuoD5Init = { 1, 3, 3, 3, 23, 61, 87, 179, 463, 55, 1727, 99, 7527, 15281, 0 }; - static ulong[] dim1662JoeKuoD5Init = { 1, 3, 5, 9, 9, 49, 27, 103, 221, 277, 1093, 3547, 8009, 8711, 0 }; - static ulong[] dim1663JoeKuoD5Init = { 1, 3, 1, 7, 15, 59, 79, 59, 451, 763, 1687, 389, 1665, 12149, 0 }; - static ulong[] dim1664JoeKuoD5Init = { 1, 3, 7, 9, 25, 25, 37, 53, 173, 1003, 1175, 3881, 4355, 6247, 0 }; - static ulong[] dim1665JoeKuoD5Init = { 1, 3, 5, 3, 15, 31, 123, 133, 79, 581, 405, 2869, 2759, 2295, 0 }; - static ulong[] dim1666JoeKuoD5Init = { 1, 3, 7, 13, 19, 3, 35, 135, 287, 433, 205, 2119, 6293, 2931, 0 }; - static ulong[] dim1667JoeKuoD5Init = { 1, 1, 5, 13, 21, 29, 69, 109, 401, 753, 1371, 3777, 5473, 8357, 0 }; - static ulong[] dim1668JoeKuoD5Init = { 1, 1, 3, 7, 11, 27, 101, 153, 483, 639, 687, 2325, 329, 12427, 0 }; - static ulong[] dim1669JoeKuoD5Init = { 1, 1, 3, 13, 31, 41, 93, 83, 121, 645, 479, 1417, 1967, 2807, 0 }; - static ulong[] dim1670JoeKuoD5Init = { 1, 1, 7, 5, 3, 29, 41, 115, 41, 81, 5, 1063, 943, 10151, 0 }; - static ulong[] dim1671JoeKuoD5Init = { 1, 1, 1, 13, 5, 33, 79, 245, 271, 373, 1339, 1471, 4695, 12791, 0 }; - static ulong[] dim1672JoeKuoD5Init = { 1, 1, 3, 3, 5, 5, 19, 101, 109, 429, 1587, 3453, 4549, 8173, 0 }; - static ulong[] dim1673JoeKuoD5Init = { 1, 1, 7, 7, 5, 33, 5, 15, 183, 241, 871, 1263, 85, 13525, 0 }; - static ulong[] dim1674JoeKuoD5Init = { 1, 3, 5, 1, 15, 5, 115, 165, 451, 789, 515, 3359, 1231, 3129, 0 }; - static ulong[] dim1675JoeKuoD5Init = { 1, 3, 7, 3, 5, 45, 109, 233, 369, 819, 987, 3157, 5961, 5705, 0 }; - static ulong[] dim1676JoeKuoD5Init = { 1, 3, 3, 11, 7, 63, 43, 249, 95, 853, 917, 1749, 4275, 10109, 0 }; - static ulong[] dim1677JoeKuoD5Init = { 1, 1, 1, 9, 21, 5, 53, 249, 3, 11, 1171, 3289, 6659, 6555, 0 }; - static ulong[] dim1678JoeKuoD5Init = { 1, 3, 5, 11, 9, 19, 35, 253, 13, 229, 149, 3153, 3833, 11635, 0 }; - static ulong[] dim1679JoeKuoD5Init = { 1, 1, 1, 11, 1, 19, 127, 119, 405, 19, 589, 2613, 399, 3869, 0 }; - static ulong[] dim1680JoeKuoD5Init = { 1, 1, 5, 1, 3, 11, 35, 147, 11, 765, 237, 2451, 5041, 4919, 0 }; - static ulong[] dim1681JoeKuoD5Init = { 1, 1, 1, 11, 15, 7, 91, 7, 5, 223, 1505, 3513, 185, 2767, 0 }; - static ulong[] dim1682JoeKuoD5Init = { 1, 1, 7, 7, 27, 17, 81, 181, 11, 803, 319, 3891, 4505, 6035, 0 }; - static ulong[] dim1683JoeKuoD5Init = { 1, 3, 5, 15, 29, 13, 47, 137, 301, 975, 77, 3351, 6307, 2613, 0 }; - static ulong[] dim1684JoeKuoD5Init = { 1, 3, 7, 5, 15, 41, 99, 171, 465, 145, 1859, 2949, 7915, 7755, 0 }; - static ulong[] dim1685JoeKuoD5Init = { 1, 1, 5, 5, 3, 25, 123, 251, 423, 921, 987, 793, 2199, 1255, 0 }; - static ulong[] dim1686JoeKuoD5Init = { 1, 3, 7, 3, 1, 63, 75, 101, 219, 1013, 1761, 2171, 2763, 11185, 0 }; - static ulong[] dim1687JoeKuoD5Init = { 1, 3, 5, 13, 13, 15, 33, 147, 5, 915, 1903, 2607, 3847, 167, 0 }; - static ulong[] dim1688JoeKuoD5Init = { 1, 1, 3, 1, 23, 27, 71, 17, 381, 269, 603, 2303, 1399, 13795, 0 }; - static ulong[] dim1689JoeKuoD5Init = { 1, 3, 7, 5, 29, 5, 51, 151, 271, 369, 595, 531, 7155, 15871, 0 }; - static ulong[] dim1690JoeKuoD5Init = { 1, 1, 7, 13, 9, 49, 49, 119, 191, 105, 1203, 3431, 7063, 10831, 0 }; - static ulong[] dim1691JoeKuoD5Init = { 1, 1, 5, 15, 31, 49, 37, 147, 155, 865, 339, 257, 4065, 7249, 0 }; - static ulong[] dim1692JoeKuoD5Init = { 1, 1, 3, 11, 3, 23, 127, 19, 363, 733, 1059, 3693, 4623, 2853, 0 }; - static ulong[] dim1693JoeKuoD5Init = { 1, 1, 5, 3, 3, 55, 13, 177, 453, 447, 183, 3247, 5923, 15485, 0 }; - static ulong[] dim1694JoeKuoD5Init = { 1, 1, 1, 7, 3, 57, 93, 13, 347, 225, 535, 3187, 6047, 11315, 0 }; - static ulong[] dim1695JoeKuoD5Init = { 1, 3, 5, 9, 17, 5, 121, 35, 35, 393, 1941, 1901, 7099, 2639, 0 }; - static ulong[] dim1696JoeKuoD5Init = { 1, 1, 5, 13, 13, 43, 61, 143, 291, 667, 103, 3679, 7899, 3603, 0 }; - static ulong[] dim1697JoeKuoD5Init = { 1, 3, 1, 15, 31, 57, 41, 101, 455, 541, 1001, 1879, 1879, 7411, 0 }; - static ulong[] dim1698JoeKuoD5Init = { 1, 3, 3, 7, 13, 29, 113, 151, 305, 593, 147, 737, 6643, 14463, 0 }; - static ulong[] dim1699JoeKuoD5Init = { 1, 3, 7, 3, 17, 55, 3, 179, 277, 873, 1915, 2541, 4245, 4357, 0 }; - static ulong[] dim1700JoeKuoD5Init = { 1, 1, 5, 11, 21, 43, 97, 251, 15, 443, 957, 923, 7497, 9377, 0 }; - static ulong[] dim1701JoeKuoD5Init = { 1, 3, 7, 7, 23, 19, 27, 3, 35, 407, 451, 3653, 813, 8833, 0 }; - static ulong[] dim1702JoeKuoD5Init = { 1, 1, 1, 5, 15, 25, 5, 165, 231, 221, 1325, 641, 4545, 7667, 0 }; - static ulong[] dim1703JoeKuoD5Init = { 1, 3, 7, 1, 13, 17, 25, 225, 237, 289, 187, 2881, 4723, 15579, 0 }; - static ulong[] dim1704JoeKuoD5Init = { 1, 3, 1, 3, 15, 43, 53, 241, 163, 853, 491, 2497, 761, 1707, 0 }; - static ulong[] dim1705JoeKuoD5Init = { 1, 1, 1, 3, 13, 19, 83, 97, 7, 639, 1985, 3553, 3971, 10661, 0 }; - static ulong[] dim1706JoeKuoD5Init = { 1, 3, 1, 1, 15, 37, 21, 139, 33, 643, 63, 2213, 1807, 14483, 0 }; - static ulong[] dim1707JoeKuoD5Init = { 1, 1, 7, 11, 3, 55, 67, 45, 313, 539, 1057, 455, 6473, 1499, 0 }; - static ulong[] dim1708JoeKuoD5Init = { 1, 3, 1, 9, 1, 29, 91, 133, 461, 301, 539, 2001, 8189, 2009, 0 }; - static ulong[] dim1709JoeKuoD5Init = { 1, 1, 5, 9, 17, 5, 77, 221, 423, 505, 419, 1987, 8171, 12985, 0 }; - static ulong[] dim1710JoeKuoD5Init = { 1, 1, 5, 13, 21, 11, 69, 53, 43, 819, 1513, 1767, 2981, 4333, 0 }; - static ulong[] dim1711JoeKuoD5Init = { 1, 3, 3, 9, 9, 29, 83, 183, 9, 815, 1051, 819, 2089, 13917, 0 }; - static ulong[] dim1712JoeKuoD5Init = { 1, 3, 7, 1, 21, 41, 87, 133, 149, 847, 205, 1511, 2441, 13537, 0 }; - static ulong[] dim1713JoeKuoD5Init = { 1, 1, 5, 3, 23, 1, 121, 89, 349, 355, 1919, 2045, 1723, 11859, 0 }; - static ulong[] dim1714JoeKuoD5Init = { 1, 3, 5, 1, 21, 47, 111, 65, 367, 505, 805, 2823, 5807, 6221, 0 }; - static ulong[] dim1715JoeKuoD5Init = { 1, 3, 7, 7, 7, 39, 35, 35, 497, 411, 387, 203, 1513, 15385, 0 }; - static ulong[] dim1716JoeKuoD5Init = { 1, 3, 1, 7, 3, 7, 23, 195, 353, 241, 327, 1041, 4667, 4333, 0 }; - static ulong[] dim1717JoeKuoD5Init = { 1, 1, 1, 9, 31, 51, 45, 243, 485, 785, 419, 1107, 7691, 2303, 0 }; - static ulong[] dim1718JoeKuoD5Init = { 1, 1, 1, 7, 31, 1, 121, 79, 263, 153, 695, 3617, 7435, 11587, 0 }; - static ulong[] dim1719JoeKuoD5Init = { 1, 3, 7, 7, 27, 33, 43, 223, 153, 755, 1151, 3343, 2795, 7781, 0 }; - static ulong[] dim1720JoeKuoD5Init = { 1, 1, 1, 15, 5, 41, 39, 181, 485, 129, 529, 2335, 6843, 7733, 0 }; - static ulong[] dim1721JoeKuoD5Init = { 1, 1, 5, 11, 31, 55, 117, 157, 227, 125, 557, 315, 3031, 8671, 0 }; - static ulong[] dim1722JoeKuoD5Init = { 1, 1, 3, 7, 15, 5, 117, 149, 239, 85, 341, 995, 1709, 9303, 0 }; - static ulong[] dim1723JoeKuoD5Init = { 1, 3, 1, 9, 3, 23, 17, 87, 327, 929, 519, 3441, 7599, 15021, 0 }; - static ulong[] dim1724JoeKuoD5Init = { 1, 3, 3, 9, 23, 31, 81, 37, 493, 451, 603, 1943, 1055, 3959, 0 }; - static ulong[] dim1725JoeKuoD5Init = { 1, 1, 3, 13, 7, 61, 61, 127, 303, 675, 955, 249, 7653, 8441, 0 }; - static ulong[] dim1726JoeKuoD5Init = { 1, 3, 1, 5, 23, 1, 95, 109, 155, 853, 1567, 4007, 4205, 7839, 0 }; - static ulong[] dim1727JoeKuoD5Init = { 1, 3, 7, 1, 11, 27, 57, 167, 285, 421, 143, 3937, 4865, 10581, 0 }; - static ulong[] dim1728JoeKuoD5Init = { 1, 1, 1, 11, 15, 19, 49, 39, 383, 549, 1563, 2499, 7889, 239, 0 }; - static ulong[] dim1729JoeKuoD5Init = { 1, 1, 1, 7, 13, 47, 61, 77, 443, 961, 1979, 931, 433, 6457, 0 }; - static ulong[] dim1730JoeKuoD5Init = { 1, 1, 1, 5, 5, 1, 49, 137, 417, 579, 1079, 1511, 1611, 16083, 0 }; - static ulong[] dim1731JoeKuoD5Init = { 1, 3, 3, 11, 7, 51, 43, 29, 199, 525, 801, 3887, 619, 3389, 0 }; - static ulong[] dim1732JoeKuoD5Init = { 1, 1, 1, 11, 25, 23, 65, 65, 201, 875, 787, 3747, 7275, 6191, 0 }; - static ulong[] dim1733JoeKuoD5Init = { 1, 1, 3, 1, 19, 21, 117, 169, 39, 901, 3, 3579, 6119, 2057, 0 }; - static ulong[] dim1734JoeKuoD5Init = { 1, 3, 1, 9, 13, 59, 33, 43, 237, 767, 819, 3555, 1337, 13469, 0 }; - static ulong[] dim1735JoeKuoD5Init = { 1, 3, 7, 1, 25, 51, 59, 11, 427, 353, 1601, 3905, 6975, 1065, 0 }; - static ulong[] dim1736JoeKuoD5Init = { 1, 1, 7, 5, 19, 35, 43, 137, 227, 17, 803, 919, 6651, 3339, 0 }; - static ulong[] dim1737JoeKuoD5Init = { 1, 3, 1, 15, 21, 21, 41, 197, 373, 849, 1753, 515, 4093, 15407, 0 }; - static ulong[] dim1738JoeKuoD5Init = { 1, 1, 3, 3, 11, 5, 49, 223, 351, 349, 987, 1785, 269, 3037, 0 }; - static ulong[] dim1739JoeKuoD5Init = { 1, 3, 3, 9, 3, 47, 103, 225, 21, 285, 1529, 399, 4951, 10767, 0 }; - static ulong[] dim1740JoeKuoD5Init = { 1, 1, 5, 11, 25, 27, 97, 87, 487, 613, 607, 1905, 6019, 423, 0 }; - static ulong[] dim1741JoeKuoD5Init = { 1, 1, 7, 3, 23, 53, 23, 147, 69, 781, 373, 1261, 8011, 9611, 0 }; - static ulong[] dim1742JoeKuoD5Init = { 1, 3, 7, 11, 21, 43, 67, 87, 173, 57, 1147, 1841, 6031, 11261, 0 }; - static ulong[] dim1743JoeKuoD5Init = { 1, 1, 5, 7, 29, 23, 15, 113, 485, 699, 259, 1175, 7489, 5119, 0 }; - static ulong[] dim1744JoeKuoD5Init = { 1, 3, 7, 13, 15, 13, 85, 219, 107, 811, 1599, 2267, 8047, 12427, 0 }; - static ulong[] dim1745JoeKuoD5Init = { 1, 1, 3, 11, 9, 7, 127, 201, 275, 293, 1313, 3251, 3745, 15237, 0 }; - static ulong[] dim1746JoeKuoD5Init = { 1, 1, 3, 15, 1, 3, 57, 235, 509, 353, 513, 467, 1409, 4733, 0 }; - static ulong[] dim1747JoeKuoD5Init = { 1, 3, 5, 7, 13, 43, 9, 41, 39, 919, 1545, 43, 8029, 1413, 0 }; - static ulong[] dim1748JoeKuoD5Init = { 1, 1, 7, 3, 21, 7, 33, 41, 161, 53, 1635, 787, 6197, 4841, 0 }; - static ulong[] dim1749JoeKuoD5Init = { 1, 3, 3, 9, 29, 41, 19, 161, 205, 1003, 1899, 7, 4329, 11151, 0 }; - static ulong[] dim1750JoeKuoD5Init = { 1, 3, 3, 7, 23, 23, 27, 145, 375, 433, 1729, 3787, 4985, 2167, 0 }; - static ulong[] dim1751JoeKuoD5Init = { 1, 1, 3, 5, 15, 21, 77, 13, 33, 227, 837, 1373, 2745, 2339, 0 }; - static ulong[] dim1752JoeKuoD5Init = { 1, 3, 1, 13, 17, 57, 31, 83, 135, 535, 693, 803, 1459, 319, 0 }; - static ulong[] dim1753JoeKuoD5Init = { 1, 1, 1, 15, 11, 39, 105, 111, 247, 901, 395, 573, 3359, 8955, 0 }; - static ulong[] dim1754JoeKuoD5Init = { 1, 1, 3, 5, 23, 27, 99, 83, 277, 229, 429, 1451, 4755, 13951, 0 }; - static ulong[] dim1755JoeKuoD5Init = { 1, 3, 5, 15, 27, 17, 37, 81, 83, 991, 1509, 1931, 7389, 6053, 0 }; - static ulong[] dim1756JoeKuoD5Init = { 1, 1, 3, 13, 27, 55, 117, 93, 55, 65, 155, 3933, 3159, 9507, 0 }; - static ulong[] dim1757JoeKuoD5Init = { 1, 1, 7, 7, 15, 47, 109, 79, 379, 175, 419, 3285, 3207, 1675, 0 }; - static ulong[] dim1758JoeKuoD5Init = { 1, 1, 7, 15, 31, 19, 123, 229, 151, 549, 1329, 3835, 511, 14679, 0 }; - static ulong[] dim1759JoeKuoD5Init = { 1, 1, 5, 5, 25, 43, 89, 145, 419, 5, 1131, 2143, 7473, 14101, 0 }; - static ulong[] dim1760JoeKuoD5Init = { 1, 1, 1, 11, 21, 43, 7, 123, 15, 743, 241, 1737, 2239, 11007, 0 }; - static ulong[] dim1761JoeKuoD5Init = { 1, 1, 1, 15, 27, 3, 119, 157, 361, 471, 1673, 1873, 4555, 16337, 0 }; - static ulong[] dim1762JoeKuoD5Init = { 1, 1, 1, 7, 15, 39, 95, 189, 353, 605, 349, 2763, 5125, 7943, 0 }; - static ulong[] dim1763JoeKuoD5Init = { 1, 3, 3, 13, 13, 1, 45, 69, 191, 183, 1967, 2455, 3879, 2397, 0 }; - static ulong[] dim1764JoeKuoD5Init = { 1, 3, 7, 1, 3, 23, 109, 123, 127, 813, 1499, 39, 1991, 9767, 0 }; - static ulong[] dim1765JoeKuoD5Init = { 1, 3, 3, 1, 7, 3, 125, 93, 279, 803, 1203, 3623, 4359, 4251, 0 }; - static ulong[] dim1766JoeKuoD5Init = { 1, 3, 1, 15, 25, 57, 61, 103, 219, 983, 957, 895, 4077, 11799, 0 }; - static ulong[] dim1767JoeKuoD5Init = { 1, 3, 1, 9, 21, 11, 15, 137, 491, 643, 1737, 3459, 4367, 5727, 0 }; - static ulong[] dim1768JoeKuoD5Init = { 1, 3, 5, 9, 25, 57, 111, 129, 101, 807, 1481, 3703, 2713, 6375, 0 }; - static ulong[] dim1769JoeKuoD5Init = { 1, 3, 3, 1, 31, 59, 75, 173, 209, 273, 121, 747, 257, 9713, 0 }; - static ulong[] dim1770JoeKuoD5Init = { 1, 3, 5, 11, 5, 31, 107, 243, 189, 407, 773, 503, 6197, 9455, 0 }; - static ulong[] dim1771JoeKuoD5Init = { 1, 3, 5, 5, 29, 25, 31, 169, 393, 857, 1739, 883, 2147, 15569, 0 }; - static ulong[] dim1772JoeKuoD5Init = { 1, 1, 3, 11, 31, 47, 17, 119, 499, 595, 207, 1709, 4585, 12855, 0 }; - static ulong[] dim1773JoeKuoD5Init = { 1, 3, 5, 3, 21, 33, 55, 197, 349, 41, 453, 1913, 2301, 6461, 0 }; - static ulong[] dim1774JoeKuoD5Init = { 1, 3, 5, 13, 27, 37, 105, 217, 145, 1007, 259, 2681, 477, 15931, 0 }; - static ulong[] dim1775JoeKuoD5Init = { 1, 3, 3, 13, 3, 39, 9, 231, 395, 735, 501, 1631, 2931, 11947, 0 }; - static ulong[] dim1776JoeKuoD5Init = { 1, 3, 3, 11, 13, 61, 113, 113, 473, 591, 499, 2169, 6419, 10619, 0 }; - static ulong[] dim1777JoeKuoD5Init = { 1, 1, 1, 5, 29, 63, 43, 127, 243, 647, 1633, 1361, 3755, 11315, 0 }; - static ulong[] dim1778JoeKuoD5Init = { 1, 3, 5, 1, 13, 31, 111, 63, 69, 1005, 1955, 339, 2415, 4855, 0 }; - static ulong[] dim1779JoeKuoD5Init = { 1, 3, 5, 13, 25, 11, 21, 1, 343, 259, 1359, 597, 7029, 16229, 0 }; - static ulong[] dim1780JoeKuoD5Init = { 1, 1, 1, 7, 27, 13, 17, 43, 509, 105, 347, 443, 5939, 12173, 0 }; - static ulong[] dim1781JoeKuoD5Init = { 1, 3, 1, 13, 15, 25, 93, 199, 305, 725, 597, 1497, 313, 10677, 0 }; - static ulong[] dim1782JoeKuoD5Init = { 1, 3, 3, 15, 17, 7, 103, 95, 83, 433, 441, 2587, 3365, 14771, 0 }; - static ulong[] dim1783JoeKuoD5Init = { 1, 1, 7, 1, 17, 7, 55, 189, 451, 729, 817, 243, 4089, 6569, 0 }; - static ulong[] dim1784JoeKuoD5Init = { 1, 3, 1, 1, 5, 7, 19, 113, 191, 211, 1205, 4005, 3221, 7521, 0 }; - static ulong[] dim1785JoeKuoD5Init = { 1, 3, 1, 15, 25, 49, 77, 187, 105, 87, 955, 2381, 1243, 11335, 0 }; - static ulong[] dim1786JoeKuoD5Init = { 1, 3, 5, 1, 19, 63, 113, 3, 7, 105, 185, 1499, 6885, 9063, 0 }; - static ulong[] dim1787JoeKuoD5Init = { 1, 3, 3, 11, 31, 47, 37, 107, 31, 691, 1049, 2273, 1595, 4431, 0 }; - static ulong[] dim1788JoeKuoD5Init = { 1, 1, 1, 3, 23, 57, 51, 17, 225, 551, 965, 3497, 2549, 1153, 0 }; - static ulong[] dim1789JoeKuoD5Init = { 1, 3, 1, 5, 25, 41, 123, 143, 13, 437, 1081, 1625, 147, 6239, 0 }; - static ulong[] dim1790JoeKuoD5Init = { 1, 3, 3, 3, 31, 49, 17, 119, 315, 155, 37, 1125, 1223, 341, 0 }; - static ulong[] dim1791JoeKuoD5Init = { 1, 3, 1, 7, 9, 49, 35, 223, 449, 147, 317, 29, 4651, 15995, 0 }; - static ulong[] dim1792JoeKuoD5Init = { 1, 1, 3, 3, 9, 23, 97, 209, 343, 279, 1947, 3465, 7775, 5779, 0 }; - static ulong[] dim1793JoeKuoD5Init = { 1, 1, 7, 1, 7, 61, 111, 135, 473, 105, 1529, 2855, 3457, 7053, 0 }; - static ulong[] dim1794JoeKuoD5Init = { 1, 3, 5, 7, 29, 3, 63, 25, 115, 423, 1425, 1363, 77, 11485, 0 }; - static ulong[] dim1795JoeKuoD5Init = { 1, 3, 1, 15, 23, 59, 101, 87, 319, 785, 1639, 3427, 3165, 11273, 0 }; - static ulong[] dim1796JoeKuoD5Init = { 1, 3, 1, 13, 23, 7, 47, 221, 137, 775, 329, 1777, 3091, 4693, 0 }; - static ulong[] dim1797JoeKuoD5Init = { 1, 3, 7, 13, 1, 33, 31, 177, 481, 865, 739, 97, 5113, 16371, 0 }; - static ulong[] dim1798JoeKuoD5Init = { 1, 1, 3, 9, 31, 57, 99, 241, 465, 915, 1181, 225, 6795, 5743, 0 }; - static ulong[] dim1799JoeKuoD5Init = { 1, 1, 5, 3, 13, 25, 71, 119, 31, 169, 1745, 4085, 2945, 13357, 0 }; - static ulong[] dim1800JoeKuoD5Init = { 1, 1, 5, 5, 31, 61, 123, 71, 375, 1003, 1303, 2149, 5867, 10523, 0 }; - static ulong[] dim1801JoeKuoD5Init = { 1, 3, 3, 11, 21, 13, 25, 147, 147, 591, 259, 1707, 1777, 5869, 0 }; - static ulong[] dim1802JoeKuoD5Init = { 1, 3, 1, 13, 7, 13, 87, 227, 305, 235, 1263, 953, 4509, 11375, 0 }; - static ulong[] dim1803JoeKuoD5Init = { 1, 3, 5, 1, 11, 23, 103, 177, 9, 329, 1519, 2393, 6627, 14631, 0 }; - static ulong[] dim1804JoeKuoD5Init = { 1, 1, 7, 9, 25, 19, 75, 87, 361, 741, 1745, 3281, 6771, 3111, 0 }; - static ulong[] dim1805JoeKuoD5Init = { 1, 3, 7, 5, 23, 5, 1, 247, 43, 61, 1489, 3537, 5079, 11545, 0 }; - static ulong[] dim1806JoeKuoD5Init = { 1, 1, 5, 15, 9, 43, 49, 213, 191, 567, 1237, 681, 6715, 6471, 0 }; - static ulong[] dim1807JoeKuoD5Init = { 1, 3, 7, 1, 31, 53, 83, 53, 117, 1001, 525, 841, 2891, 4281, 0 }; - static ulong[] dim1808JoeKuoD5Init = { 1, 1, 1, 9, 21, 49, 21, 215, 209, 611, 1849, 969, 3081, 9485, 0 }; - static ulong[] dim1809JoeKuoD5Init = { 1, 3, 5, 15, 13, 25, 37, 31, 357, 611, 83, 1615, 8137, 14505, 0 }; - static ulong[] dim1810JoeKuoD5Init = { 1, 3, 3, 11, 29, 31, 9, 27, 427, 883, 555, 2559, 7039, 11345, 0 }; - static ulong[] dim1811JoeKuoD5Init = { 1, 1, 3, 11, 3, 17, 9, 251, 493, 977, 1713, 2711, 4377, 3171, 0 }; - static ulong[] dim1812JoeKuoD5Init = { 1, 1, 1, 7, 9, 1, 27, 179, 345, 425, 413, 2101, 3417, 1497, 0 }; - static ulong[] dim1813JoeKuoD5Init = { 1, 1, 3, 3, 13, 33, 121, 81, 247, 1003, 1405, 2769, 1919, 10807, 0 }; - static ulong[] dim1814JoeKuoD5Init = { 1, 1, 3, 15, 29, 51, 13, 101, 237, 165, 1483, 3961, 2389, 8379, 0 }; - static ulong[] dim1815JoeKuoD5Init = { 1, 3, 5, 11, 17, 3, 51, 141, 295, 165, 1089, 3889, 6415, 4969, 0 }; - static ulong[] dim1816JoeKuoD5Init = { 1, 1, 7, 3, 25, 47, 1, 17, 499, 409, 1417, 2975, 3935, 13363, 0 }; - static ulong[] dim1817JoeKuoD5Init = { 1, 1, 3, 13, 7, 55, 91, 121, 509, 675, 1203, 795, 1225, 15329, 0 }; - static ulong[] dim1818JoeKuoD5Init = { 1, 3, 7, 5, 3, 29, 19, 103, 11, 511, 799, 773, 515, 9931, 0 }; - static ulong[] dim1819JoeKuoD5Init = { 1, 1, 5, 3, 27, 63, 19, 83, 213, 977, 1923, 999, 7935, 2081, 0 }; - static ulong[] dim1820JoeKuoD5Init = { 1, 3, 7, 3, 19, 17, 127, 251, 417, 711, 85, 2757, 6461, 83, 0 }; - static ulong[] dim1821JoeKuoD5Init = { 1, 1, 3, 9, 11, 7, 113, 127, 287, 647, 1775, 3201, 2551, 13389, 0 }; - static ulong[] dim1822JoeKuoD5Init = { 1, 1, 7, 15, 31, 33, 81, 53, 207, 361, 665, 2073, 4249, 6699, 0 }; - static ulong[] dim1823JoeKuoD5Init = { 1, 3, 5, 11, 25, 43, 83, 159, 31, 693, 1315, 2043, 3463, 15771, 0 }; - static ulong[] dim1824JoeKuoD5Init = { 1, 1, 7, 15, 9, 1, 93, 207, 97, 293, 67, 2411, 1241, 10819, 0 }; - static ulong[] dim1825JoeKuoD5Init = { 1, 1, 7, 15, 17, 41, 113, 153, 7, 499, 131, 737, 7881, 2691, 0 }; - static ulong[] dim1826JoeKuoD5Init = { 1, 3, 1, 11, 5, 3, 125, 49, 63, 375, 811, 3295, 7997, 1063, 0 }; - static ulong[] dim1827JoeKuoD5Init = { 1, 1, 1, 5, 1, 27, 37, 101, 179, 975, 421, 2785, 8093, 11803, 0 }; - static ulong[] dim1828JoeKuoD5Init = { 1, 3, 7, 3, 27, 35, 89, 111, 481, 821, 223, 2983, 2369, 4861, 0 }; - static ulong[] dim1829JoeKuoD5Init = { 1, 1, 5, 3, 21, 59, 25, 237, 73, 451, 309, 241, 4955, 9889, 0 }; - static ulong[] dim1830JoeKuoD5Init = { 1, 3, 3, 15, 25, 37, 85, 29, 103, 893, 337, 2831, 6679, 15171, 0 }; - static ulong[] dim1831JoeKuoD5Init = { 1, 1, 7, 3, 13, 1, 101, 109, 223, 243, 1749, 3611, 4097, 14439, 0 }; - static ulong[] dim1832JoeKuoD5Init = { 1, 3, 3, 11, 31, 49, 97, 181, 269, 567, 1801, 3129, 2697, 15167, 0 }; - static ulong[] dim1833JoeKuoD5Init = { 1, 3, 1, 5, 11, 11, 105, 161, 163, 363, 187, 3671, 6793, 4197, 0 }; - static ulong[] dim1834JoeKuoD5Init = { 1, 1, 3, 1, 23, 61, 127, 9, 101, 493, 1875, 3943, 3501, 1685, 0 }; - static ulong[] dim1835JoeKuoD5Init = { 1, 1, 5, 3, 29, 13, 11, 185, 437, 151, 927, 199, 7739, 14771, 0 }; - static ulong[] dim1836JoeKuoD5Init = { 1, 3, 1, 5, 17, 17, 35, 147, 387, 401, 1385, 1993, 1551, 2421, 0 }; - static ulong[] dim1837JoeKuoD5Init = { 1, 1, 5, 7, 25, 27, 1, 43, 407, 503, 1917, 23, 3459, 7653, 0 }; - static ulong[] dim1838JoeKuoD5Init = { 1, 3, 7, 1, 29, 37, 69, 193, 359, 901, 1661, 4049, 2923, 15553, 0 }; - static ulong[] dim1839JoeKuoD5Init = { 1, 1, 3, 11, 31, 53, 45, 5, 143, 823, 483, 669, 8037, 14021, 0 }; - static ulong[] dim1840JoeKuoD5Init = { 1, 3, 3, 15, 23, 47, 105, 185, 267, 347, 85, 3121, 5811, 6229, 0 }; - static ulong[] dim1841JoeKuoD5Init = { 1, 1, 5, 5, 27, 43, 25, 143, 197, 425, 1537, 1701, 6061, 12125, 0 }; - static ulong[] dim1842JoeKuoD5Init = { 1, 3, 1, 1, 31, 57, 21, 21, 301, 573, 947, 2087, 3135, 1767, 0 }; - static ulong[] dim1843JoeKuoD5Init = { 1, 1, 5, 15, 23, 35, 35, 191, 195, 131, 1669, 3311, 4107, 9311, 0 }; - static ulong[] dim1844JoeKuoD5Init = { 1, 1, 7, 5, 23, 13, 111, 165, 283, 949, 1575, 2359, 5891, 9911, 0 }; - static ulong[] dim1845JoeKuoD5Init = { 1, 1, 5, 13, 17, 31, 31, 179, 45, 475, 975, 251, 353, 6331, 0 }; - static ulong[] dim1846JoeKuoD5Init = { 1, 3, 1, 13, 15, 9, 127, 35, 463, 711, 1783, 837, 7859, 14299, 0 }; - static ulong[] dim1847JoeKuoD5Init = { 1, 3, 5, 5, 31, 57, 79, 7, 319, 517, 677, 3923, 1363, 11355, 0 }; - static ulong[] dim1848JoeKuoD5Init = { 1, 3, 7, 3, 17, 17, 49, 171, 95, 519, 775, 2265, 7953, 617, 0 }; - static ulong[] dim1849JoeKuoD5Init = { 1, 3, 5, 9, 3, 35, 87, 185, 369, 795, 1171, 3777, 4983, 1153, 0 }; - static ulong[] dim1850JoeKuoD5Init = { 1, 1, 5, 3, 9, 3, 1, 131, 275, 921, 507, 1877, 1573, 6231, 0 }; - static ulong[] dim1851JoeKuoD5Init = { 1, 1, 5, 15, 7, 53, 77, 255, 329, 449, 1859, 3625, 7027, 9921, 0 }; - static ulong[] dim1852JoeKuoD5Init = { 1, 1, 5, 7, 1, 47, 57, 111, 303, 749, 689, 2963, 8085, 9097, 0 }; - static ulong[] dim1853JoeKuoD5Init = { 1, 3, 7, 11, 19, 47, 61, 3, 481, 371, 1737, 287, 5485, 15433, 0 }; - static ulong[] dim1854JoeKuoD5Init = { 1, 3, 1, 13, 23, 45, 33, 83, 483, 411, 257, 749, 3959, 10269, 0 }; - static ulong[] dim1855JoeKuoD5Init = { 1, 1, 7, 5, 25, 15, 11, 181, 131, 943, 125, 3367, 2429, 2151, 0 }; - static ulong[] dim1856JoeKuoD5Init = { 1, 3, 5, 15, 25, 35, 37, 163, 399, 575, 843, 1567, 4401, 14757, 0 }; - static ulong[] dim1857JoeKuoD5Init = { 1, 1, 5, 1, 5, 3, 31, 199, 479, 525, 973, 2843, 7831, 6693, 0 }; - static ulong[] dim1858JoeKuoD5Init = { 1, 1, 5, 3, 21, 7, 123, 31, 207, 741, 425, 2139, 2965, 1017, 0 }; - static ulong[] dim1859JoeKuoD5Init = { 1, 1, 1, 11, 3, 31, 61, 85, 303, 627, 1995, 3211, 5747, 14897, 0 }; - static ulong[] dim1860JoeKuoD5Init = { 1, 1, 7, 7, 9, 25, 45, 73, 427, 945, 1505, 1121, 7585, 13115, 0 }; - static ulong[] dim1861JoeKuoD5Init = { 1, 1, 5, 1, 9, 43, 75, 63, 445, 709, 645, 1105, 1375, 12303, 0 }; - static ulong[] dim1862JoeKuoD5Init = { 1, 1, 3, 5, 25, 37, 101, 209, 239, 429, 1455, 3587, 4231, 6501, 0 }; - static ulong[] dim1863JoeKuoD5Init = { 1, 3, 7, 1, 21, 23, 113, 227, 151, 97, 367, 889, 7675, 14093, 0 }; - static ulong[] dim1864JoeKuoD5Init = { 1, 1, 7, 11, 13, 31, 63, 7, 31, 973, 1935, 53, 4941, 9057, 0 }; - static ulong[] dim1865JoeKuoD5Init = { 1, 3, 1, 13, 21, 23, 79, 43, 255, 1003, 1741, 1003, 355, 3839, 0 }; - static ulong[] dim1866JoeKuoD5Init = { 1, 1, 5, 9, 31, 17, 45, 235, 271, 711, 61, 235, 513, 11321, 0 }; - static ulong[] dim1867JoeKuoD5Init = { 1, 1, 3, 9, 29, 35, 43, 115, 9, 787, 325, 625, 7905, 8191, 29233, 0 }; - static ulong[] dim1868JoeKuoD5Init = { 1, 1, 1, 13, 5, 17, 67, 161, 357, 163, 1129, 3819, 3601, 5961, 9259, 0 }; - static ulong[] dim1869JoeKuoD5Init = { 1, 3, 7, 13, 25, 17, 83, 41, 463, 879, 1881, 1107, 4337, 409, 8633, 0 }; - static ulong[] dim1870JoeKuoD5Init = { 1, 3, 1, 1, 17, 45, 127, 213, 285, 791, 479, 3153, 3001, 16207, 32669, 0 }; - static ulong[] dim1871JoeKuoD5Init = { 1, 1, 7, 11, 23, 41, 103, 209, 81, 903, 1787, 907, 161, 15739, 17367, 0 }; - static ulong[] dim1872JoeKuoD5Init = { 1, 3, 1, 11, 17, 61, 69, 251, 321, 361, 905, 1081, 5749, 2639, 21195, 0 }; - static ulong[] dim1873JoeKuoD5Init = { 1, 1, 7, 13, 27, 39, 61, 161, 139, 837, 579, 1979, 4413, 8701, 16301, 0 }; - static ulong[] dim1874JoeKuoD5Init = { 1, 3, 3, 7, 3, 49, 111, 77, 423, 491, 1489, 2615, 4997, 3695, 15109, 0 }; - static ulong[] dim1875JoeKuoD5Init = { 1, 1, 5, 7, 31, 3, 53, 113, 45, 767, 1561, 2925, 605, 3211, 8413, 0 }; - static ulong[] dim1876JoeKuoD5Init = { 1, 3, 1, 15, 31, 29, 65, 13, 19, 159, 639, 2155, 2699, 7001, 15575, 0 }; - static ulong[] dim1877JoeKuoD5Init = { 1, 3, 5, 1, 3, 33, 37, 89, 189, 661, 1685, 503, 6037, 12993, 9571, 0 }; - static ulong[] dim1878JoeKuoD5Init = { 1, 3, 5, 13, 31, 13, 41, 35, 217, 193, 1273, 443, 1385, 13661, 14873, 0 }; - static ulong[] dim1879JoeKuoD5Init = { 1, 1, 7, 15, 3, 9, 123, 251, 155, 545, 813, 317, 5127, 15305, 5571, 0 }; - static ulong[] dim1880JoeKuoD5Init = { 1, 1, 1, 15, 3, 39, 41, 39, 273, 881, 809, 1643, 687, 5525, 3473, 0 }; - static ulong[] dim1881JoeKuoD5Init = { 1, 3, 5, 11, 7, 25, 25, 27, 263, 773, 155, 1541, 7545, 873, 32713, 0 }; - static ulong[] dim1882JoeKuoD5Init = { 1, 1, 5, 9, 1, 49, 57, 17, 433, 73, 635, 1073, 7459, 15653, 47, 0 }; - static ulong[] dim1883JoeKuoD5Init = { 1, 1, 1, 13, 1, 5, 65, 105, 353, 361, 339, 3983, 2707, 10165, 20883, 0 }; - static ulong[] dim1884JoeKuoD5Init = { 1, 3, 5, 3, 23, 29, 125, 223, 463, 493, 1989, 1583, 8153, 13475, 5789, 0 }; - static ulong[] dim1885JoeKuoD5Init = { 1, 1, 7, 7, 27, 39, 61, 127, 387, 215, 1769, 2279, 7883, 1491, 29625, 0 }; - static ulong[] dim1886JoeKuoD5Init = { 1, 1, 7, 5, 5, 13, 11, 47, 409, 673, 1927, 1277, 6971, 8195, 22663, 0 }; - static ulong[] dim1887JoeKuoD5Init = { 1, 3, 3, 13, 1, 53, 123, 187, 25, 29, 1107, 1929, 6995, 5081, 8861, 0 }; - static ulong[] dim1888JoeKuoD5Init = { 1, 3, 1, 5, 25, 27, 53, 65, 239, 299, 21, 3389, 1587, 1437, 26209, 0 }; - static ulong[] dim1889JoeKuoD5Init = { 1, 1, 1, 7, 15, 35, 37, 105, 169, 843, 623, 3763, 7101, 5245, 17203, 0 }; - static ulong[] dim1890JoeKuoD5Init = { 1, 1, 3, 15, 21, 7, 29, 29, 465, 149, 189, 1115, 6471, 11275, 28769, 0 }; - static ulong[] dim1891JoeKuoD5Init = { 1, 1, 1, 9, 31, 1, 99, 101, 321, 675, 1631, 1371, 7733, 1697, 4437, 0 }; - static ulong[] dim1892JoeKuoD5Init = { 1, 1, 3, 9, 7, 27, 47, 207, 295, 787, 1539, 2233, 7849, 15843, 11149, 0 }; - static ulong[] dim1893JoeKuoD5Init = { 1, 3, 1, 3, 17, 29, 61, 143, 289, 939, 729, 297, 1513, 4387, 3347, 0 }; - static ulong[] dim1894JoeKuoD5Init = { 1, 3, 5, 13, 15, 25, 125, 13, 157, 377, 317, 827, 5137, 829, 21215, 0 }; - static ulong[] dim1895JoeKuoD5Init = { 1, 3, 5, 13, 17, 37, 79, 87, 163, 847, 1009, 2259, 6543, 8697, 4837, 0 }; - static ulong[] dim1896JoeKuoD5Init = { 1, 1, 5, 11, 29, 7, 13, 91, 279, 439, 691, 4047, 159, 9403, 27735, 0 }; - static ulong[] dim1897JoeKuoD5Init = { 1, 1, 5, 5, 23, 61, 53, 93, 343, 349, 355, 1275, 3573, 12847, 8969, 0 }; - static ulong[] dim1898JoeKuoD5Init = { 1, 1, 3, 11, 1, 49, 47, 255, 371, 511, 579, 2385, 2237, 2015, 23973, 0 }; - static ulong[] dim1899JoeKuoD5Init = { 1, 1, 7, 11, 15, 31, 13, 121, 399, 957, 731, 3743, 1573, 2293, 27755, 0 }; - static ulong[] dim1900JoeKuoD5Init = { 1, 3, 5, 5, 23, 19, 57, 211, 133, 197, 379, 1037, 625, 9405, 11547, 0 }; - static ulong[] dim1901JoeKuoD5Init = { 1, 1, 5, 15, 7, 13, 75, 93, 415, 551, 1885, 2259, 23, 14321, 21509, 0 }; - static ulong[] dim1902JoeKuoD5Init = { 1, 1, 3, 5, 29, 37, 23, 59, 199, 559, 1761, 821, 5077, 12017, 16505, 0 }; - static ulong[] dim1903JoeKuoD5Init = { 1, 1, 7, 7, 19, 29, 31, 101, 121, 605, 1679, 2317, 3359, 13557, 17567, 0 }; - static ulong[] dim1904JoeKuoD5Init = { 1, 1, 3, 15, 3, 5, 45, 201, 401, 689, 1775, 3615, 2641, 14149, 29241, 0 }; - static ulong[] dim1905JoeKuoD5Init = { 1, 3, 1, 5, 9, 13, 51, 101, 41, 347, 57, 613, 5813, 3753, 22007, 0 }; - static ulong[] dim1906JoeKuoD5Init = { 1, 1, 5, 15, 19, 59, 57, 57, 405, 647, 1943, 353, 1691, 9287, 29567, 0 }; - static ulong[] dim1907JoeKuoD5Init = { 1, 3, 1, 13, 29, 11, 51, 137, 163, 365, 153, 3791, 5367, 4649, 11255, 0 }; - static ulong[] dim1908JoeKuoD5Init = { 1, 3, 1, 1, 27, 37, 99, 211, 377, 543, 649, 2107, 3511, 10385, 1093, 0 }; - static ulong[] dim1909JoeKuoD5Init = { 1, 1, 5, 9, 29, 25, 85, 75, 55, 75, 825, 2129, 6867, 9053, 22687, 0 }; - static ulong[] dim1910JoeKuoD5Init = { 1, 3, 7, 1, 19, 57, 29, 99, 369, 107, 1187, 2919, 6163, 15209, 7911, 0 }; - static ulong[] dim1911JoeKuoD5Init = { 1, 1, 3, 11, 25, 55, 111, 197, 329, 307, 1531, 1753, 1275, 5543, 23411, 0 }; - static ulong[] dim1912JoeKuoD5Init = { 1, 1, 5, 9, 21, 59, 97, 211, 117, 331, 1919, 1763, 1755, 12517, 16579, 0 }; - static ulong[] dim1913JoeKuoD5Init = { 1, 3, 7, 11, 5, 37, 21, 229, 109, 341, 421, 2413, 785, 3251, 10245, 0 }; - static ulong[] dim1914JoeKuoD5Init = { 1, 3, 5, 11, 27, 3, 89, 15, 455, 53, 1447, 137, 681, 7811, 16817, 0 }; - static ulong[] dim1915JoeKuoD5Init = { 1, 3, 5, 13, 9, 57, 45, 101, 459, 801, 409, 911, 749, 11875, 6039, 0 }; - static ulong[] dim1916JoeKuoD5Init = { 1, 3, 1, 13, 23, 31, 49, 105, 255, 485, 1587, 1137, 2113, 16313, 19073, 0 }; - static ulong[] dim1917JoeKuoD5Init = { 1, 3, 7, 9, 31, 59, 117, 213, 293, 195, 991, 3531, 157, 1747, 20883, 0 }; - static ulong[] dim1918JoeKuoD5Init = { 1, 1, 3, 11, 17, 31, 63, 33, 415, 341, 779, 423, 5661, 2533, 23031, 0 }; - static ulong[] dim1919JoeKuoD5Init = { 1, 3, 5, 3, 11, 41, 69, 117, 441, 3, 885, 3387, 4291, 497, 9991, 0 }; - static ulong[] dim1920JoeKuoD5Init = { 1, 3, 1, 15, 27, 29, 17, 109, 315, 433, 291, 577, 3209, 3305, 6759, 0 }; - static ulong[] dim1921JoeKuoD5Init = { 1, 1, 5, 1, 29, 37, 75, 139, 243, 217, 319, 1025, 2415, 5957, 8303, 0 }; - static ulong[] dim1922JoeKuoD5Init = { 1, 3, 5, 9, 15, 41, 19, 21, 279, 563, 893, 1391, 4907, 14381, 7165, 0 }; - static ulong[] dim1923JoeKuoD5Init = { 1, 3, 1, 13, 21, 35, 23, 139, 441, 463, 563, 155, 2009, 14887, 30943, 0 }; - static ulong[] dim1924JoeKuoD5Init = { 1, 1, 5, 3, 23, 23, 13, 157, 511, 401, 1573, 3019, 1791, 587, 10927, 0 }; - static ulong[] dim1925JoeKuoD5Init = { 1, 1, 5, 5, 1, 45, 127, 85, 27, 729, 993, 1487, 5577, 14113, 23163, 0 }; - static ulong[] dim1926JoeKuoD5Init = { 1, 3, 7, 5, 31, 15, 19, 7, 503, 359, 595, 1471, 2587, 7827, 31497, 0 }; - static ulong[] dim1927JoeKuoD5Init = { 1, 3, 1, 1, 13, 29, 35, 49, 381, 677, 407, 2681, 7923, 2917, 4001, 0 }; - static ulong[] dim1928JoeKuoD5Init = { 1, 3, 3, 5, 25, 51, 3, 33, 229, 105, 1449, 417, 2577, 5185, 18737, 0 }; - static ulong[] dim1929JoeKuoD5Init = { 1, 3, 7, 9, 29, 17, 9, 185, 253, 929, 1267, 2559, 2271, 10501, 21687, 0 }; - static ulong[] dim1930JoeKuoD5Init = { 1, 3, 3, 13, 9, 29, 89, 193, 309, 385, 73, 1835, 5193, 10235, 29827, 0 }; - static ulong[] dim1931JoeKuoD5Init = { 1, 3, 5, 7, 29, 23, 9, 119, 325, 277, 1883, 613, 6299, 10799, 16271, 0 }; - static ulong[] dim1932JoeKuoD5Init = { 1, 1, 5, 11, 29, 55, 71, 5, 99, 303, 1853, 2225, 3047, 16019, 23257, 0 }; - static ulong[] dim1933JoeKuoD5Init = { 1, 3, 1, 1, 19, 19, 35, 39, 389, 737, 433, 1489, 5903, 10181, 11249, 0 }; - static ulong[] dim1934JoeKuoD5Init = { 1, 1, 3, 13, 15, 13, 21, 191, 369, 939, 1353, 2645, 221, 49, 14783, 0 }; - static ulong[] dim1935JoeKuoD5Init = { 1, 1, 1, 1, 17, 5, 21, 121, 359, 863, 893, 2887, 4431, 5245, 20865, 0 }; - static ulong[] dim1936JoeKuoD5Init = { 1, 3, 5, 11, 15, 25, 59, 37, 263, 425, 1143, 3843, 4955, 6639, 8411, 0 }; - static ulong[] dim1937JoeKuoD5Init = { 1, 1, 7, 15, 3, 5, 123, 131, 229, 93, 113, 3609, 2007, 7709, 32141, 0 }; - static ulong[] dim1938JoeKuoD5Init = { 1, 3, 5, 11, 25, 43, 103, 199, 243, 533, 1947, 683, 1013, 13155, 29877, 0 }; - static ulong[] dim1939JoeKuoD5Init = { 1, 3, 1, 9, 17, 41, 57, 99, 137, 839, 1437, 3997, 2473, 10169, 20253, 0 }; - static ulong[] dim1940JoeKuoD5Init = { 1, 1, 3, 5, 19, 49, 55, 185, 175, 319, 1173, 1049, 5289, 3297, 23755, 0 }; - static ulong[] dim1941JoeKuoD5Init = { 1, 3, 7, 5, 25, 7, 81, 119, 319, 743, 1655, 3719, 5731, 11015, 11309, 0 }; - static ulong[] dim1942JoeKuoD5Init = { 1, 1, 1, 9, 31, 53, 61, 119, 207, 689, 81, 367, 2495, 1965, 15559, 0 }; - static ulong[] dim1943JoeKuoD5Init = { 1, 1, 1, 3, 21, 47, 9, 199, 273, 397, 1293, 2709, 3687, 5755, 6015, 0 }; - static ulong[] dim1944JoeKuoD5Init = { 1, 3, 5, 15, 1, 7, 55, 55, 343, 363, 1207, 3731, 7489, 2365, 25301, 0 }; - static ulong[] dim1945JoeKuoD5Init = { 1, 3, 3, 7, 3, 31, 87, 15, 327, 479, 177, 1261, 913, 4189, 4565, 0 }; - static ulong[] dim1946JoeKuoD5Init = { 1, 1, 7, 9, 19, 37, 29, 17, 185, 827, 239, 281, 287, 16105, 23549, 0 }; - static ulong[] dim1947JoeKuoD5Init = { 1, 1, 1, 3, 23, 17, 73, 123, 287, 665, 297, 215, 359, 11741, 29159, 0 }; - static ulong[] dim1948JoeKuoD5Init = { 1, 3, 1, 11, 13, 45, 35, 81, 211, 257, 655, 911, 5949, 9597, 11677, 0 }; - static ulong[] dim1949JoeKuoD5Init = { 1, 3, 3, 15, 7, 39, 31, 103, 341, 871, 299, 635, 951, 13669, 30083, 0 }; - static ulong[] dim1950JoeKuoD5Init = { 1, 1, 1, 7, 7, 15, 55, 45, 375, 711, 1339, 3045, 4691, 13247, 14611, 0 }; - static ulong[] dim1951JoeKuoD5Init = { 1, 1, 1, 9, 19, 33, 67, 91, 83, 541, 1229, 3209, 2783, 11519, 10729, 0 }; - static ulong[] dim1952JoeKuoD5Init = { 1, 3, 5, 7, 15, 15, 89, 7, 173, 809, 1229, 117, 2323, 15145, 2863, 0 }; - static ulong[] dim1953JoeKuoD5Init = { 1, 3, 5, 13, 1, 55, 39, 187, 491, 675, 1357, 1109, 2701, 14891, 17061, 0 }; - static ulong[] dim1954JoeKuoD5Init = { 1, 3, 3, 5, 7, 47, 127, 111, 481, 177, 1553, 2949, 6403, 1993, 26227, 0 }; - static ulong[] dim1955JoeKuoD5Init = { 1, 1, 3, 11, 31, 3, 111, 193, 445, 359, 1039, 667, 7463, 7983, 10901, 0 }; - static ulong[] dim1956JoeKuoD5Init = { 1, 3, 5, 15, 29, 17, 15, 69, 111, 27, 647, 3377, 185, 12083, 21197, 0 }; - static ulong[] dim1957JoeKuoD5Init = { 1, 3, 7, 5, 17, 57, 5, 189, 383, 407, 145, 1185, 3307, 12373, 28531, 0 }; - static ulong[] dim1958JoeKuoD5Init = { 1, 1, 5, 9, 23, 43, 41, 19, 127, 687, 1841, 3707, 4983, 14585, 15253, 0 }; - static ulong[] dim1959JoeKuoD5Init = { 1, 1, 3, 9, 13, 61, 13, 113, 43, 423, 1073, 1843, 1071, 7869, 21137, 0 }; - static ulong[] dim1960JoeKuoD5Init = { 1, 1, 3, 3, 7, 43, 87, 185, 375, 699, 283, 3265, 4905, 9317, 3055, 0 }; - static ulong[] dim1961JoeKuoD5Init = { 1, 1, 7, 9, 17, 15, 47, 73, 211, 37, 427, 3841, 2801, 12131, 19619, 0 }; - static ulong[] dim1962JoeKuoD5Init = { 1, 1, 1, 7, 17, 35, 53, 67, 221, 97, 199, 2825, 1997, 9903, 3003, 0 }; - static ulong[] dim1963JoeKuoD5Init = { 1, 3, 5, 9, 23, 53, 69, 225, 413, 307, 553, 2631, 6499, 6277, 30337, 0 }; - static ulong[] dim1964JoeKuoD5Init = { 1, 3, 5, 13, 5, 23, 85, 193, 437, 607, 397, 2003, 4345, 3575, 27939, 0 }; - static ulong[] dim1965JoeKuoD5Init = { 1, 3, 1, 13, 13, 45, 117, 191, 143, 477, 473, 3051, 5903, 6253, 22679, 0 }; - static ulong[] dim1966JoeKuoD5Init = { 1, 1, 1, 13, 31, 49, 31, 217, 119, 893, 1415, 1633, 7573, 8353, 32231, 0 }; - static ulong[] dim1967JoeKuoD5Init = { 1, 1, 3, 5, 29, 47, 25, 3, 425, 883, 1461, 3679, 6635, 9103, 26793, 0 }; - static ulong[] dim1968JoeKuoD5Init = { 1, 1, 5, 15, 11, 27, 87, 31, 153, 115, 1573, 745, 6515, 14321, 21301, 0 }; - static ulong[] dim1969JoeKuoD5Init = { 1, 1, 5, 11, 15, 57, 41, 157, 147, 867, 1959, 943, 6431, 14581, 9579, 0 }; - static ulong[] dim1970JoeKuoD5Init = { 1, 3, 7, 9, 5, 13, 1, 203, 317, 185, 1569, 3621, 4873, 13249, 19153, 0 }; - static ulong[] dim1971JoeKuoD5Init = { 1, 1, 1, 5, 5, 29, 41, 3, 37, 919, 1037, 237, 4699, 12011, 18669, 0 }; - static ulong[] dim1972JoeKuoD5Init = { 1, 1, 1, 1, 21, 1, 55, 195, 289, 635, 981, 1395, 1827, 7481, 19163, 0 }; - static ulong[] dim1973JoeKuoD5Init = { 1, 1, 5, 13, 15, 15, 89, 109, 17, 111, 815, 2637, 6917, 7973, 9471, 0 }; - static ulong[] dim1974JoeKuoD5Init = { 1, 1, 1, 15, 9, 25, 73, 101, 417, 519, 1697, 2861, 2281, 10959, 30433, 0 }; - static ulong[] dim1975JoeKuoD5Init = { 1, 3, 3, 3, 21, 51, 89, 157, 181, 307, 355, 661, 4885, 12411, 23473, 0 }; - static ulong[] dim1976JoeKuoD5Init = { 1, 1, 1, 15, 17, 37, 19, 139, 205, 73, 97, 2463, 2785, 9355, 23989, 0 }; - static ulong[] dim1977JoeKuoD5Init = { 1, 1, 3, 1, 7, 39, 117, 191, 395, 539, 1823, 2333, 1205, 14131, 2301, 0 }; - static ulong[] dim1978JoeKuoD5Init = { 1, 1, 5, 13, 21, 11, 49, 43, 381, 15, 1743, 641, 95, 10581, 15437, 0 }; - static ulong[] dim1979JoeKuoD5Init = { 1, 3, 7, 7, 5, 53, 55, 23, 265, 163, 173, 1399, 7257, 15097, 13491, 0 }; - static ulong[] dim1980JoeKuoD5Init = { 1, 3, 3, 13, 27, 55, 97, 51, 469, 7, 871, 3213, 5719, 871, 11669, 0 }; - static ulong[] dim1981JoeKuoD5Init = { 1, 1, 7, 3, 29, 35, 47, 31, 77, 335, 537, 1695, 461, 14417, 23945, 0 }; - static ulong[] dim1982JoeKuoD5Init = { 1, 3, 5, 13, 1, 47, 97, 113, 235, 593, 1437, 3893, 5299, 857, 451, 0 }; - static ulong[] dim1983JoeKuoD5Init = { 1, 3, 7, 3, 3, 53, 51, 203, 177, 205, 773, 281, 7689, 8039, 7275, 0 }; - static ulong[] dim1984JoeKuoD5Init = { 1, 1, 7, 3, 3, 37, 33, 113, 429, 791, 1593, 3259, 1275, 11113, 16001, 0 }; - static ulong[] dim1985JoeKuoD5Init = { 1, 3, 5, 7, 27, 9, 109, 229, 453, 633, 2047, 1803, 4127, 3453, 15625, 0 }; - static ulong[] dim1986JoeKuoD5Init = { 1, 3, 5, 15, 17, 59, 15, 73, 105, 627, 1181, 2925, 2077, 16067, 15829, 0 }; - static ulong[] dim1987JoeKuoD5Init = { 1, 3, 1, 1, 15, 41, 1, 143, 493, 261, 845, 737, 6249, 7663, 32439, 0 }; - static ulong[] dim1988JoeKuoD5Init = { 1, 3, 5, 9, 11, 45, 101, 227, 227, 211, 243, 2817, 179, 3361, 20535, 0 }; - static ulong[] dim1989JoeKuoD5Init = { 1, 3, 1, 3, 11, 25, 105, 173, 249, 465, 853, 2365, 5035, 11541, 5481, 0 }; - static ulong[] dim1990JoeKuoD5Init = { 1, 3, 5, 9, 21, 29, 77, 245, 311, 879, 1007, 2545, 1561, 2949, 24855, 0 }; - static ulong[] dim1991JoeKuoD5Init = { 1, 1, 5, 13, 1, 31, 105, 151, 127, 413, 553, 645, 863, 15943, 32731, 0 }; - static ulong[] dim1992JoeKuoD5Init = { 1, 3, 7, 11, 21, 13, 71, 229, 283, 493, 1445, 15, 4681, 3137, 18199, 0 }; - static ulong[] dim1993JoeKuoD5Init = { 1, 1, 3, 15, 27, 17, 37, 213, 253, 117, 205, 1489, 2997, 6483, 17201, 0 }; - static ulong[] dim1994JoeKuoD5Init = { 1, 1, 7, 13, 3, 29, 83, 109, 503, 139, 1119, 59, 5259, 8289, 7717, 0 }; - static ulong[] dim1995JoeKuoD5Init = { 1, 1, 3, 13, 13, 5, 65, 231, 117, 1009, 163, 21, 7639, 16275, 10661, 0 }; - static ulong[] dim1996JoeKuoD5Init = { 1, 3, 7, 7, 19, 63, 31, 211, 487, 277, 27, 3685, 5371, 8157, 29735, 0 }; - static ulong[] dim1997JoeKuoD5Init = { 1, 1, 3, 1, 11, 49, 113, 191, 3, 923, 797, 2055, 3999, 8511, 23931, 0 }; - static ulong[] dim1998JoeKuoD5Init = { 1, 1, 7, 7, 13, 27, 87, 43, 433, 401, 1441, 1301, 2639, 5773, 12431, 0 }; - static ulong[] dim1999JoeKuoD5Init = { 1, 1, 3, 15, 21, 55, 17, 57, 449, 811, 519, 2329, 7607, 4255, 2845, 0 }; - - static ulong[][] JoeKuoD5initializers = { - dim1JoeKuoD5Init, - dim2JoeKuoD5Init, - dim3JoeKuoD5Init, - dim4JoeKuoD5Init, - dim5JoeKuoD5Init, - dim6JoeKuoD5Init, - dim7JoeKuoD5Init, - dim8JoeKuoD5Init, - dim9JoeKuoD5Init, - dim10JoeKuoD5Init, - dim11JoeKuoD5Init, - dim12JoeKuoD5Init, - dim13JoeKuoD5Init, - dim14JoeKuoD5Init, - dim15JoeKuoD5Init, - dim16JoeKuoD5Init, - dim17JoeKuoD5Init, - dim18JoeKuoD5Init, - dim19JoeKuoD5Init, - dim20JoeKuoD5Init, - dim21JoeKuoD5Init, - dim22JoeKuoD5Init, - dim23JoeKuoD5Init, - dim24JoeKuoD5Init, - dim25JoeKuoD5Init, - dim26JoeKuoD5Init, - dim27JoeKuoD5Init, - dim28JoeKuoD5Init, - dim29JoeKuoD5Init, - dim30JoeKuoD5Init, - dim31JoeKuoD5Init, - dim32JoeKuoD5Init, - dim33JoeKuoD5Init, - dim34JoeKuoD5Init, - dim35JoeKuoD5Init, - dim36JoeKuoD5Init, - dim37JoeKuoD5Init, - dim38JoeKuoD5Init, - dim39JoeKuoD5Init, - dim40JoeKuoD5Init, - dim41JoeKuoD5Init, - dim42JoeKuoD5Init, - dim43JoeKuoD5Init, - dim44JoeKuoD5Init, - dim45JoeKuoD5Init, - dim46JoeKuoD5Init, - dim47JoeKuoD5Init, - dim48JoeKuoD5Init, - dim49JoeKuoD5Init, - dim50JoeKuoD5Init, - dim51JoeKuoD5Init, - dim52JoeKuoD5Init, - dim53JoeKuoD5Init, - dim54JoeKuoD5Init, - dim55JoeKuoD5Init, - dim56JoeKuoD5Init, - dim57JoeKuoD5Init, - dim58JoeKuoD5Init, - dim59JoeKuoD5Init, - dim60JoeKuoD5Init, - dim61JoeKuoD5Init, - dim62JoeKuoD5Init, - dim63JoeKuoD5Init, - dim64JoeKuoD5Init, - dim65JoeKuoD5Init, - dim66JoeKuoD5Init, - dim67JoeKuoD5Init, - dim68JoeKuoD5Init, - dim69JoeKuoD5Init, - dim70JoeKuoD5Init, - dim71JoeKuoD5Init, - dim72JoeKuoD5Init, - dim73JoeKuoD5Init, - dim74JoeKuoD5Init, - dim75JoeKuoD5Init, - dim76JoeKuoD5Init, - dim77JoeKuoD5Init, - dim78JoeKuoD5Init, - dim79JoeKuoD5Init, - dim80JoeKuoD5Init, - dim81JoeKuoD5Init, - dim82JoeKuoD5Init, - dim83JoeKuoD5Init, - dim84JoeKuoD5Init, - dim85JoeKuoD5Init, - dim86JoeKuoD5Init, - dim87JoeKuoD5Init, - dim88JoeKuoD5Init, - dim89JoeKuoD5Init, - dim90JoeKuoD5Init, - dim91JoeKuoD5Init, - dim92JoeKuoD5Init, - dim93JoeKuoD5Init, - dim94JoeKuoD5Init, - dim95JoeKuoD5Init, - dim96JoeKuoD5Init, - dim97JoeKuoD5Init, - dim98JoeKuoD5Init, - dim99JoeKuoD5Init, - dim100JoeKuoD5Init, - dim101JoeKuoD5Init, - dim102JoeKuoD5Init, - dim103JoeKuoD5Init, - dim104JoeKuoD5Init, - dim105JoeKuoD5Init, - dim106JoeKuoD5Init, - dim107JoeKuoD5Init, - dim108JoeKuoD5Init, - dim109JoeKuoD5Init, - dim110JoeKuoD5Init, - dim111JoeKuoD5Init, - dim112JoeKuoD5Init, - dim113JoeKuoD5Init, - dim114JoeKuoD5Init, - dim115JoeKuoD5Init, - dim116JoeKuoD5Init, - dim117JoeKuoD5Init, - dim118JoeKuoD5Init, - dim119JoeKuoD5Init, - dim120JoeKuoD5Init, - dim121JoeKuoD5Init, - dim122JoeKuoD5Init, - dim123JoeKuoD5Init, - dim124JoeKuoD5Init, - dim125JoeKuoD5Init, - dim126JoeKuoD5Init, - dim127JoeKuoD5Init, - dim128JoeKuoD5Init, - dim129JoeKuoD5Init, - dim130JoeKuoD5Init, - dim131JoeKuoD5Init, - dim132JoeKuoD5Init, - dim133JoeKuoD5Init, - dim134JoeKuoD5Init, - dim135JoeKuoD5Init, - dim136JoeKuoD5Init, - dim137JoeKuoD5Init, - dim138JoeKuoD5Init, - dim139JoeKuoD5Init, - dim140JoeKuoD5Init, - dim141JoeKuoD5Init, - dim142JoeKuoD5Init, - dim143JoeKuoD5Init, - dim144JoeKuoD5Init, - dim145JoeKuoD5Init, - dim146JoeKuoD5Init, - dim147JoeKuoD5Init, - dim148JoeKuoD5Init, - dim149JoeKuoD5Init, - dim150JoeKuoD5Init, - dim151JoeKuoD5Init, - dim152JoeKuoD5Init, - dim153JoeKuoD5Init, - dim154JoeKuoD5Init, - dim155JoeKuoD5Init, - dim156JoeKuoD5Init, - dim157JoeKuoD5Init, - dim158JoeKuoD5Init, - dim159JoeKuoD5Init, - dim160JoeKuoD5Init, - dim161JoeKuoD5Init, - dim162JoeKuoD5Init, - dim163JoeKuoD5Init, - dim164JoeKuoD5Init, - dim165JoeKuoD5Init, - dim166JoeKuoD5Init, - dim167JoeKuoD5Init, - dim168JoeKuoD5Init, - dim169JoeKuoD5Init, - dim170JoeKuoD5Init, - dim171JoeKuoD5Init, - dim172JoeKuoD5Init, - dim173JoeKuoD5Init, - dim174JoeKuoD5Init, - dim175JoeKuoD5Init, - dim176JoeKuoD5Init, - dim177JoeKuoD5Init, - dim178JoeKuoD5Init, - dim179JoeKuoD5Init, - dim180JoeKuoD5Init, - dim181JoeKuoD5Init, - dim182JoeKuoD5Init, - dim183JoeKuoD5Init, - dim184JoeKuoD5Init, - dim185JoeKuoD5Init, - dim186JoeKuoD5Init, - dim187JoeKuoD5Init, - dim188JoeKuoD5Init, - dim189JoeKuoD5Init, - dim190JoeKuoD5Init, - dim191JoeKuoD5Init, - dim192JoeKuoD5Init, - dim193JoeKuoD5Init, - dim194JoeKuoD5Init, - dim195JoeKuoD5Init, - dim196JoeKuoD5Init, - dim197JoeKuoD5Init, - dim198JoeKuoD5Init, - dim199JoeKuoD5Init, - dim200JoeKuoD5Init, - dim201JoeKuoD5Init, - dim202JoeKuoD5Init, - dim203JoeKuoD5Init, - dim204JoeKuoD5Init, - dim205JoeKuoD5Init, - dim206JoeKuoD5Init, - dim207JoeKuoD5Init, - dim208JoeKuoD5Init, - dim209JoeKuoD5Init, - dim210JoeKuoD5Init, - dim211JoeKuoD5Init, - dim212JoeKuoD5Init, - dim213JoeKuoD5Init, - dim214JoeKuoD5Init, - dim215JoeKuoD5Init, - dim216JoeKuoD5Init, - dim217JoeKuoD5Init, - dim218JoeKuoD5Init, - dim219JoeKuoD5Init, - dim220JoeKuoD5Init, - dim221JoeKuoD5Init, - dim222JoeKuoD5Init, - dim223JoeKuoD5Init, - dim224JoeKuoD5Init, - dim225JoeKuoD5Init, - dim226JoeKuoD5Init, - dim227JoeKuoD5Init, - dim228JoeKuoD5Init, - dim229JoeKuoD5Init, - dim230JoeKuoD5Init, - dim231JoeKuoD5Init, - dim232JoeKuoD5Init, - dim233JoeKuoD5Init, - dim234JoeKuoD5Init, - dim235JoeKuoD5Init, - dim236JoeKuoD5Init, - dim237JoeKuoD5Init, - dim238JoeKuoD5Init, - dim239JoeKuoD5Init, - dim240JoeKuoD5Init, - dim241JoeKuoD5Init, - dim242JoeKuoD5Init, - dim243JoeKuoD5Init, - dim244JoeKuoD5Init, - dim245JoeKuoD5Init, - dim246JoeKuoD5Init, - dim247JoeKuoD5Init, - dim248JoeKuoD5Init, - dim249JoeKuoD5Init, - dim250JoeKuoD5Init, - dim251JoeKuoD5Init, - dim252JoeKuoD5Init, - dim253JoeKuoD5Init, - dim254JoeKuoD5Init, - dim255JoeKuoD5Init, - dim256JoeKuoD5Init, - dim257JoeKuoD5Init, - dim258JoeKuoD5Init, - dim259JoeKuoD5Init, - dim260JoeKuoD5Init, - dim261JoeKuoD5Init, - dim262JoeKuoD5Init, - dim263JoeKuoD5Init, - dim264JoeKuoD5Init, - dim265JoeKuoD5Init, - dim266JoeKuoD5Init, - dim267JoeKuoD5Init, - dim268JoeKuoD5Init, - dim269JoeKuoD5Init, - dim270JoeKuoD5Init, - dim271JoeKuoD5Init, - dim272JoeKuoD5Init, - dim273JoeKuoD5Init, - dim274JoeKuoD5Init, - dim275JoeKuoD5Init, - dim276JoeKuoD5Init, - dim277JoeKuoD5Init, - dim278JoeKuoD5Init, - dim279JoeKuoD5Init, - dim280JoeKuoD5Init, - dim281JoeKuoD5Init, - dim282JoeKuoD5Init, - dim283JoeKuoD5Init, - dim284JoeKuoD5Init, - dim285JoeKuoD5Init, - dim286JoeKuoD5Init, - dim287JoeKuoD5Init, - dim288JoeKuoD5Init, - dim289JoeKuoD5Init, - dim290JoeKuoD5Init, - dim291JoeKuoD5Init, - dim292JoeKuoD5Init, - dim293JoeKuoD5Init, - dim294JoeKuoD5Init, - dim295JoeKuoD5Init, - dim296JoeKuoD5Init, - dim297JoeKuoD5Init, - dim298JoeKuoD5Init, - dim299JoeKuoD5Init, - dim300JoeKuoD5Init, - dim301JoeKuoD5Init, - dim302JoeKuoD5Init, - dim303JoeKuoD5Init, - dim304JoeKuoD5Init, - dim305JoeKuoD5Init, - dim306JoeKuoD5Init, - dim307JoeKuoD5Init, - dim308JoeKuoD5Init, - dim309JoeKuoD5Init, - dim310JoeKuoD5Init, - dim311JoeKuoD5Init, - dim312JoeKuoD5Init, - dim313JoeKuoD5Init, - dim314JoeKuoD5Init, - dim315JoeKuoD5Init, - dim316JoeKuoD5Init, - dim317JoeKuoD5Init, - dim318JoeKuoD5Init, - dim319JoeKuoD5Init, - dim320JoeKuoD5Init, - dim321JoeKuoD5Init, - dim322JoeKuoD5Init, - dim323JoeKuoD5Init, - dim324JoeKuoD5Init, - dim325JoeKuoD5Init, - dim326JoeKuoD5Init, - dim327JoeKuoD5Init, - dim328JoeKuoD5Init, - dim329JoeKuoD5Init, - dim330JoeKuoD5Init, - dim331JoeKuoD5Init, - dim332JoeKuoD5Init, - dim333JoeKuoD5Init, - dim334JoeKuoD5Init, - dim335JoeKuoD5Init, - dim336JoeKuoD5Init, - dim337JoeKuoD5Init, - dim338JoeKuoD5Init, - dim339JoeKuoD5Init, - dim340JoeKuoD5Init, - dim341JoeKuoD5Init, - dim342JoeKuoD5Init, - dim343JoeKuoD5Init, - dim344JoeKuoD5Init, - dim345JoeKuoD5Init, - dim346JoeKuoD5Init, - dim347JoeKuoD5Init, - dim348JoeKuoD5Init, - dim349JoeKuoD5Init, - dim350JoeKuoD5Init, - dim351JoeKuoD5Init, - dim352JoeKuoD5Init, - dim353JoeKuoD5Init, - dim354JoeKuoD5Init, - dim355JoeKuoD5Init, - dim356JoeKuoD5Init, - dim357JoeKuoD5Init, - dim358JoeKuoD5Init, - dim359JoeKuoD5Init, - dim360JoeKuoD5Init, - dim361JoeKuoD5Init, - dim362JoeKuoD5Init, - dim363JoeKuoD5Init, - dim364JoeKuoD5Init, - dim365JoeKuoD5Init, - dim366JoeKuoD5Init, - dim367JoeKuoD5Init, - dim368JoeKuoD5Init, - dim369JoeKuoD5Init, - dim370JoeKuoD5Init, - dim371JoeKuoD5Init, - dim372JoeKuoD5Init, - dim373JoeKuoD5Init, - dim374JoeKuoD5Init, - dim375JoeKuoD5Init, - dim376JoeKuoD5Init, - dim377JoeKuoD5Init, - dim378JoeKuoD5Init, - dim379JoeKuoD5Init, - dim380JoeKuoD5Init, - dim381JoeKuoD5Init, - dim382JoeKuoD5Init, - dim383JoeKuoD5Init, - dim384JoeKuoD5Init, - dim385JoeKuoD5Init, - dim386JoeKuoD5Init, - dim387JoeKuoD5Init, - dim388JoeKuoD5Init, - dim389JoeKuoD5Init, - dim390JoeKuoD5Init, - dim391JoeKuoD5Init, - dim392JoeKuoD5Init, - dim393JoeKuoD5Init, - dim394JoeKuoD5Init, - dim395JoeKuoD5Init, - dim396JoeKuoD5Init, - dim397JoeKuoD5Init, - dim398JoeKuoD5Init, - dim399JoeKuoD5Init, - dim400JoeKuoD5Init, - dim401JoeKuoD5Init, - dim402JoeKuoD5Init, - dim403JoeKuoD5Init, - dim404JoeKuoD5Init, - dim405JoeKuoD5Init, - dim406JoeKuoD5Init, - dim407JoeKuoD5Init, - dim408JoeKuoD5Init, - dim409JoeKuoD5Init, - dim410JoeKuoD5Init, - dim411JoeKuoD5Init, - dim412JoeKuoD5Init, - dim413JoeKuoD5Init, - dim414JoeKuoD5Init, - dim415JoeKuoD5Init, - dim416JoeKuoD5Init, - dim417JoeKuoD5Init, - dim418JoeKuoD5Init, - dim419JoeKuoD5Init, - dim420JoeKuoD5Init, - dim421JoeKuoD5Init, - dim422JoeKuoD5Init, - dim423JoeKuoD5Init, - dim424JoeKuoD5Init, - dim425JoeKuoD5Init, - dim426JoeKuoD5Init, - dim427JoeKuoD5Init, - dim428JoeKuoD5Init, - dim429JoeKuoD5Init, - dim430JoeKuoD5Init, - dim431JoeKuoD5Init, - dim432JoeKuoD5Init, - dim433JoeKuoD5Init, - dim434JoeKuoD5Init, - dim435JoeKuoD5Init, - dim436JoeKuoD5Init, - dim437JoeKuoD5Init, - dim438JoeKuoD5Init, - dim439JoeKuoD5Init, - dim440JoeKuoD5Init, - dim441JoeKuoD5Init, - dim442JoeKuoD5Init, - dim443JoeKuoD5Init, - dim444JoeKuoD5Init, - dim445JoeKuoD5Init, - dim446JoeKuoD5Init, - dim447JoeKuoD5Init, - dim448JoeKuoD5Init, - dim449JoeKuoD5Init, - dim450JoeKuoD5Init, - dim451JoeKuoD5Init, - dim452JoeKuoD5Init, - dim453JoeKuoD5Init, - dim454JoeKuoD5Init, - dim455JoeKuoD5Init, - dim456JoeKuoD5Init, - dim457JoeKuoD5Init, - dim458JoeKuoD5Init, - dim459JoeKuoD5Init, - dim460JoeKuoD5Init, - dim461JoeKuoD5Init, - dim462JoeKuoD5Init, - dim463JoeKuoD5Init, - dim464JoeKuoD5Init, - dim465JoeKuoD5Init, - dim466JoeKuoD5Init, - dim467JoeKuoD5Init, - dim468JoeKuoD5Init, - dim469JoeKuoD5Init, - dim470JoeKuoD5Init, - dim471JoeKuoD5Init, - dim472JoeKuoD5Init, - dim473JoeKuoD5Init, - dim474JoeKuoD5Init, - dim475JoeKuoD5Init, - dim476JoeKuoD5Init, - dim477JoeKuoD5Init, - dim478JoeKuoD5Init, - dim479JoeKuoD5Init, - dim480JoeKuoD5Init, - dim481JoeKuoD5Init, - dim482JoeKuoD5Init, - dim483JoeKuoD5Init, - dim484JoeKuoD5Init, - dim485JoeKuoD5Init, - dim486JoeKuoD5Init, - dim487JoeKuoD5Init, - dim488JoeKuoD5Init, - dim489JoeKuoD5Init, - dim490JoeKuoD5Init, - dim491JoeKuoD5Init, - dim492JoeKuoD5Init, - dim493JoeKuoD5Init, - dim494JoeKuoD5Init, - dim495JoeKuoD5Init, - dim496JoeKuoD5Init, - dim497JoeKuoD5Init, - dim498JoeKuoD5Init, - dim499JoeKuoD5Init, - dim500JoeKuoD5Init, - dim501JoeKuoD5Init, - dim502JoeKuoD5Init, - dim503JoeKuoD5Init, - dim504JoeKuoD5Init, - dim505JoeKuoD5Init, - dim506JoeKuoD5Init, - dim507JoeKuoD5Init, - dim508JoeKuoD5Init, - dim509JoeKuoD5Init, - dim510JoeKuoD5Init, - dim511JoeKuoD5Init, - dim512JoeKuoD5Init, - dim513JoeKuoD5Init, - dim514JoeKuoD5Init, - dim515JoeKuoD5Init, - dim516JoeKuoD5Init, - dim517JoeKuoD5Init, - dim518JoeKuoD5Init, - dim519JoeKuoD5Init, - dim520JoeKuoD5Init, - dim521JoeKuoD5Init, - dim522JoeKuoD5Init, - dim523JoeKuoD5Init, - dim524JoeKuoD5Init, - dim525JoeKuoD5Init, - dim526JoeKuoD5Init, - dim527JoeKuoD5Init, - dim528JoeKuoD5Init, - dim529JoeKuoD5Init, - dim530JoeKuoD5Init, - dim531JoeKuoD5Init, - dim532JoeKuoD5Init, - dim533JoeKuoD5Init, - dim534JoeKuoD5Init, - dim535JoeKuoD5Init, - dim536JoeKuoD5Init, - dim537JoeKuoD5Init, - dim538JoeKuoD5Init, - dim539JoeKuoD5Init, - dim540JoeKuoD5Init, - dim541JoeKuoD5Init, - dim542JoeKuoD5Init, - dim543JoeKuoD5Init, - dim544JoeKuoD5Init, - dim545JoeKuoD5Init, - dim546JoeKuoD5Init, - dim547JoeKuoD5Init, - dim548JoeKuoD5Init, - dim549JoeKuoD5Init, - dim550JoeKuoD5Init, - dim551JoeKuoD5Init, - dim552JoeKuoD5Init, - dim553JoeKuoD5Init, - dim554JoeKuoD5Init, - dim555JoeKuoD5Init, - dim556JoeKuoD5Init, - dim557JoeKuoD5Init, - dim558JoeKuoD5Init, - dim559JoeKuoD5Init, - dim560JoeKuoD5Init, - dim561JoeKuoD5Init, - dim562JoeKuoD5Init, - dim563JoeKuoD5Init, - dim564JoeKuoD5Init, - dim565JoeKuoD5Init, - dim566JoeKuoD5Init, - dim567JoeKuoD5Init, - dim568JoeKuoD5Init, - dim569JoeKuoD5Init, - dim570JoeKuoD5Init, - dim571JoeKuoD5Init, - dim572JoeKuoD5Init, - dim573JoeKuoD5Init, - dim574JoeKuoD5Init, - dim575JoeKuoD5Init, - dim576JoeKuoD5Init, - dim577JoeKuoD5Init, - dim578JoeKuoD5Init, - dim579JoeKuoD5Init, - dim580JoeKuoD5Init, - dim581JoeKuoD5Init, - dim582JoeKuoD5Init, - dim583JoeKuoD5Init, - dim584JoeKuoD5Init, - dim585JoeKuoD5Init, - dim586JoeKuoD5Init, - dim587JoeKuoD5Init, - dim588JoeKuoD5Init, - dim589JoeKuoD5Init, - dim590JoeKuoD5Init, - dim591JoeKuoD5Init, - dim592JoeKuoD5Init, - dim593JoeKuoD5Init, - dim594JoeKuoD5Init, - dim595JoeKuoD5Init, - dim596JoeKuoD5Init, - dim597JoeKuoD5Init, - dim598JoeKuoD5Init, - dim599JoeKuoD5Init, - dim600JoeKuoD5Init, - dim601JoeKuoD5Init, - dim602JoeKuoD5Init, - dim603JoeKuoD5Init, - dim604JoeKuoD5Init, - dim605JoeKuoD5Init, - dim606JoeKuoD5Init, - dim607JoeKuoD5Init, - dim608JoeKuoD5Init, - dim609JoeKuoD5Init, - dim610JoeKuoD5Init, - dim611JoeKuoD5Init, - dim612JoeKuoD5Init, - dim613JoeKuoD5Init, - dim614JoeKuoD5Init, - dim615JoeKuoD5Init, - dim616JoeKuoD5Init, - dim617JoeKuoD5Init, - dim618JoeKuoD5Init, - dim619JoeKuoD5Init, - dim620JoeKuoD5Init, - dim621JoeKuoD5Init, - dim622JoeKuoD5Init, - dim623JoeKuoD5Init, - dim624JoeKuoD5Init, - dim625JoeKuoD5Init, - dim626JoeKuoD5Init, - dim627JoeKuoD5Init, - dim628JoeKuoD5Init, - dim629JoeKuoD5Init, - dim630JoeKuoD5Init, - dim631JoeKuoD5Init, - dim632JoeKuoD5Init, - dim633JoeKuoD5Init, - dim634JoeKuoD5Init, - dim635JoeKuoD5Init, - dim636JoeKuoD5Init, - dim637JoeKuoD5Init, - dim638JoeKuoD5Init, - dim639JoeKuoD5Init, - dim640JoeKuoD5Init, - dim641JoeKuoD5Init, - dim642JoeKuoD5Init, - dim643JoeKuoD5Init, - dim644JoeKuoD5Init, - dim645JoeKuoD5Init, - dim646JoeKuoD5Init, - dim647JoeKuoD5Init, - dim648JoeKuoD5Init, - dim649JoeKuoD5Init, - dim650JoeKuoD5Init, - dim651JoeKuoD5Init, - dim652JoeKuoD5Init, - dim653JoeKuoD5Init, - dim654JoeKuoD5Init, - dim655JoeKuoD5Init, - dim656JoeKuoD5Init, - dim657JoeKuoD5Init, - dim658JoeKuoD5Init, - dim659JoeKuoD5Init, - dim660JoeKuoD5Init, - dim661JoeKuoD5Init, - dim662JoeKuoD5Init, - dim663JoeKuoD5Init, - dim664JoeKuoD5Init, - dim665JoeKuoD5Init, - dim666JoeKuoD5Init, - dim667JoeKuoD5Init, - dim668JoeKuoD5Init, - dim669JoeKuoD5Init, - dim670JoeKuoD5Init, - dim671JoeKuoD5Init, - dim672JoeKuoD5Init, - dim673JoeKuoD5Init, - dim674JoeKuoD5Init, - dim675JoeKuoD5Init, - dim676JoeKuoD5Init, - dim677JoeKuoD5Init, - dim678JoeKuoD5Init, - dim679JoeKuoD5Init, - dim680JoeKuoD5Init, - dim681JoeKuoD5Init, - dim682JoeKuoD5Init, - dim683JoeKuoD5Init, - dim684JoeKuoD5Init, - dim685JoeKuoD5Init, - dim686JoeKuoD5Init, - dim687JoeKuoD5Init, - dim688JoeKuoD5Init, - dim689JoeKuoD5Init, - dim690JoeKuoD5Init, - dim691JoeKuoD5Init, - dim692JoeKuoD5Init, - dim693JoeKuoD5Init, - dim694JoeKuoD5Init, - dim695JoeKuoD5Init, - dim696JoeKuoD5Init, - dim697JoeKuoD5Init, - dim698JoeKuoD5Init, - dim699JoeKuoD5Init, - dim700JoeKuoD5Init, - dim701JoeKuoD5Init, - dim702JoeKuoD5Init, - dim703JoeKuoD5Init, - dim704JoeKuoD5Init, - dim705JoeKuoD5Init, - dim706JoeKuoD5Init, - dim707JoeKuoD5Init, - dim708JoeKuoD5Init, - dim709JoeKuoD5Init, - dim710JoeKuoD5Init, - dim711JoeKuoD5Init, - dim712JoeKuoD5Init, - dim713JoeKuoD5Init, - dim714JoeKuoD5Init, - dim715JoeKuoD5Init, - dim716JoeKuoD5Init, - dim717JoeKuoD5Init, - dim718JoeKuoD5Init, - dim719JoeKuoD5Init, - dim720JoeKuoD5Init, - dim721JoeKuoD5Init, - dim722JoeKuoD5Init, - dim723JoeKuoD5Init, - dim724JoeKuoD5Init, - dim725JoeKuoD5Init, - dim726JoeKuoD5Init, - dim727JoeKuoD5Init, - dim728JoeKuoD5Init, - dim729JoeKuoD5Init, - dim730JoeKuoD5Init, - dim731JoeKuoD5Init, - dim732JoeKuoD5Init, - dim733JoeKuoD5Init, - dim734JoeKuoD5Init, - dim735JoeKuoD5Init, - dim736JoeKuoD5Init, - dim737JoeKuoD5Init, - dim738JoeKuoD5Init, - dim739JoeKuoD5Init, - dim740JoeKuoD5Init, - dim741JoeKuoD5Init, - dim742JoeKuoD5Init, - dim743JoeKuoD5Init, - dim744JoeKuoD5Init, - dim745JoeKuoD5Init, - dim746JoeKuoD5Init, - dim747JoeKuoD5Init, - dim748JoeKuoD5Init, - dim749JoeKuoD5Init, - dim750JoeKuoD5Init, - dim751JoeKuoD5Init, - dim752JoeKuoD5Init, - dim753JoeKuoD5Init, - dim754JoeKuoD5Init, - dim755JoeKuoD5Init, - dim756JoeKuoD5Init, - dim757JoeKuoD5Init, - dim758JoeKuoD5Init, - dim759JoeKuoD5Init, - dim760JoeKuoD5Init, - dim761JoeKuoD5Init, - dim762JoeKuoD5Init, - dim763JoeKuoD5Init, - dim764JoeKuoD5Init, - dim765JoeKuoD5Init, - dim766JoeKuoD5Init, - dim767JoeKuoD5Init, - dim768JoeKuoD5Init, - dim769JoeKuoD5Init, - dim770JoeKuoD5Init, - dim771JoeKuoD5Init, - dim772JoeKuoD5Init, - dim773JoeKuoD5Init, - dim774JoeKuoD5Init, - dim775JoeKuoD5Init, - dim776JoeKuoD5Init, - dim777JoeKuoD5Init, - dim778JoeKuoD5Init, - dim779JoeKuoD5Init, - dim780JoeKuoD5Init, - dim781JoeKuoD5Init, - dim782JoeKuoD5Init, - dim783JoeKuoD5Init, - dim784JoeKuoD5Init, - dim785JoeKuoD5Init, - dim786JoeKuoD5Init, - dim787JoeKuoD5Init, - dim788JoeKuoD5Init, - dim789JoeKuoD5Init, - dim790JoeKuoD5Init, - dim791JoeKuoD5Init, - dim792JoeKuoD5Init, - dim793JoeKuoD5Init, - dim794JoeKuoD5Init, - dim795JoeKuoD5Init, - dim796JoeKuoD5Init, - dim797JoeKuoD5Init, - dim798JoeKuoD5Init, - dim799JoeKuoD5Init, - dim800JoeKuoD5Init, - dim801JoeKuoD5Init, - dim802JoeKuoD5Init, - dim803JoeKuoD5Init, - dim804JoeKuoD5Init, - dim805JoeKuoD5Init, - dim806JoeKuoD5Init, - dim807JoeKuoD5Init, - dim808JoeKuoD5Init, - dim809JoeKuoD5Init, - dim810JoeKuoD5Init, - dim811JoeKuoD5Init, - dim812JoeKuoD5Init, - dim813JoeKuoD5Init, - dim814JoeKuoD5Init, - dim815JoeKuoD5Init, - dim816JoeKuoD5Init, - dim817JoeKuoD5Init, - dim818JoeKuoD5Init, - dim819JoeKuoD5Init, - dim820JoeKuoD5Init, - dim821JoeKuoD5Init, - dim822JoeKuoD5Init, - dim823JoeKuoD5Init, - dim824JoeKuoD5Init, - dim825JoeKuoD5Init, - dim826JoeKuoD5Init, - dim827JoeKuoD5Init, - dim828JoeKuoD5Init, - dim829JoeKuoD5Init, - dim830JoeKuoD5Init, - dim831JoeKuoD5Init, - dim832JoeKuoD5Init, - dim833JoeKuoD5Init, - dim834JoeKuoD5Init, - dim835JoeKuoD5Init, - dim836JoeKuoD5Init, - dim837JoeKuoD5Init, - dim838JoeKuoD5Init, - dim839JoeKuoD5Init, - dim840JoeKuoD5Init, - dim841JoeKuoD5Init, - dim842JoeKuoD5Init, - dim843JoeKuoD5Init, - dim844JoeKuoD5Init, - dim845JoeKuoD5Init, - dim846JoeKuoD5Init, - dim847JoeKuoD5Init, - dim848JoeKuoD5Init, - dim849JoeKuoD5Init, - dim850JoeKuoD5Init, - dim851JoeKuoD5Init, - dim852JoeKuoD5Init, - dim853JoeKuoD5Init, - dim854JoeKuoD5Init, - dim855JoeKuoD5Init, - dim856JoeKuoD5Init, - dim857JoeKuoD5Init, - dim858JoeKuoD5Init, - dim859JoeKuoD5Init, - dim860JoeKuoD5Init, - dim861JoeKuoD5Init, - dim862JoeKuoD5Init, - dim863JoeKuoD5Init, - dim864JoeKuoD5Init, - dim865JoeKuoD5Init, - dim866JoeKuoD5Init, - dim867JoeKuoD5Init, - dim868JoeKuoD5Init, - dim869JoeKuoD5Init, - dim870JoeKuoD5Init, - dim871JoeKuoD5Init, - dim872JoeKuoD5Init, - dim873JoeKuoD5Init, - dim874JoeKuoD5Init, - dim875JoeKuoD5Init, - dim876JoeKuoD5Init, - dim877JoeKuoD5Init, - dim878JoeKuoD5Init, - dim879JoeKuoD5Init, - dim880JoeKuoD5Init, - dim881JoeKuoD5Init, - dim882JoeKuoD5Init, - dim883JoeKuoD5Init, - dim884JoeKuoD5Init, - dim885JoeKuoD5Init, - dim886JoeKuoD5Init, - dim887JoeKuoD5Init, - dim888JoeKuoD5Init, - dim889JoeKuoD5Init, - dim890JoeKuoD5Init, - dim891JoeKuoD5Init, - dim892JoeKuoD5Init, - dim893JoeKuoD5Init, - dim894JoeKuoD5Init, - dim895JoeKuoD5Init, - dim896JoeKuoD5Init, - dim897JoeKuoD5Init, - dim898JoeKuoD5Init, - dim899JoeKuoD5Init, - dim900JoeKuoD5Init, - dim901JoeKuoD5Init, - dim902JoeKuoD5Init, - dim903JoeKuoD5Init, - dim904JoeKuoD5Init, - dim905JoeKuoD5Init, - dim906JoeKuoD5Init, - dim907JoeKuoD5Init, - dim908JoeKuoD5Init, - dim909JoeKuoD5Init, - dim910JoeKuoD5Init, - dim911JoeKuoD5Init, - dim912JoeKuoD5Init, - dim913JoeKuoD5Init, - dim914JoeKuoD5Init, - dim915JoeKuoD5Init, - dim916JoeKuoD5Init, - dim917JoeKuoD5Init, - dim918JoeKuoD5Init, - dim919JoeKuoD5Init, - dim920JoeKuoD5Init, - dim921JoeKuoD5Init, - dim922JoeKuoD5Init, - dim923JoeKuoD5Init, - dim924JoeKuoD5Init, - dim925JoeKuoD5Init, - dim926JoeKuoD5Init, - dim927JoeKuoD5Init, - dim928JoeKuoD5Init, - dim929JoeKuoD5Init, - dim930JoeKuoD5Init, - dim931JoeKuoD5Init, - dim932JoeKuoD5Init, - dim933JoeKuoD5Init, - dim934JoeKuoD5Init, - dim935JoeKuoD5Init, - dim936JoeKuoD5Init, - dim937JoeKuoD5Init, - dim938JoeKuoD5Init, - dim939JoeKuoD5Init, - dim940JoeKuoD5Init, - dim941JoeKuoD5Init, - dim942JoeKuoD5Init, - dim943JoeKuoD5Init, - dim944JoeKuoD5Init, - dim945JoeKuoD5Init, - dim946JoeKuoD5Init, - dim947JoeKuoD5Init, - dim948JoeKuoD5Init, - dim949JoeKuoD5Init, - dim950JoeKuoD5Init, - dim951JoeKuoD5Init, - dim952JoeKuoD5Init, - dim953JoeKuoD5Init, - dim954JoeKuoD5Init, - dim955JoeKuoD5Init, - dim956JoeKuoD5Init, - dim957JoeKuoD5Init, - dim958JoeKuoD5Init, - dim959JoeKuoD5Init, - dim960JoeKuoD5Init, - dim961JoeKuoD5Init, - dim962JoeKuoD5Init, - dim963JoeKuoD5Init, - dim964JoeKuoD5Init, - dim965JoeKuoD5Init, - dim966JoeKuoD5Init, - dim967JoeKuoD5Init, - dim968JoeKuoD5Init, - dim969JoeKuoD5Init, - dim970JoeKuoD5Init, - dim971JoeKuoD5Init, - dim972JoeKuoD5Init, - dim973JoeKuoD5Init, - dim974JoeKuoD5Init, - dim975JoeKuoD5Init, - dim976JoeKuoD5Init, - dim977JoeKuoD5Init, - dim978JoeKuoD5Init, - dim979JoeKuoD5Init, - dim980JoeKuoD5Init, - dim981JoeKuoD5Init, - dim982JoeKuoD5Init, - dim983JoeKuoD5Init, - dim984JoeKuoD5Init, - dim985JoeKuoD5Init, - dim986JoeKuoD5Init, - dim987JoeKuoD5Init, - dim988JoeKuoD5Init, - dim989JoeKuoD5Init, - dim990JoeKuoD5Init, - dim991JoeKuoD5Init, - dim992JoeKuoD5Init, - dim993JoeKuoD5Init, - dim994JoeKuoD5Init, - dim995JoeKuoD5Init, - dim996JoeKuoD5Init, - dim997JoeKuoD5Init, - dim998JoeKuoD5Init, - dim999JoeKuoD5Init, - dim1000JoeKuoD5Init, - dim1001JoeKuoD5Init, - dim1002JoeKuoD5Init, - dim1003JoeKuoD5Init, - dim1004JoeKuoD5Init, - dim1005JoeKuoD5Init, - dim1006JoeKuoD5Init, - dim1007JoeKuoD5Init, - dim1008JoeKuoD5Init, - dim1009JoeKuoD5Init, - dim1010JoeKuoD5Init, - dim1011JoeKuoD5Init, - dim1012JoeKuoD5Init, - dim1013JoeKuoD5Init, - dim1014JoeKuoD5Init, - dim1015JoeKuoD5Init, - dim1016JoeKuoD5Init, - dim1017JoeKuoD5Init, - dim1018JoeKuoD5Init, - dim1019JoeKuoD5Init, - dim1020JoeKuoD5Init, - dim1021JoeKuoD5Init, - dim1022JoeKuoD5Init, - dim1023JoeKuoD5Init, - dim1024JoeKuoD5Init, - dim1025JoeKuoD5Init, - dim1026JoeKuoD5Init, - dim1027JoeKuoD5Init, - dim1028JoeKuoD5Init, - dim1029JoeKuoD5Init, - dim1030JoeKuoD5Init, - dim1031JoeKuoD5Init, - dim1032JoeKuoD5Init, - dim1033JoeKuoD5Init, - dim1034JoeKuoD5Init, - dim1035JoeKuoD5Init, - dim1036JoeKuoD5Init, - dim1037JoeKuoD5Init, - dim1038JoeKuoD5Init, - dim1039JoeKuoD5Init, - dim1040JoeKuoD5Init, - dim1041JoeKuoD5Init, - dim1042JoeKuoD5Init, - dim1043JoeKuoD5Init, - dim1044JoeKuoD5Init, - dim1045JoeKuoD5Init, - dim1046JoeKuoD5Init, - dim1047JoeKuoD5Init, - dim1048JoeKuoD5Init, - dim1049JoeKuoD5Init, - dim1050JoeKuoD5Init, - dim1051JoeKuoD5Init, - dim1052JoeKuoD5Init, - dim1053JoeKuoD5Init, - dim1054JoeKuoD5Init, - dim1055JoeKuoD5Init, - dim1056JoeKuoD5Init, - dim1057JoeKuoD5Init, - dim1058JoeKuoD5Init, - dim1059JoeKuoD5Init, - dim1060JoeKuoD5Init, - dim1061JoeKuoD5Init, - dim1062JoeKuoD5Init, - dim1063JoeKuoD5Init, - dim1064JoeKuoD5Init, - dim1065JoeKuoD5Init, - dim1066JoeKuoD5Init, - dim1067JoeKuoD5Init, - dim1068JoeKuoD5Init, - dim1069JoeKuoD5Init, - dim1070JoeKuoD5Init, - dim1071JoeKuoD5Init, - dim1072JoeKuoD5Init, - dim1073JoeKuoD5Init, - dim1074JoeKuoD5Init, - dim1075JoeKuoD5Init, - dim1076JoeKuoD5Init, - dim1077JoeKuoD5Init, - dim1078JoeKuoD5Init, - dim1079JoeKuoD5Init, - dim1080JoeKuoD5Init, - dim1081JoeKuoD5Init, - dim1082JoeKuoD5Init, - dim1083JoeKuoD5Init, - dim1084JoeKuoD5Init, - dim1085JoeKuoD5Init, - dim1086JoeKuoD5Init, - dim1087JoeKuoD5Init, - dim1088JoeKuoD5Init, - dim1089JoeKuoD5Init, - dim1090JoeKuoD5Init, - dim1091JoeKuoD5Init, - dim1092JoeKuoD5Init, - dim1093JoeKuoD5Init, - dim1094JoeKuoD5Init, - dim1095JoeKuoD5Init, - dim1096JoeKuoD5Init, - dim1097JoeKuoD5Init, - dim1098JoeKuoD5Init, - dim1099JoeKuoD5Init, - dim1100JoeKuoD5Init, - dim1101JoeKuoD5Init, - dim1102JoeKuoD5Init, - dim1103JoeKuoD5Init, - dim1104JoeKuoD5Init, - dim1105JoeKuoD5Init, - dim1106JoeKuoD5Init, - dim1107JoeKuoD5Init, - dim1108JoeKuoD5Init, - dim1109JoeKuoD5Init, - dim1110JoeKuoD5Init, - dim1111JoeKuoD5Init, - dim1112JoeKuoD5Init, - dim1113JoeKuoD5Init, - dim1114JoeKuoD5Init, - dim1115JoeKuoD5Init, - dim1116JoeKuoD5Init, - dim1117JoeKuoD5Init, - dim1118JoeKuoD5Init, - dim1119JoeKuoD5Init, - dim1120JoeKuoD5Init, - dim1121JoeKuoD5Init, - dim1122JoeKuoD5Init, - dim1123JoeKuoD5Init, - dim1124JoeKuoD5Init, - dim1125JoeKuoD5Init, - dim1126JoeKuoD5Init, - dim1127JoeKuoD5Init, - dim1128JoeKuoD5Init, - dim1129JoeKuoD5Init, - dim1130JoeKuoD5Init, - dim1131JoeKuoD5Init, - dim1132JoeKuoD5Init, - dim1133JoeKuoD5Init, - dim1134JoeKuoD5Init, - dim1135JoeKuoD5Init, - dim1136JoeKuoD5Init, - dim1137JoeKuoD5Init, - dim1138JoeKuoD5Init, - dim1139JoeKuoD5Init, - dim1140JoeKuoD5Init, - dim1141JoeKuoD5Init, - dim1142JoeKuoD5Init, - dim1143JoeKuoD5Init, - dim1144JoeKuoD5Init, - dim1145JoeKuoD5Init, - dim1146JoeKuoD5Init, - dim1147JoeKuoD5Init, - dim1148JoeKuoD5Init, - dim1149JoeKuoD5Init, - dim1150JoeKuoD5Init, - dim1151JoeKuoD5Init, - dim1152JoeKuoD5Init, - dim1153JoeKuoD5Init, - dim1154JoeKuoD5Init, - dim1155JoeKuoD5Init, - dim1156JoeKuoD5Init, - dim1157JoeKuoD5Init, - dim1158JoeKuoD5Init, - dim1159JoeKuoD5Init, - dim1160JoeKuoD5Init, - dim1161JoeKuoD5Init, - dim1162JoeKuoD5Init, - dim1163JoeKuoD5Init, - dim1164JoeKuoD5Init, - dim1165JoeKuoD5Init, - dim1166JoeKuoD5Init, - dim1167JoeKuoD5Init, - dim1168JoeKuoD5Init, - dim1169JoeKuoD5Init, - dim1170JoeKuoD5Init, - dim1171JoeKuoD5Init, - dim1172JoeKuoD5Init, - dim1173JoeKuoD5Init, - dim1174JoeKuoD5Init, - dim1175JoeKuoD5Init, - dim1176JoeKuoD5Init, - dim1177JoeKuoD5Init, - dim1178JoeKuoD5Init, - dim1179JoeKuoD5Init, - dim1180JoeKuoD5Init, - dim1181JoeKuoD5Init, - dim1182JoeKuoD5Init, - dim1183JoeKuoD5Init, - dim1184JoeKuoD5Init, - dim1185JoeKuoD5Init, - dim1186JoeKuoD5Init, - dim1187JoeKuoD5Init, - dim1188JoeKuoD5Init, - dim1189JoeKuoD5Init, - dim1190JoeKuoD5Init, - dim1191JoeKuoD5Init, - dim1192JoeKuoD5Init, - dim1193JoeKuoD5Init, - dim1194JoeKuoD5Init, - dim1195JoeKuoD5Init, - dim1196JoeKuoD5Init, - dim1197JoeKuoD5Init, - dim1198JoeKuoD5Init, - dim1199JoeKuoD5Init, - dim1200JoeKuoD5Init, - dim1201JoeKuoD5Init, - dim1202JoeKuoD5Init, - dim1203JoeKuoD5Init, - dim1204JoeKuoD5Init, - dim1205JoeKuoD5Init, - dim1206JoeKuoD5Init, - dim1207JoeKuoD5Init, - dim1208JoeKuoD5Init, - dim1209JoeKuoD5Init, - dim1210JoeKuoD5Init, - dim1211JoeKuoD5Init, - dim1212JoeKuoD5Init, - dim1213JoeKuoD5Init, - dim1214JoeKuoD5Init, - dim1215JoeKuoD5Init, - dim1216JoeKuoD5Init, - dim1217JoeKuoD5Init, - dim1218JoeKuoD5Init, - dim1219JoeKuoD5Init, - dim1220JoeKuoD5Init, - dim1221JoeKuoD5Init, - dim1222JoeKuoD5Init, - dim1223JoeKuoD5Init, - dim1224JoeKuoD5Init, - dim1225JoeKuoD5Init, - dim1226JoeKuoD5Init, - dim1227JoeKuoD5Init, - dim1228JoeKuoD5Init, - dim1229JoeKuoD5Init, - dim1230JoeKuoD5Init, - dim1231JoeKuoD5Init, - dim1232JoeKuoD5Init, - dim1233JoeKuoD5Init, - dim1234JoeKuoD5Init, - dim1235JoeKuoD5Init, - dim1236JoeKuoD5Init, - dim1237JoeKuoD5Init, - dim1238JoeKuoD5Init, - dim1239JoeKuoD5Init, - dim1240JoeKuoD5Init, - dim1241JoeKuoD5Init, - dim1242JoeKuoD5Init, - dim1243JoeKuoD5Init, - dim1244JoeKuoD5Init, - dim1245JoeKuoD5Init, - dim1246JoeKuoD5Init, - dim1247JoeKuoD5Init, - dim1248JoeKuoD5Init, - dim1249JoeKuoD5Init, - dim1250JoeKuoD5Init, - dim1251JoeKuoD5Init, - dim1252JoeKuoD5Init, - dim1253JoeKuoD5Init, - dim1254JoeKuoD5Init, - dim1255JoeKuoD5Init, - dim1256JoeKuoD5Init, - dim1257JoeKuoD5Init, - dim1258JoeKuoD5Init, - dim1259JoeKuoD5Init, - dim1260JoeKuoD5Init, - dim1261JoeKuoD5Init, - dim1262JoeKuoD5Init, - dim1263JoeKuoD5Init, - dim1264JoeKuoD5Init, - dim1265JoeKuoD5Init, - dim1266JoeKuoD5Init, - dim1267JoeKuoD5Init, - dim1268JoeKuoD5Init, - dim1269JoeKuoD5Init, - dim1270JoeKuoD5Init, - dim1271JoeKuoD5Init, - dim1272JoeKuoD5Init, - dim1273JoeKuoD5Init, - dim1274JoeKuoD5Init, - dim1275JoeKuoD5Init, - dim1276JoeKuoD5Init, - dim1277JoeKuoD5Init, - dim1278JoeKuoD5Init, - dim1279JoeKuoD5Init, - dim1280JoeKuoD5Init, - dim1281JoeKuoD5Init, - dim1282JoeKuoD5Init, - dim1283JoeKuoD5Init, - dim1284JoeKuoD5Init, - dim1285JoeKuoD5Init, - dim1286JoeKuoD5Init, - dim1287JoeKuoD5Init, - dim1288JoeKuoD5Init, - dim1289JoeKuoD5Init, - dim1290JoeKuoD5Init, - dim1291JoeKuoD5Init, - dim1292JoeKuoD5Init, - dim1293JoeKuoD5Init, - dim1294JoeKuoD5Init, - dim1295JoeKuoD5Init, - dim1296JoeKuoD5Init, - dim1297JoeKuoD5Init, - dim1298JoeKuoD5Init, - dim1299JoeKuoD5Init, - dim1300JoeKuoD5Init, - dim1301JoeKuoD5Init, - dim1302JoeKuoD5Init, - dim1303JoeKuoD5Init, - dim1304JoeKuoD5Init, - dim1305JoeKuoD5Init, - dim1306JoeKuoD5Init, - dim1307JoeKuoD5Init, - dim1308JoeKuoD5Init, - dim1309JoeKuoD5Init, - dim1310JoeKuoD5Init, - dim1311JoeKuoD5Init, - dim1312JoeKuoD5Init, - dim1313JoeKuoD5Init, - dim1314JoeKuoD5Init, - dim1315JoeKuoD5Init, - dim1316JoeKuoD5Init, - dim1317JoeKuoD5Init, - dim1318JoeKuoD5Init, - dim1319JoeKuoD5Init, - dim1320JoeKuoD5Init, - dim1321JoeKuoD5Init, - dim1322JoeKuoD5Init, - dim1323JoeKuoD5Init, - dim1324JoeKuoD5Init, - dim1325JoeKuoD5Init, - dim1326JoeKuoD5Init, - dim1327JoeKuoD5Init, - dim1328JoeKuoD5Init, - dim1329JoeKuoD5Init, - dim1330JoeKuoD5Init, - dim1331JoeKuoD5Init, - dim1332JoeKuoD5Init, - dim1333JoeKuoD5Init, - dim1334JoeKuoD5Init, - dim1335JoeKuoD5Init, - dim1336JoeKuoD5Init, - dim1337JoeKuoD5Init, - dim1338JoeKuoD5Init, - dim1339JoeKuoD5Init, - dim1340JoeKuoD5Init, - dim1341JoeKuoD5Init, - dim1342JoeKuoD5Init, - dim1343JoeKuoD5Init, - dim1344JoeKuoD5Init, - dim1345JoeKuoD5Init, - dim1346JoeKuoD5Init, - dim1347JoeKuoD5Init, - dim1348JoeKuoD5Init, - dim1349JoeKuoD5Init, - dim1350JoeKuoD5Init, - dim1351JoeKuoD5Init, - dim1352JoeKuoD5Init, - dim1353JoeKuoD5Init, - dim1354JoeKuoD5Init, - dim1355JoeKuoD5Init, - dim1356JoeKuoD5Init, - dim1357JoeKuoD5Init, - dim1358JoeKuoD5Init, - dim1359JoeKuoD5Init, - dim1360JoeKuoD5Init, - dim1361JoeKuoD5Init, - dim1362JoeKuoD5Init, - dim1363JoeKuoD5Init, - dim1364JoeKuoD5Init, - dim1365JoeKuoD5Init, - dim1366JoeKuoD5Init, - dim1367JoeKuoD5Init, - dim1368JoeKuoD5Init, - dim1369JoeKuoD5Init, - dim1370JoeKuoD5Init, - dim1371JoeKuoD5Init, - dim1372JoeKuoD5Init, - dim1373JoeKuoD5Init, - dim1374JoeKuoD5Init, - dim1375JoeKuoD5Init, - dim1376JoeKuoD5Init, - dim1377JoeKuoD5Init, - dim1378JoeKuoD5Init, - dim1379JoeKuoD5Init, - dim1380JoeKuoD5Init, - dim1381JoeKuoD5Init, - dim1382JoeKuoD5Init, - dim1383JoeKuoD5Init, - dim1384JoeKuoD5Init, - dim1385JoeKuoD5Init, - dim1386JoeKuoD5Init, - dim1387JoeKuoD5Init, - dim1388JoeKuoD5Init, - dim1389JoeKuoD5Init, - dim1390JoeKuoD5Init, - dim1391JoeKuoD5Init, - dim1392JoeKuoD5Init, - dim1393JoeKuoD5Init, - dim1394JoeKuoD5Init, - dim1395JoeKuoD5Init, - dim1396JoeKuoD5Init, - dim1397JoeKuoD5Init, - dim1398JoeKuoD5Init, - dim1399JoeKuoD5Init, - dim1400JoeKuoD5Init, - dim1401JoeKuoD5Init, - dim1402JoeKuoD5Init, - dim1403JoeKuoD5Init, - dim1404JoeKuoD5Init, - dim1405JoeKuoD5Init, - dim1406JoeKuoD5Init, - dim1407JoeKuoD5Init, - dim1408JoeKuoD5Init, - dim1409JoeKuoD5Init, - dim1410JoeKuoD5Init, - dim1411JoeKuoD5Init, - dim1412JoeKuoD5Init, - dim1413JoeKuoD5Init, - dim1414JoeKuoD5Init, - dim1415JoeKuoD5Init, - dim1416JoeKuoD5Init, - dim1417JoeKuoD5Init, - dim1418JoeKuoD5Init, - dim1419JoeKuoD5Init, - dim1420JoeKuoD5Init, - dim1421JoeKuoD5Init, - dim1422JoeKuoD5Init, - dim1423JoeKuoD5Init, - dim1424JoeKuoD5Init, - dim1425JoeKuoD5Init, - dim1426JoeKuoD5Init, - dim1427JoeKuoD5Init, - dim1428JoeKuoD5Init, - dim1429JoeKuoD5Init, - dim1430JoeKuoD5Init, - dim1431JoeKuoD5Init, - dim1432JoeKuoD5Init, - dim1433JoeKuoD5Init, - dim1434JoeKuoD5Init, - dim1435JoeKuoD5Init, - dim1436JoeKuoD5Init, - dim1437JoeKuoD5Init, - dim1438JoeKuoD5Init, - dim1439JoeKuoD5Init, - dim1440JoeKuoD5Init, - dim1441JoeKuoD5Init, - dim1442JoeKuoD5Init, - dim1443JoeKuoD5Init, - dim1444JoeKuoD5Init, - dim1445JoeKuoD5Init, - dim1446JoeKuoD5Init, - dim1447JoeKuoD5Init, - dim1448JoeKuoD5Init, - dim1449JoeKuoD5Init, - dim1450JoeKuoD5Init, - dim1451JoeKuoD5Init, - dim1452JoeKuoD5Init, - dim1453JoeKuoD5Init, - dim1454JoeKuoD5Init, - dim1455JoeKuoD5Init, - dim1456JoeKuoD5Init, - dim1457JoeKuoD5Init, - dim1458JoeKuoD5Init, - dim1459JoeKuoD5Init, - dim1460JoeKuoD5Init, - dim1461JoeKuoD5Init, - dim1462JoeKuoD5Init, - dim1463JoeKuoD5Init, - dim1464JoeKuoD5Init, - dim1465JoeKuoD5Init, - dim1466JoeKuoD5Init, - dim1467JoeKuoD5Init, - dim1468JoeKuoD5Init, - dim1469JoeKuoD5Init, - dim1470JoeKuoD5Init, - dim1471JoeKuoD5Init, - dim1472JoeKuoD5Init, - dim1473JoeKuoD5Init, - dim1474JoeKuoD5Init, - dim1475JoeKuoD5Init, - dim1476JoeKuoD5Init, - dim1477JoeKuoD5Init, - dim1478JoeKuoD5Init, - dim1479JoeKuoD5Init, - dim1480JoeKuoD5Init, - dim1481JoeKuoD5Init, - dim1482JoeKuoD5Init, - dim1483JoeKuoD5Init, - dim1484JoeKuoD5Init, - dim1485JoeKuoD5Init, - dim1486JoeKuoD5Init, - dim1487JoeKuoD5Init, - dim1488JoeKuoD5Init, - dim1489JoeKuoD5Init, - dim1490JoeKuoD5Init, - dim1491JoeKuoD5Init, - dim1492JoeKuoD5Init, - dim1493JoeKuoD5Init, - dim1494JoeKuoD5Init, - dim1495JoeKuoD5Init, - dim1496JoeKuoD5Init, - dim1497JoeKuoD5Init, - dim1498JoeKuoD5Init, - dim1499JoeKuoD5Init, - dim1500JoeKuoD5Init, - dim1501JoeKuoD5Init, - dim1502JoeKuoD5Init, - dim1503JoeKuoD5Init, - dim1504JoeKuoD5Init, - dim1505JoeKuoD5Init, - dim1506JoeKuoD5Init, - dim1507JoeKuoD5Init, - dim1508JoeKuoD5Init, - dim1509JoeKuoD5Init, - dim1510JoeKuoD5Init, - dim1511JoeKuoD5Init, - dim1512JoeKuoD5Init, - dim1513JoeKuoD5Init, - dim1514JoeKuoD5Init, - dim1515JoeKuoD5Init, - dim1516JoeKuoD5Init, - dim1517JoeKuoD5Init, - dim1518JoeKuoD5Init, - dim1519JoeKuoD5Init, - dim1520JoeKuoD5Init, - dim1521JoeKuoD5Init, - dim1522JoeKuoD5Init, - dim1523JoeKuoD5Init, - dim1524JoeKuoD5Init, - dim1525JoeKuoD5Init, - dim1526JoeKuoD5Init, - dim1527JoeKuoD5Init, - dim1528JoeKuoD5Init, - dim1529JoeKuoD5Init, - dim1530JoeKuoD5Init, - dim1531JoeKuoD5Init, - dim1532JoeKuoD5Init, - dim1533JoeKuoD5Init, - dim1534JoeKuoD5Init, - dim1535JoeKuoD5Init, - dim1536JoeKuoD5Init, - dim1537JoeKuoD5Init, - dim1538JoeKuoD5Init, - dim1539JoeKuoD5Init, - dim1540JoeKuoD5Init, - dim1541JoeKuoD5Init, - dim1542JoeKuoD5Init, - dim1543JoeKuoD5Init, - dim1544JoeKuoD5Init, - dim1545JoeKuoD5Init, - dim1546JoeKuoD5Init, - dim1547JoeKuoD5Init, - dim1548JoeKuoD5Init, - dim1549JoeKuoD5Init, - dim1550JoeKuoD5Init, - dim1551JoeKuoD5Init, - dim1552JoeKuoD5Init, - dim1553JoeKuoD5Init, - dim1554JoeKuoD5Init, - dim1555JoeKuoD5Init, - dim1556JoeKuoD5Init, - dim1557JoeKuoD5Init, - dim1558JoeKuoD5Init, - dim1559JoeKuoD5Init, - dim1560JoeKuoD5Init, - dim1561JoeKuoD5Init, - dim1562JoeKuoD5Init, - dim1563JoeKuoD5Init, - dim1564JoeKuoD5Init, - dim1565JoeKuoD5Init, - dim1566JoeKuoD5Init, - dim1567JoeKuoD5Init, - dim1568JoeKuoD5Init, - dim1569JoeKuoD5Init, - dim1570JoeKuoD5Init, - dim1571JoeKuoD5Init, - dim1572JoeKuoD5Init, - dim1573JoeKuoD5Init, - dim1574JoeKuoD5Init, - dim1575JoeKuoD5Init, - dim1576JoeKuoD5Init, - dim1577JoeKuoD5Init, - dim1578JoeKuoD5Init, - dim1579JoeKuoD5Init, - dim1580JoeKuoD5Init, - dim1581JoeKuoD5Init, - dim1582JoeKuoD5Init, - dim1583JoeKuoD5Init, - dim1584JoeKuoD5Init, - dim1585JoeKuoD5Init, - dim1586JoeKuoD5Init, - dim1587JoeKuoD5Init, - dim1588JoeKuoD5Init, - dim1589JoeKuoD5Init, - dim1590JoeKuoD5Init, - dim1591JoeKuoD5Init, - dim1592JoeKuoD5Init, - dim1593JoeKuoD5Init, - dim1594JoeKuoD5Init, - dim1595JoeKuoD5Init, - dim1596JoeKuoD5Init, - dim1597JoeKuoD5Init, - dim1598JoeKuoD5Init, - dim1599JoeKuoD5Init, - dim1600JoeKuoD5Init, - dim1601JoeKuoD5Init, - dim1602JoeKuoD5Init, - dim1603JoeKuoD5Init, - dim1604JoeKuoD5Init, - dim1605JoeKuoD5Init, - dim1606JoeKuoD5Init, - dim1607JoeKuoD5Init, - dim1608JoeKuoD5Init, - dim1609JoeKuoD5Init, - dim1610JoeKuoD5Init, - dim1611JoeKuoD5Init, - dim1612JoeKuoD5Init, - dim1613JoeKuoD5Init, - dim1614JoeKuoD5Init, - dim1615JoeKuoD5Init, - dim1616JoeKuoD5Init, - dim1617JoeKuoD5Init, - dim1618JoeKuoD5Init, - dim1619JoeKuoD5Init, - dim1620JoeKuoD5Init, - dim1621JoeKuoD5Init, - dim1622JoeKuoD5Init, - dim1623JoeKuoD5Init, - dim1624JoeKuoD5Init, - dim1625JoeKuoD5Init, - dim1626JoeKuoD5Init, - dim1627JoeKuoD5Init, - dim1628JoeKuoD5Init, - dim1629JoeKuoD5Init, - dim1630JoeKuoD5Init, - dim1631JoeKuoD5Init, - dim1632JoeKuoD5Init, - dim1633JoeKuoD5Init, - dim1634JoeKuoD5Init, - dim1635JoeKuoD5Init, - dim1636JoeKuoD5Init, - dim1637JoeKuoD5Init, - dim1638JoeKuoD5Init, - dim1639JoeKuoD5Init, - dim1640JoeKuoD5Init, - dim1641JoeKuoD5Init, - dim1642JoeKuoD5Init, - dim1643JoeKuoD5Init, - dim1644JoeKuoD5Init, - dim1645JoeKuoD5Init, - dim1646JoeKuoD5Init, - dim1647JoeKuoD5Init, - dim1648JoeKuoD5Init, - dim1649JoeKuoD5Init, - dim1650JoeKuoD5Init, - dim1651JoeKuoD5Init, - dim1652JoeKuoD5Init, - dim1653JoeKuoD5Init, - dim1654JoeKuoD5Init, - dim1655JoeKuoD5Init, - dim1656JoeKuoD5Init, - dim1657JoeKuoD5Init, - dim1658JoeKuoD5Init, - dim1659JoeKuoD5Init, - dim1660JoeKuoD5Init, - dim1661JoeKuoD5Init, - dim1662JoeKuoD5Init, - dim1663JoeKuoD5Init, - dim1664JoeKuoD5Init, - dim1665JoeKuoD5Init, - dim1666JoeKuoD5Init, - dim1667JoeKuoD5Init, - dim1668JoeKuoD5Init, - dim1669JoeKuoD5Init, - dim1670JoeKuoD5Init, - dim1671JoeKuoD5Init, - dim1672JoeKuoD5Init, - dim1673JoeKuoD5Init, - dim1674JoeKuoD5Init, - dim1675JoeKuoD5Init, - dim1676JoeKuoD5Init, - dim1677JoeKuoD5Init, - dim1678JoeKuoD5Init, - dim1679JoeKuoD5Init, - dim1680JoeKuoD5Init, - dim1681JoeKuoD5Init, - dim1682JoeKuoD5Init, - dim1683JoeKuoD5Init, - dim1684JoeKuoD5Init, - dim1685JoeKuoD5Init, - dim1686JoeKuoD5Init, - dim1687JoeKuoD5Init, - dim1688JoeKuoD5Init, - dim1689JoeKuoD5Init, - dim1690JoeKuoD5Init, - dim1691JoeKuoD5Init, - dim1692JoeKuoD5Init, - dim1693JoeKuoD5Init, - dim1694JoeKuoD5Init, - dim1695JoeKuoD5Init, - dim1696JoeKuoD5Init, - dim1697JoeKuoD5Init, - dim1698JoeKuoD5Init, - dim1699JoeKuoD5Init, - dim1700JoeKuoD5Init, - dim1701JoeKuoD5Init, - dim1702JoeKuoD5Init, - dim1703JoeKuoD5Init, - dim1704JoeKuoD5Init, - dim1705JoeKuoD5Init, - dim1706JoeKuoD5Init, - dim1707JoeKuoD5Init, - dim1708JoeKuoD5Init, - dim1709JoeKuoD5Init, - dim1710JoeKuoD5Init, - dim1711JoeKuoD5Init, - dim1712JoeKuoD5Init, - dim1713JoeKuoD5Init, - dim1714JoeKuoD5Init, - dim1715JoeKuoD5Init, - dim1716JoeKuoD5Init, - dim1717JoeKuoD5Init, - dim1718JoeKuoD5Init, - dim1719JoeKuoD5Init, - dim1720JoeKuoD5Init, - dim1721JoeKuoD5Init, - dim1722JoeKuoD5Init, - dim1723JoeKuoD5Init, - dim1724JoeKuoD5Init, - dim1725JoeKuoD5Init, - dim1726JoeKuoD5Init, - dim1727JoeKuoD5Init, - dim1728JoeKuoD5Init, - dim1729JoeKuoD5Init, - dim1730JoeKuoD5Init, - dim1731JoeKuoD5Init, - dim1732JoeKuoD5Init, - dim1733JoeKuoD5Init, - dim1734JoeKuoD5Init, - dim1735JoeKuoD5Init, - dim1736JoeKuoD5Init, - dim1737JoeKuoD5Init, - dim1738JoeKuoD5Init, - dim1739JoeKuoD5Init, - dim1740JoeKuoD5Init, - dim1741JoeKuoD5Init, - dim1742JoeKuoD5Init, - dim1743JoeKuoD5Init, - dim1744JoeKuoD5Init, - dim1745JoeKuoD5Init, - dim1746JoeKuoD5Init, - dim1747JoeKuoD5Init, - dim1748JoeKuoD5Init, - dim1749JoeKuoD5Init, - dim1750JoeKuoD5Init, - dim1751JoeKuoD5Init, - dim1752JoeKuoD5Init, - dim1753JoeKuoD5Init, - dim1754JoeKuoD5Init, - dim1755JoeKuoD5Init, - dim1756JoeKuoD5Init, - dim1757JoeKuoD5Init, - dim1758JoeKuoD5Init, - dim1759JoeKuoD5Init, - dim1760JoeKuoD5Init, - dim1761JoeKuoD5Init, - dim1762JoeKuoD5Init, - dim1763JoeKuoD5Init, - dim1764JoeKuoD5Init, - dim1765JoeKuoD5Init, - dim1766JoeKuoD5Init, - dim1767JoeKuoD5Init, - dim1768JoeKuoD5Init, - dim1769JoeKuoD5Init, - dim1770JoeKuoD5Init, - dim1771JoeKuoD5Init, - dim1772JoeKuoD5Init, - dim1773JoeKuoD5Init, - dim1774JoeKuoD5Init, - dim1775JoeKuoD5Init, - dim1776JoeKuoD5Init, - dim1777JoeKuoD5Init, - dim1778JoeKuoD5Init, - dim1779JoeKuoD5Init, - dim1780JoeKuoD5Init, - dim1781JoeKuoD5Init, - dim1782JoeKuoD5Init, - dim1783JoeKuoD5Init, - dim1784JoeKuoD5Init, - dim1785JoeKuoD5Init, - dim1786JoeKuoD5Init, - dim1787JoeKuoD5Init, - dim1788JoeKuoD5Init, - dim1789JoeKuoD5Init, - dim1790JoeKuoD5Init, - dim1791JoeKuoD5Init, - dim1792JoeKuoD5Init, - dim1793JoeKuoD5Init, - dim1794JoeKuoD5Init, - dim1795JoeKuoD5Init, - dim1796JoeKuoD5Init, - dim1797JoeKuoD5Init, - dim1798JoeKuoD5Init, - dim1799JoeKuoD5Init, - dim1800JoeKuoD5Init, - dim1801JoeKuoD5Init, - dim1802JoeKuoD5Init, - dim1803JoeKuoD5Init, - dim1804JoeKuoD5Init, - dim1805JoeKuoD5Init, - dim1806JoeKuoD5Init, - dim1807JoeKuoD5Init, - dim1808JoeKuoD5Init, - dim1809JoeKuoD5Init, - dim1810JoeKuoD5Init, - dim1811JoeKuoD5Init, - dim1812JoeKuoD5Init, - dim1813JoeKuoD5Init, - dim1814JoeKuoD5Init, - dim1815JoeKuoD5Init, - dim1816JoeKuoD5Init, - dim1817JoeKuoD5Init, - dim1818JoeKuoD5Init, - dim1819JoeKuoD5Init, - dim1820JoeKuoD5Init, - dim1821JoeKuoD5Init, - dim1822JoeKuoD5Init, - dim1823JoeKuoD5Init, - dim1824JoeKuoD5Init, - dim1825JoeKuoD5Init, - dim1826JoeKuoD5Init, - dim1827JoeKuoD5Init, - dim1828JoeKuoD5Init, - dim1829JoeKuoD5Init, - dim1830JoeKuoD5Init, - dim1831JoeKuoD5Init, - dim1832JoeKuoD5Init, - dim1833JoeKuoD5Init, - dim1834JoeKuoD5Init, - dim1835JoeKuoD5Init, - dim1836JoeKuoD5Init, - dim1837JoeKuoD5Init, - dim1838JoeKuoD5Init, - dim1839JoeKuoD5Init, - dim1840JoeKuoD5Init, - dim1841JoeKuoD5Init, - dim1842JoeKuoD5Init, - dim1843JoeKuoD5Init, - dim1844JoeKuoD5Init, - dim1845JoeKuoD5Init, - dim1846JoeKuoD5Init, - dim1847JoeKuoD5Init, - dim1848JoeKuoD5Init, - dim1849JoeKuoD5Init, - dim1850JoeKuoD5Init, - dim1851JoeKuoD5Init, - dim1852JoeKuoD5Init, - dim1853JoeKuoD5Init, - dim1854JoeKuoD5Init, - dim1855JoeKuoD5Init, - dim1856JoeKuoD5Init, - dim1857JoeKuoD5Init, - dim1858JoeKuoD5Init, - dim1859JoeKuoD5Init, - dim1860JoeKuoD5Init, - dim1861JoeKuoD5Init, - dim1862JoeKuoD5Init, - dim1863JoeKuoD5Init, - dim1864JoeKuoD5Init, - dim1865JoeKuoD5Init, - dim1866JoeKuoD5Init, - dim1867JoeKuoD5Init, - dim1868JoeKuoD5Init, - dim1869JoeKuoD5Init, - dim1870JoeKuoD5Init, - dim1871JoeKuoD5Init, - dim1872JoeKuoD5Init, - dim1873JoeKuoD5Init, - dim1874JoeKuoD5Init, - dim1875JoeKuoD5Init, - dim1876JoeKuoD5Init, - dim1877JoeKuoD5Init, - dim1878JoeKuoD5Init, - dim1879JoeKuoD5Init, - dim1880JoeKuoD5Init, - dim1881JoeKuoD5Init, - dim1882JoeKuoD5Init, - dim1883JoeKuoD5Init, - dim1884JoeKuoD5Init, - dim1885JoeKuoD5Init, - dim1886JoeKuoD5Init, - dim1887JoeKuoD5Init, - dim1888JoeKuoD5Init, - dim1889JoeKuoD5Init, - dim1890JoeKuoD5Init, - dim1891JoeKuoD5Init, - dim1892JoeKuoD5Init, - dim1893JoeKuoD5Init, - dim1894JoeKuoD5Init, - dim1895JoeKuoD5Init, - dim1896JoeKuoD5Init, - dim1897JoeKuoD5Init, - dim1898JoeKuoD5Init, - dim1899JoeKuoD5Init, - dim1900JoeKuoD5Init, - dim1901JoeKuoD5Init, - dim1902JoeKuoD5Init, - dim1903JoeKuoD5Init, - dim1904JoeKuoD5Init, - dim1905JoeKuoD5Init, - dim1906JoeKuoD5Init, - dim1907JoeKuoD5Init, - dim1908JoeKuoD5Init, - dim1909JoeKuoD5Init, - dim1910JoeKuoD5Init, - dim1911JoeKuoD5Init, - dim1912JoeKuoD5Init, - dim1913JoeKuoD5Init, - dim1914JoeKuoD5Init, - dim1915JoeKuoD5Init, - dim1916JoeKuoD5Init, - dim1917JoeKuoD5Init, - dim1918JoeKuoD5Init, - dim1919JoeKuoD5Init, - dim1920JoeKuoD5Init, - dim1921JoeKuoD5Init, - dim1922JoeKuoD5Init, - dim1923JoeKuoD5Init, - dim1924JoeKuoD5Init, - dim1925JoeKuoD5Init, - dim1926JoeKuoD5Init, - dim1927JoeKuoD5Init, - dim1928JoeKuoD5Init, - dim1929JoeKuoD5Init, - dim1930JoeKuoD5Init, - dim1931JoeKuoD5Init, - dim1932JoeKuoD5Init, - dim1933JoeKuoD5Init, - dim1934JoeKuoD5Init, - dim1935JoeKuoD5Init, - dim1936JoeKuoD5Init, - dim1937JoeKuoD5Init, - dim1938JoeKuoD5Init, - dim1939JoeKuoD5Init, - dim1940JoeKuoD5Init, - dim1941JoeKuoD5Init, - dim1942JoeKuoD5Init, - dim1943JoeKuoD5Init, - dim1944JoeKuoD5Init, - dim1945JoeKuoD5Init, - dim1946JoeKuoD5Init, - dim1947JoeKuoD5Init, - dim1948JoeKuoD5Init, - dim1949JoeKuoD5Init, - dim1950JoeKuoD5Init, - dim1951JoeKuoD5Init, - dim1952JoeKuoD5Init, - dim1953JoeKuoD5Init, - dim1954JoeKuoD5Init, - dim1955JoeKuoD5Init, - dim1956JoeKuoD5Init, - dim1957JoeKuoD5Init, - dim1958JoeKuoD5Init, - dim1959JoeKuoD5Init, - dim1960JoeKuoD5Init, - dim1961JoeKuoD5Init, - dim1962JoeKuoD5Init, - dim1963JoeKuoD5Init, - dim1964JoeKuoD5Init, - dim1965JoeKuoD5Init, - dim1966JoeKuoD5Init, - dim1967JoeKuoD5Init, - dim1968JoeKuoD5Init, - dim1969JoeKuoD5Init, - dim1970JoeKuoD5Init, - dim1971JoeKuoD5Init, - dim1972JoeKuoD5Init, - dim1973JoeKuoD5Init, - dim1974JoeKuoD5Init, - dim1975JoeKuoD5Init, - dim1976JoeKuoD5Init, - dim1977JoeKuoD5Init, - dim1978JoeKuoD5Init, - dim1979JoeKuoD5Init, - dim1980JoeKuoD5Init, - dim1981JoeKuoD5Init, - dim1982JoeKuoD5Init, - dim1983JoeKuoD5Init, - dim1984JoeKuoD5Init, - dim1985JoeKuoD5Init, - dim1986JoeKuoD5Init, - dim1987JoeKuoD5Init, - dim1988JoeKuoD5Init, - dim1989JoeKuoD5Init, - dim1990JoeKuoD5Init, - dim1991JoeKuoD5Init, - dim1992JoeKuoD5Init, - dim1993JoeKuoD5Init, - dim1994JoeKuoD5Init, - dim1995JoeKuoD5Init, - dim1996JoeKuoD5Init, - dim1997JoeKuoD5Init, - dim1998JoeKuoD5Init, - dim1999JoeKuoD5Init - }; - - static ulong[] dim1Kuo2Init = { 1, 0 }; - static ulong[] dim2Kuo2Init = { 1, 1, 0 }; - static ulong[] dim3Kuo2Init = { 1, 1, 1, 0 }; - static ulong[] dim4Kuo2Init = { 1, 3, 1, 0 }; - static ulong[] dim5Kuo2Init = { 1, 3, 7, 1, 0 }; - static ulong[] dim6Kuo2Init = { 1, 1, 3, 7, 0 }; - static ulong[] dim7Kuo2Init = { 1, 3, 1, 7, 23, 0 }; - static ulong[] dim8Kuo2Init = { 1, 1, 5, 1, 27, 0 }; - static ulong[] dim9Kuo2Init = { 1, 3, 5, 3, 25, 0 }; - static ulong[] dim10Kuo2Init = { 1, 1, 5, 9, 21, 0 }; - static ulong[] dim11Kuo2Init = { 1, 1, 3, 13, 27, 0 }; - static ulong[] dim12Kuo2Init = { 1, 3, 7, 11, 3, 0 }; - static ulong[] dim13Kuo2Init = { 1, 3, 1, 13, 31, 47, 0 }; - static ulong[] dim14Kuo2Init = { 1, 3, 3, 5, 13, 17, 0 }; - static ulong[] dim15Kuo2Init = { 1, 1, 7, 3, 13, 51, 0 }; - static ulong[] dim16Kuo2Init = { 1, 3, 3, 11, 7, 63, 0 }; - static ulong[] dim17Kuo2Init = { 1, 1, 1, 7, 3, 53, 0 }; - static ulong[] dim18Kuo2Init = { 1, 3, 5, 11, 3, 43, 0 }; - static ulong[] dim19Kuo2Init = { 1, 1, 7, 5, 19, 59, 59, 0 }; - static ulong[] dim20Kuo2Init = { 1, 1, 7, 9, 15, 25, 63, 0 }; - static ulong[] dim21Kuo2Init = { 1, 3, 7, 7, 27, 5, 17, 0 }; - static ulong[] dim22Kuo2Init = { 1, 3, 1, 5, 7, 51, 69, 0 }; - static ulong[] dim23Kuo2Init = { 1, 3, 3, 11, 23, 5, 35, 0 }; - static ulong[] dim24Kuo2Init = { 1, 1, 5, 1, 3, 17, 59, 0 }; - static ulong[] dim25Kuo2Init = { 1, 3, 7, 7, 3, 51, 57, 0 }; - static ulong[] dim26Kuo2Init = { 1, 3, 7, 11, 17, 1, 17, 0 }; - static ulong[] dim27Kuo2Init = { 1, 1, 1, 11, 25, 45, 3, 0 }; - static ulong[] dim28Kuo2Init = { 1, 1, 5, 15, 23, 53, 79, 0 }; - static ulong[] dim29Kuo2Init = { 1, 3, 3, 3, 19, 31, 39, 0 }; - static ulong[] dim30Kuo2Init = { 1, 1, 1, 9, 9, 21, 23, 0 }; - static ulong[] dim31Kuo2Init = { 1, 1, 3, 5, 31, 13, 97, 0 }; - static ulong[] dim32Kuo2Init = { 1, 1, 1, 15, 9, 39, 3, 0 }; - static ulong[] dim33Kuo2Init = { 1, 3, 1, 1, 27, 55, 37, 0 }; - static ulong[] dim34Kuo2Init = { 1, 3, 7, 11, 21, 49, 17, 0 }; - static ulong[] dim35Kuo2Init = { 1, 3, 3, 9, 31, 37, 95, 0 }; - static ulong[] dim36Kuo2Init = { 1, 1, 1, 1, 7, 35, 95, 0 }; - static ulong[] dim37Kuo2Init = { 1, 1, 5, 15, 15, 61, 11, 211, 0 }; - static ulong[] dim38Kuo2Init = { 1, 1, 7, 7, 29, 33, 127, 171, 0 }; - static ulong[] dim39Kuo2Init = { 1, 3, 5, 9, 17, 27, 85, 95, 0 }; - static ulong[] dim40Kuo2Init = { 1, 3, 7, 1, 25, 43, 35, 21, 0 }; - static ulong[] dim41Kuo2Init = { 1, 3, 5, 15, 9, 17, 43, 253, 0 }; - static ulong[] dim42Kuo2Init = { 1, 1, 5, 11, 27, 45, 37, 147, 0 }; - static ulong[] dim43Kuo2Init = { 1, 1, 7, 5, 7, 35, 29, 191, 0 }; - static ulong[] dim44Kuo2Init = { 1, 3, 1, 1, 15, 33, 21, 125, 0 }; - static ulong[] dim45Kuo2Init = { 1, 1, 1, 7, 31, 41, 33, 11, 0 }; - static ulong[] dim46Kuo2Init = { 1, 1, 7, 7, 27, 9, 111, 209, 0 }; - static ulong[] dim47Kuo2Init = { 1, 3, 7, 15, 1, 57, 63, 43, 0 }; - static ulong[] dim48Kuo2Init = { 1, 3, 3, 13, 1, 51, 5, 51, 0 }; - static ulong[] dim49Kuo2Init = { 1, 3, 5, 3, 27, 17, 103, 247, 0 }; - static ulong[] dim50Kuo2Init = { 1, 3, 7, 7, 11, 27, 51, 103, 0 }; - static ulong[] dim51Kuo2Init = { 1, 3, 3, 1, 23, 21, 65, 135, 0 }; - static ulong[] dim52Kuo2Init = { 1, 1, 7, 9, 1, 7, 71, 251, 0 }; - static ulong[] dim53Kuo2Init = { 1, 3, 1, 5, 11, 31, 43, 129, 225, 0 }; - static ulong[] dim54Kuo2Init = { 1, 1, 1, 5, 15, 15, 127, 225, 439, 0 }; - static ulong[] dim55Kuo2Init = { 1, 1, 3, 13, 27, 45, 103, 65, 313, 0 }; - static ulong[] dim56Kuo2Init = { 1, 3, 3, 15, 13, 31, 27, 231, 183, 0 }; - static ulong[] dim57Kuo2Init = { 1, 1, 3, 7, 23, 5, 15, 75, 159, 0 }; - static ulong[] dim58Kuo2Init = { 1, 1, 5, 15, 21, 3, 99, 23, 465, 0 }; - static ulong[] dim59Kuo2Init = { 1, 3, 7, 5, 23, 47, 119, 103, 271, 0 }; - static ulong[] dim60Kuo2Init = { 1, 3, 1, 11, 25, 13, 83, 5, 21, 0 }; - static ulong[] dim61Kuo2Init = { 1, 3, 5, 3, 7, 41, 123, 87, 243, 0 }; - static ulong[] dim62Kuo2Init = { 1, 1, 3, 11, 3, 7, 91, 227, 349, 0 }; - static ulong[] dim63Kuo2Init = { 1, 1, 1, 9, 29, 23, 31, 175, 145, 0 }; - static ulong[] dim64Kuo2Init = { 1, 1, 7, 7, 13, 25, 67, 59, 109, 0 }; - static ulong[] dim65Kuo2Init = { 1, 3, 7, 11, 25, 49, 23, 55, 135, 0 }; - static ulong[] dim66Kuo2Init = { 1, 3, 5, 7, 27, 61, 5, 193, 375, 0 }; - static ulong[] dim67Kuo2Init = { 1, 1, 5, 9, 23, 27, 41, 239, 383, 0 }; - static ulong[] dim68Kuo2Init = { 1, 1, 3, 15, 3, 43, 81, 77, 91, 0 }; - static ulong[] dim69Kuo2Init = { 1, 1, 1, 13, 29, 17, 23, 105, 393, 0 }; - static ulong[] dim70Kuo2Init = { 1, 3, 3, 3, 27, 41, 89, 79, 295, 0 }; - static ulong[] dim71Kuo2Init = { 1, 3, 3, 5, 27, 63, 29, 189, 505, 0 }; - static ulong[] dim72Kuo2Init = { 1, 1, 3, 7, 23, 63, 117, 75, 165, 0 }; - static ulong[] dim73Kuo2Init = { 1, 1, 5, 13, 1, 47, 123, 159, 485, 0 }; - static ulong[] dim74Kuo2Init = { 1, 3, 5, 1, 23, 27, 125, 45, 351, 0 }; - static ulong[] dim75Kuo2Init = { 1, 3, 1, 5, 11, 33, 75, 17, 85, 0 }; - static ulong[] dim76Kuo2Init = { 1, 3, 7, 9, 23, 31, 33, 91, 131, 0 }; - static ulong[] dim77Kuo2Init = { 1, 1, 3, 7, 23, 31, 89, 243, 229, 0 }; - static ulong[] dim78Kuo2Init = { 1, 1, 7, 15, 3, 9, 97, 59, 159, 0 }; - static ulong[] dim79Kuo2Init = { 1, 3, 3, 9, 23, 1, 105, 217, 491, 0 }; - static ulong[] dim80Kuo2Init = { 1, 3, 7, 13, 19, 3, 95, 149, 169, 0 }; - static ulong[] dim81Kuo2Init = { 1, 1, 5, 11, 29, 57, 7, 69, 33, 0 }; - static ulong[] dim82Kuo2Init = { 1, 1, 7, 7, 23, 1, 17, 3, 325, 0 }; - static ulong[] dim83Kuo2Init = { 1, 3, 1, 7, 23, 7, 49, 251, 501, 0 }; - static ulong[] dim84Kuo2Init = { 1, 1, 5, 9, 13, 59, 51, 15, 231, 0 }; - static ulong[] dim85Kuo2Init = { 1, 1, 1, 7, 13, 43, 21, 227, 165, 0 }; - static ulong[] dim86Kuo2Init = { 1, 1, 5, 1, 17, 59, 85, 13, 81, 0 }; - static ulong[] dim87Kuo2Init = { 1, 1, 5, 11, 25, 39, 109, 149, 89, 0 }; - static ulong[] dim88Kuo2Init = { 1, 3, 1, 13, 3, 47, 85, 1, 241, 0 }; - static ulong[] dim89Kuo2Init = { 1, 1, 7, 7, 29, 25, 71, 13, 221, 0 }; - static ulong[] dim90Kuo2Init = { 1, 1, 3, 5, 1, 3, 17, 241, 227, 0 }; - static ulong[] dim91Kuo2Init = { 1, 3, 1, 7, 3, 23, 127, 209, 139, 0 }; - static ulong[] dim92Kuo2Init = { 1, 1, 3, 5, 31, 39, 55, 193, 27, 0 }; - static ulong[] dim93Kuo2Init = { 1, 3, 5, 3, 5, 19, 71, 161, 255, 0 }; - static ulong[] dim94Kuo2Init = { 1, 3, 3, 7, 17, 27, 105, 13, 131, 0 }; - static ulong[] dim95Kuo2Init = { 1, 1, 3, 1, 23, 7, 43, 171, 503, 0 }; - static ulong[] dim96Kuo2Init = { 1, 3, 5, 7, 7, 11, 9, 243, 173, 0 }; - static ulong[] dim97Kuo2Init = { 1, 1, 7, 13, 23, 3, 119, 243, 189, 0 }; - static ulong[] dim98Kuo2Init = { 1, 1, 3, 11, 17, 55, 53, 159, 339, 0 }; - static ulong[] dim99Kuo2Init = { 1, 3, 3, 11, 5, 17, 69, 103, 453, 0 }; - static ulong[] dim100Kuo2Init = { 1, 3, 7, 7, 9, 41, 31, 165, 117, 0 }; - static ulong[] dim101Kuo2Init = { 1, 1, 5, 3, 5, 39, 79, 141, 205, 483, 0 }; - static ulong[] dim102Kuo2Init = { 1, 3, 1, 3, 3, 59, 57, 189, 279, 769, 0 }; - static ulong[] dim103Kuo2Init = { 1, 1, 3, 13, 25, 21, 107, 61, 329, 695, 0 }; - static ulong[] dim104Kuo2Init = { 1, 3, 5, 15, 3, 61, 71, 161, 55, 757, 0 }; - static ulong[] dim105Kuo2Init = { 1, 1, 1, 11, 9, 17, 121, 41, 177, 261, 0 }; - static ulong[] dim106Kuo2Init = { 1, 1, 5, 3, 25, 49, 55, 119, 171, 213, 0 }; - static ulong[] dim107Kuo2Init = { 1, 3, 3, 13, 21, 35, 73, 33, 43, 673, 0 }; - static ulong[] dim108Kuo2Init = { 1, 3, 5, 7, 25, 5, 7, 93, 485, 635, 0 }; - static ulong[] dim109Kuo2Init = { 1, 1, 5, 1, 5, 55, 17, 33, 67, 553, 0 }; - static ulong[] dim110Kuo2Init = { 1, 1, 7, 1, 15, 31, 67, 219, 241, 233, 0 }; - static ulong[] dim111Kuo2Init = { 1, 1, 3, 7, 9, 33, 77, 115, 401, 617, 0 }; - static ulong[] dim112Kuo2Init = { 1, 1, 3, 3, 1, 11, 79, 49, 327, 287, 0 }; - static ulong[] dim113Kuo2Init = { 1, 3, 5, 15, 19, 49, 115, 73, 193, 615, 0 }; - static ulong[] dim114Kuo2Init = { 1, 3, 5, 13, 15, 41, 17, 133, 369, 783, 0 }; - static ulong[] dim115Kuo2Init = { 1, 1, 7, 13, 9, 15, 59, 43, 129, 337, 0 }; - static ulong[] dim116Kuo2Init = { 1, 1, 3, 11, 13, 41, 35, 111, 385, 243, 0 }; - static ulong[] dim117Kuo2Init = { 1, 3, 5, 11, 7, 25, 79, 9, 5, 159, 0 }; - static ulong[] dim118Kuo2Init = { 1, 3, 3, 1, 7, 17, 31, 3, 27, 829, 0 }; - static ulong[] dim119Kuo2Init = { 1, 3, 3, 15, 27, 33, 13, 29, 223, 545, 0 }; - static ulong[] dim120Kuo2Init = { 1, 1, 5, 1, 7, 7, 31, 103, 307, 315, 0 }; - static ulong[] dim121Kuo2Init = { 1, 3, 7, 9, 15, 9, 61, 75, 99, 173, 0 }; - static ulong[] dim122Kuo2Init = { 1, 3, 3, 15, 21, 31, 49, 45, 301, 593, 0 }; - static ulong[] dim123Kuo2Init = { 1, 3, 1, 11, 3, 1, 37, 109, 413, 517, 0 }; - static ulong[] dim124Kuo2Init = { 1, 3, 1, 15, 1, 47, 45, 189, 331, 3, 0 }; - static ulong[] dim125Kuo2Init = { 1, 3, 7, 5, 3, 47, 107, 141, 257, 189, 0 }; - static ulong[] dim126Kuo2Init = { 1, 1, 1, 11, 5, 31, 49, 35, 139, 895, 0 }; - static ulong[] dim127Kuo2Init = { 1, 3, 3, 7, 17, 23, 47, 229, 225, 393, 0 }; - static ulong[] dim128Kuo2Init = { 1, 1, 1, 11, 17, 39, 125, 223, 251, 95, 0 }; - static ulong[] dim129Kuo2Init = { 1, 3, 7, 9, 31, 1, 29, 81, 301, 309, 0 }; - static ulong[] dim130Kuo2Init = { 1, 1, 1, 5, 29, 3, 5, 7, 481, 989, 0 }; - static ulong[] dim131Kuo2Init = { 1, 1, 1, 5, 19, 29, 103, 103, 385, 541, 0 }; - static ulong[] dim132Kuo2Init = { 1, 3, 7, 13, 31, 53, 27, 51, 305, 345, 0 }; - static ulong[] dim133Kuo2Init = { 1, 3, 5, 5, 19, 51, 41, 15, 31, 761, 0 }; - static ulong[] dim134Kuo2Init = { 1, 1, 5, 3, 25, 21, 93, 205, 129, 179, 0 }; - static ulong[] dim135Kuo2Init = { 1, 3, 7, 11, 5, 31, 29, 143, 103, 227, 0 }; - static ulong[] dim136Kuo2Init = { 1, 3, 1, 11, 29, 47, 97, 217, 13, 897, 0 }; - static ulong[] dim137Kuo2Init = { 1, 1, 3, 13, 15, 39, 85, 181, 471, 853, 0 }; - static ulong[] dim138Kuo2Init = { 1, 3, 1, 11, 11, 21, 5, 233, 415, 897, 0 }; - static ulong[] dim139Kuo2Init = { 1, 1, 5, 7, 3, 19, 103, 27, 353, 775, 0 }; - static ulong[] dim140Kuo2Init = { 1, 3, 3, 1, 21, 57, 123, 27, 61, 719, 0 }; - static ulong[] dim141Kuo2Init = { 1, 1, 3, 13, 5, 57, 87, 77, 301, 633, 0 }; - static ulong[] dim142Kuo2Init = { 1, 3, 7, 5, 21, 59, 19, 177, 147, 357, 0 }; - static ulong[] dim143Kuo2Init = { 1, 1, 5, 1, 5, 57, 43, 249, 475, 189, 0 }; - static ulong[] dim144Kuo2Init = { 1, 3, 7, 9, 15, 49, 29, 75, 75, 839, 0 }; - static ulong[] dim145Kuo2Init = { 1, 1, 3, 7, 23, 47, 17, 83, 275, 917, 0 }; - static ulong[] dim146Kuo2Init = { 1, 3, 7, 1, 23, 17, 35, 237, 357, 363, 0 }; - static ulong[] dim147Kuo2Init = { 1, 1, 3, 1, 17, 35, 85, 215, 405, 469, 0 }; - static ulong[] dim148Kuo2Init = { 1, 3, 1, 9, 21, 21, 103, 205, 79, 431, 0 }; - static ulong[] dim149Kuo2Init = { 1, 1, 3, 1, 7, 13, 127, 233, 93, 215, 0 }; - static ulong[] dim150Kuo2Init = { 1, 3, 1, 11, 13, 19, 87, 219, 49, 133, 0 }; - static ulong[] dim151Kuo2Init = { 1, 3, 7, 3, 27, 51, 125, 235, 159, 981, 0 }; - static ulong[] dim152Kuo2Init = { 1, 1, 3, 7, 29, 37, 3, 189, 419, 329, 0 }; - static ulong[] dim153Kuo2Init = { 1, 1, 5, 13, 9, 61, 125, 29, 111, 751, 0 }; - static ulong[] dim154Kuo2Init = { 1, 1, 3, 5, 5, 43, 59, 15, 445, 803, 0 }; - static ulong[] dim155Kuo2Init = { 1, 1, 7, 15, 25, 55, 37, 231, 287, 97, 0 }; - static ulong[] dim156Kuo2Init = { 1, 1, 1, 1, 13, 5, 97, 25, 53, 579, 0 }; - static ulong[] dim157Kuo2Init = { 1, 3, 5, 13, 27, 63, 17, 197, 285, 741, 0 }; - static ulong[] dim158Kuo2Init = { 1, 1, 5, 3, 7, 31, 13, 167, 235, 965, 0 }; - static ulong[] dim159Kuo2Init = { 1, 3, 5, 7, 3, 35, 97, 131, 89, 313, 0 }; - static ulong[] dim160Kuo2Init = { 1, 1, 3, 13, 23, 3, 91, 155, 249, 829, 0 }; - static ulong[] dim161Kuo2Init = { 1, 3, 7, 13, 1, 41, 51, 233, 233, 163, 1357, 0 }; - static ulong[] dim162Kuo2Init = { 1, 3, 1, 3, 13, 3, 55, 9, 511, 441, 811, 0 }; - static ulong[] dim163Kuo2Init = { 1, 3, 5, 5, 11, 57, 45, 65, 397, 199, 1195, 0 }; - static ulong[] dim164Kuo2Init = { 1, 3, 5, 11, 11, 15, 95, 163, 319, 727, 1793, 0 }; - static ulong[] dim165Kuo2Init = { 1, 1, 5, 7, 31, 47, 49, 177, 229, 719, 241, 0 }; - static ulong[] dim166Kuo2Init = { 1, 3, 1, 13, 9, 25, 69, 67, 151, 369, 1205, 0 }; - static ulong[] dim167Kuo2Init = { 1, 1, 7, 3, 9, 39, 99, 109, 111, 787, 181, 0 }; - static ulong[] dim168Kuo2Init = { 1, 1, 3, 11, 23, 1, 49, 111, 45, 293, 1603, 0 }; - static ulong[] dim169Kuo2Init = { 1, 1, 1, 3, 5, 45, 11, 197, 357, 109, 1291, 0 }; - static ulong[] dim170Kuo2Init = { 1, 3, 5, 11, 5, 25, 91, 91, 339, 559, 311, 0 }; - static ulong[] dim171Kuo2Init = { 1, 3, 3, 3, 21, 37, 69, 129, 205, 333, 165, 0 }; - static ulong[] dim172Kuo2Init = { 1, 1, 1, 15, 9, 19, 115, 153, 23, 381, 1727, 0 }; - static ulong[] dim173Kuo2Init = { 1, 1, 3, 1, 3, 35, 77, 217, 133, 943, 169, 0 }; - static ulong[] dim174Kuo2Init = { 1, 1, 5, 9, 1, 39, 67, 217, 143, 529, 769, 0 }; - static ulong[] dim175Kuo2Init = { 1, 1, 3, 3, 9, 9, 9, 203, 425, 601, 1389, 0 }; - static ulong[] dim176Kuo2Init = { 1, 3, 7, 3, 15, 19, 109, 31, 417, 127, 1109, 0 }; - static ulong[] dim177Kuo2Init = { 1, 3, 1, 15, 1, 37, 75, 199, 419, 917, 1929, 0 }; - static ulong[] dim178Kuo2Init = { 1, 3, 3, 9, 21, 37, 23, 165, 67, 39, 1685, 0 }; - static ulong[] dim179Kuo2Init = { 1, 3, 3, 7, 3, 25, 75, 67, 451, 889, 1015, 0 }; - static ulong[] dim180Kuo2Init = { 1, 3, 1, 1, 27, 37, 39, 7, 411, 391, 463, 0 }; - static ulong[] dim181Kuo2Init = { 1, 1, 7, 15, 25, 19, 55, 131, 245, 887, 971, 0 }; - static ulong[] dim182Kuo2Init = { 1, 3, 1, 9, 19, 9, 9, 31, 143, 647, 39, 0 }; - static ulong[] dim183Kuo2Init = { 1, 3, 7, 1, 27, 7, 107, 179, 327, 947, 953, 0 }; - static ulong[] dim184Kuo2Init = { 1, 3, 7, 13, 23, 31, 65, 29, 157, 67, 2009, 0 }; - static ulong[] dim185Kuo2Init = { 1, 3, 5, 13, 19, 31, 19, 249, 385, 209, 281, 0 }; - static ulong[] dim186Kuo2Init = { 1, 1, 7, 15, 3, 63, 1, 97, 349, 1007, 1463, 0 }; - static ulong[] dim187Kuo2Init = { 1, 3, 3, 11, 25, 3, 21, 195, 213, 1013, 637, 0 }; - static ulong[] dim188Kuo2Init = { 1, 3, 1, 1, 27, 7, 95, 215, 473, 1023, 231, 0 }; - static ulong[] dim189Kuo2Init = { 1, 3, 3, 11, 15, 15, 45, 55, 63, 693, 845, 0 }; - static ulong[] dim190Kuo2Init = { 1, 1, 3, 1, 27, 3, 63, 139, 139, 729, 861, 0 }; - static ulong[] dim191Kuo2Init = { 1, 1, 5, 3, 31, 37, 125, 175, 311, 951, 1745, 0 }; - static ulong[] dim192Kuo2Init = { 1, 1, 1, 11, 1, 19, 7, 203, 301, 403, 1293, 0 }; - static ulong[] dim193Kuo2Init = { 1, 3, 1, 5, 13, 39, 27, 155, 27, 725, 993, 0 }; - static ulong[] dim194Kuo2Init = { 1, 3, 5, 1, 5, 57, 19, 225, 407, 713, 1687, 0 }; - static ulong[] dim195Kuo2Init = { 1, 1, 1, 1, 29, 23, 83, 191, 469, 105, 311, 0 }; - static ulong[] dim196Kuo2Init = { 1, 1, 1, 11, 5, 17, 111, 5, 395, 183, 1167, 0 }; - static ulong[] dim197Kuo2Init = { 1, 3, 1, 9, 1, 41, 3, 49, 253, 735, 693, 0 }; - static ulong[] dim198Kuo2Init = { 1, 1, 5, 3, 21, 11, 43, 33, 225, 291, 1581, 0 }; - static ulong[] dim199Kuo2Init = { 1, 1, 1, 1, 5, 29, 43, 85, 465, 879, 1161, 0 }; - static ulong[] dim200Kuo2Init = { 1, 3, 1, 7, 11, 43, 61, 41, 287, 655, 1417, 0 }; - static ulong[] dim201Kuo2Init = { 1, 3, 1, 15, 21, 13, 85, 69, 353, 1005, 1109, 0 }; - static ulong[] dim202Kuo2Init = { 1, 1, 7, 1, 3, 29, 115, 227, 473, 877, 443, 0 }; - static ulong[] dim203Kuo2Init = { 1, 3, 3, 13, 13, 57, 95, 91, 473, 667, 1551, 0 }; - static ulong[] dim204Kuo2Init = { 1, 3, 3, 3, 13, 5, 45, 219, 371, 843, 95, 0 }; - static ulong[] dim205Kuo2Init = { 1, 3, 7, 1, 17, 45, 93, 63, 235, 37, 1081, 0 }; - static ulong[] dim206Kuo2Init = { 1, 3, 3, 1, 17, 21, 5, 91, 433, 321, 645, 0 }; - static ulong[] dim207Kuo2Init = { 1, 1, 7, 11, 9, 5, 33, 189, 205, 51, 259, 0 }; - static ulong[] dim208Kuo2Init = { 1, 1, 7, 3, 17, 9, 11, 235, 477, 419, 721, 0 }; - static ulong[] dim209Kuo2Init = { 1, 1, 1, 15, 21, 49, 25, 103, 25, 273, 1159, 0 }; - static ulong[] dim210Kuo2Init = { 1, 1, 1, 15, 29, 7, 97, 47, 219, 979, 961, 0 }; - static ulong[] dim211Kuo2Init = { 1, 1, 7, 13, 3, 9, 103, 179, 471, 841, 1265, 0 }; - static ulong[] dim212Kuo2Init = { 1, 1, 7, 15, 11, 33, 57, 181, 125, 307, 535, 0 }; - static ulong[] dim213Kuo2Init = { 1, 1, 7, 15, 21, 27, 15, 65, 235, 45, 1169, 0 }; - static ulong[] dim214Kuo2Init = { 1, 3, 1, 5, 9, 59, 123, 25, 391, 253, 1801, 0 }; - static ulong[] dim215Kuo2Init = { 1, 3, 1, 1, 13, 17, 85, 207, 417, 179, 951, 0 }; - static ulong[] dim216Kuo2Init = { 1, 1, 1, 15, 27, 13, 51, 169, 351, 351, 1255, 0 }; - static ulong[] dim217Kuo2Init = { 1, 3, 7, 13, 21, 63, 93, 27, 277, 999, 1381, 0 }; - static ulong[] dim218Kuo2Init = { 1, 1, 5, 9, 21, 11, 99, 199, 281, 281, 373, 0 }; - static ulong[] dim219Kuo2Init = { 1, 1, 5, 1, 1, 41, 17, 43, 411, 315, 1953, 0 }; - static ulong[] dim220Kuo2Init = { 1, 1, 5, 11, 25, 49, 7, 61, 359, 989, 1165, 0 }; - static ulong[] dim221Kuo2Init = { 1, 1, 5, 1, 21, 23, 77, 51, 501, 579, 1969, 0 }; - static ulong[] dim222Kuo2Init = { 1, 3, 7, 3, 15, 43, 89, 107, 331, 723, 771, 0 }; - static ulong[] dim223Kuo2Init = { 1, 1, 3, 15, 3, 57, 41, 241, 183, 579, 1577, 0 }; - static ulong[] dim224Kuo2Init = { 1, 3, 7, 3, 29, 31, 31, 121, 87, 1009, 235, 0 }; - static ulong[] dim225Kuo2Init = { 1, 3, 3, 1, 25, 11, 67, 33, 275, 297, 1143, 0 }; - static ulong[] dim226Kuo2Init = { 1, 1, 7, 13, 17, 29, 99, 39, 111, 29, 881, 0 }; - static ulong[] dim227Kuo2Init = { 1, 1, 7, 1, 7, 25, 27, 107, 169, 77, 1037, 0 }; - static ulong[] dim228Kuo2Init = { 1, 3, 1, 15, 17, 59, 105, 87, 295, 253, 1847, 0 }; - static ulong[] dim229Kuo2Init = { 1, 1, 7, 11, 25, 57, 75, 129, 379, 95, 381, 0 }; - static ulong[] dim230Kuo2Init = { 1, 1, 7, 11, 19, 51, 69, 23, 443, 89, 1245, 0 }; - static ulong[] dim231Kuo2Init = { 1, 3, 7, 15, 3, 43, 71, 173, 435, 125, 1039, 0 }; - static ulong[] dim232Kuo2Init = { 1, 1, 1, 13, 27, 37, 101, 97, 201, 187, 243, 0 }; - static ulong[] dim233Kuo2Init = { 1, 1, 3, 15, 13, 37, 11, 81, 233, 701, 1629, 0 }; - static ulong[] dim234Kuo2Init = { 1, 1, 3, 11, 21, 43, 37, 233, 129, 281, 511, 0 }; - static ulong[] dim235Kuo2Init = { 1, 3, 7, 3, 17, 7, 89, 19, 59, 339, 337, 0 }; - static ulong[] dim236Kuo2Init = { 1, 3, 7, 13, 27, 31, 97, 197, 485, 367, 1169, 0 }; - static ulong[] dim237Kuo2Init = { 1, 1, 7, 13, 9, 5, 93, 93, 289, 79, 57, 0 }; - static ulong[] dim238Kuo2Init = { 1, 3, 5, 13, 23, 61, 99, 201, 115, 583, 1271, 0 }; - static ulong[] dim239Kuo2Init = { 1, 3, 3, 15, 9, 55, 1, 197, 149, 919, 805, 0 }; - static ulong[] dim240Kuo2Init = { 1, 1, 1, 5, 29, 43, 119, 55, 397, 973, 1843, 0 }; - static ulong[] dim241Kuo2Init = { 1, 3, 1, 1, 5, 55, 99, 223, 323, 543, 1851, 0 }; - static ulong[] dim242Kuo2Init = { 1, 1, 1, 15, 1, 31, 17, 107, 303, 675, 1093, 0 }; - static ulong[] dim243Kuo2Init = { 1, 1, 5, 11, 9, 19, 61, 123, 411, 65, 317, 0 }; - static ulong[] dim244Kuo2Init = { 1, 3, 5, 5, 9, 15, 35, 181, 467, 289, 85, 0 }; - static ulong[] dim245Kuo2Init = { 1, 1, 1, 13, 19, 59, 75, 167, 507, 249, 259, 0 }; - static ulong[] dim246Kuo2Init = { 1, 3, 5, 3, 13, 7, 53, 87, 97, 667, 1493, 0 }; - static ulong[] dim247Kuo2Init = { 1, 1, 7, 1, 17, 35, 109, 21, 437, 225, 155, 0 }; - static ulong[] dim248Kuo2Init = { 1, 3, 7, 11, 3, 25, 51, 29, 499, 987, 223, 0 }; - static ulong[] dim249Kuo2Init = { 1, 1, 7, 7, 23, 57, 13, 23, 335, 627, 887, 0 }; - static ulong[] dim250Kuo2Init = { 1, 1, 7, 3, 15, 45, 89, 217, 393, 235, 969, 0 }; - static ulong[] dim251Kuo2Init = { 1, 3, 3, 7, 19, 47, 1, 193, 229, 45, 1617, 0 }; - static ulong[] dim252Kuo2Init = { 1, 3, 1, 9, 29, 63, 15, 57, 509, 147, 323, 0 }; - static ulong[] dim253Kuo2Init = { 1, 3, 5, 9, 9, 33, 77, 83, 109, 335, 481, 0 }; - static ulong[] dim254Kuo2Init = { 1, 1, 3, 1, 7, 47, 69, 3, 23, 243, 1787, 0 }; - static ulong[] dim255Kuo2Init = { 1, 3, 7, 7, 7, 13, 77, 211, 349, 383, 1793, 0 }; - static ulong[] dim256Kuo2Init = { 1, 1, 5, 11, 9, 9, 1, 173, 263, 965, 993, 0 }; - static ulong[] dim257Kuo2Init = { 1, 3, 3, 1, 11, 57, 85, 1, 293, 921, 1711, 0 }; - static ulong[] dim258Kuo2Init = { 1, 3, 3, 13, 29, 25, 13, 143, 373, 575, 1985, 0 }; - static ulong[] dim259Kuo2Init = { 1, 3, 1, 13, 1, 9, 71, 135, 117, 989, 1331, 0 }; - static ulong[] dim260Kuo2Init = { 1, 3, 3, 13, 29, 21, 47, 225, 199, 107, 117, 0 }; - static ulong[] dim261Kuo2Init = { 1, 1, 7, 13, 25, 5, 57, 135, 397, 411, 1275, 0 }; - static ulong[] dim262Kuo2Init = { 1, 1, 3, 1, 11, 19, 39, 9, 165, 813, 871, 0 }; - static ulong[] dim263Kuo2Init = { 1, 3, 1, 11, 29, 1, 71, 35, 361, 331, 773, 0 }; - static ulong[] dim264Kuo2Init = { 1, 1, 3, 9, 23, 23, 73, 7, 505, 183, 563, 0 }; - static ulong[] dim265Kuo2Init = { 1, 3, 5, 9, 25, 35, 123, 111, 221, 1, 873, 0 }; - static ulong[] dim266Kuo2Init = { 1, 1, 3, 3, 15, 43, 53, 71, 339, 321, 1973, 0 }; - static ulong[] dim267Kuo2Init = { 1, 1, 5, 13, 13, 57, 27, 151, 337, 739, 1205, 0 }; - static ulong[] dim268Kuo2Init = { 1, 3, 5, 13, 23, 3, 111, 101, 37, 523, 659, 0 }; - static ulong[] dim269Kuo2Init = { 1, 3, 5, 13, 23, 53, 53, 91, 505, 779, 759, 0 }; - static ulong[] dim270Kuo2Init = { 1, 1, 5, 7, 21, 43, 91, 213, 163, 29, 137, 0 }; - static ulong[] dim271Kuo2Init = { 1, 1, 1, 3, 21, 37, 97, 241, 77, 169, 1255, 0 }; - static ulong[] dim272Kuo2Init = { 1, 3, 3, 1, 5, 31, 119, 127, 137, 915, 1705, 0 }; - static ulong[] dim273Kuo2Init = { 1, 3, 3, 13, 5, 47, 117, 171, 67, 285, 225, 0 }; - static ulong[] dim274Kuo2Init = { 1, 1, 7, 9, 3, 35, 25, 25, 147, 537, 1703, 0 }; - static ulong[] dim275Kuo2Init = { 1, 3, 5, 3, 27, 41, 57, 71, 383, 763, 431, 0 }; - static ulong[] dim276Kuo2Init = { 1, 3, 3, 1, 17, 9, 105, 119, 243, 459, 881, 0 }; - static ulong[] dim277Kuo2Init = { 1, 3, 5, 15, 13, 45, 49, 41, 117, 473, 1701, 0 }; - static ulong[] dim278Kuo2Init = { 1, 1, 3, 11, 13, 5, 77, 17, 11, 1019, 353, 0 }; - static ulong[] dim279Kuo2Init = { 1, 3, 1, 11, 31, 35, 87, 195, 371, 169, 1075, 0 }; - static ulong[] dim280Kuo2Init = { 1, 3, 5, 1, 1, 1, 65, 177, 35, 497, 103, 0 }; - static ulong[] dim281Kuo2Init = { 1, 1, 3, 1, 31, 21, 77, 153, 139, 663, 443, 0 }; - static ulong[] dim282Kuo2Init = { 1, 1, 1, 1, 31, 25, 21, 87, 345, 13, 301, 0 }; - static ulong[] dim283Kuo2Init = { 1, 1, 1, 7, 7, 1, 95, 5, 429, 551, 1011, 0 }; - static ulong[] dim284Kuo2Init = { 1, 3, 5, 15, 23, 63, 119, 185, 463, 371, 567, 0 }; - static ulong[] dim285Kuo2Init = { 1, 1, 5, 5, 21, 21, 33, 141, 181, 885, 717, 0 }; - static ulong[] dim286Kuo2Init = { 1, 1, 1, 5, 11, 35, 37, 231, 67, 951, 1721, 0 }; - static ulong[] dim287Kuo2Init = { 1, 3, 7, 9, 13, 29, 113, 55, 27, 625, 285, 0 }; - static ulong[] dim288Kuo2Init = { 1, 1, 7, 5, 19, 45, 5, 233, 133, 401, 99, 0 }; - static ulong[] dim289Kuo2Init = { 1, 1, 5, 1, 7, 49, 127, 173, 187, 513, 171, 0 }; - static ulong[] dim290Kuo2Init = { 1, 1, 7, 3, 17, 59, 51, 81, 197, 1021, 763, 0 }; - static ulong[] dim291Kuo2Init = { 1, 1, 3, 1, 9, 51, 31, 149, 397, 929, 81, 0 }; - static ulong[] dim292Kuo2Init = { 1, 1, 7, 9, 29, 29, 21, 191, 107, 9, 807, 0 }; - static ulong[] dim293Kuo2Init = { 1, 1, 5, 3, 15, 3, 125, 105, 225, 571, 33, 0 }; - static ulong[] dim294Kuo2Init = { 1, 1, 5, 15, 31, 61, 113, 7, 59, 829, 1259, 0 }; - static ulong[] dim295Kuo2Init = { 1, 3, 1, 5, 29, 27, 33, 145, 211, 837, 749, 0 }; - static ulong[] dim296Kuo2Init = { 1, 1, 1, 1, 27, 15, 25, 197, 51, 71, 813, 0 }; - static ulong[] dim297Kuo2Init = { 1, 1, 1, 3, 27, 59, 1, 163, 467, 991, 1489, 0 }; - static ulong[] dim298Kuo2Init = { 1, 3, 3, 13, 1, 27, 105, 225, 403, 803, 409, 0 }; - static ulong[] dim299Kuo2Init = { 1, 1, 5, 3, 7, 31, 99, 55, 275, 487, 983, 0 }; - static ulong[] dim300Kuo2Init = { 1, 1, 1, 5, 27, 63, 107, 161, 491, 887, 825, 0 }; - static ulong[] dim301Kuo2Init = { 1, 1, 5, 15, 15, 19, 87, 165, 55, 477, 1641, 0 }; - static ulong[] dim302Kuo2Init = { 1, 3, 5, 7, 21, 49, 105, 151, 251, 385, 1265, 0 }; - static ulong[] dim303Kuo2Init = { 1, 1, 5, 3, 5, 43, 47, 213, 387, 523, 1547, 0 }; - static ulong[] dim304Kuo2Init = { 1, 3, 1, 11, 15, 55, 93, 167, 377, 201, 1031, 0 }; - static ulong[] dim305Kuo2Init = { 1, 1, 7, 7, 9, 27, 35, 251, 425, 27, 1527, 0 }; - static ulong[] dim306Kuo2Init = { 1, 1, 7, 7, 15, 55, 123, 21, 53, 77, 345, 0 }; - static ulong[] dim307Kuo2Init = { 1, 1, 5, 15, 13, 11, 75, 101, 75, 217, 219, 0 }; - static ulong[] dim308Kuo2Init = { 1, 1, 3, 9, 1, 29, 117, 209, 301, 803, 1487, 0 }; - static ulong[] dim309Kuo2Init = { 1, 3, 5, 3, 31, 57, 63, 171, 59, 591, 1323, 0 }; - static ulong[] dim310Kuo2Init = { 1, 3, 7, 11, 19, 27, 111, 87, 439, 1023, 691, 0 }; - static ulong[] dim311Kuo2Init = { 1, 3, 7, 13, 15, 57, 11, 249, 383, 291, 1221, 0 }; - static ulong[] dim312Kuo2Init = { 1, 1, 3, 13, 23, 43, 31, 75, 293, 701, 1065, 0 }; - static ulong[] dim313Kuo2Init = { 1, 1, 5, 5, 9, 53, 115, 235, 389, 907, 1883, 0 }; - static ulong[] dim314Kuo2Init = { 1, 1, 1, 11, 17, 31, 111, 187, 483, 323, 307, 0 }; - static ulong[] dim315Kuo2Init = { 1, 1, 3, 1, 23, 33, 25, 27, 267, 231, 467, 0 }; - static ulong[] dim316Kuo2Init = { 1, 3, 1, 1, 29, 15, 1, 151, 369, 943, 1293, 0 }; - static ulong[] dim317Kuo2Init = { 1, 1, 1, 15, 31, 9, 1, 223, 7, 99, 1725, 0 }; - static ulong[] dim318Kuo2Init = { 1, 1, 1, 1, 13, 3, 103, 177, 61, 939, 1321, 0 }; - static ulong[] dim319Kuo2Init = { 1, 3, 3, 7, 29, 45, 63, 119, 467, 1011, 1687, 0 }; - static ulong[] dim320Kuo2Init = { 1, 3, 5, 13, 13, 51, 69, 113, 231, 807, 863, 0 }; - static ulong[] dim321Kuo2Init = { 1, 1, 1, 13, 13, 57, 121, 219, 77, 959, 1883, 0 }; - static ulong[] dim322Kuo2Init = { 1, 1, 3, 13, 25, 19, 83, 139, 31, 3, 367, 0 }; - static ulong[] dim323Kuo2Init = { 1, 3, 7, 13, 19, 49, 45, 47, 197, 253, 1769, 0 }; - static ulong[] dim324Kuo2Init = { 1, 3, 1, 5, 13, 59, 65, 23, 31, 127, 1693, 0 }; - static ulong[] dim325Kuo2Init = { 1, 1, 7, 5, 15, 33, 85, 59, 483, 87, 1109, 0 }; - static ulong[] dim326Kuo2Init = { 1, 1, 1, 13, 29, 39, 87, 109, 223, 927, 723, 0 }; - static ulong[] dim327Kuo2Init = { 1, 1, 7, 11, 29, 19, 13, 73, 479, 989, 767, 0 }; - static ulong[] dim328Kuo2Init = { 1, 3, 1, 15, 27, 33, 119, 237, 117, 181, 1719, 0 }; - static ulong[] dim329Kuo2Init = { 1, 1, 7, 9, 1, 55, 115, 91, 355, 21, 531, 0 }; - static ulong[] dim330Kuo2Init = { 1, 1, 5, 7, 29, 23, 41, 227, 455, 587, 523, 0 }; - static ulong[] dim331Kuo2Init = { 1, 3, 5, 9, 31, 21, 105, 139, 69, 907, 1195, 0 }; - static ulong[] dim332Kuo2Init = { 1, 1, 1, 13, 11, 63, 33, 161, 133, 493, 1055, 0 }; - static ulong[] dim333Kuo2Init = { 1, 1, 7, 15, 19, 37, 37, 145, 321, 781, 575, 0 }; - static ulong[] dim334Kuo2Init = { 1, 1, 5, 5, 29, 17, 109, 193, 271, 831, 915, 0 }; - static ulong[] dim335Kuo2Init = { 1, 3, 3, 11, 17, 63, 57, 245, 347, 647, 321, 0 }; - static ulong[] dim336Kuo2Init = { 1, 3, 5, 7, 15, 15, 45, 11, 383, 231, 267, 0 }; - static ulong[] dim337Kuo2Init = { 1, 3, 5, 13, 15, 45, 67, 135, 135, 247, 1261, 205, 0 }; - static ulong[] dim338Kuo2Init = { 1, 1, 7, 5, 13, 37, 63, 179, 43, 679, 1127, 779, 0 }; - static ulong[] dim339Kuo2Init = { 1, 3, 7, 15, 7, 11, 105, 207, 93, 127, 907, 3931, 0 }; - static ulong[] dim340Kuo2Init = { 1, 3, 7, 3, 29, 45, 53, 91, 97, 175, 1847, 1119, 0 }; - static ulong[] dim341Kuo2Init = { 1, 3, 7, 13, 29, 25, 49, 245, 39, 651, 1353, 481, 0 }; - static ulong[] dim342Kuo2Init = { 1, 1, 5, 13, 13, 49, 119, 85, 101, 361, 1163, 2693, 0 }; - static ulong[] dim343Kuo2Init = { 1, 1, 7, 11, 3, 13, 23, 95, 169, 1005, 1911, 849, 0 }; - static ulong[] dim344Kuo2Init = { 1, 3, 7, 15, 1, 25, 45, 111, 3, 683, 1383, 1387, 0 }; - static ulong[] dim345Kuo2Init = { 1, 3, 1, 3, 19, 37, 97, 183, 27, 971, 853, 255, 0 }; - static ulong[] dim346Kuo2Init = { 1, 3, 5, 7, 7, 61, 19, 163, 161, 921, 1561, 841, 0 }; - static ulong[] dim347Kuo2Init = { 1, 1, 3, 7, 3, 17, 43, 185, 231, 513, 1499, 695, 0 }; - static ulong[] dim348Kuo2Init = { 1, 3, 1, 13, 27, 17, 123, 155, 13, 873, 21, 1687, 0 }; - static ulong[] dim349Kuo2Init = { 1, 1, 5, 11, 7, 15, 83, 103, 489, 529, 1331, 3783, 0 }; - static ulong[] dim350Kuo2Init = { 1, 1, 7, 13, 11, 45, 11, 105, 341, 39, 1697, 2701, 0 }; - static ulong[] dim351Kuo2Init = { 1, 1, 1, 15, 1, 37, 119, 179, 471, 343, 927, 2469, 0 }; - static ulong[] dim352Kuo2Init = { 1, 1, 3, 9, 29, 57, 59, 133, 309, 587, 1775, 1811, 0 }; - static ulong[] dim353Kuo2Init = { 1, 1, 5, 15, 7, 51, 25, 151, 173, 961, 1449, 2215, 0 }; - static ulong[] dim354Kuo2Init = { 1, 3, 1, 5, 21, 49, 113, 199, 433, 563, 849, 2741, 0 }; - static ulong[] dim355Kuo2Init = { 1, 3, 7, 9, 19, 7, 3, 95, 259, 919, 1939, 2747, 0 }; - static ulong[] dim356Kuo2Init = { 1, 3, 5, 1, 19, 35, 83, 95, 359, 85, 677, 805, 0 }; - static ulong[] dim357Kuo2Init = { 1, 3, 1, 9, 19, 37, 63, 43, 251, 301, 1217, 3361, 0 }; - static ulong[] dim358Kuo2Init = { 1, 1, 3, 7, 5, 33, 45, 15, 191, 49, 1511, 157, 0 }; - static ulong[] dim359Kuo2Init = { 1, 3, 3, 3, 7, 3, 1, 241, 239, 229, 103, 215, 0 }; - static ulong[] dim360Kuo2Init = { 1, 3, 3, 3, 29, 27, 31, 61, 331, 847, 1699, 923, 0 }; - static ulong[] dim361Kuo2Init = { 1, 3, 1, 5, 11, 15, 81, 97, 411, 471, 1521, 73, 0 }; - static ulong[] dim362Kuo2Init = { 1, 1, 7, 7, 7, 17, 95, 245, 415, 31, 259, 1835, 0 }; - static ulong[] dim363Kuo2Init = { 1, 1, 1, 1, 23, 55, 27, 201, 21, 651, 1965, 1723, 0 }; - static ulong[] dim364Kuo2Init = { 1, 1, 7, 11, 19, 43, 33, 7, 1, 635, 1651, 1041, 0 }; - static ulong[] dim365Kuo2Init = { 1, 1, 1, 15, 29, 11, 31, 11, 29, 935, 715, 1115, 0 }; - static ulong[] dim366Kuo2Init = { 1, 1, 3, 3, 23, 51, 115, 55, 45, 135, 913, 3181, 0 }; - static ulong[] dim367Kuo2Init = { 1, 3, 7, 5, 15, 23, 39, 145, 51, 243, 1705, 3889, 0 }; - static ulong[] dim368Kuo2Init = { 1, 1, 7, 5, 27, 43, 63, 15, 365, 299, 1413, 1553, 0 }; - static ulong[] dim369Kuo2Init = { 1, 3, 1, 1, 19, 41, 123, 123, 331, 487, 2033, 1849, 0 }; - static ulong[] dim370Kuo2Init = { 1, 3, 5, 13, 21, 27, 91, 225, 387, 529, 1529, 1855, 0 }; - static ulong[] dim371Kuo2Init = { 1, 3, 5, 13, 23, 51, 27, 213, 55, 619, 773, 2037, 0 }; - static ulong[] dim372Kuo2Init = { 1, 3, 3, 1, 11, 9, 125, 205, 255, 813, 925, 2031, 0 }; - static ulong[] dim373Kuo2Init = { 1, 3, 5, 9, 23, 45, 43, 197, 475, 487, 79, 3649, 0 }; - static ulong[] dim374Kuo2Init = { 1, 1, 1, 1, 5, 53, 97, 243, 433, 75, 467, 1213, 0 }; - static ulong[] dim375Kuo2Init = { 1, 1, 5, 7, 5, 53, 15, 91, 405, 791, 1293, 1517, 0 }; - static ulong[] dim376Kuo2Init = { 1, 1, 1, 3, 17, 27, 19, 81, 227, 935, 1511, 3709, 0 }; - static ulong[] dim377Kuo2Init = { 1, 1, 5, 11, 17, 41, 125, 131, 295, 867, 1291, 2833, 0 }; - static ulong[] dim378Kuo2Init = { 1, 3, 7, 13, 3, 11, 63, 159, 341, 143, 1779, 1441, 0 }; - static ulong[] dim379Kuo2Init = { 1, 1, 7, 3, 29, 3, 103, 7, 145, 589, 723, 663, 0 }; - static ulong[] dim380Kuo2Init = { 1, 1, 7, 15, 5, 25, 105, 129, 277, 163, 349, 219, 0 }; - static ulong[] dim381Kuo2Init = { 1, 3, 1, 9, 21, 27, 127, 167, 285, 135, 1493, 3825, 0 }; - static ulong[] dim382Kuo2Init = { 1, 3, 1, 1, 7, 41, 95, 255, 273, 75, 383, 15, 0 }; - static ulong[] dim383Kuo2Init = { 1, 3, 5, 7, 21, 19, 67, 19, 465, 899, 1515, 425, 0 }; - static ulong[] dim384Kuo2Init = { 1, 1, 5, 15, 17, 45, 31, 227, 229, 271, 1169, 3915, 0 }; - static ulong[] dim385Kuo2Init = { 1, 3, 7, 11, 7, 23, 117, 195, 435, 171, 777, 3473, 0 }; - static ulong[] dim386Kuo2Init = { 1, 1, 3, 3, 27, 7, 99, 11, 361, 129, 717, 1241, 0 }; - static ulong[] dim387Kuo2Init = { 1, 1, 5, 9, 27, 1, 11, 115, 15, 561, 1989, 3857, 0 }; - static ulong[] dim388Kuo2Init = { 1, 1, 1, 5, 29, 55, 23, 83, 45, 427, 987, 3627, 0 }; - static ulong[] dim389Kuo2Init = { 1, 1, 1, 9, 5, 59, 119, 77, 297, 129, 1675, 2621, 0 }; - static ulong[] dim390Kuo2Init = { 1, 1, 5, 11, 27, 49, 69, 115, 453, 863, 811, 535, 0 }; - static ulong[] dim391Kuo2Init = { 1, 1, 5, 9, 21, 43, 109, 207, 5, 987, 1747, 47, 0 }; - static ulong[] dim392Kuo2Init = { 1, 3, 5, 5, 27, 31, 67, 133, 153, 137, 1167, 325, 0 }; - static ulong[] dim393Kuo2Init = { 1, 1, 3, 15, 9, 7, 51, 221, 317, 917, 1589, 1701, 0 }; - static ulong[] dim394Kuo2Init = { 1, 1, 3, 11, 7, 21, 3, 235, 237, 853, 1883, 2733, 0 }; - static ulong[] dim395Kuo2Init = { 1, 3, 7, 1, 9, 59, 69, 71, 191, 507, 1387, 2643, 0 }; - static ulong[] dim396Kuo2Init = { 1, 1, 1, 7, 13, 17, 59, 115, 401, 373, 431, 2895, 0 }; - static ulong[] dim397Kuo2Init = { 1, 3, 7, 7, 31, 23, 51, 173, 425, 823, 1375, 1675, 0 }; - static ulong[] dim398Kuo2Init = { 1, 3, 1, 13, 1, 57, 57, 203, 275, 825, 969, 1357, 0 }; - static ulong[] dim399Kuo2Init = { 1, 3, 1, 1, 31, 39, 125, 49, 11, 255, 373, 805, 0 }; - static ulong[] dim400Kuo2Init = { 1, 3, 7, 1, 7, 59, 43, 143, 447, 73, 1979, 3401, 0 }; - static ulong[] dim401Kuo2Init = { 1, 3, 7, 15, 29, 31, 11, 49, 241, 157, 1147, 1049, 0 }; - static ulong[] dim402Kuo2Init = { 1, 1, 3, 11, 19, 39, 41, 145, 219, 811, 425, 3561, 0 }; - static ulong[] dim403Kuo2Init = { 1, 1, 3, 13, 23, 49, 123, 3, 423, 661, 329, 3883, 0 }; - static ulong[] dim404Kuo2Init = { 1, 3, 1, 15, 21, 21, 5, 105, 19, 171, 1187, 1451, 0 }; - static ulong[] dim405Kuo2Init = { 1, 1, 7, 3, 27, 7, 31, 25, 339, 107, 827, 2813, 0 }; - static ulong[] dim406Kuo2Init = { 1, 1, 3, 3, 7, 9, 5, 241, 419, 19, 303, 1327, 0 }; - static ulong[] dim407Kuo2Init = { 1, 3, 3, 5, 1, 17, 105, 143, 345, 953, 857, 2241, 0 }; - static ulong[] dim408Kuo2Init = { 1, 3, 7, 5, 11, 63, 39, 49, 3, 601, 1491, 3095, 0 }; - static ulong[] dim409Kuo2Init = { 1, 1, 5, 1, 27, 35, 25, 231, 265, 27, 83, 511, 0 }; - static ulong[] dim410Kuo2Init = { 1, 3, 5, 3, 29, 1, 119, 39, 81, 551, 1709, 2105, 0 }; - static ulong[] dim411Kuo2Init = { 1, 3, 1, 5, 29, 31, 99, 93, 391, 691, 411, 637, 0 }; - static ulong[] dim412Kuo2Init = { 1, 3, 5, 1, 21, 53, 81, 171, 303, 987, 1235, 1559, 0 }; - static ulong[] dim413Kuo2Init = { 1, 3, 3, 5, 7, 63, 51, 89, 257, 489, 275, 2309, 0 }; - static ulong[] dim414Kuo2Init = { 1, 3, 1, 5, 5, 33, 25, 55, 241, 259, 1213, 2409, 0 }; - static ulong[] dim415Kuo2Init = { 1, 3, 7, 3, 11, 57, 85, 209, 329, 611, 45, 1183, 0 }; - static ulong[] dim416Kuo2Init = { 1, 3, 3, 15, 3, 15, 31, 27, 363, 291, 1063, 229, 0 }; - static ulong[] dim417Kuo2Init = { 1, 3, 1, 1, 1, 3, 47, 189, 287, 337, 879, 1881, 0 }; - static ulong[] dim418Kuo2Init = { 1, 1, 3, 5, 9, 11, 65, 237, 499, 431, 1677, 2503, 0 }; - static ulong[] dim419Kuo2Init = { 1, 3, 1, 15, 3, 17, 101, 23, 367, 643, 1485, 1625, 0 }; - static ulong[] dim420Kuo2Init = { 1, 3, 3, 13, 9, 3, 87, 11, 137, 835, 1095, 891, 0 }; - static ulong[] dim421Kuo2Init = { 1, 1, 5, 7, 15, 3, 49, 253, 29, 159, 315, 2133, 0 }; - static ulong[] dim422Kuo2Init = { 1, 1, 3, 15, 11, 11, 17, 37, 287, 35, 813, 2715, 0 }; - static ulong[] dim423Kuo2Init = { 1, 1, 1, 9, 3, 51, 57, 205, 385, 157, 811, 627, 0 }; - static ulong[] dim424Kuo2Init = { 1, 3, 7, 15, 13, 33, 65, 117, 339, 805, 19, 3775, 0 }; - static ulong[] dim425Kuo2Init = { 1, 3, 5, 5, 9, 5, 25, 177, 469, 599, 1527, 3799, 0 }; - static ulong[] dim426Kuo2Init = { 1, 1, 3, 9, 1, 45, 65, 69, 121, 263, 1355, 1205, 0 }; - static ulong[] dim427Kuo2Init = { 1, 1, 3, 3, 3, 33, 121, 163, 95, 137, 1393, 4017, 0 }; - static ulong[] dim428Kuo2Init = { 1, 3, 7, 7, 19, 27, 17, 239, 253, 305, 1929, 1725, 0 }; - static ulong[] dim429Kuo2Init = { 1, 3, 5, 7, 5, 19, 115, 95, 93, 87, 1379, 3295, 0 }; - static ulong[] dim430Kuo2Init = { 1, 3, 3, 3, 5, 51, 7, 171, 153, 329, 1627, 3503, 0 }; - static ulong[] dim431Kuo2Init = { 1, 1, 5, 9, 27, 15, 91, 99, 433, 689, 1551, 1827, 0 }; - static ulong[] dim432Kuo2Init = { 1, 3, 3, 11, 17, 35, 29, 203, 171, 513, 771, 2011, 0 }; - static ulong[] dim433Kuo2Init = { 1, 3, 5, 11, 29, 57, 69, 239, 87, 477, 187, 4079, 0 }; - static ulong[] dim434Kuo2Init = { 1, 1, 1, 11, 9, 25, 37, 41, 113, 339, 1347, 3475, 0 }; - static ulong[] dim435Kuo2Init = { 1, 3, 1, 15, 17, 17, 53, 17, 327, 123, 915, 655, 0 }; - static ulong[] dim436Kuo2Init = { 1, 1, 5, 13, 29, 3, 85, 173, 139, 51, 929, 3407, 0 }; - static ulong[] dim437Kuo2Init = { 1, 3, 5, 3, 25, 13, 19, 91, 285, 309, 105, 2331, 0 }; - static ulong[] dim438Kuo2Init = { 1, 3, 7, 7, 13, 23, 103, 7, 435, 571, 731, 431, 0 }; - static ulong[] dim439Kuo2Init = { 1, 1, 3, 11, 23, 3, 29, 25, 369, 941, 2031, 2311, 0 }; - static ulong[] dim440Kuo2Init = { 1, 3, 5, 3, 11, 49, 69, 61, 267, 241, 1221, 1533, 0 }; - static ulong[] dim441Kuo2Init = { 1, 3, 3, 5, 17, 43, 27, 191, 201, 653, 933, 2571, 0 }; - static ulong[] dim442Kuo2Init = { 1, 1, 1, 13, 1, 7, 117, 179, 61, 1003, 379, 2359, 0 }; - static ulong[] dim443Kuo2Init = { 1, 3, 5, 15, 9, 53, 23, 217, 237, 647, 377, 677, 0 }; - static ulong[] dim444Kuo2Init = { 1, 1, 1, 1, 15, 55, 73, 1, 119, 679, 203, 309, 0 }; - static ulong[] dim445Kuo2Init = { 1, 1, 5, 15, 11, 13, 15, 211, 105, 655, 739, 1439, 0 }; - static ulong[] dim446Kuo2Init = { 1, 3, 5, 5, 9, 41, 87, 237, 65, 837, 1127, 2539, 0 }; - static ulong[] dim447Kuo2Init = { 1, 1, 3, 9, 3, 57, 23, 55, 359, 909, 969, 1437, 0 }; - static ulong[] dim448Kuo2Init = { 1, 1, 1, 9, 23, 57, 23, 127, 139, 961, 1985, 2785, 0 }; - static ulong[] dim449Kuo2Init = { 1, 3, 7, 1, 31, 7, 65, 215, 305, 245, 971, 139, 0 }; - static ulong[] dim450Kuo2Init = { 1, 3, 3, 11, 3, 3, 29, 173, 189, 807, 219, 2807, 0 }; - static ulong[] dim451Kuo2Init = { 1, 3, 5, 7, 25, 39, 7, 157, 397, 773, 461, 3051, 0 }; - static ulong[] dim452Kuo2Init = { 1, 3, 7, 7, 9, 7, 33, 19, 127, 177, 189, 1247, 0 }; - static ulong[] dim453Kuo2Init = { 1, 3, 5, 3, 5, 13, 77, 219, 339, 969, 1193, 2545, 0 }; - static ulong[] dim454Kuo2Init = { 1, 3, 3, 13, 29, 45, 123, 9, 335, 985, 1923, 2449, 0 }; - static ulong[] dim455Kuo2Init = { 1, 3, 1, 9, 7, 43, 29, 83, 153, 381, 1849, 2563, 0 }; - static ulong[] dim456Kuo2Init = { 1, 3, 3, 1, 29, 31, 107, 151, 171, 137, 1749, 1541, 0 }; - static ulong[] dim457Kuo2Init = { 1, 3, 7, 1, 13, 53, 27, 119, 295, 879, 1113, 1293, 0 }; - static ulong[] dim458Kuo2Init = { 1, 1, 7, 9, 19, 25, 127, 215, 271, 521, 1093, 1595, 0 }; - static ulong[] dim459Kuo2Init = { 1, 1, 5, 11, 11, 9, 35, 55, 447, 513, 1415, 2427, 0 }; - static ulong[] dim460Kuo2Init = { 1, 3, 1, 5, 19, 19, 19, 111, 73, 895, 1879, 3679, 0 }; - static ulong[] dim461Kuo2Init = { 1, 1, 7, 13, 13, 55, 65, 131, 461, 775, 1817, 1795, 0 }; - static ulong[] dim462Kuo2Init = { 1, 3, 7, 9, 31, 41, 119, 75, 419, 319, 1463, 3491, 0 }; - static ulong[] dim463Kuo2Init = { 1, 1, 7, 7, 27, 33, 71, 223, 381, 181, 541, 1695, 0 }; - static ulong[] dim464Kuo2Init = { 1, 3, 7, 5, 29, 53, 109, 109, 35, 607, 559, 4045, 0 }; - static ulong[] dim465Kuo2Init = { 1, 3, 1, 13, 11, 9, 9, 91, 85, 41, 1155, 3989, 0 }; - static ulong[] dim466Kuo2Init = { 1, 1, 3, 15, 23, 13, 3, 243, 443, 671, 1461, 3329, 0 }; - static ulong[] dim467Kuo2Init = { 1, 1, 1, 1, 27, 25, 37, 153, 299, 51, 371, 1269, 0 }; - static ulong[] dim468Kuo2Init = { 1, 3, 7, 11, 13, 51, 85, 177, 489, 867, 779, 3423, 0 }; - static ulong[] dim469Kuo2Init = { 1, 1, 7, 1, 25, 51, 105, 117, 105, 743, 67, 2889, 0 }; - static ulong[] dim470Kuo2Init = { 1, 1, 3, 3, 29, 31, 65, 11, 87, 647, 193, 1229, 0 }; - static ulong[] dim471Kuo2Init = { 1, 3, 5, 9, 19, 19, 19, 193, 441, 947, 1385, 1321, 0 }; - static ulong[] dim472Kuo2Init = { 1, 1, 1, 9, 9, 31, 109, 77, 449, 775, 187, 2609, 0 }; - static ulong[] dim473Kuo2Init = { 1, 1, 1, 13, 31, 57, 121, 251, 9, 673, 473, 755, 0 }; - static ulong[] dim474Kuo2Init = { 1, 3, 3, 7, 25, 21, 93, 183, 277, 167, 1305, 897, 0 }; - static ulong[] dim475Kuo2Init = { 1, 1, 5, 5, 29, 15, 29, 67, 193, 525, 851, 2287, 0 }; - static ulong[] dim476Kuo2Init = { 1, 1, 5, 9, 7, 53, 117, 203, 89, 221, 235, 2783, 0 }; - static ulong[] dim477Kuo2Init = { 1, 3, 5, 13, 7, 25, 69, 25, 329, 151, 1721, 1279, 0 }; - static ulong[] dim478Kuo2Init = { 1, 1, 1, 7, 15, 9, 119, 75, 95, 297, 1149, 1385, 0 }; - static ulong[] dim479Kuo2Init = { 1, 3, 3, 15, 23, 1, 109, 81, 249, 189, 737, 1809, 0 }; - static ulong[] dim480Kuo2Init = { 1, 1, 7, 5, 29, 53, 77, 79, 339, 625, 1131, 2539, 0 }; - static ulong[] dim481Kuo2Init = { 1, 1, 7, 15, 23, 35, 39, 25, 287, 321, 151, 193, 6637, 0 }; - static ulong[] dim482Kuo2Init = { 1, 3, 5, 9, 15, 31, 31, 111, 393, 97, 407, 1087, 1413, 0 }; - static ulong[] dim483Kuo2Init = { 1, 1, 1, 13, 21, 63, 71, 193, 443, 541, 1989, 2979, 7087, 0 }; - static ulong[] dim484Kuo2Init = { 1, 3, 3, 1, 11, 41, 19, 219, 497, 273, 1293, 2233, 2967, 0 }; - static ulong[] dim485Kuo2Init = { 1, 1, 5, 7, 23, 15, 119, 245, 223, 773, 1261, 1623, 8067, 0 }; - static ulong[] dim486Kuo2Init = { 1, 1, 1, 15, 3, 39, 39, 11, 141, 347, 1473, 3503, 3595, 0 }; - static ulong[] dim487Kuo2Init = { 1, 1, 1, 5, 27, 15, 81, 159, 279, 907, 143, 3195, 7127, 0 }; - static ulong[] dim488Kuo2Init = { 1, 1, 1, 9, 27, 29, 109, 29, 147, 255, 1851, 677, 2883, 0 }; - static ulong[] dim489Kuo2Init = { 1, 1, 5, 1, 1, 23, 3, 107, 9, 757, 319, 949, 3887, 0 }; - static ulong[] dim490Kuo2Init = { 1, 1, 7, 1, 13, 41, 21, 9, 53, 179, 1273, 17, 5195, 0 }; - static ulong[] dim491Kuo2Init = { 1, 3, 3, 15, 9, 41, 121, 13, 245, 415, 2041, 3813, 6807, 0 }; - static ulong[] dim492Kuo2Init = { 1, 3, 5, 13, 7, 5, 43, 137, 191, 855, 735, 3711, 2459, 0 }; - static ulong[] dim493Kuo2Init = { 1, 3, 3, 13, 15, 53, 13, 245, 217, 159, 271, 261, 7383, 0 }; - static ulong[] dim494Kuo2Init = { 1, 3, 1, 9, 1, 39, 79, 73, 349, 367, 51, 155, 53, 0 }; - static ulong[] dim495Kuo2Init = { 1, 1, 7, 5, 11, 19, 99, 131, 217, 729, 1481, 4015, 6109, 0 }; - static ulong[] dim496Kuo2Init = { 1, 3, 1, 3, 9, 7, 55, 119, 285, 803, 427, 3755, 3153, 0 }; - static ulong[] dim497Kuo2Init = { 1, 1, 7, 13, 25, 3, 111, 51, 1, 995, 657, 1551, 3633, 0 }; - static ulong[] dim498Kuo2Init = { 1, 3, 3, 1, 29, 49, 15, 219, 295, 335, 191, 611, 1151, 0 }; - static ulong[] dim499Kuo2Init = { 1, 3, 3, 3, 5, 37, 115, 199, 143, 11, 1487, 3841, 4669, 0 }; - static ulong[] dim500Kuo2Init = { 1, 1, 3, 5, 23, 33, 67, 51, 433, 351, 1467, 2935, 4135, 0 }; - static ulong[] dim501Kuo2Init = { 1, 3, 3, 15, 3, 57, 55, 7, 487, 983, 1481, 799, 6141, 0 }; - static ulong[] dim502Kuo2Init = { 1, 3, 5, 3, 23, 1, 37, 117, 131, 55, 449, 637, 693, 0 }; - static ulong[] dim503Kuo2Init = { 1, 3, 1, 9, 11, 7, 43, 149, 463, 349, 1773, 643, 765, 0 }; - static ulong[] dim504Kuo2Init = { 1, 3, 1, 1, 25, 39, 1, 33, 209, 131, 157, 2695, 623, 0 }; - static ulong[] dim505Kuo2Init = { 1, 1, 1, 7, 15, 41, 105, 51, 465, 453, 1091, 905, 4831, 0 }; - static ulong[] dim506Kuo2Init = { 1, 3, 7, 9, 1, 39, 45, 117, 481, 481, 87, 1869, 7063, 0 }; - static ulong[] dim507Kuo2Init = { 1, 1, 7, 1, 27, 1, 87, 75, 295, 287, 163, 911, 1725, 0 }; - static ulong[] dim508Kuo2Init = { 1, 3, 3, 9, 31, 61, 75, 53, 63, 179, 1941, 555, 1303, 0 }; - static ulong[] dim509Kuo2Init = { 1, 3, 3, 9, 31, 37, 9, 51, 381, 639, 595, 731, 7531, 0 }; - static ulong[] dim510Kuo2Init = { 1, 3, 1, 1, 3, 25, 59, 19, 187, 235, 173, 893, 4845, 0 }; - static ulong[] dim511Kuo2Init = { 1, 1, 7, 7, 1, 23, 9, 9, 493, 643, 53, 179, 6993, 0 }; - static ulong[] dim512Kuo2Init = { 1, 1, 1, 1, 25, 55, 81, 63, 67, 967, 957, 1025, 8033, 0 }; - static ulong[] dim513Kuo2Init = { 1, 3, 1, 7, 5, 43, 67, 127, 103, 241, 77, 43, 5173, 0 }; - static ulong[] dim514Kuo2Init = { 1, 1, 3, 7, 9, 25, 17, 231, 315, 699, 787, 591, 7257, 0 }; - static ulong[] dim515Kuo2Init = { 1, 3, 1, 15, 21, 19, 7, 179, 335, 701, 323, 121, 4733, 0 }; - static ulong[] dim516Kuo2Init = { 1, 1, 3, 7, 11, 59, 75, 147, 391, 535, 1841, 3025, 5621, 0 }; - static ulong[] dim517Kuo2Init = { 1, 1, 3, 7, 21, 25, 101, 71, 195, 495, 1241, 2229, 2865, 0 }; - static ulong[] dim518Kuo2Init = { 1, 3, 1, 5, 19, 55, 93, 41, 287, 787, 929, 3161, 4247, 0 }; - static ulong[] dim519Kuo2Init = { 1, 3, 3, 11, 25, 31, 79, 225, 189, 187, 595, 465, 7169, 0 }; - static ulong[] dim520Kuo2Init = { 1, 1, 3, 13, 25, 37, 7, 87, 511, 451, 1681, 1911, 5269, 0 }; - static ulong[] dim521Kuo2Init = { 1, 3, 3, 13, 21, 31, 117, 73, 391, 127, 1201, 189, 6621, 0 }; - static ulong[] dim522Kuo2Init = { 1, 3, 1, 7, 9, 49, 77, 91, 197, 889, 119, 1335, 4833, 0 }; - static ulong[] dim523Kuo2Init = { 1, 1, 7, 3, 11, 61, 103, 19, 345, 937, 1393, 963, 2283, 0 }; - static ulong[] dim524Kuo2Init = { 1, 1, 1, 9, 3, 3, 113, 189, 383, 727, 781, 3515, 5045, 0 }; - static ulong[] dim525Kuo2Init = { 1, 1, 7, 15, 27, 45, 65, 137, 5, 185, 1561, 2063, 761, 0 }; - static ulong[] dim526Kuo2Init = { 1, 1, 3, 9, 17, 5, 71, 209, 387, 693, 773, 2105, 1265, 0 }; - static ulong[] dim527Kuo2Init = { 1, 1, 3, 11, 9, 49, 53, 53, 7, 5, 543, 1605, 265, 0 }; - static ulong[] dim528Kuo2Init = { 1, 3, 3, 3, 23, 21, 27, 187, 495, 101, 517, 853, 2801, 0 }; - static ulong[] dim529Kuo2Init = { 1, 3, 5, 1, 7, 61, 47, 113, 375, 307, 255, 3341, 3663, 0 }; - static ulong[] dim530Kuo2Init = { 1, 1, 1, 1, 19, 9, 33, 235, 413, 999, 1889, 3633, 745, 0 }; - static ulong[] dim531Kuo2Init = { 1, 1, 1, 7, 27, 27, 19, 57, 1, 639, 831, 3481, 395, 0 }; - static ulong[] dim532Kuo2Init = { 1, 3, 3, 5, 19, 55, 27, 215, 319, 855, 1597, 1539, 4359, 0 }; - static ulong[] dim533Kuo2Init = { 1, 3, 7, 11, 3, 35, 5, 3, 341, 795, 315, 935, 2417, 0 }; - static ulong[] dim534Kuo2Init = { 1, 1, 1, 3, 25, 55, 53, 143, 361, 203, 863, 2491, 4701, 0 }; - static ulong[] dim535Kuo2Init = { 1, 1, 5, 9, 19, 9, 29, 153, 387, 373, 647, 2825, 1391, 0 }; - static ulong[] dim536Kuo2Init = { 1, 1, 3, 9, 1, 37, 103, 17, 347, 577, 181, 2863, 6525, 0 }; - static ulong[] dim537Kuo2Init = { 1, 1, 1, 3, 17, 19, 41, 61, 49, 75, 1243, 33, 7725, 0 }; - static ulong[] dim538Kuo2Init = { 1, 3, 1, 9, 7, 23, 107, 227, 225, 139, 451, 1303, 5657, 0 }; - static ulong[] dim539Kuo2Init = { 1, 3, 5, 11, 27, 37, 95, 195, 261, 827, 817, 2555, 8189, 0 }; - static ulong[] dim540Kuo2Init = { 1, 3, 1, 11, 13, 17, 73, 113, 287, 73, 977, 2815, 4281, 0 }; - static ulong[] dim541Kuo2Init = { 1, 1, 5, 7, 23, 7, 103, 41, 237, 745, 1645, 2041, 6063, 0 }; - static ulong[] dim542Kuo2Init = { 1, 1, 3, 15, 17, 1, 63, 115, 303, 175, 1511, 3027, 1265, 0 }; - static ulong[] dim543Kuo2Init = { 1, 3, 5, 3, 29, 57, 1, 51, 127, 539, 1171, 3567, 6409, 0 }; - static ulong[] dim544Kuo2Init = { 1, 1, 1, 9, 29, 63, 85, 127, 375, 453, 539, 563, 5709, 0 }; - static ulong[] dim545Kuo2Init = { 1, 1, 1, 7, 29, 31, 109, 159, 15, 621, 1593, 3793, 4503, 0 }; - static ulong[] dim546Kuo2Init = { 1, 1, 3, 3, 17, 27, 59, 9, 263, 705, 909, 643, 4967, 0 }; - static ulong[] dim547Kuo2Init = { 1, 3, 5, 7, 23, 13, 37, 179, 439, 77, 1055, 3129, 371, 0 }; - static ulong[] dim548Kuo2Init = { 1, 3, 1, 11, 25, 1, 123, 109, 27, 393, 1729, 3597, 5197, 0 }; - static ulong[] dim549Kuo2Init = { 1, 3, 5, 11, 15, 9, 25, 19, 1, 927, 39, 925, 87, 0 }; - static ulong[] dim550Kuo2Init = { 1, 3, 5, 1, 9, 7, 85, 95, 497, 487, 311, 2109, 259, 0 }; - static ulong[] dim551Kuo2Init = { 1, 3, 5, 1, 5, 59, 75, 243, 179, 975, 187, 415, 1161, 0 }; - static ulong[] dim552Kuo2Init = { 1, 3, 3, 13, 11, 61, 109, 129, 71, 917, 523, 1189, 4857, 0 }; - static ulong[] dim553Kuo2Init = { 1, 3, 1, 1, 3, 57, 15, 79, 265, 839, 559, 729, 2737, 0 }; - static ulong[] dim554Kuo2Init = { 1, 1, 7, 9, 21, 45, 69, 245, 331, 197, 1947, 3145, 6927, 0 }; - static ulong[] dim555Kuo2Init = { 1, 3, 7, 7, 31, 41, 73, 59, 93, 565, 1885, 3803, 7013, 0 }; - static ulong[] dim556Kuo2Init = { 1, 1, 1, 13, 23, 19, 107, 77, 449, 965, 99, 1215, 4699, 0 }; - static ulong[] dim557Kuo2Init = { 1, 1, 3, 13, 11, 3, 37, 209, 221, 197, 1913, 631, 1621, 0 }; - static ulong[] dim558Kuo2Init = { 1, 1, 5, 9, 27, 51, 61, 249, 269, 507, 1005, 2471, 4621, 0 }; - static ulong[] dim559Kuo2Init = { 1, 3, 5, 1, 3, 49, 69, 227, 289, 261, 1103, 389, 4883, 0 }; - static ulong[] dim560Kuo2Init = { 1, 1, 5, 3, 29, 35, 43, 167, 451, 1017, 865, 1507, 7387, 0 }; - static ulong[] dim561Kuo2Init = { 1, 1, 3, 15, 13, 1, 53, 9, 23, 581, 627, 3823, 6767, 0 }; - static ulong[] dim562Kuo2Init = { 1, 3, 1, 7, 3, 21, 115, 73, 353, 725, 1971, 1623, 7359, 0 }; - static ulong[] dim563Kuo2Init = { 1, 1, 3, 5, 17, 15, 37, 219, 187, 699, 1463, 1563, 2785, 0 }; - static ulong[] dim564Kuo2Init = { 1, 3, 7, 13, 11, 43, 9, 49, 125, 681, 499, 2127, 6613, 0 }; - static ulong[] dim565Kuo2Init = { 1, 3, 5, 11, 5, 21, 115, 227, 305, 247, 1947, 853, 5357, 0 }; - static ulong[] dim566Kuo2Init = { 1, 3, 1, 9, 29, 37, 1, 181, 427, 435, 1757, 1535, 4383, 0 }; - static ulong[] dim567Kuo2Init = { 1, 3, 1, 15, 15, 41, 123, 7, 367, 767, 777, 3455, 7739, 0 }; - static ulong[] dim568Kuo2Init = { 1, 1, 5, 9, 13, 3, 5, 79, 3, 121, 1113, 1731, 501, 0 }; - static ulong[] dim569Kuo2Init = { 1, 1, 3, 13, 1, 13, 127, 215, 329, 381, 205, 2391, 581, 0 }; - static ulong[] dim570Kuo2Init = { 1, 1, 3, 7, 7, 19, 9, 23, 463, 455, 1921, 763, 5077, 0 }; - static ulong[] dim571Kuo2Init = { 1, 1, 3, 3, 13, 23, 65, 7, 337, 603, 1243, 2161, 5883, 0 }; - static ulong[] dim572Kuo2Init = { 1, 3, 5, 1, 15, 23, 73, 151, 243, 847, 1189, 1663, 2011, 0 }; - static ulong[] dim573Kuo2Init = { 1, 1, 7, 7, 11, 17, 91, 219, 127, 317, 1807, 1369, 7433, 0 }; - static ulong[] dim574Kuo2Init = { 1, 3, 5, 9, 31, 49, 65, 47, 11, 541, 55, 2743, 4987, 0 }; - static ulong[] dim575Kuo2Init = { 1, 3, 7, 13, 23, 23, 51, 129, 111, 319, 1195, 1593, 4407, 0 }; - static ulong[] dim576Kuo2Init = { 1, 3, 1, 7, 21, 25, 35, 187, 409, 981, 293, 873, 7447, 0 }; - static ulong[] dim577Kuo2Init = { 1, 3, 1, 9, 3, 11, 25, 75, 347, 907, 1645, 2997, 5953, 0 }; - static ulong[] dim578Kuo2Init = { 1, 3, 7, 7, 25, 49, 99, 37, 45, 81, 95, 2637, 1337, 0 }; - static ulong[] dim579Kuo2Init = { 1, 3, 5, 3, 29, 35, 85, 167, 503, 257, 1101, 2647, 1469, 0 }; - static ulong[] dim580Kuo2Init = { 1, 3, 5, 1, 27, 17, 93, 197, 485, 899, 1201, 3633, 1289, 0 }; - static ulong[] dim581Kuo2Init = { 1, 3, 1, 7, 5, 17, 53, 167, 353, 1023, 1063, 2221, 3635, 0 }; - static ulong[] dim582Kuo2Init = { 1, 1, 5, 11, 9, 43, 123, 241, 77, 657, 1789, 235, 2105, 0 }; - static ulong[] dim583Kuo2Init = { 1, 1, 5, 9, 9, 53, 109, 185, 443, 803, 115, 2079, 7839, 0 }; - static ulong[] dim584Kuo2Init = { 1, 1, 1, 13, 29, 29, 35, 235, 253, 529, 153, 1613, 6723, 0 }; - static ulong[] dim585Kuo2Init = { 1, 3, 1, 13, 11, 31, 81, 177, 135, 659, 605, 1253, 5077, 0 }; - static ulong[] dim586Kuo2Init = { 1, 3, 5, 3, 25, 53, 87, 183, 285, 639, 657, 2307, 5477, 0 }; - static ulong[] dim587Kuo2Init = { 1, 1, 7, 7, 9, 35, 31, 83, 165, 735, 1445, 3935, 515, 0 }; - static ulong[] dim588Kuo2Init = { 1, 3, 5, 1, 13, 59, 99, 191, 187, 375, 959, 1145, 1487, 0 }; - static ulong[] dim589Kuo2Init = { 1, 3, 7, 3, 1, 1, 127, 127, 101, 583, 121, 2879, 63, 0 }; - static ulong[] dim590Kuo2Init = { 1, 3, 7, 11, 13, 1, 125, 81, 31, 177, 107, 2339, 755, 0 }; - static ulong[] dim591Kuo2Init = { 1, 1, 3, 13, 7, 33, 9, 247, 395, 255, 1817, 1509, 5401, 0 }; - static ulong[] dim592Kuo2Init = { 1, 1, 7, 7, 27, 19, 87, 167, 425, 1019, 1419, 4025, 5483, 0 }; - static ulong[] dim593Kuo2Init = { 1, 3, 7, 7, 5, 49, 97, 65, 355, 207, 323, 2367, 171, 0 }; - static ulong[] dim594Kuo2Init = { 1, 3, 7, 5, 23, 5, 125, 131, 115, 585, 1533, 3489, 507, 0 }; - static ulong[] dim595Kuo2Init = { 1, 3, 3, 15, 29, 51, 79, 239, 289, 909, 1339, 857, 1661, 0 }; - static ulong[] dim596Kuo2Init = { 1, 3, 5, 11, 23, 1, 65, 123, 439, 349, 1593, 1913, 433, 0 }; - static ulong[] dim597Kuo2Init = { 1, 1, 7, 5, 27, 45, 59, 33, 375, 553, 1955, 731, 4335, 0 }; - static ulong[] dim598Kuo2Init = { 1, 1, 3, 7, 25, 63, 51, 183, 67, 783, 885, 3385, 7109, 0 }; - static ulong[] dim599Kuo2Init = { 1, 3, 7, 9, 3, 43, 105, 145, 123, 503, 203, 1029, 6713, 0 }; - static ulong[] dim600Kuo2Init = { 1, 3, 7, 7, 11, 49, 113, 69, 489, 649, 1393, 1475, 6663, 0 }; - static ulong[] dim601Kuo2Init = { 1, 1, 5, 11, 13, 5, 105, 21, 451, 137, 2029, 1459, 7981, 0 }; - static ulong[] dim602Kuo2Init = { 1, 1, 7, 5, 7, 17, 3, 213, 255, 867, 89, 2437, 1151, 0 }; - static ulong[] dim603Kuo2Init = { 1, 1, 7, 9, 19, 23, 115, 161, 257, 419, 1133, 1291, 243, 0 }; - static ulong[] dim604Kuo2Init = { 1, 3, 5, 7, 27, 45, 23, 157, 371, 219, 1001, 343, 2419, 0 }; - static ulong[] dim605Kuo2Init = { 1, 3, 1, 1, 21, 59, 91, 153, 19, 469, 1923, 2439, 3837, 0 }; - static ulong[] dim606Kuo2Init = { 1, 3, 7, 3, 23, 29, 57, 201, 209, 249, 63, 2929, 2719, 0 }; - static ulong[] dim607Kuo2Init = { 1, 1, 5, 3, 11, 3, 75, 91, 157, 557, 1775, 387, 803, 0 }; - static ulong[] dim608Kuo2Init = { 1, 3, 3, 3, 27, 57, 69, 135, 317, 897, 1417, 1853, 747, 0 }; - static ulong[] dim609Kuo2Init = { 1, 1, 7, 11, 15, 19, 115, 219, 57, 925, 1869, 609, 1631, 0 }; - static ulong[] dim610Kuo2Init = { 1, 1, 1, 11, 29, 21, 45, 19, 91, 271, 971, 2569, 423, 0 }; - static ulong[] dim611Kuo2Init = { 1, 3, 3, 13, 5, 9, 5, 101, 147, 777, 1647, 457, 4053, 0 }; - static ulong[] dim612Kuo2Init = { 1, 1, 5, 9, 9, 25, 13, 175, 53, 467, 1555, 2969, 1669, 0 }; - static ulong[] dim613Kuo2Init = { 1, 1, 1, 7, 21, 49, 1, 49, 317, 505, 1495, 1053, 2293, 0 }; - static ulong[] dim614Kuo2Init = { 1, 1, 1, 3, 15, 43, 91, 207, 211, 725, 2039, 803, 4029, 0 }; - static ulong[] dim615Kuo2Init = { 1, 1, 7, 13, 17, 45, 39, 125, 129, 169, 47, 2105, 1749, 0 }; - static ulong[] dim616Kuo2Init = { 1, 3, 7, 11, 19, 13, 5, 105, 203, 611, 147, 2291, 1823, 0 }; - static ulong[] dim617Kuo2Init = { 1, 1, 5, 1, 5, 15, 15, 35, 33, 467, 59, 2435, 3141, 0 }; - static ulong[] dim618Kuo2Init = { 1, 3, 1, 5, 29, 43, 35, 3, 173, 619, 1595, 347, 2513, 0 }; - static ulong[] dim619Kuo2Init = { 1, 3, 3, 1, 23, 37, 3, 123, 301, 403, 1603, 2345, 1031, 0 }; - static ulong[] dim620Kuo2Init = { 1, 3, 5, 9, 23, 55, 23, 19, 497, 501, 99, 1925, 6243, 0 }; - static ulong[] dim621Kuo2Init = { 1, 3, 5, 1, 21, 37, 83, 59, 285, 107, 1909, 3647, 8041, 0 }; - static ulong[] dim622Kuo2Init = { 1, 3, 5, 1, 7, 11, 91, 1, 357, 643, 1319, 2895, 2193, 0 }; - static ulong[] dim623Kuo2Init = { 1, 1, 5, 9, 27, 29, 25, 125, 433, 525, 1511, 585, 5263, 0 }; - static ulong[] dim624Kuo2Init = { 1, 3, 1, 11, 13, 49, 79, 37, 165, 923, 749, 2207, 4673, 0 }; - static ulong[] dim625Kuo2Init = { 1, 1, 5, 9, 29, 37, 51, 3, 133, 859, 153, 1199, 2269, 0 }; - static ulong[] dim626Kuo2Init = { 1, 1, 7, 5, 9, 57, 101, 231, 383, 245, 1997, 2661, 6069, 0 }; - static ulong[] dim627Kuo2Init = { 1, 1, 7, 7, 25, 61, 25, 185, 247, 509, 1953, 3309, 4879, 0 }; - static ulong[] dim628Kuo2Init = { 1, 1, 3, 7, 19, 61, 95, 105, 355, 219, 103, 249, 579, 0 }; - static ulong[] dim629Kuo2Init = { 1, 3, 7, 15, 7, 3, 51, 143, 273, 203, 353, 1587, 2239, 0 }; - static ulong[] dim630Kuo2Init = { 1, 3, 3, 9, 27, 47, 123, 185, 337, 183, 983, 2313, 815, 0 }; - static ulong[] dim631Kuo2Init = { 1, 1, 5, 15, 19, 19, 3, 199, 247, 151, 1911, 301, 5311, 0 }; - static ulong[] dim632Kuo2Init = { 1, 1, 1, 3, 7, 63, 61, 151, 297, 541, 1457, 2945, 5703, 0 }; - static ulong[] dim633Kuo2Init = { 1, 3, 7, 5, 31, 1, 109, 179, 197, 109, 695, 2429, 3483, 0 }; - static ulong[] dim634Kuo2Init = { 1, 3, 7, 1, 27, 25, 27, 113, 455, 655, 1813, 2341, 4785, 0 }; - static ulong[] dim635Kuo2Init = { 1, 1, 5, 15, 9, 47, 105, 15, 75, 901, 1539, 2599, 1013, 0 }; - static ulong[] dim636Kuo2Init = { 1, 3, 1, 11, 17, 17, 29, 219, 121, 383, 1575, 3153, 6151, 0 }; - static ulong[] dim637Kuo2Init = { 1, 1, 1, 3, 29, 51, 35, 95, 89, 279, 1255, 2967, 455, 0 }; - static ulong[] dim638Kuo2Init = { 1, 3, 5, 15, 3, 3, 15, 181, 91, 169, 1703, 777, 6539, 0 }; - static ulong[] dim639Kuo2Init = { 1, 1, 3, 13, 15, 29, 115, 225, 179, 271, 737, 2425, 3149, 0 }; - static ulong[] dim640Kuo2Init = { 1, 3, 7, 3, 13, 29, 1, 169, 35, 145, 725, 3679, 2593, 0 }; - static ulong[] dim641Kuo2Init = { 1, 1, 7, 9, 11, 1, 51, 65, 283, 791, 449, 1387, 7347, 0 }; - static ulong[] dim642Kuo2Init = { 1, 3, 1, 13, 21, 23, 79, 207, 425, 839, 737, 243, 6761, 0 }; - static ulong[] dim643Kuo2Init = { 1, 3, 3, 5, 11, 25, 93, 119, 245, 539, 405, 1925, 1595, 0 }; - static ulong[] dim644Kuo2Init = { 1, 3, 7, 15, 5, 19, 97, 225, 471, 801, 379, 923, 1961, 0 }; - static ulong[] dim645Kuo2Init = { 1, 3, 7, 15, 25, 49, 41, 237, 11, 983, 1889, 3947, 2579, 0 }; - static ulong[] dim646Kuo2Init = { 1, 3, 5, 13, 3, 39, 51, 131, 477, 699, 1101, 1289, 7683, 0 }; - static ulong[] dim647Kuo2Init = { 1, 1, 7, 1, 23, 39, 99, 167, 53, 333, 1059, 2947, 2097, 0 }; - static ulong[] dim648Kuo2Init = { 1, 1, 5, 15, 9, 55, 33, 121, 485, 767, 793, 1015, 7657, 0 }; - static ulong[] dim649Kuo2Init = { 1, 1, 7, 13, 15, 57, 5, 39, 197, 67, 1471, 841, 1797, 0 }; - static ulong[] dim650Kuo2Init = { 1, 3, 5, 3, 15, 17, 11, 139, 21, 827, 465, 1341, 1115, 0 }; - static ulong[] dim651Kuo2Init = { 1, 3, 7, 11, 7, 3, 29, 107, 79, 19, 493, 1705, 4631, 0 }; - static ulong[] dim652Kuo2Init = { 1, 1, 7, 1, 9, 61, 79, 23, 83, 863, 1189, 2653, 2139, 0 }; - static ulong[] dim653Kuo2Init = { 1, 1, 7, 7, 7, 39, 105, 147, 293, 799, 781, 1085, 1405, 0 }; - static ulong[] dim654Kuo2Init = { 1, 3, 3, 13, 27, 55, 89, 73, 255, 845, 485, 739, 4937, 0 }; - static ulong[] dim655Kuo2Init = { 1, 3, 1, 5, 19, 41, 93, 125, 203, 789, 1447, 189, 4743, 0 }; - static ulong[] dim656Kuo2Init = { 1, 3, 3, 11, 9, 9, 51, 237, 353, 313, 101, 873, 5605, 0 }; - static ulong[] dim657Kuo2Init = { 1, 3, 1, 5, 1, 33, 67, 29, 361, 945, 5, 305, 1461, 0 }; - static ulong[] dim658Kuo2Init = { 1, 1, 7, 3, 5, 31, 47, 145, 369, 419, 415, 2645, 4665, 0 }; - static ulong[] dim659Kuo2Init = { 1, 1, 1, 1, 9, 35, 3, 67, 233, 991, 1683, 1145, 6283, 0 }; - static ulong[] dim660Kuo2Init = { 1, 1, 1, 7, 13, 43, 95, 141, 415, 219, 1877, 2763, 3975, 0 }; - static ulong[] dim661Kuo2Init = { 1, 1, 3, 9, 25, 1, 125, 139, 31, 791, 2033, 2477, 297, 0 }; - static ulong[] dim662Kuo2Init = { 1, 1, 3, 7, 13, 53, 29, 53, 341, 905, 1953, 593, 3121, 0 }; - static ulong[] dim663Kuo2Init = { 1, 3, 3, 5, 21, 45, 97, 231, 377, 117, 1449, 1159, 1831, 0 }; - static ulong[] dim664Kuo2Init = { 1, 3, 7, 3, 13, 25, 33, 15, 479, 141, 1101, 1611, 2145, 0 }; - static ulong[] dim665Kuo2Init = { 1, 3, 5, 13, 19, 33, 85, 215, 107, 273, 1361, 1103, 3461, 0 }; - static ulong[] dim666Kuo2Init = { 1, 3, 5, 9, 7, 29, 91, 55, 239, 971, 1389, 301, 6011, 0 }; - static ulong[] dim667Kuo2Init = { 1, 3, 3, 3, 31, 39, 73, 131, 53, 583, 1387, 3827, 5621, 0 }; - static ulong[] dim668Kuo2Init = { 1, 1, 7, 1, 21, 47, 39, 99, 95, 915, 1281, 675, 4147, 0 }; - static ulong[] dim669Kuo2Init = { 1, 3, 7, 13, 19, 17, 121, 151, 163, 447, 1741, 2563, 957, 0 }; - static ulong[] dim670Kuo2Init = { 1, 3, 1, 11, 19, 19, 9, 31, 105, 829, 1957, 3327, 2923, 0 }; - static ulong[] dim671Kuo2Init = { 1, 1, 1, 1, 29, 49, 67, 135, 165, 203, 691, 4043, 4973, 0 }; - static ulong[] dim672Kuo2Init = { 1, 3, 3, 15, 17, 57, 53, 123, 311, 169, 1705, 3853, 3243, 0 }; - static ulong[] dim673Kuo2Init = { 1, 1, 7, 5, 11, 51, 39, 215, 209, 353, 1857, 369, 1793, 0 }; - static ulong[] dim674Kuo2Init = { 1, 1, 1, 3, 1, 55, 19, 145, 283, 471, 929, 3207, 5819, 0 }; - static ulong[] dim675Kuo2Init = { 1, 1, 3, 13, 21, 23, 49, 241, 53, 153, 591, 949, 859, 0 }; - static ulong[] dim676Kuo2Init = { 1, 3, 1, 5, 21, 13, 105, 147, 29, 407, 589, 1659, 5265, 0 }; - static ulong[] dim677Kuo2Init = { 1, 1, 1, 9, 19, 27, 83, 175, 329, 459, 1401, 2195, 5997, 0 }; - static ulong[] dim678Kuo2Init = { 1, 1, 5, 1, 29, 39, 33, 73, 363, 143, 617, 1507, 5871, 0 }; - static ulong[] dim679Kuo2Init = { 1, 1, 1, 7, 29, 23, 19, 51, 331, 299, 1883, 1973, 1969, 0 }; - static ulong[] dim680Kuo2Init = { 1, 3, 7, 13, 1, 49, 25, 43, 17, 297, 683, 1189, 6049, 0 }; - static ulong[] dim681Kuo2Init = { 1, 3, 1, 15, 23, 25, 29, 231, 425, 501, 1787, 3223, 5789, 0 }; - static ulong[] dim682Kuo2Init = { 1, 3, 7, 1, 1, 3, 23, 231, 377, 485, 1469, 1089, 1539, 0 }; - static ulong[] dim683Kuo2Init = { 1, 1, 5, 5, 29, 25, 93, 51, 249, 25, 1355, 23, 2961, 0 }; - static ulong[] dim684Kuo2Init = { 1, 3, 5, 13, 11, 55, 117, 221, 137, 941, 1127, 735, 4835, 0 }; - static ulong[] dim685Kuo2Init = { 1, 3, 3, 15, 5, 53, 35, 245, 31, 985, 2035, 163, 5223, 0 }; - static ulong[] dim686Kuo2Init = { 1, 1, 7, 7, 27, 25, 17, 113, 187, 283, 723, 2703, 4873, 0 }; - static ulong[] dim687Kuo2Init = { 1, 1, 1, 1, 3, 61, 81, 125, 335, 997, 975, 2371, 1829, 0 }; - static ulong[] dim688Kuo2Init = { 1, 3, 1, 15, 21, 9, 67, 55, 109, 657, 837, 1737, 5147, 0 }; - static ulong[] dim689Kuo2Init = { 1, 1, 3, 3, 19, 41, 117, 39, 441, 985, 955, 1467, 7297, 0 }; - static ulong[] dim690Kuo2Init = { 1, 1, 7, 7, 23, 1, 11, 11, 221, 539, 1807, 1887, 7921, 0 }; - static ulong[] dim691Kuo2Init = { 1, 3, 3, 1, 27, 45, 73, 39, 217, 233, 2015, 1209, 7101, 0 }; - static ulong[] dim692Kuo2Init = { 1, 3, 1, 11, 19, 57, 85, 45, 395, 23, 405, 2723, 653, 0 }; - static ulong[] dim693Kuo2Init = { 1, 1, 5, 15, 3, 43, 95, 149, 395, 359, 1067, 3571, 6219, 0 }; - static ulong[] dim694Kuo2Init = { 1, 1, 5, 5, 15, 3, 33, 181, 427, 565, 103, 261, 2375, 0 }; - static ulong[] dim695Kuo2Init = { 1, 3, 3, 15, 1, 3, 89, 239, 461, 675, 1149, 819, 3481, 0 }; - static ulong[] dim696Kuo2Init = { 1, 1, 5, 9, 23, 57, 1, 147, 245, 941, 1425, 2403, 7915, 0 }; - static ulong[] dim697Kuo2Init = { 1, 3, 1, 13, 3, 25, 43, 205, 295, 799, 1845, 2695, 3183, 0 }; - static ulong[] dim698Kuo2Init = { 1, 3, 1, 15, 11, 19, 111, 83, 479, 927, 709, 2739, 1233, 0 }; - static ulong[] dim699Kuo2Init = { 1, 3, 7, 13, 25, 41, 49, 39, 63, 265, 717, 3843, 3091, 0 }; - static ulong[] dim700Kuo2Init = { 1, 3, 1, 5, 27, 11, 55, 31, 103, 263, 759, 1969, 1301, 0 }; - static ulong[] dim701Kuo2Init = { 1, 1, 7, 15, 15, 33, 61, 93, 177, 645, 387, 3999, 4511, 0 }; - static ulong[] dim702Kuo2Init = { 1, 1, 7, 9, 5, 43, 87, 125, 443, 825, 1423, 1575, 2661, 0 }; - static ulong[] dim703Kuo2Init = { 1, 3, 1, 5, 3, 59, 59, 91, 63, 805, 1461, 4009, 4235, 0 }; - static ulong[] dim704Kuo2Init = { 1, 1, 3, 7, 15, 13, 95, 179, 479, 735, 1075, 4089, 4807, 0 }; - static ulong[] dim705Kuo2Init = { 1, 3, 1, 3, 23, 63, 63, 77, 299, 939, 661, 1007, 3299, 0 }; - static ulong[] dim706Kuo2Init = { 1, 1, 5, 3, 7, 49, 1, 217, 87, 561, 275, 3137, 4355, 0 }; - static ulong[] dim707Kuo2Init = { 1, 3, 5, 9, 21, 25, 49, 199, 207, 513, 231, 3053, 8023, 0 }; - static ulong[] dim708Kuo2Init = { 1, 1, 5, 1, 19, 39, 79, 225, 213, 719, 577, 3885, 7151, 0 }; - static ulong[] dim709Kuo2Init = { 1, 3, 1, 7, 9, 7, 9, 63, 185, 877, 253, 1401, 7665, 0 }; - static ulong[] dim710Kuo2Init = { 1, 1, 7, 15, 7, 9, 33, 79, 241, 727, 681, 2195, 5285, 0 }; - static ulong[] dim711Kuo2Init = { 1, 3, 3, 9, 21, 27, 9, 17, 277, 365, 1497, 2323, 1215, 0 }; - static ulong[] dim712Kuo2Init = { 1, 1, 3, 3, 29, 23, 63, 209, 487, 243, 1137, 45, 3949, 0 }; - static ulong[] dim713Kuo2Init = { 1, 1, 1, 15, 1, 33, 29, 245, 25, 497, 809, 4017, 2149, 0 }; - static ulong[] dim714Kuo2Init = { 1, 3, 3, 3, 25, 11, 117, 129, 23, 547, 175, 463, 2731, 0 }; - static ulong[] dim715Kuo2Init = { 1, 3, 3, 3, 5, 47, 69, 197, 131, 101, 1003, 1573, 3629, 0 }; - static ulong[] dim716Kuo2Init = { 1, 1, 1, 9, 7, 33, 63, 53, 159, 1009, 963, 203, 3395, 0 }; - static ulong[] dim717Kuo2Init = { 1, 3, 1, 1, 9, 11, 95, 73, 359, 357, 421, 1169, 7317, 0 }; - static ulong[] dim718Kuo2Init = { 1, 3, 5, 15, 27, 57, 105, 109, 457, 161, 901, 2239, 2143, 0 }; - static ulong[] dim719Kuo2Init = { 1, 1, 3, 7, 7, 61, 11, 211, 7, 515, 895, 1341, 2603, 0 }; - static ulong[] dim720Kuo2Init = { 1, 3, 3, 3, 7, 15, 67, 237, 5, 345, 1631, 923, 4269, 0 }; - static ulong[] dim721Kuo2Init = { 1, 1, 1, 15, 15, 27, 73, 7, 359, 49, 381, 2415, 1979, 0 }; - static ulong[] dim722Kuo2Init = { 1, 3, 7, 7, 15, 33, 1, 39, 19, 171, 93, 1815, 2675, 0 }; - static ulong[] dim723Kuo2Init = { 1, 3, 7, 9, 13, 37, 85, 75, 395, 767, 1855, 3413, 1845, 0 }; - static ulong[] dim724Kuo2Init = { 1, 3, 5, 15, 7, 59, 33, 235, 455, 21, 237, 3103, 6065, 0 }; - static ulong[] dim725Kuo2Init = { 1, 1, 3, 3, 29, 9, 67, 173, 303, 9, 1899, 3799, 63, 0 }; - static ulong[] dim726Kuo2Init = { 1, 1, 3, 5, 15, 53, 13, 149, 45, 223, 823, 1351, 4517, 0 }; - static ulong[] dim727Kuo2Init = { 1, 3, 3, 15, 21, 59, 81, 185, 245, 589, 1149, 3351, 4879, 0 }; - static ulong[] dim728Kuo2Init = { 1, 1, 1, 1, 11, 29, 17, 57, 199, 941, 1497, 227, 6271, 0 }; - static ulong[] dim729Kuo2Init = { 1, 3, 5, 7, 13, 35, 97, 247, 439, 687, 1821, 1583, 5919, 0 }; - static ulong[] dim730Kuo2Init = { 1, 1, 3, 7, 27, 25, 123, 129, 15, 497, 1491, 171, 6369, 0 }; - static ulong[] dim731Kuo2Init = { 1, 3, 1, 1, 25, 27, 63, 27, 261, 707, 579, 2599, 5925, 0 }; - static ulong[] dim732Kuo2Init = { 1, 1, 3, 9, 9, 39, 63, 141, 293, 601, 573, 445, 1003, 0 }; - static ulong[] dim733Kuo2Init = { 1, 3, 3, 15, 7, 25, 21, 189, 137, 13, 1923, 1019, 7219, 0 }; - static ulong[] dim734Kuo2Init = { 1, 3, 5, 9, 27, 45, 13, 251, 403, 781, 2009, 239, 4777, 0 }; - static ulong[] dim735Kuo2Init = { 1, 1, 5, 3, 21, 35, 93, 89, 249, 473, 1241, 2485, 291, 0 }; - static ulong[] dim736Kuo2Init = { 1, 3, 7, 15, 5, 53, 45, 213, 41, 393, 529, 599, 4993, 0 }; - static ulong[] dim737Kuo2Init = { 1, 3, 7, 5, 29, 29, 9, 163, 27, 617, 2015, 117, 6065, 0 }; - static ulong[] dim738Kuo2Init = { 1, 1, 7, 3, 9, 19, 31, 67, 395, 1003, 1907, 1165, 3375, 0 }; - static ulong[] dim739Kuo2Init = { 1, 1, 7, 1, 1, 37, 41, 131, 397, 181, 481, 2691, 6519, 0 }; - static ulong[] dim740Kuo2Init = { 1, 3, 5, 3, 9, 31, 127, 145, 435, 149, 597, 3611, 7715, 0 }; - static ulong[] dim741Kuo2Init = { 1, 1, 3, 9, 27, 33, 37, 165, 167, 699, 1313, 3599, 827, 0 }; - static ulong[] dim742Kuo2Init = { 1, 1, 1, 9, 15, 3, 21, 123, 319, 1009, 901, 819, 823, 0 }; - static ulong[] dim743Kuo2Init = { 1, 1, 7, 9, 29, 27, 101, 33, 341, 449, 607, 2807, 5553, 0 }; - static ulong[] dim744Kuo2Init = { 1, 3, 5, 3, 21, 25, 41, 105, 255, 339, 1971, 175, 47, 0 }; - static ulong[] dim745Kuo2Init = { 1, 1, 3, 5, 5, 3, 21, 73, 111, 293, 1283, 2531, 7609, 0 }; - static ulong[] dim746Kuo2Init = { 1, 3, 7, 3, 29, 47, 83, 165, 249, 281, 175, 1043, 4143, 0 }; - static ulong[] dim747Kuo2Init = { 1, 3, 1, 15, 27, 59, 3, 101, 343, 813, 1559, 553, 7801, 0 }; - static ulong[] dim748Kuo2Init = { 1, 1, 7, 15, 1, 9, 77, 205, 151, 255, 701, 2653, 2079, 0 }; - static ulong[] dim749Kuo2Init = { 1, 3, 3, 3, 13, 39, 37, 161, 499, 657, 1557, 3969, 3489, 0 }; - static ulong[] dim750Kuo2Init = { 1, 1, 1, 15, 9, 27, 41, 253, 119, 583, 73, 3255, 6067, 0 }; - static ulong[] dim751Kuo2Init = { 1, 1, 7, 7, 27, 43, 53, 99, 245, 169, 659, 81, 2943, 0 }; - static ulong[] dim752Kuo2Init = { 1, 1, 1, 11, 27, 13, 41, 217, 493, 145, 835, 3745, 97, 0 }; - static ulong[] dim753Kuo2Init = { 1, 3, 1, 9, 7, 13, 117, 113, 197, 503, 953, 2433, 7663, 0 }; - static ulong[] dim754Kuo2Init = { 1, 3, 5, 5, 9, 47, 101, 47, 187, 469, 69, 4031, 6231, 0 }; - static ulong[] dim755Kuo2Init = { 1, 1, 1, 3, 27, 27, 47, 219, 11, 201, 1267, 2703, 6711, 0 }; - static ulong[] dim756Kuo2Init = { 1, 3, 7, 7, 27, 27, 97, 101, 7, 541, 105, 3821, 7533, 0 }; - static ulong[] dim757Kuo2Init = { 1, 3, 5, 13, 21, 17, 99, 213, 347, 595, 519, 1113, 5427, 0 }; - static ulong[] dim758Kuo2Init = { 1, 1, 7, 13, 31, 1, 25, 111, 387, 27, 99, 119, 3265, 0 }; - static ulong[] dim759Kuo2Init = { 1, 1, 7, 15, 11, 43, 19, 177, 11, 943, 3, 623, 4223, 0 }; - static ulong[] dim760Kuo2Init = { 1, 3, 7, 3, 31, 59, 21, 241, 375, 703, 1465, 2375, 2853, 0 }; - static ulong[] dim761Kuo2Init = { 1, 1, 7, 15, 1, 49, 51, 161, 397, 583, 913, 985, 5519, 0 }; - static ulong[] dim762Kuo2Init = { 1, 3, 1, 3, 13, 37, 23, 165, 223, 427, 129, 1553, 4145, 0 }; - static ulong[] dim763Kuo2Init = { 1, 3, 3, 3, 1, 23, 47, 237, 371, 315, 1631, 2037, 61, 0 }; - static ulong[] dim764Kuo2Init = { 1, 3, 5, 15, 23, 59, 71, 237, 487, 443, 1475, 3065, 2453, 0 }; - static ulong[] dim765Kuo2Init = { 1, 1, 3, 13, 25, 57, 71, 3, 247, 145, 2011, 553, 7565, 0 }; - static ulong[] dim766Kuo2Init = { 1, 1, 1, 9, 21, 1, 61, 91, 3, 807, 1795, 2665, 473, 0 }; - static ulong[] dim767Kuo2Init = { 1, 3, 7, 11, 9, 7, 123, 233, 249, 825, 1505, 3599, 6653, 0 }; - static ulong[] dim768Kuo2Init = { 1, 1, 3, 15, 11, 37, 119, 63, 233, 541, 1373, 765, 4913, 0 }; - static ulong[] dim769Kuo2Init = { 1, 1, 1, 9, 5, 15, 77, 65, 321, 613, 1857, 3699, 1, 0 }; - static ulong[] dim770Kuo2Init = { 1, 3, 1, 15, 13, 37, 123, 9, 105, 121, 893, 1009, 7871, 0 }; - static ulong[] dim771Kuo2Init = { 1, 3, 5, 1, 23, 61, 29, 223, 209, 605, 409, 875, 5233, 0 }; - static ulong[] dim772Kuo2Init = { 1, 1, 3, 11, 5, 61, 9, 85, 361, 613, 1555, 2323, 5119, 0 }; - static ulong[] dim773Kuo2Init = { 1, 1, 1, 1, 17, 49, 67, 191, 247, 873, 1283, 171, 1689, 0 }; - static ulong[] dim774Kuo2Init = { 1, 3, 3, 13, 17, 17, 45, 73, 175, 243, 97, 315, 1429, 0 }; - static ulong[] dim775Kuo2Init = { 1, 3, 5, 5, 13, 1, 113, 87, 241, 199, 145, 3823, 5965, 0 }; - static ulong[] dim776Kuo2Init = { 1, 3, 3, 7, 7, 47, 115, 139, 239, 547, 109, 2251, 6987, 0 }; - static ulong[] dim777Kuo2Init = { 1, 3, 1, 11, 3, 59, 111, 225, 385, 887, 425, 1879, 4535, 0 }; - static ulong[] dim778Kuo2Init = { 1, 1, 3, 9, 27, 35, 55, 125, 379, 529, 191, 1657, 2835, 0 }; - static ulong[] dim779Kuo2Init = { 1, 1, 7, 11, 25, 11, 85, 21, 65, 377, 1989, 1963, 6985, 0 }; - static ulong[] dim780Kuo2Init = { 1, 3, 7, 11, 15, 59, 91, 51, 145, 627, 1617, 3029, 3621, 0 }; - static ulong[] dim781Kuo2Init = { 1, 3, 7, 11, 29, 9, 15, 189, 495, 997, 467, 343, 7615, 0 }; - static ulong[] dim782Kuo2Init = { 1, 1, 7, 7, 17, 37, 89, 31, 355, 323, 1361, 3785, 643, 0 }; - static ulong[] dim783Kuo2Init = { 1, 1, 7, 1, 27, 19, 15, 5, 383, 1023, 923, 3283, 2997, 0 }; - static ulong[] dim784Kuo2Init = { 1, 3, 7, 15, 11, 41, 117, 255, 407, 117, 495, 99, 7687, 0 }; - static ulong[] dim785Kuo2Init = { 1, 1, 1, 9, 9, 29, 109, 103, 81, 237, 1547, 3083, 2449, 0 }; - static ulong[] dim786Kuo2Init = { 1, 3, 5, 1, 19, 57, 43, 215, 251, 417, 1719, 3767, 1543, 0 }; - static ulong[] dim787Kuo2Init = { 1, 3, 7, 11, 15, 9, 1, 171, 439, 637, 1709, 1483, 4111, 0 }; - static ulong[] dim788Kuo2Init = { 1, 3, 1, 5, 25, 31, 101, 101, 301, 169, 803, 2119, 5035, 0 }; - static ulong[] dim789Kuo2Init = { 1, 1, 7, 5, 21, 57, 59, 149, 31, 1023, 1063, 2465, 1517, 0 }; - static ulong[] dim790Kuo2Init = { 1, 1, 5, 5, 7, 29, 101, 19, 49, 187, 715, 843, 1553, 0 }; - static ulong[] dim791Kuo2Init = { 1, 3, 3, 5, 21, 43, 27, 203, 125, 629, 1395, 15, 7647, 0 }; - static ulong[] dim792Kuo2Init = { 1, 1, 3, 11, 27, 49, 69, 135, 447, 503, 1589, 209, 791, 0 }; - static ulong[] dim793Kuo2Init = { 1, 3, 1, 15, 17, 57, 27, 55, 237, 223, 949, 2119, 3221, 0 }; - static ulong[] dim794Kuo2Init = { 1, 3, 3, 9, 3, 37, 43, 49, 41, 899, 1657, 2463, 1303, 0 }; - static ulong[] dim795Kuo2Init = { 1, 1, 7, 13, 27, 27, 19, 93, 139, 745, 889, 951, 6925, 0 }; - static ulong[] dim796Kuo2Init = { 1, 3, 1, 13, 15, 33, 97, 217, 333, 295, 683, 397, 3889, 0 }; - static ulong[] dim797Kuo2Init = { 1, 3, 5, 15, 17, 57, 47, 173, 15, 77, 863, 1441, 6851, 0 }; - static ulong[] dim798Kuo2Init = { 1, 3, 5, 7, 3, 43, 21, 37, 349, 1021, 725, 1985, 481, 0 }; - static ulong[] dim799Kuo2Init = { 1, 1, 1, 13, 9, 45, 85, 177, 15, 915, 187, 15, 6621, 0 }; - static ulong[] dim800Kuo2Init = { 1, 3, 5, 11, 5, 29, 113, 95, 461, 607, 1637, 1897, 721, 0 }; - static ulong[] dim801Kuo2Init = { 1, 3, 1, 11, 13, 23, 55, 169, 29, 803, 1433, 2113, 7255, 0 }; - static ulong[] dim802Kuo2Init = { 1, 1, 5, 3, 31, 1, 45, 251, 129, 267, 1489, 427, 4993, 0 }; - static ulong[] dim803Kuo2Init = { 1, 1, 1, 9, 9, 11, 19, 31, 493, 195, 1545, 2681, 2187, 0 }; - static ulong[] dim804Kuo2Init = { 1, 3, 1, 7, 3, 51, 121, 149, 325, 921, 241, 999, 6039, 0 }; - static ulong[] dim805Kuo2Init = { 1, 3, 3, 15, 17, 37, 41, 157, 209, 587, 1351, 2353, 1197, 0 }; - static ulong[] dim806Kuo2Init = { 1, 1, 5, 13, 13, 55, 45, 3, 475, 9, 11, 3175, 2185, 0 }; - static ulong[] dim807Kuo2Init = { 1, 3, 5, 13, 31, 33, 63, 149, 463, 493, 1483, 1457, 6051, 0 }; - static ulong[] dim808Kuo2Init = { 1, 1, 1, 3, 3, 11, 119, 177, 207, 631, 105, 263, 2533, 0 }; - static ulong[] dim809Kuo2Init = { 1, 1, 1, 15, 23, 27, 73, 77, 143, 523, 1883, 3289, 1685, 0 }; - static ulong[] dim810Kuo2Init = { 1, 3, 1, 5, 21, 31, 25, 183, 71, 679, 1697, 3473, 4233, 0 }; - static ulong[] dim811Kuo2Init = { 1, 1, 7, 15, 9, 13, 103, 125, 223, 83, 1255, 2755, 1447, 0 }; - static ulong[] dim812Kuo2Init = { 1, 3, 5, 15, 15, 51, 69, 101, 369, 463, 1515, 3485, 1871, 0 }; - static ulong[] dim813Kuo2Init = { 1, 3, 5, 7, 21, 31, 55, 223, 477, 995, 147, 387, 7917, 0 }; - static ulong[] dim814Kuo2Init = { 1, 3, 5, 5, 7, 31, 73, 243, 283, 949, 705, 449, 3309, 0 }; - static ulong[] dim815Kuo2Init = { 1, 1, 5, 9, 15, 5, 25, 219, 379, 1013, 1683, 703, 4855, 0 }; - static ulong[] dim816Kuo2Init = { 1, 1, 7, 15, 25, 15, 99, 217, 265, 851, 149, 1557, 8107, 0 }; - static ulong[] dim817Kuo2Init = { 1, 3, 3, 5, 1, 59, 35, 119, 245, 9, 765, 833, 1707, 0 }; - static ulong[] dim818Kuo2Init = { 1, 1, 1, 13, 23, 49, 25, 153, 215, 365, 1943, 2975, 1301, 0 }; - static ulong[] dim819Kuo2Init = { 1, 3, 5, 7, 15, 45, 25, 215, 225, 431, 1161, 2389, 1969, 0 }; - static ulong[] dim820Kuo2Init = { 1, 3, 5, 9, 19, 31, 121, 189, 331, 23, 419, 3171, 6241, 0 }; - static ulong[] dim821Kuo2Init = { 1, 1, 5, 5, 17, 39, 69, 215, 307, 827, 557, 3251, 3211, 0 }; - static ulong[] dim822Kuo2Init = { 1, 1, 3, 11, 31, 27, 23, 119, 463, 605, 453, 1573, 1981, 0 }; - static ulong[] dim823Kuo2Init = { 1, 1, 5, 11, 1, 15, 37, 111, 481, 331, 1481, 1013, 3259, 0 }; - static ulong[] dim824Kuo2Init = { 1, 1, 1, 11, 21, 39, 25, 183, 351, 553, 3, 3969, 2551, 0 }; - static ulong[] dim825Kuo2Init = { 1, 3, 7, 1, 19, 5, 3, 55, 483, 373, 1529, 535, 4215, 0 }; - static ulong[] dim826Kuo2Init = { 1, 1, 3, 1, 25, 61, 89, 197, 465, 493, 661, 2361, 4211, 0 }; - static ulong[] dim827Kuo2Init = { 1, 3, 1, 9, 29, 61, 59, 175, 389, 973, 1763, 4077, 6211, 0 }; - static ulong[] dim828Kuo2Init = { 1, 3, 1, 7, 11, 41, 117, 75, 291, 125, 273, 5, 8169, 0 }; - static ulong[] dim829Kuo2Init = { 1, 1, 5, 11, 21, 53, 121, 31, 451, 631, 1901, 4059, 6801, 0 }; - static ulong[] dim830Kuo2Init = { 1, 3, 7, 3, 13, 33, 51, 247, 409, 881, 935, 1927, 1559, 0 }; - static ulong[] dim831Kuo2Init = { 1, 1, 3, 13, 15, 51, 105, 209, 159, 333, 325, 3699, 5461, 0 }; - static ulong[] dim832Kuo2Init = { 1, 3, 3, 5, 17, 7, 47, 57, 59, 673, 611, 253, 1531, 0 }; - static ulong[] dim833Kuo2Init = { 1, 1, 7, 1, 19, 27, 15, 189, 319, 649, 1593, 875, 8187, 0 }; - static ulong[] dim834Kuo2Init = { 1, 1, 1, 3, 15, 17, 81, 183, 409, 433, 679, 1881, 7827, 0 }; - static ulong[] dim835Kuo2Init = { 1, 1, 3, 9, 23, 37, 83, 235, 225, 599, 1979, 2871, 1353, 0 }; - static ulong[] dim836Kuo2Init = { 1, 1, 7, 7, 27, 11, 93, 115, 339, 233, 1733, 2071, 3187, 0 }; - static ulong[] dim837Kuo2Init = { 1, 1, 1, 7, 27, 47, 61, 73, 361, 621, 1907, 3103, 1873, 0 }; - static ulong[] dim838Kuo2Init = { 1, 1, 1, 9, 9, 13, 67, 161, 21, 953, 1101, 2255, 4841, 0 }; - static ulong[] dim839Kuo2Init = { 1, 3, 7, 7, 29, 39, 31, 73, 351, 401, 441, 4085, 2829, 0 }; - static ulong[] dim840Kuo2Init = { 1, 1, 5, 15, 9, 23, 127, 111, 309, 955, 623, 1995, 1961, 0 }; - static ulong[] dim841Kuo2Init = { 1, 3, 5, 9, 3, 3, 27, 91, 287, 73, 1449, 1347, 8069, 0 }; - static ulong[] dim842Kuo2Init = { 1, 1, 5, 3, 9, 49, 87, 3, 59, 193, 1999, 2295, 2247, 0 }; - static ulong[] dim843Kuo2Init = { 1, 3, 3, 3, 21, 21, 97, 47, 195, 65, 1281, 1411, 6503, 0 }; - static ulong[] dim844Kuo2Init = { 1, 1, 7, 13, 1, 11, 85, 195, 429, 71, 1053, 3623, 2921, 0 }; - static ulong[] dim845Kuo2Init = { 1, 3, 1, 5, 17, 15, 105, 155, 291, 889, 1997, 3629, 7025, 0 }; - static ulong[] dim846Kuo2Init = { 1, 1, 3, 7, 9, 3, 79, 41, 21, 819, 1665, 4021, 7057, 0 }; - static ulong[] dim847Kuo2Init = { 1, 1, 3, 1, 1, 23, 73, 5, 75, 435, 889, 2577, 697, 0 }; - static ulong[] dim848Kuo2Init = { 1, 3, 7, 1, 1, 5, 77, 183, 109, 159, 1463, 2689, 7799, 0 }; - static ulong[] dim849Kuo2Init = { 1, 1, 1, 13, 29, 55, 123, 247, 509, 909, 247, 3053, 7301, 0 }; - static ulong[] dim850Kuo2Init = { 1, 1, 5, 13, 7, 23, 43, 177, 59, 643, 1517, 1869, 3269, 0 }; - static ulong[] dim851Kuo2Init = { 1, 3, 1, 9, 7, 43, 3, 13, 387, 893, 1013, 7, 7481, 0 }; - static ulong[] dim852Kuo2Init = { 1, 1, 1, 1, 9, 35, 111, 199, 77, 375, 981, 3475, 2339, 0 }; - static ulong[] dim853Kuo2Init = { 1, 3, 5, 7, 5, 13, 27, 5, 113, 65, 1785, 1517, 8027, 0 }; - static ulong[] dim854Kuo2Init = { 1, 3, 7, 5, 25, 47, 15, 7, 45, 441, 7, 1601, 6543, 0 }; - static ulong[] dim855Kuo2Init = { 1, 1, 7, 3, 17, 59, 71, 93, 441, 763, 769, 1977, 287, 0 }; - static ulong[] dim856Kuo2Init = { 1, 1, 7, 11, 29, 23, 61, 199, 469, 757, 1473, 2625, 5909, 0 }; - static ulong[] dim857Kuo2Init = { 1, 1, 5, 11, 27, 47, 41, 91, 457, 1003, 217, 401, 8113, 0 }; - static ulong[] dim858Kuo2Init = { 1, 1, 5, 7, 1, 33, 43, 45, 169, 485, 191, 615, 5141, 0 }; - static ulong[] dim859Kuo2Init = { 1, 3, 1, 5, 5, 53, 19, 185, 189, 681, 1685, 661, 6825, 0 }; - static ulong[] dim860Kuo2Init = { 1, 3, 3, 1, 1, 7, 47, 27, 275, 63, 1029, 449, 4665, 0 }; - static ulong[] dim861Kuo2Init = { 1, 3, 3, 1, 3, 31, 1, 77, 275, 871, 1031, 1025, 4683, 0 }; - static ulong[] dim862Kuo2Init = { 1, 1, 3, 3, 9, 35, 39, 43, 363, 129, 431, 1351, 8037, 0 }; - static ulong[] dim863Kuo2Init = { 1, 1, 5, 3, 3, 39, 29, 99, 441, 819, 175, 3503, 4911, 0 }; - static ulong[] dim864Kuo2Init = { 1, 3, 5, 13, 9, 17, 87, 5, 311, 307, 659, 2795, 4055, 0 }; - static ulong[] dim865Kuo2Init = { 1, 1, 3, 13, 13, 51, 69, 99, 65, 257, 87, 1407, 3157, 0 }; - static ulong[] dim866Kuo2Init = { 1, 1, 5, 9, 19, 41, 97, 231, 85, 743, 637, 755, 6209, 0 }; - static ulong[] dim867Kuo2Init = { 1, 1, 5, 15, 21, 63, 81, 35, 477, 39, 873, 3679, 6477, 0 }; - static ulong[] dim868Kuo2Init = { 1, 1, 7, 13, 23, 37, 115, 87, 171, 33, 1779, 3169, 3205, 0 }; - static ulong[] dim869Kuo2Init = { 1, 3, 7, 11, 9, 41, 111, 9, 5, 441, 1677, 311, 1019, 0 }; - static ulong[] dim870Kuo2Init = { 1, 1, 5, 15, 7, 23, 7, 181, 461, 357, 187, 3461, 6689, 0 }; - static ulong[] dim871Kuo2Init = { 1, 1, 3, 11, 15, 37, 101, 125, 271, 205, 57, 3361, 3965, 0 }; - static ulong[] dim872Kuo2Init = { 1, 3, 3, 9, 25, 41, 97, 133, 39, 383, 669, 4007, 25, 0 }; - static ulong[] dim873Kuo2Init = { 1, 3, 7, 13, 17, 13, 79, 61, 145, 567, 1079, 287, 467, 0 }; - static ulong[] dim874Kuo2Init = { 1, 1, 5, 1, 7, 47, 97, 131, 119, 1013, 1991, 741, 27, 0 }; - static ulong[] dim875Kuo2Init = { 1, 3, 5, 9, 23, 21, 71, 209, 239, 801, 133, 2891, 1141, 0 }; - static ulong[] dim876Kuo2Init = { 1, 1, 7, 9, 17, 11, 109, 251, 127, 447, 1257, 3831, 1511, 0 }; - static ulong[] dim877Kuo2Init = { 1, 3, 1, 13, 21, 9, 69, 241, 61, 521, 1281, 3499, 4001, 0 }; - static ulong[] dim878Kuo2Init = { 1, 1, 5, 15, 5, 23, 117, 111, 159, 861, 295, 3403, 981, 0 }; - static ulong[] dim879Kuo2Init = { 1, 3, 3, 5, 3, 37, 85, 129, 281, 261, 1753, 1399, 43, 0 }; - static ulong[] dim880Kuo2Init = { 1, 1, 5, 5, 3, 49, 67, 221, 3, 143, 617, 2579, 373, 0 }; - static ulong[] dim881Kuo2Init = { 1, 3, 5, 11, 29, 49, 59, 47, 21, 725, 655, 3467, 2375, 0 }; - static ulong[] dim882Kuo2Init = { 1, 3, 3, 13, 15, 43, 19, 185, 411, 299, 1351, 3543, 5429, 0 }; - static ulong[] dim883Kuo2Init = { 1, 1, 5, 11, 19, 63, 19, 167, 439, 627, 1729, 245, 193, 0 }; - static ulong[] dim884Kuo2Init = { 1, 1, 3, 1, 5, 5, 115, 127, 295, 321, 1167, 3187, 6165, 0 }; - static ulong[] dim885Kuo2Init = { 1, 3, 1, 9, 9, 51, 87, 205, 211, 427, 1817, 3169, 1469, 0 }; - static ulong[] dim886Kuo2Init = { 1, 3, 1, 15, 27, 57, 15, 199, 87, 361, 583, 2467, 1367, 0 }; - static ulong[] dim887Kuo2Init = { 1, 1, 1, 11, 27, 7, 53, 173, 505, 839, 929, 3977, 7667, 0 }; - static ulong[] dim888Kuo2Init = { 1, 3, 3, 13, 7, 37, 51, 109, 249, 233, 899, 3991, 6667, 0 }; - static ulong[] dim889Kuo2Init = { 1, 3, 1, 11, 17, 23, 105, 213, 425, 175, 869, 3185, 6301, 0 }; - static ulong[] dim890Kuo2Init = { 1, 1, 5, 5, 17, 47, 5, 135, 497, 227, 1135, 689, 5047, 0 }; - static ulong[] dim891Kuo2Init = { 1, 3, 3, 11, 5, 49, 29, 177, 325, 727, 1719, 1805, 3361, 0 }; - static ulong[] dim892Kuo2Init = { 1, 1, 3, 3, 11, 7, 87, 169, 27, 137, 1835, 1377, 4915, 0 }; - static ulong[] dim893Kuo2Init = { 1, 3, 5, 5, 21, 53, 99, 137, 133, 599, 479, 2859, 6731, 0 }; - static ulong[] dim894Kuo2Init = { 1, 1, 5, 5, 15, 15, 31, 239, 183, 167, 1799, 1533, 309, 0 }; - static ulong[] dim895Kuo2Init = { 1, 3, 5, 15, 23, 51, 85, 133, 51, 991, 899, 3777, 2231, 0 }; - static ulong[] dim896Kuo2Init = { 1, 1, 3, 1, 15, 19, 29, 5, 415, 531, 253, 49, 7197, 0 }; - static ulong[] dim897Kuo2Init = { 1, 1, 5, 15, 21, 23, 41, 213, 189, 579, 1181, 3425, 8037, 0 }; - static ulong[] dim898Kuo2Init = { 1, 1, 5, 13, 9, 63, 21, 195, 71, 137, 1283, 2895, 3301, 0 }; - static ulong[] dim899Kuo2Init = { 1, 1, 7, 1, 11, 5, 103, 183, 403, 177, 1561, 201, 2843, 0 }; - static ulong[] dim900Kuo2Init = { 1, 3, 3, 9, 19, 15, 85, 123, 273, 891, 493, 3761, 557, 0 }; - static ulong[] dim901Kuo2Init = { 1, 3, 7, 9, 9, 23, 123, 243, 71, 137, 1937, 3199, 6865, 0 }; - static ulong[] dim902Kuo2Init = { 1, 1, 1, 15, 15, 55, 119, 203, 449, 969, 181, 2573, 3261, 0 }; - static ulong[] dim903Kuo2Init = { 1, 1, 1, 9, 29, 9, 87, 117, 85, 369, 911, 1203, 7287, 0 }; - static ulong[] dim904Kuo2Init = { 1, 1, 1, 7, 1, 35, 9, 85, 253, 123, 67, 2089, 4693, 0 }; - static ulong[] dim905Kuo2Init = { 1, 3, 5, 15, 11, 13, 43, 97, 407, 1011, 1839, 525, 6809, 0 }; - static ulong[] dim906Kuo2Init = { 1, 3, 3, 7, 11, 49, 5, 29, 299, 35, 1883, 763, 3099, 0 }; - static ulong[] dim907Kuo2Init = { 1, 3, 3, 13, 31, 5, 61, 79, 409, 1001, 1057, 1673, 4689, 0 }; - static ulong[] dim908Kuo2Init = { 1, 1, 3, 7, 23, 53, 23, 243, 335, 847, 1011, 659, 3739, 0 }; - static ulong[] dim909Kuo2Init = { 1, 3, 5, 1, 15, 55, 15, 161, 417, 225, 227, 3933, 5625, 0 }; - static ulong[] dim910Kuo2Init = { 1, 3, 7, 11, 25, 1, 75, 33, 401, 777, 1999, 1649, 1269, 0 }; - static ulong[] dim911Kuo2Init = { 1, 3, 5, 5, 3, 1, 13, 99, 447, 579, 225, 3851, 5379, 0 }; - static ulong[] dim912Kuo2Init = { 1, 1, 3, 13, 19, 33, 39, 93, 133, 889, 113, 3983, 1115, 0 }; - static ulong[] dim913Kuo2Init = { 1, 3, 5, 13, 1, 47, 113, 231, 461, 653, 1965, 849, 4513, 0 }; - static ulong[] dim914Kuo2Init = { 1, 1, 3, 1, 23, 7, 105, 115, 463, 385, 1355, 1417, 6341, 0 }; - static ulong[] dim915Kuo2Init = { 1, 1, 5, 7, 9, 27, 123, 193, 5, 735, 733, 2385, 6569, 0 }; - static ulong[] dim916Kuo2Init = { 1, 3, 1, 11, 13, 51, 53, 15, 289, 433, 951, 3657, 5239, 0 }; - static ulong[] dim917Kuo2Init = { 1, 1, 7, 3, 7, 59, 69, 57, 471, 247, 259, 2617, 47, 0 }; - static ulong[] dim918Kuo2Init = { 1, 3, 7, 13, 5, 41, 45, 67, 363, 295, 1715, 3567, 2457, 0 }; - static ulong[] dim919Kuo2Init = { 1, 1, 5, 3, 21, 19, 79, 37, 273, 613, 475, 3989, 3779, 0 }; - static ulong[] dim920Kuo2Init = { 1, 1, 5, 3, 21, 11, 53, 117, 367, 295, 1027, 2579, 2717, 0 }; - static ulong[] dim921Kuo2Init = { 1, 1, 5, 7, 29, 1, 47, 185, 377, 267, 1375, 801, 5967, 0 }; - static ulong[] dim922Kuo2Init = { 1, 3, 3, 3, 15, 5, 51, 183, 249, 789, 785, 1459, 7865, 0 }; - static ulong[] dim923Kuo2Init = { 1, 3, 5, 5, 31, 17, 89, 9, 247, 67, 1259, 3099, 2805, 0 }; - static ulong[] dim924Kuo2Init = { 1, 3, 3, 11, 31, 51, 55, 37, 201, 779, 1235, 1905, 1995, 0 }; - static ulong[] dim925Kuo2Init = { 1, 3, 1, 1, 27, 31, 25, 37, 443, 399, 1911, 3951, 4311, 0 }; - static ulong[] dim926Kuo2Init = { 1, 3, 3, 11, 11, 13, 69, 209, 295, 431, 573, 1781, 7767, 0 }; - static ulong[] dim927Kuo2Init = { 1, 3, 1, 3, 23, 55, 57, 29, 137, 407, 1339, 1411, 123, 0 }; - static ulong[] dim928Kuo2Init = { 1, 3, 3, 13, 5, 15, 7, 29, 353, 143, 133, 2351, 1555, 0 }; - static ulong[] dim929Kuo2Init = { 1, 1, 7, 9, 17, 53, 61, 197, 245, 327, 147, 3231, 1825, 0 }; - static ulong[] dim930Kuo2Init = { 1, 3, 5, 3, 27, 55, 31, 15, 429, 703, 1863, 3697, 2169, 0 }; - static ulong[] dim931Kuo2Init = { 1, 3, 3, 1, 19, 45, 61, 179, 471, 219, 1127, 3521, 8065, 0 }; - static ulong[] dim932Kuo2Init = { 1, 3, 5, 5, 17, 21, 77, 117, 331, 979, 175, 3155, 1589, 0 }; - static ulong[] dim933Kuo2Init = { 1, 3, 1, 9, 13, 41, 25, 221, 115, 333, 1851, 543, 5479, 0 }; - static ulong[] dim934Kuo2Init = { 1, 3, 3, 13, 25, 35, 113, 107, 21, 85, 815, 3013, 8067, 0 }; - static ulong[] dim935Kuo2Init = { 1, 1, 3, 9, 23, 37, 55, 193, 301, 463, 1361, 3455, 5745, 0 }; - static ulong[] dim936Kuo2Init = { 1, 3, 5, 7, 3, 63, 73, 83, 35, 709, 719, 1133, 6711, 0 }; - static ulong[] dim937Kuo2Init = { 1, 1, 5, 7, 11, 7, 67, 199, 285, 527, 1181, 39, 5639, 0 }; - static ulong[] dim938Kuo2Init = { 1, 3, 3, 3, 17, 13, 33, 213, 97, 499, 1651, 3369, 6001, 0 }; - static ulong[] dim939Kuo2Init = { 1, 1, 3, 1, 15, 37, 67, 31, 225, 205, 1009, 2579, 331, 0 }; - static ulong[] dim940Kuo2Init = { 1, 1, 7, 1, 29, 3, 91, 153, 395, 89, 2019, 1297, 7035, 0 }; - static ulong[] dim941Kuo2Init = { 1, 3, 3, 5, 29, 31, 65, 137, 289, 351, 677, 3305, 5073, 0 }; - static ulong[] dim942Kuo2Init = { 1, 1, 3, 13, 15, 21, 43, 227, 399, 921, 123, 3199, 6925, 0 }; - static ulong[] dim943Kuo2Init = { 1, 1, 7, 13, 17, 11, 107, 251, 55, 525, 869, 209, 6209, 0 }; - static ulong[] dim944Kuo2Init = { 1, 1, 3, 11, 29, 39, 123, 171, 223, 441, 525, 2583, 71, 0 }; - static ulong[] dim945Kuo2Init = { 1, 3, 7, 9, 5, 3, 3, 205, 119, 631, 1997, 3105, 6483, 0 }; - static ulong[] dim946Kuo2Init = { 1, 1, 7, 7, 23, 37, 79, 245, 401, 241, 1471, 2941, 4389, 0 }; - static ulong[] dim947Kuo2Init = { 1, 3, 1, 13, 25, 7, 43, 215, 155, 805, 1497, 387, 2045, 0 }; - static ulong[] dim948Kuo2Init = { 1, 1, 3, 3, 7, 37, 115, 39, 139, 555, 1325, 2351, 6045, 0 }; - static ulong[] dim949Kuo2Init = { 1, 1, 5, 7, 3, 53, 35, 103, 505, 361, 457, 2495, 1325, 0 }; - static ulong[] dim950Kuo2Init = { 1, 3, 7, 13, 21, 33, 39, 81, 465, 601, 1131, 2977, 1409, 0 }; - static ulong[] dim951Kuo2Init = { 1, 1, 5, 5, 25, 1, 21, 241, 255, 663, 1509, 2455, 5705, 0 }; - static ulong[] dim952Kuo2Init = { 1, 1, 7, 13, 1, 47, 91, 195, 195, 503, 1931, 1681, 5131, 0 }; - static ulong[] dim953Kuo2Init = { 1, 1, 3, 9, 27, 37, 103, 21, 237, 677, 1949, 357, 2781, 0 }; - static ulong[] dim954Kuo2Init = { 1, 3, 7, 9, 29, 51, 107, 49, 251, 433, 1235, 4041, 2971, 0 }; - static ulong[] dim955Kuo2Init = { 1, 3, 3, 1, 19, 37, 113, 75, 365, 145, 93, 1185, 1871, 0 }; - static ulong[] dim956Kuo2Init = { 1, 1, 5, 5, 25, 15, 113, 239, 27, 321, 1351, 1441, 3333, 0 }; - static ulong[] dim957Kuo2Init = { 1, 1, 5, 13, 31, 35, 103, 83, 111, 573, 59, 3753, 5667, 0 }; - static ulong[] dim958Kuo2Init = { 1, 1, 5, 13, 1, 43, 75, 115, 397, 187, 1669, 3837, 5219, 0 }; - static ulong[] dim959Kuo2Init = { 1, 1, 3, 1, 23, 13, 65, 145, 271, 909, 1517, 1659, 7975, 0 }; - static ulong[] dim960Kuo2Init = { 1, 1, 7, 15, 21, 23, 1, 33, 37, 313, 687, 2375, 555, 0 }; - static ulong[] dim961Kuo2Init = { 1, 1, 7, 13, 1, 35, 11, 157, 295, 403, 1295, 3301, 4805, 0 }; - static ulong[] dim962Kuo2Init = { 1, 3, 1, 13, 9, 27, 3, 111, 133, 395, 981, 2399, 7009, 0 }; - static ulong[] dim963Kuo2Init = { 1, 1, 7, 15, 23, 11, 75, 31, 5, 599, 1589, 2243, 3263, 0 }; - static ulong[] dim964Kuo2Init = { 1, 1, 3, 9, 7, 49, 31, 5, 457, 93, 221, 2463, 2287, 0 }; - static ulong[] dim965Kuo2Init = { 1, 1, 5, 3, 9, 31, 49, 5, 481, 145, 53, 2477, 5569, 0 }; - static ulong[] dim966Kuo2Init = { 1, 1, 1, 1, 19, 47, 59, 83, 19, 887, 335, 2305, 6265, 0 }; - static ulong[] dim967Kuo2Init = { 1, 3, 7, 15, 27, 15, 93, 37, 213, 17, 311, 3159, 6911, 0 }; - static ulong[] dim968Kuo2Init = { 1, 1, 3, 9, 19, 47, 93, 31, 489, 731, 1905, 1675, 1, 0 }; - static ulong[] dim969Kuo2Init = { 1, 1, 1, 7, 9, 3, 17, 185, 203, 963, 521, 2797, 7511, 0 }; - static ulong[] dim970Kuo2Init = { 1, 3, 7, 11, 31, 27, 47, 147, 467, 505, 1991, 2247, 4207, 0 }; - static ulong[] dim971Kuo2Init = { 1, 3, 1, 5, 9, 11, 89, 199, 359, 723, 1203, 1511, 7915, 0 }; - static ulong[] dim972Kuo2Init = { 1, 3, 5, 9, 27, 63, 93, 19, 305, 641, 997, 1725, 5681, 0 }; - static ulong[] dim973Kuo2Init = { 1, 3, 3, 3, 13, 19, 9, 43, 99, 111, 1353, 935, 7765, 0 }; - static ulong[] dim974Kuo2Init = { 1, 3, 1, 9, 5, 39, 109, 79, 497, 351, 1345, 3019, 5909, 0 }; - static ulong[] dim975Kuo2Init = { 1, 1, 3, 1, 13, 29, 11, 199, 31, 443, 1587, 3397, 7045, 0 }; - static ulong[] dim976Kuo2Init = { 1, 1, 1, 11, 7, 9, 49, 107, 153, 207, 887, 2135, 1389, 0 }; - static ulong[] dim977Kuo2Init = { 1, 1, 1, 3, 29, 53, 111, 143, 421, 521, 1099, 1709, 7027, 0 }; - static ulong[] dim978Kuo2Init = { 1, 1, 5, 5, 5, 19, 127, 99, 501, 819, 1729, 1701, 5829, 0 }; - static ulong[] dim979Kuo2Init = { 1, 3, 7, 5, 7, 15, 43, 49, 223, 793, 889, 793, 271, 0 }; - static ulong[] dim980Kuo2Init = { 1, 3, 5, 11, 27, 27, 55, 69, 185, 511, 951, 2821, 5357, 0 }; - static ulong[] dim981Kuo2Init = { 1, 3, 7, 13, 17, 19, 31, 9, 401, 397, 829, 1063, 693, 0 }; - static ulong[] dim982Kuo2Init = { 1, 1, 7, 9, 21, 13, 75, 13, 327, 929, 955, 1421, 2809, 0 }; - static ulong[] dim983Kuo2Init = { 1, 1, 3, 15, 17, 5, 115, 231, 29, 23, 1743, 779, 5083, 0 }; - static ulong[] dim984Kuo2Init = { 1, 1, 7, 11, 9, 51, 93, 3, 155, 111, 243, 3889, 6733, 0 }; - static ulong[] dim985Kuo2Init = { 1, 1, 5, 9, 29, 63, 119, 145, 391, 1021, 503, 555, 4657, 0 }; - static ulong[] dim986Kuo2Init = { 1, 1, 1, 15, 15, 41, 69, 131, 365, 195, 1809, 2773, 4067, 0 }; - static ulong[] dim987Kuo2Init = { 1, 1, 1, 15, 5, 3, 119, 63, 243, 759, 2037, 3443, 5771, 0 }; - static ulong[] dim988Kuo2Init = { 1, 3, 5, 5, 1, 1, 21, 163, 481, 781, 769, 3031, 2707, 0 }; - static ulong[] dim989Kuo2Init = { 1, 1, 5, 7, 15, 29, 3, 119, 13, 977, 1759, 2327, 3961, 0 }; - static ulong[] dim990Kuo2Init = { 1, 1, 3, 1, 9, 25, 55, 131, 335, 289, 1049, 3589, 3131, 0 }; - static ulong[] dim991Kuo2Init = { 1, 1, 7, 1, 27, 55, 113, 97, 249, 817, 1497, 3773, 6183, 0 }; - static ulong[] dim992Kuo2Init = { 1, 3, 3, 7, 3, 15, 11, 157, 201, 145, 1741, 721, 4945, 0 }; - static ulong[] dim993Kuo2Init = { 1, 1, 7, 3, 19, 9, 123, 151, 169, 841, 65, 2463, 5357, 0 }; - static ulong[] dim994Kuo2Init = { 1, 3, 1, 11, 5, 31, 123, 69, 93, 541, 131, 1469, 5791, 0 }; - static ulong[] dim995Kuo2Init = { 1, 3, 5, 1, 25, 23, 115, 69, 333, 457, 17, 1155, 523, 0 }; - static ulong[] dim996Kuo2Init = { 1, 3, 5, 11, 11, 51, 21, 145, 209, 557, 1109, 2293, 4631, 0 }; - static ulong[] dim997Kuo2Init = { 1, 1, 7, 5, 11, 21, 107, 41, 409, 485, 1745, 3471, 1699, 0 }; - static ulong[] dim998Kuo2Init = { 1, 1, 3, 7, 5, 47, 65, 79, 299, 191, 381, 3803, 6499, 0 }; - static ulong[] dim999Kuo2Init = { 1, 3, 3, 7, 19, 11, 73, 69, 461, 777, 1871, 47, 1281, 0 }; - static ulong[] dim1000Kuo2Init = { 1, 3, 5, 7, 13, 39, 63, 103, 103, 845, 1023, 3241, 1291, 0 }; - static ulong[] dim1001Kuo2Init = { 1, 1, 5, 13, 3, 11, 103, 135, 403, 801, 847, 371, 6243, 0 }; - static ulong[] dim1002Kuo2Init = { 1, 3, 1, 5, 21, 57, 19, 205, 33, 399, 777, 2981, 2365, 0 }; - static ulong[] dim1003Kuo2Init = { 1, 1, 1, 5, 17, 11, 105, 23, 243, 581, 1391, 1509, 8009, 0 }; - static ulong[] dim1004Kuo2Init = { 1, 3, 3, 3, 11, 13, 85, 107, 181, 89, 1323, 3059, 5097, 0 }; - static ulong[] dim1005Kuo2Init = { 1, 1, 1, 15, 1, 29, 57, 221, 389, 127, 841, 1727, 6217, 0 }; - static ulong[] dim1006Kuo2Init = { 1, 3, 1, 9, 25, 51, 89, 67, 257, 921, 621, 1523, 3449, 0 }; - static ulong[] dim1007Kuo2Init = { 1, 3, 5, 5, 25, 15, 25, 47, 29, 775, 1925, 3819, 8063, 0 }; - static ulong[] dim1008Kuo2Init = { 1, 1, 1, 5, 25, 55, 89, 75, 47, 135, 1155, 1923, 2241, 0 }; - static ulong[] dim1009Kuo2Init = { 1, 3, 5, 9, 29, 5, 55, 43, 355, 879, 127, 3565, 2583, 0 }; - static ulong[] dim1010Kuo2Init = { 1, 1, 3, 13, 23, 47, 27, 63, 217, 119, 357, 423, 5897, 0 }; - static ulong[] dim1011Kuo2Init = { 1, 3, 5, 1, 23, 1, 89, 255, 381, 175, 1069, 3809, 1743, 0 }; - static ulong[] dim1012Kuo2Init = { 1, 1, 7, 3, 7, 35, 47, 159, 347, 543, 187, 1103, 5019, 0 }; - static ulong[] dim1013Kuo2Init = { 1, 1, 1, 7, 19, 3, 89, 15, 487, 541, 625, 1711, 3713, 0 }; - static ulong[] dim1014Kuo2Init = { 1, 1, 5, 15, 17, 61, 13, 45, 359, 107, 1487, 121, 6919, 0 }; - static ulong[] dim1015Kuo2Init = { 1, 3, 3, 3, 1, 5, 99, 255, 147, 737, 1675, 4069, 7685, 0 }; - static ulong[] dim1016Kuo2Init = { 1, 3, 7, 1, 5, 33, 39, 217, 255, 833, 661, 3411, 7273, 0 }; - static ulong[] dim1017Kuo2Init = { 1, 3, 3, 5, 9, 41, 25, 223, 319, 45, 687, 3861, 2603, 0 }; - static ulong[] dim1018Kuo2Init = { 1, 1, 3, 15, 15, 43, 61, 163, 45, 835, 545, 561, 4895, 0 }; - static ulong[] dim1019Kuo2Init = { 1, 3, 7, 3, 21, 61, 65, 119, 337, 609, 1185, 2863, 1431, 0 }; - static ulong[] dim1020Kuo2Init = { 1, 1, 3, 3, 29, 49, 51, 173, 107, 21, 1655, 1333, 4703, 0 }; - static ulong[] dim1021Kuo2Init = { 1, 3, 1, 3, 27, 23, 111, 77, 3, 789, 943, 3089, 2865, 0 }; - static ulong[] dim1022Kuo2Init = { 1, 3, 1, 1, 5, 7, 85, 209, 317, 241, 1159, 2193, 229, 0 }; - static ulong[] dim1023Kuo2Init = { 1, 1, 3, 13, 23, 27, 115, 111, 265, 427, 1457, 2281, 2235, 0 }; - static ulong[] dim1024Kuo2Init = { 1, 3, 1, 13, 5, 51, 21, 125, 335, 359, 1189, 1095, 6843, 0 }; - static ulong[] dim1025Kuo2Init = { 1, 3, 5, 7, 5, 17, 93, 43, 297, 109, 1721, 3991, 6861, 0 }; - static ulong[] dim1026Kuo2Init = { 1, 3, 7, 7, 23, 45, 61, 149, 89, 1009, 937, 2477, 1617, 0 }; - static ulong[] dim1027Kuo2Init = { 1, 1, 3, 1, 23, 19, 21, 29, 481, 771, 261, 2377, 2323, 0 }; - static ulong[] dim1028Kuo2Init = { 1, 1, 3, 7, 29, 21, 99, 159, 219, 983, 1169, 667, 3073, 0 }; - static ulong[] dim1029Kuo2Init = { 1, 3, 5, 9, 7, 61, 69, 197, 29, 3, 1767, 2113, 689, 0 }; - static ulong[] dim1030Kuo2Init = { 1, 1, 3, 7, 9, 37, 45, 11, 405, 243, 661, 2545, 5185, 0 }; - static ulong[] dim1031Kuo2Init = { 1, 1, 7, 3, 7, 23, 13, 193, 91, 551, 1963, 2663, 7605, 0 }; - static ulong[] dim1032Kuo2Init = { 1, 1, 1, 1, 27, 17, 79, 251, 103, 33, 45, 2517, 3611, 0 }; - static ulong[] dim1033Kuo2Init = { 1, 3, 3, 1, 19, 57, 15, 175, 77, 299, 1805, 3331, 1365, 0 }; - static ulong[] dim1034Kuo2Init = { 1, 1, 3, 5, 31, 59, 51, 85, 359, 197, 679, 3017, 7929, 0 }; - static ulong[] dim1035Kuo2Init = { 1, 3, 7, 13, 15, 19, 71, 31, 69, 353, 489, 1167, 337, 0 }; - static ulong[] dim1036Kuo2Init = { 1, 1, 3, 13, 5, 33, 35, 33, 345, 63, 1775, 3475, 1375, 0 }; - static ulong[] dim1037Kuo2Init = { 1, 1, 3, 1, 29, 53, 109, 3, 191, 1011, 1043, 3057, 4757, 0 }; - static ulong[] dim1038Kuo2Init = { 1, 1, 5, 11, 3, 21, 101, 137, 155, 959, 683, 1407, 1239, 0 }; - static ulong[] dim1039Kuo2Init = { 1, 3, 5, 13, 3, 9, 117, 81, 143, 753, 561, 871, 2417, 0 }; - static ulong[] dim1040Kuo2Init = { 1, 1, 7, 7, 25, 11, 33, 173, 321, 487, 33, 551, 6613, 0 }; - static ulong[] dim1041Kuo2Init = { 1, 3, 5, 7, 3, 29, 9, 133, 251, 561, 975, 3153, 1115, 0 }; - static ulong[] dim1042Kuo2Init = { 1, 3, 5, 3, 1, 11, 89, 145, 33, 967, 365, 3661, 2917, 0 }; - static ulong[] dim1043Kuo2Init = { 1, 3, 7, 5, 21, 55, 49, 139, 507, 405, 99, 2819, 6541, 0 }; - static ulong[] dim1044Kuo2Init = { 1, 1, 7, 1, 13, 41, 77, 53, 185, 995, 2045, 1659, 1081, 0 }; - static ulong[] dim1045Kuo2Init = { 1, 3, 1, 3, 5, 29, 25, 111, 173, 793, 953, 2825, 673, 0 }; - static ulong[] dim1046Kuo2Init = { 1, 3, 1, 3, 13, 3, 73, 39, 143, 603, 253, 2879, 3827, 0 }; - static ulong[] dim1047Kuo2Init = { 1, 3, 1, 11, 3, 35, 93, 237, 401, 1005, 1047, 3065, 6285, 0 }; - static ulong[] dim1048Kuo2Init = { 1, 3, 1, 13, 7, 7, 17, 65, 107, 971, 999, 623, 6491, 0 }; - static ulong[] dim1049Kuo2Init = { 1, 3, 3, 11, 31, 1, 83, 111, 255, 969, 871, 3459, 2419, 0 }; - static ulong[] dim1050Kuo2Init = { 1, 3, 1, 7, 3, 49, 99, 27, 253, 937, 1237, 343, 6133, 0 }; - static ulong[] dim1051Kuo2Init = { 1, 1, 5, 11, 31, 7, 83, 75, 77, 583, 847, 2263, 1925, 0 }; - static ulong[] dim1052Kuo2Init = { 1, 1, 3, 11, 3, 37, 119, 229, 411, 953, 1087, 3005, 1521, 0 }; - static ulong[] dim1053Kuo2Init = { 1, 3, 7, 13, 5, 53, 125, 207, 297, 465, 1989, 1769, 5113, 0 }; - static ulong[] dim1054Kuo2Init = { 1, 3, 5, 11, 13, 13, 9, 105, 303, 641, 997, 929, 393, 0 }; - static ulong[] dim1055Kuo2Init = { 1, 3, 5, 9, 21, 21, 125, 49, 509, 993, 317, 2367, 2775, 0 }; - static ulong[] dim1056Kuo2Init = { 1, 3, 3, 9, 15, 1, 91, 101, 339, 625, 1521, 2285, 1847, 0 }; - static ulong[] dim1057Kuo2Init = { 1, 1, 5, 15, 15, 31, 57, 253, 407, 715, 1143, 3707, 5105, 0 }; - static ulong[] dim1058Kuo2Init = { 1, 3, 1, 5, 21, 1, 77, 139, 499, 777, 349, 1647, 1389, 0 }; - static ulong[] dim1059Kuo2Init = { 1, 3, 5, 5, 11, 55, 29, 209, 491, 823, 1961, 3833, 5825, 0 }; - static ulong[] dim1060Kuo2Init = { 1, 1, 7, 11, 3, 21, 43, 147, 83, 245, 139, 3585, 975, 0 }; - static ulong[] dim1061Kuo2Init = { 1, 1, 1, 3, 19, 9, 19, 251, 163, 85, 239, 2573, 1079, 0 }; - static ulong[] dim1062Kuo2Init = { 1, 1, 5, 13, 27, 35, 27, 191, 279, 589, 1737, 2759, 1691, 0 }; - static ulong[] dim1063Kuo2Init = { 1, 1, 7, 3, 17, 5, 47, 173, 183, 713, 667, 3683, 2167, 0 }; - static ulong[] dim1064Kuo2Init = { 1, 3, 5, 13, 25, 41, 29, 125, 173, 325, 1341, 481, 365, 0 }; - static ulong[] dim1065Kuo2Init = { 1, 3, 1, 5, 27, 61, 23, 11, 265, 255, 801, 921, 7145, 0 }; - static ulong[] dim1066Kuo2Init = { 1, 3, 5, 5, 27, 49, 27, 245, 253, 787, 1451, 2349, 2125, 0 }; - static ulong[] dim1067Kuo2Init = { 1, 1, 7, 7, 13, 31, 61, 215, 339, 315, 377, 1121, 2667, 0 }; - static ulong[] dim1068Kuo2Init = { 1, 3, 5, 9, 31, 63, 27, 115, 367, 939, 437, 1771, 1219, 0 }; - static ulong[] dim1069Kuo2Init = { 1, 1, 3, 5, 3, 7, 33, 147, 177, 249, 649, 2505, 4705, 0 }; - static ulong[] dim1070Kuo2Init = { 1, 3, 1, 9, 11, 31, 23, 237, 223, 311, 493, 1255, 2121, 0 }; - static ulong[] dim1071Kuo2Init = { 1, 3, 5, 7, 5, 43, 51, 1, 425, 115, 1487, 373, 3765, 0 }; - static ulong[] dim1072Kuo2Init = { 1, 3, 3, 9, 3, 11, 125, 31, 375, 73, 673, 1933, 7763, 0 }; - static ulong[] dim1073Kuo2Init = { 1, 1, 3, 7, 31, 43, 67, 177, 33, 693, 185, 137, 4869, 0 }; - static ulong[] dim1074Kuo2Init = { 1, 1, 1, 9, 21, 53, 111, 41, 249, 845, 193, 2519, 4745, 0 }; - static ulong[] dim1075Kuo2Init = { 1, 3, 5, 3, 11, 15, 11, 249, 325, 561, 411, 71, 6973, 0 }; - static ulong[] dim1076Kuo2Init = { 1, 1, 7, 5, 5, 13, 31, 113, 149, 475, 869, 627, 2789, 0 }; - static ulong[] dim1077Kuo2Init = { 1, 1, 1, 5, 7, 23, 49, 65, 201, 111, 1061, 393, 2101, 0 }; - static ulong[] dim1078Kuo2Init = { 1, 1, 3, 5, 23, 47, 49, 111, 315, 227, 1985, 3579, 875, 0 }; - static ulong[] dim1079Kuo2Init = { 1, 3, 5, 5, 21, 17, 101, 135, 475, 505, 51, 3203, 1735, 0 }; - static ulong[] dim1080Kuo2Init = { 1, 1, 7, 15, 19, 41, 53, 197, 117, 315, 1663, 143, 1081, 0 }; - static ulong[] dim1081Kuo2Init = { 1, 1, 3, 7, 5, 29, 87, 39, 235, 675, 1101, 1257, 4045, 0 }; - static ulong[] dim1082Kuo2Init = { 1, 3, 5, 15, 25, 49, 63, 125, 447, 181, 357, 3017, 6861, 0 }; - static ulong[] dim1083Kuo2Init = { 1, 1, 5, 15, 31, 21, 61, 197, 133, 85, 913, 3031, 855, 0 }; - static ulong[] dim1084Kuo2Init = { 1, 1, 5, 7, 31, 45, 111, 243, 277, 569, 1311, 125, 3417, 0 }; - static ulong[] dim1085Kuo2Init = { 1, 1, 3, 11, 9, 49, 127, 151, 407, 407, 915, 1831, 4093, 0 }; - static ulong[] dim1086Kuo2Init = { 1, 3, 5, 11, 3, 47, 69, 97, 315, 993, 845, 67, 39, 0 }; - static ulong[] dim1087Kuo2Init = { 1, 3, 3, 11, 1, 5, 105, 115, 293, 187, 1369, 3039, 6833, 0 }; - static ulong[] dim1088Kuo2Init = { 1, 3, 3, 15, 23, 19, 15, 59, 139, 523, 1599, 1773, 8059, 0 }; - static ulong[] dim1089Kuo2Init = { 1, 1, 1, 13, 3, 9, 39, 205, 115, 35, 1737, 2713, 3263, 0 }; - static ulong[] dim1090Kuo2Init = { 1, 1, 3, 7, 11, 41, 71, 61, 329, 11, 1069, 2565, 6359, 0 }; - static ulong[] dim1091Kuo2Init = { 1, 3, 7, 9, 1, 57, 5, 17, 117, 37, 827, 3449, 1297, 0 }; - static ulong[] dim1092Kuo2Init = { 1, 1, 5, 1, 29, 49, 3, 7, 145, 183, 1777, 2351, 6675, 0 }; - static ulong[] dim1093Kuo2Init = { 1, 1, 5, 7, 5, 57, 97, 61, 197, 713, 695, 2385, 1917, 0 }; - static ulong[] dim1094Kuo2Init = { 1, 3, 1, 11, 21, 49, 41, 133, 307, 473, 1983, 3693, 3241, 0 }; - static ulong[] dim1095Kuo2Init = { 1, 1, 5, 1, 3, 59, 47, 141, 49, 531, 1237, 3085, 5651, 0 }; - static ulong[] dim1096Kuo2Init = { 1, 1, 5, 1, 17, 21, 3, 101, 169, 475, 473, 255, 6637, 0 }; - static ulong[] dim1097Kuo2Init = { 1, 3, 5, 1, 19, 25, 71, 251, 327, 715, 1945, 1123, 4911, 0 }; - static ulong[] dim1098Kuo2Init = { 1, 1, 5, 3, 15, 55, 127, 221, 163, 281, 1391, 4083, 7995, 0 }; - static ulong[] dim1099Kuo2Init = { 1, 1, 3, 9, 27, 7, 65, 143, 433, 599, 1971, 2169, 813, 0 }; - static ulong[] dim1100Kuo2Init = { 1, 3, 3, 1, 9, 49, 107, 103, 381, 1005, 705, 2385, 5007, 0 }; - static ulong[] dim1101Kuo2Init = { 1, 3, 5, 7, 15, 45, 41, 175, 137, 1019, 1869, 2337, 3433, 0 }; - static ulong[] dim1102Kuo2Init = { 1, 3, 7, 15, 15, 51, 89, 193, 325, 391, 197, 2607, 6717, 0 }; - static ulong[] dim1103Kuo2Init = { 1, 3, 7, 1, 15, 11, 113, 245, 255, 481, 237, 3205, 4551, 0 }; - static ulong[] dim1104Kuo2Init = { 1, 3, 3, 1, 11, 19, 93, 97, 67, 793, 1165, 989, 4643, 0 }; - static ulong[] dim1105Kuo2Init = { 1, 1, 1, 15, 17, 51, 63, 37, 353, 745, 1439, 2599, 2771, 0 }; - static ulong[] dim1106Kuo2Init = { 1, 1, 7, 9, 7, 3, 87, 245, 257, 399, 311, 3063, 3801, 0 }; - static ulong[] dim1107Kuo2Init = { 1, 1, 5, 11, 13, 3, 83, 39, 165, 827, 1581, 2491, 2067, 0 }; - static ulong[] dim1108Kuo2Init = { 1, 3, 3, 3, 21, 3, 21, 95, 505, 971, 1599, 2479, 4155, 0 }; - static ulong[] dim1109Kuo2Init = { 1, 3, 1, 11, 11, 57, 115, 83, 473, 457, 2015, 1855, 1851, 0 }; - static ulong[] dim1110Kuo2Init = { 1, 3, 7, 11, 29, 7, 73, 203, 445, 771, 1225, 3587, 245, 0 }; - static ulong[] dim1111Kuo2Init = { 1, 3, 5, 1, 13, 53, 79, 245, 347, 277, 779, 653, 6213, 7661, 0 }; - static ulong[] dim1112Kuo2Init = { 1, 3, 5, 3, 17, 43, 31, 251, 177, 337, 157, 3171, 3813, 7787, 0 }; - static ulong[] dim1113Kuo2Init = { 1, 3, 5, 9, 23, 9, 7, 45, 65, 517, 1449, 1943, 4995, 2403, 0 }; - static ulong[] dim1114Kuo2Init = { 1, 3, 3, 9, 19, 45, 71, 91, 491, 113, 1041, 717, 681, 13331, 0 }; - static ulong[] dim1115Kuo2Init = { 1, 3, 5, 9, 15, 35, 19, 25, 119, 677, 1355, 3065, 6325, 7821, 0 }; - static ulong[] dim1116Kuo2Init = { 1, 3, 7, 5, 27, 63, 41, 117, 271, 327, 1731, 3501, 4489, 11119, 0 }; - static ulong[] dim1117Kuo2Init = { 1, 1, 3, 5, 11, 35, 51, 79, 347, 905, 857, 3647, 4773, 15111, 0 }; - static ulong[] dim1118Kuo2Init = { 1, 3, 7, 3, 21, 3, 19, 147, 429, 275, 1813, 1937, 4489, 7993, 0 }; - static ulong[] dim1119Kuo2Init = { 1, 3, 7, 9, 27, 59, 77, 179, 209, 897, 807, 1121, 7575, 9769, 0 }; - static ulong[] dim1120Kuo2Init = { 1, 3, 3, 9, 15, 39, 81, 183, 213, 419, 125, 1943, 5621, 9073, 0 }; - static ulong[] dim1121Kuo2Init = { 1, 3, 1, 7, 11, 41, 111, 169, 31, 807, 1277, 3293, 3233, 409, 0 }; - static ulong[] dim1122Kuo2Init = { 1, 1, 3, 11, 31, 11, 39, 69, 429, 185, 1523, 469, 5453, 12453, 0 }; - static ulong[] dim1123Kuo2Init = { 1, 1, 5, 13, 15, 59, 5, 179, 457, 803, 1503, 633, 7591, 8861, 0 }; - static ulong[] dim1124Kuo2Init = { 1, 3, 5, 13, 19, 47, 15, 37, 271, 361, 1403, 2043, 6671, 4171, 0 }; - static ulong[] dim1125Kuo2Init = { 1, 3, 3, 15, 3, 37, 107, 29, 505, 465, 955, 2431, 5899, 11363, 0 }; - static ulong[] dim1126Kuo2Init = { 1, 1, 3, 9, 11, 49, 71, 191, 197, 365, 757, 309, 3881, 9427, 0 }; - static ulong[] dim1127Kuo2Init = { 1, 1, 7, 13, 11, 9, 3, 109, 403, 403, 867, 325, 329, 13675, 0 }; - static ulong[] dim1128Kuo2Init = { 1, 3, 3, 7, 13, 61, 33, 125, 431, 797, 565, 4065, 6375, 10343, 0 }; - static ulong[] dim1129Kuo2Init = { 1, 1, 1, 1, 23, 59, 45, 103, 231, 829, 1197, 1547, 2319, 13541, 0 }; - static ulong[] dim1130Kuo2Init = { 1, 1, 7, 13, 17, 59, 119, 51, 305, 153, 571, 1323, 6427, 12291, 0 }; - static ulong[] dim1131Kuo2Init = { 1, 3, 3, 9, 21, 17, 27, 223, 311, 1015, 1925, 1497, 6407, 15517, 0 }; - static ulong[] dim1132Kuo2Init = { 1, 3, 1, 15, 13, 63, 99, 163, 35, 583, 787, 2679, 4991, 5933, 0 }; - static ulong[] dim1133Kuo2Init = { 1, 1, 3, 7, 31, 43, 77, 141, 153, 455, 745, 1377, 7363, 7301, 0 }; - static ulong[] dim1134Kuo2Init = { 1, 1, 3, 15, 23, 49, 1, 149, 393, 483, 1577, 1885, 7483, 9769, 0 }; - static ulong[] dim1135Kuo2Init = { 1, 1, 7, 11, 23, 5, 103, 143, 35, 899, 2001, 2643, 2533, 7827, 0 }; - static ulong[] dim1136Kuo2Init = { 1, 3, 5, 5, 13, 49, 121, 113, 75, 271, 1111, 535, 1255, 6977, 0 }; - static ulong[] dim1137Kuo2Init = { 1, 1, 1, 3, 25, 53, 11, 151, 107, 985, 1933, 2791, 4101, 14515, 0 }; - static ulong[] dim1138Kuo2Init = { 1, 3, 1, 7, 29, 39, 73, 103, 139, 65, 573, 3909, 2645, 9603, 0 }; - static ulong[] dim1139Kuo2Init = { 1, 3, 7, 9, 3, 31, 45, 79, 195, 749, 65, 4041, 3915, 3137, 0 }; - static ulong[] dim1140Kuo2Init = { 1, 3, 3, 13, 5, 37, 87, 211, 61, 237, 1903, 755, 4077, 14791, 0 }; - static ulong[] dim1141Kuo2Init = { 1, 1, 7, 5, 3, 63, 63, 45, 357, 887, 1511, 2503, 6669, 3163, 0 }; - static ulong[] dim1142Kuo2Init = { 1, 3, 1, 5, 17, 29, 113, 117, 487, 369, 1337, 3129, 3517, 2107, 0 }; - static ulong[] dim1143Kuo2Init = { 1, 1, 7, 1, 7, 13, 15, 203, 421, 267, 1049, 1645, 2047, 11733, 0 }; - static ulong[] dim1144Kuo2Init = { 1, 1, 1, 5, 17, 27, 5, 101, 109, 651, 601, 673, 67, 8539, 0 }; - static ulong[] dim1145Kuo2Init = { 1, 1, 5, 13, 9, 53, 85, 165, 197, 979, 925, 419, 4631, 15269, 0 }; - static ulong[] dim1146Kuo2Init = { 1, 3, 7, 15, 5, 5, 61, 205, 257, 279, 81, 4059, 2375, 12821, 0 }; - static ulong[] dim1147Kuo2Init = { 1, 3, 1, 11, 27, 41, 39, 41, 75, 1017, 529, 2709, 3385, 3879, 0 }; - static ulong[] dim1148Kuo2Init = { 1, 3, 1, 13, 25, 63, 125, 137, 27, 839, 617, 2129, 711, 3955, 0 }; - static ulong[] dim1149Kuo2Init = { 1, 3, 5, 5, 27, 19, 27, 51, 369, 593, 605, 2471, 6995, 5957, 0 }; - static ulong[] dim1150Kuo2Init = { 1, 3, 3, 5, 9, 11, 63, 157, 447, 713, 1145, 2013, 3061, 13763, 0 }; - static ulong[] dim1151Kuo2Init = { 1, 1, 5, 1, 15, 51, 49, 185, 337, 109, 1335, 841, 7005, 8969, 0 }; - static ulong[] dim1152Kuo2Init = { 1, 1, 5, 15, 17, 25, 31, 135, 43, 469, 1895, 3369, 6981, 8515, 0 }; - static ulong[] dim1153Kuo2Init = { 1, 1, 5, 9, 21, 11, 117, 79, 39, 63, 1355, 2309, 4409, 6463, 0 }; - static ulong[] dim1154Kuo2Init = { 1, 3, 3, 15, 11, 55, 55, 75, 251, 209, 1715, 697, 2199, 2155, 0 }; - static ulong[] dim1155Kuo2Init = { 1, 3, 5, 13, 31, 29, 55, 23, 391, 1011, 1701, 787, 8165, 1315, 0 }; - static ulong[] dim1156Kuo2Init = { 1, 1, 7, 7, 23, 55, 125, 15, 77, 107, 2043, 1501, 727, 13693, 0 }; - static ulong[] dim1157Kuo2Init = { 1, 1, 7, 7, 27, 37, 47, 247, 227, 595, 175, 3459, 395, 9903, 0 }; - static ulong[] dim1158Kuo2Init = { 1, 3, 5, 9, 7, 7, 61, 81, 405, 117, 51, 3715, 2757, 2797, 0 }; - static ulong[] dim1159Kuo2Init = { 1, 1, 1, 15, 15, 25, 9, 109, 497, 395, 777, 1187, 7451, 15959, 0 }; - static ulong[] dim1160Kuo2Init = { 1, 3, 3, 7, 7, 23, 69, 27, 97, 145, 1165, 993, 235, 1785, 0 }; - static ulong[] dim1161Kuo2Init = { 1, 1, 3, 15, 17, 49, 73, 27, 223, 83, 295, 1425, 4817, 7325, 0 }; - static ulong[] dim1162Kuo2Init = { 1, 3, 7, 5, 25, 13, 69, 119, 483, 635, 1105, 2547, 457, 5607, 0 }; - static ulong[] dim1163Kuo2Init = { 1, 1, 7, 9, 13, 29, 69, 7, 223, 95, 1255, 459, 4633, 12609, 0 }; - static ulong[] dim1164Kuo2Init = { 1, 1, 1, 1, 15, 57, 105, 161, 429, 615, 201, 2601, 3169, 3163, 0 }; - static ulong[] dim1165Kuo2Init = { 1, 3, 3, 1, 5, 5, 127, 129, 457, 59, 459, 3731, 2069, 9147, 0 }; - static ulong[] dim1166Kuo2Init = { 1, 1, 1, 7, 25, 45, 101, 111, 119, 739, 157, 3967, 6427, 2845, 0 }; - static ulong[] dim1167Kuo2Init = { 1, 3, 1, 9, 15, 15, 105, 147, 119, 815, 1263, 2201, 5413, 15255, 0 }; - static ulong[] dim1168Kuo2Init = { 1, 3, 1, 5, 15, 47, 87, 131, 451, 805, 1043, 2917, 5495, 5103, 0 }; - static ulong[] dim1169Kuo2Init = { 1, 1, 3, 11, 29, 35, 33, 135, 509, 425, 723, 1947, 7237, 8941, 0 }; - static ulong[] dim1170Kuo2Init = { 1, 1, 3, 7, 5, 39, 83, 83, 353, 685, 195, 385, 2431, 8753, 0 }; - static ulong[] dim1171Kuo2Init = { 1, 3, 3, 7, 25, 45, 3, 129, 413, 1005, 625, 3503, 5473, 3577, 0 }; - static ulong[] dim1172Kuo2Init = { 1, 1, 3, 13, 7, 37, 29, 163, 397, 671, 1043, 3581, 465, 9521, 0 }; - static ulong[] dim1173Kuo2Init = { 1, 1, 3, 5, 31, 21, 111, 95, 385, 787, 1205, 795, 4779, 11421, 0 }; - static ulong[] dim1174Kuo2Init = { 1, 1, 1, 3, 25, 15, 51, 149, 423, 907, 863, 1535, 5809, 1069, 0 }; - static ulong[] dim1175Kuo2Init = { 1, 3, 5, 5, 19, 57, 51, 49, 39, 349, 1453, 3091, 4861, 8771, 0 }; - static ulong[] dim1176Kuo2Init = { 1, 1, 5, 15, 1, 45, 93, 85, 511, 607, 793, 1023, 1525, 535, 0 }; - static ulong[] dim1177Kuo2Init = { 1, 3, 3, 11, 7, 53, 83, 139, 173, 947, 1381, 433, 5821, 4173, 0 }; - static ulong[] dim1178Kuo2Init = { 1, 3, 5, 9, 27, 17, 17, 237, 427, 295, 929, 1539, 2373, 6671, 0 }; - static ulong[] dim1179Kuo2Init = { 1, 1, 1, 1, 9, 53, 87, 129, 443, 729, 1067, 359, 789, 7637, 0 }; - static ulong[] dim1180Kuo2Init = { 1, 1, 1, 7, 7, 23, 71, 115, 343, 207, 889, 3561, 475, 3437, 0 }; - static ulong[] dim1181Kuo2Init = { 1, 3, 5, 9, 17, 31, 85, 135, 155, 269, 575, 537, 5305, 979, 0 }; - static ulong[] dim1182Kuo2Init = { 1, 3, 1, 5, 19, 41, 61, 103, 49, 93, 733, 1791, 3577, 1763, 0 }; - static ulong[] dim1183Kuo2Init = { 1, 1, 3, 3, 27, 23, 3, 143, 341, 847, 1859, 995, 5277, 5025, 0 }; - static ulong[] dim1184Kuo2Init = { 1, 3, 5, 13, 7, 29, 37, 201, 359, 255, 1543, 3735, 1217, 7251, 0 }; - static ulong[] dim1185Kuo2Init = { 1, 1, 7, 9, 27, 45, 15, 187, 181, 571, 1345, 1473, 519, 7499, 0 }; - static ulong[] dim1186Kuo2Init = { 1, 1, 7, 7, 11, 11, 75, 179, 455, 495, 283, 2995, 1515, 5497, 0 }; - static ulong[] dim1187Kuo2Init = { 1, 1, 7, 3, 11, 19, 91, 165, 175, 967, 1719, 739, 103, 15259, 0 }; - static ulong[] dim1188Kuo2Init = { 1, 3, 3, 9, 7, 5, 121, 65, 83, 687, 837, 2303, 1953, 15419, 0 }; - static ulong[] dim1189Kuo2Init = { 1, 3, 1, 13, 31, 39, 43, 69, 129, 815, 1419, 3179, 595, 14471, 0 }; - static ulong[] dim1190Kuo2Init = { 1, 1, 5, 9, 9, 33, 75, 141, 271, 259, 91, 553, 7521, 9591, 0 }; - static ulong[] dim1191Kuo2Init = { 1, 1, 5, 1, 27, 55, 125, 41, 103, 161, 9, 1339, 3205, 973, 0 }; - static ulong[] dim1192Kuo2Init = { 1, 1, 3, 3, 13, 15, 93, 179, 435, 667, 1365, 169, 4685, 16175, 0 }; - static ulong[] dim1193Kuo2Init = { 1, 1, 5, 9, 17, 55, 45, 237, 291, 837, 1019, 2983, 1679, 13583, 0 }; - static ulong[] dim1194Kuo2Init = { 1, 3, 1, 3, 3, 37, 37, 239, 265, 117, 1239, 529, 4855, 11423, 0 }; - static ulong[] dim1195Kuo2Init = { 1, 3, 5, 3, 11, 11, 121, 81, 55, 35, 1551, 775, 6973, 13525, 0 }; - static ulong[] dim1196Kuo2Init = { 1, 3, 3, 11, 15, 19, 49, 117, 269, 147, 1891, 2975, 1779, 9327, 0 }; - static ulong[] dim1197Kuo2Init = { 1, 1, 1, 7, 9, 39, 111, 131, 179, 629, 1807, 3327, 1535, 2845, 0 }; - static ulong[] dim1198Kuo2Init = { 1, 3, 7, 13, 11, 59, 125, 41, 13, 637, 1679, 487, 4655, 8045, 0 }; - static ulong[] dim1199Kuo2Init = { 1, 1, 3, 7, 17, 15, 63, 105, 271, 205, 283, 3427, 1921, 12729, 0 }; - static ulong[] dim1200Kuo2Init = { 1, 1, 3, 5, 13, 57, 23, 141, 261, 829, 1149, 945, 4191, 13277, 0 }; - static ulong[] dim1201Kuo2Init = { 1, 1, 5, 7, 13, 59, 79, 221, 473, 803, 2027, 437, 7823, 14225, 0 }; - static ulong[] dim1202Kuo2Init = { 1, 3, 3, 9, 15, 21, 53, 69, 13, 479, 193, 1031, 4911, 12011, 0 }; - static ulong[] dim1203Kuo2Init = { 1, 1, 5, 7, 25, 7, 99, 81, 21, 247, 1019, 2537, 3647, 8211, 0 }; - static ulong[] dim1204Kuo2Init = { 1, 3, 7, 15, 27, 47, 105, 141, 49, 65, 525, 1717, 1339, 9079, 0 }; - static ulong[] dim1205Kuo2Init = { 1, 1, 7, 3, 27, 1, 31, 135, 175, 997, 1517, 1139, 7975, 14941, 0 }; - static ulong[] dim1206Kuo2Init = { 1, 1, 1, 5, 9, 5, 77, 175, 333, 975, 873, 523, 2967, 9463, 0 }; - static ulong[] dim1207Kuo2Init = { 1, 3, 5, 9, 5, 61, 17, 141, 405, 591, 711, 1077, 2875, 8827, 0 }; - static ulong[] dim1208Kuo2Init = { 1, 3, 1, 11, 9, 13, 29, 9, 443, 717, 2019, 1031, 6459, 6673, 0 }; - static ulong[] dim1209Kuo2Init = { 1, 1, 3, 5, 7, 51, 45, 163, 113, 705, 1411, 3861, 527, 6119, 0 }; - static ulong[] dim1210Kuo2Init = { 1, 1, 1, 5, 9, 43, 57, 79, 221, 131, 1543, 2243, 5277, 6249, 0 }; - static ulong[] dim1211Kuo2Init = { 1, 1, 1, 7, 15, 63, 89, 11, 211, 245, 89, 219, 241, 545, 0 }; - static ulong[] dim1212Kuo2Init = { 1, 3, 3, 7, 31, 21, 97, 43, 457, 941, 363, 3275, 4731, 3167, 0 }; - static ulong[] dim1213Kuo2Init = { 1, 1, 7, 9, 31, 45, 15, 119, 283, 645, 1239, 3835, 5317, 4643, 0 }; - static ulong[] dim1214Kuo2Init = { 1, 1, 5, 3, 23, 31, 49, 67, 487, 935, 1899, 2545, 8135, 12609, 0 }; - static ulong[] dim1215Kuo2Init = { 1, 3, 7, 9, 21, 63, 15, 233, 463, 763, 327, 2585, 4399, 14643, 0 }; - static ulong[] dim1216Kuo2Init = { 1, 1, 7, 9, 13, 5, 95, 11, 239, 507, 955, 569, 6443, 3009, 0 }; - static ulong[] dim1217Kuo2Init = { 1, 3, 5, 9, 31, 27, 99, 251, 487, 383, 1117, 2231, 6541, 10409, 0 }; - static ulong[] dim1218Kuo2Init = { 1, 3, 3, 15, 23, 37, 81, 149, 127, 341, 1749, 207, 2257, 2659, 0 }; - static ulong[] dim1219Kuo2Init = { 1, 1, 7, 9, 15, 7, 59, 63, 187, 719, 1295, 3509, 2293, 4959, 0 }; - static ulong[] dim1220Kuo2Init = { 1, 1, 5, 13, 3, 49, 27, 17, 261, 463, 1719, 793, 4365, 4041, 0 }; - static ulong[] dim1221Kuo2Init = { 1, 3, 3, 7, 7, 37, 19, 133, 197, 789, 383, 1005, 7353, 2431, 0 }; - static ulong[] dim1222Kuo2Init = { 1, 1, 1, 13, 21, 11, 27, 247, 309, 103, 1707, 2555, 2731, 11755, 0 }; - static ulong[] dim1223Kuo2Init = { 1, 3, 1, 15, 13, 45, 119, 233, 387, 781, 851, 3207, 5251, 9741, 0 }; - static ulong[] dim1224Kuo2Init = { 1, 3, 7, 15, 3, 17, 13, 217, 245, 267, 55, 3065, 3733, 2577, 0 }; - static ulong[] dim1225Kuo2Init = { 1, 1, 7, 13, 11, 25, 7, 219, 209, 295, 1725, 359, 5489, 1057, 0 }; - static ulong[] dim1226Kuo2Init = { 1, 3, 1, 3, 7, 1, 93, 33, 485, 977, 1113, 3049, 7015, 14275, 0 }; - static ulong[] dim1227Kuo2Init = { 1, 3, 3, 13, 15, 9, 115, 113, 221, 1, 875, 1485, 3523, 6817, 0 }; - static ulong[] dim1228Kuo2Init = { 1, 1, 5, 15, 3, 41, 113, 5, 7, 1023, 349, 1901, 1223, 11355, 0 }; - static ulong[] dim1229Kuo2Init = { 1, 3, 7, 13, 27, 59, 113, 123, 81, 795, 803, 955, 7101, 7715, 0 }; - static ulong[] dim1230Kuo2Init = { 1, 1, 1, 15, 15, 19, 123, 183, 341, 9, 943, 549, 1261, 8305, 0 }; - static ulong[] dim1231Kuo2Init = { 1, 1, 3, 5, 25, 45, 109, 239, 399, 405, 1859, 3721, 2023, 12543, 0 }; - static ulong[] dim1232Kuo2Init = { 1, 3, 1, 11, 11, 51, 119, 83, 189, 119, 51, 3601, 1589, 3821, 0 }; - static ulong[] dim1233Kuo2Init = { 1, 3, 3, 3, 9, 41, 13, 91, 329, 625, 1837, 2539, 5603, 2135, 0 }; - static ulong[] dim1234Kuo2Init = { 1, 3, 5, 7, 5, 59, 125, 133, 321, 759, 237, 3299, 4663, 15767, 0 }; - static ulong[] dim1235Kuo2Init = { 1, 1, 7, 7, 29, 3, 45, 37, 69, 437, 1321, 3545, 373, 3349, 0 }; - static ulong[] dim1236Kuo2Init = { 1, 1, 1, 13, 13, 47, 87, 33, 93, 639, 673, 1675, 5997, 9049, 0 }; - static ulong[] dim1237Kuo2Init = { 1, 3, 1, 3, 31, 27, 33, 175, 71, 509, 229, 2959, 7929, 7551, 0 }; - static ulong[] dim1238Kuo2Init = { 1, 1, 3, 7, 17, 41, 101, 119, 51, 297, 595, 41, 7919, 6173, 0 }; - static ulong[] dim1239Kuo2Init = { 1, 3, 5, 11, 11, 63, 17, 177, 349, 327, 531, 783, 4025, 3367, 0 }; - static ulong[] dim1240Kuo2Init = { 1, 3, 1, 13, 11, 31, 97, 137, 117, 981, 3, 2873, 6399, 5055, 0 }; - static ulong[] dim1241Kuo2Init = { 1, 3, 7, 11, 9, 63, 53, 237, 255, 161, 1709, 3591, 2569, 8687, 0 }; - static ulong[] dim1242Kuo2Init = { 1, 3, 3, 11, 23, 9, 97, 143, 403, 597, 1651, 933, 1351, 3675, 0 }; - static ulong[] dim1243Kuo2Init = { 1, 1, 1, 9, 23, 11, 93, 103, 245, 797, 723, 4029, 4313, 14217, 0 }; - static ulong[] dim1244Kuo2Init = { 1, 1, 1, 3, 13, 51, 77, 237, 109, 933, 449, 429, 6991, 13475, 0 }; - static ulong[] dim1245Kuo2Init = { 1, 3, 1, 1, 29, 63, 65, 63, 129, 693, 1441, 3877, 3015, 7817, 0 }; - static ulong[] dim1246Kuo2Init = { 1, 1, 7, 3, 7, 57, 63, 129, 15, 257, 739, 3395, 1473, 12735, 0 }; - static ulong[] dim1247Kuo2Init = { 1, 1, 1, 9, 23, 21, 123, 81, 297, 899, 1719, 3523, 4895, 12503, 0 }; - static ulong[] dim1248Kuo2Init = { 1, 1, 3, 1, 9, 3, 61, 7, 251, 1003, 289, 1321, 7041, 6811, 0 }; - static ulong[] dim1249Kuo2Init = { 1, 3, 5, 9, 3, 9, 87, 13, 363, 713, 673, 717, 1449, 6869, 0 }; - static ulong[] dim1250Kuo2Init = { 1, 1, 3, 9, 25, 53, 115, 111, 499, 425, 1037, 3751, 5767, 10047, 0 }; - static ulong[] dim1251Kuo2Init = { 1, 3, 7, 11, 23, 43, 75, 101, 105, 115, 887, 3747, 149, 5513, 0 }; - static ulong[] dim1252Kuo2Init = { 1, 3, 1, 9, 7, 43, 125, 63, 3, 365, 1345, 821, 731, 14007, 0 }; - static ulong[] dim1253Kuo2Init = { 1, 3, 1, 7, 29, 49, 55, 37, 343, 481, 1319, 1167, 4835, 10549, 0 }; - static ulong[] dim1254Kuo2Init = { 1, 1, 7, 13, 11, 33, 123, 91, 301, 765, 1037, 2935, 1213, 10141, 0 }; - static ulong[] dim1255Kuo2Init = { 1, 1, 7, 1, 21, 55, 57, 79, 187, 977, 297, 63, 3431, 10597, 0 }; - static ulong[] dim1256Kuo2Init = { 1, 3, 5, 9, 5, 25, 33, 25, 477, 105, 1757, 2051, 1263, 15421, 0 }; - static ulong[] dim1257Kuo2Init = { 1, 3, 5, 11, 5, 39, 63, 209, 223, 497, 785, 2127, 4293, 7583, 0 }; - static ulong[] dim1258Kuo2Init = { 1, 1, 5, 3, 9, 23, 107, 125, 319, 143, 947, 1135, 4391, 6297, 0 }; - static ulong[] dim1259Kuo2Init = { 1, 3, 7, 15, 19, 21, 103, 161, 5, 739, 1537, 2697, 1827, 8287, 0 }; - static ulong[] dim1260Kuo2Init = { 1, 1, 7, 3, 29, 37, 117, 199, 35, 683, 1539, 2915, 8129, 14785, 0 }; - static ulong[] dim1261Kuo2Init = { 1, 3, 1, 3, 7, 35, 39, 181, 111, 165, 1919, 1583, 4219, 179, 0 }; - static ulong[] dim1262Kuo2Init = { 1, 3, 3, 11, 15, 5, 13, 123, 93, 615, 1811, 3235, 4533, 2423, 0 }; - static ulong[] dim1263Kuo2Init = { 1, 1, 1, 15, 25, 17, 21, 37, 5, 413, 1681, 2297, 5571, 6037, 0 }; - static ulong[] dim1264Kuo2Init = { 1, 1, 1, 9, 27, 21, 7, 139, 235, 163, 1809, 783, 507, 8867, 0 }; - static ulong[] dim1265Kuo2Init = { 1, 3, 7, 9, 23, 57, 1, 55, 311, 687, 1987, 463, 5639, 4795, 0 }; - static ulong[] dim1266Kuo2Init = { 1, 1, 7, 9, 11, 55, 31, 77, 277, 447, 799, 993, 489, 3539, 0 }; - static ulong[] dim1267Kuo2Init = { 1, 1, 1, 5, 27, 19, 23, 207, 11, 81, 1539, 1051, 1155, 11475, 0 }; - static ulong[] dim1268Kuo2Init = { 1, 1, 5, 1, 23, 63, 23, 247, 261, 789, 1305, 3003, 1033, 1883, 0 }; - static ulong[] dim1269Kuo2Init = { 1, 1, 5, 15, 1, 35, 1, 147, 51, 513, 35, 3285, 7461, 13733, 0 }; - static ulong[] dim1270Kuo2Init = { 1, 1, 1, 5, 29, 25, 107, 91, 355, 213, 203, 2371, 1383, 14285, 0 }; - static ulong[] dim1271Kuo2Init = { 1, 3, 7, 13, 11, 35, 109, 171, 229, 209, 375, 2911, 1943, 7037, 0 }; - static ulong[] dim1272Kuo2Init = { 1, 1, 5, 11, 21, 39, 113, 5, 167, 769, 2047, 3083, 7421, 14085, 0 }; - static ulong[] dim1273Kuo2Init = { 1, 3, 7, 13, 13, 27, 83, 67, 171, 671, 1675, 2473, 3241, 15283, 0 }; - static ulong[] dim1274Kuo2Init = { 1, 1, 1, 7, 5, 27, 23, 171, 443, 243, 217, 3349, 1919, 2345, 0 }; - static ulong[] dim1275Kuo2Init = { 1, 1, 1, 11, 7, 1, 41, 25, 47, 835, 1071, 3091, 6133, 7249, 0 }; - static ulong[] dim1276Kuo2Init = { 1, 1, 7, 15, 27, 41, 3, 153, 479, 447, 1457, 2267, 3781, 9851, 0 }; - static ulong[] dim1277Kuo2Init = { 1, 1, 7, 7, 25, 1, 125, 129, 231, 505, 1709, 3117, 6069, 3103, 0 }; - static ulong[] dim1278Kuo2Init = { 1, 3, 3, 13, 9, 53, 73, 93, 185, 1007, 1883, 3087, 7453, 13335, 0 }; - static ulong[] dim1279Kuo2Init = { 1, 1, 1, 5, 7, 51, 65, 189, 397, 73, 377, 2593, 6703, 16145, 0 }; - static ulong[] dim1280Kuo2Init = { 1, 1, 7, 3, 17, 55, 93, 251, 29, 937, 223, 721, 3275, 11881, 0 }; - static ulong[] dim1281Kuo2Init = { 1, 3, 7, 1, 1, 45, 99, 117, 279, 87, 2015, 3681, 5625, 5191, 0 }; - static ulong[] dim1282Kuo2Init = { 1, 3, 7, 9, 7, 63, 23, 83, 277, 959, 693, 3945, 4551, 13711, 0 }; - static ulong[] dim1283Kuo2Init = { 1, 3, 1, 1, 23, 57, 127, 7, 323, 545, 1909, 2399, 4483, 12165, 0 }; - static ulong[] dim1284Kuo2Init = { 1, 3, 1, 7, 23, 37, 39, 213, 45, 949, 661, 397, 189, 2835, 0 }; - static ulong[] dim1285Kuo2Init = { 1, 1, 1, 11, 17, 11, 97, 141, 389, 137, 907, 3939, 1205, 9751, 0 }; - static ulong[] dim1286Kuo2Init = { 1, 1, 5, 9, 25, 45, 53, 101, 43, 503, 777, 1327, 8127, 1977, 0 }; - static ulong[] dim1287Kuo2Init = { 1, 3, 1, 5, 19, 15, 71, 193, 443, 817, 1507, 291, 3781, 5841, 0 }; - static ulong[] dim1288Kuo2Init = { 1, 3, 3, 1, 25, 41, 121, 17, 471, 357, 1193, 3079, 2025, 773, 0 }; - static ulong[] dim1289Kuo2Init = { 1, 1, 3, 9, 5, 31, 123, 35, 103, 439, 1199, 1887, 6923, 9439, 0 }; - static ulong[] dim1290Kuo2Init = { 1, 3, 1, 5, 7, 35, 1, 151, 467, 573, 517, 3681, 4563, 3143, 0 }; - static ulong[] dim1291Kuo2Init = { 1, 3, 1, 7, 19, 61, 43, 57, 217, 113, 1045, 3773, 1197, 14627, 0 }; - static ulong[] dim1292Kuo2Init = { 1, 3, 7, 11, 7, 51, 71, 31, 71, 143, 319, 2979, 849, 14403, 0 }; - static ulong[] dim1293Kuo2Init = { 1, 1, 1, 15, 17, 25, 119, 253, 13, 959, 1217, 261, 2853, 10449, 0 }; - static ulong[] dim1294Kuo2Init = { 1, 3, 7, 15, 23, 19, 71, 205, 63, 915, 317, 1637, 1963, 10047, 0 }; - static ulong[] dim1295Kuo2Init = { 1, 1, 5, 9, 21, 57, 119, 223, 169, 87, 593, 2871, 1201, 4531, 0 }; - static ulong[] dim1296Kuo2Init = { 1, 3, 5, 3, 7, 11, 25, 129, 469, 199, 323, 4021, 2983, 1459, 0 }; - static ulong[] dim1297Kuo2Init = { 1, 3, 1, 1, 7, 39, 41, 75, 75, 113, 985, 3353, 5393, 7055, 0 }; - static ulong[] dim1298Kuo2Init = { 1, 3, 3, 11, 19, 55, 37, 235, 221, 197, 1041, 3447, 8045, 801, 0 }; - static ulong[] dim1299Kuo2Init = { 1, 1, 7, 7, 9, 19, 3, 221, 265, 963, 1815, 469, 2929, 10711, 0 }; - static ulong[] dim1300Kuo2Init = { 1, 3, 1, 5, 27, 11, 59, 57, 91, 235, 1465, 825, 6429, 15537, 0 }; - static ulong[] dim1301Kuo2Init = { 1, 1, 1, 1, 19, 21, 47, 235, 223, 761, 173, 3793, 2197, 10919, 0 }; - static ulong[] dim1302Kuo2Init = { 1, 3, 3, 9, 11, 61, 19, 121, 51, 617, 441, 1889, 6225, 3317, 0 }; - static ulong[] dim1303Kuo2Init = { 1, 3, 1, 7, 25, 27, 65, 163, 165, 7, 1303, 3275, 173, 6923, 0 }; - static ulong[] dim1304Kuo2Init = { 1, 3, 1, 13, 23, 39, 35, 105, 267, 679, 1675, 2837, 1213, 14985, 0 }; - static ulong[] dim1305Kuo2Init = { 1, 1, 5, 1, 21, 39, 1, 229, 101, 421, 513, 571, 7195, 9975, 0 }; - static ulong[] dim1306Kuo2Init = { 1, 1, 1, 1, 13, 23, 97, 157, 1, 969, 2011, 295, 6775, 7397, 0 }; - static ulong[] dim1307Kuo2Init = { 1, 1, 5, 5, 15, 9, 63, 21, 435, 51, 1279, 1309, 4303, 15771, 0 }; - static ulong[] dim1308Kuo2Init = { 1, 3, 1, 3, 3, 43, 121, 59, 365, 437, 215, 2899, 761, 1369, 0 }; - static ulong[] dim1309Kuo2Init = { 1, 1, 3, 7, 17, 25, 29, 149, 291, 117, 247, 2779, 7379, 11671, 0 }; - static ulong[] dim1310Kuo2Init = { 1, 3, 5, 15, 7, 3, 87, 213, 467, 91, 145, 1241, 1557, 6427, 0 }; - static ulong[] dim1311Kuo2Init = { 1, 1, 3, 9, 3, 51, 1, 61, 259, 535, 399, 3101, 5781, 14635, 0 }; - static ulong[] dim1312Kuo2Init = { 1, 3, 3, 11, 21, 17, 127, 117, 203, 825, 1481, 3979, 3605, 10537, 0 }; - static ulong[] dim1313Kuo2Init = { 1, 1, 5, 13, 15, 5, 119, 79, 439, 209, 1811, 3199, 7933, 1677, 0 }; - static ulong[] dim1314Kuo2Init = { 1, 1, 3, 15, 9, 9, 111, 103, 145, 839, 187, 2937, 6871, 10573, 0 }; - static ulong[] dim1315Kuo2Init = { 1, 3, 1, 9, 19, 7, 39, 37, 209, 83, 1143, 3767, 6013, 8829, 0 }; - static ulong[] dim1316Kuo2Init = { 1, 1, 7, 5, 31, 39, 97, 167, 323, 343, 999, 2179, 6683, 4079, 0 }; - static ulong[] dim1317Kuo2Init = { 1, 1, 1, 7, 1, 31, 5, 109, 391, 17, 1943, 2753, 3825, 327, 0 }; - static ulong[] dim1318Kuo2Init = { 1, 1, 7, 9, 9, 19, 49, 137, 421, 669, 829, 3261, 3995, 4347, 0 }; - static ulong[] dim1319Kuo2Init = { 1, 3, 5, 3, 25, 43, 51, 97, 315, 1021, 183, 87, 6465, 15415, 0 }; - static ulong[] dim1320Kuo2Init = { 1, 3, 1, 1, 15, 61, 111, 249, 99, 1001, 791, 869, 7017, 5943, 0 }; - static ulong[] dim1321Kuo2Init = { 1, 3, 7, 3, 3, 7, 51, 127, 275, 683, 1055, 3727, 1273, 3007, 0 }; - static ulong[] dim1322Kuo2Init = { 1, 3, 1, 15, 19, 33, 113, 167, 473, 287, 233, 905, 2213, 12233, 0 }; - static ulong[] dim1323Kuo2Init = { 1, 3, 3, 7, 3, 45, 83, 107, 7, 651, 603, 2663, 5261, 15521, 0 }; - static ulong[] dim1324Kuo2Init = { 1, 3, 3, 9, 19, 49, 51, 81, 101, 23, 1345, 17, 4215, 7089, 0 }; - static ulong[] dim1325Kuo2Init = { 1, 3, 5, 5, 7, 7, 65, 221, 7, 513, 1567, 4041, 6339, 8665, 0 }; - static ulong[] dim1326Kuo2Init = { 1, 1, 7, 9, 15, 61, 91, 29, 85, 903, 1805, 1957, 63, 13941, 0 }; - static ulong[] dim1327Kuo2Init = { 1, 1, 1, 1, 29, 19, 31, 21, 43, 353, 1419, 3999, 6651, 1897, 0 }; - static ulong[] dim1328Kuo2Init = { 1, 1, 3, 13, 31, 7, 65, 57, 25, 1015, 1969, 1547, 4815, 4183, 0 }; - static ulong[] dim1329Kuo2Init = { 1, 1, 7, 11, 25, 37, 91, 163, 287, 283, 1531, 149, 7799, 15, 0 }; - static ulong[] dim1330Kuo2Init = { 1, 3, 5, 7, 23, 25, 71, 7, 439, 645, 843, 315, 4577, 6703, 0 }; - static ulong[] dim1331Kuo2Init = { 1, 1, 5, 15, 13, 39, 57, 115, 91, 475, 2003, 3787, 4053, 13299, 0 }; - static ulong[] dim1332Kuo2Init = { 1, 3, 3, 7, 1, 53, 53, 83, 7, 133, 1523, 347, 3569, 6495, 0 }; - static ulong[] dim1333Kuo2Init = { 1, 1, 7, 13, 15, 53, 31, 153, 181, 465, 687, 3375, 3393, 565, 0 }; - static ulong[] dim1334Kuo2Init = { 1, 3, 3, 3, 19, 21, 95, 45, 399, 1, 213, 2003, 221, 11961, 0 }; - static ulong[] dim1335Kuo2Init = { 1, 1, 5, 13, 27, 29, 35, 55, 239, 999, 23, 2645, 5399, 865, 0 }; - static ulong[] dim1336Kuo2Init = { 1, 1, 5, 11, 5, 3, 43, 217, 321, 159, 1611, 495, 435, 6989, 0 }; - static ulong[] dim1337Kuo2Init = { 1, 1, 5, 1, 27, 15, 29, 109, 385, 449, 651, 1551, 5983, 12985, 0 }; - static ulong[] dim1338Kuo2Init = { 1, 3, 5, 11, 27, 35, 11, 155, 279, 5, 389, 1157, 2401, 12485, 0 }; - static ulong[] dim1339Kuo2Init = { 1, 1, 3, 3, 7, 7, 3, 185, 469, 995, 271, 2315, 3269, 909, 0 }; - static ulong[] dim1340Kuo2Init = { 1, 3, 5, 3, 27, 31, 111, 47, 351, 17, 1321, 3973, 457, 15773, 0 }; - static ulong[] dim1341Kuo2Init = { 1, 3, 1, 7, 19, 59, 71, 215, 93, 235, 1985, 1149, 1887, 2963, 0 }; - static ulong[] dim1342Kuo2Init = { 1, 3, 5, 3, 3, 3, 87, 205, 187, 373, 1557, 311, 5807, 13343, 0 }; - static ulong[] dim1343Kuo2Init = { 1, 1, 7, 13, 19, 17, 31, 113, 183, 31, 1117, 3241, 4781, 15071, 0 }; - static ulong[] dim1344Kuo2Init = { 1, 3, 5, 5, 3, 25, 33, 93, 473, 353, 1005, 2385, 649, 5219, 0 }; - static ulong[] dim1345Kuo2Init = { 1, 1, 3, 5, 25, 37, 39, 109, 511, 1005, 641, 3597, 7601, 613, 0 }; - static ulong[] dim1346Kuo2Init = { 1, 1, 7, 7, 3, 17, 69, 145, 147, 321, 849, 3057, 7299, 12343, 0 }; - static ulong[] dim1347Kuo2Init = { 1, 1, 3, 15, 11, 35, 19, 179, 337, 53, 679, 4009, 769, 2899, 0 }; - static ulong[] dim1348Kuo2Init = { 1, 1, 7, 11, 19, 47, 61, 11, 349, 769, 445, 2051, 5653, 7143, 0 }; - static ulong[] dim1349Kuo2Init = { 1, 1, 3, 9, 3, 39, 53, 193, 313, 299, 1579, 2237, 661, 6047, 0 }; - static ulong[] dim1350Kuo2Init = { 1, 1, 7, 7, 29, 17, 9, 225, 143, 285, 1169, 3109, 927, 5257, 0 }; - static ulong[] dim1351Kuo2Init = { 1, 3, 7, 5, 5, 27, 107, 253, 439, 1017, 253, 3437, 5435, 13479, 0 }; - static ulong[] dim1352Kuo2Init = { 1, 3, 3, 1, 9, 61, 111, 75, 241, 451, 1361, 2853, 5457, 15853, 0 }; - static ulong[] dim1353Kuo2Init = { 1, 1, 1, 5, 15, 23, 21, 115, 505, 265, 131, 1277, 2545, 8955, 0 }; - static ulong[] dim1354Kuo2Init = { 1, 1, 1, 1, 17, 43, 3, 253, 315, 19, 787, 1477, 2529, 6527, 0 }; - static ulong[] dim1355Kuo2Init = { 1, 1, 1, 7, 17, 31, 87, 121, 201, 367, 265, 3899, 1961, 12761, 0 }; - static ulong[] dim1356Kuo2Init = { 1, 1, 7, 9, 9, 55, 101, 163, 39, 351, 1877, 2481, 3265, 15575, 0 }; - static ulong[] dim1357Kuo2Init = { 1, 1, 3, 5, 29, 19, 21, 39, 187, 401, 547, 2477, 995, 3339, 0 }; - static ulong[] dim1358Kuo2Init = { 1, 3, 3, 5, 19, 25, 59, 247, 389, 733, 1867, 3401, 5115, 12791, 0 }; - static ulong[] dim1359Kuo2Init = { 1, 1, 3, 15, 11, 39, 29, 239, 157, 145, 1553, 3419, 5787, 3983, 0 }; - static ulong[] dim1360Kuo2Init = { 1, 1, 1, 15, 23, 47, 99, 71, 335, 749, 875, 5, 8049, 4585, 0 }; - static ulong[] dim1361Kuo2Init = { 1, 3, 7, 11, 19, 17, 25, 23, 243, 171, 929, 1981, 363, 13631, 0 }; - static ulong[] dim1362Kuo2Init = { 1, 1, 1, 1, 19, 43, 101, 199, 157, 431, 1127, 3261, 4063, 10569, 0 }; - static ulong[] dim1363Kuo2Init = { 1, 3, 5, 15, 15, 43, 1, 199, 281, 841, 1643, 2827, 6997, 11309, 0 }; - static ulong[] dim1364Kuo2Init = { 1, 1, 1, 11, 5, 53, 127, 147, 141, 319, 1605, 3717, 6519, 15315, 0 }; - static ulong[] dim1365Kuo2Init = { 1, 3, 3, 7, 31, 5, 39, 221, 91, 521, 527, 3253, 2877, 1439, 0 }; - static ulong[] dim1366Kuo2Init = { 1, 3, 5, 1, 9, 61, 69, 27, 393, 557, 1949, 3035, 3717, 5099, 0 }; - static ulong[] dim1367Kuo2Init = { 1, 3, 7, 3, 19, 43, 77, 161, 469, 721, 73, 685, 1681, 5581, 0 }; - static ulong[] dim1368Kuo2Init = { 1, 1, 7, 5, 27, 3, 119, 223, 255, 905, 501, 1809, 5591, 29, 0 }; - static ulong[] dim1369Kuo2Init = { 1, 1, 3, 11, 13, 1, 13, 103, 305, 679, 1485, 4077, 1419, 7893, 0 }; - static ulong[] dim1370Kuo2Init = { 1, 1, 1, 15, 21, 7, 39, 49, 451, 291, 93, 3563, 5071, 15353, 0 }; - static ulong[] dim1371Kuo2Init = { 1, 3, 7, 9, 19, 53, 57, 149, 171, 377, 1903, 235, 2181, 8207, 0 }; - static ulong[] dim1372Kuo2Init = { 1, 3, 5, 15, 23, 25, 63, 53, 23, 263, 1681, 3305, 461, 9875, 0 }; - static ulong[] dim1373Kuo2Init = { 1, 1, 3, 5, 5, 15, 71, 217, 493, 323, 1451, 1629, 7677, 15945, 0 }; - static ulong[] dim1374Kuo2Init = { 1, 1, 5, 9, 31, 53, 95, 37, 357, 61, 1601, 3565, 3705, 6617, 0 }; - static ulong[] dim1375Kuo2Init = { 1, 3, 1, 5, 17, 33, 81, 119, 233, 219, 1429, 2183, 771, 7199, 0 }; - static ulong[] dim1376Kuo2Init = { 1, 1, 7, 9, 27, 17, 7, 17, 281, 959, 1065, 3489, 6665, 14469, 0 }; - static ulong[] dim1377Kuo2Init = { 1, 3, 1, 15, 21, 15, 99, 77, 437, 571, 207, 609, 7287, 9395, 0 }; - static ulong[] dim1378Kuo2Init = { 1, 1, 7, 1, 1, 49, 39, 189, 111, 65, 1345, 2559, 7835, 9869, 0 }; - static ulong[] dim1379Kuo2Init = { 1, 1, 1, 1, 27, 17, 93, 83, 339, 465, 1445, 3557, 6489, 6985, 0 }; - static ulong[] dim1380Kuo2Init = { 1, 1, 5, 3, 1, 7, 35, 39, 491, 563, 1815, 2513, 5523, 12691, 0 }; - static ulong[] dim1381Kuo2Init = { 1, 1, 3, 5, 3, 31, 127, 91, 87, 447, 1237, 3419, 6979, 6311, 0 }; - static ulong[] dim1382Kuo2Init = { 1, 1, 7, 3, 25, 61, 45, 219, 455, 859, 781, 2991, 6585, 11511, 0 }; - static ulong[] dim1383Kuo2Init = { 1, 3, 3, 13, 15, 37, 77, 211, 403, 349, 35, 2785, 4439, 5715, 0 }; - static ulong[] dim1384Kuo2Init = { 1, 1, 3, 1, 1, 19, 45, 37, 459, 839, 17, 3223, 6411, 9209, 0 }; - static ulong[] dim1385Kuo2Init = { 1, 3, 1, 3, 27, 43, 63, 241, 455, 593, 1855, 3689, 7825, 10197, 0 }; - static ulong[] dim1386Kuo2Init = { 1, 3, 3, 1, 5, 17, 71, 209, 57, 991, 617, 3097, 5431, 2057, 0 }; - static ulong[] dim1387Kuo2Init = { 1, 1, 5, 15, 31, 21, 119, 53, 447, 969, 335, 3793, 3225, 9809, 0 }; - static ulong[] dim1388Kuo2Init = { 1, 1, 1, 11, 17, 51, 17, 7, 257, 221, 119, 2631, 6395, 8495, 0 }; - static ulong[] dim1389Kuo2Init = { 1, 3, 1, 15, 31, 13, 3, 9, 479, 233, 1051, 1953, 7863, 5969, 0 }; - static ulong[] dim1390Kuo2Init = { 1, 3, 1, 9, 13, 49, 57, 161, 65, 871, 2021, 3337, 7071, 12969, 0 }; - static ulong[] dim1391Kuo2Init = { 1, 3, 5, 15, 1, 53, 3, 77, 487, 207, 1761, 847, 3131, 1933, 0 }; - static ulong[] dim1392Kuo2Init = { 1, 3, 1, 7, 7, 21, 55, 217, 167, 113, 1029, 2761, 2063, 5267, 0 }; - static ulong[] dim1393Kuo2Init = { 1, 3, 3, 7, 15, 57, 119, 9, 211, 93, 209, 2905, 2589, 12341, 0 }; - static ulong[] dim1394Kuo2Init = { 1, 3, 1, 15, 25, 7, 41, 87, 451, 613, 353, 2619, 6015, 14003, 0 }; - static ulong[] dim1395Kuo2Init = { 1, 3, 3, 11, 23, 5, 3, 145, 471, 685, 3, 3431, 2843, 11725, 0 }; - static ulong[] dim1396Kuo2Init = { 1, 3, 7, 11, 13, 45, 73, 45, 169, 395, 1279, 2589, 1419, 14965, 0 }; - static ulong[] dim1397Kuo2Init = { 1, 3, 5, 9, 25, 23, 77, 149, 27, 441, 1391, 1853, 3993, 15507, 0 }; - static ulong[] dim1398Kuo2Init = { 1, 1, 1, 7, 21, 33, 39, 59, 161, 399, 447, 1249, 5407, 11825, 0 }; - static ulong[] dim1399Kuo2Init = { 1, 1, 5, 3, 25, 53, 37, 237, 91, 625, 1195, 1161, 7005, 7831, 0 }; - static ulong[] dim1400Kuo2Init = { 1, 3, 7, 5, 7, 63, 37, 101, 399, 645, 545, 3419, 6619, 2179, 0 }; - static ulong[] dim1401Kuo2Init = { 1, 1, 5, 11, 11, 51, 103, 207, 267, 909, 1975, 2279, 1991, 1891, 0 }; - static ulong[] dim1402Kuo2Init = { 1, 1, 7, 1, 27, 45, 9, 1, 423, 197, 697, 2765, 2653, 2613, 0 }; - static ulong[] dim1403Kuo2Init = { 1, 3, 7, 1, 27, 13, 45, 47, 493, 131, 565, 1363, 4921, 10023, 0 }; - static ulong[] dim1404Kuo2Init = { 1, 3, 7, 1, 7, 47, 99, 107, 343, 933, 1017, 3931, 1329, 2833, 0 }; - static ulong[] dim1405Kuo2Init = { 1, 1, 3, 1, 13, 9, 5, 131, 475, 537, 1857, 2579, 6377, 14363, 0 }; - static ulong[] dim1406Kuo2Init = { 1, 1, 5, 5, 15, 7, 87, 39, 51, 563, 1145, 3639, 4261, 9585, 0 }; - static ulong[] dim1407Kuo2Init = { 1, 3, 1, 3, 3, 61, 23, 223, 221, 165, 315, 2475, 7907, 10171, 0 }; - static ulong[] dim1408Kuo2Init = { 1, 1, 3, 9, 23, 57, 121, 171, 439, 101, 261, 1115, 1291, 2951, 0 }; - static ulong[] dim1409Kuo2Init = { 1, 1, 1, 9, 15, 23, 81, 189, 301, 515, 297, 915, 763, 11037, 0 }; - static ulong[] dim1410Kuo2Init = { 1, 3, 5, 9, 17, 45, 33, 101, 65, 687, 2011, 1821, 6891, 7321, 0 }; - static ulong[] dim1411Kuo2Init = { 1, 3, 5, 5, 9, 61, 11, 69, 345, 211, 393, 331, 3953, 13987, 0 }; - static ulong[] dim1412Kuo2Init = { 1, 1, 5, 15, 9, 23, 11, 45, 325, 1019, 1499, 831, 127, 9237, 0 }; - static ulong[] dim1413Kuo2Init = { 1, 1, 5, 5, 19, 9, 53, 213, 417, 761, 1275, 2117, 465, 15195, 0 }; - static ulong[] dim1414Kuo2Init = { 1, 3, 1, 7, 25, 53, 57, 95, 31, 791, 345, 3769, 3487, 4269, 0 }; - static ulong[] dim1415Kuo2Init = { 1, 3, 3, 1, 17, 9, 127, 203, 67, 435, 281, 3857, 819, 11235, 0 }; - static ulong[] dim1416Kuo2Init = { 1, 3, 1, 7, 23, 45, 127, 197, 501, 11, 1125, 2781, 7979, 1699, 0 }; - static ulong[] dim1417Kuo2Init = { 1, 3, 3, 13, 21, 21, 57, 125, 225, 593, 27, 539, 7989, 9597, 0 }; - static ulong[] dim1418Kuo2Init = { 1, 3, 7, 7, 29, 27, 57, 19, 51, 981, 205, 169, 5713, 4777, 0 }; - static ulong[] dim1419Kuo2Init = { 1, 3, 7, 7, 1, 59, 57, 61, 145, 683, 1043, 11, 5277, 5095, 0 }; - static ulong[] dim1420Kuo2Init = { 1, 1, 1, 3, 7, 39, 123, 251, 259, 295, 1333, 395, 5463, 11593, 0 }; - static ulong[] dim1421Kuo2Init = { 1, 1, 7, 15, 1, 9, 71, 79, 299, 1007, 1403, 237, 4845, 10521, 0 }; - static ulong[] dim1422Kuo2Init = { 1, 1, 5, 5, 11, 51, 45, 51, 489, 865, 511, 1415, 7867, 4235, 0 }; - static ulong[] dim1423Kuo2Init = { 1, 3, 3, 9, 23, 31, 83, 77, 461, 111, 1985, 3401, 271, 9763, 0 }; - static ulong[] dim1424Kuo2Init = { 1, 3, 5, 11, 19, 53, 45, 135, 171, 593, 1761, 1019, 7715, 9835, 0 }; - static ulong[] dim1425Kuo2Init = { 1, 1, 3, 5, 21, 47, 95, 1, 419, 547, 447, 3475, 7829, 12019, 0 }; - static ulong[] dim1426Kuo2Init = { 1, 3, 7, 13, 15, 29, 21, 197, 491, 997, 453, 3415, 745, 11259, 0 }; - static ulong[] dim1427Kuo2Init = { 1, 1, 3, 11, 19, 39, 99, 83, 35, 941, 1175, 2749, 4181, 8791, 0 }; - static ulong[] dim1428Kuo2Init = { 1, 1, 5, 7, 23, 3, 101, 11, 81, 291, 1815, 3391, 7615, 1305, 0 }; - static ulong[] dim1429Kuo2Init = { 1, 3, 5, 13, 27, 35, 71, 185, 87, 939, 1025, 1577, 5919, 5335, 0 }; - static ulong[] dim1430Kuo2Init = { 1, 3, 3, 9, 3, 31, 23, 213, 371, 595, 2003, 647, 909, 7503, 0 }; - static ulong[] dim1431Kuo2Init = { 1, 1, 5, 9, 31, 63, 125, 113, 273, 985, 1049, 1819, 2773, 6495, 0 }; - static ulong[] dim1432Kuo2Init = { 1, 1, 1, 5, 21, 7, 87, 207, 455, 403, 677, 175, 531, 10467, 0 }; - static ulong[] dim1433Kuo2Init = { 1, 1, 5, 1, 3, 45, 109, 75, 429, 983, 423, 3491, 7949, 15253, 0 }; - static ulong[] dim1434Kuo2Init = { 1, 1, 3, 1, 23, 27, 91, 5, 235, 121, 1087, 325, 5191, 8271, 0 }; - static ulong[] dim1435Kuo2Init = { 1, 3, 3, 15, 29, 63, 91, 129, 305, 827, 1311, 2765, 253, 1495, 0 }; - static ulong[] dim1436Kuo2Init = { 1, 3, 1, 15, 21, 45, 7, 21, 169, 275, 629, 589, 4623, 5491, 0 }; - static ulong[] dim1437Kuo2Init = { 1, 3, 1, 3, 13, 45, 127, 105, 377, 49, 1161, 489, 595, 7041, 0 }; - static ulong[] dim1438Kuo2Init = { 1, 1, 5, 11, 31, 61, 91, 1, 35, 189, 1479, 2041, 1585, 13009, 0 }; - static ulong[] dim1439Kuo2Init = { 1, 3, 3, 1, 23, 47, 69, 47, 361, 375, 77, 3777, 5769, 9925, 0 }; - static ulong[] dim1440Kuo2Init = { 1, 3, 3, 9, 5, 13, 31, 119, 411, 735, 839, 2919, 543, 12929, 0 }; - static ulong[] dim1441Kuo2Init = { 1, 3, 5, 11, 19, 5, 29, 185, 115, 841, 507, 1433, 5091, 3593, 0 }; - static ulong[] dim1442Kuo2Init = { 1, 3, 1, 13, 15, 19, 23, 83, 319, 99, 785, 697, 3703, 8733, 0 }; - static ulong[] dim1443Kuo2Init = { 1, 3, 5, 3, 7, 31, 53, 213, 287, 797, 1807, 879, 4227, 12013, 0 }; - static ulong[] dim1444Kuo2Init = { 1, 3, 3, 1, 23, 53, 91, 173, 253, 971, 1017, 2185, 4911, 15359, 0 }; - static ulong[] dim1445Kuo2Init = { 1, 3, 7, 3, 17, 27, 77, 225, 97, 199, 607, 1615, 963, 671, 0 }; - static ulong[] dim1446Kuo2Init = { 1, 1, 5, 11, 9, 61, 3, 105, 455, 953, 455, 3925, 3947, 7873, 0 }; - static ulong[] dim1447Kuo2Init = { 1, 3, 7, 7, 3, 49, 121, 109, 239, 855, 789, 3627, 3873, 6785, 0 }; - static ulong[] dim1448Kuo2Init = { 1, 1, 5, 5, 29, 35, 99, 159, 17, 221, 855, 2081, 2791, 11413, 0 }; - static ulong[] dim1449Kuo2Init = { 1, 3, 7, 5, 23, 53, 75, 93, 207, 189, 2035, 1829, 7581, 1425, 0 }; - static ulong[] dim1450Kuo2Init = { 1, 1, 3, 9, 3, 61, 61, 237, 53, 875, 1617, 727, 2683, 15797, 0 }; - static ulong[] dim1451Kuo2Init = { 1, 1, 1, 11, 23, 3, 105, 107, 353, 579, 119, 3041, 3005, 15581, 0 }; - static ulong[] dim1452Kuo2Init = { 1, 1, 1, 11, 31, 15, 89, 215, 161, 39, 629, 2873, 1635, 1029, 0 }; - static ulong[] dim1453Kuo2Init = { 1, 3, 3, 15, 15, 25, 53, 27, 167, 497, 1795, 1283, 7869, 15821, 0 }; - static ulong[] dim1454Kuo2Init = { 1, 3, 7, 3, 27, 39, 111, 29, 445, 365, 273, 2183, 475, 12503, 0 }; - static ulong[] dim1455Kuo2Init = { 1, 3, 7, 5, 9, 13, 25, 115, 419, 387, 1663, 3445, 157, 10549, 0 }; - static ulong[] dim1456Kuo2Init = { 1, 1, 5, 13, 23, 39, 7, 247, 127, 285, 675, 1785, 1823, 10183, 0 }; - static ulong[] dim1457Kuo2Init = { 1, 1, 1, 11, 31, 39, 93, 19, 125, 453, 1963, 2619, 6195, 2231, 0 }; - static ulong[] dim1458Kuo2Init = { 1, 1, 7, 3, 31, 51, 59, 19, 15, 251, 749, 2469, 369, 15413, 0 }; - static ulong[] dim1459Kuo2Init = { 1, 1, 7, 9, 19, 59, 111, 255, 91, 89, 1447, 353, 6701, 7955, 0 }; - static ulong[] dim1460Kuo2Init = { 1, 1, 7, 3, 3, 21, 115, 159, 489, 609, 1993, 2961, 3117, 3977, 0 }; - static ulong[] dim1461Kuo2Init = { 1, 3, 7, 13, 13, 13, 57, 41, 5, 337, 2005, 2587, 3873, 12829, 0 }; - static ulong[] dim1462Kuo2Init = { 1, 1, 3, 9, 9, 3, 39, 165, 155, 353, 985, 2221, 2973, 6331, 0 }; - static ulong[] dim1463Kuo2Init = { 1, 3, 3, 5, 3, 15, 121, 191, 367, 513, 1765, 3957, 3113, 10669, 0 }; - static ulong[] dim1464Kuo2Init = { 1, 3, 7, 1, 13, 41, 63, 241, 405, 43, 1211, 1499, 1095, 11867, 0 }; - static ulong[] dim1465Kuo2Init = { 1, 3, 7, 15, 17, 17, 63, 197, 377, 981, 1615, 2407, 6669, 411, 0 }; - static ulong[] dim1466Kuo2Init = { 1, 1, 3, 1, 3, 39, 85, 15, 9, 747, 423, 3103, 7341, 10953, 0 }; - static ulong[] dim1467Kuo2Init = { 1, 1, 7, 13, 25, 9, 17, 137, 267, 405, 1819, 641, 7305, 13971, 0 }; - static ulong[] dim1468Kuo2Init = { 1, 3, 5, 5, 19, 45, 121, 65, 385, 715, 267, 1841, 6317, 5827, 0 }; - static ulong[] dim1469Kuo2Init = { 1, 1, 7, 9, 11, 31, 57, 123, 107, 913, 669, 1053, 1213, 8791, 0 }; - static ulong[] dim1470Kuo2Init = { 1, 1, 3, 7, 21, 3, 57, 227, 401, 443, 1847, 3523, 4717, 2505, 0 }; - static ulong[] dim1471Kuo2Init = { 1, 3, 3, 15, 29, 41, 67, 217, 431, 37, 1775, 297, 1921, 8715, 0 }; - static ulong[] dim1472Kuo2Init = { 1, 3, 7, 7, 27, 35, 113, 57, 23, 927, 141, 1363, 4209, 4399, 0 }; - static ulong[] dim1473Kuo2Init = { 1, 1, 7, 9, 19, 51, 107, 189, 463, 695, 1931, 1541, 1285, 15703, 0 }; - static ulong[] dim1474Kuo2Init = { 1, 3, 5, 7, 29, 43, 109, 117, 389, 7, 1129, 1945, 6987, 799, 0 }; - static ulong[] dim1475Kuo2Init = { 1, 1, 1, 13, 9, 7, 119, 61, 385, 315, 1953, 1745, 8117, 15863, 0 }; - static ulong[] dim1476Kuo2Init = { 1, 1, 7, 7, 21, 55, 95, 113, 293, 899, 1327, 161, 6613, 14949, 0 }; - static ulong[] dim1477Kuo2Init = { 1, 1, 7, 9, 19, 21, 89, 5, 477, 441, 1477, 1995, 6633, 5523, 0 }; - static ulong[] dim1478Kuo2Init = { 1, 3, 3, 11, 15, 27, 17, 239, 263, 267, 1729, 3583, 4117, 13637, 0 }; - static ulong[] dim1479Kuo2Init = { 1, 1, 5, 5, 11, 53, 15, 201, 401, 845, 741, 2803, 3087, 9001, 0 }; - static ulong[] dim1480Kuo2Init = { 1, 3, 3, 11, 17, 21, 65, 109, 163, 251, 1487, 1541, 481, 10545, 0 }; - static ulong[] dim1481Kuo2Init = { 1, 3, 3, 13, 21, 61, 71, 121, 331, 551, 1237, 805, 3799, 1437, 0 }; - static ulong[] dim1482Kuo2Init = { 1, 3, 1, 11, 21, 29, 61, 161, 193, 745, 935, 1013, 3507, 6091, 0 }; - static ulong[] dim1483Kuo2Init = { 1, 3, 7, 15, 5, 59, 99, 147, 467, 625, 1873, 3459, 5749, 10571, 0 }; - static ulong[] dim1484Kuo2Init = { 1, 3, 1, 3, 9, 21, 57, 63, 205, 891, 1963, 2271, 6303, 9565, 0 }; - static ulong[] dim1485Kuo2Init = { 1, 1, 1, 1, 17, 55, 21, 105, 181, 763, 763, 337, 2283, 5203, 0 }; - static ulong[] dim1486Kuo2Init = { 1, 3, 3, 11, 25, 33, 7, 107, 329, 49, 31, 995, 757, 9781, 0 }; - static ulong[] dim1487Kuo2Init = { 1, 3, 7, 13, 17, 19, 107, 189, 359, 709, 819, 3943, 1891, 12173, 0 }; - static ulong[] dim1488Kuo2Init = { 1, 1, 7, 5, 3, 55, 121, 37, 493, 579, 2021, 3129, 6519, 14569, 0 }; - static ulong[] dim1489Kuo2Init = { 1, 1, 5, 15, 17, 3, 59, 75, 453, 323, 1559, 3695, 7711, 7665, 0 }; - static ulong[] dim1490Kuo2Init = { 1, 3, 3, 7, 9, 35, 121, 179, 345, 973, 337, 3655, 3815, 6317, 0 }; - static ulong[] dim1491Kuo2Init = { 1, 3, 7, 7, 9, 27, 59, 253, 9, 221, 587, 1087, 7295, 12193, 0 }; - static ulong[] dim1492Kuo2Init = { 1, 1, 3, 7, 27, 1, 105, 99, 49, 555, 2019, 2863, 5211, 2485, 0 }; - static ulong[] dim1493Kuo2Init = { 1, 1, 3, 15, 25, 55, 23, 221, 501, 671, 11, 1801, 6485, 14983, 0 }; - static ulong[] dim1494Kuo2Init = { 1, 3, 1, 3, 27, 45, 69, 159, 77, 541, 1441, 2043, 5609, 6799, 0 }; - static ulong[] dim1495Kuo2Init = { 1, 1, 5, 3, 21, 31, 7, 197, 511, 299, 1523, 3341, 301, 8639, 0 }; - static ulong[] dim1496Kuo2Init = { 1, 1, 7, 1, 9, 59, 63, 253, 191, 653, 383, 1239, 7839, 3699, 0 }; - static ulong[] dim1497Kuo2Init = { 1, 1, 3, 9, 13, 33, 73, 209, 125, 939, 1507, 3527, 6039, 14027, 0 }; - static ulong[] dim1498Kuo2Init = { 1, 1, 3, 13, 13, 21, 5, 15, 301, 625, 713, 2867, 3129, 4939, 0 }; - static ulong[] dim1499Kuo2Init = { 1, 1, 1, 13, 23, 5, 115, 69, 101, 327, 563, 2623, 6491, 7381, 0 }; - static ulong[] dim1500Kuo2Init = { 1, 1, 5, 7, 9, 53, 1, 91, 53, 823, 281, 2281, 6509, 2515, 0 }; - static ulong[] dim1501Kuo2Init = { 1, 1, 5, 5, 13, 61, 105, 183, 39, 493, 773, 1815, 1549, 7511, 0 }; - static ulong[] dim1502Kuo2Init = { 1, 1, 3, 13, 29, 27, 97, 205, 425, 13, 1227, 625, 137, 6785, 0 }; - static ulong[] dim1503Kuo2Init = { 1, 3, 7, 11, 13, 29, 105, 85, 251, 151, 1515, 3137, 8051, 14333, 0 }; - static ulong[] dim1504Kuo2Init = { 1, 3, 7, 9, 25, 59, 99, 43, 435, 361, 297, 449, 5633, 5813, 0 }; - static ulong[] dim1505Kuo2Init = { 1, 3, 1, 13, 17, 45, 113, 79, 315, 781, 785, 3463, 1299, 5959, 0 }; - static ulong[] dim1506Kuo2Init = { 1, 1, 7, 15, 19, 47, 35, 13, 487, 227, 1965, 4035, 4285, 14395, 0 }; - static ulong[] dim1507Kuo2Init = { 1, 3, 7, 5, 9, 41, 91, 127, 101, 519, 1147, 3851, 7929, 1807, 0 }; - static ulong[] dim1508Kuo2Init = { 1, 1, 7, 1, 19, 63, 45, 75, 437, 309, 1327, 3913, 5961, 2825, 0 }; - static ulong[] dim1509Kuo2Init = { 1, 1, 1, 15, 11, 1, 77, 11, 105, 499, 859, 2403, 4453, 12297, 0 }; - static ulong[] dim1510Kuo2Init = { 1, 1, 5, 5, 9, 33, 87, 85, 167, 35, 501, 1027, 4489, 10513, 0 }; - static ulong[] dim1511Kuo2Init = { 1, 1, 7, 13, 5, 3, 75, 75, 417, 319, 423, 1107, 371, 12493, 0 }; - static ulong[] dim1512Kuo2Init = { 1, 3, 7, 7, 15, 57, 7, 105, 95, 287, 1865, 2795, 5187, 543, 0 }; - static ulong[] dim1513Kuo2Init = { 1, 1, 1, 11, 1, 3, 121, 99, 299, 415, 47, 997, 2939, 8529, 0 }; - static ulong[] dim1514Kuo2Init = { 1, 1, 7, 11, 23, 17, 101, 209, 267, 459, 1965, 2153, 6361, 9553, 0 }; - static ulong[] dim1515Kuo2Init = { 1, 1, 3, 5, 1, 9, 7, 17, 109, 245, 701, 2161, 2109, 3301, 0 }; - static ulong[] dim1516Kuo2Init = { 1, 3, 5, 3, 13, 21, 113, 159, 261, 467, 127, 437, 8071, 11647, 0 }; - static ulong[] dim1517Kuo2Init = { 1, 3, 1, 15, 29, 63, 93, 31, 189, 881, 17, 2689, 1273, 4991, 0 }; - static ulong[] dim1518Kuo2Init = { 1, 3, 3, 7, 31, 23, 39, 177, 505, 207, 67, 2897, 315, 5981, 0 }; - static ulong[] dim1519Kuo2Init = { 1, 3, 5, 5, 31, 19, 87, 237, 119, 439, 1893, 3079, 3709, 15051, 0 }; - static ulong[] dim1520Kuo2Init = { 1, 3, 5, 1, 31, 35, 125, 173, 197, 765, 1419, 465, 1919, 2641, 0 }; - static ulong[] dim1521Kuo2Init = { 1, 1, 5, 11, 19, 15, 49, 255, 447, 939, 137, 2371, 6617, 79, 0 }; - static ulong[] dim1522Kuo2Init = { 1, 3, 3, 1, 11, 29, 81, 81, 327, 593, 135, 415, 2417, 8671, 0 }; - static ulong[] dim1523Kuo2Init = { 1, 1, 7, 11, 11, 35, 9, 143, 311, 57, 557, 793, 6597, 12979, 0 }; - static ulong[] dim1524Kuo2Init = { 1, 1, 7, 1, 27, 1, 105, 149, 417, 605, 431, 2419, 4113, 5651, 0 }; - static ulong[] dim1525Kuo2Init = { 1, 1, 3, 15, 1, 45, 63, 119, 167, 607, 961, 2561, 7839, 13343, 0 }; - static ulong[] dim1526Kuo2Init = { 1, 1, 5, 15, 11, 47, 75, 209, 175, 219, 443, 1311, 3383, 14073, 0 }; - static ulong[] dim1527Kuo2Init = { 1, 3, 5, 15, 17, 49, 97, 3, 343, 515, 129, 2243, 1567, 6119, 0 }; - static ulong[] dim1528Kuo2Init = { 1, 1, 3, 13, 3, 31, 111, 173, 97, 211, 69, 1771, 3039, 10305, 0 }; - static ulong[] dim1529Kuo2Init = { 1, 1, 1, 11, 7, 27, 5, 163, 277, 959, 1287, 3603, 2617, 12883, 0 }; - static ulong[] dim1530Kuo2Init = { 1, 1, 7, 5, 7, 63, 25, 235, 301, 575, 1979, 1519, 5765, 6331, 0 }; - static ulong[] dim1531Kuo2Init = { 1, 3, 5, 7, 23, 35, 43, 171, 481, 559, 1495, 665, 6325, 2733, 0 }; - static ulong[] dim1532Kuo2Init = { 1, 1, 7, 5, 3, 55, 99, 141, 37, 757, 11, 911, 2523, 11031, 0 }; - static ulong[] dim1533Kuo2Init = { 1, 1, 5, 7, 17, 9, 91, 9, 141, 693, 581, 2151, 3527, 11575, 0 }; - static ulong[] dim1534Kuo2Init = { 1, 1, 7, 1, 19, 31, 23, 59, 215, 873, 161, 1719, 509, 4509, 0 }; - static ulong[] dim1535Kuo2Init = { 1, 1, 7, 9, 17, 29, 57, 31, 233, 109, 865, 759, 3289, 11595, 0 }; - static ulong[] dim1536Kuo2Init = { 1, 3, 3, 15, 5, 61, 17, 69, 413, 95, 41, 1375, 1959, 11945, 0 }; - static ulong[] dim1537Kuo2Init = { 1, 3, 7, 1, 25, 3, 77, 9, 301, 117, 255, 3169, 3493, 5503, 0 }; - static ulong[] dim1538Kuo2Init = { 1, 1, 5, 3, 31, 1, 87, 211, 45, 185, 329, 3883, 3621, 4007, 0 }; - static ulong[] dim1539Kuo2Init = { 1, 1, 5, 15, 11, 5, 123, 131, 479, 981, 921, 3557, 5897, 9387, 0 }; - static ulong[] dim1540Kuo2Init = { 1, 1, 3, 3, 9, 43, 25, 57, 151, 975, 403, 727, 1155, 13495, 0 }; - static ulong[] dim1541Kuo2Init = { 1, 3, 3, 15, 29, 59, 31, 169, 201, 1007, 1017, 3121, 3989, 7835, 0 }; - static ulong[] dim1542Kuo2Init = { 1, 1, 3, 9, 19, 7, 103, 137, 135, 855, 179, 2859, 6959, 9749, 0 }; - static ulong[] dim1543Kuo2Init = { 1, 3, 3, 15, 3, 3, 121, 231, 461, 511, 1203, 2105, 6379, 6809, 0 }; - static ulong[] dim1544Kuo2Init = { 1, 1, 7, 15, 29, 5, 19, 215, 13, 813, 1421, 1725, 7809, 2379, 0 }; - static ulong[] dim1545Kuo2Init = { 1, 3, 5, 1, 9, 55, 127, 129, 95, 449, 1607, 4043, 5175, 6063, 0 }; - static ulong[] dim1546Kuo2Init = { 1, 1, 1, 9, 17, 31, 103, 107, 89, 5, 1747, 3405, 5739, 1959, 0 }; - static ulong[] dim1547Kuo2Init = { 1, 3, 1, 15, 5, 43, 41, 15, 453, 691, 739, 3755, 6597, 9737, 0 }; - static ulong[] dim1548Kuo2Init = { 1, 1, 3, 5, 27, 55, 111, 19, 349, 753, 1667, 3683, 4617, 12663, 0 }; - static ulong[] dim1549Kuo2Init = { 1, 1, 5, 11, 29, 57, 111, 187, 45, 957, 2001, 2743, 2813, 3831, 0 }; - static ulong[] dim1550Kuo2Init = { 1, 3, 7, 5, 13, 63, 25, 59, 169, 577, 301, 1535, 5355, 15835, 0 }; - static ulong[] dim1551Kuo2Init = { 1, 3, 3, 7, 7, 25, 101, 249, 59, 217, 557, 2565, 5103, 13787, 0 }; - static ulong[] dim1552Kuo2Init = { 1, 3, 7, 9, 5, 31, 97, 19, 435, 205, 1217, 3659, 7687, 8381, 0 }; - static ulong[] dim1553Kuo2Init = { 1, 1, 1, 5, 7, 33, 41, 89, 243, 769, 1915, 2235, 757, 367, 0 }; - static ulong[] dim1554Kuo2Init = { 1, 1, 1, 15, 3, 11, 103, 41, 79, 585, 1661, 1739, 2075, 15113, 0 }; - static ulong[] dim1555Kuo2Init = { 1, 1, 5, 5, 5, 53, 103, 167, 387, 591, 317, 2539, 3763, 3341, 0 }; - static ulong[] dim1556Kuo2Init = { 1, 1, 7, 7, 31, 29, 69, 43, 257, 471, 435, 3895, 445, 10941, 0 }; - static ulong[] dim1557Kuo2Init = { 1, 1, 1, 9, 13, 63, 3, 167, 447, 569, 949, 2289, 6383, 5887, 0 }; - static ulong[] dim1558Kuo2Init = { 1, 1, 5, 5, 11, 31, 35, 9, 383, 933, 519, 3773, 4987, 2737, 0 }; - static ulong[] dim1559Kuo2Init = { 1, 1, 7, 7, 15, 17, 121, 109, 299, 579, 683, 1365, 2471, 14275, 0 }; - static ulong[] dim1560Kuo2Init = { 1, 1, 1, 9, 19, 9, 17, 229, 405, 545, 1923, 991, 473, 11233, 0 }; - static ulong[] dim1561Kuo2Init = { 1, 1, 3, 13, 13, 1, 101, 241, 51, 885, 1835, 1095, 2917, 15167, 0 }; - static ulong[] dim1562Kuo2Init = { 1, 3, 5, 3, 31, 35, 127, 17, 153, 415, 769, 299, 7791, 8697, 0 }; - static ulong[] dim1563Kuo2Init = { 1, 3, 3, 3, 23, 35, 77, 237, 427, 611, 2025, 3201, 7855, 789, 0 }; - static ulong[] dim1564Kuo2Init = { 1, 3, 1, 5, 9, 25, 123, 215, 387, 939, 471, 1123, 6747, 14803, 0 }; - static ulong[] dim1565Kuo2Init = { 1, 1, 5, 15, 1, 55, 85, 249, 315, 253, 1705, 35, 7351, 11255, 0 }; - static ulong[] dim1566Kuo2Init = { 1, 3, 5, 3, 7, 15, 5, 167, 351, 145, 1891, 2691, 3035, 873, 0 }; - static ulong[] dim1567Kuo2Init = { 1, 3, 1, 15, 19, 33, 85, 241, 259, 625, 615, 97, 5977, 4777, 0 }; - static ulong[] dim1568Kuo2Init = { 1, 3, 7, 9, 19, 17, 9, 197, 141, 5, 355, 3001, 6903, 13809, 0 }; - static ulong[] dim1569Kuo2Init = { 1, 1, 7, 13, 9, 39, 79, 43, 465, 49, 849, 1509, 5251, 11239, 0 }; - static ulong[] dim1570Kuo2Init = { 1, 1, 7, 3, 5, 21, 37, 159, 461, 1015, 329, 4095, 2513, 6213, 0 }; - static ulong[] dim1571Kuo2Init = { 1, 1, 7, 7, 7, 19, 127, 15, 61, 439, 1381, 677, 2851, 1635, 0 }; - static ulong[] dim1572Kuo2Init = { 1, 1, 3, 5, 17, 19, 125, 171, 175, 441, 1153, 2445, 2907, 13089, 0 }; - static ulong[] dim1573Kuo2Init = { 1, 1, 7, 9, 17, 59, 53, 81, 5, 685, 1257, 3179, 5067, 10131, 0 }; - static ulong[] dim1574Kuo2Init = { 1, 1, 5, 3, 9, 47, 25, 111, 235, 117, 65, 2565, 865, 15173, 0 }; - static ulong[] dim1575Kuo2Init = { 1, 3, 1, 7, 27, 5, 55, 155, 221, 451, 1823, 1277, 1397, 15715, 0 }; - static ulong[] dim1576Kuo2Init = { 1, 1, 1, 15, 17, 5, 115, 209, 393, 973, 177, 825, 3315, 8333, 0 }; - static ulong[] dim1577Kuo2Init = { 1, 1, 3, 13, 23, 47, 121, 47, 379, 433, 807, 3723, 2595, 14727, 0 }; - static ulong[] dim1578Kuo2Init = { 1, 1, 3, 5, 29, 59, 39, 205, 327, 999, 1897, 3441, 5355, 12881, 0 }; - static ulong[] dim1579Kuo2Init = { 1, 1, 3, 3, 27, 63, 57, 175, 225, 353, 675, 2955, 6581, 2735, 0 }; - static ulong[] dim1580Kuo2Init = { 1, 3, 3, 1, 11, 55, 55, 191, 239, 579, 1355, 2449, 563, 9757, 0 }; - static ulong[] dim1581Kuo2Init = { 1, 1, 7, 5, 1, 49, 35, 19, 25, 783, 1453, 1063, 4811, 1449, 0 }; - static ulong[] dim1582Kuo2Init = { 1, 3, 1, 13, 11, 63, 17, 203, 479, 133, 1951, 385, 6803, 13453, 0 }; - static ulong[] dim1583Kuo2Init = { 1, 3, 7, 9, 21, 19, 15, 125, 397, 109, 1903, 4053, 6449, 8821, 0 }; - static ulong[] dim1584Kuo2Init = { 1, 3, 7, 15, 1, 33, 45, 161, 43, 729, 397, 4093, 8123, 3123, 0 }; - static ulong[] dim1585Kuo2Init = { 1, 3, 7, 7, 3, 35, 3, 183, 231, 351, 1381, 1251, 3423, 3361, 0 }; - static ulong[] dim1586Kuo2Init = { 1, 1, 1, 5, 23, 11, 71, 137, 323, 809, 827, 1573, 4483, 8691, 0 }; - static ulong[] dim1587Kuo2Init = { 1, 3, 7, 7, 17, 29, 121, 47, 139, 687, 95, 1507, 2009, 1679, 0 }; - static ulong[] dim1588Kuo2Init = { 1, 3, 7, 9, 25, 53, 127, 137, 295, 863, 299, 1831, 5359, 4787, 0 }; - static ulong[] dim1589Kuo2Init = { 1, 3, 1, 9, 29, 3, 83, 35, 367, 675, 1511, 381, 6675, 897, 0 }; - static ulong[] dim1590Kuo2Init = { 1, 3, 5, 13, 1, 15, 57, 199, 349, 873, 1059, 3767, 841, 16259, 0 }; - static ulong[] dim1591Kuo2Init = { 1, 3, 7, 3, 13, 5, 47, 203, 211, 899, 1107, 743, 6825, 8703, 0 }; - static ulong[] dim1592Kuo2Init = { 1, 3, 7, 11, 31, 41, 11, 59, 59, 859, 787, 977, 2223, 15921, 0 }; - static ulong[] dim1593Kuo2Init = { 1, 3, 5, 5, 31, 11, 39, 105, 109, 487, 1459, 2935, 3723, 4697, 0 }; - static ulong[] dim1594Kuo2Init = { 1, 3, 3, 13, 9, 17, 39, 239, 183, 885, 123, 387, 2369, 16179, 0 }; - static ulong[] dim1595Kuo2Init = { 1, 1, 1, 7, 25, 47, 23, 29, 95, 331, 2005, 633, 649, 1623, 0 }; - static ulong[] dim1596Kuo2Init = { 1, 1, 3, 13, 9, 21, 41, 125, 287, 309, 1421, 1637, 2611, 2259, 0 }; - static ulong[] dim1597Kuo2Init = { 1, 1, 3, 3, 11, 27, 117, 93, 419, 521, 1699, 233, 1967, 14147, 0 }; - static ulong[] dim1598Kuo2Init = { 1, 1, 3, 11, 25, 21, 61, 15, 415, 693, 1685, 1727, 961, 3887, 0 }; - static ulong[] dim1599Kuo2Init = { 1, 3, 7, 9, 15, 39, 41, 19, 237, 231, 1605, 2641, 6047, 10235, 0 }; - static ulong[] dim1600Kuo2Init = { 1, 1, 3, 9, 5, 49, 113, 133, 499, 545, 467, 683, 579, 8123, 0 }; - static ulong[] dim1601Kuo2Init = { 1, 3, 5, 13, 11, 31, 121, 229, 225, 135, 85, 1389, 5317, 13453, 0 }; - static ulong[] dim1602Kuo2Init = { 1, 3, 7, 9, 17, 51, 77, 141, 413, 805, 1759, 1139, 5847, 16153, 0 }; - static ulong[] dim1603Kuo2Init = { 1, 3, 5, 7, 23, 29, 79, 235, 113, 981, 1147, 219, 2609, 1089, 0 }; - static ulong[] dim1604Kuo2Init = { 1, 1, 5, 7, 5, 45, 123, 123, 335, 409, 115, 971, 827, 427, 0 }; - static ulong[] dim1605Kuo2Init = { 1, 3, 7, 13, 13, 45, 41, 173, 261, 151, 1199, 2803, 5801, 2449, 0 }; - static ulong[] dim1606Kuo2Init = { 1, 3, 1, 7, 5, 17, 9, 91, 475, 505, 1983, 2539, 339, 16365, 0 }; - static ulong[] dim1607Kuo2Init = { 1, 1, 7, 5, 25, 31, 77, 53, 293, 735, 1423, 165, 4363, 5923, 0 }; - static ulong[] dim1608Kuo2Init = { 1, 1, 1, 15, 7, 51, 117, 91, 347, 677, 1059, 2861, 3583, 11995, 0 }; - static ulong[] dim1609Kuo2Init = { 1, 3, 3, 13, 27, 27, 123, 251, 47, 885, 2015, 1089, 4077, 8591, 0 }; - static ulong[] dim1610Kuo2Init = { 1, 1, 7, 11, 17, 41, 97, 47, 201, 789, 881, 1565, 1169, 10967, 0 }; - static ulong[] dim1611Kuo2Init = { 1, 1, 3, 15, 25, 43, 45, 237, 73, 909, 1041, 1025, 3217, 9347, 0 }; - static ulong[] dim1612Kuo2Init = { 1, 1, 1, 3, 7, 59, 51, 177, 223, 125, 63, 3311, 3171, 8725, 0 }; - static ulong[] dim1613Kuo2Init = { 1, 1, 1, 1, 31, 25, 55, 117, 493, 419, 1749, 2799, 6943, 12427, 0 }; - static ulong[] dim1614Kuo2Init = { 1, 3, 5, 13, 1, 59, 123, 239, 239, 589, 667, 1029, 1357, 6801, 0 }; - static ulong[] dim1615Kuo2Init = { 1, 1, 7, 15, 21, 7, 43, 103, 159, 685, 1435, 529, 4225, 5051, 0 }; - static ulong[] dim1616Kuo2Init = { 1, 3, 1, 13, 29, 21, 19, 229, 369, 317, 1681, 685, 5301, 11107, 0 }; - static ulong[] dim1617Kuo2Init = { 1, 3, 7, 9, 17, 13, 117, 21, 203, 123, 1933, 3981, 5133, 11729, 0 }; - static ulong[] dim1618Kuo2Init = { 1, 3, 3, 1, 29, 5, 119, 27, 135, 913, 1891, 2785, 6311, 8439, 0 }; - static ulong[] dim1619Kuo2Init = { 1, 3, 7, 5, 3, 31, 95, 55, 89, 541, 609, 773, 6513, 10015, 0 }; - static ulong[] dim1620Kuo2Init = { 1, 3, 7, 1, 25, 27, 71, 153, 215, 921, 29, 2103, 1605, 59, 0 }; - static ulong[] dim1621Kuo2Init = { 1, 1, 3, 5, 15, 31, 65, 35, 221, 571, 873, 1271, 5399, 15659, 0 }; - static ulong[] dim1622Kuo2Init = { 1, 3, 5, 3, 31, 31, 127, 251, 379, 801, 905, 1661, 225, 11939, 0 }; - static ulong[] dim1623Kuo2Init = { 1, 3, 1, 15, 31, 59, 51, 117, 325, 491, 1801, 669, 2867, 5325, 0 }; - static ulong[] dim1624Kuo2Init = { 1, 1, 5, 13, 1, 15, 3, 105, 81, 229, 573, 3047, 6373, 11947, 0 }; - static ulong[] dim1625Kuo2Init = { 1, 1, 3, 9, 7, 51, 83, 103, 277, 5, 1189, 89, 7173, 1617, 0 }; - static ulong[] dim1626Kuo2Init = { 1, 1, 5, 3, 11, 13, 5, 205, 179, 23, 1327, 3049, 23, 5123, 0 }; - static ulong[] dim1627Kuo2Init = { 1, 3, 5, 7, 7, 23, 117, 133, 449, 265, 1087, 1565, 7185, 7099, 0 }; - static ulong[] dim1628Kuo2Init = { 1, 1, 3, 5, 7, 13, 31, 197, 29, 659, 1485, 2395, 3239, 5837, 0 }; - static ulong[] dim1629Kuo2Init = { 1, 3, 5, 13, 15, 53, 67, 107, 103, 675, 253, 471, 283, 1221, 0 }; - static ulong[] dim1630Kuo2Init = { 1, 1, 5, 11, 17, 17, 65, 165, 141, 839, 217, 3779, 1151, 3551, 0 }; - static ulong[] dim1631Kuo2Init = { 1, 1, 7, 13, 13, 23, 57, 241, 253, 565, 371, 3713, 4539, 1033, 0 }; - static ulong[] dim1632Kuo2Init = { 1, 1, 7, 11, 17, 11, 121, 193, 9, 33, 695, 1361, 6433, 895, 0 }; - static ulong[] dim1633Kuo2Init = { 1, 1, 1, 3, 15, 11, 87, 87, 419, 605, 163, 377, 3729, 4309, 0 }; - static ulong[] dim1634Kuo2Init = { 1, 3, 5, 3, 17, 43, 13, 99, 409, 919, 1347, 1407, 1723, 11317, 0 }; - static ulong[] dim1635Kuo2Init = { 1, 1, 1, 9, 1, 21, 111, 225, 191, 65, 1231, 27, 387, 12225, 0 }; - static ulong[] dim1636Kuo2Init = { 1, 1, 3, 11, 19, 63, 61, 103, 31, 241, 1807, 3101, 7275, 2333, 0 }; - static ulong[] dim1637Kuo2Init = { 1, 1, 7, 5, 31, 41, 115, 77, 347, 85, 69, 1911, 7345, 15269, 0 }; - static ulong[] dim1638Kuo2Init = { 1, 1, 7, 1, 25, 41, 105, 5, 161, 721, 1667, 1285, 6197, 14823, 0 }; - static ulong[] dim1639Kuo2Init = { 1, 3, 3, 9, 15, 33, 43, 155, 269, 215, 663, 3425, 7725, 15307, 0 }; - static ulong[] dim1640Kuo2Init = { 1, 3, 5, 15, 23, 43, 71, 79, 163, 167, 1207, 741, 141, 8269, 0 }; - static ulong[] dim1641Kuo2Init = { 1, 1, 7, 9, 21, 21, 39, 181, 379, 383, 343, 1685, 1713, 10377, 0 }; - static ulong[] dim1642Kuo2Init = { 1, 3, 3, 7, 3, 17, 45, 11, 351, 111, 229, 3241, 6953, 7143, 0 }; - static ulong[] dim1643Kuo2Init = { 1, 1, 7, 13, 15, 57, 87, 247, 361, 943, 801, 1861, 5705, 14499, 0 }; - static ulong[] dim1644Kuo2Init = { 1, 1, 5, 7, 11, 9, 89, 235, 235, 225, 1053, 2909, 993, 15471, 0 }; - static ulong[] dim1645Kuo2Init = { 1, 3, 3, 11, 15, 47, 73, 13, 477, 703, 1353, 3633, 4059, 16367, 0 }; - static ulong[] dim1646Kuo2Init = { 1, 1, 5, 15, 9, 39, 49, 141, 181, 917, 1331, 427, 7455, 13753, 0 }; - static ulong[] dim1647Kuo2Init = { 1, 3, 1, 13, 11, 7, 113, 101, 473, 851, 771, 1287, 8157, 2113, 0 }; - static ulong[] dim1648Kuo2Init = { 1, 3, 1, 15, 23, 33, 87, 5, 245, 853, 1433, 85, 5655, 11579, 0 }; - static ulong[] dim1649Kuo2Init = { 1, 1, 5, 15, 19, 59, 103, 249, 247, 589, 797, 2733, 6603, 2065, 0 }; - static ulong[] dim1650Kuo2Init = { 1, 1, 1, 7, 25, 63, 105, 183, 497, 25, 739, 521, 7327, 12711, 0 }; - static ulong[] dim1651Kuo2Init = { 1, 3, 3, 7, 27, 13, 63, 23, 417, 303, 155, 2227, 5621, 1643, 0 }; - static ulong[] dim1652Kuo2Init = { 1, 1, 5, 9, 29, 13, 75, 199, 353, 577, 1715, 3939, 2659, 5969, 0 }; - static ulong[] dim1653Kuo2Init = { 1, 1, 5, 11, 11, 37, 55, 185, 435, 763, 333, 3243, 7553, 9741, 0 }; - static ulong[] dim1654Kuo2Init = { 1, 3, 7, 13, 7, 1, 65, 243, 443, 869, 769, 4027, 4831, 7333, 0 }; - static ulong[] dim1655Kuo2Init = { 1, 1, 5, 11, 31, 23, 93, 117, 323, 157, 811, 1543, 449, 8371, 0 }; - static ulong[] dim1656Kuo2Init = { 1, 3, 1, 9, 27, 25, 87, 223, 467, 761, 547, 2381, 411, 14035, 0 }; - static ulong[] dim1657Kuo2Init = { 1, 1, 7, 9, 31, 27, 127, 11, 243, 263, 255, 831, 6801, 10923, 0 }; - static ulong[] dim1658Kuo2Init = { 1, 3, 5, 15, 23, 11, 77, 5, 255, 699, 13, 3883, 4703, 2785, 0 }; - static ulong[] dim1659Kuo2Init = { 1, 3, 1, 1, 25, 37, 47, 75, 79, 881, 1505, 2825, 2477, 1963, 0 }; - static ulong[] dim1660Kuo2Init = { 1, 1, 3, 7, 29, 39, 33, 151, 153, 869, 65, 107, 7173, 5059, 0 }; - static ulong[] dim1661Kuo2Init = { 1, 1, 5, 13, 29, 41, 61, 37, 353, 429, 587, 2431, 3711, 14149, 0 }; - static ulong[] dim1662Kuo2Init = { 1, 1, 3, 7, 13, 23, 29, 157, 427, 353, 1485, 879, 3851, 15775, 0 }; - static ulong[] dim1663Kuo2Init = { 1, 1, 5, 11, 7, 17, 91, 225, 275, 923, 1383, 2587, 7545, 7203, 0 }; - static ulong[] dim1664Kuo2Init = { 1, 1, 5, 3, 3, 57, 75, 97, 233, 233, 1547, 1915, 1229, 8559, 0 }; - static ulong[] dim1665Kuo2Init = { 1, 3, 3, 11, 11, 63, 15, 121, 209, 31, 171, 1117, 2373, 7545, 0 }; - static ulong[] dim1666Kuo2Init = { 1, 1, 1, 3, 27, 7, 89, 155, 7, 829, 537, 3639, 1721, 8199, 0 }; - static ulong[] dim1667Kuo2Init = { 1, 1, 1, 1, 5, 43, 59, 245, 321, 869, 785, 367, 2693, 8603, 0 }; - static ulong[] dim1668Kuo2Init = { 1, 1, 3, 1, 23, 17, 19, 79, 303, 919, 1119, 303, 907, 9033, 0 }; - static ulong[] dim1669Kuo2Init = { 1, 3, 1, 15, 17, 43, 1, 207, 395, 251, 727, 1341, 2073, 16319, 0 }; - static ulong[] dim1670Kuo2Init = { 1, 3, 3, 15, 3, 31, 97, 111, 161, 947, 1509, 2143, 4773, 3569, 0 }; - static ulong[] dim1671Kuo2Init = { 1, 3, 7, 3, 5, 33, 19, 149, 233, 221, 517, 21, 7651, 14987, 0 }; - static ulong[] dim1672Kuo2Init = { 1, 3, 3, 7, 19, 1, 39, 253, 311, 681, 897, 2777, 5181, 6985, 0 }; - static ulong[] dim1673Kuo2Init = { 1, 3, 5, 13, 3, 39, 75, 225, 491, 631, 513, 935, 2775, 6405, 0 }; - static ulong[] dim1674Kuo2Init = { 1, 3, 5, 9, 29, 57, 67, 67, 53, 955, 1297, 3871, 131, 7317, 0 }; - static ulong[] dim1675Kuo2Init = { 1, 3, 3, 9, 31, 55, 53, 179, 305, 625, 1097, 1203, 1973, 2807, 0 }; - static ulong[] dim1676Kuo2Init = { 1, 1, 1, 5, 5, 47, 25, 7, 279, 751, 1149, 2871, 2985, 11941, 0 }; - static ulong[] dim1677Kuo2Init = { 1, 3, 7, 5, 21, 47, 29, 23, 419, 181, 517, 1261, 2329, 11667, 0 }; - static ulong[] dim1678Kuo2Init = { 1, 1, 1, 3, 5, 53, 61, 1, 273, 165, 1227, 2901, 2739, 2453, 0 }; - static ulong[] dim1679Kuo2Init = { 1, 3, 1, 7, 1, 21, 89, 27, 487, 167, 717, 3653, 3971, 7825, 0 }; - static ulong[] dim1680Kuo2Init = { 1, 1, 3, 5, 3, 43, 19, 221, 21, 329, 1415, 1137, 1073, 2869, 0 }; - static ulong[] dim1681Kuo2Init = { 1, 1, 7, 13, 27, 61, 65, 93, 469, 975, 5, 3919, 7565, 13885, 0 }; - static ulong[] dim1682Kuo2Init = { 1, 1, 5, 9, 9, 9, 111, 97, 35, 595, 997, 797, 5963, 12977, 0 }; - static ulong[] dim1683Kuo2Init = { 1, 3, 7, 11, 5, 1, 125, 169, 393, 127, 1297, 3853, 1177, 10553, 0 }; - static ulong[] dim1684Kuo2Init = { 1, 1, 3, 13, 11, 53, 55, 119, 41, 895, 1379, 1955, 7059, 143, 0 }; - static ulong[] dim1685Kuo2Init = { 1, 3, 1, 7, 1, 9, 49, 165, 479, 247, 1555, 2199, 6695, 8983, 0 }; - static ulong[] dim1686Kuo2Init = { 1, 3, 3, 3, 17, 53, 47, 97, 301, 649, 1121, 7, 1335, 11535, 0 }; - static ulong[] dim1687Kuo2Init = { 1, 3, 1, 1, 25, 49, 5, 227, 335, 401, 651, 3089, 823, 3159, 0 }; - static ulong[] dim1688Kuo2Init = { 1, 1, 5, 7, 7, 25, 79, 15, 79, 381, 991, 2319, 6087, 5919, 0 }; - static ulong[] dim1689Kuo2Init = { 1, 3, 7, 3, 17, 53, 99, 237, 305, 411, 1751, 753, 4785, 57, 0 }; - static ulong[] dim1690Kuo2Init = { 1, 1, 5, 7, 15, 27, 91, 159, 451, 877, 715, 1183, 3619, 4521, 0 }; - static ulong[] dim1691Kuo2Init = { 1, 3, 7, 5, 25, 9, 9, 1, 421, 707, 1619, 1423, 7183, 687, 0 }; - static ulong[] dim1692Kuo2Init = { 1, 3, 7, 3, 3, 49, 79, 249, 299, 559, 1619, 2071, 8135, 1975, 0 }; - static ulong[] dim1693Kuo2Init = { 1, 3, 1, 9, 29, 63, 67, 93, 373, 505, 193, 791, 5761, 8329, 0 }; - static ulong[] dim1694Kuo2Init = { 1, 1, 3, 3, 7, 33, 33, 233, 507, 471, 1369, 3355, 27, 6389, 0 }; - static ulong[] dim1695Kuo2Init = { 1, 3, 3, 9, 21, 13, 25, 249, 39, 305, 827, 3559, 937, 6079, 0 }; - static ulong[] dim1696Kuo2Init = { 1, 1, 1, 13, 25, 29, 115, 165, 65, 217, 1519, 3117, 3211, 7211, 0 }; - static ulong[] dim1697Kuo2Init = { 1, 1, 1, 3, 21, 17, 55, 117, 61, 807, 1821, 703, 3403, 14181, 0 }; - static ulong[] dim1698Kuo2Init = { 1, 3, 5, 1, 3, 5, 65, 199, 399, 695, 1527, 1187, 7887, 15437, 0 }; - static ulong[] dim1699Kuo2Init = { 1, 3, 1, 3, 23, 47, 43, 49, 377, 893, 423, 3745, 4291, 2579, 0 }; - static ulong[] dim1700Kuo2Init = { 1, 3, 3, 13, 15, 13, 19, 235, 209, 963, 1331, 1559, 5631, 2411, 0 }; - static ulong[] dim1701Kuo2Init = { 1, 3, 5, 1, 3, 47, 5, 179, 483, 163, 123, 1241, 5767, 4361, 0 }; - static ulong[] dim1702Kuo2Init = { 1, 3, 5, 13, 15, 25, 123, 13, 313, 959, 1845, 3949, 7395, 5727, 0 }; - static ulong[] dim1703Kuo2Init = { 1, 3, 7, 7, 21, 35, 67, 209, 229, 213, 1403, 561, 4229, 13611, 0 }; - static ulong[] dim1704Kuo2Init = { 1, 3, 5, 15, 17, 45, 93, 5, 493, 779, 1357, 243, 2067, 4621, 0 }; - static ulong[] dim1705Kuo2Init = { 1, 3, 7, 1, 19, 29, 11, 219, 247, 133, 443, 1331, 5027, 6953, 0 }; - static ulong[] dim1706Kuo2Init = { 1, 1, 7, 5, 29, 41, 21, 95, 175, 761, 1425, 2471, 4597, 7071, 0 }; - static ulong[] dim1707Kuo2Init = { 1, 3, 7, 15, 25, 5, 49, 153, 415, 703, 321, 3727, 4541, 9711, 0 }; - static ulong[] dim1708Kuo2Init = { 1, 3, 5, 5, 21, 49, 15, 41, 203, 909, 953, 1587, 6323, 12589, 0 }; - static ulong[] dim1709Kuo2Init = { 1, 3, 3, 7, 29, 21, 59, 245, 287, 411, 1211, 2527, 5247, 11691, 0 }; - static ulong[] dim1710Kuo2Init = { 1, 1, 3, 15, 5, 29, 25, 123, 29, 613, 627, 269, 6479, 817, 0 }; - static ulong[] dim1711Kuo2Init = { 1, 3, 5, 3, 23, 11, 15, 177, 421, 803, 273, 3145, 7211, 7141, 0 }; - static ulong[] dim1712Kuo2Init = { 1, 1, 7, 13, 13, 37, 59, 81, 57, 349, 833, 871, 1343, 8911, 0 }; - static ulong[] dim1713Kuo2Init = { 1, 3, 5, 3, 23, 11, 33, 39, 123, 77, 259, 2667, 2121, 203, 0 }; - static ulong[] dim1714Kuo2Init = { 1, 3, 7, 5, 5, 57, 31, 101, 463, 633, 1351, 2209, 5235, 8591, 0 }; - static ulong[] dim1715Kuo2Init = { 1, 1, 7, 9, 1, 35, 39, 121, 155, 847, 1355, 2161, 3073, 5873, 0 }; - static ulong[] dim1716Kuo2Init = { 1, 3, 7, 11, 19, 23, 29, 233, 501, 321, 1131, 641, 4023, 11955, 0 }; - static ulong[] dim1717Kuo2Init = { 1, 3, 3, 7, 13, 39, 119, 157, 261, 167, 511, 2349, 1489, 11523, 0 }; - static ulong[] dim1718Kuo2Init = { 1, 3, 5, 15, 27, 3, 19, 165, 229, 591, 1975, 3411, 4453, 3291, 0 }; - static ulong[] dim1719Kuo2Init = { 1, 3, 5, 15, 11, 41, 61, 117, 505, 347, 957, 2545, 1123, 16229, 0 }; - static ulong[] dim1720Kuo2Init = { 1, 1, 5, 15, 1, 21, 101, 123, 341, 613, 451, 3731, 8031, 1611, 0 }; - static ulong[] dim1721Kuo2Init = { 1, 1, 5, 11, 27, 1, 53, 69, 509, 751, 407, 2777, 1319, 10897, 0 }; - static ulong[] dim1722Kuo2Init = { 1, 3, 5, 7, 7, 5, 127, 91, 17, 699, 1761, 2083, 4587, 10747, 0 }; - static ulong[] dim1723Kuo2Init = { 1, 3, 5, 11, 1, 57, 107, 245, 89, 899, 1765, 3521, 4933, 721, 0 }; - static ulong[] dim1724Kuo2Init = { 1, 1, 1, 1, 27, 49, 113, 201, 491, 921, 417, 3541, 5889, 8417, 0 }; - static ulong[] dim1725Kuo2Init = { 1, 3, 5, 11, 1, 37, 5, 43, 337, 883, 1351, 351, 269, 5501, 0 }; - static ulong[] dim1726Kuo2Init = { 1, 3, 5, 5, 9, 11, 127, 87, 463, 999, 635, 2355, 763, 11959, 0 }; - static ulong[] dim1727Kuo2Init = { 1, 3, 1, 15, 25, 21, 111, 241, 31, 35, 1869, 2913, 5963, 9989, 0 }; - static ulong[] dim1728Kuo2Init = { 1, 1, 7, 13, 23, 57, 7, 225, 115, 649, 395, 515, 5335, 10829, 0 }; - static ulong[] dim1729Kuo2Init = { 1, 3, 5, 13, 21, 21, 51, 1, 39, 927, 681, 1341, 7703, 631, 0 }; - static ulong[] dim1730Kuo2Init = { 1, 1, 3, 13, 25, 35, 101, 215, 15, 207, 137, 409, 6239, 11609, 0 }; - static ulong[] dim1731Kuo2Init = { 1, 3, 1, 15, 11, 47, 17, 131, 405, 633, 35, 3335, 821, 4681, 0 }; - static ulong[] dim1732Kuo2Init = { 1, 1, 1, 9, 17, 17, 105, 81, 449, 421, 707, 1041, 3991, 2943, 0 }; - static ulong[] dim1733Kuo2Init = { 1, 1, 1, 1, 29, 55, 43, 161, 449, 163, 1295, 2583, 1405, 14211, 0 }; - static ulong[] dim1734Kuo2Init = { 1, 1, 1, 7, 15, 41, 125, 65, 347, 753, 1245, 2343, 733, 2269, 0 }; - static ulong[] dim1735Kuo2Init = { 1, 3, 7, 5, 15, 25, 107, 35, 369, 395, 939, 427, 5201, 15761, 0 }; - static ulong[] dim1736Kuo2Init = { 1, 1, 3, 13, 29, 11, 9, 53, 393, 855, 483, 3773, 3491, 14857, 0 }; - static ulong[] dim1737Kuo2Init = { 1, 1, 5, 11, 25, 55, 25, 9, 161, 307, 1381, 2129, 1923, 8779, 0 }; - static ulong[] dim1738Kuo2Init = { 1, 1, 5, 1, 5, 1, 99, 205, 207, 607, 639, 29, 8045, 7159, 0 }; - static ulong[] dim1739Kuo2Init = { 1, 1, 3, 7, 29, 55, 15, 133, 217, 425, 1331, 2337, 2209, 1839, 0 }; - static ulong[] dim1740Kuo2Init = { 1, 3, 5, 1, 25, 1, 47, 135, 433, 647, 1693, 3983, 975, 14725, 0 }; - static ulong[] dim1741Kuo2Init = { 1, 3, 7, 13, 29, 41, 115, 227, 505, 17, 2041, 247, 7409, 12353, 0 }; - static ulong[] dim1742Kuo2Init = { 1, 1, 1, 13, 19, 29, 25, 175, 189, 581, 877, 2775, 737, 223, 0 }; - static ulong[] dim1743Kuo2Init = { 1, 3, 7, 11, 27, 61, 21, 209, 51, 653, 631, 3723, 7471, 11083, 0 }; - static ulong[] dim1744Kuo2Init = { 1, 3, 1, 9, 9, 41, 33, 61, 97, 551, 1029, 663, 5373, 8443, 0 }; - static ulong[] dim1745Kuo2Init = { 1, 3, 3, 9, 9, 39, 85, 103, 95, 865, 269, 1243, 5709, 3969, 0 }; - static ulong[] dim1746Kuo2Init = { 1, 3, 5, 15, 9, 17, 75, 199, 3, 681, 1447, 1663, 7139, 10459, 0 }; - static ulong[] dim1747Kuo2Init = { 1, 1, 1, 15, 3, 21, 99, 203, 161, 669, 611, 771, 7773, 6069, 0 }; - static ulong[] dim1748Kuo2Init = { 1, 3, 3, 3, 17, 13, 111, 93, 35, 119, 113, 1169, 4891, 7753, 0 }; - static ulong[] dim1749Kuo2Init = { 1, 1, 1, 11, 17, 7, 91, 39, 293, 443, 1819, 275, 7699, 8043, 0 }; - static ulong[] dim1750Kuo2Init = { 1, 1, 3, 13, 21, 37, 93, 165, 281, 515, 1913, 839, 2177, 4907, 0 }; - static ulong[] dim1751Kuo2Init = { 1, 3, 5, 11, 17, 23, 59, 161, 99, 371, 1223, 2815, 4019, 9225, 0 }; - static ulong[] dim1752Kuo2Init = { 1, 3, 1, 5, 31, 31, 31, 111, 441, 585, 393, 1665, 1421, 7305, 0 }; - static ulong[] dim1753Kuo2Init = { 1, 1, 5, 11, 19, 29, 81, 71, 223, 759, 2035, 1027, 2725, 4869, 0 }; - static ulong[] dim1754Kuo2Init = { 1, 1, 1, 11, 19, 13, 33, 139, 457, 321, 793, 2043, 4823, 10819, 0 }; - static ulong[] dim1755Kuo2Init = { 1, 3, 3, 5, 27, 9, 93, 141, 269, 177, 545, 1977, 1049, 8445, 0 }; - static ulong[] dim1756Kuo2Init = { 1, 1, 7, 3, 3, 25, 11, 75, 241, 641, 523, 2255, 6649, 2191, 0 }; - static ulong[] dim1757Kuo2Init = { 1, 1, 5, 11, 31, 31, 109, 235, 345, 291, 127, 2015, 7745, 4527, 0 }; - static ulong[] dim1758Kuo2Init = { 1, 1, 3, 7, 3, 55, 107, 51, 145, 545, 1601, 1973, 4083, 3297, 0 }; - static ulong[] dim1759Kuo2Init = { 1, 3, 5, 1, 21, 29, 31, 147, 245, 229, 1387, 2763, 769, 513, 0 }; - static ulong[] dim1760Kuo2Init = { 1, 3, 5, 15, 3, 41, 119, 61, 401, 361, 443, 3663, 3691, 1851, 0 }; - static ulong[] dim1761Kuo2Init = { 1, 3, 5, 5, 17, 7, 55, 159, 121, 841, 913, 3507, 5989, 15807, 0 }; - static ulong[] dim1762Kuo2Init = { 1, 1, 3, 13, 5, 39, 65, 3, 261, 159, 439, 739, 6899, 61, 0 }; - static ulong[] dim1763Kuo2Init = { 1, 1, 5, 13, 13, 43, 111, 17, 1, 503, 587, 1943, 7773, 14015, 0 }; - static ulong[] dim1764Kuo2Init = { 1, 3, 1, 1, 5, 43, 55, 7, 171, 637, 39, 2341, 3027, 8521, 0 }; - static ulong[] dim1765Kuo2Init = { 1, 3, 5, 7, 15, 49, 103, 157, 187, 773, 1391, 21, 5909, 14537, 0 }; - static ulong[] dim1766Kuo2Init = { 1, 1, 5, 13, 1, 29, 63, 249, 473, 351, 705, 1999, 4135, 9683, 0 }; - static ulong[] dim1767Kuo2Init = { 1, 3, 1, 7, 5, 7, 77, 179, 347, 101, 1055, 549, 297, 3195, 0 }; - static ulong[] dim1768Kuo2Init = { 1, 1, 1, 5, 19, 51, 15, 247, 269, 545, 43, 2647, 1245, 6051, 0 }; - static ulong[] dim1769Kuo2Init = { 1, 1, 5, 1, 9, 19, 45, 81, 145, 369, 1505, 1973, 3203, 10947, 0 }; - static ulong[] dim1770Kuo2Init = { 1, 3, 5, 3, 11, 51, 113, 173, 121, 923, 969, 4005, 247, 1729, 0 }; - static ulong[] dim1771Kuo2Init = { 1, 1, 7, 13, 1, 51, 111, 125, 163, 307, 1183, 1865, 2517, 9017, 0 }; - static ulong[] dim1772Kuo2Init = { 1, 1, 5, 13, 7, 9, 115, 191, 53, 891, 1703, 2507, 3103, 12511, 0 }; - static ulong[] dim1773Kuo2Init = { 1, 1, 3, 11, 9, 19, 3, 213, 421, 299, 1341, 3313, 637, 4977, 0 }; - static ulong[] dim1774Kuo2Init = { 1, 3, 5, 13, 21, 7, 89, 185, 337, 105, 415, 375, 4357, 16305, 0 }; - static ulong[] dim1775Kuo2Init = { 1, 1, 7, 7, 23, 25, 55, 19, 253, 879, 1779, 2451, 3485, 3383, 0 }; - static ulong[] dim1776Kuo2Init = { 1, 3, 7, 7, 25, 33, 77, 67, 211, 571, 2029, 161, 3747, 11275, 0 }; - static ulong[] dim1777Kuo2Init = { 1, 1, 3, 3, 15, 33, 55, 121, 97, 5, 907, 1869, 8171, 1553, 0 }; - static ulong[] dim1778Kuo2Init = { 1, 1, 1, 9, 3, 33, 21, 165, 181, 211, 437, 1887, 895, 11549, 0 }; - static ulong[] dim1779Kuo2Init = { 1, 3, 5, 3, 5, 7, 103, 95, 477, 585, 1307, 1017, 4115, 6011, 0 }; - static ulong[] dim1780Kuo2Init = { 1, 1, 3, 11, 25, 45, 67, 239, 171, 869, 285, 2495, 4091, 15037, 0 }; - static ulong[] dim1781Kuo2Init = { 1, 1, 3, 13, 5, 41, 103, 17, 283, 833, 179, 1183, 3323, 9777, 0 }; - static ulong[] dim1782Kuo2Init = { 1, 3, 3, 5, 13, 29, 111, 37, 245, 329, 677, 4039, 2533, 3759, 0 }; - static ulong[] dim1783Kuo2Init = { 1, 1, 7, 15, 23, 63, 115, 243, 347, 869, 587, 3073, 7727, 399, 0 }; - static ulong[] dim1784Kuo2Init = { 1, 1, 7, 7, 5, 57, 49, 39, 463, 417, 1183, 1007, 3823, 15299, 0 }; - static ulong[] dim1785Kuo2Init = { 1, 1, 1, 5, 23, 41, 65, 207, 151, 919, 1495, 2841, 1453, 6273, 0 }; - static ulong[] dim1786Kuo2Init = { 1, 1, 1, 1, 15, 19, 51, 193, 187, 711, 11, 1291, 143, 15375, 0 }; - static ulong[] dim1787Kuo2Init = { 1, 1, 3, 13, 25, 19, 3, 113, 157, 699, 1699, 1793, 29, 1869, 0 }; - static ulong[] dim1788Kuo2Init = { 1, 3, 3, 7, 7, 37, 25, 73, 353, 443, 1517, 2621, 489, 15411, 0 }; - static ulong[] dim1789Kuo2Init = { 1, 1, 1, 1, 7, 9, 91, 67, 471, 395, 1417, 431, 4793, 9517, 0 }; - static ulong[] dim1790Kuo2Init = { 1, 3, 1, 5, 31, 15, 63, 67, 109, 537, 1543, 1021, 2549, 13587, 0 }; - static ulong[] dim1791Kuo2Init = { 1, 1, 1, 3, 7, 63, 127, 141, 23, 281, 523, 283, 347, 2095, 0 }; - static ulong[] dim1792Kuo2Init = { 1, 1, 7, 9, 21, 21, 71, 97, 357, 887, 1785, 3471, 3187, 12163, 0 }; - static ulong[] dim1793Kuo2Init = { 1, 3, 3, 3, 25, 23, 127, 135, 199, 661, 7, 3279, 91, 11879, 0 }; - static ulong[] dim1794Kuo2Init = { 1, 1, 7, 5, 29, 51, 41, 5, 387, 901, 233, 1559, 511, 7735, 0 }; - static ulong[] dim1795Kuo2Init = { 1, 1, 5, 9, 3, 13, 45, 119, 177, 381, 1363, 3627, 259, 771, 0 }; - static ulong[] dim1796Kuo2Init = { 1, 1, 5, 11, 5, 31, 73, 151, 487, 371, 1543, 1183, 697, 10225, 0 }; - static ulong[] dim1797Kuo2Init = { 1, 3, 5, 7, 29, 39, 125, 245, 373, 43, 583, 233, 5799, 7865, 0 }; - static ulong[] dim1798Kuo2Init = { 1, 1, 7, 13, 17, 41, 47, 7, 161, 717, 947, 2421, 1983, 12963, 0 }; - static ulong[] dim1799Kuo2Init = { 1, 3, 3, 3, 31, 19, 11, 131, 217, 533, 1407, 421, 163, 5849, 0 }; - static ulong[] dim1800Kuo2Init = { 1, 1, 3, 13, 31, 49, 77, 33, 335, 627, 1135, 4021, 6609, 819, 0 }; - static ulong[] dim1801Kuo2Init = { 1, 3, 5, 5, 17, 51, 27, 83, 153, 469, 85, 2725, 4297, 8869, 0 }; - static ulong[] dim1802Kuo2Init = { 1, 3, 5, 9, 29, 7, 93, 53, 251, 579, 1243, 2689, 4655, 9247, 0 }; - static ulong[] dim1803Kuo2Init = { 1, 3, 1, 13, 9, 35, 59, 213, 181, 409, 1177, 3783, 6339, 339, 0 }; - static ulong[] dim1804Kuo2Init = { 1, 1, 1, 7, 25, 55, 111, 133, 481, 757, 1683, 2193, 681, 12141, 0 }; - static ulong[] dim1805Kuo2Init = { 1, 1, 3, 13, 11, 1, 57, 137, 359, 325, 67, 3069, 1125, 8305, 0 }; - static ulong[] dim1806Kuo2Init = { 1, 1, 1, 5, 21, 11, 79, 195, 335, 85, 1749, 1859, 4253, 6391, 0 }; - static ulong[] dim1807Kuo2Init = { 1, 1, 3, 13, 17, 55, 23, 119, 159, 843, 1677, 1725, 1139, 2051, 0 }; - static ulong[] dim1808Kuo2Init = { 1, 3, 1, 11, 31, 35, 11, 49, 497, 807, 191, 3889, 7811, 13217, 0 }; - static ulong[] dim1809Kuo2Init = { 1, 3, 1, 9, 29, 63, 117, 161, 191, 371, 245, 219, 1559, 13303, 0 }; - static ulong[] dim1810Kuo2Init = { 1, 3, 3, 7, 5, 19, 37, 231, 381, 323, 233, 3973, 6531, 8807, 0 }; - static ulong[] dim1811Kuo2Init = { 1, 1, 1, 11, 3, 43, 35, 103, 291, 363, 531, 1129, 3321, 3167, 0 }; - static ulong[] dim1812Kuo2Init = { 1, 3, 3, 15, 25, 9, 47, 139, 143, 155, 2005, 1573, 2007, 6483, 0 }; - static ulong[] dim1813Kuo2Init = { 1, 3, 7, 5, 25, 3, 125, 19, 255, 699, 1651, 1449, 3753, 12873, 0 }; - static ulong[] dim1814Kuo2Init = { 1, 1, 7, 5, 7, 7, 63, 31, 255, 991, 1029, 1635, 4941, 7891, 0 }; - static ulong[] dim1815Kuo2Init = { 1, 3, 3, 1, 3, 13, 59, 73, 429, 931, 53, 711, 3305, 7621, 0 }; - static ulong[] dim1816Kuo2Init = { 1, 3, 3, 5, 15, 55, 103, 159, 185, 365, 1283, 1171, 6659, 2547, 0 }; - static ulong[] dim1817Kuo2Init = { 1, 1, 5, 5, 25, 33, 91, 87, 323, 235, 1997, 1397, 6777, 10065, 0 }; - static ulong[] dim1818Kuo2Init = { 1, 3, 1, 1, 7, 35, 19, 5, 327, 163, 651, 215, 7965, 1143, 0 }; - static ulong[] dim1819Kuo2Init = { 1, 1, 1, 11, 7, 13, 69, 129, 277, 665, 1763, 33, 8145, 7131, 0 }; - static ulong[] dim1820Kuo2Init = { 1, 3, 3, 13, 17, 25, 111, 247, 91, 537, 325, 2627, 1777, 2861, 0 }; - static ulong[] dim1821Kuo2Init = { 1, 3, 3, 3, 29, 15, 87, 41, 103, 957, 105, 757, 2635, 4825, 0 }; - static ulong[] dim1822Kuo2Init = { 1, 1, 3, 11, 21, 43, 73, 143, 31, 913, 1579, 1725, 6679, 2491, 0 }; - static ulong[] dim1823Kuo2Init = { 1, 3, 1, 11, 1, 31, 93, 231, 327, 177, 921, 2715, 8015, 3295, 0 }; - static ulong[] dim1824Kuo2Init = { 1, 3, 1, 3, 5, 47, 59, 1, 105, 991, 1581, 115, 1957, 10753, 0 }; - static ulong[] dim1825Kuo2Init = { 1, 3, 7, 9, 13, 31, 65, 241, 353, 613, 1065, 1201, 7267, 2099, 0 }; - static ulong[] dim1826Kuo2Init = { 1, 3, 7, 11, 5, 55, 121, 45, 279, 765, 1263, 993, 5047, 12059, 0 }; - static ulong[] dim1827Kuo2Init = { 1, 1, 7, 3, 25, 27, 13, 123, 357, 339, 1299, 297, 361, 4951, 0 }; - static ulong[] dim1828Kuo2Init = { 1, 3, 5, 3, 13, 43, 117, 237, 3, 463, 911, 3447, 7463, 5985, 0 }; - static ulong[] dim1829Kuo2Init = { 1, 3, 1, 15, 13, 1, 21, 213, 115, 291, 1317, 2201, 7939, 16135, 0 }; - static ulong[] dim1830Kuo2Init = { 1, 1, 3, 15, 13, 15, 55, 51, 203, 277, 71, 1025, 4237, 301, 0 }; - static ulong[] dim1831Kuo2Init = { 1, 1, 5, 5, 17, 31, 95, 25, 7, 519, 1971, 3069, 1937, 5693, 0 }; - static ulong[] dim1832Kuo2Init = { 1, 3, 7, 5, 11, 17, 31, 111, 219, 199, 303, 2527, 4185, 13185, 0 }; - static ulong[] dim1833Kuo2Init = { 1, 3, 5, 13, 11, 17, 105, 147, 51, 885, 675, 3035, 4245, 3257, 0 }; - static ulong[] dim1834Kuo2Init = { 1, 3, 3, 5, 9, 17, 37, 139, 251, 85, 361, 2569, 2727, 14111, 0 }; - static ulong[] dim1835Kuo2Init = { 1, 3, 5, 9, 31, 5, 101, 1, 475, 645, 1515, 2713, 2771, 2981, 0 }; - static ulong[] dim1836Kuo2Init = { 1, 3, 3, 13, 21, 21, 31, 117, 511, 525, 1105, 2881, 6361, 6991, 0 }; - static ulong[] dim1837Kuo2Init = { 1, 1, 5, 5, 15, 5, 47, 11, 391, 239, 65, 1545, 691, 3973, 0 }; - static ulong[] dim1838Kuo2Init = { 1, 3, 1, 1, 9, 3, 91, 49, 505, 353, 1593, 4009, 2535, 4947, 0 }; - static ulong[] dim1839Kuo2Init = { 1, 3, 1, 13, 15, 27, 45, 255, 503, 487, 613, 3453, 655, 10083, 0 }; - static ulong[] dim1840Kuo2Init = { 1, 1, 1, 9, 23, 17, 39, 219, 281, 669, 867, 773, 2555, 12565, 0 }; - static ulong[] dim1841Kuo2Init = { 1, 3, 1, 7, 21, 29, 61, 85, 441, 273, 1889, 1441, 6291, 2599, 0 }; - static ulong[] dim1842Kuo2Init = { 1, 1, 1, 7, 1, 7, 95, 9, 105, 77, 463, 701, 6001, 13491, 0 }; - static ulong[] dim1843Kuo2Init = { 1, 3, 7, 3, 29, 57, 61, 123, 105, 909, 1925, 1255, 7069, 3049, 0 }; - static ulong[] dim1844Kuo2Init = { 1, 1, 3, 11, 15, 37, 23, 25, 359, 743, 1599, 575, 4095, 11539, 0 }; - static ulong[] dim1845Kuo2Init = { 1, 3, 3, 9, 17, 33, 59, 245, 119, 457, 147, 1027, 4051, 507, 0 }; - static ulong[] dim1846Kuo2Init = { 1, 3, 1, 11, 25, 59, 97, 37, 199, 247, 985, 635, 3501, 11213, 0 }; - static ulong[] dim1847Kuo2Init = { 1, 1, 5, 7, 21, 19, 17, 181, 183, 331, 817, 1069, 3863, 7547, 0 }; - static ulong[] dim1848Kuo2Init = { 1, 3, 5, 1, 11, 25, 121, 127, 105, 57, 689, 701, 1527, 5301, 0 }; - static ulong[] dim1849Kuo2Init = { 1, 1, 7, 3, 25, 59, 67, 103, 265, 649, 957, 3073, 3047, 12881, 0 }; - static ulong[] dim1850Kuo2Init = { 1, 3, 1, 3, 17, 15, 103, 37, 359, 665, 1677, 2563, 7079, 2577, 0 }; - static ulong[] dim1851Kuo2Init = { 1, 1, 1, 13, 21, 43, 117, 187, 447, 711, 749, 643, 183, 13053, 0 }; - static ulong[] dim1852Kuo2Init = { 1, 3, 7, 3, 15, 45, 23, 169, 481, 841, 625, 3241, 7739, 13463, 0 }; - static ulong[] dim1853Kuo2Init = { 1, 3, 7, 9, 7, 11, 9, 73, 57, 595, 1981, 3499, 53, 3445, 0 }; - static ulong[] dim1854Kuo2Init = { 1, 3, 3, 11, 17, 13, 61, 139, 445, 287, 705, 3157, 7503, 15279, 0 }; - static ulong[] dim1855Kuo2Init = { 1, 3, 5, 5, 15, 5, 15, 117, 177, 517, 1907, 399, 1613, 9495, 0 }; - static ulong[] dim1856Kuo2Init = { 1, 3, 5, 13, 19, 37, 81, 179, 473, 477, 551, 1235, 6503, 14401, 0 }; - static ulong[] dim1857Kuo2Init = { 1, 3, 5, 7, 1, 21, 29, 181, 25, 349, 1915, 1047, 6645, 5153, 0 }; - static ulong[] dim1858Kuo2Init = { 1, 3, 1, 11, 31, 31, 13, 165, 147, 995, 1767, 4013, 4993, 51, 0 }; - static ulong[] dim1859Kuo2Init = { 1, 1, 3, 11, 19, 33, 47, 179, 465, 811, 1535, 2555, 1843, 10877, 0 }; - static ulong[] dim1860Kuo2Init = { 1, 3, 5, 7, 25, 13, 49, 105, 39, 893, 1729, 1297, 6071, 685, 0 }; - static ulong[] dim1861Kuo2Init = { 1, 1, 3, 5, 3, 17, 69, 141, 83, 393, 1377, 3401, 1749, 10307, 0 }; - static ulong[] dim1862Kuo2Init = { 1, 3, 7, 7, 5, 43, 27, 39, 61, 119, 829, 2105, 8155, 1647, 0 }; - static ulong[] dim1863Kuo2Init = { 1, 1, 1, 3, 7, 61, 83, 253, 129, 459, 1241, 569, 7457, 3635, 0 }; - static ulong[] dim1864Kuo2Init = { 1, 1, 1, 5, 21, 17, 97, 213, 463, 549, 1219, 3685, 3721, 8659, 0 }; - static ulong[] dim1865Kuo2Init = { 1, 3, 7, 5, 19, 53, 45, 151, 15, 483, 1077, 1811, 4861, 9979, 0 }; - static ulong[] dim1866Kuo2Init = { 1, 1, 5, 13, 7, 21, 11, 117, 267, 723, 573, 3335, 6331, 3255, 0 }; - static ulong[] dim1867Kuo2Init = { 1, 3, 5, 3, 23, 17, 83, 171, 501, 249, 1937, 593, 3757, 6035, 30841, 0 }; - static ulong[] dim1868Kuo2Init = { 1, 3, 7, 1, 13, 15, 19, 33, 191, 509, 1461, 2105, 2175, 10593, 27199, 0 }; - static ulong[] dim1869Kuo2Init = { 1, 3, 3, 3, 9, 7, 7, 51, 199, 339, 393, 2543, 4269, 2447, 17671, 0 }; - static ulong[] dim1870Kuo2Init = { 1, 3, 1, 1, 17, 3, 71, 119, 15, 333, 1313, 2609, 1077, 2493, 23109, 0 }; - static ulong[] dim1871Kuo2Init = { 1, 1, 1, 11, 7, 45, 69, 69, 241, 995, 1111, 2141, 5467, 5003, 11135, 0 }; - static ulong[] dim1872Kuo2Init = { 1, 1, 7, 11, 21, 1, 25, 35, 445, 379, 449, 3703, 3281, 3433, 5207, 0 }; - static ulong[] dim1873Kuo2Init = { 1, 3, 3, 5, 15, 49, 119, 11, 331, 681, 1209, 161, 7969, 11115, 4775, 0 }; - static ulong[] dim1874Kuo2Init = { 1, 3, 7, 15, 1, 1, 61, 131, 141, 849, 2035, 125, 2457, 9209, 18411, 0 }; - static ulong[] dim1875Kuo2Init = { 1, 1, 5, 5, 25, 17, 91, 255, 137, 815, 1803, 3521, 181, 15683, 32099, 0 }; - static ulong[] dim1876Kuo2Init = { 1, 3, 1, 11, 29, 13, 91, 129, 167, 323, 823, 3717, 473, 7617, 5431, 0 }; - static ulong[] dim1877Kuo2Init = { 1, 1, 5, 9, 17, 41, 65, 5, 57, 441, 765, 2761, 5033, 14551, 28223, 0 }; - static ulong[] dim1878Kuo2Init = { 1, 3, 1, 1, 11, 11, 35, 109, 197, 349, 1495, 4057, 5255, 8327, 29281, 0 }; - static ulong[] dim1879Kuo2Init = { 1, 1, 7, 1, 27, 33, 7, 133, 439, 329, 655, 2459, 5369, 14681, 12271, 0 }; - static ulong[] dim1880Kuo2Init = { 1, 1, 1, 13, 29, 11, 15, 71, 117, 849, 285, 3779, 1181, 6315, 23627, 0 }; - static ulong[] dim1881Kuo2Init = { 1, 3, 3, 7, 15, 33, 93, 133, 239, 169, 197, 3005, 1035, 6771, 10881, 0 }; - static ulong[] dim1882Kuo2Init = { 1, 3, 3, 13, 29, 13, 69, 157, 275, 335, 1977, 461, 8087, 10027, 6377, 0 }; - static ulong[] dim1883Kuo2Init = { 1, 3, 1, 15, 25, 23, 107, 125, 27, 455, 207, 3425, 5319, 4861, 4853, 0 }; - static ulong[] dim1884Kuo2Init = { 1, 1, 5, 15, 17, 49, 3, 129, 401, 451, 363, 553, 3999, 8115, 25621, 0 }; - static ulong[] dim1885Kuo2Init = { 1, 3, 3, 3, 9, 63, 71, 219, 331, 43, 1369, 3821, 5189, 8799, 19413, 0 }; - static ulong[] dim1886Kuo2Init = { 1, 1, 3, 13, 31, 19, 57, 127, 229, 429, 535, 591, 1135, 12559, 4219, 0 }; - static ulong[] dim1887Kuo2Init = { 1, 1, 7, 3, 11, 41, 49, 45, 423, 299, 571, 1907, 1755, 10813, 14199, 0 }; - static ulong[] dim1888Kuo2Init = { 1, 3, 1, 1, 1, 41, 53, 139, 345, 521, 1051, 691, 7367, 923, 2171, 0 }; - static ulong[] dim1889Kuo2Init = { 1, 1, 7, 1, 23, 39, 21, 241, 433, 269, 1733, 3455, 8171, 585, 9035, 0 }; - static ulong[] dim1890Kuo2Init = { 1, 1, 3, 3, 15, 31, 39, 75, 223, 827, 1799, 2699, 6927, 4251, 16799, 0 }; - static ulong[] dim1891Kuo2Init = { 1, 1, 7, 11, 25, 17, 5, 199, 265, 953, 1609, 185, 5069, 10061, 31235, 0 }; - static ulong[] dim1892Kuo2Init = { 1, 3, 3, 7, 11, 17, 125, 149, 29, 149, 1241, 3975, 2915, 13847, 8245, 0 }; - static ulong[] dim1893Kuo2Init = { 1, 3, 5, 15, 19, 7, 115, 127, 325, 147, 505, 3199, 2261, 15309, 1925, 0 }; - static ulong[] dim1894Kuo2Init = { 1, 1, 3, 15, 19, 27, 45, 131, 35, 69, 275, 2895, 8131, 6311, 15507, 0 }; - static ulong[] dim1895Kuo2Init = { 1, 3, 7, 5, 5, 35, 115, 39, 343, 491, 199, 985, 7767, 13183, 23341, 0 }; - static ulong[] dim1896Kuo2Init = { 1, 3, 3, 3, 17, 19, 125, 237, 393, 1, 1763, 2129, 2221, 4993, 23023, 0 }; - static ulong[] dim1897Kuo2Init = { 1, 1, 5, 13, 1, 39, 53, 77, 43, 665, 173, 1923, 5071, 2713, 28507, 0 }; - static ulong[] dim1898Kuo2Init = { 1, 1, 3, 5, 7, 57, 77, 19, 9, 441, 1941, 475, 4059, 3977, 25689, 0 }; - static ulong[] dim1899Kuo2Init = { 1, 1, 3, 9, 23, 49, 35, 139, 189, 431, 1077, 1057, 1565, 5597, 23755, 0 }; - static ulong[] dim1900Kuo2Init = { 1, 1, 7, 1, 7, 5, 121, 69, 277, 797, 1879, 3479, 3023, 1781, 31307, 0 }; - static ulong[] dim1901Kuo2Init = { 1, 1, 5, 15, 5, 23, 75, 181, 97, 491, 399, 63, 3211, 7099, 14597, 0 }; - static ulong[] dim1902Kuo2Init = { 1, 3, 1, 11, 9, 3, 85, 159, 143, 13, 599, 3685, 4291, 11457, 24571, 0 }; - static ulong[] dim1903Kuo2Init = { 1, 3, 7, 9, 23, 45, 17, 197, 351, 997, 1789, 3965, 1163, 9027, 28843, 0 }; - static ulong[] dim1904Kuo2Init = { 1, 1, 5, 15, 25, 13, 93, 141, 395, 905, 933, 3169, 7551, 1775, 22043, 0 }; - static ulong[] dim1905Kuo2Init = { 1, 3, 3, 11, 17, 47, 115, 211, 157, 887, 1829, 767, 6821, 5243, 26423, 0 }; - static ulong[] dim1906Kuo2Init = { 1, 1, 1, 1, 15, 33, 27, 239, 405, 5, 861, 1909, 1261, 1921, 32245, 0 }; - static ulong[] dim1907Kuo2Init = { 1, 1, 1, 15, 5, 15, 21, 251, 489, 789, 507, 321, 6429, 1885, 23139, 0 }; - static ulong[] dim1908Kuo2Init = { 1, 1, 1, 13, 19, 61, 59, 201, 69, 933, 83, 1657, 1331, 16183, 23085, 0 }; - static ulong[] dim1909Kuo2Init = { 1, 3, 1, 5, 29, 59, 61, 149, 95, 897, 1107, 2853, 5271, 7069, 3759, 0 }; - static ulong[] dim1910Kuo2Init = { 1, 1, 3, 9, 17, 53, 71, 183, 29, 353, 1621, 4015, 6395, 8737, 12507, 0 }; - static ulong[] dim1911Kuo2Init = { 1, 3, 3, 15, 23, 31, 77, 187, 429, 59, 117, 641, 1039, 15113, 1177, 0 }; - static ulong[] dim1912Kuo2Init = { 1, 1, 3, 7, 17, 9, 73, 37, 177, 901, 573, 2503, 5865, 13939, 10123, 0 }; - static ulong[] dim1913Kuo2Init = { 1, 3, 1, 1, 7, 21, 55, 255, 85, 993, 583, 3345, 3211, 6027, 18677, 0 }; - static ulong[] dim1914Kuo2Init = { 1, 3, 3, 1, 27, 37, 111, 235, 281, 363, 121, 3749, 7381, 14959, 22997, 0 }; - static ulong[] dim1915Kuo2Init = { 1, 1, 1, 11, 13, 19, 47, 203, 157, 975, 1173, 1389, 1021, 6481, 547, 0 }; - static ulong[] dim1916Kuo2Init = { 1, 3, 5, 11, 7, 51, 121, 99, 289, 303, 1759, 571, 3585, 2263, 21231, 0 }; - static ulong[] dim1917Kuo2Init = { 1, 3, 5, 9, 9, 7, 25, 39, 443, 635, 1597, 2095, 6739, 16367, 11285, 0 }; - static ulong[] dim1918Kuo2Init = { 1, 1, 1, 9, 5, 47, 107, 223, 389, 25, 1353, 501, 8025, 7269, 23617, 0 }; - static ulong[] dim1919Kuo2Init = { 1, 1, 5, 5, 23, 25, 59, 133, 387, 761, 835, 105, 45, 5469, 13461, 0 }; - static ulong[] dim1920Kuo2Init = { 1, 1, 3, 11, 5, 33, 121, 149, 121, 881, 603, 3455, 7667, 3039, 8471, 0 }; - static ulong[] dim1921Kuo2Init = { 1, 3, 5, 9, 17, 41, 1, 109, 67, 511, 617, 1139, 7605, 12211, 8603, 0 }; - static ulong[] dim1922Kuo2Init = { 1, 1, 3, 9, 13, 27, 5, 163, 17, 889, 199, 77, 5233, 6383, 15787, 0 }; - static ulong[] dim1923Kuo2Init = { 1, 1, 1, 13, 5, 27, 45, 47, 213, 473, 1101, 623, 6169, 3139, 27561, 0 }; - static ulong[] dim1924Kuo2Init = { 1, 1, 3, 13, 15, 63, 79, 51, 47, 227, 1771, 3167, 2975, 16075, 9117, 0 }; - static ulong[] dim1925Kuo2Init = { 1, 1, 5, 5, 29, 9, 87, 213, 349, 763, 1341, 1299, 1183, 4763, 14869, 0 }; - static ulong[] dim1926Kuo2Init = { 1, 3, 7, 1, 23, 3, 37, 99, 341, 67, 1273, 3383, 7805, 8373, 19401, 0 }; - static ulong[] dim1927Kuo2Init = { 1, 3, 3, 3, 7, 25, 23, 231, 291, 591, 291, 1077, 7291, 9763, 515, 0 }; - static ulong[] dim1928Kuo2Init = { 1, 1, 1, 3, 9, 49, 99, 127, 501, 375, 995, 1883, 6229, 1141, 16513, 0 }; - static ulong[] dim1929Kuo2Init = { 1, 1, 1, 13, 21, 35, 43, 39, 405, 283, 1555, 3189, 4999, 139, 11031, 0 }; - static ulong[] dim1930Kuo2Init = { 1, 3, 3, 1, 25, 3, 29, 89, 71, 975, 435, 2513, 4667, 14859, 22495, 0 }; - static ulong[] dim1931Kuo2Init = { 1, 3, 5, 9, 27, 45, 29, 145, 97, 149, 341, 3253, 5385, 8099, 169, 0 }; - static ulong[] dim1932Kuo2Init = { 1, 1, 1, 3, 17, 49, 73, 31, 291, 191, 959, 3139, 6221, 423, 5247, 0 }; - static ulong[] dim1933Kuo2Init = { 1, 3, 7, 3, 11, 23, 25, 65, 291, 877, 15, 437, 3883, 6545, 16327, 0 }; - static ulong[] dim1934Kuo2Init = { 1, 3, 1, 7, 21, 53, 35, 143, 433, 117, 1135, 467, 6825, 16041, 3351, 0 }; - static ulong[] dim1935Kuo2Init = { 1, 3, 5, 1, 11, 57, 105, 147, 443, 1, 1879, 2963, 4041, 8929, 219, 0 }; - static ulong[] dim1936Kuo2Init = { 1, 3, 3, 11, 13, 59, 57, 175, 151, 1015, 629, 1549, 4161, 16147, 25857, 0 }; - static ulong[] dim1937Kuo2Init = { 1, 1, 7, 9, 15, 27, 19, 111, 495, 7, 1219, 2679, 3257, 7111, 23187, 0 }; - static ulong[] dim1938Kuo2Init = { 1, 1, 1, 7, 5, 3, 37, 247, 43, 223, 1681, 225, 6573, 7523, 14433, 0 }; - static ulong[] dim1939Kuo2Init = { 1, 1, 3, 3, 7, 31, 71, 141, 341, 319, 653, 3463, 963, 10133, 27313, 0 }; - static ulong[] dim1940Kuo2Init = { 1, 1, 1, 11, 3, 61, 71, 9, 253, 69, 527, 2927, 1637, 15141, 32423, 0 }; - static ulong[] dim1941Kuo2Init = { 1, 3, 3, 3, 21, 41, 119, 175, 363, 629, 909, 439, 8043, 12489, 18635, 0 }; - static ulong[] dim1942Kuo2Init = { 1, 1, 5, 3, 11, 19, 73, 87, 133, 947, 537, 803, 965, 9139, 7429, 0 }; - static ulong[] dim1943Kuo2Init = { 1, 1, 7, 3, 9, 45, 113, 213, 499, 493, 811, 389, 5323, 409, 17147, 0 }; - static ulong[] dim1944Kuo2Init = { 1, 3, 1, 1, 9, 29, 61, 231, 55, 625, 1917, 3157, 4635, 11441, 24799, 0 }; - static ulong[] dim1945Kuo2Init = { 1, 3, 3, 15, 15, 11, 93, 245, 247, 405, 1123, 2639, 1739, 11957, 19131, 0 }; - static ulong[] dim1946Kuo2Init = { 1, 3, 5, 3, 19, 7, 47, 241, 97, 635, 1871, 2609, 5529, 11591, 13895, 0 }; - static ulong[] dim1947Kuo2Init = { 1, 1, 1, 11, 11, 45, 11, 13, 109, 141, 83, 2109, 3259, 7441, 25881, 0 }; - static ulong[] dim1948Kuo2Init = { 1, 1, 7, 13, 21, 61, 73, 129, 393, 175, 699, 2551, 4761, 13133, 9993, 0 }; - static ulong[] dim1949Kuo2Init = { 1, 1, 7, 1, 31, 17, 85, 57, 457, 383, 1099, 1819, 503, 1389, 28341, 0 }; - static ulong[] dim1950Kuo2Init = { 1, 3, 5, 7, 3, 17, 41, 33, 245, 815, 31, 2259, 1293, 9051, 13241, 0 }; - static ulong[] dim1951Kuo2Init = { 1, 3, 7, 7, 23, 15, 81, 77, 193, 201, 785, 1271, 3061, 4429, 26665, 0 }; - static ulong[] dim1952Kuo2Init = { 1, 1, 5, 15, 29, 23, 43, 227, 119, 843, 55, 1837, 51, 13115, 27725, 0 }; - static ulong[] dim1953Kuo2Init = { 1, 3, 1, 11, 1, 33, 25, 233, 43, 367, 705, 2323, 2721, 12845, 29415, 0 }; - static ulong[] dim1954Kuo2Init = { 1, 3, 5, 1, 25, 23, 5, 233, 507, 267, 607, 3009, 5035, 1069, 30735, 0 }; - static ulong[] dim1955Kuo2Init = { 1, 1, 7, 5, 27, 5, 69, 5, 371, 951, 657, 421, 5707, 10455, 10961, 0 }; - static ulong[] dim1956Kuo2Init = { 1, 1, 3, 11, 13, 13, 71, 113, 381, 619, 1713, 315, 7903, 4737, 24747, 0 }; - static ulong[] dim1957Kuo2Init = { 1, 3, 5, 11, 15, 21, 39, 221, 9, 263, 1697, 3189, 7095, 7769, 10915, 0 }; - static ulong[] dim1958Kuo2Init = { 1, 1, 1, 1, 17, 47, 77, 27, 377, 79, 1245, 1233, 3761, 3667, 12785, 0 }; - static ulong[] dim1959Kuo2Init = { 1, 1, 3, 13, 11, 9, 89, 57, 339, 845, 393, 1717, 3415, 5725, 28655, 0 }; - static ulong[] dim1960Kuo2Init = { 1, 3, 7, 3, 11, 61, 89, 37, 59, 117, 883, 1911, 4513, 561, 31273, 0 }; - static ulong[] dim1961Kuo2Init = { 1, 1, 1, 13, 21, 29, 9, 147, 109, 783, 1647, 2147, 7285, 4035, 8181, 0 }; - static ulong[] dim1962Kuo2Init = { 1, 3, 1, 13, 29, 15, 95, 71, 319, 489, 601, 1731, 7927, 9115, 32607, 0 }; - static ulong[] dim1963Kuo2Init = { 1, 1, 3, 13, 1, 59, 53, 193, 105, 653, 249, 3285, 7817, 4157, 13299, 0 }; - static ulong[] dim1964Kuo2Init = { 1, 1, 7, 15, 5, 63, 5, 111, 427, 781, 1077, 1267, 7253, 4883, 24539, 0 }; - static ulong[] dim1965Kuo2Init = { 1, 1, 1, 5, 15, 13, 97, 187, 175, 617, 931, 3675, 8085, 14433, 22179, 0 }; - static ulong[] dim1966Kuo2Init = { 1, 3, 3, 13, 29, 29, 7, 45, 295, 185, 15, 3171, 5701, 11099, 8663, 0 }; - static ulong[] dim1967Kuo2Init = { 1, 3, 5, 15, 21, 47, 37, 189, 447, 123, 1979, 3633, 4875, 12667, 2349, 0 }; - static ulong[] dim1968Kuo2Init = { 1, 3, 1, 3, 17, 37, 97, 167, 207, 347, 499, 129, 3131, 6649, 10051, 0 }; - static ulong[] dim1969Kuo2Init = { 1, 3, 7, 13, 21, 21, 15, 125, 405, 175, 89, 3299, 1321, 15595, 26015, 0 }; - static ulong[] dim1970Kuo2Init = { 1, 1, 5, 1, 25, 21, 11, 25, 351, 1011, 753, 1813, 2229, 9675, 10073, 0 }; - static ulong[] dim1971Kuo2Init = { 1, 3, 5, 1, 21, 49, 61, 241, 303, 833, 653, 259, 4397, 545, 24857, 0 }; - static ulong[] dim1972Kuo2Init = { 1, 1, 5, 5, 27, 61, 99, 181, 415, 945, 763, 1207, 5413, 11447, 11117, 0 }; - static ulong[] dim1973Kuo2Init = { 1, 1, 3, 3, 27, 11, 5, 197, 211, 971, 1991, 4007, 2337, 2683, 27371, 0 }; - static ulong[] dim1974Kuo2Init = { 1, 1, 5, 3, 5, 39, 25, 59, 223, 117, 1543, 2527, 2673, 15411, 8769, 0 }; - static ulong[] dim1975Kuo2Init = { 1, 3, 7, 11, 31, 7, 33, 7, 319, 679, 685, 953, 491, 251, 16333, 0 }; - static ulong[] dim1976Kuo2Init = { 1, 1, 5, 5, 1, 15, 69, 87, 447, 363, 1883, 937, 2691, 14777, 19757, 0 }; - static ulong[] dim1977Kuo2Init = { 1, 1, 1, 1, 11, 51, 21, 183, 143, 577, 819, 3693, 5421, 9105, 10465, 0 }; - static ulong[] dim1978Kuo2Init = { 1, 1, 7, 1, 7, 7, 25, 131, 63, 881, 931, 2039, 1371, 7479, 7009, 0 }; - static ulong[] dim1979Kuo2Init = { 1, 1, 5, 5, 17, 37, 121, 101, 133, 829, 495, 1031, 6843, 13863, 6543, 0 }; - static ulong[] dim1980Kuo2Init = { 1, 1, 1, 9, 5, 53, 15, 11, 215, 295, 1401, 1633, 395, 201, 18941, 0 }; - static ulong[] dim1981Kuo2Init = { 1, 3, 7, 7, 21, 39, 107, 153, 139, 557, 683, 1993, 3495, 9929, 12067, 0 }; - static ulong[] dim1982Kuo2Init = { 1, 3, 3, 13, 27, 57, 63, 151, 13, 827, 1079, 1209, 5631, 9627, 4765, 0 }; - static ulong[] dim1983Kuo2Init = { 1, 1, 3, 13, 9, 9, 75, 209, 437, 475, 1905, 3021, 7097, 10637, 13301, 0 }; - static ulong[] dim1984Kuo2Init = { 1, 1, 3, 1, 21, 43, 45, 7, 467, 825, 1189, 1525, 3295, 2575, 12071, 0 }; - static ulong[] dim1985Kuo2Init = { 1, 3, 3, 1, 25, 57, 23, 243, 79, 39, 881, 467, 4183, 13881, 26719, 0 }; - static ulong[] dim1986Kuo2Init = { 1, 1, 1, 11, 27, 41, 79, 223, 443, 489, 1531, 3671, 7905, 9593, 175, 0 }; - static ulong[] dim1987Kuo2Init = { 1, 3, 3, 5, 1, 25, 89, 151, 165, 681, 1099, 665, 1209, 13617, 15259, 0 }; - static ulong[] dim1988Kuo2Init = { 1, 3, 3, 3, 17, 25, 13, 85, 179, 335, 951, 4085, 3251, 15061, 14609, 0 }; - static ulong[] dim1989Kuo2Init = { 1, 1, 5, 11, 15, 25, 89, 135, 27, 323, 1143, 7, 3569, 6841, 9243, 0 }; - static ulong[] dim1990Kuo2Init = { 1, 1, 7, 5, 13, 43, 83, 23, 477, 229, 1623, 2641, 1235, 681, 17379, 0 }; - static ulong[] dim1991Kuo2Init = { 1, 3, 1, 13, 1, 17, 77, 125, 121, 253, 1329, 1081, 1191, 7477, 13441, 0 }; - static ulong[] dim1992Kuo2Init = { 1, 1, 7, 15, 5, 61, 23, 251, 407, 373, 1399, 1907, 4145, 15997, 12069, 0 }; - static ulong[] dim1993Kuo2Init = { 1, 1, 3, 7, 9, 27, 85, 209, 21, 225, 745, 1405, 813, 1605, 17463, 0 }; - static ulong[] dim1994Kuo2Init = { 1, 1, 7, 5, 19, 47, 111, 215, 335, 211, 1437, 425, 2325, 15761, 13937, 0 }; - static ulong[] dim1995Kuo2Init = { 1, 3, 5, 9, 31, 21, 113, 89, 369, 165, 1673, 3143, 6765, 13897, 15295, 0 }; - static ulong[] dim1996Kuo2Init = { 1, 3, 1, 1, 23, 57, 97, 9, 219, 513, 1001, 1903, 6033, 4561, 8157, 0 }; - static ulong[] dim1997Kuo2Init = { 1, 3, 5, 13, 17, 59, 125, 93, 397, 277, 1273, 529, 3881, 3345, 32553, 0 }; - static ulong[] dim1998Kuo2Init = { 1, 3, 1, 3, 29, 3, 73, 201, 129, 747, 1417, 77, 4399, 10283, 3677, 0 }; - static ulong[] dim1999Kuo2Init = { 1, 3, 5, 11, 15, 13, 15, 193, 139, 683, 839, 1849, 1229, 7903, 15797, 0 }; - static ulong[] dim2000Kuo2Init = { 1, 1, 7, 1, 19, 37, 103, 173, 63, 269, 1125, 425, 1235, 4193, 10095, 0 }; - static ulong[] dim2001Kuo2Init = { 1, 3, 1, 3, 31, 33, 101, 71, 333, 565, 651, 1741, 3613, 2641, 27201, 0 }; - static ulong[] dim2002Kuo2Init = { 1, 1, 7, 7, 9, 43, 111, 231, 383, 221, 1239, 1927, 715, 7663, 24709, 0 }; - static ulong[] dim2003Kuo2Init = { 1, 1, 7, 1, 3, 41, 117, 129, 53, 527, 1973, 3377, 2803, 10855, 9405, 0 }; - static ulong[] dim2004Kuo2Init = { 1, 3, 5, 15, 15, 61, 29, 75, 141, 517, 255, 1797, 1291, 13859, 10255, 0 }; - static ulong[] dim2005Kuo2Init = { 1, 1, 5, 9, 1, 55, 99, 133, 9, 793, 1525, 2565, 1755, 7293, 27221, 0 }; - static ulong[] dim2006Kuo2Init = { 1, 3, 7, 1, 19, 25, 113, 47, 117, 285, 1937, 513, 75, 2149, 25369, 0 }; - static ulong[] dim2007Kuo2Init = { 1, 3, 3, 7, 3, 45, 1, 145, 501, 197, 423, 1131, 4649, 11027, 25237, 0 }; - static ulong[] dim2008Kuo2Init = { 1, 1, 1, 9, 29, 49, 17, 85, 137, 765, 649, 809, 103, 7537, 5603, 0 }; - static ulong[] dim2009Kuo2Init = { 1, 3, 1, 13, 23, 63, 85, 83, 135, 495, 2023, 2331, 1743, 16221, 2421, 0 }; - static ulong[] dim2010Kuo2Init = { 1, 1, 1, 3, 25, 15, 75, 123, 309, 729, 481, 2335, 6963, 16309, 24593, 0 }; - static ulong[] dim2011Kuo2Init = { 1, 3, 1, 7, 1, 3, 41, 57, 353, 821, 1439, 3445, 2295, 15269, 15821, 0 }; - static ulong[] dim2012Kuo2Init = { 1, 3, 7, 1, 19, 41, 107, 159, 361, 1017, 1435, 2593, 3849, 1139, 5059, 0 }; - static ulong[] dim2013Kuo2Init = { 1, 1, 7, 5, 23, 63, 23, 67, 263, 939, 1167, 3367, 2003, 7903, 1361, 0 }; - static ulong[] dim2014Kuo2Init = { 1, 3, 5, 15, 11, 21, 109, 135, 219, 183, 1303, 2023, 6471, 8203, 21717, 0 }; - static ulong[] dim2015Kuo2Init = { 1, 3, 3, 11, 11, 7, 109, 183, 313, 701, 1661, 2215, 7993, 6097, 15583, 0 }; - static ulong[] dim2016Kuo2Init = { 1, 1, 7, 9, 5, 55, 85, 123, 507, 303, 1701, 767, 313, 12517, 10969, 0 }; - static ulong[] dim2017Kuo2Init = { 1, 3, 1, 15, 1, 31, 97, 249, 407, 829, 693, 135, 5929, 13287, 23105, 0 }; - static ulong[] dim2018Kuo2Init = { 1, 3, 3, 15, 23, 45, 13, 209, 365, 715, 827, 1451, 3817, 9039, 8601, 0 }; - static ulong[] dim2019Kuo2Init = { 1, 1, 5, 3, 3, 5, 41, 175, 65, 467, 179, 1941, 2261, 14143, 10277, 0 }; - static ulong[] dim2020Kuo2Init = { 1, 1, 7, 1, 15, 61, 37, 231, 275, 69, 7, 417, 8131, 12569, 16275, 0 }; - static ulong[] dim2021Kuo2Init = { 1, 1, 7, 11, 3, 49, 1, 243, 237, 303, 2033, 1501, 8059, 1479, 1675, 0 }; - static ulong[] dim2022Kuo2Init = { 1, 1, 3, 5, 21, 49, 87, 5, 235, 343, 1635, 3459, 3961, 14433, 10965, 0 }; - static ulong[] dim2023Kuo2Init = { 1, 1, 7, 13, 29, 5, 105, 167, 57, 247, 1683, 1011, 2071, 10681, 679, 0 }; - static ulong[] dim2024Kuo2Init = { 1, 1, 3, 7, 11, 31, 39, 19, 501, 945, 2043, 3591, 657, 8087, 21159, 0 }; - static ulong[] dim2025Kuo2Init = { 1, 3, 5, 9, 7, 23, 3, 5, 35, 101, 409, 3769, 7163, 739, 28421, 0 }; - static ulong[] dim2026Kuo2Init = { 1, 3, 5, 1, 23, 61, 65, 105, 303, 765, 1483, 883, 5743, 13479, 21489, 0 }; - static ulong[] dim2027Kuo2Init = { 1, 1, 7, 13, 11, 5, 17, 237, 105, 539, 1237, 2727, 3781, 13195, 17029, 0 }; - static ulong[] dim2028Kuo2Init = { 1, 3, 3, 15, 15, 23, 47, 129, 485, 797, 705, 931, 3865, 5029, 27847, 0 }; - static ulong[] dim2029Kuo2Init = { 1, 3, 5, 13, 23, 61, 77, 221, 155, 429, 1933, 3007, 8001, 2137, 15737, 0 }; - static ulong[] dim2030Kuo2Init = { 1, 3, 3, 15, 3, 57, 79, 95, 419, 953, 449, 1843, 6893, 1061, 28427, 0 }; - static ulong[] dim2031Kuo2Init = { 1, 3, 3, 9, 19, 9, 39, 5, 189, 3, 181, 3091, 4215, 14881, 18273, 0 }; - static ulong[] dim2032Kuo2Init = { 1, 1, 3, 13, 17, 63, 27, 49, 483, 947, 173, 3667, 3529, 15343, 23189, 0 }; - static ulong[] dim2033Kuo2Init = { 1, 1, 3, 9, 17, 51, 37, 245, 177, 231, 689, 29, 1029, 12397, 26265, 0 }; - static ulong[] dim2034Kuo2Init = { 1, 3, 1, 13, 15, 35, 55, 5, 303, 559, 1853, 3859, 1879, 3167, 6903, 0 }; - static ulong[] dim2035Kuo2Init = { 1, 3, 3, 9, 9, 47, 59, 163, 373, 621, 1349, 2661, 1787, 13611, 28199, 0 }; - static ulong[] dim2036Kuo2Init = { 1, 3, 3, 9, 15, 55, 93, 193, 267, 325, 1705, 155, 3001, 407, 20829, 0 }; - static ulong[] dim2037Kuo2Init = { 1, 3, 5, 15, 13, 9, 65, 123, 325, 313, 25, 991, 2227, 6597, 30453, 0 }; - static ulong[] dim2038Kuo2Init = { 1, 1, 5, 1, 23, 51, 61, 229, 27, 285, 1185, 1943, 7603, 10565, 22741, 0 }; - static ulong[] dim2039Kuo2Init = { 1, 3, 7, 3, 17, 43, 21, 153, 359, 437, 1275, 3589, 1089, 3941, 16777, 0 }; - static ulong[] dim2040Kuo2Init = { 1, 3, 5, 3, 19, 43, 127, 213, 181, 255, 929, 2553, 1101, 231, 2977, 0 }; - static ulong[] dim2041Kuo2Init = { 1, 3, 7, 11, 7, 49, 39, 209, 141, 691, 1903, 1211, 687, 13107, 17055, 0 }; - static ulong[] dim2042Kuo2Init = { 1, 1, 5, 1, 15, 21, 65, 209, 305, 65, 1383, 2247, 5813, 8961, 16281, 0 }; - static ulong[] dim2043Kuo2Init = { 1, 3, 7, 11, 27, 1, 71, 97, 129, 317, 601, 981, 1947, 8897, 23489, 0 }; - static ulong[] dim2044Kuo2Init = { 1, 1, 3, 9, 17, 35, 57, 37, 243, 217, 703, 3159, 4791, 1365, 14885, 0 }; - static ulong[] dim2045Kuo2Init = { 1, 3, 5, 7, 7, 43, 59, 253, 141, 537, 547, 955, 5351, 13087, 5465, 0 }; - static ulong[] dim2046Kuo2Init = { 1, 1, 5, 9, 15, 53, 47, 105, 55, 1017, 819, 3355, 3653, 11051, 29509, 0 }; - static ulong[] dim2047Kuo2Init = { 1, 1, 3, 7, 17, 39, 13, 125, 161, 985, 1753, 1327, 7635, 11045, 3935, 0 }; - static ulong[] dim2048Kuo2Init = { 1, 1, 7, 9, 1, 19, 55, 227, 111, 347, 85, 3871, 7153, 10527, 3137, 0 }; - static ulong[] dim2049Kuo2Init = { 1, 3, 5, 9, 13, 7, 35, 25, 17, 269, 611, 1523, 3539, 15611, 11837, 0 }; - static ulong[] dim2050Kuo2Init = { 1, 1, 5, 7, 29, 13, 109, 253, 355, 25, 243, 1433, 7463, 10149, 31469, 0 }; - static ulong[] dim2051Kuo2Init = { 1, 3, 3, 15, 1, 51, 85, 27, 137, 299, 1943, 3805, 2661, 8091, 385, 0 }; - static ulong[] dim2052Kuo2Init = { 1, 1, 5, 11, 19, 39, 103, 89, 285, 305, 1157, 149, 6661, 1423, 27163, 0 }; - static ulong[] dim2053Kuo2Init = { 1, 1, 7, 9, 25, 35, 7, 227, 125, 811, 1867, 1851, 5271, 11405, 21457, 0 }; - static ulong[] dim2054Kuo2Init = { 1, 1, 7, 1, 31, 19, 103, 239, 301, 395, 1737, 3467, 7153, 12437, 25795, 0 }; - static ulong[] dim2055Kuo2Init = { 1, 3, 3, 15, 25, 43, 69, 155, 437, 9, 863, 2497, 6857, 3947, 12231, 0 }; - static ulong[] dim2056Kuo2Init = { 1, 3, 7, 11, 3, 63, 27, 207, 87, 727, 791, 1663, 8121, 13149, 3927, 0 }; - static ulong[] dim2057Kuo2Init = { 1, 3, 1, 7, 9, 19, 123, 131, 415, 565, 1571, 1085, 2989, 13693, 32487, 0 }; - static ulong[] dim2058Kuo2Init = { 1, 3, 7, 9, 11, 27, 117, 63, 255, 297, 1147, 1501, 3435, 5861, 21351, 0 }; - static ulong[] dim2059Kuo2Init = { 1, 3, 1, 5, 19, 5, 115, 89, 153, 705, 1233, 1803, 7237, 983, 9299, 0 }; - static ulong[] dim2060Kuo2Init = { 1, 3, 3, 13, 21, 13, 89, 135, 5, 221, 191, 2611, 6007, 9177, 11101, 0 }; - static ulong[] dim2061Kuo2Init = { 1, 3, 7, 15, 9, 43, 123, 123, 301, 233, 1727, 3973, 5241, 13437, 24507, 0 }; - static ulong[] dim2062Kuo2Init = { 1, 3, 3, 5, 19, 29, 33, 127, 185, 319, 1767, 1133, 95, 7745, 32213, 0 }; - static ulong[] dim2063Kuo2Init = { 1, 3, 7, 11, 13, 1, 91, 189, 75, 91, 583, 2317, 5257, 12133, 1951, 0 }; - static ulong[] dim2064Kuo2Init = { 1, 1, 3, 9, 23, 23, 65, 7, 157, 143, 781, 997, 2357, 4907, 16797, 0 }; - static ulong[] dim2065Kuo2Init = { 1, 1, 1, 11, 5, 43, 45, 131, 331, 253, 1975, 415, 2571, 14905, 9595, 0 }; - static ulong[] dim2066Kuo2Init = { 1, 3, 7, 11, 1, 11, 95, 133, 393, 117, 833, 2661, 1683, 14333, 26279, 0 }; - static ulong[] dim2067Kuo2Init = { 1, 3, 7, 5, 23, 51, 57, 9, 63, 377, 2043, 1967, 7039, 13783, 16075, 0 }; - static ulong[] dim2068Kuo2Init = { 1, 3, 5, 5, 13, 49, 65, 59, 449, 665, 2017, 375, 3781, 15139, 26341, 0 }; - static ulong[] dim2069Kuo2Init = { 1, 1, 7, 13, 15, 63, 83, 229, 465, 319, 469, 951, 2405, 15357, 6051, 0 }; - static ulong[] dim2070Kuo2Init = { 1, 3, 3, 7, 15, 37, 97, 37, 89, 717, 449, 1821, 3319, 4957, 5455, 0 }; - static ulong[] dim2071Kuo2Init = { 1, 1, 5, 3, 3, 7, 55, 39, 131, 497, 349, 4083, 6695, 14939, 13979, 0 }; - static ulong[] dim2072Kuo2Init = { 1, 3, 3, 7, 15, 45, 109, 239, 415, 453, 729, 835, 4585, 12751, 8595, 0 }; - static ulong[] dim2073Kuo2Init = { 1, 1, 7, 9, 29, 1, 13, 85, 185, 419, 1269, 981, 5079, 2723, 5275, 0 }; - static ulong[] dim2074Kuo2Init = { 1, 1, 7, 11, 7, 41, 121, 75, 91, 943, 1487, 995, 6815, 15881, 27113, 0 }; - static ulong[] dim2075Kuo2Init = { 1, 1, 7, 9, 1, 53, 83, 209, 327, 547, 1505, 1517, 6105, 5903, 13823, 0 }; - static ulong[] dim2076Kuo2Init = { 1, 1, 3, 15, 25, 1, 33, 61, 249, 367, 1733, 3351, 273, 10053, 27115, 0 }; - static ulong[] dim2077Kuo2Init = { 1, 3, 3, 11, 29, 27, 75, 143, 103, 509, 813, 1881, 2631, 933, 31141, 0 }; - static ulong[] dim2078Kuo2Init = { 1, 3, 3, 7, 31, 9, 27, 69, 291, 927, 183, 1755, 7383, 7721, 4405, 0 }; - static ulong[] dim2079Kuo2Init = { 1, 3, 1, 11, 25, 23, 89, 99, 101, 725, 1791, 2669, 7055, 6703, 27507, 0 }; - static ulong[] dim2080Kuo2Init = { 1, 3, 5, 15, 1, 41, 23, 103, 123, 863, 1643, 947, 1349, 549, 29299, 0 }; - static ulong[] dim2081Kuo2Init = { 1, 1, 3, 3, 9, 53, 67, 187, 203, 565, 1455, 645, 7983, 5311, 8827, 0 }; - static ulong[] dim2082Kuo2Init = { 1, 1, 3, 7, 11, 29, 35, 207, 449, 537, 245, 945, 4067, 10961, 27301, 0 }; - static ulong[] dim2083Kuo2Init = { 1, 3, 1, 13, 3, 23, 15, 171, 439, 217, 1245, 3301, 289, 6895, 30095, 0 }; - static ulong[] dim2084Kuo2Init = { 1, 3, 5, 9, 21, 47, 71, 191, 425, 11, 1831, 3111, 7399, 13689, 28163, 0 }; - static ulong[] dim2085Kuo2Init = { 1, 1, 5, 15, 5, 61, 97, 41, 451, 459, 1007, 2439, 5613, 7985, 9255, 0 }; - static ulong[] dim2086Kuo2Init = { 1, 1, 1, 1, 9, 57, 61, 143, 3, 753, 1839, 2623, 5261, 6169, 13195, 0 }; - static ulong[] dim2087Kuo2Init = { 1, 1, 1, 3, 19, 23, 15, 31, 481, 123, 653, 2763, 5663, 12771, 7469, 0 }; - static ulong[] dim2088Kuo2Init = { 1, 1, 1, 11, 17, 55, 111, 181, 293, 9, 41, 3625, 2865, 9109, 14261, 0 }; - static ulong[] dim2089Kuo2Init = { 1, 1, 5, 15, 27, 13, 45, 109, 321, 609, 551, 4071, 6467, 8245, 6889, 0 }; - static ulong[] dim2090Kuo2Init = { 1, 1, 1, 11, 23, 15, 75, 9, 261, 189, 287, 2479, 2319, 2647, 3415, 0 }; - static ulong[] dim2091Kuo2Init = { 1, 3, 1, 3, 31, 47, 45, 73, 439, 789, 687, 3205, 863, 2471, 27997, 0 }; - static ulong[] dim2092Kuo2Init = { 1, 3, 3, 13, 17, 47, 111, 205, 307, 299, 439, 965, 6093, 3215, 29381, 0 }; - static ulong[] dim2093Kuo2Init = { 1, 1, 7, 11, 11, 31, 119, 93, 385, 149, 843, 3081, 6793, 4427, 23967, 0 }; - static ulong[] dim2094Kuo2Init = { 1, 3, 7, 11, 7, 9, 27, 135, 465, 169, 1229, 1491, 3527, 13801, 13187, 0 }; - static ulong[] dim2095Kuo2Init = { 1, 3, 7, 1, 27, 43, 9, 213, 95, 273, 1067, 1819, 4087, 15955, 7865, 0 }; - static ulong[] dim2096Kuo2Init = { 1, 1, 3, 5, 25, 53, 49, 15, 159, 713, 203, 1599, 4807, 7275, 20589, 0 }; - static ulong[] dim2097Kuo2Init = { 1, 3, 1, 7, 9, 33, 5, 41, 289, 611, 153, 1019, 5571, 8459, 2903, 0 }; - static ulong[] dim2098Kuo2Init = { 1, 1, 5, 11, 5, 9, 9, 245, 205, 821, 73, 2907, 2061, 10255, 24837, 0 }; - static ulong[] dim2099Kuo2Init = { 1, 3, 3, 15, 3, 29, 79, 139, 57, 181, 741, 667, 3251, 15741, 2349, 0 }; - static ulong[] dim2100Kuo2Init = { 1, 1, 7, 11, 15, 31, 63, 115, 475, 801, 195, 155, 2167, 9215, 11041, 0 }; - static ulong[] dim2101Kuo2Init = { 1, 3, 7, 3, 7, 45, 17, 151, 353, 751, 373, 1523, 6271, 10307, 637, 0 }; - static ulong[] dim2102Kuo2Init = { 1, 1, 1, 13, 15, 59, 99, 143, 261, 349, 327, 3931, 3365, 12179, 3017, 0 }; - static ulong[] dim2103Kuo2Init = { 1, 3, 5, 1, 27, 13, 105, 127, 177, 857, 405, 185, 5793, 8043, 11671, 0 }; - static ulong[] dim2104Kuo2Init = { 1, 1, 7, 5, 9, 51, 127, 47, 421, 687, 961, 1413, 6619, 3459, 9093, 0 }; - static ulong[] dim2105Kuo2Init = { 1, 1, 7, 11, 15, 45, 7, 123, 479, 55, 491, 2901, 5183, 6081, 31719, 0 }; - static ulong[] dim2106Kuo2Init = { 1, 3, 3, 13, 3, 49, 29, 147, 453, 659, 753, 233, 251, 12445, 6573, 0 }; - static ulong[] dim2107Kuo2Init = { 1, 1, 3, 9, 7, 41, 3, 59, 187, 37, 1503, 4079, 5687, 16213, 9573, 0 }; - static ulong[] dim2108Kuo2Init = { 1, 3, 7, 13, 19, 49, 75, 173, 219, 889, 859, 2021, 2249, 4031, 29485, 0 }; - static ulong[] dim2109Kuo2Init = { 1, 3, 7, 9, 3, 21, 37, 79, 277, 307, 465, 1219, 4099, 5285, 27883, 0 }; - static ulong[] dim2110Kuo2Init = { 1, 3, 5, 3, 19, 49, 97, 7, 483, 995, 775, 883, 2011, 16321, 31869, 0 }; - static ulong[] dim2111Kuo2Init = { 1, 3, 7, 1, 25, 59, 113, 177, 507, 911, 1251, 571, 917, 2655, 31463, 0 }; - static ulong[] dim2112Kuo2Init = { 1, 3, 1, 5, 15, 23, 47, 79, 401, 245, 317, 1033, 3377, 2605, 13021, 0 }; - static ulong[] dim2113Kuo2Init = { 1, 1, 3, 7, 3, 1, 41, 253, 507, 283, 707, 1305, 2353, 5721, 15469, 0 }; - static ulong[] dim2114Kuo2Init = { 1, 3, 1, 7, 25, 25, 15, 79, 193, 235, 1981, 2059, 2057, 1647, 5443, 0 }; - static ulong[] dim2115Kuo2Init = { 1, 1, 1, 3, 7, 37, 51, 169, 163, 223, 457, 1841, 857, 15847, 27369, 0 }; - static ulong[] dim2116Kuo2Init = { 1, 1, 3, 11, 23, 49, 93, 89, 347, 213, 615, 1305, 885, 6195, 6659, 0 }; - static ulong[] dim2117Kuo2Init = { 1, 3, 7, 9, 9, 27, 3, 217, 337, 977, 1109, 1915, 677, 8927, 4449, 0 }; - static ulong[] dim2118Kuo2Init = { 1, 1, 7, 5, 11, 39, 23, 189, 467, 735, 817, 2269, 5959, 2933, 15667, 0 }; - static ulong[] dim2119Kuo2Init = { 1, 1, 5, 5, 21, 33, 21, 241, 75, 751, 671, 3053, 7865, 4261, 13455, 0 }; - static ulong[] dim2120Kuo2Init = { 1, 3, 1, 7, 25, 11, 21, 149, 429, 275, 1815, 1153, 4471, 14993, 3543, 0 }; - static ulong[] dim2121Kuo2Init = { 1, 3, 5, 1, 3, 47, 9, 113, 423, 205, 1905, 57, 6157, 6335, 7425, 0 }; - static ulong[] dim2122Kuo2Init = { 1, 1, 7, 11, 17, 13, 97, 99, 145, 319, 945, 1559, 3379, 12559, 22479, 0 }; - static ulong[] dim2123Kuo2Init = { 1, 1, 7, 9, 3, 47, 105, 251, 87, 293, 1191, 2211, 4631, 8443, 11789, 0 }; - static ulong[] dim2124Kuo2Init = { 1, 1, 1, 3, 5, 1, 41, 115, 331, 401, 1649, 179, 1639, 16241, 18481, 0 }; - static ulong[] dim2125Kuo2Init = { 1, 3, 1, 7, 15, 33, 117, 121, 81, 807, 1897, 1731, 2793, 12531, 8863, 0 }; - static ulong[] dim2126Kuo2Init = { 1, 3, 1, 13, 1, 41, 83, 5, 331, 423, 855, 1327, 5799, 3679, 21461, 0 }; - static ulong[] dim2127Kuo2Init = { 1, 3, 1, 3, 19, 37, 75, 39, 413, 123, 1073, 2299, 5379, 12805, 3527, 0 }; - static ulong[] dim2128Kuo2Init = { 1, 3, 3, 1, 7, 17, 25, 227, 383, 501, 673, 2609, 1843, 3367, 9901, 0 }; - static ulong[] dim2129Kuo2Init = { 1, 1, 7, 11, 25, 29, 95, 33, 431, 257, 1013, 3755, 2813, 15247, 1045, 0 }; - static ulong[] dim2130Kuo2Init = { 1, 1, 7, 3, 15, 25, 79, 67, 175, 697, 1867, 1967, 8023, 2017, 15449, 0 }; - static ulong[] dim2131Kuo2Init = { 1, 3, 3, 1, 21, 25, 67, 177, 479, 81, 495, 3531, 1997, 5169, 15861, 0 }; - static ulong[] dim2132Kuo2Init = { 1, 3, 3, 9, 7, 23, 57, 97, 7, 917, 1969, 3421, 2149, 11379, 1035, 0 }; - static ulong[] dim2133Kuo2Init = { 1, 1, 5, 9, 5, 45, 51, 29, 289, 49, 1311, 4005, 3619, 12337, 7693, 0 }; - static ulong[] dim2134Kuo2Init = { 1, 3, 1, 7, 25, 9, 11, 23, 281, 517, 1309, 2719, 3133, 529, 21795, 0 }; - static ulong[] dim2135Kuo2Init = { 1, 3, 3, 1, 5, 43, 79, 87, 389, 189, 547, 3161, 4765, 10751, 15557, 0 }; - static ulong[] dim2136Kuo2Init = { 1, 3, 1, 13, 29, 11, 5, 75, 453, 323, 999, 341, 6991, 14803, 31057, 0 }; - static ulong[] dim2137Kuo2Init = { 1, 1, 5, 11, 7, 3, 81, 201, 195, 221, 1949, 2205, 2273, 12029, 21089, 0 }; - static ulong[] dim2138Kuo2Init = { 1, 1, 7, 1, 25, 53, 7, 135, 7, 179, 797, 567, 1459, 9773, 2839, 0 }; - static ulong[] dim2139Kuo2Init = { 1, 1, 3, 7, 31, 27, 41, 253, 273, 749, 1605, 2259, 7171, 11861, 11769, 0 }; - static ulong[] dim2140Kuo2Init = { 1, 1, 1, 5, 13, 49, 25, 131, 397, 783, 1849, 3585, 2727, 8213, 14849, 0 }; - static ulong[] dim2141Kuo2Init = { 1, 3, 5, 1, 25, 35, 121, 159, 27, 305, 1841, 1893, 829, 11659, 9859, 0 }; - static ulong[] dim2142Kuo2Init = { 1, 1, 5, 5, 3, 11, 79, 49, 95, 755, 1011, 2247, 5731, 12975, 20241, 0 }; - static ulong[] dim2143Kuo2Init = { 1, 1, 5, 3, 25, 5, 103, 35, 337, 619, 35, 3655, 5137, 4867, 6055, 0 }; - static ulong[] dim2144Kuo2Init = { 1, 1, 7, 1, 15, 35, 67, 113, 381, 1001, 177, 3981, 1059, 4433, 26845, 0 }; - static ulong[] dim2145Kuo2Init = { 1, 3, 7, 9, 19, 3, 107, 161, 109, 129, 1447, 4053, 7435, 3483, 7595, 0 }; - static ulong[] dim2146Kuo2Init = { 1, 1, 7, 9, 13, 25, 19, 137, 149, 191, 719, 1279, 6129, 6367, 9335, 0 }; - static ulong[] dim2147Kuo2Init = { 1, 3, 5, 11, 19, 55, 19, 191, 31, 341, 485, 1165, 501, 11771, 17423, 0 }; - static ulong[] dim2148Kuo2Init = { 1, 3, 7, 1, 21, 35, 115, 163, 99, 581, 1769, 1887, 6349, 13467, 10503, 0 }; - static ulong[] dim2149Kuo2Init = { 1, 1, 7, 3, 23, 21, 105, 255, 501, 171, 1689, 1747, 2603, 11783, 7633, 0 }; - static ulong[] dim2150Kuo2Init = { 1, 1, 7, 7, 9, 45, 65, 95, 47, 163, 1597, 2693, 7407, 8155, 13645, 0 }; - static ulong[] dim2151Kuo2Init = { 1, 1, 1, 1, 9, 5, 105, 55, 217, 773, 43, 741, 1093, 8087, 8003, 0 }; - static ulong[] dim2152Kuo2Init = { 1, 3, 5, 15, 19, 29, 127, 29, 23, 27, 2011, 623, 2649, 2979, 269, 0 }; - static ulong[] dim2153Kuo2Init = { 1, 3, 3, 15, 3, 17, 121, 85, 313, 333, 89, 1, 1147, 15909, 24017, 0 }; - static ulong[] dim2154Kuo2Init = { 1, 3, 5, 13, 17, 53, 89, 27, 219, 451, 629, 2539, 4151, 4811, 17057, 0 }; - static ulong[] dim2155Kuo2Init = { 1, 1, 1, 3, 31, 47, 127, 63, 85, 387, 61, 685, 1103, 1257, 19305, 0 }; - static ulong[] dim2156Kuo2Init = { 1, 3, 7, 11, 25, 7, 39, 209, 449, 667, 227, 605, 987, 1699, 11001, 0 }; - static ulong[] dim2157Kuo2Init = { 1, 3, 5, 15, 23, 35, 15, 193, 25, 1021, 1371, 3015, 7837, 14087, 21779, 0 }; - static ulong[] dim2158Kuo2Init = { 1, 1, 5, 1, 1, 25, 25, 241, 493, 901, 1261, 261, 6959, 16013, 2849, 0 }; - static ulong[] dim2159Kuo2Init = { 1, 3, 1, 5, 13, 27, 85, 41, 139, 567, 753, 3255, 5633, 15687, 3019, 0 }; - static ulong[] dim2160Kuo2Init = { 1, 1, 3, 11, 19, 61, 43, 153, 299, 931, 1481, 203, 593, 5019, 28309, 0 }; - static ulong[] dim2161Kuo2Init = { 1, 3, 7, 7, 9, 11, 107, 243, 227, 69, 605, 3761, 1091, 4503, 21203, 0 }; - static ulong[] dim2162Kuo2Init = { 1, 3, 5, 11, 11, 55, 47, 167, 291, 883, 1411, 3099, 1099, 11619, 9781, 0 }; - static ulong[] dim2163Kuo2Init = { 1, 3, 7, 15, 23, 53, 109, 247, 459, 793, 839, 3069, 1829, 5151, 26255, 0 }; - static ulong[] dim2164Kuo2Init = { 1, 3, 1, 15, 11, 31, 73, 193, 341, 791, 187, 3787, 4481, 11435, 715, 0 }; - static ulong[] dim2165Kuo2Init = { 1, 3, 1, 13, 13, 61, 79, 193, 455, 571, 1277, 1565, 7385, 4393, 27447, 0 }; - static ulong[] dim2166Kuo2Init = { 1, 3, 7, 3, 13, 35, 39, 89, 335, 701, 1423, 2441, 2895, 2795, 28511, 0 }; - static ulong[] dim2167Kuo2Init = { 1, 3, 1, 1, 9, 27, 39, 163, 127, 163, 1881, 1995, 2629, 4541, 1669, 0 }; - static ulong[] dim2168Kuo2Init = { 1, 1, 5, 3, 5, 53, 29, 223, 433, 643, 1035, 2339, 5947, 3047, 27409, 0 }; - static ulong[] dim2169Kuo2Init = { 1, 3, 1, 15, 5, 35, 47, 49, 347, 579, 551, 2285, 3171, 8041, 8223, 0 }; - static ulong[] dim2170Kuo2Init = { 1, 1, 1, 1, 1, 57, 51, 219, 339, 95, 1585, 2811, 4771, 1475, 7919, 0 }; - static ulong[] dim2171Kuo2Init = { 1, 3, 7, 3, 21, 11, 51, 143, 111, 475, 1669, 3717, 6579, 7161, 9491, 0 }; - static ulong[] dim2172Kuo2Init = { 1, 3, 1, 5, 1, 17, 15, 179, 485, 587, 571, 3259, 3299, 207, 2121, 0 }; - static ulong[] dim2173Kuo2Init = { 1, 3, 5, 13, 27, 19, 23, 47, 289, 997, 523, 3183, 8087, 2621, 31471, 0 }; - static ulong[] dim2174Kuo2Init = { 1, 1, 3, 7, 23, 21, 125, 181, 393, 177, 419, 2809, 6727, 1063, 10889, 0 }; - static ulong[] dim2175Kuo2Init = { 1, 3, 5, 1, 19, 29, 115, 149, 439, 125, 7, 2173, 6691, 4063, 8193, 0 }; - static ulong[] dim2176Kuo2Init = { 1, 1, 3, 11, 3, 17, 9, 251, 493, 977, 1713, 2711, 4377, 3171, 22195, 0 }; - static ulong[] dim2177Kuo2Init = { 1, 1, 3, 1, 17, 63, 73, 141, 323, 875, 713, 2133, 3283, 10039, 11431, 0 }; - static ulong[] dim2178Kuo2Init = { 1, 1, 7, 5, 29, 33, 63, 19, 191, 915, 1523, 3505, 2431, 9531, 5253, 0 }; - static ulong[] dim2179Kuo2Init = { 1, 3, 5, 5, 15, 25, 81, 97, 455, 141, 1947, 2001, 6015, 11439, 29725, 0 }; - static ulong[] dim2180Kuo2Init = { 1, 1, 1, 1, 7, 35, 71, 205, 485, 495, 345, 1991, 6905, 12535, 2209, 0 }; - static ulong[] dim2181Kuo2Init = { 1, 1, 7, 15, 27, 23, 19, 119, 347, 519, 423, 1567, 7783, 15095, 23609, 0 }; - static ulong[] dim2182Kuo2Init = { 1, 3, 7, 1, 23, 13, 23, 239, 199, 575, 1149, 771, 3779, 12437, 32301, 0 }; - static ulong[] dim2183Kuo2Init = { 1, 3, 5, 3, 31, 55, 87, 111, 233, 633, 1037, 4053, 2007, 15197, 31531, 0 }; - static ulong[] dim2184Kuo2Init = { 1, 1, 1, 7, 3, 47, 11, 169, 293, 959, 903, 2129, 1049, 1311, 4027, 0 }; - static ulong[] dim2185Kuo2Init = { 1, 3, 3, 7, 1, 15, 37, 79, 299, 989, 969, 2699, 4531, 8455, 30613, 0 }; - static ulong[] dim2186Kuo2Init = { 1, 3, 1, 15, 13, 25, 57, 237, 117, 659, 517, 1821, 4755, 6745, 13269, 0 }; - static ulong[] dim2187Kuo2Init = { 1, 3, 7, 11, 3, 27, 53, 197, 285, 897, 5, 675, 255, 5999, 7629, 0 }; - static ulong[] dim2188Kuo2Init = { 1, 3, 7, 7, 21, 21, 71, 117, 347, 251, 1025, 2455, 7177, 9135, 15569, 0 }; - static ulong[] dim2189Kuo2Init = { 1, 3, 1, 3, 25, 7, 113, 229, 243, 173, 1903, 427, 2743, 2245, 12783, 0 }; - static ulong[] dim2190Kuo2Init = { 1, 1, 1, 15, 11, 53, 45, 209, 181, 147, 183, 3133, 4793, 14731, 16491, 0 }; - static ulong[] dim2191Kuo2Init = { 1, 3, 7, 5, 27, 45, 77, 211, 89, 555, 1829, 4073, 839, 12079, 27745, 0 }; - static ulong[] dim2192Kuo2Init = { 1, 1, 3, 7, 1, 29, 17, 65, 47, 995, 85, 69, 641, 4139, 1221, 0 }; - static ulong[] dim2193Kuo2Init = { 1, 3, 3, 3, 11, 57, 11, 69, 285, 837, 1129, 3465, 323, 4599, 6593, 0 }; - static ulong[] dim2194Kuo2Init = { 1, 3, 5, 7, 19, 27, 1, 197, 259, 315, 567, 613, 5385, 4495, 13507, 0 }; - static ulong[] dim2195Kuo2Init = { 1, 3, 3, 7, 13, 63, 3, 81, 363, 67, 1025, 1403, 4469, 9881, 3563, 0 }; - static ulong[] dim2196Kuo2Init = { 1, 1, 1, 5, 23, 1, 103, 51, 445, 1017, 361, 811, 4555, 6013, 25117, 0 }; - static ulong[] dim2197Kuo2Init = { 1, 1, 1, 11, 21, 33, 73, 13, 155, 419, 371, 499, 3003, 7577, 19191, 0 }; - static ulong[] dim2198Kuo2Init = { 1, 1, 1, 13, 19, 57, 91, 251, 157, 551, 1529, 2649, 7785, 4357, 18533, 0 }; - static ulong[] dim2199Kuo2Init = { 1, 1, 1, 15, 29, 23, 33, 139, 495, 87, 1291, 1441, 819, 321, 24597, 0 }; - static ulong[] dim2200Kuo2Init = { 1, 1, 5, 7, 11, 21, 127, 135, 395, 511, 213, 4043, 5869, 5733, 23157, 0 }; - static ulong[] dim2201Kuo2Init = { 1, 3, 5, 5, 1, 61, 99, 155, 415, 111, 1335, 241, 1935, 7457, 7127, 0 }; - static ulong[] dim2202Kuo2Init = { 1, 1, 3, 7, 25, 43, 69, 97, 423, 989, 1433, 107, 7253, 6543, 1685, 0 }; - static ulong[] dim2203Kuo2Init = { 1, 3, 1, 3, 9, 51, 77, 69, 1, 75, 1859, 3735, 1199, 13725, 6689, 0 }; - static ulong[] dim2204Kuo2Init = { 1, 3, 5, 7, 13, 7, 103, 91, 465, 675, 1221, 2853, 6785, 7113, 12671, 0 }; - static ulong[] dim2205Kuo2Init = { 1, 3, 1, 15, 9, 9, 75, 17, 357, 559, 1021, 1023, 779, 10805, 12707, 0 }; - static ulong[] dim2206Kuo2Init = { 1, 3, 5, 1, 19, 41, 25, 209, 61, 225, 533, 2661, 6735, 4877, 20085, 0 }; - static ulong[] dim2207Kuo2Init = { 1, 1, 5, 7, 29, 35, 61, 21, 203, 689, 1431, 2009, 3475, 2103, 19457, 0 }; - static ulong[] dim2208Kuo2Init = { 1, 1, 3, 9, 7, 51, 119, 115, 357, 969, 779, 2407, 1669, 4671, 21945, 0 }; - static ulong[] dim2209Kuo2Init = { 1, 1, 5, 13, 5, 33, 125, 61, 123, 569, 7, 2389, 3325, 15701, 16931, 0 }; - static ulong[] dim2210Kuo2Init = { 1, 1, 3, 7, 13, 29, 7, 205, 397, 861, 1035, 675, 5963, 9229, 14537, 0 }; - static ulong[] dim2211Kuo2Init = { 1, 3, 7, 5, 13, 41, 69, 25, 461, 745, 189, 3239, 4515, 2717, 22815, 0 }; - static ulong[] dim2212Kuo2Init = { 1, 1, 1, 7, 29, 47, 49, 91, 403, 325, 1241, 2295, 6371, 6791, 911, 0 }; - static ulong[] dim2213Kuo2Init = { 1, 1, 1, 5, 13, 47, 83, 161, 371, 779, 1935, 3445, 735, 1963, 17267, 0 }; - static ulong[] dim2214Kuo2Init = { 1, 3, 7, 7, 19, 59, 41, 217, 71, 407, 1639, 4081, 8011, 4805, 1847, 0 }; - static ulong[] dim2215Kuo2Init = { 1, 1, 7, 9, 21, 11, 113, 151, 269, 119, 615, 2657, 1835, 16071, 7475, 0 }; - static ulong[] dim2216Kuo2Init = { 1, 1, 1, 13, 13, 53, 121, 231, 419, 439, 1287, 3043, 8187, 4355, 16377, 0 }; - static ulong[] dim2217Kuo2Init = { 1, 1, 1, 3, 1, 51, 69, 49, 403, 549, 659, 501, 7497, 9461, 8813, 0 }; - static ulong[] dim2218Kuo2Init = { 1, 3, 3, 9, 15, 13, 11, 65, 241, 77, 675, 2077, 927, 11841, 2527, 0 }; - static ulong[] dim2219Kuo2Init = { 1, 1, 5, 9, 23, 35, 113, 33, 497, 1001, 1105, 2157, 1209, 7821, 20345, 0 }; - static ulong[] dim2220Kuo2Init = { 1, 1, 1, 5, 23, 39, 81, 151, 259, 491, 1129, 1115, 4501, 5513, 20347, 0 }; - static ulong[] dim2221Kuo2Init = { 1, 1, 5, 1, 11, 59, 55, 195, 157, 915, 35, 489, 2805, 9059, 14757, 0 }; - static ulong[] dim2222Kuo2Init = { 1, 3, 5, 15, 9, 21, 91, 59, 425, 127, 1939, 2763, 1243, 4303, 4549, 0 }; - static ulong[] dim2223Kuo2Init = { 1, 1, 5, 13, 19, 29, 127, 251, 91, 419, 333, 2943, 1649, 8653, 32401, 0 }; - static ulong[] dim2224Kuo2Init = { 1, 3, 1, 11, 13, 13, 73, 153, 131, 675, 1235, 1565, 2153, 3999, 3075, 0 }; - static ulong[] dim2225Kuo2Init = { 1, 1, 5, 13, 1, 29, 111, 229, 23, 649, 1017, 2257, 1967, 9839, 21179, 0 }; - static ulong[] dim2226Kuo2Init = { 1, 1, 3, 9, 13, 59, 39, 243, 453, 51, 801, 727, 5391, 11987, 12431, 0 }; - static ulong[] dim2227Kuo2Init = { 1, 1, 7, 5, 9, 7, 59, 203, 177, 255, 1525, 1869, 5187, 135, 11205, 0 }; - static ulong[] dim2228Kuo2Init = { 1, 1, 5, 5, 17, 49, 115, 101, 45, 385, 1751, 883, 7437, 3839, 7997, 0 }; - static ulong[] dim2229Kuo2Init = { 1, 1, 1, 13, 11, 17, 99, 127, 457, 333, 395, 1387, 4533, 2247, 5999, 0 }; - static ulong[] dim2230Kuo2Init = { 1, 3, 7, 7, 15, 61, 103, 217, 175, 133, 1721, 1735, 8083, 14973, 20891, 0 }; - static ulong[] dim2231Kuo2Init = { 1, 1, 1, 13, 31, 35, 69, 53, 191, 671, 1339, 1677, 4463, 1951, 28129, 0 }; - static ulong[] dim2232Kuo2Init = { 1, 3, 3, 15, 19, 13, 73, 171, 481, 981, 343, 1831, 2967, 1801, 9923, 0 }; - static ulong[] dim2233Kuo2Init = { 1, 1, 7, 7, 9, 29, 57, 113, 425, 705, 673, 3749, 1883, 12295, 9669, 0 }; - static ulong[] dim2234Kuo2Init = { 1, 3, 1, 3, 13, 35, 23, 35, 303, 281, 773, 3053, 3841, 7943, 5023, 0 }; - static ulong[] dim2235Kuo2Init = { 1, 1, 7, 15, 11, 27, 85, 163, 349, 289, 297, 3043, 6469, 12029, 8087, 0 }; - static ulong[] dim2236Kuo2Init = { 1, 1, 5, 15, 27, 47, 3, 51, 87, 583, 893, 971, 6859, 7459, 6931, 0 }; - static ulong[] dim2237Kuo2Init = { 1, 3, 3, 15, 21, 57, 65, 141, 129, 345, 745, 2281, 4753, 2899, 1891, 0 }; - static ulong[] dim2238Kuo2Init = { 1, 1, 1, 11, 7, 3, 87, 127, 133, 243, 241, 557, 6537, 1645, 24843, 0 }; - static ulong[] dim2239Kuo2Init = { 1, 1, 7, 1, 7, 37, 91, 9, 337, 787, 1833, 3259, 1335, 6365, 30259, 0 }; - static ulong[] dim2240Kuo2Init = { 1, 1, 1, 9, 7, 3, 127, 41, 41, 377, 1633, 3031, 4483, 12555, 23921, 0 }; - static ulong[] dim2241Kuo2Init = { 1, 1, 7, 1, 21, 9, 77, 243, 373, 289, 715, 2323, 2549, 8891, 22603, 0 }; - static ulong[] dim2242Kuo2Init = { 1, 1, 1, 5, 19, 53, 81, 83, 111, 593, 1041, 499, 5849, 1261, 9561, 0 }; - static ulong[] dim2243Kuo2Init = { 1, 3, 5, 15, 11, 45, 13, 217, 309, 249, 1597, 2829, 2185, 11919, 22975, 0 }; - static ulong[] dim2244Kuo2Init = { 1, 1, 1, 3, 31, 3, 69, 105, 449, 339, 1705, 551, 1701, 1163, 22551, 0 }; - static ulong[] dim2245Kuo2Init = { 1, 1, 3, 7, 29, 23, 115, 119, 25, 425, 225, 1379, 1443, 9549, 31083, 0 }; - static ulong[] dim2246Kuo2Init = { 1, 1, 7, 11, 31, 37, 121, 29, 367, 171, 1611, 3147, 4887, 15191, 27943, 0 }; - static ulong[] dim2247Kuo2Init = { 1, 1, 5, 1, 25, 11, 39, 137, 251, 557, 1833, 2803, 2081, 819, 12493, 0 }; - static ulong[] dim2248Kuo2Init = { 1, 1, 1, 3, 17, 19, 87, 123, 333, 215, 685, 1235, 2327, 5927, 16909, 0 }; - static ulong[] dim2249Kuo2Init = { 1, 1, 7, 7, 5, 31, 127, 205, 197, 671, 1101, 1767, 7871, 4157, 31301, 0 }; - static ulong[] dim2250Kuo2Init = { 1, 1, 5, 5, 17, 5, 23, 175, 363, 831, 563, 2599, 7081, 11695, 10301, 0 }; - static ulong[] dim2251Kuo2Init = { 1, 3, 3, 1, 21, 55, 97, 163, 443, 533, 1889, 1431, 6671, 14699, 26863, 0 }; - static ulong[] dim2252Kuo2Init = { 1, 3, 5, 15, 27, 15, 7, 215, 7, 557, 819, 3855, 619, 10185, 23715, 0 }; - static ulong[] dim2253Kuo2Init = { 1, 3, 7, 1, 17, 23, 25, 59, 369, 675, 463, 809, 8097, 9263, 8907, 0 }; - static ulong[] dim2254Kuo2Init = { 1, 1, 1, 3, 1, 29, 63, 65, 103, 659, 1883, 1141, 641, 6083, 16237, 0 }; - static ulong[] dim2255Kuo2Init = { 1, 1, 1, 3, 5, 41, 13, 143, 349, 811, 1645, 1871, 3385, 12795, 25105, 0 }; - static ulong[] dim2256Kuo2Init = { 1, 1, 1, 15, 17, 7, 73, 195, 439, 85, 1701, 3989, 1619, 5319, 20593, 0 }; - static ulong[] dim2257Kuo2Init = { 1, 1, 3, 15, 1, 9, 61, 223, 441, 543, 765, 3477, 2569, 6061, 25353, 0 }; - static ulong[] dim2258Kuo2Init = { 1, 1, 3, 11, 29, 63, 9, 149, 307, 705, 871, 2975, 4145, 431, 14483, 0 }; - static ulong[] dim2259Kuo2Init = { 1, 1, 1, 3, 11, 7, 103, 85, 389, 719, 1201, 3139, 2941, 13867, 1915, 0 }; - static ulong[] dim2260Kuo2Init = { 1, 1, 3, 3, 21, 27, 65, 59, 223, 335, 1845, 1315, 3619, 1851, 4313, 0 }; - static ulong[] dim2261Kuo2Init = { 1, 3, 7, 13, 21, 21, 19, 181, 39, 89, 1703, 791, 597, 3349, 14387, 0 }; - static ulong[] dim2262Kuo2Init = { 1, 3, 5, 3, 9, 19, 49, 253, 61, 313, 1763, 629, 1951, 16157, 14435, 0 }; - static ulong[] dim2263Kuo2Init = { 1, 1, 5, 13, 23, 41, 45, 107, 111, 287, 1829, 33, 5433, 7283, 20573, 0 }; - static ulong[] dim2264Kuo2Init = { 1, 3, 3, 5, 17, 43, 117, 55, 275, 763, 1581, 2349, 1219, 16145, 545, 0 }; - static ulong[] dim2265Kuo2Init = { 1, 1, 5, 3, 13, 23, 65, 97, 347, 169, 1371, 2373, 4577, 14667, 5713, 0 }; - static ulong[] dim2266Kuo2Init = { 1, 1, 5, 11, 1, 43, 17, 87, 287, 943, 1257, 3383, 2389, 3349, 11641, 0 }; - static ulong[] dim2267Kuo2Init = { 1, 3, 1, 7, 27, 37, 127, 27, 239, 5, 575, 1811, 7185, 10233, 20519, 0 }; - static ulong[] dim2268Kuo2Init = { 1, 3, 1, 13, 21, 33, 91, 147, 351, 283, 1765, 3497, 3113, 7635, 21229, 0 }; - static ulong[] dim2269Kuo2Init = { 1, 3, 7, 3, 19, 39, 47, 135, 495, 401, 843, 551, 5239, 6525, 32339, 0 }; - static ulong[] dim2270Kuo2Init = { 1, 3, 3, 3, 1, 37, 61, 243, 491, 139, 613, 685, 3027, 8053, 4935, 0 }; - static ulong[] dim2271Kuo2Init = { 1, 1, 7, 1, 13, 43, 25, 117, 43, 161, 747, 3005, 5445, 7559, 31029, 0 }; - static ulong[] dim2272Kuo2Init = { 1, 1, 1, 1, 9, 31, 107, 57, 121, 733, 1813, 2057, 2473, 1769, 14649, 0 }; - static ulong[] dim2273Kuo2Init = { 1, 1, 7, 7, 7, 53, 105, 163, 401, 391, 849, 2359, 6819, 13905, 17267, 0 }; - static ulong[] dim2274Kuo2Init = { 1, 1, 5, 7, 23, 9, 31, 39, 7, 767, 153, 2969, 5539, 6581, 30515, 0 }; - static ulong[] dim2275Kuo2Init = { 1, 3, 7, 5, 3, 63, 73, 167, 485, 837, 403, 193, 2707, 2017, 743, 0 }; - static ulong[] dim2276Kuo2Init = { 1, 1, 5, 15, 17, 59, 115, 115, 463, 203, 607, 343, 577, 6985, 8797, 0 }; - static ulong[] dim2277Kuo2Init = { 1, 1, 7, 3, 19, 61, 33, 245, 337, 105, 597, 807, 1669, 5447, 15173, 0 }; - static ulong[] dim2278Kuo2Init = { 1, 3, 3, 9, 27, 51, 67, 135, 151, 215, 217, 221, 6467, 3693, 4563, 0 }; - static ulong[] dim2279Kuo2Init = { 1, 1, 1, 3, 1, 5, 91, 223, 491, 783, 287, 4067, 6747, 2489, 11513, 0 }; - static ulong[] dim2280Kuo2Init = { 1, 3, 1, 3, 25, 15, 9, 3, 445, 893, 399, 2073, 3715, 2493, 7761, 0 }; - static ulong[] dim2281Kuo2Init = { 1, 3, 1, 11, 5, 41, 121, 107, 15, 547, 1417, 1275, 7255, 14979, 26993, 0 }; - static ulong[] dim2282Kuo2Init = { 1, 1, 5, 5, 29, 41, 115, 195, 305, 887, 335, 3919, 6607, 15783, 21457, 0 }; - static ulong[] dim2283Kuo2Init = { 1, 1, 7, 15, 11, 43, 53, 19, 37, 219, 1905, 1153, 4783, 11817, 11119, 0 }; - static ulong[] dim2284Kuo2Init = { 1, 1, 5, 13, 31, 57, 73, 237, 443, 755, 1141, 793, 8177, 9053, 25949, 0 }; - static ulong[] dim2285Kuo2Init = { 1, 1, 3, 9, 9, 11, 1, 151, 249, 701, 523, 2383, 647, 7979, 28965, 0 }; - static ulong[] dim2286Kuo2Init = { 1, 3, 1, 9, 7, 47, 47, 117, 239, 213, 1747, 3093, 3111, 6689, 22451, 0 }; - static ulong[] dim2287Kuo2Init = { 1, 1, 3, 1, 21, 43, 111, 97, 323, 733, 1051, 3567, 1217, 3731, 15475, 0 }; - static ulong[] dim2288Kuo2Init = { 1, 3, 1, 9, 29, 13, 63, 151, 469, 211, 927, 1893, 7741, 9733, 5777, 0 }; - static ulong[] dim2289Kuo2Init = { 1, 1, 1, 15, 17, 49, 65, 81, 325, 847, 193, 3777, 4979, 1621, 17401, 0 }; - static ulong[] dim2290Kuo2Init = { 1, 3, 3, 15, 27, 31, 37, 185, 339, 731, 1317, 527, 1889, 10609, 27419, 0 }; - static ulong[] dim2291Kuo2Init = { 1, 1, 3, 13, 27, 45, 85, 193, 293, 909, 205, 2245, 2845, 11575, 21997, 0 }; - static ulong[] dim2292Kuo2Init = { 1, 3, 1, 3, 13, 63, 49, 97, 343, 331, 2015, 2117, 6367, 13501, 12029, 0 }; - static ulong[] dim2293Kuo2Init = { 1, 3, 3, 1, 15, 9, 61, 41, 355, 327, 1285, 571, 3437, 10489, 24383, 0 }; - static ulong[] dim2294Kuo2Init = { 1, 1, 7, 13, 23, 13, 7, 127, 329, 323, 2037, 31, 407, 11301, 28027, 0 }; - static ulong[] dim2295Kuo2Init = { 1, 1, 3, 1, 23, 61, 99, 237, 15, 257, 1575, 2077, 6507, 3365, 21885, 0 }; - static ulong[] dim2296Kuo2Init = { 1, 3, 5, 11, 15, 61, 111, 25, 309, 853, 1203, 2943, 4875, 9233, 197, 0 }; - static ulong[] dim2297Kuo2Init = { 1, 3, 3, 7, 5, 15, 17, 97, 213, 991, 867, 2291, 8129, 9381, 787, 0 }; - static ulong[] dim2298Kuo2Init = { 1, 3, 5, 1, 31, 45, 105, 35, 403, 595, 1007, 3633, 5167, 11245, 6643, 0 }; - static ulong[] dim2299Kuo2Init = { 1, 3, 5, 5, 1, 51, 121, 161, 109, 369, 447, 213, 4879, 5639, 7233, 0 }; - static ulong[] dim2300Kuo2Init = { 1, 1, 7, 5, 3, 27, 35, 143, 489, 435, 1483, 3261, 7427, 3105, 5297, 0 }; - static ulong[] dim2301Kuo2Init = { 1, 3, 1, 5, 11, 1, 75, 63, 367, 523, 291, 1429, 5509, 8641, 6847, 0 }; - static ulong[] dim2302Kuo2Init = { 1, 1, 7, 13, 5, 59, 69, 81, 359, 905, 723, 3449, 3961, 16231, 19789, 0 }; - static ulong[] dim2303Kuo2Init = { 1, 1, 7, 7, 13, 53, 119, 129, 87, 325, 415, 3313, 6045, 5293, 21325, 0 }; - static ulong[] dim2304Kuo2Init = { 1, 1, 3, 3, 3, 45, 73, 109, 337, 185, 781, 3277, 2575, 15999, 8309, 0 }; - static ulong[] dim2305Kuo2Init = { 1, 1, 3, 15, 15, 59, 35, 77, 441, 635, 627, 183, 4599, 8749, 24149, 0 }; - static ulong[] dim2306Kuo2Init = { 1, 3, 3, 7, 23, 51, 31, 23, 367, 473, 27, 1021, 2587, 3063, 32563, 0 }; - static ulong[] dim2307Kuo2Init = { 1, 1, 7, 5, 9, 57, 45, 147, 95, 233, 1349, 1497, 7103, 4049, 905, 0 }; - static ulong[] dim2308Kuo2Init = { 1, 1, 7, 9, 9, 21, 89, 59, 379, 467, 1619, 809, 3947, 1715, 9841, 0 }; - static ulong[] dim2309Kuo2Init = { 1, 3, 5, 9, 23, 41, 43, 213, 429, 825, 279, 1117, 659, 13157, 3977, 0 }; - static ulong[] dim2310Kuo2Init = { 1, 1, 3, 15, 1, 57, 79, 87, 285, 693, 1947, 3417, 4241, 8595, 18075, 0 }; - static ulong[] dim2311Kuo2Init = { 1, 1, 1, 1, 11, 19, 9, 79, 407, 475, 655, 2925, 2919, 6343, 19637, 0 }; - static ulong[] dim2312Kuo2Init = { 1, 3, 3, 13, 1, 41, 107, 185, 29, 169, 915, 3535, 3543, 8015, 7097, 0 }; - static ulong[] dim2313Kuo2Init = { 1, 1, 3, 11, 29, 1, 25, 199, 129, 471, 1335, 3413, 7373, 9881, 32595, 0 }; - static ulong[] dim2314Kuo2Init = { 1, 3, 3, 1, 25, 13, 95, 23, 145, 775, 1873, 2347, 323, 10021, 20551, 0 }; - static ulong[] dim2315Kuo2Init = { 1, 3, 3, 15, 3, 35, 25, 79, 279, 251, 245, 2917, 1147, 9525, 9473, 0 }; - static ulong[] dim2316Kuo2Init = { 1, 3, 3, 11, 25, 35, 115, 13, 191, 447, 1041, 3437, 5941, 903, 26727, 0 }; - static ulong[] dim2317Kuo2Init = { 1, 3, 5, 15, 27, 49, 29, 169, 167, 685, 931, 1705, 4513, 16217, 8545, 0 }; - static ulong[] dim2318Kuo2Init = { 1, 3, 5, 3, 5, 55, 55, 113, 129, 491, 1583, 2103, 2233, 12669, 2809, 0 }; - static ulong[] dim2319Kuo2Init = { 1, 1, 1, 7, 7, 57, 47, 43, 91, 415, 1903, 1067, 4281, 16095, 19919, 0 }; - static ulong[] dim2320Kuo2Init = { 1, 3, 7, 7, 29, 7, 65, 19, 119, 473, 493, 2861, 7765, 15057, 13809, 0 }; - static ulong[] dim2321Kuo2Init = { 1, 1, 5, 9, 3, 49, 83, 73, 135, 971, 1233, 3623, 7351, 15255, 29921, 0 }; - static ulong[] dim2322Kuo2Init = { 1, 3, 3, 11, 29, 53, 5, 57, 41, 215, 477, 1851, 2219, 16289, 23801, 0 }; - static ulong[] dim2323Kuo2Init = { 1, 1, 3, 7, 9, 29, 55, 37, 415, 537, 1459, 431, 4559, 5569, 2031, 0 }; - static ulong[] dim2324Kuo2Init = { 1, 1, 5, 1, 5, 15, 47, 159, 369, 677, 691, 2647, 6243, 15909, 17725, 0 }; - static ulong[] dim2325Kuo2Init = { 1, 1, 5, 9, 13, 43, 45, 167, 503, 939, 1609, 1123, 2799, 3903, 27007, 0 }; - static ulong[] dim2326Kuo2Init = { 1, 3, 1, 13, 19, 43, 95, 247, 475, 193, 1513, 885, 5391, 7041, 13473, 0 }; - static ulong[] dim2327Kuo2Init = { 1, 1, 7, 13, 25, 61, 3, 237, 473, 671, 101, 1129, 787, 14697, 909, 0 }; - static ulong[] dim2328Kuo2Init = { 1, 1, 7, 15, 25, 3, 53, 81, 147, 27, 1691, 2093, 2627, 9523, 16021, 0 }; - static ulong[] dim2329Kuo2Init = { 1, 1, 7, 15, 11, 17, 35, 39, 187, 119, 541, 485, 3997, 16067, 12707, 0 }; - static ulong[] dim2330Kuo2Init = { 1, 3, 7, 9, 17, 5, 57, 31, 75, 637, 1521, 3435, 387, 9325, 8165, 0 }; - static ulong[] dim2331Kuo2Init = { 1, 1, 7, 3, 17, 33, 65, 55, 193, 55, 777, 151, 7605, 6927, 22731, 0 }; - static ulong[] dim2332Kuo2Init = { 1, 1, 3, 15, 9, 21, 33, 29, 395, 179, 445, 895, 203, 14665, 28945, 0 }; - static ulong[] dim2333Kuo2Init = { 1, 3, 3, 11, 25, 63, 35, 51, 261, 83, 1227, 2897, 8157, 11703, 21067, 0 }; - static ulong[] dim2334Kuo2Init = { 1, 1, 5, 11, 15, 59, 1, 115, 225, 427, 397, 2113, 8117, 9387, 15817, 0 }; - static ulong[] dim2335Kuo2Init = { 1, 1, 5, 3, 25, 23, 15, 3, 227, 341, 449, 217, 3583, 5617, 5215, 0 }; - static ulong[] dim2336Kuo2Init = { 1, 3, 1, 9, 15, 61, 29, 241, 245, 857, 217, 1253, 2643, 435, 11991, 0 }; - static ulong[] dim2337Kuo2Init = { 1, 1, 7, 7, 27, 17, 89, 123, 121, 97, 1749, 3341, 2279, 1067, 28845, 0 }; - static ulong[] dim2338Kuo2Init = { 1, 1, 1, 13, 17, 21, 27, 153, 135, 831, 361, 3487, 7221, 9343, 26523, 0 }; - static ulong[] dim2339Kuo2Init = { 1, 1, 7, 15, 11, 59, 115, 103, 425, 221, 1485, 3471, 773, 14989, 1193, 0 }; - static ulong[] dim2340Kuo2Init = { 1, 1, 7, 11, 1, 19, 113, 115, 149, 429, 1695, 409, 2343, 11843, 16319, 0 }; - static ulong[] dim2341Kuo2Init = { 1, 1, 1, 9, 29, 5, 37, 29, 197, 331, 2033, 1319, 5667, 1311, 3563, 0 }; - static ulong[] dim2342Kuo2Init = { 1, 1, 1, 11, 13, 7, 73, 25, 391, 245, 1447, 4001, 7059, 3091, 27423, 0 }; - static ulong[] dim2343Kuo2Init = { 1, 1, 5, 13, 21, 1, 125, 201, 103, 349, 1123, 2067, 7007, 12927, 27169, 0 }; - static ulong[] dim2344Kuo2Init = { 1, 3, 3, 5, 25, 49, 73, 31, 55, 659, 1407, 3433, 6513, 151, 18409, 0 }; - static ulong[] dim2345Kuo2Init = { 1, 1, 5, 13, 5, 19, 57, 73, 197, 69, 1477, 2763, 5691, 6639, 23613, 0 }; - static ulong[] dim2346Kuo2Init = { 1, 3, 5, 5, 17, 47, 49, 77, 275, 341, 2017, 3257, 111, 925, 549, 0 }; - static ulong[] dim2347Kuo2Init = { 1, 1, 7, 9, 29, 7, 27, 195, 411, 435, 1689, 1537, 3381, 11521, 4505, 0 }; - static ulong[] dim2348Kuo2Init = { 1, 1, 1, 15, 13, 23, 97, 189, 285, 351, 1371, 3161, 2337, 5239, 31675, 0 }; - static ulong[] dim2349Kuo2Init = { 1, 1, 5, 3, 27, 57, 105, 197, 423, 109, 1967, 3363, 1925, 14261, 13569, 0 }; - static ulong[] dim2350Kuo2Init = { 1, 1, 3, 15, 21, 15, 7, 45, 411, 905, 1323, 3225, 5867, 2281, 13213, 0 }; - static ulong[] dim2351Kuo2Init = { 1, 3, 7, 9, 29, 51, 41, 97, 393, 381, 1765, 1159, 965, 6013, 12541, 0 }; - static ulong[] dim2352Kuo2Init = { 1, 1, 7, 5, 13, 35, 107, 231, 135, 745, 259, 2999, 1291, 14025, 2065, 0 }; - static ulong[] dim2353Kuo2Init = { 1, 3, 5, 13, 13, 29, 65, 91, 101, 469, 1337, 2717, 1781, 10019, 23097, 0 }; - static ulong[] dim2354Kuo2Init = { 1, 3, 3, 9, 3, 11, 23, 253, 175, 35, 1651, 3713, 3575, 4837, 10385, 0 }; - static ulong[] dim2355Kuo2Init = { 1, 3, 1, 11, 13, 57, 33, 39, 55, 717, 679, 2417, 3665, 7753, 27659, 0 }; - static ulong[] dim2356Kuo2Init = { 1, 3, 1, 15, 25, 9, 93, 205, 369, 567, 1525, 3797, 6047, 407, 2155, 0 }; - static ulong[] dim2357Kuo2Init = { 1, 3, 7, 3, 5, 47, 15, 227, 325, 837, 1849, 3577, 1427, 5629, 17023, 0 }; - static ulong[] dim2358Kuo2Init = { 1, 3, 5, 7, 17, 23, 43, 231, 23, 95, 423, 2225, 8051, 6775, 4087, 0 }; - static ulong[] dim2359Kuo2Init = { 1, 1, 3, 15, 11, 45, 87, 213, 187, 159, 377, 3269, 2393, 7587, 8027, 0 }; - static ulong[] dim2360Kuo2Init = { 1, 1, 5, 3, 5, 25, 115, 19, 229, 13, 935, 3269, 3877, 8081, 20583, 0 }; - static ulong[] dim2361Kuo2Init = { 1, 3, 3, 15, 31, 47, 21, 179, 503, 43, 915, 2987, 323, 15843, 18869, 0 }; - static ulong[] dim2362Kuo2Init = { 1, 1, 7, 7, 25, 9, 27, 169, 431, 495, 65, 3999, 4363, 8677, 12049, 0 }; - static ulong[] dim2363Kuo2Init = { 1, 3, 5, 13, 17, 37, 123, 197, 185, 501, 1471, 149, 4649, 2337, 10279, 0 }; - static ulong[] dim2364Kuo2Init = { 1, 1, 7, 13, 11, 11, 3, 103, 43, 97, 349, 3515, 2621, 11587, 26495, 0 }; - static ulong[] dim2365Kuo2Init = { 1, 1, 1, 5, 3, 19, 99, 135, 355, 265, 1719, 2533, 4313, 11301, 18415, 0 }; - static ulong[] dim2366Kuo2Init = { 1, 3, 7, 9, 1, 55, 115, 251, 293, 903, 931, 3687, 5019, 14277, 589, 0 }; - static ulong[] dim2367Kuo2Init = { 1, 1, 3, 5, 31, 5, 123, 179, 51, 135, 9, 2779, 8143, 10033, 31473, 0 }; - static ulong[] dim2368Kuo2Init = { 1, 3, 1, 5, 3, 39, 87, 235, 289, 907, 1211, 453, 611, 4009, 25787, 0 }; - static ulong[] dim2369Kuo2Init = { 1, 3, 7, 9, 27, 7, 47, 123, 333, 713, 1349, 1345, 1641, 5935, 19127, 0 }; - static ulong[] dim2370Kuo2Init = { 1, 1, 5, 11, 13, 17, 47, 235, 329, 955, 1761, 1957, 3611, 9705, 20307, 0 }; - static ulong[] dim2371Kuo2Init = { 1, 1, 7, 15, 15, 59, 45, 17, 57, 871, 407, 943, 1881, 12929, 2181, 0 }; - static ulong[] dim2372Kuo2Init = { 1, 1, 7, 1, 7, 43, 41, 193, 29, 675, 1449, 2121, 1681, 13951, 21659, 0 }; - static ulong[] dim2373Kuo2Init = { 1, 1, 5, 3, 21, 53, 63, 75, 7, 793, 245, 349, 4801, 4057, 13269, 0 }; - static ulong[] dim2374Kuo2Init = { 1, 1, 3, 13, 23, 9, 109, 167, 165, 573, 685, 129, 1781, 10331, 9429, 0 }; - static ulong[] dim2375Kuo2Init = { 1, 3, 3, 15, 29, 43, 109, 25, 461, 991, 1509, 39, 6959, 13245, 18505, 0 }; - static ulong[] dim2376Kuo2Init = { 1, 3, 1, 7, 25, 43, 57, 61, 399, 787, 1479, 1613, 4295, 4189, 1371, 0 }; - static ulong[] dim2377Kuo2Init = { 1, 3, 3, 13, 27, 57, 49, 139, 189, 683, 115, 963, 5833, 3249, 28785, 0 }; - static ulong[] dim2378Kuo2Init = { 1, 3, 5, 1, 3, 29, 41, 49, 341, 299, 1195, 57, 5791, 4409, 17733, 0 }; - static ulong[] dim2379Kuo2Init = { 1, 1, 5, 7, 11, 21, 115, 145, 207, 41, 1531, 1897, 2627, 3653, 267, 0 }; - static ulong[] dim2380Kuo2Init = { 1, 3, 3, 9, 1, 3, 5, 79, 449, 281, 1711, 2863, 6267, 14863, 29957, 0 }; - static ulong[] dim2381Kuo2Init = { 1, 3, 1, 3, 15, 63, 127, 123, 457, 523, 1409, 2709, 4543, 13071, 17751, 0 }; - static ulong[] dim2382Kuo2Init = { 1, 3, 1, 3, 7, 61, 21, 139, 481, 747, 107, 1041, 359, 7683, 30327, 0 }; - static ulong[] dim2383Kuo2Init = { 1, 3, 3, 7, 3, 25, 7, 113, 39, 853, 1461, 2655, 2601, 7619, 2923, 0 }; - static ulong[] dim2384Kuo2Init = { 1, 3, 3, 1, 19, 25, 5, 27, 439, 407, 1281, 2487, 2275, 8793, 119, 0 }; - static ulong[] dim2385Kuo2Init = { 1, 3, 3, 1, 11, 37, 55, 131, 227, 79, 117, 2367, 1495, 15873, 24341, 0 }; - static ulong[] dim2386Kuo2Init = { 1, 3, 1, 1, 11, 21, 35, 167, 413, 645, 1139, 2535, 8167, 5937, 29047, 0 }; - static ulong[] dim2387Kuo2Init = { 1, 3, 7, 1, 5, 43, 31, 5, 419, 577, 1333, 1599, 3745, 10219, 27501, 0 }; - static ulong[] dim2388Kuo2Init = { 1, 3, 1, 13, 21, 35, 115, 105, 187, 567, 1303, 1637, 3681, 14089, 12705, 0 }; - static ulong[] dim2389Kuo2Init = { 1, 1, 3, 15, 19, 61, 65, 115, 395, 501, 1015, 2117, 7647, 3077, 15265, 0 }; - static ulong[] dim2390Kuo2Init = { 1, 3, 1, 1, 29, 11, 21, 177, 15, 193, 1177, 1225, 6251, 9983, 12599, 0 }; - static ulong[] dim2391Kuo2Init = { 1, 1, 1, 5, 5, 27, 27, 249, 197, 125, 571, 277, 4659, 14943, 19805, 0 }; - static ulong[] dim2392Kuo2Init = { 1, 3, 3, 7, 27, 37, 75, 235, 249, 191, 1123, 1355, 4249, 14971, 11349, 0 }; - static ulong[] dim2393Kuo2Init = { 1, 1, 5, 9, 31, 19, 7, 91, 87, 515, 293, 1289, 2495, 11311, 3939, 0 }; - static ulong[] dim2394Kuo2Init = { 1, 1, 5, 15, 15, 51, 43, 231, 401, 557, 689, 1103, 457, 3493, 22193, 0 }; - static ulong[] dim2395Kuo2Init = { 1, 3, 5, 9, 25, 39, 125, 91, 373, 331, 39, 35, 2397, 5043, 32061, 0 }; - static ulong[] dim2396Kuo2Init = { 1, 1, 3, 11, 13, 37, 61, 27, 349, 377, 1589, 3711, 6551, 4795, 5507, 0 }; - static ulong[] dim2397Kuo2Init = { 1, 3, 5, 7, 25, 49, 107, 189, 371, 363, 1011, 2133, 6923, 2441, 8295, 0 }; - static ulong[] dim2398Kuo2Init = { 1, 1, 3, 11, 3, 11, 27, 9, 193, 979, 867, 3085, 3783, 14851, 11565, 0 }; - static ulong[] dim2399Kuo2Init = { 1, 1, 3, 1, 1, 55, 17, 239, 351, 373, 939, 2115, 3697, 7881, 6603, 0 }; - static ulong[] dim2400Kuo2Init = { 1, 3, 1, 7, 23, 17, 81, 143, 497, 875, 939, 3193, 7023, 3327, 29327, 0 }; - static ulong[] dim2401Kuo2Init = { 1, 3, 7, 13, 27, 61, 1, 127, 369, 471, 1511, 2227, 565, 4121, 11155, 0 }; - static ulong[] dim2402Kuo2Init = { 1, 3, 3, 5, 5, 53, 77, 185, 11, 801, 1289, 975, 5191, 3733, 18489, 0 }; - static ulong[] dim2403Kuo2Init = { 1, 3, 1, 7, 19, 19, 67, 9, 121, 473, 377, 3771, 7561, 5751, 26295, 0 }; - static ulong[] dim2404Kuo2Init = { 1, 3, 1, 5, 19, 41, 7, 227, 465, 803, 1979, 281, 1337, 7973, 20341, 0 }; - static ulong[] dim2405Kuo2Init = { 1, 1, 1, 5, 9, 5, 123, 45, 65, 801, 373, 2093, 1473, 14503, 1401, 0 }; - static ulong[] dim2406Kuo2Init = { 1, 1, 3, 9, 29, 39, 123, 17, 253, 649, 1755, 4081, 3415, 8805, 28635, 0 }; - static ulong[] dim2407Kuo2Init = { 1, 3, 1, 1, 23, 7, 57, 163, 93, 829, 93, 1767, 1073, 14825, 21505, 0 }; - static ulong[] dim2408Kuo2Init = { 1, 1, 7, 13, 21, 59, 59, 229, 175, 485, 621, 3785, 4949, 12281, 14569, 0 }; - static ulong[] dim2409Kuo2Init = { 1, 3, 5, 13, 7, 51, 123, 221, 119, 61, 1271, 1857, 3505, 14413, 20975, 0 }; - static ulong[] dim2410Kuo2Init = { 1, 3, 7, 5, 17, 51, 67, 123, 121, 379, 605, 3361, 5557, 9127, 15251, 0 }; - static ulong[] dim2411Kuo2Init = { 1, 3, 7, 9, 27, 11, 33, 33, 439, 347, 1305, 11, 6839, 493, 771, 0 }; - static ulong[] dim2412Kuo2Init = { 1, 3, 5, 15, 5, 13, 7, 131, 129, 865, 1115, 2651, 1567, 783, 15073, 0 }; - static ulong[] dim2413Kuo2Init = { 1, 1, 3, 11, 11, 13, 95, 115, 361, 1009, 413, 2671, 6267, 5393, 18963, 0 }; - static ulong[] dim2414Kuo2Init = { 1, 3, 1, 9, 27, 11, 33, 183, 343, 113, 1323, 3197, 3889, 8533, 31493, 0 }; - static ulong[] dim2415Kuo2Init = { 1, 3, 3, 11, 11, 21, 93, 35, 177, 133, 539, 679, 6263, 8619, 2751, 0 }; - static ulong[] dim2416Kuo2Init = { 1, 1, 3, 1, 27, 31, 21, 157, 365, 635, 1279, 575, 2245, 11597, 3899, 0 }; - static ulong[] dim2417Kuo2Init = { 1, 3, 1, 5, 7, 45, 15, 237, 191, 541, 1631, 1459, 1973, 15333, 30419, 0 }; - static ulong[] dim2418Kuo2Init = { 1, 3, 1, 13, 3, 47, 103, 101, 423, 739, 947, 3225, 783, 14771, 20183, 0 }; - static ulong[] dim2419Kuo2Init = { 1, 3, 1, 5, 23, 19, 21, 245, 341, 907, 745, 1913, 1545, 7801, 9995, 0 }; - static ulong[] dim2420Kuo2Init = { 1, 3, 1, 3, 7, 47, 55, 15, 193, 123, 73, 427, 6415, 6611, 6317, 0 }; - static ulong[] dim2421Kuo2Init = { 1, 1, 1, 7, 3, 17, 27, 5, 295, 453, 1503, 2327, 4209, 3663, 16843, 0 }; - static ulong[] dim2422Kuo2Init = { 1, 1, 1, 3, 25, 19, 41, 161, 333, 153, 999, 1129, 103, 9471, 12707, 0 }; - static ulong[] dim2423Kuo2Init = { 1, 3, 3, 3, 21, 37, 73, 159, 179, 913, 691, 755, 3033, 1999, 15459, 0 }; - static ulong[] dim2424Kuo2Init = { 1, 1, 5, 13, 1, 3, 67, 131, 119, 769, 747, 1047, 6751, 2753, 22611, 0 }; - static ulong[] dim2425Kuo2Init = { 1, 3, 7, 5, 11, 1, 27, 81, 423, 691, 357, 3679, 2467, 15107, 13029, 0 }; - static ulong[] dim2426Kuo2Init = { 1, 3, 5, 9, 21, 21, 109, 69, 319, 283, 1831, 1403, 5531, 14461, 14057, 0 }; - static ulong[] dim2427Kuo2Init = { 1, 3, 7, 13, 21, 33, 77, 149, 495, 361, 401, 3313, 1849, 14009, 5933, 0 }; - static ulong[] dim2428Kuo2Init = { 1, 3, 7, 15, 11, 3, 33, 181, 21, 437, 1843, 3591, 589, 1721, 27495, 0 }; - static ulong[] dim2429Kuo2Init = { 1, 1, 1, 9, 25, 61, 103, 25, 71, 471, 219, 3623, 1517, 15471, 23179, 0 }; - static ulong[] dim2430Kuo2Init = { 1, 1, 7, 1, 7, 59, 99, 143, 387, 231, 241, 1215, 3785, 13543, 27469, 0 }; - static ulong[] dim2431Kuo2Init = { 1, 3, 1, 11, 25, 61, 93, 171, 421, 515, 1761, 1399, 7791, 291, 28455, 0 }; - static ulong[] dim2432Kuo2Init = { 1, 1, 3, 11, 1, 23, 117, 251, 467, 445, 737, 2637, 4183, 8561, 24977, 0 }; - static ulong[] dim2433Kuo2Init = { 1, 3, 5, 11, 11, 35, 111, 209, 415, 485, 1609, 1113, 3329, 15365, 1999, 0 }; - static ulong[] dim2434Kuo2Init = { 1, 1, 3, 15, 19, 17, 43, 67, 191, 711, 395, 921, 2511, 8417, 4071, 0 }; - static ulong[] dim2435Kuo2Init = { 1, 3, 3, 11, 9, 5, 89, 115, 451, 533, 1057, 1835, 2137, 9253, 19217, 0 }; - static ulong[] dim2436Kuo2Init = { 1, 3, 7, 11, 9, 45, 119, 89, 485, 109, 1755, 709, 7729, 14659, 19203, 0 }; - static ulong[] dim2437Kuo2Init = { 1, 1, 3, 7, 11, 7, 107, 113, 305, 431, 481, 2965, 6195, 2369, 14843, 0 }; - static ulong[] dim2438Kuo2Init = { 1, 3, 1, 13, 5, 37, 11, 193, 135, 697, 665, 3085, 4691, 3799, 11915, 0 }; - static ulong[] dim2439Kuo2Init = { 1, 1, 1, 9, 1, 47, 23, 143, 255, 93, 615, 2039, 6591, 14479, 24963, 0 }; - static ulong[] dim2440Kuo2Init = { 1, 3, 3, 11, 15, 11, 75, 57, 151, 29, 1073, 2763, 5613, 15703, 2447, 0 }; - static ulong[] dim2441Kuo2Init = { 1, 1, 5, 9, 19, 15, 79, 113, 359, 997, 1799, 695, 7075, 10091, 15271, 0 }; - static ulong[] dim2442Kuo2Init = { 1, 3, 5, 9, 3, 63, 45, 253, 257, 739, 1759, 317, 1955, 1283, 11127, 0 }; - static ulong[] dim2443Kuo2Init = { 1, 3, 5, 13, 29, 37, 67, 177, 203, 497, 947, 2339, 2401, 9199, 22331, 0 }; - static ulong[] dim2444Kuo2Init = { 1, 1, 1, 5, 23, 15, 67, 131, 213, 21, 1167, 1729, 3297, 337, 12253, 0 }; - static ulong[] dim2445Kuo2Init = { 1, 3, 3, 11, 21, 7, 69, 79, 297, 401, 1491, 1655, 2525, 4871, 17919, 0 }; - static ulong[] dim2446Kuo2Init = { 1, 3, 5, 15, 5, 15, 113, 45, 205, 317, 109, 2793, 4975, 5563, 3649, 0 }; - static ulong[] dim2447Kuo2Init = { 1, 3, 3, 7, 13, 59, 17, 63, 311, 161, 419, 1693, 2937, 8671, 24741, 0 }; - static ulong[] dim2448Kuo2Init = { 1, 1, 5, 3, 17, 21, 103, 105, 117, 211, 941, 385, 6455, 9069, 10147, 0 }; - static ulong[] dim2449Kuo2Init = { 1, 3, 5, 7, 5, 13, 43, 155, 89, 747, 359, 219, 6597, 5175, 24585, 0 }; - static ulong[] dim2450Kuo2Init = { 1, 3, 5, 13, 7, 45, 17, 169, 421, 161, 207, 2033, 4805, 2737, 7799, 0 }; - static ulong[] dim2451Kuo2Init = { 1, 1, 7, 9, 15, 55, 55, 219, 441, 409, 443, 3363, 6895, 16339, 16091, 0 }; - static ulong[] dim2452Kuo2Init = { 1, 1, 3, 5, 3, 23, 17, 217, 93, 799, 1419, 3405, 7911, 15609, 25461, 0 }; - static ulong[] dim2453Kuo2Init = { 1, 1, 1, 5, 29, 19, 17, 97, 319, 743, 1773, 2513, 2395, 1885, 6835, 0 }; - static ulong[] dim2454Kuo2Init = { 1, 3, 3, 3, 25, 41, 79, 191, 175, 319, 1903, 2281, 5709, 2817, 14213, 0 }; - static ulong[] dim2455Kuo2Init = { 1, 3, 5, 9, 21, 55, 9, 51, 223, 519, 225, 2543, 4183, 283, 599, 0 }; - static ulong[] dim2456Kuo2Init = { 1, 1, 1, 15, 23, 39, 21, 171, 167, 739, 1779, 3469, 8121, 7013, 23445, 0 }; - static ulong[] dim2457Kuo2Init = { 1, 3, 3, 9, 9, 5, 55, 253, 43, 397, 927, 237, 4459, 12817, 29563, 0 }; - static ulong[] dim2458Kuo2Init = { 1, 3, 7, 3, 3, 57, 113, 221, 391, 365, 311, 1027, 3369, 7637, 25765, 0 }; - static ulong[] dim2459Kuo2Init = { 1, 3, 3, 1, 19, 3, 91, 161, 421, 961, 1237, 4063, 2573, 483, 3375, 0 }; - static ulong[] dim2460Kuo2Init = { 1, 1, 1, 5, 19, 35, 119, 211, 489, 649, 1233, 447, 3727, 15541, 4769, 0 }; - static ulong[] dim2461Kuo2Init = { 1, 3, 7, 15, 7, 1, 15, 103, 81, 59, 1953, 3729, 6451, 15051, 17421, 0 }; - static ulong[] dim2462Kuo2Init = { 1, 1, 3, 11, 11, 41, 73, 63, 485, 47, 585, 3503, 4787, 12445, 8513, 0 }; - static ulong[] dim2463Kuo2Init = { 1, 1, 5, 1, 29, 35, 37, 99, 443, 171, 1455, 1705, 5587, 8791, 6269, 0 }; - static ulong[] dim2464Kuo2Init = { 1, 3, 3, 9, 19, 23, 103, 19, 307, 615, 2037, 3289, 1453, 12955, 28069, 0 }; - static ulong[] dim2465Kuo2Init = { 1, 3, 7, 5, 21, 57, 89, 29, 419, 681, 1413, 3375, 7341, 14825, 18251, 0 }; - static ulong[] dim2466Kuo2Init = { 1, 3, 5, 11, 21, 49, 67, 69, 47, 33, 449, 1831, 1125, 1011, 16223, 0 }; - static ulong[] dim2467Kuo2Init = { 1, 1, 3, 5, 17, 11, 67, 237, 299, 843, 1177, 1825, 1109, 12157, 9347, 0 }; - static ulong[] dim2468Kuo2Init = { 1, 3, 3, 9, 21, 63, 47, 239, 219, 319, 1505, 393, 143, 5009, 9017, 0 }; - static ulong[] dim2469Kuo2Init = { 1, 3, 5, 11, 1, 25, 21, 1, 15, 947, 1533, 1201, 3929, 7943, 9335, 0 }; - static ulong[] dim2470Kuo2Init = { 1, 1, 1, 15, 29, 45, 29, 119, 419, 793, 345, 789, 6415, 5481, 31111, 0 }; - static ulong[] dim2471Kuo2Init = { 1, 1, 1, 1, 19, 59, 3, 199, 247, 905, 1347, 4021, 1913, 15315, 15265, 0 }; - static ulong[] dim2472Kuo2Init = { 1, 3, 3, 7, 23, 63, 1, 87, 455, 1013, 789, 603, 7027, 11527, 17571, 0 }; - static ulong[] dim2473Kuo2Init = { 1, 3, 3, 15, 13, 27, 95, 61, 343, 201, 997, 2153, 3239, 2475, 9827, 0 }; - static ulong[] dim2474Kuo2Init = { 1, 3, 3, 1, 29, 49, 77, 245, 167, 873, 1467, 2475, 3951, 10253, 8345, 0 }; - static ulong[] dim2475Kuo2Init = { 1, 1, 1, 15, 5, 41, 71, 81, 491, 971, 1955, 1901, 4383, 13961, 3745, 0 }; - static ulong[] dim2476Kuo2Init = { 1, 1, 1, 7, 21, 31, 11, 247, 47, 251, 509, 739, 2745, 14531, 19633, 0 }; - static ulong[] dim2477Kuo2Init = { 1, 1, 7, 13, 31, 47, 105, 167, 443, 623, 503, 3283, 1935, 2627, 19807, 0 }; - static ulong[] dim2478Kuo2Init = { 1, 1, 7, 3, 21, 9, 67, 39, 263, 395, 407, 3813, 5033, 14647, 11963, 0 }; - static ulong[] dim2479Kuo2Init = { 1, 1, 1, 9, 3, 29, 9, 101, 313, 861, 529, 1171, 7943, 13701, 16497, 0 }; - static ulong[] dim2480Kuo2Init = { 1, 1, 5, 15, 9, 3, 29, 53, 379, 721, 1777, 2767, 7591, 8923, 16909, 0 }; - static ulong[] dim2481Kuo2Init = { 1, 1, 3, 9, 19, 7, 103, 189, 325, 995, 1419, 333, 4053, 10441, 1287, 0 }; - static ulong[] dim2482Kuo2Init = { 1, 1, 7, 1, 1, 1, 53, 31, 425, 477, 695, 389, 6523, 7565, 95, 0 }; - static ulong[] dim2483Kuo2Init = { 1, 1, 7, 15, 1, 5, 75, 211, 487, 641, 287, 3709, 2257, 12017, 31921, 0 }; - static ulong[] dim2484Kuo2Init = { 1, 3, 5, 7, 31, 7, 33, 177, 349, 257, 1383, 303, 469, 10941, 16211, 0 }; - static ulong[] dim2485Kuo2Init = { 1, 1, 5, 1, 7, 21, 89, 229, 237, 447, 1805, 3271, 7073, 3401, 7143, 0 }; - static ulong[] dim2486Kuo2Init = { 1, 3, 1, 7, 11, 35, 127, 139, 497, 629, 543, 77, 2505, 8781, 30445, 0 }; - static ulong[] dim2487Kuo2Init = { 1, 1, 7, 13, 1, 27, 59, 125, 399, 37, 597, 431, 4531, 7525, 2629, 0 }; - static ulong[] dim2488Kuo2Init = { 1, 3, 3, 1, 25, 27, 75, 221, 269, 587, 669, 1807, 5437, 12715, 22419, 0 }; - static ulong[] dim2489Kuo2Init = { 1, 1, 5, 7, 31, 29, 7, 135, 493, 1011, 1273, 3899, 6069, 9657, 21375, 0 }; - static ulong[] dim2490Kuo2Init = { 1, 3, 5, 7, 3, 13, 123, 39, 37, 397, 1023, 2733, 2275, 8415, 12011, 0 }; - static ulong[] dim2491Kuo2Init = { 1, 1, 5, 3, 1, 63, 115, 191, 159, 283, 7, 1073, 5609, 13113, 1755, 0 }; - static ulong[] dim2492Kuo2Init = { 1, 1, 3, 5, 11, 35, 83, 91, 315, 823, 1961, 1023, 4191, 1013, 24451, 0 }; - static ulong[] dim2493Kuo2Init = { 1, 1, 3, 15, 31, 13, 121, 213, 289, 763, 297, 3405, 4987, 13713, 16853, 0 }; - static ulong[] dim2494Kuo2Init = { 1, 3, 1, 3, 9, 57, 53, 171, 203, 71, 1973, 3555, 5079, 16173, 6399, 0 }; - static ulong[] dim2495Kuo2Init = { 1, 1, 3, 7, 21, 51, 105, 237, 491, 465, 597, 3055, 1657, 131, 19281, 0 }; - static ulong[] dim2496Kuo2Init = { 1, 1, 7, 15, 15, 41, 1, 61, 3, 879, 1985, 651, 3945, 6979, 793, 0 }; - static ulong[] dim2497Kuo2Init = { 1, 1, 1, 3, 15, 45, 51, 23, 1, 265, 1345, 3967, 1419, 247, 9225, 0 }; - static ulong[] dim2498Kuo2Init = { 1, 1, 5, 5, 19, 31, 107, 73, 331, 135, 1645, 3465, 6809, 12793, 15589, 0 }; - static ulong[] dim2499Kuo2Init = { 1, 1, 1, 1, 29, 47, 103, 133, 15, 113, 717, 891, 1967, 6063, 24975, 0 }; - static ulong[] dim2500Kuo2Init = { 1, 1, 3, 1, 17, 39, 3, 103, 373, 379, 267, 131, 473, 10475, 18595, 0 }; - static ulong[] dim2501Kuo2Init = { 1, 1, 3, 3, 27, 51, 17, 227, 425, 29, 969, 1515, 7045, 5869, 2031, 0 }; - static ulong[] dim2502Kuo2Init = { 1, 3, 7, 5, 17, 59, 69, 21, 119, 359, 1805, 1225, 1969, 14601, 7175, 0 }; - static ulong[] dim2503Kuo2Init = { 1, 3, 7, 9, 5, 23, 89, 89, 269, 159, 2017, 269, 4247, 14369, 4413, 0 }; - static ulong[] dim2504Kuo2Init = { 1, 1, 7, 1, 19, 35, 67, 243, 71, 653, 1673, 647, 1171, 16167, 15223, 0 }; - static ulong[] dim2505Kuo2Init = { 1, 1, 7, 7, 19, 37, 27, 69, 253, 233, 933, 649, 5449, 10651, 24709, 0 }; - static ulong[] dim2506Kuo2Init = { 1, 1, 5, 15, 13, 39, 113, 253, 351, 281, 309, 2351, 2225, 14121, 24059, 0 }; - static ulong[] dim2507Kuo2Init = { 1, 3, 1, 9, 13, 43, 115, 137, 107, 921, 37, 1743, 183, 5037, 4649, 0 }; - static ulong[] dim2508Kuo2Init = { 1, 1, 5, 15, 23, 11, 121, 161, 337, 155, 1053, 2907, 1163, 12929, 9065, 0 }; - static ulong[] dim2509Kuo2Init = { 1, 1, 3, 1, 1, 23, 85, 253, 245, 359, 1881, 581, 381, 15877, 15781, 0 }; - static ulong[] dim2510Kuo2Init = { 1, 3, 5, 11, 17, 49, 33, 133, 247, 339, 969, 3347, 1791, 16115, 10821, 0 }; - static ulong[] dim2511Kuo2Init = { 1, 3, 1, 9, 31, 41, 31, 103, 79, 339, 1311, 2609, 7455, 4543, 14765, 0 }; - static ulong[] dim2512Kuo2Init = { 1, 3, 7, 13, 13, 25, 75, 219, 443, 543, 9, 1101, 6833, 2091, 20729, 0 }; - static ulong[] dim2513Kuo2Init = { 1, 1, 3, 9, 3, 51, 125, 137, 107, 123, 1113, 3735, 655, 6897, 32047, 0 }; - static ulong[] dim2514Kuo2Init = { 1, 1, 3, 1, 17, 49, 31, 87, 399, 405, 1497, 1199, 6135, 6889, 23913, 0 }; - static ulong[] dim2515Kuo2Init = { 1, 1, 1, 13, 17, 59, 87, 153, 183, 539, 1231, 569, 1877, 11605, 9301, 0 }; - static ulong[] dim2516Kuo2Init = { 1, 3, 1, 9, 15, 57, 41, 247, 107, 1019, 1423, 49, 3093, 1667, 28241, 0 }; - static ulong[] dim2517Kuo2Init = { 1, 1, 1, 1, 19, 9, 41, 79, 383, 83, 1091, 457, 7245, 3639, 24411, 0 }; - static ulong[] dim2518Kuo2Init = { 1, 3, 7, 11, 31, 23, 71, 157, 327, 973, 39, 1303, 3519, 6071, 19297, 0 }; - static ulong[] dim2519Kuo2Init = { 1, 1, 7, 13, 27, 17, 105, 245, 83, 825, 33, 2331, 6469, 5547, 5409, 0 }; - static ulong[] dim2520Kuo2Init = { 1, 3, 1, 9, 21, 1, 105, 161, 269, 767, 2039, 941, 5063, 2763, 31333, 0 }; - static ulong[] dim2521Kuo2Init = { 1, 3, 1, 1, 17, 33, 37, 185, 505, 979, 239, 3001, 1441, 7803, 23377, 0 }; - static ulong[] dim2522Kuo2Init = { 1, 1, 3, 3, 23, 5, 63, 249, 409, 501, 1177, 655, 5109, 309, 3791, 0 }; - static ulong[] dim2523Kuo2Init = { 1, 1, 5, 1, 11, 37, 67, 5, 399, 479, 1119, 295, 2343, 11141, 28209, 0 }; - static ulong[] dim2524Kuo2Init = { 1, 1, 5, 11, 3, 17, 75, 93, 69, 957, 1851, 2297, 6757, 9401, 15847, 0 }; - static ulong[] dim2525Kuo2Init = { 1, 1, 3, 9, 5, 39, 75, 143, 235, 411, 1309, 1327, 863, 5579, 5153, 0 }; - static ulong[] dim2526Kuo2Init = { 1, 1, 7, 13, 23, 3, 39, 7, 257, 941, 1441, 2931, 1651, 4669, 16193, 0 }; - static ulong[] dim2527Kuo2Init = { 1, 1, 1, 15, 27, 43, 51, 197, 369, 531, 397, 387, 3021, 8885, 21943, 0 }; - static ulong[] dim2528Kuo2Init = { 1, 1, 5, 11, 25, 49, 9, 227, 501, 687, 131, 2899, 7175, 11359, 19997, 0 }; - static ulong[] dim2529Kuo2Init = { 1, 3, 3, 9, 23, 1, 51, 53, 437, 331, 1503, 3345, 5909, 439, 4771, 0 }; - static ulong[] dim2530Kuo2Init = { 1, 3, 1, 7, 13, 13, 101, 71, 345, 675, 653, 2297, 1099, 11115, 28917, 0 }; - static ulong[] dim2531Kuo2Init = { 1, 1, 3, 5, 5, 23, 69, 155, 133, 527, 1443, 1099, 2395, 2213, 16533, 0 }; - static ulong[] dim2532Kuo2Init = { 1, 1, 7, 7, 9, 37, 75, 17, 397, 919, 1223, 491, 4719, 3915, 30101, 0 }; - static ulong[] dim2533Kuo2Init = { 1, 3, 1, 7, 7, 51, 105, 31, 5, 149, 1275, 1381, 1963, 14737, 30975, 0 }; - static ulong[] dim2534Kuo2Init = { 1, 1, 7, 5, 1, 51, 49, 21, 371, 293, 159, 3681, 7979, 15611, 255, 0 }; - static ulong[] dim2535Kuo2Init = { 1, 1, 1, 7, 27, 53, 51, 135, 181, 419, 757, 2913, 941, 5863, 19619, 0 }; - static ulong[] dim2536Kuo2Init = { 1, 1, 7, 5, 19, 1, 115, 113, 29, 355, 1203, 279, 7967, 12419, 1003, 0 }; - static ulong[] dim2537Kuo2Init = { 1, 1, 1, 11, 1, 63, 109, 215, 285, 801, 1995, 3771, 4113, 11973, 16507, 0 }; - static ulong[] dim2538Kuo2Init = { 1, 3, 3, 9, 19, 55, 107, 139, 95, 139, 1595, 929, 7023, 15245, 30163, 0 }; - static ulong[] dim2539Kuo2Init = { 1, 1, 1, 13, 19, 1, 33, 23, 325, 245, 1671, 3065, 6767, 13583, 4683, 0 }; - static ulong[] dim2540Kuo2Init = { 1, 1, 7, 5, 17, 55, 33, 235, 119, 715, 83, 1089, 5943, 11897, 13259, 0 }; - static ulong[] dim2541Kuo2Init = { 1, 3, 7, 5, 25, 27, 111, 225, 99, 917, 731, 2617, 7915, 7283, 357, 0 }; - static ulong[] dim2542Kuo2Init = { 1, 3, 1, 3, 13, 9, 127, 251, 189, 573, 1897, 2147, 2641, 13191, 3847, 0 }; - static ulong[] dim2543Kuo2Init = { 1, 3, 7, 1, 19, 49, 49, 231, 321, 67, 1067, 2267, 7873, 2825, 445, 0 }; - static ulong[] dim2544Kuo2Init = { 1, 3, 7, 5, 27, 55, 23, 155, 103, 969, 1929, 2171, 5601, 1267, 31897, 0 }; - static ulong[] dim2545Kuo2Init = { 1, 3, 3, 7, 3, 27, 107, 7, 61, 601, 1957, 4075, 2955, 7717, 10473, 0 }; - static ulong[] dim2546Kuo2Init = { 1, 3, 5, 13, 31, 25, 111, 11, 391, 727, 243, 1471, 143, 16161, 5591, 0 }; - static ulong[] dim2547Kuo2Init = { 1, 1, 1, 11, 11, 43, 117, 117, 173, 933, 163, 1571, 1901, 3201, 1151, 0 }; - static ulong[] dim2548Kuo2Init = { 1, 3, 5, 3, 17, 13, 47, 217, 351, 777, 607, 401, 3485, 8679, 20357, 0 }; - static ulong[] dim2549Kuo2Init = { 1, 1, 7, 15, 5, 13, 37, 7, 469, 413, 1343, 947, 5883, 6125, 14803, 0 }; - static ulong[] dim2550Kuo2Init = { 1, 3, 1, 3, 1, 61, 7, 67, 229, 931, 1997, 3067, 3507, 11675, 31837, 0 }; - static ulong[] dim2551Kuo2Init = { 1, 1, 5, 1, 5, 35, 43, 65, 101, 75, 629, 1149, 625, 1865, 5215, 0 }; - static ulong[] dim2552Kuo2Init = { 1, 1, 7, 7, 17, 61, 47, 29, 277, 861, 1901, 35, 1405, 4393, 26899, 0 }; - static ulong[] dim2553Kuo2Init = { 1, 1, 5, 13, 13, 11, 21, 27, 473, 145, 867, 2781, 2865, 2793, 3265, 0 }; - static ulong[] dim2554Kuo2Init = { 1, 1, 7, 11, 11, 31, 41, 119, 243, 989, 2047, 1455, 8037, 11633, 31199, 0 }; - static ulong[] dim2555Kuo2Init = { 1, 1, 7, 5, 29, 19, 1, 89, 63, 41, 323, 2135, 2091, 15061, 29039, 0 }; - static ulong[] dim2556Kuo2Init = { 1, 3, 5, 15, 9, 53, 15, 191, 229, 487, 1287, 1163, 6985, 881, 4789, 0 }; - static ulong[] dim2557Kuo2Init = { 1, 1, 3, 9, 11, 57, 89, 205, 355, 551, 1643, 1565, 4181, 10805, 29359, 0 }; - static ulong[] dim2558Kuo2Init = { 1, 1, 7, 7, 31, 3, 103, 165, 37, 195, 245, 1225, 2811, 14785, 9307, 0 }; - static ulong[] dim2559Kuo2Init = { 1, 1, 7, 5, 19, 31, 47, 115, 361, 1019, 1517, 4079, 3717, 11301, 12051, 0 }; - static ulong[] dim2560Kuo2Init = { 1, 3, 5, 9, 31, 21, 57, 27, 353, 623, 1217, 3079, 5429, 8645, 10773, 0 }; - static ulong[] dim2561Kuo2Init = { 1, 1, 7, 7, 3, 11, 55, 209, 239, 509, 959, 2091, 123, 11365, 26593, 0 }; - static ulong[] dim2562Kuo2Init = { 1, 1, 5, 9, 7, 19, 51, 179, 103, 901, 1717, 1837, 4327, 9753, 24147, 0 }; - static ulong[] dim2563Kuo2Init = { 1, 1, 1, 5, 9, 63, 19, 103, 265, 893, 1519, 4063, 7951, 15601, 15019, 0 }; - static ulong[] dim2564Kuo2Init = { 1, 1, 3, 1, 19, 29, 15, 11, 235, 785, 77, 3957, 4829, 9903, 8483, 0 }; - static ulong[] dim2565Kuo2Init = { 1, 1, 3, 9, 27, 33, 25, 103, 387, 131, 1555, 301, 1471, 11331, 15091, 0 }; - static ulong[] dim2566Kuo2Init = { 1, 3, 3, 13, 25, 63, 75, 245, 189, 527, 1829, 1943, 407, 15219, 24453, 0 }; - static ulong[] dim2567Kuo2Init = { 1, 3, 1, 11, 29, 27, 35, 5, 215, 949, 97, 3843, 7911, 15947, 25037, 0 }; - static ulong[] dim2568Kuo2Init = { 1, 3, 3, 9, 29, 49, 43, 245, 257, 741, 1067, 2405, 3793, 3787, 22921, 0 }; - static ulong[] dim2569Kuo2Init = { 1, 1, 3, 15, 29, 29, 39, 25, 485, 257, 1003, 77, 1617, 5151, 29595, 0 }; - static ulong[] dim2570Kuo2Init = { 1, 1, 3, 5, 9, 39, 61, 59, 197, 501, 527, 3371, 1739, 5697, 11857, 0 }; - static ulong[] dim2571Kuo2Init = { 1, 1, 1, 15, 31, 27, 41, 91, 11, 373, 627, 361, 8001, 12231, 5715, 0 }; - static ulong[] dim2572Kuo2Init = { 1, 3, 3, 9, 31, 27, 67, 203, 95, 221, 1911, 1045, 1311, 11633, 5375, 0 }; - static ulong[] dim2573Kuo2Init = { 1, 1, 5, 15, 31, 49, 59, 185, 285, 173, 1351, 1665, 5941, 2075, 26087, 0 }; - static ulong[] dim2574Kuo2Init = { 1, 1, 7, 9, 23, 33, 95, 171, 71, 743, 11, 33, 1263, 1595, 18281, 0 }; - static ulong[] dim2575Kuo2Init = { 1, 1, 1, 7, 13, 59, 99, 245, 497, 951, 1195, 1503, 6069, 2293, 31661, 0 }; - static ulong[] dim2576Kuo2Init = { 1, 3, 5, 3, 3, 3, 29, 3, 197, 697, 105, 435, 4583, 5407, 32727, 0 }; - static ulong[] dim2577Kuo2Init = { 1, 3, 7, 1, 9, 41, 77, 199, 495, 999, 1791, 2183, 2819, 10771, 6957, 0 }; - static ulong[] dim2578Kuo2Init = { 1, 1, 7, 15, 27, 13, 51, 33, 243, 947, 835, 2251, 1751, 10319, 3269, 0 }; - static ulong[] dim2579Kuo2Init = { 1, 3, 5, 7, 17, 59, 125, 151, 113, 889, 21, 3839, 1475, 10643, 3291, 0 }; - static ulong[] dim2580Kuo2Init = { 1, 3, 7, 3, 27, 55, 101, 13, 177, 967, 35, 3081, 3559, 6539, 13557, 0 }; - static ulong[] dim2581Kuo2Init = { 1, 3, 5, 13, 27, 7, 107, 147, 455, 605, 1589, 2325, 6891, 10431, 18227, 0 }; - static ulong[] dim2582Kuo2Init = { 1, 1, 3, 3, 27, 13, 121, 249, 205, 359, 1909, 4011, 6833, 11583, 8705, 0 }; - static ulong[] dim2583Kuo2Init = { 1, 3, 5, 9, 21, 47, 77, 103, 173, 637, 1921, 991, 6471, 6053, 1963, 0 }; - static ulong[] dim2584Kuo2Init = { 1, 1, 3, 15, 11, 9, 71, 161, 253, 1, 973, 3079, 4887, 10045, 20467, 0 }; - static ulong[] dim2585Kuo2Init = { 1, 1, 5, 13, 27, 45, 11, 147, 79, 375, 533, 43, 7217, 9393, 20773, 0 }; - static ulong[] dim2586Kuo2Init = { 1, 1, 5, 3, 21, 47, 107, 83, 505, 463, 967, 3437, 3051, 11239, 20271, 0 }; - static ulong[] dim2587Kuo2Init = { 1, 1, 1, 15, 7, 9, 97, 143, 483, 393, 39, 447, 7779, 11037, 23283, 0 }; - static ulong[] dim2588Kuo2Init = { 1, 3, 1, 1, 31, 59, 85, 231, 209, 297, 353, 2577, 6209, 6691, 2941, 0 }; - static ulong[] dim2589Kuo2Init = { 1, 1, 7, 3, 19, 7, 81, 41, 419, 987, 1221, 2151, 5297, 1601, 1289, 0 }; - static ulong[] dim2590Kuo2Init = { 1, 3, 3, 13, 25, 13, 57, 199, 101, 157, 1273, 159, 5417, 5153, 30529, 0 }; - static ulong[] dim2591Kuo2Init = { 1, 1, 5, 1, 31, 41, 67, 71, 95, 929, 133, 3007, 6837, 7863, 23759, 0 }; - static ulong[] dim2592Kuo2Init = { 1, 1, 5, 3, 13, 59, 35, 11, 187, 251, 1119, 1517, 1433, 15475, 17981, 0 }; - static ulong[] dim2593Kuo2Init = { 1, 1, 3, 7, 5, 37, 11, 39, 111, 775, 761, 2853, 2283, 203, 22563, 0 }; - static ulong[] dim2594Kuo2Init = { 1, 1, 1, 11, 5, 45, 119, 81, 125, 481, 547, 3659, 5583, 6577, 17239, 0 }; - static ulong[] dim2595Kuo2Init = { 1, 3, 3, 13, 9, 25, 43, 103, 283, 637, 715, 3841, 5633, 503, 21933, 0 }; - static ulong[] dim2596Kuo2Init = { 1, 3, 1, 13, 21, 39, 1, 215, 235, 171, 1377, 2131, 2907, 11311, 11337, 0 }; - static ulong[] dim2597Kuo2Init = { 1, 3, 1, 3, 27, 19, 73, 83, 325, 451, 1779, 1665, 555, 7729, 26757, 0 }; - static ulong[] dim2598Kuo2Init = { 1, 3, 5, 13, 9, 29, 123, 177, 289, 553, 1323, 2531, 4071, 7395, 25847, 0 }; - static ulong[] dim2599Kuo2Init = { 1, 1, 7, 13, 1, 1, 29, 125, 253, 179, 1905, 821, 5329, 6181, 18445, 0 }; - static ulong[] dim2600Kuo2Init = { 1, 1, 1, 9, 15, 19, 59, 227, 63, 637, 1315, 2611, 1163, 6451, 8919, 0 }; - static ulong[] dim2601Kuo2Init = { 1, 1, 1, 5, 23, 39, 57, 143, 9, 811, 1101, 609, 1281, 9457, 14999, 0 }; - static ulong[] dim2602Kuo2Init = { 1, 3, 3, 7, 5, 31, 21, 31, 33, 271, 381, 1179, 4039, 14033, 19741, 0 }; - static ulong[] dim2603Kuo2Init = { 1, 3, 7, 15, 9, 41, 91, 247, 59, 201, 1837, 2609, 5481, 15479, 32253, 0 }; - static ulong[] dim2604Kuo2Init = { 1, 1, 3, 5, 15, 53, 7, 193, 451, 935, 701, 177, 7943, 5687, 15725, 0 }; - static ulong[] dim2605Kuo2Init = { 1, 3, 1, 13, 19, 9, 33, 173, 229, 993, 1637, 905, 5665, 9083, 10737, 0 }; - static ulong[] dim2606Kuo2Init = { 1, 1, 7, 9, 17, 33, 3, 145, 213, 317, 1135, 3281, 4169, 4601, 30347, 0 }; - static ulong[] dim2607Kuo2Init = { 1, 1, 1, 3, 23, 1, 49, 173, 351, 827, 937, 2423, 6443, 6413, 20383, 0 }; - static ulong[] dim2608Kuo2Init = { 1, 3, 5, 3, 21, 9, 7, 29, 293, 489, 339, 2403, 6303, 12283, 18047, 0 }; - static ulong[] dim2609Kuo2Init = { 1, 1, 7, 11, 23, 25, 49, 135, 389, 821, 17, 169, 4265, 5203, 3893, 0 }; - static ulong[] dim2610Kuo2Init = { 1, 1, 3, 3, 27, 63, 109, 165, 141, 129, 1441, 1443, 3991, 1639, 31461, 0 }; - static ulong[] dim2611Kuo2Init = { 1, 3, 7, 7, 25, 15, 85, 217, 223, 537, 1671, 2865, 4157, 8353, 18335, 0 }; - static ulong[] dim2612Kuo2Init = { 1, 3, 5, 11, 19, 19, 95, 159, 161, 599, 1059, 2065, 7159, 11273, 17501, 0 }; - static ulong[] dim2613Kuo2Init = { 1, 3, 7, 3, 15, 29, 5, 97, 95, 65, 1913, 1221, 329, 11601, 27033, 0 }; - static ulong[] dim2614Kuo2Init = { 1, 3, 3, 1, 25, 39, 103, 139, 379, 547, 1415, 4027, 559, 2101, 6133, 0 }; - static ulong[] dim2615Kuo2Init = { 1, 1, 7, 15, 21, 47, 115, 171, 17, 559, 1757, 745, 2573, 13969, 4193, 0 }; - static ulong[] dim2616Kuo2Init = { 1, 3, 3, 9, 19, 15, 37, 131, 199, 377, 67, 2455, 6807, 3365, 19697, 0 }; - static ulong[] dim2617Kuo2Init = { 1, 3, 5, 9, 25, 59, 9, 61, 369, 285, 231, 2911, 1817, 2125, 27637, 0 }; - static ulong[] dim2618Kuo2Init = { 1, 3, 1, 13, 25, 55, 61, 153, 507, 105, 149, 1589, 7167, 12363, 10257, 0 }; - static ulong[] dim2619Kuo2Init = { 1, 3, 1, 7, 9, 23, 109, 29, 167, 463, 101, 979, 3671, 10165, 12553, 0 }; - static ulong[] dim2620Kuo2Init = { 1, 3, 3, 9, 21, 49, 103, 217, 269, 761, 915, 3529, 125, 429, 24131, 0 }; - static ulong[] dim2621Kuo2Init = { 1, 3, 5, 15, 27, 61, 73, 13, 339, 1023, 967, 3883, 5515, 5893, 26183, 0 }; - static ulong[] dim2622Kuo2Init = { 1, 1, 1, 5, 5, 39, 87, 183, 141, 147, 779, 1733, 6137, 5985, 1335, 0 }; - static ulong[] dim2623Kuo2Init = { 1, 3, 5, 11, 23, 9, 61, 67, 235, 823, 1129, 401, 3049, 5593, 5193, 0 }; - static ulong[] dim2624Kuo2Init = { 1, 1, 3, 3, 27, 39, 27, 111, 81, 27, 283, 4081, 6511, 6785, 20953, 0 }; - static ulong[] dim2625Kuo2Init = { 1, 3, 7, 7, 17, 49, 93, 85, 327, 287, 1473, 3769, 2229, 12221, 27355, 0 }; - static ulong[] dim2626Kuo2Init = { 1, 3, 1, 3, 15, 15, 71, 105, 139, 137, 1139, 859, 7923, 581, 7697, 0 }; - static ulong[] dim2627Kuo2Init = { 1, 3, 7, 15, 29, 45, 17, 159, 233, 345, 1827, 2261, 6773, 5435, 17961, 0 }; - static ulong[] dim2628Kuo2Init = { 1, 3, 5, 13, 21, 15, 33, 229, 71, 709, 1757, 1479, 7289, 15629, 24041, 0 }; - static ulong[] dim2629Kuo2Init = { 1, 3, 3, 1, 27, 9, 103, 115, 137, 911, 603, 3615, 7671, 2439, 10041, 0 }; - static ulong[] dim2630Kuo2Init = { 1, 1, 5, 5, 21, 59, 67, 193, 249, 781, 761, 403, 6299, 527, 8533, 0 }; - static ulong[] dim2631Kuo2Init = { 1, 3, 3, 3, 5, 61, 71, 183, 151, 801, 1645, 2789, 5911, 11681, 5907, 0 }; - static ulong[] dim2632Kuo2Init = { 1, 1, 5, 7, 9, 19, 53, 239, 259, 273, 679, 2101, 1525, 2139, 30353, 0 }; - static ulong[] dim2633Kuo2Init = { 1, 1, 3, 1, 31, 25, 37, 225, 287, 31, 433, 2407, 1717, 6669, 10743, 0 }; - static ulong[] dim2634Kuo2Init = { 1, 3, 1, 13, 31, 13, 89, 225, 173, 723, 651, 3315, 6457, 9387, 7759, 0 }; - static ulong[] dim2635Kuo2Init = { 1, 1, 5, 7, 3, 25, 45, 79, 11, 843, 2031, 2827, 5029, 1359, 23489, 0 }; - static ulong[] dim2636Kuo2Init = { 1, 3, 5, 9, 7, 1, 53, 135, 327, 13, 1051, 2911, 5553, 6557, 16415, 0 }; - static ulong[] dim2637Kuo2Init = { 1, 1, 1, 5, 19, 19, 57, 147, 43, 503, 1899, 1709, 5589, 4251, 10871, 0 }; - static ulong[] dim2638Kuo2Init = { 1, 1, 5, 7, 1, 41, 83, 51, 89, 1015, 1441, 1735, 7217, 11431, 29623, 0 }; - static ulong[] dim2639Kuo2Init = { 1, 3, 7, 7, 29, 45, 73, 233, 399, 553, 961, 2053, 3537, 4015, 19963, 0 }; - static ulong[] dim2640Kuo2Init = { 1, 1, 5, 3, 21, 5, 1, 105, 341, 355, 849, 2235, 2801, 13749, 17933, 0 }; - static ulong[] dim2641Kuo2Init = { 1, 1, 7, 1, 25, 57, 29, 233, 485, 807, 1005, 1933, 3897, 1267, 30807, 0 }; - static ulong[] dim2642Kuo2Init = { 1, 1, 7, 15, 31, 53, 49, 31, 325, 335, 671, 1183, 2955, 3, 31739, 0 }; - static ulong[] dim2643Kuo2Init = { 1, 1, 5, 3, 17, 41, 19, 73, 215, 227, 1251, 907, 3303, 5343, 30385, 0 }; - static ulong[] dim2644Kuo2Init = { 1, 1, 1, 5, 15, 61, 123, 61, 27, 759, 645, 2571, 411, 13925, 29905, 0 }; - static ulong[] dim2645Kuo2Init = { 1, 3, 1, 5, 7, 55, 81, 241, 497, 1005, 1593, 2479, 25, 10627, 14043, 0 }; - static ulong[] dim2646Kuo2Init = { 1, 3, 3, 9, 19, 33, 87, 63, 441, 773, 1367, 2945, 4897, 14209, 6667, 0 }; - static ulong[] dim2647Kuo2Init = { 1, 1, 7, 15, 31, 59, 121, 153, 111, 329, 833, 2031, 4063, 13775, 9033, 0 }; - static ulong[] dim2648Kuo2Init = { 1, 3, 1, 11, 3, 33, 47, 65, 329, 149, 1509, 3617, 1381, 9003, 4953, 0 }; - static ulong[] dim2649Kuo2Init = { 1, 3, 1, 3, 7, 59, 39, 173, 157, 741, 343, 1039, 1695, 12077, 13203, 0 }; - static ulong[] dim2650Kuo2Init = { 1, 3, 7, 1, 17, 21, 21, 5, 65, 163, 711, 2251, 4761, 11895, 15571, 0 }; - static ulong[] dim2651Kuo2Init = { 1, 3, 7, 7, 7, 59, 31, 227, 283, 223, 163, 2639, 3037, 14423, 21507, 0 }; - static ulong[] dim2652Kuo2Init = { 1, 1, 1, 5, 9, 37, 5, 149, 395, 491, 711, 447, 5657, 443, 7183, 0 }; - static ulong[] dim2653Kuo2Init = { 1, 1, 5, 9, 17, 61, 31, 229, 207, 755, 199, 1585, 2771, 1499, 4911, 0 }; - static ulong[] dim2654Kuo2Init = { 1, 3, 5, 7, 1, 1, 53, 185, 407, 57, 525, 543, 5009, 1825, 8583, 0 }; - static ulong[] dim2655Kuo2Init = { 1, 1, 1, 3, 13, 49, 85, 175, 261, 653, 665, 3173, 4709, 11547, 14881, 0 }; - static ulong[] dim2656Kuo2Init = { 1, 1, 1, 3, 21, 47, 21, 33, 265, 171, 765, 3871, 3577, 15135, 13483, 0 }; - static ulong[] dim2657Kuo2Init = { 1, 3, 1, 3, 29, 5, 109, 3, 249, 379, 1259, 677, 1177, 13061, 31985, 0 }; - static ulong[] dim2658Kuo2Init = { 1, 3, 7, 3, 15, 25, 123, 93, 193, 419, 1173, 2493, 2937, 14909, 3147, 0 }; - static ulong[] dim2659Kuo2Init = { 1, 3, 3, 3, 9, 59, 55, 95, 93, 319, 1281, 587, 8065, 15697, 32101, 0 }; - static ulong[] dim2660Kuo2Init = { 1, 3, 5, 7, 25, 61, 105, 199, 101, 255, 849, 377, 3245, 8139, 8383, 0 }; - static ulong[] dim2661Kuo2Init = { 1, 1, 5, 9, 3, 47, 79, 155, 15, 661, 1417, 87, 4225, 13241, 15971, 0 }; - static ulong[] dim2662Kuo2Init = { 1, 3, 3, 1, 13, 39, 101, 79, 271, 21, 1983, 2821, 4177, 14081, 31219, 0 }; - static ulong[] dim2663Kuo2Init = { 1, 1, 1, 7, 15, 51, 123, 17, 29, 123, 1131, 147, 4191, 6729, 19359, 0 }; - static ulong[] dim2664Kuo2Init = { 1, 1, 7, 7, 17, 39, 47, 215, 219, 643, 1877, 3965, 5799, 16131, 24675, 0 }; - static ulong[] dim2665Kuo2Init = { 1, 3, 5, 7, 11, 53, 57, 133, 289, 33, 1631, 2037, 6699, 14153, 25309, 0 }; - static ulong[] dim2666Kuo2Init = { 1, 3, 7, 7, 9, 17, 125, 123, 91, 15, 1279, 297, 2583, 11141, 7257, 0 }; - static ulong[] dim2667Kuo2Init = { 1, 1, 7, 9, 13, 9, 83, 117, 365, 533, 343, 121, 7553, 14417, 23239, 0 }; - static ulong[] dim2668Kuo2Init = { 1, 3, 3, 9, 5, 27, 97, 229, 321, 123, 1669, 621, 4937, 683, 31061, 0 }; - static ulong[] dim2669Kuo2Init = { 1, 3, 1, 3, 1, 23, 63, 21, 271, 695, 601, 113, 6331, 8837, 16721, 0 }; - static ulong[] dim2670Kuo2Init = { 1, 3, 7, 13, 15, 41, 53, 115, 225, 5, 1315, 2285, 3815, 5949, 4263, 0 }; - static ulong[] dim2671Kuo2Init = { 1, 1, 1, 9, 21, 41, 25, 47, 9, 423, 1171, 2515, 3461, 13273, 13059, 0 }; - static ulong[] dim2672Kuo2Init = { 1, 3, 5, 15, 5, 29, 111, 15, 505, 347, 347, 2521, 4583, 5729, 11645, 0 }; - static ulong[] dim2673Kuo2Init = { 1, 3, 3, 1, 9, 15, 57, 211, 163, 749, 1549, 1015, 441, 16025, 28943, 0 }; - static ulong[] dim2674Kuo2Init = { 1, 1, 3, 15, 15, 27, 111, 79, 131, 831, 2045, 1937, 6969, 11223, 22711, 0 }; - static ulong[] dim2675Kuo2Init = { 1, 3, 5, 1, 3, 37, 37, 221, 143, 955, 1387, 3483, 5845, 13411, 16225, 0 }; - static ulong[] dim2676Kuo2Init = { 1, 3, 1, 3, 7, 13, 75, 57, 357, 109, 241, 165, 1845, 213, 8337, 0 }; - static ulong[] dim2677Kuo2Init = { 1, 3, 1, 15, 5, 41, 109, 129, 91, 459, 1237, 467, 8015, 14499, 19897, 0 }; - static ulong[] dim2678Kuo2Init = { 1, 1, 5, 7, 23, 45, 73, 135, 161, 921, 127, 3723, 1795, 4047, 16607, 0 }; - static ulong[] dim2679Kuo2Init = { 1, 3, 1, 9, 21, 17, 13, 133, 251, 927, 1551, 3087, 317, 2989, 30481, 0 }; - static ulong[] dim2680Kuo2Init = { 1, 1, 3, 7, 15, 51, 17, 77, 345, 833, 983, 2855, 383, 10873, 20019, 0 }; - static ulong[] dim2681Kuo2Init = { 1, 1, 7, 7, 3, 9, 65, 115, 449, 375, 27, 2053, 175, 6793, 9761, 0 }; - static ulong[] dim2682Kuo2Init = { 1, 3, 5, 7, 17, 7, 51, 207, 389, 995, 1663, 3697, 5539, 13495, 4053, 0 }; - static ulong[] dim2683Kuo2Init = { 1, 1, 1, 13, 5, 25, 125, 139, 123, 433, 1323, 273, 6061, 7145, 13929, 0 }; - static ulong[] dim2684Kuo2Init = { 1, 3, 7, 3, 3, 1, 65, 217, 203, 887, 121, 961, 2843, 16171, 8433, 0 }; - static ulong[] dim2685Kuo2Init = { 1, 1, 3, 1, 21, 25, 93, 237, 203, 721, 1135, 751, 7193, 7453, 29593, 0 }; - static ulong[] dim2686Kuo2Init = { 1, 1, 5, 13, 27, 41, 125, 31, 145, 69, 1865, 471, 6031, 6589, 16185, 0 }; - static ulong[] dim2687Kuo2Init = { 1, 1, 5, 1, 13, 39, 15, 251, 125, 781, 1635, 231, 7503, 12647, 9493, 0 }; - static ulong[] dim2688Kuo2Init = { 1, 1, 3, 11, 31, 35, 39, 49, 279, 281, 285, 1707, 607, 3405, 5803, 0 }; - static ulong[] dim2689Kuo2Init = { 1, 3, 5, 7, 29, 61, 43, 15, 413, 759, 159, 2027, 4065, 9501, 31597, 0 }; - static ulong[] dim2690Kuo2Init = { 1, 1, 5, 3, 21, 19, 25, 31, 21, 139, 1273, 871, 423, 13737, 1633, 0 }; - static ulong[] dim2691Kuo2Init = { 1, 1, 5, 11, 9, 15, 15, 247, 459, 49, 2047, 289, 7457, 13367, 3343, 0 }; - static ulong[] dim2692Kuo2Init = { 1, 3, 7, 1, 5, 43, 49, 115, 201, 131, 297, 2069, 801, 7599, 675, 0 }; - static ulong[] dim2693Kuo2Init = { 1, 1, 3, 15, 11, 19, 41, 135, 107, 325, 431, 2459, 7629, 3407, 19635, 0 }; - static ulong[] dim2694Kuo2Init = { 1, 1, 7, 15, 1, 45, 89, 249, 463, 319, 1577, 549, 3623, 7053, 23037, 0 }; - static ulong[] dim2695Kuo2Init = { 1, 3, 1, 11, 27, 23, 123, 63, 219, 77, 179, 3283, 2887, 14023, 28277, 0 }; - static ulong[] dim2696Kuo2Init = { 1, 3, 1, 9, 29, 47, 39, 61, 413, 327, 1529, 593, 7779, 14857, 14165, 0 }; - static ulong[] dim2697Kuo2Init = { 1, 3, 5, 3, 29, 15, 73, 231, 141, 435, 1835, 1023, 289, 1859, 1069, 0 }; - static ulong[] dim2698Kuo2Init = { 1, 3, 3, 3, 9, 35, 1, 153, 111, 521, 461, 3001, 5401, 9529, 19845, 0 }; - static ulong[] dim2699Kuo2Init = { 1, 1, 1, 15, 17, 43, 49, 227, 87, 199, 179, 1619, 6093, 15695, 30739, 0 }; - static ulong[] dim2700Kuo2Init = { 1, 3, 3, 9, 17, 53, 67, 199, 263, 931, 413, 1019, 679, 15483, 22211, 0 }; - static ulong[] dim2701Kuo2Init = { 1, 1, 7, 3, 19, 7, 55, 111, 499, 587, 1685, 1007, 5147, 6097, 31801, 0 }; - static ulong[] dim2702Kuo2Init = { 1, 3, 7, 5, 17, 15, 41, 167, 495, 439, 1161, 3737, 5957, 4151, 26597, 0 }; - static ulong[] dim2703Kuo2Init = { 1, 3, 5, 13, 17, 35, 103, 205, 83, 613, 1541, 2825, 2773, 14487, 177, 0 }; - static ulong[] dim2704Kuo2Init = { 1, 3, 1, 5, 11, 31, 1, 93, 87, 917, 1209, 1489, 4063, 7811, 31291, 0 }; - static ulong[] dim2705Kuo2Init = { 1, 1, 5, 9, 27, 25, 15, 121, 51, 207, 567, 2091, 6177, 121, 15305, 0 }; - static ulong[] dim2706Kuo2Init = { 1, 3, 7, 13, 17, 27, 13, 31, 443, 487, 863, 3253, 4961, 2695, 6427, 0 }; - static ulong[] dim2707Kuo2Init = { 1, 3, 7, 15, 23, 23, 85, 229, 123, 151, 519, 2581, 4073, 5915, 23715, 0 }; - static ulong[] dim2708Kuo2Init = { 1, 3, 5, 9, 19, 41, 33, 71, 511, 683, 1387, 2975, 5069, 4327, 25881, 0 }; - static ulong[] dim2709Kuo2Init = { 1, 1, 7, 3, 9, 25, 29, 73, 55, 323, 483, 1509, 4895, 5151, 13095, 0 }; - static ulong[] dim2710Kuo2Init = { 1, 3, 7, 3, 7, 19, 95, 163, 239, 721, 747, 3965, 6943, 11771, 5991, 0 }; - static ulong[] dim2711Kuo2Init = { 1, 3, 1, 9, 27, 11, 5, 9, 291, 987, 313, 129, 4147, 1005, 25719, 0 }; - static ulong[] dim2712Kuo2Init = { 1, 1, 1, 5, 7, 25, 85, 197, 177, 759, 1083, 2615, 3647, 11873, 17035, 0 }; - static ulong[] dim2713Kuo2Init = { 1, 3, 1, 13, 13, 11, 29, 45, 103, 319, 1325, 2987, 7253, 3967, 32547, 0 }; - static ulong[] dim2714Kuo2Init = { 1, 3, 5, 9, 11, 27, 103, 75, 113, 741, 175, 2715, 1595, 7899, 261, 0 }; - static ulong[] dim2715Kuo2Init = { 1, 1, 3, 5, 3, 39, 113, 19, 301, 19, 1369, 2759, 467, 10387, 15763, 0 }; - static ulong[] dim2716Kuo2Init = { 1, 1, 5, 5, 5, 23, 47, 21, 69, 57, 1183, 2725, 2329, 4829, 22769, 0 }; - static ulong[] dim2717Kuo2Init = { 1, 3, 3, 13, 1, 39, 111, 11, 133, 143, 465, 1551, 2969, 2353, 9381, 0 }; - static ulong[] dim2718Kuo2Init = { 1, 3, 7, 3, 29, 19, 75, 97, 139, 325, 189, 477, 5687, 11105, 17325, 0 }; - static ulong[] dim2719Kuo2Init = { 1, 1, 3, 15, 25, 51, 53, 177, 41, 677, 233, 467, 4977, 8055, 30257, 0 }; - static ulong[] dim2720Kuo2Init = { 1, 3, 7, 5, 29, 49, 23, 247, 167, 229, 719, 1583, 3451, 11901, 10991, 0 }; - static ulong[] dim2721Kuo2Init = { 1, 1, 1, 13, 5, 39, 35, 247, 185, 409, 1481, 3993, 2023, 9251, 1253, 0 }; - static ulong[] dim2722Kuo2Init = { 1, 1, 3, 13, 27, 35, 49, 251, 359, 161, 1535, 3277, 1483, 8045, 22373, 0 }; - static ulong[] dim2723Kuo2Init = { 1, 1, 1, 7, 3, 63, 103, 7, 141, 305, 1803, 3429, 6819, 3389, 12915, 0 }; - static ulong[] dim2724Kuo2Init = { 1, 3, 3, 15, 15, 7, 19, 121, 421, 633, 1619, 1225, 4061, 13649, 25537, 0 }; - static ulong[] dim2725Kuo2Init = { 1, 3, 7, 13, 5, 49, 117, 97, 85, 13, 55, 2991, 6215, 15087, 29311, 0 }; - static ulong[] dim2726Kuo2Init = { 1, 1, 7, 13, 29, 37, 23, 75, 11, 899, 1519, 2151, 235, 7121, 20881, 0 }; - static ulong[] dim2727Kuo2Init = { 1, 3, 5, 13, 7, 9, 97, 57, 307, 791, 745, 881, 6627, 1639, 22029, 0 }; - static ulong[] dim2728Kuo2Init = { 1, 3, 7, 11, 31, 25, 67, 153, 397, 115, 1951, 553, 2511, 853, 22771, 0 }; - static ulong[] dim2729Kuo2Init = { 1, 1, 7, 13, 13, 33, 3, 49, 281, 847, 395, 2671, 7173, 11035, 2809, 0 }; - static ulong[] dim2730Kuo2Init = { 1, 3, 7, 11, 7, 13, 21, 93, 279, 453, 1793, 1183, 4071, 11357, 15871, 0 }; - static ulong[] dim2731Kuo2Init = { 1, 3, 5, 1, 31, 27, 87, 115, 373, 519, 1691, 3339, 5319, 10765, 3497, 0 }; - static ulong[] dim2732Kuo2Init = { 1, 3, 5, 11, 27, 13, 73, 111, 349, 889, 1447, 1733, 7701, 9263, 27267, 0 }; - static ulong[] dim2733Kuo2Init = { 1, 1, 1, 13, 15, 25, 31, 187, 227, 119, 955, 1233, 2749, 8477, 12031, 0 }; - static ulong[] dim2734Kuo2Init = { 1, 3, 1, 7, 19, 13, 89, 151, 61, 267, 1833, 3023, 8177, 12863, 13851, 0 }; - static ulong[] dim2735Kuo2Init = { 1, 1, 7, 11, 11, 19, 65, 223, 175, 893, 1515, 2323, 6725, 747, 10299, 0 }; - static ulong[] dim2736Kuo2Init = { 1, 1, 1, 15, 3, 17, 109, 119, 371, 193, 1289, 219, 463, 9043, 31471, 0 }; - static ulong[] dim2737Kuo2Init = { 1, 1, 1, 3, 9, 9, 71, 185, 81, 849, 917, 2495, 4065, 14161, 14287, 0 }; - static ulong[] dim2738Kuo2Init = { 1, 1, 5, 3, 5, 59, 111, 133, 351, 247, 1035, 3277, 3865, 5879, 16537, 0 }; - static ulong[] dim2739Kuo2Init = { 1, 3, 3, 11, 23, 47, 3, 39, 343, 71, 109, 4005, 7453, 8327, 9797, 0 }; - static ulong[] dim2740Kuo2Init = { 1, 1, 1, 5, 21, 31, 53, 33, 115, 287, 431, 2085, 5275, 5253, 18137, 0 }; - static ulong[] dim2741Kuo2Init = { 1, 3, 1, 15, 21, 43, 95, 143, 103, 611, 583, 41, 483, 13973, 30231, 0 }; - static ulong[] dim2742Kuo2Init = { 1, 1, 1, 9, 9, 33, 49, 35, 329, 887, 1593, 2301, 229, 10291, 21153, 0 }; - static ulong[] dim2743Kuo2Init = { 1, 3, 5, 9, 25, 55, 55, 207, 381, 747, 997, 3105, 377, 15327, 24367, 0 }; - static ulong[] dim2744Kuo2Init = { 1, 3, 7, 15, 23, 25, 101, 225, 345, 579, 975, 2383, 7833, 12727, 15991, 0 }; - static ulong[] dim2745Kuo2Init = { 1, 3, 3, 1, 23, 13, 51, 45, 471, 271, 151, 1407, 2079, 3521, 6469, 0 }; - static ulong[] dim2746Kuo2Init = { 1, 3, 1, 9, 3, 11, 117, 115, 89, 871, 1989, 1341, 2415, 12921, 3531, 0 }; - static ulong[] dim2747Kuo2Init = { 1, 3, 3, 1, 3, 49, 41, 215, 277, 155, 1185, 2837, 4361, 14495, 19877, 0 }; - static ulong[] dim2748Kuo2Init = { 1, 1, 1, 9, 9, 19, 31, 211, 179, 367, 1597, 561, 5397, 7525, 2963, 0 }; - static ulong[] dim2749Kuo2Init = { 1, 3, 7, 11, 25, 45, 29, 151, 107, 13, 1461, 235, 6939, 6223, 13111, 0 }; - static ulong[] dim2750Kuo2Init = { 1, 3, 7, 15, 17, 11, 43, 113, 65, 321, 1393, 1131, 2481, 13139, 14647, 0 }; - static ulong[] dim2751Kuo2Init = { 1, 3, 7, 3, 15, 23, 45, 229, 175, 857, 1303, 783, 3929, 855, 13581, 0 }; - static ulong[] dim2752Kuo2Init = { 1, 3, 7, 3, 7, 55, 99, 85, 415, 667, 603, 593, 427, 10725, 6973, 0 }; - static ulong[] dim2753Kuo2Init = { 1, 3, 7, 3, 1, 23, 93, 177, 59, 601, 1947, 3253, 639, 10007, 1441, 0 }; - static ulong[] dim2754Kuo2Init = { 1, 3, 5, 11, 13, 37, 79, 19, 395, 161, 945, 969, 1579, 13537, 6347, 0 }; - static ulong[] dim2755Kuo2Init = { 1, 3, 1, 15, 3, 61, 101, 3, 289, 707, 61, 1405, 811, 6727, 22339, 0 }; - static ulong[] dim2756Kuo2Init = { 1, 3, 5, 11, 3, 45, 19, 125, 503, 153, 1439, 2105, 7483, 1835, 22841, 0 }; - static ulong[] dim2757Kuo2Init = { 1, 1, 7, 3, 23, 49, 49, 227, 413, 57, 1829, 37, 407, 4203, 20575, 0 }; - static ulong[] dim2758Kuo2Init = { 1, 3, 5, 11, 3, 43, 93, 85, 37, 471, 1971, 1559, 5151, 11641, 13011, 0 }; - static ulong[] dim2759Kuo2Init = { 1, 1, 5, 15, 5, 13, 17, 209, 125, 581, 57, 43, 7089, 3367, 16073, 0 }; - static ulong[] dim2760Kuo2Init = { 1, 3, 3, 9, 29, 51, 93, 223, 73, 917, 1657, 2811, 1593, 8595, 23347, 0 }; - static ulong[] dim2761Kuo2Init = { 1, 3, 1, 15, 25, 21, 111, 207, 61, 815, 805, 1439, 5745, 5065, 9877, 0 }; - static ulong[] dim2762Kuo2Init = { 1, 3, 3, 15, 7, 1, 113, 225, 467, 341, 1145, 3839, 1127, 5085, 885, 0 }; - static ulong[] dim2763Kuo2Init = { 1, 1, 7, 3, 13, 27, 103, 17, 175, 351, 1321, 2093, 3407, 3387, 1663, 0 }; - static ulong[] dim2764Kuo2Init = { 1, 3, 5, 13, 5, 61, 31, 223, 249, 797, 1541, 3985, 2165, 8741, 561, 0 }; - static ulong[] dim2765Kuo2Init = { 1, 1, 1, 7, 21, 51, 119, 9, 331, 305, 1279, 3331, 2769, 673, 26293, 0 }; - static ulong[] dim2766Kuo2Init = { 1, 1, 3, 9, 7, 61, 65, 157, 7, 259, 871, 557, 7917, 12839, 18521, 0 }; - static ulong[] dim2767Kuo2Init = { 1, 3, 3, 5, 9, 63, 21, 109, 409, 843, 1811, 1869, 6833, 6041, 31557, 0 }; - static ulong[] dim2768Kuo2Init = { 1, 1, 5, 15, 17, 17, 25, 79, 157, 657, 1049, 2071, 4381, 14123, 4609, 0 }; - static ulong[] dim2769Kuo2Init = { 1, 1, 5, 3, 3, 7, 45, 69, 311, 197, 1729, 2803, 2621, 1165, 26455, 0 }; - static ulong[] dim2770Kuo2Init = { 1, 3, 7, 7, 23, 21, 21, 227, 481, 825, 1871, 325, 3199, 5591, 22061, 0 }; - static ulong[] dim2771Kuo2Init = { 1, 3, 1, 7, 7, 53, 125, 163, 133, 1015, 727, 329, 403, 3347, 8957, 0 }; - static ulong[] dim2772Kuo2Init = { 1, 1, 3, 1, 13, 19, 107, 31, 261, 771, 195, 2381, 2577, 5381, 7159, 0 }; - static ulong[] dim2773Kuo2Init = { 1, 3, 7, 9, 7, 21, 61, 179, 405, 745, 689, 2527, 4189, 12869, 32101, 0 }; - static ulong[] dim2774Kuo2Init = { 1, 3, 7, 1, 3, 25, 35, 103, 107, 433, 1039, 3557, 7207, 13945, 27751, 0 }; - static ulong[] dim2775Kuo2Init = { 1, 3, 5, 5, 7, 9, 55, 93, 39, 965, 1391, 1069, 6003, 3785, 17337, 0 }; - static ulong[] dim2776Kuo2Init = { 1, 1, 5, 5, 11, 33, 127, 247, 443, 697, 2007, 491, 3773, 4921, 21083, 0 }; - static ulong[] dim2777Kuo2Init = { 1, 1, 5, 9, 1, 3, 33, 99, 31, 797, 295, 2855, 1911, 5741, 21255, 0 }; - static ulong[] dim2778Kuo2Init = { 1, 1, 5, 9, 25, 27, 77, 111, 119, 1, 193, 2825, 3721, 2923, 1301, 0 }; - static ulong[] dim2779Kuo2Init = { 1, 1, 1, 9, 11, 51, 51, 193, 331, 867, 1711, 969, 1245, 2815, 13165, 0 }; - static ulong[] dim2780Kuo2Init = { 1, 3, 5, 1, 23, 29, 23, 193, 357, 567, 983, 2861, 3973, 3613, 8049, 0 }; - static ulong[] dim2781Kuo2Init = { 1, 1, 7, 3, 27, 1, 117, 255, 149, 427, 1211, 2945, 4057, 725, 11061, 0 }; - static ulong[] dim2782Kuo2Init = { 1, 1, 7, 5, 13, 5, 101, 21, 167, 535, 825, 639, 6659, 9779, 11939, 0 }; - static ulong[] dim2783Kuo2Init = { 1, 3, 7, 1, 23, 25, 5, 15, 491, 531, 1035, 1989, 2125, 2779, 3207, 0 }; - static ulong[] dim2784Kuo2Init = { 1, 1, 3, 13, 13, 25, 43, 155, 251, 761, 123, 1373, 649, 11709, 22331, 0 }; - static ulong[] dim2785Kuo2Init = { 1, 3, 5, 13, 25, 37, 15, 247, 303, 95, 1837, 499, 2181, 11223, 1633, 0 }; - static ulong[] dim2786Kuo2Init = { 1, 1, 1, 5, 15, 53, 29, 193, 11, 625, 21, 3893, 957, 493, 32393, 0 }; - static ulong[] dim2787Kuo2Init = { 1, 1, 5, 9, 31, 13, 3, 235, 65, 563, 1787, 387, 2573, 3435, 8669, 0 }; - static ulong[] dim2788Kuo2Init = { 1, 3, 5, 1, 29, 17, 73, 81, 207, 335, 1949, 3519, 6491, 9185, 2305, 0 }; - static ulong[] dim2789Kuo2Init = { 1, 1, 3, 11, 5, 43, 15, 141, 347, 171, 1965, 2733, 7873, 7295, 10571, 0 }; - static ulong[] dim2790Kuo2Init = { 1, 1, 5, 11, 5, 3, 73, 89, 189, 77, 877, 1127, 3609, 11649, 31191, 0 }; - static ulong[] dim2791Kuo2Init = { 1, 1, 3, 15, 15, 25, 103, 73, 363, 261, 833, 2297, 4295, 13505, 8435, 0 }; - static ulong[] dim2792Kuo2Init = { 1, 1, 3, 9, 23, 57, 15, 87, 215, 789, 975, 2659, 6407, 9883, 3863, 0 }; - static ulong[] dim2793Kuo2Init = { 1, 1, 1, 9, 19, 51, 127, 77, 259, 161, 1527, 1911, 6707, 15573, 12479, 0 }; - static ulong[] dim2794Kuo2Init = { 1, 3, 1, 15, 11, 5, 35, 89, 235, 281, 269, 511, 783, 307, 19887, 0 }; - static ulong[] dim2795Kuo2Init = { 1, 3, 7, 15, 1, 43, 85, 25, 133, 577, 1719, 3999, 4597, 125, 12945, 0 }; - static ulong[] dim2796Kuo2Init = { 1, 3, 5, 15, 3, 1, 3, 111, 145, 485, 1959, 1859, 3567, 4219, 7507, 0 }; - static ulong[] dim2797Kuo2Init = { 1, 1, 3, 5, 27, 17, 45, 157, 87, 895, 497, 3, 1553, 2697, 24767, 0 }; - static ulong[] dim2798Kuo2Init = { 1, 3, 5, 1, 31, 23, 123, 67, 349, 717, 1699, 823, 851, 1283, 25641, 0 }; - static ulong[] dim2799Kuo2Init = { 1, 1, 5, 15, 9, 61, 43, 171, 33, 367, 1887, 917, 1901, 10881, 5699, 0 }; - static ulong[] dim2800Kuo2Init = { 1, 3, 1, 7, 11, 33, 45, 19, 71, 913, 687, 265, 1579, 13857, 3833, 0 }; - static ulong[] dim2801Kuo2Init = { 1, 3, 1, 5, 7, 15, 11, 87, 277, 435, 1479, 3025, 4663, 12063, 25185, 0 }; - static ulong[] dim2802Kuo2Init = { 1, 1, 1, 1, 15, 11, 91, 99, 195, 77, 967, 2741, 4291, 4441, 2763, 0 }; - static ulong[] dim2803Kuo2Init = { 1, 3, 7, 9, 9, 47, 25, 225, 193, 569, 561, 2567, 2751, 9035, 21613, 0 }; - static ulong[] dim2804Kuo2Init = { 1, 1, 3, 9, 3, 25, 99, 95, 33, 811, 479, 99, 7893, 869, 6879, 0 }; - static ulong[] dim2805Kuo2Init = { 1, 1, 5, 7, 11, 43, 111, 131, 107, 989, 147, 529, 6361, 769, 26651, 0 }; - static ulong[] dim2806Kuo2Init = { 1, 1, 5, 9, 23, 47, 81, 97, 357, 613, 609, 357, 2001, 14795, 25093, 0 }; - static ulong[] dim2807Kuo2Init = { 1, 1, 7, 3, 1, 13, 31, 171, 471, 981, 1923, 3053, 1577, 14433, 1795, 0 }; - static ulong[] dim2808Kuo2Init = { 1, 1, 3, 11, 29, 15, 107, 5, 281, 773, 1323, 763, 6821, 15309, 21459, 0 }; - static ulong[] dim2809Kuo2Init = { 1, 1, 5, 3, 17, 47, 49, 159, 17, 595, 1405, 1307, 3027, 3023, 17231, 0 }; - static ulong[] dim2810Kuo2Init = { 1, 3, 3, 11, 5, 37, 39, 247, 391, 587, 1305, 969, 7183, 1079, 5723, 0 }; - static ulong[] dim2811Kuo2Init = { 1, 3, 7, 5, 11, 57, 49, 55, 505, 961, 115, 2445, 583, 9175, 11897, 0 }; - static ulong[] dim2812Kuo2Init = { 1, 1, 7, 13, 23, 35, 9, 59, 147, 139, 361, 1497, 1691, 1149, 19777, 0 }; - static ulong[] dim2813Kuo2Init = { 1, 3, 7, 1, 19, 41, 71, 63, 401, 193, 107, 1891, 5353, 4619, 18311, 0 }; - static ulong[] dim2814Kuo2Init = { 1, 1, 7, 1, 27, 7, 49, 69, 179, 461, 1625, 2431, 5149, 3221, 14221, 0 }; - static ulong[] dim2815Kuo2Init = { 1, 3, 7, 13, 7, 11, 55, 93, 191, 1011, 139, 2323, 5103, 9655, 28605, 0 }; - static ulong[] dim2816Kuo2Init = { 1, 1, 5, 7, 29, 53, 117, 253, 193, 29, 2003, 2051, 6113, 4941, 18407, 0 }; - static ulong[] dim2817Kuo2Init = { 1, 1, 5, 5, 31, 7, 63, 179, 371, 1007, 107, 113, 6845, 8507, 9691, 0 }; - static ulong[] dim2818Kuo2Init = { 1, 1, 7, 7, 9, 31, 91, 225, 115, 905, 1593, 2791, 1507, 13323, 787, 0 }; - static ulong[] dim2819Kuo2Init = { 1, 3, 1, 9, 31, 13, 81, 111, 255, 467, 2007, 3591, 3849, 3445, 6859, 0 }; - static ulong[] dim2820Kuo2Init = { 1, 3, 7, 15, 19, 3, 89, 171, 445, 803, 1583, 1875, 5631, 10583, 32527, 0 }; - static ulong[] dim2821Kuo2Init = { 1, 3, 3, 15, 29, 29, 41, 199, 237, 507, 1715, 3887, 2951, 5803, 32749, 0 }; - static ulong[] dim2822Kuo2Init = { 1, 1, 3, 5, 21, 51, 29, 131, 459, 611, 967, 99, 8057, 12685, 16021, 0 }; - static ulong[] dim2823Kuo2Init = { 1, 3, 5, 5, 21, 19, 103, 131, 149, 477, 437, 4003, 7141, 2465, 32723, 0 }; - static ulong[] dim2824Kuo2Init = { 1, 3, 7, 15, 9, 41, 115, 47, 261, 589, 1859, 631, 719, 4459, 26475, 0 }; - static ulong[] dim2825Kuo2Init = { 1, 3, 1, 7, 9, 43, 79, 51, 383, 355, 1977, 739, 7333, 3573, 16061, 0 }; - static ulong[] dim2826Kuo2Init = { 1, 1, 3, 1, 11, 9, 79, 141, 135, 195, 755, 585, 7125, 4643, 31791, 0 }; - static ulong[] dim2827Kuo2Init = { 1, 1, 1, 7, 21, 23, 5, 225, 57, 307, 455, 3713, 8167, 4759, 10337, 0 }; - static ulong[] dim2828Kuo2Init = { 1, 3, 1, 15, 3, 45, 9, 225, 167, 847, 1205, 2105, 2547, 10925, 31181, 0 }; - static ulong[] dim2829Kuo2Init = { 1, 1, 3, 5, 3, 25, 57, 21, 45, 685, 53, 2447, 3139, 10949, 14939, 0 }; - static ulong[] dim2830Kuo2Init = { 1, 3, 5, 7, 13, 55, 13, 185, 353, 613, 1655, 1171, 6261, 1703, 26859, 0 }; - static ulong[] dim2831Kuo2Init = { 1, 1, 1, 15, 25, 29, 99, 81, 141, 387, 1369, 2177, 289, 14499, 23795, 0 }; - static ulong[] dim2832Kuo2Init = { 1, 3, 7, 5, 1, 37, 123, 99, 1, 707, 1415, 1275, 3979, 3359, 17807, 0 }; - static ulong[] dim2833Kuo2Init = { 1, 1, 5, 15, 19, 7, 113, 51, 329, 109, 1705, 517, 1887, 393, 8283, 0 }; - static ulong[] dim2834Kuo2Init = { 1, 3, 1, 13, 23, 63, 89, 117, 89, 515, 1221, 3267, 2371, 5065, 16391, 0 }; - static ulong[] dim2835Kuo2Init = { 1, 3, 5, 15, 1, 17, 39, 129, 453, 503, 841, 2997, 4279, 8639, 17623, 0 }; - static ulong[] dim2836Kuo2Init = { 1, 3, 5, 15, 27, 23, 127, 85, 301, 491, 959, 3241, 7525, 13723, 12317, 0 }; - static ulong[] dim2837Kuo2Init = { 1, 3, 5, 9, 31, 63, 45, 237, 173, 823, 223, 3129, 3285, 359, 3549, 0 }; - static ulong[] dim2838Kuo2Init = { 1, 3, 5, 7, 19, 29, 85, 191, 395, 717, 1305, 2529, 7939, 10905, 8941, 0 }; - static ulong[] dim2839Kuo2Init = { 1, 1, 5, 13, 31, 3, 41, 61, 461, 341, 683, 1973, 7127, 2183, 2137, 0 }; - static ulong[] dim2840Kuo2Init = { 1, 3, 1, 7, 27, 33, 97, 97, 319, 329, 1075, 539, 3313, 6343, 11249, 0 }; - static ulong[] dim2841Kuo2Init = { 1, 3, 5, 7, 25, 31, 99, 59, 337, 169, 861, 1989, 5999, 5397, 20563, 0 }; - static ulong[] dim2842Kuo2Init = { 1, 1, 5, 13, 17, 37, 83, 33, 75, 887, 379, 3499, 733, 4343, 31503, 0 }; - static ulong[] dim2843Kuo2Init = { 1, 1, 3, 1, 3, 45, 3, 245, 37, 797, 43, 943, 5301, 6857, 6653, 0 }; - static ulong[] dim2844Kuo2Init = { 1, 1, 1, 3, 9, 7, 39, 231, 349, 481, 1831, 2115, 6381, 13021, 18775, 0 }; - static ulong[] dim2845Kuo2Init = { 1, 3, 1, 11, 31, 27, 33, 103, 469, 987, 663, 3533, 1441, 4703, 23383, 0 }; - static ulong[] dim2846Kuo2Init = { 1, 3, 3, 15, 27, 59, 31, 31, 463, 851, 1957, 2905, 4823, 12549, 849, 0 }; - static ulong[] dim2847Kuo2Init = { 1, 3, 7, 5, 17, 31, 125, 183, 189, 297, 417, 1387, 5811, 10517, 19367, 0 }; - static ulong[] dim2848Kuo2Init = { 1, 3, 7, 7, 7, 9, 91, 9, 343, 267, 493, 431, 2345, 7173, 1769, 0 }; - static ulong[] dim2849Kuo2Init = { 1, 1, 1, 13, 13, 43, 75, 83, 19, 115, 1609, 2449, 5647, 12201, 27053, 0 }; - static ulong[] dim2850Kuo2Init = { 1, 3, 7, 7, 1, 7, 81, 89, 371, 283, 993, 3875, 6853, 16039, 12725, 0 }; - static ulong[] dim2851Kuo2Init = { 1, 1, 7, 1, 21, 61, 121, 135, 333, 339, 39, 2543, 3517, 9099, 27495, 0 }; - static ulong[] dim2852Kuo2Init = { 1, 1, 7, 13, 19, 59, 65, 65, 407, 255, 915, 2679, 2841, 13981, 6351, 0 }; - static ulong[] dim2853Kuo2Init = { 1, 3, 1, 5, 9, 45, 73, 217, 93, 3, 493, 531, 6709, 6543, 26243, 0 }; - static ulong[] dim2854Kuo2Init = { 1, 3, 3, 13, 9, 25, 77, 223, 495, 789, 1885, 383, 7767, 4309, 29863, 0 }; - static ulong[] dim2855Kuo2Init = { 1, 3, 5, 7, 21, 55, 11, 13, 19, 605, 1067, 667, 1163, 3847, 17997, 0 }; - static ulong[] dim2856Kuo2Init = { 1, 1, 7, 1, 15, 51, 69, 115, 19, 1003, 1307, 3245, 7087, 6935, 25439, 0 }; - static ulong[] dim2857Kuo2Init = { 1, 1, 7, 5, 11, 7, 85, 171, 301, 953, 507, 3873, 1121, 1663, 6321, 0 }; - static ulong[] dim2858Kuo2Init = { 1, 1, 1, 13, 11, 1, 105, 175, 163, 847, 983, 3869, 3571, 3405, 25475, 0 }; - static ulong[] dim2859Kuo2Init = { 1, 3, 5, 15, 7, 51, 89, 127, 347, 867, 429, 1483, 5203, 5215, 18521, 0 }; - static ulong[] dim2860Kuo2Init = { 1, 1, 3, 7, 21, 35, 91, 107, 111, 895, 1827, 3273, 3189, 4253, 12643, 0 }; - static ulong[] dim2861Kuo2Init = { 1, 3, 5, 15, 31, 33, 59, 27, 59, 297, 7, 1521, 1571, 10275, 32537, 0 }; - static ulong[] dim2862Kuo2Init = { 1, 1, 5, 11, 1, 27, 17, 115, 349, 593, 1819, 707, 4915, 2053, 13393, 0 }; - static ulong[] dim2863Kuo2Init = { 1, 1, 1, 1, 25, 47, 73, 163, 191, 637, 1723, 2431, 4821, 4283, 14647, 0 }; - static ulong[] dim2864Kuo2Init = { 1, 3, 7, 13, 1, 55, 67, 89, 113, 757, 1675, 255, 99, 9427, 953, 0 }; - static ulong[] dim2865Kuo2Init = { 1, 3, 7, 5, 1, 33, 7, 49, 299, 205, 1933, 2319, 6047, 6837, 6411, 0 }; - static ulong[] dim2866Kuo2Init = { 1, 1, 7, 5, 11, 35, 61, 211, 487, 253, 1463, 2039, 3859, 4315, 29603, 0 }; - static ulong[] dim2867Kuo2Init = { 1, 3, 1, 15, 23, 49, 99, 41, 263, 177, 193, 921, 1031, 13745, 14283, 0 }; - static ulong[] dim2868Kuo2Init = { 1, 3, 7, 5, 19, 35, 91, 19, 481, 305, 477, 2989, 7319, 2477, 2481, 0 }; - static ulong[] dim2869Kuo2Init = { 1, 3, 7, 13, 1, 15, 25, 133, 175, 571, 15, 505, 7459, 13283, 10253, 0 }; - static ulong[] dim2870Kuo2Init = { 1, 3, 7, 11, 13, 27, 95, 179, 149, 267, 481, 543, 3643, 4261, 1241, 0 }; - static ulong[] dim2871Kuo2Init = { 1, 1, 3, 1, 5, 25, 115, 27, 503, 595, 43, 975, 6223, 14173, 12977, 0 }; - static ulong[] dim2872Kuo2Init = { 1, 1, 1, 13, 17, 55, 3, 129, 125, 565, 785, 2787, 5963, 12565, 11061, 0 }; - static ulong[] dim2873Kuo2Init = { 1, 1, 1, 1, 23, 25, 51, 89, 317, 887, 1007, 1619, 3221, 4015, 18183, 0 }; - static ulong[] dim2874Kuo2Init = { 1, 3, 3, 7, 27, 37, 33, 131, 379, 505, 1679, 2381, 629, 8593, 15553, 0 }; - static ulong[] dim2875Kuo2Init = { 1, 3, 1, 9, 21, 53, 79, 85, 27, 541, 997, 1721, 2379, 9939, 32197, 0 }; - static ulong[] dim2876Kuo2Init = { 1, 3, 7, 5, 29, 3, 29, 7, 499, 195, 157, 1431, 1117, 14781, 14811, 0 }; - static ulong[] dim2877Kuo2Init = { 1, 3, 3, 9, 23, 19, 41, 59, 313, 391, 193, 3813, 2769, 7845, 4853, 0 }; - static ulong[] dim2878Kuo2Init = { 1, 1, 7, 7, 7, 61, 103, 45, 225, 753, 339, 963, 3991, 8699, 19805, 0 }; - static ulong[] dim2879Kuo2Init = { 1, 1, 3, 5, 15, 61, 125, 121, 53, 105, 121, 1939, 4745, 1193, 1733, 0 }; - static ulong[] dim2880Kuo2Init = { 1, 1, 7, 7, 29, 29, 71, 137, 195, 757, 1251, 3483, 6977, 1189, 4929, 0 }; - static ulong[] dim2881Kuo2Init = { 1, 1, 3, 9, 1, 11, 21, 39, 199, 873, 1063, 3327, 2171, 14611, 15283, 0 }; - static ulong[] dim2882Kuo2Init = { 1, 3, 3, 15, 11, 19, 71, 185, 235, 211, 1435, 543, 3445, 2533, 25037, 0 }; - static ulong[] dim2883Kuo2Init = { 1, 3, 1, 7, 15, 17, 33, 139, 301, 853, 2027, 1665, 4931, 2083, 9775, 0 }; - static ulong[] dim2884Kuo2Init = { 1, 3, 5, 1, 31, 21, 91, 71, 273, 119, 801, 2071, 4537, 541, 743, 0 }; - static ulong[] dim2885Kuo2Init = { 1, 1, 3, 5, 29, 23, 15, 225, 333, 979, 443, 1425, 3383, 5137, 27273, 0 }; - static ulong[] dim2886Kuo2Init = { 1, 1, 1, 5, 21, 27, 121, 169, 495, 883, 355, 3923, 1505, 13033, 6421, 0 }; - static ulong[] dim2887Kuo2Init = { 1, 3, 1, 5, 3, 17, 19, 169, 43, 659, 893, 1913, 885, 1239, 4055, 0 }; - static ulong[] dim2888Kuo2Init = { 1, 1, 1, 13, 13, 39, 1, 123, 29, 573, 475, 535, 4685, 6377, 30009, 0 }; - static ulong[] dim2889Kuo2Init = { 1, 3, 7, 7, 15, 53, 93, 183, 379, 125, 489, 4059, 5411, 7909, 25799, 0 }; - static ulong[] dim2890Kuo2Init = { 1, 1, 1, 3, 23, 31, 75, 61, 75, 379, 1221, 3045, 7111, 10639, 3177, 0 }; - static ulong[] dim2891Kuo2Init = { 1, 1, 1, 7, 27, 37, 77, 145, 35, 1005, 1105, 1301, 5217, 3011, 22631, 0 }; - static ulong[] dim2892Kuo2Init = { 1, 1, 5, 5, 29, 7, 55, 139, 323, 413, 31, 1719, 2315, 5809, 9521, 0 }; - static ulong[] dim2893Kuo2Init = { 1, 3, 1, 3, 21, 61, 45, 143, 427, 511, 1007, 1009, 6775, 4243, 29573, 0 }; - static ulong[] dim2894Kuo2Init = { 1, 1, 3, 9, 11, 13, 29, 99, 179, 493, 1793, 375, 109, 8561, 14799, 0 }; - static ulong[] dim2895Kuo2Init = { 1, 3, 1, 9, 5, 37, 83, 227, 241, 933, 869, 2125, 2733, 205, 14985, 0 }; - static ulong[] dim2896Kuo2Init = { 1, 3, 7, 3, 11, 17, 39, 97, 229, 805, 491, 2881, 4147, 2159, 32461, 0 }; - static ulong[] dim2897Kuo2Init = { 1, 3, 7, 15, 27, 17, 71, 227, 247, 731, 1287, 397, 7237, 10869, 7799, 0 }; - static ulong[] dim2898Kuo2Init = { 1, 3, 7, 15, 7, 1, 63, 163, 249, 111, 1015, 2379, 7051, 11615, 20031, 0 }; - static ulong[] dim2899Kuo2Init = { 1, 1, 7, 1, 1, 41, 61, 99, 385, 725, 161, 2595, 1789, 6619, 13397, 0 }; - static ulong[] dim2900Kuo2Init = { 1, 1, 7, 15, 5, 53, 59, 153, 427, 251, 1977, 1757, 821, 6391, 7825, 0 }; - static ulong[] dim2901Kuo2Init = { 1, 1, 3, 15, 17, 19, 83, 55, 199, 573, 337, 919, 649, 555, 27791, 0 }; - static ulong[] dim2902Kuo2Init = { 1, 3, 1, 5, 25, 11, 23, 167, 443, 325, 2037, 2533, 643, 1815, 24747, 0 }; - static ulong[] dim2903Kuo2Init = { 1, 1, 1, 7, 3, 15, 21, 73, 165, 241, 1089, 337, 4465, 11867, 31075, 0 }; - static ulong[] dim2904Kuo2Init = { 1, 3, 1, 9, 31, 33, 41, 217, 185, 973, 1971, 1537, 1251, 4307, 22729, 0 }; - static ulong[] dim2905Kuo2Init = { 1, 1, 1, 11, 7, 51, 17, 37, 113, 339, 211, 947, 4649, 8061, 1533, 0 }; - static ulong[] dim2906Kuo2Init = { 1, 3, 3, 11, 7, 1, 29, 233, 145, 121, 83, 3311, 2007, 15325, 2507, 0 }; - static ulong[] dim2907Kuo2Init = { 1, 3, 1, 5, 25, 9, 117, 227, 359, 401, 695, 841, 5825, 14661, 14937, 0 }; - static ulong[] dim2908Kuo2Init = { 1, 3, 3, 13, 27, 43, 61, 117, 297, 773, 1589, 347, 3227, 10893, 3331, 0 }; - static ulong[] dim2909Kuo2Init = { 1, 1, 5, 13, 5, 15, 65, 97, 155, 905, 655, 1665, 2759, 14709, 14327, 0 }; - static ulong[] dim2910Kuo2Init = { 1, 3, 3, 11, 31, 9, 63, 207, 287, 895, 817, 1753, 1961, 15363, 5269, 0 }; - static ulong[] dim2911Kuo2Init = { 1, 1, 1, 11, 3, 17, 21, 131, 295, 553, 1583, 1797, 6949, 7047, 30351, 0 }; - static ulong[] dim2912Kuo2Init = { 1, 3, 7, 5, 23, 9, 123, 155, 1, 525, 469, 165, 591, 6113, 17593, 0 }; - static ulong[] dim2913Kuo2Init = { 1, 3, 5, 13, 27, 21, 125, 175, 323, 113, 1805, 3775, 443, 15723, 187, 0 }; - static ulong[] dim2914Kuo2Init = { 1, 3, 5, 13, 29, 7, 89, 123, 349, 469, 635, 629, 1227, 11601, 10409, 0 }; - static ulong[] dim2915Kuo2Init = { 1, 3, 1, 5, 13, 7, 13, 209, 431, 59, 2001, 1347, 4619, 11581, 23281, 0 }; - static ulong[] dim2916Kuo2Init = { 1, 3, 5, 3, 3, 9, 15, 169, 77, 293, 17, 3205, 5035, 14777, 2175, 0 }; - static ulong[] dim2917Kuo2Init = { 1, 1, 1, 9, 27, 5, 39, 237, 275, 121, 217, 1283, 1619, 9115, 18019, 0 }; - static ulong[] dim2918Kuo2Init = { 1, 1, 1, 11, 31, 43, 111, 235, 439, 217, 769, 513, 5147, 4033, 27329, 0 }; - static ulong[] dim2919Kuo2Init = { 1, 1, 5, 5, 31, 25, 35, 71, 441, 1013, 963, 2945, 4507, 16329, 5965, 0 }; - static ulong[] dim2920Kuo2Init = { 1, 3, 1, 7, 27, 25, 109, 43, 421, 963, 553, 3347, 3159, 11909, 29827, 0 }; - static ulong[] dim2921Kuo2Init = { 1, 3, 3, 11, 5, 17, 1, 253, 497, 209, 423, 3837, 5233, 3919, 4593, 0 }; - static ulong[] dim2922Kuo2Init = { 1, 3, 5, 11, 1, 61, 85, 61, 59, 637, 1017, 455, 5529, 7495, 16645, 0 }; - static ulong[] dim2923Kuo2Init = { 1, 1, 1, 5, 11, 11, 111, 151, 297, 289, 259, 1737, 4033, 5545, 22049, 0 }; - static ulong[] dim2924Kuo2Init = { 1, 1, 3, 9, 11, 33, 53, 43, 95, 859, 1113, 3201, 2705, 15009, 24945, 0 }; - static ulong[] dim2925Kuo2Init = { 1, 1, 7, 3, 7, 1, 59, 201, 127, 1023, 879, 1359, 4323, 11829, 32591, 0 }; - static ulong[] dim2926Kuo2Init = { 1, 1, 5, 13, 1, 15, 65, 3, 7, 373, 427, 3987, 3849, 16289, 3669, 0 }; - static ulong[] dim2927Kuo2Init = { 1, 1, 1, 3, 23, 21, 49, 215, 159, 577, 963, 3257, 5919, 4397, 14811, 0 }; - static ulong[] dim2928Kuo2Init = { 1, 3, 1, 9, 3, 43, 51, 49, 331, 717, 791, 279, 3305, 955, 14003, 0 }; - static ulong[] dim2929Kuo2Init = { 1, 1, 7, 7, 19, 45, 11, 249, 9, 221, 1525, 2413, 1807, 191, 3063, 0 }; - static ulong[] dim2930Kuo2Init = { 1, 3, 7, 1, 17, 33, 45, 201, 471, 683, 13, 3851, 7337, 2249, 8287, 0 }; - static ulong[] dim2931Kuo2Init = { 1, 3, 3, 1, 11, 21, 85, 141, 445, 691, 577, 2781, 3677, 11799, 25555, 0 }; - static ulong[] dim2932Kuo2Init = { 1, 1, 7, 1, 3, 27, 71, 245, 341, 69, 1355, 1289, 8165, 1159, 6001, 0 }; - static ulong[] dim2933Kuo2Init = { 1, 3, 3, 15, 11, 31, 31, 117, 193, 847, 1755, 1629, 6707, 5447, 15961, 0 }; - static ulong[] dim2934Kuo2Init = { 1, 1, 1, 1, 23, 13, 69, 107, 33, 731, 233, 2225, 201, 2667, 19935, 0 }; - static ulong[] dim2935Kuo2Init = { 1, 1, 1, 9, 31, 9, 25, 225, 373, 99, 1725, 3029, 5019, 10927, 541, 0 }; - static ulong[] dim2936Kuo2Init = { 1, 3, 3, 1, 29, 29, 37, 235, 135, 99, 599, 581, 7663, 1607, 7957, 0 }; - static ulong[] dim2937Kuo2Init = { 1, 3, 1, 11, 1, 31, 79, 33, 319, 341, 1701, 973, 5783, 3003, 15311, 0 }; - static ulong[] dim2938Kuo2Init = { 1, 3, 5, 15, 19, 11, 95, 51, 35, 887, 1505, 207, 7925, 1919, 30735, 0 }; - static ulong[] dim2939Kuo2Init = { 1, 3, 5, 7, 3, 27, 55, 41, 293, 519, 1885, 617, 321, 5911, 26813, 0 }; - static ulong[] dim2940Kuo2Init = { 1, 1, 7, 1, 7, 59, 9, 59, 291, 927, 1241, 1707, 3833, 13859, 3311, 0 }; - static ulong[] dim2941Kuo2Init = { 1, 3, 3, 13, 17, 61, 1, 155, 355, 943, 159, 2519, 7835, 14097, 671, 0 }; - static ulong[] dim2942Kuo2Init = { 1, 1, 3, 3, 29, 33, 59, 37, 363, 605, 365, 2431, 2529, 6449, 8847, 0 }; - static ulong[] dim2943Kuo2Init = { 1, 3, 7, 5, 1, 33, 87, 215, 465, 937, 2031, 421, 2535, 10017, 18395, 0 }; - static ulong[] dim2944Kuo2Init = { 1, 1, 7, 1, 27, 25, 7, 103, 501, 53, 1491, 99, 7433, 8251, 18849, 0 }; - static ulong[] dim2945Kuo2Init = { 1, 3, 1, 1, 31, 15, 7, 89, 145, 457, 7, 2821, 6595, 5893, 29049, 0 }; - static ulong[] dim2946Kuo2Init = { 1, 1, 3, 7, 15, 55, 127, 39, 493, 39, 1753, 643, 4005, 12041, 21811, 0 }; - static ulong[] dim2947Kuo2Init = { 1, 3, 3, 3, 17, 23, 79, 129, 181, 1017, 767, 1869, 4589, 4059, 15391, 0 }; - static ulong[] dim2948Kuo2Init = { 1, 1, 1, 3, 13, 17, 109, 253, 441, 361, 1641, 1647, 2139, 11629, 21061, 0 }; - static ulong[] dim2949Kuo2Init = { 1, 1, 3, 15, 5, 15, 43, 113, 455, 17, 353, 3431, 4871, 14777, 3257, 0 }; - static ulong[] dim2950Kuo2Init = { 1, 3, 1, 1, 7, 5, 49, 199, 295, 467, 1151, 2563, 1261, 1611, 8457, 0 }; - static ulong[] dim2951Kuo2Init = { 1, 3, 3, 9, 21, 1, 107, 71, 67, 271, 427, 673, 2093, 13255, 15941, 0 }; - static ulong[] dim2952Kuo2Init = { 1, 1, 7, 7, 19, 55, 127, 109, 101, 773, 1423, 2725, 2403, 1419, 2543, 0 }; - static ulong[] dim2953Kuo2Init = { 1, 3, 5, 9, 25, 49, 15, 77, 423, 723, 2033, 275, 1593, 3055, 12043, 0 }; - static ulong[] dim2954Kuo2Init = { 1, 3, 1, 9, 29, 27, 115, 5, 407, 797, 2041, 155, 2389, 9749, 31653, 0 }; - static ulong[] dim2955Kuo2Init = { 1, 3, 3, 7, 5, 29, 123, 139, 467, 377, 1853, 2769, 6523, 14195, 31539, 0 }; - static ulong[] dim2956Kuo2Init = { 1, 3, 3, 5, 25, 41, 103, 89, 469, 577, 1583, 1061, 7609, 4261, 17323, 0 }; - static ulong[] dim2957Kuo2Init = { 1, 1, 5, 5, 29, 37, 79, 179, 189, 185, 535, 3433, 6091, 4935, 21853, 0 }; - static ulong[] dim2958Kuo2Init = { 1, 1, 5, 13, 17, 63, 119, 191, 7, 353, 1591, 2881, 7857, 11355, 32427, 0 }; - static ulong[] dim2959Kuo2Init = { 1, 3, 1, 7, 13, 53, 21, 151, 499, 721, 1495, 2101, 7061, 12529, 16733, 0 }; - static ulong[] dim2960Kuo2Init = { 1, 1, 7, 1, 1, 1, 17, 141, 221, 875, 1569, 3165, 2583, 2803, 21001, 0 }; - static ulong[] dim2961Kuo2Init = { 1, 3, 3, 13, 7, 7, 99, 129, 381, 237, 159, 2359, 2223, 7465, 25437, 0 }; - static ulong[] dim2962Kuo2Init = { 1, 1, 3, 15, 31, 19, 103, 17, 475, 649, 279, 1321, 1751, 6957, 26055, 0 }; - static ulong[] dim2963Kuo2Init = { 1, 1, 1, 7, 5, 41, 3, 29, 23, 513, 1619, 291, 3949, 12117, 15175, 0 }; - static ulong[] dim2964Kuo2Init = { 1, 3, 1, 3, 13, 13, 73, 77, 373, 999, 1985, 161, 3223, 10873, 2967, 0 }; - static ulong[] dim2965Kuo2Init = { 1, 1, 5, 7, 27, 1, 47, 79, 463, 499, 37, 113, 3207, 6753, 13207, 0 }; - static ulong[] dim2966Kuo2Init = { 1, 1, 1, 9, 29, 33, 71, 225, 71, 943, 197, 3645, 7459, 5495, 22449, 0 }; - static ulong[] dim2967Kuo2Init = { 1, 1, 3, 9, 1, 21, 101, 31, 357, 689, 1081, 165, 621, 11277, 21773, 0 }; - static ulong[] dim2968Kuo2Init = { 1, 1, 7, 3, 13, 13, 21, 11, 87, 741, 765, 3299, 2741, 12825, 13383, 0 }; - static ulong[] dim2969Kuo2Init = { 1, 3, 3, 5, 5, 51, 49, 215, 427, 513, 621, 4067, 661, 12261, 6839, 0 }; - static ulong[] dim2970Kuo2Init = { 1, 1, 7, 9, 13, 9, 77, 17, 229, 139, 1053, 2061, 4915, 1047, 3621, 0 }; - static ulong[] dim2971Kuo2Init = { 1, 1, 3, 1, 9, 7, 125, 165, 301, 721, 493, 543, 4885, 5011, 24545, 0 }; - static ulong[] dim2972Kuo2Init = { 1, 3, 3, 11, 31, 11, 5, 61, 89, 35, 1551, 3031, 1175, 16223, 19433, 0 }; - static ulong[] dim2973Kuo2Init = { 1, 1, 1, 11, 27, 31, 115, 181, 487, 53, 795, 1789, 7343, 7821, 20469, 0 }; - static ulong[] dim2974Kuo2Init = { 1, 1, 5, 3, 7, 25, 89, 145, 107, 361, 171, 2407, 1159, 9341, 23877, 0 }; - static ulong[] dim2975Kuo2Init = { 1, 3, 3, 15, 27, 47, 31, 53, 53, 479, 1479, 427, 461, 7287, 15947, 0 }; - static ulong[] dim2976Kuo2Init = { 1, 3, 7, 5, 3, 11, 79, 151, 463, 315, 919, 1531, 2367, 5189, 6971, 0 }; - static ulong[] dim2977Kuo2Init = { 1, 1, 5, 9, 25, 17, 3, 111, 167, 365, 871, 355, 6763, 11889, 5531, 0 }; - static ulong[] dim2978Kuo2Init = { 1, 1, 1, 13, 25, 31, 25, 185, 63, 335, 177, 3017, 941, 11849, 6879, 0 }; - static ulong[] dim2979Kuo2Init = { 1, 1, 3, 7, 29, 13, 81, 121, 119, 807, 1647, 569, 23, 9045, 15513, 0 }; - static ulong[] dim2980Kuo2Init = { 1, 1, 1, 5, 5, 61, 115, 79, 115, 401, 383, 3679, 8159, 15199, 1531, 0 }; - static ulong[] dim2981Kuo2Init = { 1, 3, 3, 11, 17, 45, 17, 37, 175, 735, 849, 3597, 7253, 11863, 5215, 0 }; - static ulong[] dim2982Kuo2Init = { 1, 1, 1, 13, 7, 59, 99, 67, 223, 635, 1645, 3169, 2655, 15925, 14969, 0 }; - static ulong[] dim2983Kuo2Init = { 1, 3, 7, 15, 25, 17, 17, 25, 1, 799, 829, 2085, 7371, 6905, 11573, 0 }; - static ulong[] dim2984Kuo2Init = { 1, 1, 5, 1, 19, 33, 127, 31, 305, 523, 1141, 1171, 3707, 14687, 27897, 0 }; - static ulong[] dim2985Kuo2Init = { 1, 1, 1, 11, 3, 7, 95, 243, 373, 481, 1663, 1449, 687, 5643, 3265, 0 }; - static ulong[] dim2986Kuo2Init = { 1, 3, 7, 11, 17, 35, 45, 15, 201, 389, 1085, 1597, 5073, 5009, 6921, 0 }; - static ulong[] dim2987Kuo2Init = { 1, 1, 5, 1, 25, 33, 99, 57, 429, 153, 1663, 1797, 785, 7323, 24763, 0 }; - static ulong[] dim2988Kuo2Init = { 1, 1, 7, 15, 1, 63, 93, 225, 189, 297, 927, 2127, 7335, 5187, 12047, 0 }; - static ulong[] dim2989Kuo2Init = { 1, 1, 5, 9, 23, 47, 27, 113, 469, 649, 1135, 1363, 6777, 2047, 5759, 0 }; - static ulong[] dim2990Kuo2Init = { 1, 1, 3, 1, 9, 33, 21, 123, 309, 635, 1217, 1087, 4525, 10165, 18071, 0 }; - static ulong[] dim2991Kuo2Init = { 1, 3, 3, 3, 19, 49, 13, 217, 155, 945, 1987, 2425, 3891, 13831, 21777, 0 }; - static ulong[] dim2992Kuo2Init = { 1, 1, 3, 11, 25, 9, 75, 149, 241, 175, 799, 1285, 3265, 14103, 30147, 0 }; - static ulong[] dim2993Kuo2Init = { 1, 1, 1, 3, 13, 41, 87, 127, 179, 723, 1345, 667, 4155, 8037, 29583, 0 }; - static ulong[] dim2994Kuo2Init = { 1, 1, 1, 9, 15, 57, 67, 197, 131, 957, 1855, 2857, 2939, 6459, 5807, 0 }; - static ulong[] dim2995Kuo2Init = { 1, 3, 5, 5, 23, 39, 19, 95, 103, 961, 239, 1151, 1069, 10261, 6065, 0 }; - static ulong[] dim2996Kuo2Init = { 1, 3, 3, 15, 23, 29, 51, 121, 45, 561, 1317, 1777, 1325, 5833, 5765, 0 }; - static ulong[] dim2997Kuo2Init = { 1, 1, 5, 1, 31, 3, 67, 9, 453, 281, 525, 1751, 5771, 14257, 11869, 0 }; - static ulong[] dim2998Kuo2Init = { 1, 1, 7, 1, 13, 35, 33, 59, 117, 737, 929, 547, 4839, 7013, 28395, 0 }; - static ulong[] dim2999Kuo2Init = { 1, 3, 7, 15, 21, 41, 19, 15, 73, 377, 665, 3867, 6445, 13137, 995, 0 }; - static ulong[] dim3000Kuo2Init = { 1, 3, 7, 11, 13, 41, 53, 115, 435, 607, 871, 315, 6573, 6321, 10413, 0 }; - static ulong[] dim3001Kuo2Init = { 1, 3, 3, 3, 27, 31, 23, 7, 151, 923, 1903, 789, 5031, 10631, 777, 0 }; - static ulong[] dim3002Kuo2Init = { 1, 1, 7, 7, 9, 25, 17, 241, 19, 569, 1269, 1211, 3947, 11351, 31211, 0 }; - static ulong[] dim3003Kuo2Init = { 1, 1, 7, 13, 25, 31, 79, 111, 157, 483, 1787, 1201, 3491, 7943, 4879, 0 }; - static ulong[] dim3004Kuo2Init = { 1, 3, 7, 13, 19, 9, 31, 133, 125, 347, 15, 1287, 4355, 15357, 21391, 0 }; - static ulong[] dim3005Kuo2Init = { 1, 3, 3, 13, 1, 29, 63, 175, 279, 799, 1867, 2221, 6043, 307, 12475, 0 }; - static ulong[] dim3006Kuo2Init = { 1, 1, 7, 5, 23, 51, 93, 65, 209, 45, 409, 3405, 2053, 1399, 4423, 0 }; - static ulong[] dim3007Kuo2Init = { 1, 3, 7, 13, 23, 55, 21, 121, 281, 115, 85, 1941, 2609, 7041, 16267, 0 }; - static ulong[] dim3008Kuo2Init = { 1, 1, 3, 5, 25, 3, 113, 107, 37, 393, 737, 2671, 7405, 12191, 27679, 0 }; - static ulong[] dim3009Kuo2Init = { 1, 1, 3, 13, 15, 13, 33, 233, 25, 163, 1097, 2977, 6933, 14625, 29587, 0 }; - static ulong[] dim3010Kuo2Init = { 1, 1, 1, 1, 31, 13, 11, 25, 47, 589, 2035, 3595, 1299, 10171, 12695, 0 }; - static ulong[] dim3011Kuo2Init = { 1, 3, 5, 11, 31, 63, 97, 67, 381, 1021, 1029, 2869, 5779, 15451, 4291, 0 }; - static ulong[] dim3012Kuo2Init = { 1, 1, 1, 5, 9, 37, 9, 205, 169, 375, 1367, 1749, 8015, 1019, 12671, 0 }; - static ulong[] dim3013Kuo2Init = { 1, 3, 5, 7, 13, 29, 75, 53, 173, 535, 1795, 1705, 3601, 2487, 29851, 0 }; - static ulong[] dim3014Kuo2Init = { 1, 3, 3, 5, 5, 17, 81, 209, 229, 913, 959, 3597, 1515, 13401, 1531, 0 }; - static ulong[] dim3015Kuo2Init = { 1, 3, 3, 5, 29, 47, 5, 43, 117, 215, 1469, 3743, 6801, 10511, 11097, 0 }; - static ulong[] dim3016Kuo2Init = { 1, 1, 1, 9, 11, 5, 79, 247, 43, 853, 663, 1967, 355, 12263, 15877, 0 }; - static ulong[] dim3017Kuo2Init = { 1, 3, 3, 5, 25, 23, 105, 203, 255, 677, 1855, 527, 825, 433, 27701, 0 }; - static ulong[] dim3018Kuo2Init = { 1, 3, 3, 1, 13, 29, 119, 47, 331, 203, 1515, 1581, 1707, 10621, 19371, 0 }; - static ulong[] dim3019Kuo2Init = { 1, 1, 1, 13, 27, 15, 5, 255, 201, 861, 1809, 703, 1707, 8209, 5175, 0 }; - static ulong[] dim3020Kuo2Init = { 1, 3, 1, 13, 17, 61, 41, 143, 459, 291, 1747, 3605, 5545, 7441, 21493, 0 }; - static ulong[] dim3021Kuo2Init = { 1, 1, 3, 9, 21, 61, 77, 61, 79, 855, 57, 1543, 2755, 6249, 3387, 0 }; - static ulong[] dim3022Kuo2Init = { 1, 1, 3, 1, 17, 5, 117, 243, 153, 397, 693, 701, 2201, 11375, 23753, 0 }; - static ulong[] dim3023Kuo2Init = { 1, 1, 7, 7, 17, 25, 123, 239, 411, 633, 395, 3809, 1483, 15125, 22221, 0 }; - static ulong[] dim3024Kuo2Init = { 1, 3, 3, 3, 7, 45, 57, 51, 35, 463, 1287, 3101, 4213, 12931, 28639, 0 }; - static ulong[] dim3025Kuo2Init = { 1, 3, 1, 5, 13, 7, 103, 177, 277, 645, 833, 883, 3607, 13545, 6405, 0 }; - static ulong[] dim3026Kuo2Init = { 1, 3, 7, 11, 17, 3, 41, 161, 511, 483, 773, 147, 8113, 2203, 29711, 0 }; - static ulong[] dim3027Kuo2Init = { 1, 3, 1, 5, 13, 29, 79, 189, 351, 65, 93, 1195, 5205, 7989, 14085, 0 }; - static ulong[] dim3028Kuo2Init = { 1, 1, 3, 11, 13, 5, 13, 35, 231, 627, 1155, 1117, 3889, 3645, 25099, 0 }; - static ulong[] dim3029Kuo2Init = { 1, 3, 5, 3, 13, 63, 73, 83, 249, 559, 303, 3303, 5387, 15773, 16249, 0 }; - static ulong[] dim3030Kuo2Init = { 1, 1, 1, 9, 21, 23, 63, 153, 291, 951, 1409, 1333, 5385, 14621, 13763, 0 }; - static ulong[] dim3031Kuo2Init = { 1, 3, 1, 9, 1, 45, 13, 139, 437, 495, 773, 1401, 1599, 2555, 21579, 0 }; - static ulong[] dim3032Kuo2Init = { 1, 3, 1, 9, 11, 15, 51, 123, 393, 223, 1045, 1001, 6955, 12755, 5979, 0 }; - static ulong[] dim3033Kuo2Init = { 1, 1, 1, 7, 31, 31, 57, 127, 339, 133, 1489, 3055, 3051, 14931, 7757, 0 }; - static ulong[] dim3034Kuo2Init = { 1, 3, 5, 9, 1, 23, 97, 79, 491, 641, 295, 2597, 3857, 1889, 16295, 0 }; - static ulong[] dim3035Kuo2Init = { 1, 3, 7, 7, 21, 31, 111, 77, 199, 401, 1829, 925, 6023, 16161, 1783, 0 }; - static ulong[] dim3036Kuo2Init = { 1, 3, 3, 1, 5, 9, 53, 133, 347, 761, 841, 841, 3031, 10201, 27245, 0 }; - static ulong[] dim3037Kuo2Init = { 1, 1, 3, 13, 31, 35, 21, 19, 95, 861, 1385, 3607, 335, 14643, 20435, 0 }; - static ulong[] dim3038Kuo2Init = { 1, 3, 3, 13, 7, 61, 47, 225, 235, 333, 1923, 2961, 61, 14463, 12329, 0 }; - static ulong[] dim3039Kuo2Init = { 1, 3, 5, 5, 23, 35, 43, 175, 25, 573, 1253, 233, 5377, 3153, 24543, 0 }; - static ulong[] dim3040Kuo2Init = { 1, 1, 5, 11, 27, 55, 49, 239, 479, 475, 223, 2947, 89, 5517, 2925, 0 }; - static ulong[] dim3041Kuo2Init = { 1, 3, 5, 13, 31, 45, 11, 255, 251, 647, 1161, 847, 1175, 1219, 19735, 0 }; - static ulong[] dim3042Kuo2Init = { 1, 3, 5, 1, 13, 19, 13, 31, 309, 165, 49, 2281, 5607, 11987, 19255, 0 }; - static ulong[] dim3043Kuo2Init = { 1, 3, 7, 7, 15, 35, 51, 243, 119, 179, 1055, 3751, 4133, 14873, 12317, 0 }; - static ulong[] dim3044Kuo2Init = { 1, 3, 7, 13, 13, 47, 87, 169, 203, 27, 449, 2755, 5407, 11857, 291, 0 }; - static ulong[] dim3045Kuo2Init = { 1, 3, 3, 5, 29, 27, 1, 225, 493, 649, 1075, 2197, 2201, 14425, 18853, 0 }; - static ulong[] dim3046Kuo2Init = { 1, 3, 7, 1, 23, 21, 87, 237, 377, 575, 445, 1845, 6689, 10945, 17517, 0 }; - static ulong[] dim3047Kuo2Init = { 1, 1, 5, 5, 19, 43, 5, 177, 507, 395, 945, 2933, 1237, 10069, 15707, 0 }; - static ulong[] dim3048Kuo2Init = { 1, 1, 1, 9, 31, 61, 85, 45, 325, 915, 863, 839, 2335, 14631, 32479, 0 }; - static ulong[] dim3049Kuo2Init = { 1, 1, 3, 5, 11, 61, 47, 119, 439, 407, 203, 2841, 2205, 5335, 29721, 0 }; - static ulong[] dim3050Kuo2Init = { 1, 3, 5, 11, 9, 9, 63, 179, 315, 257, 901, 5, 4523, 11085, 23639, 0 }; - static ulong[] dim3051Kuo2Init = { 1, 1, 5, 1, 11, 9, 83, 109, 265, 601, 1457, 795, 509, 5605, 13235, 0 }; - static ulong[] dim3052Kuo2Init = { 1, 3, 3, 13, 31, 25, 59, 37, 25, 811, 657, 467, 1317, 3783, 27645, 0 }; - static ulong[] dim3053Kuo2Init = { 1, 1, 1, 9, 31, 51, 81, 255, 379, 575, 1401, 2341, 2411, 11893, 29599, 0 }; - static ulong[] dim3054Kuo2Init = { 1, 1, 5, 13, 3, 47, 79, 183, 111, 409, 1223, 1305, 1073, 9251, 28331, 0 }; - static ulong[] dim3055Kuo2Init = { 1, 3, 3, 7, 31, 9, 39, 125, 269, 999, 1427, 1845, 4427, 3825, 29289, 0 }; - static ulong[] dim3056Kuo2Init = { 1, 1, 3, 3, 17, 41, 3, 29, 9, 253, 925, 1279, 2263, 15521, 25455, 0 }; - static ulong[] dim3057Kuo2Init = { 1, 1, 7, 7, 31, 31, 53, 95, 225, 967, 893, 1315, 5683, 3311, 15259, 0 }; - static ulong[] dim3058Kuo2Init = { 1, 1, 7, 3, 31, 21, 123, 145, 117, 137, 499, 2381, 6467, 15677, 2079, 0 }; - static ulong[] dim3059Kuo2Init = { 1, 1, 3, 15, 3, 15, 17, 235, 463, 493, 1465, 1717, 6511, 5331, 10265, 0 }; - static ulong[] dim3060Kuo2Init = { 1, 3, 3, 1, 25, 41, 31, 225, 115, 199, 1831, 29, 5563, 2697, 26689, 0 }; - static ulong[] dim3061Kuo2Init = { 1, 3, 7, 15, 7, 23, 29, 79, 35, 493, 997, 2139, 3813, 9915, 16693, 0 }; - static ulong[] dim3062Kuo2Init = { 1, 1, 7, 13, 13, 59, 71, 127, 41, 271, 1513, 2239, 6739, 6351, 11331, 0 }; - static ulong[] dim3063Kuo2Init = { 1, 3, 5, 1, 23, 63, 109, 225, 413, 277, 927, 1781, 843, 5959, 16655, 0 }; - static ulong[] dim3064Kuo2Init = { 1, 3, 5, 13, 9, 55, 91, 143, 401, 695, 1857, 205, 3617, 11847, 27339, 0 }; - static ulong[] dim3065Kuo2Init = { 1, 1, 3, 1, 21, 41, 5, 1, 207, 247, 1269, 3071, 8045, 8711, 3595, 0 }; - static ulong[] dim3066Kuo2Init = { 1, 3, 7, 15, 5, 23, 29, 119, 435, 961, 333, 2337, 3469, 6363, 29145, 0 }; - static ulong[] dim3067Kuo2Init = { 1, 3, 5, 5, 21, 19, 65, 177, 309, 115, 707, 1659, 941, 6825, 3595, 0 }; - static ulong[] dim3068Kuo2Init = { 1, 1, 1, 5, 29, 5, 113, 15, 13, 897, 1535, 3453, 3539, 3937, 22647, 0 }; - static ulong[] dim3069Kuo2Init = { 1, 1, 3, 9, 13, 41, 45, 11, 259, 127, 1421, 195, 4555, 11643, 30239, 0 }; - static ulong[] dim3070Kuo2Init = { 1, 3, 3, 15, 5, 17, 115, 89, 183, 729, 1655, 3599, 1443, 11799, 29777, 0 }; - static ulong[] dim3071Kuo2Init = { 1, 3, 3, 15, 19, 57, 61, 3, 53, 221, 799, 3243, 5255, 3271, 8677, 0 }; - static ulong[] dim3072Kuo2Init = { 1, 3, 1, 5, 23, 45, 103, 173, 453, 111, 1145, 891, 4989, 3195, 20129, 0 }; - static ulong[] dim3073Kuo2Init = { 1, 3, 1, 13, 13, 25, 71, 71, 125, 753, 397, 613, 1641, 2611, 1879, 0 }; - static ulong[] dim3074Kuo2Init = { 1, 1, 1, 15, 23, 59, 25, 199, 285, 161, 225, 4039, 5427, 13711, 23643, 0 }; - static ulong[] dim3075Kuo2Init = { 1, 1, 7, 13, 25, 9, 119, 121, 369, 811, 1857, 2227, 5711, 2761, 23033, 0 }; - static ulong[] dim3076Kuo2Init = { 1, 1, 3, 15, 27, 43, 75, 231, 221, 869, 603, 537, 3679, 15963, 27183, 0 }; - static ulong[] dim3077Kuo2Init = { 1, 1, 5, 3, 9, 35, 33, 39, 383, 415, 1769, 3837, 1479, 3411, 20917, 0 }; - static ulong[] dim3078Kuo2Init = { 1, 1, 5, 15, 7, 47, 119, 105, 31, 79, 229, 135, 1509, 1571, 24355, 0 }; - static ulong[] dim3079Kuo2Init = { 1, 1, 5, 7, 7, 15, 99, 79, 65, 869, 1781, 2111, 2405, 1901, 8419, 0 }; - static ulong[] dim3080Kuo2Init = { 1, 1, 3, 15, 7, 59, 13, 211, 439, 543, 755, 2177, 971, 6045, 24943, 0 }; - static ulong[] dim3081Kuo2Init = { 1, 1, 3, 7, 13, 25, 89, 71, 453, 71, 1205, 1419, 971, 11139, 25075, 0 }; - static ulong[] dim3082Kuo2Init = { 1, 3, 5, 3, 7, 63, 21, 17, 179, 749, 915, 3977, 5399, 11385, 13825, 0 }; - static ulong[] dim3083Kuo2Init = { 1, 1, 5, 9, 19, 49, 77, 47, 351, 815, 1925, 559, 4503, 8095, 3115, 0 }; - static ulong[] dim3084Kuo2Init = { 1, 3, 1, 9, 13, 61, 79, 245, 509, 691, 387, 2067, 1493, 10783, 31911, 0 }; - static ulong[] dim3085Kuo2Init = { 1, 3, 1, 11, 31, 27, 117, 55, 93, 389, 1299, 573, 6883, 10449, 19779, 0 }; - static ulong[] dim3086Kuo2Init = { 1, 3, 3, 7, 15, 27, 5, 207, 215, 773, 1989, 2341, 2101, 10585, 6675, 0 }; - static ulong[] dim3087Kuo2Init = { 1, 3, 3, 15, 19, 37, 93, 127, 233, 49, 557, 1683, 7299, 5399, 21571, 0 }; - static ulong[] dim3088Kuo2Init = { 1, 3, 1, 15, 15, 21, 95, 81, 167, 113, 245, 3607, 2007, 1847, 2317, 0 }; - static ulong[] dim3089Kuo2Init = { 1, 3, 3, 9, 21, 13, 1, 203, 361, 695, 539, 3927, 4149, 249, 8425, 0 }; - static ulong[] dim3090Kuo2Init = { 1, 3, 3, 11, 1, 61, 25, 159, 215, 235, 1561, 99, 2965, 13035, 11673, 0 }; - static ulong[] dim3091Kuo2Init = { 1, 3, 1, 1, 5, 27, 13, 83, 457, 57, 995, 2163, 257, 12671, 18391, 0 }; - static ulong[] dim3092Kuo2Init = { 1, 1, 5, 13, 23, 25, 69, 15, 53, 253, 1789, 3415, 3667, 3255, 26871, 0 }; - static ulong[] dim3093Kuo2Init = { 1, 1, 3, 3, 9, 13, 25, 81, 247, 483, 921, 649, 4759, 15037, 4923, 0 }; - static ulong[] dim3094Kuo2Init = { 1, 3, 5, 1, 5, 1, 111, 179, 329, 395, 1661, 2647, 6487, 11109, 15465, 0 }; - static ulong[] dim3095Kuo2Init = { 1, 1, 3, 7, 27, 27, 13, 123, 225, 181, 1205, 2703, 1753, 2513, 1671, 0 }; - static ulong[] dim3096Kuo2Init = { 1, 3, 7, 9, 23, 51, 1, 9, 233, 709, 257, 999, 5761, 3281, 8083, 0 }; - static ulong[] dim3097Kuo2Init = { 1, 1, 7, 11, 31, 33, 29, 83, 251, 1021, 1395, 447, 4071, 13257, 5821, 0 }; - static ulong[] dim3098Kuo2Init = { 1, 1, 5, 1, 11, 19, 67, 35, 371, 425, 613, 1065, 269, 3895, 19507, 0 }; - static ulong[] dim3099Kuo2Init = { 1, 3, 5, 1, 1, 53, 79, 229, 489, 373, 1195, 3221, 7425, 2731, 16607, 0 }; - static ulong[] dim3100Kuo2Init = { 1, 1, 3, 3, 3, 11, 49, 241, 269, 727, 549, 2463, 6983, 13067, 19829, 0 }; - static ulong[] dim3101Kuo2Init = { 1, 3, 5, 15, 13, 41, 53, 215, 131, 363, 595, 2777, 3929, 1305, 12725, 0 }; - static ulong[] dim3102Kuo2Init = { 1, 3, 3, 1, 5, 41, 87, 243, 485, 401, 1599, 397, 4207, 3707, 28949, 0 }; - static ulong[] dim3103Kuo2Init = { 1, 1, 1, 3, 7, 5, 31, 59, 25, 391, 1419, 2355, 953, 1179, 22605, 0 }; - static ulong[] dim3104Kuo2Init = { 1, 3, 3, 5, 13, 47, 3, 167, 25, 381, 341, 1999, 3423, 4465, 19517, 0 }; - static ulong[] dim3105Kuo2Init = { 1, 1, 3, 3, 21, 55, 93, 93, 243, 67, 1743, 139, 5783, 2261, 22411, 0 }; - static ulong[] dim3106Kuo2Init = { 1, 1, 1, 15, 25, 19, 1, 247, 325, 641, 347, 1095, 7301, 7079, 25403, 0 }; - static ulong[] dim3107Kuo2Init = { 1, 3, 5, 13, 29, 53, 23, 229, 425, 311, 1159, 2241, 105, 11165, 28737, 0 }; - static ulong[] dim3108Kuo2Init = { 1, 1, 7, 9, 31, 23, 3, 191, 119, 113, 543, 1119, 3375, 13605, 27753, 0 }; - static ulong[] dim3109Kuo2Init = { 1, 1, 7, 15, 1, 49, 23, 193, 165, 869, 509, 1017, 1045, 13709, 16293, 0 }; - static ulong[] dim3110Kuo2Init = { 1, 1, 1, 13, 3, 15, 25, 239, 423, 359, 409, 1075, 2629, 2291, 20293, 0 }; - static ulong[] dim3111Kuo2Init = { 1, 1, 3, 15, 27, 35, 67, 83, 11, 1, 1129, 1917, 1475, 14831, 13161, 0 }; - static ulong[] dim3112Kuo2Init = { 1, 1, 7, 11, 27, 21, 117, 191, 321, 721, 929, 2293, 2257, 9259, 4849, 0 }; - static ulong[] dim3113Kuo2Init = { 1, 1, 1, 1, 25, 61, 21, 211, 491, 127, 1423, 2291, 5121, 14065, 14835, 0 }; - static ulong[] dim3114Kuo2Init = { 1, 1, 7, 15, 17, 15, 81, 221, 319, 1015, 1643, 665, 7429, 7829, 5369, 0 }; - static ulong[] dim3115Kuo2Init = { 1, 3, 7, 13, 31, 45, 77, 103, 79, 891, 43, 1561, 295, 3977, 17699, 0 }; - static ulong[] dim3116Kuo2Init = { 1, 3, 5, 1, 11, 19, 105, 1, 179, 699, 655, 3125, 5851, 9577, 29513, 0 }; - static ulong[] dim3117Kuo2Init = { 1, 3, 7, 13, 1, 15, 105, 239, 113, 917, 219, 1857, 801, 11703, 20955, 0 }; - static ulong[] dim3118Kuo2Init = { 1, 1, 1, 9, 3, 35, 69, 43, 133, 455, 471, 1785, 4659, 6325, 3183, 0 }; - static ulong[] dim3119Kuo2Init = { 1, 1, 5, 3, 7, 57, 127, 13, 151, 359, 135, 2445, 1795, 3257, 32305, 0 }; - static ulong[] dim3120Kuo2Init = { 1, 1, 3, 9, 11, 43, 51, 109, 323, 789, 1181, 1577, 4445, 1623, 28489, 0 }; - static ulong[] dim3121Kuo2Init = { 1, 3, 7, 5, 19, 55, 71, 65, 35, 605, 165, 1573, 1429, 7123, 1967, 0 }; - static ulong[] dim3122Kuo2Init = { 1, 1, 1, 15, 15, 27, 87, 67, 503, 833, 1841, 2639, 5629, 5511, 12393, 0 }; - static ulong[] dim3123Kuo2Init = { 1, 3, 1, 11, 9, 59, 85, 59, 289, 679, 1957, 399, 7949, 4735, 709, 0 }; - static ulong[] dim3124Kuo2Init = { 1, 3, 5, 7, 3, 37, 109, 3, 33, 971, 123, 1585, 3273, 8421, 20903, 0 }; - static ulong[] dim3125Kuo2Init = { 1, 1, 1, 3, 17, 37, 99, 3, 405, 579, 755, 1337, 3649, 8217, 11011, 0 }; - static ulong[] dim3126Kuo2Init = { 1, 1, 7, 9, 25, 59, 87, 115, 237, 749, 355, 1781, 5199, 7019, 10615, 0 }; - static ulong[] dim3127Kuo2Init = { 1, 1, 3, 11, 23, 5, 105, 129, 453, 813, 1423, 2703, 6241, 14969, 22943, 0 }; - static ulong[] dim3128Kuo2Init = { 1, 1, 5, 7, 21, 41, 89, 129, 473, 139, 595, 925, 3915, 12059, 19675, 0 }; - static ulong[] dim3129Kuo2Init = { 1, 1, 5, 3, 17, 19, 83, 19, 191, 757, 1185, 1849, 3403, 779, 24773, 0 }; - static ulong[] dim3130Kuo2Init = { 1, 1, 5, 11, 13, 31, 121, 211, 357, 487, 829, 1215, 1, 15103, 10835, 0 }; - static ulong[] dim3131Kuo2Init = { 1, 1, 5, 15, 1, 15, 105, 137, 169, 295, 993, 261, 6787, 16339, 20307, 0 }; - static ulong[] dim3132Kuo2Init = { 1, 1, 5, 15, 21, 11, 53, 149, 443, 285, 371, 2541, 7041, 5745, 12127, 0 }; - static ulong[] dim3133Kuo2Init = { 1, 3, 5, 1, 9, 23, 89, 77, 337, 623, 329, 1021, 2013, 11023, 27045, 0 }; - static ulong[] dim3134Kuo2Init = { 1, 1, 7, 7, 1, 11, 35, 67, 93, 121, 1155, 1063, 4997, 9567, 24023, 0 }; - static ulong[] dim3135Kuo2Init = { 1, 1, 7, 7, 3, 33, 119, 243, 423, 615, 721, 3057, 7873, 9329, 20783, 0 }; - static ulong[] dim3136Kuo2Init = { 1, 3, 3, 15, 3, 23, 41, 121, 111, 483, 1607, 181, 895, 12923, 21707, 0 }; - static ulong[] dim3137Kuo2Init = { 1, 3, 7, 5, 9, 63, 65, 87, 235, 915, 1569, 3421, 1373, 2159, 353, 0 }; - static ulong[] dim3138Kuo2Init = { 1, 1, 7, 7, 29, 3, 35, 193, 95, 977, 1405, 23, 1135, 5047, 16429, 0 }; - static ulong[] dim3139Kuo2Init = { 1, 1, 7, 3, 7, 57, 123, 111, 33, 781, 613, 3423, 4701, 8727, 22665, 0 }; - static ulong[] dim3140Kuo2Init = { 1, 1, 1, 11, 13, 43, 101, 83, 447, 503, 1955, 2125, 4469, 14937, 24067, 0 }; - static ulong[] dim3141Kuo2Init = { 1, 1, 5, 15, 7, 41, 115, 17, 335, 497, 1753, 1131, 4623, 11483, 5181, 0 }; - static ulong[] dim3142Kuo2Init = { 1, 1, 7, 9, 19, 37, 1, 89, 117, 211, 1203, 2469, 5989, 11429, 31597, 0 }; - static ulong[] dim3143Kuo2Init = { 1, 3, 3, 11, 3, 7, 125, 97, 203, 935, 533, 2607, 6075, 12995, 9997, 0 }; - static ulong[] dim3144Kuo2Init = { 1, 1, 7, 1, 27, 25, 53, 99, 243, 729, 1521, 875, 2363, 3309, 22621, 0 }; - static ulong[] dim3145Kuo2Init = { 1, 3, 3, 1, 21, 7, 79, 105, 363, 227, 9, 2445, 3021, 15177, 19029, 0 }; - static ulong[] dim3146Kuo2Init = { 1, 3, 7, 7, 13, 53, 55, 21, 137, 953, 1583, 3439, 2995, 4447, 19881, 0 }; - static ulong[] dim3147Kuo2Init = { 1, 1, 7, 11, 29, 21, 83, 195, 387, 133, 1135, 1425, 4655, 9171, 19217, 0 }; - static ulong[] dim3148Kuo2Init = { 1, 3, 5, 7, 3, 19, 45, 249, 451, 797, 693, 3511, 7213, 12851, 31915, 0 }; - static ulong[] dim3149Kuo2Init = { 1, 3, 3, 15, 17, 35, 119, 153, 493, 815, 1621, 2305, 7963, 6405, 6253, 0 }; - static ulong[] dim3150Kuo2Init = { 1, 1, 3, 15, 19, 23, 111, 223, 469, 1015, 799, 1453, 7639, 2307, 20595, 0 }; - static ulong[] dim3151Kuo2Init = { 1, 1, 5, 9, 9, 49, 33, 233, 3, 531, 1723, 845, 3585, 13993, 11955, 0 }; - static ulong[] dim3152Kuo2Init = { 1, 1, 7, 7, 1, 7, 3, 217, 191, 1, 2013, 3143, 5919, 3285, 10733, 0 }; - static ulong[] dim3153Kuo2Init = { 1, 1, 3, 15, 25, 9, 93, 127, 471, 51, 1227, 341, 3455, 11015, 21427, 0 }; - static ulong[] dim3154Kuo2Init = { 1, 1, 5, 9, 23, 45, 9, 1, 445, 927, 661, 829, 411, 13531, 30903, 0 }; - static ulong[] dim3155Kuo2Init = { 1, 3, 3, 5, 21, 25, 17, 225, 43, 209, 659, 3681, 3281, 10135, 6121, 0 }; - static ulong[] dim3156Kuo2Init = { 1, 3, 1, 7, 17, 33, 103, 209, 187, 759, 617, 2971, 3563, 12925, 23503, 0 }; - static ulong[] dim3157Kuo2Init = { 1, 3, 5, 13, 21, 13, 35, 65, 507, 95, 695, 961, 7589, 9633, 29065, 0 }; - static ulong[] dim3158Kuo2Init = { 1, 3, 5, 5, 13, 17, 11, 145, 11, 115, 1449, 2361, 2959, 6713, 15345, 0 }; - static ulong[] dim3159Kuo2Init = { 1, 1, 3, 9, 21, 19, 15, 7, 303, 995, 1245, 349, 4117, 10993, 20627, 0 }; - static ulong[] dim3160Kuo2Init = { 1, 3, 1, 3, 1, 9, 21, 43, 259, 725, 1735, 1515, 3465, 10867, 14895, 0 }; - static ulong[] dim3161Kuo2Init = { 1, 1, 1, 3, 7, 25, 57, 29, 435, 663, 383, 1197, 981, 4943, 24527, 0 }; - static ulong[] dim3162Kuo2Init = { 1, 1, 3, 13, 3, 29, 43, 149, 351, 293, 1549, 3177, 6771, 7291, 23227, 0 }; - static ulong[] dim3163Kuo2Init = { 1, 1, 1, 9, 29, 53, 9, 43, 369, 763, 1269, 595, 6559, 13799, 27751, 0 }; - static ulong[] dim3164Kuo2Init = { 1, 1, 3, 3, 7, 53, 79, 167, 121, 761, 1015, 1299, 1523, 55, 4431, 0 }; - static ulong[] dim3165Kuo2Init = { 1, 3, 1, 15, 19, 9, 103, 17, 121, 621, 765, 2225, 4123, 815, 4305, 0 }; - static ulong[] dim3166Kuo2Init = { 1, 3, 7, 7, 29, 59, 43, 73, 505, 755, 617, 2113, 5605, 11887, 10211, 0 }; - static ulong[] dim3167Kuo2Init = { 1, 1, 5, 15, 23, 47, 27, 241, 287, 649, 1601, 2461, 7851, 7901, 24305, 0 }; - static ulong[] dim3168Kuo2Init = { 1, 3, 1, 3, 9, 31, 43, 103, 227, 381, 813, 3871, 2293, 5317, 4907, 0 }; - static ulong[] dim3169Kuo2Init = { 1, 3, 7, 1, 29, 41, 49, 75, 389, 799, 1283, 1823, 6907, 11715, 24101, 0 }; - static ulong[] dim3170Kuo2Init = { 1, 1, 3, 9, 1, 17, 53, 61, 133, 485, 317, 1779, 2437, 6195, 4745, 0 }; - static ulong[] dim3171Kuo2Init = { 1, 3, 7, 11, 1, 55, 79, 147, 511, 29, 495, 1145, 677, 8581, 9491, 0 }; - static ulong[] dim3172Kuo2Init = { 1, 1, 1, 7, 15, 23, 51, 243, 139, 605, 2035, 1039, 1135, 10747, 28225, 0 }; - static ulong[] dim3173Kuo2Init = { 1, 3, 3, 1, 15, 5, 121, 73, 403, 861, 1587, 2985, 2217, 1969, 10459, 0 }; - static ulong[] dim3174Kuo2Init = { 1, 1, 3, 3, 15, 45, 123, 235, 85, 973, 915, 2217, 2405, 4473, 8119, 0 }; - static ulong[] dim3175Kuo2Init = { 1, 1, 3, 3, 29, 29, 9, 47, 173, 121, 861, 1081, 917, 9757, 25923, 0 }; - static ulong[] dim3176Kuo2Init = { 1, 1, 3, 7, 25, 59, 57, 35, 291, 529, 1069, 4037, 4865, 5047, 1133, 0 }; - static ulong[] dim3177Kuo2Init = { 1, 1, 5, 7, 5, 25, 49, 171, 363, 427, 1807, 1903, 6455, 12201, 12043, 0 }; - static ulong[] dim3178Kuo2Init = { 1, 1, 3, 3, 23, 13, 77, 61, 415, 307, 1237, 2785, 1133, 14337, 25755, 0 }; - static ulong[] dim3179Kuo2Init = { 1, 1, 1, 3, 3, 49, 95, 117, 409, 641, 393, 3205, 5047, 4795, 22773, 0 }; - static ulong[] dim3180Kuo2Init = { 1, 3, 7, 5, 15, 25, 39, 37, 15, 735, 1107, 2467, 8037, 6395, 26043, 0 }; - static ulong[] dim3181Kuo2Init = { 1, 1, 3, 7, 15, 51, 53, 211, 223, 165, 217, 3519, 6973, 823, 15733, 0 }; - static ulong[] dim3182Kuo2Init = { 1, 1, 3, 11, 25, 15, 57, 9, 373, 445, 369, 2199, 2793, 12279, 7413, 0 }; - static ulong[] dim3183Kuo2Init = { 1, 1, 3, 1, 29, 13, 37, 91, 429, 5, 467, 813, 2375, 10467, 10373, 0 }; - static ulong[] dim3184Kuo2Init = { 1, 1, 7, 15, 1, 21, 65, 145, 341, 839, 467, 1029, 3127, 11519, 6711, 0 }; - static ulong[] dim3185Kuo2Init = { 1, 1, 3, 11, 29, 55, 115, 65, 501, 375, 1669, 2227, 125, 8059, 15489, 0 }; - static ulong[] dim3186Kuo2Init = { 1, 3, 1, 3, 7, 9, 71, 179, 203, 1017, 107, 49, 1093, 4847, 14383, 0 }; - static ulong[] dim3187Kuo2Init = { 1, 3, 7, 13, 9, 57, 75, 139, 67, 587, 1681, 1717, 459, 7835, 317, 0 }; - static ulong[] dim3188Kuo2Init = { 1, 3, 1, 1, 13, 15, 37, 123, 233, 467, 1425, 2119, 2589, 10087, 31997, 0 }; - static ulong[] dim3189Kuo2Init = { 1, 3, 7, 9, 29, 53, 119, 19, 387, 225, 1845, 2849, 181, 1991, 10323, 0 }; - static ulong[] dim3190Kuo2Init = { 1, 3, 5, 11, 1, 61, 5, 221, 389, 595, 499, 2103, 5967, 4677, 17551, 0 }; - static ulong[] dim3191Kuo2Init = { 1, 1, 7, 5, 31, 9, 63, 121, 505, 997, 939, 7, 7809, 11337, 11825, 0 }; - static ulong[] dim3192Kuo2Init = { 1, 1, 1, 7, 27, 35, 99, 145, 401, 887, 657, 1023, 6215, 15775, 13477, 0 }; - static ulong[] dim3193Kuo2Init = { 1, 3, 3, 15, 7, 39, 35, 63, 395, 621, 1551, 2061, 7817, 6159, 13765, 0 }; - static ulong[] dim3194Kuo2Init = { 1, 1, 7, 3, 13, 5, 17, 19, 469, 541, 707, 1697, 699, 5031, 4121, 0 }; - static ulong[] dim3195Kuo2Init = { 1, 3, 3, 1, 31, 7, 21, 15, 137, 151, 599, 857, 6267, 4725, 20317, 0 }; - static ulong[] dim3196Kuo2Init = { 1, 1, 7, 9, 23, 13, 59, 169, 73, 517, 1209, 2063, 1881, 849, 3263, 0 }; - static ulong[] dim3197Kuo2Init = { 1, 1, 1, 9, 3, 61, 115, 75, 161, 395, 1889, 1229, 6153, 597, 5667, 0 }; - static ulong[] dim3198Kuo2Init = { 1, 1, 3, 11, 5, 31, 37, 163, 469, 237, 91, 3531, 7197, 12673, 13741, 0 }; - static ulong[] dim3199Kuo2Init = { 1, 1, 3, 1, 17, 61, 31, 29, 3, 855, 1703, 2091, 2791, 1963, 7385, 0 }; - static ulong[] dim3200Kuo2Init = { 1, 1, 1, 5, 13, 53, 105, 239, 143, 199, 2003, 4005, 1911, 4965, 31675, 0 }; - static ulong[] dim3201Kuo2Init = { 1, 3, 7, 3, 7, 37, 73, 85, 219, 165, 887, 243, 117, 767, 5519, 0 }; - static ulong[] dim3202Kuo2Init = { 1, 1, 7, 9, 21, 3, 89, 13, 261, 835, 529, 3851, 4905, 2881, 3889, 0 }; - static ulong[] dim3203Kuo2Init = { 1, 1, 7, 3, 15, 41, 21, 89, 137, 959, 839, 4087, 1689, 11347, 17701, 0 }; - static ulong[] dim3204Kuo2Init = { 1, 3, 7, 3, 15, 17, 63, 31, 493, 509, 1079, 3223, 7649, 4377, 20291, 0 }; - static ulong[] dim3205Kuo2Init = { 1, 3, 5, 5, 5, 63, 101, 83, 431, 201, 1965, 1227, 2161, 14661, 2027, 0 }; - static ulong[] dim3206Kuo2Init = { 1, 1, 7, 3, 29, 19, 81, 245, 125, 795, 181, 4017, 4061, 12909, 30591, 0 }; - static ulong[] dim3207Kuo2Init = { 1, 1, 5, 11, 19, 63, 49, 205, 485, 789, 1123, 715, 6553, 5637, 7977, 0 }; - static ulong[] dim3208Kuo2Init = { 1, 3, 3, 7, 13, 63, 113, 63, 187, 515, 725, 3583, 1699, 5165, 21823, 0 }; - static ulong[] dim3209Kuo2Init = { 1, 3, 1, 3, 27, 17, 17, 241, 205, 593, 697, 4023, 7603, 15421, 9679, 0 }; - static ulong[] dim3210Kuo2Init = { 1, 3, 1, 1, 3, 15, 39, 209, 53, 405, 601, 3315, 5487, 12163, 14741, 0 }; - static ulong[] dim3211Kuo2Init = { 1, 1, 3, 13, 31, 9, 9, 159, 187, 307, 1115, 381, 7763, 4231, 2387, 0 }; - static ulong[] dim3212Kuo2Init = { 1, 1, 7, 13, 1, 41, 17, 101, 321, 473, 515, 1959, 7589, 9323, 23947, 0 }; - static ulong[] dim3213Kuo2Init = { 1, 3, 3, 9, 21, 55, 55, 137, 115, 791, 1411, 3543, 8173, 14403, 28019, 0 }; - static ulong[] dim3214Kuo2Init = { 1, 3, 3, 7, 29, 35, 83, 119, 243, 561, 423, 2435, 7613, 1081, 29911, 0 }; - static ulong[] dim3215Kuo2Init = { 1, 3, 1, 15, 13, 21, 9, 205, 3, 901, 1305, 4015, 4045, 11685, 489, 0 }; - static ulong[] dim3216Kuo2Init = { 1, 1, 5, 13, 27, 57, 73, 173, 391, 259, 757, 3177, 3767, 5251, 12381, 0 }; - static ulong[] dim3217Kuo2Init = { 1, 1, 3, 1, 3, 15, 121, 1, 85, 795, 1465, 1247, 5703, 3399, 28519, 0 }; - static ulong[] dim3218Kuo2Init = { 1, 1, 1, 7, 27, 7, 41, 147, 277, 317, 1161, 2205, 1845, 12379, 9121, 0 }; - static ulong[] dim3219Kuo2Init = { 1, 3, 3, 9, 5, 59, 107, 115, 13, 469, 595, 3979, 7563, 521, 6407, 0 }; - static ulong[] dim3220Kuo2Init = { 1, 1, 7, 9, 31, 43, 107, 107, 49, 67, 475, 1371, 3205, 2035, 6349, 0 }; - static ulong[] dim3221Kuo2Init = { 1, 3, 1, 3, 19, 33, 73, 171, 493, 473, 1963, 2453, 2833, 6847, 9899, 0 }; - static ulong[] dim3222Kuo2Init = { 1, 3, 1, 1, 31, 57, 33, 201, 431, 623, 327, 481, 2377, 6533, 30339, 0 }; - static ulong[] dim3223Kuo2Init = { 1, 1, 7, 1, 31, 11, 47, 183, 209, 661, 357, 3809, 4129, 5465, 29141, 0 }; - static ulong[] dim3224Kuo2Init = { 1, 1, 3, 3, 19, 43, 99, 45, 471, 983, 627, 2397, 753, 6735, 24945, 0 }; - static ulong[] dim3225Kuo2Init = { 1, 3, 5, 11, 3, 31, 127, 255, 175, 549, 1743, 3417, 3753, 11497, 5273, 0 }; - static ulong[] dim3226Kuo2Init = { 1, 3, 5, 7, 5, 17, 77, 99, 109, 973, 93, 1287, 1781, 6055, 6987, 0 }; - static ulong[] dim3227Kuo2Init = { 1, 1, 7, 5, 17, 31, 23, 231, 63, 315, 1119, 2175, 5807, 6497, 12991, 0 }; - static ulong[] dim3228Kuo2Init = { 1, 3, 5, 1, 25, 17, 51, 81, 253, 725, 1351, 1941, 3893, 13059, 27373, 0 }; - static ulong[] dim3229Kuo2Init = { 1, 3, 3, 7, 17, 43, 35, 151, 127, 587, 229, 2253, 4299, 10269, 169, 0 }; - static ulong[] dim3230Kuo2Init = { 1, 1, 5, 11, 15, 11, 65, 31, 263, 897, 1345, 3011, 6767, 15851, 16801, 0 }; - static ulong[] dim3231Kuo2Init = { 1, 3, 3, 15, 15, 1, 119, 235, 57, 339, 503, 2633, 1307, 14387, 28759, 0 }; - static ulong[] dim3232Kuo2Init = { 1, 3, 1, 5, 5, 57, 111, 117, 273, 703, 1363, 1579, 97, 15323, 24897, 0 }; - static ulong[] dim3233Kuo2Init = { 1, 3, 5, 13, 23, 29, 43, 171, 347, 651, 869, 3623, 1643, 14647, 16271, 0 }; - static ulong[] dim3234Kuo2Init = { 1, 3, 5, 15, 11, 35, 41, 121, 117, 67, 1649, 1201, 213, 13013, 20403, 0 }; - static ulong[] dim3235Kuo2Init = { 1, 3, 5, 7, 3, 33, 61, 97, 439, 371, 117, 1341, 6513, 11043, 10055, 0 }; - static ulong[] dim3236Kuo2Init = { 1, 3, 3, 1, 25, 9, 25, 13, 121, 593, 1879, 2487, 385, 4341, 11515, 0 }; - static ulong[] dim3237Kuo2Init = { 1, 3, 1, 7, 11, 23, 65, 181, 205, 381, 1749, 3837, 5343, 12389, 27243, 0 }; - static ulong[] dim3238Kuo2Init = { 1, 3, 3, 15, 19, 9, 11, 185, 109, 49, 311, 1225, 7445, 14459, 12631, 0 }; - static ulong[] dim3239Kuo2Init = { 1, 3, 7, 7, 27, 3, 87, 179, 467, 823, 1641, 189, 3489, 3203, 10447, 0 }; - static ulong[] dim3240Kuo2Init = { 1, 3, 5, 3, 5, 15, 117, 139, 39, 497, 1137, 1193, 2281, 12945, 1329, 0 }; - static ulong[] dim3241Kuo2Init = { 1, 3, 7, 15, 21, 9, 111, 115, 461, 987, 1091, 2363, 5453, 3929, 26887, 0 }; - static ulong[] dim3242Kuo2Init = { 1, 1, 1, 11, 19, 25, 113, 65, 301, 491, 1679, 4007, 4709, 4547, 25155, 0 }; - static ulong[] dim3243Kuo2Init = { 1, 3, 1, 15, 29, 23, 87, 209, 471, 247, 633, 2533, 1077, 5079, 10311, 0 }; - static ulong[] dim3244Kuo2Init = { 1, 3, 3, 1, 27, 21, 27, 57, 69, 883, 145, 1559, 6751, 873, 28941, 0 }; - static ulong[] dim3245Kuo2Init = { 1, 1, 7, 5, 23, 63, 113, 57, 243, 133, 1159, 3837, 4781, 6029, 391, 0 }; - static ulong[] dim3246Kuo2Init = { 1, 1, 1, 7, 27, 47, 33, 211, 317, 891, 1955, 3201, 803, 1645, 26669, 0 }; - static ulong[] dim3247Kuo2Init = { 1, 1, 7, 9, 17, 5, 69, 233, 491, 489, 49, 1395, 1907, 10189, 17853, 0 }; - static ulong[] dim3248Kuo2Init = { 1, 1, 7, 13, 9, 29, 25, 169, 469, 1015, 1729, 3095, 281, 15537, 32565, 0 }; - static ulong[] dim3249Kuo2Init = { 1, 1, 1, 7, 23, 63, 55, 65, 1, 913, 343, 3749, 3085, 13557, 32121, 0 }; - static ulong[] dim3250Kuo2Init = { 1, 3, 7, 13, 15, 29, 15, 141, 113, 315, 645, 821, 5083, 12141, 1603, 0 }; - static ulong[] dim3251Kuo2Init = { 1, 3, 5, 11, 19, 7, 73, 245, 139, 923, 731, 211, 7223, 8179, 20811, 0 }; - static ulong[] dim3252Kuo2Init = { 1, 3, 7, 11, 31, 21, 35, 253, 373, 889, 1671, 1069, 3475, 1947, 16129, 0 }; - static ulong[] dim3253Kuo2Init = { 1, 1, 1, 11, 17, 11, 3, 223, 169, 577, 2045, 2591, 2593, 10911, 20657, 0 }; - static ulong[] dim3254Kuo2Init = { 1, 3, 3, 5, 21, 57, 121, 185, 329, 581, 471, 1799, 393, 1059, 19339, 0 }; - static ulong[] dim3255Kuo2Init = { 1, 1, 3, 3, 17, 63, 39, 227, 447, 157, 1803, 239, 93, 5297, 801, 0 }; - static ulong[] dim3256Kuo2Init = { 1, 3, 5, 5, 23, 47, 127, 211, 415, 943, 757, 213, 5071, 5811, 2135, 0 }; - static ulong[] dim3257Kuo2Init = { 1, 3, 1, 5, 7, 63, 95, 83, 307, 241, 511, 1417, 2141, 2599, 1665, 0 }; - static ulong[] dim3258Kuo2Init = { 1, 1, 7, 1, 17, 31, 113, 53, 27, 611, 45, 1909, 6519, 5687, 23335, 0 }; - static ulong[] dim3259Kuo2Init = { 1, 1, 5, 9, 5, 43, 81, 99, 505, 739, 633, 1563, 6385, 14799, 24813, 0 }; - static ulong[] dim3260Kuo2Init = { 1, 3, 7, 13, 19, 47, 11, 87, 403, 763, 483, 3793, 7445, 4865, 13187, 0 }; - static ulong[] dim3261Kuo2Init = { 1, 1, 7, 9, 17, 49, 25, 57, 417, 253, 1901, 115, 3933, 11743, 1925, 0 }; - static ulong[] dim3262Kuo2Init = { 1, 3, 5, 7, 15, 21, 13, 143, 399, 953, 1397, 3905, 7935, 11957, 4817, 0 }; - static ulong[] dim3263Kuo2Init = { 1, 1, 5, 1, 7, 63, 49, 11, 321, 181, 545, 2035, 5339, 2727, 11623, 0 }; - static ulong[] dim3264Kuo2Init = { 1, 3, 7, 1, 15, 13, 49, 101, 499, 831, 427, 531, 4165, 7087, 14077, 0 }; - static ulong[] dim3265Kuo2Init = { 1, 3, 5, 9, 13, 19, 119, 115, 283, 1015, 1189, 2507, 2491, 13467, 10437, 0 }; - static ulong[] dim3266Kuo2Init = { 1, 1, 5, 3, 11, 31, 103, 3, 421, 717, 611, 2711, 2221, 13187, 19973, 0 }; - static ulong[] dim3267Kuo2Init = { 1, 1, 1, 11, 3, 53, 61, 3, 337, 55, 751, 3467, 7851, 3437, 31047, 0 }; - static ulong[] dim3268Kuo2Init = { 1, 1, 1, 5, 1, 57, 81, 127, 425, 965, 1633, 2193, 7061, 2239, 18383, 0 }; - static ulong[] dim3269Kuo2Init = { 1, 1, 5, 15, 11, 55, 49, 31, 497, 715, 1725, 1359, 177, 13011, 11291, 0 }; - static ulong[] dim3270Kuo2Init = { 1, 1, 5, 9, 3, 11, 121, 217, 77, 627, 1857, 41, 7613, 3471, 10591, 0 }; - static ulong[] dim3271Kuo2Init = { 1, 1, 7, 11, 13, 23, 81, 253, 263, 663, 1581, 1839, 1327, 7735, 22843, 0 }; - static ulong[] dim3272Kuo2Init = { 1, 1, 7, 3, 31, 29, 97, 243, 215, 893, 1179, 953, 915, 16003, 32685, 0 }; - static ulong[] dim3273Kuo2Init = { 1, 1, 7, 3, 5, 61, 7, 35, 439, 1023, 1079, 3639, 3179, 8793, 8413, 0 }; - static ulong[] dim3274Kuo2Init = { 1, 1, 5, 13, 31, 1, 99, 199, 181, 75, 283, 1581, 1137, 2725, 27179, 0 }; - static ulong[] dim3275Kuo2Init = { 1, 3, 7, 1, 27, 35, 45, 49, 179, 403, 593, 2849, 2349, 5835, 32533, 0 }; - static ulong[] dim3276Kuo2Init = { 1, 1, 1, 1, 5, 31, 21, 153, 169, 19, 813, 3077, 2569, 12355, 3805, 0 }; - static ulong[] dim3277Kuo2Init = { 1, 1, 5, 11, 1, 15, 77, 31, 17, 827, 2005, 799, 5663, 779, 28605, 0 }; - static ulong[] dim3278Kuo2Init = { 1, 1, 5, 3, 29, 51, 3, 91, 505, 161, 2041, 2841, 269, 33, 21771, 0 }; - static ulong[] dim3279Kuo2Init = { 1, 1, 3, 5, 17, 55, 105, 233, 9, 647, 987, 3801, 1421, 8589, 23389, 0 }; - static ulong[] dim3280Kuo2Init = { 1, 1, 7, 15, 27, 63, 73, 87, 111, 233, 1231, 3631, 4355, 15843, 1227, 0 }; - static ulong[] dim3281Kuo2Init = { 1, 1, 3, 15, 17, 5, 63, 23, 55, 655, 1909, 891, 7873, 11163, 26269, 0 }; - static ulong[] dim3282Kuo2Init = { 1, 1, 1, 5, 19, 7, 47, 31, 41, 229, 1381, 773, 2183, 1687, 15761, 0 }; - static ulong[] dim3283Kuo2Init = { 1, 1, 7, 3, 17, 57, 81, 115, 41, 907, 1353, 981, 2601, 10247, 13753, 0 }; - static ulong[] dim3284Kuo2Init = { 1, 3, 3, 1, 5, 13, 83, 19, 107, 935, 1519, 795, 2035, 5649, 21125, 0 }; - static ulong[] dim3285Kuo2Init = { 1, 1, 3, 9, 21, 7, 77, 229, 85, 837, 1085, 781, 6599, 5645, 15481, 0 }; - static ulong[] dim3286Kuo2Init = { 1, 3, 3, 1, 13, 23, 109, 21, 77, 223, 131, 4013, 7507, 10463, 25621, 0 }; - static ulong[] dim3287Kuo2Init = { 1, 3, 5, 11, 21, 55, 99, 195, 447, 57, 1395, 1283, 377, 15019, 26951, 0 }; - static ulong[] dim3288Kuo2Init = { 1, 3, 5, 13, 13, 35, 119, 39, 161, 609, 247, 2541, 3133, 9625, 12129, 0 }; - static ulong[] dim3289Kuo2Init = { 1, 3, 3, 15, 7, 55, 69, 169, 459, 461, 1359, 255, 4567, 7915, 16883, 0 }; - static ulong[] dim3290Kuo2Init = { 1, 1, 1, 11, 25, 41, 93, 105, 147, 893, 515, 3161, 351, 12079, 3445, 0 }; - static ulong[] dim3291Kuo2Init = { 1, 3, 3, 5, 15, 59, 93, 61, 235, 971, 1203, 2213, 3257, 16001, 20581, 0 }; - static ulong[] dim3292Kuo2Init = { 1, 1, 1, 11, 19, 5, 53, 49, 101, 653, 897, 3761, 8087, 14891, 30595, 0 }; - static ulong[] dim3293Kuo2Init = { 1, 1, 3, 7, 13, 27, 37, 29, 181, 875, 1429, 2483, 2987, 15951, 16217, 0 }; - static ulong[] dim3294Kuo2Init = { 1, 3, 5, 7, 11, 53, 69, 33, 309, 467, 1149, 3103, 3713, 9701, 16637, 0 }; - static ulong[] dim3295Kuo2Init = { 1, 1, 5, 1, 31, 63, 5, 187, 371, 895, 1365, 2671, 5899, 15493, 9685, 0 }; - static ulong[] dim3296Kuo2Init = { 1, 3, 1, 5, 19, 3, 127, 251, 39, 335, 489, 3359, 4939, 413, 521, 0 }; - static ulong[] dim3297Kuo2Init = { 1, 1, 7, 11, 11, 37, 51, 135, 191, 535, 1037, 2365, 381, 8253, 21177, 0 }; - static ulong[] dim3298Kuo2Init = { 1, 1, 3, 13, 9, 23, 77, 147, 93, 793, 1223, 2655, 3873, 6049, 19201, 0 }; - static ulong[] dim3299Kuo2Init = { 1, 3, 5, 5, 15, 41, 21, 217, 149, 965, 1173, 1779, 501, 4829, 17439, 0 }; - static ulong[] dim3300Kuo2Init = { 1, 3, 5, 15, 11, 37, 63, 233, 103, 453, 799, 571, 1991, 439, 26713, 0 }; - static ulong[] dim3301Kuo2Init = { 1, 1, 7, 9, 31, 1, 11, 155, 483, 875, 1943, 1355, 3125, 8771, 30531, 0 }; - static ulong[] dim3302Kuo2Init = { 1, 3, 3, 13, 7, 31, 9, 139, 277, 203, 1937, 31, 4519, 2127, 22557, 0 }; - static ulong[] dim3303Kuo2Init = { 1, 1, 1, 3, 19, 53, 117, 225, 391, 501, 607, 1493, 3119, 10817, 6307, 0 }; - static ulong[] dim3304Kuo2Init = { 1, 1, 3, 11, 3, 19, 3, 51, 507, 245, 1563, 3987, 7461, 4851, 23697, 0 }; - static ulong[] dim3305Kuo2Init = { 1, 3, 3, 9, 1, 39, 49, 21, 39, 631, 1777, 1689, 665, 5657, 26469, 0 }; - static ulong[] dim3306Kuo2Init = { 1, 3, 7, 3, 17, 41, 73, 13, 97, 649, 1737, 653, 5093, 629, 4389, 0 }; - static ulong[] dim3307Kuo2Init = { 1, 3, 5, 1, 13, 9, 99, 149, 389, 151, 313, 2517, 77, 2157, 4713, 0 }; - static ulong[] dim3308Kuo2Init = { 1, 3, 5, 1, 15, 25, 3, 129, 111, 847, 585, 3103, 6237, 8491, 24519, 0 }; - static ulong[] dim3309Kuo2Init = { 1, 1, 3, 1, 11, 25, 71, 229, 325, 51, 537, 3393, 6561, 6871, 30609, 0 }; - static ulong[] dim3310Kuo2Init = { 1, 3, 7, 15, 5, 3, 109, 237, 469, 235, 1703, 525, 2579, 9107, 13261, 0 }; - static ulong[] dim3311Kuo2Init = { 1, 3, 7, 13, 7, 31, 65, 67, 165, 1003, 957, 371, 5857, 16307, 4069, 0 }; - static ulong[] dim3312Kuo2Init = { 1, 1, 7, 15, 7, 63, 51, 199, 63, 259, 1383, 2747, 5945, 8061, 30961, 0 }; - static ulong[] dim3313Kuo2Init = { 1, 1, 1, 7, 13, 43, 67, 143, 407, 369, 1803, 2405, 4737, 5741, 21311, 0 }; - static ulong[] dim3314Kuo2Init = { 1, 3, 7, 11, 19, 25, 127, 251, 325, 327, 169, 3745, 2115, 4591, 12383, 0 }; - static ulong[] dim3315Kuo2Init = { 1, 1, 3, 13, 31, 61, 35, 209, 161, 171, 1155, 531, 5493, 13607, 23809, 0 }; - static ulong[] dim3316Kuo2Init = { 1, 1, 3, 9, 21, 39, 93, 185, 421, 355, 2039, 259, 7309, 6747, 745, 0 }; - static ulong[] dim3317Kuo2Init = { 1, 3, 5, 11, 1, 39, 43, 169, 137, 21, 1377, 3091, 4893, 1197, 1785, 0 }; - static ulong[] dim3318Kuo2Init = { 1, 1, 5, 5, 29, 59, 89, 79, 457, 463, 193, 727, 2505, 10509, 5379, 0 }; - static ulong[] dim3319Kuo2Init = { 1, 3, 3, 9, 23, 23, 59, 35, 425, 47, 1787, 1705, 3469, 14583, 3439, 0 }; - static ulong[] dim3320Kuo2Init = { 1, 1, 7, 5, 27, 5, 85, 51, 31, 277, 851, 2731, 5613, 11305, 23727, 0 }; - static ulong[] dim3321Kuo2Init = { 1, 3, 1, 15, 15, 47, 109, 211, 385, 505, 791, 253, 4123, 13393, 31515, 0 }; - static ulong[] dim3322Kuo2Init = { 1, 3, 5, 3, 25, 9, 73, 35, 203, 721, 1111, 1791, 5241, 15307, 4385, 0 }; - static ulong[] dim3323Kuo2Init = { 1, 3, 5, 1, 9, 43, 127, 127, 191, 21, 1967, 3523, 5959, 5775, 24635, 0 }; - static ulong[] dim3324Kuo2Init = { 1, 3, 7, 5, 7, 23, 75, 37, 307, 375, 1731, 2945, 763, 11723, 32033, 0 }; - static ulong[] dim3325Kuo2Init = { 1, 3, 3, 13, 31, 19, 83, 185, 457, 109, 349, 1085, 7381, 8851, 27633, 0 }; - static ulong[] dim3326Kuo2Init = { 1, 3, 3, 1, 25, 17, 79, 73, 381, 655, 409, 2043, 6803, 9041, 25733, 0 }; - static ulong[] dim3327Kuo2Init = { 1, 3, 5, 7, 17, 9, 61, 47, 429, 507, 1933, 1653, 2057, 15791, 12035, 0 }; - static ulong[] dim3328Kuo2Init = { 1, 1, 7, 1, 5, 57, 31, 83, 223, 281, 1485, 2965, 4543, 9719, 22109, 0 }; - static ulong[] dim3329Kuo2Init = { 1, 1, 3, 3, 5, 11, 69, 65, 229, 87, 1707, 2701, 985, 12261, 32209, 0 }; - static ulong[] dim3330Kuo2Init = { 1, 3, 7, 15, 13, 29, 121, 1, 475, 905, 1843, 571, 5595, 1685, 8061, 0 }; - static ulong[] dim3331Kuo2Init = { 1, 3, 5, 1, 9, 37, 115, 35, 309, 117, 17, 3537, 4491, 13863, 12611, 0 }; - static ulong[] dim3332Kuo2Init = { 1, 1, 7, 15, 9, 1, 79, 135, 95, 417, 633, 2109, 7911, 15009, 32399, 0 }; - static ulong[] dim3333Kuo2Init = { 1, 3, 7, 5, 9, 41, 23, 137, 135, 429, 267, 3787, 4643, 1221, 20257, 0 }; - static ulong[] dim3334Kuo2Init = { 1, 3, 3, 1, 11, 37, 97, 107, 43, 273, 213, 1779, 2317, 7325, 2495, 0 }; - static ulong[] dim3335Kuo2Init = { 1, 1, 3, 9, 13, 57, 29, 29, 5, 45, 633, 3437, 8147, 11819, 16397, 0 }; - static ulong[] dim3336Kuo2Init = { 1, 3, 7, 5, 19, 47, 67, 39, 281, 1003, 1489, 199, 3099, 3925, 17517, 0 }; - static ulong[] dim3337Kuo2Init = { 1, 3, 3, 3, 21, 49, 91, 47, 435, 193, 683, 1845, 6237, 5573, 10647, 0 }; - static ulong[] dim3338Kuo2Init = { 1, 3, 1, 11, 3, 59, 5, 197, 393, 389, 1735, 1417, 2061, 11827, 7587, 0 }; - static ulong[] dim3339Kuo2Init = { 1, 1, 5, 15, 1, 35, 113, 81, 233, 435, 1481, 2007, 6043, 9005, 19277, 0 }; - static ulong[] dim3340Kuo2Init = { 1, 3, 1, 11, 9, 53, 109, 193, 329, 187, 35, 3693, 951, 9735, 5587, 0 }; - static ulong[] dim3341Kuo2Init = { 1, 1, 1, 5, 19, 41, 25, 225, 269, 317, 201, 2817, 971, 2873, 22637, 0 }; - static ulong[] dim3342Kuo2Init = { 1, 3, 7, 1, 9, 47, 105, 219, 69, 633, 1073, 1895, 1759, 12353, 9011, 0 }; - static ulong[] dim3343Kuo2Init = { 1, 1, 7, 11, 11, 59, 3, 163, 361, 157, 1937, 3589, 1531, 9303, 3627, 0 }; - static ulong[] dim3344Kuo2Init = { 1, 1, 3, 9, 31, 15, 23, 5, 447, 59, 1907, 197, 2775, 11303, 32553, 0 }; - static ulong[] dim3345Kuo2Init = { 1, 3, 1, 13, 11, 35, 83, 97, 225, 761, 907, 3107, 1827, 14745, 235, 0 }; - static ulong[] dim3346Kuo2Init = { 1, 3, 1, 13, 13, 37, 127, 55, 511, 861, 1769, 3999, 8135, 445, 12537, 0 }; - static ulong[] dim3347Kuo2Init = { 1, 1, 7, 11, 21, 61, 111, 107, 129, 43, 837, 3811, 3261, 15273, 24319, 0 }; - static ulong[] dim3348Kuo2Init = { 1, 3, 7, 1, 17, 15, 23, 27, 227, 573, 1739, 2611, 3977, 493, 24091, 0 }; - static ulong[] dim3349Kuo2Init = { 1, 3, 3, 5, 17, 59, 17, 61, 443, 215, 1171, 1587, 55, 14417, 30225, 0 }; - static ulong[] dim3350Kuo2Init = { 1, 3, 3, 5, 5, 51, 5, 101, 147, 951, 445, 2203, 6731, 3993, 12935, 0 }; - static ulong[] dim3351Kuo2Init = { 1, 1, 3, 13, 31, 15, 117, 125, 413, 927, 1837, 2781, 2569, 12177, 20551, 0 }; - static ulong[] dim3352Kuo2Init = { 1, 1, 1, 9, 27, 13, 115, 243, 211, 123, 1631, 1277, 1217, 15271, 26377, 0 }; - static ulong[] dim3353Kuo2Init = { 1, 3, 7, 3, 27, 55, 5, 91, 255, 367, 503, 659, 1527, 15907, 4485, 0 }; - static ulong[] dim3354Kuo2Init = { 1, 3, 3, 13, 9, 11, 29, 175, 305, 593, 1209, 551, 7579, 1273, 22545, 0 }; - static ulong[] dim3355Kuo2Init = { 1, 3, 3, 13, 17, 33, 101, 83, 93, 261, 1395, 573, 6665, 10073, 26139, 0 }; - static ulong[] dim3356Kuo2Init = { 1, 1, 3, 7, 25, 35, 93, 11, 29, 941, 525, 457, 1293, 15753, 19273, 0 }; - static ulong[] dim3357Kuo2Init = { 1, 3, 5, 15, 5, 31, 101, 211, 383, 759, 1287, 429, 291, 12347, 12683, 0 }; - static ulong[] dim3358Kuo2Init = { 1, 1, 7, 3, 9, 53, 119, 81, 91, 113, 1525, 1037, 8021, 2913, 11205, 0 }; - static ulong[] dim3359Kuo2Init = { 1, 1, 3, 1, 9, 47, 59, 23, 497, 273, 453, 1063, 2523, 8929, 43, 0 }; - static ulong[] dim3360Kuo2Init = { 1, 1, 3, 9, 1, 23, 65, 147, 327, 851, 177, 4047, 3881, 2885, 21021, 0 }; - static ulong[] dim3361Kuo2Init = { 1, 1, 7, 1, 19, 53, 13, 117, 267, 803, 21, 3825, 2387, 7273, 19753, 0 }; - static ulong[] dim3362Kuo2Init = { 1, 3, 5, 7, 9, 9, 107, 9, 261, 797, 1337, 1535, 663, 6635, 3383, 0 }; - static ulong[] dim3363Kuo2Init = { 1, 1, 7, 13, 13, 27, 65, 75, 375, 805, 1079, 947, 993, 1793, 16235, 0 }; - static ulong[] dim3364Kuo2Init = { 1, 3, 3, 9, 11, 17, 119, 57, 501, 105, 1109, 3607, 1805, 8277, 24869, 0 }; - static ulong[] dim3365Kuo2Init = { 1, 3, 7, 1, 1, 29, 125, 205, 453, 607, 1371, 2169, 2723, 7381, 23411, 0 }; - static ulong[] dim3366Kuo2Init = { 1, 3, 7, 13, 13, 57, 83, 149, 197, 739, 823, 1551, 5329, 10781, 6055, 0 }; - static ulong[] dim3367Kuo2Init = { 1, 3, 7, 1, 5, 33, 9, 237, 37, 733, 879, 1303, 365, 5595, 32425, 0 }; - static ulong[] dim3368Kuo2Init = { 1, 1, 1, 1, 17, 13, 117, 189, 323, 377, 1645, 2143, 4469, 9497, 11573, 0 }; - static ulong[] dim3369Kuo2Init = { 1, 3, 1, 5, 13, 47, 19, 19, 155, 681, 1909, 913, 6985, 11449, 9981, 0 }; - static ulong[] dim3370Kuo2Init = { 1, 3, 7, 11, 29, 55, 73, 113, 291, 865, 239, 209, 67, 10813, 19287, 0 }; - static ulong[] dim3371Kuo2Init = { 1, 3, 5, 9, 3, 7, 27, 119, 267, 649, 1125, 2953, 3393, 3281, 15539, 0 }; - static ulong[] dim3372Kuo2Init = { 1, 3, 3, 13, 9, 41, 25, 145, 233, 475, 873, 631, 2429, 12071, 18123, 0 }; - static ulong[] dim3373Kuo2Init = { 1, 3, 1, 3, 17, 53, 85, 71, 193, 339, 493, 2495, 4369, 7239, 21395, 0 }; - static ulong[] dim3374Kuo2Init = { 1, 3, 1, 3, 25, 51, 87, 11, 291, 659, 455, 1217, 5737, 3263, 15213, 0 }; - static ulong[] dim3375Kuo2Init = { 1, 3, 1, 11, 5, 37, 93, 51, 359, 113, 1847, 4007, 2497, 12287, 16961, 0 }; - static ulong[] dim3376Kuo2Init = { 1, 3, 5, 11, 1, 27, 107, 189, 353, 499, 395, 1717, 6313, 315, 17027, 0 }; - static ulong[] dim3377Kuo2Init = { 1, 1, 3, 3, 15, 57, 105, 107, 17, 769, 1207, 3243, 179, 305, 16425, 0 }; - static ulong[] dim3378Kuo2Init = { 1, 3, 5, 1, 19, 9, 87, 5, 303, 653, 481, 1673, 3101, 7751, 23301, 0 }; - static ulong[] dim3379Kuo2Init = { 1, 1, 5, 9, 31, 39, 67, 225, 287, 285, 1937, 413, 2101, 10941, 32071, 0 }; - static ulong[] dim3380Kuo2Init = { 1, 3, 5, 5, 1, 25, 49, 61, 309, 19, 641, 247, 7909, 13761, 14231, 0 }; - static ulong[] dim3381Kuo2Init = { 1, 1, 5, 5, 13, 31, 55, 141, 223, 573, 895, 2853, 5663, 15519, 10871, 0 }; - static ulong[] dim3382Kuo2Init = { 1, 3, 3, 11, 31, 27, 61, 239, 215, 897, 857, 2591, 6251, 14317, 10973, 0 }; - static ulong[] dim3383Kuo2Init = { 1, 3, 1, 5, 29, 23, 115, 5, 449, 455, 1597, 3329, 4463, 10653, 17079, 0 }; - static ulong[] dim3384Kuo2Init = { 1, 1, 1, 1, 31, 27, 25, 43, 99, 817, 1863, 1563, 7021, 4981, 5049, 0 }; - static ulong[] dim3385Kuo2Init = { 1, 1, 7, 5, 1, 13, 95, 241, 269, 145, 737, 1479, 7469, 10069, 21421, 0 }; - static ulong[] dim3386Kuo2Init = { 1, 1, 5, 5, 21, 47, 111, 153, 411, 763, 2003, 1809, 5887, 4543, 7505, 0 }; - static ulong[] dim3387Kuo2Init = { 1, 3, 3, 7, 1, 31, 75, 131, 103, 873, 1893, 2025, 6525, 57, 19701, 0 }; - static ulong[] dim3388Kuo2Init = { 1, 1, 1, 7, 13, 3, 41, 243, 19, 1007, 365, 601, 7015, 485, 6313, 0 }; - static ulong[] dim3389Kuo2Init = { 1, 3, 5, 9, 9, 49, 27, 47, 139, 837, 43, 2843, 83, 9987, 29817, 0 }; - static ulong[] dim3390Kuo2Init = { 1, 3, 7, 15, 27, 51, 95, 133, 275, 625, 1489, 4077, 3049, 15213, 23817, 0 }; - static ulong[] dim3391Kuo2Init = { 1, 1, 1, 7, 1, 33, 101, 109, 131, 997, 101, 881, 3051, 1215, 4783, 0 }; - static ulong[] dim3392Kuo2Init = { 1, 3, 7, 5, 9, 7, 3, 223, 343, 467, 697, 3441, 4723, 4265, 29517, 0 }; - static ulong[] dim3393Kuo2Init = { 1, 1, 7, 3, 17, 25, 97, 191, 413, 211, 263, 2027, 2025, 6125, 9667, 0 }; - static ulong[] dim3394Kuo2Init = { 1, 1, 7, 11, 15, 15, 57, 151, 351, 187, 103, 1231, 567, 7829, 17941, 0 }; - static ulong[] dim3395Kuo2Init = { 1, 3, 3, 7, 13, 43, 49, 235, 195, 271, 1945, 1459, 2335, 141, 27615, 0 }; - static ulong[] dim3396Kuo2Init = { 1, 1, 7, 9, 5, 49, 123, 231, 133, 781, 697, 157, 2889, 12929, 18099, 0 }; - static ulong[] dim3397Kuo2Init = { 1, 1, 3, 7, 19, 25, 127, 181, 169, 981, 1955, 3289, 2077, 10627, 30383, 0 }; - static ulong[] dim3398Kuo2Init = { 1, 3, 7, 9, 1, 53, 99, 163, 291, 701, 1367, 3941, 3211, 6661, 29143, 0 }; - static ulong[] dim3399Kuo2Init = { 1, 1, 7, 9, 7, 49, 83, 77, 9, 549, 705, 527, 5609, 10933, 27715, 0 }; - static ulong[] dim3400Kuo2Init = { 1, 3, 5, 7, 27, 15, 31, 75, 39, 823, 497, 875, 435, 14427, 30859, 0 }; - static ulong[] dim3401Kuo2Init = { 1, 1, 7, 5, 21, 49, 63, 245, 357, 653, 45, 2053, 169, 7459, 2441, 0 }; - static ulong[] dim3402Kuo2Init = { 1, 3, 1, 13, 7, 53, 109, 167, 243, 585, 1173, 1925, 601, 13899, 29, 0 }; - static ulong[] dim3403Kuo2Init = { 1, 3, 3, 15, 21, 1, 119, 33, 129, 893, 1047, 1223, 3335, 5711, 28213, 0 }; - static ulong[] dim3404Kuo2Init = { 1, 1, 5, 11, 21, 47, 97, 9, 201, 647, 1595, 3091, 3635, 15487, 21375, 0 }; - static ulong[] dim3405Kuo2Init = { 1, 3, 1, 11, 11, 17, 11, 133, 447, 925, 97, 2841, 4147, 15803, 6311, 0 }; - static ulong[] dim3406Kuo2Init = { 1, 3, 1, 7, 13, 27, 27, 201, 105, 37, 399, 1695, 4263, 6081, 21461, 0 }; - static ulong[] dim3407Kuo2Init = { 1, 1, 7, 5, 7, 25, 45, 83, 327, 283, 1799, 691, 2795, 12961, 125, 0 }; - static ulong[] dim3408Kuo2Init = { 1, 1, 5, 11, 23, 23, 11, 221, 189, 353, 887, 3087, 4937, 11335, 29193, 0 }; - static ulong[] dim3409Kuo2Init = { 1, 1, 1, 9, 1, 47, 49, 141, 391, 661, 1289, 3937, 5833, 10731, 26501, 0 }; - static ulong[] dim3410Kuo2Init = { 1, 3, 7, 5, 21, 57, 89, 123, 163, 137, 1575, 4073, 7663, 13611, 11511, 0 }; - static ulong[] dim3411Kuo2Init = { 1, 1, 7, 15, 17, 27, 27, 149, 67, 147, 1069, 353, 3323, 7763, 11549, 0 }; - static ulong[] dim3412Kuo2Init = { 1, 3, 1, 3, 19, 61, 11, 19, 403, 451, 737, 3107, 847, 13403, 25943, 0 }; - static ulong[] dim3413Kuo2Init = { 1, 1, 1, 11, 11, 55, 93, 185, 241, 807, 1017, 1707, 2745, 1923, 20451, 0 }; - static ulong[] dim3414Kuo2Init = { 1, 3, 1, 5, 25, 51, 125, 87, 275, 43, 65, 3327, 3313, 211, 24217, 0 }; - static ulong[] dim3415Kuo2Init = { 1, 3, 3, 7, 23, 9, 3, 207, 367, 939, 423, 3741, 4051, 2673, 25363, 0 }; - static ulong[] dim3416Kuo2Init = { 1, 1, 1, 9, 5, 41, 47, 255, 359, 179, 365, 3037, 6377, 14293, 21925, 0 }; - static ulong[] dim3417Kuo2Init = { 1, 1, 7, 9, 31, 31, 97, 77, 479, 375, 491, 1101, 6717, 5499, 12693, 0 }; - static ulong[] dim3418Kuo2Init = { 1, 1, 3, 1, 29, 55, 75, 209, 231, 15, 49, 3233, 3627, 11307, 11413, 0 }; - static ulong[] dim3419Kuo2Init = { 1, 1, 7, 5, 13, 25, 105, 165, 15, 863, 827, 3691, 3531, 1487, 14615, 0 }; - static ulong[] dim3420Kuo2Init = { 1, 3, 3, 1, 19, 17, 51, 37, 349, 71, 31, 2545, 1151, 6187, 26835, 0 }; - static ulong[] dim3421Kuo2Init = { 1, 3, 3, 13, 21, 43, 19, 81, 307, 751, 61, 3319, 2129, 9275, 18825, 0 }; - static ulong[] dim3422Kuo2Init = { 1, 3, 7, 11, 11, 57, 117, 29, 189, 267, 31, 579, 6103, 10553, 15037, 0 }; - static ulong[] dim3423Kuo2Init = { 1, 3, 3, 5, 7, 41, 101, 149, 43, 693, 797, 2447, 2973, 11177, 5795, 0 }; - static ulong[] dim3424Kuo2Init = { 1, 1, 1, 15, 25, 55, 117, 207, 187, 211, 109, 3719, 8161, 8091, 8301, 0 }; - static ulong[] dim3425Kuo2Init = { 1, 1, 5, 11, 3, 27, 17, 61, 71, 555, 847, 1733, 6171, 6467, 2289, 0 }; - static ulong[] dim3426Kuo2Init = { 1, 3, 7, 15, 31, 57, 103, 173, 127, 513, 2003, 1483, 3495, 1951, 30371, 0 }; - static ulong[] dim3427Kuo2Init = { 1, 3, 7, 1, 13, 3, 107, 63, 77, 647, 1645, 2935, 4019, 595, 21603, 0 }; - static ulong[] dim3428Kuo2Init = { 1, 3, 7, 15, 23, 23, 121, 51, 163, 321, 2005, 3873, 41, 15907, 26881, 0 }; - static ulong[] dim3429Kuo2Init = { 1, 3, 1, 11, 27, 63, 1, 173, 423, 1023, 1123, 1683, 5395, 15017, 31877, 0 }; - static ulong[] dim3430Kuo2Init = { 1, 1, 3, 1, 19, 19, 67, 121, 277, 409, 809, 4061, 6041, 2161, 13845, 0 }; - static ulong[] dim3431Kuo2Init = { 1, 3, 7, 9, 13, 1, 111, 241, 193, 463, 1585, 2787, 2651, 4439, 27315, 0 }; - static ulong[] dim3432Kuo2Init = { 1, 3, 1, 3, 5, 1, 83, 213, 425, 623, 1709, 3523, 4547, 5827, 14637, 0 }; - static ulong[] dim3433Kuo2Init = { 1, 1, 5, 9, 11, 43, 87, 31, 455, 559, 1117, 2541, 6381, 6333, 16025, 0 }; - static ulong[] dim3434Kuo2Init = { 1, 1, 3, 11, 5, 61, 69, 115, 253, 743, 719, 3745, 3739, 5511, 12207, 0 }; - static ulong[] dim3435Kuo2Init = { 1, 3, 7, 1, 31, 63, 11, 239, 217, 569, 749, 2445, 7183, 11169, 15683, 0 }; - static ulong[] dim3436Kuo2Init = { 1, 1, 1, 13, 21, 47, 11, 187, 65, 19, 217, 2205, 5435, 14333, 8095, 0 }; - static ulong[] dim3437Kuo2Init = { 1, 1, 5, 1, 15, 63, 81, 3, 291, 289, 1575, 3499, 5583, 16189, 14587, 0 }; - static ulong[] dim3438Kuo2Init = { 1, 1, 1, 11, 29, 1, 105, 195, 37, 875, 203, 3937, 3661, 1103, 569, 0 }; - static ulong[] dim3439Kuo2Init = { 1, 3, 3, 7, 25, 55, 7, 75, 185, 995, 569, 1861, 1149, 14763, 7581, 0 }; - static ulong[] dim3440Kuo2Init = { 1, 1, 3, 15, 13, 3, 107, 223, 273, 607, 1877, 3595, 3985, 1675, 9387, 0 }; - static ulong[] dim3441Kuo2Init = { 1, 3, 7, 15, 15, 35, 57, 95, 99, 5, 351, 3767, 7617, 7071, 1465, 0 }; - static ulong[] dim3442Kuo2Init = { 1, 1, 7, 1, 13, 11, 19, 169, 381, 245, 99, 1121, 7127, 6145, 625, 0 }; - static ulong[] dim3443Kuo2Init = { 1, 3, 5, 15, 29, 13, 89, 81, 31, 827, 989, 445, 6361, 7953, 5035, 0 }; - static ulong[] dim3444Kuo2Init = { 1, 1, 5, 11, 5, 9, 21, 27, 321, 739, 557, 3953, 3739, 15215, 5467, 0 }; - static ulong[] dim3445Kuo2Init = { 1, 3, 5, 7, 9, 41, 111, 195, 385, 647, 829, 2109, 3313, 2457, 10925, 0 }; - static ulong[] dim3446Kuo2Init = { 1, 3, 7, 1, 9, 47, 107, 15, 367, 385, 969, 1947, 1069, 6929, 16135, 0 }; - static ulong[] dim3447Kuo2Init = { 1, 1, 5, 7, 31, 27, 19, 133, 413, 79, 1051, 173, 1033, 9609, 17485, 0 }; - static ulong[] dim3448Kuo2Init = { 1, 1, 5, 9, 23, 19, 71, 135, 203, 659, 385, 771, 2053, 6803, 27443, 0 }; - static ulong[] dim3449Kuo2Init = { 1, 1, 1, 11, 5, 11, 15, 117, 353, 949, 1873, 3925, 6831, 12609, 20761, 0 }; - static ulong[] dim3450Kuo2Init = { 1, 1, 5, 9, 13, 51, 111, 105, 75, 147, 543, 2177, 2595, 4397, 20075, 0 }; - static ulong[] dim3451Kuo2Init = { 1, 3, 7, 1, 31, 41, 17, 81, 477, 143, 1671, 131, 3861, 7937, 12421, 0 }; - static ulong[] dim3452Kuo2Init = { 1, 1, 7, 9, 29, 55, 59, 141, 407, 287, 1205, 2349, 5033, 15907, 19857, 0 }; - static ulong[] dim3453Kuo2Init = { 1, 3, 7, 11, 5, 7, 123, 183, 333, 547, 849, 3447, 2419, 6873, 16951, 0 }; - static ulong[] dim3454Kuo2Init = { 1, 3, 7, 9, 9, 31, 63, 249, 211, 63, 1577, 235, 621, 4907, 25537, 0 }; - static ulong[] dim3455Kuo2Init = { 1, 1, 1, 1, 13, 41, 1, 37, 455, 111, 1959, 1529, 4029, 10687, 17283, 0 }; - static ulong[] dim3456Kuo2Init = { 1, 3, 1, 7, 9, 31, 105, 63, 39, 409, 1151, 2631, 1491, 2837, 2489, 0 }; - static ulong[] dim3457Kuo2Init = { 1, 3, 1, 5, 23, 63, 61, 31, 229, 685, 1869, 3101, 4285, 4485, 15371, 0 }; - static ulong[] dim3458Kuo2Init = { 1, 3, 1, 5, 17, 1, 9, 149, 239, 393, 1925, 2111, 1035, 16343, 10655, 0 }; - static ulong[] dim3459Kuo2Init = { 1, 1, 5, 15, 5, 35, 107, 155, 381, 119, 1157, 3875, 2647, 3149, 141, 0 }; - static ulong[] dim3460Kuo2Init = { 1, 1, 3, 1, 31, 1, 123, 163, 337, 653, 659, 2011, 2613, 15469, 16925, 0 }; - static ulong[] dim3461Kuo2Init = { 1, 1, 7, 5, 19, 51, 3, 17, 151, 705, 349, 3015, 7791, 9899, 30235, 0 }; - static ulong[] dim3462Kuo2Init = { 1, 1, 3, 11, 25, 55, 51, 201, 511, 67, 857, 1233, 2813, 10031, 17433, 0 }; - static ulong[] dim3463Kuo2Init = { 1, 1, 5, 9, 17, 3, 27, 193, 81, 765, 711, 2551, 2569, 9081, 9997, 0 }; - static ulong[] dim3464Kuo2Init = { 1, 3, 1, 9, 17, 19, 51, 41, 249, 157, 989, 597, 6059, 7699, 14761, 0 }; - static ulong[] dim3465Kuo2Init = { 1, 1, 1, 11, 7, 3, 87, 101, 171, 287, 1259, 1161, 2765, 9293, 1343, 0 }; - static ulong[] dim3466Kuo2Init = { 1, 3, 1, 11, 1, 49, 91, 179, 287, 661, 573, 255, 2873, 12153, 16505, 0 }; - static ulong[] dim3467Kuo2Init = { 1, 3, 1, 5, 27, 9, 101, 15, 173, 327, 1523, 3727, 6089, 195, 29999, 0 }; - static ulong[] dim3468Kuo2Init = { 1, 3, 3, 13, 5, 17, 31, 61, 395, 451, 743, 2337, 7295, 2411, 31039, 0 }; - static ulong[] dim3469Kuo2Init = { 1, 1, 1, 11, 17, 25, 59, 209, 255, 401, 321, 1881, 4539, 5371, 25829, 0 }; - static ulong[] dim3470Kuo2Init = { 1, 3, 5, 1, 21, 15, 57, 11, 233, 13, 1969, 1839, 7923, 11731, 32641, 0 }; - static ulong[] dim3471Kuo2Init = { 1, 1, 1, 15, 15, 11, 69, 179, 167, 867, 1901, 1113, 5613, 1481, 18975, 0 }; - static ulong[] dim3472Kuo2Init = { 1, 3, 3, 11, 15, 61, 1, 35, 111, 347, 141, 2749, 2987, 5587, 12385, 0 }; - static ulong[] dim3473Kuo2Init = { 1, 1, 7, 9, 3, 41, 53, 101, 417, 729, 403, 2043, 453, 2479, 21141, 0 }; - static ulong[] dim3474Kuo2Init = { 1, 1, 3, 7, 3, 55, 47, 227, 331, 425, 1361, 1657, 7231, 727, 4093, 0 }; - static ulong[] dim3475Kuo2Init = { 1, 1, 1, 1, 9, 37, 91, 207, 493, 463, 161, 3887, 543, 8349, 17949, 0 }; - static ulong[] dim3476Kuo2Init = { 1, 3, 3, 15, 25, 9, 89, 221, 293, 997, 969, 3239, 5147, 7173, 11277, 0 }; - static ulong[] dim3477Kuo2Init = { 1, 1, 7, 3, 21, 29, 87, 7, 331, 939, 1919, 5, 113, 2189, 21471, 0 }; - static ulong[] dim3478Kuo2Init = { 1, 3, 3, 5, 11, 47, 67, 119, 5, 357, 981, 4055, 6327, 13281, 185, 0 }; - static ulong[] dim3479Kuo2Init = { 1, 3, 7, 13, 27, 55, 39, 23, 209, 721, 2043, 417, 655, 15333, 5015, 0 }; - static ulong[] dim3480Kuo2Init = { 1, 3, 7, 5, 27, 7, 95, 125, 9, 1001, 557, 2947, 553, 4991, 11517, 0 }; - static ulong[] dim3481Kuo2Init = { 1, 3, 5, 13, 3, 25, 5, 99, 355, 63, 1241, 2559, 4717, 9935, 19245, 0 }; - static ulong[] dim3482Kuo2Init = { 1, 3, 1, 13, 3, 27, 45, 141, 123, 859, 603, 2495, 3815, 4229, 17501, 0 }; - static ulong[] dim3483Kuo2Init = { 1, 3, 5, 3, 13, 53, 5, 157, 33, 493, 1611, 105, 7855, 12173, 6877, 0 }; - static ulong[] dim3484Kuo2Init = { 1, 3, 7, 7, 13, 29, 89, 19, 267, 563, 645, 2637, 6889, 8283, 25807, 0 }; - static ulong[] dim3485Kuo2Init = { 1, 3, 5, 15, 23, 55, 89, 69, 363, 333, 377, 3109, 5125, 1411, 22499, 0 }; - static ulong[] dim3486Kuo2Init = { 1, 1, 5, 3, 29, 5, 11, 151, 455, 667, 1697, 1087, 1147, 12269, 14291, 0 }; - static ulong[] dim3487Kuo2Init = { 1, 3, 7, 11, 1, 29, 21, 209, 173, 719, 1679, 1637, 6835, 8629, 27391, 0 }; - static ulong[] dim3488Kuo2Init = { 1, 3, 7, 7, 23, 47, 125, 145, 93, 425, 2039, 2665, 3219, 12491, 12731, 0 }; - static ulong[] dim3489Kuo2Init = { 1, 1, 3, 9, 19, 55, 99, 253, 39, 189, 559, 1893, 2155, 7165, 7705, 0 }; - static ulong[] dim3490Kuo2Init = { 1, 1, 7, 15, 1, 63, 85, 9, 281, 551, 1697, 1341, 6039, 3315, 26821, 0 }; - static ulong[] dim3491Kuo2Init = { 1, 3, 1, 15, 19, 29, 63, 221, 201, 671, 529, 1221, 4455, 2769, 941, 0 }; - static ulong[] dim3492Kuo2Init = { 1, 3, 5, 11, 23, 17, 113, 167, 173, 17, 1911, 1995, 6459, 1517, 19169, 0 }; - static ulong[] dim3493Kuo2Init = { 1, 3, 5, 7, 23, 7, 77, 231, 157, 237, 1855, 2771, 7871, 13523, 18143, 0 }; - static ulong[] dim3494Kuo2Init = { 1, 3, 5, 5, 17, 49, 59, 175, 269, 765, 1863, 3661, 4979, 7029, 4071, 0 }; - static ulong[] dim3495Kuo2Init = { 1, 3, 3, 7, 31, 53, 9, 89, 353, 557, 1805, 3153, 4761, 14547, 20487, 0 }; - static ulong[] dim3496Kuo2Init = { 1, 1, 1, 15, 23, 45, 31, 151, 299, 745, 1899, 3113, 4177, 107, 28863, 0 }; - static ulong[] dim3497Kuo2Init = { 1, 3, 7, 3, 5, 39, 21, 145, 487, 35, 1891, 3985, 2501, 16217, 11963, 0 }; - static ulong[] dim3498Kuo2Init = { 1, 3, 1, 3, 29, 7, 15, 207, 235, 789, 1195, 253, 6443, 8921, 26009, 0 }; - static ulong[] dim3499Kuo2Init = { 1, 3, 1, 15, 23, 53, 105, 233, 71, 595, 765, 2383, 7959, 3543, 5795, 0 }; - static ulong[] dim3500Kuo2Init = { 1, 3, 1, 9, 1, 13, 95, 113, 311, 839, 1375, 4083, 7621, 4261, 6067, 0 }; - static ulong[] dim3501Kuo2Init = { 1, 1, 3, 1, 25, 41, 111, 185, 15, 779, 375, 927, 3487, 8293, 11101, 0 }; - static ulong[] dim3502Kuo2Init = { 1, 3, 3, 7, 3, 15, 79, 233, 255, 279, 171, 1659, 2131, 3659, 2381, 0 }; - static ulong[] dim3503Kuo2Init = { 1, 3, 5, 15, 21, 47, 19, 163, 481, 135, 875, 1143, 5929, 1269, 30729, 0 }; - static ulong[] dim3504Kuo2Init = { 1, 3, 5, 9, 15, 33, 45, 83, 345, 751, 2045, 3221, 3101, 8727, 3785, 0 }; - static ulong[] dim3505Kuo2Init = { 1, 3, 3, 15, 29, 49, 95, 83, 31, 433, 693, 2459, 3563, 12973, 17627, 0 }; - static ulong[] dim3506Kuo2Init = { 1, 3, 3, 15, 31, 19, 97, 165, 353, 109, 1957, 1493, 3025, 15721, 21733, 0 }; - static ulong[] dim3507Kuo2Init = { 1, 1, 3, 15, 17, 55, 23, 47, 473, 803, 1921, 2523, 6493, 1881, 2277, 0 }; - static ulong[] dim3508Kuo2Init = { 1, 3, 7, 1, 11, 11, 27, 137, 259, 825, 1093, 305, 1289, 9177, 22177, 0 }; - static ulong[] dim3509Kuo2Init = { 1, 1, 3, 3, 5, 13, 85, 191, 319, 533, 1579, 351, 987, 13229, 8727, 0 }; - static ulong[] dim3510Kuo2Init = { 1, 3, 5, 11, 21, 21, 21, 107, 201, 281, 809, 2331, 1513, 10721, 31379, 0 }; - static ulong[] dim3511Kuo2Init = { 1, 3, 3, 3, 1, 21, 55, 157, 487, 303, 891, 2035, 7329, 16203, 11811, 0 }; - static ulong[] dim3512Kuo2Init = { 1, 1, 3, 15, 3, 35, 91, 157, 501, 169, 1437, 1765, 395, 4991, 19543, 0 }; - static ulong[] dim3513Kuo2Init = { 1, 3, 7, 7, 1, 43, 3, 33, 13, 393, 805, 1453, 6409, 3153, 3609, 0 }; - static ulong[] dim3514Kuo2Init = { 1, 3, 5, 9, 25, 57, 13, 189, 333, 639, 1241, 277, 3665, 16025, 12687, 0 }; - static ulong[] dim3515Kuo2Init = { 1, 1, 3, 9, 5, 31, 45, 93, 193, 469, 1325, 3109, 2115, 15903, 2211, 0 }; - static ulong[] dim3516Kuo2Init = { 1, 3, 5, 15, 9, 37, 125, 163, 75, 505, 383, 705, 2155, 15999, 29139, 0 }; - static ulong[] dim3517Kuo2Init = { 1, 1, 1, 5, 13, 33, 37, 101, 459, 943, 821, 975, 5511, 3923, 12037, 0 }; - static ulong[] dim3518Kuo2Init = { 1, 3, 7, 3, 11, 45, 77, 79, 35, 289, 499, 2285, 1179, 953, 19641, 0 }; - static ulong[] dim3519Kuo2Init = { 1, 3, 5, 1, 21, 25, 27, 13, 49, 365, 2047, 3015, 6483, 15287, 21813, 0 }; - static ulong[] dim3520Kuo2Init = { 1, 1, 1, 11, 21, 5, 113, 215, 247, 377, 625, 2481, 7681, 343, 29051, 0 }; - static ulong[] dim3521Kuo2Init = { 1, 1, 3, 15, 17, 33, 85, 143, 97, 443, 2029, 2343, 2539, 6033, 23371, 0 }; - static ulong[] dim3522Kuo2Init = { 1, 1, 7, 13, 31, 31, 59, 135, 415, 1015, 1295, 2477, 1119, 15633, 23699, 0 }; - static ulong[] dim3523Kuo2Init = { 1, 3, 5, 3, 3, 23, 61, 135, 273, 501, 1245, 427, 6981, 12135, 15081, 0 }; - static ulong[] dim3524Kuo2Init = { 1, 3, 7, 1, 15, 35, 15, 127, 57, 813, 1769, 1919, 659, 7051, 30567, 0 }; - static ulong[] dim3525Kuo2Init = { 1, 3, 1, 5, 31, 11, 85, 131, 483, 33, 1311, 1101, 3939, 8531, 21019, 0 }; - static ulong[] dim3526Kuo2Init = { 1, 1, 5, 15, 17, 17, 127, 33, 111, 805, 1139, 2631, 7015, 11253, 13141, 0 }; - static ulong[] dim3527Kuo2Init = { 1, 3, 3, 9, 5, 5, 55, 223, 237, 641, 1081, 1145, 3773, 15829, 2309, 0 }; - static ulong[] dim3528Kuo2Init = { 1, 1, 7, 3, 29, 35, 97, 197, 259, 665, 1101, 2423, 1689, 12363, 16037, 0 }; - static ulong[] dim3529Kuo2Init = { 1, 1, 7, 15, 7, 59, 59, 199, 187, 83, 803, 1391, 6701, 8105, 22967, 0 }; - static ulong[] dim3530Kuo2Init = { 1, 1, 5, 9, 1, 59, 91, 253, 277, 1019, 87, 3727, 3367, 13351, 10217, 0 }; - static ulong[] dim3531Kuo2Init = { 1, 3, 3, 11, 19, 39, 35, 29, 259, 525, 555, 1683, 1885, 8957, 17431, 0 }; - static ulong[] dim3532Kuo2Init = { 1, 1, 1, 5, 3, 5, 99, 49, 19, 211, 135, 1677, 37, 14611, 25219, 0 }; - static ulong[] dim3533Kuo2Init = { 1, 3, 7, 3, 15, 31, 3, 201, 329, 755, 1013, 1917, 785, 14243, 28877, 0 }; - static ulong[] dim3534Kuo2Init = { 1, 3, 5, 15, 3, 13, 113, 41, 123, 157, 165, 125, 5147, 10085, 13903, 0 }; - static ulong[] dim3535Kuo2Init = { 1, 3, 7, 11, 15, 29, 127, 249, 51, 543, 667, 2401, 2623, 2447, 9471, 0 }; - static ulong[] dim3536Kuo2Init = { 1, 3, 3, 1, 7, 55, 127, 165, 235, 271, 1721, 2301, 1705, 8209, 10837, 0 }; - static ulong[] dim3537Kuo2Init = { 1, 1, 3, 15, 31, 27, 49, 13, 33, 797, 1533, 3325, 7257, 21, 16787, 0 }; - static ulong[] dim3538Kuo2Init = { 1, 1, 3, 13, 17, 29, 43, 79, 219, 133, 15, 2707, 5517, 15923, 18125, 0 }; - static ulong[] dim3539Kuo2Init = { 1, 1, 7, 1, 21, 1, 61, 233, 123, 599, 201, 1431, 3637, 7921, 14069, 0 }; - static ulong[] dim3540Kuo2Init = { 1, 3, 3, 9, 1, 1, 113, 187, 189, 1013, 1085, 3693, 337, 9807, 25367, 0 }; - static ulong[] dim3541Kuo2Init = { 1, 3, 3, 13, 11, 13, 125, 243, 77, 671, 177, 647, 1985, 15007, 27919, 0 }; - static ulong[] dim3542Kuo2Init = { 1, 3, 7, 13, 23, 3, 85, 13, 15, 443, 673, 1, 8119, 16227, 4497, 0 }; - static ulong[] dim3543Kuo2Init = { 1, 1, 3, 3, 5, 25, 113, 125, 503, 141, 945, 631, 6413, 2997, 28309, 0 }; - static ulong[] dim3544Kuo2Init = { 1, 3, 5, 5, 15, 37, 7, 169, 423, 917, 485, 3557, 1093, 11613, 11301, 0 }; - static ulong[] dim3545Kuo2Init = { 1, 1, 7, 3, 5, 35, 45, 99, 215, 537, 1055, 3109, 7745, 15741, 30499, 0 }; - static ulong[] dim3546Kuo2Init = { 1, 3, 5, 13, 19, 21, 37, 127, 83, 489, 1809, 2479, 5875, 2559, 13593, 0 }; - static ulong[] dim3547Kuo2Init = { 1, 1, 3, 15, 11, 31, 19, 111, 245, 619, 793, 453, 2557, 16269, 2823, 0 }; - static ulong[] dim3548Kuo2Init = { 1, 3, 3, 7, 31, 1, 99, 255, 187, 277, 71, 1985, 3919, 8445, 10791, 0 }; - static ulong[] dim3549Kuo2Init = { 1, 3, 1, 11, 25, 1, 63, 5, 219, 601, 1155, 2411, 7673, 8979, 23729, 0 }; - static ulong[] dim3550Kuo2Init = { 1, 1, 1, 11, 31, 59, 11, 37, 361, 145, 879, 2655, 3591, 13615, 25559, 0 }; - static ulong[] dim3551Kuo2Init = { 1, 3, 5, 7, 15, 5, 117, 175, 417, 825, 585, 1429, 5163, 335, 32281, 0 }; - static ulong[] dim3552Kuo2Init = { 1, 1, 1, 5, 27, 9, 107, 181, 493, 651, 1317, 2059, 4155, 15039, 27693, 0 }; - static ulong[] dim3553Kuo2Init = { 1, 3, 7, 3, 1, 11, 13, 187, 173, 991, 1743, 2403, 5279, 11387, 11035, 0 }; - static ulong[] dim3554Kuo2Init = { 1, 3, 1, 11, 31, 39, 87, 63, 177, 581, 609, 3315, 4859, 9597, 29901, 0 }; - static ulong[] dim3555Kuo2Init = { 1, 3, 3, 11, 15, 47, 1, 53, 91, 39, 37, 1697, 6719, 383, 1793, 0 }; - static ulong[] dim3556Kuo2Init = { 1, 3, 5, 5, 7, 19, 123, 167, 509, 585, 1153, 1803, 987, 2633, 14177, 0 }; - static ulong[] dim3557Kuo2Init = { 1, 1, 5, 7, 9, 5, 59, 137, 209, 95, 519, 177, 5627, 7843, 23207, 0 }; - static ulong[] dim3558Kuo2Init = { 1, 1, 1, 15, 7, 3, 89, 31, 125, 391, 545, 3781, 985, 7355, 27935, 0 }; - static ulong[] dim3559Kuo2Init = { 1, 3, 7, 3, 31, 11, 7, 147, 155, 421, 195, 861, 3787, 10843, 2239, 0 }; - static ulong[] dim3560Kuo2Init = { 1, 1, 3, 15, 23, 29, 71, 79, 279, 157, 853, 421, 6499, 7695, 5527, 0 }; - static ulong[] dim3561Kuo2Init = { 1, 3, 3, 11, 3, 63, 49, 199, 5, 457, 479, 3419, 6649, 14259, 17789, 0 }; - static ulong[] dim3562Kuo2Init = { 1, 1, 3, 3, 23, 7, 85, 105, 281, 929, 1487, 3797, 3487, 15959, 25859, 0 }; - static ulong[] dim3563Kuo2Init = { 1, 3, 5, 5, 23, 27, 33, 5, 283, 853, 1939, 3745, 2995, 14715, 32739, 0 }; - static ulong[] dim3564Kuo2Init = { 1, 3, 3, 5, 9, 7, 111, 53, 299, 237, 1263, 2053, 6359, 15617, 29347, 0 }; - static ulong[] dim3565Kuo2Init = { 1, 3, 3, 13, 29, 61, 55, 181, 49, 377, 729, 117, 8125, 15317, 32363, 0 }; - static ulong[] dim3566Kuo2Init = { 1, 1, 7, 1, 9, 31, 77, 107, 21, 375, 1719, 1701, 5439, 4187, 32397, 0 }; - static ulong[] dim3567Kuo2Init = { 1, 1, 3, 11, 31, 41, 101, 1, 171, 401, 1711, 3027, 161, 441, 15589, 0 }; - static ulong[] dim3568Kuo2Init = { 1, 1, 3, 15, 25, 35, 7, 85, 45, 409, 1769, 767, 2615, 1313, 7031, 0 }; - static ulong[] dim3569Kuo2Init = { 1, 3, 5, 7, 29, 7, 73, 25, 397, 767, 315, 2105, 4677, 12081, 7763, 0 }; - static ulong[] dim3570Kuo2Init = { 1, 3, 5, 13, 31, 63, 87, 29, 81, 969, 1931, 3713, 7217, 15899, 20505, 0 }; - static ulong[] dim3571Kuo2Init = { 1, 1, 5, 3, 15, 31, 121, 141, 209, 697, 941, 1565, 1363, 11919, 24479, 0 }; - static ulong[] dim3572Kuo2Init = { 1, 1, 7, 15, 23, 9, 5, 179, 437, 259, 1223, 2159, 4825, 2977, 20851, 0 }; - static ulong[] dim3573Kuo2Init = { 1, 1, 1, 13, 13, 25, 33, 169, 91, 1001, 1931, 1853, 6173, 5411, 21081, 0 }; - static ulong[] dim3574Kuo2Init = { 1, 1, 1, 13, 1, 53, 109, 53, 345, 519, 771, 1673, 6721, 3585, 6289, 0 }; - static ulong[] dim3575Kuo2Init = { 1, 3, 3, 3, 27, 37, 77, 243, 207, 791, 1585, 1965, 3327, 4719, 7121, 0 }; - static ulong[] dim3576Kuo2Init = { 1, 3, 1, 7, 3, 15, 115, 175, 303, 59, 835, 3347, 6055, 4959, 6963, 0 }; - static ulong[] dim3577Kuo2Init = { 1, 3, 5, 1, 11, 5, 99, 139, 351, 709, 281, 2635, 379, 2543, 29879, 0 }; - static ulong[] dim3578Kuo2Init = { 1, 3, 1, 11, 7, 9, 117, 209, 221, 667, 491, 2833, 1113, 12289, 7947, 0 }; - static ulong[] dim3579Kuo2Init = { 1, 3, 5, 9, 17, 11, 11, 43, 475, 169, 1167, 2601, 2733, 243, 17279, 0 }; - static ulong[] dim3580Kuo2Init = { 1, 1, 5, 15, 31, 43, 7, 107, 309, 993, 635, 3779, 1041, 9997, 23049, 0 }; - static ulong[] dim3581Kuo2Init = { 1, 3, 5, 9, 21, 15, 21, 41, 451, 1021, 131, 1539, 7147, 1639, 31157, 0 }; - static ulong[] dim3582Kuo2Init = { 1, 1, 3, 1, 25, 37, 67, 91, 463, 63, 653, 4045, 1255, 3315, 10747, 0 }; - static ulong[] dim3583Kuo2Init = { 1, 1, 3, 3, 29, 3, 95, 125, 477, 845, 563, 3095, 2985, 8935, 23247, 0 }; - static ulong[] dim3584Kuo2Init = { 1, 3, 5, 13, 11, 5, 21, 193, 121, 857, 997, 3487, 4613, 12231, 7819, 0 }; - static ulong[] dim3585Kuo2Init = { 1, 1, 3, 15, 27, 1, 65, 219, 241, 99, 1193, 3157, 7641, 10327, 25241, 0 }; - static ulong[] dim3586Kuo2Init = { 1, 3, 7, 1, 3, 25, 61, 191, 501, 219, 1863, 4039, 5879, 11203, 10581, 0 }; - static ulong[] dim3587Kuo2Init = { 1, 1, 5, 3, 23, 39, 81, 37, 477, 969, 1, 1161, 7171, 3595, 375, 0 }; - static ulong[] dim3588Kuo2Init = { 1, 3, 3, 3, 21, 17, 99, 101, 165, 849, 607, 1863, 6675, 13557, 3349, 0 }; - static ulong[] dim3589Kuo2Init = { 1, 3, 5, 15, 9, 1, 125, 93, 211, 971, 1275, 545, 3625, 1503, 10735, 0 }; - static ulong[] dim3590Kuo2Init = { 1, 3, 3, 7, 19, 53, 1, 169, 453, 227, 425, 2831, 6751, 11693, 20483, 0 }; - static ulong[] dim3591Kuo2Init = { 1, 1, 1, 3, 9, 19, 121, 203, 55, 485, 37, 3977, 2193, 9819, 4635, 0 }; - static ulong[] dim3592Kuo2Init = { 1, 3, 5, 15, 17, 35, 121, 207, 233, 149, 1607, 3599, 1013, 2295, 9113, 0 }; - static ulong[] dim3593Kuo2Init = { 1, 3, 3, 13, 29, 17, 39, 85, 47, 477, 1967, 701, 1063, 3521, 23583, 0 }; - static ulong[] dim3594Kuo2Init = { 1, 3, 3, 3, 23, 57, 69, 49, 55, 81, 1195, 347, 3869, 4843, 97, 0 }; - static ulong[] dim3595Kuo2Init = { 1, 3, 3, 1, 9, 19, 31, 199, 173, 5, 1557, 2669, 5471, 7203, 27289, 0 }; - static ulong[] dim3596Kuo2Init = { 1, 3, 3, 3, 3, 1, 121, 195, 193, 359, 1269, 973, 3443, 1669, 31895, 0 }; - static ulong[] dim3597Kuo2Init = { 1, 1, 3, 7, 3, 43, 39, 77, 149, 111, 425, 1567, 1289, 13443, 30175, 0 }; - static ulong[] dim3598Kuo2Init = { 1, 3, 3, 5, 15, 55, 67, 209, 167, 439, 825, 3165, 6537, 10291, 2561, 0 }; - static ulong[] dim3599Kuo2Init = { 1, 1, 5, 7, 1, 27, 49, 67, 123, 905, 759, 1471, 4379, 8211, 1829, 0 }; - static ulong[] dim3600Kuo2Init = { 1, 1, 7, 13, 23, 7, 99, 169, 349, 889, 1671, 3039, 6757, 7071, 20707, 0 }; - static ulong[] dim3601Kuo2Init = { 1, 3, 3, 5, 21, 59, 103, 167, 69, 77, 155, 301, 6647, 13487, 19241, 0 }; - static ulong[] dim3602Kuo2Init = { 1, 1, 7, 9, 5, 53, 19, 17, 239, 691, 1079, 3485, 4941, 1769, 6953, 0 }; - static ulong[] dim3603Kuo2Init = { 1, 3, 5, 13, 15, 37, 87, 137, 205, 743, 965, 3911, 1421, 3003, 26639, 0 }; - static ulong[] dim3604Kuo2Init = { 1, 1, 5, 7, 31, 17, 49, 151, 159, 323, 1393, 1677, 2335, 289, 30059, 0 }; - static ulong[] dim3605Kuo2Init = { 1, 1, 7, 11, 25, 37, 93, 221, 441, 329, 421, 903, 2803, 11455, 20521, 0 }; - static ulong[] dim3606Kuo2Init = { 1, 3, 5, 3, 11, 1, 127, 231, 451, 333, 1501, 1353, 1741, 7149, 17527, 0 }; - static ulong[] dim3607Kuo2Init = { 1, 1, 7, 9, 25, 33, 101, 255, 69, 693, 1579, 2307, 6071, 6711, 20071, 0 }; - static ulong[] dim3608Kuo2Init = { 1, 3, 5, 15, 29, 61, 39, 31, 193, 573, 1151, 2237, 125, 7851, 29569, 0 }; - static ulong[] dim3609Kuo2Init = { 1, 3, 5, 15, 25, 15, 93, 93, 309, 765, 23, 2111, 7001, 3885, 18391, 0 }; - static ulong[] dim3610Kuo2Init = { 1, 1, 1, 5, 29, 9, 119, 165, 127, 847, 753, 4089, 5739, 10385, 28691, 0 }; - static ulong[] dim3611Kuo2Init = { 1, 1, 1, 7, 5, 23, 41, 39, 429, 851, 1221, 3817, 8049, 14547, 9277, 0 }; - static ulong[] dim3612Kuo2Init = { 1, 3, 7, 1, 7, 23, 105, 231, 241, 49, 1083, 3903, 1469, 11055, 27949, 0 }; - static ulong[] dim3613Kuo2Init = { 1, 1, 7, 15, 9, 11, 127, 83, 425, 671, 657, 2431, 1003, 2997, 5593, 0 }; - static ulong[] dim3614Kuo2Init = { 1, 3, 1, 13, 15, 35, 73, 193, 155, 183, 2033, 2385, 7979, 8551, 2507, 0 }; - static ulong[] dim3615Kuo2Init = { 1, 3, 5, 9, 29, 43, 59, 17, 227, 159, 1839, 4047, 1667, 2541, 30517, 0 }; - static ulong[] dim3616Kuo2Init = { 1, 3, 7, 9, 31, 45, 109, 243, 163, 871, 951, 2463, 5573, 8415, 16857, 0 }; - static ulong[] dim3617Kuo2Init = { 1, 3, 7, 7, 11, 57, 93, 243, 227, 863, 483, 2371, 6781, 6811, 23423, 0 }; - static ulong[] dim3618Kuo2Init = { 1, 3, 1, 1, 13, 9, 113, 3, 207, 735, 1021, 1933, 6635, 13609, 19651, 0 }; - static ulong[] dim3619Kuo2Init = { 1, 1, 7, 9, 5, 33, 33, 159, 273, 291, 159, 1693, 217, 12487, 21853, 0 }; - static ulong[] dim3620Kuo2Init = { 1, 3, 1, 13, 27, 51, 65, 117, 485, 471, 29, 3929, 4509, 13577, 6745, 0 }; - static ulong[] dim3621Kuo2Init = { 1, 3, 3, 13, 5, 29, 23, 81, 353, 727, 1437, 3239, 717, 13857, 18881, 0 }; - static ulong[] dim3622Kuo2Init = { 1, 3, 1, 1, 11, 41, 97, 73, 271, 847, 471, 2857, 691, 10951, 31465, 0 }; - static ulong[] dim3623Kuo2Init = { 1, 1, 1, 9, 11, 59, 3, 71, 235, 715, 1349, 199, 2853, 13641, 5025, 0 }; - static ulong[] dim3624Kuo2Init = { 1, 3, 1, 9, 23, 7, 23, 49, 31, 145, 533, 2625, 207, 3661, 25215, 0 }; - static ulong[] dim3625Kuo2Init = { 1, 3, 5, 15, 17, 17, 53, 129, 105, 285, 1423, 3985, 8015, 3565, 24495, 0 }; - static ulong[] dim3626Kuo2Init = { 1, 1, 1, 13, 7, 29, 93, 123, 167, 845, 69, 2297, 543, 9165, 4029, 0 }; - static ulong[] dim3627Kuo2Init = { 1, 3, 7, 15, 19, 57, 71, 99, 95, 165, 1875, 4011, 4779, 4057, 16331, 0 }; - static ulong[] dim3628Kuo2Init = { 1, 1, 5, 11, 19, 43, 45, 83, 383, 111, 1859, 2767, 1469, 3687, 18343, 0 }; - static ulong[] dim3629Kuo2Init = { 1, 1, 5, 1, 11, 7, 63, 51, 487, 609, 1619, 3399, 1, 7253, 24325, 0 }; - static ulong[] dim3630Kuo2Init = { 1, 3, 3, 7, 29, 27, 83, 61, 353, 913, 1359, 689, 7741, 3357, 7731, 0 }; - static ulong[] dim3631Kuo2Init = { 1, 1, 1, 7, 31, 9, 5, 221, 177, 379, 1953, 3389, 3861, 10265, 1347, 0 }; - static ulong[] dim3632Kuo2Init = { 1, 3, 5, 13, 7, 13, 57, 9, 233, 601, 719, 1855, 6481, 9987, 16463, 0 }; - static ulong[] dim3633Kuo2Init = { 1, 1, 3, 1, 15, 27, 67, 211, 289, 969, 1719, 2329, 3665, 7133, 24645, 0 }; - static ulong[] dim3634Kuo2Init = { 1, 1, 3, 9, 21, 37, 63, 11, 19, 797, 1591, 2037, 7731, 12533, 2799, 0 }; - static ulong[] dim3635Kuo2Init = { 1, 3, 5, 9, 15, 37, 1, 123, 209, 321, 737, 837, 561, 2631, 18547, 0 }; - static ulong[] dim3636Kuo2Init = { 1, 3, 1, 1, 13, 33, 27, 119, 407, 675, 903, 2229, 1963, 3857, 5795, 0 }; - static ulong[] dim3637Kuo2Init = { 1, 1, 5, 5, 9, 31, 25, 115, 471, 353, 113, 3297, 87, 9413, 25209, 0 }; - static ulong[] dim3638Kuo2Init = { 1, 3, 5, 7, 23, 27, 29, 95, 387, 747, 155, 3991, 3505, 975, 6371, 0 }; - static ulong[] dim3639Kuo2Init = { 1, 1, 5, 13, 15, 45, 3, 213, 299, 775, 525, 2639, 491, 12039, 20295, 0 }; - static ulong[] dim3640Kuo2Init = { 1, 1, 7, 15, 5, 47, 59, 131, 165, 93, 583, 3823, 7781, 16339, 16523, 0 }; - static ulong[] dim3641Kuo2Init = { 1, 3, 5, 3, 25, 61, 23, 75, 343, 15, 347, 259, 4621, 8275, 10323, 0 }; - static ulong[] dim3642Kuo2Init = { 1, 3, 3, 13, 7, 25, 1, 153, 199, 225, 1217, 161, 1185, 10775, 6709, 0 }; - static ulong[] dim3643Kuo2Init = { 1, 1, 1, 1, 1, 49, 27, 67, 411, 425, 1385, 3921, 6373, 14581, 25159, 0 }; - static ulong[] dim3644Kuo2Init = { 1, 1, 1, 11, 5, 59, 125, 239, 391, 823, 969, 3287, 7257, 5405, 15, 0 }; - static ulong[] dim3645Kuo2Init = { 1, 1, 5, 1, 1, 17, 109, 145, 289, 601, 1539, 807, 1123, 14541, 15885, 0 }; - static ulong[] dim3646Kuo2Init = { 1, 1, 3, 9, 23, 29, 119, 79, 253, 921, 1935, 4047, 7639, 10419, 26597, 0 }; - static ulong[] dim3647Kuo2Init = { 1, 1, 5, 11, 27, 53, 63, 123, 85, 121, 481, 3581, 4545, 7275, 981, 0 }; - static ulong[] dim3648Kuo2Init = { 1, 3, 3, 1, 27, 5, 43, 247, 299, 411, 299, 2545, 4403, 9903, 16161, 0 }; - static ulong[] dim3649Kuo2Init = { 1, 3, 1, 11, 29, 21, 83, 37, 425, 741, 899, 3643, 6641, 5241, 3627, 0 }; - static ulong[] dim3650Kuo2Init = { 1, 1, 7, 9, 11, 23, 43, 191, 225, 101, 1423, 927, 1303, 15417, 25553, 0 }; - static ulong[] dim3651Kuo2Init = { 1, 3, 1, 1, 23, 47, 103, 177, 437, 113, 295, 699, 1225, 8259, 19469, 0 }; - static ulong[] dim3652Kuo2Init = { 1, 1, 7, 3, 13, 61, 119, 231, 33, 217, 1419, 989, 4413, 9171, 1199, 0 }; - static ulong[] dim3653Kuo2Init = { 1, 1, 1, 1, 5, 13, 87, 185, 69, 471, 1665, 2201, 5889, 7931, 2913, 0 }; - static ulong[] dim3654Kuo2Init = { 1, 1, 1, 15, 17, 7, 111, 27, 91, 127, 301, 3641, 561, 6697, 16767, 0 }; - static ulong[] dim3655Kuo2Init = { 1, 3, 3, 9, 11, 25, 127, 139, 355, 475, 821, 843, 493, 2713, 16877, 0 }; - static ulong[] dim3656Kuo2Init = { 1, 3, 5, 7, 27, 19, 51, 127, 211, 869, 339, 2469, 1515, 9007, 28807, 0 }; - static ulong[] dim3657Kuo2Init = { 1, 1, 3, 7, 15, 23, 79, 49, 185, 465, 1165, 1103, 5975, 13867, 30039, 0 }; - static ulong[] dim3658Kuo2Init = { 1, 3, 1, 5, 27, 41, 49, 195, 23, 441, 1225, 3861, 6661, 7261, 25415, 0 }; - static ulong[] dim3659Kuo2Init = { 1, 1, 3, 3, 27, 41, 57, 139, 87, 403, 1351, 2063, 5445, 4559, 7181, 0 }; - static ulong[] dim3660Kuo2Init = { 1, 1, 3, 15, 7, 35, 43, 177, 63, 1021, 1157, 3831, 1515, 8117, 16567, 0 }; - static ulong[] dim3661Kuo2Init = { 1, 3, 7, 9, 5, 47, 59, 221, 415, 541, 857, 257, 6961, 16349, 28975, 0 }; - static ulong[] dim3662Kuo2Init = { 1, 3, 5, 9, 13, 55, 55, 63, 7, 817, 693, 1183, 7417, 7087, 31173, 0 }; - static ulong[] dim3663Kuo2Init = { 1, 3, 5, 9, 1, 29, 17, 15, 417, 559, 155, 495, 6269, 11163, 15073, 0 }; - static ulong[] dim3664Kuo2Init = { 1, 1, 5, 1, 29, 59, 49, 253, 489, 657, 1723, 1969, 471, 10821, 3527, 0 }; - static ulong[] dim3665Kuo2Init = { 1, 1, 1, 5, 29, 33, 121, 9, 73, 33, 89, 3419, 6491, 5361, 31587, 0 }; - static ulong[] dim3666Kuo2Init = { 1, 3, 3, 5, 1, 49, 121, 25, 481, 813, 607, 757, 5493, 4353, 14355, 0 }; - static ulong[] dim3667Kuo2Init = { 1, 1, 1, 1, 21, 45, 61, 101, 357, 875, 1381, 1731, 6505, 12891, 19595, 54305, 0 }; - static ulong[] dim3668Kuo2Init = { 1, 3, 7, 7, 19, 55, 99, 131, 309, 303, 1575, 3241, 6799, 6543, 26973, 46843, 0 }; - static ulong[] dim3669Kuo2Init = { 1, 1, 3, 3, 27, 11, 63, 237, 13, 949, 1359, 1563, 5501, 5293, 923, 3413, 0 }; - static ulong[] dim3670Kuo2Init = { 1, 1, 3, 7, 13, 55, 117, 143, 225, 161, 805, 3259, 4113, 8457, 461, 55507, 0 }; - static ulong[] dim3671Kuo2Init = { 1, 1, 1, 15, 15, 57, 127, 249, 409, 885, 587, 285, 7087, 11613, 725, 61955, 0 }; - static ulong[] dim3672Kuo2Init = { 1, 1, 3, 9, 21, 5, 127, 179, 193, 683, 2045, 2555, 6707, 63, 815, 57953, 0 }; - static ulong[] dim3673Kuo2Init = { 1, 3, 7, 7, 25, 45, 49, 37, 289, 431, 719, 3071, 7343, 1377, 18515, 33777, 0 }; - static ulong[] dim3674Kuo2Init = { 1, 3, 3, 7, 19, 5, 127, 29, 385, 895, 1951, 3817, 3277, 7677, 19781, 31181, 0 }; - static ulong[] dim3675Kuo2Init = { 1, 3, 3, 9, 19, 25, 105, 123, 445, 923, 801, 455, 955, 5529, 29133, 47531, 0 }; - static ulong[] dim3676Kuo2Init = { 1, 1, 3, 11, 1, 15, 51, 5, 27, 335, 523, 2859, 5605, 15197, 14669, 29623, 0 }; - static ulong[] dim3677Kuo2Init = { 1, 1, 3, 1, 11, 53, 97, 229, 477, 991, 749, 607, 6833, 6817, 2397, 31543, 0 }; - static ulong[] dim3678Kuo2Init = { 1, 3, 3, 9, 9, 45, 123, 201, 129, 587, 1373, 3733, 2331, 9741, 29441, 24711, 0 }; - static ulong[] dim3679Kuo2Init = { 1, 1, 7, 9, 1, 53, 29, 99, 475, 227, 1955, 351, 2583, 2335, 1821, 21105, 0 }; - static ulong[] dim3680Kuo2Init = { 1, 1, 7, 7, 13, 7, 121, 121, 163, 325, 13, 779, 4173, 7285, 26205, 19693, 0 }; - static ulong[] dim3681Kuo2Init = { 1, 1, 3, 13, 17, 23, 23, 167, 131, 821, 933, 1919, 853, 7525, 8195, 7357, 0 }; - static ulong[] dim3682Kuo2Init = { 1, 1, 5, 9, 21, 29, 97, 105, 85, 865, 459, 1405, 5767, 8379, 23397, 35269, 0 }; - static ulong[] dim3683Kuo2Init = { 1, 3, 3, 15, 7, 41, 125, 107, 507, 323, 149, 3475, 1149, 8811, 8295, 20543, 0 }; - static ulong[] dim3684Kuo2Init = { 1, 1, 5, 11, 13, 35, 41, 249, 195, 603, 873, 3825, 1679, 11727, 13839, 22241, 0 }; - static ulong[] dim3685Kuo2Init = { 1, 3, 5, 3, 13, 15, 19, 113, 141, 7, 627, 1285, 6701, 15921, 4235, 30879, 0 }; - static ulong[] dim3686Kuo2Init = { 1, 1, 7, 9, 15, 57, 65, 239, 49, 657, 673, 4039, 5493, 2487, 1807, 14341, 0 }; - static ulong[] dim3687Kuo2Init = { 1, 1, 1, 13, 25, 47, 19, 191, 177, 163, 1721, 3473, 6667, 10017, 19863, 43803, 0 }; - static ulong[] dim3688Kuo2Init = { 1, 3, 5, 11, 15, 39, 33, 95, 353, 121, 503, 3025, 4773, 3853, 14263, 61149, 0 }; - static ulong[] dim3689Kuo2Init = { 1, 1, 5, 3, 1, 57, 7, 105, 363, 797, 635, 23, 1795, 13501, 45, 22081, 0 }; - static ulong[] dim3690Kuo2Init = { 1, 3, 7, 15, 19, 21, 9, 237, 249, 641, 1599, 3623, 2941, 12917, 5511, 18017, 0 }; - static ulong[] dim3691Kuo2Init = { 1, 1, 5, 9, 17, 57, 81, 165, 315, 985, 1965, 3571, 2693, 11591, 13675, 36739, 0 }; - static ulong[] dim3692Kuo2Init = { 1, 1, 7, 15, 5, 3, 11, 247, 79, 707, 1601, 2301, 7281, 4871, 26735, 14277, 0 }; - static ulong[] dim3693Kuo2Init = { 1, 1, 5, 7, 17, 27, 101, 211, 507, 95, 1333, 2919, 1251, 3905, 1897, 12791, 0 }; - static ulong[] dim3694Kuo2Init = { 1, 3, 5, 15, 29, 15, 119, 3, 181, 621, 349, 2509, 295, 15719, 1593, 27333, 0 }; - static ulong[] dim3695Kuo2Init = { 1, 1, 7, 9, 9, 29, 75, 245, 353, 147, 1197, 2571, 7033, 15903, 28319, 7733, 0 }; - static ulong[] dim3696Kuo2Init = { 1, 1, 7, 11, 19, 23, 53, 41, 377, 673, 1843, 1283, 1343, 2089, 12295, 33189, 0 }; - static ulong[] dim3697Kuo2Init = { 1, 1, 1, 9, 17, 21, 17, 251, 399, 531, 2007, 3449, 265, 289, 15937, 19571, 0 }; - static ulong[] dim3698Kuo2Init = { 1, 1, 5, 15, 15, 53, 21, 141, 387, 885, 1409, 2883, 2101, 4741, 597, 23435, 0 }; - static ulong[] dim3699Kuo2Init = { 1, 3, 1, 7, 27, 63, 33, 157, 331, 921, 1097, 3963, 3275, 14909, 2359, 12327, 0 }; - static ulong[] dim3700Kuo2Init = { 1, 1, 3, 11, 15, 7, 121, 235, 219, 181, 1305, 3877, 2233, 4921, 31409, 28211, 0 }; - static ulong[] dim3701Kuo2Init = { 1, 3, 3, 7, 23, 25, 67, 147, 211, 757, 1903, 3077, 3931, 11885, 3053, 45709, 0 }; - static ulong[] dim3702Kuo2Init = { 1, 1, 1, 5, 29, 21, 121, 115, 231, 957, 203, 689, 5521, 2467, 21489, 10057, 0 }; - static ulong[] dim3703Kuo2Init = { 1, 1, 5, 9, 15, 17, 11, 177, 319, 547, 801, 3899, 5919, 8785, 12019, 2535, 0 }; - static ulong[] dim3704Kuo2Init = { 1, 3, 1, 3, 21, 51, 83, 121, 317, 715, 467, 3587, 383, 3519, 26731, 64151, 0 }; - static ulong[] dim3705Kuo2Init = { 1, 3, 3, 13, 31, 47, 41, 247, 211, 333, 691, 2679, 4599, 2479, 27687, 45793, 0 }; - static ulong[] dim3706Kuo2Init = { 1, 1, 1, 11, 31, 9, 41, 241, 439, 391, 949, 2957, 5105, 5073, 7607, 4809, 0 }; - static ulong[] dim3707Kuo2Init = { 1, 1, 1, 9, 5, 57, 11, 167, 193, 1019, 533, 2559, 3899, 15199, 13723, 1909, 0 }; - static ulong[] dim3708Kuo2Init = { 1, 3, 3, 3, 5, 17, 5, 21, 445, 857, 2017, 2759, 5011, 8415, 881, 15747, 0 }; - static ulong[] dim3709Kuo2Init = { 1, 1, 1, 1, 1, 25, 31, 61, 407, 71, 263, 681, 5325, 13747, 10833, 12191, 0 }; - static ulong[] dim3710Kuo2Init = { 1, 3, 3, 9, 27, 3, 73, 145, 5, 851, 1519, 2809, 5857, 2327, 32659, 11145, 0 }; - static ulong[] dim3711Kuo2Init = { 1, 3, 3, 5, 21, 3, 47, 11, 17, 1023, 621, 3527, 613, 5607, 19377, 49671, 0 }; - static ulong[] dim3712Kuo2Init = { 1, 3, 1, 11, 5, 5, 57, 39, 221, 847, 735, 3951, 6661, 13959, 16735, 26471, 0 }; - static ulong[] dim3713Kuo2Init = { 1, 3, 1, 11, 3, 31, 15, 121, 31, 689, 151, 849, 2859, 14903, 6065, 9203, 0 }; - static ulong[] dim3714Kuo2Init = { 1, 3, 3, 9, 5, 63, 27, 51, 379, 657, 1381, 67, 2733, 7673, 13217, 14265, 0 }; - static ulong[] dim3715Kuo2Init = { 1, 1, 7, 15, 27, 63, 21, 25, 315, 101, 851, 2585, 4423, 7857, 30561, 60301, 0 }; - static ulong[] dim3716Kuo2Init = { 1, 3, 3, 11, 21, 51, 9, 39, 123, 763, 1777, 3427, 5071, 7905, 1017, 15373, 0 }; - static ulong[] dim3717Kuo2Init = { 1, 3, 1, 7, 25, 59, 3, 223, 71, 33, 731, 2303, 7153, 12847, 9707, 50871, 0 }; - static ulong[] dim3718Kuo2Init = { 1, 1, 5, 11, 31, 61, 13, 155, 467, 501, 371, 1447, 7925, 13135, 27629, 45097, 0 }; - static ulong[] dim3719Kuo2Init = { 1, 1, 1, 1, 13, 25, 35, 153, 333, 9, 1609, 539, 5029, 2059, 3547, 55407, 0 }; - static ulong[] dim3720Kuo2Init = { 1, 1, 7, 9, 21, 55, 101, 199, 279, 77, 1337, 3503, 2365, 4969, 2411, 16853, 0 }; - static ulong[] dim3721Kuo2Init = { 1, 1, 7, 11, 29, 9, 111, 63, 435, 445, 1711, 3981, 6517, 14593, 29433, 31027, 0 }; - static ulong[] dim3722Kuo2Init = { 1, 1, 7, 1, 15, 57, 43, 137, 189, 83, 187, 417, 3425, 14653, 17805, 57685, 0 }; - static ulong[] dim3723Kuo2Init = { 1, 1, 5, 3, 27, 23, 71, 65, 399, 605, 421, 463, 2019, 10707, 26201, 23573, 0 }; - static ulong[] dim3724Kuo2Init = { 1, 1, 3, 15, 17, 57, 119, 125, 365, 681, 1967, 241, 7647, 13317, 23661, 55683, 0 }; - static ulong[] dim3725Kuo2Init = { 1, 1, 7, 1, 7, 63, 91, 161, 45, 533, 1833, 2465, 5081, 6341, 16713, 34685, 0 }; - static ulong[] dim3726Kuo2Init = { 1, 3, 1, 9, 23, 9, 43, 157, 307, 521, 1611, 3851, 6943, 14939, 13833, 20099, 0 }; - static ulong[] dim3727Kuo2Init = { 1, 1, 5, 3, 27, 13, 35, 131, 129, 257, 1015, 1849, 6645, 11567, 13385, 30943, 0 }; - static ulong[] dim3728Kuo2Init = { 1, 1, 5, 1, 21, 49, 101, 77, 301, 541, 481, 2903, 8121, 2689, 21541, 25337, 0 }; - static ulong[] dim3729Kuo2Init = { 1, 1, 5, 11, 1, 13, 125, 209, 327, 245, 1055, 1097, 4931, 15721, 8193, 19923, 0 }; - static ulong[] dim3730Kuo2Init = { 1, 1, 1, 11, 17, 31, 85, 159, 405, 287, 1083, 1679, 6227, 305, 9549, 27303, 0 }; - static ulong[] dim3731Kuo2Init = { 1, 1, 1, 13, 7, 45, 125, 181, 219, 811, 1471, 999, 93, 12845, 4597, 60641, 0 }; - static ulong[] dim3732Kuo2Init = { 1, 3, 5, 7, 29, 23, 109, 37, 367, 185, 1467, 1871, 6349, 8563, 8743, 30277, 0 }; - static ulong[] dim3733Kuo2Init = { 1, 1, 1, 15, 19, 23, 75, 93, 191, 993, 1111, 1531, 2105, 8869, 27217, 16609, 0 }; - static ulong[] dim3734Kuo2Init = { 1, 3, 1, 15, 31, 29, 23, 145, 467, 465, 637, 3169, 889, 9225, 17917, 8379, 0 }; - static ulong[] dim3735Kuo2Init = { 1, 3, 5, 1, 1, 33, 7, 209, 99, 753, 113, 2945, 345, 14091, 13169, 4799, 0 }; - static ulong[] dim3736Kuo2Init = { 1, 3, 3, 11, 21, 5, 9, 97, 347, 537, 1287, 1401, 815, 9289, 17259, 11755, 0 }; - static ulong[] dim3737Kuo2Init = { 1, 1, 5, 1, 7, 9, 21, 87, 495, 685, 1675, 1909, 4215, 1589, 18229, 2253, 0 }; - static ulong[] dim3738Kuo2Init = { 1, 1, 1, 3, 7, 29, 121, 67, 383, 351, 1555, 3091, 3677, 3489, 30241, 55309, 0 }; - static ulong[] dim3739Kuo2Init = { 1, 1, 7, 11, 21, 39, 33, 201, 195, 601, 1235, 3499, 1657, 4495, 26501, 49783, 0 }; - static ulong[] dim3740Kuo2Init = { 1, 1, 5, 1, 15, 37, 91, 169, 65, 471, 1409, 3017, 1071, 15331, 27085, 22837, 0 }; - static ulong[] dim3741Kuo2Init = { 1, 1, 5, 13, 23, 45, 115, 153, 27, 773, 637, 2673, 79, 4275, 21133, 38509, 0 }; - static ulong[] dim3742Kuo2Init = { 1, 3, 1, 13, 17, 53, 49, 55, 439, 255, 383, 1057, 4995, 3853, 29839, 2529, 0 }; - static ulong[] dim3743Kuo2Init = { 1, 3, 5, 9, 17, 29, 73, 205, 1, 685, 991, 3563, 4281, 2341, 27111, 36609, 0 }; - static ulong[] dim3744Kuo2Init = { 1, 3, 5, 9, 19, 25, 65, 167, 425, 289, 963, 1653, 131, 4599, 4615, 57653, 0 }; - static ulong[] dim3745Kuo2Init = { 1, 1, 1, 11, 19, 57, 93, 239, 375, 739, 1101, 881, 7391, 921, 11493, 50417, 0 }; - static ulong[] dim3746Kuo2Init = { 1, 3, 5, 15, 7, 33, 5, 59, 381, 123, 33, 1903, 2639, 12073, 511, 659, 0 }; - static ulong[] dim3747Kuo2Init = { 1, 1, 3, 1, 23, 1, 77, 55, 455, 687, 1825, 1355, 2997, 615, 123, 17611, 0 }; - static ulong[] dim3748Kuo2Init = { 1, 1, 7, 13, 25, 61, 119, 101, 397, 645, 485, 3361, 899, 5103, 3307, 9765, 0 }; - static ulong[] dim3749Kuo2Init = { 1, 3, 1, 3, 25, 59, 27, 245, 3, 915, 1001, 977, 7913, 4667, 24845, 37183, 0 }; - static ulong[] dim3750Kuo2Init = { 1, 1, 7, 15, 19, 21, 1, 233, 175, 347, 1335, 2757, 1615, 8381, 10611, 32409, 0 }; - static ulong[] dim3751Kuo2Init = { 1, 1, 7, 15, 23, 33, 7, 51, 235, 735, 615, 3305, 4555, 15079, 21309, 55397, 0 }; - static ulong[] dim3752Kuo2Init = { 1, 3, 1, 3, 19, 49, 59, 213, 155, 23, 239, 753, 1473, 6869, 19993, 14383, 0 }; - static ulong[] dim3753Kuo2Init = { 1, 1, 5, 9, 17, 37, 23, 163, 45, 409, 1103, 289, 4707, 12657, 26033, 27547, 0 }; - static ulong[] dim3754Kuo2Init = { 1, 3, 7, 9, 23, 49, 83, 63, 79, 643, 107, 3041, 1921, 10343, 19179, 4961, 0 }; - static ulong[] dim3755Kuo2Init = { 1, 1, 7, 7, 31, 7, 81, 145, 281, 751, 867, 535, 6593, 7255, 13785, 62137, 0 }; - static ulong[] dim3756Kuo2Init = { 1, 1, 7, 1, 13, 55, 59, 203, 329, 421, 483, 2931, 521, 3013, 1077, 3405, 0 }; - static ulong[] dim3757Kuo2Init = { 1, 3, 5, 1, 15, 13, 21, 205, 187, 491, 887, 893, 3917, 6989, 23569, 48729, 0 }; - static ulong[] dim3758Kuo2Init = { 1, 1, 3, 11, 15, 35, 63, 109, 157, 643, 961, 3713, 1459, 8585, 6113, 7339, 0 }; - static ulong[] dim3759Kuo2Init = { 1, 3, 7, 9, 7, 53, 57, 251, 203, 701, 2041, 73, 7637, 12745, 8003, 45849, 0 }; - static ulong[] dim3760Kuo2Init = { 1, 3, 5, 1, 23, 27, 109, 211, 273, 1013, 19, 2499, 377, 5185, 25261, 8997, 0 }; - static ulong[] dim3761Kuo2Init = { 1, 3, 7, 15, 3, 35, 41, 85, 391, 409, 1945, 25, 6069, 3499, 10879, 38239, 0 }; - static ulong[] dim3762Kuo2Init = { 1, 3, 1, 3, 3, 37, 65, 229, 441, 675, 909, 3887, 7347, 3221, 1935, 65147, 0 }; - static ulong[] dim3763Kuo2Init = { 1, 3, 5, 13, 13, 29, 119, 29, 277, 303, 685, 1921, 4863, 12483, 9303, 59355, 0 }; - static ulong[] dim3764Kuo2Init = { 1, 1, 1, 9, 21, 43, 115, 253, 349, 655, 779, 1965, 4831, 6491, 16051, 6975, 0 }; - static ulong[] dim3765Kuo2Init = { 1, 3, 3, 7, 1, 9, 55, 253, 21, 655, 133, 3777, 4239, 14447, 7221, 59819, 0 }; - static ulong[] dim3766Kuo2Init = { 1, 1, 7, 3, 19, 49, 11, 93, 39, 149, 683, 3295, 6519, 12187, 2231, 39829, 0 }; - static ulong[] dim3767Kuo2Init = { 1, 3, 7, 5, 23, 9, 101, 197, 3, 873, 1459, 747, 6939, 5629, 27305, 32235, 0 }; - static ulong[] dim3768Kuo2Init = { 1, 1, 5, 7, 13, 9, 31, 251, 481, 877, 773, 993, 4431, 12081, 15987, 27081, 0 }; - static ulong[] dim3769Kuo2Init = { 1, 1, 1, 1, 9, 49, 13, 89, 39, 797, 815, 319, 5917, 621, 25867, 46433, 0 }; - static ulong[] dim3770Kuo2Init = { 1, 3, 1, 7, 23, 27, 83, 123, 83, 177, 1001, 995, 2765, 6401, 15593, 20205, 0 }; - static ulong[] dim3771Kuo2Init = { 1, 1, 5, 13, 25, 9, 59, 123, 141, 737, 1111, 1883, 2647, 733, 3551, 44453, 0 }; - static ulong[] dim3772Kuo2Init = { 1, 3, 1, 5, 7, 49, 25, 177, 297, 87, 1039, 1917, 3167, 11025, 22959, 63929, 0 }; - static ulong[] dim3773Kuo2Init = { 1, 1, 1, 3, 17, 57, 103, 99, 127, 579, 903, 2835, 607, 9723, 22397, 36621, 0 }; - static ulong[] dim3774Kuo2Init = { 1, 1, 3, 15, 13, 47, 77, 213, 383, 371, 887, 281, 6171, 10383, 12157, 57899, 0 }; - static ulong[] dim3775Kuo2Init = { 1, 3, 1, 5, 5, 15, 65, 119, 303, 265, 783, 3075, 7893, 441, 22065, 52157, 0 }; - static ulong[] dim3776Kuo2Init = { 1, 3, 5, 15, 7, 49, 105, 145, 301, 57, 1949, 3073, 435, 1171, 27691, 34821, 0 }; - static ulong[] dim3777Kuo2Init = { 1, 3, 1, 11, 5, 31, 33, 159, 319, 437, 453, 1005, 3335, 5895, 15407, 159, 0 }; - static ulong[] dim3778Kuo2Init = { 1, 3, 3, 9, 31, 15, 69, 129, 221, 991, 1879, 1251, 5303, 6677, 15823, 46319, 0 }; - static ulong[] dim3779Kuo2Init = { 1, 3, 7, 11, 1, 47, 49, 13, 401, 755, 1703, 2021, 5195, 9489, 9191, 30427, 0 }; - static ulong[] dim3780Kuo2Init = { 1, 1, 7, 9, 7, 11, 25, 147, 471, 31, 489, 3477, 3025, 4011, 7733, 22091, 0 }; - static ulong[] dim3781Kuo2Init = { 1, 1, 5, 9, 7, 7, 99, 23, 397, 67, 2027, 3885, 3269, 15385, 24367, 1715, 0 }; - static ulong[] dim3782Kuo2Init = { 1, 1, 5, 1, 7, 45, 83, 159, 501, 561, 993, 1495, 4415, 2559, 27, 60825, 0 }; - static ulong[] dim3783Kuo2Init = { 1, 3, 1, 7, 7, 43, 99, 159, 117, 453, 1841, 1807, 1881, 12513, 16413, 37993, 0 }; - static ulong[] dim3784Kuo2Init = { 1, 3, 1, 13, 15, 37, 53, 173, 279, 415, 535, 2553, 3995, 8245, 4507, 19575, 0 }; - static ulong[] dim3785Kuo2Init = { 1, 1, 7, 9, 25, 7, 79, 25, 105, 525, 1179, 1793, 4899, 10253, 22655, 1419, 0 }; - static ulong[] dim3786Kuo2Init = { 1, 1, 5, 11, 11, 35, 77, 139, 449, 879, 619, 1645, 3309, 37, 10607, 43757, 0 }; - static ulong[] dim3787Kuo2Init = { 1, 1, 1, 13, 17, 17, 7, 69, 389, 733, 775, 791, 5451, 15737, 9043, 16573, 0 }; - static ulong[] dim3788Kuo2Init = { 1, 1, 7, 5, 15, 57, 81, 19, 307, 207, 241, 449, 7745, 521, 16975, 11907, 0 }; - static ulong[] dim3789Kuo2Init = { 1, 1, 1, 5, 25, 1, 55, 229, 123, 809, 1673, 3461, 7729, 8615, 8755, 35929, 0 }; - static ulong[] dim3790Kuo2Init = { 1, 3, 3, 1, 23, 7, 19, 235, 375, 79, 899, 21, 7681, 7169, 13057, 1379, 0 }; - static ulong[] dim3791Kuo2Init = { 1, 3, 3, 7, 29, 49, 93, 217, 409, 263, 225, 2333, 1621, 14741, 4933, 58263, 0 }; - static ulong[] dim3792Kuo2Init = { 1, 3, 1, 13, 11, 35, 19, 55, 71, 937, 551, 1693, 3843, 7411, 29501, 31525, 0 }; - static ulong[] dim3793Kuo2Init = { 1, 1, 5, 13, 17, 17, 105, 31, 181, 915, 321, 3161, 5247, 13317, 23595, 21783, 0 }; - static ulong[] dim3794Kuo2Init = { 1, 3, 5, 15, 31, 19, 85, 71, 55, 933, 1425, 2419, 2891, 15813, 18209, 30347, 0 }; - static ulong[] dim3795Kuo2Init = { 1, 1, 7, 9, 1, 45, 31, 1, 193, 445, 1293, 2563, 5837, 6113, 5741, 12245, 0 }; - static ulong[] dim3796Kuo2Init = { 1, 3, 5, 9, 25, 25, 7, 155, 267, 65, 2015, 2021, 6331, 6973, 1303, 14833, 0 }; - static ulong[] dim3797Kuo2Init = { 1, 1, 5, 11, 21, 31, 87, 21, 509, 555, 429, 1405, 4417, 1891, 15679, 3819, 0 }; - static ulong[] dim3798Kuo2Init = { 1, 3, 7, 3, 19, 49, 53, 251, 423, 949, 971, 425, 1589, 5257, 19021, 16817, 0 }; - static ulong[] dim3799Kuo2Init = { 1, 1, 5, 7, 1, 27, 71, 185, 357, 1009, 897, 491, 6433, 6717, 23445, 29097, 0 }; - static ulong[] dim3800Kuo2Init = { 1, 3, 7, 15, 9, 39, 87, 25, 149, 291, 1249, 3987, 7441, 11225, 18051, 17747, 0 }; - static ulong[] dim3801Kuo2Init = { 1, 1, 7, 1, 13, 61, 13, 141, 39, 317, 579, 2181, 6735, 14749, 25997, 16025, 0 }; - static ulong[] dim3802Kuo2Init = { 1, 1, 7, 7, 27, 19, 127, 231, 13, 7, 1707, 87, 7379, 8171, 27435, 47911, 0 }; - static ulong[] dim3803Kuo2Init = { 1, 1, 1, 15, 21, 33, 33, 85, 205, 321, 785, 4051, 2503, 15589, 10881, 63103, 0 }; - static ulong[] dim3804Kuo2Init = { 1, 1, 1, 3, 15, 11, 31, 105, 185, 113, 293, 3279, 4867, 9249, 14403, 24951, 0 }; - static ulong[] dim3805Kuo2Init = { 1, 3, 5, 13, 7, 47, 105, 253, 117, 577, 2019, 2089, 1357, 5299, 27961, 36675, 0 }; - static ulong[] dim3806Kuo2Init = { 1, 1, 1, 7, 31, 33, 117, 51, 283, 453, 1657, 1343, 6491, 649, 1029, 44809, 0 }; - static ulong[] dim3807Kuo2Init = { 1, 1, 1, 3, 3, 45, 121, 155, 191, 607, 1087, 3291, 8171, 3757, 14247, 49647, 0 }; - static ulong[] dim3808Kuo2Init = { 1, 3, 1, 3, 7, 17, 109, 163, 87, 63, 573, 3127, 3361, 6733, 26729, 44427, 0 }; - static ulong[] dim3809Kuo2Init = { 1, 1, 1, 5, 13, 23, 29, 173, 487, 345, 351, 3401, 4611, 5591, 6209, 58537, 0 }; - static ulong[] dim3810Kuo2Init = { 1, 3, 1, 5, 23, 49, 31, 51, 157, 623, 1103, 681, 6645, 2147, 1715, 42253, 0 }; - static ulong[] dim3811Kuo2Init = { 1, 1, 7, 9, 7, 61, 85, 129, 309, 701, 1139, 3211, 4943, 8365, 20727, 51025, 0 }; - static ulong[] dim3812Kuo2Init = { 1, 1, 3, 11, 29, 47, 119, 181, 109, 403, 1459, 39, 609, 7405, 25651, 61395, 0 }; - static ulong[] dim3813Kuo2Init = { 1, 3, 3, 7, 5, 55, 65, 155, 273, 177, 1879, 3901, 3219, 8699, 10445, 40141, 0 }; - static ulong[] dim3814Kuo2Init = { 1, 3, 7, 15, 3, 11, 45, 85, 473, 1013, 1725, 155, 3369, 7345, 1475, 28781, 0 }; - static ulong[] dim3815Kuo2Init = { 1, 1, 1, 11, 13, 61, 31, 217, 111, 719, 161, 1053, 1451, 10437, 28909, 1173, 0 }; - static ulong[] dim3816Kuo2Init = { 1, 1, 3, 11, 9, 21, 119, 119, 355, 563, 855, 853, 4243, 5201, 2521, 41389, 0 }; - static ulong[] dim3817Kuo2Init = { 1, 1, 5, 15, 9, 5, 15, 79, 489, 499, 1065, 2073, 7567, 5385, 9329, 17643, 0 }; - static ulong[] dim3818Kuo2Init = { 1, 3, 3, 7, 15, 53, 61, 225, 381, 217, 163, 4005, 7269, 4481, 23697, 46055, 0 }; - static ulong[] dim3819Kuo2Init = { 1, 3, 3, 13, 1, 55, 77, 95, 345, 113, 1359, 539, 6979, 5459, 9551, 45035, 0 }; - static ulong[] dim3820Kuo2Init = { 1, 1, 5, 3, 5, 45, 93, 147, 387, 165, 1529, 1243, 7639, 5531, 22381, 63517, 0 }; - static ulong[] dim3821Kuo2Init = { 1, 1, 3, 1, 9, 27, 109, 161, 71, 547, 259, 1399, 5815, 1569, 26627, 63133, 0 }; - static ulong[] dim3822Kuo2Init = { 1, 1, 3, 3, 29, 37, 21, 205, 49, 863, 707, 307, 573, 3167, 17595, 63485, 0 }; - static ulong[] dim3823Kuo2Init = { 1, 1, 5, 1, 17, 15, 95, 21, 111, 991, 657, 3865, 8091, 7589, 30487, 63229, 0 }; - static ulong[] dim3824Kuo2Init = { 1, 1, 1, 7, 29, 11, 65, 201, 357, 269, 281, 1329, 6359, 7875, 23561, 44489, 0 }; - static ulong[] dim3825Kuo2Init = { 1, 1, 7, 7, 27, 29, 1, 15, 475, 393, 1917, 3605, 4463, 7809, 16529, 64599, 0 }; - static ulong[] dim3826Kuo2Init = { 1, 3, 5, 13, 29, 15, 11, 255, 315, 209, 895, 2813, 2263, 7095, 1447, 55307, 0 }; - static ulong[] dim3827Kuo2Init = { 1, 3, 1, 15, 17, 11, 73, 57, 13, 529, 35, 1065, 81, 13801, 19531, 27249, 0 }; - static ulong[] dim3828Kuo2Init = { 1, 3, 1, 11, 19, 15, 117, 235, 219, 109, 1885, 4005, 3565, 2591, 29233, 47111, 0 }; - static ulong[] dim3829Kuo2Init = { 1, 3, 3, 11, 21, 35, 27, 227, 393, 57, 1637, 537, 2463, 4483, 32153, 22035, 0 }; - static ulong[] dim3830Kuo2Init = { 1, 1, 7, 5, 13, 9, 79, 147, 341, 1007, 1093, 3837, 5581, 3363, 10637, 60109, 0 }; - static ulong[] dim3831Kuo2Init = { 1, 3, 5, 13, 31, 49, 121, 231, 485, 947, 127, 1817, 3005, 11085, 14157, 21145, 0 }; - static ulong[] dim3832Kuo2Init = { 1, 1, 3, 1, 1, 23, 17, 195, 351, 527, 1787, 3885, 2281, 729, 25083, 63523, 0 }; - static ulong[] dim3833Kuo2Init = { 1, 3, 5, 15, 19, 31, 51, 5, 55, 551, 33, 1735, 427, 2859, 3941, 48639, 0 }; - static ulong[] dim3834Kuo2Init = { 1, 3, 7, 7, 11, 59, 101, 125, 167, 311, 1487, 969, 5023, 3893, 22065, 48803, 0 }; - static ulong[] dim3835Kuo2Init = { 1, 3, 3, 11, 27, 11, 77, 43, 295, 31, 1061, 2999, 4451, 10339, 9213, 63705, 0 }; - static ulong[] dim3836Kuo2Init = { 1, 3, 1, 11, 1, 63, 83, 179, 413, 317, 1921, 2917, 6697, 6637, 5291, 48791, 0 }; - static ulong[] dim3837Kuo2Init = { 1, 1, 3, 3, 19, 57, 55, 159, 137, 291, 1353, 81, 2495, 12315, 31031, 41081, 0 }; - static ulong[] dim3838Kuo2Init = { 1, 1, 3, 3, 25, 49, 49, 239, 53, 999, 303, 3083, 2455, 3977, 13945, 22667, 0 }; - static ulong[] dim3839Kuo2Init = { 1, 3, 5, 15, 7, 15, 85, 215, 463, 301, 1061, 3993, 5927, 703, 23083, 44633, 0 }; - static ulong[] dim3840Kuo2Init = { 1, 3, 3, 1, 9, 53, 21, 165, 129, 697, 1867, 2427, 5383, 13223, 12127, 60477, 0 }; - static ulong[] dim3841Kuo2Init = { 1, 3, 5, 5, 17, 13, 37, 151, 337, 425, 829, 2415, 1705, 10389, 26299, 45655, 0 }; - static ulong[] dim3842Kuo2Init = { 1, 3, 1, 9, 13, 3, 99, 111, 371, 589, 605, 3137, 4515, 5303, 6151, 14225, 0 }; - static ulong[] dim3843Kuo2Init = { 1, 1, 3, 11, 15, 59, 31, 95, 305, 133, 751, 13, 7691, 2603, 21761, 18577, 0 }; - static ulong[] dim3844Kuo2Init = { 1, 1, 1, 13, 25, 47, 93, 251, 341, 465, 1043, 3391, 271, 3431, 16465, 53283, 0 }; - static ulong[] dim3845Kuo2Init = { 1, 1, 5, 9, 31, 1, 31, 77, 383, 151, 1243, 3165, 2363, 13751, 10251, 55111, 0 }; - static ulong[] dim3846Kuo2Init = { 1, 1, 5, 13, 23, 35, 123, 229, 193, 29, 201, 2661, 7539, 10407, 30831, 56091, 0 }; - static ulong[] dim3847Kuo2Init = { 1, 1, 5, 15, 19, 17, 83, 157, 265, 649, 815, 531, 3905, 10691, 4137, 29875, 0 }; - static ulong[] dim3848Kuo2Init = { 1, 1, 3, 7, 29, 41, 29, 153, 509, 617, 151, 2409, 4631, 6525, 8539, 20855, 0 }; - static ulong[] dim3849Kuo2Init = { 1, 1, 1, 5, 27, 37, 55, 215, 135, 463, 163, 1415, 1457, 2675, 9461, 6585, 0 }; - static ulong[] dim3850Kuo2Init = { 1, 3, 5, 7, 23, 17, 29, 183, 33, 593, 717, 1487, 4777, 6281, 3299, 37531, 0 }; - static ulong[] dim3851Kuo2Init = { 1, 1, 5, 15, 15, 17, 91, 243, 259, 655, 1347, 3229, 1449, 10069, 2671, 11391, 0 }; - static ulong[] dim3852Kuo2Init = { 1, 1, 7, 15, 17, 35, 35, 105, 285, 761, 1989, 3427, 3649, 223, 21887, 6153, 0 }; - static ulong[] dim3853Kuo2Init = { 1, 3, 1, 5, 17, 55, 47, 235, 7, 829, 1437, 1669, 2837, 6573, 3847, 32347, 0 }; - static ulong[] dim3854Kuo2Init = { 1, 1, 5, 11, 5, 19, 41, 151, 59, 427, 1917, 3339, 4139, 13781, 15171, 50597, 0 }; - static ulong[] dim3855Kuo2Init = { 1, 3, 5, 1, 3, 47, 77, 175, 239, 729, 1957, 2941, 4749, 15157, 30351, 57657, 0 }; - static ulong[] dim3856Kuo2Init = { 1, 3, 5, 1, 23, 39, 51, 239, 455, 347, 1673, 1355, 1707, 10125, 18923, 53953, 0 }; - static ulong[] dim3857Kuo2Init = { 1, 3, 3, 11, 5, 21, 113, 161, 325, 663, 9, 641, 4089, 7043, 9771, 16719, 0 }; - static ulong[] dim3858Kuo2Init = { 1, 3, 7, 7, 1, 63, 3, 77, 67, 575, 313, 1249, 1203, 8121, 13647, 563, 0 }; - static ulong[] dim3859Kuo2Init = { 1, 3, 3, 15, 17, 61, 95, 75, 421, 671, 835, 4015, 6591, 7589, 8039, 10055, 0 }; - static ulong[] dim3860Kuo2Init = { 1, 1, 3, 3, 27, 43, 75, 121, 143, 235, 1243, 2063, 7711, 7925, 2943, 23419, 0 }; - static ulong[] dim3861Kuo2Init = { 1, 3, 5, 15, 1, 21, 41, 225, 427, 843, 1417, 3481, 5239, 16373, 11599, 37267, 0 }; - static ulong[] dim3862Kuo2Init = { 1, 1, 7, 15, 17, 23, 95, 185, 193, 471, 1475, 861, 5115, 4573, 12909, 12337, 0 }; - static ulong[] dim3863Kuo2Init = { 1, 3, 1, 7, 19, 25, 107, 171, 355, 57, 1301, 2343, 6425, 5537, 29391, 27187, 0 }; - static ulong[] dim3864Kuo2Init = { 1, 3, 5, 9, 19, 35, 67, 157, 183, 477, 961, 1087, 7329, 15787, 9547, 59001, 0 }; - static ulong[] dim3865Kuo2Init = { 1, 1, 3, 5, 29, 57, 29, 119, 315, 533, 717, 1099, 713, 1473, 19511, 59777, 0 }; - static ulong[] dim3866Kuo2Init = { 1, 3, 7, 7, 17, 63, 71, 181, 103, 943, 305, 1657, 6117, 11921, 6119, 26437, 0 }; - static ulong[] dim3867Kuo2Init = { 1, 3, 7, 9, 3, 61, 91, 65, 389, 331, 549, 2355, 4591, 3385, 19913, 62541, 0 }; - static ulong[] dim3868Kuo2Init = { 1, 1, 5, 1, 17, 1, 127, 127, 471, 139, 1147, 1463, 5403, 10877, 11469, 65283, 0 }; - static ulong[] dim3869Kuo2Init = { 1, 3, 1, 13, 27, 29, 31, 57, 433, 941, 1559, 2495, 83, 14701, 20787, 10761, 0 }; - static ulong[] dim3870Kuo2Init = { 1, 3, 3, 9, 23, 59, 23, 175, 25, 865, 751, 3395, 4111, 10287, 28191, 38487, 0 }; - static ulong[] dim3871Kuo2Init = { 1, 1, 3, 7, 21, 3, 107, 205, 349, 473, 1115, 1647, 2379, 4709, 21697, 47899, 0 }; - static ulong[] dim3872Kuo2Init = { 1, 3, 5, 15, 27, 49, 113, 73, 487, 487, 1531, 357, 8073, 10275, 7713, 9169, 0 }; - static ulong[] dim3873Kuo2Init = { 1, 3, 3, 13, 1, 55, 97, 19, 5, 997, 1, 437, 343, 4867, 4897, 20291, 0 }; - static ulong[] dim3874Kuo2Init = { 1, 3, 7, 5, 19, 51, 25, 3, 143, 783, 1415, 2231, 1809, 2011, 32607, 33817, 0 }; - static ulong[] dim3875Kuo2Init = { 1, 1, 5, 1, 3, 59, 49, 183, 447, 55, 17, 1455, 3753, 13531, 17193, 22375, 0 }; - static ulong[] dim3876Kuo2Init = { 1, 3, 7, 5, 21, 55, 25, 79, 161, 763, 815, 2161, 1639, 7165, 15681, 53681, 0 }; - static ulong[] dim3877Kuo2Init = { 1, 3, 7, 3, 15, 53, 75, 243, 49, 701, 519, 1781, 8073, 16349, 487, 35051, 0 }; - static ulong[] dim3878Kuo2Init = { 1, 3, 3, 15, 11, 33, 65, 93, 157, 499, 1487, 627, 4483, 9001, 26869, 11713, 0 }; - static ulong[] dim3879Kuo2Init = { 1, 1, 3, 9, 15, 43, 29, 159, 125, 329, 1619, 41, 2565, 6043, 23983, 33397, 0 }; - static ulong[] dim3880Kuo2Init = { 1, 1, 1, 9, 31, 25, 71, 53, 109, 415, 1895, 309, 5121, 3659, 24591, 5207, 0 }; - static ulong[] dim3881Kuo2Init = { 1, 3, 1, 5, 23, 33, 35, 95, 171, 395, 171, 1085, 6629, 757, 29347, 22703, 0 }; - static ulong[] dim3882Kuo2Init = { 1, 1, 7, 5, 17, 59, 35, 9, 141, 311, 1075, 2499, 321, 14733, 4069, 46015, 0 }; - static ulong[] dim3883Kuo2Init = { 1, 1, 1, 13, 5, 27, 93, 105, 205, 875, 1867, 2423, 3015, 2939, 27529, 24221, 0 }; - static ulong[] dim3884Kuo2Init = { 1, 1, 1, 15, 21, 51, 55, 239, 95, 517, 1449, 537, 8083, 11519, 30293, 56663, 0 }; - static ulong[] dim3885Kuo2Init = { 1, 3, 5, 7, 3, 1, 31, 77, 75, 343, 423, 3781, 1171, 5331, 8885, 1917, 0 }; - static ulong[] dim3886Kuo2Init = { 1, 3, 1, 13, 1, 45, 127, 123, 153, 769, 1549, 3049, 4023, 10475, 3185, 7973, 0 }; - static ulong[] dim3887Kuo2Init = { 1, 3, 5, 15, 17, 17, 63, 197, 483, 253, 1655, 4053, 3753, 4159, 23551, 34501, 0 }; - static ulong[] dim3888Kuo2Init = { 1, 3, 7, 7, 27, 35, 91, 241, 377, 299, 1741, 2009, 4051, 3753, 18631, 56383, 0 }; - static ulong[] dim3889Kuo2Init = { 1, 1, 3, 9, 11, 45, 101, 221, 167, 845, 249, 2297, 967, 5203, 29305, 8875, 0 }; - static ulong[] dim3890Kuo2Init = { 1, 3, 5, 9, 31, 41, 21, 251, 421, 47, 421, 3037, 867, 12623, 23289, 39289, 0 }; - static ulong[] dim3891Kuo2Init = { 1, 1, 7, 9, 31, 13, 99, 207, 181, 683, 1881, 2047, 2299, 15795, 24597, 46881, 0 }; - static ulong[] dim3892Kuo2Init = { 1, 1, 1, 15, 1, 45, 57, 171, 149, 909, 1493, 181, 4539, 9625, 20357, 9291, 0 }; - static ulong[] dim3893Kuo2Init = { 1, 3, 5, 15, 5, 19, 101, 167, 245, 213, 1453, 1447, 19, 2091, 27345, 45839, 0 }; - static ulong[] dim3894Kuo2Init = { 1, 1, 5, 5, 5, 61, 59, 159, 343, 51, 2009, 3651, 5263, 1425, 4399, 34357, 0 }; - static ulong[] dim3895Kuo2Init = { 1, 3, 1, 15, 15, 61, 49, 15, 415, 365, 551, 797, 7147, 12771, 17557, 30663, 0 }; - static ulong[] dim3896Kuo2Init = { 1, 3, 1, 7, 17, 15, 125, 195, 455, 553, 1259, 1851, 5149, 6843, 29195, 15015, 0 }; - static ulong[] dim3897Kuo2Init = { 1, 3, 7, 3, 23, 21, 5, 195, 77, 881, 941, 2839, 2837, 10405, 22289, 6211, 0 }; - static ulong[] dim3898Kuo2Init = { 1, 1, 1, 7, 11, 61, 99, 247, 251, 183, 1263, 157, 511, 8627, 19503, 43933, 0 }; - static ulong[] dim3899Kuo2Init = { 1, 3, 1, 9, 15, 15, 113, 255, 225, 173, 1427, 3837, 6607, 3777, 4913, 11173, 0 }; - static ulong[] dim3900Kuo2Init = { 1, 1, 1, 5, 17, 51, 65, 249, 361, 377, 1597, 3065, 5949, 9363, 25597, 40657, 0 }; - static ulong[] dim3901Kuo2Init = { 1, 1, 3, 13, 15, 41, 51, 75, 277, 611, 517, 3751, 721, 6673, 32715, 29053, 0 }; - static ulong[] dim3902Kuo2Init = { 1, 3, 3, 11, 31, 61, 97, 163, 79, 267, 1601, 3155, 1623, 6301, 12897, 1555, 0 }; - static ulong[] dim3903Kuo2Init = { 1, 1, 5, 1, 31, 33, 29, 239, 15, 235, 1675, 1453, 1005, 4811, 21601, 34343, 0 }; - static ulong[] dim3904Kuo2Init = { 1, 3, 7, 9, 13, 23, 43, 119, 313, 249, 643, 3797, 5299, 5127, 5639, 8509, 0 }; - static ulong[] dim3905Kuo2Init = { 1, 1, 7, 5, 11, 51, 85, 181, 231, 641, 1285, 1417, 4535, 10417, 21261, 4965, 0 }; - static ulong[] dim3906Kuo2Init = { 1, 3, 5, 1, 15, 47, 109, 197, 93, 115, 47, 2315, 863, 2787, 25487, 4069, 0 }; - static ulong[] dim3907Kuo2Init = { 1, 1, 7, 11, 13, 43, 117, 203, 189, 151, 549, 1045, 7953, 11003, 17637, 3627, 0 }; - static ulong[] dim3908Kuo2Init = { 1, 3, 5, 7, 7, 29, 5, 55, 281, 767, 1809, 2489, 6417, 10927, 30935, 10769, 0 }; - static ulong[] dim3909Kuo2Init = { 1, 3, 7, 1, 5, 21, 75, 247, 127, 223, 103, 1737, 6577, 389, 26319, 20005, 0 }; - static ulong[] dim3910Kuo2Init = { 1, 1, 1, 5, 15, 55, 33, 171, 115, 535, 1523, 383, 2029, 16339, 12799, 46209, 0 }; - static ulong[] dim3911Kuo2Init = { 1, 1, 5, 5, 21, 39, 9, 239, 221, 497, 913, 2465, 561, 15701, 18851, 11207, 0 }; - static ulong[] dim3912Kuo2Init = { 1, 3, 7, 3, 5, 33, 97, 227, 91, 283, 1971, 3791, 2313, 9519, 11039, 46973, 0 }; - static ulong[] dim3913Kuo2Init = { 1, 1, 7, 7, 1, 35, 1, 23, 391, 365, 1099, 429, 5159, 409, 17641, 55545, 0 }; - static ulong[] dim3914Kuo2Init = { 1, 3, 7, 9, 29, 11, 5, 63, 1, 401, 265, 753, 6933, 899, 10407, 21391, 0 }; - static ulong[] dim3915Kuo2Init = { 1, 1, 3, 5, 25, 7, 95, 251, 241, 625, 661, 829, 1077, 2157, 27767, 32355, 0 }; - static ulong[] dim3916Kuo2Init = { 1, 3, 7, 3, 21, 17, 63, 85, 83, 507, 265, 1183, 6095, 343, 11011, 39071, 0 }; - static ulong[] dim3917Kuo2Init = { 1, 3, 7, 11, 7, 23, 17, 67, 83, 875, 1487, 2565, 6619, 8651, 31249, 28487, 0 }; - static ulong[] dim3918Kuo2Init = { 1, 3, 3, 7, 9, 27, 63, 23, 107, 103, 1059, 2029, 1417, 8883, 7003, 4729, 0 }; - static ulong[] dim3919Kuo2Init = { 1, 1, 1, 11, 5, 53, 67, 41, 227, 643, 1767, 615, 2165, 14475, 21143, 22079, 0 }; - static ulong[] dim3920Kuo2Init = { 1, 1, 7, 7, 1, 19, 77, 211, 379, 173, 1097, 3865, 3735, 10719, 9223, 209, 0 }; - static ulong[] dim3921Kuo2Init = { 1, 1, 5, 7, 31, 53, 77, 73, 329, 587, 1121, 2139, 7433, 9569, 20289, 47867, 0 }; - static ulong[] dim3922Kuo2Init = { 1, 1, 3, 3, 7, 21, 19, 181, 209, 603, 885, 2251, 1563, 6435, 9455, 1753, 0 }; - static ulong[] dim3923Kuo2Init = { 1, 1, 5, 11, 5, 7, 67, 111, 355, 457, 193, 1311, 5987, 5223, 13489, 49679, 0 }; - static ulong[] dim3924Kuo2Init = { 1, 1, 3, 9, 23, 11, 21, 217, 361, 803, 325, 2767, 3363, 9753, 26523, 20517, 0 }; - static ulong[] dim3925Kuo2Init = { 1, 3, 5, 11, 27, 13, 71, 127, 249, 49, 153, 4017, 289, 10705, 19671, 21929, 0 }; - static ulong[] dim3926Kuo2Init = { 1, 1, 5, 5, 13, 51, 113, 109, 135, 507, 719, 2011, 3803, 12049, 13629, 50781, 0 }; - static ulong[] dim3927Kuo2Init = { 1, 3, 1, 9, 5, 33, 125, 223, 309, 909, 1209, 3099, 3431, 853, 2553, 1845, 0 }; - static ulong[] dim3928Kuo2Init = { 1, 3, 1, 5, 21, 61, 63, 21, 485, 101, 1307, 3777, 6331, 3549, 20867, 41487, 0 }; - static ulong[] dim3929Kuo2Init = { 1, 3, 7, 1, 1, 33, 115, 97, 445, 521, 1801, 2869, 7893, 10229, 27265, 7749, 0 }; - static ulong[] dim3930Kuo2Init = { 1, 1, 1, 15, 7, 25, 23, 87, 277, 699, 783, 2891, 5033, 14031, 22947, 15921, 0 }; - static ulong[] dim3931Kuo2Init = { 1, 3, 5, 11, 17, 1, 53, 195, 125, 937, 739, 999, 1729, 14809, 16855, 16407, 0 }; - static ulong[] dim3932Kuo2Init = { 1, 1, 7, 15, 11, 21, 13, 205, 367, 167, 1967, 4003, 1145, 5679, 26437, 27597, 0 }; - static ulong[] dim3933Kuo2Init = { 1, 1, 1, 15, 15, 45, 51, 23, 51, 279, 1463, 1585, 5863, 6625, 32427, 33877, 0 }; - static ulong[] dim3934Kuo2Init = { 1, 1, 1, 9, 9, 47, 83, 61, 493, 399, 1055, 231, 671, 11643, 9151, 48169, 0 }; - static ulong[] dim3935Kuo2Init = { 1, 3, 1, 13, 9, 43, 3, 119, 439, 335, 1167, 249, 193, 4305, 8821, 49611, 0 }; - static ulong[] dim3936Kuo2Init = { 1, 3, 5, 1, 19, 55, 43, 251, 17, 865, 147, 507, 1315, 12029, 5077, 6003, 0 }; - static ulong[] dim3937Kuo2Init = { 1, 3, 7, 7, 3, 23, 83, 7, 241, 197, 139, 1325, 7777, 8425, 27451, 47015, 0 }; - static ulong[] dim3938Kuo2Init = { 1, 1, 3, 3, 27, 29, 37, 31, 325, 937, 59, 2615, 7331, 15635, 29159, 49697, 0 }; - static ulong[] dim3939Kuo2Init = { 1, 3, 3, 5, 27, 47, 125, 165, 363, 573, 189, 3249, 1471, 7869, 6169, 43525, 0 }; - static ulong[] dim3940Kuo2Init = { 1, 1, 3, 13, 19, 33, 15, 123, 245, 939, 209, 853, 6485, 5059, 21891, 7115, 0 }; - static ulong[] dim3941Kuo2Init = { 1, 3, 7, 1, 23, 59, 91, 197, 79, 381, 151, 3533, 7553, 511, 3381, 29339, 0 }; - static ulong[] dim3942Kuo2Init = { 1, 3, 5, 3, 21, 61, 73, 57, 317, 77, 2027, 1055, 3599, 15157, 17017, 23563, 0 }; - static ulong[] dim3943Kuo2Init = { 1, 1, 7, 1, 15, 43, 97, 205, 421, 901, 1589, 2051, 5737, 13231, 15325, 54725, 0 }; - static ulong[] dim3944Kuo2Init = { 1, 1, 5, 5, 31, 33, 93, 129, 385, 961, 733, 277, 3555, 5619, 16499, 57747, 0 }; - static ulong[] dim3945Kuo2Init = { 1, 3, 1, 5, 17, 3, 65, 167, 237, 785, 771, 4033, 6053, 343, 9499, 55861, 0 }; - static ulong[] dim3946Kuo2Init = { 1, 3, 3, 3, 19, 57, 23, 119, 75, 435, 1023, 2357, 4671, 14581, 15343, 2383, 0 }; - - static ulong[][] Kuo2initializers = { - dim1Kuo2Init, - dim2Kuo2Init, - dim3Kuo2Init, - dim4Kuo2Init, - dim5Kuo2Init, - dim6Kuo2Init, - dim7Kuo2Init, - dim8Kuo2Init, - dim9Kuo2Init, - dim10Kuo2Init, - dim11Kuo2Init, - dim12Kuo2Init, - dim13Kuo2Init, - dim14Kuo2Init, - dim15Kuo2Init, - dim16Kuo2Init, - dim17Kuo2Init, - dim18Kuo2Init, - dim19Kuo2Init, - dim20Kuo2Init, - dim21Kuo2Init, - dim22Kuo2Init, - dim23Kuo2Init, - dim24Kuo2Init, - dim25Kuo2Init, - dim26Kuo2Init, - dim27Kuo2Init, - dim28Kuo2Init, - dim29Kuo2Init, - dim30Kuo2Init, - dim31Kuo2Init, - dim32Kuo2Init, - dim33Kuo2Init, - dim34Kuo2Init, - dim35Kuo2Init, - dim36Kuo2Init, - dim37Kuo2Init, - dim38Kuo2Init, - dim39Kuo2Init, - dim40Kuo2Init, - dim41Kuo2Init, - dim42Kuo2Init, - dim43Kuo2Init, - dim44Kuo2Init, - dim45Kuo2Init, - dim46Kuo2Init, - dim47Kuo2Init, - dim48Kuo2Init, - dim49Kuo2Init, - dim50Kuo2Init, - dim51Kuo2Init, - dim52Kuo2Init, - dim53Kuo2Init, - dim54Kuo2Init, - dim55Kuo2Init, - dim56Kuo2Init, - dim57Kuo2Init, - dim58Kuo2Init, - dim59Kuo2Init, - dim60Kuo2Init, - dim61Kuo2Init, - dim62Kuo2Init, - dim63Kuo2Init, - dim64Kuo2Init, - dim65Kuo2Init, - dim66Kuo2Init, - dim67Kuo2Init, - dim68Kuo2Init, - dim69Kuo2Init, - dim70Kuo2Init, - dim71Kuo2Init, - dim72Kuo2Init, - dim73Kuo2Init, - dim74Kuo2Init, - dim75Kuo2Init, - dim76Kuo2Init, - dim77Kuo2Init, - dim78Kuo2Init, - dim79Kuo2Init, - dim80Kuo2Init, - dim81Kuo2Init, - dim82Kuo2Init, - dim83Kuo2Init, - dim84Kuo2Init, - dim85Kuo2Init, - dim86Kuo2Init, - dim87Kuo2Init, - dim88Kuo2Init, - dim89Kuo2Init, - dim90Kuo2Init, - dim91Kuo2Init, - dim92Kuo2Init, - dim93Kuo2Init, - dim94Kuo2Init, - dim95Kuo2Init, - dim96Kuo2Init, - dim97Kuo2Init, - dim98Kuo2Init, - dim99Kuo2Init, - dim100Kuo2Init, - dim101Kuo2Init, - dim102Kuo2Init, - dim103Kuo2Init, - dim104Kuo2Init, - dim105Kuo2Init, - dim106Kuo2Init, - dim107Kuo2Init, - dim108Kuo2Init, - dim109Kuo2Init, - dim110Kuo2Init, - dim111Kuo2Init, - dim112Kuo2Init, - dim113Kuo2Init, - dim114Kuo2Init, - dim115Kuo2Init, - dim116Kuo2Init, - dim117Kuo2Init, - dim118Kuo2Init, - dim119Kuo2Init, - dim120Kuo2Init, - dim121Kuo2Init, - dim122Kuo2Init, - dim123Kuo2Init, - dim124Kuo2Init, - dim125Kuo2Init, - dim126Kuo2Init, - dim127Kuo2Init, - dim128Kuo2Init, - dim129Kuo2Init, - dim130Kuo2Init, - dim131Kuo2Init, - dim132Kuo2Init, - dim133Kuo2Init, - dim134Kuo2Init, - dim135Kuo2Init, - dim136Kuo2Init, - dim137Kuo2Init, - dim138Kuo2Init, - dim139Kuo2Init, - dim140Kuo2Init, - dim141Kuo2Init, - dim142Kuo2Init, - dim143Kuo2Init, - dim144Kuo2Init, - dim145Kuo2Init, - dim146Kuo2Init, - dim147Kuo2Init, - dim148Kuo2Init, - dim149Kuo2Init, - dim150Kuo2Init, - dim151Kuo2Init, - dim152Kuo2Init, - dim153Kuo2Init, - dim154Kuo2Init, - dim155Kuo2Init, - dim156Kuo2Init, - dim157Kuo2Init, - dim158Kuo2Init, - dim159Kuo2Init, - dim160Kuo2Init, - dim161Kuo2Init, - dim162Kuo2Init, - dim163Kuo2Init, - dim164Kuo2Init, - dim165Kuo2Init, - dim166Kuo2Init, - dim167Kuo2Init, - dim168Kuo2Init, - dim169Kuo2Init, - dim170Kuo2Init, - dim171Kuo2Init, - dim172Kuo2Init, - dim173Kuo2Init, - dim174Kuo2Init, - dim175Kuo2Init, - dim176Kuo2Init, - dim177Kuo2Init, - dim178Kuo2Init, - dim179Kuo2Init, - dim180Kuo2Init, - dim181Kuo2Init, - dim182Kuo2Init, - dim183Kuo2Init, - dim184Kuo2Init, - dim185Kuo2Init, - dim186Kuo2Init, - dim187Kuo2Init, - dim188Kuo2Init, - dim189Kuo2Init, - dim190Kuo2Init, - dim191Kuo2Init, - dim192Kuo2Init, - dim193Kuo2Init, - dim194Kuo2Init, - dim195Kuo2Init, - dim196Kuo2Init, - dim197Kuo2Init, - dim198Kuo2Init, - dim199Kuo2Init, - dim200Kuo2Init, - dim201Kuo2Init, - dim202Kuo2Init, - dim203Kuo2Init, - dim204Kuo2Init, - dim205Kuo2Init, - dim206Kuo2Init, - dim207Kuo2Init, - dim208Kuo2Init, - dim209Kuo2Init, - dim210Kuo2Init, - dim211Kuo2Init, - dim212Kuo2Init, - dim213Kuo2Init, - dim214Kuo2Init, - dim215Kuo2Init, - dim216Kuo2Init, - dim217Kuo2Init, - dim218Kuo2Init, - dim219Kuo2Init, - dim220Kuo2Init, - dim221Kuo2Init, - dim222Kuo2Init, - dim223Kuo2Init, - dim224Kuo2Init, - dim225Kuo2Init, - dim226Kuo2Init, - dim227Kuo2Init, - dim228Kuo2Init, - dim229Kuo2Init, - dim230Kuo2Init, - dim231Kuo2Init, - dim232Kuo2Init, - dim233Kuo2Init, - dim234Kuo2Init, - dim235Kuo2Init, - dim236Kuo2Init, - dim237Kuo2Init, - dim238Kuo2Init, - dim239Kuo2Init, - dim240Kuo2Init, - dim241Kuo2Init, - dim242Kuo2Init, - dim243Kuo2Init, - dim244Kuo2Init, - dim245Kuo2Init, - dim246Kuo2Init, - dim247Kuo2Init, - dim248Kuo2Init, - dim249Kuo2Init, - dim250Kuo2Init, - dim251Kuo2Init, - dim252Kuo2Init, - dim253Kuo2Init, - dim254Kuo2Init, - dim255Kuo2Init, - dim256Kuo2Init, - dim257Kuo2Init, - dim258Kuo2Init, - dim259Kuo2Init, - dim260Kuo2Init, - dim261Kuo2Init, - dim262Kuo2Init, - dim263Kuo2Init, - dim264Kuo2Init, - dim265Kuo2Init, - dim266Kuo2Init, - dim267Kuo2Init, - dim268Kuo2Init, - dim269Kuo2Init, - dim270Kuo2Init, - dim271Kuo2Init, - dim272Kuo2Init, - dim273Kuo2Init, - dim274Kuo2Init, - dim275Kuo2Init, - dim276Kuo2Init, - dim277Kuo2Init, - dim278Kuo2Init, - dim279Kuo2Init, - dim280Kuo2Init, - dim281Kuo2Init, - dim282Kuo2Init, - dim283Kuo2Init, - dim284Kuo2Init, - dim285Kuo2Init, - dim286Kuo2Init, - dim287Kuo2Init, - dim288Kuo2Init, - dim289Kuo2Init, - dim290Kuo2Init, - dim291Kuo2Init, - dim292Kuo2Init, - dim293Kuo2Init, - dim294Kuo2Init, - dim295Kuo2Init, - dim296Kuo2Init, - dim297Kuo2Init, - dim298Kuo2Init, - dim299Kuo2Init, - dim300Kuo2Init, - dim301Kuo2Init, - dim302Kuo2Init, - dim303Kuo2Init, - dim304Kuo2Init, - dim305Kuo2Init, - dim306Kuo2Init, - dim307Kuo2Init, - dim308Kuo2Init, - dim309Kuo2Init, - dim310Kuo2Init, - dim311Kuo2Init, - dim312Kuo2Init, - dim313Kuo2Init, - dim314Kuo2Init, - dim315Kuo2Init, - dim316Kuo2Init, - dim317Kuo2Init, - dim318Kuo2Init, - dim319Kuo2Init, - dim320Kuo2Init, - dim321Kuo2Init, - dim322Kuo2Init, - dim323Kuo2Init, - dim324Kuo2Init, - dim325Kuo2Init, - dim326Kuo2Init, - dim327Kuo2Init, - dim328Kuo2Init, - dim329Kuo2Init, - dim330Kuo2Init, - dim331Kuo2Init, - dim332Kuo2Init, - dim333Kuo2Init, - dim334Kuo2Init, - dim335Kuo2Init, - dim336Kuo2Init, - dim337Kuo2Init, - dim338Kuo2Init, - dim339Kuo2Init, - dim340Kuo2Init, - dim341Kuo2Init, - dim342Kuo2Init, - dim343Kuo2Init, - dim344Kuo2Init, - dim345Kuo2Init, - dim346Kuo2Init, - dim347Kuo2Init, - dim348Kuo2Init, - dim349Kuo2Init, - dim350Kuo2Init, - dim351Kuo2Init, - dim352Kuo2Init, - dim353Kuo2Init, - dim354Kuo2Init, - dim355Kuo2Init, - dim356Kuo2Init, - dim357Kuo2Init, - dim358Kuo2Init, - dim359Kuo2Init, - dim360Kuo2Init, - dim361Kuo2Init, - dim362Kuo2Init, - dim363Kuo2Init, - dim364Kuo2Init, - dim365Kuo2Init, - dim366Kuo2Init, - dim367Kuo2Init, - dim368Kuo2Init, - dim369Kuo2Init, - dim370Kuo2Init, - dim371Kuo2Init, - dim372Kuo2Init, - dim373Kuo2Init, - dim374Kuo2Init, - dim375Kuo2Init, - dim376Kuo2Init, - dim377Kuo2Init, - dim378Kuo2Init, - dim379Kuo2Init, - dim380Kuo2Init, - dim381Kuo2Init, - dim382Kuo2Init, - dim383Kuo2Init, - dim384Kuo2Init, - dim385Kuo2Init, - dim386Kuo2Init, - dim387Kuo2Init, - dim388Kuo2Init, - dim389Kuo2Init, - dim390Kuo2Init, - dim391Kuo2Init, - dim392Kuo2Init, - dim393Kuo2Init, - dim394Kuo2Init, - dim395Kuo2Init, - dim396Kuo2Init, - dim397Kuo2Init, - dim398Kuo2Init, - dim399Kuo2Init, - dim400Kuo2Init, - dim401Kuo2Init, - dim402Kuo2Init, - dim403Kuo2Init, - dim404Kuo2Init, - dim405Kuo2Init, - dim406Kuo2Init, - dim407Kuo2Init, - dim408Kuo2Init, - dim409Kuo2Init, - dim410Kuo2Init, - dim411Kuo2Init, - dim412Kuo2Init, - dim413Kuo2Init, - dim414Kuo2Init, - dim415Kuo2Init, - dim416Kuo2Init, - dim417Kuo2Init, - dim418Kuo2Init, - dim419Kuo2Init, - dim420Kuo2Init, - dim421Kuo2Init, - dim422Kuo2Init, - dim423Kuo2Init, - dim424Kuo2Init, - dim425Kuo2Init, - dim426Kuo2Init, - dim427Kuo2Init, - dim428Kuo2Init, - dim429Kuo2Init, - dim430Kuo2Init, - dim431Kuo2Init, - dim432Kuo2Init, - dim433Kuo2Init, - dim434Kuo2Init, - dim435Kuo2Init, - dim436Kuo2Init, - dim437Kuo2Init, - dim438Kuo2Init, - dim439Kuo2Init, - dim440Kuo2Init, - dim441Kuo2Init, - dim442Kuo2Init, - dim443Kuo2Init, - dim444Kuo2Init, - dim445Kuo2Init, - dim446Kuo2Init, - dim447Kuo2Init, - dim448Kuo2Init, - dim449Kuo2Init, - dim450Kuo2Init, - dim451Kuo2Init, - dim452Kuo2Init, - dim453Kuo2Init, - dim454Kuo2Init, - dim455Kuo2Init, - dim456Kuo2Init, - dim457Kuo2Init, - dim458Kuo2Init, - dim459Kuo2Init, - dim460Kuo2Init, - dim461Kuo2Init, - dim462Kuo2Init, - dim463Kuo2Init, - dim464Kuo2Init, - dim465Kuo2Init, - dim466Kuo2Init, - dim467Kuo2Init, - dim468Kuo2Init, - dim469Kuo2Init, - dim470Kuo2Init, - dim471Kuo2Init, - dim472Kuo2Init, - dim473Kuo2Init, - dim474Kuo2Init, - dim475Kuo2Init, - dim476Kuo2Init, - dim477Kuo2Init, - dim478Kuo2Init, - dim479Kuo2Init, - dim480Kuo2Init, - dim481Kuo2Init, - dim482Kuo2Init, - dim483Kuo2Init, - dim484Kuo2Init, - dim485Kuo2Init, - dim486Kuo2Init, - dim487Kuo2Init, - dim488Kuo2Init, - dim489Kuo2Init, - dim490Kuo2Init, - dim491Kuo2Init, - dim492Kuo2Init, - dim493Kuo2Init, - dim494Kuo2Init, - dim495Kuo2Init, - dim496Kuo2Init, - dim497Kuo2Init, - dim498Kuo2Init, - dim499Kuo2Init, - dim500Kuo2Init, - dim501Kuo2Init, - dim502Kuo2Init, - dim503Kuo2Init, - dim504Kuo2Init, - dim505Kuo2Init, - dim506Kuo2Init, - dim507Kuo2Init, - dim508Kuo2Init, - dim509Kuo2Init, - dim510Kuo2Init, - dim511Kuo2Init, - dim512Kuo2Init, - dim513Kuo2Init, - dim514Kuo2Init, - dim515Kuo2Init, - dim516Kuo2Init, - dim517Kuo2Init, - dim518Kuo2Init, - dim519Kuo2Init, - dim520Kuo2Init, - dim521Kuo2Init, - dim522Kuo2Init, - dim523Kuo2Init, - dim524Kuo2Init, - dim525Kuo2Init, - dim526Kuo2Init, - dim527Kuo2Init, - dim528Kuo2Init, - dim529Kuo2Init, - dim530Kuo2Init, - dim531Kuo2Init, - dim532Kuo2Init, - dim533Kuo2Init, - dim534Kuo2Init, - dim535Kuo2Init, - dim536Kuo2Init, - dim537Kuo2Init, - dim538Kuo2Init, - dim539Kuo2Init, - dim540Kuo2Init, - dim541Kuo2Init, - dim542Kuo2Init, - dim543Kuo2Init, - dim544Kuo2Init, - dim545Kuo2Init, - dim546Kuo2Init, - dim547Kuo2Init, - dim548Kuo2Init, - dim549Kuo2Init, - dim550Kuo2Init, - dim551Kuo2Init, - dim552Kuo2Init, - dim553Kuo2Init, - dim554Kuo2Init, - dim555Kuo2Init, - dim556Kuo2Init, - dim557Kuo2Init, - dim558Kuo2Init, - dim559Kuo2Init, - dim560Kuo2Init, - dim561Kuo2Init, - dim562Kuo2Init, - dim563Kuo2Init, - dim564Kuo2Init, - dim565Kuo2Init, - dim566Kuo2Init, - dim567Kuo2Init, - dim568Kuo2Init, - dim569Kuo2Init, - dim570Kuo2Init, - dim571Kuo2Init, - dim572Kuo2Init, - dim573Kuo2Init, - dim574Kuo2Init, - dim575Kuo2Init, - dim576Kuo2Init, - dim577Kuo2Init, - dim578Kuo2Init, - dim579Kuo2Init, - dim580Kuo2Init, - dim581Kuo2Init, - dim582Kuo2Init, - dim583Kuo2Init, - dim584Kuo2Init, - dim585Kuo2Init, - dim586Kuo2Init, - dim587Kuo2Init, - dim588Kuo2Init, - dim589Kuo2Init, - dim590Kuo2Init, - dim591Kuo2Init, - dim592Kuo2Init, - dim593Kuo2Init, - dim594Kuo2Init, - dim595Kuo2Init, - dim596Kuo2Init, - dim597Kuo2Init, - dim598Kuo2Init, - dim599Kuo2Init, - dim600Kuo2Init, - dim601Kuo2Init, - dim602Kuo2Init, - dim603Kuo2Init, - dim604Kuo2Init, - dim605Kuo2Init, - dim606Kuo2Init, - dim607Kuo2Init, - dim608Kuo2Init, - dim609Kuo2Init, - dim610Kuo2Init, - dim611Kuo2Init, - dim612Kuo2Init, - dim613Kuo2Init, - dim614Kuo2Init, - dim615Kuo2Init, - dim616Kuo2Init, - dim617Kuo2Init, - dim618Kuo2Init, - dim619Kuo2Init, - dim620Kuo2Init, - dim621Kuo2Init, - dim622Kuo2Init, - dim623Kuo2Init, - dim624Kuo2Init, - dim625Kuo2Init, - dim626Kuo2Init, - dim627Kuo2Init, - dim628Kuo2Init, - dim629Kuo2Init, - dim630Kuo2Init, - dim631Kuo2Init, - dim632Kuo2Init, - dim633Kuo2Init, - dim634Kuo2Init, - dim635Kuo2Init, - dim636Kuo2Init, - dim637Kuo2Init, - dim638Kuo2Init, - dim639Kuo2Init, - dim640Kuo2Init, - dim641Kuo2Init, - dim642Kuo2Init, - dim643Kuo2Init, - dim644Kuo2Init, - dim645Kuo2Init, - dim646Kuo2Init, - dim647Kuo2Init, - dim648Kuo2Init, - dim649Kuo2Init, - dim650Kuo2Init, - dim651Kuo2Init, - dim652Kuo2Init, - dim653Kuo2Init, - dim654Kuo2Init, - dim655Kuo2Init, - dim656Kuo2Init, - dim657Kuo2Init, - dim658Kuo2Init, - dim659Kuo2Init, - dim660Kuo2Init, - dim661Kuo2Init, - dim662Kuo2Init, - dim663Kuo2Init, - dim664Kuo2Init, - dim665Kuo2Init, - dim666Kuo2Init, - dim667Kuo2Init, - dim668Kuo2Init, - dim669Kuo2Init, - dim670Kuo2Init, - dim671Kuo2Init, - dim672Kuo2Init, - dim673Kuo2Init, - dim674Kuo2Init, - dim675Kuo2Init, - dim676Kuo2Init, - dim677Kuo2Init, - dim678Kuo2Init, - dim679Kuo2Init, - dim680Kuo2Init, - dim681Kuo2Init, - dim682Kuo2Init, - dim683Kuo2Init, - dim684Kuo2Init, - dim685Kuo2Init, - dim686Kuo2Init, - dim687Kuo2Init, - dim688Kuo2Init, - dim689Kuo2Init, - dim690Kuo2Init, - dim691Kuo2Init, - dim692Kuo2Init, - dim693Kuo2Init, - dim694Kuo2Init, - dim695Kuo2Init, - dim696Kuo2Init, - dim697Kuo2Init, - dim698Kuo2Init, - dim699Kuo2Init, - dim700Kuo2Init, - dim701Kuo2Init, - dim702Kuo2Init, - dim703Kuo2Init, - dim704Kuo2Init, - dim705Kuo2Init, - dim706Kuo2Init, - dim707Kuo2Init, - dim708Kuo2Init, - dim709Kuo2Init, - dim710Kuo2Init, - dim711Kuo2Init, - dim712Kuo2Init, - dim713Kuo2Init, - dim714Kuo2Init, - dim715Kuo2Init, - dim716Kuo2Init, - dim717Kuo2Init, - dim718Kuo2Init, - dim719Kuo2Init, - dim720Kuo2Init, - dim721Kuo2Init, - dim722Kuo2Init, - dim723Kuo2Init, - dim724Kuo2Init, - dim725Kuo2Init, - dim726Kuo2Init, - dim727Kuo2Init, - dim728Kuo2Init, - dim729Kuo2Init, - dim730Kuo2Init, - dim731Kuo2Init, - dim732Kuo2Init, - dim733Kuo2Init, - dim734Kuo2Init, - dim735Kuo2Init, - dim736Kuo2Init, - dim737Kuo2Init, - dim738Kuo2Init, - dim739Kuo2Init, - dim740Kuo2Init, - dim741Kuo2Init, - dim742Kuo2Init, - dim743Kuo2Init, - dim744Kuo2Init, - dim745Kuo2Init, - dim746Kuo2Init, - dim747Kuo2Init, - dim748Kuo2Init, - dim749Kuo2Init, - dim750Kuo2Init, - dim751Kuo2Init, - dim752Kuo2Init, - dim753Kuo2Init, - dim754Kuo2Init, - dim755Kuo2Init, - dim756Kuo2Init, - dim757Kuo2Init, - dim758Kuo2Init, - dim759Kuo2Init, - dim760Kuo2Init, - dim761Kuo2Init, - dim762Kuo2Init, - dim763Kuo2Init, - dim764Kuo2Init, - dim765Kuo2Init, - dim766Kuo2Init, - dim767Kuo2Init, - dim768Kuo2Init, - dim769Kuo2Init, - dim770Kuo2Init, - dim771Kuo2Init, - dim772Kuo2Init, - dim773Kuo2Init, - dim774Kuo2Init, - dim775Kuo2Init, - dim776Kuo2Init, - dim777Kuo2Init, - dim778Kuo2Init, - dim779Kuo2Init, - dim780Kuo2Init, - dim781Kuo2Init, - dim782Kuo2Init, - dim783Kuo2Init, - dim784Kuo2Init, - dim785Kuo2Init, - dim786Kuo2Init, - dim787Kuo2Init, - dim788Kuo2Init, - dim789Kuo2Init, - dim790Kuo2Init, - dim791Kuo2Init, - dim792Kuo2Init, - dim793Kuo2Init, - dim794Kuo2Init, - dim795Kuo2Init, - dim796Kuo2Init, - dim797Kuo2Init, - dim798Kuo2Init, - dim799Kuo2Init, - dim800Kuo2Init, - dim801Kuo2Init, - dim802Kuo2Init, - dim803Kuo2Init, - dim804Kuo2Init, - dim805Kuo2Init, - dim806Kuo2Init, - dim807Kuo2Init, - dim808Kuo2Init, - dim809Kuo2Init, - dim810Kuo2Init, - dim811Kuo2Init, - dim812Kuo2Init, - dim813Kuo2Init, - dim814Kuo2Init, - dim815Kuo2Init, - dim816Kuo2Init, - dim817Kuo2Init, - dim818Kuo2Init, - dim819Kuo2Init, - dim820Kuo2Init, - dim821Kuo2Init, - dim822Kuo2Init, - dim823Kuo2Init, - dim824Kuo2Init, - dim825Kuo2Init, - dim826Kuo2Init, - dim827Kuo2Init, - dim828Kuo2Init, - dim829Kuo2Init, - dim830Kuo2Init, - dim831Kuo2Init, - dim832Kuo2Init, - dim833Kuo2Init, - dim834Kuo2Init, - dim835Kuo2Init, - dim836Kuo2Init, - dim837Kuo2Init, - dim838Kuo2Init, - dim839Kuo2Init, - dim840Kuo2Init, - dim841Kuo2Init, - dim842Kuo2Init, - dim843Kuo2Init, - dim844Kuo2Init, - dim845Kuo2Init, - dim846Kuo2Init, - dim847Kuo2Init, - dim848Kuo2Init, - dim849Kuo2Init, - dim850Kuo2Init, - dim851Kuo2Init, - dim852Kuo2Init, - dim853Kuo2Init, - dim854Kuo2Init, - dim855Kuo2Init, - dim856Kuo2Init, - dim857Kuo2Init, - dim858Kuo2Init, - dim859Kuo2Init, - dim860Kuo2Init, - dim861Kuo2Init, - dim862Kuo2Init, - dim863Kuo2Init, - dim864Kuo2Init, - dim865Kuo2Init, - dim866Kuo2Init, - dim867Kuo2Init, - dim868Kuo2Init, - dim869Kuo2Init, - dim870Kuo2Init, - dim871Kuo2Init, - dim872Kuo2Init, - dim873Kuo2Init, - dim874Kuo2Init, - dim875Kuo2Init, - dim876Kuo2Init, - dim877Kuo2Init, - dim878Kuo2Init, - dim879Kuo2Init, - dim880Kuo2Init, - dim881Kuo2Init, - dim882Kuo2Init, - dim883Kuo2Init, - dim884Kuo2Init, - dim885Kuo2Init, - dim886Kuo2Init, - dim887Kuo2Init, - dim888Kuo2Init, - dim889Kuo2Init, - dim890Kuo2Init, - dim891Kuo2Init, - dim892Kuo2Init, - dim893Kuo2Init, - dim894Kuo2Init, - dim895Kuo2Init, - dim896Kuo2Init, - dim897Kuo2Init, - dim898Kuo2Init, - dim899Kuo2Init, - dim900Kuo2Init, - dim901Kuo2Init, - dim902Kuo2Init, - dim903Kuo2Init, - dim904Kuo2Init, - dim905Kuo2Init, - dim906Kuo2Init, - dim907Kuo2Init, - dim908Kuo2Init, - dim909Kuo2Init, - dim910Kuo2Init, - dim911Kuo2Init, - dim912Kuo2Init, - dim913Kuo2Init, - dim914Kuo2Init, - dim915Kuo2Init, - dim916Kuo2Init, - dim917Kuo2Init, - dim918Kuo2Init, - dim919Kuo2Init, - dim920Kuo2Init, - dim921Kuo2Init, - dim922Kuo2Init, - dim923Kuo2Init, - dim924Kuo2Init, - dim925Kuo2Init, - dim926Kuo2Init, - dim927Kuo2Init, - dim928Kuo2Init, - dim929Kuo2Init, - dim930Kuo2Init, - dim931Kuo2Init, - dim932Kuo2Init, - dim933Kuo2Init, - dim934Kuo2Init, - dim935Kuo2Init, - dim936Kuo2Init, - dim937Kuo2Init, - dim938Kuo2Init, - dim939Kuo2Init, - dim940Kuo2Init, - dim941Kuo2Init, - dim942Kuo2Init, - dim943Kuo2Init, - dim944Kuo2Init, - dim945Kuo2Init, - dim946Kuo2Init, - dim947Kuo2Init, - dim948Kuo2Init, - dim949Kuo2Init, - dim950Kuo2Init, - dim951Kuo2Init, - dim952Kuo2Init, - dim953Kuo2Init, - dim954Kuo2Init, - dim955Kuo2Init, - dim956Kuo2Init, - dim957Kuo2Init, - dim958Kuo2Init, - dim959Kuo2Init, - dim960Kuo2Init, - dim961Kuo2Init, - dim962Kuo2Init, - dim963Kuo2Init, - dim964Kuo2Init, - dim965Kuo2Init, - dim966Kuo2Init, - dim967Kuo2Init, - dim968Kuo2Init, - dim969Kuo2Init, - dim970Kuo2Init, - dim971Kuo2Init, - dim972Kuo2Init, - dim973Kuo2Init, - dim974Kuo2Init, - dim975Kuo2Init, - dim976Kuo2Init, - dim977Kuo2Init, - dim978Kuo2Init, - dim979Kuo2Init, - dim980Kuo2Init, - dim981Kuo2Init, - dim982Kuo2Init, - dim983Kuo2Init, - dim984Kuo2Init, - dim985Kuo2Init, - dim986Kuo2Init, - dim987Kuo2Init, - dim988Kuo2Init, - dim989Kuo2Init, - dim990Kuo2Init, - dim991Kuo2Init, - dim992Kuo2Init, - dim993Kuo2Init, - dim994Kuo2Init, - dim995Kuo2Init, - dim996Kuo2Init, - dim997Kuo2Init, - dim998Kuo2Init, - dim999Kuo2Init, - dim1000Kuo2Init, - dim1001Kuo2Init, - dim1002Kuo2Init, - dim1003Kuo2Init, - dim1004Kuo2Init, - dim1005Kuo2Init, - dim1006Kuo2Init, - dim1007Kuo2Init, - dim1008Kuo2Init, - dim1009Kuo2Init, - dim1010Kuo2Init, - dim1011Kuo2Init, - dim1012Kuo2Init, - dim1013Kuo2Init, - dim1014Kuo2Init, - dim1015Kuo2Init, - dim1016Kuo2Init, - dim1017Kuo2Init, - dim1018Kuo2Init, - dim1019Kuo2Init, - dim1020Kuo2Init, - dim1021Kuo2Init, - dim1022Kuo2Init, - dim1023Kuo2Init, - dim1024Kuo2Init, - dim1025Kuo2Init, - dim1026Kuo2Init, - dim1027Kuo2Init, - dim1028Kuo2Init, - dim1029Kuo2Init, - dim1030Kuo2Init, - dim1031Kuo2Init, - dim1032Kuo2Init, - dim1033Kuo2Init, - dim1034Kuo2Init, - dim1035Kuo2Init, - dim1036Kuo2Init, - dim1037Kuo2Init, - dim1038Kuo2Init, - dim1039Kuo2Init, - dim1040Kuo2Init, - dim1041Kuo2Init, - dim1042Kuo2Init, - dim1043Kuo2Init, - dim1044Kuo2Init, - dim1045Kuo2Init, - dim1046Kuo2Init, - dim1047Kuo2Init, - dim1048Kuo2Init, - dim1049Kuo2Init, - dim1050Kuo2Init, - dim1051Kuo2Init, - dim1052Kuo2Init, - dim1053Kuo2Init, - dim1054Kuo2Init, - dim1055Kuo2Init, - dim1056Kuo2Init, - dim1057Kuo2Init, - dim1058Kuo2Init, - dim1059Kuo2Init, - dim1060Kuo2Init, - dim1061Kuo2Init, - dim1062Kuo2Init, - dim1063Kuo2Init, - dim1064Kuo2Init, - dim1065Kuo2Init, - dim1066Kuo2Init, - dim1067Kuo2Init, - dim1068Kuo2Init, - dim1069Kuo2Init, - dim1070Kuo2Init, - dim1071Kuo2Init, - dim1072Kuo2Init, - dim1073Kuo2Init, - dim1074Kuo2Init, - dim1075Kuo2Init, - dim1076Kuo2Init, - dim1077Kuo2Init, - dim1078Kuo2Init, - dim1079Kuo2Init, - dim1080Kuo2Init, - dim1081Kuo2Init, - dim1082Kuo2Init, - dim1083Kuo2Init, - dim1084Kuo2Init, - dim1085Kuo2Init, - dim1086Kuo2Init, - dim1087Kuo2Init, - dim1088Kuo2Init, - dim1089Kuo2Init, - dim1090Kuo2Init, - dim1091Kuo2Init, - dim1092Kuo2Init, - dim1093Kuo2Init, - dim1094Kuo2Init, - dim1095Kuo2Init, - dim1096Kuo2Init, - dim1097Kuo2Init, - dim1098Kuo2Init, - dim1099Kuo2Init, - dim1100Kuo2Init, - dim1101Kuo2Init, - dim1102Kuo2Init, - dim1103Kuo2Init, - dim1104Kuo2Init, - dim1105Kuo2Init, - dim1106Kuo2Init, - dim1107Kuo2Init, - dim1108Kuo2Init, - dim1109Kuo2Init, - dim1110Kuo2Init, - dim1111Kuo2Init, - dim1112Kuo2Init, - dim1113Kuo2Init, - dim1114Kuo2Init, - dim1115Kuo2Init, - dim1116Kuo2Init, - dim1117Kuo2Init, - dim1118Kuo2Init, - dim1119Kuo2Init, - dim1120Kuo2Init, - dim1121Kuo2Init, - dim1122Kuo2Init, - dim1123Kuo2Init, - dim1124Kuo2Init, - dim1125Kuo2Init, - dim1126Kuo2Init, - dim1127Kuo2Init, - dim1128Kuo2Init, - dim1129Kuo2Init, - dim1130Kuo2Init, - dim1131Kuo2Init, - dim1132Kuo2Init, - dim1133Kuo2Init, - dim1134Kuo2Init, - dim1135Kuo2Init, - dim1136Kuo2Init, - dim1137Kuo2Init, - dim1138Kuo2Init, - dim1139Kuo2Init, - dim1140Kuo2Init, - dim1141Kuo2Init, - dim1142Kuo2Init, - dim1143Kuo2Init, - dim1144Kuo2Init, - dim1145Kuo2Init, - dim1146Kuo2Init, - dim1147Kuo2Init, - dim1148Kuo2Init, - dim1149Kuo2Init, - dim1150Kuo2Init, - dim1151Kuo2Init, - dim1152Kuo2Init, - dim1153Kuo2Init, - dim1154Kuo2Init, - dim1155Kuo2Init, - dim1156Kuo2Init, - dim1157Kuo2Init, - dim1158Kuo2Init, - dim1159Kuo2Init, - dim1160Kuo2Init, - dim1161Kuo2Init, - dim1162Kuo2Init, - dim1163Kuo2Init, - dim1164Kuo2Init, - dim1165Kuo2Init, - dim1166Kuo2Init, - dim1167Kuo2Init, - dim1168Kuo2Init, - dim1169Kuo2Init, - dim1170Kuo2Init, - dim1171Kuo2Init, - dim1172Kuo2Init, - dim1173Kuo2Init, - dim1174Kuo2Init, - dim1175Kuo2Init, - dim1176Kuo2Init, - dim1177Kuo2Init, - dim1178Kuo2Init, - dim1179Kuo2Init, - dim1180Kuo2Init, - dim1181Kuo2Init, - dim1182Kuo2Init, - dim1183Kuo2Init, - dim1184Kuo2Init, - dim1185Kuo2Init, - dim1186Kuo2Init, - dim1187Kuo2Init, - dim1188Kuo2Init, - dim1189Kuo2Init, - dim1190Kuo2Init, - dim1191Kuo2Init, - dim1192Kuo2Init, - dim1193Kuo2Init, - dim1194Kuo2Init, - dim1195Kuo2Init, - dim1196Kuo2Init, - dim1197Kuo2Init, - dim1198Kuo2Init, - dim1199Kuo2Init, - dim1200Kuo2Init, - dim1201Kuo2Init, - dim1202Kuo2Init, - dim1203Kuo2Init, - dim1204Kuo2Init, - dim1205Kuo2Init, - dim1206Kuo2Init, - dim1207Kuo2Init, - dim1208Kuo2Init, - dim1209Kuo2Init, - dim1210Kuo2Init, - dim1211Kuo2Init, - dim1212Kuo2Init, - dim1213Kuo2Init, - dim1214Kuo2Init, - dim1215Kuo2Init, - dim1216Kuo2Init, - dim1217Kuo2Init, - dim1218Kuo2Init, - dim1219Kuo2Init, - dim1220Kuo2Init, - dim1221Kuo2Init, - dim1222Kuo2Init, - dim1223Kuo2Init, - dim1224Kuo2Init, - dim1225Kuo2Init, - dim1226Kuo2Init, - dim1227Kuo2Init, - dim1228Kuo2Init, - dim1229Kuo2Init, - dim1230Kuo2Init, - dim1231Kuo2Init, - dim1232Kuo2Init, - dim1233Kuo2Init, - dim1234Kuo2Init, - dim1235Kuo2Init, - dim1236Kuo2Init, - dim1237Kuo2Init, - dim1238Kuo2Init, - dim1239Kuo2Init, - dim1240Kuo2Init, - dim1241Kuo2Init, - dim1242Kuo2Init, - dim1243Kuo2Init, - dim1244Kuo2Init, - dim1245Kuo2Init, - dim1246Kuo2Init, - dim1247Kuo2Init, - dim1248Kuo2Init, - dim1249Kuo2Init, - dim1250Kuo2Init, - dim1251Kuo2Init, - dim1252Kuo2Init, - dim1253Kuo2Init, - dim1254Kuo2Init, - dim1255Kuo2Init, - dim1256Kuo2Init, - dim1257Kuo2Init, - dim1258Kuo2Init, - dim1259Kuo2Init, - dim1260Kuo2Init, - dim1261Kuo2Init, - dim1262Kuo2Init, - dim1263Kuo2Init, - dim1264Kuo2Init, - dim1265Kuo2Init, - dim1266Kuo2Init, - dim1267Kuo2Init, - dim1268Kuo2Init, - dim1269Kuo2Init, - dim1270Kuo2Init, - dim1271Kuo2Init, - dim1272Kuo2Init, - dim1273Kuo2Init, - dim1274Kuo2Init, - dim1275Kuo2Init, - dim1276Kuo2Init, - dim1277Kuo2Init, - dim1278Kuo2Init, - dim1279Kuo2Init, - dim1280Kuo2Init, - dim1281Kuo2Init, - dim1282Kuo2Init, - dim1283Kuo2Init, - dim1284Kuo2Init, - dim1285Kuo2Init, - dim1286Kuo2Init, - dim1287Kuo2Init, - dim1288Kuo2Init, - dim1289Kuo2Init, - dim1290Kuo2Init, - dim1291Kuo2Init, - dim1292Kuo2Init, - dim1293Kuo2Init, - dim1294Kuo2Init, - dim1295Kuo2Init, - dim1296Kuo2Init, - dim1297Kuo2Init, - dim1298Kuo2Init, - dim1299Kuo2Init, - dim1300Kuo2Init, - dim1301Kuo2Init, - dim1302Kuo2Init, - dim1303Kuo2Init, - dim1304Kuo2Init, - dim1305Kuo2Init, - dim1306Kuo2Init, - dim1307Kuo2Init, - dim1308Kuo2Init, - dim1309Kuo2Init, - dim1310Kuo2Init, - dim1311Kuo2Init, - dim1312Kuo2Init, - dim1313Kuo2Init, - dim1314Kuo2Init, - dim1315Kuo2Init, - dim1316Kuo2Init, - dim1317Kuo2Init, - dim1318Kuo2Init, - dim1319Kuo2Init, - dim1320Kuo2Init, - dim1321Kuo2Init, - dim1322Kuo2Init, - dim1323Kuo2Init, - dim1324Kuo2Init, - dim1325Kuo2Init, - dim1326Kuo2Init, - dim1327Kuo2Init, - dim1328Kuo2Init, - dim1329Kuo2Init, - dim1330Kuo2Init, - dim1331Kuo2Init, - dim1332Kuo2Init, - dim1333Kuo2Init, - dim1334Kuo2Init, - dim1335Kuo2Init, - dim1336Kuo2Init, - dim1337Kuo2Init, - dim1338Kuo2Init, - dim1339Kuo2Init, - dim1340Kuo2Init, - dim1341Kuo2Init, - dim1342Kuo2Init, - dim1343Kuo2Init, - dim1344Kuo2Init, - dim1345Kuo2Init, - dim1346Kuo2Init, - dim1347Kuo2Init, - dim1348Kuo2Init, - dim1349Kuo2Init, - dim1350Kuo2Init, - dim1351Kuo2Init, - dim1352Kuo2Init, - dim1353Kuo2Init, - dim1354Kuo2Init, - dim1355Kuo2Init, - dim1356Kuo2Init, - dim1357Kuo2Init, - dim1358Kuo2Init, - dim1359Kuo2Init, - dim1360Kuo2Init, - dim1361Kuo2Init, - dim1362Kuo2Init, - dim1363Kuo2Init, - dim1364Kuo2Init, - dim1365Kuo2Init, - dim1366Kuo2Init, - dim1367Kuo2Init, - dim1368Kuo2Init, - dim1369Kuo2Init, - dim1370Kuo2Init, - dim1371Kuo2Init, - dim1372Kuo2Init, - dim1373Kuo2Init, - dim1374Kuo2Init, - dim1375Kuo2Init, - dim1376Kuo2Init, - dim1377Kuo2Init, - dim1378Kuo2Init, - dim1379Kuo2Init, - dim1380Kuo2Init, - dim1381Kuo2Init, - dim1382Kuo2Init, - dim1383Kuo2Init, - dim1384Kuo2Init, - dim1385Kuo2Init, - dim1386Kuo2Init, - dim1387Kuo2Init, - dim1388Kuo2Init, - dim1389Kuo2Init, - dim1390Kuo2Init, - dim1391Kuo2Init, - dim1392Kuo2Init, - dim1393Kuo2Init, - dim1394Kuo2Init, - dim1395Kuo2Init, - dim1396Kuo2Init, - dim1397Kuo2Init, - dim1398Kuo2Init, - dim1399Kuo2Init, - dim1400Kuo2Init, - dim1401Kuo2Init, - dim1402Kuo2Init, - dim1403Kuo2Init, - dim1404Kuo2Init, - dim1405Kuo2Init, - dim1406Kuo2Init, - dim1407Kuo2Init, - dim1408Kuo2Init, - dim1409Kuo2Init, - dim1410Kuo2Init, - dim1411Kuo2Init, - dim1412Kuo2Init, - dim1413Kuo2Init, - dim1414Kuo2Init, - dim1415Kuo2Init, - dim1416Kuo2Init, - dim1417Kuo2Init, - dim1418Kuo2Init, - dim1419Kuo2Init, - dim1420Kuo2Init, - dim1421Kuo2Init, - dim1422Kuo2Init, - dim1423Kuo2Init, - dim1424Kuo2Init, - dim1425Kuo2Init, - dim1426Kuo2Init, - dim1427Kuo2Init, - dim1428Kuo2Init, - dim1429Kuo2Init, - dim1430Kuo2Init, - dim1431Kuo2Init, - dim1432Kuo2Init, - dim1433Kuo2Init, - dim1434Kuo2Init, - dim1435Kuo2Init, - dim1436Kuo2Init, - dim1437Kuo2Init, - dim1438Kuo2Init, - dim1439Kuo2Init, - dim1440Kuo2Init, - dim1441Kuo2Init, - dim1442Kuo2Init, - dim1443Kuo2Init, - dim1444Kuo2Init, - dim1445Kuo2Init, - dim1446Kuo2Init, - dim1447Kuo2Init, - dim1448Kuo2Init, - dim1449Kuo2Init, - dim1450Kuo2Init, - dim1451Kuo2Init, - dim1452Kuo2Init, - dim1453Kuo2Init, - dim1454Kuo2Init, - dim1455Kuo2Init, - dim1456Kuo2Init, - dim1457Kuo2Init, - dim1458Kuo2Init, - dim1459Kuo2Init, - dim1460Kuo2Init, - dim1461Kuo2Init, - dim1462Kuo2Init, - dim1463Kuo2Init, - dim1464Kuo2Init, - dim1465Kuo2Init, - dim1466Kuo2Init, - dim1467Kuo2Init, - dim1468Kuo2Init, - dim1469Kuo2Init, - dim1470Kuo2Init, - dim1471Kuo2Init, - dim1472Kuo2Init, - dim1473Kuo2Init, - dim1474Kuo2Init, - dim1475Kuo2Init, - dim1476Kuo2Init, - dim1477Kuo2Init, - dim1478Kuo2Init, - dim1479Kuo2Init, - dim1480Kuo2Init, - dim1481Kuo2Init, - dim1482Kuo2Init, - dim1483Kuo2Init, - dim1484Kuo2Init, - dim1485Kuo2Init, - dim1486Kuo2Init, - dim1487Kuo2Init, - dim1488Kuo2Init, - dim1489Kuo2Init, - dim1490Kuo2Init, - dim1491Kuo2Init, - dim1492Kuo2Init, - dim1493Kuo2Init, - dim1494Kuo2Init, - dim1495Kuo2Init, - dim1496Kuo2Init, - dim1497Kuo2Init, - dim1498Kuo2Init, - dim1499Kuo2Init, - dim1500Kuo2Init, - dim1501Kuo2Init, - dim1502Kuo2Init, - dim1503Kuo2Init, - dim1504Kuo2Init, - dim1505Kuo2Init, - dim1506Kuo2Init, - dim1507Kuo2Init, - dim1508Kuo2Init, - dim1509Kuo2Init, - dim1510Kuo2Init, - dim1511Kuo2Init, - dim1512Kuo2Init, - dim1513Kuo2Init, - dim1514Kuo2Init, - dim1515Kuo2Init, - dim1516Kuo2Init, - dim1517Kuo2Init, - dim1518Kuo2Init, - dim1519Kuo2Init, - dim1520Kuo2Init, - dim1521Kuo2Init, - dim1522Kuo2Init, - dim1523Kuo2Init, - dim1524Kuo2Init, - dim1525Kuo2Init, - dim1526Kuo2Init, - dim1527Kuo2Init, - dim1528Kuo2Init, - dim1529Kuo2Init, - dim1530Kuo2Init, - dim1531Kuo2Init, - dim1532Kuo2Init, - dim1533Kuo2Init, - dim1534Kuo2Init, - dim1535Kuo2Init, - dim1536Kuo2Init, - dim1537Kuo2Init, - dim1538Kuo2Init, - dim1539Kuo2Init, - dim1540Kuo2Init, - dim1541Kuo2Init, - dim1542Kuo2Init, - dim1543Kuo2Init, - dim1544Kuo2Init, - dim1545Kuo2Init, - dim1546Kuo2Init, - dim1547Kuo2Init, - dim1548Kuo2Init, - dim1549Kuo2Init, - dim1550Kuo2Init, - dim1551Kuo2Init, - dim1552Kuo2Init, - dim1553Kuo2Init, - dim1554Kuo2Init, - dim1555Kuo2Init, - dim1556Kuo2Init, - dim1557Kuo2Init, - dim1558Kuo2Init, - dim1559Kuo2Init, - dim1560Kuo2Init, - dim1561Kuo2Init, - dim1562Kuo2Init, - dim1563Kuo2Init, - dim1564Kuo2Init, - dim1565Kuo2Init, - dim1566Kuo2Init, - dim1567Kuo2Init, - dim1568Kuo2Init, - dim1569Kuo2Init, - dim1570Kuo2Init, - dim1571Kuo2Init, - dim1572Kuo2Init, - dim1573Kuo2Init, - dim1574Kuo2Init, - dim1575Kuo2Init, - dim1576Kuo2Init, - dim1577Kuo2Init, - dim1578Kuo2Init, - dim1579Kuo2Init, - dim1580Kuo2Init, - dim1581Kuo2Init, - dim1582Kuo2Init, - dim1583Kuo2Init, - dim1584Kuo2Init, - dim1585Kuo2Init, - dim1586Kuo2Init, - dim1587Kuo2Init, - dim1588Kuo2Init, - dim1589Kuo2Init, - dim1590Kuo2Init, - dim1591Kuo2Init, - dim1592Kuo2Init, - dim1593Kuo2Init, - dim1594Kuo2Init, - dim1595Kuo2Init, - dim1596Kuo2Init, - dim1597Kuo2Init, - dim1598Kuo2Init, - dim1599Kuo2Init, - dim1600Kuo2Init, - dim1601Kuo2Init, - dim1602Kuo2Init, - dim1603Kuo2Init, - dim1604Kuo2Init, - dim1605Kuo2Init, - dim1606Kuo2Init, - dim1607Kuo2Init, - dim1608Kuo2Init, - dim1609Kuo2Init, - dim1610Kuo2Init, - dim1611Kuo2Init, - dim1612Kuo2Init, - dim1613Kuo2Init, - dim1614Kuo2Init, - dim1615Kuo2Init, - dim1616Kuo2Init, - dim1617Kuo2Init, - dim1618Kuo2Init, - dim1619Kuo2Init, - dim1620Kuo2Init, - dim1621Kuo2Init, - dim1622Kuo2Init, - dim1623Kuo2Init, - dim1624Kuo2Init, - dim1625Kuo2Init, - dim1626Kuo2Init, - dim1627Kuo2Init, - dim1628Kuo2Init, - dim1629Kuo2Init, - dim1630Kuo2Init, - dim1631Kuo2Init, - dim1632Kuo2Init, - dim1633Kuo2Init, - dim1634Kuo2Init, - dim1635Kuo2Init, - dim1636Kuo2Init, - dim1637Kuo2Init, - dim1638Kuo2Init, - dim1639Kuo2Init, - dim1640Kuo2Init, - dim1641Kuo2Init, - dim1642Kuo2Init, - dim1643Kuo2Init, - dim1644Kuo2Init, - dim1645Kuo2Init, - dim1646Kuo2Init, - dim1647Kuo2Init, - dim1648Kuo2Init, - dim1649Kuo2Init, - dim1650Kuo2Init, - dim1651Kuo2Init, - dim1652Kuo2Init, - dim1653Kuo2Init, - dim1654Kuo2Init, - dim1655Kuo2Init, - dim1656Kuo2Init, - dim1657Kuo2Init, - dim1658Kuo2Init, - dim1659Kuo2Init, - dim1660Kuo2Init, - dim1661Kuo2Init, - dim1662Kuo2Init, - dim1663Kuo2Init, - dim1664Kuo2Init, - dim1665Kuo2Init, - dim1666Kuo2Init, - dim1667Kuo2Init, - dim1668Kuo2Init, - dim1669Kuo2Init, - dim1670Kuo2Init, - dim1671Kuo2Init, - dim1672Kuo2Init, - dim1673Kuo2Init, - dim1674Kuo2Init, - dim1675Kuo2Init, - dim1676Kuo2Init, - dim1677Kuo2Init, - dim1678Kuo2Init, - dim1679Kuo2Init, - dim1680Kuo2Init, - dim1681Kuo2Init, - dim1682Kuo2Init, - dim1683Kuo2Init, - dim1684Kuo2Init, - dim1685Kuo2Init, - dim1686Kuo2Init, - dim1687Kuo2Init, - dim1688Kuo2Init, - dim1689Kuo2Init, - dim1690Kuo2Init, - dim1691Kuo2Init, - dim1692Kuo2Init, - dim1693Kuo2Init, - dim1694Kuo2Init, - dim1695Kuo2Init, - dim1696Kuo2Init, - dim1697Kuo2Init, - dim1698Kuo2Init, - dim1699Kuo2Init, - dim1700Kuo2Init, - dim1701Kuo2Init, - dim1702Kuo2Init, - dim1703Kuo2Init, - dim1704Kuo2Init, - dim1705Kuo2Init, - dim1706Kuo2Init, - dim1707Kuo2Init, - dim1708Kuo2Init, - dim1709Kuo2Init, - dim1710Kuo2Init, - dim1711Kuo2Init, - dim1712Kuo2Init, - dim1713Kuo2Init, - dim1714Kuo2Init, - dim1715Kuo2Init, - dim1716Kuo2Init, - dim1717Kuo2Init, - dim1718Kuo2Init, - dim1719Kuo2Init, - dim1720Kuo2Init, - dim1721Kuo2Init, - dim1722Kuo2Init, - dim1723Kuo2Init, - dim1724Kuo2Init, - dim1725Kuo2Init, - dim1726Kuo2Init, - dim1727Kuo2Init, - dim1728Kuo2Init, - dim1729Kuo2Init, - dim1730Kuo2Init, - dim1731Kuo2Init, - dim1732Kuo2Init, - dim1733Kuo2Init, - dim1734Kuo2Init, - dim1735Kuo2Init, - dim1736Kuo2Init, - dim1737Kuo2Init, - dim1738Kuo2Init, - dim1739Kuo2Init, - dim1740Kuo2Init, - dim1741Kuo2Init, - dim1742Kuo2Init, - dim1743Kuo2Init, - dim1744Kuo2Init, - dim1745Kuo2Init, - dim1746Kuo2Init, - dim1747Kuo2Init, - dim1748Kuo2Init, - dim1749Kuo2Init, - dim1750Kuo2Init, - dim1751Kuo2Init, - dim1752Kuo2Init, - dim1753Kuo2Init, - dim1754Kuo2Init, - dim1755Kuo2Init, - dim1756Kuo2Init, - dim1757Kuo2Init, - dim1758Kuo2Init, - dim1759Kuo2Init, - dim1760Kuo2Init, - dim1761Kuo2Init, - dim1762Kuo2Init, - dim1763Kuo2Init, - dim1764Kuo2Init, - dim1765Kuo2Init, - dim1766Kuo2Init, - dim1767Kuo2Init, - dim1768Kuo2Init, - dim1769Kuo2Init, - dim1770Kuo2Init, - dim1771Kuo2Init, - dim1772Kuo2Init, - dim1773Kuo2Init, - dim1774Kuo2Init, - dim1775Kuo2Init, - dim1776Kuo2Init, - dim1777Kuo2Init, - dim1778Kuo2Init, - dim1779Kuo2Init, - dim1780Kuo2Init, - dim1781Kuo2Init, - dim1782Kuo2Init, - dim1783Kuo2Init, - dim1784Kuo2Init, - dim1785Kuo2Init, - dim1786Kuo2Init, - dim1787Kuo2Init, - dim1788Kuo2Init, - dim1789Kuo2Init, - dim1790Kuo2Init, - dim1791Kuo2Init, - dim1792Kuo2Init, - dim1793Kuo2Init, - dim1794Kuo2Init, - dim1795Kuo2Init, - dim1796Kuo2Init, - dim1797Kuo2Init, - dim1798Kuo2Init, - dim1799Kuo2Init, - dim1800Kuo2Init, - dim1801Kuo2Init, - dim1802Kuo2Init, - dim1803Kuo2Init, - dim1804Kuo2Init, - dim1805Kuo2Init, - dim1806Kuo2Init, - dim1807Kuo2Init, - dim1808Kuo2Init, - dim1809Kuo2Init, - dim1810Kuo2Init, - dim1811Kuo2Init, - dim1812Kuo2Init, - dim1813Kuo2Init, - dim1814Kuo2Init, - dim1815Kuo2Init, - dim1816Kuo2Init, - dim1817Kuo2Init, - dim1818Kuo2Init, - dim1819Kuo2Init, - dim1820Kuo2Init, - dim1821Kuo2Init, - dim1822Kuo2Init, - dim1823Kuo2Init, - dim1824Kuo2Init, - dim1825Kuo2Init, - dim1826Kuo2Init, - dim1827Kuo2Init, - dim1828Kuo2Init, - dim1829Kuo2Init, - dim1830Kuo2Init, - dim1831Kuo2Init, - dim1832Kuo2Init, - dim1833Kuo2Init, - dim1834Kuo2Init, - dim1835Kuo2Init, - dim1836Kuo2Init, - dim1837Kuo2Init, - dim1838Kuo2Init, - dim1839Kuo2Init, - dim1840Kuo2Init, - dim1841Kuo2Init, - dim1842Kuo2Init, - dim1843Kuo2Init, - dim1844Kuo2Init, - dim1845Kuo2Init, - dim1846Kuo2Init, - dim1847Kuo2Init, - dim1848Kuo2Init, - dim1849Kuo2Init, - dim1850Kuo2Init, - dim1851Kuo2Init, - dim1852Kuo2Init, - dim1853Kuo2Init, - dim1854Kuo2Init, - dim1855Kuo2Init, - dim1856Kuo2Init, - dim1857Kuo2Init, - dim1858Kuo2Init, - dim1859Kuo2Init, - dim1860Kuo2Init, - dim1861Kuo2Init, - dim1862Kuo2Init, - dim1863Kuo2Init, - dim1864Kuo2Init, - dim1865Kuo2Init, - dim1866Kuo2Init, - dim1867Kuo2Init, - dim1868Kuo2Init, - dim1869Kuo2Init, - dim1870Kuo2Init, - dim1871Kuo2Init, - dim1872Kuo2Init, - dim1873Kuo2Init, - dim1874Kuo2Init, - dim1875Kuo2Init, - dim1876Kuo2Init, - dim1877Kuo2Init, - dim1878Kuo2Init, - dim1879Kuo2Init, - dim1880Kuo2Init, - dim1881Kuo2Init, - dim1882Kuo2Init, - dim1883Kuo2Init, - dim1884Kuo2Init, - dim1885Kuo2Init, - dim1886Kuo2Init, - dim1887Kuo2Init, - dim1888Kuo2Init, - dim1889Kuo2Init, - dim1890Kuo2Init, - dim1891Kuo2Init, - dim1892Kuo2Init, - dim1893Kuo2Init, - dim1894Kuo2Init, - dim1895Kuo2Init, - dim1896Kuo2Init, - dim1897Kuo2Init, - dim1898Kuo2Init, - dim1899Kuo2Init, - dim1900Kuo2Init, - dim1901Kuo2Init, - dim1902Kuo2Init, - dim1903Kuo2Init, - dim1904Kuo2Init, - dim1905Kuo2Init, - dim1906Kuo2Init, - dim1907Kuo2Init, - dim1908Kuo2Init, - dim1909Kuo2Init, - dim1910Kuo2Init, - dim1911Kuo2Init, - dim1912Kuo2Init, - dim1913Kuo2Init, - dim1914Kuo2Init, - dim1915Kuo2Init, - dim1916Kuo2Init, - dim1917Kuo2Init, - dim1918Kuo2Init, - dim1919Kuo2Init, - dim1920Kuo2Init, - dim1921Kuo2Init, - dim1922Kuo2Init, - dim1923Kuo2Init, - dim1924Kuo2Init, - dim1925Kuo2Init, - dim1926Kuo2Init, - dim1927Kuo2Init, - dim1928Kuo2Init, - dim1929Kuo2Init, - dim1930Kuo2Init, - dim1931Kuo2Init, - dim1932Kuo2Init, - dim1933Kuo2Init, - dim1934Kuo2Init, - dim1935Kuo2Init, - dim1936Kuo2Init, - dim1937Kuo2Init, - dim1938Kuo2Init, - dim1939Kuo2Init, - dim1940Kuo2Init, - dim1941Kuo2Init, - dim1942Kuo2Init, - dim1943Kuo2Init, - dim1944Kuo2Init, - dim1945Kuo2Init, - dim1946Kuo2Init, - dim1947Kuo2Init, - dim1948Kuo2Init, - dim1949Kuo2Init, - dim1950Kuo2Init, - dim1951Kuo2Init, - dim1952Kuo2Init, - dim1953Kuo2Init, - dim1954Kuo2Init, - dim1955Kuo2Init, - dim1956Kuo2Init, - dim1957Kuo2Init, - dim1958Kuo2Init, - dim1959Kuo2Init, - dim1960Kuo2Init, - dim1961Kuo2Init, - dim1962Kuo2Init, - dim1963Kuo2Init, - dim1964Kuo2Init, - dim1965Kuo2Init, - dim1966Kuo2Init, - dim1967Kuo2Init, - dim1968Kuo2Init, - dim1969Kuo2Init, - dim1970Kuo2Init, - dim1971Kuo2Init, - dim1972Kuo2Init, - dim1973Kuo2Init, - dim1974Kuo2Init, - dim1975Kuo2Init, - dim1976Kuo2Init, - dim1977Kuo2Init, - dim1978Kuo2Init, - dim1979Kuo2Init, - dim1980Kuo2Init, - dim1981Kuo2Init, - dim1982Kuo2Init, - dim1983Kuo2Init, - dim1984Kuo2Init, - dim1985Kuo2Init, - dim1986Kuo2Init, - dim1987Kuo2Init, - dim1988Kuo2Init, - dim1989Kuo2Init, - dim1990Kuo2Init, - dim1991Kuo2Init, - dim1992Kuo2Init, - dim1993Kuo2Init, - dim1994Kuo2Init, - dim1995Kuo2Init, - dim1996Kuo2Init, - dim1997Kuo2Init, - dim1998Kuo2Init, - dim1999Kuo2Init, - dim2000Kuo2Init, - dim2001Kuo2Init, - dim2002Kuo2Init, - dim2003Kuo2Init, - dim2004Kuo2Init, - dim2005Kuo2Init, - dim2006Kuo2Init, - dim2007Kuo2Init, - dim2008Kuo2Init, - dim2009Kuo2Init, - dim2010Kuo2Init, - dim2011Kuo2Init, - dim2012Kuo2Init, - dim2013Kuo2Init, - dim2014Kuo2Init, - dim2015Kuo2Init, - dim2016Kuo2Init, - dim2017Kuo2Init, - dim2018Kuo2Init, - dim2019Kuo2Init, - dim2020Kuo2Init, - dim2021Kuo2Init, - dim2022Kuo2Init, - dim2023Kuo2Init, - dim2024Kuo2Init, - dim2025Kuo2Init, - dim2026Kuo2Init, - dim2027Kuo2Init, - dim2028Kuo2Init, - dim2029Kuo2Init, - dim2030Kuo2Init, - dim2031Kuo2Init, - dim2032Kuo2Init, - dim2033Kuo2Init, - dim2034Kuo2Init, - dim2035Kuo2Init, - dim2036Kuo2Init, - dim2037Kuo2Init, - dim2038Kuo2Init, - dim2039Kuo2Init, - dim2040Kuo2Init, - dim2041Kuo2Init, - dim2042Kuo2Init, - dim2043Kuo2Init, - dim2044Kuo2Init, - dim2045Kuo2Init, - dim2046Kuo2Init, - dim2047Kuo2Init, - dim2048Kuo2Init, - dim2049Kuo2Init, - dim2050Kuo2Init, - dim2051Kuo2Init, - dim2052Kuo2Init, - dim2053Kuo2Init, - dim2054Kuo2Init, - dim2055Kuo2Init, - dim2056Kuo2Init, - dim2057Kuo2Init, - dim2058Kuo2Init, - dim2059Kuo2Init, - dim2060Kuo2Init, - dim2061Kuo2Init, - dim2062Kuo2Init, - dim2063Kuo2Init, - dim2064Kuo2Init, - dim2065Kuo2Init, - dim2066Kuo2Init, - dim2067Kuo2Init, - dim2068Kuo2Init, - dim2069Kuo2Init, - dim2070Kuo2Init, - dim2071Kuo2Init, - dim2072Kuo2Init, - dim2073Kuo2Init, - dim2074Kuo2Init, - dim2075Kuo2Init, - dim2076Kuo2Init, - dim2077Kuo2Init, - dim2078Kuo2Init, - dim2079Kuo2Init, - dim2080Kuo2Init, - dim2081Kuo2Init, - dim2082Kuo2Init, - dim2083Kuo2Init, - dim2084Kuo2Init, - dim2085Kuo2Init, - dim2086Kuo2Init, - dim2087Kuo2Init, - dim2088Kuo2Init, - dim2089Kuo2Init, - dim2090Kuo2Init, - dim2091Kuo2Init, - dim2092Kuo2Init, - dim2093Kuo2Init, - dim2094Kuo2Init, - dim2095Kuo2Init, - dim2096Kuo2Init, - dim2097Kuo2Init, - dim2098Kuo2Init, - dim2099Kuo2Init, - dim2100Kuo2Init, - dim2101Kuo2Init, - dim2102Kuo2Init, - dim2103Kuo2Init, - dim2104Kuo2Init, - dim2105Kuo2Init, - dim2106Kuo2Init, - dim2107Kuo2Init, - dim2108Kuo2Init, - dim2109Kuo2Init, - dim2110Kuo2Init, - dim2111Kuo2Init, - dim2112Kuo2Init, - dim2113Kuo2Init, - dim2114Kuo2Init, - dim2115Kuo2Init, - dim2116Kuo2Init, - dim2117Kuo2Init, - dim2118Kuo2Init, - dim2119Kuo2Init, - dim2120Kuo2Init, - dim2121Kuo2Init, - dim2122Kuo2Init, - dim2123Kuo2Init, - dim2124Kuo2Init, - dim2125Kuo2Init, - dim2126Kuo2Init, - dim2127Kuo2Init, - dim2128Kuo2Init, - dim2129Kuo2Init, - dim2130Kuo2Init, - dim2131Kuo2Init, - dim2132Kuo2Init, - dim2133Kuo2Init, - dim2134Kuo2Init, - dim2135Kuo2Init, - dim2136Kuo2Init, - dim2137Kuo2Init, - dim2138Kuo2Init, - dim2139Kuo2Init, - dim2140Kuo2Init, - dim2141Kuo2Init, - dim2142Kuo2Init, - dim2143Kuo2Init, - dim2144Kuo2Init, - dim2145Kuo2Init, - dim2146Kuo2Init, - dim2147Kuo2Init, - dim2148Kuo2Init, - dim2149Kuo2Init, - dim2150Kuo2Init, - dim2151Kuo2Init, - dim2152Kuo2Init, - dim2153Kuo2Init, - dim2154Kuo2Init, - dim2155Kuo2Init, - dim2156Kuo2Init, - dim2157Kuo2Init, - dim2158Kuo2Init, - dim2159Kuo2Init, - dim2160Kuo2Init, - dim2161Kuo2Init, - dim2162Kuo2Init, - dim2163Kuo2Init, - dim2164Kuo2Init, - dim2165Kuo2Init, - dim2166Kuo2Init, - dim2167Kuo2Init, - dim2168Kuo2Init, - dim2169Kuo2Init, - dim2170Kuo2Init, - dim2171Kuo2Init, - dim2172Kuo2Init, - dim2173Kuo2Init, - dim2174Kuo2Init, - dim2175Kuo2Init, - dim2176Kuo2Init, - dim2177Kuo2Init, - dim2178Kuo2Init, - dim2179Kuo2Init, - dim2180Kuo2Init, - dim2181Kuo2Init, - dim2182Kuo2Init, - dim2183Kuo2Init, - dim2184Kuo2Init, - dim2185Kuo2Init, - dim2186Kuo2Init, - dim2187Kuo2Init, - dim2188Kuo2Init, - dim2189Kuo2Init, - dim2190Kuo2Init, - dim2191Kuo2Init, - dim2192Kuo2Init, - dim2193Kuo2Init, - dim2194Kuo2Init, - dim2195Kuo2Init, - dim2196Kuo2Init, - dim2197Kuo2Init, - dim2198Kuo2Init, - dim2199Kuo2Init, - dim2200Kuo2Init, - dim2201Kuo2Init, - dim2202Kuo2Init, - dim2203Kuo2Init, - dim2204Kuo2Init, - dim2205Kuo2Init, - dim2206Kuo2Init, - dim2207Kuo2Init, - dim2208Kuo2Init, - dim2209Kuo2Init, - dim2210Kuo2Init, - dim2211Kuo2Init, - dim2212Kuo2Init, - dim2213Kuo2Init, - dim2214Kuo2Init, - dim2215Kuo2Init, - dim2216Kuo2Init, - dim2217Kuo2Init, - dim2218Kuo2Init, - dim2219Kuo2Init, - dim2220Kuo2Init, - dim2221Kuo2Init, - dim2222Kuo2Init, - dim2223Kuo2Init, - dim2224Kuo2Init, - dim2225Kuo2Init, - dim2226Kuo2Init, - dim2227Kuo2Init, - dim2228Kuo2Init, - dim2229Kuo2Init, - dim2230Kuo2Init, - dim2231Kuo2Init, - dim2232Kuo2Init, - dim2233Kuo2Init, - dim2234Kuo2Init, - dim2235Kuo2Init, - dim2236Kuo2Init, - dim2237Kuo2Init, - dim2238Kuo2Init, - dim2239Kuo2Init, - dim2240Kuo2Init, - dim2241Kuo2Init, - dim2242Kuo2Init, - dim2243Kuo2Init, - dim2244Kuo2Init, - dim2245Kuo2Init, - dim2246Kuo2Init, - dim2247Kuo2Init, - dim2248Kuo2Init, - dim2249Kuo2Init, - dim2250Kuo2Init, - dim2251Kuo2Init, - dim2252Kuo2Init, - dim2253Kuo2Init, - dim2254Kuo2Init, - dim2255Kuo2Init, - dim2256Kuo2Init, - dim2257Kuo2Init, - dim2258Kuo2Init, - dim2259Kuo2Init, - dim2260Kuo2Init, - dim2261Kuo2Init, - dim2262Kuo2Init, - dim2263Kuo2Init, - dim2264Kuo2Init, - dim2265Kuo2Init, - dim2266Kuo2Init, - dim2267Kuo2Init, - dim2268Kuo2Init, - dim2269Kuo2Init, - dim2270Kuo2Init, - dim2271Kuo2Init, - dim2272Kuo2Init, - dim2273Kuo2Init, - dim2274Kuo2Init, - dim2275Kuo2Init, - dim2276Kuo2Init, - dim2277Kuo2Init, - dim2278Kuo2Init, - dim2279Kuo2Init, - dim2280Kuo2Init, - dim2281Kuo2Init, - dim2282Kuo2Init, - dim2283Kuo2Init, - dim2284Kuo2Init, - dim2285Kuo2Init, - dim2286Kuo2Init, - dim2287Kuo2Init, - dim2288Kuo2Init, - dim2289Kuo2Init, - dim2290Kuo2Init, - dim2291Kuo2Init, - dim2292Kuo2Init, - dim2293Kuo2Init, - dim2294Kuo2Init, - dim2295Kuo2Init, - dim2296Kuo2Init, - dim2297Kuo2Init, - dim2298Kuo2Init, - dim2299Kuo2Init, - dim2300Kuo2Init, - dim2301Kuo2Init, - dim2302Kuo2Init, - dim2303Kuo2Init, - dim2304Kuo2Init, - dim2305Kuo2Init, - dim2306Kuo2Init, - dim2307Kuo2Init, - dim2308Kuo2Init, - dim2309Kuo2Init, - dim2310Kuo2Init, - dim2311Kuo2Init, - dim2312Kuo2Init, - dim2313Kuo2Init, - dim2314Kuo2Init, - dim2315Kuo2Init, - dim2316Kuo2Init, - dim2317Kuo2Init, - dim2318Kuo2Init, - dim2319Kuo2Init, - dim2320Kuo2Init, - dim2321Kuo2Init, - dim2322Kuo2Init, - dim2323Kuo2Init, - dim2324Kuo2Init, - dim2325Kuo2Init, - dim2326Kuo2Init, - dim2327Kuo2Init, - dim2328Kuo2Init, - dim2329Kuo2Init, - dim2330Kuo2Init, - dim2331Kuo2Init, - dim2332Kuo2Init, - dim2333Kuo2Init, - dim2334Kuo2Init, - dim2335Kuo2Init, - dim2336Kuo2Init, - dim2337Kuo2Init, - dim2338Kuo2Init, - dim2339Kuo2Init, - dim2340Kuo2Init, - dim2341Kuo2Init, - dim2342Kuo2Init, - dim2343Kuo2Init, - dim2344Kuo2Init, - dim2345Kuo2Init, - dim2346Kuo2Init, - dim2347Kuo2Init, - dim2348Kuo2Init, - dim2349Kuo2Init, - dim2350Kuo2Init, - dim2351Kuo2Init, - dim2352Kuo2Init, - dim2353Kuo2Init, - dim2354Kuo2Init, - dim2355Kuo2Init, - dim2356Kuo2Init, - dim2357Kuo2Init, - dim2358Kuo2Init, - dim2359Kuo2Init, - dim2360Kuo2Init, - dim2361Kuo2Init, - dim2362Kuo2Init, - dim2363Kuo2Init, - dim2364Kuo2Init, - dim2365Kuo2Init, - dim2366Kuo2Init, - dim2367Kuo2Init, - dim2368Kuo2Init, - dim2369Kuo2Init, - dim2370Kuo2Init, - dim2371Kuo2Init, - dim2372Kuo2Init, - dim2373Kuo2Init, - dim2374Kuo2Init, - dim2375Kuo2Init, - dim2376Kuo2Init, - dim2377Kuo2Init, - dim2378Kuo2Init, - dim2379Kuo2Init, - dim2380Kuo2Init, - dim2381Kuo2Init, - dim2382Kuo2Init, - dim2383Kuo2Init, - dim2384Kuo2Init, - dim2385Kuo2Init, - dim2386Kuo2Init, - dim2387Kuo2Init, - dim2388Kuo2Init, - dim2389Kuo2Init, - dim2390Kuo2Init, - dim2391Kuo2Init, - dim2392Kuo2Init, - dim2393Kuo2Init, - dim2394Kuo2Init, - dim2395Kuo2Init, - dim2396Kuo2Init, - dim2397Kuo2Init, - dim2398Kuo2Init, - dim2399Kuo2Init, - dim2400Kuo2Init, - dim2401Kuo2Init, - dim2402Kuo2Init, - dim2403Kuo2Init, - dim2404Kuo2Init, - dim2405Kuo2Init, - dim2406Kuo2Init, - dim2407Kuo2Init, - dim2408Kuo2Init, - dim2409Kuo2Init, - dim2410Kuo2Init, - dim2411Kuo2Init, - dim2412Kuo2Init, - dim2413Kuo2Init, - dim2414Kuo2Init, - dim2415Kuo2Init, - dim2416Kuo2Init, - dim2417Kuo2Init, - dim2418Kuo2Init, - dim2419Kuo2Init, - dim2420Kuo2Init, - dim2421Kuo2Init, - dim2422Kuo2Init, - dim2423Kuo2Init, - dim2424Kuo2Init, - dim2425Kuo2Init, - dim2426Kuo2Init, - dim2427Kuo2Init, - dim2428Kuo2Init, - dim2429Kuo2Init, - dim2430Kuo2Init, - dim2431Kuo2Init, - dim2432Kuo2Init, - dim2433Kuo2Init, - dim2434Kuo2Init, - dim2435Kuo2Init, - dim2436Kuo2Init, - dim2437Kuo2Init, - dim2438Kuo2Init, - dim2439Kuo2Init, - dim2440Kuo2Init, - dim2441Kuo2Init, - dim2442Kuo2Init, - dim2443Kuo2Init, - dim2444Kuo2Init, - dim2445Kuo2Init, - dim2446Kuo2Init, - dim2447Kuo2Init, - dim2448Kuo2Init, - dim2449Kuo2Init, - dim2450Kuo2Init, - dim2451Kuo2Init, - dim2452Kuo2Init, - dim2453Kuo2Init, - dim2454Kuo2Init, - dim2455Kuo2Init, - dim2456Kuo2Init, - dim2457Kuo2Init, - dim2458Kuo2Init, - dim2459Kuo2Init, - dim2460Kuo2Init, - dim2461Kuo2Init, - dim2462Kuo2Init, - dim2463Kuo2Init, - dim2464Kuo2Init, - dim2465Kuo2Init, - dim2466Kuo2Init, - dim2467Kuo2Init, - dim2468Kuo2Init, - dim2469Kuo2Init, - dim2470Kuo2Init, - dim2471Kuo2Init, - dim2472Kuo2Init, - dim2473Kuo2Init, - dim2474Kuo2Init, - dim2475Kuo2Init, - dim2476Kuo2Init, - dim2477Kuo2Init, - dim2478Kuo2Init, - dim2479Kuo2Init, - dim2480Kuo2Init, - dim2481Kuo2Init, - dim2482Kuo2Init, - dim2483Kuo2Init, - dim2484Kuo2Init, - dim2485Kuo2Init, - dim2486Kuo2Init, - dim2487Kuo2Init, - dim2488Kuo2Init, - dim2489Kuo2Init, - dim2490Kuo2Init, - dim2491Kuo2Init, - dim2492Kuo2Init, - dim2493Kuo2Init, - dim2494Kuo2Init, - dim2495Kuo2Init, - dim2496Kuo2Init, - dim2497Kuo2Init, - dim2498Kuo2Init, - dim2499Kuo2Init, - dim2500Kuo2Init, - dim2501Kuo2Init, - dim2502Kuo2Init, - dim2503Kuo2Init, - dim2504Kuo2Init, - dim2505Kuo2Init, - dim2506Kuo2Init, - dim2507Kuo2Init, - dim2508Kuo2Init, - dim2509Kuo2Init, - dim2510Kuo2Init, - dim2511Kuo2Init, - dim2512Kuo2Init, - dim2513Kuo2Init, - dim2514Kuo2Init, - dim2515Kuo2Init, - dim2516Kuo2Init, - dim2517Kuo2Init, - dim2518Kuo2Init, - dim2519Kuo2Init, - dim2520Kuo2Init, - dim2521Kuo2Init, - dim2522Kuo2Init, - dim2523Kuo2Init, - dim2524Kuo2Init, - dim2525Kuo2Init, - dim2526Kuo2Init, - dim2527Kuo2Init, - dim2528Kuo2Init, - dim2529Kuo2Init, - dim2530Kuo2Init, - dim2531Kuo2Init, - dim2532Kuo2Init, - dim2533Kuo2Init, - dim2534Kuo2Init, - dim2535Kuo2Init, - dim2536Kuo2Init, - dim2537Kuo2Init, - dim2538Kuo2Init, - dim2539Kuo2Init, - dim2540Kuo2Init, - dim2541Kuo2Init, - dim2542Kuo2Init, - dim2543Kuo2Init, - dim2544Kuo2Init, - dim2545Kuo2Init, - dim2546Kuo2Init, - dim2547Kuo2Init, - dim2548Kuo2Init, - dim2549Kuo2Init, - dim2550Kuo2Init, - dim2551Kuo2Init, - dim2552Kuo2Init, - dim2553Kuo2Init, - dim2554Kuo2Init, - dim2555Kuo2Init, - dim2556Kuo2Init, - dim2557Kuo2Init, - dim2558Kuo2Init, - dim2559Kuo2Init, - dim2560Kuo2Init, - dim2561Kuo2Init, - dim2562Kuo2Init, - dim2563Kuo2Init, - dim2564Kuo2Init, - dim2565Kuo2Init, - dim2566Kuo2Init, - dim2567Kuo2Init, - dim2568Kuo2Init, - dim2569Kuo2Init, - dim2570Kuo2Init, - dim2571Kuo2Init, - dim2572Kuo2Init, - dim2573Kuo2Init, - dim2574Kuo2Init, - dim2575Kuo2Init, - dim2576Kuo2Init, - dim2577Kuo2Init, - dim2578Kuo2Init, - dim2579Kuo2Init, - dim2580Kuo2Init, - dim2581Kuo2Init, - dim2582Kuo2Init, - dim2583Kuo2Init, - dim2584Kuo2Init, - dim2585Kuo2Init, - dim2586Kuo2Init, - dim2587Kuo2Init, - dim2588Kuo2Init, - dim2589Kuo2Init, - dim2590Kuo2Init, - dim2591Kuo2Init, - dim2592Kuo2Init, - dim2593Kuo2Init, - dim2594Kuo2Init, - dim2595Kuo2Init, - dim2596Kuo2Init, - dim2597Kuo2Init, - dim2598Kuo2Init, - dim2599Kuo2Init, - dim2600Kuo2Init, - dim2601Kuo2Init, - dim2602Kuo2Init, - dim2603Kuo2Init, - dim2604Kuo2Init, - dim2605Kuo2Init, - dim2606Kuo2Init, - dim2607Kuo2Init, - dim2608Kuo2Init, - dim2609Kuo2Init, - dim2610Kuo2Init, - dim2611Kuo2Init, - dim2612Kuo2Init, - dim2613Kuo2Init, - dim2614Kuo2Init, - dim2615Kuo2Init, - dim2616Kuo2Init, - dim2617Kuo2Init, - dim2618Kuo2Init, - dim2619Kuo2Init, - dim2620Kuo2Init, - dim2621Kuo2Init, - dim2622Kuo2Init, - dim2623Kuo2Init, - dim2624Kuo2Init, - dim2625Kuo2Init, - dim2626Kuo2Init, - dim2627Kuo2Init, - dim2628Kuo2Init, - dim2629Kuo2Init, - dim2630Kuo2Init, - dim2631Kuo2Init, - dim2632Kuo2Init, - dim2633Kuo2Init, - dim2634Kuo2Init, - dim2635Kuo2Init, - dim2636Kuo2Init, - dim2637Kuo2Init, - dim2638Kuo2Init, - dim2639Kuo2Init, - dim2640Kuo2Init, - dim2641Kuo2Init, - dim2642Kuo2Init, - dim2643Kuo2Init, - dim2644Kuo2Init, - dim2645Kuo2Init, - dim2646Kuo2Init, - dim2647Kuo2Init, - dim2648Kuo2Init, - dim2649Kuo2Init, - dim2650Kuo2Init, - dim2651Kuo2Init, - dim2652Kuo2Init, - dim2653Kuo2Init, - dim2654Kuo2Init, - dim2655Kuo2Init, - dim2656Kuo2Init, - dim2657Kuo2Init, - dim2658Kuo2Init, - dim2659Kuo2Init, - dim2660Kuo2Init, - dim2661Kuo2Init, - dim2662Kuo2Init, - dim2663Kuo2Init, - dim2664Kuo2Init, - dim2665Kuo2Init, - dim2666Kuo2Init, - dim2667Kuo2Init, - dim2668Kuo2Init, - dim2669Kuo2Init, - dim2670Kuo2Init, - dim2671Kuo2Init, - dim2672Kuo2Init, - dim2673Kuo2Init, - dim2674Kuo2Init, - dim2675Kuo2Init, - dim2676Kuo2Init, - dim2677Kuo2Init, - dim2678Kuo2Init, - dim2679Kuo2Init, - dim2680Kuo2Init, - dim2681Kuo2Init, - dim2682Kuo2Init, - dim2683Kuo2Init, - dim2684Kuo2Init, - dim2685Kuo2Init, - dim2686Kuo2Init, - dim2687Kuo2Init, - dim2688Kuo2Init, - dim2689Kuo2Init, - dim2690Kuo2Init, - dim2691Kuo2Init, - dim2692Kuo2Init, - dim2693Kuo2Init, - dim2694Kuo2Init, - dim2695Kuo2Init, - dim2696Kuo2Init, - dim2697Kuo2Init, - dim2698Kuo2Init, - dim2699Kuo2Init, - dim2700Kuo2Init, - dim2701Kuo2Init, - dim2702Kuo2Init, - dim2703Kuo2Init, - dim2704Kuo2Init, - dim2705Kuo2Init, - dim2706Kuo2Init, - dim2707Kuo2Init, - dim2708Kuo2Init, - dim2709Kuo2Init, - dim2710Kuo2Init, - dim2711Kuo2Init, - dim2712Kuo2Init, - dim2713Kuo2Init, - dim2714Kuo2Init, - dim2715Kuo2Init, - dim2716Kuo2Init, - dim2717Kuo2Init, - dim2718Kuo2Init, - dim2719Kuo2Init, - dim2720Kuo2Init, - dim2721Kuo2Init, - dim2722Kuo2Init, - dim2723Kuo2Init, - dim2724Kuo2Init, - dim2725Kuo2Init, - dim2726Kuo2Init, - dim2727Kuo2Init, - dim2728Kuo2Init, - dim2729Kuo2Init, - dim2730Kuo2Init, - dim2731Kuo2Init, - dim2732Kuo2Init, - dim2733Kuo2Init, - dim2734Kuo2Init, - dim2735Kuo2Init, - dim2736Kuo2Init, - dim2737Kuo2Init, - dim2738Kuo2Init, - dim2739Kuo2Init, - dim2740Kuo2Init, - dim2741Kuo2Init, - dim2742Kuo2Init, - dim2743Kuo2Init, - dim2744Kuo2Init, - dim2745Kuo2Init, - dim2746Kuo2Init, - dim2747Kuo2Init, - dim2748Kuo2Init, - dim2749Kuo2Init, - dim2750Kuo2Init, - dim2751Kuo2Init, - dim2752Kuo2Init, - dim2753Kuo2Init, - dim2754Kuo2Init, - dim2755Kuo2Init, - dim2756Kuo2Init, - dim2757Kuo2Init, - dim2758Kuo2Init, - dim2759Kuo2Init, - dim2760Kuo2Init, - dim2761Kuo2Init, - dim2762Kuo2Init, - dim2763Kuo2Init, - dim2764Kuo2Init, - dim2765Kuo2Init, - dim2766Kuo2Init, - dim2767Kuo2Init, - dim2768Kuo2Init, - dim2769Kuo2Init, - dim2770Kuo2Init, - dim2771Kuo2Init, - dim2772Kuo2Init, - dim2773Kuo2Init, - dim2774Kuo2Init, - dim2775Kuo2Init, - dim2776Kuo2Init, - dim2777Kuo2Init, - dim2778Kuo2Init, - dim2779Kuo2Init, - dim2780Kuo2Init, - dim2781Kuo2Init, - dim2782Kuo2Init, - dim2783Kuo2Init, - dim2784Kuo2Init, - dim2785Kuo2Init, - dim2786Kuo2Init, - dim2787Kuo2Init, - dim2788Kuo2Init, - dim2789Kuo2Init, - dim2790Kuo2Init, - dim2791Kuo2Init, - dim2792Kuo2Init, - dim2793Kuo2Init, - dim2794Kuo2Init, - dim2795Kuo2Init, - dim2796Kuo2Init, - dim2797Kuo2Init, - dim2798Kuo2Init, - dim2799Kuo2Init, - dim2800Kuo2Init, - dim2801Kuo2Init, - dim2802Kuo2Init, - dim2803Kuo2Init, - dim2804Kuo2Init, - dim2805Kuo2Init, - dim2806Kuo2Init, - dim2807Kuo2Init, - dim2808Kuo2Init, - dim2809Kuo2Init, - dim2810Kuo2Init, - dim2811Kuo2Init, - dim2812Kuo2Init, - dim2813Kuo2Init, - dim2814Kuo2Init, - dim2815Kuo2Init, - dim2816Kuo2Init, - dim2817Kuo2Init, - dim2818Kuo2Init, - dim2819Kuo2Init, - dim2820Kuo2Init, - dim2821Kuo2Init, - dim2822Kuo2Init, - dim2823Kuo2Init, - dim2824Kuo2Init, - dim2825Kuo2Init, - dim2826Kuo2Init, - dim2827Kuo2Init, - dim2828Kuo2Init, - dim2829Kuo2Init, - dim2830Kuo2Init, - dim2831Kuo2Init, - dim2832Kuo2Init, - dim2833Kuo2Init, - dim2834Kuo2Init, - dim2835Kuo2Init, - dim2836Kuo2Init, - dim2837Kuo2Init, - dim2838Kuo2Init, - dim2839Kuo2Init, - dim2840Kuo2Init, - dim2841Kuo2Init, - dim2842Kuo2Init, - dim2843Kuo2Init, - dim2844Kuo2Init, - dim2845Kuo2Init, - dim2846Kuo2Init, - dim2847Kuo2Init, - dim2848Kuo2Init, - dim2849Kuo2Init, - dim2850Kuo2Init, - dim2851Kuo2Init, - dim2852Kuo2Init, - dim2853Kuo2Init, - dim2854Kuo2Init, - dim2855Kuo2Init, - dim2856Kuo2Init, - dim2857Kuo2Init, - dim2858Kuo2Init, - dim2859Kuo2Init, - dim2860Kuo2Init, - dim2861Kuo2Init, - dim2862Kuo2Init, - dim2863Kuo2Init, - dim2864Kuo2Init, - dim2865Kuo2Init, - dim2866Kuo2Init, - dim2867Kuo2Init, - dim2868Kuo2Init, - dim2869Kuo2Init, - dim2870Kuo2Init, - dim2871Kuo2Init, - dim2872Kuo2Init, - dim2873Kuo2Init, - dim2874Kuo2Init, - dim2875Kuo2Init, - dim2876Kuo2Init, - dim2877Kuo2Init, - dim2878Kuo2Init, - dim2879Kuo2Init, - dim2880Kuo2Init, - dim2881Kuo2Init, - dim2882Kuo2Init, - dim2883Kuo2Init, - dim2884Kuo2Init, - dim2885Kuo2Init, - dim2886Kuo2Init, - dim2887Kuo2Init, - dim2888Kuo2Init, - dim2889Kuo2Init, - dim2890Kuo2Init, - dim2891Kuo2Init, - dim2892Kuo2Init, - dim2893Kuo2Init, - dim2894Kuo2Init, - dim2895Kuo2Init, - dim2896Kuo2Init, - dim2897Kuo2Init, - dim2898Kuo2Init, - dim2899Kuo2Init, - dim2900Kuo2Init, - dim2901Kuo2Init, - dim2902Kuo2Init, - dim2903Kuo2Init, - dim2904Kuo2Init, - dim2905Kuo2Init, - dim2906Kuo2Init, - dim2907Kuo2Init, - dim2908Kuo2Init, - dim2909Kuo2Init, - dim2910Kuo2Init, - dim2911Kuo2Init, - dim2912Kuo2Init, - dim2913Kuo2Init, - dim2914Kuo2Init, - dim2915Kuo2Init, - dim2916Kuo2Init, - dim2917Kuo2Init, - dim2918Kuo2Init, - dim2919Kuo2Init, - dim2920Kuo2Init, - dim2921Kuo2Init, - dim2922Kuo2Init, - dim2923Kuo2Init, - dim2924Kuo2Init, - dim2925Kuo2Init, - dim2926Kuo2Init, - dim2927Kuo2Init, - dim2928Kuo2Init, - dim2929Kuo2Init, - dim2930Kuo2Init, - dim2931Kuo2Init, - dim2932Kuo2Init, - dim2933Kuo2Init, - dim2934Kuo2Init, - dim2935Kuo2Init, - dim2936Kuo2Init, - dim2937Kuo2Init, - dim2938Kuo2Init, - dim2939Kuo2Init, - dim2940Kuo2Init, - dim2941Kuo2Init, - dim2942Kuo2Init, - dim2943Kuo2Init, - dim2944Kuo2Init, - dim2945Kuo2Init, - dim2946Kuo2Init, - dim2947Kuo2Init, - dim2948Kuo2Init, - dim2949Kuo2Init, - dim2950Kuo2Init, - dim2951Kuo2Init, - dim2952Kuo2Init, - dim2953Kuo2Init, - dim2954Kuo2Init, - dim2955Kuo2Init, - dim2956Kuo2Init, - dim2957Kuo2Init, - dim2958Kuo2Init, - dim2959Kuo2Init, - dim2960Kuo2Init, - dim2961Kuo2Init, - dim2962Kuo2Init, - dim2963Kuo2Init, - dim2964Kuo2Init, - dim2965Kuo2Init, - dim2966Kuo2Init, - dim2967Kuo2Init, - dim2968Kuo2Init, - dim2969Kuo2Init, - dim2970Kuo2Init, - dim2971Kuo2Init, - dim2972Kuo2Init, - dim2973Kuo2Init, - dim2974Kuo2Init, - dim2975Kuo2Init, - dim2976Kuo2Init, - dim2977Kuo2Init, - dim2978Kuo2Init, - dim2979Kuo2Init, - dim2980Kuo2Init, - dim2981Kuo2Init, - dim2982Kuo2Init, - dim2983Kuo2Init, - dim2984Kuo2Init, - dim2985Kuo2Init, - dim2986Kuo2Init, - dim2987Kuo2Init, - dim2988Kuo2Init, - dim2989Kuo2Init, - dim2990Kuo2Init, - dim2991Kuo2Init, - dim2992Kuo2Init, - dim2993Kuo2Init, - dim2994Kuo2Init, - dim2995Kuo2Init, - dim2996Kuo2Init, - dim2997Kuo2Init, - dim2998Kuo2Init, - dim2999Kuo2Init, - dim3000Kuo2Init, - dim3001Kuo2Init, - dim3002Kuo2Init, - dim3003Kuo2Init, - dim3004Kuo2Init, - dim3005Kuo2Init, - dim3006Kuo2Init, - dim3007Kuo2Init, - dim3008Kuo2Init, - dim3009Kuo2Init, - dim3010Kuo2Init, - dim3011Kuo2Init, - dim3012Kuo2Init, - dim3013Kuo2Init, - dim3014Kuo2Init, - dim3015Kuo2Init, - dim3016Kuo2Init, - dim3017Kuo2Init, - dim3018Kuo2Init, - dim3019Kuo2Init, - dim3020Kuo2Init, - dim3021Kuo2Init, - dim3022Kuo2Init, - dim3023Kuo2Init, - dim3024Kuo2Init, - dim3025Kuo2Init, - dim3026Kuo2Init, - dim3027Kuo2Init, - dim3028Kuo2Init, - dim3029Kuo2Init, - dim3030Kuo2Init, - dim3031Kuo2Init, - dim3032Kuo2Init, - dim3033Kuo2Init, - dim3034Kuo2Init, - dim3035Kuo2Init, - dim3036Kuo2Init, - dim3037Kuo2Init, - dim3038Kuo2Init, - dim3039Kuo2Init, - dim3040Kuo2Init, - dim3041Kuo2Init, - dim3042Kuo2Init, - dim3043Kuo2Init, - dim3044Kuo2Init, - dim3045Kuo2Init, - dim3046Kuo2Init, - dim3047Kuo2Init, - dim3048Kuo2Init, - dim3049Kuo2Init, - dim3050Kuo2Init, - dim3051Kuo2Init, - dim3052Kuo2Init, - dim3053Kuo2Init, - dim3054Kuo2Init, - dim3055Kuo2Init, - dim3056Kuo2Init, - dim3057Kuo2Init, - dim3058Kuo2Init, - dim3059Kuo2Init, - dim3060Kuo2Init, - dim3061Kuo2Init, - dim3062Kuo2Init, - dim3063Kuo2Init, - dim3064Kuo2Init, - dim3065Kuo2Init, - dim3066Kuo2Init, - dim3067Kuo2Init, - dim3068Kuo2Init, - dim3069Kuo2Init, - dim3070Kuo2Init, - dim3071Kuo2Init, - dim3072Kuo2Init, - dim3073Kuo2Init, - dim3074Kuo2Init, - dim3075Kuo2Init, - dim3076Kuo2Init, - dim3077Kuo2Init, - dim3078Kuo2Init, - dim3079Kuo2Init, - dim3080Kuo2Init, - dim3081Kuo2Init, - dim3082Kuo2Init, - dim3083Kuo2Init, - dim3084Kuo2Init, - dim3085Kuo2Init, - dim3086Kuo2Init, - dim3087Kuo2Init, - dim3088Kuo2Init, - dim3089Kuo2Init, - dim3090Kuo2Init, - dim3091Kuo2Init, - dim3092Kuo2Init, - dim3093Kuo2Init, - dim3094Kuo2Init, - dim3095Kuo2Init, - dim3096Kuo2Init, - dim3097Kuo2Init, - dim3098Kuo2Init, - dim3099Kuo2Init, - dim3100Kuo2Init, - dim3101Kuo2Init, - dim3102Kuo2Init, - dim3103Kuo2Init, - dim3104Kuo2Init, - dim3105Kuo2Init, - dim3106Kuo2Init, - dim3107Kuo2Init, - dim3108Kuo2Init, - dim3109Kuo2Init, - dim3110Kuo2Init, - dim3111Kuo2Init, - dim3112Kuo2Init, - dim3113Kuo2Init, - dim3114Kuo2Init, - dim3115Kuo2Init, - dim3116Kuo2Init, - dim3117Kuo2Init, - dim3118Kuo2Init, - dim3119Kuo2Init, - dim3120Kuo2Init, - dim3121Kuo2Init, - dim3122Kuo2Init, - dim3123Kuo2Init, - dim3124Kuo2Init, - dim3125Kuo2Init, - dim3126Kuo2Init, - dim3127Kuo2Init, - dim3128Kuo2Init, - dim3129Kuo2Init, - dim3130Kuo2Init, - dim3131Kuo2Init, - dim3132Kuo2Init, - dim3133Kuo2Init, - dim3134Kuo2Init, - dim3135Kuo2Init, - dim3136Kuo2Init, - dim3137Kuo2Init, - dim3138Kuo2Init, - dim3139Kuo2Init, - dim3140Kuo2Init, - dim3141Kuo2Init, - dim3142Kuo2Init, - dim3143Kuo2Init, - dim3144Kuo2Init, - dim3145Kuo2Init, - dim3146Kuo2Init, - dim3147Kuo2Init, - dim3148Kuo2Init, - dim3149Kuo2Init, - dim3150Kuo2Init, - dim3151Kuo2Init, - dim3152Kuo2Init, - dim3153Kuo2Init, - dim3154Kuo2Init, - dim3155Kuo2Init, - dim3156Kuo2Init, - dim3157Kuo2Init, - dim3158Kuo2Init, - dim3159Kuo2Init, - dim3160Kuo2Init, - dim3161Kuo2Init, - dim3162Kuo2Init, - dim3163Kuo2Init, - dim3164Kuo2Init, - dim3165Kuo2Init, - dim3166Kuo2Init, - dim3167Kuo2Init, - dim3168Kuo2Init, - dim3169Kuo2Init, - dim3170Kuo2Init, - dim3171Kuo2Init, - dim3172Kuo2Init, - dim3173Kuo2Init, - dim3174Kuo2Init, - dim3175Kuo2Init, - dim3176Kuo2Init, - dim3177Kuo2Init, - dim3178Kuo2Init, - dim3179Kuo2Init, - dim3180Kuo2Init, - dim3181Kuo2Init, - dim3182Kuo2Init, - dim3183Kuo2Init, - dim3184Kuo2Init, - dim3185Kuo2Init, - dim3186Kuo2Init, - dim3187Kuo2Init, - dim3188Kuo2Init, - dim3189Kuo2Init, - dim3190Kuo2Init, - dim3191Kuo2Init, - dim3192Kuo2Init, - dim3193Kuo2Init, - dim3194Kuo2Init, - dim3195Kuo2Init, - dim3196Kuo2Init, - dim3197Kuo2Init, - dim3198Kuo2Init, - dim3199Kuo2Init, - dim3200Kuo2Init, - dim3201Kuo2Init, - dim3202Kuo2Init, - dim3203Kuo2Init, - dim3204Kuo2Init, - dim3205Kuo2Init, - dim3206Kuo2Init, - dim3207Kuo2Init, - dim3208Kuo2Init, - dim3209Kuo2Init, - dim3210Kuo2Init, - dim3211Kuo2Init, - dim3212Kuo2Init, - dim3213Kuo2Init, - dim3214Kuo2Init, - dim3215Kuo2Init, - dim3216Kuo2Init, - dim3217Kuo2Init, - dim3218Kuo2Init, - dim3219Kuo2Init, - dim3220Kuo2Init, - dim3221Kuo2Init, - dim3222Kuo2Init, - dim3223Kuo2Init, - dim3224Kuo2Init, - dim3225Kuo2Init, - dim3226Kuo2Init, - dim3227Kuo2Init, - dim3228Kuo2Init, - dim3229Kuo2Init, - dim3230Kuo2Init, - dim3231Kuo2Init, - dim3232Kuo2Init, - dim3233Kuo2Init, - dim3234Kuo2Init, - dim3235Kuo2Init, - dim3236Kuo2Init, - dim3237Kuo2Init, - dim3238Kuo2Init, - dim3239Kuo2Init, - dim3240Kuo2Init, - dim3241Kuo2Init, - dim3242Kuo2Init, - dim3243Kuo2Init, - dim3244Kuo2Init, - dim3245Kuo2Init, - dim3246Kuo2Init, - dim3247Kuo2Init, - dim3248Kuo2Init, - dim3249Kuo2Init, - dim3250Kuo2Init, - dim3251Kuo2Init, - dim3252Kuo2Init, - dim3253Kuo2Init, - dim3254Kuo2Init, - dim3255Kuo2Init, - dim3256Kuo2Init, - dim3257Kuo2Init, - dim3258Kuo2Init, - dim3259Kuo2Init, - dim3260Kuo2Init, - dim3261Kuo2Init, - dim3262Kuo2Init, - dim3263Kuo2Init, - dim3264Kuo2Init, - dim3265Kuo2Init, - dim3266Kuo2Init, - dim3267Kuo2Init, - dim3268Kuo2Init, - dim3269Kuo2Init, - dim3270Kuo2Init, - dim3271Kuo2Init, - dim3272Kuo2Init, - dim3273Kuo2Init, - dim3274Kuo2Init, - dim3275Kuo2Init, - dim3276Kuo2Init, - dim3277Kuo2Init, - dim3278Kuo2Init, - dim3279Kuo2Init, - dim3280Kuo2Init, - dim3281Kuo2Init, - dim3282Kuo2Init, - dim3283Kuo2Init, - dim3284Kuo2Init, - dim3285Kuo2Init, - dim3286Kuo2Init, - dim3287Kuo2Init, - dim3288Kuo2Init, - dim3289Kuo2Init, - dim3290Kuo2Init, - dim3291Kuo2Init, - dim3292Kuo2Init, - dim3293Kuo2Init, - dim3294Kuo2Init, - dim3295Kuo2Init, - dim3296Kuo2Init, - dim3297Kuo2Init, - dim3298Kuo2Init, - dim3299Kuo2Init, - dim3300Kuo2Init, - dim3301Kuo2Init, - dim3302Kuo2Init, - dim3303Kuo2Init, - dim3304Kuo2Init, - dim3305Kuo2Init, - dim3306Kuo2Init, - dim3307Kuo2Init, - dim3308Kuo2Init, - dim3309Kuo2Init, - dim3310Kuo2Init, - dim3311Kuo2Init, - dim3312Kuo2Init, - dim3313Kuo2Init, - dim3314Kuo2Init, - dim3315Kuo2Init, - dim3316Kuo2Init, - dim3317Kuo2Init, - dim3318Kuo2Init, - dim3319Kuo2Init, - dim3320Kuo2Init, - dim3321Kuo2Init, - dim3322Kuo2Init, - dim3323Kuo2Init, - dim3324Kuo2Init, - dim3325Kuo2Init, - dim3326Kuo2Init, - dim3327Kuo2Init, - dim3328Kuo2Init, - dim3329Kuo2Init, - dim3330Kuo2Init, - dim3331Kuo2Init, - dim3332Kuo2Init, - dim3333Kuo2Init, - dim3334Kuo2Init, - dim3335Kuo2Init, - dim3336Kuo2Init, - dim3337Kuo2Init, - dim3338Kuo2Init, - dim3339Kuo2Init, - dim3340Kuo2Init, - dim3341Kuo2Init, - dim3342Kuo2Init, - dim3343Kuo2Init, - dim3344Kuo2Init, - dim3345Kuo2Init, - dim3346Kuo2Init, - dim3347Kuo2Init, - dim3348Kuo2Init, - dim3349Kuo2Init, - dim3350Kuo2Init, - dim3351Kuo2Init, - dim3352Kuo2Init, - dim3353Kuo2Init, - dim3354Kuo2Init, - dim3355Kuo2Init, - dim3356Kuo2Init, - dim3357Kuo2Init, - dim3358Kuo2Init, - dim3359Kuo2Init, - dim3360Kuo2Init, - dim3361Kuo2Init, - dim3362Kuo2Init, - dim3363Kuo2Init, - dim3364Kuo2Init, - dim3365Kuo2Init, - dim3366Kuo2Init, - dim3367Kuo2Init, - dim3368Kuo2Init, - dim3369Kuo2Init, - dim3370Kuo2Init, - dim3371Kuo2Init, - dim3372Kuo2Init, - dim3373Kuo2Init, - dim3374Kuo2Init, - dim3375Kuo2Init, - dim3376Kuo2Init, - dim3377Kuo2Init, - dim3378Kuo2Init, - dim3379Kuo2Init, - dim3380Kuo2Init, - dim3381Kuo2Init, - dim3382Kuo2Init, - dim3383Kuo2Init, - dim3384Kuo2Init, - dim3385Kuo2Init, - dim3386Kuo2Init, - dim3387Kuo2Init, - dim3388Kuo2Init, - dim3389Kuo2Init, - dim3390Kuo2Init, - dim3391Kuo2Init, - dim3392Kuo2Init, - dim3393Kuo2Init, - dim3394Kuo2Init, - dim3395Kuo2Init, - dim3396Kuo2Init, - dim3397Kuo2Init, - dim3398Kuo2Init, - dim3399Kuo2Init, - dim3400Kuo2Init, - dim3401Kuo2Init, - dim3402Kuo2Init, - dim3403Kuo2Init, - dim3404Kuo2Init, - dim3405Kuo2Init, - dim3406Kuo2Init, - dim3407Kuo2Init, - dim3408Kuo2Init, - dim3409Kuo2Init, - dim3410Kuo2Init, - dim3411Kuo2Init, - dim3412Kuo2Init, - dim3413Kuo2Init, - dim3414Kuo2Init, - dim3415Kuo2Init, - dim3416Kuo2Init, - dim3417Kuo2Init, - dim3418Kuo2Init, - dim3419Kuo2Init, - dim3420Kuo2Init, - dim3421Kuo2Init, - dim3422Kuo2Init, - dim3423Kuo2Init, - dim3424Kuo2Init, - dim3425Kuo2Init, - dim3426Kuo2Init, - dim3427Kuo2Init, - dim3428Kuo2Init, - dim3429Kuo2Init, - dim3430Kuo2Init, - dim3431Kuo2Init, - dim3432Kuo2Init, - dim3433Kuo2Init, - dim3434Kuo2Init, - dim3435Kuo2Init, - dim3436Kuo2Init, - dim3437Kuo2Init, - dim3438Kuo2Init, - dim3439Kuo2Init, - dim3440Kuo2Init, - dim3441Kuo2Init, - dim3442Kuo2Init, - dim3443Kuo2Init, - dim3444Kuo2Init, - dim3445Kuo2Init, - dim3446Kuo2Init, - dim3447Kuo2Init, - dim3448Kuo2Init, - dim3449Kuo2Init, - dim3450Kuo2Init, - dim3451Kuo2Init, - dim3452Kuo2Init, - dim3453Kuo2Init, - dim3454Kuo2Init, - dim3455Kuo2Init, - dim3456Kuo2Init, - dim3457Kuo2Init, - dim3458Kuo2Init, - dim3459Kuo2Init, - dim3460Kuo2Init, - dim3461Kuo2Init, - dim3462Kuo2Init, - dim3463Kuo2Init, - dim3464Kuo2Init, - dim3465Kuo2Init, - dim3466Kuo2Init, - dim3467Kuo2Init, - dim3468Kuo2Init, - dim3469Kuo2Init, - dim3470Kuo2Init, - dim3471Kuo2Init, - dim3472Kuo2Init, - dim3473Kuo2Init, - dim3474Kuo2Init, - dim3475Kuo2Init, - dim3476Kuo2Init, - dim3477Kuo2Init, - dim3478Kuo2Init, - dim3479Kuo2Init, - dim3480Kuo2Init, - dim3481Kuo2Init, - dim3482Kuo2Init, - dim3483Kuo2Init, - dim3484Kuo2Init, - dim3485Kuo2Init, - dim3486Kuo2Init, - dim3487Kuo2Init, - dim3488Kuo2Init, - dim3489Kuo2Init, - dim3490Kuo2Init, - dim3491Kuo2Init, - dim3492Kuo2Init, - dim3493Kuo2Init, - dim3494Kuo2Init, - dim3495Kuo2Init, - dim3496Kuo2Init, - dim3497Kuo2Init, - dim3498Kuo2Init, - dim3499Kuo2Init, - dim3500Kuo2Init, - dim3501Kuo2Init, - dim3502Kuo2Init, - dim3503Kuo2Init, - dim3504Kuo2Init, - dim3505Kuo2Init, - dim3506Kuo2Init, - dim3507Kuo2Init, - dim3508Kuo2Init, - dim3509Kuo2Init, - dim3510Kuo2Init, - dim3511Kuo2Init, - dim3512Kuo2Init, - dim3513Kuo2Init, - dim3514Kuo2Init, - dim3515Kuo2Init, - dim3516Kuo2Init, - dim3517Kuo2Init, - dim3518Kuo2Init, - dim3519Kuo2Init, - dim3520Kuo2Init, - dim3521Kuo2Init, - dim3522Kuo2Init, - dim3523Kuo2Init, - dim3524Kuo2Init, - dim3525Kuo2Init, - dim3526Kuo2Init, - dim3527Kuo2Init, - dim3528Kuo2Init, - dim3529Kuo2Init, - dim3530Kuo2Init, - dim3531Kuo2Init, - dim3532Kuo2Init, - dim3533Kuo2Init, - dim3534Kuo2Init, - dim3535Kuo2Init, - dim3536Kuo2Init, - dim3537Kuo2Init, - dim3538Kuo2Init, - dim3539Kuo2Init, - dim3540Kuo2Init, - dim3541Kuo2Init, - dim3542Kuo2Init, - dim3543Kuo2Init, - dim3544Kuo2Init, - dim3545Kuo2Init, - dim3546Kuo2Init, - dim3547Kuo2Init, - dim3548Kuo2Init, - dim3549Kuo2Init, - dim3550Kuo2Init, - dim3551Kuo2Init, - dim3552Kuo2Init, - dim3553Kuo2Init, - dim3554Kuo2Init, - dim3555Kuo2Init, - dim3556Kuo2Init, - dim3557Kuo2Init, - dim3558Kuo2Init, - dim3559Kuo2Init, - dim3560Kuo2Init, - dim3561Kuo2Init, - dim3562Kuo2Init, - dim3563Kuo2Init, - dim3564Kuo2Init, - dim3565Kuo2Init, - dim3566Kuo2Init, - dim3567Kuo2Init, - dim3568Kuo2Init, - dim3569Kuo2Init, - dim3570Kuo2Init, - dim3571Kuo2Init, - dim3572Kuo2Init, - dim3573Kuo2Init, - dim3574Kuo2Init, - dim3575Kuo2Init, - dim3576Kuo2Init, - dim3577Kuo2Init, - dim3578Kuo2Init, - dim3579Kuo2Init, - dim3580Kuo2Init, - dim3581Kuo2Init, - dim3582Kuo2Init, - dim3583Kuo2Init, - dim3584Kuo2Init, - dim3585Kuo2Init, - dim3586Kuo2Init, - dim3587Kuo2Init, - dim3588Kuo2Init, - dim3589Kuo2Init, - dim3590Kuo2Init, - dim3591Kuo2Init, - dim3592Kuo2Init, - dim3593Kuo2Init, - dim3594Kuo2Init, - dim3595Kuo2Init, - dim3596Kuo2Init, - dim3597Kuo2Init, - dim3598Kuo2Init, - dim3599Kuo2Init, - dim3600Kuo2Init, - dim3601Kuo2Init, - dim3602Kuo2Init, - dim3603Kuo2Init, - dim3604Kuo2Init, - dim3605Kuo2Init, - dim3606Kuo2Init, - dim3607Kuo2Init, - dim3608Kuo2Init, - dim3609Kuo2Init, - dim3610Kuo2Init, - dim3611Kuo2Init, - dim3612Kuo2Init, - dim3613Kuo2Init, - dim3614Kuo2Init, - dim3615Kuo2Init, - dim3616Kuo2Init, - dim3617Kuo2Init, - dim3618Kuo2Init, - dim3619Kuo2Init, - dim3620Kuo2Init, - dim3621Kuo2Init, - dim3622Kuo2Init, - dim3623Kuo2Init, - dim3624Kuo2Init, - dim3625Kuo2Init, - dim3626Kuo2Init, - dim3627Kuo2Init, - dim3628Kuo2Init, - dim3629Kuo2Init, - dim3630Kuo2Init, - dim3631Kuo2Init, - dim3632Kuo2Init, - dim3633Kuo2Init, - dim3634Kuo2Init, - dim3635Kuo2Init, - dim3636Kuo2Init, - dim3637Kuo2Init, - dim3638Kuo2Init, - dim3639Kuo2Init, - dim3640Kuo2Init, - dim3641Kuo2Init, - dim3642Kuo2Init, - dim3643Kuo2Init, - dim3644Kuo2Init, - dim3645Kuo2Init, - dim3646Kuo2Init, - dim3647Kuo2Init, - dim3648Kuo2Init, - dim3649Kuo2Init, - dim3650Kuo2Init, - dim3651Kuo2Init, - dim3652Kuo2Init, - dim3653Kuo2Init, - dim3654Kuo2Init, - dim3655Kuo2Init, - dim3656Kuo2Init, - dim3657Kuo2Init, - dim3658Kuo2Init, - dim3659Kuo2Init, - dim3660Kuo2Init, - dim3661Kuo2Init, - dim3662Kuo2Init, - dim3663Kuo2Init, - dim3664Kuo2Init, - dim3665Kuo2Init, - dim3666Kuo2Init, - dim3667Kuo2Init, - dim3668Kuo2Init, - dim3669Kuo2Init, - dim3670Kuo2Init, - dim3671Kuo2Init, - dim3672Kuo2Init, - dim3673Kuo2Init, - dim3674Kuo2Init, - dim3675Kuo2Init, - dim3676Kuo2Init, - dim3677Kuo2Init, - dim3678Kuo2Init, - dim3679Kuo2Init, - dim3680Kuo2Init, - dim3681Kuo2Init, - dim3682Kuo2Init, - dim3683Kuo2Init, - dim3684Kuo2Init, - dim3685Kuo2Init, - dim3686Kuo2Init, - dim3687Kuo2Init, - dim3688Kuo2Init, - dim3689Kuo2Init, - dim3690Kuo2Init, - dim3691Kuo2Init, - dim3692Kuo2Init, - dim3693Kuo2Init, - dim3694Kuo2Init, - dim3695Kuo2Init, - dim3696Kuo2Init, - dim3697Kuo2Init, - dim3698Kuo2Init, - dim3699Kuo2Init, - dim3700Kuo2Init, - dim3701Kuo2Init, - dim3702Kuo2Init, - dim3703Kuo2Init, - dim3704Kuo2Init, - dim3705Kuo2Init, - dim3706Kuo2Init, - dim3707Kuo2Init, - dim3708Kuo2Init, - dim3709Kuo2Init, - dim3710Kuo2Init, - dim3711Kuo2Init, - dim3712Kuo2Init, - dim3713Kuo2Init, - dim3714Kuo2Init, - dim3715Kuo2Init, - dim3716Kuo2Init, - dim3717Kuo2Init, - dim3718Kuo2Init, - dim3719Kuo2Init, - dim3720Kuo2Init, - dim3721Kuo2Init, - dim3722Kuo2Init, - dim3723Kuo2Init, - dim3724Kuo2Init, - dim3725Kuo2Init, - dim3726Kuo2Init, - dim3727Kuo2Init, - dim3728Kuo2Init, - dim3729Kuo2Init, - dim3730Kuo2Init, - dim3731Kuo2Init, - dim3732Kuo2Init, - dim3733Kuo2Init, - dim3734Kuo2Init, - dim3735Kuo2Init, - dim3736Kuo2Init, - dim3737Kuo2Init, - dim3738Kuo2Init, - dim3739Kuo2Init, - dim3740Kuo2Init, - dim3741Kuo2Init, - dim3742Kuo2Init, - dim3743Kuo2Init, - dim3744Kuo2Init, - dim3745Kuo2Init, - dim3746Kuo2Init, - dim3747Kuo2Init, - dim3748Kuo2Init, - dim3749Kuo2Init, - dim3750Kuo2Init, - dim3751Kuo2Init, - dim3752Kuo2Init, - dim3753Kuo2Init, - dim3754Kuo2Init, - dim3755Kuo2Init, - dim3756Kuo2Init, - dim3757Kuo2Init, - dim3758Kuo2Init, - dim3759Kuo2Init, - dim3760Kuo2Init, - dim3761Kuo2Init, - dim3762Kuo2Init, - dim3763Kuo2Init, - dim3764Kuo2Init, - dim3765Kuo2Init, - dim3766Kuo2Init, - dim3767Kuo2Init, - dim3768Kuo2Init, - dim3769Kuo2Init, - dim3770Kuo2Init, - dim3771Kuo2Init, - dim3772Kuo2Init, - dim3773Kuo2Init, - dim3774Kuo2Init, - dim3775Kuo2Init, - dim3776Kuo2Init, - dim3777Kuo2Init, - dim3778Kuo2Init, - dim3779Kuo2Init, - dim3780Kuo2Init, - dim3781Kuo2Init, - dim3782Kuo2Init, - dim3783Kuo2Init, - dim3784Kuo2Init, - dim3785Kuo2Init, - dim3786Kuo2Init, - dim3787Kuo2Init, - dim3788Kuo2Init, - dim3789Kuo2Init, - dim3790Kuo2Init, - dim3791Kuo2Init, - dim3792Kuo2Init, - dim3793Kuo2Init, - dim3794Kuo2Init, - dim3795Kuo2Init, - dim3796Kuo2Init, - dim3797Kuo2Init, - dim3798Kuo2Init, - dim3799Kuo2Init, - dim3800Kuo2Init, - dim3801Kuo2Init, - dim3802Kuo2Init, - dim3803Kuo2Init, - dim3804Kuo2Init, - dim3805Kuo2Init, - dim3806Kuo2Init, - dim3807Kuo2Init, - dim3808Kuo2Init, - dim3809Kuo2Init, - dim3810Kuo2Init, - dim3811Kuo2Init, - dim3812Kuo2Init, - dim3813Kuo2Init, - dim3814Kuo2Init, - dim3815Kuo2Init, - dim3816Kuo2Init, - dim3817Kuo2Init, - dim3818Kuo2Init, - dim3819Kuo2Init, - dim3820Kuo2Init, - dim3821Kuo2Init, - dim3822Kuo2Init, - dim3823Kuo2Init, - dim3824Kuo2Init, - dim3825Kuo2Init, - dim3826Kuo2Init, - dim3827Kuo2Init, - dim3828Kuo2Init, - dim3829Kuo2Init, - dim3830Kuo2Init, - dim3831Kuo2Init, - dim3832Kuo2Init, - dim3833Kuo2Init, - dim3834Kuo2Init, - dim3835Kuo2Init, - dim3836Kuo2Init, - dim3837Kuo2Init, - dim3838Kuo2Init, - dim3839Kuo2Init, - dim3840Kuo2Init, - dim3841Kuo2Init, - dim3842Kuo2Init, - dim3843Kuo2Init, - dim3844Kuo2Init, - dim3845Kuo2Init, - dim3846Kuo2Init, - dim3847Kuo2Init, - dim3848Kuo2Init, - dim3849Kuo2Init, - dim3850Kuo2Init, - dim3851Kuo2Init, - dim3852Kuo2Init, - dim3853Kuo2Init, - dim3854Kuo2Init, - dim3855Kuo2Init, - dim3856Kuo2Init, - dim3857Kuo2Init, - dim3858Kuo2Init, - dim3859Kuo2Init, - dim3860Kuo2Init, - dim3861Kuo2Init, - dim3862Kuo2Init, - dim3863Kuo2Init, - dim3864Kuo2Init, - dim3865Kuo2Init, - dim3866Kuo2Init, - dim3867Kuo2Init, - dim3868Kuo2Init, - dim3869Kuo2Init, - dim3870Kuo2Init, - dim3871Kuo2Init, - dim3872Kuo2Init, - dim3873Kuo2Init, - dim3874Kuo2Init, - dim3875Kuo2Init, - dim3876Kuo2Init, - dim3877Kuo2Init, - dim3878Kuo2Init, - dim3879Kuo2Init, - dim3880Kuo2Init, - dim3881Kuo2Init, - dim3882Kuo2Init, - dim3883Kuo2Init, - dim3884Kuo2Init, - dim3885Kuo2Init, - dim3886Kuo2Init, - dim3887Kuo2Init, - dim3888Kuo2Init, - dim3889Kuo2Init, - dim3890Kuo2Init, - dim3891Kuo2Init, - dim3892Kuo2Init, - dim3893Kuo2Init, - dim3894Kuo2Init, - dim3895Kuo2Init, - dim3896Kuo2Init, - dim3897Kuo2Init, - dim3898Kuo2Init, - dim3899Kuo2Init, - dim3900Kuo2Init, - dim3901Kuo2Init, - dim3902Kuo2Init, - dim3903Kuo2Init, - dim3904Kuo2Init, - dim3905Kuo2Init, - dim3906Kuo2Init, - dim3907Kuo2Init, - dim3908Kuo2Init, - dim3909Kuo2Init, - dim3910Kuo2Init, - dim3911Kuo2Init, - dim3912Kuo2Init, - dim3913Kuo2Init, - dim3914Kuo2Init, - dim3915Kuo2Init, - dim3916Kuo2Init, - dim3917Kuo2Init, - dim3918Kuo2Init, - dim3919Kuo2Init, - dim3920Kuo2Init, - dim3921Kuo2Init, - dim3922Kuo2Init, - dim3923Kuo2Init, - dim3924Kuo2Init, - dim3925Kuo2Init, - dim3926Kuo2Init, - dim3927Kuo2Init, - dim3928Kuo2Init, - dim3929Kuo2Init, - dim3930Kuo2Init, - dim3931Kuo2Init, - dim3932Kuo2Init, - dim3933Kuo2Init, - dim3934Kuo2Init, - dim3935Kuo2Init, - dim3936Kuo2Init, - dim3937Kuo2Init, - dim3938Kuo2Init, - dim3939Kuo2Init, - dim3940Kuo2Init, - dim3941Kuo2Init, - dim3942Kuo2Init, - dim3943Kuo2Init, - dim3944Kuo2Init, - dim3945Kuo2Init, - dim3946Kuo2Init, - }; - } - -#endif - -} diff --git a/src/QLNet/Math/statistics/ConvergenceStatistics.cs b/src/QLNet/Math/statistics/ConvergenceStatistics.cs new file mode 100644 index 000000000..1a14ae6a0 --- /dev/null +++ b/src/QLNet/Math/statistics/ConvergenceStatistics.cs @@ -0,0 +1,146 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + public interface IConvergenceSteps + { + int initialSamples(); + int nextSamples(int current); + } + + public class DoublingConvergenceSteps : IConvergenceSteps + { + + public int initialSamples() { return 1; } + public int nextSamples(int current) { return 2 * current + 1; } + } + + //! statistics class with convergence table + /*! This class decorates another statistics class adding a + convergence table calculation. The table tracks the + convergence of the mean. + + It is possible to specify the number of samples at which the + mean should be stored by mean of the second template + parameter; the default is to store \f$ 2^{n-1} \f$ samples at + the \f$ n \f$-th step. Any passed class must implement the + following interface: + \code + Size initialSamples() const + Size nextSamples(Size currentSamples) const + \endcode + as well as a copy constructor. + + \test results are tested against known good values. + */ + public class ConvergenceStatistics : ConvergenceStatistics + where T : IGeneralStatistics, new () + { + public ConvergenceStatistics(T stats, DoublingConvergenceSteps rule) : base(stats, rule) { } + public ConvergenceStatistics() : base(new DoublingConvergenceSteps()) { } + public ConvergenceStatistics(DoublingConvergenceSteps rule) : base(rule) { } + } + + public class ConvergenceStatistics : IGeneralStatistics + where T : IGeneralStatistics, new () + where U : IConvergenceSteps, new () + { + + private List> table_ = new List>(); + public List>convergenceTable() { return table_; } + + private U samplingRule_; + private int nextSampleSize_; + + public ConvergenceStatistics(T stats, U rule) + { + impl_ = stats; + samplingRule_ = rule; + + reset(); + } + + public ConvergenceStatistics() : this(FastActivator.Create()) { } + public ConvergenceStatistics(U rule) + { + samplingRule_ = rule; + reset(); + } + + public void reset() + { + impl_.reset(); + nextSampleSize_ = samplingRule_.initialSamples(); + table_.Clear(); + } + + public void add + (double value) { add(value, 1); } + public void add + (double value, double weight) + { + impl_.add(value, weight); + if (samples() == nextSampleSize_) + { + table_.Add(new KeyValuePair(samples(), mean())); + nextSampleSize_ = samplingRule_.nextSamples(nextSampleSize_); + } + } + + //! adds a sequence of data to the set, with default weight + public void addSequence(List list) + { + foreach (double v in list) + add + (v, 1); + } + //! adds a sequence of data to the set, each with its weight + public void addSequence(List data, List weight) + { + for (int i = 0; i < data.Count; i++) + add + (data[i], weight[i]); + } + + #region wrap-up Stat + protected T impl_ = FastActivator.Create(); + + public int samples() { return impl_.samples(); } + public double mean() { return impl_.mean(); } + public double min() { return impl_.min(); } + public double max() { return impl_.max(); } + public double standardDeviation() { return impl_.standardDeviation(); } + public double variance() { return impl_.variance(); } + public double skewness() { return impl_.skewness(); } + public double kurtosis() { return impl_.kurtosis(); } + public double percentile(double percent) { return impl_.percentile(percent); } + public double weightSum() { return impl_.weightSum(); } + public double errorEstimate() { return impl_.errorEstimate(); } + + public KeyValuePair expectationValue(Func, double> f, + Func, bool> inRange) + { + return impl_.expectationValue(f, inRange); + } + #endregion + } +} diff --git a/src/QLNet/Math/statistics/DiscrepancyStatistics.cs b/src/QLNet/Math/statistics/DiscrepancyStatistics.cs index 87b819519..81d0e12f4 100644 --- a/src/QLNet/Math/statistics/DiscrepancyStatistics.cs +++ b/src/QLNet/Math/statistics/DiscrepancyStatistics.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -41,16 +41,20 @@ public DiscrepancyStatistics(int dimension) public double discrepancy() { int N = samples(); - if (N == 0) return 0; + if (N == 0) + return 0; return Math.Sqrt(adiscr_ / (N * N) - bdiscr_ / N * cdiscr_ + ddiscr_); } - public override void add(List begin) + public override void add + (List begin) { - add(begin, 1); + add + (begin, 1); } - public override void add(List begin, double weight) + public override void add + (List begin, double weight) { base.add(begin, weight); int k, m, N; diff --git a/src/QLNet/Math/statistics/GaussianStatistics.cs b/src/QLNet/Math/statistics/GaussianStatistics.cs new file mode 100644 index 000000000..165bebc03 --- /dev/null +++ b/src/QLNet/Math/statistics/GaussianStatistics.cs @@ -0,0 +1,213 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + //! Statistics tool for gaussian-assumption risk measures + /*! This class wraps a somewhat generic statistic tool and adds + a number of gaussian risk measures (e.g.: value-at-risk, expected + shortfall, etc.) based on the mean and variance provided by + the underlying statistic tool. + */ + public class GenericGaussianStatistics : IGeneralStatistics where Stat : IGeneralStatistics, new () + { + public GenericGaussianStatistics() { } + public GenericGaussianStatistics(Stat s) + { + impl_ = s; + } + + #region wrap-up Stat + protected Stat impl_ = FastActivator.Create(); + + public int samples() { return impl_.samples(); } + public double mean() { return impl_.mean(); } + public double min() { return impl_.min(); } + public double max() { return impl_.max(); } + public double standardDeviation() { return impl_.standardDeviation(); } + public double variance() { return impl_.variance(); } + public double skewness() { return impl_.skewness(); } + public double kurtosis() { return impl_.kurtosis(); } + public double percentile(double percent) { return impl_.percentile(percent); } + public double weightSum() { return impl_.weightSum(); } + public double errorEstimate() { return impl_.errorEstimate(); } + + public void reset() { impl_.reset(); } + public void add + (double value, double weight) { impl_.add(value, weight); } + public void addSequence(List data, List weight) { impl_.addSequence(data, weight); } + + public KeyValuePair expectationValue(Func, double> f, + Func, bool> inRange) + { + return impl_.expectationValue(f, inRange); + } + #endregion + + + // Gaussian risk measures + /*! returns the downside variance + */ + public double gaussianDownsideVariance() { return gaussianRegret(0.0); } + + /*! returns the downside deviation, defined as the square root of the downside variance. */ + public double gaussianDownsideDeviation() { return Math.Sqrt(gaussianDownsideVariance()); } + + /*! returns the variance of observations below target + See Dembo, Freeman "The Rules Of Risk", Wiley (2001) + */ + public double gaussianRegret(double target) + { + double m = this.mean(); + double std = this.standardDeviation(); + double variance = std * std; + CumulativeNormalDistribution gIntegral = new CumulativeNormalDistribution(m, std); + NormalDistribution g = new NormalDistribution(m, std); + double firstTerm = variance + m * m - 2.0 * target * m + target * target; + double alfa = gIntegral.value(target); + double secondTerm = m - target; + double beta = variance * g.value(target); + double result = alfa * firstTerm - beta * secondTerm; + return result / alfa; + } + + /*! gaussian-assumption y-th percentile + */ + /*! \pre percentile must be in range (0%-100%) extremes excluded */ + public double gaussianPercentile(double percentile) + { + Utils.QL_REQUIRE(percentile > 0.0 && percentile < 1.0, () => "percentile (" + percentile + ") must be in (0.0, 1.0)"); + + InverseCumulativeNormal gInverse = new InverseCumulativeNormal(mean(), standardDeviation()); + return gInverse.value(percentile); + } + public double gaussianTopPercentile(double percentile) { return gaussianPercentile(1.0 - percentile); } + + //! gaussian-assumption Potential-Upside at a given percentile + public double gaussianPotentialUpside(double percentile) + { + Utils.QL_REQUIRE(percentile<1.0 && percentile >= 0.9, () => "percentile (" + percentile + ") out of range [0.9, 1)"); + + double result = gaussianPercentile(percentile); + // potential upside must be a gain, i.e., floored at 0.0 + return Math.Max(result, 0.0); + } + + //! gaussian-assumption Value-At-Risk at a given percentile + public double gaussianValueAtRisk(double percentile) + { + Utils.QL_REQUIRE(percentile < 1.0 && percentile >= 0.9, () => "percentile (" + percentile + ") out of range [0.9, 1)"); + + double result = gaussianPercentile(1.0 - percentile); + // VAR must be a loss + // this means that it has to be MIN(dist(1.0-percentile), 0.0) + // VAR must also be a positive quantity, so -MIN(*) + return -Math.Min(result, 0.0); + } + + //! gaussian-assumption Expected Shortfall at a given percentile + /*! Assuming a gaussian distribution it + returns the expected loss in case that the loss exceeded + a VaR threshold, + + that is the average of observations below the + given percentile \f$ p \f$. + Also know as conditional value-at-risk. + + See Artzner, Delbaen, Eber and Heath, + "Coherent measures of risk", Mathematical Finance 9 (1999) + */ + public double gaussianExpectedShortfall(double percentile) + { + Utils.QL_REQUIRE(percentile < 1.0 && percentile >= 0.9, () => "percentile (" + percentile + ") out of range [0.9, 1)"); + + double m = this.mean(); + double std = this.standardDeviation(); + InverseCumulativeNormal gInverse = new InverseCumulativeNormal(m, std); + double var = gInverse.value(1.0 - percentile); + NormalDistribution g = new NormalDistribution(m, std); + double result = m - std * std * g.value(var) / (1.0 - percentile); + // expectedShortfall must be a loss + // this means that it has to be MIN(result, 0.0) + // expectedShortfall must also be a positive quantity, so -MIN(*) + return -Math.Min(result, 0.0); + } + + //! gaussian-assumption Shortfall (observations below target) + public double gaussianShortfall(double target) + { + CumulativeNormalDistribution gIntegral = new CumulativeNormalDistribution(this.mean(), this.standardDeviation()); + return gIntegral.value(target); + } + + //! gaussian-assumption Average Shortfall (averaged shortfallness) + public double gaussianAverageShortfall(double target) + { + double m = this.mean(); + double std = this.standardDeviation(); + CumulativeNormalDistribution gIntegral = new CumulativeNormalDistribution(m, std); + NormalDistribution g = new NormalDistribution(m, std); + return ((target - m) + std * std * g.value(target) / gIntegral.value(target)); + } + } + + //! default gaussian statistic tool + public class GaussianStatistics : GenericGaussianStatistics { } + + + //! Helper class for precomputed distributions + public class StatsHolder : IGeneralStatistics + { + private double mean_, standardDeviation_; + public double mean() { return mean_; } + public double standardDeviation() { return standardDeviation_; } + + public StatsHolder() { } // required for generics + public StatsHolder(double mean, double standardDeviation) + { + mean_ = mean; + standardDeviation_ = standardDeviation; + } + + #region IGeneralStatistics + public int samples() { throw new NotSupportedException(); } + public double min() { throw new NotSupportedException(); } + public double max() { throw new NotSupportedException(); } + public double variance() { throw new NotSupportedException(); } + public double skewness() { throw new NotSupportedException(); } + public double kurtosis() { throw new NotSupportedException(); } + public double percentile(double percent) { throw new NotSupportedException(); } + public double weightSum() { throw new NotSupportedException(); } + public double errorEstimate() { throw new NotSupportedException(); } + + public void reset() { throw new NotSupportedException(); } + public void add + (double value, double weight) { throw new NotSupportedException(); } + public void addSequence(List data, List weight) { throw new NotSupportedException(); } + + public KeyValuePair expectationValue(Func, double> f, + Func, bool> inRange) + { + throw new NotSupportedException(); + } + #endregion + } +} diff --git a/src/QLNet/Math/statistics/GeneralStatistics.cs b/src/QLNet/Math/statistics/GeneralStatistics.cs new file mode 100644 index 000000000..98427661d --- /dev/null +++ b/src/QLNet/Math/statistics/GeneralStatistics.cs @@ -0,0 +1,284 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QLNet +{ + public interface IGeneralStatistics + { + int samples(); + double mean(); + double min(); + double max(); + double standardDeviation(); + double variance(); + double skewness(); + double kurtosis(); + double percentile(double percent); + double weightSum(); + double errorEstimate(); + + void reset(); + void add + (double value, double weight); + void addSequence(List data, List weight); + + KeyValuePair expectationValue(Func, double> f, + Func, bool> inRange); + } + + //! Statistics tool + /*! This class accumulates a set of data and returns their + statistics (e.g: mean, variance, skewness, kurtosis, + error estimation, percentile, etc.) based on the empirical + distribution (no gaussian assumption) + + It doesn't suffer the numerical instability problem of + IncrementalStatistics. The downside is that it stores all + samples, thus increasing the memory requirements. + */ + public class GeneralStatistics : IGeneralStatistics + { + private List> samples_; + //! number of samples collected + public int samples() { return samples_.Count; } + //! collected data + public List> data() { return samples_; } + + private bool sorted_; + private double? mean_ = null, weightSum_ = null, variance_ = null, skewness_ = null, kurtosis_ = null; + + + public GeneralStatistics() { reset(); } + + + /*! returns the error estimate on the mean value, defined as + \f$ \epsilon = \sigma/\sqrt{N}. \f$ */ + public double errorEstimate() { return Math.Sqrt(variance() / samples()); } + + /*! returns the minimum sample value */ + public double min() + { + Utils.QL_REQUIRE(samples() > 0, () => "empty sample set"); + return samples_.Min(x => x.Key); + } + + /*! returns the maximum sample value */ + public double max() + { + Utils.QL_REQUIRE(samples() > 0, () => "empty sample set"); + return samples_.Max(x => x.Key); + } + + + //! adds a datum to the set, possibly with a weight + public void add + (double value) { add(value, 1); } + public void add + (double value, double weight) + { + Utils.QL_REQUIRE(weight >= 0.0, () => "negative weight not allowed"); + samples_.Add(new KeyValuePair(value, weight)); + + sorted_ = false; + mean_ = weightSum_ = variance_ = skewness_ = kurtosis_ = null; + } + + //! resets the data to a null set + public void reset() + { + samples_ = new List>(); + + sorted_ = true; + mean_ = weightSum_ = variance_ = skewness_ = kurtosis_ = null; + } + + //! sort the data set in increasing order + public void sort() + { + if (!sorted_) + { + samples_.Sort((x, y) => x.Key.CompareTo(y.Key)); + sorted_ = true; + } + } + + + //! sum of data weights + public double weightSum() + { + if (weightSum_ == null) + weightSum_ = samples_.Sum>(x => x.Value); + return weightSum_.GetValueOrDefault(); + } + + /*! returns the mean, defined as + \f[ \langle x \rangle = \frac{\sum w_i x_i}{\sum w_i}. \f] */ + public double mean() + { + if (mean_ == null) + { + int N = samples(); + Utils.QL_REQUIRE(samples() > 0, () => "empty sample set"); + // eat our own dog food + mean_ = expectationValue(x => x.Key * x.Value, x => true).Key; + } + return mean_.GetValueOrDefault(); + } + + /*! returns the standard deviation \f$ \sigma \f$, defined as the + square root of the variance. */ + public double standardDeviation() { return Math.Sqrt(variance()); } + + /*! returns the variance, defined as + \f[ \sigma^2 = \frac{N}{N-1} \left\langle \left( + x-\langle x \rangle \right)^2 \right\rangle. \f] */ + public double variance() + { + if (variance_ == null) + { + int N = samples(); + Utils.QL_REQUIRE(N > 1, () => "sample number <=1, unsufficient"); + // Subtract the mean and square. Repeat on the whole range. + // Hopefully, the whole thing will be inlined in a single loop. + double s2 = expectationValue(x => Math.Pow(x.Key * x.Value - mean(), 2), x => true).Key; + variance_ = s2 * N / (N - 1.0); + } + return variance_.GetValueOrDefault(); + } + + /*! returns the skewness, defined as + \f[ \frac{N^2}{(N-1)(N-2)} \frac{\left\langle \left( + x-\langle x \rangle \right)^3 \right\rangle}{\sigma^3}. \f] + The above evaluates to 0 for a Gaussian distribution. + */ + public double skewness() + { + if (skewness_ == null) + { + int N = samples(); + Utils.QL_REQUIRE(N > 2, () => "sample number <=2, unsufficient"); + + double x = expectationValue(y => Math.Pow(y.Key * y.Value - mean(), 3), y => true).Key; + double sigma = standardDeviation(); + + skewness_ = (x / Math.Pow(sigma, 3)) * (N / (N - 1.0)) * (N / (N - 2.0)); + } + return skewness_.GetValueOrDefault(); + } + + /*! returns the excess kurtosis + The above evaluates to 0 for a Gaussian distribution. + */ + public double kurtosis() + { + if (kurtosis_ == null) + { + int N = samples(); + Utils.QL_REQUIRE(N > 3, () => "sample number <=3, unsufficient"); + + double x = expectationValue(y => Math.Pow(y.Key * y.Value - mean(), 4), y => true).Key; + double sigma2 = variance(); + + double c1 = (N / (N - 1.0)) * (N / (N - 2.0)) * ((N + 1.0) / (N - 3.0)); + double c2 = 3.0 * ((N - 1.0) / (N - 2.0)) * ((N - 1.0) / (N - 3.0)); + + kurtosis_ = c1 * (x / (sigma2 * sigma2)) - c2; + } + return kurtosis_.GetValueOrDefault(); + } + + /*! Expectation value of a function \f$ f \f$ on a given range \f$ \mathcal{R} \f$, i.e., + + The range is passed as a boolean function returning + true if the argument belongs to the range + or false otherwise. + + The function returns a pair made of the result and the number of observations in the given range. */ + public KeyValuePair expectationValue(Func, double> f, + Func, bool> inRange) + { + double num = 0.0, den = 0.0; + int N = 0; + + foreach (KeyValuePair x in samples_.Where>(x => inRange(x))) + { + num += f(x) * x.Value; + den += x.Value; + N += 1; + } + + if (N == 0) + return new KeyValuePair(0, 0); + return new KeyValuePair(num / den, N); + } + + /*! \f$ y \f$-th percentile, defined as the value \f$ \bar{x} \f$ + \pre \f$ y \f$ must be in the range \f$ (0-1]. \f$ + */ + public double percentile(double percent) + { + + Utils.QL_REQUIRE(percent > 0.0 && percent <= 1.0, () => "percentile (" + percent + ") must be in (0.0, 1.0]"); + + double sampleWeight = weightSum(); + Utils.QL_REQUIRE(sampleWeight > 0, () => "empty sample set"); + + sort(); + + double integral = 0, target = percent * sampleWeight; + int pos = samples_.Count(x => { integral += x.Value; return integral < target; }); + return samples_[pos].Key; + } + + /*! \f$ y \f$-th top percentile, defined as the value + \pre \f$ y \f$ must be in the range \f$ (0-1]. \f$ + */ + public double topPercentile(double percent) + { + Utils.QL_REQUIRE(percent > 0.0 && percent <= 1.0, () => "percentile (" + percent + ") must be in (0.0, 1.0]"); + + double sampleWeight = weightSum(); + Utils.QL_REQUIRE(sampleWeight > 0, () => "empty sample set"); + + sort(); + + double integral = 0, target = 1 - percent * sampleWeight; + int pos = samples_.Count(x => { integral += x.Value; return integral < target; }); + return samples_[pos].Key; + } + + //! adds a sequence of data to the set, with default weight + public void addSequence(List list) + { + foreach (double v in list) + add + (v, 1); + } + //! adds a sequence of data to the set, each with its weight + public void addSequence(List data, List weight) + { + for (int i = 0; i < data.Count; i++) + add + (data[i], weight[i]); + } + } +} diff --git a/src/QLNet/Math/statistics/IncrementalStatistics.cs b/src/QLNet/Math/statistics/IncrementalStatistics.cs new file mode 100644 index 000000000..3507faf1f --- /dev/null +++ b/src/QLNet/Math/statistics/IncrementalStatistics.cs @@ -0,0 +1,253 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + //! Statistics tool based on incremental accumulation + /*! It can accumulate a set of data and return statistics (e.g: mean, + variance, skewness, kurtosis, error estimation, etc.) + + \warning high moments are numerically unstable for high + average/standardDeviation ratios. + */ + public class IncrementalStatistics : IGeneralStatistics + { + protected int sampleNumber_, downsideSampleNumber_; + protected double sampleWeight_, downsideSampleWeight_; + protected double sum_, quadraticSum_, downsideQuadraticSum_, cubicSum_, fourthPowerSum_; + protected double min_, max_; + + public IncrementalStatistics() { reset(); } + + #region required IGeneralStatistics methods not supported by this class + public KeyValuePair expectationValue(Func, double> f, + Func, bool> inRange) + { + throw new NotSupportedException(); + } + public double percentile(double percent) { throw new NotSupportedException(); } + #endregion + + //! number of samples collected + public int samples() { return sampleNumber_; } + + //! sum of data weights + public double weightSum() { return sampleWeight_; } + + /*! returns the mean, defined as + \f[ \langle x \rangle = \frac{\sum w_i x_i}{\sum w_i}. \f] + */ + public double mean() + { + Utils.QL_REQUIRE(sampleWeight_ > 0.0, () => "sampleWeight_=0, insufficient"); + return sum_ / sampleWeight_; + } + + /*! returns the variance, defined as + \f[ \frac{N}{N-1} \left\langle \left( + x-\langle x \rangle \right)^2 \right\rangle. \f] + */ + public double variance() + { + Utils.QL_REQUIRE(sampleWeight_ > 0.0, () => "sampleWeight_=0, insufficient"); + Utils.QL_REQUIRE(sampleNumber_ > 1, () => "sample number <=1, insufficient"); + + double m = mean(); + double v = quadraticSum_ / sampleWeight_; + v -= m * m; + v *= sampleNumber_ / (sampleNumber_ - 1.0); + + Utils.QL_REQUIRE(v >= 0.0, () => "negative variance (" + v + ")"); + return v; + } + + /*! returns the standard deviation \f$ \sigma \f$, defined as the square root of the variance. */ + public double standardDeviation() { return Math.Sqrt(variance()); } + + /*! returns the downside variance + */ + public double downsideVariance() + { + if (downsideSampleWeight_.IsEqual(0.0)) + { + Utils.QL_REQUIRE(sampleWeight_ > 0.0, () => "sampleWeight_=0, insufficient"); + return 0.0; + } + + Utils.QL_REQUIRE(downsideSampleNumber_ > 1, () => "sample number below zero <=1, insufficient"); + return (downsideSampleNumber_ / (downsideSampleNumber_ - 1.0)) * + (downsideQuadraticSum_ / downsideSampleWeight_); + } + + + /*! returns the error estimate \f$ \epsilon \f$, defined as the + * square root of the ratio of the variance to the number of samples. */ + public double errorEstimate() + { + double var = variance(); + Utils.QL_REQUIRE(samples() > 0, () => "empty sample set"); + return Math.Sqrt(var / samples()); + } + + /*! returns the skewness, defined as + \f[ \frac{N^2}{(N-1)(N-2)} \frac{\left\langle \left( + x-\langle x \rangle \right)^3 \right\rangle}{\sigma^3}. \f] + The above evaluates to 0 for a Gaussian distribution. + */ + public double skewness() + { + Utils.QL_REQUIRE(sampleNumber_ > 2, () => "sample number <=2, insufficient"); + + double s = standardDeviation(); + if (s.IsEqual(0.0)) + return 0.0; + + double m = mean(); + double result = cubicSum_ / sampleWeight_; + result -= 3.0 * m * (quadraticSum_ / sampleWeight_); + result += 2.0 * m * m * m; + result /= s * s * s; + result *= sampleNumber_ / (sampleNumber_ - 1.0); + result *= sampleNumber_ / (sampleNumber_ - 2.0); + return result; + } + + /*! returns the excess kurtosis + The above evaluates to 0 for a Gaussian distribution. + */ + public double kurtosis() + { + Utils.QL_REQUIRE(sampleNumber_ > 3, () => "sample number <=3, insufficient"); + + double m = mean(); + double v = variance(); + + double c = (sampleNumber_ - 1.0) / (sampleNumber_ - 2.0); + c *= (sampleNumber_ - 1.0) / (sampleNumber_ - 3.0); + c *= 3.0; + + if (v.IsEqual(0.0)) + return c; + + double result = fourthPowerSum_ / sampleWeight_; + result -= 4.0 * m * (cubicSum_ / sampleWeight_); + result += 6.0 * m * m * (quadraticSum_ / sampleWeight_); + result -= 3.0 * m * m * m * m; + result /= v * v; + result *= sampleNumber_ / (sampleNumber_ - 1.0); + result *= sampleNumber_ / (sampleNumber_ - 2.0); + result *= (sampleNumber_ + 1.0) / (sampleNumber_ - 3.0); + + return result - c; + } + + /*! returns the minimum sample value */ + public double min() + { + Utils.QL_REQUIRE(samples() > 0, () => "empty sample set"); + return min_; + } + + /*! returns the maximum sample value */ + public double max() + { + Utils.QL_REQUIRE(samples() > 0, () => "empty sample set"); + return max_; + } + + /*! returns the downside deviation, defined as the square root of the downside variance. */ + public double downsideDeviation() { return Math.Sqrt(downsideVariance()); } + + + // Modifiers + //! adds a datum to the set, possibly with a weight + /*! \pre weight must be positive or null */ + public void add + (double value) { add(value, 1); } + public void add + (double value, double weight) + { + Utils.QL_REQUIRE(weight >= 0.0, () => "negative weight (" + weight + ") not allowed"); + + int oldSamples = sampleNumber_; + sampleNumber_++; + Utils.QL_REQUIRE(sampleNumber_ > oldSamples, () => "maximum number of samples reached"); + + sampleWeight_ += weight; + + double temp = weight * value; + sum_ += temp; + temp *= value; + quadraticSum_ += temp; + if (value < 0.0) + { + downsideQuadraticSum_ += temp; + downsideSampleNumber_++; + downsideSampleWeight_ += weight; + } + temp *= value; + cubicSum_ += temp; + temp *= value; + fourthPowerSum_ += temp; + if (oldSamples == 0) + { + min_ = max_ = value; + } + else + { + min_ = Math.Min(value, min_); + max_ = Math.Max(value, max_); + } + } + + //! resets the data to a null set + public void reset() + { + min_ = double.MaxValue; + max_ = double.MinValue; + sampleNumber_ = 0; + downsideSampleNumber_ = 0; + sampleWeight_ = 0.0; + downsideSampleWeight_ = 0.0; + sum_ = 0.0; + quadraticSum_ = 0.0; + downsideQuadraticSum_ = 0.0; + cubicSum_ = 0.0; + fourthPowerSum_ = 0.0; + } + + //! adds a sequence of data to the set, with default weight + public void addSequence(List list) + { + foreach (double v in list) + add + (v, 1); + } + //! adds a sequence of data to the set, each with its weight + /*! \pre weights must be positive or null */ + public void addSequence(List data, List weight) + { + for (int i = 0; i < data.Count; i++) + add + (data[i], weight[i]); + } + } +} diff --git a/src/QLNet/Math/statistics/RiskStatistics.cs b/src/QLNet/Math/statistics/RiskStatistics.cs new file mode 100644 index 000000000..de6762f73 --- /dev/null +++ b/src/QLNet/Math/statistics/RiskStatistics.cs @@ -0,0 +1,194 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + //! empirical-distribution risk measures + /*! This class wraps a somewhat generic statistic tool and adds + a number of risk measures (e.g.: value-at-risk, expected + shortfall, etc.) based on the data distribution as reported by + the underlying statistic tool. + + \todo add historical annualized volatility + */ + public class GenericRiskStatistics : IGeneralStatistics where Stat : IGeneralStatistics, new () + { + + #region wrap-up Stat + protected Stat impl_ = FastActivator.Create(); + + public int samples() { return impl_.samples(); } + public double mean() { return impl_.mean(); } + public double min() { return impl_.min(); } + public double max() { return impl_.max(); } + public double standardDeviation() { return impl_.standardDeviation(); } + public double variance() { return impl_.variance(); } + public double skewness() { return impl_.skewness(); } + public double kurtosis() { return impl_.kurtosis(); } + public double percentile(double percent) { return impl_.percentile(percent); } + public double weightSum() { return impl_.weightSum(); } + public double errorEstimate() { return impl_.errorEstimate(); } + + public void reset() { impl_.reset(); } + public void add + (double value, double weight) { impl_.add(value, weight); } + public void addSequence(List data, List weight) { impl_.addSequence(data, weight); } + + public KeyValuePair expectationValue(Func, double> f, + Func, bool> inRange) + { + return impl_.expectationValue(f, inRange); + } + #endregion + + + /*! returns the variance of observations below the mean, + See Markowitz (1959). + */ + public double semiVariance() { return regret(this.mean()); } + + /*! returns the semi deviation, defined as the square root of the semi variance. */ + public double semiDeviation() { return Math.Sqrt(semiVariance()); } + + // returns the variance of observations below 0.0, + public double downsideVariance() { return regret(0.0); } + + /*! returns the downside deviation, defined as the square root of the downside variance. */ + public double downsideDeviation() { return Math.Sqrt(downsideVariance()); } + + /*! returns the variance of observations below target, + See Dembo and Freeman, "The Rules Of Risk", Wiley (2001). + */ + public double regret(double target) + { + // average over the range below the target + KeyValuePair result = expectationValue(z => Math.Pow(z.Key - target, 2), + z => z.Key < target); + double x = result.Key; + int N = result.Value; + Utils.QL_REQUIRE(N > 1, () => "samples under target <= 1, unsufficient"); + return (N / (N - 1.0)) * x; + } + + //! potential upside (the reciprocal of VAR) at a given percentile + public double potentialUpside(double centile) + { + Utils.QL_REQUIRE(centile < 1.0 && centile >= 0.9, () => "percentile (" + centile + ") out of range [0.9, 1)"); + + // potential upside must be a gain, i.e., floored at 0.0 + return Math.Max(percentile(centile), 0.0); + } + + //! value-at-risk at a given percentile + public double valueAtRisk(double centile) + { + Utils.QL_REQUIRE(centile < 1.0 && centile >= 0.9, () => "percentile (" + centile + ") out of range [0.9, 1)"); + + // must be a loss, i.e., capped at 0.0 and negated + return -Math.Min(percentile(1.0 - centile), 0.0); + } + + //! expected shortfall at a given percentile + /*! returns the expected loss in case that the loss exceeded + a VaR threshold, + + that is the average of observations below the + given percentile \f$ p \f$. + Also know as conditional value-at-risk. + + See Artzner, Delbaen, Eber and Heath, + "Coherent measures of risk", Mathematical Finance 9 (1999) + */ + public double expectedShortfall(double centile) + { + Utils.QL_REQUIRE(centile < 1.0 && centile >= 0.9, () => "percentile (" + centile + ") out of range [0.9, 1)"); + + Utils.QL_REQUIRE(samples() != 0, () => "empty sample set"); + + double target = -valueAtRisk(centile); + KeyValuePair result = expectationValue(z => z.Key, z => z.Key < target); + double x = result.Key; + int N = result.Value; + Utils.QL_REQUIRE(N != 0, () => "no data below the target"); + // must be a loss, i.e., capped at 0.0 and negated + return -Math.Min(x, 0.0); + } + + // probability of missing the given target + public double shortfall(double target) + { + Utils.QL_REQUIRE(samples() != 0, () => "empty sample set"); + return expectationValue(x => x.Key < target ? 1 : 0, x => true).Key; + } + + // averaged shortfallness + public double averageShortfall(double target) + { + KeyValuePair result = expectationValue(z => target - z.Key, z => z.Key < target); + double x = result.Key; + int N = result.Value; + Utils.QL_REQUIRE(N != 0, () => "no data below the target"); + return x; + } + } + + //! default risk measures tool + /*! \test the correctness of the returned values is tested by checking them against numerical calculations. */ + public class RiskStatistics : GenericRiskStatistics + { + public double gaussianPercentile(double value) + { + return impl_.gaussianPercentile(value); + } + public double gaussianPotentialUpside(double value) + { + return impl_.gaussianPotentialUpside(value); + } + public double gaussianValueAtRisk(double value) + { + return impl_.gaussianValueAtRisk(value); + } + public double gaussianExpectedShortfall(double value) + { + return impl_.gaussianExpectedShortfall(value); + } + public double gaussianShortfall(double value) + { + return impl_.gaussianShortfall(value); + } + public double gaussianAverageShortfall(double value) + { + return impl_.gaussianAverageShortfall(value); + } + public double gaussianRegret(double value) + { + return impl_.gaussianRegret(value); + } + public double gaussianDownsideVariance() + { + return impl_.gaussianDownsideVariance(); + } + } + + //! default statistics tool + /*! \test the correctness of the returned values is tested by checking them against numerical calculations. */ + public class Statistics : RiskStatistics { } +} diff --git a/src/QLNet/Math/statistics/SequenceStatistics.cs b/src/QLNet/Math/statistics/SequenceStatistics.cs new file mode 100644 index 000000000..30a2cc2ae --- /dev/null +++ b/src/QLNet/Math/statistics/SequenceStatistics.cs @@ -0,0 +1,269 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace QLNet +{ + //! Statistics analysis of N-dimensional (sequence) data + /*! It provides 1-dimensional statistics as discrepancy plus + N-dimensional (sequence) statistics (e.g. mean, + variance, skewness, kurtosis, etc.) with one component for each + dimension of the sample space. + + For most of the statistics this class relies on + the StatisticsType underlying class to provide 1-D methods that + will be iterated for all the components of the N-D data. These + lifted methods are the union of all the methods that might be + requested to the 1-D underlying StatisticsType class, with the + usual compile-time checks provided by the template approach. + + \test the correctness of the returned values is tested by + checking them against numerical calculations. + */ + public class GenericSequenceStatistics where S : IGeneralStatistics, new () + { + protected int dimension_; + public int size() { return dimension_; } + + protected List stats_; + protected List results_; + protected Matrix quadraticSum_; + + public GenericSequenceStatistics(int dimension) + { + dimension_ = 0; + reset(dimension); + } + + //! returns the covariance Matrix + public Matrix covariance() + { + double sampleWeight = weightSum(); + Utils.QL_REQUIRE(sampleWeight > 0.0, () => "sampleWeight=0, unsufficient"); + + double sampleNumber = samples(); + Utils.QL_REQUIRE(sampleNumber > 1.0, () => "sample number <=1, unsufficient"); + + List m = mean(); + double inv = 1.0 / sampleWeight; + + Matrix result = inv * quadraticSum_; + result -= Matrix.outerProduct(m, m); + + result *= (sampleNumber / (sampleNumber - 1.0)); + return result; + } + //! returns the correlation Matrix + public Matrix correlation() + { + Matrix correlation = covariance(); + Vector variances = correlation.diagonal(); + for (int i = 0; i < dimension_; i++) + { + for (int j = 0; j < dimension_; j++) + { + if (i == j) + { + if (variances[i].IsEqual(0.0)) + { + correlation[i, j] = 1.0; + } + else + { + correlation[i, j] *= 1.0 / Math.Sqrt(variances[i] * variances[j]); + } + } + else + { + if (variances[i].IsEqual(0.0) && variances[j].IsEqual(0.0)) + { + correlation[i, j] = 1.0; + } + else if (variances[i].IsEqual(0.0) || variances[j].IsEqual(0.0)) + { + correlation[i, j] = 0.0; + } + else + { + correlation[i, j] *= 1.0 / Math.Sqrt(variances[i] * variances[j]); + } + } + } // j for + } // i for + return correlation; + } + + // 1-D inspectors lifted from underlying statistics class + public int samples() { return (stats_.Count == 0) ? 0 : stats_[0].samples(); } + public double weightSum() { return (stats_.Count == 0) ? 0.0 : stats_[0].weightSum(); } + + // N-D inspectors lifted from underlying statistics class + // no argument list + private List noArg(string method) + { + // do not check for null - in this case we throw anyways + for (int i = 0; i < dimension_; i++) + { + MethodInfo methodInfo = Utils.GetMethodInfo(stats_[i], method); + results_[i] = (double)methodInfo.Invoke(stats_[i], new object[] { }); + } + return results_; + } + // single argument list + private List singleArg(double x, string method) + { + // do not check for null - in this case we throw anyways + for (int i = 0; i < dimension_; i++) + { + MethodInfo methodInfo = Utils.GetMethodInfo(stats_[i], method); + results_[i] = (double)methodInfo.Invoke(stats_[i], new object[] { x }); + } + return results_; + } + + // void argument list + public List mean() + { + for (int i = 0; i < dimension_; i++) + results_[i] = stats_[i].mean(); + return results_; + } + public List variance() + { + for (int i = 0; i < dimension_; i++) + results_[i] = stats_[i].variance(); + return results_; + } + public List standardDeviation() + { + for (int i = 0; i < dimension_; i++) + results_[i] = stats_[i].standardDeviation(); + return results_; + } + public List downsideVariance() { return noArg("downsideVariance"); } + public List downsideDeviation() { return noArg("downsideDeviation"); } + public List semiVariance() { return noArg("semiVariance"); } + public List semiDeviation() { return noArg("semiDeviation"); } + public List errorEstimate() { return noArg("errorEstimate"); } + public List skewness() + { + for (int i = 0; i < dimension_; i++) + results_[i] = stats_[i].skewness(); + return results_; + } + public List kurtosis() + { + for (int i = 0; i < dimension_; i++) + results_[i] = stats_[i].kurtosis(); + return results_; + } + public List min() + { + for (int i = 0; i < dimension_; i++) + results_[i] = stats_[i].min(); + return results_; + } + public List max() + { + for (int i = 0; i < dimension_; i++) + results_[i] = stats_[i].max(); + return results_; + } + + // single argument list + public List gaussianPercentile(double x) { return singleArg(x, "gaussianPercentile"); } + public List percentile(double x) + { + for (int i = 0; i < dimension_; i++) + results_[i] = stats_[i].percentile(x); + return results_; + } + public List gaussianPotentialUpside(double x) { return singleArg(x, "gaussianPotentialUpside"); } + public List potentialUpside(double x) { return singleArg(x, "potentialUpside"); } + public List gaussianValueAtRisk(double x) { return singleArg(x, "gaussianValueAtRisk"); } + public List valueAtRisk(double x) { return singleArg(x, "valueAtRisk"); } + public List gaussianExpectedShortfall(double x) { return singleArg(x, "gaussianExpectedShortfall"); } + public List expectedShortfall(double x) { return singleArg(x, "expectedShortfall"); } + public List gaussianShortfall(double x) { return singleArg(x, "gaussianShortfall"); } + public List shortfall(double x) { return singleArg(x, "shortfall"); } + public List gaussianAverageShortfall(double x) { return singleArg(x, "gaussianAverageShortfall"); } + public List averageShortfall(double x) { return singleArg(x, "averageShortfall"); } + public List regret(double x) { return singleArg(x, "regret"); } + + + // Modifiers + public virtual void reset(int dimension) + { + // (re-)initialize + if (dimension > 0) + { + if (dimension == dimension_) + { + for (int i = 0; i < dimension_; ++i) + stats_[i].reset(); + } + else + { + dimension_ = dimension; + stats_ = new InitializedList(dimension); + results_ = new InitializedList(dimension); + } + quadraticSum_ = new Matrix(dimension_, dimension_, 0.0); + } + else + { + dimension_ = dimension; + } + } + + public virtual void add + (List begin) { add(begin, 1); } + + public virtual void add + (List begin, double weight) + { + if (dimension_ == 0) + { + // stat wasn't initialized yet + int dimension = begin.Count; + Utils.QL_REQUIRE(dimension > 0, () => "sample error: end<=begin"); + reset(dimension); + } + + Utils.QL_REQUIRE(begin.Count == dimension_, () => + "sample size mismatch: " + dimension_ + " required, " + begin.Count + " provided"); + + quadraticSum_ += weight * Matrix.outerProduct(begin, begin); + + for (int i = 0; i < dimension_; ++i) + stats_[i].add(begin[i], weight); + } + } + + //! default multi-dimensional statistics tool + /*! \test the correctness of the returned values is tested by + checking them against numerical calculations. + */ + public class SequenceStatistics : GenericSequenceStatistics + { + public SequenceStatistics(int dimension) : base(dimension) { } + } +} diff --git a/src/QLNet/Math/statistics/convergencestatistics.cs b/src/QLNet/Math/statistics/convergencestatistics.cs deleted file mode 100644 index 9f6752d1c..000000000 --- a/src/QLNet/Math/statistics/convergencestatistics.cs +++ /dev/null @@ -1,129 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet { - public interface IConvergenceSteps { - int initialSamples(); - int nextSamples(int current); - } - - public class DoublingConvergenceSteps : IConvergenceSteps { - - public int initialSamples() { return 1; } - public int nextSamples(int current) { return 2 * current + 1; } - } - - //! statistics class with convergence table - /*! This class decorates another statistics class adding a - convergence table calculation. The table tracks the - convergence of the mean. - - It is possible to specify the number of samples at which the - mean should be stored by mean of the second template - parameter; the default is to store \f$ 2^{n-1} \f$ samples at - the \f$ n \f$-th step. Any passed class must implement the - following interface: - \code - Size initialSamples() const - Size nextSamples(Size currentSamples) const - \endcode - as well as a copy constructor. - - \test results are tested against known good values. - */ - public class ConvergenceStatistics : ConvergenceStatistics - where T : IGeneralStatistics, new() { - public ConvergenceStatistics(T stats, DoublingConvergenceSteps rule) : base(stats, rule) { } - public ConvergenceStatistics() : base(new DoublingConvergenceSteps()) { } - public ConvergenceStatistics(DoublingConvergenceSteps rule) : base(rule) { } - } - - public class ConvergenceStatistics : IGeneralStatistics - where T : IGeneralStatistics, new() - where U : IConvergenceSteps, new() { - - private List> table_ = new List>(); - public List>convergenceTable() { return table_; } - - private U samplingRule_; - private int nextSampleSize_; - - public ConvergenceStatistics(T stats, U rule) { - impl_ = stats; - samplingRule_ = rule; - - reset(); - } - - public ConvergenceStatistics() : this(FastActivator.Create()) { } - public ConvergenceStatistics(U rule) { - samplingRule_ = rule; - reset(); - } - - public void reset() { - impl_.reset(); - nextSampleSize_ = samplingRule_.initialSamples(); - table_.Clear(); - } - - public void add(double value) { add(value, 1); } - public void add(double value, double weight) { - impl_.add(value, weight); - if (samples() == nextSampleSize_) { - table_.Add(new KeyValuePair(samples(), mean())); - nextSampleSize_ = samplingRule_.nextSamples(nextSampleSize_); - } - } - - //! adds a sequence of data to the set, with default weight - public void addSequence(List list) { - foreach(double v in list) - add(v, 1); - } - //! adds a sequence of data to the set, each with its weight - public void addSequence(List data, List weight) { - for(int i=0; i< data.Count; i++) - add(data[i], weight[i]); - } - - #region wrap-up Stat - protected T impl_ = FastActivator.Create(); - - public int samples() { return impl_.samples(); } - public double mean() { return impl_.mean(); } - public double min() { return impl_.min(); } - public double max() { return impl_.max(); } - public double standardDeviation() { return impl_.standardDeviation(); } - public double variance() { return impl_.variance(); } - public double skewness() { return impl_.skewness(); } - public double kurtosis() { return impl_.kurtosis(); } - public double percentile(double percent) { return impl_.percentile(percent); } - public double weightSum() { return impl_.weightSum(); } - public double errorEstimate() { return impl_.errorEstimate(); } - - public KeyValuePair expectationValue(Func, double> f, - Func, bool> inRange) { - return impl_.expectationValue(f, inRange); - } - #endregion - } -} diff --git a/src/QLNet/Math/statistics/gaussianstatistics.cs b/src/QLNet/Math/statistics/gaussianstatistics.cs deleted file mode 100644 index f3874185c..000000000 --- a/src/QLNet/Math/statistics/gaussianstatistics.cs +++ /dev/null @@ -1,197 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet { - //! Statistics tool for gaussian-assumption risk measures - /*! This class wraps a somewhat generic statistic tool and adds - a number of gaussian risk measures (e.g.: value-at-risk, expected - shortfall, etc.) based on the mean and variance provided by - the underlying statistic tool. - */ - public class GenericGaussianStatistics : IGeneralStatistics where Stat : IGeneralStatistics, new() { - public GenericGaussianStatistics() { } - public GenericGaussianStatistics(Stat s) { - impl_ = s; - } - - #region wrap-up Stat - protected Stat impl_ = FastActivator.Create(); - - public int samples() { return impl_.samples(); } - public double mean() { return impl_.mean(); } - public double min() { return impl_.min(); } - public double max() { return impl_.max(); } - public double standardDeviation() { return impl_.standardDeviation(); } - public double variance() { return impl_.variance(); } - public double skewness() { return impl_.skewness(); } - public double kurtosis() { return impl_.kurtosis(); } - public double percentile(double percent) { return impl_.percentile(percent); } - public double weightSum() { return impl_.weightSum(); } - public double errorEstimate() { return impl_.errorEstimate(); } - - public void reset() { impl_.reset(); } - public void add(double value, double weight) { impl_.add(value, weight); } - public void addSequence(List data, List weight) { impl_.addSequence(data, weight); } - - public KeyValuePair expectationValue(Func, double> f, - Func, bool> inRange) { - return impl_.expectationValue(f, inRange); - } - #endregion - - - // Gaussian risk measures - /*! returns the downside variance - */ - public double gaussianDownsideVariance() { return gaussianRegret(0.0); } - - /*! returns the downside deviation, defined as the square root of the downside variance. */ - public double gaussianDownsideDeviation() { return Math.Sqrt(gaussianDownsideVariance()); } - - /*! returns the variance of observations below target - See Dembo, Freeman "The Rules Of Risk", Wiley (2001) - */ - public double gaussianRegret(double target) { - double m = this.mean(); - double std = this.standardDeviation(); - double variance = std*std; - CumulativeNormalDistribution gIntegral = new CumulativeNormalDistribution(m, std); - NormalDistribution g = new NormalDistribution(m, std); - double firstTerm = variance + m*m - 2.0*target*m + target*target; - double alfa = gIntegral.value(target); - double secondTerm = m - target; - double beta = variance * g.value(target); - double result = alfa*firstTerm - beta*secondTerm; - return result/alfa; - } - - /*! gaussian-assumption y-th percentile - */ - /*! \pre percentile must be in range (0%-100%) extremes excluded */ - public double gaussianPercentile(double percentile) { - Utils.QL_REQUIRE(percentile > 0.0 && percentile < 1.0,()=> "percentile (" + percentile + ") must be in (0.0, 1.0)"); - - InverseCumulativeNormal gInverse = new InverseCumulativeNormal(mean(), standardDeviation()); - return gInverse.value(percentile); - } - public double gaussianTopPercentile(double percentile) { return gaussianPercentile(1.0 - percentile); } - - //! gaussian-assumption Potential-Upside at a given percentile - public double gaussianPotentialUpside(double percentile) { - Utils.QL_REQUIRE(percentile<1.0 && percentile>=0.9,()=> "percentile (" + percentile + ") out of range [0.9, 1)"); - - double result = gaussianPercentile(percentile); - // potential upside must be a gain, i.e., floored at 0.0 - return Math.Max(result, 0.0); - } - - //! gaussian-assumption Value-At-Risk at a given percentile - public double gaussianValueAtRisk(double percentile) { - Utils.QL_REQUIRE(percentile<1.0 && percentile>=0.9,()=> "percentile (" + percentile + ") out of range [0.9, 1)"); - - double result = gaussianPercentile(1.0-percentile); - // VAR must be a loss - // this means that it has to be MIN(dist(1.0-percentile), 0.0) - // VAR must also be a positive quantity, so -MIN(*) - return -Math.Min(result, 0.0); - } - - //! gaussian-assumption Expected Shortfall at a given percentile - /*! Assuming a gaussian distribution it - returns the expected loss in case that the loss exceeded - a VaR threshold, - - that is the average of observations below the - given percentile \f$ p \f$. - Also know as conditional value-at-risk. - - See Artzner, Delbaen, Eber and Heath, - "Coherent measures of risk", Mathematical Finance 9 (1999) - */ - public double gaussianExpectedShortfall(double percentile) { - Utils.QL_REQUIRE(percentile<1.0 && percentile>=0.9,()=> "percentile (" + percentile + ") out of range [0.9, 1)"); - - double m = this.mean(); - double std = this.standardDeviation(); - InverseCumulativeNormal gInverse = new InverseCumulativeNormal(m, std); - double var = gInverse.value(1.0 - percentile); - NormalDistribution g = new NormalDistribution(m, std); - double result = m - std * std * g.value(var) / (1.0 - percentile); - // expectedShortfall must be a loss - // this means that it has to be MIN(result, 0.0) - // expectedShortfall must also be a positive quantity, so -MIN(*) - return -Math.Min(result, 0.0); - } - - //! gaussian-assumption Shortfall (observations below target) - public double gaussianShortfall(double target) { - CumulativeNormalDistribution gIntegral = new CumulativeNormalDistribution(this.mean(), this.standardDeviation()); - return gIntegral.value(target); - } - - //! gaussian-assumption Average Shortfall (averaged shortfallness) - public double gaussianAverageShortfall(double target) { - double m = this.mean(); - double std = this.standardDeviation(); - CumulativeNormalDistribution gIntegral = new CumulativeNormalDistribution(m, std); - NormalDistribution g = new NormalDistribution(m, std); - return ((target - m) + std * std * g.value(target) / gIntegral.value(target)); - } - } - - //! default gaussian statistic tool - public class GaussianStatistics : GenericGaussianStatistics { } - - - //! Helper class for precomputed distributions - public class StatsHolder : IGeneralStatistics { - private double mean_, standardDeviation_; - public double mean() { return mean_; } - public double standardDeviation() { return standardDeviation_; } - - public StatsHolder() { } // required for generics - public StatsHolder(double mean, double standardDeviation) { - mean_ = mean; - standardDeviation_ = standardDeviation; - } - - #region IGeneralStatistics - public int samples() { throw new NotSupportedException(); } - public double min() { throw new NotSupportedException(); } - public double max() { throw new NotSupportedException(); } - public double variance() { throw new NotSupportedException(); } - public double skewness() { throw new NotSupportedException(); } - public double kurtosis() { throw new NotSupportedException(); } - public double percentile(double percent) { throw new NotSupportedException(); } - public double weightSum() { throw new NotSupportedException(); } - public double errorEstimate() { throw new NotSupportedException(); } - - public void reset() { throw new NotSupportedException(); } - public void add(double value, double weight) { throw new NotSupportedException(); } - public void addSequence(List data, List weight) { throw new NotSupportedException(); } - - public KeyValuePair expectationValue(Func, double> f, - Func, bool> inRange) { - throw new NotSupportedException(); - } - #endregion - } -} diff --git a/src/QLNet/Math/statistics/generalstatistics.cs b/src/QLNet/Math/statistics/generalstatistics.cs deleted file mode 100644 index 7ce555467..000000000 --- a/src/QLNet/Math/statistics/generalstatistics.cs +++ /dev/null @@ -1,254 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace QLNet { - public interface IGeneralStatistics { - int samples(); - double mean(); - double min(); - double max(); - double standardDeviation(); - double variance(); - double skewness(); - double kurtosis(); - double percentile(double percent); - double weightSum(); - double errorEstimate(); - - void reset(); - void add(double value, double weight); - void addSequence(List data, List weight); - - KeyValuePair expectationValue(Func, double> f, - Func, bool> inRange); - } - - //! Statistics tool - /*! This class accumulates a set of data and returns their - statistics (e.g: mean, variance, skewness, kurtosis, - error estimation, percentile, etc.) based on the empirical - distribution (no gaussian assumption) - - It doesn't suffer the numerical instability problem of - IncrementalStatistics. The downside is that it stores all - samples, thus increasing the memory requirements. - */ - public class GeneralStatistics : IGeneralStatistics { - private List> samples_; - //! number of samples collected - public int samples() { return samples_.Count; } - //! collected data - public List> data() { return samples_; } - - private bool sorted_; - private double? mean_ = null, weightSum_ = null, variance_ = null, skewness_ = null, kurtosis_ = null; - - - public GeneralStatistics() { reset(); } - - - /*! returns the error estimate on the mean value, defined as - \f$ \epsilon = \sigma/\sqrt{N}. \f$ */ - public double errorEstimate() { return Math.Sqrt(variance()/samples()); } - - /*! returns the minimum sample value */ - public double min() { - Utils.QL_REQUIRE(samples() > 0,()=> "empty sample set"); - return samples_.Min(x => x.Key); - } - - /*! returns the maximum sample value */ - public double max() { - Utils.QL_REQUIRE(samples() > 0,()=> "empty sample set"); - return samples_.Max(x => x.Key); - } - - - //! adds a datum to the set, possibly with a weight - public void add(double value) { add(value, 1); } - public void add(double value, double weight) { - Utils.QL_REQUIRE(weight>=0.0,()=> "negative weight not allowed"); - samples_.Add(new KeyValuePair(value,weight)); - - sorted_ = false; - mean_ = weightSum_ = variance_ = skewness_ = kurtosis_ = null; - } - - //! resets the data to a null set - public void reset(){ - samples_ = new List>(); - - sorted_ = true; - mean_ = weightSum_ = variance_ = skewness_ = kurtosis_ = null; - } - - //! sort the data set in increasing order - public void sort() { - if (!sorted_) { - samples_.Sort((x, y) => x.Key.CompareTo(y.Key)); - sorted_ = true; - } - } - - - //! sum of data weights - public double weightSum() { - if (weightSum_ == null) - weightSum_ = samples_.Sum>(x => x.Value); - return weightSum_.GetValueOrDefault(); - } - - /*! returns the mean, defined as - \f[ \langle x \rangle = \frac{\sum w_i x_i}{\sum w_i}. \f] */ - public double mean() { - if (mean_ == null) { - int N = samples(); - Utils.QL_REQUIRE(samples() > 0,()=> "empty sample set"); - // eat our own dog food - mean_ = expectationValue(x => x.Key * x.Value, x => true).Key; - } - return mean_.GetValueOrDefault(); - } - - /*! returns the standard deviation \f$ \sigma \f$, defined as the - square root of the variance. */ - public double standardDeviation() { return Math.Sqrt(variance()); } - - /*! returns the variance, defined as - \f[ \sigma^2 = \frac{N}{N-1} \left\langle \left( - x-\langle x \rangle \right)^2 \right\rangle. \f] */ - public double variance() { - if (variance_ == null) { - int N = samples(); - Utils.QL_REQUIRE(N > 1,()=> "sample number <=1, unsufficient"); - // Subtract the mean and square. Repeat on the whole range. - // Hopefully, the whole thing will be inlined in a single loop. - double s2 = expectationValue(x => Math.Pow(x.Key * x.Value - mean(), 2), x => true).Key; - variance_ = s2 * N / (N - 1.0); - } - return variance_.GetValueOrDefault(); - } - - /*! returns the skewness, defined as - \f[ \frac{N^2}{(N-1)(N-2)} \frac{\left\langle \left( - x-\langle x \rangle \right)^3 \right\rangle}{\sigma^3}. \f] - The above evaluates to 0 for a Gaussian distribution. - */ - public double skewness() { - if (skewness_ == null) { - int N = samples(); - Utils.QL_REQUIRE(N > 2,()=> "sample number <=2, unsufficient"); - - double x = expectationValue(y => Math.Pow(y.Key * y.Value - mean(), 3), y => true).Key; - double sigma = standardDeviation(); - - skewness_ = (x / Math.Pow(sigma, 3)) * (N / (N - 1.0)) * (N / (N - 2.0)); - } - return skewness_.GetValueOrDefault(); - } - - /*! returns the excess kurtosis - The above evaluates to 0 for a Gaussian distribution. - */ - public double kurtosis() { - if (kurtosis_ == null) { - int N = samples(); - Utils.QL_REQUIRE(N > 3,()=> "sample number <=3, unsufficient"); - - double x = expectationValue(y => Math.Pow(y.Key * y.Value - mean(), 4), y => true).Key; - double sigma2 = variance(); - - double c1 = (N / (N - 1.0)) * (N / (N - 2.0)) * ((N + 1.0) / (N - 3.0)); - double c2 = 3.0 * ((N - 1.0) / (N - 2.0)) * ((N - 1.0) / (N - 3.0)); - - kurtosis_ = c1 * (x / (sigma2 * sigma2)) - c2; - } - return kurtosis_.GetValueOrDefault(); - } - - /*! Expectation value of a function \f$ f \f$ on a given range \f$ \mathcal{R} \f$, i.e., - - The range is passed as a boolean function returning - true if the argument belongs to the range - or false otherwise. - - The function returns a pair made of the result and the number of observations in the given range. */ - public KeyValuePair expectationValue(Func, double> f, - Func, bool> inRange) { - double num = 0.0, den = 0.0; - int N = 0; - - foreach(KeyValuePair x in samples_.Where>(x => inRange(x))) { - num += f(x)*x.Value; - den += x.Value; - N += 1; - } - - if (N == 0) return new KeyValuePair(0,0); - return new KeyValuePair(num/den,N); - } - - /*! \f$ y \f$-th percentile, defined as the value \f$ \bar{x} \f$ - \pre \f$ y \f$ must be in the range \f$ (0-1]. \f$ - */ - public double percentile(double percent) { - - Utils.QL_REQUIRE(percent > 0.0 && percent <= 1.0,()=> "percentile (" + percent + ") must be in (0.0, 1.0]"); - - double sampleWeight = weightSum(); - Utils.QL_REQUIRE(sampleWeight > 0,()=> "empty sample set"); - - sort(); - - double integral = 0, target = percent*sampleWeight; - int pos = samples_.Count(x => { integral += x.Value; return integral < target; } ); - return samples_[pos].Key; - } - - /*! \f$ y \f$-th top percentile, defined as the value - \pre \f$ y \f$ must be in the range \f$ (0-1]. \f$ - */ - public double topPercentile(double percent) { - Utils.QL_REQUIRE(percent > 0.0 && percent <= 1.0,()=> "percentile (" + percent + ") must be in (0.0, 1.0]"); - - double sampleWeight = weightSum(); - Utils.QL_REQUIRE(sampleWeight > 0,()=> "empty sample set"); - - sort(); - - double integral = 0, target = 1 - percent*sampleWeight; - int pos = samples_.Count(x => { integral += x.Value; return integral < target; } ); - return samples_[pos].Key; - } - - //! adds a sequence of data to the set, with default weight - public void addSequence(List list) { - foreach(double v in list) - add(v, 1); - } - //! adds a sequence of data to the set, each with its weight - public void addSequence(List data, List weight) { - for(int i=0; i< data.Count; i++) - add(data[i], weight[i]); - } - } -} diff --git a/src/QLNet/Math/statistics/incrementalstatistics.cs b/src/QLNet/Math/statistics/incrementalstatistics.cs deleted file mode 100644 index cd216560c..000000000 --- a/src/QLNet/Math/statistics/incrementalstatistics.cs +++ /dev/null @@ -1,227 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet { - //! Statistics tool based on incremental accumulation - /*! It can accumulate a set of data and return statistics (e.g: mean, - variance, skewness, kurtosis, error estimation, etc.) - - \warning high moments are numerically unstable for high - average/standardDeviation ratios. - */ - public class IncrementalStatistics : IGeneralStatistics { - protected int sampleNumber_, downsideSampleNumber_; - protected double sampleWeight_, downsideSampleWeight_; - protected double sum_, quadraticSum_, downsideQuadraticSum_, cubicSum_, fourthPowerSum_; - protected double min_, max_; - - public IncrementalStatistics() { reset(); } - - #region required IGeneralStatistics methods not supported by this class - public KeyValuePair expectationValue(Func, double> f, - Func, bool> inRange) { - throw new NotSupportedException(); - } - public double percentile(double percent) { throw new NotSupportedException(); } - #endregion - - //! number of samples collected - public int samples() { return sampleNumber_; } - - //! sum of data weights - public double weightSum() { return sampleWeight_; } - - /*! returns the mean, defined as - \f[ \langle x \rangle = \frac{\sum w_i x_i}{\sum w_i}. \f] - */ - public double mean() { - Utils.QL_REQUIRE(sampleWeight_>0.0,()=> "sampleWeight_=0, insufficient"); - return sum_/sampleWeight_; - } - - /*! returns the variance, defined as - \f[ \frac{N}{N-1} \left\langle \left( - x-\langle x \rangle \right)^2 \right\rangle. \f] - */ - public double variance() { - Utils.QL_REQUIRE(sampleWeight_>0.0,()=> "sampleWeight_=0, insufficient"); - Utils.QL_REQUIRE(sampleNumber_>1,()=> "sample number <=1, insufficient"); - - double m = mean(); - double v = quadraticSum_/sampleWeight_; - v -= m*m; - v *= sampleNumber_/(sampleNumber_-1.0); - - Utils.QL_REQUIRE(v >= 0.0,()=> "negative variance (" + v + ")"); - return v; - } - - /*! returns the standard deviation \f$ \sigma \f$, defined as the square root of the variance. */ - public double standardDeviation() { return Math.Sqrt(variance()); } - - /*! returns the downside variance - */ - public double downsideVariance() { - if (downsideSampleWeight_.IsEqual(0.0)) { - Utils.QL_REQUIRE(sampleWeight_>0.0,()=> "sampleWeight_=0, insufficient"); - return 0.0; - } - - Utils.QL_REQUIRE(downsideSampleNumber_>1,()=> "sample number below zero <=1, insufficient"); - return (downsideSampleNumber_/(downsideSampleNumber_-1.0))* - (downsideQuadraticSum_ /downsideSampleWeight_); - } - - - /*! returns the error estimate \f$ \epsilon \f$, defined as the - * square root of the ratio of the variance to the number of samples. */ - public double errorEstimate() { - double var = variance(); - Utils.QL_REQUIRE(samples() > 0,()=> "empty sample set"); - return Math.Sqrt(var/samples()); - } - - /*! returns the skewness, defined as - \f[ \frac{N^2}{(N-1)(N-2)} \frac{\left\langle \left( - x-\langle x \rangle \right)^3 \right\rangle}{\sigma^3}. \f] - The above evaluates to 0 for a Gaussian distribution. - */ - public double skewness() { - Utils.QL_REQUIRE(sampleNumber_>2,()=> "sample number <=2, insufficient"); - - double s = standardDeviation(); - if (s.IsEqual(0.0)) return 0.0; - - double m = mean(); - double result = cubicSum_/sampleWeight_; - result -= 3.0*m*(quadraticSum_/sampleWeight_); - result += 2.0*m*m*m; - result /= s*s*s; - result *= sampleNumber_/(sampleNumber_-1.0); - result *= sampleNumber_/(sampleNumber_-2.0); - return result; - } - - /*! returns the excess kurtosis - The above evaluates to 0 for a Gaussian distribution. - */ - public double kurtosis() { - Utils.QL_REQUIRE(sampleNumber_>3,()=> "sample number <=3, insufficient"); - - double m = mean(); - double v = variance(); - - double c = (sampleNumber_-1.0)/(sampleNumber_-2.0); - c *= (sampleNumber_-1.0)/(sampleNumber_-3.0); - c *= 3.0; - - if (v.IsEqual(0.0)) return c; - - double result = fourthPowerSum_/sampleWeight_; - result -= 4.0*m*(cubicSum_/sampleWeight_); - result += 6.0*m*m*(quadraticSum_/sampleWeight_); - result -= 3.0*m*m*m*m; - result /= v*v; - result *= sampleNumber_/(sampleNumber_-1.0); - result *= sampleNumber_/(sampleNumber_-2.0); - result *= (sampleNumber_+1.0)/(sampleNumber_-3.0); - - return result-c; - } - - /*! returns the minimum sample value */ - public double min() { - Utils.QL_REQUIRE(samples() > 0,()=> "empty sample set"); - return min_; - } - - /*! returns the maximum sample value */ - public double max() { - Utils.QL_REQUIRE(samples() > 0,()=> "empty sample set"); - return max_; - } - - /*! returns the downside deviation, defined as the square root of the downside variance. */ - public double downsideDeviation() { return Math.Sqrt(downsideVariance()); } - - - // Modifiers - //! adds a datum to the set, possibly with a weight - /*! \pre weight must be positive or null */ - public void add(double value) { add(value, 1); } - public void add(double value, double weight) { - Utils.QL_REQUIRE(weight>=0.0,()=> "negative weight (" + weight + ") not allowed"); - - int oldSamples = sampleNumber_; - sampleNumber_++; - Utils.QL_REQUIRE(sampleNumber_ > oldSamples,()=> "maximum number of samples reached"); - - sampleWeight_ += weight; - - double temp = weight*value; - sum_ += temp; - temp *= value; - quadraticSum_ += temp; - if (value<0.0) { - downsideQuadraticSum_ += temp; - downsideSampleNumber_++; - downsideSampleWeight_ += weight; - } - temp *= value; - cubicSum_ += temp; - temp *= value; - fourthPowerSum_ += temp; - if (oldSamples == 0) { - min_ = max_ = value; - } else { - min_ = Math.Min(value, min_); - max_ = Math.Max(value, max_); - } - } - - //! resets the data to a null set - public void reset() { - min_ = double.MaxValue; - max_ = double.MinValue; - sampleNumber_ = 0; - downsideSampleNumber_ = 0; - sampleWeight_ = 0.0; - downsideSampleWeight_ = 0.0; - sum_ = 0.0; - quadraticSum_ = 0.0; - downsideQuadraticSum_ = 0.0; - cubicSum_ = 0.0; - fourthPowerSum_ = 0.0; - } - - //! adds a sequence of data to the set, with default weight - public void addSequence(List list) { - foreach (double v in list) - add(v, 1); - } - //! adds a sequence of data to the set, each with its weight - /*! \pre weights must be positive or null */ - public void addSequence(List data, List weight) { - for (int i = 0; i < data.Count; i++) - add(data[i], weight[i]); - } - } -} diff --git a/src/QLNet/Math/statistics/riskstatistics.cs b/src/QLNet/Math/statistics/riskstatistics.cs deleted file mode 100644 index 4977485f2..000000000 --- a/src/QLNet/Math/statistics/riskstatistics.cs +++ /dev/null @@ -1,175 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet { - //! empirical-distribution risk measures - /*! This class wraps a somewhat generic statistic tool and adds - a number of risk measures (e.g.: value-at-risk, expected - shortfall, etc.) based on the data distribution as reported by - the underlying statistic tool. - - \todo add historical annualized volatility - */ - public class GenericRiskStatistics : IGeneralStatistics where Stat : IGeneralStatistics, new() { - - #region wrap-up Stat - protected Stat impl_ = FastActivator.Create(); - - public int samples() { return impl_.samples(); } - public double mean() { return impl_.mean(); } - public double min() { return impl_.min(); } - public double max() { return impl_.max(); } - public double standardDeviation() { return impl_.standardDeviation(); } - public double variance() { return impl_.variance(); } - public double skewness() { return impl_.skewness(); } - public double kurtosis() { return impl_.kurtosis(); } - public double percentile(double percent) { return impl_.percentile(percent); } - public double weightSum() { return impl_.weightSum(); } - public double errorEstimate() { return impl_.errorEstimate(); } - - public void reset() { impl_.reset(); } - public void add(double value, double weight) { impl_.add(value, weight); } - public void addSequence(List data, List weight) { impl_.addSequence(data, weight); } - - public KeyValuePair expectationValue(Func, double> f, - Func, bool> inRange) { - return impl_.expectationValue(f, inRange); - } - #endregion - - - /*! returns the variance of observations below the mean, - See Markowitz (1959). - */ - public double semiVariance() { return regret(this.mean()); } - - /*! returns the semi deviation, defined as the square root of the semi variance. */ - public double semiDeviation() { return Math.Sqrt(semiVariance()); } - - // returns the variance of observations below 0.0, - public double downsideVariance() { return regret(0.0); } - - /*! returns the downside deviation, defined as the square root of the downside variance. */ - public double downsideDeviation() { return Math.Sqrt(downsideVariance()); } - - /*! returns the variance of observations below target, - See Dembo and Freeman, "The Rules Of Risk", Wiley (2001). - */ - public double regret(double target) { - // average over the range below the target - KeyValuePair result = expectationValue(z => Math.Pow(z.Key - target, 2), - z => z.Key < target); - double x = result.Key; - int N = result.Value; - Utils.QL_REQUIRE(N > 1,()=> "samples under target <= 1, unsufficient"); - return (N/(N-1.0))*x; - } - - //! potential upside (the reciprocal of VAR) at a given percentile - public double potentialUpside(double centile) { - Utils.QL_REQUIRE(centile < 1.0 && centile >= 0.9,()=> "percentile (" + centile + ") out of range [0.9, 1)"); - - // potential upside must be a gain, i.e., floored at 0.0 - return Math.Max(percentile(centile), 0.0); - } - - //! value-at-risk at a given percentile - public double valueAtRisk(double centile) { - Utils.QL_REQUIRE(centile < 1.0 && centile >= 0.9,()=> "percentile (" + centile + ") out of range [0.9, 1)"); - - // must be a loss, i.e., capped at 0.0 and negated - return -Math.Min(percentile(1.0 - centile), 0.0); - } - - //! expected shortfall at a given percentile - /*! returns the expected loss in case that the loss exceeded - a VaR threshold, - - that is the average of observations below the - given percentile \f$ p \f$. - Also know as conditional value-at-risk. - - See Artzner, Delbaen, Eber and Heath, - "Coherent measures of risk", Mathematical Finance 9 (1999) - */ - public double expectedShortfall(double centile) { - Utils.QL_REQUIRE(centile < 1.0 && centile >= 0.9,()=> "percentile (" + centile + ") out of range [0.9, 1)"); - - Utils.QL_REQUIRE(samples() != 0,()=> "empty sample set"); - - double target = -valueAtRisk(centile); - KeyValuePair result = expectationValue(z => z.Key, z => z.Key < target); - double x = result.Key; - int N = result.Value; - Utils.QL_REQUIRE(N != 0,()=> "no data below the target"); - // must be a loss, i.e., capped at 0.0 and negated - return -Math.Min(x, 0.0); - } - - // probability of missing the given target - public double shortfall(double target) { - Utils.QL_REQUIRE(samples() != 0,()=> "empty sample set"); - return expectationValue(x => x.Key < target ? 1 : 0, x => true).Key; - } - - // averaged shortfallness - public double averageShortfall(double target) { - KeyValuePair result = expectationValue(z => target - z.Key, z => z.Key < target); - double x = result.Key; - int N = result.Value; - Utils.QL_REQUIRE(N != 0,()=> "no data below the target"); - return x; - } - } - - //! default risk measures tool - /*! \test the correctness of the returned values is tested by checking them against numerical calculations. */ - public class RiskStatistics : GenericRiskStatistics { - public double gaussianPercentile(double value) { - return impl_.gaussianPercentile(value); - } - public double gaussianPotentialUpside(double value) { - return impl_.gaussianPotentialUpside(value); - } - public double gaussianValueAtRisk(double value) { - return impl_.gaussianValueAtRisk(value); - } - public double gaussianExpectedShortfall(double value) { - return impl_.gaussianExpectedShortfall(value); - } - public double gaussianShortfall(double value) { - return impl_.gaussianShortfall(value); - } - public double gaussianAverageShortfall(double value) { - return impl_.gaussianAverageShortfall(value); - } - public double gaussianRegret(double value) { - return impl_.gaussianRegret(value); - } - public double gaussianDownsideVariance() { - return impl_.gaussianDownsideVariance(); - } - } - - //! default statistics tool - /*! \test the correctness of the returned values is tested by checking them against numerical calculations. */ - public class Statistics : RiskStatistics { } -} diff --git a/src/QLNet/Math/statistics/sequencestatistics.cs b/src/QLNet/Math/statistics/sequencestatistics.cs deleted file mode 100644 index a3936a913..000000000 --- a/src/QLNet/Math/statistics/sequencestatistics.cs +++ /dev/null @@ -1,219 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Reflection; - -namespace QLNet { - //! Statistics analysis of N-dimensional (sequence) data - /*! It provides 1-dimensional statistics as discrepancy plus - N-dimensional (sequence) statistics (e.g. mean, - variance, skewness, kurtosis, etc.) with one component for each - dimension of the sample space. - - For most of the statistics this class relies on - the StatisticsType underlying class to provide 1-D methods that - will be iterated for all the components of the N-D data. These - lifted methods are the union of all the methods that might be - requested to the 1-D underlying StatisticsType class, with the - usual compile-time checks provided by the template approach. - - \test the correctness of the returned values is tested by - checking them against numerical calculations. - */ - public class GenericSequenceStatistics where S : IGeneralStatistics, new() { - protected int dimension_; - public int size() { return dimension_; } - - protected List stats_; - protected List results_; - protected Matrix quadraticSum_; - - public GenericSequenceStatistics(int dimension) { - dimension_ = 0; - reset(dimension); - } - - //! returns the covariance Matrix - public Matrix covariance() { - double sampleWeight = weightSum(); - Utils.QL_REQUIRE(sampleWeight > 0.0,()=> "sampleWeight=0, unsufficient"); - - double sampleNumber = samples(); - Utils.QL_REQUIRE(sampleNumber > 1.0,()=> "sample number <=1, unsufficient"); - - List m = mean(); - double inv = 1.0/sampleWeight; - - Matrix result = inv*quadraticSum_; - result -= Matrix.outerProduct(m, m); - - result *= (sampleNumber/(sampleNumber-1.0)); - return result; - } - //! returns the correlation Matrix - public Matrix correlation() { - Matrix correlation = covariance(); - Vector variances = correlation.diagonal(); - for (int i=0; i noArg(string method) { - // do not check for null - in this case we throw anyways - for (int i = 0; i < dimension_; i++) { - MethodInfo methodInfo = Utils.GetMethodInfo( stats_[i], method ); - results_[i] = (double)methodInfo.Invoke(stats_[i], new object[] { }); - } - return results_; - } - // single argument list - private List singleArg(double x, string method) { - // do not check for null - in this case we throw anyways - for (int i = 0; i < dimension_; i++) { - MethodInfo methodInfo = Utils.GetMethodInfo( stats_[i], method ); - results_[i] = (double)methodInfo.Invoke(stats_[i], new object[] { x }); - } - return results_; - } - - // void argument list - public List mean() { - for (int i=0; i variance() { - for (int i=0; i standardDeviation() { - for (int i=0; i downsideVariance() { return noArg("downsideVariance"); } - public List downsideDeviation() { return noArg("downsideDeviation"); } - public List semiVariance() { return noArg("semiVariance"); } - public List semiDeviation() { return noArg("semiDeviation"); } - public List errorEstimate() { return noArg("errorEstimate"); } - public List skewness() { - for (int i=0; i kurtosis() { - for (int i=0; i min() { - for (int i=0; i max() { - for (int i=0; i gaussianPercentile(double x) { return singleArg(x, "gaussianPercentile"); } - public List percentile(double x) { - for (int i=0; i gaussianPotentialUpside(double x) { return singleArg(x, "gaussianPotentialUpside"); } - public List potentialUpside(double x) { return singleArg(x, "potentialUpside"); } - public List gaussianValueAtRisk(double x) { return singleArg(x, "gaussianValueAtRisk"); } - public List valueAtRisk(double x) { return singleArg(x, "valueAtRisk"); } - public List gaussianExpectedShortfall(double x) { return singleArg(x, "gaussianExpectedShortfall"); } - public List expectedShortfall(double x) { return singleArg(x, "expectedShortfall"); } - public List gaussianShortfall(double x) { return singleArg(x, "gaussianShortfall"); } - public List shortfall(double x) { return singleArg(x, "shortfall"); } - public List gaussianAverageShortfall(double x) { return singleArg(x, "gaussianAverageShortfall"); } - public List averageShortfall(double x) { return singleArg(x, "averageShortfall"); } - public List regret(double x) { return singleArg(x, "regret"); } - - - // Modifiers - public virtual void reset(int dimension) { - // (re-)initialize - if (dimension > 0) { - if (dimension == dimension_) { - for (int i=0; i(dimension); - results_ = new InitializedList(dimension); - } - quadraticSum_ = new Matrix(dimension_, dimension_, 0.0); - } else { - dimension_ = dimension; - } - } - - public virtual void add(List begin) { add(begin, 1); } - - public virtual void add(List begin, double weight) { - if (dimension_ == 0) { - // stat wasn't initialized yet - int dimension = begin.Count; - Utils.QL_REQUIRE(dimension>0,()=> "sample error: end<=begin"); - reset(dimension); - } - - Utils.QL_REQUIRE(begin.Count == dimension_,()=> - "sample size mismatch: " + dimension_ + " required, " + begin.Count + " provided"); - - quadraticSum_ += weight * Matrix.outerProduct(begin, begin); - - for (int i=0; i { - public SequenceStatistics(int dimension) : base(dimension) { } - } -} diff --git a/src/QLNet/Math/transformedgrid.cs b/src/QLNet/Math/transformedgrid.cs deleted file mode 100644 index 43a93bb4b..000000000 --- a/src/QLNet/Math/transformedgrid.cs +++ /dev/null @@ -1,83 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! transformed grid - /*! This package encapuslates an array of grid points. It is used primarily in PDE calculations. - */ - public class TransformedGrid { - protected Vector grid_; - protected Vector transformedGrid_; - protected Vector dxm_; - protected Vector dxp_; - protected Vector dx_; - - public Vector gridArray() { return grid_;} - public Vector transformedGridArray() { return transformedGrid_;} - public Vector dxmArray() { return dxm_;} - public Vector dxpArray() { return dxp_;} - public Vector dxArray() { return dx_;} - - public TransformedGrid (Vector grid) { - grid_ = grid.Clone(); - transformedGrid_ = grid.Clone(); - dxm_= new Vector(grid.size()); - dxp_ = new Vector(grid.size()); - dx_ = new Vector(grid.size()); - - for (int i=1; i < transformedGrid_.size() -1 ; i++) { - dxm_[i] = transformedGrid_[i] - transformedGrid_[i-1]; - dxp_[i] = transformedGrid_[i+1] - transformedGrid_[i]; - dx_[i] = dxm_[i] + dxp_[i]; - } - } - - public TransformedGrid(Vector grid, Func func) { - grid_ = grid.Clone(); - transformedGrid_ = new Vector(grid.size()); - dxm_= new Vector(grid.size()); - dxp_ = new Vector(grid.size()); - dx_ = new Vector(grid.size()); - - for(int i=0; i. - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - //! American exercise condition. - /*! \todo unify the intrinsicValues/Payoff thing */ - public class AmericanCondition : CurveDependentStepCondition { - public AmericanCondition(Option.Type type, double strike) : base(type, strike) { } +namespace QLNet +{ + //! American exercise condition. + /*! \todo unify the intrinsicValues/Payoff thing */ + public class AmericanCondition : CurveDependentStepCondition + { + public AmericanCondition(Option.Type type, double strike) : base(type, strike) { } - public AmericanCondition(Vector intrinsicValues) : base(intrinsicValues) { } + public AmericanCondition(Vector intrinsicValues) : base(intrinsicValues) { } - protected override double applyToValue(double current, double intrinsic) { - return Math.Max(current, intrinsic); - } - } + protected override double applyToValue(double current, double intrinsic) + { + return Math.Max(current, intrinsic); + } + } } diff --git a/src/QLNet/Methods/Finitedifferences/BSMOperator.cs b/src/QLNet/Methods/Finitedifferences/BSMOperator.cs new file mode 100644 index 000000000..3daa5dad1 --- /dev/null +++ b/src/QLNet/Methods/Finitedifferences/BSMOperator.cs @@ -0,0 +1,45 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +namespace QLNet +{ + //! Black-Scholes-Merton differential operator + /*! \ingroup findiff */ + public class BSMOperator : TridiagonalOperator + { + public BSMOperator() { } + + public BSMOperator(int size, double dx, double r, double q, double sigma) : base(size) + { + double sigma2 = sigma * sigma; + double nu = r - q - sigma2 / 2; + double pd = -(sigma2 / dx - nu) / (2 * dx); + double pu = -(sigma2 / dx + nu) / (2 * dx); + double pm = sigma2 / (dx * dx) + r; + setMidRows(pd, pm, pu); + } + + public BSMOperator(Vector grid, GeneralizedBlackScholesProcess process, double residualTime) : base(grid.size()) + { + LogGrid logGrid = new LogGrid(grid); + var cc = new PdeConstantCoeff(process, residualTime, process.stateVariable().link.value()); + cc.generateOperator(residualTime, logGrid, this); + } + } +} diff --git a/src/QLNet/Methods/Finitedifferences/BoundaryCondition.cs b/src/QLNet/Methods/Finitedifferences/BoundaryCondition.cs index 31f5e503e..cd2315a54 100644 --- a/src/QLNet/Methods/Finitedifferences/BoundaryCondition.cs +++ b/src/QLNet/Methods/Finitedifferences/BoundaryCondition.cs @@ -1,123 +1,133 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - //! Abstract boundary condition class for finite difference problems - public class BoundaryCondition where Operator : IOperator { - //! \todo Generalize for n-dimensional conditions - public enum Side { None, Upper, Lower }; - - // interface - /*! This method modifies an operator \f$ L \f$ before it is - applied to an array \f$ u \f$ so that \f$ v = Lu \f$ will - satisfy the given condition. */ - public virtual void applyBeforeApplying(IOperator o) { throw new NotSupportedException(); } - - /*! This method modifies an array \f$ u \f$ so that it satisfies the given condition. */ - public virtual void applyAfterApplying(Vector v) { throw new NotSupportedException(); } - - /*! This method modifies an operator \f$ L \f$ before the linear - system \f$ Lu' = u \f$ is solved so that \f$ u' \f$ will - satisfy the given condition. */ - public virtual void applyBeforeSolving(IOperator o, Vector v) { throw new NotSupportedException(); } - - /*! This method modifies an array \f$ u \f$ so that it satisfies the given condition. */ - public virtual void applyAfterSolving(Vector v) { throw new NotSupportedException(); } - - /*! This method sets the current time for time-dependent boundary conditions. */ - public virtual void setTime(double t) { throw new NotSupportedException(); } - } - - - // Time-independent boundary conditions for tridiagonal operators - - //! Neumann boundary condition (i.e., constant derivative) - /*! \warning The value passed must not be the value of the derivative. - Instead, it must be comprehensive of the grid step - between the first two points--i.e., it must be the - difference between f[0] and f[1]. - \todo generalize to time-dependent conditions. - - \ingroup findiff - */ - // NeumanBC works on TridiagonalOperator. IOperator here is for type compatobility with options - public class NeumannBC : BoundaryCondition { - private double value_; - private Side side_; - - public NeumannBC(double value, Side side) { - value_ = value; - side_ = side; - } - - // interface - public override void applyBeforeApplying(IOperator o) { - TridiagonalOperator L = o as TridiagonalOperator; - switch (side_) { - case Side.Lower: - L.setFirstRow(-1.0,1.0); - break; - case Side.Upper: - L.setLastRow(-1.0,1.0); - break; - default: - throw new ArgumentException("unknown side for Neumann boundary condition"); - } - } - - public override void applyAfterApplying(Vector u) { - switch (side_) { - case Side.Lower: - u[0] = u[1] - value_; - break; - case Side.Upper: - u[u.size()-1] = u[u.size()-2] + value_; - break; - default: - throw new ArgumentException("unknown side for Neumann boundary condition"); - } - } - - public override void applyBeforeSolving(IOperator o, Vector rhs) { - TridiagonalOperator L = o as TridiagonalOperator; - switch (side_) { - case Side.Lower: - L.setFirstRow(-1.0,1.0); - rhs[0] = value_; - break; - case Side.Upper: - L.setLastRow(-1.0,1.0); - rhs[rhs.size()-1] = value_; - break; - default: - throw new ArgumentException("unknown side for Neumann boundary condition"); - } - } - public override void applyAfterSolving(Vector v) - { - // Nothing to do here - } - - public override void setTime(double t) - { - // Nothing to do here - } - } +namespace QLNet +{ + //! Abstract boundary condition class for finite difference problems + public class BoundaryCondition where Operator : IOperator + { + //! \todo Generalize for n-dimensional conditions + public enum Side { None, Upper, Lower } + + // interface + /*! This method modifies an operator \f$ L \f$ before it is + applied to an array \f$ u \f$ so that \f$ v = Lu \f$ will + satisfy the given condition. */ + public virtual void applyBeforeApplying(IOperator o) { throw new NotSupportedException(); } + + /*! This method modifies an array \f$ u \f$ so that it satisfies the given condition. */ + public virtual void applyAfterApplying(Vector v) { throw new NotSupportedException(); } + + /*! This method modifies an operator \f$ L \f$ before the linear + system \f$ Lu' = u \f$ is solved so that \f$ u' \f$ will + satisfy the given condition. */ + public virtual void applyBeforeSolving(IOperator o, Vector v) { throw new NotSupportedException(); } + + /*! This method modifies an array \f$ u \f$ so that it satisfies the given condition. */ + public virtual void applyAfterSolving(Vector v) { throw new NotSupportedException(); } + + /*! This method sets the current time for time-dependent boundary conditions. */ + public virtual void setTime(double t) { throw new NotSupportedException(); } + } + + + // Time-independent boundary conditions for tridiagonal operators + + //! Neumann boundary condition (i.e., constant derivative) + /*! \warning The value passed must not be the value of the derivative. + Instead, it must be comprehensive of the grid step + between the first two points--i.e., it must be the + difference between f[0] and f[1]. + \todo generalize to time-dependent conditions. + + \ingroup findiff + */ + // NeumanBC works on TridiagonalOperator. IOperator here is for type compatobility with options + public class NeumannBC : BoundaryCondition + { + private double value_; + private Side side_; + + public NeumannBC(double value, Side side) + { + value_ = value; + side_ = side; + } + + // interface + public override void applyBeforeApplying(IOperator o) + { + TridiagonalOperator L = o as TridiagonalOperator; + switch (side_) + { + case Side.Lower: + L.setFirstRow(-1.0, 1.0); + break; + case Side.Upper: + L.setLastRow(-1.0, 1.0); + break; + default: + throw new ArgumentException("unknown side for Neumann boundary condition"); + } + } + + public override void applyAfterApplying(Vector u) + { + switch (side_) + { + case Side.Lower: + u[0] = u[1] - value_; + break; + case Side.Upper: + u[u.size() - 1] = u[u.size() - 2] + value_; + break; + default: + throw new ArgumentException("unknown side for Neumann boundary condition"); + } + } + + public override void applyBeforeSolving(IOperator o, Vector rhs) + { + TridiagonalOperator L = o as TridiagonalOperator; + switch (side_) + { + case Side.Lower: + L.setFirstRow(-1.0, 1.0); + rhs[0] = value_; + break; + case Side.Upper: + L.setLastRow(-1.0, 1.0); + rhs[rhs.size() - 1] = value_; + break; + default: + throw new ArgumentException("unknown side for Neumann boundary condition"); + } + } + public override void applyAfterSolving(Vector v) + { + // Nothing to do here + } + + public override void setTime(double t) + { + // Nothing to do here + } + } } diff --git a/src/QLNet/Methods/Finitedifferences/CrankNicolson.cs b/src/QLNet/Methods/Finitedifferences/CrankNicolson.cs new file mode 100644 index 000000000..4b30eff97 --- /dev/null +++ b/src/QLNet/Methods/Finitedifferences/CrankNicolson.cs @@ -0,0 +1,45 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System.Collections.Generic; + +namespace QLNet +{ + //! Crank-Nicolson scheme for finite difference methods + /*! In this implementation, the passed operator must be derived + from either TimeConstantOperator or TimeDependentOperator. + Also, it must implement at least the following interface: + + \warning The differential operator must be linear for + this evolver to work. + + \ingroup findiff + */ + public class CrankNicolson : MixedScheme, ISchemeFactory where Operator : IOperator + { + // constructors + public CrankNicolson() { } // required for generics + public CrankNicolson(Operator L, List> bcs) + : base(L, 0.5, bcs) { } + + public IMixedScheme factory(object L, object bcs, object[] additionalFields = null) + { + return new CrankNicolson((Operator)L, (List>)bcs); + } + } +} diff --git a/src/QLNet/Methods/Finitedifferences/DMinus.cs b/src/QLNet/Methods/Finitedifferences/DMinus.cs index 88949f985..97a0cebeb 100644 --- a/src/QLNet/Methods/Finitedifferences/DMinus.cs +++ b/src/QLNet/Methods/Finitedifferences/DMinus.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,23 +20,23 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! \f$ D_{-} \f$ matricial representation - /*! The differential operator \f$ D_{-} \f$ discretizes the - first derivative with the first-order formula - \f[ \frac{\partial u_{i}}{\partial x} \approx - \frac{u_{i}-u_{i-1}}{h} = D_{-} u_{i} - \f] + //! \f$ D_{-} \f$ matricial representation + /*! The differential operator \f$ D_{-} \f$ discretizes the + first derivative with the first-order formula + \f[ \frac{\partial u_{i}}{\partial x} \approx + \frac{u_{i}-u_{i-1}}{h} = D_{-} u_{i} + \f] - \ingroup findiff - */ - public class DMinus : TridiagonalOperator - { - public DMinus(int gridPoints, double h) - : base(gridPoints) - { - setFirstRow(-1.0/h, 1.0/h); // linear extrapolation - setMidRows(-1.0/h, 1.0/h, 0.0); - setLastRow(-1.0/h, 1.0/h); - } - } + \ingroup findiff + */ + public class DMinus : TridiagonalOperator + { + public DMinus(int gridPoints, double h) + : base(gridPoints) + { + setFirstRow(-1.0 / h, 1.0 / h); // linear extrapolation + setMidRows(-1.0 / h, 1.0 / h, 0.0); + setLastRow(-1.0 / h, 1.0 / h); + } + } } diff --git a/src/QLNet/Methods/Finitedifferences/DPlus.cs b/src/QLNet/Methods/Finitedifferences/DPlus.cs index 62eda0681..6e0057e32 100644 --- a/src/QLNet/Methods/Finitedifferences/DPlus.cs +++ b/src/QLNet/Methods/Finitedifferences/DPlus.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,23 +20,23 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! \f$ D_{+} \f$ matricial representation - /*! The differential operator \f$ D_{+} \f$ discretizes the - first derivative with the first-order formula - \f[ \frac{\partial u_{i}}{\partial x} \approx - \frac{u_{i+1}-u_{i}}{h} = D_{+} u_{i} - \f] + //! \f$ D_{+} \f$ matricial representation + /*! The differential operator \f$ D_{+} \f$ discretizes the + first derivative with the first-order formula + \f[ \frac{\partial u_{i}}{\partial x} \approx + \frac{u_{i+1}-u_{i}}{h} = D_{+} u_{i} + \f] - \ingroup findiff - */ - public class DPlus : TridiagonalOperator - { - public DPlus(int gridPoints, double h) - : base(gridPoints) - { - setFirstRow(-1.0/h, 1.0/h); - setMidRows(0.0, -1.0/h, 1.0/h); - setLastRow(-1.0/h, 1.0/h); // linear extrapolation - } - } + \ingroup findiff + */ + public class DPlus : TridiagonalOperator + { + public DPlus(int gridPoints, double h) + : base(gridPoints) + { + setFirstRow(-1.0 / h, 1.0 / h); + setMidRows(0.0, -1.0 / h, 1.0 / h); + setLastRow(-1.0 / h, 1.0 / h); // linear extrapolation + } + } } diff --git a/src/QLNet/Methods/Finitedifferences/DPlusDMinus.cs b/src/QLNet/Methods/Finitedifferences/DPlusDMinus.cs index 925b88c03..3125a4acb 100644 --- a/src/QLNet/Methods/Finitedifferences/DPlusDMinus.cs +++ b/src/QLNet/Methods/Finitedifferences/DPlusDMinus.cs @@ -1,38 +1,41 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { - //! \f$ D_{+}D_{-} \f$ matricial representation - /*! The differential operator \f$ D_{+}D_{-} \f$ discretizes the - second derivative with the second-order formula +namespace QLNet +{ + //! \f$ D_{+}D_{-} \f$ matricial representation + /*! The differential operator \f$ D_{+}D_{-} \f$ discretizes the + second derivative with the second-order formula - \ingroup findiff + \ingroup findiff - \test the correctness of the returned values is tested by - checking them against numerical calculations. - */ - public class DPlusDMinus : TridiagonalOperator { - public DPlusDMinus(int gridPoints, double h) - : base(gridPoints) { - setFirstRow(0.0,0.0); // linear extrapolation - setMidRows(1/(h*h),-2/(h*h),1/(h*h)); - setLastRow(0.0,0.0); // linear extrapolation - } - } + \test the correctness of the returned values is tested by + checking them against numerical calculations. + */ + public class DPlusDMinus : TridiagonalOperator + { + public DPlusDMinus(int gridPoints, double h) + : base(gridPoints) + { + setFirstRow(0.0, 0.0); // linear extrapolation + setMidRows(1 / (h * h), -2 / (h * h), 1 / (h * h)); + setLastRow(0.0, 0.0); // linear extrapolation + } + } } diff --git a/src/QLNet/Methods/Finitedifferences/DZero.cs b/src/QLNet/Methods/Finitedifferences/DZero.cs new file mode 100644 index 000000000..032a434ab --- /dev/null +++ b/src/QLNet/Methods/Finitedifferences/DZero.cs @@ -0,0 +1,41 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +namespace QLNet +{ + //! \f$ D_{0} \f$ matricial representation + /*! The differential operator \f$ D_{0} \f$ discretizes the + first derivative with the second-order formula + + \ingroup findiff + + \test the correctness of the returned values is tested by + checking them against numerical calculations. + */ + public class DZero : TridiagonalOperator + { + public DZero(int gridPoints, double h) + : base(gridPoints) + { + setFirstRow(-1 / h, 1 / h); // linear extrapolation + setMidRows(-1 / (2 * h), 0.0, 1 / (2 * h)); + setLastRow(-1 / h, 1 / h); // linear extrapolation + } + } +} diff --git a/src/QLNet/Methods/Finitedifferences/ExplicitEuler.cs b/src/QLNet/Methods/Finitedifferences/ExplicitEuler.cs index d18bfb6f8..47aad28a9 100644 --- a/src/QLNet/Methods/Finitedifferences/ExplicitEuler.cs +++ b/src/QLNet/Methods/Finitedifferences/ExplicitEuler.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,43 +21,43 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! %Forward Euler scheme for finite difference methods - /*! See sect. \ref findiff for details on the method. - - In this implementation, the passed operator must be derived - from either TimeConstantOperator or TimeDependentOperator. - Also, it must implement at least the following interface: - - // copy constructor/assignment - // (these will be provided by the compiler if none is defined) - Operator(const Operator&); - Operator& operator=(const Operator&); - - // inspectors - Size size(); - - // modifiers - void setTime(Time t); - - // operator interface - array_type applyTo(const array_type&); - static Operator identity(Size size); - - // operator algebra - Operator operator*(Real, const Operator&); - Operator operator-(const Operator&, const Operator&); - \endcode - - \todo add Richardson extrapolation - - \ingroup findiff - */ - public class ExplicitEuler : MixedScheme where Operator : IOperator - { - // constructors - public ExplicitEuler() { } // required for generics - public ExplicitEuler(Operator L, List> bcs) - : base(L, 0.0, bcs) - { } - } + //! %Forward Euler scheme for finite difference methods + /*! See sect. \ref findiff for details on the method. + + In this implementation, the passed operator must be derived + from either TimeConstantOperator or TimeDependentOperator. + Also, it must implement at least the following interface: + + // copy constructor/assignment + // (these will be provided by the compiler if none is defined) + Operator(const Operator&); + Operator& operator=(const Operator&); + + // inspectors + Size size(); + + // modifiers + void setTime(Time t); + + // operator interface + array_type applyTo(const array_type&); + static Operator identity(Size size); + + // operator algebra + Operator operator*(Real, const Operator&); + Operator operator-(const Operator&, const Operator&); + \endcode + + \todo add Richardson extrapolation + + \ingroup findiff + */ + public class ExplicitEuler : MixedScheme where Operator : IOperator + { + // constructors + public ExplicitEuler() { } // required for generics + public ExplicitEuler(Operator L, List> bcs) + : base(L, 0.0, bcs) + { } + } } diff --git a/src/QLNet/Methods/Finitedifferences/FiniteDifferenceModel.cs b/src/QLNet/Methods/Finitedifferences/FiniteDifferenceModel.cs new file mode 100644 index 000000000..40aefc94d --- /dev/null +++ b/src/QLNet/Methods/Finitedifferences/FiniteDifferenceModel.cs @@ -0,0 +1,124 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QLNet +{ + public class FiniteDifferenceModel where Evolver : IMixedScheme, ISchemeFactory, new () + { + private Evolver evolver_; + public Evolver evolver() { return evolver_; } + + private List stoppingTimes_; + + // constructors + public FiniteDifferenceModel(object L, object bcs) + : this(L, bcs, new List()) { } + public FiniteDifferenceModel(object L, object bcs, List stoppingTimes) + { + evolver_ = (Evolver)FastActivator.Create().factory(L, bcs); + stoppingTimes_ = stoppingTimes; + stoppingTimes_.Sort(); + stoppingTimes_ = stoppingTimes_.Distinct().ToList(); + } + + //public FiniteDifferenceModel(Evolver evolver, List stoppingTimes = List()) + public FiniteDifferenceModel(Evolver evolver, List stoppingTimes) + { + evolver_ = evolver; + + stoppingTimes_ = stoppingTimes; + stoppingTimes_.Sort(); + stoppingTimes_ = stoppingTimes_.Distinct().ToList(); + } + + /*! solves the problem between the given times, applying a condition at every step. + \warning being this a rollback, from must be a later time than to. */ + public void rollback(ref object a, double from, double to, int steps) { rollbackImpl(ref a, from, to, steps, null); } + public void rollback(ref object a, double from, double to, int steps, IStepCondition condition) + { + rollbackImpl(ref a, from, to, steps, condition); + } + + private void rollbackImpl(ref object o, double from, double to, int steps, IStepCondition condition) + { + + Utils.QL_REQUIRE(from >= to, () => "trying to roll back from " + from + " to " + to); + + double dt = (from - to) / steps, t = from; + evolver_.setStep(dt); + + if (!stoppingTimes_.empty() && stoppingTimes_.Last() == from) + { + if (condition != null) + condition.applyTo(o, from); + } + for (int i = 0; i < steps; ++i, t -= dt) + { + double now = t, next = t - dt; + if (Math.Abs(to - next) < Math.Sqrt(Const.QL_EPSILON)) + next = to; + bool hit = false; + for (int j = stoppingTimes_.Count - 1; j >= 0 ; --j) + { + if (next <= stoppingTimes_[j] && stoppingTimes_[j] < now) + { + // a stopping time was hit + hit = true; + + // perform a small step to stoppingTimes_[j]... + evolver_.setStep(now - stoppingTimes_[j]); + evolver_.step(ref o, now); + if (condition != null) + condition.applyTo(o, stoppingTimes_[j]); + // ...and continue the cycle + now = stoppingTimes_[j]; + } + } + // if we did hit... + if (hit) + { + // ...we might have to make a small step to + // complete the big one... + if (now > next) + { + evolver_.setStep(now - next); + evolver_.step(ref o, now); + if (condition != null) + condition.applyTo(o, next); + } + // ...and in any case, we have to reset the + // evolver to the default step. + evolver_.setStep(dt); + } + else + { + // if we didn't, the evolver is already set to the + // default step, which is ok for us. + evolver_.step(ref o, now); + if (condition != null) + condition.applyTo(o, next); + } + } + } + + } +} diff --git a/src/QLNet/Methods/Finitedifferences/ImplicitEuler.cs b/src/QLNet/Methods/Finitedifferences/ImplicitEuler.cs index a5fb53e34..61ca8fd98 100644 --- a/src/QLNet/Methods/Finitedifferences/ImplicitEuler.cs +++ b/src/QLNet/Methods/Finitedifferences/ImplicitEuler.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,39 +21,39 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! Backward Euler scheme for finite difference methods - /*! In this implementation, the passed operator must be derived - from either TimeConstantOperator or TimeDependentOperator. - Also, it must implement at least the following interface: - - // copy constructor/assignment - // (these will be provided by the compiler if none is defined) - Operator(const Operator&); - Operator& operator=(const Operator&); - - // inspectors - Size size(); - - // modifiers - void setTime(Time t); - - // operator interface - array_type solveFor(const array_type&); - static Operator identity(Size size); - - // operator algebra - Operator operator*(Real, const Operator&); - Operator operator+(const Operator&, const Operator&); - \endcode - - \ingroup findiff - */ - public class ImplicitEuler : MixedScheme where Operator : IOperator - { - // constructors - public ImplicitEuler() { } // required for generics - public ImplicitEuler(Operator L, List> bcs) - : base (L, 1.0, bcs) - { } - } + //! Backward Euler scheme for finite difference methods + /*! In this implementation, the passed operator must be derived + from either TimeConstantOperator or TimeDependentOperator. + Also, it must implement at least the following interface: + + // copy constructor/assignment + // (these will be provided by the compiler if none is defined) + Operator(const Operator&); + Operator& operator=(const Operator&); + + // inspectors + Size size(); + + // modifiers + void setTime(Time t); + + // operator interface + array_type solveFor(const array_type&); + static Operator identity(Size size); + + // operator algebra + Operator operator*(Real, const Operator&); + Operator operator+(const Operator&, const Operator&); + \endcode + + \ingroup findiff + */ + public class ImplicitEuler : MixedScheme where Operator : IOperator + { + // constructors + public ImplicitEuler() { } // required for generics + public ImplicitEuler(Operator L, List> bcs) + : base(L, 1.0, bcs) + { } + } } diff --git a/src/QLNet/Methods/Finitedifferences/Meshers/Concentrating1dMesher.cs b/src/QLNet/Methods/Finitedifferences/Meshers/Concentrating1dMesher.cs index a472eb8c1..0ddc17bea 100644 --- a/src/QLNet/Methods/Finitedifferences/Meshers/Concentrating1dMesher.cs +++ b/src/QLNet/Methods/Finitedifferences/Meshers/Concentrating1dMesher.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -34,24 +34,25 @@ public static double Asinh(double x) public class Concentrating1dMesher : Fdm1dMesher { public Concentrating1dMesher(double start, double end, int size, - Pair cPoints = null, - bool requireCPoint = false) - : base(size) + Pair < double?, double? > cPoints = null, + bool requireCPoint = false) + : base(size) { Utils.QL_REQUIRE(end > start, () => "end must be larger than start"); - if ( cPoints == null ) cPoints = new Pair(); + if (cPoints == null) + cPoints = new Pair < double?, double? >(); double? cPoint = cPoints.first; - double? density = cPoints.second == null ? null : cPoints.second * (end - start); + double ? density = cPoints.second == null ? null : cPoints.second * (end - start); Utils.QL_REQUIRE(cPoint == null || (cPoint >= start && cPoint <= end), - () => "cPoint must be between start and end"); + () => "cPoint must be between start and end"); Utils.QL_REQUIRE(density == null || density > 0.0, - () => "density > 0 required"); + () => "density > 0 required"); Utils.QL_REQUIRE(cPoint == null || density != null, - () => "density must be given if cPoint is given"); + () => "density must be given if cPoint is given"); Utils.QL_REQUIRE(!requireCPoint || cPoint != null, - () => "cPoint is required in grid but not given"); + () => "cPoint is required in grid but not given"); double dx = 1.0 / (size - 1); @@ -72,7 +73,7 @@ public Concentrating1dMesher(double start, double end, int size, double u0 = Math.Max( Math.Min(Convert.ToInt32(z0 * (size - 1) + 0.5), - Convert.ToInt32(size) - 2), + Convert.ToInt32(size) - 2), 1) / (Convert.ToDouble(size - 1)); u.Add(u0); z.Add(z0); @@ -110,9 +111,9 @@ public Concentrating1dMesher(double start, double end, int size, public class OdeIntegrationFct { - public OdeIntegrationFct(List points, - List betas, - double tol) + public OdeIntegrationFct(List < double? > points, + List < double? > betas, + double tol) { rk_ = new AdaptiveRungeKutta(tol); points_ = points; @@ -131,13 +132,13 @@ protected double jac(double a, double x, double y) for (int i = 0; i < points_.Count; ++i) { s += 1.0 / (betas_[i].GetValueOrDefault() + (y - points_[i].GetValueOrDefault()) * - (y - points_[i].GetValueOrDefault())); + (y - points_[i].GetValueOrDefault())); } return a / Math.Sqrt(s); } protected AdaptiveRungeKutta rk_; - protected List points_, betas_; + protected List < double? > points_, betas_; } public class OdeSolver : ISolver1d @@ -178,14 +179,14 @@ public override double value(double v) } public Concentrating1dMesher(double start, double end, int size, - List> cPoints, - double tol = 1e-8) - : base(size) + List < Tuple < double?, double?, bool >> cPoints, + double tol = 1e-8) + : base(size) { Utils.QL_REQUIRE(end > start, () => "end must be larger than start"); - List points = new List(), betas = new List(); - foreach (Tuple iter in cPoints) + List < double? > points = new List < double? >(), betas = new List < double? >(); + foreach (Tuple < double?, double?, bool > iter in cPoints) { points.Add(iter.Item1); betas.Add((iter.Item2 * (end - start)) * (iter.Item2 * (end - start))); @@ -226,8 +227,8 @@ public Concentrating1dMesher(double start, double end, int size, LinearInterpolation odeSolution = new LinearInterpolation(x, x.Count, y); // ensure required points are part of the grid - List> w = - new InitializedList>(1, new Pair(0.0, 0.0)); + List < Pair < double?, double? >> w = + new InitializedList < Pair < double?, double? >> (1, new Pair < double?, double? >(0.0, 0.0)); for (int i = 0; i < points.Count; ++i) { @@ -239,10 +240,10 @@ public Concentrating1dMesher(double start, double end, int size, new OdeSolver2(odeSolution.value, points[i].Value), Const.QL_EPSILON, x[j], 0.5 / size); - w.Add(new Pair(Math.Min(x[size - 2], x[j]), e)); + w.Add(new Pair < double?, double? >(Math.Min(x[size - 2], x[j]), e)); } } - w.Add(new Pair(1.0, 1.0)); + w.Add(new Pair < double?, double? >(1.0, 1.0)); w = w.OrderBy(xx => xx.first).Distinct(new equal_on_first()).ToList(); List u = new List(w.Count), z = new List(w.Count); diff --git a/src/QLNet/Methods/Finitedifferences/Meshers/Fdm1dMesher.cs b/src/QLNet/Methods/Finitedifferences/Meshers/Fdm1dMesher.cs index 95ba6e8dd..7576257ae 100644 --- a/src/QLNet/Methods/Finitedifferences/Meshers/Fdm1dMesher.cs +++ b/src/QLNet/Methods/Finitedifferences/Meshers/Fdm1dMesher.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,8 +29,8 @@ public class Fdm1dMesher public Fdm1dMesher(int size) { locations_ = new InitializedList(size); - dplus_ = new InitializedList(size); - dminus_ = new InitializedList(size); + dplus_ = new InitializedList < double? >(size); + dminus_ = new InitializedList < double? >(size); } public int size() @@ -59,6 +59,6 @@ public List locations() } protected List locations_; - protected List dplus_, dminus_; + protected List < double? > dplus_, dminus_; } } diff --git a/src/QLNet/Methods/Finitedifferences/Meshers/FdmBlackScholesMesher.cs b/src/QLNet/Methods/Finitedifferences/Meshers/FdmBlackScholesMesher.cs index 728d10ac5..34ec6c434 100644 --- a/src/QLNet/Methods/Finitedifferences/Meshers/FdmBlackScholesMesher.cs +++ b/src/QLNet/Methods/Finitedifferences/Meshers/FdmBlackScholesMesher.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -27,116 +27,121 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class Pair - { - protected KeyValuePair pair; - - public Pair() { } - - public Pair(TFirst first, TSecond second) - { - pair = new KeyValuePair(first, second); - } - - public void set(TFirst first, TSecond second) - { - pair = new KeyValuePair(first, second); - } - - public TFirst first - { - get - { - return pair.Key; - } - } - - public TSecond second - { - get - { - return pair.Value; - } - } - } - - public class equal_on_first : IEqualityComparer> - { - public bool Equals(Pair p1, - Pair p2) - { - return Utils.close_enough(p1.first.Value, p2.first.Value, 1000); - } - - public int GetHashCode(Pair p) - { - return Convert.ToInt32(p.first.Value * p.second.Value); - } - - } - - public class FdmBlackScholesMesher : Fdm1dMesher - { - public FdmBlackScholesMesher(int size, - GeneralizedBlackScholesProcess process, - double maturity, double strike, - double? xMinConstraint = null, - double? xMaxConstraint = null, - double eps = 0.0001, - double scaleFactor = 1.5, - Pair cPoint - = null) - : base(size) - { - double S = process.x0(); - Utils.QL_REQUIRE(S > 0.0, () => "negative or null underlying given"); - - // Set the grid boundaries - double normInvEps = new InverseCumulativeNormal().value(1-eps); - double sigmaSqrtT - = process.blackVolatility().currentLink().blackVol(maturity, strike) - * Math.Sqrt(maturity); - - double? xMin = Math.Log(S) - sigmaSqrtT*normInvEps*scaleFactor; - double? xMax = Math.Log(S) + sigmaSqrtT*normInvEps*scaleFactor; - - if (xMinConstraint != null) { - xMin = xMinConstraint; - } - if (xMaxConstraint != null) { - xMax = xMaxConstraint; - } - - Fdm1dMesher helper; - if ( cPoint != null - && Math.Log(cPoint.first.Value) >=xMin && Math.Log(cPoint.first.Value) <=xMax) { - - helper = new Concentrating1dMesher(xMin.Value, xMax.Value, size, - new Pair(Math.Log(cPoint.first.Value), cPoint.second)); - } - else { - helper = new Uniform1dMesher(xMin.Value, xMax.Value, size); - } - - locations_ = helper.locations(); - for (int i=0; i < locations_.Count; ++i) { - dplus_[i] = helper.dplus(i); - dminus_[i] = helper.dminus(i); - } - } - - public static GeneralizedBlackScholesProcess processHelper( Handle s0, - Handle rTS, - Handle qTS, - double vol) - { - return new GeneralizedBlackScholesProcess( - s0, qTS, rTS, - new Handle( - new BlackConstantVol(rTS.currentLink().referenceDate(), - new Calendar(), - vol, - rTS.currentLink().dayCounter()))); - } - } + public class Pair + { + protected KeyValuePair pair; + + public Pair() { } + + public Pair(TFirst first, TSecond second) + { + pair = new KeyValuePair(first, second); + } + + public void set(TFirst first, TSecond second) + { + pair = new KeyValuePair(first, second); + } + + public TFirst first + { + get + { + return pair.Key; + } + } + + public TSecond second + { + get + { + return pair.Value; + } + } + } + + public class equal_on_first : IEqualityComparer < Pair < double?, double? >> + { + public bool Equals(Pair < double?, double? > p1, + Pair < double?, double? > p2) + { + return Utils.close_enough(p1.first.Value, p2.first.Value, 1000); + } + + public int GetHashCode(Pair < double?, double? > p) + { + return Convert.ToInt32(p.first.Value * p.second.Value); + } + + } + + public class FdmBlackScholesMesher : Fdm1dMesher + { + public FdmBlackScholesMesher(int size, + GeneralizedBlackScholesProcess process, + double maturity, double strike, + double? xMinConstraint = null, + double? xMaxConstraint = null, + double eps = 0.0001, + double scaleFactor = 1.5, + Pair < double?, double? > cPoint + = null) + : base(size) + { + double S = process.x0(); + Utils.QL_REQUIRE(S > 0.0, () => "negative or null underlying given"); + + // Set the grid boundaries + double normInvEps = new InverseCumulativeNormal().value(1 - eps); + double sigmaSqrtT + = process.blackVolatility().currentLink().blackVol(maturity, strike) + * Math.Sqrt(maturity); + + double? xMin = Math.Log(S) - sigmaSqrtT * normInvEps * scaleFactor; + double? xMax = Math.Log(S) + sigmaSqrtT * normInvEps * scaleFactor; + + if (xMinConstraint != null) + { + xMin = xMinConstraint; + } + if (xMaxConstraint != null) + { + xMax = xMaxConstraint; + } + + Fdm1dMesher helper; + if (cPoint != null + && Math.Log(cPoint.first.Value) >= xMin && Math.Log(cPoint.first.Value) <= xMax) + { + + helper = new Concentrating1dMesher(xMin.Value, xMax.Value, size, + new Pair < double?, double? >(Math.Log(cPoint.first.Value), cPoint.second)); + } + else + { + helper = new Uniform1dMesher(xMin.Value, xMax.Value, size); + } + + locations_ = helper.locations(); + for (int i = 0; i < locations_.Count; ++i) + { + dplus_[i] = helper.dplus(i); + dminus_[i] = helper.dminus(i); + } + } + + public static GeneralizedBlackScholesProcess processHelper(Handle s0, + Handle rTS, + Handle qTS, + double vol) + { + return new GeneralizedBlackScholesProcess( + s0, qTS, rTS, + new Handle( + new BlackConstantVol(rTS.currentLink().referenceDate(), + new Calendar(), + vol, + rTS.currentLink().dayCounter()))); + } + } } diff --git a/src/QLNet/Methods/Finitedifferences/Meshers/FdmMesher.cs b/src/QLNet/Methods/Finitedifferences/Meshers/FdmMesher.cs index 5c5376fba..1a044b817 100644 --- a/src/QLNet/Methods/Finitedifferences/Meshers/FdmMesher.cs +++ b/src/QLNet/Methods/Finitedifferences/Meshers/FdmMesher.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,24 +20,26 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public abstract class FdmMesher - { - public FdmMesher(FdmLinearOpLayout layout) { - layout_ = layout; - } + public abstract class FdmMesher + { + public FdmMesher(FdmLinearOpLayout layout) + { + layout_ = layout; + } - public abstract double? dplus(FdmLinearOpIterator iter, + public abstract double? dplus(FdmLinearOpIterator iter, int direction); - public abstract double? dminus(FdmLinearOpIterator iter, + public abstract double? dminus(FdmLinearOpIterator iter, int direction); - public abstract double location(FdmLinearOpIterator iter, - int direction); - public abstract Vector locations(int direction); + public abstract double location(FdmLinearOpIterator iter, + int direction); + public abstract Vector locations(int direction); - public FdmLinearOpLayout layout() { - return layout_; - } + public FdmLinearOpLayout layout() + { + return layout_; + } - protected FdmLinearOpLayout layout_; - } + protected FdmLinearOpLayout layout_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/Meshers/FdmMesherComposite.cs b/src/QLNet/Methods/Finitedifferences/Meshers/FdmMesherComposite.cs index 8487005bb..225185bd5 100644 --- a/src/QLNet/Methods/Finitedifferences/Meshers/FdmMesherComposite.cs +++ b/src/QLNet/Methods/Finitedifferences/Meshers/FdmMesherComposite.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,96 +22,97 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class FdmMesherComposite : FdmMesher - { - public FdmMesherComposite(FdmLinearOpLayout layout, List mesher) - : base(layout) - { - mesher_ = mesher; - for (int i = 0; i < mesher.Count; ++i) - { - Utils.QL_REQUIRE(mesher[i].size() == layout.dim()[i], - () => "size of 1d mesher " + i + " does not fit to layout"); - } - } - - public FdmMesherComposite(List mesher) - : base(getLayoutFromMeshers(mesher)) - { - mesher_ = mesher; - } - - public FdmMesherComposite(Fdm1dMesher mesher) - : base(getLayoutFromMeshers(new List() { mesher })) - { - mesher_ = new List() { mesher }; - } - - public FdmMesherComposite(Fdm1dMesher m1, Fdm1dMesher m2) - : base(getLayoutFromMeshers(new List() { m1, m2 })) - { - mesher_ = new List() { m1, m2 }; - } - - public FdmMesherComposite(Fdm1dMesher m1, Fdm1dMesher m2, Fdm1dMesher m3) - : base(getLayoutFromMeshers(new List() { m1, m2, m3 })) - { - mesher_ = new List() { m1, m2, m3 }; - } - - public FdmMesherComposite(Fdm1dMesher m1, Fdm1dMesher m2, Fdm1dMesher m3, Fdm1dMesher m4) - : base(getLayoutFromMeshers(new List() { m1, m2, m3, m4 })) - { - mesher_ = new List() { m1, m2, m3, m4 }; - } - - public override double? dplus(FdmLinearOpIterator iter, int direction) - { - return mesher_[direction].dplus(iter.coordinates()[direction]); - } - - public override double? dminus(FdmLinearOpIterator iter, int direction) - { - return mesher_[direction].dminus(iter.coordinates()[direction]); - } - - public override double location(FdmLinearOpIterator iter, - int direction) - { - return mesher_[direction].location(iter.coordinates()[direction]); - } - - public override Vector locations(int direction) - { - Vector retVal = new Vector(layout_.size()); - - FdmLinearOpIterator endIter = layout_.end(); - for (FdmLinearOpIterator iter = layout_.begin(); - iter != endIter; ++iter) - { - retVal[iter.index()] = - mesher_[direction].locations()[iter.coordinates()[direction]]; - } - - return retVal; - } - - public List getFdm1dMeshers() - { - return mesher_; - } - - protected static FdmLinearOpLayout getLayoutFromMeshers(List meshers) - { - List dim = new InitializedList(meshers.Count); - for (int i=0; i < dim.Count; ++i) { - dim[i] = meshers[i].size(); - } - return new FdmLinearOpLayout(dim); - } - - protected Vector dx_; - protected List> locations_; - protected List mesher_; - } + public class FdmMesherComposite : FdmMesher + { + public FdmMesherComposite(FdmLinearOpLayout layout, List mesher) + : base(layout) + { + mesher_ = mesher; + for (int i = 0; i < mesher.Count; ++i) + { + Utils.QL_REQUIRE(mesher[i].size() == layout.dim()[i], + () => "size of 1d mesher " + i + " does not fit to layout"); + } + } + + public FdmMesherComposite(List mesher) + : base(getLayoutFromMeshers(mesher)) + { + mesher_ = mesher; + } + + public FdmMesherComposite(Fdm1dMesher mesher) + : base(getLayoutFromMeshers(new List() { mesher })) + { + mesher_ = new List() { mesher }; + } + + public FdmMesherComposite(Fdm1dMesher m1, Fdm1dMesher m2) + : base(getLayoutFromMeshers(new List() { m1, m2 })) + { + mesher_ = new List() { m1, m2 }; + } + + public FdmMesherComposite(Fdm1dMesher m1, Fdm1dMesher m2, Fdm1dMesher m3) + : base(getLayoutFromMeshers(new List() { m1, m2, m3 })) + { + mesher_ = new List() { m1, m2, m3 }; + } + + public FdmMesherComposite(Fdm1dMesher m1, Fdm1dMesher m2, Fdm1dMesher m3, Fdm1dMesher m4) + : base(getLayoutFromMeshers(new List() { m1, m2, m3, m4 })) + { + mesher_ = new List() { m1, m2, m3, m4 }; + } + + public override double? dplus(FdmLinearOpIterator iter, int direction) + { + return mesher_[direction].dplus(iter.coordinates()[direction]); + } + + public override double? dminus(FdmLinearOpIterator iter, int direction) + { + return mesher_[direction].dminus(iter.coordinates()[direction]); + } + + public override double location(FdmLinearOpIterator iter, + int direction) + { + return mesher_[direction].location(iter.coordinates()[direction]); + } + + public override Vector locations(int direction) + { + Vector retVal = new Vector(layout_.size()); + + FdmLinearOpIterator endIter = layout_.end(); + for (FdmLinearOpIterator iter = layout_.begin(); + iter != endIter; ++iter) + { + retVal[iter.index()] = + mesher_[direction].locations()[iter.coordinates()[direction]]; + } + + return retVal; + } + + public List getFdm1dMeshers() + { + return mesher_; + } + + protected static FdmLinearOpLayout getLayoutFromMeshers(List meshers) + { + List dim = new InitializedList(meshers.Count); + for (int i = 0; i < dim.Count; ++i) + { + dim[i] = meshers[i].size(); + } + return new FdmLinearOpLayout(dim); + } + + protected Vector dx_; + protected List> locations_; + protected List mesher_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/Meshers/FdmSimpleProcess1dMesher.cs b/src/QLNet/Methods/Finitedifferences/Meshers/FdmSimpleProcess1dMesher.cs index 3774802ef..346c9bdcb 100644 --- a/src/QLNet/Methods/Finitedifferences/Meshers/FdmSimpleProcess1dMesher.cs +++ b/src/QLNet/Methods/Finitedifferences/Meshers/FdmSimpleProcess1dMesher.cs @@ -1,74 +1,74 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ +*/ using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; namespace QLNet { ///

/// One-dimensional grid mesher - /// - public class FdmSimpleProcess1DMesher : Fdm1dMesher - { - public FdmSimpleProcess1DMesher(int size, - StochasticProcess1D process, - double maturity, int tAvgSteps = 10, - double epsilon = 0.0001, - double? mandatoryPoint = null) - : base(size) - { - locations_ = new InitializedList(locations_.Count, 0.0); - for (int l=1; l<=tAvgSteps; ++l) - { - double t = (maturity*l)/tAvgSteps; - + ///
+ public class FdmSimpleProcess1DMesher : Fdm1dMesher + { + public FdmSimpleProcess1DMesher(int size, + StochasticProcess1D process, + double maturity, int tAvgSteps = 10, + double epsilon = 0.0001, + double? mandatoryPoint = null) + : base(size) + { + locations_ = new InitializedList(locations_.Count, 0.0); + for (int l = 1; l <= tAvgSteps; ++l) + { + double t = (maturity * l) / tAvgSteps; + double mp = (mandatoryPoint != null) ? mandatoryPoint.Value - : process.x0(); + : process.x0(); double qMin = Math.Min(Math.Min(mp, process.x0()), - process.evolve(0, process.x0(), t, - new InverseCumulativeNormal().value(epsilon))); + process.evolve(0, process.x0(), t, + new InverseCumulativeNormal().value(epsilon))); double qMax = Math.Max(Math.Max(mp, process.x0()), - process.evolve(0, process.x0(), t, - new InverseCumulativeNormal().value(1 - epsilon))); - - double dp = (1 - 2 * epsilon) / (size - 1); + process.evolve(0, process.x0(), t, + new InverseCumulativeNormal().value(1 - epsilon))); + + double dp = (1 - 2 * epsilon) / (size - 1); double p = epsilon; locations_[0] += qMin; - - for (int i=1; i < size-1; ++i) + + for (int i = 1; i < size - 1; ++i) { - p += dp; - locations_[i] += process.evolve(0, process.x0(), t, - new InverseCumulativeNormal().value(p)); + p += dp; + locations_[i] += process.evolve(0, process.x0(), t, + new InverseCumulativeNormal().value(p)); } locations_[locations_.Count - 1] += qMax; - } - locations_ = locations_.Select(x => x / tAvgSteps).ToList(); - for (int i=0; i < size-1; ++i) - { - dminus_[i+1] = dplus_[i] = locations_[i+1] - locations_[i]; - } - - dplus_[dplus_.Count - 1] = null; - dminus_[0] = null; + } + locations_ = locations_.Select(x => x / tAvgSteps).ToList(); + for (int i = 0; i < size - 1; ++i) + { + dminus_[i + 1] = dplus_[i] = locations_[i + 1] - locations_[i]; + } + + dplus_[dplus_.Count - 1] = null; + dminus_[0] = null; } } } diff --git a/src/QLNet/Methods/Finitedifferences/Meshers/Uniform1dMesher.cs b/src/QLNet/Methods/Finitedifferences/Meshers/Uniform1dMesher.cs index 11a229fc3..a0e8da5a5 100644 --- a/src/QLNet/Methods/Finitedifferences/Meshers/Uniform1dMesher.cs +++ b/src/QLNet/Methods/Finitedifferences/Meshers/Uniform1dMesher.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Methods/Finitedifferences/Meshers/UniformGridMesher.cs b/src/QLNet/Methods/Finitedifferences/Meshers/UniformGridMesher.cs index 29a0eade8..2999029ce 100644 --- a/src/QLNet/Methods/Finitedifferences/Meshers/UniformGridMesher.cs +++ b/src/QLNet/Methods/Finitedifferences/Meshers/UniformGridMesher.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -26,14 +26,14 @@ namespace QLNet ///
public class UniformGridMesher : FdmMesher { - public UniformGridMesher(FdmLinearOpLayout layout, List> boundaries) - : base(layout) + public UniformGridMesher(FdmLinearOpLayout layout, List < Pair < double?, double? >> boundaries) + : base(layout) { dx_ = new Vector(layout.dim().Count); locations_ = new InitializedList>(layout.dim().Count); Utils.QL_REQUIRE(boundaries.Count == layout.dim().Count, - () => "inconsistent boundaries given"); + () => "inconsistent boundaries given"); for (int i = 0; i < layout.dim().Count; ++i) { @@ -59,7 +59,7 @@ public UniformGridMesher(FdmLinearOpLayout layout, List> } public override double location(FdmLinearOpIterator iter, - int direction) + int direction) { return locations_[direction][iter.coordinates()[direction]]; } @@ -70,8 +70,8 @@ public override Vector locations(int direction) FdmLinearOpIterator endIter = layout_.end(); for (FdmLinearOpIterator iter = layout_.begin(); - iter != endIter; - ++iter) + iter != endIter; + ++iter) { retVal[iter.index()] = locations_[direction][iter.coordinates()[direction]]; } diff --git a/src/QLNet/Methods/Finitedifferences/MixedScheme.cs b/src/QLNet/Methods/Finitedifferences/MixedScheme.cs new file mode 100644 index 000000000..cee8ab538 --- /dev/null +++ b/src/QLNet/Methods/Finitedifferences/MixedScheme.cs @@ -0,0 +1,104 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System.Collections.Generic; + +namespace QLNet +{ + public interface ISchemeFactory + { + IMixedScheme factory(object L, object bcs, object[] additionalInputs = null); + } + + public interface IMixedScheme + { + void step(ref object a, double t); + void setStep(double dt); + } + + //! Mixed (explicit/implicit) scheme for finite difference methods + /*! In this implementation, the passed operator must be derived + from either TimeConstantOperator or TimeDependentOperator. + + \ingroup findiff + */ + public class MixedScheme : IMixedScheme where Operator : IOperator + { + protected Operator L_, I_, explicitPart_, implicitPart_; + protected double dt_; + protected double theta_; + protected List> bcs_; + + // constructors + public MixedScheme() { } // required for generics + public MixedScheme(Operator L, double theta, List> bcs) + { + L_ = (Operator)L.Clone(); + I_ = (Operator)L.identity(L.size()); + dt_ = 0.0; + theta_ = theta; + bcs_ = bcs; + } + + public void step(ref object o, double t) + { + Vector a = (Vector)o; + + int i; + for (i = 0; i < bcs_.Count; i++) + bcs_[i].setTime(t); + if (theta_.IsNotEqual(1.0)) // there is an explicit part + { + if (L_.isTimeDependent()) + { + L_.setTime(t); + explicitPart_ = (Operator)L_.subtract(I_, L_.multiply((1.0 - theta_) * dt_, L_)); + } + for (i = 0; i < bcs_.Count; i++) + bcs_[i].applyBeforeApplying(explicitPart_); + a = explicitPart_.applyTo(a); + for (i = 0; i < bcs_.Count; i++) + bcs_[i].applyAfterApplying(a); + } + if (theta_.IsNotEqual(0.0)) // there is an implicit part + { + if (L_.isTimeDependent()) + { + L_.setTime(t - dt_); + implicitPart_ = (Operator)L_.add(I_, L_.multiply(theta_ * dt_, L_)); + } + for (i = 0; i < bcs_.Count; i++) + bcs_[i].applyBeforeSolving(implicitPart_, a); + a = implicitPart_.solveFor(a); + for (i = 0; i < bcs_.Count; i++) + bcs_[i].applyAfterSolving(a); + } + + o = a; + } + + public void setStep(double dt) + { + dt_ = dt; + if (theta_.IsNotEqual(1.0)) // there is an explicit part + explicitPart_ = (Operator)L_.subtract(I_, L_.multiply((1.0 - theta_) * dt_, L_)); + if (theta_.IsNotEqual(0.0)) // there is an implicit part + implicitPart_ = (Operator)L_.add(I_, L_.multiply(theta_ * dt_, L_)); + } + } +} diff --git a/src/QLNet/Methods/Finitedifferences/OperatorFactory.cs b/src/QLNet/Methods/Finitedifferences/OperatorFactory.cs index d723e3e23..8268aefe8 100644 --- a/src/QLNet/Methods/Finitedifferences/OperatorFactory.cs +++ b/src/QLNet/Methods/Finitedifferences/OperatorFactory.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -30,7 +30,7 @@ namespace QLNet public static class OperatorFactory { public static TridiagonalOperator getOperator(GeneralizedBlackScholesProcess process, Vector grid, - double residualTime, bool timeDependent) + double residualTime, bool timeDependent) { if (timeDependent) //! Black-Scholes-Merton differential operator diff --git a/src/QLNet/Methods/Finitedifferences/Operators/FdmBlackScholesOp.cs b/src/QLNet/Methods/Finitedifferences/Operators/FdmBlackScholesOp.cs index 684275d9b..b7d727209 100644 --- a/src/QLNet/Methods/Finitedifferences/Operators/FdmBlackScholesOp.cs +++ b/src/QLNet/Methods/Finitedifferences/Operators/FdmBlackScholesOp.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,132 +21,144 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class FdmBlackScholesOp : FdmLinearOpComposite - { - public FdmBlackScholesOp(FdmMesher mesher, - GeneralizedBlackScholesProcess bsProcess, - double strike, - bool localVol = false, - double? illegalLocalVolOverwrite = null, - int direction = 0) - { - mesher_ = mesher; - rTS_ = bsProcess.riskFreeRate().currentLink(); - qTS_ = bsProcess.dividendYield().currentLink(); - volTS_ = bsProcess.blackVolatility().currentLink(); - localVol_ = (localVol) ? bsProcess.localVolatility().currentLink() - : null; - x_ = (localVol) ? new Vector(Vector.Exp(mesher.locations(direction))) : null; - dxMap_ = new FirstDerivativeOp(direction, mesher); - dxxMap_= new SecondDerivativeOp(direction, mesher); - mapT_ = new TripleBandLinearOp(direction, mesher); - strike_ = strike; - illegalLocalVolOverwrite_ = illegalLocalVolOverwrite; - direction_ = direction; - } - public override int size() { return 1; } - - //! Time \f$t1 <= t2\f$ is required - public override void setTime(double t1, double t2) - { - double r = rTS_.forwardRate(t1, t2, Compounding.Continuous).rate(); - double q = qTS_.forwardRate(t1, t2, Compounding.Continuous).rate(); - - if (localVol_ != null) + public class FdmBlackScholesOp : FdmLinearOpComposite + { + public FdmBlackScholesOp(FdmMesher mesher, + GeneralizedBlackScholesProcess bsProcess, + double strike, + bool localVol = false, + double? illegalLocalVolOverwrite = null, + int direction = 0) + { + mesher_ = mesher; + rTS_ = bsProcess.riskFreeRate().currentLink(); + qTS_ = bsProcess.dividendYield().currentLink(); + volTS_ = bsProcess.blackVolatility().currentLink(); + localVol_ = (localVol) ? bsProcess.localVolatility().currentLink() + : null; + x_ = (localVol) ? new Vector(Vector.Exp(mesher.locations(direction))) : null; + dxMap_ = new FirstDerivativeOp(direction, mesher); + dxxMap_ = new SecondDerivativeOp(direction, mesher); + mapT_ = new TripleBandLinearOp(direction, mesher); + strike_ = strike; + illegalLocalVolOverwrite_ = illegalLocalVolOverwrite; + direction_ = direction; + } + public override int size() { return 1; } + + //! Time \f$t1 <= t2\f$ is required + public override void setTime(double t1, double t2) + { + double r = rTS_.forwardRate(t1, t2, Compounding.Continuous).rate(); + double q = qTS_.forwardRate(t1, t2, Compounding.Continuous).rate(); + + if (localVol_ != null) + { + FdmLinearOpLayout layout = mesher_.layout(); + FdmLinearOpIterator endIter = layout.end(); + + Vector v = new Vector(layout.size()); + for (FdmLinearOpIterator iter = layout.begin(); + iter != endIter; ++iter) { - FdmLinearOpLayout layout = mesher_.layout(); - FdmLinearOpIterator endIter = layout.end(); - - Vector v = new Vector(layout.size()); - for (FdmLinearOpIterator iter = layout.begin(); - iter != endIter; ++iter) - { - int i = iter.index(); - - if (illegalLocalVolOverwrite_ == null) { - double t = localVol_.localVol(0.5 * (t1 + t2), x_[i], true); - v[i] = t * t; - } - else { - try { - double t = localVol_.localVol(0.5 * (t1 + t2), x_[i], true); - v[i] = t * t; - } catch { - v[i] = illegalLocalVolOverwrite_.Value * illegalLocalVolOverwrite_.Value; - } - - } - } - mapT_.axpyb(r - q - 0.5*v, dxMap_, - dxxMap_.mult(0.5*v), new Vector(1, -r)); - } - else { - double vv - = volTS_.blackForwardVariance(t1, t2, strike_)/(t2-t1); - mapT_.axpyb(new Vector(1, r - q - 0.5*vv), dxMap_, - dxxMap_.mult(0.5*new Vector(mesher_.layout().size(), vv)), - new Vector(1, -r)); + int i = iter.index(); + + if (illegalLocalVolOverwrite_ == null) + { + double t = localVol_.localVol(0.5 * (t1 + t2), x_[i], true); + v[i] = t * t; + } + else + { + try + { + double t = localVol_.localVol(0.5 * (t1 + t2), x_[i], true); + v[i] = t * t; + } + catch + { + v[i] = illegalLocalVolOverwrite_.Value * illegalLocalVolOverwrite_.Value; + } + + } } - } + mapT_.axpyb(r - q - 0.5 * v, dxMap_, + dxxMap_.mult(0.5 * v), new Vector(1, -r)); + } + else + { + double vv + = volTS_.blackForwardVariance(t1, t2, strike_) / (t2 - t1); + mapT_.axpyb(new Vector(1, r - q - 0.5 * vv), dxMap_, + dxxMap_.mult(0.5 * new Vector(mesher_.layout().size(), vv)), + new Vector(1, -r)); + } + } - public override Vector apply(Vector r) - { - return mapT_.apply(r); - } + public override Vector apply(Vector r) + { + return mapT_.apply(r); + } - public override Vector apply_mixed(Vector r) { + public override Vector apply_mixed(Vector r) + { + Vector retVal = new Vector(r.size(), 0.0); + return retVal; + } + + public override Vector apply_direction(int direction, Vector r) + { + if (direction == direction_) + return mapT_.apply(r); + else + { Vector retVal = new Vector(r.size(), 0.0); return retVal; - } - - public override Vector apply_direction(int direction, Vector r) { - if (direction == direction_) - return mapT_.apply(r); - else { - Vector retVal = new Vector(r.size(), 0.0); - return retVal; - } - } - public override Vector solve_splitting(int direction, Vector r, double dt) { - if (direction == direction_) - return mapT_.solve_splitting(r, dt, 1.0); - else { - Vector retVal = new Vector(r); - return retVal; - } - } - public override Vector preconditioner(Vector r, double dt) { return solve_splitting(direction_, r, dt); } - - public override List toMatrixDecomp() - { - List retVal = new InitializedList(1, mapT_.toMatrix()); + } + } + public override Vector solve_splitting(int direction, Vector r, double dt) + { + if (direction == direction_) + return mapT_.solve_splitting(r, dt, 1.0); + else + { + Vector retVal = new Vector(r); return retVal; - } - - #region IOperator interface - public override IOperator identity(int size) { return null; } - public override Vector applyTo(Vector v) { return null; } - public override Vector solveFor(Vector rhs) { return null; } - - public override IOperator multiply(double a, IOperator D) { return null; } - public override IOperator add(IOperator A, IOperator B) { return null; } - public override IOperator subtract(IOperator A, IOperator B) { return null; } - - public override bool isTimeDependent() { return false; } - public override void setTime(double t) { } - public override object Clone() { return this.MemberwiseClone(); } - #endregion - - protected FdmMesher mesher_; - protected YieldTermStructure rTS_, qTS_; - protected BlackVolTermStructure volTS_; - protected LocalVolTermStructure localVol_; - protected Vector x_; - protected FirstDerivativeOp dxMap_; - protected TripleBandLinearOp dxxMap_; - protected TripleBandLinearOp mapT_; - protected double strike_; - protected double? illegalLocalVolOverwrite_; - protected int direction_; - } + } + } + public override Vector preconditioner(Vector r, double dt) { return solve_splitting(direction_, r, dt); } + + public override List toMatrixDecomp() + { + List retVal = new InitializedList(1, mapT_.toMatrix()); + return retVal; + } + + #region IOperator interface + public override IOperator identity(int size) { return null; } + public override Vector applyTo(Vector v) { return null; } + public override Vector solveFor(Vector rhs) { return null; } + + public override IOperator multiply(double a, IOperator D) { return null; } + public override IOperator add + (IOperator A, IOperator B) { return null; } + public override IOperator subtract(IOperator A, IOperator B) { return null; } + + public override bool isTimeDependent() { return false; } + public override void setTime(double t) { } + public override object Clone() { return this.MemberwiseClone(); } + #endregion + + protected FdmMesher mesher_; + protected YieldTermStructure rTS_, qTS_; + protected BlackVolTermStructure volTS_; + protected LocalVolTermStructure localVol_; + protected Vector x_; + protected FirstDerivativeOp dxMap_; + protected TripleBandLinearOp dxxMap_; + protected TripleBandLinearOp mapT_; + protected double strike_; + protected double? illegalLocalVolOverwrite_; + protected int direction_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/Operators/FdmHullWhiteOp.cs b/src/QLNet/Methods/Finitedifferences/Operators/FdmHullWhiteOp.cs index 1f4edc727..c0fc3394c 100644 --- a/src/QLNet/Methods/Finitedifferences/Operators/FdmHullWhiteOp.cs +++ b/src/QLNet/Methods/Finitedifferences/Operators/FdmHullWhiteOp.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,85 +21,91 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class FdmHullWhiteOp : FdmLinearOpComposite - { - public FdmHullWhiteOp(FdmMesher mesher, - HullWhite model, - int direction) - { - x_ = mesher.locations(direction); - dzMap_ = new TripleBandLinearOp(new FirstDerivativeOp(direction, mesher).mult(-1.0 * x_ * model.a()).add( - new SecondDerivativeOp(direction, mesher).mult(0.5 * model.sigma() * model.sigma() - * new Vector(mesher.layout().size(), 1.0)))); - mapT_ = new TripleBandLinearOp(direction, mesher); - direction_ = direction; - model_ = model; - } - public override int size() { return 1; } - - //! Time \f$t1 <= t2\f$ is required - public override void setTime(double t1, double t2) - { - OneFactorModel.ShortRateDynamics dynamics = model_.dynamics(); - - double phi = 0.5* ( dynamics.shortRate(t1, 0.0) - + dynamics.shortRate(t2, 0.0)); - - mapT_.axpyb(new Vector(), dzMap_, dzMap_, -1.0 * (x_ + phi)); - } - - public override Vector apply(Vector r) - { - return mapT_.apply(r); - } + public class FdmHullWhiteOp : FdmLinearOpComposite + { + public FdmHullWhiteOp(FdmMesher mesher, + HullWhite model, + int direction) + { + x_ = mesher.locations(direction); + dzMap_ = new TripleBandLinearOp(new FirstDerivativeOp(direction, mesher).mult(-1.0 * x_ * model.a()).add( + new SecondDerivativeOp(direction, mesher).mult(0.5 * model.sigma() * model.sigma() + * new Vector(mesher.layout().size(), 1.0)))); + mapT_ = new TripleBandLinearOp(direction, mesher); + direction_ = direction; + model_ = model; + } + public override int size() { return 1; } + + //! Time \f$t1 <= t2\f$ is required + public override void setTime(double t1, double t2) + { + OneFactorModel.ShortRateDynamics dynamics = model_.dynamics(); + + double phi = 0.5 * (dynamics.shortRate(t1, 0.0) + + dynamics.shortRate(t2, 0.0)); + + mapT_.axpyb(new Vector(), dzMap_, dzMap_, -1.0 * (x_ + phi)); + } + + public override Vector apply(Vector r) + { + return mapT_.apply(r); + } - public override Vector apply_mixed(Vector r) { + public override Vector apply_mixed(Vector r) + { + Vector retVal = new Vector(r.size(), 0.0); + return retVal; + } + + public override Vector apply_direction(int direction, Vector r) + { + if (direction == direction_) + return mapT_.apply(r); + else + { Vector retVal = new Vector(r.size(), 0.0); return retVal; - } - - public override Vector apply_direction(int direction, Vector r) { - if (direction == direction_) - return mapT_.apply(r); - else { - Vector retVal = new Vector(r.size(), 0.0); - return retVal; - } - } - public override Vector solve_splitting(int direction, Vector r, double s) { - if (direction == direction_) - return mapT_.solve_splitting(r, s, 1.0); - else { - Vector retVal = new Vector(r.size(), 0.0); - return retVal; - } - } - public override Vector preconditioner(Vector r, double s) { return solve_splitting(direction_, r, s); } - - public override List toMatrixDecomp() - { - List retVal = new InitializedList(1, mapT_.toMatrix()); + } + } + public override Vector solve_splitting(int direction, Vector r, double s) + { + if (direction == direction_) + return mapT_.solve_splitting(r, s, 1.0); + else + { + Vector retVal = new Vector(r.size(), 0.0); return retVal; - } - - #region IOperator interface - public override IOperator identity(int size) { return null; } - public override Vector applyTo(Vector v) { return new Vector(); } - public override Vector solveFor(Vector rhs) { return new Vector(); } - - public override IOperator multiply(double a, IOperator D) { return null; } - public override IOperator add(IOperator A, IOperator B) { return null; } - public override IOperator subtract(IOperator A, IOperator B) { return null; } - - public override bool isTimeDependent() { return false; } - public override void setTime(double t) { } - public override object Clone() { return this.MemberwiseClone(); } - #endregion - - protected HullWhite model_; - protected Vector x_; - protected TripleBandLinearOp dzMap_; - protected TripleBandLinearOp mapT_; - protected int direction_; - } + } + } + public override Vector preconditioner(Vector r, double s) { return solve_splitting(direction_, r, s); } + + public override List toMatrixDecomp() + { + List retVal = new InitializedList(1, mapT_.toMatrix()); + return retVal; + } + + #region IOperator interface + public override IOperator identity(int size) { return null; } + public override Vector applyTo(Vector v) { return new Vector(); } + public override Vector solveFor(Vector rhs) { return new Vector(); } + + public override IOperator multiply(double a, IOperator D) { return null; } + public override IOperator add + (IOperator A, IOperator B) { return null; } + public override IOperator subtract(IOperator A, IOperator B) { return null; } + + public override bool isTimeDependent() { return false; } + public override void setTime(double t) { } + public override object Clone() { return this.MemberwiseClone(); } + #endregion + + protected HullWhite model_; + protected Vector x_; + protected TripleBandLinearOp dzMap_; + protected TripleBandLinearOp mapT_; + protected int direction_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/Operators/FdmLinearOp.cs b/src/QLNet/Methods/Finitedifferences/Operators/FdmLinearOp.cs index f5420c269..827ff2c8e 100644 --- a/src/QLNet/Methods/Finitedifferences/Operators/FdmLinearOp.cs +++ b/src/QLNet/Methods/Finitedifferences/Operators/FdmLinearOp.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,24 +20,25 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public abstract class FdmLinearOp : IOperator - { - public abstract Vector apply(Vector r); - public abstract SparseMatrix toMatrix(); - - //IOperator interface - public abstract int size(); - public abstract IOperator identity(int size); - public abstract Vector applyTo(Vector v); - public abstract Vector solveFor(Vector rhs); - - public abstract IOperator multiply(double a, IOperator D); - public abstract IOperator add(IOperator A, IOperator B); - public abstract IOperator subtract(IOperator A, IOperator B); - - public abstract bool isTimeDependent(); - public abstract void setTime(double t); - - public abstract object Clone(); - } + public abstract class FdmLinearOp : IOperator + { + public abstract Vector apply(Vector r); + public abstract SparseMatrix toMatrix(); + + //IOperator interface + public abstract int size(); + public abstract IOperator identity(int size); + public abstract Vector applyTo(Vector v); + public abstract Vector solveFor(Vector rhs); + + public abstract IOperator multiply(double a, IOperator D); + public abstract IOperator add + (IOperator A, IOperator B); + public abstract IOperator subtract(IOperator A, IOperator B); + + public abstract bool isTimeDependent(); + public abstract void setTime(double t); + + public abstract object Clone(); + } } diff --git a/src/QLNet/Methods/Finitedifferences/Operators/FdmLinearOpComposite.cs b/src/QLNet/Methods/Finitedifferences/Operators/FdmLinearOpComposite.cs index d47123c9e..11580da87 100644 --- a/src/QLNet/Methods/Finitedifferences/Operators/FdmLinearOpComposite.cs +++ b/src/QLNet/Methods/Finitedifferences/Operators/FdmLinearOpComposite.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,26 +22,27 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public abstract class FdmLinearOpComposite : FdmLinearOp - { - //! Time \f$t1 <= t2\f$ is required - public abstract void setTime(double t1, double t2); - - public abstract Vector apply_mixed(Vector r); - - public abstract Vector apply_direction(int direction, Vector r); - public abstract Vector solve_splitting(int direction, Vector r, double s); - public abstract Vector preconditioner(Vector r, double s); - - public virtual List toMatrixDecomp() - { - return null; - } - - public override SparseMatrix toMatrix() { - List dcmp = toMatrixDecomp(); - SparseMatrix retVal = dcmp.accumulate(1, dcmp.Count, dcmp.First(), (a, b) => a + b); - return retVal; - } - } + public abstract class FdmLinearOpComposite : FdmLinearOp + { + //! Time \f$t1 <= t2\f$ is required + public abstract void setTime(double t1, double t2); + + public abstract Vector apply_mixed(Vector r); + + public abstract Vector apply_direction(int direction, Vector r); + public abstract Vector solve_splitting(int direction, Vector r, double s); + public abstract Vector preconditioner(Vector r, double s); + + public virtual List toMatrixDecomp() + { + return null; + } + + public override SparseMatrix toMatrix() + { + List dcmp = toMatrixDecomp(); + SparseMatrix retVal = dcmp.accumulate(1, dcmp.Count, dcmp.First(), (a, b) => a + b); + return retVal; + } + } } diff --git a/src/QLNet/Methods/Finitedifferences/Operators/FdmLinearOpIterator.cs b/src/QLNet/Methods/Finitedifferences/Operators/FdmLinearOpIterator.cs index d58d51ee9..aa74acde4 100644 --- a/src/QLNet/Methods/Finitedifferences/Operators/FdmLinearOpIterator.cs +++ b/src/QLNet/Methods/Finitedifferences/Operators/FdmLinearOpIterator.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Methods/Finitedifferences/Operators/FdmLinearOpLayout.cs b/src/QLNet/Methods/Finitedifferences/Operators/FdmLinearOpLayout.cs index 39706b54d..ff02e850e 100644 --- a/src/QLNet/Methods/Finitedifferences/Operators/FdmLinearOpLayout.cs +++ b/src/QLNet/Methods/Finitedifferences/Operators/FdmLinearOpLayout.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,110 +22,120 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class FdmLinearOpLayout - { - public FdmLinearOpLayout(List dim) { - dim_ = dim; - spacing_ = new InitializedList(dim.Count); - spacing_[0] = 1; - - for (int i = 0; i < dim.Count - 1; i++) - spacing_[i + 1] = dim[i] * spacing_[i]; - - size_ = spacing_.Last() * dim.Last(); - } - - public FdmLinearOpIterator begin() { - return new FdmLinearOpIterator(dim_); - } - - public FdmLinearOpIterator end() { - return new FdmLinearOpIterator(size_); - } - - public List dim() { - return dim_; - } - - public List spacing() - { - return spacing_; - } - - public int size() - { - return size_; - } - - public int index(List coordinates) { - return coordinates.inner_product(0, coordinates.Count, 0, spacing_, 0); - } - - public int neighbourhood(FdmLinearOpIterator iterator, int i, int offset) { - int myIndex = iterator.index() - iterator.coordinates()[i] * spacing_[i]; - - int coorOffset = iterator.coordinates()[i] + offset; - - if (coorOffset < 0) - { - coorOffset = -coorOffset; - } - else if (coorOffset >= dim_[i]) - { - coorOffset = 2 * (dim_[i] - 1) - coorOffset; - } - return myIndex + coorOffset * spacing_[i]; - } - - public int neighbourhood(FdmLinearOpIterator iterator, - int i1, int offset1, - int i2, int offset2) { - int myIndex = iterator.index() - - iterator.coordinates()[i1] * spacing_[i1] - - iterator.coordinates()[i2] * spacing_[i2]; - - int coorOffset1 = iterator.coordinates()[i1] + offset1; - if (coorOffset1 < 0) - { - coorOffset1 = -coorOffset1; - } - else if (coorOffset1 >= dim_[i1]) - { - coorOffset1 = 2 * (dim_[i1] - 1) - coorOffset1; - } - - int coorOffset2 = iterator.coordinates()[i2] + offset2; - if (coorOffset2 < 0) - { - coorOffset2 = -coorOffset2; - } - else if (coorOffset2 >= dim_[i2]) - { - coorOffset2 = 2 * (dim_[i2] - 1) - coorOffset2; - } - - return myIndex + coorOffset1 * spacing_[i1] + coorOffset2 * spacing_[i2]; - } - - public FdmLinearOpIterator iter_neighbourhood(FdmLinearOpIterator iterator, int i, int offset) { - List coordinates = iterator.coordinates(); - - int coorOffset = coordinates[i] + offset; - if (coorOffset < 0) { - coorOffset=-coorOffset; - } - else if (coorOffset >= dim_[i]) { - coorOffset = 2*(dim_[i]-1) - coorOffset; - } - coordinates[i] = coorOffset; - - FdmLinearOpIterator retVal = new FdmLinearOpIterator(dim_, coordinates, - index(coordinates)); - - return retVal; - } - - protected List dim_, spacing_; - protected int size_; - } + public class FdmLinearOpLayout + { + public FdmLinearOpLayout(List dim) + { + dim_ = dim; + spacing_ = new InitializedList(dim.Count); + spacing_[0] = 1; + + for (int i = 0; i < dim.Count - 1; i++) + spacing_[i + 1] = dim[i] * spacing_[i]; + + size_ = spacing_.Last() * dim.Last(); + } + + public FdmLinearOpIterator begin() + { + return new FdmLinearOpIterator(dim_); + } + + public FdmLinearOpIterator end() + { + return new FdmLinearOpIterator(size_); + } + + public List dim() + { + return dim_; + } + + public List spacing() + { + return spacing_; + } + + public int size() + { + return size_; + } + + public int index(List coordinates) + { + return coordinates.inner_product(0, coordinates.Count, 0, spacing_, 0); + } + + public int neighbourhood(FdmLinearOpIterator iterator, int i, int offset) + { + int myIndex = iterator.index() - iterator.coordinates()[i] * spacing_[i]; + + int coorOffset = iterator.coordinates()[i] + offset; + + if (coorOffset < 0) + { + coorOffset = -coorOffset; + } + else if (coorOffset >= dim_[i]) + { + coorOffset = 2 * (dim_[i] - 1) - coorOffset; + } + return myIndex + coorOffset * spacing_[i]; + } + + public int neighbourhood(FdmLinearOpIterator iterator, + int i1, int offset1, + int i2, int offset2) + { + int myIndex = iterator.index() + - iterator.coordinates()[i1] * spacing_[i1] + - iterator.coordinates()[i2] * spacing_[i2]; + + int coorOffset1 = iterator.coordinates()[i1] + offset1; + if (coorOffset1 < 0) + { + coorOffset1 = -coorOffset1; + } + else if (coorOffset1 >= dim_[i1]) + { + coorOffset1 = 2 * (dim_[i1] - 1) - coorOffset1; + } + + int coorOffset2 = iterator.coordinates()[i2] + offset2; + if (coorOffset2 < 0) + { + coorOffset2 = -coorOffset2; + } + else if (coorOffset2 >= dim_[i2]) + { + coorOffset2 = 2 * (dim_[i2] - 1) - coorOffset2; + } + + return myIndex + coorOffset1 * spacing_[i1] + coorOffset2 * spacing_[i2]; + } + + public FdmLinearOpIterator iter_neighbourhood(FdmLinearOpIterator iterator, int i, int offset) + { + List coordinates = iterator.coordinates(); + + int coorOffset = coordinates[i] + offset; + if (coorOffset < 0) + { + coorOffset = -coorOffset; + } + else if (coorOffset >= dim_[i]) + { + coorOffset = 2 * (dim_[i] - 1) - coorOffset; + } + coordinates[i] = coorOffset; + + FdmLinearOpIterator retVal = new FdmLinearOpIterator(dim_, coordinates, + index(coordinates)); + + return retVal; + } + + protected List dim_, spacing_; + protected int size_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/Operators/FirstDerivativeOp.cs b/src/QLNet/Methods/Finitedifferences/Operators/FirstDerivativeOp.cs index 1043b8c6e..f63e0a303 100644 --- a/src/QLNet/Methods/Finitedifferences/Operators/FirstDerivativeOp.cs +++ b/src/QLNet/Methods/Finitedifferences/Operators/FirstDerivativeOp.cs @@ -1,17 +1,17 @@ -/* +/* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,51 +22,51 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class FirstDerivativeOp : TripleBandLinearOp - { - public FirstDerivativeOp(FirstDerivativeOp rhs) - : base (rhs.direction_, rhs.mesher_) - { - lower_ = rhs.lower_; - diag_ = rhs.diag_; - upper_ = rhs.upper_; - } - public FirstDerivativeOp(int direction, FdmMesher mesher) - : base(direction, mesher) - { - FdmLinearOpLayout layout = mesher.layout(); - FdmLinearOpIterator endIter = layout.end(); + public class FirstDerivativeOp : TripleBandLinearOp + { + public FirstDerivativeOp(FirstDerivativeOp rhs) + : base(rhs.direction_, rhs.mesher_) + { + lower_ = rhs.lower_; + diag_ = rhs.diag_; + upper_ = rhs.upper_; + } + public FirstDerivativeOp(int direction, FdmMesher mesher) + : base(direction, mesher) + { + FdmLinearOpLayout layout = mesher.layout(); + FdmLinearOpIterator endIter = layout.end(); - for (FdmLinearOpIterator iter = layout.begin(); iter != endIter; ++iter) - { - int i = iter.index(); - double? hm = mesher.dminus(iter, direction_); - double? hp = mesher.dplus(iter, direction_); + for (FdmLinearOpIterator iter = layout.begin(); iter != endIter; ++iter) + { + int i = iter.index(); + double? hm = mesher.dminus(iter, direction_); + double? hp = mesher.dplus(iter, direction_); - double? zetam1 = hm * (hm + hp); - double? zeta0 = hm * hp; - double? zetap1 = hp * (hm + hp); + double? zetam1 = hm * (hm + hp); + double? zeta0 = hm * hp; + double? zetap1 = hp * (hm + hp); - if (iter.coordinates()[direction_] == 0) - { - //upwinding scheme - lower_[i] = 0.0; - diag_[i] = -(upper_[i] = 1 / hp.Value); - } - else if (iter.coordinates()[direction_] - == layout.dim()[direction] - 1) - { - // downwinding scheme - lower_[i] = -(diag_[i] = 1 / hm.Value); - upper_[i] = 0.0; - } - else - { - lower_[i] = -hp.Value / zetam1.Value; - diag_[i] = (hp.Value - hm.Value) / zeta0.Value; - upper_[i] = hm.Value / zetap1.Value; - } + if (iter.coordinates()[direction_] == 0) + { + //upwinding scheme + lower_[i] = 0.0; + diag_[i] = -(upper_[i] = 1 / hp.Value); + } + else if (iter.coordinates()[direction_] + == layout.dim()[direction] - 1) + { + // downwinding scheme + lower_[i] = -(diag_[i] = 1 / hm.Value); + upper_[i] = 0.0; + } + else + { + lower_[i] = -hp.Value / zetam1.Value; + diag_[i] = (hp.Value - hm.Value) / zeta0.Value; + upper_[i] = hm.Value / zetap1.Value; } - } - } + } + } + } } diff --git a/src/QLNet/Methods/Finitedifferences/Operators/NinePointLinearOp.cs b/src/QLNet/Methods/Finitedifferences/Operators/NinePointLinearOp.cs index cfe39e747..73682332b 100644 --- a/src/QLNet/Methods/Finitedifferences/Operators/NinePointLinearOp.cs +++ b/src/QLNet/Methods/Finitedifferences/Operators/NinePointLinearOp.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,194 +21,198 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class NinePointLinearOp : FdmLinearOp - { - public NinePointLinearOp(int d0, int d1, FdmMesher mesher) - { - d0_ = d0; - d1_ = d1; - i00_ = new InitializedList(mesher.layout().size()); - i10_ = new InitializedList(mesher.layout().size()); - i20_ = new InitializedList(mesher.layout().size()); - i01_ = new InitializedList(mesher.layout().size()); - i21_ = new InitializedList(mesher.layout().size()); - i02_ = new InitializedList(mesher.layout().size()); - i12_ = new InitializedList(mesher.layout().size()); - i22_ = new InitializedList(mesher.layout().size()); - a00_ = new InitializedList(mesher.layout().size()); - a10_ = new InitializedList(mesher.layout().size()); - a20_ = new InitializedList(mesher.layout().size()); - a01_ = new InitializedList(mesher.layout().size()); - a11_ = new InitializedList(mesher.layout().size()); - a21_ = new InitializedList(mesher.layout().size()); - a02_ = new InitializedList(mesher.layout().size()); - a12_ = new InitializedList(mesher.layout().size()); - a22_ = new InitializedList(mesher.layout().size()); - mesher_ = mesher; - - Utils.QL_REQUIRE(d0_ != d1_ - && d0_ < mesher.layout().dim().Count - && d1_ < mesher.layout().dim().Count, - () => "inconsistent derivative directions"); - - FdmLinearOpLayout layout = mesher.layout(); - FdmLinearOpIterator endIter = layout.end(); - - for (FdmLinearOpIterator iter = layout.begin(); iter != endIter; ++iter) - { - int i = iter.index(); - - i10_[i] = layout.neighbourhood(iter, d1_, -1); - i01_[i] = layout.neighbourhood(iter, d0_, -1); - i21_[i] = layout.neighbourhood(iter, d0_, 1); - i12_[i] = layout.neighbourhood(iter, d1_, 1); - i00_[i] = layout.neighbourhood(iter, d0_, -1, d1_, -1); - i20_[i] = layout.neighbourhood(iter, d0_, 1, d1_, -1); - i02_[i] = layout.neighbourhood(iter, d0_, -1, d1_, 1); - i22_[i] = layout.neighbourhood(iter, d0_, 1, d1_, 1); - } - } - public NinePointLinearOp(NinePointLinearOp m) - { - d0_ = m.d0_; - d1_ = m.d1_; - i00_ = new InitializedList(m.mesher_.layout().size()); - i10_ = new InitializedList(m.mesher_.layout().size()); - i20_ = new InitializedList(m.mesher_.layout().size()); - i01_ = new InitializedList(m.mesher_.layout().size()); - i21_ = new InitializedList(m.mesher_.layout().size()); - i02_ = new InitializedList(m.mesher_.layout().size()); - i12_ = new InitializedList(m.mesher_.layout().size()); - i22_ = new InitializedList(m.mesher_.layout().size()); - a00_ = new InitializedList(m.mesher_.layout().size()); - a10_ = new InitializedList(m.mesher_.layout().size()); - a20_ = new InitializedList(m.mesher_.layout().size()); - a01_ = new InitializedList(m.mesher_.layout().size()); - a11_ = new InitializedList(m.mesher_.layout().size()); - a21_ = new InitializedList(m.mesher_.layout().size()); - a02_ = new InitializedList(m.mesher_.layout().size()); - a12_ = new InitializedList(m.mesher_.layout().size()); - a22_ = new InitializedList(m.mesher_.layout().size()); - mesher_ = m.mesher_; - - m.i00_.copy(0, m.i00_.Count, 0, i00_); - m.i10_.copy(0, m.i10_.Count, 0, i10_); - m.i20_.copy(0, m.i20_.Count, 0, i20_); - m.i01_.copy(0, m.i01_.Count, 0, i01_); - m.i21_.copy(0, m.i21_.Count, 0, i21_); - m.i02_.copy(0, m.i02_.Count, 0, i02_); - m.i12_.copy(0, m.i12_.Count, 0, i12_); - m.i22_.copy(0, m.i22_.Count, 0, i22_); - m.a00_.copy(0, m.a00_.Count, 0, a00_); - m.a10_.copy(0, m.a10_.Count, 0, a10_); - m.a20_.copy(0, m.a20_.Count, 0, a20_); - m.a01_.copy(0, m.a01_.Count, 0, a01_); - m.a11_.copy(0, m.a11_.Count, 0, a11_); - m.a21_.copy(0, m.a21_.Count, 0, a21_); - m.a02_.copy(0, m.a02_.Count, 0, a02_); - m.a12_.copy(0, m.a12_.Count, 0, a12_); - m.a22_.copy(0, m.a22_.Count, 0, a22_); - } - - public override Vector apply(Vector r) - { - FdmLinearOpLayout index=mesher_.layout(); - Utils.QL_REQUIRE(r.size() == index.size(), () => "inconsistent length of r " - + r.size() + " vs " + index.size()); - - Vector retVal = new Vector(r.size()); - - //#pragma omp parallel for - for (int i=0; i < retVal.size(); ++i) { - retVal[i] = a00_[i]*r[i00_[i]] - + a01_[i]*r[i01_[i]] - + a02_[i]*r[i02_[i]] - + a10_[i]*r[i10_[i]] - + a11_[i]*r[i] - + a12_[i]*r[i12_[i]] - + a20_[i]*r[i20_[i]] - + a21_[i]*r[i21_[i]] - + a22_[i]*r[i22_[i]]; - } - return retVal; - } - public NinePointLinearOp mult(Vector r) - { - NinePointLinearOp retVal = new NinePointLinearOp(d0_, d1_, mesher_); - int size = mesher_.layout().size(); - - //#pragma omp parallel for - for (int i=0; i < size; ++i) { - double s = r[i]; - retVal.a11_[i]=a11_[i]*s; retVal.a00_[i]=a00_[i]*s; - retVal.a01_[i]=a01_[i]*s; retVal.a02_[i]=a02_[i]*s; - retVal.a10_[i]=a10_[i]*s; retVal.a20_[i]=a20_[i]*s; - retVal.a21_[i]=a21_[i]*s; retVal.a12_[i]=a12_[i]*s; - retVal.a22_[i]=a22_[i]*s; - } - - return retVal; - } - - public override SparseMatrix toMatrix() - { - FdmLinearOpLayout index = mesher_.layout(); - int n = index.size(); - - SparseMatrix retVal = new SparseMatrix(n, n); - for (int i=0; i < index.size(); ++i) { - retVal[i, i00_[i]] += a00_[i]; - retVal[i, i01_[i]] += a01_[i]; - retVal[i, i02_[i]] += a02_[i]; - retVal[i, i10_[i]] += a10_[i]; - retVal[i, i ] += a11_[i]; - retVal[i, i12_[i]] += a12_[i]; - retVal[i, i20_[i]] += a20_[i]; - retVal[i, i21_[i]] += a21_[i]; - retVal[i, i22_[i]] += a22_[i]; - } - - return retVal; - } - - public void swap(NinePointLinearOp m) - { - Utils.swap(ref d0_, ref m.d0_); - Utils.swap(ref d1_, ref m.d1_); - - Utils.swap(ref i00_, ref m.i00_); Utils.swap(ref i10_, ref m.i10_); Utils.swap(ref i20_, ref m.i20_); - Utils.swap(ref i01_, ref m.i01_); Utils.swap(ref i21_, ref m.i21_); Utils.swap(ref i02_, ref m.i02_); - Utils.swap(ref i12_,ref m.i12_); Utils.swap(ref i22_, ref m.i22_); - Utils.swap(ref a00_,ref m.a00_); Utils.swap(ref a10_, ref m.a10_); Utils.swap(ref a20_, ref m.a20_); - Utils.swap(ref a01_, ref m.a01_); Utils.swap(ref a21_, ref m.a21_); Utils.swap(ref a02_, ref m.a02_); - Utils.swap(ref a12_, ref m.a12_); Utils.swap(ref a22_, ref m.a22_); Utils.swap(ref a11_, ref m.a11_); - - Utils.swap(ref mesher_, ref m.mesher_); - } - - #region IOperator interface - public override int size() { return 0; } - public override IOperator identity(int size) { return null; } - public override Vector applyTo(Vector v) { return new Vector(); } - public override Vector solveFor(Vector rhs) { return new Vector(); } - - public override IOperator multiply(double a, IOperator D) { return null; } - public override IOperator add(IOperator A, IOperator B) { return null; } - public override IOperator subtract(IOperator A, IOperator B) { return null; } - - public override bool isTimeDependent() { return false; } - public override void setTime(double t) { } - public override object Clone() { return this.MemberwiseClone(); } - #endregion - - protected int d0_, d1_; - protected List i00_, i10_, i20_; - protected List i01_, i21_; - protected List i02_, i12_, i22_; - protected List a00_, a10_, a20_; - protected List a01_, a11_, a21_; - protected List a02_, a12_, a22_; - - protected FdmMesher mesher_; - } + public class NinePointLinearOp : FdmLinearOp + { + public NinePointLinearOp(int d0, int d1, FdmMesher mesher) + { + d0_ = d0; + d1_ = d1; + i00_ = new InitializedList(mesher.layout().size()); + i10_ = new InitializedList(mesher.layout().size()); + i20_ = new InitializedList(mesher.layout().size()); + i01_ = new InitializedList(mesher.layout().size()); + i21_ = new InitializedList(mesher.layout().size()); + i02_ = new InitializedList(mesher.layout().size()); + i12_ = new InitializedList(mesher.layout().size()); + i22_ = new InitializedList(mesher.layout().size()); + a00_ = new InitializedList(mesher.layout().size()); + a10_ = new InitializedList(mesher.layout().size()); + a20_ = new InitializedList(mesher.layout().size()); + a01_ = new InitializedList(mesher.layout().size()); + a11_ = new InitializedList(mesher.layout().size()); + a21_ = new InitializedList(mesher.layout().size()); + a02_ = new InitializedList(mesher.layout().size()); + a12_ = new InitializedList(mesher.layout().size()); + a22_ = new InitializedList(mesher.layout().size()); + mesher_ = mesher; + + Utils.QL_REQUIRE(d0_ != d1_ + && d0_ < mesher.layout().dim().Count + && d1_ < mesher.layout().dim().Count, + () => "inconsistent derivative directions"); + + FdmLinearOpLayout layout = mesher.layout(); + FdmLinearOpIterator endIter = layout.end(); + + for (FdmLinearOpIterator iter = layout.begin(); iter != endIter; ++iter) + { + int i = iter.index(); + + i10_[i] = layout.neighbourhood(iter, d1_, -1); + i01_[i] = layout.neighbourhood(iter, d0_, -1); + i21_[i] = layout.neighbourhood(iter, d0_, 1); + i12_[i] = layout.neighbourhood(iter, d1_, 1); + i00_[i] = layout.neighbourhood(iter, d0_, -1, d1_, -1); + i20_[i] = layout.neighbourhood(iter, d0_, 1, d1_, -1); + i02_[i] = layout.neighbourhood(iter, d0_, -1, d1_, 1); + i22_[i] = layout.neighbourhood(iter, d0_, 1, d1_, 1); + } + } + public NinePointLinearOp(NinePointLinearOp m) + { + d0_ = m.d0_; + d1_ = m.d1_; + i00_ = new InitializedList(m.mesher_.layout().size()); + i10_ = new InitializedList(m.mesher_.layout().size()); + i20_ = new InitializedList(m.mesher_.layout().size()); + i01_ = new InitializedList(m.mesher_.layout().size()); + i21_ = new InitializedList(m.mesher_.layout().size()); + i02_ = new InitializedList(m.mesher_.layout().size()); + i12_ = new InitializedList(m.mesher_.layout().size()); + i22_ = new InitializedList(m.mesher_.layout().size()); + a00_ = new InitializedList(m.mesher_.layout().size()); + a10_ = new InitializedList(m.mesher_.layout().size()); + a20_ = new InitializedList(m.mesher_.layout().size()); + a01_ = new InitializedList(m.mesher_.layout().size()); + a11_ = new InitializedList(m.mesher_.layout().size()); + a21_ = new InitializedList(m.mesher_.layout().size()); + a02_ = new InitializedList(m.mesher_.layout().size()); + a12_ = new InitializedList(m.mesher_.layout().size()); + a22_ = new InitializedList(m.mesher_.layout().size()); + mesher_ = m.mesher_; + + m.i00_.copy(0, m.i00_.Count, 0, i00_); + m.i10_.copy(0, m.i10_.Count, 0, i10_); + m.i20_.copy(0, m.i20_.Count, 0, i20_); + m.i01_.copy(0, m.i01_.Count, 0, i01_); + m.i21_.copy(0, m.i21_.Count, 0, i21_); + m.i02_.copy(0, m.i02_.Count, 0, i02_); + m.i12_.copy(0, m.i12_.Count, 0, i12_); + m.i22_.copy(0, m.i22_.Count, 0, i22_); + m.a00_.copy(0, m.a00_.Count, 0, a00_); + m.a10_.copy(0, m.a10_.Count, 0, a10_); + m.a20_.copy(0, m.a20_.Count, 0, a20_); + m.a01_.copy(0, m.a01_.Count, 0, a01_); + m.a11_.copy(0, m.a11_.Count, 0, a11_); + m.a21_.copy(0, m.a21_.Count, 0, a21_); + m.a02_.copy(0, m.a02_.Count, 0, a02_); + m.a12_.copy(0, m.a12_.Count, 0, a12_); + m.a22_.copy(0, m.a22_.Count, 0, a22_); + } + + public override Vector apply(Vector r) + { + FdmLinearOpLayout index = mesher_.layout(); + Utils.QL_REQUIRE(r.size() == index.size(), () => "inconsistent length of r " + + r.size() + " vs " + index.size()); + + Vector retVal = new Vector(r.size()); + + //#pragma omp parallel for + for (int i = 0; i < retVal.size(); ++i) + { + retVal[i] = a00_[i] * r[i00_[i]] + + a01_[i] * r[i01_[i]] + + a02_[i] * r[i02_[i]] + + a10_[i] * r[i10_[i]] + + a11_[i] * r[i] + + a12_[i] * r[i12_[i]] + + a20_[i] * r[i20_[i]] + + a21_[i] * r[i21_[i]] + + a22_[i] * r[i22_[i]]; + } + return retVal; + } + public NinePointLinearOp mult(Vector r) + { + NinePointLinearOp retVal = new NinePointLinearOp(d0_, d1_, mesher_); + int size = mesher_.layout().size(); + + //#pragma omp parallel for + for (int i = 0; i < size; ++i) + { + double s = r[i]; + retVal.a11_[i] = a11_[i] * s; retVal.a00_[i] = a00_[i] * s; + retVal.a01_[i] = a01_[i] * s; retVal.a02_[i] = a02_[i] * s; + retVal.a10_[i] = a10_[i] * s; retVal.a20_[i] = a20_[i] * s; + retVal.a21_[i] = a21_[i] * s; retVal.a12_[i] = a12_[i] * s; + retVal.a22_[i] = a22_[i] * s; + } + + return retVal; + } + + public override SparseMatrix toMatrix() + { + FdmLinearOpLayout index = mesher_.layout(); + int n = index.size(); + + SparseMatrix retVal = new SparseMatrix(n, n); + for (int i = 0; i < index.size(); ++i) + { + retVal[i, i00_[i]] += a00_[i]; + retVal[i, i01_[i]] += a01_[i]; + retVal[i, i02_[i]] += a02_[i]; + retVal[i, i10_[i]] += a10_[i]; + retVal[i, i ] += a11_[i]; + retVal[i, i12_[i]] += a12_[i]; + retVal[i, i20_[i]] += a20_[i]; + retVal[i, i21_[i]] += a21_[i]; + retVal[i, i22_[i]] += a22_[i]; + } + + return retVal; + } + + public void swap(NinePointLinearOp m) + { + Utils.swap(ref d0_, ref m.d0_); + Utils.swap(ref d1_, ref m.d1_); + + Utils.swap(ref i00_, ref m.i00_); Utils.swap(ref i10_, ref m.i10_); Utils.swap(ref i20_, ref m.i20_); + Utils.swap(ref i01_, ref m.i01_); Utils.swap(ref i21_, ref m.i21_); Utils.swap(ref i02_, ref m.i02_); + Utils.swap(ref i12_, ref m.i12_); Utils.swap(ref i22_, ref m.i22_); + Utils.swap(ref a00_, ref m.a00_); Utils.swap(ref a10_, ref m.a10_); Utils.swap(ref a20_, ref m.a20_); + Utils.swap(ref a01_, ref m.a01_); Utils.swap(ref a21_, ref m.a21_); Utils.swap(ref a02_, ref m.a02_); + Utils.swap(ref a12_, ref m.a12_); Utils.swap(ref a22_, ref m.a22_); Utils.swap(ref a11_, ref m.a11_); + + Utils.swap(ref mesher_, ref m.mesher_); + } + + #region IOperator interface + public override int size() { return 0; } + public override IOperator identity(int size) { return null; } + public override Vector applyTo(Vector v) { return new Vector(); } + public override Vector solveFor(Vector rhs) { return new Vector(); } + + public override IOperator multiply(double a, IOperator D) { return null; } + public override IOperator add + (IOperator A, IOperator B) { return null; } + public override IOperator subtract(IOperator A, IOperator B) { return null; } + + public override bool isTimeDependent() { return false; } + public override void setTime(double t) { } + public override object Clone() { return this.MemberwiseClone(); } + #endregion + + protected int d0_, d1_; + protected List i00_, i10_, i20_; + protected List i01_, i21_; + protected List i02_, i12_, i22_; + protected List a00_, a10_, a20_; + protected List a01_, a11_, a21_; + protected List a02_, a12_, a22_; + + protected FdmMesher mesher_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/Operators/SecondDerivativeOp.cs b/src/QLNet/Methods/Finitedifferences/Operators/SecondDerivativeOp.cs index f6653ef07..6c93d24b3 100644 --- a/src/QLNet/Methods/Finitedifferences/Operators/SecondDerivativeOp.cs +++ b/src/QLNet/Methods/Finitedifferences/Operators/SecondDerivativeOp.cs @@ -1,17 +1,17 @@ -/* +/* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,43 +22,43 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class SecondDerivativeOp : TripleBandLinearOp - { - public SecondDerivativeOp(SecondDerivativeOp rhs) - : base (rhs.direction_, rhs.mesher_) - { - lower_ = rhs.lower_; - diag_ = rhs.diag_; - upper_ = rhs.upper_; - } - public SecondDerivativeOp(int direction, FdmMesher mesher) - : base(direction, mesher) - { - FdmLinearOpLayout layout = mesher.layout(); - FdmLinearOpIterator endIter = layout.end(); + public class SecondDerivativeOp : TripleBandLinearOp + { + public SecondDerivativeOp(SecondDerivativeOp rhs) + : base(rhs.direction_, rhs.mesher_) + { + lower_ = rhs.lower_; + diag_ = rhs.diag_; + upper_ = rhs.upper_; + } + public SecondDerivativeOp(int direction, FdmMesher mesher) + : base(direction, mesher) + { + FdmLinearOpLayout layout = mesher.layout(); + FdmLinearOpIterator endIter = layout.end(); - for (FdmLinearOpIterator iter = layout.begin(); iter != endIter; ++iter) - { - int i = iter.index(); - double? hm = mesher.dminus(iter, direction_); - double? hp = mesher.dplus(iter, direction_); + for (FdmLinearOpIterator iter = layout.begin(); iter != endIter; ++iter) + { + int i = iter.index(); + double? hm = mesher.dminus(iter, direction_); + double? hp = mesher.dplus(iter, direction_); - double? zetam1 = hm * (hm + hp); - double? zeta0 = hm * hp; - double? zetap1 = hp * (hm + hp); + double? zetam1 = hm * (hm + hp); + double? zeta0 = hm * hp; + double? zetap1 = hp * (hm + hp); - int co = iter.coordinates()[direction_]; - if (co == 0 || co == layout.dim()[direction] - 1) - { - lower_[i] = diag_[i] = upper_[i] = 0.0; - } - else - { - lower_[i] = 2.0 / zetam1.Value; - diag_[i] = -2.0 / zeta0.Value; - upper_[i] = 2.0 / zetap1.Value; - } + int co = iter.coordinates()[direction_]; + if (co == 0 || co == layout.dim()[direction] - 1) + { + lower_[i] = diag_[i] = upper_[i] = 0.0; + } + else + { + lower_[i] = 2.0 / zetam1.Value; + diag_[i] = -2.0 / zeta0.Value; + upper_[i] = 2.0 / zetap1.Value; } - } - } + } + } + } } diff --git a/src/QLNet/Methods/Finitedifferences/Operators/SecondOrderMixedDerivativeOp.cs b/src/QLNet/Methods/Finitedifferences/Operators/SecondOrderMixedDerivativeOp.cs index c58990891..67040f478 100644 --- a/src/QLNet/Methods/Finitedifferences/Operators/SecondOrderMixedDerivativeOp.cs +++ b/src/QLNet/Methods/Finitedifferences/Operators/SecondOrderMixedDerivativeOp.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,116 +20,116 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class SecondOrderMixedDerivativeOp : NinePointLinearOp - { - public SecondOrderMixedDerivativeOp(int d0, int d1, FdmMesher mesher) - : base (d0, d1, mesher) - { - FdmLinearOpLayout layout = mesher.layout(); - FdmLinearOpIterator endIter = layout.end(); + public class SecondOrderMixedDerivativeOp : NinePointLinearOp + { + public SecondOrderMixedDerivativeOp(int d0, int d1, FdmMesher mesher) + : base(d0, d1, mesher) + { + FdmLinearOpLayout layout = mesher.layout(); + FdmLinearOpIterator endIter = layout.end(); - for (FdmLinearOpIterator iter = layout.begin(); iter != endIter; ++iter) - { - int i = iter.index(); - double? hm_d0 = mesher.dminus(iter, d0_); - double? hp_d0 = mesher.dplus(iter, d0_); - double? hm_d1 = mesher.dminus(iter, d1_); - double? hp_d1 = mesher.dplus(iter, d1_); + for (FdmLinearOpIterator iter = layout.begin(); iter != endIter; ++iter) + { + int i = iter.index(); + double? hm_d0 = mesher.dminus(iter, d0_); + double? hp_d0 = mesher.dplus(iter, d0_); + double? hm_d1 = mesher.dminus(iter, d1_); + double? hp_d1 = mesher.dplus(iter, d1_); - double? zetam1 = hm_d0 * (hm_d0 + hp_d0); - double? zeta0 = hm_d0 * hp_d0; - double? zetap1 = hp_d0 * (hm_d0 + hp_d0); - double? phim1 = hm_d1 * (hm_d1 + hp_d1); - double? phi0 = hm_d1 * hp_d1; - double? phip1 = hp_d1 * (hm_d1 + hp_d1); + double? zetam1 = hm_d0 * (hm_d0 + hp_d0); + double? zeta0 = hm_d0 * hp_d0; + double? zetap1 = hp_d0 * (hm_d0 + hp_d0); + double? phim1 = hm_d1 * (hm_d1 + hp_d1); + double? phi0 = hm_d1 * hp_d1; + double? phip1 = hp_d1 * (hm_d1 + hp_d1); - int c0 = iter.coordinates()[d0_]; - int c1 = iter.coordinates()[d1_]; - if (c0 == 0 && c1 == 0) - { - // lower left corner - a00_[i] = a01_[i] = a02_[i] = a10_[i] = a20_[i] = 0.0; - a11_[i] = a22_[i] = 1.0 / (hp_d0.Value * hp_d1.Value); - a21_[i] = a12_[i] = -a11_[i]; - } - else if (c0 == layout.dim()[d0_] - 1 && c1 == 0) - { - // upper left corner - a22_[i] = a21_[i] = a20_[i] = a10_[i] = a00_[i] = 0.0; - a01_[i] = a12_[i] = 1.0 / (hm_d0.Value * hp_d1.Value); - a11_[i] = a02_[i] = -a01_[i]; - } - else if (c0 == 0 && c1 == layout.dim()[d1_] - 1) - { - // lower right corner - a00_[i] = a01_[i] = a02_[i] = a12_[i] = a22_[i] = 0.0; - a10_[i] = a21_[i] = 1.0 / (hp_d0.Value * hm_d1.Value); - a20_[i] = a11_[i] = -a10_[i]; - } - else if (c0 == layout.dim()[d0_] - 1 && c1 == layout.dim()[d1_] - 1) - { - // upper right corner - a20_[i] = a21_[i] = a22_[i] = a12_[i] = a02_[i] = 0.0; - a00_[i] = a11_[i] = 1.0 / (hm_d0.Value * hm_d1.Value); - a10_[i] = a01_[i] = -a00_[i]; - } - else if (c0 == 0) - { - // lower side - a00_[i] = a01_[i] = a02_[i] = 0.0; - a10_[i] = hp_d1.Value / (hp_d0.Value * phim1.Value); - a20_[i] = -a10_[i]; - a21_[i] = (hp_d1.Value - hm_d1.Value) / (hp_d0.Value * phi0.Value); - a11_[i] = -a21_[i]; - a22_[i] = hm_d1.Value / (hp_d0.Value * phip1.Value); - a12_[i] = -a22_[i]; - } - else if (c0 == layout.dim()[d0_] - 1) - { - // upper side - a20_[i] = a21_[i] = a22_[i] = 0.0; - a00_[i] = hp_d1.Value / (hm_d0.Value * phim1.Value); - a10_[i] = -a00_[i]; - a11_[i] = (hp_d1.Value - hm_d1.Value) / (hm_d0.Value * phi0.Value); - a01_[i] = -a11_[i]; - a12_[i] = hm_d1.Value / (hm_d0.Value * phip1.Value); - a02_[i] = -a12_[i]; - } - else if (c1 == 0) - { - // left side - a00_[i] = a10_[i] = a20_[i] = 0.0; - a01_[i] = hp_d0.Value / (zetam1.Value * hp_d1.Value); - a02_[i] = -a01_[i]; - a12_[i] = (hp_d0.Value - hm_d0.Value) / (zeta0.Value * hp_d1.Value); - a11_[i] = -a12_[i]; - a22_[i] = hm_d0.Value / (zetap1.Value * hp_d1.Value); - a21_[i] = -a22_[i]; - } - else if (c1 == layout.dim()[d1_] - 1) - { - // right side - a22_[i] = a12_[i] = a02_[i] = 0.0; - a00_[i] = hp_d0.Value / (zetam1.Value * hm_d1.Value); - a01_[i] = -a00_[i]; - a11_[i] = (hp_d0.Value - hm_d0.Value) / (zeta0.Value * hm_d1.Value); - a10_[i] = -a11_[i]; - a21_[i] = hm_d0.Value / (zetap1.Value * hm_d1.Value); - a20_[i] = -a21_[i]; - } - else - { - a00_[i] = hp_d0.Value * hp_d1.Value / (zetam1.Value * phim1.Value); - a10_[i] = -(hp_d0.Value - hm_d0.Value) * hp_d1.Value / (zeta0.Value * phim1.Value); - a20_[i] = -hm_d0.Value * hp_d1.Value / (zetap1.Value * phim1.Value); - a01_[i] = -hp_d0.Value * (hp_d1.Value - hm_d1.Value) / (zetam1.Value * phi0.Value); - a11_[i] = (hp_d0.Value - hm_d0.Value) * (hp_d1.Value - hm_d1.Value) / (zeta0.Value * phi0.Value); - a21_[i] = hm_d0.Value * (hp_d1.Value - hm_d1.Value) / (zetap1.Value * phi0.Value); - a02_[i] = -hp_d0.Value * hm_d1.Value / (zetam1.Value * phip1.Value); - a12_[i] = hm_d1.Value * (hp_d0.Value - hm_d0.Value) / (zeta0.Value * phip1.Value); - a22_[i] = hm_d0.Value * hm_d1.Value / (zetap1.Value * phip1.Value); - } + int c0 = iter.coordinates()[d0_]; + int c1 = iter.coordinates()[d1_]; + if (c0 == 0 && c1 == 0) + { + // lower left corner + a00_[i] = a01_[i] = a02_[i] = a10_[i] = a20_[i] = 0.0; + a11_[i] = a22_[i] = 1.0 / (hp_d0.Value * hp_d1.Value); + a21_[i] = a12_[i] = -a11_[i]; + } + else if (c0 == layout.dim()[d0_] - 1 && c1 == 0) + { + // upper left corner + a22_[i] = a21_[i] = a20_[i] = a10_[i] = a00_[i] = 0.0; + a01_[i] = a12_[i] = 1.0 / (hm_d0.Value * hp_d1.Value); + a11_[i] = a02_[i] = -a01_[i]; + } + else if (c0 == 0 && c1 == layout.dim()[d1_] - 1) + { + // lower right corner + a00_[i] = a01_[i] = a02_[i] = a12_[i] = a22_[i] = 0.0; + a10_[i] = a21_[i] = 1.0 / (hp_d0.Value * hm_d1.Value); + a20_[i] = a11_[i] = -a10_[i]; + } + else if (c0 == layout.dim()[d0_] - 1 && c1 == layout.dim()[d1_] - 1) + { + // upper right corner + a20_[i] = a21_[i] = a22_[i] = a12_[i] = a02_[i] = 0.0; + a00_[i] = a11_[i] = 1.0 / (hm_d0.Value * hm_d1.Value); + a10_[i] = a01_[i] = -a00_[i]; + } + else if (c0 == 0) + { + // lower side + a00_[i] = a01_[i] = a02_[i] = 0.0; + a10_[i] = hp_d1.Value / (hp_d0.Value * phim1.Value); + a20_[i] = -a10_[i]; + a21_[i] = (hp_d1.Value - hm_d1.Value) / (hp_d0.Value * phi0.Value); + a11_[i] = -a21_[i]; + a22_[i] = hm_d1.Value / (hp_d0.Value * phip1.Value); + a12_[i] = -a22_[i]; + } + else if (c0 == layout.dim()[d0_] - 1) + { + // upper side + a20_[i] = a21_[i] = a22_[i] = 0.0; + a00_[i] = hp_d1.Value / (hm_d0.Value * phim1.Value); + a10_[i] = -a00_[i]; + a11_[i] = (hp_d1.Value - hm_d1.Value) / (hm_d0.Value * phi0.Value); + a01_[i] = -a11_[i]; + a12_[i] = hm_d1.Value / (hm_d0.Value * phip1.Value); + a02_[i] = -a12_[i]; + } + else if (c1 == 0) + { + // left side + a00_[i] = a10_[i] = a20_[i] = 0.0; + a01_[i] = hp_d0.Value / (zetam1.Value * hp_d1.Value); + a02_[i] = -a01_[i]; + a12_[i] = (hp_d0.Value - hm_d0.Value) / (zeta0.Value * hp_d1.Value); + a11_[i] = -a12_[i]; + a22_[i] = hm_d0.Value / (zetap1.Value * hp_d1.Value); + a21_[i] = -a22_[i]; + } + else if (c1 == layout.dim()[d1_] - 1) + { + // right side + a22_[i] = a12_[i] = a02_[i] = 0.0; + a00_[i] = hp_d0.Value / (zetam1.Value * hm_d1.Value); + a01_[i] = -a00_[i]; + a11_[i] = (hp_d0.Value - hm_d0.Value) / (zeta0.Value * hm_d1.Value); + a10_[i] = -a11_[i]; + a21_[i] = hm_d0.Value / (zetap1.Value * hm_d1.Value); + a20_[i] = -a21_[i]; + } + else + { + a00_[i] = hp_d0.Value * hp_d1.Value / (zetam1.Value * phim1.Value); + a10_[i] = -(hp_d0.Value - hm_d0.Value) * hp_d1.Value / (zeta0.Value * phim1.Value); + a20_[i] = -hm_d0.Value * hp_d1.Value / (zetap1.Value * phim1.Value); + a01_[i] = -hp_d0.Value * (hp_d1.Value - hm_d1.Value) / (zetam1.Value * phi0.Value); + a11_[i] = (hp_d0.Value - hm_d0.Value) * (hp_d1.Value - hm_d1.Value) / (zeta0.Value * phi0.Value); + a21_[i] = hm_d0.Value * (hp_d1.Value - hm_d1.Value) / (zetap1.Value * phi0.Value); + a02_[i] = -hp_d0.Value * hm_d1.Value / (zetam1.Value * phip1.Value); + a12_[i] = hm_d1.Value * (hp_d0.Value - hm_d0.Value) / (zeta0.Value * phip1.Value); + a22_[i] = hm_d0.Value * hm_d1.Value / (zetap1.Value * phip1.Value); } - } - } + } + } + } } diff --git a/src/QLNet/Methods/Finitedifferences/Operators/TripleBandLinearOp.cs b/src/QLNet/Methods/Finitedifferences/Operators/TripleBandLinearOp.cs index 7f55a9196..4b2012f07 100644 --- a/src/QLNet/Methods/Finitedifferences/Operators/TripleBandLinearOp.cs +++ b/src/QLNet/Methods/Finitedifferences/Operators/TripleBandLinearOp.cs @@ -1,17 +1,17 @@ -/* +/* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,288 +22,309 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class TripleBandLinearOp : FdmLinearOp - { - public TripleBandLinearOp(int direction, FdmMesher mesher) - { - direction_ = direction; - i0_ = new InitializedList(mesher.layout().size()); - i2_ = new InitializedList(mesher.layout().size()); - reverseIndex_ = new InitializedList(mesher.layout().size()); - lower_ = new InitializedList(mesher.layout().size()); - diag_ = new InitializedList(mesher.layout().size()); - upper_ = new InitializedList(mesher.layout().size()); - mesher_ = mesher; - - FdmLinearOpLayout layout = mesher.layout(); - FdmLinearOpIterator endIter = layout.end(); - - int tmp; - List newDim = new List(layout.dim()); - tmp = newDim[direction_]; - newDim[direction_] = newDim[0]; - newDim[0] = tmp; - - List newSpacing = new FdmLinearOpLayout(newDim).spacing(); - tmp = newSpacing[direction_]; - newSpacing[direction_] = newSpacing[0]; - newSpacing[0] = tmp; - - for (FdmLinearOpIterator iter = layout.begin(); iter!=endIter; ++iter) { - int i = iter.index(); - - i0_[i] = layout.neighbourhood(iter, direction, -1); - i2_[i] = layout.neighbourhood(iter, direction, 1); - - List coordinates = iter.coordinates(); - - int newIndex = coordinates.inner_product(0, coordinates.Count, 0, newSpacing, 0); - reverseIndex_[newIndex] = i; - } - } - - public TripleBandLinearOp(TripleBandLinearOp m) - { - direction_ = m.direction_; - i0_ = new InitializedList(m.mesher_.layout().size()); - i2_ = new InitializedList(m.mesher_.layout().size()); - reverseIndex_ = new InitializedList(m.mesher_.layout().size()); - lower_ = new InitializedList(m.mesher_.layout().size()); - diag_ = new InitializedList(m.mesher_.layout().size()); - upper_ = new InitializedList(m.mesher_.layout().size()); - mesher_ = m.mesher_; - - int len = m.mesher_.layout().size(); - m.i0_.copy(0, len, 0, i0_); - m.i2_.copy(0, len, 0, i2_); - m.reverseIndex_.copy(0, len, 0, reverseIndex_); - m.lower_.copy(0, len, 0, lower_); - m.diag_.copy(0, len, 0, diag_); - m.upper_.copy(0, len, 0, upper_); - } - - protected TripleBandLinearOp() - { - - } - - public override Vector apply(Vector r) - { - FdmLinearOpLayout index = mesher_.layout(); - - Utils.QL_REQUIRE(r.size() == index.size(), () => "inconsistent length of r"); - - Vector retVal = new Vector(r.size()); - //#pragma omp parallel for - for (int i=0; i < index.size(); ++i) { - retVal[i] = r[i0_[i]] * lower_[i] + r[i] * diag_[i] + r[i2_[i]] * upper_[i]; - } - - return retVal; - } - - public override SparseMatrix toMatrix() - { - FdmLinearOpLayout index = mesher_.layout(); - int n = index.size(); - - SparseMatrix retVal = new SparseMatrix(n, n); - for (int i=0; i < n; ++i) { - retVal[i, i0_[i]] += lower_[i]; - retVal[i, i ] += diag_[i]; - retVal[i, i2_[i]] += upper_[i]; - } - - return retVal; - } - - public Vector solve_splitting(Vector r, double a, double b = 1.0) - { - FdmLinearOpLayout layout = mesher_.layout(); - Utils.QL_REQUIRE(r.size() == layout.size(), () => "inconsistent size of rhs"); - - for (FdmLinearOpIterator iter = layout.begin(); - iter!=layout.end(); ++iter) { - List coordinates = iter.coordinates(); - Utils.QL_REQUIRE( coordinates[direction_] != 0 - || lower_[iter.index()] == 0, () => "removing non zero entry!"); - Utils.QL_REQUIRE( coordinates[direction_] != layout.dim()[direction_]-1 - || upper_[iter.index()] == 0, () => "removing non zero entry!"); - } - - Vector retVal = new Vector(r.size()), tmp = new Vector(r.size()); - - // Thomson algorithm to solve a tridiagonal system. - // Example code taken from Tridiagonalopertor and - // changed to fit for the triple band operator. - int rim1 = reverseIndex_[0]; - double bet = 1.0 / (a * diag_[rim1] + b); - Utils.QL_REQUIRE(bet != 0.0, () => "division by zero"); - retVal[reverseIndex_[0]] = r[rim1]*bet; - - for (int j=1; j<=layout.size()-1; j++){ - int ri = reverseIndex_[j]; - tmp[j] = a * upper_[rim1] * bet; - - bet = b + a * (diag_[ri] - tmp[j] * lower_[ri]); - Utils.QL_REQUIRE(bet != 0.0, () => "division by zero"); //QL_ENSURE - bet=1.0/bet; - - retVal[ri] = (r[ri] - a * lower_[ri] * retVal[rim1]) * bet; - rim1 = ri; - } - // cannot be j>=0 with Size j - for (int j=layout.size()-2; j>0; --j) - retVal[reverseIndex_[j]] -= tmp[j+1]*retVal[reverseIndex_[j+1]]; - retVal[reverseIndex_[0]] -= tmp[1]*retVal[reverseIndex_[1]]; - - return retVal; - } - - public TripleBandLinearOp mult(Vector u) - { - TripleBandLinearOp retVal = new TripleBandLinearOp(direction_, mesher_); - - int size = mesher_.layout().size(); - //#pragma omp parallel for - for (int i=0; i < size; ++i) { - double s = u[i]; - retVal.lower_[i]= lower_[i]*s; - retVal.diag_[i] = diag_[i]*s; - retVal.upper_[i]= upper_[i]*s; + public class TripleBandLinearOp : FdmLinearOp + { + public TripleBandLinearOp(int direction, FdmMesher mesher) + { + direction_ = direction; + i0_ = new InitializedList(mesher.layout().size()); + i2_ = new InitializedList(mesher.layout().size()); + reverseIndex_ = new InitializedList(mesher.layout().size()); + lower_ = new InitializedList(mesher.layout().size()); + diag_ = new InitializedList(mesher.layout().size()); + upper_ = new InitializedList(mesher.layout().size()); + mesher_ = mesher; + + FdmLinearOpLayout layout = mesher.layout(); + FdmLinearOpIterator endIter = layout.end(); + + int tmp; + List newDim = new List(layout.dim()); + tmp = newDim[direction_]; + newDim[direction_] = newDim[0]; + newDim[0] = tmp; + + List newSpacing = new FdmLinearOpLayout(newDim).spacing(); + tmp = newSpacing[direction_]; + newSpacing[direction_] = newSpacing[0]; + newSpacing[0] = tmp; + + for (FdmLinearOpIterator iter = layout.begin(); iter != endIter; ++iter) + { + int i = iter.index(); + + i0_[i] = layout.neighbourhood(iter, direction, -1); + i2_[i] = layout.neighbourhood(iter, direction, 1); + + List coordinates = iter.coordinates(); + + int newIndex = coordinates.inner_product(0, coordinates.Count, 0, newSpacing, 0); + reverseIndex_[newIndex] = i; + } + } + + public TripleBandLinearOp(TripleBandLinearOp m) + { + direction_ = m.direction_; + i0_ = new InitializedList(m.mesher_.layout().size()); + i2_ = new InitializedList(m.mesher_.layout().size()); + reverseIndex_ = new InitializedList(m.mesher_.layout().size()); + lower_ = new InitializedList(m.mesher_.layout().size()); + diag_ = new InitializedList(m.mesher_.layout().size()); + upper_ = new InitializedList(m.mesher_.layout().size()); + mesher_ = m.mesher_; + + int len = m.mesher_.layout().size(); + m.i0_.copy(0, len, 0, i0_); + m.i2_.copy(0, len, 0, i2_); + m.reverseIndex_.copy(0, len, 0, reverseIndex_); + m.lower_.copy(0, len, 0, lower_); + m.diag_.copy(0, len, 0, diag_); + m.upper_.copy(0, len, 0, upper_); + } + + protected TripleBandLinearOp() + { + + } + + public override Vector apply(Vector r) + { + FdmLinearOpLayout index = mesher_.layout(); + + Utils.QL_REQUIRE(r.size() == index.size(), () => "inconsistent length of r"); + + Vector retVal = new Vector(r.size()); + //#pragma omp parallel for + for (int i = 0; i < index.size(); ++i) + { + retVal[i] = r[i0_[i]] * lower_[i] + r[i] * diag_[i] + r[i2_[i]] * upper_[i]; + } + + return retVal; + } + + public override SparseMatrix toMatrix() + { + FdmLinearOpLayout index = mesher_.layout(); + int n = index.size(); + + SparseMatrix retVal = new SparseMatrix(n, n); + for (int i = 0; i < n; ++i) + { + retVal[i, i0_[i]] += lower_[i]; + retVal[i, i ] += diag_[i]; + retVal[i, i2_[i]] += upper_[i]; + } + + return retVal; + } + + public Vector solve_splitting(Vector r, double a, double b = 1.0) + { + FdmLinearOpLayout layout = mesher_.layout(); + Utils.QL_REQUIRE(r.size() == layout.size(), () => "inconsistent size of rhs"); + + for (FdmLinearOpIterator iter = layout.begin(); + iter != layout.end(); ++iter) + { + List coordinates = iter.coordinates(); + Utils.QL_REQUIRE(coordinates[direction_] != 0 + || lower_[iter.index()] == 0, () => "removing non zero entry!"); + Utils.QL_REQUIRE(coordinates[direction_] != layout.dim()[direction_] - 1 + || upper_[iter.index()] == 0, () => "removing non zero entry!"); + } + + Vector retVal = new Vector(r.size()), tmp = new Vector(r.size()); + + // Thomson algorithm to solve a tridiagonal system. + // Example code taken from Tridiagonalopertor and + // changed to fit for the triple band operator. + int rim1 = reverseIndex_[0]; + double bet = 1.0 / (a * diag_[rim1] + b); + Utils.QL_REQUIRE(bet != 0.0, () => "division by zero"); + retVal[reverseIndex_[0]] = r[rim1] * bet; + + for (int j = 1; j <= layout.size() - 1; j++) + { + int ri = reverseIndex_[j]; + tmp[j] = a * upper_[rim1] * bet; + + bet = b + a * (diag_[ri] - tmp[j] * lower_[ri]); + Utils.QL_REQUIRE(bet != 0.0, () => "division by zero"); //QL_ENSURE + bet = 1.0 / bet; + + retVal[ri] = (r[ri] - a * lower_[ri] * retVal[rim1]) * bet; + rim1 = ri; + } + // cannot be j>=0 with Size j + for (int j = layout.size() - 2; j > 0; --j) + retVal[reverseIndex_[j]] -= tmp[j + 1] * retVal[reverseIndex_[j + 1]]; + retVal[reverseIndex_[0]] -= tmp[1] * retVal[reverseIndex_[1]]; + + return retVal; + } + + public TripleBandLinearOp mult(Vector u) + { + TripleBandLinearOp retVal = new TripleBandLinearOp(direction_, mesher_); + + int size = mesher_.layout().size(); + //#pragma omp parallel for + for (int i = 0; i < size; ++i) + { + double s = u[i]; + retVal.lower_[i] = lower_[i] * s; + retVal.diag_[i] = diag_[i] * s; + retVal.upper_[i] = upper_[i] * s; + } + + return retVal; + } + + public TripleBandLinearOp multR(Vector u) + { + FdmLinearOpLayout layout = mesher_.layout(); + int size = layout.size(); + Utils.QL_REQUIRE(u.size() == size, () => "inconsistent size of rhs"); + TripleBandLinearOp retVal = new TripleBandLinearOp(direction_, mesher_); + + for (int i = 0; i < size; ++i) + { + double sm1 = i > 0 ? u[i - 1] : 1.0; + double s0 = u[i]; + double sp1 = i < size - 1 ? u[i + 1] : 1.0; + retVal.lower_[i] = lower_[i] * sm1; + retVal.diag_[i] = diag_[i] * s0; + retVal.upper_[i] = upper_[i] * sp1; + } + + return retVal; + } + + public TripleBandLinearOp add + (TripleBandLinearOp m) + { + TripleBandLinearOp retVal = new TripleBandLinearOp(direction_, mesher_); + int size = mesher_.layout().size(); + //#pragma omp parallel for + for (int i = 0; i < size; ++i) + { + retVal.lower_[i] = lower_[i] + m.lower_[i]; + retVal.diag_[i] = diag_[i] + m.diag_[i]; + retVal.upper_[i] = upper_[i] + m.upper_[i]; + } + + return retVal; + } + + public TripleBandLinearOp add + (Vector u) + { + + TripleBandLinearOp retVal = new TripleBandLinearOp(direction_, mesher_); + + int size = mesher_.layout().size(); + //#pragma omp parallel for + for (int i = 0; i < size; ++i) + { + retVal.lower_[i] = lower_[i]; + retVal.upper_[i] = upper_[i]; + retVal.diag_[i] = diag_[i] + u[i]; + } + + return retVal; + } + + public void axpyb(Vector a, TripleBandLinearOp x, TripleBandLinearOp y, Vector b) + { + int size = mesher_.layout().size(); + + if (a.empty()) + { + if (b.empty()) + { + //#pragma omp parallel for + for (int i = 0; i < size; ++i) + { + diag_[i] = y.diag_[i]; + lower_[i] = y.lower_[i]; + upper_[i] = y.upper_[i]; + } } - - return retVal; - } - - public TripleBandLinearOp multR(Vector u) - { - FdmLinearOpLayout layout = mesher_.layout(); - int size = layout.size(); - Utils.QL_REQUIRE(u.size() == size, () => "inconsistent size of rhs"); - TripleBandLinearOp retVal = new TripleBandLinearOp(direction_, mesher_); - - for (int i=0; i < size; ++i) { - double sm1 = i > 0? u[i-1] : 1.0; - double s0 = u[i]; - double sp1 = i < size - 1 ? u[i + 1] : 1.0; - retVal.lower_[i]= lower_[i]*sm1; - retVal.diag_[i] = diag_[i]*s0; - retVal.upper_[i]= upper_[i]*sp1; + else + { + int binc = (b.size() > 1) ? 1 : 0; + //#pragma omp parallel for + for (int i = 0; i < size; ++i) + { + diag_[i] = y.diag_[i] + b[i * binc]; + lower_[i] = y.lower_[i]; + upper_[i] = y.upper_[i]; + } } + } + else if (b.empty()) + { + int ainc = (a.size() > 1) ? 1 : 0; - return retVal; - } - - public TripleBandLinearOp add(TripleBandLinearOp m) - { - TripleBandLinearOp retVal = new TripleBandLinearOp(direction_, mesher_); - int size = mesher_.layout().size(); //#pragma omp parallel for - for (int i=0; i < size; ++i) { - retVal.lower_[i]= lower_[i] + m.lower_[i]; - retVal.diag_[i] = diag_[i] + m.diag_[i]; - retVal.upper_[i]= upper_[i] + m.upper_[i]; + for (int i = 0; i < size; ++i) + { + double s = a[i * ainc]; + diag_[i] = y.diag_[i] + s * x.diag_[i]; + lower_[i] = y.lower_[i] + s * x.lower_[i]; + upper_[i] = y.upper_[i] + s * x.upper_[i]; } + } + else + { + int binc = (b.size() > 1) ? 1 : 0; + int ainc = (a.size() > 1) ? 1 : 0; - return retVal; - } - - public TripleBandLinearOp add(Vector u) - { - - TripleBandLinearOp retVal = new TripleBandLinearOp(direction_, mesher_); - - int size = mesher_.layout().size(); //#pragma omp parallel for - for (int i=0; i < size; ++i) { - retVal.lower_[i]= lower_[i]; - retVal.upper_[i]= upper_[i]; - retVal.diag_[i] = diag_[i]+u[i]; - } - - return retVal; - } - - public void axpyb(Vector a, TripleBandLinearOp x, TripleBandLinearOp y, Vector b) - { - int size = mesher_.layout().size(); - - if (a.empty()) { - if (b.empty()) { - //#pragma omp parallel for - for (int i=0; i < size; ++i) { - diag_[i] = y.diag_[i]; - lower_[i] = y.lower_[i]; - upper_[i] = y.upper_[i]; - } - } - else { - int binc = (b.size() > 1) ? 1 : 0; - //#pragma omp parallel for - for (int i=0; i < size; ++i) { - diag_[i] = y.diag_[i] + b[i*binc]; - lower_[i] = y.lower_[i]; - upper_[i] = y.upper_[i]; - } - } - } - else if (b.empty()) { - int ainc = (a.size() > 1) ? 1 : 0; - - //#pragma omp parallel for - for (int i=0; i < size; ++i) { - double s = a[i*ainc]; - diag_[i] = y.diag_[i] + s*x.diag_[i]; - lower_[i] = y.lower_[i] + s*x.lower_[i]; - upper_[i] = y.upper_[i] + s*x.upper_[i]; - } - } - else { - int binc = (b.size() > 1) ? 1 : 0; - int ainc = (a.size() > 1) ? 1 : 0; - - //#pragma omp parallel for - for (int i=0; i < size; ++i) { - double s = a[i*ainc]; - diag_[i] = y.diag_[i] + s * x.diag_[i] + b[i * binc]; - lower_[i] = y.lower_[i] + s * x.lower_[i]; - upper_[i] = y.upper_[i] + s * x.upper_[i]; - } + for (int i = 0; i < size; ++i) + { + double s = a[i * ainc]; + diag_[i] = y.diag_[i] + s * x.diag_[i] + b[i * binc]; + lower_[i] = y.lower_[i] + s * x.lower_[i]; + upper_[i] = y.upper_[i] + s * x.upper_[i]; } - } - - public void swap(TripleBandLinearOp m) - { - Utils.swap(ref mesher_, ref m.mesher_); - Utils.swap(ref direction_, ref m.direction_); - Utils.swap(ref i0_, ref m.i0_); - Utils.swap(ref i2_, ref m.i2_); - Utils.swap(ref reverseIndex_, ref m.reverseIndex_); - Utils.swap(ref lower_, ref m.lower_); - Utils.swap(ref diag_, ref m.diag_); - Utils.swap(ref upper_, ref m.upper_); - } - - #region IOperator interface - public override int size() { return 0; } - public override IOperator identity(int size) { return null; } - public override Vector applyTo(Vector v) { return null; } - public override Vector solveFor(Vector rhs) { return null; } - - public override IOperator multiply(double a, IOperator D) { return null; } - public override IOperator add(IOperator A, IOperator B) { return null; } - public override IOperator subtract(IOperator A, IOperator B) { return null; } - - public override bool isTimeDependent() { return false; } - public override void setTime(double t) { } - public override object Clone() { return this.MemberwiseClone(); } - #endregion - - protected int direction_; - protected List i0_, i2_; - protected List reverseIndex_; - protected List lower_, diag_, upper_; - protected FdmMesher mesher_; - } + } + } + + public void swap(TripleBandLinearOp m) + { + Utils.swap(ref mesher_, ref m.mesher_); + Utils.swap(ref direction_, ref m.direction_); + Utils.swap(ref i0_, ref m.i0_); + Utils.swap(ref i2_, ref m.i2_); + Utils.swap(ref reverseIndex_, ref m.reverseIndex_); + Utils.swap(ref lower_, ref m.lower_); + Utils.swap(ref diag_, ref m.diag_); + Utils.swap(ref upper_, ref m.upper_); + } + + #region IOperator interface + public override int size() { return 0; } + public override IOperator identity(int size) { return null; } + public override Vector applyTo(Vector v) { return null; } + public override Vector solveFor(Vector rhs) { return null; } + + public override IOperator multiply(double a, IOperator D) { return null; } + public override IOperator add + (IOperator A, IOperator B) { return null; } + public override IOperator subtract(IOperator A, IOperator B) { return null; } + + public override bool isTimeDependent() { return false; } + public override void setTime(double t) { } + public override object Clone() { return this.MemberwiseClone(); } + #endregion + + protected int direction_; + protected List i0_, i2_; + protected List reverseIndex_; + protected List lower_, diag_, upper_; + protected FdmMesher mesher_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/ParallelEvolver.cs b/src/QLNet/Methods/Finitedifferences/ParallelEvolver.cs index 1566ada94..85de78340 100644 --- a/src/QLNet/Methods/Finitedifferences/ParallelEvolver.cs +++ b/src/QLNet/Methods/Finitedifferences/ParallelEvolver.cs @@ -1,77 +1,89 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System.Collections.Generic; -namespace QLNet { - /*! \brief Parallel evolver for multiple arrays +namespace QLNet +{ + /*! \brief Parallel evolver for multiple arrays - This class takes the evolver class and creates a new class which evolves - each of the evolvers in parallel. Part of what this does is to take the - types for each evolver class and then wrapper them so that they create - new types which are sets of the old types. + This class takes the evolver class and creates a new class which evolves + each of the evolvers in parallel. Part of what this does is to take the + types for each evolver class and then wrapper them so that they create + new types which are sets of the old types. - This class is intended to be run in situations where there are parallel - differential equations such as with some convertible bond models. - */ - /*! \ingroup findiff */ + This class is intended to be run in situations where there are parallel + differential equations such as with some convertible bond models. + */ + /*! \ingroup findiff */ - public class StepConditionSet : List>, IStepCondition - where array_type : Vector { - public void applyTo(object o, double t) { - List a = (List)o; - for (int i=0; i < Count; i++) { - this[i].applyTo(a[i], t); - } - } - } + public class StepConditionSet : List>, IStepCondition + where array_type : Vector + { + public void applyTo(object o, double t) + { + List a = (List)o; + for (int i = 0; i < Count; i++) + { + this[i].applyTo(a[i], t); + } + } + } - public class BoundaryConditionSet : List>> { } + public class BoundaryConditionSet : List>> { } - public class ParallelEvolver : IMixedScheme, ISchemeFactory where Evolver : IMixedScheme, ISchemeFactory, new() { - private List evolvers_; + public class ParallelEvolver : IMixedScheme, ISchemeFactory where Evolver : IMixedScheme, ISchemeFactory, new () + { + private List evolvers_; - // required for generics - public ParallelEvolver() { } - public ParallelEvolver(List L, BoundaryConditionSet bcs) { - evolvers_ = new List(L.Count); - for (int i = 0; i < L.Count; i++) { - evolvers_.Add(FastActivator.Create().factory(L[i], bcs[i])); - } - } + // required for generics + public ParallelEvolver() { } + public ParallelEvolver(List L, BoundaryConditionSet bcs) + { + evolvers_ = new List(L.Count); + for (int i = 0; i < L.Count; i++) + { + evolvers_.Add(FastActivator.Create().factory(L[i], bcs[i])); + } + } - public void step(ref object o, double t) { - List a = (List)o; - for (int i=0; i < evolvers_.Count; i++) { - object temp = a[i]; - evolvers_[i].step(ref temp, t); - a[i] = temp as Vector; - } - } + public void step(ref object o, double t) + { + List a = (List)o; + for (int i = 0; i < evolvers_.Count; i++) + { + object temp = a[i]; + evolvers_[i].step(ref temp, t); + a[i] = temp as Vector; + } + } - public void setStep(double dt) { - for (int i = 0; i < evolvers_.Count; i++) { - evolvers_[i].setStep(dt); - } - } + public void setStep(double dt) + { + for (int i = 0; i < evolvers_.Count; i++) + { + evolvers_[i].setStep(dt); + } + } - public IMixedScheme factory(object L, object bcs, object[] additionalFields = null) { - return new ParallelEvolver((List)L, (BoundaryConditionSet)bcs); - } - } + public IMixedScheme factory(object L, object bcs, object[] additionalFields = null) + { + return new ParallelEvolver((List)L, (BoundaryConditionSet)bcs); + } + } } diff --git a/src/QLNet/Methods/Finitedifferences/Pde.cs b/src/QLNet/Methods/Finitedifferences/Pde.cs new file mode 100644 index 000000000..dbb06e125 --- /dev/null +++ b/src/QLNet/Methods/Finitedifferences/Pde.cs @@ -0,0 +1,101 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + public abstract class PdeSecondOrderParabolic + { + public abstract double diffusion(double t, double x); + public abstract double drift(double t, double x); + public abstract double discount(double t, double x); + public abstract PdeSecondOrderParabolic factory(GeneralizedBlackScholesProcess process); + + public void generateOperator(double t, TransformedGrid tg, TridiagonalOperator L) + { + for (int i = 1; i < tg.size() - 1; i++) + { + double sigma = diffusion(t, tg.grid(i)); + double nu = drift(t, tg.grid(i)); + double r = discount(t, tg.grid(i)); + double sigma2 = sigma * sigma; + + double pd = -(sigma2 / tg.dxm(i) - nu) / tg.dx(i); + double pu = -(sigma2 / tg.dxp(i) + nu) / tg.dx(i); + double pm = sigma2 / (tg.dxm(i) * tg.dxp(i)) + r; + L.setMidRow(i, pd, pm, pu); + } + } + } + + + public class PdeConstantCoeff : PdeSecondOrderParabolic where PdeClass : PdeSecondOrderParabolic, new () + { + private double diffusion_; + private double drift_; + private double discount_; + + public PdeConstantCoeff(GeneralizedBlackScholesProcess process, double t, double x) + { + PdeClass pde = (PdeClass) FastActivator.Create().factory(process); + diffusion_ = pde.diffusion(t, x); + drift_ = pde.drift(t, x); + discount_ = pde.discount(t, x); + } + + public override double diffusion(double x, double y) { return diffusion_; } + public override double drift(double x, double y) { return drift_; } + public override double discount(double x, double y) { return discount_; } + public override PdeSecondOrderParabolic factory(GeneralizedBlackScholesProcess process) + { + throw new NotSupportedException(); + } + } + + + public class GenericTimeSetter : TridiagonalOperator.TimeSetter where PdeClass : PdeSecondOrderParabolic, new () + { + private LogGrid grid_; + private PdeClass pde_; + + public GenericTimeSetter(Vector grid, GeneralizedBlackScholesProcess process) + { + grid_ = new LogGrid(grid); + pde_ = (PdeClass) FastActivator.Create().factory(process); + } + + public override void setTime(double t, IOperator L) + { + pde_.generateOperator(t, grid_, (TridiagonalOperator)L); + } + } + + + public class PdeOperator : TridiagonalOperator where PdeClass : PdeSecondOrderParabolic, new () + { + public PdeOperator(Vector grid, GeneralizedBlackScholesProcess process) : this(grid, process, 0) { } + public PdeOperator(Vector grid, GeneralizedBlackScholesProcess process, double residualTime) + : base(grid.size()) + { + timeSetter_ = new GenericTimeSetter(grid, process); + setTime(residualTime); + } + } + +} diff --git a/src/QLNet/Methods/Finitedifferences/PdeBsm.cs b/src/QLNet/Methods/Finitedifferences/PdeBsm.cs new file mode 100644 index 000000000..79adcb3aa --- /dev/null +++ b/src/QLNet/Methods/Finitedifferences/PdeBsm.cs @@ -0,0 +1,52 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + public class PdeBSM : PdeSecondOrderParabolic + { + private GeneralizedBlackScholesProcess process_; + + public PdeBSM() { } // required for generics + public PdeBSM(GeneralizedBlackScholesProcess process) + { + process_ = process; + } + + public override double diffusion(double t, double x) + { + return process_.diffusion(t, x); + } + + public override double drift(double t, double x) + { + return process_.drift(t, x); + } + + public override double discount(double t, double x) + { + if (Math.Abs(t) < 1e-8) + t = 0; + return process_.riskFreeRate().link.forwardRate(t, t, Compounding.Continuous, Frequency.NoFrequency, true).rate(); + } + + public override PdeSecondOrderParabolic factory(GeneralizedBlackScholesProcess process) { return new PdeBSM(process); } + } +} diff --git a/src/QLNet/Methods/Finitedifferences/pdeshortrate.cs b/src/QLNet/Methods/Finitedifferences/PdeShortRate.cs similarity index 95% rename from src/QLNet/Methods/Finitedifferences/pdeshortrate.cs rename to src/QLNet/Methods/Finitedifferences/PdeShortRate.cs index d12888f65..889b4b6eb 100644 --- a/src/QLNet/Methods/Finitedifferences/pdeshortrate.cs +++ b/src/QLNet/Methods/Finitedifferences/PdeShortRate.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Methods/Finitedifferences/Schemes/BoundaryConditionSchemeHelper.cs b/src/QLNet/Methods/Finitedifferences/Schemes/BoundaryConditionSchemeHelper.cs index 1e767228a..71f92d302 100644 --- a/src/QLNet/Methods/Finitedifferences/Schemes/BoundaryConditionSchemeHelper.cs +++ b/src/QLNet/Methods/Finitedifferences/Schemes/BoundaryConditionSchemeHelper.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,35 +23,40 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class BoundaryConditionSchemeHelper - { - public BoundaryConditionSchemeHelper(List> bcSet) - { - bcSet_ = bcSet; - } - - //BoundaryCondition inheritance - public void applyBeforeApplying(IOperator op) { - for (int i=0; i < bcSet_.Count; ++i) - bcSet_[i].applyBeforeApplying(op); - } - public void applyBeforeSolving(IOperator op, Vector a) { - for (int i=0; i < bcSet_.Count; ++i) - bcSet_[i].applyBeforeSolving(op, a); - } - public void applyAfterApplying(Vector a) { - for (int i=0; i < bcSet_.Count; ++i) - bcSet_[i].applyAfterApplying(a); - } - public void applyAfterSolving(Vector a) { - for (int i=0; i < bcSet_.Count; ++i) - bcSet_[i].applyAfterSolving(a); - } - public void setTime(double t) { - for (int i=0; i < bcSet_.Count; ++i) - bcSet_[i].setTime(t); - } - - protected List> bcSet_; - } + public class BoundaryConditionSchemeHelper + { + public BoundaryConditionSchemeHelper(List> bcSet) + { + bcSet_ = bcSet; + } + + //BoundaryCondition inheritance + public void applyBeforeApplying(IOperator op) + { + for (int i = 0; i < bcSet_.Count; ++i) + bcSet_[i].applyBeforeApplying(op); + } + public void applyBeforeSolving(IOperator op, Vector a) + { + for (int i = 0; i < bcSet_.Count; ++i) + bcSet_[i].applyBeforeSolving(op, a); + } + public void applyAfterApplying(Vector a) + { + for (int i = 0; i < bcSet_.Count; ++i) + bcSet_[i].applyAfterApplying(a); + } + public void applyAfterSolving(Vector a) + { + for (int i = 0; i < bcSet_.Count; ++i) + bcSet_[i].applyAfterSolving(a); + } + public void setTime(double t) + { + for (int i = 0; i < bcSet_.Count; ++i) + bcSet_[i].setTime(t); + } + + protected List> bcSet_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/Schemes/CraigSneydScheme.cs b/src/QLNet/Methods/Finitedifferences/Schemes/CraigSneydScheme.cs index 20c1e8394..d521b3314 100644 --- a/src/QLNet/Methods/Finitedifferences/Schemes/CraigSneydScheme.cs +++ b/src/QLNet/Methods/Finitedifferences/Schemes/CraigSneydScheme.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -31,8 +31,8 @@ public CraigSneydScheme() { } public CraigSneydScheme(double theta, double mu, - FdmLinearOpComposite map, - List> bcSet = null) + FdmLinearOpComposite map, + List> bcSet = null) { dt_ = null; theta_ = theta; @@ -48,7 +48,7 @@ public IMixedScheme factory(object L, object bcs, object[] additionalInputs = nu double? theta = additionalInputs[0] as double?; double? mu = additionalInputs[1] as double?; return new CraigSneydScheme(theta.Value, mu.Value, - L as FdmLinearOpComposite, bcs as List>); + L as FdmLinearOpComposite, bcs as List>); } #endregion diff --git a/src/QLNet/Methods/Finitedifferences/Schemes/DouglasScheme.cs b/src/QLNet/Methods/Finitedifferences/Schemes/DouglasScheme.cs index e13de1c18..3467c798f 100644 --- a/src/QLNet/Methods/Finitedifferences/Schemes/DouglasScheme.cs +++ b/src/QLNet/Methods/Finitedifferences/Schemes/DouglasScheme.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -31,8 +31,8 @@ public DouglasScheme() { } public DouglasScheme(double theta, - FdmLinearOpComposite map, - List> bcSet = null) + FdmLinearOpComposite map, + List> bcSet = null) { dt_ = null; theta_ = theta; @@ -46,7 +46,7 @@ public IMixedScheme factory(object L, object bcs, object[] additionalInputs = nu { double? theta = additionalInputs[0] as double?; return new DouglasScheme(theta.Value, - L as FdmLinearOpComposite, bcs as List>); + L as FdmLinearOpComposite, bcs as List>); } #endregion diff --git a/src/QLNet/Methods/Finitedifferences/Schemes/ExplicitEulerScheme.cs b/src/QLNet/Methods/Finitedifferences/Schemes/ExplicitEulerScheme.cs index 56c1f7a47..a0cd8c371 100644 --- a/src/QLNet/Methods/Finitedifferences/Schemes/ExplicitEulerScheme.cs +++ b/src/QLNet/Methods/Finitedifferences/Schemes/ExplicitEulerScheme.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,45 +23,45 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class ExplicitEulerScheme : IMixedScheme, ISchemeFactory - { - public ExplicitEulerScheme() { } - public ExplicitEulerScheme(FdmLinearOpComposite map, - List> bcSet = null) - { - dt_ = null; - map_ = map; - bcSet_ = new BoundaryConditionSchemeHelper(bcSet); - } + public class ExplicitEulerScheme : IMixedScheme, ISchemeFactory + { + public ExplicitEulerScheme() { } + public ExplicitEulerScheme(FdmLinearOpComposite map, + List> bcSet = null) + { + dt_ = null; + map_ = map; + bcSet_ = new BoundaryConditionSchemeHelper(bcSet); + } - #region ISchemeFactory - public IMixedScheme factory(object L, object bcs, object[] additionalInputs = null) - { - return new ExplicitEulerScheme(L as FdmLinearOpComposite, bcs as List>); - } - #endregion + #region ISchemeFactory + public IMixedScheme factory(object L, object bcs, object[] additionalInputs = null) + { + return new ExplicitEulerScheme(L as FdmLinearOpComposite, bcs as List>); + } + #endregion - #region IMixedScheme interface - public void step(ref object a, double t) - { - Utils.QL_REQUIRE(t-dt_ > -1e-8, () => "a step towards negative time given"); - map_.setTime(Math.Max(0.0, t - dt_.Value), t); - bcSet_.setTime(Math.Max(0.0, t - dt_.Value)); + #region IMixedScheme interface + public void step(ref object a, double t) + { + Utils.QL_REQUIRE(t - dt_ > -1e-8, () => "a step towards negative time given"); + map_.setTime(Math.Max(0.0, t - dt_.Value), t); + bcSet_.setTime(Math.Max(0.0, t - dt_.Value)); - bcSet_.applyBeforeApplying(map_); - a = (a as Vector) + dt_.Value * map_.apply(a as Vector); - bcSet_.applyAfterApplying(a as Vector); + bcSet_.applyBeforeApplying(map_); + a = (a as Vector) + dt_.Value * map_.apply(a as Vector); + bcSet_.applyAfterApplying(a as Vector); - } + } - public void setStep(double dt) - { - dt_ = dt; - } - #endregion + public void setStep(double dt) + { + dt_ = dt; + } + #endregion - protected double? dt_; - protected FdmLinearOpComposite map_; - protected BoundaryConditionSchemeHelper bcSet_; - } + protected double? dt_; + protected FdmLinearOpComposite map_; + protected BoundaryConditionSchemeHelper bcSet_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/Schemes/HundsdorferScheme.cs b/src/QLNet/Methods/Finitedifferences/Schemes/HundsdorferScheme.cs index 419bfcdd8..1a2b8dbd3 100644 --- a/src/QLNet/Methods/Finitedifferences/Schemes/HundsdorferScheme.cs +++ b/src/QLNet/Methods/Finitedifferences/Schemes/HundsdorferScheme.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -31,8 +31,8 @@ public HundsdorferScheme() { } public HundsdorferScheme(double theta, double mu, - FdmLinearOpComposite map, - List> bcSet = null) + FdmLinearOpComposite map, + List> bcSet = null) { dt_ = null; theta_ = theta; @@ -48,7 +48,7 @@ public IMixedScheme factory(object L, object bcs, object[] additionalInputs = nu double? theta = additionalInputs[0] as double?; double? mu = additionalInputs[1] as double?; return new HundsdorferScheme(theta.Value, mu.Value, - L as FdmLinearOpComposite, bcs as List>); + L as FdmLinearOpComposite, bcs as List>); } #endregion diff --git a/src/QLNet/Methods/Finitedifferences/Schemes/ImplicitEulerScheme.cs b/src/QLNet/Methods/Finitedifferences/Schemes/ImplicitEulerScheme.cs index fd2829e3e..9c8abc34c 100644 --- a/src/QLNet/Methods/Finitedifferences/Schemes/ImplicitEulerScheme.cs +++ b/src/QLNet/Methods/Finitedifferences/Schemes/ImplicitEulerScheme.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,81 +23,83 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class ImplicitEulerScheme : IMixedScheme, ISchemeFactory - { - public enum SolverType { BiCGstab, GMRES } - - public ImplicitEulerScheme() { } - public ImplicitEulerScheme(FdmLinearOpComposite map, - List> bcSet, - double relTol = 1e-8, - SolverType solverType = SolverType.BiCGstab) - { - dt_ = null; - iterations_ = 0; - relTol_ = relTol; - map_ = map; - bcSet_ = new BoundaryConditionSchemeHelper(bcSet); - solverType_ = solverType; - } - - #region ISchemeFactory - public IMixedScheme factory(object L, object bcs, object[] additionalFields = null) - { - return new ImplicitEulerScheme(L as FdmLinearOpComposite, bcs as List>); - } - #endregion - - #region IMixedScheme interface - public void step(ref object a, double t) - { - Utils.QL_REQUIRE(t-dt_.Value > -1e-8, () => "a step towards negative time given"); - map_.setTime(Math.Max(0.0, t-dt_.Value), t); - bcSet_.setTime(Math.Max(0.0, t-dt_.Value)); - - bcSet_.applyBeforeSolving(map_, a as Vector); - - if (solverType_ == SolverType.BiCGstab) { - BiCGStabResult result = - new BiCGStab(this.apply, Math.Max(10, (a as Vector).Count), relTol_, x => map_.preconditioner(x, -dt_.Value)).solve(a as Vector, a as Vector); - - iterations_ += result.Iterations; - a = result.X; - } - else if (solverType_ == SolverType.GMRES) { - GMRESResult result = - new GMRES(this.apply, Math.Max(10, (a as Vector).Count) / 10, relTol_, x => map_.preconditioner(x, -dt_.Value)).solve(a as Vector, a as Vector); - - iterations_ += result.Errors.Count; - a = result.X; - } - else - Utils.QL_FAIL("unknown/illegal solver type"); - - bcSet_.applyAfterSolving(a as Vector); - } - - public void setStep(double dt) - { - dt_ = dt; - } - #endregion - - public int numberOfIterations() - { - return iterations_; - } - - protected Vector apply(Vector r) - { - return r - dt_.Value * map_.apply(r); - } - - protected double? dt_; - protected int iterations_; - protected double relTol_; - protected FdmLinearOpComposite map_; - protected BoundaryConditionSchemeHelper bcSet_; - protected SolverType solverType_; - } + public class ImplicitEulerScheme : IMixedScheme, ISchemeFactory + { + public enum SolverType { BiCGstab, GMRES } + + public ImplicitEulerScheme() { } + public ImplicitEulerScheme(FdmLinearOpComposite map, + List> bcSet, + double relTol = 1e-8, + SolverType solverType = SolverType.BiCGstab) + { + dt_ = null; + iterations_ = 0; + relTol_ = relTol; + map_ = map; + bcSet_ = new BoundaryConditionSchemeHelper(bcSet); + solverType_ = solverType; + } + + #region ISchemeFactory + public IMixedScheme factory(object L, object bcs, object[] additionalFields = null) + { + return new ImplicitEulerScheme(L as FdmLinearOpComposite, bcs as List>); + } + #endregion + + #region IMixedScheme interface + public void step(ref object a, double t) + { + Utils.QL_REQUIRE(t - dt_.Value > -1e-8, () => "a step towards negative time given"); + map_.setTime(Math.Max(0.0, t - dt_.Value), t); + bcSet_.setTime(Math.Max(0.0, t - dt_.Value)); + + bcSet_.applyBeforeSolving(map_, a as Vector); + + if (solverType_ == SolverType.BiCGstab) + { + BiCGStabResult result = + new BiCGStab(this.apply, Math.Max(10, (a as Vector).Count), relTol_, x => map_.preconditioner(x, -dt_.Value)).solve(a as Vector, a as Vector); + + iterations_ += result.Iterations; + a = result.X; + } + else if (solverType_ == SolverType.GMRES) + { + GMRESResult result = + new GMRES(this.apply, Math.Max(10, (a as Vector).Count) / 10, relTol_, x => map_.preconditioner(x, -dt_.Value)).solve(a as Vector, a as Vector); + + iterations_ += result.Errors.Count; + a = result.X; + } + else + Utils.QL_FAIL("unknown/illegal solver type"); + + bcSet_.applyAfterSolving(a as Vector); + } + + public void setStep(double dt) + { + dt_ = dt; + } + #endregion + + public int numberOfIterations() + { + return iterations_; + } + + protected Vector apply(Vector r) + { + return r - dt_.Value * map_.apply(r); + } + + protected double? dt_; + protected int iterations_; + protected double relTol_; + protected FdmLinearOpComposite map_; + protected BoundaryConditionSchemeHelper bcSet_; + protected SolverType solverType_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/Schemes/ModifiedCraigSneydScheme.cs b/src/QLNet/Methods/Finitedifferences/Schemes/ModifiedCraigSneydScheme.cs index 0d6bb2cc3..865afca10 100644 --- a/src/QLNet/Methods/Finitedifferences/Schemes/ModifiedCraigSneydScheme.cs +++ b/src/QLNet/Methods/Finitedifferences/Schemes/ModifiedCraigSneydScheme.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,79 +23,80 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! modified Craig-Sneyd scheme - - /*! References: - K. J. in ’t Hout and S. Foulon, - ADI finite difference schemes for option pricing in the Heston - model with correlation, http://arxiv.org/pdf/0811.3427 - */ - public class ModifiedCraigSneydScheme : IMixedScheme, ISchemeFactory - { - public ModifiedCraigSneydScheme() { } - public ModifiedCraigSneydScheme(double theta, double mu, - FdmLinearOpComposite map, - List> bcSet = null) - { - dt_ = null; - theta_ = theta; - mu_ = mu; - map_ = map; - bcSet_ = new BoundaryConditionSchemeHelper(bcSet); - } - - #region ISchemeFactory - public IMixedScheme factory(object L, object bcs, object[] additionalInputs) - { - double? theta = additionalInputs[0] as double?; - double? mu = additionalInputs[1] as double?; - return new ModifiedCraigSneydScheme(theta.Value, mu.Value, - L as FdmLinearOpComposite, bcs as List>); - } - #endregion - - #region IMixedScheme interface - public void step(ref object a, double t) - { - Utils.QL_REQUIRE(t-dt_.Value > -1e-8, () => "a step towards negative time given"); - map_.setTime(Math.Max(0.0, t-dt_.Value), t); - bcSet_.setTime(Math.Max(0.0, t - dt_.Value)); - - bcSet_.applyBeforeApplying(map_); - Vector y = (a as Vector) + dt_.Value*map_.apply(a as Vector); - bcSet_.applyAfterApplying(y); - - Vector y0 = y; - - for (int i=0; i < map_.size(); ++i) { - Vector rhs = y - theta_ * dt_.Value * map_.apply_direction(i, a as Vector); - y = map_.solve_splitting(i, rhs, -theta_*dt_.Value); - } - - bcSet_.applyBeforeApplying(map_); - Vector yt = y0 + mu_ * dt_.Value * map_.apply_mixed(y - (a as Vector)) - +(0.5-mu_)*dt_.Value*map_.apply(y-(a as Vector));; - bcSet_.applyAfterApplying(yt); - - for (int i = 0; i < map_.size(); ++i) - { - Vector rhs = yt - theta_ * dt_.Value * map_.apply_direction(i, a as Vector); - yt = map_.solve_splitting(i, rhs, -theta_*dt_.Value); - } - bcSet_.applyAfterSolving(yt); - - a = yt; - } - - public void setStep(double dt) - { - dt_ = dt; - } - #endregion - - protected double? dt_; - protected double theta_, mu_; - protected FdmLinearOpComposite map_; - protected BoundaryConditionSchemeHelper bcSet_; - } + //! modified Craig-Sneyd scheme + + /*! References: + K. J. in ’t Hout and S. Foulon, + ADI finite difference schemes for option pricing in the Heston + model with correlation, http://arxiv.org/pdf/0811.3427 + */ + public class ModifiedCraigSneydScheme : IMixedScheme, ISchemeFactory + { + public ModifiedCraigSneydScheme() { } + public ModifiedCraigSneydScheme(double theta, double mu, + FdmLinearOpComposite map, + List> bcSet = null) + { + dt_ = null; + theta_ = theta; + mu_ = mu; + map_ = map; + bcSet_ = new BoundaryConditionSchemeHelper(bcSet); + } + + #region ISchemeFactory + public IMixedScheme factory(object L, object bcs, object[] additionalInputs) + { + double? theta = additionalInputs[0] as double?; + double? mu = additionalInputs[1] as double?; + return new ModifiedCraigSneydScheme(theta.Value, mu.Value, + L as FdmLinearOpComposite, bcs as List>); + } + #endregion + + #region IMixedScheme interface + public void step(ref object a, double t) + { + Utils.QL_REQUIRE(t - dt_.Value > -1e-8, () => "a step towards negative time given"); + map_.setTime(Math.Max(0.0, t - dt_.Value), t); + bcSet_.setTime(Math.Max(0.0, t - dt_.Value)); + + bcSet_.applyBeforeApplying(map_); + Vector y = (a as Vector) + dt_.Value * map_.apply(a as Vector); + bcSet_.applyAfterApplying(y); + + Vector y0 = y; + + for (int i = 0; i < map_.size(); ++i) + { + Vector rhs = y - theta_ * dt_.Value * map_.apply_direction(i, a as Vector); + y = map_.solve_splitting(i, rhs, -theta_ * dt_.Value); + } + + bcSet_.applyBeforeApplying(map_); + Vector yt = y0 + mu_ * dt_.Value * map_.apply_mixed(y - (a as Vector)) + + (0.5 - mu_) * dt_.Value * map_.apply(y - (a as Vector));; + bcSet_.applyAfterApplying(yt); + + for (int i = 0; i < map_.size(); ++i) + { + Vector rhs = yt - theta_ * dt_.Value * map_.apply_direction(i, a as Vector); + yt = map_.solve_splitting(i, rhs, -theta_ * dt_.Value); + } + bcSet_.applyAfterSolving(yt); + + a = yt; + } + + public void setStep(double dt) + { + dt_ = dt; + } + #endregion + + protected double? dt_; + protected double theta_, mu_; + protected FdmLinearOpComposite map_; + protected BoundaryConditionSchemeHelper bcSet_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/ShoutCondition.cs b/src/QLNet/Methods/Finitedifferences/ShoutCondition.cs index d5b9b712c..0ea2088ab 100644 --- a/src/QLNet/Methods/Finitedifferences/ShoutCondition.cs +++ b/src/QLNet/Methods/Finitedifferences/ShoutCondition.cs @@ -1,54 +1,60 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - //! Shout option condition - /*! A shout option is an option where the holder has the right to - lock in a minimum value for the payoff at one (shout) time - during the option's life. The minimum value is the option's - intrinsic value at the shout time. - */ - public class ShoutCondition : CurveDependentStepCondition { - double resTime_; - double rate_; - double disc_; - - public ShoutCondition(Option.Type type, double strike, double resTime, double rate) - : base(type, strike) { - resTime_ = resTime; - rate_ = rate; - } - - public ShoutCondition(Vector intrinsicValues, double resTime, double rate) - : base(intrinsicValues) { - resTime_ = resTime; - rate_ = rate; - } - - public void applyTo(Vector a, double t) { - disc_ = Math.Exp(-rate_ * (t - resTime_)); - base.applyTo(a, t); - } - - protected override double applyToValue(double current, double intrinsic) { - return Math.Max(current, disc_ * intrinsic ); - } - } +namespace QLNet +{ + //! Shout option condition + /*! A shout option is an option where the holder has the right to + lock in a minimum value for the payoff at one (shout) time + during the option's life. The minimum value is the option's + intrinsic value at the shout time. + */ + public class ShoutCondition : CurveDependentStepCondition + { + double resTime_; + double rate_; + double disc_; + + public ShoutCondition(Option.Type type, double strike, double resTime, double rate) + : base(type, strike) + { + resTime_ = resTime; + rate_ = rate; + } + + public ShoutCondition(Vector intrinsicValues, double resTime, double rate) + : base(intrinsicValues) + { + resTime_ = resTime; + rate_ = rate; + } + + public void applyTo(Vector a, double t) + { + disc_ = Math.Exp(-rate_ * (t - resTime_)); + base.applyTo(a, t); + } + + protected override double applyToValue(double current, double intrinsic) + { + return Math.Max(current, disc_ * intrinsic); + } + } } diff --git a/src/QLNet/Methods/Finitedifferences/Solvers/Fdm1DimSolver.cs b/src/QLNet/Methods/Finitedifferences/Solvers/Fdm1DimSolver.cs index 7feadee82..1d0896fff 100644 --- a/src/QLNet/Methods/Finitedifferences/Solvers/Fdm1DimSolver.cs +++ b/src/QLNet/Methods/Finitedifferences/Solvers/Fdm1DimSolver.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,92 +23,92 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class Fdm1DimSolver : LazyObject - { - public Fdm1DimSolver(FdmSolverDesc solverDesc, - FdmSchemeDesc schemeDesc, - FdmLinearOpComposite op) - { - solverDesc_ = solverDesc; - schemeDesc_ = schemeDesc; - op_ = op; - thetaCondition_ = new FdmSnapshotCondition( - 0.99*Math.Min(1.0/365.0, - solverDesc.condition.stoppingTimes().empty() - ? solverDesc.maturity - : solverDesc.condition.stoppingTimes().First())); - - conditions_ = FdmStepConditionComposite.joinConditions(thetaCondition_, - solverDesc.condition); - x_ = new InitializedList(solverDesc.mesher.layout().size()); - initialValues_= new InitializedList(solverDesc.mesher.layout().size()); - resultValues_ = new Vector(solverDesc.mesher.layout().size()); - - FdmMesher mesher = solverDesc.mesher; - FdmLinearOpLayout layout = mesher.layout(); - - FdmLinearOpIterator endIter = layout.end(); - for (FdmLinearOpIterator iter = layout.begin(); iter != endIter; - ++iter) - { - initialValues_[iter.index()] - = solverDesc_.calculator.avgInnerValue(iter, - solverDesc.maturity); - x_[iter.index()] = mesher.location(iter, 0); - } - } - - public double interpolateAt(double x) - { - calculate(); - return interpolation_.value(x); - } - public double thetaAt(double x) - { - Utils.QL_REQUIRE(conditions_.stoppingTimes().First() > 0.0, - () => "stopping time at zero-> can't calculate theta"); - - calculate(); - Vector thetaValues = new Vector(resultValues_.size()); - thetaValues = thetaCondition_.getValues(); - - double temp = new MonotonicCubicNaturalSpline( - x_, x_.Count, thetaValues).value(x); - return ( temp - interpolateAt(x) ) / thetaCondition_.getTime(); - } - public double derivativeX(double x) - { - calculate(); - return interpolation_.derivative(x); - } - public double derivativeXX(double x) - { - calculate(); - return interpolation_.secondDerivative(x); - } - protected override void performCalculations() - { - object rhs = new Vector(initialValues_.Count); - for(int i = 0; i < initialValues_.Count; i++) - (rhs as Vector)[i] = initialValues_[i]; - - new FdmBackwardSolver(op_, solverDesc_.bcSet, conditions_, schemeDesc_) - .rollback(ref rhs, solverDesc_.maturity, 0.0, - solverDesc_.timeSteps, solverDesc_.dampingSteps); - - for (int i = 0; i < initialValues_.Count; i++) - resultValues_[i] = (rhs as Vector)[i]; - - interpolation_ = new MonotonicCubicNaturalSpline(x_, x_.Count, resultValues_); - } - - protected FdmSolverDesc solverDesc_; - protected FdmSchemeDesc schemeDesc_; - protected FdmLinearOpComposite op_; - protected FdmSnapshotCondition thetaCondition_; - protected FdmStepConditionComposite conditions_; - protected List x_, initialValues_; - protected Vector resultValues_; - protected CubicInterpolation interpolation_; - } + public class Fdm1DimSolver : LazyObject + { + public Fdm1DimSolver(FdmSolverDesc solverDesc, + FdmSchemeDesc schemeDesc, + FdmLinearOpComposite op) + { + solverDesc_ = solverDesc; + schemeDesc_ = schemeDesc; + op_ = op; + thetaCondition_ = new FdmSnapshotCondition( + 0.99 * Math.Min(1.0 / 365.0, + solverDesc.condition.stoppingTimes().empty() + ? solverDesc.maturity + : solverDesc.condition.stoppingTimes().First())); + + conditions_ = FdmStepConditionComposite.joinConditions(thetaCondition_, + solverDesc.condition); + x_ = new InitializedList(solverDesc.mesher.layout().size()); + initialValues_ = new InitializedList(solverDesc.mesher.layout().size()); + resultValues_ = new Vector(solverDesc.mesher.layout().size()); + + FdmMesher mesher = solverDesc.mesher; + FdmLinearOpLayout layout = mesher.layout(); + + FdmLinearOpIterator endIter = layout.end(); + for (FdmLinearOpIterator iter = layout.begin(); iter != endIter; + ++iter) + { + initialValues_[iter.index()] + = solverDesc_.calculator.avgInnerValue(iter, + solverDesc.maturity); + x_[iter.index()] = mesher.location(iter, 0); + } + } + + public double interpolateAt(double x) + { + calculate(); + return interpolation_.value(x); + } + public double thetaAt(double x) + { + Utils.QL_REQUIRE(conditions_.stoppingTimes().First() > 0.0, + () => "stopping time at zero-> can't calculate theta"); + + calculate(); + Vector thetaValues = new Vector(resultValues_.size()); + thetaValues = thetaCondition_.getValues(); + + double temp = new MonotonicCubicNaturalSpline( + x_, x_.Count, thetaValues).value(x); + return (temp - interpolateAt(x)) / thetaCondition_.getTime(); + } + public double derivativeX(double x) + { + calculate(); + return interpolation_.derivative(x); + } + public double derivativeXX(double x) + { + calculate(); + return interpolation_.secondDerivative(x); + } + protected override void performCalculations() + { + object rhs = new Vector(initialValues_.Count); + for (int i = 0; i < initialValues_.Count; i++) + (rhs as Vector)[i] = initialValues_[i]; + + new FdmBackwardSolver(op_, solverDesc_.bcSet, conditions_, schemeDesc_) + .rollback(ref rhs, solverDesc_.maturity, 0.0, + solverDesc_.timeSteps, solverDesc_.dampingSteps); + + for (int i = 0; i < initialValues_.Count; i++) + resultValues_[i] = (rhs as Vector)[i]; + + interpolation_ = new MonotonicCubicNaturalSpline(x_, x_.Count, resultValues_); + } + + protected FdmSolverDesc solverDesc_; + protected FdmSchemeDesc schemeDesc_; + protected FdmLinearOpComposite op_; + protected FdmSnapshotCondition thetaCondition_; + protected FdmStepConditionComposite conditions_; + protected List x_, initialValues_; + protected Vector resultValues_; + protected CubicInterpolation interpolation_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/Solvers/FdmBackwardSolver.cs b/src/QLNet/Methods/Finitedifferences/Solvers/FdmBackwardSolver.cs index 0e7e34a4a..a3d0bed4d 100644 --- a/src/QLNet/Methods/Finitedifferences/Solvers/FdmBackwardSolver.cs +++ b/src/QLNet/Methods/Finitedifferences/Solvers/FdmBackwardSolver.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,153 +21,155 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class FdmSchemeDesc - { - public enum FdmSchemeType - { - HundsdorferType, DouglasType, - CraigSneydType, ModifiedCraigSneydType, - ImplicitEulerType, ExplicitEulerType - } - - public FdmSchemeDesc() { } - public FdmSchemeDesc(FdmSchemeType type, double theta, double mu) - { - type_ = type; - theta_ = theta; - mu_ = mu; - } - - public FdmSchemeType type - { - get + public class FdmSchemeDesc + { + public enum FdmSchemeType + { + HundsdorferType, DouglasType, + CraigSneydType, ModifiedCraigSneydType, + ImplicitEulerType, ExplicitEulerType + } + + public FdmSchemeDesc() { } + public FdmSchemeDesc(FdmSchemeType type, double theta, double mu) + { + type_ = type; + theta_ = theta; + mu_ = mu; + } + + public FdmSchemeType type + { + get + { + return type_; + } + } + + public double theta + { + get + { + return theta_; + } + } + + public double mu + { + get + { + return mu_; + } + } + + protected FdmSchemeType type_; + private double theta_, mu_; + + // some default scheme descriptions + public FdmSchemeDesc Douglas() { return new FdmSchemeDesc(FdmSchemeType.DouglasType, 0.5, 0.0); } + public FdmSchemeDesc ImplicitEuler() { return new FdmSchemeDesc(FdmSchemeType.ImplicitEulerType, 0.0, 0.0); } + public FdmSchemeDesc ExplicitEuler() { return new FdmSchemeDesc(FdmSchemeType.ExplicitEulerType, 0.0, 0.0); } + public FdmSchemeDesc CraigSneyd() { return new FdmSchemeDesc(FdmSchemeType.CraigSneydType, 0.5, 0.5); } + public FdmSchemeDesc ModifiedCraigSneyd() { return new FdmSchemeDesc(FdmSchemeType.ModifiedCraigSneydType, 1.0 / 3.0, 1.0 / 3.0); } + public FdmSchemeDesc Hundsdorfer() { return new FdmSchemeDesc(FdmSchemeType.HundsdorferType, 0.5 + Math.Sqrt(3.0) / 6.0, 0.5); } + public FdmSchemeDesc ModifiedHundsdorfer() { return new FdmSchemeDesc(FdmSchemeType.HundsdorferType, 1.0 - Math.Sqrt(2.0) / 2.0, 0.5); } + } + + public class FdmBackwardSolver + { + public FdmBackwardSolver(FdmLinearOpComposite map, + FdmBoundaryConditionSet bcSet, + FdmStepConditionComposite condition, + FdmSchemeDesc schemeDesc) + { + map_ = map; + bcSet_ = bcSet; + condition_ = condition; + schemeDesc_ = schemeDesc; + } + + public void rollback(ref object a, + double from, double to, + int steps, int dampingSteps) + { + double deltaT = from - to; + int allSteps = steps + dampingSteps; + double dampingTo = from - (deltaT * dampingSteps) / allSteps; + + if (dampingSteps > 0 + && schemeDesc_.type != FdmSchemeDesc.FdmSchemeType.ImplicitEulerType) + { + ImplicitEulerScheme implicitEvolver = new ImplicitEulerScheme(map_, bcSet_); + FiniteDifferenceModel dampingModel + = new FiniteDifferenceModel(implicitEvolver, condition_.stoppingTimes()); + + dampingModel.rollback(ref a, from, dampingTo, + dampingSteps, condition_); + } + + switch (schemeDesc_.type) + { + case FdmSchemeDesc.FdmSchemeType.HundsdorferType: { - return type_; + HundsdorferScheme hsEvolver = new HundsdorferScheme(schemeDesc_.theta, schemeDesc_.mu, + map_, bcSet_); + FiniteDifferenceModel + hsModel = new FiniteDifferenceModel(hsEvolver, condition_.stoppingTimes()); + hsModel.rollback(ref a, dampingTo, to, steps, condition_); } - } - - public double theta - { - get + break; + case FdmSchemeDesc.FdmSchemeType.DouglasType: { - return theta_; + DouglasScheme dsEvolver = new DouglasScheme(schemeDesc_.theta, map_, bcSet_); + FiniteDifferenceModel + dsModel = new FiniteDifferenceModel(dsEvolver, condition_.stoppingTimes()); + dsModel.rollback(ref a, dampingTo, to, steps, condition_); } - } - - public double mu - { - get + break; + case FdmSchemeDesc.FdmSchemeType.CraigSneydType: { - return mu_; + CraigSneydScheme csEvolver = new CraigSneydScheme(schemeDesc_.theta, schemeDesc_.mu, + map_, bcSet_); + FiniteDifferenceModel + csModel = new FiniteDifferenceModel(csEvolver, condition_.stoppingTimes()); + csModel.rollback(ref a, dampingTo, to, steps, condition_); } - } - - protected FdmSchemeType type_; - private double theta_, mu_; - - // some default scheme descriptions - public FdmSchemeDesc Douglas() { return new FdmSchemeDesc(FdmSchemeType.DouglasType, 0.5, 0.0); } - public FdmSchemeDesc ImplicitEuler() { return new FdmSchemeDesc(FdmSchemeType.ImplicitEulerType, 0.0, 0.0); } - public FdmSchemeDesc ExplicitEuler() { return new FdmSchemeDesc(FdmSchemeType.ExplicitEulerType, 0.0, 0.0); } - public FdmSchemeDesc CraigSneyd() { return new FdmSchemeDesc(FdmSchemeType.CraigSneydType, 0.5, 0.5); } - public FdmSchemeDesc ModifiedCraigSneyd() { return new FdmSchemeDesc(FdmSchemeType.ModifiedCraigSneydType, 1.0 / 3.0, 1.0 / 3.0); } - public FdmSchemeDesc Hundsdorfer() { return new FdmSchemeDesc(FdmSchemeType.HundsdorferType, 0.5 + Math.Sqrt(3.0) / 6.0, 0.5); } - public FdmSchemeDesc ModifiedHundsdorfer() { return new FdmSchemeDesc(FdmSchemeType.HundsdorferType, 1.0 - Math.Sqrt(2.0) / 2.0, 0.5); } - } - - public class FdmBackwardSolver - { - public FdmBackwardSolver(FdmLinearOpComposite map, - FdmBoundaryConditionSet bcSet, - FdmStepConditionComposite condition, - FdmSchemeDesc schemeDesc) - { - map_ = map; - bcSet_ = bcSet; - condition_ = condition; - schemeDesc_ = schemeDesc; - } - - public void rollback(ref object a, - double from, double to, - int steps, int dampingSteps) - { - double deltaT = from - to; - int allSteps = steps + dampingSteps; - double dampingTo = from - (deltaT*dampingSteps)/allSteps; - - if ( dampingSteps > 0 - && schemeDesc_.type != FdmSchemeDesc.FdmSchemeType.ImplicitEulerType) { - ImplicitEulerScheme implicitEvolver = new ImplicitEulerScheme(map_, bcSet_); - FiniteDifferenceModel dampingModel - = new FiniteDifferenceModel(implicitEvolver, condition_.stoppingTimes()); - - dampingModel.rollback(ref a, from, dampingTo, - dampingSteps, condition_); + break; + case FdmSchemeDesc.FdmSchemeType.ModifiedCraigSneydType: + { + ModifiedCraigSneydScheme csEvolver = new ModifiedCraigSneydScheme(schemeDesc_.theta, + schemeDesc_.mu, + map_, bcSet_); + FiniteDifferenceModel + mcsModel = new FiniteDifferenceModel(csEvolver, condition_.stoppingTimes()); + mcsModel.rollback(ref a, dampingTo, to, steps, condition_); } - - switch (schemeDesc_.type) { - case FdmSchemeDesc.FdmSchemeType.HundsdorferType: - { - HundsdorferScheme hsEvolver = new HundsdorferScheme(schemeDesc_.theta, schemeDesc_.mu, - map_, bcSet_); - FiniteDifferenceModel - hsModel = new FiniteDifferenceModel(hsEvolver, condition_.stoppingTimes()); - hsModel.rollback(ref a, dampingTo, to, steps, condition_); - } - break; - case FdmSchemeDesc.FdmSchemeType.DouglasType: - { - DouglasScheme dsEvolver = new DouglasScheme(schemeDesc_.theta, map_, bcSet_); - FiniteDifferenceModel - dsModel = new FiniteDifferenceModel(dsEvolver, condition_.stoppingTimes()); - dsModel.rollback(ref a, dampingTo, to, steps, condition_); - } - break; - case FdmSchemeDesc.FdmSchemeType.CraigSneydType: - { - CraigSneydScheme csEvolver = new CraigSneydScheme(schemeDesc_.theta, schemeDesc_.mu, - map_, bcSet_); - FiniteDifferenceModel - csModel = new FiniteDifferenceModel(csEvolver, condition_.stoppingTimes()); - csModel.rollback(ref a, dampingTo, to, steps, condition_); - } - break; - case FdmSchemeDesc.FdmSchemeType.ModifiedCraigSneydType: - { - ModifiedCraigSneydScheme csEvolver = new ModifiedCraigSneydScheme(schemeDesc_.theta, - schemeDesc_.mu, - map_, bcSet_); - FiniteDifferenceModel - mcsModel = new FiniteDifferenceModel(csEvolver, condition_.stoppingTimes()); - mcsModel.rollback(ref a, dampingTo, to, steps, condition_); - } - break; - case FdmSchemeDesc.FdmSchemeType.ImplicitEulerType: - { - ImplicitEulerScheme implicitEvolver = new ImplicitEulerScheme(map_, bcSet_); - FiniteDifferenceModel - implicitModel = new FiniteDifferenceModel(implicitEvolver, condition_.stoppingTimes()); - implicitModel.rollback(ref a, from, to, allSteps, condition_); - } - break; - case FdmSchemeDesc.FdmSchemeType.ExplicitEulerType: - { - ExplicitEulerScheme explicitEvolver = new ExplicitEulerScheme(map_, bcSet_); - FiniteDifferenceModel - explicitModel = new FiniteDifferenceModel(explicitEvolver, condition_.stoppingTimes()); - explicitModel.rollback(ref a, dampingTo, to, steps, condition_); - } - break; - default: - Utils.QL_FAIL("Unknown scheme type"); - break; + break; + case FdmSchemeDesc.FdmSchemeType.ImplicitEulerType: + { + ImplicitEulerScheme implicitEvolver = new ImplicitEulerScheme(map_, bcSet_); + FiniteDifferenceModel + implicitModel = new FiniteDifferenceModel(implicitEvolver, condition_.stoppingTimes()); + implicitModel.rollback(ref a, from, to, allSteps, condition_); + } + break; + case FdmSchemeDesc.FdmSchemeType.ExplicitEulerType: + { + ExplicitEulerScheme explicitEvolver = new ExplicitEulerScheme(map_, bcSet_); + FiniteDifferenceModel + explicitModel = new FiniteDifferenceModel(explicitEvolver, condition_.stoppingTimes()); + explicitModel.rollback(ref a, dampingTo, to, steps, condition_); } - } + break; + default: + Utils.QL_FAIL("Unknown scheme type"); + break; + } + } - protected FdmLinearOpComposite map_; - protected FdmBoundaryConditionSet bcSet_; - protected FdmStepConditionComposite condition_; - protected FdmSchemeDesc schemeDesc_; - } + protected FdmLinearOpComposite map_; + protected FdmBoundaryConditionSet bcSet_; + protected FdmStepConditionComposite condition_; + protected FdmSchemeDesc schemeDesc_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/Solvers/FdmBlackScholesSolver.cs b/src/QLNet/Methods/Finitedifferences/Solvers/FdmBlackScholesSolver.cs index bcdfe5c83..b22019558 100644 --- a/src/QLNet/Methods/Finitedifferences/Solvers/FdmBlackScholesSolver.cs +++ b/src/QLNet/Methods/Finitedifferences/Solvers/FdmBlackScholesSolver.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,58 +21,61 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class FdmBlackScholesSolver : LazyObject - { - public FdmBlackScholesSolver( - Handle process, - double strike, - FdmSolverDesc solverDesc, - FdmSchemeDesc schemeDesc = null, - bool localVol = false, - double? illegalLocalVolOverwrite = null) - { - process_ = process; - strike_ = strike; - solverDesc_ = solverDesc; - schemeDesc_ = schemeDesc ?? new FdmSchemeDesc().Douglas(); - localVol_ = localVol; - illegalLocalVolOverwrite_ = illegalLocalVolOverwrite; - } + public class FdmBlackScholesSolver : LazyObject + { + public FdmBlackScholesSolver( + Handle process, + double strike, + FdmSolverDesc solverDesc, + FdmSchemeDesc schemeDesc = null, + bool localVol = false, + double? illegalLocalVolOverwrite = null) + { + process_ = process; + strike_ = strike; + solverDesc_ = solverDesc; + schemeDesc_ = schemeDesc ?? new FdmSchemeDesc().Douglas(); + localVol_ = localVol; + illegalLocalVolOverwrite_ = illegalLocalVolOverwrite; + } + + public double valueAt(double s) + { + calculate(); + return solver_.interpolateAt(Math.Log(s)); + } + public double deltaAt(double s) + { + calculate(); + return solver_.derivativeX(Math.Log(s)) / s; + } + public double gammaAt(double s) + { + calculate(); + return (solver_.derivativeXX(Math.Log(s)) + - solver_.derivativeX(Math.Log(s))) / (s * s); + } + public double thetaAt(double s) + { + return solver_.thetaAt(Math.Log(s)); + } - public double valueAt(double s) - { - calculate(); - return solver_.interpolateAt(Math.Log(s)); - } - public double deltaAt(double s) { - calculate(); - return solver_.derivativeX(Math.Log(s)) / s; - } - public double gammaAt(double s) { - calculate(); - return (solver_.derivativeXX(Math.Log(s)) - - solver_.derivativeX(Math.Log(s))) / (s * s); - } - public double thetaAt(double s) { - return solver_.thetaAt(Math.Log(s)); - } - - protected override void performCalculations() - { - FdmBlackScholesOp op = new FdmBlackScholesOp( - solverDesc_.mesher, process_.currentLink(), strike_, - localVol_, illegalLocalVolOverwrite_); + protected override void performCalculations() + { + FdmBlackScholesOp op = new FdmBlackScholesOp( + solverDesc_.mesher, process_.currentLink(), strike_, + localVol_, illegalLocalVolOverwrite_); - solver_ = new Fdm1DimSolver(solverDesc_, schemeDesc_, op); - } + solver_ = new Fdm1DimSolver(solverDesc_, schemeDesc_, op); + } - protected Handle process_; - protected double strike_; - protected FdmSolverDesc solverDesc_; - protected FdmSchemeDesc schemeDesc_; - protected bool localVol_; - protected double? illegalLocalVolOverwrite_; - protected Fdm1DimSolver solver_; - } + protected Handle process_; + protected double strike_; + protected FdmSolverDesc solverDesc_; + protected FdmSchemeDesc schemeDesc_; + protected bool localVol_; + protected double? illegalLocalVolOverwrite_; + protected Fdm1DimSolver solver_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/Solvers/FdmHullWhiteSolver.cs b/src/QLNet/Methods/Finitedifferences/Solvers/FdmHullWhiteSolver.cs index f0b11c3ee..873898b75 100644 --- a/src/QLNet/Methods/Finitedifferences/Solvers/FdmHullWhiteSolver.cs +++ b/src/QLNet/Methods/Finitedifferences/Solvers/FdmHullWhiteSolver.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,45 +21,48 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class FdmHullWhiteSolver : LazyObject - { - public FdmHullWhiteSolver( - Handle model, - FdmSolverDesc solverDesc, - FdmSchemeDesc schemeDesc = null) - { - solverDesc_ = solverDesc; - schemeDesc_ = schemeDesc ?? new FdmSchemeDesc().Hundsdorfer(); - model_ = model; - model_.registerWith(update); - } + public class FdmHullWhiteSolver : LazyObject + { + public FdmHullWhiteSolver( + Handle model, + FdmSolverDesc solverDesc, + FdmSchemeDesc schemeDesc = null) + { + solverDesc_ = solverDesc; + schemeDesc_ = schemeDesc ?? new FdmSchemeDesc().Hundsdorfer(); + model_ = model; + model_.registerWith(update); + } + + public double valueAt(double s) + { + calculate(); + return solver_.interpolateAt(s); + } + public double deltaAt(double s) + { + return 0.0; + } + public double gammaAt(double s) + { + return 0.0; + } + public double thetaAt(double s) + { + return 0.0; + } + + protected override void performCalculations() + { + FdmHullWhiteOp op = new FdmHullWhiteOp( + solverDesc_.mesher, model_.currentLink(), 0); - public double valueAt(double s) - { - calculate(); - return solver_.interpolateAt(s); - } - public double deltaAt(double s) { - return 0.0; - } - public double gammaAt(double s) { - return 0.0; - } - public double thetaAt(double s) { - return 0.0; - } - - protected override void performCalculations() - { - FdmHullWhiteOp op = new FdmHullWhiteOp( - solverDesc_.mesher, model_.currentLink(), 0); + solver_ = new Fdm1DimSolver(solverDesc_, schemeDesc_, op); + } - solver_ = new Fdm1DimSolver(solverDesc_, schemeDesc_, op); - } - - protected Handle model_; - protected FdmSolverDesc solverDesc_; - protected FdmSchemeDesc schemeDesc_; - protected Fdm1DimSolver solver_; - } + protected Handle model_; + protected FdmSolverDesc solverDesc_; + protected FdmSchemeDesc schemeDesc_; + protected Fdm1DimSolver solver_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/Solvers/FdmSolverDesc.cs b/src/QLNet/Methods/Finitedifferences/Solvers/FdmSolverDesc.cs index 55defc61f..56bb66f7d 100644 --- a/src/QLNet/Methods/Finitedifferences/Solvers/FdmSolverDesc.cs +++ b/src/QLNet/Methods/Finitedifferences/Solvers/FdmSolverDesc.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -31,44 +31,86 @@ public struct FdmSolverDesc public FdmMesher mesher { - get { return _mesher; } - set { _mesher = value; } + get + { + return _mesher; + } + set + { + _mesher = value; + } } public FdmBoundaryConditionSet bcSet { - get { return _bcSet; } - set { _bcSet = value; } + get + { + return _bcSet; + } + set + { + _bcSet = value; + } } public FdmStepConditionComposite condition { - get { return _condition; } - set { _condition = value; } + get + { + return _condition; + } + set + { + _condition = value; + } } public FdmInnerValueCalculator calculator { - get { return _calculator; } - set { _calculator = value; } + get + { + return _calculator; + } + set + { + _calculator = value; + } } public double maturity { - get { return _maturity; } - set { _maturity = value; } + get + { + return _maturity; + } + set + { + _maturity = value; + } } public int timeSteps { - get { return _timeSteps; } - set { _timeSteps = value; } + get + { + return _timeSteps; + } + set + { + _timeSteps = value; + } } public int dampingSteps { - get { return _dampingSteps; } - set { _dampingSteps = value; } + get + { + return _dampingSteps; + } + set + { + _dampingSteps = value; + } } } } diff --git a/src/QLNet/Methods/Finitedifferences/StepCondition.cs b/src/QLNet/Methods/Finitedifferences/StepCondition.cs index 6fa033fd7..9f6cc1853 100644 --- a/src/QLNet/Methods/Finitedifferences/StepCondition.cs +++ b/src/QLNet/Methods/Finitedifferences/StepCondition.cs @@ -1,96 +1,114 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - //! condition to be applied at every time step - /*! \ingroup findiff */ - public interface IStepCondition where array_type : Vector { - void applyTo(object o, double t); - } - - - /* Abstract base class which allows step conditions to use both payoff and array functions */ - public class CurveDependentStepCondition : IStepCondition where array_type : Vector { - CurveWrapper curveItem_; - - protected CurveDependentStepCondition(Option.Type type, double strike) { - curveItem_ = new PayoffWrapper(type, strike); - } - protected CurveDependentStepCondition(Payoff p) { - curveItem_ = new PayoffWrapper(p); - } - protected CurveDependentStepCondition(array_type a) { - curveItem_ = new ArrayWrapper(a); - } - - protected double getValue(array_type a, int index) { - return curveItem_.getValue(a, index); - } - - public void applyTo(object o, double t) { - Vector a = (Vector)o; - for (int i = 0; i < a.size(); i++) { - a[i] = applyToValue(a[i], getValue((array_type)o, i)); - } - } - - protected virtual double applyToValue(double a, double b) { throw new NotImplementedException(); } - - protected abstract class CurveWrapper { - public abstract double getValue(array_type a, int i); - } - - protected class ArrayWrapper : CurveWrapper { - private array_type value_; - - public ArrayWrapper(array_type a) { - value_ = a; - } - - public override double getValue(array_type a, int i) { - return value_[i]; - } - } - - protected class PayoffWrapper : CurveWrapper { - private Payoff payoff_; - - public PayoffWrapper(Payoff p) { - payoff_ = p; - } - public PayoffWrapper(Option.Type type, double strike) { - payoff_ = new PlainVanillaPayoff(type, strike); - } - public override double getValue(array_type a, int i) { - return a[i]; - } - } - } - - - //! %null step condition - /*! \ingroup findiff */ - public class NullCondition : IStepCondition where array_type : Vector { - public void applyTo(object a, double t) - { - // Nothing to do here - } - } +namespace QLNet +{ + //! condition to be applied at every time step + /*! \ingroup findiff */ + public interface IStepCondition where array_type : Vector + { + void applyTo(object o, double t); + } + + + /* Abstract base class which allows step conditions to use both payoff and array functions */ + public class CurveDependentStepCondition : IStepCondition where array_type : Vector + { + CurveWrapper curveItem_; + + protected CurveDependentStepCondition(Option.Type type, double strike) + { + curveItem_ = new PayoffWrapper(type, strike); + } + protected CurveDependentStepCondition(Payoff p) + { + curveItem_ = new PayoffWrapper(p); + } + protected CurveDependentStepCondition(array_type a) + { + curveItem_ = new ArrayWrapper(a); + } + + protected double getValue(array_type a, int index) + { + return curveItem_.getValue(a, index); + } + + public void applyTo(object o, double t) + { + Vector a = (Vector)o; + for (int i = 0; i < a.size(); i++) + { + a[i] = applyToValue(a[i], getValue((array_type)o, i)); + } + } + + protected virtual double applyToValue(double a, double b) { throw new NotImplementedException(); } + + protected abstract class CurveWrapper + { + public abstract double getValue(array_type a, int i); + } + + protected class ArrayWrapper : CurveWrapper + { + private array_type value_; + + public ArrayWrapper(array_type a) + { + value_ = a; + } + + public override double getValue(array_type a, int i) + { + return value_[i]; + } + } + + protected class PayoffWrapper : CurveWrapper + { + private Payoff payoff_; + + public PayoffWrapper(Payoff p) + { + payoff_ = p; + } + public PayoffWrapper(Option.Type type, double strike) + { + payoff_ = new PlainVanillaPayoff(type, strike); + } + public override double getValue(array_type a, int i) + { + return a[i]; + } + } + } + + + //! %null step condition + /*! \ingroup findiff */ + public class NullCondition : IStepCondition where array_type : Vector + { + public void applyTo(object a, double t) + { + // Nothing to do here + } + } } diff --git a/src/QLNet/Methods/Finitedifferences/StepConditions/FdmAmericanStepCondition.cs b/src/QLNet/Methods/Finitedifferences/StepConditions/FdmAmericanStepCondition.cs index bdf556359..1f97893b6 100644 --- a/src/QLNet/Methods/Finitedifferences/StepConditions/FdmAmericanStepCondition.cs +++ b/src/QLNet/Methods/Finitedifferences/StepConditions/FdmAmericanStepCondition.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,32 +23,32 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class FdmAmericanStepCondition : IStepCondition - { - public FdmAmericanStepCondition(FdmMesher mesher, FdmInnerValueCalculator calculator) - { - mesher_ = mesher; - calculator_ = calculator; - } - - public void applyTo(object o, double t) - { - Vector a = (Vector)o; - FdmLinearOpLayout layout = mesher_.layout(); - FdmLinearOpIterator endIter = layout.end(); - - for (FdmLinearOpIterator iter = layout.begin(); iter != endIter; - ++iter) + public class FdmAmericanStepCondition : IStepCondition + { + public FdmAmericanStepCondition(FdmMesher mesher, FdmInnerValueCalculator calculator) + { + mesher_ = mesher; + calculator_ = calculator; + } + + public void applyTo(object o, double t) + { + Vector a = (Vector)o; + FdmLinearOpLayout layout = mesher_.layout(); + FdmLinearOpIterator endIter = layout.end(); + + for (FdmLinearOpIterator iter = layout.begin(); iter != endIter; + ++iter) + { + double innerValue = calculator_.innerValue(iter, t); + if (innerValue > a[iter.index()]) { - double innerValue = calculator_.innerValue(iter, t); - if (innerValue > a[iter.index()]) - { - a[iter.index()] = innerValue; - } + a[iter.index()] = innerValue; } - } + } + } - protected FdmMesher mesher_; - protected FdmInnerValueCalculator calculator_; - } + protected FdmMesher mesher_; + protected FdmInnerValueCalculator calculator_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/StepConditions/FdmBermudanStepCondition.cs b/src/QLNet/Methods/Finitedifferences/StepConditions/FdmBermudanStepCondition.cs index 79fa1eb8b..ebd7833bd 100644 --- a/src/QLNet/Methods/Finitedifferences/StepConditions/FdmBermudanStepCondition.cs +++ b/src/QLNet/Methods/Finitedifferences/StepConditions/FdmBermudanStepCondition.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -27,10 +27,10 @@ namespace QLNet public class FdmBermudanStepCondition : IStepCondition { public FdmBermudanStepCondition(List exerciseDates, - Date referenceDate, - DayCounter dayCounter, - FdmMesher mesher, - FdmInnerValueCalculator calculator) + Date referenceDate, + DayCounter dayCounter, + FdmMesher mesher, + FdmInnerValueCalculator calculator) { mesher_ = mesher; calculator_ = calculator; @@ -55,8 +55,8 @@ public void applyTo(object o, double t) Vector locations = new Vector(dims); for (FdmLinearOpIterator iter = layout.begin(); - iter != endIter; - ++iter) + iter != endIter; + ++iter) { for (int i = 0; i < dims; ++i) locations[i] = mesher_.location(iter, i); diff --git a/src/QLNet/Methods/Finitedifferences/StepConditions/FdmSnapshotCondition.cs b/src/QLNet/Methods/Finitedifferences/StepConditions/FdmSnapshotCondition.cs index 4d78e72d5..751d7bf79 100644 --- a/src/QLNet/Methods/Finitedifferences/StepConditions/FdmSnapshotCondition.cs +++ b/src/QLNet/Methods/Finitedifferences/StepConditions/FdmSnapshotCondition.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,23 +23,23 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class FdmSnapshotCondition : IStepCondition - { - public FdmSnapshotCondition(double t) - { - t_ = t; - } - - public void applyTo(object o, double t) - { - if (t == t_) - values_ = (Vector)o; - } - - public double getTime() { return t_; } - public Vector getValues() { return values_; } - - protected double t_; - protected Vector values_; - } + public class FdmSnapshotCondition : IStepCondition + { + public FdmSnapshotCondition(double t) + { + t_ = t; + } + + public void applyTo(object o, double t) + { + if (t == t_) + values_ = (Vector)o; + } + + public double getTime() { return t_; } + public Vector getValues() { return values_; } + + protected double t_; + protected Vector values_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/StepConditions/FdmStepConditionComposite.cs b/src/QLNet/Methods/Finitedifferences/StepConditions/FdmStepConditionComposite.cs index 57752640a..ce37af8bb 100644 --- a/src/QLNet/Methods/Finitedifferences/StepConditions/FdmStepConditionComposite.cs +++ b/src/QLNet/Methods/Finitedifferences/StepConditions/FdmStepConditionComposite.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,86 +23,91 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class FdmStepConditionComposite : IStepCondition - { - public FdmStepConditionComposite() { - conditions_ = new List>(); - stoppingTimes_ = new List(); - } - public FdmStepConditionComposite(List> stoppingTimes, List> conditions) - { - conditions_ = conditions; - - List allStoppingTimes = new List(); - foreach (List iter in stoppingTimes) { - foreach(double t in iter) - allStoppingTimes.Add(t); - } - stoppingTimes_ = allStoppingTimes.Distinct().OrderBy(x => x).ToList(); - } - - public void applyTo(object o, double t) - { - foreach(IStepCondition iter in conditions_) - iter.applyTo(o, t); - } - - public static FdmStepConditionComposite joinConditions(FdmSnapshotCondition c1, - FdmStepConditionComposite c2) - { - List> stoppingTimes = new List>(); - stoppingTimes.Add(c2.stoppingTimes()); - stoppingTimes.Add(new InitializedList(1, c1.getTime())); - - List> conditions = new List>(); - conditions.Add(c2); - conditions.Add(c1); - - return new FdmStepConditionComposite(stoppingTimes, conditions); - } - - public static FdmStepConditionComposite vanillaComposite(DividendSchedule cashFlow, - Exercise exercise, - FdmMesher mesher, - FdmInnerValueCalculator calculator, - Date refDate, - DayCounter dayCounter) - { - List> stoppingTimes = new List>(); - List> stepConditions = new List>(); - - if(!cashFlow.empty()) { - FdmDividendHandler dividendCondition = - new FdmDividendHandler(cashFlow, mesher, - refDate, dayCounter, 0); - - stepConditions.Add(dividendCondition); - stoppingTimes.Add(dividendCondition.dividendTimes()); - } - - Utils.QL_REQUIRE( exercise.type() == Exercise.Type.American - || exercise.type() == Exercise.Type.European - || exercise.type() == Exercise.Type.Bermudan, - () => "exercise type is not supported"); - if (exercise.type() == Exercise.Type.American) { - stepConditions.Add(new FdmAmericanStepCondition(mesher,calculator)); - } - else if (exercise.type() == Exercise.Type.Bermudan) { - FdmBermudanStepCondition bermudanCondition = - new FdmBermudanStepCondition(exercise.dates(), - refDate, dayCounter, - mesher, calculator); - stepConditions.Add(bermudanCondition); - stoppingTimes.Add(bermudanCondition.exerciseTimes()); - } - - return new FdmStepConditionComposite(stoppingTimes, stepConditions); - } - - public List stoppingTimes() { return stoppingTimes_; } - public List> conditions() { return conditions_; } - - protected List stoppingTimes_; - protected List> conditions_; - } + public class FdmStepConditionComposite : IStepCondition + { + public FdmStepConditionComposite() + { + conditions_ = new List>(); + stoppingTimes_ = new List(); + } + public FdmStepConditionComposite(List> stoppingTimes, List> conditions) + { + conditions_ = conditions; + + List allStoppingTimes = new List(); + foreach (List iter in stoppingTimes) + { + foreach (double t in iter) + allStoppingTimes.Add(t); + } + stoppingTimes_ = allStoppingTimes.Distinct().OrderBy(x => x).ToList(); + } + + public void applyTo(object o, double t) + { + foreach (IStepCondition iter in conditions_) + iter.applyTo(o, t); + } + + public static FdmStepConditionComposite joinConditions(FdmSnapshotCondition c1, + FdmStepConditionComposite c2) + { + List> stoppingTimes = new List>(); + stoppingTimes.Add(c2.stoppingTimes()); + stoppingTimes.Add(new InitializedList(1, c1.getTime())); + + List> conditions = new List>(); + conditions.Add(c2); + conditions.Add(c1); + + return new FdmStepConditionComposite(stoppingTimes, conditions); + } + + public static FdmStepConditionComposite vanillaComposite(DividendSchedule cashFlow, + Exercise exercise, + FdmMesher mesher, + FdmInnerValueCalculator calculator, + Date refDate, + DayCounter dayCounter) + { + List> stoppingTimes = new List>(); + List> stepConditions = new List>(); + + if (!cashFlow.empty()) + { + FdmDividendHandler dividendCondition = + new FdmDividendHandler(cashFlow, mesher, + refDate, dayCounter, 0); + + stepConditions.Add(dividendCondition); + stoppingTimes.Add(dividendCondition.dividendTimes()); + } + + Utils.QL_REQUIRE(exercise.type() == Exercise.Type.American + || exercise.type() == Exercise.Type.European + || exercise.type() == Exercise.Type.Bermudan, + () => "exercise type is not supported"); + if (exercise.type() == Exercise.Type.American) + { + stepConditions.Add(new FdmAmericanStepCondition(mesher, calculator)); + } + else if (exercise.type() == Exercise.Type.Bermudan) + { + FdmBermudanStepCondition bermudanCondition = + new FdmBermudanStepCondition(exercise.dates(), + refDate, dayCounter, + mesher, calculator); + stepConditions.Add(bermudanCondition); + stoppingTimes.Add(bermudanCondition.exerciseTimes()); + } + + return new FdmStepConditionComposite(stoppingTimes, stepConditions); + } + + public List stoppingTimes() { return stoppingTimes_; } + public List> conditions() { return conditions_; } + + protected List stoppingTimes_; + protected List> conditions_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/TRBDF2.cs b/src/QLNet/Methods/Finitedifferences/TRBDF2.cs index 072be41a5..3b7a97e63 100644 --- a/src/QLNet/Methods/Finitedifferences/TRBDF2.cs +++ b/src/QLNet/Methods/Finitedifferences/TRBDF2.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2011 Fabien Le Floc'h Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,129 +22,135 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! TR-BDF2 scheme for finite difference methods - /*! See for details. - - In this implementation, the passed operator must be derived - from either TimeConstantOperator or TimeDependentOperator. - Also, it must implement at least the following interface: - - // copy constructor/assignment - // (these will be provided by the compiler if none is defined) - Operator(const Operator&); - Operator& operator=(const Operator&); - - // inspectors - Size size(); - - // modifiers - void setTime(Time t); - - // operator interface - array_type applyTo(const array_type&); - array_type solveFor(const array_type&); - static Operator identity(Size size); - - // operator algebra - Operator operator*(Real, const Operator&); - Operator operator+(const Operator&, const Operator&); - Operator operator+(const Operator&, const Operator&); - \endcode - - \warning The differential operator must be linear for - this evolver to work. - - \ingroup findiff - */ - - // NOTE: There is room for performance improvement especially in - // the array manipulation - public class Trbdf2 : IMixedScheme where Operator : IOperator - { - protected Operator L_, I_, implicitPart_, explicitBDF2PartFull_, explicitTrapezoidalPart_, explicitBDF2PartMid_; - protected double dt_, alpha_; - protected Vector aInit_; - protected List> bcs_; - - // constructors - public Trbdf2() { } // required for generics - public Trbdf2(Operator L, List> bcs) - { - L_ = (Operator)L.Clone(); - I_ = (Operator)L.identity(L.size()); - dt_ = 0.0; - bcs_ = bcs; - alpha_ = 2.0 - Math.Sqrt(2.0); - } - - public void step(ref object a, double t) - { - int i; - Vector aInit = new Vector((a as Vector).size()); - for (i=0; i< (a as Vector).size();i++) { - aInit[i] = (a as Vector)[i]; - } - aInit_ = aInit; - for (i=0; i for details. + + In this implementation, the passed operator must be derived + from either TimeConstantOperator or TimeDependentOperator. + Also, it must implement at least the following interface: + + // copy constructor/assignment + // (these will be provided by the compiler if none is defined) + Operator(const Operator&); + Operator& operator=(const Operator&); + + // inspectors + Size size(); + + // modifiers + void setTime(Time t); + + // operator interface + array_type applyTo(const array_type&); + array_type solveFor(const array_type&); + static Operator identity(Size size); + + // operator algebra + Operator operator*(Real, const Operator&); + Operator operator+(const Operator&, const Operator&); + Operator operator+(const Operator&, const Operator&); + \endcode + + \warning The differential operator must be linear for + this evolver to work. + + \ingroup findiff + */ + + // NOTE: There is room for performance improvement especially in + // the array manipulation + public class Trbdf2 : IMixedScheme where Operator : IOperator + { + protected Operator L_, I_, implicitPart_, explicitBDF2PartFull_, explicitTrapezoidalPart_, explicitBDF2PartMid_; + protected double dt_, alpha_; + protected Vector aInit_; + protected List> bcs_; + + // constructors + public Trbdf2() { } // required for generics + public Trbdf2(Operator L, List> bcs) + { + L_ = (Operator)L.Clone(); + I_ = (Operator)L.identity(L.size()); + dt_ = 0.0; + bcs_ = bcs; + alpha_ = 2.0 - Math.Sqrt(2.0); + } + + public void step(ref object a, double t) + { + int i; + Vector aInit = new Vector((a as Vector).size()); + for (i = 0; i < (a as Vector).size(); i++) + { + aInit[i] = (a as Vector)[i]; + } + aInit_ = aInit; + for (i = 0; i < bcs_.Count; i++) + bcs_[i].setTime(t); + //trapezoidal explicit part + if (L_.isTimeDependent()) + { + L_.setTime(t); + explicitTrapezoidalPart_ = (Operator)I_.subtract(I_, L_.multiply(- 0.5 * alpha_ * dt_, L_)); + } + for (i = 0; i < bcs_.Count; i++) + bcs_[i].applyBeforeApplying(explicitTrapezoidalPart_); + a = explicitTrapezoidalPart_.applyTo((a as Vector)); + for (i = 0; i < bcs_.Count; i++) + bcs_[i].applyAfterApplying((a as Vector)); + + // trapezoidal implicit part + if (L_.isTimeDependent()) + { + L_.setTime(t - dt_); + implicitPart_ = (Operator)I_.add(I_, L_.multiply(0.5 * alpha_ * dt_, L_)); + } + for (i = 0; i < bcs_.Count; i++) + bcs_[i].applyBeforeSolving(implicitPart_, (a as Vector)); + a = implicitPart_.solveFor((a as Vector)); + for (i = 0; i < bcs_.Count; i++) + bcs_[i].applyAfterSolving((a as Vector)); + + + // BDF2 explicit part + if (L_.isTimeDependent()) + { + L_.setTime(t); + } + for (i = 0; i < bcs_.Count; i++) + { + bcs_[i].applyBeforeApplying(explicitBDF2PartFull_); + } + Vector b0 = explicitBDF2PartFull_.applyTo(aInit_); + for (i = 0; i < bcs_.Count; i++) + bcs_[i].applyAfterApplying(b0); + + for (i = 0; i < bcs_.Count; i++) + { + bcs_[i].applyBeforeApplying(explicitBDF2PartMid_); + } + Vector b1 = explicitBDF2PartMid_.applyTo((a as Vector)); + for (i = 0; i < bcs_.Count; i++) + bcs_[i].applyAfterApplying(b1); + a = b0 + b1; + + // reuse implicit part - works only for alpha=2-sqrt(2) + for (i = 0; i < bcs_.Count; i++) + bcs_[i].applyBeforeSolving(implicitPart_, (a as Vector)); + a = implicitPart_.solveFor((a as Vector)); + for (i = 0; i < bcs_.Count; i++) + bcs_[i].applyAfterSolving((a as Vector)); + } + + public void setStep(double dt) + { + dt_ = dt; + + implicitPart_ = (Operator)L_.add(I_, L_.multiply(0.5 * alpha_ * dt_, L_)); + explicitTrapezoidalPart_ = (Operator)L_.subtract(I_, L_.multiply(0.5 * alpha_ * dt_, L_)); + explicitBDF2PartFull_ = (Operator)I_.multiply(-(1.0 - alpha_) * (1.0 - alpha_) / (alpha_ * (2.0 - alpha_)), I_); + explicitBDF2PartMid_ = (Operator)I_.multiply(1.0 / (alpha_ * (2.0 - alpha_)), I_); + } + } } diff --git a/src/QLNet/Methods/Finitedifferences/TridiagonalOperator.cs b/src/QLNet/Methods/Finitedifferences/TridiagonalOperator.cs index 8c4c885ee..11efefeb7 100644 --- a/src/QLNet/Methods/Finitedifferences/TridiagonalOperator.cs +++ b/src/QLNet/Methods/Finitedifferences/TridiagonalOperator.cs @@ -1,239 +1,268 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Andrea Maggiulli - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - public interface IOperator : ICloneable { - int size(); - IOperator identity(int size); - Vector applyTo(Vector v); - Vector solveFor(Vector rhs); - - IOperator multiply(double a, IOperator D); - IOperator add(IOperator A, IOperator B); - IOperator subtract(IOperator A, IOperator B); - - bool isTimeDependent(); - void setTime(double t); - } - - //! Base implementation for tridiagonal operator - /*! \warning to use real time-dependant algebra, you must overload - the corresponding operators in the inheriting - time-dependent class. - - \ingroup findiff - */ - public class TridiagonalOperator : IOperator { - protected TimeSetter timeSetter_; - - protected Vector diagonal_, lowerDiagonal_, upperDiagonal_; - public Vector lowerDiagonal() { return lowerDiagonal_; } - public Vector diagonal() { return diagonal_; } - public Vector upperDiagonal() { return upperDiagonal_; } - - public int size() { return diagonal_.Count; } - - public TridiagonalOperator() : this(0) { } - public TridiagonalOperator(int size) { - if (size >= 2) { - diagonal_ = new Vector(size); - lowerDiagonal_ = new Vector(size - 1); - upperDiagonal_ = new Vector(size - 1); - } else if (size == 0) { - diagonal_ = new Vector(0); - lowerDiagonal_ = new Vector(0); - upperDiagonal_ = new Vector(0); - } else { - throw new ArgumentException("invalid size (" + size + ") for tridiagonal operator " + - "(must be null or >= 2)"); - } - } - - public TridiagonalOperator(Vector low, Vector mid, Vector high) { - diagonal_ = mid.Clone(); - lowerDiagonal_ = low.Clone(); - upperDiagonal_ = high.Clone(); - - Utils.QL_REQUIRE(low.Count == mid.Count - 1,()=> "wrong size for lower diagonal vector"); - Utils.QL_REQUIRE(high.Count == mid.Count - 1,()=> "wrong size for upper diagonal vector"); - } - - public object Clone() { return this.MemberwiseClone(); } - - public IOperator multiply(double a, IOperator o) { - TridiagonalOperator D = o as TridiagonalOperator; - Vector low = D.lowerDiagonal_*a, - mid = D.diagonal_*a, - high = D.upperDiagonal_*a; - TridiagonalOperator result = new TridiagonalOperator(low,mid,high); - return result; - } - - public IOperator add(IOperator A, IOperator B) { - TridiagonalOperator D1 = A as TridiagonalOperator; - TridiagonalOperator D2 = B as TridiagonalOperator; - - Vector low = D1.lowerDiagonal_+D2.lowerDiagonal_, - mid = D1.diagonal_+D2.diagonal_, - high = D1.upperDiagonal_+D2.upperDiagonal_; - TridiagonalOperator result = new TridiagonalOperator(low,mid,high); - return result; - } - - public IOperator subtract(IOperator A, IOperator B) { - TridiagonalOperator D1 = A as TridiagonalOperator; - TridiagonalOperator D2 = B as TridiagonalOperator; - - Vector low = D1.lowerDiagonal_-D2.lowerDiagonal_, - mid = D1.diagonal_-D2.diagonal_, - high = D1.upperDiagonal_-D2.upperDiagonal_; - TridiagonalOperator result = new TridiagonalOperator(low,mid,high); - return result; - } - - - //! apply operator to a given array - public Vector applyTo(Vector v) { - Utils.QL_REQUIRE(v.Count == size(),()=> "vector of the wrong size (" + v.Count + "instead of " + size() + ")"); - - Vector result = new Vector(size()); - - // transform(InputIterator1 start1, InputIterator1 finish1, InputIterator2 start2, OutputIterator result, - // BinaryOperation binary_op) - result = Vector.DirectMultiply(diagonal_, v); - - // matricial product - result[0] += upperDiagonal_[0] * v[1]; - for (int j = 1; j <= size() - 2; j++) - result[j] += lowerDiagonal_[j - 1] * v[j - 1] + upperDiagonal_[j] * v[j + 1]; - result[size() - 1] += lowerDiagonal_[size() - 2] * v[size() - 2]; - - return result; - } - - //! solve linear system for a given right-hand side - public Vector solveFor(Vector rhs) { - Utils.QL_REQUIRE(rhs.Count == size(),()=> "rhs has the wrong size"); - - Vector result = new Vector(size()), tmp = new Vector(size()); - - double bet = diagonal_[0]; - Utils.QL_REQUIRE(bet.IsNotEqual(0.0),()=> "division by zero"); - result[0] = rhs[0] / bet; - - for (int j = 1; j < size(); j++) { - tmp[j] = upperDiagonal_[j - 1] / bet; - bet = diagonal_[j] - lowerDiagonal_[j - 1] * tmp[j]; - Utils.QL_REQUIRE(bet.IsNotEqual(0.0),()=> "division by zero"); - result[j] = (rhs[j] - lowerDiagonal_[j - 1] * result[j - 1]) / bet; +namespace QLNet +{ + public interface IOperator : ICloneable + { + int size(); + IOperator identity(int size); + Vector applyTo(Vector v); + Vector solveFor(Vector rhs); + + IOperator multiply(double a, IOperator D); + IOperator add + (IOperator A, IOperator B); + IOperator subtract(IOperator A, IOperator B); + + bool isTimeDependent(); + void setTime(double t); + } + + //! Base implementation for tridiagonal operator + /*! \warning to use real time-dependant algebra, you must overload + the corresponding operators in the inheriting + time-dependent class. + + \ingroup findiff + */ + public class TridiagonalOperator : IOperator + { + protected TimeSetter timeSetter_; + + protected Vector diagonal_, lowerDiagonal_, upperDiagonal_; + public Vector lowerDiagonal() { return lowerDiagonal_; } + public Vector diagonal() { return diagonal_; } + public Vector upperDiagonal() { return upperDiagonal_; } + + public int size() { return diagonal_.Count; } + + public TridiagonalOperator() : this(0) { } + public TridiagonalOperator(int size) + { + if (size >= 2) + { + diagonal_ = new Vector(size); + lowerDiagonal_ = new Vector(size - 1); + upperDiagonal_ = new Vector(size - 1); + } + else if (size == 0) + { + diagonal_ = new Vector(0); + lowerDiagonal_ = new Vector(0); + upperDiagonal_ = new Vector(0); + } + else + { + throw new ArgumentException("invalid size (" + size + ") for tridiagonal operator " + + "(must be null or >= 2)"); + } + } + + public TridiagonalOperator(Vector low, Vector mid, Vector high) + { + diagonal_ = mid.Clone(); + lowerDiagonal_ = low.Clone(); + upperDiagonal_ = high.Clone(); + + Utils.QL_REQUIRE(low.Count == mid.Count - 1, () => "wrong size for lower diagonal vector"); + Utils.QL_REQUIRE(high.Count == mid.Count - 1, () => "wrong size for upper diagonal vector"); + } + + public object Clone() { return this.MemberwiseClone(); } + + public IOperator multiply(double a, IOperator o) + { + TridiagonalOperator D = o as TridiagonalOperator; + Vector low = D.lowerDiagonal_ * a, + mid = D.diagonal_ * a, + high = D.upperDiagonal_ * a; + TridiagonalOperator result = new TridiagonalOperator(low, mid, high); + return result; + } + + public IOperator add + (IOperator A, IOperator B) + { + TridiagonalOperator D1 = A as TridiagonalOperator; + TridiagonalOperator D2 = B as TridiagonalOperator; + + Vector low = D1.lowerDiagonal_ + D2.lowerDiagonal_, + mid = D1.diagonal_ + D2.diagonal_, + high = D1.upperDiagonal_ + D2.upperDiagonal_; + TridiagonalOperator result = new TridiagonalOperator(low, mid, high); + return result; + } + + public IOperator subtract(IOperator A, IOperator B) + { + TridiagonalOperator D1 = A as TridiagonalOperator; + TridiagonalOperator D2 = B as TridiagonalOperator; + + Vector low = D1.lowerDiagonal_ - D2.lowerDiagonal_, + mid = D1.diagonal_ - D2.diagonal_, + high = D1.upperDiagonal_ - D2.upperDiagonal_; + TridiagonalOperator result = new TridiagonalOperator(low, mid, high); + return result; + } + + + //! apply operator to a given array + public Vector applyTo(Vector v) + { + Utils.QL_REQUIRE(v.Count == size(), () => "vector of the wrong size (" + v.Count + "instead of " + size() + ")"); + + Vector result = new Vector(size()); + + // transform(InputIterator1 start1, InputIterator1 finish1, InputIterator2 start2, OutputIterator result, + // BinaryOperation binary_op) + result = Vector.DirectMultiply(diagonal_, v); + + // matricial product + result[0] += upperDiagonal_[0] * v[1]; + for (int j = 1; j <= size() - 2; j++) + result[j] += lowerDiagonal_[j - 1] * v[j - 1] + upperDiagonal_[j] * v[j + 1]; + result[size() - 1] += lowerDiagonal_[size() - 2] * v[size() - 2]; + + return result; + } + + //! solve linear system for a given right-hand side + public Vector solveFor(Vector rhs) + { + Utils.QL_REQUIRE(rhs.Count == size(), () => "rhs has the wrong size"); + + Vector result = new Vector(size()), tmp = new Vector(size()); + + double bet = diagonal_[0]; + Utils.QL_REQUIRE(bet.IsNotEqual(0.0), () => "division by zero"); + result[0] = rhs[0] / bet; + + for (int j = 1; j < size(); j++) + { + tmp[j] = upperDiagonal_[j - 1] / bet; + bet = diagonal_[j] - lowerDiagonal_[j - 1] * tmp[j]; + Utils.QL_REQUIRE(bet.IsNotEqual(0.0), () => "division by zero"); + result[j] = (rhs[j] - lowerDiagonal_[j - 1] * result[j - 1]) / bet; + } + // cannot be j>=0 with Size j + for (int j = size() - 2; j > 0; --j) + result[j] -= tmp[j + 1] * result[j + 1]; + result[0] -= tmp[1] * result[1]; + return result; + } + + //! solve linear system with SOR approach + public Vector SOR(Vector rhs, double tol) + { + Utils.QL_REQUIRE(rhs.Count == size(), () => "rhs has the wrong size"); + + // initial guess + Vector result = rhs.Clone(); + + // solve tridiagonal system with SOR technique + double omega = 1.5; + double err = 2.0 * tol; + double temp; + int i; + for (int sorIteration = 0; err > tol; sorIteration++) + { + Utils.QL_REQUIRE(sorIteration < 100000, () => + "tolerance (" + tol + ") not reached in " + sorIteration + " iterations. " + "The error still is " + err); + + temp = omega * (rhs[0] - + upperDiagonal_[0] * result[1] - + diagonal_[0] * result[0]) / diagonal_[0]; + err = temp* temp; + result[0] += temp; + + for (i = 1; i < size() - 1; i++) + { + temp = omega * (rhs[i] - + upperDiagonal_[i] * result[i + 1] - + diagonal_[i] * result[i] - + lowerDiagonal_[i - 1] * result[i - 1]) / diagonal_[i]; + err += temp* temp; + result[i] += temp; } - // cannot be j>=0 with Size j - for (int j = size() - 2; j > 0; --j) - result[j] -= tmp[j + 1] * result[j + 1]; - result[0] -= tmp[1] * result[1]; - return result; - } - - //! solve linear system with SOR approach - public Vector SOR(Vector rhs, double tol) { - Utils.QL_REQUIRE(rhs.Count == size(),()=> "rhs has the wrong size"); - - // initial guess - Vector result = rhs.Clone(); - - // solve tridiagonal system with SOR technique - double omega = 1.5; - double err = 2.0 * tol; - double temp; - int i; - for (int sorIteration = 0; err > tol; sorIteration++) { - Utils.QL_REQUIRE(sorIteration < 100000,()=> - "tolerance (" + tol + ") not reached in " + sorIteration + " iterations. " + "The error still is " + err); - - temp = omega * (rhs[0] - - upperDiagonal_[0] * result[1] - - diagonal_[0] * result[0]) / diagonal_[0]; - err = temp * temp; - result[0] += temp; - - for (i = 1; i < size() - 1; i++) { - temp = omega * (rhs[i] - - upperDiagonal_[i] * result[i + 1] - - diagonal_[i] * result[i] - - lowerDiagonal_[i - 1] * result[i - 1]) / diagonal_[i]; - err += temp * temp; - result[i] += temp; - } - - temp = omega * (rhs[i] - - diagonal_[i] * result[i] - - lowerDiagonal_[i - 1] * result[i - 1]) / diagonal_[i]; - err += temp * temp; - result[i] += temp; - } - return result; - } - - //! identity instance - public IOperator identity(int size) { - TridiagonalOperator I = new TridiagonalOperator(new Vector(size - 1, 0.0), // lower diagonal - new Vector(size, 1.0), // diagonal - new Vector(size - 1, 0.0)); // upper diagonal - return I; - } - - public void setFirstRow(double valB, double valC) { - diagonal_[0] = valB; - upperDiagonal_[0] = valC; - } - public void setMidRow(int i, double valA, double valB, double valC) { - Utils.QL_REQUIRE(i >= 1 && i <= size() - 2,()=> "out of range in TridiagonalSystem::setMidRow"); + + temp = omega * (rhs[i] - + diagonal_[i] * result[i] - + lowerDiagonal_[i - 1] * result[i - 1]) / diagonal_[i]; + err += temp* temp; + result[i] += temp; + } + return result; + } + + //! identity instance + public IOperator identity(int size) + { + TridiagonalOperator I = new TridiagonalOperator(new Vector(size - 1, 0.0), // lower diagonal + new Vector(size, 1.0), // diagonal + new Vector(size - 1, 0.0)); // upper diagonal + return I; + } + + public void setFirstRow(double valB, double valC) + { + diagonal_[0] = valB; + upperDiagonal_[0] = valC; + } + public void setMidRow(int i, double valA, double valB, double valC) + { + Utils.QL_REQUIRE(i >= 1 && i <= size() - 2, () => "out of range in TridiagonalSystem::setMidRow"); + lowerDiagonal_[i - 1] = valA; + diagonal_[i] = valB; + upperDiagonal_[i] = valC; + } + + public void setMidRows(double valA, double valB, double valC) + { + for (int i = 1; i <= size() - 2; i++) + { lowerDiagonal_[i - 1] = valA; diagonal_[i] = valB; upperDiagonal_[i] = valC; - } - - public void setMidRows(double valA, double valB, double valC) { - for (int i = 1; i <= size() - 2; i++) { - lowerDiagonal_[i - 1] = valA; - diagonal_[i] = valB; - upperDiagonal_[i] = valC; - } - } - - public void setLastRow(double valA, double valB) { - lowerDiagonal_[size() - 2] = valA; - diagonal_[size() - 1] = valB; - } - - public bool isTimeDependent() { return timeSetter_ != null; } - public void setTime(double t) { - if (timeSetter_ != null) - timeSetter_.setTime(t, this); - } - - //! encapsulation of time-setting logic - public abstract class TimeSetter { - public abstract void setTime(double t, IOperator L); - } - } + } + } + + public void setLastRow(double valA, double valB) + { + lowerDiagonal_[size() - 2] = valA; + diagonal_[size() - 1] = valB; + } + + public bool isTimeDependent() { return timeSetter_ != null; } + public void setTime(double t) + { + if (timeSetter_ != null) + timeSetter_.setTime(t, this); + } + + //! encapsulation of time-setting logic + public abstract class TimeSetter + { + public abstract void setTime(double t, IOperator L); + } + } } diff --git a/src/QLNet/Methods/Finitedifferences/Utilities/FdmAffineModelSwapInnerValue.cs b/src/QLNet/Methods/Finitedifferences/Utilities/FdmAffineModelSwapInnerValue.cs index 15d1c5836..246303ef5 100644 --- a/src/QLNet/Methods/Finitedifferences/Utilities/FdmAffineModelSwapInnerValue.cs +++ b/src/QLNet/Methods/Finitedifferences/Utilities/FdmAffineModelSwapInnerValue.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,111 +22,114 @@ under the terms of the QLNet license. You should have received a using System.Linq; namespace QLNet -{ - public class FdmAffineModelSwapInnerValue : FdmInnerValueCalculator where ModelType : ITermStructureConsistentModel, IAffineModel - { - public FdmAffineModelSwapInnerValue( - ModelType disModel, - ModelType fwdModel, - VanillaSwap swap, - Dictionary exerciseDates, - FdmMesher mesher, - int direction) - { - disModel_ = disModel; - fwdModel_ = fwdModel; - mesher_ = mesher; - direction_ = direction; - swap_ = new VanillaSwap(swap.swapType, - swap.nominal, - swap.fixedSchedule(), - swap.fixedRate, - swap.fixedDayCount(), - swap.floatingSchedule(), - swap.iborIndex().clone(fwdTs_), - swap.spread, - swap.floatingDayCount(), - null); - exerciseDates_ = exerciseDates; - } - - public override double innerValue(FdmLinearOpIterator iter, double t) - { - Date iterExerciseDate = exerciseDates_.ContainsKey(t) ? exerciseDates_[t] : exerciseDates_.Last().Value; - - Vector disRate = getState(disModel_, t, iter); - Vector fwdRate = getState(fwdModel_, t, iter); - - if (disTs_.empty() || iterExerciseDate != disTs_.currentLink().referenceDate()) - { - Handle discount - = disModel_.termStructure(); +{ + public class FdmAffineModelSwapInnerValue : FdmInnerValueCalculator where ModelType : ITermStructureConsistentModel, IAffineModel + { + public FdmAffineModelSwapInnerValue( + ModelType disModel, + ModelType fwdModel, + VanillaSwap swap, + Dictionary exerciseDates, + FdmMesher mesher, + int direction) + { + disModel_ = disModel; + fwdModel_ = fwdModel; + mesher_ = mesher; + direction_ = direction; + swap_ = new VanillaSwap(swap.swapType, + swap.nominal, + swap.fixedSchedule(), + swap.fixedRate, + swap.fixedDayCount(), + swap.floatingSchedule(), + swap.iborIndex().clone(fwdTs_), + swap.spread, + swap.floatingDayCount(), + null); + exerciseDates_ = exerciseDates; + } - disTs_.linkTo(new FdmAffineModelTermStructure(disRate, - discount.currentLink().calendar(), discount.currentLink().dayCounter(), - iterExerciseDate, discount.currentLink().referenceDate(), - disModel_)); + public override double innerValue(FdmLinearOpIterator iter, double t) + { + Date iterExerciseDate = exerciseDates_.ContainsKey(t) ? exerciseDates_[t] : exerciseDates_.Last().Value; - Handle fwd = fwdModel_.termStructure(); + Vector disRate = getState(disModel_, t, iter); + Vector fwdRate = getState(fwdModel_, t, iter); - fwdTs_.linkTo(new FdmAffineModelTermStructure(fwdRate, - fwd.currentLink().calendar(), fwd.currentLink().dayCounter(), - iterExerciseDate, fwd.currentLink().referenceDate(), - fwdModel_)); + if (disTs_.empty() || iterExerciseDate != disTs_.currentLink().referenceDate()) + { + Handle discount + = disModel_.termStructure(); - } - else { - (disTs_.currentLink() as FdmAffineModelTermStructure).setVariable(disRate); - (fwdTs_.currentLink() as FdmAffineModelTermStructure).setVariable(fwdRate); - } + disTs_.linkTo(new FdmAffineModelTermStructure(disRate, + discount.currentLink().calendar(), discount.currentLink().dayCounter(), + iterExerciseDate, discount.currentLink().referenceDate(), + disModel_)); + + Handle fwd = fwdModel_.termStructure(); + + fwdTs_.linkTo(new FdmAffineModelTermStructure(fwdRate, + fwd.currentLink().calendar(), fwd.currentLink().dayCounter(), + iterExerciseDate, fwd.currentLink().referenceDate(), + fwdModel_)); - double npv = 0.0; - for (int j = 0; j < 2; j++) { - for (int i =0; i < swap_.leg(j).Count; ++i) { - npv += (swap_.leg(j)[i] as Coupon).accrualStartDate() >= iterExerciseDate - ? swap_.leg(j)[i].amount() * disTs_.currentLink().discount(swap_.leg(j)[i].date()) - : 0.0; - } - if (j == 0) - npv *= -1.0; + } + else + { + (disTs_.currentLink() as FdmAffineModelTermStructure).setVariable(disRate); + (fwdTs_.currentLink() as FdmAffineModelTermStructure).setVariable(fwdRate); + } + + double npv = 0.0; + for (int j = 0; j < 2; j++) + { + for (int i = 0; i < swap_.leg(j).Count; ++i) + { + npv += (swap_.leg(j)[i] as Coupon).accrualStartDate() >= iterExerciseDate + ? swap_.leg(j)[i].amount() * disTs_.currentLink().discount(swap_.leg(j)[i].date()) + : 0.0; } - if (swap_.swapType == VanillaSwap.Type.Receiver) - npv *= -1.0; - - return Math.Max(0.0, npv); - } - public override double avgInnerValue(FdmLinearOpIterator iter, double t) - { - return innerValue(iter, t); - } - - public Vector getState(ModelType model, double t, FdmLinearOpIterator iter) - { - if (model.GetType().Equals(typeof(HullWhite))) - { - Vector retVal = new Vector(1, (model as HullWhite).dynamics().shortRate(t, - mesher_.location(iter, direction_))); - return retVal; - } - else if (model.GetType().Equals(typeof(G2))) - { - Vector retVal = new Vector(2); - retVal[0] = mesher_.location(iter, direction_); - retVal[1] = mesher_.location(iter, direction_ + 1); - - return retVal; - } - else - return new Vector(); - } - - protected RelinkableHandle disTs_ = new RelinkableHandle(), fwdTs_ = new RelinkableHandle(); - protected ModelType disModel_, fwdModel_; - - protected IborIndex index_; - protected VanillaSwap swap_; - protected Dictionary exerciseDates_; - protected FdmMesher mesher_; - protected int direction_; - } + if (j == 0) + npv *= -1.0; + } + if (swap_.swapType == VanillaSwap.Type.Receiver) + npv *= -1.0; + + return Math.Max(0.0, npv); + } + public override double avgInnerValue(FdmLinearOpIterator iter, double t) + { + return innerValue(iter, t); + } + + public Vector getState(ModelType model, double t, FdmLinearOpIterator iter) + { + if (model.GetType().Equals(typeof(HullWhite))) + { + Vector retVal = new Vector(1, (model as HullWhite).dynamics().shortRate(t, + mesher_.location(iter, direction_))); + return retVal; + } + else if (model.GetType().Equals(typeof(G2))) + { + Vector retVal = new Vector(2); + retVal[0] = mesher_.location(iter, direction_); + retVal[1] = mesher_.location(iter, direction_ + 1); + + return retVal; + } + else + return new Vector(); + } + + protected RelinkableHandle disTs_ = new RelinkableHandle(), fwdTs_ = new RelinkableHandle(); + protected ModelType disModel_, fwdModel_; + + protected IborIndex index_; + protected VanillaSwap swap_; + protected Dictionary exerciseDates_; + protected FdmMesher mesher_; + protected int direction_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/Utilities/FdmAffineModelTermStructure.cs b/src/QLNet/Methods/Finitedifferences/Utilities/FdmAffineModelTermStructure.cs index 0b2f63f23..dbb9cbfb1 100644 --- a/src/QLNet/Methods/Finitedifferences/Utilities/FdmAffineModelTermStructure.cs +++ b/src/QLNet/Methods/Finitedifferences/Utilities/FdmAffineModelTermStructure.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,38 +22,38 @@ under the terms of the QLNet license. You should have received a using System.Linq; namespace QLNet -{ - public class FdmAffineModelTermStructure : YieldTermStructure - { - public FdmAffineModelTermStructure( - Vector r, - Calendar cal, - DayCounter dayCounter, - Date referenceDate, - Date modelReferenceDate, - IAffineModel model) - : base(referenceDate, cal, dayCounter) - { - r_ = r; - t_ = dayCounter.yearFraction(modelReferenceDate, referenceDate); - model_ = model; - model_.registerWith(update); - } - - public override Date maxDate() { return Date.maxDate(); } - public void setVariable(Vector r) - { - r_ = r; - notifyObservers(); - } - - protected override double discountImpl(double d) - { - return model_.discountBond(t_, d + t_, r_); - } - - protected Vector r_; - protected double t_; - protected IAffineModel model_; - } +{ + public class FdmAffineModelTermStructure : YieldTermStructure + { + public FdmAffineModelTermStructure( + Vector r, + Calendar cal, + DayCounter dayCounter, + Date referenceDate, + Date modelReferenceDate, + IAffineModel model) + : base(referenceDate, cal, dayCounter) + { + r_ = r; + t_ = dayCounter.yearFraction(modelReferenceDate, referenceDate); + model_ = model; + model_.registerWith(update); + } + + public override Date maxDate() { return Date.maxDate(); } + public void setVariable(Vector r) + { + r_ = r; + notifyObservers(); + } + + protected override double discountImpl(double d) + { + return model_.discountBond(t_, d + t_, r_); + } + + protected Vector r_; + protected double t_; + protected IAffineModel model_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/Utilities/FdmBoundaryConditionSet.cs b/src/QLNet/Methods/Finitedifferences/Utilities/FdmBoundaryConditionSet.cs index 4e7c27e9c..9c1c8f008 100644 --- a/src/QLNet/Methods/Finitedifferences/Utilities/FdmBoundaryConditionSet.cs +++ b/src/QLNet/Methods/Finitedifferences/Utilities/FdmBoundaryConditionSet.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,8 +22,8 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class FdmBoundaryConditionSet : List> - { + public class FdmBoundaryConditionSet : List> + { - } + } } diff --git a/src/QLNet/Methods/Finitedifferences/Utilities/FdmDirichletBoundary.cs b/src/QLNet/Methods/Finitedifferences/Utilities/FdmDirichletBoundary.cs index 4bb5e1f74..fd87a4192 100644 --- a/src/QLNet/Methods/Finitedifferences/Utilities/FdmDirichletBoundary.cs +++ b/src/QLNet/Methods/Finitedifferences/Utilities/FdmDirichletBoundary.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -27,12 +27,12 @@ namespace QLNet public class FdmDirichletBoundary : BoundaryCondition { public FdmDirichletBoundary(FdmMesher mesher, - double valueOnBoundary, int direction, Side side) + double valueOnBoundary, int direction, Side side) { side_ = side; valueOnBoundary_ = valueOnBoundary; indices_ = new FdmIndicesOnBoundary(mesher.layout(), - direction, side).getIndices(); + direction, side).getIndices(); if (side_ == Side.Lower) { xExtreme_ = mesher.locations(direction)[0]; @@ -40,7 +40,7 @@ public FdmDirichletBoundary(FdmMesher mesher, else if (side_ == Side.Upper) { xExtreme_ = mesher - .locations(direction)[mesher.layout().dim()[direction] - 1]; + .locations(direction)[mesher.layout().dim()[direction] - 1]; } else { @@ -78,8 +78,8 @@ public double applyAfterApplying(double x, double value) { return ((side_ == Side.Lower && x < xExtreme_) || (side_ == Side.Upper && x > xExtreme_)) - ? valueOnBoundary_ - : value; + ? valueOnBoundary_ + : value; } protected Side side_; diff --git a/src/QLNet/Methods/Finitedifferences/Utilities/FdmDividendHandler.cs b/src/QLNet/Methods/Finitedifferences/Utilities/FdmDividendHandler.cs index e5d3d1e87..254e49df2 100644 --- a/src/QLNet/Methods/Finitedifferences/Utilities/FdmDividendHandler.cs +++ b/src/QLNet/Methods/Finitedifferences/Utilities/FdmDividendHandler.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -28,10 +28,10 @@ namespace QLNet public class FdmDividendHandler : IStepCondition { public FdmDividendHandler(DividendSchedule schedule, - FdmMesher mesher, - Date referenceDate, - DayCounter dayCounter, - int equityDirection) + FdmMesher mesher, + Date referenceDate, + DayCounter dayCounter, + int equityDirection) { x_ = new Vector(mesher.layout().dim()[equityDirection]); mesher_ = mesher; @@ -98,7 +98,7 @@ public void applyTo(object o, double t) { int index = j * ySpacing + k * xSpacing; a[index] = interp.value( - Math.Max(x_[0], x_[k] - dividend), true); + Math.Max(x_[0], x_[k] - dividend), true); } } } diff --git a/src/QLNet/Methods/Finitedifferences/Utilities/FdmIndicesOnBoundary.cs b/src/QLNet/Methods/Finitedifferences/Utilities/FdmIndicesOnBoundary.cs index 8667055f6..4df91c9c7 100644 --- a/src/QLNet/Methods/Finitedifferences/Utilities/FdmIndicesOnBoundary.cs +++ b/src/QLNet/Methods/Finitedifferences/Utilities/FdmIndicesOnBoundary.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -27,21 +27,21 @@ namespace QLNet public class FdmIndicesOnBoundary { public FdmIndicesOnBoundary(FdmLinearOpLayout layout, - int direction, FdmDirichletBoundary.Side side) + int direction, FdmDirichletBoundary.Side side) { List newDim = new List(layout.dim()); newDim[direction] = 1; int hyperSize = newDim.accumulate(0, newDim.Count, 1, - (a, b) => (a * b)); + (a, b) => (a * b)); indices_ = new InitializedList(hyperSize); int i = 0; FdmLinearOpIterator endIter = layout.end(); for (FdmLinearOpIterator iter = layout.begin(); - iter != endIter; - ++iter) + iter != endIter; + ++iter) { if ((side == FdmDirichletBoundary.Side.Lower && iter.coordinates()[direction] == 0) diff --git a/src/QLNet/Methods/Finitedifferences/Utilities/FdmInnerValueCalculator.cs b/src/QLNet/Methods/Finitedifferences/Utilities/FdmInnerValueCalculator.cs index c2d5199a9..6d00c844a 100644 --- a/src/QLNet/Methods/Finitedifferences/Utilities/FdmInnerValueCalculator.cs +++ b/src/QLNet/Methods/Finitedifferences/Utilities/FdmInnerValueCalculator.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,123 +23,128 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public abstract class FdmInnerValueCalculator - { - public abstract double innerValue(FdmLinearOpIterator iter, double t); - public abstract double avgInnerValue(FdmLinearOpIterator iter, double t); - } - - public class FdmLogInnerValue : FdmInnerValueCalculator - { - public FdmLogInnerValue(Payoff payoff, - FdmMesher mesher, - int direction) - { - payoff_ = payoff; - mesher_ = mesher; - direction_ = direction; - avgInnerValues_ = new List(); - } - - public override double innerValue(FdmLinearOpIterator iter, double t) - { - double s = Math.Exp(mesher_.location(iter, direction_)); - return payoff_.value(s); - } - public override double avgInnerValue(FdmLinearOpIterator iter, double t) - { - if (avgInnerValues_.empty()) + public abstract class FdmInnerValueCalculator + { + public abstract double innerValue(FdmLinearOpIterator iter, double t); + public abstract double avgInnerValue(FdmLinearOpIterator iter, double t); + } + + public class FdmLogInnerValue : FdmInnerValueCalculator + { + public FdmLogInnerValue(Payoff payoff, + FdmMesher mesher, + int direction) + { + payoff_ = payoff; + mesher_ = mesher; + direction_ = direction; + avgInnerValues_ = new List(); + } + + public override double innerValue(FdmLinearOpIterator iter, double t) + { + double s = Math.Exp(mesher_.location(iter, direction_)); + return payoff_.value(s); + } + public override double avgInnerValue(FdmLinearOpIterator iter, double t) + { + if (avgInnerValues_.empty()) + { + // calculate caching values + avgInnerValues_ = new InitializedList(mesher_.layout().dim()[direction_]); + List initialized = new InitializedList(avgInnerValues_.Count, false); + + FdmLinearOpLayout layout = mesher_.layout(); + FdmLinearOpIterator endIter = layout.end(); + for (FdmLinearOpIterator new_iter = layout.begin(); new_iter != endIter; + ++new_iter) { - // calculate caching values - avgInnerValues_ = new InitializedList(mesher_.layout().dim()[direction_]); - List initialized = new InitializedList(avgInnerValues_.Count, false); - - FdmLinearOpLayout layout = mesher_.layout(); - FdmLinearOpIterator endIter = layout.end(); - for (FdmLinearOpIterator new_iter = layout.begin(); new_iter != endIter; - ++new_iter) - { - int xn = new_iter.coordinates()[direction_]; - if (!initialized[xn]) - { - initialized[xn] = true; - avgInnerValues_[xn] = avgInnerValueCalc(new_iter, t); - } - } - } - return avgInnerValues_[iter.coordinates()[direction_]]; - } - - protected double avgInnerValueCalc(FdmLinearOpIterator iter, double t) - { - int dim = mesher_.layout().dim()[direction_]; - int coord = iter.coordinates()[direction_]; - double loc = mesher_.location(iter,direction_); - double a = loc; - double b = loc; - if (coord > 0) { - a -= mesher_.dminus(iter, direction_).Value / 2.0; - } - if (coord < dim-1) { - b += mesher_.dplus(iter, direction_).Value / 2.0; - } - Func f = x => payoff_.value(Math.Exp(x)); - double retVal; - try { - double acc - = ((f(a) != 0.0 || f(b) != 0.0) ? (f(a)+f(b))*5e-5 : 1e-4); - retVal = new SimpsonIntegral(acc, 8).value(f, a, b)/(b-a); - } - catch { - // use default value - retVal = innerValue(iter, t); + int xn = new_iter.coordinates()[direction_]; + if (!initialized[xn]) + { + initialized[xn] = true; + avgInnerValues_[xn] = avgInnerValueCalc(new_iter, t); + } } - - return retVal; - } - - protected Payoff payoff_; - protected FdmMesher mesher_; - protected int direction_; - protected List avgInnerValues_; - } - - public class FdmLogBasketInnerValue : FdmInnerValueCalculator - { - public FdmLogBasketInnerValue(BasketPayoff payoff, + } + return avgInnerValues_[iter.coordinates()[direction_]]; + } + + protected double avgInnerValueCalc(FdmLinearOpIterator iter, double t) + { + int dim = mesher_.layout().dim()[direction_]; + int coord = iter.coordinates()[direction_]; + double loc = mesher_.location(iter, direction_); + double a = loc; + double b = loc; + if (coord > 0) + { + a -= mesher_.dminus(iter, direction_).Value / 2.0; + } + if (coord < dim - 1) + { + b += mesher_.dplus(iter, direction_).Value / 2.0; + } + Func f = x => payoff_.value(Math.Exp(x)); + double retVal; + try + { + double acc + = ((f(a) != 0.0 || f(b) != 0.0) ? (f(a) + f(b)) * 5e-5 : 1e-4); + retVal = new SimpsonIntegral(acc, 8).value(f, a, b) / (b - a); + } + catch + { + // use default value + retVal = innerValue(iter, t); + } + + return retVal; + } + + protected Payoff payoff_; + protected FdmMesher mesher_; + protected int direction_; + protected List avgInnerValues_; + } + + public class FdmLogBasketInnerValue : FdmInnerValueCalculator + { + public FdmLogBasketInnerValue(BasketPayoff payoff, FdmMesher mesher) - { - payoff_ = payoff; - mesher_ = mesher; - } - - public override double innerValue(FdmLinearOpIterator iter, double t) - { - Vector x = new Vector(mesher_.layout().dim().Count); - for (int i=0; i < x.size(); ++i) { - x[i] = Math.Exp(mesher_.location(iter, i)); - } - - return payoff_.value(x); - } - public override double avgInnerValue(FdmLinearOpIterator iter, double t) - { - return innerValue(iter, t); - } - - protected BasketPayoff payoff_; - protected FdmMesher mesher_; - } - - public class FdmZeroInnerValue : FdmInnerValueCalculator - { - public override double innerValue(FdmLinearOpIterator iter, double t) - { - return 0.0; - } - public override double avgInnerValue(FdmLinearOpIterator iter, double t) - { - return 0.0; - } - } + { + payoff_ = payoff; + mesher_ = mesher; + } + + public override double innerValue(FdmLinearOpIterator iter, double t) + { + Vector x = new Vector(mesher_.layout().dim().Count); + for (int i = 0; i < x.size(); ++i) + { + x[i] = Math.Exp(mesher_.location(iter, i)); + } + + return payoff_.value(x); + } + public override double avgInnerValue(FdmLinearOpIterator iter, double t) + { + return innerValue(iter, t); + } + + protected BasketPayoff payoff_; + protected FdmMesher mesher_; + } + + public class FdmZeroInnerValue : FdmInnerValueCalculator + { + public override double innerValue(FdmLinearOpIterator iter, double t) + { + return 0.0; + } + public override double avgInnerValue(FdmLinearOpIterator iter, double t) + { + return 0.0; + } + } } diff --git a/src/QLNet/Methods/Finitedifferences/Utilities/FdmMesherIntegral.cs b/src/QLNet/Methods/Finitedifferences/Utilities/FdmMesherIntegral.cs index e06c22aa8..971d4b499 100644 --- a/src/QLNet/Methods/Finitedifferences/Utilities/FdmMesherIntegral.cs +++ b/src/QLNet/Methods/Finitedifferences/Utilities/FdmMesherIntegral.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,44 +23,46 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class FdmMesherIntegral - { - public FdmMesherIntegral( - FdmMesherComposite mesher, - Func integrator1d) - { - meshers_ = new List(mesher.getFdm1dMeshers()); - integrator1d_ = integrator1d; - } + public class FdmMesherIntegral + { + public FdmMesherIntegral( + FdmMesherComposite mesher, + Func integrator1d) + { + meshers_ = new List(mesher.getFdm1dMeshers()); + integrator1d_ = integrator1d; + } - public double integrate(Vector f) - { - Vector x = new Vector(meshers_.Last().locations()); + public double integrate(Vector f) + { + Vector x = new Vector(meshers_.Last().locations()); - if (meshers_.Count == 1) { - return integrator1d_(x, f); - } + if (meshers_.Count == 1) + { + return integrator1d_(x, f); + } - FdmMesherComposite subMesher = - new FdmMesherComposite( - new List(meshers_.GetRange(0, meshers_.Count - 1))); + FdmMesherComposite subMesher = + new FdmMesherComposite( + new List(meshers_.GetRange(0, meshers_.Count - 1))); - FdmMesherIntegral subMesherIntegral = new FdmMesherIntegral(subMesher, integrator1d_); - int subSize = subMesher.layout().size(); + FdmMesherIntegral subMesherIntegral = new FdmMesherIntegral(subMesher, integrator1d_); + int subSize = subMesher.layout().size(); - Vector g = new Vector(x.size()), fSub = new Vector(subSize); + Vector g = new Vector(x.size()), fSub = new Vector(subSize); - for (int i=0; i < x.size(); ++i) { - f.copy(i *subSize, - (i+1)*subSize, 0, fSub); + for (int i = 0; i < x.size(); ++i) + { + f.copy(i * subSize, + (i + 1)*subSize, 0, fSub); - g[i] = subMesherIntegral.integrate(fSub); - } + g[i] = subMesherIntegral.integrate(fSub); + } - return integrator1d_(x, g); - } + return integrator1d_(x, g); + } - protected List meshers_; - protected Func integrator1d_; - } + protected List meshers_; + protected Func integrator1d_; + } } diff --git a/src/QLNet/Methods/Finitedifferences/Utilities/ListUtils.cs b/src/QLNet/Methods/Finitedifferences/Utilities/ListUtils.cs index 6a177b818..8de043361 100644 --- a/src/QLNet/Methods/Finitedifferences/Utilities/ListUtils.cs +++ b/src/QLNet/Methods/Finitedifferences/Utilities/ListUtils.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,56 +24,88 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public static class GenericListUtils - { - public static T accumulate(this IList list, int first, int last, T init, Func func) - { - T result = init; - for (int i = first; i < last; i++) - { - result = func(result, list[i]); - } - - return result; - } - - public static int distance(this IList list, T first, T last) - { - int iFirst = list.IndexOf(first); - int iLast = list.IndexOf(last); - - return (Math.Abs(iLast - iFirst + 1) * (iLast < iFirst ? -1 : 1)); - } - - public static void copy(this IList input1, int first1, int last1, int first2, IList output) - { - int index = first2; - for (int i = first1; i < last1; i++) - { - output[index++] = input1[i]; - } - } - - public static double inner_product(this IList input1, int first1, int last1, int first2, IList v, double init) - { - double sum = init; - int index = first2; - for (int i = first1; i < last1; i++) - { - sum += v[index++] * input1[i]; - } - return sum; - } - - public static int inner_product(this IList input1, int first1, int last1, int first2, IList v, int init) - { - int sum = init; - int index = first2; - for (int i = first1; i < last1; i++) - { - sum += v[index++] * input1[i]; - } - return sum; - } - } + public static class GenericListUtils + { + public static T accumulate(this IList list, int first, int last, T init, Func func) + { + T result = init; + for (int i = first; i < last; i++) + { + result = func(result, list[i]); + } + + return result; + } + + public static int distance(this IList list, T first, T last) + { + int iFirst = list.IndexOf(first); + int iLast = list.IndexOf(last); + + return (Math.Abs(iLast - iFirst + 1) * (iLast < iFirst ? -1 : 1)); + } + + public static void copy(this IList input1, int first1, int last1, int first2, IList output) + { + int index = first2; + for (int i = first1; i < last1; i++) + { + output[index++] = input1[i]; + } + } + + public static double inner_product(this IList input1, int first1, int last1, int first2, IList v, double init) + { + double sum = init; + int index = first2; + for (int i = first1; i < last1; i++) + { + sum += v[index++] * input1[i]; + } + return sum; + } + + public static int inner_product(this IList input1, int first1, int last1, int first2, IList v, int init) + { + int sum = init; + int index = first2; + for (int i = first1; i < last1; i++) + { + sum += v[index++] * input1[i]; + } + return sum; + } + + static readonly Random generator = new Random(1); + + public static void Shuffle(this IList sequence) + { + // The simplest and most efficient way to return a random subet is to perform + // an in-place, partial Fisher-Yates shuffle of the sequence. While we could do + // a full shuffle, it would be wasteful in the cases where subsetSize is shorter + // than the length of the sequence. + // See: http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle + + var m = 0; // keeps track of count items shuffled + var w = sequence.Count; // upper bound of shrinking swap range + var g = w - 1; // used to compute the second swap index + + // perform in-place, partial Fisher-Yates shuffle + while (m < w) + { + var k = g - generator.Next(w); + var tmp = sequence[k]; + sequence[k] = sequence[m]; + sequence[m] = tmp; + ++m; + --w; + } + } + public static IList Clone(this IList input) where T : ICloneable, new () + { + IList c = new InitializedList(input.Count); + c.ForEach((ii, vv) => c[ii] = (T)input[ii].Clone()); + return c; + } + } } diff --git a/src/QLNet/Methods/Finitedifferences/ZeroCondition.cs b/src/QLNet/Methods/Finitedifferences/ZeroCondition.cs index 4165799e8..8ad0032df 100644 --- a/src/QLNet/Methods/Finitedifferences/ZeroCondition.cs +++ b/src/QLNet/Methods/Finitedifferences/ZeroCondition.cs @@ -2,18 +2,18 @@ Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl Copyright (C) 2003, 2004, 2005 StatPro Italia srl Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,16 +22,17 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! Zero exercise condition. - /*! Used in CEV models */ - public class ZeroCondition : IStepCondition where array_type : Vector - { - public void applyTo(object a, double t) - { - Vector o = (Vector)a; - for(int i=0; i < o.Count; i++) { - o[i] = Math.Max(o[i], 0.0); - } - } - } + //! Zero exercise condition. + /*! Used in CEV models */ + public class ZeroCondition : IStepCondition where array_type : Vector + { + public void applyTo(object a, double t) + { + Vector o = (Vector)a; + for (int i = 0; i < o.Count; i++) + { + o[i] = Math.Max(o[i], 0.0); + } + } + } } diff --git a/src/QLNet/Methods/Finitedifferences/bsmoperator.cs b/src/QLNet/Methods/Finitedifferences/bsmoperator.cs deleted file mode 100644 index 6bb21d127..000000000 --- a/src/QLNet/Methods/Finitedifferences/bsmoperator.cs +++ /dev/null @@ -1,41 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -namespace QLNet { - //! Black-Scholes-Merton differential operator - /*! \ingroup findiff */ - public class BSMOperator : TridiagonalOperator { - public BSMOperator() { } - - public BSMOperator(int size, double dx, double r, double q, double sigma) : base(size) { - double sigma2 = sigma*sigma; - double nu = r-q-sigma2/2; - double pd = -(sigma2/dx-nu)/(2*dx); - double pu = -(sigma2/dx+nu)/(2*dx); - double pm = sigma2/(dx*dx)+r; - setMidRows(pd,pm,pu); - } - - public BSMOperator(Vector grid, GeneralizedBlackScholesProcess process, double residualTime) : base(grid.size()) { - LogGrid logGrid = new LogGrid(grid); - var cc = new PdeConstantCoeff(process, residualTime, process.stateVariable().link.value()); - cc.generateOperator(residualTime, logGrid, this); - } - } -} diff --git a/src/QLNet/Methods/Finitedifferences/cranknicolson.cs b/src/QLNet/Methods/Finitedifferences/cranknicolson.cs deleted file mode 100644 index 89e23b155..000000000 --- a/src/QLNet/Methods/Finitedifferences/cranknicolson.cs +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System.Collections.Generic; - -namespace QLNet { - //! Crank-Nicolson scheme for finite difference methods - /*! In this implementation, the passed operator must be derived - from either TimeConstantOperator or TimeDependentOperator. - Also, it must implement at least the following interface: - - \warning The differential operator must be linear for - this evolver to work. - - \ingroup findiff - */ - public class CrankNicolson : MixedScheme, ISchemeFactory where Operator : IOperator { - // constructors - public CrankNicolson() { } // required for generics - public CrankNicolson(Operator L, List> bcs) - : base(L, 0.5, bcs) { } - - public IMixedScheme factory(object L, object bcs, object[] additionalFields = null) - { - return new CrankNicolson((Operator)L, (List>)bcs); - } - } -} diff --git a/src/QLNet/Methods/Finitedifferences/dzero.cs b/src/QLNet/Methods/Finitedifferences/dzero.cs deleted file mode 100644 index cb0cb3e0d..000000000 --- a/src/QLNet/Methods/Finitedifferences/dzero.cs +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -namespace QLNet { - //! \f$ D_{0} \f$ matricial representation - /*! The differential operator \f$ D_{0} \f$ discretizes the - first derivative with the second-order formula - - \ingroup findiff - - \test the correctness of the returned values is tested by - checking them against numerical calculations. - */ - public class DZero : TridiagonalOperator { - public DZero(int gridPoints, double h) - : base(gridPoints) { - setFirstRow(-1 / h, 1 / h); // linear extrapolation - setMidRows(-1 / (2 * h), 0.0, 1 / (2 * h)); - setLastRow(-1 / h, 1 / h); // linear extrapolation - } - } -} diff --git a/src/QLNet/Methods/Finitedifferences/finitedifferencemodel.cs b/src/QLNet/Methods/Finitedifferences/finitedifferencemodel.cs deleted file mode 100644 index 31cfff9c4..000000000 --- a/src/QLNet/Methods/Finitedifferences/finitedifferencemodel.cs +++ /dev/null @@ -1,110 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace QLNet { - public class FiniteDifferenceModel where Evolver : IMixedScheme, ISchemeFactory, new() { - private Evolver evolver_; - public Evolver evolver() { return evolver_; } - - private List stoppingTimes_; - - // constructors - public FiniteDifferenceModel(object L, object bcs) - : this(L, bcs, new List()) { } - public FiniteDifferenceModel(object L, object bcs, List stoppingTimes) { - evolver_ = (Evolver)FastActivator.Create().factory(L, bcs); - stoppingTimes_ = stoppingTimes; - stoppingTimes_.Sort(); - stoppingTimes_ = stoppingTimes_.Distinct().ToList(); - } - - //public FiniteDifferenceModel(Evolver evolver, List stoppingTimes = List()) - public FiniteDifferenceModel(Evolver evolver, List stoppingTimes) { - evolver_ = evolver; - - stoppingTimes_ = stoppingTimes; - stoppingTimes_.Sort(); - stoppingTimes_ = stoppingTimes_.Distinct().ToList(); - } - - /*! solves the problem between the given times, applying a condition at every step. - \warning being this a rollback, from must be a later time than to. */ - public void rollback(ref object a, double from, double to, int steps) { rollbackImpl(ref a, from, to, steps, null); } - public void rollback(ref object a, double from, double to, int steps, IStepCondition condition) { - rollbackImpl(ref a,from,to,steps, condition); - } - - private void rollbackImpl(ref object o, double from, double to, int steps, IStepCondition condition) { - - Utils.QL_REQUIRE(from >= to,()=> "trying to roll back from " + from + " to " + to); - - double dt = (from - to) / steps, t = from; - evolver_.setStep(dt); - - if (!stoppingTimes_.empty() && stoppingTimes_.Last() == from) - { - if (condition != null) - condition.applyTo(o, from); - } - for (int i=0; i= 0 ; --j) { - if (next <= stoppingTimes_[j] && stoppingTimes_[j] < now) { - // a stopping time was hit - hit = true; - - // perform a small step to stoppingTimes_[j]... - evolver_.setStep(now-stoppingTimes_[j]); - evolver_.step(ref o, now); - if (condition != null) - condition.applyTo(o,stoppingTimes_[j]); - // ...and continue the cycle - now = stoppingTimes_[j]; - } - } - // if we did hit... - if (hit) { - // ...we might have to make a small step to - // complete the big one... - if (now > next) { - evolver_.setStep(now - next); - evolver_.step(ref o,now); - if (condition != null) - condition.applyTo(o,next); - } - // ...and in any case, we have to reset the - // evolver to the default step. - evolver_.setStep(dt); - } else { - // if we didn't, the evolver is already set to the - // default step, which is ok for us. - evolver_.step(ref o,now); - if (condition != null) - condition.applyTo(o, next); - } - } - } - - } -} diff --git a/src/QLNet/Methods/Finitedifferences/mixedscheme.cs b/src/QLNet/Methods/Finitedifferences/mixedscheme.cs deleted file mode 100644 index 002d81fc5..000000000 --- a/src/QLNet/Methods/Finitedifferences/mixedscheme.cs +++ /dev/null @@ -1,93 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System.Collections.Generic; - -namespace QLNet { - public interface ISchemeFactory { - IMixedScheme factory(object L, object bcs, object[] additionalInputs = null); - } - - public interface IMixedScheme { - void step(ref object a, double t); - void setStep(double dt); - } - - //! Mixed (explicit/implicit) scheme for finite difference methods - /*! In this implementation, the passed operator must be derived - from either TimeConstantOperator or TimeDependentOperator. - - \ingroup findiff - */ - public class MixedScheme : IMixedScheme where Operator : IOperator { - protected Operator L_, I_, explicitPart_, implicitPart_; - protected double dt_; - protected double theta_; - protected List> bcs_; - - // constructors - public MixedScheme() { } // required for generics - public MixedScheme(Operator L, double theta, List> bcs) { - L_ = (Operator)L.Clone(); - I_ = (Operator)L.identity(L.size()); - dt_ = 0.0; - theta_ = theta; - bcs_ = bcs; - } - - public void step(ref object o, double t) { - Vector a = (Vector)o; - - int i; - for (i=0; i. - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - public abstract class PdeSecondOrderParabolic { - public abstract double diffusion(double t, double x); - public abstract double drift(double t, double x); - public abstract double discount(double t, double x); - public abstract PdeSecondOrderParabolic factory(GeneralizedBlackScholesProcess process); - - public void generateOperator(double t, TransformedGrid tg, TridiagonalOperator L) { - for (int i=1; i < tg.size() - 1; i++) { - double sigma = diffusion(t, tg.grid(i)); - double nu = drift(t, tg.grid(i)); - double r = discount(t, tg.grid(i)); - double sigma2 = sigma * sigma; - - double pd = -(sigma2/tg.dxm(i)-nu)/ tg.dx(i); - double pu = -(sigma2/tg.dxp(i)+nu)/ tg.dx(i); - double pm = sigma2/(tg.dxm(i) * tg.dxp(i))+r; - L.setMidRow(i, pd,pm,pu); - } - } - } - - - public class PdeConstantCoeff : PdeSecondOrderParabolic where PdeClass : PdeSecondOrderParabolic, new() { - private double diffusion_; - private double drift_; - private double discount_; - - public PdeConstantCoeff(GeneralizedBlackScholesProcess process, double t, double x) { - PdeClass pde = (PdeClass) FastActivator.Create().factory(process); - diffusion_ = pde.diffusion(t, x); - drift_ = pde.drift(t, x); - discount_ = pde.discount(t, x); - } - - public override double diffusion(double x, double y) { return diffusion_; } - public override double drift(double x, double y) { return drift_; } - public override double discount(double x, double y) { return discount_; } - public override PdeSecondOrderParabolic factory(GeneralizedBlackScholesProcess process) { - throw new NotSupportedException(); - } - } - - - public class GenericTimeSetter : TridiagonalOperator.TimeSetter where PdeClass : PdeSecondOrderParabolic, new() { - private LogGrid grid_; - private PdeClass pde_; - - public GenericTimeSetter(Vector grid, GeneralizedBlackScholesProcess process) { - grid_ = new LogGrid(grid); - pde_ = (PdeClass) FastActivator.Create().factory(process); - } - - public override void setTime(double t, IOperator L) { - pde_.generateOperator(t, grid_, (TridiagonalOperator)L); - } - } - - - public class PdeOperator : TridiagonalOperator where PdeClass : PdeSecondOrderParabolic, new() { - public PdeOperator(Vector grid, GeneralizedBlackScholesProcess process) : this(grid, process, 0) { } - public PdeOperator(Vector grid, GeneralizedBlackScholesProcess process, double residualTime) - : base(grid.size()) { - timeSetter_ = new GenericTimeSetter(grid, process); - setTime(residualTime); - } - } - -} diff --git a/src/QLNet/Methods/Finitedifferences/pdebsm.cs b/src/QLNet/Methods/Finitedifferences/pdebsm.cs deleted file mode 100644 index 3473a53b0..000000000 --- a/src/QLNet/Methods/Finitedifferences/pdebsm.cs +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - public class PdeBSM : PdeSecondOrderParabolic { - private GeneralizedBlackScholesProcess process_; - - public PdeBSM() { } // required for generics - public PdeBSM(GeneralizedBlackScholesProcess process) { - process_ = process; - } - - public override double diffusion(double t, double x) { - return process_.diffusion(t, x); - } - - public override double drift(double t, double x) { - return process_.drift(t, x); - } - - public override double discount(double t, double x) { - if (Math.Abs(t) < 1e-8) t = 0; - return process_.riskFreeRate().link.forwardRate(t,t, Compounding.Continuous, Frequency.NoFrequency,true).rate(); - } - - public override PdeSecondOrderParabolic factory(GeneralizedBlackScholesProcess process) { return new PdeBSM(process); } - } -} diff --git a/src/QLNet/Methods/lattices/binominaltree.cs b/src/QLNet/Methods/lattices/BinominalTree.cs similarity index 99% rename from src/QLNet/Methods/lattices/binominaltree.cs rename to src/QLNet/Methods/lattices/BinominalTree.cs index a54d57501..45ef5a212 100644 --- a/src/QLNet/Methods/lattices/binominaltree.cs +++ b/src/QLNet/Methods/lattices/BinominalTree.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -44,7 +44,7 @@ public abstract class BinomialTree : Tree, ITree public enum Branches { branches = 2 - }; + } protected double x0_, driftPerStep_; protected double dt_; diff --git a/src/QLNet/Methods/lattices/bsmlattice.cs b/src/QLNet/Methods/lattices/BsmLattice.cs similarity index 91% rename from src/QLNet/Methods/lattices/bsmlattice.cs rename to src/QLNet/Methods/lattices/BsmLattice.cs index 527cd994e..4e1413af8 100644 --- a/src/QLNet/Methods/lattices/bsmlattice.cs +++ b/src/QLNet/Methods/lattices/BsmLattice.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -40,8 +40,8 @@ public BlackScholesLattice(ITree tree, double riskFreeRate, double end, int step { tree_ = tree; riskFreeRate_ = riskFreeRate; - dt_ = end/steps; - discount_ = Math.Exp(-riskFreeRate*(end/steps)); + dt_ = end / steps; + discount_ = Math.Exp(-riskFreeRate * (end / steps)); pd_ = tree.probability(0, 0, 0); pu_ = tree.probability(0, 0, 1); } @@ -69,7 +69,7 @@ public double discount(int i, int j) public override void stepback(int i, Vector values, Vector newValues) { for (int j = 0; j < size(i); j++) - newValues[j] = (pd_*values[j] + pu_*values[j + 1])*discount_; + newValues[j] = (pd_ * values[j] + pu_ * values[j + 1]) * discount_; } public override double underlying(int i, int index) diff --git a/src/QLNet/Methods/lattices/Lattice.cs b/src/QLNet/Methods/lattices/Lattice.cs new file mode 100644 index 000000000..8cfcff060 --- /dev/null +++ b/src/QLNet/Methods/lattices/Lattice.cs @@ -0,0 +1,147 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + + +namespace QLNet +{ + //! Tree-based lattice-method base class + /*! This class defines a lattice method that is able to rollback + (with discount) a discretized asset object. It will be based + on one or more trees. + */ + public interface IGenericLattice + { + int size(int i); + double discount(int i, int j); + void stepback(int i, Vector values, Vector newValues); + double underlying(int i, int index); + int descendant(int i, int index, int branch); + double probability(int i, int index, int branch); + } + + public class TreeLattice : Lattice where T : IGenericLattice + { + // this should be overriden in the dering class + protected virtual T impl() { throw new NotSupportedException(); } + + private int n_; + private int statePricesLimit_; + + // Arrow-Debrew state prices + protected List statePrices_; + + public TreeLattice(TimeGrid timeGrid, int n) : base(timeGrid) + { + n_ = n; + Utils.QL_REQUIRE(n > 0, () => "there is no zeronomial lattice!"); + statePrices_ = new InitializedList(1, new Vector(1, 1.0)); + statePricesLimit_ = 0; + } + + + // Lattice interface + public override void initialize(DiscretizedAsset asset, double t) + { + int i = t_.index(t); + asset.setTime(t); + asset.reset(impl().size(i)); + } + + public override void rollback(DiscretizedAsset asset, double to) + { + partialRollback(asset, to); + asset.adjustValues(); + } + + public override void partialRollback(DiscretizedAsset asset, double to) + { + double from = asset.time(); + + if (Utils.close(from, to)) + return; + + Utils.QL_REQUIRE(from > to, () => "cannot roll the asset back to" + to + " (it is already at t = " + from + ")"); + + int iFrom = t_.index(from); + int iTo = t_.index(to); + + for (int i = iFrom - 1; i >= iTo; --i) + { + Vector newValues = new Vector(impl().size(i)); + impl().stepback(i, asset.values(), newValues); + asset.setTime(t_[i]); + asset.setValues(newValues); + // skip the very last adjustment + if (i != iTo) + asset.adjustValues(); + } + } + + //! Computes the present value of an asset using Arrow-Debrew prices + public override double presentValue(DiscretizedAsset asset) + { + int i = t_.index(asset.time()); + return Vector.DotProduct(asset.values(), statePrices(i)); + } + + public Vector statePrices(int i) + { + if (i > statePricesLimit_) + computeStatePrices(i); + return statePrices_[i]; + } + + public virtual void stepback(int i, Vector values, Vector newValues) + { + for (int j = 0; j < impl().size(i); j++) + { + double value = 0.0; + for (int l = 0; l < n_; l++) + { + double d1, d2; + d1 = impl().probability(i, j, l); + d2 = values[impl().descendant(i, j, l)]; + value += impl().probability(i, j, l) * values[impl().descendant(i, j, l)]; + } + value *= impl().discount(i, j); + newValues[j] = value; + } + } + + protected void computeStatePrices(int until) + { + for (int i = statePricesLimit_; i < until; i++) + { + statePrices_.Add(new Vector(impl().size(i + 1), 0.0)); + for (int j = 0; j < impl().size(i); j++) + { + double disc = impl().discount(i, j); + double statePrice = statePrices_[i][j]; + for (int l = 0; l < n_; l++) + { + statePrices_[i + 1][impl().descendant(i, j, l)] += statePrice * disc * impl().probability(i, j, l); + } + } + } + statePricesLimit_ = until; + } + } +} diff --git a/src/QLNet/Methods/lattices/Lattice1D.cs b/src/QLNet/Methods/lattices/Lattice1D.cs new file mode 100644 index 000000000..c5f4c066a --- /dev/null +++ b/src/QLNet/Methods/lattices/Lattice1D.cs @@ -0,0 +1,40 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +namespace QLNet +{ + //! One-dimensional tree-based lattice. + public class TreeLattice1D : TreeLattice where T : IGenericLattice + { + public TreeLattice1D(TimeGrid timeGrid, int n) : base(timeGrid, n) { } + + public override Vector grid(double t) + { + int i = timeGrid().index(t); + Vector grid = new Vector(impl().size(i)); + for (int j = 0; j < grid.size(); j++) + grid[j] = impl().underlying(i, j); + return grid; + } + public virtual double underlying(int i, int index) + { + return impl().underlying(i, index); + } + } +} diff --git a/src/QLNet/Methods/lattices/Lattice2D.cs b/src/QLNet/Methods/lattices/Lattice2D.cs new file mode 100644 index 000000000..5c505f839 --- /dev/null +++ b/src/QLNet/Methods/lattices/Lattice2D.cs @@ -0,0 +1,116 @@ +/* + Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + + +namespace QLNet +{ + + //! Two-dimensional tree-based lattice. + /*! This lattice is based on two trinomial trees and primarily used + for the G2 short-rate model. + + \ingroup lattices + */ + public class TreeLattice2D : TreeLattice + where T : IGenericLattice + where Tl : TrinomialTree + { + Matrix m_; + double rho_; + + protected Tl tree1_; + protected Tl tree2_; + public enum Branches { branches = 3 } + //// smelly + + public override Vector grid(double t) { throw new NotImplementedException("not implemented"); } + + // this is a workaround for CuriouslyRecurringTemplate of TreeLattice + // recheck it + public TreeLattice2D(TrinomialTree tree1, TrinomialTree tree2, double correlation) + : base(tree1.timeGrid(), (int)Branches.branches * (int)Branches.branches) + { + tree1_ = (Tl) tree1; //le cast à voir!! + tree2_ = (Tl)tree2; //le cast à voir!! + m_ = new Matrix((int)Branches.branches, (int)Branches.branches); + rho_ = Math.Abs(correlation); + + // what happens here? + if (correlation < 0.0 && (int)Branches.branches == 3) + { + m_[0, 0] = -1.0; + m_[0, 1] = -4.0; + m_[0, 2] = 5.0; + m_[1, 0] = -4.0; + m_[1, 1] = 8.0; + m_[1, 2] = -4.0; + m_[2, 0] = 5.0; + m_[2, 1] = -4.0; + m_[2, 2] = -1.0; + } + else + { + m_[0, 0] = 5.0; + m_[0, 1] = -4.0; + m_[0, 2] = -1.0; + m_[1, 0] = -4.0; + m_[1, 1] = 8.0; + m_[1, 2] = -4.0; + m_[2, 0] = -1.0; + m_[2, 1] = -4.0; + m_[2, 2] = 5.0; + } + } + + public int size(int i) {return (tree1_.size(i) * tree2_.size(i));} + + public int descendant(int i, int index, int branch) + { + int modulo = tree1_.size(i); + + int index1 = index % modulo; + int index2 = index / modulo; + int branch1 = branch % (int)Branches.branches; + int branch2 = branch / (int)Branches.branches; + + modulo = tree1_.size(i + 1); + return tree1_.descendant(i, index1, branch1) + + tree2_.descendant(i, index2, branch2) * modulo; + } + + public double probability(int i, int index, int branch) + { + int modulo = tree1_.size(i); + int index1 = index % modulo; + int index2 = index / modulo; + int branch1 = branch % (int)Branches.branches; + int branch2 = branch / (int)Branches.branches; + + double prob1 = tree1_.probability(i, index1, branch1); + double prob2 = tree2_.probability(i, index2, branch2); + // does the 36 below depend on T::branches? + return prob1 * prob2 + rho_ * (m_[branch1, branch2]) / 36.0; + } + + } + +} + + diff --git a/src/QLNet/Methods/lattices/tree.cs b/src/QLNet/Methods/lattices/Tree.cs similarity index 93% rename from src/QLNet/Methods/lattices/tree.cs rename to src/QLNet/Methods/lattices/Tree.cs index 926a16702..3bcafe765 100644 --- a/src/QLNet/Methods/lattices/tree.cs +++ b/src/QLNet/Methods/lattices/Tree.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Methods/lattices/TrinomialTree.cs b/src/QLNet/Methods/lattices/TrinomialTree.cs new file mode 100644 index 000000000..234f83e18 --- /dev/null +++ b/src/QLNet/Methods/lattices/TrinomialTree.cs @@ -0,0 +1,177 @@ +/* + Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + public class TrinomialTree : Tree + { + public enum Branches { branches = 3 } + private List branchings_; + protected double x0_; + protected List dx_; + protected TimeGrid timeGrid_; + + public TrinomialTree(StochasticProcess1D process, + TimeGrid timeGrid) + : this(process, timeGrid, false) {} + + public TrinomialTree(StochasticProcess1D process, + TimeGrid timeGrid, + bool isPositive /*= false*/) + : base(timeGrid.size()) + { + branchings_ = new List(); + dx_ = new InitializedList(1); + timeGrid_ = timeGrid; + x0_ = process.x0(); + + int nTimeSteps = timeGrid.size() - 1; + int jMin = 0; + int jMax = 0; + + for (int i = 0; i < nTimeSteps; i++) + { + double t = timeGrid[i]; + double dt = timeGrid.dt(i); + + //Variance must be independent of x + double v2 = process.variance(t, 0.0, dt); + double v = Math.Sqrt(v2); + dx_.Add(v * Math.Sqrt(3.0)); + + Branching branching = new Branching(); + for (int j = jMin; j <= jMax; j++) + { + double x = x0_ + j * dx_[i]; + double m = process.expectation(t, x, dt); + int temp = (int)(Math.Floor((m - x0_) / dx_[i + 1] + 0.5)); + + if (isPositive) + { + while (x0_ + (temp - 1)*dx_[i + 1] <= 0) + { + temp++; + } + } + + double e = m - (x0_ + temp * dx_[i + 1]); + double e2 = e * e; + double e3 = e * Math.Sqrt(3.0); + + double p1 = (1.0 + e2 / v2 - e3 / v) / 6.0; + double p2 = (2.0 - e2 / v2) / 3.0; + double p3 = (1.0 + e2 / v2 + e3 / v) / 6.0; + + branching.add(temp, p1, p2, p3); + } + branchings_.Add(branching); + + jMin = branching.jMin(); + jMax = branching.jMax(); + } + } + + public double dx(int i) { return dx_[i]; } + + public TimeGrid timeGrid() { return timeGrid_; } + + public int size(int i) { return i == 0 ? 1 : branchings_[i - 1].size(); } + + public double underlying(int i, int index) + { + if (i == 0) + return x0_; + else + return x0_ + (branchings_[i - 1].jMin() + + (double)index) * dx(i); + } + + public int descendant(int i, int index, int branch) + { + return branchings_[i].descendant(index, branch); + } + + public double probability(int i, int index, int branch) + { + return branchings_[i].probability(index, branch); + } + + /* Branching scheme for a trinomial node. Each node has three + descendants, with the middle branch linked to the node + which is closest to the expectation of the variable. */ + private class Branching + { + + private List k_; + private List> probs_; + private int kMin_, jMin_, kMax_, jMax_; + + public Branching() + { + k_ = new List(); + probs_ = new InitializedList>(3); + kMin_ = int.MaxValue ; + jMin_ = int.MaxValue ; + kMax_ = int.MinValue; + jMax_ = int.MinValue ; + } + public int descendant(int index, int branch) + { + return k_[index] - jMin_ - 1 + branch; + } + + public double probability(int index, int branch) + { + return probs_[branch][index]; + } + + public int size() + { + return jMax_ - jMin_ + 1; + } + + public int jMin() + { + return jMin_; + } + + public int jMax() + { + return jMax_; + } + + public void add + (int k, double p1, double p2, double p3) + { + // store + k_.Add(k); + probs_[0].Add(p1); + probs_[1].Add(p2); + probs_[2].Add(p3); + // maintain invariants + kMin_ = Math.Min(kMin_, k); + jMin_ = kMin_ - 1; + kMax_ = Math.Max(kMax_, k); + jMax_ = kMax_ + 1; + } + } + } +} diff --git a/src/QLNet/Methods/lattices/lattice.cs b/src/QLNet/Methods/lattices/lattice.cs deleted file mode 100644 index fa922c0b5..000000000 --- a/src/QLNet/Methods/lattices/lattice.cs +++ /dev/null @@ -1,130 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - - -namespace QLNet { - //! Tree-based lattice-method base class - /*! This class defines a lattice method that is able to rollback - (with discount) a discretized asset object. It will be based - on one or more trees. - */ - public interface IGenericLattice - { - int size(int i); - double discount(int i, int j); - void stepback(int i, Vector values, Vector newValues); - double underlying(int i, int index); - int descendant(int i, int index, int branch); - double probability(int i, int index, int branch); - } - - public class TreeLattice : Lattice where T : IGenericLattice{ - // this should be overriden in the dering class - protected virtual T impl() { throw new NotSupportedException(); } - - private int n_; - private int statePricesLimit_; - - // Arrow-Debrew state prices - protected List statePrices_; - - public TreeLattice(TimeGrid timeGrid, int n) : base(timeGrid) { - n_ = n; - Utils.QL_REQUIRE(n>0,()=> "there is no zeronomial lattice!"); - statePrices_ = new InitializedList(1, new Vector(1, 1.0)); - statePricesLimit_ = 0; - } - - - // Lattice interface - public override void initialize(DiscretizedAsset asset, double t) { - int i = t_.index(t); - asset.setTime(t); - asset.reset(impl().size(i)); - } - - public override void rollback(DiscretizedAsset asset, double to) { - partialRollback(asset,to); - asset.adjustValues(); - } - - public override void partialRollback(DiscretizedAsset asset, double to) { - double from = asset.time(); - - if (Utils.close(from,to)) return; - - Utils.QL_REQUIRE(from > to,()=> "cannot roll the asset back to" + to + " (it is already at t = " + from + ")"); - - int iFrom = t_.index(from); - int iTo = t_.index(to); - - for (int i=iFrom-1; i>=iTo; --i) { - Vector newValues = new Vector(impl().size(i)); - impl().stepback(i, asset.values(), newValues); - asset.setTime(t_[i]); - asset.setValues(newValues); - // skip the very last adjustment - if (i != iTo) - asset.adjustValues(); - } - } - - //! Computes the present value of an asset using Arrow-Debrew prices - public override double presentValue(DiscretizedAsset asset) { - int i = t_.index(asset.time()); - return Vector.DotProduct(asset.values(), statePrices(i)); - } - - public Vector statePrices(int i) { - if (i > statePricesLimit_) computeStatePrices(i); - return statePrices_[i]; - } - - public virtual void stepback(int i, Vector values, Vector newValues) { - for (int j=0; j. - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -namespace QLNet { - //! One-dimensional tree-based lattice. - public class TreeLattice1D : TreeLattice where T : IGenericLattice{ - public TreeLattice1D(TimeGrid timeGrid, int n) : base(timeGrid, n) { } - - public override Vector grid(double t) { - int i = timeGrid().index(t); - Vector grid = new Vector(impl().size(i)); - for (int j=0; j. - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - - -namespace QLNet { - - //! Two-dimensional tree-based lattice. - /*! This lattice is based on two trinomial trees and primarily used - for the G2 short-rate model. - - \ingroup lattices - */ - public class TreeLattice2D : TreeLattice - where T : IGenericLattice - where Tl : TrinomialTree - { - Matrix m_; - double rho_; - - protected Tl tree1_; - protected Tl tree2_; - public enum Branches { branches = 3 }; - //// smelly - - public override Vector grid(double t) { throw new NotImplementedException("not implemented"); } - - // this is a workaround for CuriouslyRecurringTemplate of TreeLattice - // recheck it - public TreeLattice2D(TrinomialTree tree1,TrinomialTree tree2,double correlation) - : base(tree1.timeGrid(), (int)Branches.branches * (int)Branches.branches) - { - tree1_ = (Tl) tree1; //le cast à voir!! - tree2_ = (Tl)tree2; //le cast à voir!! - m_ = new Matrix((int)Branches.branches, (int)Branches.branches); - rho_ = Math.Abs(correlation); - - // what happens here? - if (correlation < 0.0 && (int)Branches.branches == 3) - { - m_[0, 0] = -1.0; - m_[0, 1] = -4.0; - m_[0, 2] = 5.0; - m_[1, 0] = -4.0; - m_[1, 1] = 8.0; - m_[1, 2] = -4.0; - m_[2, 0] = 5.0; - m_[2, 1] = -4.0; - m_[2, 2] = -1.0; - } - else - { - m_[0, 0] = 5.0; - m_[0, 1] = -4.0; - m_[0, 2] = -1.0; - m_[1, 0] = -4.0; - m_[1, 1] = 8.0; - m_[1, 2] = -4.0; - m_[2, 0] = -1.0; - m_[2, 1] = -4.0; - m_[2, 2] = 5.0; - } - } - - public int size(int i) {return (tree1_.size(i)*tree2_.size(i));} - - public int descendant(int i, int index, int branch) - { - int modulo = tree1_.size(i); - - int index1 = index % modulo; - int index2 = index / modulo; - int branch1 = branch % (int)Branches.branches; - int branch2 = branch / (int)Branches.branches; - - modulo = tree1_.size(i+1); - return tree1_.descendant(i, index1, branch1) + - tree2_.descendant(i, index2, branch2)*modulo; - } - - public double probability(int i, int index, int branch) - { - int modulo = tree1_.size(i); - int index1 = index % modulo; - int index2 = index / modulo; - int branch1 = branch % (int)Branches.branches; - int branch2 = branch / (int)Branches.branches; - - double prob1 = tree1_.probability(i, index1, branch1); - double prob2 = tree2_.probability(i, index2, branch2); - // does the 36 below depend on T::branches? - return prob1*prob2 + rho_*(m_[branch1,branch2])/36.0; - } - - } - -} - - diff --git a/src/QLNet/Methods/lattices/trinomialtree.cs b/src/QLNet/Methods/lattices/trinomialtree.cs deleted file mode 100644 index 742998df9..000000000 --- a/src/QLNet/Methods/lattices/trinomialtree.cs +++ /dev/null @@ -1,162 +0,0 @@ -/* - Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet -{ - public class TrinomialTree : Tree - { - public enum Branches { branches = 3 }; - private List branchings_; - protected double x0_; - protected List dx_; - protected TimeGrid timeGrid_; - - public TrinomialTree( StochasticProcess1D process, - TimeGrid timeGrid) - : this( process,timeGrid,false){} - - public TrinomialTree( StochasticProcess1D process, - TimeGrid timeGrid, - bool isPositive /*= false*/) - : base(timeGrid.size()) - { - branchings_ = new List(); - dx_ = new InitializedList(1); - timeGrid_=timeGrid; - x0_ = process.x0(); - - int nTimeSteps = timeGrid.size() - 1; - int jMin = 0; - int jMax = 0; - - for (int i=0; i k_; - private List> probs_; - private int kMin_, jMin_, kMax_, jMax_; - - public Branching() - { - k_ = new List(); - probs_ = new InitializedList>(3); - kMin_ = int.MaxValue ; - jMin_ = int.MaxValue ; - kMax_ = int.MinValue; - jMax_ = int.MinValue ; - } - public int descendant(int index, int branch) { - return k_[index] - jMin_ - 1 + branch; - } - - public double probability(int index, int branch) { - return probs_[branch][index]; - } - - public int size() { - return jMax_ - jMin_ + 1; - } - - public int jMin() { - return jMin_; - } - - public int jMax() { - return jMax_; - } - - public void add(int k, double p1, double p2, double p3) { - // store - k_.Add(k); - probs_[0].Add(p1); - probs_[1].Add(p2); - probs_[2].Add(p3); - // maintain invariants - kMin_ = Math.Min(kMin_, k); - jMin_ = kMin_ - 1; - kMax_ = Math.Max(kMax_, k); - jMax_ = kMax_ + 1; - } - } - } -} diff --git a/src/QLNet/Methods/montecarlo/BrownianBridge.cs b/src/QLNet/Methods/montecarlo/BrownianBridge.cs new file mode 100644 index 000000000..598db3d92 --- /dev/null +++ b/src/QLNet/Methods/montecarlo/BrownianBridge.cs @@ -0,0 +1,198 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/using System; +using System.Collections.Generic; + +// =========================================================================== +// NOTE: The following copyright notice applies to the original code, +// +// Copyright (C) 2002 Peter Jдckel "Monte Carlo Methods in Finance". +// All rights reserved. +// +// Permission to use, copy, modify, and distribute this software is freely +// granted, provided that this notice is preserved. +// =========================================================================== +namespace QLNet +{ + //! Builds Wiener process paths using Gaussian variates + /*! This class generates normalized (i.e., unit-variance) paths as + sequences of variations. In order to obtain the actual path of + the underlying, the returned variations must be multiplied by + the integrated variance (including time) over the + corresponding time step. + + \ingroup mcarlo + */ + public class BrownianBridge + { + private int size_; + public int size() { return size_; } + + private List t_; + public List times() { return t_; } + + private List sqrtdt_; + private List bridgeIndex_, leftIndex_, rightIndex_; + private List leftWeight_, rightWeight_, stdDev_; + + + //! unit-time path + public BrownianBridge(int steps) + { + size_ = steps; + t_ = new InitializedList(size_); + sqrtdt_ = new InitializedList(size_); + bridgeIndex_ = new InitializedList(size_); + leftIndex_ = new InitializedList(size_); + rightIndex_ = new InitializedList(size_); + leftWeight_ = new InitializedList(size_); + rightWeight_ = new InitializedList(size_); + stdDev_ = new InitializedList(size_); + for (int i = 0; i < size_; ++i) + t_[i] = i + 1; + initialize(); + } + + //! generic times + /*! \note the starting time of the path is assumed to be 0 and must not be included */ + public BrownianBridge(List times) + { + size_ = times.Count; + t_ = new InitializedList(size_); + sqrtdt_ = new InitializedList(size_); + bridgeIndex_ = new InitializedList(size_); + leftIndex_ = new InitializedList(size_); + rightIndex_ = new InitializedList(size_); + leftWeight_ = new InitializedList(size_); + rightWeight_ = new InitializedList(size_); + stdDev_ = new InitializedList(size_); + initialize(); + } + + //! generic times + public BrownianBridge(TimeGrid timeGrid) + { + size_ = timeGrid.size() - 1; + t_ = new InitializedList(size_); + sqrtdt_ = new InitializedList(size_); + sqrtdt_ = new InitializedList(size_); + bridgeIndex_ = new InitializedList(size_); + leftIndex_ = new InitializedList(size_); + rightIndex_ = new InitializedList(size_); + leftWeight_ = new InitializedList(size_); + rightWeight_ = new InitializedList(size_); + stdDev_ = new InitializedList(size_); + for (int i = 0; i < size_; ++i) + t_[i] = timeGrid[i + 1]; + initialize(); + } + + + private void initialize() + { + sqrtdt_[0] = Math.Sqrt(t_[0]); + for (int i = 1; i < size_; ++i) + sqrtdt_[i] = Math.Sqrt(t_[i] - t_[i - 1]); + + // map is used to indicate which points are already constructed. + // If map[i] is zero, path point i is yet unconstructed. + // map[i]-1 is the index of the variate that constructs + // the path point # i. + List map = new InitializedList(size_); + + // The first point in the construction is the global step. + map[size_ - 1] = 1; + // The global step is constructed from the first variate. + bridgeIndex_[0] = size_ - 1; + // The variance of the global step + stdDev_[0] = Math.Sqrt(t_[size_ - 1]); + // The global step to the last point in time is special. + leftWeight_[0] = rightWeight_[0] = 0.0; + for (int j = 0, i = 1; i < size_; ++i) + { + // Find the next unpopulated entry in the map. + while (map[j] != 0) + ++j; + int k = j; + // Find the next populated entry in the map from there. + while (map[k] == 0) + ++k; + // l-1 is now the index of the point to be constructed next. + int l = j + ((k - 1 - j) >> 1); + map[l] = i; + // The i-th Gaussian variate will be used to set point l-1. + bridgeIndex_[i] = l; + leftIndex_[i] = j; + rightIndex_[i] = k; + if (j != 0) + { + leftWeight_[i] = (t_[k] - t_[l]) / (t_[k] - t_[j - 1]); + rightWeight_[i] = (t_[l] - t_[j - 1]) / (t_[k] - t_[j - 1]); + stdDev_[i] = + Math.Sqrt(((t_[l] - t_[j - 1]) * (t_[k] - t_[l])) + / (t_[k] - t_[j - 1])); + } + else + { + leftWeight_[i] = (t_[k] - t_[l]) / t_[k]; + rightWeight_[i] = t_[l] / t_[k]; + stdDev_[i] = Math.Sqrt(t_[l] * (t_[k] - t_[l]) / t_[k]); + } + j = k + 1; + if (j >= size_) + j = 0; // wrap around + } + } + + // Brownian-bridge constructor + public void transform(List begin, List output) + { + Utils.QL_REQUIRE(begin.Count != 0, () => "invalid sequence"); + Utils.QL_REQUIRE(begin.Count == size_, () => "incompatible sequence size"); + // We use output to store the path... + output[size_ - 1] = stdDev_[0] * begin[0]; + for (int i = 1; i < size_; ++i) + { + int j = leftIndex_[i]; + int k = rightIndex_[i]; + int l = bridgeIndex_[i]; + if (j != 0) + { + output[l] = + leftWeight_[i] * output[j - 1] + + rightWeight_[i] * output[k] + + stdDev_[i] * begin[i]; + } + else + { + output[l] = + rightWeight_[i] * output[k] + + stdDev_[i] * begin[i]; + } + } + // ...after which, we calculate the variations and + // normalize to unit times + for (int i = size_ - 1; i >= 1; --i) + { + output[i] -= output[i - 1]; + output[i] /= sqrtdt_[i]; + } + output[0] /= sqrtdt_[0]; + } + } +} diff --git a/src/QLNet/Methods/montecarlo/earlyexercisepathpricer.cs b/src/QLNet/Methods/montecarlo/EarlyExercisePathPricer.cs similarity index 94% rename from src/QLNet/Methods/montecarlo/earlyexercisepathpricer.cs rename to src/QLNet/Methods/montecarlo/EarlyExercisePathPricer.cs index f678ea533..9900fa6bf 100644 --- a/src/QLNet/Methods/montecarlo/earlyexercisepathpricer.cs +++ b/src/QLNet/Methods/montecarlo/EarlyExercisePathPricer.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Methods/montecarlo/LongstaffSchwartzPathPricer.cs b/src/QLNet/Methods/montecarlo/LongstaffSchwartzPathPricer.cs new file mode 100644 index 000000000..fbc06c6ff --- /dev/null +++ b/src/QLNet/Methods/montecarlo/LongstaffSchwartzPathPricer.cs @@ -0,0 +1,163 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + //! Longstaff-Schwarz path pricer for early exercise options + /*! References: + + Francis Longstaff, Eduardo Schwartz, 2001. Valuing American Options + by Simulation: A Simple Least-Squares Approach, The Review of + Financial Studies, Volume 14, No. 1, 113-147 + + \ingroup mcarlo + + \test the correctness of the returned value is tested by + reproducing results available in web/literature + */ + public class LongstaffSchwartzPathPricer : PathPricer where PathType : IPath + { + protected bool calibrationPhase_; + protected IEarlyExercisePathPricer pathPricer_; + + protected List coeff_; + protected List dF_; + + protected List paths_ = new List(); + protected List> v_; + + public LongstaffSchwartzPathPricer(TimeGrid times, IEarlyExercisePathPricer pathPricer, + YieldTermStructure termStructure) + { + calibrationPhase_ = true; + pathPricer_ = pathPricer; + coeff_ = new InitializedList(times.size() - 1); + dF_ = new InitializedList(times.size() - 1); + v_ = pathPricer_.basisSystem(); + + for (int i = 0; i < times.size() - 1; ++i) + { + dF_[i] = termStructure.discount(times[i + 1]) + / termStructure.discount(times[i]); + } + } + + + public double value(PathType path) + { + if (calibrationPhase_) + { + // store paths for the calibration + paths_.Add((PathType)path.Clone()); + // result doesn't matter + return 0.0; + } + + int len = EarlyExerciseTraits.pathLength(path); + double price = pathPricer_.value(path, len - 1); + for (int i = len - 2; i > 0; --i) + { + price *= dF_[i]; + + double exercise = pathPricer_.value(path, i); + if (exercise > 0.0) + { + double regValue = pathPricer_.state(path, i); + + double continuationValue = 0.0; + for (int l = 0; l < v_.Count; ++l) + { + continuationValue += coeff_[i][l] * v_[l](regValue); + } + + if (continuationValue < exercise) + { + price = exercise; + } + } + } + + return price * dF_[0]; + } + + public void calibrate() + { + int n = paths_.Count; + Vector prices = new Vector(n), exercise = new Vector(n); + int len = EarlyExerciseTraits.pathLength(paths_[0]); + + for (int i = 0; i < paths_.Count; i++) + prices[i] = pathPricer_.value(paths_[i], len - 1); + + for (int i = len - 2; i > 0; --i) + { + List y = new List(); + List x = new List(); + + //roll back step + for (int j = 0; j < n; ++j) + { + exercise[j] = pathPricer_.value(paths_[j], i); + + if (exercise[j] > 0.0) + { + x.Add(pathPricer_.state(paths_[j], i)); + y.Add(dF_[i]*prices[j]); + } + } + + if (v_.Count <= x.Count) + { + coeff_[i] = new LinearLeastSquaresRegression(x, y, v_).coefficients(); + } + else + { + // if number of itm paths is smaller then the number of + // calibration functions -> no early exercise + coeff_[i] = new Vector(v_.Count); + } + + for (int j = 0, k = 0; j < n; ++j) + { + prices[j] *= dF_[i]; + if (exercise[j] > 0.0) + { + double continuationValue = 0.0; + for (int l = 0; l < v_.Count; ++l) + { + continuationValue += coeff_[i][l] * v_[l](x[k]); + } + if (continuationValue < exercise[j]) + { + prices[j] = exercise[j]; + } + ++k; + } + } + } + + // remove calibration paths + paths_.Clear(); + // entering the calculation phase + calibrationPhase_ = false; + } + } +} diff --git a/src/QLNet/Methods/montecarlo/LsmBasisSystem.cs b/src/QLNet/Methods/montecarlo/LsmBasisSystem.cs new file mode 100644 index 000000000..68b618dbb --- /dev/null +++ b/src/QLNet/Methods/montecarlo/LsmBasisSystem.cs @@ -0,0 +1,183 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QLNet +{ + public static class LsmBasisSystem + { + public enum PolynomType + { + Monomial, Laguerre, Hermite, Hyperbolic, + Legendre, Chebyshev, Chebyshev2th + } + + public static List> pathBasisSystem(int order, PolynomType polynomType) + { + List> ret = new List>(); + for (int i = 0; i <= order; ++i) + { + switch (polynomType) + { + case PolynomType.Monomial: + ret.Add(new MonomialFct(i).value); + break; + case PolynomType.Laguerre: + ret.Add((x) => new GaussLaguerrePolynomial().weightedValue(i, x)); + break; + case PolynomType.Hermite: + ret.Add((x) => new GaussHermitePolynomial().weightedValue(i, x)); + break; + case PolynomType.Hyperbolic: + ret.Add((x) => new GaussHyperbolicPolynomial().weightedValue(i, x)); + break; + case PolynomType.Legendre: + ret.Add((x) => new GaussLegendrePolynomial().weightedValue(i, x)); + break; + case PolynomType.Chebyshev: + ret.Add((x) => new GaussChebyshevPolynomial().weightedValue(i, x)); + break; + case PolynomType.Chebyshev2th: + ret.Add((x) => new GaussChebyshev2ndPolynomial().weightedValue(i, x)); + break; + default: + Utils.QL_FAIL("unknown regression type"); + break; + } + } + return ret; + } + + + public static List> multiPathBasisSystem(int dim, int order, PolynomType polynomType) + { + + List> b = pathBasisSystem(order, polynomType); + + List> ret = new List>(); + ret.Add((xx) => 1.0); + + for (int i = 1; i <= order; ++i) + { + List> a = w(dim, i, polynomType, b); + + foreach (var iter in a) + { + ret.Add(iter); + } + } + + // remove-o-zap: now remove redundant functions. + // usually we do have a lot of them due to the construction schema. + // We use a more "hands on" method here. + List rm = new InitializedList(ret.Count, true); + + Vector x = new Vector(dim), v = new Vector(ret.Count); + MersenneTwisterUniformRng rng = new MersenneTwisterUniformRng(1234UL); + + for (int i = 0; i < 10; ++i) + { + int k; + + // calculate random x vector + for (k = 0; k < dim; ++k) + { + x[k] = rng.next().value; + } + + // get return values for all basis functions + for (k = 0; k < ret.Count; ++k) + { + v[k] = ret[k](x); + } + + // find duplicates + for (k = 0; k < ret.Count; ++k) + { + if (v.First(xx => (Math.Abs(v[k] - xx) <= 10 * v[k]*Const.QL_EPSILON)) .IsEqual(v.First() + k)) + { + // don't remove this item, it's unique! + rm[k] = false; + } + } + } + + int iter2 = 0; + for (int i = 0; i < rm.Count; ++i) + { + if (rm[i]) + { + ret.RemoveAt(iter2); + } + else + { + ++iter2; + } + } + + return ret; + } + + private static List> w(int dim, int order, PolynomType polynomType, List> b) + { + + List> ret = new List>(); + + for (int i = order; i >= 1; --i) + { + List> left = w(dim, order - i, polynomType, b); + + for (int j = 0; j < dim; ++j) + { + Func a = (xx => b[i](xx[j])); + + if (i == order) + ret.Add(a); + else // add linear combinations + for (j = 0; j < left.Count; ++j) + ret.Add(xx => a(xx * left[j](xx))); + } + } + return ret; + } + } + + + public class MonomialFct : IValue + { + private int order_; + + public MonomialFct(int order) + { + order_ = order; + } + + public double value(double x) + { + double ret = 1.0; + for (int i = 0; i < order_; ++i) + { + ret *= x; + } + return ret; + } + } +} diff --git a/src/QLNet/Methods/montecarlo/mctraits.cs b/src/QLNet/Methods/montecarlo/MCTraits.cs similarity index 92% rename from src/QLNet/Methods/montecarlo/mctraits.cs rename to src/QLNet/Methods/montecarlo/MCTraits.cs index d08938d53..64fc294a6 100644 --- a/src/QLNet/Methods/montecarlo/mctraits.cs +++ b/src/QLNet/Methods/montecarlo/MCTraits.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Methods/montecarlo/montecarlomodel.cs b/src/QLNet/Methods/montecarlo/MontecarloModel.cs similarity index 76% rename from src/QLNet/Methods/montecarlo/montecarlomodel.cs rename to src/QLNet/Methods/montecarlo/MontecarloModel.cs index 931d94d56..1929e6632 100644 --- a/src/QLNet/Methods/montecarlo/montecarlomodel.cs +++ b/src/QLNet/Methods/montecarlo/MontecarloModel.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -38,9 +38,9 @@ pricer and the option value. */ public class MonteCarloModel where S : IGeneralStatistics { - public MonteCarloModel( IPathGenerator pathGenerator, PathPricer pathPricer, - S sampleAccumulator,bool antitheticVariate, PathPricer cvPathPricer = null, - double cvOptionValue = 0,IPathGenerator cvPathGenerator = null) + public MonteCarloModel(IPathGenerator pathGenerator, PathPricer pathPricer, + S sampleAccumulator, bool antitheticVariate, PathPricer cvPathPricer = null, + double cvOptionValue = 0, IPathGenerator cvPathGenerator = null) { pathGenerator_ = pathGenerator; pathPricer_ = pathPricer; @@ -49,53 +49,53 @@ public MonteCarloModel( IPathGenerator pathGenerator, PathPricer pa cvPathPricer_ = cvPathPricer; cvOptionValue_ = cvOptionValue; cvPathGenerator_ = cvPathGenerator; - if ( cvPathPricer_ == null ) + if (cvPathPricer_ == null) isControlVariate_ = false; else isControlVariate_ = true; } - public void addSamples( int samples ) + public void addSamples(int samples) { - for ( int j = 1; j <= samples; j++ ) + for (int j = 1; j <= samples; j++) { Sample path = pathGenerator_.next(); - double price = pathPricer_.value( path.value ); + double price = pathPricer_.value(path.value); - if ( isControlVariate_ ) + if (isControlVariate_) { - if ( cvPathGenerator_ == null ) + if (cvPathGenerator_ == null) { - price += cvOptionValue_ - cvPathPricer_.value( path.value ); + price += cvOptionValue_ - cvPathPricer_.value(path.value); } else { Sample cvPath = cvPathGenerator_.next(); - price += cvOptionValue_ - cvPathPricer_.value( cvPath.value ); + price += cvOptionValue_ - cvPathPricer_.value(cvPath.value); } } - if ( isAntitheticVariate_ ) + if (isAntitheticVariate_) { path = pathGenerator_.antithetic(); - double price2 = pathPricer_.value( path.value ); - if ( isControlVariate_ ) + double price2 = pathPricer_.value(path.value); + if (isControlVariate_) { - if ( cvPathGenerator_ == null ) - price2 += cvOptionValue_ - cvPathPricer_.value( path.value ); + if (cvPathGenerator_ == null) + price2 += cvOptionValue_ - cvPathPricer_.value(path.value); else { Sample cvPath = cvPathGenerator_.antithetic(); - price2 += cvOptionValue_ - cvPathPricer_.value( cvPath.value ); + price2 += cvOptionValue_ - cvPathPricer_.value(cvPath.value); } } - sampleAccumulator_.add( ( price + price2 ) / 2.0, path.weight ); + sampleAccumulator_.add((price + price2) / 2.0, path.weight); } else { - sampleAccumulator_.add( price, path.weight ); + sampleAccumulator_.add(price, path.weight); } } } diff --git a/src/QLNet/Methods/montecarlo/MultiPath.cs b/src/QLNet/Methods/montecarlo/MultiPath.cs new file mode 100644 index 000000000..f8ae3b510 --- /dev/null +++ b/src/QLNet/Methods/montecarlo/MultiPath.cs @@ -0,0 +1,64 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + //! Correlated multiple asset paths + /*! MultiPath contains the list of paths for each asset, i.e., + multipath[j] is the path followed by the j-th asset. + + \ingroup mcarlo + */ + public class MultiPath : IPath + { + private List multiPath_; + + public MultiPath() {} + public MultiPath(int nAsset, TimeGrid timeGrid) + { + multiPath_ = new List(nAsset); + for (int i = 0; i < nAsset; i++) + multiPath_.Add(new Path(timeGrid)); + Utils.QL_REQUIRE(nAsset > 0, () => "number of asset must be positive"); + } + + public MultiPath(List multiPath) + { + multiPath_ = multiPath; + } + + // inspectors + public int assetNumber() { return multiPath_.Count; } + public int length() { return pathSize(); } + public int pathSize() { return multiPath_[0].length(); } + + // read/write access to components + public Path this[int j] { get { return multiPath_[j]; } set { multiPath_[j] = value; } } + + // ICloneable interface + public object Clone() + { + MultiPath temp = (MultiPath)this.MemberwiseClone(); + temp.multiPath_ = new List(this.multiPath_); + return temp; + } + } +} diff --git a/src/QLNet/Methods/montecarlo/multipathgenerator.cs b/src/QLNet/Methods/montecarlo/MultiPathGenerator.cs similarity index 86% rename from src/QLNet/Methods/montecarlo/multipathgenerator.cs rename to src/QLNet/Methods/montecarlo/MultiPathGenerator.cs index f1a7a7ab2..916b4a411 100644 --- a/src/QLNet/Methods/montecarlo/multipathgenerator.cs +++ b/src/QLNet/Methods/montecarlo/MultiPathGenerator.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -42,11 +42,11 @@ public MultiPathGenerator(StochasticProcess process, TimeGrid times, GSG generat next_ = new Sample(new MultiPath(process.size(), times), 1.0); Utils.QL_REQUIRE(generator_.dimension() == process.factors() * (times.size() - 1), () => - "dimension (" + generator_.dimension() - + ") is not equal to (" - + process.factors() + " * " + (times.size() - 1) - + ") the number of factors " - + "times the number of time steps"); + "dimension (" + generator_.dimension() + + ") is not equal to (" + + process.factors() + " * " + (times.size() - 1) + + ") the number of factors " + + "times the number of time steps"); Utils.QL_REQUIRE(times.size() > 1, () => "no times given"); } @@ -70,8 +70,8 @@ private Sample next(bool antithetic) Sample> sequence_ = antithetic - ? generator_.lastSequence() - : generator_.nextSequence(); + ? generator_.lastSequence() + : generator_.nextSequence(); int m = process_.size(); int n = process_.factors(); diff --git a/src/QLNet/Methods/montecarlo/Path.cs b/src/QLNet/Methods/montecarlo/Path.cs new file mode 100644 index 000000000..e68217813 --- /dev/null +++ b/src/QLNet/Methods/montecarlo/Path.cs @@ -0,0 +1,89 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Linq; + +namespace QLNet +{ + //! single-factor random walk + /*! \ingroup mcarlo + + \note the path includes the initial asset value as its first point. + */ + + public interface IPath : ICloneable + { + int length(); + } + + public interface IPathGenerator + { + Sample next(); + Sample antithetic(); + } + + public class Path : IPath + { + private TimeGrid timeGrid_; + private Vector values_; + + // required for generics + public Path() { } + + public Path(TimeGrid timeGrid) : this(timeGrid, new Vector()) { } + public Path(TimeGrid timeGrid, Vector values) + { + timeGrid_ = timeGrid; + values_ = values.Clone(); + if (values_.empty()) + values_ = new Vector(timeGrid_.size()); + + Utils.QL_REQUIRE(values_.size() == timeGrid_.size(), () => "different number of times and asset values"); + } + + // inspectors + public bool empty() { return timeGrid_.empty(); } + public int length() { return timeGrid_.size(); } + + //! asset value at the \f$ i \f$-th point + public double this[int i] { get { return values_[i]; } set { values_[i] = value; } } + public double value(int i) { return values_[i]; } + + //! time at the \f$ i \f$-th point + public double time(int i) { return timeGrid_[i]; } + + //! initial asset value + public double front() { return values_.First(); } + public void setFront(double value) { values_[0] = value; } + + //! final asset value + public double back() { return values_.Last(); } + + //! time grid + public TimeGrid timeGrid() { return timeGrid_; } + + // ICloneable interface + public object Clone() + { + Path temp = (Path)this.MemberwiseClone(); + temp.values_ = new Vector(this.values_); + return temp; + } + } +} diff --git a/src/QLNet/Methods/montecarlo/pathgenerator.cs b/src/QLNet/Methods/montecarlo/PathGenerator.cs similarity index 86% rename from src/QLNet/Methods/montecarlo/pathgenerator.cs rename to src/QLNet/Methods/montecarlo/PathGenerator.cs index 238d5a644..4c17c7773 100644 --- a/src/QLNet/Methods/montecarlo/pathgenerator.cs +++ b/src/QLNet/Methods/montecarlo/PathGenerator.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -53,7 +53,7 @@ public PathGenerator(StochasticProcess process, double length, int timeSteps, GS temp_ = new InitializedList(dimension_); bb_ = new BrownianBridge(timeGrid_); Utils.QL_REQUIRE(dimension_ == timeSteps, () => - "sequence generator dimensionality (" + dimension_ + ") != timeSteps (" + timeSteps + ")"); + "sequence generator dimensionality (" + dimension_ + ") != timeSteps (" + timeSteps + ")"); } public PathGenerator(StochasticProcess process, TimeGrid timeGrid, GSG generator, bool brownianBridge) @@ -68,7 +68,7 @@ public PathGenerator(StochasticProcess process, TimeGrid timeGrid, GSG generator bb_ = new BrownianBridge(timeGrid_); Utils.QL_REQUIRE(dimension_ == timeGrid_.size() - 1, () => - "sequence generator dimensionality (" + dimension_ + ") != timeSteps (" + (timeGrid_.size() - 1) + ")"); + "sequence generator dimensionality (" + dimension_ + ") != timeSteps (" + (timeGrid_.size() - 1) + ")"); } public Sample next() @@ -85,8 +85,8 @@ private Sample next(bool antithetic) { Sample> sequence_ = antithetic - ? generator_.lastSequence() - : generator_.nextSequence(); + ? generator_.lastSequence() + : generator_.nextSequence(); if (brownianBridge_) { @@ -107,9 +107,9 @@ private Sample next(bool antithetic) double t = timeGrid_[i - 1]; double dt = timeGrid_.dt(i - 1); path[i] = process_.evolve(t, path[i - 1], dt, - antithetic - ? -temp_[i - 1] - : temp_[i - 1]); + antithetic + ? -temp_[i - 1] + : temp_[i - 1]); } return next_; } diff --git a/src/QLNet/Methods/montecarlo/pathpricer.cs b/src/QLNet/Methods/montecarlo/PathPricer.cs similarity index 71% rename from src/QLNet/Methods/montecarlo/pathpricer.cs rename to src/QLNet/Methods/montecarlo/PathPricer.cs index 1403914ae..c3a24e6b0 100644 --- a/src/QLNet/Methods/montecarlo/pathpricer.cs +++ b/src/QLNet/Methods/montecarlo/PathPricer.cs @@ -1,29 +1,31 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { - //! base class for path pricers - /*! Returns the value of an option on a given path. +namespace QLNet +{ + //! base class for path pricers + /*! Returns the value of an option on a given path. - \ingroup mcarlo - */ - public interface PathPricer { - double value(PathType pt); - } + \ingroup mcarlo + */ + public interface PathPricer + { + double value(PathType pt); + } } diff --git a/src/QLNet/Methods/montecarlo/sample.cs b/src/QLNet/Methods/montecarlo/Sample.cs similarity index 93% rename from src/QLNet/Methods/montecarlo/sample.cs rename to src/QLNet/Methods/montecarlo/Sample.cs index b363124f3..46b5e932c 100644 --- a/src/QLNet/Methods/montecarlo/sample.cs +++ b/src/QLNet/Methods/montecarlo/Sample.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Methods/montecarlo/brownianbridge.cs b/src/QLNet/Methods/montecarlo/brownianbridge.cs deleted file mode 100644 index 83870543a..000000000 --- a/src/QLNet/Methods/montecarlo/brownianbridge.cs +++ /dev/null @@ -1,182 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/using System; -using System.Collections.Generic; - -// =========================================================================== -// NOTE: The following copyright notice applies to the original code, -// -// Copyright (C) 2002 Peter Jдckel "Monte Carlo Methods in Finance". -// All rights reserved. -// -// Permission to use, copy, modify, and distribute this software is freely -// granted, provided that this notice is preserved. -// =========================================================================== -namespace QLNet { - //! Builds Wiener process paths using Gaussian variates - /*! This class generates normalized (i.e., unit-variance) paths as - sequences of variations. In order to obtain the actual path of - the underlying, the returned variations must be multiplied by - the integrated variance (including time) over the - corresponding time step. - - \ingroup mcarlo - */ - public class BrownianBridge { - private int size_; - public int size() { return size_; } - - private List t_; - public List times() { return t_; } - - private List sqrtdt_; - private List bridgeIndex_, leftIndex_, rightIndex_; - private List leftWeight_, rightWeight_, stdDev_; - - - //! unit-time path - public BrownianBridge(int steps) { - size_ = steps; - t_ = new InitializedList(size_); - sqrtdt_ = new InitializedList(size_); - bridgeIndex_ = new InitializedList(size_); - leftIndex_ = new InitializedList(size_); - rightIndex_ = new InitializedList(size_); - leftWeight_ = new InitializedList(size_); - rightWeight_ = new InitializedList(size_); - stdDev_ = new InitializedList(size_); - for (int i=0; i times) { - size_ = times.Count; - t_ = new InitializedList(size_); - sqrtdt_ = new InitializedList(size_); - bridgeIndex_ = new InitializedList(size_); - leftIndex_ = new InitializedList(size_); - rightIndex_ = new InitializedList(size_); - leftWeight_ = new InitializedList(size_); - rightWeight_ = new InitializedList(size_); - stdDev_ = new InitializedList(size_); - initialize(); - } - - //! generic times - public BrownianBridge(TimeGrid timeGrid) { - size_ = timeGrid.size()-1; - t_ = new InitializedList(size_); - sqrtdt_ = new InitializedList(size_); - sqrtdt_ = new InitializedList(size_); - bridgeIndex_ = new InitializedList(size_); - leftIndex_ = new InitializedList(size_); - rightIndex_ = new InitializedList(size_); - leftWeight_ = new InitializedList(size_); - rightWeight_ = new InitializedList(size_); - stdDev_ = new InitializedList(size_); - for (int i=0; i map = new InitializedList(size_); - - // The first point in the construction is the global step. - map[size_-1] = 1; - // The global step is constructed from the first variate. - bridgeIndex_[0] = size_-1; - // The variance of the global step - stdDev_[0] = Math.Sqrt(t_[size_-1]); - // The global step to the last point in time is special. - leftWeight_[0] = rightWeight_[0] = 0.0; - for (int j=0, i=1; i>1); - map[l] = i; - // The i-th Gaussian variate will be used to set point l-1. - bridgeIndex_[i] = l; - leftIndex_[i] = j; - rightIndex_[i] = k; - if (j != 0) { - leftWeight_[i]= (t_[k]-t_[l])/(t_[k]-t_[j-1]); - rightWeight_[i] = (t_[l]-t_[j-1])/(t_[k]-t_[j-1]); - stdDev_[i] = - Math.Sqrt(((t_[l]-t_[j-1])*(t_[k]-t_[l])) - /(t_[k]-t_[j-1])); - } else { - leftWeight_[i] = (t_[k]-t_[l])/t_[k]; - rightWeight_[i] = t_[l]/t_[k]; - stdDev_[i] = Math.Sqrt(t_[l] * (t_[k] - t_[l]) / t_[k]); - } - j=k+1; - if (j>=size_) - j=0; // wrap around - } - } - - // Brownian-bridge constructor - public void transform(List begin, List output) { - Utils.QL_REQUIRE(begin.Count != 0,()=> "invalid sequence"); - Utils.QL_REQUIRE(begin.Count == size_,()=> "incompatible sequence size"); - // We use output to store the path... - output[size_-1] = stdDev_[0] * begin[0]; - for (int i=1; i= 1; --i) { - output[i] -= output[i-1]; - output[i] /= sqrtdt_[i]; - } - output[0] /= sqrtdt_[0]; - } - } -} diff --git a/src/QLNet/Methods/montecarlo/longstaffschwartzpathpricer.cs b/src/QLNet/Methods/montecarlo/longstaffschwartzpathpricer.cs deleted file mode 100644 index c3c498da6..000000000 --- a/src/QLNet/Methods/montecarlo/longstaffschwartzpathpricer.cs +++ /dev/null @@ -1,143 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet { - //! Longstaff-Schwarz path pricer for early exercise options - /*! References: - - Francis Longstaff, Eduardo Schwartz, 2001. Valuing American Options - by Simulation: A Simple Least-Squares Approach, The Review of - Financial Studies, Volume 14, No. 1, 113-147 - - \ingroup mcarlo - - \test the correctness of the returned value is tested by - reproducing results available in web/literature - */ - public class LongstaffSchwartzPathPricer : PathPricer where PathType : IPath { - protected bool calibrationPhase_; - protected IEarlyExercisePathPricer pathPricer_; - - protected List coeff_; - protected List dF_; - - protected List paths_ = new List(); - protected List> v_; - - public LongstaffSchwartzPathPricer(TimeGrid times, IEarlyExercisePathPricer pathPricer, - YieldTermStructure termStructure) { - calibrationPhase_ = true; - pathPricer_ = pathPricer; - coeff_ = new InitializedList(times.size()-1); - dF_ = new InitializedList(times.size()-1); - v_ = pathPricer_.basisSystem(); - - for (int i=0; i.pathLength(path); - double price = pathPricer_.value(path, len-1); - for (int i = len - 2; i > 0; --i) { - price*=dF_[i]; - - double exercise = pathPricer_.value(path, i); - if (exercise > 0.0) { - double regValue = pathPricer_.state(path, i); - - double continuationValue = 0.0; - for (int l = 0; l < v_.Count; ++l) { - continuationValue += coeff_[i][l] * v_[l](regValue); - } - - if (continuationValue < exercise) { - price = exercise; - } - } - } - - return price*dF_[0]; - } - - public void calibrate() { - int n = paths_.Count; - Vector prices = new Vector(n), exercise = new Vector(n); - int len = EarlyExerciseTraits.pathLength(paths_[0]); - - for(int i = 0; i0; --i) { - List y = new List(); - List x = new List(); - - //roll back step - for (int j=0; j0.0) { - x.Add(pathPricer_.state(paths_[j], i)); - y.Add(dF_[i]*prices[j]); - } - } - - if (v_.Count <= x.Count) { - coeff_[i] = new LinearLeastSquaresRegression(x, y, v_).coefficients(); - } - else { - // if number of itm paths is smaller then the number of - // calibration functions -> no early exercise - coeff_[i] = new Vector(v_.Count); - } - - for (int j=0, k=0; j0.0) { - double continuationValue = 0.0; - for (int l = 0; l < v_.Count; ++l) { - continuationValue += coeff_[i][l] * v_[l](x[k]); - } - if (continuationValue < exercise[j]) { - prices[j] = exercise[j]; - } - ++k; - } - } - } - - // remove calibration paths - paths_.Clear(); - // entering the calculation phase - calibrationPhase_ = false; - } - } -} diff --git a/src/QLNet/Methods/montecarlo/lsmbasissystem.cs b/src/QLNet/Methods/montecarlo/lsmbasissystem.cs deleted file mode 100644 index 82d69305d..000000000 --- a/src/QLNet/Methods/montecarlo/lsmbasissystem.cs +++ /dev/null @@ -1,159 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace QLNet { - public static class LsmBasisSystem { - public enum PolynomType { - Monomial, Laguerre, Hermite, Hyperbolic, - Legendre, Chebyshev, Chebyshev2th - }; - - public static List> pathBasisSystem(int order, PolynomType polynomType) { - List> ret = new List>(); - for (int i=0; i<=order; ++i) { - switch (polynomType) { - case PolynomType.Monomial: - ret.Add(new MonomialFct(i).value); - break; - case PolynomType.Laguerre: - ret.Add((x) => new GaussLaguerrePolynomial().weightedValue(i, x)); - break; - case PolynomType.Hermite: - ret.Add((x) => new GaussHermitePolynomial().weightedValue(i, x)); - break; - case PolynomType.Hyperbolic: - ret.Add((x) => new GaussHyperbolicPolynomial().weightedValue(i, x)); - break; - case PolynomType.Legendre: - ret.Add((x) => new GaussLegendrePolynomial().weightedValue(i, x)); - break; - case PolynomType.Chebyshev: - ret.Add((x) => new GaussChebyshevPolynomial().weightedValue(i, x)); - break; - case PolynomType.Chebyshev2th: - ret.Add((x) => new GaussChebyshev2ndPolynomial().weightedValue(i, x)); - break; - default: - Utils.QL_FAIL("unknown regression type"); - break; - } - } - return ret; - } - - - public static List> multiPathBasisSystem(int dim, int order, PolynomType polynomType) { - - List> b = pathBasisSystem(order, polynomType); - - List> ret = new List>(); - ret.Add((xx) => 1.0); - - for (int i=1; i<=order; ++i) { - List> a = w(dim, i, polynomType, b); - - foreach (var iter in a) { - ret.Add(iter); - } - } - - // remove-o-zap: now remove redundant functions. - // usually we do have a lot of them due to the construction schema. - // We use a more "hands on" method here. - List rm = new InitializedList(ret.Count, true); - - Vector x = new Vector(dim), v = new Vector(ret.Count); - MersenneTwisterUniformRng rng = new MersenneTwisterUniformRng(1234UL); - - for (int i=0; i<10; ++i) { - int k; - - // calculate random x vector - for (k=0; k (Math.Abs(v[k] - xx) <= 10*v[k]*Const.QL_EPSILON)) .IsEqual( v.First() + k)) { - // don't remove this item, it's unique! - rm[k] = false; - } - } - } - - int iter2 = 0; - for (int i = 0; i < rm.Count; ++i) { - if (rm[i]) { - ret.RemoveAt(iter2); - } - else { - ++iter2; - } - } - - return ret; - } - - private static List> w(int dim, int order, PolynomType polynomType, List> b) { - - List> ret = new List>(); - - for (int i=order; i>=1; --i) { - List> left = w(dim, order-i, polynomType, b); - - for (int j=0; j a = (xx => b[i](xx[j])); - - if (i == order) - ret.Add(a); - else // add linear combinations - for (j=0; j a(xx * left[j](xx))); - } - } - return ret; - } - } - - - public class MonomialFct : IValue { - private int order_; - - public MonomialFct(int order) { - order_ = order; - } - - public double value(double x) { - double ret = 1.0; - for (int i = 0; i < order_; ++i) { - ret *= x; - } - return ret; - } - } -} diff --git a/src/QLNet/Methods/montecarlo/multipath.cs b/src/QLNet/Methods/montecarlo/multipath.cs deleted file mode 100644 index e3d4e369b..000000000 --- a/src/QLNet/Methods/montecarlo/multipath.cs +++ /dev/null @@ -1,59 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet { - //! Correlated multiple asset paths - /*! MultiPath contains the list of paths for each asset, i.e., - multipath[j] is the path followed by the j-th asset. - - \ingroup mcarlo - */ - public class MultiPath : IPath { - private List multiPath_; - - public MultiPath() {} - public MultiPath(int nAsset, TimeGrid timeGrid) { - multiPath_ = new List(nAsset); - for (int i = 0; i < nAsset; i++) - multiPath_.Add(new Path(timeGrid)); - Utils.QL_REQUIRE(nAsset > 0,()=> "number of asset must be positive"); - } - - public MultiPath(List multiPath) { - multiPath_ = multiPath; - } - - // inspectors - public int assetNumber() { return multiPath_.Count; } - public int length() { return pathSize(); } - public int pathSize() { return multiPath_[0].length(); } - - // read/write access to components - public Path this[int j] { get { return multiPath_[j]; } set { multiPath_[j] = value; } } - - // ICloneable interface - public object Clone() { - MultiPath temp = (MultiPath)this.MemberwiseClone(); - temp.multiPath_ = new List(this.multiPath_); - return temp; - } - } -} diff --git a/src/QLNet/Methods/montecarlo/path.cs b/src/QLNet/Methods/montecarlo/path.cs deleted file mode 100644 index 6baa7fb7c..000000000 --- a/src/QLNet/Methods/montecarlo/path.cs +++ /dev/null @@ -1,85 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Linq; - -namespace QLNet { - //! single-factor random walk - /*! \ingroup mcarlo - - \note the path includes the initial asset value as its first point. - */ - - public interface IPath : ICloneable - { - int length(); - } - - public interface IPathGenerator - { - Sample next(); - Sample antithetic(); - } - - public class Path : IPath { - private TimeGrid timeGrid_; - private Vector values_; - - // required for generics - public Path() { } - - public Path(TimeGrid timeGrid) : this(timeGrid, new Vector()) { } - public Path(TimeGrid timeGrid, Vector values) { - timeGrid_ = timeGrid; - values_ = values.Clone(); - if (values_.empty()) - values_ = new Vector(timeGrid_.size()); - - Utils.QL_REQUIRE(values_.size() == timeGrid_.size(),()=> "different number of times and asset values"); - } - - // inspectors - public bool empty() { return timeGrid_.empty(); } - public int length() { return timeGrid_.size(); } - - //! asset value at the \f$ i \f$-th point - public double this[int i] { get { return values_[i]; } set { values_[i] = value; } } - public double value(int i) { return values_[i]; } - - //! time at the \f$ i \f$-th point - public double time(int i) { return timeGrid_[i]; } - - //! initial asset value - public double front() { return values_.First(); } - public void setFront(double value) { values_[0] = value; } - - //! final asset value - public double back() { return values_.Last(); } - - //! time grid - public TimeGrid timeGrid() { return timeGrid_; } - - // ICloneable interface - public object Clone() { - Path temp = (Path)this.MemberwiseClone(); - temp.values_ = new Vector(this.values_); - return temp; - } - } -} diff --git a/src/QLNet/Models/CalibrationHelper.cs b/src/QLNet/Models/CalibrationHelper.cs index 6c8fd0c1f..b29d42d6e 100644 --- a/src/QLNet/Models/CalibrationHelper.cs +++ b/src/QLNet/Models/CalibrationHelper.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,133 +22,132 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! liquid market instrument used during calibration - public abstract class CalibrationHelper : LazyObject - { - public enum CalibrationErrorType - { - RelativePriceError, PriceError, ImpliedVolError - } - - protected CalibrationHelper( Handle volatility, - Handle termStructure, - CalibrationErrorType calibrationErrorType = CalibrationErrorType.RelativePriceError, - VolatilityType type = VolatilityType.ShiftedLognormal, - double shift = 0.0) - { - volatility_ = volatility; - termStructure_ = termStructure; - calibrationErrorType_ = calibrationErrorType; - volatilityType_ = type; - shift_ = shift; - - volatility_.registerWith( update ); - termStructure_.registerWith( update ); - } - - protected override void performCalculations() - { - marketValue_ = blackPrice(volatility_.link.value()); - } - - //! returns the volatility Handle - public Handle volatility() { return volatility_; } - - //! returns the volatility type - public VolatilityType volatilityType() { return volatilityType_; } - - //! returns the actual price of the instrument (from volatility) - public double marketValue() { calculate(); return marketValue_; } - - //! returns the price of the instrument according to the model - public abstract double modelValue(); - - //! returns the error resulting from the model valuation - public virtual double calibrationError() - { - double error = 0 ; - - switch ( calibrationErrorType_ ) - { - case CalibrationErrorType.RelativePriceError: - error = Math.Abs( marketValue() - modelValue() ) / marketValue(); - break; - case CalibrationErrorType.PriceError: - error = marketValue() - modelValue(); - break; - case CalibrationErrorType.ImpliedVolError: - { - double minVol = volatilityType_ == VolatilityType.ShiftedLognormal ? 0.0010 : 0.00005; - double maxVol = volatilityType_ == VolatilityType.ShiftedLognormal ? 10.0 : 0.50; - double lowerPrice = blackPrice(minVol); - double upperPrice = blackPrice(maxVol); - double modelPrice = modelValue(); - - double implied; - if ( modelPrice <= lowerPrice ) - implied = 0.001; - else - if ( modelPrice >= upperPrice ) - implied = 10.0; - else - implied = this.impliedVolatility( modelPrice, 1e-12, 5000, 0.001, 10 ); - error = implied - volatility_.link.value(); - } - break; - default: - Utils.QL_FAIL( "unknown Calibration Error Type" ); - break; - } - - return error; - - } - - public abstract void addTimesTo( List times ); - - //! Black volatility implied by the model - public double impliedVolatility( double targetValue, - double accuracy, int maxEvaluations, double minVol, double maxVol ) - { - - ImpliedVolatilityHelper f = new ImpliedVolatilityHelper( this, targetValue ); - Brent solver = new Brent(); - solver.setMaxEvaluations( maxEvaluations ); - return solver.solve( f, accuracy, volatility_.link.value(), minVol, maxVol ); - } - - //! Black price given a volatility - public abstract double blackPrice( double volatility ); - - public void setPricingEngine( IPricingEngine engine ) {engine_ = engine;} - - - protected double marketValue_; - protected Handle volatility_; - protected Handle termStructure_; - protected IPricingEngine engine_; - protected VolatilityType volatilityType_; - protected double shift_; - - - private CalibrationErrorType calibrationErrorType_; - - private class ImpliedVolatilityHelper : ISolver1d - { - private CalibrationHelper helper_; - private double value_; - - public ImpliedVolatilityHelper( CalibrationHelper helper, double value ) - { - helper_ = helper; - value_ = value; - } - - public override double value( double x ) - { - return value_ - helper_.blackPrice( x ); - } - } - - } + //! liquid market instrument used during calibration + public abstract class CalibrationHelper : LazyObject + { + public enum CalibrationErrorType + { + RelativePriceError, PriceError, ImpliedVolError + } + + protected CalibrationHelper(Handle volatility, + Handle termStructure, + CalibrationErrorType calibrationErrorType = CalibrationErrorType.RelativePriceError, + VolatilityType type = VolatilityType.ShiftedLognormal, + double shift = 0.0) + { + volatility_ = volatility; + termStructure_ = termStructure; + calibrationErrorType_ = calibrationErrorType; + volatilityType_ = type; + shift_ = shift; + + volatility_.registerWith(update); + termStructure_.registerWith(update); + } + + protected override void performCalculations() + { + marketValue_ = blackPrice(volatility_.link.value()); + } + + //! returns the volatility Handle + public Handle volatility() { return volatility_; } + + //! returns the volatility type + public VolatilityType volatilityType() { return volatilityType_; } + + //! returns the actual price of the instrument (from volatility) + public double marketValue() { calculate(); return marketValue_; } + + //! returns the price of the instrument according to the model + public abstract double modelValue(); + + //! returns the error resulting from the model valuation + public virtual double calibrationError() + { + double error = 0 ; + + switch (calibrationErrorType_) + { + case CalibrationErrorType.RelativePriceError: + error = Math.Abs(marketValue() - modelValue()) / marketValue(); + break; + case CalibrationErrorType.PriceError: + error = marketValue() - modelValue(); + break; + case CalibrationErrorType.ImpliedVolError: + { + double minVol = volatilityType_ == VolatilityType.ShiftedLognormal ? 0.0010 : 0.00005; + double maxVol = volatilityType_ == VolatilityType.ShiftedLognormal ? 10.0 : 0.50; + double lowerPrice = blackPrice(minVol); + double upperPrice = blackPrice(maxVol); + double modelPrice = modelValue(); + + double implied; + if (modelPrice <= lowerPrice) + implied = 0.001; + else if (modelPrice >= upperPrice) + implied = 10.0; + else + implied = this.impliedVolatility(modelPrice, 1e-12, 5000, 0.001, 10); + error = implied - volatility_.link.value(); + } + break; + default: + Utils.QL_FAIL("unknown Calibration Error Type"); + break; + } + + return error; + + } + + public abstract void addTimesTo(List times); + + //! Black volatility implied by the model + public double impliedVolatility(double targetValue, + double accuracy, int maxEvaluations, double minVol, double maxVol) + { + + ImpliedVolatilityHelper f = new ImpliedVolatilityHelper(this, targetValue); + Brent solver = new Brent(); + solver.setMaxEvaluations(maxEvaluations); + return solver.solve(f, accuracy, volatility_.link.value(), minVol, maxVol); + } + + //! Black price given a volatility + public abstract double blackPrice(double volatility); + + public void setPricingEngine(IPricingEngine engine) {engine_ = engine;} + + + protected double marketValue_; + protected Handle volatility_; + protected Handle termStructure_; + protected IPricingEngine engine_; + protected VolatilityType volatilityType_; + protected double shift_; + + + private CalibrationErrorType calibrationErrorType_; + + private class ImpliedVolatilityHelper : ISolver1d + { + private CalibrationHelper helper_; + private double value_; + + public ImpliedVolatilityHelper(CalibrationHelper helper, double value) + { + helper_ = helper; + value_ = value; + } + + public override double value(double x) + { + return value_ - helper_.blackPrice(x); + } + } + + } } diff --git a/src/QLNet/Models/Equity/HestonModel.cs b/src/QLNet/Models/Equity/HestonModel.cs index d469e1726..b4aa87e5a 100644 --- a/src/QLNet/Models/Equity/HestonModel.cs +++ b/src/QLNet/Models/Equity/HestonModel.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -30,20 +30,20 @@ with Stochastic Volatility with Applications to Bond and public class HestonModel : CalibratedModel { public HestonModel(HestonProcess process) - :base(5) + : base(5) { process_ = process; - arguments_[0] = new ConstantParameter( process.theta(), new PositiveConstraint() ); - arguments_[1] = new ConstantParameter( process.kappa(), new PositiveConstraint() ); - arguments_[2] = new ConstantParameter( process.sigma(), new PositiveConstraint() ); - arguments_[3] = new ConstantParameter( process.rho(), new BoundaryConstraint( -1.0, 1.0 ) ); - arguments_[4] = new ConstantParameter( process.v0(), new PositiveConstraint() ); + arguments_[0] = new ConstantParameter(process.theta(), new PositiveConstraint()); + arguments_[1] = new ConstantParameter(process.kappa(), new PositiveConstraint()); + arguments_[2] = new ConstantParameter(process.sigma(), new PositiveConstraint()); + arguments_[3] = new ConstantParameter(process.rho(), new BoundaryConstraint(-1.0, 1.0)); + arguments_[4] = new ConstantParameter(process.v0(), new PositiveConstraint()); generateArguments(); process_.riskFreeRate().registerWith(update) ; - process_.dividendYield().registerWith( update) ; - process_.s0().registerWith( update ) ; + process_.dividendYield().registerWith(update) ; + process_.s0().registerWith(update) ; } @@ -63,41 +63,41 @@ public HestonModel(HestonProcess process) public class FellerConstraint : Constraint { - private class Impl : IConstraint + private class Impl : IConstraint { - public bool test(Vector param) + public bool test(Vector param) { double theta = param[0]; double kappa = param[1]; double sigma = param[2]; - return (sigma >= 0.0 && sigma*sigma < 2.0*kappa*theta); + return (sigma >= 0.0 && sigma * sigma < 2.0 * kappa * theta); } public Vector upperBound(Vector parameters) { - return new Vector( parameters.size(), Double.MaxValue ); + return new Vector(parameters.size(), Double.MaxValue); } public Vector lowerBound(Vector parameters) { - return new Vector( parameters.size(), Double.MinValue ); + return new Vector(parameters.size(), Double.MinValue); } } - + public FellerConstraint() - : base(new FellerConstraint.Impl()) + : base(new FellerConstraint.Impl()) {} - + } protected override void generateArguments() { - process_ = new HestonProcess( process_.riskFreeRate(), - process_.dividendYield(), - process_.s0(), - v0(), kappa(), theta(), - sigma(), rho() ) ; + process_ = new HestonProcess(process_.riskFreeRate(), + process_.dividendYield(), + process_.s0(), + v0(), kappa(), theta(), + sigma(), rho()) ; } protected HestonProcess process_; } diff --git a/src/QLNet/Models/Equity/HestonModelHelper.cs b/src/QLNet/Models/Equity/HestonModelHelper.cs index 1ce542315..ec0f948ba 100644 --- a/src/QLNet/Models/Equity/HestonModelHelper.cs +++ b/src/QLNet/Models/Equity/HestonModelHelper.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,15 +21,15 @@ namespace QLNet //! calibration helper for Heston model public class HestonModelHelper : CalibrationHelper { - public HestonModelHelper( Period maturity, - Calendar calendar, - double s0, - double strikePrice, - Handle volatility, - Handle riskFreeRate, - Handle dividendYield, - CalibrationHelper.CalibrationErrorType errorType = CalibrationErrorType.RelativePriceError) - :base(volatility, riskFreeRate, errorType) + public HestonModelHelper(Period maturity, + Calendar calendar, + double s0, + double strikePrice, + Handle volatility, + Handle riskFreeRate, + Handle dividendYield, + CalibrationHelper.CalibrationErrorType errorType = CalibrationErrorType.RelativePriceError) + : base(volatility, riskFreeRate, errorType) { maturity_ = maturity; calendar_ = calendar; @@ -40,22 +40,22 @@ public HestonModelHelper( Period maturity, dividendYield.registerWith(update); } - public HestonModelHelper( Period maturity, - Calendar calendar, - Handle s0, - double strikePrice, - Handle volatility, - Handle riskFreeRate, - Handle dividendYield, - CalibrationHelper.CalibrationErrorType errorType = CalibrationErrorType.RelativePriceError) - :base(volatility, riskFreeRate, errorType) + public HestonModelHelper(Period maturity, + Calendar calendar, + Handle s0, + double strikePrice, + Handle volatility, + Handle riskFreeRate, + Handle dividendYield, + CalibrationHelper.CalibrationErrorType errorType = CalibrationErrorType.RelativePriceError) + : base(volatility, riskFreeRate, errorType) { maturity_ = maturity; calendar_ = calendar; s0_ = s0; strikePrice_ = strikePrice; dividendYield_ = dividendYield; - + s0.registerWith(update); dividendYield.registerWith(update); } @@ -67,13 +67,13 @@ protected override void performCalculations() exerciseDate_ = calendar_.advance(termStructure_.link.referenceDate(), maturity_); tau_ = termStructure_.link.timeFromReference(exerciseDate_); type_ = strikePrice_ * termStructure_.link.discount(tau_) >= - s0_.link.value() * dividendYield_.link.discount(tau_) - ? Option.Type.Call - : Option.Type.Put; - StrikedTypePayoff payoff = new PlainVanillaPayoff(type_, strikePrice_); - Exercise exercise = new EuropeanExercise(exerciseDate_); - option_ = new VanillaOption(payoff, exercise); - base.performCalculations(); + s0_.link.value() * dividendYield_.link.discount(tau_) + ? Option.Type.Call + : Option.Type.Put; + StrikedTypePayoff payoff = new PlainVanillaPayoff(type_, strikePrice_); + Exercise exercise = new EuropeanExercise(exerciseDate_); + option_ = new VanillaOption(payoff, exercise); + base.performCalculations(); } public override double modelValue() @@ -87,13 +87,14 @@ public override double blackPrice(double volatility) { calculate(); double stdDev = volatility * Math.Sqrt(maturity()); - return Utils.blackFormula( type_, strikePrice_ * termStructure_.link.discount(tau_), - s0_.link.value() * dividendYield_.link.discount(tau_), stdDev); + return Utils.blackFormula(type_, strikePrice_ * termStructure_.link.discount(tau_), + s0_.link.value() * dividendYield_.link.discount(tau_), stdDev); } public double maturity() { calculate(); return tau_; } - - + public Option.Type optionType() { calculate(); return type_; } + public double strike() { return strikePrice_; } + private Period maturity_; private Calendar calendar_; private Handle s0_; @@ -103,7 +104,7 @@ public override double blackPrice(double volatility) private double tau_; private Option.Type type_; private VanillaOption option_; - } + } + - } diff --git a/src/QLNet/Models/Equity/PiecewiseTimeDependentHestonModel.cs b/src/QLNet/Models/Equity/PiecewiseTimeDependentHestonModel.cs index 902753cb4..c2304cd09 100644 --- a/src/QLNet/Models/Equity/PiecewiseTimeDependentHestonModel.cs +++ b/src/QLNet/Models/Equity/PiecewiseTimeDependentHestonModel.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -27,23 +27,23 @@ namespace QLNet with Stochastic Volatility with Applications to Bond and Currency Options. The review of Financial Studies, Volume 6, Issue 2, 327-343. - - A. Elices, Models with time-dependent parameters using + + A. Elices, Models with time-dependent parameters using transform methods: application to Heston’s model, http://arxiv.org/pdf/0708.2020 */ public class PiecewiseTimeDependentHestonModel : CalibratedModel { - public PiecewiseTimeDependentHestonModel( Handle riskFreeRate, - Handle dividendYield, - Handle s0, - double v0, - Parameter theta, - Parameter kappa, - Parameter sigma, - Parameter rho, - TimeGrid timeGrid) - :base(5) + public PiecewiseTimeDependentHestonModel(Handle riskFreeRate, + Handle dividendYield, + Handle s0, + double v0, + Parameter theta, + Parameter kappa, + Parameter sigma, + Parameter rho, + TimeGrid timeGrid) + : base(5) { s0_ = s0; riskFreeRate_ = riskFreeRate; @@ -54,7 +54,7 @@ public PiecewiseTimeDependentHestonModel( Handle riskFreeRat arguments_[1] = kappa; arguments_[2] = sigma; arguments_[3] = rho; - arguments_[4] = new ConstantParameter( v0, new PositiveConstraint() ); + arguments_[4] = new ConstantParameter(v0, new PositiveConstraint()); s0.registerWith(update) ; riskFreeRate.registerWith(update) ; @@ -78,8 +78,8 @@ public PiecewiseTimeDependentHestonModel( Handle riskFreeRat public TimeGrid timeGrid() { return timeGrid_; } public Handle dividendYield() { return dividendYield_; } public Handle riskFreeRate() { return riskFreeRate_; } - - + + protected Handle s0_; protected Handle riskFreeRate_; protected Handle dividendYield_; diff --git a/src/QLNet/Models/MarketModels/BrownianGenerator.cs b/src/QLNet/Models/MarketModels/BrownianGenerator.cs index 5ab4f10d5..158e7f210 100644 --- a/src/QLNet/Models/MarketModels/BrownianGenerator.cs +++ b/src/QLNet/Models/MarketModels/BrownianGenerator.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -26,9 +26,9 @@ public interface IBrownianGenerator int numberOfSteps() ; } - public interface IBrownianGeneratorFactory + public interface IBrownianGeneratorFactory { - IBrownianGenerator create(int factors,int steps) ; + IBrownianGenerator create(int factors, int steps) ; } } diff --git a/src/QLNet/Models/MarketModels/BrownianGenerators/SobolBrownianGenerator.cs b/src/QLNet/Models/MarketModels/BrownianGenerators/SobolBrownianGenerator.cs index fe5a63112..f50ec4e75 100644 --- a/src/QLNet/Models/MarketModels/BrownianGenerators/SobolBrownianGenerator.cs +++ b/src/QLNet/Models/MarketModels/BrownianGenerators/SobolBrownianGenerator.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,7 +24,8 @@ namespace QLNet */ public class SobolBrownianGenerator : IBrownianGenerator { - public enum Ordering { + public enum Ordering + { Factors, /*!< The variates with the best quality will be used for the evolution of the first factor. */ Steps, /*!< The variates with the best quality will be @@ -34,22 +35,22 @@ the variates with the best quality to the most important factors and the largest steps. */ } - public SobolBrownianGenerator( int factors, int steps,Ordering ordering,ulong seed = 0, - SobolRsg.DirectionIntegers directionIntegers = SobolRsg.DirectionIntegers.Jaeckel) + public SobolBrownianGenerator(int factors, int steps, Ordering ordering, ulong seed = 0, + SobolRsg.DirectionIntegers directionIntegers = SobolRsg.DirectionIntegers.Jaeckel) { factors_ = factors; steps_ = steps; ordering_ = ordering; generator_ = new InverseCumulativeRsg( - new SobolRsg(factors*steps, seed, directionIntegers),new InverseCumulativeNormal()); + new SobolRsg(factors * steps, seed, directionIntegers), new InverseCumulativeNormal()); bridge_ = new BrownianBridge(steps); lastStep_ = 0; orderedIndices_ = new InitializedList>(factors); bridgedVariates_ = new InitializedList>(factors); - for ( int i = 0 ; i < factors ; i++) + for (int i = 0 ; i < factors ; i++) { orderedIndices_[i] = new InitializedList(steps); - bridgedVariates_[i] = new InitializedList( steps ); + bridgedVariates_[i] = new InitializedList(steps); } switch (ordering_) @@ -73,26 +74,26 @@ public double nextPath() { Sample> sample = generator_.nextSequence(); // Brownian-bridge the variates according to the ordered indices - for (int i=0; i permList = new List(); - foreach ( var index in orderedIndices_[i] ) + foreach (var index in orderedIndices_[i]) { - permList.Add( sample.value[index]); + permList.Add(sample.value[index]); } - bridge_.transform( permList, bridgedVariates_[i] ); // TODO Check + bridge_.transform(permList, bridgedVariates_[i]); // TODO Check } lastStep_ = 0; return sample.weight; } public double nextStep(List output) { - #if QL_EXTRA_SAFETY_CHECKS - Utils.QL_REQUIRE(output.Count == factors_,()=> "size mismatch"); - Utils.QL_REQUIRE(lastStep_ "sequence exhausted"); - #endif - for (int i=0; i "size mismatch"); + Utils.QL_REQUIRE(lastStep_ "sequence exhausted"); +#endif + for (int i = 0; i output) public int numberOfFactors() { return factors_; } public int numberOfSteps() { return steps_; } - + // test interface public List > orderedIndices() {return orderedIndices_;} public List > transform(List > variates) { - Utils.QL_REQUIRE( (variates.Count == factors_*steps_),()=> "inconsistent variate vector"); + Utils.QL_REQUIRE((variates.Count == factors_ * steps_), () => "inconsistent variate vector"); - int dim = factors_*steps_; + int dim = factors_ * steps_; int nPaths = variates.First().Count; - - List> retVal = new InitializedList>(factors_,new InitializedList(nPaths*steps_)); - - for (int j=0; j < nPaths; ++j) + + List> retVal = new InitializedList>(factors_, new InitializedList(nPaths * steps_)); + + for (int j = 0; j < nPaths; ++j) { - List sample = new InitializedList(steps_*factors_); - for (int k=0; k < dim; ++k) + List sample = new InitializedList(steps_ * factors_); + for (int k = 0; k < dim; ++k) { sample[k] = variates[k][j]; } - for (int i=0; i permList = new List(); - foreach ( var index in orderedIndices_[i] ) + foreach (var index in orderedIndices_[i]) { - permList.Add( sample[index] ); + permList.Add(sample[index]); } - List temp = retVal[i].GetRange( j * steps_, retVal[i].Count - ( j * steps_ ) ); - bridge_.transform( permList, temp ); // TODO Check + List temp = retVal[i].GetRange(j * steps_, retVal[i].Count - (j * steps_)); + bridge_.transform(permList, temp); // TODO Check } } return retVal; } - private void fillByFactor(List > M,int factors, int steps) + private void fillByFactor(List > M, int factors, int steps) { int counter = 0; - for (int i=0; i > M,int factors, int steps) + private void fillByStep(List > M, int factors, int steps) { int counter = 0; - for ( int j = 0; j < steps; ++j ) - for ( int i = 0; i < factors; ++i ) + for (int j = 0; j < steps; ++j) + for (int i = 0; i < factors; ++i) M[i][j] = counter++; } // variate 2 is used for the second factor's full path - private void fillByDiagonal(List > M,int factors, int steps) + private void fillByDiagonal(List > M, int factors, int steps) { // starting position of the current diagonal int i0 = 0, j0 = 0; // current position int i = 0, j = 0; int counter = 0; - while (counter < factors*steps) + while (counter < factors * steps) { M[i][j] = counter++; - if (i == 0 || j == steps-1) + if (i == 0 || j == steps - 1) { // we completed a diagonal and have to start a new one - if (i0 < factors-1) + if (i0 < factors - 1) { // we start the path of the next factor - i0 = i0+1; + i0 = i0 + 1; j0 = 0; - } - else + } + else { // we move along the path of the last factor - i0 = factors-1; - j0 = j0+1; + i0 = factors - 1; + j0 = j0 + 1; } i = i0; j = j0; - } - else + } + else { // we move along the diagonal - i = i-1; - j = j+1; + i = i - 1; + j = j + 1; } } } - + private int factors_, steps_; private Ordering ordering_; - private InverseCumulativeRsg generator_; + private InverseCumulativeRsg generator_; private BrownianBridge bridge_; // work variables private int lastStep_; @@ -197,23 +198,23 @@ private void fillByDiagonal(List > M,int factors, int steps) private List > bridgedVariates_; } - public class SobolBrownianGeneratorFactory : IBrownianGeneratorFactory + public class SobolBrownianGeneratorFactory : IBrownianGeneratorFactory { - public SobolBrownianGeneratorFactory( SobolBrownianGenerator.Ordering ordering,ulong seed = 0, - SobolRsg.DirectionIntegers integers = SobolRsg.DirectionIntegers.Jaeckel) + public SobolBrownianGeneratorFactory(SobolBrownianGenerator.Ordering ordering, ulong seed = 0, + SobolRsg.DirectionIntegers integers = SobolRsg.DirectionIntegers.Jaeckel) { ordering_ = ordering; seed_ = seed; integers_ = integers; } - + public IBrownianGenerator create(int factors, int steps) { return new SobolBrownianGenerator(factors, steps, ordering_, seed_, integers_); } - + private SobolBrownianGenerator.Ordering ordering_; private ulong seed_; private SobolRsg.DirectionIntegers integers_; - }; + } } diff --git a/src/QLNet/Models/Model.cs b/src/QLNet/Models/Model.cs new file mode 100644 index 000000000..e15d119f4 --- /dev/null +++ b/src/QLNet/Models/Model.cs @@ -0,0 +1,382 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + //! Affine model class + /*! Base class for analytically tractable models. + + \ingroup shortrate + */ + public abstract class AffineModel : IObservable + { + //! Implied discount curve + public abstract double discount(double t); + public abstract double discountBond(double now, double maturity, Vector factors); + public abstract double discountBondOption(Option.Type type, double strike, double maturity, double bondMaturity); + + private readonly WeakEventSource eventSource = new WeakEventSource(); + public event Callback notifyObserversEvent + { + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } + } + + public void registerWith(Callback handler) { notifyObserversEvent += handler; } + public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } + protected void notifyObservers() + { + eventSource.Raise(); + } + } + + //Affince Model Interface used for multihritage in + //liborforwardmodel.cs & analyticcapfloorengine.cs + public interface IAffineModel : IObservable + { + double discount(double t); + double discountBond(double now, double maturity, Vector factors); + double discountBondOption(Option.Type type, double strike, double maturity, double bondMaturity); + } + + //TermStructureConsistentModel used in analyticcapfloorengine.cs + public class TermStructureConsistentModel : IObservable + { + public TermStructureConsistentModel(Handle termStructure) + { + termStructure_ = termStructure; + } + + public Handle termStructure() + { + return termStructure_; + } + private Handle termStructure_; + + private readonly WeakEventSource eventSource = new WeakEventSource(); + public event Callback notifyObserversEvent + { + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } + } + + public void registerWith(Callback handler) { notifyObserversEvent += handler; } + public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } + protected void notifyObservers() + { + eventSource.Raise(); + } + } + + //ITermStructureConsistentModel used ins shortratemodel blackkarasinski.cs/hullwhite.cs + public interface ITermStructureConsistentModel + { + Handle termStructure(); + Handle termStructure_ { get; set; } + void notifyObservers(); + event Callback notifyObserversEvent; + void registerWith(Callback handler); + void unregisterWith(Callback handler); + void update(); + } + + //! Calibrated model class + public class CalibratedModel : IObserver, IObservable + { + protected List arguments_; + + protected Constraint constraint_; + public Constraint constraint() { return constraint_; } + + protected EndCriteria.Type shortRateEndCriteria_; + public EndCriteria.Type endCriteria() { return shortRateEndCriteria_; } + + + public CalibratedModel(int nArguments) + { + arguments_ = new InitializedList(nArguments); + constraint_ = new PrivateConstraint(arguments_); + shortRateEndCriteria_ = EndCriteria.Type.None; + } + + //! Calibrate to a set of market instruments (caps/swaptions) + /*! An additional constraint can be passed which must be + satisfied in addition to the constraints of the model. + */ + public void calibrate(List instruments, + OptimizationMethod method, + EndCriteria endCriteria, + Constraint additionalConstraint = null, + List weights = null, + List fixParameters = null) + { + if (weights == null) + weights = new List(); + if (additionalConstraint == null) + additionalConstraint = new Constraint(); + Utils.QL_REQUIRE(weights.empty() || weights.Count == instruments.Count, () => + "mismatch between number of instruments (" + + instruments.Count + ") and weights(" + + weights.Count + ")"); + + Constraint c; + if (additionalConstraint.empty()) + c = constraint_; + else + c = new CompositeConstraint(constraint_, additionalConstraint); + List w = weights.Count == 0 ? new InitializedList(instruments.Count, 1.0) : weights; + + Vector prms = parameters(); + List all = new InitializedList(prms.size(), false); + Projection proj = new Projection(prms, fixParameters ?? all); + CalibrationFunction f = new CalibrationFunction(this, instruments, w, proj); + ProjectedConstraint pc = new ProjectedConstraint(c, proj); + Problem prob = new Problem(f, pc, proj.project(prms)); + shortRateEndCriteria_ = method.minimize(prob, endCriteria); + Vector result = new Vector(prob.currentValue()); + setParams(proj.include(result)); + Vector shortRateProblemValues_ = prob.values(result); + + notifyObservers(); + } + + public double value(Vector parameters, List instruments) + { + List w = new InitializedList(instruments.Count, 1.0); + Projection p = new Projection(parameters); + CalibrationFunction f = new CalibrationFunction(this, instruments, w, p); + return f.value(parameters); + } + + //! Returns array of arguments on which calibration is done + public Vector parameters() + { + int size = 0, i; + for (i = 0; i < arguments_.Count; i++) + size += arguments_[i].size(); + Vector p = new Vector(size); + int k = 0; + for (i = 0; i < arguments_.Count; i++) + { + for (int j = 0; j < arguments_[i].size(); j++, k++) + { + p[k] = arguments_[i].parameters()[j]; + } + } + return p; + } + + public virtual void setParams(Vector parameters) + { + int p = 0; + for (int i = 0; i < arguments_.Count; ++i) + { + for (int j = 0; j < arguments_[i].size(); ++j) + { + Utils.QL_REQUIRE(p != parameters.Count, () => "parameter array too small"); + arguments_[i].setParam(j, parameters[p++]); + } + } + + Utils.QL_REQUIRE(p == parameters.Count, () => "parameter array too big!"); + update(); + } + + protected virtual void generateArguments() {} + + + //! Constraint imposed on arguments + private class PrivateConstraint : Constraint + { + public PrivateConstraint(List arguments) : base(new Impl(arguments)) { } + + private class Impl : IConstraint + { + private List arguments_; + + public Impl(List arguments) + { + arguments_ = arguments; + } + + public bool test(Vector p) + { + int k = 0; + for (int i = 0; i < arguments_.Count; i++) + { + int size = arguments_[i].size(); + Vector testParams = new Vector(size); + for (int j = 0; j < size; j++, k++) + testParams[j] = p[k]; + if (!arguments_[i].testParams(testParams)) + return false; + } + return true; + } + + public Vector upperBound(Vector parameters) + { + int k = 0, k2 = 0; + int totalSize = 0; + for (int i = 0; i < arguments_.Count; i++) + { + totalSize += arguments_[i].size(); + } + + Vector result = new Vector(totalSize); + for (int i = 0; i < arguments_.Count; i++) + { + int size = arguments_[i].size(); + Vector partialParams = new Vector(size); + for (int j = 0; j < size; j++, k++) + partialParams[j] = parameters[k]; + Vector tmpBound = arguments_[i].constraint().upperBound(partialParams); + for (int j = 0; j < size; j++, k2++) + result[k2] = tmpBound[j]; + } + return result; + } + + public Vector lowerBound(Vector parameters) + { + int k = 0, k2 = 0; + int totalSize = 0; + for (int i = 0; i < arguments_.Count; i++) + { + totalSize += arguments_[i].size(); + } + Vector result = new Vector(totalSize); + for (int i = 0; i < arguments_.Count; i++) + { + int size = arguments_[i].size(); + Vector partialParams = new Vector(size); + for (int j = 0; j < size; j++, k++) + partialParams[j] = parameters[k]; + Vector tmpBound = arguments_[i].constraint().lowerBound(partialParams); + for (int j = 0; j < size; j++, k2++) + result[k2] = tmpBound[j]; + } + return result; + } + } + } + + //! Calibration cost function class + private class CalibrationFunction : CostFunction + { + public CalibrationFunction(CalibratedModel model, + List instruments, + List weights, + Projection projection) + { + // recheck + model_ = model; + instruments_ = instruments; + weights_ = weights; + projection_ = projection; + } + + public override double value(Vector p) + { + model_.setParams(projection_.include(p)); + + double value = 0.0; + for (int i = 0; i < instruments_.Count; i++) + { + double diff = instruments_[i].calibrationError(); + value += diff * diff * weights_[i]; + } + + return Math.Sqrt(value); + } + + public override Vector values(Vector p) + { + model_.setParams(projection_.include(p)); + + Vector values = new Vector(instruments_.Count); + for (int i = 0; i < instruments_.Count; i++) + { + values[i] = instruments_[i].calibrationError() * Math.Sqrt(weights_[i]); + } + return values; + } + + public override double finiteDifferenceEpsilon() { return 1e-6; } + + private CalibratedModel model_; + private List instruments_; + private List weights_; + private Projection projection_; + + } + + + #region Observer & Observable + private readonly WeakEventSource eventSource = new WeakEventSource(); + public event Callback notifyObserversEvent + { + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } + } + + public void registerWith(Callback handler) { notifyObserversEvent += handler; } + public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } + public void notifyObservers() + { + eventSource.Raise(); + } + + public void update() + { + generateArguments(); + notifyObservers(); + } + #endregion + } + + //! Abstract short-rate model class + /*! \ingroup shortrate */ + public abstract class ShortRateModel : CalibratedModel + { + protected ShortRateModel(int nArguments) : base(nArguments) { } + + public abstract Lattice tree(TimeGrid t); + } +} diff --git a/src/QLNet/Models/Parameter.cs b/src/QLNet/Models/Parameter.cs index 3e8318361..33a60da3e 100644 --- a/src/QLNet/Models/Parameter.cs +++ b/src/QLNet/Models/Parameter.cs @@ -2,18 +2,18 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -39,24 +39,24 @@ public Parameter() constraint_ = new NoConstraint(); } - protected Parameter( int size, Impl impl, Constraint constraint ) + protected Parameter(int size, Impl impl, Constraint constraint) { impl_ = impl; - params_ = new Vector( size ); + params_ = new Vector(size); constraint_ = constraint; } - public void setParam( int i, double x ) { params_[i] = x; } - public bool testParams( Vector p ) { return constraint_.test( p ); } + public void setParam(int i, double x) { params_[i] = x; } + public bool testParams(Vector p) { return constraint_.test(p); } public int size() { return params_.size(); } - public double value( double t ) { return impl_.value( params_, t ); } + public double value(double t) { return impl_.value(params_, t); } public Constraint constraint() { return constraint_; } //! Base class for model parameter implementation public abstract class Impl { - public abstract double value( Vector p, double t ); + public abstract double value(Vector p, double t); } } @@ -65,22 +65,22 @@ public class ConstantParameter : Parameter { private new class Impl : Parameter.Impl { - public override double value( Vector parameters, double UnnamedParameter1 ) + public override double value(Vector parameters, double UnnamedParameter1) { return parameters[0]; } } - public ConstantParameter( Constraint constraint ) - : base( 1, new ConstantParameter.Impl(), constraint ) + public ConstantParameter(Constraint constraint) + : base(1, new ConstantParameter.Impl(), constraint) { } - public ConstantParameter( double value, Constraint constraint ) - : base( 1, new ConstantParameter.Impl(), constraint ) + public ConstantParameter(double value, Constraint constraint) + : base(1, new ConstantParameter.Impl(), constraint) { params_[0] = value; - Utils.QL_REQUIRE(testParams( params_ ) ,()=> ": invalid value" ); + Utils.QL_REQUIRE(testParams(params_), () => ": invalid value"); } } @@ -90,13 +90,13 @@ public class NullParameter : Parameter { private new class Impl : Parameter.Impl { - public override double value( Vector UnnamedParameter1, double UnnamedParameter2 ) + public override double value(Vector UnnamedParameter1, double UnnamedParameter2) { return 0.0; } } public NullParameter() - : base( 0, new NullParameter.Impl(), new NoConstraint() ) + : base(0, new NullParameter.Impl(), new NoConstraint()) { } } @@ -105,30 +105,30 @@ public NullParameter() // ! \f$ a(t) = a_i if t_{i-1} \geq t < t_i \f$. // This kind of parameter is usually used to enhance the fitting of a // model - // + // public class PiecewiseConstantParameter : Parameter { private new class Impl : Parameter.Impl { - public Impl( List times ) + public Impl(List times) { times_ = times; } - public override double value( Vector parameters, double t ) + public override double value(Vector parameters, double t) { int size = times_.Count; - for ( int i = 0; i < size; i++ ) + for (int i = 0; i < size; i++) { - if ( t < times_[i] ) + if (t < times_[i]) return parameters[i]; } return parameters[size]; } private List times_; } - public PiecewiseConstantParameter( List times, Constraint constraint = null) - : base( times.Count + 1, new PiecewiseConstantParameter.Impl( times ), constraint ?? new NoConstraint() ) + public PiecewiseConstantParameter(List times, Constraint constraint = null) + : base(times.Count + 1, new PiecewiseConstantParameter.Impl(times), constraint ?? new NoConstraint()) { } } @@ -142,20 +142,20 @@ public class NumericalImpl : Parameter.Impl private List values_; private Handle termStructure_; - public NumericalImpl( Handle termStructure ) + public NumericalImpl(Handle termStructure) { times_ = new List(); values_ = new List(); termStructure_ = termStructure; } - public void setvalue( double t, double x ) + public void setvalue(double t, double x) { - times_.Add( t ); - values_.Add( x ); + times_.Add(t); + values_.Add(x); } - public void change( double x ) + public void change(double x) { values_[values_.Count - 1] = x; } @@ -165,10 +165,10 @@ public void reset() times_.Clear(); values_.Clear(); } - public override double value( Vector UnnamedParameter1, double t ) + public override double value(Vector UnnamedParameter1, double t) { - int nIndex = times_.FindIndex( val => val.IsEqual(t) ); - Utils.QL_REQUIRE( nIndex != -1,()=> "fitting parameter not set!" ); + int nIndex = times_.FindIndex(val => val.IsEqual(t)); + Utils.QL_REQUIRE(nIndex != -1, () => "fitting parameter not set!"); return values_[nIndex]; } @@ -176,13 +176,13 @@ public override double value( Vector UnnamedParameter1, double t ) public Handle termStructure() { return termStructure_; } } - public TermStructureFittingParameter( Parameter.Impl impl ) - : base( 0, impl, new NoConstraint() ) + public TermStructureFittingParameter(Parameter.Impl impl) + : base(0, impl, new NoConstraint()) { } - public TermStructureFittingParameter( Handle term ) - : base( 0, new NumericalImpl( term ), new NoConstraint() ) + public TermStructureFittingParameter(Handle term) + : base(0, new NumericalImpl(term), new NoConstraint()) { } } diff --git a/src/QLNet/Models/Shortrate/OneFactorModel.cs b/src/QLNet/Models/Shortrate/OneFactorModel.cs index c50f65a0f..18508992c 100644 --- a/src/QLNet/Models/Shortrate/OneFactorModel.cs +++ b/src/QLNet/Models/Shortrate/OneFactorModel.cs @@ -6,13 +6,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -72,8 +72,8 @@ protected override ShortRateTree impl() //! Plain tree build-up from short-rate dynamics public ShortRateTree(TrinomialTree tree, - ShortRateDynamics dynamics, - TimeGrid timeGrid) + ShortRateDynamics dynamics, + TimeGrid timeGrid) : base(timeGrid, tree.size(1)) { tree_ = tree; @@ -81,8 +81,8 @@ public ShortRateTree(TrinomialTree tree, } //! Tree build-up + numerical fitting to term-structure - public ShortRateTree(TrinomialTree tree,ShortRateDynamics dynamics,TermStructureFittingParameter.NumericalImpl theta, - TimeGrid timeGrid) + public ShortRateTree(TrinomialTree tree, ShortRateDynamics dynamics, TermStructureFittingParameter.NumericalImpl theta, + TimeGrid timeGrid) : base(timeGrid, tree.size(1)) { tree_ = tree; @@ -142,9 +142,9 @@ public class Helper : ISolver1d private ShortRateTree tree_; public Helper(int i, - double discountBondPrice, - TermStructureFittingParameter.NumericalImpl theta, - ShortRateTree tree) + double discountBondPrice, + TermStructureFittingParameter.NumericalImpl theta, + ShortRateTree tree) { size_ = tree.size(i); i_ = i; @@ -175,8 +175,8 @@ protected OneFactorAffineModel(int nArguments) {} public virtual double discountBond(double now, - double maturity, - Vector factors) + double maturity, + Vector factors) { return discountBond(now, maturity, factors[0]); } @@ -194,9 +194,9 @@ public double discount(double t) } public virtual double discountBondOption(Option.Type type, - double strike, - double maturity, - double bondMaturity) + double strike, + double maturity, + double bondMaturity) { throw new NotImplementedException(); } diff --git a/src/QLNet/Models/Shortrate/Onefactormodels/BlackKarasinski.cs b/src/QLNet/Models/Shortrate/Onefactormodels/BlackKarasinski.cs new file mode 100644 index 000000000..11307dce9 --- /dev/null +++ b/src/QLNet/Models/Shortrate/Onefactormodels/BlackKarasinski.cs @@ -0,0 +1,155 @@ +/* + Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + + public class BlackKarasinski : OneFactorModel, + ITermStructureConsistentModel + { + private double a() { return a_.value(0.0); } + private double sigma() { return sigma_.value(0.0); } + + Parameter a_; + Parameter sigma_; + + public BlackKarasinski(Handle termStructure, + double a, double sigma) + : base(2) + { + a_ = arguments_[0]; + sigma_ = arguments_[1]; + a_ = arguments_[0] = new ConstantParameter(a, new PositiveConstraint()); + sigma_ = arguments_[1] = new ConstantParameter(sigma, new PositiveConstraint()); + termStructure_ = new Handle(); + termStructure_ = termStructure; + termStructure.registerWith(update); + } + + public BlackKarasinski(Handle termStructure) + : this(termStructure, 0.1, 0.1) + { } + + public override Lattice tree(TimeGrid grid) + { + TermStructureFittingParameter phi = new TermStructureFittingParameter(termStructure()); + + ShortRateDynamics numericDynamics = + new Dynamics(phi, a(), sigma()); + + TrinomialTree trinomial = + new TrinomialTree(numericDynamics.process(), grid); + ShortRateTree numericTree = + new ShortRateTree(trinomial, numericDynamics, grid); + + TermStructureFittingParameter.NumericalImpl impl = + (TermStructureFittingParameter.NumericalImpl)phi.implementation(); + impl.reset(); + double value = 1.0; + double vMin = -50.0; + double vMax = 50.0; + for (int i = 0; i < (grid.size() - 1); i++) + { + double discountBond = termStructure().link.discount(grid[i + 1]); + double xMin = trinomial.underlying(i, 0); + double dx = trinomial.dx(i); + Helper finder = new Helper(i, xMin, dx, discountBond, numericTree); + Brent s1d = new Brent(); + s1d.setMaxEvaluations(1000); + value = s1d.solve(finder, 1e-7, value, vMin, vMax); + impl.setvalue(grid[i], value); + } + return numericTree; + } + + public override ShortRateDynamics dynamics() + { + throw new NotImplementedException("no defined process for Black-Karasinski"); + } + + #region ITermStructureConsistentModel + public Handle termStructure() + { + return termStructure_; + } + + public Handle termStructure_ { get; set; } + + #endregion + } + + //! Short-rate dynamics in the Black-Karasinski model + public class Dynamics : OneFactorModel.ShortRateDynamics + { + + public Dynamics(Parameter fitting, double alpha, double sigma) + : base((StochasticProcess1D)(new OrnsteinUhlenbeckProcess(alpha, sigma))) + { + fitting_ = fitting; + } + + public override double variable(double t, double r) + { + return Math.Log(r) - fitting_.value(t); + } + + public override double shortRate(double t, double x) + { + return Math.Exp(x + fitting_.value(t)); + } + + private Parameter fitting_; + } + + // Private function used by solver to determine time-dependent parameter + public class Helper : ISolver1d + { + private int size_; + private double dt_; + private double xMin_, dx_; + private Vector statePrices_; + private double discountBondPrice_; + + public Helper(int i, double xMin, double dx, + double discountBondPrice, + OneFactorModel.ShortRateTree tree) + { + size_ = tree.size(i); + dt_ = tree.timeGrid().dt(i); + xMin_ = xMin; + dx_ = dx; + statePrices_ = tree.statePrices(i); + discountBondPrice_ = discountBondPrice; + } + + public override double value(double theta) + { + double value = discountBondPrice_; + double x = xMin_; + for (int j = 0; j < size_; j++) + { + double discount = Math.Exp(-Math.Exp(theta + x) * dt_); + value -= statePrices_[j] * discount; + x += dx_; + } + return value; + } + } +} diff --git a/src/QLNet/Models/Shortrate/Onefactormodels/coxingersollross.cs b/src/QLNet/Models/Shortrate/Onefactormodels/CoxIngersollRoss.cs similarity index 91% rename from src/QLNet/Models/Shortrate/Onefactormodels/coxingersollross.cs rename to src/QLNet/Models/Shortrate/Onefactormodels/CoxIngersollRoss.cs index e2276682d..0e9376dc5 100644 --- a/src/QLNet/Models/Shortrate/Onefactormodels/coxingersollross.cs +++ b/src/QLNet/Models/Shortrate/Onefactormodels/CoxIngersollRoss.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -36,9 +36,9 @@ public class CoxIngersollRoss : OneFactorAffineModel private Parameter r0_; public CoxIngersollRoss(double r0 = 0.05, - double theta = 0.1, - double k = 0.1, - double sigma = 0.1) + double theta = 0.1, + double k = 0.1, + double sigma = 0.1) : base(4) { theta_ = arguments_[0]; @@ -48,9 +48,9 @@ public CoxIngersollRoss(double r0 = 0.05, } public override double discountBondOption(Option.Type type, - double strike, - double maturity, - double bondMaturity) + double strike, + double maturity, + double bondMaturity) { Utils.QL_REQUIRE(strike > 0.0, () => "strike must be positive"); double discountT = discountBond(0.0, maturity, x0()); @@ -181,9 +181,9 @@ public override double diffusion(double d1, double d2) public class Dynamics : ShortRateDynamics { public Dynamics(double theta, - double k, - double sigma, - double x0) + double k, + double sigma, + double x0) : base(new HelperProcess(theta, k, sigma, Math.Sqrt(x0))) { } diff --git a/src/QLNet/Models/Shortrate/Onefactormodels/hullwhite.cs b/src/QLNet/Models/Shortrate/Onefactormodels/HullWhite.cs similarity index 92% rename from src/QLNet/Models/Shortrate/Onefactormodels/hullwhite.cs rename to src/QLNet/Models/Shortrate/Onefactormodels/HullWhite.cs index f5a6974b2..06759e661 100644 --- a/src/QLNet/Models/Shortrate/Onefactormodels/hullwhite.cs +++ b/src/QLNet/Models/Shortrate/Onefactormodels/HullWhite.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -34,9 +34,9 @@ namespace QLNet public class HullWhite : Vasicek, ITermStructureConsistentModel { public HullWhite(Handle termStructure, - double a, double sigma) + double a, double sigma) : base(termStructure.link.forwardRate(0.0, 0.0, Compounding.Continuous, Frequency.NoFrequency).rate(), - a, 0.0, sigma, 0.0) + a, 0.0, sigma, 0.0) { this.termStructure_ = termStructure; b_ = arguments_[1] = new NullParameter(); //to change @@ -46,7 +46,7 @@ public HullWhite(Handle termStructure, } public HullWhite(Handle termStructure, - double a) + double a) : this(termStructure, a, 0.01) { } @@ -89,9 +89,9 @@ public override ShortRateDynamics dynamics() } public override double discountBondOption(Option.Type type, - double strike, - double maturity, - double bondMaturity) + double strike, + double maturity, + double bondMaturity) { double _a = a(); double v; @@ -119,10 +119,10 @@ public override double discountBondOption(Option.Type type, deposit day counter, F_quoted is futures' market price. */ public static double convexityBias(double futuresPrice, - double t, - double T, - double sigma, - double a) + double t, + double T, + double sigma, + double a) { Utils.QL_REQUIRE(futuresPrice >= 0.0, () => "negative futures price (" + futuresPrice + ") not allowed"); Utils.QL_REQUIRE(t >= 0.0, () => "negative t (" + t + ") not allowed"); @@ -205,7 +205,7 @@ public class FittingParameter : TermStructureFittingParameter private double a_, sigma_; public Impl(Handle termStructure, - double a, double sigma) + double a, double sigma) { termStructure_ = termStructure; a_ = a; @@ -222,7 +222,7 @@ public override double value(Vector v, double t) } public FittingParameter(Handle termStructure, - double a, double sigma) + double a, double sigma) : base(new FittingParameter.Impl(termStructure, a, sigma)) { } } diff --git a/src/QLNet/Models/Shortrate/Onefactormodels/vasicek.cs b/src/QLNet/Models/Shortrate/Onefactormodels/Vasicek.cs similarity index 96% rename from src/QLNet/Models/Shortrate/Onefactormodels/vasicek.cs rename to src/QLNet/Models/Shortrate/Onefactormodels/Vasicek.cs index 5474f86e9..d83b922af 100644 --- a/src/QLNet/Models/Shortrate/Onefactormodels/vasicek.cs +++ b/src/QLNet/Models/Shortrate/Onefactormodels/Vasicek.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -41,7 +41,7 @@ public Vasicek(double r0, double a, double b = 0.05, double sigma = 0.01, double } public override double discountBondOption(Option.Type type, double strike, double maturity, - double bondMaturity) + double bondMaturity) { double v; double _a = a(); diff --git a/src/QLNet/Models/Shortrate/Onefactormodels/blackkarasinski.cs b/src/QLNet/Models/Shortrate/Onefactormodels/blackkarasinski.cs deleted file mode 100644 index 08fe7415a..000000000 --- a/src/QLNet/Models/Shortrate/Onefactormodels/blackkarasinski.cs +++ /dev/null @@ -1,147 +0,0 @@ -/* - Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet -{ - - public class BlackKarasinski : OneFactorModel, - ITermStructureConsistentModel - { - private double a() { return a_.value(0.0); } - private double sigma() { return sigma_.value(0.0); } - - Parameter a_; - Parameter sigma_; - - public BlackKarasinski( Handle termStructure, - double a, double sigma ) - : base(2) - { - a_=arguments_[0]; - sigma_=arguments_[1]; - a_ = arguments_[0] = new ConstantParameter(a, new PositiveConstraint()); - sigma_ = arguments_[1] = new ConstantParameter(sigma, new PositiveConstraint()); - termStructure_ = new Handle(); - termStructure_ = termStructure; - termStructure.registerWith(update); - } - - public BlackKarasinski(Handle termStructure) - : this(termStructure, 0.1, 0.1) - { } - - public override Lattice tree( TimeGrid grid) - { - TermStructureFittingParameter phi= new TermStructureFittingParameter(termStructure()); - - ShortRateDynamics numericDynamics= - new Dynamics(phi, a(), sigma()); - - TrinomialTree trinomial= - new TrinomialTree(numericDynamics.process(), grid); - ShortRateTree numericTree = - new ShortRateTree(trinomial, numericDynamics, grid); - - TermStructureFittingParameter.NumericalImpl impl = - (TermStructureFittingParameter.NumericalImpl)phi.implementation(); - impl.reset(); - double value = 1.0; - double vMin = -50.0; - double vMax = 50.0; - for (int i=0; i<(grid.size() - 1); i++) { - double discountBond = termStructure().link.discount(grid[i+1]); - double xMin = trinomial.underlying(i, 0); - double dx = trinomial.dx(i); - Helper finder = new Helper(i, xMin, dx, discountBond, numericTree); - Brent s1d = new Brent(); - s1d.setMaxEvaluations(1000); - value = s1d.solve(finder, 1e-7, value, vMin, vMax); - impl.setvalue(grid[i], value); - } - return numericTree; - } - - public override ShortRateDynamics dynamics() { - throw new NotImplementedException("no defined process for Black-Karasinski"); - } - - #region ITermStructureConsistentModel - public Handle termStructure(){ - return termStructure_; - } - - public Handle termStructure_ { get; set; } - - #endregion - } - - //! Short-rate dynamics in the Black-Karasinski model - public class Dynamics : OneFactorModel.ShortRateDynamics - { - - public Dynamics(Parameter fitting, double alpha, double sigma) - : base((StochasticProcess1D)(new OrnsteinUhlenbeckProcess(alpha, sigma))){ - fitting_=fitting; } - - public override double variable(double t, double r) - { - return Math.Log(r) - fitting_.value(t); - } - - public override double shortRate(double t, double x) - { - return Math.Exp(x + fitting_.value(t)); - } - - private Parameter fitting_; - } - - // Private function used by solver to determine time-dependent parameter - public class Helper : ISolver1d - { - private int size_; - private double dt_; - private double xMin_, dx_; - private Vector statePrices_; - private double discountBondPrice_; - - public Helper(int i, double xMin, double dx, - double discountBondPrice, - OneFactorModel.ShortRateTree tree){ - size_=tree.size(i); - dt_=tree.timeGrid().dt(i); - xMin_=xMin; - dx_=dx; - statePrices_=tree.statePrices(i); - discountBondPrice_=discountBondPrice; - } - - public override double value(double theta){ - double value = discountBondPrice_; - double x = xMin_; - for (int j=0; j. - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -34,7 +34,7 @@ public override Lattice tree(TimeGrid grid) ShortRateDynamics dyn = dynamics(); TrinomialTree tree1 = new TrinomialTree(dyn.xProcess(), grid); TrinomialTree tree2 = new TrinomialTree(dyn.yProcess(), grid); - return (Lattice) (new ShortRateTree(tree1, tree2, dyn)); + return (Lattice)(new ShortRateTree(tree1, tree2, dyn)); } //! Class describing the dynamics of the two state variables @@ -48,8 +48,8 @@ public abstract class ShortRateDynamics public double correlation_ { get; set; } protected ShortRateDynamics(StochasticProcess1D xProcess, - StochasticProcess1D yProcess, - double correlation) + StochasticProcess1D yProcess, + double correlation) { xProcess_ = xProcess; yProcess_ = yProcess; @@ -92,8 +92,8 @@ protected override ShortRateTree impl() //! Plain tree build-up from short-rate dynamics public ShortRateTree(TrinomialTree tree1, - TrinomialTree tree2, - ShortRateDynamics dynamics) + TrinomialTree tree2, + ShortRateDynamics dynamics) : base(tree1, tree2, dynamics.correlation()) { dynamics_ = dynamics; diff --git a/src/QLNet/Models/Shortrate/Twofactorsmodels/G2.cs b/src/QLNet/Models/Shortrate/Twofactorsmodels/G2.cs new file mode 100644 index 000000000..f44368581 --- /dev/null +++ b/src/QLNet/Models/Shortrate/Twofactorsmodels/G2.cs @@ -0,0 +1,463 @@ +/* + Copyright (C) 2010 Philippe double (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +// Two-factor additive Gaussian Model G2 + + + +namespace QLNet +{ + + //! Two-additive-factor gaussian model class. + /*! This class implements a two-additive-factor model defined by + \f[ + dr_t = \varphi(t) + x_t + y_t + \f] + where \f$ x_t \f$ and \f$ y_t \f$ are defined by + \f[ + dx_t = -a x_t dt + \sigma dW^1_t, x_0 = 0 + \f] + \f[ + dy_t = -b y_t dt + \sigma dW^2_t, y_0 = 0 + \f] + and \f$ dW^1_t dW^2_t = \rho dt \f$. + + \bug This class was not tested enough to guarantee + its functionality. + + \ingroup shortrate + */ + public class G2 : TwoFactorModel, + IAffineModel, + ITermStructureConsistentModel + { + + + #region ITermStructureConsistentModel + public Handle termStructure() + { + return termStructure_; + } + + public Handle termStructure_ { get; set; } + #endregion + + Parameter a_; + Parameter sigma_; + Parameter b_; + Parameter eta_; + Parameter rho_; + Parameter phi_; + + public G2(Handle termStructure, + double a, + double sigma, + double b, + double eta, + double rho) + : base(5) + { + termStructure_ = termStructure; + a_ = arguments_[0] = new ConstantParameter(a, new PositiveConstraint()); + sigma_ = arguments_[1] = new ConstantParameter(sigma, new PositiveConstraint()); + b_ = arguments_[2] = new ConstantParameter(b, new PositiveConstraint()); + eta_ = arguments_[3] = new ConstantParameter(eta, new PositiveConstraint()); + rho_ = arguments_[4] = new ConstantParameter(rho, new BoundaryConstraint(-1.0, 1.0)); + + generateArguments(); + termStructure.registerWith(update); + } + + public G2(Handle termStructure, + double a, + double sigma, + double b, + double eta) + : this(termStructure, a, sigma, b, eta, -0.75) + { } + + public G2(Handle termStructure, + double a, + double sigma, + double b) + : this(termStructure, a, sigma, b, 0.01, -0.75) + { } + + + public G2(Handle termStructure, + double a, + double sigma) + : this(termStructure, a, sigma, 0.1, 0.01, -0.75) + { } + + public G2(Handle termStructure, + double a) + : this(termStructure, a, 0.01, 0.1, 0.01, -0.75) + { } + + public G2(Handle termStructure) + : this(termStructure, 0.1, 0.01, 0.1, 0.01, -0.75) + { } + + public override ShortRateDynamics dynamics() + { + return new Dynamics(phi_, a(), sigma(), b(), eta(), rho()); + } + + public virtual double discountBond(double now, + double maturity, + Vector factors) + { + Utils.QL_REQUIRE(factors.size() > 1, () => "g2 model needs two factors to compute discount bond"); + return discountBond(now, maturity, factors[0], factors[1]); + } + + public virtual double discountBond(double t, double T, double x, double y) + { + return A(t, T) * Math.Exp(-B(a(), (T - t)) * x - B(b(), (T - t)) * y); + } + + + public virtual double discountBondOption(Option.Type type, + double strike, + double maturity, + double bondMaturity) + { + double v = sigmaP(maturity, bondMaturity); + double f = termStructure().link.discount(bondMaturity); + double k = termStructure().link.discount(maturity) * strike; + + return Utils.blackFormula(type, k, f, v); + } + + public double discount(double t) + { + return termStructure().currentLink().discount(t); + } + + public double swaption(Swaption.Arguments arguments, + double fixedRate, + double range, + int intervals) + { + + Date settlement = termStructure().link.referenceDate(); + DayCounter dayCounter = termStructure().link.dayCounter(); + double start = dayCounter.yearFraction(settlement, + arguments.floatingResetDates[0]); + double w = (arguments.type == VanillaSwap.Type.Payer ? 1 : -1); + + List fixedPayTimes = new InitializedList(arguments.fixedPayDates.Count); + for (int i = 0; i < fixedPayTimes.Count; ++i) + fixedPayTimes[i] = + dayCounter.yearFraction(settlement, + arguments.fixedPayDates[i]); + + SwaptionPricingFunction function = new SwaptionPricingFunction(a(), + sigma(), b(), eta(), rho(), + w, start, + fixedPayTimes, + fixedRate, this); + + double upper = function.mux() + range * function.sigmax(); + double lower = function.mux() - range * function.sigmax(); + SegmentIntegral integrator = new SegmentIntegral(intervals); + return arguments.nominal * w * termStructure().link.discount(start) * + integrator.value(function.value, lower, upper); + } + + #region protected + protected override void generateArguments() + { + phi_ = new FittingParameter(termStructure(), + a(), sigma(), b(), eta(), rho()); + } + + protected double A(double t, double T) + { + return termStructure().link.discount(T) / termStructure().link.discount(t) * + Math.Exp(0.5 * (V(T - t) - V(T) + V(t))); + } + + protected double B(double x, double t) + { + return (1.0 - Math.Exp(-x * t)) / x; + } + #endregion + + #region private + double sigmaP(double t, double s) + { + double temp = 1.0 - Math.Exp(-(a() + b()) * t); + double temp1 = 1.0 - Math.Exp(-a() * (s - t)); + double temp2 = 1.0 - Math.Exp(-b() * (s - t)); + double a3 = a() * a() * a(); + double b3 = b() * b() * b(); + double sigma2 = sigma() * sigma(); + double eta2 = eta() * eta(); + double value = + 0.5 * sigma2 * temp1 * temp1 * (1.0 - Math.Exp(-2.0 * a() * t)) / a3 + + 0.5 * eta2 * temp2 * temp2 * (1.0 - Math.Exp(-2.0 * b() * t)) / b3 + + 2.0 * rho() * sigma() * eta() / (a() * b() * (a() + b())) * + temp1 * temp2 * temp; + return Math.Sqrt(value); + } + + + double V(double t) + { + double expat = Math.Exp(-a() * t); + double expbt = Math.Exp(-b() * t); + double cx = sigma() / a(); + double cy = eta() / b(); + double valuex = cx * cx * (t + (2.0 * expat - 0.5 * expat * expat - 1.5) / a()); + double valuey = cy * cy * (t + (2.0 * expbt - 0.5 * expbt * expbt - 1.5) / b()); + double value = 2.0 * rho() * cx * cy * (t + (expat - 1.0) / a() + + (expbt - 1.0) / b() + - (expat * expbt - 1.0) / (a() + b())); + return valuex + valuey + value; + } + + double a() { return a_.value(0.0); } + double sigma() { return sigma_.value(0.0); } + double b() { return b_.value(0.0); } + double eta() { return eta_.value(0.0); } + double rho() { return rho_.value(0.0); } + + #endregion + + public class Dynamics : ShortRateDynamics + { + + Parameter fitting_; + public Dynamics(Parameter fitting, + double a, + double sigma, + double b, + double eta, + double rho) + : base((StochasticProcess1D)new OrnsteinUhlenbeckProcess(a, sigma), + (StochasticProcess1D)(new OrnsteinUhlenbeckProcess(b, eta)), rho) + { + fitting_ = fitting; + } + + public override double shortRate(double t, double x, double y) + { + return fitting_.value(t) + x + y; + } + + public override StochasticProcess process() + { + throw new NotImplementedException(); + } + + //! Analytical term-structure fitting parameter \f$ \varphi(t) \f$. + /*! \f$ \varphi(t) \f$ is analytically defined by + \f[ + \varphi(t) = f(t) + + \frac{1}{2}(\frac{\sigma(1-e^{-at})}{a})^2 + + \frac{1}{2}(\frac{\eta(1-e^{-bt})}{b})^2 + + \rho\frac{\sigma(1-e^{-at})}{a}\frac{\eta(1-e^{-bt})}{b}, + \f] + where \f$ f(t) \f$ is the instantaneous forward rate at \f$ t \f$. + */ + } + + public class FittingParameter : TermStructureFittingParameter + { + + private new class Impl : Parameter.Impl + { + + + public Impl(Handle termStructure, + double a, + double sigma, + double b, + double eta, + double rho) + { + termStructure_ = termStructure; + a_ = a; + sigma_ = sigma; + b_ = b; + eta_ = eta; + rho_ = rho; + } + + public override double value(Vector v, double t) + { + InterestRate forward = termStructure_.currentLink().forwardRate(t, t, + Compounding.Continuous, + Frequency.NoFrequency); + double temp1 = sigma_ * (1.0 - Math.Exp(-a_ * t)) / a_; + double temp2 = eta_ * (1.0 - Math.Exp(-b_ * t)) / b_; + double value = 0.5 * temp1 * temp1 + 0.5 * temp2 * temp2 + + rho_ * temp1 * temp2 + forward.value(); + return value; + } + Handle termStructure_; + double a_, sigma_, b_, eta_, rho_; + } + + public FittingParameter(Handle termStructure, + double a, + double sigma, + double b, + double eta, + double rho) + : base((Parameter.Impl)( + new FittingParameter.Impl(termStructure, a, sigma, + b, eta, rho))) { } + } + + public class SwaptionPricingFunction + { + + #region private fields + double a_, sigma_, b_, eta_, rho_, w_; + double T_; + List t_; + double rate_; + int size_; + Vector A_, Ba_, Bb_; + double mux_, muy_, sigmax_, sigmay_, rhoxy_; + #endregion + + public SwaptionPricingFunction(double a, double sigma, + double b, double eta, double rho, + double w, double start, + List payTimes, + double fixedRate, G2 model) + { + a_ = a; + sigma_ = sigma; + b_ = b; + eta_ = eta; + rho_ = rho; + w_ = w; + T_ = start; + t_ = payTimes; + rate_ = fixedRate; + size_ = t_.Count; + + A_ = new Vector(size_); + Ba_ = new Vector(size_); + Bb_ = new Vector(size_); + + + sigmax_ = sigma_ * Math.Sqrt(0.5 * (1.0 - Math.Exp(-2.0 * a_ * T_)) / a_); + sigmay_ = eta_ * Math.Sqrt(0.5 * (1.0 - Math.Exp(-2.0 * b_ * T_)) / b_); + rhoxy_ = rho_ * eta_ * sigma_ * (1.0 - Math.Exp(-(a_ + b_) * T_)) / + ((a_ + b_) * sigmax_ * sigmay_); + + double temp = sigma_ * sigma_ / (a_ * a_); + mux_ = -((temp + rho_ * sigma_ * eta_ / (a_ * b_)) * (1.0 - Math.Exp(-a * T_)) - + 0.5 * temp * (1.0 - Math.Exp(-2.0 * a_ * T_)) - + rho_ * sigma_ * eta_ / (b_ * (a_ + b_)) * + (1.0 - Math.Exp(-(b_ + a_) * T_))); + + temp = eta_ * eta_ / (b_ * b_); + muy_ = -((temp + rho_ * sigma_ * eta_ / (a_ * b_)) * (1.0 - Math.Exp(-b * T_)) - + 0.5 * temp * (1.0 - Math.Exp(-2.0 * b_ * T_)) - + rho_ * sigma_ * eta_ / (a_ * (a_ + b_)) * + (1.0 - Math.Exp(-(b_ + a_) * T_))); + + for (int i = 0; i < size_; i++) + { + A_[i] = model.A(T_, t_[i]); + Ba_[i] = model.B(a_, t_[i] - T_); + Bb_[i] = model.B(b_, t_[i] - T_); + } + } + + internal double mux() { return mux_; } + + internal double sigmax() { return sigmax_; } + + public double value(double x) + { + CumulativeNormalDistribution phi = new CumulativeNormalDistribution(); + double temp = (x - mux_) / sigmax_; + double txy = Math.Sqrt(1.0 - rhoxy_ * rhoxy_); + + Vector lambda = new Vector(size_); + int i; + for (i = 0; i < size_; i++) + { + double tau = (i == 0 ? t_[0] - T_ : t_[i] - t_[i - 1]); + double c = (i == size_ - 1 ? (1.0 + rate_ * tau) : rate_ * tau); + lambda[i] = c * A_[i] * Math.Exp(-Ba_[i] * x); + } + + SolvingFunction function = new SolvingFunction(lambda, Bb_); + Brent s1d = new Brent(); + s1d.setMaxEvaluations(1000); + double yb = s1d.solve(function, 1e-6, 0.00, -100.0, 100.0); + + double h1 = (yb - muy_) / (sigmay_ * txy) - + rhoxy_ * (x - mux_) / (sigmax_ * txy); + double value = phi.value(-w_ * h1); + + + for (i = 0; i < size_; i++) + { + double h2 = h1 + + Bb_[i] * sigmay_ * Math.Sqrt(1.0 - rhoxy_ * rhoxy_); + double kappa = - Bb_[i] * + (muy_ - 0.5 * txy * txy * sigmay_ * sigmay_ * Bb_[i] + + rhoxy_ * sigmay_ * (x - mux_) / sigmax_); + value -= lambda[i] * Math.Exp(kappa) * phi.value(-w_ * h2); + } + + return Math.Exp(-0.5 * temp * temp) * value / + (sigmax_ * Math.Sqrt(2.0 * QLNet.Const.M_PI)); + } + + public class SolvingFunction : ISolver1d + { + + Vector lambda_; + Vector Bb_; + + public SolvingFunction(Vector lambda, Vector Bb) + { + lambda_ = lambda; + Bb_ = Bb; + } + + public override double value(double y) + { + double value = 1.0; + for (int i = 0; i < lambda_.size(); i++) + { + value -= lambda_[i] * Math.Exp(-Bb_[i] * y); + } + return value; + } + + } + + } + + } +} + + diff --git a/src/QLNet/Models/Shortrate/Twofactorsmodels/g2.cs b/src/QLNet/Models/Shortrate/Twofactorsmodels/g2.cs deleted file mode 100644 index 0158bf7d2..000000000 --- a/src/QLNet/Models/Shortrate/Twofactorsmodels/g2.cs +++ /dev/null @@ -1,456 +0,0 @@ -/* - Copyright (C) 2010 Philippe double (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -// Two-factor additive Gaussian Model G2 + + - -namespace QLNet -{ - - //! Two-additive-factor gaussian model class. - /*! This class implements a two-additive-factor model defined by - \f[ - dr_t = \varphi(t) + x_t + y_t - \f] - where \f$ x_t \f$ and \f$ y_t \f$ are defined by - \f[ - dx_t = -a x_t dt + \sigma dW^1_t, x_0 = 0 - \f] - \f[ - dy_t = -b y_t dt + \sigma dW^2_t, y_0 = 0 - \f] - and \f$ dW^1_t dW^2_t = \rho dt \f$. - - \bug This class was not tested enough to guarantee - its functionality. - - \ingroup shortrate - */ - public class G2 : TwoFactorModel, - IAffineModel, - ITermStructureConsistentModel - { - - - #region ITermStructureConsistentModel - public Handle termStructure() - { - return termStructure_; - } - - public Handle termStructure_ { get; set; } - #endregion - - Parameter a_; - Parameter sigma_; - Parameter b_; - Parameter eta_; - Parameter rho_; - Parameter phi_; - - public G2(Handle termStructure, - double a, - double sigma, - double b, - double eta, - double rho) - : base(5) - { - termStructure_ = termStructure; - a_ = arguments_[0] = new ConstantParameter(a, new PositiveConstraint()); - sigma_ = arguments_[1] = new ConstantParameter(sigma, new PositiveConstraint()); - b_ = arguments_[2] = new ConstantParameter(b, new PositiveConstraint()); - eta_ = arguments_[3] = new ConstantParameter(eta, new PositiveConstraint()); - rho_ = arguments_[4] = new ConstantParameter(rho, new BoundaryConstraint(-1.0, 1.0)); - - generateArguments(); - termStructure.registerWith(update); - } - - public G2(Handle termStructure, - double a, - double sigma, - double b, - double eta) - : this(termStructure, a, sigma, b, eta, -0.75) - { } - - public G2(Handle termStructure, - double a, - double sigma, - double b) - : this(termStructure, a, sigma, b, 0.01, -0.75) - { } - - - public G2(Handle termStructure, - double a, - double sigma) - : this(termStructure, a, sigma, 0.1, 0.01, -0.75) - { } - - public G2(Handle termStructure, - double a) - : this(termStructure, a, 0.01, 0.1, 0.01, -0.75) - { } - - public G2(Handle termStructure) - : this(termStructure, 0.1, 0.01, 0.1, 0.01, -0.75) - { } - - public override ShortRateDynamics dynamics() - { - return new Dynamics(phi_, a(), sigma(), b(), eta(), rho()); - } - - public virtual double discountBond(double now, - double maturity, - Vector factors) - { - Utils.QL_REQUIRE(factors.size() > 1,()=> "g2 model needs two factors to compute discount bond"); - return discountBond(now, maturity, factors[0], factors[1]); - } - - public virtual double discountBond(double t, double T, double x, double y) - { - return A(t, T) * Math.Exp(-B(a(), (T - t)) * x - B(b(), (T - t)) * y); - } - - - public virtual double discountBondOption(Option.Type type, - double strike, - double maturity, - double bondMaturity) - { - double v = sigmaP(maturity, bondMaturity); - double f = termStructure().link.discount(bondMaturity); - double k = termStructure().link.discount(maturity) * strike; - - return Utils.blackFormula(type, k, f, v); - } - - public double discount(double t) - { - return termStructure().currentLink().discount(t); - } - - public double swaption(Swaption.Arguments arguments, - double fixedRate, - double range, - int intervals){ - - Date settlement = termStructure().link.referenceDate(); - DayCounter dayCounter = termStructure().link.dayCounter(); - double start = dayCounter.yearFraction(settlement, - arguments.floatingResetDates[0]); - double w = (arguments.type==VanillaSwap.Type.Payer ? 1 : -1 ); - - List fixedPayTimes = new InitializedList(arguments.fixedPayDates.Count); - for (int i=0; i termStructure, - double a, - double sigma, - double b, - double eta, - double rho) - { - termStructure_ = termStructure; - a_ = a; - sigma_ = sigma; - b_ = b; - eta_ = eta; - rho_ = rho; - } - - public override double value(Vector v, double t) - { - InterestRate forward = termStructure_.currentLink().forwardRate(t, t, - Compounding.Continuous, - Frequency.NoFrequency); - double temp1 = sigma_ * (1.0 - Math.Exp(-a_ * t)) / a_; - double temp2 = eta_ * (1.0 - Math.Exp(-b_ * t)) / b_; - double value = 0.5 * temp1 * temp1 + 0.5 * temp2 * temp2 + - rho_ * temp1 * temp2 + forward.value(); - return value; - } - Handle termStructure_; - double a_, sigma_, b_, eta_, rho_; - } - - public FittingParameter(Handle termStructure, - double a, - double sigma, - double b, - double eta, - double rho) - : base((Parameter.Impl)( - new FittingParameter.Impl(termStructure, a, sigma, - b, eta, rho))) { } - } - - public class SwaptionPricingFunction { - - #region private fields - double a_, sigma_, b_, eta_, rho_, w_; - double T_; - List t_; - double rate_; - int size_; - Vector A_, Ba_, Bb_; - double mux_, muy_, sigmax_, sigmay_, rhoxy_; - #endregion - - public SwaptionPricingFunction(double a, double sigma, - double b, double eta, double rho, - double w, double start, - List payTimes, - double fixedRate, G2 model) - { - a_ = a; - sigma_ = sigma; - b_ = b; - eta_ = eta; - rho_ = rho; - w_ = w; - T_ = start; - t_ = payTimes; - rate_ = fixedRate; - size_ = t_.Count; - - A_ = new Vector(size_); - Ba_ = new Vector(size_); - Bb_ = new Vector(size_); - - - sigmax_ = sigma_*Math.Sqrt(0.5*(1.0-Math.Exp(-2.0*a_*T_))/a_); - sigmay_ = eta_*Math.Sqrt(0.5*(1.0-Math.Exp(-2.0*b_*T_))/b_); - rhoxy_ = rho_*eta_*sigma_*(1.0 - Math.Exp(-(a_+b_)*T_))/ - ((a_+b_)*sigmax_*sigmay_); - - double temp = sigma_*sigma_/(a_*a_); - mux_ = -((temp+rho_*sigma_*eta_/(a_*b_))*(1.0 - Math.Exp(-a*T_)) - - 0.5*temp*(1.0 - Math.Exp(-2.0*a_*T_)) - - rho_*sigma_*eta_/(b_*(a_+b_))* - (1.0- Math.Exp(-(b_+a_)*T_))); - - temp = eta_*eta_/(b_*b_); - muy_ = -((temp+rho_*sigma_*eta_/(a_*b_))*(1.0 - Math.Exp(-b*T_)) - - 0.5*temp*(1.0 - Math.Exp(-2.0*b_*T_)) - - rho_*sigma_*eta_/(a_*(a_+b_))* - (1.0- Math.Exp(-(b_+a_)*T_))); - - for (int i=0; i. + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System.Collections.Generic; + +namespace QLNet +{ + public class CapHelper : CalibrationHelper + { + public CapHelper(Period length, + Handle volatility, + IborIndex index, + // data for ATM swap-rate calculation + Frequency fixedLegFrequency, + DayCounter fixedLegDayCounter, + bool includeFirstSwaplet, + Handle termStructure, + CalibrationErrorType errorType = CalibrationErrorType.RelativePriceError) + : base(volatility, termStructure, errorType) + { + length_ = length; + index_ = index; + fixedLegFrequency_ = fixedLegFrequency; + fixedLegDayCounter_ = fixedLegDayCounter; + includeFirstSwaplet_ = includeFirstSwaplet; + + index_.registerWith(update); + } + + public override void addTimesTo(List times) + { + calculate(); + CapFloor.Arguments args = new CapFloor.Arguments(); + cap_.setupArguments(args); + List capTimes = new DiscretizedCapFloor(args, + termStructure_.link.referenceDate(), + termStructure_.link.dayCounter()).mandatoryTimes(); + for (int i = 0; i < capTimes.Count; i++) + times.Insert(times.Count, capTimes[i]); + + } + + public override double modelValue() + { + calculate(); + cap_.setPricingEngine(engine_); + return cap_.NPV(); + } + + public override double blackPrice(double sigma) + { + calculate(); + Quote vol = new SimpleQuote(sigma); + IPricingEngine black = new BlackCapFloorEngine(termStructure_, + new Handle(vol)); + cap_.setPricingEngine(black); + double value = cap_.NPV(); + cap_.setPricingEngine(engine_); + return value; + } + + protected override void performCalculations() + { + Period indexTenor = index_.tenor(); + double fixedRate = 0.04; // dummy value + Date startDate, maturity; + if (includeFirstSwaplet_) + { + startDate = termStructure_.link.referenceDate(); + maturity = termStructure_.link.referenceDate() + length_; + } + else + { + startDate = termStructure_.link.referenceDate() + indexTenor; + maturity = termStructure_.link.referenceDate() + length_; + } + IborIndex dummyIndex = new IborIndex("dummy", + indexTenor, + index_.fixingDays(), + index_.currency(), + index_.fixingCalendar(), + index_.businessDayConvention(), + index_.endOfMonth(), + termStructure_.link.dayCounter(), + termStructure_); + + List nominals = new InitializedList(1, 1.0); + + Schedule floatSchedule = new Schedule(startDate, maturity, + index_.tenor(), index_.fixingCalendar(), + index_.businessDayConvention(), + index_.businessDayConvention(), + DateGeneration.Rule.Forward, false); + List floatingLeg = new IborLeg(floatSchedule, index_) + .withFixingDays(0) + .withNotionals(nominals) + .withPaymentAdjustment(index_.businessDayConvention()); + + Schedule fixedSchedule = new Schedule(startDate, maturity, new Period(fixedLegFrequency_), + index_.fixingCalendar(), + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Forward, false); + List fixedLeg = new FixedRateLeg(fixedSchedule) + .withCouponRates(fixedRate, fixedLegDayCounter_) + .withNotionals(nominals) + .withPaymentAdjustment(index_.businessDayConvention()); + + Swap swap = new Swap(floatingLeg, fixedLeg); + swap.setPricingEngine(new DiscountingSwapEngine(termStructure_, false)); + double fairRate = fixedRate - (double)(swap.NPV() / (swap.legBPS(1) / 1.0e-4)); + cap_ = new Cap(floatingLeg, new InitializedList(1, fairRate)); + + base.performCalculations(); + + } + + private Cap cap_; + private Period length_; + private IborIndex index_; + private Frequency fixedLegFrequency_; + private DayCounter fixedLegDayCounter_; + private bool includeFirstSwaplet_; + } +} diff --git a/src/QLNet/Models/Shortrate/calibrationhelpers/SwaptionHelper.cs b/src/QLNet/Models/Shortrate/calibrationhelpers/SwaptionHelper.cs new file mode 100644 index 000000000..73dca1d33 --- /dev/null +++ b/src/QLNet/Models/Shortrate/calibrationhelpers/SwaptionHelper.cs @@ -0,0 +1,238 @@ +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System.Collections.Generic; + +namespace QLNet +{ + public class SwaptionHelper : CalibrationHelper + { + public SwaptionHelper(Period maturity, + Period length, + Handle volatility, + IborIndex index, + Period fixedLegTenor, + DayCounter fixedLegDayCounter, + DayCounter floatingLegDayCounter, + Handle termStructure, + CalibrationErrorType errorType = CalibrationErrorType.RelativePriceError, + double? strike = null, + double nominal = 1.0, + VolatilityType type = VolatilityType.ShiftedLognormal, + double shift = 0.0) + : base(volatility, termStructure, errorType, type, shift) + { + exerciseDate_ = null; + endDate_ = null; + maturity_ = maturity; + length_ = length; + fixedLegTenor_ = fixedLegTenor; + index_ = index; + fixedLegDayCounter_ = fixedLegDayCounter; + floatingLegDayCounter_ = floatingLegDayCounter; + strike_ = strike; + nominal_ = nominal; + + index_ .registerWith(update); + } + + public SwaptionHelper(Date exerciseDate, + Period length, + Handle volatility, + IborIndex index, + Period fixedLegTenor, + DayCounter fixedLegDayCounter, + DayCounter floatingLegDayCounter, + Handle termStructure, + CalibrationErrorType errorType = CalibrationErrorType.RelativePriceError, + double? strike = null, + double nominal = 1.0, + VolatilityType type = VolatilityType.ShiftedLognormal, + double shift = 0.0) + : base(volatility, termStructure, errorType, type, shift) + { + exerciseDate_ = exerciseDate; + endDate_ = null; + maturity_ = new Period(0, TimeUnit.Days); + length_ = length; + fixedLegTenor_ = fixedLegTenor; + index_ = index; + fixedLegDayCounter_ = fixedLegDayCounter; + floatingLegDayCounter_ = floatingLegDayCounter; + strike_ = strike; + nominal_ = nominal; + + index_.registerWith(update); + } + + public SwaptionHelper(Date exerciseDate, + Date endDate, + Handle volatility, + IborIndex index, + Period fixedLegTenor, + DayCounter fixedLegDayCounter, + DayCounter floatingLegDayCounter, + Handle termStructure, + CalibrationErrorType errorType = CalibrationErrorType.RelativePriceError, + double? strike = null, + double nominal = 1.0, + VolatilityType type = VolatilityType.ShiftedLognormal, + double shift = 0.0) + : base(volatility, termStructure, errorType, type, shift) + { + exerciseDate_ = exerciseDate; + endDate_ = endDate; + maturity_ = new Period(0, TimeUnit.Days); + length_ = new Period(0, TimeUnit.Days); + fixedLegTenor_ = fixedLegTenor; + index_ = index; + fixedLegDayCounter_ = fixedLegDayCounter; + floatingLegDayCounter_ = floatingLegDayCounter; + strike_ = strike; + nominal_ = nominal; + + index_.registerWith(update); + } + + + public override void addTimesTo(List times) + { + calculate(); + Swaption.Arguments args = new Swaption.Arguments(); + swaption_.setupArguments(args); + + List swaptionTimes = + new DiscretizedSwaption(args, + termStructure_.link.referenceDate(), + termStructure_.link.dayCounter()).mandatoryTimes(); + + for (int i = 0; i < swaptionTimes.Count; i++) + times.Insert(times.Count, swaptionTimes[i]); + } + + public override double modelValue() + { + calculate(); + swaption_.setPricingEngine(engine_); + return swaption_.NPV(); + } + + public override double blackPrice(double sigma) + { + calculate(); + SimpleQuote sq = new SimpleQuote(sigma); + Handle vol = new Handle(sq); + + IPricingEngine engine = null; + switch (volatilityType_) + { + case VolatilityType.ShiftedLognormal: + engine = new BlackSwaptionEngine(termStructure_, vol, new Actual365Fixed(), shift_); + break; + + case VolatilityType.Normal: + engine = new BachelierSwaptionEngine(termStructure_, vol, new Actual365Fixed()); + break; + + default: + Utils.QL_FAIL("can not construct engine: " + volatilityType_); + break; + } + + swaption_.setPricingEngine(engine); + double value = swaption_.NPV(); + swaption_.setPricingEngine(engine_); + return value; + } + + public VanillaSwap underlyingSwap() { calculate(); return swap_; } + public Swaption swaption() { calculate(); return swaption_; } + + protected override void performCalculations() + { + Calendar calendar = index_.fixingCalendar(); + int fixingDays = index_.fixingDays(); + + Date exerciseDate = exerciseDate_; + if (exerciseDate == null) + exerciseDate = calendar.advance(termStructure_.link.referenceDate(), + maturity_, + index_.businessDayConvention()); + + Date startDate = calendar.advance(exerciseDate, + fixingDays, TimeUnit.Days, + index_.businessDayConvention()); + + Date endDate = endDate_; + if (endDate == null) + endDate = calendar.advance(startDate, length_, + index_.businessDayConvention()); + + Schedule fixedSchedule = new Schedule(startDate, endDate, fixedLegTenor_, calendar, + index_.businessDayConvention(), + index_.businessDayConvention(), + DateGeneration.Rule.Forward, false); + Schedule floatSchedule = new Schedule(startDate, endDate, index_.tenor(), calendar, + index_.businessDayConvention(), + index_.businessDayConvention(), + DateGeneration.Rule.Forward, false); + + IPricingEngine swapEngine = new DiscountingSwapEngine(termStructure_, false); + + VanillaSwap.Type type = VanillaSwap.Type.Receiver; + + VanillaSwap temp = new VanillaSwap(VanillaSwap.Type.Receiver, nominal_, + fixedSchedule, 0.0, fixedLegDayCounter_, + floatSchedule, index_, 0.0, floatingLegDayCounter_); + temp.setPricingEngine(swapEngine); + double forward = temp.fairRate(); + if (! strike_.HasValue) + { + exerciseRate_ = forward; + } + else + { + exerciseRate_ = strike_.Value; + type = strike_ <= forward ? VanillaSwap.Type.Receiver : VanillaSwap.Type.Payer; + // ensure that calibration instrument is out of the money + } + swap_ = new VanillaSwap(type, nominal_, + fixedSchedule, exerciseRate_, fixedLegDayCounter_, + floatSchedule, index_, 0.0, floatingLegDayCounter_); + swap_.setPricingEngine(swapEngine); + + Exercise exercise = new EuropeanExercise(exerciseDate); + + swaption_ = new Swaption(swap_, exercise); + + base.performCalculations(); + } + + private Date exerciseDate_, endDate_; + private Period maturity_, length_, fixedLegTenor_; + private IborIndex index_; + private DayCounter fixedLegDayCounter_, floatingLegDayCounter_; + private double? strike_; + private double nominal_; + private double exerciseRate_; + private VanillaSwap swap_; + private Swaption swaption_; + } +} diff --git a/src/QLNet/Models/Shortrate/calibrationhelpers/caphelper.cs b/src/QLNet/Models/Shortrate/calibrationhelpers/caphelper.cs deleted file mode 100644 index 556f82ba4..000000000 --- a/src/QLNet/Models/Shortrate/calibrationhelpers/caphelper.cs +++ /dev/null @@ -1,141 +0,0 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System.Collections.Generic; - -namespace QLNet -{ - public class CapHelper : CalibrationHelper - { - public CapHelper( Period length, - Handle volatility, - IborIndex index, - // data for ATM swap-rate calculation - Frequency fixedLegFrequency, - DayCounter fixedLegDayCounter, - bool includeFirstSwaplet, - Handle termStructure, - CalibrationErrorType errorType = CalibrationErrorType.RelativePriceError) - : base( volatility, termStructure, errorType ) - { - length_ = length; - index_ = index; - fixedLegFrequency_ = fixedLegFrequency; - fixedLegDayCounter_ = fixedLegDayCounter; - includeFirstSwaplet_ = includeFirstSwaplet; - - index_.registerWith(update); - } - - public override void addTimesTo( List times ) - { - calculate(); - CapFloor.Arguments args = new CapFloor.Arguments(); - cap_.setupArguments( args ); - List capTimes = new DiscretizedCapFloor( args, - termStructure_.link.referenceDate(), - termStructure_.link.dayCounter() ).mandatoryTimes(); - for ( int i = 0; i < capTimes.Count; i++ ) - times.Insert( times.Count, capTimes[i] ); - - } - - public override double modelValue() - { - calculate(); - cap_.setPricingEngine( engine_ ); - return cap_.NPV(); - } - - public override double blackPrice( double sigma ) - { - calculate(); - Quote vol = new SimpleQuote( sigma ); - IPricingEngine black = new BlackCapFloorEngine( termStructure_, - new Handle( vol ) ); - cap_.setPricingEngine( black ); - double value = cap_.NPV(); - cap_.setPricingEngine( engine_ ); - return value; - } - - protected override void performCalculations() - { - Period indexTenor = index_.tenor(); - double fixedRate = 0.04; // dummy value - Date startDate, maturity; - if ( includeFirstSwaplet_ ) - { - startDate = termStructure_.link.referenceDate(); - maturity = termStructure_.link.referenceDate() + length_; - } - else - { - startDate = termStructure_.link.referenceDate() + indexTenor; - maturity = termStructure_.link.referenceDate() + length_; - } - IborIndex dummyIndex = new IborIndex( "dummy", - indexTenor, - index_.fixingDays(), - index_.currency(), - index_.fixingCalendar(), - index_.businessDayConvention(), - index_.endOfMonth(), - termStructure_.link.dayCounter(), - termStructure_ ); - - List nominals = new InitializedList( 1, 1.0 ); - - Schedule floatSchedule = new Schedule( startDate, maturity, - index_.tenor(), index_.fixingCalendar(), - index_.businessDayConvention(), - index_.businessDayConvention(), - DateGeneration.Rule.Forward, false ); - List floatingLeg = new IborLeg( floatSchedule, index_ ) - .withFixingDays( 0 ) - .withNotionals( nominals ) - .withPaymentAdjustment( index_.businessDayConvention() ); - - Schedule fixedSchedule = new Schedule( startDate, maturity, new Period( fixedLegFrequency_ ), - index_.fixingCalendar(), - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Forward, false ); - List fixedLeg = new FixedRateLeg( fixedSchedule ) - .withCouponRates( fixedRate, fixedLegDayCounter_ ) - .withNotionals( nominals ) - .withPaymentAdjustment( index_.businessDayConvention() ); - - Swap swap = new Swap( floatingLeg, fixedLeg ); - swap.setPricingEngine( new DiscountingSwapEngine( termStructure_, false ) ); - double fairRate = fixedRate - (double)(swap.NPV() / ( swap.legBPS( 1 ) / 1.0e-4 )); - cap_ = new Cap( floatingLeg, new InitializedList( 1, fairRate ) ); - - base.performCalculations(); - - } - - private Cap cap_; - private Period length_; - private IborIndex index_; - private Frequency fixedLegFrequency_; - private DayCounter fixedLegDayCounter_; - private bool includeFirstSwaplet_; - } -} diff --git a/src/QLNet/Models/Shortrate/calibrationhelpers/swaptionhelper.cs b/src/QLNet/Models/Shortrate/calibrationhelpers/swaptionhelper.cs deleted file mode 100644 index f67147073..000000000 --- a/src/QLNet/Models/Shortrate/calibrationhelpers/swaptionhelper.cs +++ /dev/null @@ -1,238 +0,0 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System.Collections.Generic; - -namespace QLNet -{ - public class SwaptionHelper : CalibrationHelper - { - public SwaptionHelper( Period maturity, - Period length, - Handle volatility, - IborIndex index, - Period fixedLegTenor, - DayCounter fixedLegDayCounter, - DayCounter floatingLegDayCounter, - Handle termStructure, - CalibrationErrorType errorType = CalibrationErrorType.RelativePriceError, - double? strike = null, - double nominal = 1.0, - VolatilityType type = VolatilityType.ShiftedLognormal, - double shift = 0.0) - : base(volatility, termStructure, errorType, type, shift) - { - exerciseDate_ = null; - endDate_ = null; - maturity_ = maturity; - length_ = length; - fixedLegTenor_ = fixedLegTenor; - index_ = index; - fixedLegDayCounter_ = fixedLegDayCounter; - floatingLegDayCounter_ = floatingLegDayCounter; - strike_ = strike; - nominal_ = nominal; - - index_ .registerWith(update); - } - - public SwaptionHelper( Date exerciseDate, - Period length, - Handle volatility, - IborIndex index, - Period fixedLegTenor, - DayCounter fixedLegDayCounter, - DayCounter floatingLegDayCounter, - Handle termStructure, - CalibrationErrorType errorType = CalibrationErrorType.RelativePriceError, - double? strike = null, - double nominal = 1.0, - VolatilityType type = VolatilityType.ShiftedLognormal, - double shift = 0.0 ) - : base( volatility, termStructure, errorType, type, shift ) - { - exerciseDate_ = exerciseDate; - endDate_ = null; - maturity_ = new Period(0,TimeUnit.Days); - length_ = length; - fixedLegTenor_ = fixedLegTenor; - index_ = index; - fixedLegDayCounter_ = fixedLegDayCounter; - floatingLegDayCounter_ = floatingLegDayCounter; - strike_ = strike; - nominal_ = nominal; - - index_.registerWith( update ); - } - - public SwaptionHelper( Date exerciseDate, - Date endDate, - Handle volatility, - IborIndex index, - Period fixedLegTenor, - DayCounter fixedLegDayCounter, - DayCounter floatingLegDayCounter, - Handle termStructure, - CalibrationErrorType errorType = CalibrationErrorType.RelativePriceError, - double? strike =null, - double nominal = 1.0, - VolatilityType type = VolatilityType.ShiftedLognormal, - double shift = 0.0) - : base(volatility, termStructure, errorType, type, shift) - { - exerciseDate_ = exerciseDate; - endDate_ = endDate; - maturity_ = new Period( 0, TimeUnit.Days ); - length_ = new Period( 0, TimeUnit.Days ); - fixedLegTenor_ = fixedLegTenor; - index_ = index; - fixedLegDayCounter_ = fixedLegDayCounter; - floatingLegDayCounter_ = floatingLegDayCounter; - strike_ = strike; - nominal_ = nominal; - - index_.registerWith( update ); - } - - - public override void addTimesTo( List times ) - { - calculate(); - Swaption.Arguments args = new Swaption.Arguments(); - swaption_.setupArguments( args ); - - List swaptionTimes = - new DiscretizedSwaption( args, - termStructure_.link.referenceDate(), - termStructure_.link.dayCounter() ).mandatoryTimes(); - - for ( int i = 0; i < swaptionTimes.Count; i++ ) - times.Insert( times.Count, swaptionTimes[i] ); - } - - public override double modelValue() - { - calculate(); - swaption_.setPricingEngine( engine_ ); - return swaption_.NPV(); - } - - public override double blackPrice( double sigma ) - { - calculate(); - SimpleQuote sq = new SimpleQuote( sigma ); - Handle vol = new Handle( sq ); - - IPricingEngine engine = null; - switch(volatilityType_) - { - case VolatilityType.ShiftedLognormal: - engine = new BlackSwaptionEngine( termStructure_, vol, new Actual365Fixed(), shift_ ); - break; - - case VolatilityType.Normal: - engine = new BachelierSwaptionEngine( termStructure_, vol, new Actual365Fixed() ); - break; - - default: - Utils.QL_FAIL("can not construct engine: " + volatilityType_); - break; - } - - swaption_.setPricingEngine(engine); - double value = swaption_.NPV(); - swaption_.setPricingEngine(engine_); - return value; - } - - public VanillaSwap underlyingSwap() { calculate(); return swap_; } - public Swaption swaption() { calculate(); return swaption_; } - - protected override void performCalculations() - { - Calendar calendar = index_.fixingCalendar(); - int fixingDays = index_.fixingDays(); - - Date exerciseDate = exerciseDate_; - if (exerciseDate == null) - exerciseDate = calendar.advance(termStructure_.link.referenceDate(), - maturity_, - index_.businessDayConvention()); - - Date startDate = calendar.advance(exerciseDate, - fixingDays, TimeUnit.Days, - index_.businessDayConvention()); - - Date endDate = endDate_; - if (endDate == null) - endDate = calendar.advance(startDate, length_, - index_.businessDayConvention()); - - Schedule fixedSchedule = new Schedule(startDate, endDate, fixedLegTenor_, calendar, - index_.businessDayConvention(), - index_.businessDayConvention(), - DateGeneration.Rule.Forward, false); - Schedule floatSchedule = new Schedule(startDate, endDate, index_.tenor(), calendar, - index_.businessDayConvention(), - index_.businessDayConvention(), - DateGeneration.Rule.Forward, false); - - IPricingEngine swapEngine = new DiscountingSwapEngine(termStructure_, false); - - VanillaSwap.Type type = VanillaSwap.Type.Receiver; - - VanillaSwap temp = new VanillaSwap(VanillaSwap.Type.Receiver, nominal_, - fixedSchedule, 0.0, fixedLegDayCounter_, - floatSchedule, index_, 0.0, floatingLegDayCounter_); - temp.setPricingEngine(swapEngine); - double forward = temp.fairRate(); - if(! strike_.HasValue) - { - exerciseRate_ = forward; - } - else - { - exerciseRate_ = strike_.Value; - type = strike_ <= forward ? VanillaSwap.Type.Receiver : VanillaSwap.Type.Payer; - // ensure that calibration instrument is out of the money - } - swap_ = new VanillaSwap(type, nominal_, - fixedSchedule, exerciseRate_, fixedLegDayCounter_, - floatSchedule, index_, 0.0, floatingLegDayCounter_); - swap_.setPricingEngine(swapEngine); - - Exercise exercise = new EuropeanExercise(exerciseDate); - - swaption_ = new Swaption(swap_, exercise); - - base.performCalculations(); - } - - private Date exerciseDate_, endDate_; - private Period maturity_, length_, fixedLegTenor_; - private IborIndex index_; - private DayCounter fixedLegDayCounter_, floatingLegDayCounter_; - private double? strike_; - private double nominal_; - private double exerciseRate_; - private VanillaSwap swap_; - private Swaption swaption_; - } -} diff --git a/src/QLNet/Models/model.cs b/src/QLNet/Models/model.cs deleted file mode 100644 index e1b9338d9..000000000 --- a/src/QLNet/Models/model.cs +++ /dev/null @@ -1,345 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet { - //! Affine model class - /*! Base class for analytically tractable models. - - \ingroup shortrate - */ - public abstract class AffineModel : IObservable { - //! Implied discount curve - public abstract double discount(double t); - public abstract double discountBond(double now, double maturity, Vector factors); - public abstract double discountBondOption(Option.Type type, double strike, double maturity, double bondMaturity); - - private readonly WeakEventSource eventSource = new WeakEventSource(); - public event Callback notifyObserversEvent - { - add { eventSource.Subscribe(value); } - remove { eventSource.Unsubscribe(value); } - } - - public void registerWith(Callback handler) { notifyObserversEvent += handler; } - public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } - protected void notifyObservers() - { - eventSource.Raise(); - } - } - - //Affince Model Interface used for multihritage in - //liborforwardmodel.cs & analyticcapfloorengine.cs - public interface IAffineModel : IObservable - { - double discount(double t); - double discountBond(double now, double maturity, Vector factors); - double discountBondOption(Option.Type type, double strike, double maturity, double bondMaturity); - } - - //TermStructureConsistentModel used in analyticcapfloorengine.cs - public class TermStructureConsistentModel : IObservable - { - public TermStructureConsistentModel(Handle termStructure) - { - termStructure_ = termStructure; - } - - public Handle termStructure() - { - return termStructure_; - } - private Handle termStructure_; - - private readonly WeakEventSource eventSource = new WeakEventSource(); - public event Callback notifyObserversEvent - { - add { eventSource.Subscribe(value); } - remove { eventSource.Unsubscribe(value); } - } - - public void registerWith(Callback handler) { notifyObserversEvent += handler; } - public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } - protected void notifyObservers() - { - eventSource.Raise(); - } - } - - //ITermStructureConsistentModel used ins shortratemodel blackkarasinski.cs/hullwhite.cs - public interface ITermStructureConsistentModel - { - Handle termStructure(); - Handle termStructure_ { get; set; } - void notifyObservers(); - event Callback notifyObserversEvent; - void registerWith(Callback handler); - void unregisterWith(Callback handler); - void update(); - } - - //! Calibrated model class - public class CalibratedModel : IObserver, IObservable { - protected List arguments_; - - protected Constraint constraint_; - public Constraint constraint() { return constraint_; } - - protected EndCriteria.Type shortRateEndCriteria_; - public EndCriteria.Type endCriteria() { return shortRateEndCriteria_; } - - - public CalibratedModel(int nArguments) { - arguments_ = new InitializedList(nArguments); - constraint_ = new PrivateConstraint(arguments_); - shortRateEndCriteria_ = EndCriteria.Type.None; - } - - //! Calibrate to a set of market instruments (caps/swaptions) - /*! An additional constraint can be passed which must be - satisfied in addition to the constraints of the model. - */ - public void calibrate(List instruments, - OptimizationMethod method, - EndCriteria endCriteria, - Constraint additionalConstraint = null, - List weights = null, - List fixParameters = null) - { - if ( weights == null ) weights = new List(); - if ( additionalConstraint == null ) additionalConstraint = new Constraint(); - Utils.QL_REQUIRE( weights.empty() || weights.Count == instruments.Count,()=> - "mismatch between number of instruments (" + - instruments.Count + ") and weights(" + - weights.Count + ")" ); - - Constraint c; - if (additionalConstraint.empty()) - c = constraint_; - else - c = new CompositeConstraint(constraint_,additionalConstraint); - List w = weights.Count == 0 ? new InitializedList(instruments.Count, 1.0): weights; - - Vector prms = parameters(); - List all = new InitializedList(prms.size(), false); - Projection proj = new Projection(prms,fixParameters ?? all); - CalibrationFunction f = new CalibrationFunction(this,instruments,w,proj); - ProjectedConstraint pc = new ProjectedConstraint(c,proj); - Problem prob = new Problem(f, pc, proj.project(prms)); - shortRateEndCriteria_ = method.minimize(prob, endCriteria); - Vector result = new Vector(prob.currentValue()); - setParams(proj.include(result)); - Vector shortRateProblemValues_ = prob.values(result); - - notifyObservers(); - } - - public double value(Vector parameters, List instruments) { - List w = new InitializedList(instruments.Count, 1.0); - Projection p = new Projection(parameters); - CalibrationFunction f = new CalibrationFunction(this, instruments, w, p); - return f.value(parameters); - } - - //! Returns array of arguments on which calibration is done - public Vector parameters() { - int size = 0, i; - for (i=0; i "parameter array too small"); - arguments_[i].setParam(j, parameters[p++]); - } - } - - Utils.QL_REQUIRE(p==parameters.Count,()=> "parameter array too big!"); - update(); - } - - protected virtual void generateArguments() {} - - - //! Constraint imposed on arguments - private class PrivateConstraint : Constraint { - public PrivateConstraint(List arguments) : base(new Impl(arguments)) { } - - private class Impl : IConstraint { - private List arguments_; - - public Impl(List arguments) { - arguments_ = arguments; - } - - public bool test(Vector p) { - int k=0; - for (int i=0; i instruments, - List weights, - Projection projection) - { - // recheck - model_ = model; - instruments_ = instruments; - weights_ = weights; - projection_ = projection; - } - - public override double value( Vector p ) - { - model_.setParams( projection_.include(p) ); - - double value = 0.0; - for ( int i = 0; i < instruments_.Count; i++ ) - { - double diff = instruments_[i].calibrationError(); - value += diff * diff * weights_[i]; - } - - return Math.Sqrt( value ); - } - - public override Vector values( Vector p ) - { - model_.setParams( projection_.include(p) ); - - Vector values = new Vector( instruments_.Count ); - for ( int i = 0; i < instruments_.Count; i++ ) - { - values[i] = instruments_[i].calibrationError() * Math.Sqrt( weights_[i] ); - } - return values; - } - - public override double finiteDifferenceEpsilon() { return 1e-6; } - - private CalibratedModel model_; - private List instruments_; - private List weights_; - private Projection projection_; - - } - - - #region Observer & Observable - private readonly WeakEventSource eventSource = new WeakEventSource(); - public event Callback notifyObserversEvent - { - add { eventSource.Subscribe(value); } - remove { eventSource.Unsubscribe(value); } - } - - public void registerWith(Callback handler) { notifyObserversEvent += handler; } - public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } - public void notifyObservers() - { - eventSource.Raise(); - } - - public void update() - { - generateArguments(); - notifyObservers(); - } - #endregion - } - - //! Abstract short-rate model class - /*! \ingroup shortrate */ - public abstract class ShortRateModel : CalibratedModel { - protected ShortRateModel(int nArguments) : base(nArguments) { } - - public abstract Lattice tree(TimeGrid t); - } -} diff --git a/src/QLNet/Money.cs b/src/QLNet/Money.cs index 21d4c6d3e..997f8031b 100644 --- a/src/QLNet/Money.cs +++ b/src/QLNet/Money.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -28,7 +28,7 @@ namespace QLNet public class Money { #region Define - + public enum ConversionType { /// @@ -38,13 +38,13 @@ public enum ConversionType /// /// convert both operands to the base currency before converting /// - BaseCurrencyConversion, + BaseCurrencyConversion, /// /// return the result in the currency of the first operand /// AutomatedConversion } - + #endregion #region Attributes @@ -55,7 +55,7 @@ public enum ConversionType [ThreadStatic] private static Currency baseCurrency_; - public static ConversionType conversionType {get {return conversionType_;}set {conversionType_ = value;}} + public static ConversionType conversionType {get {return conversionType_;} set {conversionType_ = value;}} public static Currency baseCurrency { get { return baseCurrency_; } set { baseCurrency_ = value; } } private double value_; @@ -76,7 +76,7 @@ public Money(Currency currency, double value) currency_ = currency; } - public Money(double value, Currency currency) :this(currency,value) { } + public Money(double value, Currency currency) : this(currency, value) { } #endregion @@ -84,14 +84,20 @@ public Money(double value, Currency currency) :this(currency,value) { } public Currency currency { - get { return currency_; } + get + { + return currency_; + } } public double value { - get { return value_; } + get + { + return value_; + } } - #endregion + #endregion #region Methods @@ -105,128 +111,128 @@ public static void convertTo(ref Money m, Currency target) } public static void convertToBase(ref Money m) { - Utils.QL_REQUIRE(!baseCurrency.empty(),()=> "no base currency set"); + Utils.QL_REQUIRE(!baseCurrency.empty(), () => "no base currency set"); convertTo(ref m, baseCurrency); } public Money rounded() { return new Money(currency_.rounding.Round(value_), currency_); } - public override String ToString() + public override String ToString() { - return this.rounded().value + "-" + this.currency.code + "-" + this.currency.symbol ; + return this.rounded().value + "-" + this.currency.code + "-" + this.currency.symbol ; } #endregion #region Operators - - public static Money operator * (Money m , double x) + + public static Money operator * (Money m, double x) { return new Money(m.value_ * x, m.currency); } - public static Money operator *(double x, Money m) + public static Money operator *(double x, Money m) { - return m*x; + return m * x; } public static Money operator / (Money m, double x) { - return new Money(m.value_ / x,m.currency); + return new Money(m.value_ / x, m.currency); } - public static Money operator+(Money m1,Money m2) + public static Money operator+(Money m1, Money m2) { - Money m = new Money (m1.currency ,m1.value ); + Money m = new Money(m1.currency, m1.value); - if (m1.currency_ == m2.currency_) + if (m1.currency_ == m2.currency_) { m.value_ += m2.value_; - } - else if (Money.conversionType == Money.ConversionType.BaseCurrencyConversion) + } + else if (Money.conversionType == Money.ConversionType.BaseCurrencyConversion) { Money.convertToBase(ref m); Money tmp = m2; Money.convertToBase(ref tmp); m += tmp; - } - else if (Money.conversionType == Money.ConversionType.AutomatedConversion) - { + } + else if (Money.conversionType == Money.ConversionType.AutomatedConversion) + { Money tmp = m2; Money.convertTo(ref tmp, m.currency_); m += tmp; - } - else - { - Utils.QL_FAIL("currency mismatch and no conversion specified"); - } + } + else + { + Utils.QL_FAIL("currency mismatch and no conversion specified"); + } - return m; - } - public static Money operator-(Money m1, Money m2) + return m; + } + public static Money operator-(Money m1, Money m2) { - Money m = new Money ( m1.currency ,m1.value ); + Money m = new Money(m1.currency, m1.value); - if (m.currency_ == m2.currency_) + if (m.currency_ == m2.currency_) { m.value_ -= m2.value_; - } - else if (Money.conversionType == Money.ConversionType.BaseCurrencyConversion) + } + else if (Money.conversionType == Money.ConversionType.BaseCurrencyConversion) { convertToBase(ref m); Money tmp = m2; convertToBase(ref tmp); m -= tmp; - } - else if (Money.conversionType == Money.ConversionType.AutomatedConversion) + } + else if (Money.conversionType == Money.ConversionType.AutomatedConversion) { Money tmp = m2; convertTo(ref tmp, m.currency_); m -= tmp; - } - else + } + else { Utils.QL_FAIL("currency mismatch and no conversion specified"); } - + return m; } - public static bool operator ==(Money m1,Money m2) + public static bool operator ==(Money m1, Money m2) { - if ((object)m1 == null && (object)m2 == null) + if ((object)m1 == null && (object)m2 == null) return true; - else if ((object)m1 == null || (object)m2 == null) + else if ((object)m1 == null || (object)m2 == null) return false; - else if (m1.currency == m2.currency) + else if (m1.currency == m2.currency) { return m1.value.IsEqual(m2.value); - } - else if (Money.conversionType == Money.ConversionType.BaseCurrencyConversion) + } + else if (Money.conversionType == Money.ConversionType.BaseCurrencyConversion) { Money tmp1 = m1; convertToBase(ref tmp1); Money tmp2 = m2; convertToBase(ref tmp2); return tmp1 == tmp2; - } - else if (Money.conversionType == Money.ConversionType.AutomatedConversion) + } + else if (Money.conversionType == Money.ConversionType.AutomatedConversion) { Money tmp = m2; convertTo(ref tmp, m1.currency); return m1 == tmp; - } - else + } + else { - Utils.QL_FAIL("currency mismatch and no conversion specified"); + Utils.QL_FAIL("currency mismatch and no conversion specified"); return false; } } - public static bool operator !=(Money m1,Money m2) + public static bool operator !=(Money m1, Money m2) { - return !( m1 == m2 ) ; + return !(m1 == m2) ; } public override bool Equals(object o) { return (this == (Money)o); } public override int GetHashCode() { return 0; } - #endregion - } + #endregion + } } diff --git a/src/QLNet/numericalmethod.cs b/src/QLNet/NumericalMethod.cs similarity index 96% rename from src/QLNet/numericalmethod.cs rename to src/QLNet/NumericalMethod.cs index 1f4001f3c..0732e8619 100644 --- a/src/QLNet/numericalmethod.cs +++ b/src/QLNet/NumericalMethod.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Option.cs b/src/QLNet/Option.cs index 4b5080868..28d76f8f2 100644 --- a/src/QLNet/Option.cs +++ b/src/QLNet/Option.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Patterns/FastActivator.cs b/src/QLNet/Patterns/FastActivator.cs index 8da442f3d..21a5246cc 100644 --- a/src/QLNet/Patterns/FastActivator.cs +++ b/src/QLNet/Patterns/FastActivator.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,10 +20,10 @@ namespace QLNet { - // Base on Sergey Teplyakov code + // Base on Sergey Teplyakov code // https://blogs.msdn.microsoft.com/seteplia/2017/02/01/dissecting-the-new-constraint-in-c-a-perfect-example-of-a-leaky-abstraction/ // - public static class FastActivator where T : new() + public static class FastActivator where T : new () { /// /// Extremely fast generic factory method that returns an instance @@ -34,26 +34,26 @@ namespace QLNet public static class DynamicModuleLambdaCompiler { - public static Func GenerateFactory() where T : new() + public static Func GenerateFactory() where T : new () { Expression> expr = () => new T(); NewExpression newExpr = (NewExpression)expr.Body; - #if NET40 || NET45 +#if NET40 || NET45 var method = new DynamicMethod( - name: "lambda", - returnType: newExpr.Type, - parameterTypes: new Type[0], - m: typeof(DynamicModuleLambdaCompiler).Module, - skipVisibility: true); - #else + name: "lambda", + returnType: newExpr.Type, + parameterTypes: new Type[0], + m: typeof(DynamicModuleLambdaCompiler).Module, + skipVisibility: true); +#else var method = new DynamicMethod( - name: "lambda", - returnType: newExpr.Type, - parameterTypes: new Type[0], - m: typeof(DynamicModuleLambdaCompiler).GetTypeInfo().Module, - skipVisibility: true); - #endif + name: "lambda", + returnType: newExpr.Type, + parameterTypes: new Type[0], + m: typeof(DynamicModuleLambdaCompiler).GetTypeInfo().Module, + skipVisibility: true); +#endif ILGenerator ilGen = method.GetILGenerator(); // Constructor for value types could be null diff --git a/src/QLNet/Patterns/LazyObject.cs b/src/QLNet/Patterns/LazyObject.cs index 6e9e6b59d..9919b3703 100644 --- a/src/QLNet/Patterns/LazyObject.cs +++ b/src/QLNet/Patterns/LazyObject.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,106 +20,112 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - // Framework for calculation on demand and result caching. - // Introduces Observer pattern - public abstract class LazyObject : IObservable, IObserver - { - protected bool calculated_; - protected bool frozen_; + // Framework for calculation on demand and result caching. + // Introduces Observer pattern + public abstract class LazyObject : IObservable, IObserver + { + protected bool calculated_; + protected bool frozen_; - #region Observer interface - // Here we define this object as observable - private readonly WeakEventSource eventSource = new WeakEventSource(); - public event Callback notifyObserversEvent - { - add { eventSource.Subscribe(value); } - remove { eventSource.Unsubscribe(value); } - } + #region Observer interface + // Here we define this object as observable + private readonly WeakEventSource eventSource = new WeakEventSource(); + public event Callback notifyObserversEvent + { + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } + } - public void registerWith(Callback handler) { notifyObserversEvent += handler; } - public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } - protected void notifyObservers() - { - eventSource.Raise(); - } + public void registerWith(Callback handler) { notifyObserversEvent += handler; } + public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } + protected void notifyObservers() + { + eventSource.Raise(); + } - // This method is the observer interface - // It must be implemented in derived classes and linked to the event of the required Observer - public virtual void update() - { - // observers don't expect notifications from frozen objects - // LazyObject forwards notifications only once until it has been recalculated - if (!frozen_ && calculated_) - notifyObservers(); - calculated_ = false; - } - #endregion + // This method is the observer interface + // It must be implemented in derived classes and linked to the event of the required Observer + public virtual void update() + { + // observers don't expect notifications from frozen objects + // LazyObject forwards notifications only once until it has been recalculated + if (!frozen_ && calculated_) + notifyObservers(); + calculated_ = false; + } + #endregion - #region Calculation methods - /*! This method forces recalculation of any results which would otherwise be cached. - * It needs to call the LazyCalculationEvent event. - Explicit invocation of this method is not necessary if the object has registered itself as - observer with the structures on which such results depend. It is strongly advised to follow this - policy when possible. */ - public virtual void recalculate() - { - bool wasFrozen = frozen_; - calculated_ = frozen_ = false; - try - { - calculate(); - } - catch - { - frozen_ = wasFrozen; - notifyObservers(); - throw; - } + #region Calculation methods + /*! This method forces recalculation of any results which would otherwise be cached. + * It needs to call the LazyCalculationEvent event. + Explicit invocation of this method is not necessary if the object has registered itself as + observer with the structures on which such results depend. It is strongly advised to follow this + policy when possible. */ + public virtual void recalculate() + { + bool wasFrozen = frozen_; + calculated_ = frozen_ = false; + try + { + calculate(); + } + catch + { frozen_ = wasFrozen; notifyObservers(); - } + throw; + } + frozen_ = wasFrozen; + notifyObservers(); + } - /*! This method constrains the object to return the presently cached results on successive invocations, - * even if arguments upon which they depend should change. */ - public void freeze() { frozen_ = true; } + /*! This method constrains the object to return the presently cached results on successive invocations, + * even if arguments upon which they depend should change. */ + public void freeze() { frozen_ = true; } - // This method reverts the effect of the freeze method, thus re-enabling recalculations. - public void unfreeze() - { - frozen_ = false; - notifyObservers(); // send notification, just in case we lost any - } + // This method reverts the effect of the freeze method, thus re-enabling recalculations. + public void unfreeze() + { + frozen_ = false; + notifyObservers(); // send notification, just in case we lost any + } - /*! This method performs all needed calculations by calling the performCalculations method. - Objects cache the results of the previous calculation. Such results will be returned upon - later invocations of calculate. When the results depend - on arguments which could change between invocations, the lazy object must register itself - as observer of such objects for the calculations to be performed again when they change. - Should this method be redefined in derived classes, LazyObject::calculate() should be called - in the overriding method. */ - protected virtual void calculate() - { - if (!calculated_ && !frozen_) + /*! This method performs all needed calculations by calling the performCalculations method. + Objects cache the results of the previous calculation. Such results will be returned upon + later invocations of calculate. When the results depend + on arguments which could change between invocations, the lazy object must register itself + as observer of such objects for the calculations to be performed again when they change. + Should this method be redefined in derived classes, LazyObject::calculate() should be called + in the overriding method. */ + protected virtual void calculate() + { + if (!calculated_ && !frozen_) + { + calculated_ = true; // prevent infinite recursion in case of bootstrapping + try + { + performCalculations(); + } + catch { - calculated_ = true; // prevent infinite recursion in case of bootstrapping - try - { - performCalculations(); - } - catch - { - calculated_ = false; - throw; - } + calculated_ = false; + throw; } - } + } + } - /* This method must implement any calculations which must be (re)done - * in order to calculate the desired results. */ - protected virtual void performCalculations() - { - throw new NotSupportedException(); - } - #endregion - } + /* This method must implement any calculations which must be (re)done + * in order to calculate the desired results. */ + protected virtual void performCalculations() + { + throw new NotSupportedException(); + } + #endregion + } } diff --git a/src/QLNet/Patterns/ObservableValue.cs b/src/QLNet/Patterns/ObservableValue.cs new file mode 100644 index 000000000..60f5d9073 --- /dev/null +++ b/src/QLNet/Patterns/ObservableValue.cs @@ -0,0 +1,92 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +namespace QLNet +{ + //! %observable and assignable proxy to concrete value + /*! Observers can be registered with instances of this class so + that they are notified when a different value is assigned to + such instances. Client code can copy the contained value or + pass it to functions via implicit conversion. + \note it is not possible to call non-const method on the + returned value. This is by design, as this possibility + would necessarily bypass the notification code; client + code should modify the value via re-assignment instead. + */ + public class ObservableValue : IObservable where T : new () + { + private T value_; + + public ObservableValue() + { + value_ = FastActivator.Create(); + } + + public ObservableValue(T t) + { + value_ = t; + } + + public ObservableValue(ObservableValue t) + { + value_ = t.value_; + } + + + // controlled assignment + public ObservableValue Assign(T t) + { + value_ = t; + notifyObservers(); + return this; + } + + public ObservableValue Assign(ObservableValue t) + { + value_ = t.value_; + notifyObservers(); + return this; + } + + //! explicit inspector + public T value() { return value_; } + + + // Subjects, i.e. observables, should define interface internally like follows. + private readonly WeakEventSource eventSource = new WeakEventSource(); + public event Callback notifyObserversEvent + { + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } + } + + public void registerWith(Callback handler) { notifyObserversEvent += handler; } + public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } + protected void notifyObservers() + { + eventSource.Raise(); + } + } +} diff --git a/src/QLNet/Patterns/Observer.cs b/src/QLNet/Patterns/Observer.cs index 9a607281f..1e7e64672 100644 --- a/src/QLNet/Patterns/Observer.cs +++ b/src/QLNet/Patterns/Observer.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Patterns/Visitor.cs b/src/QLNet/Patterns/Visitor.cs index 3fe7da4a1..9400c7451 100644 --- a/src/QLNet/Patterns/Visitor.cs +++ b/src/QLNet/Patterns/Visitor.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,9 +19,9 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - // to make the objects Visitor-ready - public interface IAcyclicVisitor - { - void visit(object o); - } + // to make the objects Visitor-ready + public interface IAcyclicVisitor + { + void visit(object o); + } } diff --git a/src/QLNet/Patterns/WeakEventSource.cs b/src/QLNet/Patterns/WeakEventSource.cs index af31d75e6..b96b834ec 100644 --- a/src/QLNet/Patterns/WeakEventSource.cs +++ b/src/QLNet/Patterns/WeakEventSource.cs @@ -7,7 +7,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -47,9 +47,9 @@ public void Raise() public void Subscribe(Callback handler) { var weakHandlers = handler - .GetInvocationList() - .Select(d => new WeakDelegate(d)) - .ToList(); + .GetInvocationList() + .Select(d => new WeakDelegate(d)) + .ToList(); lock (_handlers) { @@ -75,7 +75,7 @@ private class WeakDelegate // ReSharper disable once StaticMemberInGenericType (by design) private static readonly ConcurrentDictionary _openHandlerCache = - new ConcurrentDictionary(); + new ConcurrentDictionary(); private static OpenEventHandler CreateOpenHandler(MethodInfo method) { @@ -84,18 +84,18 @@ private static OpenEventHandler CreateOpenHandler(MethodInfo method) if (method.IsStatic) { var expr = Expression.Lambda( - Expression.Call( - method), - target); + Expression.Call( + method), + target); return expr.Compile(); } else { var expr = Expression.Lambda( - Expression.Call( - Expression.Convert(target, method.DeclaringType), - method), - target); + Expression.Call( + Expression.Convert(target, method.DeclaringType), + method), + target); return expr.Compile(); } } @@ -109,11 +109,11 @@ private static OpenEventHandler CreateOpenHandler(MethodInfo method) public WeakDelegate(Delegate handler) { _weakTarget = handler.Target != null ? new WeakReference(handler.Target) : null; - #if NET40 || NET45 - _method = handler.Method; - #else - _method = handler.GetMethodInfo(); - #endif +#if NET40 || NET45 + _method = handler.Method; +#else + _method = handler.GetMethodInfo(); +#endif _openHandler = _openHandlerCache.GetOrAdd(_method, CreateOpenHandler); } @@ -133,13 +133,13 @@ public bool Invoke() public bool IsMatch(Callback handler) { - #if NET40 || NET45 - return _weakTarget.Target != null && ( ReferenceEquals( handler.Target, _weakTarget.Target ) - && handler.Method.Equals( _method ) ); - #else - return _weakTarget.Target != null && (ReferenceEquals(handler.Target, _weakTarget.Target) - && handler.GetMethodInfo().Equals(_method)); - #endif +#if NET40 || NET45 + return _weakTarget.Target != null && (ReferenceEquals(handler.Target, _weakTarget.Target) + && handler.Method.Equals(_method)); +#else + return _weakTarget.Target != null && (ReferenceEquals(handler.Target, _weakTarget.Target) + && handler.GetMethodInfo().Equals(_method)); +#endif } } diff --git a/src/QLNet/Patterns/observablevalue.cs b/src/QLNet/Patterns/observablevalue.cs deleted file mode 100644 index f4f2a9b08..000000000 --- a/src/QLNet/Patterns/observablevalue.cs +++ /dev/null @@ -1,79 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -namespace QLNet { - //! %observable and assignable proxy to concrete value - /*! Observers can be registered with instances of this class so - that they are notified when a different value is assigned to - such instances. Client code can copy the contained value or - pass it to functions via implicit conversion. - \note it is not possible to call non-const method on the - returned value. This is by design, as this possibility - would necessarily bypass the notification code; client - code should modify the value via re-assignment instead. - */ - public class ObservableValue : IObservable where T : new() { - private T value_; - - public ObservableValue() { - value_ = FastActivator.Create(); - } - - public ObservableValue(T t) { - value_ = t; - } - - public ObservableValue(ObservableValue t) { - value_ = t.value_; - } - - - // controlled assignment - public ObservableValue Assign(T t) { - value_ = t; - notifyObservers(); - return this; - } - - public ObservableValue Assign(ObservableValue t) { - value_ = t.value_; - notifyObservers(); - return this; - } - - //! explicit inspector - public T value() { return value_; } - - - // Subjects, i.e. observables, should define interface internally like follows. - private readonly WeakEventSource eventSource = new WeakEventSource(); - public event Callback notifyObserversEvent - { - add { eventSource.Subscribe(value); } - remove { eventSource.Unsubscribe(value); } - } - - public void registerWith(Callback handler) { notifyObserversEvent += handler; } - public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } - protected void notifyObservers() - { - eventSource.Raise(); - } - } -} diff --git a/src/QLNet/Payoff.cs b/src/QLNet/Payoff.cs new file mode 100644 index 000000000..11b38356a --- /dev/null +++ b/src/QLNet/Payoff.cs @@ -0,0 +1,43 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! Abstract base class for option payoffs + public class Payoff + { + // Payoff interface + /*! \warning This method is used for output and comparison between + payoffs. It is not meant to be used for writing + switch-on-type code. + */ + public virtual string name() { throw new NotImplementedException(); } + public virtual string description() { throw new NotImplementedException(); } + public virtual double value(double price) { throw new NotImplementedException(); } + + public virtual void accept(IAcyclicVisitor v) + { + if (v != null) + v.visit(this); + else + Utils.QL_FAIL("not an event visitor"); + } + } +} diff --git a/src/QLNet/PricingEngine.cs b/src/QLNet/PricingEngine.cs index c8578b5ce..0ff57ee4b 100644 --- a/src/QLNet/PricingEngine.cs +++ b/src/QLNet/PricingEngine.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -47,8 +47,8 @@ public interface IGenericEngine : IPricingEngine, IObserver // template base class for option pricing engines // Derived engines only need to implement the calculate() method. public abstract class GenericEngine : IGenericEngine - where ArgumentsType : IPricingEngineArguments, new() - where ResultsType : IPricingEngineResults, new() + where ArgumentsType : IPricingEngineArguments, new () + where ResultsType : IPricingEngineResults, new () { protected ArgumentsType arguments_ = FastActivator.Create(); protected ResultsType results_ = FastActivator.Create(); @@ -80,8 +80,14 @@ public virtual void calculate() public event Callback notifyObserversEvent { - add { eventSource.Subscribe(value); } - remove { eventSource.Unsubscribe(value); } + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } } public void registerWith(Callback handler) diff --git a/src/QLNet/Pricingengines/Americanpayoffatexpiry.cs b/src/QLNet/Pricingengines/Americanpayoffatexpiry.cs index 6b084c70e..ee64372a9 100644 --- a/src/QLNet/Pricingengines/Americanpayoffatexpiry.cs +++ b/src/QLNet/Pricingengines/Americanpayoffatexpiry.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,11 +23,11 @@ under the terms of the QLNet license. You should have received a namespace QLNet { //! Analytic formula for American exercise payoff at-expiry options - //! \todo calculate greeks + //! \todo calculate greeks public class AmericanPayoffAtExpiry { - public AmericanPayoffAtExpiry( double spot, double discount, double dividendDiscount, double variance, - StrikedTypePayoff payoff, bool knock_in = true ) + public AmericanPayoffAtExpiry(double spot, double discount, double dividendDiscount, double variance, + StrikedTypePayoff payoff, bool knock_in = true) { spot_ = spot; discount_ = discount; @@ -35,70 +35,70 @@ public AmericanPayoffAtExpiry( double spot, double discount, double dividendDisc variance_ = variance; knock_in_ = knock_in; - Utils.QL_REQUIRE( spot_ > 0.0,()=> "positive spot value required" ); - Utils.QL_REQUIRE( discount_ > 0.0, () => "positive discount required" ); - Utils.QL_REQUIRE( dividendDiscount_ > 0.0, () => "positive dividend discount required" ); - Utils.QL_REQUIRE( variance_ >= 0.0, () => "negative variance not allowed" ); + Utils.QL_REQUIRE(spot_ > 0.0, () => "positive spot value required"); + Utils.QL_REQUIRE(discount_ > 0.0, () => "positive discount required"); + Utils.QL_REQUIRE(dividendDiscount_ > 0.0, () => "positive dividend discount required"); + Utils.QL_REQUIRE(variance_ >= 0.0, () => "negative variance not allowed"); - stdDev_ = Math.Sqrt( variance_ ); + stdDev_ = Math.Sqrt(variance_); Option.Type type = payoff.optionType(); strike_ = payoff.strike(); forward_ = spot_ * dividendDiscount_ / discount_; - mu_ = Math.Log( dividendDiscount_ / discount_ ) / variance_ - 0.5; + mu_ = Math.Log(dividendDiscount_ / discount_) / variance_ - 0.5; // binary cash-or-nothing payoff? CashOrNothingPayoff coo = payoff as CashOrNothingPayoff; - if ( coo != null ) + if (coo != null) { K_ = coo.cashPayoff(); } // binary asset-or-nothing payoff? AssetOrNothingPayoff aoo = payoff as AssetOrNothingPayoff; - if ( aoo != null ) + if (aoo != null) { K_ = forward_; mu_ += 1.0; } - log_H_S_ = Math.Log( strike_ / spot_ ); - double log_S_H_ = Math.Log(spot_/strike_); + log_H_S_ = Math.Log(strike_ / spot_); + double log_S_H_ = Math.Log(spot_ / strike_); double eta = 0.0; double phi = 0.0; - - switch (type) + + switch (type) { case Option.Type.Call: - if (knock_in_) + if (knock_in_) { // up-and-in cash-(at-expiry)-or-nothing option // a.k.a. american call with cash-or-nothing payoff eta = -1.0; phi = 1.0; - } - else + } + else { // up-and-out cash-(at-expiry)-or-nothing option - eta = -1.0; - phi = -1.0; + eta = -1.0; + phi = -1.0; } break; case Option.Type.Put: - if (knock_in_) + if (knock_in_) { // down-and-in cash-(at-expiry)-or-nothing option // a.k.a. american put with cash-or-nothing payoff eta = 1.0; phi = -1.0; - } - else + } + else { // down-and-out cash-(at-expiry)-or-nothing option - eta = 1.0; - phi = 1.0; + eta = 1.0; + phi = 1.0; } break; default: @@ -107,24 +107,24 @@ public AmericanPayoffAtExpiry( double spot, double discount, double dividendDisc } - if ( variance_ >= Const.QL_EPSILON ) + if (variance_ >= Const.QL_EPSILON) { - D1_ = phi * ( log_S_H_ / stdDev_ + mu_ * stdDev_ ); - D2_ = eta * ( log_H_S_ / stdDev_ + mu_ * stdDev_ ); + D1_ = phi * (log_S_H_ / stdDev_ + mu_ * stdDev_); + D2_ = eta * (log_H_S_ / stdDev_ + mu_ * stdDev_); CumulativeNormalDistribution f = new CumulativeNormalDistribution(); - cum_d1_ = f.value( D1_ ); - cum_d2_ = f.value( D2_ ); - n_d1_ = f.derivative( D1_ ); - n_d2_ = f.derivative( D2_ ); + cum_d1_ = f.value(D1_); + cum_d2_ = f.value(D2_); + n_d1_ = f.derivative(D1_); + n_d2_ = f.derivative(D2_); } else { - if ( log_S_H_ * phi > 0 ) + if (log_S_H_ * phi > 0) cum_d1_ = 1.0; else cum_d1_ = 0.0; - if ( log_H_S_ * eta > 0 ) + if (log_H_S_ * eta > 0) cum_d2_ = 1.0; else cum_d2_ = 0.0; @@ -132,20 +132,20 @@ public AmericanPayoffAtExpiry( double spot, double discount, double dividendDisc n_d1_ = 0.0; n_d2_ = 0.0; } - - switch (type) + + switch (type) { case Option.Type.Call: - if (strike_<=spot_) + if (strike_ <= spot_) { - if (knock_in_) + if (knock_in_) { // up-and-in cash-(at-expiry)-or-nothing option // a.k.a. american call with cash-or-nothing payoff cum_d1_ = 0.5; cum_d2_ = 0.5; - } - else + } + else { // up-and-out cash-(at-expiry)-or-nothing option // already knocked out @@ -157,18 +157,18 @@ public AmericanPayoffAtExpiry( double spot, double discount, double dividendDisc } break; case Option.Type.Put: - if (strike_>=spot_) + if (strike_ >= spot_) { - if (knock_in_) + if (knock_in_) { - // down-and-in cash-(at-expiry)-or-nothing option - // a.k.a. american put with cash-or-nothing payoff + // down-and-in cash-(at-expiry)-or-nothing option + // a.k.a. american put with cash-or-nothing payoff cum_d1_ = 0.5; cum_d2_ = 0.5; - } - else + } + else { - // down-and-out cash-(at-expiry)-or-nothing option + // down-and-out cash-(at-expiry)-or-nothing option // already knocked out cum_d1_ = 0.0; cum_d2_ = 0.0; @@ -183,9 +183,9 @@ public AmericanPayoffAtExpiry( double spot, double discount, double dividendDisc } - inTheMoney_ = ( type == Option.Type.Call && strike_ < spot_ ) || - ( type == Option.Type.Put && strike_ > spot_ ); - if ( inTheMoney_ ) + inTheMoney_ = (type == Option.Type.Call && strike_ < spot_) || + (type == Option.Type.Put && strike_ > spot_); + if (inTheMoney_) { X_ = 1.0; Y_ = 1.0; @@ -194,17 +194,17 @@ public AmericanPayoffAtExpiry( double spot, double discount, double dividendDisc { X_ = 1.0; if (cum_d2_.IsEqual(0.0)) - Y_ = 0.0; // check needed on some extreme cases + Y_ = 0.0; // check needed on some extreme cases else - Y_ = Math.Pow((strike_/spot_),(2.0*mu_)); + Y_ = Math.Pow((strike_ / spot_), (2.0 * mu_)); } - if ( !knock_in_ ) - Y_ *= -1.0; + if (!knock_in_) + Y_ *= -1.0; } public double value() { - return discount_ * K_ * ( X_ * cum_d1_ + Y_ * cum_d2_ ); + return discount_ * K_ * (X_ * cum_d1_ + Y_ * cum_d2_); } diff --git a/src/QLNet/Pricingengines/Americanpayoffathit.cs b/src/QLNet/Pricingengines/Americanpayoffathit.cs index 4aa2b27a3..bb8f31c77 100644 --- a/src/QLNet/Pricingengines/Americanpayoffathit.cs +++ b/src/QLNet/Pricingengines/Americanpayoffathit.cs @@ -1,247 +1,289 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - - //! Analytic formula for American exercise payoff at-hit options - //! \todo calculate greeks - public class AmericanPayoffAtHit { - private double spot_; - private double discount_; - private double dividendDiscount_; - private double variance_; - private double stdDev_; - - private double strike_; - private double K_; - - private double mu_; - private double lambda_; - private double muPlusLambda_; - private double muMinusLambda_; - private double log_H_S_; - - private double D1_; - private double D2_; - - private double alpha_; - private double beta_; - private double DalphaDd1_; - private double DbetaDd2_; - - private bool inTheMoney_; - private double forward_; - private double X_; - - public AmericanPayoffAtHit(double spot, double discount, double dividendDiscount, double variance, StrikedTypePayoff payoff) { - spot_ = spot; - discount_ = discount; - dividendDiscount_ = dividendDiscount; - variance_ = variance; - - Utils.QL_REQUIRE(spot_ > 0.0,()=> "positive spot value required"); - Utils.QL_REQUIRE(discount_ > 0.0,()=> "positive discount required"); - Utils.QL_REQUIRE(dividendDiscount_ > 0.0,()=> "positive dividend discount required"); - Utils.QL_REQUIRE(variance_ >= 0.0,()=> "negative variance not allowed"); - - stdDev_ = Math.Sqrt(variance_); - - Option.Type type = payoff.optionType(); - strike_ = payoff.strike(); - - - log_H_S_ = Math.Log(strike_ / spot_); - - double n_d1; - double n_d2; - double cum_d1_; - double cum_d2_; - if (variance_ >= Const.QL_EPSILON) { - if (discount_ .IsEqual(0.0) && dividendDiscount_.IsEqual(0.0)) { - mu_ = -0.5; - lambda_ = 0.5; - } else if (discount_.IsEqual(0.0)) { - Utils.QL_FAIL("null discount not handled yet"); - } else { - mu_ = Math.Log(dividendDiscount_ / discount_) / variance_ - 0.5; - lambda_ = Math.Sqrt(mu_ * mu_ - 2.0 * Math.Log(discount_) / variance_); - } - D1_ = log_H_S_ / stdDev_ + lambda_ * stdDev_; - D2_ = D1_ - 2.0 * lambda_ * stdDev_; - CumulativeNormalDistribution f = new CumulativeNormalDistribution(); - cum_d1_ = f.value(D1_); - cum_d2_ = f.value(D2_); - n_d1 = f.derivative(D1_); - n_d2 = f.derivative(D2_); - } else { - // not tested yet - mu_ = Math.Log(dividendDiscount_ / discount_) / variance_ - 0.5; - lambda_ = Math.Sqrt(mu_ * mu_ - 2.0 * Math.Log(discount_) / variance_); - if (log_H_S_ > 0) { - cum_d1_ = 1.0; - cum_d2_ = 1.0; - } else { - cum_d1_ = 0.0; - cum_d2_ = 0.0; - } - n_d1 = 0.0; - n_d2 = 0.0; +namespace QLNet +{ + + //! Analytic formula for American exercise payoff at-hit options + //! \todo calculate greeks + public class AmericanPayoffAtHit + { + private double spot_; + private double discount_; + private double dividendDiscount_; + private double variance_; + private double stdDev_; + + private double strike_; + private double K_; + + private double mu_; + private double lambda_; + private double muPlusLambda_; + private double muMinusLambda_; + private double log_H_S_; + + private double D1_; + private double D2_; + + private double alpha_; + private double beta_; + private double DalphaDd1_; + private double DbetaDd2_; + + private bool inTheMoney_; + private double forward_; + private double X_; + + public AmericanPayoffAtHit(double spot, double discount, double dividendDiscount, double variance, StrikedTypePayoff payoff) + { + spot_ = spot; + discount_ = discount; + dividendDiscount_ = dividendDiscount; + variance_ = variance; + + Utils.QL_REQUIRE(spot_ > 0.0, () => "positive spot value required"); + Utils.QL_REQUIRE(discount_ > 0.0, () => "positive discount required"); + Utils.QL_REQUIRE(dividendDiscount_ > 0.0, () => "positive dividend discount required"); + Utils.QL_REQUIRE(variance_ >= 0.0, () => "negative variance not allowed"); + + stdDev_ = Math.Sqrt(variance_); + + Option.Type type = payoff.optionType(); + strike_ = payoff.strike(); + + + log_H_S_ = Math.Log(strike_ / spot_); + + double n_d1; + double n_d2; + double cum_d1_; + double cum_d2_; + if (variance_ >= Const.QL_EPSILON) + { + if (discount_ .IsEqual(0.0) && dividendDiscount_.IsEqual(0.0)) + { + mu_ = -0.5; + lambda_ = 0.5; } - - - switch (type) { - // up-and-in cash-(at-hit)-or-nothing option - // a.k.a. american call with cash-or-nothing payoff - case Option.Type.Call: - if (strike_ > spot_) { - alpha_ = 1.0 - cum_d1_; // N(-d1) - DalphaDd1_ = -n_d1; // -n( d1) - beta_ = 1.0 - cum_d2_; // N(-d2) - DbetaDd2_ = -n_d2; // -n( d2) - } else { - alpha_ = 0.5; - DalphaDd1_ = 0.0; - beta_ = 0.5; - DbetaDd2_ = 0.0; - } - break; - // down-and-in cash-(at-hit)-or-nothing option - // a.k.a. american put with cash-or-nothing payoff - case Option.Type.Put: - if (strike_ < spot_) { - alpha_ = cum_d1_; // N(d1) - DalphaDd1_ = n_d1; // n(d1) - beta_ = cum_d2_; // N(d2) - DbetaDd2_ = n_d2; // n(d2) - } else { - alpha_ = 0.5; - DalphaDd1_ = 0.0; - beta_ = 0.5; - DbetaDd2_ = 0.0; - } - break; - default: - Utils.QL_FAIL("invalid option type"); - break; + else if (discount_.IsEqual(0.0)) + { + Utils.QL_FAIL("null discount not handled yet"); } - - - muPlusLambda_ = mu_ + lambda_; - muMinusLambda_ = mu_ - lambda_; - inTheMoney_ = (type == Option.Type.Call && strike_ < spot_) || (type == Option.Type.Put && strike_ > spot_); - - if (inTheMoney_) { - forward_ = 1.0; - X_ = 1.0; - } else { - forward_ = Math.Pow(strike_ / spot_, muPlusLambda_); - X_ = Math.Pow(strike_ / spot_, muMinusLambda_); + else + { + mu_ = Math.Log(dividendDiscount_ / discount_) / variance_ - 0.5; + lambda_ = Math.Sqrt(mu_ * mu_ - 2.0 * Math.Log(discount_) / variance_); } - - - // Binary Cash-Or-Nothing payoff? - CashOrNothingPayoff coo = payoff as CashOrNothingPayoff; - if (coo != null) { - K_ = coo.cashPayoff(); + D1_ = log_H_S_ / stdDev_ + lambda_ * stdDev_; + D2_ = D1_ - 2.0 * lambda_ * stdDev_; + CumulativeNormalDistribution f = new CumulativeNormalDistribution(); + cum_d1_ = f.value(D1_); + cum_d2_ = f.value(D2_); + n_d1 = f.derivative(D1_); + n_d2 = f.derivative(D2_); + } + else + { + // not tested yet + mu_ = Math.Log(dividendDiscount_ / discount_) / variance_ - 0.5; + lambda_ = Math.Sqrt(mu_ * mu_ - 2.0 * Math.Log(discount_) / variance_); + if (log_H_S_ > 0) + { + cum_d1_ = 1.0; + cum_d2_ = 1.0; } - - // Binary Asset-Or-Nothing payoff? - AssetOrNothingPayoff aoo = payoff as AssetOrNothingPayoff; - - if (aoo != null) { - if (inTheMoney_) { - K_ = spot_; - } else { - K_ = aoo.strike(); - } + else + { + cum_d1_ = 0.0; + cum_d2_ = 0.0; } - } - - // inline definitions - public double value() { - return K_ * (forward_ * alpha_ + X_ * beta_); - } - - public double delta() { - double tempDelta = -spot_ * stdDev_; - double DalphaDs = DalphaDd1_ / tempDelta; - double DbetaDs = DbetaDd2_ / tempDelta; - - double DforwardDs; - double DXDs; - if (inTheMoney_) { - DforwardDs = 0.0; - DXDs = 0.0; - } else { - DforwardDs = -muPlusLambda_ * forward_ / spot_; - DXDs = -muMinusLambda_ * X_ / spot_; + n_d1 = 0.0; + n_d2 = 0.0; + } + + + switch (type) + { + // up-and-in cash-(at-hit)-or-nothing option + // a.k.a. american call with cash-or-nothing payoff + case Option.Type.Call: + if (strike_ > spot_) + { + alpha_ = 1.0 - cum_d1_; // N(-d1) + DalphaDd1_ = -n_d1; // -n( d1) + beta_ = 1.0 - cum_d2_; // N(-d2) + DbetaDd2_ = -n_d2; // -n( d2) + } + else + { + alpha_ = 0.5; + DalphaDd1_ = 0.0; + beta_ = 0.5; + DbetaDd2_ = 0.0; + } + break; + // down-and-in cash-(at-hit)-or-nothing option + // a.k.a. american put with cash-or-nothing payoff + case Option.Type.Put: + if (strike_ < spot_) + { + alpha_ = cum_d1_; // N(d1) + DalphaDd1_ = n_d1; // n(d1) + beta_ = cum_d2_; // N(d2) + DbetaDd2_ = n_d2; // n(d2) + } + else + { + alpha_ = 0.5; + DalphaDd1_ = 0.0; + beta_ = 0.5; + DbetaDd2_ = 0.0; + } + break; + default: + Utils.QL_FAIL("invalid option type"); + break; + } + + + muPlusLambda_ = mu_ + lambda_; + muMinusLambda_ = mu_ - lambda_; + inTheMoney_ = (type == Option.Type.Call && strike_ < spot_) || (type == Option.Type.Put && strike_ > spot_); + + if (inTheMoney_) + { + forward_ = 1.0; + X_ = 1.0; + } + else + { + forward_ = Math.Pow(strike_ / spot_, muPlusLambda_); + X_ = Math.Pow(strike_ / spot_, muMinusLambda_); + } + + + // Binary Cash-Or-Nothing payoff? + CashOrNothingPayoff coo = payoff as CashOrNothingPayoff; + if (coo != null) + { + K_ = coo.cashPayoff(); + } + + // Binary Asset-Or-Nothing payoff? + AssetOrNothingPayoff aoo = payoff as AssetOrNothingPayoff; + + if (aoo != null) + { + if (inTheMoney_) + { + K_ = spot_; } - - return K_ * (DalphaDs * forward_ + alpha_ * DforwardDs + DbetaDs * X_ + beta_ * DXDs); - } - - public double gamma() { - double tempDelta = -spot_ * stdDev_; - double DalphaDs = DalphaDd1_ / tempDelta; - double DbetaDs = DbetaDd2_ / tempDelta; - double D2alphaDs2 = -DalphaDs / spot_ * (1 - D1_ / stdDev_); - double D2betaDs2 = -DbetaDs / spot_ * (1 - D2_ / stdDev_); - - double DforwardDs; - double DXDs; - double D2forwardDs2; - double D2XDs2; - if (inTheMoney_) { - DforwardDs = 0.0; - DXDs = 0.0; - D2forwardDs2 = 0.0; - D2XDs2 = 0.0; - } else { - DforwardDs = -muPlusLambda_ * forward_ / spot_; - DXDs = -muMinusLambda_ * X_ / spot_; - D2forwardDs2 = muPlusLambda_ * forward_ / (spot_ * spot_) * (1 + muPlusLambda_); - D2XDs2 = muMinusLambda_ * X_ / (spot_ * spot_) * (1 + muMinusLambda_); + else + { + K_ = aoo.strike(); } - - return K_ * (D2alphaDs2 * forward_ + DalphaDs * DforwardDs + DalphaDs * DforwardDs + alpha_ * D2forwardDs2 + D2betaDs2 * X_ + DbetaDs * DXDs + DbetaDs * DXDs + beta_ * D2XDs2); - - } - - public double rho(double maturity) { - Utils.QL_REQUIRE(maturity >= 0.0,()=> "negative maturity not allowed"); - - // actually D.Dr / T - double DalphaDr = -DalphaDd1_ / (lambda_ * stdDev_) * (1.0 + mu_); - double DbetaDr = DbetaDd2_ / (lambda_ * stdDev_) * (1.0 + mu_); - double DforwardDr; - double DXDr; - if (inTheMoney_) { - DforwardDr = 0.0; - DXDr = 0.0; - } else { - DforwardDr = forward_ * (1.0 + (1.0 + mu_) / lambda_) * log_H_S_ / variance_; - DXDr = X_ * (1.0 - (1.0 + mu_) / lambda_) * log_H_S_ / variance_; - } - - return maturity * K_ * (DalphaDr * forward_ + alpha_ * DforwardDr + DbetaDr * X_ + beta_ * DXDr); - } - } + } + } + + // inline definitions + public double value() + { + return K_ * (forward_ * alpha_ + X_ * beta_); + } + + public double delta() + { + double tempDelta = -spot_ * stdDev_; + double DalphaDs = DalphaDd1_ / tempDelta; + double DbetaDs = DbetaDd2_ / tempDelta; + + double DforwardDs; + double DXDs; + if (inTheMoney_) + { + DforwardDs = 0.0; + DXDs = 0.0; + } + else + { + DforwardDs = -muPlusLambda_ * forward_ / spot_; + DXDs = -muMinusLambda_ * X_ / spot_; + } + + return K_ * (DalphaDs * forward_ + alpha_ * DforwardDs + DbetaDs * X_ + beta_ * DXDs); + } + + public double gamma() + { + double tempDelta = -spot_ * stdDev_; + double DalphaDs = DalphaDd1_ / tempDelta; + double DbetaDs = DbetaDd2_ / tempDelta; + double D2alphaDs2 = -DalphaDs / spot_ * (1 - D1_ / stdDev_); + double D2betaDs2 = -DbetaDs / spot_ * (1 - D2_ / stdDev_); + + double DforwardDs; + double DXDs; + double D2forwardDs2; + double D2XDs2; + if (inTheMoney_) + { + DforwardDs = 0.0; + DXDs = 0.0; + D2forwardDs2 = 0.0; + D2XDs2 = 0.0; + } + else + { + DforwardDs = -muPlusLambda_ * forward_ / spot_; + DXDs = -muMinusLambda_ * X_ / spot_; + D2forwardDs2 = muPlusLambda_ * forward_ / (spot_ * spot_) * (1 + muPlusLambda_); + D2XDs2 = muMinusLambda_ * X_ / (spot_ * spot_) * (1 + muMinusLambda_); + } + + return K_ * (D2alphaDs2 * forward_ + DalphaDs * DforwardDs + DalphaDs * DforwardDs + alpha_ * D2forwardDs2 + D2betaDs2 * X_ + DbetaDs * DXDs + DbetaDs * DXDs + beta_ * D2XDs2); + + } + + public double rho(double maturity) + { + Utils.QL_REQUIRE(maturity >= 0.0, () => "negative maturity not allowed"); + + // actually D.Dr / T + double DalphaDr = -DalphaDd1_ / (lambda_ * stdDev_) * (1.0 + mu_); + double DbetaDr = DbetaDd2_ / (lambda_ * stdDev_) * (1.0 + mu_); + double DforwardDr; + double DXDr; + if (inTheMoney_) + { + DforwardDr = 0.0; + DXDr = 0.0; + } + else + { + DforwardDr = forward_ * (1.0 + (1.0 + mu_) / lambda_) * log_H_S_ / variance_; + DXDr = X_ * (1.0 - (1.0 + mu_) / lambda_) * log_H_S_ / variance_; + } + + return maturity * K_ * (DalphaDr * forward_ + alpha_ * DforwardDr + DbetaDr * X_ + beta_ * DXDr); + } + } } diff --git a/src/QLNet/Pricingengines/Basket/KirkEngine.cs b/src/QLNet/Pricingengines/Basket/KirkEngine.cs index b7080b2cb..2dcae36c4 100644 --- a/src/QLNet/Pricingengines/Basket/KirkEngine.cs +++ b/src/QLNet/Pricingengines/Basket/KirkEngine.cs @@ -1,20 +1,20 @@ -// +// // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. -// +// using System; @@ -23,7 +23,7 @@ namespace QLNet //! Pricing engine for spread option on two futures /*! This class implements formulae from "Correlation in the Energy Markets", E. Kirk - Managing Energy Price Risk. + Managing Energy Price Risk. London: Risk Publications and Enron, pp. 71-78 \ingroup basketengines @@ -33,9 +33,9 @@ reproducing results available in literature. */ public class KirkEngine : BasketOption.Engine { - public KirkEngine( BlackProcess process1, - BlackProcess process2, - double correlation) + public KirkEngine(BlackProcess process1, + BlackProcess process2, + double correlation) { process1_ = process1; process2_ = process2; @@ -47,19 +47,19 @@ public KirkEngine( BlackProcess process1, public override void calculate() { - - Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European,()=> "not an European Option"); + + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European Option"); EuropeanExercise exercise = arguments_.exercise as EuropeanExercise; - Utils.QL_REQUIRE(exercise!=null,()=> "not an European Option"); + Utils.QL_REQUIRE(exercise != null, () => "not an European Option"); SpreadBasketPayoff spreadPayoff = arguments_.payoff as SpreadBasketPayoff; - Utils.QL_REQUIRE(spreadPayoff!=null,()=>" spread payoff expected"); + Utils.QL_REQUIRE(spreadPayoff != null, () => " spread payoff expected"); PlainVanillaPayoff payoff = spreadPayoff.basePayoff() as PlainVanillaPayoff; - Utils.QL_REQUIRE(payoff!= null, ()=> "non-plain payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); double strike = payoff.strike(); - + double f1 = process1_.stateVariable().link.value(); double f2 = process2_.stateVariable().link.value(); @@ -70,18 +70,18 @@ public override void calculate() double riskFreeDiscount = process1_.riskFreeRate().link.discount(exercise.lastDate()); Func Square = x => x * x; - double f = f1/(f2 + strike); - double v = Math.Sqrt( variance1 - + variance2 * Square( f2 / ( f2 + strike ) ) - - 2*rho_*Math.Sqrt(variance1*variance2) - *(f2/(f2+strike))); - - BlackCalculator black = new BlackCalculator( new PlainVanillaPayoff(payoff.optionType(),1.0), f, v, riskFreeDiscount); - - results_.value = (f2 + strike)*black.value(); - + double f = f1 / (f2 + strike); + double v = Math.Sqrt(variance1 + + variance2 * Square(f2 / (f2 + strike)) + - 2 * rho_ * Math.Sqrt(variance1 * variance2) + * (f2 / (f2 + strike))); + + BlackCalculator black = new BlackCalculator(new PlainVanillaPayoff(payoff.optionType(), 1.0), f, v, riskFreeDiscount); + + results_.value = (f2 + strike) * black.value(); + } - + private BlackProcess process1_; private BlackProcess process2_; private double rho_; diff --git a/src/QLNet/Pricingengines/Basket/MCEuropeanBasketEngine.cs b/src/QLNet/Pricingengines/Basket/MCEuropeanBasketEngine.cs index b0f6aec19..1fd53edc1 100644 --- a/src/QLNet/Pricingengines/Basket/MCEuropeanBasketEngine.cs +++ b/src/QLNet/Pricingengines/Basket/MCEuropeanBasketEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,8 +20,8 @@ namespace QLNet \test the correctness of the returned value is tested by reproducing results available in literature. - - */ + + */ class MCEuropeanBasketEngine { } diff --git a/src/QLNet/Pricingengines/Basket/StulzEngine.cs b/src/QLNet/Pricingengines/Basket/StulzEngine.cs index 62a6c20ed..5d5abecdb 100644 --- a/src/QLNet/Pricingengines/Basket/StulzEngine.cs +++ b/src/QLNet/Pricingengines/Basket/StulzEngine.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -37,7 +37,7 @@ reproducing results available in literature. */ public class StulzEngine : BasketOption.Engine { - public StulzEngine(GeneralizedBlackScholesProcess process1,GeneralizedBlackScholesProcess process2,double correlation) + public StulzEngine(GeneralizedBlackScholesProcess process1, GeneralizedBlackScholesProcess process2, double correlation) { process1_ = process1; process2_ = process2; @@ -47,23 +47,23 @@ public StulzEngine(GeneralizedBlackScholesProcess process1,GeneralizedBlackSchol } public override void calculate() { - - Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European,()=> "not an European Option"); + + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European Option"); EuropeanExercise exercise = arguments_.exercise as EuropeanExercise; - Utils.QL_REQUIRE(exercise!=null,()=> "not an European Option"); + Utils.QL_REQUIRE(exercise != null, () => "not an European Option"); BasketPayoff basket_payoff = arguments_.payoff as BasketPayoff; MinBasketPayoff min_basket = arguments_.payoff as MinBasketPayoff; MaxBasketPayoff max_basket = arguments_.payoff as MaxBasketPayoff; - - Utils.QL_REQUIRE(min_basket != null || max_basket!= null, ()=> "unknown basket type"); + + Utils.QL_REQUIRE(min_basket != null || max_basket != null, () => "unknown basket type"); PlainVanillaPayoff payoff = basket_payoff.basePayoff() as PlainVanillaPayoff; - - Utils.QL_REQUIRE(payoff!=null,()=> "non-plain payoff given"); + + Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); double strike = payoff.strike(); @@ -79,62 +79,62 @@ public override void calculate() double forward1 = process1_.stateVariable().link.value() * dividendDiscount1 / riskFreeDiscount; double forward2 = process2_.stateVariable().link.value() * dividendDiscount2 / riskFreeDiscount; - if (max_basket!=null) + if (max_basket != null) { - switch (payoff.optionType()) + switch (payoff.optionType()) { // euro call on a two asset max basket case Option.Type.Call: results_.value = euroTwoAssetMaxBasketCall(forward1, forward2, strike, - riskFreeDiscount, - variance1, variance2, - rho_); + riskFreeDiscount, + variance1, variance2, + rho_); break; // euro put on a two asset max basket case Option.Type.Put: results_.value = strike * riskFreeDiscount - - euroTwoAssetMaxBasketCall(forward1, forward2, 0.0, - riskFreeDiscount, - variance1, variance2, rho_) + - euroTwoAssetMaxBasketCall(forward1, forward2, strike, - riskFreeDiscount, - variance1, variance2, rho_); + euroTwoAssetMaxBasketCall(forward1, forward2, 0.0, + riskFreeDiscount, + variance1, variance2, rho_) + + euroTwoAssetMaxBasketCall(forward1, forward2, strike, + riskFreeDiscount, + variance1, variance2, rho_); break; default: Utils.QL_FAIL("unknown option type"); break; - + } - } - else if (min_basket != null) + } + else if (min_basket != null) { - switch (payoff.optionType()) + switch (payoff.optionType()) { // euro call on a two asset min basket case Option.Type.Call: results_.value = euroTwoAssetMinBasketCall(forward1, forward2, strike, - riskFreeDiscount, - variance1, variance2, - rho_); + riskFreeDiscount, + variance1, variance2, + rho_); break; // euro put on a two asset min basket case Option.Type.Put: results_.value = strike * riskFreeDiscount - - euroTwoAssetMinBasketCall(forward1, forward2, 0.0, - riskFreeDiscount, - variance1, variance2, rho_) + - euroTwoAssetMinBasketCall(forward1, forward2, strike, - riskFreeDiscount, - variance1, variance2, rho_); + euroTwoAssetMinBasketCall(forward1, forward2, 0.0, + riskFreeDiscount, + variance1, variance2, rho_) + + euroTwoAssetMinBasketCall(forward1, forward2, strike, + riskFreeDiscount, + variance1, variance2, rho_); break; default: Utils.QL_FAIL("unknown option type"); break; } - - } - else + + } + else { Utils.QL_FAIL("unknown type"); } @@ -142,62 +142,62 @@ public override void calculate() } // calculate the value of euro min basket call - private double euroTwoAssetMinBasketCall( double forward1, double forward2,double strike,double riskFreeDiscount, - double variance1, double variance2,double rho ) + private double euroTwoAssetMinBasketCall(double forward1, double forward2, double strike, double riskFreeDiscount, + double variance1, double variance2, double rho) { double stdDev1 = Math.Sqrt(variance1); double stdDev2 = Math.Sqrt(variance2); - double variance = variance1 + variance2 - 2*rho*stdDev1*stdDev2; + double variance = variance1 + variance2 - 2 * rho * stdDev1 * stdDev2; double stdDev = Math.Sqrt(variance); double modRho1 = (rho * stdDev2 - stdDev1) / stdDev; double modRho2 = (rho * stdDev1 - stdDev2) / stdDev; - double D1 = (Math.Log(forward1/forward2) + 0.5*variance) / stdDev; + double D1 = (Math.Log(forward1 / forward2) + 0.5 * variance) / stdDev; double alfa, beta, gamma; - if (strike.IsNotEqual(0.0)) + if (strike.IsNotEqual(0.0)) { BivariateCumulativeNormalDistribution bivCNorm = new BivariateCumulativeNormalDistribution(rho); BivariateCumulativeNormalDistribution bivCNormMod2 = new BivariateCumulativeNormalDistribution(modRho2); BivariateCumulativeNormalDistribution bivCNormMod1 = new BivariateCumulativeNormalDistribution(modRho1); - double D1_1 = (Math.Log(forward1/strike) + 0.5*variance1) / stdDev1; - double D1_2 = (Math.Log(forward2/strike) + 0.5*variance2) / stdDev2; + double D1_1 = (Math.Log(forward1 / strike) + 0.5 * variance1) / stdDev1; + double D1_2 = (Math.Log(forward2 / strike) + 0.5 * variance2) / stdDev2; alfa = bivCNormMod1.value(D1_1, -D1); beta = bivCNormMod2.value(D1_2, D1 - stdDev); gamma = bivCNorm.value(D1_1 - stdDev1, D1_2 - stdDev2); - } - else + } + else { - CumulativeNormalDistribution cum = new CumulativeNormalDistribution(); - alfa = cum.value(-D1); - beta = cum.value(D1 - stdDev); - gamma = 1.0; + CumulativeNormalDistribution cum = new CumulativeNormalDistribution(); + alfa = cum.value(-D1); + beta = cum.value(D1 - stdDev); + gamma = 1.0; } - return riskFreeDiscount * (forward1*alfa + forward2*beta - strike*gamma); + return riskFreeDiscount * (forward1 * alfa + forward2 * beta - strike * gamma); } - + // calculate the value of euro max basket call - private double euroTwoAssetMaxBasketCall(double forward1, double forward2,double strike,double riskFreeDiscount, - double variance1, double variance2,double rho) + private double euroTwoAssetMaxBasketCall(double forward1, double forward2, double strike, double riskFreeDiscount, + double variance1, double variance2, double rho) { StrikedTypePayoff payoff = new PlainVanillaPayoff(Option.Type.Call, strike); - double black1 = Utils.blackFormula(payoff.optionType(), payoff.strike(),forward1, + double black1 = Utils.blackFormula(payoff.optionType(), payoff.strike(), forward1, Math.Sqrt(variance1)) * riskFreeDiscount; - double black2 = Utils.blackFormula(payoff.optionType(), payoff.strike(),forward2, + double black2 = Utils.blackFormula(payoff.optionType(), payoff.strike(), forward2, Math.Sqrt(variance2)) * riskFreeDiscount; return black1 + black2 - - euroTwoAssetMinBasketCall(forward1, forward2, strike, - riskFreeDiscount, - variance1, variance2, rho); - } + euroTwoAssetMinBasketCall(forward1, forward2, strike, + riskFreeDiscount, + variance1, variance2, rho); + } private GeneralizedBlackScholesProcess process1_; private GeneralizedBlackScholesProcess process2_; diff --git a/src/QLNet/Pricingengines/BlackCalculator.cs b/src/QLNet/Pricingengines/BlackCalculator.cs index cfb8cc67d..4cbb1f4d9 100644 --- a/src/QLNet/Pricingengines/BlackCalculator.cs +++ b/src/QLNet/Pricingengines/BlackCalculator.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,345 +19,386 @@ under the terms of the QLNet license. You should have received a using System; using System.Reflection; -namespace QLNet { - //! Black 1976 calculator class - /*! \bug When the variance is null, division by zero occur during - the calculation of delta, delta forward, gamma, gamma - forward, rho, dividend rho, vega, and strike sensitivity. - */ - public class BlackCalculator { - protected double strike_, forward_, stdDev_, discount_, variance_; - double D1_, D2_, alpha_, beta_, DalphaDd1_, DbetaDd2_; - double n_d1_, cum_d1_, n_d2_, cum_d2_; - double X_, DXDs_, DXDstrike_; - - public BlackCalculator(StrikedTypePayoff payoff, double forward, double stdDev, double discount) { - strike_ = payoff.strike(); - forward_ = forward; - stdDev_ = stdDev; - discount_ = discount; - variance_ = stdDev*stdDev; - - Utils.QL_REQUIRE(forward>0.0,()=> "positive forward value required: " + forward + " not allowed"); - Utils.QL_REQUIRE(stdDev>=0.0,()=> "non-negative standard deviation required: " + stdDev + " not allowed"); - Utils.QL_REQUIRE(discount>0.0,()=> "positive discount required: " + discount + " not allowed"); - - if (stdDev_>=Const.QL_EPSILON) { - if (strike_.IsEqual(0.0)) { - n_d1_ = 0.0; - n_d2_ = 0.0; - cum_d1_ = 1.0; - cum_d2_= 1.0; - } else { - D1_ = Math.Log(forward/strike_)/stdDev_ + 0.5*stdDev_; - D2_ = D1_-stdDev_; - CumulativeNormalDistribution f = new CumulativeNormalDistribution(); - cum_d1_ = f.value(D1_); - cum_d2_= f.value(D2_); - n_d1_ = f.derivative(D1_); - n_d2_ = f.derivative(D2_); - } - } else { - if (forward>strike_) { - cum_d1_ = 1.0; - cum_d2_= 1.0; - } else { - cum_d1_ = 0.0; - cum_d2_= 0.0; - } - n_d1_ = 0.0; - n_d2_ = 0.0; +namespace QLNet +{ + //! Black 1976 calculator class + /*! \bug When the variance is null, division by zero occur during + the calculation of delta, delta forward, gamma, gamma + forward, rho, dividend rho, vega, and strike sensitivity. + */ + public class BlackCalculator + { + protected double strike_, forward_, stdDev_, discount_, variance_; + double D1_, D2_, alpha_, beta_, DalphaDd1_, DbetaDd2_; + double n_d1_, cum_d1_, n_d2_, cum_d2_; + double X_, DXDs_, DXDstrike_; + + public BlackCalculator(StrikedTypePayoff payoff, double forward, double stdDev, double discount) + { + strike_ = payoff.strike(); + forward_ = forward; + stdDev_ = stdDev; + discount_ = discount; + variance_ = stdDev * stdDev; + + Utils.QL_REQUIRE(forward > 0.0, () => "positive forward value required: " + forward + " not allowed"); + Utils.QL_REQUIRE(stdDev >= 0.0, () => "non-negative standard deviation required: " + stdDev + " not allowed"); + Utils.QL_REQUIRE(discount > 0.0, () => "positive discount required: " + discount + " not allowed"); + + if (stdDev_ >= Const.QL_EPSILON) + { + if (strike_.IsEqual(0.0)) + { + n_d1_ = 0.0; + n_d2_ = 0.0; + cum_d1_ = 1.0; + cum_d2_ = 1.0; } - - X_ = strike_; - DXDstrike_ = 1.0; - - // the following one will probably disappear as soon as - // super-share will be properly handled - DXDs_ = 0.0; - - // this part is always executed. - // in case of plain-vanilla payoffs, it is also the only part - // which is executed. - switch (payoff.optionType()) { - case Option.Type.Call: - alpha_ = cum_d1_;// N(d1) - DalphaDd1_ = n_d1_;// n(d1) - beta_ = -cum_d2_;// -N(d2) - DbetaDd2_ = - n_d2_;// -n(d2) - break; - case Option.Type.Put: - alpha_ = -1.0+cum_d1_;// -N(-d1) - DalphaDd1_ = n_d1_;// n( d1) - beta_ = 1.0-cum_d2_;// N(-d2) - DbetaDd2_ = - n_d2_;// -n( d2) - break; - default: - Utils.QL_FAIL("invalid option type"); - break; + else + { + D1_ = Math.Log(forward / strike_) / stdDev_ + 0.5 * stdDev_; + D2_ = D1_ - stdDev_; + CumulativeNormalDistribution f = new CumulativeNormalDistribution(); + cum_d1_ = f.value(D1_); + cum_d2_ = f.value(D2_); + n_d1_ = f.derivative(D1_); + n_d2_ = f.derivative(D2_); } - - // now dispatch on type. - - Calculator calc = new Calculator(this); - payoff.accept(calc); - } - - public double value() { - double result = discount_ * (forward_ * alpha_ + X_ * beta_); - return result; - } - - /*! Sensitivity to change in the underlying forward price. */ - public double deltaForward() { - - double temp = stdDev_ * forward_; - double DalphaDforward = DalphaDd1_ / temp; - double DbetaDforward = DbetaDd2_ / temp; - double temp2 = DalphaDforward * forward_ + alpha_ - + DbetaDforward * X_; // DXDforward = 0.0 - - return discount_ * temp2; - } - - /*! Sensitivity to change in the underlying spot price. */ - public virtual double delta(double spot) { - Utils.QL_REQUIRE(spot > 0.0,()=> "positive spot value required: " + spot + " not allowed"); - - double DforwardDs = forward_ / spot; - - double temp = stdDev_*spot; - double DalphaDs = DalphaDd1_/temp; - double DbetaDs = DbetaDd2_/temp; - double temp2 = DalphaDs * forward_ + alpha_ * DforwardDs - +DbetaDs * X_ + beta_ * DXDs_; - - return discount_ * temp2; - } - - /*! Sensitivity in percent to a percent change in the - underlying forward price. */ - public double elasticityForward() { - double val = value(); - double del = deltaForward(); - if (val > Const.QL_EPSILON) - return del/val*forward_; - if (Math.Abs(del)0.0) - return double.MaxValue; - return double.MinValue; - } - - /*! Sensitivity in percent to a percent change in the - underlying spot price. */ - public virtual double elasticity(double spot) { - double val = value(); - double del = delta(spot); - if (val>Const.QL_EPSILON) - return del/val*spot; - if (Math.Abs(del) < Const.QL_EPSILON) - return 0.0; - if (del>0.0) - return double.MaxValue; - return double.MinValue; - } - - /*! Second order derivative with respect to change in the - underlying forward price. */ - public double gammaForward() { - - double temp = stdDev_ * forward_; - double DalphaDforward = DalphaDd1_ / temp; - double DbetaDforward = DbetaDd2_ / temp; - - double D2alphaDforward2 = -DalphaDforward / forward_ * (1 + D1_ / stdDev_); - double D2betaDforward2 = -DbetaDforward / forward_ * (1 + D2_ / stdDev_); - - double temp2 = D2alphaDforward2 * forward_ + 2.0 * DalphaDforward - + D2betaDforward2 * X_; // DXDforward = 0.0 - - return discount_ * temp2; - } - - /*! Second order derivative with respect to change in the - underlying spot price. */ - public virtual double gamma(double spot) { - - Utils.QL_REQUIRE(spot > 0.0,()=> "positive spot value required: " + spot + " not allowed"); - - double DforwardDs = forward_ / spot; - - double temp = stdDev_ * spot; - double DalphaDs = DalphaDd1_ / temp; - double DbetaDs = DbetaDd2_ / temp; - - double D2alphaDs2 = -DalphaDs / spot * (1 + D1_ / stdDev_); - double D2betaDs2 = -DbetaDs / spot * (1 + D2_ / stdDev_); - - double temp2 = D2alphaDs2 * forward_ + 2.0 * DalphaDs * DforwardDs - + D2betaDs2 * X_ + 2.0 * DbetaDs * DXDs_; - - return discount_ * temp2; - } - - /*! Sensitivity to time to maturity. */ - public virtual double theta(double spot, double maturity) { - - if (maturity.IsEqual(0.0)) return 0.0; - Utils.QL_REQUIRE(maturity>0.0,()=> "non negative maturity required: " + maturity + " not allowed"); - - return -( Math.Log(discount_) * value() - + Math.Log(forward_ / spot) * spot * delta(spot) - +0.5*variance_ * spot * spot * gamma(spot))/maturity; - } - - /*! Sensitivity to time to maturity per day, - assuming 365 day per year. */ - public virtual double thetaPerDay(double spot, double maturity) { - return theta(spot, maturity) / 365.0; - } - - /*! Sensitivity to volatility. */ - public double vega(double maturity) { - Utils.QL_REQUIRE(maturity>=0.0,()=> "negative maturity not allowed"); - - double temp = Math.Log(strike_/forward_)/variance_; - // actually DalphaDsigma / SQRT(T) - double DalphaDsigma = DalphaDd1_*(temp+0.5); - double DbetaDsigma = DbetaDd2_ *(temp-0.5); - - double temp2 = DalphaDsigma * forward_ + DbetaDsigma * X_; - - return discount_ * Math.Sqrt(maturity) * temp2; - - } - - /*! Sensitivity to discounting rate. */ - public double rho(double maturity) { - Utils.QL_REQUIRE(maturity >= 0.0,()=> "negative maturity not allowed"); - - // actually DalphaDr / T - double DalphaDr = DalphaDd1_ / stdDev_; - double DbetaDr = DbetaDd2_ / stdDev_; - double temp = DalphaDr * forward_ + alpha_ * forward_ + DbetaDr * X_; - - return maturity * (discount_ * temp - value()); - } - - /*! Sensitivity to dividend/growth rate. */ - public double dividendRho(double maturity) { - Utils.QL_REQUIRE(maturity >= 0.0,()=> "negative maturity not allowed"); - - // actually DalphaDq / T - double DalphaDq = -DalphaDd1_ / stdDev_; - double DbetaDq = -DbetaDd2_ / stdDev_; - - double temp = DalphaDq * forward_ - alpha_ * forward_ + DbetaDq * X_; - - return maturity * discount_ * temp; - } - - /*! Probability of being in the money in the bond martingale - measure, i.e. N(d2). - It is a risk-neutral probability, not the real world one. - */ - public double itmCashProbability() { - return cum_d2_; - } - - /*! Probability of being in the money in the asset martingale - measure, i.e. N(d1). - It is a risk-neutral probability, not the real world one. - */ - public double itmAssetProbability() { - return cum_d1_; - } - - /*! Sensitivity to strike. */ - public double strikeSensitivity() { - - double temp = stdDev_ * strike_; - double DalphaDstrike = -DalphaDd1_ / temp; - double DbetaDstrike = -DbetaDd2_ / temp; - - double temp2 = DalphaDstrike * forward_ + DbetaDstrike * X_ + beta_ * DXDstrike_; - - return discount_ * temp2; - } - - public double alpha() { - return alpha_; - } - public double beta() { - return beta_; - } - - - class Calculator : IAcyclicVisitor { - private BlackCalculator black_; - - public Calculator(BlackCalculator black) { - black_ = black; + } + else + { + if (forward > strike_) + { + cum_d1_ = 1.0; + cum_d2_ = 1.0; } - - public void visit(object o) { - Type[] types = new Type[] { o.GetType() }; - MethodInfo methodInfo = Utils.GetMethodInfo( this, "visit", types ); - if (methodInfo != null) { - methodInfo.Invoke(this, new object[] { o }); - } + else + { + cum_d1_ = 0.0; + cum_d2_ = 0.0; } + n_d1_ = 0.0; + n_d2_ = 0.0; + } + + X_ = strike_; + DXDstrike_ = 1.0; + + // the following one will probably disappear as soon as + // super-share will be properly handled + DXDs_ = 0.0; + + // this part is always executed. + // in case of plain-vanilla payoffs, it is also the only part + // which is executed. + switch (payoff.optionType()) + { + case Option.Type.Call: + alpha_ = cum_d1_;// N(d1) + DalphaDd1_ = n_d1_;// n(d1) + beta_ = -cum_d2_;// -N(d2) + DbetaDd2_ = - n_d2_;// -n(d2) + break; + case Option.Type.Put: + alpha_ = -1.0 + cum_d1_; // -N(-d1) + DalphaDd1_ = n_d1_;// n( d1) + beta_ = 1.0 - cum_d2_; // N(-d2) + DbetaDd2_ = - n_d2_;// -n( d2) + break; + default: + Utils.QL_FAIL("invalid option type"); + break; + } + + // now dispatch on type. + + Calculator calc = new Calculator(this); + payoff.accept(calc); + } + + public double value() + { + double result = discount_ * (forward_ * alpha_ + X_ * beta_); + return result; + } + + /*! Sensitivity to change in the underlying forward price. */ + public double deltaForward() + { + + double temp = stdDev_ * forward_; + double DalphaDforward = DalphaDd1_ / temp; + double DbetaDforward = DbetaDd2_ / temp; + double temp2 = DalphaDforward * forward_ + alpha_ + + DbetaDforward * X_; // DXDforward = 0.0 + + return discount_ * temp2; + } + + /*! Sensitivity to change in the underlying spot price. */ + public virtual double delta(double spot) + { + Utils.QL_REQUIRE(spot > 0.0, () => "positive spot value required: " + spot + " not allowed"); + + double DforwardDs = forward_ / spot; + + double temp = stdDev_ * spot; + double DalphaDs = DalphaDd1_ / temp; + double DbetaDs = DbetaDd2_ / temp; + double temp2 = DalphaDs * forward_ + alpha_ * DforwardDs + + DbetaDs * X_ + beta_ * DXDs_; + + return discount_ * temp2; + } + + /*! Sensitivity in percent to a percent change in the + underlying forward price. */ + public double elasticityForward() + { + double val = value(); + double del = deltaForward(); + if (val > Const.QL_EPSILON) + return del / val * forward_; + if (Math.Abs(del) < Const.QL_EPSILON) + return 0.0; + if (del > 0.0) + return double.MaxValue; + return double.MinValue; + } + + /*! Sensitivity in percent to a percent change in the + underlying spot price. */ + public virtual double elasticity(double spot) + { + double val = value(); + double del = delta(spot); + if (val > Const.QL_EPSILON) + return del / val * spot; + if (Math.Abs(del) < Const.QL_EPSILON) + return 0.0; + if (del > 0.0) + return double.MaxValue; + return double.MinValue; + } + + /*! Second order derivative with respect to change in the + underlying forward price. */ + public double gammaForward() + { + + double temp = stdDev_ * forward_; + double DalphaDforward = DalphaDd1_ / temp; + double DbetaDforward = DbetaDd2_ / temp; + + double D2alphaDforward2 = -DalphaDforward / forward_ * (1 + D1_ / stdDev_); + double D2betaDforward2 = -DbetaDforward / forward_ * (1 + D2_ / stdDev_); + + double temp2 = D2alphaDforward2 * forward_ + 2.0 * DalphaDforward + + D2betaDforward2 * X_; // DXDforward = 0.0 + + return discount_ * temp2; + } + + /*! Second order derivative with respect to change in the + underlying spot price. */ + public virtual double gamma(double spot) + { + + Utils.QL_REQUIRE(spot > 0.0, () => "positive spot value required: " + spot + " not allowed"); + + double DforwardDs = forward_ / spot; + + double temp = stdDev_ * spot; + double DalphaDs = DalphaDd1_ / temp; + double DbetaDs = DbetaDd2_ / temp; + + double D2alphaDs2 = -DalphaDs / spot * (1 + D1_ / stdDev_); + double D2betaDs2 = -DbetaDs / spot * (1 + D2_ / stdDev_); + + double temp2 = D2alphaDs2 * forward_ + 2.0 * DalphaDs * DforwardDs + + D2betaDs2 * X_ + 2.0 * DbetaDs * DXDs_; + + return discount_ * temp2; + } + + /*! Sensitivity to time to maturity. */ + public virtual double theta(double spot, double maturity) + { + + if (maturity.IsEqual(0.0)) + return 0.0; + Utils.QL_REQUIRE(maturity > 0.0, () => "non negative maturity required: " + maturity + " not allowed"); + + return -(Math.Log(discount_) * value() + + Math.Log(forward_ / spot) * spot * delta(spot) + + 0.5 * variance_ * spot * spot * gamma(spot)) / maturity; + } + + /*! Sensitivity to time to maturity per day, + assuming 365 day per year. */ + public virtual double thetaPerDay(double spot, double maturity) + { + return theta(spot, maturity) / 365.0; + } + + /*! Sensitivity to volatility. */ + public double vega(double maturity) + { + Utils.QL_REQUIRE(maturity >= 0.0, () => "negative maturity not allowed"); + + double temp = Math.Log(strike_ / forward_) / variance_; + // actually DalphaDsigma / SQRT(T) + double DalphaDsigma = DalphaDd1_ * (temp + 0.5); + double DbetaDsigma = DbetaDd2_ * (temp - 0.5); + + double temp2 = DalphaDsigma * forward_ + DbetaDsigma * X_; + + return discount_ * Math.Sqrt(maturity) * temp2; + + } + + /*! Sensitivity to discounting rate. */ + public double rho(double maturity) + { + Utils.QL_REQUIRE(maturity >= 0.0, () => "negative maturity not allowed"); + + // actually DalphaDr / T + double DalphaDr = DalphaDd1_ / stdDev_; + double DbetaDr = DbetaDd2_ / stdDev_; + double temp = DalphaDr * forward_ + alpha_ * forward_ + DbetaDr * X_; + + return maturity * (discount_ * temp - value()); + } + + /*! Sensitivity to dividend/growth rate. */ + public double dividendRho(double maturity) + { + Utils.QL_REQUIRE(maturity >= 0.0, () => "negative maturity not allowed"); + + // actually DalphaDq / T + double DalphaDq = -DalphaDd1_ / stdDev_; + double DbetaDq = -DbetaDd2_ / stdDev_; + + double temp = DalphaDq * forward_ - alpha_ * forward_ + DbetaDq * X_; - public void visit(Payoff p) { - Utils.QL_FAIL("unsupported payoff type: " + p.name()); - } + return maturity * discount_ * temp; + } + + /*! Probability of being in the money in the bond martingale + measure, i.e. N(d2). + It is a risk-neutral probability, not the real world one. + */ + public double itmCashProbability() + { + return cum_d2_; + } - public void visit(PlainVanillaPayoff p) + /*! Probability of being in the money in the asset martingale + measure, i.e. N(d1). + It is a risk-neutral probability, not the real world one. + */ + public double itmAssetProbability() + { + return cum_d1_; + } + + /*! Sensitivity to strike. */ + public double strikeSensitivity() + { + + double temp = stdDev_ * strike_; + double DalphaDstrike = -DalphaDd1_ / temp; + double DbetaDstrike = -DbetaDd2_ / temp; + + double temp2 = DalphaDstrike * forward_ + DbetaDstrike * X_ + beta_ * DXDstrike_; + + return discount_ * temp2; + } + + public double alpha() + { + return alpha_; + } + public double beta() + { + return beta_; + } + + + class Calculator : IAcyclicVisitor + { + private BlackCalculator black_; + + public Calculator(BlackCalculator black) + { + black_ = black; + } + + public void visit(object o) + { + Type[] types = new Type[] { o.GetType() }; + MethodInfo methodInfo = Utils.GetMethodInfo(this, "visit", types); + if (methodInfo != null) { - // Nothing to do here - } - - public void visit(CashOrNothingPayoff payoff) { - black_.alpha_ = black_.DalphaDd1_ = 0.0; - black_.X_ = payoff.cashPayoff(); - black_.DXDstrike_ = 0.0; - switch (payoff.optionType()) { - case Option.Type.Call: - black_.beta_ = black_.cum_d2_; - black_.DbetaDd2_ = black_.n_d2_; - break; - case Option.Type.Put: - black_.beta_ = 1.0-black_.cum_d2_; - black_.DbetaDd2_ = -black_.n_d2_; - break; - default: - Utils.QL_FAIL("invalid option type"); - break; - } + methodInfo.Invoke(this, new object[] { o }); } - - public void visit(AssetOrNothingPayoff payoff) { - black_.beta_ = black_.DbetaDd2_ = 0.0; - switch (payoff.optionType()) { - case Option.Type.Call: - black_.alpha_ = black_.cum_d1_; - black_.DalphaDd1_ = black_.n_d1_; - break; - case Option.Type.Put: - black_.alpha_ = 1.0-black_.cum_d1_; - black_.DalphaDd1_ = -black_.n_d1_; - break; - default: - Utils.QL_FAIL("invalid option type"); - break; - } + } + + public void visit(Payoff p) + { + Utils.QL_FAIL("unsupported payoff type: " + p.name()); + } + + public void visit(PlainVanillaPayoff p) + { + // Nothing to do here + } + + public void visit(CashOrNothingPayoff payoff) + { + black_.alpha_ = black_.DalphaDd1_ = 0.0; + black_.X_ = payoff.cashPayoff(); + black_.DXDstrike_ = 0.0; + switch (payoff.optionType()) + { + case Option.Type.Call: + black_.beta_ = black_.cum_d2_; + black_.DbetaDd2_ = black_.n_d2_; + break; + case Option.Type.Put: + black_.beta_ = 1.0 - black_.cum_d2_; + black_.DbetaDd2_ = -black_.n_d2_; + break; + default: + Utils.QL_FAIL("invalid option type"); + break; } + } - public void visit(GapPayoff payoff) { - black_.X_ = payoff.secondStrike(); - black_.DXDstrike_ = 0.0; + public void visit(AssetOrNothingPayoff payoff) + { + black_.beta_ = black_.DbetaDd2_ = 0.0; + switch (payoff.optionType()) + { + case Option.Type.Call: + black_.alpha_ = black_.cum_d1_; + black_.DalphaDd1_ = black_.n_d1_; + break; + case Option.Type.Put: + black_.alpha_ = 1.0 - black_.cum_d1_; + black_.DalphaDd1_ = -black_.n_d1_; + break; + default: + Utils.QL_FAIL("invalid option type"); + break; } - } - } + } + + public void visit(GapPayoff payoff) + { + black_.X_ = payoff.secondStrike(); + black_.DXDstrike_ = 0.0; + } + } + } } diff --git a/src/QLNet/Pricingengines/BlackDeltaCalculator.cs b/src/QLNet/Pricingengines/BlackDeltaCalculator.cs index c60a4b3bf..362c6b533 100644 --- a/src/QLNet/Pricingengines/BlackDeltaCalculator.cs +++ b/src/QLNet/Pricingengines/BlackDeltaCalculator.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -36,48 +36,48 @@ public BlackDeltaCalculator(Option.Type ot, double fDiscount, // foreign discount double stdDev) { - dt_ = dt; + dt_ = dt; ot_ = ot; - dDiscount_ = dDiscount; + dDiscount_ = dDiscount; fDiscount_ = fDiscount; - stdDev_ = stdDev; + stdDev_ = stdDev; spot_ = spot; - forward_ = spot*fDiscount/dDiscount; + forward_ = spot * fDiscount / dDiscount; phi_ = (int)ot; - - Utils.QL_REQUIRE(spot_>0.0,()=> "positive spot value required: " + spot_ + " not allowed"); - Utils.QL_REQUIRE(dDiscount_>0.0,()=> "positive domestic discount factor required: " + dDiscount_ + " not allowed"); - Utils.QL_REQUIRE(fDiscount_>0.0,()=> "positive foreign discount factor required: " + fDiscount_ + " not allowed"); - Utils.QL_REQUIRE(stdDev_>=0.0,()=> "non-negative standard deviation required: " + stdDev_ + " not allowed"); - fExpPos_ =forward_*Math.Exp(0.5*stdDev_*stdDev_); - fExpNeg_ =forward_*Math.Exp(-0.5*stdDev_*stdDev_); + Utils.QL_REQUIRE(spot_ > 0.0, () => "positive spot value required: " + spot_ + " not allowed"); + Utils.QL_REQUIRE(dDiscount_ > 0.0, () => "positive domestic discount factor required: " + dDiscount_ + " not allowed"); + Utils.QL_REQUIRE(fDiscount_ > 0.0, () => "positive foreign discount factor required: " + fDiscount_ + " not allowed"); + Utils.QL_REQUIRE(stdDev_ >= 0.0, () => "non-negative standard deviation required: " + stdDev_ + " not allowed"); + + fExpPos_ = forward_ * Math.Exp(0.5 * stdDev_ * stdDev_); + fExpNeg_ = forward_ * Math.Exp(-0.5 * stdDev_ * stdDev_); } // Give strike, receive delta according to specified type public double deltaFromStrike(double strike) { - Utils.QL_REQUIRE(strike >=0.0,()=> "positive strike value required: " + strike + " not allowed"); + Utils.QL_REQUIRE(strike >= 0.0, () => "positive strike value required: " + strike + " not allowed"); - double res=0.0; + double res = 0.0; - switch(dt_) + switch (dt_) { case DeltaVolQuote.DeltaType.Spot: - res=phi_*fDiscount_*cumD1(strike); + res = phi_ * fDiscount_ * cumD1(strike); break; case DeltaVolQuote.DeltaType.Fwd: - res=phi_*cumD1(strike); + res = phi_ * cumD1(strike); break; case DeltaVolQuote.DeltaType.PaSpot: - res=phi_*fDiscount_*cumD2(strike)*strike/forward_; + res = phi_ * fDiscount_ * cumD2(strike) * strike / forward_; break; case DeltaVolQuote.DeltaType.PaFwd: - res=phi_*cumD2(strike)*strike/forward_; + res = phi_ * cumD2(strike) * strike / forward_; break; default: @@ -85,7 +85,7 @@ public double deltaFromStrike(double strike) break; } return res; - + } // Give delta according to specified type, receive strike @@ -96,39 +96,39 @@ public double strikeFromDelta(double delta) public double cumD1(double strike) // N(d1) or N(-d1) { - double d1_=0.0; + double d1_ = 0.0; double cum_d1_pos_ = 1.0; // N(d1) double cum_d1_neg_ = 0.0; // N(-d1) CumulativeNormalDistribution f = new CumulativeNormalDistribution(); - if (stdDev_>=Const.QL_EPSILON) + if (stdDev_ >= Const.QL_EPSILON) { - if(strike>0) + if (strike > 0) { - d1_ = Math.Log(forward_/strike)/stdDev_ + 0.5*stdDev_; - return f.value(phi_*d1_); + d1_ = Math.Log(forward_ / strike) / stdDev_ + 0.5 * stdDev_; + return f.value(phi_ * d1_); } - } - else + } + else { - if (forward_0) - { + if (phi_ > 0) + { // if Call return cum_d1_pos_; - } + } else { return cum_d1_neg_; @@ -137,74 +137,74 @@ public double cumD1(double strike) // N(d1) or N(-d1) } public double cumD2(double strike) // N(d2) or N(-d2) { - double d2_=0.0; - double cum_d2_pos_= 1.0; // N(d2) - double cum_d2_neg_= 0.0; // N(-d2) + double d2_ = 0.0; + double cum_d2_pos_ = 1.0; // N(d2) + double cum_d2_neg_ = 0.0; // N(-d2) CumulativeNormalDistribution f = new CumulativeNormalDistribution(); - if (stdDev_>=Const.QL_EPSILON) + if (stdDev_ >= Const.QL_EPSILON) { - if(strike>0) + if (strike > 0) { - d2_ = Math.Log(forward_/strike)/stdDev_ - 0.5*stdDev_; - return f.value(phi_*d2_); + d2_ = Math.Log(forward_ / strike) / stdDev_ - 0.5 * stdDev_; + return f.value(phi_ * d2_); } - } - else + } + else { - if (forward_0) - { - // if Call - return cum_d2_pos_; - } - else - { - return cum_d2_neg_; - } + } + + if (phi_ > 0) + { + // if Call + return cum_d2_pos_; + } + else + { + return cum_d2_neg_; + } } public double nD1(double strike) // n(d1) { - double d1_=0.0; + double d1_ = 0.0; double n_d1_ = 0.0; // n(d1) - if (stdDev_>=Const.QL_EPSILON) + if (stdDev_ >= Const.QL_EPSILON) { - if(strike>0) + if (strike > 0) { - d1_ = Math.Log(forward_/strike)/stdDev_ + 0.5*stdDev_; + d1_ = Math.Log(forward_ / strike) / stdDev_ + 0.5 * stdDev_; CumulativeNormalDistribution f = new CumulativeNormalDistribution(); n_d1_ = f.derivative(d1_); } } - return n_d1_; + return n_d1_; } public double nD2(double strike) // n(d2) { - double d2_=0.0; - double n_d2_= 0.0; // n(d2) + double d2_ = 0.0; + double n_d2_ = 0.0; // n(d2) - if (stdDev_>=Const.QL_EPSILON) + if (stdDev_ >= Const.QL_EPSILON) { - if(strike>0) + if (strike > 0) { - d2_ = Math.Log(forward_/strike)/stdDev_ - 0.5*stdDev_; + d2_ = Math.Log(forward_ / strike) / stdDev_ - 0.5 * stdDev_; CumulativeNormalDistribution f = new CumulativeNormalDistribution(); n_d2_ = f.derivative(d2_); } @@ -213,8 +213,8 @@ public double nD2(double strike) // n(d2) return n_d2_; } - public void setDeltaType( DeltaVolQuote.DeltaType dt ) { dt_ = dt; } - public void setOptionType( Option.Type ot ) + public void setDeltaType(DeltaVolQuote.DeltaType dt) { dt_ = dt; } + public void setOptionType(Option.Type ot) { ot_ = ot; phi_ = (int) ot_ ; @@ -223,34 +223,34 @@ public void setOptionType( Option.Type ot ) // The following function can be calculated without an explicit strike public double atmStrike(DeltaVolQuote.AtmType atmT) { - double res=0.0; + double res = 0.0; - switch(atmT) + switch (atmT) { case DeltaVolQuote.AtmType.AtmDeltaNeutral: - if(dt_==DeltaVolQuote.DeltaType.Spot || dt_==DeltaVolQuote.DeltaType.Fwd) + if (dt_ == DeltaVolQuote.DeltaType.Spot || dt_ == DeltaVolQuote.DeltaType.Fwd) { - res=fExpPos_; - } - else + res = fExpPos_; + } + else { - res=fExpNeg_; + res = fExpNeg_; } break; case DeltaVolQuote.AtmType.AtmFwd: - res=forward_; + res = forward_; break; - case DeltaVolQuote.AtmType.AtmGammaMax: + case DeltaVolQuote.AtmType.AtmGammaMax: case DeltaVolQuote.AtmType.AtmVegaMax: - res=fExpPos_; + res = fExpPos_; break; case DeltaVolQuote.AtmType.AtmPutCall50: - Utils.QL_REQUIRE(dt_==DeltaVolQuote.DeltaType.Fwd,()=> - "|PutDelta|=CallDelta=0.50 only possible for forward delta."); - res=fExpPos_; + Utils.QL_REQUIRE(dt_ == DeltaVolQuote.DeltaType.Fwd, () => + "|PutDelta|=CallDelta=0.50 only possible for forward delta."); + res = fExpPos_; break; default: @@ -261,28 +261,28 @@ public double atmStrike(DeltaVolQuote.AtmType atmT) return res; } - + // alternative delta type private double strikeFromDelta(double delta, DeltaVolQuote.DeltaType dt) { - double res=0.0; - double arg=0.0; + double res = 0.0; + double arg = 0.0; InverseCumulativeNormal f = new InverseCumulativeNormal(); - Utils.QL_REQUIRE(delta*phi_>=0.0,()=> "Option type and delta are incoherent."); + Utils.QL_REQUIRE(delta * phi_ >= 0.0, () => "Option type and delta are incoherent."); - switch ( dt ) + switch (dt) { case DeltaVolQuote.DeltaType.Spot: - Utils.QL_REQUIRE( Math.Abs( delta ) <= fDiscount_, () => "Spot delta out of range." ); - arg = -phi_ * f.value( phi_ * delta / fDiscount_ ) * stdDev_ + 0.5 * stdDev_ * stdDev_; - res = forward_ * Math.Exp( arg ); + Utils.QL_REQUIRE(Math.Abs(delta) <= fDiscount_, () => "Spot delta out of range."); + arg = -phi_ * f.value(phi_ * delta / fDiscount_) * stdDev_ + 0.5 * stdDev_ * stdDev_; + res = forward_ * Math.Exp(arg); break; case DeltaVolQuote.DeltaType.Fwd: - Utils.QL_REQUIRE( Math.Abs( delta ) <= 1.0, () => "Forward delta out of range." ); - arg = -phi_ * f.value( phi_ * delta ) * stdDev_ + 0.5 * stdDev_ * stdDev_; - res = forward_ * Math.Exp( arg ); + Utils.QL_REQUIRE(Math.Abs(delta) <= 1.0, () => "Forward delta out of range."); + arg = -phi_ * f.value(phi_ * delta) * stdDev_ + 0.5 * stdDev_ * stdDev_; + res = forward_ * Math.Exp(arg); break; case DeltaVolQuote.DeltaType.PaSpot: @@ -301,29 +301,29 @@ private double strikeFromDelta(double delta, DeltaVolQuote.DeltaType dt) // solved without any problems, but also numerically. BlackDeltaPremiumAdjustedSolverClass f1 = new BlackDeltaPremiumAdjustedSolverClass( - ot_, dt, spot_, dDiscount_, fDiscount_, stdDev_, delta ); + ot_, dt, spot_, dDiscount_, fDiscount_, stdDev_, delta); Brent solver = new Brent(); - solver.setMaxEvaluations( 1000 ); + solver.setMaxEvaluations(1000); double accuracy = 1.0e-10; double rightLimit = 0.0; double leftLimit = 0.0; // Strike of not premium adjusted is always to the right of premium adjusted - if ( dt == DeltaVolQuote.DeltaType.PaSpot ) + if (dt == DeltaVolQuote.DeltaType.PaSpot) { - rightLimit = strikeFromDelta( delta, DeltaVolQuote.DeltaType.Spot ); + rightLimit = strikeFromDelta(delta, DeltaVolQuote.DeltaType.Spot); } else { - rightLimit = strikeFromDelta( delta, DeltaVolQuote.DeltaType.Fwd ); + rightLimit = strikeFromDelta(delta, DeltaVolQuote.DeltaType.Fwd); } - if ( phi_ < 0 ) + if (phi_ < 0) { // if put - res = solver.solve( f1, accuracy, rightLimit, 0.0, spot_ * 100.0 ); + res = solver.solve(f1, accuracy, rightLimit, 0.0, spot_ * 100.0); break; } else @@ -333,24 +333,24 @@ private double strikeFromDelta(double delta, DeltaVolQuote.DeltaType dt) // deltas have their maximum. BlackDeltaPremiumAdjustedMaxStrikeClass g = new BlackDeltaPremiumAdjustedMaxStrikeClass( - ot_, dt, spot_, dDiscount_, fDiscount_, stdDev_ ); + ot_, dt, spot_, dDiscount_, fDiscount_, stdDev_); - leftLimit = solver.solve( g, accuracy, rightLimit * 0.5, 0.0, rightLimit ); + leftLimit = solver.solve(g, accuracy, rightLimit * 0.5, 0.0, rightLimit); - double guess = leftLimit + ( rightLimit - leftLimit ) * 0.5; + double guess = leftLimit + (rightLimit - leftLimit) * 0.5; - res = solver.solve( f1, accuracy, guess, leftLimit, rightLimit ); + res = solver.solve(f1, accuracy, guess, leftLimit, rightLimit); } // end if phi<0 else break; default: - Utils.QL_FAIL( "invalid delta type" ); + Utils.QL_FAIL("invalid delta type"); break; } - return res; + return res; } private DeltaVolQuote.DeltaType dt_; @@ -359,26 +359,26 @@ private double strikeFromDelta(double delta, DeltaVolQuote.DeltaType dt) private double stdDev_, spot_, forward_; private int phi_; - private double fExpPos_,fExpNeg_; - + private double fExpPos_, fExpNeg_; + } - + public class BlackDeltaPremiumAdjustedSolverClass : ISolver1d { - public BlackDeltaPremiumAdjustedSolverClass( Option.Type ot, - DeltaVolQuote.DeltaType dt, - double spot, - double dDiscount, // domestic discount - double fDiscount, // foreign discount - double stdDev, - double delta) + public BlackDeltaPremiumAdjustedSolverClass(Option.Type ot, + DeltaVolQuote.DeltaType dt, + double spot, + double dDiscount, // domestic discount + double fDiscount, // foreign discount + double stdDev, + double delta) { - bdc_ = new BlackDeltaCalculator(ot,dt,spot,dDiscount,fDiscount,stdDev); + bdc_ = new BlackDeltaCalculator(ot, dt, spot, dDiscount, fDiscount, stdDev); delta_ = delta; } - public override double value( double strike ) { return bdc_.deltaFromStrike( strike ) - delta_; } + public override double value(double strike) { return bdc_.deltaFromStrike(strike) - delta_; } private BlackDeltaCalculator bdc_; private double delta_; @@ -386,18 +386,18 @@ public BlackDeltaPremiumAdjustedSolverClass( Option.Type ot, public class BlackDeltaPremiumAdjustedMaxStrikeClass : ISolver1d { - public BlackDeltaPremiumAdjustedMaxStrikeClass( Option.Type ot, - DeltaVolQuote.DeltaType dt, - double spot, - double dDiscount, // domestic discount - double fDiscount, // foreign discount - double stdDev) + public BlackDeltaPremiumAdjustedMaxStrikeClass(Option.Type ot, + DeltaVolQuote.DeltaType dt, + double spot, + double dDiscount, // domestic discount + double fDiscount, // foreign discount + double stdDev) { - bdc_ = new BlackDeltaCalculator(ot,dt,spot,dDiscount,fDiscount,stdDev); + bdc_ = new BlackDeltaCalculator(ot, dt, spot, dDiscount, fDiscount, stdDev); stdDev_ = stdDev; } - public override double value( double strike ) { return bdc_.cumD2( strike ) * stdDev_ - bdc_.nD2( strike ); } + public override double value(double strike) { return bdc_.cumD2(strike) * stdDev_ - bdc_.nD2(strike); } private BlackDeltaCalculator bdc_; private double stdDev_; diff --git a/src/QLNet/Pricingengines/BlackFormula.cs b/src/QLNet/Pricingengines/BlackFormula.cs new file mode 100644 index 000000000..a691c5db3 --- /dev/null +++ b/src/QLNet/Pricingengines/BlackFormula.cs @@ -0,0 +1,618 @@ +// Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) +// +// This file is part of QLNet Project https://github.com/amaggiulli/qlnet +// QLNet is free software: you can redistribute it and/or modify it +// under the terms of the QLNet license. You should have received a +// copy of the license along with this program; if not, license is +// available at . +// +// QLNet is a based on QuantLib, a free-software/open-source library +// for financial quantitative analysts and developers - http://quantlib.org/ +// The QuantLib license is available online at http://quantlib.org/license.shtml. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the license for more details. + +using System; + +namespace QLNet +{ + + public partial class Utils + { + /*! Black 1976 formula + \warning instead of volatility it uses standard deviation, + i.e. volatility*sqrt(timeToMaturity) + */ + public static double blackFormula(Option.Type optionType, + double strike, + double forward, + double stdDev, + double discount = 1.0, + double displacement = 0.0) + { + checkParameters(strike, forward, displacement); + Utils.QL_REQUIRE(stdDev >= 0.0, () => "stdDev (" + stdDev + ") must be non-negative"); + Utils.QL_REQUIRE(discount > 0.0, () => "discount (" + discount + ") must be positive"); + + if (stdDev.IsEqual(0.0)) + return Math.Max((forward - strike) * (int)optionType, 0.0) * discount; + + forward = forward + displacement; + strike = strike + displacement; + + // since displacement is non-negative strike==0 iff displacement==0 + // so returning forward*discount is OK + if (strike.IsEqual(0.0)) + return (optionType == Option.Type.Call ? forward* discount : 0.0); + + double d1 = Math.Log(forward / strike) / stdDev + 0.5 * stdDev; + double d2 = d1 - stdDev; + CumulativeNormalDistribution phi = new CumulativeNormalDistribution(); + double nd1 = phi.value((int)optionType * d1); + double nd2 = phi.value((int)optionType * d2); + double result = discount * (int)optionType * (forward * nd1 - strike * nd2); + Utils.QL_REQUIRE(result >= 0.0, () => + "negative value (" + result + ") for " + + stdDev + " stdDev, " + + optionType + " option, " + + strike + " strike , " + + forward + " forward"); + return result; + } + + public static double blackFormula(PlainVanillaPayoff payoff, + double forward, + double stdDev, + double discount = 1.0, + double displacement = 0.0) + { + return blackFormula(payoff.optionType(), payoff.strike(), forward, stdDev, discount, displacement); + } + + /*! Approximated Black 1976 implied standard deviation, + i.e. volatility*sqrt(timeToMaturity). + + It is calculated using Brenner and Subrahmanyan (1988) and Feinstein + (1988) approximation for at-the-money forward option, with the + extended moneyness approximation by Corrado and Miller (1996) + */ + public static double blackFormulaImpliedStdDevApproximation(Option.Type optionType, + double strike, + double forward, + double blackPrice, + double discount = 1.0, + double displacement = 0.0) + { + checkParameters(strike, forward, displacement); + Utils.QL_REQUIRE(blackPrice >= 0.0, () => + "blackPrice (" + blackPrice + ") must be non-negative"); + Utils.QL_REQUIRE(discount > 0.0, () => + "discount (" + discount + ") must be positive"); + + double stdDev; + forward = forward + displacement; + strike = strike + displacement; + if (strike.IsEqual(forward)) + // Brenner-Subrahmanyan (1988) and Feinstein (1988) ATM approx. + stdDev = blackPrice / discount * Math.Sqrt(2.0 * Const.M_PI) / forward; + else + { + // Corrado and Miller extended moneyness approximation + double moneynessDelta = (int)optionType * (forward - strike); + double moneynessDelta_2 = moneynessDelta / 2.0; + double temp = blackPrice / discount - moneynessDelta_2; + double moneynessDelta_PI = moneynessDelta * moneynessDelta / Const.M_PI; + double temp2 = temp * temp - moneynessDelta_PI; + if (temp2 < 0.0) // approximation breaks down, 2 alternatives: + // 1. zero it + temp2 = 0.0; + // 2. Manaster-Koehler (1982) efficient Newton-Raphson seed + temp2 = Math.Sqrt(temp2); + temp += temp2; + temp *= Math.Sqrt(2.0 * Const.M_PI); + stdDev = temp / (forward + strike); + } + + Utils.QL_REQUIRE(stdDev >= 0.0, () => "stdDev (" + stdDev + ") must be non-negative"); + return stdDev; + } + + public static double blackFormulaImpliedStdDevApproximation(PlainVanillaPayoff payoff, + double forward, + double blackPrice, + double discount, + double displacement) + { + return blackFormulaImpliedStdDevApproximation(payoff.optionType(), + payoff.strike(), forward, blackPrice, discount, displacement); + } + + + /*! Approximated Black 1976 implied standard deviation, + i.e. volatility*sqrt(timeToMaturity). + + It is calculated following "An improved approach to computing + implied volatility", Chambers, Nawalkha, The Financial Review, + 2001, 89-100. The atm option price must be known to use this + method. + */ + public static double blackFormulaImpliedStdDevChambers(Option.Type optionType, + double strike, + double forward, + double blackPrice, + double blackAtmPrice, + double discount = 1.0, + double displacement = 0.0) + { + checkParameters(strike, forward, displacement); + QL_REQUIRE(blackPrice >= 0.0, () => + "blackPrice (" + blackPrice + ") must be non-negative"); + QL_REQUIRE(blackAtmPrice >= 0.0, () => + "blackAtmPrice (" + blackAtmPrice + ") must be non-negative"); + QL_REQUIRE(discount > 0.0, () => + "discount (" + discount + ") must be positive"); + + double stdDev; + + forward = forward + displacement; + strike = strike + displacement; + blackPrice /= discount; + blackAtmPrice /= discount; + + double s0 = Const.M_SQRT2 * Const.M_SQRTPI * blackAtmPrice / + forward; // Brenner-Subrahmanyam formula + double priceAtmVol = blackFormula(optionType, strike, forward, s0, 1.0, 0.0); + double dc = blackPrice - priceAtmVol; + + if (close(dc, 0.0)) + { + stdDev = s0; + } + else + { + double d1 = blackFormulaStdDevDerivative(strike, forward, s0, 1.0, 0.0); + double d2 = blackFormulaStdDevSecondDerivative(strike, forward, s0, 1.0, 0.0); + double ds = 0.0; + double tmp = d1 * d1 + 2.0 * d2 * dc; + if (Math.Abs(d2) > 1E-10 && tmp >= 0.0) + ds = (-d1 + Math.Sqrt(tmp)) / d2; // second order approximation + else if (Math.Abs(d1) > 1E-10) + ds = dc / d1; // first order approximation + stdDev = s0 + ds; + } + + QL_REQUIRE(stdDev >= 0.0, () => "stdDev (" + stdDev + ") must be non-negative"); + return stdDev; + } + + public static double blackFormulaImpliedStdDevChambers(PlainVanillaPayoff payoff, + double forward, + double blackPrice, + double blackAtmPrice, + double discount, + double displacement) + { + return blackFormulaImpliedStdDevChambers(payoff.optionType(), payoff.strike(), forward, blackPrice, + blackAtmPrice, discount, displacement); + } + + + /*! Black 1976 implied standard deviation, + i.e. volatility*sqrt(timeToMaturity) + */ + public static double blackFormulaImpliedStdDev(Option.Type optionType, + double strike, + double forward, + double blackPrice, + double discount = 1.0, + double displacement = 0.0, + double? guess = null, + double accuracy = 1.0e-6, + int maxIterations = 100) + { + checkParameters(strike, forward, displacement); + + QL_REQUIRE(discount > 0.0, () => + "discount (" + discount + ") must be positive"); + + QL_REQUIRE(blackPrice >= 0.0, () => + "option price (" + blackPrice + ") must be non-negative"); + // check the price of the "other" option implied by put-call paity + double otherOptionPrice = blackPrice - (int)optionType * (forward - strike) * discount; + QL_REQUIRE(otherOptionPrice >= 0.0, () => + "negative " + (-1 * (int)optionType) + + " price (" + otherOptionPrice + + ") implied by put-call parity. No solution exists for " + + optionType + " strike " + strike + + ", forward " + forward + + ", price " + blackPrice + + ", deflator " + discount); + + // solve for the out-of-the-money option which has + // greater vega/price ratio, i.e. + // it is numerically more robust for implied vol calculations + if (optionType == Option.Type.Put && strike > forward) + { + optionType = Option.Type.Call; + blackPrice = otherOptionPrice; + } + if (optionType == Option.Type.Call && strike < forward) + { + optionType = Option.Type.Put; + blackPrice = otherOptionPrice; + } + + strike = strike + displacement; + forward = forward + displacement; + + if (guess == null) + guess = blackFormulaImpliedStdDevApproximation(optionType, strike, forward, blackPrice, discount, displacement); + else + QL_REQUIRE(guess >= 0.0, () => "stdDev guess (" + guess + ") must be non-negative"); + + BlackImpliedStdDevHelper f = new BlackImpliedStdDevHelper(optionType, strike, forward, blackPrice / discount); + NewtonSafe solver = new NewtonSafe(); + solver.setMaxEvaluations(maxIterations); + double minSdtDev = 0.0, maxStdDev = 24.0; // 24 = 300% * sqrt(60) + double stdDev = solver.solve(f, accuracy, guess.Value, minSdtDev, maxStdDev); + QL_REQUIRE(stdDev >= 0.0, () => "stdDev (" + stdDev + ") must be non-negative"); + return stdDev; + } + + public static double blackFormulaImpliedStdDev(PlainVanillaPayoff payoff, + double forward, + double blackPrice, + double discount, + double displacement, + double guess, + double accuracy, + int maxIterations = 100) + { + return blackFormulaImpliedStdDev(payoff.optionType(), payoff.strike(), + forward, blackPrice, discount, displacement, guess, accuracy, maxIterations); + } + + + /*! Black 1976 probability of being in the money (in the bond martingale measure), i.e. N(d2). + It is a risk-neutral probability, not the real world one. + \warning instead of volatility it uses standard deviation, i.e. volatility*sqrt(timeToMaturity) + */ + public static double blackFormulaCashItmProbability(Option.Type optionType, + double strike, + double forward, + double stdDev, + double displacement = 0.0) + { + checkParameters(strike, forward, displacement); + if (stdDev.IsEqual(0.0)) + return (forward * (int)optionType > strike * (int)optionType ? 1.0 : 0.0); + + forward = forward + displacement; + strike = strike + displacement; + if (strike.IsEqual(0.0)) + return (optionType == Option.Type.Call ? 1.0 : 0.0); + double d2 = Math.Log(forward / strike) / stdDev - 0.5 * stdDev; + CumulativeNormalDistribution phi = new CumulativeNormalDistribution(); + return phi.value((int)optionType * d2); + } + + public static double blackFormulaCashItmProbability(PlainVanillaPayoff payoff, + double forward, + double stdDev, + double displacement = 0.0) + { + return blackFormulaCashItmProbability(payoff.optionType(), + payoff.strike(), forward, stdDev, displacement); + } + + /*! Black 1976 formula for standard deviation derivative + \warning instead of volatility it uses standard deviation, i.e. + volatility*sqrt(timeToMaturity), and it returns the + derivative with respect to the standard deviation. + If T is the time to maturity Black vega would be + blackStdDevDerivative(strike, forward, stdDev)*sqrt(T) + */ + public static double blackFormulaStdDevDerivative(double strike, + double forward, + double stdDev, + double discount = 1.0, + double displacement = 0.0) + { + checkParameters(strike, forward, displacement); + QL_REQUIRE(stdDev >= 0.0, () => + "stdDev (" + stdDev + ") must be non-negative"); + QL_REQUIRE(discount > 0.0, () => + "discount (" + discount + ") must be positive"); + + forward = forward + displacement; + strike = strike + displacement; + + if (stdDev.IsEqual(0.0) || strike.IsEqual(0.0)) + return 0.0; + + double d1 = Math.Log(forward / strike) / stdDev + .5 * stdDev; + return discount * forward * + new CumulativeNormalDistribution().derivative(d1); + } + /*! Black 1976 formula for derivative with respect to implied vol, this + is basically the vega, but if you want 1% change multiply by 1% + */ + public static double blackFormulaVolDerivative(double strike, + double forward, + double stdDev, + double expiry, + double discount = 1.0, + double displacement = 0.0) + { + return blackFormulaStdDevDerivative(strike, forward, stdDev, discount, displacement) * Math.Sqrt(expiry); + } + + public static double blackFormulaStdDevDerivative(PlainVanillaPayoff payoff, + double forward, + double stdDev, + double discount = 1.0, + double displacement = 0.0) + { + return blackFormulaStdDevDerivative(payoff.strike(), forward, stdDev, discount, displacement); + } + + /*! Black 1976 formula for second derivative by standard deviation + \warning instead of volatility it uses standard deviation, i.e. + volatility*sqrt(timeToMaturity), and it returns the + derivative with respect to the standard deviation. + */ + public static double blackFormulaStdDevSecondDerivative(double strike, + double forward, + double stdDev, + double discount, + double displacement) + { + checkParameters(strike, forward, displacement); + QL_REQUIRE(stdDev >= 0.0, () => + "stdDev (" + stdDev + ") must be non-negative"); + QL_REQUIRE(discount > 0.0, () => + "discount (" + discount + ") must be positive"); + + forward = forward + displacement; + strike = strike + displacement; + + if (stdDev.IsEqual(0.0) || strike.IsEqual(0.0)) + return 0.0; + + double d1 = Math.Log(forward / strike) / stdDev + .5 * stdDev; + double d1p = -Math.Log(forward / strike) / (stdDev * stdDev) + .5; + return discount * forward * + new NormalDistribution().derivative(d1) * d1p; + } + + public static double blackFormulaStdDevSecondDerivative(PlainVanillaPayoff payoff, + double forward, + double stdDev, + double discount = 1.0, + double displacement = 0.0) + { + return blackFormulaStdDevSecondDerivative(payoff.strike(), forward, stdDev, discount, displacement); + } + + /*! Black style formula when forward is normal rather than + log-normal. This is essentially the model of Bachelier. + + \warning Bachelier model needs absolute volatility, not + percentage volatility. Standard deviation is + absoluteVolatility*sqrt(timeToMaturity) + */ + public static double bachelierBlackFormula(Option.Type optionType, + double strike, + double forward, + double stdDev, + double discount = 1.0) + { + QL_REQUIRE(stdDev >= 0.0, () => + "stdDev (" + stdDev + ") must be non-negative"); + QL_REQUIRE(discount > 0.0, () => + "discount (" + discount + ") must be positive"); + double d = (forward - strike) * (int)optionType, h = d / stdDev; + if (stdDev.IsEqual(0.0)) + return discount * Math.Max(d, 0.0); + CumulativeNormalDistribution phi = new CumulativeNormalDistribution(); + double result = discount * (stdDev * phi.derivative(h) + d * phi.value(h)); + QL_REQUIRE(result >= 0.0, () => + "negative value (" + result + ") for " + + stdDev + " stdDev, " + + optionType + " option, " + + strike + " strike , " + + forward + " forward"); + return result; + } + + public static double bachelierBlackFormula(PlainVanillaPayoff payoff, + double forward, + double stdDev, + double discount = 1.0) + { + return bachelierBlackFormula(payoff.optionType(), payoff.strike(), forward, stdDev, discount); + } + + /*! Approximated Bachelier implied volatility + + It is calculated using the analytic implied volatility approximation + of J. Choi, K Kim and M. Kwak (2009), “Numerical Approximation of the + Implied Volatility Under Arithmetic Brownian Motion”, + Applied Math. Finance, 16(3), pp. 261-268. + */ + public static double bachelierBlackFormulaImpliedVol(Option.Type optionType, + double strike, + double forward, + double tte, + double bachelierPrice, + double discount = 1.0) + { + double SQRT_QL_EPSILON = Math.Sqrt(Const.QL_EPSILON); + + QL_REQUIRE(tte > 0.0, () => "tte (" + tte + ") must be positive"); + + double forwardPremium = bachelierPrice / discount; + + double straddlePremium; + if (optionType == Option.Type.Call) + { + straddlePremium = 2.0 * forwardPremium - (forward - strike); + } + else + { + straddlePremium = 2.0 * forwardPremium + (forward - strike); + } + + double nu = (forward - strike) / straddlePremium; + QL_REQUIRE(nu <= 1.0, () => "nu (" + nu + ") must be <= 1.0"); + QL_REQUIRE(nu >= -1.0, () => "nu (" + nu + ") must be >= -1.0"); + + nu = Math.Max(-1.0 + Const.QL_EPSILON, Math.Min(nu, 1.0 - Const.QL_EPSILON)); + + // nu / arctanh(nu) -> 1 as nu -> 0 + double eta = (Math.Abs(nu) < SQRT_QL_EPSILON) ? 1.0 : nu / ((Math.Log(1 + nu) - Math.Log(1 - nu)) / 2); + + double heta = h(eta); + + double impliedBpvol = Math.Sqrt(Const.M_PI / (2 * tte)) * straddlePremium * heta; + + return impliedBpvol; + } + + public static double h(double eta) + { + + const double A0 = 3.994961687345134e-1; + const double A1 = 2.100960795068497e+1; + const double A2 = 4.980340217855084e+1; + const double A3 = 5.988761102690991e+2; + const double A4 = 1.848489695437094e+3; + const double A5 = 6.106322407867059e+3; + const double A6 = 2.493415285349361e+4; + const double A7 = 1.266458051348246e+4; + + const double B0 = 1.000000000000000e+0; + const double B1 = 4.990534153589422e+1; + const double B2 = 3.093573936743112e+1; + const double B3 = 1.495105008310999e+3; + const double B4 = 1.323614537899738e+3; + const double B5 = 1.598919697679745e+4; + const double B6 = 2.392008891720782e+4; + const double B7 = 3.608817108375034e+3; + const double B8 = -2.067719486400926e+2; + const double B9 = 1.174240599306013e+1; + + QL_REQUIRE(eta >= 0.0, () => + "eta (" + eta + ") must be non-negative"); + + double num = A0 + eta * (A1 + eta * (A2 + eta * (A3 + eta * (A4 + eta + * (A5 + eta * (A6 + eta * A7)))))); + + double den = B0 + eta * (B1 + eta * (B2 + eta * (B3 + eta * (B4 + eta + * (B5 + eta * (B6 + eta * (B7 + eta * (B8 + eta * B9)))))))); + + return Math.Sqrt(eta) * (num / den); + + } + + /*! Bachelier formula for standard deviation derivative + \warning instead of volatility it uses standard deviation, i.e. + volatility*sqrt(timeToMaturity), and it returns the + derivative with respect to the standard deviation. + If T is the time to maturity Black vega would be + blackStdDevDerivative(strike, forward, stdDev)*sqrt(T) + */ + + public static double bachelierBlackFormulaStdDevDerivative(double strike, + double forward, + double stdDev, + double discount = 1.0) + { + QL_REQUIRE(stdDev >= 0.0, () => + "stdDev (" + stdDev + ") must be non-negative"); + QL_REQUIRE(discount > 0.0, () => + "discount (" + discount + ") must be positive"); + + if (stdDev.IsEqual(0.0)) + return 0.0; + + double d1 = (forward - strike) / stdDev; + return discount * + new CumulativeNormalDistribution().derivative(d1); + } + + public static double bachelierBlackFormulaStdDevDerivative(PlainVanillaPayoff payoff, + double forward, + double stdDev, + double discount = 1.0) + { + return bachelierBlackFormulaStdDevDerivative(payoff.strike(), forward, stdDev, discount); + } + + public static void checkParameters(double strike, double forward, double displacement) + { + Utils.QL_REQUIRE(displacement >= 0.0, () => + "displacement (" + displacement + ") must be non-negative"); + Utils.QL_REQUIRE(strike + displacement >= 0.0, () => + "strike + displacement (" + strike + " + " + displacement + ") must be non-negative"); + Utils.QL_REQUIRE(forward + displacement > 0.0, () => + "forward + displacement (" + forward + " + " + displacement + ") must be positive"); + } + + class BlackImpliedStdDevHelper : ISolver1d + { + public BlackImpliedStdDevHelper(Option.Type optionType, + double strike, + double forward, + double undiscountedBlackPrice, + double displacement = 0.0) + { + halfOptionType_ = 0.5 * (int)optionType; + signedStrike_ = (int)optionType * (strike + displacement); + signedForward_ = (int)optionType * (forward + displacement); + undiscountedBlackPrice_ = undiscountedBlackPrice; + N_ = new CumulativeNormalDistribution(); + checkParameters(strike, forward, displacement); + Utils.QL_REQUIRE(undiscountedBlackPrice >= 0.0, () => + "undiscounted Black price (" + + undiscountedBlackPrice + ") must be non-negative"); + signedMoneyness_ = (int)optionType * Math.Log((forward + displacement) / (strike + displacement)); + } + public override double value(double stdDev) + { +#if QL_EXTRA_SAFETY_CHECKS + Utils.QL_REQUIRE(stdDev >= 0.0, () => "stdDev (" + stdDev + ") must be non-negative"); +#endif + if (stdDev.IsEqual(0.0)) + return Math.Max(signedForward_ - signedStrike_, 0.0) + - undiscountedBlackPrice_; + double temp = halfOptionType_ * stdDev; + double d = signedMoneyness_ / stdDev; + double signedD1 = d + temp; + double signedD2 = d - temp; + double result = signedForward_ * N_.value(signedD1) + - signedStrike_ * N_.value(signedD2); + // numerical inaccuracies can yield a negative answer + return Math.Max(0.0, result) - undiscountedBlackPrice_; + } + + public override double derivative(double stdDev) + { +#if QL_EXTRA_SAFETY_CHECKS + QL_REQUIRE(stdDev >= 0.0, + "stdDev (" << stdDev << ") must be non-negative"); +#endif + double signedD1 = signedMoneyness_ / stdDev + halfOptionType_ * stdDev; + return signedForward_ * N_.derivative(signedD1); + } + + + private double halfOptionType_; + private double signedStrike_, signedForward_; + private double undiscountedBlackPrice_, signedMoneyness_; + private CumulativeNormalDistribution N_; + } + } +} \ No newline at end of file diff --git a/src/QLNet/Pricingengines/Blackscholescalculator.cs b/src/QLNet/Pricingengines/Blackscholescalculator.cs index 0b750edd8..69914cffd 100644 --- a/src/QLNet/Pricingengines/Blackscholescalculator.cs +++ b/src/QLNet/Pricingengines/Blackscholescalculator.cs @@ -1,71 +1,72 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { +namespace QLNet +{ - //! Black-Scholes 1973 calculator class - public class BlackScholesCalculator : BlackCalculator - { - protected double spot_; - protected double growth_; + //! Black-Scholes 1973 calculator class + public class BlackScholesCalculator : BlackCalculator + { + protected double spot_; + protected double growth_; - public BlackScholesCalculator(StrikedTypePayoff payoff, double spot, double growth, double stdDev, double discount) - : base(payoff, spot * growth / discount, stdDev, discount) - { - spot_ = spot; - growth_ = growth; + public BlackScholesCalculator(StrikedTypePayoff payoff, double spot, double growth, double stdDev, double discount) + : base(payoff, spot* growth / discount, stdDev, discount) + { + spot_ = spot; + growth_ = growth; - Utils.QL_REQUIRE(spot_ >= 0.0,()=> "positive spot value required: " + spot_ + " not allowed"); - Utils.QL_REQUIRE(growth_ >= 0.0,()=> "positive growth value required: " + growth_ + " not allowed"); - } + Utils.QL_REQUIRE(spot_ >= 0.0, () => "positive spot value required: " + spot_ + " not allowed"); + Utils.QL_REQUIRE(growth_ >= 0.0, () => "positive growth value required: " + growth_ + " not allowed"); + } - //! Sensitivity to change in the underlying spot price. + //! Sensitivity to change in the underlying spot price. - public double delta() - { - return base.delta(spot_); - } + public double delta() + { + return base.delta(spot_); + } // ! Sensitivity in percent to a percent change in the -// underlying spot price. - public double elasticity() - { - return base.elasticity(spot_); - } +// underlying spot price. + public double elasticity() + { + return base.elasticity(spot_); + } // ! Second order derivative with respect to change in the -// underlying spot price. - public double gamma() - { - return base.gamma(spot_); - } - //! Sensitivity to time to maturity. - public double theta(double maturity) - { - return base.theta(spot_, maturity); - } +// underlying spot price. + public double gamma() + { + return base.gamma(spot_); + } + //! Sensitivity to time to maturity. + public double theta(double maturity) + { + return base.theta(spot_, maturity); + } // ! Sensitivity to time to maturity per day -// (assuming 365 day in a year). - public double thetaPerDay(double maturity) - { - return base.thetaPerDay(spot_, maturity); - } - } +// (assuming 365 day in a year). + public double thetaPerDay(double maturity) + { + return base.thetaPerDay(spot_, maturity); + } + } } diff --git a/src/QLNet/Pricingengines/Bond/BlackCallableBondEngine.cs b/src/QLNet/Pricingengines/Bond/BlackCallableBondEngine.cs index 301064c00..6e3aadfcf 100644 --- a/src/QLNet/Pricingengines/Bond/BlackCallableBondEngine.cs +++ b/src/QLNet/Pricingengines/Bond/BlackCallableBondEngine.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -33,14 +33,14 @@ option follows the Black "European bond option" treatment in \ingroup callablebondengines */ - public class BlackCallableFixedRateBondEngine : CallableFixedRateBond.Engine + public class BlackCallableFixedRateBondEngine : CallableFixedRateBond.Engine { //! volatility is the quoted fwd yield volatility, not price vol public BlackCallableFixedRateBondEngine(Handle fwdYieldVol, Handle discountCurve) { - volatility_ = new Handle( new CallableBondConstantVolatility(0, new NullCalendar(), - fwdYieldVol, - new Actual365Fixed())); + volatility_ = new Handle(new CallableBondConstantVolatility(0, new NullCalendar(), + fwdYieldVol, + new Actual365Fixed())); discountCurve_ = discountCurve; volatility_.registerWith(update); @@ -59,46 +59,48 @@ public BlackCallableFixedRateBondEngine(Handle public override void calculate() { // validate args for Black engine - Utils.QL_REQUIRE( arguments_.putCallSchedule.Count == 1, () => "Must have exactly one call/put date to use Black Engine" ); + Utils.QL_REQUIRE(arguments_.putCallSchedule.Count == 1, () => "Must have exactly one call/put date to use Black Engine"); Date settle = arguments_.settlementDate; Date exerciseDate = arguments_.callabilityDates[0]; - Utils.QL_REQUIRE( exerciseDate >= settle, () => "must have exercise Date >= settlement Date" ); + Utils.QL_REQUIRE(exerciseDate >= settle, () => "must have exercise Date >= settlement Date"); List fixedLeg = arguments_.cashflows; double value = CashFlows.npv(fixedLeg, discountCurve_, false, settle); - double npv = CashFlows.npv(fixedLeg, discountCurve_,false, discountCurve_.link.referenceDate()); + double npv = CashFlows.npv(fixedLeg, discountCurve_, false, discountCurve_.link.referenceDate()); - double fwdCashPrice = (value - spotIncome())/ - discountCurve_.link.discount(exerciseDate); + double fwdCashPrice = (value - spotIncome()) / + discountCurve_.link.discount(exerciseDate); double cashStrike = arguments_.callabilityPrices[0]; Option.Type type = (arguments_.putCallSchedule[0].type() == - Callability.Type.Call ? Option.Type.Call : Option.Type.Put); + Callability.Type.Call ? Option.Type.Call : Option.Type.Put); double priceVol = forwardPriceVolatility(); double exerciseTime = volatility_.link.dayCounter().yearFraction( - volatility_.link.referenceDate(), - exerciseDate); + volatility_.link.referenceDate(), + exerciseDate); double embeddedOptionValue = Utils.blackFormula(type, cashStrike, fwdCashPrice, - priceVol*Math.Sqrt(exerciseTime)); + priceVol * Math.Sqrt(exerciseTime)); - if (type == Option.Type.Call) + if (type == Option.Type.Call) { results_.value = npv - embeddedOptionValue; results_.settlementValue = value - embeddedOptionValue; - } else { + } + else + { results_.value = npv + embeddedOptionValue; results_.settlementValue = value + embeddedOptionValue; } } - + private Handle volatility_; private Handle discountCurve_; // present value of all coupons paid during the life of option @@ -131,7 +133,7 @@ 1. cashflows are in ascending order ! } return income / discountCurve_.link.discount(settlement); } - + // converts the yield volatility into a forward price volatility private double forwardPriceVolatility() { @@ -140,7 +142,7 @@ private double forwardPriceVolatility() List fixedLeg = arguments_.cashflows; // value of bond cash flows at option maturity - double fwdNpv = CashFlows.npv(fixedLeg, discountCurve_,false, exerciseDate); + double fwdNpv = CashFlows.npv(fixedLeg, discountCurve_, false, exerciseDate); DayCounter dayCounter = arguments_.paymentDayCounter; Frequency frequency = arguments_.frequency; @@ -161,20 +163,20 @@ private double forwardPriceVolatility() double fwdDur = CashFlows.duration(fixedLeg, fwdRate, - Duration.Type.Modified,false, + Duration.Type.Modified, false, exerciseDate); double cashStrike = arguments_.callabilityPrices[0]; dayCounter = volatility_.link.dayCounter(); Date referenceDate = volatility_.link.referenceDate(); double exerciseTime = dayCounter.yearFraction(referenceDate, - exerciseDate); + exerciseDate); double maturityTime = dayCounter.yearFraction(referenceDate, - bondMaturity); + bondMaturity); double yieldVol = volatility_.link.volatility(exerciseTime, - maturityTime-exerciseTime, + maturityTime - exerciseTime, cashStrike); - double fwdPriceVol = yieldVol*fwdDur*fwdYtm; + double fwdPriceVol = yieldVol * fwdDur * fwdYtm; return fwdPriceVol; } } @@ -193,12 +195,12 @@ public class BlackCallableZeroCouponBondEngine : BlackCallableFixedRateBondEngin { //! volatility is the quoted fwd yield volatility, not price vol - public BlackCallableZeroCouponBondEngine(Handle fwdYieldVol,Handle discountCurve) - : base(fwdYieldVol, discountCurve) {} + public BlackCallableZeroCouponBondEngine(Handle fwdYieldVol, Handle discountCurve) + : base(fwdYieldVol, discountCurve) {} //! volatility is the quoted fwd yield volatility, not price vol public BlackCallableZeroCouponBondEngine(Handle yieldVolStructure, Handle discountCurve) - : base(yieldVolStructure, discountCurve) {} + : base(yieldVolStructure, discountCurve) {} } } diff --git a/src/QLNet/Pricingengines/Bond/BondFunctions.cs b/src/QLNet/Pricingengines/Bond/BondFunctions.cs index fe9742d4a..2746c9d4d 100644 --- a/src/QLNet/Pricingengines/Bond/BondFunctions.cs +++ b/src/QLNet/Pricingengines/Bond/BondFunctions.cs @@ -5,18 +5,22 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ +using System; +using System.Collections.Generic; +using System.Linq; + namespace QLNet { //! Bond adapters of CashFlows functions @@ -119,9 +123,9 @@ public static Date accrualStartDate(Bond bond, Date settlementDate = null) if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); return CashFlows.accrualStartDate(bond.cashflows(), false, settlementDate); } @@ -130,9 +134,9 @@ public static Date accrualEndDate(Bond bond, Date settlementDate = null) if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); return CashFlows.accrualEndDate(bond.cashflows(), false, settlementDate); } @@ -141,9 +145,9 @@ public static Date referencePeriodStart(Bond bond, Date settlementDate = null) if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); return CashFlows.referencePeriodStart(bond.cashflows(), false, settlementDate); } @@ -152,9 +156,9 @@ public static Date referencePeriodEnd(Bond bond, Date settlementDate = null) if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); return CashFlows.referencePeriodEnd(bond.cashflows(), false, settlementDate); } @@ -163,9 +167,9 @@ public static double accrualPeriod(Bond bond, Date settlementDate = null) if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); return CashFlows.accrualPeriod(bond.cashflows(), false, settlementDate); } @@ -174,9 +178,9 @@ public static int accrualDays(Bond bond, Date settlementDate = null) if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); return CashFlows.accrualDays(bond.cashflows(), false, settlementDate); } @@ -185,9 +189,9 @@ public static double accruedPeriod(Bond bond, Date settlementDate = null) if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); return CashFlows.accruedPeriod(bond.cashflows(), false, settlementDate); } @@ -196,9 +200,9 @@ public static double accruedDays(Bond bond, Date settlementDate = null) if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); return CashFlows.accruedDays(bond.cashflows(), false, settlementDate); } @@ -207,9 +211,9 @@ public static double accruedAmount(Bond bond, Date settlementDate = null) if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); return CashFlows.accruedAmount(bond.cashflows(), false, settlementDate) * 100.0 / bond.notional(settlementDate); } @@ -223,10 +227,10 @@ public static double cleanPrice(Bond bond, YieldTermStructure discountCurve, Dat if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " settlementDate date (maturity being " + - bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " settlementDate date (maturity being " + + bond.maturityDate() + ")"); double dirtyPrice = CashFlows.npv(bond.cashflows(), discountCurve, false, settlementDate) * 100.0 / bond.notional(settlementDate); @@ -237,9 +241,9 @@ public static double bps(Bond bond, YieldTermStructure discountCurve, Date settl if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); return CashFlows.bps(bond.cashflows(), discountCurve, false, settlementDate) * 100.0 / bond.notional(settlementDate); } @@ -248,11 +252,11 @@ public static double atmRate(Bond bond, YieldTermStructure discountCurve, Date s if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); - double? dirtyPrice = cleanPrice == null ? null : cleanPrice + bond.accruedAmount(settlementDate); + double ? dirtyPrice = cleanPrice == null ? null : cleanPrice + bond.accruedAmount(settlementDate); double currentNotional = bond.notional(settlementDate); double? npv = dirtyPrice / 100.0 * currentNotional; @@ -265,57 +269,57 @@ public static double atmRate(Bond bond, YieldTermStructure discountCurve, Date s public static double cleanPrice(Bond bond, InterestRate yield, Date settlementDate = null) { - return dirtyPrice(bond, yield, settlementDate) - bond.accruedAmount(settlementDate); + return dirtyPrice(bond, yield, settlementDate) - bond.accruedAmount(settlementDate); } public static double cleanPrice(Bond bond, double yield, DayCounter dayCounter, Compounding compounding, Frequency frequency, - Date settlementDate = null) + Date settlementDate = null) { return cleanPrice(bond, new InterestRate(yield, dayCounter, compounding, frequency), settlementDate); } public static double dirtyPrice(Bond bond, InterestRate yield, Date settlementDate = null) { - if (settlementDate == null) - settlementDate = bond.settlementDate(); + if (settlementDate == null) + settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); - double dirtyPrice = CashFlows.npv(bond.cashflows(), yield, false, settlementDate) * - 100.0 / bond.notional(settlementDate); - return dirtyPrice; + double dirtyPrice = CashFlows.npv(bond.cashflows(), yield, false, settlementDate) * + 100.0 / bond.notional(settlementDate); + return dirtyPrice; } public static double dirtyPrice(Bond bond, double yield, DayCounter dayCounter, Compounding compounding, Frequency frequency, - Date settlementDate = null) + Date settlementDate = null) { - return dirtyPrice(bond, new InterestRate(yield, dayCounter, compounding, frequency), settlementDate); + return dirtyPrice(bond, new InterestRate(yield, dayCounter, compounding, frequency), settlementDate); } public static double bps(Bond bond, InterestRate yield, Date settlementDate = null) { if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); return CashFlows.bps(bond.cashflows(), yield, false, settlementDate) * - 100.0 / bond.notional(settlementDate); + 100.0 / bond.notional(settlementDate); } public static double bps(Bond bond, double yield, DayCounter dayCounter, Compounding compounding, Frequency frequency, - Date settlementDate = null) + Date settlementDate = null) { return bps(bond, new InterestRate(yield, dayCounter, compounding, frequency), settlementDate); } public static double yield(Bond bond, double cleanPrice, DayCounter dayCounter, Compounding compounding, Frequency frequency, - Date settlementDate = null, double accuracy = 1.0e-10, int maxIterations = 100, double guess = 0.05) + Date settlementDate = null, double accuracy = 1.0e-10, int maxIterations = 100, double guess = 0.05) { if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); double dirtyPrice = cleanPrice + bond.accruedAmount(settlementDate); dirtyPrice /= 100.0 / bond.notional(settlementDate); @@ -326,19 +330,19 @@ public static double yield(Bond bond, double cleanPrice, DayCounter dayCounter, accuracy, maxIterations, guess); } public static double duration(Bond bond, InterestRate yield, Duration.Type type = Duration.Type.Modified, - Date settlementDate = null) + Date settlementDate = null) { if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); return CashFlows.duration(bond.cashflows(), yield, type, false, settlementDate); } public static double duration(Bond bond, double yield, DayCounter dayCounter, Compounding compounding, Frequency frequency, - Duration.Type type = Duration.Type.Modified, Date settlementDate = null) + Duration.Type type = Duration.Type.Modified, Date settlementDate = null) { return duration(bond, new InterestRate(yield, dayCounter, compounding, frequency), type, settlementDate); } @@ -347,14 +351,14 @@ public static double convexity(Bond bond, InterestRate yield, Date settlementDat if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); return CashFlows.convexity(bond.cashflows(), yield, false, settlementDate); } public static double convexity(Bond bond, double yield, DayCounter dayCounter, Compounding compounding, Frequency frequency, - Date settlementDate = null) + Date settlementDate = null) { return convexity(bond, new InterestRate(yield, dayCounter, compounding, frequency), settlementDate); } @@ -363,15 +367,15 @@ public static double basisPointValue(Bond bond, InterestRate yield, Date settlem if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); return CashFlows.basisPointValue(bond.cashflows(), yield, false, settlementDate); } public static double basisPointValue(Bond bond, double yield, DayCounter dayCounter, Compounding compounding, Frequency frequency, - Date settlementDate = null) + Date settlementDate = null) { return CashFlows.basisPointValue(bond.cashflows(), new InterestRate(yield, dayCounter, compounding, frequency), false, settlementDate); } @@ -380,15 +384,15 @@ public static double yieldValueBasisPoint(Bond bond, InterestRate yield, Date se if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); return CashFlows.yieldValueBasisPoint(bond.cashflows(), yield, false, settlementDate); } public static double yieldValueBasisPoint(Bond bond, double yield, DayCounter dayCounter, Compounding compounding, - Frequency frequency, Date settlementDate = null) + Frequency frequency, Date settlementDate = null) { return CashFlows.yieldValueBasisPoint(bond.cashflows(), new InterestRate(yield, dayCounter, compounding, frequency), false, settlementDate); } @@ -397,29 +401,29 @@ public static double yieldValueBasisPoint(Bond bond, double yield, DayCounter da #region Z-spread functions public static double cleanPrice(Bond bond, YieldTermStructure discount, double zSpread, DayCounter dayCounter, Compounding compounding, - Frequency frequency, Date settlementDate = null) + Frequency frequency, Date settlementDate = null) { if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); double dirtyPrice = CashFlows.npv(bond.cashflows(), discount, zSpread, dayCounter, compounding, frequency, false, settlementDate) * 100.0 / bond.notional(settlementDate); return dirtyPrice - bond.accruedAmount(settlementDate); } public static double zSpread(Bond bond, double cleanPrice, YieldTermStructure discount, DayCounter dayCounter, Compounding compounding, - Frequency frequency, Date settlementDate = null, double accuracy = 1.0e-10, int maxIterations = 100, - double guess = 0.0) + Frequency frequency, Date settlementDate = null, double accuracy = 1.0e-10, int maxIterations = 100, + double guess = 0.0) { if (settlementDate == null) settlementDate = bond.settlementDate(); - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); double dirtyPrice = cleanPrice + bond.accruedAmount(settlementDate); dirtyPrice /= 100.0 / bond.notional(settlementDate); @@ -433,5 +437,32 @@ public static double zSpread(Bond bond, double cleanPrice, YieldTermStructure di } #endregion + #region Raw Functions + + public static DateTime WeightedAverageLife(DateTime today, List amounts, List schedule) + { + Utils.QL_REQUIRE(amounts.Count == schedule.Count, () => "Amount list is incompatible with schedule"); + double totAmount = amounts.Sum(); + + if (totAmount.IsEqual(0)) + return today; + + double wal = 0; + DayCounter dc = new Actual365Fixed(); + + for (int x = 0; x < amounts.Count; x++) + { + double per = amounts[x] / totAmount; + double years = dc.yearFraction(today, schedule[x]); + double yearw = years * per; + wal += yearw; + } + + return today.AddDays(wal * 365).Date; + + } + + #endregion + } } diff --git a/src/QLNet/Pricingengines/Bond/Discountingbondengine.cs b/src/QLNet/Pricingengines/Bond/Discountingbondengine.cs index 2ed1f5ce0..220ecfef1 100644 --- a/src/QLNet/Pricingengines/Bond/Discountingbondengine.cs +++ b/src/QLNet/Pricingengines/Bond/Discountingbondengine.cs @@ -1,42 +1,42 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet +namespace QLNet { - public class DiscountingBondEngine : Bond.Engine + public class DiscountingBondEngine : Bond.Engine { private Handle discountCurve_; private bool? includeSettlementDateFlows_; public Handle discountCurve() {return discountCurve_; } - public DiscountingBondEngine(Handle discountCurve, bool? includeSettlementDateFlows = null) + public DiscountingBondEngine(Handle discountCurve, bool? includeSettlementDateFlows = null) { discountCurve_ = discountCurve; discountCurve_.registerWith(update); includeSettlementDateFlows_ = includeSettlementDateFlows; } - public override void calculate() + public override void calculate() { - Utils.QL_REQUIRE( !discountCurve_.empty(), () => "discounting term structure handle is empty" ); + Utils.QL_REQUIRE(!discountCurve_.empty(), () => "discounting term structure handle is empty"); results_.valuationDate = discountCurve_.link.referenceDate(); bool includeRefDateFlows = @@ -63,11 +63,11 @@ public override void calculate() { // no such luck results_.settlementValue = - CashFlows.npv(arguments_.cashflows, - discountCurve_, - false, - arguments_.settlementDate, - arguments_.settlementDate); + CashFlows.npv(arguments_.cashflows, + discountCurve_, + false, + arguments_.settlementDate, + arguments_.settlementDate); } } } diff --git a/src/QLNet/Pricingengines/Bond/TreeCallableBondEngine.cs b/src/QLNet/Pricingengines/Bond/TreeCallableBondEngine.cs index 7f8de883f..25e343b0c 100644 --- a/src/QLNet/Pricingengines/Bond/TreeCallableBondEngine.cs +++ b/src/QLNet/Pricingengines/Bond/TreeCallableBondEngine.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -32,7 +32,7 @@ model cannot provide one itself. public TreeCallableFixedRateBondEngine(ShortRateModel model, int timeSteps, Handle termStructure) : base(model, timeSteps) - + { termStructure_ = termStructure; termStructure_.registerWith(update); @@ -40,7 +40,7 @@ public TreeCallableFixedRateBondEngine(ShortRateModel model, int timeSteps, public TreeCallableFixedRateBondEngine(ShortRateModel model, TimeGrid timeGrid, - Handle termStructure ) + Handle termStructure) : base(model, timeGrid) { termStructure_ = termStructure; @@ -49,41 +49,41 @@ public TreeCallableFixedRateBondEngine(ShortRateModel model, TimeGrid timeGrid, public override void calculate() { - Utils.QL_REQUIRE( model_ != null, () => "no model specified" ); + Utils.QL_REQUIRE(model_ != null, () => "no model specified"); - Date referenceDate; - DayCounter dayCounter; + Date referenceDate; + DayCounter dayCounter; - ITermStructureConsistentModel tsmodel = (ITermStructureConsistentModel)base.model_.link; - if (tsmodel != null) - { + ITermStructureConsistentModel tsmodel = (ITermStructureConsistentModel)base.model_.link; + if (tsmodel != null) + { referenceDate = tsmodel.termStructure().link.referenceDate(); dayCounter = tsmodel.termStructure().link.dayCounter(); - } - else - { + } + else + { referenceDate = termStructure_.link.referenceDate(); dayCounter = termStructure_.link.dayCounter(); - } + } - DiscretizedCallableFixedRateBond callableBond = new DiscretizedCallableFixedRateBond(arguments_, referenceDate, dayCounter); - Lattice lattice; + DiscretizedCallableFixedRateBond callableBond = new DiscretizedCallableFixedRateBond(arguments_, referenceDate, dayCounter); + Lattice lattice; - if (lattice_ != null) - { + if (lattice_ != null) + { lattice = lattice_; - } - else - { + } + else + { List times = callableBond.mandatoryTimes(); - TimeGrid timeGrid = new TimeGrid( times, times.Count, timeSteps_ ); + TimeGrid timeGrid = new TimeGrid(times, times.Count, timeSteps_); lattice = model_.link.tree(timeGrid); - } + } - double redemptionTime = dayCounter.yearFraction(referenceDate, arguments_.redemptionDate); - callableBond.initialize(lattice, redemptionTime); - callableBond.rollback(0.0); - results_.value = results_.settlementValue = callableBond.presentValue(); + double redemptionTime = dayCounter.yearFraction(referenceDate, arguments_.redemptionDate); + callableBond.initialize(lattice, redemptionTime); + callableBond.rollback(0.0); + results_.value = results_.settlementValue = callableBond.presentValue(); } private Handle termStructure_; diff --git a/src/QLNet/Pricingengines/CapFloor/AnalyticCapFloorEngine.cs b/src/QLNet/Pricingengines/CapFloor/AnalyticCapFloorEngine.cs new file mode 100644 index 000000000..2c98fbfab --- /dev/null +++ b/src/QLNet/Pricingengines/CapFloor/AnalyticCapFloorEngine.cs @@ -0,0 +1,137 @@ +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + + public class AnalyticCapFloorEngine : GenericModelEngine + { + + /*! \note the term structure is only needed when the short-rate + model cannot provide one itself. + */ + + private Handle termStructure_; + + public AnalyticCapFloorEngine(IAffineModel model) + : this(model, new Handle()) { } + + + public AnalyticCapFloorEngine(IAffineModel model, + Handle termStructure) + : base(model) + { + termStructure_ = termStructure; + termStructure_.registerWith(update); + } + + public override void calculate() + { + if (model_ == null) + throw new ArgumentException("null model"); + + Date referenceDate = new Date(); + DayCounter dayCounter = new DayCounter(); + try + { + TermStructureConsistentModel tsmodel = (TermStructureConsistentModel)model_.link; + ///if (tsmodel != null) + referenceDate = tsmodel.termStructure().link.referenceDate(); + dayCounter = tsmodel.termStructure().link.dayCounter(); + } + //else + catch + { + referenceDate = termStructure_.link.referenceDate(); + dayCounter = termStructure_.link.dayCounter(); + } + + double value = 0.0; + CapFloorType type = arguments_.type; + int nPeriods = arguments_.endDates.Count; + + for (int i = 0; i < nPeriods; i++) + { + double fixingTime = + dayCounter.yearFraction(referenceDate, + arguments_.fixingDates[i]); + double paymentTime = + dayCounter.yearFraction(referenceDate, + arguments_.endDates[i]); +#if QL_TODAYS_PAYMENTS + if (paymentTime >= 0.0) + { +#else + if (paymentTime > 0.0) + { +#endif + double tenor = arguments_.accrualTimes[i]; + double fixing = (double)arguments_.forwards[i]; + if (fixingTime <= 0.0) + { + if (type == CapFloorType.Cap || type == CapFloorType.Collar) + { + double discount = model_.link.discount(paymentTime); + double strike = (double)arguments_.capRates[i]; + value += discount * arguments_.nominals[i] * tenor + * arguments_.gearings[i] + * Math.Max(0.0, fixing - strike); + } + if (type == CapFloorType.Floor || type == CapFloorType.Collar) + { + double discount = model_.link.discount(paymentTime); + double strike = (double)arguments_.floorRates[i]; + double mult = (type == CapFloorType.Floor) ? 1.0 : -1.0; + value += discount * arguments_.nominals[i] * tenor + * mult * arguments_.gearings[i] + * Math.Max(0.0, strike - fixing); + } + } + else + { + double maturity = + dayCounter.yearFraction(referenceDate, + arguments_.startDates[i]); + if (type == CapFloorType.Cap || type == CapFloorType.Collar) + { + double temp = 1.0 + (double)arguments_.capRates[i] * tenor; + value += arguments_.nominals[i] * + arguments_.gearings[i] * temp * + model_.link.discountBondOption(Option.Type.Put, 1.0 / temp, + maturity, paymentTime); + } + if (type == CapFloorType.Floor || type == CapFloorType.Collar) + { + double temp = 1.0 + (double)arguments_.floorRates[i] * tenor; + double mult = (type == CapFloorType.Floor) ? 1.0 : -1.0; + value += arguments_.nominals[i] * + arguments_.gearings[i] * temp * mult * + model_.link.discountBondOption(Option.Type.Call, 1.0 / temp, + maturity, paymentTime); + } + } + } + } + results_.value = value; + } + } +} \ No newline at end of file diff --git a/src/QLNet/Pricingengines/CapFloor/BachelierCapFloorEngine.cs b/src/QLNet/Pricingengines/CapFloor/BachelierCapFloorEngine.cs index 2253e7b7b..2ec862d03 100644 --- a/src/QLNet/Pricingengines/CapFloor/BachelierCapFloorEngine.cs +++ b/src/QLNet/Pricingengines/CapFloor/BachelierCapFloorEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,30 +21,30 @@ namespace QLNet { public class BachelierCapFloorEngine : CapFloorEngine { - public BachelierCapFloorEngine(Handle discountCurve,double vol,DayCounter dc = null) // new Actual365Fixed() + public BachelierCapFloorEngine(Handle discountCurve, double vol, DayCounter dc = null) // new Actual365Fixed() { - + discountCurve_ = discountCurve; vol_ = new Handle( - new ConstantOptionletVolatility(0, new NullCalendar(), BusinessDayConvention.Following, vol, - dc ?? new Actual365Fixed())) ; + new ConstantOptionletVolatility(0, new NullCalendar(), BusinessDayConvention.Following, vol, + dc ?? new Actual365Fixed())) ; discountCurve_.registerWith(update); } - public BachelierCapFloorEngine(Handle discountCurve,Handle vol,DayCounter dc = null) + public BachelierCapFloorEngine(Handle discountCurve, Handle vol, DayCounter dc = null) { discountCurve_ = discountCurve; vol_ = new Handle( - new ConstantOptionletVolatility( 0, new NullCalendar(), BusinessDayConvention.Following, vol, - dc ?? new Actual365Fixed() ) ); - discountCurve_.registerWith( update ); + new ConstantOptionletVolatility(0, new NullCalendar(), BusinessDayConvention.Following, vol, + dc ?? new Actual365Fixed())); + discountCurve_.registerWith(update); vol_.registerWith(update); } - public BachelierCapFloorEngine(Handle discountCurve,Handle vol) + public BachelierCapFloorEngine(Handle discountCurve, Handle vol) { discountCurve_ = discountCurve; vol_ = vol; - discountCurve_.registerWith( update ); - vol_.registerWith( update ); + discountCurve_.registerWith(update); + vol_.registerWith(update); } public override void calculate() @@ -67,9 +67,9 @@ public override void calculate() // For the double being just discard expired caplets if (paymentDate > settlement) { - double d = arguments_.nominals[i]* - arguments_.gearings[i]* - discountCurve_.link.discount(paymentDate)* + double d = arguments_.nominals[i] * + arguments_.gearings[i] * + discountCurve_.link.discount(paymentDate) * arguments_.accrualTimes[i]; double forward = arguments_.forwards[i].Value; @@ -85,7 +85,7 @@ public override void calculate() if (sqrtTime > 0.0) { stdDevs[i] = Math.Sqrt(vol_.link.blackVariance(fixingDate, strike)); - vegas[i] = Utils.bachelierBlackFormulaStdDevDerivative(strike, forward, stdDevs[i], d)*sqrtTime; + vegas[i] = Utils.bachelierBlackFormulaStdDevDerivative(strike, forward, stdDevs[i], d) * sqrtTime; } // include caplets with past fixing date values[i] = Utils.bachelierBlackFormula(Option.Type.Call, strike, forward, stdDevs[i], d); @@ -97,7 +97,7 @@ public override void calculate() if (sqrtTime > 0.0) { stdDevs[i] = Math.Sqrt(vol_.link.blackVariance(fixingDate, strike)); - floorletVega = Utils.bachelierBlackFormulaStdDevDerivative(strike, forward, stdDevs[i], d)*sqrtTime; + floorletVega = Utils.bachelierBlackFormulaStdDevDerivative(strike, forward, stdDevs[i], d) * sqrtTime; } double floorlet = Utils.bachelierBlackFormula(Option.Type.Put, strike, forward, stdDevs[i], d); if (type == CapFloorType.Floor) @@ -125,11 +125,11 @@ public override void calculate() if (type != CapFloorType.Collar) results_.additionalResults["optionletsStdDev"] = stdDevs; } - + public Handle termStructure() { return discountCurve_; } public Handle volatility() { return vol_; } - + private Handle discountCurve_; private Handle vol_; } diff --git a/src/QLNet/Pricingengines/CapFloor/BlackCapFloorEngine.cs b/src/QLNet/Pricingengines/CapFloor/BlackCapFloorEngine.cs index f6f949d31..b7283dd5f 100644 --- a/src/QLNet/Pricingengines/CapFloor/BlackCapFloorEngine.cs +++ b/src/QLNet/Pricingengines/CapFloor/BlackCapFloorEngine.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -31,36 +31,36 @@ public class BlackCapFloorEngine : CapFloorEngine private Handle vol_; private double displacement_; - public BlackCapFloorEngine( Handle discountCurve,double vol, - DayCounter dc =null,double displacement = 0.0) + public BlackCapFloorEngine(Handle discountCurve, double vol, + DayCounter dc = null, double displacement = 0.0) { discountCurve_ = discountCurve; - vol_ = new Handle(new ConstantOptionletVolatility(0, new NullCalendar(), BusinessDayConvention.Following, vol, dc??new Actual365Fixed())); + vol_ = new Handle(new ConstantOptionletVolatility(0, new NullCalendar(), BusinessDayConvention.Following, vol, dc ?? new Actual365Fixed())); displacement_ = displacement; - discountCurve_.registerWith(update ); + discountCurve_.registerWith(update); } - public BlackCapFloorEngine( Handle discountCurve,Handle vol, - DayCounter dc = null,double displacement = 0.0) + public BlackCapFloorEngine(Handle discountCurve, Handle vol, + DayCounter dc = null, double displacement = 0.0) { discountCurve_ = discountCurve; - vol_ = new Handle( new ConstantOptionletVolatility( - 0, new NullCalendar(), BusinessDayConvention.Following, vol, dc ?? new Actual365Fixed() ) ); + vol_ = new Handle(new ConstantOptionletVolatility( + 0, new NullCalendar(), BusinessDayConvention.Following, vol, dc ?? new Actual365Fixed())); displacement_ = displacement; - discountCurve_.registerWith( update ); - vol_.registerWith( update ); - + discountCurve_.registerWith(update); + vol_.registerWith(update); + } - public BlackCapFloorEngine( Handle discountCurve,Handle vol, - double displacement = 0.0) + public BlackCapFloorEngine(Handle discountCurve, Handle vol, + double displacement = 0.0) { discountCurve_ = discountCurve; vol_ = vol; displacement_ = displacement; - discountCurve_.registerWith( update ); - vol_.registerWith( update ); + discountCurve_.registerWith(update); + vol_.registerWith(update); } - public override void calculate() + public override void calculate() { double value = 0.0; double vega = 0.0; @@ -72,11 +72,11 @@ public override void calculate() Date today = vol_.link.referenceDate(); Date settlement = discountCurve_.link.referenceDate(); - for (int i=0; i settlement) - { + if (paymentDate > settlement) + { // discard expired caplets double d = arguments_.nominals[i] * arguments_.gearings[i] * @@ -88,57 +88,57 @@ public override void calculate() Date fixingDate = arguments_.fixingDates[i]; double sqrtTime = 0.0; if (fixingDate > today) - sqrtTime = Math.Sqrt( vol_.link.timeFromReference( fixingDate ) ); + sqrtTime = Math.Sqrt(vol_.link.timeFromReference(fixingDate)); - if (type == CapFloorType.Cap || type == CapFloorType.Collar) + if (type == CapFloorType.Cap || type == CapFloorType.Collar) { double? strike = arguments_.capRates[i]; - if (sqrtTime>0.0) + if (sqrtTime > 0.0) { - stdDevs[i] = Math.Sqrt( vol_.link.blackVariance( fixingDate, strike.Value ) ); - vegas[i] = Utils.blackFormulaStdDevDerivative( strike.Value, forward.Value, stdDevs[i], d, displacement_ ) * sqrtTime; + stdDevs[i] = Math.Sqrt(vol_.link.blackVariance(fixingDate, strike.Value)); + vegas[i] = Utils.blackFormulaStdDevDerivative(strike.Value, forward.Value, stdDevs[i], d, displacement_) * sqrtTime; } // include caplets with past fixing date values[i] = Utils.blackFormula(Option.Type.Call, strike.Value, - forward.Value, stdDevs[i], d, displacement_ ); + forward.Value, stdDevs[i], d, displacement_); } if (type == CapFloorType.Floor || type == CapFloorType.Collar) { double? strike = arguments_.floorRates[i]; double floorletVega = 0.0; - - if (sqrtTime>0.0) + + if (sqrtTime > 0.0) { - stdDevs[i] = Math.Sqrt( vol_.link.blackVariance( fixingDate, strike.Value ) ); - floorletVega = Utils.blackFormulaStdDevDerivative( strike.Value, forward.Value, stdDevs[i], d, displacement_ ) * sqrtTime; + stdDevs[i] = Math.Sqrt(vol_.link.blackVariance(fixingDate, strike.Value)); + floorletVega = Utils.blackFormulaStdDevDerivative(strike.Value, forward.Value, stdDevs[i], d, displacement_) * sqrtTime; } double floorlet = Utils.blackFormula(Option.Type.Put, strike.Value, - forward.Value, stdDevs[i], d, displacement_ ); - if (type == CapFloorType.Floor) + forward.Value, stdDevs[i], d, displacement_); + if (type == CapFloorType.Floor) { values[i] = floorlet; vegas[i] = floorletVega; - } - else + } + else { // a collar is long a cap and short a floor values[i] -= floorlet; vegas[i] -= floorletVega; } - } - value += values[i]; - vega += vegas[i]; + } + value += values[i]; + vega += vegas[i]; } - } - results_.value = value; - results_.additionalResults["vega"] = vega; + } + results_.value = value; + results_.additionalResults["vega"] = vega; - results_.additionalResults["optionletsPrice"] = values; - results_.additionalResults["optionletsVega"] = vegas; - results_.additionalResults["optionletsAtmForward"] = arguments_.forwards; - if (type != CapFloorType.Collar) + results_.additionalResults["optionletsPrice"] = values; + results_.additionalResults["optionletsVega"] = vegas; + results_.additionalResults["optionletsAtmForward"] = arguments_.forwards; + if (type != CapFloorType.Collar) results_.additionalResults["optionletsStdDev"] = stdDevs; - } + } public Handle termStructure() { return discountCurve_; } public Handle volatility() { return vol_; } diff --git a/src/QLNet/Pricingengines/CapFloor/DiscretizedCapFloor.cs b/src/QLNet/Pricingengines/CapFloor/DiscretizedCapFloor.cs new file mode 100644 index 000000000..3a9d6f412 --- /dev/null +++ b/src/QLNet/Pricingengines/CapFloor/DiscretizedCapFloor.cs @@ -0,0 +1,137 @@ +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + public class DiscretizedCapFloor : DiscretizedAsset + { + private CapFloor.Arguments arguments_; + private List startTimes_; + private List endTimes_; + + public DiscretizedCapFloor(CapFloor.Arguments args, + Date referenceDate, + DayCounter dayCounter) + { + arguments_ = args; + + startTimes_ = new InitializedList(args.startDates.Count); + for (int i = 0; i < startTimes_.Count; ++i) + startTimes_[i] = dayCounter.yearFraction(referenceDate, + args.startDates[i]); + + endTimes_ = new InitializedList(args.endDates.Count); + for (int i = 0; i < endTimes_.Count; ++i) + endTimes_[i] = dayCounter.yearFraction(referenceDate, + args.endDates[i]); + } + + public override void reset(int size) + { + values_ = new Vector(size, 0.0); + adjustValues(); + } + + public override List mandatoryTimes() + { + List times = startTimes_; + + for (int j = 0; j < endTimes_.Count; j++) + times.Insert(0, endTimes_[j]); + return times; + } + + protected override void preAdjustValuesImpl() + { + for (int i = 0; i < startTimes_.Count; i++) + { + if (isOnTime(startTimes_[i])) + { + double end = endTimes_[i]; + double tenor = arguments_.accrualTimes[i]; + DiscretizedDiscountBond bond = new DiscretizedDiscountBond(); + bond.initialize(method(), end); + bond.rollback(time_); + + CapFloorType type = arguments_.type; + double gearing = arguments_.gearings[i]; + double nominal = arguments_.nominals[i]; + + if ((type == CapFloorType.Cap) || + (type == CapFloorType.Collar)) + { + double accrual = (double)(1.0 + arguments_.capRates[i] * tenor); + double strike = 1.0 / accrual; + for (int j = 0; j < values_.size(); j++) + values_[j] += nominal * accrual * gearing * + Math.Max(strike - bond.values()[j], 0.0); + } + + if ((type == CapFloorType.Floor) || + (type == CapFloorType.Collar)) + { + double accrual = (double)(1.0 + arguments_.floorRates[i] * tenor); + double strike = 1.0 / accrual; + double mult = (type == CapFloorType.Floor) ? 1.0 : -1.0; + for (int j = 0; j < values_.size(); j++) + values_[j] += nominal * accrual * mult * gearing * + Math.Max(bond.values()[j] - strike, 0.0); + } + } + } + } + + protected override void postAdjustValuesImpl() + { + for (int i = 0; i < endTimes_.Count; i++) + { + if (isOnTime(endTimes_[i])) + { + if (startTimes_[i] < 0.0) + { + double nominal = arguments_.nominals[i]; + double accrual = arguments_.accrualTimes[i]; + double fixing = (double)arguments_.forwards[i]; + double gearing = arguments_.gearings[i]; + CapFloorType type = arguments_.type; + + if (type == CapFloorType.Cap || type == CapFloorType.Collar) + { + double cap = (double) arguments_.capRates[i]; + double capletRate = Math.Max(fixing - cap, 0.0); + values_ += capletRate * accrual * nominal * gearing; + } + + if (type == CapFloorType.Floor || type == CapFloorType.Collar) + { + double floor = (double)arguments_.floorRates[i]; + double floorletRate = Math.Max(floor - fixing, 0.0); + if (type == CapFloorType.Floor) + values_ += floorletRate * accrual * nominal * gearing; + else + values_ -= floorletRate * accrual * nominal * gearing; + } + } + } + } + } + } +} diff --git a/src/QLNet/Pricingengines/CapFloor/analyticcapfloorengine.cs b/src/QLNet/Pricingengines/CapFloor/analyticcapfloorengine.cs deleted file mode 100644 index 57bc37c2e..000000000 --- a/src/QLNet/Pricingengines/CapFloor/analyticcapfloorengine.cs +++ /dev/null @@ -1,135 +0,0 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet -{ - - public class AnalyticCapFloorEngine : GenericModelEngine - { - - /*! \note the term structure is only needed when the short-rate - model cannot provide one itself. - */ - - private Handle termStructure_; - - public AnalyticCapFloorEngine(IAffineModel model) - : this(model, new Handle()) { } - - - public AnalyticCapFloorEngine(IAffineModel model, - Handle termStructure) - : base(model) - { - termStructure_ = termStructure; - termStructure_.registerWith(update); - } - - public override void calculate() - { - if (model_ == null) - throw new ArgumentException("null model"); - - Date referenceDate = new Date(); - DayCounter dayCounter = new DayCounter(); - try{ - TermStructureConsistentModel tsmodel = (TermStructureConsistentModel)model_.link; - ///if (tsmodel != null) - referenceDate = tsmodel.termStructure().link.referenceDate(); - dayCounter = tsmodel.termStructure().link.dayCounter(); - } - //else - catch - { - referenceDate = termStructure_.link.referenceDate(); - dayCounter = termStructure_.link.dayCounter(); - } - - double value = 0.0; - CapFloorType type = arguments_.type; - int nPeriods = arguments_.endDates.Count; - - for (int i = 0; i < nPeriods; i++) - { - double fixingTime = - dayCounter.yearFraction(referenceDate, - arguments_.fixingDates[i]); - double paymentTime = - dayCounter.yearFraction(referenceDate, - arguments_.endDates[i]); - #if QL_TODAYS_PAYMENTS - if (paymentTime >= 0.0) { - #else - if (paymentTime > 0.0) - { - #endif - double tenor = arguments_.accrualTimes[i]; - double fixing = (double)arguments_.forwards[i]; - if (fixingTime <= 0.0) - { - if (type == CapFloorType.Cap || type == CapFloorType.Collar) - { - double discount = model_.link.discount(paymentTime); - double strike = (double)arguments_.capRates[i]; - value += discount * arguments_.nominals[i] * tenor - * arguments_.gearings[i] - * Math.Max(0.0, fixing - strike); - } - if (type == CapFloorType.Floor || type == CapFloorType.Collar) - { - double discount = model_.link.discount(paymentTime); - double strike = (double)arguments_.floorRates[i]; - double mult = (type == CapFloorType.Floor) ? 1.0 : -1.0; - value += discount * arguments_.nominals[i] * tenor - * mult * arguments_.gearings[i] - * Math.Max(0.0, strike - fixing); - } - } - else - { - double maturity = - dayCounter.yearFraction(referenceDate, - arguments_.startDates[i]); - if (type == CapFloorType.Cap || type == CapFloorType.Collar) - { - double temp = 1.0 + (double)arguments_.capRates[i] * tenor; - value += arguments_.nominals[i] * - arguments_.gearings[i] * temp * - model_.link.discountBondOption(Option.Type.Put, 1.0 / temp, - maturity, paymentTime); - } - if (type == CapFloorType.Floor || type == CapFloorType.Collar) - { - double temp = 1.0 + (double)arguments_.floorRates[i] * tenor; - double mult = (type == CapFloorType.Floor) ? 1.0 : -1.0; - value += arguments_.nominals[i] * - arguments_.gearings[i] * temp * mult * - model_.link.discountBondOption(Option.Type.Call, 1.0 / temp, - maturity, paymentTime); - } - } - } - } - results_.value = value; - } - } -} \ No newline at end of file diff --git a/src/QLNet/Pricingengines/CapFloor/discretizedcapfloor.cs b/src/QLNet/Pricingengines/CapFloor/discretizedcapfloor.cs deleted file mode 100644 index eb9bbf7b6..000000000 --- a/src/QLNet/Pricingengines/CapFloor/discretizedcapfloor.cs +++ /dev/null @@ -1,125 +0,0 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet -{ - public class DiscretizedCapFloor : DiscretizedAsset { - private CapFloor.Arguments arguments_; - private List startTimes_; - private List endTimes_; - - public DiscretizedCapFloor(CapFloor.Arguments args, - Date referenceDate, - DayCounter dayCounter) - { - arguments_ = args; - - startTimes_= new InitializedList(args.startDates.Count); - for (int i = 0; i < startTimes_.Count; ++i) - startTimes_[i] = dayCounter.yearFraction(referenceDate, - args.startDates[i]); - - endTimes_ = new InitializedList(args.endDates.Count); - for (int i = 0; i < endTimes_.Count; ++i) - endTimes_[i] = dayCounter.yearFraction(referenceDate, - args.endDates[i]); - } - - public override void reset(int size) { - values_ = new Vector(size, 0.0); - adjustValues(); - } - - public override List mandatoryTimes() { - List times = startTimes_; - - for (int j = 0; j < endTimes_.Count; j++) - times.Insert(0, endTimes_[j]); - return times; - } - - protected override void preAdjustValuesImpl() - { - for (int i=0; i. -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,35 +29,35 @@ reproducing numerical derivatives. */ public class AnalyticCliquetEngine : CliquetOption.Engine { - public AnalyticCliquetEngine( GeneralizedBlackScholesProcess process) + public AnalyticCliquetEngine(GeneralizedBlackScholesProcess process) { - process_=process; + process_ = process; process_.registerWith(update); } public override void calculate() { Utils.QL_REQUIRE(arguments_.accruedCoupon == null && - arguments_.lastFixing == null,()=> - "this engine cannot price options already started"); + arguments_.lastFixing == null, () => + "this engine cannot price options already started"); Utils.QL_REQUIRE(arguments_.localCap == null && - arguments_.localFloor == null && - arguments_.globalCap == null && - arguments_.globalFloor == null,()=> - "this engine cannot price capped/floored options"); + arguments_.localFloor == null && + arguments_.globalCap == null && + arguments_.globalFloor == null, () => + "this engine cannot price capped/floored options"); - Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European,()=> "not an European option"); + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European option"); PercentageStrikePayoff moneyness = arguments_.payoff as PercentageStrikePayoff; - Utils.QL_REQUIRE(moneyness!=null,()=> "wrong payoff given"); + Utils.QL_REQUIRE(moneyness != null, () => "wrong payoff given"); List resetDates = arguments_.resetDates; resetDates.Add(arguments_.exercise.lastDate()); double underlying = process_.stateVariable().link.value(); - Utils.QL_REQUIRE(underlying > 0.0,()=> "negative or null underlying"); + Utils.QL_REQUIRE(underlying > 0.0, () => "negative or null underlying"); double strike = underlying * moneyness.strike(); - StrikedTypePayoff payoff = new PlainVanillaPayoff(moneyness.optionType(),strike); + StrikedTypePayoff payoff = new PlainVanillaPayoff(moneyness.optionType(), strike); results_.value = 0.0; results_.delta = results_.gamma = 0.0; @@ -65,15 +65,15 @@ public override void calculate() results_.rho = results_.dividendRho = 0.0; results_.vega = 0.0; - for (int i = 1; i < resetDates.Count; i++) + for (int i = 1; i < resetDates.Count; i++) { - double weight = process_.dividendYield().link.discount(resetDates[i-1]); + double weight = process_.dividendYield().link.discount(resetDates[i - 1]); double discount = process_.riskFreeRate().link.discount(resetDates[i]) / - process_.riskFreeRate().link.discount(resetDates[i-1]); + process_.riskFreeRate().link.discount(resetDates[i - 1]); double qDiscount = process_.dividendYield().link.discount(resetDates[i]) / - process_.dividendYield().link.discount(resetDates[i-1]); - double forward = underlying*qDiscount/discount; - double variance = process_.blackVolatility().link.blackForwardVariance(resetDates[i-1],resetDates[i],strike); + process_.dividendYield().link.discount(resetDates[i - 1]); + double forward = underlying * qDiscount / discount; + double variance = process_.blackVolatility().link.blackForwardVariance(resetDates[i - 1], resetDates[i], strike); BlackCalculator black = new BlackCalculator(payoff, forward, Math.Sqrt(variance), discount); @@ -87,22 +87,22 @@ public override void calculate() black.beta()); results_.gamma += 0.0; results_.theta += process_.dividendYield().link.forwardRate( - resetDates[i-1], resetDates[i], rfdc, Compounding.Continuous, Frequency.NoFrequency).value() * - weight * black.value(); + resetDates[i - 1], resetDates[i], rfdc, Compounding.Continuous, Frequency.NoFrequency).value() * + weight * black.value(); - double dt = rfdc.yearFraction(resetDates[i-1],resetDates[i]); + double dt = rfdc.yearFraction(resetDates[i - 1], resetDates[i]); results_.rho += weight * black.rho(dt); - double t = divdc.yearFraction( process_.dividendYield().link.referenceDate(),resetDates[i-1]); - dt = divdc.yearFraction(resetDates[i-1],resetDates[i]); + double t = divdc.yearFraction(process_.dividendYield().link.referenceDate(), resetDates[i - 1]); + dt = divdc.yearFraction(resetDates[i - 1], resetDates[i]); results_.dividendRho += weight * (black.dividendRho(dt) - t * black.value()); - dt = voldc.yearFraction(resetDates[i-1], resetDates[i]); + dt = voldc.yearFraction(resetDates[i - 1], resetDates[i]); results_.vega += weight * black.vega(dt); } } - + private GeneralizedBlackScholesProcess process_; } } diff --git a/src/QLNet/Pricingengines/Cliquet/AnalyticPerformanceEngine.cs b/src/QLNet/Pricingengines/Cliquet/AnalyticPerformanceEngine.cs index bf7eb4860..b1c4e5f6e 100644 --- a/src/QLNet/Pricingengines/Cliquet/AnalyticPerformanceEngine.cs +++ b/src/QLNet/Pricingengines/Cliquet/AnalyticPerformanceEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,29 +29,29 @@ public class AnalyticPerformanceEngine : CliquetOption.Engine public AnalyticPerformanceEngine(GeneralizedBlackScholesProcess process) { process_ = process; - process_.registerWith( update ); + process_.registerWith(update); } public override void calculate() { Utils.QL_REQUIRE(arguments_.accruedCoupon == null && - arguments_.lastFixing == null,()=> + arguments_.lastFixing == null, () => "this engine cannot price options already started"); Utils.QL_REQUIRE(arguments_.localCap == null && arguments_.localFloor == null && arguments_.globalCap == null && - arguments_.globalFloor == null,()=> + arguments_.globalFloor == null, () => "this engine cannot price capped/floored options"); - Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European,()=>"not an European option"); + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European option"); PercentageStrikePayoff moneyness = arguments_.payoff as PercentageStrikePayoff; - Utils.QL_REQUIRE(moneyness!= null,()=> "wrong payoff given"); + Utils.QL_REQUIRE(moneyness != null, () => "wrong payoff given"); List resetDates = arguments_.resetDates; resetDates.Add(arguments_.exercise.lastDate()); double underlying = process_.stateVariable().link.value(); - Utils.QL_REQUIRE(underlying > 0.0,()=> "negative or null underlying"); + Utils.QL_REQUIRE(underlying > 0.0, () => "negative or null underlying"); StrikedTypePayoff payoff = new PlainVanillaPayoff(moneyness.optionType(), 1.0); @@ -61,17 +61,17 @@ public override void calculate() results_.rho = results_.dividendRho = 0.0; results_.vega = 0.0; - for (int i = 1; i < resetDates.Count; i++) + for (int i = 1; i < resetDates.Count; i++) { - double discount = process_.riskFreeRate().link.discount(resetDates[i-1]); + double discount = process_.riskFreeRate().link.discount(resetDates[i - 1]); double rDiscount = process_.riskFreeRate().link.discount(resetDates[i]) / - process_.riskFreeRate().link.discount(resetDates[i-1]); + process_.riskFreeRate().link.discount(resetDates[i - 1]); double qDiscount = process_.dividendYield().link.discount(resetDates[i]) / - process_.dividendYield().link.discount(resetDates[i-1]); - double forward = (1.0/moneyness.strike())*qDiscount/rDiscount; + process_.dividendYield().link.discount(resetDates[i - 1]); + double forward = (1.0 / moneyness.strike()) * qDiscount / rDiscount; double variance = process_.blackVolatility().link.blackForwardVariance( - resetDates[i-1],resetDates[i], - underlying * moneyness.strike()); + resetDates[i - 1], resetDates[i], + underlying * moneyness.strike()); BlackCalculator black = new BlackCalculator(payoff, forward, Math.Sqrt(variance), rDiscount); @@ -83,23 +83,23 @@ public override void calculate() results_.delta += 0.0; results_.gamma += 0.0; results_.theta += process_.riskFreeRate().link.forwardRate( - resetDates[i-1], resetDates[i], rfdc, Compounding.Continuous, Frequency.NoFrequency).value() * - discount * moneyness.strike() * black.value(); + resetDates[i - 1], resetDates[i], rfdc, Compounding.Continuous, Frequency.NoFrequency).value() * + discount * moneyness.strike() * black.value(); - double dt = rfdc.yearFraction(resetDates[i-1],resetDates[i]); - double t = rfdc.yearFraction( process_.riskFreeRate().link.referenceDate(),resetDates[i-1]); + double dt = rfdc.yearFraction(resetDates[i - 1], resetDates[i]); + double t = rfdc.yearFraction(process_.riskFreeRate().link.referenceDate(), resetDates[i - 1]); results_.rho += discount * moneyness.strike() * (black.rho(dt) - t * black.value()); - dt = divdc.yearFraction(resetDates[i-1],resetDates[i]); + dt = divdc.yearFraction(resetDates[i - 1], resetDates[i]); results_.dividendRho += discount * moneyness.strike() * black.dividendRho(dt); - dt = voldc.yearFraction(resetDates[i-1], resetDates[i]); + dt = voldc.yearFraction(resetDates[i - 1], resetDates[i]); results_.vega += discount * moneyness.strike() * black.vega(dt); - } + } + + } - } - private GeneralizedBlackScholesProcess process_; } } diff --git a/src/QLNet/Pricingengines/Forward/ForwardPerformanceVanillaEngine.cs b/src/QLNet/Pricingengines/Forward/ForwardPerformanceVanillaEngine.cs index da4a1ef8a..b779e04ed 100644 --- a/src/QLNet/Pricingengines/Forward/ForwardPerformanceVanillaEngine.cs +++ b/src/QLNet/Pricingengines/Forward/ForwardPerformanceVanillaEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -31,8 +31,8 @@ reproducing numerical derivatives. */ public class ForwardPerformanceVanillaEngine : ForwardVanillaEngine { - public ForwardPerformanceVanillaEngine( GeneralizedBlackScholesProcess process, GetOriginalEngine getEngine ) - : base( process, getEngine ) { } + public ForwardPerformanceVanillaEngine(GeneralizedBlackScholesProcess process, GetOriginalEngine getEngine) + : base(process, getEngine) { } public override void calculate() { this.setup(); @@ -43,8 +43,8 @@ protected override void getOriginalResults() { DayCounter rfdc = this.process_.riskFreeRate().link.dayCounter(); double resetTime = rfdc.yearFraction(this.process_.riskFreeRate().link.referenceDate(), - this.arguments_.resetDate ); - double discR = this.process_.riskFreeRate().link.discount(this.arguments_.resetDate ); + this.arguments_.resetDate); + double discR = this.process_.riskFreeRate().link.discount(this.arguments_.resetDate); // it's a performance option discR /= this.process_.stateVariable().link.value(); @@ -53,8 +53,8 @@ protected override void getOriginalResults() this.results_.delta = 0.0; this.results_.gamma = 0.0; this.results_.theta = this.process_.riskFreeRate().link. - zeroRate( this.arguments_.resetDate, rfdc, Compounding.Continuous, Frequency.NoFrequency ).value() - * this.results_.value; + zeroRate(this.arguments_.resetDate, rfdc, Compounding.Continuous, Frequency.NoFrequency).value() + * this.results_.value; this.results_.vega = discR * this.originalResults_.vega; this.results_.rho = -resetTime * this.results_.value + discR * this.originalResults_.rho; this.results_.dividendRho = discR * this.originalResults_.dividendRho; diff --git a/src/QLNet/Pricingengines/Forward/ForwardVanillaEngine.cs b/src/QLNet/Pricingengines/Forward/ForwardVanillaEngine.cs index 4d5b73d41..ceb8a06f0 100644 --- a/src/QLNet/Pricingengines/Forward/ForwardVanillaEngine.cs +++ b/src/QLNet/Pricingengines/Forward/ForwardVanillaEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -32,9 +32,9 @@ reproducing numerical derivatives. public class ForwardVanillaEngine : GenericEngine { - public delegate IPricingEngine GetOriginalEngine( GeneralizedBlackScholesProcess process ); + public delegate IPricingEngine GetOriginalEngine(GeneralizedBlackScholesProcess process); - public ForwardVanillaEngine( GeneralizedBlackScholesProcess process, GetOriginalEngine getEngine) + public ForwardVanillaEngine(GeneralizedBlackScholesProcess process, GetOriginalEngine getEngine) { process_ = process; process_.registerWith(update); @@ -46,77 +46,77 @@ public override void calculate() originalEngine_.calculate(); getOriginalResults(); } - + protected void setup() { StrikedTypePayoff argumentsPayoff = this.arguments_.payoff as StrikedTypePayoff; - Utils.QL_REQUIRE(argumentsPayoff != null,()=> "wrong payoff given"); + Utils.QL_REQUIRE(argumentsPayoff != null, () => "wrong payoff given"); StrikedTypePayoff payoff = new PlainVanillaPayoff(argumentsPayoff.optionType(), - this.arguments_.moneyness * process_.x0()); + this.arguments_.moneyness * process_.x0()); // maybe the forward value is "better", in some fashion // the right level is needed in order to interpolate // the vol Handle spot = process_.stateVariable(); - Utils.QL_REQUIRE(spot.link.value() >= 0.0,()=> "negative or null underlting given"); + Utils.QL_REQUIRE(spot.link.value() >= 0.0, () => "negative or null underlting given"); Handle dividendYield = new Handle( - new ImpliedTermStructure(process_.dividendYield(),this.arguments_.resetDate)); + new ImpliedTermStructure(process_.dividendYield(), this.arguments_.resetDate)); Handle riskFreeRate = new Handle( - new ImpliedTermStructure(process_.riskFreeRate(),this.arguments_.resetDate)); + new ImpliedTermStructure(process_.riskFreeRate(), this.arguments_.resetDate)); // The following approach is ok if the vol is at most // time dependant. It is plain wrong if it is asset dependant. // In the latter case the right solution would be stochastic // volatility or at least local volatility (which unfortunately // implies an unrealistic time-decreasing smile) - Handle blackVolatility= new Handle( - new ImpliedVolTermStructure(process_.blackVolatility(),this.arguments_.resetDate)); + Handle blackVolatility = new Handle( + new ImpliedVolTermStructure(process_.blackVolatility(), this.arguments_.resetDate)); GeneralizedBlackScholesProcess fwdProcess = new GeneralizedBlackScholesProcess(spot, dividendYield, - riskFreeRate,blackVolatility); + riskFreeRate, blackVolatility); - originalEngine_ = getOriginalEngine_(fwdProcess); + originalEngine_ = getOriginalEngine_(fwdProcess); originalEngine_.reset(); originalArguments_ = originalEngine_.getArguments() as Option.Arguments; - Utils.QL_REQUIRE(originalArguments_!= null,()=> "wrong engine type"); + Utils.QL_REQUIRE(originalArguments_ != null, () => "wrong engine type"); originalResults_ = originalEngine_.getResults() as OneAssetOption.Results; - Utils.QL_REQUIRE(originalResults_!= null,()=> "wrong engine type"); + Utils.QL_REQUIRE(originalResults_ != null, () => "wrong engine type"); originalArguments_.payoff = payoff; originalArguments_.exercise = this.arguments_.exercise; originalArguments_.validate(); - + } protected virtual void getOriginalResults() { DayCounter rfdc = process_.riskFreeRate().link.dayCounter(); DayCounter divdc = process_.dividendYield().link.dayCounter(); - double resetTime = rfdc.yearFraction( process_.riskFreeRate().link.referenceDate(),this.arguments_.resetDate ); - double discQ = process_.dividendYield().link.discount(this.arguments_.resetDate ); + double resetTime = rfdc.yearFraction(process_.riskFreeRate().link.referenceDate(), this.arguments_.resetDate); + double discQ = process_.dividendYield().link.discount(this.arguments_.resetDate); this.results_.value = discQ * originalResults_.value; // I need the strike derivative here ... - if ( originalResults_.delta != null && originalResults_.strikeSensitivity != null ) + if (originalResults_.delta != null && originalResults_.strikeSensitivity != null) { - this.results_.delta = discQ * ( originalResults_.delta + - this.arguments_.moneyness * originalResults_.strikeSensitivity ); + this.results_.delta = discQ * (originalResults_.delta + + this.arguments_.moneyness * originalResults_.strikeSensitivity); } this.results_.gamma = 0.0; this.results_.theta = process_.dividendYield().link. - zeroRate( this.arguments_.resetDate, divdc, Compounding.Continuous, Frequency.NoFrequency ).value() - * this.results_.value; - if ( originalResults_.vega != null) + zeroRate(this.arguments_.resetDate, divdc, Compounding.Continuous, Frequency.NoFrequency).value() + * this.results_.value; + if (originalResults_.vega != null) this.results_.vega = discQ * originalResults_.vega; - if ( originalResults_.rho != null ) + if (originalResults_.rho != null) this.results_.rho = discQ * originalResults_.rho; - if ( originalResults_.dividendRho != null ) + if (originalResults_.dividendRho != null) { this.results_.dividendRho = -resetTime * this.results_.value - + discQ * originalResults_.dividendRho; + + discQ * originalResults_.dividendRho; } } protected GeneralizedBlackScholesProcess process_; diff --git a/src/QLNet/Pricingengines/genericmodelengine.cs b/src/QLNet/Pricingengines/GenericModelEngine.cs similarity index 64% rename from src/QLNet/Pricingengines/genericmodelengine.cs rename to src/QLNet/Pricingengines/GenericModelEngine.cs index 472140d12..09fcee7df 100644 --- a/src/QLNet/Pricingengines/genericmodelengine.cs +++ b/src/QLNet/Pricingengines/GenericModelEngine.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,29 +22,29 @@ namespace QLNet { public class GenericModelEngine - : GenericEngine - where ArgumentsType : IPricingEngineArguments, new() - where ResultsType : IPricingEngineResults, new() - where ModelType : IObservable + : GenericEngine + where ArgumentsType : IPricingEngineArguments, new () + where ResultsType : IPricingEngineResults, new () + where ModelType : IObservable { public GenericModelEngine() { } - public GenericModelEngine( Handle model ) + public GenericModelEngine(Handle model) { model_ = model; - model_.registerWith( update ); + model_.registerWith(update); } - public GenericModelEngine(ModelType model ) + public GenericModelEngine(ModelType model) { model_ = new Handle(model); - model_.registerWith( update ); + model_.registerWith(update); } - public void setModel( Handle model ) + public void setModel(Handle model) { - if ( model_ != null ) - model_.unregisterWith( update ); + if (model_ != null) + model_.unregisterWith(update); model_ = model; - if ( model_ != null ) - model_.registerWith( update ); + if (model_ != null) + model_.registerWith(update); update(); } diff --git a/src/QLNet/Pricingengines/Greeks.cs b/src/QLNet/Pricingengines/Greeks.cs index d0a430669..ed968b2d4 100644 --- a/src/QLNet/Pricingengines/Greeks.cs +++ b/src/QLNet/Pricingengines/Greeks.cs @@ -1,41 +1,43 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { - public static partial class Utils { - //! default theta calculation for Black-Scholes options - public static double blackScholesTheta(GeneralizedBlackScholesProcess p, double value, double delta, double gamma) - { - - double u = p.stateVariable().currentLink().value(); - double r = p.riskFreeRate().currentLink().zeroRate(0.0, Compounding.Continuous).rate(); - double q = p.dividendYield().currentLink().zeroRate(0.0, Compounding.Continuous).rate(); - double v = p.localVolatility().currentLink().localVol(0.0, u, false); - - return r *value -(r-q)*u *delta - 0.5 *v *v *u *u *gamma; - } - - //! default theta-per-day calculation - public static double defaultThetaPerDay(double theta) - { - return theta/365.0; - } - } +namespace QLNet +{ + public static partial class Utils + { + //! default theta calculation for Black-Scholes options + public static double blackScholesTheta(GeneralizedBlackScholesProcess p, double value, double delta, double gamma) + { + + double u = p.stateVariable().currentLink().value(); + double r = p.riskFreeRate().currentLink().zeroRate(0.0, Compounding.Continuous).rate(); + double q = p.dividendYield().currentLink().zeroRate(0.0, Compounding.Continuous).rate(); + double v = p.localVolatility().currentLink().localVol(0.0, u, false); + + return r * value - (r - q) * u * delta - 0.5 * v * v * u * u * gamma; + } + + //! default theta-per-day calculation + public static double defaultThetaPerDay(double theta) + { + return theta / 365.0; + } + } } diff --git a/src/QLNet/Pricingengines/LatticeShortRateModelEngine.cs b/src/QLNet/Pricingengines/LatticeShortRateModelEngine.cs new file mode 100644 index 000000000..060baf773 --- /dev/null +++ b/src/QLNet/Pricingengines/LatticeShortRateModelEngine.cs @@ -0,0 +1,68 @@ +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + + //! Engine for a short-rate model specialized on a lattice + /*! Derived engines only need to implement the calculate() + method + */ + public class LatticeShortRateModelEngine + : GenericModelEngine + where ArgumentsType : IPricingEngineArguments, new () + where ResultsType : IPricingEngineResults, new () + + { + protected TimeGrid timeGrid_; + protected int timeSteps_; + protected Lattice lattice_; + + public LatticeShortRateModelEngine(ShortRateModel model, + int timeSteps) + : base(model) + { + timeSteps_ = timeSteps; + Utils.QL_REQUIRE(timeSteps > 0, () => "timeSteps must be positive, " + timeSteps + " not allowed"); + } + + public LatticeShortRateModelEngine(ShortRateModel model, + TimeGrid timeGrid) + : base(model) + { + timeGrid_ = new TimeGrid(timeGrid.Last(), timeGrid.size() - 1 /*timeGrid.dt(1) - timeGrid.dt(0)*/); + timeGrid_ = timeGrid; + timeSteps_ = 0; + lattice_ = this.model_.link.tree(timeGrid); + } + + #region PricingEngine + #region Observer & Observable + public override void update() + { + if (!timeGrid_.empty()) + lattice_ = this.model_.link.tree(timeGrid_); + notifyObservers(); + } + #endregion + #endregion + } + +} \ No newline at end of file diff --git a/src/QLNet/Pricingengines/Loan/DiscountingLoanEngine.cs b/src/QLNet/Pricingengines/Loan/DiscountingLoanEngine.cs index 0b3c0f44e..52fe29aa6 100644 --- a/src/QLNet/Pricingengines/Loan/DiscountingLoanEngine.cs +++ b/src/QLNet/Pricingengines/Loan/DiscountingLoanEngine.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) Copyright (C) 2017 Francois Botha (igitur@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,44 +20,44 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class DiscountingLoanEngine : Loan.Engine - { - private readonly Handle discountCurve_; - private readonly bool? includeSettlementDateFlows_; - - public Handle discountCurve() { return discountCurve_; } - - public DiscountingLoanEngine(Handle discountCurve, bool? includeSettlementDateFlows = null) - { - discountCurve_ = discountCurve; - discountCurve_.registerWith(this.update); - includeSettlementDateFlows_ = includeSettlementDateFlows; - } - - public override void calculate() - { - QLNet.Utils.QL_REQUIRE(!discountCurve_.empty(), () => "discounting term structure handle is empty"); - - results_.valuationDate = discountCurve_.link.referenceDate(); - bool includeRefDateFlows = - includeSettlementDateFlows_.HasValue ? - includeSettlementDateFlows_.Value : - Settings.includeReferenceDateEvents; - - results_.value = 0; - results_.cash = 0; - for (int i = 0; i < arguments_.legs.Count; ++i) - { - results_.value += CashFlows.npv(arguments_.legs[i], - discountCurve_, - includeRefDateFlows, - results_.valuationDate, - results_.valuationDate) - * arguments_.payer[i]; - - results_.cash += CashFlows.cash(arguments_.legs[i], results_.valuationDate) - * arguments_.payer[i]; - } - } - } + public class DiscountingLoanEngine : Loan.Engine + { + private readonly Handle discountCurve_; + private readonly bool? includeSettlementDateFlows_; + + public Handle discountCurve() { return discountCurve_; } + + public DiscountingLoanEngine(Handle discountCurve, bool? includeSettlementDateFlows = null) + { + discountCurve_ = discountCurve; + discountCurve_.registerWith(this.update); + includeSettlementDateFlows_ = includeSettlementDateFlows; + } + + public override void calculate() + { + QLNet.Utils.QL_REQUIRE(!discountCurve_.empty(), () => "discounting term structure handle is empty"); + + results_.valuationDate = discountCurve_.link.referenceDate(); + bool includeRefDateFlows = + includeSettlementDateFlows_.HasValue ? + includeSettlementDateFlows_.Value : + Settings.includeReferenceDateEvents; + + results_.value = 0; + results_.cash = 0; + for (int i = 0; i < arguments_.legs.Count; ++i) + { + results_.value += CashFlows.npv(arguments_.legs[i], + discountCurve_, + includeRefDateFlows, + results_.valuationDate, + results_.valuationDate) + * arguments_.payer[i]; + + results_.cash += CashFlows.cash(arguments_.legs[i], results_.valuationDate) + * arguments_.payer[i]; + } + } + } } diff --git a/src/QLNet/Pricingengines/Lookback/AnalyticContinuousFixedLookbackEngine.cs b/src/QLNet/Pricingengines/Lookback/AnalyticContinuousFixedLookbackEngine.cs index 8b6a581c9..48ec2d4c8 100644 --- a/src/QLNet/Pricingengines/Lookback/AnalyticContinuousFixedLookbackEngine.cs +++ b/src/QLNet/Pricingengines/Lookback/AnalyticContinuousFixedLookbackEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -31,23 +31,23 @@ public AnalyticContinuousFixedLookbackEngine(GeneralizedBlackScholesProcess proc public override void calculate() { PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; - Utils.QL_REQUIRE(payoff!=null,()=> "Non-plain payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "Non-plain payoff given"); - Utils.QL_REQUIRE(process_.x0() > 0.0,()=> "negative or null underlying"); + Utils.QL_REQUIRE(process_.x0() > 0.0, () => "negative or null underlying"); double strike = payoff.strike(); - switch (payoff.optionType()) + switch (payoff.optionType()) { case Option.Type.Call: - Utils.QL_REQUIRE(payoff.strike()>=0.0,()=>"Strike must be positive or null"); + Utils.QL_REQUIRE(payoff.strike() >= 0.0, () => "Strike must be positive or null"); if (strike <= minmax()) results_.value = A(1) + C(1); else results_.value = B(1); break; case Option.Type.Put: - Utils.QL_REQUIRE(payoff.strike()>0.0,()=>"Strike must be positive"); + Utils.QL_REQUIRE(payoff.strike() > 0.0, () => "Strike must be positive"); if (strike >= minmax()) results_.value = A(-1) + C(-1); else @@ -58,68 +58,68 @@ public override void calculate() break; } } - + private GeneralizedBlackScholesProcess process_; private CumulativeNormalDistribution f_ = new CumulativeNormalDistribution(); // helper methods private double underlying() { return process_.x0(); } - private double strike() + private double strike() { PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; - Utils.QL_REQUIRE(payoff!=null,()=> "Non-plain payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "Non-plain payoff given"); return payoff.strike(); } - private double residualTime() { return process_.time( arguments_.exercise.lastDate() ); } - private double volatility() { return process_.blackVolatility().link.blackVol( residualTime(), strike() ); } + private double residualTime() { return process_.time(arguments_.exercise.lastDate()); } + private double volatility() { return process_.blackVolatility().link.blackVol(residualTime(), strike()); } private double minmax() { return arguments_.minmax.GetValueOrDefault(); } private double stdDeviation() {return volatility() * Math.Sqrt(residualTime());} private double riskFreeRate() { - return process_.riskFreeRate().link.zeroRate( residualTime(), - Compounding.Continuous,Frequency.NoFrequency ).value(); + return process_.riskFreeRate().link.zeroRate(residualTime(), + Compounding.Continuous, Frequency.NoFrequency).value(); } - private double riskFreeDiscount() { return process_.riskFreeRate().link.discount( residualTime() ); } + private double riskFreeDiscount() { return process_.riskFreeRate().link.discount(residualTime()); } private double dividendYield() { - return process_.dividendYield().link.zeroRate( residualTime(), - Compounding.Continuous, Frequency.NoFrequency ).value(); + return process_.dividendYield().link.zeroRate(residualTime(), + Compounding.Continuous, Frequency.NoFrequency).value(); } - private double dividendDiscount() { return process_.dividendYield().link.discount( residualTime() ); } - private double A( double eta ) + private double dividendDiscount() { return process_.dividendYield().link.discount(residualTime()); } + private double A(double eta) { double vol = volatility(); - double lambda = 2.0*(riskFreeRate() - dividendYield())/(vol*vol); - double ss = underlying()/minmax(); - double d1 = Math.Log(ss)/stdDeviation() + 0.5*(lambda+1.0)*stdDeviation(); - double N1 = f_.value(eta*d1); - double N2 = f_.value(eta*(d1-stdDeviation())); - double N3 = f_.value(eta*(d1-lambda*stdDeviation())); - double N4 = f_.value(eta*d1); + double lambda = 2.0 * (riskFreeRate() - dividendYield()) / (vol * vol); + double ss = underlying() / minmax(); + double d1 = Math.Log(ss) / stdDeviation() + 0.5 * (lambda + 1.0) * stdDeviation(); + double N1 = f_.value(eta * d1); + double N2 = f_.value(eta * (d1 - stdDeviation())); + double N3 = f_.value(eta * (d1 - lambda * stdDeviation())); + double N4 = f_.value(eta * d1); double powss = Math.Pow(ss, -lambda); - return eta*(underlying() * dividendDiscount() * N1 - - minmax() * riskFreeDiscount() * N2 - - underlying() * riskFreeDiscount() * - (powss * N3 - dividendDiscount()* N4/riskFreeDiscount())/lambda); + return eta * (underlying() * dividendDiscount() * N1 - + minmax() * riskFreeDiscount() * N2 - + underlying() * riskFreeDiscount() * + (powss * N3 - dividendDiscount() * N4 / riskFreeDiscount()) / lambda); } - private double B( double eta ) + private double B(double eta) { double vol = volatility(); - double lambda = 2.0*(riskFreeRate() - dividendYield())/(vol*vol); - double ss = underlying()/strike(); - double d1 = Math.Log(ss)/stdDeviation() + 0.5*(lambda+1.0)*stdDeviation(); - double N1 = f_.value(eta*d1); - double N2 = f_.value(eta*(d1-stdDeviation())); - double N3 = f_.value(eta*(d1-lambda*stdDeviation())); - double N4 = f_.value(eta*d1); + double lambda = 2.0 * (riskFreeRate() - dividendYield()) / (vol * vol); + double ss = underlying() / strike(); + double d1 = Math.Log(ss) / stdDeviation() + 0.5 * (lambda + 1.0) * stdDeviation(); + double N1 = f_.value(eta * d1); + double N2 = f_.value(eta * (d1 - stdDeviation())); + double N3 = f_.value(eta * (d1 - lambda * stdDeviation())); + double N4 = f_.value(eta * d1); double powss = Math.Pow(ss, -lambda); - return eta*(underlying() * dividendDiscount() * N1 - - strike() * riskFreeDiscount() * N2 - - underlying() * riskFreeDiscount() * - (powss * N3 - dividendDiscount()* N4/riskFreeDiscount())/lambda); + return eta * (underlying() * dividendDiscount() * N1 - + strike() * riskFreeDiscount() * N2 - + underlying() * riskFreeDiscount() * + (powss * N3 - dividendDiscount() * N4 / riskFreeDiscount()) / lambda); } - private double C( double eta ) + private double C(double eta) { - return eta * ( riskFreeDiscount() * ( minmax() - strike() ) ); + return eta * (riskFreeDiscount() * (minmax() - strike())); } } } diff --git a/src/QLNet/Pricingengines/Lookback/AnalyticContinuousFloatingLookbackEngine.cs b/src/QLNet/Pricingengines/Lookback/AnalyticContinuousFloatingLookbackEngine.cs index 999afff41..8fb3fe5b7 100644 --- a/src/QLNet/Pricingengines/Lookback/AnalyticContinuousFloatingLookbackEngine.cs +++ b/src/QLNet/Pricingengines/Lookback/AnalyticContinuousFloatingLookbackEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -25,17 +25,17 @@ public class AnalyticContinuousFloatingLookbackEngine : ContinuousFloatingLookba { public AnalyticContinuousFloatingLookbackEngine(GeneralizedBlackScholesProcess process) { - process_=process; + process_ = process; process_.registerWith(update); } public override void calculate() { FloatingTypePayoff payoff = arguments_.payoff as FloatingTypePayoff; - Utils.QL_REQUIRE(payoff != null,()=> "Non-floating payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "Non-floating payoff given"); - Utils.QL_REQUIRE(process_.x0() > 0.0,()=> "negative or null underlying"); + Utils.QL_REQUIRE(process_.x0() > 0.0, () => "negative or null underlying"); - switch (payoff.optionType()) + switch (payoff.optionType()) { case Option.Type.Call: results_.value = A(1); @@ -48,42 +48,42 @@ public override void calculate() break; } } - + private GeneralizedBlackScholesProcess process_; private CumulativeNormalDistribution f_ = new CumulativeNormalDistribution(); // helper methods private double underlying() { return process_.x0(); } - private double residualTime() { return process_.time( arguments_.exercise.lastDate() ); } - private double volatility() { return process_.blackVolatility().link.blackVol( residualTime(), minmax() ); } + private double residualTime() { return process_.time(arguments_.exercise.lastDate()); } + private double volatility() { return process_.blackVolatility().link.blackVol(residualTime(), minmax()); } private double minmax() { return arguments_.minmax.GetValueOrDefault(); } private double stdDeviation() {return volatility() * Math.Sqrt(residualTime());} private double riskFreeRate() { - return process_.riskFreeRate().link.zeroRate( residualTime(), - Compounding.Continuous,Frequency.NoFrequency ).value(); + return process_.riskFreeRate().link.zeroRate(residualTime(), + Compounding.Continuous, Frequency.NoFrequency).value(); } - private double riskFreeDiscount() { return process_.riskFreeRate().link.discount( residualTime() ); } + private double riskFreeDiscount() { return process_.riskFreeRate().link.discount(residualTime()); } private double dividendYield() { - return process_.dividendYield().link.zeroRate( residualTime(), - Compounding.Continuous, Frequency.NoFrequency ).value(); + return process_.dividendYield().link.zeroRate(residualTime(), + Compounding.Continuous, Frequency.NoFrequency).value(); } - private double dividendDiscount() { return process_.dividendYield().link.discount( residualTime() ); } - private double A( double eta ) + private double dividendDiscount() { return process_.dividendYield().link.discount(residualTime()); } + private double A(double eta) { double vol = volatility(); - double lambda = 2.0*(riskFreeRate() - dividendYield())/(vol*vol); - double s = underlying()/minmax(); - double d1 = Math.Log(s)/stdDeviation() + 0.5*(lambda+1.0)*stdDeviation(); - double n1 = f_.value(eta*d1); - double n2 = f_.value(eta*(d1-stdDeviation())); - double n3 = f_.value(eta*(-d1+lambda*stdDeviation())); - double n4 = f_.value(eta*-d1); + double lambda = 2.0 * (riskFreeRate() - dividendYield()) / (vol * vol); + double s = underlying() / minmax(); + double d1 = Math.Log(s) / stdDeviation() + 0.5 * (lambda + 1.0) * stdDeviation(); + double n1 = f_.value(eta * d1); + double n2 = f_.value(eta * (d1 - stdDeviation())); + double n3 = f_.value(eta * (-d1 + lambda * stdDeviation())); + double n4 = f_.value(eta * -d1); double pow_s = Math.Pow(s, -lambda); - return eta*((underlying() * dividendDiscount() * n1 - - minmax() * riskFreeDiscount() * n2) + - (underlying() * riskFreeDiscount() * - (pow_s * n3 - dividendDiscount()* n4/riskFreeDiscount())/lambda)); + return eta * ((underlying() * dividendDiscount() * n1 - + minmax() * riskFreeDiscount() * n2) + + (underlying() * riskFreeDiscount() * + (pow_s * n3 - dividendDiscount() * n4 / riskFreeDiscount()) / lambda)); } } } diff --git a/src/QLNet/Pricingengines/Lookback/AnalyticContinuousPartialFixedLookbackEngine.cs b/src/QLNet/Pricingengines/Lookback/AnalyticContinuousPartialFixedLookbackEngine.cs index 074f318f3..a7a342325 100644 --- a/src/QLNet/Pricingengines/Lookback/AnalyticContinuousPartialFixedLookbackEngine.cs +++ b/src/QLNet/Pricingengines/Lookback/AnalyticContinuousPartialFixedLookbackEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -31,18 +31,18 @@ public AnalyticContinuousPartialFixedLookbackEngine(GeneralizedBlackScholesProce public override void calculate() { PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; - Utils.QL_REQUIRE(payoff!=null,()=> "Non-plain payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "Non-plain payoff given"); - Utils.QL_REQUIRE(process_.x0() > 0.0,()=> "negative or null underlying"); + Utils.QL_REQUIRE(process_.x0() > 0.0, () => "negative or null underlying"); - switch (payoff.optionType()) + switch (payoff.optionType()) { case Option.Type.Call: - Utils.QL_REQUIRE(payoff.strike()>=0.0,()=>"Strike must be positive or null"); + Utils.QL_REQUIRE(payoff.strike() >= 0.0, () => "Strike must be positive or null"); results_.value = A(1); break; case Option.Type.Put: - Utils.QL_REQUIRE(payoff.strike()>0.0,()=>"Strike must be positive"); + Utils.QL_REQUIRE(payoff.strike() > 0.0, () => "Strike must be positive"); results_.value = A(-1); break; default: @@ -50,43 +50,43 @@ public override void calculate() break; } } - + private GeneralizedBlackScholesProcess process_; private CumulativeNormalDistribution f_ = new CumulativeNormalDistribution(); // helper methods private double underlying() {return process_.x0();} - private double strike() + private double strike() { PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; - Utils.QL_REQUIRE(payoff!=null,()=> "Non-plain payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "Non-plain payoff given"); return payoff.strike(); } - private double residualTime() { return process_.time( arguments_.exercise.lastDate() ); } - private double volatility() { return process_.blackVolatility().link.blackVol( residualTime(), strike() ); } - private double lookbackPeriodStartTime() { return process_.time( arguments_.lookbackPeriodStart ); } + private double residualTime() { return process_.time(arguments_.exercise.lastDate()); } + private double volatility() { return process_.blackVolatility().link.blackVol(residualTime(), strike()); } + private double lookbackPeriodStartTime() { return process_.time(arguments_.lookbackPeriodStart); } private double stdDeviation() {return volatility() * Math.Sqrt(residualTime());} private double riskFreeRate() { - return process_.riskFreeRate().link.zeroRate( residualTime(), - Compounding.Continuous,Frequency.NoFrequency ).value(); + return process_.riskFreeRate().link.zeroRate(residualTime(), + Compounding.Continuous, Frequency.NoFrequency).value(); } - private double riskFreeDiscount() { return process_.riskFreeRate().link.discount( residualTime() ); } + private double riskFreeDiscount() { return process_.riskFreeRate().link.discount(residualTime()); } private double dividendYield() { - return process_.dividendYield().link.zeroRate( residualTime(), - Compounding.Continuous, Frequency.NoFrequency ).value(); + return process_.dividendYield().link.zeroRate(residualTime(), + Compounding.Continuous, Frequency.NoFrequency).value(); } - private double dividendDiscount() { return process_.dividendYield().link.discount( residualTime() ); } + private double dividendDiscount() { return process_.dividendYield().link.discount(residualTime()); } private double A(double eta) { bool differentStartOfLookback = lookbackPeriodStartTime().IsNotEqual(residualTime()); double carry = riskFreeRate() - dividendYield(); double vol = volatility(); - double x = 2.0*carry/(vol*vol); - double s = underlying()/strike(); + double x = 2.0 * carry / (vol * vol); + double s = underlying() / strike(); double ls = Math.Log(s); - double d1 = ls/stdDeviation() + 0.5*(x+1.0)*stdDeviation(); + double d1 = ls / stdDeviation() + 0.5 * (x + 1.0) * stdDeviation(); double d2 = d1 - stdDeviation(); double e1 = 0, e2 = 0; @@ -94,41 +94,42 @@ private double A(double eta) { e1 = (carry + vol * vol / 2) * (residualTime() - lookbackPeriodStartTime()) / (vol * Math.Sqrt(residualTime() - lookbackPeriodStartTime())); e2 = e1 - vol * Math.Sqrt(residualTime() - lookbackPeriodStartTime()); - } + } double f1 = (ls + (carry + vol * vol / 2) * lookbackPeriodStartTime()) / (vol * Math.Sqrt(lookbackPeriodStartTime())); double f2 = f1 - vol * Math.Sqrt(lookbackPeriodStartTime()); - double n1 = f_.value(eta*d1); - double n2 = f_.value(eta*d2); + double n1 = f_.value(eta * d1); + double n2 = f_.value(eta * d2); - BivariateCumulativeNormalDistributionWe04DP cnbn1 = new BivariateCumulativeNormalDistributionWe04DP(-1), - cnbn2= new BivariateCumulativeNormalDistributionWe04DP(0), - cnbn3= new BivariateCumulativeNormalDistributionWe04DP(0); - if (differentStartOfLookback) { - cnbn1 = new BivariateCumulativeNormalDistributionWe04DP (-Math.Sqrt(lookbackPeriodStartTime() / residualTime())); - cnbn2 = new BivariateCumulativeNormalDistributionWe04DP (Math.Sqrt(1 - lookbackPeriodStartTime() / residualTime())); - cnbn3 = new BivariateCumulativeNormalDistributionWe04DP (-Math.Sqrt(1 - lookbackPeriodStartTime() / residualTime())); + BivariateCumulativeNormalDistributionWe04DP cnbn1 = new BivariateCumulativeNormalDistributionWe04DP(-1), + cnbn2 = new BivariateCumulativeNormalDistributionWe04DP(0), + cnbn3 = new BivariateCumulativeNormalDistributionWe04DP(0); + if (differentStartOfLookback) + { + cnbn1 = new BivariateCumulativeNormalDistributionWe04DP(-Math.Sqrt(lookbackPeriodStartTime() / residualTime())); + cnbn2 = new BivariateCumulativeNormalDistributionWe04DP(Math.Sqrt(1 - lookbackPeriodStartTime() / residualTime())); + cnbn3 = new BivariateCumulativeNormalDistributionWe04DP(-Math.Sqrt(1 - lookbackPeriodStartTime() / residualTime())); } - double n3 = cnbn1.value(eta*(d1-x*stdDeviation()), eta*(-f1+2.0* carry * Math.Sqrt(lookbackPeriodStartTime()) / vol)); - double n4 = cnbn2.value(eta*e1, eta*d1); - double n5 = cnbn3.value(-eta*e1, eta*d1); - double n6 = cnbn1.value(eta*f2, -eta*d2); - double n7 = f_.value(eta*f1); - double n8 = f_.value(-eta*e2); + double n3 = cnbn1.value(eta * (d1 - x * stdDeviation()), eta * (-f1 + 2.0 * carry * Math.Sqrt(lookbackPeriodStartTime()) / vol)); + double n4 = cnbn2.value(eta * e1, eta * d1); + double n5 = cnbn3.value(-eta * e1, eta * d1); + double n6 = cnbn1.value(eta * f2, -eta * d2); + double n7 = f_.value(eta * f1); + double n8 = f_.value(-eta * e2); double pow_s = Math.Pow(s, -x); double carryDiscount = Math.Exp(-carry * (residualTime() - lookbackPeriodStartTime())); - return eta*(underlying() * dividendDiscount() * n1 - - strike() * riskFreeDiscount() * n2 - + underlying() * riskFreeDiscount() / x - * (-pow_s * n3 + dividendDiscount() / riskFreeDiscount() * n4) - - underlying() * dividendDiscount() * n5 - - strike() * riskFreeDiscount() * n6 - + carryDiscount * dividendDiscount() - * (1 - 0.5 * vol * vol / carry) * - underlying() * n7 * n8); + return eta * (underlying() * dividendDiscount() * n1 + - strike() * riskFreeDiscount() * n2 + + underlying() * riskFreeDiscount() / x + * (-pow_s * n3 + dividendDiscount() / riskFreeDiscount() * n4) + - underlying() * dividendDiscount() * n5 + - strike() * riskFreeDiscount() * n6 + + carryDiscount * dividendDiscount() + * (1 - 0.5 * vol * vol / carry) * + underlying() * n7 * n8); } } } diff --git a/src/QLNet/Pricingengines/Lookback/AnalyticContinuousPartialFloatingLookbackEngine.cs b/src/QLNet/Pricingengines/Lookback/AnalyticContinuousPartialFloatingLookbackEngine.cs index e617a8f78..1acd33ed3 100644 --- a/src/QLNet/Pricingengines/Lookback/AnalyticContinuousPartialFloatingLookbackEngine.cs +++ b/src/QLNet/Pricingengines/Lookback/AnalyticContinuousPartialFloatingLookbackEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -27,16 +27,16 @@ public class AnalyticContinuousPartialFloatingLookbackEngine : ContinuousPartial public AnalyticContinuousPartialFloatingLookbackEngine(GeneralizedBlackScholesProcess process) { process_ = process; - process_.registerWith( update ); + process_.registerWith(update); } public override void calculate() { FloatingTypePayoff payoff = arguments_.payoff as FloatingTypePayoff; - Utils.QL_REQUIRE(payoff!=null,()=> "Non-floating payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "Non-floating payoff given"); - Utils.QL_REQUIRE(process_.x0() > 0.0,()=> "negative or null underlying"); + Utils.QL_REQUIRE(process_.x0() > 0.0, () => "negative or null underlying"); - switch (payoff.optionType()) + switch (payoff.optionType()) { case Option.Type.Call: results_.value = A(1); @@ -49,39 +49,39 @@ public override void calculate() break; } } - + private GeneralizedBlackScholesProcess process_; private CumulativeNormalDistribution f_ = new CumulativeNormalDistribution(); // helper methods private double underlying() { return process_.x0(); } - private double residualTime() { return process_.time( arguments_.exercise.lastDate() ); } - private double volatility() { return process_.blackVolatility().link.blackVol( residualTime(), minmax() ); } + private double residualTime() { return process_.time(arguments_.exercise.lastDate()); } + private double volatility() { return process_.blackVolatility().link.blackVol(residualTime(), minmax()); } private double minmax() { return arguments_.minmax.GetValueOrDefault(); } private double lambda() { return arguments_.lambda; } - private double lookbackPeriodEndTime() { return process_.time( arguments_.lookbackPeriodEnd ); } + private double lookbackPeriodEndTime() { return process_.time(arguments_.lookbackPeriodEnd); } private double stdDeviation() {return volatility() * Math.Sqrt(residualTime());} private double riskFreeRate() { - return process_.riskFreeRate().link.zeroRate( residualTime(), Compounding.Continuous, - Frequency.NoFrequency ).value(); + return process_.riskFreeRate().link.zeroRate(residualTime(), Compounding.Continuous, + Frequency.NoFrequency).value(); } - private double riskFreeDiscount() { return process_.riskFreeRate().link.discount( residualTime() ); } + private double riskFreeDiscount() { return process_.riskFreeRate().link.discount(residualTime()); } private double dividendYield() { - return process_.dividendYield().link.zeroRate( residualTime(), - Compounding.Continuous, Frequency.NoFrequency ).value(); + return process_.dividendYield().link.zeroRate(residualTime(), + Compounding.Continuous, Frequency.NoFrequency).value(); } - private double dividendDiscount() { return process_.dividendYield().link.discount( residualTime() ); } + private double dividendDiscount() { return process_.dividendYield().link.discount(residualTime()); } private double A(double eta) { bool fullLookbackPeriod = lookbackPeriodEndTime().IsEqual(residualTime()); double carry = riskFreeRate() - dividendYield(); double vol = volatility(); - double x = 2.0*carry/(vol*vol); - double s = underlying()/minmax(); + double x = 2.0 * carry / (vol * vol); + double s = underlying() / minmax(); double ls = Math.Log(s); - double d1 = ls/stdDeviation() + 0.5*(x+1.0)*stdDeviation(); + double d1 = ls / stdDeviation() + 0.5 * (x + 1.0) * stdDeviation(); double d2 = d1 - stdDeviation(); double e1 = 0, e2 = 0; @@ -89,7 +89,7 @@ private double A(double eta) { e1 = (carry + vol * vol / 2) * (residualTime() - lookbackPeriodEndTime()) / (vol * Math.Sqrt(residualTime() - lookbackPeriodEndTime())); e2 = e1 - vol * Math.Sqrt(residualTime() - lookbackPeriodEndTime()); - } + } double f1 = (ls + (carry + vol * vol / 2) * lookbackPeriodEndTime()) / (vol * Math.Sqrt(lookbackPeriodEndTime())); double f2 = f1 - vol * Math.Sqrt(lookbackPeriodEndTime()); @@ -97,59 +97,60 @@ private double A(double eta) double l1 = Math.Log(lambda()) / vol; double g1 = l1 / Math.Sqrt(residualTime()); double g2 = 0; - if (!fullLookbackPeriod) g2 = l1 / Math.Sqrt(residualTime() - lookbackPeriodEndTime()); - - double n1 = f_.value(eta*(d1 - g1)); - double n2 = f_.value(eta*(d2 - g1)); + if (!fullLookbackPeriod) + g2 = l1 / Math.Sqrt(residualTime() - lookbackPeriodEndTime()); - BivariateCumulativeNormalDistributionWe04DP cnbn1 = new BivariateCumulativeNormalDistributionWe04DP(1), - cnbn2 = new BivariateCumulativeNormalDistributionWe04DP(0), - cnbn3 = new BivariateCumulativeNormalDistributionWe04DP(-1); - if (!fullLookbackPeriod) + double n1 = f_.value(eta * (d1 - g1)); + double n2 = f_.value(eta * (d2 - g1)); + + BivariateCumulativeNormalDistributionWe04DP cnbn1 = new BivariateCumulativeNormalDistributionWe04DP(1), + cnbn2 = new BivariateCumulativeNormalDistributionWe04DP(0), + cnbn3 = new BivariateCumulativeNormalDistributionWe04DP(-1); + if (!fullLookbackPeriod) { - cnbn1 = new BivariateCumulativeNormalDistributionWe04DP (Math.Sqrt(lookbackPeriodEndTime() / residualTime())); - cnbn2 = new BivariateCumulativeNormalDistributionWe04DP (-Math.Sqrt(1 - lookbackPeriodEndTime() / residualTime())); - cnbn3 = new BivariateCumulativeNormalDistributionWe04DP (-Math.Sqrt(lookbackPeriodEndTime() / residualTime())); + cnbn1 = new BivariateCumulativeNormalDistributionWe04DP(Math.Sqrt(lookbackPeriodEndTime() / residualTime())); + cnbn2 = new BivariateCumulativeNormalDistributionWe04DP(-Math.Sqrt(1 - lookbackPeriodEndTime() / residualTime())); + cnbn3 = new BivariateCumulativeNormalDistributionWe04DP(-Math.Sqrt(lookbackPeriodEndTime() / residualTime())); } - double n3 = cnbn1.value(eta*(-f1+2.0* carry * Math.Sqrt(lookbackPeriodEndTime()) / vol), eta*(-d1+x*stdDeviation()-g1)); + double n3 = cnbn1.value(eta * (-f1 + 2.0 * carry * Math.Sqrt(lookbackPeriodEndTime()) / vol), eta * (-d1 + x * stdDeviation() - g1)); double n4 = 0, n5 = 0, n6 = 0, n7 = 0; if (!fullLookbackPeriod) { - n4 = cnbn2.value(-eta*(d1+g1), eta*(e1 + g2)); - n5 = cnbn2.value(-eta*(d1-g1), eta*(e1 - g2)); - n6 = cnbn3.value(eta*-f2, eta*(d2 - g1)); - n7 = f_.value(eta*(e2 - g2)); + n4 = cnbn2.value(-eta * (d1 + g1), eta * (e1 + g2)); + n5 = cnbn2.value(-eta * (d1 - g1), eta * (e1 - g2)); + n6 = cnbn3.value(eta * -f2, eta * (d2 - g1)); + n7 = f_.value(eta * (e2 - g2)); } else { - n4 = f_.value(-eta*(d1+g1)); + n4 = f_.value(-eta * (d1 + g1)); } - double n8 = f_.value(-eta*f1); + double n8 = f_.value(-eta * f1); double pow_s = Math.Pow(s, -x); double pow_l = Math.Pow(lambda(), x); if (!fullLookbackPeriod) { - return eta*(underlying() * dividendDiscount() * n1 - - lambda() * minmax() * riskFreeDiscount() * n2 + - underlying() * riskFreeDiscount() * lambda() / x * - (pow_s * n3 - dividendDiscount() / riskFreeDiscount() * pow_l * n4) - + underlying() * dividendDiscount() * n5 + - riskFreeDiscount() * lambda() * minmax() * n6 - - Math.Exp(-carry * (residualTime() - lookbackPeriodEndTime())) * - dividendDiscount() * (1 + 0.5 * vol * vol / carry) * lambda() * - underlying() * n7 * n8); + return eta * (underlying() * dividendDiscount() * n1 - + lambda() * minmax() * riskFreeDiscount() * n2 + + underlying() * riskFreeDiscount() * lambda() / x * + (pow_s * n3 - dividendDiscount() / riskFreeDiscount() * pow_l * n4) + + underlying() * dividendDiscount() * n5 + + riskFreeDiscount() * lambda() * minmax() * n6 - + Math.Exp(-carry * (residualTime() - lookbackPeriodEndTime())) * + dividendDiscount() * (1 + 0.5 * vol * vol / carry) * lambda() * + underlying() * n7 * n8); } else { //Simpler calculation - return eta*(underlying() * dividendDiscount() * n1 - - lambda() * minmax() * riskFreeDiscount() * n2 + - underlying() * riskFreeDiscount() * lambda() / x * - (pow_s * n3 - dividendDiscount() / riskFreeDiscount() * pow_l * n4)); - } + return eta * (underlying() * dividendDiscount() * n1 - + lambda() * minmax() * riskFreeDiscount() * n2 + + underlying() * riskFreeDiscount() * lambda() / x * + (pow_s * n3 - dividendDiscount() / riskFreeDiscount() * pow_l * n4)); + } } } } diff --git a/src/QLNet/Pricingengines/mclongstaffschwartzengine.cs b/src/QLNet/Pricingengines/MCLongstaffSchwartzEngine.cs similarity index 51% rename from src/QLNet/Pricingengines/mclongstaffschwartzengine.cs rename to src/QLNet/Pricingengines/MCLongstaffSchwartzEngine.cs index cfd254b53..da25d1c3b 100644 --- a/src/QLNet/Pricingengines/mclongstaffschwartzengine.cs +++ b/src/QLNet/Pricingengines/MCLongstaffSchwartzEngine.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -32,30 +32,30 @@ namespace QLNet reproducing results available in web/literature */ public abstract class MCLongstaffSchwartzEngine - : MCLongstaffSchwartzEngine - where GenericEngine : IPricingEngine, new() - where RNG : IRSG, new() + : MCLongstaffSchwartzEngine + where GenericEngine : IPricingEngine, new () + where RNG : IRSG, new () { - protected MCLongstaffSchwartzEngine( StochasticProcess process, - int? timeSteps, - int? timeStepsPerYear, - bool brownianBridge, - bool antitheticVariate, - bool controlVariate, - int? requiredSamples, - double? requiredTolerance, - int? maxSamples, - ulong seed, - int nCalibrationSamples ) : - base( process, timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, controlVariate, - requiredSamples, requiredTolerance, maxSamples, seed, nCalibrationSamples ) + protected MCLongstaffSchwartzEngine(StochasticProcess process, + int? timeSteps, + int? timeStepsPerYear, + bool brownianBridge, + bool antitheticVariate, + bool controlVariate, + int? requiredSamples, + double? requiredTolerance, + int? maxSamples, + ulong seed, + int nCalibrationSamples) : + base(process, timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, controlVariate, + requiredSamples, requiredTolerance, maxSamples, seed, nCalibrationSamples) {} } public abstract class MCLongstaffSchwartzEngine : McSimulation, IPricingEngine - where GenericEngine : IPricingEngine, new() - where RNG : IRSG, new() - where S : IGeneralStatistics, new() + where GenericEngine : IPricingEngine, new () + where RNG : IRSG, new () + where S : IGeneralStatistics, new () { protected StochasticProcess process_; protected int? timeSteps_; @@ -73,18 +73,18 @@ public abstract class MCLongstaffSchwartzEngine : McS protected LongstaffSchwartzPathPricer pathPricer_; - protected MCLongstaffSchwartzEngine( StochasticProcess process, - int? timeSteps, - int? timeStepsPerYear, - bool brownianBridge, - bool antitheticVariate, - bool controlVariate, - int? requiredSamples, - double? requiredTolerance, - int? maxSamples, - ulong seed, - int? nCalibrationSamples ) - : base( antitheticVariate, controlVariate ) + protected MCLongstaffSchwartzEngine(StochasticProcess process, + int? timeSteps, + int? timeStepsPerYear, + bool brownianBridge, + bool antitheticVariate, + bool controlVariate, + int? requiredSamples, + double? requiredTolerance, + int? maxSamples, + ulong seed, + int? nCalibrationSamples) + : base(antitheticVariate, controlVariate) { process_ = process; timeSteps_ = timeSteps; @@ -97,29 +97,29 @@ protected MCLongstaffSchwartzEngine( StochasticProcess process, nCalibrationSamples_ = nCalibrationSamples ?? 2048; - Utils.QL_REQUIRE( timeSteps != null || - timeStepsPerYear != null,()=> "no time steps provided" ); - Utils.QL_REQUIRE( timeSteps == null || - timeStepsPerYear == null,()=> "both time steps and time steps per year were provided" ); - Utils.QL_REQUIRE( timeSteps != 0,()=> - "timeSteps must be positive, " + timeSteps + " not allowed" ); - Utils.QL_REQUIRE( timeStepsPerYear != 0,()=> - "timeStepsPerYear must be positive, " + timeStepsPerYear + " not allowed" ); + Utils.QL_REQUIRE(timeSteps != null || + timeStepsPerYear != null, () => "no time steps provided"); + Utils.QL_REQUIRE(timeSteps == null || + timeStepsPerYear == null, () => "both time steps and time steps per year were provided"); + Utils.QL_REQUIRE(timeSteps != 0, () => + "timeSteps must be positive, " + timeSteps + " not allowed"); + Utils.QL_REQUIRE(timeStepsPerYear != 0, () => + "timeStepsPerYear must be positive, " + timeStepsPerYear + " not allowed"); - process_.registerWith( update ); + process_.registerWith(update); } public virtual void calculate() { pathPricer_ = lsmPathPricer(); - mcModel_ = new MonteCarloModel( pathGenerator(), pathPricer_, FastActivator.Create(), antitheticVariate_ ); + mcModel_ = new MonteCarloModel(pathGenerator(), pathPricer_, FastActivator.Create(), antitheticVariate_); - mcModel_.addSamples( nCalibrationSamples_ ); + mcModel_.addSamples(nCalibrationSamples_); pathPricer_.calibrate(); - base.calculate( requiredTolerance_, requiredSamples_, maxSamples_ ); + base.calculate(requiredTolerance_, requiredSamples_, maxSamples_); results_.value = mcModel_.sampleAccumulator().mean(); - if ( FastActivator.Create().allowsErrorEstimate != 0 ) + if (FastActivator.Create().allowsErrorEstimate != 0) { results_.errorEstimate = mcModel_.sampleAccumulator().errorEstimate(); } @@ -128,26 +128,26 @@ public virtual void calculate() protected override TimeGrid timeGrid() { Date lastExerciseDate = arguments_.exercise.lastDate(); - double t = process_.time( lastExerciseDate ); - if ( timeSteps_ != null ) + double t = process_.time(lastExerciseDate); + if (timeSteps_ != null) { - return new TimeGrid( t, timeSteps_.Value ); + return new TimeGrid(t, timeSteps_.Value); } - else if ( timeStepsPerYear_ != null ) + else if (timeStepsPerYear_ != null) { - int steps = (int)( timeStepsPerYear_.Value * t ); - return new TimeGrid( t, Math.Max( steps, 1 ) ); + int steps = (int)(timeStepsPerYear_.Value * t); + return new TimeGrid(t, Math.Max(steps, 1)); } else { - Utils.QL_FAIL( "time steps not specified" ); + Utils.QL_FAIL("time steps not specified"); return null; } } protected override PathPricer pathPricer() { - Utils.QL_REQUIRE( pathPricer_!=null,()=> "path pricer unknown" ); + Utils.QL_REQUIRE(pathPricer_ != null, () => "path pricer unknown"); return pathPricer_; } @@ -155,11 +155,11 @@ protected override IPathGenerator pathGenerator() { int dimensions = process_.factors(); TimeGrid grid = timeGrid(); - IRNG generator = (IRNG) FastActivator.Create().make_sequence_generator( dimensions * ( grid.size() - 1 ), seed_ ); - if ( typeof( MC ) == typeof( SingleVariate ) ) - return new PathGenerator( process_, grid, generator, brownianBridge_ ); + IRNG generator = (IRNG) FastActivator.Create().make_sequence_generator(dimensions * (grid.size() - 1), seed_); + if (typeof(MC) == typeof(SingleVariate)) + return new PathGenerator(process_, grid, generator, brownianBridge_); else - return new MultiPathGenerator( process_, grid, generator, brownianBridge_ ); + return new MultiPathGenerator(process_, grid, generator, brownianBridge_); } @@ -178,12 +178,18 @@ protected override IPathGenerator pathGenerator() private readonly WeakEventSource eventSource = new WeakEventSource(); public event Callback notifyObserversEvent { - add { eventSource.Subscribe( value ); } - remove { eventSource.Unsubscribe( value ); } + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } } - public void registerWith( Callback handler ) { notifyObserversEvent += handler; } - public void unregisterWith( Callback handler ) { notifyObserversEvent -= handler; } + public void registerWith(Callback handler) { notifyObserversEvent += handler; } + public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } protected void notifyObservers() { eventSource.Raise(); diff --git a/src/QLNet/Pricingengines/mcsimulation.cs b/src/QLNet/Pricingengines/McSimulation.cs similarity index 57% rename from src/QLNet/Pricingengines/mcsimulation.cs rename to src/QLNet/Pricingengines/McSimulation.cs index c94855003..08fe687be 100644 --- a/src/QLNet/Pricingengines/mcsimulation.cs +++ b/src/QLNet/Pricingengines/McSimulation.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -30,42 +30,42 @@ Carlo engine. See McVanillaEngine as an example. */ - public abstract class McSimulation where S : IGeneralStatistics, new() + public abstract class McSimulation where S : IGeneralStatistics, new () { - protected McSimulation( bool antitheticVariate, bool controlVariate ) + protected McSimulation(bool antitheticVariate, bool controlVariate) { antitheticVariate_ = antitheticVariate; controlVariate_ = controlVariate; } //! add samples until the required absolute tolerance is reached - public double value( double tolerance, int maxSamples = int.MaxValue, int minSamples = 1023) + public double value(double tolerance, int maxSamples = int.MaxValue, int minSamples = 1023) { int sampleNumber = mcModel_.sampleAccumulator().samples(); - if ( sampleNumber < minSamples ) + if (sampleNumber < minSamples) { - mcModel_.addSamples( minSamples - sampleNumber ); + mcModel_.addSamples(minSamples - sampleNumber); sampleNumber = mcModel_.sampleAccumulator().samples(); } int nextBatch; double order; double error = mcModel_.sampleAccumulator().errorEstimate(); - while ( maxError( error ) > tolerance ) + while (maxError(error) > tolerance) { - Utils.QL_REQUIRE( sampleNumber < maxSamples,()=> - "max number of samples (" + maxSamples - + ") reached, while error (" + error - + ") is still above tolerance (" + tolerance + ")" ); + Utils.QL_REQUIRE(sampleNumber < maxSamples, () => + "max number of samples (" + maxSamples + + ") reached, while error (" + error + + ") is still above tolerance (" + tolerance + ")"); // conservative estimate of how many samples are needed - order = maxError( error * error ) / tolerance / tolerance; - nextBatch = (int)Math.Max( sampleNumber * order * 0.8 - sampleNumber, minSamples ); + order = maxError(error* error) / tolerance / tolerance; + nextBatch = (int)Math.Max(sampleNumber* order * 0.8 - sampleNumber, minSamples); // do not exceed maxSamples - nextBatch = Math.Min( nextBatch, maxSamples - sampleNumber ); + nextBatch = Math.Min(nextBatch, maxSamples - sampleNumber); sampleNumber += nextBatch; - mcModel_.addSamples( nextBatch ); + mcModel_.addSamples(nextBatch); error = mcModel_.sampleAccumulator().errorEstimate(); } @@ -73,16 +73,16 @@ public double value( double tolerance, int maxSamples = int.MaxValue, int minSam } //! simulate a fixed number of samples - public double valueWithSamples( int samples ) + public double valueWithSamples(int samples) { int sampleNumber = mcModel_.sampleAccumulator().samples(); - Utils.QL_REQUIRE( samples >= sampleNumber,()=> - "number of already simulated samples (" + sampleNumber - + ") greater than requested samples (" + samples + ")" ); + Utils.QL_REQUIRE(samples >= sampleNumber, () => + "number of already simulated samples (" + sampleNumber + + ") greater than requested samples (" + samples + ")"); - mcModel_.addSamples( samples - sampleNumber ); + mcModel_.addSamples(samples - sampleNumber); return mcModel_.sampleAccumulator().mean(); } @@ -94,41 +94,41 @@ public double valueWithSamples( int samples ) public S sampleAccumulator() { return mcModel_.sampleAccumulator(); } //! basic calculate method provided to inherited pricing engines - public void calculate( double? requiredTolerance, int? requiredSamples, int? maxSamples ) + public void calculate(double? requiredTolerance, int? requiredSamples, int? maxSamples) { - Utils.QL_REQUIRE( requiredTolerance != null || - requiredSamples != null,()=> "neither tolerance nor number of samples set" ); + Utils.QL_REQUIRE(requiredTolerance != null || + requiredSamples != null, () => "neither tolerance nor number of samples set"); //! Initialize the one-factor Monte Carlo - if ( this.controlVariate_ ) + if (this.controlVariate_) { double? controlVariateValue = this.controlVariateValue(); - Utils.QL_REQUIRE(controlVariateValue != null,()=> "engine does not provide control-variation price"); + Utils.QL_REQUIRE(controlVariateValue != null, () => "engine does not provide control-variation price"); PathPricer controlPP = this.controlPathPricer(); - Utils.QL_REQUIRE(controlPP != null ,()=> "engine does not provide control-variation path pricer"); + Utils.QL_REQUIRE(controlPP != null, () => "engine does not provide control-variation path pricer"); IPathGenerator controlPG = this.controlPathGenerator(); - this.mcModel_ = new MonteCarloModel( pathGenerator(), pathPricer(), FastActivator.Create(), antitheticVariate_, - controlPP, controlVariateValue.GetValueOrDefault(), controlPG ); + this.mcModel_ = new MonteCarloModel(pathGenerator(), pathPricer(), FastActivator.Create(), antitheticVariate_, + controlPP, controlVariateValue.GetValueOrDefault(), controlPG); } else { - this.mcModel_ = new MonteCarloModel( pathGenerator(), pathPricer(), FastActivator.Create(), antitheticVariate_ ); + this.mcModel_ = new MonteCarloModel(pathGenerator(), pathPricer(), FastActivator.Create(), antitheticVariate_); } - if ( requiredTolerance != null ) + if (requiredTolerance != null) { - if ( maxSamples != null ) - value( requiredTolerance.Value, maxSamples.Value ); + if (maxSamples != null) + value(requiredTolerance.Value, maxSamples.Value); else - value( requiredTolerance.Value ); + value(requiredTolerance.Value); } else { - valueWithSamples( requiredSamples.GetValueOrDefault() ); + valueWithSamples(requiredSamples.GetValueOrDefault()); } } @@ -141,8 +141,8 @@ public void calculate( double? requiredTolerance, int? requiredSamples, int? max protected virtual IPricingEngine controlPricingEngine() { return null; } protected virtual double? controlVariateValue() { return null; } - protected static double maxError( List sequence ) { return sequence.Max(); } - protected static double maxError( double error ) { return error; } + protected static double maxError(List sequence) { return sequence.Max(); } + protected static double maxError(double error) { return error; } protected MonteCarloModel mcModel_; protected bool antitheticVariate_, controlVariate_; diff --git a/src/QLNet/Pricingengines/Option/KirkSpreadOptionEngine.cs b/src/QLNet/Pricingengines/Option/KirkSpreadOptionEngine.cs new file mode 100644 index 000000000..9aa5d73ca --- /dev/null +++ b/src/QLNet/Pricingengines/Option/KirkSpreadOptionEngine.cs @@ -0,0 +1,106 @@ +// Copyright (C) 2008-2018 Andrea Maggiulli (a.maggiulli@gmail.com) +// +// This file is part of QLNet Project https://github.com/amaggiulli/qlnet +// QLNet is free software: you can redistribute it and/or modify it +// under the terms of the QLNet license. You should have received a +// copy of the license along with this program; if not, license is +// available at . +// +// QLNet is a based on QuantLib, a free-software/open-source library +// for financial quantitative analysts and developers - http://quantlib.org/ +// The QuantLib license is available online at http://quantlib.org/license.shtml. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the license for more details. +using System; + +namespace QLNet +{ + /// + /// Kirk approximation for European spread option on futures + /// + public class KirkSpreadOptionEngine : SpreadOption.Engine + { + public KirkSpreadOptionEngine(BlackProcess process1, + BlackProcess process2, + Handle correlation) + { + process1_ = process1; + process2_ = process2; + rho_ = correlation; + } + + public override void calculate() + { + // First: tests on types + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => + "not an European Option"); + + PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; + Utils.QL_REQUIRE(payoff != null, () => "not a plain-vanilla payoff"); + + // forward values - futures, so b=0 + double forward1 = process1_.stateVariable().link.value(); + double forward2 = process2_.stateVariable().link.value(); + + Date exerciseDate = arguments_.exercise.lastDate(); + + // Volatilities + double sigma1 = process1_.blackVolatility().link.blackVol(exerciseDate, + forward1); + double sigma2 = process2_.blackVolatility().link.blackVol(exerciseDate, + forward2); + + double riskFreeDiscount = process1_.riskFreeRate().link.discount(exerciseDate); + + double strike = payoff.strike(); + + // Unique F (forward) value for pricing + double F = forward1 / (forward2 + strike); + + // Its volatility + double sigma = + Math.Sqrt(Math.Pow(sigma1, 2) + + Math.Pow((sigma2 * (forward2 / (forward2 + strike))), 2) + - 2 * rho_.link.value() * sigma1 * sigma2 * (forward2 / (forward2 + strike))); + + // Day counter and Dates handling variables + DayCounter rfdc = process1_.riskFreeRate().link.dayCounter(); + double t = rfdc.yearFraction(process1_.riskFreeRate().link.referenceDate(), + arguments_.exercise.lastDate()); + + // Black-Scholes solution values + double d1 = (Math.Log(F) + 0.5 * Math.Pow(sigma, + 2) * t) / (sigma * Math.Sqrt(t)); + double d2 = d1 - sigma * Math.Sqrt(t); + + NormalDistribution pdf = new NormalDistribution(); + CumulativeNormalDistribution cum = new CumulativeNormalDistribution(); + double Nd1 = cum.value(d1); + double Nd2 = cum.value(d2); + double NMd1 = cum.value(-d1); + double NMd2 = cum.value(-d2); + + Option.Type optionType = payoff.optionType(); + + if (optionType == Option.Type.Call) + { + results_.value = riskFreeDiscount * (F * Nd1 - Nd2) * (forward2 + strike); + } + else + { + results_.value = riskFreeDiscount * (NMd2 - F * NMd1) * (forward2 + strike); + } + + double ? callValue = optionType == Option.Type.Call ? results_.value : + riskFreeDiscount * (F * Nd1 - Nd2) * (forward2 + strike); + results_.theta = (Math.Log(riskFreeDiscount) / t) * callValue + + riskFreeDiscount * (forward1 * sigma) / (2 * Math.Sqrt(t)) * pdf.value(d1); + } + + private BlackProcess process1_; + private BlackProcess process2_; + private Handle rho_; + } +} diff --git a/src/QLNet/Pricingengines/Swap/CounterpartyAdjSwapEngine.cs b/src/QLNet/Pricingengines/Swap/CounterpartyAdjSwapEngine.cs index 91c94e4b6..a9491a687 100644 --- a/src/QLNet/Pricingengines/Swap/CounterpartyAdjSwapEngine.cs +++ b/src/QLNet/Pricingengines/Swap/CounterpartyAdjSwapEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,18 +19,18 @@ namespace QLNet { /*! Bilateral (CVA and DVA) default adjusted vanilla swap pricing - engine. Collateral is not considered. No wrong way risk is + engine. Collateral is not considered. No wrong way risk is considered (rates and counterparty default are uncorrelated). Based on: - Sorensen, E.H. and Bollier, T.F., Pricing swap default + Sorensen, E.H. and Bollier, T.F., Pricing swap default risk. Financial Analysts Journal, 1994, 50, 23–33 Also see sect. II-5 in: Risk Neutral Pricing of Counterparty Risk D. Brigo, M. Masetti, 2004 - or in sections 3 and 4 of "A Formula for Interest Rate Swaps + or in sections 3 and 4 of "A Formula for Interest Rate Swaps Valuation under Counterparty Risk in presence of Netting Agreements" D. Brigo and M. Masetti; May 4, 2005 - to do: Compute fair rate through iteration instead of the + to do: Compute fair rate through iteration instead of the current approximation . to do: write Issuer based constructors (event type) to do: Check consistency between option engine discount and the one given @@ -38,12 +38,12 @@ current approximation . public class CounterpartyAdjSwapEngine : VanillaSwap.Engine { // Constructors - //! + //! /*! Creates the engine from an arbitrary swaption engine. - If the investor default model is not given a default + If the investor default model is not given a default free one is assumed. @param discountCurve Used in pricing. - @param swaptionEngine Determines the volatility and thus the + @param swaptionEngine Determines the volatility and thus the exposure model. @param ctptyDTS Counterparty default curve. @param ctptyRecoveryRate Counterparty recovey rate. @@ -51,8 +51,8 @@ @param ctptyRecoveryRate Counterparty recovey rate. @param invstRecoveryRate Investor recovery rate. */ public CounterpartyAdjSwapEngine(Handle discountCurve, - Handle swaptionEngine,Handle ctptyDTS,double ctptyRecoveryRate, - Handle invstDTS=null,double invstRecoveryRate = 0.999) + Handle swaptionEngine, Handle ctptyDTS, double ctptyRecoveryRate, + Handle invstDTS = null, double invstRecoveryRate = 0.999) { baseSwapEngine_ = new Handle(new DiscountingSwapEngine(discountCurve)); swaptionletEngine_ = swaptionEngine; @@ -60,18 +60,18 @@ public CounterpartyAdjSwapEngine(Handle discountCurve, defaultTS_ = ctptyDTS; ctptyRecoveryRate_ = ctptyRecoveryRate; invstDTS_ = invstDTS ?? new Handle( - new FlatHazardRate(0, ctptyDTS.link.calendar(), 1.0E-12, ctptyDTS.link.dayCounter())); + new FlatHazardRate(0, ctptyDTS.link.calendar(), 1.0E-12, ctptyDTS.link.dayCounter())); invstRecoveryRate_ = invstRecoveryRate; discountCurve.registerWith(update) ; - ctptyDTS.registerWith( update ) ; - invstDTS_.registerWith( update ) ; - swaptionEngine.registerWith( update ) ; + ctptyDTS.registerWith(update) ; + invstDTS_.registerWith(update) ; + swaptionEngine.registerWith(update) ; } - /*! Creates an engine with a black volatility model for the + /*! Creates an engine with a black volatility model for the exposure. - If the investor default model is not given a default + If the investor default model is not given a default free one is assumed. @param discountCurve Used in pricing. @param blackVol Black volatility used in the exposure model. @@ -80,9 +80,9 @@ @param ctptyRecoveryRate Counterparty recovey rate. @param invstDTS Investor (swap holder) default curve. @param invstRecoveryRate Investor recovery rate. */ - public CounterpartyAdjSwapEngine(Handle discountCurve,double blackVol, - Handle ctptyDTS,double ctptyRecoveryRate, - Handle invstDTS=null,double invstRecoveryRate = 0.999) + public CounterpartyAdjSwapEngine(Handle discountCurve, double blackVol, + Handle ctptyDTS, double ctptyRecoveryRate, + Handle invstDTS = null, double invstRecoveryRate = 0.999) { baseSwapEngine_ = new Handle(new DiscountingSwapEngine(discountCurve)); swaptionletEngine_ = new Handle(new BlackSwaptionEngine(discountCurve, blackVol)); @@ -90,7 +90,7 @@ public CounterpartyAdjSwapEngine(Handle discountCurve,double defaultTS_ = ctptyDTS; ctptyRecoveryRate_ = ctptyRecoveryRate; invstDTS_ = invstDTS ?? new Handle( - new FlatHazardRate(0, ctptyDTS.link.calendar(), 1.0e-12, ctptyDTS.link.dayCounter())); + new FlatHazardRate(0, ctptyDTS.link.calendar(), 1.0e-12, ctptyDTS.link.dayCounter())); invstRecoveryRate_ = invstRecoveryRate; discountCurve.registerWith(update) ; @@ -98,9 +98,9 @@ public CounterpartyAdjSwapEngine(Handle discountCurve,double invstDTS_.registerWith(update) ; } - /*! Creates an engine with a black volatility model for the + /*! Creates an engine with a black volatility model for the exposure. The volatility is given as a quote. - If the investor default model is not given a default + If the investor default model is not given a default free one is assumed. @param discountCurve Used in pricing. @param blackVol Black volatility used in the exposure model. @@ -109,9 +109,9 @@ @param ctptyRecoveryRate Counterparty recovey rate. @param invstDTS Investor (swap holder) default curve. @param invstRecoveryRate Investor recovery rate. */ - public CounterpartyAdjSwapEngine(Handle discountCurve,Handle blackVol, - Handle ctptyDTS,double ctptyRecoveryRate, - Handle invstDTS=null,double invstRecoveryRate = 0.999) + public CounterpartyAdjSwapEngine(Handle discountCurve, Handle blackVol, + Handle ctptyDTS, double ctptyRecoveryRate, + Handle invstDTS = null, double invstRecoveryRate = 0.999) { baseSwapEngine_ = new Handle(new DiscountingSwapEngine(discountCurve)); swaptionletEngine_ = new Handle(new BlackSwaptionEngine(discountCurve, blackVol)); @@ -119,7 +119,7 @@ public CounterpartyAdjSwapEngine(Handle discountCurve,Handle defaultTS_ = ctptyDTS; ctptyRecoveryRate_ = ctptyRecoveryRate; invstDTS_ = invstDTS ?? new Handle( - new FlatHazardRate(0, ctptyDTS.link.calendar(), 1.0e-12, ctptyDTS.link.dayCounter())); + new FlatHazardRate(0, ctptyDTS.link.calendar(), 1.0e-12, ctptyDTS.link.dayCounter())); invstRecoveryRate_ = invstRecoveryRate; discountCurve.registerWith(update) ; @@ -130,15 +130,15 @@ public CounterpartyAdjSwapEngine(Handle discountCurve,Handle public override void calculate() { - /* both DTS, YTS ref dates and pricing date consistency + /* both DTS, YTS ref dates and pricing date consistency checks? settlement... */ - Utils.QL_REQUIRE(!discountCurve_.empty(),()=> "no discount term structure set"); - Utils.QL_REQUIRE(!defaultTS_.empty(),()=> "no ctpty default term structure set"); - Utils.QL_REQUIRE(!swaptionletEngine_.empty(),()=> "no swap option engine set"); + Utils.QL_REQUIRE(!discountCurve_.empty(), () => "no discount term structure set"); + Utils.QL_REQUIRE(!defaultTS_.empty(), () => "no ctpty default term structure set"); + Utils.QL_REQUIRE(!swaptionletEngine_.empty(), () => "no swap option engine set"); Date priceDate = defaultTS_.link.referenceDate(); - double cumOptVal = 0.0,cumPutVal = 0.0; + double cumOptVal = 0.0, cumPutVal = 0.0; // Vanilla swap so 0 leg is floater int index = 0; @@ -164,12 +164,12 @@ public override void calculate() Swap.Results vSResults = baseSwapEngine_.link.getResults() as Swap.Results; - double? baseSwapFairRate = -baseSwapRate*vSResults.legNPV[1]/ vSResults.legNPV[0]; + double? baseSwapFairRate = -baseSwapRate * vSResults.legNPV[1] / vSResults.legNPV[0]; double? baseSwapNPV = vSResults.value; VanillaSwap.Type reversedType = arguments_.type == VanillaSwap.Type.Payer - ? VanillaSwap.Type.Receiver - : VanillaSwap.Type.Payer; + ? VanillaSwap.Type.Receiver + : VanillaSwap.Type.Payer; // Swaplet options summatory: while (nextFD != arguments_.fixedPayDates.Last()) @@ -177,40 +177,40 @@ public override void calculate() // iFD coupon not fixed, create swaptionlet: IborIndex swapIndex = ((FloatingRateCoupon)arguments_.legs[1][0]).index() as IborIndex; - // Alternatively one could cap this period to, say, 1M + // Alternatively one could cap this period to, say, 1M Period baseSwapsTenor = new Period(arguments_.fixedPayDates.Last().serialNumber() - - swapletStart.serialNumber(),TimeUnit.Days); + - swapletStart.serialNumber(), TimeUnit.Days); VanillaSwap swaplet = new MakeVanillaSwap(baseSwapsTenor, swapIndex, baseSwapFairRate) - .withType(arguments_.type) - .withNominal(arguments_.nominal) - .withEffectiveDate(swapletStart) - .withTerminationDate(arguments_.fixedPayDates.Last()).value(); - - VanillaSwap revSwaplet = new MakeVanillaSwap(baseSwapsTenor,swapIndex,baseSwapFairRate) - .withType(reversedType) - .withNominal(arguments_.nominal) - .withEffectiveDate(swapletStart) - .withTerminationDate(arguments_.fixedPayDates.Last()).value(); - - Swaption swaptionlet = new Swaption(swaplet,new EuropeanExercise(swapletStart)); - Swaption putSwaplet = new Swaption(revSwaplet,new EuropeanExercise (swapletStart)); + .withType(arguments_.type) + .withNominal(arguments_.nominal) + .withEffectiveDate(swapletStart) + .withTerminationDate(arguments_.fixedPayDates.Last()).value(); + + VanillaSwap revSwaplet = new MakeVanillaSwap(baseSwapsTenor, swapIndex, baseSwapFairRate) + .withType(reversedType) + .withNominal(arguments_.nominal) + .withEffectiveDate(swapletStart) + .withTerminationDate(arguments_.fixedPayDates.Last()).value(); + + Swaption swaptionlet = new Swaption(swaplet, new EuropeanExercise(swapletStart)); + Swaption putSwaplet = new Swaption(revSwaplet, new EuropeanExercise(swapletStart)); swaptionlet.setPricingEngine(swaptionletEngine_.currentLink()); putSwaplet.setPricingEngine(swaptionletEngine_.currentLink()); // atm underlying swap means that the value of put = value // call so this double pricing is not needed - cumOptVal += swaptionlet.NPV()*defaultTS_.link.defaultProbability( - swapletStart, nextFD); - cumPutVal += putSwaplet.NPV()*invstDTS_.link.defaultProbability(swapletStart, nextFD); + cumOptVal += swaptionlet.NPV() * defaultTS_.link.defaultProbability( + swapletStart, nextFD); + cumPutVal += putSwaplet.NPV() * invstDTS_.link.defaultProbability(swapletStart, nextFD); swapletStart = nextFD; index++; nextFD = arguments_.fixedPayDates[index]; } - results_.value = baseSwapNPV - (1.0-ctptyRecoveryRate_)*cumOptVal+ (1.0-invstRecoveryRate_)*cumPutVal; - results_.fairRate = -baseSwapRate*(vSResults.legNPV[1] - (1.0 - ctptyRecoveryRate_)*cumOptVal + - (1.0-invstRecoveryRate_)*cumPutVal )/vSResults.legNPV[0]; + results_.value = baseSwapNPV - (1.0 - ctptyRecoveryRate_) * cumOptVal + (1.0 - invstRecoveryRate_) * cumPutVal; + results_.fairRate = -baseSwapRate * (vSResults.legNPV[1] - (1.0 - ctptyRecoveryRate_) * cumOptVal + + (1.0 - invstRecoveryRate_) * cumPutVal) / vSResults.legNPV[0]; } diff --git a/src/QLNet/Pricingengines/Swap/DiscountingBasisSwapEngine.cs b/src/QLNet/Pricingengines/Swap/DiscountingBasisSwapEngine.cs index e9c61d300..0ca8dd019 100644 --- a/src/QLNet/Pricingengines/Swap/DiscountingBasisSwapEngine.cs +++ b/src/QLNet/Pricingengines/Swap/DiscountingBasisSwapEngine.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,39 +19,48 @@ under the terms of the QLNet license. You should have received a using System; using System.Collections.Generic; -namespace QLNet { - public class DiscountingBasisSwapEngine : Swap.SwapEngine { - private List> discountCurve_; - - public DiscountingBasisSwapEngine(Handle discountCurve1 , - Handle discountCurve2) - { - discountCurve_ = new List>(); - discountCurve_.Add(discountCurve1); - discountCurve_.Add(discountCurve2); - } - - // Instrument interface - public override void calculate() { - if (discountCurve_.empty()) throw new ArgumentException("no discounting term structure set"); - if (discountCurve_.Count != arguments_.legs.Count) throw new ArgumentException("no discounting term structure set for all legs"); - - results_.value = results_.cash = 0; - results_.errorEstimate = null; - results_.legNPV = new InitializedList(arguments_.legs.Count); - results_.legBPS = new InitializedList(arguments_.legs.Count); - List startDiscounts = new InitializedList(arguments_.legs.Count); - for (int i=0; i> discountCurve_; + + public DiscountingBasisSwapEngine(Handle discountCurve1, + Handle discountCurve2) + { + discountCurve_ = new List>(); + discountCurve_.Add(discountCurve1); + discountCurve_.Add(discountCurve2); + } + + // Instrument interface + public override void calculate() + { + if (discountCurve_.empty()) + throw new ArgumentException("no discounting term structure set"); + if (discountCurve_.Count != arguments_.legs.Count) + throw new ArgumentException("no discounting term structure set for all legs"); + + results_.value = results_.cash = 0; + results_.errorEstimate = null; + results_.legNPV = new InitializedList < double? >(arguments_.legs.Count); + results_.legBPS = new InitializedList < double? >(arguments_.legs.Count); + List < double? > startDiscounts = new InitializedList < double? >(arguments_.legs.Count); + for (int i = 0; i < arguments_.legs.Count; ++i) + { + results_.value += results_.legNPV[i]; + results_.cash += arguments_.payer[i] * CashFlows.cash(arguments_.legs[i]); + try + { + Date d = CashFlows.startDate(arguments_.legs[i]); + startDiscounts[i] = discountCurve_[i].link.discount(d); + } + catch + { + startDiscounts[i] = null; } - results_.additionalResults.Add("startDiscounts", startDiscounts); - } - } + } + results_.additionalResults.Add("startDiscounts", startDiscounts); + } + } } diff --git a/src/QLNet/Pricingengines/Swap/Discountingswapengine.cs b/src/QLNet/Pricingengines/Swap/Discountingswapengine.cs index c436efa19..d9a22d8dc 100644 --- a/src/QLNet/Pricingengines/Swap/Discountingswapengine.cs +++ b/src/QLNet/Pricingengines/Swap/Discountingswapengine.cs @@ -1,34 +1,34 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet +namespace QLNet { - public class DiscountingSwapEngine : Swap.SwapEngine + public class DiscountingSwapEngine : Swap.SwapEngine { private Handle discountCurve_; private bool? includeSettlementDateFlows_; private Date settlementDate_, npvDate_; - public DiscountingSwapEngine(Handle discountCurve,bool? includeSettlementDateFlows = null, - Date settlementDate = null, Date npvDate = null) + public DiscountingSwapEngine(Handle discountCurve, bool? includeSettlementDateFlows = null, + Date settlementDate = null, Date npvDate = null) { discountCurve_ = discountCurve; discountCurve_.registerWith(update); @@ -38,9 +38,9 @@ public DiscountingSwapEngine(Handle discountCurve,bool? incl } // Instrument interface - public override void calculate() + public override void calculate() { - Utils.QL_REQUIRE( !discountCurve_.empty(), () => "discounting term structure handle is empty" ); + Utils.QL_REQUIRE(!discountCurve_.empty(), () => "discounting term structure handle is empty"); results_.value = results_.cash = 0; results_.errorEstimate = null; @@ -48,86 +48,86 @@ public override void calculate() Date refDate = discountCurve_.link.referenceDate(); Date settlementDate = settlementDate_; - if (settlementDate_== null ) + if (settlementDate_ == null) { settlementDate = refDate; - } - else + } + else { - Utils.QL_REQUIRE( settlementDate >= refDate, () => - "settlement date (" + settlementDate + ") before " + - "discount curve reference date (" + refDate + ")"); + Utils.QL_REQUIRE(settlementDate >= refDate, () => + "settlement date (" + settlementDate + ") before " + + "discount curve reference date (" + refDate + ")"); } results_.valuationDate = npvDate_; - if (npvDate_== null ) + if (npvDate_ == null) { results_.valuationDate = refDate; - } - else + } + else { - Utils.QL_REQUIRE( npvDate_ >= refDate, () => - "npv date (" + npvDate_ + ") before "+ - "discount curve reference date (" + refDate + ")"); + Utils.QL_REQUIRE(npvDate_ >= refDate, () => + "npv date (" + npvDate_ + ") before " + + "discount curve reference date (" + refDate + ")"); } results_.npvDateDiscount = discountCurve_.link.discount(results_.valuationDate); - + int n = arguments_.legs.Count; - - results_.legNPV = new InitializedList(n); - results_.legBPS= new InitializedList(n); - results_.startDiscounts= new InitializedList(n); - results_.endDiscounts = new InitializedList(n); + + results_.legNPV = new InitializedList < double? >(n); + results_.legBPS = new InitializedList < double? >(n); + results_.startDiscounts = new InitializedList < double? >(n); + results_.endDiscounts = new InitializedList < double? >(n); bool includeRefDateFlows = includeSettlementDateFlows_.HasValue ? includeSettlementDateFlows_.Value : Settings.includeReferenceDateEvents; - for (int i=0; i< n; ++i) + for (int i = 0; i < n; ++i) { - try + try { YieldTermStructure discount_ref = discountCurve_.currentLink(); double npv = 0, bps = 0; CashFlows.npvbps(arguments_.legs[i], - discount_ref, - includeRefDateFlows, - settlementDate, - results_.valuationDate, - out npv, - out bps); - results_.legNPV[i] = npv *arguments_.payer[i]; - results_.legBPS[i] = bps *arguments_.payer[i]; - - if ( !arguments_.legs[i].empty() ) - { - Date d1 = CashFlows.startDate( arguments_.legs[i] ); - if ( d1 >= refDate ) - results_.startDiscounts[i] = discountCurve_.link.discount( d1 ); - else - results_.startDiscounts[i] = null; - - Date d2 = CashFlows.maturityDate( arguments_.legs[i] ); - if ( d2 >= refDate ) - results_.endDiscounts[i] = discountCurve_.link.discount( d2 ); - else - results_.endDiscounts[i] = null; - } - else - { - results_.startDiscounts[i] = null; - results_.endDiscounts[i] = null; - } - - } - catch (Exception e) + discount_ref, + includeRefDateFlows, + settlementDate, + results_.valuationDate, + out npv, + out bps); + results_.legNPV[i] = npv * arguments_.payer[i]; + results_.legBPS[i] = bps * arguments_.payer[i]; + + if (!arguments_.legs[i].empty()) + { + Date d1 = CashFlows.startDate(arguments_.legs[i]); + if (d1 >= refDate) + results_.startDiscounts[i] = discountCurve_.link.discount(d1); + else + results_.startDiscounts[i] = null; + + Date d2 = CashFlows.maturityDate(arguments_.legs[i]); + if (d2 >= refDate) + results_.endDiscounts[i] = discountCurve_.link.discount(d2); + else + results_.endDiscounts[i] = null; + } + else + { + results_.startDiscounts[i] = null; + results_.endDiscounts[i] = null; + } + + } + catch (Exception e) { - Utils.QL_FAIL( (i+1) + " leg: " + e.Message); + Utils.QL_FAIL((i + 1) + " leg: " + e.Message); } results_.value += results_.legNPV[i]; } } - } + } } diff --git a/src/QLNet/Pricingengines/Swap/DiscretizedSwap.cs b/src/QLNet/Pricingengines/Swap/DiscretizedSwap.cs new file mode 100644 index 000000000..f62c40dd8 --- /dev/null +++ b/src/QLNet/Pricingengines/Swap/DiscretizedSwap.cs @@ -0,0 +1,181 @@ +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System.Collections.Generic; + +namespace QLNet +{ + public class DiscretizedSwap : DiscretizedAsset + { + + private VanillaSwap.Arguments arguments_; + private List fixedResetTimes_; + private List fixedPayTimes_; + private List floatingResetTimes_; + private List floatingPayTimes_; + + public DiscretizedSwap(VanillaSwap.Arguments args, + Date referenceDate, + DayCounter dayCounter) + { + arguments_ = args; + fixedResetTimes_ = new InitializedList(args.fixedResetDates.Count); + for (int i = 0; i < fixedResetTimes_.Count; ++i) + fixedResetTimes_[i] = + dayCounter.yearFraction(referenceDate, + args.fixedResetDates[i]); + + fixedPayTimes_ = new InitializedList(args.fixedPayDates.Count); + for (int i = 0; i < fixedPayTimes_.Count; ++i) + fixedPayTimes_[i] = + dayCounter.yearFraction(referenceDate, + args.fixedPayDates[i]); + + floatingResetTimes_ = new InitializedList(args.floatingResetDates.Count); + for (int i = 0; i < floatingResetTimes_.Count; ++i) + floatingResetTimes_[i] = + dayCounter.yearFraction(referenceDate, + args.floatingResetDates[i]); + + floatingPayTimes_ = new InitializedList(args.floatingPayDates.Count); + for (int i = 0; i < floatingPayTimes_.Count; ++i) + floatingPayTimes_[i] = + dayCounter.yearFraction(referenceDate, + args.floatingPayDates[i]); + } + + public override void reset(int size) + { + values_ = new Vector(size, 0.0); + adjustValues(); + } + + public override List mandatoryTimes() + { + List times = new List(); + for (int i = 0; i < fixedResetTimes_.Count; i++) + { + double t = fixedResetTimes_[i]; + if (t >= 0.0) + times.Add(t); + } + for (int i = 0; i < fixedPayTimes_.Count; i++) + { + double t = fixedPayTimes_[i]; + if (t >= 0.0) + times.Add(t); + } + for (int i = 0; i < floatingResetTimes_.Count; i++) + { + double t = floatingResetTimes_[i]; + if (t >= 0.0) + times.Add(t); + } + for (int i = 0; i < floatingPayTimes_.Count; i++) + { + double t = floatingPayTimes_[i]; + if (t >= 0.0) + times.Add(t); + } + return times; + } + + protected override void preAdjustValuesImpl() + { + // floating payments + for (int i = 0; i < floatingResetTimes_.Count; i++) + { + double t = floatingResetTimes_[i]; + if (t >= 0.0 && isOnTime(t)) + { + DiscretizedDiscountBond bond = new DiscretizedDiscountBond(); + bond.initialize(method(), floatingPayTimes_[i]); + bond.rollback(time_); + + double nominal = arguments_.nominal; + double T = arguments_.floatingAccrualTimes[i]; + double spread = arguments_.floatingSpreads[i]; + double accruedSpread = nominal * T * spread; + for (int j = 0; j < values_.size(); j++) + { + double coupon = nominal * (1.0 - bond.values()[j]) + + accruedSpread * bond.values()[j]; + if (arguments_.type == VanillaSwap.Type.Payer) + values_[j] += coupon; + else + values_[j] -= coupon; + } + } + } + // fixed payments + for (int i = 0; i < fixedResetTimes_.Count; i++) + { + double t = fixedResetTimes_[i]; + if (t >= 0.0 && isOnTime(t)) + { + DiscretizedDiscountBond bond = new DiscretizedDiscountBond(); + bond.initialize(method(), fixedPayTimes_[i]); + bond.rollback(time_); + + double fixedCoupon = arguments_.fixedCoupons[i]; + for (int j = 0; j < values_.size(); j++) + { + double coupon = fixedCoupon * bond.values()[j]; + if (arguments_.type == VanillaSwap.Type.Payer) + values_[j] -= coupon; + else + values_[j] += coupon; + } + } + } + } + + protected override void postAdjustValuesImpl() + { + // fixed coupons whose reset time is in the past won't be managed + // in preAdjustValues() + for (int i = 0; i < fixedPayTimes_.Count; i++) + { + double t = fixedPayTimes_[i]; + double reset = fixedResetTimes_[i]; + if (t >= 0.0 && isOnTime(t) && reset < 0.0) + { + double fixedCoupon = arguments_.fixedCoupons[i]; + if (arguments_.type == VanillaSwap.Type.Payer) + values_ -= fixedCoupon; + else + values_ += fixedCoupon; + } + } + // the same applies to floating payments whose rate is already fixed + for (int i = 0; i < floatingPayTimes_.Count; i++) + { + double t = floatingPayTimes_[i]; + double reset = floatingResetTimes_[i]; + if (t >= 0.0 && isOnTime(t) && reset < 0.0) + { + double currentFloatingCoupon = arguments_.floatingCoupons[i]; + if (arguments_.type == VanillaSwap.Type.Payer) + values_ += currentFloatingCoupon; + else + values_ -= currentFloatingCoupon; + } + } + } + } +} diff --git a/src/QLNet/Pricingengines/Swap/treeswapengine.cs b/src/QLNet/Pricingengines/Swap/TreeSwapEngine.cs similarity index 88% rename from src/QLNet/Pricingengines/Swap/treeswapengine.cs rename to src/QLNet/Pricingengines/Swap/TreeSwapEngine.cs index 4304b854a..6bbd8a0f3 100644 --- a/src/QLNet/Pricingengines/Swap/treeswapengine.cs +++ b/src/QLNet/Pricingengines/Swap/TreeSwapEngine.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -26,7 +26,7 @@ namespace QLNet /// /// Numerical lattice engine for swaps /// - public class TreeVanillaSwapEngine : LatticeShortRateModelEngine + public class TreeVanillaSwapEngine : LatticeShortRateModelEngine { private Handle termStructure_; @@ -36,8 +36,8 @@ model cannot provide one itself. */ public TreeVanillaSwapEngine(ShortRateModel model, - int timeSteps, - Handle termStructure) + int timeSteps, + Handle termStructure) : base(model, timeSteps) { termStructure_ = termStructure; @@ -45,8 +45,8 @@ public TreeVanillaSwapEngine(ShortRateModel model, } public TreeVanillaSwapEngine(ShortRateModel model, - TimeGrid timeGrid, - Handle termStructure) + TimeGrid timeGrid, + Handle termStructure) : base(model, timeGrid) { termStructure_ = termStructure; diff --git a/src/QLNet/Pricingengines/Swap/discretizedswap.cs b/src/QLNet/Pricingengines/Swap/discretizedswap.cs deleted file mode 100644 index 6d8a992b1..000000000 --- a/src/QLNet/Pricingengines/Swap/discretizedswap.cs +++ /dev/null @@ -1,166 +0,0 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System.Collections.Generic; - -namespace QLNet -{ - public class DiscretizedSwap : DiscretizedAsset - { - - private VanillaSwap.Arguments arguments_; - private List fixedResetTimes_; - private List fixedPayTimes_; - private List floatingResetTimes_; - private List floatingPayTimes_; - - public DiscretizedSwap(VanillaSwap.Arguments args, - Date referenceDate, - DayCounter dayCounter) - { - arguments_ = args; - fixedResetTimes_ = new InitializedList(args.fixedResetDates.Count); - for (int i = 0; i < fixedResetTimes_.Count; ++i) - fixedResetTimes_[i] = - dayCounter.yearFraction(referenceDate, - args.fixedResetDates[i]); - - fixedPayTimes_ = new InitializedList(args.fixedPayDates.Count); - for (int i = 0; i < fixedPayTimes_.Count; ++i) - fixedPayTimes_[i] = - dayCounter.yearFraction(referenceDate, - args.fixedPayDates[i]); - - floatingResetTimes_ = new InitializedList(args.floatingResetDates.Count); - for (int i = 0; i < floatingResetTimes_.Count; ++i) - floatingResetTimes_[i] = - dayCounter.yearFraction(referenceDate, - args.floatingResetDates[i]); - - floatingPayTimes_ = new InitializedList(args.floatingPayDates.Count); - for (int i = 0; i < floatingPayTimes_.Count; ++i) - floatingPayTimes_[i] = - dayCounter.yearFraction(referenceDate, - args.floatingPayDates[i]); - } - - public override void reset(int size){ - values_ = new Vector(size, 0.0); - adjustValues(); - } - - public override List mandatoryTimes() - { - List times = new List(); - for (int i = 0; i < fixedResetTimes_.Count; i++){ - double t = fixedResetTimes_[i]; - if (t >= 0.0) - times.Add(t); - } - for (int i = 0; i < fixedPayTimes_.Count; i++){ - double t = fixedPayTimes_[i]; - if (t >= 0.0) - times.Add(t); - } - for (int i = 0; i < floatingResetTimes_.Count; i++){ - double t = floatingResetTimes_[i]; - if (t >= 0.0) - times.Add(t); - } - for (int i = 0; i < floatingPayTimes_.Count; i++){ - double t = floatingPayTimes_[i]; - if (t >= 0.0) - times.Add(t); - } - return times; - } - - protected override void preAdjustValuesImpl() - { - // floating payments - for (int i = 0; i < floatingResetTimes_.Count; i++){ - double t = floatingResetTimes_[i]; - if (t >= 0.0 && isOnTime(t)){ - DiscretizedDiscountBond bond = new DiscretizedDiscountBond(); - bond.initialize(method(), floatingPayTimes_[i]); - bond.rollback(time_); - - double nominal = arguments_.nominal; - double T = arguments_.floatingAccrualTimes[i]; - double spread = arguments_.floatingSpreads[i]; - double accruedSpread = nominal * T * spread; - for (int j = 0; j < values_.size(); j++){ - double coupon = nominal * (1.0 - bond.values()[j]) - + accruedSpread * bond.values()[j]; - if (arguments_.type == VanillaSwap.Type.Payer) - values_[j] += coupon; - else - values_[j] -= coupon; - } - } - } - // fixed payments - for (int i = 0; i < fixedResetTimes_.Count; i++){ - double t = fixedResetTimes_[i]; - if (t >= 0.0 && isOnTime(t)){ - DiscretizedDiscountBond bond = new DiscretizedDiscountBond(); - bond.initialize(method(), fixedPayTimes_[i]); - bond.rollback(time_); - - double fixedCoupon = arguments_.fixedCoupons[i]; - for (int j = 0; j < values_.size(); j++){ - double coupon = fixedCoupon * bond.values()[j]; - if (arguments_.type == VanillaSwap.Type.Payer) - values_[j] -= coupon; - else - values_[j] += coupon; - } - } - } - } - - protected override void postAdjustValuesImpl() - { - // fixed coupons whose reset time is in the past won't be managed - // in preAdjustValues() - for (int i = 0; i < fixedPayTimes_.Count; i++){ - double t = fixedPayTimes_[i]; - double reset = fixedResetTimes_[i]; - if (t >= 0.0 && isOnTime(t) && reset < 0.0){ - double fixedCoupon = arguments_.fixedCoupons[i]; - if (arguments_.type == VanillaSwap.Type.Payer) - values_ -= fixedCoupon; - else - values_ += fixedCoupon; - } - } - // the same applies to floating payments whose rate is already fixed - for (int i = 0; i < floatingPayTimes_.Count; i++){ - double t = floatingPayTimes_[i]; - double reset = floatingResetTimes_[i]; - if (t >= 0.0 && isOnTime(t) && reset < 0.0){ - double currentFloatingCoupon = arguments_.floatingCoupons[i]; - if (arguments_.type == VanillaSwap.Type.Payer) - values_ += currentFloatingCoupon; - else - values_ -= currentFloatingCoupon; - } - } - } - } -} diff --git a/src/QLNet/Pricingengines/asian/AnalyticContinuousGeometricAveragePriceAsianEngine.cs b/src/QLNet/Pricingengines/asian/AnalyticContinuousGeometricAveragePriceAsianEngine.cs index 8afe9a360..aef8dc0c8 100644 --- a/src/QLNet/Pricingengines/asian/AnalyticContinuousGeometricAveragePriceAsianEngine.cs +++ b/src/QLNet/Pricingengines/asian/AnalyticContinuousGeometricAveragePriceAsianEngine.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -39,67 +39,67 @@ reproducing numerical derivatives. */ public class AnalyticContinuousGeometricAveragePriceAsianEngine : ContinuousAveragingAsianOption.Engine { - public AnalyticContinuousGeometricAveragePriceAsianEngine( GeneralizedBlackScholesProcess process ) + public AnalyticContinuousGeometricAveragePriceAsianEngine(GeneralizedBlackScholesProcess process) { process_ = process; - process_.registerWith( update ); + process_.registerWith(update); } public override void calculate() { - Utils.QL_REQUIRE(arguments_.averageType == Average.Type.Geometric,()=> "not a geometric average option"); - Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European,()=> "not an European Option"); + Utils.QL_REQUIRE(arguments_.averageType == Average.Type.Geometric, () => "not a geometric average option"); + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European Option"); Date exercise = arguments_.exercise.lastDate(); PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; - Utils.QL_REQUIRE( payoff != null,()=> "non-plain payoff given" ); + Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); - double volatility = process_.blackVolatility().link.blackVol( exercise, payoff.strike() ); - double variance = process_.blackVolatility().link.blackVariance( exercise,payoff.strike() ); - double riskFreeDiscount = process_.riskFreeRate().link.discount( exercise ); + double volatility = process_.blackVolatility().link.blackVol(exercise, payoff.strike()); + double variance = process_.blackVolatility().link.blackVariance(exercise, payoff.strike()); + double riskFreeDiscount = process_.riskFreeRate().link.discount(exercise); DayCounter rfdc = process_.riskFreeRate().link.dayCounter(); DayCounter divdc = process_.dividendYield().link.dayCounter(); DayCounter voldc = process_.blackVolatility().link.dayCounter(); double dividendYield = 0.5 * ( - process_.riskFreeRate().link.zeroRate( exercise, rfdc, - Compounding.Continuous, - Frequency.NoFrequency ).rate() + - process_.dividendYield().link.zeroRate( exercise, divdc, - Compounding.Continuous, - Frequency.NoFrequency ).rate() + - volatility * volatility / 6.0 ); + process_.riskFreeRate().link.zeroRate(exercise, rfdc, + Compounding.Continuous, + Frequency.NoFrequency).rate() + + process_.dividendYield().link.zeroRate(exercise, divdc, + Compounding.Continuous, + Frequency.NoFrequency).rate() + + volatility * volatility / 6.0); - double t_q = divdc.yearFraction( process_.dividendYield().link.referenceDate(), exercise ); - double dividendDiscount = Math.Exp( -dividendYield * t_q ); + double t_q = divdc.yearFraction(process_.dividendYield().link.referenceDate(), exercise); + double dividendDiscount = Math.Exp(-dividendYield * t_q); double spot = process_.stateVariable().link.value(); - Utils.QL_REQUIRE( spot > 0.0,()=> "negative or null underlying" ); + Utils.QL_REQUIRE(spot > 0.0, () => "negative or null underlying"); double forward = spot * dividendDiscount / riskFreeDiscount; - BlackCalculator black = new BlackCalculator( payoff, forward, Math.Sqrt( variance / 3.0 ), riskFreeDiscount ); + BlackCalculator black = new BlackCalculator(payoff, forward, Math.Sqrt(variance / 3.0), riskFreeDiscount); results_.value = black.value(); - results_.delta = black.delta( spot ); - results_.gamma = black.gamma( spot ); + results_.delta = black.delta(spot); + results_.gamma = black.gamma(spot); - results_.dividendRho = black.dividendRho( t_q ) / 2.0; + results_.dividendRho = black.dividendRho(t_q) / 2.0; - double t_r = rfdc.yearFraction( process_.riskFreeRate().link.referenceDate(),arguments_.exercise.lastDate() ); - results_.rho = black.rho( t_r ) + 0.5 * black.dividendRho( t_q ); + double t_r = rfdc.yearFraction(process_.riskFreeRate().link.referenceDate(), arguments_.exercise.lastDate()); + results_.rho = black.rho(t_r) + 0.5 * black.dividendRho(t_q); - double t_v = voldc.yearFraction(process_.blackVolatility().link.referenceDate(),arguments_.exercise.lastDate() ); - results_.vega = black.vega( t_v ) / Math.Sqrt( 3.0 ) + - black.dividendRho( t_q ) * volatility / 6.0; + double t_v = voldc.yearFraction(process_.blackVolatility().link.referenceDate(), arguments_.exercise.lastDate()); + results_.vega = black.vega(t_v) / Math.Sqrt(3.0) + + black.dividendRho(t_q) * volatility / 6.0; try { - results_.theta = black.theta( spot, t_v ); + results_.theta = black.theta(spot, t_v); } - catch ( Exception /*Error*/) + catch (Exception /*Error*/) { - results_.theta = null; + results_.theta = null; } } diff --git a/src/QLNet/Pricingengines/asian/AnalyticDiscreteGeometricAveragePriceAsianEngine.cs b/src/QLNet/Pricingengines/asian/AnalyticDiscreteGeometricAveragePriceAsianEngine.cs index 8a7372bc5..5e87fec82 100644 --- a/src/QLNet/Pricingengines/asian/AnalyticDiscreteGeometricAveragePriceAsianEngine.cs +++ b/src/QLNet/Pricingengines/asian/AnalyticDiscreteGeometricAveragePriceAsianEngine.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -42,10 +42,10 @@ public class AnalyticDiscreteGeometricAveragePriceAsianEngine : DiscreteAveragin { private GeneralizedBlackScholesProcess process_; - public AnalyticDiscreteGeometricAveragePriceAsianEngine( GeneralizedBlackScholesProcess process ) + public AnalyticDiscreteGeometricAveragePriceAsianEngine(GeneralizedBlackScholesProcess process) { process_ = process; - process_.registerWith( update ); + process_.registerWith(update); } public override void calculate() @@ -54,26 +54,27 @@ public override void calculate() since it can be used as control variate for the Arithmetic version QL_REQUIRE(arguments_.averageType == Average::Geometric,"not a geometric average option") */ - Utils.QL_REQUIRE( arguments_.exercise.type() == Exercise.Type.European, () => "not an European Option" ); + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European Option"); double runningLog; int pastFixings; - if ( arguments_.averageType == Average.Type.Geometric ) + if (arguments_.averageType == Average.Type.Geometric) { - Utils.QL_REQUIRE( arguments_.runningAccumulator > 0.0, () => - "positive running product required: " + arguments_.runningAccumulator + " not allowed" ); + Utils.QL_REQUIRE(arguments_.runningAccumulator > 0.0, () => + "positive running product required: " + arguments_.runningAccumulator + " not allowed"); - runningLog = Math.Log( arguments_.runningAccumulator.GetValueOrDefault() ); + runningLog = Math.Log(arguments_.runningAccumulator.GetValueOrDefault()); pastFixings = arguments_.pastFixings.GetValueOrDefault(); } else - { // it is being used as control variate + { + // it is being used as control variate runningLog = 1.0; pastFixings = 0; } PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; - Utils.QL_REQUIRE( payoff != null, () => "non-plain payoff given" ); + Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); Date referenceDate = process_.riskFreeRate().link.referenceDate(); DayCounter rfdc = process_.riskFreeRate().link.dayCounter(); @@ -81,12 +82,12 @@ public override void calculate() DayCounter voldc = process_.blackVolatility().link.dayCounter(); List fixingTimes = new List(); int i; - for ( i = 0; i < arguments_.fixingDates.Count; i++ ) + for (i = 0; i < arguments_.fixingDates.Count; i++) { - if ( arguments_.fixingDates[i] >= referenceDate ) + if (arguments_.fixingDates[i] >= referenceDate) { - double t = voldc.yearFraction( referenceDate, arguments_.fixingDates[i] ); - fixingTimes.Add( t ); + double t = voldc.yearFraction(referenceDate, arguments_.fixingDates[i]); + fixingTimes.Add(t); } } @@ -98,79 +99,79 @@ public override void calculate() double futureWeight = 1.0 - pastWeight; double timeSum = 0; - fixingTimes.ForEach( ( ii, vv ) => timeSum += fixingTimes[ii] ); + fixingTimes.ForEach((ii, vv) => timeSum += fixingTimes[ii]); - double vola = process_.blackVolatility().link.blackVol( arguments_.exercise.lastDate(), payoff.strike() ); + double vola = process_.blackVolatility().link.blackVol(arguments_.exercise.lastDate(), payoff.strike()); double temp = 0.0; - for ( i = pastFixings + 1; i < numberOfFixings; i++ ) - temp += fixingTimes[i - pastFixings - 1] * ( N - i ); - double variance = vola * vola / N / N * ( timeSum + 2.0 * temp ); - double dsigG_dsig = Math.Sqrt( ( timeSum + 2.0 * temp ) ) / N; + for (i = pastFixings + 1; i < numberOfFixings; i++) + temp += fixingTimes[i - pastFixings - 1] * (N - i); + double variance = vola * vola / N / N * (timeSum + 2.0 * temp); + double dsigG_dsig = Math.Sqrt((timeSum + 2.0 * temp)) / N; double sigG = vola * dsigG_dsig; - double dmuG_dsig = -( vola * timeSum ) / N; + double dmuG_dsig = -(vola * timeSum) / N; Date exDate = arguments_.exercise.lastDate(); double dividendRate = process_.dividendYield().link. - zeroRate( exDate, divdc, Compounding.Continuous, Frequency.NoFrequency ).rate(); + zeroRate(exDate, divdc, Compounding.Continuous, Frequency.NoFrequency).rate(); double riskFreeRate = process_.riskFreeRate().link. - zeroRate( exDate, rfdc, Compounding.Continuous, Frequency.NoFrequency ).rate(); + zeroRate(exDate, rfdc, Compounding.Continuous, Frequency.NoFrequency).rate(); double nu = riskFreeRate - dividendRate - 0.5 * vola * vola; double s = process_.stateVariable().link.value(); - Utils.QL_REQUIRE( s > 0.0, () => "positive underlying value required" ); + Utils.QL_REQUIRE(s > 0.0, () => "positive underlying value required"); - int M = ( pastFixings == 0 ? 1 : pastFixings ); - double muG = pastWeight * runningLog / M + futureWeight * Math.Log( s ) + nu * timeSum / N; - double forwardPrice = Math.Exp( muG + variance / 2.0 ); + int M = (pastFixings == 0 ? 1 : pastFixings); + double muG = pastWeight * runningLog / M + futureWeight * Math.Log(s) + nu * timeSum / N; + double forwardPrice = Math.Exp(muG + variance / 2.0); - double riskFreeDiscount = process_.riskFreeRate().link.discount( arguments_.exercise.lastDate() ); + double riskFreeDiscount = process_.riskFreeRate().link.discount(arguments_.exercise.lastDate()); - BlackCalculator black = new BlackCalculator( payoff, forwardPrice, Math.Sqrt( variance ), riskFreeDiscount ); + BlackCalculator black = new BlackCalculator(payoff, forwardPrice, Math.Sqrt(variance), riskFreeDiscount); results_.value = black.value(); - results_.delta = futureWeight * black.delta( forwardPrice ) * forwardPrice / s; - results_.gamma = forwardPrice * futureWeight / ( s * s ) - * ( black.gamma( forwardPrice ) * futureWeight * forwardPrice - - pastWeight * black.delta( forwardPrice ) ); + results_.delta = futureWeight * black.delta(forwardPrice) * forwardPrice / s; + results_.gamma = forwardPrice * futureWeight / (s * s) + * (black.gamma(forwardPrice) * futureWeight * forwardPrice + - pastWeight * black.delta(forwardPrice)); double Nx_1, nx_1; CumulativeNormalDistribution CND = new CumulativeNormalDistribution(); NormalDistribution ND = new NormalDistribution(); - if ( sigG > Const.QL_EPSILON ) + if (sigG > Const.QL_EPSILON) { - double x_1 = ( muG - Math.Log( payoff.strike() ) + variance ) / sigG; - Nx_1 = CND.value( x_1 ); - nx_1 = ND.value( x_1 ); + double x_1 = (muG - Math.Log(payoff.strike()) + variance) / sigG; + Nx_1 = CND.value(x_1); + nx_1 = ND.value(x_1); } else { - Nx_1 = ( muG > Math.Log( payoff.strike() ) ? 1.0 : 0.0 ); + Nx_1 = (muG > Math.Log(payoff.strike()) ? 1.0 : 0.0); nx_1 = 0.0; } results_.vega = forwardPrice * riskFreeDiscount * - ( ( dmuG_dsig + sigG * dsigG_dsig ) * Nx_1 + nx_1 * dsigG_dsig ); + ((dmuG_dsig + sigG * dsigG_dsig) * Nx_1 + nx_1 * dsigG_dsig); - if ( payoff.optionType() == Option.Type.Put ) + if (payoff.optionType() == Option.Type.Put) results_.vega -= riskFreeDiscount * forwardPrice * - ( dmuG_dsig + sigG * dsigG_dsig ); + (dmuG_dsig + sigG * dsigG_dsig); - double tRho = rfdc.yearFraction( process_.riskFreeRate().link.referenceDate(), - arguments_.exercise.lastDate() ); - results_.rho = black.rho( tRho ) * timeSum / ( N * tRho ) - - ( tRho - timeSum / N ) * results_.value; + double tRho = rfdc.yearFraction(process_.riskFreeRate().link.referenceDate(), + arguments_.exercise.lastDate()); + results_.rho = black.rho(tRho) * timeSum / (N * tRho) + - (tRho - timeSum / N) * results_.value; double tDiv = divdc.yearFraction( - process_.dividendYield().link.referenceDate(), - arguments_.exercise.lastDate() ); + process_.dividendYield().link.referenceDate(), + arguments_.exercise.lastDate()); - results_.dividendRho = black.dividendRho( tDiv ) * timeSum / ( N * tDiv ); + results_.dividendRho = black.dividendRho(tDiv) * timeSum / (N * tDiv); results_.strikeSensitivity = black.strikeSensitivity(); - results_.theta = Utils.blackScholesTheta( process_, - results_.value.GetValueOrDefault(), - results_.delta.GetValueOrDefault(), - results_.gamma.GetValueOrDefault() ); + results_.theta = Utils.blackScholesTheta(process_, + results_.value.GetValueOrDefault(), + results_.delta.GetValueOrDefault(), + results_.gamma.GetValueOrDefault()); } } } diff --git a/src/QLNet/Pricingengines/asian/AnalyticDiscreteGeometricAverageStrikeAsianEngine.cs b/src/QLNet/Pricingengines/asian/AnalyticDiscreteGeometricAverageStrikeAsianEngine.cs index a52a90c7c..9bab73dad 100644 --- a/src/QLNet/Pricingengines/asian/AnalyticDiscreteGeometricAverageStrikeAsianEngine.cs +++ b/src/QLNet/Pricingengines/asian/AnalyticDiscreteGeometricAverageStrikeAsianEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -41,32 +41,32 @@ public AnalyticDiscreteGeometricAverageStrikeAsianEngine(GeneralizedBlackScholes } public override void calculate() { - Utils.QL_REQUIRE(arguments_.averageType == Average.Type.Geometric,()=> - "not a geometric average option"); + Utils.QL_REQUIRE(arguments_.averageType == Average.Type.Geometric, () => + "not a geometric average option"); - Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European,()=> - "not an European option"); + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => + "not an European option"); - Utils.QL_REQUIRE(arguments_.runningAccumulator > 0.0,()=> - "positive running product required: " + arguments_.runningAccumulator + "not allowed"); + Utils.QL_REQUIRE(arguments_.runningAccumulator > 0.0, () => + "positive running product required: " + arguments_.runningAccumulator + "not allowed"); double runningLog = Math.Log(arguments_.runningAccumulator.GetValueOrDefault()); int? pastFixings = arguments_.pastFixings; - Utils.QL_REQUIRE(pastFixings == 0,()=> "past fixings currently not managed"); + Utils.QL_REQUIRE(pastFixings == 0, () => "past fixings currently not managed"); PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; - Utils.QL_REQUIRE(payoff != null,()=> "non-plain payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); DayCounter rfdc = process_.riskFreeRate().link.dayCounter(); DayCounter divdc = process_.dividendYield().link.dayCounter(); DayCounter voldc = process_.blackVolatility().link.dayCounter(); List fixingTimes = new List(); - for (int i=0; i=arguments_.fixingDates[0]) + if (arguments_.fixingDates[i] >= arguments_.fixingDates[0]) { - double t = voldc.yearFraction(arguments_.fixingDates[0],arguments_.fixingDates[i]); + double t = voldc.yearFraction(arguments_.fixingDates[0], arguments_.fixingDates[i]); fixingTimes.Add(t); } } @@ -75,70 +75,70 @@ public override void calculate() int numberOfFixings = pastFixings.GetValueOrDefault() + remainingFixings; double N = (double)(numberOfFixings); - double pastWeight = pastFixings.GetValueOrDefault()/N; - double futureWeight = 1.0-pastWeight; + double pastWeight = pastFixings.GetValueOrDefault() / N; + double futureWeight = 1.0 - pastWeight; double timeSum = 0; - fixingTimes.ForEach( ( ii, vv ) => timeSum += fixingTimes[ii] ); + fixingTimes.ForEach((ii, vv) => timeSum += fixingTimes[ii]); double residualTime = rfdc.yearFraction(arguments_.fixingDates[pastFixings.GetValueOrDefault()], - arguments_.exercise.lastDate()); + arguments_.exercise.lastDate()); double underlying = process_.stateVariable().link.value(); - Utils.QL_REQUIRE(underlying > 0.0,()=> "positive underlying value required"); + Utils.QL_REQUIRE(underlying > 0.0, () => "positive underlying value required"); double volatility = process_.blackVolatility().link.blackVol(arguments_.exercise.lastDate(), underlying); Date exDate = arguments_.exercise.lastDate(); - double dividendRate = process_.dividendYield().link.zeroRate(exDate, divdc, - Compounding.Continuous, Frequency.NoFrequency).value(); + double dividendRate = process_.dividendYield().link.zeroRate(exDate, divdc, + Compounding.Continuous, Frequency.NoFrequency).value(); - double riskFreeRate = process_.riskFreeRate().link.zeroRate(exDate, rfdc, - Compounding.Continuous, Frequency.NoFrequency).value(); + double riskFreeRate = process_.riskFreeRate().link.zeroRate(exDate, rfdc, + Compounding.Continuous, Frequency.NoFrequency).value(); - double nu = riskFreeRate - dividendRate - 0.5*volatility*volatility; + double nu = riskFreeRate - dividendRate - 0.5 * volatility * volatility; double temp = 0.0; - for (int i=pastFixings.GetValueOrDefault()+1; i. + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System.Collections.Generic; +using System.Linq; + +namespace QLNet +{ + //! Pricing engine for discrete average Asians using Monte Carlo simulation + /*! \warning control-variate calculation is disabled under VC++6. + + \ingroup asianengines + */ + + public class MCDiscreteAveragingAsianEngine : McSimulation, IGenericEngine + //DiscreteAveragingAsianOption.Engine, + //McSimulation + where RNG : IRSG, new () + where S : IGeneralStatistics, new () + { + // data members + protected GeneralizedBlackScholesProcess process_; + protected int maxTimeStepsPerYear_; + protected int requiredSamples_, maxSamples_; + double requiredTolerance_; + bool brownianBridge_; + ulong seed_; + + // constructor + public MCDiscreteAveragingAsianEngine( + GeneralizedBlackScholesProcess process, + int maxTimeStepsPerYear, + bool brownianBridge, + bool antitheticVariate, + bool controlVariate, + int requiredSamples, + double requiredTolerance, + int maxSamples, + ulong seed) : base(antitheticVariate, controlVariate) + { + process_ = process; + maxTimeStepsPerYear_ = maxTimeStepsPerYear; + requiredSamples_ = requiredSamples; + maxSamples_ = maxSamples; + requiredTolerance_ = requiredTolerance; + brownianBridge_ = brownianBridge; + seed_ = seed; + process_.registerWith(update); + } + + public void calculate() + { + base.calculate(requiredTolerance_, requiredSamples_, maxSamples_); + results_.value = this.mcModel_.sampleAccumulator().mean(); + if (FastActivator.Create().allowsErrorEstimate != 0) + results_.errorEstimate = + this.mcModel_.sampleAccumulator().errorEstimate(); + } + + // McSimulation implementation + protected override TimeGrid timeGrid() + { + Date referenceDate = process_.riskFreeRate().link.referenceDate(); + DayCounter voldc = process_.blackVolatility().link.dayCounter() ; + List fixingTimes = new InitializedList(arguments_.fixingDates.Count); + + for (int i = 0; i < arguments_.fixingDates.Count; i++) + { + if (arguments_.fixingDates[i] >= referenceDate) + { + double t = voldc.yearFraction(referenceDate, + arguments_.fixingDates[i]); + fixingTimes.Add(t); + } + } + // handle here maxStepsPerYear + return new TimeGrid(fixingTimes.Last(), fixingTimes.Count); + } + + protected override IPathGenerator pathGenerator() + { + + TimeGrid grid = this.timeGrid(); + IRNG gen = (IRNG)new RNG().make_sequence_generator(grid.size() - 1, seed_); + return new PathGenerator(process_, grid, + gen, brownianBridge_); + } + + protected override double? controlVariateValue() + { + IPricingEngine controlPE = this.controlPricingEngine(); + Utils.QL_REQUIRE(controlPE != null, () => "engine does not provide control variation pricing engine"); + + DiscreteAveragingAsianOption.Arguments controlArguments = + (DiscreteAveragingAsianOption.Arguments)controlPE.getArguments(); + controlArguments = arguments_; + controlPE.calculate(); + + DiscreteAveragingAsianOption.Results controlResults = + (DiscreteAveragingAsianOption.Results)(controlPE.getResults()); + + return controlResults.value; + + } + + protected override PathPricer pathPricer() + { + throw new System.NotImplementedException(); + } + + #region PricingEngine + protected DiscreteAveragingAsianOption.Arguments arguments_ = new DiscreteAveragingAsianOption.Arguments(); + protected DiscreteAveragingAsianOption.Results results_ = new DiscreteAveragingAsianOption.Results(); + + public IPricingEngineArguments getArguments() { return arguments_; } + public IPricingEngineResults getResults() { return results_; } + public void reset() { results_.reset(); } + + #region Observer & Observable + // observable interface + private readonly WeakEventSource eventSource = new WeakEventSource(); + public event Callback notifyObserversEvent + { + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } + } + + public void registerWith(Callback handler) { notifyObserversEvent += handler; } + public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } + protected void notifyObservers() + { + eventSource.Raise(); + } + + public void update() { notifyObservers(); } + #endregion + #endregion + } +} diff --git a/src/QLNet/Pricingengines/asian/Mc_Discr_Arith_Av_Price.cs b/src/QLNet/Pricingengines/asian/Mc_Discr_Arith_Av_Price.cs new file mode 100644 index 000000000..9f7be9e7d --- /dev/null +++ b/src/QLNet/Pricingengines/asian/Mc_Discr_Arith_Av_Price.cs @@ -0,0 +1,269 @@ +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +namespace QLNet +{ + //! Monte Carlo pricing engine for discrete arithmetic average price Asian + /*! Monte Carlo pricing engine for discrete arithmetic average price + Asian options. It can use MCDiscreteGeometricAPEngine (Monte Carlo + discrete arithmetic average price engine) and + AnalyticDiscreteGeometricAveragePriceAsianEngine (analytic discrete + arithmetic average price engine) for control variation. + + \ingroup asianengines + + \test the correctness of the returned value is tested by + reproducing results available in literature. + */ + //template + public class MCDiscreteArithmeticAPEngine + : MCDiscreteAveragingAsianEngine + where RNG : IRSG, new () + where S : IGeneralStatistics, new () + { + + // constructor + public MCDiscreteArithmeticAPEngine( + GeneralizedBlackScholesProcess process, + int maxTimeStepPerYear, + bool brownianBridge, + bool antitheticVariate, + bool controlVariate, + int requiredSamples, + double requiredTolerance, + int maxSamples, + ulong seed) + : base(process, maxTimeStepPerYear, brownianBridge, antitheticVariate, + controlVariate, requiredSamples, requiredTolerance, maxSamples, seed) + { + } + + protected override PathPricer pathPricer() + { + PlainVanillaPayoff payoff = (PlainVanillaPayoff)(this.arguments_.payoff); + Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); + + EuropeanExercise exercise = (EuropeanExercise)this.arguments_.exercise; + Utils.QL_REQUIRE(exercise != null, () => "wrong exercise given"); + + return (PathPricer)new ArithmeticAPOPathPricer( + payoff.optionType(), + payoff.strike(), + this.process_.riskFreeRate().link.discount(this.timeGrid().Last()), + this.arguments_.runningAccumulator.GetValueOrDefault(), + this.arguments_.pastFixings.GetValueOrDefault()); + } + + protected override PathPricer controlPathPricer() + { + PlainVanillaPayoff payoff = (PlainVanillaPayoff)this.arguments_.payoff; + Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); + + EuropeanExercise exercise = (EuropeanExercise)this.arguments_.exercise; + Utils.QL_REQUIRE(exercise != null, () => "wrong exercise given"); + + // for seasoned option the geometric strike might be rescaled + // to obtain an equivalent arithmetic strike. + // Any change applied here MUST be applied to the analytic engine too + return (PathPricer)new GeometricAPOPathPricer( + payoff.optionType(), + payoff.strike(), + this.process_.riskFreeRate().link.discount(this.timeGrid().Last())); + } + + protected override IPricingEngine controlPricingEngine() + { + return new AnalyticDiscreteGeometricAveragePriceAsianEngine(this.process_); + } + } + + public class ArithmeticAPOPathPricer : PathPricer + { + + private PlainVanillaPayoff payoff_; + private double discount_; + private double runningSum_; + private int pastFixings_; + + public ArithmeticAPOPathPricer(Option.Type type, + double strike, + double discount, + double runningSum, + int pastFixings) + { + payoff_ = new PlainVanillaPayoff(type, strike); + discount_ = discount; + runningSum_ = runningSum; + pastFixings_ = pastFixings; + Utils.QL_REQUIRE(strike >= 0.0, () => "strike less than zero not allowed"); + } + + public ArithmeticAPOPathPricer(Option.Type type, + double strike, + double discount, + double runningSum) + : this(type, strike, discount, runningSum, 0) { } + + public ArithmeticAPOPathPricer(Option.Type type, + double strike, + double discount) + : this(type, strike, discount, 0.0, 0) { } + + + public double value(Path path) + { + int n = path.length(); + Utils.QL_REQUIRE(n > 1, () => "the path cannot be empty"); + + double sum = runningSum_; + int fixings; + if (path.timeGrid().mandatoryTimes()[0].IsEqual(0.0)) + { + // include initial fixing + for (int i = 0; i < path.length(); i++) + sum += path[i]; + fixings = pastFixings_ + n; + } + else + { + for (int i = 1; i < path.length(); i++) + sum += path[i]; + fixings = pastFixings_ + n - 1; + } + double averagePrice = sum / fixings; + return discount_ * payoff_.value(averagePrice); + + } + + public double value(IPath path) + { + Utils.QL_REQUIRE(path.length() > 0, () => "the path cannot be empty"); + return payoff_.value(((Path) path).back()) * discount_; + } + } + // + public class MakeMCDiscreteArithmeticAPEngine + where RNG : IRSG, new () + where S : Statistics, new () + { + public MakeMCDiscreteArithmeticAPEngine(GeneralizedBlackScholesProcess process) + { + process_ = process; + antithetic_ = false; + controlVariate_ = false; + steps_ = null; + samples_ = null; + maxSamples_ = null; + tolerance_ = null; + brownianBridge_ = true; + seed_ = 0; + } + + // named parameters + public MakeMCDiscreteArithmeticAPEngine withStepsPerYear(int maxSteps) + { + steps_ = maxSteps; + return this; + } + + public MakeMCDiscreteArithmeticAPEngine withBrownianBridge(bool b) + { + brownianBridge_ = b; + return this; + } + + public MakeMCDiscreteArithmeticAPEngine withBrownianBridge() + { + return withBrownianBridge(true); + } + + public MakeMCDiscreteArithmeticAPEngine withSamples(int samples) + { + Utils.QL_REQUIRE(tolerance_ == null, () => "tolerance already set"); + samples_ = samples; + return this; + } + + public MakeMCDiscreteArithmeticAPEngine withTolerance(double tolerance) + { + Utils.QL_REQUIRE(samples_ == null, () => "number of samples already set"); + Utils.QL_REQUIRE(FastActivator.Create().allowsErrorEstimate != 0, () => + "chosen random generator policy does not allow an error estimate"); + tolerance_ = tolerance; + return this; + } + + public MakeMCDiscreteArithmeticAPEngine withMaxSamples(int samples) + { + maxSamples_ = samples; + return this; + } + + public MakeMCDiscreteArithmeticAPEngine withSeed(ulong seed) + { + seed_ = seed; + return this; + } + + public MakeMCDiscreteArithmeticAPEngine withAntitheticVariate(bool b) + { + antithetic_ = b; + return this; + } + + public MakeMCDiscreteArithmeticAPEngine withAntitheticVariate() + { + return this.withAntitheticVariate(true); + } + + public MakeMCDiscreteArithmeticAPEngine withControlVariate(bool b) + { + controlVariate_ = b; + return this; + } + + public MakeMCDiscreteArithmeticAPEngine withControlVariate() + { + return this.withControlVariate(true); + } + + + // conversion to pricing engine + public IPricingEngine value() + { + Utils.QL_REQUIRE(steps_ != null, () => "max number of steps per year not given"); + return (IPricingEngine)new MCDiscreteArithmeticAPEngine(process_, + steps_.Value, + brownianBridge_, + antithetic_, controlVariate_, + samples_.Value, tolerance_.Value, + maxSamples_.Value, + seed_); + + } + + private GeneralizedBlackScholesProcess process_; + private bool antithetic_, controlVariate_; + private int? steps_, samples_, maxSamples_; + private double? tolerance_; + private bool brownianBridge_; + private ulong seed_; + } + +} diff --git a/src/QLNet/Pricingengines/asian/mc_discr_arith_av_strike.cs b/src/QLNet/Pricingengines/asian/Mc_Discr_Arith_Av_Strike.cs similarity index 79% rename from src/QLNet/Pricingengines/asian/mc_discr_arith_av_strike.cs rename to src/QLNet/Pricingengines/asian/Mc_Discr_Arith_Av_Strike.cs index 1473461e3..d2fc7b545 100644 --- a/src/QLNet/Pricingengines/asian/mc_discr_arith_av_strike.cs +++ b/src/QLNet/Pricingengines/asian/Mc_Discr_Arith_Av_Strike.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -26,8 +26,8 @@ namespace QLNet /// public class MCDiscreteArithmeticASEngine : MCDiscreteAveragingAsianEngine - where RNG : IRSG, new() - where S : Statistics, new() + where RNG : IRSG, new () + where S : Statistics, new () { // constructor public MCDiscreteArithmeticASEngine( @@ -39,22 +39,22 @@ public MCDiscreteArithmeticASEngine( int maxSamples, ulong seed) : base(process, 1, brownianBridge, antitheticVariate, false, - requiredSamples, requiredTolerance, maxSamples, seed) + requiredSamples, requiredTolerance, maxSamples, seed) { } protected override PathPricer pathPricer() { - PlainVanillaPayoff payoff = (PlainVanillaPayoff) (this.arguments_.payoff); + PlainVanillaPayoff payoff = (PlainVanillaPayoff)(this.arguments_.payoff); Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); EuropeanExercise exercise = (EuropeanExercise) this.arguments_.exercise; Utils.QL_REQUIRE(exercise != null, () => "wrong exercise given"); return (PathPricer) new ArithmeticASOPathPricer( - payoff.optionType(), - this.process_.riskFreeRate().link.discount(this.timeGrid().Last()), - this.arguments_.runningAccumulator.GetValueOrDefault(), - this.arguments_.pastFixings.GetValueOrDefault()); + payoff.optionType(), + this.process_.riskFreeRate().link.discount(this.timeGrid().Last()), + this.arguments_.runningAccumulator.GetValueOrDefault(), + this.arguments_.pastFixings.GetValueOrDefault()); } } @@ -66,9 +66,9 @@ public class ArithmeticASOPathPricer : PathPricer private int pastFixings_; public ArithmeticASOPathPricer(Option.Type type, - double discount, - double runningSum, - int pastFixings) + double discount, + double runningSum, + int pastFixings) { type_ = type; discount_ = discount; @@ -77,13 +77,13 @@ public ArithmeticASOPathPricer(Option.Type type, } public ArithmeticASOPathPricer(Option.Type type, - double discount, - double runningSum) + double discount, + double runningSum) : this(type, discount, runningSum, 0) { } public ArithmeticASOPathPricer(Option.Type type, - double discount) + double discount) : this(type, discount, 0.0, 0) { } @@ -112,8 +112,8 @@ public double value(Path path) } public class MakeMCDiscreteArithmeticASEngine - where RNG : IRSG, new() - where S : Statistics, new() + where RNG : IRSG, new () + where S : Statistics, new () { public MakeMCDiscreteArithmeticASEngine(GeneralizedBlackScholesProcess process) { @@ -149,7 +149,7 @@ public MakeMCDiscreteArithmeticASEngine withTolerance(double tolerance) { Utils.QL_REQUIRE(samples_ == null, () => "number of samples already set"); Utils.QL_REQUIRE(FastActivator.Create().allowsErrorEstimate != 0, () => - "chosen random generator policy " + "does not allow an error estimate"); + "chosen random generator policy " + "does not allow an error estimate"); tolerance_ = tolerance; return this; } @@ -181,11 +181,11 @@ public MakeMCDiscreteArithmeticASEngine withAntitheticVariate() public IPricingEngine value() { return new MCDiscreteArithmeticASEngine(process_, - brownianBridge_, - antithetic_, - samples_.Value, tolerance_.Value, - maxSamples_.Value, - seed_); + brownianBridge_, + antithetic_, + samples_.Value, tolerance_.Value, + maxSamples_.Value, + seed_); } private GeneralizedBlackScholesProcess process_; diff --git a/src/QLNet/Pricingengines/asian/mc_discr_geom_av_price.cs b/src/QLNet/Pricingengines/asian/Mc_Discr_Geom_Av_Price.cs similarity index 78% rename from src/QLNet/Pricingengines/asian/mc_discr_geom_av_price.cs rename to src/QLNet/Pricingengines/asian/Mc_Discr_Geom_Av_Price.cs index 203f48233..b2e06ecd5 100644 --- a/src/QLNet/Pricingengines/asian/mc_discr_geom_av_price.cs +++ b/src/QLNet/Pricingengines/asian/Mc_Discr_Geom_Av_Price.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -33,8 +33,8 @@ namespace QLNet /// public class MCDiscreteGeometricAPEngine : MCDiscreteAveragingAsianEngine - where RNG : IRSG, new() - where S : IGeneralStatistics, new() + where RNG : IRSG, new () + where S : IGeneralStatistics, new () { public MCDiscreteGeometricAPEngine( GeneralizedBlackScholesProcess process, @@ -47,25 +47,25 @@ public MCDiscreteGeometricAPEngine( int maxSamples, ulong seed) : base(process, maxTimeStepPerYear, brownianBridge, antitheticVariate, - controlVariate, requiredSamples, requiredTolerance, maxSamples, seed) + controlVariate, requiredSamples, requiredTolerance, maxSamples, seed) { } // conversion to pricing engine protected override PathPricer pathPricer() { - PlainVanillaPayoff payoff = (PlainVanillaPayoff) (this.arguments_.payoff); + PlainVanillaPayoff payoff = (PlainVanillaPayoff)(this.arguments_.payoff); Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); EuropeanExercise exercise = (EuropeanExercise) this.arguments_.exercise; Utils.QL_REQUIRE(exercise != null, () => "wrong exercise given"); return (PathPricer) new GeometricAPOPathPricer( - payoff.optionType(), - payoff.strike(), - this.process_.riskFreeRate().link.discount( - this.timeGrid().Last()), - this.arguments_.runningAccumulator.GetValueOrDefault(), - this.arguments_.pastFixings.GetValueOrDefault()); + payoff.optionType(), + payoff.strike(), + this.process_.riskFreeRate().link.discount( + this.timeGrid().Last()), + this.arguments_.runningAccumulator.GetValueOrDefault(), + this.arguments_.pastFixings.GetValueOrDefault()); } } @@ -77,10 +77,10 @@ public class GeometricAPOPathPricer : PathPricer private int pastFixings_; public GeometricAPOPathPricer(Option.Type type, - double strike, - double discount, - double runningProduct, - int pastFixings) + double strike, + double discount, + double runningProduct, + int pastFixings) { payoff_ = new PlainVanillaPayoff(type, strike); discount_ = discount; @@ -90,15 +90,15 @@ public GeometricAPOPathPricer(Option.Type type, } public GeometricAPOPathPricer(Option.Type type, - double strike, - double discount, - double runningProduct) + double strike, + double discount, + double runningProduct) : this(type, strike, discount, runningProduct, 0) { } public GeometricAPOPathPricer(Option.Type type, - double strike, - double discount) + double strike, + double discount) : this(type, strike, discount, 1.0, 0) { } @@ -138,8 +138,8 @@ public double value(Path path) // public class MakeMCDiscreteGeometricAPEngine - where RNG : IRSG, new() - where S : Statistics, new() + where RNG : IRSG, new () + where S : Statistics, new () { public MakeMCDiscreteGeometricAPEngine(GeneralizedBlackScholesProcess process) { @@ -183,7 +183,7 @@ public MakeMCDiscreteGeometricAPEngine withTolerance(double tolerance) { Utils.QL_REQUIRE(samples_ == null, () => "number of samples already set"); Utils.QL_REQUIRE(FastActivator.Create().allowsErrorEstimate != 0, () => - "chosen random generator policy " + "does not allow an error estimate"); + "chosen random generator policy " + "does not allow an error estimate"); tolerance_ = tolerance; return this; } @@ -227,12 +227,12 @@ public IPricingEngine value() { Utils.QL_REQUIRE(steps_ != null, () => "max number of steps per year not given"); return (IPricingEngine) new MCDiscreteGeometricAPEngine(process_, - steps_.Value, - brownianBridge_, - antithetic_, controlVariate_, - samples_.Value, tolerance_.Value, - maxSamples_.Value, - seed_); + steps_.Value, + brownianBridge_, + antithetic_, controlVariate_, + samples_.Value, tolerance_.Value, + maxSamples_.Value, + seed_); } private GeneralizedBlackScholesProcess process_; diff --git a/src/QLNet/Pricingengines/asian/mc_discr_arith_av_price.cs b/src/QLNet/Pricingengines/asian/mc_discr_arith_av_price.cs deleted file mode 100644 index de0367f0c..000000000 --- a/src/QLNet/Pricingengines/asian/mc_discr_arith_av_price.cs +++ /dev/null @@ -1,255 +0,0 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -namespace QLNet -{ - //! Monte Carlo pricing engine for discrete arithmetic average price Asian - /*! Monte Carlo pricing engine for discrete arithmetic average price - Asian options. It can use MCDiscreteGeometricAPEngine (Monte Carlo - discrete arithmetic average price engine) and - AnalyticDiscreteGeometricAveragePriceAsianEngine (analytic discrete - arithmetic average price engine) for control variation. - - \ingroup asianengines - - \test the correctness of the returned value is tested by - reproducing results available in literature. - */ - //template - public class MCDiscreteArithmeticAPEngine - : MCDiscreteAveragingAsianEngine - where RNG : IRSG, new() - where S : IGeneralStatistics, new() - { - - // constructor - public MCDiscreteArithmeticAPEngine( - GeneralizedBlackScholesProcess process, - int maxTimeStepPerYear, - bool brownianBridge, - bool antitheticVariate, - bool controlVariate, - int requiredSamples, - double requiredTolerance, - int maxSamples, - ulong seed) - : base(process, maxTimeStepPerYear, brownianBridge, antitheticVariate, - controlVariate, requiredSamples, requiredTolerance, maxSamples, seed) - { - } - - protected override PathPricer pathPricer() - { - PlainVanillaPayoff payoff = (PlainVanillaPayoff)(this.arguments_.payoff); - Utils.QL_REQUIRE(payoff != null,()=> "non-plain payoff given"); - - EuropeanExercise exercise = (EuropeanExercise)this.arguments_.exercise; - Utils.QL_REQUIRE(exercise != null,()=> "wrong exercise given"); - - return (PathPricer)new ArithmeticAPOPathPricer( - payoff.optionType(), - payoff.strike(), - this.process_.riskFreeRate().link.discount(this.timeGrid().Last()), - this.arguments_.runningAccumulator.GetValueOrDefault(), - this.arguments_.pastFixings.GetValueOrDefault()); - } - - protected override PathPricer controlPathPricer() - { - PlainVanillaPayoff payoff = (PlainVanillaPayoff)this.arguments_.payoff; - Utils.QL_REQUIRE(payoff != null,()=> "non-plain payoff given"); - - EuropeanExercise exercise = (EuropeanExercise)this.arguments_.exercise; - Utils.QL_REQUIRE(exercise != null,()=> "wrong exercise given"); - - // for seasoned option the geometric strike might be rescaled - // to obtain an equivalent arithmetic strike. - // Any change applied here MUST be applied to the analytic engine too - return (PathPricer)new GeometricAPOPathPricer( - payoff.optionType(), - payoff.strike(), - this.process_.riskFreeRate().link.discount(this.timeGrid().Last())); - } - - protected override IPricingEngine controlPricingEngine() { - return new AnalyticDiscreteGeometricAveragePriceAsianEngine(this.process_); - } - } - - public class ArithmeticAPOPathPricer : PathPricer - { - - private PlainVanillaPayoff payoff_; - private double discount_; - private double runningSum_; - private int pastFixings_; - - public ArithmeticAPOPathPricer(Option.Type type, - double strike, - double discount, - double runningSum, - int pastFixings ) - { - payoff_=new PlainVanillaPayoff(type, strike); - discount_ = discount; - runningSum_ = runningSum; - pastFixings_ = pastFixings; - Utils.QL_REQUIRE(strike>=0.0,()=> "strike less than zero not allowed"); - } - - public ArithmeticAPOPathPricer(Option.Type type, - double strike, - double discount, - double runningSum) - : this(type, strike, discount, runningSum, 0) { } - - public ArithmeticAPOPathPricer(Option.Type type, - double strike, - double discount) - : this(type, strike, discount, 0.0, 0) { } - - - public double value(Path path) - { - int n = path.length(); - Utils.QL_REQUIRE(n>1,()=> "the path cannot be empty"); - - double sum = runningSum_; - int fixings; - if (path.timeGrid().mandatoryTimes()[0].IsEqual(0.0)) { - // include initial fixing - for(int i=0;i 0, () => "the path cannot be empty" ); - return payoff_.value(((Path) path).back()) * discount_; - } - } - // - public class MakeMCDiscreteArithmeticAPEngine - where RNG : IRSG, new() - where S : Statistics, new() - { - public MakeMCDiscreteArithmeticAPEngine(GeneralizedBlackScholesProcess process) - { - process_ = process; - antithetic_ = false; - controlVariate_ = false; - steps_= null; - samples_ = null; - maxSamples_ = null; - tolerance_ = null; - brownianBridge_ = true; - seed_ = 0; - } - - // named parameters - public MakeMCDiscreteArithmeticAPEngine withStepsPerYear(int maxSteps){ - steps_ = maxSteps; - return this; - } - - public MakeMCDiscreteArithmeticAPEngine withBrownianBridge(bool b){ - brownianBridge_ = b; - return this; - } - - public MakeMCDiscreteArithmeticAPEngine withBrownianBridge(){ - return withBrownianBridge(true); - } - - public MakeMCDiscreteArithmeticAPEngine withSamples(int samples){ - Utils.QL_REQUIRE( tolerance_ == null, () => "tolerance already set" ); - samples_ = samples; - return this; - } - - public MakeMCDiscreteArithmeticAPEngine withTolerance(double tolerance) - { - Utils.QL_REQUIRE( samples_ == null, () => "number of samples already set" ); - Utils.QL_REQUIRE(FastActivator.Create().allowsErrorEstimate != 0,()=> - "chosen random generator policy does not allow an error estimate"); - tolerance_ = tolerance; - return this; - } - - public MakeMCDiscreteArithmeticAPEngine withMaxSamples(int samples){ - maxSamples_ = samples; - return this; - } - - public MakeMCDiscreteArithmeticAPEngine withSeed(ulong seed){ - seed_ = seed; - return this; - } - - public MakeMCDiscreteArithmeticAPEngine withAntitheticVariate(bool b){ - antithetic_ = b; - return this; - } - - public MakeMCDiscreteArithmeticAPEngine withAntitheticVariate(){ - return this.withAntitheticVariate(true); - } - - public MakeMCDiscreteArithmeticAPEngine withControlVariate(bool b){ - controlVariate_ = b; - return this; - } - - public MakeMCDiscreteArithmeticAPEngine withControlVariate(){ - return this.withControlVariate(true); - } - - - // conversion to pricing engine - public IPricingEngine value() - { - Utils.QL_REQUIRE(steps_ != null,()=> "max number of steps per year not given"); - return (IPricingEngine)new MCDiscreteArithmeticAPEngine(process_, - steps_.Value, - brownianBridge_, - antithetic_, controlVariate_, - samples_.Value, tolerance_.Value, - maxSamples_.Value, - seed_); - - } - - private GeneralizedBlackScholesProcess process_; - private bool antithetic_, controlVariate_; - private int? steps_, samples_, maxSamples_; - private double? tolerance_; - private bool brownianBridge_; - private ulong seed_; - } - -} diff --git a/src/QLNet/Pricingengines/asian/mcdiscreteasianengine.cs b/src/QLNet/Pricingengines/asian/mcdiscreteasianengine.cs deleted file mode 100644 index 5e8264b02..000000000 --- a/src/QLNet/Pricingengines/asian/mcdiscreteasianengine.cs +++ /dev/null @@ -1,148 +0,0 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System.Collections.Generic; -using System.Linq; - -namespace QLNet -{ - //! Pricing engine for discrete average Asians using Monte Carlo simulation - /*! \warning control-variate calculation is disabled under VC++6. - - \ingroup asianengines - */ - - public class MCDiscreteAveragingAsianEngine : McSimulation, IGenericEngine - //DiscreteAveragingAsianOption.Engine, - //McSimulation - where RNG : IRSG, new() - where S : IGeneralStatistics, new() - { - // data members - protected GeneralizedBlackScholesProcess process_; - protected int maxTimeStepsPerYear_; - protected int requiredSamples_, maxSamples_; - double requiredTolerance_; - bool brownianBridge_; - ulong seed_; - - // constructor - public MCDiscreteAveragingAsianEngine( - GeneralizedBlackScholesProcess process, - int maxTimeStepsPerYear, - bool brownianBridge, - bool antitheticVariate, - bool controlVariate, - int requiredSamples, - double requiredTolerance, - int maxSamples, - ulong seed) : base(antitheticVariate, controlVariate) - { - process_=process; - maxTimeStepsPerYear_ = maxTimeStepsPerYear; - requiredSamples_=requiredSamples; - maxSamples_ = maxSamples; - requiredTolerance_=requiredTolerance; - brownianBridge_ = brownianBridge; - seed_=seed; - process_.registerWith(update); - } - - public void calculate() { - base.calculate(requiredTolerance_,requiredSamples_,maxSamples_); - results_.value = this.mcModel_.sampleAccumulator().mean(); - if (FastActivator.Create().allowsErrorEstimate!=0) - results_.errorEstimate = - this.mcModel_.sampleAccumulator().errorEstimate(); - } - - // McSimulation implementation - protected override TimeGrid timeGrid() { - Date referenceDate = process_.riskFreeRate().link.referenceDate(); - DayCounter voldc = process_.blackVolatility().link.dayCounter() ; - List fixingTimes = new InitializedList(arguments_.fixingDates.Count); - - for (int i=0; i=referenceDate) { - double t = voldc.yearFraction(referenceDate, - arguments_.fixingDates[i]); - fixingTimes.Add( t); - } - } - // handle here maxStepsPerYear - return new TimeGrid(fixingTimes.Last(), fixingTimes.Count); - } - - protected override IPathGenerator pathGenerator() { - - TimeGrid grid = this.timeGrid(); - IRNG gen = (IRNG)new RNG().make_sequence_generator(grid.size()-1,seed_); - return new PathGenerator(process_, grid, - gen, brownianBridge_); - } - - protected override double? controlVariateValue() { - IPricingEngine controlPE = this.controlPricingEngine(); - Utils.QL_REQUIRE(controlPE!=null,()=> "engine does not provide control variation pricing engine"); - - DiscreteAveragingAsianOption.Arguments controlArguments = - (DiscreteAveragingAsianOption.Arguments)controlPE.getArguments(); - controlArguments = arguments_; - controlPE.calculate(); - - DiscreteAveragingAsianOption.Results controlResults = - (DiscreteAveragingAsianOption.Results)(controlPE.getResults()); - - return controlResults.value; - - } - - protected override PathPricer pathPricer() { - throw new System.NotImplementedException(); - } - - #region PricingEngine - protected DiscreteAveragingAsianOption.Arguments arguments_ = new DiscreteAveragingAsianOption.Arguments(); - protected DiscreteAveragingAsianOption.Results results_ = new DiscreteAveragingAsianOption.Results(); - - public IPricingEngineArguments getArguments() { return arguments_; } - public IPricingEngineResults getResults() { return results_; } - public void reset() { results_.reset(); } - - #region Observer & Observable - // observable interface - private readonly WeakEventSource eventSource = new WeakEventSource(); - public event Callback notifyObserversEvent - { - add { eventSource.Subscribe(value); } - remove { eventSource.Unsubscribe(value); } - } - - public void registerWith(Callback handler) { notifyObserversEvent += handler; } - public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } - protected void notifyObservers() - { - eventSource.Raise(); - } - - public void update() { notifyObservers(); } - #endregion - #endregion - } -} diff --git a/src/QLNet/Pricingengines/barrier/AnalyticBarrierEngine.cs b/src/QLNet/Pricingengines/barrier/AnalyticBarrierEngine.cs index 622672f04..087775f7a 100644 --- a/src/QLNet/Pricingengines/barrier/AnalyticBarrierEngine.cs +++ b/src/QLNet/Pricingengines/barrier/AnalyticBarrierEngine.cs @@ -1,26 +1,27 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { +namespace QLNet +{ - //! Pricing Engine for barrier options using analytical formulae + //! Pricing Engine for barrier options using analytical formulae // ! The formulas are taken from "Option pricing formulas", // E.G. Haug, McGraw-Hill, p.69 and following. // @@ -28,226 +29,226 @@ namespace QLNet { // // \test the correctness of the returned value is tested by // reproducing results available in literature. -// - public class AnalyticBarrierEngine : BarrierOption.Engine - { - public AnalyticBarrierEngine(GeneralizedBlackScholesProcess process) - { - process_ = process; +// + public class AnalyticBarrierEngine : BarrierOption.Engine + { + public AnalyticBarrierEngine(GeneralizedBlackScholesProcess process) + { + process_ = process; process_.registerWith(update); - } - public override void calculate() - { - - PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; - - Utils.QL_REQUIRE(payoff != null,()=> "non-plain payoff given"); - Utils.QL_REQUIRE(payoff.strike()>0.0,()=> "strike must be positive"); - - double strike = payoff.strike(); - double spot = process_.x0(); - - Utils.QL_REQUIRE(spot >= 0.0,()=> "negative or null underlying given"); - Utils.QL_REQUIRE(!triggered(spot),()=> "barrier touched"); - - Barrier.Type barrierType = arguments_.barrierType; - - switch (payoff.optionType()) - { - case Option.Type.Call: - switch (barrierType) - { - case Barrier.Type.DownIn: - if (strike >= barrier()) - results_.value = C(1, 1) + E(1); - else - results_.value = A(1) - B(1) + D(1, 1) + E(1); - break; - case Barrier.Type.UpIn: - if (strike >= barrier()) - results_.value = A(1) + E(-1); - else - results_.value = B(1) - C(-1, 1) + D(-1, 1) + E(-1); - break; - case Barrier.Type.DownOut: - if (strike >= barrier()) - results_.value = A(1) - C(1, 1) + F(1); - else - results_.value = B(1) - D(1, 1) + F(1); - break; - case Barrier.Type.UpOut: - if (strike >= barrier()) - results_.value = F(-1); - else - results_.value = A(1) - B(1) + C(-1, 1) - D(-1, 1) + F(-1); - break; - } - break; - case Option.Type.Put: - switch (barrierType) - { - case Barrier.Type.DownIn: - if (strike >= barrier()) - results_.value = B(-1) - C(1, -1) + D(1, -1) + E(1); - else - results_.value = A(-1) + E(1); - break; - case Barrier.Type.UpIn: - if (strike >= barrier()) - results_.value = A(-1) - B(-1) + D(-1, -1) + E(-1); - else - results_.value = C(-1, -1) + E(-1); - break; - case Barrier.Type.DownOut: - if (strike >= barrier()) - results_.value = A(-1) - B(-1) + C(1, -1) - D(1, -1) + F(1); - else - results_.value = F(1); - break; - case Barrier.Type.UpOut: - if (strike >= barrier()) - results_.value = B(-1) - D(-1, -1) + F(-1); - else - results_.value = A(-1) - C(-1, -1) + F(-1); - break; - } - break; - default: - Utils.QL_FAIL("unknown type"); - break; - } - } - private GeneralizedBlackScholesProcess process_; - private CumulativeNormalDistribution f_ = new CumulativeNormalDistribution(); - - private double underlying() - { - return process_.x0(); - } - - private double strike() - { + } + public override void calculate() + { + PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; - Utils.QL_REQUIRE(payoff != null,()=> "non-plain payoff given"); - return payoff.strike(); - } - private double residualTime() - { - return process_.time(arguments_.exercise.lastDate()); - } - private double volatility() - { - return process_.blackVolatility().link.blackVol(residualTime(), strike()); - } - private double barrier() - { - return arguments_.barrier.GetValueOrDefault(); - } - private double rebate() - { - return arguments_.rebate.GetValueOrDefault(); - } - private double stdDeviation() - { - return volatility() * Math.Sqrt(residualTime()); - } - private double riskFreeRate() - { - return process_.riskFreeRate().link.zeroRate(residualTime(), Compounding.Continuous, Frequency.NoFrequency).rate(); - } - private double riskFreeDiscount() - { - return process_.riskFreeRate().link.discount(residualTime()); - } - private double dividendYield() - { - return process_.dividendYield().link.zeroRate(residualTime(), Compounding.Continuous, Frequency.NoFrequency).rate(); - } - private double dividendDiscount() - { - return process_.dividendYield().link.discount(residualTime()); - } - private double mu() - { - double vol = volatility(); - return (riskFreeRate() - dividendYield())/(vol * vol) - 0.5; - } - private double muSigma() - { - return (1 + mu()) * stdDeviation(); - } - private double A(double phi) - { - double x1 = Math.Log(underlying()/strike())/stdDeviation() + muSigma(); - double N1 = f_.value(phi *x1); - double N2 = f_.value(phi * (x1 - stdDeviation())); - return phi*(underlying() * dividendDiscount() * N1 - strike() * riskFreeDiscount() * N2); - } - private double B(double phi) - { - double x2 = Math.Log(underlying()/barrier())/stdDeviation() + muSigma(); - double N1 = f_.value(phi * x2); - double N2 = f_.value(phi * (x2 - stdDeviation())); - return phi*(underlying() * dividendDiscount() * N1 - strike() * riskFreeDiscount() * N2); - } - private double C(double eta, double phi) - { - double HS = barrier()/underlying(); - double powHS0 = Math.Pow(HS, 2 * mu()); - double powHS1 = powHS0 * HS * HS; - double y1 = Math.Log(barrier()*HS/strike())/stdDeviation() + muSigma(); - double N1 = f_.value(eta * y1); - double N2 = f_.value(eta * (y1 - stdDeviation())); - return phi*(underlying() * dividendDiscount() * powHS1 * N1 - strike() * riskFreeDiscount() * powHS0 * N2); - } - private double D(double eta, double phi) - { - double HS = barrier()/underlying(); - double powHS0 = Math.Pow(HS, 2 * mu()); - double powHS1 = powHS0 * HS * HS; - double y2 = Math.Log(barrier()/underlying())/stdDeviation() + muSigma(); - double N1 = f_.value(eta * y2); + + Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); + Utils.QL_REQUIRE(payoff.strike() > 0.0, () => "strike must be positive"); + + double strike = payoff.strike(); + double spot = process_.x0(); + + Utils.QL_REQUIRE(spot >= 0.0, () => "negative or null underlying given"); + Utils.QL_REQUIRE(!triggered(spot), () => "barrier touched"); + + Barrier.Type barrierType = arguments_.barrierType; + + switch (payoff.optionType()) + { + case Option.Type.Call: + switch (barrierType) + { + case Barrier.Type.DownIn: + if (strike >= barrier()) + results_.value = C(1, 1) + E(1); + else + results_.value = A(1) - B(1) + D(1, 1) + E(1); + break; + case Barrier.Type.UpIn: + if (strike >= barrier()) + results_.value = A(1) + E(-1); + else + results_.value = B(1) - C(-1, 1) + D(-1, 1) + E(-1); + break; + case Barrier.Type.DownOut: + if (strike >= barrier()) + results_.value = A(1) - C(1, 1) + F(1); + else + results_.value = B(1) - D(1, 1) + F(1); + break; + case Barrier.Type.UpOut: + if (strike >= barrier()) + results_.value = F(-1); + else + results_.value = A(1) - B(1) + C(-1, 1) - D(-1, 1) + F(-1); + break; + } + break; + case Option.Type.Put: + switch (barrierType) + { + case Barrier.Type.DownIn: + if (strike >= barrier()) + results_.value = B(-1) - C(1, -1) + D(1, -1) + E(1); + else + results_.value = A(-1) + E(1); + break; + case Barrier.Type.UpIn: + if (strike >= barrier()) + results_.value = A(-1) - B(-1) + D(-1, -1) + E(-1); + else + results_.value = C(-1, -1) + E(-1); + break; + case Barrier.Type.DownOut: + if (strike >= barrier()) + results_.value = A(-1) - B(-1) + C(1, -1) - D(1, -1) + F(1); + else + results_.value = F(1); + break; + case Barrier.Type.UpOut: + if (strike >= barrier()) + results_.value = B(-1) - D(-1, -1) + F(-1); + else + results_.value = A(-1) - C(-1, -1) + F(-1); + break; + } + break; + default: + Utils.QL_FAIL("unknown type"); + break; + } + } + private GeneralizedBlackScholesProcess process_; + private CumulativeNormalDistribution f_ = new CumulativeNormalDistribution(); + + private double underlying() + { + return process_.x0(); + } + + private double strike() + { + PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; + Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); + return payoff.strike(); + } + private double residualTime() + { + return process_.time(arguments_.exercise.lastDate()); + } + private double volatility() + { + return process_.blackVolatility().link.blackVol(residualTime(), strike()); + } + private double barrier() + { + return arguments_.barrier.GetValueOrDefault(); + } + private double rebate() + { + return arguments_.rebate.GetValueOrDefault(); + } + private double stdDeviation() + { + return volatility() * Math.Sqrt(residualTime()); + } + private double riskFreeRate() + { + return process_.riskFreeRate().link.zeroRate(residualTime(), Compounding.Continuous, Frequency.NoFrequency).rate(); + } + private double riskFreeDiscount() + { + return process_.riskFreeRate().link.discount(residualTime()); + } + private double dividendYield() + { + return process_.dividendYield().link.zeroRate(residualTime(), Compounding.Continuous, Frequency.NoFrequency).rate(); + } + private double dividendDiscount() + { + return process_.dividendYield().link.discount(residualTime()); + } + private double mu() + { + double vol = volatility(); + return (riskFreeRate() - dividendYield()) / (vol * vol) - 0.5; + } + private double muSigma() + { + return (1 + mu()) * stdDeviation(); + } + private double A(double phi) + { + double x1 = Math.Log(underlying() / strike()) / stdDeviation() + muSigma(); + double N1 = f_.value(phi * x1); + double N2 = f_.value(phi * (x1 - stdDeviation())); + return phi * (underlying() * dividendDiscount() * N1 - strike() * riskFreeDiscount() * N2); + } + private double B(double phi) + { + double x2 = Math.Log(underlying() / barrier()) / stdDeviation() + muSigma(); + double N1 = f_.value(phi * x2); + double N2 = f_.value(phi * (x2 - stdDeviation())); + return phi * (underlying() * dividendDiscount() * N1 - strike() * riskFreeDiscount() * N2); + } + private double C(double eta, double phi) + { + double HS = barrier() / underlying(); + double powHS0 = Math.Pow(HS, 2 * mu()); + double powHS1 = powHS0 * HS * HS; + double y1 = Math.Log(barrier() * HS / strike()) / stdDeviation() + muSigma(); + double N1 = f_.value(eta * y1); + double N2 = f_.value(eta * (y1 - stdDeviation())); + return phi * (underlying() * dividendDiscount() * powHS1 * N1 - strike() * riskFreeDiscount() * powHS0 * N2); + } + private double D(double eta, double phi) + { + double HS = barrier() / underlying(); + double powHS0 = Math.Pow(HS, 2 * mu()); + double powHS1 = powHS0 * HS * HS; + double y2 = Math.Log(barrier() / underlying()) / stdDeviation() + muSigma(); + double N1 = f_.value(eta * y2); + double N2 = f_.value(eta * (y2 - stdDeviation())); + return phi * (underlying() * dividendDiscount() * powHS1 * N1 - strike() * riskFreeDiscount() * powHS0 * N2); + } + private double E(double eta) + { + if (rebate() > 0) + { + double powHS0 = Math.Pow(barrier() / underlying(), 2 * mu()); + double x2 = Math.Log(underlying() / barrier()) / stdDeviation() + muSigma(); + double y2 = Math.Log(barrier() / underlying()) / stdDeviation() + muSigma(); + double N1 = f_.value(eta * (x2 - stdDeviation())); double N2 = f_.value(eta * (y2 - stdDeviation())); - return phi*(underlying() * dividendDiscount() * powHS1 * N1 - strike() * riskFreeDiscount() * powHS0 * N2); - } - private double E(double eta) - { - if (rebate() > 0) - { - double powHS0 = Math.Pow(barrier()/underlying(), 2 * mu()); - double x2 = Math.Log(underlying()/barrier())/stdDeviation() + muSigma(); - double y2 = Math.Log(barrier()/underlying())/stdDeviation() + muSigma(); - double N1 = f_.value(eta * (x2 - stdDeviation())); - double N2 = f_.value(eta * (y2 - stdDeviation())); - return rebate() * riskFreeDiscount() * (N1 - powHS0 * N2); - } - else - { - return 0.0; - } - } - private double F(double eta) - { - if (rebate() > 0) - { - double m = mu(); - double vol = volatility(); - double lambda = Math.Sqrt(m *m + 2.0 *riskFreeRate()/(vol * vol)); - double HS = barrier()/underlying(); - double powHSplus = Math.Pow(HS, m + lambda); - double powHSminus = Math.Pow(HS, m - lambda); - - double sigmaSqrtT = stdDeviation(); - double z = Math.Log(barrier()/underlying())/sigmaSqrtT + lambda * sigmaSqrtT; - - double N1 = f_.value(eta * z); - double N2 = f_.value(eta * (z - 2.0 * lambda * sigmaSqrtT)); - return rebate() * (powHSplus * N1 + powHSminus * N2); - } - else - { - return 0.0; - } - } - } + return rebate() * riskFreeDiscount() * (N1 - powHS0 * N2); + } + else + { + return 0.0; + } + } + private double F(double eta) + { + if (rebate() > 0) + { + double m = mu(); + double vol = volatility(); + double lambda = Math.Sqrt(m * m + 2.0 * riskFreeRate() / (vol * vol)); + double HS = barrier() / underlying(); + double powHSplus = Math.Pow(HS, m + lambda); + double powHSminus = Math.Pow(HS, m - lambda); + + double sigmaSqrtT = stdDeviation(); + double z = Math.Log(barrier() / underlying()) / sigmaSqrtT + lambda * sigmaSqrtT; + + double N1 = f_.value(eta * z); + double N2 = f_.value(eta * (z - 2.0 * lambda * sigmaSqrtT)); + return rebate() * (powHSplus * N1 + powHSminus * N2); + } + else + { + return 0.0; + } + } + } } \ No newline at end of file diff --git a/src/QLNet/Pricingengines/barrier/AnalyticBinaryBarrierEngine.cs b/src/QLNet/Pricingengines/barrier/AnalyticBinaryBarrierEngine.cs index 1546967ab..96d426cab 100644 --- a/src/QLNet/Pricingengines/barrier/AnalyticBinaryBarrierEngine.cs +++ b/src/QLNet/Pricingengines/barrier/AnalyticBinaryBarrierEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,7 +19,7 @@ namespace QLNet { //! Analytic pricing engine for American binary barriers options /*! The formulas are taken from "The complete guide to option pricing formulas 2nd Ed", - E.G. Haug, McGraw-Hill, p.176 and following. + E.G. Haug, McGraw-Hill, p.176 and following. \ingroup barrierengines @@ -33,7 +33,7 @@ reproducing results available in literature. */ public class AnalyticBinaryBarrierEngine : BarrierOption.Engine { - public AnalyticBinaryBarrierEngine( GeneralizedBlackScholesProcess process) + public AnalyticBinaryBarrierEngine(GeneralizedBlackScholesProcess process) { process_ = process; process_.registerWith(update); @@ -41,25 +41,25 @@ public AnalyticBinaryBarrierEngine( GeneralizedBlackScholesProcess process) public override void calculate() { AmericanExercise ex = arguments_.exercise as AmericanExercise; - Utils.QL_REQUIRE(ex!=null,()=> "non-American exercise given"); - Utils.QL_REQUIRE(ex.payoffAtExpiry(),()=> "payoff must be at expiry"); - Utils.QL_REQUIRE(ex.dates()[0] <= process_.blackVolatility().link.referenceDate(),()=> - "American option with window exercise not handled yet"); + Utils.QL_REQUIRE(ex != null, () => "non-American exercise given"); + Utils.QL_REQUIRE(ex.payoffAtExpiry(), () => "payoff must be at expiry"); + Utils.QL_REQUIRE(ex.dates()[0] <= process_.blackVolatility().link.referenceDate(), () => + "American option with window exercise not handled yet"); StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; - Utils.QL_REQUIRE(payoff!=null,()=> "non-striked payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "non-striked payoff given"); double spot = process_.stateVariable().link.value(); - Utils.QL_REQUIRE(spot > 0.0,()=> "negative or null underlying given"); + Utils.QL_REQUIRE(spot > 0.0, () => "negative or null underlying given"); - double variance = process_.blackVolatility().link.blackVariance(ex.lastDate(),payoff.strike()); + double variance = process_.blackVolatility().link.blackVariance(ex.lastDate(), payoff.strike()); double? barrier = arguments_.barrier; - Utils.QL_REQUIRE(barrier>0.0,()=>"positive barrier value required"); + Utils.QL_REQUIRE(barrier > 0.0, () => "positive barrier value required"); Barrier.Type barrierType = arguments_.barrierType; // KO degenerate cases - if ( (barrierType == Barrier.Type.DownOut && spot <= barrier) || - (barrierType == Barrier.Type.UpOut && spot >= barrier)) + if ((barrierType == Barrier.Type.DownOut && spot <= barrier) || + (barrierType == Barrier.Type.UpOut && spot >= barrier)) { // knocked out, no value results_.value = 0; @@ -74,7 +74,7 @@ public override void calculate() // KI degenerate cases if ((barrierType == Barrier.Type.DownIn && spot <= barrier) || - (barrierType == Barrier.Type.UpIn && spot >= barrier)) + (barrierType == Barrier.Type.UpIn && spot >= barrier)) { // knocked in - is a digital european Exercise exercise = new EuropeanExercise(arguments_.exercise.lastDate()); @@ -95,24 +95,24 @@ public override void calculate() double riskFreeDiscount = process_.riskFreeRate().link.discount(ex.lastDate()); - AnalyticBinaryBarrierEngine_helper helper = new AnalyticBinaryBarrierEngine_helper( - process_, payoff, ex, arguments_ ); + AnalyticBinaryBarrierEngine_helper helper = new AnalyticBinaryBarrierEngine_helper( + process_, payoff, ex, arguments_); results_.value = helper.payoffAtExpiry(spot, variance, riskFreeDiscount); } - + private GeneralizedBlackScholesProcess process_; } - // calc helper object + // calc helper object public class AnalyticBinaryBarrierEngine_helper { - + public AnalyticBinaryBarrierEngine_helper( - GeneralizedBlackScholesProcess process, - StrikedTypePayoff payoff, - AmericanExercise exercise, - BarrierOption.Arguments arguments) + GeneralizedBlackScholesProcess process, + StrikedTypePayoff payoff, + AmericanExercise exercise, + BarrierOption.Arguments arguments) { process_ = process; payoff_ = payoff; @@ -124,41 +124,41 @@ public double payoffAtExpiry(double spot, double variance, double discount) { double dividendDiscount = process_.dividendYield().link.discount(exercise_.lastDate()); - Utils.QL_REQUIRE(spot>0.0,()=> "positive spot value required"); - Utils.QL_REQUIRE(discount>0.0,()=> "positive discount required"); - Utils.QL_REQUIRE(dividendDiscount>0.0,()=> "positive dividend discount required"); - Utils.QL_REQUIRE(variance>=0.0,()=> "negative variance not allowed"); + Utils.QL_REQUIRE(spot > 0.0, () => "positive spot value required"); + Utils.QL_REQUIRE(discount > 0.0, () => "positive discount required"); + Utils.QL_REQUIRE(dividendDiscount > 0.0, () => "positive dividend discount required"); + Utils.QL_REQUIRE(variance >= 0.0, () => "negative variance not allowed"); Option.Type type = payoff_.optionType(); double strike = payoff_.strike(); double? barrier = arguments_.barrier; - Utils.QL_REQUIRE(barrier>0.0,()=>"positive barrier value required"); + Utils.QL_REQUIRE(barrier > 0.0, () => "positive barrier value required"); Barrier.Type barrierType = arguments_.barrierType; double stdDev = Math.Sqrt(variance); - double mu = Math.Log(dividendDiscount/discount)/variance - 0.5; + double mu = Math.Log(dividendDiscount / discount) / variance - 0.5; double K = 0; // binary cash-or-nothing payoff? CashOrNothingPayoff coo = payoff_ as CashOrNothingPayoff; - if (coo != null ) + if (coo != null) { K = coo.cashPayoff(); } // binary asset-or-nothing payoff? AssetOrNothingPayoff aoo = payoff_ as AssetOrNothingPayoff; - if (aoo!=null) + if (aoo != null) { - mu += 1.0; + mu += 1.0; K = spot * dividendDiscount / discount; // forward } - double log_S_X = Math.Log(spot/strike); - double log_S_H = Math.Log(spot/barrier.GetValueOrDefault()); - double log_H_S = Math.Log(barrier.GetValueOrDefault()/spot); - double log_H2_SX = Math.Log(barrier.GetValueOrDefault()*barrier.GetValueOrDefault()/(spot*strike)); - double H_S_2mu = Math.Pow(barrier.GetValueOrDefault()/spot, 2*mu); + double log_S_X = Math.Log(spot / strike); + double log_S_H = Math.Log(spot / barrier.GetValueOrDefault()); + double log_H_S = Math.Log(barrier.GetValueOrDefault() / spot); + double log_H2_SX = Math.Log(barrier.GetValueOrDefault() * barrier.GetValueOrDefault() / (spot * strike)); + double H_S_2mu = Math.Pow(barrier.GetValueOrDefault() / spot, 2 * mu); double eta = (barrierType == Barrier.Type.DownIn || barrierType == Barrier.Type.DownOut ? 1.0 : -1.0); @@ -166,70 +166,70 @@ public double payoffAtExpiry(double spot, double variance, double discount) double x1, x2, y1, y2; double cum_x1, cum_x2, cum_y1, cum_y2; - if (variance>=Const.QL_EPSILON) + if (variance >= Const.QL_EPSILON) { // we calculate using mu*stddev instead of (mu+1)*stddev // because cash-or-nothing don't need it. asset-or-nothing // mu is really mu+1 - x1 = phi*(log_S_X/stdDev + mu*stdDev); - x2 = phi*(log_S_H/stdDev + mu*stdDev); - y1 = eta*(log_H2_SX/stdDev + mu*stdDev); - y2 = eta*(log_H_S/stdDev + mu*stdDev); + x1 = phi * (log_S_X / stdDev + mu * stdDev); + x2 = phi * (log_S_H / stdDev + mu * stdDev); + y1 = eta * (log_H2_SX / stdDev + mu * stdDev); + y2 = eta * (log_H_S / stdDev + mu * stdDev); CumulativeNormalDistribution f = new CumulativeNormalDistribution(); cum_x1 = f.value(x1); cum_x2 = f.value(x2); cum_y1 = f.value(y1); cum_y2 = f.value(y2); - } - else + } + else { - if (log_S_X>0) - cum_x1= 1.0; + if (log_S_X > 0) + cum_x1 = 1.0; else - cum_x1= 0.0; - if (log_S_H>0) - cum_x2= 1.0; + cum_x1 = 0.0; + if (log_S_H > 0) + cum_x2 = 1.0; else - cum_x2= 0.0; - if (log_H2_SX>0) - cum_y1= 1.0; + cum_x2 = 0.0; + if (log_H2_SX > 0) + cum_y1 = 1.0; else - cum_y1= 0.0; - if (log_H_S>0) - cum_y2= 1.0; + cum_y1 = 0.0; + if (log_H_S > 0) + cum_y2 = 1.0; else - cum_y2= 0.0; + cum_y2 = 0.0; } double alpha = 0; - switch (barrierType) + switch (barrierType) { case Barrier.Type.DownIn: - if (type == Option.Type.Call) + if (type == Option.Type.Call) { // down-in and call - if (strike >= barrier) + if (strike >= barrier) { // B3 (eta=1, phi=1) - alpha = H_S_2mu * cum_y1; - } - else + alpha = H_S_2mu * cum_y1; + } + else { // B1-B2+B4 (eta=1, phi=1) - alpha = cum_x1 - cum_x2 + H_S_2mu * cum_y2; + alpha = cum_x1 - cum_x2 + H_S_2mu * cum_y2; } } - else + else { - // down-in and put - if (strike >= barrier) + // down-in and put + if (strike >= barrier) { // B2-B3+B4 (eta=1, phi=-1) - alpha = cum_x2 + H_S_2mu*(-cum_y1 + cum_y2); - } - else + alpha = cum_x2 + H_S_2mu * (-cum_y1 + cum_y2); + } + else { // B1 (eta=1, phi=-1) alpha = cum_x1; @@ -238,90 +238,90 @@ public double payoffAtExpiry(double spot, double variance, double discount) break; case Barrier.Type.UpIn: - if (type == Option.Type.Call) + if (type == Option.Type.Call) { // up-in and call - if (strike >= barrier) + if (strike >= barrier) { // B1 (eta=-1, phi=1) - alpha = cum_x1; - } - else + alpha = cum_x1; + } + else { // B2-B3+B4 (eta=-1, phi=1) alpha = cum_x2 + H_S_2mu * (-cum_y1 + cum_y2); } } - else + else { - // up-in and put - if (strike >= barrier) + // up-in and put + if (strike >= barrier) { // B1-B2+B4 (eta=-1, phi=-1) alpha = cum_x1 - cum_x2 + H_S_2mu * cum_y2; - } - else + } + else { // B3 (eta=-1, phi=-1) - alpha = H_S_2mu * cum_y1; + alpha = H_S_2mu * cum_y1; } } break; case Barrier.Type.DownOut: - if (type == Option.Type.Call) + if (type == Option.Type.Call) { // down-out and call - if (strike >= barrier) + if (strike >= barrier) { // B1-B3 (eta=1, phi=1) - alpha = cum_x1 - H_S_2mu * cum_y1; - } - else + alpha = cum_x1 - H_S_2mu * cum_y1; + } + else { // B2-B4 (eta=1, phi=1) - alpha = cum_x2 - H_S_2mu * cum_y2; + alpha = cum_x2 - H_S_2mu * cum_y2; } } - else + else { - // down-out and put - if (strike >= barrier) + // down-out and put + if (strike >= barrier) { // B1-B2+B3-B4 (eta=1, phi=-1) - alpha = cum_x1 - cum_x2 + H_S_2mu * (cum_y1-cum_y2); - } - else + alpha = cum_x1 - cum_x2 + H_S_2mu * (cum_y1 - cum_y2); + } + else { // always 0 - alpha = 0; + alpha = 0; } } break; case Barrier.Type.UpOut: - if (type == Option.Type.Call) + if (type == Option.Type.Call) { // up-out and call - if (strike >= barrier) + if (strike >= barrier) { // always 0 - alpha = 0; - } - else + alpha = 0; + } + else { // B1-B2+B3-B4 (eta=-1, phi=1) - alpha = cum_x1 - cum_x2 + H_S_2mu * (cum_y1-cum_y2); + alpha = cum_x1 - cum_x2 + H_S_2mu * (cum_y1 - cum_y2); } } - else + else { - // up-out and put - if (strike >= barrier) + // up-out and put + if (strike >= barrier) { // B2-B4 (eta=-1, phi=-1) alpha = cum_x2 - H_S_2mu * cum_y2; - } - else + } + else { // B1-B3 (eta=-1, phi=-1) alpha = cum_x1 - H_S_2mu * cum_y1; @@ -335,10 +335,10 @@ public double payoffAtExpiry(double spot, double variance, double discount) return discount * K * alpha; } - + private GeneralizedBlackScholesProcess process_; private StrikedTypePayoff payoff_; private AmericanExercise exercise_; private BarrierOption.Arguments arguments_; - } + } } diff --git a/src/QLNet/Pricingengines/barrier/AnalyticDoubleBarrierBinaryEngine.cs b/src/QLNet/Pricingengines/barrier/AnalyticDoubleBarrierBinaryEngine.cs index 81356a9f6..1c32add33 100644 --- a/src/QLNet/Pricingengines/barrier/AnalyticDoubleBarrierBinaryEngine.cs +++ b/src/QLNet/Pricingengines/barrier/AnalyticDoubleBarrierBinaryEngine.cs @@ -1,21 +1,21 @@ -/* - Copyright (C) 2015 Thema Consulting SA - Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. +/* + Copyright (C) 2015 Thema Consulting SA + Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; @@ -24,299 +24,300 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! Analytic pricing engine for double barrier binary options - /*! This engine implements C.H.Hui series ("One-Touch Double Barrier - Binary Option Values", Applied Financial Economics 6/1996), as - described in "The complete guide to option pricing formulas 2nd Ed", - E.G. Haug, McGraw-Hill, p.180 - - The Knock In part of KI+KO and KO+KI options pays at hit, while the - Double Knock In pays at end. - This engine thus requires European esercise for Double Knock options, - and American exercise for KIKO/KOKI. - - \ingroup barrierengines - - greeks are calculated by simple numeric derivation - - \test - - the correctness of the returned value is tested by reproducing - results available in literature. - */ - - // calc helper object - public class AnalyticDoubleBarrierBinaryEngineHelper - { - public AnalyticDoubleBarrierBinaryEngineHelper( - GeneralizedBlackScholesProcess process, - CashOrNothingPayoff payoff, - DoubleBarrierOption.Arguments arguments) - { - process_ = process; - payoff_ = payoff; - arguments_ = arguments; - } - - // helper object methods - public double payoffAtExpiry(double spot, double variance, - DoubleBarrier.Type barrierType, - int maxIteration = 100, - double requiredConvergence = 1e-8) - { - Utils.QL_REQUIRE(spot>0.0, - () => "positive spot value required"); - - Utils.QL_REQUIRE(variance>=0.0, - () => "negative variance not allowed"); - - double residualTime = process_.time(arguments_.exercise.lastDate()); - Utils.QL_REQUIRE(residualTime>0.0, - () => "expiration time must be > 0"); - - // Option::Type type = payoff_->optionType(); // this is not used ? - double cash = payoff_.cashPayoff(); - double barrier_lo = arguments_.barrier_lo.Value; - double barrier_hi = arguments_.barrier_hi.Value; - - double sigmaq = variance/residualTime; - double r = process_.riskFreeRate().currentLink().zeroRate(residualTime, Compounding.Continuous, - Frequency.NoFrequency).rate(); - double q = process_.dividendYield().currentLink().zeroRate(residualTime, - Compounding.Continuous, Frequency.NoFrequency).rate(); - double b = r - q; - - double alpha = -0.5 * ( 2*b/sigmaq - 1); - double beta = -0.25 * Math.Pow(( 2*b/sigmaq - 1), 2) - 2 * r/sigmaq; - double Z = Math.Log(barrier_hi / barrier_lo); - double factor = ((2*Const.M_PI*cash)/Math.Pow(Z,2)); // common factor - double lo_alpha = Math.Pow(spot/barrier_lo, alpha); - double hi_alpha = Math.Pow(spot/barrier_hi, alpha); - - double tot = 0, term = 0; - for (int i = 1 ; i < maxIteration ; ++i) - { - double term1 = (lo_alpha-Math.Pow(-1.0, i)*hi_alpha) / - (Math.Pow(alpha,2)+Math.Pow(i*Const.M_PI/Z, 2)); - double term2 = Math.Sin(i*Const.M_PI/Z * Math.Log(spot/barrier_lo)); - double term3 = Math.Exp(-0.5*(Math.Pow(i*Const.M_PI/Z,2)-beta)*variance); - term = factor * i * term1 * term2 * term3; - tot += term; - } - - // Check if convergence is sufficiently fast (for extreme parameters with big alpha the convergence can be very - // poor, see for example Hui "One-touch double barrier binary option value") - Utils.QL_REQUIRE(Math.Abs(term) < requiredConvergence, () => "serie did not converge sufficiently fast"); - - if (barrierType == DoubleBarrier.Type.KnockOut) - return Math.Max(tot, 0.0); // KO - else { - double discount = process_.riskFreeRate().currentLink().discount( - arguments_.exercise.lastDate()); - Utils.QL_REQUIRE(discount>0.0, - () => "positive discount required"); - return Math.Max(cash * discount - tot, 0.0); // KI - } - } - // helper object methods - public double payoffKIKO(double spot, double variance, - DoubleBarrier.Type barrierType, - int maxIteration = 1000, - double requiredConvergence = 1e-8) - { - Utils.QL_REQUIRE(spot>0.0, - () => "positive spot value required"); - - Utils.QL_REQUIRE(variance>=0.0, - () => "negative variance not allowed"); - - double residualTime = process_.time(arguments_.exercise.lastDate()); - Utils.QL_REQUIRE(residualTime>0.0, - () => "expiration time must be > 0"); - - double cash = payoff_.cashPayoff(); - double barrier_lo = arguments_.barrier_lo.Value; - double barrier_hi = arguments_.barrier_hi.Value; - if (barrierType == DoubleBarrier.Type.KOKI) - Utils.swap(ref barrier_lo, ref barrier_hi); - - double sigmaq = variance/residualTime; - double r = process_.riskFreeRate().currentLink().zeroRate(residualTime, Compounding.Continuous, - Frequency.NoFrequency).rate(); - double q = process_.dividendYield().currentLink().zeroRate(residualTime, - Compounding.Continuous, Frequency.NoFrequency).rate(); - double b = r - q; - - double alpha = -0.5 * ( 2*b/sigmaq - 1); - double beta = -0.25 * Math.Pow(( 2*b/sigmaq - 1), 2) - 2 * r/sigmaq; - double Z = Math.Log(barrier_hi / barrier_lo); - double log_S_L = Math.Log(spot / barrier_lo); - - double tot = 0, term = 0; - for (int i = 1 ; i < maxIteration ; ++i) - { - double factor = Math.Pow(i*Const.M_PI/Z,2)-beta; - double term1 = (beta - Math.Pow(i * Const.M_PI / Z, 2) * Math.Exp(-0.5 * factor * variance)) / factor; - double term2 = Math.Sin(i * Const.M_PI/Z * log_S_L); - term = (2.0/(i*Const.M_PI)) * term1 * term2; - tot += term; - } - tot += 1 - log_S_L / Z; - tot *= cash*Math.Pow(spot/barrier_lo, alpha); - - // Check if convergence is sufficiently fast - Utils.QL_REQUIRE(Math.Abs(term) < requiredConvergence, () => "serie did not converge sufficiently fast"); - - return Math.Max(tot, 0.0); - } - - protected GeneralizedBlackScholesProcess process_; - protected CashOrNothingPayoff payoff_; - protected DoubleBarrierOption.Arguments arguments_; - } - public class AnalyticDoubleBarrierBinaryEngine : DoubleBarrierOption.Engine - { - public AnalyticDoubleBarrierBinaryEngine(GeneralizedBlackScholesProcess process) - { - process_ = process; - process_.registerWith(update); - } - - public override void calculate() - { - if (arguments_.barrierType == DoubleBarrier.Type.KIKO || - arguments_.barrierType == DoubleBarrier.Type.KOKI) - { - AmericanExercise ex = arguments_.exercise as AmericanExercise; - Utils.QL_REQUIRE(ex != null, () => "KIKO/KOKI options must have American exercise"); - Utils.QL_REQUIRE(ex.dates()[0] <= - process_.blackVolatility().currentLink().referenceDate(), - () => "American option with window exercise not handled yet"); - } - else - { - EuropeanExercise ex = arguments_.exercise as EuropeanExercise; - Utils.QL_REQUIRE(ex != null, () => "non-European exercise given"); - } - CashOrNothingPayoff payoff = arguments_.payoff as CashOrNothingPayoff; - Utils.QL_REQUIRE(payoff != null, () => "a cash-or-nothing payoff must be given"); - - double spot = process_.stateVariable().currentLink().value(); - Utils.QL_REQUIRE(spot > 0.0, () => "negative or null underlying given"); - - double variance = - process_.blackVolatility().currentLink().blackVariance( - arguments_.exercise.lastDate(), - payoff.strike()); - double barrier_lo = arguments_.barrier_lo.Value; - double barrier_hi = arguments_.barrier_hi.Value; - DoubleBarrier.Type barrierType = arguments_.barrierType; - Utils.QL_REQUIRE(barrier_lo > 0.0, - () => "positive low barrier value required"); - Utils.QL_REQUIRE(barrier_hi > 0.0, - () => "positive high barrier value required"); - Utils.QL_REQUIRE(barrier_lo < barrier_hi, - () => "barrier_lo must be < barrier_hi"); - Utils.QL_REQUIRE(barrierType == DoubleBarrier.Type.KnockIn || - barrierType == DoubleBarrier.Type.KnockOut || - barrierType == DoubleBarrier.Type.KIKO || - barrierType == DoubleBarrier.Type.KOKI, - () => "Unsupported barrier type"); - - // degenerate cases - switch (barrierType) - { - case DoubleBarrier.Type.KnockOut: - if (spot <= barrier_lo || spot >= barrier_hi) - { - // knocked out, no value - results_.value = 0; - results_.delta = 0; - results_.gamma = 0; - results_.vega = 0; - results_.rho = 0; - return; - } - break; - - case DoubleBarrier.Type.KnockIn: - if (spot <= barrier_lo || spot >= barrier_hi) - { - // knocked in - pays - results_.value = payoff.cashPayoff(); - results_.delta = 0; - results_.gamma = 0; - results_.vega = 0; - results_.rho = 0; - return; - } - break; - - case DoubleBarrier.Type.KIKO: - if (spot >= barrier_hi) - { - // knocked out, no value - results_.value = 0; - results_.delta = 0; - results_.gamma = 0; - results_.vega = 0; - results_.rho = 0; - return; - } - else if (spot <= barrier_lo) - { - // knocked in, pays - results_.value = payoff.cashPayoff(); - results_.delta = 0; - results_.gamma = 0; - results_.vega = 0; - results_.rho = 0; - return; - } - break; - - case DoubleBarrier.Type.KOKI: - if (spot <= barrier_lo) - { - // knocked out, no value - results_.value = 0; - results_.delta = 0; - results_.gamma = 0; - results_.vega = 0; - results_.rho = 0; - return; - } - else if (spot >= barrier_hi) - { - // knocked in, pays - results_.value = payoff.cashPayoff(); - results_.delta = 0; - results_.gamma = 0; - results_.vega = 0; - results_.rho = 0; - return; - } - break; - } - - AnalyticDoubleBarrierBinaryEngineHelper helper = new AnalyticDoubleBarrierBinaryEngineHelper(process_, - payoff, arguments_); - switch (barrierType) - { - case DoubleBarrier.Type.KnockOut: - case DoubleBarrier.Type.KnockIn: - results_.value = helper.payoffAtExpiry(spot, variance, barrierType); - break; - - case DoubleBarrier.Type.KIKO: - case DoubleBarrier.Type.KOKI: - results_.value = helper.payoffKIKO(spot, variance, barrierType); - break; - default: - results_.value = null; - break; - } - } - - protected GeneralizedBlackScholesProcess process_; - } + //! Analytic pricing engine for double barrier binary options + /*! This engine implements C.H.Hui series ("One-Touch Double Barrier + Binary Option Values", Applied Financial Economics 6/1996), as + described in "The complete guide to option pricing formulas 2nd Ed", + E.G. Haug, McGraw-Hill, p.180 + + The Knock In part of KI+KO and KO+KI options pays at hit, while the + Double Knock In pays at end. + This engine thus requires European esercise for Double Knock options, + and American exercise for KIKO/KOKI. + + \ingroup barrierengines + + greeks are calculated by simple numeric derivation + + \test + - the correctness of the returned value is tested by reproducing + results available in literature. + */ + + // calc helper object + public class AnalyticDoubleBarrierBinaryEngineHelper + { + public AnalyticDoubleBarrierBinaryEngineHelper( + GeneralizedBlackScholesProcess process, + CashOrNothingPayoff payoff, + DoubleBarrierOption.Arguments arguments) + { + process_ = process; + payoff_ = payoff; + arguments_ = arguments; + } + + // helper object methods + public double payoffAtExpiry(double spot, double variance, + DoubleBarrier.Type barrierType, + int maxIteration = 100, + double requiredConvergence = 1e-8) + { + Utils.QL_REQUIRE(spot > 0.0, + () => "positive spot value required"); + + Utils.QL_REQUIRE(variance >= 0.0, + () => "negative variance not allowed"); + + double residualTime = process_.time(arguments_.exercise.lastDate()); + Utils.QL_REQUIRE(residualTime > 0.0, + () => "expiration time must be > 0"); + + // Option::Type type = payoff_->optionType(); // this is not used ? + double cash = payoff_.cashPayoff(); + double barrier_lo = arguments_.barrier_lo.Value; + double barrier_hi = arguments_.barrier_hi.Value; + + double sigmaq = variance / residualTime; + double r = process_.riskFreeRate().currentLink().zeroRate(residualTime, Compounding.Continuous, + Frequency.NoFrequency).rate(); + double q = process_.dividendYield().currentLink().zeroRate(residualTime, + Compounding.Continuous, Frequency.NoFrequency).rate(); + double b = r - q; + + double alpha = -0.5 * (2 * b / sigmaq - 1); + double beta = -0.25 * Math.Pow((2 * b / sigmaq - 1), 2) - 2 * r / sigmaq; + double Z = Math.Log(barrier_hi / barrier_lo); + double factor = ((2 * Const.M_PI * cash) / Math.Pow(Z, 2)); // common factor + double lo_alpha = Math.Pow(spot / barrier_lo, alpha); + double hi_alpha = Math.Pow(spot / barrier_hi, alpha); + + double tot = 0, term = 0; + for (int i = 1 ; i < maxIteration ; ++i) + { + double term1 = (lo_alpha - Math.Pow(-1.0, i) * hi_alpha) / + (Math.Pow(alpha, 2) + Math.Pow(i * Const.M_PI / Z, 2)); + double term2 = Math.Sin(i * Const.M_PI / Z * Math.Log(spot / barrier_lo)); + double term3 = Math.Exp(-0.5 * (Math.Pow(i * Const.M_PI / Z, 2) - beta) * variance); + term = factor * i * term1 * term2 * term3; + tot += term; + } + + // Check if convergence is sufficiently fast (for extreme parameters with big alpha the convergence can be very + // poor, see for example Hui "One-touch double barrier binary option value") + Utils.QL_REQUIRE(Math.Abs(term) < requiredConvergence, () => "serie did not converge sufficiently fast"); + + if (barrierType == DoubleBarrier.Type.KnockOut) + return Math.Max(tot, 0.0); // KO + else + { + double discount = process_.riskFreeRate().currentLink().discount( + arguments_.exercise.lastDate()); + Utils.QL_REQUIRE(discount>0.0, + () => "positive discount required"); + return Math.Max(cash * discount - tot, 0.0); // KI + } + } + // helper object methods + public double payoffKIKO(double spot, double variance, + DoubleBarrier.Type barrierType, + int maxIteration = 1000, + double requiredConvergence = 1e-8) + { + Utils.QL_REQUIRE(spot > 0.0, + () => "positive spot value required"); + + Utils.QL_REQUIRE(variance >= 0.0, + () => "negative variance not allowed"); + + double residualTime = process_.time(arguments_.exercise.lastDate()); + Utils.QL_REQUIRE(residualTime > 0.0, + () => "expiration time must be > 0"); + + double cash = payoff_.cashPayoff(); + double barrier_lo = arguments_.barrier_lo.Value; + double barrier_hi = arguments_.barrier_hi.Value; + if (barrierType == DoubleBarrier.Type.KOKI) + Utils.swap(ref barrier_lo, ref barrier_hi); + + double sigmaq = variance / residualTime; + double r = process_.riskFreeRate().currentLink().zeroRate(residualTime, Compounding.Continuous, + Frequency.NoFrequency).rate(); + double q = process_.dividendYield().currentLink().zeroRate(residualTime, + Compounding.Continuous, Frequency.NoFrequency).rate(); + double b = r - q; + + double alpha = -0.5 * (2 * b / sigmaq - 1); + double beta = -0.25 * Math.Pow((2 * b / sigmaq - 1), 2) - 2 * r / sigmaq; + double Z = Math.Log(barrier_hi / barrier_lo); + double log_S_L = Math.Log(spot / barrier_lo); + + double tot = 0, term = 0; + for (int i = 1 ; i < maxIteration ; ++i) + { + double factor = Math.Pow(i * Const.M_PI / Z, 2) - beta; + double term1 = (beta - Math.Pow(i * Const.M_PI / Z, 2) * Math.Exp(-0.5 * factor * variance)) / factor; + double term2 = Math.Sin(i * Const.M_PI / Z * log_S_L); + term = (2.0 / (i * Const.M_PI)) * term1 * term2; + tot += term; + } + tot += 1 - log_S_L / Z; + tot *= cash * Math.Pow(spot / barrier_lo, alpha); + + // Check if convergence is sufficiently fast + Utils.QL_REQUIRE(Math.Abs(term) < requiredConvergence, () => "serie did not converge sufficiently fast"); + + return Math.Max(tot, 0.0); + } + + protected GeneralizedBlackScholesProcess process_; + protected CashOrNothingPayoff payoff_; + protected DoubleBarrierOption.Arguments arguments_; + } + public class AnalyticDoubleBarrierBinaryEngine : DoubleBarrierOption.Engine + { + public AnalyticDoubleBarrierBinaryEngine(GeneralizedBlackScholesProcess process) + { + process_ = process; + process_.registerWith(update); + } + + public override void calculate() + { + if (arguments_.barrierType == DoubleBarrier.Type.KIKO || + arguments_.barrierType == DoubleBarrier.Type.KOKI) + { + AmericanExercise ex = arguments_.exercise as AmericanExercise; + Utils.QL_REQUIRE(ex != null, () => "KIKO/KOKI options must have American exercise"); + Utils.QL_REQUIRE(ex.dates()[0] <= + process_.blackVolatility().currentLink().referenceDate(), + () => "American option with window exercise not handled yet"); + } + else + { + EuropeanExercise ex = arguments_.exercise as EuropeanExercise; + Utils.QL_REQUIRE(ex != null, () => "non-European exercise given"); + } + CashOrNothingPayoff payoff = arguments_.payoff as CashOrNothingPayoff; + Utils.QL_REQUIRE(payoff != null, () => "a cash-or-nothing payoff must be given"); + + double spot = process_.stateVariable().currentLink().value(); + Utils.QL_REQUIRE(spot > 0.0, () => "negative or null underlying given"); + + double variance = + process_.blackVolatility().currentLink().blackVariance( + arguments_.exercise.lastDate(), + payoff.strike()); + double barrier_lo = arguments_.barrier_lo.Value; + double barrier_hi = arguments_.barrier_hi.Value; + DoubleBarrier.Type barrierType = arguments_.barrierType; + Utils.QL_REQUIRE(barrier_lo > 0.0, + () => "positive low barrier value required"); + Utils.QL_REQUIRE(barrier_hi > 0.0, + () => "positive high barrier value required"); + Utils.QL_REQUIRE(barrier_lo < barrier_hi, + () => "barrier_lo must be < barrier_hi"); + Utils.QL_REQUIRE(barrierType == DoubleBarrier.Type.KnockIn || + barrierType == DoubleBarrier.Type.KnockOut || + barrierType == DoubleBarrier.Type.KIKO || + barrierType == DoubleBarrier.Type.KOKI, + () => "Unsupported barrier type"); + + // degenerate cases + switch (barrierType) + { + case DoubleBarrier.Type.KnockOut: + if (spot <= barrier_lo || spot >= barrier_hi) + { + // knocked out, no value + results_.value = 0; + results_.delta = 0; + results_.gamma = 0; + results_.vega = 0; + results_.rho = 0; + return; + } + break; + + case DoubleBarrier.Type.KnockIn: + if (spot <= barrier_lo || spot >= barrier_hi) + { + // knocked in - pays + results_.value = payoff.cashPayoff(); + results_.delta = 0; + results_.gamma = 0; + results_.vega = 0; + results_.rho = 0; + return; + } + break; + + case DoubleBarrier.Type.KIKO: + if (spot >= barrier_hi) + { + // knocked out, no value + results_.value = 0; + results_.delta = 0; + results_.gamma = 0; + results_.vega = 0; + results_.rho = 0; + return; + } + else if (spot <= barrier_lo) + { + // knocked in, pays + results_.value = payoff.cashPayoff(); + results_.delta = 0; + results_.gamma = 0; + results_.vega = 0; + results_.rho = 0; + return; + } + break; + + case DoubleBarrier.Type.KOKI: + if (spot <= barrier_lo) + { + // knocked out, no value + results_.value = 0; + results_.delta = 0; + results_.gamma = 0; + results_.vega = 0; + results_.rho = 0; + return; + } + else if (spot >= barrier_hi) + { + // knocked in, pays + results_.value = payoff.cashPayoff(); + results_.delta = 0; + results_.gamma = 0; + results_.vega = 0; + results_.rho = 0; + return; + } + break; + } + + AnalyticDoubleBarrierBinaryEngineHelper helper = new AnalyticDoubleBarrierBinaryEngineHelper(process_, + payoff, arguments_); + switch (barrierType) + { + case DoubleBarrier.Type.KnockOut: + case DoubleBarrier.Type.KnockIn: + results_.value = helper.payoffAtExpiry(spot, variance, barrierType); + break; + + case DoubleBarrier.Type.KIKO: + case DoubleBarrier.Type.KOKI: + results_.value = helper.payoffKIKO(spot, variance, barrierType); + break; + default: + results_.value = null; + break; + } + } + + protected GeneralizedBlackScholesProcess process_; + } } diff --git a/src/QLNet/Pricingengines/barrier/AnalyticDoubleBarrierEngine.cs b/src/QLNet/Pricingengines/barrier/AnalyticDoubleBarrierEngine.cs index f336d9200..5712aaa3d 100644 --- a/src/QLNet/Pricingengines/barrier/AnalyticDoubleBarrierEngine.cs +++ b/src/QLNet/Pricingengines/barrier/AnalyticDoubleBarrierEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,7 +20,7 @@ namespace QLNet //! Pricing engine for double barrier european options using analytical formulae /*! The formulas are taken from "The complete guide to option pricing formulas 2nd Ed", E.G. Haug, McGraw-Hill, p.156 and following. - Implements the Ikeda and Kunitomo series (see "Pricing Options with + Implements the Ikeda and Kunitomo series (see "Pricing Options with Curved Boundaries" Mathematical Finance 2/1992"). This code handles only flat barriers @@ -43,34 +43,34 @@ public AnalyticDoubleBarrierEngine(GeneralizedBlackScholesProcess process, int s } public override void calculate() { - Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European,()=> - "this engine handles only european options"); + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => + "this engine handles only european options"); PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; - Utils.QL_REQUIRE(payoff!=null,()=> "non-plain payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); double strike = payoff.strike(); - Utils.QL_REQUIRE(strike>0.0,()=> "strike must be positive"); + Utils.QL_REQUIRE(strike > 0.0, () => "strike must be positive"); double spot = underlying(); - Utils.QL_REQUIRE(spot >= 0.0,()=> "negative or null underlying given"); - Utils.QL_REQUIRE(!triggered(spot),()=> "barrier(s) already touched"); + Utils.QL_REQUIRE(spot >= 0.0, () => "negative or null underlying given"); + Utils.QL_REQUIRE(!triggered(spot), () => "barrier(s) already touched"); DoubleBarrier.Type barrierType = arguments_.barrierType; - if (triggered(spot)) + if (triggered(spot)) { if (barrierType == DoubleBarrier.Type.KnockIn) results_.value = vanillaEquivalent(); // knocked in else results_.value = 0.0; // knocked out - } - else + } + else { - switch (payoff.optionType()) + switch (payoff.optionType()) { case Option.Type.Call: - switch (barrierType) + switch (barrierType) { case DoubleBarrier.Type.KnockIn: results_.value = callKI(); @@ -88,7 +88,7 @@ public override void calculate() } break; case Option.Type.Put: - switch (barrierType) + switch (barrierType) { case DoubleBarrier.Type.KnockIn: results_.value = putKI(); @@ -111,7 +111,7 @@ public override void calculate() } } } - + private GeneralizedBlackScholesProcess process_; private CumulativeNormalDistribution f_ ; private int series_; @@ -120,11 +120,11 @@ public override void calculate() private double strike() { PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; - Utils.QL_REQUIRE(payoff!=null,()=> "non-plain payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); return payoff.strike(); } - private double residualTime() { return process_.time( arguments_.exercise.lastDate() ); } - private double volatility() { return process_.blackVolatility().link.blackVol( residualTime(), strike() ); } + private double residualTime() { return process_.time(arguments_.exercise.lastDate()); } + private double volatility() { return process_.blackVolatility().link.blackVol(residualTime(), strike()); } private double volatilitySquared() { return volatility() * volatility(); } private double barrierLo() { return arguments_.barrier_lo.GetValueOrDefault(); } private double barrierHi() { return arguments_.barrier_hi.GetValueOrDefault(); } @@ -132,18 +132,18 @@ private double strike() private double stdDeviation() {return volatility() * Math.Sqrt(residualTime());} private double riskFreeRate() { - return process_.riskFreeRate().link.zeroRate( - residualTime(), Compounding.Continuous,Frequency.NoFrequency ).value(); + return process_.riskFreeRate().link.zeroRate( + residualTime(), Compounding.Continuous, Frequency.NoFrequency).value(); } - private double riskFreeDiscount() { return process_.riskFreeRate().link.discount( residualTime() ); } + private double riskFreeDiscount() { return process_.riskFreeRate().link.discount(residualTime()); } private double dividendYield() { - return process_.dividendYield().link.zeroRate( - residualTime(),Compounding.Continuous, Frequency.NoFrequency ).value(); + return process_.dividendYield().link.zeroRate( + residualTime(), Compounding.Continuous, Frequency.NoFrequency).value(); } private double costOfCarry() { return riskFreeRate() - dividendYield(); } - private double dividendDiscount() { return process_.dividendYield().link.discount( residualTime() ); } - private double vanillaEquivalent() + private double dividendDiscount() { return process_.dividendYield().link.discount(residualTime()); } + private double vanillaEquivalent() { // Call KI equates to vanilla - callKO StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; @@ -162,24 +162,24 @@ private double callKO() double acc1 = 0; double acc2 = 0; - for (int n = -series_ ; n <= series_ ; ++n) + for (int n = -series_ ; n <= series_ ; ++n) { double L2n = Math.Pow(barrierLo(), 2 * n); double U2n = Math.Pow(barrierHi(), 2 * n); - double d1 = Math.Log( underlying()* U2n / (strike() * L2n) ) / stdDeviation() + bsigma; - double d2 = Math.Log( underlying()* U2n / (barrierHi() * L2n) ) / stdDeviation() + bsigma; - double d3 = Math.Log( Math.Pow(barrierLo(), 2 * n + 2) / (strike() * underlying() * U2n) ) / stdDeviation() + bsigma; - double d4 = Math.Log( Math.Pow(barrierLo(), 2 * n + 2) / (barrierHi() * underlying() * U2n) ) / stdDeviation() + bsigma; - - acc1 += Math.Pow( Math.Pow(barrierHi(), n) / Math.Pow(barrierLo(), n), mu1 ) * - (f_.value(d1) - f_.value(d2)) - - Math.Pow( Math.Pow(barrierLo(), n+1) / (Math.Pow(barrierHi(), n) * underlying()), mu1 ) * - (f_.value(d3) - f_.value(d4)); - - acc2 += Math.Pow( Math.Pow(barrierHi(), n) / Math.Pow(barrierLo(), n), mu1-2) * - (f_.value(d1 - stdDeviation()) - f_.value(d2 - stdDeviation())) - - Math.Pow( Math.Pow(barrierLo(), n+1) / (Math.Pow(barrierHi(), n) * underlying()), mu1-2 ) * - (f_.value(d3-stdDeviation()) - f_.value(d4-stdDeviation())); + double d1 = Math.Log(underlying() * U2n / (strike() * L2n)) / stdDeviation() + bsigma; + double d2 = Math.Log(underlying() * U2n / (barrierHi() * L2n)) / stdDeviation() + bsigma; + double d3 = Math.Log(Math.Pow(barrierLo(), 2 * n + 2) / (strike() * underlying() * U2n)) / stdDeviation() + bsigma; + double d4 = Math.Log(Math.Pow(barrierLo(), 2 * n + 2) / (barrierHi() * underlying() * U2n)) / stdDeviation() + bsigma; + + acc1 += Math.Pow(Math.Pow(barrierHi(), n) / Math.Pow(barrierLo(), n), mu1) * + (f_.value(d1) - f_.value(d2)) - + Math.Pow(Math.Pow(barrierLo(), n + 1) / (Math.Pow(barrierHi(), n) * underlying()), mu1) * + (f_.value(d3) - f_.value(d4)); + + acc2 += Math.Pow(Math.Pow(barrierHi(), n) / Math.Pow(barrierLo(), n), mu1 - 2) * + (f_.value(d1 - stdDeviation()) - f_.value(d2 - stdDeviation())) - + Math.Pow(Math.Pow(barrierLo(), n + 1) / (Math.Pow(barrierHi(), n) * underlying()), mu1 - 2) * + (f_.value(d3 - stdDeviation()) - f_.value(d4 - stdDeviation())); } double rend = Math.Exp(-dividendYield() * residualTime()); @@ -190,29 +190,30 @@ private double callKO() private double putKO() { - + double mu1 = 2 * costOfCarry() / volatilitySquared() + 1; double bsigma = (costOfCarry() + volatilitySquared() / 2.0) * residualTime() / stdDeviation(); double acc1 = 0; double acc2 = 0; - for (int n = -series_ ; n <= series_ ; ++n) { + for (int n = -series_ ; n <= series_ ; ++n) + { double L2n = Math.Pow(barrierLo(), 2 * n); double U2n = Math.Pow(barrierHi(), 2 * n); - double y1 = Math.Log( underlying()* U2n / (Math.Pow(barrierLo(), 2 * n + 1)) ) / stdDeviation() + bsigma; - double y2 = Math.Log( underlying()* U2n / (strike() * L2n) ) / stdDeviation() + bsigma; - double y3 = Math.Log( Math.Pow(barrierLo(), 2 * n + 2) / (barrierLo() * underlying() * U2n) ) / stdDeviation() + bsigma; - double y4 = Math.Log( Math.Pow(barrierLo(), 2 * n + 2) / (strike() * underlying() * U2n) ) / stdDeviation() + bsigma; - - acc1 += Math.Pow( Math.Pow(barrierHi(), n) / Math.Pow(barrierLo(), n), mu1-2) * - (f_.value(y1 - stdDeviation()) - f_.value(y2 - stdDeviation())) - - Math.Pow( Math.Pow(barrierLo(), n+1) / (Math.Pow(barrierHi(), n) * underlying()), mu1-2 ) * - (f_.value(y3-stdDeviation()) - f_.value(y4-stdDeviation())); - - acc2 += Math.Pow( Math.Pow(barrierHi(), n) / Math.Pow(barrierLo(), n), mu1 ) * - (f_.value(y1) - f_.value(y2)) - - Math.Pow( Math.Pow(barrierLo(), n+1) / (Math.Pow(barrierHi(), n) * underlying()), mu1 ) * - (f_.value(y3) - f_.value(y4)); + double y1 = Math.Log(underlying() * U2n / (Math.Pow(barrierLo(), 2 * n + 1))) / stdDeviation() + bsigma; + double y2 = Math.Log(underlying() * U2n / (strike() * L2n)) / stdDeviation() + bsigma; + double y3 = Math.Log(Math.Pow(barrierLo(), 2 * n + 2) / (barrierLo() * underlying() * U2n)) / stdDeviation() + bsigma; + double y4 = Math.Log(Math.Pow(barrierLo(), 2 * n + 2) / (strike() * underlying() * U2n)) / stdDeviation() + bsigma; + + acc1 += Math.Pow(Math.Pow(barrierHi(), n) / Math.Pow(barrierLo(), n), mu1 - 2) * + (f_.value(y1 - stdDeviation()) - f_.value(y2 - stdDeviation())) - + Math.Pow(Math.Pow(barrierLo(), n + 1) / (Math.Pow(barrierHi(), n) * underlying()), mu1 - 2) * + (f_.value(y3 - stdDeviation()) - f_.value(y4 - stdDeviation())); + + acc2 += Math.Pow(Math.Pow(barrierHi(), n) / Math.Pow(barrierLo(), n), mu1) * + (f_.value(y1) - f_.value(y2)) - + Math.Pow(Math.Pow(barrierLo(), n + 1) / (Math.Pow(barrierHi(), n) * underlying()), mu1) * + (f_.value(y3) - f_.value(y4)); } diff --git a/src/QLNet/Pricingengines/barrier/BinomialBarrierEngine.cs b/src/QLNet/Pricingengines/barrier/BinomialBarrierEngine.cs index 42cae40fb..202a4d870 100644 --- a/src/QLNet/Pricingengines/barrier/BinomialBarrierEngine.cs +++ b/src/QLNet/Pricingengines/barrier/BinomialBarrierEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -27,21 +27,21 @@ namespace QLNet \test the correctness of the returned values is tested by checking it against analytic european results. */ - public class BinomialBarrierEngine : BarrierOption.Engine + public class BinomialBarrierEngine : BarrierOption.Engine { - public delegate ITree GetTree( StochasticProcess1D process, double end, int steps, double strike ); - public delegate DiscretizedAsset GetAsset( BarrierOption.Arguments args, StochasticProcess process, TimeGrid grid = null ); + public delegate ITree GetTree(StochasticProcess1D process, double end, int steps, double strike); + public delegate DiscretizedAsset GetAsset(BarrierOption.Arguments args, StochasticProcess process, TimeGrid grid = null); /*! \param maxTimeSteps is used to limit timeSteps when using Boyle-Lau - optimization. If zero (the default) the maximum number of + optimization. If zero (the default) the maximum number of steps is calculated by an heuristic: anything when < 1000, otherwise no more than 5*timeSteps. If maxTimeSteps is equal to timeSteps Boyle-Lau is disabled. - Likewise if the lattice is not CoxRossRubinstein Boyle-Lau is + Likewise if the lattice is not CoxRossRubinstein Boyle-Lau is disabled and maxTimeSteps ignored. */ - public BinomialBarrierEngine( GetTree getTree, GetAsset getAsset , - GeneralizedBlackScholesProcess process, int timeSteps, int maxTimeSteps = 0 ) + public BinomialBarrierEngine(GetTree getTree, GetAsset getAsset, + GeneralizedBlackScholesProcess process, int timeSteps, int maxTimeSteps = 0) { process_ = process; timeSteps_ = timeSteps; @@ -49,12 +49,12 @@ public BinomialBarrierEngine( GetTree getTree, GetAsset getAsset , getTree_ = getTree; getAsset_ = getAsset; - Utils.QL_REQUIRE(timeSteps>0,()=> - "timeSteps must be positive, " + timeSteps + " not allowed"); - Utils.QL_REQUIRE(maxTimeSteps==0 || maxTimeSteps>=timeSteps,()=> - "maxTimeSteps must be zero or greater than or equal to timeSteps, " + maxTimeSteps + " not allowed"); - if (maxTimeSteps_== 0) - maxTimeSteps_ = Math.Max( 1000, timeSteps_*5); + Utils.QL_REQUIRE(timeSteps > 0, () => + "timeSteps must be positive, " + timeSteps + " not allowed"); + Utils.QL_REQUIRE(maxTimeSteps == 0 || maxTimeSteps >= timeSteps, () => + "maxTimeSteps must be zero or greater than or equal to timeSteps, " + maxTimeSteps + " not allowed"); + if (maxTimeSteps_ == 0) + maxTimeSteps_ = Math.Max(1000, timeSteps_ * 5); process_.registerWith(update); } @@ -66,11 +66,11 @@ public override void calculate() Calendar volcal = process_.blackVolatility().link.calendar(); double s0 = process_.stateVariable().link.value(); - Utils.QL_REQUIRE(s0 > 0.0,()=> "negative or null underlying given"); + Utils.QL_REQUIRE(s0 > 0.0, () => "negative or null underlying given"); double v = process_.blackVolatility().link.blackVol(arguments_.exercise.lastDate(), s0); Date maturityDate = arguments_.exercise.lastDate(); - double r = process_.riskFreeRate().link.zeroRate(maturityDate,rfdc, Compounding.Continuous, Frequency.NoFrequency).value(); - double q = process_.dividendYield().link.zeroRate(maturityDate,divdc, Compounding.Continuous, Frequency.NoFrequency).value(); + double r = process_.riskFreeRate().link.zeroRate(maturityDate, rfdc, Compounding.Continuous, Frequency.NoFrequency).value(); + double q = process_.dividendYield().link.zeroRate(maturityDate, divdc, Compounding.Continuous, Frequency.NoFrequency).value(); Date referenceDate = process_.riskFreeRate().link.referenceDate(); // binomial trees with constant coefficient @@ -79,12 +79,12 @@ public override void calculate() Handle flatVol = new Handle(new BlackConstantVol(referenceDate, volcal, v, voldc)); StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; - Utils.QL_REQUIRE(payoff != null,()=> "non-striked payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "non-striked payoff given"); double maturity = rfdc.yearFraction(referenceDate, maturityDate); StochasticProcess1D bs = new GeneralizedBlackScholesProcess(process_.stateVariable(), - flatDividends, flatRiskFree, flatVol); + flatDividends, flatRiskFree, flatVol); // correct timesteps to ensure a (local) minimum, using Boyle and Lau // approach. See Journal of Derivatives, 1/1994, @@ -92,19 +92,19 @@ public override void calculate() // Note: this approach works only for CoxRossRubinstein lattices, so // is disabled if T is not a CoxRossRubinstein or derived from it. int optimum_steps = timeSteps_; - if ( maxTimeSteps_ > timeSteps_ && s0 > 0 && arguments_.barrier > 0 ) // boost::is_base_of::value && + if (maxTimeSteps_ > timeSteps_ && s0 > 0 && arguments_.barrier > 0) // boost::is_base_of::value && { double divisor; if (s0 > arguments_.barrier) divisor = Math.Pow(Math.Log(s0 / arguments_.barrier.Value), 2); else divisor = Math.Pow(Math.Log(arguments_.barrier.Value / s0), 2); - if (!Utils.close(divisor,0)) + if (!Utils.close(divisor, 0)) { - for (int i=1; i < timeSteps_ ; ++i) + for (int i = 1; i < timeSteps_ ; ++i) { - int optimum = (int)(( i*i * v*v * maturity) / divisor); - if (timeSteps_ < optimum) + int optimum = (int)((i * i * v * v * maturity) / divisor); + if (timeSteps_ < optimum) { optimum_steps = optimum; break; // found first minimum with iterations>=timesteps @@ -112,7 +112,7 @@ public override void calculate() } } - if (optimum_steps > maxTimeSteps_) + if (optimum_steps > maxTimeSteps_) optimum_steps = maxTimeSteps_; // too high, limit } @@ -120,20 +120,20 @@ public override void calculate() ITree tree = getTree_(bs, maturity, optimum_steps, payoff.strike()); - BlackScholesLattice lattice = new BlackScholesLattice( tree, r, maturity, optimum_steps ); + BlackScholesLattice lattice = new BlackScholesLattice(tree, r, maturity, optimum_steps); - DiscretizedAsset option = getAsset_( arguments_, process_, grid ); + DiscretizedAsset option = getAsset_(arguments_, process_, grid); option.initialize(lattice, maturity); // Partial derivatives calculated from various points in the - // binomial tree + // binomial tree // (see J.C.Hull, "Options, Futures and other derivatives", 6th edition, pp 397/398) // Rollback to third-last step, and get underlying prices (s2) & // option values (p2) at this point option.rollback(grid[2]); Vector va2 = new Vector(option.values()); - Utils.QL_REQUIRE(va2.size() == 3,()=> "Expect 3 nodes in grid at second step"); + Utils.QL_REQUIRE(va2.size() == 3, () => "Expect 3 nodes in grid at second step"); double p2u = va2[2]; // up double p2m = va2[1]; // mid double p2d = va2[0]; // down (low) @@ -142,15 +142,15 @@ public override void calculate() double s2d = lattice.underlying(2, 0); // down (low) price // calculate gamma by taking the first derivate of the two deltas - double delta2u = (p2u - p2m)/(s2u-s2m); - double delta2d = (p2m-p2d)/(s2m-s2d); - double gamma = (delta2u - delta2d) / ((s2u-s2d)/2); + double delta2u = (p2u - p2m) / (s2u - s2m); + double delta2d = (p2m - p2d) / (s2m - s2d); + double gamma = (delta2u - delta2d) / ((s2u - s2d) / 2); // Rollback to second-last step, and get option values (p1) at // this point option.rollback(grid[1]); Vector va = new Vector(option.values()); - Utils.QL_REQUIRE(va.size() == 2,()=> "Expect 2 nodes in grid at first step"); + Utils.QL_REQUIRE(va.size() == 2, () => "Expect 2 nodes in grid at first step"); double p1u = va[1]; double p1d = va[0]; double s1u = lattice.underlying(1, 1); // up (high) price diff --git a/src/QLNet/Pricingengines/barrier/BinomialDoubleBarrierEngine.cs b/src/QLNet/Pricingengines/barrier/BinomialDoubleBarrierEngine.cs index bd8c9c384..7e7b5f5e6 100644 --- a/src/QLNet/Pricingengines/barrier/BinomialDoubleBarrierEngine.cs +++ b/src/QLNet/Pricingengines/barrier/BinomialDoubleBarrierEngine.cs @@ -1,49 +1,49 @@ -// Copyright (C) 2015 Thema Consulting SA +// Copyright (C) 2015 Thema Consulting SA // Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. using System; namespace QLNet -{ - //! Pricing engine for double barrier options using binomial trees - /*! \ingroup barrierengines - - \note This engine requires a the discretized option classes. - By default uses a standard binomial implementation, but it can - also work with DiscretizedDermanKaniDoubleBarrierOption to - implement a Derman-Kani optimization. - - \test the correctness of the returned values is tested by - checking it against analytic results. - */ - public class BinomialDoubleBarrierEngine : DoubleBarrierOption.Engine +{ + //! Pricing engine for double barrier options using binomial trees + /*! \ingroup barrierengines + + \note This engine requires a the discretized option classes. + By default uses a standard binomial implementation, but it can + also work with DiscretizedDermanKaniDoubleBarrierOption to + implement a Derman-Kani optimization. + + \test the correctness of the returned values is tested by + checking it against analytic results. + */ + public class BinomialDoubleBarrierEngine : DoubleBarrierOption.Engine { - public delegate ITree GetTree( StochasticProcess1D process, double end, int steps, double strike ); - public delegate DiscretizedAsset GetAsset( DoubleBarrierOption.Arguments args, StochasticProcess process, TimeGrid grid = null ); + public delegate ITree GetTree(StochasticProcess1D process, double end, int steps, double strike); + public delegate DiscretizedAsset GetAsset(DoubleBarrierOption.Arguments args, StochasticProcess process, TimeGrid grid = null); /*! \param maxTimeSteps is used to limit timeSteps when using Boyle-Lau - optimization. If zero (the default) the maximum number of + optimization. If zero (the default) the maximum number of steps is calculated by an heuristic: anything when < 1000, otherwise no more than 5*timeSteps. If maxTimeSteps is equal to timeSteps Boyle-Lau is disabled. - Likewise if the lattice is not CoxRossRubinstein Boyle-Lau is + Likewise if the lattice is not CoxRossRubinstein Boyle-Lau is disabled and maxTimeSteps ignored. - */ - public BinomialDoubleBarrierEngine(GetTree getTree, GetAsset getAsset, - GeneralizedBlackScholesProcess process, int timeSteps, int maxTimeSteps = 0 ) + */ + public BinomialDoubleBarrierEngine(GetTree getTree, GetAsset getAsset, + GeneralizedBlackScholesProcess process, int timeSteps, int maxTimeSteps = 0) { process_ = process; timeSteps_ = timeSteps; @@ -51,12 +51,12 @@ public BinomialDoubleBarrierEngine(GetTree getTree, GetAsset getAsset, getTree_ = getTree; getAsset_ = getAsset; - Utils.QL_REQUIRE(timeSteps>0,()=> - "timeSteps must be positive, " + timeSteps + " not allowed"); - Utils.QL_REQUIRE(maxTimeSteps==0 || maxTimeSteps>=timeSteps,()=> - "maxTimeSteps must be zero or greater than or equal to timeSteps, " + maxTimeSteps + " not allowed"); - if (maxTimeSteps_== 0) - maxTimeSteps_ = Math.Max( 1000, timeSteps_*5); + Utils.QL_REQUIRE(timeSteps > 0, () => + "timeSteps must be positive, " + timeSteps + " not allowed"); + Utils.QL_REQUIRE(maxTimeSteps == 0 || maxTimeSteps >= timeSteps, () => + "maxTimeSteps must be zero or greater than or equal to timeSteps, " + maxTimeSteps + " not allowed"); + if (maxTimeSteps_ == 0) + maxTimeSteps_ = Math.Max(1000, timeSteps_ * 5); process_.registerWith(update); } @@ -68,11 +68,11 @@ public override void calculate() Calendar volcal = process_.blackVolatility().link.calendar(); double s0 = process_.stateVariable().link.value(); - Utils.QL_REQUIRE(s0 > 0.0,()=> "negative or null underlying given"); + Utils.QL_REQUIRE(s0 > 0.0, () => "negative or null underlying given"); double v = process_.blackVolatility().link.blackVol(arguments_.exercise.lastDate(), s0); Date maturityDate = arguments_.exercise.lastDate(); - double r = process_.riskFreeRate().link.zeroRate(maturityDate,rfdc, Compounding.Continuous, Frequency.NoFrequency).value(); - double q = process_.dividendYield().link.zeroRate(maturityDate,divdc, Compounding.Continuous, Frequency.NoFrequency).value(); + double r = process_.riskFreeRate().link.zeroRate(maturityDate, rfdc, Compounding.Continuous, Frequency.NoFrequency).value(); + double q = process_.dividendYield().link.zeroRate(maturityDate, divdc, Compounding.Continuous, Frequency.NoFrequency).value(); Date referenceDate = process_.riskFreeRate().link.referenceDate(); // binomial trees with constant coefficient @@ -81,31 +81,31 @@ public override void calculate() Handle flatVol = new Handle(new BlackConstantVol(referenceDate, volcal, v, voldc)); StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; - Utils.QL_REQUIRE(payoff != null,()=> "non-striked payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "non-striked payoff given"); double maturity = rfdc.yearFraction(referenceDate, maturityDate); StochasticProcess1D bs = new GeneralizedBlackScholesProcess(process_.stateVariable(), - flatDividends, flatRiskFree, flatVol); - - TimeGrid grid = new TimeGrid(maturity, timeSteps_); - - ITree tree = getTree_(bs, maturity, timeSteps_, payoff.strike()); - + flatDividends, flatRiskFree, flatVol); + + TimeGrid grid = new TimeGrid(maturity, timeSteps_); + + ITree tree = getTree_(bs, maturity, timeSteps_, payoff.strike()); + BlackScholesLattice lattice = new BlackScholesLattice(tree, r, maturity, timeSteps_); - DiscretizedAsset option = getAsset_( arguments_, process_, grid ); - option.initialize(lattice, maturity); - - // Partial derivatives calculated from various points in the - // binomial tree - // (see J.C.Hull, "Options, Futures and other derivatives", 6th edition, pp 397/398) - - // Rollback to third-last step, and get underlying prices (s2) & + DiscretizedAsset option = getAsset_(arguments_, process_, grid); + option.initialize(lattice, maturity); + + // Partial derivatives calculated from various points in the + // binomial tree + // (see J.C.Hull, "Options, Futures and other derivatives", 6th edition, pp 397/398) + + // Rollback to third-last step, and get underlying prices (s2) & // option values (p2) at this point option.rollback(grid[2]); Vector va2 = new Vector(option.values()); - Utils.QL_REQUIRE(va2.size() == 3,()=> "Expect 3 nodes in grid at second step"); + Utils.QL_REQUIRE(va2.size() == 3, () => "Expect 3 nodes in grid at second step"); double p2u = va2[2]; // up double p2m = va2[1]; // mid double p2d = va2[0]; // down (low) @@ -114,15 +114,15 @@ public override void calculate() double s2d = lattice.underlying(2, 0); // down (low) price // calculate gamma by taking the first derivate of the two deltas - double delta2u = (p2u - p2m)/(s2u-s2m); - double delta2d = (p2m-p2d)/(s2m-s2d); - double gamma = (delta2u - delta2d) / ((s2u-s2d)/2); + double delta2u = (p2u - p2m) / (s2u - s2m); + double delta2d = (p2m - p2d) / (s2m - s2d); + double gamma = (delta2u - delta2d) / ((s2u - s2d) / 2); // Rollback to second-last step, and get option values (p1) at // this point option.rollback(grid[1]); Vector va = new Vector(option.values()); - Utils.QL_REQUIRE(va.size() == 2,()=> "Expect 2 nodes in grid at first step"); + Utils.QL_REQUIRE(va.size() == 2, () => "Expect 2 nodes in grid at first step"); double p1u = va[1]; double p1d = va[0]; double s1u = lattice.underlying(1, 1); // up (high) price diff --git a/src/QLNet/Pricingengines/barrier/DiscretizedBarrierOption.cs b/src/QLNet/Pricingengines/barrier/DiscretizedBarrierOption.cs index b8b32ade9..a567429b3 100644 --- a/src/QLNet/Pricingengines/barrier/DiscretizedBarrierOption.cs +++ b/src/QLNet/Pricingengines/barrier/DiscretizedBarrierOption.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,29 +21,29 @@ namespace QLNet { public class DiscretizedBarrierOption : DiscretizedAsset { - public DiscretizedBarrierOption( BarrierOption.Arguments args,StochasticProcess process,TimeGrid grid = null) + public DiscretizedBarrierOption(BarrierOption.Arguments args, StochasticProcess process, TimeGrid grid = null) { - arguments_ = args; + arguments_ = args; vanilla_ = new DiscretizedVanillaOption(arguments_, process, grid); - Utils.QL_REQUIRE( args.exercise.dates().Count >0 ,()=> "specify at least one stopping date" ); + Utils.QL_REQUIRE(args.exercise.dates().Count > 0, () => "specify at least one stopping date"); - stoppingTimes_ = new InitializedList( args.exercise.dates().Count ); - for ( int i = 0; i < stoppingTimes_.Count; ++i ) + stoppingTimes_ = new InitializedList(args.exercise.dates().Count); + for (int i = 0; i < stoppingTimes_.Count; ++i) { - stoppingTimes_[i] = process.time( args.exercise.date( i ) ); - if ( grid != null && !grid.empty() ) + stoppingTimes_[i] = process.time(args.exercise.date(i)); + if (grid != null && !grid.empty()) { // adjust to the given grid - stoppingTimes_[i] = grid.closestTime( stoppingTimes_[i] ); + stoppingTimes_[i] = grid.closestTime(stoppingTimes_[i]); } } } public override void reset(int size) { - vanilla_.initialize( method(), time() ); - values_ = new Vector( size, 0.0 ); + vanilla_.initialize(method(), time()); + values_ = new Vector(size, 0.0); adjustValues(); } @@ -57,8 +57,8 @@ public void checkBarrier(Vector optvalues, Vector grid) { double now = time(); bool endTime = isOnTime(stoppingTimes_.Last()); - bool stoppingTime = false; - switch (arguments_.exercise.type()) + bool stoppingTime = false; + switch (arguments_.exercise.type()) { case Exercise.Type.American: if (now <= stoppingTimes_[1] && @@ -70,9 +70,9 @@ public void checkBarrier(Vector optvalues, Vector grid) stoppingTime = true; break; case Exercise.Type.Bermudan: - for (int i=0; i= arguments_.barrier) + if (grid[j] >= arguments_.barrier) { // knocked in - if (stoppingTime) + if (stoppingTime) { - optvalues[j] = Math.Max( vanilla_.values()[j], arguments_.payoff.value( grid[j] ) ); + optvalues[j] = Math.Max(vanilla_.values()[j], arguments_.payoff.value(grid[j])); } else - optvalues[j] = vanilla_.values()[j]; + optvalues[j] = vanilla_.values()[j]; } else if (endTime) - optvalues[j] = arguments_.rebate.GetValueOrDefault(); + optvalues[j] = arguments_.rebate.GetValueOrDefault(); break; case Barrier.Type.UpOut: if (grid[j] >= arguments_.barrier) optvalues[j] = arguments_.rebate.GetValueOrDefault(); // knocked out else if (stoppingTime) - optvalues[j] = Math.Max( optvalues[j], arguments_.payoff.value( grid[j] ) ); + optvalues[j] = Math.Max(optvalues[j], arguments_.payoff.value(grid[j])); break; default: Utils.QL_FAIL("invalid barrier type"); @@ -134,109 +135,109 @@ public void checkBarrier(Vector optvalues, Vector grid) } } } - + protected override void postAdjustValuesImpl() { - if (arguments_.barrierType==Barrier.Type.DownIn || - arguments_.barrierType==Barrier.Type.UpIn) + if (arguments_.barrierType == Barrier.Type.DownIn || + arguments_.barrierType == Barrier.Type.UpIn) { vanilla_.rollback(time()); } Vector grid = method().grid(time()); checkBarrier(values_, grid); } - + private BarrierOption.Arguments arguments_; private List stoppingTimes_; - private DiscretizedVanillaOption vanilla_; + private DiscretizedVanillaOption vanilla_; } - public class DiscretizedDermanKaniBarrierOption : DiscretizedAsset + public class DiscretizedDermanKaniBarrierOption : DiscretizedAsset { public DiscretizedDermanKaniBarrierOption(BarrierOption.Arguments args, - StochasticProcess process,TimeGrid grid = null) + StochasticProcess process, TimeGrid grid = null) { - unenhanced_ = new DiscretizedBarrierOption(args, process, grid ); + unenhanced_ = new DiscretizedBarrierOption(args, process, grid); } public override void reset(int size) { - unenhanced_.initialize( method(), time() ); - values_ = new Vector( size, 0.0 ); + unenhanced_.initialize(method(), time()); + values_ = new Vector(size, 0.0); adjustValues(); } public override List mandatoryTimes() {return unenhanced_.mandatoryTimes();} - + protected override void postAdjustValuesImpl() { - unenhanced_.rollback( time() ); + unenhanced_.rollback(time()); - Vector grid = method().grid( time() ); - adjustBarrier( values_, grid ); - unenhanced_.checkBarrier( values_, grid ); // compute payoffs + Vector grid = method().grid(time()); + adjustBarrier(values_, grid); + unenhanced_.checkBarrier(values_, grid); // compute payoffs } - + private void adjustBarrier(Vector optvalues, Vector grid) { double? barrier = unenhanced_.arguments().barrier; double? rebate = unenhanced_.arguments().rebate; - switch (unenhanced_.arguments().barrierType) + switch (unenhanced_.arguments().barrierType) { case Barrier.Type.DownIn: - for (int j=0; j barrier) + if (grid[j] <= barrier && grid[j + 1] > barrier) { - double? ltob = (barrier-grid[j]); - double? htob = (grid[j+1]-barrier); - double htol = (grid[j+1]-grid[j]); - double u1 = unenhanced_.values()[j+1]; - double t1 = unenhanced_.vanilla()[j+1]; - optvalues[j+1] = Math.Max(0.0, (ltob.GetValueOrDefault()*t1+htob.GetValueOrDefault()*u1)/htol); + double? ltob = (barrier - grid[j]); + double? htob = (grid[j + 1] - barrier); + double htol = (grid[j + 1] - grid[j]); + double u1 = unenhanced_.values()[j + 1]; + double t1 = unenhanced_.vanilla()[j + 1]; + optvalues[j + 1] = Math.Max(0.0, (ltob.GetValueOrDefault() * t1 + htob.GetValueOrDefault() * u1) / htol); } } break; case Barrier.Type.DownOut: - for (int j=0; j barrier) + if (grid[j] <= barrier && grid[j + 1] > barrier) { - double? a = (barrier-grid[j])*rebate; - double? b = (grid[j+1]-barrier)*unenhanced_.values()[j+1]; - double c = (grid[j+1]-grid[j]); - optvalues[j+1] = Math.Max(0.0, (a.GetValueOrDefault()+b.GetValueOrDefault())/c); + double? a = (barrier - grid[j]) * rebate; + double? b = (grid[j + 1] - barrier) * unenhanced_.values()[j + 1]; + double c = (grid[j + 1] - grid[j]); + optvalues[j + 1] = Math.Max(0.0, (a.GetValueOrDefault() + b.GetValueOrDefault()) / c); } } break; case Barrier.Type.UpIn: - for (int j=0; j= barrier) + if (grid[j] < barrier && grid[j + 1] >= barrier) { - double? ltob = (barrier-grid[j]); - double? htob = (grid[j+1]-barrier); - double htol = (grid[j+1]-grid[j]); - double u = unenhanced_.values()[j]; - double t = unenhanced_.vanilla()[j]; - optvalues[j] = Math.Max(0.0, (ltob.GetValueOrDefault()*u+htob.GetValueOrDefault()*t)/htol); // derman std + double? ltob = (barrier - grid[j]); + double? htob = (grid[j + 1] - barrier); + double htol = (grid[j + 1] - grid[j]); + double u = unenhanced_.values()[j]; + double t = unenhanced_.vanilla()[j]; + optvalues[j] = Math.Max(0.0, (ltob.GetValueOrDefault() * u + htob.GetValueOrDefault() * t) / htol); // derman std } } break; case Barrier.Type.UpOut: - for (int j=0; j= barrier) + if (grid[j] < barrier && grid[j + 1] >= barrier) { - double? a = (barrier-grid[j])*unenhanced_.values()[j]; - double? b = (grid[j+1]-barrier)*rebate; - double c = (grid[j+1]-grid[j]); - optvalues[j] = Math.Max(0.0, (a.GetValueOrDefault()+b.GetValueOrDefault())/c); + double? a = (barrier - grid[j]) * unenhanced_.values()[j]; + double? b = (grid[j + 1] - barrier) * rebate; + double c = (grid[j + 1] - grid[j]); + optvalues[j] = Math.Max(0.0, (a.GetValueOrDefault() + b.GetValueOrDefault()) / c); } - } - break; - } + } + break; + } } private DiscretizedBarrierOption unenhanced_; } diff --git a/src/QLNet/Pricingengines/barrier/DiscretizedDoubleBarrierOption.cs b/src/QLNet/Pricingengines/barrier/DiscretizedDoubleBarrierOption.cs index 6b3706b4a..8ef2d5d75 100644 --- a/src/QLNet/Pricingengines/barrier/DiscretizedDoubleBarrierOption.cs +++ b/src/QLNet/Pricingengines/barrier/DiscretizedDoubleBarrierOption.cs @@ -1,16 +1,16 @@ // Copyright (C) 2015 Thema Consulting SA // Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,30 +21,30 @@ namespace QLNet { public class DiscretizedDoubleBarrierOption : DiscretizedAsset - { - public DiscretizedDoubleBarrierOption(DoubleBarrierOption.Arguments args, StochasticProcess process, TimeGrid grid = null) + { + public DiscretizedDoubleBarrierOption(DoubleBarrierOption.Arguments args, StochasticProcess process, TimeGrid grid = null) { - arguments_ = args; + arguments_ = args; vanilla_ = new DiscretizedVanillaOption(arguments_, process, grid); - Utils.QL_REQUIRE( args.exercise.dates().Count >0 ,()=> "specify at least one stopping date" ); + Utils.QL_REQUIRE(args.exercise.dates().Count > 0, () => "specify at least one stopping date"); - stoppingTimes_ = new InitializedList( args.exercise.dates().Count ); - for ( int i = 0; i < stoppingTimes_.Count; ++i ) + stoppingTimes_ = new InitializedList(args.exercise.dates().Count); + for (int i = 0; i < stoppingTimes_.Count; ++i) { - stoppingTimes_[i] = process.time( args.exercise.date( i ) ); - if ( grid != null && !grid.empty() ) + stoppingTimes_[i] = process.time(args.exercise.date(i)); + if (grid != null && !grid.empty()) { // adjust to the given grid - stoppingTimes_[i] = grid.closestTime( stoppingTimes_[i] ); + stoppingTimes_[i] = grid.closestTime(stoppingTimes_[i]); } } } public override void reset(int size) { - vanilla_.initialize( method(), time() ); - values_ = new Vector( size, 0.0 ); + vanilla_.initialize(method(), time()); + values_ = new Vector(size, 0.0); adjustValues(); } @@ -58,8 +58,8 @@ public void checkBarrier(Vector optvalues, Vector grid) { double now = time(); bool endTime = isOnTime(stoppingTimes_.Last()); - bool stoppingTime = false; - switch (arguments_.exercise.type()) + bool stoppingTime = false; + switch (arguments_.exercise.type()) { case Exercise.Type.American: if (now <= stoppingTimes_[1] && @@ -71,9 +71,9 @@ public void checkBarrier(Vector optvalues, Vector grid) stoppingTime = true; break; case Exercise.Type.Bermudan: - for (int i=0; i= arguments_.barrier_hi) - { - // knocked in up - if (stoppingTime) - { - optvalues[j] = Math.Max(vanilla_.values()[j], arguments_.payoff.value(grid[j])); + else if (grid[j] >= arguments_.barrier_hi) + { + // knocked in up + if (stoppingTime) + { + optvalues[j] = Math.Max(vanilla_.values()[j], arguments_.payoff.value(grid[j])); } else - optvalues[j] = vanilla()[j]; + optvalues[j] = vanilla()[j]; } else if (endTime) - optvalues[j] = arguments_.rebate.GetValueOrDefault(); + optvalues[j] = arguments_.rebate.GetValueOrDefault(); break; case DoubleBarrier.Type.KnockOut: if (grid[j] <= arguments_.barrier_lo) - optvalues[j] = arguments_.rebate.GetValueOrDefault(); // knocked out lo - else if (grid[j] >= arguments_.barrier_hi) - optvalues[j] = arguments_.rebate.GetValueOrDefault(); // knocked out lo - else if (stoppingTime) { - optvalues[j] = Math.Max( optvalues[j], arguments_.payoff.value( grid[j] ) ); + optvalues[j] = arguments_.rebate.GetValueOrDefault(); // knocked out lo + else if (grid[j] >= arguments_.barrier_hi) + optvalues[j] = arguments_.rebate.GetValueOrDefault(); // knocked out lo + else if (stoppingTime) + { + optvalues[j] = Math.Max(optvalues[j], arguments_.payoff.value(grid[j])); } break; case DoubleBarrier.Type.KIKO: // low barrier is KI, high is KO - if (grid[j] <= arguments_.barrier_lo) { + if (grid[j] <= arguments_.barrier_lo) + { // knocked in dn - if (stoppingTime) { - optvalues[j] = Math.Max(vanilla_.values()[j], arguments_.payoff.value(grid[j])); + if (stoppingTime) + { + optvalues[j] = Math.Max(vanilla_.values()[j], arguments_.payoff.value(grid[j])); } else - optvalues[j] = vanilla()[j]; + optvalues[j] = vanilla()[j]; } - else if (grid[j] >= arguments_.barrier_hi) - optvalues[j] = arguments_.rebate.GetValueOrDefault(); // knocked out hi - else if (endTime) - optvalues[j] = arguments_.rebate.GetValueOrDefault(); + else if (grid[j] >= arguments_.barrier_hi) + optvalues[j] = arguments_.rebate.GetValueOrDefault(); // knocked out hi + else if (endTime) + optvalues[j] = arguments_.rebate.GetValueOrDefault(); break; - case DoubleBarrier.Type.KOKI: + case DoubleBarrier.Type.KOKI: // low barrier is KO, high is KI - if (grid[j] <= arguments_.barrier_lo) - optvalues[j] = arguments_.rebate.GetValueOrDefault(); // knocked out lo - else if (grid[j] >= arguments_.barrier_hi) { + if (grid[j] <= arguments_.barrier_lo) + optvalues[j] = arguments_.rebate.GetValueOrDefault(); // knocked out lo + else if (grid[j] >= arguments_.barrier_hi) + { // knocked in up - if (stoppingTime) { - optvalues[j] = Math.Max(vanilla_.values()[j], arguments_.payoff.value(grid[j])); + if (stoppingTime) + { + optvalues[j] = Math.Max(vanilla_.values()[j], arguments_.payoff.value(grid[j])); } else - optvalues[j] = vanilla()[j]; + optvalues[j] = vanilla()[j]; } - else if (endTime) - optvalues[j] = arguments_.rebate.GetValueOrDefault(); + else if (endTime) + optvalues[j] = arguments_.rebate.GetValueOrDefault(); break; default: Utils.QL_FAIL("invalid barrier type"); @@ -157,113 +162,119 @@ public void checkBarrier(Vector optvalues, Vector grid) } } } - + protected override void postAdjustValuesImpl() { - if (arguments_.barrierType!=DoubleBarrier.Type.KnockOut) + if (arguments_.barrierType != DoubleBarrier.Type.KnockOut) { vanilla_.rollback(time()); } Vector grid = method().grid(time()); checkBarrier(values_, grid); } - + private DoubleBarrierOption.Arguments arguments_; private List stoppingTimes_; - private DiscretizedVanillaOption vanilla_; + private DiscretizedVanillaOption vanilla_; - } - - //! Derman-Kani-Ergener-Bardhan discretized option helper class + } + + //! Derman-Kani-Ergener-Bardhan discretized option helper class /*! This class is used with the BinomialDoubleBarrierEngine to implement the enhanced binomial algorithm of E.Derman, I.Kani, D.Ergener, I.Bardhan ("Enhanced Numerical Methods for Options with Barriers", 1995) - \note This algorithm is only suitable if the payoff can be approximated + \note This algorithm is only suitable if the payoff can be approximated linearly, e.g. is not usable for cash-or-nothing payoffs. */ - public class DiscretizedDermanKaniDoubleBarrierOption : DiscretizedAsset - { - public DiscretizedDermanKaniDoubleBarrierOption(DoubleBarrierOption.Arguments args, - StochasticProcess process,TimeGrid grid = null) + public class DiscretizedDermanKaniDoubleBarrierOption : DiscretizedAsset + { + public DiscretizedDermanKaniDoubleBarrierOption(DoubleBarrierOption.Arguments args, + StochasticProcess process, TimeGrid grid = null) { - unenhanced_ = new DiscretizedDoubleBarrierOption(args, process, grid ); + unenhanced_ = new DiscretizedDoubleBarrierOption(args, process, grid); } public override void reset(int size) { - unenhanced_.initialize( method(), time() ); - values_ = new Vector( size, 0.0 ); + unenhanced_.initialize(method(), time()); + values_ = new Vector(size, 0.0); adjustValues(); } public override List mandatoryTimes() {return unenhanced_.mandatoryTimes();} - + protected override void postAdjustValuesImpl() { - unenhanced_.rollback( time() ); + unenhanced_.rollback(time()); - Vector grid = method().grid( time() ); - unenhanced_.checkBarrier( values_, grid ); // compute payoffs + Vector grid = method().grid(time()); + unenhanced_.checkBarrier(values_, grid); // compute payoffs adjustBarrier(values_, grid); } - + private void adjustBarrier(Vector optvalues, Vector grid) { - double? barrier_lo = unenhanced_.arguments().barrier_lo; + double? barrier_lo = unenhanced_.arguments().barrier_lo; double? barrier_hi = unenhanced_.arguments().barrier_hi; double? rebate = unenhanced_.arguments().rebate; - switch (unenhanced_.arguments().barrierType) + switch (unenhanced_.arguments().barrierType) { case DoubleBarrier.Type.KnockIn: - for (int j=0; j barrier_lo) { + for (int j = 0; j < optvalues.size() - 1; ++j) + { + if (grid[j] <= barrier_lo && grid[j + 1] > barrier_lo) + { // grid[j+1] above barrier_lo, grid[j] under (in), // interpolate optvalues[j+1] - double? ltob = (barrier_lo-grid[j]); - double? htob = (grid[j+1]-barrier_lo); - double htol = (grid[j+1]-grid[j]); - double u1 = unenhanced_.values()[j+1]; - double t1 = unenhanced_.vanilla()[j+1]; + double? ltob = (barrier_lo - grid[j]); + double? htob = (grid[j + 1] - barrier_lo); + double htol = (grid[j + 1] - grid[j]); + double u1 = unenhanced_.values()[j + 1]; + double t1 = unenhanced_.vanilla()[j + 1]; optvalues[j + 1] = Math.Max(0.0, (ltob.GetValueOrDefault() * t1 + htob.GetValueOrDefault() * u1) / htol); // derman std } - else if (grid[j] < barrier_hi && grid[j+1] >= barrier_hi) { - // grid[j+1] above barrier_hi (in), grid[j] under, + else if (grid[j] < barrier_hi && grid[j + 1] >= barrier_hi) + { + // grid[j+1] above barrier_hi (in), grid[j] under, // interpolate optvalues[j] - double? ltob = (barrier_hi-grid[j]); - double? htob = (grid[j+1]-barrier_hi); - double htol = (grid[j+1]-grid[j]); + double? ltob = (barrier_hi - grid[j]); + double? htob = (grid[j + 1] - barrier_hi); + double htol = (grid[j + 1] - grid[j]); double u = unenhanced_.values()[j]; - double t = unenhanced_.vanilla()[j]; + double t = unenhanced_.vanilla()[j]; optvalues[j] = Math.Max(0.0, (ltob.GetValueOrDefault() * u + htob.GetValueOrDefault() * t) / htol); // derman std } } - break; + break; case DoubleBarrier.Type.KnockOut: - for (int j=0; j barrier_lo) { + for (int j = 0; j < optvalues.size() - 1; ++j) + { + if (grid[j] <= barrier_lo && grid[j + 1] > barrier_lo) + { // grid[j+1] above barrier_lo, grid[j] under (out), // interpolate optvalues[j+1] - double? a = (barrier_lo-grid[j])*rebate; - double? b = (grid[j+1]-barrier_lo)*unenhanced_.values()[j+1]; - double c = (grid[j+1]-grid[j]); + double? a = (barrier_lo - grid[j]) * rebate; + double? b = (grid[j + 1] - barrier_lo) * unenhanced_.values()[j + 1]; + double c = (grid[j + 1] - grid[j]); optvalues[j + 1] = Math.Max(0.0, (a.GetValueOrDefault() + b.GetValueOrDefault()) / c); } - else if (grid[j] < barrier_hi && grid[j+1] >= barrier_hi) { - // grid[j+1] above barrier_hi (out), grid[j] under, + else if (grid[j] < barrier_hi && grid[j + 1] >= barrier_hi) + { + // grid[j+1] above barrier_hi (out), grid[j] under, // interpolate optvalues[j] - double? a = (barrier_hi-grid[j])*unenhanced_.values()[j]; - double? b = (grid[j+1]-barrier_hi)*rebate; - double c = (grid[j+1]-grid[j]); + double? a = (barrier_hi - grid[j]) * unenhanced_.values()[j]; + double? b = (grid[j + 1] - barrier_hi) * rebate; + double c = (grid[j + 1] - grid[j]); optvalues[j] = Math.Max(0.0, (a.GetValueOrDefault() + b.GetValueOrDefault()) / c); } - } - break; - default: + } + break; + default: Utils.QL_FAIL("unsupported barrier type"); break; - } + } } private DiscretizedDoubleBarrierOption unenhanced_; } diff --git a/src/QLNet/Pricingengines/barrier/FdBlackScholesBarrierEngine.cs b/src/QLNet/Pricingengines/barrier/FdBlackScholesBarrierEngine.cs index b737d0314..f898e7185 100644 --- a/src/QLNet/Pricingengines/barrier/FdBlackScholesBarrierEngine.cs +++ b/src/QLNet/Pricingengines/barrier/FdBlackScholesBarrierEngine.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -67,7 +67,7 @@ public override void calculate() Fdm1dMesher equityMesher = new FdmBlackScholesMesher(xGrid_, process_, maturity, - payoff.strike(), xMin, xMax); + payoff.strike(), xMin, xMax); FdmMesher mesher = new FdmMesherComposite(equityMesher); @@ -83,8 +83,8 @@ public override void calculate() // 3.1 Step condition if discrete dividends FdmDividendHandler dividendCondition = new FdmDividendHandler(arguments_.cashFlow, mesher, - process_.riskFreeRate().currentLink().referenceDate(), - process_.riskFreeRate().currentLink().dayCounter(), 0); + process_.riskFreeRate().currentLink().referenceDate(), + process_.riskFreeRate().currentLink().dayCounter(), 0); if (!arguments_.cashFlow.empty()) { @@ -93,7 +93,7 @@ public override void calculate() } Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, - () => "only european style option are supported"); + () => "only european style option are supported"); FdmStepConditionComposite conditions = new FdmStepConditionComposite(stoppingTimes, stepConditions); @@ -105,7 +105,7 @@ public override void calculate() { boundaries.Add( new FdmDirichletBoundary(mesher, arguments_.rebate.Value, 0, - FdmDirichletBoundary.Side.Lower)); + FdmDirichletBoundary.Side.Lower)); } if (arguments_.barrierType == Barrier.Type.UpIn @@ -113,7 +113,7 @@ public override void calculate() { boundaries.Add( new FdmDirichletBoundary(mesher, arguments_.rebate.Value, 0, - FdmDirichletBoundary.Side.Upper)); + FdmDirichletBoundary.Side.Upper)); } // 5. Solver @@ -128,9 +128,9 @@ public override void calculate() FdmBlackScholesSolver solver = new FdmBlackScholesSolver( - new Handle(process_), - payoff.strike(), solverDesc, schemeDesc_, - localVol_, illegalLocalVolOverwrite_); + new Handle(process_), + payoff.strike(), solverDesc, schemeDesc_, + localVol_, illegalLocalVolOverwrite_); double spot = process_.x0(); results_.value = solver.valueAt(spot); @@ -148,8 +148,8 @@ public override void calculate() // Calculate the vanilla option DividendVanillaOption vanillaOption = new DividendVanillaOption(castedPayoff, arguments_.exercise, - dividendCondition.dividendDates(), - dividendCondition.dividends()); + dividendCondition.dividendDates(), + dividendCondition.dividends()); vanillaOption.setPricingEngine( new FdBlackScholesVanillaEngine( @@ -160,20 +160,20 @@ public override void calculate() // Calculate the rebate value DividendBarrierOption rebateOption = new DividendBarrierOption(arguments_.barrierType, - arguments_.barrier.Value, - arguments_.rebate.Value, - castedPayoff, arguments_.exercise, - dividendCondition.dividendDates(), - dividendCondition.dividends()); + arguments_.barrier.Value, + arguments_.rebate.Value, + castedPayoff, arguments_.exercise, + dividendCondition.dividendDates(), + dividendCondition.dividends()); int min_grid_size = 50; int rebateDampingSteps = (dampingSteps_ > 0) ? Math.Min(1, dampingSteps_ / 2) : 0; rebateOption.setPricingEngine(new FdBlackScholesRebateEngine( - process_, tGrid_, Math.Max(min_grid_size, xGrid_ / 5), - rebateDampingSteps, schemeDesc_, localVol_, - illegalLocalVolOverwrite_)); + process_, tGrid_, Math.Max(min_grid_size, xGrid_ / 5), + rebateDampingSteps, schemeDesc_, localVol_, + illegalLocalVolOverwrite_)); results_.value = vanillaOption.NPV() + rebateOption.NPV() - results_.value; diff --git a/src/QLNet/Pricingengines/barrier/FdBlackScholesRebateEngine.cs b/src/QLNet/Pricingengines/barrier/FdBlackScholesRebateEngine.cs index eb7723e05..f47915606 100644 --- a/src/QLNet/Pricingengines/barrier/FdBlackScholesRebateEngine.cs +++ b/src/QLNet/Pricingengines/barrier/FdBlackScholesRebateEngine.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,108 +29,113 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class FdBlackScholesRebateEngine : DividendBarrierOption.Engine - { - // Constructor - public FdBlackScholesRebateEngine( - GeneralizedBlackScholesProcess process, - int tGrid = 100, int xGrid = 100, int dampingSteps = 0, - FdmSchemeDesc schemeDesc = null, - bool localVol = false, - double? illegalLocalVolOverwrite = null) - { - process_ = process; - tGrid_ = tGrid; - xGrid_ = xGrid; - dampingSteps_ = dampingSteps; - schemeDesc_ = schemeDesc == null ? new FdmSchemeDesc().Douglas() : schemeDesc; - localVol_ = localVol; - illegalLocalVolOverwrite_ = illegalLocalVolOverwrite; - - process_.registerWith(update); - } - - public override void calculate() { - // 1. Mesher - StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; - double maturity = process_.time(arguments_.exercise.lastDate()); - - double? xMin=null; - double? xMax=null; - if ( arguments_.barrierType == Barrier.Type.DownIn - || arguments_.barrierType == Barrier.Type.DownOut) { - xMin = Math.Log(arguments_.barrier.Value); - } - if ( arguments_.barrierType == Barrier.Type.UpIn - || arguments_.barrierType == Barrier.Type.UpOut) { - xMax = Math.Log(arguments_.barrier.Value); - } - - Fdm1dMesher equityMesher = - new FdmBlackScholesMesher(xGrid_, process_, maturity, - payoff.strike(), xMin, xMax); - - FdmMesher mesher = - new FdmMesherComposite(equityMesher); - - // 2. Calculator - StrikedTypePayoff rebatePayoff = - new CashOrNothingPayoff(Option.Type.Call, 0.0, arguments_.rebate.Value); - FdmInnerValueCalculator calculator = - new FdmLogInnerValue(rebatePayoff, mesher, 0); - - // 3. Step conditions - Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, - () => "only european style option are supported"); - - FdmStepConditionComposite conditions = - FdmStepConditionComposite.vanillaComposite( - arguments_.cashFlow, arguments_.exercise, - mesher, calculator, - process_.riskFreeRate().currentLink().referenceDate(), - process_.riskFreeRate().currentLink().dayCounter()); - - // 4. Boundary conditions - FdmBoundaryConditionSet boundaries = new FdmBoundaryConditionSet(); - if ( arguments_.barrierType == Barrier.Type.DownIn - || arguments_.barrierType == Barrier.Type.DownOut) { - boundaries.Add(new FdmDirichletBoundary(mesher, arguments_.rebate.Value, 0, - FdmDirichletBoundary.Side.Lower)); - - } - if ( arguments_.barrierType == Barrier.Type.UpIn - || arguments_.barrierType == Barrier.Type.UpOut) { - boundaries.Add(new FdmDirichletBoundary(mesher, arguments_.rebate.Value, 0, - FdmDirichletBoundary.Side.Upper)); - } - - // 5. Solver - FdmSolverDesc solverDesc = new FdmSolverDesc(); - solverDesc.mesher = mesher; - solverDesc.bcSet = boundaries; - solverDesc.condition = conditions; - solverDesc.calculator = calculator; - solverDesc.maturity = maturity; - solverDesc.dampingSteps = dampingSteps_; - solverDesc.timeSteps = tGrid_; - - FdmBlackScholesSolver solver = - new FdmBlackScholesSolver( - new Handle(process_), - payoff.strike(), solverDesc, schemeDesc_, - localVol_, illegalLocalVolOverwrite_); - - double spot = process_.x0(); - results_.value = solver.valueAt(spot); - results_.delta = solver.deltaAt(spot); - results_.gamma = solver.gammaAt(spot); - results_.theta = solver.thetaAt(spot); - } - - protected GeneralizedBlackScholesProcess process_; - protected int tGrid_, xGrid_, dampingSteps_; - protected FdmSchemeDesc schemeDesc_; - protected bool localVol_; - protected double? illegalLocalVolOverwrite_; - } + public class FdBlackScholesRebateEngine : DividendBarrierOption.Engine + { + // Constructor + public FdBlackScholesRebateEngine( + GeneralizedBlackScholesProcess process, + int tGrid = 100, int xGrid = 100, int dampingSteps = 0, + FdmSchemeDesc schemeDesc = null, + bool localVol = false, + double? illegalLocalVolOverwrite = null) + { + process_ = process; + tGrid_ = tGrid; + xGrid_ = xGrid; + dampingSteps_ = dampingSteps; + schemeDesc_ = schemeDesc == null ? new FdmSchemeDesc().Douglas() : schemeDesc; + localVol_ = localVol; + illegalLocalVolOverwrite_ = illegalLocalVolOverwrite; + + process_.registerWith(update); + } + + public override void calculate() + { + // 1. Mesher + StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; + double maturity = process_.time(arguments_.exercise.lastDate()); + + double? xMin = null; + double? xMax = null; + if (arguments_.barrierType == Barrier.Type.DownIn + || arguments_.barrierType == Barrier.Type.DownOut) + { + xMin = Math.Log(arguments_.barrier.Value); + } + if (arguments_.barrierType == Barrier.Type.UpIn + || arguments_.barrierType == Barrier.Type.UpOut) + { + xMax = Math.Log(arguments_.barrier.Value); + } + + Fdm1dMesher equityMesher = + new FdmBlackScholesMesher(xGrid_, process_, maturity, + payoff.strike(), xMin, xMax); + + FdmMesher mesher = + new FdmMesherComposite(equityMesher); + + // 2. Calculator + StrikedTypePayoff rebatePayoff = + new CashOrNothingPayoff(Option.Type.Call, 0.0, arguments_.rebate.Value); + FdmInnerValueCalculator calculator = + new FdmLogInnerValue(rebatePayoff, mesher, 0); + + // 3. Step conditions + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, + () => "only european style option are supported"); + + FdmStepConditionComposite conditions = + FdmStepConditionComposite.vanillaComposite( + arguments_.cashFlow, arguments_.exercise, + mesher, calculator, + process_.riskFreeRate().currentLink().referenceDate(), + process_.riskFreeRate().currentLink().dayCounter()); + + // 4. Boundary conditions + FdmBoundaryConditionSet boundaries = new FdmBoundaryConditionSet(); + if (arguments_.barrierType == Barrier.Type.DownIn + || arguments_.barrierType == Barrier.Type.DownOut) + { + boundaries.Add(new FdmDirichletBoundary(mesher, arguments_.rebate.Value, 0, + FdmDirichletBoundary.Side.Lower)); + + } + if (arguments_.barrierType == Barrier.Type.UpIn + || arguments_.barrierType == Barrier.Type.UpOut) + { + boundaries.Add(new FdmDirichletBoundary(mesher, arguments_.rebate.Value, 0, + FdmDirichletBoundary.Side.Upper)); + } + + // 5. Solver + FdmSolverDesc solverDesc = new FdmSolverDesc(); + solverDesc.mesher = mesher; + solverDesc.bcSet = boundaries; + solverDesc.condition = conditions; + solverDesc.calculator = calculator; + solverDesc.maturity = maturity; + solverDesc.dampingSteps = dampingSteps_; + solverDesc.timeSteps = tGrid_; + + FdmBlackScholesSolver solver = + new FdmBlackScholesSolver( + new Handle(process_), + payoff.strike(), solverDesc, schemeDesc_, + localVol_, illegalLocalVolOverwrite_); + + double spot = process_.x0(); + results_.value = solver.valueAt(spot); + results_.delta = solver.deltaAt(spot); + results_.gamma = solver.gammaAt(spot); + results_.theta = solver.thetaAt(spot); + } + + protected GeneralizedBlackScholesProcess process_; + protected int tGrid_, xGrid_, dampingSteps_; + protected FdmSchemeDesc schemeDesc_; + protected bool localVol_; + protected double? illegalLocalVolOverwrite_; + } } diff --git a/src/QLNet/Pricingengines/barrier/VannaVolgaBarrierEngine.cs b/src/QLNet/Pricingengines/barrier/VannaVolgaBarrierEngine.cs index ec1c6d455..2beb1b351 100644 --- a/src/QLNet/Pricingengines/barrier/VannaVolgaBarrierEngine.cs +++ b/src/QLNet/Pricingengines/barrier/VannaVolgaBarrierEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -18,36 +18,36 @@ namespace QLNet { - public class VannaVolgaBarrierEngine : GenericEngine + public class VannaVolgaBarrierEngine : GenericEngine { - public VannaVolgaBarrierEngine( Handle atmVol, - Handle vol25Put, - Handle vol25Call, - Handle spotFX, - Handle domesticTS, - Handle foreignTS, - bool adaptVanDelta = false, - double bsPriceWithSmile = 0.0) + public VannaVolgaBarrierEngine(Handle atmVol, + Handle vol25Put, + Handle vol25Call, + Handle spotFX, + Handle domesticTS, + Handle foreignTS, + bool adaptVanDelta = false, + double bsPriceWithSmile = 0.0) { - atmVol_ = atmVol; - vol25Put_ = vol25Put; - vol25Call_ = vol25Call; + atmVol_ = atmVol; + vol25Put_ = vol25Put; + vol25Call_ = vol25Call; T_ = atmVol_.link.maturity(); - spotFX_ = spotFX; - domesticTS_ = domesticTS; + spotFX_ = spotFX; + domesticTS_ = domesticTS; foreignTS_ = foreignTS; adaptVanDelta_ = adaptVanDelta; bsPriceWithSmile_ = bsPriceWithSmile; - Utils.QL_REQUIRE( vol25Put_.link.delta().IsEqual(-0.25),()=> "25 delta put is required by vanna volga method" ); - Utils.QL_REQUIRE( vol25Call_.link.delta().IsEqual(0.25),()=> "25 delta call is required by vanna volga method" ); + Utils.QL_REQUIRE(vol25Put_.link.delta().IsEqual(-0.25), () => "25 delta put is required by vanna volga method"); + Utils.QL_REQUIRE(vol25Call_.link.delta().IsEqual(0.25), () => "25 delta call is required by vanna volga method"); - Utils.QL_REQUIRE( vol25Put_.link.maturity().IsEqual(vol25Call_.link.maturity()) && - vol25Put_.link.maturity().IsEqual(atmVol_.link.maturity()),()=> - "Maturity of 3 vols are not the same" ); + Utils.QL_REQUIRE(vol25Put_.link.maturity().IsEqual(vol25Call_.link.maturity()) && + vol25Put_.link.maturity().IsEqual(atmVol_.link.maturity()), () => + "Maturity of 3 vols are not the same"); - Utils.QL_REQUIRE( !domesticTS_.empty(),()=> "domestic yield curve is not defined" ); - Utils.QL_REQUIRE( !foreignTS_.empty(),()=> "foreign yield curve is not defined" ); + Utils.QL_REQUIRE(!domesticTS_.empty(), () => "domestic yield curve is not defined"); + Utils.QL_REQUIRE(!foreignTS_.empty(), () => "foreign yield curve is not defined"); atmVol_.registerWith(update); vol25Put_.registerWith(update); @@ -60,6 +60,12 @@ public VannaVolgaBarrierEngine( Handle atmVol, public override void calculate() { + Utils.QL_REQUIRE(arguments_.barrierType == Barrier.Type.UpIn || + arguments_.barrierType == Barrier.Type.UpOut || + arguments_.barrierType == Barrier.Type.DownIn || + arguments_.barrierType == Barrier.Type.DownOut, () => + "Invalid barrier type"); + double sigmaShift_vega = 0.0001; double sigmaShift_volga = 0.0001; double spotShift_delta = 0.0001 * spotFX_.link.value(); @@ -69,9 +75,9 @@ public override void calculate() Handle atmVolQuote = new Handle(new SimpleQuote(atmVol_.link.value())); //used for shift BlackVolTermStructure blackVolTS = new BlackConstantVol(Settings.evaluationDate(), - new NullCalendar(), atmVolQuote, new Actual365Fixed()); - BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(x0Quote,foreignTS_,domesticTS_, - new Handle(blackVolTS)); + new NullCalendar(), atmVolQuote, new Actual365Fixed()); + BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(x0Quote, foreignTS_, domesticTS_, + new Handle(blackVolTS)); IPricingEngine engineBS = new AnalyticBarrierEngine(stochProcess); @@ -85,12 +91,12 @@ public override void calculate() double put25Vol = vol25Put_.link.value(); BlackDeltaCalculator blackDeltaCalculatorPut25 = new BlackDeltaCalculator( - Option.Type.Put, vol25Put_.link.deltaType(), x0Quote.link.value(), + Option.Type.Put, vol25Put_.link.deltaType(), x0Quote.link.value(), domesticTS_.link.discount(T_), foreignTS_.link.discount(T_), put25Vol * Math.Sqrt(T_)); double put25Strike = blackDeltaCalculatorPut25.strikeFromDelta(-0.25); BlackDeltaCalculator blackDeltaCalculatorCall25 = new BlackDeltaCalculator( - Option.Type.Call, vol25Call_.link.deltaType(), x0Quote.link.value(), + Option.Type.Call, vol25Call_.link.deltaType(), x0Quote.link.value(), domesticTS_.link.discount(T_), foreignTS_.link.discount(T_), call25Vol * Math.Sqrt(T_)); double call25Strike = blackDeltaCalculatorCall25.strikeFromDelta(0.25); @@ -104,49 +110,49 @@ public override void calculate() vols.Add(atmVol_.link.value()); strikes.Add(call25Strike); vols.Add(call25Vol); - VannaVolga vannaVolga = new VannaVolga(x0Quote.link.value(), domesticTS_.link.discount(T_), - foreignTS_.link.discount(T_), T_); + VannaVolga vannaVolga = new VannaVolga(x0Quote.link.value(), domesticTS_.link.discount(T_), + foreignTS_.link.discount(T_), T_); Interpolation interpolation = vannaVolga.interpolate(strikes, strikes.Count, vols); interpolation.enableExtrapolation(); StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; double strikeVol = interpolation.value(payoff.strike()); - //vannila option price - double vanillaOption = Utils.blackFormula(payoff.optionType(), payoff.strike(), - x0Quote.link.value()* foreignTS_.link.discount(T_)/ domesticTS_.link.discount(T_), - strikeVol * Math.Sqrt(T_), - domesticTS_.link.discount(T_)); + // Vanilla option price + double vanillaOption = Utils.blackFormula(payoff.optionType(), payoff.strike(), + x0Quote.link.value() * foreignTS_.link.discount(T_) / domesticTS_.link.discount(T_), + strikeVol * Math.Sqrt(T_), + domesticTS_.link.discount(T_)); //spot > barrier up&out 0 - if(x0Quote.link.value() >= arguments_.barrier && arguments_.barrierType == Barrier.Type.UpOut) + if (x0Quote.link.value() >= arguments_.barrier && arguments_.barrierType == Barrier.Type.UpOut) { results_.value = 0.0; - results_.additionalResults["VanillaPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; - results_.additionalResults["BarrierInPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; + results_.additionalResults["VanillaPrice"] = adaptVanDelta_ ? bsPriceWithSmile_ : vanillaOption; + results_.additionalResults["BarrierInPrice"] = adaptVanDelta_ ? bsPriceWithSmile_ : vanillaOption; results_.additionalResults["BarrierOutPrice"] = 0.0; } //spot > barrier up&in vanilla - else if(x0Quote.link.value() >= arguments_.barrier && arguments_.barrierType == Barrier.Type.UpIn) + else if (x0Quote.link.value() >= arguments_.barrier && arguments_.barrierType == Barrier.Type.UpIn) { - results_.value = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; - results_.additionalResults["VanillaPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; - results_.additionalResults["BarrierInPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; + results_.value = adaptVanDelta_ ? bsPriceWithSmile_ : vanillaOption; + results_.additionalResults["VanillaPrice"] = adaptVanDelta_ ? bsPriceWithSmile_ : vanillaOption; + results_.additionalResults["BarrierInPrice"] = adaptVanDelta_ ? bsPriceWithSmile_ : vanillaOption; results_.additionalResults["BarrierOutPrice"] = 0.0; } //spot < barrier down&out 0 - else if(x0Quote.link.value() <= arguments_.barrier && arguments_.barrierType == Barrier.Type.DownOut) + else if (x0Quote.link.value() <= arguments_.barrier && arguments_.barrierType == Barrier.Type.DownOut) { results_.value = 0.0; - results_.additionalResults["VanillaPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; - results_.additionalResults["BarrierInPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; + results_.additionalResults["VanillaPrice"] = adaptVanDelta_ ? bsPriceWithSmile_ : vanillaOption; + results_.additionalResults["BarrierInPrice"] = adaptVanDelta_ ? bsPriceWithSmile_ : vanillaOption; results_.additionalResults["BarrierOutPrice"] = 0.0; } //spot < barrier down&in vanilla - else if(x0Quote.link.value() <= arguments_.barrier && arguments_.barrierType == Barrier.Type.DownIn) + else if (x0Quote.link.value() <= arguments_.barrier && arguments_.barrierType == Barrier.Type.DownIn) { - results_.value = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; - results_.additionalResults["VanillaPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; - results_.additionalResults["BarrierInPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; + results_.value = adaptVanDelta_ ? bsPriceWithSmile_ : vanillaOption; + results_.additionalResults["VanillaPrice"] = adaptVanDelta_ ? bsPriceWithSmile_ : vanillaOption; + results_.additionalResults["BarrierInPrice"] = adaptVanDelta_ ? bsPriceWithSmile_ : vanillaOption; results_.additionalResults["BarrierOutPrice"] = 0.0; } else @@ -154,94 +160,94 @@ public override void calculate() //set up BS barrier option pricing //only calculate out barrier option price // in barrier price = vanilla - out barrier - Barrier.Type barrierTyp; - if(arguments_.barrierType == Barrier.Type.UpOut) - barrierTyp = arguments_.barrierType; - else if(arguments_.barrierType == Barrier.Type.UpIn) - barrierTyp = Barrier.Type.UpOut; - else if(arguments_.barrierType == Barrier.Type.DownOut) - barrierTyp = arguments_.barrierType; + Barrier.Type barrierType; + if (arguments_.barrierType == Barrier.Type.UpOut) + barrierType = arguments_.barrierType; + else if (arguments_.barrierType == Barrier.Type.UpIn) + barrierType = Barrier.Type.UpOut; + else if (arguments_.barrierType == Barrier.Type.DownOut) + barrierType = arguments_.barrierType; else - barrierTyp = Barrier.Type.DownOut; + barrierType = Barrier.Type.DownOut; - BarrierOption barrierOption = new BarrierOption(barrierTyp, - arguments_.barrier.GetValueOrDefault(), - arguments_.rebate.GetValueOrDefault(), - (StrikedTypePayoff)arguments_.payoff, - arguments_.exercise); + BarrierOption barrierOption = new BarrierOption(barrierType, + arguments_.barrier.GetValueOrDefault(), + arguments_.rebate.GetValueOrDefault(), + (StrikedTypePayoff)arguments_.payoff, + arguments_.exercise); barrierOption.setPricingEngine(engineBS); //BS price with atm vol double priceBS = barrierOption.NPV(); - double priceAtmCallBS = Utils.blackFormula(Option.Type.Call,atmStrike, - x0Quote.link.value()* foreignTS_.link.discount(T_)/ domesticTS_.link.discount(T_), - atmVol_.link.value() * Math.Sqrt(T_), - domesticTS_.link.discount(T_)); - double price25CallBS = Utils.blackFormula(Option.Type.Call,call25Strike, - x0Quote.link.value()* foreignTS_.link.discount(T_)/ domesticTS_.link.discount(T_), - atmVol_.link.value() * Math.Sqrt(T_), - domesticTS_.link.discount(T_)); - double price25PutBS = Utils.blackFormula(Option.Type.Put,put25Strike, - x0Quote.link.value()* foreignTS_.link.discount(T_)/ domesticTS_.link.discount(T_), - atmVol_.link.value() * Math.Sqrt(T_), - domesticTS_.link.discount(T_)); + double priceAtmCallBS = Utils.blackFormula(Option.Type.Call, atmStrike, + x0Quote.link.value() * foreignTS_.link.discount(T_) / domesticTS_.link.discount(T_), + atmVol_.link.value() * Math.Sqrt(T_), + domesticTS_.link.discount(T_)); + double price25CallBS = Utils.blackFormula(Option.Type.Call, call25Strike, + x0Quote.link.value() * foreignTS_.link.discount(T_) / domesticTS_.link.discount(T_), + atmVol_.link.value() * Math.Sqrt(T_), + domesticTS_.link.discount(T_)); + double price25PutBS = Utils.blackFormula(Option.Type.Put, put25Strike, + x0Quote.link.value() * foreignTS_.link.discount(T_) / domesticTS_.link.discount(T_), + atmVol_.link.value() * Math.Sqrt(T_), + domesticTS_.link.discount(T_)); //market price - double priceAtmCallMkt = Utils.blackFormula(Option.Type.Call,atmStrike, - x0Quote.link.value()* foreignTS_.link.discount(T_)/ domesticTS_.link.discount(T_), - atmVol_.link.value() * Math.Sqrt(T_), - domesticTS_.link.discount(T_)); + double priceAtmCallMkt = Utils.blackFormula(Option.Type.Call, atmStrike, + x0Quote.link.value() * foreignTS_.link.discount(T_) / domesticTS_.link.discount(T_), + atmVol_.link.value() * Math.Sqrt(T_), + domesticTS_.link.discount(T_)); - double price25CallMkt = Utils.blackFormula(Option.Type.Call,call25Strike, - x0Quote.link.value()* foreignTS_.link.discount(T_)/ domesticTS_.link.discount(T_), - call25Vol * Math.Sqrt(T_), - domesticTS_.link.discount(T_)); - double price25PutMkt = Utils.blackFormula(Option.Type.Put,put25Strike, - x0Quote.link.value()* foreignTS_.link.discount(T_)/ domesticTS_.link.discount(T_), - put25Vol * Math.Sqrt(T_), - domesticTS_.link.discount(T_)); + double price25CallMkt = Utils.blackFormula(Option.Type.Call, call25Strike, + x0Quote.link.value() * foreignTS_.link.discount(T_) / domesticTS_.link.discount(T_), + call25Vol * Math.Sqrt(T_), + domesticTS_.link.discount(T_)); + double price25PutMkt = Utils.blackFormula(Option.Type.Put, put25Strike, + x0Quote.link.value() * foreignTS_.link.discount(T_) / domesticTS_.link.discount(T_), + put25Vol * Math.Sqrt(T_), + domesticTS_.link.discount(T_)); //Analytical Black Scholes formula for vanilla option NormalDistribution norm = new NormalDistribution(); - double d1atm = (Math.Log(x0Quote.link.value()* foreignTS_.link.discount(T_)/ - domesticTS_.link.discount(T_)/atmStrike) - + 0.5*Math.Pow(atmVolQuote.link.value(),2.0) * T_)/ - (atmVolQuote.link.value() * Math.Sqrt(T_)); - double vegaAtm_Analytical = x0Quote.link.value() * norm.value(d1atm) * Math.Sqrt(T_) * - foreignTS_.link.discount(T_); - double vannaAtm_Analytical = vegaAtm_Analytical/x0Quote.link.value() * - (1.0 - d1atm/(atmVolQuote.link.value()*Math.Sqrt(T_))); - double volgaAtm_Analytical = vegaAtm_Analytical * d1atm * (d1atm - atmVolQuote.link.value() * Math.Sqrt(T_))/ - atmVolQuote.link.value(); - - double d125call = (Math.Log(x0Quote.link.value()* foreignTS_.link.discount(T_)/ - domesticTS_.link.discount(T_)/call25Strike) - + 0.5*Math.Pow(atmVolQuote.link.value(),2.0) * T_)/(atmVolQuote.link.value() * Math.Sqrt(T_)); - double vega25Call_Analytical = x0Quote.link.value() * norm.value(d125call) * Math.Sqrt(T_) * - foreignTS_.link.discount(T_); - double vanna25Call_Analytical = vega25Call_Analytical/x0Quote.link.value() * - (1.0 - d125call/(atmVolQuote.link.value()*Math.Sqrt(T_))); - double volga25Call_Analytical = vega25Call_Analytical * d125call * - (d125call - atmVolQuote.link.value() * Math.Sqrt(T_))/atmVolQuote.link.value(); - - double d125Put = (Math.Log(x0Quote.link.value()* foreignTS_.link.discount(T_)/ - domesticTS_.link.discount(T_)/put25Strike) - + 0.5*Math.Pow(atmVolQuote.link.value(),2.0) * T_)/(atmVolQuote.link.value() * Math.Sqrt(T_)); - double vega25Put_Analytical = x0Quote.link.value() * norm.value(d125Put) * Math.Sqrt(T_) * - foreignTS_.link.discount(T_); - double vanna25Put_Analytical = vega25Put_Analytical/x0Quote.link.value() * - (1.0 - d125Put/(atmVolQuote.link.value()*Math.Sqrt(T_))); - double volga25Put_Analytical = vega25Put_Analytical * d125Put * - (d125Put - atmVolQuote.link.value() * Math.Sqrt(T_))/atmVolQuote.link.value(); + double d1atm = (Math.Log(x0Quote.link.value() * foreignTS_.link.discount(T_) / + domesticTS_.link.discount(T_) / atmStrike) + + 0.5 * Math.Pow(atmVolQuote.link.value(), 2.0) * T_) / + (atmVolQuote.link.value() * Math.Sqrt(T_)); + double vegaAtm_Analytical = x0Quote.link.value() * norm.value(d1atm) * Math.Sqrt(T_) * + foreignTS_.link.discount(T_); + double vannaAtm_Analytical = vegaAtm_Analytical / x0Quote.link.value() * + (1.0 - d1atm / (atmVolQuote.link.value() * Math.Sqrt(T_))); + double volgaAtm_Analytical = vegaAtm_Analytical * d1atm * (d1atm - atmVolQuote.link.value() * Math.Sqrt(T_)) / + atmVolQuote.link.value(); + + double d125call = (Math.Log(x0Quote.link.value() * foreignTS_.link.discount(T_) / + domesticTS_.link.discount(T_) / call25Strike) + + 0.5 * Math.Pow(atmVolQuote.link.value(), 2.0) * T_) / (atmVolQuote.link.value() * Math.Sqrt(T_)); + double vega25Call_Analytical = x0Quote.link.value() * norm.value(d125call) * Math.Sqrt(T_) * + foreignTS_.link.discount(T_); + double vanna25Call_Analytical = vega25Call_Analytical / x0Quote.link.value() * + (1.0 - d125call / (atmVolQuote.link.value() * Math.Sqrt(T_))); + double volga25Call_Analytical = vega25Call_Analytical * d125call * + (d125call - atmVolQuote.link.value() * Math.Sqrt(T_)) / atmVolQuote.link.value(); + + double d125Put = (Math.Log(x0Quote.link.value() * foreignTS_.link.discount(T_) / + domesticTS_.link.discount(T_) / put25Strike) + + 0.5 * Math.Pow(atmVolQuote.link.value(), 2.0) * T_) / (atmVolQuote.link.value() * Math.Sqrt(T_)); + double vega25Put_Analytical = x0Quote.link.value() * norm.value(d125Put) * Math.Sqrt(T_) * + foreignTS_.link.discount(T_); + double vanna25Put_Analytical = vega25Put_Analytical / x0Quote.link.value() * + (1.0 - d125Put / (atmVolQuote.link.value() * Math.Sqrt(T_))); + double volga25Put_Analytical = vega25Put_Analytical * d125Put * + (d125Put - atmVolQuote.link.value() * Math.Sqrt(T_)) / atmVolQuote.link.value(); //BS vega ((SimpleQuote)atmVolQuote.currentLink()).setValue(atmVolQuote.link.value() + sigmaShift_vega); barrierOption.recalculate(); - double vegaBarBS = (barrierOption.NPV() - priceBS)/sigmaShift_vega; + double vegaBarBS = (barrierOption.NPV() - priceBS) / sigmaShift_vega; ((SimpleQuote)atmVolQuote.currentLink()).setValue(atmVolQuote.link.value() - sigmaShift_vega);//setback @@ -256,12 +262,12 @@ public override void calculate() //shifted npv ((SimpleQuote)atmVolQuote.currentLink()).setValue(atmVolQuote.link.value() + sigmaShift_vega); barrierOption.recalculate(); - double vegaBarBS2 = (barrierOption.NPV() - priceBS2)/sigmaShift_vega; - double volgaBarBS = (vegaBarBS2 - vegaBarBS)/sigmaShift_volga; + double vegaBarBS2 = (barrierOption.NPV() - priceBS2) / sigmaShift_vega; + double volgaBarBS = (vegaBarBS2 - vegaBarBS) / sigmaShift_volga; - ((SimpleQuote)atmVolQuote.currentLink()).setValue(atmVolQuote.link.value() - - sigmaShift_volga - - sigmaShift_vega);//setback + ((SimpleQuote)atmVolQuote.currentLink()).setValue(atmVolQuote.link.value() + - sigmaShift_volga + - sigmaShift_vega);//setback //BS Delta //base delta @@ -274,7 +280,7 @@ public override void calculate() double priceBS_delta2 = barrierOption.NPV(); ((SimpleQuote)x0Quote.currentLink()).setValue(x0Quote.link.value() + spotShift_delta);//set back - double deltaBar1 = (priceBS_delta1 - priceBS_delta2)/(2.0*spotShift_delta); + double deltaBar1 = (priceBS_delta1 - priceBS_delta2) / (2.0 * spotShift_delta); //shifted delta ((SimpleQuote)atmVolQuote.currentLink()).setValue(atmVolQuote.link.value() + sigmaShift_vanna);//shift sigma @@ -287,27 +293,27 @@ public override void calculate() priceBS_delta2 = barrierOption.NPV(); ((SimpleQuote)x0Quote.currentLink()).setValue(x0Quote.link.value() + spotShift_delta);//set back - double deltaBar2 = (priceBS_delta1 - priceBS_delta2)/(2.0*spotShift_delta); + double deltaBar2 = (priceBS_delta1 - priceBS_delta2) / (2.0 * spotShift_delta); - double vannaBarBS = (deltaBar2 - deltaBar1)/sigmaShift_vanna; + double vannaBarBS = (deltaBar2 - deltaBar1) / sigmaShift_vanna; ((SimpleQuote)atmVolQuote.currentLink()).setValue(atmVolQuote.link.value() - sigmaShift_vanna);//set back //Matrix - Matrix A = new Matrix(3,3,0.0); + Matrix A = new Matrix(3, 3, 0.0); //analytical - A[0,0] = vegaAtm_Analytical; - A[0,1] = vega25Call_Analytical; - A[0,2] = vega25Put_Analytical; - A[1,0] = vannaAtm_Analytical; - A[1,1] = vanna25Call_Analytical; - A[1,2] = vanna25Put_Analytical; - A[2,0] = volgaAtm_Analytical; - A[2,1] = volga25Call_Analytical; - A[2,2] = volga25Put_Analytical; - - Vector b = new Vector(3,0.0); + A[0, 0] = vegaAtm_Analytical; + A[0, 1] = vega25Call_Analytical; + A[0, 2] = vega25Put_Analytical; + A[1, 0] = vannaAtm_Analytical; + A[1, 1] = vanna25Call_Analytical; + A[1, 2] = vanna25Put_Analytical; + A[2, 0] = volgaAtm_Analytical; + A[2, 1] = volga25Call_Analytical; + A[2, 2] = volga25Put_Analytical; + + Vector b = new Vector(3, 0.0); b[0] = vegaBarBS; b[1] = vannaBarBS; b[2] = volgaBarBS; @@ -318,33 +324,33 @@ public override void calculate() //touch probability CumulativeNormalDistribution cnd = new CumulativeNormalDistribution(); - double mu = domesticTS_.link.zeroRate(T_, Compounding.Continuous).value() - - foreignTS_.link.zeroRate(T_, Compounding.Continuous).value() - - Math.Pow(atmVol_.link.value(), 2.0)/2.0; - double h2 = (Math.Log(arguments_.barrier.GetValueOrDefault()/x0Quote.link.value()) + mu*T_)/ - (atmVol_.link.value()*Math.Sqrt(T_)); - double h2Prime = (Math.Log(x0Quote.link.value()/arguments_.barrier.GetValueOrDefault()) + mu*T_)/ - (atmVol_.link.value()*Math.Sqrt(T_)); + double mu = domesticTS_.link.zeroRate(T_, Compounding.Continuous).value() - + foreignTS_.link.zeroRate(T_, Compounding.Continuous).value() - + Math.Pow(atmVol_.link.value(), 2.0) / 2.0; + double h2 = (Math.Log(arguments_.barrier.GetValueOrDefault() / x0Quote.link.value()) + mu * T_) / + (atmVol_.link.value() * Math.Sqrt(T_)); + double h2Prime = (Math.Log(x0Quote.link.value() / arguments_.barrier.GetValueOrDefault()) + mu * T_) / + (atmVol_.link.value() * Math.Sqrt(T_)); double probTouch = 0.0; - if(arguments_.barrierType == Barrier.Type.UpIn || arguments_.barrierType == Barrier.Type.UpOut) - probTouch = cnd.value(h2Prime) + Math.Pow(arguments_.barrier.GetValueOrDefault()/x0Quote.link.value(), - 2.0*mu/Math.Pow(atmVol_.link.value(), 2.0))*cnd.value(-h2); + if (arguments_.barrierType == Barrier.Type.UpIn || arguments_.barrierType == Barrier.Type.UpOut) + probTouch = cnd.value(h2Prime) + Math.Pow(arguments_.barrier.GetValueOrDefault() / x0Quote.link.value(), + 2.0 * mu / Math.Pow(atmVol_.link.value(), 2.0)) * cnd.value(-h2); else - probTouch = cnd.value(-h2Prime) + Math.Pow(arguments_.barrier.GetValueOrDefault()/x0Quote.link.value(), - 2.0*mu/Math.Pow(atmVol_.link.value(), 2.0))*cnd.value(h2); + probTouch = cnd.value(-h2Prime) + Math.Pow(arguments_.barrier.GetValueOrDefault() / x0Quote.link.value(), + 2.0 * mu / Math.Pow(atmVol_.link.value(), 2.0)) * cnd.value(h2); double p_survival = 1.0 - probTouch; double lambda = p_survival ; - double adjust = q[0]*(priceAtmCallMkt - priceAtmCallBS) - + q[1]*(price25CallMkt - price25CallBS) - + q[2]*(price25PutMkt - price25PutBS); - double outPrice = priceBS + lambda*adjust;// + double adjust = q[0] * (priceAtmCallMkt - priceAtmCallBS) + + q[1] * (price25CallMkt - price25CallBS) + + q[2] * (price25PutMkt - price25PutBS); + double outPrice = priceBS + lambda * adjust; // double inPrice; //adapt Vanilla delta - if(adaptVanDelta_ == true) + if (adaptVanDelta_ == true) { - outPrice += lambda*(bsPriceWithSmile_ - vanillaOption); + outPrice += lambda * (bsPriceWithSmile_ - vanillaOption); //capfloored by (0, vanilla) outPrice = Math.Max(0.0, Math.Min(bsPriceWithSmile_, outPrice)); inPrice = bsPriceWithSmile_ - outPrice; @@ -352,11 +358,11 @@ public override void calculate() else { //capfloored by (0, vanilla) - outPrice = Math.Max(0.0, Math.Min(vanillaOption , outPrice)); + outPrice = Math.Max(0.0, Math.Min(vanillaOption, outPrice)); inPrice = vanillaOption - outPrice; } - if(arguments_.barrierType == Barrier.Type.DownOut || arguments_.barrierType == Barrier.Type.UpOut) + if (arguments_.barrierType == Barrier.Type.DownOut || arguments_.barrierType == Barrier.Type.UpOut) results_.value = outPrice; else results_.value = inPrice; diff --git a/src/QLNet/Pricingengines/barrier/VannaVolgaDoubleBarrierEngine.cs b/src/QLNet/Pricingengines/barrier/VannaVolgaDoubleBarrierEngine.cs index ff905c740..3870b6f96 100644 --- a/src/QLNet/Pricingengines/barrier/VannaVolgaDoubleBarrierEngine.cs +++ b/src/QLNet/Pricingengines/barrier/VannaVolgaDoubleBarrierEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -18,44 +18,44 @@ namespace QLNet { - public class VannaVolgaDoubleBarrierEngine : GenericEngine + public class VannaVolgaDoubleBarrierEngine : GenericEngine { - public delegate IPricingEngine GetOriginalEngine( GeneralizedBlackScholesProcess process, int series ); - - public VannaVolgaDoubleBarrierEngine( Handle atmVol, - Handle vol25Put, - Handle vol25Call, - Handle spotFX, - Handle domesticTS, - Handle foreignTS, - GetOriginalEngine getEngine, - bool adaptVanDelta = false, - double bsPriceWithSmile = 0.0, - int series = 5 ) - : base() - + public delegate IPricingEngine GetOriginalEngine(GeneralizedBlackScholesProcess process, int series); + + public VannaVolgaDoubleBarrierEngine(Handle atmVol, + Handle vol25Put, + Handle vol25Call, + Handle spotFX, + Handle domesticTS, + Handle foreignTS, + GetOriginalEngine getEngine, + bool adaptVanDelta = false, + double bsPriceWithSmile = 0.0, + int series = 5) + : base() + { - atmVol_ = atmVol; - vol25Put_ = vol25Put; - vol25Call_ = vol25Call; + atmVol_ = atmVol; + vol25Put_ = vol25Put; + vol25Call_ = vol25Call; T_ = atmVol_.link.maturity(); - spotFX_ = spotFX; - domesticTS_ = domesticTS; + spotFX_ = spotFX; + domesticTS_ = domesticTS; foreignTS_ = foreignTS; - adaptVanDelta_ = adaptVanDelta; + adaptVanDelta_ = adaptVanDelta; bsPriceWithSmile_ = bsPriceWithSmile; series_ = series; getOriginalEngine_ = getEngine; - Utils.QL_REQUIRE(vol25Put_.link.delta().IsEqual(-0.25) ,()=> "25 delta put is required by vanna volga method"); - Utils.QL_REQUIRE(vol25Call_.link.delta().IsEqual(0.25),()=> "25 delta call is required by vanna volga method"); + Utils.QL_REQUIRE(vol25Put_.link.delta().IsEqual(-0.25), () => "25 delta put is required by vanna volga method"); + Utils.QL_REQUIRE(vol25Call_.link.delta().IsEqual(0.25), () => "25 delta call is required by vanna volga method"); - Utils.QL_REQUIRE(vol25Put_.link.maturity().IsEqual(vol25Call_.link.maturity()) && - vol25Put_.link.maturity().IsEqual(atmVol_.link.maturity()),()=> + Utils.QL_REQUIRE(vol25Put_.link.maturity().IsEqual(vol25Call_.link.maturity()) && + vol25Put_.link.maturity().IsEqual(atmVol_.link.maturity()), () => "Maturity of 3 vols are not the same"); - Utils.QL_REQUIRE(!domesticTS_.empty(),()=> "domestic yield curve is not defined"); - Utils.QL_REQUIRE(!foreignTS_.empty(),()=> "foreign yield curve is not defined"); + Utils.QL_REQUIRE(!domesticTS_.empty(), () => "domestic yield curve is not defined"); + Utils.QL_REQUIRE(!foreignTS_.empty(), () => "foreign yield curve is not defined"); atmVol_.registerWith(update); vol25Put_.registerWith(update); @@ -65,33 +65,33 @@ public VannaVolgaDoubleBarrierEngine( Handle atmVol, foreignTS_.registerWith(update); } - public override void calculate() + public override void calculate() { double sigmaShift_vega = 0.001; double sigmaShift_volga = 0.0001; double spotShift_delta = 0.0001 * spotFX_.link.value(); double sigmaShift_vanna = 0.0001; - Utils.QL_REQUIRE(arguments_.barrierType==DoubleBarrier.Type.KnockIn || - arguments_.barrierType==DoubleBarrier.Type.KnockOut, ()=> - "Only same type barrier supported"); + Utils.QL_REQUIRE(arguments_.barrierType == DoubleBarrier.Type.KnockIn || + arguments_.barrierType == DoubleBarrier.Type.KnockOut, () => + "Only same type barrier supported"); - Handle x0Quote = new Handle( new SimpleQuote(spotFX_.link.value())); + Handle x0Quote = new Handle(new SimpleQuote(spotFX_.link.value())); Handle atmVolQuote = new Handle(new SimpleQuote(atmVol_.link.value())); - BlackVolTermStructure blackVolTS = new BlackConstantVol( Settings.evaluationDate(), - new NullCalendar(), atmVolQuote, new Actual365Fixed()); - - BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(x0Quote,foreignTS_,domesticTS_, - new Handle(blackVolTS)); + BlackVolTermStructure blackVolTS = new BlackConstantVol(Settings.evaluationDate(), + new NullCalendar(), atmVolQuote, new Actual365Fixed()); + + BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(x0Quote, foreignTS_, domesticTS_, + new Handle(blackVolTS)); - IPricingEngine engineBS = getOriginalEngine_( stochProcess, series_ ); + IPricingEngine engineBS = getOriginalEngine_(stochProcess, series_); BlackDeltaCalculator blackDeltaCalculatorAtm = new BlackDeltaCalculator( Option.Type.Call, atmVol_.link.deltaType(), x0Quote.link.value(), domesticTS_.link.discount(T_), foreignTS_.link.discount(T_), atmVol_.link.value() * Math.Sqrt(T_)); - + double atmStrike = blackDeltaCalculatorAtm.atmStrike(atmVol_.link.atmType()); double call25Vol = vol25Call_.link.value(); @@ -116,35 +116,35 @@ public override void calculate() vols.Add(atmVol_.link.value()); strikes.Add(call25Strike); vols.Add(call25Vol); - VannaVolga vannaVolga = new VannaVolga(x0Quote.link.value(), foreignTS_.link.discount(T_), - foreignTS_.link.discount(T_), T_); + VannaVolga vannaVolga = new VannaVolga(x0Quote.link.value(), foreignTS_.link.discount(T_), + foreignTS_.link.discount(T_), T_); Interpolation interpolation = vannaVolga.interpolate(strikes, strikes.Count, vols); interpolation.enableExtrapolation(); StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; - Utils.QL_REQUIRE(payoff!=null, ()=> "invalid payoff"); + Utils.QL_REQUIRE(payoff != null, () => "invalid payoff"); double strikeVol = interpolation.value(payoff.strike()); - //vannila option price + // Vanilla option price double vanillaOption = Utils.blackFormula(payoff.optionType(), payoff.strike(), - x0Quote.link.value()* foreignTS_.link.discount(T_)/ domesticTS_.link.discount(T_), - strikeVol * Math.Sqrt(T_), - domesticTS_.link.discount(T_)); + x0Quote.link.value() * foreignTS_.link.discount(T_) / domesticTS_.link.discount(T_), + strikeVol * Math.Sqrt(T_), + domesticTS_.link.discount(T_)); //already out - if((x0Quote.link.value() > arguments_.barrier_hi || x0Quote.link.value() < arguments_.barrier_lo) - && arguments_.barrierType == DoubleBarrier.Type.KnockOut) + if ((x0Quote.link.value() > arguments_.barrier_hi || x0Quote.link.value() < arguments_.barrier_lo) + && arguments_.barrierType == DoubleBarrier.Type.KnockOut) { results_.value = 0.0; - results_.additionalResults["VanillaPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; - results_.additionalResults["BarrierInPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; + results_.additionalResults["VanillaPrice"] = adaptVanDelta_ ? bsPriceWithSmile_ : vanillaOption; + results_.additionalResults["BarrierInPrice"] = adaptVanDelta_ ? bsPriceWithSmile_ : vanillaOption; results_.additionalResults["BarrierOutPrice"] = 0.0; } //already in - else if((x0Quote.link.value() > arguments_.barrier_hi || x0Quote.link.value() < arguments_.barrier_lo) + else if ((x0Quote.link.value() > arguments_.barrier_hi || x0Quote.link.value() < arguments_.barrier_lo) && arguments_.barrierType == DoubleBarrier.Type.KnockIn) { - results_.value = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; - results_.additionalResults["VanillaPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; - results_.additionalResults["BarrierInPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; + results_.value = adaptVanDelta_ ? bsPriceWithSmile_ : vanillaOption; + results_.additionalResults["VanillaPrice"] = adaptVanDelta_ ? bsPriceWithSmile_ : vanillaOption; + results_.additionalResults["BarrierInPrice"] = adaptVanDelta_ ? bsPriceWithSmile_ : vanillaOption; results_.additionalResults["BarrierOutPrice"] = 0.0; } else @@ -153,7 +153,7 @@ public override void calculate() //only calculate out barrier option price // in barrier price = vanilla - out barrier DoubleBarrierOption doubleBarrierOption = new DoubleBarrierOption( - arguments_.barrierType, + DoubleBarrier.Type.KnockOut, arguments_.barrier_lo.GetValueOrDefault(), arguments_.barrier_hi.GetValueOrDefault(), arguments_.rebate.GetValueOrDefault(), @@ -165,58 +165,58 @@ public override void calculate() //BS price double priceBS = doubleBarrierOption.NPV(); - double priceAtmCallBS = Utils.blackFormula(Option.Type.Call,atmStrike, - x0Quote.link.value()* foreignTS_.link.discount(T_)/ domesticTS_.link.discount(T_), - atmVol_.link.value() * Math.Sqrt(T_), - domesticTS_.link.discount(T_)); - double price25CallBS = Utils.blackFormula(Option.Type.Call,call25Strike, - x0Quote.link.value()* foreignTS_.link.discount(T_)/ domesticTS_.link.discount(T_), - atmVol_.link.value() * Math.Sqrt(T_), - domesticTS_.link.discount(T_)); - double price25PutBS = Utils.blackFormula(Option.Type.Put,put25Strike, - x0Quote.link.value()* foreignTS_.link.discount(T_)/ domesticTS_.link.discount(T_), - atmVol_.link.value() * Math.Sqrt(T_), - domesticTS_.link.discount(T_)); + double priceAtmCallBS = Utils.blackFormula(Option.Type.Call, atmStrike, + x0Quote.link.value() * foreignTS_.link.discount(T_) / domesticTS_.link.discount(T_), + atmVol_.link.value() * Math.Sqrt(T_), + domesticTS_.link.discount(T_)); + double price25CallBS = Utils.blackFormula(Option.Type.Call, call25Strike, + x0Quote.link.value() * foreignTS_.link.discount(T_) / domesticTS_.link.discount(T_), + atmVol_.link.value() * Math.Sqrt(T_), + domesticTS_.link.discount(T_)); + double price25PutBS = Utils.blackFormula(Option.Type.Put, put25Strike, + x0Quote.link.value() * foreignTS_.link.discount(T_) / domesticTS_.link.discount(T_), + atmVol_.link.value() * Math.Sqrt(T_), + domesticTS_.link.discount(T_)); //market price - double priceAtmCallMkt = Utils.blackFormula(Option.Type.Call,atmStrike, - x0Quote.link.value()* foreignTS_.link.discount(T_)/ domesticTS_.link.discount(T_), - atmVol_.link.value() * Math.Sqrt(T_), - domesticTS_.link.discount(T_)); - double price25CallMkt = Utils.blackFormula(Option.Type.Call,call25Strike, - x0Quote.link.value()* foreignTS_.link.discount(T_)/ domesticTS_.link.discount(T_), - call25Vol * Math.Sqrt(T_), - domesticTS_.link.discount(T_)); - double price25PutMkt = Utils.blackFormula(Option.Type.Put,put25Strike, - x0Quote.link.value()* foreignTS_.link.discount(T_)/ domesticTS_.link.discount(T_), - put25Vol * Math.Sqrt(T_), - domesticTS_.link.discount(T_)); + double priceAtmCallMkt = Utils.blackFormula(Option.Type.Call, atmStrike, + x0Quote.link.value() * foreignTS_.link.discount(T_) / domesticTS_.link.discount(T_), + atmVol_.link.value() * Math.Sqrt(T_), + domesticTS_.link.discount(T_)); + double price25CallMkt = Utils.blackFormula(Option.Type.Call, call25Strike, + x0Quote.link.value() * foreignTS_.link.discount(T_) / domesticTS_.link.discount(T_), + call25Vol * Math.Sqrt(T_), + domesticTS_.link.discount(T_)); + double price25PutMkt = Utils.blackFormula(Option.Type.Put, put25Strike, + x0Quote.link.value() * foreignTS_.link.discount(T_) / domesticTS_.link.discount(T_), + put25Vol * Math.Sqrt(T_), + domesticTS_.link.discount(T_)); //Analytical Black Scholes formula NormalDistribution norm = new NormalDistribution(); - double d1atm = (Math.Log(x0Quote.link.value()* foreignTS_.link.discount(T_)/ domesticTS_.link.discount(T_)/atmStrike) - + 0.5*Math.Pow(atmVolQuote.link.value(),2.0) * T_)/(atmVolQuote.link.value() * Math.Sqrt(T_)); + double d1atm = (Math.Log(x0Quote.link.value() * foreignTS_.link.discount(T_) / domesticTS_.link.discount(T_) / atmStrike) + + 0.5 * Math.Pow(atmVolQuote.link.value(), 2.0) * T_) / (atmVolQuote.link.value() * Math.Sqrt(T_)); double vegaAtm_Analytical = x0Quote.link.value() * norm.value(d1atm) * Math.Sqrt(T_) * foreignTS_.link.discount(T_); - double vannaAtm_Analytical = vegaAtm_Analytical/x0Quote.link.value() *(1.0 - d1atm/(atmVolQuote.link.value()*Math.Sqrt(T_))); - double volgaAtm_Analytical = vegaAtm_Analytical * d1atm * (d1atm - atmVolQuote.link.value() * Math.Sqrt(T_))/atmVolQuote.link.value(); + double vannaAtm_Analytical = vegaAtm_Analytical / x0Quote.link.value() * (1.0 - d1atm / (atmVolQuote.link.value() * Math.Sqrt(T_))); + double volgaAtm_Analytical = vegaAtm_Analytical * d1atm * (d1atm - atmVolQuote.link.value() * Math.Sqrt(T_)) / atmVolQuote.link.value(); - double d125call = (Math.Log(x0Quote.link.value()* foreignTS_.link.discount(T_)/ domesticTS_.link.discount(T_)/call25Strike) - + 0.5*Math.Pow(atmVolQuote.link.value(),2.0) * T_)/(atmVolQuote.link.value() * Math.Sqrt(T_)); + double d125call = (Math.Log(x0Quote.link.value() * foreignTS_.link.discount(T_) / domesticTS_.link.discount(T_) / call25Strike) + + 0.5 * Math.Pow(atmVolQuote.link.value(), 2.0) * T_) / (atmVolQuote.link.value() * Math.Sqrt(T_)); double vega25Call_Analytical = x0Quote.link.value() * norm.value(d125call) * Math.Sqrt(T_) * foreignTS_.link.discount(T_); - double vanna25Call_Analytical = vega25Call_Analytical/x0Quote.link.value() *(1.0 - d125call/(atmVolQuote.link.value()*Math.Sqrt(T_))); - double volga25Call_Analytical = vega25Call_Analytical * d125call * (d125call - atmVolQuote.link.value() * Math.Sqrt(T_))/atmVolQuote.link.value(); + double vanna25Call_Analytical = vega25Call_Analytical / x0Quote.link.value() * (1.0 - d125call / (atmVolQuote.link.value() * Math.Sqrt(T_))); + double volga25Call_Analytical = vega25Call_Analytical * d125call * (d125call - atmVolQuote.link.value() * Math.Sqrt(T_)) / atmVolQuote.link.value(); - double d125Put = (Math.Log(x0Quote.link.value()* foreignTS_.link.discount(T_)/ domesticTS_.link.discount(T_)/put25Strike) - + 0.5*Math.Pow(atmVolQuote.link.value(),2.0) * T_)/(atmVolQuote.link.value() * Math.Sqrt(T_)); + double d125Put = (Math.Log(x0Quote.link.value() * foreignTS_.link.discount(T_) / domesticTS_.link.discount(T_) / put25Strike) + + 0.5 * Math.Pow(atmVolQuote.link.value(), 2.0) * T_) / (atmVolQuote.link.value() * Math.Sqrt(T_)); double vega25Put_Analytical = x0Quote.link.value() * norm.value(d125Put) * Math.Sqrt(T_) * foreignTS_.link.discount(T_); - double vanna25Put_Analytical = vega25Put_Analytical/x0Quote.link.value() *(1.0 - d125Put/(atmVolQuote.link.value()*Math.Sqrt(T_))); - double volga25Put_Analytical = vega25Put_Analytical * d125Put * (d125Put - atmVolQuote.link.value() * Math.Sqrt(T_))/atmVolQuote.link.value(); + double vanna25Put_Analytical = vega25Put_Analytical / x0Quote.link.value() * (1.0 - d125Put / (atmVolQuote.link.value() * Math.Sqrt(T_))); + double volga25Put_Analytical = vega25Put_Analytical * d125Put * (d125Put - atmVolQuote.link.value() * Math.Sqrt(T_)) / atmVolQuote.link.value(); //BS vega ((SimpleQuote)atmVolQuote.currentLink()).setValue(atmVolQuote.link.value() + sigmaShift_vega); doubleBarrierOption.recalculate(); - double vegaBarBS = (doubleBarrierOption.NPV() - priceBS)/sigmaShift_vega; + double vegaBarBS = (doubleBarrierOption.NPV() - priceBS) / sigmaShift_vega; ((SimpleQuote)atmVolQuote.currentLink()).setValue(atmVolQuote.link.value() - sigmaShift_vega);//setback //BS volga @@ -230,11 +230,11 @@ public override void calculate() //shifted npv ((SimpleQuote)atmVolQuote.currentLink()).setValue(atmVolQuote.link.value() + sigmaShift_vega); doubleBarrierOption.recalculate(); - double vegaBarBS2 = (doubleBarrierOption.NPV() - priceBS2)/sigmaShift_vega; - double volgaBarBS = (vegaBarBS2 - vegaBarBS)/sigmaShift_volga; + double vegaBarBS2 = (doubleBarrierOption.NPV() - priceBS2) / sigmaShift_vega; + double volgaBarBS = (vegaBarBS2 - vegaBarBS) / sigmaShift_volga; ((SimpleQuote)atmVolQuote.currentLink()).setValue(atmVolQuote.link.value() - - sigmaShift_volga - - sigmaShift_vega);//setback + - sigmaShift_volga + - sigmaShift_vega);//setback //BS Delta //base delta @@ -247,7 +247,7 @@ public override void calculate() double priceBS_delta2 = doubleBarrierOption.NPV(); ((SimpleQuote)x0Quote.currentLink()).setValue(x0Quote.link.value() + spotShift_delta);//set back - double deltaBar1 = (priceBS_delta1 - priceBS_delta2)/(2.0*spotShift_delta); + double deltaBar1 = (priceBS_delta1 - priceBS_delta2) / (2.0 * spotShift_delta); //shifted vanna ((SimpleQuote)atmVolQuote.currentLink()).setValue(atmVolQuote.link.value() + sigmaShift_vanna);//shift sigma @@ -261,27 +261,27 @@ public override void calculate() priceBS_delta2 = doubleBarrierOption.NPV(); ((SimpleQuote)x0Quote.currentLink()).setValue(x0Quote.link.value() + spotShift_delta);//set back - double deltaBar2 = (priceBS_delta1 - priceBS_delta2)/(2.0*spotShift_delta); + double deltaBar2 = (priceBS_delta1 - priceBS_delta2) / (2.0 * spotShift_delta); - double vannaBarBS = (deltaBar2 - deltaBar1)/sigmaShift_vanna; + double vannaBarBS = (deltaBar2 - deltaBar1) / sigmaShift_vanna; ((SimpleQuote)atmVolQuote.currentLink()).setValue(atmVolQuote.link.value() - sigmaShift_vanna);//set back //Matrix - Matrix A = new Matrix(3,3,0.0); + Matrix A = new Matrix(3, 3, 0.0); //analytical - A[0,0] = vegaAtm_Analytical; - A[0,1] = vega25Call_Analytical; - A[0,2] = vega25Put_Analytical; - A[1,0] = vannaAtm_Analytical; - A[1,1] = vanna25Call_Analytical; - A[1,2] = vanna25Put_Analytical; - A[2,0] = volgaAtm_Analytical; - A[2,1] = volga25Call_Analytical; - A[2,2] = volga25Put_Analytical; - - Vector b = new Vector(3,0.0); + A[0, 0] = vegaAtm_Analytical; + A[0, 1] = vega25Call_Analytical; + A[0, 2] = vega25Put_Analytical; + A[1, 0] = vannaAtm_Analytical; + A[1, 1] = vanna25Call_Analytical; + A[1, 2] = vanna25Put_Analytical; + A[2, 0] = volgaAtm_Analytical; + A[2, 1] = volga25Call_Analytical; + A[2, 2] = volga25Put_Analytical; + + Vector b = new Vector(3, 0.0); b[0] = vegaBarBS; b[1] = vannaBarBS; b[2] = volgaBarBS; @@ -289,57 +289,59 @@ public override void calculate() double H = arguments_.barrier_hi.GetValueOrDefault(); double L = arguments_.barrier_lo.GetValueOrDefault(); - double theta_tilt_minus = ((domesticTS_.link.zeroRate(T_, Compounding.Continuous).value() - - foreignTS_.link.zeroRate(T_, Compounding.Continuous).value())/ - atmVol_.link.value() - atmVol_.link.value()/2.0)*Math.Sqrt(T_); - double h = 1.0/atmVol_.link.value() * Math.Log(H/x0Quote.link.value())/Math.Sqrt(T_); - double l = 1.0/atmVol_.link.value() * Math.Log(L/x0Quote.link.value())/Math.Sqrt(T_); + double theta_tilt_minus = ((domesticTS_.link.zeroRate(T_, Compounding.Continuous).value() - + foreignTS_.link.zeroRate(T_, Compounding.Continuous).value()) / + atmVol_.link.value() - atmVol_.link.value() / 2.0) * Math.Sqrt(T_); + double h = 1.0 / atmVol_.link.value() * Math.Log(H / x0Quote.link.value()) / Math.Sqrt(T_); + double l = 1.0 / atmVol_.link.value() * Math.Log(L / x0Quote.link.value()) / Math.Sqrt(T_); CumulativeNormalDistribution cnd = new CumulativeNormalDistribution(); double doubleNoTouch = 0.0; - for(int j = -series_; j< series_;j++ ) + for (int j = -series_; j < series_; j++) { - double e_minus = 2*j*(h-l) - theta_tilt_minus; - doubleNoTouch += Math.Exp(-2.0*j*theta_tilt_minus*(h-l))*(cnd.value(h+e_minus) - cnd.value(l+e_minus)) - - Math.Exp(-2.0*j*theta_tilt_minus*(h-l)+2.0*theta_tilt_minus*h)* - (cnd.value(h-2.0*h+e_minus) - cnd.value(l-2.0*h+e_minus)); + double e_minus = 2 * j * (h - l) - theta_tilt_minus; + doubleNoTouch += Math.Exp(-2.0 * j * theta_tilt_minus * (h - l)) * (cnd.value(h + e_minus) - cnd.value(l + e_minus)) + - Math.Exp(-2.0 * j * theta_tilt_minus * (h - l) + 2.0 * theta_tilt_minus * h) * + (cnd.value(h - 2.0 * h + e_minus) - cnd.value(l - 2.0 * h + e_minus)); } double p_survival = doubleNoTouch; double lambda = p_survival ; - double adjust = q[0]*(priceAtmCallMkt - priceAtmCallBS) - + q[1]*(price25CallMkt - price25CallBS) - + q[2]*(price25PutMkt - price25PutBS); - double outPrice = priceBS + lambda*adjust;// + double adjust = q[0] * (priceAtmCallMkt - priceAtmCallBS) + + q[1] * (price25CallMkt - price25CallBS) + + q[2] * (price25PutMkt - price25PutBS); + double outPrice = priceBS + lambda * adjust; // double inPrice; //adapt Vanilla delta - if(adaptVanDelta_ == true){ - outPrice += lambda*(bsPriceWithSmile_ - vanillaOption); + if (adaptVanDelta_ == true) + { + outPrice += lambda * (bsPriceWithSmile_ - vanillaOption); //capfloored by (0, vanilla) outPrice = Math.Max(0.0, Math.Min(bsPriceWithSmile_, outPrice)); inPrice = bsPriceWithSmile_ - outPrice; } - else{ + else + { //capfloored by (0, vanilla) - outPrice = Math.Max(0.0, Math.Min(vanillaOption , outPrice)); + outPrice = Math.Max(0.0, Math.Min(vanillaOption, outPrice)); inPrice = vanillaOption - outPrice; } - if(arguments_.barrierType == DoubleBarrier.Type.KnockOut) + if (arguments_.barrierType == DoubleBarrier.Type.KnockOut) results_.value = outPrice; else results_.value = inPrice; - + results_.additionalResults["VanillaPrice"] = vanillaOption; results_.additionalResults["BarrierInPrice"] = inPrice; results_.additionalResults["BarrierOutPrice"] = outPrice; results_.additionalResults["lambda"] = lambda; - + } } - + private Handle atmVol_; private Handle vol25Put_; private Handle vol25Call_; diff --git a/src/QLNet/Pricingengines/barrier/WulinYongDoubleBarrierEngine.cs b/src/QLNet/Pricingengines/barrier/WulinYongDoubleBarrierEngine.cs index 2d3515014..5abbda026 100644 --- a/src/QLNet/Pricingengines/barrier/WulinYongDoubleBarrierEngine.cs +++ b/src/QLNet/Pricingengines/barrier/WulinYongDoubleBarrierEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -28,7 +28,7 @@ reproducing results available in literature. */ public class WulinYongDoubleBarrierEngine : DoubleBarrierOption.Engine { - public WulinYongDoubleBarrierEngine(GeneralizedBlackScholesProcess process,int series = 5) + public WulinYongDoubleBarrierEngine(GeneralizedBlackScholesProcess process, int series = 5) { process_ = process; series_ = series; @@ -39,18 +39,18 @@ public WulinYongDoubleBarrierEngine(GeneralizedBlackScholesProcess process,int s public override void calculate() { PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; - Utils.QL_REQUIRE(payoff!=null,()=> "non-plain payoff given"); - Utils.QL_REQUIRE(payoff.strike()>0.0,()=> "strike must be positive"); + Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); + Utils.QL_REQUIRE(payoff.strike() > 0.0, () => "strike must be positive"); double K = payoff.strike(); double S = process_.x0(); - Utils.QL_REQUIRE(S >= 0.0,()=> "negative or null underlying given"); - Utils.QL_REQUIRE(!triggered(S),()=> "barrier touched"); + Utils.QL_REQUIRE(S >= 0.0, () => "negative or null underlying given"); + Utils.QL_REQUIRE(!triggered(S), () => "barrier touched"); DoubleBarrier.Type barrierType = arguments_.barrierType; - Utils.QL_REQUIRE(barrierType == DoubleBarrier.Type.KnockOut || - barrierType == DoubleBarrier.Type.KnockIn,()=> - "only KnockIn and KnockOut options supported"); + Utils.QL_REQUIRE(barrierType == DoubleBarrier.Type.KnockOut || + barrierType == DoubleBarrier.Type.KnockIn, () => + "only KnockIn and KnockOut options supported"); double L = arguments_.barrier_lo.GetValueOrDefault(); double H = arguments_.barrier_hi.GetValueOrDefault(); @@ -62,8 +62,8 @@ public override void calculate() double rf = dividendYield(); double df = dividendDiscount(); double vol = volatility(); - double mu = rd - rf - vol*vol/2.0; - double sgn = mu > 0 ? 1.0 :(mu < 0 ? -1.0: 0.0); + double mu = rd - rf - vol * vol / 2.0; + double sgn = mu > 0 ? 1.0 : (mu < 0 ? -1.0 : 0.0); //rebate double R_L = arguments_.rebate.GetValueOrDefault(); double R_H = arguments_.rebate.GetValueOrDefault(); @@ -76,55 +76,56 @@ public override void calculate() double barrierOut = 0; double rebateIn = 0; - for(int n = -series_; n < series_; n++){ - double d1 = D(S/H*Math.Pow(L/H, 2.0*n), vol*vol+mu, vol, T); - double d2 = d1 - vol*Math.Sqrt(T); - double g1 = D(H/S*Math.Pow(L/H, 2.0*n - 1.0), vol*vol+mu, vol, T); - double g2 = g1 - vol*Math.Sqrt(T); - double h1 = D(S/H*Math.Pow(L/H, 2.0*n - 1.0), vol*vol+mu, vol, T); - double h2 = h1 - vol*Math.Sqrt(T); - double k1 = D(L/S*Math.Pow(L/H, 2.0*n - 1.0), vol*vol+mu, vol, T); - double k2 = k1 - vol*Math.Sqrt(T); - double d1_down = D(S/K_down*Math.Pow(L/H, 2.0*n), vol*vol+mu, vol, T); - double d2_down = d1_down - vol*Math.Sqrt(T); - double d1_up = D(S/K_up*Math.Pow(L/H, 2.0*n), vol*vol+mu, vol, T); - double d2_up = d1_up - vol*Math.Sqrt(T); - double k1_down = D((H*H)/(K_down*S)*Math.Pow(L/H, 2.0*n), vol*vol+mu, vol, T); - double k2_down = k1_down - vol*Math.Sqrt(T); - double k1_up = D((H*H)/(K_up*S)*Math.Pow(L/H, 2.0*n), vol*vol+mu, vol, T); - double k2_up = k1_up - vol*Math.Sqrt(T); - - if( payoff.optionType() == Option.Type.Call) + for (int n = -series_; n < series_; n++) + { + double d1 = D(S / H * Math.Pow(L / H, 2.0 * n), vol * vol + mu, vol, T); + double d2 = d1 - vol * Math.Sqrt(T); + double g1 = D(H / S * Math.Pow(L / H, 2.0 * n - 1.0), vol * vol + mu, vol, T); + double g2 = g1 - vol * Math.Sqrt(T); + double h1 = D(S / H * Math.Pow(L / H, 2.0 * n - 1.0), vol * vol + mu, vol, T); + double h2 = h1 - vol * Math.Sqrt(T); + double k1 = D(L / S * Math.Pow(L / H, 2.0 * n - 1.0), vol * vol + mu, vol, T); + double k2 = k1 - vol * Math.Sqrt(T); + double d1_down = D(S / K_down * Math.Pow(L / H, 2.0 * n), vol * vol + mu, vol, T); + double d2_down = d1_down - vol * Math.Sqrt(T); + double d1_up = D(S / K_up * Math.Pow(L / H, 2.0 * n), vol * vol + mu, vol, T); + double d2_up = d1_up - vol * Math.Sqrt(T); + double k1_down = D((H * H) / (K_down * S) * Math.Pow(L / H, 2.0 * n), vol * vol + mu, vol, T); + double k2_down = k1_down - vol * Math.Sqrt(T); + double k1_up = D((H * H) / (K_up * S) * Math.Pow(L / H, 2.0 * n), vol * vol + mu, vol, T); + double k2_up = k1_up - vol * Math.Sqrt(T); + + if (payoff.optionType() == Option.Type.Call) { - barrierOut += Math.Pow(L/H, 2.0 * n * mu/(vol*vol))* - (df*S*Math.Pow(L/H, 2.0*n)*(f_.value(d1_down)-f_.value(d1)) - -dd*K*(f_.value(d2_down)-f_.value(d2)) - -df*Math.Pow(L/H, 2.0*n)*H*H/S*Math.Pow(H/S, 2.0*mu/(vol*vol))*(f_.value(k1_down)-f_.value(k1)) - +dd*K*Math.Pow(H/S,2.0*mu/(vol*vol))*(f_.value(k2_down)-f_.value(k2))); + barrierOut += Math.Pow(L / H, 2.0 * n * mu / (vol * vol)) * + (df * S * Math.Pow(L / H, 2.0 * n) * (f_.value(d1_down) - f_.value(d1)) + - dd * K * (f_.value(d2_down) - f_.value(d2)) + - df * Math.Pow(L / H, 2.0 * n) * H * H / S * Math.Pow(H / S, 2.0 * mu / (vol * vol)) * (f_.value(k1_down) - f_.value(k1)) + + dd * K * Math.Pow(H / S, 2.0 * mu / (vol * vol)) * (f_.value(k2_down) - f_.value(k2))); } - else if(payoff.optionType() == Option.Type.Put) + else if (payoff.optionType() == Option.Type.Put) { - barrierOut += Math.Pow(L/H, 2.0 * n * mu/(vol*vol))* - (dd*K*(f_.value(h2)-f_.value(d2_up)) - -df*S*Math.Pow(L/H, 2.0*n)*(f_.value(h1)-f_.value(d1_up)) - -dd*K*Math.Pow(H/S,2.0*mu/(vol*vol))*(f_.value(g2)-f_.value(k2_up)) - +df*Math.Pow(L/H, 2.0*n)*H*H/S*Math.Pow(H/S, 2.0*mu/(vol*vol))*(f_.value(g1)-f_.value(k1_up))); + barrierOut += Math.Pow(L / H, 2.0 * n * mu / (vol * vol)) * + (dd * K * (f_.value(h2) - f_.value(d2_up)) + - df * S * Math.Pow(L / H, 2.0 * n) * (f_.value(h1) - f_.value(d1_up)) + - dd * K * Math.Pow(H / S, 2.0 * mu / (vol * vol)) * (f_.value(g2) - f_.value(k2_up)) + + df * Math.Pow(L / H, 2.0 * n) * H * H / S * Math.Pow(H / S, 2.0 * mu / (vol * vol)) * (f_.value(g1) - f_.value(k1_up))); } - else + else { Utils.QL_FAIL("option type not recognized"); } - double v1 = D(H/S*Math.Pow(H/L, 2.0*n), -mu, vol, T); - double v2 = D(H/S*Math.Pow(H/L, 2.0*n), mu, vol, T); - double v3 = D(S/L*Math.Pow(H/L, 2.0*n), -mu, vol, T); - double v4 = D(S/L*Math.Pow(H/L, 2.0*n), mu, vol, T); - rebateIn += dd * R_H * sgn * (Math.Pow(L/H, 2.0*n*mu/(vol*vol)) * f_.value(sgn * v1) - Math.Pow(H/S, 2.0*mu/(vol*vol)) * f_.value(-sgn * v2)) - + dd * R_L * sgn * (Math.Pow(L/S, 2.0*mu/(vol*vol)) * f_.value(-sgn * v3) - Math.Pow(H/L, 2.0*n*mu/(vol*vol)) * f_.value(sgn * v4)); + double v1 = D(H / S * Math.Pow(H / L, 2.0 * n), -mu, vol, T); + double v2 = D(H / S * Math.Pow(H / L, 2.0 * n), mu, vol, T); + double v3 = D(S / L * Math.Pow(H / L, 2.0 * n), -mu, vol, T); + double v4 = D(S / L * Math.Pow(H / L, 2.0 * n), mu, vol, T); + rebateIn += dd * R_H * sgn * (Math.Pow(L / H, 2.0 * n * mu / (vol * vol)) * f_.value(sgn * v1) - Math.Pow(H / S, 2.0 * mu / (vol * vol)) * f_.value(-sgn * v2)) + + dd * R_L * sgn * (Math.Pow(L / S, 2.0 * mu / (vol * vol)) * f_.value(-sgn * v3) - Math.Pow(H / L, 2.0 * n * mu / (vol * vol)) * f_.value(sgn * v4)); } //rebate paid at maturity - if(barrierType == DoubleBarrier.Type.KnockOut) + if (barrierType == DoubleBarrier.Type.KnockOut) results_.value = barrierOut ; else results_.value = european - barrierOut; @@ -134,7 +135,7 @@ public override void calculate() results_.additionalResults["barrierIn"] = european - barrierOut; } - + private GeneralizedBlackScholesProcess process_; private int series_; private CumulativeNormalDistribution f_; @@ -143,27 +144,27 @@ public override void calculate() private double strike() { PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; - Utils.QL_REQUIRE(payoff!=null,()=> "non-plain payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); return payoff.strike(); } - private double residualTime() { return process_.time( arguments_.exercise.lastDate() ); } - private double volatility() { return process_.blackVolatility().link.blackVol( residualTime(), strike() ); } + private double residualTime() { return process_.time(arguments_.exercise.lastDate()); } + private double volatility() { return process_.blackVolatility().link.blackVol(residualTime(), strike()); } private double riskFreeRate() { - return process_.riskFreeRate().link.zeroRate( - residualTime(), Compounding.Continuous,Frequency.NoFrequency ).value(); + return process_.riskFreeRate().link.zeroRate( + residualTime(), Compounding.Continuous, Frequency.NoFrequency).value(); } - private double riskFreeDiscount() { return process_.riskFreeRate().link.discount( residualTime() ); } + private double riskFreeDiscount() { return process_.riskFreeRate().link.discount(residualTime()); } private double dividendYield() { - return process_.dividendYield().link.zeroRate( - residualTime(),Compounding.Continuous, Frequency.NoFrequency ).value(); + return process_.dividendYield().link.zeroRate( + residualTime(), Compounding.Continuous, Frequency.NoFrequency).value(); } - private double dividendDiscount() { return process_.dividendYield().link.discount( residualTime() ); } + private double dividendDiscount() { return process_.dividendYield().link.discount(residualTime()); } private double D(double X, double lambda, double sigma, double T) { - return (Math.Log(X) + lambda * T)/(sigma * Math.Sqrt(T)); + return (Math.Log(X) + lambda * T) / (sigma * Math.Sqrt(T)); } } } diff --git a/src/QLNet/Pricingengines/blackformula.cs b/src/QLNet/Pricingengines/blackformula.cs deleted file mode 100644 index fe1d7025d..000000000 --- a/src/QLNet/Pricingengines/blackformula.cs +++ /dev/null @@ -1,619 +0,0 @@ -// Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// -// This file is part of QLNet Project https://github.com/amaggiulli/qlnet -// QLNet is free software: you can redistribute it and/or modify it -// under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// -// QLNet is a based on QuantLib, a free-software/open-source library -// for financial quantitative analysts and developers - http://quantlib.org/ -// The QuantLib license is available online at http://quantlib.org/license.shtml. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the license for more details. - -using System; - -namespace QLNet -{ - - public partial class Utils - { - /*! Black 1976 formula - \warning instead of volatility it uses standard deviation, - i.e. volatility*sqrt(timeToMaturity) - */ - public static double blackFormula( Option.Type optionType, - double strike, - double forward, - double stdDev, - double discount = 1.0, - double displacement = 0.0 ) - { - checkParameters(strike, forward, displacement); - Utils.QL_REQUIRE(stdDev>=0.0,()=> "stdDev (" + stdDev + ") must be non-negative"); - Utils.QL_REQUIRE(discount>0.0,()=> "discount (" + discount + ") must be positive"); - - if (stdDev.IsEqual(0.0)) - return Math.Max((forward-strike)*(int)optionType, 0.0)*discount; - - forward = forward + displacement; - strike = strike + displacement; - - // since displacement is non-negative strike==0 iff displacement==0 - // so returning forward*discount is OK - if (strike.IsEqual(0.0)) - return (optionType==Option.Type.Call ? forward*discount : 0.0); - - double d1 = Math.Log(forward/strike)/stdDev + 0.5*stdDev; - double d2 = d1 - stdDev; - CumulativeNormalDistribution phi = new CumulativeNormalDistribution(); - double nd1 = phi.value( (int)optionType * d1 ); - double nd2 = phi.value( (int)optionType * d2 ); - double result = discount * (int)optionType * ( forward * nd1 - strike * nd2 ); - Utils.QL_REQUIRE(result>=0.0,()=> - "negative value (" + result + ") for " + - stdDev + " stdDev, " + - optionType + " option, " + - strike + " strike , " + - forward + " forward"); - return result; - } - - public static double blackFormula( PlainVanillaPayoff payoff, - double forward, - double stdDev, - double discount = 1.0, - double displacement = 0.0) - { - return blackFormula( payoff.optionType(),payoff.strike(), forward, stdDev, discount, displacement ); - } - - /*! Approximated Black 1976 implied standard deviation, - i.e. volatility*sqrt(timeToMaturity). - - It is calculated using Brenner and Subrahmanyan (1988) and Feinstein - (1988) approximation for at-the-money forward option, with the - extended moneyness approximation by Corrado and Miller (1996) - */ - public static double blackFormulaImpliedStdDevApproximation( Option.Type optionType, - double strike, - double forward, - double blackPrice, - double discount = 1.0, - double displacement = 0.0 ) - { - checkParameters(strike, forward, displacement); - Utils.QL_REQUIRE(blackPrice>=0.0,()=> - "blackPrice (" + blackPrice + ") must be non-negative"); - Utils.QL_REQUIRE(discount>0.0,()=> - "discount (" + discount + ") must be positive"); - - double stdDev; - forward = forward + displacement; - strike = strike + displacement; - if (strike.IsEqual(forward)) - // Brenner-Subrahmanyan (1988) and Feinstein (1988) ATM approx. - stdDev = blackPrice/discount*Math.Sqrt(2.0 * Const.M_PI)/forward; - else - { - // Corrado and Miller extended moneyness approximation - double moneynessDelta = (int)optionType*(forward-strike); - double moneynessDelta_2 = moneynessDelta/2.0; - double temp = blackPrice/discount - moneynessDelta_2; - double moneynessDelta_PI = moneynessDelta*moneynessDelta/Const.M_PI; - double temp2 = temp*temp-moneynessDelta_PI; - if (temp2<0.0) // approximation breaks down, 2 alternatives: - // 1. zero it - temp2=0.0; - // 2. Manaster-Koehler (1982) efficient Newton-Raphson seed - temp2 = Math.Sqrt(temp2); - temp += temp2; - temp *= Math.Sqrt(2.0 * Const.M_PI); - stdDev = temp/(forward+strike); - } - - Utils.QL_REQUIRE(stdDev>=0.0,()=> "stdDev (" + stdDev + ") must be non-negative"); - return stdDev; - } - - public static double blackFormulaImpliedStdDevApproximation( PlainVanillaPayoff payoff, - double forward, - double blackPrice, - double discount, - double displacement) - { - return blackFormulaImpliedStdDevApproximation(payoff.optionType(), - payoff.strike(), forward, blackPrice, discount, displacement); - } - - - /*! Approximated Black 1976 implied standard deviation, - i.e. volatility*sqrt(timeToMaturity). - - It is calculated following "An improved approach to computing - implied volatility", Chambers, Nawalkha, The Financial Review, - 2001, 89-100. The atm option price must be known to use this - method. - */ - public static double blackFormulaImpliedStdDevChambers( Option.Type optionType, - double strike, - double forward, - double blackPrice, - double blackAtmPrice, - double discount = 1.0, - double displacement = 0.0 ) - { - checkParameters(strike, forward, displacement); - QL_REQUIRE(blackPrice >= 0.0,()=> - "blackPrice (" + blackPrice + ") must be non-negative"); - QL_REQUIRE(blackAtmPrice >= 0.0, ()=> - "blackAtmPrice ("+ blackAtmPrice + ") must be non-negative"); - QL_REQUIRE(discount > 0.0,()=> - "discount (" + discount + ") must be positive"); - - double stdDev; - - forward = forward + displacement; - strike = strike + displacement; - blackPrice /= discount; - blackAtmPrice /= discount; - - double s0 = Const.M_SQRT2 * Const.M_SQRTPI * blackAtmPrice / - forward; // Brenner-Subrahmanyam formula - double priceAtmVol = blackFormula(optionType, strike, forward, s0, 1.0, 0.0); - double dc = blackPrice - priceAtmVol; - - if (close(dc, 0.0)) - { - stdDev = s0; - } - else - { - double d1 = blackFormulaStdDevDerivative(strike, forward, s0, 1.0, 0.0); - double d2 = blackFormulaStdDevSecondDerivative(strike, forward, s0,1.0, 0.0); - double ds = 0.0; - double tmp = d1 * d1 + 2.0 * d2 * dc; - if (Math.Abs(d2) > 1E-10 && tmp >= 0.0) - ds = (-d1 + Math.Sqrt(tmp)) / d2; // second order approximation - else - if(Math.Abs(d1) > 1E-10) - ds = dc / d1; // first order approximation - stdDev = s0 + ds; - } - - QL_REQUIRE(stdDev >= 0.0,()=> "stdDev (" + stdDev + ") must be non-negative"); - return stdDev; - } - - public static double blackFormulaImpliedStdDevChambers( PlainVanillaPayoff payoff, - double forward, - double blackPrice, - double blackAtmPrice, - double discount, - double displacement) - { - return blackFormulaImpliedStdDevChambers(payoff.optionType(), payoff.strike(), forward, blackPrice, - blackAtmPrice, discount, displacement); - } - - - /*! Black 1976 implied standard deviation, - i.e. volatility*sqrt(timeToMaturity) - */ - public static double blackFormulaImpliedStdDev( Option.Type optionType, - double strike, - double forward, - double blackPrice, - double discount = 1.0, - double displacement = 0.0, - double? guess =null, - double accuracy = 1.0e-6, - int maxIterations = 100 ) - { - checkParameters(strike, forward, displacement); - - QL_REQUIRE(discount>0.0,()=> - "discount (" + discount + ") must be positive"); - - QL_REQUIRE(blackPrice>=0.0,()=> - "option price (" + blackPrice + ") must be non-negative"); - // check the price of the "other" option implied by put-call paity - double otherOptionPrice = blackPrice - (int)optionType*(forward-strike)*discount; - QL_REQUIRE(otherOptionPrice>=0.0,()=> - "negative " + (-1*(int)optionType) + - " price (" + otherOptionPrice + - ") implied by put-call parity. No solution exists for " + - optionType + " strike " + strike + - ", forward " + forward + - ", price " + blackPrice + - ", deflator " + discount); - - // solve for the out-of-the-money option which has - // greater vega/price ratio, i.e. - // it is numerically more robust for implied vol calculations - if (optionType==Option.Type.Put && strike>forward) - { - optionType = Option.Type.Call; - blackPrice = otherOptionPrice; - } - if (optionType==Option.Type.Call && strike=0.0,()=> "stdDev guess (" + guess + ") must be non-negative"); - - BlackImpliedStdDevHelper f = new BlackImpliedStdDevHelper(optionType, strike, forward,blackPrice/discount); - NewtonSafe solver = new NewtonSafe(); - solver.setMaxEvaluations(maxIterations); - double minSdtDev = 0.0, maxStdDev = 24.0; // 24 = 300% * sqrt(60) - double stdDev = solver.solve(f, accuracy, guess.Value, minSdtDev, maxStdDev); - QL_REQUIRE(stdDev>=0.0,()=> "stdDev (" + stdDev + ") must be non-negative"); - return stdDev; - } - - public static double blackFormulaImpliedStdDev( PlainVanillaPayoff payoff, - double forward, - double blackPrice, - double discount, - double displacement, - double guess, - double accuracy, - int maxIterations = 100) - { - return blackFormulaImpliedStdDev(payoff.optionType(), payoff.strike(), - forward, blackPrice, discount, displacement, guess, accuracy, maxIterations); - } - - - /*! Black 1976 probability of being in the money (in the bond martingale measure), i.e. N(d2). - It is a risk-neutral probability, not the real world one. - \warning instead of volatility it uses standard deviation, i.e. volatility*sqrt(timeToMaturity) - */ - public static double blackFormulaCashItmProbability( Option.Type optionType, - double strike, - double forward, - double stdDev, - double displacement = 0.0 ) - { - checkParameters(strike, forward, displacement); - if (stdDev.IsEqual(0.0)) - return (forward*(int)optionType > strike*(int)optionType ? 1.0 : 0.0); - - forward = forward + displacement; - strike = strike + displacement; - if (strike.IsEqual(0.0)) - return (optionType==Option.Type.Call ? 1.0 : 0.0); - double d2 = Math.Log(forward/strike)/stdDev - 0.5*stdDev; - CumulativeNormalDistribution phi = new CumulativeNormalDistribution(); - return phi.value((int)optionType*d2); - } - - public static double blackFormulaCashItmProbability( PlainVanillaPayoff payoff, - double forward, - double stdDev, - double displacement = 0.0) - { - return blackFormulaCashItmProbability( payoff.optionType(), - payoff.strike(), forward, stdDev, displacement ); - } - - /*! Black 1976 formula for standard deviation derivative - \warning instead of volatility it uses standard deviation, i.e. - volatility*sqrt(timeToMaturity), and it returns the - derivative with respect to the standard deviation. - If T is the time to maturity Black vega would be - blackStdDevDerivative(strike, forward, stdDev)*sqrt(T) - */ - public static double blackFormulaStdDevDerivative( double strike, - double forward, - double stdDev, - double discount = 1.0, - double displacement = 0.0 ) - { - checkParameters(strike, forward, displacement); - QL_REQUIRE(stdDev>=0.0,()=> - "stdDev (" + stdDev + ") must be non-negative"); - QL_REQUIRE(discount>0.0,()=> - "discount (" + discount + ") must be positive"); - - forward = forward + displacement; - strike = strike + displacement; - - if (stdDev.IsEqual(0.0) || strike.IsEqual(0.0)) - return 0.0; - - double d1 = Math.Log(forward/strike)/stdDev + .5*stdDev; - return discount * forward * - new CumulativeNormalDistribution().derivative(d1); - } - /*! Black 1976 formula for derivative with respect to implied vol, this - is basically the vega, but if you want 1% change multiply by 1% - */ - public static double blackFormulaVolDerivative( double strike, - double forward, - double stdDev, - double expiry, - double discount = 1.0, - double displacement = 0.0 ) - { - return blackFormulaStdDevDerivative(strike,forward,stdDev,discount,displacement)*Math.Sqrt(expiry); - } - - public static double blackFormulaStdDevDerivative( PlainVanillaPayoff payoff, - double forward, - double stdDev, - double discount = 1.0, - double displacement = 0.0) - { - return blackFormulaStdDevDerivative( payoff.strike(), forward,stdDev, discount, displacement ); - } - - /*! Black 1976 formula for second derivative by standard deviation - \warning instead of volatility it uses standard deviation, i.e. - volatility*sqrt(timeToMaturity), and it returns the - derivative with respect to the standard deviation. - */ - public static double blackFormulaStdDevSecondDerivative( double strike, - double forward, - double stdDev, - double discount, - double displacement ) - { - checkParameters(strike, forward, displacement); - QL_REQUIRE(stdDev>=0.0,()=> - "stdDev (" + stdDev + ") must be non-negative"); - QL_REQUIRE(discount>0.0,()=> - "discount (" + discount + ") must be positive"); - - forward = forward + displacement; - strike = strike + displacement; - - if (stdDev.IsEqual(0.0) || strike.IsEqual(0.0)) - return 0.0; - - double d1 = Math.Log(forward/strike)/stdDev + .5*stdDev; - double d1p = -Math.Log(forward/strike)/(stdDev*stdDev) + .5; - return discount * forward * - new NormalDistribution().derivative(d1) * d1p; - } - - public static double blackFormulaStdDevSecondDerivative( PlainVanillaPayoff payoff, - double forward, - double stdDev, - double discount = 1.0, - double displacement = 0.0) - { - return blackFormulaStdDevSecondDerivative( payoff.strike(), forward,stdDev, discount, displacement ); - } - - /*! Black style formula when forward is normal rather than - log-normal. This is essentially the model of Bachelier. - - \warning Bachelier model needs absolute volatility, not - percentage volatility. Standard deviation is - absoluteVolatility*sqrt(timeToMaturity) - */ - public static double bachelierBlackFormula( Option.Type optionType, - double strike, - double forward, - double stdDev, - double discount = 1.0 ) - { - QL_REQUIRE(stdDev>=0.0,()=> - "stdDev (" + stdDev + ") must be non-negative"); - QL_REQUIRE(discount>0.0,()=> - "discount (" + discount + ") must be positive"); - double d = (forward-strike)*(int)optionType, h = d/stdDev; - if (stdDev.IsEqual(0.0)) - return discount*Math.Max(d, 0.0); - CumulativeNormalDistribution phi = new CumulativeNormalDistribution(); - double result = discount*(stdDev*phi.derivative(h) + d*phi.value(h)); - QL_REQUIRE(result>=0.0,()=> - "negative value (" + result + ") for " + - stdDev + " stdDev, " + - optionType + " option, " + - strike + " strike , " + - forward + " forward"); - return result; - } - - public static double bachelierBlackFormula( PlainVanillaPayoff payoff, - double forward, - double stdDev, - double discount = 1.0) - { - return bachelierBlackFormula( payoff.optionType(),payoff.strike(), forward, stdDev, discount ); - } - - /*! Approximated Bachelier implied volatility - - It is calculated using the analytic implied volatility approximation - of J. Choi, K Kim and M. Kwak (2009), “Numerical Approximation of the - Implied Volatility Under Arithmetic Brownian Motion”, - Applied Math. Finance, 16(3), pp. 261-268. - */ - public static double bachelierBlackFormulaImpliedVol( Option.Type optionType, - double strike, - double forward, - double tte, - double bachelierPrice, - double discount = 1.0 ) - { - double SQRT_QL_EPSILON = Math.Sqrt(Const.QL_EPSILON); - - QL_REQUIRE(tte>0.0,()=> "tte (" + tte + ") must be positive"); - - double forwardPremium = bachelierPrice/discount; - - double straddlePremium; - if (optionType==Option.Type.Call) - { - straddlePremium = 2.0 * forwardPremium - (forward - strike); - } - else - { - straddlePremium = 2.0 * forwardPremium + (forward - strike); - } - - double nu = (forward - strike) / straddlePremium; - QL_REQUIRE(nu<=1.0,()=> "nu (" + nu + ") must be <= 1.0"); - QL_REQUIRE(nu>=-1.0,()=> "nu (" + nu + ") must be >= -1.0"); - - nu = Math.Max(-1.0 + Const.QL_EPSILON, Math.Min(nu,1.0 - Const.QL_EPSILON)); - - // nu / arctanh(nu) -> 1 as nu -> 0 - double eta = (Math.Abs(nu) < SQRT_QL_EPSILON) ? 1.0 : nu / ((Math.Log(1 + nu) - Math.Log(1 - nu))/2); - - double heta = h(eta); - - double impliedBpvol = Math.Sqrt(Const.M_PI / (2 * tte)) * straddlePremium * heta; - - return impliedBpvol; - } - - public static double h(double eta) - { - - const double A0 = 3.994961687345134e-1; - const double A1 = 2.100960795068497e+1; - const double A2 = 4.980340217855084e+1; - const double A3 = 5.988761102690991e+2; - const double A4 = 1.848489695437094e+3; - const double A5 = 6.106322407867059e+3; - const double A6 = 2.493415285349361e+4; - const double A7 = 1.266458051348246e+4; - - const double B0 = 1.000000000000000e+0; - const double B1 = 4.990534153589422e+1; - const double B2 = 3.093573936743112e+1; - const double B3 = 1.495105008310999e+3; - const double B4 = 1.323614537899738e+3; - const double B5 = 1.598919697679745e+4; - const double B6 = 2.392008891720782e+4; - const double B7 = 3.608817108375034e+3; - const double B8 = -2.067719486400926e+2; - const double B9 = 1.174240599306013e+1; - - QL_REQUIRE(eta>=0.0,()=> - "eta (" + eta + ") must be non-negative"); - - double num = A0 + eta * (A1 + eta * (A2 + eta * (A3 + eta * (A4 + eta - * (A5 + eta * (A6 + eta * A7)))))); - - double den = B0 + eta * (B1 + eta * (B2 + eta * (B3 + eta * (B4 + eta - * (B5 + eta * (B6 + eta * (B7 + eta * (B8 + eta * B9)))))))); - - return Math.Sqrt(eta) * (num / den); - - } - - /*! Bachelier formula for standard deviation derivative - \warning instead of volatility it uses standard deviation, i.e. - volatility*sqrt(timeToMaturity), and it returns the - derivative with respect to the standard deviation. - If T is the time to maturity Black vega would be - blackStdDevDerivative(strike, forward, stdDev)*sqrt(T) - */ - - public static double bachelierBlackFormulaStdDevDerivative( double strike, - double forward, - double stdDev, - double discount = 1.0 ) - { - QL_REQUIRE( stdDev >= 0.0,()=> - "stdDev (" + stdDev + ") must be non-negative" ); - QL_REQUIRE( discount > 0.0,()=> - "discount (" + discount + ") must be positive" ); - - if ( stdDev.IsEqual(0.0) ) - return 0.0; - - double d1 = ( forward - strike ) / stdDev; - return discount * - new CumulativeNormalDistribution().derivative( d1 ); - } - - public static double bachelierBlackFormulaStdDevDerivative( PlainVanillaPayoff payoff, - double forward, - double stdDev, - double discount = 1.0) - { - return bachelierBlackFormulaStdDevDerivative( payoff.strike(), forward, stdDev, discount ); - } - - public static void checkParameters( double strike,double forward,double displacement ) - { - Utils.QL_REQUIRE( displacement >= 0.0,()=> - "displacement (" + displacement + ") must be non-negative" ); - Utils.QL_REQUIRE( strike + displacement >= 0.0,()=> - "strike + displacement (" + strike + " + " + displacement + ") must be non-negative" ); - Utils.QL_REQUIRE( forward + displacement > 0.0, () => - "forward + displacement (" + forward + " + " + displacement + ") must be positive" ); - } - - class BlackImpliedStdDevHelper : ISolver1d - { - public BlackImpliedStdDevHelper( Option.Type optionType, - double strike, - double forward, - double undiscountedBlackPrice, - double displacement = 0.0 ) - { - halfOptionType_ = 0.5 * (int)optionType; - signedStrike_ = (int)optionType * ( strike + displacement ); - signedForward_ = (int)optionType * ( forward + displacement ); - undiscountedBlackPrice_ = undiscountedBlackPrice; - N_ = new CumulativeNormalDistribution(); - checkParameters( strike, forward, displacement ); - Utils.QL_REQUIRE( undiscountedBlackPrice >= 0.0, () => - "undiscounted Black price (" + - undiscountedBlackPrice + ") must be non-negative" ); - signedMoneyness_ = (int)optionType * Math.Log( ( forward + displacement ) / ( strike + displacement ) ); - } - public override double value( double stdDev ) - { -#if QL_EXTRA_SAFETY_CHECKS - Utils.QL_REQUIRE(stdDev>=0.0,()=> "stdDev (" + stdDev + ") must be non-negative"); -#endif - if ( stdDev.IsEqual(0.0) ) - return Math.Max( signedForward_ - signedStrike_, 0.0 ) - - undiscountedBlackPrice_; - double temp = halfOptionType_ * stdDev; - double d = signedMoneyness_ / stdDev; - double signedD1 = d + temp; - double signedD2 = d - temp; - double result = signedForward_ * N_.value( signedD1 ) - - signedStrike_ * N_.value( signedD2 ); - // numerical inaccuracies can yield a negative answer - return Math.Max( 0.0, result ) - undiscountedBlackPrice_; - } - - public override double derivative( double stdDev ) - { -#if QL_EXTRA_SAFETY_CHECKS - QL_REQUIRE(stdDev>=0.0, - "stdDev (" << stdDev << ") must be non-negative"); -#endif - double signedD1 = signedMoneyness_ / stdDev + halfOptionType_ * stdDev; - return signedForward_ * N_.derivative( signedD1 ); - } - - - private double halfOptionType_; - private double signedStrike_, signedForward_; - private double undiscountedBlackPrice_, signedMoneyness_; - private CumulativeNormalDistribution N_; - } - } -} \ No newline at end of file diff --git a/src/QLNet/Pricingengines/credit/IntegralCdsEngine.cs b/src/QLNet/Pricingengines/credit/IntegralCdsEngine.cs index 44dc19e87..f9fc4f7b4 100644 --- a/src/QLNet/Pricingengines/credit/IntegralCdsEngine.cs +++ b/src/QLNet/Pricingengines/credit/IntegralCdsEngine.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,55 +19,55 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class IntegralCdsEngine : CreditDefaultSwap.Engine - { - const double basisPoint = 1.0e-4; - - public IntegralCdsEngine(Period step, Handle probability, - double recoveryRate, Handle discountCurve, bool? includeSettlementDateFlows = null) - { - integrationStep_ = step ; - probability_ = probability; - recoveryRate_ = recoveryRate; - discountCurve_ = discountCurve; - includeSettlementDateFlows_ = includeSettlementDateFlows; - - probability_.registerWith(update); - discountCurve_.registerWith(update); - } - - public override void calculate() - { - Utils.QL_REQUIRE( integrationStep_ != null, () => "null period set" ); - Utils.QL_REQUIRE( !discountCurve_.empty(), () => "no discount term structure set" ); - Utils.QL_REQUIRE( !probability_.empty(), () => "no probability term structure set" ); - - Date today = Settings.evaluationDate(); - Date settlementDate = discountCurve_.link.referenceDate(); - - // Upfront Flow NPV. Either we are on-the-run (no flow) - // or we are forward start - double upfPVO1 = 0.0; - if(!arguments_.upfrontPayment.hasOccurred( settlementDate, includeSettlementDateFlows_)) - { + public class IntegralCdsEngine : CreditDefaultSwap.Engine + { + const double basisPoint = 1.0e-4; + + public IntegralCdsEngine(Period step, Handle probability, + double recoveryRate, Handle discountCurve, bool? includeSettlementDateFlows = null) + { + integrationStep_ = step ; + probability_ = probability; + recoveryRate_ = recoveryRate; + discountCurve_ = discountCurve; + includeSettlementDateFlows_ = includeSettlementDateFlows; + + probability_.registerWith(update); + discountCurve_.registerWith(update); + } + + public override void calculate() + { + Utils.QL_REQUIRE(integrationStep_ != null, () => "null period set"); + Utils.QL_REQUIRE(!discountCurve_.empty(), () => "no discount term structure set"); + Utils.QL_REQUIRE(!probability_.empty(), () => "no probability term structure set"); + + Date today = Settings.evaluationDate(); + Date settlementDate = discountCurve_.link.referenceDate(); + + // Upfront Flow NPV. Either we are on-the-run (no flow) + // or we are forward start + double upfPVO1 = 0.0; + if (!arguments_.upfrontPayment.hasOccurred(settlementDate, includeSettlementDateFlows_)) + { // date determining the probability survival so we have to pay // the upfront (did not knock out) - Date effectiveUpfrontDate = - arguments_.protectionStart > probability_.link.referenceDate() ? - arguments_.protectionStart : probability_.link.referenceDate(); + Date effectiveUpfrontDate = + arguments_.protectionStart > probability_.link.referenceDate() ? + arguments_.protectionStart : probability_.link.referenceDate(); upfPVO1 = - probability_.link.survivalProbability(effectiveUpfrontDate) * - discountCurve_.link.discount(arguments_.upfrontPayment.date()); - } - results_.upfrontNPV = upfPVO1 * arguments_.upfrontPayment.amount(); - - results_.couponLegNPV = 0.0; - results_.defaultLegNPV = 0.0; - for (int i=0; i probability_; - private double recoveryRate_; - private Handle discountCurve_; - private bool? includeSettlementDateFlows_; - } + private Period integrationStep_; + private Handle probability_; + private double recoveryRate_; + private Handle discountCurve_; + private bool? includeSettlementDateFlows_; + } } diff --git a/src/QLNet/Pricingengines/credit/IsdaCdsEngine.cs b/src/QLNet/Pricingengines/credit/IsdaCdsEngine.cs index f866daf9e..ade00fc02 100644 --- a/src/QLNet/Pricingengines/credit/IsdaCdsEngine.cs +++ b/src/QLNet/Pricingengines/credit/IsdaCdsEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -25,15 +25,15 @@ public class IsdaCdsEngine : CreditDefaultSwap.Engine public enum NumericalFix { None, // as in [1] footnote 26 (i.e. 10^{-50} is added to - // denominators $f_i+h_i$$) + // denominators $f_i+h_i$$) Taylor // as in [2] i.e. for $f_i+h_i < 10^{-4}$ a Taylor expansion - // is used to avoid zero denominators + // is used to avoid zero denominators } public enum AccrualBias { HalfDayBias, // as in [1] formula (50), second (error) term is - // included + // included NoBias // as in [1], but second term in formula (50) is not included } @@ -41,7 +41,7 @@ public enum ForwardsInCouponPeriod { Flat, // as in [1], formula (52), second (error) term is included Piecewise // as in [1], but second term in formula (52) is not - // included + // included } /*! Constructor where the client code is responsible for providing a @@ -58,12 +58,12 @@ provide the evaluation date's fixing. */ public IsdaCdsEngine(Handle probability, - double recoveryRate, - Handle discountCurve, - bool? includeSettlementDateFlows = null, - NumericalFix numericalFix = NumericalFix.Taylor, - AccrualBias accrualBias = AccrualBias.HalfDayBias, - ForwardsInCouponPeriod forwardsInCouponPeriod = ForwardsInCouponPeriod.Piecewise) + double recoveryRate, + Handle discountCurve, + bool? includeSettlementDateFlows = null, + NumericalFix numericalFix = NumericalFix.Taylor, + AccrualBias accrualBias = AccrualBias.HalfDayBias, + ForwardsInCouponPeriod forwardsInCouponPeriod = ForwardsInCouponPeriod.Piecewise) { probability_ = probability; recoveryRate_ = recoveryRate; @@ -83,12 +83,12 @@ public IsdaCdsEngine(Handle probability, public override void calculate() { Utils.QL_REQUIRE(numericalFix_ == NumericalFix.None || numericalFix_ == NumericalFix.Taylor, () => - "numerical fix must be None or Taylor"); + "numerical fix must be None or Taylor"); Utils.QL_REQUIRE(accrualBias_ == AccrualBias.HalfDayBias || accrualBias_ == AccrualBias.NoBias, () => - "accrual bias must be HalfDayBias or NoBias"); + "accrual bias must be HalfDayBias or NoBias"); Utils.QL_REQUIRE(forwardsInCouponPeriod_ == ForwardsInCouponPeriod.Flat || forwardsInCouponPeriod_ == ForwardsInCouponPeriod.Piecewise, () => - "forwards in coupon period must be Flat or Piecewise"); + "forwards in coupon period must be Flat or Piecewise"); // it would be possible to handle the cases which are excluded below, // but the ISDA engine is not explicitly specified to handle them, @@ -96,7 +96,7 @@ public override void calculate() Actual365Fixed dc = new Actual365Fixed(); Actual360 dc1 = new Actual360(); - Actual360 dc2 = new Actual360(true); + Actual360 dc2 = new Actual360(true); Date evalDate = Settings.evaluationDate(); @@ -106,20 +106,20 @@ public override void calculate() Utils.QL_REQUIRE(!discountCurve_.empty(), () => "no discount term structure set"); Utils.QL_REQUIRE(!probability_.empty(), () => "no probability term structure set"); Utils.QL_REQUIRE(discountCurve_.link.dayCounter() == dc, () => - "yield term structure day counter (" + discountCurve_.link.dayCounter() + ") should be Act/365(Fixed)"); + "yield term structure day counter (" + discountCurve_.link.dayCounter() + ") should be Act/365(Fixed)"); Utils.QL_REQUIRE(probability_.link.dayCounter() == dc, () => - "probability term structure day counter (" + probability_.link.dayCounter() + ") should be " - + "Act/365(Fixed)"); + "probability term structure day counter (" + probability_.link.dayCounter() + ") should be " + + "Act/365(Fixed)"); Utils.QL_REQUIRE(discountCurve_.link.referenceDate() == evalDate, () => - "yield term structure reference date (" + discountCurve_.link.referenceDate() - + " should be evaluation date (" + evalDate + ")"); + "yield term structure reference date (" + discountCurve_.link.referenceDate() + + " should be evaluation date (" + evalDate + ")"); Utils.QL_REQUIRE(probability_.link.referenceDate() == evalDate, () => - "probability term structure reference date (" + probability_.link.referenceDate() - + " should be evaluation date (" + evalDate + ")"); + "probability term structure reference date (" + probability_.link.referenceDate() + + " should be evaluation date (" + evalDate + ")"); Utils.QL_REQUIRE(arguments_.settlesAccrual, () => "ISDA engine not compatible with non accrual paying CDS"); Utils.QL_REQUIRE(arguments_.paysAtDefaultTime, () => "ISDA engine not compatible with end period payment"); Utils.QL_REQUIRE((arguments_.claim as FaceValueClaim) != null, () => - "ISDA engine not compatible with non face value claim"); + "ISDA engine not compatible with non face value claim"); Date maturity = arguments_.maturity; Date effectiveProtectionStart = Date.Max(arguments_.protectionStart, evalDate + 1); @@ -131,11 +131,12 @@ public override void calculate() var castY2 = discountCurve_.link as InterpolatedForwardCurve; var castY3 = discountCurve_.link as InterpolatedForwardCurve; var castY4 = discountCurve_.link as FlatForward; - if ( castY1 != null) + if (castY1 != null) { - if (castY1.dates() != null) yDates = castY1.dates(); + if (castY1.dates() != null) + yDates = castY1.dates(); } - else if ( castY2 != null) + else if (castY2 != null) { yDates = castY2.dates(); } @@ -143,7 +144,7 @@ public override void calculate() { yDates = castY3.dates(); } - else if ( castY4 != null) + else if (castY4 != null) { } else @@ -155,15 +156,15 @@ public override void calculate() var castC2 = probability_.link as InterpolatedHazardRateCurve; var castC3 = probability_.link as FlatHazardRate; - if ( castC1 != null) + if (castC1 != null) { cDates = castC1.dates(); } - else if ( castC2 != null ) + else if (castC2 != null) { cDates = castC2.dates(); } - else if ( castC3 != null ) + else if (castC3 != null) { } else @@ -211,9 +212,9 @@ public override void calculate() { double fhphhq = fhphh * fhphh; protectionNpv += - P0 * Q0 * hhat * (1.0 - 0.5 * fhphh + 1.0 / 6.0 * fhphhq - - 1.0 / 24.0 * fhphhq * fhphh + - 1.0 / 120 * fhphhq * fhphhq); + P0 * Q0 * hhat * (1.0 - 0.5 * fhphh + 1.0 / 6.0 * fhphhq - + 1.0 / 24.0 * fhphhq * fhphh + + 1.0 / 120 * fhphhq * fhphhq); } else { @@ -237,8 +238,8 @@ public override void calculate() Utils.QL_REQUIRE(coupon.dayCounter() == dc || coupon.dayCounter() == dc1 || coupon.dayCounter() == dc2, () => - "ISDA engine requires a coupon day counter Act/365Fixed " - + "or Act/360 (" + coupon.dayCounter() + ")"); + "ISDA engine requires a coupon day counter Act/365Fixed " + + "or Act/360 (" + coupon.dayCounter() + ")"); // premium coupons @@ -249,15 +250,15 @@ public override void calculate() double x3 = probability_.link.survivalProbability(coupon.date() - 1); premiumNpv += - coupon.amount() * - discountCurve_.link.discount(coupon.date()) * - probability_.link.survivalProbability(coupon.date() - 1); + coupon.amount() * + discountCurve_.link.discount(coupon.date()) * + probability_.link.survivalProbability(coupon.date() - 1); } // default accruals if (!new simple_event(coupon.accrualEndDate()) - .hasOccurred(effectiveProtectionStart, false)) + .hasOccurred(effectiveProtectionStart, false)) { Date start = Date.Max(coupon.accrualStartDate(), effectiveProtectionStart) - 1; Date end = coupon.date() - 1; @@ -270,7 +271,7 @@ public override void calculate() { foreach (Date node in nodes) { - if ( node > start && node < end) + if (node > start && node < end) { localNodes.Add(node); } @@ -302,21 +303,21 @@ public override void calculate() // code ? double fhphhq = fhphh * fhphh; defaultAccrThisNode += - hhat * P0 * Q0 * - ((t0 - tstart) * - (1.0 - 0.5 * fhphh + 1.0 / 6.0 * fhphhq - - 1.0 / 24.0 * fhphhq * fhphh) + - (t1 - t0) * - (0.5 - 1.0 / 3.0 * fhphh + 1.0 / 8.0 * fhphhq - - 1.0 / 30.0 * fhphhq * fhphh)); + hhat * P0 * Q0 * + ((t0 - tstart) * + (1.0 - 0.5 * fhphh + 1.0 / 6.0 * fhphhq - + 1.0 / 24.0 * fhphhq * fhphh) + + (t1 - t0) * + (0.5 - 1.0 / 3.0 * fhphh + 1.0 / 8.0 * fhphhq - + 1.0 / 30.0 * fhphhq * fhphh)); } else { defaultAccrThisNode += - (hhat / (fhphh + nFix)) * - ((t1 - t0) * ((P0 * Q0 - P1 * Q1) / (fhphh + nFix) - - P1 * Q1) + - (t0 - tstart) * (P0 * Q0 - P1 * Q1)); + (hhat / (fhphh + nFix)) * + ((t1 - t0) * ((P0 * Q0 - P1 * Q1) / (fhphh + nFix) - + P1 * Q1) + + (t0 - tstart) * (P0 * Q0 - P1 * Q1)); } t0 = t1; @@ -335,10 +336,10 @@ public override void calculate() double upfPVO1 = 0.0; results_.upfrontNPV = 0.0; if (!arguments_.upfrontPayment.hasOccurred( - evalDate, includeSettlementDateFlows_)) + evalDate, includeSettlementDateFlows_)) { upfPVO1 = - discountCurve_.link.discount(arguments_.upfrontPayment.date()); + discountCurve_.link.discount(arguments_.upfrontPayment.date()); if (arguments_.upfrontPayment.amount().IsNotEqual(0.0)) { results_.upfrontNPV = upfPVO1 * arguments_.upfrontPayment.amount(); @@ -351,8 +352,8 @@ public override void calculate() !arguments_.accrualRebate.hasOccurred(evalDate, includeSettlementDateFlows_)) { results_.accrualRebateNPV = - discountCurve_.link.discount(arguments_.accrualRebate.date()) * - arguments_.accrualRebate.amount(); + discountCurve_.link.discount(arguments_.accrualRebate.date()) * + arguments_.accrualRebate.amount(); } double upfrontSign = 1; @@ -373,11 +374,11 @@ public override void calculate() results_.errorEstimate = null; - if (results_.couponLegNPV.IsNotEqual( 0.0)) + if (results_.couponLegNPV.IsNotEqual(0.0)) { results_.fairSpread = - -results_.defaultLegNPV * arguments_.spread / - (results_.couponLegNPV + results_.accrualRebateNPV); + -results_.defaultLegNPV * arguments_.spread / + (results_.couponLegNPV + results_.accrualRebateNPV); } else { @@ -388,9 +389,9 @@ public override void calculate() if (upfrontSensitivity.IsNotEqual(0.0)) { results_.fairUpfront = - -upfrontSign * (results_.defaultLegNPV + results_.couponLegNPV + - results_.accrualRebateNPV) / - upfrontSensitivity; + -upfrontSign * (results_.defaultLegNPV + results_.couponLegNPV + + results_.accrualRebateNPV) / + upfrontSensitivity; } else { @@ -402,7 +403,7 @@ public override void calculate() if (arguments_.spread.IsNotEqual(0.0)) { results_.couponLegBPS = - results_.couponLegNPV * basisPoint / arguments_.spread; + results_.couponLegNPV * basisPoint / arguments_.spread; } else { @@ -412,7 +413,7 @@ public override void calculate() if (arguments_.upfront != null && arguments_.upfront.IsNotEqual(0.0)) { results_.upfrontBPS = - results_.upfrontNPV * basisPoint / (arguments_.upfront); + results_.upfrontNPV * basisPoint / (arguments_.upfront); } else { @@ -427,6 +428,6 @@ public override void calculate() private NumericalFix numericalFix_; private AccrualBias accrualBias_; private ForwardsInCouponPeriod forwardsInCouponPeriod_; - }; + } } diff --git a/src/QLNet/Pricingengines/credit/MidPointCdsEngine.cs b/src/QLNet/Pricingengines/credit/MidPointCdsEngine.cs index 6c571e970..82b58929d 100644 --- a/src/QLNet/Pricingengines/credit/MidPointCdsEngine.cs +++ b/src/QLNet/Pricingengines/credit/MidPointCdsEngine.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,54 +19,54 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class MidPointCdsEngine : CreditDefaultSwap.Engine - { - const double basisPoint = 1.0e-4; - - public MidPointCdsEngine(Handle probability, - double recoveryRate, - Handle discountCurve, - bool? includeSettlementDateFlows = null) - { - probability_ = probability; - recoveryRate_ = recoveryRate; + public class MidPointCdsEngine : CreditDefaultSwap.Engine + { + const double basisPoint = 1.0e-4; + + public MidPointCdsEngine(Handle probability, + double recoveryRate, + Handle discountCurve, + bool? includeSettlementDateFlows = null) + { + probability_ = probability; + recoveryRate_ = recoveryRate; discountCurve_ = discountCurve; - includeSettlementDateFlows_ = includeSettlementDateFlows; + includeSettlementDateFlows_ = includeSettlementDateFlows; - probability_.registerWith(update); - discountCurve_.registerWith(update); - } + probability_.registerWith(update); + discountCurve_.registerWith(update); + } - public override void calculate() - { - Utils.QL_REQUIRE( !discountCurve_.empty(), () => "no discount term structure set" ); - Utils.QL_REQUIRE( !probability_.empty(), () => "no probability term structure set" ); + public override void calculate() + { + Utils.QL_REQUIRE(!discountCurve_.empty(), () => "no discount term structure set"); + Utils.QL_REQUIRE(!probability_.empty(), () => "no probability term structure set"); - Date today = Settings.evaluationDate(); - Date settlementDate = discountCurve_.link.referenceDate(); + Date today = Settings.evaluationDate(); + Date settlementDate = discountCurve_.link.referenceDate(); - // Upfront Flow NPV. Either we are on-the-run (no flow) - // or we are forward start - double upfPVO1 = 0.0; - if (!arguments_.upfrontPayment.hasOccurred( settlementDate, includeSettlementDateFlows_)) - { + // Upfront Flow NPV. Either we are on-the-run (no flow) + // or we are forward start + double upfPVO1 = 0.0; + if (!arguments_.upfrontPayment.hasOccurred(settlementDate, includeSettlementDateFlows_)) + { // date determining the probability survival so we have to pay // the upfront (did not knock out) Date effectiveUpfrontDate = arguments_.protectionStart > probability_.link.referenceDate() ? arguments_.protectionStart : probability_.link.referenceDate(); upfPVO1 = probability_.link.survivalProbability(effectiveUpfrontDate) * discountCurve_.link.discount(arguments_.upfrontPayment.date()); - } - results_.upfrontNPV = upfPVO1 * arguments_.upfrontPayment.amount(); + } + results_.upfrontNPV = upfPVO1 * arguments_.upfrontPayment.amount(); - results_.couponLegNPV = 0.0; - results_.defaultLegNPV = 0.0; - for (int i=0; i probability_; - private double recoveryRate_; - private Handle discountCurve_; - private bool? includeSettlementDateFlows_; - } + results_.upfrontNPV * basisPoint / (arguments_.upfront.Value); + } + else + { + results_.upfrontBPS = null; + } + } + + + + private Handle probability_; + private double recoveryRate_; + private Handle discountCurve_; + private bool? includeSettlementDateFlows_; + } } diff --git a/src/QLNet/Pricingengines/inflation/InflationCapFloorEngines.cs b/src/QLNet/Pricingengines/inflation/InflationCapFloorEngines.cs index 337ad4dc4..b6b78cef9 100644 --- a/src/QLNet/Pricingengines/inflation/InflationCapFloorEngines.cs +++ b/src/QLNet/Pricingengines/inflation/InflationCapFloorEngines.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,62 +20,62 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! Base YoY inflation cap/floor engine - /*! This class doesn't know yet what sort of vol it is. The - inflation index must be linked to a yoy inflation term - structure. This provides the curves, hence the call uses a - shared_ptr<> not a handle<> to the index. - - \ingroup inflationcapfloorengines - */ - - public class YoYInflationCapFloorEngine : YoYInflationCapFloor.Engine - { - public YoYInflationCapFloorEngine( YoYInflationIndex index, Handle vol ) - { - index_ = index; - volatility_ = vol; - - index_.registerWith( update ); - volatility_.registerWith(update); - } + //! Base YoY inflation cap/floor engine + /*! This class doesn't know yet what sort of vol it is. The + inflation index must be linked to a yoy inflation term + structure. This provides the curves, hence the call uses a + shared_ptr<> not a handle<> to the index. + + \ingroup inflationcapfloorengines + */ + + public class YoYInflationCapFloorEngine : YoYInflationCapFloor.Engine + { + public YoYInflationCapFloorEngine(YoYInflationIndex index, Handle vol) + { + index_ = index; + volatility_ = vol; + + index_.registerWith(update); + volatility_.registerWith(update); + } public YoYInflationIndex index() { return index_;} public Handle volatility() { return volatility_; } - public void setVolatility( Handle vol ) - { - if ( !volatility_.empty() ) - volatility_ .unregisterWith(update ); - volatility_ = vol; - volatility_.registerWith(update); - update(); - } - - public override void calculate() - { - // copy black version then adapt to others - - double value = 0.0; - int optionlets = arguments_.startDates.Count; - List values = new InitializedList( optionlets,0.0 ); - List stdDevs = new InitializedList( optionlets,0.0); - List forwards = new InitializedList (optionlets,0.0); - CapFloorType type = arguments_.type; - - Handle yoyTS - = index().yoyInflationTermStructure(); - Handle nominalTS - = yoyTS.link.nominalTermStructure(); - Date settlement = nominalTS.link.referenceDate(); - - - for (int i=0; i vol) + { + if (!volatility_.empty()) + volatility_ .unregisterWith(update); + volatility_ = vol; + volatility_.registerWith(update); + update(); + } + + public override void calculate() + { + // copy black version then adapt to others + + double value = 0.0; + int optionlets = arguments_.startDates.Count; + List values = new InitializedList(optionlets, 0.0); + List stdDevs = new InitializedList(optionlets, 0.0); + List forwards = new InitializedList (optionlets, 0.0); + CapFloorType type = arguments_.type; + + Handle yoyTS + = index().yoyInflationTermStructure(); + Handle nominalTS + = yoyTS.link.nominalTermStructure(); + Date settlement = nominalTS.link.referenceDate(); + + + for (int i = 0; i < optionlets; ++i) + { Date paymentDate = arguments_.payDates[i]; - if (paymentDate > settlement) - { - // discard expired caplets + if (paymentDate > settlement) + { + // discard expired caplets double d = arguments_.nominals[i] * arguments_.gearings[i] * nominalTS.link.discount(paymentDate) * @@ -88,113 +88,114 @@ Handle nominalTS // This also means that we do not need the coupon to have // a pricing engine to return the swaplet rate and then // the adjusted fixing in the instrument. - forwards[i] = yoyTS.link.yoyRate(arguments_.fixingDates[i],new Period(0,TimeUnit.Days)); + forwards[i] = yoyTS.link.yoyRate(arguments_.fixingDates[i], new Period(0, TimeUnit.Days)); double forward = forwards[i]; Date fixingDate = arguments_.fixingDates[i]; double sqrtTime = 0.0; if (fixingDate > volatility_.link.baseDate()) - { + { sqrtTime = Math.Sqrt(volatility_.link.timeFromBase(fixingDate)); } - if (type == CapFloorType.Cap || type == CapFloorType.Collar) - { - double strike = arguments_.capRates[i].Value; - if (sqrtTime>0.0) - { - stdDevs[i] = Math.Sqrt(volatility_.link.totalVariance(fixingDate, strike, new Period(0,TimeUnit.Days))); - - } - - // sttDev=0 for already-fixed dates so everything on forward - values[i] = optionletImpl(Option.Type.Call, strike, forward, stdDevs[i], d); - } - if (type == CapFloorType.Floor || type == CapFloorType.Collar) - { - double strike = arguments_.floorRates[i].Value; - if (sqrtTime>0.0) { - stdDevs[i] = Math.Sqrt( volatility_.link.totalVariance(fixingDate, strike, new Period(0,TimeUnit.Days))); - } - double floorlet = optionletImpl(Option.Type.Put, strike, forward, stdDevs[i], d); - if (type == CapFloorType.Floor) - { - values[i] = floorlet; - } - else - { - // a collar is long a cap and short a floor - values[i] -= floorlet; - } - - } - value += values[i]; + if (type == CapFloorType.Cap || type == CapFloorType.Collar) + { + double strike = arguments_.capRates[i].Value; + if (sqrtTime > 0.0) + { + stdDevs[i] = Math.Sqrt(volatility_.link.totalVariance(fixingDate, strike, new Period(0, TimeUnit.Days))); + + } + + // sttDev=0 for already-fixed dates so everything on forward + values[i] = optionletImpl(Option.Type.Call, strike, forward, stdDevs[i], d); + } + if (type == CapFloorType.Floor || type == CapFloorType.Collar) + { + double strike = arguments_.floorRates[i].Value; + if (sqrtTime > 0.0) + { + stdDevs[i] = Math.Sqrt(volatility_.link.totalVariance(fixingDate, strike, new Period(0, TimeUnit.Days))); + } + double floorlet = optionletImpl(Option.Type.Put, strike, forward, stdDevs[i], d); + if (type == CapFloorType.Floor) + { + values[i] = floorlet; + } + else + { + // a collar is long a cap and short a floor + values[i] -= floorlet; + } + + } + value += values[i]; } - } - results_.value = value; + } + results_.value = value; - results_.additionalResults["optionletsPrice"] = values; - results_.additionalResults["optionletsAtmForward"] = forwards; - if (type != CapFloorType.Collar) + results_.additionalResults["optionletsPrice"] = values; + results_.additionalResults["optionletsAtmForward"] = forwards; + if (type != CapFloorType.Collar) results_.additionalResults["optionletsStdDev"] = stdDevs; - } + } + - //! descendents only need to implement this - protected virtual double optionletImpl( Option.Type type, double strike, double forward, double stdDev, - double d ) { throw new NotImplementedException( "not implemented" ); } + protected virtual double optionletImpl(Option.Type type, double strike, double forward, double stdDev, + double d) { throw new NotImplementedException("not implemented"); } protected YoYInflationIndex index_; protected Handle volatility_; - } - - //! Black-formula inflation cap/floor engine (standalone, i.e. no coupon pricer) - public class YoYInflationBlackCapFloorEngine : YoYInflationCapFloorEngine - { - public YoYInflationBlackCapFloorEngine( YoYInflationIndex index, Handle volatility ) - : base( index, volatility ) - { } - - protected override double optionletImpl( Option.Type type, double strike, double forward, double stdDev, - double d ) - { - return Utils.blackFormula( type, strike, forward, stdDev, d ); - } - - } - - //! Unit Displaced Black-formula inflation cap/floor engine (standalone, i.e. no coupon pricer) - public class YoYInflationUnitDisplacedBlackCapFloorEngine : YoYInflationCapFloorEngine - { - public YoYInflationUnitDisplacedBlackCapFloorEngine(YoYInflationIndex index,Handle vol) - : base( index, vol ) - { } - - protected override double optionletImpl( Option.Type type, double strike, - double forward, double stdDev, - double d ) - { - // could use displacement parameter in blackFormula but this is clearer - return Utils.blackFormula( type, strike + 1.0, forward + 1.0, stdDev, d ); - } - - } - - //! Unit Displaced Black-formula inflation cap/floor engine (standalone, i.e. no coupon pricer) - public class YoYInflationBachelierCapFloorEngine : YoYInflationCapFloorEngine - { - public YoYInflationBachelierCapFloorEngine(YoYInflationIndex index,Handle vol) - : base( index, vol ) - { } - - protected override double optionletImpl( Option.Type type, double strike, - double forward, double stdDev, - double d ) - { - return Utils.bachelierBlackFormula( type, strike, forward, stdDev, d ); - } - - - }; + } + + //! Black-formula inflation cap/floor engine (standalone, i.e. no coupon pricer) + public class YoYInflationBlackCapFloorEngine : YoYInflationCapFloorEngine + { + public YoYInflationBlackCapFloorEngine(YoYInflationIndex index, Handle volatility) + : base(index, volatility) + { } + + protected override double optionletImpl(Option.Type type, double strike, double forward, double stdDev, + double d) + { + return Utils.blackFormula(type, strike, forward, stdDev, d); + } + + } + + //! Unit Displaced Black-formula inflation cap/floor engine (standalone, i.e. no coupon pricer) + public class YoYInflationUnitDisplacedBlackCapFloorEngine : YoYInflationCapFloorEngine + { + public YoYInflationUnitDisplacedBlackCapFloorEngine(YoYInflationIndex index, Handle vol) + : base(index, vol) + { } + + protected override double optionletImpl(Option.Type type, double strike, + double forward, double stdDev, + double d) + { + // could use displacement parameter in blackFormula but this is clearer + return Utils.blackFormula(type, strike + 1.0, forward + 1.0, stdDev, d); + } + + } + + //! Unit Displaced Black-formula inflation cap/floor engine (standalone, i.e. no coupon pricer) + public class YoYInflationBachelierCapFloorEngine : YoYInflationCapFloorEngine + { + public YoYInflationBachelierCapFloorEngine(YoYInflationIndex index, Handle vol) + : base(index, vol) + { } + + protected override double optionletImpl(Option.Type type, double strike, + double forward, double stdDev, + double d) + { + return Utils.bachelierBlackFormula(type, strike, forward, stdDev, d); + } + + + } } diff --git a/src/QLNet/Pricingengines/inflation/InterpolatingCPICapFloorEngine.cs b/src/QLNet/Pricingengines/inflation/InterpolatingCPICapFloorEngine.cs index 8747faba7..28bf02eb9 100644 --- a/src/QLNet/Pricingengines/inflation/InterpolatingCPICapFloorEngine.cs +++ b/src/QLNet/Pricingengines/inflation/InterpolatingCPICapFloorEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -38,8 +38,8 @@ public override void calculate() // TODO next line will fail if units are different Period lagDiff = arguments_.observationLag - priceSurf_.link.observationLag(); // next line will fail if units are different if Period() is not well written - Utils.QL_REQUIRE(lagDiff >= new Period(0, TimeUnit.Months),()=> "InterpolatingCPICapFloorEngine: " + - "lag difference must be non-negative: " + lagDiff); + Utils.QL_REQUIRE(lagDiff >= new Period(0, TimeUnit.Months), () => "InterpolatingCPICapFloorEngine: " + + "lag difference must be non-negative: " + lagDiff); // we now need an effective maturity to use in the price surface because this uses // maturity of calibration instruments as its time axis, N.B. this must also @@ -48,56 +48,56 @@ public override void calculate() // what interpolation do we use? Index / flat / linear - if (arguments_.observationInterpolation == InterpolationType.AsIndex) + if (arguments_.observationInterpolation == InterpolationType.AsIndex) { // same as index means we can just use the price surface // since this uses the index - if (arguments_.type == Option.Type.Call) + if (arguments_.type == Option.Type.Call) { npv = priceSurf_.link.capPrice(effectiveMaturity, arguments_.strike); - } - else + } + else { npv = priceSurf_.link.floorPrice(effectiveMaturity, arguments_.strike); } - } - else + } + else { - KeyValuePair dd = Utils.inflationPeriod(effectiveMaturity, arguments_.infIndex.link.frequency()); + KeyValuePair dd = Utils.inflationPeriod(effectiveMaturity, arguments_.infIndex.link.frequency()); double priceStart = 0.0; - if (arguments_.type == Option.Type.Call) + if (arguments_.type == Option.Type.Call) { priceStart = priceSurf_.link.capPrice(dd.Key, arguments_.strike); - } - else + } + else { priceStart = priceSurf_.link.floorPrice(dd.Key, arguments_.strike); } // if we use a flat index vs the interpolated one ... - if (arguments_.observationInterpolation == InterpolationType.Flat) + if (arguments_.observationInterpolation == InterpolationType.Flat) { // then use the price for the first day in the period because the value cannot change after then npv = priceStart; - } - else + } + else { // linear interpolation will be very close double priceEnd = 0.0; - if (arguments_.type == Option.Type.Call) + if (arguments_.type == Option.Type.Call) { - priceEnd = priceSurf_.link.capPrice((dd.Value + new Period(1,TimeUnit.Days)), arguments_.strike); - } - else + priceEnd = priceSurf_.link.capPrice((dd.Value + new Period(1, TimeUnit.Days)), arguments_.strike); + } + else { - priceEnd = priceSurf_.link.floorPrice((dd.Value + new Period(1,TimeUnit.Days)), arguments_.strike); + priceEnd = priceSurf_.link.floorPrice((dd.Value + new Period(1, TimeUnit.Days)), arguments_.strike); } npv = priceStart + (priceEnd - priceStart) * (effectiveMaturity - dd.Key) - / ( (dd.Value + new Period(1,TimeUnit.Days)) - dd.Key); // can't get to next period' + / ((dd.Value + new Period(1, TimeUnit.Days)) - dd.Key); // can't get to next period' } } diff --git a/src/QLNet/Pricingengines/latticeshortratemodelengine.cs b/src/QLNet/Pricingengines/latticeshortratemodelengine.cs deleted file mode 100644 index 3a7929a16..000000000 --- a/src/QLNet/Pricingengines/latticeshortratemodelengine.cs +++ /dev/null @@ -1,66 +0,0 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet{ - - //! Engine for a short-rate model specialized on a lattice - /*! Derived engines only need to implement the calculate() - method - */ - public class LatticeShortRateModelEngine - : GenericModelEngine - where ArgumentsType : IPricingEngineArguments, new() - where ResultsType : IPricingEngineResults, new() - - { - protected TimeGrid timeGrid_; - protected int timeSteps_; - protected Lattice lattice_; - - public LatticeShortRateModelEngine( ShortRateModel model, - int timeSteps) - : base(model) - { - timeSteps_=timeSteps; - Utils.QL_REQUIRE(timeSteps > 0,()=> "timeSteps must be positive, " + timeSteps + " not allowed"); - } - - public LatticeShortRateModelEngine( ShortRateModel model, - TimeGrid timeGrid) - : base(model) { - timeGrid_ = new TimeGrid(timeGrid.Last(),timeGrid.size()-1 /*timeGrid.dt(1) - timeGrid.dt(0)*/); - timeGrid_=timeGrid; - timeSteps_=0; - lattice_=this.model_.link.tree(timeGrid); - } - - #region PricingEngine - #region Observer & Observable - public override void update() - { - if (!timeGrid_.empty()) - lattice_ = this.model_.link.tree(timeGrid_); - notifyObservers(); - } - #endregion - #endregion - } - -} \ No newline at end of file diff --git a/src/QLNet/Pricingengines/swaption/blackswaptionengine.cs b/src/QLNet/Pricingengines/swaption/BlackSwaptionEngine.cs similarity index 69% rename from src/QLNet/Pricingengines/swaption/blackswaptionengine.cs rename to src/QLNet/Pricingengines/swaption/BlackSwaptionEngine.cs index e729407b7..234acee41 100644 --- a/src/QLNet/Pricingengines/swaption/blackswaptionengine.cs +++ b/src/QLNet/Pricingengines/swaption/BlackSwaptionEngine.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,48 +29,48 @@ public interface ISwaptionEngineSpec VolatilityType type(); double value(Option.Type type, double strike, double atmForward, double stdDev, double annuity, - double displacement = 0.0); + double displacement = 0.0); double vega(double strike, double atmForward, double stdDev, double exerciseTime, double annuity, - double displacement = 0.0); + double displacement = 0.0); } /*! Generic Black-style-formula swaption engine This is the base class for the Black and Bachelier swaption engines */ public class BlackStyleSwaptionEngine : SwaptionEngine - where Spec : ISwaptionEngineSpec, new() + where Spec : ISwaptionEngineSpec, new () { public enum CashAnnuityModel { SwapRate, DiscountCurve - }; + } public BlackStyleSwaptionEngine(Handle discountCurve, - double vol, - DayCounter dc = null, - double? displacement = 0.0, - CashAnnuityModel model = CashAnnuityModel.DiscountCurve) + double vol, + DayCounter dc = null, + double? displacement = 0.0, + CashAnnuityModel model = CashAnnuityModel.DiscountCurve) { dc = dc == null ? new Actual365Fixed() : dc; discountCurve_ = discountCurve; vol_ = new Handle(new ConstantSwaptionVolatility(0, new NullCalendar(), - BusinessDayConvention.Following, vol, dc, new Spec().type(), displacement)); + BusinessDayConvention.Following, vol, dc, new Spec().type(), displacement)); model_ = model; displacement_ = displacement; discountCurve_.registerWith(update); } public BlackStyleSwaptionEngine(Handle discountCurve, - Handle vol, - DayCounter dc = null, - double? displacement = 0.0, - CashAnnuityModel model = CashAnnuityModel.DiscountCurve) + Handle vol, + DayCounter dc = null, + double? displacement = 0.0, + CashAnnuityModel model = CashAnnuityModel.DiscountCurve) { dc = dc == null ? new Actual365Fixed() : dc; discountCurve_ = discountCurve; vol_ = new Handle(new ConstantSwaptionVolatility(0, new NullCalendar(), - BusinessDayConvention.Following, vol, dc, new Spec().type(), displacement)); + BusinessDayConvention.Following, vol, dc, new Spec().type(), displacement)); model_ = model; displacement_ = displacement; discountCurve_.registerWith(update); @@ -78,9 +78,9 @@ public BlackStyleSwaptionEngine(Handle discountCurve, } public BlackStyleSwaptionEngine(Handle discountCurve, - Handle volatility, - double? displacement = 0.0, - CashAnnuityModel model = CashAnnuityModel.DiscountCurve) + Handle volatility, + double? displacement = 0.0, + CashAnnuityModel model = CashAnnuityModel.DiscountCurve) { discountCurve_ = discountCurve; vol_ = volatility; @@ -105,11 +105,11 @@ public override void calculate() List fixedLeg = swap.fixedLeg(); FixedRateCoupon firstCoupon = fixedLeg[0] as FixedRateCoupon; - Utils.QL_REQUIRE(firstCoupon!=null,()=> "wrong coupon type"); + Utils.QL_REQUIRE(firstCoupon != null, () => "wrong coupon type"); Utils.QL_REQUIRE(firstCoupon.accrualStartDate() >= exerciseDate, - () => "swap start (" + firstCoupon.accrualStartDate() + ") before exercise date (" - + exerciseDate + ") not supported in Black swaption engine"); + () => "swap start (" + firstCoupon.accrualStartDate() + ") before exercise date (" + + exerciseDate + ") not supported in Black swaption engine"); // using the forecasting curve swap.setPricingEngine(new DiscountingSwapEngine(swap.iborIndex().forwardingTermStructure())); @@ -149,13 +149,13 @@ public override void calculate() // we assume that the cash settlement date is equal // to the swap start date Date discountDate = model_ == CashAnnuityModel.DiscountCurve - ? firstCoupon.accrualStartDate() - : discountCurve_.link.referenceDate(); + ? firstCoupon.accrualStartDate() + : discountCurve_.link.referenceDate(); double fixedLegCashBPS = CashFlows.bps(fixedLeg, - new InterestRate(atmForward, dayCount, Compounding.Compounded, Frequency.Annual), false, - discountDate); + new InterestRate(atmForward, dayCount, Compounding.Compounded, Frequency.Annual), false, + discountDate); annuity = Math.Abs(fixedLegCashBPS / basisPoint) * discountCurve_.link.discount(discountDate); break; @@ -167,15 +167,15 @@ public override void calculate() results_.additionalResults["annuity"] = annuity; double swapLength = vol_.link.swapLength(swap.floatingSchedule().dates().First(), - swap.floatingSchedule().dates().Last()); + swap.floatingSchedule().dates().Last()); results_.additionalResults["swapLength"] = swapLength; double variance = vol_.link.blackVariance(exerciseDate, - swapLength, - strike); + swapLength, + strike); double displacement = displacement_ == null - ? vol_.link.shift(exerciseDate, swapLength) - : Convert.ToDouble(displacement_); + ? vol_.link.shift(exerciseDate, swapLength) + : Convert.ToDouble(displacement_); double stdDev = Math.Sqrt(variance); results_.additionalResults["stdDev"] = stdDev; Option.Type w = (arguments_.type == VanillaSwap.Type.Payer) ? Option.Type.Call : Option.Type.Put; @@ -218,13 +218,13 @@ public Black76Spec() } public double value(Option.Type type, double strike, double atmForward, double stdDev, double annuity, - double displacement = 0.0) + double displacement = 0.0) { return Utils.blackFormula(type, strike, atmForward, stdDev, annuity, displacement); } public double vega(double strike, double atmForward, double stdDev, double exerciseTime, double annuity, - double displacement = 0.0) + double displacement = 0.0) { return Math.Sqrt(exerciseTime) * Utils.blackFormulaStdDevDerivative(strike, atmForward, stdDev, annuity, displacement); @@ -247,13 +247,13 @@ public BachelierSpec() } public double value(Option.Type type, double strike, double atmForward, double stdDev, double annuity, - double displacement = 0.0) + double displacement = 0.0) { return Utils.bachelierBlackFormula(type, strike, atmForward, stdDev, annuity); } public double vega(double strike, double atmForward, double stdDev, double exerciseTime, double annuity, - double displacement = 0.0) + double displacement = 0.0) { return Math.Sqrt(exerciseTime) * Utils.bachelierBlackFormulaStdDevDerivative(strike, atmForward, stdDev, annuity); @@ -263,51 +263,51 @@ public double vega(double strike, double atmForward, double stdDev, double exerc public class BlackSwaptionEngine : BlackStyleSwaptionEngine { public BlackSwaptionEngine(Handle discountCurve, - double vol, DayCounter dc = null, - double? displacement = 0.0, - CashAnnuityModel model = CashAnnuityModel.DiscountCurve) - : base(discountCurve, vol, dc, displacement, model) + double vol, DayCounter dc = null, + double? displacement = 0.0, + CashAnnuityModel model = CashAnnuityModel.DiscountCurve) + : base(discountCurve, vol, dc, displacement, model) { } public BlackSwaptionEngine(Handle discountCurve, - Handle vol, DayCounter dc = null, - double? displacement = 0.0, - CashAnnuityModel model = CashAnnuityModel.DiscountCurve) - : base(discountCurve, vol, dc, displacement, model) + Handle vol, DayCounter dc = null, + double? displacement = 0.0, + CashAnnuityModel model = CashAnnuityModel.DiscountCurve) + : base(discountCurve, vol, dc, displacement, model) { } public BlackSwaptionEngine(Handle discountCurve, - Handle vol, - double? displacement = null, - CashAnnuityModel model = CashAnnuityModel.DiscountCurve) - : base(discountCurve, vol, displacement, model) + Handle vol, + double? displacement = null, + CashAnnuityModel model = CashAnnuityModel.DiscountCurve) + : base(discountCurve, vol, displacement, model) { Utils.QL_REQUIRE(vol.link.volatilityType() == VolatilityType.ShiftedLognormal, - () => "BlackSwaptionEngine requires (shifted) lognormal input volatility"); + () => "BlackSwaptionEngine requires (shifted) lognormal input volatility"); } } public class BachelierSwaptionEngine : BlackStyleSwaptionEngine { public BachelierSwaptionEngine(Handle discountCurve, - double vol, DayCounter dc = null, - CashAnnuityModel model = CashAnnuityModel.DiscountCurve) + double vol, DayCounter dc = null, + CashAnnuityModel model = CashAnnuityModel.DiscountCurve) : base(discountCurve, vol, dc, 0.0, model) { } public BachelierSwaptionEngine(Handle discountCurve, - Handle vol, DayCounter dc = null, - CashAnnuityModel model = CashAnnuityModel.DiscountCurve) + Handle vol, DayCounter dc = null, + CashAnnuityModel model = CashAnnuityModel.DiscountCurve) : base(discountCurve, vol, dc, 0.0, model) { } public BachelierSwaptionEngine(Handle discountCurve, - Handle vol, - CashAnnuityModel model = CashAnnuityModel.DiscountCurve) + Handle vol, + CashAnnuityModel model = CashAnnuityModel.DiscountCurve) : base(discountCurve, vol, 0.0, model) { Utils.QL_REQUIRE(vol.link.volatilityType() == VolatilityType.Normal, - () => "BachelierSwaptionEngine requires normal input volatility"); + () => "BachelierSwaptionEngine requires normal input volatility"); } } } diff --git a/src/QLNet/Pricingengines/swaption/DiscretizedSwaption.cs b/src/QLNet/Pricingengines/swaption/DiscretizedSwaption.cs new file mode 100644 index 000000000..ef2694122 --- /dev/null +++ b/src/QLNet/Pricingengines/swaption/DiscretizedSwaption.cs @@ -0,0 +1,101 @@ +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QLNet +{ + public class DiscretizedSwaption : DiscretizedOption + { + + private Swaption.Arguments arguments_; + private double lastPayment_; + + public DiscretizedSwaption(Swaption.Arguments args, + Date referenceDate, + DayCounter dayCounter) + : base(new DiscretizedSwap(args, referenceDate, dayCounter), args.exercise.type(), new List()) + { + arguments_ = args; + exerciseTimes_ = new InitializedList(arguments_.exercise.dates().Count); + for (int i = 0; i < exerciseTimes_.Count; ++i) + exerciseTimes_[i] = + dayCounter.yearFraction(referenceDate, + arguments_.exercise.date(i)); + + // Date adjustments can get time vectors out of synch. + // Here, we try and collapse similar dates which could cause + // a mispricing. + for (int i = 0; i < arguments_.exercise.dates().Count; i++) + { + Date exerciseDate = arguments_.exercise.date(i); + for (int j = 0; j < arguments_.fixedPayDates.Count; j++) + { + if (withinNextWeek(exerciseDate, + arguments_.fixedPayDates[j]) + // coupons in the future are dealt with below + && arguments_.fixedResetDates[j] < referenceDate) + arguments_.fixedPayDates[j] = exerciseDate; + } + for (int j = 0; j < arguments_.fixedResetDates.Count; j++) + { + if (withinPreviousWeek(exerciseDate, + arguments_.fixedResetDates[j])) + arguments_.fixedResetDates[j] = exerciseDate; + } + for (int j = 0; j < arguments_.floatingResetDates.Count; j++) + { + if (withinPreviousWeek(exerciseDate, + arguments_.floatingResetDates[j])) + arguments_.floatingResetDates[j] = exerciseDate; + } + } + + double lastFixedPayment = + dayCounter.yearFraction(referenceDate, + arguments_.fixedPayDates.Last()); + double lastFloatingPayment = + dayCounter.yearFraction(referenceDate, + arguments_.floatingPayDates.Last()); + lastPayment_ = Math.Max(lastFixedPayment, lastFloatingPayment); + + underlying_ = new DiscretizedSwap(arguments_, + referenceDate, + dayCounter); + + } + + public override void reset(int size) + { + underlying_.initialize(method(), lastPayment_); + base.reset(size); + } + + public bool withinPreviousWeek(Date d1, Date d2) + { + return d2 >= d1 - 7 && d2 <= d1; + } + + public bool withinNextWeek(Date d1, Date d2) + { + return d2 >= d1 && d2 <= d1 + 7; + } + } +} diff --git a/src/QLNet/Pricingengines/swaption/G2SwaptionEngine.cs b/src/QLNet/Pricingengines/swaption/G2SwaptionEngine.cs new file mode 100644 index 000000000..7ed97cbaf --- /dev/null +++ b/src/QLNet/Pricingengines/swaption/G2SwaptionEngine.cs @@ -0,0 +1,71 @@ +/* + Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + + +using System; + +namespace QLNet +{ + // Swaption pricing engine for two-factor additive Gaussian Model G2 + + + //! %Swaption priced by means of the Black formula + /*! \ingroup swaptionengines + + \warning The engine assumes that the exercise date equals the + start date of the passed swap. + */ + public class G2SwaptionEngine : GenericModelEngine + { + double range_; + int intervals_; + + // range is the number of standard deviations to use in the + // exponential term of the integral for the european swaption. + // intervals is the number of intervals to use in the integration. + public G2SwaptionEngine(G2 model, + double range, + int intervals) + : base(model) + { + + range_ = range; + intervals_ = intervals; + } + + public override void calculate() + { + Utils.QL_REQUIRE(arguments_.settlementType == Settlement.Type.Physical, () => + "cash-settled swaptions not priced with G2 engine"); + + // adjust the fixed rate of the swap for the spread on the + // floating leg (which is not taken into account by the + // model) + VanillaSwap swap = arguments_.swap; + swap.setPricingEngine(new DiscountingSwapEngine(model_.link.termStructure())); + double correction = swap.spread * + Math.Abs(swap.floatingLegBPS() / swap.fixedLegBPS()); + double fixedRate = swap.fixedRate - correction; + + results_.value = model_.link.swaption(arguments_, fixedRate, + range_, intervals_); + } + + } + +} \ No newline at end of file diff --git a/src/QLNet/Pricingengines/swaption/JamshidianSwaptionEngine.cs b/src/QLNet/Pricingengines/swaption/JamshidianSwaptionEngine.cs new file mode 100644 index 000000000..10ea94593 --- /dev/null +++ b/src/QLNet/Pricingengines/swaption/JamshidianSwaptionEngine.cs @@ -0,0 +1,170 @@ +/* + Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QLNet +{ + //! Jamshidian swaption engine + /*! \ingroup swaptionengines + + \warning The engine assumes that the exercise date equals the + start date of the passed swap. + */ + + public class JamshidianSwaptionEngine : GenericModelEngine + { + + /*! \note the term structure is only needed when the short-rate + model cannot provide one itself. + */ + public JamshidianSwaptionEngine(OneFactorAffineModel model, + Handle termStructure) + : base(model) + { + termStructure_ = termStructure; + termStructure_.registerWith(update); + } + + public JamshidianSwaptionEngine(OneFactorAffineModel model) + : this(model, new Handle()) + { } + + private Handle termStructure_; + + public class rStarFinder : ISolver1d + { + + public rStarFinder(OneFactorAffineModel model, + double nominal, + double maturity, + List fixedPayTimes, + List amounts) + { + strike_ = nominal; + maturity_ = maturity; + times_ = fixedPayTimes; + amounts_ = amounts; + model_ = model; + } + + public override double value(double x) + { + double value = strike_; + int size = times_.Count; + for (int i = 0; i < size; i++) + { + double dbValue = + model_.discountBond(maturity_, times_[i], x); + value -= amounts_[i] * dbValue; + } + return value; + } + + private double strike_; + private double maturity_; + private List times_; + private List amounts_; + private OneFactorAffineModel model_; + } + + public override void calculate() + { + Utils.QL_REQUIRE(arguments_.settlementType == Settlement.Type.Physical, () => + "cash-settled swaptions not priced by Jamshidian engine"); + + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => + "cannot use the Jamshidian decomposition on exotic swaptions"); + + Utils.QL_REQUIRE(arguments_.swap.spread.IsEqual(0.0), () => + "non zero spread (" + arguments_.swap.spread + ") not allowed"); + + Date referenceDate; + DayCounter dayCounter; + + ITermStructureConsistentModel tsmodel = (ITermStructureConsistentModel)base.model_.link; + try + { + if (tsmodel != null) + { + referenceDate = tsmodel.termStructure().link.referenceDate(); + dayCounter = tsmodel.termStructure().link.dayCounter(); + } + else + { + referenceDate = termStructure_.link.referenceDate(); + dayCounter = termStructure_.link.dayCounter(); + } + } + catch + { + referenceDate = termStructure_.link.referenceDate(); + dayCounter = termStructure_.link.dayCounter(); + } + + List amounts = new InitializedList(arguments_.fixedCoupons.Count); + for (int i = 0; i < amounts.Count; i++) + amounts[i] = arguments_.fixedCoupons[i]; + amounts[amounts.Count - 1] = amounts.Last() + arguments_.nominal; + + double maturity = dayCounter.yearFraction(referenceDate, + arguments_.exercise.date(0)); + + List fixedPayTimes = new InitializedList(arguments_.fixedPayDates.Count); + for (int i = 0; i < fixedPayTimes.Count; i++) + fixedPayTimes[i] = + dayCounter.yearFraction(referenceDate, + arguments_.fixedPayDates[i]); + + rStarFinder finder = new rStarFinder(model_, arguments_.nominal, maturity, + fixedPayTimes, amounts); + Brent s1d = new Brent(); + double minStrike = -10.0; + double maxStrike = 10.0; + s1d.setMaxEvaluations(10000); + s1d.setLowerBound(minStrike); + s1d.setUpperBound(maxStrike); + double rStar = s1d.solve(finder, 1e-8, 0.05, minStrike, maxStrike); + + Option.Type w = arguments_.type == VanillaSwap.Type.Payer ? + Option.Type.Put : Option.Type.Call; + int size = arguments_.fixedCoupons.Count; + + double value = 0.0; + for (int i = 0; i < size; i++) + { + double fixedPayTime = + dayCounter.yearFraction(referenceDate, + arguments_.fixedPayDates[i]); + double strike = model_.link.discountBond(maturity, + fixedPayTime, + rStar); + double dboValue = model_.link.discountBondOption( + w, strike, maturity, + fixedPayTime); + value += amounts[i] * dboValue; + } + results_.value = value; + } + } +} \ No newline at end of file diff --git a/src/QLNet/Pricingengines/swaption/TreeSwaptionEngine.cs b/src/QLNet/Pricingengines/swaption/TreeSwaptionEngine.cs new file mode 100644 index 000000000..48bb3af0b --- /dev/null +++ b/src/QLNet/Pricingengines/swaption/TreeSwaptionEngine.cs @@ -0,0 +1,138 @@ +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QLNet +{ + //! Numerical lattice engine for swaptions + /*! \ingroup swaptionengines + + \warning This engine is not guaranteed to work if the + underlying swap has a start date in the past, i.e., + before today's date. When using this engine, prune + the initial part of the swap so that it starts at + \f$ t \geq 0 \f$. + + \test calculations are checked against cached results + */ + public class TreeSwaptionEngine + : LatticeShortRateModelEngine + { + + private Handle termStructure_; + + /* Constructors + \note the term structure is only needed when the short-rate + model cannot provide one itself. + */ + public TreeSwaptionEngine(ShortRateModel model, + int timeSteps) + : this(model, timeSteps, new Handle()) + { } + public TreeSwaptionEngine(ShortRateModel model, + int timeSteps, + Handle termStructure) + : base(model, timeSteps) + { + termStructure_ = termStructure; + termStructure_.registerWith(update); + } + public TreeSwaptionEngine(ShortRateModel model, + TimeGrid timeGrid) + : this(model, timeGrid, new Handle()) + { } + public TreeSwaptionEngine(ShortRateModel model, + TimeGrid timeGrid, + Handle termStructure) + : base(model, timeGrid) + { + termStructure_ = new Handle(); + termStructure_ = termStructure; + termStructure_.registerWith(update); + } + + public override void calculate() + { + + Utils.QL_REQUIRE(arguments_.settlementType == Settlement.Type.Physical, () => + "cash-settled swaptions not priced with tree engine"); + + Utils.QL_REQUIRE(model_ != null, () => "no model specified"); + + Date referenceDate; + DayCounter dayCounter; + + ITermStructureConsistentModel tsmodel = + (ITermStructureConsistentModel)base.model_.link; + try + { + if (tsmodel != null) + { + referenceDate = tsmodel.termStructure().link.referenceDate(); + dayCounter = tsmodel.termStructure().link.dayCounter(); + } + else + { + referenceDate = termStructure_.link.referenceDate(); + dayCounter = termStructure_.link.dayCounter(); + } + } + catch + { + referenceDate = termStructure_.link.referenceDate(); + dayCounter = termStructure_.link.dayCounter(); + } + + DiscretizedSwaption swaption = new DiscretizedSwaption(arguments_, referenceDate, dayCounter); + Lattice lattice ; + + if (lattice_ != null) + { + lattice = lattice_; + } + else + { + List times = swaption.mandatoryTimes(); + TimeGrid timeGrid = new TimeGrid(times, times.Count, timeSteps_); + lattice = model_.link.tree(timeGrid); + } + + List stoppingTimes = new InitializedList(arguments_.exercise.dates().Count); + for (int i = 0; i < stoppingTimes.Count; ++i) + stoppingTimes[i] = + dayCounter.yearFraction(referenceDate, + arguments_.exercise.date(i)); + + swaption.initialize(lattice, stoppingTimes.Last()); + + double nextExercise; + + List listExercise = new List(); + listExercise.AddRange(stoppingTimes.FindAll(x => x >= 0)); + nextExercise = listExercise[0]; + swaption.rollback(nextExercise); + + results_.value = swaption.presentValue(); + } + + } +} diff --git a/src/QLNet/Pricingengines/swaption/discretizedswaption.cs b/src/QLNet/Pricingengines/swaption/discretizedswaption.cs deleted file mode 100644 index a709527df..000000000 --- a/src/QLNet/Pricingengines/swaption/discretizedswaption.cs +++ /dev/null @@ -1,93 +0,0 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace QLNet -{ - public class DiscretizedSwaption : DiscretizedOption { - - private Swaption.Arguments arguments_; - private double lastPayment_; - - public DiscretizedSwaption(Swaption.Arguments args, - Date referenceDate, - DayCounter dayCounter) - : base(new DiscretizedSwap(args, referenceDate, dayCounter), args.exercise.type(), new List()) - { - arguments_=args; - exerciseTimes_ = new InitializedList(arguments_.exercise.dates().Count); - for (int i = 0; i < exerciseTimes_.Count; ++i) - exerciseTimes_[i] = - dayCounter.yearFraction(referenceDate, - arguments_.exercise.date(i)); - - // Date adjustments can get time vectors out of synch. - // Here, we try and collapse similar dates which could cause - // a mispricing. - for (int i=0; i= d1-7 && d2 <= d1; - } - - public bool withinNextWeek( Date d1, Date d2) { - return d2 >= d1 && d2 <= d1+7; - } - } -} diff --git a/src/QLNet/Pricingengines/swaption/g2swaptionengine.cs b/src/QLNet/Pricingengines/swaption/g2swaptionengine.cs deleted file mode 100644 index 34ecdd25c..000000000 --- a/src/QLNet/Pricingengines/swaption/g2swaptionengine.cs +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - - -using System; - -namespace QLNet -{ - // Swaption pricing engine for two-factor additive Gaussian Model G2 + + - //! %Swaption priced by means of the Black formula - /*! \ingroup swaptionengines - - \warning The engine assumes that the exercise date equals the - start date of the passed swap. - */ - public class G2SwaptionEngine : GenericModelEngine { - double range_; - int intervals_; - - // range is the number of standard deviations to use in the - // exponential term of the integral for the european swaption. - // intervals is the number of intervals to use in the integration. - public G2SwaptionEngine(G2 model, - double range, - int intervals) - : base(model){ - - range_ = range; - intervals_ = intervals; - } - - public override void calculate() { - Utils.QL_REQUIRE(arguments_.settlementType == Settlement.Type.Physical,()=> - "cash-settled swaptions not priced with G2 engine"); - - // adjust the fixed rate of the swap for the spread on the - // floating leg (which is not taken into account by the - // model) - VanillaSwap swap = arguments_.swap; - swap.setPricingEngine(new DiscountingSwapEngine(model_.link.termStructure())); - double correction = swap.spread * - Math.Abs(swap.floatingLegBPS() / swap.fixedLegBPS()); - double fixedRate = swap.fixedRate - correction; - - results_.value = model_.link.swaption(arguments_, fixedRate, - range_, intervals_); - } - - } - -} \ No newline at end of file diff --git a/src/QLNet/Pricingengines/swaption/jamshidianswaptionengine.cs b/src/QLNet/Pricingengines/swaption/jamshidianswaptionengine.cs deleted file mode 100644 index 1dd8078c5..000000000 --- a/src/QLNet/Pricingengines/swaption/jamshidianswaptionengine.cs +++ /dev/null @@ -1,170 +0,0 @@ -/* - Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; -using System.Collections.Generic; -using System.Linq; - -namespace QLNet -{ - //! Jamshidian swaption engine - /*! \ingroup swaptionengines - - \warning The engine assumes that the exercise date equals the - start date of the passed swap. - */ - - public class JamshidianSwaptionEngine : GenericModelEngine - { - - /*! \note the term structure is only needed when the short-rate - model cannot provide one itself. - */ - public JamshidianSwaptionEngine(OneFactorAffineModel model, - Handle termStructure) - : base(model) - { - termStructure_ = termStructure; - termStructure_.registerWith(update); - } - - public JamshidianSwaptionEngine(OneFactorAffineModel model) - : this(model, new Handle()) - { } - - private Handle termStructure_; - - public class rStarFinder : ISolver1d - { - - public rStarFinder(OneFactorAffineModel model, - double nominal, - double maturity, - List fixedPayTimes, - List amounts) - { - strike_ = nominal; - maturity_ = maturity; - times_ = fixedPayTimes; - amounts_ = amounts; - model_ = model; - } - - public override double value(double x) - { - double value = strike_; - int size = times_.Count; - for (int i = 0; i < size; i++) - { - double dbValue = - model_.discountBond(maturity_, times_[i], x); - value -= amounts_[i] * dbValue; - } - return value; - } - - private double strike_; - private double maturity_; - private List times_; - private List amounts_; - private OneFactorAffineModel model_; - } - - public override void calculate() - { - Utils.QL_REQUIRE(arguments_.settlementType == Settlement.Type.Physical,()=> - "cash-settled swaptions not priced by Jamshidian engine"); - - Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European,()=> - "cannot use the Jamshidian decomposition on exotic swaptions"); - - Utils.QL_REQUIRE(arguments_.swap.spread.IsEqual(0.0) ,()=> - "non zero spread (" + arguments_.swap.spread + ") not allowed"); - - Date referenceDate; - DayCounter dayCounter; - - ITermStructureConsistentModel tsmodel = (ITermStructureConsistentModel)base.model_.link; - try - { - if (tsmodel != null) - { - referenceDate = tsmodel.termStructure().link.referenceDate(); - dayCounter = tsmodel.termStructure().link.dayCounter(); - } - else - { - referenceDate = termStructure_.link.referenceDate(); - dayCounter = termStructure_.link.dayCounter(); - } - } - catch - { - referenceDate = termStructure_.link.referenceDate(); - dayCounter = termStructure_.link.dayCounter(); - } - - List amounts = new InitializedList(arguments_.fixedCoupons.Count); - for (int i = 0; i < amounts.Count; i++) - amounts[i] = arguments_.fixedCoupons[i]; - amounts[amounts.Count-1] = amounts.Last() + arguments_.nominal; - - double maturity = dayCounter.yearFraction(referenceDate, - arguments_.exercise.date(0)); - - List fixedPayTimes = new InitializedList(arguments_.fixedPayDates.Count); - for (int i = 0; i < fixedPayTimes.Count; i++) - fixedPayTimes[i] = - dayCounter.yearFraction(referenceDate, - arguments_.fixedPayDates[i]); - - rStarFinder finder = new rStarFinder(model_, arguments_.nominal, maturity, - fixedPayTimes, amounts); - Brent s1d = new Brent(); - double minStrike = -10.0; - double maxStrike = 10.0; - s1d.setMaxEvaluations(10000); - s1d.setLowerBound(minStrike); - s1d.setUpperBound(maxStrike); - double rStar = s1d.solve(finder, 1e-8, 0.05, minStrike, maxStrike); - - Option.Type w = arguments_.type == VanillaSwap.Type.Payer ? - Option.Type.Put : Option.Type.Call; - int size = arguments_.fixedCoupons.Count; - - double value = 0.0; - for (int i = 0; i < size; i++) - { - double fixedPayTime = - dayCounter.yearFraction(referenceDate, - arguments_.fixedPayDates[i]); - double strike = model_.link.discountBond(maturity, - fixedPayTime, - rStar); - double dboValue = model_.link.discountBondOption( - w, strike, maturity, - fixedPayTime); - value += amounts[i] * dboValue; - } - results_.value = value; - } - } -} \ No newline at end of file diff --git a/src/QLNet/Pricingengines/swaption/treeswaptionengine.cs b/src/QLNet/Pricingengines/swaption/treeswaptionengine.cs deleted file mode 100644 index 274dd28b5..000000000 --- a/src/QLNet/Pricingengines/swaption/treeswaptionengine.cs +++ /dev/null @@ -1,127 +0,0 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace QLNet -{ - //! Numerical lattice engine for swaptions - /*! \ingroup swaptionengines - - \warning This engine is not guaranteed to work if the - underlying swap has a start date in the past, i.e., - before today's date. When using this engine, prune - the initial part of the swap so that it starts at - \f$ t \geq 0 \f$. - - \test calculations are checked against cached results - */ - public class TreeSwaptionEngine - : LatticeShortRateModelEngine - { - - private Handle termStructure_; - - /* Constructors - \note the term structure is only needed when the short-rate - model cannot provide one itself. - */ - public TreeSwaptionEngine(ShortRateModel model, - int timeSteps) - : this(model, timeSteps, new Handle()) - { } - public TreeSwaptionEngine(ShortRateModel model, - int timeSteps, - Handle termStructure) - : base(model, timeSteps) { - termStructure_=termStructure; - termStructure_.registerWith(update); - } - public TreeSwaptionEngine(ShortRateModel model, - TimeGrid timeGrid) - : this(model, timeGrid, new Handle()) - { } - public TreeSwaptionEngine(ShortRateModel model, - TimeGrid timeGrid, - Handle termStructure) - : base(model, timeGrid) { - termStructure_=new Handle(); - termStructure_=termStructure; - termStructure_.registerWith(update); - } - - public override void calculate(){ - - Utils.QL_REQUIRE(arguments_.settlementType == Settlement.Type.Physical,()=> - "cash-settled swaptions not priced with tree engine"); - - Utils.QL_REQUIRE(model_!= null, ()=> "no model specified"); - - Date referenceDate; - DayCounter dayCounter; - - ITermStructureConsistentModel tsmodel = - (ITermStructureConsistentModel)base.model_.link; - try { - if (tsmodel!=null) { - referenceDate = tsmodel.termStructure().link.referenceDate(); - dayCounter = tsmodel.termStructure().link.dayCounter(); - } else { - referenceDate = termStructure_.link.referenceDate(); - dayCounter = termStructure_.link.dayCounter(); - } - } - catch{ - referenceDate = termStructure_.link.referenceDate(); - dayCounter = termStructure_.link.dayCounter(); - } - - DiscretizedSwaption swaption = new DiscretizedSwaption(arguments_, referenceDate, dayCounter); - Lattice lattice ; - - if (lattice_!=null) { - lattice = lattice_; - } else { - List times = swaption.mandatoryTimes(); - TimeGrid timeGrid = new TimeGrid( times, times.Count, timeSteps_ ); - lattice = model_.link.tree(timeGrid); - } - - List stoppingTimes = new InitializedList(arguments_.exercise.dates().Count); - for (int i=0; i listExercise = new List(); - listExercise.AddRange(stoppingTimes.FindAll(x => x >= 0)); - nextExercise=listExercise[0]; - swaption.rollback(nextExercise); - - results_.value = swaption.presentValue(); - } - - } -} diff --git a/src/QLNet/Pricingengines/vanilla/AnalyticBSMHullWhiteEngine.cs b/src/QLNet/Pricingengines/vanilla/AnalyticBSMHullWhiteEngine.cs index e9122a6eb..366179189 100644 --- a/src/QLNet/Pricingengines/vanilla/AnalyticBSMHullWhiteEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/AnalyticBSMHullWhiteEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -27,13 +27,13 @@ namespace QLNet \test the correctness of the returned value is tested by reproducing results available in web/literature */ - public class AnalyticBSMHullWhiteEngine : GenericModelEngine { public AnalyticBSMHullWhiteEngine(double equityShortRateCorrelation, GeneralizedBlackScholesProcess process, HullWhite model) - :base(model) + : base(model) { rho_ = equityShortRateCorrelation; process_ = process; @@ -43,66 +43,66 @@ public AnalyticBSMHullWhiteEngine(double equityShortRateCorrelation, public override void calculate() { - Utils.QL_REQUIRE(process_.x0() > 0.0,()=> "negative or null underlying given"); + Utils.QL_REQUIRE(process_.x0() > 0.0, () => "negative or null underlying given"); StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; - Utils.QL_REQUIRE(payoff!=null,()=> "non-striked payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "non-striked payoff given"); Exercise exercise = arguments_.exercise; double t = process_.riskFreeRate().link.dayCounter().yearFraction(process_.riskFreeRate().link.referenceDate(), - exercise.lastDate()); + exercise.lastDate()); double a = model_.link.parameters()[0]; double sigma = model_.link.parameters()[1]; - double eta = process_.blackVolatility().link.blackVol(exercise.lastDate(),payoff.strike()); + double eta = process_.blackVolatility().link.blackVol(exercise.lastDate(), payoff.strike()); double varianceOffset; - if (a*t > Math.Pow(Const.QL_EPSILON, 0.25)) + if (a * t > Math.Pow(Const.QL_EPSILON, 0.25)) { - double v = sigma*sigma/(a*a) *(t + 2/a*Math.Exp(-a*t) - 1/(2*a)*Math.Exp(-2*a*t) - 3/(2*a)); - double mu = 2*rho_*sigma*eta/a*(t-1/a*(1-Math.Exp(-a*t))); + double v = sigma * sigma / (a * a) * (t + 2 / a * Math.Exp(-a * t) - 1 / (2 * a) * Math.Exp(-2 * a * t) - 3 / (2 * a)); + double mu = 2 * rho_ * sigma * eta / a * (t - 1 / a * (1 - Math.Exp(-a * t))); varianceOffset = v + mu; } - else + else { // low-a algebraic limit - double v = sigma*sigma*t*t*t*(1/3.0-0.25*a*t+7/60.0*a*a*t*t); - double mu = rho_*sigma*eta*t*t*(1-a*t/3.0+a*a*t*t/12.0); + double v = sigma * sigma * t * t * t * (1 / 3.0 - 0.25 * a * t + 7 / 60.0 * a * a * t * t); + double mu = rho_ * sigma * eta * t * t * (1 - a * t / 3.0 + a * a * t * t / 12.0); varianceOffset = v + mu; } Handle volTS = new Handle( - new ShiftedBlackVolTermStructure(varianceOffset,process_.blackVolatility())); + new ShiftedBlackVolTermStructure(varianceOffset, process_.blackVolatility())); GeneralizedBlackScholesProcess adjProcess = - new GeneralizedBlackScholesProcess(process_.stateVariable(), - process_.dividendYield(), - process_.riskFreeRate(), - volTS); + new GeneralizedBlackScholesProcess(process_.stateVariable(), + process_.dividendYield(), + process_.riskFreeRate(), + volTS); AnalyticEuropeanEngine bsmEngine = new AnalyticEuropeanEngine(adjProcess); VanillaOption option = new VanillaOption(payoff, exercise); option.setupArguments(bsmEngine.getArguments()); - + bsmEngine.calculate(); results_ = bsmEngine.getResults() as OneAssetOption.Results; - + } - + private double rho_; private GeneralizedBlackScholesProcess process_; } - - public class ShiftedBlackVolTermStructure : BlackVolTermStructure + + public class ShiftedBlackVolTermStructure : BlackVolTermStructure { - public ShiftedBlackVolTermStructure( double varianceOffset,Handle volTS) - : base(volTS.link.referenceDate(),volTS.link.calendar(),BusinessDayConvention.Following,volTS.link.dayCounter()) + public ShiftedBlackVolTermStructure(double varianceOffset, Handle volTS) + : base(volTS.link.referenceDate(), volTS.link.calendar(), BusinessDayConvention.Following, volTS.link.dayCounter()) { varianceOffset_ = varianceOffset; volTS_ = volTS; @@ -112,21 +112,21 @@ public ShiftedBlackVolTermStructure( double varianceOffset,Handle volTS_; - + } } diff --git a/src/QLNet/Pricingengines/vanilla/AnalyticDigitalAmericanEngine.cs b/src/QLNet/Pricingengines/vanilla/AnalyticDigitalAmericanEngine.cs index 3ee601a26..00ed44cf6 100644 --- a/src/QLNet/Pricingengines/vanilla/AnalyticDigitalAmericanEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/AnalyticDigitalAmericanEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -49,43 +49,43 @@ public AnalyticDigitalAmericanEngine(GeneralizedBlackScholesProcess process) public override void calculate() { AmericanExercise ex = arguments_.exercise as AmericanExercise; - Utils.QL_REQUIRE(ex != null,()=> "non-American exercise given"); - Utils.QL_REQUIRE(ex.dates()[0] <= process_.blackVolatility().link.referenceDate(),()=> - "American option with window exercise not handled yet"); + Utils.QL_REQUIRE(ex != null, () => "non-American exercise given"); + Utils.QL_REQUIRE(ex.dates()[0] <= process_.blackVolatility().link.referenceDate(), () => + "American option with window exercise not handled yet"); StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; - Utils.QL_REQUIRE(payoff!=null,()=> "non-striked payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "non-striked payoff given"); double spot = process_.stateVariable().link.value(); - Utils.QL_REQUIRE(spot > 0.0, ()=> "negative or null underlying given"); + Utils.QL_REQUIRE(spot > 0.0, () => "negative or null underlying given"); - double variance = process_.blackVolatility().link.blackVariance(ex.lastDate(),payoff.strike()); + double variance = process_.blackVolatility().link.blackVariance(ex.lastDate(), payoff.strike()); double dividendDiscount = process_.dividendYield().link.discount(ex.lastDate()); double riskFreeDiscount = process_.riskFreeRate().link.discount(ex.lastDate()); - if ( ex.payoffAtExpiry() ) + if (ex.payoffAtExpiry()) { - AmericanPayoffAtExpiry pricer = new AmericanPayoffAtExpiry( spot, riskFreeDiscount, - dividendDiscount, variance, - payoff, knock_in() ); + AmericanPayoffAtExpiry pricer = new AmericanPayoffAtExpiry(spot, riskFreeDiscount, + dividendDiscount, variance, + payoff, knock_in()); results_.value = pricer.value(); } else { - AmericanPayoffAtHit pricer = new AmericanPayoffAtHit( spot, riskFreeDiscount, dividendDiscount, variance, payoff ); + AmericanPayoffAtHit pricer = new AmericanPayoffAtHit(spot, riskFreeDiscount, dividendDiscount, variance, payoff); results_.value = pricer.value(); results_.delta = pricer.delta(); results_.gamma = pricer.gamma(); DayCounter rfdc = process_.riskFreeRate().link.dayCounter(); - double t = rfdc.yearFraction( process_.riskFreeRate().link.referenceDate(), - arguments_.exercise.lastDate() ); - results_.rho = pricer.rho( t ); + double t = rfdc.yearFraction(process_.riskFreeRate().link.referenceDate(), + arguments_.exercise.lastDate()); + results_.rho = pricer.rho(t); } - + } public virtual bool knock_in() {return true;} - + private GeneralizedBlackScholesProcess process_; } @@ -112,13 +112,13 @@ reproducing results available in literature. reproducing numerical derivatives. */ - public class AnalyticDigitalAmericanKOEngine : AnalyticDigitalAmericanEngine + public class AnalyticDigitalAmericanKOEngine : AnalyticDigitalAmericanEngine { public AnalyticDigitalAmericanKOEngine(GeneralizedBlackScholesProcess engine): - base(engine) {} + base(engine) {} public override bool knock_in() {return false;} - + } } diff --git a/src/QLNet/Pricingengines/vanilla/AnalyticDividendEuropeanEngine.cs b/src/QLNet/Pricingengines/vanilla/AnalyticDividendEuropeanEngine.cs index af7f585f5..5e0aa45d2 100644 --- a/src/QLNet/Pricingengines/vanilla/AnalyticDividendEuropeanEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/AnalyticDividendEuropeanEngine.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,86 +20,86 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! Analytic pricing engine for European options with discrete dividends - /*! \ingroup vanillaengines - - \test the correctness of the returned greeks is tested by - reproducing numerical derivatives. - */ - public class AnalyticDividendEuropeanEngine : DividendVanillaOption.Engine - { - public AnalyticDividendEuropeanEngine(GeneralizedBlackScholesProcess process) - { - process_ = process; - process_.registerWith(update); - } - - public override void calculate() - { - Utils.QL_REQUIRE( arguments_.exercise.type() == Exercise.Type.European, () => "not an European option" ); - - StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; - Utils.QL_REQUIRE( payoff != null, () => "non-striked payoff given" ); - - Date settlementDate = process_.riskFreeRate().link.referenceDate(); - double riskless = 0.0; - int i; - for (i=0; i= settlementDate) - riskless += arguments_.cashFlow[i].amount() * - process_.riskFreeRate().link.discount(arguments_.cashFlow[i].date()); - - double spot = process_.stateVariable().link.value() - riskless; - Utils.QL_REQUIRE( spot > 0.0, () => "negative or null underlying after subtracting dividends" ); - - double dividendDiscount = process_.dividendYield().link.discount(arguments_.exercise.lastDate()); - double riskFreeDiscount = process_.riskFreeRate().link.discount(arguments_.exercise.lastDate()); - double forwardPrice = spot * dividendDiscount / riskFreeDiscount; - - double variance = process_.blackVolatility().link.blackVariance( arguments_.exercise.lastDate(), - payoff.strike()); - - BlackCalculator black = new BlackCalculator(payoff, forwardPrice, Math.Sqrt(variance), riskFreeDiscount); - - results_.value = black.value(); - results_.delta = black.delta(spot); - results_.gamma = black.gamma(spot); - - DayCounter rfdc = process_.riskFreeRate().link.dayCounter(); - DayCounter voldc = process_.blackVolatility().link.dayCounter(); - double t = voldc.yearFraction( process_.blackVolatility().link.referenceDate(),arguments_.exercise.lastDate()); - results_.vega = black.vega(t); - - double delta_theta = 0.0, delta_rho = 0.0; - for (i = 0; i < arguments_.cashFlow.Count; i++) - { - Date d = arguments_.cashFlow[i].date(); - if (d >= settlementDate) - { - delta_theta -= arguments_.cashFlow[i].amount() * - process_.riskFreeRate().link.zeroRate(d,rfdc,Compounding.Continuous,Frequency.Annual).value() * - process_.riskFreeRate().link.discount(d); - double t1 = process_.time(d); - delta_rho += arguments_.cashFlow[i].amount() * t1 * - process_.riskFreeRate().link.discount(t1); - } - } - t = process_.time(arguments_.exercise.lastDate()); - try - { - results_.theta = black.theta(spot, t) + - delta_theta * black.delta(spot); - } - catch (Exception) - { - results_.theta = null; - } - - results_.rho = black.rho(t) + delta_rho * black.delta(spot); - - } - - - private GeneralizedBlackScholesProcess process_; - } + //! Analytic pricing engine for European options with discrete dividends + /*! \ingroup vanillaengines + + \test the correctness of the returned greeks is tested by + reproducing numerical derivatives. + */ + public class AnalyticDividendEuropeanEngine : DividendVanillaOption.Engine + { + public AnalyticDividendEuropeanEngine(GeneralizedBlackScholesProcess process) + { + process_ = process; + process_.registerWith(update); + } + + public override void calculate() + { + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European option"); + + StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; + Utils.QL_REQUIRE(payoff != null, () => "non-striked payoff given"); + + Date settlementDate = process_.riskFreeRate().link.referenceDate(); + double riskless = 0.0; + int i; + for (i = 0; i < arguments_.cashFlow.Count; i++) + if (arguments_.cashFlow[i].date() >= settlementDate) + riskless += arguments_.cashFlow[i].amount() * + process_.riskFreeRate().link.discount(arguments_.cashFlow[i].date()); + + double spot = process_.stateVariable().link.value() - riskless; + Utils.QL_REQUIRE(spot > 0.0, () => "negative or null underlying after subtracting dividends"); + + double dividendDiscount = process_.dividendYield().link.discount(arguments_.exercise.lastDate()); + double riskFreeDiscount = process_.riskFreeRate().link.discount(arguments_.exercise.lastDate()); + double forwardPrice = spot * dividendDiscount / riskFreeDiscount; + + double variance = process_.blackVolatility().link.blackVariance(arguments_.exercise.lastDate(), + payoff.strike()); + + BlackCalculator black = new BlackCalculator(payoff, forwardPrice, Math.Sqrt(variance), riskFreeDiscount); + + results_.value = black.value(); + results_.delta = black.delta(spot); + results_.gamma = black.gamma(spot); + + DayCounter rfdc = process_.riskFreeRate().link.dayCounter(); + DayCounter voldc = process_.blackVolatility().link.dayCounter(); + double t = voldc.yearFraction(process_.blackVolatility().link.referenceDate(), arguments_.exercise.lastDate()); + results_.vega = black.vega(t); + + double delta_theta = 0.0, delta_rho = 0.0; + for (i = 0; i < arguments_.cashFlow.Count; i++) + { + Date d = arguments_.cashFlow[i].date(); + if (d >= settlementDate) + { + delta_theta -= arguments_.cashFlow[i].amount() * + process_.riskFreeRate().link.zeroRate(d, rfdc, Compounding.Continuous, Frequency.Annual).value() * + process_.riskFreeRate().link.discount(d); + double t1 = process_.time(d); + delta_rho += arguments_.cashFlow[i].amount() * t1 * + process_.riskFreeRate().link.discount(t1); + } + } + t = process_.time(arguments_.exercise.lastDate()); + try + { + results_.theta = black.theta(spot, t) + + delta_theta * black.delta(spot); + } + catch (Exception) + { + results_.theta = null; + } + + results_.rho = black.rho(t) + delta_rho * black.delta(spot); + + } + + + private GeneralizedBlackScholesProcess process_; + } } diff --git a/src/QLNet/Pricingengines/vanilla/AnalyticEuropeanEngine.cs b/src/QLNet/Pricingengines/vanilla/AnalyticEuropeanEngine.cs index fc64205b6..4ad4d3671 100644 --- a/src/QLNet/Pricingengines/vanilla/AnalyticEuropeanEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/AnalyticEuropeanEngine.cs @@ -1,103 +1,110 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - //! Pricing engine for European vanilla options using analytical formulae - /*! \ingroup vanillaengines - - \test - - the correctness of the returned value is tested by - reproducing results available in literature. - - the correctness of the returned greeks is tested by - reproducing results available in literature. - - the correctness of the returned greeks is tested by - reproducing numerical derivatives. - - the correctness of the returned implied volatility is tested - by using it for reproducing the target value. - - the implied-volatility calculation is tested by checking - that it does not modify the option. - - the correctness of the returned value in case of - cash-or-nothing digital payoff is tested by reproducing - results available in literature. - - the correctness of the returned value in case of - asset-or-nothing digital payoff is tested by reproducing - results available in literature. - - the correctness of the returned value in case of gap digital - payoff is tested by reproducing results available in - literature. - - the correctness of the returned greeks in case of - cash-or-nothing digital payoff is tested by reproducing - numerical derivatives. - */ - public class AnalyticEuropeanEngine : VanillaOption.Engine { - private GeneralizedBlackScholesProcess process_; - - public AnalyticEuropeanEngine(GeneralizedBlackScholesProcess process) { - process_ = process; - - process_.registerWith(update); - } - - public override void calculate() { - - Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European,()=> "not an European option"); - - StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; - Utils.QL_REQUIRE(payoff != null,()=> "non-striked payoff given"); - - double variance = process_.blackVolatility().link.blackVariance(arguments_.exercise.lastDate(), payoff.strike()); - double dividendDiscount = process_.dividendYield().link.discount(arguments_.exercise.lastDate()); - double riskFreeDiscount = process_.riskFreeRate().link.discount(arguments_.exercise.lastDate()); - double spot = process_.stateVariable().link.value(); - Utils.QL_REQUIRE(spot > 0.0,()=> "negative or null underlying given"); - double forwardPrice = spot * dividendDiscount / riskFreeDiscount; - - BlackCalculator black = new BlackCalculator(payoff, forwardPrice, Math.Sqrt(variance), riskFreeDiscount); - - results_.value = black.value(); - results_.delta = black.delta(spot); - results_.deltaForward = black.deltaForward(); - results_.elasticity = black.elasticity(spot); - results_.gamma = black.gamma(spot); - - DayCounter rfdc = process_.riskFreeRate().link.dayCounter(); - DayCounter divdc = process_.dividendYield().link.dayCounter(); - DayCounter voldc = process_.blackVolatility().link.dayCounter(); - double t = rfdc.yearFraction(process_.riskFreeRate().link.referenceDate(), arguments_.exercise.lastDate()); - results_.rho = black.rho(t); - - t = divdc.yearFraction(process_.dividendYield().link.referenceDate(), arguments_.exercise.lastDate()); - results_.dividendRho = black.dividendRho(t); - - t = voldc.yearFraction(process_.blackVolatility().link.referenceDate(), arguments_.exercise.lastDate()); - results_.vega = black.vega(t); - try { - results_.theta = black.theta(spot, t); - results_.thetaPerDay = black.thetaPerDay(spot, t); - } catch { - results_.theta = null; - results_.thetaPerDay = null; - } - - results_.strikeSensitivity = black.strikeSensitivity(); - results_.itmCashProbability = black.itmCashProbability(); - } - } +namespace QLNet +{ + //! Pricing engine for European vanilla options using analytical formulae + /*! \ingroup vanillaengines + + \test + - the correctness of the returned value is tested by + reproducing results available in literature. + - the correctness of the returned greeks is tested by + reproducing results available in literature. + - the correctness of the returned greeks is tested by + reproducing numerical derivatives. + - the correctness of the returned implied volatility is tested + by using it for reproducing the target value. + - the implied-volatility calculation is tested by checking + that it does not modify the option. + - the correctness of the returned value in case of + cash-or-nothing digital payoff is tested by reproducing + results available in literature. + - the correctness of the returned value in case of + asset-or-nothing digital payoff is tested by reproducing + results available in literature. + - the correctness of the returned value in case of gap digital + payoff is tested by reproducing results available in + literature. + - the correctness of the returned greeks in case of + cash-or-nothing digital payoff is tested by reproducing + numerical derivatives. + */ + public class AnalyticEuropeanEngine : VanillaOption.Engine + { + private GeneralizedBlackScholesProcess process_; + + public AnalyticEuropeanEngine(GeneralizedBlackScholesProcess process) + { + process_ = process; + + process_.registerWith(update); + } + + public override void calculate() + { + + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European option"); + + StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; + Utils.QL_REQUIRE(payoff != null, () => "non-striked payoff given"); + + double variance = process_.blackVolatility().link.blackVariance(arguments_.exercise.lastDate(), payoff.strike()); + double dividendDiscount = process_.dividendYield().link.discount(arguments_.exercise.lastDate()); + double riskFreeDiscount = process_.riskFreeRate().link.discount(arguments_.exercise.lastDate()); + double spot = process_.stateVariable().link.value(); + Utils.QL_REQUIRE(spot > 0.0, () => "negative or null underlying given"); + double forwardPrice = spot * dividendDiscount / riskFreeDiscount; + + BlackCalculator black = new BlackCalculator(payoff, forwardPrice, Math.Sqrt(variance), riskFreeDiscount); + + results_.value = black.value(); + results_.delta = black.delta(spot); + results_.deltaForward = black.deltaForward(); + results_.elasticity = black.elasticity(spot); + results_.gamma = black.gamma(spot); + + DayCounter rfdc = process_.riskFreeRate().link.dayCounter(); + DayCounter divdc = process_.dividendYield().link.dayCounter(); + DayCounter voldc = process_.blackVolatility().link.dayCounter(); + double t = rfdc.yearFraction(process_.riskFreeRate().link.referenceDate(), arguments_.exercise.lastDate()); + results_.rho = black.rho(t); + + t = divdc.yearFraction(process_.dividendYield().link.referenceDate(), arguments_.exercise.lastDate()); + results_.dividendRho = black.dividendRho(t); + + t = voldc.yearFraction(process_.blackVolatility().link.referenceDate(), arguments_.exercise.lastDate()); + results_.vega = black.vega(t); + try + { + results_.theta = black.theta(spot, t); + results_.thetaPerDay = black.thetaPerDay(spot, t); + } + catch + { + results_.theta = null; + results_.thetaPerDay = null; + } + + results_.strikeSensitivity = black.strikeSensitivity(); + results_.itmCashProbability = black.itmCashProbability(); + } + } } diff --git a/src/QLNet/Pricingengines/vanilla/AnalyticH1HWEngine.cs b/src/QLNet/Pricingengines/vanilla/AnalyticH1HWEngine.cs index e34e0de55..9fe781f1b 100644 --- a/src/QLNet/Pricingengines/vanilla/AnalyticH1HWEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/AnalyticH1HWEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -40,17 +40,17 @@ the finite difference Heston-Hull-White engine */ public class AnalyticH1HWEngine : AnalyticHestonHullWhiteEngine { - public AnalyticH1HWEngine( HestonModel model, HullWhite hullWhiteModel, double rhoSr, int integrationOrder = 144 ) - :base(model, hullWhiteModel, integrationOrder) + public AnalyticH1HWEngine(HestonModel model, HullWhite hullWhiteModel, double rhoSr, int integrationOrder = 144) + : base(model, hullWhiteModel, integrationOrder) { rhoSr_ = rhoSr; - Utils.QL_REQUIRE(rhoSr_ >= 0.0,()=> "Fourier integration is not stable if " + - "the equity interest rate correlation is negative"); + Utils.QL_REQUIRE(rhoSr_ >= 0.0, () => "Fourier integration is not stable if " + + "the equity interest rate correlation is negative"); } - public AnalyticH1HWEngine(HestonModel model,HullWhite hullWhiteModel,double rhoSr, double relTolerance, - int maxEvaluations) - : base( model, hullWhiteModel,relTolerance, maxEvaluations ) + public AnalyticH1HWEngine(HestonModel model, HullWhite hullWhiteModel, double rhoSr, double relTolerance, + int maxEvaluations) + : base(model, hullWhiteModel, relTolerance, maxEvaluations) { rhoSr_ = rhoSr; } @@ -58,13 +58,13 @@ public AnalyticH1HWEngine(HestonModel model,HullWhite hullWhiteModel,double rhoS protected override Complex addOnTerm(double u, double t, int j) { return base.addOnTerm(u, t, j) - + new Fj_Helper(model_, hullWhiteModel_, rhoSr_, t, 0.0, j).value(u); + + new Fj_Helper(model_, hullWhiteModel_, rhoSr_, t, 0.0, j).value(u); } private class Fj_Helper { - public Fj_Helper( Handle hestonModel, HullWhite hullWhiteModel, double rhoSr, double term, - double strike, int j) + public Fj_Helper(Handle hestonModel, HullWhite hullWhiteModel, double rhoSr, double term, + double strike, int j) { j_ = j; lambda_ = hullWhiteModel.a(); @@ -73,81 +73,81 @@ public Fj_Helper( Handle hestonModel, HullWhite hullWhiteModel, dou kappa_ = hestonModel.link.kappa(); theta_ = hestonModel.link.theta(); gamma_ = hestonModel.link.sigma(); - d_ = 4.0*kappa_*theta_/(gamma_*gamma_); + d_ = 4.0 * kappa_ * theta_ / (gamma_ * gamma_); rhoSr_ = rhoSr; term_ = term; } public Complex value(double u) { - double gamma2 = gamma_*gamma_; + double gamma2 = gamma_ * gamma_; double a, b, c; - if (8.0*kappa_*theta_/gamma2 > 1.0) + if (8.0 * kappa_ * theta_ / gamma2 > 1.0) { - a = Math.Sqrt(theta_ - gamma2/(8.0*kappa_)); + a = Math.Sqrt(theta_ - gamma2 / (8.0 * kappa_)); b = Math.Sqrt(v0_) - a; - c = -Math.Log((LambdaApprox(1.0) - a)/b); + c = -Math.Log((LambdaApprox(1.0) - a) / b); } else { - a = Math.Sqrt(gamma2/(2.0*kappa_)) - *Math.Exp(GammaFunction.logValue(0.5*(d_ + 1.0)) - - GammaFunction.logValue(0.5*d_)); + a = Math.Sqrt(gamma2 / (2.0 * kappa_)) + * Math.Exp(GammaFunction.logValue(0.5 * (d_ + 1.0)) + - GammaFunction.logValue(0.5 * d_)); double t1 = 0.0; - double t2 = 1.0/kappa_; + double t2 = 1.0 / kappa_; double Lambda_t1 = Math.Sqrt(v0_); double Lambda_t2 = Lambda(t2); - c = Math.Log((Lambda_t2 - a)/(Lambda_t1 - a))/(t1 - t2); - b = Math.Exp(c*t1)*(Lambda_t1 - a); + c = Math.Log((Lambda_t2 - a) / (Lambda_t1 - a)) / (t1 - t2); + b = Math.Exp(c * t1) * (Lambda_t1 - a); } Complex I4 = - -1.0/lambda_*new Complex(u*u, ((j_ == 1u) ? -u : u)) - *(b/c*(1.0 - Math.Exp(-c*term_)) - + a*term_ - + a/lambda_*(Math.Exp(-lambda_*term_) - 1.0) - + b/(c - lambda_)*Math.Exp(-c*term_) - *(1.0 - Math.Exp(-term_*(lambda_ - c)))); - - return eta_*rhoSr_*I4; + -1.0 / lambda_ * new Complex(u * u, ((j_ == 1u) ? -u : u)) + *(b / c * (1.0 - Math.Exp(-c * term_)) + + a * term_ + + a / lambda_ * (Math.Exp(-lambda_ * term_) - 1.0) + + b / (c - lambda_)*Math.Exp(-c * term_) + * (1.0 - Math.Exp(-term_ * (lambda_ - c)))); + + return eta_ * rhoSr_ * I4; } - - private double c(double t) { return gamma_*gamma_/(4*kappa_)*(1.0-Math.Exp(-kappa_*t));} + + private double c(double t) { return gamma_ * gamma_ / (4 * kappa_) * (1.0 - Math.Exp(-kappa_ * t));} private double lambda(double t) { - return 4.0*kappa_*v0_*Math.Exp(-kappa_*t) / ( gamma_ * gamma_ * ( 1.0 - Math.Exp( -kappa_ * t ) ) ); + return 4.0 * kappa_ * v0_ * Math.Exp(-kappa_ * t) / (gamma_ * gamma_ * (1.0 - Math.Exp(-kappa_ * t))); } private double Lambda(double t) { int maxIter = 1000; double lambdaT = lambda(t); - int i=0; + int i = 0; double retVal = 0.0, s; - do + do { double k = i; - s=Math.Exp(k*Math.Log(0.5*lambdaT) + GammaFunction.logValue(0.5*(1+d_)+k) - - GammaFunction.logValue(k+1) - GammaFunction.logValue(0.5*d_+k)); + s = Math.Exp(k * Math.Log(0.5 * lambdaT) + GammaFunction.logValue(0.5 * (1 + d_) + k) + - GammaFunction.logValue(k + 1) - GammaFunction.logValue(0.5 * d_ + k)); retVal += s; - } + } while (s > Double.Epsilon && ++i < maxIter); - Utils.QL_REQUIRE(i < maxIter,()=> "can not calculate Lambda"); + Utils.QL_REQUIRE(i < maxIter, () => "can not calculate Lambda"); - retVal *= Math.Sqrt(2*c(t)) * Math.Exp(-0.5*lambdaT); + retVal *= Math.Sqrt(2 * c(t)) * Math.Exp(-0.5 * lambdaT); return retVal; } private double LambdaApprox(double t) { - return Math.Sqrt( c(t)*(lambda(t)-1.0) + c(t)*d_*(1.0 + 1.0/(2.0*(d_+lambda(t))))); + return Math.Sqrt(c(t)*(lambda(t) - 1.0) + c(t)*d_*(1.0 + 1.0 / (2.0 * (d_ + lambda(t))))); } private int j_; diff --git a/src/QLNet/Pricingengines/vanilla/AnalyticHestonEngine.cs b/src/QLNet/Pricingengines/vanilla/AnalyticHestonEngine.cs index 7d83409f8..201406287 100644 --- a/src/QLNet/Pricingengines/vanilla/AnalyticHestonEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/AnalyticHestonEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -57,30 +57,30 @@ Wiley Finance reproducing results available in web/literature and comparison with Black pricing. */ - public class AnalyticHestonEngine : GenericModelEngine + public class AnalyticHestonEngine : GenericModelEngine { - private class integrand1 + private class integrand1 { private double c_inf; - private Func f; - - public integrand1(double _c_inf, Func _f) + private Func f; + + public integrand1(double _c_inf, Func _f) { c_inf = _c_inf; f = _f; } - - public double value(double x) + + public double value(double x) { if ((x + 1.0)*c_inf > Const.QL_EPSILON) { - return f(-Math.Log(0.5*x + 0.5)/c_inf)/((x + 1.0)*c_inf); + return f(-Math.Log(0.5 * x + 0.5) / c_inf) / ((x + 1.0) * c_inf); } else { return 0.0; } - + } } private class integrand2 @@ -88,17 +88,17 @@ private class integrand2 private double c_inf; private Func f; - public integrand2( double _c_inf, Func _f ) + public integrand2(double _c_inf, Func _f) { c_inf = _c_inf; f = _f; } - public double value( double x ) + public double value(double x) { - if (x*c_inf > Const.QL_EPSILON) + if (x * c_inf > Const.QL_EPSILON) { - return f(-Math.Log(x)/c_inf)/(x*c_inf); + return f(-Math.Log(x) / c_inf) / (x * c_inf); } else { @@ -110,23 +110,23 @@ public double value( double x ) public class Integration { // non adaptive integration algorithms based on Gaussian quadrature - public static Integration gaussLaguerre (int intOrder = 128) + public static Integration gaussLaguerre(int intOrder = 128) { - Utils.QL_REQUIRE(intOrder <= 192,()=> "maximum integraton order (192) exceeded"); + Utils.QL_REQUIRE(intOrder <= 192, () => "maximum integraton order (192) exceeded"); return new Integration(Algorithm.GaussLaguerre, new GaussLaguerreIntegration(intOrder)); } - public static Integration gaussLegendre (int intOrder = 128) + public static Integration gaussLegendre(int intOrder = 128) { - return new Integration(Algorithm.GaussLegendre, new GaussLegendreIntegration(intOrder)); + return new Integration(Algorithm.GaussLegendre, new GaussLegendreIntegration(intOrder)); } - public static Integration gaussChebyshev( int intOrder = 128 ) + public static Integration gaussChebyshev(int intOrder = 128) { - return new Integration(Algorithm.GaussChebyshev, new GaussChebyshevIntegration(intOrder)); + return new Integration(Algorithm.GaussChebyshev, new GaussChebyshevIntegration(intOrder)); } - public static Integration gaussChebyshev2nd( int intOrder = 128 ) + public static Integration gaussChebyshev2nd(int intOrder = 128) { return new Integration(Algorithm.GaussChebyshev2nd, new GaussChebyshev2ndIntegration(intOrder)); } @@ -135,50 +135,50 @@ public static Integration gaussChebyshev2nd( int intOrder = 128 ) // be used.Be aware: using a too large number for maxEvaluations might // result in a stack overflow as the these integrations are based on // recursive algorithms. - public static Integration gaussLobatto(double relTolerance, double? absTolerance,int maxEvaluations = 1000) + public static Integration gaussLobatto(double relTolerance, double? absTolerance, int maxEvaluations = 1000) { - return new Integration(Algorithm.GaussLobatto, new GaussLobattoIntegral( maxEvaluations, - absTolerance,relTolerance,false)); + return new Integration(Algorithm.GaussLobatto, new GaussLobattoIntegral(maxEvaluations, + absTolerance, relTolerance, false)); } // usually these routines have a poor convergence behavior. public static Integration gaussKronrod(double absTolerance, int maxEvaluations = 1000) { - return new Integration(Algorithm.GaussKronrod, new GaussKronrodAdaptive(absTolerance,maxEvaluations)); + return new Integration(Algorithm.GaussKronrod, new GaussKronrodAdaptive(absTolerance, maxEvaluations)); } public static Integration simpson(double absTolerance, int maxEvaluations = 1000) { - return new Integration(Algorithm.Simpson, new SimpsonIntegral(absTolerance,maxEvaluations)); + return new Integration(Algorithm.Simpson, new SimpsonIntegral(absTolerance, maxEvaluations)); } public static Integration trapezoid(double absTolerance, int maxEvaluations = 1000) { - return new Integration(Algorithm.Trapezoid, new TrapezoidIntegral(absTolerance,maxEvaluations)); + return new Integration(Algorithm.Trapezoid, new TrapezoidIntegral(absTolerance, maxEvaluations)); } public double calculate(double c_inf, Func f) { double retVal = 0; - switch ( intAlgo_ ) + switch (intAlgo_) { case Algorithm.GaussLaguerre: - retVal = gaussianQuadrature_.value( f ); + retVal = gaussianQuadrature_.value(f); break; case Algorithm.GaussLegendre: case Algorithm.GaussChebyshev: case Algorithm.GaussChebyshev2nd: - retVal = gaussianQuadrature_ .value( new integrand1( c_inf, f ).value ); + retVal = gaussianQuadrature_ .value(new integrand1(c_inf, f).value); break; case Algorithm.Simpson: case Algorithm.Trapezoid: case Algorithm.GaussLobatto: case Algorithm.GaussKronrod: - retVal = integrator_.value(new integrand2( c_inf, f ).value,0.0, 1.0 ); + retVal = integrator_.value(new integrand2(c_inf, f).value, 0.0, 1.0); break; default: - Utils.QL_FAIL( "unknwon integration algorithm" ); + Utils.QL_FAIL("unknwon integration algorithm"); break; } @@ -187,17 +187,17 @@ public double calculate(double c_inf, Func f) public int numberOfEvaluations() { - if ( integrator_ != null ) + if (integrator_ != null) { return integrator_.numberOfEvaluations(); } - else if ( gaussianQuadrature_ != null ) + else if (gaussianQuadrature_ != null) { return gaussianQuadrature_.order(); } else { - Utils.QL_FAIL( "neither Integrator nor GaussianQuadrature given" ); + Utils.QL_FAIL("neither Integrator nor GaussianQuadrature given"); } return 0; // jfc } @@ -205,24 +205,24 @@ public int numberOfEvaluations() public bool isAdaptiveIntegration() { return intAlgo_ == Algorithm.GaussLobatto - || intAlgo_ == Algorithm.GaussKronrod - || intAlgo_ == Algorithm.Simpson - || intAlgo_ == Algorithm.Trapezoid; + || intAlgo_ == Algorithm.GaussKronrod + || intAlgo_ == Algorithm.Simpson + || intAlgo_ == Algorithm.Trapezoid; } private enum Algorithm - { - GaussLobatto, - GaussKronrod, - Simpson, + { + GaussLobatto, + GaussKronrod, + Simpson, Trapezoid, - GaussLaguerre, + GaussLaguerre, GaussLegendre, - GaussChebyshev, - GaussChebyshev2nd + GaussChebyshev, + GaussChebyshev2nd } - private Integration( Algorithm intAlgo, GaussianQuadrature gaussianQuadrature ) + private Integration(Algorithm intAlgo, GaussianQuadrature gaussianQuadrature) { intAlgo_ = intAlgo; gaussianQuadrature_ = gaussianQuadrature; @@ -240,15 +240,15 @@ private Integration(Algorithm intAlgo, Integrator integrator) } - public enum ComplexLogFormula { Gatheral, BranchCorrection }; + public enum ComplexLogFormula { Gatheral, BranchCorrection } // Simple to use constructor: Using adaptive // Gauss-Lobatto integration and Gatheral's version of complex log. // Be aware: using a too large number for maxEvaluations might result // in a stack overflow as the Lobatto integration is a recursive // algorithm. - public AnalyticHestonEngine( HestonModel model, double relTolerance, int maxEvaluations ) - :base(model) + public AnalyticHestonEngine(HestonModel model, double relTolerance, int maxEvaluations) + : base(model) { evaluations_ = 0; cpxLog_ = ComplexLogFormula.Gatheral; @@ -258,36 +258,36 @@ public AnalyticHestonEngine( HestonModel model, double relTolerance, int maxEval // Constructor using Laguerre integration // and Gatheral's version of complex log. public AnalyticHestonEngine(HestonModel model, int integrationOrder = 144) - :base(model) + : base(model) { evaluations_ = 0; cpxLog_ = ComplexLogFormula.Gatheral; - integration_ = Integration.gaussLaguerre( integrationOrder ); + integration_ = Integration.gaussLaguerre(integrationOrder); } // Constructor giving full control // over the Fourier integration algorithm public AnalyticHestonEngine(HestonModel model, ComplexLogFormula cpxLog, Integration integration) - :base(model) + : base(model) { evaluations_ = 0; cpxLog_ = cpxLog; integration_ = integration; // TODO check - - Utils.QL_REQUIRE( cpxLog_ != ComplexLogFormula.BranchCorrection - || !integration.isAdaptiveIntegration(),()=> - "Branch correction does not work in conjunction with adaptive integration methods"); + + Utils.QL_REQUIRE(cpxLog_ != ComplexLogFormula.BranchCorrection + || !integration.isAdaptiveIntegration(), () => + "Branch correction does not work in conjunction with adaptive integration methods"); } public override void calculate() { // this is a european option pricer - Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European,()=>"not an European option"); + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European option"); // plain vanilla PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; - Utils.QL_REQUIRE(payoff != null ,()=> "non plain vanilla payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "non plain vanilla payoff given"); HestonProcess process = model_.link.process(); @@ -295,72 +295,72 @@ public override void calculate() double dividendDiscount = process.dividendYield().link.discount(arguments_.exercise.lastDate()); double spotPrice = process.s0().link.value(); - Utils.QL_REQUIRE(spotPrice > 0.0,()=> "negative or null underlying given"); + Utils.QL_REQUIRE(spotPrice > 0.0, () => "negative or null underlying given"); double strikePrice = payoff.strike(); double term = process.time(arguments_.exercise.lastDate()); double? resultsValue = null; - doCalculation( riskFreeDiscount, - dividendDiscount, - spotPrice, - strikePrice, - term, - model_.link.kappa(), - model_.link.theta(), - model_.link.sigma(), - model_.link.v0(), - model_.link.rho(), - payoff, - integration_, - cpxLog_, - this, - ref resultsValue, - ref evaluations_); + doCalculation(riskFreeDiscount, + dividendDiscount, + spotPrice, + strikePrice, + term, + model_.link.kappa(), + model_.link.theta(), + model_.link.sigma(), + model_.link.v0(), + model_.link.rho(), + payoff, + integration_, + cpxLog_, + this, + ref resultsValue, + ref evaluations_); results_.value = resultsValue; } public int numberOfEvaluations() { return evaluations_; } - public static void doCalculation( double riskFreeDiscount, - double dividendDiscount, - double spotPrice, - double strikePrice, - double term, - double kappa, double theta, double sigma, double v0, double rho, - TypePayoff type, - Integration integration, - ComplexLogFormula cpxLog, - AnalyticHestonEngine enginePtr, - ref double? value, - ref int evaluations) + public static void doCalculation(double riskFreeDiscount, + double dividendDiscount, + double spotPrice, + double strikePrice, + double term, + double kappa, double theta, double sigma, double v0, double rho, + TypePayoff type, + Integration integration, + ComplexLogFormula cpxLog, + AnalyticHestonEngine enginePtr, + ref double? value, + ref int evaluations) { - - double ratio = riskFreeDiscount/dividendDiscount; + + double ratio = riskFreeDiscount / dividendDiscount; double c_inf = Math.Min(10.0, Math.Max(0.0001, - Math.Sqrt( 1.0 - ( Math.Pow(rho,2) ) ) / sigma ) ) - *(v0 + kappa*theta*term); + Math.Sqrt(1.0 - (Math.Pow(rho, 2))) / sigma)) + * (v0 + kappa * theta * term); evaluations = 0; double p1 = integration.calculate(c_inf, - new Fj_Helper(kappa, theta, sigma, v0, spotPrice, rho, enginePtr, - cpxLog, term, strikePrice, ratio, 1).value)/Const.M_PI; - evaluations+= integration.numberOfEvaluations(); + new Fj_Helper(kappa, theta, sigma, v0, spotPrice, rho, enginePtr, + cpxLog, term, strikePrice, ratio, 1).value) / Const.M_PI; + evaluations += integration.numberOfEvaluations(); double p2 = integration.calculate(c_inf, - new Fj_Helper(kappa, theta, sigma, v0, spotPrice, rho, enginePtr, - cpxLog, term, strikePrice, ratio, 2).value)/Const.M_PI; - - evaluations+= integration.numberOfEvaluations(); + new Fj_Helper(kappa, theta, sigma, v0, spotPrice, rho, enginePtr, + cpxLog, term, strikePrice, ratio, 2).value) / Const.M_PI; + + evaluations += integration.numberOfEvaluations(); switch (type.optionType()) { case Option.Type.Call: - value = spotPrice*dividendDiscount*(p1+0.5) - strikePrice*riskFreeDiscount*(p2+0.5); + value = spotPrice * dividendDiscount * (p1 + 0.5) - strikePrice * riskFreeDiscount * (p2 + 0.5); break; case Option.Type.Put: - value = spotPrice*dividendDiscount*(p1-0.5) - strikePrice*riskFreeDiscount*(p2-0.5); + value = spotPrice * dividendDiscount * (p1 - 0.5) - strikePrice * riskFreeDiscount * (p2 - 0.5); break; default: Utils.QL_FAIL("unknown option type"); @@ -369,18 +369,18 @@ public static void doCalculation( double riskFreeDiscount, } - + // call back for extended stochastic volatility // plus jump diffusion engines like bates model - protected virtual Complex addOnTerm( double phi, double t, int j) { return new Complex(0,0); } + protected virtual Complex addOnTerm(double phi, double t, int j) { return new Complex(0, 0); } - private class Fj_Helper + private class Fj_Helper { - public Fj_Helper( VanillaOption.Arguments arguments, - HestonModel model, - AnalyticHestonEngine engine, - ComplexLogFormula cpxLog, - double term, double ratio, int j) + public Fj_Helper(VanillaOption.Arguments arguments, + HestonModel model, + AnalyticHestonEngine engine, + ComplexLogFormula cpxLog, + double term, double ratio, int j) { j_ = j; //arg_(arguments), kappa_ = model.kappa(); @@ -390,11 +390,11 @@ public Fj_Helper( VanillaOption.Arguments arguments, cpxLog_ = cpxLog; term_ = term; x_ = Math.Log(model.process().s0().link.value()); - sx_ = Math.Log( ((StrikedTypePayoff)(arguments.payoff)).strike()); + sx_ = Math.Log(((StrikedTypePayoff)(arguments.payoff)).strike()); dd_ = x_ - Math.Log(ratio); - sigma2_ = sigma_*sigma_; - rsigma_ = model.rho()*sigma_; - t0_ = kappa_ - ((j_ == 1) ? model.rho()*sigma_ : 0); + sigma2_ = sigma_ * sigma_; + rsigma_ = model.rho() * sigma_; + t0_ = kappa_ - ((j_ == 1) ? model.rho() * sigma_ : 0); b_ = 0; g_km1_ = 0; engine_ = engine; @@ -418,10 +418,10 @@ public Fj_Helper(double kappa, double theta, double sigma, term_ = term; x_ = Math.Log(s0); sx_ = Math.Log(strike); - dd_ = x_-Math.Log(ratio); - sigma2_ = sigma_*sigma_; - rsigma_ = rho*sigma_; - t0_ = kappa - ((j== 1)? rho*sigma : 0); + dd_ = x_ - Math.Log(ratio); + sigma2_ = sigma_ * sigma_; + rsigma_ = rho * sigma_; + t0_ = kappa - ((j == 1) ? rho* sigma : 0); b_ = 0; g_km1_ = 0; engine_ = engine; @@ -444,10 +444,10 @@ public Fj_Helper(double kappa, double theta, double sigma, term_ = term; x_ = Math.Log(s0); sx_ = Math.Log(strike); - dd_ = x_-Math.Log(ratio); - sigma2_ = sigma_*sigma_; - rsigma_ = rho*sigma_; - t0_ = kappa - ((j== 1)? rho*sigma : 0); + dd_ = x_ - Math.Log(ratio); + sigma2_ = sigma_ * sigma_; + rsigma_ = rho * sigma_; + t0_ = kappa - ((j == 1) ? rho* sigma : 0); b_ = 0; g_km1_ = 0; engine_ = null; @@ -455,99 +455,99 @@ public Fj_Helper(double kappa, double theta, double sigma, public double value(double phi) { - double rpsig = rsigma_*phi; + double rpsig = rsigma_ * phi; - Complex t1 = t0_+ new Complex(0, -rpsig); - Complex d = Complex.Sqrt(t1*t1 - sigma2_*phi * new Complex(-phi, (j_== 1)? 1 : -1)); - Complex ex = Complex.Exp(-d*term_); + Complex t1 = t0_ + new Complex(0, -rpsig); + Complex d = Complex.Sqrt(t1 * t1 - sigma2_ * phi * new Complex(-phi, (j_ == 1) ? 1 : -1)); + Complex ex = Complex.Exp(-d * term_); Complex addOnTerm = engine_ != null ? engine_.addOnTerm(phi, term_, j_) : 0.0; - if (cpxLog_ == ComplexLogFormula.Gatheral) + if (cpxLog_ == ComplexLogFormula.Gatheral) { - if (phi.IsNotEqual(0.0)) + if (phi.IsNotEqual(0.0)) { - if (sigma_ > 1e-5) + if (sigma_ > 1e-5) { - Complex p = (t1-d)/(t1+d); - Complex g = Complex.Log((1.0 - p*ex)/(1.0 - p)); + Complex p = (t1 - d) / (t1 + d); + Complex g = Complex.Log((1.0 - p * ex) / (1.0 - p)); - return Complex.Exp(v0_*(t1-d)*(1.0-ex)/(sigma2_*(1.0-ex*p)) - + (kappa_*theta_)/sigma2_*((t1-d)*term_-2.0*g) - + new Complex(0.0, phi*(dd_-sx_)) + return Complex.Exp(v0_ * (t1 - d) * (1.0 - ex) / (sigma2_ * (1.0 - ex * p)) + + (kappa_ * theta_) / sigma2_ * ((t1 - d) * term_ - 2.0 * g) + + new Complex(0.0, phi * (dd_ - sx_)) + addOnTerm - ).Imaginary/phi; + ).Imaginary / phi; } - else + else { - Complex td = phi/(2.0*t1) * new Complex(-phi, (j_== 1)? 1 : -1); - Complex p = td*sigma2_/(t1+d); - Complex g = p*(1.0-ex); + Complex td = phi / (2.0 * t1) * new Complex(-phi, (j_ == 1) ? 1 : -1); + Complex p = td * sigma2_ / (t1 + d); + Complex g = p * (1.0 - ex); - return Complex.Exp(v0_*td*(1.0-ex)/(1.0-p*ex) - + (kappa_*theta_)*(td*term_-2.0*g/sigma2_) - + new Complex(0.0, phi*(dd_-sx_)) + return Complex.Exp(v0_ * td * (1.0 - ex) / (1.0 - p * ex) + + (kappa_ * theta_) * (td * term_ - 2.0 * g / sigma2_) + + new Complex(0.0, phi * (dd_ - sx_)) + addOnTerm - ).Imaginary/phi; + ).Imaginary / phi; } } - else + else { - // use l'Hospital's rule - if (j_ == 1) + // use l'Hospital's rule + if (j_ == 1) { - double kmr = rsigma_-kappa_; - if (Math.Abs(kmr) > 1e-7) + double kmr = rsigma_ - kappa_; + if (Math.Abs(kmr) > 1e-7) { - return dd_-sx_ - + (Math.Exp(kmr*term_)*kappa_*theta_ - -kappa_*theta_*(kmr*term_+1.0) ) / (2*kmr*kmr) - - v0_*(1.0-Math.Exp(kmr*term_)) / (2.0*kmr); + return dd_ - sx_ + + (Math.Exp(kmr * term_) * kappa_ * theta_ + - kappa_ * theta_ * (kmr * term_ + 1.0)) / (2 * kmr * kmr) + - v0_ * (1.0 - Math.Exp(kmr * term_)) / (2.0 * kmr); } else // \kappa = \rho * \sigma - return dd_-sx_ + 0.25*kappa_*theta_*term_*term_ - + 0.5*v0_*term_; + return dd_ - sx_ + 0.25 * kappa_ * theta_ * term_ * term_ + + 0.5 * v0_ * term_; } - else + else { - return dd_-sx_ - - (Math.Exp(-kappa_*term_)*kappa_*theta_ - +kappa_*theta_*(kappa_*term_-1.0))/(2*kappa_*kappa_) - - v0_*(1.0-Math.Exp(-kappa_*term_))/(2*kappa_); + return dd_ - sx_ + - (Math.Exp(-kappa_ * term_) * kappa_ * theta_ + + kappa_ * theta_ * (kappa_ * term_ - 1.0)) / (2 * kappa_ * kappa_) + - v0_ * (1.0 - Math.Exp(-kappa_ * term_)) / (2 * kappa_); } } } - else if (cpxLog_ == ComplexLogFormula.BranchCorrection) + else if (cpxLog_ == ComplexLogFormula.BranchCorrection) { - Complex p = (t1+d)/(t1 - d); + Complex p = (t1 + d) / (t1 - d); // next term: g = std::log((1.0 - p*std::exp(d*term_))/(1.0 - p)) Complex g = new Complex(); // the exp of the following expression is needed. - Complex e = Complex.Log(p)+d*term_; + Complex e = Complex.Log(p) + d * term_; // does it fit to the machine precision? - if (Math.Exp(-e.Real) > Const.QL_EPSILON) + if (Math.Exp(-e.Real) > Const.QL_EPSILON) { - g = Complex.Log((1.0 - p/ex)/(1.0 - p)); - } - else + g = Complex.Log((1.0 - p / ex) / (1.0 - p)); + } + else { // use a "big phi" approximation - g = d*term_ + Complex.Log(p/(p - 1.0)); + g = d * term_ + Complex.Log(p / (p - 1.0)); - if (g.Imaginary > Const.M_PI || g.Imaginary <= -Const.M_PI) + if (g.Imaginary > Const.M_PI || g.Imaginary <= -Const.M_PI) { // get back to principal branch of the complex logarithm - double im = g.Imaginary - (2*Const.M_PI)* Math.Floor(g.Imaginary/2*Const.M_PI); + double im = g.Imaginary - (2 * Const.M_PI) * Math.Floor(g.Imaginary / 2 * Const.M_PI); if (im > Const.M_PI) - im -= 2*Const.M_PI; + im -= 2 * Const.M_PI; else if (im <= -Const.M_PI) - im += 2*Const.M_PI; + im += 2 * Const.M_PI; g = new Complex(g.Real, im); - } + } } // be careful here as we have to use a log branch correction @@ -563,16 +563,16 @@ public double value(double phi) --b_; g_km1_ = g.Imaginary; - g += new Complex(0, 2*b_*Const.M_PI); + g += new Complex(0, 2 * b_ * Const.M_PI); - return Complex.Exp(v0_*(t1+d)*(ex-1.0)/(sigma2_*(ex-p)) - + (kappa_*theta_)/sigma2_*((t1+d)*term_-2.0*g) - + new Complex(0,phi*(dd_-sx_)) + return Complex.Exp(v0_ * (t1 + d) * (ex - 1.0) / (sigma2_ * (ex - p)) + + (kappa_ * theta_) / sigma2_ * ((t1 + d) * term_ - 2.0 * g) + + new Complex(0, phi * (dd_ - sx_)) + addOnTerm - ).Imaginary/phi; - + ).Imaginary / phi; + } - else + else { Utils.QL_FAIL("unknown complex logarithm formula"); } diff --git a/src/QLNet/Pricingengines/vanilla/AnalyticHestonHullWhiteEngine.cs b/src/QLNet/Pricingengines/vanilla/AnalyticHestonHullWhiteEngine.cs index 5609c45fe..1b18d624d 100644 --- a/src/QLNet/Pricingengines/vanilla/AnalyticHestonHullWhiteEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/AnalyticHestonHullWhiteEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,7 +19,7 @@ namespace QLNet { //! Analytic Heston engine incl. stochastic interest rates - /*! + /*! References: Karel in't Hout, Joris Bierkens, Antoine von der Ploeg, @@ -39,12 +39,12 @@ against QuantLib's analytic Heston and */ public class AnalyticHestonHullWhiteEngine : AnalyticHestonEngine { - + // see AnalticHestonEninge for usage of different constructors - public AnalyticHestonHullWhiteEngine( HestonModel hestonModel, - HullWhite hullWhiteModel, - int integrationOrder = 144) - :base(hestonModel, integrationOrder) + public AnalyticHestonHullWhiteEngine(HestonModel hestonModel, + HullWhite hullWhiteModel, + int integrationOrder = 144) + : base(hestonModel, integrationOrder) { hullWhiteModel_ = hullWhiteModel; @@ -52,15 +52,15 @@ public AnalyticHestonHullWhiteEngine( HestonModel hestonModel, hullWhiteModel_.registerWith(update); } - public AnalyticHestonHullWhiteEngine( HestonModel hestonModel, - HullWhite hullWhiteModel, - double relTolerance, int maxEvaluations) - :base(hestonModel, relTolerance, maxEvaluations) + public AnalyticHestonHullWhiteEngine(HestonModel hestonModel, + HullWhite hullWhiteModel, + double relTolerance, int maxEvaluations) + : base(hestonModel, relTolerance, maxEvaluations) { hullWhiteModel_ = hullWhiteModel; update(); - hullWhiteModel_.registerWith( update ); + hullWhiteModel_.registerWith(update); } public void setupArguments(VanillaOption.Arguments args) @@ -78,15 +78,15 @@ public override void update() public override void calculate() { double t = model_.link.process().time(arguments_.exercise.lastDate()); - if (a_*t > Math.Pow(Const.QL_EPSILON, 0.25)) + if (a_ * t > Math.Pow(Const.QL_EPSILON, 0.25)) { - m_ = sigma_*sigma_/(2*a_*a_) - *(t+2/a_*Math.Exp(-a_*t)-1/(2*a_)*Math.Exp(-2*a_*t)-3/(2*a_)); + m_ = sigma_ * sigma_ / (2 * a_ * a_) + * (t + 2 / a_ * Math.Exp(-a_ * t) - 1 / (2 * a_) * Math.Exp(-2 * a_ * t) - 3 / (2 * a_)); } - else + else { // low-a algebraic limit - m_ = 0.5*sigma_*sigma_*t*t*t*(1/3.0-0.25*a_*t+7/60.0*a_*a_*t*t); + m_ = 0.5 * sigma_ * sigma_ * t * t * t * (1 / 3.0 - 0.25 * a_ * t + 7 / 60.0 * a_ * a_ * t * t); } base.calculate(); @@ -94,7 +94,7 @@ public override void calculate() protected override Complex addOnTerm(double u, double t, int j) { - return new Complex(-m_*u*u, u*(m_-2*m_*(j-1))); + return new Complex(-m_ * u * u, u * (m_ - 2 * m_ * (j - 1))); } protected HullWhite hullWhiteModel_; diff --git a/src/QLNet/Pricingengines/vanilla/AnalyticPTDHestonEngine.cs b/src/QLNet/Pricingengines/vanilla/AnalyticPTDHestonEngine.cs index 2e6200566..29cc6cfea 100644 --- a/src/QLNet/Pricingengines/vanilla/AnalyticPTDHestonEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/AnalyticPTDHestonEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -31,53 +31,53 @@ with Stochastic Volatility with Applications to Bond and J. Gatheral, The Volatility Surface: A Practitioner's Guide, Wiley Finance - A. Elices, Models with time-dependent parameters using + A. Elices, Models with time-dependent parameters using transform methods: application to Heston’s model, http://arxiv.org/pdf/0708.2020 \ingroup vanillaengines */ public class AnalyticPTDHestonEngine : GenericModelEngine + VanillaOption.Arguments, VanillaOption.Results> { // Simple to use constructor: Using adaptive // Gauss-Lobatto integration and Gatheral's version of complex log. // Be aware: using a too large number for maxEvaluations might result // in a stack overflow as the Lobatto integration is a recursive // algorithm. - public AnalyticPTDHestonEngine(PiecewiseTimeDependentHestonModel model,double relTolerance, int maxEvaluations) - :base(model) + public AnalyticPTDHestonEngine(PiecewiseTimeDependentHestonModel model, double relTolerance, int maxEvaluations) + : base(model) { integration_ = AnalyticHestonEngine.Integration.gaussLobatto(relTolerance, null, maxEvaluations); } // Constructor using Laguerre integration // and Gatheral's version of complex log. - public AnalyticPTDHestonEngine(PiecewiseTimeDependentHestonModel model,int integrationOrder = 144) - :base(model) + public AnalyticPTDHestonEngine(PiecewiseTimeDependentHestonModel model, int integrationOrder = 144) + : base(model) { - integration_ = AnalyticHestonEngine.Integration.gaussLaguerre( integrationOrder ); - + integration_ = AnalyticHestonEngine.Integration.gaussLaguerre(integrationOrder); + } public override void calculate() { // this is an european option pricer - Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European,()=> "not an European option"); + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European option"); // plain vanilla PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; - Utils.QL_REQUIRE(payoff!=null,()=> "non-striked payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "non-striked payoff given"); double v0 = model_.link.v0(); double spotPrice = model_.link.s0(); - Utils.QL_REQUIRE(spotPrice > 0.0,()=> "negative or null underlying given"); + Utils.QL_REQUIRE(spotPrice > 0.0, () => "negative or null underlying given"); double strike = payoff.strike(); - double term = model_.link.riskFreeRate().link.dayCounter().yearFraction( - model_.link.riskFreeRate().link.referenceDate(),arguments_.exercise.lastDate()); - double riskFreeDiscount = model_.link.riskFreeRate().link.discount( arguments_.exercise.lastDate() ); - double dividendDiscount = model_.link.dividendYield().link.discount( arguments_.exercise.lastDate() ); + double term = model_.link.riskFreeRate().link.dayCounter().yearFraction( + model_.link.riskFreeRate().link.referenceDate(), arguments_.exercise.lastDate()); + double riskFreeDiscount = model_.link.riskFreeRate().link.discount(arguments_.exercise.lastDate()); + double dividendDiscount = model_.link.dividendYield().link.discount(arguments_.exercise.lastDate()); //average values TimeGrid timeGrid = model_.link.timeGrid(); @@ -86,73 +86,73 @@ public override void calculate() for (int i = 1; i <= n; ++i) { - double t = 0.5*(timeGrid[i - 1] + timeGrid[i]); - kappaAvg += model_.link.kappa( t ); - thetaAvg += model_.link.theta( t ); - sigmaAvg += model_.link.sigma( t ); - rhoAvg += model_.link.rho( t ); + double t = 0.5 * (timeGrid[i - 1] + timeGrid[i]); + kappaAvg += model_.link.kappa(t); + thetaAvg += model_.link.theta(t); + sigmaAvg += model_.link.sigma(t); + rhoAvg += model_.link.rho(t); } kappaAvg /= n; thetaAvg /= n; sigmaAvg /= n; rhoAvg /= n; - double c_inf = Math.Min(10.0, Math.Max(0.0001, - Math.Sqrt(1.0 - Math.Pow(rhoAvg,2))/sigmaAvg)) *(v0 + kappaAvg*thetaAvg*term); + double c_inf = Math.Min(10.0, Math.Max(0.0001, + Math.Sqrt(1.0 - Math.Pow(rhoAvg, 2)) / sigmaAvg)) * (v0 + kappaAvg * thetaAvg * term); double p1 = integration_.calculate(c_inf, - new Fj_Helper(model_, term, strike, 1).value)/Const.M_PI; + new Fj_Helper(model_, term, strike, 1).value) / Const.M_PI; double p2 = integration_.calculate(c_inf, - new Fj_Helper(model_, term, strike, 2).value)/Const.M_PI; + new Fj_Helper(model_, term, strike, 2).value) / Const.M_PI; switch (payoff.optionType()) { case Option.Type.Call: - results_.value = spotPrice*dividendDiscount*(p1 + 0.5) - - strike*riskFreeDiscount*(p2 + 0.5); + results_.value = spotPrice * dividendDiscount * (p1 + 0.5) + - strike * riskFreeDiscount * (p2 + 0.5); break; case Option.Type.Put: - results_.value = spotPrice*dividendDiscount*(p1 - 0.5) - - strike*riskFreeDiscount*(p2 - 0.5); + results_.value = spotPrice * dividendDiscount * (p1 - 0.5) + - strike * riskFreeDiscount * (p2 - 0.5); break; default: Utils.QL_FAIL("unknown option type"); break; } } - + private class Fj_Helper { - public Fj_Helper(Handle model,double term, double strike, int j) + public Fj_Helper(Handle model, double term, double strike, int j) { j_ = j; term_ = term; v0_ = model.link.v0(); x_ = Math.Log(model.link.s0()); sx_ = Math.Log(strike); - r_ = new InitializedList(model.link.timeGrid().size()-1); - q_ = new InitializedList(model.link.timeGrid().size()-1); + r_ = new InitializedList(model.link.timeGrid().size() - 1); + q_ = new InitializedList(model.link.timeGrid().size() - 1); model_ = model; timeGrid_ = model.link.timeGrid(); - for (int i=0; i "maturity is too large"); + double end = Math.Min(term_, timeGrid_[i + 1]); + r_[i] = model.link.riskFreeRate().link.forwardRate(begin, end, + Compounding.Continuous, Frequency.NoFrequency).rate(); + q_[i] = model.link.dividendYield().link.forwardRate(begin, end, + Compounding.Continuous, Frequency.NoFrequency).rate(); + } + + Utils.QL_REQUIRE(term_ < model_.link.timeGrid().Last(), () => "maturity is too large"); } - + public double value(double phi) { - // avoid numeric overflow for phi->0. + // avoid numeric overflow for phi->0. phi = Math.Max(Double.Epsilon, phi); Complex D = 0.0; @@ -165,44 +165,44 @@ public double value(double phi) { double end = Math.Min(term_, timeGrid_[i]); double tau = end - begin; - double t = 0.5*(end + begin); + double t = 0.5 * (end + begin); double rho = model_.link.rho(t); double sigma = model_.link.sigma(t); double kappa = model_.link.kappa(t); double theta = model_.link.theta(t); - double sigma2 = sigma*sigma; - double t0 = kappa - ((j_ == 1) ? rho*sigma : 0); - double rpsig = rho*sigma*phi; + double sigma2 = sigma * sigma; + double t0 = kappa - ((j_ == 1) ? rho* sigma : 0); + double rpsig = rho * sigma * phi; Complex t1 = t0 + new Complex(0, -rpsig); - Complex d = Complex.Sqrt(t1*t1 - sigma2*phi * new Complex(-phi, (j_ == 1) ? 1 : -1)); - Complex g = (t1 - d)/(t1 + d); - Complex gt = (t1 - d - D*sigma2)/(t1 + d - D*sigma2); + Complex d = Complex.Sqrt(t1 * t1 - sigma2 * phi * new Complex(-phi, (j_ == 1) ? 1 : -1)); + Complex g = (t1 - d) / (t1 + d); + Complex gt = (t1 - d - D * sigma2) / (t1 + d - D * sigma2); - D = (t1 + d)/sigma2*(g - gt*Complex.Exp(-d*tau)) / (1.0 - gt*Complex.Exp(-d*tau)); + D = (t1 + d) / sigma2 * (g - gt * Complex.Exp(-d * tau)) / (1.0 - gt * Complex.Exp(-d * tau)); - Complex lng = Complex.Log((1.0 - gt*Complex.Exp(-d*tau))/(1.0 - gt)); + Complex lng = Complex.Log((1.0 - gt * Complex.Exp(-d * tau)) / (1.0 - gt)); - C = (kappa*theta)/sigma2*((t1 - d)*tau - 2.0*lng) - + new Complex(0.0, phi*(r_[i - 1] - q_[i - 1])*tau) + C; + C = (kappa * theta) / sigma2 * ((t1 - d) * tau - 2.0 * lng) + + new Complex(0.0, phi * (r_[i - 1] - q_[i - 1])*tau) + C; } } - return Complex.Exp(v0_*D + C + new Complex(0.0, phi*(x_ - sx_))).Imaginary / phi; + return Complex.Exp(v0_ * D + C + new Complex(0.0, phi * (x_ - sx_))).Imaginary / phi; } - - - private int j_; + + + private int j_; private double term_; private double v0_, x_, sx_; - + private List r_, q_; - private Handle model_; + private Handle model_; private TimeGrid timeGrid_; } - private AnalyticHestonEngine.Integration integration_; - + private AnalyticHestonEngine.Integration integration_; + } } diff --git a/src/QLNet/Pricingengines/vanilla/BaroneAdesiWhaleyEngine.cs b/src/QLNet/Pricingengines/vanilla/BaroneAdesiWhaleyEngine.cs new file mode 100644 index 000000000..00bb1c606 --- /dev/null +++ b/src/QLNet/Pricingengines/vanilla/BaroneAdesiWhaleyEngine.cs @@ -0,0 +1,241 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! Barone-Adesi and Whaley pricing engine for American options (1987) + /*! \ingroup vanillaengines + + \test the correctness of the returned value is tested by + reproducing results available in literature. + */ + public class BaroneAdesiWhaleyApproximationEngine : VanillaOption.Engine + { + private GeneralizedBlackScholesProcess process_; + + public BaroneAdesiWhaleyApproximationEngine(GeneralizedBlackScholesProcess process) + { + process_ = process; + + process_.registerWith(update); + } + + // critical commodity price + public static double criticalPrice(StrikedTypePayoff payoff, double riskFreeDiscount, double dividendDiscount, + double variance, double tolerance) + { + + // Calculation of seed value, Si + double n = 2.0 * Math.Log(dividendDiscount / riskFreeDiscount) / (variance); + double m = -2.0 * Math.Log(riskFreeDiscount) / (variance); + double bT = Math.Log(dividendDiscount / riskFreeDiscount); + + double qu, Su, h, Si = 0; + switch (payoff.optionType()) + { + case Option.Type.Call: + qu = (-(n - 1.0) + Math.Sqrt(((n - 1.0) * (n - 1.0)) + 4.0 * m)) / 2.0; + Su = payoff.strike() / (1.0 - 1.0 / qu); + h = -(bT + 2.0 * Math.Sqrt(variance)) * payoff.strike() / + (Su - payoff.strike()); + Si = payoff.strike() + (Su - payoff.strike()) * + (1.0 - Math.Exp(h)); + break; + case Option.Type.Put: + qu = (-(n - 1.0) - Math.Sqrt(((n - 1.0) * (n - 1.0)) + 4.0 * m)) / 2.0; + Su = payoff.strike() / (1.0 - 1.0 / qu); + h = (bT - 2.0 * Math.Sqrt(variance)) * payoff.strike() / + (payoff.strike() - Su); + Si = Su + (payoff.strike() - Su) * Math.Exp(h); + break; + default: + Utils.QL_FAIL("unknown option type"); + break; + } + + + // Newton Raphson algorithm for finding critical price Si + double Q, LHS, RHS, bi; + double forwardSi = Si * dividendDiscount / riskFreeDiscount; + double d1 = (Math.Log(forwardSi / payoff.strike()) + 0.5 * variance) / + Math.Sqrt(variance); + CumulativeNormalDistribution cumNormalDist = new CumulativeNormalDistribution(); + double K = (!Utils.close(riskFreeDiscount, 1.0, 1000)) + ? -2.0 * Math.Log(riskFreeDiscount) + / (variance * (1.0 - riskFreeDiscount)) + : 2.0 / variance; + + double temp = Utils.blackFormula(payoff.optionType(), payoff.strike(), + forwardSi, Math.Sqrt(variance)) * riskFreeDiscount; + switch (payoff.optionType()) + { + case Option.Type.Call: + Q = (-(n - 1.0) + Math.Sqrt(((n - 1.0) * (n - 1.0)) + 4 * K)) / 2; + LHS = Si - payoff.strike(); + RHS = temp + (1 - dividendDiscount * cumNormalDist.value(d1)) * Si / Q; + bi = dividendDiscount * cumNormalDist.value(d1) * (1 - 1 / Q) + + (1 - dividendDiscount * + cumNormalDist.derivative(d1) / Math.Sqrt(variance)) / Q; + while (Math.Abs(LHS - RHS) / payoff.strike() > tolerance) + { + Si = (payoff.strike() + RHS - bi * Si) / (1 - bi); + forwardSi = Si * dividendDiscount / riskFreeDiscount; + d1 = (Math.Log(forwardSi / payoff.strike()) + 0.5 * variance) + / Math.Sqrt(variance); + LHS = Si - payoff.strike(); + double temp2 = Utils.blackFormula(payoff.optionType(), payoff.strike(), + forwardSi, Math.Sqrt(variance)) * riskFreeDiscount; + RHS = temp2 + (1 - dividendDiscount * cumNormalDist.value(d1)) * Si / Q; + bi = dividendDiscount * cumNormalDist.value(d1) * (1 - 1 / Q) + + (1 - dividendDiscount * + cumNormalDist.derivative(d1) / Math.Sqrt(variance)) + / Q; + } + break; + case Option.Type.Put: + Q = (-(n - 1.0) - Math.Sqrt(((n - 1.0) * (n - 1.0)) + 4 * K)) / 2; + LHS = payoff.strike() - Si; + RHS = temp - (1 - dividendDiscount * cumNormalDist.value(-d1)) * Si / Q; + bi = -dividendDiscount * cumNormalDist.value(-d1) * (1 - 1 / Q) + - (1 + dividendDiscount * cumNormalDist.derivative(-d1) + / Math.Sqrt(variance)) / Q; + while (Math.Abs(LHS - RHS) / payoff.strike() > tolerance) + { + Si = (payoff.strike() - RHS + bi * Si) / (1 + bi); + forwardSi = Si * dividendDiscount / riskFreeDiscount; + d1 = (Math.Log(forwardSi / payoff.strike()) + 0.5 * variance) + / Math.Sqrt(variance); + LHS = payoff.strike() - Si; + double temp2 = Utils.blackFormula(payoff.optionType(), payoff.strike(), + forwardSi, Math.Sqrt(variance)) * riskFreeDiscount; + RHS = temp2 - (1 - dividendDiscount * cumNormalDist.value(-d1)) * Si / Q; + bi = -dividendDiscount * cumNormalDist.value(-d1) * (1 - 1 / Q) + - (1 + dividendDiscount * cumNormalDist.derivative(-d1) + / Math.Sqrt(variance)) / Q; + } + break; + default: + Utils.QL_FAIL("unknown option type"); + break; + } + + return Si; + } + + public override void calculate() + { + + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.American, () => "not an American Option"); + + AmericanExercise ex = arguments_.exercise as AmericanExercise; + Utils.QL_REQUIRE(ex != null, () => "non-American exercise given"); + + Utils.QL_REQUIRE(!ex.payoffAtExpiry(), () => "payoff at expiry not handled"); + + StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; + Utils.QL_REQUIRE(payoff != null, () => "non-striked payoff given"); + + double variance = process_.blackVolatility().link.blackVariance(ex.lastDate(), payoff.strike()); + double dividendDiscount = process_.dividendYield().link.discount(ex.lastDate()); + double riskFreeDiscount = process_.riskFreeRate().link.discount(ex.lastDate()); + double spot = process_.stateVariable().link.value(); + Utils.QL_REQUIRE(spot > 0.0, () => "negative or null underlying given"); + double forwardPrice = spot * dividendDiscount / riskFreeDiscount; + BlackCalculator black = new BlackCalculator(payoff, forwardPrice, Math.Sqrt(variance), riskFreeDiscount); + + if (dividendDiscount >= 1.0 && payoff.optionType() == Option.Type.Call) + { + // early exercise never optimal + results_.value = black.value(); + results_.delta = black.delta(spot); + results_.deltaForward = black.deltaForward(); + results_.elasticity = black.elasticity(spot); + results_.gamma = black.gamma(spot); + + DayCounter rfdc = process_.riskFreeRate().link.dayCounter(); + DayCounter divdc = process_.dividendYield().link.dayCounter(); + DayCounter voldc = process_.blackVolatility().link.dayCounter(); + double t = rfdc.yearFraction(process_.riskFreeRate().link.referenceDate(), arguments_.exercise.lastDate()); + results_.rho = black.rho(t); + + t = divdc.yearFraction(process_.dividendYield().link.referenceDate(), arguments_.exercise.lastDate()); + results_.dividendRho = black.dividendRho(t); + + t = voldc.yearFraction(process_.blackVolatility().link.referenceDate(), arguments_.exercise.lastDate()); + results_.vega = black.vega(t); + results_.theta = black.theta(spot, t); + results_.thetaPerDay = black.thetaPerDay(spot, t); + + results_.strikeSensitivity = black.strikeSensitivity(); + results_.itmCashProbability = black.itmCashProbability(); + } + else + { + // early exercise can be optimal + CumulativeNormalDistribution cumNormalDist = new CumulativeNormalDistribution(); + double tolerance = 1e-6; + double Sk = criticalPrice(payoff, riskFreeDiscount, + dividendDiscount, variance, tolerance); + double forwardSk = Sk * dividendDiscount / riskFreeDiscount; + double d1 = (Math.Log(forwardSk / payoff.strike()) + 0.5 * variance) + / Math.Sqrt(variance); + double n = 2.0 * Math.Log(dividendDiscount / riskFreeDiscount) / variance; + double K = (!Utils.close(riskFreeDiscount, 1.0, 1000)) + ? -2.0 * Math.Log(riskFreeDiscount) + / (variance * (1.0 - riskFreeDiscount)) + : 2.0 / variance; + double Q, a; + switch (payoff.optionType()) + { + case Option.Type.Call: + Q = (-(n - 1.0) + Math.Sqrt(((n - 1.0) * (n - 1.0)) + 4.0 * K)) / 2.0; + a = (Sk / Q) * (1.0 - dividendDiscount * cumNormalDist.value(d1)); + if (spot < Sk) + { + results_.value = black.value() + + a * Math.Pow((spot / Sk), Q); + } + else + { + results_.value = spot - payoff.strike(); + } + break; + case Option.Type.Put: + Q = (-(n - 1.0) - Math.Sqrt(((n - 1.0) * (n - 1.0)) + 4.0 * K)) / 2.0; + a = -(Sk / Q) * + (1.0 - dividendDiscount * cumNormalDist.value(-d1)); + if (spot > Sk) + { + results_.value = black.value() + + a * Math.Pow((spot / Sk), Q); + } + else + { + results_.value = payoff.strike() - spot; + } + break; + default: + Utils.QL_FAIL("unknown option type"); + break; + } + } // end of "early exercise can be optimal" + } + } +} diff --git a/src/QLNet/Pricingengines/vanilla/BinomialEngine.cs b/src/QLNet/Pricingengines/vanilla/BinomialEngine.cs new file mode 100644 index 000000000..6900bad11 --- /dev/null +++ b/src/QLNet/Pricingengines/vanilla/BinomialEngine.cs @@ -0,0 +1,126 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! Pricing engine for vanilla options using binomial trees + /*! \ingroup vanillaengines + + \test the correctness of the returned values is tested by + checking it against analytic results. + + \todo Greeks are not overly accurate. They could be improved + by building a tree so that it has three points at the + current time. The value would be fetched from the middle + one, while the two side points would be used for + estimating partial derivatives. + */ + public class BinomialVanillaEngine : VanillaOption.Engine where T : ITreeFactory, ITree, new () + { + private GeneralizedBlackScholesProcess process_; + private int timeSteps_; + + public BinomialVanillaEngine(GeneralizedBlackScholesProcess process, int timeSteps) + { + process_ = process; + timeSteps_ = timeSteps; + + Utils.QL_REQUIRE(timeSteps > 0, () => "timeSteps must be positive, " + timeSteps + " not allowed"); + + process_.registerWith(update); + } + + public override void calculate() + { + + DayCounter rfdc = process_.riskFreeRate().link.dayCounter(); + DayCounter divdc = process_.dividendYield().link.dayCounter(); + DayCounter voldc = process_.blackVolatility().link.dayCounter(); + Calendar volcal = process_.blackVolatility().link.calendar(); + + double s0 = process_.stateVariable().link.value(); + Utils.QL_REQUIRE(s0 > 0.0, () => "negative or null underlying given"); + double v = process_.blackVolatility().link.blackVol(arguments_.exercise.lastDate(), s0); + Date maturityDate = arguments_.exercise.lastDate(); + double r = process_.riskFreeRate().link.zeroRate(maturityDate, rfdc, Compounding.Continuous, Frequency.NoFrequency).rate(); + double q = process_.dividendYield().link.zeroRate(maturityDate, divdc, Compounding.Continuous, Frequency.NoFrequency).rate(); + Date referenceDate = process_.riskFreeRate().link.referenceDate(); + + // binomial trees with constant coefficient + var flatRiskFree = new Handle(new FlatForward(referenceDate, r, rfdc)); + var flatDividends = new Handle(new FlatForward(referenceDate, q, divdc)); + var flatVol = new Handle(new BlackConstantVol(referenceDate, volcal, v, voldc)); + + PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; + Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); + + double maturity = rfdc.yearFraction(referenceDate, maturityDate); + + StochasticProcess1D bs = + new GeneralizedBlackScholesProcess(process_.stateVariable(), flatDividends, flatRiskFree, flatVol); + + TimeGrid grid = new TimeGrid(maturity, timeSteps_); + + T tree = FastActivator.Create().factory(bs, maturity, timeSteps_, payoff.strike()); + + BlackScholesLattice lattice = new BlackScholesLattice(tree, r, maturity, timeSteps_); + + DiscretizedVanillaOption option = new DiscretizedVanillaOption(arguments_, process_, grid); + + option.initialize(lattice, maturity); + + // Partial derivatives calculated from various points in the + // binomial tree (Odegaard) + + // Rollback to third-last step, and get underlying price (s2) & + // option values (p2) at this point + option.rollback(grid[2]); + Vector va2 = new Vector(option.values()); + Utils.QL_REQUIRE(va2.size() == 3, () => "Expect 3 nodes in grid at second step"); + double p2h = va2[2]; // high-price + double s2 = lattice.underlying(2, 2); // high price + + // Rollback to second-last step, and get option value (p1) at + // this point + option.rollback(grid[1]); + Vector va = new Vector(option.values()); + Utils.QL_REQUIRE(va.size() == 2, () => "Expect 2 nodes in grid at first step"); + double p1 = va[1]; + + // Finally, rollback to t=0 + option.rollback(0.0); + double p0 = option.presentValue(); + double s1 = lattice.underlying(1, 1); + + // Calculate partial derivatives + double delta0 = (p1 - p0) / (s1 - s0); // dp/ds + double delta1 = (p2h - p1) / (s2 - s1); // dp/ds + + // Store results + results_.value = p0; + results_.delta = delta0; + results_.gamma = 2.0 * (delta1 - delta0) / (s2 - s0); //d(delta)/ds + results_.theta = Utils.blackScholesTheta(process_, + results_.value.GetValueOrDefault(), + results_.delta.GetValueOrDefault(), + results_.gamma.GetValueOrDefault()); + } + } +} diff --git a/src/QLNet/Pricingengines/vanilla/BjerksundStenslandEngine.cs b/src/QLNet/Pricingengines/vanilla/BjerksundStenslandEngine.cs new file mode 100644 index 000000000..03552819e --- /dev/null +++ b/src/QLNet/Pricingengines/vanilla/BjerksundStenslandEngine.cs @@ -0,0 +1,154 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! Bjerksund and Stensland pricing engine for American options (1993) + /*! \ingroup vanillaengines + + \test the correctness of the returned value is tested by + reproducing results available in literature. + */ + public class BjerksundStenslandApproximationEngine : VanillaOption.Engine + { + private GeneralizedBlackScholesProcess process_; + + public BjerksundStenslandApproximationEngine(GeneralizedBlackScholesProcess process) + { + process_ = process; + + process_.registerWith(update); + } + + public override void calculate() + { + + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.American, () => "not an American Option"); + + AmericanExercise ex = arguments_.exercise as AmericanExercise; + Utils.QL_REQUIRE(ex != null, () => "non-American exercise given"); + + Utils.QL_REQUIRE(!ex.payoffAtExpiry(), () => "payoff at expiry not handled"); + + PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; + Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); + + double variance = process_.blackVolatility().link.blackVariance(ex.lastDate(), payoff.strike()); + double dividendDiscount = process_.dividendYield().link.discount(ex.lastDate()); + double riskFreeDiscount = process_.riskFreeRate().link.discount(ex.lastDate()); + + double spot = process_.stateVariable().link.value(); + Utils.QL_REQUIRE(spot > 0.0, () => "negative or null underlying given"); + + double strike = payoff.strike(); + + if (payoff.optionType() == Option.Type.Put) + { + // use put-call simmetry + Utils.swap(ref spot, ref strike); + Utils.swap(ref riskFreeDiscount, ref dividendDiscount); + payoff = new PlainVanillaPayoff(Option.Type.Call, strike); + } + + if (dividendDiscount >= 1.0) + { + // early exercise is never optimal - use Black formula + double forwardPrice = spot * dividendDiscount / riskFreeDiscount; + BlackCalculator black = new BlackCalculator(payoff, forwardPrice, Math.Sqrt(variance), riskFreeDiscount); + + results_.value = black.value(); + results_.delta = black.delta(spot); + results_.deltaForward = black.deltaForward(); + results_.elasticity = black.elasticity(spot); + results_.gamma = black.gamma(spot); + + DayCounter rfdc = process_.riskFreeRate().link.dayCounter(); + DayCounter divdc = process_.dividendYield().link.dayCounter(); + DayCounter voldc = process_.blackVolatility().link.dayCounter(); + double t = rfdc.yearFraction(process_.riskFreeRate().link.referenceDate(), arguments_.exercise.lastDate()); + results_.rho = black.rho(t); + + t = divdc.yearFraction(process_.dividendYield().link.referenceDate(), arguments_.exercise.lastDate()); + results_.dividendRho = black.dividendRho(t); + + t = voldc.yearFraction(process_.blackVolatility().link.referenceDate(), arguments_.exercise.lastDate()); + results_.vega = black.vega(t); + results_.theta = black.theta(spot, t); + results_.thetaPerDay = black.thetaPerDay(spot, t); + + results_.strikeSensitivity = black.strikeSensitivity(); + results_.itmCashProbability = black.itmCashProbability(); + } + else + { + // early exercise can be optimal - use approximation + results_.value = americanCallApproximation(spot, strike, riskFreeDiscount, dividendDiscount, variance); + } + } + + + // helper functions + private CumulativeNormalDistribution cumNormalDist = new CumulativeNormalDistribution(); + + double phi(double S, double gamma, double H, double I, double rT, double bT, double variance) + { + + double lambda = (-rT + gamma * bT + 0.5 * gamma * (gamma - 1.0) * variance); + double d = -(Math.Log(S / H) + (bT + (gamma - 0.5) * variance)) / Math.Sqrt(variance); + double kappa = 2.0 * bT / variance + (2.0 * gamma - 1.0); + return Math.Exp(lambda) * (cumNormalDist.value(d) + - Math.Pow((I / S), kappa) * + cumNormalDist.value(d - 2.0 * Math.Log(I / S) / Math.Sqrt(variance))); + } + + + double americanCallApproximation(double S, double X, double rfD, double dD, double variance) + { + + double bT = Math.Log(dD / rfD); + double rT = Math.Log(1.0 / rfD); + + double beta = (0.5 - bT / variance) + Math.Sqrt(Math.Pow((bT / variance - 0.5), 2.0) + 2.0 * rT / variance); + double BInfinity = beta / (beta - 1.0) * X; + double B0 = Math.Max(X, rT / (rT - bT) * X); + double ht = -(bT + 2.0 * Math.Sqrt(variance)) * B0 / (BInfinity - B0); + + // investigate what happen to I for dD->0.0 + double I = B0 + (BInfinity - B0) * (1 - Math.Exp(ht)); + Utils.QL_REQUIRE(I >= X, () => "Bjerksund-Stensland approximation not applicable to this set of parameters"); + if (S >= I) + { + return S - X; + } + else + { + // investigate what happen to alpha for dD->0.0 + double alpha = (I - X) * Math.Pow(I, (-beta)); + return (I - X) * Math.Pow(S / I, beta) + * (1 - phi(S, beta, I, I, rT, bT, variance)) + + S * phi(S, 1.0, I, I, rT, bT, variance) + - S * phi(S, 1.0, X, I, rT, bT, variance) + - X * phi(S, 0.0, I, I, rT, bT, variance) + + X * phi(S, 0.0, X, I, rT, bT, variance); + } + } + + } +} diff --git a/src/QLNet/Pricingengines/vanilla/DiscretizedVanillaOption.cs b/src/QLNet/Pricingengines/vanilla/DiscretizedVanillaOption.cs new file mode 100644 index 000000000..26a1c7820 --- /dev/null +++ b/src/QLNet/Pricingengines/vanilla/DiscretizedVanillaOption.cs @@ -0,0 +1,91 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + public class DiscretizedVanillaOption : DiscretizedAsset + { + private VanillaOption.Arguments arguments_; + private List stoppingTimes_; + + public DiscretizedVanillaOption(VanillaOption.Arguments args, StochasticProcess process, TimeGrid grid) + { + arguments_ = args; + + stoppingTimes_ = new InitializedList(args.exercise.dates().Count); + for (int i = 0; i < stoppingTimes_.Count; ++i) + { + stoppingTimes_[i] = process.time(args.exercise.date(i)); + if (!grid.empty()) + { + // adjust to the given grid + stoppingTimes_[i] = grid.closestTime(stoppingTimes_[i]); + } + } + } + + public override void reset(int size) + { + values_ = new Vector(size, 0.0); + adjustValues(); + } + + public override List mandatoryTimes() + { + return stoppingTimes_; + } + + protected override void postAdjustValuesImpl() + { + double now = time(); + switch (arguments_.exercise.type()) + { + case Exercise.Type.American: + if (now <= stoppingTimes_[1] && now >= stoppingTimes_[0]) + applySpecificCondition(); + break; + case Exercise.Type.European: + if (isOnTime(stoppingTimes_[0])) + applySpecificCondition(); + break; + case Exercise.Type.Bermudan: + for (int i = 0; i < stoppingTimes_.Count; i++) + { + if (isOnTime(stoppingTimes_[i])) + applySpecificCondition(); + } + break; + default: + Utils.QL_FAIL("invalid option type"); + break; + } + } + + private void applySpecificCondition() + { + Vector grid = method().grid(time()); + for (int j = 0; j < values_.size(); j++) + { + values_[j] = Math.Max(values_[j], arguments_.payoff.value(grid[j])); + } + } + } +} diff --git a/src/QLNet/Pricingengines/vanilla/FDAmericanEngine.cs b/src/QLNet/Pricingengines/vanilla/FDAmericanEngine.cs index 588a5bac6..a4bc318a0 100644 --- a/src/QLNet/Pricingengines/vanilla/FDAmericanEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/FDAmericanEngine.cs @@ -1,43 +1,45 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { - //! Finite-differences pricing engine for American one asset options - /*! \ingroup vanillaengines - - \test - - the correctness of the returned value is tested by reproducing results available in literature. - - the correctness of the returned greeks is tested by reproducing numerical derivatives. - */ - public class FDAmericanEngine : FDEngineAdapter, OneAssetOption.Engine>, - IFDEngine { - // required for generics - public FDAmericanEngine() { } - - public FDAmericanEngine(GeneralizedBlackScholesProcess process, int timeSteps = 100 , int gridPoints = 100 , - bool timeDependent = false) - : base(process, timeSteps, gridPoints, timeDependent) { } - - public IFDEngine factory(GeneralizedBlackScholesProcess process, int timeSteps = 100 , int gridPoints = 100) - { - return new FDAmericanEngine(process, timeSteps, gridPoints); - } - } +namespace QLNet +{ + //! Finite-differences pricing engine for American one asset options + /*! \ingroup vanillaengines + + \test + - the correctness of the returned value is tested by reproducing results available in literature. + - the correctness of the returned greeks is tested by reproducing numerical derivatives. + */ + public class FDAmericanEngine : FDEngineAdapter, OneAssetOption.Engine>, + IFDEngine + { + // required for generics + public FDAmericanEngine() { } + + public FDAmericanEngine(GeneralizedBlackScholesProcess process, int timeSteps = 100, int gridPoints = 100, + bool timeDependent = false) + : base(process, timeSteps, gridPoints, timeDependent) { } + + public IFDEngine factory(GeneralizedBlackScholesProcess process, int timeSteps = 100, int gridPoints = 100) + { + return new FDAmericanEngine(process, timeSteps, gridPoints); + } + } } diff --git a/src/QLNet/Pricingengines/vanilla/FDBermudanEngine.cs b/src/QLNet/Pricingengines/vanilla/FDBermudanEngine.cs index 8a1c0b041..8b0058452 100644 --- a/src/QLNet/Pricingengines/vanilla/FDBermudanEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/FDBermudanEngine.cs @@ -1,75 +1,86 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - //! Finite-differences Bermudan engine - /*! \ingroup vanillaengines */ - public class FDBermudanEngine : FDMultiPeriodEngine, IGenericEngine { - protected double extraTermInBermudan; +namespace QLNet +{ + //! Finite-differences Bermudan engine + /*! \ingroup vanillaengines */ + public class FDBermudanEngine : FDMultiPeriodEngine, IGenericEngine + { + protected double extraTermInBermudan; - // constructor - public FDBermudanEngine(GeneralizedBlackScholesProcess process, int timeSteps = 100, int gridPoints = 100, - bool timeDependent = false) - : base(process, timeSteps, gridPoints, timeDependent) { } + // constructor + public FDBermudanEngine(GeneralizedBlackScholesProcess process, int timeSteps = 100, int gridPoints = 100, + bool timeDependent = false) + : base(process, timeSteps, gridPoints, timeDependent) { } - public void calculate() { - setupArguments(arguments_); - base.calculate(results_); - } + public void calculate() + { + setupArguments(arguments_); + base.calculate(results_); + } - protected override void initializeStepCondition() { - stepCondition_ = new NullCondition(); - } + protected override void initializeStepCondition() + { + stepCondition_ = new NullCondition(); + } - protected override void executeIntermediateStep(int i) { - int size = intrinsicValues_.size(); - for (int j=0; j. - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - // this is template version to serve as base for FDStepConditionEngine and FDMultiPeriodEngine - public class FDConditionEngineTemplate : FDVanillaEngine { - #region Common definitions for deriving classes - protected IStepCondition stepCondition_; - protected SampledCurve prices_; - protected virtual void initializeStepCondition() { - if (stepConditionImpl_ == null) - throw new NotSupportedException(); - else - stepCondition_ = stepConditionImpl_(); - } - - protected Func> stepConditionImpl_; - public void setStepCondition(Func> impl) { - stepConditionImpl_ = impl; - } - #endregion - - // required for generics - public FDConditionEngineTemplate() { } - - public FDConditionEngineTemplate(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) - : base(process, timeSteps, gridPoints, timeDependent) { } - } - - // this is template version to serve as base for FDAmericanCondition and FDShoutCondition - public class FDConditionTemplate : FDConditionEngineTemplate - where baseEngine : FDConditionEngineTemplate, new() { - #region Common definitions for deriving classes - protected baseEngine engine_; - - // below is a wrap-up of baseEngine instead of c++ template inheritance - public override void setupArguments(IPricingEngineArguments a) { engine_.setupArguments(a); } - public override void calculate(IPricingEngineResults r) { engine_.calculate(r); } - #endregion - - // required for generics - public FDConditionTemplate() { } - - public FDConditionTemplate(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) - : base(process, timeSteps, gridPoints, timeDependent) { - // init engine - engine_ = (baseEngine)FastActivator.Create().factory(process, timeSteps, gridPoints, timeDependent); - } - } - - - public class FDAmericanCondition : FDConditionTemplate - where baseEngine : FDConditionEngineTemplate, new() { - - // required for generics - public FDAmericanCondition() { } - // required for template inheritance - public override FDVanillaEngine factory(GeneralizedBlackScholesProcess process, - int timeSteps, int gridPoints, bool timeDependent) { - return new FDAmericanCondition(process, timeSteps, gridPoints, timeDependent); - } - - public FDAmericanCondition(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) - : base(process, timeSteps, gridPoints, timeDependent) { - engine_.setStepCondition(initializeStepConditionImpl); - } - - protected IStepCondition initializeStepConditionImpl() { - return new AmericanCondition(engine_.intrinsicValues_.values()); - } - } - - - public class FDShoutCondition : FDConditionTemplate - where baseEngine : FDConditionEngineTemplate, new() { - - // required for generics - public FDShoutCondition() { } - // required for template inheritance - public override FDVanillaEngine factory(GeneralizedBlackScholesProcess process, - int timeSteps, int gridPoints, bool timeDependent) { - return new FDShoutCondition(process, timeSteps, gridPoints, timeDependent); - } - - public FDShoutCondition(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) - : base(process, timeSteps, gridPoints, timeDependent) { - engine_.setStepCondition(initializeStepConditionImpl); - } - - protected IStepCondition initializeStepConditionImpl() { - // the following to rely on process_ which is the same for engine and here - // therefore wrapping is not requried - double residualTime = engine_.getResidualTime(); - double riskFreeRate = process_.riskFreeRate().link.zeroRate(residualTime, Compounding.Continuous).rate(); - - return new ShoutCondition(engine_.intrinsicValues_.values(), residualTime, riskFreeRate); - } - } +namespace QLNet +{ + // this is template version to serve as base for FDStepConditionEngine and FDMultiPeriodEngine + public class FDConditionEngineTemplate : FDVanillaEngine + { + #region Common definitions for deriving classes + protected IStepCondition stepCondition_; + protected SampledCurve prices_; + protected virtual void initializeStepCondition() + { + if (stepConditionImpl_ == null) + throw new NotSupportedException(); + else + stepCondition_ = stepConditionImpl_(); + } + + protected Func> stepConditionImpl_; + public void setStepCondition(Func> impl) + { + stepConditionImpl_ = impl; + } + #endregion + + // required for generics + public FDConditionEngineTemplate() { } + + public FDConditionEngineTemplate(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) + : base(process, timeSteps, gridPoints, timeDependent) { } + } + + // this is template version to serve as base for FDAmericanCondition and FDShoutCondition + public class FDConditionTemplate : FDConditionEngineTemplate + where baseEngine : FDConditionEngineTemplate, new () + { + #region Common definitions for deriving classes + protected baseEngine engine_; + + // below is a wrap-up of baseEngine instead of c++ template inheritance + public override void setupArguments(IPricingEngineArguments a) { engine_.setupArguments(a); } + public override void calculate(IPricingEngineResults r) { engine_.calculate(r); } + #endregion + + // required for generics + public FDConditionTemplate() { } + + public FDConditionTemplate(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) + : base(process, timeSteps, gridPoints, timeDependent) + { + // init engine + engine_ = (baseEngine)FastActivator.Create().factory(process, timeSteps, gridPoints, timeDependent); + } + } + + + public class FDAmericanCondition : FDConditionTemplate + where baseEngine : FDConditionEngineTemplate, new () + { + + // required for generics + public FDAmericanCondition() { } + // required for template inheritance + public override FDVanillaEngine factory(GeneralizedBlackScholesProcess process, + int timeSteps, int gridPoints, bool timeDependent) + { + return new FDAmericanCondition(process, timeSteps, gridPoints, timeDependent); + } + + public FDAmericanCondition(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) + : base(process, timeSteps, gridPoints, timeDependent) + { + engine_.setStepCondition(initializeStepConditionImpl); + } + + protected IStepCondition initializeStepConditionImpl() + { + return new AmericanCondition(engine_.intrinsicValues_.values()); + } + } + + + public class FDShoutCondition : FDConditionTemplate + where baseEngine : FDConditionEngineTemplate, new () + { + + // required for generics + public FDShoutCondition() { } + // required for template inheritance + public override FDVanillaEngine factory(GeneralizedBlackScholesProcess process, + int timeSteps, int gridPoints, bool timeDependent) + { + return new FDShoutCondition(process, timeSteps, gridPoints, timeDependent); + } + + public FDShoutCondition(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) + : base(process, timeSteps, gridPoints, timeDependent) + { + engine_.setStepCondition(initializeStepConditionImpl); + } + + protected IStepCondition initializeStepConditionImpl() + { + // the following to rely on process_ which is the same for engine and here + // therefore wrapping is not requried + double residualTime = engine_.getResidualTime(); + double riskFreeRate = process_.riskFreeRate().link.zeroRate(residualTime, Compounding.Continuous).rate(); + + return new ShoutCondition(engine_.intrinsicValues_.values(), residualTime, riskFreeRate); + } + } } diff --git a/src/QLNet/Pricingengines/vanilla/FDDividendAmericanEngine.cs b/src/QLNet/Pricingengines/vanilla/FDDividendAmericanEngine.cs index 10645eeaa..24cee0f4d 100644 --- a/src/QLNet/Pricingengines/vanilla/FDDividendAmericanEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/FDDividendAmericanEngine.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,7 +20,7 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! Finite-differences pricing engine for dividend American options + //! Finite-differences pricing engine for dividend American options /*! \ingroup vanillaengines \test @@ -29,21 +29,21 @@ reproducing numerical derivatives. - the invariance of the results upon addition of null dividends is tested. */ - public class FDDividendAmericanEngine: FDEngineAdapter,DividendVanillaOption.Engine>, - IFDEngine - { - public FDDividendAmericanEngine() - {} - - public FDDividendAmericanEngine( GeneralizedBlackScholesProcess process,int timeSteps=100, int gridPoints=100, - bool timeDependent = false) - : base(process, timeSteps, gridPoints,timeDependent) - {} - - public IFDEngine factory(GeneralizedBlackScholesProcess process, int timeSteps = 100 , int gridPoints = 100) - { - return new FDDividendAmericanEngine(process, timeSteps, gridPoints); - } - - } + public class FDDividendAmericanEngine: FDEngineAdapter, DividendVanillaOption.Engine>, + IFDEngine + { + public FDDividendAmericanEngine() + {} + + public FDDividendAmericanEngine(GeneralizedBlackScholesProcess process, int timeSteps = 100, int gridPoints = 100, + bool timeDependent = false) + : base(process, timeSteps, gridPoints, timeDependent) + {} + + public IFDEngine factory(GeneralizedBlackScholesProcess process, int timeSteps = 100, int gridPoints = 100) + { + return new FDDividendAmericanEngine(process, timeSteps, gridPoints); + } + + } } diff --git a/src/QLNet/Pricingengines/vanilla/FDDividendEngine.cs b/src/QLNet/Pricingengines/vanilla/FDDividendEngine.cs index aae53910a..e8e0002b9 100644 --- a/src/QLNet/Pricingengines/vanilla/FDDividendEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/FDDividendEngine.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,191 +20,213 @@ under the terms of the QLNet license. You should have received a using System; using System.Collections.Generic; -namespace QLNet { - //! Abstract base class for dividend engines - /*! \todo The dividend class really needs to be made more - sophisticated to distinguish between fixed dividends and fractional dividends - */ - public abstract class FDDividendEngineBase : FDMultiPeriodEngine { - // required for generics - protected FDDividendEngineBase() { } - - //public FDDividendEngineBase(GeneralizedBlackScholesProcess process, - // Size timeSteps = 100, Size gridPoints = 100, bool timeDependent = false) - protected FDDividendEngineBase(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) - : base(process, timeSteps, gridPoints, timeDependent) {} - - public override FDVanillaEngine factory(GeneralizedBlackScholesProcess process, - int timeSteps, int gridPoints, bool timeDependent) - { - return factory2(process, timeSteps, gridPoints, timeDependent); - } - - public abstract FDVanillaEngine factory2(GeneralizedBlackScholesProcess process, - int timeSteps, int gridPoints, bool timeDependent); - - public override void setupArguments(IPricingEngineArguments a) { - DividendVanillaOption.Arguments args = a as DividendVanillaOption.Arguments; - Utils.QL_REQUIRE(args != null,()=> "incorrect argument type"); - List events = new List(); - foreach (Event e in args.cashFlow) - events.Add(e); - base.setupArguments(a, events); - } - - protected double getDividendAmount(int i) { +namespace QLNet +{ + //! Abstract base class for dividend engines + /*! \todo The dividend class really needs to be made more + sophisticated to distinguish between fixed dividends and fractional dividends + */ + public abstract class FDDividendEngineBase : FDMultiPeriodEngine + { + // required for generics + protected FDDividendEngineBase() { } + + //public FDDividendEngineBase(GeneralizedBlackScholesProcess process, + // Size timeSteps = 100, Size gridPoints = 100, bool timeDependent = false) + protected FDDividendEngineBase(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) + : base(process, timeSteps, gridPoints, timeDependent) {} + + public override FDVanillaEngine factory(GeneralizedBlackScholesProcess process, + int timeSteps, int gridPoints, bool timeDependent) + { + return factory2(process, timeSteps, gridPoints, timeDependent); + } + + public abstract FDVanillaEngine factory2(GeneralizedBlackScholesProcess process, + int timeSteps, int gridPoints, bool timeDependent); + + public override void setupArguments(IPricingEngineArguments a) + { + DividendVanillaOption.Arguments args = a as DividendVanillaOption.Arguments; + Utils.QL_REQUIRE(args != null, () => "incorrect argument type"); + List events = new List(); + foreach (Event e in args.cashFlow) + events.Add(e); + base.setupArguments(a, events); + } + + protected double getDividendAmount(int i) + { + Dividend dividend = events_[i] as Dividend; + if (dividend != null) + { + return dividend.amount(); + } + else + { + return 0.0; + } + } + + protected double getDiscountedDividend(int i) + { + double dividend = getDividendAmount(i); + double discount = process_.riskFreeRate().link.discount(events_[i].date()) / + process_.dividendYield().link.discount(events_[i].date()); + return dividend * discount; + } + } + + + //! Finite-differences pricing engine for dividend options using + // escowed dividend model + /*! \ingroup vanillaengines */ + /* The merton 73 engine is the classic engine described in most + derivatives texts. However, Haug, Haug, and Lewis in + "Back to Basics: a new approach to the discrete dividend + problem" argues that this scheme underprices call options. + This is set as the default engine, because it is consistent + with the analytic version. + */ + public class FDDividendEngineMerton73 : FDDividendEngineBase + { + // required for generics + public FDDividendEngineMerton73() { } + + public FDDividendEngineMerton73(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) + : base(process, timeSteps, gridPoints, timeDependent) {} + + public override FDVanillaEngine factory2(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) + { + throw new NotImplementedException(); + } + // The value of the x axis is the NPV of the underlying minus the + // value of the paid dividends. + + // Note that to get the PDE to work, I have to scale the values + // and not shift them. This means that the price curve assumes + // that the dividends are scaled with the value of the underlying. + // + protected override void setGridLimits() + { + double paidDividends = 0.0; + for (int i = 0; i < events_.Count; i++) + { + if (getDividendTime(i) >= 0.0) + paidDividends += getDiscountedDividend(i); + } + + base.setGridLimits(process_.stateVariable().link.value() - paidDividends, getResidualTime()); + ensureStrikeInGrid(); + } + + // TODO: Make this work for both fixed and scaled dividends + protected override void executeIntermediateStep(int step) + { + double scaleFactor = getDiscountedDividend(step) / center_ + 1.0; + sMin_ *= scaleFactor; + sMax_ *= scaleFactor; + center_ *= scaleFactor; + + intrinsicValues_.scaleGrid(scaleFactor); + intrinsicValues_.sample(payoff_.value); + prices_.scaleGrid(scaleFactor); + initializeOperator(); + initializeModel(); + + initializeStepCondition(); + stepCondition_.applyTo(prices_.values(), getDividendTime(step)); + } + + + } + + + //! Finite-differences engine for dividend options using shifted dividends + /*! \ingroup vanillaengines */ + /* This engine uses the same algorithm that was used in quantlib + in versions 0.3.11 and earlier. It produces results that + are different from the Merton 73 engine. + + \todo Review literature to see whether this is described + */ + public class FDDividendEngineShiftScale : FDDividendEngineBase + { + public FDDividendEngineShiftScale(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) + : base(process, timeSteps, gridPoints, timeDependent) {} + + public override FDVanillaEngine factory2(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) + { + throw new NotImplementedException(); + } + + protected override void setGridLimits() + { + double underlying = process_.stateVariable().link.value(); + for (int i = 0; i < events_.Count; i++) + { Dividend dividend = events_[i] as Dividend; - if (dividend != null) { - return dividend.amount(); - } else { - return 0.0; - } - } - - protected double getDiscountedDividend(int i) { - double dividend = getDividendAmount(i); - double discount = process_.riskFreeRate().link.discount(events_[i].date()) / - process_.dividendYield().link.discount(events_[i].date()); - return dividend * discount; - } - } - - - //! Finite-differences pricing engine for dividend options using - // escowed dividend model - /*! \ingroup vanillaengines */ - /* The merton 73 engine is the classic engine described in most - derivatives texts. However, Haug, Haug, and Lewis in - "Back to Basics: a new approach to the discrete dividend - problem" argues that this scheme underprices call options. - This is set as the default engine, because it is consistent - with the analytic version. - */ - public class FDDividendEngineMerton73 : FDDividendEngineBase { - // required for generics - public FDDividendEngineMerton73() { } - - public FDDividendEngineMerton73(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) - : base(process, timeSteps, gridPoints, timeDependent) {} - - public override FDVanillaEngine factory2(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) - { - throw new NotImplementedException(); - } - // The value of the x axis is the NPV of the underlying minus the - // value of the paid dividends. - - // Note that to get the PDE to work, I have to scale the values - // and not shift them. This means that the price curve assumes - // that the dividends are scaled with the value of the underlying. - // - protected override void setGridLimits() { - double paidDividends = 0.0; - for (int i=0; i= 0.0) - paidDividends += getDiscountedDividend(i); - } - - base.setGridLimits(process_.stateVariable().link.value()-paidDividends, getResidualTime()); - ensureStrikeInGrid(); - } - - // TODO: Make this work for both fixed and scaled dividends - protected override void executeIntermediateStep(int step) { - double scaleFactor = getDiscountedDividend(step) / center_ + 1.0; - sMin_ *= scaleFactor; - sMax_ *= scaleFactor; - center_ *= scaleFactor; - - intrinsicValues_.scaleGrid(scaleFactor); - intrinsicValues_.sample(payoff_.value); - prices_.scaleGrid(scaleFactor); - initializeOperator(); - initializeModel(); - - initializeStepCondition(); - stepCondition_.applyTo(prices_.values(), getDividendTime(step)); - } - - - } - - - //! Finite-differences engine for dividend options using shifted dividends - /*! \ingroup vanillaengines */ - /* This engine uses the same algorithm that was used in quantlib - in versions 0.3.11 and earlier. It produces results that - are different from the Merton 73 engine. - - \todo Review literature to see whether this is described - */ - public class FDDividendEngineShiftScale : FDDividendEngineBase { - public FDDividendEngineShiftScale(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) - : base(process, timeSteps, gridPoints, timeDependent) {} - - public override FDVanillaEngine factory2(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) - { - throw new NotImplementedException(); - } - - protected override void setGridLimits() { - double underlying = process_.stateVariable().link.value(); - for (int i=0; i. - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,19 +19,19 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class FDDividendEuropeanEngine : FDEngineAdapter, IFDEngine - { - public FDDividendEuropeanEngine() - {} + public class FDDividendEuropeanEngine : FDEngineAdapter, IFDEngine + { + public FDDividendEuropeanEngine() + {} - public FDDividendEuropeanEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, - bool timeDependent = false) - : base(process, timeSteps, gridPoints, timeDependent) { } + public FDDividendEuropeanEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, + bool timeDependent = false) + : base(process, timeSteps, gridPoints, timeDependent) { } - public IFDEngine factory(GeneralizedBlackScholesProcess process, int timeSteps = 100 , int gridPoints = 100) - { - return new FDDividendEuropeanEngine(process, timeSteps, gridPoints); - } - } + public IFDEngine factory(GeneralizedBlackScholesProcess process, int timeSteps = 100, int gridPoints = 100) + { + return new FDDividendEuropeanEngine(process, timeSteps, gridPoints); + } + } } diff --git a/src/QLNet/Pricingengines/vanilla/FDEuropeanEngine.cs b/src/QLNet/Pricingengines/vanilla/FDEuropeanEngine.cs index f5e298bbe..d6d4e463b 100644 --- a/src/QLNet/Pricingengines/vanilla/FDEuropeanEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/FDEuropeanEngine.cs @@ -1,94 +1,104 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { - //! Pricing engine for European options using finite-differences - /*! \ingroup vanillaengines - - \test the correctness of the returned value is tested by - checking it against analytic results. - */ - public class FDEuropeanEngine : FDVanillaEngine, IGenericEngine { - private SampledCurve prices_; - - public FDEuropeanEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints) - : this(process, timeSteps, gridPoints, false) { } - public FDEuropeanEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) - : base(process, timeSteps, gridPoints, timeDependent) { - prices_ = new SampledCurve(gridPoints); - - process.registerWith(update); - } - - public void calculate() { - setupArguments(arguments_); - setGridLimits(); - initializeInitialCondition(); - initializeOperator(); - initializeBoundaryConditions(); - - var model = new FiniteDifferenceModel>(finiteDifferenceOperator_, BCs_); - - prices_ = (SampledCurve)intrinsicValues_.Clone(); - - // this is a workaround for pointers to avoid unsafe code - // in the grid calculation Vector temp goes through many operations - object temp = prices_.values(); - model.rollback(ref temp, getResidualTime(), 0, timeSteps_); - prices_.setValues((Vector)temp); - - results_.value = prices_.valueAtCenter(); - results_.delta = prices_.firstDerivativeAtCenter(); - results_.gamma = prices_.secondDerivativeAtCenter(); - results_.theta = Utils.blackScholesTheta(process_, - results_.value.GetValueOrDefault(), - results_.delta.GetValueOrDefault(), - results_.gamma.GetValueOrDefault()); - results_.additionalResults["priceCurve"] = prices_; - } - - #region IGenericEngine copy-cat - protected OneAssetOption.Arguments arguments_ = new OneAssetOption.Arguments(); - protected OneAssetOption.Results results_ = new OneAssetOption.Results(); - - public IPricingEngineArguments getArguments() { return arguments_; } - public IPricingEngineResults getResults() { return results_; } - public void reset() { results_.reset(); } - - #region Observer & Observable - // observable interface - private readonly WeakEventSource eventSource = new WeakEventSource(); - public event Callback notifyObserversEvent - { - add { eventSource.Subscribe(value); } - remove { eventSource.Unsubscribe(value); } - } - - public void registerWith(Callback handler) { notifyObserversEvent += handler; } - public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } - protected void notifyObservers() - { - eventSource.Raise(); - } - - public void update() { notifyObservers(); } - #endregion - #endregion - } +namespace QLNet +{ + //! Pricing engine for European options using finite-differences + /*! \ingroup vanillaengines + + \test the correctness of the returned value is tested by + checking it against analytic results. + */ + public class FDEuropeanEngine : FDVanillaEngine, IGenericEngine + { + private SampledCurve prices_; + + public FDEuropeanEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints) + : this(process, timeSteps, gridPoints, false) { } + public FDEuropeanEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) + : base(process, timeSteps, gridPoints, timeDependent) + { + prices_ = new SampledCurve(gridPoints); + + process.registerWith(update); + } + + public void calculate() + { + setupArguments(arguments_); + setGridLimits(); + initializeInitialCondition(); + initializeOperator(); + initializeBoundaryConditions(); + + var model = new FiniteDifferenceModel>(finiteDifferenceOperator_, BCs_); + + prices_ = (SampledCurve)intrinsicValues_.Clone(); + + // this is a workaround for pointers to avoid unsafe code + // in the grid calculation Vector temp goes through many operations + object temp = prices_.values(); + model.rollback(ref temp, getResidualTime(), 0, timeSteps_); + prices_.setValues((Vector)temp); + + results_.value = prices_.valueAtCenter(); + results_.delta = prices_.firstDerivativeAtCenter(); + results_.gamma = prices_.secondDerivativeAtCenter(); + results_.theta = Utils.blackScholesTheta(process_, + results_.value.GetValueOrDefault(), + results_.delta.GetValueOrDefault(), + results_.gamma.GetValueOrDefault()); + results_.additionalResults["priceCurve"] = prices_; + } + + #region IGenericEngine copy-cat + protected OneAssetOption.Arguments arguments_ = new OneAssetOption.Arguments(); + protected OneAssetOption.Results results_ = new OneAssetOption.Results(); + + public IPricingEngineArguments getArguments() { return arguments_; } + public IPricingEngineResults getResults() { return results_; } + public void reset() { results_.reset(); } + + #region Observer & Observable + // observable interface + private readonly WeakEventSource eventSource = new WeakEventSource(); + public event Callback notifyObserversEvent + { + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } + } + + public void registerWith(Callback handler) { notifyObserversEvent += handler; } + public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } + protected void notifyObservers() + { + eventSource.Raise(); + } + + public void update() { notifyObservers(); } + #endregion + #endregion + } } diff --git a/src/QLNet/Pricingengines/vanilla/FDMultiPeriodEngine.cs b/src/QLNet/Pricingengines/vanilla/FDMultiPeriodEngine.cs index d99dfac0d..0f0a7c47f 100644 --- a/src/QLNet/Pricingengines/vanilla/FDMultiPeriodEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/FDMultiPeriodEngine.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,150 +20,163 @@ under the terms of the QLNet license. You should have received a using System; using System.Collections.Generic; -namespace QLNet { - public class FDMultiPeriodEngine : FDConditionEngineTemplate { - protected List events_ = new List(); - protected List stoppingTimes_ = new List(); - protected int timeStepPerPeriod_; - protected FiniteDifferenceModel> model_; - - // required for generics - public FDMultiPeriodEngine() { } - - //protected FDMultiPeriodEngine(GeneralizedBlackScholesProcess process, - // int gridPoints = 100, int timeSteps = 100, bool timeDependent = false) - protected FDMultiPeriodEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) - : base(process, timeSteps, gridPoints, timeDependent) - { - timeStepPerPeriod_ = timeSteps; - } - - protected virtual void executeIntermediateStep(int step) { throw new NotSupportedException(); } - - - protected override void initializeStepCondition() { - stepCondition_ = new NullCondition(); - } - - protected virtual void initializeModel() { - model_ = new FiniteDifferenceModel>(finiteDifferenceOperator_,BCs_); - } - - protected double getDividendTime(int i) { - return stoppingTimes_[i]; - } - - protected virtual void setupArguments(IPricingEngineArguments args, List schedule) { - base.setupArguments(args); - events_ = schedule; - stoppingTimes_.Clear(); - int n = schedule.Count; - stoppingTimes_ = new List(n); - for (int i = 0; i < n; ++i) - stoppingTimes_.Add(process_.time(events_[i].date())); - } - - public override void setupArguments(IPricingEngineArguments a) { - base.setupArguments(a); - OneAssetOption.Arguments args = a as OneAssetOption.Arguments; - Utils.QL_REQUIRE(args != null,()=> "incorrect argument type"); - events_.Clear(); - - int n = args.exercise.dates().Count; - stoppingTimes_ = new InitializedList(n); - for (int i = 0; i < n; ++i) - stoppingTimes_[i] = process_.time(args.exercise.date(i)); - } - - public override void calculate(IPricingEngineResults r) { - OneAssetOption.Results results = r as OneAssetOption.Results; - Utils.QL_REQUIRE(results != null,()=> "incorrect results type"); - - double beginDate, endDate; - int dateNumber = stoppingTimes_.Count; - bool lastDateIsResTime = false; - int firstIndex = -1; - int lastIndex = dateNumber - 1; - bool firstDateIsZero = false; - double firstNonZeroDate = getResidualTime(); - - double dateTolerance = 1e-6; - int j; - - if (dateNumber > 0) { - Utils.QL_REQUIRE(getDividendTime(0) >= 0,()=> "first date (" + getDividendTime(0) + ") cannot be negative"); - if (getDividendTime(0) < getResidualTime() * dateTolerance) { - firstDateIsZero = true; - firstIndex = 0; - if (dateNumber >= 2) - firstNonZeroDate = getDividendTime(1); - } - - if (Math.Abs(getDividendTime(lastIndex) - getResidualTime()) < dateTolerance) { - lastDateIsResTime = true; - lastIndex = dateNumber - 2; - } - - if (!firstDateIsZero) - firstNonZeroDate = getDividendTime(0); - - if (dateNumber >= 2) { - for (j = 1; j < dateNumber; j++) - Utils.QL_REQUIRE(getDividendTime(j - 1) < getDividendTime(j),()=> - "dates must be in increasing order: " + getDividendTime(j - 1) + - " is not strictly smaller than " + getDividendTime(j)); - } +namespace QLNet +{ + public class FDMultiPeriodEngine : FDConditionEngineTemplate + { + protected List events_ = new List(); + protected List stoppingTimes_ = new List(); + protected int timeStepPerPeriod_; + protected FiniteDifferenceModel> model_; + + // required for generics + public FDMultiPeriodEngine() { } + + //protected FDMultiPeriodEngine(GeneralizedBlackScholesProcess process, + // int gridPoints = 100, int timeSteps = 100, bool timeDependent = false) + protected FDMultiPeriodEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) + : base(process, timeSteps, gridPoints, timeDependent) + { + timeStepPerPeriod_ = timeSteps; + } + + protected virtual void executeIntermediateStep(int step) { throw new NotSupportedException(); } + + + protected override void initializeStepCondition() + { + stepCondition_ = new NullCondition(); + } + + protected virtual void initializeModel() + { + model_ = new FiniteDifferenceModel>(finiteDifferenceOperator_, BCs_); + } + + protected double getDividendTime(int i) + { + return stoppingTimes_[i]; + } + + protected virtual void setupArguments(IPricingEngineArguments args, List schedule) + { + base.setupArguments(args); + events_ = schedule; + stoppingTimes_.Clear(); + int n = schedule.Count; + stoppingTimes_ = new List(n); + for (int i = 0; i < n; ++i) + stoppingTimes_.Add(process_.time(events_[i].date())); + } + + public override void setupArguments(IPricingEngineArguments a) + { + base.setupArguments(a); + OneAssetOption.Arguments args = a as OneAssetOption.Arguments; + Utils.QL_REQUIRE(args != null, () => "incorrect argument type"); + events_.Clear(); + + int n = args.exercise.dates().Count; + stoppingTimes_ = new InitializedList(n); + for (int i = 0; i < n; ++i) + stoppingTimes_[i] = process_.time(args.exercise.date(i)); + } + + public override void calculate(IPricingEngineResults r) + { + OneAssetOption.Results results = r as OneAssetOption.Results; + Utils.QL_REQUIRE(results != null, () => "incorrect results type"); + + double beginDate, endDate; + int dateNumber = stoppingTimes_.Count; + bool lastDateIsResTime = false; + int firstIndex = -1; + int lastIndex = dateNumber - 1; + bool firstDateIsZero = false; + double firstNonZeroDate = getResidualTime(); + + double dateTolerance = 1e-6; + int j; + + if (dateNumber > 0) + { + Utils.QL_REQUIRE(getDividendTime(0) >= 0, () => "first date (" + getDividendTime(0) + ") cannot be negative"); + if (getDividendTime(0) < getResidualTime() * dateTolerance) + { + firstDateIsZero = true; + firstIndex = 0; + if (dateNumber >= 2) + firstNonZeroDate = getDividendTime(1); } - double dt = getResidualTime() / (timeStepPerPeriod_ * (dateNumber + 1)); - - // Ensure that dt is always smaller than the first non-zero date - if (firstNonZeroDate <= dt) - dt = firstNonZeroDate / 2.0; - - setGridLimits(); - initializeInitialCondition(); - initializeOperator(); - initializeBoundaryConditions(); - initializeModel(); - initializeStepCondition(); - - prices_ = (SampledCurve)intrinsicValues_.Clone(); - if (lastDateIsResTime) - executeIntermediateStep(dateNumber - 1); - - j = lastIndex; - object temp; - do { - if (j == dateNumber - 1) - beginDate = getResidualTime(); - else - beginDate = getDividendTime(j + 1); - - if (j >= 0) - endDate = getDividendTime(j); - else - endDate = dt; + if (Math.Abs(getDividendTime(lastIndex) - getResidualTime()) < dateTolerance) + { + lastDateIsResTime = true; + lastIndex = dateNumber - 2; + } - temp = prices_.values(); - model_.rollback(ref temp, beginDate, endDate, timeStepPerPeriod_, stepCondition_); - prices_.setValues((Vector)temp); + if (!firstDateIsZero) + firstNonZeroDate = getDividendTime(0); - if (j >= 0) - executeIntermediateStep(j); - } while (--j >= firstIndex); + if (dateNumber >= 2) + { + for (j = 1; j < dateNumber; j++) + Utils.QL_REQUIRE(getDividendTime(j - 1) < getDividendTime(j), () => + "dates must be in increasing order: " + getDividendTime(j - 1) + + " is not strictly smaller than " + getDividendTime(j)); + } + } + + double dt = getResidualTime() / (timeStepPerPeriod_ * (dateNumber + 1)); + + // Ensure that dt is always smaller than the first non-zero date + if (firstNonZeroDate <= dt) + dt = firstNonZeroDate / 2.0; + + setGridLimits(); + initializeInitialCondition(); + initializeOperator(); + initializeBoundaryConditions(); + initializeModel(); + initializeStepCondition(); + + prices_ = (SampledCurve)intrinsicValues_.Clone(); + if (lastDateIsResTime) + executeIntermediateStep(dateNumber - 1); + + j = lastIndex; + object temp; + do + { + if (j == dateNumber - 1) + beginDate = getResidualTime(); + else + beginDate = getDividendTime(j + 1); + + if (j >= 0) + endDate = getDividendTime(j); + else + endDate = dt; temp = prices_.values(); - model_.rollback(ref temp, dt, 0, 1, stepCondition_); + model_.rollback(ref temp, beginDate, endDate, timeStepPerPeriod_, stepCondition_); prices_.setValues((Vector)temp); - if (firstDateIsZero) - executeIntermediateStep(0); + if (j >= 0) + executeIntermediateStep(j); + } while (--j >= firstIndex); + + temp = prices_.values(); + model_.rollback(ref temp, dt, 0, 1, stepCondition_); + prices_.setValues((Vector)temp); + + if (firstDateIsZero) + executeIntermediateStep(0); - results.value = prices_.valueAtCenter(); - results.delta = prices_.firstDerivativeAtCenter(); - results.gamma = prices_.secondDerivativeAtCenter(); - results.additionalResults["priceCurve"] = prices_; - } - } + results.value = prices_.valueAtCenter(); + results.delta = prices_.firstDerivativeAtCenter(); + results.gamma = prices_.secondDerivativeAtCenter(); + results.additionalResults["priceCurve"] = prices_; + } + } } diff --git a/src/QLNet/Pricingengines/vanilla/FDShoutEngine.cs b/src/QLNet/Pricingengines/vanilla/FDShoutEngine.cs index 57197015f..925f6717f 100644 --- a/src/QLNet/Pricingengines/vanilla/FDShoutEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/FDShoutEngine.cs @@ -1,42 +1,44 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { - //! Finite-differences pricing engine for shout vanilla options - /*! \ingroup vanillaengines - - \test the correctness of the returned greeks is tested by - reproducing numerical derivatives. - */ - public class FDShoutEngine : FDEngineAdapter, VanillaOption.Engine>, - IFDEngine { - // required for generics - public FDShoutEngine() { } - - public FDShoutEngine(GeneralizedBlackScholesProcess process, int timeSteps , int gridPoints , - bool timeDependent = false) - : base(process, timeSteps, gridPoints, timeDependent) { } - - public IFDEngine factory(GeneralizedBlackScholesProcess process, int timeSteps = 100, int gridPoints = 100 ) - { - return new FDShoutEngine(process, timeSteps, gridPoints); - } - } +namespace QLNet +{ + //! Finite-differences pricing engine for shout vanilla options + /*! \ingroup vanillaengines + + \test the correctness of the returned greeks is tested by + reproducing numerical derivatives. + */ + public class FDShoutEngine : FDEngineAdapter, VanillaOption.Engine>, + IFDEngine + { + // required for generics + public FDShoutEngine() { } + + public FDShoutEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, + bool timeDependent = false) + : base(process, timeSteps, gridPoints, timeDependent) { } + + public IFDEngine factory(GeneralizedBlackScholesProcess process, int timeSteps = 100, int gridPoints = 100) + { + return new FDShoutEngine(process, timeSteps, gridPoints); + } + } } diff --git a/src/QLNet/Pricingengines/vanilla/FDStepConditionEngine.cs b/src/QLNet/Pricingengines/vanilla/FDStepConditionEngine.cs index 492bbb37c..b423433ba 100644 --- a/src/QLNet/Pricingengines/vanilla/FDStepConditionEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/FDStepConditionEngine.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,91 +19,96 @@ under the terms of the QLNet license. You should have received a using System; using System.Collections.Generic; -namespace QLNet { - //! Finite-differences pricing engine for American-style vanilla options - public class FDStepConditionEngine : FDConditionEngineTemplate { - protected TridiagonalOperator controlOperator_; - protected List> controlBCs_; - protected SampledCurve controlPrices_; - - // required for generics - public FDStepConditionEngine() { } - // required for template inheritance - public override FDVanillaEngine factory(GeneralizedBlackScholesProcess process, - int timeSteps, int gridPoints, bool timeDependent) { - return new FDStepConditionEngine(process, timeSteps, gridPoints, timeDependent); - } - - //public FDStepConditionEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, - // bool timeDependent = false) - public FDStepConditionEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) - : base(process, timeSteps, gridPoints, timeDependent) { - controlBCs_ = new InitializedList>(2); - controlPrices_ = new SampledCurve(gridPoints); - } - - public override void calculate(IPricingEngineResults r) { - OneAssetOption.Results results = r as OneAssetOption.Results; - setGridLimits(); - initializeInitialCondition(); - initializeOperator(); - initializeBoundaryConditions(); - initializeStepCondition(); - - List operatorSet = new List(); - List arraySet = new List(); - BoundaryConditionSet bcSet = new BoundaryConditionSet(); - StepConditionSet conditionSet = new StepConditionSet(); - - prices_ = (SampledCurve)intrinsicValues_.Clone(); - - controlPrices_ = (SampledCurve)intrinsicValues_.Clone(); - controlOperator_ = (TridiagonalOperator)finiteDifferenceOperator_.Clone(); - controlBCs_[0] = BCs_[0]; - controlBCs_[1] = BCs_[1]; - - operatorSet.Add(finiteDifferenceOperator_); - operatorSet.Add(controlOperator_); - - arraySet.Add(prices_.values()); - arraySet.Add(controlPrices_.values()); - - bcSet.Add(BCs_); - bcSet.Add(controlBCs_); - - conditionSet.Add(stepCondition_); - conditionSet.Add(new NullCondition()); - - var model = new FiniteDifferenceModel>>(operatorSet, bcSet); - - object temp = arraySet; - model.rollback(ref temp, getResidualTime(), 0.0, timeSteps_, conditionSet); - arraySet = (List)temp; - - prices_.setValues(arraySet[0]); - controlPrices_.setValues(arraySet[1]); - - StrikedTypePayoff striked_payoff = payoff_ as StrikedTypePayoff; - Utils.QL_REQUIRE(striked_payoff != null,()=> "non-striked payoff given"); - - double variance = process_.blackVolatility().link.blackVariance(exerciseDate_, striked_payoff.strike()); - double dividendDiscount = process_.dividendYield().link.discount(exerciseDate_); - double riskFreeDiscount = process_.riskFreeRate().link.discount(exerciseDate_); - double spot = process_.stateVariable().link.value(); - double forwardPrice = spot * dividendDiscount / riskFreeDiscount; - - BlackCalculator black = new BlackCalculator(striked_payoff, forwardPrice, Math.Sqrt(variance), riskFreeDiscount); - - results.value = prices_.valueAtCenter() - - controlPrices_.valueAtCenter() - + black.value(); - results.delta = prices_.firstDerivativeAtCenter() - - controlPrices_.firstDerivativeAtCenter() - + black.delta(spot); - results.gamma = prices_.secondDerivativeAtCenter() - - controlPrices_.secondDerivativeAtCenter() - + black.gamma(spot); - results.additionalResults["priceCurve"] = prices_; - } - } +namespace QLNet +{ + //! Finite-differences pricing engine for American-style vanilla options + public class FDStepConditionEngine : FDConditionEngineTemplate + { + protected TridiagonalOperator controlOperator_; + protected List> controlBCs_; + protected SampledCurve controlPrices_; + + // required for generics + public FDStepConditionEngine() { } + // required for template inheritance + public override FDVanillaEngine factory(GeneralizedBlackScholesProcess process, + int timeSteps, int gridPoints, bool timeDependent) + { + return new FDStepConditionEngine(process, timeSteps, gridPoints, timeDependent); + } + + //public FDStepConditionEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, + // bool timeDependent = false) + public FDStepConditionEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) + : base(process, timeSteps, gridPoints, timeDependent) + { + controlBCs_ = new InitializedList>(2); + controlPrices_ = new SampledCurve(gridPoints); + } + + public override void calculate(IPricingEngineResults r) + { + OneAssetOption.Results results = r as OneAssetOption.Results; + setGridLimits(); + initializeInitialCondition(); + initializeOperator(); + initializeBoundaryConditions(); + initializeStepCondition(); + + List operatorSet = new List(); + List arraySet = new List(); + BoundaryConditionSet bcSet = new BoundaryConditionSet(); + StepConditionSet conditionSet = new StepConditionSet(); + + prices_ = (SampledCurve)intrinsicValues_.Clone(); + + controlPrices_ = (SampledCurve)intrinsicValues_.Clone(); + controlOperator_ = (TridiagonalOperator)finiteDifferenceOperator_.Clone(); + controlBCs_[0] = BCs_[0]; + controlBCs_[1] = BCs_[1]; + + operatorSet.Add(finiteDifferenceOperator_); + operatorSet.Add(controlOperator_); + + arraySet.Add(prices_.values()); + arraySet.Add(controlPrices_.values()); + + bcSet.Add(BCs_); + bcSet.Add(controlBCs_); + + conditionSet.Add(stepCondition_); + conditionSet.Add(new NullCondition()); + + var model = new FiniteDifferenceModel>>(operatorSet, bcSet); + + object temp = arraySet; + model.rollback(ref temp, getResidualTime(), 0.0, timeSteps_, conditionSet); + arraySet = (List)temp; + + prices_.setValues(arraySet[0]); + controlPrices_.setValues(arraySet[1]); + + StrikedTypePayoff striked_payoff = payoff_ as StrikedTypePayoff; + Utils.QL_REQUIRE(striked_payoff != null, () => "non-striked payoff given"); + + double variance = process_.blackVolatility().link.blackVariance(exerciseDate_, striked_payoff.strike()); + double dividendDiscount = process_.dividendYield().link.discount(exerciseDate_); + double riskFreeDiscount = process_.riskFreeRate().link.discount(exerciseDate_); + double spot = process_.stateVariable().link.value(); + double forwardPrice = spot * dividendDiscount / riskFreeDiscount; + + BlackCalculator black = new BlackCalculator(striked_payoff, forwardPrice, Math.Sqrt(variance), riskFreeDiscount); + + results.value = prices_.valueAtCenter() + - controlPrices_.valueAtCenter() + + black.value(); + results.delta = prices_.firstDerivativeAtCenter() + - controlPrices_.firstDerivativeAtCenter() + + black.delta(spot); + results.gamma = prices_.secondDerivativeAtCenter() + - controlPrices_.secondDerivativeAtCenter() + + black.gamma(spot); + results.additionalResults["priceCurve"] = prices_; + } + } } diff --git a/src/QLNet/Pricingengines/vanilla/FDVanillaEngine.cs b/src/QLNet/Pricingengines/vanilla/FDVanillaEngine.cs index 63ccfa373..061d74ae8 100644 --- a/src/QLNet/Pricingengines/vanilla/FDVanillaEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/FDVanillaEngine.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,186 +20,213 @@ under the terms of the QLNet license. You should have received a using System; using System.Collections.Generic; -namespace QLNet { - //! Finite-differences pricing engine for BSM one asset options - /*! The name is a misnomer as this is a base class for any finite difference scheme. Its main job is to handle grid layout. - - \ingroup vanillaengines - */ - public class FDVanillaEngine { - protected GeneralizedBlackScholesProcess process_; - protected int timeSteps_, gridPoints_; - protected bool timeDependent_; - protected Date exerciseDate_; - protected Payoff payoff_; - protected TridiagonalOperator finiteDifferenceOperator_; - public SampledCurve intrinsicValues_ { get; set; } +namespace QLNet +{ + //! Finite-differences pricing engine for BSM one asset options + /*! The name is a misnomer as this is a base class for any finite difference scheme. Its main job is to handle grid layout. + + \ingroup vanillaengines + */ + public class FDVanillaEngine + { + protected GeneralizedBlackScholesProcess process_; + protected int timeSteps_, gridPoints_; + protected bool timeDependent_; + protected Date exerciseDate_; + protected Payoff payoff_; + protected TridiagonalOperator finiteDifferenceOperator_; + public SampledCurve intrinsicValues_ { get; set; } protected List> BCs_; - // temporaries - protected double sMin_, center_, sMax_; - - // temporaries - const double safetyZoneFactor_ = 1.1; - - // required for generics and template iheritance - public FDVanillaEngine() { } - // this should be defined as new in each deriving class which use template iheritance - // in order to return a proper class to wrap - public virtual FDVanillaEngine factory(GeneralizedBlackScholesProcess process, - int timeSteps, int gridPoints, bool timeDependent) { - return new FDVanillaEngine(process, timeSteps, gridPoints, timeDependent); - } - - public FDVanillaEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) { - process_ = process; - timeSteps_ = timeSteps; - gridPoints_ = gridPoints; - timeDependent_ = timeDependent; - intrinsicValues_ = new SampledCurve(gridPoints); - BCs_ = new InitializedList>(2); - } - - public Vector grid() { return intrinsicValues_.grid(); } - - protected virtual void setGridLimits() { - setGridLimits(process_.stateVariable().link.value(), getResidualTime()); - ensureStrikeInGrid(); - } - - protected void setGridLimits(double center, double t) { - Utils.QL_REQUIRE(center > 0.0,()=> "negative or null underlying given"); - Utils.QL_REQUIRE( t > 0.0,()=> "negative or zero residual time" ); - center_ = center; - int newGridPoints = safeGridPoints(gridPoints_, t); - if (newGridPoints > intrinsicValues_.size()) { - intrinsicValues_ = new SampledCurve(newGridPoints); - } - - double volSqrtTime = Math.Sqrt(process_.blackVolatility().link.blackVariance(t, center_)); - - // the prefactor fine tunes performance at small volatilities - double prefactor = 1.0 + 0.02/volSqrtTime; - double minMaxFactor = Math.Exp(4.0 * prefactor * volSqrtTime); - sMin_ = center_/minMaxFactor; // underlying grid min value - sMax_ = center_*minMaxFactor; // underlying grid max value - } - - public void ensureStrikeInGrid() { - // ensure strike is included in the grid - StrikedTypePayoff striked_payoff = payoff_ as StrikedTypePayoff; - if (striked_payoff == null) return; - - double requiredGridValue = striked_payoff.strike(); - - if(sMin_ > requiredGridValue/safetyZoneFactor_){ - sMin_ = requiredGridValue/safetyZoneFactor_; - // enforce central placement of the underlying - sMax_ = center_/(sMin_/center_); - } - if(sMax_ < requiredGridValue*safetyZoneFactor_){ - sMax_ = requiredGridValue*safetyZoneFactor_; - // enforce central placement of the underlying - sMin_ = center_/(sMax_/center_); - } - } - - protected void initializeInitialCondition() { - intrinsicValues_.setLogGrid(sMin_, sMax_); - intrinsicValues_.sample(payoff_.value); - } - - protected void initializeOperator() { - finiteDifferenceOperator_ = OperatorFactory.getOperator(process_, intrinsicValues_.grid(), - getResidualTime(), timeDependent_); - } - - protected void initializeBoundaryConditions() { - BCs_[0] = new NeumannBC(intrinsicValues_.value(1) - intrinsicValues_.value(0), NeumannBC.Side.Lower); - BCs_[1] = new NeumannBC(intrinsicValues_.value(intrinsicValues_.size() - 1) - - intrinsicValues_.value(intrinsicValues_.size()-2), - NeumannBC.Side.Upper); - } - - public double getResidualTime() { - return process_.time(exerciseDate_); - } - - // safety check to be sure we have enough grid points. - private int safeGridPoints(int gridPoints, double residualTime) { - const int minGridPoints = 10; - const int minGridPointsPerYear = 2; - return Math.Max(gridPoints, - residualTime > 1 ? - (int)(minGridPoints + (residualTime-1.0) * minGridPointsPerYear) - : minGridPoints); - } - - public virtual void setupArguments(IPricingEngineArguments a) { - OneAssetOption.Arguments args = a as OneAssetOption.Arguments; - Utils.QL_REQUIRE(args != null,()=> "incorrect argument type"); - - exerciseDate_ = args.exercise.lastDate(); - payoff_ = args.payoff; - } - public virtual void calculate(IPricingEngineResults r) { throw new NotSupportedException(); } - } - - - // this is the interface to allow generic use of FDAmericanEngine and FDShoutEngine - // those engines are shortcuts to FDEngineAdapter - public interface IFDEngine : IPricingEngine { - IFDEngine factory(GeneralizedBlackScholesProcess process, int timeSteps = 100 , int gridPoints = 100); - } - - public class FDEngineAdapter : FDVanillaEngine, IGenericEngine - where Base : FDConditionEngineTemplate, new() - where Engine : IGenericEngine, new() { - - // a wrap-up of base engine - Base optionBase; - - // required for generics - public FDEngineAdapter() { } - - //public FDEngineAdapter(GeneralizedBlackScholesProcess process, Size timeSteps=100, Size gridPoints=100, bool timeDependent = false) - public FDEngineAdapter(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) { - optionBase = (Base) FastActivator.Create().factory(process, timeSteps, gridPoints, timeDependent); - process.registerWith(update); - } - - public void calculate() { - optionBase.setupArguments(getArguments()); - optionBase.calculate(getResults()); - } - - - #region IGenericEngine wrap-up - // we do not need to register with the wrapped engine because all we need is containers for parameters and results - protected IGenericEngine engine_ = FastActivator.Create(); - - public IPricingEngineArguments getArguments() { return engine_.getArguments(); } - public IPricingEngineResults getResults() { return engine_.getResults(); } - public void reset() { engine_.reset(); } - #endregion - - #region Observer & Observable - // observable interface - private readonly WeakEventSource eventSource = new WeakEventSource(); - public event Callback notifyObserversEvent - { - add { eventSource.Subscribe(value); } - remove { eventSource.Unsubscribe(value); } - } - - public void registerWith(Callback handler) { notifyObserversEvent += handler; } - public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } - protected void notifyObservers() - { - eventSource.Raise(); - } - - public void update() { notifyObservers(); } - #endregion - } + // temporaries + protected double sMin_, center_, sMax_; + + // temporaries + const double safetyZoneFactor_ = 1.1; + + // required for generics and template iheritance + public FDVanillaEngine() { } + // this should be defined as new in each deriving class which use template iheritance + // in order to return a proper class to wrap + public virtual FDVanillaEngine factory(GeneralizedBlackScholesProcess process, + int timeSteps, int gridPoints, bool timeDependent) + { + return new FDVanillaEngine(process, timeSteps, gridPoints, timeDependent); + } + + public FDVanillaEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) + { + process_ = process; + timeSteps_ = timeSteps; + gridPoints_ = gridPoints; + timeDependent_ = timeDependent; + intrinsicValues_ = new SampledCurve(gridPoints); + BCs_ = new InitializedList>(2); + } + + public Vector grid() { return intrinsicValues_.grid(); } + + protected virtual void setGridLimits() + { + setGridLimits(process_.stateVariable().link.value(), getResidualTime()); + ensureStrikeInGrid(); + } + + protected void setGridLimits(double center, double t) + { + Utils.QL_REQUIRE(center > 0.0, () => "negative or null underlying given"); + Utils.QL_REQUIRE(t > 0.0, () => "negative or zero residual time"); + center_ = center; + int newGridPoints = safeGridPoints(gridPoints_, t); + if (newGridPoints > intrinsicValues_.size()) + { + intrinsicValues_ = new SampledCurve(newGridPoints); + } + + double volSqrtTime = Math.Sqrt(process_.blackVolatility().link.blackVariance(t, center_)); + + // the prefactor fine tunes performance at small volatilities + double prefactor = 1.0 + 0.02 / volSqrtTime; + double minMaxFactor = Math.Exp(4.0 * prefactor * volSqrtTime); + sMin_ = center_ / minMaxFactor; // underlying grid min value + sMax_ = center_ * minMaxFactor; // underlying grid max value + } + + public void ensureStrikeInGrid() + { + // ensure strike is included in the grid + StrikedTypePayoff striked_payoff = payoff_ as StrikedTypePayoff; + if (striked_payoff == null) + return; + + double requiredGridValue = striked_payoff.strike(); + + if (sMin_ > requiredGridValue / safetyZoneFactor_) + { + sMin_ = requiredGridValue / safetyZoneFactor_; + // enforce central placement of the underlying + sMax_ = center_ / (sMin_ / center_); + } + if (sMax_ < requiredGridValue * safetyZoneFactor_) + { + sMax_ = requiredGridValue * safetyZoneFactor_; + // enforce central placement of the underlying + sMin_ = center_ / (sMax_ / center_); + } + } + + protected void initializeInitialCondition() + { + intrinsicValues_.setLogGrid(sMin_, sMax_); + intrinsicValues_.sample(payoff_.value); + } + + protected void initializeOperator() + { + finiteDifferenceOperator_ = OperatorFactory.getOperator(process_, intrinsicValues_.grid(), + getResidualTime(), timeDependent_); + } + + protected void initializeBoundaryConditions() + { + BCs_[0] = new NeumannBC(intrinsicValues_.value(1) - intrinsicValues_.value(0), NeumannBC.Side.Lower); + BCs_[1] = new NeumannBC(intrinsicValues_.value(intrinsicValues_.size() - 1) - + intrinsicValues_.value(intrinsicValues_.size() - 2), + NeumannBC.Side.Upper); + } + + public double getResidualTime() + { + return process_.time(exerciseDate_); + } + + // safety check to be sure we have enough grid points. + private int safeGridPoints(int gridPoints, double residualTime) + { + const int minGridPoints = 10; + const int minGridPointsPerYear = 2; + return Math.Max(gridPoints, + residualTime > 1 ? + (int)(minGridPoints + (residualTime - 1.0) * minGridPointsPerYear) + : minGridPoints); + } + + public virtual void setupArguments(IPricingEngineArguments a) + { + OneAssetOption.Arguments args = a as OneAssetOption.Arguments; + Utils.QL_REQUIRE(args != null, () => "incorrect argument type"); + + exerciseDate_ = args.exercise.lastDate(); + payoff_ = args.payoff; + } + public virtual void calculate(IPricingEngineResults r) { throw new NotSupportedException(); } + } + + + // this is the interface to allow generic use of FDAmericanEngine and FDShoutEngine + // those engines are shortcuts to FDEngineAdapter + public interface IFDEngine : IPricingEngine + { + IFDEngine factory(GeneralizedBlackScholesProcess process, int timeSteps = 100, int gridPoints = 100); + } + + public class FDEngineAdapter : FDVanillaEngine, IGenericEngine + where Base : FDConditionEngineTemplate, new () + where Engine : IGenericEngine, new () + { + + // a wrap-up of base engine + Base optionBase; + + // required for generics + public FDEngineAdapter() { } + + //public FDEngineAdapter(GeneralizedBlackScholesProcess process, Size timeSteps=100, Size gridPoints=100, bool timeDependent = false) + public FDEngineAdapter(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) + { + optionBase = (Base) FastActivator.Create().factory(process, timeSteps, gridPoints, timeDependent); + process.registerWith(update); + } + + public void calculate() + { + optionBase.setupArguments(getArguments()); + optionBase.calculate(getResults()); + } + + + #region IGenericEngine wrap-up + // we do not need to register with the wrapped engine because all we need is containers for parameters and results + protected IGenericEngine engine_ = FastActivator.Create(); + + public IPricingEngineArguments getArguments() { return engine_.getArguments(); } + public IPricingEngineResults getResults() { return engine_.getResults(); } + public void reset() { engine_.reset(); } + #endregion + + #region Observer & Observable + // observable interface + private readonly WeakEventSource eventSource = new WeakEventSource(); + public event Callback notifyObserversEvent + { + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } + } + + public void registerWith(Callback handler) { notifyObserversEvent += handler; } + public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } + protected void notifyObservers() + { + eventSource.Raise(); + } + + public void update() { notifyObservers(); } + #endregion + } } diff --git a/src/QLNet/Pricingengines/vanilla/FdBlackScholesVanillaEngine.cs b/src/QLNet/Pricingengines/vanilla/FdBlackScholesVanillaEngine.cs index 846365ad4..44da25eb2 100644 --- a/src/QLNet/Pricingengines/vanilla/FdBlackScholesVanillaEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/FdBlackScholesVanillaEngine.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,80 +23,81 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class FdBlackScholesVanillaEngine : DividendVanillaOption.Engine - { - public FdBlackScholesVanillaEngine( - GeneralizedBlackScholesProcess process, - int tGrid = 100, int xGrid = 100, int dampingSteps = 0, - FdmSchemeDesc schemeDesc = null, - bool localVol = false, - double? illegalLocalVolOverwrite = null) - { - process_ = process; - tGrid_ = tGrid; - xGrid_ = xGrid; - dampingSteps_ = dampingSteps; - schemeDesc_ = schemeDesc == null ? new FdmSchemeDesc().Douglas() : schemeDesc; - localVol_ = localVol; - illegalLocalVolOverwrite_ = illegalLocalVolOverwrite; - - process_.registerWith(update); - } - - public override void calculate() { - // 1. Mesher - StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; - - double maturity = process_.time(arguments_.exercise.lastDate()); - Fdm1dMesher equityMesher = - new FdmBlackScholesMesher( - xGrid_, process_, maturity, payoff.strike(), - null, null, 0.0001, 1.5, - new Pair(payoff.strike(), 0.1)); - - FdmMesher mesher = - new FdmMesherComposite(equityMesher); - - // 2. Calculator - FdmInnerValueCalculator calculator = new FdmLogInnerValue(payoff, mesher, 0); - - // 3. Step conditions - FdmStepConditionComposite conditions = FdmStepConditionComposite.vanillaComposite( - arguments_.cashFlow, arguments_.exercise, - mesher, calculator, - process_.riskFreeRate().currentLink().referenceDate(), - process_.riskFreeRate().currentLink().dayCounter()); - - // 4. Boundary conditions - FdmBoundaryConditionSet boundaries = new FdmBoundaryConditionSet(); - - // 5. Solver - FdmSolverDesc solverDesc = new FdmSolverDesc(); - solverDesc.mesher = mesher; - solverDesc.bcSet = boundaries; - solverDesc.condition = conditions; - solverDesc.calculator = calculator; - solverDesc.maturity = maturity; - solverDesc.dampingSteps = dampingSteps_; - solverDesc.timeSteps = tGrid_; - - FdmBlackScholesSolver solver = - new FdmBlackScholesSolver( - new Handle(process_), - payoff.strike(), solverDesc, schemeDesc_, - localVol_, illegalLocalVolOverwrite_); - - double spot = process_.x0(); - results_.value = solver.valueAt(spot); - results_.delta = solver.deltaAt(spot); - results_.gamma = solver.gammaAt(spot); - results_.theta = solver.thetaAt(spot); - } - - protected GeneralizedBlackScholesProcess process_; - protected int tGrid_, xGrid_, dampingSteps_; - protected FdmSchemeDesc schemeDesc_; - protected bool localVol_; - protected double? illegalLocalVolOverwrite_; - } + public class FdBlackScholesVanillaEngine : DividendVanillaOption.Engine + { + public FdBlackScholesVanillaEngine( + GeneralizedBlackScholesProcess process, + int tGrid = 100, int xGrid = 100, int dampingSteps = 0, + FdmSchemeDesc schemeDesc = null, + bool localVol = false, + double? illegalLocalVolOverwrite = null) + { + process_ = process; + tGrid_ = tGrid; + xGrid_ = xGrid; + dampingSteps_ = dampingSteps; + schemeDesc_ = schemeDesc == null ? new FdmSchemeDesc().Douglas() : schemeDesc; + localVol_ = localVol; + illegalLocalVolOverwrite_ = illegalLocalVolOverwrite; + + process_.registerWith(update); + } + + public override void calculate() + { + // 1. Mesher + StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; + + double maturity = process_.time(arguments_.exercise.lastDate()); + Fdm1dMesher equityMesher = + new FdmBlackScholesMesher( + xGrid_, process_, maturity, payoff.strike(), + null, null, 0.0001, 1.5, + new Pair < double?, double? >(payoff.strike(), 0.1)); + + FdmMesher mesher = + new FdmMesherComposite(equityMesher); + + // 2. Calculator + FdmInnerValueCalculator calculator = new FdmLogInnerValue(payoff, mesher, 0); + + // 3. Step conditions + FdmStepConditionComposite conditions = FdmStepConditionComposite.vanillaComposite( + arguments_.cashFlow, arguments_.exercise, + mesher, calculator, + process_.riskFreeRate().currentLink().referenceDate(), + process_.riskFreeRate().currentLink().dayCounter()); + + // 4. Boundary conditions + FdmBoundaryConditionSet boundaries = new FdmBoundaryConditionSet(); + + // 5. Solver + FdmSolverDesc solverDesc = new FdmSolverDesc(); + solverDesc.mesher = mesher; + solverDesc.bcSet = boundaries; + solverDesc.condition = conditions; + solverDesc.calculator = calculator; + solverDesc.maturity = maturity; + solverDesc.dampingSteps = dampingSteps_; + solverDesc.timeSteps = tGrid_; + + FdmBlackScholesSolver solver = + new FdmBlackScholesSolver( + new Handle(process_), + payoff.strike(), solverDesc, schemeDesc_, + localVol_, illegalLocalVolOverwrite_); + + double spot = process_.x0(); + results_.value = solver.valueAt(spot); + results_.delta = solver.deltaAt(spot); + results_.gamma = solver.gammaAt(spot); + results_.theta = solver.thetaAt(spot); + } + + protected GeneralizedBlackScholesProcess process_; + protected int tGrid_, xGrid_, dampingSteps_; + protected FdmSchemeDesc schemeDesc_; + protected bool localVol_; + protected double? illegalLocalVolOverwrite_; + } } diff --git a/src/QLNet/Pricingengines/vanilla/FdHestonVanillaEngine.cs b/src/QLNet/Pricingengines/vanilla/FdHestonVanillaEngine.cs index b7e77cad2..6ebd20a18 100644 --- a/src/QLNet/Pricingengines/vanilla/FdHestonVanillaEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/FdHestonVanillaEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Pricingengines/vanilla/FdHullWhiteSwaptionEngine.cs b/src/QLNet/Pricingengines/vanilla/FdHullWhiteSwaptionEngine.cs index b03436402..46a61339c 100644 --- a/src/QLNet/Pricingengines/vanilla/FdHullWhiteSwaptionEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/FdHullWhiteSwaptionEngine.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,95 +23,97 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class FdHullWhiteSwaptionEngine : GenericModelEngine - { - public FdHullWhiteSwaptionEngine( - HullWhite model, - int tGrid = 100, int xGrid = 100, - int dampingSteps = 0, double invEps = 1e-5, - FdmSchemeDesc schemeDesc = null) - : base(model) - { - tGrid_ = tGrid; - xGrid_ = xGrid; - dampingSteps_ = dampingSteps; - schemeDesc_ = schemeDesc == null ? new FdmSchemeDesc().Douglas() : schemeDesc; - invEps_ = invEps; - } - - public override void calculate() { - // 1. Term structure - Handle ts = model_.currentLink().termStructure(); - - // 2. Mesher - DayCounter dc = ts.currentLink().dayCounter(); - Date referenceDate = ts.currentLink().referenceDate(); - double maturity = dc.yearFraction(referenceDate, - arguments_.exercise.lastDate()); - - - OrnsteinUhlenbeckProcess process = new OrnsteinUhlenbeckProcess(model_.currentLink().a(), model_.currentLink().sigma()); - - Fdm1dMesher shortRateMesher = - new FdmSimpleProcess1DMesher(xGrid_, process, maturity, 1, invEps_); - - FdmMesher mesher = new FdmMesherComposite(shortRateMesher); - - // 3. Inner Value Calculator - List exerciseDates = arguments_.exercise.dates(); - Dictionary t2d = new Dictionary(); - - for (int i=0; i < exerciseDates.Count; ++i) { - double t = dc.yearFraction(referenceDate, exerciseDates[i]); - Utils.QL_REQUIRE(t >= 0, () => "exercise dates must not contain past date"); - - t2d.Add(t, exerciseDates[i]); - } - - Handle disTs = model_.currentLink().termStructure(); - Handle fwdTs - = arguments_.swap.iborIndex().forwardingTermStructure(); - - Utils.QL_REQUIRE(fwdTs.currentLink().dayCounter() == disTs.currentLink().dayCounter(), - () => "day counter of forward and discount curve must match"); - Utils.QL_REQUIRE(fwdTs.currentLink().referenceDate() == disTs.currentLink().referenceDate(), - () => "reference date of forward and discount curve must match"); - - HullWhite fwdModel = - new HullWhite(fwdTs, model_.currentLink().a(), model_.currentLink().sigma()); - - FdmInnerValueCalculator calculator = - new FdmAffineModelSwapInnerValue( - model_.currentLink(), fwdModel, - arguments_.swap, t2d, mesher, 0); - - // 4. Step conditions - FdmStepConditionComposite conditions = - FdmStepConditionComposite.vanillaComposite( - new DividendSchedule(), arguments_.exercise, - mesher, calculator, referenceDate, dc); - - // 5. Boundary conditions - FdmBoundaryConditionSet boundaries = new FdmBoundaryConditionSet(); - - // 6. Solver - FdmSolverDesc solverDesc = new FdmSolverDesc(); - solverDesc.mesher = mesher; - solverDesc.bcSet = boundaries; - solverDesc.condition = conditions; - solverDesc.calculator = calculator; - solverDesc.maturity = maturity; - solverDesc.timeSteps = tGrid_; - solverDesc.dampingSteps = dampingSteps_; - - FdmHullWhiteSolver solver = - new FdmHullWhiteSolver(model_, solverDesc, schemeDesc_); - - results_.value = solver.valueAt(0.0); - } - - protected int tGrid_, xGrid_, dampingSteps_; - protected FdmSchemeDesc schemeDesc_; - protected double invEps_; - } + public class FdHullWhiteSwaptionEngine : GenericModelEngine + { + public FdHullWhiteSwaptionEngine( + HullWhite model, + int tGrid = 100, int xGrid = 100, + int dampingSteps = 0, double invEps = 1e-5, + FdmSchemeDesc schemeDesc = null) + : base(model) + { + tGrid_ = tGrid; + xGrid_ = xGrid; + dampingSteps_ = dampingSteps; + schemeDesc_ = schemeDesc == null ? new FdmSchemeDesc().Douglas() : schemeDesc; + invEps_ = invEps; + } + + public override void calculate() + { + // 1. Term structure + Handle ts = model_.currentLink().termStructure(); + + // 2. Mesher + DayCounter dc = ts.currentLink().dayCounter(); + Date referenceDate = ts.currentLink().referenceDate(); + double maturity = dc.yearFraction(referenceDate, + arguments_.exercise.lastDate()); + + + OrnsteinUhlenbeckProcess process = new OrnsteinUhlenbeckProcess(model_.currentLink().a(), model_.currentLink().sigma()); + + Fdm1dMesher shortRateMesher = + new FdmSimpleProcess1DMesher(xGrid_, process, maturity, 1, invEps_); + + FdmMesher mesher = new FdmMesherComposite(shortRateMesher); + + // 3. Inner Value Calculator + List exerciseDates = arguments_.exercise.dates(); + Dictionary t2d = new Dictionary(); + + for (int i = 0; i < exerciseDates.Count; ++i) + { + double t = dc.yearFraction(referenceDate, exerciseDates[i]); + Utils.QL_REQUIRE(t >= 0, () => "exercise dates must not contain past date"); + + t2d.Add(t, exerciseDates[i]); + } + + Handle disTs = model_.currentLink().termStructure(); + Handle fwdTs + = arguments_.swap.iborIndex().forwardingTermStructure(); + + Utils.QL_REQUIRE(fwdTs.currentLink().dayCounter() == disTs.currentLink().dayCounter(), + () => "day counter of forward and discount curve must match"); + Utils.QL_REQUIRE(fwdTs.currentLink().referenceDate() == disTs.currentLink().referenceDate(), + () => "reference date of forward and discount curve must match"); + + HullWhite fwdModel = + new HullWhite(fwdTs, model_.currentLink().a(), model_.currentLink().sigma()); + + FdmInnerValueCalculator calculator = + new FdmAffineModelSwapInnerValue( + model_.currentLink(), fwdModel, + arguments_.swap, t2d, mesher, 0); + + // 4. Step conditions + FdmStepConditionComposite conditions = + FdmStepConditionComposite.vanillaComposite( + new DividendSchedule(), arguments_.exercise, + mesher, calculator, referenceDate, dc); + + // 5. Boundary conditions + FdmBoundaryConditionSet boundaries = new FdmBoundaryConditionSet(); + + // 6. Solver + FdmSolverDesc solverDesc = new FdmSolverDesc(); + solverDesc.mesher = mesher; + solverDesc.bcSet = boundaries; + solverDesc.condition = conditions; + solverDesc.calculator = calculator; + solverDesc.maturity = maturity; + solverDesc.timeSteps = tGrid_; + solverDesc.dampingSteps = dampingSteps_; + + FdmHullWhiteSolver solver = + new FdmHullWhiteSolver(model_, solverDesc, schemeDesc_); + + results_.value = solver.valueAt(0.0); + } + + protected int tGrid_, xGrid_, dampingSteps_; + protected FdmSchemeDesc schemeDesc_; + protected double invEps_; + } } diff --git a/src/QLNet/Pricingengines/vanilla/HestonExpansionEngine.cs b/src/QLNet/Pricingengines/vanilla/HestonExpansionEngine.cs index 0321f12e0..bdaecf5da 100644 --- a/src/QLNet/Pricingengines/vanilla/HestonExpansionEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/HestonExpansionEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -30,13 +30,13 @@ multifactor local-stochastic vol models \ingroup vanillaengines */ - public class HestonExpansionEngine : GenericModelEngine + public class HestonExpansionEngine : GenericModelEngine { - public enum HestonExpansionFormula { LPP2, LPP3, Forde }; + public enum HestonExpansionFormula { LPP2, LPP3, Forde } - public HestonExpansionEngine(HestonModel model,HestonExpansionFormula formula) - :base(model) + public HestonExpansionEngine(HestonModel model, HestonExpansionFormula formula) + : base(model) { formula_ = formula; } @@ -44,7 +44,7 @@ public HestonExpansionEngine(HestonModel model,HestonExpansionFormula formula) public override void calculate() { // this is a european option pricer - Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European,()=>"not an European option"); + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European option"); // plain vanilla PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; @@ -63,28 +63,28 @@ public override void calculate() //possible optimization: // if term=lastTerm & model=lastModel & formula=lastApprox, reuse approx. - double forward = spotPrice*dividendDiscount/riskFreeDiscount; + double forward = spotPrice * dividendDiscount / riskFreeDiscount; double vol = 0; - switch(formula_) + switch (formula_) { - case HestonExpansionFormula.LPP2: + case HestonExpansionFormula.LPP2: { LPP2HestonExpansion expansion = new LPP2HestonExpansion(model_.link.kappa(), model_.link.theta(), - model_.link.sigma(), model_.link.v0(),model_.link.rho(), term); + model_.link.sigma(), model_.link.v0(), model_.link.rho(), term); vol = expansion.impliedVolatility(strikePrice, forward); break; } - case HestonExpansionFormula.LPP3: + case HestonExpansionFormula.LPP3: { LPP3HestonExpansion expansion = new LPP3HestonExpansion(model_.link.kappa(), model_.link.theta(), - model_.link.sigma(), model_.link.v0(),model_.link.rho(), term); + model_.link.sigma(), model_.link.v0(), model_.link.rho(), term); vol = expansion.impliedVolatility(strikePrice, forward); break; } - case HestonExpansionFormula.Forde: + case HestonExpansionFormula.Forde: { FordeHestonExpansion expansion = new FordeHestonExpansion(model_.link.kappa(), model_.link.theta(), - model_.link.sigma(), model_.link.v0(),model_.link.rho(), term); + model_.link.sigma(), model_.link.v0(), model_.link.rho(), term); vol = expansion.impliedVolatility(strikePrice, forward); break; } @@ -92,7 +92,7 @@ public override void calculate() Utils.QL_FAIL("unknown expansion formula"); break; } - double price = Utils.blackFormula(payoff, forward, vol*Math.Sqrt(term),riskFreeDiscount, 0); + double price = Utils.blackFormula(payoff, forward, vol * Math.Sqrt(term), riskFreeDiscount, 0); results_.value = price; } @@ -106,11 +106,11 @@ public override void calculate() strike to impliedVolatility(strike, forward) would be performed. */ - - public abstract class HestonExpansion + + public abstract class HestonExpansion { ~HestonExpansion() {} - public abstract double impliedVolatility(double strike,double forward) ; + public abstract double impliedVolatility(double strike, double forward) ; } @@ -126,94 +126,94 @@ public class LPP2HestonExpansion : HestonExpansion { public LPP2HestonExpansion(double kappa, double theta, double sigma, double v0, double rho, double term) { - ekt = Math.Exp(kappa*term); - e2kt = ekt*ekt; - e3kt = e2kt*ekt; - e4kt = e2kt*e2kt; + ekt = Math.Exp(kappa * term); + e2kt = ekt * ekt; + e3kt = e2kt * ekt; + e4kt = e2kt * e2kt; coeffs[0] = z0(term, kappa, theta, sigma, v0, rho); coeffs[1] = z1(term, kappa, theta, sigma, v0, rho); coeffs[2] = z2(term, kappa, theta, sigma, v0, rho); } public override double impliedVolatility(double strike, double forward) { - double x = Math.Log(strike/forward); - double vol = coeffs[0]+x*(coeffs[1]+(x*coeffs[2])); - return Math.Max(1e-8,vol); + double x = Math.Log(strike / forward); + double vol = coeffs[0] + x * (coeffs[1] + (x * coeffs[2])); + return Math.Max(1e-8, vol); } private double[] coeffs = new double[3]; private double ekt, e2kt, e3kt, e4kt; private double z0(double t, double kappa, double theta, double delta, double y, double rho) { - return (4*Math.Pow(delta,2)*kappa*(-theta - 4*ekt*(theta + kappa*t*(theta - y)) + - e2kt*((5 - 2*kappa*t)*theta - 2*y) + 2*y)* - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y) + - 128*ekt*Math.Pow(kappa,3)* - Math.Pow((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y,2) + - 32*delta*ekt*Math.Pow(kappa,2)*rho* - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y)* - ((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y) + - Math.Pow(delta,2)*ekt*Math.Pow(rho,2)* - (-theta + kappa*t*theta + (theta - y)/ekt + y)* - Math.Pow((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y,2) + - (48*Math.Pow(delta,2)*e2kt*Math.Pow(kappa,2)*Math.Pow(rho,2)* - Math.Pow((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y,2))/ - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y) - - Math.Pow(delta,2)*Math.Pow(rho,2)*((1 + ekt*(-1 + kappa*t))*theta + - (-1 + ekt)*y)*Math.Pow((2 + kappa*t + ekt*(-2 + kappa*t))* - theta + (-1 + ekt - kappa*t)*y,2) + - 2*Math.Pow(delta,2)*kappa*((1 + ekt*(-1 + kappa*t))*theta + - (-1 + ekt)*y)*(theta - 2*y + - e2kt*(-5*theta + 2*kappa*t*theta + 2*y + - 8*Math.Pow(rho,2)*((-3 + kappa*t)*theta + y)) + - 4*ekt*(theta + kappa*t*theta - kappa*t*y + - Math.Pow(rho,2)*((6 + kappa*t*(4 + kappa*t))*theta - (2 + kappa*t*(2 + kappa*t))*y))) - - (8*Math.Pow(delta,2)*Math.Pow(kappa,2)*((1 + ekt*(-1 + kappa*t))*theta + - (-1 + ekt)*y)*(theta - 2*y + - e2kt*(-5*theta + 2*kappa*t*theta + 2*y + - 8*Math.Pow(rho,2)*((-3 + kappa*t)*theta + y)) + - 4*ekt*(theta + kappa*t*theta - kappa*t*y + - Math.Pow(rho,2)*((6 + kappa*t*(4 + kappa*t))*theta - (2 + kappa*t*(2 + kappa*t))*y)))) - /(-theta + kappa*t*theta + (theta - y)/ekt + y))/ - (128.0*e3kt*Math.Pow(kappa,5)*Math.Pow(t,2)* - Math.Pow((-theta + kappa*t*theta + (theta - y)/ekt + y)/(kappa*t),1.5)); + return (4 * Math.Pow(delta, 2) * kappa * (-theta - 4 * ekt * (theta + kappa * t * (theta - y)) + + e2kt * ((5 - 2 * kappa * t) * theta - 2 * y) + 2 * y) * + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) + + 128 * ekt * Math.Pow(kappa, 3) * + Math.Pow((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y, 2) + + 32 * delta * ekt * Math.Pow(kappa, 2) * rho * + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) * + ((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y) + + Math.Pow(delta, 2) * ekt * Math.Pow(rho, 2) * + (-theta + kappa * t * theta + (theta - y) / ekt + y) * + Math.Pow((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y, 2) + + (48 * Math.Pow(delta, 2) * e2kt * Math.Pow(kappa, 2) * Math.Pow(rho, 2) * + Math.Pow((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y, 2)) / + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) - + Math.Pow(delta, 2) * Math.Pow(rho, 2) * ((1 + ekt * (-1 + kappa * t)) * theta + + (-1 + ekt) * y) * Math.Pow((2 + kappa * t + ekt * (-2 + kappa * t)) * + theta + (-1 + ekt - kappa * t) * y, 2) + + 2 * Math.Pow(delta, 2) * kappa * ((1 + ekt * (-1 + kappa * t)) * theta + + (-1 + ekt) * y) * (theta - 2 * y + + e2kt * (-5 * theta + 2 * kappa * t * theta + 2 * y + + 8 * Math.Pow(rho, 2) * ((-3 + kappa * t) * theta + y)) + + 4 * ekt * (theta + kappa * t * theta - kappa * t * y + + Math.Pow(rho, 2) * ((6 + kappa * t * (4 + kappa * t)) * theta - (2 + kappa * t * (2 + kappa * t)) * y))) - + (8 * Math.Pow(delta, 2) * Math.Pow(kappa, 2) * ((1 + ekt * (-1 + kappa * t)) * theta + + (-1 + ekt) * y) * (theta - 2 * y + + e2kt * (-5 * theta + 2 * kappa * t * theta + 2 * y + + 8 * Math.Pow(rho, 2) * ((-3 + kappa * t) * theta + y)) + + 4 * ekt * (theta + kappa * t * theta - kappa * t * y + + Math.Pow(rho, 2) * ((6 + kappa * t * (4 + kappa * t)) * theta - (2 + kappa * t * (2 + kappa * t)) * y)))) + / (-theta + kappa * t * theta + (theta - y) / ekt + y)) / + (128.0 * e3kt * Math.Pow(kappa, 5) * Math.Pow(t, 2) * + Math.Pow((-theta + kappa * t * theta + (theta - y) / ekt + y) / (kappa * t), 1.5)); } private double z1(double t, double kappa, double theta, double delta, double y, double rho) { - return (delta*rho*(-(delta*Math.Pow(-1 + ekt,2)*rho*(4*theta - y)*y) + - 2*ekt*Math.Pow(kappa,3)*Math.Pow(t,2)*theta* - ((2 + 2*ekt + delta*rho*t)*theta - (2 + delta*rho*t)*y) - - 2*(-1 + ekt)*kappa*(2*theta - y)* - ((-1 + ekt)*(-2 + delta*rho*t)*theta + - (-2 + 2*ekt + delta*rho*t)*y) + - Math.Pow(kappa,2)*t*((-1 + ekt)* - (-4 + delta*rho*t + ekt*(-12 + delta*rho*t))*Math.Pow(theta,2) + - 2*(-4 + 4*e2kt + delta*rho*t + 3*delta*ekt*rho*t)*theta* - y - (-4 + delta*rho*t + 2*ekt*(2 + delta*rho*t))*Math.Pow(y,2))))/ - (8.0*Math.Pow(kappa,2)*t*Math.Sqrt((-theta + kappa*t*theta + (theta - y)/ekt + y)/ - (kappa*t))*Math.Pow((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y, - 2)); + return (delta * rho * (-(delta * Math.Pow(-1 + ekt, 2) * rho * (4 * theta - y) * y) + + 2 * ekt * Math.Pow(kappa, 3) * Math.Pow(t, 2) * theta * + ((2 + 2 * ekt + delta * rho * t) * theta - (2 + delta * rho * t) * y) - + 2 * (-1 + ekt) * kappa * (2 * theta - y) * + ((-1 + ekt) * (-2 + delta * rho * t) * theta + + (-2 + 2 * ekt + delta * rho * t) * y) + + Math.Pow(kappa, 2) * t * ((-1 + ekt) * + (-4 + delta * rho * t + ekt * (-12 + delta * rho * t)) * Math.Pow(theta, 2) + + 2 * (-4 + 4 * e2kt + delta * rho * t + 3 * delta * ekt * rho * t) * theta * + y - (-4 + delta * rho * t + 2 * ekt * (2 + delta * rho * t)) * Math.Pow(y, 2)))) / + (8.0 * Math.Pow(kappa, 2) * t * Math.Sqrt((-theta + kappa * t * theta + (theta - y) / ekt + y) / + (kappa * t)) * Math.Pow((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y, + 2)); } private double z2(double t, double kappa, double theta, double delta, double y, double rho) { - return (Math.Pow(delta,2)*Math.Sqrt((-theta + kappa*t*theta + (theta - y)/ekt + y)/(kappa*t))* - (-12*Math.Pow(rho,2)*Math.Pow((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y,2) + - (-theta + kappa*t*theta + (theta - y)/ekt + y)* - (theta - 2*y + e2kt* - (-5*theta + 2*kappa*t*theta + 2*y + 8*Math.Pow(rho,2)*((-3 + kappa*t)*theta + y)) + - 4*ekt*(theta + kappa*t*theta - kappa*t*y + - Math.Pow(rho,2)*((6 + kappa*t*(4 + kappa*t))*theta - (2 + kappa*t*(2 + kappa*t))*y)))) - )/(16.0*e2kt*Math.Pow(-theta + kappa*t*theta + (theta - y)/ekt + y, - 4)); + return (Math.Pow(delta, 2) * Math.Sqrt((-theta + kappa * t * theta + (theta - y) / ekt + y) / (kappa * t)) * + (-12 * Math.Pow(rho, 2) * Math.Pow((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y, 2) + + (-theta + kappa * t * theta + (theta - y) / ekt + y) * + (theta - 2 * y + e2kt * + (-5 * theta + 2 * kappa * t * theta + 2 * y + 8 * Math.Pow(rho, 2) * ((-3 + kappa * t) * theta + y)) + + 4 * ekt * (theta + kappa * t * theta - kappa * t * y + + Math.Pow(rho, 2) * ((6 + kappa * t * (4 + kappa * t)) * theta - (2 + kappa * t * (2 + kappa * t)) * y)))) + ) / (16.0 * e2kt * Math.Pow(-theta + kappa * t * theta + (theta - y) / ekt + y, + 4)); } } - + /*! Lorig Pagliarani Pascucci expansion of order-3 for the Heston model. During calibration, it can be initialized once per expiry, and called many times with different strikes. The formula is also @@ -222,527 +222,527 @@ available in the Mathematica notebook from the authors at */ public class LPP3HestonExpansion : HestonExpansion { - public LPP3HestonExpansion(double kappa, double theta,double sigma, double v0,double rho, double term) + public LPP3HestonExpansion(double kappa, double theta, double sigma, double v0, double rho, double term) { - ekt = Math.Exp( kappa * term ); + ekt = Math.Exp(kappa * term); e2kt = ekt * ekt; e3kt = e2kt * ekt; e4kt = e2kt * e2kt; - coeffs[0] = z0( term, kappa, theta, sigma, v0, rho ); - coeffs[1] = z1( term, kappa, theta, sigma, v0, rho ); - coeffs[2] = z2( term, kappa, theta, sigma, v0, rho ); - coeffs[3] = z3( term, kappa, theta, sigma, v0, rho ); + coeffs[0] = z0(term, kappa, theta, sigma, v0, rho); + coeffs[1] = z1(term, kappa, theta, sigma, v0, rho); + coeffs[2] = z2(term, kappa, theta, sigma, v0, rho); + coeffs[3] = z3(term, kappa, theta, sigma, v0, rho); } - public override double impliedVolatility(double strike,double forward) + public override double impliedVolatility(double strike, double forward) { - double x = Math.Log(strike/forward); - double vol = coeffs[0]+x*(coeffs[1]+x*(coeffs[2]+x*(coeffs[3]))); - return Math.Max(1e-8,vol); + double x = Math.Log(strike / forward); + double vol = coeffs[0] + x * (coeffs[1] + x * (coeffs[2] + x * (coeffs[3]))); + return Math.Max(1e-8, vol); } - + private double[] coeffs = new double[4]; private double ekt, e2kt, e3kt, e4kt; - private double z0(double t, double kappa, double theta,double delta, double y, double rho) + private double z0(double t, double kappa, double theta, double delta, double y, double rho) { - return (96*Math.Pow(delta, 2)*ekt*Math.Pow(kappa, 3)* - (-theta - 4*ekt*(theta + kappa*t*(theta - y)) + - e2kt*((5 - 2*kappa*t)*theta - 2*y) + 2*y)* - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y) + - 3072*e2kt*Math.Pow(kappa, 5)* - Math.Pow((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y, 2) + - 96*Math.Pow(delta, 3)*ekt*Math.Pow(kappa, 2)*rho* - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y)* - (-2*theta - kappa*t*theta - 2*ekt*(2 + kappa*t)* - (2*theta + kappa*t*(theta - y)) + e2kt*((10 - 3*kappa*t)*theta - 3*y) + - 3*y + 2*kappa*t*y) + 768*delta*e2kt*Math.Pow(kappa, 4)*rho* - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y)* - ((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y) + - 6*Math.Pow(delta, 3)*kappa*rho*(-theta - 4*ekt*(theta + kappa*t*(theta - y)) + - e2kt*((5 - 2*kappa*t)*theta - 2*y) + 2*y)* - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y)* - ((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y) + - 24*Math.Pow(delta, 2)*e2kt*Math.Pow(kappa, 2)*Math.Pow(rho, 2)* - (-theta + kappa*t*theta + (theta - y)/ekt + y)* - Math.Pow((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y, 2) + - (1152*Math.Pow(delta, 2)*e3kt*Math.Pow(kappa, 4)*Math.Pow(rho, 2)* - Math.Pow((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y, 2))/ - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y) - - 24*Math.Pow(delta, 2)*ekt*Math.Pow(kappa, 2)*Math.Pow(rho, 2)* - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y)* - Math.Pow((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y, 2) + - 80*Math.Pow(delta, 3)*ekt*kappa*Math.Pow(rho, 3)* - Math.Pow((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y, 3) + - Math.Pow(delta, 3)*ekt*Math.Pow(rho, 3)* - (-theta + kappa*t*theta + (theta - y)/ekt + y)* - Math.Pow((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y, 3) - - (1440*Math.Pow(delta, 3)*e3kt*Math.Pow(kappa, 3)*Math.Pow(rho, 3)* - Math.Pow((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y, 3))/ - Math.Pow((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y, 2) - - (528*Math.Pow(delta, 3)*e2kt*Math.Pow(kappa, 2)*Math.Pow(rho, 3)* - Math.Pow((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y, 3))/ - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y) - - 3*Math.Pow(delta, 3)*Math.Pow(rho, 3)*((1 + ekt*(-1 + kappa*t))*theta + - (-1 + ekt)*y)*Math.Pow((2 + kappa*t + ekt*(-2 + kappa*t))* - theta + (-1 + ekt - kappa*t)*y, 3) + - 384*Math.Pow(delta, 3)*e2kt*Math.Pow(kappa, 3)*rho* - ((2 + kappa*t + 2*ekt*Math.Pow(2 + kappa*t, 2) + - e2kt*(-10 + 3*kappa*t))*theta + - (-3 + 3*e2kt - 2*kappa*t - 2*ekt*kappa*t*(2 + kappa*t))*y) - - (576*Math.Pow(delta, 3)*e2kt*Math.Pow(kappa, 3)*rho* - ((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y)* - ((1 + e2kt*(-5 + 2*kappa*t + 4*Math.Pow(rho, 2)*(-3 + kappa*t)) + - 2*ekt*(2 + 2*kappa*t + - Math.Pow(rho, 2)*(6 + 4*kappa*t + Math.Pow(kappa, 2)*Math.Pow(t, 2))))*theta + - 2*(-1 + e2kt*(1 + 2*Math.Pow(rho, 2)) - - ekt*(2*kappa*t + - Math.Pow(rho, 2)*(2 + 2*kappa*t + Math.Pow(kappa, 2)*Math.Pow(t, 2))))*y))/ - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y) + - Math.Pow(delta, 3)*rho*((1 + ekt*(-1 + kappa*t))*theta + - (-1 + ekt)*y)*((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y)* - (theta*(12*ekt*Math.Pow(kappa, 3)*Math.Pow(rho, 2)*Math.Pow(t, 2) + - 8*Math.Pow(-1 + ekt, 2)*Math.Pow(rho, 2)*theta - - (-1 + ekt)*kappa* - (3 + 8*Math.Pow(rho, 2)*t*theta + ekt*(15 + 8*Math.Pow(rho, 2)*(9 + t*theta))) - + 2*Math.Pow(kappa, 2)*t*(Math.Pow(rho, 2)*t*theta + - 2*ekt*(3 + Math.Pow(rho, 2)*(12 + t*theta)) + - e2kt*(3 + Math.Pow(rho, 2)*(12 + t*theta)))) - - 2*(6*ekt*Math.Pow(kappa, 3)*Math.Pow(rho, 2)*Math.Pow(t, 2) + - 4*Math.Pow(-1 + ekt, 2)*Math.Pow(rho, 2)*theta + - 2*Math.Pow(kappa, 2)*t*(Math.Pow(rho, 2)*t*theta + - ekt*(3 + Math.Pow(rho, 2)*(6 + t*theta))) - - (-1 + ekt)*kappa* - (3 + 6*Math.Pow(rho, 2)*t*theta + ekt*(3 + 2*Math.Pow(rho, 2)*(6 + t*theta))))* - y + 2*Math.Pow(rho, 2)*Math.Pow(1 - ekt + kappa*t, 2)*Math.Pow(y, 2)) - - (40*Math.Pow(delta, 3)*kappa*rho*((1 + ekt*(-1 + kappa*t))*theta + - (-1 + ekt)*y)*((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y)* - (theta*(12*ekt*Math.Pow(kappa, 3)*Math.Pow(rho, 2)*Math.Pow(t, 2) + - 8*Math.Pow(-1 + ekt, 2)*Math.Pow(rho, 2)*theta - - (-1 + ekt)*kappa* - (3 + 8*Math.Pow(rho, 2)*t*theta + - ekt*(15 + 8*Math.Pow(rho, 2)*(9 + t*theta))) + - 2*Math.Pow(kappa, 2)*t*(Math.Pow(rho, 2)*t*theta + - 2*ekt*(3 + Math.Pow(rho, 2)*(12 + t*theta)) + - e2kt*(3 + Math.Pow(rho, 2)*(12 + t*theta)))) - - 2*(6*ekt*Math.Pow(kappa, 3)*Math.Pow(rho, 2)*Math.Pow(t, 2) + - 4*Math.Pow(-1 + ekt, 2)*Math.Pow(rho, 2)*theta + - 2*Math.Pow(kappa, 2)*t*(Math.Pow(rho, 2)*t*theta + - ekt*(3 + Math.Pow(rho, 2)*(6 + t*theta))) - - (-1 + ekt)*kappa* - (3 + 6*Math.Pow(rho, 2)*t*theta + ekt*(3 + 2*Math.Pow(rho, 2)*(6 + t*theta))) - )*y + 2*Math.Pow(rho, 2)*Math.Pow(1 - ekt + kappa*t, 2)*Math.Pow(y, 2)))/ - (-theta + kappa*t*theta + (theta - y)/ekt + y) - - 12*Math.Pow(delta, 3)*kappa*rho*((1 + ekt*(-1 + kappa*t))*theta + - (-1 + ekt)*y)*(2*theta + kappa*t*theta - y - kappa*t*y + - ekt*((-2 + kappa*t)*theta + y))* - (theta - 2*y + e2kt* - (-5*theta + 2*kappa*t*theta + 2*y + 4*Math.Pow(rho, 2)*((-3 + kappa*t)*theta + y)) + - 2*ekt*(2*(theta + kappa*t*(theta - y)) + - Math.Pow(rho, 2)*((6 + kappa*t*(4 + kappa*t))*theta - (2 + kappa*t*(2 + kappa*t))*y))) + - (288*Math.Pow(delta, 3)*Math.Pow(kappa, 2)*rho* - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y)* - (2*theta + kappa*t*theta - y - kappa*t*y + ekt*((-2 + kappa*t)*theta + y))* - (theta - 2*y + e2kt* - (-5*theta + 2*kappa*t*theta + 2*y + 4*Math.Pow(rho, 2)*((-3 + kappa*t)*theta + y)) + - 2*ekt*(2*(theta + kappa*t*(theta - y)) + - Math.Pow(rho, 2)*((6 + kappa*t*(4 + kappa*t))*theta - (2 + kappa*t*(2 + kappa*t))*y)))) - /(-theta + kappa*t*theta + (theta - y)/ekt + y) + - 48*Math.Pow(delta, 2)*ekt*Math.Pow(kappa, 3)* - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y)* - (theta - 2*y + e2kt* - (-5*theta + 2*kappa*t*theta + 2*y + 8*Math.Pow(rho, 2)*((-3 + kappa*t)*theta + y)) + - 4*ekt*(theta + kappa*t*theta - kappa*t*y + - Math.Pow(rho, 2)*((6 + kappa*t*(4 + kappa*t))*theta - (2 + kappa*t*(2 + kappa*t))*y))) - - (192*Math.Pow(delta, 2)*ekt*Math.Pow(kappa, 4)* - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y)* - (theta - 2*y + e2kt* - (-5*theta + 2*kappa*t*theta + 2*y + 8*Math.Pow(rho, 2)*((-3 + kappa*t)*theta + y)) + - 4*ekt*(theta + kappa*t*theta - kappa*t*y + - Math.Pow(rho, 2)*((6 + kappa*t*(4 + kappa*t))*theta - (2 + kappa*t*(2 + kappa*t))*y)))) - /(-theta + kappa*t*theta + (theta - y)/ekt + y) + - 3*Math.Pow(delta, 3)*kappa*rho*((1 + ekt*(-1 + kappa*t))*theta + - (-1 + ekt)*y)*((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y)* - (theta - 2*y + e2kt* - (-5*theta + 2*kappa*t*theta + 2*y + 8*Math.Pow(rho, 2)*((-3 + kappa*t)*theta + y)) + - 4*ekt*(theta + kappa*t*theta - kappa*t*y + - Math.Pow(rho, 2)*((6 + kappa*t*(4 + kappa*t))*theta - (2 + kappa*t*(2 + kappa*t))*y))) - - (12*Math.Pow(delta, 3)*Math.Pow(kappa, 2)*rho* - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y)* - ((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y)* - (theta - 2*y + e2kt* - (-5*theta + 2*kappa*t*theta + 2*y + 8*Math.Pow(rho, 2)*((-3 + kappa*t)*theta + y)) + - 4*ekt*(theta + kappa*t*theta - kappa*t*y + - Math.Pow(rho, 2)*((6 + kappa*t*(4 + kappa*t))*theta - (2 + kappa*t*(2 + kappa*t))*y)))) - /(-theta + kappa*t*theta + (theta - y)/ekt + y) + - 4*Math.Pow(delta, 3)*kappa*rho*((1 + ekt*(-1 + kappa*t))*theta + - (-1 + ekt)*y)*(3*(theta - 2*y)*((2 + kappa*t)*theta - (1 + kappa*t)*y) + - 3*ekt*(6*Math.Pow(theta, 2) + theta*y - 2*Math.Pow(y, 2) + - kappa* - (13*t*Math.Pow(theta, 2) + theta*(8 - 18*t*y) + - 4*y*(-3 + t*y)) + - 4*Math.Pow(kappa, 2)*t* - (theta + t*Math.Pow(theta, 2) - 2*t*theta*y + y*(-2 + t*y))) + - 3*e3kt*(10*Math.Pow(theta, 2) + - 2*Math.Pow(kappa, 2)*t*theta*(6 + 8*Math.Pow(rho, 2) + t*theta) - - 9*theta*y + 2*Math.Pow(y, 2) + - kappa*(-9*t*Math.Pow(theta, 2) + 4*(3 + 4*Math.Pow(rho, 2))*y + - theta*(-40 - 64*Math.Pow(rho, 2) + 4*t*y))) + - e2kt*(-54*Math.Pow(theta, 2) + - 8*Math.Pow(kappa, 4)*Math.Pow(rho, 2)*Math.Pow(t, 3)*(theta - y) + - 39*theta*y - 6*Math.Pow(y, 2) + - 24*Math.Pow(kappa, 3)*Math.Pow(t, 2)* - (theta + 2*Math.Pow(rho, 2)*theta - (1 + Math.Pow(rho, 2))*y) + - 6*Math.Pow(kappa, 2)*t* - (3*t*Math.Pow(theta, 2) - 8*(1 + Math.Pow(rho, 2))*y + - theta*(16 + 24*Math.Pow(rho, 2) - 3*t*y)) - - 3*kappa* - (5*t*Math.Pow(theta, 2) + 2*y*(8*Math.Pow(rho, 2) + 3*t*y) - - theta*(32 + 64*Math.Pow(rho, 2) + 17*t*y)))) - - (48*Math.Pow(delta, 3)*Math.Pow(kappa, 2)*rho* - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y)* - (3*(theta - 2*y)*((2 + kappa*t)*theta - (1 + kappa*t)*y) + - 3*ekt*(6*Math.Pow(theta, 2) + theta*y - 2*Math.Pow(y, 2) + - kappa*(13*t*Math.Pow(theta, 2) + theta*(8 - 18*t*y) + 4*y*(-3 + t*y)) + - 4*Math.Pow(kappa, 2)*t*(theta + t*Math.Pow(theta, 2) - 2*t*theta*y + y*(-2 + t*y))) + - 3*e3kt*(10*Math.Pow(theta, 2) + - 2*Math.Pow(kappa, 2)*t*theta*(6 + 8*Math.Pow(rho, 2) + t*theta) - 9*theta*y + - 2*Math.Pow(y, 2) + kappa*(-9*t*Math.Pow(theta, 2) + 4*(3 + 4*Math.Pow(rho, 2))*y + - theta*(-40 - 64*Math.Pow(rho, 2) + 4*t*y))) + - e2kt*(-54*Math.Pow(theta, 2) + - 8*Math.Pow(kappa, 4)*Math.Pow(rho, 2)*Math.Pow(t, 3)*(theta - y) + 39*theta*y - 6*Math.Pow(y, 2) + - 24*Math.Pow(kappa, 3)*Math.Pow(t, 2)* - (theta + 2*Math.Pow(rho, 2)*theta - (1 + Math.Pow(rho, 2))*y) + - 6*Math.Pow(kappa, 2)*t*(3*t*Math.Pow(theta, 2) - 8*(1 + Math.Pow(rho, 2))*y + - theta*(16 + 24*Math.Pow(rho, 2) - 3*t*y)) - - 3*kappa*(5*t*Math.Pow(theta, 2) + 2*y*(8*Math.Pow(rho, 2) + 3*t*y) - - theta*(32 + 64*Math.Pow(rho, 2) + 17*t*y)))))/ - (-theta + kappa*t*theta + (theta - y)/ekt + y) + - (240*Math.Pow(delta, 3)*e2kt*Math.Pow(kappa, 2)*rho* - ((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y)* - (12*ekt*Math.Pow(kappa, 3)*Math.Pow(rho, 2)*Math.Pow(t, 2)*(theta - y) + - 2*Math.Pow(-1 + ekt, 2)*Math.Pow(rho, 2)*Math.Pow(-2*theta + y, 2) - - (-1 + ekt)*kappa* - (8*(1 + ekt)*Math.Pow(rho, 2)*t*Math.Pow(theta, 2) + - 2*y*(-3 - 3*ekt*(1 + 4*Math.Pow(rho, 2)) + 2*Math.Pow(rho, 2)*t*y) + - theta*(3 - 12*Math.Pow(rho, 2)*t*y + ekt*(15 + Math.Pow(rho, 2)*(72 - 4*t*y))) - ) + 2*Math.Pow(kappa, 2)*t*(e2kt*theta* - (3 + Math.Pow(rho, 2)*(12 + t*theta)) + Math.Pow(rho, 2)*t*Math.Pow(theta - y, 2) + - 2*ekt*(Math.Pow(rho, 2)*t*Math.Pow(theta, 2) - 3*(y + 2*Math.Pow(rho, 2)*y) + - theta*(3 + Math.Pow(rho, 2)*(12 - t*y))))))/ - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y))/ - (3072.0*e4kt*Math.Pow(kappa, 7)*Math.Pow(t, 2)* - Math.Pow((-theta + kappa*t*theta + (theta - y)/ekt + y)/(kappa*t), 1.5)); + return (96 * Math.Pow(delta, 2) * ekt * Math.Pow(kappa, 3) * + (-theta - 4 * ekt * (theta + kappa * t * (theta - y)) + + e2kt * ((5 - 2 * kappa * t) * theta - 2 * y) + 2 * y) * + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) + + 3072 * e2kt * Math.Pow(kappa, 5) * + Math.Pow((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y, 2) + + 96 * Math.Pow(delta, 3) * ekt * Math.Pow(kappa, 2) * rho * + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) * + (-2 * theta - kappa * t * theta - 2 * ekt * (2 + kappa * t) * + (2 * theta + kappa * t * (theta - y)) + e2kt * ((10 - 3 * kappa * t) * theta - 3 * y) + + 3 * y + 2 * kappa * t * y) + 768 * delta * e2kt * Math.Pow(kappa, 4) * rho * + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) * + ((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y) + + 6 * Math.Pow(delta, 3) * kappa * rho * (-theta - 4 * ekt * (theta + kappa * t * (theta - y)) + + e2kt * ((5 - 2 * kappa * t) * theta - 2 * y) + 2 * y) * + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) * + ((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y) + + 24 * Math.Pow(delta, 2) * e2kt * Math.Pow(kappa, 2) * Math.Pow(rho, 2) * + (-theta + kappa * t * theta + (theta - y) / ekt + y) * + Math.Pow((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y, 2) + + (1152 * Math.Pow(delta, 2) * e3kt * Math.Pow(kappa, 4) * Math.Pow(rho, 2) * + Math.Pow((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y, 2)) / + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) - + 24 * Math.Pow(delta, 2) * ekt * Math.Pow(kappa, 2) * Math.Pow(rho, 2) * + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) * + Math.Pow((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y, 2) + + 80 * Math.Pow(delta, 3) * ekt * kappa * Math.Pow(rho, 3) * + Math.Pow((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y, 3) + + Math.Pow(delta, 3) * ekt * Math.Pow(rho, 3) * + (-theta + kappa * t * theta + (theta - y) / ekt + y) * + Math.Pow((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y, 3) - + (1440 * Math.Pow(delta, 3) * e3kt * Math.Pow(kappa, 3) * Math.Pow(rho, 3) * + Math.Pow((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y, 3)) / + Math.Pow((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y, 2) - + (528 * Math.Pow(delta, 3) * e2kt * Math.Pow(kappa, 2) * Math.Pow(rho, 3) * + Math.Pow((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y, 3)) / + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) - + 3 * Math.Pow(delta, 3) * Math.Pow(rho, 3) * ((1 + ekt * (-1 + kappa * t)) * theta + + (-1 + ekt) * y) * Math.Pow((2 + kappa * t + ekt * (-2 + kappa * t)) * + theta + (-1 + ekt - kappa * t) * y, 3) + + 384 * Math.Pow(delta, 3) * e2kt * Math.Pow(kappa, 3) * rho * + ((2 + kappa * t + 2 * ekt * Math.Pow(2 + kappa * t, 2) + + e2kt * (-10 + 3 * kappa * t)) * theta + + (-3 + 3 * e2kt - 2 * kappa * t - 2 * ekt * kappa * t * (2 + kappa * t)) * y) - + (576 * Math.Pow(delta, 3) * e2kt * Math.Pow(kappa, 3) * rho * + ((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y) * + ((1 + e2kt * (-5 + 2 * kappa * t + 4 * Math.Pow(rho, 2) * (-3 + kappa * t)) + + 2 * ekt * (2 + 2 * kappa * t + + Math.Pow(rho, 2) * (6 + 4 * kappa * t + Math.Pow(kappa, 2) * Math.Pow(t, 2)))) * theta + + 2 * (-1 + e2kt * (1 + 2 * Math.Pow(rho, 2)) - + ekt * (2 * kappa * t + + Math.Pow(rho, 2) * (2 + 2 * kappa * t + Math.Pow(kappa, 2) * Math.Pow(t, 2)))) * y)) / + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) + + Math.Pow(delta, 3) * rho * ((1 + ekt * (-1 + kappa * t)) * theta + + (-1 + ekt) * y) * ((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y) * + (theta * (12 * ekt * Math.Pow(kappa, 3) * Math.Pow(rho, 2) * Math.Pow(t, 2) + + 8 * Math.Pow(-1 + ekt, 2) * Math.Pow(rho, 2) * theta - + (-1 + ekt) * kappa * + (3 + 8 * Math.Pow(rho, 2) * t * theta + ekt * (15 + 8 * Math.Pow(rho, 2) * (9 + t * theta))) + + 2 * Math.Pow(kappa, 2) * t * (Math.Pow(rho, 2) * t * theta + + 2 * ekt * (3 + Math.Pow(rho, 2) * (12 + t * theta)) + + e2kt * (3 + Math.Pow(rho, 2) * (12 + t * theta)))) - + 2 * (6 * ekt * Math.Pow(kappa, 3) * Math.Pow(rho, 2) * Math.Pow(t, 2) + + 4 * Math.Pow(-1 + ekt, 2) * Math.Pow(rho, 2) * theta + + 2 * Math.Pow(kappa, 2) * t * (Math.Pow(rho, 2) * t * theta + + ekt * (3 + Math.Pow(rho, 2) * (6 + t * theta))) - + (-1 + ekt) * kappa * + (3 + 6 * Math.Pow(rho, 2) * t * theta + ekt * (3 + 2 * Math.Pow(rho, 2) * (6 + t * theta)))) * + y + 2 * Math.Pow(rho, 2) * Math.Pow(1 - ekt + kappa * t, 2) * Math.Pow(y, 2)) - + (40 * Math.Pow(delta, 3) * kappa * rho * ((1 + ekt * (-1 + kappa * t)) * theta + + (-1 + ekt) * y) * ((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y) * + (theta * (12 * ekt * Math.Pow(kappa, 3) * Math.Pow(rho, 2) * Math.Pow(t, 2) + + 8 * Math.Pow(-1 + ekt, 2) * Math.Pow(rho, 2) * theta - + (-1 + ekt) * kappa * + (3 + 8 * Math.Pow(rho, 2) * t * theta + + ekt * (15 + 8 * Math.Pow(rho, 2) * (9 + t * theta))) + + 2 * Math.Pow(kappa, 2) * t * (Math.Pow(rho, 2) * t * theta + + 2 * ekt * (3 + Math.Pow(rho, 2) * (12 + t * theta)) + + e2kt * (3 + Math.Pow(rho, 2) * (12 + t * theta)))) - + 2 * (6 * ekt * Math.Pow(kappa, 3) * Math.Pow(rho, 2) * Math.Pow(t, 2) + + 4 * Math.Pow(-1 + ekt, 2) * Math.Pow(rho, 2) * theta + + 2 * Math.Pow(kappa, 2) * t * (Math.Pow(rho, 2) * t * theta + + ekt * (3 + Math.Pow(rho, 2) * (6 + t * theta))) - + (-1 + ekt) * kappa * + (3 + 6 * Math.Pow(rho, 2) * t * theta + ekt * (3 + 2 * Math.Pow(rho, 2) * (6 + t * theta))) + ) * y + 2 * Math.Pow(rho, 2) * Math.Pow(1 - ekt + kappa * t, 2) * Math.Pow(y, 2))) / + (-theta + kappa * t * theta + (theta - y) / ekt + y) - + 12 * Math.Pow(delta, 3) * kappa * rho * ((1 + ekt * (-1 + kappa * t)) * theta + + (-1 + ekt) * y) * (2 * theta + kappa * t * theta - y - kappa * t * y + + ekt * ((-2 + kappa * t) * theta + y)) * + (theta - 2 * y + e2kt * + (-5 * theta + 2 * kappa * t * theta + 2 * y + 4 * Math.Pow(rho, 2) * ((-3 + kappa * t) * theta + y)) + + 2 * ekt * (2 * (theta + kappa * t * (theta - y)) + + Math.Pow(rho, 2) * ((6 + kappa * t * (4 + kappa * t)) * theta - (2 + kappa * t * (2 + kappa * t)) * y))) + + (288 * Math.Pow(delta, 3) * Math.Pow(kappa, 2) * rho * + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) * + (2 * theta + kappa * t * theta - y - kappa * t * y + ekt * ((-2 + kappa * t) * theta + y)) * + (theta - 2 * y + e2kt * + (-5 * theta + 2 * kappa * t * theta + 2 * y + 4 * Math.Pow(rho, 2) * ((-3 + kappa * t) * theta + y)) + + 2 * ekt * (2 * (theta + kappa * t * (theta - y)) + + Math.Pow(rho, 2) * ((6 + kappa * t * (4 + kappa * t)) * theta - (2 + kappa * t * (2 + kappa * t)) * y)))) + / (-theta + kappa * t * theta + (theta - y) / ekt + y) + + 48 * Math.Pow(delta, 2) * ekt * Math.Pow(kappa, 3) * + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) * + (theta - 2 * y + e2kt * + (-5 * theta + 2 * kappa * t * theta + 2 * y + 8 * Math.Pow(rho, 2) * ((-3 + kappa * t) * theta + y)) + + 4 * ekt * (theta + kappa * t * theta - kappa * t * y + + Math.Pow(rho, 2) * ((6 + kappa * t * (4 + kappa * t)) * theta - (2 + kappa * t * (2 + kappa * t)) * y))) - + (192 * Math.Pow(delta, 2) * ekt * Math.Pow(kappa, 4) * + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) * + (theta - 2 * y + e2kt * + (-5 * theta + 2 * kappa * t * theta + 2 * y + 8 * Math.Pow(rho, 2) * ((-3 + kappa * t) * theta + y)) + + 4 * ekt * (theta + kappa * t * theta - kappa * t * y + + Math.Pow(rho, 2) * ((6 + kappa * t * (4 + kappa * t)) * theta - (2 + kappa * t * (2 + kappa * t)) * y)))) + / (-theta + kappa * t * theta + (theta - y) / ekt + y) + + 3 * Math.Pow(delta, 3) * kappa * rho * ((1 + ekt * (-1 + kappa * t)) * theta + + (-1 + ekt) * y) * ((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y) * + (theta - 2 * y + e2kt * + (-5 * theta + 2 * kappa * t * theta + 2 * y + 8 * Math.Pow(rho, 2) * ((-3 + kappa * t) * theta + y)) + + 4 * ekt * (theta + kappa * t * theta - kappa * t * y + + Math.Pow(rho, 2) * ((6 + kappa * t * (4 + kappa * t)) * theta - (2 + kappa * t * (2 + kappa * t)) * y))) - + (12 * Math.Pow(delta, 3) * Math.Pow(kappa, 2) * rho * + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) * + ((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y) * + (theta - 2 * y + e2kt * + (-5 * theta + 2 * kappa * t * theta + 2 * y + 8 * Math.Pow(rho, 2) * ((-3 + kappa * t) * theta + y)) + + 4 * ekt * (theta + kappa * t * theta - kappa * t * y + + Math.Pow(rho, 2) * ((6 + kappa * t * (4 + kappa * t)) * theta - (2 + kappa * t * (2 + kappa * t)) * y)))) + / (-theta + kappa * t * theta + (theta - y) / ekt + y) + + 4 * Math.Pow(delta, 3) * kappa * rho * ((1 + ekt * (-1 + kappa * t)) * theta + + (-1 + ekt) * y) * (3 * (theta - 2 * y) * ((2 + kappa * t) * theta - (1 + kappa * t) * y) + + 3 * ekt * (6 * Math.Pow(theta, 2) + theta * y - 2 * Math.Pow(y, 2) + + kappa * + (13 * t * Math.Pow(theta, 2) + theta * (8 - 18 * t * y) + + 4 * y * (-3 + t * y)) + + 4 * Math.Pow(kappa, 2) * t * + (theta + t * Math.Pow(theta, 2) - 2 * t * theta * y + y * (-2 + t * y))) + + 3 * e3kt * (10 * Math.Pow(theta, 2) + + 2 * Math.Pow(kappa, 2) * t * theta * (6 + 8 * Math.Pow(rho, 2) + t * theta) - + 9 * theta * y + 2 * Math.Pow(y, 2) + + kappa * (-9 * t * Math.Pow(theta, 2) + 4 * (3 + 4 * Math.Pow(rho, 2)) * y + + theta * (-40 - 64 * Math.Pow(rho, 2) + 4 * t * y))) + + e2kt * (-54 * Math.Pow(theta, 2) + + 8 * Math.Pow(kappa, 4) * Math.Pow(rho, 2) * Math.Pow(t, 3) * (theta - y) + + 39 * theta * y - 6 * Math.Pow(y, 2) + + 24 * Math.Pow(kappa, 3) * Math.Pow(t, 2) * + (theta + 2 * Math.Pow(rho, 2) * theta - (1 + Math.Pow(rho, 2)) * y) + + 6 * Math.Pow(kappa, 2) * t * + (3 * t * Math.Pow(theta, 2) - 8 * (1 + Math.Pow(rho, 2)) * y + + theta * (16 + 24 * Math.Pow(rho, 2) - 3 * t * y)) - + 3 * kappa * + (5 * t * Math.Pow(theta, 2) + 2 * y * (8 * Math.Pow(rho, 2) + 3 * t * y) - + theta * (32 + 64 * Math.Pow(rho, 2) + 17 * t * y)))) - + (48 * Math.Pow(delta, 3) * Math.Pow(kappa, 2) * rho * + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) * + (3 * (theta - 2 * y) * ((2 + kappa * t) * theta - (1 + kappa * t) * y) + + 3 * ekt * (6 * Math.Pow(theta, 2) + theta * y - 2 * Math.Pow(y, 2) + + kappa * (13 * t * Math.Pow(theta, 2) + theta * (8 - 18 * t * y) + 4 * y * (-3 + t * y)) + + 4 * Math.Pow(kappa, 2) * t * (theta + t * Math.Pow(theta, 2) - 2 * t * theta * y + y * (-2 + t * y))) + + 3 * e3kt * (10 * Math.Pow(theta, 2) + + 2 * Math.Pow(kappa, 2) * t * theta * (6 + 8 * Math.Pow(rho, 2) + t * theta) - 9 * theta * y + + 2 * Math.Pow(y, 2) + kappa * (-9 * t * Math.Pow(theta, 2) + 4 * (3 + 4 * Math.Pow(rho, 2)) * y + + theta * (-40 - 64 * Math.Pow(rho, 2) + 4 * t * y))) + + e2kt * (-54 * Math.Pow(theta, 2) + + 8 * Math.Pow(kappa, 4) * Math.Pow(rho, 2) * Math.Pow(t, 3) * (theta - y) + 39 * theta * y - 6 * Math.Pow(y, 2) + + 24 * Math.Pow(kappa, 3) * Math.Pow(t, 2) * + (theta + 2 * Math.Pow(rho, 2) * theta - (1 + Math.Pow(rho, 2)) * y) + + 6 * Math.Pow(kappa, 2) * t * (3 * t * Math.Pow(theta, 2) - 8 * (1 + Math.Pow(rho, 2)) * y + + theta * (16 + 24 * Math.Pow(rho, 2) - 3 * t * y)) - + 3 * kappa * (5 * t * Math.Pow(theta, 2) + 2 * y * (8 * Math.Pow(rho, 2) + 3 * t * y) - + theta * (32 + 64 * Math.Pow(rho, 2) + 17 * t * y))))) / + (-theta + kappa * t * theta + (theta - y) / ekt + y) + + (240 * Math.Pow(delta, 3) * e2kt * Math.Pow(kappa, 2) * rho * + ((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y) * + (12 * ekt * Math.Pow(kappa, 3) * Math.Pow(rho, 2) * Math.Pow(t, 2) * (theta - y) + + 2 * Math.Pow(-1 + ekt, 2) * Math.Pow(rho, 2) * Math.Pow(-2 * theta + y, 2) - + (-1 + ekt) * kappa * + (8 * (1 + ekt) * Math.Pow(rho, 2) * t * Math.Pow(theta, 2) + + 2 * y * (-3 - 3 * ekt * (1 + 4 * Math.Pow(rho, 2)) + 2 * Math.Pow(rho, 2) * t * y) + + theta * (3 - 12 * Math.Pow(rho, 2) * t * y + ekt * (15 + Math.Pow(rho, 2) * (72 - 4 * t * y))) + ) + 2 * Math.Pow(kappa, 2) * t * (e2kt * theta * + (3 + Math.Pow(rho, 2) * (12 + t * theta)) + Math.Pow(rho, 2) * t * Math.Pow(theta - y, 2) + + 2 * ekt * (Math.Pow(rho, 2) * t * Math.Pow(theta, 2) - 3 * (y + 2 * Math.Pow(rho, 2) * y) + + theta * (3 + Math.Pow(rho, 2) * (12 - t * y)))))) / + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y)) / + (3072.0 * e4kt * Math.Pow(kappa, 7) * Math.Pow(t, 2) * + Math.Pow((-theta + kappa * t * theta + (theta - y) / ekt + y) / (kappa * t), 1.5)); } - private double z1(double t, double kappa, double theta,double delta, double y, double rho) + private double z1(double t, double kappa, double theta, double delta, double y, double rho) { - return (delta*(768*e2kt*Math.Pow(kappa, 4)*rho* - ((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y) - - (576*delta*e2kt*Math.Pow(kappa, 3)*Math.Pow(rho, 2)* - Math.Pow((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y, 2))/ - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y) - - 10*Math.Pow(delta, 2)*Math.Pow(rho, 3)*Math.Pow((2 + kappa*t + ekt*(-2 + kappa*t))* - theta + (-1 + ekt - kappa*t)*y, 3) + - (6*Math.Pow(delta, 2)*kappa*Math.Pow(rho, 3)* - Math.Pow((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y, 3))/ - (-theta + kappa*t*theta + (theta - y)/ekt + y) - - (3360*Math.Pow(delta, 2)*e3kt*Math.Pow(kappa, 3)*Math.Pow(rho, 3)* - Math.Pow((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y, 3))/ - Math.Pow((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y, 3) - - (288*Math.Pow(delta, 2)*e2kt*Math.Pow(kappa, 2)*Math.Pow(rho, 3)* - Math.Pow((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y, 3))/ - Math.Pow((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y, 2) + - (234*Math.Pow(delta, 2)*ekt*kappa*Math.Pow(rho, 3)* - Math.Pow((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y, 3))/ - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y) - - 96*delta*ekt*Math.Pow(kappa, 3)* - ((1 + 4*ekt*(1 + kappa*t) + e2kt*(-5 + 2*kappa*t))*theta + - 2*(-1 + e2kt - 2*ekt*kappa*t)*y) - - 12*Math.Pow(delta, 2)*kappa*rho*((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y)* - ((1 + 4*ekt*(1 + kappa*t) + e2kt*(-5 + 2*kappa*t))*theta + - 2*(-1 + e2kt - 2*ekt*kappa*t)*y) - - 192*Math.Pow(delta, 2)*ekt*Math.Pow(kappa, 2)*rho* - ((2 + kappa*t + 2*ekt*Math.Pow(2 + kappa*t, 2) + - e2kt*(-10 + 3*kappa*t))*theta + - (-3 + 3*e2kt - 2*kappa*t - 2*ekt*kappa*t*(2 + kappa*t))*y) - - (12*Math.Pow(delta, 2)*ekt*Math.Pow(kappa, 2)*rho* - ((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y)* - ((1 + e2kt*(-5 + 2*kappa*t + 8*Math.Pow(rho, 2)*(-3 + kappa*t)) + - 4*ekt*(1 + kappa*t + - Math.Pow(rho, 2)*(6 + 4*kappa*t + Math.Pow(kappa, 2)*Math.Pow(t, 2))))*theta + - 2*(-1 + e2kt*(1 + 4*Math.Pow(rho, 2)) - - 2*ekt*(kappa*t + - Math.Pow(rho, 2)*(2 + 2*kappa*t + Math.Pow(kappa, 2)*Math.Pow(t, 2))))*y))/ - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y) + - (576*Math.Pow(delta, 2)*ekt*Math.Pow(kappa, 2)*rho* - ((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y)* - ((1 + e2kt*(-5 + 2*kappa*t + 4*Math.Pow(rho, 2)*(-3 + kappa*t)) + - 2*ekt*(2 + 2*kappa*t + - Math.Pow(rho, 2)*(6 + 4*kappa*t + Math.Pow(kappa, 2)*Math.Pow(t, 2))))*theta + - 2*(-1 + e2kt*(1 + 2*Math.Pow(rho, 2)) - - ekt*(2*kappa*t + - Math.Pow(rho, 2)*(2 + 2*kappa*t + Math.Pow(kappa, 2)*Math.Pow(t, 2))))*y))/ - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y) + - (5*Math.Pow(delta, 2)*rho*((1 + ekt*(-1 + kappa*t))*theta + - (-1 + ekt)*y)* - ((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y)* - (theta*(12*ekt*Math.Pow(kappa, 3)*Math.Pow(rho, 2)*Math.Pow(t, 2) + - 8*Math.Pow(-1 + ekt, 2)*Math.Pow(rho, 2)*theta - - (-1 + ekt)*kappa* - (3 + 8*Math.Pow(rho, 2)*t*theta + - ekt*(15 + 8*Math.Pow(rho, 2)*(9 + t*theta))) + - 2*Math.Pow(kappa, 2)*t*(Math.Pow(rho, 2)*t*theta + - 2*ekt*(3 + Math.Pow(rho, 2)*(12 + t*theta)) + - e2kt*(3 + Math.Pow(rho, 2)*(12 + t*theta)))) - - 2*(6*ekt*Math.Pow(kappa, 3)*Math.Pow(rho, 2)*Math.Pow(t, 2) + - 4*Math.Pow(-1 + ekt, 2)*Math.Pow(rho, 2)*theta + - 2*Math.Pow(kappa, 2)*t*(Math.Pow(rho, 2)*t*theta + - ekt*(3 + Math.Pow(rho, 2)*(6 + t*theta))) - - (-1 + ekt)*kappa* - (3 + 6*Math.Pow(rho, 2)*t*theta + - ekt*(3 + 2*Math.Pow(rho, 2)*(6 + t*theta))))*y + - 2*Math.Pow(rho, 2)*Math.Pow(1 - ekt + kappa*t, 2)*Math.Pow(y, 2)))/ - (ekt*(-theta + kappa*t*theta + (theta - y)/ekt + y)) - - (48*Math.Pow(delta, 2)*kappa*rho*((1 + ekt*(-1 + kappa*t))*theta + - (-1 + ekt)*y)* - (2*theta + kappa*t*theta - y - kappa*t*y + - ekt*((-2 + kappa*t)*theta + y))* - (theta - 2*y + e2kt* - (-5*theta + 2*kappa*t*theta + 2*y + 4*Math.Pow(rho, 2)*((-3 + kappa*t)*theta + y)) + - 2*ekt*(2*(theta + kappa*t*(theta - y)) + - Math.Pow(rho, 2)*((6 + kappa*t*(4 + kappa*t))*theta - (2 + kappa*t*(2 + kappa*t))*y)) - ))/(ekt*(-theta + kappa*t*theta + (theta - y)/ekt + y)) + - (96*delta*Math.Pow(kappa, 3)*((1 + ekt*(-1 + kappa*t))*theta + - (-1 + ekt)*y)* - (theta - 2*y + e2kt* - (-5*theta + 2*kappa*t*theta + 2*y + 8*Math.Pow(rho, 2)*((-3 + kappa*t)*theta + y)) + - 4*ekt*(theta + kappa*t*theta - kappa*t*y + - Math.Pow(rho, 2)*((6 + kappa*t*(4 + kappa*t))*theta - (2 + kappa*t*(2 + kappa*t))*y)) - ))/(-theta + kappa*t*theta + (theta - y)/ekt + y) + - (9*Math.Pow(delta, 2)*kappa*rho*((1 + ekt*(-1 + kappa*t))*theta + - (-1 + ekt)*y)* - ((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y)* - (theta - 2*y + e2kt* - (-5*theta + 2*kappa*t*theta + 2*y + 8*Math.Pow(rho, 2)*((-3 + kappa*t)*theta + y)) + - 4*ekt*(theta + kappa*t*theta - kappa*t*y + - Math.Pow(rho, 2)*((6 + kappa*t*(4 + kappa*t))*theta - (2 + kappa*t*(2 + kappa*t))*y)) - ))/(ekt*(-theta + kappa*t*theta + (theta - y)/ekt + y)) - - (48*Math.Pow(delta, 2)*ekt*Math.Pow(kappa, 2)*rho* - (3*(theta - 2*y)*((2 + kappa*t)*theta - (1 + kappa*t)*y) + - 3*ekt*(6*Math.Pow(theta, 2) + theta*y - 2*Math.Pow(y, 2) + - kappa*(13*t*Math.Pow(theta, 2) + theta*(8 - 18*t*y) + 4*y*(-3 + t*y)) + - 4*Math.Pow(kappa, 2)*t*(theta + t*Math.Pow(theta, 2) - 2*t*theta*y + y*(-2 + t*y))) + - 3*e3kt*(10*Math.Pow(theta, 2) + - 2*Math.Pow(kappa, 2)*t*theta*(6 + 8*Math.Pow(rho, 2) + t*theta) - 9*theta*y + - 2*Math.Pow(y, 2) + kappa*(-9*t*Math.Pow(theta, 2) + 4*(3 + 4*Math.Pow(rho, 2))*y + - theta*(-40 - 64*Math.Pow(rho, 2) + 4*t*y))) + - e2kt*(-54*Math.Pow(theta, 2) + - 8*Math.Pow(kappa, 4)*Math.Pow(rho, 2)*Math.Pow(t, 3)*(theta - y) + 39*theta*y - - 6*Math.Pow(y, 2) + 24*Math.Pow(kappa, 3)*Math.Pow(t, 2)* - (theta + 2*Math.Pow(rho, 2)*theta - (1 + Math.Pow(rho, 2))*y) + - 6*Math.Pow(kappa, 2)*t*(3*t*Math.Pow(theta, 2) - 8*(1 + Math.Pow(rho, 2))*y + - theta*(16 + 24*Math.Pow(rho, 2) - 3*t*y)) - - 3*kappa*(5*t*Math.Pow(theta, 2) + 2*y*(8*Math.Pow(rho, 2) + 3*t*y) - - theta*(32 + 64*Math.Pow(rho, 2) + 17*t*y)))))/ - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y) + - (12*Math.Pow(delta, 2)*kappa*rho*((1 + ekt*(-1 + kappa*t))*theta + - (-1 + ekt)*y)* - (3*(theta - 2*y)*((2 + kappa*t)*theta - (1 + kappa*t)*y) + - 3*ekt*(6*Math.Pow(theta, 2) + theta*y - 2*Math.Pow(y, 2) + - kappa*(13*t*Math.Pow(theta, 2) + theta*(8 - 18*t*y) + 4*y*(-3 + t*y)) + - 4*Math.Pow(kappa, 2)*t*(theta + t*Math.Pow(theta, 2) - 2*t*theta*y + y*(-2 + t*y))) + - 3*e3kt*(10*Math.Pow(theta, 2) + - 2*Math.Pow(kappa, 2)*t*theta*(6 + 8*Math.Pow(rho, 2) + t*theta) - 9*theta*y + - 2*Math.Pow(y, 2) + kappa*(-9*t*Math.Pow(theta, 2) + 4*(3 + 4*Math.Pow(rho, 2))*y + - theta*(-40 - 64*Math.Pow(rho, 2) + 4*t*y))) + - e2kt*(-54*Math.Pow(theta, 2) + - 8*Math.Pow(kappa, 4)*Math.Pow(rho, 2)*Math.Pow(t, 3)*(theta - y) + 39*theta*y - - 6*Math.Pow(y, 2) + 24*Math.Pow(kappa, 3)*Math.Pow(t, 2)* - (theta + 2*Math.Pow(rho, 2)*theta - (1 + Math.Pow(rho, 2))*y) + - 6*Math.Pow(kappa, 2)*t*(3*t*Math.Pow(theta, 2) - 8*(1 + Math.Pow(rho, 2))*y + - theta*(16 + 24*Math.Pow(rho, 2) - 3*t*y)) - - 3*kappa*(5*t*Math.Pow(theta, 2) + 2*y*(8*Math.Pow(rho, 2) + 3*t*y) - - theta*(32 + 64*Math.Pow(rho, 2) + 17*t*y)))))/ - (ekt*(-theta + kappa*t*theta + (theta - y)/ekt + y)) + - (240*Math.Pow(delta, 2)*e2kt*Math.Pow(kappa, 2)*rho* - ((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y)* - (12*ekt*Math.Pow(kappa, 3)*Math.Pow(rho, 2)*Math.Pow(t, 2)*(theta - y) + - 2*Math.Pow(-1 + ekt, 2)*Math.Pow(rho, 2)*Math.Pow(-2*theta + y, 2) - - (-1 + ekt)*kappa* - (8*(1 + ekt)*Math.Pow(rho, 2)*t*Math.Pow(theta, 2) + - 2*y*(-3 - 3*ekt*(1 + 4*Math.Pow(rho, 2)) + 2*Math.Pow(rho, 2)*t*y) + - theta*(3 - 12*Math.Pow(rho, 2)*t*y + - ekt*(15 + Math.Pow(rho, 2)*(72 - 4*t*y)))) + - 2*Math.Pow(kappa, 2)*t*(e2kt*theta*(3 + Math.Pow(rho, 2)*(12 + t*theta)) + - Math.Pow(rho, 2)*t*Math.Pow(theta - y, 2) + - 2*ekt*(Math.Pow(rho, 2)*t*Math.Pow(theta, 2) - 3*(y + 2*Math.Pow(rho, 2)*y) + - theta*(3 + Math.Pow(rho, 2)*(12 - t*y))))))/ - Math.Pow((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y, 2) - - (120*Math.Pow(delta, 2)*ekt*kappa*rho* - ((2 + kappa*t + ekt*(-2 + kappa*t))*theta + - (-1 + ekt - kappa*t)*y)* - (12*ekt*Math.Pow(kappa, 3)*Math.Pow(rho, 2)*Math.Pow(t, 2)*(theta - y) + - 2*Math.Pow(-1 + ekt, 2)*Math.Pow(rho, 2)*Math.Pow(-2*theta + y, 2) - - (-1 + ekt)*kappa* - (8*(1 + ekt)*Math.Pow(rho, 2)*t*Math.Pow(theta, 2) + - 2*y*(-3 - 3*ekt*(1 + 4*Math.Pow(rho, 2)) + 2*Math.Pow(rho, 2)*t*y) + - theta*(3 - 12*Math.Pow(rho, 2)*t*y + - ekt*(15 + Math.Pow(rho, 2)*(72 - 4*t*y)))) + - 2*Math.Pow(kappa, 2)*t*(e2kt*theta*(3 + Math.Pow(rho, 2)*(12 + t*theta)) + - Math.Pow(rho, 2)*t*Math.Pow(theta - y, 2) + - 2*ekt*(Math.Pow(rho, 2)*t*Math.Pow(theta, 2) - 3*(y + 2*Math.Pow(rho, 2)*y) + - theta*(3 + Math.Pow(rho, 2)*(12 - t*y))))))/ - ((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y)))/ - (1536.0*e3kt*Math.Pow(kappa, 6)*Math.Pow(t, 2)* - Math.Pow((-theta + kappa*t*theta + (theta - y)/ekt + y)/(kappa*t), 1.5)); + return (delta * (768 * e2kt * Math.Pow(kappa, 4) * rho * + ((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y) - + (576 * delta * e2kt * Math.Pow(kappa, 3) * Math.Pow(rho, 2) * + Math.Pow((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y, 2)) / + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) - + 10 * Math.Pow(delta, 2) * Math.Pow(rho, 3) * Math.Pow((2 + kappa * t + ekt * (-2 + kappa * t)) * + theta + (-1 + ekt - kappa * t) * y, 3) + + (6 * Math.Pow(delta, 2) * kappa * Math.Pow(rho, 3) * + Math.Pow((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y, 3)) / + (-theta + kappa * t * theta + (theta - y) / ekt + y) - + (3360 * Math.Pow(delta, 2) * e3kt * Math.Pow(kappa, 3) * Math.Pow(rho, 3) * + Math.Pow((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y, 3)) / + Math.Pow((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y, 3) - + (288 * Math.Pow(delta, 2) * e2kt * Math.Pow(kappa, 2) * Math.Pow(rho, 3) * + Math.Pow((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y, 3)) / + Math.Pow((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y, 2) + + (234 * Math.Pow(delta, 2) * ekt * kappa * Math.Pow(rho, 3) * + Math.Pow((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y, 3)) / + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) - + 96 * delta * ekt * Math.Pow(kappa, 3) * + ((1 + 4 * ekt * (1 + kappa * t) + e2kt * (-5 + 2 * kappa * t)) * theta + + 2 * (-1 + e2kt - 2 * ekt * kappa * t) * y) - + 12 * Math.Pow(delta, 2) * kappa * rho * ((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y) * + ((1 + 4 * ekt * (1 + kappa * t) + e2kt * (-5 + 2 * kappa * t)) * theta + + 2 * (-1 + e2kt - 2 * ekt * kappa * t) * y) - + 192 * Math.Pow(delta, 2) * ekt * Math.Pow(kappa, 2) * rho * + ((2 + kappa * t + 2 * ekt * Math.Pow(2 + kappa * t, 2) + + e2kt * (-10 + 3 * kappa * t)) * theta + + (-3 + 3 * e2kt - 2 * kappa * t - 2 * ekt * kappa * t * (2 + kappa * t)) * y) + - (12 * Math.Pow(delta, 2) * ekt * Math.Pow(kappa, 2) * rho * + ((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y) * + ((1 + e2kt * (-5 + 2 * kappa * t + 8 * Math.Pow(rho, 2) * (-3 + kappa * t)) + + 4 * ekt * (1 + kappa * t + + Math.Pow(rho, 2) * (6 + 4 * kappa * t + Math.Pow(kappa, 2) * Math.Pow(t, 2)))) * theta + + 2 * (-1 + e2kt * (1 + 4 * Math.Pow(rho, 2)) - + 2 * ekt * (kappa * t + + Math.Pow(rho, 2) * (2 + 2 * kappa * t + Math.Pow(kappa, 2) * Math.Pow(t, 2)))) * y)) / + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) + + (576 * Math.Pow(delta, 2) * ekt * Math.Pow(kappa, 2) * rho * + ((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y) * + ((1 + e2kt * (-5 + 2 * kappa * t + 4 * Math.Pow(rho, 2) * (-3 + kappa * t)) + + 2 * ekt * (2 + 2 * kappa * t + + Math.Pow(rho, 2) * (6 + 4 * kappa * t + Math.Pow(kappa, 2) * Math.Pow(t, 2)))) * theta + + 2 * (-1 + e2kt * (1 + 2 * Math.Pow(rho, 2)) - + ekt * (2 * kappa * t + + Math.Pow(rho, 2) * (2 + 2 * kappa * t + Math.Pow(kappa, 2) * Math.Pow(t, 2)))) * y)) / + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) + + (5 * Math.Pow(delta, 2) * rho * ((1 + ekt * (-1 + kappa * t)) * theta + + (-1 + ekt) * y) * + ((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y) * + (theta * (12 * ekt * Math.Pow(kappa, 3) * Math.Pow(rho, 2) * Math.Pow(t, 2) + + 8 * Math.Pow(-1 + ekt, 2) * Math.Pow(rho, 2) * theta - + (-1 + ekt) * kappa * + (3 + 8 * Math.Pow(rho, 2) * t * theta + + ekt * (15 + 8 * Math.Pow(rho, 2) * (9 + t * theta))) + + 2 * Math.Pow(kappa, 2) * t * (Math.Pow(rho, 2) * t * theta + + 2 * ekt * (3 + Math.Pow(rho, 2) * (12 + t * theta)) + + e2kt * (3 + Math.Pow(rho, 2) * (12 + t * theta)))) - + 2 * (6 * ekt * Math.Pow(kappa, 3) * Math.Pow(rho, 2) * Math.Pow(t, 2) + + 4 * Math.Pow(-1 + ekt, 2) * Math.Pow(rho, 2) * theta + + 2 * Math.Pow(kappa, 2) * t * (Math.Pow(rho, 2) * t * theta + + ekt * (3 + Math.Pow(rho, 2) * (6 + t * theta))) - + (-1 + ekt) * kappa * + (3 + 6 * Math.Pow(rho, 2) * t * theta + + ekt * (3 + 2 * Math.Pow(rho, 2) * (6 + t * theta)))) * y + + 2 * Math.Pow(rho, 2) * Math.Pow(1 - ekt + kappa * t, 2) * Math.Pow(y, 2))) / + (ekt * (-theta + kappa * t * theta + (theta - y) / ekt + y)) - + (48 * Math.Pow(delta, 2) * kappa * rho * ((1 + ekt * (-1 + kappa * t)) * theta + + (-1 + ekt) * y) * + (2 * theta + kappa * t * theta - y - kappa * t * y + + ekt * ((-2 + kappa * t) * theta + y)) * + (theta - 2 * y + e2kt * + (-5 * theta + 2 * kappa * t * theta + 2 * y + 4 * Math.Pow(rho, 2) * ((-3 + kappa * t) * theta + y)) + + 2 * ekt * (2 * (theta + kappa * t * (theta - y)) + + Math.Pow(rho, 2) * ((6 + kappa * t * (4 + kappa * t)) * theta - (2 + kappa * t * (2 + kappa * t)) * y)) + )) / (ekt * (-theta + kappa * t * theta + (theta - y) / ekt + y)) + + (96 * delta * Math.Pow(kappa, 3) * ((1 + ekt * (-1 + kappa * t)) * theta + + (-1 + ekt) * y) * + (theta - 2 * y + e2kt * + (-5 * theta + 2 * kappa * t * theta + 2 * y + 8 * Math.Pow(rho, 2) * ((-3 + kappa * t) * theta + y)) + + 4 * ekt * (theta + kappa * t * theta - kappa * t * y + + Math.Pow(rho, 2) * ((6 + kappa * t * (4 + kappa * t)) * theta - (2 + kappa * t * (2 + kappa * t)) * y)) + )) / (-theta + kappa * t * theta + (theta - y) / ekt + y) + + (9 * Math.Pow(delta, 2) * kappa * rho * ((1 + ekt * (-1 + kappa * t)) * theta + + (-1 + ekt) * y) * + ((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y) * + (theta - 2 * y + e2kt * + (-5 * theta + 2 * kappa * t * theta + 2 * y + 8 * Math.Pow(rho, 2) * ((-3 + kappa * t) * theta + y)) + + 4 * ekt * (theta + kappa * t * theta - kappa * t * y + + Math.Pow(rho, 2) * ((6 + kappa * t * (4 + kappa * t)) * theta - (2 + kappa * t * (2 + kappa * t)) * y)) + )) / (ekt * (-theta + kappa * t * theta + (theta - y) / ekt + y)) - + (48 * Math.Pow(delta, 2) * ekt * Math.Pow(kappa, 2) * rho * + (3 * (theta - 2 * y) * ((2 + kappa * t) * theta - (1 + kappa * t) * y) + + 3 * ekt * (6 * Math.Pow(theta, 2) + theta * y - 2 * Math.Pow(y, 2) + + kappa * (13 * t * Math.Pow(theta, 2) + theta * (8 - 18 * t * y) + 4 * y * (-3 + t * y)) + + 4 * Math.Pow(kappa, 2) * t * (theta + t * Math.Pow(theta, 2) - 2 * t * theta * y + y * (-2 + t * y))) + + 3 * e3kt * (10 * Math.Pow(theta, 2) + + 2 * Math.Pow(kappa, 2) * t * theta * (6 + 8 * Math.Pow(rho, 2) + t * theta) - 9 * theta * y + + 2 * Math.Pow(y, 2) + kappa * (-9 * t * Math.Pow(theta, 2) + 4 * (3 + 4 * Math.Pow(rho, 2)) * y + + theta * (-40 - 64 * Math.Pow(rho, 2) + 4 * t * y))) + + e2kt * (-54 * Math.Pow(theta, 2) + + 8 * Math.Pow(kappa, 4) * Math.Pow(rho, 2) * Math.Pow(t, 3) * (theta - y) + 39 * theta * y - + 6 * Math.Pow(y, 2) + 24 * Math.Pow(kappa, 3) * Math.Pow(t, 2) * + (theta + 2 * Math.Pow(rho, 2) * theta - (1 + Math.Pow(rho, 2)) * y) + + 6 * Math.Pow(kappa, 2) * t * (3 * t * Math.Pow(theta, 2) - 8 * (1 + Math.Pow(rho, 2)) * y + + theta * (16 + 24 * Math.Pow(rho, 2) - 3 * t * y)) - + 3 * kappa * (5 * t * Math.Pow(theta, 2) + 2 * y * (8 * Math.Pow(rho, 2) + 3 * t * y) - + theta * (32 + 64 * Math.Pow(rho, 2) + 17 * t * y))))) / + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y) + + (12 * Math.Pow(delta, 2) * kappa * rho * ((1 + ekt * (-1 + kappa * t)) * theta + + (-1 + ekt) * y) * + (3 * (theta - 2 * y) * ((2 + kappa * t) * theta - (1 + kappa * t) * y) + + 3 * ekt * (6 * Math.Pow(theta, 2) + theta * y - 2 * Math.Pow(y, 2) + + kappa * (13 * t * Math.Pow(theta, 2) + theta * (8 - 18 * t * y) + 4 * y * (-3 + t * y)) + + 4 * Math.Pow(kappa, 2) * t * (theta + t * Math.Pow(theta, 2) - 2 * t * theta * y + y * (-2 + t * y))) + + 3 * e3kt * (10 * Math.Pow(theta, 2) + + 2 * Math.Pow(kappa, 2) * t * theta * (6 + 8 * Math.Pow(rho, 2) + t * theta) - 9 * theta * y + + 2 * Math.Pow(y, 2) + kappa * (-9 * t * Math.Pow(theta, 2) + 4 * (3 + 4 * Math.Pow(rho, 2)) * y + + theta * (-40 - 64 * Math.Pow(rho, 2) + 4 * t * y))) + + e2kt * (-54 * Math.Pow(theta, 2) + + 8 * Math.Pow(kappa, 4) * Math.Pow(rho, 2) * Math.Pow(t, 3) * (theta - y) + 39 * theta * y - + 6 * Math.Pow(y, 2) + 24 * Math.Pow(kappa, 3) * Math.Pow(t, 2) * + (theta + 2 * Math.Pow(rho, 2) * theta - (1 + Math.Pow(rho, 2)) * y) + + 6 * Math.Pow(kappa, 2) * t * (3 * t * Math.Pow(theta, 2) - 8 * (1 + Math.Pow(rho, 2)) * y + + theta * (16 + 24 * Math.Pow(rho, 2) - 3 * t * y)) - + 3 * kappa * (5 * t * Math.Pow(theta, 2) + 2 * y * (8 * Math.Pow(rho, 2) + 3 * t * y) - + theta * (32 + 64 * Math.Pow(rho, 2) + 17 * t * y))))) / + (ekt * (-theta + kappa * t * theta + (theta - y) / ekt + y)) + + (240 * Math.Pow(delta, 2) * e2kt * Math.Pow(kappa, 2) * rho * + ((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y) * + (12 * ekt * Math.Pow(kappa, 3) * Math.Pow(rho, 2) * Math.Pow(t, 2) * (theta - y) + + 2 * Math.Pow(-1 + ekt, 2) * Math.Pow(rho, 2) * Math.Pow(-2 * theta + y, 2) - + (-1 + ekt) * kappa * + (8 * (1 + ekt) * Math.Pow(rho, 2) * t * Math.Pow(theta, 2) + + 2 * y * (-3 - 3 * ekt * (1 + 4 * Math.Pow(rho, 2)) + 2 * Math.Pow(rho, 2) * t * y) + + theta * (3 - 12 * Math.Pow(rho, 2) * t * y + + ekt * (15 + Math.Pow(rho, 2) * (72 - 4 * t * y)))) + + 2 * Math.Pow(kappa, 2) * t * (e2kt * theta * (3 + Math.Pow(rho, 2) * (12 + t * theta)) + + Math.Pow(rho, 2) * t * Math.Pow(theta - y, 2) + + 2 * ekt * (Math.Pow(rho, 2) * t * Math.Pow(theta, 2) - 3 * (y + 2 * Math.Pow(rho, 2) * y) + + theta * (3 + Math.Pow(rho, 2) * (12 - t * y)))))) / + Math.Pow((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y, 2) - + (120 * Math.Pow(delta, 2) * ekt * kappa * rho * + ((2 + kappa * t + ekt * (-2 + kappa * t)) * theta + + (-1 + ekt - kappa * t) * y) * + (12 * ekt * Math.Pow(kappa, 3) * Math.Pow(rho, 2) * Math.Pow(t, 2) * (theta - y) + + 2 * Math.Pow(-1 + ekt, 2) * Math.Pow(rho, 2) * Math.Pow(-2 * theta + y, 2) - + (-1 + ekt) * kappa * + (8 * (1 + ekt) * Math.Pow(rho, 2) * t * Math.Pow(theta, 2) + + 2 * y * (-3 - 3 * ekt * (1 + 4 * Math.Pow(rho, 2)) + 2 * Math.Pow(rho, 2) * t * y) + + theta * (3 - 12 * Math.Pow(rho, 2) * t * y + + ekt * (15 + Math.Pow(rho, 2) * (72 - 4 * t * y)))) + + 2 * Math.Pow(kappa, 2) * t * (e2kt * theta * (3 + Math.Pow(rho, 2) * (12 + t * theta)) + + Math.Pow(rho, 2) * t * Math.Pow(theta - y, 2) + + 2 * ekt * (Math.Pow(rho, 2) * t * Math.Pow(theta, 2) - 3 * (y + 2 * Math.Pow(rho, 2) * y) + + theta * (3 + Math.Pow(rho, 2) * (12 - t * y)))))) / + ((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y))) / + (1536.0 * e3kt * Math.Pow(kappa, 6) * Math.Pow(t, 2) * + Math.Pow((-theta + kappa * t * theta + (theta - y) / ekt + y) / (kappa * t), 1.5)); } - private double z2(double t, double kappa, double theta,double delta, double y, double rho) + private double z2(double t, double kappa, double theta, double delta, double y, double rho) { - return (Math.Pow(delta, 2)*(8*e3kt*Math.Pow(kappa, 5)*Math.Pow(rho, 2)*Math.Pow(t, 4)*(2 + delta*rho*t)* - Math.Pow(theta, 2)*(theta - y) - delta*Math.Pow(-1 + ekt, 3)*rho* - (2*(-1 + ekt*(-5 + 24*Math.Pow(rho, 2)))*Math.Pow(theta, 3) + - (7 + ekt*(3 + 56*Math.Pow(rho, 2)))*Math.Pow(theta, 2)*y - - 3*(1 + ekt*(-3 + 8*Math.Pow(rho, 2)))*theta*Math.Pow(y, 2) + - 2*(-1 + ekt*(-1 + 2*Math.Pow(rho, 2)))*Math.Pow(y, 3)) - - Math.Pow(-1 + ekt, 2)*kappa* - ((-4 + delta*rho*t - 8*ekt* - (2 - 12*Math.Pow(rho, 2) - 4*delta*rho*t + 25*delta*Math.Pow(rho, 3)*t) + - e2kt*(20 - 96*Math.Pow(rho, 2) + 3*delta*rho*t + 56*delta*Math.Pow(rho, 3)*t) - )*Math.Pow(theta, 3) - 2*(-8 + 2*delta*rho*t + - e2kt*(24 - 80*Math.Pow(rho, 2) - 9*delta*rho*t + - 24*delta*Math.Pow(rho, 3)*t) - - 4*ekt* - (4 - 20*Math.Pow(rho, 2) - 10*delta*rho*t + 39*delta*Math.Pow(rho, 3)*t) - )*Math.Pow(theta, 2)*y + (5*(-4 + delta*rho*t) + - ekt*(-16 + 80*Math.Pow(rho, 2) + 57*delta*rho*t - - 140*delta*Math.Pow(rho, 3)*t) + - 2*e2kt*(18 - 40*Math.Pow(rho, 2) - 3*delta*rho*t + - 6*delta*Math.Pow(rho, 3)*t))*theta*Math.Pow(y, 2) + - 2*(4 + e2kt*(-4 + 8*Math.Pow(rho, 2)) - delta*rho*t + - ekt*rho*(-8*rho - 7*delta*t + 14*delta*Math.Pow(rho, 2)*t))*Math.Pow(y, 3)) + - ekt*(-1 + ekt)*Math.Pow(kappa, 2)*t* - ((-24 + 128*Math.Pow(rho, 2) + 9*delta*rho*t - 144*delta*Math.Pow(rho, 3)*t - - 4*ekt*(6 - 8*Math.Pow(rho, 2) - 9*delta*rho*t + 6*delta*Math.Pow(rho, 3)*t) + - e2kt*(48 - 160*Math.Pow(rho, 2) - 9*delta*rho*t + - 24*delta*Math.Pow(rho, 3)*t))*Math.Pow(theta, 3) - - (-72 + 320*Math.Pow(rho, 2) + 27*delta*rho*t - 360*delta*Math.Pow(rho, 3)*t - - ekt*rho*(160*rho - 81*delta*t + 348*delta*Math.Pow(rho, 2)*t) + - 2*e2kt*(36 - 80*Math.Pow(rho, 2) - 3*delta*rho*t + - 6*delta*Math.Pow(rho, 3)*t))*Math.Pow(theta, 2)*y - - 2*(32 - 128*Math.Pow(rho, 2) + 12*e2kt*(-1 + 2*Math.Pow(rho, 2)) - - 15*delta*rho*t + 144*delta*Math.Pow(rho, 3)*t + - 2*ekt*(-10 + 52*Math.Pow(rho, 2) - 13*delta*rho*t + - 58*delta*Math.Pow(rho, 3)*t))*theta*Math.Pow(y, 2) + - 4*(4 - 16*Math.Pow(rho, 2) - 3*delta*rho*t + 18*delta*Math.Pow(rho, 3)*t + - ekt*(-4 + 16*Math.Pow(rho, 2) - 2*delta*rho*t + 11*delta*Math.Pow(rho, 3)*t))* - Math.Pow(y, 3)) - 4*e2kt*Math.Pow(kappa, 4)*Math.Pow(t, 3)*theta* - (2*e2kt*(-1 + 2*Math.Pow(rho, 2))*Math.Pow(theta, 2) + - Math.Pow(rho, 2)*(4 + 13*delta*rho*t)*Math.Pow(theta - y, 2) + - ekt*((-4 + 16*Math.Pow(rho, 2) - 2*delta*rho*t + 9*delta*Math.Pow(rho, 3)*t)* - Math.Pow(theta, 2) + (4 - 32*Math.Pow(rho, 2) + 2*delta*rho*t - 19*delta*Math.Pow(rho, 3)*t)* - theta*y + 4*Math.Pow(rho, 2)*(2 + delta*rho*t)*Math.Pow(y, 2))) - - 2*ekt*Math.Pow(kappa, 3)*Math.Pow(t, 2)* - (-4*Math.Pow(rho, 2)*(-4 + 3*delta*rho*t)*Math.Pow(theta - y, 3) + - e3kt*Math.Pow(theta, 2)* - ((18 - 40*Math.Pow(rho, 2) - delta*rho*t + 2*delta*Math.Pow(rho, 3)*t)*theta + - 12*(-1 + 2*Math.Pow(rho, 2))*y) + - 2*ekt*((-9 + 36*Math.Pow(rho, 2) + 19*delta*Math.Pow(rho, 3)*t)*Math.Pow(theta, 3) + - 2*(9 - 30*Math.Pow(rho, 2) + 7*delta*Math.Pow(rho, 3)*t)*Math.Pow(theta, 2)*y + - (-8 + 20*Math.Pow(rho, 2) + delta*rho*t - 46*delta*Math.Pow(rho, 3)*t)*theta*Math.Pow(y, 2) + - Math.Pow(rho, 2)*(4 + 13*delta*rho*t)*Math.Pow(y, 3)) + - e2kt*(8*theta*y*(-3*theta + 2*y) + - delta*rho*t*theta*(7*Math.Pow(theta, 2) - 23*theta*y + 8*Math.Pow(y, 2)) - - 8*Math.Pow(rho, 2)*(6*Math.Pow(theta, 3) - 18*Math.Pow(theta, 2)*y + 11*theta*Math.Pow(y, 2) - - Math.Pow(y, 3)) + 4*delta*Math.Pow(rho, 3)*t* - (-13*Math.Pow(theta, 3) + 31*Math.Pow(theta, 2)*y - 14*theta*Math.Pow(y, 2) + Math.Pow(y, 3))))))/ - (64.0*Math.Pow(kappa, 2)*t*Math.Sqrt((-theta + kappa*t*theta + (theta - y)/ekt + y)/ - (kappa*t))*Math.Pow((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y,4)); + return (Math.Pow(delta, 2) * (8 * e3kt * Math.Pow(kappa, 5) * Math.Pow(rho, 2) * Math.Pow(t, 4) * (2 + delta * rho * t) * + Math.Pow(theta, 2) * (theta - y) - delta * Math.Pow(-1 + ekt, 3) * rho * + (2 * (-1 + ekt * (-5 + 24 * Math.Pow(rho, 2))) * Math.Pow(theta, 3) + + (7 + ekt * (3 + 56 * Math.Pow(rho, 2))) * Math.Pow(theta, 2) * y - + 3 * (1 + ekt * (-3 + 8 * Math.Pow(rho, 2))) * theta * Math.Pow(y, 2) + + 2 * (-1 + ekt * (-1 + 2 * Math.Pow(rho, 2))) * Math.Pow(y, 3)) - + Math.Pow(-1 + ekt, 2) * kappa * + ((-4 + delta * rho * t - 8 * ekt * + (2 - 12 * Math.Pow(rho, 2) - 4 * delta * rho * t + 25 * delta * Math.Pow(rho, 3) * t) + + e2kt * (20 - 96 * Math.Pow(rho, 2) + 3 * delta * rho * t + 56 * delta * Math.Pow(rho, 3) * t) + ) * Math.Pow(theta, 3) - 2 * (-8 + 2 * delta * rho * t + + e2kt * (24 - 80 * Math.Pow(rho, 2) - 9 * delta * rho * t + + 24 * delta * Math.Pow(rho, 3) * t) - + 4 * ekt * + (4 - 20 * Math.Pow(rho, 2) - 10 * delta * rho * t + 39 * delta * Math.Pow(rho, 3) * t) + ) * Math.Pow(theta, 2) * y + (5 * (-4 + delta * rho * t) + + ekt * (-16 + 80 * Math.Pow(rho, 2) + 57 * delta * rho * t - + 140 * delta * Math.Pow(rho, 3) * t) + + 2 * e2kt * (18 - 40 * Math.Pow(rho, 2) - 3 * delta * rho * t + + 6 * delta * Math.Pow(rho, 3) * t)) * theta * Math.Pow(y, 2) + + 2 * (4 + e2kt * (-4 + 8 * Math.Pow(rho, 2)) - delta * rho * t + + ekt * rho * (-8 * rho - 7 * delta * t + 14 * delta * Math.Pow(rho, 2) * t)) * Math.Pow(y, 3)) + + ekt * (-1 + ekt) * Math.Pow(kappa, 2) * t * + ((-24 + 128 * Math.Pow(rho, 2) + 9 * delta * rho * t - 144 * delta * Math.Pow(rho, 3) * t - + 4 * ekt * (6 - 8 * Math.Pow(rho, 2) - 9 * delta * rho * t + 6 * delta * Math.Pow(rho, 3) * t) + + e2kt * (48 - 160 * Math.Pow(rho, 2) - 9 * delta * rho * t + + 24 * delta * Math.Pow(rho, 3) * t)) * Math.Pow(theta, 3) - + (-72 + 320 * Math.Pow(rho, 2) + 27 * delta * rho * t - 360 * delta * Math.Pow(rho, 3) * t - + ekt * rho * (160 * rho - 81 * delta * t + 348 * delta * Math.Pow(rho, 2) * t) + + 2 * e2kt * (36 - 80 * Math.Pow(rho, 2) - 3 * delta * rho * t + + 6 * delta * Math.Pow(rho, 3) * t)) * Math.Pow(theta, 2) * y - + 2 * (32 - 128 * Math.Pow(rho, 2) + 12 * e2kt * (-1 + 2 * Math.Pow(rho, 2)) - + 15 * delta * rho * t + 144 * delta * Math.Pow(rho, 3) * t + + 2 * ekt * (-10 + 52 * Math.Pow(rho, 2) - 13 * delta * rho * t + + 58 * delta * Math.Pow(rho, 3) * t)) * theta * Math.Pow(y, 2) + + 4 * (4 - 16 * Math.Pow(rho, 2) - 3 * delta * rho * t + 18 * delta * Math.Pow(rho, 3) * t + + ekt * (-4 + 16 * Math.Pow(rho, 2) - 2 * delta * rho * t + 11 * delta * Math.Pow(rho, 3) * t)) * + Math.Pow(y, 3)) - 4 * e2kt * Math.Pow(kappa, 4) * Math.Pow(t, 3) * theta * + (2 * e2kt * (-1 + 2 * Math.Pow(rho, 2)) * Math.Pow(theta, 2) + + Math.Pow(rho, 2) * (4 + 13 * delta * rho * t) * Math.Pow(theta - y, 2) + + ekt * ((-4 + 16 * Math.Pow(rho, 2) - 2 * delta * rho * t + 9 * delta * Math.Pow(rho, 3) * t) * + Math.Pow(theta, 2) + (4 - 32 * Math.Pow(rho, 2) + 2 * delta * rho * t - 19 * delta * Math.Pow(rho, 3) * t) * + theta * y + 4 * Math.Pow(rho, 2) * (2 + delta * rho * t) * Math.Pow(y, 2))) - + 2 * ekt * Math.Pow(kappa, 3) * Math.Pow(t, 2) * + (-4 * Math.Pow(rho, 2) * (-4 + 3 * delta * rho * t) * Math.Pow(theta - y, 3) + + e3kt * Math.Pow(theta, 2) * + ((18 - 40 * Math.Pow(rho, 2) - delta * rho * t + 2 * delta * Math.Pow(rho, 3) * t) * theta + + 12 * (-1 + 2 * Math.Pow(rho, 2)) * y) + + 2 * ekt * ((-9 + 36 * Math.Pow(rho, 2) + 19 * delta * Math.Pow(rho, 3) * t) * Math.Pow(theta, 3) + + 2 * (9 - 30 * Math.Pow(rho, 2) + 7 * delta * Math.Pow(rho, 3) * t) * Math.Pow(theta, 2) * y + + (-8 + 20 * Math.Pow(rho, 2) + delta * rho * t - 46 * delta * Math.Pow(rho, 3) * t) * theta * Math.Pow(y, 2) + + Math.Pow(rho, 2) * (4 + 13 * delta * rho * t) * Math.Pow(y, 3)) + + e2kt * (8 * theta * y * (-3 * theta + 2 * y) + + delta * rho * t * theta * (7 * Math.Pow(theta, 2) - 23 * theta * y + 8 * Math.Pow(y, 2)) - + 8 * Math.Pow(rho, 2) * (6 * Math.Pow(theta, 3) - 18 * Math.Pow(theta, 2) * y + 11 * theta * Math.Pow(y, 2) - + Math.Pow(y, 3)) + 4 * delta * Math.Pow(rho, 3) * t * + (-13 * Math.Pow(theta, 3) + 31 * Math.Pow(theta, 2) * y - 14 * theta * Math.Pow(y, 2) + Math.Pow(y, 3)))))) / + (64.0 * Math.Pow(kappa, 2) * t * Math.Sqrt((-theta + kappa * t * theta + (theta - y) / ekt + y) / + (kappa * t)) * Math.Pow((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y, 4)); } - private double z3(double t, double kappa, double theta,double delta, double y, double rho) + private double z3(double t, double kappa, double theta, double delta, double y, double rho) { - return (Math.Pow(delta, 3)*ekt*rho*((-15*(2 + kappa*t) + - 3*e4kt*(50 - 79*kappa*t + 35*Math.Pow(kappa, 2)*Math.Pow(t, 2) - - 6*Math.Pow(kappa, 3)*Math.Pow(t, 3) + - 8*Math.Pow(rho, 2)*(-18 + 15*kappa*t - 6*Math.Pow(kappa, 2)*Math.Pow(t, 2) + - Math.Pow(kappa, 3)*Math.Pow(t, 3))) + - ekt*(-3*(20 + 86*kappa*t + 29*Math.Pow(kappa, 2)*Math.Pow(t, 2)) + - Math.Pow(rho, 2)*(432 + 936*kappa*t + 552*Math.Pow(kappa, 2)*Math.Pow(t, 2) + - 92*Math.Pow(kappa, 3)*Math.Pow(t, 3))) + - e2kt*(360 + 324*kappa*t - 261*Math.Pow(kappa, 2)*Math.Pow(t, 2) - - 48*Math.Pow(kappa, 3)*Math.Pow(t, 3) - - 4*Math.Pow(rho, 2)*(324 + 378*kappa*t - 12*Math.Pow(kappa, 2)*Math.Pow(t, 2) - - 2*Math.Pow(kappa, 3)*Math.Pow(t, 3) + 23*Math.Pow(kappa, 4)*Math.Pow(t, 4))) + - e3kt*(3*(-140 + 62*kappa*t + 81*Math.Pow(kappa, 2)*Math.Pow(t, 2) - - 38*Math.Pow(kappa, 3)*Math.Pow(t, 3) + 8*Math.Pow(kappa, 4)*Math.Pow(t, 4)) + - 4*Math.Pow(rho, 2)*(324 + 54*kappa*t - 114*Math.Pow(kappa, 2)*Math.Pow(t, 2) + - 77*Math.Pow(kappa, 3)*Math.Pow(t, 3) - 19*Math.Pow(kappa, 4)*Math.Pow(t, 4) + - 2*Math.Pow(kappa, 5)*Math.Pow(t, 5))))*Math.Pow(theta, 3) + - (15*(7 + 4*kappa*t) + 3*e4kt* - (-79 + 70*kappa*t - 18*Math.Pow(kappa, 2)*Math.Pow(t, 2) + - 24*Math.Pow(rho, 2)*(5 - 4*kappa*t + Math.Pow(kappa, 2)*Math.Pow(t, 2))) - - 3*ekt*(26 - 200*kappa*t - 87*Math.Pow(kappa, 2)*Math.Pow(t, 2) + - 4*Math.Pow(rho, 2)*(30 + 142*kappa*t + 115*Math.Pow(kappa, 2)*Math.Pow(t, 2) + - 23*Math.Pow(kappa, 3)*Math.Pow(t, 3))) + - 2*e2kt*(3*(-66 - 195*kappa*t + 63*Math.Pow(kappa, 2)*Math.Pow(t, 2) + - 16*Math.Pow(kappa, 3)*Math.Pow(t, 3)) + - 4*Math.Pow(rho, 2)*(135 + 390*kappa*t - 9*Math.Pow(kappa, 2)*Math.Pow(t, 2) - - 48*Math.Pow(kappa, 3)*Math.Pow(t, 3) + 23*Math.Pow(kappa, 4)*Math.Pow(t, 4))) + - e3kt*(606 + 300*kappa*t - 585*Math.Pow(kappa, 2)*Math.Pow(t, 2) + - 210*Math.Pow(kappa, 3)*Math.Pow(t, 3) - 24*Math.Pow(kappa, 4)*Math.Pow(t, 4) - - 4*Math.Pow(rho, 2)*(270 + 282*kappa*t - 345*Math.Pow(kappa, 2)*Math.Pow(t, 2) + - 153*Math.Pow(kappa, 3)*Math.Pow(t, 3) - 29*Math.Pow(kappa, 4)*Math.Pow(t, 4) + - 2*Math.Pow(kappa, 5)*Math.Pow(t, 5))))*Math.Pow(theta, 2)*y + - (-93 - 75*kappa*t + 3*e4kt* - (35 - 18*kappa*t + 24*Math.Pow(rho, 2)*(-2 + kappa*t)) + - 3*ekt*(58 - 123*kappa*t - 86*Math.Pow(kappa, 2)*Math.Pow(t, 2) + - 4*Math.Pow(rho, 2)*(12 + 80*kappa*t + 92*Math.Pow(kappa, 2)*Math.Pow(t, 2) + - 23*Math.Pow(kappa, 3)*Math.Pow(t, 3))) + - e3kt*(-3*(74 + 137*kappa*t - 100*Math.Pow(kappa, 2)*Math.Pow(t, 2) + - 16*Math.Pow(kappa, 3)*Math.Pow(t, 3)) - - 16*Math.Pow(rho, 2)*(-27 - 51*kappa*t + 45*Math.Pow(kappa, 2)*Math.Pow(t, 2) - - 12*Math.Pow(kappa, 3)*Math.Pow(t, 3) + Math.Pow(kappa, 4)*Math.Pow(t, 4))) + - e2kt*(36 + 909*kappa*t - 42*Math.Pow(kappa, 2)*Math.Pow(t, 2) - - 60*Math.Pow(kappa, 3)*Math.Pow(t, 3) - - 4*Math.Pow(rho, 2)*(108 + 462*kappa*t + 96*Math.Pow(kappa, 2)*Math.Pow(t, 2) - - 117*Math.Pow(kappa, 3)*Math.Pow(t, 3) + 23*Math.Pow(kappa, 4)*Math.Pow(t, 4))))* - theta*Math.Pow(y, 2) - + 2*(9 + 3*e4kt*(-3 + 4*Math.Pow(rho, 2)) + 15*kappa*t + - e2kt*(-3*kappa*t*(33 + 10*kappa*t) + - Math.Pow(rho, 2)*(36 + 192*kappa*t + 96*Math.Pow(kappa, 2)*Math.Pow(t, 2) - - 46*Math.Pow(kappa, 3)*Math.Pow(t, 3))) + - e3kt*(18 + 57*kappa*t - 12*Math.Pow(kappa, 2)*Math.Pow(t, 2) - - 2*Math.Pow(rho, 2)*(18 + 48*kappa*t - 21*Math.Pow(kappa, 2)*Math.Pow(t, 2) + - 2*Math.Pow(kappa, 3)*Math.Pow(t, 3))) + - ekt*(3*(-6 + 9*kappa*t + 14*Math.Pow(kappa, 2)*Math.Pow(t, 2)) - - 2*Math.Pow(rho, 2)*(6 + 48*kappa*t + 69*Math.Pow(kappa, 2)*Math.Pow(t, 2) + - 23*Math.Pow(kappa, 3)*Math.Pow(t, 3))))*Math.Pow(y, 3)))/ - (96.0*kappa*t*Math.Sqrt((-theta + kappa*t*theta + (theta - y)/ekt + y)/(kappa*t))* - Math.Pow((1 + ekt*(-1 + kappa*t))*theta + (-1 + ekt)*y, 5)); + return (Math.Pow(delta, 3) * ekt * rho * ((-15 * (2 + kappa * t) + + 3 * e4kt * (50 - 79 * kappa * t + 35 * Math.Pow(kappa, 2) * Math.Pow(t, 2) - + 6 * Math.Pow(kappa, 3) * Math.Pow(t, 3) + + 8 * Math.Pow(rho, 2) * (-18 + 15 * kappa * t - 6 * Math.Pow(kappa, 2) * Math.Pow(t, 2) + + Math.Pow(kappa, 3) * Math.Pow(t, 3))) + + ekt * (-3 * (20 + 86 * kappa * t + 29 * Math.Pow(kappa, 2) * Math.Pow(t, 2)) + + Math.Pow(rho, 2) * (432 + 936 * kappa * t + 552 * Math.Pow(kappa, 2) * Math.Pow(t, 2) + + 92 * Math.Pow(kappa, 3) * Math.Pow(t, 3))) + + e2kt * (360 + 324 * kappa * t - 261 * Math.Pow(kappa, 2) * Math.Pow(t, 2) - + 48 * Math.Pow(kappa, 3) * Math.Pow(t, 3) - + 4 * Math.Pow(rho, 2) * (324 + 378 * kappa * t - 12 * Math.Pow(kappa, 2) * Math.Pow(t, 2) - + 2 * Math.Pow(kappa, 3) * Math.Pow(t, 3) + 23 * Math.Pow(kappa, 4) * Math.Pow(t, 4))) + + e3kt * (3 * (-140 + 62 * kappa * t + 81 * Math.Pow(kappa, 2) * Math.Pow(t, 2) - + 38 * Math.Pow(kappa, 3) * Math.Pow(t, 3) + 8 * Math.Pow(kappa, 4) * Math.Pow(t, 4)) + + 4 * Math.Pow(rho, 2) * (324 + 54 * kappa * t - 114 * Math.Pow(kappa, 2) * Math.Pow(t, 2) + + 77 * Math.Pow(kappa, 3) * Math.Pow(t, 3) - 19 * Math.Pow(kappa, 4) * Math.Pow(t, 4) + + 2 * Math.Pow(kappa, 5) * Math.Pow(t, 5)))) * Math.Pow(theta, 3) + + (15 * (7 + 4 * kappa * t) + 3 * e4kt * + (-79 + 70 * kappa * t - 18 * Math.Pow(kappa, 2) * Math.Pow(t, 2) + + 24 * Math.Pow(rho, 2) * (5 - 4 * kappa * t + Math.Pow(kappa, 2) * Math.Pow(t, 2))) - + 3 * ekt * (26 - 200 * kappa * t - 87 * Math.Pow(kappa, 2) * Math.Pow(t, 2) + + 4 * Math.Pow(rho, 2) * (30 + 142 * kappa * t + 115 * Math.Pow(kappa, 2) * Math.Pow(t, 2) + + 23 * Math.Pow(kappa, 3) * Math.Pow(t, 3))) + + 2 * e2kt * (3 * (-66 - 195 * kappa * t + 63 * Math.Pow(kappa, 2) * Math.Pow(t, 2) + + 16 * Math.Pow(kappa, 3) * Math.Pow(t, 3)) + + 4 * Math.Pow(rho, 2) * (135 + 390 * kappa * t - 9 * Math.Pow(kappa, 2) * Math.Pow(t, 2) - + 48 * Math.Pow(kappa, 3) * Math.Pow(t, 3) + 23 * Math.Pow(kappa, 4) * Math.Pow(t, 4))) + + e3kt * (606 + 300 * kappa * t - 585 * Math.Pow(kappa, 2) * Math.Pow(t, 2) + + 210 * Math.Pow(kappa, 3) * Math.Pow(t, 3) - 24 * Math.Pow(kappa, 4) * Math.Pow(t, 4) - + 4 * Math.Pow(rho, 2) * (270 + 282 * kappa * t - 345 * Math.Pow(kappa, 2) * Math.Pow(t, 2) + + 153 * Math.Pow(kappa, 3) * Math.Pow(t, 3) - 29 * Math.Pow(kappa, 4) * Math.Pow(t, 4) + + 2 * Math.Pow(kappa, 5) * Math.Pow(t, 5)))) * Math.Pow(theta, 2) * y + + (-93 - 75 * kappa * t + 3 * e4kt * + (35 - 18 * kappa * t + 24 * Math.Pow(rho, 2) * (-2 + kappa * t)) + + 3 * ekt * (58 - 123 * kappa * t - 86 * Math.Pow(kappa, 2) * Math.Pow(t, 2) + + 4 * Math.Pow(rho, 2) * (12 + 80 * kappa * t + 92 * Math.Pow(kappa, 2) * Math.Pow(t, 2) + + 23 * Math.Pow(kappa, 3) * Math.Pow(t, 3))) + + e3kt * (-3 * (74 + 137 * kappa * t - 100 * Math.Pow(kappa, 2) * Math.Pow(t, 2) + + 16 * Math.Pow(kappa, 3) * Math.Pow(t, 3)) - + 16 * Math.Pow(rho, 2) * (-27 - 51 * kappa * t + 45 * Math.Pow(kappa, 2) * Math.Pow(t, 2) - + 12 * Math.Pow(kappa, 3) * Math.Pow(t, 3) + Math.Pow(kappa, 4) * Math.Pow(t, 4))) + + e2kt * (36 + 909 * kappa * t - 42 * Math.Pow(kappa, 2) * Math.Pow(t, 2) - + 60 * Math.Pow(kappa, 3) * Math.Pow(t, 3) - + 4 * Math.Pow(rho, 2) * (108 + 462 * kappa * t + 96 * Math.Pow(kappa, 2) * Math.Pow(t, 2) - + 117 * Math.Pow(kappa, 3) * Math.Pow(t, 3) + 23 * Math.Pow(kappa, 4) * Math.Pow(t, 4)))) * + theta * Math.Pow(y, 2) + + 2 * (9 + 3 * e4kt * (-3 + 4 * Math.Pow(rho, 2)) + 15 * kappa * t + + e2kt * (-3 * kappa * t * (33 + 10 * kappa * t) + + Math.Pow(rho, 2) * (36 + 192 * kappa * t + 96 * Math.Pow(kappa, 2) * Math.Pow(t, 2) - + 46 * Math.Pow(kappa, 3) * Math.Pow(t, 3))) + + e3kt * (18 + 57 * kappa * t - 12 * Math.Pow(kappa, 2) * Math.Pow(t, 2) - + 2 * Math.Pow(rho, 2) * (18 + 48 * kappa * t - 21 * Math.Pow(kappa, 2) * Math.Pow(t, 2) + + 2 * Math.Pow(kappa, 3) * Math.Pow(t, 3))) + + ekt * (3 * (-6 + 9 * kappa * t + 14 * Math.Pow(kappa, 2) * Math.Pow(t, 2)) - + 2 * Math.Pow(rho, 2) * (6 + 48 * kappa * t + 69 * Math.Pow(kappa, 2) * Math.Pow(t, 2) + + 23 * Math.Pow(kappa, 3) * Math.Pow(t, 3)))) * Math.Pow(y, 3))) / + (96.0 * kappa * t * Math.Sqrt((-theta + kappa * t * theta + (theta - y) / ekt + y) / (kappa * t)) * + Math.Pow((1 + ekt * (-1 + kappa * t)) * theta + (-1 + ekt) * y, 5)); } } @@ -751,30 +751,30 @@ private double z3(double t, double kappa, double theta,double delta, double y, d under the Heston model" M Forde, A Jacquier, R Lee - SIAM Journal on Financial Mathematics, 2012 - SIAM */ - public class FordeHestonExpansion : HestonExpansion + public class FordeHestonExpansion : HestonExpansion { - public FordeHestonExpansion(double kappa, double theta,double sigma, double v0,double rho, double term) + public FordeHestonExpansion(double kappa, double theta, double sigma, double v0, double rho, double term) { double v0Sqrt = Math.Sqrt(v0); double rhoBarSquare = 1 - rho * rho; double sigma00 = v0Sqrt; double sigma01 = v0Sqrt * (rho * sigma / (4 * v0)); //term in x - double sigma02 = v0Sqrt * ((1 - 5 * rho * rho / 2) / 24 * sigma * sigma/ (v0 * v0)); //term in x*x + double sigma02 = v0Sqrt * ((1 - 5 * rho * rho / 2) / 24 * sigma * sigma / (v0 * v0)); //term in x*x double a00 = -sigma * sigma / 12 * (1 - rho * rho / 4) + v0 * rho * sigma / 4 + kappa / 2 * (theta - v0); double a01 = rho * sigma / (24 * v0) * (sigma * sigma * rhoBarSquare - 2 * kappa * (theta + v0) + v0 * rho * sigma); //term in x double a02 = (176 * sigma * sigma - 480 * kappa * theta - 712 * rho * rho * sigma * sigma + 521 * rho * rho * rho * rho * sigma * sigma + 40 * sigma * rho * rho * rho * v0 + 1040 * kappa * theta * rho * rho - 80 * v0 * kappa * rho * rho) * sigma * sigma / (v0 * v0 * 7680); - coeffs[0] = sigma00*sigma00+a00*term; - coeffs[1] = sigma00*sigma01*2+a01*term; - coeffs[2] = sigma00*sigma02*2+sigma01*sigma01+a02*term; - coeffs[3] = sigma01*sigma02*2; - coeffs[4] = sigma02*sigma02; + coeffs[0] = sigma00 * sigma00 + a00 * term; + coeffs[1] = sigma00 * sigma01 * 2 + a01 * term; + coeffs[2] = sigma00 * sigma02 * 2 + sigma01 * sigma01 + a02 * term; + coeffs[3] = sigma01 * sigma02 * 2; + coeffs[4] = sigma02 * sigma02; } - public override double impliedVolatility(double strike,double forward) + public override double impliedVolatility(double strike, double forward) { - double x = Math.Log(strike/forward); - double var = coeffs[0]+x*(coeffs[1]+(x*(coeffs[2]+x*(coeffs[3]+(x*coeffs[4]))))); - var = Math.Max(1e-8,var); + double x = Math.Log(strike / forward); + double var = coeffs[0] + x * (coeffs[1] + (x * (coeffs[2] + x * (coeffs[3] + (x * coeffs[4]))))); + var = Math.Max(1e-8, var); return Math.Sqrt(var); } diff --git a/src/QLNet/Pricingengines/vanilla/Integralengine.cs b/src/QLNet/Pricingengines/vanilla/Integralengine.cs index 90fbf72a9..c99b15494 100644 --- a/src/QLNet/Pricingengines/vanilla/Integralengine.cs +++ b/src/QLNet/Pricingengines/vanilla/Integralengine.cs @@ -1,86 +1,87 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - - public class Integrand - { - private Payoff payoff_; - private double s0_; - private double drift_; - private double variance_; - - public Integrand(Payoff payoff, double s0, double drift, double variance) - { - payoff_ = payoff; - s0_ = s0; - drift_ = drift; - variance_ = variance; - } - public double value(double x) - { - double temp = s0_ * Math.Exp(x); - double result = payoff_.value(temp); - return result * Math.Exp(-(x - drift_) * (x - drift_) / (2.0 * variance_)); - } - } - - //! Pricing engine for European vanilla options using integral approach +namespace QLNet +{ + + public class Integrand + { + private Payoff payoff_; + private double s0_; + private double drift_; + private double variance_; + + public Integrand(Payoff payoff, double s0, double drift, double variance) + { + payoff_ = payoff; + s0_ = s0; + drift_ = drift; + variance_ = variance; + } + public double value(double x) + { + double temp = s0_ * Math.Exp(x); + double result = payoff_.value(temp); + return result * Math.Exp(-(x - drift_) * (x - drift_) / (2.0 * variance_)); + } + } + + //! Pricing engine for European vanilla options using integral approach // ! \todo define tolerance for calculate() // // \ingroup vanillaengines -// - public class IntegralEngine : VanillaOption.Engine - { - private GeneralizedBlackScholesProcess process_; +// + public class IntegralEngine : VanillaOption.Engine + { + private GeneralizedBlackScholesProcess process_; - public IntegralEngine(GeneralizedBlackScholesProcess process) - { - process_ = process; + public IntegralEngine(GeneralizedBlackScholesProcess process) + { + process_ = process; - process_.registerWith(update); - } + process_.registerWith(update); + } - public override void calculate() - { - Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European Option"); + public override void calculate() + { + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European Option"); - StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; + StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; - Utils.QL_REQUIRE(payoff != null, () => "not an European Option"); + Utils.QL_REQUIRE(payoff != null, () => "not an European Option"); - double variance = process_.blackVolatility().link.blackVariance(arguments_.exercise.lastDate(), payoff.strike()); + double variance = process_.blackVolatility().link.blackVariance(arguments_.exercise.lastDate(), payoff.strike()); - double dividendDiscount = process_.dividendYield().link.discount(arguments_.exercise.lastDate()); - double riskFreeDiscount = process_.riskFreeRate().link.discount(arguments_.exercise.lastDate()); - double drift = Math.Log(dividendDiscount / riskFreeDiscount) - 0.5 * variance; + double dividendDiscount = process_.dividendYield().link.discount(arguments_.exercise.lastDate()); + double riskFreeDiscount = process_.riskFreeRate().link.discount(arguments_.exercise.lastDate()); + double drift = Math.Log(dividendDiscount / riskFreeDiscount) - 0.5 * variance; - Integrand f = new Integrand(arguments_.payoff, process_.stateVariable().link.value(), drift, variance); - SegmentIntegral integrator = new SegmentIntegral(5000); + Integrand f = new Integrand(arguments_.payoff, process_.stateVariable().link.value(), drift, variance); + SegmentIntegral integrator = new SegmentIntegral(5000); - double infinity = 10.0 * Math.Sqrt(variance); - results_.value = process_.riskFreeRate().link.discount(arguments_.exercise.lastDate()) / - Math.Sqrt(2.0 * Math.PI * variance) * - integrator.value(f.value, drift - infinity, drift + infinity); - } - } + double infinity = 10.0 * Math.Sqrt(variance); + results_.value = process_.riskFreeRate().link.discount(arguments_.exercise.lastDate()) / + Math.Sqrt(2.0 * Math.PI * variance) * + integrator.value(f.value, drift - infinity, drift + infinity); + } + } } diff --git a/src/QLNet/Pricingengines/vanilla/Juquadraticengine.cs b/src/QLNet/Pricingengines/vanilla/Juquadraticengine.cs index 307bd4f66..b0bffcfa9 100644 --- a/src/QLNet/Pricingengines/vanilla/Juquadraticengine.cs +++ b/src/QLNet/Pricingengines/vanilla/Juquadraticengine.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -39,13 +39,13 @@ namespace QLNet // // \test the correctness of the returned value is tested by // reproducing results available in literature. - // + // public class JuQuadraticApproximationEngine : VanillaOption.Engine { // An Approximate Formula for Pricing American Options // Journal of Derivatives Winter 1999 // Ju, N. - // + // private GeneralizedBlackScholesProcess process_; @@ -57,23 +57,23 @@ public JuQuadraticApproximationEngine(GeneralizedBlackScholesProcess process) public override void calculate() { - Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.American,()=> "not an American Option"); + Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.American, () => "not an American Option"); AmericanExercise ex = arguments_.exercise as AmericanExercise; - Utils.QL_REQUIRE(ex != null,()=> "non-American exercise given"); + Utils.QL_REQUIRE(ex != null, () => "non-American exercise given"); - Utils.QL_REQUIRE(!ex.payoffAtExpiry(),()=> "payoff at expiry not handled"); + Utils.QL_REQUIRE(!ex.payoffAtExpiry(), () => "payoff at expiry not handled"); StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; - Utils.QL_REQUIRE(payoff != null,()=> "non-striked payoff given"); + Utils.QL_REQUIRE(payoff != null, () => "non-striked payoff given"); double variance = process_.blackVolatility().link.blackVariance(ex.lastDate(), payoff.strike()); double dividendDiscount = process_.dividendYield().link.discount(ex.lastDate()); double riskFreeDiscount = process_.riskFreeRate().link.discount(ex.lastDate()); double spot = process_.stateVariable().link.value(); - Utils.QL_REQUIRE(spot > 0.0,()=> "negative or null underlying given"); + Utils.QL_REQUIRE(spot > 0.0, () => "negative or null underlying given"); double forwardPrice = spot * dividendDiscount / riskFreeDiscount; BlackCalculator black = new BlackCalculator(payoff, forwardPrice, Math.Sqrt(variance), riskFreeDiscount); @@ -112,7 +112,7 @@ public override void calculate() double tolerance = 1e-6; double Sk = BaroneAdesiWhaleyApproximationEngine.criticalPrice(payoff, riskFreeDiscount, dividendDiscount, - variance, tolerance); + variance, tolerance); double forwardSk = Sk * dividendDiscount / riskFreeDiscount; diff --git a/src/QLNet/Pricingengines/vanilla/MCEuropeanHestonEngine.cs b/src/QLNet/Pricingengines/vanilla/MCEuropeanHestonEngine.cs index 71ffba3bb..cc5f3ed43 100644 --- a/src/QLNet/Pricingengines/vanilla/MCEuropeanHestonEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/MCEuropeanHestonEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,145 +23,145 @@ namespace QLNet reproducing results available in web/literature */ public class MCEuropeanHestonEngine : MCVanillaEngine - where RNG : IRSG, new() - where S : IGeneralStatistics, new() + where RNG : IRSG, new () + where S : IGeneralStatistics, new () { - public MCEuropeanHestonEngine( HestonProcess process, - int? timeSteps, - int? timeStepsPerYear, - bool antitheticVariate, - int? requiredSamples, - double? requiredTolerance, - int? maxSamples, - ulong seed) - :base( process, timeSteps, timeStepsPerYear,false, antitheticVariate, false,requiredSamples, requiredTolerance, - maxSamples, seed ) + public MCEuropeanHestonEngine(HestonProcess process, + int? timeSteps, + int? timeStepsPerYear, + bool antitheticVariate, + int? requiredSamples, + double? requiredTolerance, + int? maxSamples, + ulong seed) + : base(process, timeSteps, timeStepsPerYear, false, antitheticVariate, false, requiredSamples, requiredTolerance, + maxSamples, seed) {} protected override PathPricer pathPricer() { - PlainVanillaPayoff payoff= this.arguments_.payoff as PlainVanillaPayoff; - Utils.QL_REQUIRE(payoff!=null,()=> "non-plain payoff given"); + PlainVanillaPayoff payoff = this.arguments_.payoff as PlainVanillaPayoff; + Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); HestonProcess process = this.process_ as HestonProcess; - Utils.QL_REQUIRE(process!= null,()=> "Heston process required"); + Utils.QL_REQUIRE(process != null, () => "Heston process required"); - return new EuropeanHestonPathPricer( payoff.optionType(), - payoff.strike(), - process.riskFreeRate().link.discount(this.timeGrid().Last())); + return new EuropeanHestonPathPricer(payoff.optionType(), + payoff.strike(), + process.riskFreeRate().link.discount(this.timeGrid().Last())); } } //! Monte Carlo Heston European engine factory - public class MakeMCEuropeanHestonEngine - where RNG : IRSG, new() - where S : IGeneralStatistics, new() - { - public MakeMCEuropeanHestonEngine( HestonProcess process ) - { - process_ = process; - antithetic_ = false; - steps_ = null; - stepsPerYear_ = null; - samples_ = null; - maxSamples_ = null; - tolerance_ = null; - seed_ = 0; - - - } - // named parameters - public MakeMCEuropeanHestonEngine withSteps( int steps ) - { - Utils.QL_REQUIRE( stepsPerYear_ == null,()=> "number of steps per year already set" ); - steps_ = steps; - return this; - } - - public MakeMCEuropeanHestonEngine withStepsPerYear( int steps ) - { - Utils.QL_REQUIRE( steps_ == null,()=> "number of steps already set" ); - stepsPerYear_ = steps; - return this; - } - - public MakeMCEuropeanHestonEngine withSamples( int samples ) - { - Utils.QL_REQUIRE( tolerance_ == null,()=> "tolerance already set" ); - samples_ = samples; - return this; - } - - public MakeMCEuropeanHestonEngine withAbsoluteTolerance( double tolerance ) - { - Utils.QL_REQUIRE(samples_ == null,()=> "number of samples already set"); - Utils.QL_REQUIRE( FastActivator.Create().allowsErrorEstimate != 0, () => "chosen random generator policy does not allow an error estimate" ); - tolerance_ = tolerance; - return this; - } - - public MakeMCEuropeanHestonEngine withMaxSamples( int samples ) - { - maxSamples_ = samples; - return this; - } - - public MakeMCEuropeanHestonEngine withSeed( ulong seed ) - { - seed_ = seed; - return this; - } - - public MakeMCEuropeanHestonEngine withAntitheticVariate( bool b = true ) - { - antithetic_ = b; - return this; - } - - // conversion to pricing engine - public IPricingEngine getAsPricingEngine() - { - Utils.QL_REQUIRE(steps_ != null || stepsPerYear_ != null,()=> "number of steps not given"); - return new MCEuropeanHestonEngine(process_, + public class MakeMCEuropeanHestonEngine + where RNG : IRSG, new () + where S : IGeneralStatistics, new () + { + public MakeMCEuropeanHestonEngine(HestonProcess process) + { + process_ = process; + antithetic_ = false; + steps_ = null; + stepsPerYear_ = null; + samples_ = null; + maxSamples_ = null; + tolerance_ = null; + seed_ = 0; + + + } + // named parameters + public MakeMCEuropeanHestonEngine withSteps(int steps) + { + Utils.QL_REQUIRE(stepsPerYear_ == null, () => "number of steps per year already set"); + steps_ = steps; + return this; + } + + public MakeMCEuropeanHestonEngine withStepsPerYear(int steps) + { + Utils.QL_REQUIRE(steps_ == null, () => "number of steps already set"); + stepsPerYear_ = steps; + return this; + } + + public MakeMCEuropeanHestonEngine withSamples(int samples) + { + Utils.QL_REQUIRE(tolerance_ == null, () => "tolerance already set"); + samples_ = samples; + return this; + } + + public MakeMCEuropeanHestonEngine withAbsoluteTolerance(double tolerance) + { + Utils.QL_REQUIRE(samples_ == null, () => "number of samples already set"); + Utils.QL_REQUIRE(FastActivator.Create().allowsErrorEstimate != 0, () => "chosen random generator policy does not allow an error estimate"); + tolerance_ = tolerance; + return this; + } + + public MakeMCEuropeanHestonEngine withMaxSamples(int samples) + { + maxSamples_ = samples; + return this; + } + + public MakeMCEuropeanHestonEngine withSeed(ulong seed) + { + seed_ = seed; + return this; + } + + public MakeMCEuropeanHestonEngine withAntitheticVariate(bool b = true) + { + antithetic_ = b; + return this; + } + + // conversion to pricing engine + public IPricingEngine getAsPricingEngine() + { + Utils.QL_REQUIRE(steps_ != null || stepsPerYear_ != null, () => "number of steps not given"); + return new MCEuropeanHestonEngine(process_, steps_, stepsPerYear_, antithetic_, samples_, tolerance_, maxSamples_, seed_); - } + } - private HestonProcess process_; - private bool antithetic_; - private int? steps_, stepsPerYear_, samples_, maxSamples_; - private double? tolerance_; - private ulong seed_; - }; + private HestonProcess process_; + private bool antithetic_; + private int? steps_, stepsPerYear_, samples_, maxSamples_; + private double? tolerance_; + private ulong seed_; + } - public class EuropeanHestonPathPricer : PathPricer + public class EuropeanHestonPathPricer : PathPricer { - public EuropeanHestonPathPricer(Option.Type type, double strike,double discount) + public EuropeanHestonPathPricer(Option.Type type, double strike, double discount) { payoff_ = new PlainVanillaPayoff(type, strike); discount_ = discount; - Utils.QL_REQUIRE( strike >= 0.0,()=> "strike less than zero not allowed" ); + Utils.QL_REQUIRE(strike >= 0.0, () => "strike less than zero not allowed"); } - + public double value(IPath multiPath) { MultiPath m = multiPath as MultiPath; - Utils.QL_REQUIRE( m != null , () => "the path is invalid" ); + Utils.QL_REQUIRE(m != null, () => "the path is invalid"); Path path = m[0]; int n = m.pathSize(); - Utils.QL_REQUIRE(n>0,()=> "the path cannot be empty"); + Utils.QL_REQUIRE(n > 0, () => "the path cannot be empty"); - return payoff_.value(path.back()) * discount_; + return payoff_.value(path.back()) * discount_; } - + private PlainVanillaPayoff payoff_; private double discount_; } diff --git a/src/QLNet/Pricingengines/vanilla/MCHestonHullWhiteEngine.cs b/src/QLNet/Pricingengines/vanilla/MCHestonHullWhiteEngine.cs index d64dedec7..4c60a7e09 100644 --- a/src/QLNet/Pricingengines/vanilla/MCHestonHullWhiteEngine.cs +++ b/src/QLNet/Pricingengines/vanilla/MCHestonHullWhiteEngine.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -18,20 +18,20 @@ namespace QLNet { public class MCHestonHullWhiteEngine : MCVanillaEngine - where RNG : IRSG, new() - where S : IGeneralStatistics, new() + where RNG : IRSG, new () + where S : IGeneralStatistics, new () { - public MCHestonHullWhiteEngine( HybridHestonHullWhiteProcess process, - int? timeSteps, - int? timeStepsPerYear, - bool antitheticVariate, - bool controlVariate, - int? requiredSamples, - double? requiredTolerance, - int? maxSamples, - ulong seed) - :base(process, timeSteps, timeStepsPerYear,false, antitheticVariate,controlVariate, requiredSamples, - requiredTolerance, maxSamples, seed) + public MCHestonHullWhiteEngine(HybridHestonHullWhiteProcess process, + int? timeSteps, + int? timeStepsPerYear, + bool antitheticVariate, + bool controlVariate, + int? requiredSamples, + double? requiredTolerance, + int? maxSamples, + ulong seed) + : base(process, timeSteps, timeStepsPerYear, false, antitheticVariate, controlVariate, requiredSamples, + requiredTolerance, maxSamples, seed) { process_ = process; } @@ -40,55 +40,55 @@ public override void calculate() { base.calculate(); - if (this.controlVariate_) + if (this.controlVariate_) { // control variate might lead to small negative // option values for deep OTM options this.results_.value = Math.Max(0.0, this.results_.value.GetValueOrDefault()); } } - + protected override PathPricer pathPricer() { Exercise exercise = arguments_.exercise; - Utils.QL_REQUIRE(exercise.type() == Exercise.Type.European,()=> "only european exercise is supported"); + Utils.QL_REQUIRE(exercise.type() == Exercise.Type.European, () => "only european exercise is supported"); double exerciseTime = process_.time(exercise.lastDate()); - return new HestonHullWhitePathPricer(exerciseTime,this.arguments_.payoff,(HybridHestonHullWhiteProcess) process_); + return new HestonHullWhitePathPricer(exerciseTime, this.arguments_.payoff, (HybridHestonHullWhiteProcess) process_); } protected override PathPricer controlPathPricer() { HybridHestonHullWhiteProcess process = process_ as HybridHestonHullWhiteProcess; - Utils.QL_REQUIRE( process != null, () => "invalid process" ); + Utils.QL_REQUIRE(process != null, () => "invalid process"); HestonProcess hestonProcess = process.hestonProcess() ; - Utils.QL_REQUIRE(hestonProcess != null ,()=> - "first constituent of the joint stochastic process need to be of type HestonProcess"); + Utils.QL_REQUIRE(hestonProcess != null, () => + "first constituent of the joint stochastic process need to be of type HestonProcess"); Exercise exercise = this.arguments_.exercise; - Utils.QL_REQUIRE(exercise.type() == Exercise.Type.European,()=>"only european exercise is supported"); + Utils.QL_REQUIRE(exercise.type() == Exercise.Type.European, () => "only european exercise is supported"); double exerciseTime = process.time(exercise.lastDate()); - return new HestonHullWhitePathPricer(exerciseTime,this.arguments_.payoff,process) ; + return new HestonHullWhitePathPricer(exerciseTime, this.arguments_.payoff, process) ; } protected override IPricingEngine controlPricingEngine() { HybridHestonHullWhiteProcess process = process_ as HybridHestonHullWhiteProcess; - Utils.QL_REQUIRE( process != null, () => "invalid process" ); + Utils.QL_REQUIRE(process != null, () => "invalid process"); HestonProcess hestonProcess = process.hestonProcess(); HullWhiteForwardProcess hullWhiteProcess = process.hullWhiteProcess(); HestonModel hestonModel = new HestonModel(hestonProcess); - + HullWhite hwModel = new HullWhite(hestonProcess.riskFreeRate(), hullWhiteProcess.a(), hullWhiteProcess.sigma()); @@ -100,22 +100,22 @@ protected override IPathGenerator controlPathGenerator() { int dimensions = process_.factors(); TimeGrid grid = this.timeGrid(); - IRNG generator = (IRNG)new RNG().make_sequence_generator(dimensions*(grid.size()-1),this.seed_); + IRNG generator = (IRNG)new RNG().make_sequence_generator(dimensions * (grid.size() - 1), this.seed_); HybridHestonHullWhiteProcess process = process_ as HybridHestonHullWhiteProcess; - Utils.QL_REQUIRE( process != null , ()=> "invalid process"); - HybridHestonHullWhiteProcess cvProcess = new HybridHestonHullWhiteProcess( process.hestonProcess(), - process.hullWhiteProcess(), 0.0, process.discretization() ); + Utils.QL_REQUIRE(process != null, () => "invalid process"); + HybridHestonHullWhiteProcess cvProcess = new HybridHestonHullWhiteProcess(process.hestonProcess(), + process.hullWhiteProcess(), 0.0, process.discretization()); return new MultiPathGenerator(cvProcess, grid, generator, false) ; } } - + //! Monte Carlo Heston/Hull-White engine factory - public class MakeMCHestonHullWhiteEngine - where RNG : IRSG, new() - where S : IGeneralStatistics, new() + public class MakeMCHestonHullWhiteEngine + where RNG : IRSG, new () + where S : IGeneralStatistics, new () { - public MakeMCHestonHullWhiteEngine( HybridHestonHullWhiteProcess process) + public MakeMCHestonHullWhiteEngine(HybridHestonHullWhiteProcess process) { process_ = process; steps_ = null; @@ -128,46 +128,46 @@ public MakeMCHestonHullWhiteEngine( HybridHestonHullWhiteProcess process) seed_ = 0; } // named parameters - public MakeMCHestonHullWhiteEngine withSteps( int steps ) + public MakeMCHestonHullWhiteEngine withSteps(int steps) { steps_ = steps; return this; } - public MakeMCHestonHullWhiteEngine withStepsPerYear( int steps ) + public MakeMCHestonHullWhiteEngine withStepsPerYear(int steps) { stepsPerYear_ = steps; return this; } - public MakeMCHestonHullWhiteEngine withAntitheticVariate( bool b = true ) + public MakeMCHestonHullWhiteEngine withAntitheticVariate(bool b = true) { antithetic_ = b; return this; } - public MakeMCHestonHullWhiteEngine withControlVariate( bool b = true ) + public MakeMCHestonHullWhiteEngine withControlVariate(bool b = true) { controlVariate_ = b; return this; } - public MakeMCHestonHullWhiteEngine withSamples( int samples ) + public MakeMCHestonHullWhiteEngine withSamples(int samples) { - Utils.QL_REQUIRE( tolerance_ == null,()=> "tolerance already set" ); + Utils.QL_REQUIRE(tolerance_ == null, () => "tolerance already set"); samples_ = samples; return this; } - public MakeMCHestonHullWhiteEngine withAbsoluteTolerance( double tolerance ) + public MakeMCHestonHullWhiteEngine withAbsoluteTolerance(double tolerance) { - Utils.QL_REQUIRE(samples_ == null,()=> "number of samples already set"); - Utils.QL_REQUIRE( FastActivator.Create().allowsErrorEstimate != 0, () => - "chosen random generator policy does not allow an error estimate" ); + Utils.QL_REQUIRE(samples_ == null, () => "number of samples already set"); + Utils.QL_REQUIRE(FastActivator.Create().allowsErrorEstimate != 0, () => + "chosen random generator policy does not allow an error estimate"); tolerance_ = tolerance; return this; } - public MakeMCHestonHullWhiteEngine withMaxSamples( int samples ) + public MakeMCHestonHullWhiteEngine withMaxSamples(int samples) { maxSamples_ = samples; return this; } - public MakeMCHestonHullWhiteEngine withSeed( ulong seed ) + public MakeMCHestonHullWhiteEngine withSeed(ulong seed) { seed_ = seed; return this; @@ -175,19 +175,19 @@ public MakeMCHestonHullWhiteEngine withSeed( ulong seed ) // conversion to pricing engine public IPricingEngine getAsPricingEngine() { - Utils.QL_REQUIRE(steps_ != null || stepsPerYear_ != null,()=> "number of steps not given"); - Utils.QL_REQUIRE(steps_ == null || stepsPerYear_ == null,()=> "number of steps overspecified"); - return new MCHestonHullWhiteEngine(process_, - steps_, - stepsPerYear_, - antithetic_, - controlVariate_, - samples_, - tolerance_, - maxSamples_, - seed_); - } - + Utils.QL_REQUIRE(steps_ != null || stepsPerYear_ != null, () => "number of steps not given"); + Utils.QL_REQUIRE(steps_ == null || stepsPerYear_ == null, () => "number of steps overspecified"); + return new MCHestonHullWhiteEngine(process_, + steps_, + stepsPerYear_, + antithetic_, + controlVariate_, + samples_, + tolerance_, + maxSamples_, + seed_); + } + private HybridHestonHullWhiteProcess process_; private int? steps_, stepsPerYear_, samples_, maxSamples_; private bool antithetic_, controlVariate_; @@ -195,9 +195,9 @@ public IPricingEngine getAsPricingEngine() private ulong seed_; } - public class HestonHullWhitePathPricer : PathPricer + public class HestonHullWhitePathPricer : PathPricer { - public HestonHullWhitePathPricer( double exerciseTime,Payoff payoff,HybridHestonHullWhiteProcess process) + public HestonHullWhitePathPricer(double exerciseTime, Payoff payoff, HybridHestonHullWhiteProcess process) { exerciseTime_ = exerciseTime; payoff_ = payoff; @@ -207,18 +207,18 @@ public HestonHullWhitePathPricer( double exerciseTime,Payoff payoff,HybridHeston public double value(IPath path) { MultiPath p = path as MultiPath; - Utils.QL_REQUIRE( p != null , ()=> "invalid path"); + Utils.QL_REQUIRE(p != null, () => "invalid path"); - Utils.QL_REQUIRE(p.pathSize() > 0,()=> "the path cannot be empty"); + Utils.QL_REQUIRE(p.pathSize() > 0, () => "the path cannot be empty"); Vector states = new Vector(p.assetNumber()); - for (int j=0; j < states.size(); ++j) + for (int j = 0; j < states.size(); ++j) { - states[j] = p[j][p.pathSize()-1]; + states[j] = p[j][p.pathSize() - 1]; } - double df = 1.0/process_.numeraire(exerciseTime_, states); - return payoff_.value(states[0])*df; + double df = 1.0 / process_.numeraire(exerciseTime_, states); + return payoff_.value(states[0]) * df; } private double exerciseTime_; diff --git a/src/QLNet/Pricingengines/vanilla/mcamericanengine.cs b/src/QLNet/Pricingengines/vanilla/McAmericanEngine.cs similarity index 53% rename from src/QLNet/Pricingengines/vanilla/mcamericanengine.cs rename to src/QLNet/Pricingengines/vanilla/McAmericanEngine.cs index 182ded1f5..9bc9c6222 100644 --- a/src/QLNet/Pricingengines/vanilla/mcamericanengine.cs +++ b/src/QLNet/Pricingengines/vanilla/McAmericanEngine.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -31,28 +31,28 @@ namespace QLNet reproducing results available in web/literature */ public class MCAmericanEngine : MCLongstaffSchwartzEngine - where RNG : IRSG, new() - where S : IGeneralStatistics, new() + where RNG : IRSG, new () + where S : IGeneralStatistics, new () { private int polynomOrder_; private LsmBasisSystem.PolynomType polynomType_; - // int nCalibrationSamples = Null()) - public MCAmericanEngine( GeneralizedBlackScholesProcess process, - int? timeSteps, - int? timeStepsPerYear, - bool antitheticVariate, - bool controlVariate, - int? requiredSamples, - double? requiredTolerance, - int? maxSamples, - ulong seed, - int polynomOrder, - LsmBasisSystem.PolynomType polynomType, - int nCalibrationSamples ) - : base( process, timeSteps, timeStepsPerYear, false, antitheticVariate, controlVariate, requiredSamples, - requiredTolerance, maxSamples, seed, nCalibrationSamples ) + // int nCalibrationSamples = Null()) + public MCAmericanEngine(GeneralizedBlackScholesProcess process, + int? timeSteps, + int? timeStepsPerYear, + bool antitheticVariate, + bool controlVariate, + int? requiredSamples, + double? requiredTolerance, + int? maxSamples, + ulong seed, + int polynomOrder, + LsmBasisSystem.PolynomType polynomType, + int nCalibrationSamples) + : base(process, timeSteps, timeStepsPerYear, false, antitheticVariate, controlVariate, requiredSamples, + requiredTolerance, maxSamples, seed, nCalibrationSamples) { polynomOrder_ = polynomOrder; polynomType_ = polynomType; @@ -62,37 +62,37 @@ public MCAmericanEngine( GeneralizedBlackScholesProcess process, public override void calculate() { base.calculate(); - if ( controlVariate_ ) + if (controlVariate_) { // control variate might lead to small negative // option values for deep OTM options - this.results_.value = Math.Max( 0.0, this.results_.value.Value ); + this.results_.value = Math.Max(0.0, this.results_.value.Value); } } protected override LongstaffSchwartzPathPricer lsmPathPricer() { GeneralizedBlackScholesProcess process = process_ as GeneralizedBlackScholesProcess; - Utils.QL_REQUIRE( process != null ,()=> "generalized Black-Scholes process required" ); + Utils.QL_REQUIRE(process != null, () => "generalized Black-Scholes process required"); EarlyExercise exercise = arguments_.exercise as EarlyExercise; - Utils.QL_REQUIRE( exercise != null,()=> "wrong exercise given" ); - Utils.QL_REQUIRE( !exercise.payoffAtExpiry(),()=> "payoff at expiry not handled" ); + Utils.QL_REQUIRE(exercise != null, () => "wrong exercise given"); + Utils.QL_REQUIRE(!exercise.payoffAtExpiry(), () => "payoff at expiry not handled"); - AmericanPathPricer earlyExercisePathPricer = new AmericanPathPricer( arguments_.payoff, polynomOrder_, polynomType_ ); + AmericanPathPricer earlyExercisePathPricer = new AmericanPathPricer(arguments_.payoff, polynomOrder_, polynomType_); - return new LongstaffSchwartzPathPricer( timeGrid(), earlyExercisePathPricer, process.riskFreeRate() ); + return new LongstaffSchwartzPathPricer(timeGrid(), earlyExercisePathPricer, process.riskFreeRate()); } protected override double? controlVariateValue() { IPricingEngine controlPE = controlPricingEngine(); - Utils.QL_REQUIRE( controlPE != null ,()=> "engine does not provide control variation pricing engine" ); + Utils.QL_REQUIRE(controlPE != null, () => "engine does not provide control variation pricing engine"); VanillaOption.Arguments controlArguments = controlPE.getArguments() as VanillaOption.Arguments; controlArguments = arguments_; - controlArguments.exercise = new EuropeanExercise( arguments_.exercise.lastDate() ); + controlArguments.exercise = new EuropeanExercise(arguments_.exercise.lastDate()); controlPE.calculate(); @@ -104,21 +104,21 @@ protected override LongstaffSchwartzPathPricer lsmPathPricer() protected override IPricingEngine controlPricingEngine() { GeneralizedBlackScholesProcess process = process_ as GeneralizedBlackScholesProcess; - Utils.QL_REQUIRE( process != null,()=> "generalized Black-Scholes process required" ); + Utils.QL_REQUIRE(process != null, () => "generalized Black-Scholes process required"); - return new AnalyticEuropeanEngine( process ); + return new AnalyticEuropeanEngine(process); } protected override PathPricer controlPathPricer() { StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; - Utils.QL_REQUIRE( payoff != null,()=> "StrikedTypePayoff needed for control variate" ); + Utils.QL_REQUIRE(payoff != null, () => "StrikedTypePayoff needed for control variate"); GeneralizedBlackScholesProcess process = process_ as GeneralizedBlackScholesProcess; - Utils.QL_REQUIRE( process != null,()=> "generalized Black-Scholes process required" ); + Utils.QL_REQUIRE(process != null, () => "generalized Black-Scholes process required"); - return new EuropeanPathPricer( payoff.optionType(), payoff.strike(), - process.riskFreeRate().link.discount( timeGrid().Last() ) ); + return new EuropeanPathPricer(payoff.optionType(), payoff.strike(), + process.riskFreeRate().link.discount(timeGrid().Last())); } } @@ -129,61 +129,61 @@ public class AmericanPathPricer : IEarlyExercisePathPricer protected Payoff payoff_; protected List> v_ = new List>(); - public AmericanPathPricer( Payoff payoff, int polynomOrder, LsmBasisSystem.PolynomType polynomType ) + public AmericanPathPricer(Payoff payoff, int polynomOrder, LsmBasisSystem.PolynomType polynomType) { scalingValue_ = 1; payoff_ = payoff; - v_ = LsmBasisSystem.pathBasisSystem( polynomOrder, polynomType ); + v_ = LsmBasisSystem.pathBasisSystem(polynomOrder, polynomType); - Utils.QL_REQUIRE( ( polynomType == LsmBasisSystem.PolynomType.Monomial - || polynomType == LsmBasisSystem.PolynomType.Laguerre - || polynomType == LsmBasisSystem.PolynomType.Hermite - || polynomType == LsmBasisSystem.PolynomType.Hyperbolic - || polynomType == LsmBasisSystem.PolynomType.Chebyshev2th ) ,()=> "insufficient polynom type" ); + Utils.QL_REQUIRE((polynomType == LsmBasisSystem.PolynomType.Monomial + || polynomType == LsmBasisSystem.PolynomType.Laguerre + || polynomType == LsmBasisSystem.PolynomType.Hermite + || polynomType == LsmBasisSystem.PolynomType.Hyperbolic + || polynomType == LsmBasisSystem.PolynomType.Chebyshev2th), () => "insufficient polynom type"); // the payoff gives an additional value - v_.Add( this.payoff ); + v_.Add(this.payoff); StrikedTypePayoff strikePayoff = payoff_ as StrikedTypePayoff; - if ( strikePayoff != null ) + if (strikePayoff != null) { scalingValue_ /= strikePayoff.strike(); } } // scale values of the underlying to increase numerical stability - public double state( IPath path, int t ) { return ( path as Path )[t] * scalingValue_; } - public double value( IPath path, int t ) { return payoff( state( path, t ) ); } + public double state(IPath path, int t) { return (path as Path)[t] * scalingValue_; } + public double value(IPath path, int t) { return payoff(state(path, t)); } public List> basisSystem() { return v_; } - protected double payoff( double state ) { return payoff_.value( state / scalingValue_ ); } + protected double payoff(double state) { return payoff_.value(state / scalingValue_); } } //! Monte Carlo American engine factory //template public class MakeMCAmericanEngine : MakeMCAmericanEngine - where RNG : IRSG, new() + where RNG : IRSG, new () { - public MakeMCAmericanEngine( GeneralizedBlackScholesProcess process ) : base( process ) { } + public MakeMCAmericanEngine(GeneralizedBlackScholesProcess process) : base(process) { } } public class MakeMCAmericanEngine - where RNG : IRSG, new() - where S : IGeneralStatistics, new() + where RNG : IRSG, new () + where S : IGeneralStatistics, new () { private GeneralizedBlackScholesProcess process_; private bool antithetic_, controlVariate_; private int? steps_, stepsPerYear_; - private int? samples_, maxSamples_; + private int? samples_, maxSamples_; private int calibrationSamples_; private double? tolerance_; private ulong seed_; private int polynomOrder_; private LsmBasisSystem.PolynomType polynomType_; - public MakeMCAmericanEngine( GeneralizedBlackScholesProcess process ) + public MakeMCAmericanEngine(GeneralizedBlackScholesProcess process) { process_ = process; antithetic_ = false; @@ -200,63 +200,63 @@ public MakeMCAmericanEngine( GeneralizedBlackScholesProcess process ) } // named parameters - public MakeMCAmericanEngine withSteps( int steps ) + public MakeMCAmericanEngine withSteps(int steps) { steps_ = steps; return this; } - public MakeMCAmericanEngine withStepsPerYear( int steps ) + public MakeMCAmericanEngine withStepsPerYear(int steps) { stepsPerYear_ = steps; return this; } - public MakeMCAmericanEngine withSamples( int samples ) + public MakeMCAmericanEngine withSamples(int samples) { - Utils.QL_REQUIRE( tolerance_ == null,()=> "tolerance already set" ); + Utils.QL_REQUIRE(tolerance_ == null, () => "tolerance already set"); samples_ = samples; return this; } - public MakeMCAmericanEngine withAbsoluteTolerance( double tolerance ) + public MakeMCAmericanEngine withAbsoluteTolerance(double tolerance) { - Utils.QL_REQUIRE(samples_ == null,()=> "number of samples already set"); - Utils.QL_REQUIRE( FastActivator.Create().allowsErrorEstimate != 0, () => "chosen random generator policy does not allow an error estimate" ); + Utils.QL_REQUIRE(samples_ == null, () => "number of samples already set"); + Utils.QL_REQUIRE(FastActivator.Create().allowsErrorEstimate != 0, () => "chosen random generator policy does not allow an error estimate"); tolerance_ = tolerance; return this; } - public MakeMCAmericanEngine withMaxSamples( int samples ) + public MakeMCAmericanEngine withMaxSamples(int samples) { maxSamples_ = samples; return this; } - public MakeMCAmericanEngine withSeed( ulong seed ) + public MakeMCAmericanEngine withSeed(ulong seed) { seed_ = seed; return this; } - public MakeMCAmericanEngine withAntitheticVariate() { return withAntitheticVariate( true ); } - public MakeMCAmericanEngine withAntitheticVariate( bool b ) + public MakeMCAmericanEngine withAntitheticVariate() { return withAntitheticVariate(true); } + public MakeMCAmericanEngine withAntitheticVariate(bool b) { antithetic_ = b; return this; } - public MakeMCAmericanEngine withControlVariate( bool b ) + public MakeMCAmericanEngine withControlVariate(bool b) { controlVariate_ = b; return this; } - public MakeMCAmericanEngine withPolynomOrder( int polynomOrder ) + public MakeMCAmericanEngine withPolynomOrder(int polynomOrder) { polynomOrder_ = polynomOrder; return this; } - public MakeMCAmericanEngine withBasisSystem( LsmBasisSystem.PolynomType polynomType ) + public MakeMCAmericanEngine withBasisSystem(LsmBasisSystem.PolynomType polynomType) { polynomType_ = polynomType; return this; } - public MakeMCAmericanEngine withCalibrationSamples( int samples ) + public MakeMCAmericanEngine withCalibrationSamples(int samples) { calibrationSamples_ = samples; return this; @@ -265,11 +265,11 @@ public MakeMCAmericanEngine withCalibrationSamples( int samples ) // conversion to pricing engine public IPricingEngine value() { - Utils.QL_REQUIRE( steps_ != null || stepsPerYear_ != null,() => "number of steps not given" ); - Utils.QL_REQUIRE( steps_ == null || stepsPerYear_ == null,()=> "number of steps overspecified" ); + Utils.QL_REQUIRE(steps_ != null || stepsPerYear_ != null, () => "number of steps not given"); + Utils.QL_REQUIRE(steps_ == null || stepsPerYear_ == null, () => "number of steps overspecified"); - return new MCAmericanEngine( process_, steps_, stepsPerYear_, antithetic_, controlVariate_, samples_, tolerance_, - maxSamples_, seed_, polynomOrder_, polynomType_, calibrationSamples_ ); + return new MCAmericanEngine(process_, steps_, stepsPerYear_, antithetic_, controlVariate_, samples_, tolerance_, + maxSamples_, seed_, polynomOrder_, polynomType_, calibrationSamples_); } } } diff --git a/src/QLNet/Pricingengines/vanilla/mceuropeanengine.cs b/src/QLNet/Pricingengines/vanilla/McEuropeanEngine.cs similarity index 51% rename from src/QLNet/Pricingengines/vanilla/mceuropeanengine.cs rename to src/QLNet/Pricingengines/vanilla/McEuropeanEngine.cs index a6daea4a2..3e8df3fc0 100644 --- a/src/QLNet/Pricingengines/vanilla/mceuropeanengine.cs +++ b/src/QLNet/Pricingengines/vanilla/McEuropeanEngine.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -28,49 +28,49 @@ namespace QLNet checking it against analytic results. */ public class MCEuropeanEngine : MCVanillaEngine - where RNG : IRSG, new() - where S : IGeneralStatistics, new() + where RNG : IRSG, new () + where S : IGeneralStatistics, new () { // constructor - public MCEuropeanEngine( GeneralizedBlackScholesProcess process, - int? timeSteps, - int? timeStepsPerYear, - bool brownianBridge, - bool antitheticVariate, - int? requiredSamples, - double? requiredTolerance, - int? maxSamples, - ulong seed ) - : base( process, timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, false, - requiredSamples, requiredTolerance, maxSamples, seed ) { } + public MCEuropeanEngine(GeneralizedBlackScholesProcess process, + int? timeSteps, + int? timeStepsPerYear, + bool brownianBridge, + bool antitheticVariate, + int? requiredSamples, + double? requiredTolerance, + int? maxSamples, + ulong seed) + : base(process, timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, false, + requiredSamples, requiredTolerance, maxSamples, seed) { } protected override PathPricer pathPricer() { PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; - Utils.QL_REQUIRE( payoff != null,()=> "non-plain payoff given" ); + Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); GeneralizedBlackScholesProcess process = process_ as GeneralizedBlackScholesProcess; - Utils.QL_REQUIRE( process!= null,()=> "Black-Scholes process required" ); + Utils.QL_REQUIRE(process != null, () => "Black-Scholes process required"); - return new EuropeanPathPricer( payoff.optionType(), payoff.strike(), - process.riskFreeRate().link.discount( timeGrid().Last() ) ); + return new EuropeanPathPricer(payoff.optionType(), payoff.strike(), + process.riskFreeRate().link.discount(timeGrid().Last())); } } //! Monte Carlo European engine factory // template - public class MakeMCEuropeanEngine : MakeMCEuropeanEngine where RNG : IRSG, new() + public class MakeMCEuropeanEngine : MakeMCEuropeanEngine where RNG : IRSG, new () { - public MakeMCEuropeanEngine( GeneralizedBlackScholesProcess process ) : base( process ) { } + public MakeMCEuropeanEngine(GeneralizedBlackScholesProcess process) : base(process) { } } public class MakeMCEuropeanEngine - where RNG : IRSG, new() - where S : IGeneralStatistics, new() + where RNG : IRSG, new () + where S : IGeneralStatistics, new () { - public MakeMCEuropeanEngine( GeneralizedBlackScholesProcess process ) + public MakeMCEuropeanEngine(GeneralizedBlackScholesProcess process) { process_ = process; antithetic_ = false; @@ -84,46 +84,46 @@ public MakeMCEuropeanEngine( GeneralizedBlackScholesProcess process ) } // named parameters - public MakeMCEuropeanEngine withSteps( int steps ) + public MakeMCEuropeanEngine withSteps(int steps) { steps_ = steps; return this; } - public MakeMCEuropeanEngine withStepsPerYear( int steps ) + public MakeMCEuropeanEngine withStepsPerYear(int steps) { stepsPerYear_ = steps; return this; } - public MakeMCEuropeanEngine withSamples( int samples ) + public MakeMCEuropeanEngine withSamples(int samples) { - Utils.QL_REQUIRE( tolerance_ == null,()=> "tolerance already set" ); + Utils.QL_REQUIRE(tolerance_ == null, () => "tolerance already set"); samples_ = samples; return this; } - public MakeMCEuropeanEngine withAbsoluteTolerance( double tolerance ) + public MakeMCEuropeanEngine withAbsoluteTolerance(double tolerance) { - Utils.QL_REQUIRE( samples_ == null, () => "number of samples already set" ); - Utils.QL_REQUIRE( FastActivator.Create().allowsErrorEstimate != 0, () => - "chosen random generator policy does not allow an error estimate" ); + Utils.QL_REQUIRE(samples_ == null, () => "number of samples already set"); + Utils.QL_REQUIRE(FastActivator.Create().allowsErrorEstimate != 0, () => + "chosen random generator policy does not allow an error estimate"); tolerance_ = tolerance; return this; } - public MakeMCEuropeanEngine withMaxSamples( int samples ) + public MakeMCEuropeanEngine withMaxSamples(int samples) { maxSamples_ = samples; return this; } - public MakeMCEuropeanEngine withSeed( ulong seed ) + public MakeMCEuropeanEngine withSeed(ulong seed) { seed_ = seed; return this; } - public MakeMCEuropeanEngine withBrownianBridge( bool brownianBridge = true) + public MakeMCEuropeanEngine withBrownianBridge(bool brownianBridge = true) { brownianBridge_ = brownianBridge; return this; } - public MakeMCEuropeanEngine withAntitheticVariate( bool b = true) + public MakeMCEuropeanEngine withAntitheticVariate(bool b = true) { antithetic_ = b; return this; @@ -132,10 +132,10 @@ public MakeMCEuropeanEngine withAntitheticVariate( bool b = true) // conversion to pricing engine public IPricingEngine value() { - Utils.QL_REQUIRE( steps_ != null || stepsPerYear_ != null,()=>"number of steps not given" ); - Utils.QL_REQUIRE( steps_ == null || stepsPerYear_ == null,()=>"number of steps overspecified" ); - return new MCEuropeanEngine( process_, steps_, stepsPerYear_, brownianBridge_, antithetic_, - samples_, tolerance_, maxSamples_, seed_ ); + Utils.QL_REQUIRE(steps_ != null || stepsPerYear_ != null, () => "number of steps not given"); + Utils.QL_REQUIRE(steps_ == null || stepsPerYear_ == null, () => "number of steps overspecified"); + return new MCEuropeanEngine(process_, steps_, stepsPerYear_, brownianBridge_, antithetic_, + samples_, tolerance_, maxSamples_, seed_); } private GeneralizedBlackScholesProcess process_; @@ -150,17 +150,17 @@ public IPricingEngine value() public class EuropeanPathPricer : PathPricer { - public EuropeanPathPricer( Option.Type type, double strike, double discount ) + public EuropeanPathPricer(Option.Type type, double strike, double discount) { - payoff_ = new PlainVanillaPayoff( type, strike ); + payoff_ = new PlainVanillaPayoff(type, strike); discount_ = discount; - Utils.QL_REQUIRE( strike >= 0.0,()=> "strike less than zero not allowed" ); + Utils.QL_REQUIRE(strike >= 0.0, () => "strike less than zero not allowed"); } - public double value( IPath path ) + public double value(IPath path) { - Utils.QL_REQUIRE( path.length() > 0,()=> "the path cannot be empty" ); - return payoff_.value( ( path as Path ).back() ) * discount_; + Utils.QL_REQUIRE(path.length() > 0, () => "the path cannot be empty"); + return payoff_.value((path as Path).back()) * discount_; } private PlainVanillaPayoff payoff_; diff --git a/src/QLNet/Pricingengines/vanilla/mcvanillaengine.cs b/src/QLNet/Pricingengines/vanilla/McVanillaEngine.cs similarity index 50% rename from src/QLNet/Pricingengines/vanilla/mcvanillaengine.cs rename to src/QLNet/Pricingengines/vanilla/McVanillaEngine.cs index fcd0d3d32..bd430552f 100644 --- a/src/QLNet/Pricingengines/vanilla/mcvanillaengine.cs +++ b/src/QLNet/Pricingengines/vanilla/McVanillaEngine.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,26 +24,26 @@ namespace QLNet //! Pricing engine for vanilla options using Monte Carlo simulation /*! \ingroup vanillaengines */ public abstract class MCVanillaEngine : MCVanillaEngine - where RNG : IRSG, new() - where S : IGeneralStatistics, new() + where RNG : IRSG, new () + where S : IGeneralStatistics, new () { - protected MCVanillaEngine( StochasticProcess process, - int? timeSteps, - int? timeStepsPerYear, - bool brownianBridge, - bool antitheticVariate, - bool controlVariate, - int? requiredSamples, - double? requiredTolerance, - int? maxSamples, - ulong seed ) - : base( process, timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, controlVariate, requiredSamples, - requiredTolerance, maxSamples, seed ) { } + protected MCVanillaEngine(StochasticProcess process, + int? timeSteps, + int? timeStepsPerYear, + bool brownianBridge, + bool antitheticVariate, + bool controlVariate, + int? requiredSamples, + double? requiredTolerance, + int? maxSamples, + ulong seed) + : base(process, timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, controlVariate, requiredSamples, + requiredTolerance, maxSamples, seed) { } } public abstract class MCVanillaEngine : McSimulation, IGenericEngine - where RNG : IRSG, new() - where S : IGeneralStatistics, new() + where RNG : IRSG, new () + where S : IGeneralStatistics, new () { protected StochasticProcess process_; protected int? timeSteps_, timeStepsPerYear_; @@ -53,17 +53,17 @@ public abstract class MCVanillaEngine : McSimulation "no time steps provided" ); - Utils.QL_REQUIRE( timeSteps == null || timeStepsPerYear == null, () => - "both time steps and time steps per year were provided" ); - if ( timeSteps != null ) - Utils.QL_REQUIRE( timeSteps > 0, () => "timeSteps must be positive, " + timeSteps + " not allowed" ); - if ( timeStepsPerYear != null ) - Utils.QL_REQUIRE( timeStepsPerYear > 0, () => - "timeStepsPerYear must be positive, " + timeStepsPerYear + " not allowed" ); + Utils.QL_REQUIRE(timeSteps != null || timeStepsPerYear != null, () => "no time steps provided"); + Utils.QL_REQUIRE(timeSteps == null || timeStepsPerYear == null, () => + "both time steps and time steps per year were provided"); + if (timeSteps != null) + Utils.QL_REQUIRE(timeSteps > 0, () => "timeSteps must be positive, " + timeSteps + " not allowed"); + if (timeStepsPerYear != null) + Utils.QL_REQUIRE(timeStepsPerYear > 0, () => + "timeStepsPerYear must be positive, " + timeStepsPerYear + " not allowed"); - process_.registerWith( update ); + process_.registerWith(update); } public virtual void calculate() { - base.calculate( requiredTolerance_, requiredSamples_, maxSamples_ ); + base.calculate(requiredTolerance_, requiredSamples_, maxSamples_); results_.value = mcModel_.sampleAccumulator().mean(); - if ( FastActivator.Create().allowsErrorEstimate != 0 ) + if (FastActivator.Create().allowsErrorEstimate != 0) results_.errorEstimate = mcModel_.sampleAccumulator().errorEstimate(); } @@ -99,19 +99,19 @@ public virtual void calculate() protected override TimeGrid timeGrid() { Date lastExerciseDate = arguments_.exercise.lastDate(); - double t = process_.time( lastExerciseDate ); - if ( timeSteps_ != null ) + double t = process_.time(lastExerciseDate); + if (timeSteps_ != null) { - return new TimeGrid( t, timeSteps_.Value ); + return new TimeGrid(t, timeSteps_.Value); } - else if ( timeStepsPerYear_ != null ) + else if (timeStepsPerYear_ != null) { - int steps = (int)( timeStepsPerYear_ * t ); - return new TimeGrid( t, Math.Max( steps, 1 ) ); + int steps = (int)(timeStepsPerYear_ * t); + return new TimeGrid(t, Math.Max(steps, 1)); } else { - Utils.QL_FAIL( "time steps not specified" ); + Utils.QL_FAIL("time steps not specified"); return null; } } @@ -120,26 +120,26 @@ protected override IPathGenerator pathGenerator() { int dimensions = process_.factors(); TimeGrid grid = timeGrid(); - IRNG generator = (IRNG) FastActivator.Create().make_sequence_generator( dimensions * ( grid.size() - 1 ), seed_ ); - if ( typeof( MC ) == typeof( SingleVariate ) ) - return new PathGenerator( process_, grid, generator, brownianBridge_ ); + IRNG generator = (IRNG) FastActivator.Create().make_sequence_generator(dimensions * (grid.size() - 1), seed_); + if (typeof(MC) == typeof(SingleVariate)) + return new PathGenerator(process_, grid, generator, brownianBridge_); - return new MultiPathGenerator( process_, grid, generator, brownianBridge_ ); + return new MultiPathGenerator(process_, grid, generator, brownianBridge_); } protected override double? controlVariateValue() { AnalyticHestonHullWhiteEngine controlPE = controlPricingEngine() as AnalyticHestonHullWhiteEngine; - Utils.QL_REQUIRE( controlPE != null,()=> "engine does not provide control variation pricing engine" ); + Utils.QL_REQUIRE(controlPE != null, () => "engine does not provide control variation pricing engine"); OneAssetOption.Arguments controlArguments = controlPE.getArguments() as VanillaOption.Arguments; - Utils.QL_REQUIRE( controlArguments != null,()=> "engine is using inconsistent arguments" ); + Utils.QL_REQUIRE(controlArguments != null, () => "engine is using inconsistent arguments"); - controlPE.setupArguments( arguments_ ); + controlPE.setupArguments(arguments_); controlPE.calculate(); OneAssetOption.Results controlResults = controlPE.getResults() as VanillaOption.Results; - Utils.QL_REQUIRE( controlResults != null,()=> "engine returns an inconsistent result type" ); + Utils.QL_REQUIRE(controlResults != null, () => "engine returns an inconsistent result type"); return controlResults.value; } @@ -157,12 +157,18 @@ protected override IPathGenerator pathGenerator() private readonly WeakEventSource eventSource = new WeakEventSource(); public event Callback notifyObserversEvent { - add { eventSource.Subscribe( value ); } - remove { eventSource.Unsubscribe( value ); } + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } } - public void registerWith( Callback handler ) { notifyObserversEvent += handler; } - public void unregisterWith( Callback handler ) { notifyObserversEvent -= handler; } + public void registerWith(Callback handler) { notifyObserversEvent += handler; } + public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } protected void notifyObservers() { eventSource.Raise(); diff --git a/src/QLNet/Pricingengines/vanilla/baroneadesiwhaleyengine.cs b/src/QLNet/Pricingengines/vanilla/baroneadesiwhaleyengine.cs deleted file mode 100644 index 6fff44d86..000000000 --- a/src/QLNet/Pricingengines/vanilla/baroneadesiwhaleyengine.cs +++ /dev/null @@ -1,222 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! Barone-Adesi and Whaley pricing engine for American options (1987) - /*! \ingroup vanillaengines - - \test the correctness of the returned value is tested by - reproducing results available in literature. - */ - public class BaroneAdesiWhaleyApproximationEngine : VanillaOption.Engine { - private GeneralizedBlackScholesProcess process_; - - public BaroneAdesiWhaleyApproximationEngine(GeneralizedBlackScholesProcess process) { - process_ = process; - - process_.registerWith(update); - } - - // critical commodity price - public static double criticalPrice(StrikedTypePayoff payoff, double riskFreeDiscount, double dividendDiscount, - double variance, double tolerance) { - - // Calculation of seed value, Si - double n= 2.0*Math.Log(dividendDiscount/riskFreeDiscount)/(variance); - double m= -2.0*Math.Log(riskFreeDiscount)/(variance); - double bT = Math.Log(dividendDiscount/riskFreeDiscount); - - double qu, Su, h, Si = 0; - switch (payoff.optionType()) { - case Option.Type.Call: - qu = (-(n-1.0) + Math.Sqrt(((n-1.0)*(n-1.0)) + 4.0*m))/2.0; - Su = payoff.strike() / (1.0 - 1.0/qu); - h = -(bT + 2.0*Math.Sqrt(variance)) * payoff.strike() / - (Su - payoff.strike()); - Si = payoff.strike() + (Su - payoff.strike()) * - (1.0 - Math.Exp(h)); - break; - case Option.Type.Put: - qu = (-(n-1.0) - Math.Sqrt(((n-1.0)*(n-1.0)) + 4.0*m))/2.0; - Su = payoff.strike() / (1.0 - 1.0/qu); - h = (bT - 2.0*Math.Sqrt(variance)) * payoff.strike() / - (payoff.strike() - Su); - Si = Su + (payoff.strike() - Su) * Math.Exp(h); - break; - default: - Utils.QL_FAIL("unknown option type"); - break; - } - - - // Newton Raphson algorithm for finding critical price Si - double Q, LHS, RHS, bi; - double forwardSi = Si * dividendDiscount / riskFreeDiscount; - double d1 = (Math.Log(forwardSi/payoff.strike()) + 0.5*variance) / - Math.Sqrt(variance); - CumulativeNormalDistribution cumNormalDist = new CumulativeNormalDistribution(); - double K = ( !Utils.close( riskFreeDiscount, 1.0, 1000 ) ) - ? -2.0 * Math.Log( riskFreeDiscount ) - / ( variance * ( 1.0 - riskFreeDiscount ) ) - : 2.0 / variance; - - double temp = Utils.blackFormula(payoff.optionType(), payoff.strike(), - forwardSi, Math.Sqrt(variance))*riskFreeDiscount; - switch (payoff.optionType()) { - case Option.Type.Call: - Q = (-(n-1.0) + Math.Sqrt(((n-1.0)*(n-1.0)) + 4 * K)) / 2; - LHS = Si - payoff.strike(); - RHS = temp + (1 - dividendDiscount * cumNormalDist.value(d1)) * Si / Q; - bi = dividendDiscount * cumNormalDist.value(d1) * (1 - 1 / Q) + - (1 - dividendDiscount * - cumNormalDist.derivative(d1) / Math.Sqrt(variance)) / Q; - while (Math.Abs(LHS - RHS)/payoff.strike() > tolerance) { - Si = (payoff.strike() + RHS - bi * Si) / (1 - bi); - forwardSi = Si * dividendDiscount / riskFreeDiscount; - d1 = (Math.Log(forwardSi/payoff.strike())+0.5*variance) - /Math.Sqrt(variance); - LHS = Si - payoff.strike(); - double temp2 = Utils.blackFormula(payoff.optionType(), payoff.strike(), - forwardSi, Math.Sqrt(variance))*riskFreeDiscount; - RHS = temp2 + (1 - dividendDiscount * cumNormalDist.value(d1)) * Si / Q; - bi = dividendDiscount * cumNormalDist.value(d1) * (1 - 1 / Q) - + (1 - dividendDiscount * - cumNormalDist.derivative(d1) / Math.Sqrt(variance)) - / Q; - } - break; - case Option.Type.Put: - Q = (-(n-1.0) - Math.Sqrt(((n-1.0)*(n-1.0)) + 4 * K)) / 2; - LHS = payoff.strike() - Si; - RHS = temp - (1 - dividendDiscount * cumNormalDist.value(-d1)) * Si / Q; - bi = -dividendDiscount * cumNormalDist.value(-d1) * (1 - 1 / Q) - - (1 + dividendDiscount * cumNormalDist.derivative(-d1) - / Math.Sqrt(variance)) / Q; - while (Math.Abs(LHS - RHS)/payoff.strike() > tolerance) { - Si = (payoff.strike() - RHS + bi * Si) / (1 + bi); - forwardSi = Si * dividendDiscount / riskFreeDiscount; - d1 = (Math.Log(forwardSi/payoff.strike())+0.5*variance) - /Math.Sqrt(variance); - LHS = payoff.strike() - Si; - double temp2 = Utils.blackFormula(payoff.optionType(), payoff.strike(), - forwardSi, Math.Sqrt(variance))*riskFreeDiscount; - RHS = temp2 - (1 - dividendDiscount * cumNormalDist.value(-d1)) * Si / Q; - bi = -dividendDiscount * cumNormalDist.value(-d1) * (1 - 1 / Q) - - (1 + dividendDiscount * cumNormalDist.derivative(-d1) - / Math.Sqrt(variance)) / Q; - } - break; - default: - Utils.QL_FAIL("unknown option type"); - break; - } - - return Si; - } - - public override void calculate() { - - Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.American,()=> "not an American Option"); - - AmericanExercise ex = arguments_.exercise as AmericanExercise; - Utils.QL_REQUIRE(ex != null,()=> "non-American exercise given"); - - Utils.QL_REQUIRE(!ex.payoffAtExpiry(),()=> "payoff at expiry not handled"); - - StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; - Utils.QL_REQUIRE(payoff != null,()=> "non-striked payoff given"); - - double variance = process_.blackVolatility().link.blackVariance(ex.lastDate(), payoff.strike()); - double dividendDiscount = process_.dividendYield().link.discount(ex.lastDate()); - double riskFreeDiscount = process_.riskFreeRate().link.discount(ex.lastDate()); - double spot = process_.stateVariable().link.value(); - Utils.QL_REQUIRE(spot > 0.0,()=> "negative or null underlying given"); - double forwardPrice = spot * dividendDiscount / riskFreeDiscount; - BlackCalculator black = new BlackCalculator(payoff, forwardPrice, Math.Sqrt(variance), riskFreeDiscount); - - if (dividendDiscount>=1.0 && payoff.optionType()==Option.Type.Call) { - // early exercise never optimal - results_.value = black.value(); - results_.delta = black.delta(spot); - results_.deltaForward = black.deltaForward(); - results_.elasticity = black.elasticity(spot); - results_.gamma = black.gamma(spot); - - DayCounter rfdc = process_.riskFreeRate().link.dayCounter(); - DayCounter divdc = process_.dividendYield().link.dayCounter(); - DayCounter voldc = process_.blackVolatility().link.dayCounter(); - double t = rfdc.yearFraction(process_.riskFreeRate().link.referenceDate(), arguments_.exercise.lastDate()); - results_.rho = black.rho(t); - - t = divdc.yearFraction(process_.dividendYield().link.referenceDate(), arguments_.exercise.lastDate()); - results_.dividendRho = black.dividendRho(t); - - t = voldc.yearFraction(process_.blackVolatility().link.referenceDate(), arguments_.exercise.lastDate()); - results_.vega = black.vega(t); - results_.theta = black.theta(spot, t); - results_.thetaPerDay = black.thetaPerDay(spot, t); - - results_.strikeSensitivity = black.strikeSensitivity(); - results_.itmCashProbability = black.itmCashProbability(); - } else { - // early exercise can be optimal - CumulativeNormalDistribution cumNormalDist = new CumulativeNormalDistribution(); - double tolerance = 1e-6; - double Sk = criticalPrice(payoff, riskFreeDiscount, - dividendDiscount, variance, tolerance); - double forwardSk = Sk * dividendDiscount / riskFreeDiscount; - double d1 = (Math.Log(forwardSk/payoff.strike()) + 0.5*variance) - /Math.Sqrt(variance); - double n = 2.0*Math.Log(dividendDiscount/riskFreeDiscount)/variance; - double K = ( !Utils.close( riskFreeDiscount, 1.0, 1000 ) ) - ? -2.0 * Math.Log( riskFreeDiscount ) - / ( variance * ( 1.0 - riskFreeDiscount ) ) - : 2.0 / variance; - double Q, a; - switch (payoff.optionType()) { - case Option.Type.Call: - Q = (-(n-1.0) + Math.Sqrt(((n-1.0)*(n-1.0))+4.0*K))/2.0; - a = (Sk/Q) * (1.0 - dividendDiscount * cumNormalDist.value(d1)); - if (spotSk) { - results_.value = black.value() + - a * Math.Pow((spot / Sk), Q); - } else { - results_.value = payoff.strike() - spot; - } - break; - default: - Utils.QL_FAIL("unknown option type"); - break; - } - } // end of "early exercise can be optimal" - } - } -} diff --git a/src/QLNet/Pricingengines/vanilla/binomialengine.cs b/src/QLNet/Pricingengines/vanilla/binomialengine.cs deleted file mode 100644 index 03fb1c3c1..000000000 --- a/src/QLNet/Pricingengines/vanilla/binomialengine.cs +++ /dev/null @@ -1,122 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! Pricing engine for vanilla options using binomial trees - /*! \ingroup vanillaengines - - \test the correctness of the returned values is tested by - checking it against analytic results. - - \todo Greeks are not overly accurate. They could be improved - by building a tree so that it has three points at the - current time. The value would be fetched from the middle - one, while the two side points would be used for - estimating partial derivatives. - */ - public class BinomialVanillaEngine : VanillaOption.Engine where T : ITreeFactory, ITree, new() { - private GeneralizedBlackScholesProcess process_; - private int timeSteps_; - - public BinomialVanillaEngine(GeneralizedBlackScholesProcess process, int timeSteps) { - process_ = process; - timeSteps_ = timeSteps; - - Utils.QL_REQUIRE(timeSteps>0,()=> "timeSteps must be positive, " + timeSteps + " not allowed"); - - process_.registerWith(update); - } - - public override void calculate() { - - DayCounter rfdc = process_.riskFreeRate().link.dayCounter(); - DayCounter divdc = process_.dividendYield().link.dayCounter(); - DayCounter voldc = process_.blackVolatility().link.dayCounter(); - Calendar volcal = process_.blackVolatility().link.calendar(); - - double s0 = process_.stateVariable().link.value(); - Utils.QL_REQUIRE(s0 > 0.0,()=> "negative or null underlying given"); - double v = process_.blackVolatility().link.blackVol(arguments_.exercise.lastDate(), s0); - Date maturityDate = arguments_.exercise.lastDate(); - double r = process_.riskFreeRate().link.zeroRate(maturityDate, rfdc, Compounding.Continuous, Frequency.NoFrequency).rate(); - double q = process_.dividendYield().link.zeroRate(maturityDate, divdc, Compounding.Continuous, Frequency.NoFrequency).rate(); - Date referenceDate = process_.riskFreeRate().link.referenceDate(); - - // binomial trees with constant coefficient - var flatRiskFree = new Handle(new FlatForward(referenceDate, r, rfdc)); - var flatDividends = new Handle(new FlatForward(referenceDate, q, divdc)); - var flatVol = new Handle(new BlackConstantVol(referenceDate, volcal, v, voldc)); - - PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; - Utils.QL_REQUIRE(payoff!= null,()=> "non-plain payoff given"); - - double maturity = rfdc.yearFraction(referenceDate, maturityDate); - - StochasticProcess1D bs = - new GeneralizedBlackScholesProcess(process_.stateVariable(), flatDividends, flatRiskFree, flatVol); - - TimeGrid grid = new TimeGrid(maturity, timeSteps_); - - T tree = FastActivator.Create().factory(bs, maturity, timeSteps_, payoff.strike()); - - BlackScholesLattice lattice = new BlackScholesLattice(tree, r, maturity, timeSteps_); - - DiscretizedVanillaOption option = new DiscretizedVanillaOption(arguments_, process_, grid); - - option.initialize(lattice, maturity); - - // Partial derivatives calculated from various points in the - // binomial tree (Odegaard) - - // Rollback to third-last step, and get underlying price (s2) & - // option values (p2) at this point - option.rollback(grid[2]); - Vector va2 = new Vector(option.values()); - Utils.QL_REQUIRE(va2.size() == 3,()=> "Expect 3 nodes in grid at second step"); - double p2h = va2[2]; // high-price - double s2 = lattice.underlying(2, 2); // high price - - // Rollback to second-last step, and get option value (p1) at - // this point - option.rollback(grid[1]); - Vector va = new Vector(option.values()); - Utils.QL_REQUIRE(va.size() == 2,()=> "Expect 2 nodes in grid at first step"); - double p1 = va[1]; - - // Finally, rollback to t=0 - option.rollback(0.0); - double p0 = option.presentValue(); - double s1 = lattice.underlying(1, 1); - - // Calculate partial derivatives - double delta0 = (p1 - p0) / (s1 - s0); // dp/ds - double delta1 = (p2h - p1) / (s2 - s1); // dp/ds - - // Store results - results_.value = p0; - results_.delta = delta0; - results_.gamma = 2.0 * (delta1 - delta0) / (s2 - s0); //d(delta)/ds - results_.theta = Utils.blackScholesTheta(process_, - results_.value.GetValueOrDefault(), - results_.delta.GetValueOrDefault(), - results_.gamma.GetValueOrDefault()); - } - } -} diff --git a/src/QLNet/Pricingengines/vanilla/bjerksundstenslandengine.cs b/src/QLNet/Pricingengines/vanilla/bjerksundstenslandengine.cs deleted file mode 100644 index 2db5d9756..000000000 --- a/src/QLNet/Pricingengines/vanilla/bjerksundstenslandengine.cs +++ /dev/null @@ -1,141 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! Bjerksund and Stensland pricing engine for American options (1993) - /*! \ingroup vanillaengines - - \test the correctness of the returned value is tested by - reproducing results available in literature. - */ - public class BjerksundStenslandApproximationEngine : VanillaOption.Engine { - private GeneralizedBlackScholesProcess process_; - - public BjerksundStenslandApproximationEngine(GeneralizedBlackScholesProcess process) { - process_ = process; - - process_.registerWith(update); - } - - public override void calculate() { - - Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.American,()=> "not an American Option"); - - AmericanExercise ex = arguments_.exercise as AmericanExercise; - Utils.QL_REQUIRE(ex != null,()=> "non-American exercise given"); - - Utils.QL_REQUIRE(!ex.payoffAtExpiry(),()=> "payoff at expiry not handled"); - - PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; - Utils.QL_REQUIRE(payoff != null,()=> "non-plain payoff given"); - - double variance = process_.blackVolatility().link.blackVariance(ex.lastDate(), payoff.strike()); - double dividendDiscount = process_.dividendYield().link.discount(ex.lastDate()); - double riskFreeDiscount = process_.riskFreeRate().link.discount(ex.lastDate()); - - double spot = process_.stateVariable().link.value(); - Utils.QL_REQUIRE(spot > 0.0,()=> "negative or null underlying given"); - - double strike = payoff.strike(); - - if (payoff.optionType()==Option.Type.Put) { - // use put-call simmetry - Utils.swap(ref spot, ref strike); - Utils.swap(ref riskFreeDiscount, ref dividendDiscount); - payoff = new PlainVanillaPayoff(Option.Type.Call, strike); - } - - if (dividendDiscount>=1.0) { - // early exercise is never optimal - use Black formula - double forwardPrice = spot * dividendDiscount / riskFreeDiscount; - BlackCalculator black = new BlackCalculator(payoff, forwardPrice, Math.Sqrt(variance), riskFreeDiscount); - - results_.value = black.value(); - results_.delta = black.delta(spot); - results_.deltaForward = black.deltaForward(); - results_.elasticity = black.elasticity(spot); - results_.gamma = black.gamma(spot); - - DayCounter rfdc = process_.riskFreeRate().link.dayCounter(); - DayCounter divdc = process_.dividendYield().link.dayCounter(); - DayCounter voldc = process_.blackVolatility().link.dayCounter(); - double t = rfdc.yearFraction(process_.riskFreeRate().link.referenceDate(), arguments_.exercise.lastDate()); - results_.rho = black.rho(t); - - t = divdc.yearFraction(process_.dividendYield().link.referenceDate(), arguments_.exercise.lastDate()); - results_.dividendRho = black.dividendRho(t); - - t = voldc.yearFraction(process_.blackVolatility().link.referenceDate(), arguments_.exercise.lastDate()); - results_.vega = black.vega(t); - results_.theta = black.theta(spot, t); - results_.thetaPerDay = black.thetaPerDay(spot, t); - - results_.strikeSensitivity = black.strikeSensitivity(); - results_.itmCashProbability = black.itmCashProbability(); - } else { - // early exercise can be optimal - use approximation - results_.value = americanCallApproximation(spot, strike, riskFreeDiscount, dividendDiscount, variance); - } - } - - - // helper functions - private CumulativeNormalDistribution cumNormalDist = new CumulativeNormalDistribution(); - - double phi(double S, double gamma, double H, double I, double rT, double bT, double variance) { - - double lambda = (-rT + gamma * bT + 0.5 * gamma * (gamma - 1.0) * variance); - double d = -(Math.Log(S / H) + (bT + (gamma - 0.5) * variance) ) / Math.Sqrt(variance); - double kappa = 2.0 * bT / variance + (2.0 * gamma - 1.0); - return Math.Exp(lambda) * (cumNormalDist.value(d) - - Math.Pow((I / S), kappa) * - cumNormalDist.value(d - 2.0 * Math.Log(I/S) / Math.Sqrt(variance))); - } - - - double americanCallApproximation(double S, double X, double rfD, double dD, double variance) { - - double bT = Math.Log(dD/rfD); - double rT = Math.Log(1.0/rfD); - - double beta = (0.5 - bT/variance) + Math.Sqrt(Math.Pow((bT/variance - 0.5), 2.0) + 2.0 * rT/variance); - double BInfinity = beta / (beta - 1.0) * X; - double B0 = Math.Max(X, rT / (rT - bT) * X); - double ht = -(bT + 2.0*Math.Sqrt(variance)) * B0 / (BInfinity - B0); - - // investigate what happen to I for dD->0.0 - double I = B0 + (BInfinity - B0) * (1 - Math.Exp(ht)); - Utils.QL_REQUIRE(I >= X,()=> "Bjerksund-Stensland approximation not applicable to this set of parameters"); - if (S >= I) { - return S - X; - } else { - // investigate what happen to alpha for dD->0.0 - double alpha = (I - X) * Math.Pow(I, (-beta)); - return (I - X) * Math.Pow(S/I, beta) - *(1 - phi(S, beta, I, I, rT, bT, variance)) - + S * phi(S, 1.0, I, I, rT, bT, variance) - - S * phi(S, 1.0, X, I, rT, bT, variance) - - X * phi(S, 0.0, I, I, rT, bT, variance) - + X * phi(S, 0.0, X, I, rT, bT, variance); - } - } - - } -} diff --git a/src/QLNet/Pricingengines/vanilla/discretizedvanillaoption.cs b/src/QLNet/Pricingengines/vanilla/discretizedvanillaoption.cs deleted file mode 100644 index 431d120b6..000000000 --- a/src/QLNet/Pricingengines/vanilla/discretizedvanillaoption.cs +++ /dev/null @@ -1,79 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet { - public class DiscretizedVanillaOption : DiscretizedAsset { - private VanillaOption.Arguments arguments_; - private List stoppingTimes_; - - public DiscretizedVanillaOption(VanillaOption.Arguments args, StochasticProcess process, TimeGrid grid) { - arguments_ = args; - - stoppingTimes_ = new InitializedList(args.exercise.dates().Count); - for (int i=0; i mandatoryTimes() { - return stoppingTimes_; - } - - protected override void postAdjustValuesImpl() { - double now = time(); - switch (arguments_.exercise.type()) { - case Exercise.Type.American: - if (now <= stoppingTimes_[1] && now >= stoppingTimes_[0]) - applySpecificCondition(); - break; - case Exercise.Type.European: - if (isOnTime(stoppingTimes_[0])) - applySpecificCondition(); - break; - case Exercise.Type.Bermudan: - for (int i=0; i - 1.10.0 + 1.11.0 net45;net40;netstandard2.0;netcoreapp1.1 $(DefineConstants);QL_NEGATIVE_RATES QLNet diff --git a/src/QLNet/Quotes/CompositeQuote.cs b/src/QLNet/Quotes/CompositeQuote.cs index c1a20d129..742082e00 100644 --- a/src/QLNet/Quotes/CompositeQuote.cs +++ b/src/QLNet/Quotes/CompositeQuote.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2009 Andrea Maggiulli - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -53,7 +53,8 @@ public void update() //! Quote interface public override double value() { - if (!isValid()) throw new ArgumentException("invalid DerivedQuote"); + if (!isValid()) + throw new ArgumentException("invalid DerivedQuote"); return f_(element1_.link.value(), element2_.link.value()); } diff --git a/src/QLNet/Quotes/DeltaVolQuote.cs b/src/QLNet/Quotes/DeltaVolQuote.cs index 729db69be..09d9b8612 100644 --- a/src/QLNet/Quotes/DeltaVolQuote.cs +++ b/src/QLNet/Quotes/DeltaVolQuote.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,14 +22,14 @@ in FX markets as well as ATM types. */ public class DeltaVolQuote : Quote, IObserver { - public enum DeltaType + public enum DeltaType { Spot, // Spot Delta, e.g. usual Black Scholes delta Fwd, // Forward Delta PaSpot, // Premium Adjusted Spot Delta PaFwd // Premium Adjusted Forward Delta } - + public enum AtmType { AtmNull, // Default, if not an atm quote @@ -42,7 +42,7 @@ public enum AtmType } // Standard constructor delta vs vol. - public DeltaVolQuote(double delta, Handle vol,double maturity,DeltaType deltaType) + public DeltaVolQuote(double delta, Handle vol, double maturity, DeltaType deltaType) { delta_ = delta; vol_ = vol; @@ -54,14 +54,14 @@ public DeltaVolQuote(double delta, Handle vol,double maturity,DeltaType d } // Additional constructor, if special atm quote is used - public DeltaVolQuote( Handle vol,DeltaType deltaType,double maturity,AtmType atmType) + public DeltaVolQuote(Handle vol, DeltaType deltaType, double maturity, AtmType atmType) { vol_ = vol; deltaType_ = deltaType; maturity_ = maturity; atmType_ = atmType; - vol_.registerWith( update ); + vol_.registerWith(update); } public void update() { notifyObservers(); } diff --git a/src/QLNet/Quotes/DerivedQuote.cs b/src/QLNet/Quotes/DerivedQuote.cs index 5968379ee..a457dc12e 100644 --- a/src/QLNet/Quotes/DerivedQuote.cs +++ b/src/QLNet/Quotes/DerivedQuote.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2009 Andrea Maggiulli - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -41,18 +41,19 @@ public DerivedQuote(Handle element, Func f) //! Quote interface public override double value() { - if (!isValid()) throw new ArgumentException("invalid DerivedQuote"); + if (!isValid()) + throw new ArgumentException("invalid DerivedQuote"); return f_(element_.link.value()); } - public override bool isValid() - { - return element_.link.isValid(); + public override bool isValid() + { + return element_.link.isValid(); } - public void update() + public void update() { - notifyObservers(); + notifyObservers(); } } diff --git a/src/QLNet/Quotes/LastFixingQuote.cs b/src/QLNet/Quotes/LastFixingQuote.cs index 21f6bd08e..068a82434 100644 --- a/src/QLNet/Quotes/LastFixingQuote.cs +++ b/src/QLNet/Quotes/LastFixingQuote.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008,2009 Andrea Maggiulli - + Copyright (C) 2008,2009 Andrea Maggiulli + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -27,7 +27,7 @@ class LastFixingQuote : Quote, IObserver { protected Index index_; - public LastFixingQuote(Index index) + public LastFixingQuote(Index index) { index_ = index; index_.registerWith(update); @@ -36,18 +36,19 @@ public LastFixingQuote(Index index) //! Quote interface public override double value() { - if (!isValid()) throw new ArgumentException(index_.name() + " has no fixing"); + if (!isValid()) + throw new ArgumentException(index_.name() + " has no fixing"); return index_.fixing(referenceDate()); } public override bool isValid() { - return index_.timeSeries().value().Count > 0; + return index_.timeSeries().Count > 0; } - public Date referenceDate() + public Date referenceDate() { - return index_.timeSeries().value().Keys.Last(); // must be tested + return index_.timeSeries().Keys.Last(); // must be tested } public void update() diff --git a/src/QLNet/Quotes/Quote.cs b/src/QLNet/Quotes/Quote.cs index 140d4300b..ef4641ab6 100644 --- a/src/QLNet/Quotes/Quote.cs +++ b/src/QLNet/Quotes/Quote.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,30 +19,36 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! purely virtual base class for market observables - public class Quote : IObservable - { - // recheck this abstract implementations of methods which otherwise should throw "notimplemented" - // such default implementation is needed for Handles - - //! returns the current value, 0 by default - public virtual double value() { return 0; } - //! returns true if the Quote holds a valid value, true by default - public virtual bool isValid() { return true; } - - // observable interface - private readonly WeakEventSource eventSource = new WeakEventSource(); - public event Callback notifyObserversEvent - { - add { eventSource.Subscribe(value); } - remove { eventSource.Unsubscribe(value); } - } - - public void registerWith(Callback handler) { notifyObserversEvent += handler; } - public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } - protected void notifyObservers() - { - eventSource.Raise(); - } - } + //! purely virtual base class for market observables + public class Quote : IObservable + { + // recheck this abstract implementations of methods which otherwise should throw "notimplemented" + // such default implementation is needed for Handles + + //! returns the current value, 0 by default + public virtual double value() { return 0; } + //! returns true if the Quote holds a valid value, true by default + public virtual bool isValid() { return true; } + + // observable interface + private readonly WeakEventSource eventSource = new WeakEventSource(); + public event Callback notifyObserversEvent + { + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } + } + + public void registerWith(Callback handler) { notifyObserversEvent += handler; } + public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } + protected void notifyObservers() + { + eventSource.Raise(); + } + } } \ No newline at end of file diff --git a/src/QLNet/Quotes/SimpleQuote.cs b/src/QLNet/Quotes/SimpleQuote.cs index a1a5ae806..a04758fcc 100644 --- a/src/QLNet/Quotes/SimpleQuote.cs +++ b/src/QLNet/Quotes/SimpleQuote.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,38 +20,39 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - // simple quote class - //! market element returning a stored value - public class SimpleQuote : Quote - { - private double? value_; - - public SimpleQuote() { } - public SimpleQuote(double? value) { value_ = value; } - - //! Quote interface - public override double value() - { - if (!isValid()) throw new ArgumentException("invalid SimpleQuote"); - return value_.GetValueOrDefault(); - } - public override bool isValid() { return value_ != null; } - - //! returns the difference between the new value and the old value - public double setValue(double? value) - { - double? diff = value - value_; - if (diff.IsNotEqual(0.0)) - { - value_ = value; - notifyObservers(); - } - return diff.GetValueOrDefault(); - } - - public void reset() - { - setValue(null); - } - } + // simple quote class + //! market element returning a stored value + public class SimpleQuote : Quote + { + private double? value_; + + public SimpleQuote() { } + public SimpleQuote(double? value) { value_ = value; } + + //! Quote interface + public override double value() + { + if (!isValid()) + throw new ArgumentException("invalid SimpleQuote"); + return value_.GetValueOrDefault(); + } + public override bool isValid() { return value_ != null; } + + //! returns the difference between the new value and the old value + public double setValue(double? value) + { + double? diff = value - value_; + if (diff.IsNotEqual(0.0)) + { + value_ = value; + notifyObservers(); + } + return diff.GetValueOrDefault(); + } + + public void reset() + { + setValue(null); + } + } } \ No newline at end of file diff --git a/src/QLNet/Settings.cs b/src/QLNet/Settings.cs index 77d3d15f0..1e1e92687 100644 --- a/src/QLNet/Settings.cs +++ b/src/QLNet/Settings.cs @@ -2,87 +2,115 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - // we need only one instance of the class - // we can not derive it from IObservable because the class is static - public static class Settings { - - [ThreadStatic] - private static Date evaluationDate_; - - [ThreadStatic] - private static bool includeReferenceDateEvents_; - - [ThreadStatic] - private static bool enforcesTodaysHistoricFixings_; - - [ThreadStatic] - private static bool? includeTodaysCashFlows_; - - public static Date evaluationDate() - { - if (evaluationDate_ == null) - evaluationDate_ = Date.Today; - return evaluationDate_; - } - - - public static void setEvaluationDate(Date d) { - evaluationDate_ = d; - notifyObservers(); - } - - public static bool enforcesTodaysHistoricFixings - { - get { return enforcesTodaysHistoricFixings_; } - set { enforcesTodaysHistoricFixings_ = value; } - } - - public static bool includeReferenceDateEvents { - get { return includeReferenceDateEvents_; } - set { includeReferenceDateEvents_ = value; } - } - - public static bool? includeTodaysCashFlows - { - get { return includeTodaysCashFlows_; } - set { includeTodaysCashFlows_ = value; } - } - - //////////////////////////////////////////////////// - // Observable interface - private static readonly WeakEventSource eventSource = new WeakEventSource(); - public static event Callback notifyObserversEvent - { - add { eventSource.Subscribe(value); } - remove { eventSource.Unsubscribe(value); } - } - - public static void registerWith(Callback handler) { notifyObserversEvent += handler; } - public static void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } - private static void notifyObservers() - { - eventSource.Raise(); - } - } +namespace QLNet +{ + // we need only one instance of the class + // we can not derive it from IObservable because the class is static + public static class Settings + { + + [ThreadStatic] + private static Date evaluationDate_; + + [ThreadStatic] + private static bool includeReferenceDateEvents_; + + [ThreadStatic] + private static bool enforcesTodaysHistoricFixings_; + + [ThreadStatic] + private static bool? includeTodaysCashFlows_; + + public static Date evaluationDate() + { + if (evaluationDate_ == null) + evaluationDate_ = Date.Today; + return evaluationDate_; + } + + + public static void setEvaluationDate(Date d) + { + evaluationDate_ = d; + notifyObservers(); + } + + public static bool enforcesTodaysHistoricFixings + { + get + { + return enforcesTodaysHistoricFixings_; + } + set + { + enforcesTodaysHistoricFixings_ = value; + } + } + + public static bool includeReferenceDateEvents + { + get + { + return includeReferenceDateEvents_; + } + set + { + includeReferenceDateEvents_ = value; + } + } + + public static bool? includeTodaysCashFlows + { + get + { + return includeTodaysCashFlows_; + } + set + { + includeTodaysCashFlows_ = value; + } + } + + //////////////////////////////////////////////////// + // Observable interface + private static readonly WeakEventSource eventSource = new WeakEventSource(); + public static event Callback notifyObserversEvent + { + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } + } + + public static void registerWith(Callback handler) { notifyObserversEvent += handler; } + public static void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } + private static void notifyObservers() + { + eventSource.Raise(); + } + } // helper class to temporarily and safely change the settings public class SavedSettings : IDisposable diff --git a/src/QLNet/StochasticProcess.cs b/src/QLNet/StochasticProcess.cs index 515c98674..2642a2f57 100644 --- a/src/QLNet/StochasticProcess.cs +++ b/src/QLNet/StochasticProcess.cs @@ -1,247 +1,279 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - //! discretization of a stochastic process over a given time interval - public interface IDiscretization { - Vector drift(StochasticProcess sp, double t0, Vector x0, double dt); - Matrix diffusion(StochasticProcess sp, double t0, Vector x0, double dt); - Matrix covariance(StochasticProcess sp, double t0, Vector x0, double dt); - } - - //! discretization of a 1D stochastic process over a given time interval - public interface IDiscretization1D { - double drift(StochasticProcess1D sp, double t0, double x0, double dt); - double diffusion(StochasticProcess1D sp, double t0, double x0, double dt); - double variance(StochasticProcess1D sp, double t0, double x0, double dt); - } - - //! multi-dimensional stochastic process class. - /*! This class describes a stochastic process governed by - \f[ - d\mathrm{x}_t = \mu(t, x_t)\mathrm{d}t - + \sigma(t, \mathrm{x}_t) \cdot d\mathrm{W}_t. - \f] - */ - public abstract class StochasticProcess : IObservable, IObserver { - protected IDiscretization discretization_; - - protected StochasticProcess() { } - protected StochasticProcess(IDiscretization disc) { - discretization_ = disc; - } - - // Stochastic process interface - //! returns the number of dimensions of the stochastic process - public abstract int size(); - - //! returns the number of independent factors of the process - public virtual int factors() { return size(); } - - //! returns the initial values of the state variables - public abstract Vector initialValues(); - - /*! \brief returns the drift part of the equation, i.e., - \f$ \mu(t, \mathrm{x}_t) \f$ */ - public abstract Vector drift(double t, Vector x); - - /*! \brief returns the diffusion part of the equation, i.e. - \f$ \sigma(t, \mathrm{x}_t) \f$ */ - public abstract Matrix diffusion(double t, Vector x); - - /*! This method can be - overridden in derived classes which want to hard-code a - particular discretization. - */ - public virtual Vector expectation(double t0, Vector x0, double dt) { - return apply(x0, discretization_.drift(this, t0, x0, dt)); - } - - /*! returns the standard deviation. This method can be - overridden in derived classes which want to hard-code a - particular discretization. - */ - public virtual Matrix stdDeviation(double t0, Vector x0, double dt) { - return discretization_.diffusion(this, t0, x0, dt); - } - - /*! returns the covariance. This method can be - overridden in derived classes which want to hard-code a - particular discretization. - */ - public virtual Matrix covariance(double t0, Vector x0, double dt) { - return discretization_.covariance(this, t0, x0, dt); - } - - // returns the asset value after a time interval - public virtual Vector evolve(double t0, Vector x0, double dt, Vector dw) { - return apply(expectation(t0, x0, dt), stdDeviation(t0, x0, dt) * dw); - } - - // applies a change to the asset value. - public virtual Vector apply(Vector x0, Vector dx) { - return x0 + dx; - } - - // utilities - /*! returns the time value corresponding to the given date - in the reference system of the stochastic process. - - \note As a number of processes might not need this - functionality, a default implementation is given - which raises an exception. - */ - public virtual double time(Date d) { - throw new NotSupportedException("date/time conversion not supported"); - } - - - #region Observer & Observable - // Subjects, i.e. observables, should define interface internally like follows. - private readonly WeakEventSource eventSource = new WeakEventSource(); - public event Callback notifyObserversEvent - { - add { eventSource.Subscribe(value); } - remove { eventSource.Unsubscribe(value); } - } - - public void registerWith(Callback handler) { notifyObserversEvent += handler; } - public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } - protected void notifyObservers() - { - eventSource.Raise(); - } - - public virtual void update() { - notifyObservers(); - } - #endregion - } - - //! 1-dimensional stochastic process - public abstract class StochasticProcess1D : StochasticProcess { - protected new IDiscretization1D discretization_; - - protected StochasticProcess1D() {} - protected StochasticProcess1D(IDiscretization1D disc) { - discretization_ = disc; - } - - // 1-D stochastic process interface - //! returns the initial value of the state variable - public abstract double x0(); - - //! returns the drift part of the equation, i.e. \f$ \mu(t, x_t) \f$ - public abstract double drift(double t, double x); - public override Vector drift(double t, Vector x) { - #if QL_EXTRA_SAFETY_CHECKS - QL_REQUIRE(x.size() == 1, () => "1-D array required"); - #endif - Vector a = new Vector(1, drift(t, x[0])); - return a; - } - - // \brief returns the diffusion part of the equation - public abstract double diffusion(double t, double x); - public override Matrix diffusion(double t, Vector x) { - #if QL_EXTRA_SAFETY_CHECKS - QL_REQUIRE(x.size() == 1, () => "1-D array required"); - #endif - Matrix m = new Matrix(1, 1, diffusion(t, x[0])); - return m; - } - - /*! returns the expectation. This method can be - overridden in derived classes which want to hard-code a - particular discretization. - */ - public virtual double expectation(double t0, double x0, double dt) { - return apply(x0, discretization_.drift(this, t0, x0, dt)); - } - public override Vector expectation(double t0, Vector x0, double dt) { - #if QL_EXTRA_SAFETY_CHECKS - QL_REQUIRE(x0.size() == 1, () => "1-D array required"); - #endif - Vector a = new Vector(1, expectation(t0, x0[0], dt)); - return a; - } - - /*! returns the standard deviation. This method can be - overridden in derived classes which want to hard-code a - particular discretization. - */ - public virtual double stdDeviation(double t0, double x0, double dt) { - return discretization_.diffusion(this, t0, x0, dt); - } - public override Matrix stdDeviation(double t0, Vector x0, double dt) { - #if QL_EXTRA_SAFETY_CHECKS - QL_REQUIRE(x0.size() == 1, () => "1-D array required"); - #endif - Matrix m = new Matrix(1, 1, stdDeviation(t0, x0[0], dt)); - return m; - } - - /*! returns the variance. This method can be - overridden in derived classes which want to hard-code a - particular discretization. - */ - public virtual double variance(double t0, double x0, double dt) { - return discretization_.variance(this, t0, x0, dt); - } - public virtual Matrix variance(double t0, Vector x0, double dt) { - #if QL_EXTRA_SAFETY_CHECKS - QL_REQUIRE(x0.size() == 1, () => "1-D array required"); - #endif - Matrix m = new Matrix(1, 1, variance(t0, x0[0], dt)); - return m; - } - - // returns the asset value after a time interval. - public virtual double evolve(double t0, double x0, double dt, double dw) { - return apply(expectation(t0, x0, dt), stdDeviation(t0, x0, dt) * dw); - } - public virtual Vector evolve(double t0, ref Vector x0, double dt, ref Vector dw) { - #if QL_EXTRA_SAFETY_CHECKS - QL_REQUIRE(x0.size() == 1, () => "1-D array required"); - QL_REQUIRE(dw.size() == 1, () => "1-D array required"); - #endif - Vector a = new Vector(1, evolve(t0, x0[0], dt, dw[0])); - return a; - } - - // applies a change to the asset value. - public virtual double apply(double x0, double dx) { return x0 + dx; } - public virtual Vector apply(ref Vector x0, ref Vector dx) { - #if QL_EXTRA_SAFETY_CHECKS - QL_REQUIRE(x0.size() == 1, () => "1-D array required"); - QL_REQUIRE(dx.size() == 1, () => "1-D array required"); - #endif - Vector a = new Vector(1, apply(x0[0], dx[0])); - return a; - } - - //! returns the initial values of the state variables - public override Vector initialValues() { - Vector a = new Vector(1, x0()); - return a; - } - public override int size() { return 1; } - } +namespace QLNet +{ + //! discretization of a stochastic process over a given time interval + public interface IDiscretization + { + Vector drift(StochasticProcess sp, double t0, Vector x0, double dt); + Matrix diffusion(StochasticProcess sp, double t0, Vector x0, double dt); + Matrix covariance(StochasticProcess sp, double t0, Vector x0, double dt); + } + + //! discretization of a 1D stochastic process over a given time interval + public interface IDiscretization1D + { + double drift(StochasticProcess1D sp, double t0, double x0, double dt); + double diffusion(StochasticProcess1D sp, double t0, double x0, double dt); + double variance(StochasticProcess1D sp, double t0, double x0, double dt); + } + + //! multi-dimensional stochastic process class. + /*! This class describes a stochastic process governed by + \f[ + d\mathrm{x}_t = \mu(t, x_t)\mathrm{d}t + + \sigma(t, \mathrm{x}_t) \cdot d\mathrm{W}_t. + \f] + */ + public abstract class StochasticProcess : IObservable, IObserver + { + protected IDiscretization discretization_; + + protected StochasticProcess() { } + protected StochasticProcess(IDiscretization disc) + { + discretization_ = disc; + } + + // Stochastic process interface + //! returns the number of dimensions of the stochastic process + public abstract int size(); + + //! returns the number of independent factors of the process + public virtual int factors() { return size(); } + + //! returns the initial values of the state variables + public abstract Vector initialValues(); + + /*! \brief returns the drift part of the equation, i.e., + \f$ \mu(t, \mathrm{x}_t) \f$ */ + public abstract Vector drift(double t, Vector x); + + /*! \brief returns the diffusion part of the equation, i.e. + \f$ \sigma(t, \mathrm{x}_t) \f$ */ + public abstract Matrix diffusion(double t, Vector x); + + /*! This method can be + overridden in derived classes which want to hard-code a + particular discretization. + */ + public virtual Vector expectation(double t0, Vector x0, double dt) + { + return apply(x0, discretization_.drift(this, t0, x0, dt)); + } + + /*! returns the standard deviation. This method can be + overridden in derived classes which want to hard-code a + particular discretization. + */ + public virtual Matrix stdDeviation(double t0, Vector x0, double dt) + { + return discretization_.diffusion(this, t0, x0, dt); + } + + /*! returns the covariance. This method can be + overridden in derived classes which want to hard-code a + particular discretization. + */ + public virtual Matrix covariance(double t0, Vector x0, double dt) + { + return discretization_.covariance(this, t0, x0, dt); + } + + // returns the asset value after a time interval + public virtual Vector evolve(double t0, Vector x0, double dt, Vector dw) + { + return apply(expectation(t0, x0, dt), stdDeviation(t0, x0, dt) * dw); + } + + // applies a change to the asset value. + public virtual Vector apply(Vector x0, Vector dx) + { + return x0 + dx; + } + + // utilities + /*! returns the time value corresponding to the given date + in the reference system of the stochastic process. + + \note As a number of processes might not need this + functionality, a default implementation is given + which raises an exception. + */ + public virtual double time(Date d) + { + throw new NotSupportedException("date/time conversion not supported"); + } + + + #region Observer & Observable + // Subjects, i.e. observables, should define interface internally like follows. + private readonly WeakEventSource eventSource = new WeakEventSource(); + public event Callback notifyObserversEvent + { + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } + } + + public void registerWith(Callback handler) { notifyObserversEvent += handler; } + public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } + protected void notifyObservers() + { + eventSource.Raise(); + } + + public virtual void update() + { + notifyObservers(); + } + #endregion + } + + //! 1-dimensional stochastic process + public abstract class StochasticProcess1D : StochasticProcess + { + protected new IDiscretization1D discretization_; + + protected StochasticProcess1D() {} + protected StochasticProcess1D(IDiscretization1D disc) + { + discretization_ = disc; + } + + // 1-D stochastic process interface + //! returns the initial value of the state variable + public abstract double x0(); + + //! returns the drift part of the equation, i.e. \f$ \mu(t, x_t) \f$ + public abstract double drift(double t, double x); + public override Vector drift(double t, Vector x) + { +#if QL_EXTRA_SAFETY_CHECKS + QL_REQUIRE(x.size() == 1, () => "1-D array required"); +#endif + Vector a = new Vector(1, drift(t, x[0])); + return a; + } + + // \brief returns the diffusion part of the equation + public abstract double diffusion(double t, double x); + public override Matrix diffusion(double t, Vector x) + { +#if QL_EXTRA_SAFETY_CHECKS + QL_REQUIRE(x.size() == 1, () => "1-D array required"); +#endif + Matrix m = new Matrix(1, 1, diffusion(t, x[0])); + return m; + } + + /*! returns the expectation. This method can be + overridden in derived classes which want to hard-code a + particular discretization. + */ + public virtual double expectation(double t0, double x0, double dt) + { + return apply(x0, discretization_.drift(this, t0, x0, dt)); + } + public override Vector expectation(double t0, Vector x0, double dt) + { +#if QL_EXTRA_SAFETY_CHECKS + QL_REQUIRE(x0.size() == 1, () => "1-D array required"); +#endif + Vector a = new Vector(1, expectation(t0, x0[0], dt)); + return a; + } + + /*! returns the standard deviation. This method can be + overridden in derived classes which want to hard-code a + particular discretization. + */ + public virtual double stdDeviation(double t0, double x0, double dt) + { + return discretization_.diffusion(this, t0, x0, dt); + } + public override Matrix stdDeviation(double t0, Vector x0, double dt) + { +#if QL_EXTRA_SAFETY_CHECKS + QL_REQUIRE(x0.size() == 1, () => "1-D array required"); +#endif + Matrix m = new Matrix(1, 1, stdDeviation(t0, x0[0], dt)); + return m; + } + + /*! returns the variance. This method can be + overridden in derived classes which want to hard-code a + particular discretization. + */ + public virtual double variance(double t0, double x0, double dt) + { + return discretization_.variance(this, t0, x0, dt); + } + public virtual Matrix variance(double t0, Vector x0, double dt) + { +#if QL_EXTRA_SAFETY_CHECKS + QL_REQUIRE(x0.size() == 1, () => "1-D array required"); +#endif + Matrix m = new Matrix(1, 1, variance(t0, x0[0], dt)); + return m; + } + + // returns the asset value after a time interval. + public virtual double evolve(double t0, double x0, double dt, double dw) + { + return apply(expectation(t0, x0, dt), stdDeviation(t0, x0, dt) * dw); + } + public virtual Vector evolve(double t0, ref Vector x0, double dt, ref Vector dw) + { +#if QL_EXTRA_SAFETY_CHECKS + QL_REQUIRE(x0.size() == 1, () => "1-D array required"); + QL_REQUIRE(dw.size() == 1, () => "1-D array required"); +#endif + Vector a = new Vector(1, evolve(t0, x0[0], dt, dw[0])); + return a; + } + + // applies a change to the asset value. + public virtual double apply(double x0, double dx) { return x0 + dx; } + public virtual Vector apply(ref Vector x0, ref Vector dx) + { +#if QL_EXTRA_SAFETY_CHECKS + QL_REQUIRE(x0.size() == 1, () => "1-D array required"); + QL_REQUIRE(dx.size() == 1, () => "1-D array required"); +#endif + Vector a = new Vector(1, apply(x0[0], dx[0])); + return a; + } + + //! returns the initial values of the state variables + public override Vector initialValues() + { + Vector a = new Vector(1, x0()); + return a; + } + public override int size() { return 1; } + } } diff --git a/src/QLNet/Termstructures/Bootstraperror.cs b/src/QLNet/Termstructures/Bootstraperror.cs index 4f0bda030..339e51fa3 100644 --- a/src/QLNet/Termstructures/Bootstraperror.cs +++ b/src/QLNet/Termstructures/Bootstraperror.cs @@ -2,46 +2,47 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) Copyright (C) 2014 Edem Dawui (edawui@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { - //! bootstrap error - public class BootstrapError : ISolver1d - where T : Curve - where U : TermStructure - { - - private T curve_; - private BootstrapHelper helper_; - private int segment_; - - public BootstrapError( T curve, BootstrapHelper helper, int segment ) - { - curve_ = curve; - helper_ = helper; - segment_ = segment; - } - - public override double value(double guess) - { - curve_.updateGuess(curve_.data_, guess, segment_); - curve_.interpolation_.update(); - return helper_.quoteError(); - } - } +namespace QLNet +{ + //! bootstrap error + public class BootstrapError : ISolver1d + where T : Curve + where U : TermStructure + { + + private T curve_; + private BootstrapHelper helper_; + private int segment_; + + public BootstrapError(T curve, BootstrapHelper helper, int segment) + { + curve_ = curve; + helper_ = helper; + segment_ = segment; + } + + public override double value(double guess) + { + curve_.updateGuess(curve_.data_, guess, segment_); + curve_.interpolation_.update(); + return helper_.quoteError(); + } + } } diff --git a/src/QLNet/Termstructures/Bootstraphelper.cs b/src/QLNet/Termstructures/Bootstraphelper.cs index 49ba93bd5..7ab2efd8a 100644 --- a/src/QLNet/Termstructures/Bootstraphelper.cs +++ b/src/QLNet/Termstructures/Bootstraphelper.cs @@ -1,147 +1,159 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { +namespace QLNet +{ public struct Pillar { - //! Enumeration for pillar determination alternatives - /*! These alternatives specify the determination of the pillar date. */ - public enum Choice - { - MaturityDate, //! instruments maturity date - LastRelevantDate, //! last date relevant for instrument pricing - CustomDate //! custom choice - } - } - // Base helper class for bootstrapping - /* This class provides an abstraction for the instruments used to bootstrap a term structure. - It is advised that a bootstrap helper for an instrument contains an instance of the actual instrument - * class to ensure consistancy between the algorithms used during bootstrapping - and later instrument pricing. This is not yet fully enforced in the available rate helpers. */ - public class BootstrapHelper : IObservable, IObserver { - protected Handle quote_; - protected TS termStructure_; - protected Date earliestDate_, latestDate_; - protected Date maturityDate_, latestRelevantDate_, pillarDate_; - - public BootstrapHelper() { } // required for generics - - public BootstrapHelper(Handle quote) { - quote_ = quote; - quote_.registerWith(update); - } - public BootstrapHelper(double quote) { - quote_ = new Handle(new SimpleQuote(quote)); - } - - - //! BootstrapHelper interface - public Handle quote() { return quote_; } - public double quoteError() { return quote_.link.value() - impliedQuote(); } - public double quoteValue() { return quote_.link.value(); } - public bool quoteIsValid() { return quote_.link.isValid(); } - public virtual double impliedQuote() { throw new NotSupportedException(); } - - - //! sets the term structure to be used for pricing - /*! \warning Being a pointer and not a shared_ptr, the term - structure is not guaranteed to remain allocated - for the whole life of the rate helper. It is - responsibility of the programmer to ensure that - the pointer remains valid. It is advised that - this method is called only inside the term - structure being bootstrapped, setting the pointer - to this, i.e., the term structure itself. - */ - public virtual void setTermStructure(TS ts) { - if (ts == null) throw new ArgumentException("null term structure given"); - termStructure_ = ts; - } - - // earliest relevant date - // The earliest date at which discounts are needed by the helper in order to provide a quote. - public virtual Date earliestDate() { return earliestDate_; } - - //! instrument's maturity date - public virtual Date maturityDate() - { - if ( maturityDate_ == null ) - return latestRelevantDate(); - return maturityDate_; - } - - //! latest relevant date - /*! The latest date at which data are needed by the helper - in order to provide a quote. It does not necessarily - equal the maturity of the underlying instrument. - */ - public virtual Date latestRelevantDate() - { - if (latestRelevantDate_ == null) + //! Enumeration for pillar determination alternatives + /*! These alternatives specify the determination of the pillar date. */ + public enum Choice + { + MaturityDate, //! instruments maturity date + LastRelevantDate, //! last date relevant for instrument pricing + CustomDate //! custom choice + } + } + // Base helper class for bootstrapping + /* This class provides an abstraction for the instruments used to bootstrap a term structure. + It is advised that a bootstrap helper for an instrument contains an instance of the actual instrument + * class to ensure consistancy between the algorithms used during bootstrapping + and later instrument pricing. This is not yet fully enforced in the available rate helpers. */ + public class BootstrapHelper : IObservable, IObserver + { + protected Handle quote_; + protected TS termStructure_; + protected Date earliestDate_, latestDate_; + protected Date maturityDate_, latestRelevantDate_, pillarDate_; + + public BootstrapHelper() { } // required for generics + + public BootstrapHelper(Handle quote) + { + quote_ = quote; + quote_.registerWith(update); + } + public BootstrapHelper(double quote) + { + quote_ = new Handle(new SimpleQuote(quote)); + } + + + //! BootstrapHelper interface + public Handle quote() { return quote_; } + public double quoteError() { return quote_.link.value() - impliedQuote(); } + public double quoteValue() { return quote_.link.value(); } + public bool quoteIsValid() { return quote_.link.isValid(); } + public virtual double impliedQuote() { throw new NotSupportedException(); } + + + //! sets the term structure to be used for pricing + /*! \warning Being a pointer and not a shared_ptr, the term + structure is not guaranteed to remain allocated + for the whole life of the rate helper. It is + responsibility of the programmer to ensure that + the pointer remains valid. It is advised that + this method is called only inside the term + structure being bootstrapped, setting the pointer + to this, i.e., the term structure itself. + */ + public virtual void setTermStructure(TS ts) + { + if (ts == null) + throw new ArgumentException("null term structure given"); + termStructure_ = ts; + } + + // earliest relevant date + // The earliest date at which discounts are needed by the helper in order to provide a quote. + public virtual Date earliestDate() { return earliestDate_; } + + //! instrument's maturity date + public virtual Date maturityDate() + { + if (maturityDate_ == null) + return latestRelevantDate(); + return maturityDate_; + } + + //! latest relevant date + /*! The latest date at which data are needed by the helper + in order to provide a quote. It does not necessarily + equal the maturity of the underlying instrument. + */ + public virtual Date latestRelevantDate() + { + if (latestRelevantDate_ == null) return latestDate(); - return latestRelevantDate_; - } - - //! pillar date - public virtual Date pillarDate() - { - if ( pillarDate_ == null ) - return latestDate(); - return pillarDate_; - } - - // latest relevant date - /* The latest date at which discounts are needed by the helper in order to provide a quote. - * It does not necessarily equal the maturity of the underlying instrument. */ - public virtual Date latestDate() - { - if ( latestDate_ == null ) - return pillarDate_; - return latestDate_; - } - - - #region observer interface - private readonly WeakEventSource eventSource = new WeakEventSource(); - public event Callback notifyObserversEvent - { - add { eventSource.Subscribe(value); } - remove { eventSource.Unsubscribe(value); } - } - - public void registerWith(Callback handler) { notifyObserversEvent += handler; } - public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } - protected void notifyObservers() - { - eventSource.Raise(); - } - - public virtual void update() { notifyObservers(); } - #endregion - } - - public class RateHelper : BootstrapHelper - { - public RateHelper() : base() { } // required for generics - public RateHelper(Handle quote) : base(quote) {} - public RateHelper(double quote) : base (quote) {} - } + return latestRelevantDate_; + } + + //! pillar date + public virtual Date pillarDate() + { + if (pillarDate_ == null) + return latestDate(); + return pillarDate_; + } + + // latest relevant date + /* The latest date at which discounts are needed by the helper in order to provide a quote. + * It does not necessarily equal the maturity of the underlying instrument. */ + public virtual Date latestDate() + { + if (latestDate_ == null) + return pillarDate_; + return latestDate_; + } + + + #region observer interface + private readonly WeakEventSource eventSource = new WeakEventSource(); + public event Callback notifyObserversEvent + { + add + { + eventSource.Subscribe(value); + } + remove + { + eventSource.Unsubscribe(value); + } + } + + public void registerWith(Callback handler) { notifyObserversEvent += handler; } + public void unregisterWith(Callback handler) { notifyObserversEvent -= handler; } + protected void notifyObservers() + { + eventSource.Raise(); + } + + public virtual void update() { notifyObservers(); } + #endregion + } + + public class RateHelper : BootstrapHelper + { + public RateHelper() : base() { } // required for generics + public RateHelper(Handle quote) : base(quote) {} + public RateHelper(double quote) : base(quote) {} + } } diff --git a/src/QLNet/Termstructures/Credit/FlatHazardRate.cs b/src/QLNet/Termstructures/Credit/FlatHazardRate.cs index 9089008a2..3861d07e1 100644 --- a/src/QLNet/Termstructures/Credit/FlatHazardRate.cs +++ b/src/QLNet/Termstructures/Credit/FlatHazardRate.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -36,10 +36,10 @@ public FlatHazardRate(Date referenceDate, Handle hazardRate, DayCounter d public FlatHazardRate(Date referenceDate, double hazardRate, DayCounter dc) : base(referenceDate, new Calendar(), dc) { - hazardRate_ = new Handle( new SimpleQuote(hazardRate)); + hazardRate_ = new Handle(new SimpleQuote(hazardRate)); } - public FlatHazardRate(int settlementDays,Calendar calendar,Handle hazardRate,DayCounter dc) + public FlatHazardRate(int settlementDays, Calendar calendar, Handle hazardRate, DayCounter dc) : base(settlementDays, calendar, dc) { hazardRate_ = hazardRate; @@ -61,9 +61,9 @@ public FlatHazardRate(int settlementDays, Calendar calendar, double hazardRate, #endregion - + #region HazardRateStructure interface - + protected override double hazardRateImpl(double t) { return hazardRate_.link.value(); } #endregion @@ -72,12 +72,12 @@ public FlatHazardRate(int settlementDays, Calendar calendar, double hazardRate, protected override double survivalProbabilityImpl(double t) { - return Math.Exp(-hazardRate_.link.value()*t); + return Math.Exp(-hazardRate_.link.value() * t); } - + #endregion private Handle hazardRate_; - + } } diff --git a/src/QLNet/Termstructures/Credit/HazardRateStructure.cs b/src/QLNet/Termstructures/Credit/HazardRateStructure.cs index 9dc665c02..49a9d5796 100644 --- a/src/QLNet/Termstructures/Credit/HazardRateStructure.cs +++ b/src/QLNet/Termstructures/Credit/HazardRateStructure.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -34,19 +34,19 @@ Hazard rates are defined with annual frequency and continuous \ingroup defaultprobabilitytermstructures */ - public abstract class HazardRateStructure : DefaultProbabilityTermStructure + public abstract class HazardRateStructure : DefaultProbabilityTermStructure { #region Constructors - protected HazardRateStructure(DayCounter dc = null,List > jumps = null,List jumpDates = null) + protected HazardRateStructure(DayCounter dc = null, List > jumps = null, List jumpDates = null) : base(dc, jumps, jumpDates) {} - protected HazardRateStructure(Date referenceDate,Calendar cal = null,DayCounter dc = null, - List > jumps = null,List jumpDates = null) + protected HazardRateStructure(Date referenceDate, Calendar cal = null, DayCounter dc = null, + List > jumps = null, List jumpDates = null) : base(referenceDate, cal, dc, jumps, jumpDates) { } - protected HazardRateStructure(int settlementDays,Calendar cal,DayCounter dc = null, - List > jumps = null,List jumpDates = null) + protected HazardRateStructure(int settlementDays, Calendar cal, DayCounter dc = null, + List > jumps = null, List jumpDates = null) : base(settlementDays, cal, dc, jumps, jumpDates) { } #endregion @@ -79,21 +79,21 @@ implementation is available. protected override double survivalProbabilityImpl(double t) { GaussChebyshevIntegration integral = new GaussChebyshevIntegration(48); - // this stores the address of the method to integrate (so that - // we don't have to insert its full expression inside the - // integral below--it's long enough already) + // this stores the address of the method to integrate (so that + // we don't have to insert its full expression inside the + // integral below--it's long enough already) - // the Gauss-Chebyshev quadratures integrate over [-1,1], - // hence the remapping (and the Jacobian term t/2) - return Math.Exp(-integral.value(hazardRateImpl) * t/2.0); + // the Gauss-Chebyshev quadratures integrate over [-1,1], + // hence the remapping (and the Jacobian term t/2) + return Math.Exp(-integral.value(hazardRateImpl) * t / 2.0); } - + //! default density calculation protected override double defaultDensityImpl(double t) { return hazardRateImpl(t) * survivalProbabilityImpl(t); } - + #endregion } } diff --git a/src/QLNet/Termstructures/Credit/InterpolatedHazardRateCurve.cs b/src/QLNet/Termstructures/Credit/InterpolatedHazardRateCurve.cs index c2548d466..a622f9b10 100644 --- a/src/QLNet/Termstructures/Credit/InterpolatedHazardRateCurve.cs +++ b/src/QLNet/Termstructures/Credit/InterpolatedHazardRateCurve.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,165 +22,165 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class InterpolatedHazardRateCurve : HazardRateStructure,InterpolatedCurve - where Interpolator : IInterpolationFactory, new() - { - public InterpolatedHazardRateCurve( List dates, List hazardRates, DayCounter dayCounter, Calendar cal = null, - List> jumps = null, List jumpDates = null, Interpolator interpolator = default(Interpolator) ) - : base( dates[0], cal, dayCounter, jumps, jumpDates ) - { - dates_ = dates; - times_ = new List(); - data_ = hazardRates; - - if ( interpolator == null ) - interpolator_ = FastActivator.Create(); - else - interpolator_ = interpolator; - - initialize(); - } - - public InterpolatedHazardRateCurve( List dates,List hazardRates,DayCounter dayCounter,Calendar calendar, - Interpolator interpolator) - :base(dates[0], calendar, dayCounter) - { - dates_ = dates; - times_ = new List(); - data_ = hazardRates; - if ( interpolator == null ) - interpolator_ = FastActivator.Create(); - else - interpolator_ = interpolator; - initialize(); - } - - public InterpolatedHazardRateCurve( List dates, List hazardRates, DayCounter dayCounter, Interpolator interpolator ) - : base( dates[0], null, dayCounter ) - { - dates_ = dates; - if ( interpolator == null ) - interpolator_ = FastActivator.Create(); - else - interpolator_ = interpolator; - initialize(); - } - - - public List hazardRates() { return this.data_; } - - protected InterpolatedHazardRateCurve( DayCounter dc, - List> jumps = null, - List jumpDates = null, - Interpolator interpolator = default(Interpolator) ) - : base( dc, jumps, jumpDates ) - { } - - protected InterpolatedHazardRateCurve( Date referenceDate, DayCounter dc, - List> jumps = null, - List jumpDates = null, - Interpolator interpolator = default(Interpolator) ) - : base( referenceDate, null, dc, jumps, jumpDates ) - { } - - protected InterpolatedHazardRateCurve( int settlementDays, Calendar cal, DayCounter dc, - List> jumps = null, - List jumpDates = null, - Interpolator interpolator = default(Interpolator) ) - : base( settlementDays, cal, dc, jumps, jumpDates ) - {} + public class InterpolatedHazardRateCurve : HazardRateStructure, InterpolatedCurve + where Interpolator : IInterpolationFactory, new () + { + public InterpolatedHazardRateCurve(List dates, List hazardRates, DayCounter dayCounter, Calendar cal = null, + List> jumps = null, List jumpDates = null, Interpolator interpolator = default(Interpolator)) + : base(dates[0], cal, dayCounter, jumps, jumpDates) + { + dates_ = dates; + times_ = new List(); + data_ = hazardRates; + + if (interpolator == null) + interpolator_ = FastActivator.Create(); + else + interpolator_ = interpolator; + + initialize(); + } + + public InterpolatedHazardRateCurve(List dates, List hazardRates, DayCounter dayCounter, Calendar calendar, + Interpolator interpolator) + : base(dates[0], calendar, dayCounter) + { + dates_ = dates; + times_ = new List(); + data_ = hazardRates; + if (interpolator == null) + interpolator_ = FastActivator.Create(); + else + interpolator_ = interpolator; + initialize(); + } + + public InterpolatedHazardRateCurve(List dates, List hazardRates, DayCounter dayCounter, Interpolator interpolator) + : base(dates[0], null, dayCounter) + { + dates_ = dates; + if (interpolator == null) + interpolator_ = FastActivator.Create(); + else + interpolator_ = interpolator; + initialize(); + } + + + public List hazardRates() { return this.data_; } + + protected InterpolatedHazardRateCurve(DayCounter dc, + List> jumps = null, + List jumpDates = null, + Interpolator interpolator = default(Interpolator)) + : base(dc, jumps, jumpDates) + { } + + protected InterpolatedHazardRateCurve(Date referenceDate, DayCounter dc, + List> jumps = null, + List jumpDates = null, + Interpolator interpolator = default(Interpolator)) + : base(referenceDate, null, dc, jumps, jumpDates) + { } + + protected InterpolatedHazardRateCurve(int settlementDays, Calendar cal, DayCounter dc, + List> jumps = null, + List jumpDates = null, + Interpolator interpolator = default(Interpolator)) + : base(settlementDays, cal, dc, jumps, jumpDates) + {} // DefaultProbabilityTermStructure implementation - protected override double hazardRateImpl( double t ) - { - if ( t <= this.times_.Last() ) - return this.interpolation_.value( t, true ); - - // flat hazard rate extrapolation - return this.data_.Last(); - } - protected override double survivalProbabilityImpl( double t ) - { - if (t.IsEqual(0.0)) + protected override double hazardRateImpl(double t) + { + if (t <= this.times_.Last()) + return this.interpolation_.value(t, true); + + // flat hazard rate extrapolation + return this.data_.Last(); + } + protected override double survivalProbabilityImpl(double t) + { + if (t.IsEqual(0.0)) return 1.0; - double integral; - if (t <= this.times_.Last()) - { + double integral; + if (t <= this.times_.Last()) + { integral = this.interpolation_.primitive(t, true); - } - else - { + } + else + { // flat hazard rate extrapolation integral = this.interpolation_.primitive(this.times_.Last(), true) - + this.data_.Last()*(t - this.times_.Last()); - } - return Math.Exp(-integral); - } - - private void initialize() - { - Utils.QL_REQUIRE( dates_.Count >= interpolator_.requiredPoints, () => "not enough input dates given" ); - Utils.QL_REQUIRE( this.data_.Count == dates_.Count, () => "dates/data count mismatch" ); - - this.times_.Add(0.0); - for (int i=1; i dates_[i - 1], () => "invalid date (" + dates_[i] + ", vs " + dates_[i - 1] + ")" ); - this.times_.Add( dayCounter().yearFraction( dates_[0], dates_[i] ) ); - Utils.QL_REQUIRE( !Utils.close( this.times_[i], this.times_[i - 1] ), () => "two dates correspond to the same time " + - "under this curve's day count convention"); - Utils.QL_REQUIRE( this.data_[i] >= 0.0, () => "negative hazard rate" ); - } - - setupInterpolation(); - this.interpolation_.update(); - } - - #region InterpolatedCurve - - public List times_ { get; set; } - public List times() { return this.times_; } - - public List dates_ { get; set; } - public List dates() { return dates_; } - public Date maxDate_ { get; set; } - public override Date maxDate() - { - if ( maxDate_ != null ) - return maxDate_; - - return dates_.Last(); - } - - public List data_ { get; set; } - public List discounts() { return this.data_; } - public List data() { return discounts(); } - - public Interpolation interpolation_ { get; set; } - public IInterpolationFactory interpolator_ { get; set; } - - public Dictionary nodes() - { - Dictionary results = new Dictionary(); - dates_.ForEach( ( i, x ) => results.Add( x, data_[i] ) ); - return results; - } - - public void setupInterpolation() - { - interpolation_ = interpolator_.interpolate( times_, times_.Count, data_ ); - } - - public object Clone() - { - InterpolatedCurve copy = this.MemberwiseClone() as InterpolatedCurve; - copy.times_ = new List( times_ ); - copy.data_ = new List( data_ ); - copy.interpolator_ = interpolator_; - copy.setupInterpolation(); - return copy; - } - #endregion - } + + this.data_.Last() * (t - this.times_.Last()); + } + return Math.Exp(-integral); + } + + private void initialize() + { + Utils.QL_REQUIRE(dates_.Count >= interpolator_.requiredPoints, () => "not enough input dates given"); + Utils.QL_REQUIRE(this.data_.Count == dates_.Count, () => "dates/data count mismatch"); + + this.times_.Add(0.0); + for (int i = 1; i < dates_.Count; ++i) + { + Utils.QL_REQUIRE(dates_[i] > dates_[i - 1], () => "invalid date (" + dates_[i] + ", vs " + dates_[i - 1] + ")"); + this.times_.Add(dayCounter().yearFraction(dates_[0], dates_[i])); + Utils.QL_REQUIRE(!Utils.close(this.times_[i], this.times_[i - 1]), () => "two dates correspond to the same time " + + "under this curve's day count convention"); + Utils.QL_REQUIRE(this.data_[i] >= 0.0, () => "negative hazard rate"); + } + + setupInterpolation(); + this.interpolation_.update(); + } + + #region InterpolatedCurve + + public List times_ { get; set; } + public List times() { return this.times_; } + + public List dates_ { get; set; } + public List dates() { return dates_; } + public Date maxDate_ { get; set; } + public override Date maxDate() + { + if (maxDate_ != null) + return maxDate_; + + return dates_.Last(); + } + + public List data_ { get; set; } + public List discounts() { return this.data_; } + public List data() { return discounts(); } + + public Interpolation interpolation_ { get; set; } + public IInterpolationFactory interpolator_ { get; set; } + + public Dictionary nodes() + { + Dictionary results = new Dictionary(); + dates_.ForEach((i, x) => results.Add(x, data_[i])); + return results; + } + + public void setupInterpolation() + { + interpolation_ = interpolator_.interpolate(times_, times_.Count, data_); + } + + public object Clone() + { + InterpolatedCurve copy = this.MemberwiseClone() as InterpolatedCurve; + copy.times_ = new List(times_); + copy.data_ = new List(data_); + copy.interpolator_ = interpolator_; + copy.setupInterpolation(); + return copy; + } + #endregion + } } diff --git a/src/QLNet/Termstructures/Credit/InterpolatedSurvivalProbabilityCurve.cs b/src/QLNet/Termstructures/Credit/InterpolatedSurvivalProbabilityCurve.cs index dfd10ce63..9bce632c5 100644 --- a/src/QLNet/Termstructures/Credit/InterpolatedSurvivalProbabilityCurve.cs +++ b/src/QLNet/Termstructures/Credit/InterpolatedSurvivalProbabilityCurve.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,44 +24,44 @@ namespace QLNet /// /// public class InterpolatedSurvivalProbabilityCurve : SurvivalProbabilityStructure, - InterpolatedCurve where Interpolator : IInterpolationFactory, new() + InterpolatedCurve where Interpolator : IInterpolationFactory, new () { - public InterpolatedSurvivalProbabilityCurve( List dates, - List probabilities, - DayCounter dayCounter, - Calendar calendar = null, - List> jumps = null, - List jumpDates = null, - Interpolator interpolator = default(Interpolator)) - :base(dates[0], calendar, dayCounter, jumps, jumpDates) + public InterpolatedSurvivalProbabilityCurve(List dates, + List probabilities, + DayCounter dayCounter, + Calendar calendar = null, + List> jumps = null, + List jumpDates = null, + Interpolator interpolator = default(Interpolator)) + : base(dates[0], calendar, dayCounter, jumps, jumpDates) { dates_ = dates; - Utils.QL_REQUIRE(dates_.Count >= interpolator.requiredPoints,()=> "not enough input dates given"); - Utils.QL_REQUIRE(this.data_.Count == dates_.Count,()=> "dates/data count mismatch"); - Utils.QL_REQUIRE(this.data_[0].IsEqual(1.0),()=> "the first probability must be == 1.0 to flag the corresponding date as reference date"); + Utils.QL_REQUIRE(dates_.Count >= interpolator.requiredPoints, () => "not enough input dates given"); + Utils.QL_REQUIRE(this.data_.Count == dates_.Count, () => "dates/data count mismatch"); + Utils.QL_REQUIRE(this.data_[0].IsEqual(1.0), () => "the first probability must be == 1.0 to flag the corresponding date as reference date"); this.times_ = new InitializedList(dates_.Count); this.times_[0] = 0.0; for (int i = 1; i < dates_.Count; ++i) { - Utils.QL_REQUIRE(dates_[i] > dates_[i - 1],()=> - "invalid date (" + dates_[i] + ", vs " + dates_[i - 1] + ")"); + Utils.QL_REQUIRE(dates_[i] > dates_[i - 1], () => + "invalid date (" + dates_[i] + ", vs " + dates_[i - 1] + ")"); this.times_[i] = dayCounter.yearFraction(dates_[0], dates_[i]); - Utils.QL_REQUIRE(!Utils.close(this.times_[i], this.times_[i - 1]),()=> - "two dates correspond to the same time under this curve's day count convention"); - Utils.QL_REQUIRE(this.data_[i] > 0.0,()=> "negative probability"); - Utils.QL_REQUIRE(this.data_[i] <= this.data_[i - 1],()=> - "negative hazard rate implied by the survival probability " + - this.data_[i] + " at " + dates_[i] + - " (t=" + this.times_[i] + ") after the survival probability " + - this.data_[i - 1] + " at " + dates_[i - 1] + - " (t=" + this.times_[i - 1] + ")"); + Utils.QL_REQUIRE(!Utils.close(this.times_[i], this.times_[i - 1]), () => + "two dates correspond to the same time under this curve's day count convention"); + Utils.QL_REQUIRE(this.data_[i] > 0.0, () => "negative probability"); + Utils.QL_REQUIRE(this.data_[i] <= this.data_[i - 1], () => + "negative hazard rate implied by the survival probability " + + this.data_[i] + " at " + dates_[i] + + " (t=" + this.times_[i] + ") after the survival probability " + + this.data_[i - 1] + " at " + dates_[i - 1] + + " (t=" + this.times_[i - 1] + ")"); } this.interpolation_ = this.interpolator_.interpolate(this.times_, - this.times_.Count, - this.data_); + this.times_.Count, + this.data_); this.interpolation_.update(); } @@ -82,27 +82,27 @@ public Dictionary nodes() dates_.ForEach((i, x) => results.Add(x, data_[i])); return results; } - - protected InterpolatedSurvivalProbabilityCurve( DayCounter dc, - List> jumps = null, - List jumpDates = null, - Interpolator interpolator = default(Interpolator)) - :base(dc, jumps, jumpDates) { } - - protected InterpolatedSurvivalProbabilityCurve( Date referenceDate, - DayCounter dc, - List> jumps = null, - List jumpDates = null, - Interpolator interpolator = default(Interpolator)) - :base(referenceDate, new Calendar(), dc, jumps, jumpDates) { } - - protected InterpolatedSurvivalProbabilityCurve( int settlementDays, - Calendar cal, - DayCounter dc, - List> jumps = null, - List jumpDates = null, - Interpolator interpolator = default(Interpolator)) - :base(settlementDays, cal, dc, jumps, jumpDates) { } + + protected InterpolatedSurvivalProbabilityCurve(DayCounter dc, + List> jumps = null, + List jumpDates = null, + Interpolator interpolator = default(Interpolator)) + : base(dc, jumps, jumpDates) { } + + protected InterpolatedSurvivalProbabilityCurve(Date referenceDate, + DayCounter dc, + List> jumps = null, + List jumpDates = null, + Interpolator interpolator = default(Interpolator)) + : base(referenceDate, new Calendar(), dc, jumps, jumpDates) { } + + protected InterpolatedSurvivalProbabilityCurve(int settlementDays, + Calendar cal, + DayCounter dc, + List> jumps = null, + List jumpDates = null, + Interpolator interpolator = default(Interpolator)) + : base(settlementDays, cal, dc, jumps, jumpDates) { } /// /// DefaultProbabilityTermStructure implementation diff --git a/src/QLNet/Termstructures/Credit/ProbabilityTraits.cs b/src/QLNet/Termstructures/Credit/ProbabilityTraits.cs index b904c5447..9975e42c2 100644 --- a/src/QLNet/Termstructures/Credit/ProbabilityTraits.cs +++ b/src/QLNet/Termstructures/Credit/ProbabilityTraits.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -25,7 +25,7 @@ namespace QLNet /// /// Survival-Probability-curve traits /// - public class SurvivalProbability : ITraits + public class SurvivalProbability : ITraits { const double avgHazardRate = 0.01; const double maxHazardRate = 1.0; @@ -38,7 +38,7 @@ public class SurvivalProbability : ITraits public double discountImpl(Interpolation i, double t) { return i.value(t, true); } public double zeroYieldImpl(Interpolation i, double t) { throw new NotSupportedException(); } public double forwardImpl(Interpolation i, double t) { throw new NotSupportedException(); } - + public double guess(int i, InterpolatedCurve c, bool validData, int f) { if (validData) // previous iteration value @@ -70,7 +70,7 @@ public double maxValueAfter(int i, InterpolatedCurve c, bool validData, int f) } /// - /// Hazard-rate-curve traits + /// Hazard-rate-curve traits /// public class HazardRate : ITraits { @@ -85,7 +85,7 @@ public double initialValue(DefaultProbabilityTermStructure c) { return avgHazardRate; } - public double guess(int i, InterpolatedCurve c,bool validData,int f) + public double guess(int i, InterpolatedCurve c, bool validData, int f) { if (validData) // previous iteration value return c.data()[i]; @@ -97,7 +97,7 @@ public double guess(int i, InterpolatedCurve c,bool validData,int f) Date d = c.dates()[i]; return ((DefaultProbabilityTermStructure)c).hazardRate(d, true); } - public double minValueAfter(int i, InterpolatedCurve c,bool validData,int f) + public double minValueAfter(int i, InterpolatedCurve c, bool validData, int f) { if (validData) { @@ -106,7 +106,7 @@ public double minValueAfter(int i, InterpolatedCurve c,bool validData,int f) } return Const.QL_EPSILON; } - public double maxValueAfter(int i, InterpolatedCurve c,bool validData,int f) + public double maxValueAfter(int i, InterpolatedCurve c, bool validData, int f) { if (validData) { @@ -117,7 +117,7 @@ public double maxValueAfter(int i, InterpolatedCurve c,bool validData,int f) // We choose as max a value very unlikely to be exceeded. return maxHazardRate; } - public void updateGuess(List data,double rate,int i) + public void updateGuess(List data, double rate, int i) { data[i] = rate; if (i == 1) @@ -138,7 +138,7 @@ public class DefaultDensity : ITraits const double avgHazardRate = 0.01; const double maxHazardRate = 1.0; - public Date initialDate( DefaultProbabilityTermStructure c) + public Date initialDate(DefaultProbabilityTermStructure c) { return c.referenceDate(); } @@ -146,7 +146,7 @@ public double initialValue(DefaultProbabilityTermStructure c) { return avgHazardRate; } - public double guess(int i,InterpolatedCurve c,bool validData,int f) + public double guess(int i, InterpolatedCurve c, bool validData, int f) { if (validData) // previous iteration value return c.data()[i]; @@ -158,7 +158,7 @@ public double guess(int i,InterpolatedCurve c,bool validData,int f) Date d = c.dates()[i]; return ((DefaultProbabilityTermStructure)c).defaultDensity(d, true); } - public double minValueAfter(int i,InterpolatedCurve c,bool validData,int f) + public double minValueAfter(int i, InterpolatedCurve c, bool validData, int f) { if (validData) { @@ -167,7 +167,7 @@ public double minValueAfter(int i,InterpolatedCurve c,bool validData,int f) } return Const.QL_EPSILON; } - public double maxValueAfter(int i,InterpolatedCurve c,bool validData,int f) + public double maxValueAfter(int i, InterpolatedCurve c, bool validData, int f) { if (validData) { @@ -178,7 +178,7 @@ public double maxValueAfter(int i,InterpolatedCurve c,bool validData,int f) // We choose as max a value very unlikely to be exceeded. return maxHazardRate; } - public void updateGuess(List data,double density,int i) + public void updateGuess(List data, double density, int i) { data[i] = density; if (i == 1) diff --git a/src/QLNet/Termstructures/Credit/SurvivalProbabilityStructure.cs b/src/QLNet/Termstructures/Credit/SurvivalProbabilityStructure.cs index 1de8975d2..644d658dc 100644 --- a/src/QLNet/Termstructures/Credit/SurvivalProbabilityStructure.cs +++ b/src/QLNet/Termstructures/Credit/SurvivalProbabilityStructure.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -32,22 +32,22 @@ namespace QLNet /// public abstract class SurvivalProbabilityStructure : DefaultProbabilityTermStructure { - public SurvivalProbabilityStructure( DayCounter dayCounter = null, - List> jumps = null, - List jumpDates = null) - :base(dayCounter, jumps, jumpDates) {} - public SurvivalProbabilityStructure( Date referenceDate, - Calendar cal = null, - DayCounter dayCounter = null, - List> jumps = null, - List jumpDates = null) + public SurvivalProbabilityStructure(DayCounter dayCounter = null, + List> jumps = null, + List jumpDates = null) + : base(dayCounter, jumps, jumpDates) {} + public SurvivalProbabilityStructure(Date referenceDate, + Calendar cal = null, + DayCounter dayCounter = null, + List> jumps = null, + List jumpDates = null) : base(referenceDate, cal, dayCounter, jumps, jumpDates) { } - public SurvivalProbabilityStructure( int settlementDays, - Calendar cal, - DayCounter dayCounter = null, - List> jumps = null, - List jumpDates = null) + public SurvivalProbabilityStructure(int settlementDays, + Calendar cal, + DayCounter dayCounter = null, + List> jumps = null, + List jumpDates = null) : base(settlementDays, cal, dayCounter, jumps, jumpDates) { } /// diff --git a/src/QLNet/Termstructures/Curve.cs b/src/QLNet/Termstructures/Curve.cs index bdc8792a9..9aa5863b1 100644 --- a/src/QLNet/Termstructures/Curve.cs +++ b/src/QLNet/Termstructures/Curve.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2014 Edem Dawui (edawui@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,28 +20,28 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public interface Curve : ITraits, InterpolatedCurve - { - #region ITraits + public interface Curve : ITraits, InterpolatedCurve + { + #region ITraits - //protected - ITraits traits_ { get; } - #endregion + //protected + ITraits traits_ { get; } + #endregion - #region InterpolatedCurve - #endregion + #region InterpolatedCurve + #endregion - List> instruments_ { get; } - void setTermStructure( BootstrapHelper helper ); + List> instruments_ { get; } + void setTermStructure(BootstrapHelper helper); - double accuracy_ { get; } - bool moving_ { get; } + double accuracy_ { get; } + bool moving_ { get; } - void registerWith( BootstrapHelper helper ); - Date initialDate(); + void registerWith(BootstrapHelper helper); + Date initialDate(); - double timeFromReference( Date d ); - double initialValue(); - } + double timeFromReference(Date d); + double initialValue(); + } } \ No newline at end of file diff --git a/src/QLNet/Termstructures/DefaultProbabilityTermStructure.cs b/src/QLNet/Termstructures/DefaultProbabilityTermStructure.cs index 891fe74c4..994d9dcae 100644 --- a/src/QLNet/Termstructures/DefaultProbabilityTermStructure.cs +++ b/src/QLNet/Termstructures/DefaultProbabilityTermStructure.cs @@ -1,25 +1,25 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System.Collections.Generic; -namespace QLNet +namespace QLNet { //! Default probability term structure /*! This abstract class defines the interface of concrete @@ -27,19 +27,19 @@ credit structures which will be derived from this one. \ingroup defaultprobabilitytermstructures */ - public abstract class DefaultProbabilityTermStructure : TermStructure + public abstract class DefaultProbabilityTermStructure : TermStructure { #region Constructors - protected DefaultProbabilityTermStructure(DayCounter dc = null,List > jumps = null,List jumpDates = null) - :base(dc) + protected DefaultProbabilityTermStructure(DayCounter dc = null, List > jumps = null, List jumpDates = null) + : base(dc) { - if ( jumps != null ) + if (jumps != null) jumps_ = jumps; else jumps_ = new List>(); - if ( jumpDates != null ) + if (jumpDates != null) jumpDates_ = jumpDates; else jumpDates_ = new List(); @@ -47,20 +47,20 @@ protected DefaultProbabilityTermStructure(DayCounter dc = null,List(jumpDates_.Count); nJumps_ = jumps_.Count; setJumps(); - for (int i=0; i > jumps = null,List jumpDates = null) - :base(referenceDate, cal, dc) + protected DefaultProbabilityTermStructure(Date referenceDate, Calendar cal = null, DayCounter dc = null, + List > jumps = null, List jumpDates = null) + : base(referenceDate, cal, dc) { - if ( jumps != null ) + if (jumps != null) jumps_ = jumps; else jumps_ = new List>(); - if ( jumpDates != null ) + if (jumpDates != null) jumpDates_ = jumpDates; else jumpDates_ = new List(); @@ -68,20 +68,20 @@ protected DefaultProbabilityTermStructure(Date referenceDate,Calendar cal = null jumpTimes_ = new List(jumpDates_.Count); nJumps_ = jumps_.Count; setJumps(); - for (int i=0; i > jumps = null,List jumpDates = null) - : base(settlementDays, cal, dc) + protected DefaultProbabilityTermStructure(int settlementDays, Calendar cal, DayCounter dc = null, + List > jumps = null, List jumpDates = null) + : base(settlementDays, cal, dc) { - if ( jumps != null ) + if (jumps != null) jumps_ = jumps; else jumps_ = new List>(); - if ( jumpDates != null ) + if (jumpDates != null) jumpDates_ = jumpDates; else jumpDates_ = new List(); @@ -89,7 +89,7 @@ protected DefaultProbabilityTermStructure(int settlementDays,Calendar cal,DayCou jumpTimes_ = new List(jumpDates_.Count); nJumps_ = jumps_.Count; setJumps(); - for (int i=0; i "invalid " + ( i + 1 ) + " jump quote" ); - double thisJump = jumps_[i].link.value(); - Utils.QL_REQUIRE( thisJump > 0.0 && thisJump <= 1.0, () => "invalid " + ( i + 1 ) + " jump value: " + thisJump ); - jumpEffect *= thisJump; + for (int i = 0; i < nJumps_ && jumpTimes_[i] < t; ++i) + { + Utils.QL_REQUIRE(jumps_[i].link.isValid(), () => "invalid " + (i + 1) + " jump quote"); + double thisJump = jumps_[i].link.value(); + Utils.QL_REQUIRE(thisJump > 0.0 && thisJump <= 1.0, () => "invalid " + (i + 1) + " jump value: " + thisJump); + jumpEffect *= thisJump; } return jumpEffect * survivalProbabilityImpl(t); - } + } - return survivalProbabilityImpl(t); + return survivalProbabilityImpl(t); } #endregion @@ -133,7 +135,7 @@ public double survivalProbability(double t, bool extrapolate = false) // These methods return the default probability from the reference // date until a given date or time. In the latter case, the time // is calculated as a fraction of year from the reference date. - public double defaultProbability(Date d, bool extrapolate = false) + public double defaultProbability(Date d, bool extrapolate = false) { return 1.0 - survivalProbability(d, extrapolate); } @@ -141,23 +143,23 @@ public double defaultProbability(Date d, bool extrapolate = false) /*! The same day-counting rule used by the term structure should be used for calculating the passed time t. */ - public double defaultProbability(double t,bool extrapolate = false) + public double defaultProbability(double t, bool extrapolate = false) { - return 1.0 - survivalProbability(t, extrapolate); + return 1.0 - survivalProbability(t, extrapolate); } //! probability of default between two given dates - public double defaultProbability(Date d1,Date d2, bool extrapolate = false) + public double defaultProbability(Date d1, Date d2, bool extrapolate = false) { - Utils.QL_REQUIRE( d1 <= d2, () => "initial date (" + d1 + ") later than final date (" + d2 + ")" ); - double p1 = d1 < referenceDate() ? 0.0 : defaultProbability(d1,extrapolate), p2 = defaultProbability(d2,extrapolate); + Utils.QL_REQUIRE(d1 <= d2, () => "initial date (" + d1 + ") later than final date (" + d2 + ")"); + double p1 = d1 < referenceDate() ? 0.0 : defaultProbability(d1, extrapolate), p2 = defaultProbability(d2, extrapolate); return p2 - p1; } //! probability of default between two given times public double defaultProbability(double t1, double t2, bool extrapo = false) { - Utils.QL_REQUIRE( t1 <= t2, () => "initial time (" + t1 + ") later than final time (" + t2 + ")" ); - double p1 = t1 < 0.0 ? 0.0 : defaultProbability(t1,extrapolate), p2 = defaultProbability(t2,extrapolate); + Utils.QL_REQUIRE(t1 <= t2, () => "initial time (" + t1 + ") later than final time (" + t2 + ")"); + double p1 = t1 < 0.0 ? 0.0 : defaultProbability(t1, extrapolate), p2 = defaultProbability(t2, extrapolate); return p2 - p1; } @@ -187,7 +189,7 @@ public double defaultDensity(double t, bool extrapolate = false) // These methods returns the hazard rate at a given date or time. // In the latter case, the time is calculated as a fraction of year // from the reference date. - // + // // Hazard rates are defined with annual frequency and continuous // compounding. @@ -199,20 +201,20 @@ public double hazardRate(Date d, bool extrapolate = false) public double hazardRate(double t, bool extrapolate = false) { double S = survivalProbability(t, extrapolate); - return S.IsEqual(0.0) ? 0.0 : defaultDensity(t, extrapolate)/S; + return S.IsEqual(0.0) ? 0.0 : defaultDensity(t, extrapolate) / S; } #endregion #region Jump inspectors - + public List jumpDates() { return this.jumpDates_;} public List jumpTimes() {return this.jumpTimes_;} #endregion #region Observer interface - + public override void update() { base.update(); @@ -222,9 +224,9 @@ public override void update() #endregion - + #region Calculations - + // These methods must be implemented in derived classes to // perform the actual calculations. When they are called, // range check has already been performed; therefore, they @@ -232,36 +234,36 @@ public override void update() //! survival probability calculation protected abstract double survivalProbabilityImpl(double t); - + //! default density calculation protected abstract double defaultDensityImpl(double t); - + #endregion - + // methods private void setJumps() { - if (jumpDates_.empty() && !jumps_.empty()) - { + if (jumpDates_.empty() && !jumps_.empty()) + { // turn of year dates jumpDates_.Clear(); jumpTimes_.Clear(); int y = referenceDate().year(); - for (int i=0; i - "mismatch between number of jumps (" + nJumps_ + - ") and jump dates (" + jumpDates_.Count + ")"); - } - for (int i=0; i + "mismatch between number of jumps (" + nJumps_ + + ") and jump dates (" + jumpDates_.Count + ")"); + } + for (int i = 0; i < nJumps_; ++i) jumpTimes_.Add(timeFromReference(jumpDates_[i])); - + latestReference_ = base.referenceDate(); } // data members @@ -270,5 +272,5 @@ private void setJumps() private List jumpTimes_; private int nJumps_; private Date latestReference_; - } + } } diff --git a/src/QLNet/Termstructures/Inflation/CPICapFloorTermPriceSurface.cs b/src/QLNet/Termstructures/Inflation/CPICapFloorTermPriceSurface.cs index 6dc98fc21..799a78a69 100644 --- a/src/QLNet/Termstructures/Inflation/CPICapFloorTermPriceSurface.cs +++ b/src/QLNet/Termstructures/Inflation/CPICapFloorTermPriceSurface.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,11 +20,11 @@ namespace QLNet { //! Provides cpi cap/floor prices by interpolation and put/call parity (not cap/floor/swap* parity). - /*! + /*! The inflation index MUST contain a ZeroInflationTermStructure as this is used to create ATM. Unlike YoY price surfaces we assume that 1) an ATM ZeroInflationTermStructure is available - and 2) that it is safe to use it. This is supported by the + and 2) that it is safe to use it. This is supported by the fact that no stripping is required for CPI cap/floors as they only give one flow. @@ -34,15 +34,15 @@ their maturity. Options are on CPI(T)/CPI(0) but strikes are quoted for yearly average inflation, so require transformation via (1+quote)^T to obtain actual strikes. These are consistent with ZCIIS quoting conventions. - + The observationLag is that for the referenced instrument prices. - Strikes are as-quoted not as-used. - */ + Strikes are as-quoted not as-used. + */ public abstract class CPICapFloorTermPriceSurface : InflationTermStructure { - protected CPICapFloorTermPriceSurface(double nominal, + protected CPICapFloorTermPriceSurface(double nominal, double baseRate, // avoids an uncontrolled crash if index has no TS - Period observationLag, + Period observationLag, Calendar cal, // calendar in index may not be useful BusinessDayConvention bdc, DayCounter dc, @@ -53,53 +53,53 @@ protected CPICapFloorTermPriceSurface(double nominal, List cfMaturities, Matrix cPrice, Matrix fPrice) - :base(0, cal, baseRate, observationLag, zii.link.frequency(), zii.link.interpolated(), yts, dc) + : base(0, cal, baseRate, observationLag, zii.link.frequency(), zii.link.interpolated(), yts, dc) { - zii_ = zii; - cStrikes_ = cStrikes; + zii_ = zii; + cStrikes_ = cStrikes; fStrikes_ = fStrikes; - cfMaturities_ = cfMaturities; - cPrice_ = cPrice; + cfMaturities_ = cfMaturities; + cPrice_ = cPrice; fPrice_ = fPrice; nominal_ = nominal; bdc_ = bdc; // does the index have a TS? - Utils.QL_REQUIRE(!zii_.link.zeroInflationTermStructure().empty(),()=>"ZITS missing from index"); - Utils.QL_REQUIRE(!nominalTermStructure().empty(),()=>"nominal TS missing"); - + Utils.QL_REQUIRE(!zii_.link.zeroInflationTermStructure().empty(), () => "ZITS missing from index"); + Utils.QL_REQUIRE(!nominalTermStructure().empty(), () => "nominal TS missing"); + // data consistency checking, enough data? - Utils.QL_REQUIRE(fStrikes_.Count > 1,()=> "not enough floor strikes"); - Utils.QL_REQUIRE(cStrikes_.Count > 1,()=> "not enough cap strikes"); - Utils.QL_REQUIRE(cfMaturities_.Count > 1,()=> "not enough maturities"); - Utils.QL_REQUIRE(fStrikes_.Count == fPrice.rows(),()=> "floor strikes vs floor price rows not equal"); - Utils.QL_REQUIRE(cStrikes_.Count == cPrice.rows(),()=> "cap strikes vs cap price rows not equal"); - Utils.QL_REQUIRE(cfMaturities_.Count == fPrice.columns(),()=> "maturities vs floor price columns not equal"); - Utils.QL_REQUIRE(cfMaturities_.Count == cPrice.columns(),()=> "maturities vs cap price columns not equal"); + Utils.QL_REQUIRE(fStrikes_.Count > 1, () => "not enough floor strikes"); + Utils.QL_REQUIRE(cStrikes_.Count > 1, () => "not enough cap strikes"); + Utils.QL_REQUIRE(cfMaturities_.Count > 1, () => "not enough maturities"); + Utils.QL_REQUIRE(fStrikes_.Count == fPrice.rows(), () => "floor strikes vs floor price rows not equal"); + Utils.QL_REQUIRE(cStrikes_.Count == cPrice.rows(), () => "cap strikes vs cap price rows not equal"); + Utils.QL_REQUIRE(cfMaturities_.Count == fPrice.columns(), () => "maturities vs floor price columns not equal"); + Utils.QL_REQUIRE(cfMaturities_.Count == cPrice.columns(), () => "maturities vs cap price columns not equal"); // data has correct properties (positive, monotonic)? - for(int j = 0; j new Period(0,TimeUnit.Days),()=> "non-positive maturities"); - if(j>0) + Utils.QL_REQUIRE(cfMaturities[j] > new Period(0, TimeUnit.Days), () => "non-positive maturities"); + if (j > 0) { - Utils.QL_REQUIRE( cfMaturities[j] > cfMaturities[j-1],()=> "non-increasing maturities"); + Utils.QL_REQUIRE(cfMaturities[j] > cfMaturities[j - 1], () => "non-increasing maturities"); } - for(int i = 0; i 0.0,()=> "non-positive floor price: " + fPrice_[i,j] ); - if(i>0) + Utils.QL_REQUIRE(fPrice_[i, j] > 0.0, () => "non-positive floor price: " + fPrice_[i, j]); + if (i > 0) { - Utils.QL_REQUIRE( fPrice_[i,j] >= fPrice_[i-1,j],()=> "non-increasing floor prices"); + Utils.QL_REQUIRE(fPrice_[i, j] >= fPrice_[i - 1, j], () => "non-increasing floor prices"); } } - for(int i = 0; i 0.0,()=> "non-positive cap price: " + cPrice_[i,j] ); - if(i>0) + Utils.QL_REQUIRE(cPrice_[i, j] > 0.0, () => "non-positive cap price: " + cPrice_[i, j]); + if (i > 0) { - Utils.QL_REQUIRE( cPrice_[i,j] <= cPrice_[i-1,j],()=> "non-decreasing cap prices: " - + cPrice_[i,j] + " then " + cPrice_[i-1,j]); + Utils.QL_REQUIRE(cPrice_[i, j] <= cPrice_[i - 1, j], () => "non-decreasing cap prices: " + + cPrice_[i, j] + " then " + cPrice_[i - 1, j]); } } } @@ -109,26 +109,27 @@ protected CPICapFloorTermPriceSurface(double nominal, // expected between caps and floors but that no overlap in the // output is allowed so no repeats or overlaps are used cfStrikes_ = new List(); - for(int i = 0; i maxFstrike + eps) cfStrikes_.Add(k); + if (k > maxFstrike + eps) + cfStrikes_.Add(k); } // final consistency checking - Utils.QL_REQUIRE(cfStrikes_.Count > 2,()=> "overall not enough strikes"); + Utils.QL_REQUIRE(cfStrikes_.Count > 2, () => "overall not enough strikes"); for (int i = 1; i < cfStrikes_.Count; i++) - Utils.QL_REQUIRE( cfStrikes_[i] > cfStrikes_[i-1],()=> "cfStrikes not increasing"); + Utils.QL_REQUIRE(cfStrikes_[i] > cfStrikes_[i - 1], () => "cfStrikes not increasing"); } // InflationTermStructure interface public override Period observationLag() { - return zeroInflationIndex().link.zeroInflationTermStructure().link.observationLag(); + return zeroInflationIndex().link.zeroInflationTermStructure().link.observationLag(); } public override Date baseDate() { @@ -146,53 +147,53 @@ without checking the ZeroInflation ATM level. public virtual double nominal() {return nominal_;} public virtual BusinessDayConvention businessDayConvention() {return bdc_;} - //! \warning you MUST remind the compiler in any descendants with the using:: mechanism + //! \warning you MUST remind the compiler in any descendants with the using:: mechanism //! because you overload the names //! remember that the strikes use the quoting convention - public virtual double price( Period d, double k) + public virtual double price(Period d, double k) { return this.price(cpiOptionDateFromTenor(d), k); } - public virtual double capPrice( Period d, double k) + public virtual double capPrice(Period d, double k) { return this.capPrice(cpiOptionDateFromTenor(d), k); } - public virtual double floorPrice( Period d, double k) + public virtual double floorPrice(Period d, double k) { return this.floorPrice(cpiOptionDateFromTenor(d), k); } - public abstract double price( Date d, double k) ; - public abstract double capPrice( Date d, double k) ; - public abstract double floorPrice( Date d, double k) ; - + public abstract double price(Date d, double k) ; + public abstract double capPrice(Date d, double k) ; + public abstract double floorPrice(Date d, double k) ; + public virtual List strikes() {return cfStrikes_;} public virtual List capStrikes() {return cStrikes_;} public virtual List floorStrikes() {return fStrikes_;} public virtual List maturities() {return cfMaturities_;} - + public virtual Matrix capPrices() { return cPrice_; } public virtual Matrix floorPrices() { return fPrice_; } - + public virtual double minStrike() {return cfStrikes_.First();} public virtual double maxStrike() {return cfStrikes_.Last();} - public virtual Date minDate() {return referenceDate()+cfMaturities_.First();}// \TODO deal with index interpolation - public override Date maxDate() {return referenceDate()+cfMaturities_.Last();} - + public virtual Date minDate() {return referenceDate() + cfMaturities_.First();} // \TODO deal with index interpolation + public override Date maxDate() {return referenceDate() + cfMaturities_.Last();} + public virtual Date cpiOptionDateFromTenor(Period p) { return new Date(calendar().adjust(referenceDate() + p, businessDayConvention())); } - protected virtual bool checkStrike(double K) + protected virtual bool checkStrike(double K) { - return ( minStrike() <= K && K <= maxStrike() ); + return (minStrike() <= K && K <= maxStrike()); } - protected virtual bool checkMaturity(Date d) + protected virtual bool checkMaturity(Date d) { - return ( minDate() <= d && d <= maxDate() ); + return (minDate() <= d && d <= maxDate()); } - + protected Handle zii_; // data protected List cStrikes_; @@ -208,11 +209,11 @@ protected virtual bool checkMaturity(Date d) private BusinessDayConvention bdc_; } - + public class InterpolatedCPICapFloorTermPriceSurface : CPICapFloorTermPriceSurface - where Interpolator2D : IInterpolationFactory2D,new() + where Interpolator2D : IInterpolationFactory2D, new () { - public InterpolatedCPICapFloorTermPriceSurface(double nominal, + public InterpolatedCPICapFloorTermPriceSurface(double nominal, double startRate, Period observationLag, Calendar cal, @@ -225,7 +226,7 @@ public InterpolatedCPICapFloorTermPriceSurface(double nominal, List cfMaturities, Matrix cPrice, Matrix fPrice) - :base(nominal, startRate, observationLag, cal, bdc, dc,zii, yts, cStrikes, fStrikes, cfMaturities, cPrice, fPrice) + : base(nominal, startRate, observationLag, cal, bdc, dc, zii, yts, cStrikes, fStrikes, cfMaturities, cPrice, fPrice) { interpolator2d_ = FastActivator.Create(); @@ -242,88 +243,88 @@ public InterpolatedCPICapFloorTermPriceSurface(double nominal, protected override void performCalculations() { allStrikes_ = new List(); - int nMat = cfMaturities_.Count, - ncK = cStrikes_.Count, + int nMat = cfMaturities_.Count, + ncK = cStrikes_.Count, nfK = fStrikes_.Count, nK = ncK + nfK; - Matrix cP = new Matrix(nK, nMat), - fP = new Matrix(nK, nMat); + Matrix cP = new Matrix(nK, nMat), + fP = new Matrix(nK, nMat); Handle zts = zii_.link.zeroInflationTermStructure(); Handle yts = this.nominalTermStructure(); - Utils.QL_REQUIRE(!zts.empty(),()=>"Zts is empty!!!"); - Utils.QL_REQUIRE(!yts.empty(),()=>"Yts is empty!!!"); - - for (int i =0; i "Zts is empty!!!"); + Utils.QL_REQUIRE(!yts.empty(), () => "Yts is empty!!!"); + + for (int i = 0; i < nfK; i++) { allStrikes_.Add(fStrikes_[i]); - for (int j=0; j(); - for (int i=0; i atm ? capPrice( d, k ) : floorPrice( d, k ); + double atm = zeroInflationIndex().link.zeroInflationTermStructure().link.zeroRate(d); + return k > atm ? capPrice(d, k) : floorPrice(d, k); } - public override double capPrice( Date d, double k) + public override double capPrice(Date d, double k) { - double t = timeFromReference( d ); - return capPrice_.value( t, k ); + double t = timeFromReference(d); + return capPrice_.value(t, k); } - public override double floorPrice( Date d, double k) + public override double floorPrice(Date d, double k) { - double t = timeFromReference( d ); - return floorPrice_.value( t, k ); + double t = timeFromReference(d); + return floorPrice_.value(t, k); } - + // data for surfaces and curve protected List allStrikes_; protected Matrix cPriceB_; diff --git a/src/QLNet/Termstructures/Inflation/InflationHelpers.cs b/src/QLNet/Termstructures/Inflation/InflationHelpers.cs index 5ca4a10a0..171a25f0f 100644 --- a/src/QLNet/Termstructures/Inflation/InflationHelpers.cs +++ b/src/QLNet/Termstructures/Inflation/InflationHelpers.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,7 +23,7 @@ under the terms of the QLNet license. You should have received a namespace QLNet { //! Zero-coupon inflation-swap bootstrap helper - public class ZeroCouponInflationSwapHelper : BootstrapHelper + public class ZeroCouponInflationSwapHelper : BootstrapHelper { public ZeroCouponInflationSwapHelper( Handle quote, @@ -42,38 +42,38 @@ public ZeroCouponInflationSwapHelper( dayCounter_ = dayCounter; zii_ = zii; - if (zii_.interpolated()) + if (zii_.interpolated()) { // if interpolated then simple earliestDate_ = maturity_ - swapObsLag_; latestDate_ = maturity_ - swapObsLag_; - } - else + } + else { // but if NOT interpolated then the value is valid // for every day in an inflation period so you actually // get an extended validity, however for curve building // just put the first date because using that convention // for the base date throughout - KeyValuePair limStart = Utils.inflationPeriod(maturity_ - swapObsLag_, - zii_.frequency()); - earliestDate_ = limStart.Key; - latestDate_ = limStart.Key; + KeyValuePair limStart = Utils.inflationPeriod(maturity_ - swapObsLag_, + zii_.frequency()); + earliestDate_ = limStart.Key; + latestDate_ = limStart.Key; } // check that the observation lag of the swap // is compatible with the availability lag of the index AND // it's interpolation (assuming the start day is spot) - if (zii_.interpolated()) + if (zii_.interpolated()) { Period pShift = new Period(zii_.frequency()); - Utils.QL_REQUIRE( (swapObsLag_ - pShift) > zii_.availabilityLag(),()=> - "inconsistency between swap observation of index " - + swapObsLag_ + - " index availability " + zii_.availabilityLag() + - " index period " + pShift + - " and index availability " + zii_.availabilityLag() + - " need (obsLag-index period) > availLag"); + Utils.QL_REQUIRE((swapObsLag_ - pShift) > zii_.availabilityLag(), () => + "inconsistency between swap observation of index " + + swapObsLag_ + + " index availability " + zii_.availabilityLag() + + " index period " + pShift + + " and index availability " + zii_.availabilityLag() + + " need (obsLag-index period) > availLag"); } Settings.registerWith(update); @@ -83,32 +83,32 @@ public ZeroCouponInflationSwapHelper( public override void setTermStructure(ZeroInflationTermStructure z) { - base.setTermStructure( z ); - - // set up a new ZCIIS - // but this one does NOT own its inflation term structure - bool own = false; - double K = quote().link.value(); - - // The effect of the new inflation term structure is - // felt via the effect on the inflation index - Handle zits = new Handle( z, own ); - - ZeroInflationIndex new_zii = zii_.clone( zits ); - - double nominal = 1000000.0; // has to be something but doesn't matter what - Date start = z.nominalTermStructure().link.referenceDate(); - zciis_ = new ZeroCouponInflationSwap( - ZeroCouponInflationSwap.Type.Payer, - nominal, start, maturity_, - calendar_, paymentConvention_, dayCounter_, K, // fixed side & fixed rate - new_zii, swapObsLag_ ); - // Because very simple instrument only takes - // standard discounting swap engine. - zciis_.setPricingEngine( new DiscountingSwapEngine( z.nominalTermStructure() ) ); + base.setTermStructure(z); + + // set up a new ZCIIS + // but this one does NOT own its inflation term structure + bool own = false; + double K = quote().link.value(); + + // The effect of the new inflation term structure is + // felt via the effect on the inflation index + Handle zits = new Handle(z, own); + + ZeroInflationIndex new_zii = zii_.clone(zits); + + double nominal = 1000000.0; // has to be something but doesn't matter what + Date start = z.nominalTermStructure().link.referenceDate(); + zciis_ = new ZeroCouponInflationSwap( + ZeroCouponInflationSwap.Type.Payer, + nominal, start, maturity_, + calendar_, paymentConvention_, dayCounter_, K, // fixed side & fixed rate + new_zii, swapObsLag_); + // Because very simple instrument only takes + // standard discounting swap engine. + zciis_.setPricingEngine(new DiscountingSwapEngine(z.nominalTermStructure())); } - public override double impliedQuote() + public override double impliedQuote() { // what does the term structure imply? // in this case just the same value ... trivial case @@ -116,8 +116,8 @@ public override double impliedQuote() zciis_.recalculate(); return zciis_.fairRate(); } - - + + protected Period swapObsLag_; protected Date maturity_; protected Calendar calendar_; @@ -127,125 +127,125 @@ public override double impliedQuote() protected ZeroCouponInflationSwap zciis_; } - //! Year-on-year inflation-swap bootstrap helper - public class YearOnYearInflationSwapHelper : BootstrapHelper - { - public YearOnYearInflationSwapHelper( Handle quote, - Period swapObsLag, - Date maturity, - Calendar calendar, - BusinessDayConvention paymentConvention, - DayCounter dayCounter, - YoYInflationIndex yii ) - : base( quote ) - { - swapObsLag_= swapObsLag; - maturity_ = maturity; - calendar_= calendar; - paymentConvention_= paymentConvention; - dayCounter_= dayCounter; - yii_ = yii; - - if (yii_.interpolated()) - { + //! Year-on-year inflation-swap bootstrap helper + public class YearOnYearInflationSwapHelper : BootstrapHelper + { + public YearOnYearInflationSwapHelper(Handle quote, + Period swapObsLag, + Date maturity, + Calendar calendar, + BusinessDayConvention paymentConvention, + DayCounter dayCounter, + YoYInflationIndex yii) + : base(quote) + { + swapObsLag_ = swapObsLag; + maturity_ = maturity; + calendar_ = calendar; + paymentConvention_ = paymentConvention; + dayCounter_ = dayCounter; + yii_ = yii; + + if (yii_.interpolated()) + { // if interpolated then simple earliestDate_ = maturity_ - swapObsLag_; latestDate_ = maturity_ - swapObsLag_; - } - else - { + } + else + { // but if NOT interpolated then the value is valid // for every day in an inflation period so you actually // get an extended validity, however for curve building // just put the first date because using that convention // for the base date throughout - KeyValuePair limStart = Utils.inflationPeriod(maturity_ - swapObsLag_, - yii_.frequency()); + KeyValuePair limStart = Utils.inflationPeriod(maturity_ - swapObsLag_, + yii_.frequency()); earliestDate_ = limStart.Key; latestDate_ = limStart.Key; - } + } - // check that the observation lag of the swap - // is compatible with the availability lag of the index AND - // it's interpolation (assuming the start day is spot) - if (yii_.interpolated()) - { + // check that the observation lag of the swap + // is compatible with the availability lag of the index AND + // it's interpolation (assuming the start day is spot) + if (yii_.interpolated()) + { Period pShift = new Period(yii_.frequency()); - Utils.QL_REQUIRE( swapObsLag_ - pShift > yii_.availabilityLag(), () => - "inconsistency between swap observation of index " - + swapObsLag_ + - " index availability " + yii_.availabilityLag() + - " index period " + pShift + - " and index availability " + yii_.availabilityLag() + - " need (obsLag-index period) > availLag"); - } - - Settings.registerWith(update); - } - - public override void setTermStructure( YoYInflationTermStructure y ) - { - base.setTermStructure(y); - - // set up a new YYIIS - // but this one does NOT own its inflation term structure - const bool own = false; - - // The effect of the new inflation term structure is - // felt via the effect on the inflation index - Handle yyts = new Handle(y, own); - - YoYInflationIndex new_yii = yii_.clone(yyts); - - // always works because tenor is always 1 year so - // no problem with different days-in-month - Date from = Settings.evaluationDate(); - Date to = maturity_; - Schedule fixedSchedule = new MakeSchedule().from(from).to(to) - .withTenor(new Period(1,TimeUnit.Years)) - .withConvention(BusinessDayConvention.Unadjusted) - .withCalendar(calendar_)// fixed leg gets cal from sched - .value(); - Schedule yoySchedule = fixedSchedule; - double spread = 0.0; - double fixedRate = quote().link.value(); - - double nominal = 1000000.0; // has to be something but doesn't matter what - yyiis_ = new YearOnYearInflationSwap(YearOnYearInflationSwap.Type.Payer, - nominal, - fixedSchedule, - fixedRate, - dayCounter_, - yoySchedule, - new_yii, - swapObsLag_, - spread, - dayCounter_, - calendar_, // inflation index does not have a calendar - paymentConvention_); - - - // Because very simple instrument only takes - // standard discounting swap engine. - yyiis_.setPricingEngine(new DiscountingSwapEngine(y.nominalTermStructure())); - } - - public override double impliedQuote() - { - // what does the term structure imply? - // in this case just the same value ... trivial case - // (would not be so for an inflation-linked bond) - yyiis_.recalculate(); - return yyiis_.fairRate(); - } - - protected Period swapObsLag_; - protected Date maturity_; - protected Calendar calendar_; - protected BusinessDayConvention paymentConvention_; - protected DayCounter dayCounter_; - protected YoYInflationIndex yii_; - protected YearOnYearInflationSwap yyiis_; - } + Utils.QL_REQUIRE(swapObsLag_ - pShift > yii_.availabilityLag(), () => + "inconsistency between swap observation of index " + + swapObsLag_ + + " index availability " + yii_.availabilityLag() + + " index period " + pShift + + " and index availability " + yii_.availabilityLag() + + " need (obsLag-index period) > availLag"); + } + + Settings.registerWith(update); + } + + public override void setTermStructure(YoYInflationTermStructure y) + { + base.setTermStructure(y); + + // set up a new YYIIS + // but this one does NOT own its inflation term structure + const bool own = false; + + // The effect of the new inflation term structure is + // felt via the effect on the inflation index + Handle yyts = new Handle(y, own); + + YoYInflationIndex new_yii = yii_.clone(yyts); + + // always works because tenor is always 1 year so + // no problem with different days-in-month + Date from = Settings.evaluationDate(); + Date to = maturity_; + Schedule fixedSchedule = new MakeSchedule().from(from).to(to) + .withTenor(new Period(1, TimeUnit.Years)) + .withConvention(BusinessDayConvention.Unadjusted) + .withCalendar(calendar_)// fixed leg gets cal from sched + .value(); + Schedule yoySchedule = fixedSchedule; + double spread = 0.0; + double fixedRate = quote().link.value(); + + double nominal = 1000000.0; // has to be something but doesn't matter what + yyiis_ = new YearOnYearInflationSwap(YearOnYearInflationSwap.Type.Payer, + nominal, + fixedSchedule, + fixedRate, + dayCounter_, + yoySchedule, + new_yii, + swapObsLag_, + spread, + dayCounter_, + calendar_, // inflation index does not have a calendar + paymentConvention_); + + + // Because very simple instrument only takes + // standard discounting swap engine. + yyiis_.setPricingEngine(new DiscountingSwapEngine(y.nominalTermStructure())); + } + + public override double impliedQuote() + { + // what does the term structure imply? + // in this case just the same value ... trivial case + // (would not be so for an inflation-linked bond) + yyiis_.recalculate(); + return yyiis_.fairRate(); + } + + protected Period swapObsLag_; + protected Date maturity_; + protected Calendar calendar_; + protected BusinessDayConvention paymentConvention_; + protected DayCounter dayCounter_; + protected YoYInflationIndex yii_; + protected YearOnYearInflationSwap yyiis_; + } } diff --git a/src/QLNet/Termstructures/Inflation/InflationTraits.cs b/src/QLNet/Termstructures/Inflation/InflationTraits.cs index fb89e5d1e..330fc460a 100644 --- a/src/QLNet/Termstructures/Inflation/InflationTraits.cs +++ b/src/QLNet/Termstructures/Inflation/InflationTraits.cs @@ -6,13 +6,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,150 +23,150 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class ZeroInflationTraits : ITraits - { - const double avgInflation = 0.02; - const double maxInflation = 0.5; - - public Date initialDate( ZeroInflationTermStructure t ) - { - if ( t.indexIsInterpolated() ) - { - return t.referenceDate() - t.observationLag(); - } - else - { - return Utils.inflationPeriod( t.referenceDate() - t.observationLag(), - t.frequency() ).Key; - } - } - - public double initialValue( ZeroInflationTermStructure t ) - { - return t.baseRate(); - } - - public double guess( int i, InterpolatedCurve c, bool validData, int f ) - { - if ( validData ) // previous iteration value - return c.data()[i]; - - if ( i == 1 ) // first pillar - return avgInflation; - - // could/should extrapolate - return avgInflation; - } - - public double minValueAfter( int i, InterpolatedCurve c, bool validData, int f ) - { - if ( validData ) - { - double r = c.data().Min(); - return r < 0.0 ? r * 2.0 : r / 2.0; - } - return -maxInflation; - } - - public double maxValueAfter( int i, InterpolatedCurve c, bool validData, int f ) - { - if ( validData ) - { - double r = c.data().Max(); - return r < 0.0 ? r / 2.0 : r * 2.0; - } - // no constraints. - // We choose as max a value very unlikely to be exceeded. - return maxInflation; - } - - public void updateGuess( List data, double discount, int i ) - { - data[i] = discount; - } - - public int maxIterations() - { - return 5; - } - - public double discountImpl( Interpolation i, double t ) { throw new NotSupportedException(); } - - public double zeroYieldImpl( Interpolation i, double t ) { throw new NotSupportedException(); } - - public double forwardImpl( Interpolation i, double t ) { throw new NotSupportedException(); } + public class ZeroInflationTraits : ITraits + { + const double avgInflation = 0.02; + const double maxInflation = 0.5; + + public Date initialDate(ZeroInflationTermStructure t) + { + if (t.indexIsInterpolated()) + { + return t.referenceDate() - t.observationLag(); + } + else + { + return Utils.inflationPeriod(t.referenceDate() - t.observationLag(), + t.frequency()).Key; + } + } + + public double initialValue(ZeroInflationTermStructure t) + { + return t.baseRate(); + } + + public double guess(int i, InterpolatedCurve c, bool validData, int f) + { + if (validData) // previous iteration value + return c.data()[i]; + + if (i == 1) // first pillar + return avgInflation; + + // could/should extrapolate + return avgInflation; + } + + public double minValueAfter(int i, InterpolatedCurve c, bool validData, int f) + { + if (validData) + { + double r = c.data().Min(); + return r < 0.0 ? r * 2.0 : r / 2.0; + } + return -maxInflation; + } + + public double maxValueAfter(int i, InterpolatedCurve c, bool validData, int f) + { + if (validData) + { + double r = c.data().Max(); + return r < 0.0 ? r / 2.0 : r * 2.0; + } + // no constraints. + // We choose as max a value very unlikely to be exceeded. + return maxInflation; + } + + public void updateGuess(List data, double discount, int i) + { + data[i] = discount; + } + + public int maxIterations() + { + return 5; + } + + public double discountImpl(Interpolation i, double t) { throw new NotSupportedException(); } + + public double zeroYieldImpl(Interpolation i, double t) { throw new NotSupportedException(); } + + public double forwardImpl(Interpolation i, double t) { throw new NotSupportedException(); } } - public class YoYInflationTraits : ITraits - { - const double avgInflation = 0.02; - const double maxInflation = 0.5; - - public Date initialDate( YoYInflationTermStructure t ) - { - if ( t.indexIsInterpolated() ) - { - return t.referenceDate() - t.observationLag(); - } - else - { - return Utils.inflationPeriod( t.referenceDate() - t.observationLag(), - t.frequency() ).Key; - } - } - - public double initialValue( YoYInflationTermStructure t ) - { - return t.baseRate(); - } - - public double guess( int i, InterpolatedCurve c, bool validData, int f ) - { - if ( validData ) // previous iteration value - return c.data()[i]; - - if ( i == 1 ) // first pillar - return avgInflation; - - // could/should extrapolate - return avgInflation; - } - - public double minValueAfter( int i, InterpolatedCurve c, bool validData, int f ) - { - if ( validData ) - { - double r = c.data().Min(); - return r < 0.0 ? r * 2.0 : r / 2.0; - } - return -maxInflation; - } - - public double maxValueAfter( int i, InterpolatedCurve c, bool validData, int f ) - { - if ( validData ) - { - double r = c.data().Max(); - return r < 0.0 ? r / 2.0 : r * 2.0; - } - // no constraints. - // We choose as max a value very unlikely to be exceeded. - return maxInflation; - } - - public void updateGuess( List data, double discount, int i ) - { - data[i] = discount; - } - - public int maxIterations() - { - return 40; - } - - public double discountImpl( Interpolation i, double t ) { throw new NotSupportedException(); } - public double zeroYieldImpl( Interpolation i, double t ) { throw new NotSupportedException(); } - public double forwardImpl( Interpolation i, double t ) { throw new NotSupportedException(); } + public class YoYInflationTraits : ITraits + { + const double avgInflation = 0.02; + const double maxInflation = 0.5; + + public Date initialDate(YoYInflationTermStructure t) + { + if (t.indexIsInterpolated()) + { + return t.referenceDate() - t.observationLag(); + } + else + { + return Utils.inflationPeriod(t.referenceDate() - t.observationLag(), + t.frequency()).Key; + } + } + + public double initialValue(YoYInflationTermStructure t) + { + return t.baseRate(); + } + + public double guess(int i, InterpolatedCurve c, bool validData, int f) + { + if (validData) // previous iteration value + return c.data()[i]; + + if (i == 1) // first pillar + return avgInflation; + + // could/should extrapolate + return avgInflation; + } + + public double minValueAfter(int i, InterpolatedCurve c, bool validData, int f) + { + if (validData) + { + double r = c.data().Min(); + return r < 0.0 ? r * 2.0 : r / 2.0; + } + return -maxInflation; + } + + public double maxValueAfter(int i, InterpolatedCurve c, bool validData, int f) + { + if (validData) + { + double r = c.data().Max(); + return r < 0.0 ? r / 2.0 : r * 2.0; + } + // no constraints. + // We choose as max a value very unlikely to be exceeded. + return maxInflation; + } + + public void updateGuess(List data, double discount, int i) + { + data[i] = discount; + } + + public int maxIterations() + { + return 40; + } + + public double discountImpl(Interpolation i, double t) { throw new NotSupportedException(); } + public double zeroYieldImpl(Interpolation i, double t) { throw new NotSupportedException(); } + public double forwardImpl(Interpolation i, double t) { throw new NotSupportedException(); } } } diff --git a/src/QLNet/Termstructures/Inflation/InterpolatedYoYInflationCurve.cs b/src/QLNet/Termstructures/Inflation/InterpolatedYoYInflationCurve.cs index 6999b83f3..c61cddbac 100644 --- a/src/QLNet/Termstructures/Inflation/InterpolatedYoYInflationCurve.cs +++ b/src/QLNet/Termstructures/Inflation/InterpolatedYoYInflationCurve.cs @@ -6,7 +6,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -26,29 +26,29 @@ namespace QLNet \ingroup inflationtermstructures */ public class InterpolatedYoYInflationCurve : YoYInflationTermStructure, InterpolatedCurve - where Interpolator : class, IInterpolationFactory, new() + where Interpolator : class, IInterpolationFactory, new () { public InterpolatedYoYInflationCurve(Date referenceDate, - Calendar calendar, - DayCounter dayCounter, - Period lag, - Frequency frequency, - bool indexIsInterpolated, - Handle yTS, - List dates, - List rates) + Calendar calendar, + DayCounter dayCounter, + Period lag, + Frequency frequency, + bool indexIsInterpolated, + Handle yTS, + List dates, + List rates) : this(referenceDate, calendar, dayCounter, lag, frequency, indexIsInterpolated, yTS, dates, rates, FastActivator.Create()) { } public InterpolatedYoYInflationCurve(Date referenceDate, - Calendar calendar, - DayCounter dayCounter, - Period lag, - Frequency frequency, - bool indexIsInterpolated, - Handle yTS, - List dates, - List rates, - Interpolator interpolator ) + Calendar calendar, + DayCounter dayCounter, + Period lag, + Frequency frequency, + bool indexIsInterpolated, + Handle yTS, + List dates, + List rates, + Interpolator interpolator) : base(referenceDate, calendar, dayCounter, rates[0], lag, frequency, indexIsInterpolated, yTS) { times_ = new List(); @@ -62,12 +62,12 @@ public InterpolatedYoYInflationCurve(Date referenceDate, // period KeyValuePair lim = Utils.inflationPeriod(yTS.link.referenceDate() - this.observationLag(), frequency); Utils.QL_REQUIRE(lim.Key <= dates_[0] && dates_[0] <= lim.Value, () => - "first data date is not in base period, date: " + dates_[0] - + " not within [" + lim.Key + "," + lim.Value + "]"); + "first data date is not in base period, date: " + dates_[0] + + " not within [" + lim.Key + "," + lim.Value + "]"); Utils.QL_REQUIRE(this.data_.Count == dates_.Count, () => - "indices/dates count mismatch: " - + this.data_.Count + " vs " + dates_.Count); + "indices/dates count mismatch: " + + this.data_.Count + " vs " + dates_.Count); this.times_ = new InitializedList(dates_.Count); this.times_[0] = timeFromReference(dates_[0]); @@ -84,8 +84,8 @@ public InterpolatedYoYInflationCurve(Date referenceDate, this.times_[i] = timeFromReference(dates_[i]); Utils.QL_REQUIRE(!Utils.close(this.times_[i], this.times_[i - 1]), () => - "two dates correspond to the same time " + - "under this curve's day count convention"); + "two dates correspond to the same time " + + "under this curve's day count convention"); } this.interpolation_ = this.interpolator_.interpolate(times_, times_.Count, data_); diff --git a/src/QLNet/Termstructures/Inflation/InterpolatedZeroInflationCurve.cs b/src/QLNet/Termstructures/Inflation/InterpolatedZeroInflationCurve.cs index 1883472cf..6f6df371a 100644 --- a/src/QLNet/Termstructures/Inflation/InterpolatedZeroInflationCurve.cs +++ b/src/QLNet/Termstructures/Inflation/InterpolatedZeroInflationCurve.cs @@ -6,7 +6,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -22,14 +22,14 @@ under the terms of the QLNet license. You should have received a namespace QLNet { public class InterpolatedZeroInflationCurve : ZeroInflationTermStructure, InterpolatedCurve - where Interpolator : class, IInterpolationFactory, new() + where Interpolator : class, IInterpolationFactory, new () { public InterpolatedZeroInflationCurve(Date referenceDate, Calendar calendar, DayCounter dayCounter, Period lag, Frequency frequency, bool indexIsInterpolated, Handle yTS, List dates, List rates, Interpolator interpolator = default(Interpolator)) : base(referenceDate, calendar, dayCounter, rates[0], - lag, frequency, indexIsInterpolated, yTS) + lag, frequency, indexIsInterpolated, yTS) { times_ = new List(); dates_ = dates; @@ -43,8 +43,8 @@ public InterpolatedZeroInflationCurve(Date referenceDate, Calendar calendar, Day // period KeyValuePair lim = Utils.inflationPeriod(yTS.link.referenceDate() - this.observationLag(), frequency); Utils.QL_REQUIRE(lim.Key <= dates_[0] && dates_[0] <= lim.Value, () => - "first data date is not in base period, date: " + dates_[0] - + " not within [" + lim.Key + "," + lim.Value + "]"); + "first data date is not in base period, date: " + dates_[0] + + " not within [" + lim.Key + "," + lim.Value + "]"); // by convention, if the index is not interpolated we pull all the dates // back to the start of their inflationPeriods @@ -60,8 +60,8 @@ public InterpolatedZeroInflationCurve(Date referenceDate, Calendar calendar, Day Utils.QL_REQUIRE(this.data_.Count == dates_.Count, () => - "indices/dates count mismatch: " - + this.data_.Count + " vs " + dates_.Count); + "indices/dates count mismatch: " + + this.data_.Count + " vs " + dates_.Count); this.times_ = new InitializedList(dates_.Count); this.times_[0] = timeFromReference(dates_[0]); @@ -75,8 +75,8 @@ public InterpolatedZeroInflationCurve(Date referenceDate, Calendar calendar, Day // this can be negative this.times_[i] = timeFromReference(dates_[i]); Utils.QL_REQUIRE(!Utils.close(this.times_[i], this.times_[i - 1]), () => - "two dates correspond to the same time " + - "under this curve's day count convention"); + "two dates correspond to the same time " + + "under this curve's day count convention"); } this.interpolation_ = this.interpolator_.interpolate(times_, times_.Count, data_); @@ -158,15 +158,15 @@ protected override double zeroRateImpl(double t) construction. */ protected InterpolatedZeroInflationCurve(Date referenceDate, - Calendar calendar, - DayCounter dayCounter, - Period lag, - Frequency frequency, - bool indexIsInterpolated, - double baseZeroRate, - Handle yTS, - Interpolator interpolator = default(Interpolator)) - : base( referenceDate, calendar, dayCounter, baseZeroRate, lag, frequency, indexIsInterpolated, yTS ) + Calendar calendar, + DayCounter dayCounter, + Period lag, + Frequency frequency, + bool indexIsInterpolated, + double baseZeroRate, + Handle yTS, + Interpolator interpolator = default(Interpolator)) + : base(referenceDate, calendar, dayCounter, baseZeroRate, lag, frequency, indexIsInterpolated, yTS) { interpolator_ = interpolator ?? FastActivator.Create(); } diff --git a/src/QLNet/Termstructures/Inflation/PiecewiseYoYInflationCurve.cs b/src/QLNet/Termstructures/Inflation/PiecewiseYoYInflationCurve.cs index 2ce06be8c..99f2c9b93 100644 --- a/src/QLNet/Termstructures/Inflation/PiecewiseYoYInflationCurve.cs +++ b/src/QLNet/Termstructures/Inflation/PiecewiseYoYInflationCurve.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,274 +23,286 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class PiecewiseYoYInflationCurve : YoYInflationTermStructure, Curve - { - #region InflationTraits - - public Date initialDate( YoYInflationTermStructure c ) { return traits_.initialDate( c ); } - public double initialValue( YoYInflationTermStructure c ) { return traits_.initialValue( c ); } - public double guess( int i, InterpolatedCurve c, bool validData, int first ) { return traits_.guess( i, c, validData, first ); } - public double minValueAfter( int i, InterpolatedCurve c, bool validData, int first ) { return traits_.minValueAfter( i, c, validData, first ); } - public double maxValueAfter( int i, InterpolatedCurve c, bool validData, int first ) { return traits_.maxValueAfter( i, c, validData, first ); } - public void updateGuess( List data, double discount, int i ) { traits_.updateGuess( data, discount, i ); } - public int maxIterations() { return traits_.maxIterations(); } - - #endregion + public class PiecewiseYoYInflationCurve : YoYInflationTermStructure, Curve + { + #region InflationTraits - #region InterpolatedCurve + public Date initialDate(YoYInflationTermStructure c) { return traits_.initialDate(c); } + public double initialValue(YoYInflationTermStructure c) { return traits_.initialValue(c); } + public double guess(int i, InterpolatedCurve c, bool validData, int first) { return traits_.guess(i, c, validData, first); } + public double minValueAfter(int i, InterpolatedCurve c, bool validData, int first) { return traits_.minValueAfter(i, c, validData, first); } + public double maxValueAfter(int i, InterpolatedCurve c, bool validData, int first) { return traits_.maxValueAfter(i, c, validData, first); } + public void updateGuess(List data, double discount, int i) { traits_.updateGuess(data, discount, i); } + public int maxIterations() { return traits_.maxIterations(); } - public List times_ { get; set; } - public virtual List times() { return this.times_; } + #endregion - public List dates_ { get; set; } - public virtual List dates() { return dates_; } - public Date maxDate_ { get; set; } - public override Date maxDate() - { - if ( maxDate_ != null ) - return maxDate_; + #region InterpolatedCurve - return dates_.Last(); - } + public List times_ { get; set; } + public virtual List times() { return this.times_; } + + public List dates_ { get; set; } + public virtual List dates() { return dates_; } + public Date maxDate_ { get; set; } + public override Date maxDate() + { + if (maxDate_ != null) + return maxDate_; - public List data_ { get; set; } - public List forwards() { return this.data_; } - public virtual List data() { return forwards(); } + return dates_.Last(); + } - public Interpolation interpolation_ { get; set; } - public IInterpolationFactory interpolator_ { get; set; } + public List data_ { get; set; } + public List forwards() { return this.data_; } + public virtual List data() { return forwards(); } - public virtual Dictionary nodes() - { - Dictionary results = new Dictionary(); - dates_.ForEach( ( i, x ) => results.Add( x, data_[i] ) ); - return results; - } + public Interpolation interpolation_ { get; set; } + public IInterpolationFactory interpolator_ { get; set; } - public void setupInterpolation() - { - interpolation_ = interpolator_.interpolate( times_, times_.Count, data_ ); - } + public virtual Dictionary nodes() + { + Dictionary results = new Dictionary(); + dates_.ForEach((i, x) => results.Add(x, data_[i])); + return results; + } - public object Clone() - { - InterpolatedCurve copy = this.MemberwiseClone() as InterpolatedCurve; - copy.times_ = new List( times_ ); - copy.data_ = new List( data_ ); - copy.interpolator_ = interpolator_; - copy.setupInterpolation(); - return copy; - } + public void setupInterpolation() + { + interpolation_ = interpolator_.interpolate(times_, times_.Count, data_); + } + + public object Clone() + { + InterpolatedCurve copy = this.MemberwiseClone() as InterpolatedCurve; + copy.times_ = new List(times_); + copy.data_ = new List(data_); + copy.interpolator_ = interpolator_; + copy.setupInterpolation(); + return copy; + } - #endregion + #endregion - public List rates() - { - return this.data_; - } + public List rates() + { + return this.data_; + } - protected override double yoyRateImpl( double t ) - { - return this.interpolation_.value( t, true ); - } + protected override double yoyRateImpl(double t) + { + return this.interpolation_.value(t, true); + } - // these are dummy methods (for the sake of ITraits and should not be called directly - public double discountImpl( Interpolation i, double t ) { throw new NotSupportedException(); } - public double zeroYieldImpl( Interpolation i, double t ) { throw new NotSupportedException(); } - public double forwardImpl( Interpolation i, double t ) { throw new NotSupportedException(); } + // these are dummy methods (for the sake of ITraits and should not be called directly + public double discountImpl(Interpolation i, double t) { throw new NotSupportedException(); } + public double zeroYieldImpl(Interpolation i, double t) { throw new NotSupportedException(); } + public double forwardImpl(Interpolation i, double t) { throw new NotSupportedException(); } - # region new fields: Curve + # region new fields: Curve - public double initialValue() { return _traits_.initialValue( this ); } - public Date initialDate() { return _traits_.initialDate( this ); } + public double initialValue() { return _traits_.initialValue(this); } + public Date initialDate() { return _traits_.initialDate(this); } - public void registerWith( BootstrapHelper helper ) - { - helper.registerWith( this.update ); - } + public void registerWith(BootstrapHelper helper) + { + helper.registerWith(this.update); + } - //public new bool moving_ - public new bool moving_ - { - get { return base.moving_; } - set { base.moving_ = value; } - } + //public new bool moving_ + public new bool moving_ + { + get + { + return base.moving_; + } + set + { + base.moving_ = value; + } + } - public void setTermStructure( BootstrapHelper helper ) - { - helper.setTermStructure( this ); - } + public void setTermStructure(BootstrapHelper helper) + { + helper.setTermStructure(this); + } - protected ITraits _traits_ = null;//todo define with the trait for yield curve - public ITraits traits_ - { - get - { - return _traits_; - } - } + protected ITraits _traits_ = null;//todo define with the trait for yield curve + public ITraits traits_ + { + get + { + return _traits_; + } + } - protected List> _instruments_ = new List>(); + protected List> _instruments_ = new List>(); - public List> instruments_ - { - get - { - //todo edem - List> instruments = new List>(); - _instruments_.ForEach((i, x) => instruments.Add( x ) ); - return instruments; - } - } + public List> instruments_ + { + get + { + //todo edem + List> instruments = new List>(); + _instruments_.ForEach((i, x) => instruments.Add(x)); + return instruments; + } + } - protected IBootStrap bootstrap_; + protected IBootStrap bootstrap_; - protected double _accuracy_; - public double accuracy_ - { - get { return _accuracy_; } - set { _accuracy_ = value; } - } + protected double _accuracy_; + public double accuracy_ + { + get + { + return _accuracy_; + } + set + { + _accuracy_ = value; + } + } - public override Date baseDate() - { - // if indexIsInterpolated we fixed the dates in the constructor - return dates_.First(); - } + public override Date baseDate() + { + // if indexIsInterpolated we fixed the dates in the constructor + return dates_.First(); + } - # endregion + # endregion - public PiecewiseYoYInflationCurve( DayCounter dayCounter, double baseZeroRate, Period observationLag, Frequency frequency, - bool indexIsInterpolated, Handle yTS ) - : base( dayCounter, baseZeroRate, observationLag, frequency, indexIsInterpolated, yTS ) { } + public PiecewiseYoYInflationCurve(DayCounter dayCounter, double baseZeroRate, Period observationLag, Frequency frequency, + bool indexIsInterpolated, Handle yTS) + : base(dayCounter, baseZeroRate, observationLag, frequency, indexIsInterpolated, yTS) { } - public PiecewiseYoYInflationCurve( Date referenceDate, Calendar calendar, DayCounter dayCounter, double baseZeroRate, - Period observationLag, Frequency frequency, bool indexIsInterpolated, - Handle yTS ) - : base( referenceDate, calendar, dayCounter, baseZeroRate, observationLag, frequency, indexIsInterpolated, yTS ) { } + public PiecewiseYoYInflationCurve(Date referenceDate, Calendar calendar, DayCounter dayCounter, double baseZeroRate, + Period observationLag, Frequency frequency, bool indexIsInterpolated, + Handle yTS) + : base(referenceDate, calendar, dayCounter, baseZeroRate, observationLag, frequency, indexIsInterpolated, yTS) { } - public PiecewiseYoYInflationCurve( int settlementDays, Calendar calendar, DayCounter dayCounter, double baseZeroRate, - Period observationLag, Frequency frequency, bool indexIsInterpolated, - Handle yTS ) - : base( settlementDays, calendar, dayCounter, baseZeroRate, observationLag, frequency, indexIsInterpolated, yTS ) { } + public PiecewiseYoYInflationCurve(int settlementDays, Calendar calendar, DayCounter dayCounter, double baseZeroRate, + Period observationLag, Frequency frequency, bool indexIsInterpolated, + Handle yTS) + : base(settlementDays, calendar, dayCounter, baseZeroRate, observationLag, frequency, indexIsInterpolated, yTS) { } public PiecewiseYoYInflationCurve() : base() { } - } - - - public class PiecewiseYoYInflationCurve : PiecewiseYoYInflationCurve - where Traits : ITraits, new() - where Interpolator : IInterpolationFactory, new() - where Bootstrap : IBootStrap, new() - { - - public PiecewiseYoYInflationCurve( Date referenceDate, - Calendar calendar, - DayCounter dayCounter, - Period lag, - Frequency frequency, - bool indexIsInterpolated, - double baseZeroRate, - Handle nominalTS, - List> instruments, - double accuracy = 1.0e-12, - Interpolator i = default(Interpolator), - Bootstrap bootstrap = default(Bootstrap) ) - : base( referenceDate, calendar, dayCounter, baseZeroRate, lag, frequency, indexIsInterpolated, nominalTS ) - { - _instruments_ = instruments; - accuracy_ = accuracy; - if ( bootstrap == null ) - bootstrap_ = FastActivator.Create(); - else - bootstrap_ = bootstrap; - - if ( i == null ) - interpolator_ = FastActivator.Create(); - else - interpolator_ = i; - - _traits_ = FastActivator.Create(); - bootstrap_.setup( this ); - - } - - // Inflation interface - public override Date baseDate() - { - this.calculate(); - return base.baseDate(); - } - public override Date maxDate() - { - this.calculate(); - return base.maxDate(); - } - // Inspectors - public override List times() - { - calculate(); - return base.times(); - } - public override List dates() - { - calculate(); - return base.dates(); - } - public override List data() - { - calculate(); - return base.rates(); - } - public override Dictionary nodes() - { - calculate(); - return base.nodes(); - } - - // methods - protected override void performCalculations() { bootstrap_.calculate(); } - } - - - // Allows for optional 3rd generic parameter defaulted to IterativeBootstrap - public class PiecewiseYoYInflationCurve : PiecewiseYoYInflationCurve - where Interpolator : IInterpolationFactory, new() - { - public PiecewiseYoYInflationCurve( Date referenceDate, - Calendar calendar, - DayCounter dayCounter, - Period lag, - Frequency frequency, - bool indexIsInterpolated, - double baseZeroRate, - Handle nominalTS, - List> instruments, - double accuracy = 1.0e-12, - Interpolator i = default(Interpolator) ) - : base( referenceDate, calendar, dayCounter, lag, frequency, indexIsInterpolated, baseZeroRate, nominalTS, - instruments, accuracy, i ) { } - - - } + } + + + public class PiecewiseYoYInflationCurve : PiecewiseYoYInflationCurve + where Traits : ITraits, new () + where Interpolator : IInterpolationFactory, new () + where Bootstrap : IBootStrap, new () + { + + public PiecewiseYoYInflationCurve(Date referenceDate, + Calendar calendar, + DayCounter dayCounter, + Period lag, + Frequency frequency, + bool indexIsInterpolated, + double baseZeroRate, + Handle nominalTS, + List> instruments, + double accuracy = 1.0e-12, + Interpolator i = default(Interpolator), + Bootstrap bootstrap = default(Bootstrap)) + : base(referenceDate, calendar, dayCounter, baseZeroRate, lag, frequency, indexIsInterpolated, nominalTS) + { + _instruments_ = instruments; + accuracy_ = accuracy; + if (bootstrap == null) + bootstrap_ = FastActivator.Create(); + else + bootstrap_ = bootstrap; + + if (i == null) + interpolator_ = FastActivator.Create(); + else + interpolator_ = i; + + _traits_ = FastActivator.Create(); + bootstrap_.setup(this); + + } + + // Inflation interface + public override Date baseDate() + { + this.calculate(); + return base.baseDate(); + } + public override Date maxDate() + { + this.calculate(); + return base.maxDate(); + } + // Inspectors + public override List times() + { + calculate(); + return base.times(); + } + public override List dates() + { + calculate(); + return base.dates(); + } + public override List data() + { + calculate(); + return base.rates(); + } + public override Dictionary nodes() + { + calculate(); + return base.nodes(); + } + + // methods + protected override void performCalculations() { bootstrap_.calculate(); } + } + + + // Allows for optional 3rd generic parameter defaulted to IterativeBootstrap + public class PiecewiseYoYInflationCurve : PiecewiseYoYInflationCurve + where Interpolator : IInterpolationFactory, new () + { + public PiecewiseYoYInflationCurve(Date referenceDate, + Calendar calendar, + DayCounter dayCounter, + Period lag, + Frequency frequency, + bool indexIsInterpolated, + double baseZeroRate, + Handle nominalTS, + List> instruments, + double accuracy = 1.0e-12, + Interpolator i = default(Interpolator)) + : base(referenceDate, calendar, dayCounter, lag, frequency, indexIsInterpolated, baseZeroRate, nominalTS, + instruments, accuracy, i) { } + + + } } diff --git a/src/QLNet/Termstructures/Inflation/PiecewiseZeroInflationCurve.cs b/src/QLNet/Termstructures/Inflation/PiecewiseZeroInflationCurve.cs index 4a3da92cf..1f76a4c0b 100644 --- a/src/QLNet/Termstructures/Inflation/PiecewiseZeroInflationCurve.cs +++ b/src/QLNet/Termstructures/Inflation/PiecewiseZeroInflationCurve.cs @@ -6,13 +6,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,281 +24,293 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public class PiecewiseZeroInflationCurve : ZeroInflationTermStructure, Curve - { - #region InflationTraits - - public Date initialDate( ZeroInflationTermStructure c ) { return traits_.initialDate( c ); } - public double initialValue( ZeroInflationTermStructure c ) { return traits_.initialValue( c ); } - public double guess( int i, InterpolatedCurve c, bool validData, int first ) { return traits_.guess( i, c, validData, first ); } - public double minValueAfter( int i, InterpolatedCurve c, bool validData, int first ) { return traits_.minValueAfter( i, c, validData, first ); } - public double maxValueAfter( int i, InterpolatedCurve c, bool validData, int first ) { return traits_.maxValueAfter( i, c, validData, first ); } - public void updateGuess( List data, double discount, int i ) { traits_.updateGuess( data, discount, i ); } - public int maxIterations() { return traits_.maxIterations(); } - - #endregion - - #region InterpolatedCurve - - public List times_ { get; set; } - public virtual List times() { return this.times_; } - - public List dates_ { get; set; } - public virtual List dates() { return dates_; } - public Date maxDate_ { get; set; } - public override Date maxDate() - { - Date d; - if (indexIsInterpolated()) - { - d = dates_.Last(); - } - else - { - d = Utils.inflationPeriod(dates_.Last(), frequency()).Value; - } - return d; + public class PiecewiseZeroInflationCurve : ZeroInflationTermStructure, Curve + { + #region InflationTraits + + public Date initialDate(ZeroInflationTermStructure c) { return traits_.initialDate(c); } + public double initialValue(ZeroInflationTermStructure c) { return traits_.initialValue(c); } + public double guess(int i, InterpolatedCurve c, bool validData, int first) { return traits_.guess(i, c, validData, first); } + public double minValueAfter(int i, InterpolatedCurve c, bool validData, int first) { return traits_.minValueAfter(i, c, validData, first); } + public double maxValueAfter(int i, InterpolatedCurve c, bool validData, int first) { return traits_.maxValueAfter(i, c, validData, first); } + public void updateGuess(List data, double discount, int i) { traits_.updateGuess(data, discount, i); } + public int maxIterations() { return traits_.maxIterations(); } + + #endregion + + #region InterpolatedCurve + + public List times_ { get; set; } + public virtual List times() { return this.times_; } + + public List dates_ { get; set; } + public virtual List dates() { return dates_; } + public Date maxDate_ { get; set; } + public override Date maxDate() + { + Date d; + if (indexIsInterpolated()) + { + d = dates_.Last(); + } + else + { + d = Utils.inflationPeriod(dates_.Last(), frequency()).Value; + } + return d; } - public List data_ { get; set; } - public List forwards() { return this.data_; } - public virtual List data() { return forwards(); } + public List data_ { get; set; } + public List forwards() { return this.data_; } + public virtual List data() { return forwards(); } + + public Interpolation interpolation_ { get; set; } + public IInterpolationFactory interpolator_ { get; set; } - public Interpolation interpolation_ { get; set; } - public IInterpolationFactory interpolator_ { get; set; } + public virtual Dictionary nodes() + { + Dictionary results = new Dictionary(); + dates_.ForEach((i, x) => results.Add(x, data_[i])); + return results; + } - public virtual Dictionary nodes() - { - Dictionary results = new Dictionary(); - dates_.ForEach( ( i, x ) => results.Add( x, data_[i] ) ); - return results; - } + public void setupInterpolation() + { + interpolation_ = interpolator_.interpolate(times_, times_.Count, data_); + } - public void setupInterpolation() - { - interpolation_ = interpolator_.interpolate( times_, times_.Count, data_ ); - } + public object Clone() + { + InterpolatedCurve copy = this.MemberwiseClone() as InterpolatedCurve; + copy.times_ = new List(times_); + copy.data_ = new List(data_); + copy.interpolator_ = interpolator_; + copy.setupInterpolation(); + return copy; + } - public object Clone() - { - InterpolatedCurve copy = this.MemberwiseClone() as InterpolatedCurve; - copy.times_ = new List( times_ ); - copy.data_ = new List( data_ ); - copy.interpolator_ = interpolator_; - copy.setupInterpolation(); - return copy; - } + #endregion - #endregion + public List rates() + { + return this.data_; + } - public List rates() - { - return this.data_; - } + protected override double zeroRateImpl(double t) + { + return this.interpolation_.value(t, true); + } - protected override double zeroRateImpl( double t ) - { - return this.interpolation_.value( t, true ); - } + // these are dummy methods (for the sake of ITraits and should not be called directly + public double discountImpl(Interpolation i, double t) { throw new NotSupportedException(); } + public double zeroYieldImpl(Interpolation i, double t) { throw new NotSupportedException(); } + public double forwardImpl(Interpolation i, double t) { throw new NotSupportedException(); } - // these are dummy methods (for the sake of ITraits and should not be called directly - public double discountImpl( Interpolation i, double t ) { throw new NotSupportedException(); } - public double zeroYieldImpl( Interpolation i, double t ) { throw new NotSupportedException(); } - public double forwardImpl( Interpolation i, double t ) { throw new NotSupportedException(); } + # region new fields: Curve - # region new fields: Curve + public double initialValue() { return _traits_.initialValue(this); } + public Date initialDate() { return _traits_.initialDate(this); } - public double initialValue() { return _traits_.initialValue( this ); } - public Date initialDate() { return _traits_.initialDate( this ); } + public void registerWith(BootstrapHelper helper) + { + helper.registerWith(this.update); + } - public void registerWith( BootstrapHelper helper ) - { - helper.registerWith( this.update ); - } + //public new bool moving_ + public new bool moving_ + { + get + { + return base.moving_; + } + set + { + base.moving_ = value; + } + } - //public new bool moving_ - public new bool moving_ - { - get { return base.moving_; } - set { base.moving_ = value; } - } + public void setTermStructure(BootstrapHelper helper) + { + helper.setTermStructure(this); + } - public void setTermStructure( BootstrapHelper helper ) - { - helper.setTermStructure( this ); - } + protected ITraits _traits_ = null;//todo define with the trait for yield curve + public ITraits traits_ + { + get + { + return _traits_; + } + } - protected ITraits _traits_ = null;//todo define with the trait for yield curve - public ITraits traits_ - { - get - { - return _traits_; - } - } + protected List> _instruments_ = new List>(); + + public List> instruments_ + { + get + { + //todo edem + List> instruments = new List>(); + _instruments_.ForEach((i, x) => instruments.Add(x)); + return instruments; + } + } + + protected IBootStrap bootstrap_; + + + protected double _accuracy_; + public double accuracy_ + { + get + { + return _accuracy_; + } + set + { + _accuracy_ = value; + } + } + + + public override Date baseDate() + { + // if indexIsInterpolated we fixed the dates in the constructor + return dates_.First(); + } + + + # endregion - protected List> _instruments_ = new List>(); - public List> instruments_ - { - get - { - //todo edem - List> instruments = new List>(); - _instruments_.ForEach((i, x) => instruments.Add( x ) ); - return instruments; - } - } - - protected IBootStrap bootstrap_; - - - protected double _accuracy_; - public double accuracy_ - { - get { return _accuracy_; } - set { _accuracy_ = value; } - } - - - public override Date baseDate() - { - // if indexIsInterpolated we fixed the dates in the constructor - return dates_.First(); - } - - - # endregion - - - - - public PiecewiseZeroInflationCurve( DayCounter dayCounter, double baseZeroRate, Period observationLag, Frequency frequency, - bool indexIsInterpolated, Handle yTS ) - : base( dayCounter, baseZeroRate, observationLag, frequency, indexIsInterpolated, yTS ) { } - - public PiecewiseZeroInflationCurve( Date referenceDate, Calendar calendar, DayCounter dayCounter, double baseZeroRate, - Period observationLag, Frequency frequency, bool indexIsInterpolated, - Handle yTS ) - : base( referenceDate, calendar, dayCounter, baseZeroRate, observationLag, frequency, indexIsInterpolated, yTS ) { } - - public PiecewiseZeroInflationCurve( int settlementDays, Calendar calendar, DayCounter dayCounter, double baseZeroRate, - Period observationLag, Frequency frequency, bool indexIsInterpolated, - Handle yTS ) - : base( settlementDays, calendar, dayCounter, baseZeroRate, observationLag, frequency, indexIsInterpolated, yTS ) { } - - - public PiecewiseZeroInflationCurve() - : base() - { } - } - - - public class PiecewiseZeroInflationCurve : PiecewiseZeroInflationCurve - where Traits : ITraits, new() - where Interpolator : IInterpolationFactory, new() - where Bootstrap : IBootStrap, new() - { - - public PiecewiseZeroInflationCurve( Date referenceDate, - Calendar calendar, - DayCounter dayCounter, - Period lag, - Frequency frequency, - bool indexIsInterpolated, - double baseZeroRate, - Handle nominalTS, - List> instruments, - double accuracy = 1.0e-12, - Interpolator i = default(Interpolator), - Bootstrap bootstrap = default(Bootstrap) ) - : base( referenceDate, calendar, dayCounter, baseZeroRate, lag, frequency, indexIsInterpolated, nominalTS ) - { - _instruments_ = instruments; - accuracy_ = accuracy; - if ( bootstrap == null ) - bootstrap_ = FastActivator.Create(); - else - bootstrap_ = bootstrap; - - if ( i == null ) - interpolator_ = FastActivator.Create(); - else - interpolator_ = i; - - _traits_ = FastActivator.Create(); - bootstrap_.setup( this ); - - } - - // Inflation interface - public override Date baseDate() - { - this.calculate(); - return base.baseDate(); - } - public override Date maxDate() - { - this.calculate(); - return base.maxDate(); - } - - // Inspectors - public override List times() - { - calculate(); - return base.times(); - } - public override List dates() - { - calculate(); - return base.dates(); - } - public override List data() - { - calculate(); - return base.rates(); - } - public override Dictionary nodes() - { - calculate(); - return base.nodes(); - } - - // methods - protected override void performCalculations() { bootstrap_.calculate(); } - } - - - // Allows for optional 3rd generic parameter defaulted to IterativeBootstrap - public class PiecewiseZeroInflationCurve : PiecewiseZeroInflationCurve - where Interpolator : IInterpolationFactory, new() - { - public PiecewiseZeroInflationCurve( Date referenceDate, - Calendar calendar, - DayCounter dayCounter, - Period lag, - Frequency frequency, - bool indexIsInterpolated, - double baseZeroRate, - Handle nominalTS, - List> instruments, - double accuracy = 1.0e-12, - Interpolator i = default(Interpolator) ) - : base( referenceDate, calendar, dayCounter, lag, frequency, indexIsInterpolated, baseZeroRate, nominalTS, - instruments, accuracy, i ) { } - - - } + + + public PiecewiseZeroInflationCurve(DayCounter dayCounter, double baseZeroRate, Period observationLag, Frequency frequency, + bool indexIsInterpolated, Handle yTS) + : base(dayCounter, baseZeroRate, observationLag, frequency, indexIsInterpolated, yTS) { } + + public PiecewiseZeroInflationCurve(Date referenceDate, Calendar calendar, DayCounter dayCounter, double baseZeroRate, + Period observationLag, Frequency frequency, bool indexIsInterpolated, + Handle yTS) + : base(referenceDate, calendar, dayCounter, baseZeroRate, observationLag, frequency, indexIsInterpolated, yTS) { } + + public PiecewiseZeroInflationCurve(int settlementDays, Calendar calendar, DayCounter dayCounter, double baseZeroRate, + Period observationLag, Frequency frequency, bool indexIsInterpolated, + Handle yTS) + : base(settlementDays, calendar, dayCounter, baseZeroRate, observationLag, frequency, indexIsInterpolated, yTS) { } + + + public PiecewiseZeroInflationCurve() + : base() + { } + } + + + public class PiecewiseZeroInflationCurve : PiecewiseZeroInflationCurve + where Traits : ITraits, new () + where Interpolator : IInterpolationFactory, new () + where Bootstrap : IBootStrap, new () + { + + public PiecewiseZeroInflationCurve(Date referenceDate, + Calendar calendar, + DayCounter dayCounter, + Period lag, + Frequency frequency, + bool indexIsInterpolated, + double baseZeroRate, + Handle nominalTS, + List> instruments, + double accuracy = 1.0e-12, + Interpolator i = default(Interpolator), + Bootstrap bootstrap = default(Bootstrap)) + : base(referenceDate, calendar, dayCounter, baseZeroRate, lag, frequency, indexIsInterpolated, nominalTS) + { + _instruments_ = instruments; + accuracy_ = accuracy; + if (bootstrap == null) + bootstrap_ = FastActivator.Create(); + else + bootstrap_ = bootstrap; + + if (i == null) + interpolator_ = FastActivator.Create(); + else + interpolator_ = i; + + _traits_ = FastActivator.Create(); + bootstrap_.setup(this); + + } + + // Inflation interface + public override Date baseDate() + { + this.calculate(); + return base.baseDate(); + } + public override Date maxDate() + { + this.calculate(); + return base.maxDate(); + } + + // Inspectors + public override List times() + { + calculate(); + return base.times(); + } + public override List dates() + { + calculate(); + return base.dates(); + } + public override List data() + { + calculate(); + return base.rates(); + } + public override Dictionary nodes() + { + calculate(); + return base.nodes(); + } + + // methods + protected override void performCalculations() { bootstrap_.calculate(); } + } + + + // Allows for optional 3rd generic parameter defaulted to IterativeBootstrap + public class PiecewiseZeroInflationCurve : PiecewiseZeroInflationCurve + where Interpolator : IInterpolationFactory, new () + { + public PiecewiseZeroInflationCurve(Date referenceDate, + Calendar calendar, + DayCounter dayCounter, + Period lag, + Frequency frequency, + bool indexIsInterpolated, + double baseZeroRate, + Handle nominalTS, + List> instruments, + double accuracy = 1.0e-12, + Interpolator i = default(Interpolator)) + : base(referenceDate, calendar, dayCounter, lag, frequency, indexIsInterpolated, baseZeroRate, nominalTS, + instruments, accuracy, i) { } + + + } } diff --git a/src/QLNet/Termstructures/Inflation/Seasonality.cs b/src/QLNet/Termstructures/Inflation/Seasonality.cs index f745d38ac..ee91df1e1 100644 --- a/src/QLNet/Termstructures/Inflation/Seasonality.cs +++ b/src/QLNet/Termstructures/Inflation/Seasonality.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -46,16 +46,16 @@ affects. Additive seasonality is not implemented. public class Seasonality { // Seasonality interface - public virtual double correctZeroRate(Date d, double r,InflationTermStructure iTS) + public virtual double correctZeroRate(Date d, double r, InflationTermStructure iTS) { return 0; } - - public virtual double correctYoYRate(Date d, double r,InflationTermStructure iTS) + + public virtual double correctYoYRate(Date d, double r, InflationTermStructure iTS) { return 0; } - + /*! It is possible for multi-year seasonalities to be inconsistent with the inflation term structure they are given to. This method enables testing - but programmers @@ -110,7 +110,7 @@ YoY inflation the reference is always one year earlier. correction factor frequency is the same as the index frequency (or less). */ - + public class MultiplicativePriceSeasonality : Seasonality { private Date seasonalityBaseDate_; @@ -134,8 +134,8 @@ public virtual void set(Date seasonalityBaseDate, Frequency frequency, frequency_ = frequency; seasonalityFactors_ = new List(seasonalityFactors.Count); - - for(int i=0; i to)dir = -1; + if (from > to) + dir = -1; int diff = 0 ; if (factorPeriod.units() == TimeUnit.Days) { - diff = dir*diffDays; + diff = dir * diffDays; } else if (factorPeriod.units() == TimeUnit.Weeks) { - diff = dir * (diffDays / 7); + diff = dir * (diffDays / 7); } else if (factorPeriod.units() == TimeUnit.Months) { - KeyValuePair lim = Utils.inflationPeriod(to, factorFrequency); - diff = diffDays / (31*factorPeriod.length()); - Date go = from + dir*diff*factorPeriod; - while ( !(lim.Key <= go && go <= lim.Value) ) - { - go += dir*factorPeriod; - diff++; - } - diff=dir*diff; + KeyValuePair lim = Utils.inflationPeriod(to, factorFrequency); + diff = diffDays / (31 * factorPeriod.length()); + Date go = from + dir * diff * factorPeriod; + while (!(lim.Key <= go && go <= lim.Value)) + { + go += dir * factorPeriod; + diff++; + } + diff = dir * diff; } - else if (factorPeriod.units() == TimeUnit.Years) + else if (factorPeriod.units() == TimeUnit.Years) { - Utils.QL_FAIL("seasonality period time unit is not allowed to be : " + factorPeriod.units()); - } - else + Utils.QL_FAIL("seasonality period time unit is not allowed to be : " + factorPeriod.units()); + } + else { - Utils.QL_FAIL("Unknown time unit: " + factorPeriod.units()); + Utils.QL_FAIL("Unknown time unit: " + factorPeriod.units()); } // now adjust to the available number of factors, direction dependent - if (dir==1) + if (dir == 1) { - which = diff % nFactors; - } - else + which = diff % nFactors; + } + else { - which = (nFactors - (-diff % nFactors)) % nFactors; + which = (nFactors - (-diff % nFactors)) % nFactors; } - } - return seasonalityFactors()[which]; + } + return seasonalityFactors()[which]; } // Seasonality interface - public override double correctZeroRate(Date d,double r,InflationTermStructure iTS) + public override double correctZeroRate(Date d, double r, InflationTermStructure iTS) { - KeyValuePair lim = Utils.inflationPeriod(iTS.baseDate(), iTS.frequency()); - Date curveBaseDate = lim.Value; - return seasonalityCorrection(r, d, iTS.dayCounter(), curveBaseDate, true); + KeyValuePair lim = Utils.inflationPeriod(iTS.baseDate(), iTS.frequency()); + Date curveBaseDate = lim.Value; + return seasonalityCorrection(r, d, iTS.dayCounter(), curveBaseDate, true); } - + public override double correctYoYRate(Date d, double r, InflationTermStructure iTS) { - KeyValuePair lim = Utils.inflationPeriod(iTS.baseDate(), iTS.frequency()); + KeyValuePair lim = Utils.inflationPeriod(iTS.baseDate(), iTS.frequency()); Date curveBaseDate = lim.Value; return seasonalityCorrection(r, d, iTS.dayCounter(), curveBaseDate, false); } - public override bool isConsistent(InflationTermStructure iTS) + public override bool isConsistent(InflationTermStructure iTS) { // If multi-year is the specification consistent with the term structure start date? // We do NOT test daily seasonality because this will, in general, never be consistent // given weekends, holidays, leap years, etc. - if(this.frequency() == Frequency.Daily) return true; - if( (int)this.frequency() == seasonalityFactors().Count ) return true; + if (this.frequency() == Frequency.Daily) + return true; + if ((int)this.frequency() == seasonalityFactors().Count) + return true; // how many years do you need to test? int nTest = seasonalityFactors().Count / (int)this.frequency(); // ... relative to the start of the inflation curve - KeyValuePair lim = Utils.inflationPeriod(iTS.baseDate(), iTS.frequency()); + KeyValuePair lim = Utils.inflationPeriod(iTS.baseDate(), iTS.frequency()); Date curveBaseDate = lim.Value; double factorBase = this.seasonalityFactor(curveBaseDate); double eps = 0.00001; - for (int i = 1; i < nTest; i++) + for (int i = 1; i < nTest; i++) { - double factorAt = this.seasonalityFactor(curveBaseDate+new Period(i,TimeUnit.Years)); - Utils.QL_REQUIRE(Math.Abs(factorAt-factorBase) - "seasonality is inconsistent with inflation " + - "term structure, factors " + factorBase + " and later factor " - + factorAt + ", " + i + " years later from inflation curve " - + " with base date at " + curveBaseDate); + double factorAt = this.seasonalityFactor(curveBaseDate + new Period(i, TimeUnit.Years)); + Utils.QL_REQUIRE(Math.Abs(factorAt - factorBase) + "seasonality is inconsistent with inflation " + + "term structure, factors " + factorBase + " and later factor " + + factorAt + ", " + i + " years later from inflation curve " + + " with base date at " + curveBaseDate); } return true; @@ -258,7 +261,7 @@ public override bool isConsistent(InflationTermStructure iTS) protected virtual void validate() { - switch (this.frequency()) + switch (this.frequency()) { case Frequency.Semiannual: //2 case Frequency.EveryFourthMonth: //3 @@ -268,11 +271,11 @@ protected virtual void validate() case Frequency.Biweekly: // etc. case Frequency.Weekly: case Frequency.Daily: - Utils.QL_REQUIRE((this.seasonalityFactors().Count % (int)this.frequency()) == 0,()=> - "For frequency " + this.frequency() - + " require multiple of " + ((int)this.frequency()) + " factors " - + this.seasonalityFactors().Count + " were given."); - break; + Utils.QL_REQUIRE((this.seasonalityFactors().Count % (int)this.frequency()) == 0, () => + "For frequency " + this.frequency() + + " require multiple of " + ((int)this.frequency()) + " factors " + + this.seasonalityFactors().Count + " were given."); + break; default: Utils.QL_FAIL("bad frequency specified: " + this.frequency() + ", only semi-annual through daily permitted."); break; @@ -280,7 +283,7 @@ protected virtual void validate() } protected virtual double seasonalityCorrection(double rate, Date atDate, DayCounter dc, - Date curveBaseDate, bool isZeroRate) + Date curveBaseDate, bool isZeroRate) { // need _two_ corrections in order to get: seasonality = factor[atDate-seasonalityBase] / factor[reference-seasonalityBase] // i.e. for ZERO inflation rates you have the true fixing at the curve base so this factor must be normalized to one @@ -307,10 +310,10 @@ protected virtual double seasonalityCorrection(double rate, Date atDate, DayCoun } } - public class KerkhofSeasonality : MultiplicativePriceSeasonality + public class KerkhofSeasonality : MultiplicativePriceSeasonality { - public KerkhofSeasonality(Date seasonalityBaseDate,List seasonalityFactors) - : base(seasonalityBaseDate,Frequency.Monthly,seasonalityFactors) + public KerkhofSeasonality(Date seasonalityBaseDate, List seasonalityFactors) + : base(seasonalityBaseDate, Frequency.Monthly, seasonalityFactors) {} public override double seasonalityFactor(Date to) @@ -331,43 +334,43 @@ public override double seasonalityFactor(Date to) } Utils.QL_REQUIRE(seasonalityFactors().Count == 12 && - factorPeriod.units() == TimeUnit.Months,()=> + factorPeriod.units() == TimeUnit.Months, () => "12 monthly seasonal factors needed for Kerkhof Seasonality:" + " got " + seasonalityFactors().Count); double seasonalCorrection = 1.0; - for (int i = fromMonth ; i lim = Utils.inflationPeriod(curveBaseDate, Frequency.Monthly); + KeyValuePair lim = Utils.inflationPeriod(curveBaseDate, Frequency.Monthly); double timeFromCurveBase = dc.yearFraction(lim.Key, atDate); - f = Math.Pow(indexFactor, 1/timeFromCurveBase); + f = Math.Pow(indexFactor, 1 / timeFromCurveBase); } - else + else { Utils.QL_FAIL("Seasonal Kerkhof model is not defined on YoY rates"); } - return (rate + 1)*f - 1; + return (rate + 1) * f - 1; } } } diff --git a/src/QLNet/Termstructures/InflationTermStructure.cs b/src/QLNet/Termstructures/InflationTermStructure.cs index 9e1c0b20c..1073a65c1 100644 --- a/src/QLNet/Termstructures/InflationTermStructure.cs +++ b/src/QLNet/Termstructures/InflationTermStructure.cs @@ -2,18 +2,18 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -40,11 +40,11 @@ public static KeyValuePair inflationPeriod(Date d, Frequency frequen endMonth = Month.December; break; case Frequency.Semiannual: - startMonth = (Month) (6 * ((int) month - 1) / 6 + 1); + startMonth = (Month)(6 * ((int) month - 1) / 6 + 1); endMonth = startMonth + 5; break; case Frequency.Quarterly: - startMonth = (Month) (3 * ((int) month - 1) / 3 + 1); + startMonth = (Month)(3 * ((int) month - 1) / 3 + 1); endMonth = startMonth + 2; break; case Frequency.Monthly: @@ -62,8 +62,8 @@ public static KeyValuePair inflationPeriod(Date d, Frequency frequen } public static double inflationYearFraction(Frequency f, bool indexIsInterpolated, - DayCounter dayCounter, - Date d1, Date d2) + DayCounter dayCounter, + Date d1, Date d2) { double t = 0; if (indexIsInterpolated) @@ -87,7 +87,7 @@ public static double inflationYearFraction(Frequency f, bool indexIsInterpolated } //! Interface for inflation term structures. - //! \ingroup inflationtermstructures + //! \ingroup inflationtermstructures public abstract class InflationTermStructure : TermStructure { protected InflationTermStructure() @@ -95,12 +95,12 @@ protected InflationTermStructure() // Constructors protected InflationTermStructure(double baseRate, - Period observationLag, - Frequency frequency, - bool indexIsInterpolated, - Handle yTS, - DayCounter dayCounter = null, - Seasonality seasonality = null) + Period observationLag, + Frequency frequency, + bool indexIsInterpolated, + Handle yTS, + DayCounter dayCounter = null, + Seasonality seasonality = null) : base(dayCounter) { nominalTermStructure_ = yTS; @@ -113,14 +113,14 @@ protected InflationTermStructure(double baseRate, } protected InflationTermStructure(Date referenceDate, - double baseRate, - Period observationLag, - Frequency frequency, - bool indexIsInterpolated, - Handle yTS, - Calendar calendar, - DayCounter dayCounter = null, - Seasonality seasonality = null) + double baseRate, + Period observationLag, + Frequency frequency, + bool indexIsInterpolated, + Handle yTS, + Calendar calendar, + DayCounter dayCounter = null, + Seasonality seasonality = null) : base(referenceDate, calendar, dayCounter) { nominalTermStructure_ = yTS; @@ -133,14 +133,14 @@ protected InflationTermStructure(Date referenceDate, } protected InflationTermStructure(int settlementDays, - Calendar calendar, - double baseRate, - Period observationLag, - Frequency frequency, - bool indexIsInterpolated, - Handle yTS, - DayCounter dayCounter = null, - Seasonality seasonality = null) + Calendar calendar, + double baseRate, + Period observationLag, + Frequency frequency, + bool indexIsInterpolated, + Handle yTS, + DayCounter dayCounter = null, + Seasonality seasonality = null) : base(settlementDays, calendar, dayCounter) { nominalTermStructure_ = yTS; @@ -205,7 +205,7 @@ public void setSeasonality(Seasonality seasonality = null) if (seasonality_ != null) { Utils.QL_REQUIRE(seasonality_.isConsistent(this), - () => "Seasonality inconsistent with " + "inflation term structure"); + () => "Seasonality inconsistent with " + "inflation term structure"); } notifyObservers(); } @@ -242,7 +242,7 @@ protected override void checkRange(Date d, bool extrapolate) Utils.QL_REQUIRE(d >= baseDate(), () => "date (" + d + ") is before base date"); Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || d <= maxDate(), () => - "date (" + d + ") is past max curve date (" + maxDate() + ")"); + "date (" + d + ") is past max curve date (" + maxDate() + ")"); } private Seasonality seasonality_; @@ -265,7 +265,7 @@ protected ZeroInflationTermStructure(DayCounter dayCounter, Handle yTS, Seasonality seasonality = null) : base(baseZeroRate, observationLag, frequency, indexIsInterpolated, - yTS, dayCounter, seasonality) + yTS, dayCounter, seasonality) {} protected ZeroInflationTermStructure(Date referenceDate, @@ -278,7 +278,7 @@ protected ZeroInflationTermStructure(Date referenceDate, Handle yTS, Seasonality seasonality = null) : base(referenceDate, baseZeroRate, observationLag, frequency, indexIsInterpolated, - yTS, calendar, dayCounter, seasonality) + yTS, calendar, dayCounter, seasonality) {} protected ZeroInflationTermStructure(int settlementDays, @@ -291,7 +291,7 @@ protected ZeroInflationTermStructure(int settlementDays, Handle yTS, Seasonality seasonality = null) : base(settlementDays, calendar, baseZeroRate, observationLag, frequency, - indexIsInterpolated, yTS, dayCounter, seasonality) + indexIsInterpolated, yTS, dayCounter, seasonality) {} // Inspectors @@ -324,8 +324,8 @@ public double zeroRate(Date d, Period instObsLag, bool forceLinearInterpolation) } public double zeroRate(Date d, Period instObsLag, - bool forceLinearInterpolation, - bool extrapolate) + bool forceLinearInterpolation, + bool extrapolate) { Period useLag = instObsLag; if (instObsLag == new Period(-1, TimeUnit.Days)) @@ -392,7 +392,7 @@ protected YoYInflationTermStructure(DayCounter dayCounter, Handle yTS, Seasonality seasonality = null) : base(baseYoYRate, observationLag, frequency, indexIsInterpolated, - yTS, dayCounter, seasonality) + yTS, dayCounter, seasonality) {} protected YoYInflationTermStructure(Date referenceDate, @@ -405,7 +405,7 @@ protected YoYInflationTermStructure(Date referenceDate, Handle yTS, Seasonality seasonality = null) : base(referenceDate, baseYoYRate, observationLag, frequency, indexIsInterpolated, - yTS, calendar, dayCounter, seasonality) + yTS, calendar, dayCounter, seasonality) {} protected YoYInflationTermStructure(int settlementDays, @@ -418,8 +418,8 @@ protected YoYInflationTermStructure(int settlementDays, Handle yTS, Seasonality seasonality = null) : base(settlementDays, calendar, baseYoYRate, observationLag, - frequency, indexIsInterpolated, - yTS, dayCounter, seasonality) + frequency, indexIsInterpolated, + yTS, dayCounter, seasonality) {} // Inspectors @@ -445,7 +445,7 @@ public double yoyRate(Date d, Period instObsLag, bool forceLinearInterpolation) } public double yoyRate(Date d, Period instObsLag, bool forceLinearInterpolation, - bool extrapolate) + bool extrapolate) { Period useLag = instObsLag; if (instObsLag == new Period(-1, TimeUnit.Days)) diff --git a/src/QLNet/Termstructures/InterpolatedCurve.cs b/src/QLNet/Termstructures/InterpolatedCurve.cs new file mode 100644 index 000000000..f7e4683f5 --- /dev/null +++ b/src/QLNet/Termstructures/InterpolatedCurve.cs @@ -0,0 +1,59 @@ +/* + Copyright (C) 2009 Siarhei Novik (snovik@gmail.com) + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + //! Helper class to build interpolated term structures + /*! Interpolated term structures can use protected or private + inheritance from this class to obtain the relevant data + members and implement correct copy behavior. + */ + public interface InterpolatedCurve : ICloneable + { + List times_ { get; set; } + List times(); + + List dates_ { get; set; } + List dates(); + Date maxDate(); + + List data_ { get; set; } + List data(); + + Dictionary nodes(); + + Interpolation interpolation_ { get; set; } + IInterpolationFactory interpolator_ { get; set; } + void setupInterpolation(); + // Usually, the maximum date is the one corresponding to the + // last node. However, it might happen that a bit of + // extrapolation is used by construction; for instance, when a + // curve is bootstrapped and the last relevant date for an + // instrument is after the corresponding pillar. + // We provide here a slot to store this information, so that + // it's available to all derived classes (we should have + // probably done the same with the dates_ vector, but moving + // it here might not be entirely backwards-compatible). + Date maxDate_ { get; set; } + + } +} diff --git a/src/QLNet/Termstructures/Iterativebootstrap.cs b/src/QLNet/Termstructures/Iterativebootstrap.cs index 99f1b2335..f04c33ff1 100644 --- a/src/QLNet/Termstructures/Iterativebootstrap.cs +++ b/src/QLNet/Termstructures/Iterativebootstrap.cs @@ -2,18 +2,18 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) Copyright (C) 2014 Edem Dawui (edawui@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,169 +21,169 @@ under the terms of the QLNet license. You should have received a using System; using System.Collections.Generic; -namespace QLNet +namespace QLNet { - public interface IBootStrap - { - void setup( T ts ); - void calculate(); - } - - public class IterativeBootstrapForYield : IterativeBootstrap - { - } - - public class IterativeBootstrapForInflation : IterativeBootstrap - { - } - - public class IterativeBootstrapForYoYInflation : IterativeBootstrap - { - } - - - //! Universal piecewise-term-structure boostrapper. - public class IterativeBootstrap:IBootStrap - where T : Curve, new() - where U : TermStructure - { - private bool validCurve_; - private T ts_; - private int n_; - private Brent firstSolver_ = new Brent(); - private FiniteDifferenceNewtonSafe solver_ = new FiniteDifferenceNewtonSafe(); + public interface IBootStrap + { + void setup(T ts); + void calculate(); + } + + public class IterativeBootstrapForYield : IterativeBootstrap + { + } + + public class IterativeBootstrapForInflation : IterativeBootstrap + { + } + + public class IterativeBootstrapForYoYInflation : IterativeBootstrap + { + } + + + //! Universal piecewise-term-structure boostrapper. + public class IterativeBootstrap: IBootStrap + where T : Curve, new () + where U : TermStructure + { + private bool validCurve_; + private T ts_; + private int n_; + private Brent firstSolver_ = new Brent(); + private FiniteDifferenceNewtonSafe solver_ = new FiniteDifferenceNewtonSafe(); private bool initialized_, loopRequired_; - private int firstAliveHelper_, alive_; - private List previousData_; - private List> errors_; - - public IterativeBootstrap() - { - ts_ = FastActivator.Create(); - initialized_ = false; - validCurve_ = false; - } - - private void initialize() - { - // ensure helpers are sorted - ts_.instruments_.Sort( ( x, y ) => x.pillarDate().CompareTo( y.pillarDate() ) ); - - // skip expired helpers - Date firstDate = ts_.initialDate(); - Utils.QL_REQUIRE( ts_.instruments_[n_ - 1].pillarDate() > firstDate, () => "all instruments expired" ); - firstAliveHelper_ = 0; - while ( ts_.instruments_[firstAliveHelper_].pillarDate() <= firstDate ) - ++firstAliveHelper_; - alive_ = n_ - firstAliveHelper_; - Utils.QL_REQUIRE( alive_ >= ts_.interpolator_.requiredPoints - 1, () => - "not enough alive instruments: " + alive_ + - " provided, " + ( ts_.interpolator_.requiredPoints - 1 ) + - " required" ); - - - if ( ts_.dates_ == null ) + private int firstAliveHelper_, alive_; + private List previousData_; + private List> errors_; + + public IterativeBootstrap() + { + ts_ = FastActivator.Create(); + initialized_ = false; + validCurve_ = false; + } + + private void initialize() + { + // ensure helpers are sorted + ts_.instruments_.Sort((x, y) => x.pillarDate().CompareTo(y.pillarDate())); + + // skip expired helpers + Date firstDate = ts_.initialDate(); + Utils.QL_REQUIRE(ts_.instruments_[n_ - 1].pillarDate() > firstDate, () => "all instruments expired"); + firstAliveHelper_ = 0; + while (ts_.instruments_[firstAliveHelper_].pillarDate() <= firstDate) + ++firstAliveHelper_; + alive_ = n_ - firstAliveHelper_; + Utils.QL_REQUIRE(alive_ >= ts_.interpolator_.requiredPoints - 1, () => + "not enough alive instruments: " + alive_ + + " provided, " + (ts_.interpolator_.requiredPoints - 1) + + " required"); + + + if (ts_.dates_ == null) { - ts_.dates_ = new InitializedList( alive_ + 1 ); - ts_.times_ = new InitializedList( alive_ + 1 ); + ts_.dates_ = new InitializedList(alive_ + 1); + ts_.times_ = new InitializedList(alive_ + 1); } - else if ( ts_.dates_.Count != alive_ + 1 ) + else if (ts_.dates_.Count != alive_ + 1) { - ts_.dates_.Resize( alive_ + 1 ); - ts_.times_.Resize( alive_ + 1 ); + ts_.dates_.Resize(alive_ + 1); + ts_.times_.Resize(alive_ + 1); } List dates = ts_.dates_; List times = ts_.times_; - - errors_ = new List>( alive_ + 1 ); - dates[0] = firstDate ; - times[0] = ( ts_.timeFromReference( dates[0] ) ); + + errors_ = new List>(alive_ + 1); + dates[0] = firstDate ; + times[0] = (ts_.timeFromReference(dates[0])); Date latestRelevantDate, maxDate = firstDate; - for ( int i = 1, j = firstAliveHelper_; j < n_; ++i, ++j ) - { - BootstrapHelper helper = ts_.instruments_[j]; - dates[i] = ( helper.pillarDate() ); - times[i] = ( ts_.timeFromReference( dates[i] ) ); - // check for duplicated maturity - Utils.QL_REQUIRE( dates[i - 1] != dates[i], () => "more than one instrument with maturity " + dates[i] ); + for (int i = 1, j = firstAliveHelper_; j < n_; ++i, ++j) + { + BootstrapHelper helper = ts_.instruments_[j]; + dates[i] = (helper.pillarDate()); + times[i] = (ts_.timeFromReference(dates[i])); + // check for duplicated maturity + Utils.QL_REQUIRE(dates[i - 1] != dates[i], () => "more than one instrument with maturity " + dates[i]); latestRelevantDate = helper.latestRelevantDate(); // check that the helper is really extending the curve, i.e. that // pillar-sorted helpers are also sorted by latestRelevantDate - Utils.QL_REQUIRE(latestRelevantDate > maxDate,()=> - (j+1) + " instrument (pillar: " + - dates[i] + ") has latestRelevantDate (" + - latestRelevantDate + ") before or equal to " + - "previous instrument's latestRelevantDate (" + - maxDate + ")"); + Utils.QL_REQUIRE(latestRelevantDate > maxDate, () => + (j + 1) + " instrument (pillar: " + + dates[i] + ") has latestRelevantDate (" + + latestRelevantDate + ") before or equal to " + + "previous instrument's latestRelevantDate (" + + maxDate + ")"); maxDate = latestRelevantDate; // when a pillar date is different from the last relevant date the // convergence loop is required even if the Interpolator is local if (dates[i] != latestRelevantDate) - loopRequired_ = true; + loopRequired_ = true; - errors_.Add( new BootstrapError( ts_, helper, i ) ); - } + errors_.Add(new BootstrapError(ts_, helper, i)); + } ts_.maxDate_ = maxDate; - // set initial guess only if the current curve cannot be used as guess - if ( !validCurve_ || ts_.data_.Count != alive_ + 1 ) - { - // ts_->data_[0] is the only relevant item, - // but reasonable numbers might be needed for the whole data vector - // because, e.g., of interpolation's early checks - ts_.data_ = new InitializedList( alive_ + 1, ts_.initialValue() ); - previousData_ = new List( alive_ + 1 ); - } - initialized_ = true; - - } - - public void setup(T ts) - { + // set initial guess only if the current curve cannot be used as guess + if (!validCurve_ || ts_.data_.Count != alive_ + 1) + { + // ts_->data_[0] is the only relevant item, + // but reasonable numbers might be needed for the whole data vector + // because, e.g., of interpolation's early checks + ts_.data_ = new InitializedList(alive_ + 1, ts_.initialValue()); + previousData_ = new List(alive_ + 1); + } + initialized_ = true; + + } + + public void setup(T ts) + { ts_ = ts; n_ = ts_.instruments_.Count; - Utils.QL_REQUIRE( n_ > 0, () => "no bootstrap helpers given" ); + Utils.QL_REQUIRE(n_ > 0, () => "no bootstrap helpers given"); - Utils.QL_REQUIRE(n_+1 >= ts_.interpolator_.requiredPoints,()=> - "not enough instruments: " + n_ + " provided, " + (ts_.interpolator_.requiredPoints-1) + " required"); + Utils.QL_REQUIRE(n_ + 1 >= ts_.interpolator_.requiredPoints, () => + "not enough instruments: " + n_ + " provided, " + (ts_.interpolator_.requiredPoints - 1) + " required"); ts_.instruments_.ForEach((i, x) => ts_.registerWith(x)); loopRequired_ = ts_.interpolator_.global; } - public void calculate() - { - // we might have to call initialize even if the curve is initialized - // and not moving, just because helpers might be date relative and change - // with evaluation date change. - // anyway it makes little sense to use date relative helpers with a - // non-moving curve if the evaluation date changes - if ( !initialized_ || ts_.moving_ ) - initialize(); - - // setup helpers - for ( int j = firstAliveHelper_; j < n_; ++j ) - { - BootstrapHelper helper = ts_.instruments_[j]; - // check for valid quote - Utils.QL_REQUIRE( helper.quote().link.isValid(), () => - ( j + 1 ) + " instrument (maturity: " + - helper.pillarDate() + ") has an invalid quote" ); - // don't try this at home! - // This call creates helpers, and removes "const". - // There is a significant interaction with observability. - ts_.setTermStructure( ts_.instruments_[j] ); - } - - List times = ts_.times_; - List data = ts_.data_; - double accuracy = ts_.accuracy_; - int maxIterations = ts_.maxIterations() - 1; + public void calculate() + { + // we might have to call initialize even if the curve is initialized + // and not moving, just because helpers might be date relative and change + // with evaluation date change. + // anyway it makes little sense to use date relative helpers with a + // non-moving curve if the evaluation date changes + if (!initialized_ || ts_.moving_) + initialize(); + + // setup helpers + for (int j = firstAliveHelper_; j < n_; ++j) + { + BootstrapHelper helper = ts_.instruments_[j]; + // check for valid quote + Utils.QL_REQUIRE(helper.quote().link.isValid(), () => + (j + 1) + " instrument (maturity: " + + helper.pillarDate() + ") has an invalid quote"); + // don't try this at home! + // This call creates helpers, and removes "const". + // There is a significant interaction with observability. + ts_.setTermStructure(ts_.instruments_[j]); + } + + List times = ts_.times_; + List data = ts_.data_; + double accuracy = ts_.accuracy_; + int maxIterations = ts_.maxIterations() - 1; // there might be a valid curve state to use as guess bool validData = validCurve_; @@ -199,30 +199,30 @@ public void calculate() // bracket root and calculate guess double min = ts_.minValueAfter(i, ts_, validData, firstAliveHelper_); double max = ts_.maxValueAfter(i, ts_, validData, firstAliveHelper_); - double guess =ts_.guess(i, ts_, validData, firstAliveHelper_); + double guess = ts_.guess(i, ts_, validData, firstAliveHelper_); // adjust guess if needed if (guess >= max) guess = max - (max - min) / 5.0; else if (guess <= min) guess = min + (max - min) / 5.0; - + // extend interpolation if needed if (!validData) { try { - // extend interpolation a point at a time - // including the pillar to be boostrapped - ts_.interpolation_ = ts_.interpolator_.interpolate(ts_.times_, i + 1, ts_.data_); + // extend interpolation a point at a time + // including the pillar to be boostrapped + ts_.interpolation_ = ts_.interpolator_.interpolate(ts_.times_, i + 1, ts_.data_); } catch (Exception) { - if (!ts_.interpolator_.global) - throw; // no chance to fix it in a later iteration + if (!ts_.interpolator_.global) + throw; // no chance to fix it in a later iteration - // otherwise use Linear while the target - // interpolation is not usable yet - ts_.interpolation_ = new Linear().interpolate(ts_.times_, i + 1, ts_.data_); + // otherwise use Linear while the target + // interpolation is not usable yet + ts_.interpolation_ = new Linear().interpolate(ts_.times_, i + 1, ts_.data_); } ts_.interpolation_.update(); } @@ -231,48 +231,48 @@ public void calculate() { var error = new BootstrapError(ts_, ts_.instruments_[i - 1], i); if (validData) - ts_.data_[i] = solver_.solve(error, accuracy, guess, min, max); + ts_.data_[i] = solver_.solve(error, accuracy, guess, min, max); else - ts_.data_[i] = firstSolver_.solve(error, accuracy, guess, min, max); + ts_.data_[i] = firstSolver_.solve(error, accuracy, guess, min, max); } catch (Exception e) { // the previous curve state could have been a bad guess // let's restart without using it - if ( validCurve_ ) + if (validCurve_) { validCurve_ = validData = false; continue; } - Utils.QL_FAIL((iteration+1) + " iteration: failed " + - "at " + (i) + " alive instrument, "+ - "maturity " + ts_.instruments_[i - 1].pillarDate() + - ", reference date " + ts_.dates_[0] + - ": " + e.Message); + Utils.QL_FAIL((iteration + 1) + " iteration: failed " + + "at " + (i) + " alive instrument, " + + "maturity " + ts_.instruments_[i - 1].pillarDate() + + ", reference date " + ts_.dates_[0] + + ": " + e.Message); } - } + } - if ( !loopRequired_ ) - break; // no need for convergence loop + if (!loopRequired_) + break; // no need for convergence loop - // exit condition - double change = Math.Abs( data[1] - previousData_[1] ); - for ( int i = 2; i <= alive_; ++i ) - change = Math.Max( change, Math.Abs( data[i] - previousData_[i] ) ); - if ( change <= accuracy ) // convergence reached - break; + // exit condition + double change = Math.Abs(data[1] - previousData_[1]); + for (int i = 2; i <= alive_; ++i) + change = Math.Max(change, Math.Abs(data[i] - previousData_[i])); + if (change <= accuracy) // convergence reached + break; - Utils.QL_REQUIRE( iteration < maxIterations, () => - "convergence not reached after " + iteration + - " iterations; last improvement " + change + - ", required accuracy " + accuracy ); + Utils.QL_REQUIRE(iteration < maxIterations, () => + "convergence not reached after " + iteration + + " iterations; last improvement " + change + + ", required accuracy " + accuracy); validData = true; - } - validCurve_ = true; + } + validCurve_ = true; - } - } + } + } } diff --git a/src/QLNet/Termstructures/LocalBootstrap.cs b/src/QLNet/Termstructures/LocalBootstrap.cs new file mode 100644 index 000000000..2e7406556 --- /dev/null +++ b/src/QLNet/Termstructures/LocalBootstrap.cs @@ -0,0 +1,222 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) + Copyright (C) 2014 Edem Dawui (edawui@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QLNet +{ + public class LocalBootstrapForYield : LocalBootstrap + {} + + // penalty function class for solving using a multi-dimensional solver + public class PenaltyFunction : CostFunction + where T : Curve, new () + where U : TermStructure + { + private T curve_; + private int initialIndex_; + private int localisation_, start_, end_; + private List> rateHelpers_; + + public PenaltyFunction(T curve, int initialIndex, List> rateHelpers, int start, int end) + { + curve_ = curve; + initialIndex_ = initialIndex; + rateHelpers_ = rateHelpers; + start_ = start; + end_ = end; + localisation_ = end - start; + } + + public override double value(Vector x) + { + x.ForEach((j, v) => curve_.updateGuess(curve_.data_, v, j + initialIndex_)); + + curve_.interpolation_.update(); + + double penalty = rateHelpers_.GetRange(start_, localisation_) + .Aggregate(0.0, (acc, v) => Math.Abs(v.quoteError())); + return penalty; + } + + public override Vector values(Vector x) + { + x.ForEach((j, v) => curve_.updateGuess(curve_.data_, v, j + initialIndex_)); + + curve_.interpolation_.update(); + + var penalties = rateHelpers_.GetRange(start_, localisation_).Select(c => Math.Abs(c.quoteError())).ToList(); + return new Vector(penalties); + } + } + + + //! Localised-term-structure bootstrapper for most curve types. + /*! This algorithm enables a localised fitting for non-local + interpolation methods. + + As in the similar class (IterativeBootstrap) the input term + structure is solved on a number of market instruments which + are passed as a vector of handles to BootstrapHelper + instances. Their maturities mark the boundaries of the + interpolated segments. + + Unlike the IterativeBootstrap class, the solution for each + interpolated segment is derived using a local + approximation. This restricts the risk profile s.t. the risk + is localised. Therefore, we obtain a local IR risk profile + whilst using a smoother interpolation method. Particularly + good for the convex-monotone spline method. + */ + public class LocalBootstrap : IBootStrap + where T : Curve, new () + where U : TermStructure + { + private bool validCurve_; + private T ts_; // yes, it is a workaround + int localisation_; + bool forcePositive_; + + public LocalBootstrap() : this(2, true) { } + public LocalBootstrap(int localisation, bool forcePositive) + { + localisation_ = localisation; + forcePositive_ = forcePositive; + } + + public void setup(T ts) + { + ts_ = ts; + + int n = ts_.instruments_.Count; + Utils.QL_REQUIRE(n >= ts_.interpolator_.requiredPoints, () => + "not enough instruments: " + n + " provided, " + (ts_.interpolator_.requiredPoints) + " required"); + + Utils.QL_REQUIRE(n > localisation_, () => + "not enough instruments: " + n + " provided, " + localisation_ + " required."); + + ts_.instruments_.ForEach((i, x) => ts_.registerWith(x)); + } + + public void calculate() + { + + validCurve_ = false; + int nInsts = ts_.instruments_.Count, i; + + // ensure rate helpers are sorted + ts_.instruments_.Sort((x, y) => x.latestDate().CompareTo(y.latestDate())); + + // check that there is no instruments with the same maturity + for (i = 1; i < nInsts; ++i) + { + Date m1 = ts_.instruments_[i - 1].latestDate(), + m2 = ts_.instruments_[i].latestDate(); + Utils.QL_REQUIRE(m1 != m2, () => "two instruments have the same maturity (" + m1 + ")"); + } + + // check that there is no instruments with invalid quote + Utils.QL_REQUIRE((i = ts_.instruments_.FindIndex(x => !x.quoteIsValid())) == -1, () => + "instrument " + i + " (maturity: " + ts_.instruments_[i].latestDate() + ") has an invalid quote"); + + // setup instruments and register with them + ts_.instruments_.ForEach((x, j) => ts_.setTermStructure(j)); + + // set initial guess only if the current curve cannot be used as guess + if (validCurve_) + { + Utils.QL_REQUIRE(ts_.data_.Count == nInsts + 1, () => + "dimension mismatch: expected " + nInsts + 1 + ", actual " + ts_.data_.Count); + } + else + { + ts_.data_ = new InitializedList(nInsts + 1); + ts_.data_[0] = ts_.initialValue(); + } + + // calculate dates and times + ts_.dates_ = new InitializedList(nInsts + 1); + ts_.times_ = new InitializedList(nInsts + 1); + ts_.dates_[0] = ts_.initialDate(); + ts_.times_[0] = ts_.timeFromReference(ts_.dates_[0]); + for (i = 0; i < nInsts; ++i) + { + ts_.dates_[i + 1] = ts_.instruments_[i].latestDate(); + ts_.times_[i + 1] = ts_.timeFromReference(ts_.dates_[i + 1]); + if (!validCurve_) + ts_.data_[i + 1] = ts_.data_[i]; + } + + LevenbergMarquardt solver = new LevenbergMarquardt(ts_.accuracy_, ts_.accuracy_, ts_.accuracy_); + EndCriteria endCriteria = new EndCriteria(100, 10, 0.00, ts_.accuracy_, 0.00); + PositiveConstraint posConstraint = new PositiveConstraint(); + NoConstraint noConstraint = new NoConstraint(); + Constraint solverConstraint = forcePositive_ ? (Constraint)posConstraint : (Constraint)noConstraint; + + // now start the bootstrapping. + int iInst = localisation_ - 1; + + int dataAdjust = (ts_.interpolator_ as ConvexMonotone).dataSizeAdjustment; + + do + { + int initialDataPt = iInst + 1 - localisation_ + dataAdjust; + Vector startArray = new Vector(localisation_ + 1 - dataAdjust); + for (int j = 0; j < startArray.size() - 1; ++j) + startArray[j] = ts_.data_[initialDataPt + j]; + + // here we are extending the interpolation a point at a + // time... but the local interpolator can make an + // approximation for the final localisation period. + // e.g. if the localisation is 2, then the first section + // of the curve will be solved using the first 2 + // instruments... with the local interpolator making + // suitable boundary conditions. + ts_.interpolation_ = (ts_.interpolator_ as ConvexMonotone).localInterpolate(ts_.times_, iInst + 2, ts_.data_, + localisation_, ts_.interpolation_ as ConvexMonotoneInterpolation, nInsts + 1); + + if (iInst >= localisation_) + { + startArray[localisation_ - dataAdjust] = ts_.guess(iInst, ts_, false, 0); + } + else + { + startArray[localisation_ - dataAdjust] = ts_.data_[0]; + } + + var currentCost = new PenaltyFunction(ts_, initialDataPt, ts_.instruments_, + iInst - localisation_ + 1, iInst + 1); + Problem toSolve = new Problem(currentCost, solverConstraint, startArray); + EndCriteria.Type endType = solver.minimize(toSolve, endCriteria); + + // check the end criteria + Utils.QL_REQUIRE(endType == EndCriteria.Type.StationaryFunctionAccuracy || + endType == EndCriteria.Type.StationaryFunctionValue, () => + "Unable to strip yieldcurve to required accuracy "); + ++iInst; + } + while (iInst < nInsts); + + validCurve_ = true; + } + } +} diff --git a/src/QLNet/Termstructures/TermStructure.cs b/src/QLNet/Termstructures/TermStructure.cs index 97e39f635..0b5ad53f7 100644 --- a/src/QLNet/Termstructures/TermStructure.cs +++ b/src/QLNet/Termstructures/TermStructure.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,7 +23,7 @@ namespace QLNet //! Basic term-structure functionality public abstract class TermStructure : Extrapolator { - + #region Constructors // There are three ways in which a term structure can keep @@ -32,7 +32,7 @@ public abstract class TermStructure : Extrapolator // the current date of a given number of business days; and // the third is that it is based on the reference date of // some other structure. - // + // // In the first case, the constructor taking a date is to be // used; the default implementation of referenceDate() will // then return such date. In the second case, the constructor @@ -43,7 +43,7 @@ public abstract class TermStructure : Extrapolator // changes. In the last case, the referenceDate() method must // be overridden in derived classes so that it fetches and // return the appropriate date. - + //! default constructor /*! \warning term structures initialized by means of this @@ -58,18 +58,18 @@ protected TermStructure(DayCounter dc = null) settlementDays_ = null; dayCounter_ = dc; } - + //! initialize with a fixed reference date - protected TermStructure(Date referenceDate,Calendar calendar = null,DayCounter dc = null) + protected TermStructure(Date referenceDate, Calendar calendar = null, DayCounter dc = null) { moving_ = false; updated_ = true; calendar_ = calendar; referenceDate_ = referenceDate; - settlementDays_= null; + settlementDays_ = null; dayCounter_ = dc; } - + //! calculate the reference date based on the global evaluation date protected TermStructure(int settlementDays, Calendar cal, DayCounter dc = null) { @@ -81,7 +81,7 @@ protected TermStructure(int settlementDays, Calendar cal, DayCounter dc = null) Settings.registerWith(update); } - + #endregion @@ -90,7 +90,7 @@ protected TermStructure(int settlementDays, Calendar cal, DayCounter dc = null) //! the day counter used for date/time conversion public virtual DayCounter dayCounter() {return dayCounter_;} //! date/time conversion - public double timeFromReference( Date date) { return dayCounter().yearFraction(referenceDate(), date);} + public double timeFromReference(Date date) { return dayCounter().yearFraction(referenceDate(), date);} //! the latest date for which the curve can return values public abstract Date maxDate(); //! the latest time for which the curve can return values @@ -98,7 +98,7 @@ protected TermStructure(int settlementDays, Calendar cal, DayCounter dc = null) //! the date at which discount = 1.0 and/or variance = 0.0 public virtual Date referenceDate() { - if (!updated_) + if (!updated_) { Date today = Settings.evaluationDate(); referenceDate_ = calendar().advance(today, settlementDays(), TimeUnit.Days); @@ -109,12 +109,12 @@ public virtual Date referenceDate() //! the calendar used for reference and/or option date calculation public virtual Calendar calendar() {return calendar_;} //! the settlementDays used for reference date calculation - public virtual int settlementDays() + public virtual int settlementDays() { - Utils.QL_REQUIRE( settlementDays_ != null, () => "settlement days not provided for this instance" ); + Utils.QL_REQUIRE(settlementDays_ != null, () => "settlement days not provided for this instance"); return settlementDays_.Value; } - + #endregion #region observable & observer interface @@ -123,7 +123,7 @@ public virtual int settlementDays() public override void update() { if (moving_) - updated_ = false; + updated_ = false; // recheck. this is in order to notify observers in the base method of LazyObject calculated_ = true; @@ -136,23 +136,23 @@ public override void update() //! date-range check protected virtual void checkRange(Date d, bool extrapolate) { - Utils.QL_REQUIRE( d >= referenceDate(), () => - "date (" + d + ") before reference date (" + - referenceDate() + ")"); - Utils.QL_REQUIRE( extrapolate || allowsExtrapolation() || d <= maxDate(), () => - "date (" + d + ") is past max curve date (" - + maxDate() + ")"); + Utils.QL_REQUIRE(d >= referenceDate(), () => + "date (" + d + ") before reference date (" + + referenceDate() + ")"); + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || d <= maxDate(), () => + "date (" + d + ") is past max curve date (" + + maxDate() + ")"); } //! time-range check protected void checkRange(double t, bool extrapolate) { - Utils.QL_REQUIRE( t >= 0.0, () => - "negative time (" + t + ") given"); + Utils.QL_REQUIRE(t >= 0.0, () => + "negative time (" + t + ") given"); Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() - || t <= maxTime() || Utils.close_enough( t, maxTime() ), () => - "time (" + t + ") is past max curve time (" - + maxTime() + ")"); + || t <= maxTime() || Utils.close_enough(t, maxTime()), () => + "time (" + t + ") is past max curve time (" + + maxTime() + ")"); } protected bool moving_; diff --git a/src/QLNet/Termstructures/voltermstructure.cs b/src/QLNet/Termstructures/VolTermStructure.cs similarity index 78% rename from src/QLNet/Termstructures/voltermstructure.cs rename to src/QLNet/Termstructures/VolTermStructure.cs index 52adff093..aed52b384 100644 --- a/src/QLNet/Termstructures/voltermstructure.cs +++ b/src/QLNet/Termstructures/VolTermStructure.cs @@ -1,54 +1,54 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet +namespace QLNet { //! Volatility term structure /*! This abstract class defines the interface of concrete volatility structures which will be derived from this one. */ - public abstract class VolatilityTermStructure : TermStructure + public abstract class VolatilityTermStructure : TermStructure { #region Constructors - + /*! \warning term structures initialized by means of this constructor must manage their own reference date by overriding the referenceDate() method. */ protected VolatilityTermStructure(BusinessDayConvention bdc, DayCounter dc = null) - :base(dc) + : base(dc) { bdc_ = bdc; } //! initialize with a fixed reference date - protected VolatilityTermStructure(Date referenceDate,Calendar cal, BusinessDayConvention bdc, DayCounter dc = null) - :base(referenceDate, cal, dc) + protected VolatilityTermStructure(Date referenceDate, Calendar cal, BusinessDayConvention bdc, DayCounter dc = null) + : base(referenceDate, cal, dc) { bdc_ = bdc; } //! calculate the reference date based on the global evaluation date - protected VolatilityTermStructure(int settlementDays,Calendar cal, BusinessDayConvention bdc, DayCounter dc =null) - :base(settlementDays, cal, dc) + protected VolatilityTermStructure(int settlementDays, Calendar cal, BusinessDayConvention bdc, DayCounter dc = null) + : base(settlementDays, cal, dc) { bdc_ = bdc; } @@ -70,17 +70,17 @@ public virtual Date optionDateFromTenor(Period p) //! the maximum strike for which the term structure can return vols public abstract double maxStrike(); - + //! strike-range check protected void checkStrike(double k, bool extrapolate) { Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || - ( k >= minStrike() && k <= maxStrike() ), () => - "strike (" + k + ") is outside the curve domain [" - + minStrike() + "," + maxStrike() + "]"); + (k >= minStrike() && k <= maxStrike()), () => + "strike (" + k + ") is outside the curve domain [" + + minStrike() + "," + maxStrike() + "]"); } private BusinessDayConvention bdc_; - } + } } diff --git a/src/QLNet/Termstructures/Volatility/AbcdCalibration.cs b/src/QLNet/Termstructures/Volatility/AbcdCalibration.cs index 5c1ea676e..41efbca30 100644 --- a/src/QLNet/Termstructures/Volatility/AbcdCalibration.cs +++ b/src/QLNet/Termstructures/Volatility/AbcdCalibration.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,14 +21,14 @@ namespace QLNet { public class AbcdCalibration { - private class AbcdError : CostFunction + private class AbcdError : CostFunction { public AbcdError(AbcdCalibration abcd) { abcd_ = abcd; } - public override double value(Vector x) + public override double value(Vector x) { Vector y = abcd_.transformation_.direct(x); abcd_.a_ = y[0]; @@ -37,8 +37,8 @@ public override double value(Vector x) abcd_.d_ = y[3]; return abcd_.error(); } - - public override Vector values(Vector x) + + public override Vector values(Vector x) { Vector y = abcd_.transformation_.direct(x); abcd_.a_ = y[0]; @@ -47,15 +47,15 @@ public override Vector values(Vector x) abcd_.d_ = y[3]; return abcd_.errors(); } - + private AbcdCalibration abcd_; } - - private class AbcdParametersTransformation : IParametersTransformation + + private class AbcdParametersTransformation : IParametersTransformation { public AbcdParametersTransformation() { - y_= new Vector(4); + y_ = new Vector(4); } // to constrained <- from unconstrained public Vector direct(Vector x) @@ -80,48 +80,48 @@ public Vector inverse(Vector x) private Vector y_; } - + public AbcdCalibration() {} // to constrained <- from unconstrained - public AbcdCalibration( List t, - List blackVols, - double aGuess = -0.06, - double bGuess = 0.17, - double cGuess = 0.54, - double dGuess = 0.17, - bool aIsFixed = false, - bool bIsFixed = false, - bool cIsFixed = false, - bool dIsFixed = false, - bool vegaWeighted = false, - EndCriteria endCriteria = null, - OptimizationMethod method = null) + public AbcdCalibration(List t, + List blackVols, + double aGuess = -0.06, + double bGuess = 0.17, + double cGuess = 0.54, + double dGuess = 0.17, + bool aIsFixed = false, + bool bIsFixed = false, + bool cIsFixed = false, + bool dIsFixed = false, + bool vegaWeighted = false, + EndCriteria endCriteria = null, + OptimizationMethod method = null) { - aIsFixed_ = aIsFixed; + aIsFixed_ = aIsFixed; bIsFixed_ = bIsFixed; - cIsFixed_ = cIsFixed; + cIsFixed_ = cIsFixed; dIsFixed_ = dIsFixed; a_ = aGuess; b_ = bGuess; c_ = cGuess; d_ = dGuess; - abcdEndCriteria_ = QLNet.EndCriteria.Type.None; + abcdEndCriteria_ = QLNet.EndCriteria.Type.None; endCriteria_ = endCriteria; - optMethod_ = method; - weights_ = new InitializedList(blackVols.Count, 1.0/blackVols.Count); + optMethod_ = method; + weights_ = new InitializedList(blackVols.Count, 1.0 / blackVols.Count); vegaWeighted_ = vegaWeighted; times_ = t; blackVols_ = blackVols; - + AbcdMathFunction.validate(aGuess, bGuess, cGuess, dGuess); - Utils.QL_REQUIRE(blackVols.Count == t.Count,()=> - "mismatch between number of times (" + t.Count + ") and blackVols (" + blackVols.Count + ")"); + Utils.QL_REQUIRE(blackVols.Count == t.Count, () => + "mismatch between number of times (" + t.Count + ") and blackVols (" + blackVols.Count + ")"); // if no optimization method or endCriteria is provided, we provide one - if (optMethod_ == null) + if (optMethod_ == null) { double epsfcn = 1.0e-8; double xtol = 1.0e-8; @@ -130,27 +130,27 @@ public AbcdCalibration( List t, optMethod_ = new LevenbergMarquardt(epsfcn, xtol, gtol, useCostFunctionsJacobian); } - if (endCriteria_ == null) + if (endCriteria_ == null) { int maxIterations = 10000; int maxStationaryStateIterations = 1000; double rootEpsilon = 1.0e-8; double functionEpsilon = 0.3e-4; // Why 0.3e-4 ? double gradientNormEpsilon = 0.3e-4; // Why 0.3e-4 ? - endCriteria_ = new EndCriteria(maxIterations, maxStationaryStateIterations,rootEpsilon, functionEpsilon, - gradientNormEpsilon); + endCriteria_ = new EndCriteria(maxIterations, maxStationaryStateIterations, rootEpsilon, functionEpsilon, + gradientNormEpsilon); } } - + //! adjustment factors needed to match Black vols public List k(List t, List blackVols) { - Utils.QL_REQUIRE(blackVols.Count==t.Count,()=> - "mismatch between number of times (" + t.Count + ") and blackVols (" + blackVols.Count + ")"); + Utils.QL_REQUIRE(blackVols.Count == t.Count, () => + "mismatch between number of times (" + t.Count + ") and blackVols (" + blackVols.Count + ")"); List k = new InitializedList(t.Count); - for (int i=0; i k(List t, List blackVols) public void compute() { - if (vegaWeighted_) + if (vegaWeighted_) { double weightsSum = 0.0; - for (int i=0; i. -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,37 +23,37 @@ following Rebonato's notation. */ public class AbcdFunction : AbcdMathFunction { public AbcdFunction(double a = -0.06, double b = 0.17, double c = 0.54, double d = 0.17) - :base(a , b, c , d) + : base(a, b, c, d) {} //! maximum value of the volatility function public double maximumVolatility() { return maximumValue(); } //! volatility function value at time 0: \f[ f(0) \f] - public double shortTermVolatility() { return new AbcdFunction().value( 0.0 ); } + public double shortTermVolatility() { return new AbcdFunction().value(0.0); } //! volatility function value at time +inf: \f[ f(\inf) \f] public double longTermVolatility() { return longTermValue(); } /*! instantaneous covariance function at time t between T-fixing and S-fixing rates \f[ f(T-t)f(S-t) \f] */ - public double covariance( double t, double T, double S ) + public double covariance(double t, double T, double S) { - return new AbcdFunction().value( T - t ) * new AbcdFunction().value( S - t ); + return new AbcdFunction().value(T - t) * new AbcdFunction().value(S - t); } /*! integral of the instantaneous covariance function between time t1 and t2 for T-fixing and S-fixing rates \f[ \int_{t1}^{t2} f(T-t)f(S-t)dt \f] */ - public double covariance( double t1, double t2, double T, double S ) + public double covariance(double t1, double t2, double T, double S) { - Utils.QL_REQUIRE(t1<=t2,()=> "integrations bounds (" + t1 + "," + t2 + ") are in reverse order"); - double cutOff = Math.Min(S,T); - if (t1>=cutOff) + Utils.QL_REQUIRE(t1 <= t2, () => "integrations bounds (" + t1 + "," + t2 + ") are in reverse order"); + double cutOff = Math.Min(S, T); + if (t1 >= cutOff) { return 0.0; - } - else + } + else { cutOff = Math.Min(t2, cutOff); return primitive(cutOff, T, S) - primitive(t1, T, S); @@ -62,80 +62,81 @@ public double covariance( double t1, double t2, double T, double S ) /*! average volatility in [tMin,tMax] of T-fixing rate: \f[ \sqrt{ \frac{\int_{tMin}^{tMax} f^2(T-u)du}{tMax-tMin} } \f] */ - public double volatility( double tMin, double tMax, double T ) + public double volatility(double tMin, double tMax, double T) { if (tMax.IsEqual(tMin)) return instantaneousVolatility(tMax, T); - Utils.QL_REQUIRE(tMax>tMin,()=> "tMax must be > tMin"); - return Math.Sqrt(variance(tMin, tMax, T)/(tMax-tMin)); + Utils.QL_REQUIRE(tMax > tMin, () => "tMax must be > tMin"); + return Math.Sqrt(variance(tMin, tMax, T) / (tMax - tMin)); } /*! variance between tMin and tMax of T-fixing rate: \f[ \frac{\int_{tMin}^{tMax} f^2(T-u)du}{tMax-tMin} \f] */ - public double variance( double tMin, double tMax, double T ) + public double variance(double tMin, double tMax, double T) { - return covariance( tMin, tMax, T, T ); + return covariance(tMin, tMax, T, T); } - - + + // INSTANTANEOUS /*! instantaneous volatility at time t of the T-fixing rate: \f[ f(T-t) \f] */ - public double instantaneousVolatility( double u, double T ) + public double instantaneousVolatility(double u, double T) { - return Math.Sqrt(instantaneousVariance(u, T)); + return Math.Sqrt(instantaneousVariance(u, T)); } /*! instantaneous variance at time t of T-fixing rate: \f[ f(T-t)f(T-t) \f] */ - public double instantaneousVariance( double u, double T ) + public double instantaneousVariance(double u, double T) { - return instantaneousCovariance( u, T, T ); + return instantaneousCovariance(u, T, T); } /*! instantaneous covariance at time t between T and S fixing rates: \f[ f(T-u)f(S-u) \f] */ - public double instantaneousCovariance( double u, double T, double S ) + public double instantaneousCovariance(double u, double T, double S) { - return new AbcdFunction().value( T - u ) * new AbcdFunction().value( S - u ); + return new AbcdFunction().value(T - u) * new AbcdFunction().value(S - u); } // PRIMITIVE /*! indefinite integral of the instantaneous covariance function at time t between T-fixing and S-fixing rates \f[ \int f(T-t)f(S-t)dt \f] */ - public double primitive( double t, double T, double S ) + public double primitive(double t, double T, double S) { - if (T. -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -18,11 +18,11 @@ namespace QLNet { public class AtmSmileSection : SmileSection { - public AtmSmileSection( SmileSection source,double? atm = null) + public AtmSmileSection(SmileSection source, double? atm = null) { source_ = source; f_ = atm; - if ( f_ == null ) + if (f_ == null) f_ = source_.atmLevel(); } diff --git a/src/QLNet/Termstructures/Volatility/Bond/CallableBondConstantVolatility.cs b/src/QLNet/Termstructures/Volatility/Bond/CallableBondConstantVolatility.cs index 310377ccc..f82e6d14d 100644 --- a/src/QLNet/Termstructures/Volatility/Bond/CallableBondConstantVolatility.cs +++ b/src/QLNet/Termstructures/Volatility/Bond/CallableBondConstantVolatility.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,36 +23,36 @@ namespace QLNet public class CallableBondConstantVolatility : CallableBondVolatilityStructure { public CallableBondConstantVolatility(Date referenceDate, double volatility, DayCounter dayCounter) - :base(referenceDate) + : base(referenceDate) { volatility_ = new Handle(new SimpleQuote(volatility)); dayCounter_ = dayCounter; - maxBondTenor_ = new Period(100,TimeUnit.Years); + maxBondTenor_ = new Period(100, TimeUnit.Years); } public CallableBondConstantVolatility(Date referenceDate, Handle volatility, DayCounter dayCounter) - :base(referenceDate) + : base(referenceDate) { volatility_ = volatility; dayCounter_ = dayCounter; - maxBondTenor_ = new Period(100,TimeUnit.Years); + maxBondTenor_ = new Period(100, TimeUnit.Years); volatility_.registerWith(update); } public CallableBondConstantVolatility(int settlementDays, Calendar calendar, double volatility, DayCounter dayCounter) - :base(settlementDays, calendar) + : base(settlementDays, calendar) { volatility_ = new Handle(new SimpleQuote(volatility)); dayCounter_ = dayCounter; - maxBondTenor_ = new Period(100,TimeUnit.Years); + maxBondTenor_ = new Period(100, TimeUnit.Years); } - public CallableBondConstantVolatility(int settlementDays, Calendar calendar, Handle volatility,DayCounter dayCounter) - :base(settlementDays, calendar) + public CallableBondConstantVolatility(int settlementDays, Calendar calendar, Handle volatility, DayCounter dayCounter) + : base(settlementDays, calendar) { volatility_ = volatility; dayCounter_ = dayCounter; - maxBondTenor_ = new Period(100,TimeUnit.Years); + maxBondTenor_ = new Period(100, TimeUnit.Years); volatility_.registerWith(update); } @@ -75,7 +75,7 @@ protected override SmileSection smileSectionImpl(double optionTime, double bondL double atmVol = volatility_.link.value(); return new FlatSmileSection(optionTime, atmVol, dayCounter_); } - protected override double volatilityImpl( Date d , Period p, double d1) + protected override double volatilityImpl(Date d, Period p, double d1) { return volatility_.link.value(); } diff --git a/src/QLNet/Termstructures/Volatility/Bond/CallableBondVolatilityStructure.cs b/src/QLNet/Termstructures/Volatility/Bond/CallableBondVolatilityStructure.cs index 25a07c98e..b801ddcce 100644 --- a/src/QLNet/Termstructures/Volatility/Bond/CallableBondVolatilityStructure.cs +++ b/src/QLNet/Termstructures/Volatility/Bond/CallableBondVolatilityStructure.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -40,15 +40,15 @@ protected CallableBondVolatilityStructure(DayCounter dc = null, BusinessDayConve bdc_ = bdc; } //! initialize with a fixed reference date - protected CallableBondVolatilityStructure( Date referenceDate, Calendar calendar = null, DayCounter dc = null, - BusinessDayConvention bdc = BusinessDayConvention.Following) + protected CallableBondVolatilityStructure(Date referenceDate, Calendar calendar = null, DayCounter dc = null, + BusinessDayConvention bdc = BusinessDayConvention.Following) : base(referenceDate, calendar ?? new Calendar(), dc ?? new DayCounter()) { bdc_ = bdc; } //! calculate the reference date based on the global evaluation date protected CallableBondVolatilityStructure(int settlementDays, Calendar calendar, DayCounter dc = null, - BusinessDayConvention bdc = BusinessDayConvention.Following) + BusinessDayConvention bdc = BusinessDayConvention.Following) : base(settlementDays, calendar, dc ?? new DayCounter()) { bdc_ = bdc; @@ -77,9 +77,9 @@ public double blackVariance(Date optionDate, Period bondTenor, double strike, bo { double vol = volatility(optionDate, bondTenor, strike, extrapolate); KeyValuePair p = convertDates(optionDate, bondTenor); - return vol*vol*p.Key; + return vol * vol * p.Key; } - public virtual SmileSection smileSection(Date optionDate, Period bondTenor) + public virtual SmileSection smileSection(Date optionDate, Period bondTenor) { KeyValuePair p = convertDates(optionDate, bondTenor); return smileSectionImpl(p.Key, p.Value); @@ -121,11 +121,11 @@ public virtual double maxBondLength() public virtual KeyValuePair convertDates(Date optionDate, Period bondTenor) { Date end = optionDate + bondTenor; - Utils.QL_REQUIRE( end > optionDate, () => - "negative bond tenor (" + bondTenor + ") given"); - double optionTime = timeFromReference(optionDate); - double timeLength = dayCounter().yearFraction(optionDate, end); - return new KeyValuePair(optionTime, timeLength); + Utils.QL_REQUIRE(end > optionDate, () => + "negative bond tenor (" + bondTenor + ") given"); + double optionTime = timeFromReference(optionDate); + double timeLength = dayCounter().yearFraction(optionDate, end); + return new KeyValuePair(optionTime, timeLength); } //! the business day convention used for option date calculation public virtual BusinessDayConvention businessDayConvention() { return bdc_; } @@ -133,8 +133,8 @@ public virtual KeyValuePair convertDates(Date optionDate, Period public Date optionDateFromTenor(Period optionTenor) { return calendar().advance(referenceDate(), - optionTenor, - businessDayConvention()); + optionTenor, + businessDayConvention()); } //! return smile section @@ -142,7 +142,7 @@ public Date optionDateFromTenor(Period optionTenor) //! implements the actual volatility calculation in derived classes protected abstract double volatilityImpl(double optionTime, double bondLength, double strike); - protected virtual double volatilityImpl(Date optionDate, Period bondTenor, double strike) + protected virtual double volatilityImpl(Date optionDate, Period bondTenor, double strike) { KeyValuePair p = convertDates(optionDate, bondTenor); return volatilityImpl(p.Key, p.Value, strike); @@ -150,31 +150,31 @@ protected virtual double volatilityImpl(Date optionDate, Period bondTenor, doubl protected void checkRange(double optionTime, double bondLength, double k, bool extrapolate) { base.checkRange(optionTime, extrapolate); - Utils.QL_REQUIRE( bondLength >= 0.0, () => - "negative bondLength (" + bondLength + ") given"); + Utils.QL_REQUIRE(bondLength >= 0.0, () => + "negative bondLength (" + bondLength + ") given"); Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || - bondLength <= maxBondLength(), () => - "bondLength (" + bondLength + ") is past max curve bondLength (" - + maxBondLength() + ")"); + bondLength <= maxBondLength(), () => + "bondLength (" + bondLength + ") is past max curve bondLength (" + + maxBondLength() + ")"); Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || - ( k >= minStrike() && k <= maxStrike() ), () => - "strike (" + k + ") is outside the curve domain [" - + minStrike() + "," + maxStrike()+ "]"); + (k >= minStrike() && k <= maxStrike()), () => + "strike (" + k + ") is outside the curve domain [" + + minStrike() + "," + maxStrike() + "]"); } protected void checkRange(Date optionDate, Period bondTenor, double k, bool extrapolate) { base.checkRange(timeFromReference(optionDate), - extrapolate); - Utils.QL_REQUIRE( bondTenor.length() > 0, () => - "negative bond tenor (" + bondTenor + ") given"); + extrapolate); + Utils.QL_REQUIRE(bondTenor.length() > 0, () => + "negative bond tenor (" + bondTenor + ") given"); Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || - bondTenor <= maxBondTenor(), () => - "bond tenor (" + bondTenor + ") is past max tenor (" - + maxBondTenor() + ")"); + bondTenor <= maxBondTenor(), () => + "bond tenor (" + bondTenor + ") is past max tenor (" + + maxBondTenor() + ")"); Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || - ( k >= minStrike() && k <= maxStrike() ), () => - "strike (" + k + ") is outside the curve domain [" - + minStrike() + "," + maxStrike()+ "]"); + (k >= minStrike() && k <= maxStrike()), () => + "strike (" + k + ") is outside the curve domain [" + + minStrike() + "," + maxStrike() + "]"); } private BusinessDayConvention bdc_; diff --git a/src/QLNet/Termstructures/Volatility/CapFloor/CapFloorTermVolCurve.cs b/src/QLNet/Termstructures/Volatility/CapFloor/CapFloorTermVolCurve.cs index 7fb0735f1..05c6cb375 100644 --- a/src/QLNet/Termstructures/Volatility/CapFloor/CapFloorTermVolCurve.cs +++ b/src/QLNet/Termstructures/Volatility/CapFloor/CapFloorTermVolCurve.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -27,20 +27,20 @@ volatilities of a set of caps/floors with given length. public class CapFloorTermVolCurve : CapFloorTermVolatilityStructure { //! floating reference date, floating market data - public CapFloorTermVolCurve( int settlementDays, - Calendar calendar, - BusinessDayConvention bdc, - List optionTenors, - List > vols, - DayCounter dc = null ) // Actual365Fixed() - :base(settlementDays, calendar, bdc, dc?? new Actual365Fixed()) + public CapFloorTermVolCurve(int settlementDays, + Calendar calendar, + BusinessDayConvention bdc, + List optionTenors, + List > vols, + DayCounter dc = null) // Actual365Fixed() + : base(settlementDays, calendar, bdc, dc ?? new Actual365Fixed()) { nOptionTenors_ = optionTenors.Count; optionTenors_ = optionTenors; optionDates_ = new InitializedList(nOptionTenors_); optionTimes_ = new InitializedList(nOptionTenors_); volHandles_ = vols; - vols_ = new InitializedList( vols.Count); // do not initialize with nOptionTenors_ + vols_ = new InitializedList(vols.Count); // do not initialize with nOptionTenors_ checkInputs(); initializeOptionDatesAndTimes(); @@ -49,20 +49,20 @@ public CapFloorTermVolCurve( int settlementDays, } //! fixed reference date, floating market data - public CapFloorTermVolCurve( Date settlementDate, - Calendar calendar, - BusinessDayConvention bdc, - List optionTenors, - List > vols, - DayCounter dc = null ) // Actual365Fixed() - :base(settlementDate, calendar, bdc, dc?? new Actual365Fixed()) + public CapFloorTermVolCurve(Date settlementDate, + Calendar calendar, + BusinessDayConvention bdc, + List optionTenors, + List > vols, + DayCounter dc = null) // Actual365Fixed() + : base(settlementDate, calendar, bdc, dc ?? new Actual365Fixed()) { nOptionTenors_ = optionTenors.Count; optionTenors_ = optionTenors; - optionDates_ = new InitializedList( nOptionTenors_ ); - optionTimes_ = new InitializedList( nOptionTenors_ ); + optionDates_ = new InitializedList(nOptionTenors_); + optionTimes_ = new InitializedList(nOptionTenors_); volHandles_ = vols; - vols_ = new InitializedList( vols.Count ); // do not initialize with nOptionTenors_ + vols_ = new InitializedList(vols.Count); // do not initialize with nOptionTenors_ checkInputs(); initializeOptionDatesAndTimes(); @@ -70,57 +70,57 @@ public CapFloorTermVolCurve( Date settlementDate, interpolate(); } //! fixed reference date, fixed market data - public CapFloorTermVolCurve( Date settlementDate, - Calendar calendar, - BusinessDayConvention bdc, - List optionTenors, - List vols, - DayCounter dc = null ) // Actual365Fixed() - :base(settlementDate, calendar, bdc, dc??new Actual365Fixed()) + public CapFloorTermVolCurve(Date settlementDate, + Calendar calendar, + BusinessDayConvention bdc, + List optionTenors, + List vols, + DayCounter dc = null) // Actual365Fixed() + : base(settlementDate, calendar, bdc, dc ?? new Actual365Fixed()) { nOptionTenors_ = optionTenors.Count; optionTenors_ = optionTenors; - optionDates_ = new InitializedList( nOptionTenors_ ); - optionTimes_ = new InitializedList( nOptionTenors_ ); + optionDates_ = new InitializedList(nOptionTenors_); + optionTimes_ = new InitializedList(nOptionTenors_); volHandles_ = new InitializedList>(vols.Count); vols_ = vols; // do not initialize with nOptionTenors_ checkInputs(); initializeOptionDatesAndTimes(); // fill dummy handles to allow generic handle-based computations later - for (int i=0; i(new SimpleQuote(vols_[i])); interpolate(); } //! floating reference date, fixed market data - public CapFloorTermVolCurve( int settlementDays, - Calendar calendar, - BusinessDayConvention bdc, - List optionTenors, - List vols, - DayCounter dc = null) // Actual365Fixed() - :base(settlementDays, calendar, bdc, dc??new Actual365Fixed()) + public CapFloorTermVolCurve(int settlementDays, + Calendar calendar, + BusinessDayConvention bdc, + List optionTenors, + List vols, + DayCounter dc = null) // Actual365Fixed() + : base(settlementDays, calendar, bdc, dc ?? new Actual365Fixed()) { nOptionTenors_ = optionTenors.Count; optionTenors_ = optionTenors; - optionDates_ = new InitializedList( nOptionTenors_ ); - optionTimes_ = new InitializedList( nOptionTenors_ ); - volHandles_ = new InitializedList>( vols.Count ); + optionDates_ = new InitializedList(nOptionTenors_); + optionTimes_ = new InitializedList(nOptionTenors_); + volHandles_ = new InitializedList>(vols.Count); vols_ = vols; // do not initialize with nOptionTenors_ checkInputs(); initializeOptionDatesAndTimes(); // fill dummy handles to allow generic handle-based computations later - for (int i=0; i(new SimpleQuote(vols_[i])); interpolate(); - + } // TermStructure interface public override Date maxDate() { calculate(); - return optionDateFromTenor( optionTenors_.Last() ); + return optionDateFromTenor(optionTenors_.Last()); } // VolatilityTermStructure interface @@ -146,7 +146,7 @@ protected override void performCalculations() { // check if date recalculation must be called here - for ( int i = 0; i < vols_.Count; ++i ) + for (int i = 0; i < vols_.Count; ++i) vols_[i] = volHandles_[i].link.value(); interpolation_.update(); @@ -165,34 +165,34 @@ public List optionTimes() calculate(); return optionTimes_; } - - protected override double volatilityImpl(double t,double r) + + protected override double volatilityImpl(double t, double r) { calculate(); - return interpolation_.value( t, true ); + return interpolation_.value(t, true); } - + private void checkInputs() { - Utils.QL_REQUIRE(!optionTenors_.empty(),()=> "empty option tenor vector"); - Utils.QL_REQUIRE(nOptionTenors_==vols_.Count,()=> - "mismatch between number of option tenors (" + - nOptionTenors_ + ") and number of volatilities (" + - vols_.Count + ")"); - Utils.QL_REQUIRE(optionTenors_[0]> new Period(0,TimeUnit.Days),()=> - "negative first option tenor: " + optionTenors_[0]); - for (int i=1; ioptionTenors_[i-1],()=> - "non increasing option tenor: " + (i) + - " is " + optionTenors_[i-1] + ", " + - (i+1) + " is " + optionTenors_[i]); + Utils.QL_REQUIRE(!optionTenors_.empty(), () => "empty option tenor vector"); + Utils.QL_REQUIRE(nOptionTenors_ == vols_.Count, () => + "mismatch between number of option tenors (" + + nOptionTenors_ + ") and number of volatilities (" + + vols_.Count + ")"); + Utils.QL_REQUIRE(optionTenors_[0] > new Period(0, TimeUnit.Days), () => + "negative first option tenor: " + optionTenors_[0]); + for (int i = 1; i < nOptionTenors_; ++i) + Utils.QL_REQUIRE(optionTenors_[i] > optionTenors_[i - 1], () => + "non increasing option tenor: " + (i) + + " is " + optionTenors_[i - 1] + ", " + + (i + 1) + " is " + optionTenors_[i]); } private void initializeOptionDatesAndTimes() { - for ( int i = 0; i < nOptionTenors_; ++i ) + for (int i = 0; i < nOptionTenors_; ++i) { - optionDates_[i] = optionDateFromTenor( optionTenors_[i] ); - optionTimes_[i] = timeFromReference( optionDates_[i] ); + optionDates_[i] = optionDateFromTenor(optionTenors_[i]); + optionTimes_[i] = timeFromReference(optionDates_[i]); } } @@ -203,10 +203,10 @@ private void registerWithMarketData() } private void interpolate() { - interpolation_ = new CubicInterpolation( optionTimes_, optionTimes_.Count,vols_, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0 ); + interpolation_ = new CubicInterpolation(optionTimes_, optionTimes_.Count, vols_, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0); } int nOptionTenors_; diff --git a/src/QLNet/Termstructures/Volatility/CapFloor/CapFloorTermVolSurface.cs b/src/QLNet/Termstructures/Volatility/CapFloor/CapFloorTermVolSurface.cs index 360646819..554ffe4d9 100644 --- a/src/QLNet/Termstructures/Volatility/CapFloor/CapFloorTermVolSurface.cs +++ b/src/QLNet/Termstructures/Volatility/CapFloor/CapFloorTermVolSurface.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,14 +22,14 @@ namespace QLNet public class CapFloorTermVolSurface : CapFloorTermVolatilityStructure { //! floating reference date, floating market data - public CapFloorTermVolSurface( int settlementDays, - Calendar calendar, - BusinessDayConvention bdc, - List optionTenors, - List strikes, - List > > vols, - DayCounter dc = null) - :base(settlementDays, calendar, bdc, dc ?? new Actual365Fixed()) + public CapFloorTermVolSurface(int settlementDays, + Calendar calendar, + BusinessDayConvention bdc, + List optionTenors, + List strikes, + List > > vols, + DayCounter dc = null) + : base(settlementDays, calendar, bdc, dc ?? new Actual365Fixed()) { nOptionTenors_ = optionTenors.Count; optionTenors_ = optionTenors; @@ -40,111 +40,111 @@ public CapFloorTermVolSurface( int settlementDays, volHandles_ = vols; vols_ = new Matrix(vols.Count, vols[0].Count); - + checkInputs(); initializeOptionDatesAndTimes(); - for (int i=0; i - (i+1) + " row of vol handles has size " + + for (int i = 0; i < nOptionTenors_; ++i) + Utils.QL_REQUIRE(volHandles_[i].Count == nStrikes_, () => + (i + 1) + " row of vol handles has size " + volHandles_[i].Count + " instead of " + nStrikes_); registerWithMarketData(); - for (int i=0; i optionTenors, - List strikes, - List > > vols, - DayCounter dc = null) - :base(settlementDate, calendar, bdc, dc?? new Actual365Fixed()) + public CapFloorTermVolSurface(Date settlementDate, + Calendar calendar, + BusinessDayConvention bdc, + List optionTenors, + List strikes, + List > > vols, + DayCounter dc = null) + : base(settlementDate, calendar, bdc, dc ?? new Actual365Fixed()) { nOptionTenors_ = optionTenors.Count; optionTenors_ = optionTenors; - optionDates_ = new InitializedList( nOptionTenors_ ); - optionTimes_ = new InitializedList( nOptionTenors_ ); + optionDates_ = new InitializedList(nOptionTenors_); + optionTimes_ = new InitializedList(nOptionTenors_); nStrikes_ = strikes.Count; strikes_ = strikes; volHandles_ = vols; - vols_ = new Matrix( vols.Count, vols[0].Count ); + vols_ = new Matrix(vols.Count, vols[0].Count); checkInputs(); initializeOptionDatesAndTimes(); - for (int i=0; i - (i+1) + " row of vol handles has size " + volHandles_[i].Count + " instead of " + nStrikes_); + for (int i = 0; i < nOptionTenors_; ++i) + Utils.QL_REQUIRE(volHandles_[i].Count == nStrikes_, () => + (i + 1) + " row of vol handles has size " + volHandles_[i].Count + " instead of " + nStrikes_); registerWithMarketData(); - for (int i=0; i optionTenors, - List strikes, - Matrix vols, - DayCounter dc = null) - : base( settlementDate, calendar, bdc, dc ?? new Actual365Fixed() ) + public CapFloorTermVolSurface(Date settlementDate, + Calendar calendar, + BusinessDayConvention bdc, + List optionTenors, + List strikes, + Matrix vols, + DayCounter dc = null) + : base(settlementDate, calendar, bdc, dc ?? new Actual365Fixed()) { nOptionTenors_ = optionTenors.Count; optionTenors_ = optionTenors; - optionDates_ = new InitializedList( nOptionTenors_ ); - optionTimes_ = new InitializedList( nOptionTenors_ ); + optionDates_ = new InitializedList(nOptionTenors_); + optionTimes_ = new InitializedList(nOptionTenors_); nStrikes_ = strikes.Count; strikes_ = strikes; - volHandles_ = new InitializedList>>( vols.rows() ); + volHandles_ = new InitializedList>>(vols.rows()); vols_ = vols; checkInputs(); initializeOptionDatesAndTimes(); // fill dummy handles to allow generic handle-based computations later - for (int i=0; i>(nStrikes_); - for (int j=0; j(new SimpleQuote(vols_[i,j])); - } - interpolate(); + volHandles_[i] = new InitializedList>(nStrikes_); + for (int j = 0; j < nStrikes_; ++j) + volHandles_[i][j] = new Handle(new SimpleQuote(vols_[i, j])); + } + interpolate(); } //! floating reference date, fixed market data - public CapFloorTermVolSurface( int settlementDays, - Calendar calendar, - BusinessDayConvention bdc, - List optionTenors, - List strikes, - Matrix vols, - DayCounter dc = null) - : base( settlementDays, calendar, bdc, dc ?? new Actual365Fixed() ) + public CapFloorTermVolSurface(int settlementDays, + Calendar calendar, + BusinessDayConvention bdc, + List optionTenors, + List strikes, + Matrix vols, + DayCounter dc = null) + : base(settlementDays, calendar, bdc, dc ?? new Actual365Fixed()) { nOptionTenors_ = optionTenors.Count; optionTenors_ = optionTenors; - optionDates_ = new InitializedList( nOptionTenors_ ); - optionTimes_ = new InitializedList( nOptionTenors_ ); + optionDates_ = new InitializedList(nOptionTenors_); + optionTimes_ = new InitializedList(nOptionTenors_); nStrikes_ = strikes.Count; strikes_ = strikes; - volHandles_ = new InitializedList>>( vols.rows() ); + volHandles_ = new InitializedList>>(vols.rows()); vols_ = vols; checkInputs(); initializeOptionDatesAndTimes(); // fill dummy handles to allow generic handle-based computations later - for (int i=0; i>(nStrikes_); - for (int j=0; j(new SimpleQuote(vols_[i,j])); - } - interpolate(); + for (int j = 0; j < nStrikes_; ++j) + volHandles_[i][j] = new Handle(new SimpleQuote(vols_[i, j])); + } + interpolate(); } // TermStructure interface public override Date maxDate() @@ -159,35 +159,36 @@ public override Date maxDate() public override void update() { // recalculate dates if necessary... - if (moving_) { + if (moving_) + { Date d = Settings.evaluationDate() ; - if (evaluationDate_ != d) + if (evaluationDate_ != d) { evaluationDate_ = d; initializeOptionDatesAndTimes(); } - } - base.update(); + } + base.update(); } protected override void performCalculations() { // check if date recalculation must be called here - for ( int i = 0; i < nOptionTenors_; ++i ) - for ( int j = 0; j < nStrikes_; ++j ) - vols_[i,j] = volHandles_[i][j].link.value(); + for (int i = 0; i < nOptionTenors_; ++i) + for (int j = 0; j < nStrikes_; ++j) + vols_[i, j] = volHandles_[i][j].link.value(); - interpolation_.update(); + interpolation_.update(); } // some inspectors public List optionTenors() { return optionTenors_; } public List optionDates() { - // what if quotes are not available? - calculate(); - return optionDates_; + // what if quotes are not available? + calculate(); + return optionDates_; } public List optionTimes() { @@ -196,56 +197,56 @@ public List optionTimes() return optionTimes_; } public List strikes() {return strikes_;} - protected override double volatilityImpl(double t,double strike) + protected override double volatilityImpl(double t, double strike) { calculate(); return interpolation_.value(strike, t, true); } - + private void checkInputs() { - Utils.QL_REQUIRE(!optionTenors_.empty(),()=> "empty option tenor vector"); - Utils.QL_REQUIRE(nOptionTenors_==vols_.rows(),()=> + Utils.QL_REQUIRE(!optionTenors_.empty(), () => "empty option tenor vector"); + Utils.QL_REQUIRE(nOptionTenors_ == vols_.rows(), () => "mismatch between number of option tenors (" + nOptionTenors_ + ") and number of volatility rows (" + vols_.rows() + ")"); - Utils.QL_REQUIRE(optionTenors_[0]> new Period(0,TimeUnit.Days),()=> + Utils.QL_REQUIRE(optionTenors_[0] > new Period(0, TimeUnit.Days), () => "negative first option tenor: " + optionTenors_[0]); - for (int i=1; ioptionTenors_[i-1],()=> + for (int i = 1; i < nOptionTenors_; ++i) + Utils.QL_REQUIRE(optionTenors_[i] > optionTenors_[i - 1], () => "non increasing option tenor: " + i + - " is " + optionTenors_[i-1] + ", " + - (i+1) + " is " + optionTenors_[i]); + " is " + optionTenors_[i - 1] + ", " + + (i + 1) + " is " + optionTenors_[i]); - Utils.QL_REQUIRE(nStrikes_==vols_.columns(),()=> - "mismatch between strikes(" + strikes_.Count + - ") and vol columns (" + vols_.columns() + ")"); - for (int j=1; j + Utils.QL_REQUIRE(nStrikes_ == vols_.columns(), () => + "mismatch between strikes(" + strikes_.Count + + ") and vol columns (" + vols_.columns() + ")"); + for (int j = 1; j < nStrikes_; ++j) + Utils.QL_REQUIRE(strikes_[j - 1] "non increasing strikes: " + j + - " is " + strikes_[j-1] + ", " + - (j+1) + " is " + strikes_[j]); + " is " + strikes_[j - 1] + ", " + + (j + 1) + " is " + strikes_[j]); } private void initializeOptionDatesAndTimes() { - for ( int i = 0; i < nOptionTenors_; ++i ) + for (int i = 0; i < nOptionTenors_; ++i) { - optionDates_[i] = optionDateFromTenor( optionTenors_[i] ); - optionTimes_[i] = timeFromReference( optionDates_[i] ); + optionDates_[i] = optionDateFromTenor(optionTenors_[i]); + optionTimes_[i] = timeFromReference(optionDates_[i]); } } private void registerWithMarketData() { - for ( int i = 0; i < nOptionTenors_; ++i ) - for ( int j = 0; j < nStrikes_; ++j ) + for (int i = 0; i < nOptionTenors_; ++i) + for (int j = 0; j < nStrikes_; ++j) volHandles_[i][j] .registerWith(update); } private void interpolate() { - interpolation_ = new BicubicSpline( strikes_,strikes_.Count,optionTimes_, optionTimes_.Count, vols_ ); + interpolation_ = new BicubicSpline(strikes_, strikes_.Count, optionTimes_, optionTimes_.Count, vols_); } - + private int nOptionTenors_; private List optionTenors_; private List optionDates_; diff --git a/src/QLNet/Termstructures/Volatility/CapFloor/CapFloorTermVolatilityStructure.cs b/src/QLNet/Termstructures/Volatility/CapFloor/CapFloorTermVolatilityStructure.cs index 94eabc717..2fdc80aea 100644 --- a/src/QLNet/Termstructures/Volatility/CapFloor/CapFloorTermVolatilityStructure.cs +++ b/src/QLNet/Termstructures/Volatility/CapFloor/CapFloorTermVolatilityStructure.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,7 +23,7 @@ namespace QLNet /*! This class is purely abstract and defines the interface of concrete structures which will be derived from this one. */ - public abstract class CapFloorTermVolatilityStructure : VolatilityTermStructure + public abstract class CapFloorTermVolatilityStructure : VolatilityTermStructure { #region Constructors /*! \warning term structures initialized by means of this @@ -32,18 +32,18 @@ by overriding the referenceDate() method. */ protected CapFloorTermVolatilityStructure(BusinessDayConvention bdc, DayCounter dc = null) - :base(bdc, dc) {} - + : base(bdc, dc) {} + //! initialize with a fixed reference date - protected CapFloorTermVolatilityStructure(Date referenceDate,Calendar cal,BusinessDayConvention bdc,DayCounter dc = null) + protected CapFloorTermVolatilityStructure(Date referenceDate, Calendar cal, BusinessDayConvention bdc, DayCounter dc = null) : base(referenceDate, cal, bdc, dc) {} - + //! calculate the reference date based on the global evaluation date protected CapFloorTermVolatilityStructure(int settlementDays, Calendar cal, BusinessDayConvention bdc, DayCounter dc = null) : base(settlementDays, cal, bdc, dc) {} - + #endregion - + #region Volatility //! returns the volatility for a given cap/floor length and strike rate @@ -59,7 +59,7 @@ public double volatility(Date end, double strike, bool extrapolate = false) double t = timeFromReference(end); return volatility(t, strike, extrapolate); } - + //! returns the volatility for a given end time and strike rate public double volatility(double t, double strike, bool extrapolate = false) { @@ -69,7 +69,7 @@ public double volatility(double t, double strike, bool extrapolate = false) } #endregion - + //! implements the actual volatility calculation in derived classes protected abstract double volatilityImpl(double length, double strike); } diff --git a/src/QLNet/Termstructures/Volatility/CapFloor/ConstantCapFloorTermVolatility.cs b/src/QLNet/Termstructures/Volatility/CapFloor/ConstantCapFloorTermVolatility.cs index 2e82fd8e8..91a151daf 100644 --- a/src/QLNet/Termstructures/Volatility/CapFloor/ConstantCapFloorTermVolatility.cs +++ b/src/QLNet/Termstructures/Volatility/CapFloor/ConstantCapFloorTermVolatility.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Andrea Maggiulli - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -69,14 +69,14 @@ public ConstantCapFloorTermVolatility(Date referenceDate, { volatility_ = new Handle(new SimpleQuote(volatility)); } - + #region TermStructure interface public override Date maxDate() { return Date.maxDate(); } - + #endregion diff --git a/src/QLNet/Termstructures/Volatility/FlatSmileSection.cs b/src/QLNet/Termstructures/Volatility/FlatSmileSection.cs index 89c80983c..e2dc96954 100644 --- a/src/QLNet/Termstructures/Volatility/FlatSmileSection.cs +++ b/src/QLNet/Termstructures/Volatility/FlatSmileSection.cs @@ -1,57 +1,63 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { - public class FlatSmileSection : SmileSection { - private double vol_; - private double? atmLevel_; - public override double? atmLevel() - { - return atmLevel_; - } - - public FlatSmileSection(Date d, double vol, DayCounter dc, Date referenceDate = null, double? atmLevel = null, - VolatilityType type = VolatilityType.ShiftedLognormal, double shift = 0.0) - : base(d, dc, referenceDate, type, shift) { - vol_ = vol; - atmLevel_ = atmLevel; - } - - public FlatSmileSection(double exerciseTime, double vol, DayCounter dc, double? atmLevel = null, - VolatilityType type = VolatilityType.ShiftedLognormal, double shift = 0.0) - : base(exerciseTime, dc, type, shift) - { - vol_ = vol; - atmLevel_ = atmLevel; - } - - public override double minStrike () { - return double.MinValue - shift(); - } - - public override double maxStrike () { - return double.MaxValue; - } - - protected override double volatilityImpl(double d) { - return vol_; - } - } +namespace QLNet +{ + public class FlatSmileSection : SmileSection + { + private double vol_; + private double? atmLevel_; + public override double? atmLevel() + { + return atmLevel_; + } + + public FlatSmileSection(Date d, double vol, DayCounter dc, Date referenceDate = null, double? atmLevel = null, + VolatilityType type = VolatilityType.ShiftedLognormal, double shift = 0.0) + : base(d, dc, referenceDate, type, shift) + { + vol_ = vol; + atmLevel_ = atmLevel; + } + + public FlatSmileSection(double exerciseTime, double vol, DayCounter dc, double? atmLevel = null, + VolatilityType type = VolatilityType.ShiftedLognormal, double shift = 0.0) + : base(exerciseTime, dc, type, shift) + { + vol_ = vol; + atmLevel_ = atmLevel; + } + + public override double minStrike() + { + return double.MinValue - shift(); + } + + public override double maxStrike() + { + return double.MaxValue; + } + + protected override double volatilityImpl(double d) + { + return vol_; + } + } } diff --git a/src/QLNet/Termstructures/Volatility/Inflation/CPIVolatilitySurface.cs b/src/QLNet/Termstructures/Volatility/Inflation/CPIVolatilitySurface.cs index 3ed535094..34cc44d76 100644 --- a/src/QLNet/Termstructures/Volatility/Inflation/CPIVolatilitySurface.cs +++ b/src/QLNet/Termstructures/Volatility/Inflation/CPIVolatilitySurface.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,211 +21,215 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! zero inflation (i.e. CPI/RPI/HICP/etc.) volatility structures - /*! Abstract interface. CPI volatility is always with respect to - some base date. Also deal with lagged observations of an index - with a (usually different) availability lag. - */ - public abstract class CPIVolatilitySurface : VolatilityTermStructure - { - /*! calculates the reference date based on the global - evaluation date. - */ - - protected CPIVolatilitySurface(int settlementDays, - Calendar cal, - BusinessDayConvention bdc, - DayCounter dc, - Period observationLag, - Frequency frequency, - bool indexIsInterpolated) - :base(settlementDays, cal, bdc, dc) - { - baseLevel_ = null; - observationLag_ = observationLag; - frequency_ = frequency; - indexIsInterpolated_ = indexIsInterpolated; - - } - - // Volatility - /*! by default, inflation is observed with the lag - of the term structure. - - Because inflation is highly linked to dates (for - interpolation, periods, etc) time-based overload of the - methods are not provided. - */ - - //! Returns the volatility for a given maturity date and strike rate. - double volatility(Date maturityDate, double strike, - Period obsLag = null, - bool extrapolate = false) - { - if (obsLag == null) - obsLag = new Period(-1, TimeUnit.Days); - - Period useLag = obsLag; - if (obsLag == new Period(-1, TimeUnit.Days)) - { - useLag = observationLag(); - } - - if (indexIsInterpolated()) - { - checkRange(maturityDate - useLag, strike, extrapolate); - double t = timeFromReference(maturityDate - useLag); - return volatilityImpl(t, strike); - } - else - { - KeyValuePair dd = Utils.inflationPeriod(maturityDate - useLag, frequency()); - checkRange(dd.Key, strike, extrapolate); - double t = timeFromReference(dd.Key); - return volatilityImpl(t, strike); - } - } - - //! returns the volatility for a given option tenor and strike rate - public double? volatility(Period optionTenor, double strike, - Period obsLag = null, bool extrapolate = false) - { - if (obsLag == null) obsLag = new Period(-1, TimeUnit.Days); - - Date maturityDate = optionDateFromTenor(optionTenor); - return volatility(maturityDate, strike, obsLag, extrapolate); - } - - //! Returns the total integrated variance for a given exercise - //! date and strike rate. - /*! Total integrated variance is useful because it scales out - t for the optionlet pricing formulae. Note that it is - called "total" because the surface does not know whether - it represents Black, Bachelier or Displaced Diffusion - variance. These are virtual so alternate connections - between const vol and total var are possible. - */ - public virtual double totalVariance(Date exerciseDate, - double strike, - Period obsLag = null, - bool extrapolate = false) - { - if (obsLag == null) obsLag = new Period(-1, TimeUnit.Days); - - double vol = volatility(exerciseDate, strike, obsLag, extrapolate); - double t = timeFromBase(exerciseDate, obsLag); - return vol * vol * t; - } - - //! returns the total integrated variance for a given option - //! tenor and strike rate. - public virtual double? totalVariance(Period optionTenor, - double strike, - Period obsLag = null, - bool extrapolate = false) - { - if (obsLag == null) obsLag = new Period(-1, TimeUnit.Days); - - Date maturityDate = optionDateFromTenor(optionTenor); - return totalVariance(maturityDate, strike, obsLag, extrapolate); - } - - // Inspectors - /*! The term structure observes with a lag that is usually - different from the availability lag of the index. An - inflation rate is given, by default, for the maturity - requested assuming this lag. - */ - public virtual Period observationLag() { return observationLag_; } - public virtual Frequency frequency() { return frequency_; } - public virtual bool indexIsInterpolated() { return indexIsInterpolated_;} - public virtual Date baseDate() - { - // Depends on interpolation, or not, of observed index - // and observation lag with which it was built. - // We want this to work even if the index does not - // have a term structure. - if (indexIsInterpolated()) - { - return referenceDate() - observationLag(); - } - else - { - return Utils.inflationPeriod(referenceDate() - observationLag(), - frequency()).Key; - } - } - //! base date will be in the past because of observation lag - public virtual double timeFromBase(Date maturityDate, Period obsLag = null) - { - if (obsLag == null) obsLag = new Period(-1, TimeUnit.Days); - - Period useLag = obsLag; - - if (obsLag== new Period(-1,TimeUnit.Days)) - { - useLag = observationLag(); - } - - Date useDate; - if (indexIsInterpolated()) - { - useDate = maturityDate - useLag; - } - else - { - useDate = Utils.inflationPeriod(maturityDate - useLag, frequency()).Key; - } - - // This assumes that the inflation term structure starts - // as late as possible given the inflation index definition, - // which is the usual case. - return dayCounter().yearFraction(baseDate(), useDate); - } - - // acts as zero time value for boostrapping - public virtual double? baseLevel() - { - Utils.QL_REQUIRE(baseLevel_ != null ,()=> "Base volatility, for baseDate(), not set."); - return baseLevel_; - } - - protected virtual void checkRange(Date d, double strike, bool extrapolate) - { - Utils.QL_REQUIRE( d >= baseDate(), () => - "date (" + d + ") is before base date"); - Utils.QL_REQUIRE( extrapolate || allowsExtrapolation() || d <= maxDate(), () => - "date (" + d + ") is past max curve date (" - + maxDate() + ")"); - Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || - ( strike >= minStrike() && strike <= maxStrike() ), () => - "strike (" + strike + ") is outside the curve domain [" - + minStrike() + "," + maxStrike() + "]] at date = " + d); - } - - protected virtual void checkRange(double t, double strike, bool extrapolate) - { - Utils.QL_REQUIRE( t >= timeFromReference( baseDate() ), () => - "time (" + t + ") is before base date"); - Utils.QL_REQUIRE( extrapolate || allowsExtrapolation() || t <= maxTime(), () => - "time (" + t + ") is past max curve time (" - + maxTime() + ")"); - Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || - ( strike >= minStrike() && strike <= maxStrike() ), () => - "strike (" + strike + ") is outside the curve domain [" - + minStrike() + "," + maxStrike() + "] at time = " + t); - } - - /*! Implements the actual volatility surface calculation in - derived classes e.g. bilinear interpolation. N.B. does - not derive the surface. - */ - protected abstract double volatilityImpl(double length, double strike); - - protected double? baseLevel_; - // so you do not need an index - protected Period observationLag_; - protected Frequency frequency_; - protected bool indexIsInterpolated_; - } + //! zero inflation (i.e. CPI/RPI/HICP/etc.) volatility structures + /*! Abstract interface. CPI volatility is always with respect to + some base date. Also deal with lagged observations of an index + with a (usually different) availability lag. + */ + public abstract class CPIVolatilitySurface : VolatilityTermStructure + { + /*! calculates the reference date based on the global + evaluation date. + */ + + protected CPIVolatilitySurface(int settlementDays, + Calendar cal, + BusinessDayConvention bdc, + DayCounter dc, + Period observationLag, + Frequency frequency, + bool indexIsInterpolated) + : base(settlementDays, cal, bdc, dc) + { + baseLevel_ = null; + observationLag_ = observationLag; + frequency_ = frequency; + indexIsInterpolated_ = indexIsInterpolated; + + } + + // Volatility + /*! by default, inflation is observed with the lag + of the term structure. + + Because inflation is highly linked to dates (for + interpolation, periods, etc) time-based overload of the + methods are not provided. + */ + + //! Returns the volatility for a given maturity date and strike rate. + double volatility(Date maturityDate, double strike, + Period obsLag = null, + bool extrapolate = false) + { + if (obsLag == null) + obsLag = new Period(-1, TimeUnit.Days); + + Period useLag = obsLag; + if (obsLag == new Period(-1, TimeUnit.Days)) + { + useLag = observationLag(); + } + + if (indexIsInterpolated()) + { + checkRange(maturityDate - useLag, strike, extrapolate); + double t = timeFromReference(maturityDate - useLag); + return volatilityImpl(t, strike); + } + else + { + KeyValuePair dd = Utils.inflationPeriod(maturityDate - useLag, frequency()); + checkRange(dd.Key, strike, extrapolate); + double t = timeFromReference(dd.Key); + return volatilityImpl(t, strike); + } + } + + //! returns the volatility for a given option tenor and strike rate + public double? volatility(Period optionTenor, double strike, + Period obsLag = null, bool extrapolate = false) + { + if (obsLag == null) + obsLag = new Period(-1, TimeUnit.Days); + + Date maturityDate = optionDateFromTenor(optionTenor); + return volatility(maturityDate, strike, obsLag, extrapolate); + } + + //! Returns the total integrated variance for a given exercise + //! date and strike rate. + /*! Total integrated variance is useful because it scales out + t for the optionlet pricing formulae. Note that it is + called "total" because the surface does not know whether + it represents Black, Bachelier or Displaced Diffusion + variance. These are virtual so alternate connections + between const vol and total var are possible. + */ + public virtual double totalVariance(Date exerciseDate, + double strike, + Period obsLag = null, + bool extrapolate = false) + { + if (obsLag == null) + obsLag = new Period(-1, TimeUnit.Days); + + double vol = volatility(exerciseDate, strike, obsLag, extrapolate); + double t = timeFromBase(exerciseDate, obsLag); + return vol * vol * t; + } + + //! returns the total integrated variance for a given option + //! tenor and strike rate. + public virtual double? totalVariance(Period optionTenor, + double strike, + Period obsLag = null, + bool extrapolate = false) + { + if (obsLag == null) + obsLag = new Period(-1, TimeUnit.Days); + + Date maturityDate = optionDateFromTenor(optionTenor); + return totalVariance(maturityDate, strike, obsLag, extrapolate); + } + + // Inspectors + /*! The term structure observes with a lag that is usually + different from the availability lag of the index. An + inflation rate is given, by default, for the maturity + requested assuming this lag. + */ + public virtual Period observationLag() { return observationLag_; } + public virtual Frequency frequency() { return frequency_; } + public virtual bool indexIsInterpolated() { return indexIsInterpolated_;} + public virtual Date baseDate() + { + // Depends on interpolation, or not, of observed index + // and observation lag with which it was built. + // We want this to work even if the index does not + // have a term structure. + if (indexIsInterpolated()) + { + return referenceDate() - observationLag(); + } + else + { + return Utils.inflationPeriod(referenceDate() - observationLag(), + frequency()).Key; + } + } + //! base date will be in the past because of observation lag + public virtual double timeFromBase(Date maturityDate, Period obsLag = null) + { + if (obsLag == null) + obsLag = new Period(-1, TimeUnit.Days); + + Period useLag = obsLag; + + if (obsLag == new Period(-1, TimeUnit.Days)) + { + useLag = observationLag(); + } + + Date useDate; + if (indexIsInterpolated()) + { + useDate = maturityDate - useLag; + } + else + { + useDate = Utils.inflationPeriod(maturityDate - useLag, frequency()).Key; + } + + // This assumes that the inflation term structure starts + // as late as possible given the inflation index definition, + // which is the usual case. + return dayCounter().yearFraction(baseDate(), useDate); + } + + // acts as zero time value for boostrapping + public virtual double? baseLevel() + { + Utils.QL_REQUIRE(baseLevel_ != null, () => "Base volatility, for baseDate(), not set."); + return baseLevel_; + } + + protected virtual void checkRange(Date d, double strike, bool extrapolate) + { + Utils.QL_REQUIRE(d >= baseDate(), () => + "date (" + d + ") is before base date"); + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || d <= maxDate(), () => + "date (" + d + ") is past max curve date (" + + maxDate() + ")"); + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || + (strike >= minStrike() && strike <= maxStrike()), () => + "strike (" + strike + ") is outside the curve domain [" + + minStrike() + "," + maxStrike() + "]] at date = " + d); + } + + protected virtual void checkRange(double t, double strike, bool extrapolate) + { + Utils.QL_REQUIRE(t >= timeFromReference(baseDate()), () => + "time (" + t + ") is before base date"); + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || t <= maxTime(), () => + "time (" + t + ") is past max curve time (" + + maxTime() + ")"); + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || + (strike >= minStrike() && strike <= maxStrike()), () => + "strike (" + strike + ") is outside the curve domain [" + + minStrike() + "," + maxStrike() + "] at time = " + t); + } + + /*! Implements the actual volatility surface calculation in + derived classes e.g. bilinear interpolation. N.B. does + not derive the surface. + */ + protected abstract double volatilityImpl(double length, double strike); + + protected double? baseLevel_; + // so you do not need an index + protected Period observationLag_; + protected Frequency frequency_; + protected bool indexIsInterpolated_; + } } diff --git a/src/QLNet/Termstructures/Volatility/Inflation/yoyinflationoptionletvolatilitystructure.cs b/src/QLNet/Termstructures/Volatility/Inflation/YoYInflationOptionletVolatilityStructure.cs similarity index 60% rename from src/QLNet/Termstructures/Volatility/Inflation/yoyinflationoptionletvolatilitystructure.cs rename to src/QLNet/Termstructures/Volatility/Inflation/YoYInflationOptionletVolatilityStructure.cs index 2e2777f1e..8505a2cbc 100644 --- a/src/QLNet/Termstructures/Volatility/Inflation/yoyinflationoptionletvolatilitystructure.cs +++ b/src/QLNet/Termstructures/Volatility/Inflation/YoYInflationOptionletVolatilityStructure.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,17 +29,17 @@ totalVariance. Also deal with lagged observations of an index with a (usually different) availability lag. */ - public abstract class YoYOptionletVolatilitySurface : VolatilityTermStructure + public abstract class YoYOptionletVolatilitySurface : VolatilityTermStructure { // Constructor //! calculate the reference date based on the global evaluation date protected YoYOptionletVolatilitySurface(int settlementDays, - Calendar cal, - BusinessDayConvention bdc, - DayCounter dc, - Period observationLag, - Frequency frequency, - bool indexIsInterpolated) + Calendar cal, + BusinessDayConvention bdc, + DayCounter dc, + Period observationLag, + Frequency frequency, + bool indexIsInterpolated) : base(settlementDays, cal, bdc, dc) { baseLevel_ = null; @@ -60,38 +60,38 @@ public double volatility(Date maturityDate, double strike) { return volatility(maturityDate, strike, new Period(-1, TimeUnit.Days), false); } - public double volatility(Date maturityDate, double strike, Period obsLag) + public double volatility(Date maturityDate, double strike, Period obsLag) { - return volatility(maturityDate,strike,obsLag,false) ; + return volatility(maturityDate, strike, obsLag, false) ; } - public double volatility(Date maturityDate,double strike,Period obsLag, bool extrapolate) + public double volatility(Date maturityDate, double strike, Period obsLag, bool extrapolate) { Period useLag = obsLag; - if (obsLag == new Period(-1,TimeUnit.Days)) + if (obsLag == new Period(-1, TimeUnit.Days)) { useLag = observationLag(); } - if (indexIsInterpolated()) - { - checkRange(maturityDate-useLag, strike, extrapolate); - double t = timeFromReference(maturityDate-useLag); - return volatilityImpl(t,strike); - } - else - { - KeyValuePair dd = Utils.inflationPeriod(maturityDate-useLag, frequency()); + if (indexIsInterpolated()) + { + checkRange(maturityDate - useLag, strike, extrapolate); + double t = timeFromReference(maturityDate - useLag); + return volatilityImpl(t, strike); + } + else + { + KeyValuePair dd = Utils.inflationPeriod(maturityDate - useLag, frequency()); checkRange(dd.Key, strike, extrapolate); double t = timeFromReference(dd.Key); - return volatilityImpl(t,strike); - } + return volatilityImpl(t, strike); + } } public double volatility(Period optionTenor, double strike) { Date maturityDate = optionDateFromTenor(optionTenor); - return volatility(maturityDate, strike, new Period(-1,TimeUnit.Days), false); + return volatility(maturityDate, strike, new Period(-1, TimeUnit.Days), false); } public double volatility(Period optionTenor, double strike, Period obsLag) @@ -100,7 +100,7 @@ public double volatility(Period optionTenor, double strike, Period obsLag) return volatility(maturityDate, strike, obsLag, false); } - public double volatility(Period optionTenor,double strike,Period obsLag,bool extrapolate) + public double volatility(Period optionTenor, double strike, Period obsLag, bool extrapolate) { Date maturityDate = optionDateFromTenor(optionTenor); return volatility(maturityDate, strike, obsLag, extrapolate); @@ -135,7 +135,7 @@ public virtual double totalVariance(Date maturityDate, double strike, Period obs public virtual double totalVariance(Period tenor, double strike) { Date maturityDate = optionDateFromTenor(tenor); - return totalVariance(maturityDate, strike, new Period(-1,TimeUnit.Days), false); + return totalVariance(maturityDate, strike, new Period(-1, TimeUnit.Days), false); } public virtual double totalVariance(Period tenor, double strike, Period obsLag) { @@ -154,19 +154,19 @@ public virtual double totalVariance(Period tenor, double strike, Period obsLag, public virtual Period observationLag() { return observationLag_; } public virtual Frequency frequency() { return frequency_; } public virtual bool indexIsInterpolated() { return indexIsInterpolated_; } - - public virtual Date baseDate() + + public virtual Date baseDate() { // Depends on interpolation, or not, of observed index // and observation lag with which it was built. // We want this to work even if the index does not // have a yoy term structure. - if (indexIsInterpolated()) + if (indexIsInterpolated()) { return referenceDate() - observationLag(); - } - else + } + else { return Utils.inflationPeriod(referenceDate() - observationLag(), frequency()).Key; @@ -180,23 +180,23 @@ public virtual double timeFromBase(Date maturityDate) } //! needed for total variance calculations - public virtual double timeFromBase(Date maturityDate,Period obsLag) + public virtual double timeFromBase(Date maturityDate, Period obsLag) { Period useLag = obsLag; - if (obsLag==new Period(-1,TimeUnit.Days)) + if (obsLag == new Period(-1, TimeUnit.Days)) { - useLag = observationLag(); + useLag = observationLag(); } Date useDate; - if (indexIsInterpolated()) + if (indexIsInterpolated()) { - useDate = maturityDate - useLag; - } - else + useDate = maturityDate - useLag; + } + else { - useDate = Utils.inflationPeriod(maturityDate - useLag,frequency()).Key; + useDate = Utils.inflationPeriod(maturityDate - useLag, frequency()).Key; } // This assumes that the inflation term structure starts @@ -204,38 +204,38 @@ public virtual double timeFromBase(Date maturityDate,Period obsLag) // which is the usual case. return dayCounter().yearFraction(baseDate(), useDate); } - + // acts as zero time value for boostrapping - public virtual double baseLevel() + public virtual double baseLevel() { - Utils.QL_REQUIRE(baseLevel_ != null,()=> "Base volatility, for baseDate(), not set."); + Utils.QL_REQUIRE(baseLevel_ != null, () => "Base volatility, for baseDate(), not set."); return baseLevel_.Value; } - protected virtual void checkRange(Date d, double strike,bool extrapolate) + protected virtual void checkRange(Date d, double strike, bool extrapolate) { - Utils.QL_REQUIRE( d >= baseDate(),()=> "date (" + d + ") is before base date"); + Utils.QL_REQUIRE(d >= baseDate(), () => "date (" + d + ") is before base date"); - Utils.QL_REQUIRE( extrapolate || allowsExtrapolation() || d <= maxDate(),()=> - "date (" + d + ") is past max curve date (" + maxDate() + ")"); + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || d <= maxDate(), () => + "date (" + d + ") is past max curve date (" + maxDate() + ")"); - Utils.QL_REQUIRE( extrapolate || allowsExtrapolation() || ( strike >= minStrike() && strike <= maxStrike()),()=> - "strike (" + strike + ") is outside the curve domain [" + minStrike() + "," + maxStrike()+ "]] at date = " + d); + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || (strike >= minStrike() && strike <= maxStrike()), () => + "strike (" + strike + ") is outside the curve domain [" + minStrike() + "," + maxStrike() + "]] at date = " + d); } - - protected virtual void checkRange(double t, double strike,bool extrapolate) + + protected virtual void checkRange(double t, double strike, bool extrapolate) { - Utils.QL_REQUIRE( t >= timeFromReference(baseDate()),()=> "time (" + t + ") is before base date"); + Utils.QL_REQUIRE(t >= timeFromReference(baseDate()), () => "time (" + t + ") is before base date"); + + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || t <= maxTime(), () => + "time (" + t + ") is past max curve time (" + maxTime() + ")"); - Utils.QL_REQUIRE( extrapolate || allowsExtrapolation() || t <= maxTime(),()=> - "time (" + t + ") is past max curve time (" + maxTime() + ")"); + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || (strike >= minStrike() && strike <= maxStrike()), () => + "strike (" + strike + ") is outside the curve domain [" + minStrike() + "," + maxStrike() + "] at time = " + t); - Utils.QL_REQUIRE( extrapolate || allowsExtrapolation() || (strike >= minStrike() && strike <= maxStrike()),()=> - "strike (" + strike + ") is outside the curve domain [" + minStrike() + "," + maxStrike()+ "] at time = " + t); - } @@ -255,44 +255,44 @@ protected virtual void checkRange(double t, double strike,bool extrapolate) protected bool indexIsInterpolated_; } - //! Constant surface, no K or T dependence. - public class ConstantYoYOptionletVolatility : YoYOptionletVolatilitySurface - { - - // Constructor - //! calculate the reference date based on the global evaluation date - public ConstantYoYOptionletVolatility(double v, - int settlementDays, - Calendar cal, - BusinessDayConvention bdc, - DayCounter dc, - Period observationLag, - Frequency frequency, - bool indexIsInterpolated, - double minStrike = -1.0, // -100% - double maxStrike = 100.0) // +10,000% - :base(settlementDays, cal, bdc, dc, observationLag, frequency, indexIsInterpolated) - { - volatility_ = v; - minStrike_ = minStrike; - maxStrike_ = maxStrike; - } - - // Limits - public override Date maxDate() { return Date.maxDate(); } - //! the minimum strike for which the term structure can return vols - public override double minStrike() { return minStrike_; } - //! the maximum strike for which the term structure can return vols - public override double maxStrike() { return maxStrike_; } - - //! implements the actual volatility calculation in derived classes - protected override double volatilityImpl( double length, double strike ) - { - return volatility_; - } - - protected double volatility_; - protected double minStrike_, maxStrike_; - } + //! Constant surface, no K or T dependence. + public class ConstantYoYOptionletVolatility : YoYOptionletVolatilitySurface + { + + // Constructor + //! calculate the reference date based on the global evaluation date + public ConstantYoYOptionletVolatility(double v, + int settlementDays, + Calendar cal, + BusinessDayConvention bdc, + DayCounter dc, + Period observationLag, + Frequency frequency, + bool indexIsInterpolated, + double minStrike = -1.0, // -100% + double maxStrike = 100.0) // +10,000% + : base(settlementDays, cal, bdc, dc, observationLag, frequency, indexIsInterpolated) + { + volatility_ = v; + minStrike_ = minStrike; + maxStrike_ = maxStrike; + } + + // Limits + public override Date maxDate() { return Date.maxDate(); } + //! the minimum strike for which the term structure can return vols + public override double minStrike() { return minStrike_; } + //! the maximum strike for which the term structure can return vols + public override double maxStrike() { return maxStrike_; } + + //! implements the actual volatility calculation in derived classes + protected override double volatilityImpl(double length, double strike) + { + return volatility_; + } + + protected double volatility_; + protected double minStrike_, maxStrike_; + } } diff --git a/src/QLNet/Termstructures/Volatility/InterpolatedSmileSection.cs b/src/QLNet/Termstructures/Volatility/InterpolatedSmileSection.cs index 7e7c94afd..e93b9f643 100644 --- a/src/QLNet/Termstructures/Volatility/InterpolatedSmileSection.cs +++ b/src/QLNet/Termstructures/Volatility/InterpolatedSmileSection.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,17 +21,17 @@ namespace QLNet { public class InterpolatedSmileSection : SmileSection, InterpolatedCurve - where Interpolator : IInterpolationFactory, new() + where Interpolator : IInterpolationFactory, new () { - public InterpolatedSmileSection( double timeToExpiry, - List strikes, - List> stdDevHandles, - Handle atmLevel, - Interpolator interpolator = default(Interpolator), - DayCounter dc = null, //Actual365Fixed() - VolatilityType type = VolatilityType.ShiftedLognormal, - double shift = 0.0) - : base( timeToExpiry, dc ?? new Actual365Fixed(), type, shift ) + public InterpolatedSmileSection(double timeToExpiry, + List strikes, + List> stdDevHandles, + Handle atmLevel, + Interpolator interpolator = default(Interpolator), + DayCounter dc = null, //Actual365Fixed() + VolatilityType type = VolatilityType.ShiftedLognormal, + double shift = 0.0) + : base(timeToExpiry, dc ?? new Actual365Fixed(), type, shift) { exerciseTimeSquareRoot_ = Math.Sqrt(exerciseTime()); strikes_ = strikes; @@ -39,90 +39,100 @@ public InterpolatedSmileSection( double timeToExpiry, atmLevel_ = atmLevel; vols_ = new InitializedList(stdDevHandles.Count); - for (int i=0; i.Create(); + interpolation_ = interpolator.interpolate(strikes_, strikes_.Count, vols_); } - public InterpolatedSmileSection( double timeToExpiry, - List strikes, - List stdDevs, - double atmLevel, - Interpolator interpolator = default(Interpolator), - DayCounter dc = null , //Actual365Fixed(), - VolatilityType type = VolatilityType.ShiftedLognormal, - double shift = 0.0) - :base(timeToExpiry, dc?? new Actual365Fixed(), type, shift) + public InterpolatedSmileSection(double timeToExpiry, + List strikes, + List stdDevs, + double atmLevel, + Interpolator interpolator = default(Interpolator), + DayCounter dc = null, //Actual365Fixed(), + VolatilityType type = VolatilityType.ShiftedLognormal, + double shift = 0.0) + : base(timeToExpiry, dc ?? new Actual365Fixed(), type, shift) { exerciseTimeSquareRoot_ = Math.Sqrt(exerciseTime()); strikes_ = strikes; - stdDevHandles_ = new InitializedList>(stdDevs.Count); - vols_= new InitializedList(stdDevs.Count); - + stdDevHandles_ = new InitializedList>(stdDevs.Count); + vols_ = new InitializedList(stdDevs.Count); + // fill dummy handles to allow generic handle-based // computations later on - for (int i=0; i(new SimpleQuote(stdDevs[i])); atmLevel_ = new Handle(new SimpleQuote(atmLevel)); // check strikes!!!!!!!!!!!!!!!!!!!! - interpolation_ = interpolator.interpolate(strikes_,strikes_.Count,vols_); + if (interpolator == null) + interpolator = FastActivator.Create(); + interpolation_ = interpolator.interpolate(strikes_, strikes_.Count, vols_); } - public InterpolatedSmileSection( Date d, - List strikes, - List > stdDevHandles, - Handle atmLevel, - DayCounter dc = null , //Actual365Fixed(), - Interpolator interpolator = default(Interpolator), - Date referenceDate = null, - VolatilityType type = VolatilityType.ShiftedLognormal, - double shift = 0.0) - : base( d, dc?? new Actual365Fixed(), referenceDate, type, shift ) + public InterpolatedSmileSection(Date d, + List strikes, + List > stdDevHandles, + Handle atmLevel, + DayCounter dc = null, //Actual365Fixed(), + Interpolator interpolator = default(Interpolator), + Date referenceDate = null, + VolatilityType type = VolatilityType.ShiftedLognormal, + double shift = 0.0) + : base(d, dc ?? new Actual365Fixed(), referenceDate, type, shift) { exerciseTimeSquareRoot_ = Math.Sqrt(exerciseTime()); strikes_ = strikes; stdDevHandles_ = stdDevHandles; - atmLevel_ = atmLevel; + atmLevel_ = atmLevel; vols_ = new InitializedList(stdDevHandles.Count); - for (int i=0; i.Create(); + interpolation_ = interpolator.interpolate(strikes_, strikes_.Count, vols_); } - public InterpolatedSmileSection( Date d, - List strikes, - List stdDevs, - double atmLevel, - DayCounter dc = null , // Actual365Fixed(), - Interpolator interpolator = default(Interpolator), - Date referenceDate = null, - double shift = 0.0) - : base( d, dc?? new Actual365Fixed(), referenceDate, VolatilityType.ShiftedLognormal, shift ) - { - strikes_ = strikes; - stdDevHandles_ = new InitializedList>(stdDevs.Count); - vols_ = new InitializedList(stdDevs.Count); - - //fill dummy handles to allow generic handle-based - // computations later on - for (int i = 0; i < stdDevs.Count; ++i) - stdDevHandles_[i] = new Handle(new SimpleQuote(stdDevs[i])); - atmLevel_ = new Handle(new SimpleQuote(atmLevel)); - // check strikes!!!!!!!!!!!!!!!!!!!! - interpolation_ = interpolator.interpolate(strikes_, strikes_.Count, vols_); - } + public InterpolatedSmileSection(Date d, + List strikes, + List stdDevs, + double atmLevel, + DayCounter dc = null, // Actual365Fixed(), + Interpolator interpolator = default(Interpolator), + Date referenceDate = null, + double shift = 0.0) + : base(d, dc ?? new Actual365Fixed(), referenceDate, VolatilityType.ShiftedLognormal, shift) + { + exerciseTimeSquareRoot_ = Math.Sqrt(exerciseTime()); + strikes_ = strikes; + stdDevHandles_ = new InitializedList>(stdDevs.Count); + vols_ = new InitializedList(stdDevs.Count); + + //fill dummy handles to allow generic handle-based + // computations later on + for (int i = 0; i < stdDevs.Count; ++i) + stdDevHandles_[i] = new Handle(new SimpleQuote(stdDevs[i])); + atmLevel_ = new Handle(new SimpleQuote(atmLevel)); + // check strikes!!!!!!!!!!!!!!!!!!!! + if (interpolator == null) + interpolator = FastActivator.Create(); + + interpolation_ = interpolator.interpolate(strikes_, strikes_.Count, vols_); + } protected override void performCalculations() { for (int i = 0; i < stdDevHandles_.Count; ++i) - vols_[i] = stdDevHandles_[i].link.value()/exerciseTimeSquareRoot_; + vols_[i] = stdDevHandles_[i].link.value() / exerciseTimeSquareRoot_; interpolation_.update(); } @@ -131,7 +141,7 @@ protected override double varianceImpl(double strike) { calculate(); double v = interpolation_.value(strike, true); - return v*v*exerciseTime(); + return v * v * exerciseTime(); } protected override double volatilityImpl(double strike) @@ -139,8 +149,8 @@ protected override double volatilityImpl(double strike) calculate(); return interpolation_.value(strike, true); } - public override double minStrike () { return strikes_.First(); } - public override double maxStrike () { return strikes_.Last(); } + public override double minStrike() { return strikes_.First(); } + public override double maxStrike() { return strikes_.Last(); } public override double? atmLevel() { return atmLevel_.link.value(); } public override void update() {base.update();} @@ -160,7 +170,7 @@ protected override double volatilityImpl(double strike) public Date maxDate_ { get; set; } public Date maxDate() { - if ( maxDate_ != null ) + if (maxDate_ != null) return maxDate_; return dates_.Last(); @@ -176,20 +186,20 @@ public Date maxDate() public Dictionary nodes() { Dictionary results = new Dictionary(); - dates_.ForEach( ( i, x ) => results.Add( x, data_[i] ) ); + dates_.ForEach((i, x) => results.Add(x, data_[i])); return results; } public void setupInterpolation() { - interpolation_ = interpolator_.interpolate( times_, times_.Count, data_ ); + interpolation_ = interpolator_.interpolate(times_, times_.Count, data_); } public object Clone() { InterpolatedCurve copy = this.MemberwiseClone() as InterpolatedCurve; - copy.times_ = new List( times_ ); - copy.data_ = new List( data_ ); + copy.times_ = new List(times_); + copy.data_ = new List(data_); copy.interpolator_ = interpolator_; copy.setupInterpolation(); return copy; diff --git a/src/QLNet/Termstructures/Volatility/Optionlet/CapletVarianceCurve.cs b/src/QLNet/Termstructures/Volatility/Optionlet/CapletVarianceCurve.cs new file mode 100644 index 000000000..e8b1898e7 --- /dev/null +++ b/src/QLNet/Termstructures/Volatility/Optionlet/CapletVarianceCurve.cs @@ -0,0 +1,69 @@ +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System.Collections.Generic; + +namespace QLNet +{ + public class CapletVarianceCurve : OptionletVolatilityStructure + { + + private BlackVarianceCurve blackCurve_; + + public CapletVarianceCurve(Date referenceDate, + List dates, + List capletVolCurve, + DayCounter dayCounter) + : base(referenceDate, new Calendar(), BusinessDayConvention.Following, new DayCounter()) + { + blackCurve_ = new BlackVarianceCurve(referenceDate, dates, capletVolCurve, dayCounter, false); + } + + public override DayCounter dayCounter() + { + return blackCurve_.dayCounter(); + } + + public override Date maxDate() + { + return blackCurve_.maxDate(); + } + + public override double minStrike() + { + return blackCurve_.minStrike(); + } + + public override double maxStrike() + { + return blackCurve_.maxStrike(); + } + + protected override SmileSection smileSectionImpl(double t) + { + // dummy strike + double atmVol = blackCurve_.blackVol(t, 0.05, true); + return new FlatSmileSection(t, atmVol, dayCounter()); + } + + protected override double volatilityImpl(double t, double r) + { + return blackCurve_.blackVol(t, r, true); + } + } +} diff --git a/src/QLNet/Termstructures/Volatility/Optionlet/ConstantOptionletVolatility.cs b/src/QLNet/Termstructures/Volatility/Optionlet/ConstantOptionletVolatility.cs index d8544e84a..759676d65 100644 --- a/src/QLNet/Termstructures/Volatility/Optionlet/ConstantOptionletVolatility.cs +++ b/src/QLNet/Termstructures/Volatility/Optionlet/ConstantOptionletVolatility.cs @@ -1,77 +1,86 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { - //! Constant caplet volatility, no time-strike dependence - public class ConstantOptionletVolatility : OptionletVolatilityStructure { - private Handle volatility_; - - //! floating reference date, floating market data - public ConstantOptionletVolatility(int settlementDays, Calendar cal, BusinessDayConvention bdc, - Handle vol, DayCounter dc) - : base(settlementDays, cal, bdc, dc) { - volatility_ = vol; - - volatility_.registerWith(update); - } - - //! fixed reference date, floating market data - public ConstantOptionletVolatility(Date referenceDate, Calendar cal, BusinessDayConvention bdc, - Handle vol, DayCounter dc) - : base(referenceDate, cal, bdc, dc) { - volatility_ = vol; - - volatility_.registerWith(update); - } - - //! floating reference date, fixed market data - public ConstantOptionletVolatility(int settlementDays, Calendar cal, BusinessDayConvention bdc, - double vol, DayCounter dc) - : base(settlementDays, cal, bdc, dc) { - volatility_ = new Handle(new SimpleQuote(vol)); - } - - //! fixed reference date, fixed market data - public ConstantOptionletVolatility(Date referenceDate, Calendar cal, BusinessDayConvention bdc, - double vol, DayCounter dc) - : base(referenceDate, cal, bdc, dc) { - volatility_ = new Handle(new SimpleQuote(vol)); - } - - - public override Date maxDate() { return Date.maxDate(); } - public override double minStrike() { return double.MinValue; } - public override double maxStrike() { return double.MaxValue; } - - protected override SmileSection smileSectionImpl(Date d) { - double atmVol = volatility_.link.value(); - return new FlatSmileSection(d, atmVol, dayCounter(), referenceDate()); - } - - protected override SmileSection smileSectionImpl(double optionTime) { - double atmVol = volatility_.link.value(); - return new FlatSmileSection(optionTime, atmVol, dayCounter()); - } - - protected override double volatilityImpl(double d1, double d2) { - return volatility_.link.value(); - } - - } +namespace QLNet +{ + //! Constant caplet volatility, no time-strike dependence + public class ConstantOptionletVolatility : OptionletVolatilityStructure + { + private Handle volatility_; + + //! floating reference date, floating market data + public ConstantOptionletVolatility(int settlementDays, Calendar cal, BusinessDayConvention bdc, + Handle vol, DayCounter dc) + : base(settlementDays, cal, bdc, dc) + { + volatility_ = vol; + + volatility_.registerWith(update); + } + + //! fixed reference date, floating market data + public ConstantOptionletVolatility(Date referenceDate, Calendar cal, BusinessDayConvention bdc, + Handle vol, DayCounter dc) + : base(referenceDate, cal, bdc, dc) + { + volatility_ = vol; + + volatility_.registerWith(update); + } + + //! floating reference date, fixed market data + public ConstantOptionletVolatility(int settlementDays, Calendar cal, BusinessDayConvention bdc, + double vol, DayCounter dc) + : base(settlementDays, cal, bdc, dc) + { + volatility_ = new Handle(new SimpleQuote(vol)); + } + + //! fixed reference date, fixed market data + public ConstantOptionletVolatility(Date referenceDate, Calendar cal, BusinessDayConvention bdc, + double vol, DayCounter dc) + : base(referenceDate, cal, bdc, dc) + { + volatility_ = new Handle(new SimpleQuote(vol)); + } + + + public override Date maxDate() { return Date.maxDate(); } + public override double minStrike() { return double.MinValue; } + public override double maxStrike() { return double.MaxValue; } + + protected override SmileSection smileSectionImpl(Date d) + { + double atmVol = volatility_.link.value(); + return new FlatSmileSection(d, atmVol, dayCounter(), referenceDate()); + } + + protected override SmileSection smileSectionImpl(double optionTime) + { + double atmVol = volatility_.link.value(); + return new FlatSmileSection(optionTime, atmVol, dayCounter()); + } + + protected override double volatilityImpl(double d1, double d2) + { + return volatility_.link.value(); + } + + } } diff --git a/src/QLNet/Termstructures/Volatility/Optionlet/OptionletStripper.cs b/src/QLNet/Termstructures/Volatility/Optionlet/OptionletStripper.cs index 5c23296e1..75385e6ce 100644 --- a/src/QLNet/Termstructures/Volatility/Optionlet/OptionletStripper.cs +++ b/src/QLNet/Termstructures/Volatility/Optionlet/OptionletStripper.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,24 +22,24 @@ namespace QLNet /*! StrippedOptionletBase specialization. It's up to derived classes to implement LazyObject::performCalculations */ - public enum VolatilityType { ShiftedLognormal, Normal }; + public enum VolatilityType { ShiftedLognormal, Normal } public class OptionletStripper : StrippedOptionletBase { // StrippedOptionletBase interface public override List optionletStrikes(int i) { calculate(); - Utils.QL_REQUIRE( i < optionletStrikes_.Count,()=> - "index (" + i + ") must be less than optionletStrikes size (" + optionletStrikes_.Count + ")" ); + Utils.QL_REQUIRE(i < optionletStrikes_.Count, () => + "index (" + i + ") must be less than optionletStrikes size (" + optionletStrikes_.Count + ")"); return optionletStrikes_[i]; } public override List optionletVolatilities(int i) { calculate(); - Utils.QL_REQUIRE( i < optionletVolatilities_.Count,()=> - "index (" + i + ") must be less than optionletVolatilities size (" + - optionletVolatilities_.Count + ")" ); + Utils.QL_REQUIRE(i < optionletVolatilities_.Count, () => + "index (" + i + ") must be less than optionletVolatilities size (" + + optionletVolatilities_.Count + ")"); return optionletVolatilities_[i]; } @@ -79,66 +79,66 @@ public List optionletAccrualPeriods() } public CapFloorTermVolSurface termVolSurface() { return termVolSurface_; } public IborIndex iborIndex() { return iborIndex_; } - public override double displacement() { return displacement_; } + public override double displacement() { return displacement_; } public override VolatilityType volatilityType() { return volatilityType_; } - protected OptionletStripper( CapFloorTermVolSurface termVolSurface, IborIndex iborIndex, - Handle discount = null, - VolatilityType type = VolatilityType.ShiftedLognormal, - double displacement = 0.0) + protected OptionletStripper(CapFloorTermVolSurface termVolSurface, IborIndex iborIndex, + Handle discount = null, + VolatilityType type = VolatilityType.ShiftedLognormal, + double displacement = 0.0) { termVolSurface_ = termVolSurface; iborIndex_ = iborIndex; discount_ = discount ?? new Handle(); - nStrikes_ = termVolSurface.strikes().Count; + nStrikes_ = termVolSurface.strikes().Count; volatilityType_ = type; displacement_ = displacement; - - if (volatilityType_ == VolatilityType.Normal) + + if (volatilityType_ == VolatilityType.Normal) + { + Utils.QL_REQUIRE(displacement_.IsEqual(0.0), () => + "non-null displacement is not allowed with Normal model"); + } + + termVolSurface.registerWith(update); + iborIndex_.registerWith(update); + discount_.registerWith(update); + Settings.registerWith(update); + + Period indexTenor = iborIndex_.tenor(); + Period maxCapFloorTenor = termVolSurface.optionTenors().Last(); + + // optionlet tenors and capFloor lengths + optionletTenors_.Add(indexTenor); + capFloorLengths_.Add(optionletTenors_.Last() + indexTenor); + Utils.QL_REQUIRE(maxCapFloorTenor >= capFloorLengths_.Last(), () => + "too short (" + maxCapFloorTenor + ") capfloor term vol termVolSurface"); + Period nextCapFloorLength = capFloorLengths_.Last() + indexTenor; + while (nextCapFloorLength <= maxCapFloorTenor) + { + optionletTenors_.Add(capFloorLengths_.Last()); + capFloorLengths_.Add(nextCapFloorLength); + nextCapFloorLength += indexTenor; + } + nOptionletTenors_ = optionletTenors_.Count; + + optionletVolatilities_ = new InitializedList>(nOptionletTenors_) ; + for (int x = 0 ; x < nOptionletTenors_; x++) + { + optionletVolatilities_[x] = new InitializedList(nStrikes_); + } + optionletStrikes_ = new InitializedList>(nOptionletTenors_) ; + for (int x = 0; x < nOptionletTenors_; x++) { - Utils.QL_REQUIRE(displacement_.IsEqual(0.0),()=> - "non-null displacement is not allowed with Normal model"); - } - - termVolSurface.registerWith(update); - iborIndex_.registerWith( update ); - discount_.registerWith( update ); - Settings.registerWith(update); - - Period indexTenor = iborIndex_.tenor(); - Period maxCapFloorTenor = termVolSurface.optionTenors().Last(); - - // optionlet tenors and capFloor lengths - optionletTenors_.Add(indexTenor); - capFloorLengths_.Add(optionletTenors_.Last()+indexTenor); - Utils.QL_REQUIRE(maxCapFloorTenor>=capFloorLengths_.Last(),()=> - "too short (" + maxCapFloorTenor + ") capfloor term vol termVolSurface"); - Period nextCapFloorLength = capFloorLengths_.Last()+indexTenor; - while (nextCapFloorLength<=maxCapFloorTenor) - { - optionletTenors_.Add(capFloorLengths_.Last()); - capFloorLengths_.Add(nextCapFloorLength); - nextCapFloorLength += indexTenor; - } - nOptionletTenors_ = optionletTenors_.Count; - - optionletVolatilities_ = new InitializedList>( nOptionletTenors_) ; - for ( int x = 0 ; x < nOptionletTenors_; x++) - { - optionletVolatilities_[x] = new InitializedList(nStrikes_); - } - optionletStrikes_ = new InitializedList>( nOptionletTenors_ ) ; - for ( int x = 0; x < nOptionletTenors_; x++ ) - { - optionletStrikes_[x] = new List( termVolSurface.strikes() ); - } - - optionletDates_ = new InitializedList(nOptionletTenors_); - optionletTimes_ = new InitializedList(nOptionletTenors_); - atmOptionletRate_ = new InitializedList(nOptionletTenors_); - optionletPaymentDates_ = new InitializedList(nOptionletTenors_); - optionletAccrualPeriods_ = new InitializedList(nOptionletTenors_); + optionletStrikes_[x] = new List(termVolSurface.strikes()); + } + + optionletDates_ = new InitializedList(nOptionletTenors_); + optionletTimes_ = new InitializedList(nOptionletTenors_); + atmOptionletRate_ = new InitializedList(nOptionletTenors_); + optionletPaymentDates_ = new InitializedList(nOptionletTenors_); + optionletAccrualPeriods_ = new InitializedList(nOptionletTenors_); } protected CapFloorTermVolSurface termVolSurface_; diff --git a/src/QLNet/Termstructures/Volatility/Optionlet/OptionletStripper1.cs b/src/QLNet/Termstructures/Volatility/Optionlet/OptionletStripper1.cs index 1dd6b079a..415b38342 100644 --- a/src/QLNet/Termstructures/Volatility/Optionlet/OptionletStripper1.cs +++ b/src/QLNet/Termstructures/Volatility/Optionlet/OptionletStripper1.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,25 +19,25 @@ namespace QLNet { - using CapFloorMatrix = List>; + using CapFloorMatrix = List>; /*! Helper class to strip optionlet (i.e. caplet/floorlet) volatilities (a.k.a. forward-forward volatilities) from the (cap/floor) term volatilities of a CapFloorTermVolSurface. */ public class OptionletStripper1 : OptionletStripper { - public OptionletStripper1( CapFloorTermVolSurface termVolSurface, IborIndex index, - double? switchStrike = null, - double accuracy = 1.0e-6, - int maxIter = 100, - Handle discount = null, - VolatilityType type = VolatilityType.ShiftedLognormal, - double displacement = 0.0, - bool dontThrow = false) - :base(termVolSurface, index, discount, type, displacement) + public OptionletStripper1(CapFloorTermVolSurface termVolSurface, IborIndex index, + double? switchStrike = null, + double accuracy = 1.0e-6, + int maxIter = 100, + Handle discount = null, + VolatilityType type = VolatilityType.ShiftedLognormal, + double displacement = 0.0, + bool dontThrow = false) + : base(termVolSurface, index, discount, type, displacement) { volQuotes_ = new InitializedList>(nOptionletTenors_, - new InitializedList( nStrikes_, new SimpleQuote() ) ); + new InitializedList(nStrikes_, new SimpleQuote())); floatingSwitchStrike_ = switchStrike == null; capFlooMatrixNotInitialized_ = true; switchStrike_ = switchStrike; @@ -45,13 +45,13 @@ public OptionletStripper1( CapFloorTermVolSurface termVolSurface, IborIndex inde maxIter_ = maxIter; dontThrow_ = dontThrow; - capFloorPrices_ = new Matrix( nOptionletTenors_, nStrikes_ ); - optionletPrices_ = new Matrix( nOptionletTenors_, nStrikes_ ); - capFloorVols_ = new Matrix( nOptionletTenors_, nStrikes_ ); + capFloorPrices_ = new Matrix(nOptionletTenors_, nStrikes_); + optionletPrices_ = new Matrix(nOptionletTenors_, nStrikes_); + capFloorVols_ = new Matrix(nOptionletTenors_, nStrikes_); double firstGuess = 0.14; // guess is only used for shifted lognormal vols - optionletStDevs_ = new Matrix( nOptionletTenors_, nStrikes_, firstGuess ); + optionletStDevs_ = new Matrix(nOptionletTenors_, nStrikes_, firstGuess); - capFloors_ = new InitializedList>( nOptionletTenors_ ); + capFloors_ = new InitializedList>(nOptionletTenors_); } public Matrix capFloorPrices() @@ -71,7 +71,7 @@ public Matrix optionletPrices() } public double switchStrike() { - if ( floatingSwitchStrike_ ) + if (floatingSwitchStrike_) calculate(); return switchStrike_.Value; } @@ -87,17 +87,17 @@ protected override void performCalculations() for (int i = 0; i < nOptionletTenors_; ++i) { CapFloor temp = new MakeCapFloor(CapFloorType.Cap, - capFloorLengths_[i], - iborIndex_, - 0.04, // dummy strike - new Period(0, TimeUnit.Days)) - .withPricingEngine(dummy); + capFloorLengths_[i], + iborIndex_, + 0.04, // dummy strike + new Period(0, TimeUnit.Days)) + .withPricingEngine(dummy); FloatingRateCoupon lFRC = temp.lastFloatingRateCoupon(); optionletDates_[i] = lFRC.fixingDate(); optionletPaymentDates_[i] = lFRC.date(); optionletAccrualPeriods_[i] = lFRC.accrualPeriod(); optionletTimes_[i] = dc.yearFraction(referenceDate, - optionletDates_[i]); + optionletDates_[i]); atmOptionletRate_[i] = lFRC.indexFixing(); } @@ -108,12 +108,12 @@ protected override void performCalculations() { averageAtmOptionletRate += atmOptionletRate_[i]; } - switchStrike_ = averageAtmOptionletRate/nOptionletTenors_; + switchStrike_ = averageAtmOptionletRate / nOptionletTenors_; } Handle discountCurve = discount_.empty() - ? iborIndex_.forwardingTermStructure() - : discount_; + ? iborIndex_.forwardingTermStructure() + : discount_; List strikes = new List(termVolSurface_.strikes()); // initialize CapFloorMatrix @@ -126,23 +126,23 @@ protected override void performCalculations() { // using out-of-the-money options CapFloorType capFloorType = strikes[j] < switchStrike_ - ? CapFloorType.Floor - : CapFloorType.Cap; + ? CapFloorType.Floor + : CapFloorType.Cap; for (int i = 0; i < nOptionletTenors_; ++i) { if (volatilityType_ == VolatilityType.ShiftedLognormal) { BlackCapFloorEngine engine = new BlackCapFloorEngine(discountCurve, - new Handle(volQuotes_[i][j]), dc, displacement_); + new Handle(volQuotes_[i][j]), dc, displacement_); capFloors_[i].Add(new MakeCapFloor(capFloorType, capFloorLengths_[i], iborIndex_, strikes[j], - new Period(0, TimeUnit.Days)).withPricingEngine(engine)); + new Period(0, TimeUnit.Days)).withPricingEngine(engine)); } else if (volatilityType_ == VolatilityType.Normal) { BachelierCapFloorEngine engine = new BachelierCapFloorEngine(discountCurve, - new Handle(volQuotes_[i][j]), dc); + new Handle(volQuotes_[i][j]), dc); capFloors_[i].Add(new MakeCapFloor(capFloorType, capFloorLengths_[i], iborIndex_, strikes[j], - new Period(0, TimeUnit.Days)).withPricingEngine(engine)); + new Period(0, TimeUnit.Days)).withPricingEngine(engine)); } else { @@ -167,18 +167,18 @@ protected override void performCalculations() optionletPrices_[i, j] = capFloorPrices_[i, j] - previousCapFloorPrice; previousCapFloorPrice = capFloorPrices_[i, j]; double d = discountCurve.link.discount(optionletPaymentDates_[i]); - double optionletAnnuity = optionletAccrualPeriods_[i]*d; + double optionletAnnuity = optionletAccrualPeriods_[i] * d; try { if (volatilityType_ == VolatilityType.ShiftedLognormal) { - optionletStDevs_[i, j] = Utils.blackFormulaImpliedStdDev( optionletType, strikes[j], atmOptionletRate_[i], - optionletPrices_[i, j], optionletAnnuity, displacement_, optionletStDevs_[i, j], accuracy_, - maxIter_); + optionletStDevs_[i, j] = Utils.blackFormulaImpliedStdDev(optionletType, strikes[j], atmOptionletRate_[i], + optionletPrices_[i, j], optionletAnnuity, displacement_, optionletStDevs_[i, j], accuracy_, + maxIter_); } else if (volatilityType_ == VolatilityType.Normal) { - optionletStDevs_[i, j] = Math.Sqrt(optionletTimes_[i])* + optionletStDevs_[i, j] = Math.Sqrt(optionletTimes_[i]) * Utils.bachelierBlackFormulaImpliedVol( optionletType, strikes[j], atmOptionletRate_[i], optionletTimes_[i], optionletPrices_[i, j], @@ -203,7 +203,7 @@ protected override void performCalculations() "\n expiry: " + optionletDates_[i] + "\n error: " + e.Message); } - optionletVolatilities_[i][j] = optionletStDevs_[i, j]/Math.Sqrt(optionletTimes_[i]); + optionletVolatilities_[i][j] = optionletStDevs_[i, j] / Math.Sqrt(optionletTimes_[i]); } } } diff --git a/src/QLNet/Termstructures/Volatility/Optionlet/OptionletStripper2.cs b/src/QLNet/Termstructures/Volatility/Optionlet/OptionletStripper2.cs index d4f8b27c6..4aa152924 100644 --- a/src/QLNet/Termstructures/Volatility/Optionlet/OptionletStripper2.cs +++ b/src/QLNet/Termstructures/Volatility/Optionlet/OptionletStripper2.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -25,29 +25,29 @@ term volatilities of a CapFloorTermVolCurve. */ public class OptionletStripper2 : OptionletStripper { - + public OptionletStripper2(OptionletStripper1 optionletStripper1, Handle atmCapFloorTermVolCurve) - :base(optionletStripper1.termVolSurface(), - optionletStripper1.iborIndex(), - new Handle(), - optionletStripper1.volatilityType(), - optionletStripper1.displacement()) + : base(optionletStripper1.termVolSurface(), + optionletStripper1.iborIndex(), + new Handle(), + optionletStripper1.volatilityType(), + optionletStripper1.displacement()) { stripper1_ = optionletStripper1; atmCapFloorTermVolCurve_ = atmCapFloorTermVolCurve; dc_ = stripper1_.termVolSurface().dayCounter(); nOptionExpiries_ = atmCapFloorTermVolCurve.link.optionTenors().Count; - atmCapFloorStrikes_ = new InitializedList(nOptionExpiries_,0.0); - atmCapFloorPrices_ = new InitializedList(nOptionExpiries_,0.0); - spreadsVolImplied_ = new InitializedList(nOptionExpiries_,0.0); + atmCapFloorStrikes_ = new InitializedList(nOptionExpiries_, 0.0); + atmCapFloorPrices_ = new InitializedList(nOptionExpiries_, 0.0); + spreadsVolImplied_ = new InitializedList(nOptionExpiries_, 0.0); caps_ = new List(); maxEvaluations_ = 10000; accuracy_ = 1E-6; stripper1_.registerWith(update); - atmCapFloorTermVolCurve_.registerWith(update); + atmCapFloorTermVolCurve_.registerWith(update); - Utils.QL_REQUIRE( dc_ == atmCapFloorTermVolCurve.link.dayCounter(),()=> "different day counters provided" ); + Utils.QL_REQUIRE(dc_ == atmCapFloorTermVolCurve.link.dayCounter(), () => "different day counters provided"); } public List atmCapFloorStrikes() @@ -76,7 +76,7 @@ protected override void performCalculations() optionletAccrualPeriods_ = new List(stripper1_.optionletAccrualPeriods()); optionletTimes_ = new List(stripper1_.optionletFixingTimes()); atmOptionletRate_ = new List(stripper1_.atmOptionletRates()); - for (int i=0; i(stripper1_.optionletStrikes(i)); optionletVolatilities_[i] = new List(stripper1_.optionletVolatilities(i)); @@ -86,12 +86,12 @@ protected override void performCalculations() List optionExpiriesTenors = new List(atmCapFloorTermVolCurve_.link.optionTenors()); List optionExpiriesTimes = new List(atmCapFloorTermVolCurve_.link.optionTimes()); - for (int j=0; j x >= atmCapFloorStrikes_[j]); - int insertIndex = previous ; + int insertIndex = previous ; - optionletStrikes_[i].Insert(insertIndex,atmCapFloorStrikes_[j]); + optionletStrikes_[i].Insert(insertIndex, atmCapFloorStrikes_[j]); optionletVolatilities_[i].Insert(insertIndex, adjustedVol); } } } } - + private List spreadsVolImplied() { - Brent solver = new Brent(); - List result = new InitializedList(nOptionExpiries_,0.0); - double guess = 0.0001, minSpread = -0.1, maxSpread = 0.1; - for (int j=0; j result = new InitializedList(nOptionExpiries_, 0.0); + double guess = 0.0001, minSpread = -0.1, maxSpread = 0.1; + for (int j = 0; j < nOptionExpiries_; ++j) + { ObjectiveFunction f = new ObjectiveFunction(stripper1_, caps_[j], atmCapFloorPrices_[j]); solver.setMaxEvaluations(maxEvaluations_); - double root = solver.solve(f, accuracy_, guess,minSpread, maxSpread); + double root = solver.solve(f, accuracy_, guess, minSpread, maxSpread); result[j] = root; - } - return result; + } + return result; } private class ObjectiveFunction : ISolver1d { - public ObjectiveFunction(OptionletStripper1 optionletStripper1,CapFloor cap,double targetValue) + public ObjectiveFunction(OptionletStripper1 optionletStripper1, CapFloor cap, double targetValue) { cap_ = cap; targetValue_ = targetValue; - + OptionletVolatilityStructure adapter = new StrippedOptionletAdapter(optionletStripper1); // set an implausible value, so that calculation is forced @@ -153,18 +153,18 @@ public ObjectiveFunction(OptionletStripper1 optionletStripper1,CapFloor cap,doub new Handle(adapter), new Handle(spreadQuote_)); BlackCapFloorEngine engine = new BlackCapFloorEngine(optionletStripper1.iborIndex().forwardingTermStructure(), - new Handle(spreadedAdapter)); + new Handle(spreadedAdapter)); cap_.setPricingEngine(engine); } public override double value(double s) { - if ( s.IsNotEqual(spreadQuote_.value()) ) - spreadQuote_.setValue( s ); + if (s.IsNotEqual(spreadQuote_.value())) + spreadQuote_.setValue(s); return cap_.NPV() - targetValue_; } - + private SimpleQuote spreadQuote_; private CapFloor cap_; private double targetValue_; diff --git a/src/QLNet/Termstructures/Volatility/Optionlet/OptionletVolatilityStructure.cs b/src/QLNet/Termstructures/Volatility/Optionlet/OptionletVolatilityStructure.cs index aceb85109..5412aea7c 100644 --- a/src/QLNet/Termstructures/Volatility/Optionlet/OptionletVolatilityStructure.cs +++ b/src/QLNet/Termstructures/Volatility/Optionlet/OptionletVolatilityStructure.cs @@ -1,30 +1,30 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet +namespace QLNet { //! Optionlet (caplet/floorlet) volatility structure /*! This class is purely abstract and defines the interface of concrete structures which will be derived from this one. */ - public abstract class OptionletVolatilityStructure : VolatilityTermStructure + public abstract class OptionletVolatilityStructure : VolatilityTermStructure { #region Constructors //! default constructor @@ -34,17 +34,17 @@ by overriding the referenceDate() method. */ protected OptionletVolatilityStructure(BusinessDayConvention bdc = BusinessDayConvention.Following, - DayCounter dc = null) + DayCounter dc = null) : base(bdc, dc) {} //! initialize with a fixed reference date - protected OptionletVolatilityStructure(Date referenceDate,Calendar cal,BusinessDayConvention bdc,DayCounter dc = null) + protected OptionletVolatilityStructure(Date referenceDate, Calendar cal, BusinessDayConvention bdc, DayCounter dc = null) : base(referenceDate, cal, bdc, dc) {} - + //! calculate the reference date based on the global evaluation date - protected OptionletVolatilityStructure(int settlementDays,Calendar cal,BusinessDayConvention bdc,DayCounter dc = null) + protected OptionletVolatilityStructure(int settlementDays, Calendar cal, BusinessDayConvention bdc, DayCounter dc = null) : base(settlementDays, cal, bdc, dc) {} - + #endregion #region Volatility and Variance @@ -55,7 +55,7 @@ public double volatility(Period optionTenor, double strike, bool extrapolate = f Date optionDate = optionDateFromTenor(optionTenor); return volatility(optionDate, strike, extrapolate); } - + //! returns the volatility for a given option date and strike rate public double volatility(Date optionDate, double strike, bool extrapolate = false) { @@ -63,7 +63,7 @@ public double volatility(Date optionDate, double strike, bool extrapolate = fals checkStrike(strike, extrapolate); return volatilityImpl(optionDate, strike); } - + //! returns the volatility for a given option time and strike rate public double volatility(double optionTime, double strike, bool extrapolate = false) { @@ -84,25 +84,25 @@ public double blackVariance(Date optionDate, double strike, bool extrapolate = f { double v = volatility(optionDate, strike, extrapolate); double t = timeFromReference(optionDate); - return v*v*t; + return v * v * t; } //! returns the Black variance for a given option time and strike rate public double blackVariance(double optionTime, double strike, bool extrapolate = false) { double v = volatility(optionTime, strike, extrapolate); - return v*v*optionTime; + return v * v * optionTime; } //! returns the smile for a given option tenor - public SmileSection smileSection( Period optionTenor, bool extr = false) + public SmileSection smileSection(Period optionTenor, bool extr = false) { Date optionDate = optionDateFromTenor(optionTenor); return smileSection(optionDate, extrapolate); } //! returns the smile for a given option date - public SmileSection smileSection(Date optionDate,bool extr = false) + public SmileSection smileSection(Date optionDate, bool extr = false) { checkRange(optionDate, extrapolate); return smileSectionImpl(optionDate); @@ -114,15 +114,15 @@ public SmileSection smileSection(double optionTime, bool extr = false) checkRange(optionTime, extrapolate); return smileSectionImpl(optionTime); } - + #endregion - + public virtual double displacement() {return 0.0;} public virtual VolatilityType volatilityType() {return VolatilityType.ShiftedLognormal;} protected virtual SmileSection smileSectionImpl(Date optionDate) { - return smileSectionImpl(timeFromReference(optionDate)); + return smileSectionImpl(timeFromReference(optionDate)); } //! implements the actual smile calculation in derived classes @@ -138,5 +138,5 @@ protected double volatilityImpl(Date optionDate, double strike) } - + } diff --git a/src/QLNet/Termstructures/Volatility/Optionlet/SpreadedOptionletVolatility.cs b/src/QLNet/Termstructures/Volatility/Optionlet/SpreadedOptionletVolatility.cs index 39648a787..573718408 100644 --- a/src/QLNet/Termstructures/Volatility/Optionlet/SpreadedOptionletVolatility.cs +++ b/src/QLNet/Termstructures/Volatility/Optionlet/SpreadedOptionletVolatility.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,7 +22,7 @@ namespace QLNet { public class SpreadedOptionletVolatility : OptionletVolatilityStructure { - public SpreadedOptionletVolatility(Handle baseVol,Handle spread) + public SpreadedOptionletVolatility(Handle baseVol, Handle spread) { baseVol_ = baseVol; spread_ = spread; @@ -45,19 +45,19 @@ public SpreadedOptionletVolatility(Handle baseVol, // All virtual methods of base classes must be forwarded // OptionletVolatilityStructure interface - protected override SmileSection smileSectionImpl( Date d ) + protected override SmileSection smileSectionImpl(Date d) { SmileSection baseSmile = baseVol_.link.smileSection(d, true); return new SpreadedSmileSection(baseSmile, spread_); } - protected override SmileSection smileSectionImpl( double optionTime ) + protected override SmileSection smileSectionImpl(double optionTime) { SmileSection baseSmile = baseVol_.link.smileSection(optionTime, true); return new SpreadedSmileSection(baseSmile, spread_); } - protected override double volatilityImpl( double t, double s ) + protected override double volatilityImpl(double t, double s) { - return baseVol_.link.volatility( t, s, true ) + spread_.link.value(); + return baseVol_.link.volatility(t, s, true) + spread_.link.value(); } private Handle baseVol_; diff --git a/src/QLNet/Termstructures/Volatility/Optionlet/StrippedOptionletAdapter.cs b/src/QLNet/Termstructures/Volatility/Optionlet/StrippedOptionletAdapter.cs index 8c7aa75ad..1faa78656 100644 --- a/src/QLNet/Termstructures/Volatility/Optionlet/StrippedOptionletAdapter.cs +++ b/src/QLNet/Termstructures/Volatility/Optionlet/StrippedOptionletAdapter.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,11 +22,11 @@ namespace QLNet { public class StrippedOptionletAdapter : OptionletVolatilityStructure { - /*! Adapter class for turning a StrippedOptionletBase object into an - OptionletVolatilityStructure. + /*! Adapter class for turning a StrippedOptionletBase object into an + OptionletVolatilityStructure. */ public StrippedOptionletAdapter(StrippedOptionletBase s) - :base(s.settlementDays(),s.calendar(),s.businessDayConvention(),s.dayCounter()) + : base(s.settlementDays(), s.calendar(), s.businessDayConvention(), s.dayCounter()) { optionletStripper_ = s; nInterpolations_ = s.optionletMaturities(); @@ -36,66 +36,66 @@ public StrippedOptionletAdapter(StrippedOptionletBase s) } // TermStructure interface - + public override Date maxDate() { return optionletStripper_.optionletFixingDates().Last(); } - + // VolatilityTermStructure interface - + public override double minStrike() { return optionletStripper_.optionletStrikes(0).First(); } - public override double maxStrike() { return optionletStripper_.optionletStrikes( 0 ).Last(); } - public override VolatilityType volatilityType() - { - return optionletStripper_.volatilityType(); - } - - public override double displacement() - { - return optionletStripper_.displacement(); + public override double maxStrike() { return optionletStripper_.optionletStrikes(0).Last(); } + public override VolatilityType volatilityType() + { + return optionletStripper_.volatilityType(); + } + + public override double displacement() + { + return optionletStripper_.displacement(); } - + // LazyObject interface - + public override void update() { base.update(); } protected override void performCalculations() { - for (int i=0; i optionletStrikes = new List(optionletStripper_.optionletStrikes(i)); List optionletVolatilities = new List(optionletStripper_.optionletVolatilities(i)); - strikeInterpolations_.Add(new LinearInterpolation(optionletStrikes,optionletStrikes.Count,optionletVolatilities)); + strikeInterpolations_.Add(new LinearInterpolation(optionletStrikes, optionletStrikes.Count, optionletVolatilities)); } } - + // OptionletVolatilityStructure interface - + protected override SmileSection smileSectionImpl(double t) { List optionletStrikes = new List(optionletStripper_.optionletStrikes(0)); // strikes are the same for all times ?! List stddevs = new List(); - for(int i=0;i=4 ? CubicInterpolation.BoundaryCondition.Lagrange : CubicInterpolation.BoundaryCondition.SecondDerivative; - return new InterpolatedSmileSection(t,optionletStrikes,stddevs,0, - new Cubic(CubicInterpolation.DerivativeApprox.Spline,false,bc,0.0,bc,0.0)); + CubicInterpolation.BoundaryCondition bc = optionletStrikes.Count >= 4 ? CubicInterpolation.BoundaryCondition.Lagrange : CubicInterpolation.BoundaryCondition.SecondDerivative; + return new InterpolatedSmileSection(t, optionletStrikes, stddevs, 0, + new Cubic(CubicInterpolation.DerivativeApprox.Spline, false, bc, 0.0, bc, 0.0)); } - protected override double volatilityImpl(double length,double strike) + protected override double volatilityImpl(double length, double strike) { calculate(); List vol = new InitializedList(nInterpolations_); - for (int i=0; i optionletTimes = new List(optionletStripper_.optionletFixingTimes()); - LinearInterpolation timeInterpolator = new LinearInterpolation(optionletTimes, optionletTimes.Count,vol); + LinearInterpolation timeInterpolator = new LinearInterpolation(optionletTimes, optionletTimes.Count, vol); return timeInterpolator.value(length, true); } - - + + private StrippedOptionletBase optionletStripper_; private int nInterpolations_; private List strikeInterpolations_; diff --git a/src/QLNet/Termstructures/Volatility/Optionlet/StrippedOptionletBase.cs b/src/QLNet/Termstructures/Volatility/Optionlet/StrippedOptionletBase.cs index 3cd35ba35..b31fe5744 100644 --- a/src/QLNet/Termstructures/Volatility/Optionlet/StrippedOptionletBase.cs +++ b/src/QLNet/Termstructures/Volatility/Optionlet/StrippedOptionletBase.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -35,8 +35,8 @@ public abstract class StrippedOptionletBase : LazyObject public abstract DayCounter dayCounter() ; public abstract Calendar calendar() ; public abstract int settlementDays() ; - public abstract BusinessDayConvention businessDayConvention() ; - public abstract VolatilityType volatilityType() ; + public abstract BusinessDayConvention businessDayConvention() ; + public abstract VolatilityType volatilityType() ; public abstract double displacement() ; } } diff --git a/src/QLNet/Termstructures/Volatility/Optionlet/capletvariancecurve.cs b/src/QLNet/Termstructures/Volatility/Optionlet/capletvariancecurve.cs deleted file mode 100644 index 78b89bcda..000000000 --- a/src/QLNet/Termstructures/Volatility/Optionlet/capletvariancecurve.cs +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System.Collections.Generic; - -namespace QLNet -{ - public class CapletVarianceCurve : OptionletVolatilityStructure { - - private BlackVarianceCurve blackCurve_; - - public CapletVarianceCurve( Date referenceDate, - List dates, - List capletVolCurve, - DayCounter dayCounter) - : base(referenceDate, new Calendar(), BusinessDayConvention.Following, new DayCounter()) - { - blackCurve_=new BlackVarianceCurve(referenceDate, dates, capletVolCurve, dayCounter, false); - } - - public override DayCounter dayCounter() { - return blackCurve_.dayCounter(); - } - - public override Date maxDate() { - return blackCurve_.maxDate(); - } - - public override double minStrike() { - return blackCurve_.minStrike(); - } - - public override double maxStrike() { - return blackCurve_.maxStrike(); - } - - protected override SmileSection smileSectionImpl(double t) { - // dummy strike - double atmVol = blackCurve_.blackVol(t, 0.05, true); - return new FlatSmileSection(t,atmVol,dayCounter()); - } - - protected override double volatilityImpl(double t,double r){ - return blackCurve_.blackVol(t, r, true); - } - } -} diff --git a/src/QLNet/Termstructures/Volatility/Sabr.cs b/src/QLNet/Termstructures/Volatility/Sabr.cs index 8ddb94c38..6e6769a94 100644 --- a/src/QLNet/Termstructures/Volatility/Sabr.cs +++ b/src/QLNet/Termstructures/Volatility/Sabr.cs @@ -1,198 +1,200 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - public enum SabrApproximationModel { Obloj2008 = 1, Hagan2002 = 0 }; - - public partial class Utils { +namespace QLNet +{ + public enum SabrApproximationModel { Obloj2008 = 1, Hagan2002 = 0 } + + public partial class Utils + { + + public static double unsafeSabrNormalVolatility(double strike, double forward, double expiryTime, double alpha, double beta, + double nu, double rho) + { + double oneMinusBeta = 1.0 - beta; + double Fmid = forward * strike < 0.0 ? (forward + strike) * 0.5 : Math.Sqrt(forward * strike); + double gamma1 = beta / Fmid; + double gamma2 = -beta * oneMinusBeta / (Fmid * Fmid); + double zeta = alpha / (nu * oneMinusBeta) * (Math.Pow(forward, oneMinusBeta) - Math.Pow(strike, oneMinusBeta)); + double D = Math.Log((Math.Sqrt(1.0 - 2.0 * rho * zeta + zeta * zeta) + zeta - rho) / (1.0 - rho)); + double epsilon = alpha * alpha * expiryTime; + double M = forward - strike; + double a = nu * Math.Pow(Fmid, beta) / alpha; + double b = Math.Pow(a, 2.0); + double d = 1.0 + ((2.0 * gamma2 - gamma1 * gamma1) / 24.0 * b + + rho * gamma1 / 4.0 * a + + (2.0 - 3.0 * rho * rho) / 24.0) * epsilon; + + return alpha * M / D * d; + } + + public static double unsafeSabrVolatility(double strike, double forward, double expiryTime, double alpha, double beta, + double nu, double rho, SabrApproximationModel approximationModel = SabrApproximationModel.Hagan2002) + { + if (approximationModel == SabrApproximationModel.Hagan2002) + { + double oneMinusBeta = 1.0 - beta; + double A = Math.Pow(forward * strike, oneMinusBeta); + double sqrtA = Math.Sqrt(A); + double logM; - public static double unsafeSabrNormalVolatility(double strike, double forward, double expiryTime, double alpha, double beta, - double nu, double rho) - { + if (!close(forward, strike)) + logM = Math.Log(forward / strike); + else + { + double epsilon = (forward - strike) / strike; + logM = epsilon - .5 * epsilon * epsilon; + } + double z = (nu / alpha) * sqrtA * logM; + double B = 1.0 - 2.0 * rho * z + z * z; + double C = oneMinusBeta * oneMinusBeta * logM * logM; + double tmp = (Math.Sqrt(B) + z - rho) / (1.0 - rho); + double xx = Math.Log(tmp); + double D = sqrtA * (1.0 + C / 24.0 + C * C / 1920.0); + double d = 1.0 + expiryTime * + (oneMinusBeta * oneMinusBeta * alpha * alpha / (24.0 * A) + + 0.25 * rho * beta * nu * alpha / sqrtA + + (2.0 - 3.0 * rho * rho) * (nu * nu / 24.0)); + + double multiplier; + // computations become precise enough if the square of z worth slightly more than the precision machine (hence the m) + const double m = 10; + + if (Math.Abs(z * z) > Const.QL_EPSILON * m) + multiplier = z / xx; + else + { + multiplier = 1.0 - 0.5 * rho * z - (3.0 * rho * rho - 2.0) * z * z / 12.0; + } + return (alpha / D) * multiplier * d; + } + else if (approximationModel == SabrApproximationModel.Obloj2008) + { double oneMinusBeta = 1.0 - beta; - double Fmid = forward * strike < 0.0 ? (forward + strike) * 0.5 : Math.Sqrt(forward * strike); + double Fmid = Math.Sqrt(forward * strike); double gamma1 = beta / Fmid; double gamma2 = -beta * oneMinusBeta / (Fmid * Fmid); double zeta = alpha / (nu * oneMinusBeta) * (Math.Pow(forward, oneMinusBeta) - Math.Pow(strike, oneMinusBeta)); double D = Math.Log((Math.Sqrt(1.0 - 2.0 * rho * zeta + zeta * zeta) + zeta - rho) / (1.0 - rho)); double epsilon = alpha * alpha * expiryTime; - double M = forward - strike; - double a = nu * Math.Pow(Fmid, beta) / alpha; - double b = Math.Pow(a, 2.0); - double d = 1.0 + ((2.0 * gamma2 - gamma1 * gamma1) / 24.0 * b - + rho * gamma1 / 4.0 * a - + (2.0 - 3.0 * rho * rho) / 24.0) * epsilon; - return alpha * M / D * d; - } + double logM; - public static double unsafeSabrVolatility(double strike, double forward, double expiryTime, double alpha, double beta, - double nu, double rho, SabrApproximationModel approximationModel = SabrApproximationModel.Hagan2002) - { - if (approximationModel == SabrApproximationModel.Hagan2002) - { - double oneMinusBeta = 1.0 - beta; - double A = Math.Pow(forward * strike, oneMinusBeta); - double sqrtA = Math.Sqrt(A); - double logM; - - if (!close(forward, strike)) - logM = Math.Log(forward / strike); - else - { - double epsilon = (forward - strike) / strike; - logM = epsilon - .5 * epsilon * epsilon; - } - double z = (nu / alpha) * sqrtA * logM; - double B = 1.0 - 2.0 * rho * z + z * z; - double C = oneMinusBeta * oneMinusBeta * logM * logM; - double tmp = (Math.Sqrt(B) + z - rho) / (1.0 - rho); - double xx = Math.Log(tmp); - double D = sqrtA * (1.0 + C / 24.0 + C * C / 1920.0); - double d = 1.0 + expiryTime * - (oneMinusBeta * oneMinusBeta * alpha * alpha / (24.0 * A) - + 0.25 * rho * beta * nu * alpha / sqrtA - + (2.0 - 3.0 * rho * rho) * (nu * nu / 24.0)); - - double multiplier; - // computations become precise enough if the square of z worth slightly more than the precision machine (hence the m) - const double m = 10; - - if (Math.Abs(z * z) > Const.QL_EPSILON * m) - multiplier = z / xx; - else - { - multiplier = 1.0 - 0.5 * rho * z - (3.0 * rho * rho - 2.0) * z * z / 12.0; - } - return (alpha / D) * multiplier * d; - } - else if (approximationModel == SabrApproximationModel.Obloj2008) - { - double oneMinusBeta = 1.0 - beta; - double Fmid = Math.Sqrt(forward * strike); - double gamma1 = beta / Fmid; - double gamma2 = -beta * oneMinusBeta / (Fmid * Fmid); - double zeta = alpha / (nu * oneMinusBeta) * (Math.Pow(forward, oneMinusBeta) - Math.Pow(strike, oneMinusBeta)); - double D = Math.Log((Math.Sqrt(1.0 - 2.0 * rho * zeta + zeta * zeta) + zeta - rho) / (1.0 - rho)); - double epsilon = alpha * alpha * expiryTime; - - double logM; - - if (!close(forward, strike)) - logM = Math.Log(forward / strike); - else - { - double eps = (forward - strike) / strike; - logM = eps - .5 * eps * eps; - } - - double a = nu * Math.Pow(Fmid, beta) / alpha; - double b = Math.Pow(a, 2.0); - double d = 1.0 + ((2.0 * gamma2 - gamma1 * gamma1 + 1 / (Fmid * Fmid)) / 24.0 * b - + rho * gamma1 / 4.0 * a - + (2.0 - 3.0 * rho * rho) / 24.0) * epsilon; - - return alpha * logM / D * d; - } + if (!close(forward, strike)) + logM = Math.Log(forward / strike); else { - QL_FAIL("Unknown approximation model."); - return 0.0; + double eps = (forward - strike) / strike; + logM = eps - .5 * eps * eps; } - } - - public static double unsafeShiftedSabrVolatility(double strike, - double forward, - double expiryTime, - double alpha, - double beta, - double nu, - double rho, - double shift, - SabrApproximationModel approximationModel = SabrApproximationModel.Hagan2002) - { - - return unsafeSabrVolatility(strike + shift, forward + shift, expiryTime, - alpha, beta, nu, rho, approximationModel); - } - - public static void validateSabrParameters(double alpha, double beta, double nu, double rho) - { - QL_REQUIRE(alpha > 0.0,()=> "alpha must be positive: " + alpha + " not allowed"); - QL_REQUIRE(beta >= 0.0 && beta <= 1.0,()=> "beta must be in (0.0, 1.0): " + beta + " not allowed"); - QL_REQUIRE(nu >= 0.0,()=> "nu must be non negative: " + nu + " not allowed"); - QL_REQUIRE(rho * rho < 1.0,()=> "rho square must be less than one: " + rho + " not allowed"); - } - - public static double sabrVolatility(double strike, double forward, double expiryTime, double alpha, double beta, - double nu, double rho, SabrApproximationModel approximationModel = SabrApproximationModel.Hagan2002) - { - QL_REQUIRE(strike>0.0,()=> "strike must be positive: " + strike + " not allowed"); - QL_REQUIRE(forward>0.0,()=> "at the money forward rate must be: " + forward + " not allowed"); - QL_REQUIRE(expiryTime>=0.0,()=> "expiry time must be non-negative: " + expiryTime + " not allowed"); - validateSabrParameters(alpha, beta, nu, rho); - return unsafeSabrVolatility(strike, forward, expiryTime, alpha, beta, nu, rho, approximationModel); - } - - public static double shiftedSabrVolatility(double strike, - double forward, - double expiryTime, - double alpha, - double beta, - double nu, - double rho, - double shift, - SabrApproximationModel approximationModel = SabrApproximationModel.Hagan2002) - { - QL_REQUIRE(strike + shift > 0.0, () => "strike+shift must be positive: " - + strike + "+" + shift + " not allowed"); - QL_REQUIRE(forward + shift > 0.0, () => "at the money forward rate + shift must be " - + "positive: " + forward + " " + shift + " not allowed"); - QL_REQUIRE(expiryTime >= 0.0, () => "expiry time must be non-negative: " - + expiryTime + " not allowed"); - validateSabrParameters(alpha, beta, nu, rho); - return unsafeShiftedSabrVolatility(strike, forward, expiryTime, - alpha, beta, nu, rho, shift, approximationModel); - } - - public static double shiftedSabrNormalVolatility(double strike, double forward, double expiryTime, double alpha, double beta, - double nu, double rho, double shift = 0.0) - { - QL_REQUIRE(strike + shift > 0.0, () => "strike+shift must be positive: " - + strike + "+" + shift + " not allowed"); - QL_REQUIRE(forward + shift > 0.0, () => "at the money forward rate + shift must be " - + "positive: " + forward + " " + shift + " not allowed"); - QL_REQUIRE(expiryTime >= 0.0, () => "expiry time must be non-negative: " + expiryTime + " not allowed"); - validateSabrParameters(alpha, beta, nu, rho); - return unsafeSabrNormalVolatility(strike + shift, forward + shift, expiryTime, alpha, beta, nu, rho); - } - - - public static double sabrNormalVolatility(double strike, double forward, double expiryTime, double alpha, double beta, - double nu, double rho) - { - QL_REQUIRE(expiryTime >= 0.0, () => "expiry time must be non-negative: " + expiryTime + " not allowed"); - validateSabrParameters(alpha, beta, nu, rho); - return unsafeSabrNormalVolatility(strike, forward, expiryTime, alpha, beta, nu, rho); - } + + double a = nu * Math.Pow(Fmid, beta) / alpha; + double b = Math.Pow(a, 2.0); + double d = 1.0 + ((2.0 * gamma2 - gamma1 * gamma1 + 1 / (Fmid * Fmid)) / 24.0 * b + + rho * gamma1 / 4.0 * a + + (2.0 - 3.0 * rho * rho) / 24.0) * epsilon; + + return alpha * logM / D * d; + } + else + { + QL_FAIL("Unknown approximation model."); + return 0.0; + } + } + + public static double unsafeShiftedSabrVolatility(double strike, + double forward, + double expiryTime, + double alpha, + double beta, + double nu, + double rho, + double shift, + SabrApproximationModel approximationModel = SabrApproximationModel.Hagan2002) + { + + return unsafeSabrVolatility(strike + shift, forward + shift, expiryTime, + alpha, beta, nu, rho, approximationModel); + } + + public static void validateSabrParameters(double alpha, double beta, double nu, double rho) + { + QL_REQUIRE(alpha > 0.0, () => "alpha must be positive: " + alpha + " not allowed"); + QL_REQUIRE(beta >= 0.0 && beta <= 1.0, () => "beta must be in (0.0, 1.0): " + beta + " not allowed"); + QL_REQUIRE(nu >= 0.0, () => "nu must be non negative: " + nu + " not allowed"); + QL_REQUIRE(rho * rho < 1.0, () => "rho square must be less than one: " + rho + " not allowed"); + } + + public static double sabrVolatility(double strike, double forward, double expiryTime, double alpha, double beta, + double nu, double rho, SabrApproximationModel approximationModel = SabrApproximationModel.Hagan2002) + { + QL_REQUIRE(strike>0.0, () => "strike must be positive: " + strike + " not allowed"); + QL_REQUIRE(forward > 0.0, () => "at the money forward rate must be: " + forward + " not allowed"); + QL_REQUIRE(expiryTime >= 0.0, () => "expiry time must be non-negative: " + expiryTime + " not allowed"); + validateSabrParameters(alpha, beta, nu, rho); + return unsafeSabrVolatility(strike, forward, expiryTime, alpha, beta, nu, rho, approximationModel); + } + + public static double shiftedSabrVolatility(double strike, + double forward, + double expiryTime, + double alpha, + double beta, + double nu, + double rho, + double shift, + SabrApproximationModel approximationModel = SabrApproximationModel.Hagan2002) + { + QL_REQUIRE(strike + shift > 0.0, () => "strike+shift must be positive: " + + strike + "+" + shift + " not allowed"); + QL_REQUIRE(forward + shift > 0.0, () => "at the money forward rate + shift must be " + + "positive: " + forward + " " + shift + " not allowed"); + QL_REQUIRE(expiryTime >= 0.0, () => "expiry time must be non-negative: " + + expiryTime + " not allowed"); + validateSabrParameters(alpha, beta, nu, rho); + return unsafeShiftedSabrVolatility(strike, forward, expiryTime, + alpha, beta, nu, rho, shift, approximationModel); + } + + public static double shiftedSabrNormalVolatility(double strike, double forward, double expiryTime, double alpha, double beta, + double nu, double rho, double shift = 0.0) + { + QL_REQUIRE(strike + shift > 0.0, () => "strike+shift must be positive: " + + strike + "+" + shift + " not allowed"); + QL_REQUIRE(forward + shift > 0.0, () => "at the money forward rate + shift must be " + + "positive: " + forward + " " + shift + " not allowed"); + QL_REQUIRE(expiryTime >= 0.0, () => "expiry time must be non-negative: " + expiryTime + " not allowed"); + validateSabrParameters(alpha, beta, nu, rho); + return unsafeSabrNormalVolatility(strike + shift, forward + shift, expiryTime, alpha, beta, nu, rho); + } + + + public static double sabrNormalVolatility(double strike, double forward, double expiryTime, double alpha, double beta, + double nu, double rho) + { + QL_REQUIRE(expiryTime >= 0.0, () => "expiry time must be non-negative: " + expiryTime + " not allowed"); + validateSabrParameters(alpha, beta, nu, rho); + return unsafeSabrNormalVolatility(strike, forward, expiryTime, alpha, beta, nu, rho); + } } } diff --git a/src/QLNet/Termstructures/Volatility/SabrInterpolatedSmileSection.cs b/src/QLNet/Termstructures/Volatility/SabrInterpolatedSmileSection.cs index 9de9720b6..62955cc76 100644 --- a/src/QLNet/Termstructures/Volatility/SabrInterpolatedSmileSection.cs +++ b/src/QLNet/Termstructures/Volatility/SabrInterpolatedSmileSection.cs @@ -1,16 +1,16 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) // 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,178 +21,178 @@ namespace QLNet { - public class SabrInterpolatedSmileSection : SmileSection - { - //! \name Constructors - //@{ - //! all market data are quotes - public SabrInterpolatedSmileSection( - Date optionDate, - Handle forward, - List strikes, - bool hasFloatingStrikes, - Handle atmVolatility, - List > volHandles, - double alpha, double beta, double nu, double rho, - bool isAlphaFixed, bool isBetaFixed, bool isNuFixed, bool isRhoFixed, - bool vegaWeighted, - EndCriteria endCriteria = null, - OptimizationMethod method = null, - DayCounter dc = null, - double shift = 0.0) - : base(optionDate, dc, null, VolatilityType.ShiftedLognormal, shift) - { - forward_ = forward; - atmVolatility_ = atmVolatility; - volHandles_ = volHandles; - strikes_ = strikes; - actualStrikes_ = strikes; - hasFloatingStrikes_ = hasFloatingStrikes; - alpha_ = alpha; - beta_ = beta; - nu_ = nu; - rho_ = rho; - isAlphaFixed_ = isAlphaFixed; - isBetaFixed_ = isBetaFixed; - isNuFixed_ = isNuFixed; - isRhoFixed_ = isRhoFixed; - vegaWeighted_ = vegaWeighted; - endCriteria_ = endCriteria; - method_ = method; - - forward_.registerWith(update); - atmVolatility_.registerWith(update); - - for (int i = 0; i < volHandles_.Count; ++i) - volHandles_[i].registerWith(update); - } - - public SabrInterpolatedSmileSection( - Date optionDate, - double forward, - List strikes, - bool hasFloatingStrikes, - double atmVolatility, - List volHandles, - double alpha, double beta, double nu, double rho, - bool isAlphaFixed, bool isBetaFixed, bool isNuFixed, bool isRhoFixed, - bool vegaWeighted, - EndCriteria endCriteria = null, - OptimizationMethod method = null, - DayCounter dc = null, - double shift = 0.0) - : base(optionDate, dc, null, VolatilityType.ShiftedLognormal, shift) - { - forward_ = new Handle(new SimpleQuote(forward)); - atmVolatility_ = new Handle(new SimpleQuote(atmVolatility)); - strikes_ = strikes; - actualStrikes_ = strikes; - hasFloatingStrikes_ = hasFloatingStrikes; - vols_ = volHandles; - alpha_ = alpha; - beta_ = beta; - nu_ = nu; - rho_ = rho; - isAlphaFixed_ = isAlphaFixed; - isBetaFixed_ = isBetaFixed; - isNuFixed_ = isNuFixed; - isRhoFixed_ = isRhoFixed; - vegaWeighted_ = vegaWeighted; - endCriteria_ = endCriteria; - method_ = method; - - for (int i = 0; i < volHandles_.Count; ++i) - volHandles_[i] = new Handle(new SimpleQuote(volHandles[i])); - } - - - protected override void performCalculations() - { - forwardValue_ = forward_.link.value(); - vols_.Clear(); - actualStrikes_.Clear(); - // we populate the volatilities, skipping the invalid ones - for (int i = 0; i < volHandles_.Count; ++i) + public class SabrInterpolatedSmileSection : SmileSection + { + //! \name Constructors + //@{ + //! all market data are quotes + public SabrInterpolatedSmileSection( + Date optionDate, + Handle forward, + List strikes, + bool hasFloatingStrikes, + Handle atmVolatility, + List > volHandles, + double alpha, double beta, double nu, double rho, + bool isAlphaFixed, bool isBetaFixed, bool isNuFixed, bool isRhoFixed, + bool vegaWeighted, + EndCriteria endCriteria = null, + OptimizationMethod method = null, + DayCounter dc = null, + double shift = 0.0) + : base(optionDate, dc, null, VolatilityType.ShiftedLognormal, shift) + { + forward_ = forward; + atmVolatility_ = atmVolatility; + volHandles_ = volHandles; + strikes_ = strikes; + actualStrikes_ = strikes; + hasFloatingStrikes_ = hasFloatingStrikes; + alpha_ = alpha; + beta_ = beta; + nu_ = nu; + rho_ = rho; + isAlphaFixed_ = isAlphaFixed; + isBetaFixed_ = isBetaFixed; + isNuFixed_ = isNuFixed; + isRhoFixed_ = isRhoFixed; + vegaWeighted_ = vegaWeighted; + endCriteria_ = endCriteria; + method_ = method; + + forward_.registerWith(update); + atmVolatility_.registerWith(update); + + for (int i = 0; i < volHandles_.Count; ++i) + volHandles_[i].registerWith(update); + } + + public SabrInterpolatedSmileSection( + Date optionDate, + double forward, + List strikes, + bool hasFloatingStrikes, + double atmVolatility, + List volHandles, + double alpha, double beta, double nu, double rho, + bool isAlphaFixed, bool isBetaFixed, bool isNuFixed, bool isRhoFixed, + bool vegaWeighted, + EndCriteria endCriteria = null, + OptimizationMethod method = null, + DayCounter dc = null, + double shift = 0.0) + : base(optionDate, dc, null, VolatilityType.ShiftedLognormal, shift) + { + forward_ = new Handle(new SimpleQuote(forward)); + atmVolatility_ = new Handle(new SimpleQuote(atmVolatility)); + strikes_ = strikes; + actualStrikes_ = strikes; + hasFloatingStrikes_ = hasFloatingStrikes; + vols_ = volHandles; + alpha_ = alpha; + beta_ = beta; + nu_ = nu; + rho_ = rho; + isAlphaFixed_ = isAlphaFixed; + isBetaFixed_ = isBetaFixed; + isNuFixed_ = isNuFixed; + isRhoFixed_ = isRhoFixed; + vegaWeighted_ = vegaWeighted; + endCriteria_ = endCriteria; + method_ = method; + + for (int i = 0; i < volHandles_.Count; ++i) + volHandles_[i] = new Handle(new SimpleQuote(volHandles[i])); + } + + + protected override void performCalculations() + { + forwardValue_ = forward_.link.value(); + vols_.Clear(); + actualStrikes_.Clear(); + // we populate the volatilities, skipping the invalid ones + for (int i = 0; i < volHandles_.Count; ++i) + { + if (volHandles_[i].link.isValid()) { - if (volHandles_[i].link.isValid()) - { - if (hasFloatingStrikes_) - { - actualStrikes_.Add(forwardValue_ + strikes_[i]); - vols_.Add(atmVolatility_.link.value() + - volHandles_[i].link.value()); - } - else - { - actualStrikes_.Add(strikes_[i]); - vols_.Add(volHandles_[i].link.value()); - } - } + if (hasFloatingStrikes_) + { + actualStrikes_.Add(forwardValue_ + strikes_[i]); + vols_.Add(atmVolatility_.link.value() + + volHandles_[i].link.value()); + } + else + { + actualStrikes_.Add(strikes_[i]); + vols_.Add(volHandles_[i].link.value()); + } } - // we are recreating the sabrinterpolation object unconditionnaly to - // avoid iterator invalidation - createInterpolation(); - sabrInterpolation_.update(); - } - - - protected void createInterpolation() - { - SABRInterpolation tmp = new SABRInterpolation(actualStrikes_.Where(x => actualStrikes_.First().IsEqual(x)).ToList(), - actualStrikes_.Count, - vols_.Where(x => vols_.First().IsEqual(x)).ToList(), - exerciseTime(), forwardValue_, alpha_, beta_, nu_, rho_, isAlphaFixed_, - isBetaFixed_, isNuFixed_, isRhoFixed_, vegaWeighted_, - endCriteria_, method_, 0.0020, false, 50, shift()); - Utils.swap(ref tmp, ref sabrInterpolation_); - } - - protected override double varianceImpl(double strike) - { - calculate(); - double v = sabrInterpolation_.value(strike, true); - return v * v * exerciseTime(); - } - - protected override double volatilityImpl(double strike) - { - calculate(); - return sabrInterpolation_.value(strike, true); - } - public override double minStrike() { calculate(); return strikes_.First(); } - public override double maxStrike() { calculate(); return strikes_.Last(); } - public override double? atmLevel() { throw new NotImplementedException(); } - public override void update() { base.update(); } - - private List strikes_; - private List vols_; - - #region sabr - //! Svi parameters - private double alpha_, beta_, nu_, rho_; - //! Svi interpolation settings - bool isAlphaFixed_, isBetaFixed_, isNuFixed_, isRhoFixed_; - bool vegaWeighted_; - EndCriteria endCriteria_; - OptimizationMethod method_; - SABRInterpolation sabrInterpolation_; - - public double alpha() { calculate(); return alpha_; } - public double beta() { calculate(); return beta_; } - public double nu() { calculate(); return nu_; } - public double rho() { calculate(); return rho_; } - public double rmsError() { calculate(); return sabrInterpolation_.rmsError(); } - public double maxError() { calculate(); return sabrInterpolation_.maxError(); } - public EndCriteria.Type endCriteria() { calculate(); return sabrInterpolation_.endCriteria(); } - #endregion - - #region sabr smile section - protected Handle forward_; - protected Handle atmVolatility_; - protected List> volHandles_; - protected List actualStrikes_; - protected bool hasFloatingStrikes_; - protected double forwardValue_; - #endregion - } + } + // we are recreating the sabrinterpolation object unconditionnaly to + // avoid iterator invalidation + createInterpolation(); + sabrInterpolation_.update(); + } + + + protected void createInterpolation() + { + SABRInterpolation tmp = new SABRInterpolation(actualStrikes_.Where(x => actualStrikes_.First().IsEqual(x)).ToList(), + actualStrikes_.Count, + vols_.Where(x => vols_.First().IsEqual(x)).ToList(), + exerciseTime(), forwardValue_, alpha_, beta_, nu_, rho_, isAlphaFixed_, + isBetaFixed_, isNuFixed_, isRhoFixed_, vegaWeighted_, + endCriteria_, method_, 0.0020, false, 50, shift()); + Utils.swap(ref tmp, ref sabrInterpolation_); + } + + protected override double varianceImpl(double strike) + { + calculate(); + double v = sabrInterpolation_.value(strike, true); + return v * v * exerciseTime(); + } + + protected override double volatilityImpl(double strike) + { + calculate(); + return sabrInterpolation_.value(strike, true); + } + public override double minStrike() { calculate(); return strikes_.First(); } + public override double maxStrike() { calculate(); return strikes_.Last(); } + public override double? atmLevel() { throw new NotImplementedException(); } + public override void update() { base.update(); } + + private List strikes_; + private List vols_; + + #region sabr + //! Svi parameters + private double alpha_, beta_, nu_, rho_; + //! Svi interpolation settings + bool isAlphaFixed_, isBetaFixed_, isNuFixed_, isRhoFixed_; + bool vegaWeighted_; + EndCriteria endCriteria_; + OptimizationMethod method_; + SABRInterpolation sabrInterpolation_; + + public double alpha() { calculate(); return alpha_; } + public double beta() { calculate(); return beta_; } + public double nu() { calculate(); return nu_; } + public double rho() { calculate(); return rho_; } + public double rmsError() { calculate(); return sabrInterpolation_.rmsError(); } + public double maxError() { calculate(); return sabrInterpolation_.maxError(); } + public EndCriteria.Type endCriteria() { calculate(); return sabrInterpolation_.endCriteria(); } + #endregion + + #region sabr smile section + protected Handle forward_; + protected Handle atmVolatility_; + protected List> volHandles_; + protected List actualStrikes_; + protected bool hasFloatingStrikes_; + protected double forwardValue_; + #endregion + } } diff --git a/src/QLNet/Termstructures/Volatility/SmileSection.cs b/src/QLNet/Termstructures/Volatility/SmileSection.cs index 4f0c3e235..263c8210c 100644 --- a/src/QLNet/Termstructures/Volatility/SmileSection.cs +++ b/src/QLNet/Termstructures/Volatility/SmileSection.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,14 +20,14 @@ under the terms of the QLNet license. You should have received a using System; using System.Collections.Generic; -namespace QLNet +namespace QLNet { //! interest rate volatility smile section /*! This abstract class provides volatility smile section interface */ public abstract class SmileSection : LazyObject { - protected SmileSection( Date d, DayCounter dc = null, Date referenceDate = null, - VolatilityType type = VolatilityType.ShiftedLognormal, double shift = 0.0 ) + protected SmileSection(Date d, DayCounter dc = null, Date referenceDate = null, + VolatilityType type = VolatilityType.ShiftedLognormal, double shift = 0.0) { exerciseDate_ = d; dc_ = dc; @@ -35,9 +35,9 @@ protected SmileSection( Date d, DayCounter dc = null, Date referenceDate = null, shift_ = shift; isFloating_ = referenceDate == null; - if ( isFloating_ ) + if (isFloating_) { - Settings.registerWith( update ); + Settings.registerWith(update); referenceDate_ = Settings.evaluationDate(); } else @@ -45,8 +45,8 @@ protected SmileSection( Date d, DayCounter dc = null, Date referenceDate = null, initializeExerciseTime(); } - protected SmileSection( double exerciseTime, DayCounter dc = null, - VolatilityType type = VolatilityType.ShiftedLognormal, double shift = 0.0 ) + protected SmileSection(double exerciseTime, DayCounter dc = null, + VolatilityType type = VolatilityType.ShiftedLognormal, double shift = 0.0) { isFloating_ = false; referenceDate_ = null; @@ -55,7 +55,7 @@ protected SmileSection( double exerciseTime, DayCounter dc = null, volatilityType_ = type; shift_ = shift; - Utils.QL_REQUIRE( exerciseTime_ >= 0.0, () => "expiry time must be positive: " + exerciseTime_ + " not allowed" ); + Utils.QL_REQUIRE(exerciseTime_ >= 0.0, () => "expiry time must be positive: " + exerciseTime_ + " not allowed"); } protected SmileSection() { } @@ -63,7 +63,7 @@ protected SmileSection() { } public override void update() { - if ( isFloating_ ) + if (isFloating_) { referenceDate_ = Settings.evaluationDate(); initializeExerciseTime(); @@ -71,107 +71,107 @@ public override void update() } public abstract double minStrike(); public abstract double maxStrike(); - public double variance( double strike ) { return varianceImpl( strike ); } - public double volatility( double strike ) { return volatilityImpl( strike ); } + public double variance(double strike) { return varianceImpl(strike); } + public double volatility(double strike) { return volatilityImpl(strike); } public abstract double? atmLevel(); public virtual Date exerciseDate() { return exerciseDate_; } public virtual VolatilityType volatilityType() { return volatilityType_; } public virtual double shift() { return shift_; } public virtual Date referenceDate() { - Utils.QL_REQUIRE( referenceDate_ != null, () => "referenceDate not available for this instance" ); + Utils.QL_REQUIRE(referenceDate_ != null, () => "referenceDate not available for this instance"); return referenceDate_; } public virtual double exerciseTime() { return exerciseTime_; } public virtual DayCounter dayCounter() { return dc_; } - public virtual double optionPrice( double strike, Option.Type type = Option.Type.Call, double discount = 1.0 ) + public virtual double optionPrice(double strike, Option.Type type = Option.Type.Call, double discount = 1.0) { double? atm = atmLevel(); - Utils.QL_REQUIRE( atm != null, () => "smile section must provide atm level to compute option price" ); + Utils.QL_REQUIRE(atm != null, () => "smile section must provide atm level to compute option price"); // if lognormal or shifted lognormal, // for strike at -shift, return option price even if outside // minstrike, maxstrike interval - if ( volatilityType() == VolatilityType.ShiftedLognormal ) - return Utils.blackFormula( type, strike, atm.Value, Math.Abs( strike + shift() ) < Const.QL_EPSILON ? - 0.2 : Math.Sqrt( variance( strike ) ), discount, shift() ); + if (volatilityType() == VolatilityType.ShiftedLognormal) + return Utils.blackFormula(type, strike, atm.Value, Math.Abs(strike + shift()) < Const.QL_EPSILON ? + 0.2 : Math.Sqrt(variance(strike)), discount, shift()); else - return Utils.bachelierBlackFormula( type, strike, atm.Value, Math.Sqrt( variance( strike ) ), discount ); + return Utils.bachelierBlackFormula(type, strike, atm.Value, Math.Sqrt(variance(strike)), discount); } - public virtual double digitalOptionPrice( double strike, Option.Type type = Option.Type.Call, double discount = 1.0, - double gap = 1.0e-5 ) + public virtual double digitalOptionPrice(double strike, Option.Type type = Option.Type.Call, double discount = 1.0, + double gap = 1.0e-5) { double m = volatilityType() == VolatilityType.ShiftedLognormal ? -shift() : -double.MaxValue; - double kl = Math.Max( strike - gap / 2.0, m ); + double kl = Math.Max(strike - gap / 2.0, m); double kr = kl + gap; - return ( type == Option.Type.Call ? 1.0 : -1.0 ) * - ( optionPrice( kl, type, discount ) - optionPrice( kr, type, discount ) ) / gap; + return (type == Option.Type.Call ? 1.0 : -1.0) * + (optionPrice(kl, type, discount) - optionPrice(kr, type, discount)) / gap; } - public virtual double vega( double strike, double discount = 1.0 ) + public virtual double vega(double strike, double discount = 1.0) { double? atm = atmLevel(); - Utils.QL_REQUIRE( atm != null, () => - "smile section must provide atm level to compute option vega" ); - if ( volatilityType() == VolatilityType.ShiftedLognormal ) - return Utils.blackFormulaVolDerivative( strike, atmLevel().Value, - Math.Sqrt( variance( strike ) ), - exerciseTime(), discount, shift() ) * 0.01; + Utils.QL_REQUIRE(atm != null, () => + "smile section must provide atm level to compute option vega"); + if (volatilityType() == VolatilityType.ShiftedLognormal) + return Utils.blackFormulaVolDerivative(strike, atmLevel().Value, + Math.Sqrt(variance(strike)), + exerciseTime(), discount, shift()) * 0.01; else - Utils.QL_FAIL( "vega for normal smilesection not yet implemented" ); + Utils.QL_FAIL("vega for normal smilesection not yet implemented"); return 0; } - public virtual double density( double strike, double discount = 1.0, double gap = 1.0E-4 ) + public virtual double density(double strike, double discount = 1.0, double gap = 1.0E-4) { double m = volatilityType() == VolatilityType.ShiftedLognormal ? -shift() : -double.MaxValue; - double kl = Math.Max( strike - gap / 2.0, m ); + double kl = Math.Max(strike - gap / 2.0, m); double kr = kl + gap; - return ( digitalOptionPrice( kl, Option.Type.Call, discount, gap ) - - digitalOptionPrice( kr, Option.Type.Call, discount, gap ) ) / gap; + return (digitalOptionPrice(kl, Option.Type.Call, discount, gap) - + digitalOptionPrice(kr, Option.Type.Call, discount, gap)) / gap; } - public double volatility( double strike, VolatilityType volatilityType, double shift = 0.0 ) + public double volatility(double strike, VolatilityType volatilityType, double shift = 0.0) { - if ( volatilityType == volatilityType_ && Utils.close( shift, this.shift() ) ) - return volatility( strike ); + if (volatilityType == volatilityType_ && Utils.close(shift, this.shift())) + return volatility(strike); double? atm = atmLevel(); - Utils.QL_REQUIRE( atm != null, () => "smile section must provide atm level to compute converted volatilties" ); + Utils.QL_REQUIRE(atm != null, () => "smile section must provide atm level to compute converted volatilties"); Option.Type type = strike >= atm ? Option.Type.Call : Option.Type.Put; - double premium = optionPrice( strike, type ); - double premiumAtm = optionPrice( atm.Value, type ); - if ( volatilityType == VolatilityType.ShiftedLognormal ) + double premium = optionPrice(strike, type); + double premiumAtm = optionPrice(atm.Value, type); + if (volatilityType == VolatilityType.ShiftedLognormal) { try { - return Utils.blackFormulaImpliedStdDev( type, strike, atm.Value, premium, 1.0, shift ) / - Math.Sqrt( exerciseTime() ); + return Utils.blackFormulaImpliedStdDev(type, strike, atm.Value, premium, 1.0, shift) / + Math.Sqrt(exerciseTime()); } - catch ( Exception ) + catch (Exception) { - return Utils.blackFormulaImpliedStdDevChambers( type, strike, atm.Value, premium, premiumAtm, 1.0, shift ) / - Math.Sqrt( exerciseTime() ); + return Utils.blackFormulaImpliedStdDevChambers(type, strike, atm.Value, premium, premiumAtm, 1.0, shift) / + Math.Sqrt(exerciseTime()); } } else { - return Utils.bachelierBlackFormulaImpliedVol( type, strike, atm.Value, exerciseTime(), premium ); + return Utils.bachelierBlackFormulaImpliedVol(type, strike, atm.Value, exerciseTime(), premium); } } protected virtual void initializeExerciseTime() { - Utils.QL_REQUIRE( exerciseDate_ >= referenceDate_, () => - "expiry date (" + exerciseDate_ + - ") must be greater than reference date (" + - referenceDate_ + ")" ); - exerciseTime_ = dc_.yearFraction( referenceDate_, exerciseDate_ ); + Utils.QL_REQUIRE(exerciseDate_ >= referenceDate_, () => + "expiry date (" + exerciseDate_ + + ") must be greater than reference date (" + + referenceDate_ + ")"); + exerciseTime_ = dc_.yearFraction(referenceDate_, exerciseDate_); } - protected virtual double varianceImpl( double strike ) + protected virtual double varianceImpl(double strike) { - double v = volatilityImpl( strike ); + double v = volatilityImpl(strike); return v * v * exerciseTime(); } - protected abstract double volatilityImpl( double strike ); + protected abstract double volatilityImpl(double strike); private bool isFloating_; @@ -182,63 +182,67 @@ protected virtual double varianceImpl( double strike ) private VolatilityType volatilityType_; private double shift_; } - public class SabrSmileSection : SmileSection { - private double alpha_, beta_, nu_, rho_, forward_, shift_; - private VolatilityType volatilityType_; - - public SabrSmileSection(double timeToExpiry, double forward, List sabrParams, VolatilityType volatilityType = VolatilityType.ShiftedLognormal, double shift = 0.0) - : base(timeToExpiry, null, volatilityType, shift) { - forward_ = forward; - shift_ = shift; - volatilityType_ = volatilityType; - - alpha_ = sabrParams[0]; - beta_ = sabrParams[1]; - nu_ = sabrParams[2]; - rho_ = sabrParams[3]; - - Utils.QL_REQUIRE(volatilityType == VolatilityType.Normal || forward_ + shift_ > 0.0, () => "at the money forward rate + shift must be: " + forward_ + shift_ + " not allowed"); - Utils.validateSabrParameters(alpha_, beta_, nu_, rho_); - } - - public SabrSmileSection(Date d, double forward, List sabrParams, DayCounter dc = null, VolatilityType volatilityType = VolatilityType.ShiftedLognormal, double shift = 0.0) - : base(d, dc ?? new Actual365Fixed(), null, volatilityType, shift) - { - forward_ = forward; - shift_ = shift; - volatilityType_ = volatilityType; - - alpha_ = sabrParams[0]; - beta_ = sabrParams[1]; - nu_ = sabrParams[2]; - rho_ = sabrParams[3]; - - Utils.QL_REQUIRE(volatilityType == VolatilityType.Normal || forward_ + shift_ > 0.0, () => "at the money forward rate +shift must be: " + forward_ + shift_ + " not allowed"); - Utils.validateSabrParameters(alpha_, beta_, nu_, rho_); - } - - public override double minStrike () { return 0.0; } - public override double maxStrike() { return double.MaxValue; } - public override double? atmLevel() { return forward_; } - - protected override double varianceImpl(double strike) { - double vol; - if (volatilityType_ == VolatilityType.ShiftedLognormal) - vol = Utils.shiftedSabrVolatility(strike, forward_, exerciseTime(), alpha_, beta_, nu_, rho_, shift_); - else - vol = Utils.shiftedSabrNormalVolatility(strike, forward_, exerciseTime(), alpha_, beta_, nu_, rho_, shift_); - - return vol*vol*exerciseTime(); - } + public class SabrSmileSection : SmileSection + { + private double alpha_, beta_, nu_, rho_, forward_, shift_; + private VolatilityType volatilityType_; - protected override double volatilityImpl(double strike) { - double vol; - if (volatilityType_ == VolatilityType.ShiftedLognormal) - vol = Utils.shiftedSabrVolatility(strike, forward_, exerciseTime(), alpha_, beta_, nu_, rho_, shift_); - else - vol = Utils.shiftedSabrNormalVolatility(strike, forward_, exerciseTime(), alpha_, beta_, nu_, rho_, shift_); - - return vol; - } - } + public SabrSmileSection(double timeToExpiry, double forward, List sabrParams, VolatilityType volatilityType = VolatilityType.ShiftedLognormal, double shift = 0.0) + : base(timeToExpiry, null, volatilityType, shift) + { + forward_ = forward; + shift_ = shift; + volatilityType_ = volatilityType; + + alpha_ = sabrParams[0]; + beta_ = sabrParams[1]; + nu_ = sabrParams[2]; + rho_ = sabrParams[3]; + + Utils.QL_REQUIRE(volatilityType == VolatilityType.Normal || forward_ + shift_ > 0.0, () => "at the money forward rate + shift must be: " + forward_ + shift_ + " not allowed"); + Utils.validateSabrParameters(alpha_, beta_, nu_, rho_); + } + + public SabrSmileSection(Date d, double forward, List sabrParams, DayCounter dc = null, VolatilityType volatilityType = VolatilityType.ShiftedLognormal, double shift = 0.0) + : base(d, dc ?? new Actual365Fixed(), null, volatilityType, shift) + { + forward_ = forward; + shift_ = shift; + volatilityType_ = volatilityType; + + alpha_ = sabrParams[0]; + beta_ = sabrParams[1]; + nu_ = sabrParams[2]; + rho_ = sabrParams[3]; + + Utils.QL_REQUIRE(volatilityType == VolatilityType.Normal || forward_ + shift_ > 0.0, () => "at the money forward rate +shift must be: " + forward_ + shift_ + " not allowed"); + Utils.validateSabrParameters(alpha_, beta_, nu_, rho_); + } + + public override double minStrike() { return 0.0; } + public override double maxStrike() { return double.MaxValue; } + public override double? atmLevel() { return forward_; } + + protected override double varianceImpl(double strike) + { + double vol; + if (volatilityType_ == VolatilityType.ShiftedLognormal) + vol = Utils.shiftedSabrVolatility(strike, forward_, exerciseTime(), alpha_, beta_, nu_, rho_, shift_); + else + vol = Utils.shiftedSabrNormalVolatility(strike, forward_, exerciseTime(), alpha_, beta_, nu_, rho_, shift_); + + return vol * vol * exerciseTime(); + } + + protected override double volatilityImpl(double strike) + { + double vol; + if (volatilityType_ == VolatilityType.ShiftedLognormal) + vol = Utils.shiftedSabrVolatility(strike, forward_, exerciseTime(), alpha_, beta_, nu_, rho_, shift_); + else + vol = Utils.shiftedSabrNormalVolatility(strike, forward_, exerciseTime(), alpha_, beta_, nu_, rho_, shift_); + + return vol; + } + } } diff --git a/src/QLNet/Termstructures/Volatility/SpreadedSmileSection.cs b/src/QLNet/Termstructures/Volatility/SpreadedSmileSection.cs index 69dd61059..6fc536f0d 100644 --- a/src/QLNet/Termstructures/Volatility/SpreadedSmileSection.cs +++ b/src/QLNet/Termstructures/Volatility/SpreadedSmileSection.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,7 +22,7 @@ namespace QLNet { public class SpreadedSmileSection : SmileSection { - public SpreadedSmileSection(SmileSection underlyingSection,Handle spread) + public SpreadedSmileSection(SmileSection underlyingSection, Handle spread) { underlyingSection_ = underlyingSection; spread_ = spread; @@ -44,9 +44,9 @@ public SpreadedSmileSection(SmileSection underlyingSection,Handle spread) // LazyObject interface public override void update() { notifyObservers(); } - protected override double volatilityImpl( double k ) + protected override double volatilityImpl(double k) { - return underlyingSection_.volatility( k ) + spread_.link.value(); + return underlyingSection_.volatility(k) + spread_.link.value(); } private SmileSection underlyingSection_; private Handle spread_; diff --git a/src/QLNet/Termstructures/Volatility/Svi.cs b/src/QLNet/Termstructures/Volatility/Svi.cs index 0ece5a00a..7bd76446a 100644 --- a/src/QLNet/Termstructures/Volatility/Svi.cs +++ b/src/QLNet/Termstructures/Volatility/Svi.cs @@ -2,57 +2,57 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace QLNet -{ - public partial class Utils - { - public static void checkSviParameters(double a, double b, double sigma, double rho, double m) - { - Utils.QL_REQUIRE(b >= 0.0, () => "b (" + b + ") must be non negative"); - Utils.QL_REQUIRE(Math.Abs(rho) < 1.0, () => "rho (" + rho + ") must be in (-1,1)"); - Utils.QL_REQUIRE(sigma > 0.0, () => "sigma (" + sigma + ") must be positive"); - Utils.QL_REQUIRE(a + b * sigma * Math.Sqrt(1.0 - rho * rho) >= 0.0, - () => "a + b sigma sqrt(1-rho^2) (a=" + a + ", b=" + b + ", sigma=" - + sigma + ", rho=" + rho - + ") must be non negative"); - Utils.QL_REQUIRE(b * (1.0 + Math.Abs(rho)) < 4.0, - () => "b(1+|rho|) must be less than 4"); - return; - } - - public static double sviTotalVariance(double a, double b, double sigma, double rho, double m, double k) - { - return a + b * (rho * (k - m) + Math.Sqrt((k - m) * (k - m) + sigma * sigma)); - } - - public static double sviVolatility(double strike, double forward, double expiryTime, List param) - { - List params_ = new List(); - foreach(double? x in param) - params_.Add(x.Value); - - SviSmileSection sms = new SviSmileSection(expiryTime, forward, params_); - return sms.volatility(strike); - } - } -} +*/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QLNet +{ + public partial class Utils + { + public static void checkSviParameters(double a, double b, double sigma, double rho, double m) + { + Utils.QL_REQUIRE(b >= 0.0, () => "b (" + b + ") must be non negative"); + Utils.QL_REQUIRE(Math.Abs(rho) < 1.0, () => "rho (" + rho + ") must be in (-1,1)"); + Utils.QL_REQUIRE(sigma > 0.0, () => "sigma (" + sigma + ") must be positive"); + Utils.QL_REQUIRE(a + b * sigma * Math.Sqrt(1.0 - rho * rho) >= 0.0, + () => "a + b sigma sqrt(1-rho^2) (a=" + a + ", b=" + b + ", sigma=" + + sigma + ", rho=" + rho + + ") must be non negative"); + Utils.QL_REQUIRE(b * (1.0 + Math.Abs(rho)) < 4.0, + () => "b(1+|rho|) must be less than 4"); + return; + } + + public static double sviTotalVariance(double a, double b, double sigma, double rho, double m, double k) + { + return a + b * (rho * (k - m) + Math.Sqrt((k - m) * (k - m) + sigma* sigma)); + } + + public static double sviVolatility(double strike, double forward, double expiryTime, List param) + { + List params_ = new List(); + foreach (double? x in param) + params_.Add(x.Value); + + SviSmileSection sms = new SviSmileSection(expiryTime, forward, params_); + return sms.volatility(strike); + } + } +} diff --git a/src/QLNet/Termstructures/Volatility/SviInterpolatedSmileSection.cs b/src/QLNet/Termstructures/Volatility/SviInterpolatedSmileSection.cs index 1afbbdb23..1f79d0191 100644 --- a/src/QLNet/Termstructures/Volatility/SviInterpolatedSmileSection.cs +++ b/src/QLNet/Termstructures/Volatility/SviInterpolatedSmileSection.cs @@ -1,16 +1,16 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) // 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,181 +21,181 @@ namespace QLNet { - public class SviInterpolatedSmileSection : SmileSection - { - //! \name Constructors - //@{ - //! all market data are quotes - public SviInterpolatedSmileSection( - Date optionDate, - Handle forward, - List strikes, - bool hasFloatingStrikes, - Handle atmVolatility, - List > volHandles, - double a, double b, double sigma, double rho, double m, - bool isAFixed, bool isBFixed, bool isSigmaFixed, bool isRhoFixed, bool isMFixed, - bool vegaWeighted, - EndCriteria endCriteria = null, - OptimizationMethod method = null, - DayCounter dc = null) - : base(optionDate, dc) - { - forward_ = forward; - atmVolatility_ = atmVolatility; - volHandles_ = volHandles; - strikes_ = strikes; - actualStrikes_ = strikes; - hasFloatingStrikes_ = hasFloatingStrikes; - a_ = a; - b_ = b; - sigma_ = sigma; - rho_ = rho; - m_ = m; - isAFixed_ = isAFixed; - isBFixed_ = isBFixed; - isSigmaFixed_ = isSigmaFixed; - isRhoFixed_ = isRhoFixed; - isMFixed_ = isMFixed; - vegaWeighted_ = vegaWeighted; - endCriteria_ = endCriteria; - method_ = method; - - forward_.registerWith(update); - atmVolatility_.registerWith(update); - - for (int i = 0; i < volHandles_.Count; ++i) - volHandles_[i].registerWith(update); - } - - public SviInterpolatedSmileSection( - Date optionDate, - double forward, - List strikes, - bool hasFloatingStrikes, - double atmVolatility, - List volHandles, - double a, double b, double sigma, double rho, double m, - bool isAFixed, bool isBFixed, bool isSigmaFixed, bool isRhoFixed, bool isMFixed, - bool vegaWeighted, - EndCriteria endCriteria = null, - OptimizationMethod method = null, - DayCounter dc = null) - : base(optionDate, dc) - { - forward_ = new Handle(new SimpleQuote(forward)); - atmVolatility_ = new Handle(new SimpleQuote(atmVolatility)); - strikes_ = strikes; - actualStrikes_ = strikes; - hasFloatingStrikes_ = hasFloatingStrikes; - vols_ = volHandles; - a_ = a; - b_ = b; - sigma_ = sigma; - rho_ = rho; - m_ = m; - isAFixed_ = isAFixed; - isBFixed_ = isBFixed; - isSigmaFixed_ = isSigmaFixed; - isRhoFixed_ = isRhoFixed; - isMFixed_ = isMFixed; - vegaWeighted_ = vegaWeighted; - endCriteria_ = endCriteria; - method_ = method; - - for (int i = 0; i < volHandles_.Count; ++i) - volHandles_[i] = new Handle(new SimpleQuote(volHandles[i])); - } - - - protected override void performCalculations() - { - forwardValue_ = forward_.link.value(); - vols_.Clear(); - actualStrikes_.Clear(); - // we populate the volatilities, skipping the invalid ones - for (int i = 0; i < volHandles_.Count; ++i) + public class SviInterpolatedSmileSection : SmileSection + { + //! \name Constructors + //@{ + //! all market data are quotes + public SviInterpolatedSmileSection( + Date optionDate, + Handle forward, + List strikes, + bool hasFloatingStrikes, + Handle atmVolatility, + List > volHandles, + double a, double b, double sigma, double rho, double m, + bool isAFixed, bool isBFixed, bool isSigmaFixed, bool isRhoFixed, bool isMFixed, + bool vegaWeighted, + EndCriteria endCriteria = null, + OptimizationMethod method = null, + DayCounter dc = null) + : base(optionDate, dc) + { + forward_ = forward; + atmVolatility_ = atmVolatility; + volHandles_ = volHandles; + strikes_ = strikes; + actualStrikes_ = strikes; + hasFloatingStrikes_ = hasFloatingStrikes; + a_ = a; + b_ = b; + sigma_ = sigma; + rho_ = rho; + m_ = m; + isAFixed_ = isAFixed; + isBFixed_ = isBFixed; + isSigmaFixed_ = isSigmaFixed; + isRhoFixed_ = isRhoFixed; + isMFixed_ = isMFixed; + vegaWeighted_ = vegaWeighted; + endCriteria_ = endCriteria; + method_ = method; + + forward_.registerWith(update); + atmVolatility_.registerWith(update); + + for (int i = 0; i < volHandles_.Count; ++i) + volHandles_[i].registerWith(update); + } + + public SviInterpolatedSmileSection( + Date optionDate, + double forward, + List strikes, + bool hasFloatingStrikes, + double atmVolatility, + List volHandles, + double a, double b, double sigma, double rho, double m, + bool isAFixed, bool isBFixed, bool isSigmaFixed, bool isRhoFixed, bool isMFixed, + bool vegaWeighted, + EndCriteria endCriteria = null, + OptimizationMethod method = null, + DayCounter dc = null) + : base(optionDate, dc) + { + forward_ = new Handle(new SimpleQuote(forward)); + atmVolatility_ = new Handle(new SimpleQuote(atmVolatility)); + strikes_ = strikes; + actualStrikes_ = strikes; + hasFloatingStrikes_ = hasFloatingStrikes; + vols_ = volHandles; + a_ = a; + b_ = b; + sigma_ = sigma; + rho_ = rho; + m_ = m; + isAFixed_ = isAFixed; + isBFixed_ = isBFixed; + isSigmaFixed_ = isSigmaFixed; + isRhoFixed_ = isRhoFixed; + isMFixed_ = isMFixed; + vegaWeighted_ = vegaWeighted; + endCriteria_ = endCriteria; + method_ = method; + + for (int i = 0; i < volHandles_.Count; ++i) + volHandles_[i] = new Handle(new SimpleQuote(volHandles[i])); + } + + + protected override void performCalculations() + { + forwardValue_ = forward_.link.value(); + vols_.Clear(); + actualStrikes_.Clear(); + // we populate the volatilities, skipping the invalid ones + for (int i = 0; i < volHandles_.Count; ++i) + { + if (volHandles_[i].link.isValid()) { - if (volHandles_[i].link.isValid()) - { - if (hasFloatingStrikes_) - { - actualStrikes_.Add(forwardValue_ + strikes_[i]); - vols_.Add(atmVolatility_.link.value() + - volHandles_[i].link.value()); - } - else - { - actualStrikes_.Add(strikes_[i]); - vols_.Add(volHandles_[i].link.value()); - } - } + if (hasFloatingStrikes_) + { + actualStrikes_.Add(forwardValue_ + strikes_[i]); + vols_.Add(atmVolatility_.link.value() + + volHandles_[i].link.value()); + } + else + { + actualStrikes_.Add(strikes_[i]); + vols_.Add(volHandles_[i].link.value()); + } } - // we are recreating the sabrinterpolation object unconditionnaly to - // avoid iterator invalidation - createInterpolation(); - sviInterpolation_.update(); - } - - - protected void createInterpolation() - { - SviInterpolation tmp = new SviInterpolation(actualStrikes_.Where(x => actualStrikes_.First().IsEqual(x)).ToList(), - actualStrikes_.Count, - vols_.Where(x => vols_.First().IsEqual(x)).ToList(), - exerciseTime(), forwardValue_, a_, b_, sigma_, rho_, m_, isAFixed_, - isBFixed_, isSigmaFixed_, isRhoFixed_, isMFixed_, vegaWeighted_, - endCriteria_, method_); - Utils.swap(ref tmp, ref sviInterpolation_); - } - - protected override double varianceImpl(double strike) - { - calculate(); - double v = sviInterpolation_.value(strike, true); - return v * v * exerciseTime(); - } - - protected override double volatilityImpl(double strike) - { - calculate(); - return sviInterpolation_.value(strike, true); - } - public override double minStrike() { calculate(); return strikes_.First(); } - public override double maxStrike() { calculate(); return strikes_.Last(); } - public override double? atmLevel() { throw new NotImplementedException(); } - public override void update() { base.update(); } - - private List strikes_; - private List vols_; - - #region svi - //! Svi parameters - private double a_, b_, sigma_, rho_, m_; - //! Svi interpolation settings - bool isAFixed_, isBFixed_, isSigmaFixed_, isRhoFixed_, isMFixed_; - bool vegaWeighted_; - EndCriteria endCriteria_; - OptimizationMethod method_; - SviInterpolation sviInterpolation_; - - public double a() { calculate(); return a_; } - public double b() { calculate(); return b_; } - public double sigma() { calculate(); return sigma_; } - public double rho() { calculate(); return rho_; } - public double m() { calculate(); return m_; } - public double rmsError() { calculate(); return sviInterpolation_.rmsError(); } - public double maxError() { calculate(); return sviInterpolation_.maxError(); } - public EndCriteria.Type endCriteria() { calculate(); return sviInterpolation_.endCriteria(); } - #endregion - - #region svi smile section - protected Handle forward_; - protected Handle atmVolatility_; - protected List> volHandles_; - protected List actualStrikes_; - protected bool hasFloatingStrikes_; - protected double forwardValue_; - #endregion - } + } + // we are recreating the sabrinterpolation object unconditionnaly to + // avoid iterator invalidation + createInterpolation(); + sviInterpolation_.update(); + } + + + protected void createInterpolation() + { + SviInterpolation tmp = new SviInterpolation(actualStrikes_.Where(x => actualStrikes_.First().IsEqual(x)).ToList(), + actualStrikes_.Count, + vols_.Where(x => vols_.First().IsEqual(x)).ToList(), + exerciseTime(), forwardValue_, a_, b_, sigma_, rho_, m_, isAFixed_, + isBFixed_, isSigmaFixed_, isRhoFixed_, isMFixed_, vegaWeighted_, + endCriteria_, method_); + Utils.swap(ref tmp, ref sviInterpolation_); + } + + protected override double varianceImpl(double strike) + { + calculate(); + double v = sviInterpolation_.value(strike, true); + return v * v * exerciseTime(); + } + + protected override double volatilityImpl(double strike) + { + calculate(); + return sviInterpolation_.value(strike, true); + } + public override double minStrike() { calculate(); return strikes_.First(); } + public override double maxStrike() { calculate(); return strikes_.Last(); } + public override double? atmLevel() { throw new NotImplementedException(); } + public override void update() { base.update(); } + + private List strikes_; + private List vols_; + + #region svi + //! Svi parameters + private double a_, b_, sigma_, rho_, m_; + //! Svi interpolation settings + bool isAFixed_, isBFixed_, isSigmaFixed_, isRhoFixed_, isMFixed_; + bool vegaWeighted_; + EndCriteria endCriteria_; + OptimizationMethod method_; + SviInterpolation sviInterpolation_; + + public double a() { calculate(); return a_; } + public double b() { calculate(); return b_; } + public double sigma() { calculate(); return sigma_; } + public double rho() { calculate(); return rho_; } + public double m() { calculate(); return m_; } + public double rmsError() { calculate(); return sviInterpolation_.rmsError(); } + public double maxError() { calculate(); return sviInterpolation_.maxError(); } + public EndCriteria.Type endCriteria() { calculate(); return sviInterpolation_.endCriteria(); } + #endregion + + #region svi smile section + protected Handle forward_; + protected Handle atmVolatility_; + protected List> volHandles_; + protected List actualStrikes_; + protected bool hasFloatingStrikes_; + protected double forwardValue_; + #endregion + } } diff --git a/src/QLNet/Termstructures/Volatility/SviSmileSection.cs b/src/QLNet/Termstructures/Volatility/SviSmileSection.cs index f95f8e7ba..24c1b9cb0 100644 --- a/src/QLNet/Termstructures/Volatility/SviSmileSection.cs +++ b/src/QLNet/Termstructures/Volatility/SviSmileSection.cs @@ -1,16 +1,16 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) // 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,50 +21,50 @@ namespace QLNet { - public class SviSmileSection : SmileSection - { - public SviSmileSection(double timeToExpiry, double forward, - List sviParameters) - : base(timeToExpiry, null) - { - forward_ = forward; - param_ = sviParameters; - init(); - } + public class SviSmileSection : SmileSection + { + public SviSmileSection(double timeToExpiry, double forward, + List sviParameters) + : base(timeToExpiry, null) + { + forward_ = forward; + param_ = sviParameters; + init(); + } - public SviSmileSection(Date d, double forward, - List sviParameters, - DayCounter dc = null) - : base(d, dc) - { - forward_ = forward; - param_ = sviParameters; - init(); - } + public SviSmileSection(Date d, double forward, + List sviParameters, + DayCounter dc = null) + : base(d, dc) + { + forward_ = forward; + param_ = sviParameters; + init(); + } - protected override double volatilityImpl(double strike) - { - double k = Math.Log(Math.Max(strike, 1E-6) / forward_); - double totalVariance = Utils.sviTotalVariance(param_[0], param_[1], param_[2], - param_[3], param_[4], k); - return Math.Sqrt(Math.Max(0.0, totalVariance / exerciseTime())); - } - public override double minStrike() { return 0.0; } - public override double maxStrike() { return Double.MaxValue; } - public override double? atmLevel() { return forward_; } + protected override double volatilityImpl(double strike) + { + double k = Math.Log(Math.Max(strike, 1E-6) / forward_); + double totalVariance = Utils.sviTotalVariance(param_[0], param_[1], param_[2], + param_[3], param_[4], k); + return Math.Sqrt(Math.Max(0.0, totalVariance / exerciseTime())); + } + public override double minStrike() { return 0.0; } + public override double maxStrike() { return Double.MaxValue; } + public override double? atmLevel() { return forward_; } - #region svi smile section - protected double forward_; - protected List param_; - public void init() - { - Utils.QL_REQUIRE(param_.Count == 5, - () => "svi expects 5 parameters (a,b,sigma,rho,s,m) but (" - + param_.Count + ") given"); - - Utils.checkSviParameters(param_[0], param_[1], param_[2], param_[3], param_[4]); - return; - } - #endregion - } + #region svi smile section + protected double forward_; + protected List param_; + public void init() + { + Utils.QL_REQUIRE(param_.Count == 5, + () => "svi expects 5 parameters (a,b,sigma,rho,s,m) but (" + + param_.Count + ") given"); + + Utils.checkSviParameters(param_[0], param_[1], param_[2], param_[3], param_[4]); + return; + } + #endregion + } } diff --git a/src/QLNet/Termstructures/Volatility/equityfx/BlackConstantVol.cs b/src/QLNet/Termstructures/Volatility/equityfx/BlackConstantVol.cs index 70047f64c..d1d0f17c9 100644 --- a/src/QLNet/Termstructures/Volatility/equityfx/BlackConstantVol.cs +++ b/src/QLNet/Termstructures/Volatility/equityfx/BlackConstantVol.cs @@ -1,59 +1,65 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { - //! Constant Black volatility, no time-strike dependence - /*! This class implements the BlackVolatilityTermStructure interface for a constant Black volatility (no time/strike - dependence). */ - public class BlackConstantVol : BlackVolatilityTermStructure { - private Handle volatility_; +namespace QLNet +{ + //! Constant Black volatility, no time-strike dependence + /*! This class implements the BlackVolatilityTermStructure interface for a constant Black volatility (no time/strike + dependence). */ + public class BlackConstantVol : BlackVolatilityTermStructure + { + private Handle volatility_; - public BlackConstantVol(Date referenceDate, Calendar cal, double volatility, DayCounter dc) - : base(referenceDate, cal, BusinessDayConvention.Following, dc) { - volatility_ = new Handle(new SimpleQuote(volatility)); - } + public BlackConstantVol(Date referenceDate, Calendar cal, double volatility, DayCounter dc) + : base(referenceDate, cal, BusinessDayConvention.Following, dc) + { + volatility_ = new Handle(new SimpleQuote(volatility)); + } - public BlackConstantVol(Date referenceDate, Calendar cal, Handle volatility, DayCounter dc) - : base(referenceDate, cal, BusinessDayConvention.Following, dc) { - volatility_ = volatility; + public BlackConstantVol(Date referenceDate, Calendar cal, Handle volatility, DayCounter dc) + : base(referenceDate, cal, BusinessDayConvention.Following, dc) + { + volatility_ = volatility; - volatility_.registerWith(update); - } + volatility_.registerWith(update); + } - public BlackConstantVol(int settlementDays, Calendar cal, double volatility, DayCounter dc) - : base(settlementDays, cal, BusinessDayConvention.Following, dc) { - volatility_ = new Handle(new SimpleQuote(volatility)); - } + public BlackConstantVol(int settlementDays, Calendar cal, double volatility, DayCounter dc) + : base(settlementDays, cal, BusinessDayConvention.Following, dc) + { + volatility_ = new Handle(new SimpleQuote(volatility)); + } - public BlackConstantVol(int settlementDays, Calendar cal, Handle volatility, DayCounter dc) - : base(settlementDays, cal, BusinessDayConvention.Following, dc) { - volatility_ = volatility; + public BlackConstantVol(int settlementDays, Calendar cal, Handle volatility, DayCounter dc) + : base(settlementDays, cal, BusinessDayConvention.Following, dc) + { + volatility_ = volatility; - volatility_.registerWith(update); - } + volatility_.registerWith(update); + } - public override Date maxDate() { return Date.maxDate(); } - public override double minStrike() { return double.MinValue; } - public override double maxStrike() { return double.MaxValue; } + public override Date maxDate() { return Date.maxDate(); } + public override double minStrike() { return double.MinValue; } + public override double maxStrike() { return double.MaxValue; } - protected override double blackVolImpl(double t, double x) { return volatility_.link.value(); } - } + protected override double blackVolImpl(double t, double x) { return volatility_.link.value(); } + } } diff --git a/src/QLNet/Termstructures/Volatility/equityfx/BlackVarianceCurve.cs b/src/QLNet/Termstructures/Volatility/equityfx/BlackVarianceCurve.cs index ed8deb1e9..421f50f8b 100644 --- a/src/QLNet/Termstructures/Volatility/equityfx/BlackVarianceCurve.cs +++ b/src/QLNet/Termstructures/Volatility/equityfx/BlackVarianceCurve.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,81 +20,91 @@ under the terms of the QLNet license. You should have received a using System.Collections.Generic; using System.Linq; -namespace QLNet { - //! Black volatility curve modelled as variance curve - /*! This class calculates time-dependent Black volatilities using - as input a vector of (ATM) Black volatilities observed in the - market. - - The calculation is performed interpolating on the variance curve. - Linear interpolation is used as default; this can be changed - by the setInterpolation() method. - - For strike dependence, see BlackVarianceSurface. - - \todo check time extrapolation - - */ - public class BlackVarianceCurve : BlackVarianceTermStructure { - DayCounter dayCounter_; - public override DayCounter dayCounter() { return dayCounter_; } - - Date maxDate_; - List times_; - List variances_; - Interpolation varianceCurve_; - - // required for Handle - public BlackVarianceCurve(Date referenceDate, List dates, List blackVolCurve, DayCounter dayCounter, - bool forceMonotoneVariance) - : base(referenceDate) { - - dayCounter_ = dayCounter; - maxDate_ = dates.Last(); - - Utils.QL_REQUIRE(dates.Count == blackVolCurve.Count,()=> "mismatch between date vector and black vol vector"); - - // cannot have dates[0]==referenceDate, since the - // value of the vol at dates[0] would be lost - // (variance at referenceDate must be zero) - Utils.QL_REQUIRE(dates[0]>referenceDate,()=> "cannot have dates[0] <= referenceDate"); - - variances_ = new InitializedList(dates.Count+1); - times_ = new InitializedList(dates.Count + 1); - variances_[0] = 0.0; - times_[0] = 0.0; - for (int j = 1; j <= blackVolCurve.Count; j++) { - times_[j] = timeFromReference(dates[j-1]); - - Utils.QL_REQUIRE(times_[j]>times_[j-1],()=> "dates must be sorted unique!"); - variances_[j] = times_[j] * blackVolCurve[j-1]*blackVolCurve[j-1]; - Utils.QL_REQUIRE(variances_[j]>=variances_[j-1] || !forceMonotoneVariance,()=> "variance must be non-decreasing"); - } - - // default: linear interpolation - setInterpolation(); - } - - protected override double blackVarianceImpl(double t, double x) { - if (t<=times_.Last()) { - return varianceCurve_.value(t, true); - } else { - // extrapolate with flat vol - return varianceCurve_.value(times_.Last(), true) * t / times_.Last(); - } - } - - public void setInterpolation() where Interpolator : IInterpolationFactory, new() { - setInterpolation(FastActivator.Create()); - } - public void setInterpolation(Interpolator i) where Interpolator : IInterpolationFactory, new() { - varianceCurve_ = i.interpolate(times_, times_.Count, variances_); - varianceCurve_.update(); - notifyObservers(); - } - - public override Date maxDate() { return maxDate_; } - public override double minStrike() { return double.MinValue; } - public override double maxStrike() { return double.MaxValue; } - } +namespace QLNet +{ + //! Black volatility curve modelled as variance curve + /*! This class calculates time-dependent Black volatilities using + as input a vector of (ATM) Black volatilities observed in the + market. + + The calculation is performed interpolating on the variance curve. + Linear interpolation is used as default; this can be changed + by the setInterpolation() method. + + For strike dependence, see BlackVarianceSurface. + + \todo check time extrapolation + + */ + public class BlackVarianceCurve : BlackVarianceTermStructure + { + DayCounter dayCounter_; + public override DayCounter dayCounter() { return dayCounter_; } + + Date maxDate_; + List times_; + List variances_; + Interpolation varianceCurve_; + + // required for Handle + public BlackVarianceCurve(Date referenceDate, List dates, List blackVolCurve, DayCounter dayCounter, + bool forceMonotoneVariance) + : base(referenceDate) + { + + dayCounter_ = dayCounter; + maxDate_ = dates.Last(); + + Utils.QL_REQUIRE(dates.Count == blackVolCurve.Count, () => "mismatch between date vector and black vol vector"); + + // cannot have dates[0]==referenceDate, since the + // value of the vol at dates[0] would be lost + // (variance at referenceDate must be zero) + Utils.QL_REQUIRE(dates[0] > referenceDate, () => "cannot have dates[0] <= referenceDate"); + + variances_ = new InitializedList(dates.Count + 1); + times_ = new InitializedList(dates.Count + 1); + variances_[0] = 0.0; + times_[0] = 0.0; + for (int j = 1; j <= blackVolCurve.Count; j++) + { + times_[j] = timeFromReference(dates[j - 1]); + + Utils.QL_REQUIRE(times_[j] > times_[j - 1], () => "dates must be sorted unique!"); + variances_[j] = times_[j] * blackVolCurve[j - 1] * blackVolCurve[j - 1]; + Utils.QL_REQUIRE(variances_[j] >= variances_[j - 1] || !forceMonotoneVariance, () => "variance must be non-decreasing"); + } + + // default: linear interpolation + setInterpolation(); + } + + protected override double blackVarianceImpl(double t, double x) + { + if (t <= times_.Last()) + { + return varianceCurve_.value(t, true); + } + else + { + // extrapolate with flat vol + return varianceCurve_.value(times_.Last(), true) * t / times_.Last(); + } + } + + public void setInterpolation() where Interpolator : IInterpolationFactory, new () + { + setInterpolation(FastActivator.Create()); + } + public void setInterpolation(Interpolator i) where Interpolator : IInterpolationFactory, new () + { + varianceCurve_ = i.interpolate(times_, times_.Count, variances_); + varianceCurve_.update(); + notifyObservers(); + } + + public override Date maxDate() { return maxDate_; } + public override double minStrike() { return double.MinValue; } + public override double maxStrike() { return double.MaxValue; } + } } diff --git a/src/QLNet/Termstructures/Volatility/equityfx/BlackVarianceSurface.cs b/src/QLNet/Termstructures/Volatility/equityfx/BlackVarianceSurface.cs index a34549d39..56eeed7cc 100644 --- a/src/QLNet/Termstructures/Volatility/equityfx/BlackVarianceSurface.cs +++ b/src/QLNet/Termstructures/Volatility/equityfx/BlackVarianceSurface.cs @@ -6,7 +6,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -46,9 +46,9 @@ public enum Extrapolation private DayCounter dayCounter_; private Date maxDate_; private List strikes_; - private List times_; + private List times_; private List dates_; - private Matrix variances_; + private Matrix variances_; private Matrix volatilities_; private Interpolation2D varianceSurface_; private Extrapolation lowerExtrapolation_, upperExtrapolation_; @@ -66,13 +66,13 @@ public override Date maxDate() public override double maxStrike() { return strikes_.Last(); - } - - //public accessors - public virtual List strikes() { return strikes_; } - public virtual List times() { return times_; } - public virtual List dates() { return dates_; } - public virtual Matrix volatilities() { return volatilities_; } + } + + //public accessors + public virtual List strikes() { return strikes_; } + public virtual List times() { return times_; } + public virtual List dates() { return dates_; } + public virtual Matrix volatilities() { return volatilities_; } public virtual Matrix variances() { return variances_; } // required for Handle @@ -92,16 +92,16 @@ public BlackVarianceSurface(Date referenceDate, maxDate_ = dates.Last(); strikes_ = strikes; lowerExtrapolation_ = lowerExtrapolation; - upperExtrapolation_ = upperExtrapolation; - dates_ = dates; + upperExtrapolation_ = upperExtrapolation; + dates_ = dates; volatilities_ = blackVolMatrix; Utils.QL_REQUIRE(dates.Count == blackVolMatrix.columns(), () => - "mismatch between date vector and vol matrix colums"); + "mismatch between date vector and vol matrix colums"); Utils.QL_REQUIRE(strikes_.Count == blackVolMatrix.rows(), () => - "mismatch between money-strike vector and vol matrix rows"); + "mismatch between money-strike vector and vol matrix rows"); Utils.QL_REQUIRE(dates[0] >= referenceDate, () => - "cannot have dates[0] < referenceDate"); + "cannot have dates[0] < referenceDate"); int i, j; times_ = new InitializedList(dates.Count + 1); @@ -115,7 +115,7 @@ public BlackVarianceSurface(Date referenceDate, { times_[j] = timeFromReference(dates[j - 1]); Utils.QL_REQUIRE(times_[j] > times_[j - 1], - () => "dates must be sorted unique!"); + () => "dates must be sorted unique!"); for (i = 0; i < blackVolMatrix.rows(); i++) { variances_[i, j] = times_[j] * blackVolMatrix[i, j - 1] * blackVolMatrix[i, j - 1]; @@ -128,7 +128,8 @@ public BlackVarianceSurface(Date referenceDate, protected override double blackVarianceImpl(double t, double strike) { - if (t.IsEqual(0.0)) return 0.0; + if (t.IsEqual(0.0)) + return 0.0; // enforce constant extrapolation when required if (strike < strikes_.First() && lowerExtrapolation_ == Extrapolation.ConstantExtrapolation) strike = strikes_.First(); @@ -137,16 +138,16 @@ protected override double blackVarianceImpl(double t, double strike) if (t <= times_.Last()) return varianceSurface_.value(t, strike, true); - else + else return varianceSurface_.value(times_.Last(), strike, true) * t / times_.Last(); } - public void setInterpolation() where Interpolator : IInterpolationFactory2D, new() + public void setInterpolation() where Interpolator : IInterpolationFactory2D, new () { setInterpolation(FastActivator.Create()); } - public void setInterpolation(Interpolator i) where Interpolator : IInterpolationFactory2D, new() + public void setInterpolation(Interpolator i) where Interpolator : IInterpolationFactory2D, new () { varianceSurface_ = i.interpolate(times_, times_.Count, strikes_, strikes_.Count, variances_); varianceSurface_.update(); diff --git a/src/QLNet/Termstructures/Volatility/equityfx/BlackVolTermStructure.cs b/src/QLNet/Termstructures/Volatility/equityfx/BlackVolTermStructure.cs index 53b6e06a5..f4e64f482 100644 --- a/src/QLNet/Termstructures/Volatility/equityfx/BlackVolTermStructure.cs +++ b/src/QLNet/Termstructures/Volatility/equityfx/BlackVolTermStructure.cs @@ -1,25 +1,25 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet +namespace QLNet { //! Black-volatility term structure /*! This abstract class defines the interface of concrete @@ -28,31 +28,31 @@ this one. Volatilities are assumed to be expressed on an annual basis. */ - public abstract class BlackVolTermStructure : VolatilityTermStructure + public abstract class BlackVolTermStructure : VolatilityTermStructure { #region Constructors - //! default constructor - /*! \warning term structures initialized by means of this - constructor must manage their own reference date - by overriding the referenceDate() method. - */ - - protected BlackVolTermStructure(BusinessDayConvention bdc = BusinessDayConvention.Following,DayCounter dc = null) - :base(bdc, dc) - {} - + //! default constructor + /*! \warning term structures initialized by means of this + constructor must manage their own reference date + by overriding the referenceDate() method. + */ + + protected BlackVolTermStructure(BusinessDayConvention bdc = BusinessDayConvention.Following, DayCounter dc = null) + : base(bdc, dc) + {} + //! initialize with a fixed reference date - protected BlackVolTermStructure(Date referenceDate,Calendar cal = null, - BusinessDayConvention bdc = BusinessDayConvention.Following,DayCounter dc = null) - :base(referenceDate, cal, bdc, dc) + protected BlackVolTermStructure(Date referenceDate, Calendar cal = null, + BusinessDayConvention bdc = BusinessDayConvention.Following, DayCounter dc = null) + : base(referenceDate, cal, bdc, dc) {} - + //! calculate the reference date based on the global evaluation date - protected BlackVolTermStructure(int settlementDays,Calendar cal, BusinessDayConvention bdc = BusinessDayConvention.Following, - DayCounter dc = null) - :base(settlementDays, cal, bdc, dc) + protected BlackVolTermStructure(int settlementDays, Calendar cal, BusinessDayConvention bdc = BusinessDayConvention.Following, + DayCounter dc = null) + : base(settlementDays, cal, bdc, dc) {} - + #endregion #region Black Volatility @@ -65,7 +65,7 @@ public double blackVol(Date maturity, double strike, bool extrapolate = false) double t = timeFromReference(maturity); return blackVolImpl(t, strike); } - + //! spot volatility public double blackVol(double maturity, double strike, bool extrapolate = false) { @@ -73,7 +73,7 @@ public double blackVol(double maturity, double strike, bool extrapolate = false) checkStrike(strike, extrapolate); return blackVolImpl(maturity, strike); } - + //! spot variance public double blackVariance(Date maturity, double strike, bool extrapolate = false) { @@ -82,7 +82,7 @@ public double blackVariance(Date maturity, double strike, bool extrapolate = fal double t = timeFromReference(maturity); return blackVarianceImpl(t, strike); } - + //! spot variance public double blackVariance(double maturity, double strike, bool extrapolate = false) { @@ -90,12 +90,12 @@ public double blackVariance(double maturity, double strike, bool extrapolate = f checkStrike(strike, extrapolate); return blackVarianceImpl(maturity, strike); } - + //! forward (at-the-money) volatility - public double blackForwardVol(Date date1,Date date2, double strike,bool extrapolate = false) + public double blackForwardVol(Date date1, Date date2, double strike, bool extrapolate = false) { // (redundant) date-based checks - Utils.QL_REQUIRE( date1 <= date2, () => date1 + " later than " + date2 ); + Utils.QL_REQUIRE(date1 <= date2, () => date1 + " later than " + date2); checkRange(date2, extrapolate); // using the time implementation @@ -103,44 +103,44 @@ public double blackForwardVol(Date date1,Date date2, double strike,bool extrapol double time2 = timeFromReference(date2); return blackForwardVol(time1, time2, strike, extrapolate); } - + //! forward (at-the-money) volatility public double blackForwardVol(double time1, double time2, double strike, bool extrapolate = false) { - Utils.QL_REQUIRE( time1 <= time2, () => time1 + " later than " + time2 ); + Utils.QL_REQUIRE(time1 <= time2, () => time1 + " later than " + time2); checkRange(time2, extrapolate); checkStrike(strike, extrapolate); - if (time2.IsEqual(time1)) + if (time2.IsEqual(time1)) { - if (time1.IsEqual(0.0)) + if (time1.IsEqual(0.0)) { double epsilon = 1.0e-5; double var = blackVarianceImpl(epsilon, strike); - return Math.Sqrt(var/epsilon); - } - else + return Math.Sqrt(var / epsilon); + } + else { double epsilon = Math.Min(1.0e-5, time1); - double var1 = blackVarianceImpl(time1-epsilon, strike); - double var2 = blackVarianceImpl(time1+epsilon, strike); - Utils.QL_REQUIRE( var2 >= var1, () => "variances must be non-decreasing" ); - return Math.Sqrt((var2-var1)/(2*epsilon)); + double var1 = blackVarianceImpl(time1 - epsilon, strike); + double var2 = blackVarianceImpl(time1 + epsilon, strike); + Utils.QL_REQUIRE(var2 >= var1, () => "variances must be non-decreasing"); + return Math.Sqrt((var2 - var1) / (2 * epsilon)); } - } - else + } + else { double var1 = blackVarianceImpl(time1, strike); double var2 = blackVarianceImpl(time2, strike); - Utils.QL_REQUIRE( var2 >= var1, () => "variances must be non-decreasing" ); - return Math.Sqrt((var2-var1)/(time2-time1)); + Utils.QL_REQUIRE(var2 >= var1, () => "variances must be non-decreasing"); + return Math.Sqrt((var2 - var1) / (time2 - time1)); } } - + //! forward (at-the-money) variance - public double blackForwardVariance(Date date1, Date date2, double strike,bool extrapolate = false) + public double blackForwardVariance(Date date1, Date date2, double strike, bool extrapolate = false) { // (redundant) date-based checks - Utils.QL_REQUIRE( date1 <= date2, () => date1 + " later than " + date2 ); + Utils.QL_REQUIRE(date1 <= date2, () => date1 + " later than " + date2); checkRange(date2, extrapolate); // using the time implementation @@ -148,21 +148,21 @@ public double blackForwardVariance(Date date1, Date date2, double strike,bool e double time2 = timeFromReference(date2); return blackForwardVariance(time1, time2, strike, extrapolate); } - + //! forward (at-the-money) variance public double blackForwardVariance(double time1, double time2, double strike, bool extrapolate = false) { - Utils.QL_REQUIRE( time1 <= time2, () => time1 + " later than " + time2 ); - checkRange(time2, extrapolate); - checkStrike(strike, extrapolate); - double v1 = blackVarianceImpl(time1, strike); - double v2 = blackVarianceImpl(time2, strike); - Utils.QL_REQUIRE( v2 >= v1, () => "variances must be non-decreasing" ); - return v2-v1; + Utils.QL_REQUIRE(time1 <= time2, () => time1 + " later than " + time2); + checkRange(time2, extrapolate); + checkStrike(strike, extrapolate); + double v1 = blackVarianceImpl(time1, strike); + double v2 = blackVarianceImpl(time2, strike); + Utils.QL_REQUIRE(v2 >= v1, () => "variances must be non-decreasing"); + return v2 - v1; } - + #endregion - + #region Calculations // These methods must be implemented in derived classes to perform @@ -172,7 +172,7 @@ public double blackForwardVariance(double time1, double time2, double strike, b //! Black variance calculation protected abstract double blackVarianceImpl(double t, double strike); - + //! Black volatility calculation protected abstract double blackVolImpl(double t, double strike); @@ -180,15 +180,15 @@ public double blackForwardVariance(double time1, double time2, double strike, b } - //! Black-volatility term structure - /*! This abstract class acts as an adapter to BlackVolTermStructure - allowing the programmer to implement only the - blackVolImpl(Time, Real, bool) method in derived classes. + //! Black-volatility term structure + /*! This abstract class acts as an adapter to BlackVolTermStructure + allowing the programmer to implement only the + blackVolImpl(Time, Real, bool) method in derived classes. - Volatility are assumed to be expressed on an annual basis. - */ - - public abstract class BlackVolatilityTermStructure : BlackVolTermStructure + Volatility are assumed to be expressed on an annual basis. + */ + + public abstract class BlackVolatilityTermStructure : BlackVolTermStructure { #region Constructors @@ -199,33 +199,33 @@ by overriding the referenceDate() method. */ protected BlackVolatilityTermStructure(BusinessDayConvention bdc = BusinessDayConvention.Following, - DayCounter dc = null) - :base(bdc, dc) + DayCounter dc = null) + : base(bdc, dc) {} - + //! initialize with a fixed reference date - protected BlackVolatilityTermStructure(Date referenceDate,Calendar cal = null, - BusinessDayConvention bdc = BusinessDayConvention.Following,DayCounter dc = null) - :base(referenceDate, cal, bdc, dc) + protected BlackVolatilityTermStructure(Date referenceDate, Calendar cal = null, + BusinessDayConvention bdc = BusinessDayConvention.Following, DayCounter dc = null) + : base(referenceDate, cal, bdc, dc) {} - + //! calculate the reference date based on the global evaluation date - protected BlackVolatilityTermStructure(int settlementDays,Calendar cal, - BusinessDayConvention bdc = BusinessDayConvention.Following,DayCounter dc = null) - :base(settlementDays, cal, bdc, dc) + protected BlackVolatilityTermStructure(int settlementDays, Calendar cal, + BusinessDayConvention bdc = BusinessDayConvention.Following, DayCounter dc = null) + : base(settlementDays, cal, bdc, dc) {} - + #endregion - + /*! Returns the variance for the given strike and date calculating it from the volatility. */ protected override double blackVarianceImpl(double maturity, double strike) { double vol = blackVolImpl(maturity, strike); - return vol*vol*maturity; + return vol * vol * maturity; } - } + } //! Black variance term structure @@ -236,8 +236,8 @@ the programmer to implement only the Volatility are assumed to be expressed on an annual basis. */ - - public abstract class BlackVarianceTermStructure : BlackVolTermStructure + + public abstract class BlackVarianceTermStructure : BlackVolTermStructure { #region Constructors //! default constructor @@ -247,20 +247,20 @@ by overriding the referenceDate() method. */ protected BlackVarianceTermStructure(BusinessDayConvention bdc = BusinessDayConvention.Following, - DayCounter dc = null) - :base(bdc, dc) + DayCounter dc = null) + : base(bdc, dc) {} - + //! initialize with a fixed reference date - protected BlackVarianceTermStructure(Date referenceDate,Calendar cal = null, - BusinessDayConvention bdc = BusinessDayConvention.Following,DayCounter dc = null) - :base(referenceDate, cal, bdc, dc) + protected BlackVarianceTermStructure(Date referenceDate, Calendar cal = null, + BusinessDayConvention bdc = BusinessDayConvention.Following, DayCounter dc = null) + : base(referenceDate, cal, bdc, dc) {} //! calculate the reference date based on the global evaluation date - protected BlackVarianceTermStructure(int settlementDays,Calendar cal, - BusinessDayConvention bdc = BusinessDayConvention.Following,DayCounter dc = null) - :base(settlementDays, cal, bdc, dc) + protected BlackVarianceTermStructure(int settlementDays, Calendar cal, + BusinessDayConvention bdc = BusinessDayConvention.Following, DayCounter dc = null) + : base(settlementDays, cal, bdc, dc) {} #endregion @@ -272,9 +272,9 @@ protected override double blackVolImpl(double t, double strike) { double nonZeroMaturity = t.IsEqual(0.0) ? 0.00001 : t; double var = blackVarianceImpl(nonZeroMaturity, strike); - return Math.Sqrt(var/nonZeroMaturity); + return Math.Sqrt(var / nonZeroMaturity); } - + } } diff --git a/src/QLNet/Termstructures/Volatility/equityfx/FixedLocalVolSurface.cs b/src/QLNet/Termstructures/Volatility/equityfx/FixedLocalVolSurface.cs index d6c0d273a..2239c0ff0 100644 --- a/src/QLNet/Termstructures/Volatility/equityfx/FixedLocalVolSurface.cs +++ b/src/QLNet/Termstructures/Volatility/equityfx/FixedLocalVolSurface.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,207 +23,212 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public partial class Utils - { - public static Date time2Date(Date referenceDate, DayCounter dc, double t) { - t-=1e4*Const.QL_EPSILON; // add a small buffer for rounding errors - Date d = new Date(referenceDate); + public partial class Utils + { + public static Date time2Date(Date referenceDate, DayCounter dc, double t) + { + t -= 1e4 * Const.QL_EPSILON; // add a small buffer for rounding errors + Date d = new Date(referenceDate); while (dc.yearFraction(referenceDate, d += new Period(1, TimeUnit.Years)) < t); d -= new Period(1, TimeUnit.Years); while (dc.yearFraction(referenceDate, d += new Period(1, TimeUnit.Months)) < t); d -= new Period(1, TimeUnit.Months); while (dc.yearFraction(referenceDate, d++) < t); return d; - } - } - - public class FixedLocalVolSurface : LocalVolTermStructure - { - public enum Extrapolation - { - ConstantExtrapolation, - InterpolatorDefaultExtrapolation - } - - public FixedLocalVolSurface(Date referenceDate, - List dates, - List strikes, - Matrix localVolMatrix, - DayCounter dayCounter, - Extrapolation lowerExtrapolation = - Extrapolation.ConstantExtrapolation, - Extrapolation upperExtrapolation = - Extrapolation.ConstantExtrapolation) - : base(referenceDate, null, BusinessDayConvention.Following, dayCounter) - { - maxDate_ = dates.Last(); - localVolMatrix_ = localVolMatrix; - strikes_ = new InitializedList>(dates.Count, new List(strikes)); - localVolInterpol_ = new List(); - lowerExtrapolation_ = lowerExtrapolation; - upperExtrapolation_ = upperExtrapolation; - - Utils.QL_REQUIRE(dates[0]>=referenceDate, - () => "cannot have dates[0] < referenceDate"); - - times_ = new InitializedList(dates.Count); - for (int j=0; j(); - } - - public FixedLocalVolSurface(Date referenceDate, - List times, - List strikes, - Matrix localVolMatrix, - DayCounter dayCounter, - Extrapolation lowerExtrapolation = - Extrapolation.ConstantExtrapolation, - Extrapolation upperExtrapolation = - Extrapolation.ConstantExtrapolation) - : base(referenceDate, null, BusinessDayConvention.Following, dayCounter) - { - maxDate_ = Utils.time2Date(referenceDate, dayCounter, times.Last()); - times_ = times; - localVolMatrix_ = localVolMatrix; - strikes_ = new InitializedList>(times.Count, new List(strikes)); - localVolInterpol_ = new List(); - lowerExtrapolation_ = lowerExtrapolation; - upperExtrapolation_ = upperExtrapolation; - - Utils.QL_REQUIRE(times[0] >= 0.0, - () => "cannot have times[0] < 0"); - - checkSurface(); - setInterpolation(); - } - - public FixedLocalVolSurface(Date referenceDate, - List times, - List> strikes, - Matrix localVolMatrix, - DayCounter dayCounter, - Extrapolation lowerExtrapolation = - Extrapolation.ConstantExtrapolation, - Extrapolation upperExtrapolation = - Extrapolation.ConstantExtrapolation) - : base(referenceDate, null, BusinessDayConvention.Following, dayCounter) - { - maxDate_ = Utils.time2Date(referenceDate, dayCounter, times.Last()); - times_ = times; - localVolMatrix_ = localVolMatrix; - strikes_ = strikes; - localVolInterpol_ = new List(); - lowerExtrapolation_ = lowerExtrapolation; - upperExtrapolation_ = upperExtrapolation; - - Utils.QL_REQUIRE(times[0] >= 0.0, - () => "cannot have times[0] < 0"); - - Utils.QL_REQUIRE(times.Count == strikes.Count, - () => "need strikes for every time step"); - - checkSurface(); - setInterpolation(); - } - - - public override Date maxDate() { return maxDate_; } - public override double maxTime() { return times_.Last(); } - public override double minStrike() { return strikes_.Min().Min(); } - public override double maxStrike() { return strikes_.Max().Max(); } - - public void setInterpolation(Interpolator i = default(Interpolator)) - where Interpolator : class, IInterpolationFactory, new() - { - localVolInterpol_.Clear(); - Interpolator i_ = i ?? FastActivator.Create(); - for (int j=0; j < times_.Count; ++j) { - localVolInterpol_.Add(i_.interpolate( - strikes_[j], strikes_[j].Count, - localVolMatrix_.column(j))); - } - notifyObservers(); - } - - protected override double localVolImpl(double t, double strike) - { - t = Math.Min(times_.Last(), Math.Max(t, times_.First())); - - int idx = times_.BinarySearch(t); - if (idx < 0) - idx = ~idx; - - if (idx == times_.Count) - idx--; - if (Utils.close_enough(t, times_[idx])) - { - if (strikes_[idx].First() < strikes_[idx].Last()) - return localVolInterpol_[idx].value(strike, true); - else - return localVolMatrix_[localVolMatrix_.rows() / 2, idx]; - } + } + } + + public class FixedLocalVolSurface : LocalVolTermStructure + { + public enum Extrapolation + { + ConstantExtrapolation, + InterpolatorDefaultExtrapolation + } + + public FixedLocalVolSurface(Date referenceDate, + List dates, + List strikes, + Matrix localVolMatrix, + DayCounter dayCounter, + Extrapolation lowerExtrapolation = + Extrapolation.ConstantExtrapolation, + Extrapolation upperExtrapolation = + Extrapolation.ConstantExtrapolation) + : base(referenceDate, null, BusinessDayConvention.Following, dayCounter) + { + maxDate_ = dates.Last(); + localVolMatrix_ = localVolMatrix; + strikes_ = new InitializedList>(dates.Count, new List(strikes)); + localVolInterpol_ = new List(); + lowerExtrapolation_ = lowerExtrapolation; + upperExtrapolation_ = upperExtrapolation; + + Utils.QL_REQUIRE(dates[0] >= referenceDate, + () => "cannot have dates[0] < referenceDate"); + + times_ = new InitializedList(dates.Count); + for (int j = 0; j < times_.Count; j++) + times_[j] = timeFromReference(dates[j]); + + checkSurface(); + setInterpolation(); + } + + public FixedLocalVolSurface(Date referenceDate, + List times, + List strikes, + Matrix localVolMatrix, + DayCounter dayCounter, + Extrapolation lowerExtrapolation = + Extrapolation.ConstantExtrapolation, + Extrapolation upperExtrapolation = + Extrapolation.ConstantExtrapolation) + : base(referenceDate, null, BusinessDayConvention.Following, dayCounter) + { + maxDate_ = Utils.time2Date(referenceDate, dayCounter, times.Last()); + times_ = times; + localVolMatrix_ = localVolMatrix; + strikes_ = new InitializedList>(times.Count, new List(strikes)); + localVolInterpol_ = new List(); + lowerExtrapolation_ = lowerExtrapolation; + upperExtrapolation_ = upperExtrapolation; + + Utils.QL_REQUIRE(times[0] >= 0.0, + () => "cannot have times[0] < 0"); + + checkSurface(); + setInterpolation(); + } + + public FixedLocalVolSurface(Date referenceDate, + List times, + List> strikes, + Matrix localVolMatrix, + DayCounter dayCounter, + Extrapolation lowerExtrapolation = + Extrapolation.ConstantExtrapolation, + Extrapolation upperExtrapolation = + Extrapolation.ConstantExtrapolation) + : base(referenceDate, null, BusinessDayConvention.Following, dayCounter) + { + maxDate_ = Utils.time2Date(referenceDate, dayCounter, times.Last()); + times_ = times; + localVolMatrix_ = localVolMatrix; + strikes_ = strikes; + localVolInterpol_ = new List(); + lowerExtrapolation_ = lowerExtrapolation; + upperExtrapolation_ = upperExtrapolation; + + Utils.QL_REQUIRE(times[0] >= 0.0, + () => "cannot have times[0] < 0"); + + Utils.QL_REQUIRE(times.Count == strikes.Count, + () => "need strikes for every time step"); + + checkSurface(); + setInterpolation(); + } + + + public override Date maxDate() { return maxDate_; } + public override double maxTime() { return times_.Last(); } + public override double minStrike() { return strikes_.Min().Min(); } + public override double maxStrike() { return strikes_.Max().Max(); } + + public void setInterpolation(Interpolator i = default(Interpolator)) + where Interpolator : class, IInterpolationFactory, new () + { + localVolInterpol_.Clear(); + Interpolator i_ = i ?? FastActivator.Create(); + for (int j = 0; j < times_.Count; ++j) + { + localVolInterpol_.Add(i_.interpolate( + strikes_[j], strikes_[j].Count, + localVolMatrix_.column(j))); + } + notifyObservers(); + } + + protected override double localVolImpl(double t, double strike) + { + t = Math.Min(times_.Last(), Math.Max(t, times_.First())); + + int idx = times_.BinarySearch(t); + if (idx < 0) + idx = ~idx; + + if (idx == times_.Count) + idx--; + if (Utils.close_enough(t, times_[idx])) + { + if (strikes_[idx].First() < strikes_[idx].Last()) + return localVolInterpol_[idx].value(strike, true); else + return localVolMatrix_[localVolMatrix_.rows() / 2, idx]; + } + else + { + double earlierStrike = strike, laterStrike = strike; + if (lowerExtrapolation_ == Extrapolation.ConstantExtrapolation) { - double earlierStrike = strike, laterStrike = strike; - if (lowerExtrapolation_ == Extrapolation.ConstantExtrapolation) - { - if (strike < strikes_[idx - 1].First()) - earlierStrike = strikes_[idx - 1].First(); - if (strike < strikes_[idx].First()) - laterStrike = strikes_[idx].First(); - } - - if (upperExtrapolation_ == Extrapolation.ConstantExtrapolation) - { - if (strike > strikes_[idx - 1].Last()) - earlierStrike = strikes_[idx - 1].Last(); - if (strike > strikes_[idx].Last()) - laterStrike = strikes_[idx].Last(); - } - - double earlyVol = - (strikes_[idx - 1].First() < strikes_[idx - 1].Last()) - ? localVolInterpol_[idx - 1].value(earlierStrike, true) - : localVolMatrix_[localVolMatrix_.rows() / 2, idx - 1]; - double laterVol = localVolInterpol_[idx].value(laterStrike, true); - - return earlyVol - + (laterVol - earlyVol) / (times_[idx] - times_[idx - 1]) - * (t - times_[idx - 1]); - } - } - - protected Date maxDate_; - protected List times_; - protected Matrix localVolMatrix_; - protected List> strikes_; - - protected List localVolInterpol_; - protected Extrapolation lowerExtrapolation_, upperExtrapolation_; - - private void checkSurface() - { - Utils.QL_REQUIRE(times_.Count==localVolMatrix_.columns(), - () => "mismatch between date vector and vol matrix colums"); - for (int i=0; i < strikes_.Count; ++i) { - Utils.QL_REQUIRE(strikes_[i].Count == localVolMatrix_.rows(), - () => "mismatch between money-strike vector and " - + "vol matrix rows"); + if (strike < strikes_[idx - 1].First()) + earlierStrike = strikes_[idx - 1].First(); + if (strike < strikes_[idx].First()) + laterStrike = strikes_[idx].First(); } - for (int j=1; jtimes_[j-1], - () => "dates must be sorted unique!"); + if (upperExtrapolation_ == Extrapolation.ConstantExtrapolation) + { + if (strike > strikes_[idx - 1].Last()) + earlierStrike = strikes_[idx - 1].Last(); + if (strike > strikes_[idx].Last()) + laterStrike = strikes_[idx].Last(); } - for (int i=0; i < strikes_.Count; ++i) - for (int j=1; j=strikes_[i][j-1], - () => "strikes must be sorted"); - } - } - } + double earlyVol = + (strikes_[idx - 1].First() < strikes_[idx - 1].Last()) + ? localVolInterpol_[idx - 1].value(earlierStrike, true) + : localVolMatrix_[localVolMatrix_.rows() / 2, idx - 1]; + double laterVol = localVolInterpol_[idx].value(laterStrike, true); + + return earlyVol + + (laterVol - earlyVol) / (times_[idx] - times_[idx - 1]) + * (t - times_[idx - 1]); + } + } + + protected Date maxDate_; + protected List times_; + protected Matrix localVolMatrix_; + protected List> strikes_; + + protected List localVolInterpol_; + protected Extrapolation lowerExtrapolation_, upperExtrapolation_; + + private void checkSurface() + { + Utils.QL_REQUIRE(times_.Count == localVolMatrix_.columns(), + () => "mismatch between date vector and vol matrix colums"); + for (int i = 0; i < strikes_.Count; ++i) + { + Utils.QL_REQUIRE(strikes_[i].Count == localVolMatrix_.rows(), + () => "mismatch between money-strike vector and " + + "vol matrix rows"); + } + + for (int j = 1; j < times_.Count; j++) + { + Utils.QL_REQUIRE(times_[j] > times_[j - 1], + () => "dates must be sorted unique!"); + } + + for (int i = 0; i < strikes_.Count; ++i) + for (int j = 1; j < strikes_[i].Count; j++) + { + Utils.QL_REQUIRE(strikes_[i][j] >= strikes_[i][j - 1], + () => "strikes must be sorted"); + } + } + } } diff --git a/src/QLNet/Termstructures/Volatility/equityfx/HestonBlackVolSurface.cs b/src/QLNet/Termstructures/Volatility/equityfx/HestonBlackVolSurface.cs index 3fa6a2e3c..01788dade 100644 --- a/src/QLNet/Termstructures/Volatility/equityfx/HestonBlackVolSurface.cs +++ b/src/QLNet/Termstructures/Volatility/equityfx/HestonBlackVolSurface.cs @@ -6,7 +6,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -28,10 +28,10 @@ public class HestonBlackVolSurface : BlackVolTermStructure private AnalyticHestonEngine.Integration integration_; public HestonBlackVolSurface(Handle hestonModel) - : base(hestonModel.link.process().riskFreeRate().link.referenceDate(), - new NullCalendar(), - BusinessDayConvention.Following, - hestonModel.link.process().riskFreeRate().link.dayCounter()) + : base(hestonModel.link.process().riskFreeRate().link.referenceDate(), + new NullCalendar(), + BusinessDayConvention.Following, + hestonModel.link.process().riskFreeRate().link.dayCounter()) { hestonModel_ = hestonModel; integration_ = AnalyticHestonEngine.Integration.gaussLaguerre(164); @@ -68,8 +68,8 @@ protected override double blackVolImpl(double t, double strike) double spotPrice = process.s0().link.value(); double fwd = spotPrice - * process.dividendYield().link.discount(t, true) - / process.riskFreeRate().link.discount(t, true); + * process.dividendYield().link.discount(t, true) + / process.riskFreeRate().link.discount(t, true); var payoff = new PlainVanillaPayoff(fwd > strike ? Option.Type.Put : Option.Type.Call, strike); @@ -87,12 +87,13 @@ protected override double blackVolImpl(double t, double strike) int evaluations = 0; AnalyticHestonEngine.doCalculation( - df, div, spotPrice, strike, t, - kappa, theta, sigma, v0, rho, - payoff, integration_, cpxLogFormula, - hestonEnginePtr, ref npv, ref evaluations); + df, div, spotPrice, strike, t, + kappa, theta, sigma, v0, rho, + payoff, integration_, cpxLogFormula, + hestonEnginePtr, ref npv, ref evaluations); - if (npv <= 0.0) return Math.Sqrt(theta); + if (npv <= 0.0) + return Math.Sqrt(theta); Brent solver = new Brent(); solver.setMaxEvaluations(10000); diff --git a/src/QLNet/Termstructures/Volatility/equityfx/ImpliedVolTermStructure.cs b/src/QLNet/Termstructures/Volatility/equityfx/ImpliedVolTermStructure.cs index c788278f4..12663128e 100644 --- a/src/QLNet/Termstructures/Volatility/equityfx/ImpliedVolTermStructure.cs +++ b/src/QLNet/Termstructures/Volatility/equityfx/ImpliedVolTermStructure.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -30,8 +30,8 @@ time dependant only. */ public class ImpliedVolTermStructure : BlackVarianceTermStructure { - public ImpliedVolTermStructure( Handle originalTS, Date referenceDate ) - :base(referenceDate) + public ImpliedVolTermStructure(Handle originalTS, Date referenceDate) + : base(referenceDate) { originalTS_ = originalTS; originalTS_.registerWith(update); @@ -43,25 +43,25 @@ public ImpliedVolTermStructure( Handle originalTS, Date r public override double minStrike() { return originalTS_.link.minStrike(); } public override double maxStrike() { return originalTS_.link.maxStrike(); } // Visitability - public virtual void accept( IAcyclicVisitor v ) + public virtual void accept(IAcyclicVisitor v) { - if ( v != null ) - v.visit( this ); + if (v != null) + v.visit(this); else - Utils.QL_FAIL( "not an event visitor" ); + Utils.QL_FAIL("not an event visitor"); } protected override double blackVarianceImpl(double t, double strike) { /* timeShift (and/or variance) variance at evaluation date cannot be cached since the original curve could change between invocations of this method */ - double timeShift = dayCounter().yearFraction( originalTS_.link.referenceDate(),referenceDate() ); + double timeShift = dayCounter().yearFraction(originalTS_.link.referenceDate(), referenceDate()); /* t is relative to the current reference date and needs to be converted to the time relative to the reference date of the original curve */ - return originalTS_.link.blackForwardVariance( timeShift,timeShift + t,strike,true ); + return originalTS_.link.blackForwardVariance(timeShift, timeShift + t, strike, true); } - + private Handle originalTS_; } diff --git a/src/QLNet/Termstructures/Volatility/equityfx/LocalConstantVol.cs b/src/QLNet/Termstructures/Volatility/equityfx/LocalConstantVol.cs index cd3fd6f04..c0d09ef66 100644 --- a/src/QLNet/Termstructures/Volatility/equityfx/LocalConstantVol.cs +++ b/src/QLNet/Termstructures/Volatility/equityfx/LocalConstantVol.cs @@ -1,69 +1,75 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { - //! Constant local volatility, no time-strike dependence - /*! This class implements the LocalVolatilityTermStructure - interface for a constant local volatility (no time/asset - dependence). Local volatility and Black volatility are the - same when volatility is at most time dependent, so this class - is basically a proxy for BlackVolatilityTermStructure. - */ - public class LocalConstantVol : LocalVolTermStructure { - Handle volatility_; - DayCounter dayCounter_; +namespace QLNet +{ + //! Constant local volatility, no time-strike dependence + /*! This class implements the LocalVolatilityTermStructure + interface for a constant local volatility (no time/asset + dependence). Local volatility and Black volatility are the + same when volatility is at most time dependent, so this class + is basically a proxy for BlackVolatilityTermStructure. + */ + public class LocalConstantVol : LocalVolTermStructure + { + Handle volatility_; + DayCounter dayCounter_; - public LocalConstantVol(Date referenceDate, double volatility, DayCounter dc) - : base(referenceDate) { - volatility_ = new Handle(new SimpleQuote(volatility)); - dayCounter_ = dc; - } + public LocalConstantVol(Date referenceDate, double volatility, DayCounter dc) + : base(referenceDate) + { + volatility_ = new Handle(new SimpleQuote(volatility)); + dayCounter_ = dc; + } - public LocalConstantVol(Date referenceDate, Handle volatility, DayCounter dc) - : base(referenceDate) { - volatility_ = volatility; - dayCounter_ = dc; + public LocalConstantVol(Date referenceDate, Handle volatility, DayCounter dc) + : base(referenceDate) + { + volatility_ = volatility; + dayCounter_ = dc; - volatility_.registerWith(update); - } + volatility_.registerWith(update); + } - public LocalConstantVol(int settlementDays, Calendar calendar, double volatility, DayCounter dayCounter) - : base(settlementDays, calendar) { - volatility_ = new Handle(new SimpleQuote(volatility)); - dayCounter_ = dayCounter; - } + public LocalConstantVol(int settlementDays, Calendar calendar, double volatility, DayCounter dayCounter) + : base(settlementDays, calendar) + { + volatility_ = new Handle(new SimpleQuote(volatility)); + dayCounter_ = dayCounter; + } - public LocalConstantVol(int settlementDays, Calendar calendar, Handle volatility, DayCounter dayCounter) - : base(settlementDays,calendar) { - volatility_ = volatility; - dayCounter_ = dayCounter; + public LocalConstantVol(int settlementDays, Calendar calendar, Handle volatility, DayCounter dayCounter) + : base(settlementDays, calendar) + { + volatility_ = volatility; + dayCounter_ = dayCounter; - volatility_.registerWith(update); - } + volatility_.registerWith(update); + } - // TermStructure interface - public override DayCounter dayCounter() { return dayCounter_; } - public override Date maxDate() { return Date.maxDate(); } - // VolatilityTermStructure interface - public override double minStrike() { return double.MinValue; } - public override double maxStrike() { return double.MaxValue; } + // TermStructure interface + public override DayCounter dayCounter() { return dayCounter_; } + public override Date maxDate() { return Date.maxDate(); } + // VolatilityTermStructure interface + public override double minStrike() { return double.MinValue; } + public override double maxStrike() { return double.MaxValue; } - protected override double localVolImpl(double t, double s) { return volatility_.link.value(); } - } + protected override double localVolImpl(double t, double s) { return volatility_.link.value(); } + } } diff --git a/src/QLNet/Termstructures/Volatility/equityfx/LocalVolCurve.cs b/src/QLNet/Termstructures/Volatility/equityfx/LocalVolCurve.cs index 877a80907..07da76713 100644 --- a/src/QLNet/Termstructures/Volatility/equityfx/LocalVolCurve.cs +++ b/src/QLNet/Termstructures/Volatility/equityfx/LocalVolCurve.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -25,11 +25,11 @@ namespace QLNet //! Local volatility curve derived from a Black curve public class LocalVolCurve : LocalVolTermStructure { - public LocalVolCurve( Handle curve ) - : base( curve.link.businessDayConvention(), curve.link.dayCounter() ) + public LocalVolCurve(Handle curve) + : base(curve.link.businessDayConvention(), curve.link.dayCounter()) { blackVarianceCurve_ = curve; - blackVarianceCurve_.registerWith( update ); + blackVarianceCurve_.registerWith(update); } // TermStructure interface @@ -66,10 +66,10 @@ public override double maxStrike() protected override double localVolImpl(double t, double dummy) { - double dt = (1.0/365.0); + double dt = (1.0 / 365.0); double var1 = blackVarianceCurve_.link.blackVariance(t, dummy, true); double var2 = blackVarianceCurve_.link.blackVariance(t + dt, dummy, true); - double derivative = (var2 - var1)/dt; + double derivative = (var2 - var1) / dt; return Math.Sqrt(derivative); } diff --git a/src/QLNet/Termstructures/Volatility/equityfx/LocalVolSurface.cs b/src/QLNet/Termstructures/Volatility/equityfx/LocalVolSurface.cs index 8e0e3f849..1c98a7452 100644 --- a/src/QLNet/Termstructures/Volatility/equityfx/LocalVolSurface.cs +++ b/src/QLNet/Termstructures/Volatility/equityfx/LocalVolSurface.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,123 +19,134 @@ under the terms of the QLNet license. You should have received a using System; -namespace QLNet { - //! Local volatility surface derived from a Black vol surface - /*! For details about this implementation refer to - "Stochastic Volatility and Local Volatility," in - "Case Studies and Financial Modelling Course Notes," by - Jim Gatheral, Fall Term, 2003 - - see www.math.nyu.edu/fellows_fin_math/gatheral/Lecture1_Fall02.pdf - - \bug this class is untested, probably unreliable. - */ - public class LocalVolSurface : LocalVolTermStructure { - Handle blackTS_; - Handle riskFreeTS_, dividendTS_; - Handle underlying_; - - public LocalVolSurface(Handle blackTS, Handle riskFreeTS, - Handle dividendTS, Handle underlying) - : base( blackTS.link.businessDayConvention(), blackTS.link.dayCounter()) { - blackTS_ = blackTS; - riskFreeTS_ = riskFreeTS; - dividendTS_ = dividendTS; - underlying_ = underlying; - - blackTS_.registerWith(update); - riskFreeTS_.registerWith(update); - dividendTS_.registerWith(update); - underlying_.registerWith(update); - } - - public LocalVolSurface(Handle blackTS, Handle riskFreeTS, - Handle dividendTS, double underlying) - : base( blackTS.link.businessDayConvention(), blackTS.link.dayCounter()) { - blackTS_ = blackTS; - riskFreeTS_ = riskFreeTS; - dividendTS_ = dividendTS; - underlying_ = new Handle(new SimpleQuote(underlying)); - - blackTS_.registerWith(update); - riskFreeTS_.registerWith(update); - dividendTS_.registerWith(update); - underlying_.registerWith(update); - } - - // TermStructure interface - public override Date referenceDate() { return blackTS_.link.referenceDate(); } - public override DayCounter dayCounter() { return blackTS_.link.dayCounter(); } - public override Date maxDate() { return blackTS_.link.maxDate(); } - - // VolatilityTermStructure interface - public override double minStrike() { return blackTS_.link.minStrike(); } - public override double maxStrike() { return blackTS_.link.maxStrike(); } - - protected override double localVolImpl(double t, double underlyingLevel) { - - double dr = riskFreeTS_.currentLink().discount(t, true); - double dq = dividendTS_.currentLink().discount(t, true); - double forwardValue = underlying_.currentLink().value() * dq / dr; - - // strike derivatives - double strike, y, dy, strikep, strikem; - double w, wp, wm, dwdy, d2wdy2; - strike = underlyingLevel; - y = Math.Log(strike/forwardValue); - dy = ((Math.Abs(y) > 0.001) ? y*0.0001 : 0.000001); - strikep=strike*Math.Exp(dy); - strikem=strike/Math.Exp(dy); - w = blackTS_.link.blackVariance(t, strike, true); - wp = blackTS_.link.blackVariance(t, strikep, true); - wm = blackTS_.link.blackVariance(t, strikem, true); - dwdy = (wp-wm)/(2.0*dy); - d2wdy2 = (wp-2.0*w+wm)/(dy*dy); - - // time derivative - double dt, wpt, wmt, dwdt; - if (t.IsEqual(0.0)) { - dt = 0.0001; - double drpt = riskFreeTS_.currentLink().discount(t + dt, true); - double dqpt = dividendTS_.currentLink().discount(t + dt, true); - double strikept = strike * dr * dqpt / (drpt * dq); - - wpt = blackTS_.link.blackVariance(t + dt, strikept, true); - - Utils.QL_REQUIRE(wpt>=w,()=> - "decreasing variance at strike " + strike + " between time " + t + " and time " + (t+dt)); - dwdt = (wpt-w)/dt; - } else { - dt = Math.Min(0.0001, t/2.0); - double drpt = riskFreeTS_.currentLink().discount(t + dt, true); - double drmt = riskFreeTS_.currentLink().discount(t - dt, true); - double dqpt = dividendTS_.currentLink().discount(t + dt, true); - double dqmt = dividendTS_.currentLink().discount(t - dt, true); - - double strikept = strike * dr * dqpt / (drpt * dq); - double strikemt = strike * dr * dqmt / (drmt * dq); - - wpt = blackTS_.link.blackVariance(t + dt, strikept, true); - wmt = blackTS_.link.blackVariance(t - dt, strikemt, true); - Utils.QL_REQUIRE(wpt>=w,()=> - "decreasing variance at strike " + strike + " between time " + t + " and time " + (t+dt)); - Utils.QL_REQUIRE(w>=wmt,()=> - "decreasing variance at strike " + strike + " between time " + (t-dt) + " and time " + t); - dwdt = (wpt-wmt)/(2.0*dt); - } - - if (dwdy.IsEqual(0.0) && d2wdy2.IsEqual(0.0)) { // avoid /w where w might be 0.0 - return Math.Sqrt(dwdt); - } else { - double den1 = 1.0 - y/w*dwdy; - double den2 = 0.25*(-0.25 - 1.0/w + y*y/w/w)*dwdy*dwdy; - double den3 = 0.5*d2wdy2; - double den = den1+den2+den3; - double result = dwdt / den; - Utils.QL_REQUIRE(result>=0.0,()=> - "negative local vol^2 at strike " + strike + " and time " + t + "; the black vol surface is not smooth enough"); - return Math.Sqrt(result); - } - } - } +namespace QLNet +{ + //! Local volatility surface derived from a Black vol surface + /*! For details about this implementation refer to + "Stochastic Volatility and Local Volatility," in + "Case Studies and Financial Modelling Course Notes," by + Jim Gatheral, Fall Term, 2003 + + see www.math.nyu.edu/fellows_fin_math/gatheral/Lecture1_Fall02.pdf + + \bug this class is untested, probably unreliable. + */ + public class LocalVolSurface : LocalVolTermStructure + { + Handle blackTS_; + Handle riskFreeTS_, dividendTS_; + Handle underlying_; + + public LocalVolSurface(Handle blackTS, Handle riskFreeTS, + Handle dividendTS, Handle underlying) + : base(blackTS.link.businessDayConvention(), blackTS.link.dayCounter()) + { + blackTS_ = blackTS; + riskFreeTS_ = riskFreeTS; + dividendTS_ = dividendTS; + underlying_ = underlying; + + blackTS_.registerWith(update); + riskFreeTS_.registerWith(update); + dividendTS_.registerWith(update); + underlying_.registerWith(update); + } + + public LocalVolSurface(Handle blackTS, Handle riskFreeTS, + Handle dividendTS, double underlying) + : base(blackTS.link.businessDayConvention(), blackTS.link.dayCounter()) + { + blackTS_ = blackTS; + riskFreeTS_ = riskFreeTS; + dividendTS_ = dividendTS; + underlying_ = new Handle(new SimpleQuote(underlying)); + + blackTS_.registerWith(update); + riskFreeTS_.registerWith(update); + dividendTS_.registerWith(update); + underlying_.registerWith(update); + } + + // TermStructure interface + public override Date referenceDate() { return blackTS_.link.referenceDate(); } + public override DayCounter dayCounter() { return blackTS_.link.dayCounter(); } + public override Date maxDate() { return blackTS_.link.maxDate(); } + + // VolatilityTermStructure interface + public override double minStrike() { return blackTS_.link.minStrike(); } + public override double maxStrike() { return blackTS_.link.maxStrike(); } + + protected override double localVolImpl(double t, double underlyingLevel) + { + + double dr = riskFreeTS_.currentLink().discount(t, true); + double dq = dividendTS_.currentLink().discount(t, true); + double forwardValue = underlying_.currentLink().value() * dq / dr; + + // strike derivatives + double strike, y, dy, strikep, strikem; + double w, wp, wm, dwdy, d2wdy2; + strike = underlyingLevel; + y = Math.Log(strike / forwardValue); + dy = ((Math.Abs(y) > 0.001) ? y * 0.0001 : 0.000001); + strikep = strike * Math.Exp(dy); + strikem = strike / Math.Exp(dy); + w = blackTS_.link.blackVariance(t, strike, true); + wp = blackTS_.link.blackVariance(t, strikep, true); + wm = blackTS_.link.blackVariance(t, strikem, true); + dwdy = (wp - wm) / (2.0 * dy); + d2wdy2 = (wp - 2.0 * w + wm) / (dy * dy); + + // time derivative + double dt, wpt, wmt, dwdt; + if (t.IsEqual(0.0)) + { + dt = 0.0001; + double drpt = riskFreeTS_.currentLink().discount(t + dt, true); + double dqpt = dividendTS_.currentLink().discount(t + dt, true); + double strikept = strike * dr * dqpt / (drpt * dq); + + wpt = blackTS_.link.blackVariance(t + dt, strikept, true); + + Utils.QL_REQUIRE(wpt >= w, () => + "decreasing variance at strike " + strike + " between time " + t + " and time " + (t + dt)); + dwdt = (wpt - w) / dt; + } + else + { + dt = Math.Min(0.0001, t / 2.0); + double drpt = riskFreeTS_.currentLink().discount(t + dt, true); + double drmt = riskFreeTS_.currentLink().discount(t - dt, true); + double dqpt = dividendTS_.currentLink().discount(t + dt, true); + double dqmt = dividendTS_.currentLink().discount(t - dt, true); + + double strikept = strike * dr * dqpt / (drpt * dq); + double strikemt = strike * dr * dqmt / (drmt * dq); + + wpt = blackTS_.link.blackVariance(t + dt, strikept, true); + wmt = blackTS_.link.blackVariance(t - dt, strikemt, true); + Utils.QL_REQUIRE(wpt >= w, () => + "decreasing variance at strike " + strike + " between time " + t + " and time " + (t + dt)); + Utils.QL_REQUIRE(w >= wmt, () => + "decreasing variance at strike " + strike + " between time " + (t - dt) + " and time " + t); + dwdt = (wpt - wmt) / (2.0 * dt); + } + + if (dwdy.IsEqual(0.0) && d2wdy2.IsEqual(0.0)) // avoid /w where w might be 0.0 + { + return Math.Sqrt(dwdt); + } + else + { + double den1 = 1.0 - y / w * dwdy; + double den2 = 0.25 * (-0.25 - 1.0 / w + y * y / w / w) * dwdy * dwdy; + double den3 = 0.5 * d2wdy2; + double den = den1 + den2 + den3; + double result = dwdt / den; + Utils.QL_REQUIRE(result >= 0.0, () => + "negative local vol^2 at strike " + strike + " and time " + t + "; the black vol surface is not smooth enough"); + return Math.Sqrt(result); + } + } + } } diff --git a/src/QLNet/Termstructures/Volatility/equityfx/LocalVolTermStructure.cs b/src/QLNet/Termstructures/Volatility/equityfx/LocalVolTermStructure.cs index 0668884ce..cdb10b339 100644 --- a/src/QLNet/Termstructures/Volatility/equityfx/LocalVolTermStructure.cs +++ b/src/QLNet/Termstructures/Volatility/equityfx/LocalVolTermStructure.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,14 +20,14 @@ under the terms of the QLNet license. You should have received a using System; -namespace QLNet +namespace QLNet { /*! This abstract class defines the interface of concrete local-volatility term structures which will be derived from this one. Volatilities are assumed to be expressed on an annual basis. */ - public abstract class LocalVolTermStructure : VolatilityTermStructure + public abstract class LocalVolTermStructure : VolatilityTermStructure { #region Constructors //! default constructor @@ -37,18 +37,18 @@ by overriding the referenceDate() method. */ protected LocalVolTermStructure(BusinessDayConvention bdc = BusinessDayConvention.Following, DayCounter dc = null) - :base(bdc, dc) {} - + : base(bdc, dc) {} + //! initialize with a fixed reference date - protected LocalVolTermStructure(Date referenceDate,Calendar cal = null, - BusinessDayConvention bdc = BusinessDayConvention.Following,DayCounter dc = null) - :base(referenceDate, cal, bdc, dc) {} - + protected LocalVolTermStructure(Date referenceDate, Calendar cal = null, + BusinessDayConvention bdc = BusinessDayConvention.Following, DayCounter dc = null) + : base(referenceDate, cal, bdc, dc) {} + //! calculate the reference date based on the global evaluation date - protected LocalVolTermStructure(int settlementDays,Calendar cal,BusinessDayConvention bdc = BusinessDayConvention.Following, - DayCounter dc = null) - :base(settlementDays, cal, bdc, dc) {} - + protected LocalVolTermStructure(int settlementDays, Calendar cal, BusinessDayConvention bdc = BusinessDayConvention.Following, + DayCounter dc = null) + : base(settlementDays, cal, bdc, dc) {} + #endregion #region Local Volatility @@ -75,7 +75,7 @@ These methods must be implemented in derived classes to perform range check has already been performed; therefore, they must assume that extrapolation is required. */ - + //! local vol calculation protected abstract double localVolImpl(double t, double strike); diff --git a/src/QLNet/Termstructures/Volatility/equityfx/NoExceptLocalVolSurface.cs b/src/QLNet/Termstructures/Volatility/equityfx/NoExceptLocalVolSurface.cs index a3678eb5e..9386e0b0f 100644 --- a/src/QLNet/Termstructures/Volatility/equityfx/NoExceptLocalVolSurface.cs +++ b/src/QLNet/Termstructures/Volatility/equityfx/NoExceptLocalVolSurface.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -26,20 +26,20 @@ namespace QLNet public class NoExceptLocalVolSurface : LocalVolSurface { public NoExceptLocalVolSurface(Handle blackTS, - Handle riskFreeTS, - Handle dividendTS, - Handle underlying, - double illegalLocalVolOverwrite) + Handle riskFreeTS, + Handle dividendTS, + Handle underlying, + double illegalLocalVolOverwrite) : base(blackTS, riskFreeTS, dividendTS, underlying) { illegalLocalVolOverwrite_ = illegalLocalVolOverwrite; } public NoExceptLocalVolSurface(Handle blackTS, - Handle riskFreeTS, - Handle dividendTS, - double underlying, - double illegalLocalVolOverwrite) + Handle riskFreeTS, + Handle dividendTS, + double underlying, + double illegalLocalVolOverwrite) : base(blackTS, riskFreeTS, dividendTS, underlying) { illegalLocalVolOverwrite_ = illegalLocalVolOverwrite; diff --git a/src/QLNet/Termstructures/Volatility/swaption/SpreadedSwaptionVolatility.cs b/src/QLNet/Termstructures/Volatility/swaption/SpreadedSwaptionVolatility.cs index 682ca986d..5a7337c25 100644 --- a/src/QLNet/Termstructures/Volatility/swaption/SpreadedSwaptionVolatility.cs +++ b/src/QLNet/Termstructures/Volatility/swaption/SpreadedSwaptionVolatility.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -18,13 +18,13 @@ namespace QLNet { public class SpreadedSwaptionVolatility : SwaptionVolatilityStructure { - public SpreadedSwaptionVolatility(Handle baseVol,Handle spread) - :base(baseVol.link.businessDayConvention(),baseVol.link.dayCounter()) + public SpreadedSwaptionVolatility(Handle baseVol, Handle spread) + : base(baseVol.link.businessDayConvention(), baseVol.link.dayCounter()) { baseVol_ = baseVol; spread_ = spread; - enableExtrapolation( baseVol.link.allowsExtrapolation() ); + enableExtrapolation(baseVol.link.allowsExtrapolation()); baseVol_.registerWith(update); spread_.registerWith(update); } @@ -43,29 +43,29 @@ public SpreadedSwaptionVolatility(Handle baseVol,Ha // SwaptionVolatilityStructure interface public override Period maxSwapTenor() { return baseVol_.link.maxSwapTenor(); } public override VolatilityType volatilityType() { return baseVol_.link.volatilityType(); } - + // SwaptionVolatilityStructure interface - protected override SmileSection smileSectionImpl(Date optionDate,Period swapTenor) + protected override SmileSection smileSectionImpl(Date optionDate, Period swapTenor) { SmileSection baseSmile = baseVol_.link.smileSection(optionDate, swapTenor, true); return new SpreadedSmileSection(baseSmile, spread_); } - protected override SmileSection smileSectionImpl(double optionTime,double swapLength) + protected override SmileSection smileSectionImpl(double optionTime, double swapLength) { SmileSection baseSmile = baseVol_.link.smileSection(optionTime, swapLength, true); return new SpreadedSmileSection(baseSmile, spread_); } - protected override double volatilityImpl(Date optionDate,Period swapTenor,double strike) + protected override double volatilityImpl(Date optionDate, Period swapTenor, double strike) { - return baseVol_.link.volatility( optionDate, swapTenor, strike, true ) + spread_.link.value(); + return baseVol_.link.volatility(optionDate, swapTenor, strike, true) + spread_.link.value(); } - protected override double volatilityImpl(double optionTime,double swapLength,double strike) + protected override double volatilityImpl(double optionTime, double swapLength, double strike) { - return baseVol_.link.volatility( optionTime, swapLength, strike, true ) + spread_.link.value(); + return baseVol_.link.volatility(optionTime, swapLength, strike, true) + spread_.link.value(); } - protected override double shiftImpl( double optionTime, double swapLength ) + protected override double shiftImpl(double optionTime, double swapLength) { - return baseVol_.link.shift( optionTime, swapLength, true ); + return baseVol_.link.shift(optionTime, swapLength, true); } private Handle baseVol_; diff --git a/src/QLNet/Termstructures/Volatility/swaption/SwaptionConstantVol.cs b/src/QLNet/Termstructures/Volatility/swaption/SwaptionConstantVol.cs new file mode 100644 index 000000000..bb2adb3b3 --- /dev/null +++ b/src/QLNet/Termstructures/Volatility/swaption/SwaptionConstantVol.cs @@ -0,0 +1,153 @@ +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! Constant swaption volatility, no time-strike dependence + public class ConstantSwaptionVolatility : SwaptionVolatilityStructure + { + private Handle volatility_; + private Period maxSwapTenor_; + private VolatilityType volatilityType_; + private double? shift_; + + //! floating reference date, floating market data + public ConstantSwaptionVolatility(int settlementDays, + Calendar cal, + BusinessDayConvention bdc, + Handle vol, + DayCounter dc, + VolatilityType type = VolatilityType.ShiftedLognormal, + double? shift = 0.0) + : base(settlementDays, cal, bdc, dc) + { + volatility_ = vol; + maxSwapTenor_ = new Period(100, TimeUnit.Years); + volatilityType_ = type; + shift_ = shift; + volatility_.registerWith(update); + } + + //! fixed reference date, floating market data + public ConstantSwaptionVolatility(Date referenceDate, + Calendar cal, + BusinessDayConvention bdc, + Handle vol, + DayCounter dc, + VolatilityType type = VolatilityType.ShiftedLognormal, + double? shift = 0.0) + + : base(referenceDate, cal, bdc, dc) + { + volatility_ = vol; + maxSwapTenor_ = new Period(100, TimeUnit.Years); + volatilityType_ = type; + shift_ = shift; + volatility_.registerWith(update); + } + + //! floating reference date, fixed market data + public ConstantSwaptionVolatility(int settlementDays, + Calendar cal, + BusinessDayConvention bdc, + double vol, + DayCounter dc, + VolatilityType type = VolatilityType.ShiftedLognormal, + double? shift = 0.0) + : base(settlementDays, cal, bdc, dc) + { + volatility_ = new Handle(new SimpleQuote(vol)); + maxSwapTenor_ = new Period(100, TimeUnit.Years); + volatilityType_ = type; + shift_ = shift; + } + + //! fixed reference date, fixed market data + public ConstantSwaptionVolatility(Date referenceDate, + Calendar cal, + BusinessDayConvention bdc, + double vol, + DayCounter dc, + VolatilityType type = VolatilityType.ShiftedLognormal, + double? shift = 0.0) + : base(referenceDate, cal, bdc, dc) + { + volatility_ = new Handle(new SimpleQuote(vol)); + maxSwapTenor_ = new Period(100, TimeUnit.Years); + volatilityType_ = type; + shift_ = shift; + } + + // TermStructure interface + public override Date maxDate() + { + return Date.maxDate(); + } + // VolatilityTermStructure interface + public override double minStrike() + { + return double.MinValue; + } + + public override double maxStrike() + { + return double.MaxValue; + } + + // SwaptionVolatilityStructure interface + public override Period maxSwapTenor() + { + return maxSwapTenor_; + } + + public override VolatilityType volatilityType() + { + return volatilityType_; + } + + protected new SmileSection smileSectionImpl(Date d, Period p) + { + double atmVol = volatility_.link.value(); + return new FlatSmileSection(d, atmVol, dayCounter(), referenceDate()); + } + + protected override SmileSection smileSectionImpl(double optionTime, double time) + { + double atmVol = volatility_.link.value(); + return new FlatSmileSection(optionTime, atmVol, dayCounter()); + } + + protected new double volatilityImpl(Date date, Period period, double rate) + { + return volatility_.link.value(); + } + + protected override double volatilityImpl(double time, double t, double rate) + { + return volatility_.link.value(); + } + + protected override double shiftImpl(double optionTime, double swapLength) + { + base.shiftImpl(optionTime, swapLength); + return Convert.ToDouble(shift_); + } + } +} diff --git a/src/QLNet/Termstructures/Volatility/swaption/SwaptionVolCube1.cs b/src/QLNet/Termstructures/Volatility/swaption/SwaptionVolCube1.cs index 67f9755f4..aa478a591 100644 --- a/src/QLNet/Termstructures/Volatility/swaption/SwaptionVolCube1.cs +++ b/src/QLNet/Termstructures/Volatility/swaption/SwaptionVolCube1.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -28,13 +28,13 @@ namespace QLNet public class SwaptionVolCube1x : SwaptionVolatilityCube { - const double SWAPTIONVOLCUBE_VEGAWEIGHTED_TOL=15.0e-4 ; + const double SWAPTIONVOLCUBE_VEGAWEIGHTED_TOL = 15.0e-4 ; const double SWAPTIONVOLCUBE_TOL = 100.0e-4 ; - public delegate SABRInterpolation GetInterpolation( GeneralizedBlackScholesProcess process ); + public delegate SABRInterpolation GetInterpolation(GeneralizedBlackScholesProcess process); - public class Cube + public class Cube { public Cube() {} public Cube(List optionDates, @@ -45,21 +45,21 @@ public Cube(List optionDates, bool extrapolation = true, bool backwardFlat = false) { - optionTimes_ = new List(optionTimes); + optionTimes_ = new List(optionTimes); swapLengths_ = new List(swapLengths); - optionDates_ = new List(optionDates); + optionDates_ = new List(optionDates); swapTenors_ = new List(swapTenors); - nLayers_ = nLayers; + nLayers_ = nLayers; extrapolation_ = extrapolation; backwardFlat_ = backwardFlat; interpolators_ = new List(); transposedPoints_ = new List(); - - Utils.QL_REQUIRE(optionTimes.Count>1,()=> "Cube::Cube(...): optionTimes.size()<2"); - Utils.QL_REQUIRE(swapLengths.Count>1,()=> "Cube::Cube(...): swapLengths.size()<2"); - Utils.QL_REQUIRE(optionTimes.Count==optionDates.Count,()=>"Cube::Cube(...): optionTimes/optionDates mismatch"); - Utils.QL_REQUIRE(swapTenors.Count==swapLengths.Count,()=> "Cube::Cube(...): swapTenors/swapLengths mismatch"); + Utils.QL_REQUIRE(optionTimes.Count > 1, () => "Cube::Cube(...): optionTimes.size()<2"); + Utils.QL_REQUIRE(swapLengths.Count > 1, () => "Cube::Cube(...): swapLengths.size()<2"); + + Utils.QL_REQUIRE(optionTimes.Count == optionDates.Count, () => "Cube::Cube(...): optionTimes/optionDates mismatch"); + Utils.QL_REQUIRE(swapTenors.Count == swapLengths.Count, () => "Cube::Cube(...): swapTenors/swapLengths mismatch"); List points = new InitializedList(nLayers_); for (int i = 0; i < nLayers ; i++) @@ -67,17 +67,17 @@ public Cube(List optionDates, points[i] = new Matrix(optionTimes_.Count, swapLengths_.Count, 0.0); } - for (int k=0;k"Cube::setElement: incompatible IndexOfLayer "); - Utils.QL_REQUIRE(IndexOfRow"Cube::setElement: incompatible IndexOfRow"); - Utils.QL_REQUIRE(IndexOfColumn"Cube::setElement: incompatible IndexOfColumn"); + Utils.QL_REQUIRE(IndexOfLayer "Cube::setElement: incompatible IndexOfLayer "); + Utils.QL_REQUIRE(IndexOfRow "Cube::setElement: incompatible IndexOfRow"); + Utils.QL_REQUIRE(IndexOfColumn "Cube::setElement: incompatible IndexOfColumn"); Matrix p = points_[IndexOfLayer]; - p[IndexOfRow,IndexOfColumn] = x; + p[IndexOfRow, IndexOfColumn] = x; } public void setPoints(List x) { - Utils.QL_REQUIRE(x.Count==nLayers_,()=>"Cube::setPoints: incompatible number of layers "); - Utils.QL_REQUIRE(x[0].rows()==optionTimes_.Count,()=>"Cube::setPoints: incompatible size 1"); - Utils.QL_REQUIRE(x[0].columns()==swapLengths_.Count,()=>"Cube::setPoints: incompatible size 2"); + Utils.QL_REQUIRE(x.Count == nLayers_, () => "Cube::setPoints: incompatible number of layers "); + Utils.QL_REQUIRE(x[0].rows() == optionTimes_.Count, () => "Cube::setPoints: incompatible size 1"); + Utils.QL_REQUIRE(x[0].columns() == swapLengths_.Count, () => "Cube::setPoints: incompatible size 2"); points_ = x; } - public void setPoint(Date optionDate,Period swapTenor,double optionTime,double swapLength,List point) + public void setPoint(Date optionDate, Period swapTenor, double optionTime, double swapLength, List point) { bool expandOptionTimes = !optionTimes_.Exists(x => x.IsEqual(optionTime)); bool expandSwapLengths = !swapLengths_.Exists(x => x.IsEqual(swapLength)); - double optionTimesPreviousNode,swapLengthsPreviousNode; + double optionTimesPreviousNode, swapLengthsPreviousNode; optionTimesPreviousNode = optionTimes_.First(x => x >= Math.Min(optionTime, optionTimes_.Max())); int optionTimesIndex = optionTimes_.IndexOf(optionTimesPreviousNode); @@ -173,12 +173,12 @@ public void setPoint(Date optionDate,Period swapTenor,double optionTime,double s int swapLengthsIndex = swapLengths_.IndexOf(swapLengthsPreviousNode); if (expandOptionTimes || expandSwapLengths) - expandLayers(optionTimesIndex, expandOptionTimes,swapLengthsIndex, expandSwapLengths); + expandLayers(optionTimesIndex, expandOptionTimes, swapLengthsIndex, expandSwapLengths); - for (int k=0; k"Cube::setLayer: incompatible number of layer "); - Utils.QL_REQUIRE(x.rows()==optionTimes_.Count,()=>"Cube::setLayer: incompatible size 1"); - Utils.QL_REQUIRE(x.columns()==swapLengths_.Count,()=>"Cube::setLayer: incompatible size 2"); + Utils.QL_REQUIRE(i "Cube::setLayer: incompatible number of layer "); + Utils.QL_REQUIRE(x.rows() == optionTimes_.Count, () => "Cube::setLayer: incompatible size 1"); + Utils.QL_REQUIRE(x.columns() == swapLengths_.Count, () => "Cube::setLayer: incompatible size 2"); points_[i] = x; } - public void expandLayers(int i,bool expandOptionTimes,int j,bool expandSwapLengths) + public void expandLayers(int i, bool expandOptionTimes, int j, bool expandSwapLengths) { - Utils.QL_REQUIRE(i<=optionTimes_.Count,()=>"Cube::expandLayers: incompatible size 1"); - Utils.QL_REQUIRE(j<=swapLengths_.Count,()=>"Cube::expandLayers: incompatible size 2"); + Utils.QL_REQUIRE(i <= optionTimes_.Count, () => "Cube::expandLayers: incompatible size 1"); + Utils.QL_REQUIRE(j <= swapLengths_.Count, () => "Cube::expandLayers: incompatible size 2"); - if (expandOptionTimes) + if (expandOptionTimes) { - optionTimes_.Insert(i,0.0); + optionTimes_.Insert(i, 0.0); optionDates_.Insert(i, new Date()); } - if (expandSwapLengths) + if (expandSwapLengths) { - swapLengths_.Insert(j,0.0); + swapLengths_.Insert(j, 0.0); swapTenors_.Insert(j, new Period()); } - List newPoints= new InitializedList(nLayers_); + List newPoints = new InitializedList(nLayers_); for (int ii = 0; ii < nLayers_ ; ii++) { - newPoints[ii] = new Matrix(optionTimes_.Count, swapLengths_.Count, 0.0); + newPoints[ii] + = new Matrix(optionTimes_.Count, swapLengths_.Count, 0.0); } - for (int k=0; k=i && expandOptionTimes) indexOfRow = u+1; - for (int v=0; v= i && expandOptionTimes) + indexOfRow = u + 1; + for (int v = 0; v < points_[k].columns(); ++v) { int indexOfCol = v; - if (v>=j && expandSwapLengths) indexOfCol = v+1; - Matrix p=newPoints[k],p1 = points_[k]; - p[indexOfRow,indexOfCol]=p1[u,v]; + if (v >= j && expandSwapLengths) + indexOfCol = v + 1; + Matrix p = newPoints[k], p1 = points_[k]; + p[indexOfRow, indexOfCol] = p1[u, v]; } } } @@ -240,52 +243,52 @@ public void expandLayers(int i,bool expandOptionTimes,int j,bool expandSwapLengt public List optionTimes() {return optionTimes_;} public List swapLengths() { return swapLengths_;} public List points() { return points_;} - public List value(double optionTime,double swapLength) + public List value(double optionTime, double swapLength) { List result = new List(); - for (int k=0; k optionTimes_, swapLengths_; private List optionDates_; private List swapTenors_; @@ -295,7 +298,7 @@ public Matrix browse() private bool extrapolation_; private bool backwardFlat_; private List< Interpolation2D > interpolators_; - }; + } public SwaptionVolCube1x(Handle atmVolStructure, List optionTenors, @@ -316,32 +319,33 @@ public SwaptionVolCube1x(Handle atmVolStructure, int maxGuesses = 50, bool backwardFlat = false, double cutoffStrike = 0.0001) - :base(atmVolStructure, optionTenors, swapTenors,strikeSpreads, volSpreads, swapIndexBase, - shortSwapIndexBase, vegaWeightedSmileFit) + : base(atmVolStructure, optionTenors, swapTenors, strikeSpreads, volSpreads, swapIndexBase, + shortSwapIndexBase, vegaWeightedSmileFit) { parametersGuessQuotes_ = parametersGuess; isParameterFixed_ = isParameterFixed; - isAtmCalibrated_ = isAtmCalibrated; + isAtmCalibrated_ = isAtmCalibrated; endCriteria_ = endCriteria; optMethod_ = optMethod; - useMaxError_ = useMaxError; + useMaxError_ = useMaxError; maxGuesses_ = maxGuesses; backwardFlat_ = backwardFlat; cutoffStrike_ = cutoffStrike; - if (maxErrorTolerance != null) + if (maxErrorTolerance != null) { maxErrorTolerance_ = maxErrorTolerance.Value; - } + } else { maxErrorTolerance_ = SWAPTIONVOLCUBE_TOL; - if (vegaWeightedSmileFit_) maxErrorTolerance_ = SWAPTIONVOLCUBE_VEGAWEIGHTED_TOL; + if (vegaWeightedSmileFit_) + maxErrorTolerance_ = SWAPTIONVOLCUBE_VEGAWEIGHTED_TOL; } - if (errorAccept != null) + if (errorAccept != null) { errorAccept_ = errorAccept.Value; - } + } else { errorAccept_ = maxErrorTolerance_ / 5.0; @@ -357,18 +361,18 @@ protected override void performCalculations() base.performCalculations(); //! set marketVolCube_ by volSpreads_ quotes - marketVolCube_ = new Cube(optionDates_, swapTenors_,optionTimes_, swapLengths_, nStrikes_); + marketVolCube_ = new Cube(optionDates_, swapTenors_, optionTimes_, swapLengths_, nStrikes_); double atmForward; double atmVol, vol; - for (int j=0; j optionTimes = marketVolCube.optionTimes(); List swapLengths = marketVolCube.swapLengths(); @@ -429,109 +433,109 @@ public void sabrCalibrationSection(Cube marketVolCube,Cube parametersCube,Period Utils.QL_REQUIRE(k != swapTenors.Count, () => "swap tenor not found"); - List calibrationResult = new InitializedList(8,0.0); + List calibrationResult = new InitializedList(8, 0.0); List tmpMarketVolCube = marketVolCube.points(); List strikes = new List(strikeSpreads_.Count); List volatilities = new List(strikeSpreads_.Count); - for (int j=0; j=cutoffStrike_) + double strike = atmForward + strikeSpreads_[i]; + if (strike + shiftTmp >= cutoffStrike_) { strikes.Add(strike); - volatilities.Add(tmpMarketVolCube[i][j,k]); + volatilities.Add(tmpMarketVolCube[i][j, k]); } } List guess = parametersGuess_.value(optionTimes[j], swapLengths[k]); - var sabrInterpolation = new SABRInterpolation (strikes, - strikes.Count, - volatilities, - optionTimes[j], atmForward, - guess[0], guess[1], - guess[2], guess[3], - isParameterFixed_[0], - isParameterFixed_[1], - isParameterFixed_[2], - isParameterFixed_[3], - vegaWeightedSmileFit_, - endCriteria_, - optMethod_, - errorAccept_, - useMaxError_, - maxGuesses_, - shiftTmp, - volatilityType());//shiftTmp + var sabrInterpolation = new SABRInterpolation(strikes, + strikes.Count, + volatilities, + optionTimes[j], atmForward, + guess[0], guess[1], + guess[2], guess[3], + isParameterFixed_[0], + isParameterFixed_[1], + isParameterFixed_[2], + isParameterFixed_[3], + vegaWeightedSmileFit_, + endCriteria_, + optMethod_, + errorAccept_, + useMaxError_, + maxGuesses_, + shiftTmp, + volatilityType());//shiftTmp sabrInterpolation.update(); double interpolationError = sabrInterpolation.rmsError(); - calibrationResult[0]=sabrInterpolation.alpha(); - calibrationResult[1]=sabrInterpolation.beta(); - calibrationResult[2]=sabrInterpolation.nu(); - calibrationResult[3]=sabrInterpolation.rho(); - calibrationResult[4]=atmForward; - calibrationResult[5]=interpolationError; - calibrationResult[6]=sabrInterpolation.maxError(); - calibrationResult[7]=(double)sabrInterpolation.endCriteria(); - - Utils.QL_REQUIRE(calibrationResult[7].IsNotEqual((double)EndCriteria.Type.MaxIterations),()=> - "section calibration failed: " + - "option tenor " + optionDates[j] + - ", swap tenor " + swapTenors[k] + - ": max iteration (" + - endCriteria_.maxIterations() + ")" + - ", alpha " + calibrationResult[0]+ - ", beta " + calibrationResult[1] + - ", nu " + calibrationResult[2] + - ", rho " + calibrationResult[3] + - ", max error " + calibrationResult[6] + - ", error " + calibrationResult[5] - ); - - Utils.QL_REQUIRE(useMaxError_ ? calibrationResult[6] > 0 : calibrationResult[5] < maxErrorTolerance_,()=> - "section calibration failed: "+ - "option tenor " + optionDates[j] + - ", swap tenor " + swapTenors[k] + - (useMaxError_ ? ": max error " : ": error ") + - (useMaxError_ ? calibrationResult[6] : calibrationResult[5]) + - ", alpha " + calibrationResult[0] + - ", beta " + calibrationResult[1] + - ", nu " + calibrationResult[2] + - ", rho " + calibrationResult[3] + - (useMaxError_ ? ": error" : ": max error ") + - (useMaxError_ ? calibrationResult[5] : calibrationResult[6]) - ); - - parametersCube.setPoint(optionDates[j], swapTenors[k],optionTimes[j], swapLengths[k],calibrationResult); + calibrationResult[0] = sabrInterpolation.alpha(); + calibrationResult[1] = sabrInterpolation.beta(); + calibrationResult[2] = sabrInterpolation.nu(); + calibrationResult[3] = sabrInterpolation.rho(); + calibrationResult[4] = atmForward; + calibrationResult[5] = interpolationError; + calibrationResult[6] = sabrInterpolation.maxError(); + calibrationResult[7] = (double)sabrInterpolation.endCriteria(); + + Utils.QL_REQUIRE(calibrationResult[7].IsNotEqual((double)EndCriteria.Type.MaxIterations), () => + "section calibration failed: " + + "option tenor " + optionDates[j] + + ", swap tenor " + swapTenors[k] + + ": max iteration (" + + endCriteria_.maxIterations() + ")" + + ", alpha " + calibrationResult[0] + + ", beta " + calibrationResult[1] + + ", nu " + calibrationResult[2] + + ", rho " + calibrationResult[3] + + ", max error " + calibrationResult[6] + + ", error " + calibrationResult[5] + ); + + Utils.QL_REQUIRE(useMaxError_ ? calibrationResult[6] > 0 : calibrationResult[5] < maxErrorTolerance_, () => + "section calibration failed: " + + "option tenor " + optionDates[j] + + ", swap tenor " + swapTenors[k] + + (useMaxError_ ? ": max error " : ": error ") + + (useMaxError_ ? calibrationResult[6] : calibrationResult[5]) + + ", alpha " + calibrationResult[0] + + ", beta " + calibrationResult[1] + + ", nu " + calibrationResult[2] + + ", rho " + calibrationResult[3] + + (useMaxError_ ? ": error" : ": max error ") + + (useMaxError_ ? calibrationResult[5] : calibrationResult[6]) + ); + + parametersCube.setPoint(optionDates[j], swapTenors[k], optionTimes[j], swapLengths[k], calibrationResult); parametersCube.updateInterpolators(); - } + } } public void recalibration(double beta, Period swapTenor) { List betaVector = new InitializedList(nOptionTenors_, beta); - recalibration(betaVector,swapTenor); + recalibration(betaVector, swapTenor); } - public void recalibration(List beta,Period swapTenor) + public void recalibration(List beta, Period swapTenor) { - Utils.QL_REQUIRE(beta.Count == nOptionTenors_,()=> - "beta size (" + beta.Count + ") must be equal to number of option tenors (" + nOptionTenors_ + ")"); + Utils.QL_REQUIRE(beta.Count == nOptionTenors_, () => + "beta size (" + beta.Count + ") must be equal to number of option tenors (" + nOptionTenors_ + ")"); List swapTenors = marketVolCube_.swapTenors(); int k = swapTenors.IndexOf(swapTenors.First(x => x == swapTenor)); - Utils.QL_REQUIRE(k != swapTenors.Count,()=> "swap tenor (" + swapTenor + ") not found"); + Utils.QL_REQUIRE(k != swapTenors.Count, () => "swap tenor (" + swapTenor + ") not found"); - for (int i = 0; i < nOptionTenors_; ++i) + for (int i = 0; i < nOptionTenors_; ++i) { parametersGuess_.setElement(1, i, k, beta[i]); } @@ -540,34 +544,34 @@ public void recalibration(List beta,Period swapTenor) sabrCalibrationSection(marketVolCube_, sparseParameters_, swapTenor); volCubeAtmCalibrated_ = marketVolCube_; - if (isAtmCalibrated_) + if (isAtmCalibrated_) { fillVolatilityCube(); - sabrCalibrationSection(volCubeAtmCalibrated_, denseParameters_,swapTenor); + sabrCalibrationSection(volCubeAtmCalibrated_, denseParameters_, swapTenor); } notifyObservers(); } - public void recalibration(List swapLengths,List beta, Period swapTenor) + public void recalibration(List swapLengths, List beta, Period swapTenor) { - Utils.QL_REQUIRE(beta.Count == swapLengths.Count,()=> - "beta size (" + beta.Count + ") must be equal to number of swap lenghts (" - + swapLengths.Count + ")"); + Utils.QL_REQUIRE(beta.Count == swapLengths.Count, () => + "beta size (" + beta.Count + ") must be equal to number of swap lenghts (" + + swapLengths.Count + ")"); List betaTimes = new List(); for (int i = 0; i < beta.Count; i++) betaTimes.Add(timeFromReference(optionDateFromTenor(swapLengths[i]))); - LinearInterpolation betaInterpolation = new LinearInterpolation(betaTimes,betaTimes.Count, beta); + LinearInterpolation betaInterpolation = new LinearInterpolation(betaTimes, betaTimes.Count, beta); List cubeBeta = new List(); - for (int i = 0; i < optionTimes().Count; i++) + for (int i = 0; i < optionTimes().Count; i++) { double t = optionTimes()[i]; // flat extrapolation ensures admissable values if (t < betaTimes.First()) - t = betaTimes.First(); + t = betaTimes.First(); if (t > betaTimes.Last()) - t = betaTimes.Last(); + t = betaTimes.Last(); cubeBeta.Add(betaInterpolation.value(t)); } @@ -577,7 +581,7 @@ public void recalibration(List swapLengths,List beta, Period swa public void updateAfterRecalibration() { volCubeAtmCalibrated_ = marketVolCube_; - if(isAtmCalibrated_) + if (isAtmCalibrated_) { fillVolatilityCube(); denseParameters_ = sabrCalibration(volCubeAtmCalibrated_); @@ -585,34 +589,34 @@ public void updateAfterRecalibration() } notifyObservers(); } - + protected void registerWithParametersGuess() { - for (int i=0; i<4; i++) - for (int j=0; j sabrParameters = sabrParametersCube.value(optionTime, swapLength); - double shiftTmp = atmVol_.link.shift(optionTime,swapLength); - return new SabrSmileSection( optionTime, sabrParameters[4], sabrParameters, volatilityType(), shiftTmp ); // ,shiftTmp + double shiftTmp = atmVol_.link.shift(optionTime, swapLength); + return new SabrSmileSection(optionTime, sabrParameters[4], sabrParameters, volatilityType(), shiftTmp); // ,shiftTmp } protected Cube sabrCalibration(Cube marketVolCube) { @@ -621,111 +625,111 @@ protected Cube sabrCalibration(Cube marketVolCube) List optionDates = marketVolCube.optionDates(); List swapTenors = marketVolCube.swapTenors(); Matrix alphas = new Matrix(optionTimes.Count, swapLengths.Count, 0.0); - Matrix betas= new Matrix(alphas); - Matrix nus= new Matrix(alphas); - Matrix rhos= new Matrix(alphas); - Matrix forwards=new Matrix(alphas); - Matrix errors=new Matrix(alphas); - Matrix maxErrors=new Matrix(alphas); - Matrix endCriteria=new Matrix(alphas); + Matrix betas = new Matrix(alphas); + Matrix nus = new Matrix(alphas); + Matrix rhos = new Matrix(alphas); + Matrix forwards = new Matrix(alphas); + Matrix errors = new Matrix(alphas); + Matrix maxErrors = new Matrix(alphas); + Matrix endCriteria = new Matrix(alphas); List tmpMarketVolCube = marketVolCube.points(); - List strikes=new InitializedList(strikeSpreads_.Count); - List volatilities=new InitializedList(strikeSpreads_.Count); + List strikes = new InitializedList(strikeSpreads_.Count); + List volatilities = new InitializedList(strikeSpreads_.Count); - for (int j=0; j= cutoffStrike_) + double strike = atmForward + strikeSpreads_[i]; + if (strike + shiftTmp >= cutoffStrike_) { strikes.Add(strike); Matrix matrix = tmpMarketVolCube[i]; - volatilities.Add(matrix[j,k]); + volatilities.Add(matrix[j, k]); } } List guess = parametersGuess_.value(optionTimes[j], swapLengths[k]); - + SABRInterpolation sabrInterpolation = new SABRInterpolation(strikes, strikes.Count, - volatilities, - optionTimes[j], atmForward, - guess[0], guess[1], - guess[2], guess[3], - isParameterFixed_[0], - isParameterFixed_[1], - isParameterFixed_[2], - isParameterFixed_[3], - vegaWeightedSmileFit_, - endCriteria_, - optMethod_, - errorAccept_, - useMaxError_, - maxGuesses_, - shiftTmp, - volatilityType());// shiftTmp + volatilities, + optionTimes[j], atmForward, + guess[0], guess[1], + guess[2], guess[3], + isParameterFixed_[0], + isParameterFixed_[1], + isParameterFixed_[2], + isParameterFixed_[3], + vegaWeightedSmileFit_, + endCriteria_, + optMethod_, + errorAccept_, + useMaxError_, + maxGuesses_, + shiftTmp, + volatilityType());// shiftTmp sabrInterpolation.update(); double rmsError = sabrInterpolation.rmsError(); double maxError = sabrInterpolation.maxError(); - alphas [j,k] = sabrInterpolation.alpha(); - betas [j,k] = sabrInterpolation.beta(); - nus [j,k] = sabrInterpolation.nu(); - rhos [j,k] = sabrInterpolation.rho(); - forwards [j,k] = atmForward; - errors [j,k] = rmsError; - maxErrors [j,k] = maxError; - endCriteria[j,k] = (double)sabrInterpolation.endCriteria(); - - Utils.QL_REQUIRE(endCriteria[j,k].IsNotEqual((double) EndCriteria.Type.MaxIterations),()=> - "global swaptions calibration failed: "+ - "MaxIterations reached: " + "\n" + - "option maturity = " + optionDates[j] + ", \n" + - "swap tenor = " + swapTenors[k] + ", \n" + - "error = " + (errors[j,k]) + ", \n" + - "max error = " + (maxErrors[j,k]) + ", \n" + - " alpha = " + alphas[j,k] + "n" + - " beta = " + betas[j,k] + "\n" + - " nu = " + nus[j,k] + "\n" + - " rho = " + rhos[j,k] + "\n" - ); - - Utils.QL_REQUIRE(useMaxError_ ? maxError > 0 : rmsError < maxErrorTolerance_,()=> - "global swaptions calibration failed: " + - "option tenor " + optionDates[j] + - ", swap tenor " + swapTenors[k] + - (useMaxError_ ? ": max error " : ": error") + - (useMaxError_ ? maxError : rmsError) + - " alpha = " + alphas[j,k] + "\n" + - " beta = " + betas[j,k] + "\n" + - " nu = " + nus[j,k] + "\n" + - " rho = " + rhos[j,k] + "\n" + - (useMaxError_ ? ": error" : ": max error ") + - (useMaxError_ ? rmsError :maxError) - - ); + alphas [j, k] = sabrInterpolation.alpha(); + betas [j, k] = sabrInterpolation.beta(); + nus [j, k] = sabrInterpolation.nu(); + rhos [j, k] = sabrInterpolation.rho(); + forwards [j, k] = atmForward; + errors [j, k] = rmsError; + maxErrors [j, k] = maxError; + endCriteria[j, k] = (double)sabrInterpolation.endCriteria(); + + Utils.QL_REQUIRE(endCriteria[j, k].IsNotEqual((double) EndCriteria.Type.MaxIterations), () => + "global swaptions calibration failed: " + + "MaxIterations reached: " + "\n" + + "option maturity = " + optionDates[j] + ", \n" + + "swap tenor = " + swapTenors[k] + ", \n" + + "error = " + (errors[j, k]) + ", \n" + + "max error = " + (maxErrors[j, k]) + ", \n" + + " alpha = " + alphas[j, k] + "n" + + " beta = " + betas[j, k] + "\n" + + " nu = " + nus[j, k] + "\n" + + " rho = " + rhos[j, k] + "\n" + ); + + Utils.QL_REQUIRE(useMaxError_ ? maxError > 0 : rmsError < maxErrorTolerance_, () => + "global swaptions calibration failed: " + + "option tenor " + optionDates[j] + + ", swap tenor " + swapTenors[k] + + (useMaxError_ ? ": max error " : ": error") + + (useMaxError_ ? maxError : rmsError) + + " alpha = " + alphas[j, k] + "\n" + + " beta = " + betas[j, k] + "\n" + + " nu = " + nus[j, k] + "\n" + + " rho = " + rhos[j, k] + "\n" + + (useMaxError_ ? ": error" : ": max error ") + + (useMaxError_ ? rmsError : maxError) + + ); } - } - Cube sabrParametersCube = new Cube(optionDates, swapTenors,optionTimes, swapLengths, 8,true, backwardFlat_); - sabrParametersCube.setLayer(0, alphas); - sabrParametersCube.setLayer(1, betas); - sabrParametersCube.setLayer(2, nus); - sabrParametersCube.setLayer(3, rhos); - sabrParametersCube.setLayer(4, forwards); - sabrParametersCube.setLayer(5, errors); - sabrParametersCube.setLayer(6, maxErrors); - sabrParametersCube.setLayer(7, endCriteria); - - return sabrParametersCube; + } + Cube sabrParametersCube = new Cube(optionDates, swapTenors, optionTimes, swapLengths, 8, true, backwardFlat_); + sabrParametersCube.setLayer(0, alphas); + sabrParametersCube.setLayer(1, betas); + sabrParametersCube.setLayer(2, nus); + sabrParametersCube.setLayer(3, rhos); + sabrParametersCube.setLayer(4, forwards); + sabrParametersCube.setLayer(5, errors); + sabrParametersCube.setLayer(6, maxErrors); + sabrParametersCube.setLayer(7, endCriteria); + + return sabrParametersCube; } protected void fillVolatilityCube() @@ -734,74 +738,75 @@ protected void fillVolatilityCube() List atmOptionTimes = new List(atmVolStructure.optionTimes()); List optionTimes = new List(volCubeAtmCalibrated_.optionTimes()); - atmOptionTimes.InsertRange(atmOptionTimes.Count,optionTimes); + atmOptionTimes.InsertRange(atmOptionTimes.Count, optionTimes); atmOptionTimes.Sort(); atmOptionTimes = atmOptionTimes.Distinct().ToList(); List atmSwapLengths = new List(atmVolStructure.swapLengths()); List swapLengths = new List(volCubeAtmCalibrated_.swapLengths()); - atmSwapLengths.InsertRange(atmSwapLengths.Count,swapLengths); + atmSwapLengths.InsertRange(atmSwapLengths.Count, swapLengths); atmSwapLengths.Sort(); atmSwapLengths = atmSwapLengths.Distinct().ToList(); List atmOptionDates = new List(atmVolStructure.optionDates()); List optionDates = new List(volCubeAtmCalibrated_.optionDates()); - atmOptionDates.InsertRange(atmOptionDates.Count,optionDates); + atmOptionDates.InsertRange(atmOptionDates.Count, optionDates); atmOptionDates.Sort(); atmOptionDates = atmOptionDates.Distinct().ToList(); List atmSwapTenors = new List(atmVolStructure.swapTenors()); List swapTenors = new List(volCubeAtmCalibrated_.swapTenors()); - atmSwapTenors.InsertRange(atmSwapTenors.Count,swapTenors); + atmSwapTenors.InsertRange(atmSwapTenors.Count, swapTenors); atmSwapTenors.Sort(); atmSwapTenors = atmSwapTenors.Distinct().ToList(); - + createSparseSmiles(); - - for (int j=0; j x.IsEqual(atmOptionTimes[j])); bool expandSwapLengths = !swapLengths.Exists(x => x.IsEqual(atmSwapLengths[k])); - if(expandOptionTimes || expandSwapLengths) + if (expandOptionTimes || expandSwapLengths) { - double atmForward = atmStrike(atmOptionDates[j],atmSwapTenors[k]); + double atmForward = atmStrike(atmOptionDates[j], atmSwapTenors[k]); double atmVol = atmVol_.link.volatility(atmOptionDates[j], atmSwapTenors[k], atmForward); - List spreadVols = spreadVolInterpolation(atmOptionDates[j],atmSwapTenors[k]); + List spreadVols = spreadVolInterpolation(atmOptionDates[j], atmSwapTenors[k]); List volAtmCalibrated = new List(nStrikes_); - for (int i=0; i optionTimes = new List(sparseParameters_.optionTimes()); List swapLengths = new List(sparseParameters_.swapLengths()); - if (sparseSmiles_ == null) sparseSmiles_ = new List>(); + if (sparseSmiles_ == null) + sparseSmiles_ = new List>(); sparseSmiles_.Clear(); - for (int j=0; j tmp; int n = swapLengths.Count; tmp = new List(n); - for (int k=0; k spreadVolInterpolation(Date atmOptionDate,Period atmSwapTenor) + protected List spreadVolInterpolation(Date atmOptionDate, Period atmSwapTenor) { double atmOptionTime = timeFromReference(atmOptionDate); double atmTimeLength = swapLength(atmSwapTenor); @@ -812,7 +817,7 @@ protected List spreadVolInterpolation(Date atmOptionDate,Period atmSwapT List optionDates = sparseParameters_.optionDates(); List swapTenors = sparseParameters_.swapTenors(); - double optionTimesPreviousNode,swapLengthsPreviousNode; + double optionTimesPreviousNode, swapLengthsPreviousNode; optionTimesPreviousNode = optionTimes_.First(x => x >= Math.Min(atmOptionTime, optionTimes_.Max())); int optionTimesPreviousIndex = optionTimes_.IndexOf(optionTimesPreviousNode); @@ -820,57 +825,57 @@ protected List spreadVolInterpolation(Date atmOptionDate,Period atmSwapT swapLengthsPreviousNode = swapLengths_.First(x => x >= Math.Min(atmTimeLength, swapLengths_.Max())); int swapLengthsPreviousIndex = swapLengths_.IndexOf(swapLengthsPreviousNode); - if (optionTimesPreviousIndex >0) + if (optionTimesPreviousIndex > 0) optionTimesPreviousIndex --; - if (swapLengthsPreviousIndex >0) + if (swapLengthsPreviousIndex > 0) swapLengthsPreviousIndex --; List< List > smiles = new List>(); List smilesOnPreviousExpiry = new List(); List smilesOnNextExpiry = new List(); - Utils.QL_REQUIRE(optionTimesPreviousIndex+1 < sparseSmiles_.Count,()=> - "optionTimesPreviousIndex+1 >= sparseSmiles_.size()"); - Utils.QL_REQUIRE(swapLengthsPreviousIndex+1 < sparseSmiles_[0].Count,()=> - "swapLengthsPreviousIndex+1 >= sparseSmiles_[0].size()"); + Utils.QL_REQUIRE(optionTimesPreviousIndex + 1 < sparseSmiles_.Count, () => + "optionTimesPreviousIndex+1 >= sparseSmiles_.size()"); + Utils.QL_REQUIRE(swapLengthsPreviousIndex + 1 < sparseSmiles_[0].Count, () => + "swapLengthsPreviousIndex+1 >= sparseSmiles_[0].size()"); smilesOnPreviousExpiry.Add(sparseSmiles_[optionTimesPreviousIndex][swapLengthsPreviousIndex]); - smilesOnPreviousExpiry.Add(sparseSmiles_[optionTimesPreviousIndex][swapLengthsPreviousIndex+1]); - smilesOnNextExpiry.Add(sparseSmiles_[optionTimesPreviousIndex+1][swapLengthsPreviousIndex]); - smilesOnNextExpiry.Add(sparseSmiles_[optionTimesPreviousIndex+1][swapLengthsPreviousIndex+1]); + smilesOnPreviousExpiry.Add(sparseSmiles_[optionTimesPreviousIndex][swapLengthsPreviousIndex + 1]); + smilesOnNextExpiry.Add(sparseSmiles_[optionTimesPreviousIndex + 1][swapLengthsPreviousIndex]); + smilesOnNextExpiry.Add(sparseSmiles_[optionTimesPreviousIndex + 1][swapLengthsPreviousIndex + 1]); smiles.Add(smilesOnPreviousExpiry); smiles.Add(smilesOnNextExpiry); List optionsNodes = new InitializedList(2); optionsNodes[0] = optionTimes[optionTimesPreviousIndex]; - optionsNodes[1] = optionTimes[optionTimesPreviousIndex+1]; + optionsNodes[1] = optionTimes[optionTimesPreviousIndex + 1]; List optionsDateNodes = new InitializedList(2); optionsDateNodes[0] = optionDates[optionTimesPreviousIndex]; - optionsDateNodes[1] = optionDates[optionTimesPreviousIndex+1]; + optionsDateNodes[1] = optionDates[optionTimesPreviousIndex + 1]; List swapLengthsNodes = new InitializedList(2); swapLengthsNodes[0] = swapLengths[swapLengthsPreviousIndex]; - swapLengthsNodes[1] = swapLengths[swapLengthsPreviousIndex+1]; + swapLengthsNodes[1] = swapLengths[swapLengthsPreviousIndex + 1]; List swapTenorNodes = new InitializedList(2); swapTenorNodes[0] = swapTenors[swapLengthsPreviousIndex]; - swapTenorNodes[1] = swapTenors[swapLengthsPreviousIndex+1]; + swapTenorNodes[1] = swapTenors[swapLengthsPreviousIndex + 1]; double atmForward = atmStrike(atmOptionDate, atmSwapTenor); double shift = atmVol_.link.shift(atmOptionTime, atmTimeLength); Matrix atmForwards = new Matrix(2, 2, 0.0); - Matrix atmShifts = new Matrix(2,2,0.0); + Matrix atmShifts = new Matrix(2, 2, 0.0); Matrix atmVols = new Matrix(2, 2, 0.0); - for (int i=0; i<2; i++) + for (int i = 0; i < 2; i++) { - for (int j=0; j<2; j++) + for (int j = 0; j < 2; j++) { - atmForwards[i,j] = atmStrike(optionsDateNodes[i],swapTenorNodes[j]); - atmShifts[i,j] = atmVol_.link.shift(optionsNodes[i], swapLengthsNodes[j]); - atmVols[i,j] = atmVol_.link.volatility(optionsDateNodes[i], swapTenorNodes[j], atmForwards[i,j]); + atmForwards[i, j] = atmStrike(optionsDateNodes[i], swapTenorNodes[j]); + atmShifts[i, j] = atmVol_.link.shift(optionsNodes[i], swapLengthsNodes[j]); + atmVols[i, j] = atmVol_.link.volatility(optionsDateNodes[i], swapTenorNodes[j], atmForwards[i, j]); /* With the old implementation the interpolated spreads on ATM volatilities were null even if the spreads on ATM volatilities to be interpolated were non-zero. The new implementation removes @@ -891,28 +896,28 @@ good fits it is negligibile. } - for (int k=0; k. -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,7 +24,7 @@ namespace QLNet to identify the family (and its market conventions) an index of whatever length from that family must be passed in as swapIndexBase. - + Often for short swap length the swap index family is different, e.g. the EUR case: swap vs 6M Euribor is used for length>1Y, while swap vs 3M Euribor is used for the 1Y length. The @@ -32,39 +32,39 @@ shortSwapIndexBase is used to identify this second family. */ public class SwaptionVolCube2 : SwaptionVolatilityCube { - public SwaptionVolCube2( Handle atmVolStructure, - List optionTenors, - List swapTenors, - List strikeSpreads, - List > > volSpreads, - SwapIndex swapIndexBase, - SwapIndex shortSwapIndexBase, - bool vegaWeightedSmileFit) - :base(atmVolStructure, optionTenors, swapTenors,strikeSpreads, volSpreads, swapIndexBase, - shortSwapIndexBase,vegaWeightedSmileFit) + public SwaptionVolCube2(Handle atmVolStructure, + List optionTenors, + List swapTenors, + List strikeSpreads, + List > > volSpreads, + SwapIndex swapIndexBase, + SwapIndex shortSwapIndexBase, + bool vegaWeightedSmileFit) + : base(atmVolStructure, optionTenors, swapTenors, strikeSpreads, volSpreads, swapIndexBase, + shortSwapIndexBase, vegaWeightedSmileFit) { - volSpreadsInterpolator_= new List(); + volSpreadsInterpolator_ = new List(); volSpreadsMatrix_ = new List(nStrikes_); - for ( int i = 0 ; i < nStrikes_; i++) - volSpreadsMatrix_.Add (new Matrix(optionTenors.Count, swapTenors.Count, 0.0)); + for (int i = 0 ; i < nStrikes_; i++) + volSpreadsMatrix_.Add(new Matrix(optionTenors.Count, swapTenors.Count, 0.0)); } // LazyObject interface protected override void performCalculations() { base.performCalculations(); //! set volSpreadsMatrix_ by volSpreads_ quotes - for ( int i = 0; i < nStrikes_; i++ ) - for ( int j = 0; j < nOptionTenors_; j++ ) - for ( int k = 0; k < nSwapTenors_; k++ ) + for (int i = 0; i < nStrikes_; i++) + for (int j = 0; j < nOptionTenors_; j++) + for (int k = 0; k < nSwapTenors_; k++) { Matrix p = volSpreadsMatrix_[i]; - p[j,k] = volSpreads_[j * nSwapTenors_ + k][i].link.value(); + p[j, k] = volSpreads_[j * nSwapTenors_ + k][i].link.value(); } - //! create volSpreadsInterpolator_ - for (int i=0; i strikes, stdDevs; - strikes=new List(nStrikes_); - stdDevs=new List(nStrikes_); + strikes = new List(nStrikes_); + stdDevs = new List(nStrikes_); double length = swapLength(swapTenor); - for (int i=0; i(optionTime,strikes,stdDevs,atmForward,new Linear(), - new Actual365Fixed(), volatilityType(),shift); + double shift = atmVol_.link.shift(optionTime, length); + return new InterpolatedSmileSection(optionTime, strikes, stdDevs, atmForward, new Linear(), + new Actual365Fixed(), volatilityType(), shift); } - protected override SmileSection smileSectionImpl( double optionTime, double swapLength) + protected override SmileSection smileSectionImpl(double optionTime, double swapLength) { calculate(); Date optionDate = optionDateFromTime(optionTime); Rounding rounder = new Rounding(0); - Period swapTenor = new Period((int)(rounder.Round(swapLength*12.0)), TimeUnit.Months); + Period swapTenor = new Period((int)(rounder.Round(swapLength * 12.0)), TimeUnit.Months); // ensure that option date is valid fixing date optionDate = swapTenor > shortSwapIndexBase_.tenor() - ? swapIndexBase_.fixingCalendar().adjust(optionDate, BusinessDayConvention.Following) - : shortSwapIndexBase_.fixingCalendar().adjust(optionDate,BusinessDayConvention.Following); - return smileSectionImpl(optionDate, swapTenor); + ? swapIndexBase_.fixingCalendar().adjust(optionDate, BusinessDayConvention.Following) + : shortSwapIndexBase_.fixingCalendar().adjust(optionDate, BusinessDayConvention.Following); + return smileSectionImpl(optionDate, swapTenor); } private List volSpreadsInterpolator_; diff --git a/src/QLNet/Termstructures/Volatility/swaption/swaptionvoldiscrete.cs b/src/QLNet/Termstructures/Volatility/swaption/SwaptionVolDiscrete.cs similarity index 86% rename from src/QLNet/Termstructures/Volatility/swaption/swaptionvoldiscrete.cs rename to src/QLNet/Termstructures/Volatility/swaption/SwaptionVolDiscrete.cs index 7387b35e8..1f7678927 100644 --- a/src/QLNet/Termstructures/Volatility/swaption/swaptionvoldiscrete.cs +++ b/src/QLNet/Termstructures/Volatility/swaption/SwaptionVolDiscrete.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,7 +23,7 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public abstract class SwaptionVolatilityDiscrete : SwaptionVolatilityStructure + public abstract class SwaptionVolatilityDiscrete : SwaptionVolatilityStructure { protected int nOptionTenors_; protected List optionTenors_; @@ -60,7 +60,7 @@ protected SwaptionVolatilityDiscrete(List optionTenors, checkSwapTenors(); initializeSwapLengths(); - optionInterpolator_ = new LinearInterpolation(optionTimes_,optionTimes_.Count,optionDatesAsReal_); + optionInterpolator_ = new LinearInterpolation(optionTimes_, optionTimes_.Count, optionDatesAsReal_); optionInterpolator_.update(); optionInterpolator_.enableExtrapolation(); evaluationDate_ = Settings.evaluationDate(); @@ -90,7 +90,7 @@ protected SwaptionVolatilityDiscrete(List optionTenors, checkSwapTenors(); initializeSwapLengths(); - optionInterpolator_ = new LinearInterpolation(optionTimes_,optionTimes_.Count,optionDatesAsReal_); + optionInterpolator_ = new LinearInterpolation(optionTimes_, optionTimes_.Count, optionDatesAsReal_); optionInterpolator_.update(); optionInterpolator_.enableExtrapolation(); @@ -119,7 +119,7 @@ protected SwaptionVolatilityDiscrete(List optionDates, checkSwapTenors(); initializeSwapLengths(); - optionInterpolator_ = new LinearInterpolation(optionTimes_,optionTimes_.Count,optionDatesAsReal_); + optionInterpolator_ = new LinearInterpolation(optionTimes_, optionTimes_.Count, optionDatesAsReal_); optionInterpolator_.update(); optionInterpolator_.enableExtrapolation(); } @@ -187,31 +187,31 @@ public Date optionDateFromTime(double optionTime) private void checkOptionDates() { - Utils.QL_REQUIRE(optionDates_[0] > referenceDate(),()=> - "first option date (" + optionDates_[0] + ") must be greater than reference date (" + referenceDate() + ")"); + Utils.QL_REQUIRE(optionDates_[0] > referenceDate(), () => + "first option date (" + optionDates_[0] + ") must be greater than reference date (" + referenceDate() + ")"); for (int i = 1; i < nOptionTenors_; ++i) { - Utils.QL_REQUIRE(optionDates_[i] > optionDates_[i - 1],()=> - "non increasing option dates: " + i + " is " + optionDates_[i - 1] + ", " + i + 1 + " is " + optionDates_[i]); + Utils.QL_REQUIRE(optionDates_[i] > optionDates_[i - 1], () => + "non increasing option dates: " + i + " is " + optionDates_[i - 1] + ", " + i + 1 + " is " + optionDates_[i]); } } private void checkOptionTenors() { - Utils.QL_REQUIRE(optionTenors_[0] > new Period(0, TimeUnit.Days),()=> - "first option tenor is negative (" + optionTenors_[0] + ")"); + Utils.QL_REQUIRE(optionTenors_[0] > new Period(0, TimeUnit.Days), () => + "first option tenor is negative (" + optionTenors_[0] + ")"); for (int i = 1; i < nOptionTenors_; ++i) - Utils.QL_REQUIRE(optionTenors_[i] > optionTenors_[i - 1],()=> - "non increasing option tenor: " + i + " is " + optionTenors_[i - 1] + ", " + i + 1 + " is " + optionTenors_[i]); + Utils.QL_REQUIRE(optionTenors_[i] > optionTenors_[i - 1], () => + "non increasing option tenor: " + i + " is " + optionTenors_[i - 1] + ", " + i + 1 + " is " + optionTenors_[i]); } private void checkSwapTenors() { - Utils.QL_REQUIRE(swapTenors_[0] > new Period(0, TimeUnit.Days),()=> - "first swap tenor is negative (" + swapTenors_[0] + ")"); + Utils.QL_REQUIRE(swapTenors_[0] > new Period(0, TimeUnit.Days), () => + "first swap tenor is negative (" + swapTenors_[0] + ")"); for (int i = 1; i < nSwapTenors_; ++i) - Utils.QL_REQUIRE(swapTenors_[i] > swapTenors_[i - 1],()=> - "non increasing swap tenor: " + i + " is " + swapTenors_[i - 1] + ", " + i + 1 + " is " + swapTenors_[i]); + Utils.QL_REQUIRE(swapTenors_[i] > swapTenors_[i - 1], () => + "non increasing swap tenor: " + i + " is " + swapTenors_[i - 1] + ", " + i + 1 + " is " + swapTenors_[i]); } private void initializeOptionDatesAndTimes() @@ -219,7 +219,7 @@ private void initializeOptionDatesAndTimes() for (int i = 0; i < nOptionTenors_; ++i) { optionDates_[i] = optionDateFromTenor(optionTenors_[i]); - optionDatesAsReal_[i] = (double) (optionDates_[i].serialNumber()); + optionDatesAsReal_[i] = (double)(optionDates_[i].serialNumber()); } initializeOptionTimes(); } diff --git a/src/QLNet/Termstructures/Volatility/swaption/SwaptionVolMatrix.cs b/src/QLNet/Termstructures/Volatility/swaption/SwaptionVolMatrix.cs new file mode 100644 index 000000000..f55b67fc6 --- /dev/null +++ b/src/QLNet/Termstructures/Volatility/swaption/SwaptionVolMatrix.cs @@ -0,0 +1,460 @@ +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QLNet +{ + //! At-the-money swaption-volatility matrix + /*! This class provides the at-the-money volatility for a given + swaption by interpolating a volatility matrix whose elements + are the market volatilities of a set of swaption with given + option date and swapLength. + + The volatility matrix M must be defined so that: + - the number of rows equals the number of option dates + - the number of columns equals the number of swap tenors + - M[i][j] contains the volatility corresponding + to the i-th option and j-th tenor. + */ + public class SwaptionVolatilityMatrix : SwaptionVolatilityDiscrete + { + //! floating reference date, floating market data + public SwaptionVolatilityMatrix( + Calendar calendar, + BusinessDayConvention bdc, + List optionTenors, + List swapTenors, + List>> vols, + DayCounter dayCounter, + bool flatExtrapolation = false, + VolatilityType type = VolatilityType.ShiftedLognormal, + List> shifts = null) + : base(optionTenors, swapTenors, 0, calendar, bdc, dayCounter) + { + volHandles_ = vols; + shiftValues_ = shifts; + volatilities_ = new Matrix(vols.Count, vols.First().Count); + shifts_ = new Matrix(vols.Count, vols.First().Count, 0.0); + volatilityType_ = type; + checkInputs(volatilities_.rows(), volatilities_.columns(), shifts_.rows(), shifts_.columns()); + registerWithMarketData(); + + // fill dummy handles to allow generic handle-based + if (shiftValues_ == null) + { + shiftValues_ = new InitializedList>(volatilities_.rows()); + for (int i = 0; i < volatilities_.rows(); ++i) + { + shiftValues_[i] = new InitializedList(volatilities_.columns()); + for (int j = 0; j < volatilities_.columns(); ++j) + { + shiftValues_[i][j] = shifts_.rows() > 0 ? shifts_[i, j] : 0.0; + } + } + } + + if (flatExtrapolation) + { + interpolation_ = new FlatExtrapolator2D(new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, volatilities_)); + + interpolationShifts_ = new FlatExtrapolator2D(new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, shifts_)); + } + else + { + interpolation_ = new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, + volatilities_); + + interpolationShifts_ = new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, + shifts_); + } + } + + //! fixed reference date, floating market data + public SwaptionVolatilityMatrix( + Date referenceDate, + Calendar calendar, + BusinessDayConvention bdc, + List optionTenors, + List swapTenors, + List>> vols, + DayCounter dayCounter, + bool flatExtrapolation = false, + VolatilityType type = VolatilityType.ShiftedLognormal, + List> shifts = null) + : base(optionTenors, swapTenors, referenceDate, calendar, bdc, dayCounter) + { + volHandles_ = vols; + shiftValues_ = shifts; + volatilities_ = new Matrix(vols.Count, vols.First().Count); + shifts_ = new Matrix(vols.Count, vols.First().Count, 0.0); + volatilityType_ = type; + checkInputs(volatilities_.rows(), volatilities_.columns(), shifts_.rows(), shifts_.columns()); + registerWithMarketData(); + + // fill dummy handles to allow generic handle-based + if (shiftValues_ == null) + { + shiftValues_ = new InitializedList>(volatilities_.rows()); + for (int i = 0; i < volatilities_.rows(); ++i) + { + shiftValues_[i] = new InitializedList(volatilities_.columns()); + for (int j = 0; j < volatilities_.columns(); ++j) + { + shiftValues_[i][j] = shifts_.rows() > 0 ? shifts_[i, j] : 0.0; + } + } + } + + if (flatExtrapolation) + { + interpolation_ = new FlatExtrapolator2D(new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, volatilities_)); + + interpolationShifts_ = new FlatExtrapolator2D(new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, shifts_)); + } + else + { + interpolation_ = new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, + volatilities_); + + interpolationShifts_ = new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, + shifts_); + } + } + + //! floating reference date, fixed market data + public SwaptionVolatilityMatrix( + Calendar calendar, + BusinessDayConvention bdc, + List optionTenors, + List swapTenors, + Matrix vols, + DayCounter dayCounter, + bool flatExtrapolation = false, + VolatilityType type = VolatilityType.ShiftedLognormal, + Matrix shifts = null) + + : base(optionTenors, swapTenors, 0, calendar, bdc, dayCounter) + { + volHandles_ = new InitializedList>>(vols.rows()); + shiftValues_ = new InitializedList>(vols.rows()); + volatilities_ = new Matrix(vols.rows(), vols.columns()); + shifts_ = shifts ?? new Matrix(vols.rows(), vols.columns(), 0.0); + volatilityType_ = type; + checkInputs(volatilities_.rows(), volatilities_.columns(), shifts_.rows(), shifts_.columns()); + + // fill dummy handles to allow generic handle-based + // computations later on + for (int i = 0; i < vols.rows(); ++i) + { + volHandles_[i] = new InitializedList>(vols.columns()); + shiftValues_[i] = new InitializedList(vols.columns()); + for (int j = 0; j < vols.columns(); ++j) + volHandles_[i][j] = new Handle((new + SimpleQuote(vols[i, j]))); + } + + if (flatExtrapolation) + { + interpolation_ = new FlatExtrapolator2D(new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, volatilities_)); + + interpolationShifts_ = new FlatExtrapolator2D(new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, shifts_)); + } + else + { + interpolation_ = new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, + volatilities_); + + interpolationShifts_ = new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, + shifts_); + } + } + + //! fixed reference date, fixed market data + public SwaptionVolatilityMatrix( + Date referenceDate, + Calendar calendar, + BusinessDayConvention bdc, + List optionTenors, + List swapTenors, + Matrix vols, + DayCounter dayCounter, + bool flatExtrapolation = false, + VolatilityType type = VolatilityType.ShiftedLognormal, + Matrix shifts = null) + : base(optionTenors, swapTenors, referenceDate, calendar, bdc, dayCounter) + { + volHandles_ = new InitializedList>>(vols.rows()); + shiftValues_ = new InitializedList>(vols.rows()); + volatilities_ = new Matrix(vols.rows(), vols.columns()); + shifts_ = shifts ?? new Matrix(vols.rows(), vols.columns(), 0.0); + checkInputs(vols.rows(), vols.columns(), shifts_.rows(), shifts_.columns()); + volatilityType_ = type; + + // fill dummy handles to allow generic handle-based + // computations later on + for (int i = 0; i < vols.rows(); ++i) + { + volHandles_[i] = new InitializedList>(vols.columns()); + shiftValues_[i] = new InitializedList(vols.columns()); + for (int j = 0; j < vols.columns(); ++j) + { + volHandles_[i][j] = new Handle((new + SimpleQuote(vols[i, j]))); + shiftValues_[i][j] = shifts_.rows() > 0 ? shifts_[i, j] : 0.0; + } + } + + if (flatExtrapolation) + { + interpolation_ = new FlatExtrapolator2D(new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, volatilities_)); + + interpolationShifts_ = new FlatExtrapolator2D(new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, shifts_)); + } + else + { + interpolation_ = new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, + volatilities_); + + interpolationShifts_ = new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, + shifts_); + } + } + + // fixed reference date and fixed market data, option dates + public SwaptionVolatilityMatrix(Date today, + List optionDates, + List swapTenors, + Matrix vols, + DayCounter dayCounter, + bool flatExtrapolation = false, + VolatilityType type = VolatilityType.ShiftedLognormal, + Matrix shifts = null) + : base(optionDates, swapTenors, today, new Calendar(), BusinessDayConvention.Following, dayCounter) + { + volHandles_ = new InitializedList>>(vols.rows()); + shiftValues_ = new InitializedList>(vols.rows()); + volatilities_ = new Matrix(vols.rows(), vols.columns()); + shifts_ = shifts ?? new Matrix(vols.rows(), vols.columns(), 0.0); + checkInputs(vols.rows(), vols.columns(), shifts_.rows(), shifts_.columns()); + volatilityType_ = type; + + // fill dummy handles to allow generic handle-based + // computations later on + for (int i = 0; i < vols.rows(); ++i) + { + volHandles_[i] = new InitializedList>(vols.columns()); + shiftValues_[i] = new InitializedList(vols.columns()); + for (int j = 0; j < vols.columns(); ++j) + { + volHandles_[i][j] = new Handle((new + SimpleQuote(vols[i, j]))); + shiftValues_[i][j] = shifts_.rows() > 0 ? shifts_[i, j] : 0.0; + } + } + + if (flatExtrapolation) + { + interpolation_ = new FlatExtrapolator2D(new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, volatilities_)); + + interpolationShifts_ = new FlatExtrapolator2D(new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, shifts_)); + } + else + { + interpolation_ = new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, + volatilities_); + + interpolationShifts_ = new BilinearInterpolation( + swapLengths_, swapLengths_.Count, + optionTimes_, optionTimes_.Count, + shifts_); + } + } + + // LazyObject interface + //verifier protected QL public!! + protected override void performCalculations() + { + base.performCalculations(); + + // we might use iterators here... + for (int i = 0; i < volatilities_.rows(); ++i) + { + for (int j = 0; j < volatilities_.columns(); ++j) + { + volatilities_[i, j] = volHandles_[i][j].link.value(); + if (shiftValues_.Count > 0) + shifts_[i, j] = shiftValues_[i][j]; + } + } + } + + // TermStructure interface + public override Date maxDate() + { + return optionDates_.Last(); + } + + // VolatilityTermStructure interface + public override double minStrike() + { + return double.MinValue; + } + + public override double maxStrike() + { + return double.MaxValue; + } + + // SwaptionVolatilityStructure interface + public override Period maxSwapTenor() + { + return swapTenors_.Last(); + } + + // Other inspectors + //! returns the lower indexes of surrounding volatility matrix corners + public KeyValuePair locate(Date optionDate, + Period swapTenor) + { + return locate(timeFromReference(optionDate), + swapLength(swapTenor)); + } + + //! returns the lower indexes of surrounding volatility matrix corners + public KeyValuePair locate(double optionTime, + double swapLength) + { + return new KeyValuePair(interpolation_.locateY(optionTime), + interpolation_.locateX(swapLength)); + } + + //Volatility type + public override VolatilityType volatilityType() + { + return volatilityType_; + } + + #region protected + // defining the following method would break CMS test suite + // to be further investigated + protected override SmileSection smileSectionImpl(double optionTime, double swapLength) + { + double atmVol = volatilityImpl(optionTime, swapLength, 0.05); + double shift = interpolationShifts_.value(optionTime, swapLength, true); + return (SmileSection)new FlatSmileSection(optionTime, atmVol, dayCounter(), null, volatilityType(), shift); + + } + + protected override double volatilityImpl(double optionTime, double swapLength, + double strike) + { + calculate(); + return interpolation_.value(swapLength, optionTime, true); + } + + protected override double shiftImpl(double optionTime, double swapLength) + { + calculate(); + double tmp = interpolationShifts_.value(swapLength, optionTime, true); + return tmp; + } + #endregion + + #region private + private void checkInputs(int volRows, + int volsColumns, + int shiftRows, + int shiftsColumns) + { + Utils.QL_REQUIRE(nOptionTenors_ == volRows, () => + "mismatch between number of option dates (" + nOptionTenors_ + ") and number of rows (" + + volRows + ") in the vol matrix"); + Utils.QL_REQUIRE(nSwapTenors_ == volsColumns, () => + "mismatch between number of swap tenors (" + nSwapTenors_ + ") and number of rows (" + + volsColumns + ") in the vol matrix"); + + if (shiftRows == 0 && shiftsColumns == 0) + { + shifts_ = new Matrix(volRows, volsColumns, 0.0); + shiftRows = volRows; + shiftsColumns = volsColumns; + } + + Utils.QL_REQUIRE(nOptionTenors_ == shiftRows, () => + "mismatch between number of option dates (" + nOptionTenors_ + ") and number of rows (" + + shiftRows + ") in the shift matrix"); + Utils.QL_REQUIRE(nSwapTenors_ == shiftsColumns, () => + "mismatch between number of swap tenors (" + nSwapTenors_ + ") and number of rows (" + + shiftsColumns + ") in the shift matrix"); + } + private void registerWithMarketData() + { + for (int i = 0; i < volHandles_.Count; ++i) + for (int j = 0; j < volHandles_.First().Count; ++j) + volHandles_[i][j].registerWith(update); + } + private List>> volHandles_; + private List> shiftValues_; + private Matrix volatilities_, shifts_; + private Interpolation2D interpolation_, interpolationShifts_; + VolatilityType volatilityType_; + #endregion + } + +} diff --git a/src/QLNet/Termstructures/Volatility/swaption/SwaptionVolatilityCube.cs b/src/QLNet/Termstructures/Volatility/swaption/SwaptionVolatilityCube.cs index c962e7f15..a2be8ad2f 100644 --- a/src/QLNet/Termstructures/Volatility/swaption/SwaptionVolatilityCube.cs +++ b/src/QLNet/Termstructures/Volatility/swaption/SwaptionVolatilityCube.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,16 +20,16 @@ namespace QLNet { public abstract class SwaptionVolatilityCube : SwaptionVolatilityDiscrete { - protected SwaptionVolatilityCube( Handle atmVol, - List optionTenors, - List swapTenors, - List strikeSpreads, - List > > volSpreads, - SwapIndex swapIndexBase, - SwapIndex shortSwapIndexBase, - bool vegaWeightedSmileFit) - :base(optionTenors, swapTenors, 0,atmVol.link.calendar(),atmVol.link.businessDayConvention(), - atmVol.link.dayCounter()) + protected SwaptionVolatilityCube(Handle atmVol, + List optionTenors, + List swapTenors, + List strikeSpreads, + List > > volSpreads, + SwapIndex swapIndexBase, + SwapIndex shortSwapIndexBase, + bool vegaWeightedSmileFit) + : base(optionTenors, swapTenors, 0, atmVol.link.calendar(), atmVol.link.businessDayConvention(), + atmVol.link.dayCounter()) { atmVol_ = atmVol; nStrikes_ = strikeSpreads.Count; @@ -41,24 +41,24 @@ protected SwaptionVolatilityCube( Handle atmVol, shortSwapIndexBase_ = shortSwapIndexBase; vegaWeightedSmileFit_ = vegaWeightedSmileFit; - Utils.QL_REQUIRE(!atmVol_.empty(),()=> "atm vol handle not linked to anything"); - for (int i=1; i - "non increasing strike spreads: " +i + " is " + strikeSpreads_[i-1] + ", " + - (i+1) + " is " + strikeSpreads_[i]); + Utils.QL_REQUIRE(!atmVol_.empty(), () => "atm vol handle not linked to anything"); + for (int i = 1; i < nStrikes_; ++i) + Utils.QL_REQUIRE(strikeSpreads_[i - 1] + "non increasing strike spreads: " + i + " is " + strikeSpreads_[i - 1] + ", " + + (i + 1) + " is " + strikeSpreads_[i]); - Utils.QL_REQUIRE(!volSpreads_.empty(),()=> "empty vol spreads matrix"); + Utils.QL_REQUIRE(!volSpreads_.empty(), () => "empty vol spreads matrix"); - Utils.QL_REQUIRE(nOptionTenors_*nSwapTenors_==volSpreads_.Count,()=> - "mismatch between number of option tenors * swap tenors (" + - nOptionTenors_*nSwapTenors_ + ") and number of rows (" + - volSpreads_.Count + ")"); + Utils.QL_REQUIRE(nOptionTenors_*nSwapTenors_ == volSpreads_.Count, () => + "mismatch between number of option tenors * swap tenors (" + + nOptionTenors_*nSwapTenors_ + ") and number of rows (" + + volSpreads_.Count + ")"); - for (int i=0; i - "mismatch between number of strikes (" + nStrikes_ + - ") and number of columns (" + volSpreads_[i].Count + - ") in the " + (i+1) + " row"); + for (int i = 0; i + "mismatch between number of strikes (" + nStrikes_ + + ") and number of columns (" + volSpreads_[i].Count + + ") in the " + (i + 1) + " row"); atmVol_.registerWith(update); atmVol_.link.enableExtrapolation(); @@ -66,10 +66,10 @@ protected SwaptionVolatilityCube( Handle atmVol, swapIndexBase_.registerWith(update); shortSwapIndexBase_.registerWith(update); - Utils.QL_REQUIRE(shortSwapIndexBase_.tenor() - "short index tenor (" + shortSwapIndexBase_.tenor() + - ") is not less than index tenor (" + - swapIndexBase_.tenor() + ")"); + Utils.QL_REQUIRE(shortSwapIndexBase_.tenor() + "short index tenor (" + shortSwapIndexBase_.tenor() + + ") is not less than index tenor (" + + swapIndexBase_.tenor() + ")"); registerWithVolatilitySpread(); Settings.registerWith(update); @@ -83,84 +83,84 @@ public override Date referenceDate() { if (atmVol_ == null) return base.referenceDate(); - + return atmVol_.link.referenceDate(); } public new Calendar calendar() { return atmVol_.link.calendar(); } public new int settlementDays() { return atmVol_.link.settlementDays(); } // VolatilityTermStructure interface - public override double minStrike() { return -double.MaxValue; } + public override double minStrike() { return - double.MaxValue; } public override double maxStrike() { return double.MaxValue; } // SwaptionVolatilityStructure interface public override Period maxSwapTenor() { return atmVol_.link.maxSwapTenor(); } // Other inspectors - public double atmStrike( Date optionDate, Period swapTenor) + public double atmStrike(Date optionDate, Period swapTenor) { // FIXME use a familyName-based index factory - if ( swapTenor > shortSwapIndexBase_.tenor() ) + if (swapTenor > shortSwapIndexBase_.tenor()) { - if ( swapIndexBase_.exogenousDiscount() ) + if (swapIndexBase_.exogenousDiscount()) { - return new SwapIndex( swapIndexBase_.familyName(), - swapTenor, - swapIndexBase_.fixingDays(), - swapIndexBase_.currency(), - swapIndexBase_.fixingCalendar(), - swapIndexBase_.fixedLegTenor(), - swapIndexBase_.fixedLegConvention(), - swapIndexBase_.dayCounter(), - swapIndexBase_.iborIndex(), - swapIndexBase_.discountingTermStructure() ).fixing( optionDate ); + return new SwapIndex(swapIndexBase_.familyName(), + swapTenor, + swapIndexBase_.fixingDays(), + swapIndexBase_.currency(), + swapIndexBase_.fixingCalendar(), + swapIndexBase_.fixedLegTenor(), + swapIndexBase_.fixedLegConvention(), + swapIndexBase_.dayCounter(), + swapIndexBase_.iborIndex(), + swapIndexBase_.discountingTermStructure()).fixing(optionDate); } else { - return new SwapIndex( swapIndexBase_.familyName(), - swapTenor, - swapIndexBase_.fixingDays(), - swapIndexBase_.currency(), - swapIndexBase_.fixingCalendar(), - swapIndexBase_.fixedLegTenor(), - swapIndexBase_.fixedLegConvention(), - swapIndexBase_.dayCounter(), - swapIndexBase_.iborIndex() ).fixing( optionDate ); + return new SwapIndex(swapIndexBase_.familyName(), + swapTenor, + swapIndexBase_.fixingDays(), + swapIndexBase_.currency(), + swapIndexBase_.fixingCalendar(), + swapIndexBase_.fixedLegTenor(), + swapIndexBase_.fixedLegConvention(), + swapIndexBase_.dayCounter(), + swapIndexBase_.iborIndex()).fixing(optionDate); } } else { - if ( shortSwapIndexBase_.exogenousDiscount() ) + if (shortSwapIndexBase_.exogenousDiscount()) { - return new SwapIndex( shortSwapIndexBase_.familyName(), - swapTenor, - shortSwapIndexBase_.fixingDays(), - shortSwapIndexBase_.currency(), - shortSwapIndexBase_.fixingCalendar(), - shortSwapIndexBase_.fixedLegTenor(), - shortSwapIndexBase_.fixedLegConvention(), - shortSwapIndexBase_.dayCounter(), - shortSwapIndexBase_.iborIndex(), - shortSwapIndexBase_.discountingTermStructure() ).fixing( optionDate ); + return new SwapIndex(shortSwapIndexBase_.familyName(), + swapTenor, + shortSwapIndexBase_.fixingDays(), + shortSwapIndexBase_.currency(), + shortSwapIndexBase_.fixingCalendar(), + shortSwapIndexBase_.fixedLegTenor(), + shortSwapIndexBase_.fixedLegConvention(), + shortSwapIndexBase_.dayCounter(), + shortSwapIndexBase_.iborIndex(), + shortSwapIndexBase_.discountingTermStructure()).fixing(optionDate); } else { - return new SwapIndex( shortSwapIndexBase_.familyName(), - swapTenor, - shortSwapIndexBase_.fixingDays(), - shortSwapIndexBase_.currency(), - shortSwapIndexBase_.fixingCalendar(), - shortSwapIndexBase_.fixedLegTenor(), - shortSwapIndexBase_.fixedLegConvention(), - shortSwapIndexBase_.dayCounter(), - shortSwapIndexBase_.iborIndex() ).fixing( optionDate ); + return new SwapIndex(shortSwapIndexBase_.familyName(), + swapTenor, + shortSwapIndexBase_.fixingDays(), + shortSwapIndexBase_.currency(), + shortSwapIndexBase_.fixingCalendar(), + shortSwapIndexBase_.fixedLegTenor(), + shortSwapIndexBase_.fixedLegConvention(), + shortSwapIndexBase_.dayCounter(), + shortSwapIndexBase_.iborIndex()).fixing(optionDate); } } } - public double atmStrike( Period optionTenor, Period swapTenor) + public double atmStrike(Period optionTenor, Period swapTenor) { Date optionDate = optionDateFromTenor(optionTenor); return atmStrike(optionDate, swapTenor); } - public Handle atmVol() { return atmVol_; } + public Handle atmVol() { return atmVol_; } public List strikeSpreads() { return strikeSpreads_; } public List > > volSpreads() { return volSpreads_; } public SwapIndex swapIndexBase() { return swapIndexBase_; } @@ -168,12 +168,12 @@ public double atmStrike( Period optionTenor, Period swapTenor) public bool vegaWeightedSmileFit() { return vegaWeightedSmileFit_; } // LazyObject interface - protected override void performCalculations() + protected override void performCalculations() { - Utils.QL_REQUIRE(nStrikes_ >= requiredNumberOfStrikes(),()=> - "too few strikes (" + nStrikes_ - + ") required are at least " - + requiredNumberOfStrikes()); + Utils.QL_REQUIRE(nStrikes_ >= requiredNumberOfStrikes(), () => + "too few strikes (" + nStrikes_ + + ") required are at least " + + requiredNumberOfStrikes()); base.performCalculations(); } @@ -181,23 +181,23 @@ protected override void performCalculations() protected void registerWithVolatilitySpread() { - for ( int i = 0; i < nStrikes_; i++ ) - for ( int j = 0; j < nOptionTenors_; j++ ) - for ( int k = 0; k < nSwapTenors_; k++ ) + for (int i = 0; i < nStrikes_; i++) + for (int j = 0; j < nOptionTenors_; j++) + for (int k = 0; k < nSwapTenors_; k++) volSpreads_[j * nSwapTenors_ + k][i].registerWith(update); } protected virtual int requiredNumberOfStrikes() { return 2; } - protected override double volatilityImpl(double optionTime,double swapLength,double strike) + protected override double volatilityImpl(double optionTime, double swapLength, double strike) { - return smileSectionImpl(optionTime, swapLength).volatility(strike); + return smileSectionImpl(optionTime, swapLength).volatility(strike); } - protected override double volatilityImpl(Date optionDate,Period swapTenor,double strike) + protected override double volatilityImpl(Date optionDate, Period swapTenor, double strike) { - return smileSectionImpl( optionDate, swapTenor ).volatility( strike ); + return smileSectionImpl(optionDate, swapTenor).volatility(strike); } protected override double shiftImpl(double optionTime, double swapLength) { - return atmVol_.link.shift( optionTime, swapLength ); + return atmVol_.link.shift(optionTime, swapLength); } protected Handle atmVol_; protected int nStrikes_; diff --git a/src/QLNet/Termstructures/Volatility/swaption/SwaptionVolatilityStructure.cs b/src/QLNet/Termstructures/Volatility/swaption/SwaptionVolatilityStructure.cs index a504379c6..94223a494 100644 --- a/src/QLNet/Termstructures/Volatility/swaption/SwaptionVolatilityStructure.cs +++ b/src/QLNet/Termstructures/Volatility/swaption/SwaptionVolatilityStructure.cs @@ -1,30 +1,30 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet +namespace QLNet { //! %Swaption-volatility structure /*! This abstract class defines the interface of concrete swaption volatility structures which will be derived from this one. */ - public abstract class SwaptionVolatilityStructure : VolatilityTermStructure + public abstract class SwaptionVolatilityStructure : VolatilityTermStructure { #region Constructors /*! \warning term structures initialized by means of this @@ -34,15 +34,15 @@ by overriding the referenceDate() method. protected SwaptionVolatilityStructure(BusinessDayConvention bdc, DayCounter dc = null) : base(bdc, dc) {} - + //! initialize with a fixed reference date - protected SwaptionVolatilityStructure(Date referenceDate,Calendar calendar,BusinessDayConvention bdc,DayCounter dc = null) + protected SwaptionVolatilityStructure(Date referenceDate, Calendar calendar, BusinessDayConvention bdc, DayCounter dc = null) : base(referenceDate, calendar, bdc, dc) {} - + //! calculate the reference date based on the global evaluation date - protected SwaptionVolatilityStructure(int settlementDays,Calendar cal,BusinessDayConvention bdc,DayCounter dc = null) + protected SwaptionVolatilityStructure(int settlementDays, Calendar cal, BusinessDayConvention bdc, DayCounter dc = null) : base(settlementDays, cal, bdc, dc) {} - + #endregion @@ -54,7 +54,7 @@ public double volatility(Period optionTenor, Period swapTenor, double strike, bo Date optionDate = optionDateFromTenor(optionTenor); return volatility(optionDate, swapTenor, strike, extrapolate); } - + //! returns the volatility for a given option date and swap tenor public double volatility(Date optionDate, Period swapTenor, double strike, bool extrapolate = false) { @@ -144,48 +144,48 @@ public double blackVariance(double optionTime, double swapLength, double strike, return v * v * optionTime; } - + //! returns the shift for a given option tenor and swap tenor - public double shift( Period optionTenor, Period swapTenor,bool extrapolate = false) + public double shift(Period optionTenor, Period swapTenor, bool extrapolate = false) { - Date optionDate = optionDateFromTenor( optionTenor ); - return shift( optionDate, swapTenor, extrapolate ); + Date optionDate = optionDateFromTenor(optionTenor); + return shift(optionDate, swapTenor, extrapolate); } //! returns the shift for a given option date and swap tenor - public double shift( Date optionDate, Period swapTenor,bool extrapolate = false) + public double shift(Date optionDate, Period swapTenor, bool extrapolate = false) { - checkSwapTenor( swapTenor, extrapolate ); - checkRange( optionDate, extrapolate ); - return shiftImpl( optionDate, swapTenor ); + checkSwapTenor(swapTenor, extrapolate); + checkRange(optionDate, extrapolate); + return shiftImpl(optionDate, swapTenor); } //! returns the shift for a given option time and swap tenor - public double shift( double optionTime, Period swapTenor,bool extrapolate = false) + public double shift(double optionTime, Period swapTenor, bool extrapolate = false) { - checkSwapTenor( swapTenor, extrapolate ); - checkRange( optionTime, extrapolate ); - double length = swapLength( swapTenor ); - return shiftImpl( optionTime, length ); + checkSwapTenor(swapTenor, extrapolate); + checkRange(optionTime, extrapolate); + double length = swapLength(swapTenor); + return shiftImpl(optionTime, length); } //! returns the shift for a given option tenor and swap length - public double shift( Period optionTenor, double swapLength, bool extrapolate = false) + public double shift(Period optionTenor, double swapLength, bool extrapolate = false) { - Date optionDate = optionDateFromTenor( optionTenor ); - return shift( optionDate, swapLength, extrapolate ); + Date optionDate = optionDateFromTenor(optionTenor); + return shift(optionDate, swapLength, extrapolate); } //! returns the shift for a given option date and swap length - public double shift( Date optionDate, double swapLength, bool extrapolate = false) + public double shift(Date optionDate, double swapLength, bool extrapolate = false) { - checkSwapTenor( swapLength, extrapolate ); - checkRange( optionDate, extrapolate ); - double optionTime = timeFromReference( optionDate ); - return shiftImpl( optionTime, swapLength ); + checkSwapTenor(swapLength, extrapolate); + checkRange(optionDate, extrapolate); + double optionTime = timeFromReference(optionDate); + return shiftImpl(optionTime, swapLength); } //! returns the shift for a given option time and swap length - public double shift( double optionTime, double swapLength,bool extrapolate = false) + public double shift(double optionTime, double swapLength, bool extrapolate = false) { - checkSwapTenor( swapLength, extrapolate ); - checkRange( optionTime, extrapolate ); - return shiftImpl( optionTime, swapLength ); + checkSwapTenor(swapLength, extrapolate); + checkRange(optionTime, extrapolate); + return shiftImpl(optionTime, swapLength); } @@ -212,7 +212,7 @@ public SmileSection smileSection(double optionTime, double swapLength, bool extr checkRange(optionTime, extrapolate); return smileSectionImpl(optionTime, swapLength); } - + #endregion #region Limits @@ -231,7 +231,7 @@ public SmileSection smileSection(double optionTime, double swapLength, bool extr //! implements the conversion between swap tenor and swap (time) length public double swapLength(Period swapTenor) { - Utils.QL_REQUIRE( swapTenor.length() > 0, () => "non-positive swap tenor (" + swapTenor + ") given" ); + Utils.QL_REQUIRE(swapTenor.length() > 0, () => "non-positive swap tenor (" + swapTenor + ") given"); switch (swapTenor.units()) { case TimeUnit.Months: @@ -247,7 +247,7 @@ public double swapLength(Period swapTenor) //! implements the conversion between swap dates and swap (time) length public double swapLength(Date start, Date end) { - Utils.QL_REQUIRE( end > start, () => "swap end date (" + end + ") must be greater than start (" + start + ")" ); + Utils.QL_REQUIRE(end > start, () => "swap end date (" + end + ") must be greater than start (" + start + ")"); double result = (end - start) / 365.25 * 12.0; // month unit result = new ClosestRounding(0).Round(result); result /= 12.0; // year unit @@ -268,30 +268,30 @@ protected virtual double volatilityImpl(Date optionDate, Period swapTenor, doubl protected abstract double volatilityImpl(double optionTime, double swapLength, double strike); - protected virtual double shiftImpl( Date optionDate, Period swapTenor) + protected virtual double shiftImpl(Date optionDate, Period swapTenor) { - return shiftImpl( timeFromReference( optionDate ), swapLength( swapTenor ) ); + return shiftImpl(timeFromReference(optionDate), swapLength(swapTenor)); } - protected virtual double shiftImpl( double optionTime, double swapLength) + protected virtual double shiftImpl(double optionTime, double swapLength) { - Utils.QL_REQUIRE(volatilityType() == VolatilityType.ShiftedLognormal,()=> - "shift parameter only makes sense for lognormal volatilities" ); + Utils.QL_REQUIRE(volatilityType() == VolatilityType.ShiftedLognormal, () => + "shift parameter only makes sense for lognormal volatilities"); return 0.0; } protected void checkSwapTenor(Period swapTenor, bool extrapolate) { - Utils.QL_REQUIRE( swapTenor.length() > 0, () => "non-positive swap tenor (" + swapTenor + ") given" ); - Utils.QL_REQUIRE( extrapolate || allowsExtrapolation() || swapTenor <= maxSwapTenor(), () => - "swap tenor (" + swapTenor + ") is past max tenor (" + maxSwapTenor() + ")"); + Utils.QL_REQUIRE(swapTenor.length() > 0, () => "non-positive swap tenor (" + swapTenor + ") given"); + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || swapTenor <= maxSwapTenor(), () => + "swap tenor (" + swapTenor + ") is past max tenor (" + maxSwapTenor() + ")"); } protected void checkSwapTenor(double swapLength, bool extrapolate) { - Utils.QL_REQUIRE( swapLength > 0.0, () => "non-positive swap length (" + swapLength + ") given" ); - Utils.QL_REQUIRE( extrapolate || allowsExtrapolation() || swapLength <= maxSwapLength(), () => - "swap tenor (" + swapLength + ") is past max tenor (" + maxSwapLength() + ")"); + Utils.QL_REQUIRE(swapLength > 0.0, () => "non-positive swap length (" + swapLength + ") given"); + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || swapLength <= maxSwapLength(), () => + "swap tenor (" + swapLength + ") is past max tenor (" + maxSwapLength() + ")"); } - } + } } diff --git a/src/QLNet/Termstructures/Volatility/swaption/swaptionconstantvol.cs b/src/QLNet/Termstructures/Volatility/swaption/swaptionconstantvol.cs deleted file mode 100644 index 78a6f6280..000000000 --- a/src/QLNet/Termstructures/Volatility/swaption/swaptionconstantvol.cs +++ /dev/null @@ -1,141 +0,0 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet -{ - //! Constant swaption volatility, no time-strike dependence - public class ConstantSwaptionVolatility : SwaptionVolatilityStructure - { - private Handle volatility_; - private Period maxSwapTenor_; - private VolatilityType volatilityType_; - private double? shift_; - - //! floating reference date, floating market data - public ConstantSwaptionVolatility(int settlementDays, - Calendar cal, - BusinessDayConvention bdc, - Handle vol, - DayCounter dc, - VolatilityType type = VolatilityType.ShiftedLognormal, - double? shift = 0.0) - : base(settlementDays, cal, bdc, dc){ - volatility_= vol; - maxSwapTenor_ = new Period(100, TimeUnit.Years); - volatilityType_ = type; - shift_ = shift; - volatility_.registerWith(update); - } - - //! fixed reference date, floating market data - public ConstantSwaptionVolatility(Date referenceDate, - Calendar cal, - BusinessDayConvention bdc, - Handle vol, - DayCounter dc, - VolatilityType type = VolatilityType.ShiftedLognormal, - double? shift = 0.0) - - : base(referenceDate, cal, bdc, dc){ - volatility_ = vol; - maxSwapTenor_ = new Period(100, TimeUnit.Years); - volatilityType_ = type; - shift_ = shift; - volatility_.registerWith(update); - } - - //! floating reference date, fixed market data - public ConstantSwaptionVolatility(int settlementDays, - Calendar cal, - BusinessDayConvention bdc, - double vol, - DayCounter dc, - VolatilityType type = VolatilityType.ShiftedLognormal, - double? shift = 0.0) - : base(settlementDays, cal, bdc, dc){ - volatility_ = new Handle(new SimpleQuote(vol)); - maxSwapTenor_ = new Period(100, TimeUnit.Years); - volatilityType_ = type; - shift_ = shift; - } - - //! fixed reference date, fixed market data - public ConstantSwaptionVolatility( Date referenceDate, - Calendar cal, - BusinessDayConvention bdc, - double vol, - DayCounter dc, - VolatilityType type = VolatilityType.ShiftedLognormal, - double? shift = 0.0) - : base(referenceDate, cal, bdc, dc){ - volatility_ = new Handle(new SimpleQuote(vol)); - maxSwapTenor_ = new Period(100, TimeUnit.Years); - volatilityType_ = type; - shift_ = shift; - } - - // TermStructure interface - public override Date maxDate(){ - return Date.maxDate(); - } - // VolatilityTermStructure interface - public override double minStrike(){ - return double.MinValue; - } - - public override double maxStrike(){ - return double.MaxValue; - } - - // SwaptionVolatilityStructure interface - public override Period maxSwapTenor(){ - return maxSwapTenor_; - } - - public override VolatilityType volatilityType() - { - return volatilityType_; - } - - protected new SmileSection smileSectionImpl(Date d, Period p) { - double atmVol = volatility_.link.value(); - return new FlatSmileSection(d, atmVol, dayCounter(), referenceDate()); - } - - protected override SmileSection smileSectionImpl(double optionTime, double time) { - double atmVol = volatility_.link.value(); - return new FlatSmileSection(optionTime, atmVol, dayCounter()); - } - - protected new double volatilityImpl(Date date, Period period, double rate){ - return volatility_.link.value(); - } - - protected override double volatilityImpl(double time, double t, double rate){ - return volatility_.link.value(); - } - - protected override double shiftImpl(double optionTime, double swapLength) - { - base.shiftImpl(optionTime, swapLength); - return Convert.ToDouble(shift_); - } - } -} diff --git a/src/QLNet/Termstructures/Volatility/swaption/swaptionvolmatrix.cs b/src/QLNet/Termstructures/Volatility/swaption/swaptionvolmatrix.cs deleted file mode 100644 index 0e66cd9b7..000000000 --- a/src/QLNet/Termstructures/Volatility/swaption/swaptionvolmatrix.cs +++ /dev/null @@ -1,460 +0,0 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace QLNet -{ - //! At-the-money swaption-volatility matrix - /*! This class provides the at-the-money volatility for a given - swaption by interpolating a volatility matrix whose elements - are the market volatilities of a set of swaption with given - option date and swapLength. - - The volatility matrix M must be defined so that: - - the number of rows equals the number of option dates - - the number of columns equals the number of swap tenors - - M[i][j] contains the volatility corresponding - to the i-th option and j-th tenor. - */ - public class SwaptionVolatilityMatrix : SwaptionVolatilityDiscrete - { - //! floating reference date, floating market data - public SwaptionVolatilityMatrix( - Calendar calendar, - BusinessDayConvention bdc, - List optionTenors, - List swapTenors, - List>> vols, - DayCounter dayCounter, - bool flatExtrapolation = false, - VolatilityType type = VolatilityType.ShiftedLognormal, - List> shifts = null) - : base(optionTenors, swapTenors, 0, calendar, bdc, dayCounter) - { - volHandles_ = vols; - shiftValues_ = shifts; - volatilities_ = new Matrix(vols.Count, vols.First().Count); - shifts_ = new Matrix(vols.Count, vols.First().Count, 0.0); - volatilityType_ = type; - checkInputs(volatilities_.rows(), volatilities_.columns(), shifts_.rows(), shifts_.columns()); - registerWithMarketData(); - - // fill dummy handles to allow generic handle-based - if (shiftValues_ == null) - { - shiftValues_ = new InitializedList>(volatilities_.rows()); - for (int i = 0; i < volatilities_.rows(); ++i) - { - shiftValues_[i] = new InitializedList(volatilities_.columns()); - for (int j = 0; j < volatilities_.columns(); ++j) - { - shiftValues_[i][j] = shifts_.rows() > 0 ? shifts_[i, j] : 0.0; - } - } - } - - if (flatExtrapolation) - { - interpolation_ = new FlatExtrapolator2D(new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, volatilities_)); - - interpolationShifts_ = new FlatExtrapolator2D(new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, shifts_)); - } - else - { - interpolation_ = new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, - volatilities_); - - interpolationShifts_ = new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, - shifts_); - } - } - - //! fixed reference date, floating market data - public SwaptionVolatilityMatrix( - Date referenceDate, - Calendar calendar, - BusinessDayConvention bdc, - List optionTenors, - List swapTenors, - List>> vols, - DayCounter dayCounter, - bool flatExtrapolation = false, - VolatilityType type = VolatilityType.ShiftedLognormal, - List> shifts = null) - : base(optionTenors, swapTenors, referenceDate, calendar, bdc, dayCounter) - { - volHandles_ = vols; - shiftValues_ = shifts; - volatilities_ = new Matrix(vols.Count, vols.First().Count); - shifts_ = new Matrix(vols.Count, vols.First().Count, 0.0); - volatilityType_ = type; - checkInputs(volatilities_.rows(), volatilities_.columns(), shifts_.rows(), shifts_.columns()); - registerWithMarketData(); - - // fill dummy handles to allow generic handle-based - if (shiftValues_ == null) - { - shiftValues_ = new InitializedList>(volatilities_.rows()); - for (int i = 0; i < volatilities_.rows(); ++i) - { - shiftValues_[i] = new InitializedList(volatilities_.columns()); - for (int j = 0; j < volatilities_.columns(); ++j) - { - shiftValues_[i][j] = shifts_.rows() > 0 ? shifts_[i, j] : 0.0; - } - } - } - - if (flatExtrapolation) - { - interpolation_ = new FlatExtrapolator2D(new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, volatilities_)); - - interpolationShifts_ = new FlatExtrapolator2D(new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, shifts_)); - } - else - { - interpolation_ = new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, - volatilities_); - - interpolationShifts_ = new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, - shifts_); - } - } - - //! floating reference date, fixed market data - public SwaptionVolatilityMatrix( - Calendar calendar, - BusinessDayConvention bdc, - List optionTenors, - List swapTenors, - Matrix vols, - DayCounter dayCounter, - bool flatExtrapolation = false, - VolatilityType type = VolatilityType.ShiftedLognormal, - Matrix shifts = null) - - : base(optionTenors, swapTenors, 0, calendar, bdc, dayCounter) - { - volHandles_ = new InitializedList>>(vols.rows()); - shiftValues_ = new InitializedList>(vols.rows()); - volatilities_ = new Matrix(vols.rows(), vols.columns()); - shifts_ = shifts ?? new Matrix(vols.rows(), vols.columns(), 0.0); - volatilityType_ = type; - checkInputs(volatilities_.rows(), volatilities_.columns(), shifts_.rows(), shifts_.columns()); - - // fill dummy handles to allow generic handle-based - // computations later on - for (int i = 0; i < vols.rows(); ++i) - { - volHandles_[i] = new InitializedList>(vols.columns()); - shiftValues_[i] = new InitializedList(vols.columns()); - for (int j = 0; j < vols.columns(); ++j) - volHandles_[i][j] = new Handle((new - SimpleQuote(vols[i, j]))); - } - - if (flatExtrapolation) - { - interpolation_ = new FlatExtrapolator2D(new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, volatilities_)); - - interpolationShifts_ = new FlatExtrapolator2D(new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, shifts_)); - } - else - { - interpolation_ = new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, - volatilities_); - - interpolationShifts_ = new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, - shifts_); - } - } - - //! fixed reference date, fixed market data - public SwaptionVolatilityMatrix( - Date referenceDate, - Calendar calendar, - BusinessDayConvention bdc, - List optionTenors, - List swapTenors, - Matrix vols, - DayCounter dayCounter, - bool flatExtrapolation = false, - VolatilityType type = VolatilityType.ShiftedLognormal, - Matrix shifts = null) - : base(optionTenors, swapTenors, referenceDate, calendar, bdc, dayCounter) - { - volHandles_ = new InitializedList>>(vols.rows()); - shiftValues_ = new InitializedList>(vols.rows()); - volatilities_ = new Matrix(vols.rows(), vols.columns()); - shifts_ = shifts ?? new Matrix(vols.rows(), vols.columns(), 0.0); - checkInputs(vols.rows(), vols.columns(), shifts_.rows(), shifts_.columns()); - volatilityType_ = type; - - // fill dummy handles to allow generic handle-based - // computations later on - for (int i = 0; i < vols.rows(); ++i) - { - volHandles_[i] = new InitializedList>(vols.columns()); - shiftValues_[i] = new InitializedList(vols.columns()); - for (int j = 0; j < vols.columns(); ++j) - { - volHandles_[i][j] = new Handle((new - SimpleQuote(vols[i, j]))); - shiftValues_[i][j] = shifts_.rows() > 0 ? shifts_[i, j] : 0.0; - } - } - - if (flatExtrapolation) - { - interpolation_ = new FlatExtrapolator2D(new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, volatilities_)); - - interpolationShifts_ = new FlatExtrapolator2D(new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, shifts_)); - } - else - { - interpolation_ = new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, - volatilities_); - - interpolationShifts_ = new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, - shifts_); - } - } - - // fixed reference date and fixed market data, option dates - public SwaptionVolatilityMatrix(Date today, - List optionDates, - List swapTenors, - Matrix vols, - DayCounter dayCounter, - bool flatExtrapolation = false, - VolatilityType type = VolatilityType.ShiftedLognormal, - Matrix shifts = null) - : base(optionDates, swapTenors, today, new Calendar(), BusinessDayConvention.Following, dayCounter) - { - volHandles_ = new InitializedList>>(vols.rows()); - shiftValues_ = new InitializedList>(vols.rows()); - volatilities_ = new Matrix(vols.rows(), vols.columns()); - shifts_ = shifts ?? new Matrix(vols.rows(), vols.columns(), 0.0); - checkInputs(vols.rows(), vols.columns(), shifts_.rows(), shifts_.columns()); - volatilityType_ = type; - - // fill dummy handles to allow generic handle-based - // computations later on - for (int i = 0; i < vols.rows(); ++i) - { - volHandles_[i] = new InitializedList>(vols.columns()); - shiftValues_[i] = new InitializedList(vols.columns()); - for (int j = 0; j < vols.columns(); ++j) - { - volHandles_[i][j] = new Handle((new - SimpleQuote(vols[i, j]))); - shiftValues_[i][j] = shifts_.rows() > 0 ? shifts_[i, j] : 0.0; - } - } - - if (flatExtrapolation) - { - interpolation_ = new FlatExtrapolator2D(new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, volatilities_)); - - interpolationShifts_ = new FlatExtrapolator2D(new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, shifts_)); - } - else - { - interpolation_ = new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, - volatilities_); - - interpolationShifts_ = new BilinearInterpolation( - swapLengths_, swapLengths_.Count, - optionTimes_, optionTimes_.Count, - shifts_); - } - } - - // LazyObject interface - //verifier protected QL public!! - protected override void performCalculations() - { - base.performCalculations(); - - // we might use iterators here... - for (int i = 0; i < volatilities_.rows(); ++i) - { - for (int j = 0; j < volatilities_.columns(); ++j) - { - volatilities_[i, j] = volHandles_[i][j].link.value(); - if (shiftValues_.Count > 0) - shifts_[i, j] = shiftValues_[i][j]; - } - } - } - - // TermStructure interface - public override Date maxDate() - { - return optionDates_.Last(); - } - - // VolatilityTermStructure interface - public override double minStrike() - { - return double.MinValue; - } - - public override double maxStrike() - { - return double.MaxValue; - } - - // SwaptionVolatilityStructure interface - public override Period maxSwapTenor() - { - return swapTenors_.Last(); - } - - // Other inspectors - //! returns the lower indexes of surrounding volatility matrix corners - public KeyValuePair locate(Date optionDate, - Period swapTenor) - { - return locate(timeFromReference(optionDate), - swapLength(swapTenor)); - } - - //! returns the lower indexes of surrounding volatility matrix corners - public KeyValuePair locate(double optionTime, - double swapLength) - { - return new KeyValuePair(interpolation_.locateY(optionTime), - interpolation_.locateX(swapLength)); - } - - //Volatility type - public override VolatilityType volatilityType() - { - return volatilityType_; - } - - #region protected - // defining the following method would break CMS test suite - // to be further investigated - protected override SmileSection smileSectionImpl(double optionTime, double swapLength) - { - double atmVol = volatilityImpl(optionTime, swapLength, 0.05); - double shift = interpolationShifts_.value(optionTime, swapLength, true); - return (SmileSection)new FlatSmileSection(optionTime, atmVol, dayCounter(), null, volatilityType(), shift); - - } - - protected override double volatilityImpl(double optionTime, double swapLength, - double strike) - { - calculate(); - return interpolation_.value(swapLength, optionTime, true); - } - - protected override double shiftImpl(double optionTime, double swapLength) - { - calculate(); - double tmp = interpolationShifts_.value(swapLength, optionTime, true); - return tmp; - } - #endregion - - #region private - private void checkInputs(int volRows, - int volsColumns, - int shiftRows, - int shiftsColumns) - { - Utils.QL_REQUIRE(nOptionTenors_ == volRows, () => - "mismatch between number of option dates (" + nOptionTenors_ + ") and number of rows (" + - volRows + ") in the vol matrix"); - Utils.QL_REQUIRE(nSwapTenors_ == volsColumns, () => - "mismatch between number of swap tenors (" + nSwapTenors_ + ") and number of rows (" + - volsColumns + ") in the vol matrix"); - - if (shiftRows == 0 && shiftsColumns == 0) - { - shifts_ = new Matrix(volRows, volsColumns, 0.0); - shiftRows = volRows; - shiftsColumns = volsColumns; - } - - Utils.QL_REQUIRE(nOptionTenors_ == shiftRows, () => - "mismatch between number of option dates (" + nOptionTenors_ + ") and number of rows (" + - shiftRows + ") in the shift matrix"); - Utils.QL_REQUIRE(nSwapTenors_ == shiftsColumns, () => - "mismatch between number of swap tenors (" + nSwapTenors_ + ") and number of rows (" + - shiftsColumns + ") in the shift matrix"); - } - private void registerWithMarketData() - { - for (int i = 0; i < volHandles_.Count; ++i) - for (int j = 0; j < volHandles_.First().Count; ++j) - volHandles_[i][j].registerWith(update); - } - private List>> volHandles_; - private List> shiftValues_; - private Matrix volatilities_, shifts_; - private Interpolation2D interpolation_, interpolationShifts_; - VolatilityType volatilityType_; - #endregion - } - -} diff --git a/src/QLNet/Termstructures/Yield/BasisSwapHelper.cs b/src/QLNet/Termstructures/Yield/BasisSwapHelper.cs index fe4b22918..1c1202c5d 100644 --- a/src/QLNet/Termstructures/Yield/BasisSwapHelper.cs +++ b/src/QLNet/Termstructures/Yield/BasisSwapHelper.cs @@ -1,16 +1,16 @@ /* Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -33,15 +33,15 @@ assumed to be equal to the settlement date of the swap itself. public class BasisSwapHelper : RelativeDateRateHelper { public BasisSwapHelper(Handle spreadQuote, - int settlementDays, - Period swapTenor, - Calendar settlementCalendar, - BusinessDayConvention rollConvention, - IborIndex shortIndex, - IborIndex longIndex, - Handle discount = null, - bool eom = true, - bool spreadOnShort = true) + int settlementDays, + Period swapTenor, + Calendar settlementCalendar, + BusinessDayConvention rollConvention, + IborIndex shortIndex, + IborIndex longIndex, + Handle discount = null, + bool eom = true, + bool spreadOnShort = true) : base(spreadQuote) { settlementDays_ = settlementDays; @@ -106,23 +106,23 @@ protected override void initializeDates() Period shortLegTenor = shortIndex_.tenor(); Schedule shortLegSchedule = new MakeSchedule() - .from(settlementDate) - .to(maturityDate) - .withTenor(shortLegTenor) - .withCalendar(settlementCalendar_) - .withConvention(rollConvention_) - .endOfMonth(eom_) - .value(); + .from(settlementDate) + .to(maturityDate) + .withTenor(shortLegTenor) + .withCalendar(settlementCalendar_) + .withConvention(rollConvention_) + .endOfMonth(eom_) + .value(); Period longLegTenor = longIndex_.tenor(); Schedule longLegSchedule = new MakeSchedule() - .from(settlementDate) - .to(maturityDate) - .withTenor(longLegTenor) - .withCalendar(settlementCalendar_) - .withConvention(rollConvention_) - .endOfMonth(eom_) - .value(); + .from(settlementDate) + .to(maturityDate) + .withTenor(longLegTenor) + .withCalendar(settlementCalendar_) + .withConvention(rollConvention_) + .endOfMonth(eom_) + .value(); double nominal = 1.0; double shortLegSpread = 0.0; @@ -139,9 +139,9 @@ protected override void initializeDates() /* Arbitrarily set the swap as paying the long index */ swap_ = new BasisSwap(BasisSwap.Type.Payer, nominal, - shortLegSchedule, shortIndex_, shortLegSpread, shortIndex_.dayCounter(), - longLegSchedule, longIndex_, longLegSpread, longIndex_.dayCounter(), - BusinessDayConvention.Following); + shortLegSchedule, shortIndex_, shortLegSpread, shortIndex_.dayCounter(), + longLegSchedule, longIndex_, longLegSpread, longIndex_.dayCounter(), + BusinessDayConvention.Following); IPricingEngine engine; diff --git a/src/QLNet/Termstructures/Yield/Bondhelpers.cs b/src/QLNet/Termstructures/Yield/Bondhelpers.cs index f60ac5d26..1c9d91e1c 100644 --- a/src/QLNet/Termstructures/Yield/Bondhelpers.cs +++ b/src/QLNet/Termstructures/Yield/Bondhelpers.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -35,8 +35,8 @@ to give wrong results. It is advised to discard the bond after creating the helper, so that the helper has sole ownership of it. */ - public BondHelper( Handle price, Bond bond, bool useCleanPrice = true ) - : base( price ) + public BondHelper(Handle price, Bond bond, bool useCleanPrice = true) + : base(price) { bond_ = bond; @@ -44,7 +44,7 @@ public BondHelper( Handle price, Bond bond, bool useCleanPrice = true ) // bond's maturity date because of adjustment latestDate_ = bond_.cashflows().Last().date(); earliestDate_ = bond_.nextCashFlowDate(); - + termStructureHandle_ = new RelinkableHandle(); bond_.setPricingEngine(new DiscountingBondEngine(termStructureHandle_)); @@ -53,19 +53,19 @@ public BondHelper( Handle price, Bond bond, bool useCleanPrice = true ) // RateHelper interface - public override void setTermStructure( YieldTermStructure t ) + public override void setTermStructure(YieldTermStructure t) { // do not set the relinkable handle as an observer - force recalculation when needed - termStructureHandle_.linkTo( t, false ); - base.setTermStructure( t ); + termStructureHandle_.linkTo(t, false); + base.setTermStructure(t); } public override double impliedQuote() { - Utils.QL_REQUIRE( termStructure_ != null,()=> "term structure not set" ); + Utils.QL_REQUIRE(termStructure_ != null, () => "term structure not set"); // we didn't register as observers - force calculation bond_.recalculate(); - if ( useCleanPrice_ ) + if (useCleanPrice_) return bond_.cleanPrice(); else return bond_.dirtyPrice(); @@ -83,26 +83,26 @@ public override double impliedQuote() //! Fixed-coupon bond helper for curve bootstrap public class FixedRateBondHelper : BondHelper { - public FixedRateBondHelper( Handle price, - int settlementDays, - double faceAmount, - Schedule schedule, - List coupons, - DayCounter dayCounter, - BusinessDayConvention paymentConvention = BusinessDayConvention.Following, - double redemption = 100, - Date issueDate = null, - Calendar paymentCalendar = null, - Period exCouponPeriod = null, - Calendar exCouponCalendar = null, - BusinessDayConvention exCouponConvention = BusinessDayConvention.Unadjusted, - bool exCouponEndOfMonth = false, - bool useCleanPrice = true ) - : base( price, new FixedRateBond( settlementDays, faceAmount, schedule, - coupons, dayCounter, paymentConvention, - redemption, issueDate, paymentCalendar, - exCouponPeriod, exCouponCalendar, - exCouponConvention, exCouponEndOfMonth ), useCleanPrice ) + public FixedRateBondHelper(Handle price, + int settlementDays, + double faceAmount, + Schedule schedule, + List coupons, + DayCounter dayCounter, + BusinessDayConvention paymentConvention = BusinessDayConvention.Following, + double redemption = 100, + Date issueDate = null, + Calendar paymentCalendar = null, + Period exCouponPeriod = null, + Calendar exCouponCalendar = null, + BusinessDayConvention exCouponConvention = BusinessDayConvention.Unadjusted, + bool exCouponEndOfMonth = false, + bool useCleanPrice = true) + : base(price, new FixedRateBond(settlementDays, faceAmount, schedule, + coupons, dayCounter, paymentConvention, + redemption, issueDate, paymentCalendar, + exCouponPeriod, exCouponCalendar, + exCouponConvention, exCouponEndOfMonth), useCleanPrice) { fixedRateBond_ = bond_ as FixedRateBond; } @@ -114,30 +114,30 @@ public FixedRateBondHelper( Handle price, //! CPI bond helper for curve bootstrap public class CPIBondHelper : BondHelper { - public CPIBondHelper( Handle price, - int settlementDays, - double faceAmount, - bool growthOnly, - double baseCPI, - Period observationLag, - ZeroInflationIndex cpiIndex, - InterpolationType observationInterpolation, - Schedule schedule, - List fixedRate, - DayCounter accrualDayCounter, - BusinessDayConvention paymentConvention = BusinessDayConvention.Following, - Date issueDate = null, - Calendar paymentCalendar = null, - Period exCouponPeriod = null, - Calendar exCouponCalendar = null, - BusinessDayConvention exCouponConvention = BusinessDayConvention.Unadjusted, - bool exCouponEndOfMonth = false, - bool useCleanPrice = true ) - : base( price, new CPIBond( settlementDays, faceAmount, growthOnly, baseCPI, - observationLag, cpiIndex, observationInterpolation, - schedule, fixedRate, accrualDayCounter, paymentConvention, - issueDate, paymentCalendar, exCouponPeriod, exCouponCalendar, - exCouponConvention, exCouponEndOfMonth ), useCleanPrice ) + public CPIBondHelper(Handle price, + int settlementDays, + double faceAmount, + bool growthOnly, + double baseCPI, + Period observationLag, + ZeroInflationIndex cpiIndex, + InterpolationType observationInterpolation, + Schedule schedule, + List fixedRate, + DayCounter accrualDayCounter, + BusinessDayConvention paymentConvention = BusinessDayConvention.Following, + Date issueDate = null, + Calendar paymentCalendar = null, + Period exCouponPeriod = null, + Calendar exCouponCalendar = null, + BusinessDayConvention exCouponConvention = BusinessDayConvention.Unadjusted, + bool exCouponEndOfMonth = false, + bool useCleanPrice = true) + : base(price, new CPIBond(settlementDays, faceAmount, growthOnly, baseCPI, + observationLag, cpiIndex, observationInterpolation, + schedule, fixedRate, accrualDayCounter, paymentConvention, + issueDate, paymentCalendar, exCouponPeriod, exCouponCalendar, + exCouponConvention, exCouponEndOfMonth), useCleanPrice) { cpiBond_ = bond_ as CPIBond; } diff --git a/src/QLNet/Termstructures/Yield/Bootstraptraits.cs b/src/QLNet/Termstructures/Yield/Bootstraptraits.cs index 2448f001f..ca5b99396 100644 --- a/src/QLNet/Termstructures/Yield/Bootstraptraits.cs +++ b/src/QLNet/Termstructures/Yield/Bootstraptraits.cs @@ -2,18 +2,18 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2014 Edem Dawui (edawui@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,238 +24,238 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - public interface ITraits - { - Date initialDate( T c ); // start of curve data - double initialValue( T c ); // value at reference date + public interface ITraits + { + Date initialDate(T c); // start of curve data + double initialValue(T c); // value at reference date double guess(int i, InterpolatedCurve c, bool validData, int first); // possible constraints based on previous values double minValueAfter(int i, InterpolatedCurve c, bool validData, int first); double maxValueAfter(int i, InterpolatedCurve c, bool validData, int first); // update with new guess - void updateGuess( List data, double discount, int i ); - int maxIterations(); // upper bound for convergence loop - - // - double discountImpl( Interpolation i, double t ); - double zeroYieldImpl( Interpolation i, double t ); - double forwardImpl( Interpolation i, double t ); - } - - public class Discount : ITraits - { - const double maxRate = 1; - const double avgRate = 0.05; - public Date initialDate( YieldTermStructure c ) { return c.referenceDate(); } // start of curve data - public double initialValue( YieldTermStructure c ) { return 1; } // value at reference date - // update with new guess - public void updateGuess( List data, double discount, int i ) { data[i] = discount; } - public int maxIterations() { return 100; } // upper bound for convergence loop - - public double discountImpl( Interpolation i, double t ) { return i.value( t, true ); } - public double zeroYieldImpl( Interpolation i, double t ) { throw new NotSupportedException(); } - public double forwardImpl( Interpolation i, double t ) { throw new NotSupportedException(); } - - - public double guess( int i, InterpolatedCurve c, bool validData, int f ) - { - if ( validData ) // previous iteration value - return c.data()[i]; - - if ( i == 1 ) // first pillar - return 1.0 / ( 1.0 + avgRate * c.times()[1] ); - - // flat rate extrapolation - double r = -System.Math.Log( c.data()[i - 1] ) / c.times()[i - 1]; - return System.Math.Exp( -r * c.times()[i] ); - } - public double minValueAfter( int i, InterpolatedCurve c, bool validData, int f ) - { - if ( validData ) - { - #if QL_NEGATIVE_RATES - return c.data().Min() / 2.0; - #else - return c.data().Last() / 2.0; - #endif - } - double dt = c.times()[i] - c.times()[i - 1]; - return c.data()[i - 1] * System.Math.Exp( -maxRate * dt ); - } - public double maxValueAfter( int i, InterpolatedCurve c, bool validData, int f ) - { + void updateGuess(List data, double discount, int i); + int maxIterations(); // upper bound for convergence loop + // + double discountImpl(Interpolation i, double t); + double zeroYieldImpl(Interpolation i, double t); + double forwardImpl(Interpolation i, double t); + } + + public class Discount : ITraits + { + const double maxRate = 1; + const double avgRate = 0.05; + public Date initialDate(YieldTermStructure c) { return c.referenceDate(); } // start of curve data + public double initialValue(YieldTermStructure c) { return 1; } // value at reference date + // update with new guess + public void updateGuess(List data, double discount, int i) { data[i] = discount; } + public int maxIterations() { return 100; } // upper bound for convergence loop + + public double discountImpl(Interpolation i, double t) { return i.value(t, true); } + public double zeroYieldImpl(Interpolation i, double t) { throw new NotSupportedException(); } + public double forwardImpl(Interpolation i, double t) { throw new NotSupportedException(); } + + + public double guess(int i, InterpolatedCurve c, bool validData, int f) + { + if (validData) // previous iteration value + return c.data()[i]; + + if (i == 1) // first pillar + return 1.0 / (1.0 + avgRate * c.times()[1]); + + // flat rate extrapolation + double r = -System.Math.Log(c.data()[i - 1]) / c.times()[i - 1]; + return System.Math.Exp(-r * c.times()[i]); + } + public double minValueAfter(int i, InterpolatedCurve c, bool validData, int f) + { + if (validData) + { #if QL_NEGATIVE_RATES - double dt = c.times()[i] - c.times()[i-1]; - return c.data()[i-1] * Math.Exp(maxRate * dt); + return c.data().Min() / 2.0; #else - // discounts cannot increase - return c.data()[i - 1]; + return c.data().Last() / 2.0; #endif + } + double dt = c.times()[i] - c.times()[i - 1]; + return c.data()[i - 1] * System.Math.Exp(-maxRate * dt); + } + public double maxValueAfter(int i, InterpolatedCurve c, bool validData, int f) + { - } - } - - //! Zero-curve traits - public class ZeroYield : ITraits - { - const double maxRate = 3; - const double avgRate = 0.05; - - public Date initialDate( YieldTermStructure c ) { return c.referenceDate(); } // start of curve data - public double initialValue( YieldTermStructure c ) { return avgRate; } // value at reference date - // update with new guess - public void updateGuess( List data, double rate, int i ) - { - data[i] = rate; - if ( i == 1 ) - data[0] = rate; // first point is updated as well - } - public int maxIterations() { return 30; } // upper bound for convergence loop - - public double discountImpl( Interpolation i, double t ) - { - double r = zeroYieldImpl( i, t ); - return Math.Exp( -r * t ); - } - public double zeroYieldImpl( Interpolation i, double t ) { return i.value( t, true ); } - public double forwardImpl( Interpolation i, double t ) { throw new NotSupportedException(); } - - public double guess( int i, InterpolatedCurve c, bool validData, int f ) - { - - if ( validData ) // previous iteration value - return c.data()[i]; - - if ( i == 1 ) // first pillar - return avgRate; - - // extrapolate - return zeroYieldImpl( c.interpolation_, c.times()[i] ); - } - public double minValueAfter( int i, InterpolatedCurve c, bool validData, int f ) - { - if ( validData ) - { - double r = c.data().Min(); #if QL_NEGATIVE_RATES + double dt = c.times()[i] - c.times()[i - 1]; + return c.data()[i - 1] * Math.Exp(maxRate * dt); +#else + // discounts cannot increase + return c.data()[i - 1]; +#endif - return r<0.0 ? r*2.0 : r/2.0; + } + } + + //! Zero-curve traits + public class ZeroYield : ITraits + { + const double maxRate = 3; + const double avgRate = 0.05; + + public Date initialDate(YieldTermStructure c) { return c.referenceDate(); } // start of curve data + public double initialValue(YieldTermStructure c) { return avgRate; } // value at reference date + // update with new guess + public void updateGuess(List data, double rate, int i) + { + data[i] = rate; + if (i == 1) + data[0] = rate; // first point is updated as well + } + public int maxIterations() { return 30; } // upper bound for convergence loop + + public double discountImpl(Interpolation i, double t) + { + double r = zeroYieldImpl(i, t); + return Math.Exp(-r * t); + } + public double zeroYieldImpl(Interpolation i, double t) { return i.value(t, true); } + public double forwardImpl(Interpolation i, double t) { throw new NotSupportedException(); } + + public double guess(int i, InterpolatedCurve c, bool validData, int f) + { + + if (validData) // previous iteration value + return c.data()[i]; + + if (i == 1) // first pillar + return avgRate; + + // extrapolate + return zeroYieldImpl(c.interpolation_, c.times()[i]); + } + public double minValueAfter(int i, InterpolatedCurve c, bool validData, int f) + { + if (validData) + { + double r = c.data().Min(); +#if QL_NEGATIVE_RATES + + return r < 0.0 ? r * 2.0 : r / 2.0; #else - return r / 2.0; + return r / 2.0; #endif - } + } #if QL_NEGATIVE_RATES - - // no constraints. - // We choose as min a value very unlikely to be exceeded. - return -maxRate; + + // no constraints. + // We choose as min a value very unlikely to be exceeded. + return -maxRate; #else - return Const.QL_EPSILON; + return Const.QL_EPSILON; #endif - } - public double maxValueAfter( int i, InterpolatedCurve c, bool validData, int f ) - { + } + public double maxValueAfter(int i, InterpolatedCurve c, bool validData, int f) + { - if ( validData ) - { - double r = c.data().Max(); + if (validData) + { + double r = c.data().Max(); #if QL_NEGATIVE_RATES - return r<0.0 ? r/2.0 : r*2.0; + return r < 0.0 ? r / 2.0 : r * 2.0; #else - return r * 2.0; + return r * 2.0; #endif - } - return maxRate; + } + return maxRate; - } + } } - //! Forward-curve traits - public class ForwardRate : ITraits - { - const double maxRate = 3; - const double avgRate = 0.05; - - public Date initialDate( YieldTermStructure c ) { return c.referenceDate(); } // start of curve data - public double initialValue( YieldTermStructure c ) { return avgRate; } // dummy value at reference date - // update with new guess - public void updateGuess( List data, double forward, int i ) - { - data[i] = forward; - if ( i == 1 ) - data[0] = forward; // first point is updated as well - } - // upper bound for convergence loop - public int maxIterations() { return 30; } - - public double discountImpl( Interpolation i, double t ) - { - double r = zeroYieldImpl( i, t ); - return Math.Exp( -r * t ); - } - public double zeroYieldImpl( Interpolation i, double t ) - { - if ( t.IsEqual(0.0) ) - return forwardImpl( i, 0.0 ); - else - return i.primitive( t, true ) / t; - } - public double forwardImpl( Interpolation i, double t ) - { - return i.value( t, true ); - } - - public double guess( int i, InterpolatedCurve c, bool validData, int f ) - { - if ( validData ) // previous iteration value - return c.data()[i]; - - if ( i == 1 ) // first pillar - return avgRate; - - // extrapolate - return forwardImpl( c.interpolation_, c.times()[i] ); - } - - public double minValueAfter( int i, InterpolatedCurve c, bool validData, int f ) - { - if ( validData ) - { - double r = c.data().Min(); + //! Forward-curve traits + public class ForwardRate : ITraits + { + const double maxRate = 3; + const double avgRate = 0.05; + + public Date initialDate(YieldTermStructure c) { return c.referenceDate(); } // start of curve data + public double initialValue(YieldTermStructure c) { return avgRate; } // dummy value at reference date + // update with new guess + public void updateGuess(List data, double forward, int i) + { + data[i] = forward; + if (i == 1) + data[0] = forward; // first point is updated as well + } + // upper bound for convergence loop + public int maxIterations() { return 30; } + + public double discountImpl(Interpolation i, double t) + { + double r = zeroYieldImpl(i, t); + return Math.Exp(-r * t); + } + public double zeroYieldImpl(Interpolation i, double t) + { + if (t.IsEqual(0.0)) + return forwardImpl(i, 0.0); + else + return i.primitive(t, true) / t; + } + public double forwardImpl(Interpolation i, double t) + { + return i.value(t, true); + } + + public double guess(int i, InterpolatedCurve c, bool validData, int f) + { + if (validData) // previous iteration value + return c.data()[i]; + + if (i == 1) // first pillar + return avgRate; + + // extrapolate + return forwardImpl(c.interpolation_, c.times()[i]); + } + + public double minValueAfter(int i, InterpolatedCurve c, bool validData, int f) + { + if (validData) + { + double r = c.data().Min(); #if QL_NEGATIVE_RATES - return r<0.0 ? r*2.0 : r/2.0; + return r < 0.0 ? r * 2.0 : r / 2.0; #else - return r / 2.0; + return r / 2.0; #endif - } + } #if QL_NEGATIVE_RATES - // no constraints. - // We choose as min a value very unlikely to be exceeded. - return -maxRate; + // no constraints. + // We choose as min a value very unlikely to be exceeded. + return -maxRate; #else - return Const.QL_EPSILON; + return Const.QL_EPSILON; #endif - } + } - public double maxValueAfter( int i, InterpolatedCurve c, bool validData, int f ) - { - if ( validData ) - { - double r = c.data().Max(); + public double maxValueAfter(int i, InterpolatedCurve c, bool validData, int f) + { + if (validData) + { + double r = c.data().Max(); #if QL_NEGATIVE_RATES - - return r<0.0 ? r/2.0 : r*2.0; + + return r < 0.0 ? r / 2.0 : r * 2.0; #else - return r * 2.0; + return r * 2.0; #endif - } - // no constraints. - // We choose as max a value very unlikely to be exceeded. - return maxRate; + } + // no constraints. + // We choose as max a value very unlikely to be exceeded. + return maxRate; - } + } } } diff --git a/src/QLNet/Termstructures/Yield/CompositeZeroYieldStructure.cs b/src/QLNet/Termstructures/Yield/CompositeZeroYieldStructure.cs new file mode 100644 index 000000000..2417e8f10 --- /dev/null +++ b/src/QLNet/Termstructures/Yield/CompositeZeroYieldStructure.cs @@ -0,0 +1,108 @@ +/* + Copyright (C) 2018 Francois Botha (igitur@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + public class CompositeZeroYieldStructure : ZeroYieldStructure + { + private readonly Handle curve1_; + private readonly Handle curve2_; + private readonly Compounding comp_; + private readonly Frequency freq_; + private readonly Func f_; + + public CompositeZeroYieldStructure(Handle h1, + Handle h2, + Func f, + Compounding comp = Compounding.Continuous, + Frequency freq = Frequency.NoFrequency) + + { + curve1_ = h1; + curve2_ = h2; + f_ = f; + comp_ = comp; + freq_ = freq; + + if (!curve1_.empty() && !curve2_.empty()) + enableExtrapolation(curve1_.link.allowsExtrapolation() && curve2_.link.allowsExtrapolation()); + + curve1_.registerWith(update); + curve2_.registerWith(update); + } + + public override DayCounter dayCounter() + { + return curve1_.link.dayCounter(); + } + + public override Calendar calendar() + { + return curve1_.link.calendar(); + } + + public override int settlementDays() + { + return curve1_.link.settlementDays(); + } + + public override Date referenceDate() + { + return curve1_.link.referenceDate(); + } + + public override Date maxDate() + { + return curve1_.link.maxDate(); + } + + public override double maxTime() + { + return curve1_.link.maxTime(); + } + + public override void update() + { + if (!curve1_.empty() && !curve2_.empty()) + { + base.update(); + enableExtrapolation(curve1_.link.allowsExtrapolation() && curve2_.link.allowsExtrapolation()); + } + else + { + /* The implementation inherited from YieldTermStructure + asks for our reference date, which we don't have since + the original curve is still not set. Therefore, we skip + over that and just call the base-class behavior. */ + base.update(); + } + } + + protected override double zeroYieldImpl(double t) + { + double zeroRate1 = curve1_.link.zeroRate(t, comp_, freq_, true).rate(); + double zeroRate2 = curve2_.link.zeroRate(t, comp_, freq_, true).rate(); + + InterestRate compositeRate = new InterestRate(f_(zeroRate1, zeroRate2), dayCounter(), comp_, freq_); + return compositeRate.equivalentRate(Compounding.Continuous, Frequency.NoFrequency, t).value(); + } + } +} diff --git a/src/QLNet/Termstructures/Yield/DiscountCurve.cs b/src/QLNet/Termstructures/Yield/DiscountCurve.cs index fb7449688..9d4655fee 100644 --- a/src/QLNet/Termstructures/Yield/DiscountCurve.cs +++ b/src/QLNet/Termstructures/Yield/DiscountCurve.cs @@ -7,7 +7,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -26,7 +26,7 @@ namespace QLNet //! Term structure based on interpolation of discount factors /*! \ingroup yieldtermstructures */ public class InterpolatedDiscountCurve : YieldTermStructure, InterpolatedCurve - where Interpolator : class, IInterpolationFactory, new() + where Interpolator : class, IInterpolationFactory, new () { #region InterpolatedCurve @@ -38,7 +38,7 @@ public class InterpolatedDiscountCurve : YieldTermStructure, Inter public Date maxDate_ { get; set; } public override Date maxDate() { - if ( maxDate_ != null ) + if (maxDate_ != null) return maxDate_; return dates_.Last(); @@ -150,11 +150,11 @@ public InterpolatedDiscountCurve(List dates, } public InterpolatedDiscountCurve(List dates, - List discounts, - DayCounter dayCounter, - List> jumps, - List jumpDates, - Interpolator interpolator = default(Interpolator)) + List discounts, + DayCounter dayCounter, + List> jumps, + List jumpDates, + Interpolator interpolator = default(Interpolator)) : base(dates[0], null, dayCounter, jumps, jumpDates) { times_ = new List(); @@ -167,31 +167,31 @@ public InterpolatedDiscountCurve(List dates, private void initialize() { Utils.QL_REQUIRE(dates_.Count >= interpolator_.requiredPoints, - () => "not enough input dates givesn"); + () => "not enough input dates givesn"); Utils.QL_REQUIRE(this.data_.Count == this.dates_.Count, - () => "dates/data count mismatch"); + () => "dates/data count mismatch"); Utils.QL_REQUIRE(this.data_[0].IsEqual(1.0), () => "the first discount must be == 1.0 " + - "to flag the corrsponding date as settlement date"); + "to flag the corrsponding date as settlement date"); times_ = new InitializedList(dates_.Count - 1); times_.Add(0.0); for (int i = 1; i < dates_.Count; i++) { Utils.QL_REQUIRE(dates_[i] > dates_[i - 1], - () => "invalid date (" + dates_[i] + ", vs " + dates_[i - 1] + ")"); + () => "invalid date (" + dates_[i] + ", vs " + dates_[i - 1] + ")"); times_[i] = dayCounter().yearFraction(dates_[0], dates_[i]); Utils.QL_REQUIRE(!Utils.close(this.times_[i], this.times_[i - 1]), - () => "two dates correspond to the same time " + - "under this curve's day count convention"); + () => "two dates correspond to the same time " + + "under this curve's day count convention"); Utils.QL_REQUIRE(this.data_[i] > 0.0, () => "negative discount"); #if !QL_NEGATIVE_RATES - Utils.QL_REQUIRE(this.data_[i] <= this.data_[i-1], - () => "negative forward rate implied by the discount " + - this.data_[i] + " at " + dates_[i] + - " (t=" + this.times_[i] + ") after the discount " + - this.data_[i-1] + " at " + dates_[i-1] + - " (t=" + this.times_[i-1] + ")"); + Utils.QL_REQUIRE(this.data_[i] <= this.data_[i - 1], + () => "negative forward rate implied by the discount " + + this.data_[i] + " at " + dates_[i] + + " (t=" + this.times_[i] + ") after the discount " + + this.data_[i - 1] + " at " + dates_[i - 1] + + " (t=" + this.times_[i - 1] + ")"); #endif } diff --git a/src/QLNet/Termstructures/Yield/FittedBondDiscountCurve.cs b/src/QLNet/Termstructures/Yield/FittedBondDiscountCurve.cs index 77beac409..cb1e3dbc0 100644 --- a/src/QLNet/Termstructures/Yield/FittedBondDiscountCurve.cs +++ b/src/QLNet/Termstructures/Yield/FittedBondDiscountCurve.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -70,17 +70,17 @@ public class FittedBondDiscountCurve : YieldTermStructure { // Constructors //! reference date based on current evaluation date - public FittedBondDiscountCurve( int settlementDays, - Calendar calendar, - List bondHelpers, - DayCounter dayCounter, - FittingMethod fittingMethod, - double accuracy = 1.0e-10, - int maxEvaluations = 10000, - Vector guess = null, - double simplexLambda = 1.0, - int maxStationaryStateIterations = 100) - :base(settlementDays, calendar, dayCounter) + public FittedBondDiscountCurve(int settlementDays, + Calendar calendar, + List bondHelpers, + DayCounter dayCounter, + FittingMethod fittingMethod, + double accuracy = 1.0e-10, + int maxEvaluations = 10000, + Vector guess = null, + double simplexLambda = 1.0, + int maxStationaryStateIterations = 100) + : base(settlementDays, calendar, dayCounter) { accuracy_ = accuracy; maxEvaluations_ = maxEvaluations; @@ -95,16 +95,16 @@ public FittedBondDiscountCurve( int settlementDays, } //! curve reference date fixed for life of curve - public FittedBondDiscountCurve( Date referenceDate, - List bondHelpers, - DayCounter dayCounter, - FittingMethod fittingMethod, - double accuracy = 1.0e-10, - int maxEvaluations = 10000, - Vector guess = null, - double simplexLambda = 1.0, - int maxStationaryStateIterations = 100) - :base(referenceDate, new Calendar(), dayCounter) + public FittedBondDiscountCurve(Date referenceDate, + List bondHelpers, + DayCounter dayCounter, + FittingMethod fittingMethod, + double accuracy = 1.0e-10, + int maxEvaluations = 10000, + Vector guess = null, + double simplexLambda = 1.0, + int maxStationaryStateIterations = 100) + : base(referenceDate, new Calendar(), dayCounter) { accuracy_ = accuracy; maxEvaluations_ = maxEvaluations; @@ -115,7 +115,7 @@ public FittedBondDiscountCurve( Date referenceDate, fittingMethod_ = fittingMethod; fittingMethod_.curve_ = this; - setup(); + setup(); } // Inspectors @@ -136,39 +136,39 @@ public FittingMethod fitResults() private void setup() { - for (int i=0; i "no bondHelpers given"); + { + Utils.QL_REQUIRE(!bondHelpers_.empty(), () => "no bondHelpers given"); maxDate_ = Date.minDate(); Date refDate = referenceDate(); // double check bond quotes still valid and/or instruments not expired - for (int i=0; i - (i+1) + " bond (maturity: " + - bond.maturityDate() + ") has an invalid price quote"); + Utils.QL_REQUIRE(bondHelpers_[i].quote().link.isValid(), () => + (i + 1) + " bond (maturity: " + + bond.maturityDate() + ") has an invalid price quote"); Date bondSettlement = bond.settlementDate(); - Utils.QL_REQUIRE(bondSettlement>=refDate,()=> - (i+1) + " bond settlemente date (" + - bondSettlement + ") before curve reference date (" + - refDate + ")"); - Utils.QL_REQUIRE(BondFunctions.isTradable(bond, bondSettlement),()=> - (i+1) + " bond non tradable at " + - bondSettlement + " settlement date (maturity" + - " being " + bond.maturityDate() + ")"); + Utils.QL_REQUIRE(bondSettlement >= refDate, () => + (i + 1) + " bond settlemente date (" + + bondSettlement + ") before curve reference date (" + + refDate + ")"); + Utils.QL_REQUIRE(BondFunctions.isTradable(bond, bondSettlement), () => + (i + 1) + " bond non tradable at " + + bondSettlement + " settlement date (maturity" + + " being " + bond.maturityDate() + ")"); maxDate_ = Date.Max(maxDate_, bondHelpers_[i].pillarDate()); bondHelpers_[i].setTermStructure(this); } fittingMethod_.init(); fittingMethod_.calculate(); - + } protected override double discountImpl(double t) @@ -234,8 +234,8 @@ public FittingCost(FittedBondDiscountCurve.FittingMethod fittingMethod) public override double value(Vector x) { double squaredError = 0.0; - Vector vals = values(x); - for (int i = 0; i cf = bond.cashflows(); - for (int k=firstCashFlow_[i]; k firstCashFlow_; - + } - + //! total number of coefficients to fit/solve for public virtual int size() { throw new NotImplementedException(); } //! output array of results of optimization problem @@ -295,17 +295,17 @@ public override Vector values(Vector x) public double minimumCostValue() { return costValue_;} //! clone of the current object public virtual FittingMethod clone() { throw new NotImplementedException(); } - //! return whether there is a constraint at zero - public bool constrainAtZero() {return constrainAtZero_;} - //! return weights being used - public Vector weights() {return weights_;} - //! return optimization method being used - public OptimizationMethod optimizationMethod() {return optimizationMethod_;} - //! open discountFunction to public - public double discount(Vector x, double t) {return discountFunction(x, t);} - + //! return whether there is a constraint at zero + public bool constrainAtZero() {return constrainAtZero_;} + //! return weights being used + public Vector weights() {return weights_;} + //! return optimization method being used + public OptimizationMethod optimizationMethod() {return optimizationMethod_;} + //! open discountFunction to public + public double discount(Vector x, double t) {return discountFunction(x, t);} + //! constructor - protected FittingMethod(bool constrainAtZero = true, + protected FittingMethod(bool constrainAtZero = true, Vector weights = null, OptimizationMethod optimizationMethod = null) { @@ -326,14 +326,14 @@ internal virtual void init() costFunction_ = new FittingCost(this); costFunction_.firstCashFlow_ = new InitializedList(n); - for (int i=0; i cf = bond.cashflows(); Date bondSettlement = bond.settlementDate(); - for (int k=0; k - "Given weights do not cover all boostrapping helpers"); - + Utils.QL_REQUIRE(weights_.size() == n, () => + "Given weights do not cover all boostrapping helpers"); + } //! discount function called by FittedBondDiscountCurve - internal virtual double discountFunction( Vector x, double t ) { throw new NotImplementedException(); } + internal virtual double discountFunction(Vector x, double t) { throw new NotImplementedException(); } //! constrains discount function to unity at \f$ T=0 \f$, if true protected bool constrainAtZero_; @@ -385,7 +385,7 @@ internal virtual void init() protected Vector guessSolution_; //! base class sets this cost function used in the optimization routine protected FittingCost costFunction_; - + // curve optimization called here- adjust optimization parameters here internal void calculate() { @@ -394,31 +394,31 @@ internal void calculate() // start with the guess solution, if it exists Vector x = new Vector(size(), 0.0); - if (!curve_.guessSolution_.empty()) + if (!curve_.guessSolution_.empty()) { x = curve_.guessSolution_; } - if(curve_.maxEvaluations_ == 0) - { - //Don't calculate, simply use given parameters to provide a fitted curve. - //This turns the fittedbonddiscountcurve into an evaluator of the parametric - //curve, for example allowing to use the parameters for a credit spread curve - //calculated with bonds in one currency to be coupled to a discount curve in - //another currency. - return; - } - + if (curve_.maxEvaluations_ == 0) + { + //Don't calculate, simply use given parameters to provide a fitted curve. + //This turns the fittedbonddiscountcurve into an evaluator of the parametric + //curve, for example allowing to use the parameters for a credit spread curve + //calculated with bonds in one currency to be coupled to a discount curve in + //another currency. + return; + } + //workaround for backwards compatibility OptimizationMethod optimization = optimizationMethod_; - if(optimization == null) + if (optimization == null) { - optimization = new Simplex(curve_.simplexLambda_); - } - + optimization = new Simplex(curve_.simplexLambda_); + } + Problem problem = new Problem(costFunction, constraint, x); - double rootEpsilon = curve_.accuracy_; + double rootEpsilon = curve_.accuracy_; double functionEpsilon = curve_.accuracy_; double gradientNormEpsilon = curve_.accuracy_; @@ -428,7 +428,7 @@ internal void calculate() functionEpsilon, gradientNormEpsilon); - optimization.minimize(problem,endCriteria); + optimization.minimize(problem, endCriteria); solution_ = problem.currentValue(); numberOfIterations_ = problem.functionEvaluation(); diff --git a/src/QLNet/Termstructures/Yield/Flatforward.cs b/src/QLNet/Termstructures/Yield/Flatforward.cs index 7e7b20751..e404749e6 100644 --- a/src/QLNet/Termstructures/Yield/Flatforward.cs +++ b/src/QLNet/Termstructures/Yield/Flatforward.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,73 +19,80 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! Flat interest-rate curve - public class FlatForward : YieldTermStructure { - private Quote forward_; - private Compounding compounding_; - private Frequency frequency_; - private InterestRate rate_; - - // constructors - public FlatForward(Date referenceDate, Quote forward, DayCounter dayCounter) : - this(referenceDate, forward, dayCounter, Compounding.Continuous, Frequency.Annual) {} - public FlatForward(Date referenceDate, Quote forward, DayCounter dayCounter, Compounding compounding) : - this(referenceDate, forward, dayCounter, compounding, Frequency.Annual) {} - public FlatForward(Date referenceDate, Quote forward, DayCounter dayCounter, Compounding compounding, Frequency frequency) : - base(referenceDate, new Calendar(), dayCounter) { - forward_ = forward; - compounding_ = compounding; - frequency_ = frequency; + //! Flat interest-rate curve + public class FlatForward : YieldTermStructure + { + private Quote forward_; + private Compounding compounding_; + private Frequency frequency_; + private InterestRate rate_; + + // constructors + public FlatForward(Date referenceDate, Quote forward, DayCounter dayCounter) : + this(referenceDate, forward, dayCounter, Compounding.Continuous, Frequency.Annual) {} + public FlatForward(Date referenceDate, Quote forward, DayCounter dayCounter, Compounding compounding) : + this(referenceDate, forward, dayCounter, compounding, Frequency.Annual) {} + public FlatForward(Date referenceDate, Quote forward, DayCounter dayCounter, Compounding compounding, Frequency frequency) : + base(referenceDate, new Calendar(), dayCounter) + { + forward_ = forward; + compounding_ = compounding; + frequency_ = frequency; + + forward_.registerWith(update); + } + + public FlatForward(Date referenceDate, double forward, DayCounter dayCounter) : + this(referenceDate, forward, dayCounter, Compounding.Continuous, Frequency.Annual) {} + public FlatForward(Date referenceDate, double forward, DayCounter dayCounter, Compounding compounding) : + this(referenceDate, forward, dayCounter, compounding, Frequency.Annual) {} + public FlatForward(Date referenceDate, double forward, DayCounter dayCounter, Compounding compounding, Frequency frequency) : + base(referenceDate, new Calendar(), dayCounter) + { + forward_ = new SimpleQuote(forward); + compounding_ = compounding; + frequency_ = frequency; + } - forward_.registerWith(update); - } + public FlatForward(int settlementDays, Calendar calendar, Quote forward, DayCounter dayCounter) : + this(settlementDays, calendar, forward, dayCounter, Compounding.Continuous, Frequency.Annual) {} + public FlatForward(int settlementDays, Calendar calendar, Quote forward, DayCounter dayCounter, Compounding compounding) : + this(settlementDays, calendar, forward, dayCounter, compounding, Frequency.Annual) {} + public FlatForward(int settlementDays, Calendar calendar, Quote forward, DayCounter dayCounter, Compounding compounding, Frequency frequency) : + base(settlementDays, calendar, dayCounter) + { + forward_ = forward; + compounding_ = compounding; + frequency_ = frequency; - public FlatForward(Date referenceDate, double forward, DayCounter dayCounter) : - this(referenceDate, forward, dayCounter, Compounding.Continuous, Frequency.Annual) {} - public FlatForward(Date referenceDate, double forward, DayCounter dayCounter, Compounding compounding) : - this(referenceDate, forward, dayCounter, compounding, Frequency.Annual) {} - public FlatForward(Date referenceDate, double forward, DayCounter dayCounter, Compounding compounding, Frequency frequency) : - base(referenceDate, new Calendar(), dayCounter) { - forward_ = new SimpleQuote(forward); - compounding_ = compounding; - frequency_ = frequency; - } + forward_.registerWith(update); + } - public FlatForward(int settlementDays, Calendar calendar, Quote forward, DayCounter dayCounter) : - this(settlementDays, calendar, forward, dayCounter, Compounding.Continuous, Frequency.Annual) {} - public FlatForward(int settlementDays, Calendar calendar, Quote forward, DayCounter dayCounter, Compounding compounding) : - this(settlementDays, calendar, forward, dayCounter, compounding, Frequency.Annual) {} - public FlatForward(int settlementDays, Calendar calendar, Quote forward, DayCounter dayCounter, Compounding compounding, Frequency frequency) : - base(settlementDays, calendar, dayCounter) { - forward_ = forward; - compounding_ = compounding; - frequency_ = frequency; + public FlatForward(int settlementDays, Calendar calendar, double forward, DayCounter dayCounter) : + this(settlementDays, calendar, forward, dayCounter, Compounding.Continuous, Frequency.Annual) {} + public FlatForward(int settlementDays, Calendar calendar, double forward, DayCounter dayCounter, Compounding compounding) : + this(settlementDays, calendar, forward, dayCounter, compounding, Frequency.Annual) {} + public FlatForward(int settlementDays, Calendar calendar, double forward, DayCounter dayCounter, + Compounding compounding, Frequency frequency) : + base(settlementDays, calendar, dayCounter) + { + forward_ = new SimpleQuote(forward); + compounding_ = compounding; + frequency_ = frequency; + } - forward_.registerWith(update); - } + // TermStructure interface + public override Date maxDate() { return Date.maxDate(); } - public FlatForward(int settlementDays, Calendar calendar, double forward, DayCounter dayCounter) : - this(settlementDays, calendar, forward, dayCounter, Compounding.Continuous, Frequency.Annual) {} - public FlatForward(int settlementDays, Calendar calendar, double forward, DayCounter dayCounter, Compounding compounding) : - this(settlementDays, calendar, forward, dayCounter, compounding, Frequency.Annual) {} - public FlatForward(int settlementDays, Calendar calendar, double forward, DayCounter dayCounter, - Compounding compounding, Frequency frequency) : - base(settlementDays, calendar, dayCounter) { - forward_ = new SimpleQuote(forward); - compounding_ = compounding; - frequency_ = frequency; - } - - // TermStructure interface - public override Date maxDate() { return Date.maxDate(); } + protected override double discountImpl(double t) + { + calculate(); + return rate_.discountFactor(t); + } - protected override double discountImpl(double t) { - calculate(); - return rate_.discountFactor(t); - } - - protected override void performCalculations() { - rate_ = new InterestRate(forward_.value(), dayCounter(), compounding_, frequency_); - } - } + protected override void performCalculations() + { + rate_ = new InterestRate(forward_.value(), dayCounter(), compounding_, frequency_); + } + } } diff --git a/src/QLNet/Termstructures/Yield/ForwardCurve.cs b/src/QLNet/Termstructures/Yield/ForwardCurve.cs index 48796ed34..5cdf7d052 100644 --- a/src/QLNet/Termstructures/Yield/ForwardCurve.cs +++ b/src/QLNet/Termstructures/Yield/ForwardCurve.cs @@ -7,7 +7,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -23,7 +23,7 @@ under the terms of the QLNet license. You should have received a namespace QLNet { public class InterpolatedForwardCurve : ForwardRateStructure, InterpolatedCurve - where Interpolator : class, IInterpolationFactory, new() + where Interpolator : class, IInterpolationFactory, new () { #region InterpolatedCurve @@ -35,7 +35,7 @@ public class InterpolatedForwardCurve : ForwardRateStructure, Inte public Date maxDate_ { get; set; } public override Date maxDate() { - if ( maxDate_ != null ) + if (maxDate_ != null) return maxDate_; return dates_.Last(); } @@ -161,23 +161,23 @@ public InterpolatedForwardCurve(List dates, private void initialize() { Utils.QL_REQUIRE(dates_.Count >= interpolator_.requiredPoints, - () => "not enough input dates givesn"); + () => "not enough input dates givesn"); Utils.QL_REQUIRE(this.data_.Count == this.dates_.Count, - () => "dates/data count mismatch"); + () => "dates/data count mismatch"); times_ = new InitializedList(dates_.Count); times_[0] = 0.0; for (int i = 1; i < dates_.Count; i++) { Utils.QL_REQUIRE(dates_[i] > dates_[i - 1], - () => "invalid date (" + dates_[i] + ", vs " + dates_[i - 1] + ")"); + () => "invalid date (" + dates_[i] + ", vs " + dates_[i - 1] + ")"); times_[i] = dayCounter().yearFraction(dates_[0], dates_[i]); Utils.QL_REQUIRE(!Utils.close(times_[i], times_[i - 1]), - () => "two dates correspond to the same time " + - "under this curve's day count convention"); + () => "two dates correspond to the same time " + + "under this curve's day count convention"); #if !QL_NEGATIVE_RATES - Utils.QL_REQUIRE(this.data_[i] >= 0.0, () => "negative forward" ); + Utils.QL_REQUIRE(this.data_[i] >= 0.0, () => "negative forward"); #endif } @@ -207,7 +207,7 @@ protected override double zeroYieldImpl(double t) else { integral = this.interpolation_.primitive(this.times_.Last(), true) - + this.data_.Last() * (t - this.times_.Last()); + + this.data_.Last() * (t - this.times_.Last()); } return integral / t; diff --git a/src/QLNet/Termstructures/Yield/ForwardSpreadedTermStructure.cs b/src/QLNet/Termstructures/Yield/ForwardSpreadedTermStructure.cs index 22da88f4f..b97efc8ec 100644 --- a/src/QLNet/Termstructures/Yield/ForwardSpreadedTermStructure.cs +++ b/src/QLNet/Termstructures/Yield/ForwardSpreadedTermStructure.cs @@ -1,63 +1,68 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { - //! Term structure with added spread on the instantaneous forward rate - /*! \note This term structure will remain linked to the original structure, i.e., any changes in the latter will be - reflected in this structure as well. - - \ingroup yieldtermstructures - - \test - - the correctness of the returned values is tested by checking them against numerical calculations. - - observability against changes in the underlying term structure and in the added spread is checked. - */ - public class ForwardSpreadedTermStructure : ForwardRateStructure { - private Handle originalCurve_; - private Handle spread_; - - public ForwardSpreadedTermStructure(Handle h, Handle spread) { - originalCurve_ = h; - spread_ = spread; - - originalCurve_.registerWith(update); - spread_.registerWith(update); - } - - public override DayCounter dayCounter() { return originalCurve_.link.dayCounter(); } - public override Calendar calendar() { return originalCurve_.link.calendar(); } - public override int settlementDays() { return originalCurve_.link.settlementDays(); } - public override Date referenceDate() { return originalCurve_.link.referenceDate(); } - public override Date maxDate() { return originalCurve_.link.maxDate(); } - public override double maxTime() { return originalCurve_.link.maxTime(); } - - //! returns the spreaded forward rate - protected override double forwardImpl(double t) { - return originalCurve_.link.forwardRate(t, t, Compounding.Continuous, Frequency.NoFrequency, true).rate() +namespace QLNet +{ + //! Term structure with added spread on the instantaneous forward rate + /*! \note This term structure will remain linked to the original structure, i.e., any changes in the latter will be + reflected in this structure as well. + + \ingroup yieldtermstructures + + \test + - the correctness of the returned values is tested by checking them against numerical calculations. + - observability against changes in the underlying term structure and in the added spread is checked. + */ + public class ForwardSpreadedTermStructure : ForwardRateStructure + { + private Handle originalCurve_; + private Handle spread_; + + public ForwardSpreadedTermStructure(Handle h, Handle spread) + { + originalCurve_ = h; + spread_ = spread; + + originalCurve_.registerWith(update); + spread_.registerWith(update); + } + + public override DayCounter dayCounter() { return originalCurve_.link.dayCounter(); } + public override Calendar calendar() { return originalCurve_.link.calendar(); } + public override int settlementDays() { return originalCurve_.link.settlementDays(); } + public override Date referenceDate() { return originalCurve_.link.referenceDate(); } + public override Date maxDate() { return originalCurve_.link.maxDate(); } + public override double maxTime() { return originalCurve_.link.maxTime(); } + + //! returns the spreaded forward rate + protected override double forwardImpl(double t) + { + return originalCurve_.link.forwardRate(t, t, Compounding.Continuous, Frequency.NoFrequency, true).rate() + spread_.link.value(); - } + } - //! returns the spreaded zero yield rate - /* This method must disappear should the spread become a curve */ - protected override double zeroYieldImpl(double t) { - return originalCurve_.link.zeroRate(t, Compounding.Continuous, Frequency.NoFrequency, true).rate() + //! returns the spreaded zero yield rate + /* This method must disappear should the spread become a curve */ + protected override double zeroYieldImpl(double t) + { + return originalCurve_.link.zeroRate(t, Compounding.Continuous, Frequency.NoFrequency, true).rate() + spread_.link.value(); - } - } + } + } } diff --git a/src/QLNet/Termstructures/Yield/ForwardStructure.cs b/src/QLNet/Termstructures/Yield/ForwardStructure.cs index 3fa0325e4..49abf9608 100644 --- a/src/QLNet/Termstructures/Yield/ForwardStructure.cs +++ b/src/QLNet/Termstructures/Yield/ForwardStructure.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,7 +19,7 @@ under the terms of the QLNet license. You should have received a using System; using System.Collections.Generic; -namespace QLNet +namespace QLNet { //! %Forward-rate term structure /*! This abstract class acts as an adapter to YieldTermStructure allowing @@ -31,22 +31,22 @@ Forward rates are assumed to be annual continuous compounding. \ingroup yieldtermstructures */ - public abstract class ForwardRateStructure : YieldTermStructure + public abstract class ForwardRateStructure : YieldTermStructure { #region Constructors protected ForwardRateStructure(DayCounter dc = null, - List> jumps = null, List jumpDates = null) + List> jumps = null, List jumpDates = null) : base(dc, jumps, jumpDates) {} - protected ForwardRateStructure(Date refDate,Calendar cal = null,DayCounter dc = null, - List> jumps = null, List jumpDates = null) - : base(refDate, cal, dc, jumps, jumpDates) {} + protected ForwardRateStructure(Date refDate, Calendar cal = null, DayCounter dc = null, + List> jumps = null, List jumpDates = null) + : base(refDate, cal, dc, jumps, jumpDates) {} - protected ForwardRateStructure(int settlDays,Calendar cal,DayCounter dc = null, - List> jumps = null, List jumpDates = null) + protected ForwardRateStructure(int settlDays, Calendar cal, DayCounter dc = null, + List> jumps = null, List jumpDates = null) : base(settlDays, cal, dc, jumps, jumpDates) {} - + #endregion #region Calculations @@ -94,12 +94,12 @@ protected override double discountImpl(double t) if (t.IsEqual(0.0)) // this acts as a safe guard in cases where return 1.0; // zeroYieldImpl(0.0) would throw. - double r = zeroYieldImpl(t); - return Math.Exp(-r*t); + double r = zeroYieldImpl(t); + return Math.Exp(-r * t); } #endregion - } + } } diff --git a/src/QLNet/Termstructures/Yield/ImpliedTermStructure.cs b/src/QLNet/Termstructures/Yield/ImpliedTermStructure.cs index 3bd5ed28f..717fd9fb6 100644 --- a/src/QLNet/Termstructures/Yield/ImpliedTermStructure.cs +++ b/src/QLNet/Termstructures/Yield/ImpliedTermStructure.cs @@ -1,59 +1,63 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { - //! Implied term structure at a given date in the future - /*! The given date will be the implied reference date. - - \note This term structure will remain linked to the original structure, i.e., any changes in the latter will be - reflected in this structure as well. - - \ingroup yieldtermstructures - - \test - - the correctness of the returned values is tested by checking them against numerical calculations. - - observability against changes in the underlying term structure is checked. - */ - public class ImpliedTermStructure : YieldTermStructure { - private Handle originalCurve_; - - public ImpliedTermStructure(Handle h, Date referenceDate) - : base(referenceDate) { - originalCurve_ = h; - originalCurve_.registerWith(update); - } - - // YieldTermStructure interface - public override DayCounter dayCounter() { return originalCurve_.link.dayCounter(); } - public override Calendar calendar() { return originalCurve_.link.calendar(); } - public override int settlementDays() { return originalCurve_.link.settlementDays(); } - public override Date maxDate() { return originalCurve_.link.maxDate(); } - - //! returns the discount factor as seen from the evaluation date - /* t is relative to the current reference date and needs to be converted to the time relative - to the reference date of the original curve */ - protected override double discountImpl(double t) { - Date refDate = referenceDate(); - double originalTime = t + dayCounter().yearFraction(originalCurve_.link.referenceDate(), refDate); - /* discount at evaluation date cannot be cached since the original curve could change between - invocations of this method */ - return originalCurve_.link.discount(originalTime, true) / originalCurve_.link.discount(refDate, true); - } - } +namespace QLNet +{ + //! Implied term structure at a given date in the future + /*! The given date will be the implied reference date. + + \note This term structure will remain linked to the original structure, i.e., any changes in the latter will be + reflected in this structure as well. + + \ingroup yieldtermstructures + + \test + - the correctness of the returned values is tested by checking them against numerical calculations. + - observability against changes in the underlying term structure is checked. + */ + public class ImpliedTermStructure : YieldTermStructure + { + private Handle originalCurve_; + + public ImpliedTermStructure(Handle h, Date referenceDate) + : base(referenceDate) + { + originalCurve_ = h; + originalCurve_.registerWith(update); + } + + // YieldTermStructure interface + public override DayCounter dayCounter() { return originalCurve_.link.dayCounter(); } + public override Calendar calendar() { return originalCurve_.link.calendar(); } + public override int settlementDays() { return originalCurve_.link.settlementDays(); } + public override Date maxDate() { return originalCurve_.link.maxDate(); } + + //! returns the discount factor as seen from the evaluation date + /* t is relative to the current reference date and needs to be converted to the time relative + to the reference date of the original curve */ + protected override double discountImpl(double t) + { + Date refDate = referenceDate(); + double originalTime = t + dayCounter().yearFraction(originalCurve_.link.referenceDate(), refDate); + /* discount at evaluation date cannot be cached since the original curve could change between + invocations of this method */ + return originalCurve_.link.discount(originalTime, true) / originalCurve_.link.discount(refDate, true); + } + } } diff --git a/src/QLNet/Termstructures/Yield/InterpolatedPiecewiseZeroSpreadedTermStructure.cs b/src/QLNet/Termstructures/Yield/InterpolatedPiecewiseZeroSpreadedTermStructure.cs index 8f255f56c..983e90053 100644 --- a/src/QLNet/Termstructures/Yield/InterpolatedPiecewiseZeroSpreadedTermStructure.cs +++ b/src/QLNet/Termstructures/Yield/InterpolatedPiecewiseZeroSpreadedTermStructure.cs @@ -6,7 +6,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -22,7 +22,7 @@ under the terms of the QLNet license. You should have received a namespace QLNet { public class InterpolatedPiecewiseZeroSpreadedTermStructure : ZeroYieldStructure - where Interpolator : class, IInterpolationFactory, new() + where Interpolator : class, IInterpolationFactory, new () { public InterpolatedPiecewiseZeroSpreadedTermStructure(Handle h, List> spreads, @@ -54,15 +54,15 @@ public InterpolatedPiecewiseZeroSpreadedTermStructure(Handle updateInterpolation(); } - protected Handle originalCurve_; - protected List> spreads_; - protected List dates_; - protected List times_; - protected List spreadValues_; - protected Compounding compounding_; - protected Frequency frequency_; - protected DayCounter dc_; - protected Interpolator factory_; + protected Handle originalCurve_; + protected List> spreads_; + protected List dates_; + protected List times_; + protected List spreadValues_; + protected Compounding compounding_; + protected Frequency frequency_; + protected DayCounter dc_; + protected Interpolator factory_; protected Interpolation interpolator_; public override DayCounter dayCounter() { return originalCurve_.link.dayCounter(); } @@ -80,8 +80,8 @@ protected override double zeroYieldImpl(double t) zeroRate.compounding(), zeroRate.frequency()); return spreadedRate.equivalentRate(Compounding.Continuous, Frequency.NoFrequency, t).value(); - } - + } + protected double calcSpread(double t) { if (t <= times_.First()) @@ -107,8 +107,8 @@ protected double calcSpread(double t) over that and just call the base-class behavior. */ base.update(); } - } - + } + protected void updateInterpolation() { for (int i = 0; i < dates_.Count; i++) diff --git a/src/QLNet/Termstructures/Yield/NonLinearFittingMethods.cs b/src/QLNet/Termstructures/Yield/NonLinearFittingMethods.cs index aa44bc1b8..77177c113 100644 --- a/src/QLNet/Termstructures/Yield/NonLinearFittingMethods.cs +++ b/src/QLNet/Termstructures/Yield/NonLinearFittingMethods.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -28,12 +28,12 @@ and A. Shapiro (2001): "Merrill Lynch Exponential Spline */ public class ExponentialSplinesFitting : FittedBondDiscountCurve.FittingMethod { - public ExponentialSplinesFitting( bool constrainAtZero = true, - Vector weights = null, - OptimizationMethod optimizationMethod = null) - :base(constrainAtZero, weights, optimizationMethod) + public ExponentialSplinesFitting(bool constrainAtZero = true, + Vector weights = null, + OptimizationMethod optimizationMethod = null) + : base(constrainAtZero, weights, optimizationMethod) {} - + public override FittedBondDiscountCurve.FittingMethod clone() { return MemberwiseClone() as FittedBondDiscountCurve.FittingMethod; @@ -45,27 +45,27 @@ internal override double discountFunction(Vector x, double t) { double d = 0.0; int N = size(); - double kappa = x[N-1]; + double kappa = x[N - 1]; double coeff = 0; - if (!constrainAtZero_) + if (!constrainAtZero_) { - for (int i=0; i knots, bool constrainAtZero = true, Vector weights = null, - OptimizationMethod optimizationMethod = null) - :base(constrainAtZero, weights, optimizationMethod) + public CubicBSplinesFitting(List knots, bool constrainAtZero = true, Vector weights = null, + OptimizationMethod optimizationMethod = null) + : base(constrainAtZero, weights, optimizationMethod) { - splines_ = new BSpline(3, knots.Count-5, knots); + splines_ = new BSpline(3, knots.Count - 5, knots); - Utils.QL_REQUIRE(knots.Count >= 8,()=> "At least 8 knots are required" ); + Utils.QL_REQUIRE(knots.Count >= 8, () => "At least 8 knots are required"); int basisFunctions = knots.Count - 4; - if (constrainAtZero) + if (constrainAtZero) { - size_ = basisFunctions-1; + size_ = basisFunctions - 1; // Note: A small but nonzero N_th basis function at t=0 may // lead to an ill conditioned problem N_ = 1; - Utils.QL_REQUIRE(Math.Abs(splines_.value(N_, 0.0)) > Const.QL_EPSILON,()=> - "N_th cubic B-spline must be nonzero at t=0"); - } - else + Utils.QL_REQUIRE(Math.Abs(splines_.value(N_, 0.0)) > Const.QL_EPSILON, () => + "N_th cubic B-spline must be nonzero at t=0"); + } + else { size_ = basisFunctions; N_ = 0; } } - + //! cubic B-spline basis functions - public double basisFunction( int i, double t ) { return splines_.value( i, t ); } + public double basisFunction(int i, double t) { return splines_.value(i, t); } public override FittedBondDiscountCurve.FittingMethod clone() { return MemberwiseClone() as FittedBondDiscountCurve.FittingMethod; @@ -205,37 +205,37 @@ internal override double discountFunction(Vector x, double t) { double d = 0.0; - if ( !constrainAtZero_ ) + if (!constrainAtZero_) { - for ( int i = 0; i < size_; ++i ) + for (int i = 0; i < size_; ++i) { - d += x[i] * splines_.value( i, t ); + d += x[i] * splines_.value(i, t); } } else { double T = 0.0; double sum = 0.0; - for ( int i = 0; i < size_; ++i ) + for (int i = 0; i < size_; ++i) { - if ( i < N_ ) + if (i < N_) { - d += x[i] * splines_.value( i, t ); - sum += x[i] * splines_.value( i, T ); + d += x[i] * splines_.value(i, t); + sum += x[i] * splines_.value(i, T); } else { - d += x[i] * splines_.value( i + 1, t ); - sum += x[i] * splines_.value( i + 1, T ); + d += x[i] * splines_.value(i + 1, t); + sum += x[i] * splines_.value(i + 1, T); } } double coeff = 1.0 - sum; - coeff /= splines_.value( N_, T ); - d += coeff * splines_.value( N_, t ); + coeff /= splines_.value(N_, T); + d += coeff * splines_.value(N_, t); } return d; - + } private BSpline splines_; @@ -245,17 +245,17 @@ internal override double discountFunction(Vector x, double t) } //! Simple polynomial fitting method - /* + /* This is a simple/crude, but fast and robust, means of fitting a yield curve. */ - public class SimplePolynomialFitting : FittedBondDiscountCurve.FittingMethod + public class SimplePolynomialFitting : FittedBondDiscountCurve.FittingMethod { - public SimplePolynomialFitting( int degree, - bool constrainAtZero = true, - Vector weights = null, - OptimizationMethod optimizationMethod = null) - :base(constrainAtZero, weights, optimizationMethod) + public SimplePolynomialFitting(int degree, + bool constrainAtZero = true, + Vector weights = null, + OptimizationMethod optimizationMethod = null) + : base(constrainAtZero, weights, optimizationMethod) { size_ = constrainAtZero ? degree : degree + 1; } @@ -270,16 +270,16 @@ internal override double discountFunction(Vector x, double t) { double d = 0.0; - if (!constrainAtZero_) + if (!constrainAtZero_) { - for (int i=0; i discountCurve ) - :base(method != null ? method.constrainAtZero() : true, - method != null ? method.weights() : null, - method != null ? method.optimizationMethod() : null) + public SpreadFittingMethod(FittedBondDiscountCurve.FittingMethod method, Handle discountCurve) + : base(method != null ? method.constrainAtZero() : true, + method != null ? method.weights() : null, + method != null ? method.optimizationMethod() : null) { method_ = method; discountingCurve_ = discountCurve; - Utils.QL_REQUIRE( method != null,()=> "Fitting method is empty" ); - Utils.QL_REQUIRE( !discountingCurve_.empty(),()=> "Discounting curve cannot be empty" ); + Utils.QL_REQUIRE(method != null, () => "Fitting method is empty"); + Utils.QL_REQUIRE(!discountingCurve_.empty(), () => "Discounting curve cannot be empty"); } public override FittedBondDiscountCurve.FittingMethod clone() @@ -312,32 +312,32 @@ public override FittedBondDiscountCurve.FittingMethod clone() internal override void init() { //In case discount curve has a different reference date, - //discount to this curve's reference date - if (curve_.referenceDate() != discountingCurve_.link.referenceDate()) + //discount to this curve's reference date + if (curve_.referenceDate() != discountingCurve_.link.referenceDate()) { - rebase_ = discountingCurve_.link.discount(curve_.referenceDate()); - } - else + rebase_ = discountingCurve_.link.discount(curve_.referenceDate()); + } + else { - rebase_ = 1.0; - } + rebase_ = 1.0; + } - //Call regular init - base.init(); + //Call regular init + base.init(); } public override int size() { return method_.size(); } internal override double discountFunction(Vector x, double t) { - return method_.discount( x, t ) * discountingCurve_.link.discount( t, true ) / rebase_; + return method_.discount(x, t) * discountingCurve_.link.discount(t, true) / rebase_; } - // underlying parametric method + // underlying parametric method private FittedBondDiscountCurve.FittingMethod method_; // adjustment in case underlying discount curve has different reference date private double rebase_; // discount curve from on top of which the spread will be calculated private Handle discountingCurve_; - + } } diff --git a/src/QLNet/Termstructures/Yield/OISRateHelper.cs b/src/QLNet/Termstructures/Yield/OISRateHelper.cs index e33db3919..fc73eaf21 100644 --- a/src/QLNet/Termstructures/Yield/OISRateHelper.cs +++ b/src/QLNet/Termstructures/Yield/OISRateHelper.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -37,7 +37,7 @@ public OISRateHelper(int settlementDays, public OvernightIndexedSwap swap() { return swap_; } - protected override void initializeDates() + protected override void initializeDates() { // dummy OvernightIndex with curve/swap arguments @@ -46,23 +46,24 @@ protected override void initializeDates() OvernightIndex clonedOvernightIndex = clonedIborIndex as OvernightIndex; swap_ = new MakeOIS(tenor_, clonedOvernightIndex, 0.0) - .withSettlementDays(settlementDays_) - .withDiscountingTermStructure(termStructureHandle_); - + .withSettlementDays(settlementDays_) + .withDiscountingTermStructure(termStructureHandle_); + earliestDate_ = swap_.startDate(); latestDate_ = swap_.maturityDate(); } - public override void setTermStructure(YieldTermStructure t) + public override void setTermStructure(YieldTermStructure t) { // no need to register---the index is not lazy termStructureHandle_.linkTo(t, false); base.setTermStructure(t); } - public override double impliedQuote() + public override double impliedQuote() { - if (termStructure_ == null) throw new ArgumentException("term structure not set"); + if (termStructure_ == null) + throw new ArgumentException("term structure not set"); // we didn't register as observers - force calculation swap_.recalculate(); @@ -80,49 +81,50 @@ public override double impliedQuote() //! Rate helper for bootstrapping over Overnight Indexed Swap rates public class DatedOISRateHelper : RateHelper { - + public DatedOISRateHelper(Date startDate, Date endDate, Handle fixedRate, OvernightIndex overnightIndex) - - : base(fixedRate) + + : base(fixedRate) { - overnightIndex.registerWith(update); + overnightIndex.registerWith(update); - // dummy OvernightIndex with curve/swap arguments - // review here - IborIndex clonedIborIndex = overnightIndex.clone(termStructureHandle_); - OvernightIndex clonedOvernightIndex = clonedIborIndex as OvernightIndex; + // dummy OvernightIndex with curve/swap arguments + // review here + IborIndex clonedIborIndex = overnightIndex.clone(termStructureHandle_); + OvernightIndex clonedOvernightIndex = clonedIborIndex as OvernightIndex; swap_ = new MakeOIS(new Period(), clonedOvernightIndex, 0.0) - .withEffectiveDate(startDate) - .withTerminationDate(endDate) - .withDiscountingTermStructure(termStructureHandle_); + .withEffectiveDate(startDate) + .withTerminationDate(endDate) + .withDiscountingTermStructure(termStructureHandle_); earliestDate_ = swap_.startDate(); latestDate_ = swap_.maturityDate(); - + } - public override void setTermStructure(YieldTermStructure t) + public override void setTermStructure(YieldTermStructure t) { // no need to register---the index is not lazy termStructureHandle_.linkTo(t, false); base.setTermStructure(t); - + } public override double impliedQuote() { - if (termStructure_ == null) throw new ArgumentException("term structure not set"); - + if (termStructure_ == null) + throw new ArgumentException("term structure not set"); + // we didn't register as observers - force calculation swap_.recalculate(); return swap_.fairRate().Value; - } + } protected OvernightIndexedSwap swap_; protected RelinkableHandle termStructureHandle_ = new RelinkableHandle(); diff --git a/src/QLNet/Termstructures/Yield/PiecewiseYieldCurve.cs b/src/QLNet/Termstructures/Yield/PiecewiseYieldCurve.cs index ad43e1942..84a7681ef 100644 --- a/src/QLNet/Termstructures/Yield/PiecewiseYieldCurve.cs +++ b/src/QLNet/Termstructures/Yield/PiecewiseYieldCurve.cs @@ -2,18 +2,18 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) Copyright (C) 2014 Edem Dawui (edawui@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,40 +22,47 @@ under the terms of the QLNet license. You should have received a using System.Collections.Generic; using System.Linq; -namespace QLNet { - // this is an abstract class to give access to all properties and methods of PiecewiseYieldCurve and avoiding generics - public class PiecewiseYieldCurve : YieldTermStructure, Curve - { - # region new fields: Curve - - public double initialValue() { return _traits_.initialValue( this ); } - public Date initialDate() { return _traits_.initialDate( this ); } - public void registerWith( BootstrapHelper helper ) - { - helper.registerWith( this.update ); - } - public new bool moving_ - { - get { return base.moving_; } - set { base.moving_ = value; } - } - public void setTermStructure( BootstrapHelper helper ) - { - helper.setTermStructure( this ); - } - protected ITraits _traits_ = null;//todo define with the trait for yield curve - public ITraits traits_ - { - get - { - return _traits_; - } - } - public double minValueAfter( int i, InterpolatedCurve c, bool validData, int first ) { return traits_.minValueAfter( i, c, validData, first ); } - public double maxValueAfter( int i, InterpolatedCurve c, bool validData, int first ) { return traits_.maxValueAfter( i, c, validData, first ); } - public double guess( int i, InterpolatedCurve c, bool validData, int first ) { return traits_.guess( i, c, validData, first ); } - - # endregion +namespace QLNet +{ + // this is an abstract class to give access to all properties and methods of PiecewiseYieldCurve and avoiding generics + public class PiecewiseYieldCurve : YieldTermStructure, Curve + { + # region new fields: Curve + + public double initialValue() { return _traits_.initialValue(this); } + public Date initialDate() { return _traits_.initialDate(this); } + public void registerWith(BootstrapHelper helper) + { + helper.registerWith(this.update); + } + public new bool moving_ + { + get + { + return base.moving_; + } + set + { + base.moving_ = value; + } + } + public void setTermStructure(BootstrapHelper helper) + { + helper.setTermStructure(this); + } + protected ITraits _traits_ = null;//todo define with the trait for yield curve + public ITraits traits_ + { + get + { + return _traits_; + } + } + public double minValueAfter(int i, InterpolatedCurve c, bool validData, int first) { return traits_.minValueAfter(i, c, validData, first); } + public double maxValueAfter(int i, InterpolatedCurve c, bool validData, int first) { return traits_.maxValueAfter(i, c, validData, first); } + public double guess(int i, InterpolatedCurve c, bool validData, int first) { return traits_.guess(i, c, validData, first); } + + # endregion #region InterpolatedCurve public List times_ { get; set; } @@ -68,7 +75,7 @@ public ITraits traits_ public override Date maxDate() { calculate(); - if ( maxDate_ != null ) + if (maxDate_ != null) return maxDate_; return dates_.Last(); @@ -80,18 +87,21 @@ public override Date maxDate() public Interpolation interpolation_ { get; set; } public IInterpolationFactory interpolator_ { get; set; } - public Dictionary nodes() { + public Dictionary nodes() + { calculate(); Dictionary results = new Dictionary(); dates_.ForEach((i, x) => results.Add(x, data_[i])); return results; } - public void setupInterpolation() { + public void setupInterpolation() + { interpolation_ = interpolator_.interpolate(times_, times_.Count, data_); } - public object Clone() { + public object Clone() + { InterpolatedCurve copy = this.MemberwiseClone() as InterpolatedCurve; copy.times_ = new List(times_); copy.data_ = new List(data_); @@ -108,7 +118,8 @@ public object Clone() { public void updateGuess(List data, double discount, int i) { traits_.updateGuess(data, discount, i); } public int maxIterations() { return traits_.maxIterations(); } - protected override double discountImpl(double t) { + protected override double discountImpl(double t) + { calculate(); return traits_.discountImpl(interpolation_, t); } @@ -122,63 +133,69 @@ protected override double discountImpl(double t) { #endregion #region Properties - - protected double _accuracy_; - public double accuracy_ - { - get { return _accuracy_; } - set { _accuracy_ = value; } - } - - protected List _instruments_ = new List(); - public List> instruments_ - { - get - { - //todo edem - List> instruments = new List>(); - _instruments_.ForEach((i, x) => instruments.Add( x ) ); - return instruments; - } - } - - protected IBootStrap bootstrap_; + + protected double _accuracy_; + public double accuracy_ + { + get + { + return _accuracy_; + } + set + { + _accuracy_ = value; + } + } + + protected List _instruments_ = new List(); + public List> instruments_ + { + get + { + //todo edem + List> instruments = new List>(); + _instruments_.ForEach((i, x) => instruments.Add(x)); + return instruments; + } + } + + protected IBootStrap bootstrap_; #endregion // two constructors to forward down the ctor chain - public PiecewiseYieldCurve(Date referenceDate, Calendar cal, DayCounter dc, - List> jumps = null, List jumpDates = null) : base(referenceDate, cal, dc,jumps,jumpDates) - {} + public PiecewiseYieldCurve(Date referenceDate, Calendar cal, DayCounter dc, + List> jumps = null, List jumpDates = null) : base(referenceDate, cal, dc, jumps, jumpDates) + {} public PiecewiseYieldCurve(int settlementDays, Calendar cal, DayCounter dc, - List> jumps = null, List jumpDates = null) - : base(settlementDays, cal, dc,jumps,jumpDates) - {} - public PiecewiseYieldCurve() - : base() - {} - } - - public class PiecewiseYieldCurve : PiecewiseYieldCurve - where Traits : ITraits, new() - where Interpolator : IInterpolationFactory, new() - where BootStrap : IBootStrap, new() - { + List> jumps = null, List jumpDates = null) + : base(settlementDays, cal, dc, jumps, jumpDates) + {} + public PiecewiseYieldCurve() + : base() + {} + } + + public class PiecewiseYieldCurve : PiecewiseYieldCurve + where Traits : ITraits, new () + where Interpolator : IInterpolationFactory, new () + where BootStrap : IBootStrap, new () + { #region Constructors public PiecewiseYieldCurve(Date referenceDate, List instruments, DayCounter dayCounter) - : this(referenceDate, instruments, dayCounter, new List>(), new List(), - 1.0e-12, FastActivator.Create(), FastActivator.Create()) { } + : this(referenceDate, instruments, dayCounter, new List>(), new List(), + 1.0e-12, FastActivator.Create(), FastActivator.Create()) { } public PiecewiseYieldCurve(Date referenceDate, List instruments, DayCounter dayCounter, List> jumps, List jumpDates) - : this(referenceDate, instruments, dayCounter, jumps, jumpDates, 1.0e-12, FastActivator.Create(), - FastActivator.Create()) { } + : this(referenceDate, instruments, dayCounter, jumps, jumpDates, 1.0e-12, FastActivator.Create(), + FastActivator.Create()) { } public PiecewiseYieldCurve(Date referenceDate, List instruments, DayCounter dayCounter, List> jumps, List jumpDates, double accuracy) - : this(referenceDate, instruments, dayCounter, jumps, jumpDates, accuracy, FastActivator.Create(), - FastActivator.Create()) { } + : this(referenceDate, instruments, dayCounter, jumps, jumpDates, accuracy, FastActivator.Create(), + FastActivator.Create()) { } public PiecewiseYieldCurve(Date referenceDate, List instruments, DayCounter dayCounter, List> jumps, List jumpDates, double accuracy, Interpolator i) @@ -186,7 +203,8 @@ public PiecewiseYieldCurve(Date referenceDate, List instruments, public PiecewiseYieldCurve(Date referenceDate, List instruments, DayCounter dayCounter, List> jumps, List jumpDates, double accuracy, Interpolator i, BootStrap bootstrap) - : base(referenceDate, new Calendar(), dayCounter,jumps,jumpDates) { + : base(referenceDate, new Calendar(), dayCounter, jumps, jumpDates) + { _instruments_ = instruments; @@ -200,12 +218,13 @@ public PiecewiseYieldCurve(Date referenceDate, List instruments, public PiecewiseYieldCurve(int settlementDays, Calendar calendar, List instruments, DayCounter dayCounter, List> jumps, List jumpDates, double accuracy) - : this(settlementDays, calendar, instruments, dayCounter, jumps, jumpDates, accuracy, - FastActivator.Create(), FastActivator.Create()) { } + : this(settlementDays, calendar, instruments, dayCounter, jumps, jumpDates, accuracy, + FastActivator.Create(), FastActivator.Create()) { } public PiecewiseYieldCurve(int settlementDays, Calendar calendar, List instruments, DayCounter dayCounter, List> jumps, List jumpDates, double accuracy, Interpolator i, BootStrap bootstrap) - : base(settlementDays, calendar, dayCounter,jumps,jumpDates) { + : base(settlementDays, calendar, dayCounter, jumps, jumpDates) + { _instruments_ = instruments; accuracy_ = accuracy; interpolator_ = i; @@ -213,46 +232,47 @@ public PiecewiseYieldCurve(int settlementDays, Calendar calendar, List.Create(); bootstrap_.setup(this); - } + } #endregion // observer interface - public override void update() - { + public override void update() + { base.update(); - // LazyObject::update(); // we do it in the TermStructure + // LazyObject::update(); // we do it in the TermStructure } - protected override void performCalculations() - { + protected override void performCalculations() + { // just delegate to the bootstrapper bootstrap_.calculate(); } - } - - // Allows for optional 3rd generic parameter defaulted to IterativeBootstrap - public class PiecewiseYieldCurve : PiecewiseYieldCurve - where Traits : ITraits, new() - where Interpolator : IInterpolationFactory, new() { - - public PiecewiseYieldCurve(Date referenceDate, List instruments, DayCounter dayCounter) - : base(referenceDate, instruments, dayCounter) { } - public PiecewiseYieldCurve(Date referenceDate, List instruments, - DayCounter dayCounter, List> jumps, List jumpDates) - : base(referenceDate, instruments, dayCounter, jumps, jumpDates) { } - public PiecewiseYieldCurve(Date referenceDate, List instruments, - DayCounter dayCounter, List> jumps, List jumpDates, double accuracy) - : base(referenceDate, instruments, dayCounter, jumps, jumpDates, accuracy) { } - public PiecewiseYieldCurve(Date referenceDate, List instruments, - DayCounter dayCounter, List> jumps, List jumpDates, double accuracy, Interpolator i) - : base(referenceDate, instruments, dayCounter, jumps, jumpDates, accuracy, i) { } - - public PiecewiseYieldCurve(int settlementDays, Calendar calendar, List instruments, - DayCounter dayCounter) - : this(settlementDays, calendar, instruments, dayCounter, new List>(), new List(), 1.0e-12) { } - - public PiecewiseYieldCurve(int settlementDays, Calendar calendar, List instruments, - DayCounter dayCounter, List> jumps, List jumpDates, double accuracy) - : base(settlementDays, calendar, instruments, dayCounter, jumps, jumpDates, accuracy) { } - } + } + + // Allows for optional 3rd generic parameter defaulted to IterativeBootstrap + public class PiecewiseYieldCurve : PiecewiseYieldCurve + where Traits : ITraits, new () + where Interpolator : IInterpolationFactory, new () + { + + public PiecewiseYieldCurve(Date referenceDate, List instruments, DayCounter dayCounter) + : base(referenceDate, instruments, dayCounter) { } + public PiecewiseYieldCurve(Date referenceDate, List instruments, + DayCounter dayCounter, List> jumps, List jumpDates) + : base(referenceDate, instruments, dayCounter, jumps, jumpDates) { } + public PiecewiseYieldCurve(Date referenceDate, List instruments, + DayCounter dayCounter, List> jumps, List jumpDates, double accuracy) + : base(referenceDate, instruments, dayCounter, jumps, jumpDates, accuracy) { } + public PiecewiseYieldCurve(Date referenceDate, List instruments, + DayCounter dayCounter, List> jumps, List jumpDates, double accuracy, Interpolator i) + : base(referenceDate, instruments, dayCounter, jumps, jumpDates, accuracy, i) { } + + public PiecewiseYieldCurve(int settlementDays, Calendar calendar, List instruments, + DayCounter dayCounter) + : this(settlementDays, calendar, instruments, dayCounter, new List>(), new List(), 1.0e-12) { } + + public PiecewiseYieldCurve(int settlementDays, Calendar calendar, List instruments, + DayCounter dayCounter, List> jumps, List jumpDates, double accuracy) + : base(settlementDays, calendar, instruments, dayCounter, jumps, jumpDates, accuracy) { } + } } diff --git a/src/QLNet/Termstructures/Yield/Ratehelpers.cs b/src/QLNet/Termstructures/Yield/Ratehelpers.cs index 0fad8470d..314676d76 100644 --- a/src/QLNet/Termstructures/Yield/Ratehelpers.cs +++ b/src/QLNet/Termstructures/Yield/Ratehelpers.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,73 +24,73 @@ namespace QLNet public class FuturesRateHelper : RateHelper { - public FuturesRateHelper( Handle price, - Date iborStartDate, - int lengthInMonths, - Calendar calendar, - BusinessDayConvention convention, - bool endOfMonth, - DayCounter dayCounter, - Handle convAdj = null, - Futures.Type type= Futures.Type.IMM) - : base( price ) + public FuturesRateHelper(Handle price, + Date iborStartDate, + int lengthInMonths, + Calendar calendar, + BusinessDayConvention convention, + bool endOfMonth, + DayCounter dayCounter, + Handle convAdj = null, + Futures.Type type = Futures.Type.IMM) + : base(price) { convAdj_ = convAdj ?? new Handle(); - switch (type) + switch (type) { case QLNet.Futures.Type.IMM: - Utils.QL_REQUIRE(QLNet.IMM.isIMMdate(iborStartDate, false),()=> - iborStartDate + " is not a valid IMM date"); + Utils.QL_REQUIRE(QLNet.IMM.isIMMdate(iborStartDate, false), () => + iborStartDate + " is not a valid IMM date"); break; case QLNet.Futures.Type.ASX: - Utils.QL_REQUIRE(ASX.isASXdate(iborStartDate, false),()=> - iborStartDate + " is not a valid ASX date"); + Utils.QL_REQUIRE(ASX.isASXdate(iborStartDate, false), () => + iborStartDate + " is not a valid ASX date"); break; default: Utils.QL_FAIL("unknown futures type (" + type + ")"); break; } - earliestDate_ = iborStartDate; - maturityDate_ = calendar.advance(iborStartDate, new Period(lengthInMonths,TimeUnit.Months), convention, endOfMonth); - yearFraction_ = dayCounter.yearFraction(earliestDate_, maturityDate_); - pillarDate_ = latestDate_ = latestRelevantDate_ = maturityDate_; + earliestDate_ = iborStartDate; + maturityDate_ = calendar.advance(iborStartDate, new Period(lengthInMonths, TimeUnit.Months), convention, endOfMonth); + yearFraction_ = dayCounter.yearFraction(earliestDate_, maturityDate_); + pillarDate_ = latestDate_ = latestRelevantDate_ = maturityDate_; - convAdj_.registerWith(update); + convAdj_.registerWith(update); } - public FuturesRateHelper( double price, - Date iborStartDate, - int lengthInMonths, - Calendar calendar, - BusinessDayConvention convention, - bool endOfMonth, - DayCounter dayCounter, - double convexityAdjustment = 0.0, - Futures.Type type = Futures.Type.IMM ) - : base( price ) + public FuturesRateHelper(double price, + Date iborStartDate, + int lengthInMonths, + Calendar calendar, + BusinessDayConvention convention, + bool endOfMonth, + DayCounter dayCounter, + double convexityAdjustment = 0.0, + Futures.Type type = Futures.Type.IMM) + : base(price) { - convAdj_ = new Handle( new SimpleQuote( convexityAdjustment ) ); + convAdj_ = new Handle(new SimpleQuote(convexityAdjustment)); - switch (type) + switch (type) { case Futures.Type.IMM: - Utils.QL_REQUIRE(IMM.isIMMdate(iborStartDate, false),()=> - iborStartDate + " is not a valid IMM date"); + Utils.QL_REQUIRE(IMM.isIMMdate(iborStartDate, false), () => + iborStartDate + " is not a valid IMM date"); break; case Futures.Type.ASX: - Utils.QL_REQUIRE(ASX.isASXdate(iborStartDate, false),()=> - iborStartDate + " is not a valid ASX date"); + Utils.QL_REQUIRE(ASX.isASXdate(iborStartDate, false), () => + iborStartDate + " is not a valid ASX date"); break; default: Utils.QL_FAIL("unknown futures type (" + type + ")"); break; } earliestDate_ = iborStartDate; - maturityDate_ = calendar.advance(iborStartDate, new Period(lengthInMonths,TimeUnit.Months),convention, endOfMonth); + maturityDate_ = calendar.advance(iborStartDate, new Period(lengthInMonths, TimeUnit.Months), convention, endOfMonth); yearFraction_ = dayCounter.yearFraction(earliestDate_, maturityDate_); - pillarDate_ = latestDate_ = latestRelevantDate_ = maturityDate_; + pillarDate_ = latestDate_ = latestRelevantDate_ = maturityDate_; } public FuturesRateHelper(Handle price, @@ -99,25 +99,25 @@ public FuturesRateHelper(Handle price, DayCounter dayCounter, Handle convAdj = null, Futures.Type type = Futures.Type.IMM) - :base(price) + : base(price) { convAdj_ = convAdj ?? new Handle(); - - switch (type) + + switch (type) { case Futures.Type.IMM: - Utils.QL_REQUIRE(IMM.isIMMdate(iborStartDate, false),()=> - iborStartDate + " is not a valid IMM date"); - if (iborEndDate == null) + Utils.QL_REQUIRE(IMM.isIMMdate(iborStartDate, false), () => + iborStartDate + " is not a valid IMM date"); + if (iborEndDate == null) { // advance 3 months maturityDate_ = IMM.nextDate(iborStartDate, false); maturityDate_ = IMM.nextDate(maturityDate_, false); maturityDate_ = IMM.nextDate(maturityDate_, false); } - else + else { - Utils.QL_REQUIRE(iborEndDate>iborStartDate,()=> + Utils.QL_REQUIRE(iborEndDate > iborStartDate, () => "end date (" + iborEndDate + ") must be greater than start date (" + iborStartDate + ")"); @@ -125,18 +125,18 @@ public FuturesRateHelper(Handle price, } break; case QLNet.Futures.Type.ASX: - Utils.QL_REQUIRE(ASX.isASXdate(iborStartDate, false),()=> - iborStartDate + " is not a valid ASX date"); - if (iborEndDate == null) + Utils.QL_REQUIRE(ASX.isASXdate(iborStartDate, false), () => + iborStartDate + " is not a valid ASX date"); + if (iborEndDate == null) { // advance 3 months maturityDate_ = ASX.nextDate(iborStartDate, false); maturityDate_ = ASX.nextDate(maturityDate_, false); maturityDate_ = ASX.nextDate(maturityDate_, false); } - else + else { - Utils.QL_REQUIRE(iborEndDate>iborStartDate,()=> + Utils.QL_REQUIRE(iborEndDate > iborStartDate, () => "end date (" + iborEndDate + ") must be greater than start date (" + iborStartDate + ")"); @@ -154,83 +154,83 @@ public FuturesRateHelper(Handle price, convAdj_.registerWith(update); } - public FuturesRateHelper( double price, - Date iborStartDate, - Date iborEndDate, - DayCounter dayCounter, - double convAdj = 0, - Futures.Type type = Futures.Type.IMM ) - : base( price ) + public FuturesRateHelper(double price, + Date iborStartDate, + Date iborEndDate, + DayCounter dayCounter, + double convAdj = 0, + Futures.Type type = Futures.Type.IMM) + : base(price) { convAdj_ = new Handle(new SimpleQuote(convAdj)); - switch ( type ) + switch (type) { case Futures.Type.IMM: - Utils.QL_REQUIRE( IMM.isIMMdate( iborStartDate, false ), () => - iborStartDate + " is not a valid IMM date" ); - if ( iborEndDate == null ) + Utils.QL_REQUIRE(IMM.isIMMdate(iborStartDate, false), () => + iborStartDate + " is not a valid IMM date"); + if (iborEndDate == null) { // advance 3 months - maturityDate_ = IMM.nextDate( iborStartDate, false ); - maturityDate_ = IMM.nextDate( maturityDate_, false ); - maturityDate_ = IMM.nextDate( maturityDate_, false ); + maturityDate_ = IMM.nextDate(iborStartDate, false); + maturityDate_ = IMM.nextDate(maturityDate_, false); + maturityDate_ = IMM.nextDate(maturityDate_, false); } else { - Utils.QL_REQUIRE( iborEndDate > iborStartDate, () => + Utils.QL_REQUIRE(iborEndDate > iborStartDate, () => "end date (" + iborEndDate + ") must be greater than start date (" + - iborStartDate + ")" ); + iborStartDate + ")"); maturityDate_ = iborEndDate; } break; case Futures.Type.ASX: - Utils.QL_REQUIRE( ASX.isASXdate( iborStartDate, false ), () => - iborStartDate + " is not a valid ASX date" ); - if ( iborEndDate == null ) + Utils.QL_REQUIRE(ASX.isASXdate(iborStartDate, false), () => + iborStartDate + " is not a valid ASX date"); + if (iborEndDate == null) { // advance 3 months - maturityDate_ = ASX.nextDate( iborStartDate, false ); - maturityDate_ = ASX.nextDate( maturityDate_, false ); - maturityDate_ = ASX.nextDate( maturityDate_, false ); + maturityDate_ = ASX.nextDate(iborStartDate, false); + maturityDate_ = ASX.nextDate(maturityDate_, false); + maturityDate_ = ASX.nextDate(maturityDate_, false); } else { - Utils.QL_REQUIRE( iborEndDate > iborStartDate, () => + Utils.QL_REQUIRE(iborEndDate > iborStartDate, () => "end date (" + iborEndDate + ") must be greater than start date (" + - iborStartDate + ")" ); + iborStartDate + ")"); maturityDate_ = iborEndDate; } break; default: - Utils.QL_FAIL( "unknown futures type (" + type + ")" ); + Utils.QL_FAIL("unknown futures type (" + type + ")"); break; } earliestDate_ = iborStartDate; - yearFraction_ = dayCounter.yearFraction( earliestDate_, maturityDate_ ); + yearFraction_ = dayCounter.yearFraction(earliestDate_, maturityDate_); pillarDate_ = latestDate_ = latestRelevantDate_ = maturityDate_; } - public FuturesRateHelper( Handle price, - Date iborStartDate, - IborIndex i, - Handle convAdj = null, - Futures.Type type = Futures.Type.IMM ) - : base( price ) + public FuturesRateHelper(Handle price, + Date iborStartDate, + IborIndex i, + Handle convAdj = null, + Futures.Type type = Futures.Type.IMM) + : base(price) { convAdj_ = convAdj ?? new Handle(); - switch (type) + switch (type) { case Futures.Type.IMM: - Utils.QL_REQUIRE(IMM.isIMMdate(iborStartDate, false),()=> - iborStartDate + " is not a valid IMM date"); + Utils.QL_REQUIRE(IMM.isIMMdate(iborStartDate, false), () => + iborStartDate + " is not a valid IMM date"); break; case Futures.Type.ASX: - Utils.QL_REQUIRE(ASX.isASXdate(iborStartDate, false),()=> - iborStartDate + " is not a valid ASX date"); + Utils.QL_REQUIRE(ASX.isASXdate(iborStartDate, false), () => + iborStartDate + " is not a valid ASX date"); break; default: Utils.QL_FAIL("unknown futures type (" + type + ")"); @@ -241,27 +241,27 @@ public FuturesRateHelper( Handle price, maturityDate_ = cal.advance(iborStartDate, i.tenor(), i.businessDayConvention()); yearFraction_ = i.dayCounter().yearFraction(earliestDate_, maturityDate_); pillarDate_ = latestDate_ = latestRelevantDate_ = maturityDate_; - convAdj_.registerWith( update ); + convAdj_.registerWith(update); } - public FuturesRateHelper( double price, - Date iborStartDate, - IborIndex i, - double convAdj = 0.0, - Futures.Type type = Futures.Type.IMM ) - : base( price ) + public FuturesRateHelper(double price, + Date iborStartDate, + IborIndex i, + double convAdj = 0.0, + Futures.Type type = Futures.Type.IMM) + : base(price) { - convAdj_ = new Handle( new SimpleQuote( convAdj ) ); + convAdj_ = new Handle(new SimpleQuote(convAdj)); - switch (type) + switch (type) { case Futures.Type.IMM: - Utils.QL_REQUIRE(IMM.isIMMdate(iborStartDate, false),()=> - iborStartDate + " is not a valid IMM date"); + Utils.QL_REQUIRE(IMM.isIMMdate(iborStartDate, false), () => + iborStartDate + " is not a valid IMM date"); break; case Futures.Type.ASX: - Utils.QL_REQUIRE(ASX.isASXdate(iborStartDate, false),()=> - iborStartDate + " is not a valid ASX date"); + Utils.QL_REQUIRE(ASX.isASXdate(iborStartDate, false), () => + iborStartDate + " is not a valid ASX date"); break; default: Utils.QL_FAIL("unknown futures type (" + type + ")"); @@ -271,22 +271,22 @@ public FuturesRateHelper( double price, Calendar cal = i.fixingCalendar(); maturityDate_ = cal.advance(iborStartDate, i.tenor(), i.businessDayConvention()); yearFraction_ = i.dayCounter().yearFraction(earliestDate_, maturityDate_); - pillarDate_ = latestDate_ = latestRelevantDate_ = maturityDate_; + pillarDate_ = latestDate_ = latestRelevantDate_ = maturityDate_; } //! RateHelper interface public override double impliedQuote() { - Utils.QL_REQUIRE( termStructure_ != null,()=> "term structure not set" ); + Utils.QL_REQUIRE(termStructure_ != null, () => "term structure not set"); - double forwardRate = ( termStructure_.discount( earliestDate_ ) / - termStructure_.discount( maturityDate_ ) - 1 ) / yearFraction_; + double forwardRate = (termStructure_.discount(earliestDate_) / + termStructure_.discount(maturityDate_) - 1) / yearFraction_; double convAdj = convAdj_.empty() ? 0 : convAdj_.link.value(); // Convexity, as FRA/futures adjustment, has been used in the // past to take into account futures margining vs FRA. // Therefore, there's no requirement for it to be non-negative. double futureRate = forwardRate + convAdj; - return 100.0 * ( 1.0 - futureRate ); + return 100.0 * (1.0 - futureRate); } //! FuturesRateHelper inspectors @@ -308,17 +308,17 @@ public abstract class RelativeDateRateHelper : RateHelper /////////////////////////////////////////// // constructors - protected RelativeDateRateHelper( Handle quote ) - : base( quote ) + protected RelativeDateRateHelper(Handle quote) + : base(quote) { - Settings.registerWith( update ); + Settings.registerWith(update); evaluationDate_ = Settings.evaluationDate(); } - protected RelativeDateRateHelper( double quote ) - : base( quote ) + protected RelativeDateRateHelper(double quote) + : base(quote) { - Settings.registerWith( update ); + Settings.registerWith(update); evaluationDate_ = Settings.evaluationDate(); } @@ -327,7 +327,7 @@ protected RelativeDateRateHelper( double quote ) //! Observer interface public override void update() { - if ( evaluationDate_ != Settings.evaluationDate() ) + if (evaluationDate_ != Settings.evaluationDate()) { evaluationDate_ = Settings.evaluationDate(); initializeDates(); @@ -342,44 +342,44 @@ public override void update() // Rate helper for bootstrapping over deposit rates public class DepositRateHelper : RelativeDateRateHelper { - public DepositRateHelper( Handle rate, - Period tenor, - int fixingDays, - Calendar calendar, - BusinessDayConvention convention, - bool endOfMonth, - DayCounter dayCounter ) - :base( rate ) + public DepositRateHelper(Handle rate, + Period tenor, + int fixingDays, + Calendar calendar, + BusinessDayConvention convention, + bool endOfMonth, + DayCounter dayCounter) + : base(rate) { - iborIndex_ = new IborIndex( "no-fix", tenor, fixingDays, new Currency(), calendar, convention, - endOfMonth, dayCounter, termStructureHandle_ ); + iborIndex_ = new IborIndex("no-fix", tenor, fixingDays, new Currency(), calendar, convention, + endOfMonth, dayCounter, termStructureHandle_); initializeDates(); } - public DepositRateHelper( double rate, - Period tenor, - int fixingDays, - Calendar calendar, - BusinessDayConvention convention, - bool endOfMonth, - DayCounter dayCounter ) : - base( rate ) + public DepositRateHelper(double rate, + Period tenor, + int fixingDays, + Calendar calendar, + BusinessDayConvention convention, + bool endOfMonth, + DayCounter dayCounter) : + base(rate) { - iborIndex_ = new IborIndex( "no-fix", tenor, fixingDays, new Currency(), calendar, convention, - endOfMonth, dayCounter, termStructureHandle_ ); + iborIndex_ = new IborIndex("no-fix", tenor, fixingDays, new Currency(), calendar, convention, + endOfMonth, dayCounter, termStructureHandle_); initializeDates(); } - public DepositRateHelper( Handle rate, IborIndex i ) - : base( rate ) + public DepositRateHelper(Handle rate, IborIndex i) + : base(rate) { iborIndex_ = i.clone(termStructureHandle_); initializeDates(); } - public DepositRateHelper( double rate, IborIndex i ) - : base( rate ) + public DepositRateHelper(double rate, IborIndex i) + : base(rate) { - iborIndex_ = i.clone( termStructureHandle_ ); + iborIndex_ = i.clone(termStructureHandle_); initializeDates(); } @@ -388,27 +388,27 @@ public DepositRateHelper( double rate, IborIndex i ) //! RateHelper interface public override double impliedQuote() { - Utils.QL_REQUIRE( termStructure_ != null,()=> "term structure not set" ); + Utils.QL_REQUIRE(termStructure_ != null, () => "term structure not set"); // the forecast fixing flag is set to true because // we do not want to take fixing into account - return iborIndex_.fixing( fixingDate_, true ); + return iborIndex_.fixing(fixingDate_, true); } - public override void setTermStructure( YieldTermStructure t ) + public override void setTermStructure(YieldTermStructure t) { // no need to register---the index is not lazy - termStructureHandle_.linkTo( t, false ); - base.setTermStructure( t ); + termStructureHandle_.linkTo(t, false); + base.setTermStructure(t); } protected override void initializeDates() { // if the evaluation date is not a business day // then move to the next business day - Date referenceDate = iborIndex_.fixingCalendar().adjust( evaluationDate_ ); - earliestDate_ = iborIndex_.valueDate( referenceDate ); - fixingDate_ = iborIndex_.fixingDate( earliestDate_ ); - maturityDate_ = iborIndex_.maturityDate( earliestDate_ ); + Date referenceDate = iborIndex_.fixingCalendar().adjust(evaluationDate_); + earliestDate_ = iborIndex_.valueDate(referenceDate); + fixingDate_ = iborIndex_.fixingDate(earliestDate_); + maturityDate_ = iborIndex_.maturityDate(earliestDate_); pillarDate_ = latestDate_ = latestRelevantDate_ = maturityDate_; } @@ -423,63 +423,63 @@ protected override void initializeDates() public class FraRateHelper : RelativeDateRateHelper { - public FraRateHelper( Handle rate, - int monthsToStart, - int monthsToEnd, - int fixingDays, - Calendar calendar, - BusinessDayConvention convention, - bool endOfMonth, - DayCounter dayCounter, - Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, - Date customPillarDate = null) : - base( rate ) + public FraRateHelper(Handle rate, + int monthsToStart, + int monthsToEnd, + int fixingDays, + Calendar calendar, + BusinessDayConvention convention, + bool endOfMonth, + DayCounter dayCounter, + Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, + Date customPillarDate = null) : + base(rate) { - periodToStart_ = new Period( monthsToStart, TimeUnit.Months ); + periodToStart_ = new Period(monthsToStart, TimeUnit.Months); pillarChoice_ = pillarChoice; - Utils.QL_REQUIRE( monthsToEnd > monthsToStart,()=> - "monthsToEnd (" + monthsToEnd + ") must be grater than monthsToStart (" + monthsToStart + ")" ); + Utils.QL_REQUIRE(monthsToEnd > monthsToStart, () => + "monthsToEnd (" + monthsToEnd + ") must be grater than monthsToStart (" + monthsToStart + ")"); - iborIndex_ = new IborIndex( "no-fix", new Period( monthsToEnd - monthsToStart, TimeUnit.Months ), fixingDays, - new Currency(), calendar, convention, endOfMonth, dayCounter, termStructureHandle_ ); + iborIndex_ = new IborIndex("no-fix", new Period(monthsToEnd - monthsToStart, TimeUnit.Months), fixingDays, + new Currency(), calendar, convention, endOfMonth, dayCounter, termStructureHandle_); pillarDate_ = customPillarDate; initializeDates(); } - public FraRateHelper( double rate, - int monthsToStart, - int monthsToEnd, - int fixingDays, - Calendar calendar, - BusinessDayConvention convention, - bool endOfMonth, - DayCounter dayCounter, - Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, - Date customPillarDate = null) - : base( rate ) + public FraRateHelper(double rate, + int monthsToStart, + int monthsToEnd, + int fixingDays, + Calendar calendar, + BusinessDayConvention convention, + bool endOfMonth, + DayCounter dayCounter, + Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, + Date customPillarDate = null) + : base(rate) { - periodToStart_ = new Period( monthsToStart, TimeUnit.Months ); + periodToStart_ = new Period(monthsToStart, TimeUnit.Months); pillarChoice_ = pillarChoice; - Utils.QL_REQUIRE( monthsToEnd > monthsToStart, () => - "monthsToEnd (" + monthsToEnd + ") must be grater than monthsToStart (" + monthsToStart + ")" ); + Utils.QL_REQUIRE(monthsToEnd > monthsToStart, () => + "monthsToEnd (" + monthsToEnd + ") must be grater than monthsToStart (" + monthsToStart + ")"); - iborIndex_ = new IborIndex( "no-fix", new Period( monthsToEnd - monthsToStart, TimeUnit.Months ), fixingDays, - new Currency(), calendar, convention, endOfMonth, dayCounter, termStructureHandle_ ); + iborIndex_ = new IborIndex("no-fix", new Period(monthsToEnd - monthsToStart, TimeUnit.Months), fixingDays, + new Currency(), calendar, convention, endOfMonth, dayCounter, termStructureHandle_); pillarDate_ = customPillarDate; initializeDates(); } - public FraRateHelper( Handle rate, - int monthsToStart, IborIndex i, - Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, - Date customPillarDate = null ) - : base( rate ) + public FraRateHelper(Handle rate, + int monthsToStart, IborIndex i, + Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, + Date customPillarDate = null) + : base(rate) { - periodToStart_ = new Period( monthsToStart, TimeUnit.Months ); + periodToStart_ = new Period(monthsToStart, TimeUnit.Months); pillarChoice_ = pillarChoice; - iborIndex_ = i.clone( termStructureHandle_ ); + iborIndex_ = i.clone(termStructureHandle_); // We want to be notified of changes of fixings, but we don't // want notifications from termStructureHandle_ (they would @@ -489,118 +489,118 @@ public FraRateHelper( Handle rate, initializeDates(); } - public FraRateHelper( double rate, - int monthsToStart, - IborIndex i, - Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, - Date customPillarDate = null ) - : base( rate ) + public FraRateHelper(double rate, + int monthsToStart, + IborIndex i, + Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, + Date customPillarDate = null) + : base(rate) { - periodToStart_ = new Period( monthsToStart, TimeUnit.Months ); + periodToStart_ = new Period(monthsToStart, TimeUnit.Months); pillarChoice_ = pillarChoice; - iborIndex_ = i.clone( termStructureHandle_ ); - iborIndex_.registerWith( update ); + iborIndex_ = i.clone(termStructureHandle_); + iborIndex_.registerWith(update); pillarDate_ = customPillarDate; initializeDates(); } - public FraRateHelper( Handle rate, - Period periodToStart, - int lengthInMonths, - int fixingDays, - Calendar calendar, - BusinessDayConvention convention, - bool endOfMonth, - DayCounter dayCounter, - Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, - Date customPillarDate = null) - :base(rate) + public FraRateHelper(Handle rate, + Period periodToStart, + int lengthInMonths, + int fixingDays, + Calendar calendar, + BusinessDayConvention convention, + bool endOfMonth, + DayCounter dayCounter, + Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, + Date customPillarDate = null) + : base(rate) { periodToStart_ = periodToStart; pillarChoice_ = pillarChoice; // no way to take fixing into account, // even if we would like to for FRA over today iborIndex_ = new IborIndex("no-fix", // correct family name would be needed - new Period(lengthInMonths,TimeUnit.Months), - fixingDays, - new Currency(), calendar, convention, - endOfMonth, dayCounter, termStructureHandle_); - pillarDate_ = customPillarDate; - initializeDates(); + new Period(lengthInMonths, TimeUnit.Months), + fixingDays, + new Currency(), calendar, convention, + endOfMonth, dayCounter, termStructureHandle_); + pillarDate_ = customPillarDate; + initializeDates(); } - - public FraRateHelper( double rate, - Period periodToStart, - int lengthInMonths, - int fixingDays, - Calendar calendar, - BusinessDayConvention convention, - bool endOfMonth, - DayCounter dayCounter, - Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, - Date customPillarDate = null) - : base( rate ) + + public FraRateHelper(double rate, + Period periodToStart, + int lengthInMonths, + int fixingDays, + Calendar calendar, + BusinessDayConvention convention, + bool endOfMonth, + DayCounter dayCounter, + Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, + Date customPillarDate = null) + : base(rate) { periodToStart_ = periodToStart; pillarChoice_ = pillarChoice; // no way to take fixing into account, // even if we would like to for FRA over today - iborIndex_ = new IborIndex( "no-fix", // correct family name would be needed - new Period( lengthInMonths, TimeUnit.Months ), - fixingDays, - new Currency(), calendar, convention, - endOfMonth, dayCounter, termStructureHandle_ ); + iborIndex_ = new IborIndex("no-fix", // correct family name would be needed + new Period(lengthInMonths, TimeUnit.Months), + fixingDays, + new Currency(), calendar, convention, + endOfMonth, dayCounter, termStructureHandle_); pillarDate_ = customPillarDate; initializeDates(); } - - public FraRateHelper( Handle rate, - Period periodToStart, - IborIndex iborIndex, - Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, - Date customPillarDate = null) - : base( rate ) + + public FraRateHelper(Handle rate, + Period periodToStart, + IborIndex iborIndex, + Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, + Date customPillarDate = null) + : base(rate) { periodToStart_ = periodToStart; pillarChoice_ = pillarChoice; // no way to take fixing into account, // even if we would like to for FRA over today - iborIndex_ = iborIndex.clone( termStructureHandle_ ); - iborIndex_.registerWith( update ); + iborIndex_ = iborIndex.clone(termStructureHandle_); + iborIndex_.registerWith(update); pillarDate_ = customPillarDate; initializeDates(); } - - public FraRateHelper( double rate, - Period periodToStart, - IborIndex iborIndex, - Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, - Date customPillarDate = null) - : base( rate ) + + public FraRateHelper(double rate, + Period periodToStart, + IborIndex iborIndex, + Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, + Date customPillarDate = null) + : base(rate) { periodToStart_ = periodToStart; pillarChoice_ = pillarChoice; // no way to take fixing into account, // even if we would like to for FRA over today - iborIndex_ = iborIndex.clone( termStructureHandle_ ); - iborIndex_.registerWith( update ); + iborIndex_ = iborIndex.clone(termStructureHandle_); + iborIndex_.registerWith(update); pillarDate_ = customPillarDate; initializeDates(); } - public override void setTermStructure( YieldTermStructure t ) + public override void setTermStructure(YieldTermStructure t) { // no need to register---the index is not lazy - termStructureHandle_.linkTo( t, false ); - base.setTermStructure( t ); + termStructureHandle_.linkTo(t, false); + base.setTermStructure(t); } public override double impliedQuote() { - Utils.QL_REQUIRE( termStructure_ != null,()=> "term structure not set" ); - return iborIndex_.fixing( fixingDate_, true ); + Utils.QL_REQUIRE(termStructure_ != null, () => "term structure not set"); + return iborIndex_.fixing(fixingDate_, true); } protected override void initializeDates() @@ -608,11 +608,11 @@ protected override void initializeDates() // if the evaluation date is not a business day // then move to the next business day Date referenceDate = iborIndex_.fixingCalendar().adjust(evaluationDate_); - Date spotDate = iborIndex_.fixingCalendar().advance(referenceDate, new Period(iborIndex_.fixingDays(),TimeUnit.Days)); - earliestDate_ = iborIndex_.fixingCalendar().advance( spotDate, - periodToStart_, - iborIndex_.businessDayConvention(), - iborIndex_.endOfMonth()); + Date spotDate = iborIndex_.fixingCalendar().advance(referenceDate, new Period(iborIndex_.fixingDays(), TimeUnit.Days)); + earliestDate_ = iborIndex_.fixingCalendar().advance(spotDate, + periodToStart_, + iborIndex_.businessDayConvention(), + iborIndex_.endOfMonth()); // maturity date is calculated from spot date maturityDate_ = iborIndex_.fixingCalendar().advance(spotDate, periodToStart_ + iborIndex_.tenor(), @@ -622,7 +622,7 @@ protected override void initializeDates() // latest relevant date is calculated from earliestDate_ instead latestRelevantDate_ = iborIndex_.maturityDate(earliestDate_); - switch (pillarChoice_) + switch (pillarChoice_) { case Pillar.Choice.MaturityDate: pillarDate_ = maturityDate_; @@ -632,12 +632,12 @@ protected override void initializeDates() break; case Pillar.Choice.CustomDate: // pillarDate_ already assigned at construction time - Utils.QL_REQUIRE(pillarDate_ >= earliestDate_,()=> - "pillar date (" + pillarDate_ + ") must be later than or equal to the instrument's earliest date (" + - earliestDate_ + ")"); - Utils.QL_REQUIRE(pillarDate_ <= latestRelevantDate_,()=> - "pillar date (" + pillarDate_ + ") must be before or equal to the instrument's latest relevant date (" + - latestRelevantDate_ + ")"); + Utils.QL_REQUIRE(pillarDate_ >= earliestDate_, () => + "pillar date (" + pillarDate_ + ") must be later than or equal to the instrument's earliest date (" + + earliestDate_ + ")"); + Utils.QL_REQUIRE(pillarDate_ <= latestRelevantDate_, () => + "pillar date (" + pillarDate_ + ") must be before or equal to the instrument's latest relevant date (" + + latestRelevantDate_ + ")"); break; default: Utils.QL_FAIL("unknown Pillar::Choice(" + pillarChoice_ + ")"); @@ -660,18 +660,18 @@ protected override void initializeDates() // Rate helper for bootstrapping over swap rates public class SwapRateHelper : RelativeDateRateHelper { - public SwapRateHelper( Handle rate, - SwapIndex swapIndex, - Handle spread = null, - Period fwdStart = null, - // exogenous discounting curve - Handle discount = null, - Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, - Date customPillarDate = null) - : base( rate ) + public SwapRateHelper(Handle rate, + SwapIndex swapIndex, + Handle spread = null, + Period fwdStart = null, + // exogenous discounting curve + Handle discount = null, + Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, + Date customPillarDate = null) + : base(rate) { spread_ = spread ?? new Handle(); - fwdStart_ = fwdStart ?? new Period(0,TimeUnit.Days); + fwdStart_ = fwdStart ?? new Period(0, TimeUnit.Days); settlementDays_ = swapIndex.fixingDays(); tenor_ = swapIndex.tenor(); @@ -685,34 +685,34 @@ public SwapRateHelper( Handle rate, discountHandle_ = discount ?? new Handle(); // take fixing into account - iborIndex_ = swapIndex.iborIndex().clone( termStructureHandle_ ); + iborIndex_ = swapIndex.iborIndex().clone(termStructureHandle_); // We want to be notified of changes of fixings, but we don't // want notifications from termStructureHandle_ (they would // interfere with bootstrapping.) iborIndex_.registerWith(update) ; spread_.registerWith(update); - discountHandle_.registerWith( update ); + discountHandle_.registerWith(update); pillarDate_ = customPillarDate; initializeDates(); } - public SwapRateHelper( Handle rate, - Period tenor, - Calendar calendar, - Frequency fixedFrequency, - BusinessDayConvention fixedConvention, - DayCounter fixedDayCount, - IborIndex iborIndex, - Handle spread = null, - Period fwdStart = null, - // exogenous discounting curve - Handle discount = null, - int? settlementDays = null, - Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, - Date customPillarDate = null) - : base( rate ) + public SwapRateHelper(Handle rate, + Period tenor, + Calendar calendar, + Frequency fixedFrequency, + BusinessDayConvention fixedConvention, + DayCounter fixedDayCount, + IborIndex iborIndex, + Handle spread = null, + Period fwdStart = null, + // exogenous discounting curve + Handle discount = null, + int? settlementDays = null, + Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, + Date customPillarDate = null) + : base(rate) { settlementDays_ = settlementDays; tenor_ = tenor; @@ -722,34 +722,34 @@ public SwapRateHelper( Handle rate, fixedFrequency_ = fixedFrequency; fixedDayCount_ = fixedDayCount; spread_ = spread ?? new Handle(); - fwdStart_ = fwdStart ?? new Period(0,TimeUnit.Days); + fwdStart_ = fwdStart ?? new Period(0, TimeUnit.Days); discountHandle_ = discount ?? new Handle(); - if ( settlementDays_ == null) + if (settlementDays_ == null) settlementDays_ = iborIndex.fixingDays(); // take fixing into account - iborIndex_ = iborIndex.clone( termStructureHandle_ ); + iborIndex_ = iborIndex.clone(termStructureHandle_); // We want to be notified of changes of fixings, but we don't // want notifications from termStructureHandle_ (they would // interfere with bootstrapping.) iborIndex_.registerWith(update) ; - spread_.registerWith(update); - discountHandle_.registerWith(update); + spread_.registerWith(update); + discountHandle_.registerWith(update); pillarDate_ = customPillarDate; initializeDates(); } - public SwapRateHelper( double rate, - SwapIndex swapIndex, - Handle spread = null, - Period fwdStart = null, - // exogenous discounting curve - Handle discount = null, - Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, - Date customPillarDate = null) - : base( rate ) + public SwapRateHelper(double rate, + SwapIndex swapIndex, + Handle spread = null, + Period fwdStart = null, + // exogenous discounting curve + Handle discount = null, + Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, + Date customPillarDate = null) + : base(rate) { settlementDays_ = swapIndex.fixingDays(); tenor_ = swapIndex.tenor(); @@ -758,12 +758,12 @@ public SwapRateHelper( double rate, fixedConvention_ = swapIndex.fixedLegConvention(); fixedFrequency_ = swapIndex.fixedLegTenor().frequency(); fixedDayCount_ = swapIndex.dayCounter(); - spread_ = spread?? new Handle(); - fwdStart_ = fwdStart ?? new Period(0,TimeUnit.Days); + spread_ = spread ?? new Handle(); + fwdStart_ = fwdStart ?? new Period(0, TimeUnit.Days); discountHandle_ = discount ?? new Handle(); // take fixing into account - iborIndex_ = swapIndex.iborIndex().clone( termStructureHandle_ ); + iborIndex_ = swapIndex.iborIndex().clone(termStructureHandle_); // We want to be notified of changes of fixings, but we don't // want notifications from termStructureHandle_ (they would // interfere with bootstrapping.) @@ -776,21 +776,21 @@ public SwapRateHelper( double rate, } - public SwapRateHelper( double rate, - Period tenor, - Calendar calendar, - Frequency fixedFrequency, - BusinessDayConvention fixedConvention, - DayCounter fixedDayCount, - IborIndex iborIndex, - Handle spread = null, - Period fwdStart = null, - // exogenous discounting curve - Handle discount = null, - int? settlementDays = null, - Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, - Date customPillarDate = null) - : base( rate ) + public SwapRateHelper(double rate, + Period tenor, + Calendar calendar, + Frequency fixedFrequency, + BusinessDayConvention fixedConvention, + DayCounter fixedDayCount, + IborIndex iborIndex, + Handle spread = null, + Period fwdStart = null, + // exogenous discounting curve + Handle discount = null, + int? settlementDays = null, + Pillar.Choice pillarChoice = Pillar.Choice.LastRelevantDate, + Date customPillarDate = null) + : base(rate) { settlementDays_ = settlementDays; tenor_ = tenor; @@ -799,15 +799,15 @@ public SwapRateHelper( double rate, fixedConvention_ = fixedConvention; fixedFrequency_ = fixedFrequency; fixedDayCount_ = fixedDayCount; - spread_ = spread?? new Handle(); - fwdStart_ = fwdStart?? new Period(0,TimeUnit.Days); - discountHandle_ = discount?? new Handle(); + spread_ = spread ?? new Handle(); + fwdStart_ = fwdStart ?? new Period(0, TimeUnit.Days); + discountHandle_ = discount ?? new Handle(); - if ( settlementDays_ == null ) + if (settlementDays_ == null) settlementDays_ = iborIndex.fixingDays(); // take fixing into account - iborIndex_ = iborIndex.clone( termStructureHandle_ ); + iborIndex_ = iborIndex.clone(termStructureHandle_); // We want to be notified of changes of fixings, but we don't // want notifications from termStructureHandle_ (they would // interfere with bootstrapping.) @@ -815,7 +815,7 @@ public SwapRateHelper( double rate, spread_.registerWith(update); discountHandle_.registerWith(update); - pillarDate_ = customPillarDate; + pillarDate_ = customPillarDate; initializeDates(); } @@ -824,17 +824,17 @@ public SwapRateHelper( double rate, protected override void initializeDates() { // do not pass the spread here, as it might be a Quote i.e. it can dinamically change - // input discount curve Handle might be empty now but it could be assigned a curve later; + // input discount curve Handle might be empty now but it could be assigned a curve later; // use a RelinkableHandle here - swap_ = new MakeVanillaSwap( tenor_, iborIndex_, 0.0, fwdStart_ ) - .withSettlementDays( settlementDays_.Value ) - .withDiscountingTermStructure( discountRelinkableHandle_ ) - .withFixedLegDayCount( fixedDayCount_ ) - .withFixedLegTenor( new Period( fixedFrequency_ ) ) - .withFixedLegConvention( fixedConvention_ ) - .withFixedLegTerminationDateConvention( fixedConvention_ ) - .withFixedLegCalendar( calendar_ ) - .withFloatingLegCalendar( calendar_ ); + swap_ = new MakeVanillaSwap(tenor_, iborIndex_, 0.0, fwdStart_) + .withSettlementDays(settlementDays_.Value) + .withDiscountingTermStructure(discountRelinkableHandle_) + .withFixedLegDayCount(fixedDayCount_) + .withFixedLegTenor(new Period(fixedFrequency_)) + .withFixedLegConvention(fixedConvention_) + .withFixedLegTerminationDateConvention(fixedConvention_) + .withFixedLegCalendar(calendar_) + .withFloatingLegCalendar(calendar_); earliestDate_ = swap_.startDate(); @@ -843,14 +843,14 @@ protected override void initializeDates() // ...but due to adjustments, the last floating coupon might // need a later date for fixing - #if QL_USE_INDEXED_COUPON - FloatingRateCoupon lastCoupon = (FloatingRateCoupon)swap_.floatingLeg()[swap_.floatingLeg().Count - 1]; - Date fixingValueDate = iborIndex_.valueDate(lastFloating.fixingDate()); - Date endValueDate = iborIndex_.maturityDate(fixingValueDate); - latestDate_ = Date.Max(latestDate_, endValueDate); - #endif - - switch (pillarChoice_) +#if QL_USE_INDEXED_COUPON + FloatingRateCoupon lastCoupon = (FloatingRateCoupon)swap_.floatingLeg()[swap_.floatingLeg().Count - 1]; + Date fixingValueDate = iborIndex_.valueDate(lastFloating.fixingDate()); + Date endValueDate = iborIndex_.maturityDate(fixingValueDate); + latestDate_ = Date.Max(latestDate_, endValueDate); +#endif + + switch (pillarChoice_) { case Pillar.Choice.MaturityDate: pillarDate_ = maturityDate_; @@ -860,36 +860,36 @@ protected override void initializeDates() break; case Pillar.Choice.CustomDate: // pillarDate_ already assigned at construction time - Utils.QL_REQUIRE(pillarDate_ >= earliestDate_,()=> + Utils.QL_REQUIRE(pillarDate_ >= earliestDate_, () => "pillar date (" + pillarDate_ + ") must be later " + "than or equal to the instrument's earliest date (" + earliestDate_ + ")"); - Utils.QL_REQUIRE(pillarDate_ <= latestRelevantDate_,()=> - "pillar date (" + pillarDate_ + ") must be before "+ - "or equal to the instrument's latest relevant date (" + - latestRelevantDate_ + ")"); + Utils.QL_REQUIRE(pillarDate_ <= latestRelevantDate_, () => + "pillar date (" + pillarDate_ + ") must be before " + + "or equal to the instrument's latest relevant date (" + + latestRelevantDate_ + ")"); break; default: Utils.QL_FAIL("unknown Pillar::Choice(" + pillarChoice_ + ")"); break; } - latestDate_ = pillarDate_; // backward compatibility + latestDate_ = pillarDate_; // backward compatibility } - public override void setTermStructure( YieldTermStructure t ) + public override void setTermStructure(YieldTermStructure t) { // do not set the relinkable handle as an observer - // force recalculation when needed - termStructureHandle_.linkTo( t, false ); - base.setTermStructure( t ); - discountRelinkableHandle_.linkTo(discountHandle_.empty() ? t : discountHandle_,false); + termStructureHandle_.linkTo(t, false); + base.setTermStructure(t); + discountRelinkableHandle_.linkTo(discountHandle_.empty() ? t : discountHandle_, false); } public override double impliedQuote() { - Utils.QL_REQUIRE( termStructure_ != null,()=> "term structure not set" ); + Utils.QL_REQUIRE(termStructure_ != null, () => "term structure not set"); // we didn't register as observers - force calculation swap_.recalculate(); // it is from lazy objects // weak implementation... to be improved @@ -897,8 +897,8 @@ public override double impliedQuote() double floatingLegNPV = swap_.floatingLegNPV(); double spread = this.spread(); double spreadNPV = swap_.floatingLegBPS() / basisPoint * spread; - double totNPV = -( floatingLegNPV + spreadNPV ); - double result = totNPV / ( swap_.fixedLegBPS() / basisPoint ); + double totNPV = -(floatingLegNPV + spreadNPV); + double result = totNPV / (swap_.fixedLegBPS() / basisPoint); return result; } @@ -928,16 +928,16 @@ public override double impliedQuote() //! Rate helper for bootstrapping over BMA swap rates public class BMASwapRateHelper : RelativeDateRateHelper { - public BMASwapRateHelper( Handle liborFraction, - Period tenor, - int settlementDays, - Calendar calendar, - Period bmaPeriod, - BusinessDayConvention bmaConvention, - DayCounter bmaDayCount, - BMAIndex bmaIndex, - IborIndex iborIndex ) - : base( liborFraction ) + public BMASwapRateHelper(Handle liborFraction, + Period tenor, + int settlementDays, + Calendar calendar, + Period bmaPeriod, + BusinessDayConvention bmaConvention, + DayCounter bmaDayCount, + BMAIndex bmaIndex, + IborIndex iborIndex) + : base(liborFraction) { tenor_ = tenor; settlementDays_ = settlementDays; @@ -948,8 +948,8 @@ public BMASwapRateHelper( Handle liborFraction, bmaIndex_ = bmaIndex; iborIndex_ = iborIndex; - iborIndex_.registerWith( update ); - bmaIndex_.registerWith( update ); + iborIndex_.registerWith(update); + bmaIndex_.registerWith(update); initializeDates(); } @@ -957,27 +957,27 @@ public BMASwapRateHelper( Handle liborFraction, // RateHelper interface public override double impliedQuote() { - Utils.QL_REQUIRE( termStructure_ != null,()=> "term structure not set" ); + Utils.QL_REQUIRE(termStructure_ != null, () => "term structure not set"); // we didn't register as observers - force calculation swap_.recalculate(); return swap_.fairLiborFraction(); } - public override void setTermStructure( YieldTermStructure t ) + public override void setTermStructure(YieldTermStructure t) { // do not set the relinkable handle as an observer - // force recalculation when needed - termStructureHandle_.linkTo( t, false ); - base.setTermStructure( t ); + termStructureHandle_.linkTo(t, false); + base.setTermStructure(t); } protected override void initializeDates() { // if the evaluation date is not a business day // then move to the next business day - JointCalendar jc = new JointCalendar(calendar_,iborIndex_.fixingCalendar()); + JointCalendar jc = new JointCalendar(calendar_, iborIndex_.fixingCalendar()); Date referenceDate = jc.adjust(evaluationDate_); - earliestDate_ = calendar_.advance(referenceDate, new Period(settlementDays_ ,TimeUnit.Days), BusinessDayConvention.Following); + earliestDate_ = calendar_.advance(referenceDate, new Period(settlementDays_, TimeUnit.Days), BusinessDayConvention.Following); Date maturity = earliestDate_ + tenor_; @@ -985,30 +985,30 @@ protected override void initializeDates() BMAIndex clonedIndex = new BMAIndex(termStructureHandle_); Schedule bmaSchedule = new MakeSchedule().from(earliestDate_).to(maturity) - .withTenor(bmaPeriod_) - .withCalendar(bmaIndex_.fixingCalendar()) - .withConvention(bmaConvention_) - .backwards().value(); + .withTenor(bmaPeriod_) + .withCalendar(bmaIndex_.fixingCalendar()) + .withConvention(bmaConvention_) + .backwards().value(); Schedule liborSchedule = new MakeSchedule().from(earliestDate_).to(maturity) - .withTenor(iborIndex_.tenor()) - .withCalendar(iborIndex_.fixingCalendar()) - .withConvention(iborIndex_.businessDayConvention()) - .endOfMonth(iborIndex_.endOfMonth()) - .backwards().value(); + .withTenor(iborIndex_.tenor()) + .withCalendar(iborIndex_.fixingCalendar()) + .withConvention(iborIndex_.businessDayConvention()) + .endOfMonth(iborIndex_.endOfMonth()) + .backwards().value(); - swap_ = new BMASwap(BMASwap.Type.Payer, - 100.0, liborSchedule, 0.75, // arbitrary - 0.0, iborIndex_, iborIndex_.dayCounter(), bmaSchedule, clonedIndex, bmaDayCount_); + swap_ = new BMASwap(BMASwap.Type.Payer, + 100.0, liborSchedule, 0.75, // arbitrary + 0.0, iborIndex_, iborIndex_.dayCounter(), bmaSchedule, clonedIndex, bmaDayCount_); swap_.setPricingEngine(new DiscountingSwapEngine(iborIndex_.forwardingTermStructure())); Date d = calendar_.adjust(swap_.maturityDate(), BusinessDayConvention.Following); int w = d.weekday(); Date nextWednesday = (w >= 4) ? - d + new Period((11 - w) , TimeUnit.Days) : - d + new Period(( 4 - w ) , TimeUnit.Days); - latestDate_ = clonedIndex.valueDate( clonedIndex.fixingCalendar().adjust(nextWednesday)); + d + new Period((11 - w), TimeUnit.Days) : + d + new Period((4 - w), TimeUnit.Days); + latestDate_ = clonedIndex.valueDate(clonedIndex.fixingCalendar().adjust(nextWednesday)); } @@ -1029,20 +1029,20 @@ protected override void initializeDates() //! Rate helper for bootstrapping over Fx Swap rates /*! fwdFx = spotFx + fwdPoint isFxBaseCurrencyCollateralCurrency indicates if the base currency - of the fx currency pair is the one used as collateral + of the fx currency pair is the one used as collateral */ - public class FxSwapRateHelper : RelativeDateRateHelper + public class FxSwapRateHelper : RelativeDateRateHelper { - public FxSwapRateHelper( Handle fwdPoint, - Handle spotFx, - Period tenor, - int fixingDays, - Calendar calendar, - BusinessDayConvention convention, - bool endOfMonth, - bool isFxBaseCurrencyCollateralCurrency, - Handle coll) - :base(fwdPoint) + public FxSwapRateHelper(Handle fwdPoint, + Handle spotFx, + Period tenor, + int fixingDays, + Calendar calendar, + BusinessDayConvention convention, + bool endOfMonth, + bool isFxBaseCurrencyCollateralCurrency, + Handle coll) + : base(fwdPoint) { spot_ = spotFx; tenor_ = tenor; @@ -1061,10 +1061,10 @@ public FxSwapRateHelper( Handle fwdPoint, // RateHelper interface public override double impliedQuote() { - Utils.QL_REQUIRE(termStructure_ != null,()=> "term structure not set"); + Utils.QL_REQUIRE(termStructure_ != null, () => "term structure not set"); + + Utils.QL_REQUIRE(!collHandle_.empty(), () => "collateral term structure not set"); - Utils.QL_REQUIRE(!collHandle_.empty(),()=> "collateral term structure not set"); - double d1 = collHandle_.link.discount(earliestDate_); double d2 = collHandle_.link.discount(latestDate_); double collRatio = d1 / d2; @@ -1072,20 +1072,20 @@ public override double impliedQuote() d2 = termStructureHandle_.link.discount(latestDate_); double ratio = d1 / d2; double spot = spot_.link.value(); - if (isFxBaseCurrencyCollateralCurrency_) + if (isFxBaseCurrencyCollateralCurrency_) { - return (ratio/collRatio-1)*spot; + return (ratio / collRatio - 1) * spot; } - return (collRatio/ratio-1)*spot; + return (collRatio / ratio - 1) * spot; } public override void setTermStructure(YieldTermStructure t) { // do not set the relinkable handle as an observer - - // force recalculation when needed + // force recalculation when needed - termStructureHandle_.linkTo(t, false); - collRelinkableHandle_.linkTo(collHandle_, false); - base.setTermStructure(t); + termStructureHandle_.linkTo(t, false); + collRelinkableHandle_.linkTo(collHandle_, false); + base.setTermStructure(t); } @@ -1097,13 +1097,13 @@ public override void setTermStructure(YieldTermStructure t) public BusinessDayConvention businessDayConvention() { return conv_; } public bool endOfMonth() { return eom_; } public bool isFxBaseCurrencyCollateralCurrency() { return isFxBaseCurrencyCollateralCurrency_; } - + protected override void initializeDates() { // if the evaluation date is not a business day // then move to the next business day Date refDate = cal_.adjust(evaluationDate_); - earliestDate_ = cal_.advance(refDate, new Period (fixingDays_,TimeUnit.Days)); + earliestDate_ = cal_.advance(refDate, new Period(fixingDays_, TimeUnit.Days)); latestDate_ = cal_.advance(earliestDate_, tenor_, conv_, eom_); } private Handle spot_; diff --git a/src/QLNet/Termstructures/Yield/ZeroCurve.cs b/src/QLNet/Termstructures/Yield/ZeroCurve.cs index fa9208462..70b48bc5f 100644 --- a/src/QLNet/Termstructures/Yield/ZeroCurve.cs +++ b/src/QLNet/Termstructures/Yield/ZeroCurve.cs @@ -7,7 +7,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -23,7 +23,7 @@ under the terms of the QLNet license. You should have received a namespace QLNet { public class InterpolatedZeroCurve : ZeroYieldStructure, InterpolatedCurve - where Interpolator : class, IInterpolationFactory, new() + where Interpolator : class, IInterpolationFactory, new () { #region InterpolatedCurve @@ -32,10 +32,10 @@ public class InterpolatedZeroCurve : ZeroYieldStructure, Interpola public List dates_ { get; set; } public List dates() { return dates_; } - public Date maxDate_{ get; set; } + public Date maxDate_ { get; set; } public override Date maxDate() { - if ( maxDate_ != null ) + if (maxDate_ != null) return maxDate_; return dates_.Last(); @@ -140,7 +140,7 @@ public InterpolatedZeroCurve(List dates, DayCounter dayCounter, Interpolator interpolator, Compounding compounding = Compounding.Continuous, - Frequency frequency = Frequency.Annual, + Frequency frequency = Frequency.Annual, Date refDate = null) : base(refDate ?? dates[0], null, dayCounter) { @@ -148,21 +148,21 @@ public InterpolatedZeroCurve(List dates, dates_ = dates; data_ = yields; interpolator_ = interpolator; - initialize( compounding, frequency, refDate ); + initialize(compounding, frequency, refDate); } - protected void initialize( Compounding compounding, Frequency frequency, Date refDate = null ) + protected void initialize(Compounding compounding, Frequency frequency, Date refDate = null) { Utils.QL_REQUIRE(dates_.Count >= interpolator_.requiredPoints, () => "not enough input dates given"); Utils.QL_REQUIRE(data_.Count == dates_.Count, () => "dates/yields count mismatch"); times_ = new List(dates_.Count); double offset = 0.0; - if ( refDate != null ) + if (refDate != null) { offset = dayCounter().yearFraction(refDate, dates_[0]); } - times_.Add( offset ); + times_.Add(offset); if (compounding != Compounding.Continuous) { @@ -173,18 +173,18 @@ protected void initialize( Compounding compounding, Frequency frequency, Date re InterestRate r = new InterestRate(data_[0], dayCounter(), compounding, frequency); data_[0] = r.equivalentRate(Compounding.Continuous, Frequency.NoFrequency, dt).value(); #if !QL_NEGATIVE_RATES - Utils.QL_REQUIRE( data_[0] > 0.0, () => "non-positive yield" ); + Utils.QL_REQUIRE(data_[0] > 0.0, () => "non-positive yield"); #endif } for (int i = 1; i < dates_.Count; i++) { Utils.QL_REQUIRE(dates_[i] > dates_[i - 1], () => "invalid date (" + dates_[i] + ", vs " + dates_[i - 1] + ")"); - times_.Add( dayCounter().yearFraction( refDate ?? dates_[0], dates_[i] ) ); - - Utils.QL_REQUIRE( !Utils.close( times_[i], times_[i - 1] ), () => - "two dates correspond to the same time " + - "under this curve's day count convention"); + times_.Add(dayCounter().yearFraction(refDate ?? dates_[0], dates_[i])); + + Utils.QL_REQUIRE(!Utils.close(times_[i], times_[i - 1]), () => + "two dates correspond to the same time " + + "under this curve's day count convention"); // adjusting zero rates to match continuous compounding if (compounding != Compounding.Continuous) @@ -198,10 +198,10 @@ protected void initialize( Compounding compounding, Frequency frequency, Date re // positive yields are not enough to ensure non-negative fwd rates // so here's a stronger requirement Utils.QL_REQUIRE(data_[i] * times_[i] - data_[i - 1] * times_[i - 1] >= 0.0, - () => "negative forward rate implied by the zero yield " + data_[i] + " at " + dates_[i] + - " (t=" + times_[i] + ") after the zero yield " + - data_[i - 1] + " at " + dates_[i - 1] + - " (t=" + times_[i - 1] + ")"); + () => "negative forward rate implied by the zero yield " + data_[i] + " at " + dates_[i] + + " (t=" + times_[i] + ") after the zero yield " + + data_[i - 1] + " at " + dates_[i - 1] + + " (t=" + times_[i - 1] + ")"); #endif } diff --git a/src/QLNet/Termstructures/Yield/ZeroSpreadedTermStructure.cs b/src/QLNet/Termstructures/Yield/ZeroSpreadedTermStructure.cs index 6fc0ce682..0bfe8b185 100644 --- a/src/QLNet/Termstructures/Yield/ZeroSpreadedTermStructure.cs +++ b/src/QLNet/Termstructures/Yield/ZeroSpreadedTermStructure.cs @@ -1,23 +1,23 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet +namespace QLNet { //! Term structure with an added spread on the zero yield rate /*! \note This term structure will remain linked to the original @@ -32,7 +32,7 @@ checking them against numerical calculations. - observability against changes in the underlying term structure and in the added spread is checked. */ - public class ZeroSpreadedTermStructure : ZeroYieldStructure + public class ZeroSpreadedTermStructure : ZeroYieldStructure { public ZeroSpreadedTermStructure(Handle h, Handle spread, @@ -50,7 +50,7 @@ public ZeroSpreadedTermStructure(Handle h, spread_.registerWith(update); } - + #region YieldTermStructure interface public override DayCounter dayCounter() {return originalCurve_.link.dayCounter();} @@ -62,32 +62,32 @@ public ZeroSpreadedTermStructure(Handle h, #endregion - - //! returns the spreaded zero yield rate - protected override double zeroYieldImpl(double t) + + //! returns the spreaded zero yield rate + protected override double zeroYieldImpl(double t) { // to be fixed: user-defined daycounter should be used - InterestRate zeroRate = + InterestRate zeroRate = originalCurve_.link.zeroRate(t, comp_, freq_, true); - InterestRate spreadedRate = new InterestRate(zeroRate.value() + spread_.link.value(), - zeroRate.dayCounter(), - zeroRate.compounding(), - zeroRate.frequency()); - return spreadedRate.equivalentRate(Compounding.Continuous, Frequency.NoFrequency, t).value(); + InterestRate spreadedRate = new InterestRate(zeroRate.value() + spread_.link.value(), + zeroRate.dayCounter(), + zeroRate.compounding(), + zeroRate.frequency()); + return spreadedRate.equivalentRate(Compounding.Continuous, Frequency.NoFrequency, t).value(); } - //! returns the spreaded forward rate - /* This method must disappear should the spread become a curve */ - protected double forwardImpl(double t) + //! returns the spreaded forward rate + /* This method must disappear should the spread become a curve */ + protected double forwardImpl(double t) { return originalCurve_.link.forwardRate(t, t, comp_, freq_, true).value() - + spread_.link.value(); - } - - protected Handle originalCurve_; - protected Handle spread_; - protected Compounding comp_; - protected Frequency freq_; + + spread_.link.value(); + } + + protected Handle originalCurve_; + protected Handle spread_; + protected Compounding comp_; + protected Frequency freq_; protected DayCounter dc_; - } + } } diff --git a/src/QLNet/Termstructures/Yield/Zeroyieldstructure.cs b/src/QLNet/Termstructures/Yield/Zeroyieldstructure.cs index 5132a3b66..45d3dae71 100644 --- a/src/QLNet/Termstructures/Yield/Zeroyieldstructure.cs +++ b/src/QLNet/Termstructures/Yield/Zeroyieldstructure.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,7 +20,7 @@ under the terms of the QLNet license. You should have received a using System; using System.Collections.Generic; -namespace QLNet +namespace QLNet { //! Zero-yield term structure /*! This abstract class acts as an adapter to YieldTermStructure @@ -33,23 +33,23 @@ Zero rates are assumed to be annual continuous compounding. \ingroup yieldtermstructures */ - public abstract class ZeroYieldStructure : YieldTermStructure + public abstract class ZeroYieldStructure : YieldTermStructure { #region Constructors - protected ZeroYieldStructure(DayCounter dc = null,List> jumps = null, List jumpDates = null) + protected ZeroYieldStructure(DayCounter dc = null, List> jumps = null, List jumpDates = null) : base(dc, jumps, jumpDates) {} - protected ZeroYieldStructure(Date referenceDate,Calendar calendar = null,DayCounter dc = null, - List> jumps = null, List jumpDates = null) + protected ZeroYieldStructure(Date referenceDate, Calendar calendar = null, DayCounter dc = null, + List> jumps = null, List jumpDates = null) : base(referenceDate, calendar, dc, jumps, jumpDates) { } - protected ZeroYieldStructure(int settlementDays,Calendar calendar, DayCounter dc = null, - List> jumps = null, List jumpDates = null) + protected ZeroYieldStructure(int settlementDays, Calendar calendar, DayCounter dc = null, + List> jumps = null, List jumpDates = null) : base(settlementDays, calendar, dc, jumps, jumpDates) { } #endregion - + #region Calculations // This method must be implemented in derived classes to @@ -59,11 +59,11 @@ protected ZeroYieldStructure(int settlementDays,Calendar calendar, DayCounter dc //! zero-yield calculation protected abstract double zeroYieldImpl(double t); - + #endregion #region YieldTermStructure implementation - + /*! Returns the discount factor for the given date calculating it from the zero yield. */ @@ -73,7 +73,7 @@ protected override double discountImpl(double t) return 1.0; // zeroYieldImpl(0.0) would throw. double r = zeroYieldImpl(t); - return Math.Exp(-r*t); + return Math.Exp(-r * t); } #endregion diff --git a/src/QLNet/Termstructures/YieldTermStructure.cs b/src/QLNet/Termstructures/YieldTermStructure.cs index 57671eb0e..590a280ef 100644 --- a/src/QLNet/Termstructures/YieldTermStructure.cs +++ b/src/QLNet/Termstructures/YieldTermStructure.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -30,21 +30,21 @@ interest rate structures which will be derived from this one. \test observability against evaluation date changes is checked. */ - public abstract class YieldTermStructure : TermStructure + public abstract class YieldTermStructure : TermStructure { private const double dt = 0.0001; #region Constructors - protected YieldTermStructure(DayCounter dc = null,List > jumps = null,List jumpDates = null) - :base(dc) + protected YieldTermStructure(DayCounter dc = null, List > jumps = null, List jumpDates = null) + : base(dc) { - if ( jumps != null ) + if (jumps != null) jumps_ = jumps; else jumps_ = new List>(); - if ( jumpDates != null ) + if (jumpDates != null) jumpDates_ = jumpDates; else jumpDates_ = new List(); @@ -52,20 +52,20 @@ protected YieldTermStructure(DayCounter dc = null,List > jumps = n jumpTimes_ = new List(jumpDates_.Count); nJumps_ = jumps_.Count; setJumps(); - for (int i=0; i > jumps = null,List jumpDates = null) - :base(referenceDate, cal, dc) + protected YieldTermStructure(Date referenceDate, Calendar cal = null, DayCounter dc = null, + List > jumps = null, List jumpDates = null) + : base(referenceDate, cal, dc) { - if ( jumps != null ) + if (jumps != null) jumps_ = jumps; else jumps_ = new List>(); - if ( jumpDates != null ) + if (jumpDates != null) jumpDates_ = jumpDates; else jumpDates_ = new List(); @@ -73,20 +73,20 @@ protected YieldTermStructure(Date referenceDate,Calendar cal = null,DayCounter d jumpTimes_ = new List(jumpDates_.Count); nJumps_ = jumps_.Count; setJumps(); - for (int i=0; i > jumps = null,List jumpDates = null) + protected YieldTermStructure(int settlementDays, Calendar cal, DayCounter dc = null, + List > jumps = null, List jumpDates = null) : base(settlementDays, cal, dc) { - if ( jumps != null ) + if (jumps != null) jumps_ = jumps; else jumps_ = new List>(); - if ( jumpDates != null ) + if (jumpDates != null) jumpDates_ = jumpDates; else jumpDates_ = new List(); @@ -94,7 +94,7 @@ protected YieldTermStructure(int settlementDays,Calendar cal,DayCounter dc = nul jumpTimes_ = new List(jumpDates_.Count); nJumps_ = jumps_.Count; setJumps(); - for (int i=0; i0 && jumpTimes_[i] 0 && jumpTimes_[i] < t) { - Utils.QL_REQUIRE( jumps_[i].link.isValid(), () => "invalid " + ( i + 1 ) + " jump quote" ); + Utils.QL_REQUIRE(jumps_[i].link.isValid(), () => "invalid " + (i + 1) + " jump quote"); double thisJump = jumps_[i].link.value(); - Utils.QL_REQUIRE(thisJump > 0.0,()=> "invalid " + (i+1) + " jump value: " + thisJump); - #if !QL_NEGATIVE_RATES - Utils.QL_REQUIRE(thisJump <= 1.0,()=> "invalid " + (i+1) + " jump value: " + thisJump); - #endif + Utils.QL_REQUIRE(thisJump > 0.0, () => "invalid " + (i + 1) + " jump value: " + thisJump); +#if !QL_NEGATIVE_RATES + Utils.QL_REQUIRE(thisJump <= 1.0, () => "invalid " + (i + 1) + " jump value: " + thisJump); +#endif jumpEffect *= thisJump; } } return jumpEffect * discountImpl(t); } - + #endregion #region Zero-yield rates @@ -149,17 +149,17 @@ public double discount(double t, bool extrapolate = false) /*! The resulting interest rate has the required daycounting rule. */ - public InterestRate zeroRate(Date d,DayCounter dayCounter,Compounding comp,Frequency freq = Frequency.Annual, + public InterestRate zeroRate(Date d, DayCounter dayCounter, Compounding comp, Frequency freq = Frequency.Annual, bool extrapolate = false) { - if (d==referenceDate()) + if (d == referenceDate()) { - double compound = 1.0/discount(dt, extrapolate); + double compound = 1.0 / discount(dt, extrapolate); // t has been calculated with a possibly different daycounter // but the difference should not matter for very small times return InterestRate. impliedRate(compound, dayCounter, comp, freq, dt); } - double compound1 = 1.0/discount(d, extrapolate); + double compound1 = 1.0 / discount(d, extrapolate); return InterestRate.impliedRate(compound1, dayCounter, comp, freq, referenceDate(), d); } @@ -167,11 +167,12 @@ public InterestRate zeroRate(Date d,DayCounter dayCounter,Compounding comp,Frequ used by the term structure. The same rule should be used for calculating the passed time t. */ - public InterestRate zeroRate(double t, Compounding comp,Frequency freq = Frequency.Annual,bool extrapolate = false) + public InterestRate zeroRate(double t, Compounding comp, Frequency freq = Frequency.Annual, bool extrapolate = false) { - if (t.IsEqual(0.0)) t = dt; - double compound = 1.0/discount(t, extrapolate); - return InterestRate.impliedRate(compound,dayCounter(), comp, freq, t); + if (t.IsEqual(0.0)) + t = dt; + double compound = 1.0 / discount(t, extrapolate); + return InterestRate.impliedRate(compound, dayCounter(), comp, freq, t); } #endregion @@ -189,20 +190,20 @@ public InterestRate zeroRate(double t, Compounding comp,Frequency freq = Frequen rule. */ public InterestRate forwardRate(Date d1, Date d2, DayCounter dayCounter, Compounding comp, - Frequency freq = Frequency.Annual,bool extrapolate = false) + Frequency freq = Frequency.Annual, bool extrapolate = false) { - if (d1==d2) + if (d1 == d2) { checkRange(d1, extrapolate); - double t1 = Math.Max(timeFromReference(d1) - dt/2.0, 0.0); + double t1 = Math.Max(timeFromReference(d1) - dt / 2.0, 0.0); double t2 = t1 + dt; - double compound = discount(t1, true)/discount(t2, true); + double compound = discount(t1, true) / discount(t2, true); // times have been calculated with a possibly different daycounter // but the difference should not matter for very small times return InterestRate.impliedRate(compound, dayCounter, comp, freq, dt); } - Utils.QL_REQUIRE( d1 < d2, () => d1 + " later than " + d2 ); - double compound1 = discount(d1, extrapolate)/discount(d2, extrapolate); + Utils.QL_REQUIRE(d1 < d2, () => d1 + " later than " + d2); + double compound1 = discount(d1, extrapolate) / discount(d2, extrapolate); return InterestRate.impliedRate(compound1, dayCounter, comp, freq, d1, d2); } @@ -210,40 +211,40 @@ public InterestRate forwardRate(Date d1, Date d2, DayCounter dayCounter, Compoun rule. \warning dates are not adjusted for holidays */ - public InterestRate forwardRate(Date d,Period p,DayCounter dayCounter,Compounding comp, - Frequency freq = Frequency.Annual, bool extrapolate = false) + public InterestRate forwardRate(Date d, Period p, DayCounter dayCounter, Compounding comp, + Frequency freq = Frequency.Annual, bool extrapolate = false) { - return forwardRate(d, d+p, dayCounter, comp, freq, extrapolate); + return forwardRate(d, d + p, dayCounter, comp, freq, extrapolate); } /*! The resulting interest rate has the same day-counting rule used by the term structure. The same rule should be used for calculating the passed times t1 and t2. */ - public InterestRate forwardRate(double t1, double t2, Compounding comp, Frequency freq = Frequency.Annual, - bool extrapolate = false) + public InterestRate forwardRate(double t1, double t2, Compounding comp, Frequency freq = Frequency.Annual, + bool extrapolate = false) { double compound; - if (t2.IsEqual(t1)) + if (t2.IsEqual(t1)) { checkRange(t1, extrapolate); - t1 = Math.Max(t1 - dt/2.0, 0.0); + t1 = Math.Max(t1 - dt / 2.0, 0.0); t2 = t1 + dt; - compound = discount(t1, true)/discount(t2, true); - } - else + compound = discount(t1, true) / discount(t2, true); + } + else { - Utils.QL_REQUIRE( t2 > t1, () => "t2 (" + t2 + ") < t1 (" + t2 + ")" ); - compound = discount(t1, extrapolate)/discount(t2, extrapolate); + Utils.QL_REQUIRE(t2 > t1, () => "t2 (" + t2 + ") < t1 (" + t2 + ")"); + compound = discount(t1, extrapolate) / discount(t2, extrapolate); } - return InterestRate.impliedRate(compound, dayCounter(), comp, freq, t2-t1); + return InterestRate.impliedRate(compound, dayCounter(), comp, freq, t2 - t1); } #endregion #region Jump inspectors - public List jumpDates() + public List jumpDates() { return this.jumpDates_; } @@ -255,7 +256,7 @@ public List jumpTimes() #endregion #region Observer interface - + public override void update() { base.update(); @@ -274,40 +275,40 @@ public override void update() //! discount factor calculation protected abstract double discountImpl(double d); - + #endregion - + // methods private void setJumps() { - if (jumpDates_.empty() && !jumps_.empty()) - { + if (jumpDates_.empty() && !jumps_.empty()) + { // turn of year dates jumpDates_.Clear(); jumpTimes_.Clear(); int y = referenceDate().year(); - for (int i=0; i - "mismatch between number of jumps (" + nJumps_ + - ") and jump dates (" + jumpDates_.Count + ")"); - } - for (int i=0; i + "mismatch between number of jumps (" + nJumps_ + + ") and jump dates (" + jumpDates_.Count + ")"); + } + for (int i = 0; i < nJumps_; ++i) jumpTimes_.Add(timeFromReference(jumpDates_[i])); - + latestReference_ = base.referenceDate(); } - + // data members private List > jumps_; private List jumpDates_; private List jumpTimes_; private int nJumps_; private Date latestReference_; - } + } } diff --git a/src/QLNet/Termstructures/interpolatedcurve.cs b/src/QLNet/Termstructures/interpolatedcurve.cs deleted file mode 100644 index 70f7ccb21..000000000 --- a/src/QLNet/Termstructures/interpolatedcurve.cs +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (C) 2009 Siarhei Novik (snovik@gmail.com) - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet { - //! Helper class to build interpolated term structures - /*! Interpolated term structures can use protected or private - inheritance from this class to obtain the relevant data - members and implement correct copy behavior. - */ - public interface InterpolatedCurve : ICloneable { - List times_ { get; set; } - List times(); - - List dates_ { get; set; } - List dates(); - Date maxDate(); - - List data_ { get; set; } - List data(); - - Dictionary nodes(); - - Interpolation interpolation_ { get; set; } - IInterpolationFactory interpolator_ { get; set; } - void setupInterpolation(); - // Usually, the maximum date is the one corresponding to the - // last node. However, it might happen that a bit of - // extrapolation is used by construction; for instance, when a - // curve is bootstrapped and the last relevant date for an - // instrument is after the corresponding pillar. - // We provide here a slot to store this information, so that - // it's available to all derived classes (we should have - // probably done the same with the dates_ vector, but moving - // it here might not be entirely backwards-compatible). - Date maxDate_{ get; set; } - - } -} diff --git a/src/QLNet/Termstructures/localbootstrap.cs b/src/QLNet/Termstructures/localbootstrap.cs deleted file mode 100644 index 7347c9f40..000000000 --- a/src/QLNet/Termstructures/localbootstrap.cs +++ /dev/null @@ -1,207 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - Copyright (C) 2014 Edem Dawui (edawui@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace QLNet -{ - public class LocalBootstrapForYield : LocalBootstrap - {} - - // penalty function class for solving using a multi-dimensional solver - public class PenaltyFunction : CostFunction - where T : Curve, new() - where U : TermStructure - { - private T curve_; - private int initialIndex_; - private int localisation_, start_, end_; - private List> rateHelpers_; - - public PenaltyFunction( T curve, int initialIndex, List> rateHelpers, int start, int end ) - { - curve_ = curve; - initialIndex_ = initialIndex; - rateHelpers_ = rateHelpers; - start_ = start; - end_ = end; - localisation_ = end - start; - } - - public override double value(Vector x) { - x.ForEach((j, v) => curve_.updateGuess(curve_.data_, v, j + initialIndex_)); - - curve_.interpolation_.update(); - - double penalty = rateHelpers_.GetRange(start_, localisation_) - .Aggregate(0.0, (acc, v) => Math.Abs(v.quoteError())); - return penalty; - } - - public override Vector values(Vector x) { - x.ForEach((j, v) => curve_.updateGuess(curve_.data_, v, j + initialIndex_)); - - curve_.interpolation_.update(); - - var penalties = rateHelpers_.GetRange(start_, localisation_).Select(c => Math.Abs(c.quoteError())).ToList(); - return new Vector(penalties); - } - } - - - //! Localised-term-structure bootstrapper for most curve types. - /*! This algorithm enables a localised fitting for non-local - interpolation methods. - - As in the similar class (IterativeBootstrap) the input term - structure is solved on a number of market instruments which - are passed as a vector of handles to BootstrapHelper - instances. Their maturities mark the boundaries of the - interpolated segments. - - Unlike the IterativeBootstrap class, the solution for each - interpolated segment is derived using a local - approximation. This restricts the risk profile s.t. the risk - is localised. Therefore, we obtain a local IR risk profile - whilst using a smoother interpolation method. Particularly - good for the convex-monotone spline method. - */ - public class LocalBootstrap :IBootStrap - where T : Curve, new() - where U : TermStructure - { - private bool validCurve_; - private T ts_; // yes, it is a workaround - int localisation_; - bool forcePositive_; - - public LocalBootstrap() : this(2, true) { } - public LocalBootstrap(int localisation, bool forcePositive) { - localisation_ = localisation; - forcePositive_ = forcePositive; - } - - public void setup(T ts) { - ts_ = ts; - - int n = ts_.instruments_.Count; - Utils.QL_REQUIRE(n >= ts_.interpolator_.requiredPoints,()=> - "not enough instruments: " + n + " provided, " + (ts_.interpolator_.requiredPoints) + " required"); - - Utils.QL_REQUIRE(n > localisation_,()=> - "not enough instruments: " + n + " provided, " + localisation_ + " required."); - - ts_.instruments_.ForEach((i, x) => ts_.registerWith( x ) ); - } - - public void calculate() { - - validCurve_ = false; - int nInsts = ts_.instruments_.Count, i; - - // ensure rate helpers are sorted - ts_.instruments_.Sort((x, y) => x.latestDate().CompareTo(y.latestDate())); - - // check that there is no instruments with the same maturity - for (i = 1; i < nInsts; ++i) { - Date m1 = ts_.instruments_[i - 1].latestDate(), - m2 = ts_.instruments_[i].latestDate(); - Utils.QL_REQUIRE(m1 != m2,()=> "two instruments have the same maturity (" + m1 + ")"); - } - - // check that there is no instruments with invalid quote - Utils.QL_REQUIRE((i = ts_.instruments_.FindIndex(x => !x.quoteIsValid())) == -1,()=> - "instrument " + i + " (maturity: " + ts_.instruments_[i].latestDate() + ") has an invalid quote"); - - // setup instruments and register with them - ts_.instruments_.ForEach((x, j) => ts_.setTermStructure( j ) ); - - // set initial guess only if the current curve cannot be used as guess - if (validCurve_) { - Utils.QL_REQUIRE(ts_.data_.Count == nInsts + 1,()=> - "dimension mismatch: expected " + nInsts + 1 + ", actual " + ts_.data_.Count); - } else { - ts_.data_ = new InitializedList(nInsts + 1); - ts_.data_[0] = ts_.initialValue(); - } - - // calculate dates and times - ts_.dates_ = new InitializedList(nInsts + 1); - ts_.times_ = new InitializedList(nInsts + 1); - ts_.dates_[0] = ts_.initialDate(); - ts_.times_[0] = ts_.timeFromReference(ts_.dates_[0]); - for (i = 0; i < nInsts; ++i) { - ts_.dates_[i + 1] = ts_.instruments_[i].latestDate(); - ts_.times_[i + 1] = ts_.timeFromReference(ts_.dates_[i + 1]); - if (!validCurve_) - ts_.data_[i+1] = ts_.data_[i]; - } - - LevenbergMarquardt solver = new LevenbergMarquardt(ts_.accuracy_, ts_.accuracy_, ts_.accuracy_); - EndCriteria endCriteria = new EndCriteria(100, 10, 0.00, ts_.accuracy_, 0.00); - PositiveConstraint posConstraint = new PositiveConstraint(); - NoConstraint noConstraint = new NoConstraint(); - Constraint solverConstraint = forcePositive_ ? (Constraint)posConstraint : (Constraint)noConstraint; - - // now start the bootstrapping. - int iInst = localisation_ - 1; - - int dataAdjust = (ts_.interpolator_ as ConvexMonotone).dataSizeAdjustment; - - do { - int initialDataPt = iInst+1-localisation_+dataAdjust; - Vector startArray = new Vector(localisation_+1-dataAdjust); - for (int j = 0; j < startArray.size()-1; ++j) - startArray[j] = ts_.data_[initialDataPt+j]; - - // here we are extending the interpolation a point at a - // time... but the local interpolator can make an - // approximation for the final localisation period. - // e.g. if the localisation is 2, then the first section - // of the curve will be solved using the first 2 - // instruments... with the local interpolator making - // suitable boundary conditions. - ts_.interpolation_ = (ts_.interpolator_ as ConvexMonotone).localInterpolate(ts_.times_, iInst + 2, ts_.data_, - localisation_, ts_.interpolation_ as ConvexMonotoneInterpolation, nInsts + 1); - - if (iInst >= localisation_) { - startArray[localisation_ - dataAdjust] = ts_.guess( iInst, ts_, false, 0 ); - } else { - startArray[localisation_-dataAdjust] = ts_.data_[0]; - } - - var currentCost = new PenaltyFunction( ts_, initialDataPt, ts_.instruments_, - iInst - localisation_ + 1, iInst + 1 ); - Problem toSolve = new Problem( currentCost, solverConstraint, startArray ); - EndCriteria.Type endType = solver.minimize(toSolve, endCriteria); - - // check the end criteria - Utils.QL_REQUIRE(endType == EndCriteria.Type.StationaryFunctionAccuracy || - endType == EndCriteria.Type.StationaryFunctionValue,()=> - "Unable to strip yieldcurve to required accuracy "); - ++iInst; - } while (iInst < nInsts); - - validCurve_ = true; - } - } -} diff --git a/src/QLNet/Time/ASX.cs b/src/QLNet/Time/ASX.cs index d22f505c1..f16c169d6 100644 --- a/src/QLNet/Time/ASX.cs +++ b/src/QLNet/Time/ASX.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2016 Andrea Maggiulli - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -30,21 +30,22 @@ enum Months J = 4, K = 5, M = 6, N = 7, Q = 8, U = 9, V = 10, X = 11, Z = 12 - }; + } //! returns whether or not the given date is an ASX date - public static bool isASXdate( Date date, bool mainCycle = true ) + public static bool isASXdate(Date date, bool mainCycle = true) { - if ( date.weekday() != (int)DayOfWeek.Friday+1 ) + if (date.weekday() != (int)DayOfWeek.Friday + 1) return false; int d = date.Day; - if ( d < 8 || d > 14 ) + if (d < 8 || d > 14) return false; - if ( !mainCycle ) return true; + if (!mainCycle) + return true; - switch ( (Month)date.month() ) + switch ((Month)date.month()) { case Month.March: case Month.June: @@ -57,21 +58,21 @@ public static bool isASXdate( Date date, bool mainCycle = true ) } //! returns whether or not the given string is an ASX code - public static bool isASXcode( String inString, bool mainCycle = true ) + public static bool isASXcode(String inString, bool mainCycle = true) { if (inString.Length != 2) return false; string str1 = "0123456789"; - bool loc = str1.Contains(inString.Substring(1,1)); - if (!loc ) + bool loc = str1.Contains(inString.Substring(1, 1)); + if (!loc) return false; - if (mainCycle) + if (mainCycle) str1 = "hmzuHMZU"; - else + else str1 = "fghjkmnquvxzFGHJKMNQUVXZ"; - loc = str1.Contains(inString.Substring(0,1)); + loc = str1.Contains(inString.Substring(0, 1)); if (!loc) return false; @@ -81,14 +82,14 @@ public static bool isASXcode( String inString, bool mainCycle = true ) /*! returns the ASX code for the given date (e.g. M5 for June 12th, 2015). */ - public static String code( Date date ) + public static String code(Date date) { - - Utils.QL_REQUIRE(isASXdate(date, false),()=> date + " is not an ASX date"); + + Utils.QL_REQUIRE(isASXdate(date, false), () => date + " is not an ASX date"); String ASXcode = String.Empty; String y = (date.year() % 10).ToString(); - switch((Month)date.month()) + switch ((Month)date.month()) { case Month.January: ASXcode = 'F' + y; @@ -140,41 +141,55 @@ public static String code( Date date ) \warning It raises an exception if the input string is not an ASX code */ - public static Date date( String asxCode, Date refDate = null ) + public static Date date(String asxCode, Date refDate = null) { - Utils.QL_REQUIRE(isASXcode(asxCode, false),()=> - asxCode + " is not a valid ASX code"); + Utils.QL_REQUIRE(isASXcode(asxCode, false), () => + asxCode + " is not a valid ASX code"); Date referenceDate = refDate ?? Settings.evaluationDate(); String code = asxCode.ToUpper(); - String ms = code.Substring(0,1); + String ms = code.Substring(0, 1); Month m = 0; - if (ms=="F") m = Month.January; - else if (ms=="G") m = Month.February; - else if (ms=="H") m = Month.March; - else if (ms=="J") m = Month.April; - else if (ms=="K") m = Month.May; - else if (ms=="M") m = Month.June; - else if (ms=="N") m = Month.July; - else if (ms=="Q") m = Month.August; - else if (ms=="U") m = Month.September; - else if (ms=="V") m = Month.October; - else if (ms=="X") m = Month.November; - else if (ms=="Z") m = Month.December; - else Utils.QL_FAIL("invalid ASX month letter"); + if (ms == "F") + m = Month.January; + else if (ms == "G") + m = Month.February; + else if (ms == "H") + m = Month.March; + else if (ms == "J") + m = Month.April; + else if (ms == "K") + m = Month.May; + else if (ms == "M") + m = Month.June; + else if (ms == "N") + m = Month.July; + else if (ms == "Q") + m = Month.August; + else if (ms == "U") + m = Month.September; + else if (ms == "V") + m = Month.October; + else if (ms == "X") + m = Month.November; + else if (ms == "Z") + m = Month.December; + else + Utils.QL_FAIL("invalid ASX month letter"); // Year y = boost::lexical_cast(); // lexical_cast causes compilation errors with x64 - int y= int.Parse(code.Substring(1,1)); + int y = int.Parse(code.Substring(1, 1)); /* year<1900 are not valid QuantLib years: to avoid a run-time exception few lines below we need to add 10 years right away */ - if (y==0 && referenceDate.year()<=1909) y+=10; + if (y == 0 && referenceDate.year() <= 1909) + y += 10; int referenceYear = (referenceDate.year() % 10); y += referenceDate.year() - referenceYear; Date result = ASX.nextDate(new Date(1, m, y), false); - if (result 14) + int skipMonths = offset - (m % offset); + if (skipMonths != offset || refDate.Day > 14) { skipMonths += m; - if (skipMonths<=12) + if (skipMonths <= 12) { - m = skipMonths; - } - else + m = skipMonths; + } + else { - m = (skipMonths-12); - y += 1; + m = (skipMonths - 12); + y += 1; } } Date result = Date.nthWeekday(2, DayOfWeek.Friday, m, y); - if (result<=refDate) - result = nextDate(new Date(15, m, y), mainCycle); + if (result <= refDate) + result = nextDate(new Date(15, m, y), mainCycle); return result; } @@ -216,30 +231,30 @@ public static Date nextDate( Date date = null, bool mainCycle = true ) /*! returns the 1st delivery date for next contract listed in the Australian Securities Exchange */ - public static Date nextDate( String ASXcode, bool mainCycle = true, Date referenceDate = null ) + public static Date nextDate(String ASXcode, bool mainCycle = true, Date referenceDate = null) { - Date asxDate = date( ASXcode, referenceDate ); - return nextDate( asxDate + 1, mainCycle ); + Date asxDate = date(ASXcode, referenceDate); + return nextDate(asxDate + 1, mainCycle); } //! next ASX code following the given date /*! returns the ASX code for next contract listed in the Australian Securities Exchange */ - public static String nextCode( Date d = null, bool mainCycle = true ) + public static String nextCode(Date d = null, bool mainCycle = true) { - Date date = nextDate( d, mainCycle ); - return code( date ); + Date date = nextDate(d, mainCycle); + return code(date); } //! next ASX code following the given code /*! returns the ASX code for next contract listed in the Australian Securities Exchange */ - public static String nextCode( String asxCode, bool mainCycle = true, Date referenceDate = null ) + public static String nextCode(String asxCode, bool mainCycle = true, Date referenceDate = null) { - Date date = nextDate( asxCode, mainCycle, referenceDate ); - return code( date ); + Date date = nextDate(asxCode, mainCycle, referenceDate); + return code(date); } } } diff --git a/src/QLNet/Time/Calendar.cs b/src/QLNet/Time/Calendar.cs index 4923f55b6..920bc760c 100644 --- a/src/QLNet/Time/Calendar.cs +++ b/src/QLNet/Time/Calendar.cs @@ -1,19 +1,19 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - Copyright (C) 2008 Andrea Maggiulli + Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,50 +24,56 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - /*! - \ingroup datetime - \test the methods for adding and removing holidays are tested - by inspecting the calendar before and after their - invocation. - */ + /*! + \ingroup datetime + \test the methods for adding and removing holidays are tested + by inspecting the calendar before and after their + invocation. + */ - /// - /// This class provides methods for determining whether a date is a - /// business day or a holiday for a given market, and for - /// incrementing/decrementing a date of a given number of business days. - /// - /// A calendar should be defined for specific exchange holiday schedule - /// or for general country holiday schedule. Legacy city holiday schedule - /// calendars will be moved to the exchange/country convention. - /// - public class Calendar - { - protected Calendar calendar_; - public List addedHolidays { get; set; } - public List removedHolidays { get; set; } + /// + /// This class provides methods for determining whether a date is a + /// business day or a holiday for a given market, and for + /// incrementing/decrementing a date of a given number of business days. + /// + /// A calendar should be defined for specific exchange holiday schedule + /// or for general country holiday schedule. Legacy city holiday schedule + /// calendars will be moved to the exchange/country convention. + /// + public class Calendar + { + protected Calendar calendar_; + public List addedHolidays { get; set; } + public List removedHolidays { get; set; } - public Calendar calendar - { - get { return calendar_; } - set { calendar_ = value; } - } + public Calendar calendar + { + get + { + return calendar_; + } + set + { + calendar_ = value; + } + } - // constructors - /*! The default constructor returns a calendar with a null - implementation, which is therefore unusable except as a - placeholder. */ - public Calendar() - { - addedHolidays = new List(); - removedHolidays = new List(); - } + // constructors + /*! The default constructor returns a calendar with a null + implementation, which is therefore unusable except as a + placeholder. */ + public Calendar() + { + addedHolidays = new List(); + removedHolidays = new List(); + } - public Calendar(Calendar c) - { - calendar_ = c; - addedHolidays = new List(); - removedHolidays = new List(); - } + public Calendar(Calendar c) + { + calendar_ = c; + addedHolidays = new List(); + removedHolidays = new List(); + } // Wrappers for interface // @@ -79,364 +85,377 @@ public Calendar(Calendar c) // The name of the calendar. // public virtual string name() { return calendar.name(); } - // Date - // Returns true iff the date is a business day for the - // given market. - public virtual bool isBusinessDay(Date d) { - if (calendar.addedHolidays.Contains(d)) - return false; - if (calendar.removedHolidays.Contains(d)) - return true; - return calendar.isBusinessDay(d); - } - // - // Returns true iff the weekday is part of the - // weekend for the given market. - // - public virtual bool isWeekend(DayOfWeek w) { return calendar.isWeekend(w); } + // Date + // Returns true iff the date is a business day for the + // given market. + public virtual bool isBusinessDay(Date d) + { + if (calendar.addedHolidays.Contains(d)) + return false; + if (calendar.removedHolidays.Contains(d)) + return true; + return calendar.isBusinessDay(d); + } + // + // Returns true iff the weekday is part of the + // weekend for the given market. + // + public virtual bool isWeekend(DayOfWeek w) { return calendar.isWeekend(w); } - // other functions - // - // Returns whether or not the calendar is initialized - // - public bool empty() { return (object)calendar == null; } //! Returns whether or not the calendar is initialized - /// - /// Returns true iff the date is a holiday for the given - /// market. - /// - public bool isHoliday(Date d) { return !isBusinessDay(d); } - /// - /// Returns true iff the date is last business day for the - /// month in given market. - /// - public bool isEndOfMonth(Date d) { return (d.Month != adjust(d + 1).Month); } - /// - /// last business day of the month to which the given date belongs - /// - public Date endOfMonth(Date d) { return adjust(Date.endOfMonth(d), BusinessDayConvention.Preceding); } + // other functions + // + // Returns whether or not the calendar is initialized + // + public bool empty() { return (object)calendar == null; } //! Returns whether or not the calendar is initialized + /// + /// Returns true iff the date is a holiday for the given + /// market. + /// + public bool isHoliday(Date d) { return !isBusinessDay(d); } + /// + /// Returns true iff the date is last business day for the + /// month in given market. + /// + public bool isEndOfMonth(Date d) { return (d.Month != adjust(d + 1).Month); } + /// + /// last business day of the month to which the given date belongs + /// + public Date endOfMonth(Date d) { return adjust(Date.endOfMonth(d), BusinessDayConvention.Preceding); } - /// - /// Adjusts a non-business day to the appropriate near business day with respect - /// to the given convention. - /// - public Date adjust( Date d, BusinessDayConvention c = BusinessDayConvention.Following ) - { - if (d == null) throw new ArgumentException("null date"); - if (c == BusinessDayConvention.Unadjusted) return d; + /// + /// Adjusts a non-business day to the appropriate near business day with respect + /// to the given convention. + /// + public Date adjust(Date d, BusinessDayConvention c = BusinessDayConvention.Following) + { + if (d == null) + throw new ArgumentException("null date"); + if (c == BusinessDayConvention.Unadjusted) + return d; - Date d1 = d; - if (c == BusinessDayConvention.Following || c == BusinessDayConvention.ModifiedFollowing || - c == BusinessDayConvention.HalfMonthModifiedFollowing) + Date d1 = d; + if (c == BusinessDayConvention.Following || c == BusinessDayConvention.ModifiedFollowing || + c == BusinessDayConvention.HalfMonthModifiedFollowing) + { + while (isHoliday(d1)) + d1++; + if (c == BusinessDayConvention.ModifiedFollowing || c == BusinessDayConvention.HalfMonthModifiedFollowing) { - while (isHoliday(d1)) d1++; - if ( c == BusinessDayConvention.ModifiedFollowing || c == BusinessDayConvention.HalfMonthModifiedFollowing ) - { - if (d1.Month != d.Month) - return adjust(d, BusinessDayConvention.Preceding); - if ( c == BusinessDayConvention.HalfMonthModifiedFollowing ) - { - if ( d.Day <= 15 && d1.Day > 15 ) - { - return adjust( d, BusinessDayConvention.Preceding ); - } - } - } + if (d1.Month != d.Month) + return adjust(d, BusinessDayConvention.Preceding); + if (c == BusinessDayConvention.HalfMonthModifiedFollowing) + { + if (d.Day <= 15 && d1.Day > 15) + { + return adjust(d, BusinessDayConvention.Preceding); + } + } } - else if (c == BusinessDayConvention.Preceding || c == BusinessDayConvention.ModifiedPreceding) + } + else if (c == BusinessDayConvention.Preceding || c == BusinessDayConvention.ModifiedPreceding) + { + while (isHoliday(d1)) + d1--; + if (c == BusinessDayConvention.ModifiedPreceding && d1.Month != d.Month) + return adjust(d, BusinessDayConvention.Following); + } + else if (c == BusinessDayConvention.Nearest) + { + Date d2 = d; + while (isHoliday(d1) && isHoliday(d2)) { - while (isHoliday(d1)) - d1--; - if (c == BusinessDayConvention.ModifiedPreceding && d1.Month != d.Month) - return adjust(d, BusinessDayConvention.Following); + d1++; + d2--; } - else if ( c == BusinessDayConvention.Nearest ) + if (isHoliday(d1)) + return d2; + else + return d1; + } + else + Utils.QL_FAIL("unknown business-day convention"); + return d1; + } + + /// + /// Advances the given date of the given number of business days and + /// returns the result. + /// + /// The input date is not modified + public Date advance(Date d, int n, TimeUnit unit, BusinessDayConvention c = BusinessDayConvention.Following, bool endOfMonth = false) + { + if (d == null) + throw new ArgumentException("null date"); + if (n == 0) + return adjust(d, c); + else if (unit == TimeUnit.Days) + { + Date d1 = d; + if (n > 0) { - Date d2 = d; - while ( isHoliday( d1 ) && isHoliday( d2 ) ) + while (n > 0) { d1++; - d2--; + while (isHoliday(d1)) + d1++; + n--; } - if ( isHoliday( d1 ) ) - return d2; - else - return d1; } - else Utils.QL_FAIL("unknown business-day convention"); - return d1; - } - - /// - /// Advances the given date of the given number of business days and - /// returns the result. - /// - /// The input date is not modified - public Date advance( Date d, int n, TimeUnit unit, BusinessDayConvention c = BusinessDayConvention.Following, bool endOfMonth = false ) - { - if (d == null) throw new ArgumentException("null date"); - if (n == 0) - return adjust(d, c); - else if (unit == TimeUnit.Days) + else { - Date d1 = d; - if (n > 0) - { - while (n > 0) - { - d1++; - while (isHoliday(d1)) - d1++; - n--; - } - } - else - { - while (n < 0) - { - d1--; - while (isHoliday(d1)) - d1--; - n++; - } - } - return d1; + while (n < 0) + { + d1--; + while (isHoliday(d1)) + d1--; + n++; + } } - else if (unit == TimeUnit.Weeks) + return d1; + } + else if (unit == TimeUnit.Weeks) + { + Date d1 = d + new Period(n, unit); + return adjust(d1, c); + } + else + { + Date d1 = d + new Period(n, unit); + if (endOfMonth && (unit == TimeUnit.Months || unit == TimeUnit.Years) && isEndOfMonth(d)) + return this.endOfMonth(d1); + return adjust(d1, c); + } + } + /// + /// Advances the given date as specified by the given period and + /// returns the result. + /// + /// The input date is not modified. + public Date advance(Date d, Period p, BusinessDayConvention c = BusinessDayConvention.Following, bool endOfMonth = false) + { + return advance(d, p.length(), p.units(), c, endOfMonth); + } + + /// + /// Calculates the number of business days between two given + /// dates and returns the result. + /// + public int businessDaysBetween(Date from, Date to, bool includeFirst = true, bool includeLast = false) + { + int wd = 0; + if (from != to) + { + if (from < to) { - Date d1 = d + new Period(n, unit); - return adjust(d1, c); + // the last one is treated separately to avoid incrementing Date::maxDate() + for (Date d = from; d < to; ++d) + { + if (isBusinessDay(d)) + ++wd; + } + if (isBusinessDay(to)) + ++wd; } else { - Date d1 = d + new Period(n, unit); - if (endOfMonth && (unit == TimeUnit.Months || unit == TimeUnit.Years) && isEndOfMonth(d)) - return this.endOfMonth(d1); - return adjust(d1, c); + for (Date d = to; d < from; ++d) + { + if (isBusinessDay(d)) + ++wd; + } + if (isBusinessDay(from)) + ++wd; } - } - /// - /// Advances the given date as specified by the given period and - /// returns the result. - /// - /// The input date is not modified. - public Date advance( Date d, Period p, BusinessDayConvention c = BusinessDayConvention.Following, bool endOfMonth = false) - { - return advance(d, p.length(), p.units(), c, endOfMonth); - } - /// - /// Calculates the number of business days between two given - /// dates and returns the result. - /// - public int businessDaysBetween(Date from, Date to, bool includeFirst = true, bool includeLast = false) - { - int wd = 0; - if (from != to) - { - if (from < to) - { - // the last one is treated separately to avoid incrementing Date::maxDate() - for (Date d = from; d < to; ++d) - { - if (isBusinessDay(d)) - ++wd; - } - if (isBusinessDay(to)) - ++wd; - } - else - { - for (Date d = to; d < from; ++d) - { - if (isBusinessDay(d)) - ++wd; - } - if (isBusinessDay(from)) - ++wd; - } + if (isBusinessDay(from) && !includeFirst) + wd--; + if (isBusinessDay(to) && !includeLast) + wd--; - if (isBusinessDay(from) && !includeFirst) - wd--; - if (isBusinessDay(to) && !includeLast) - wd--; + if (from > to) + wd = -wd; + } + return wd; + } - if (from > to) - wd = -wd; - } - return wd; - } + /// + /// Adds a date to the set of holidays for the given calendar. + /// + public void addHoliday(Date d) + { + // if d was a genuine holiday previously removed, revert the change + calendar.removedHolidays.Remove(d); + // if it's already a holiday, leave the calendar alone. + // Otherwise, add it. + if (isBusinessDay(d)) + calendar.addedHolidays.Add(d); + } + /// + /// Removes a date from the set of holidays for the given calendar. + /// + public void removeHoliday(Date d) + { + // if d was an artificially-added holiday, revert the change + calendar.addedHolidays.Remove(d); + // if it's already a business day, leave the calendar alone. + // Otherwise, add it. + if (!isBusinessDay(d)) + calendar.removedHolidays.Add(d); + } + /// + /// Returns the holidays between two dates + /// + public static List holidayList(Calendar calendar, Date from, Date to, bool includeWeekEnds = false) + { + Utils.QL_REQUIRE(to > from, () => "'from' date (" + from + ") must be earlier than 'to' date (" + to + ")"); + List result = new List(); - /// - /// Adds a date to the set of holidays for the given calendar. - /// - public void addHoliday(Date d) { - // if d was a genuine holiday previously removed, revert the change - calendar.removedHolidays.Remove(d); - // if it's already a holiday, leave the calendar alone. - // Otherwise, add it. - if (isBusinessDay(d)) - calendar.addedHolidays.Add(d); - } - /// - /// Removes a date from the set of holidays for the given calendar. - /// - public void removeHoliday(Date d) { - // if d was an artificially-added holiday, revert the change - calendar.addedHolidays.Remove(d); - // if it's already a business day, leave the calendar alone. - // Otherwise, add it. - if (!isBusinessDay(d)) - calendar.removedHolidays.Add(d); - } - /// - /// Returns the holidays between two dates - /// - public static List holidayList(Calendar calendar, Date from, Date to, bool includeWeekEnds = false) { - Utils.QL_REQUIRE(to > from,()=> "'from' date (" + from + ") must be earlier than 'to' date (" + to + ")"); - List result = new List(); + for (Date d = from; d <= to; ++d) + { + if (calendar.isHoliday(d) + && (includeWeekEnds || !calendar.isWeekend(d.DayOfWeek))) + result.Add(d); + } + return result; + } - for (Date d = from; d <= to; ++d) - { - if (calendar.isHoliday(d) - && (includeWeekEnds || !calendar.isWeekend(d.DayOfWeek))) - result.Add(d); - } - return result; - } + /// + /// This class provides the means of determining the Easter + /// Monday for a given year, as well as specifying Saturdays + /// and Sundays as weekend days. + /// + public class WesternImpl : Calendar + { + // Western calendars + public WesternImpl() { } + public WesternImpl(Calendar c) : base(c) { } - /// - /// This class provides the means of determining the Easter - /// Monday for a given year, as well as specifying Saturdays - /// and Sundays as weekend days. - /// - public class WesternImpl : Calendar - { // Western calendars - public WesternImpl() { } - public WesternImpl(Calendar c) : base(c) { } + int[] EasterMonday = + { + 98, 90, 103, 95, 114, 106, 91, 111, 102, // 1901-1909 + 87, 107, 99, 83, 103, 95, 115, 99, 91, 111, // 1910-1919 + 96, 87, 107, 92, 112, 103, 95, 108, 100, 91, // 1920-1929 + 111, 96, 88, 107, 92, 112, 104, 88, 108, 100, // 1930-1939 + 85, 104, 96, 116, 101, 92, 112, 97, 89, 108, // 1940-1949 + 100, 85, 105, 96, 109, 101, 93, 112, 97, 89, // 1950-1959 + 109, 93, 113, 105, 90, 109, 101, 86, 106, 97, // 1960-1969 + 89, 102, 94, 113, 105, 90, 110, 101, 86, 106, // 1970-1979 + 98, 110, 102, 94, 114, 98, 90, 110, 95, 86, // 1980-1989 + 106, 91, 111, 102, 94, 107, 99, 90, 103, 95, // 1990-1999 + 115, 106, 91, 111, 103, 87, 107, 99, 84, 103, // 2000-2009 + 95, 115, 100, 91, 111, 96, 88, 107, 92, 112, // 2010-2019 + 104, 95, 108, 100, 92, 111, 96, 88, 108, 92, // 2020-2029 + 112, 104, 89, 108, 100, 85, 105, 96, 116, 101, // 2030-2039 + 93, 112, 97, 89, 109, 100, 85, 105, 97, 109, // 2040-2049 + 101, 93, 113, 97, 89, 109, 94, 113, 105, 90, // 2050-2059 + 110, 101, 86, 106, 98, 89, 102, 94, 114, 105, // 2060-2069 + 90, 110, 102, 86, 106, 98, 111, 102, 94, 114, // 2070-2079 + 99, 90, 110, 95, 87, 106, 91, 111, 103, 94, // 2080-2089 + 107, 99, 91, 103, 95, 115, 107, 91, 111, 103, // 2090-2099 + 88, 108, 100, 85, 105, 96, 109, 101, 93, 112, // 2100-2109 + 97, 89, 109, 93, 113, 105, 90, 109, 101, 86, // 2110-2119 + 106, 97, 89, 102, 94, 113, 105, 90, 110, 101, // 2120-2129 + 86, 106, 98, 110, 102, 94, 114, 98, 90, 110, // 2130-2139 + 95, 86, 106, 91, 111, 102, 94, 107, 99, 90, // 2140-2149 + 103, 95, 115, 106, 91, 111, 103, 87, 107, 99, // 2150-2159 + 84, 103, 95, 115, 100, 91, 111, 96, 88, 107, // 2160-2169 + 92, 112, 104, 95, 108, 100, 92, 111, 96, 88, // 2170-2179 + 108, 92, 112, 104, 89, 108, 100, 85, 105, 96, // 2180-2189 + 116, 101, 93, 112, 97, 89, 109, 100, 85, 105 // 2190-2199 + }; - int[] EasterMonday = { - 98, 90, 103, 95, 114, 106, 91, 111, 102, // 1901-1909 - 87, 107, 99, 83, 103, 95, 115, 99, 91, 111, // 1910-1919 - 96, 87, 107, 92, 112, 103, 95, 108, 100, 91, // 1920-1929 - 111, 96, 88, 107, 92, 112, 104, 88, 108, 100, // 1930-1939 - 85, 104, 96, 116, 101, 92, 112, 97, 89, 108, // 1940-1949 - 100, 85, 105, 96, 109, 101, 93, 112, 97, 89, // 1950-1959 - 109, 93, 113, 105, 90, 109, 101, 86, 106, 97, // 1960-1969 - 89, 102, 94, 113, 105, 90, 110, 101, 86, 106, // 1970-1979 - 98, 110, 102, 94, 114, 98, 90, 110, 95, 86, // 1980-1989 - 106, 91, 111, 102, 94, 107, 99, 90, 103, 95, // 1990-1999 - 115, 106, 91, 111, 103, 87, 107, 99, 84, 103, // 2000-2009 - 95, 115, 100, 91, 111, 96, 88, 107, 92, 112, // 2010-2019 - 104, 95, 108, 100, 92, 111, 96, 88, 108, 92, // 2020-2029 - 112, 104, 89, 108, 100, 85, 105, 96, 116, 101, // 2030-2039 - 93, 112, 97, 89, 109, 100, 85, 105, 97, 109, // 2040-2049 - 101, 93, 113, 97, 89, 109, 94, 113, 105, 90, // 2050-2059 - 110, 101, 86, 106, 98, 89, 102, 94, 114, 105, // 2060-2069 - 90, 110, 102, 86, 106, 98, 111, 102, 94, 114, // 2070-2079 - 99, 90, 110, 95, 87, 106, 91, 111, 103, 94, // 2080-2089 - 107, 99, 91, 103, 95, 115, 107, 91, 111, 103, // 2090-2099 - 88, 108, 100, 85, 105, 96, 109, 101, 93, 112, // 2100-2109 - 97, 89, 109, 93, 113, 105, 90, 109, 101, 86, // 2110-2119 - 106, 97, 89, 102, 94, 113, 105, 90, 110, 101, // 2120-2129 - 86, 106, 98, 110, 102, 94, 114, 98, 90, 110, // 2130-2139 - 95, 86, 106, 91, 111, 102, 94, 107, 99, 90, // 2140-2149 - 103, 95, 115, 106, 91, 111, 103, 87, 107, 99, // 2150-2159 - 84, 103, 95, 115, 100, 91, 111, 96, 88, 107, // 2160-2169 - 92, 112, 104, 95, 108, 100, 92, 111, 96, 88, // 2170-2179 - 108, 92, 112, 104, 89, 108, 100, 85, 105, 96, // 2180-2189 - 116, 101, 93, 112, 97, 89, 109, 100, 85, 105 // 2190-2199 - }; + public override bool isWeekend(DayOfWeek w) { return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; } + /// + /// Expressed relative to first day of year + /// + /// + /// + public int easterMonday(int y) + { + return EasterMonday[y - 1901]; + } + } + /// + /// This class provides the means of determining the Orthodox + /// Easter Monday for a given year, as well as specifying + /// Saturdays and Sundays as weekend days. + /// + public class OrthodoxImpl : Calendar + { + // Orthodox calendars + public OrthodoxImpl() { } + public OrthodoxImpl(Calendar c) : base(c) { } - public override bool isWeekend(DayOfWeek w) { return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; } - /// - /// Expressed relative to first day of year - /// - /// - /// - public int easterMonday(int y) - { - return EasterMonday[y - 1901]; - } - } - /// - /// This class provides the means of determining the Orthodox - /// Easter Monday for a given year, as well as specifying - /// Saturdays and Sundays as weekend days. - /// - public class OrthodoxImpl : Calendar - { // Orthodox calendars - public OrthodoxImpl() { } - public OrthodoxImpl(Calendar c) : base(c) { } + int[] EasterMonday = + { + 105, 118, 110, 102, 121, 106, 126, 118, 102, // 1901-1909 + 122, 114, 99, 118, 110, 95, 115, 106, 126, 111, // 1910-1919 + 103, 122, 107, 99, 119, 110, 123, 115, 107, 126, // 1920-1929 + 111, 103, 123, 107, 99, 119, 104, 123, 115, 100, // 1930-1939 + 120, 111, 96, 116, 108, 127, 112, 104, 124, 115, // 1940-1949 + 100, 120, 112, 96, 116, 108, 128, 112, 104, 124, // 1950-1959 + 109, 100, 120, 105, 125, 116, 101, 121, 113, 104, // 1960-1969 + 117, 109, 101, 120, 105, 125, 117, 101, 121, 113, // 1970-1979 + 98, 117, 109, 129, 114, 105, 125, 110, 102, 121, // 1980-1989 + 106, 98, 118, 109, 122, 114, 106, 118, 110, 102, // 1990-1999 + 122, 106, 126, 118, 103, 122, 114, 99, 119, 110, // 2000-2009 + 95, 115, 107, 126, 111, 103, 123, 107, 99, 119, // 2010-2019 + 111, 123, 115, 107, 127, 111, 103, 123, 108, 99, // 2020-2029 + 119, 104, 124, 115, 100, 120, 112, 96, 116, 108, // 2030-2039 + 128, 112, 104, 124, 116, 100, 120, 112, 97, 116, // 2040-2049 + 108, 128, 113, 104, 124, 109, 101, 120, 105, 125, // 2050-2059 + 117, 101, 121, 113, 105, 117, 109, 101, 121, 105, // 2060-2069 + 125, 110, 102, 121, 113, 98, 118, 109, 129, 114, // 2070-2079 + 106, 125, 110, 102, 122, 106, 98, 118, 110, 122, // 2080-2089 + 114, 99, 119, 110, 102, 115, 107, 126, 118, 103, // 2090-2099 + 123, 115, 100, 120, 112, 96, 116, 108, 128, 112, // 2100-2109 + 104, 124, 109, 100, 120, 105, 125, 116, 108, 121, // 2110-2119 + 113, 104, 124, 109, 101, 120, 105, 125, 117, 101, // 2120-2129 + 121, 113, 98, 117, 109, 129, 114, 105, 125, 110, // 2130-2139 + 102, 121, 113, 98, 118, 109, 129, 114, 106, 125, // 2140-2149 + 110, 102, 122, 106, 126, 118, 103, 122, 114, 99, // 2150-2159 + 119, 110, 102, 115, 107, 126, 111, 103, 123, 114, // 2160-2169 + 99, 119, 111, 130, 115, 107, 127, 111, 103, 123, // 2170-2179 + 108, 99, 119, 104, 124, 115, 100, 120, 112, 103, // 2180-2189 + 116, 108, 128, 119, 104, 124, 116, 100, 120, 112 // 2190-2199 + }; - int[] EasterMonday = { - 105, 118, 110, 102, 121, 106, 126, 118, 102, // 1901-1909 - 122, 114, 99, 118, 110, 95, 115, 106, 126, 111, // 1910-1919 - 103, 122, 107, 99, 119, 110, 123, 115, 107, 126, // 1920-1929 - 111, 103, 123, 107, 99, 119, 104, 123, 115, 100, // 1930-1939 - 120, 111, 96, 116, 108, 127, 112, 104, 124, 115, // 1940-1949 - 100, 120, 112, 96, 116, 108, 128, 112, 104, 124, // 1950-1959 - 109, 100, 120, 105, 125, 116, 101, 121, 113, 104, // 1960-1969 - 117, 109, 101, 120, 105, 125, 117, 101, 121, 113, // 1970-1979 - 98, 117, 109, 129, 114, 105, 125, 110, 102, 121, // 1980-1989 - 106, 98, 118, 109, 122, 114, 106, 118, 110, 102, // 1990-1999 - 122, 106, 126, 118, 103, 122, 114, 99, 119, 110, // 2000-2009 - 95, 115, 107, 126, 111, 103, 123, 107, 99, 119, // 2010-2019 - 111, 123, 115, 107, 127, 111, 103, 123, 108, 99, // 2020-2029 - 119, 104, 124, 115, 100, 120, 112, 96, 116, 108, // 2030-2039 - 128, 112, 104, 124, 116, 100, 120, 112, 97, 116, // 2040-2049 - 108, 128, 113, 104, 124, 109, 101, 120, 105, 125, // 2050-2059 - 117, 101, 121, 113, 105, 117, 109, 101, 121, 105, // 2060-2069 - 125, 110, 102, 121, 113, 98, 118, 109, 129, 114, // 2070-2079 - 106, 125, 110, 102, 122, 106, 98, 118, 110, 122, // 2080-2089 - 114, 99, 119, 110, 102, 115, 107, 126, 118, 103, // 2090-2099 - 123, 115, 100, 120, 112, 96, 116, 108, 128, 112, // 2100-2109 - 104, 124, 109, 100, 120, 105, 125, 116, 108, 121, // 2110-2119 - 113, 104, 124, 109, 101, 120, 105, 125, 117, 101, // 2120-2129 - 121, 113, 98, 117, 109, 129, 114, 105, 125, 110, // 2130-2139 - 102, 121, 113, 98, 118, 109, 129, 114, 106, 125, // 2140-2149 - 110, 102, 122, 106, 126, 118, 103, 122, 114, 99, // 2150-2159 - 119, 110, 102, 115, 107, 126, 111, 103, 123, 114, // 2160-2169 - 99, 119, 111, 130, 115, 107, 127, 111, 103, 123, // 2170-2179 - 108, 99, 119, 104, 124, 115, 100, 120, 112, 103, // 2180-2189 - 116, 108, 128, 119, 104, 124, 116, 100, 120, 112 // 2190-2199 - }; + public override bool isWeekend(DayOfWeek w) { return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; } + /// + /// expressed relative to first day of year + /// + /// + /// + public int easterMonday(int y) + { + return EasterMonday[y - 1901]; + } + } - public override bool isWeekend(DayOfWeek w) { return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; } - /// - /// expressed relative to first day of year - /// - /// - /// - public int easterMonday(int y) - { - return EasterMonday[y - 1901]; - } - } + // Operators + public static bool operator ==(Calendar c1, Calendar c2) + { + // If both are null, or both are same instance, return true. + if (System.Object.ReferenceEquals(c1, c2)) + { + return true; + } - // Operators - public static bool operator ==(Calendar c1, Calendar c2) - { - // If both are null, or both are same instance, return true. - if (System.Object.ReferenceEquals(c1, c2)) - { - return true; - } + // If one is null, but not both, return false. + if (((object)c1 == null) || ((object)c2 == null)) + { + return false; + } - // If one is null, but not both, return false. - if (((object)c1 == null) || ((object)c2 == null)) - { - return false; - } - - return (c1.empty() && c2.empty()) - || (!c1.empty() && !c2.empty() && c1.name() == c2.name()); - } + return (c1.empty() && c2.empty()) + || (!c1.empty() && !c2.empty() && c1.name() == c2.name()); + } - public static bool operator !=(Calendar c1, Calendar c2) - { - return !(c1 == c2); - } - public override bool Equals(object o) { return (this == (Calendar)o); } - public override int GetHashCode() { return 0; } - } + public static bool operator !=(Calendar c1, Calendar c2) + { + return !(c1 == c2); + } + public override bool Equals(object o) { return (this == (Calendar)o); } + public override int GetHashCode() { return 0; } + } } diff --git a/src/QLNet/Time/Calendars/Argentina.cs b/src/QLNet/Time/Calendars/Argentina.cs new file mode 100644 index 000000000..52129b4e0 --- /dev/null +++ b/src/QLNet/Time/Calendars/Argentina.cs @@ -0,0 +1,97 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! Argentinian calendars + /*! Holidays for the Buenos Aires stock exchange + (data from ): +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st
  • +
  • Holy Thursday
  • +
  • Good Friday
  • +
  • Labour Day, May 1st
  • +
  • May Revolution, May 25th
  • +
  • Death of General Manuel Belgrano, third Monday of June
  • +
  • Independence Day, July 9th
  • +
  • Death of General José de San Martín, third Monday of August
  • +
  • Columbus Day, October 12th (moved to preceding Monday if + on Tuesday or Wednesday and to following if on Thursday + or Friday)
  • +
  • Immaculate Conception, December 8th
  • +
  • Christmas Eve, December 24th
  • +
  • New Year's Eve, December 31th
  • +
+ + \ingroup calendars + */ + public class Argentina : Calendar + { + public Argentina() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Buenos Aires stock exchange"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Holy Thursday + || (dd == em - 4) + // Good Friday + || (dd == em - 3) + // Labour Day + || (d == 1 && m == Month.May) + // May Revolution + || (d == 25 && m == Month.May) + // Death of General Manuel Belgrano + || (d >= 15 && d <= 21 && w == DayOfWeek.Monday && m == Month.June) + // Independence Day + || (d == 9 && m == Month.July) + // Death of General José de San Martín + || (d >= 15 && d <= 21 && w == DayOfWeek.Monday && m == Month.August) + // Columbus Day + || ((d == 10 || d == 11 || d == 12 || d == 15 || d == 16) + && w == DayOfWeek.Monday && m == Month.October) + // Immaculate Conception + || (d == 8 && m == Month.December) + // Christmas Eve + || (d == 24 && m == Month.December) + // New Year's Eve + || ((d == 31 || (d == 30 && w == DayOfWeek.Friday)) && m == Month.December)) + return false; + return true; + } + } + } +} diff --git a/src/QLNet/Time/Calendars/Australia.cs b/src/QLNet/Time/Calendars/Australia.cs new file mode 100644 index 000000000..d5a0a6ae6 --- /dev/null +++ b/src/QLNet/Time/Calendars/Australia.cs @@ -0,0 +1,98 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Andrea Maggiulli + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! Australian calendar + /*! Holidays: +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st
  • +
  • Australia Day, January 26th (possibly moved to Monday)
  • +
  • Good Friday
  • +
  • Easter Monday
  • +
  • ANZAC Day. April 25th (possibly moved to Monday)
  • +
  • Queen's Birthday, second Monday in June
  • +
  • Bank Holiday, first Monday in August
  • +
  • Labour Day, first Monday in October
  • +
  • Christmas, December 25th (possibly moved to Monday or Tuesday)
  • +
  • Boxing Day, December 26th (possibly moved to Monday or + Tuesday)
  • +
+ + \ingroup calendars + */ + public class Australia : Calendar + { + public Australia() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Australia"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day (possibly moved to Monday) + || (d == 1 && m == Month.January) + // Australia Day, January 26th (possibly moved to Monday) + || ((d == 26 || ((d == 27 || d == 28) && w == DayOfWeek.Monday)) && + m == Month.January) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // ANZAC Day, April 25th (possibly moved to Monday) + || ((d == 25 || (d == 26 && w == DayOfWeek.Monday)) && m == Month.April) + // Queen's Birthday, second Monday in June + || ((d > 7 && d <= 14) && w == DayOfWeek.Monday && m == Month.June) + // Bank Holiday, first Monday in August + || (d <= 7 && w == DayOfWeek.Monday && m == Month.August) + // Labour Day, first Monday in October + || (d <= 7 && w == DayOfWeek.Monday && m == Month.October) + // Christmas, December 25th (possibly Monday or Tuesday) + || ((d == 25 || (d == 27 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) + && m == Month.December) + // Boxing Day, December 26th (possibly Monday or Tuesday) + || ((d == 26 || (d == 28 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) + && m == Month.December)) + return false; + return true; + } + } + } + +} + + + + diff --git a/src/QLNet/Time/Calendars/BespokeCalendar.cs b/src/QLNet/Time/Calendars/BespokeCalendar.cs new file mode 100644 index 000000000..05b210cdb --- /dev/null +++ b/src/QLNet/Time/Calendars/BespokeCalendar.cs @@ -0,0 +1,66 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + //! Bespoke calendar + /*! This calendar has no predefined set of business days. Holidays + and weekdays can be defined by means of the provided + interface. Instances constructed by copying remain linked to + the original one; adding a new holiday or weekday will affect + all linked instances. + + \ingroup calendars + */ + public class BespokeCalendar : Calendar + { + private string name_; + public override string name() { return name_; } + + /*! \warning different bespoke calendars created with the same + name (or different bespoke calendars created with + no name) will compare as equal. + */ + public BespokeCalendar() : this("") { } + public BespokeCalendar(string name) : base(new Impl()) + { + name_ = name; + } + + //! marks the passed day as part of the weekend + public void addWeekend(DayOfWeek w) + { + Impl impl = calendar_ as Impl; + if (impl != null) + impl.addWeekend(w); + } + + // here implementation does not follow a singleton pattern + class Impl : Calendar.WesternImpl + { + public override bool isWeekend(DayOfWeek w) { return (weekend_.Contains(w)); } + public override bool isBusinessDay(Date date) { return !isWeekend(date.DayOfWeek); } + public void addWeekend(DayOfWeek w) { weekend_.Add(w); } + + private List weekend_ = new List(); + } + } +} diff --git a/src/QLNet/Time/Calendars/Botswana.cs b/src/QLNet/Time/Calendars/Botswana.cs new file mode 100644 index 000000000..8d53cd111 --- /dev/null +++ b/src/QLNet/Time/Calendars/Botswana.cs @@ -0,0 +1,110 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Andrea Maggiulli + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + Copyright (C) 2017 Francois Botha (igitur@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! Botswana calendar + /*! Holidays: + From the Botswana Public Holidays Act + The days named in the Schedule shall be public holidays within Botswana: + Provided that +
    +
  • when any of the said days fall on a Sunday the following Monday shall be observed as a public holiday;
  • +
  • if 2nd January, 1st October or Boxing Day falls on a Monday, the following Tuesday shall be observed as a public holiday;
  • +
  • when Botswana Day referred to in the Schedule falls on a Saturday, the next following Monday shall be observed as a public holiday.
  • +
+
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st
  • +
  • Good Friday
  • +
  • Easter Monday
  • +
  • Labour Day, May 1st
  • +
  • Ascension
  • +
  • Sir Seretse Khama Day, July 1st
  • +
  • Presidents' Day
  • +
  • Independence Day, September 30th
  • +
  • Botswana Day, October 1st
  • +
  • Christmas, December 25th
  • +
  • Boxing Day, December 26th
  • +
+ + \ingroup calendars + */ + public class Botswana : Calendar + { + public Botswana() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "South Africa"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day (possibly moved to Monday or Tuesday) + || ((d == 1 || (d == 2 && w == DayOfWeek.Monday) || (d == 3 && w == DayOfWeek.Tuesday)) + && m == Month.January) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // Labour Day, May 1st (possibly moved to Monday) + || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) + && m == Month.May) + // Ascension + || (dd == em + 38) + // Sir Seretse Khama Day, July 1st (possibly moved to Monday) + || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) + && m == Month.July) + // Presidents' Day (third Monday of July) + || ((d >= 15 && d <= 21) && w == DayOfWeek.Monday && m == Month.July) + // Independence Day, September 30th (possibly moved to Monday) + || ((d == 30 && m == Month.September) || + (d == 1 && w == DayOfWeek.Monday && m == Month.October)) + // Botswana Day, October 1st (possibly moved to Monday or Tuesday) + || ((d == 1 || (d == 2 && w == DayOfWeek.Monday) || (d == 3 && w == DayOfWeek.Tuesday)) + && m == Month.October) + // Christmas + || (d == 25 && m == Month.December) + // Boxing Day (possibly moved to Monday) + || ((d == 26 || (d == 27 && w == DayOfWeek.Monday)) + && m == Month.December) + ) + return false; + + return true; + } + } + } +} + diff --git a/src/QLNet/Time/Calendars/Brazil.cs b/src/QLNet/Time/Calendars/Brazil.cs new file mode 100644 index 000000000..7c4b8b231 --- /dev/null +++ b/src/QLNet/Time/Calendars/Brazil.cs @@ -0,0 +1,193 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! Brazilian calendar + /*! Banking holidays: +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st
  • +
  • Tiradentes's Day, April 21th
  • +
  • Labour Day, May 1st
  • +
  • Independence Day, September 7th
  • +
  • Nossa Sra. Aparecida Day, October 12th
  • +
  • All Souls Day, November 2nd
  • +
  • Republic Day, November 15th
  • +
  • Christmas, December 25th
  • +
  • Passion of Christ
  • +
  • Carnival
  • +
  • Corpus Christi
  • +
+ + Holidays for the Bovespa stock exchange +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st
  • +
  • Sao Paulo City Day, January 25th
  • +
  • Tiradentes's Day, April 21th
  • +
  • Labour Day, May 1st
  • +
  • Revolution Day, July 9th
  • +
  • Independence Day, September 7th
  • +
  • Nossa Sra. Aparecida Day, October 12th
  • +
  • All Souls Day, November 2nd
  • +
  • Republic Day, November 15th
  • +
  • Black Consciousness Day, November 20th (since 2007)
  • +
  • Christmas Eve, December 24th
  • +
  • Christmas, December 25th
  • +
  • Passion of Christ
  • +
  • Carnival
  • +
  • Corpus Christi
  • +
  • the last business day of the year
  • +
+ + \ingroup calendars + + \test the correctness of the returned results is tested + against a list of known holidays. + */ + public class Brazil : Calendar + { + //! Brazilian calendars + public enum Market { Settlement, //!< generic settlement calendar + Exchange //!< BOVESPA calendar + } + + public Brazil() : this(Market.Settlement) { } + public Brazil(Market market) + { + // all calendar instances on the same market share the same implementation instance + switch (market) + { + case Market.Settlement: + calendar_ = SettlementImpl.Singleton; + break; + case Market.Exchange: + calendar_ = ExchangeImpl.Singleton; + break; + default: + Utils.QL_FAIL("unknown market"); + break; + } + } + + + private class SettlementImpl : Calendar.WesternImpl + { + public static readonly SettlementImpl Singleton = new SettlementImpl(); + private SettlementImpl() { } + + public override string name() { return "Brazil"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day; + Month m = (Month)date.Month; + int y = date.Year; + int dd = date.DayOfYear; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Tiradentes Day + || (d == 21 && m == Month.April) + // Labor Day + || (d == 1 && m == Month.May) + // Independence Day + || (d == 7 && m == Month.September) + // Nossa Sra. Aparecida Day + || (d == 12 && m == Month.October) + // All Souls Day + || (d == 2 && m == Month.November) + // Republic Day + || (d == 15 && m == Month.November) + // Christmas + || (d == 25 && m == Month.December) + // Passion of Christ + || (dd == em - 3) + // Carnival + || (dd == em - 49 || dd == em - 48) + // Corpus Christi + || (dd == em + 59) + ) + return false; + return true; + } + } + + private class ExchangeImpl : Calendar.WesternImpl + { + public static readonly ExchangeImpl Singleton = new ExchangeImpl(); + private ExchangeImpl() { } + + public override string name() { return "BOVESPA"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day; + Month m = (Month)date.Month; + int y = date.Year; + int dd = date.DayOfYear; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Sao Paulo City Day + || (d == 25 && m == Month.January) + // Tiradentes Day + || (d == 21 && m == Month.April) + // Labor Day + || (d == 1 && m == Month.May) + // Revolution Day + || (d == 9 && m == Month.July) + // Independence Day + || (d == 7 && m == Month.September) + // Nossa Sra. Aparecida Day + || (d == 12 && m == Month.October) + // All Souls Day + || (d == 2 && m == Month.November) + // Republic Day + || (d == 15 && m == Month.November) + // Black Consciousness Day + || (d == 20 && m == Month.November && y >= 2007) + // Christmas Eve + || (d == 24 && m == Month.December) + // Christmas + || (d == 25 && m == Month.December) + // Passion of Christ + || (dd == em - 3) + // Carnival + || (dd == em - 49 || dd == em - 48) + // Corpus Christi + || (dd == em + 59) + // last business day of the year + || (m == Month.December && (d == 31 || (d >= 29 && w == DayOfWeek.Friday))) + ) + return false; + return true; + } + } + + } +} diff --git a/src/QLNet/Time/Calendars/Canada.cs b/src/QLNet/Time/Calendars/Canada.cs new file mode 100644 index 000000000..80cfc8df3 --- /dev/null +++ b/src/QLNet/Time/Calendars/Canada.cs @@ -0,0 +1,186 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! Canadian calendar + /*! Banking holidays: +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st (possibly moved to Monday)
  • +
  • Family Day, third Monday of February (since 2008)
  • +
  • Good Friday
  • +
  • Easter Monday
  • +
  • Victoria Day, The Monday on or preceding 24 May
  • +
  • Canada Day, July 1st (possibly moved to Monday)
  • +
  • Provincial Holiday, first Monday of August
  • +
  • Labour Day, first Monday of September
  • +
  • Thanksgiving Day, second Monday of October
  • +
  • Remembrance Day, November 11th (possibly moved to Monday)
  • +
  • Christmas, December 25th (possibly moved to Monday or Tuesday)
  • +
  • Boxing Day, December 26th (possibly moved to Monday or + Tuesday)
  • +
+ + Holidays for the Toronto stock exchange (TSX): +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st (possibly moved to Monday)
  • +
  • Family Day, third Monday of February (since 2008)
  • +
  • Good Friday
  • +
  • Easter Monday
  • +
  • Victoria Day, The Monday on or preceding 24 May
  • +
  • Canada Day, July 1st (possibly moved to Monday)
  • +
  • Provincial Holiday, first Monday of August
  • +
  • Labour Day, first Monday of September
  • +
  • Thanksgiving Day, second Monday of October
  • +
  • Christmas, December 25th (possibly moved to Monday or Tuesday)
  • +
  • Boxing Day, December 26th (possibly moved to Monday or + Tuesday)
  • +
+ + \ingroup calendars + */ + public class Canada : Calendar + { + public enum Market + { + Settlement, //!< generic settlement calendar + TSX //!< Toronto stock exchange calendar + } + + public Canada() : this(Market.Settlement) { } + public Canada(Market m) + : base() + { + // all calendar instances on the same market share the same + // implementation instance + switch (m) + { + case Market.Settlement: + calendar_ = Settlement.Singleton; + break; + case Market.TSX: + calendar_ = TSX.Singleton; + break; + default: + throw new ArgumentException("Unknown market: " + m); + } + } + + class Settlement : Calendar.WesternImpl + { + public static readonly Settlement Singleton = new Settlement(); + private Settlement() { } + + public override string name() { return "Canada"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day (possibly moved to Monday) + || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) && m == Month.January) + // Family Day (third Monday in February, since 2008) + || ((d >= 15 && d <= 21) && w == DayOfWeek.Monday && m == Month.February + && y >= 2008) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // The Monday on or preceding 24 May (Victoria Day) + || (d > 17 && d <= 24 && w == DayOfWeek.Monday && m == Month.May) + // July 1st, possibly moved to Monday (Canada Day) + || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) && m == Month.July) + // first Monday of August (Provincial Holiday) + || (d <= 7 && w == DayOfWeek.Monday && m == Month.August) + // first Monday of September (Labor Day) + || (d <= 7 && w == DayOfWeek.Monday && m == Month.September) + // second Monday of October (Thanksgiving Day) + || (d > 7 && d <= 14 && w == DayOfWeek.Monday && m == Month.October) + // November 11th (possibly moved to Monday) + || ((d == 11 || ((d == 12 || d == 13) && w == DayOfWeek.Monday)) + && m == Month.November) + // Christmas (possibly moved to Monday or Tuesday) + || ((d == 25 || (d == 27 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) + && m == Month.December) + // Boxing Day (possibly moved to Monday or Tuesday) + || ((d == 26 || (d == 28 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) + && m == Month.December) + ) + return false; + return true; + } + } + + class TSX : Calendar.WesternImpl + { + public static readonly TSX Singleton = new TSX(); + private TSX() { } + + public override string name() { return "TSX"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day (possibly moved to Monday) + || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) && m == Month.January) + // Family Day (third Monday in February, since 2008) + || ((d >= 15 && d <= 21) && w == DayOfWeek.Monday && m == Month.February + && y >= 2008) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // The Monday on or preceding 24 May (Victoria Day) + || (d > 17 && d <= 24 && w == DayOfWeek.Monday && m == Month.May) + // July 1st, possibly moved to Monday (Canada Day) + || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) && m == Month.July) + // first Monday of August (Provincial Holiday) + || (d <= 7 && w == DayOfWeek.Monday && m == Month.August) + // first Monday of September (Labor Day) + || (d <= 7 && w == DayOfWeek.Monday && m == Month.September) + // second Monday of October (Thanksgiving Day) + || (d > 7 && d <= 14 && w == DayOfWeek.Monday && m == Month.October) + // Christmas (possibly moved to Monday or Tuesday) + || ((d == 25 || (d == 27 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) + && m == Month.December) + // Boxing Day (possibly moved to Monday or Tuesday) + || ((d == 26 || (d == 28 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) + && m == Month.December) + ) + return false; + return true; + } + } + } +} \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/China.cs b/src/QLNet/Time/Calendars/China.cs new file mode 100644 index 000000000..b12eec921 --- /dev/null +++ b/src/QLNet/Time/Calendars/China.cs @@ -0,0 +1,310 @@ +/* + Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; +using System.Collections.Generic; + +namespace QLNet +{ + //! Chinese calendar + /*! Holidays: +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's day, January 1st (possibly followed by one or + two more holidays)
  • +
  • Labour Day, first week in May
  • +
  • National Day, one week from October 1st
  • +
+ + Other holidays for which no rule is given (data available for + 2004-2015 only): +
    +
  • Chinese New Year
  • +
  • Ching Ming Festival
  • +
  • Tuen Ng Festival
  • +
  • Mid-Autumn Festival
  • +
  • 70th anniversary of the victory of anti-Japaneses war
  • +
+ + SSE data from + IB data from + + \ingroup calendars + */ + public class China : Calendar + { + public enum Market + { + SSE, //!< Shanghai stock exchange + IB //!< Interbank calendar + } + + public China(Market market = Market.SSE) + { + + // all calendar instances on the same market share the same implementation instance + switch (market) + { + case Market.SSE: + calendar_ = SseImpl.Singleton; + break; + case Market.IB: + calendar_ = IbImpl.Singleton; + break; + default: + Utils.QL_FAIL("unknown market"); + break; + } + } + + private class SseImpl : Calendar + { + public static readonly SseImpl Singleton = new SseImpl(); + private SseImpl() { } + public override string name() { return "Shanghai stock exchange"; } + + public override bool isWeekend(DayOfWeek w) + { + return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; + } + + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day; + Month m = (Month)date.Month; + int y = date.Year; + + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + || (y == 2005 && d == 3 && m == Month.January) + || (y == 2006 && (d == 2 || d == 3) && m == Month.January) + || (y == 2007 && d <= 3 && m == Month.January) + || (y == 2007 && d == 31 && m == Month.December) + || (y == 2009 && d == 2 && m == Month.January) + || (y == 2011 && d == 3 && m == Month.January) + || (y == 2012 && (d == 2 || d == 3) && m == Month.January) + || (y == 2013 && d <= 3 && m == Month.January) + || (y == 2014 && d == 1 && m == Month.January) + || (y == 2015 && d <= 3 && m == Month.January) + // Chinese New Year + || (y == 2004 && d >= 19 && d <= 28 && m == Month.January) + || (y == 2005 && d >= 7 && d <= 15 && m == Month.February) + || (y == 2006 && ((d >= 26 && m == Month.January) || + (d <= 3 && m == Month.February))) + || (y == 2007 && d >= 17 && d <= 25 && m == Month.February) + || (y == 2008 && d >= 6 && d <= 12 && m == Month.February) + || (y == 2009 && d >= 26 && d <= 30 && m == Month.January) + || (y == 2010 && d >= 15 && d <= 19 && m == Month.February) + || (y == 2011 && d >= 2 && d <= 8 && m == Month.February) + || (y == 2012 && d >= 23 && d <= 28 && m == Month.January) + || (y == 2013 && d >= 11 && d <= 15 && m == Month.February) + || (y == 2014 && d >= 31 && m == Month.January) + || (y == 2014 && d <= 6 && m == Month.February) + || (y == 2015 && d >= 18 && d <= 24 && m == Month.February) + || (y == 2016 && d >= 8 && d <= 12 && m == Month.February) + // Ching Ming Festival + || (y <= 2008 && d == 4 && m == Month.April) + || (y == 2009 && d == 6 && m == Month.April) + || (y == 2010 && d == 5 && m == Month.April) + || (y == 2011 && d >= 3 && d <= 5 && m == Month.April) + || (y == 2012 && d >= 2 && d <= 4 && m == Month.April) + || (y == 2013 && d >= 4 && d <= 5 && m == Month.April) + || (y == 2014 && d == 7 && m == Month.April) + || (y == 2015 && d >= 5 && d <= 6 && m == Month.April) + || (y == 2016 && d == 4 && m == Month.April) + // Labor Day + || (y <= 2007 && d >= 1 && d <= 7 && m == Month.May) + || (y == 2008 && d >= 1 && d <= 2 && m == Month.May) + || (y == 2009 && d == 1 && m == Month.May) + || (y == 2010 && d == 3 && m == Month.May) + || (y == 2011 && d == 2 && m == Month.May) + || (y == 2012 && ((d == 30 && m == Month.April) || + (d == 1 && m == Month.May))) + || (y == 2013 && ((d >= 29 && m == Month.April) || + (d == 1 && m == Month.May))) + || (y == 2014 && d >= 1 && d <= 3 && m == Month.May) + || (y == 2015 && d == 1 && m == Month.May) + || (y == 2016 && d >= 1 && d <= 2 && m == Month.May) + // Tuen Ng Festival + || (y <= 2008 && d == 9 && m == Month.June) + || (y == 2009 && (d == 28 || d == 29) && m == Month.May) + || (y == 2010 && d >= 14 && d <= 16 && m == Month.June) + || (y == 2011 && d >= 4 && d <= 6 && m == Month.June) + || (y == 2012 && d >= 22 && d <= 24 && m == Month.June) + || (y == 2013 && d >= 10 && d <= 12 && m == Month.June) + || (y == 2014 && d == 2 && m == Month.June) + || (y == 2015 && d == 22 && m == Month.June) + || (y == 2016 && d >= 9 && d <= 10 && m == Month.June) + // Mid-Autumn Festival + || (y <= 2008 && d == 15 && m == Month.September) + || (y == 2010 && d >= 22 && d <= 24 && m == Month.September) + || (y == 2011 && d >= 10 && d <= 12 && m == Month.September) + || (y == 2012 && d == 30 && m == Month.September) + || (y == 2013 && d >= 19 && d <= 20 && m == Month.September) + || (y == 2014 && d == 8 && m == Month.September) + || (y == 2015 && d == 27 && m == Month.September) + || (y == 2016 && d >= 15 && d <= 16 && m == Month.September) + // National Day + || (y <= 2007 && d >= 1 && d <= 7 && m == Month.October) + || (y == 2008 && ((d >= 29 && m == Month.September) || + (d <= 3 && m == Month.October))) + || (y == 2009 && d >= 1 && d <= 8 && m == Month.October) + || (y == 2010 && d >= 1 && d <= 7 && m == Month.October) + || (y == 2011 && d >= 1 && d <= 7 && m == Month.October) + || (y == 2012 && d >= 1 && d <= 7 && m == Month.October) + || (y == 2013 && d >= 1 && d <= 7 && m == Month.October) + || (y == 2014 && d >= 1 && d <= 7 && m == Month.October) + || (y == 2015 && d >= 1 && d <= 7 && m == Month.October) + || (y == 2016 && d >= 3 && d <= 7 && m == Month.October) + // 70th anniversary of the victory of anti-Japaneses war + || (y == 2015 && d >= 3 && d <= 4 && m == Month.September) + ) + return false; + return true; + + } + } + + private class IbImpl : Calendar + { + public static readonly IbImpl Singleton = new IbImpl(); + + public IbImpl() + { + sseImpl = new China(Market.SSE); + } + + public override string name() { return "China inter bank market"; } + + public override bool isWeekend(DayOfWeek w) { return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; } + public override bool isBusinessDay(Date date) + { + + List working_weekends = new List + { + // 2005 + new Date(5, Month.February, 2005), + new Date(6, Month.February, 2005), + new Date(30, Month.April, 2005), + new Date(8, Month.May, 2005), + new Date(8, Month.October, 2005), + new Date(9, Month.October, 2005), + new Date(31, Month.December, 2005), + //2006 + new Date(28, Month.January, 2006), + new Date(29, Month.April, 2006), + new Date(30, Month.April, 2006), + new Date(30, Month.September, 2006), + new Date(30, Month.December, 2006), + new Date(31, Month.December, 2006), + // 2007 + new Date(17, Month.February, 2007), + new Date(25, Month.February, 2007), + new Date(28, Month.April, 2007), + new Date(29, Month.April, 2007), + new Date(29, Month.September, 2007), + new Date(30, Month.September, 2007), + new Date(29, Month.December, 2007), + // 2008 + new Date(2, Month.February, 2008), + new Date(3, Month.February, 2008), + new Date(4, Month.May, 2008), + new Date(27, Month.September, 2008), + new Date(28, Month.September, 2008), + // 2009 + new Date(4, Month.January, 2009), + new Date(24, Month.January, 2009), + new Date(1, Month.February, 2009), + new Date(31, Month.May, 2009), + new Date(27, Month.September, 2009), + new Date(10, Month.October, 2009), + // 2010 + new Date(20, Month.February, 2010), + new Date(21, Month.February, 2010), + new Date(12, Month.June, 2010), + new Date(13, Month.June, 2010), + new Date(19, Month.September, 2010), + new Date(25, Month.September, 2010), + new Date(26, Month.September, 2010), + new Date(9, Month.October, 2010), + // 2011 + new Date(30, Month.January, 2011), + new Date(12, Month.February, 2011), + new Date(2, Month.April, 2011), + new Date(8, Month.October, 2011), + new Date(9, Month.October, 2011), + new Date(31, Month.December, 2011), + // 2012 + new Date(21, Month.January, 2012), + new Date(29, Month.January, 2012), + new Date(31, Month.March, 2012), + new Date(1, Month.April, 2012), + new Date(28, Month.April, 2012), + new Date(29, Month.September, 2012), + // 2013 + new Date(5, Month.January, 2013), + new Date(6, Month.January, 2013), + new Date(16, Month.February, 2013), + new Date(17, Month.February, 2013), + new Date(7, Month.April, 2013), + new Date(27, Month.April, 2013), + new Date(28, Month.April, 2013), + new Date(8, Month.June, 2013), + new Date(9, Month.June, 2013), + new Date(22, Month.September, 2013), + new Date(29, Month.September, 2013), + new Date(12, Month.October, 2013), + // 2014 + new Date(26, Month.January, 2014), + new Date(8, Month.February, 2014), + new Date(4, Month.May, 2014), + new Date(28, Month.September, 2014), + new Date(11, Month.October, 2014), + // 2015 + new Date(4, Month.January, 2015), + new Date(15, Month.February, 2015), + new Date(28, Month.February, 2015), + new Date(6, Month.September, 2015), + new Date(10, Month.October, 2015), + // 2016 + new Date(6, Month.February, 2016), + new Date(14, Month.February, 2016), + new Date(12, Month.June, 2016), + new Date(18, Month.September, 2016), + new Date(8, Month.October, 2016), + new Date(9, Month.October, 2016) + }; + + // If it is already a SSE business day, it must be a IB business day + return sseImpl.isBusinessDay(date) || working_weekends.Contains(date); + + } + + private Calendar sseImpl; + + } + + } +} + diff --git a/src/QLNet/Time/Calendars/CzechRepublic.cs b/src/QLNet/Time/Calendars/CzechRepublic.cs new file mode 100644 index 000000000..ae8a156b7 --- /dev/null +++ b/src/QLNet/Time/Calendars/CzechRepublic.cs @@ -0,0 +1,96 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! Czech calendars + /*! Holidays for the Prague stock exchange (see http://www.pse.cz/): +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st
  • +
  • Easter Monday
  • +
  • Labour Day, May 1st
  • +
  • Liberation Day, May 8th
  • +
  • SS. Cyril and Methodius, July 5th
  • +
  • Jan Hus Day, July 6th
  • +
  • Czech Statehood Day, September 28th
  • +
  • Independence Day, October 28th
  • +
  • Struggle for Freedom and Democracy Day, November 17th
  • +
  • Christmas Eve, December 24th
  • +
  • Christmas, December 25th
  • +
  • St. Stephen, December 26th
  • +
+ + \ingroup calendars + */ + public class CzechRepublic : Calendar + { + public CzechRepublic() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Prague stock exchange"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Easter Monday + || (dd == em) + // Labour Day + || (d == 1 && m == Month.May) + // Liberation Day + || (d == 8 && m == Month.May) + // SS. Cyril and Methodius + || (d == 5 && m == Month.July) + // Jan Hus Day + || (d == 6 && m == Month.July) + // Czech Statehood Day + || (d == 28 && m == Month.September) + // Independence Day + || (d == 28 && m == Month.October) + // Struggle for Freedom and Democracy Day + || (d == 17 && m == Month.November) + // Christmas Eve + || (d == 24 && m == Month.December) + // Christmas + || (d == 25 && m == Month.December) + // St. Stephen + || (d == 26 && m == Month.December) + // unidentified closing days for stock exchange + || (d == 2 && m == Month.January && y == 2004) + || (d == 31 && m == Month.December && y == 2004)) + return false; + return true; + } + } + } +} diff --git a/src/QLNet/Time/Calendars/Denmark.cs b/src/QLNet/Time/Calendars/Denmark.cs new file mode 100644 index 000000000..029a4ef44 --- /dev/null +++ b/src/QLNet/Time/Calendars/Denmark.cs @@ -0,0 +1,89 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Andrea Maggiulli + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! Danish calendar + /*! Holidays: +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • Maunday Thursday
  • +
  • Good Friday
  • +
  • Easter Monday
  • +
  • General Prayer Day, 25 days after Easter Monday
  • +
  • Ascension
  • +
  • Whit (Pentecost) Monday
  • +
  • New Year's Day, January 1st
  • +
  • Constitution Day, June 5th
  • +
  • Christmas, December 25th
  • +
  • Boxing Day, December 26th
  • +
+ + \ingroup calendars + */ + public class Denmark : Calendar + { + public Denmark() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Denmark"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + if (isWeekend(w) + // Maunday Thursday + || (dd == em - 4) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // General Prayer Day + || (dd == em + 25) + // Ascension + || (dd == em + 38) + // Whit Monday + || (dd == em + 49) + // New Year's Day + || (d == 1 && m == Month.January) + // Constitution Day, June 5th + || (d == 5 && m == Month.June) + // Christmas + || (d == 25 && m == Month.December) + // Boxing Day + || (d == 26 && m == Month.December)) + return false; + return true; + } + } + } +} + diff --git a/src/QLNet/Time/Calendars/Finland.cs b/src/QLNet/Time/Calendars/Finland.cs new file mode 100644 index 000000000..fd52ed773 --- /dev/null +++ b/src/QLNet/Time/Calendars/Finland.cs @@ -0,0 +1,93 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Andrea Maggiulli + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! Finnish calendar + /*! Holidays: +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st
  • +
  • Epiphany, January 6th
  • +
  • Good Friday
  • +
  • Easter Monday
  • +
  • Ascension Thursday
  • +
  • Labour Day, May 1st
  • +
  • Midsummer Eve (Friday between June 18-24)
  • +
  • Independence Day, December 6th
  • +
  • Christmas Eve, December 24th
  • +
  • Christmas, December 25th
  • +
  • Boxing Day, December 26th
  • +
+ + \ingroup calendars + */ + public class Finland : Calendar + { + public Finland() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Finland"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Epiphany + || (d == 6 && m == Month.January) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // Ascension Thursday + || (dd == em + 38) + // Labour Day + || (d == 1 && m == Month.May) + // Midsummer Eve (Friday between June 18-24) + || (w == DayOfWeek.Friday && (d >= 18 && d <= 24) && m == Month.June) + // Independence Day + || (d == 6 && m == Month.December) + // Christmas Eve + || (d == 24 && m == Month.December) + // Christmas + || (d == 25 && m == Month.December) + // Boxing Day + || (d == 26 && m == Month.December)) + return false; + return true; + } + } + } +} + diff --git a/src/QLNet/Time/Calendars/Germany.cs b/src/QLNet/Time/Calendars/Germany.cs new file mode 100644 index 000000000..79a997d8f --- /dev/null +++ b/src/QLNet/Time/Calendars/Germany.cs @@ -0,0 +1,335 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! German calendars + /*! Public holidays: +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st
  • +
  • Good Friday
  • +
  • Easter Monday
  • +
  • Ascension Thursday
  • +
  • Whit Monday
  • +
  • Corpus Christi
  • +
  • Labour Day, May 1st
  • +
  • National Day, October 3rd
  • +
  • Christmas Eve, December 24th
  • +
  • Christmas, December 25th
  • +
  • Boxing Day, December 26th
  • +
  • New Year's Eve, December 31st
  • +
+ + Holidays for the Frankfurt Stock exchange + (data from http://deutsche-boerse.com/): +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st
  • +
  • Good Friday
  • +
  • Easter Monday
  • +
  • Labour Day, May 1st
  • +
  • Christmas' Eve, December 24th
  • +
  • Christmas, December 25th
  • +
  • Christmas Holiday, December 26th
  • +
  • New Year's Eve, December 31st
  • +
+ + Holidays for the Xetra exchange + (data from http://deutsche-boerse.com/): +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st
  • +
  • Good Friday
  • +
  • Easter Monday
  • +
  • Labour Day, May 1st
  • +
  • Christmas' Eve, December 24th
  • +
  • Christmas, December 25th
  • +
  • Christmas Holiday, December 26th
  • +
  • New Year's Eve, December 31st
  • +
+ + Holidays for the Eurex exchange + (data from http://www.eurexchange.com/index.html): +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st
  • +
  • Good Friday
  • +
  • Easter Monday
  • +
  • Labour Day, May 1st
  • +
  • Christmas' Eve, December 24th
  • +
  • Christmas, December 25th
  • +
  • Christmas Holiday, December 26th
  • +
  • New Year's Eve, December 31st
  • +
+ + Holidays for the Euwax exchange + (data from http://www.boerse-stuttgart.de): +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st
  • +
  • Good Friday
  • +
  • Easter Monday
  • +
  • Labour Day, May 1st
  • +
  • Whit Monday
  • +
  • Christmas' Eve, December 24th
  • +
  • Christmas, December 25th
  • +
  • Christmas Holiday, December 26th
  • +
  • New Year's Eve, December 31st
  • +
+ + \ingroup calendars + + \test the correctness of the returned results is tested + against a list of known holidays. + */ + public class Germany : Calendar + { + //! German calendars + public enum Market + { + Settlement, //!< generic settlement calendar + FrankfurtStockExchange, //!< Frankfurt stock-exchange + Xetra, //!< Xetra + Eurex, //!< Eurex + Euwax //!< Euwax + } + + public Germany() : this(Market.FrankfurtStockExchange) { } + public Germany(Market m) + : base() + { + // all calendar instances on the same market share the same + // implementation instance + switch (m) + { + case Market.Settlement: + calendar_ = Settlement.Singleton; + break; + case Market.FrankfurtStockExchange: + calendar_ = FrankfurtStockExchange.Singleton; + break; + case Market.Xetra: + calendar_ = Xetra.Singleton; + break; + case Market.Eurex: + calendar_ = Eurex.Singleton; + break; + case Market.Euwax: + calendar_ = Euwax.Singleton; + break; + default: + throw new ArgumentException("Unknown market: " + m); + } + } + + class Settlement : Calendar.WesternImpl + { + public static readonly Settlement Singleton = new Settlement(); + private Settlement() { } + + public override string name() { return "German settlement"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // Ascension Thursday + || (dd == em + 38) + // Whit Monday + || (dd == em + 49) + // Corpus Christi + || (dd == em + 59) + // Labour Day + || (d == 1 && m == Month.May) + // National Day + || (d == 3 && m == Month.October) + // Christmas Eve + || (d == 24 && m == Month.December) + // Christmas + || (d == 25 && m == Month.December) + // Boxing Day + || (d == 26 && m == Month.December) + // New Year's Eve + || (d == 31 && m == Month.December)) + return false; + return true; + } + } + class FrankfurtStockExchange : Calendar.WesternImpl + { + public static readonly FrankfurtStockExchange Singleton = new FrankfurtStockExchange(); + private FrankfurtStockExchange() { } + + public override string name() { return "Frankfurt stock exchange"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // Labour Day + || (d == 1 && m == Month.May) + // Christmas' Eve + || (d == 24 && m == Month.December) + // Christmas + || (d == 25 && m == Month.December) + // Christmas Day + || (d == 26 && m == Month.December) + // New Year's Eve + || (d == 31 && m == Month.December)) + return false; + return true; + } + } + class Xetra : Calendar.WesternImpl + { + public static readonly Xetra Singleton = new Xetra(); + private Xetra() { } + + public override string name() { return "Xetra"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // Labour Day + || (d == 1 && m == Month.May) + // Christmas' Eve + || (d == 24 && m == Month.December) + // Christmas + || (d == 25 && m == Month.December) + // Christmas Day + || (d == 26 && m == Month.December) + // New Year's Eve + || (d == 31 && m == Month.December)) + return false; + return true; + } + } + class Eurex : Calendar.WesternImpl + { + public static readonly Eurex Singleton = new Eurex(); + private Eurex() { } + + public override string name() { return "Eurex"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // Labour Day + || (d == 1 && m == Month.May) + // Christmas' Eve + || (d == 24 && m == Month.December) + // Christmas + || (d == 25 && m == Month.December) + // Christmas Day + || (d == 26 && m == Month.December) + // New Year's Eve + || (d == 31 && m == Month.December)) + return false; + return true; + } + } + class Euwax : Calendar.WesternImpl + { + public static readonly Euwax Singleton = new Euwax(); + private Euwax() { } + + public override string name() { return "Euwax"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if ((w == DayOfWeek.Saturday || w == DayOfWeek.Sunday) + // New Year's Day + || (d == 1 && m == Month.January) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // Labour Day + || (d == 1 && m == Month.May) + // Whit Monday + || (dd == em + 49) + // Christmas' Eve + || (d == 24 && m == Month.December) + // Christmas + || (d == 25 && m == Month.December) + // Christmas Day + || (d == 26 && m == Month.December) + // New Year's Eve + || (d == 31 && m == Month.December)) + return false; + return true; + } + } + } +} \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/HongKong.cs b/src/QLNet/Time/Calendars/HongKong.cs new file mode 100644 index 000000000..f714c1e08 --- /dev/null +++ b/src/QLNet/Time/Calendars/HongKong.cs @@ -0,0 +1,300 @@ +/* + Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! Hong Kong calendars + /*! Holidays: +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st (possibly moved to Monday)
  • +
  • Good Friday
  • +
  • Easter Monday
  • +
  • Labor Day, May 1st (possibly moved to Monday)
  • +
  • SAR Establishment Day, July 1st (possibly moved to Monday)
  • +
  • National Day, October 1st (possibly moved to Monday)
  • +
  • Christmas, December 25th
  • +
  • Boxing Day, December 26th
  • +
+ + Other holidays for which no rule is given + (data available for 2004-2013 only:) +
    +
  • Lunar New Year
  • +
  • Chinese New Year
  • +
  • Ching Ming Festival
  • +
  • Buddha's birthday
  • +
  • Tuen NG Festival
  • +
  • Mid-autumn Festival
  • +
  • Chung Yeung Festival
  • +
+ + Data from + + \ingroup calendars + */ + public class HongKong : Calendar + { + public HongKong() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Hong Kong stock exchange"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day + || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) + && m == Month.January) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // Labor Day + || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) && m == Month.May) + // SAR Establishment Day + || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) && m == Month.July) + // National Day + || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) + && m == Month.October) + // Christmas Day + || (d == 25 && m == Month.December) + // Boxing Day + || (d == 26 && m == Month.December)) + return false; + + if (y == 2004) + { + if (// Lunar New Year + ((d == 22 || d == 23 || d == 24) && m == Month.January) + // Ching Ming Festival + || (d == 5 && m == Month.April) + // Buddha's birthday + || (d == 26 && m == Month.May) + // Tuen NG festival + || (d == 22 && m == Month.June) + // Mid-autumn festival + || (d == 29 && m == Month.September) + // Chung Yeung + || (d == 29 && m == Month.September)) + return false; + } + + if (y == 2005) + { + if (// Lunar New Year + ((d == 9 || d == 10 || d == 11) && m == Month.February) + // Ching Ming Festival + || (d == 5 && m == Month.April) + // Buddha's birthday + || (d == 16 && m == Month.May) + // Tuen NG festival + || (d == 11 && m == Month.June) + // Mid-autumn festival + || (d == 19 && m == Month.September) + // Chung Yeung festival + || (d == 11 && m == Month.October)) + return false; + } + + if (y == 2006) + { + if (// Lunar New Year + ((d >= 28 && d <= 31) && m == Month.January) + // Ching Ming Festival + || (d == 5 && m == Month.April) + // Buddha's birthday + || (d == 5 && m == Month.May) + // Tuen NG festival + || (d == 31 && m == Month.May) + // Mid-autumn festival + || (d == 7 && m == Month.October) + // Chung Yeung festival + || (d == 30 && m == Month.October)) + return false; + } + + if (y == 2007) + { + if (// Lunar New Year + ((d >= 17 && d <= 20) && m == Month.February) + // Ching Ming Festival + || (d == 5 && m == Month.April) + // Buddha's birthday + || (d == 24 && m == Month.May) + // Tuen NG festival + || (d == 19 && m == Month.June) + // Mid-autumn festival + || (d == 26 && m == Month.September) + // Chung Yeung festival + || (d == 19 && m == Month.October)) + return false; + } + + if (y == 2008) + { + if (// Lunar New Year + ((d >= 7 && d <= 9) && m == Month.February) + // Ching Ming Festival + || (d == 4 && m == Month.April) + // Buddha's birthday + || (d == 12 && m == Month.May) + // Tuen NG festival + || (d == 9 && m == Month.June) + // Mid-autumn festival + || (d == 15 && m == Month.September) + // Chung Yeung festival + || (d == 7 && m == Month.October)) + return false; + } + + if (y == 2009) + { + if (// Lunar New Year + ((d >= 26 && d <= 28) && m == Month.January) + // Ching Ming Festival + || (d == 4 && m == Month.April) + // Buddha's birthday + || (d == 2 && m == Month.May) + // Tuen NG festival + || (d == 28 && m == Month.May) + // Mid-autumn festival + || (d == 3 && m == Month.October) + // Chung Yeung festival + || (d == 26 && m == Month.October)) + return false; + } + + if (y == 2010) + { + if (// Lunar New Year + ((d == 15 || d == 16) && m == Month.February) + // Ching Ming Festival + || (d == 6 && m == Month.April) + // Buddha's birthday + || (d == 21 && m == Month.May) + // Tuen NG festival + || (d == 16 && m == Month.June) + // Mid-autumn festival + || (d == 23 && m == Month.September)) + return false; + } + + + if (y == 2011) + { + if (// Lunar New Year + ((d == 3 || d == 4) && m == Month.February) + // Ching Ming Festival + || (d == 5 && m == Month.April) + // Buddha's birthday + || (d == 10 && m == Month.May) + // Tuen NG festival + || (d == 6 && m == Month.June) + // Mid-autumn festival + || (d == 13 && m == Month.September) + // Chung Yeung festival + || (d == 5 && m == Month.October) + // Second day after Christmas + || (d == 27 && m == Month.December)) + return false; + } + + if (y == 2012) + { + if (// Lunar New Year + (d >= 23 && d <= 25 && m == Month.January) + // Ching Ming Festival + || (d == 4 && m == Month.April) + // Buddha's birthday + || (d == 10 && m == Month.May) + // Mid-autumn festival + || (d == 1 && m == Month.October) + // Chung Yeung festival + || (d == 23 && m == Month.October)) + return false; + } + + if (y == 2013) + { + if (// Lunar New Year + (d >= 11 && d <= 13 && m == Month.February) + // Ching Ming Festival + || (d == 4 && m == Month.April) + // Buddha's birthday + || (d == 17 && m == Month.May) + // Tuen Ng festival + || (d == 12 && m == Month.June) + // Mid-autumn festival + || (d == 20 && m == Month.September) + // Chung Yeung festival + || (d == 14 && m == Month.October)) + return false; + } + + if (y == 2014) + { + if (// Lunar New Year + ((d == 31 && m == Month.January) || (d <= 3 && m == Month.February)) + // Buddha's birthday + || (d == 6 && m == Month.May) + // Tuen Ng festival + || (d == 2 && m == Month.June) + // Mid-autumn festival + || (d == 9 && m == Month.September) + // Chung Yeung festival + || (d == 2 && m == Month.October)) + return false; + } + + if (y == 2015) + { + if (// Lunar New Year + ((d == 19 && m == Month.February) || (d == 20 && m == Month.February)) + // The day following Easter Monday + || (d == 7 && m == Month.April) + // Buddha's birthday + || (d == 25 && m == Month.May) + // Tuen Ng festival + || (d == 20 && m == Month.June) + // Mid-autumn festival + || (d == 28 && m == Month.September) + // Chung Yeung festival + || (d == 21 && m == Month.October)) + return false; + } + return true; + } + } + } +} \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/Hungary.cs b/src/QLNet/Time/Calendars/Hungary.cs new file mode 100644 index 000000000..802bc3e78 --- /dev/null +++ b/src/QLNet/Time/Calendars/Hungary.cs @@ -0,0 +1,88 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Andrea Maggiulli + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! Hungarian calendar + /*! Holidays: +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • Easter Monday
  • +
  • Whit(Pentecost) Monday
  • +
  • New Year's Day, January 1st
  • +
  • National Day, March 15th
  • +
  • Labour Day, May 1st
  • +
  • Constitution Day, August 20th
  • +
  • Republic Day, October 23rd
  • +
  • All Saints Day, November 1st
  • +
  • Christmas, December 25th
  • +
  • 2nd Day of Christmas, December 26th
  • +
+ + \ingroup calendars + */ + public class Hungary : Calendar + { + public Hungary() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Hungary"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + if (isWeekend(w) + // Easter Monday + || (dd == em) + // Whit Monday + || (dd == em + 49) + // New Year's Day + || (d == 1 && m == Month.January) + // National Day + || (d == 15 && m == Month.March) + // Labour Day + || (d == 1 && m == Month.May) + // Constitution Day + || (d == 20 && m == Month.August) + // Republic Day + || (d == 23 && m == Month.October) + // All Saints Day + || (d == 1 && m == Month.November) + // Christmas + || (d == 25 && m == Month.December) + // 2nd Day of Christmas + || (d == 26 && m == Month.December)) + return false; + return true; + } + } + } +} \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/Iceland.cs b/src/QLNet/Time/Calendars/Iceland.cs new file mode 100644 index 000000000..ee0ee3c4e --- /dev/null +++ b/src/QLNet/Time/Calendars/Iceland.cs @@ -0,0 +1,95 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! Icelandic calendars + /*! Holidays for the Iceland stock exchange + (data from ): +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st (possibly moved to Monday)
  • +
  • Holy Thursday
  • +
  • Good Friday
  • +
  • Easter Monday
  • +
  • First day of Summer (third or fourth Thursday in April)
  • +
  • Labour Day, May 1st
  • +
  • Ascension Thursday
  • +
  • Pentecost Monday
  • +
  • Independence Day, June 17th
  • +
  • Commerce Day, first Monday in August
  • +
  • Christmas, December 25th
  • +
  • Boxing Day, December 26th
  • +
+ + \ingroup calendars + */ + public class Iceland : Calendar + { + public Iceland() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Iceland stock exchange"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day (possibly moved to Monday) + || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) + && m == Month.January) + // Holy Thursday + || (dd == em - 4) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // First day of Summer + || (d >= 19 && d <= 25 && w == DayOfWeek.Thursday && m == Month.April) + // Ascension Thursday + || (dd == em + 38) + // Pentecost Monday + || (dd == em + 49) + // Labour Day + || (d == 1 && m == Month.May) + // Independence Day + || (d == 17 && m == Month.June) + // Commerce Day + || (d <= 7 && w == DayOfWeek.Monday && m == Month.August) + // Christmas + || (d == 25 && m == Month.December) + // Boxing Day + || (d == 26 && m == Month.December)) + return false; + return true; + } + } + } +} diff --git a/src/QLNet/Time/Calendars/India.cs b/src/QLNet/Time/Calendars/India.cs new file mode 100644 index 000000000..f53dbed0f --- /dev/null +++ b/src/QLNet/Time/Calendars/India.cs @@ -0,0 +1,348 @@ +/* + Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! Indian calendars + /*! Holidays for the National Stock Exchange + (data from ): +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • Republic Day, January 26th
  • +
  • Good Friday
  • +
  • Ambedkar Jayanti, April 14th
  • +
  • May Day, May 1st
  • +
  • Independence Day, August 15th
  • +
  • Gandhi Jayanti, October 2nd
  • +
  • Christmas, December 25th
  • +
+ + Other holidays for which no rule is given + (data available for 2005-2013 only:) +
    +
  • Bakri Id
  • +
  • Moharram
  • +
  • Mahashivratri
  • +
  • Holi
  • +
  • Ram Navami
  • +
  • Mahavir Jayanti
  • +
  • Id-E-Milad
  • +
  • Maharashtra Day
  • +
  • Buddha Pournima
  • +
  • Ganesh Chaturthi
  • +
  • Dasara
  • +
  • Laxmi Puja
  • +
  • Bhaubeej
  • +
  • Ramzan Id
  • +
  • Guru Nanak Jayanti
  • +
+ + \ingroup calendars + */ + public class India : Calendar + { + public India() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "National Stock Exchange of India"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // Republic Day + || (d == 26 && m == Month.January) + // Good Friday + || (dd == em - 3) + // Ambedkar Jayanti + || (d == 14 && m == Month.April) + // May Day + || (d == 1 && m == Month.May) + // Independence Day + || (d == 15 && m == Month.August) + // Gandhi Jayanti + || (d == 2 && m == Month.October) + // Christmas + || (d == 25 && m == Month.December) + ) + return false; + + if (y == 2005) + { + // Moharram, Holi, Maharashtra Day, and Ramzan Id fall + // on Saturday or Sunday in 2005 + if (// Bakri Id + (d == 21 && m == Month.January) + // Ganesh Chaturthi + || (d == 7 && m == Month.September) + // Dasara + || (d == 12 && m == Month.October) + // Laxmi Puja + || (d == 1 && m == Month.November) + // Bhaubeej + || (d == 3 && m == Month.November) + // Guru Nanak Jayanti + || (d == 15 && m == Month.November) + ) + return false; + } + + if (y == 2006) + { + if (// Bakri Id + (d == 11 && m == Month.January) + // Moharram + || (d == 9 && m == Month.February) + // Holi + || (d == 15 && m == Month.March) + // Ram Navami + || (d == 6 && m == Month.April) + // Mahavir Jayanti + || (d == 11 && m == Month.April) + // Maharashtra Day + || (d == 1 && m == Month.May) + // Bhaubeej + || (d == 24 && m == Month.October) + // Ramzan Id + || (d == 25 && m == Month.October) + ) + return false; + } + + if (y == 2007) + { + if (// Bakri Id + (d == 1 && m == Month.January) + // Moharram + || (d == 30 && m == Month.January) + // Mahashivratri + || (d == 16 && m == Month.February) + // Ram Navami + || (d == 27 && m == Month.March) + // Maharashtra Day + || (d == 1 && m == Month.May) + // Buddha Pournima + || (d == 2 && m == Month.May) + // Laxmi Puja + || (d == 9 && m == Month.November) + // Bakri Id (again) + || (d == 21 && m == Month.December) + ) + return false; + } + + if (y == 2008) + { + if (// Mahashivratri + (d == 6 && m == Month.March) + // Id-E-Milad + || (d == 20 && m == Month.March) + // Mahavir Jayanti + || (d == 18 && m == Month.April) + // Maharashtra Day + || (d == 1 && m == Month.May) + // Buddha Pournima + || (d == 19 && m == Month.May) + // Ganesh Chaturthi + || (d == 3 && m == Month.September) + // Ramzan Id + || (d == 2 && m == Month.October) + // Dasara + || (d == 9 && m == Month.October) + // Laxmi Puja + || (d == 28 && m == Month.October) + // Bhau bhij + || (d == 30 && m == Month.October) + // Gurunanak Jayanti + || (d == 13 && m == Month.November) + // Bakri Id + || (d == 9 && m == Month.December) + ) + return false; + } + + if (y == 2009) + { + if (// Moharram + (d == 8 && m == Month.January) + // Mahashivratri + || (d == 23 && m == Month.February) + // Id-E-Milad + || (d == 10 && m == Month.March) + // Holi + || (d == 11 && m == Month.March) + // Ram Navmi + || (d == 3 && m == Month.April) + // Mahavir Jayanti + || (d == 7 && m == Month.April) + // Maharashtra Day + || (d == 1 && m == Month.May) + // Ramzan Id + || (d == 21 && m == Month.September) + // Dasara + || (d == 28 && m == Month.September) + // Bhau Bhij + || (d == 19 && m == Month.October) + // Gurunanak Jayanti + || (d == 2 && m == Month.November) + // Moharram (again) + || (d == 28 && m == Month.December) + ) + return false; + } + + if (y == 2010) + { + if (// New Year's Day + (d == 1 && m == Month.January) + // Mahashivratri + || (d == 12 && m == Month.February) + // Holi + || (d == 1 && m == Month.March) + // Ram Navmi + || (d == 24 && m == Month.March) + // Ramzan Id + || (d == 10 && m == Month.September) + // Laxmi Puja + || (d == 5 && m == Month.November) + // Bakri Id + || (d == 17 && m == Month.November) + // Moharram + || (d == 17 && m == Month.December) + ) + return false; + } + + if (y == 2011) + { + if (// Mahashivratri + (d == 2 && m == Month.March) + // Ram Navmi + || (d == 12 && m == Month.April) + // Ramzan Id + || (d == 31 && m == Month.August) + // Ganesh Chaturthi + || (d == 1 && m == Month.September) + // Dasara + || (d == 6 && m == Month.October) + // Laxmi Puja + || (d == 26 && m == Month.October) + // Diwali - Balipratipada + || (d == 27 && m == Month.October) + // Bakri Id + || (d == 7 && m == Month.November) + // Gurunanak Jayanti + || (d == 10 && m == Month.November) + // Moharram + || (d == 6 && m == Month.December) + ) + return false; + } + + if (y == 2012) + { + if (// Mahashivratri + (d == 20 && m == Month.February) + // Holi + || (d == 8 && m == Month.March) + // Mahavir Jayanti + || (d == 5 && m == Month.April) + // Ramzan Id + || (d == 20 && m == Month.August) + // Ganesh Chaturthi + || (d == 19 && m == Month.September) + // Dasara + || (d == 24 && m == Month.October) + // Diwali - Balipratipada + || (d == 14 && m == Month.November) + // Gurunanak Jayanti + || (d == 28 && m == Month.November) + ) + return false; + } + + if (y == 2013) + { + if (// Holi + (d == 27 && m == Month.March) + // Ram Navmi + || (d == 19 && m == Month.April) + // Mahavir Jayanti + || (d == 24 && m == Month.April) + // Ramzan Id + || (d == 9 && m == Month.August) + // Ganesh Chaturthi + || (d == 9 && m == Month.September) + // Bakri Id + || (d == 16 && m == Month.October) + // Diwali - Balipratipada + || (d == 4 && m == Month.November) + // Moharram + || (d == 14 && m == Month.November) + ) + return false; + } + + if (y == 2014) + { + if (// Mahashivratri + (d == 27 && m == Month.February) + // Holi + || (d == 17 && m == Month.March) + // Ram Navmi + || (d == 8 && m == Month.April) + // Ramzan Id + || (d == 29 && m == Month.July) + // Ganesh Chaturthi + || (d == 29 && m == Month.August) + // Dasera + || (d == 3 && m == Month.October) + // Bakri Id + || (d == 6 && m == Month.October) + // Diwali - Balipratipada + || (d == 24 && m == Month.October) + // Moharram + || (d == 4 && m == Month.November) + // Gurunank Jayanti + || (d == 6 && m == Month.November) + ) + return false; + } + return true; + } + } + } +} + + + + diff --git a/src/QLNet/Time/Calendars/Indonesia.cs b/src/QLNet/Time/Calendars/Indonesia.cs new file mode 100644 index 000000000..9bb03f0db --- /dev/null +++ b/src/QLNet/Time/Calendars/Indonesia.cs @@ -0,0 +1,330 @@ +/* + Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! %Indonesian calendars + /*! Holidays for the Indonesia stock exchange + (data from ): +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st
  • +
  • Good Friday
  • +
  • Ascension of Jesus Christ
  • +
  • Independence Day, August 17th
  • +
  • Christmas, December 25th
  • +
+ + Other holidays for which no rule is given + (data available for 2005-2013 only:) +
    +
  • Idul Adha
  • +
  • Ied Adha
  • +
  • Imlek
  • +
  • Moslem's New Year Day
  • +
  • Chinese New Year
  • +
  • Nyepi (Saka's New Year)
  • +
  • Birthday of Prophet Muhammad SAW
  • +
  • Waisak
  • +
  • Ascension of Prophet Muhammad SAW
  • +
  • Idul Fitri
  • +
  • Ied Fitri
  • +
  • Other national leaves
  • +
+ \ingroup calendars + */ + public class Indonesia : Calendar + { + public enum Market + { + BEJ, //!< Jakarta stock exchange (merged into IDX) + JSX, //!< Jakarta stock exchange (merged into IDX) + IDX //!< Indonesia stock exchange + } + + public Indonesia() : this(Market.IDX) { } + public Indonesia(Market m) + : base() + { + // all calendar instances on the same market share the same + // implementation instance + switch (m) + { + case Market.BEJ: + case Market.JSX: + case Market.IDX: + calendar_ = BEJ.Singleton; + break; + default: + throw new ArgumentException("Unknown market: " + m); + } + } + + class BEJ : Calendar.WesternImpl + { + public static readonly BEJ Singleton = new BEJ(); + private BEJ() { } + + public override string name() { return "Jakarta stock exchange"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Good Friday + || (dd == em - 3) + // Ascension Thursday + || (dd == em + 38) + // Independence Day + || (d == 17 && m == Month.August) + // Christmas + || (d == 25 && m == Month.December) + ) + return false; + + if (y == 2005) + { + if (// Idul Adha + (d == 21 && m == Month.January) + // Imlek + || (d == 9 && m == Month.February) + // Moslem's New Year Day + || (d == 10 && m == Month.February) + // Nyepi + || (d == 11 && m == Month.March) + // Birthday of Prophet Muhammad SAW + || (d == 22 && m == Month.April) + // Waisak + || (d == 24 && m == Month.May) + // Ascension of Prophet Muhammad SAW + || (d == 2 && m == Month.September) + // Idul Fitri + || ((d == 3 || d == 4) && m == Month.November) + // National leaves + || ((d == 2 || d == 7 || d == 8) && m == Month.November) + || (d == 26 && m == Month.December) + ) + return false; + } + + if (y == 2006) + { + if (// Idul Adha + (d == 10 && m == Month.January) + // Moslem's New Year Day + || (d == 31 && m == Month.January) + // Nyepi + || (d == 30 && m == Month.March) + // Birthday of Prophet Muhammad SAW + || (d == 10 && m == Month.April) + // Ascension of Prophet Muhammad SAW + || (d == 21 && m == Month.August) + // Idul Fitri + || ((d == 24 || d == 25) && m == Month.October) + // National leaves + || ((d == 23 || d == 26 || d == 27) && m == Month.October) + ) + return false; + } + + if (y == 2007) + { + if (// Nyepi + (d == 19 && m == Month.March) + // Waisak + || (d == 1 && m == Month.June) + // Ied Adha + || (d == 20 && m == Month.December) + // National leaves + || (d == 18 && m == Month.May) + || ((d == 12 || d == 15 || d == 16) && m == Month.October) + || ((d == 21 || d == 24) && m == Month.October) + ) + return false; + } + + if (y == 2008) + { + if (// Islamic New Year + ((d == 10 || d == 11) && m == Month.January) + // Chinese New Year + || ((d == 7 || d == 8) && m == Month.February) + // Saka's New Year + || (d == 7 && m == Month.March) + // Birthday of the prophet Muhammad SAW + || (d == 20 && m == Month.March) + // Vesak Day + || (d == 20 && m == Month.May) + // Isra' Mi'raj of the prophet Muhammad SAW + || (d == 30 && m == Month.July) + // National leave + || (d == 18 && m == Month.August) + // Ied Fitr + || (d == 30 && m == Month.September) + || ((d == 1 || d == 2 || d == 3) && m == Month.October) + // Ied Adha + || (d == 8 && m == Month.December) + // Islamic New Year + || (d == 29 && m == Month.December) + // New Year's Eve + || (d == 31 && m == Month.December) + ) + return false; + } + + if (y == 2009) + { + if (// Public holiday + (d == 2 && m == Month.January) + // Chinese New Year + || (d == 26 && m == Month.January) + // Birthday of the prophet Muhammad SAW + || (d == 9 && m == Month.March) + // Saka's New Year + || (d == 26 && m == Month.March) + // National leave + || (d == 9 && m == Month.April) + // Isra' Mi'raj of the prophet Muhammad SAW + || (d == 20 && m == Month.July) + // Ied Fitr + || (d >= 18 && d <= 23 && m == Month.September) + // Ied Adha + || (d == 27 && m == Month.November) + // Islamic New Year + || (d == 18 && m == Month.December) + // Public Holiday + || (d == 24 && m == Month.December) + // Trading holiday + || (d == 31 && m == Month.December) + ) + return false; + } + + if (y == 2010) + { + if (// Birthday of the prophet Muhammad SAW + (d == 26 && m == Month.February) + // Saka's New Year + || (d == 16 && m == Month.March) + // Birth of Buddha + || (d == 28 && m == Month.May) + // Ied Fitr + || (d >= 8 && d <= 14 && m == Month.September) + // Ied Adha + || (d == 17 && m == Month.November) + // Islamic New Year + || (d == 7 && m == Month.December) + // Public Holiday + || (d == 24 && m == Month.December) + // Trading holiday + || (d == 31 && m == Month.December) + ) + return false; + } + + if (y == 2011) + { + if (// Chinese New Year + (d == 3 && m == Month.February) + // Birthday of the prophet Muhammad SAW + || (d == 15 && m == Month.February) + // Birth of Buddha + || (d == 17 && m == Month.May) + // Isra' Mi'raj of the prophet Muhammad SAW + || (d == 29 && m == Month.June) + // Ied Fitr + || (d >= 29 && m == Month.August) + || (d <= 2 && m == Month.September) + // Public Holiday + || (d == 26 && m == Month.December) + ) + return false; + } + + if (y == 2012) + { + if (// Chinese New Year + (d == 23 && m == Month.January) + // Saka New Year + || (d == 23 && m == Month.March) + // Ied ul-Fitr + || (d >= 20 && d <= 22 && m == Month.August) + // Eid ul-Adha + || (d == 26 && m == Month.October) + // Islamic New Year + || (d >= 15 && d <= 16 && m == Month.November) + // Public Holiday + || (d == 24 && m == Month.December) + // Trading Holiday + || (d == 31 && m == Month.December) + ) + return false; + } + + if (y == 2013) + { + if (// Birthday of the prophet Muhammad SAW + (d == 24 && m == Month.January) + // Saka New Year + || (d == 12 && m == Month.March) + // Isra' Mi'raj of the prophet Muhammad SAW + || (d == 6 && m == Month.June) + // Ied ul-Fitr + || (d >= 5 && d <= 9 && m == Month.August) + // Eid ul-Adha + || (d >= 14 && d <= 15 && m == Month.October) + // Islamic New Year + || (d == 5 && m == Month.November) + // Public Holiday + || (d == 26 && m == Month.December) + // Trading Holiday + || (d == 31 && m == Month.December) + ) + return false; + } + if (y == 2014) + { + if (// Lunar New Year + ((d == 31 && m == Month.January) || (d <= 3 && m == Month.February)) + // Buddha's birthday + || (d == 6 && m == Month.May) + // Tuen Ng festival + || (d == 2 && m == Month.June) + // Mid-autumn festival + || (d == 9 && m == Month.September) + // Chung Yeung festival + || (d == 2 && m == Month.October)) + return false; + } + return true; + } + } + } +} diff --git a/src/QLNet/Time/Calendars/Israel.cs b/src/QLNet/Time/Calendars/Israel.cs index 16c797be4..9740e28bc 100644 --- a/src/QLNet/Time/Calendars/Israel.cs +++ b/src/QLNet/Time/Calendars/Israel.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -54,12 +54,12 @@ public enum Market TASE //!< Tel-Aviv stock exchange calendar } - public Israel( Market m = Market.Settlement ) + public Israel(Market m = Market.Settlement) : base() { // all calendar instances on the same market share the same // implementation instance - switch ( m ) + switch (m) { case Market.Settlement: calendar_ = TelAvivImpl.Singleton; @@ -68,7 +68,7 @@ public Israel( Market m = Market.Settlement ) calendar_ = TelAvivImpl.Singleton; break; default: - throw new ArgumentException( "Unknown market: " + m ); + throw new ArgumentException("Unknown market: " + m); } } @@ -78,320 +78,320 @@ class TelAvivImpl : Calendar private TelAvivImpl() { } public override string name() { return "Tel Aviv stock exchange"; } - public override bool isWeekend( DayOfWeek w ) + public override bool isWeekend(DayOfWeek w) { return w == DayOfWeek.Friday || w == DayOfWeek.Saturday; } - public override bool isBusinessDay( Date date ) + public override bool isBusinessDay(Date date) { DayOfWeek w = date.DayOfWeek; int d = date.Day; Month m = (Month)date.Month; int y = date.Year; - if ( isWeekend( w ) - //Purim - || ( d == 24 && m == Month.February && y == 2013 ) - || ( d == 16 && m == Month.March && y == 2014 ) - || ( d == 05 && m == Month.March && y == 2015 ) - || ( d == 24 && m == Month.March && y == 2016 ) - || ( d == 12 && m == Month.March && y == 2017 ) - || ( d == 1 && m == Month.March && y == 2018 ) - || ( d == 21 && m == Month.March && y == 2019 ) - || ( d == 10 && m == Month.March && y == 2020 ) - || ( d == 26 && m == Month.February && y == 2021 ) - || ( d == 17 && m == Month.March && y == 2022 ) - || ( d == 7 && m == Month.March && y == 2023 ) - || ( d == 24 && m == Month.March && y == 2024 ) - || ( d == 14 && m == Month.March && y == 2025 ) - || ( d == 3 && m == Month.March && y == 2026 ) - || ( d == 23 && m == Month.March && y == 2027 ) - || ( d == 12 && m == Month.March && y == 2028 ) - || ( d == 1 && m == Month.March && y == 2029 ) - || ( d == 19 && m == Month.March && y == 2030 ) - || ( d == 9 && m == Month.March && y == 2031 ) - || ( d == 26 && m == Month.February && y == 2032 ) - || ( d == 15 && m == Month.March && y == 2033 ) - || ( d == 5 && m == Month.March && y == 2034 ) - || ( d == 25 && m == Month.March && y == 2035 ) - || ( d == 13 && m == Month.March && y == 2036 ) - || ( d == 1 && m == Month.March && y == 2037 ) - || ( d == 21 && m == Month.March && y == 2038 ) - || ( d == 10 && m == Month.March && y == 2039 ) - || ( d == 28 && m == Month.February && y == 2040 ) - || ( d == 17 && m == Month.March && y == 2041 ) - || ( d == 6 && m == Month.March && y == 2042 ) - || ( d == 26 && m == Month.March && y == 2043 ) - || ( d == 13 && m == Month.March && y == 2044 ) - //Passover I and Passover VII - || ( ( ( ( d == 25 || d == 26 || d == 31 ) && m == Month.March ) || ( d == 1 && m == Month.April ) ) && y == 2013 ) - || ( ( d == 14 || d == 15 || d == 20 || d == 21 ) && m == Month.April && y == 2014 ) - || ( ( d == 3 || d == 4 || d == 9 || d == 10 ) && m == Month.April && y == 2015 ) - || ( ( d == 22 || d == 23 || d == 28 || d == 29 ) && m == Month.April && y == 2016 ) - || ( ( d == 10 || d == 11 || d == 16 || d == 17 ) && m == Month.April && y == 2017 ) - || ( ( ( d == 31 && m == Month.March ) || ( ( d == 5 || d == 6 ) && m == Month.April ) ) && y == 2018 ) - || ( ( d == 20 || d == 25 || d == 26 ) && m == Month.April && y == 2019 ) - || ( ( d == 8 || d == 9 || d == 14 || d == 15 ) && m == Month.April && y == 2020 ) - || ( ( ( d == 28 && m == Month.March ) || ( d == 3 && m == Month.April ) ) && y == 2021 ) - || ( ( d == 16 || d == 22 ) && m == Month.April && y == 2022 ) - || ( ( d == 6 || d == 12 ) && m == Month.April && y == 2023 ) - || ( ( d == 23 || d == 29 ) && m == Month.April && y == 2024 ) - || ( ( d == 13 || d == 19 ) && m == Month.April && y == 2025 ) - || ( ( d == 2 || d == 8 ) && m == Month.April && y == 2026 ) - || ( ( d == 22 || d == 28 ) && m == Month.April && y == 2027 ) - || ( ( d == 11 || d == 17 ) && m == Month.April && y == 2028 ) - || ( ( ( d == 31 && m == Month.March ) || ( d == 6 && m == Month.April ) ) && y == 2029 ) - || ( ( d == 18 || d == 24 ) && m == Month.April && y == 2030 ) - || ( ( d == 8 || d == 14 ) && m == Month.April && y == 2031 ) - || ( ( ( d == 27 && m == Month.March ) || ( d == 2 && m == Month.April ) ) && y == 2032 ) - || ( ( d == 14 || d == 20 ) && m == Month.April && y == 2033 ) - || ( ( d == 4 || d == 10 ) && m == Month.April && y == 2034 ) - || ( ( d == 24 || d == 30 ) && m == Month.April && y == 2035 ) - || ( ( d == 12 || d == 18 ) && m == Month.April && y == 2036 ) - || ( ( ( d == 31 && m == Month.March ) || ( d == 6 && m == Month.April ) ) && y == 2037 ) - || ( ( d == 20 || d == 26 ) && m == Month.April && y == 2038 ) - || ( ( d == 9 || d == 15 ) && m == Month.April && y == 2039 ) - || ( ( ( d == 29 && m == Month.March ) || ( d == 4 && m == Month.April ) ) && y == 2040 ) - || ( ( d == 16 || d == 22 ) && m == Month.April && y == 2041 ) - || ( ( d == 5 || d == 11 ) && m == Month.April && y == 2042 ) - || ( ( ( d == 25 && m == Month.April ) || ( d == 1 && m == Month.May ) ) && y == 2043 ) - || ( ( d == 12 || d == 18 ) && m == Month.April && y == 2044 ) - //Memorial and Indipendence Day - || ( ( d == 15 || d == 16 ) && m == Month.April && y == 2013 ) - || ( ( d == 5 || d == 6 ) && m == Month.May && y == 2014 ) - || ( ( d == 22 || d == 23 ) && m == Month.April && y == 2015 ) - || ( ( d == 11 || d == 12 ) && m == Month.May && y == 2016 ) - || ( ( d == 1 || d == 2 ) && m == Month.May && y == 2017 ) - || ( ( d == 18 || d == 19 ) && m == Month.April && y == 2018 ) - || ( ( d == 8 || d == 9 ) && m == Month.May && y == 2019 ) - || ( ( d == 28 || d == 29 ) && m == Month.April && y == 2020 ) - || ( ( d == 14 || d == 15 ) && m == Month.April && y == 2021 ) - || ( ( d == 4 || d == 5 ) && m == Month.May && y == 2022 ) - || ( ( d == 25 || d == 26 ) && m == Month.April && y == 2023 ) - || ( ( d == 13 || d == 14 ) && m == Month.May && y == 2024 ) - || ( ( ( d == 30 && m == Month.April ) || ( d == 1 && m == Month.May ) ) && y == 2025 ) - || ( ( d == 21 || d == 22 ) && m == Month.April && y == 2026 ) - || ( ( d == 11 || d == 12 ) && m == Month.May && y == 2027 ) - || ( ( d == 1 || d == 2 ) && m == Month.May && y == 2028 ) - || ( ( d == 18 || d == 19 ) && m == Month.April && y == 2029 ) - || ( ( d == 7 || d == 8 ) && m == Month.May && y == 2030 ) - || ( ( d == 28 || d == 29 ) && m == Month.April && y == 2031 ) - || ( ( d == 14 || d == 15 ) && m == Month.April && y == 2032 ) - || ( ( d == 3 || d == 4 ) && m == Month.May && y == 2033 ) - || ( ( d == 24 || d == 25 ) && m == Month.April && y == 2034 ) - || ( ( d == 14 || d == 15 ) && m == Month.May && y == 2035 ) - || ( ( ( d == 30 && m == Month.April ) || ( d == 1 && m == Month.May ) ) && y == 2036 ) - || ( ( d == 20 || d == 21 ) && m == Month.April && y == 2037 ) - || ( ( d == 9 || d == 10 ) && m == Month.May && y == 2038 ) - || ( ( d == 27 || d == 28 ) && m == Month.April && y == 2039 ) - || ( ( d == 17 || d == 18 ) && m == Month.April && y == 2040 ) - || ( ( d == 6 || d == 7 ) && m == Month.May && y == 2041 ) - || ( ( d == 23 || d == 24 ) && m == Month.April && y == 2042 ) - || ( ( d == 13 || d == 14 ) && m == Month.May && y == 2043 ) - || ( ( d == 2 || d == 3 ) && m == Month.May && y == 2044 ) - //Pentecost (Shavuot) - || ( ( d == 14 || d == 15 ) && m == Month.May && y == 2013 ) - || ( ( d == 3 || d == 4 ) && m == Month.June && y == 2014 ) - || ( ( d == 23 || d == 24 ) && m == Month.May && y == 2015 ) - || ( ( d == 11 || d == 12 ) && m == Month.June && y == 2016 ) - || ( ( d == 30 || d == 31 ) && m == Month.May && y == 2017 ) - || ( ( d == 19 || d == 20 ) && m == Month.May && y == 2018 ) - || ( ( d == 8 || d == 9 ) && m == Month.June && y == 2019 ) - || ( ( d == 28 || d == 29 ) && m == Month.May && y == 2020 ) - || ( d == 17 && m == Month.May && y == 2021 ) - || ( d == 5 && m == Month.June && y == 2022 ) - || ( d == 26 && m == Month.May && y == 2023 ) - || ( d == 12 && m == Month.June && y == 2024 ) - || ( d == 2 && m == Month.June && y == 2025 ) - || ( d == 22 && m == Month.May && y == 2026 ) - || ( d == 11 && m == Month.June && y == 2027 ) - || ( d == 31 && m == Month.May && y == 2028 ) - || ( d == 20 && m == Month.May && y == 2029 ) - || ( d == 7 && m == Month.June && y == 2030 ) - || ( d == 28 && m == Month.May && y == 2031 ) - || ( d == 16 && m == Month.May && y == 2032 ) - || ( d == 3 && m == Month.June && y == 2033 ) - || ( d == 24 && m == Month.May && y == 2034 ) - || ( d == 13 && m == Month.June && y == 2035 ) - || ( d == 1 && m == Month.June && y == 2036 ) - || ( d == 20 && m == Month.May && y == 2037 ) - || ( d == 9 && m == Month.June && y == 2038 ) - || ( d == 29 && m == Month.May && y == 2039 ) - || ( d == 18 && m == Month.May && y == 2040 ) - || ( d == 5 && m == Month.June && y == 2041 ) - || ( d == 25 && m == Month.May && y == 2042 ) - || ( d == 14 && m == Month.June && y == 2043 ) - || ( d == 1 && m == Month.June && y == 2044 ) - //Fast Day - || ( d == 16 && m == Month.July && y == 2013 ) - || ( d == 5 && m == Month.August && y == 2014 ) - || ( d == 26 && m == Month.July && y == 2015 ) - || ( d == 14 && m == Month.August && y == 2016 ) - || ( d == 1 && m == Month.August && y == 2017 ) - || ( d == 22 && m == Month.July && y == 2018 ) - || ( d == 11 && m == Month.August && y == 2019 ) - || ( d == 30 && m == Month.July && y == 2020 ) - || ( d == 18 && m == Month.July && y == 2021 ) - || ( d == 7 && m == Month.August && y == 2022 ) - || ( d == 27 && m == Month.July && y == 2023 ) - || ( d == 13 && m == Month.August && y == 2024 ) - || ( d == 3 && m == Month.August && y == 2025 ) - || ( d == 23 && m == Month.July && y == 2026 ) - || ( d == 12 && m == Month.August && y == 2027 ) - || ( d == 1 && m == Month.August && y == 2028 ) - || ( d == 22 && m == Month.July && y == 2029 ) - || ( d == 8 && m == Month.August && y == 2030 ) - || ( d == 29 && m == Month.July && y == 2031 ) - || ( d == 18 && m == Month.July && y == 2032 ) - || ( d == 4 && m == Month.August && y == 2033 ) - || ( d == 25 && m == Month.July && y == 2034 ) - || ( d == 14 && m == Month.August && y == 2035 ) - || ( d == 3 && m == Month.August && y == 2036 ) - || ( d == 21 && m == Month.July && y == 2037 ) - || ( d == 10 && m == Month.August && y == 2038 ) - || ( d == 31 && m == Month.July && y == 2039 ) - || ( d == 19 && m == Month.July && y == 2040 ) - || ( d == 6 && m == Month.August && y == 2041 ) - || ( d == 27 && m == Month.July && y == 2042 ) - || ( d == 16 && m == Month.August && y == 2043 ) - || ( d == 2 && m == Month.August && y == 2044 ) - //Jewish New Year - || ( ( d == 4 || d == 5 || d == 6 ) && m == Month.September && y == 2013 ) - || ( ( d == 24 || d == 25 || d == 26 ) && m == Month.September && y == 2014 ) - || ( ( d == 13 || d == 14 || d == 15 ) && m == Month.September && y == 2015 ) - || ( ( d == 2 || d == 3 || d == 4 ) && m == Month.October && y == 2016 ) - || ( ( d == 20 || d == 21 || d == 22 ) && m == Month.September && y == 2017 ) - || ( ( d == 9 || d == 10 || d == 11 ) && m == Month.September && y == 2018 ) - || ( ( ( ( d == 29 || d == 30 ) && m == Month.September ) || ( d == 1 && m == Month.October ) ) && y == 2019 ) - || ( ( d == 19 || d == 20 ) && m == Month.September && y == 2020 ) - || ( ( d == 7 || d == 8 ) && m == Month.September && y == 2021 ) - || ( ( d == 26 || d == 27 ) && m == Month.September && y == 2022 ) - || ( ( d == 16 || d == 17 ) && m == Month.September && y == 2023 ) - || ( ( d == 3 || d == 4 ) && m == Month.October && y == 2024 ) - || ( ( d == 23 || d == 24 ) && m == Month.September && y == 2025 ) - || ( ( d == 12 || d == 13 ) && m == Month.September && y == 2026 ) - || ( ( d == 2 || d == 3 ) && m == Month.October && y == 2027 ) - || ( ( d == 21 || d == 22 ) && m == Month.September && y == 2028 ) - || ( ( d == 10 || d == 11 ) && m == Month.September && y == 2029 ) - || ( ( d == 28 || d == 29 ) && m == Month.September && y == 2030 ) - || ( ( d == 18 || d == 19 ) && m == Month.September && y == 2031 ) - || ( ( d == 6 || d == 7 ) && m == Month.September && y == 2032 ) - || ( ( d == 24 || d == 25 ) && m == Month.September && y == 2033 ) - || ( ( d == 14 || d == 15 ) && m == Month.September && y == 2034 ) - || ( ( d == 4 || d == 5 ) && m == Month.October && y == 2035 ) - || ( ( d == 22 || d == 23 ) && m == Month.September && y == 2036 ) - || ( ( d == 10 || d == 11 ) && m == Month.September && y == 2037 ) - || ( ( ( d == 30 && m == Month.September ) || ( d == 01 && m == Month.October ) ) && y == 2038 ) - || ( ( d == 19 || d == 20 ) && m == Month.September && y == 2039 ) - || ( ( d == 8 || d == 9 ) && m == Month.September && y == 2040 ) - || ( ( d == 26 || d == 27 ) && m == Month.September && y == 2041 ) - || ( ( d == 15 || d == 16 ) && m == Month.September && y == 2042 ) - || ( ( d == 5 || d == 6 ) && m == Month.October && y == 2043 ) - || ( ( d == 22 || d == 23 ) && m == Month.September && y == 2044 ) - //Yom Kippur - || ( ( d == 13 || d == 14 ) && m == Month.September && y == 2013 ) - || ( ( d == 3 || d == 4 ) && m == Month.October && y == 2014 ) - || ( ( d == 22 || d == 23 ) && m == Month.September && y == 2015 ) - || ( ( d == 11 || d == 12 ) && m == Month.October && y == 2016 ) - || ( ( d == 29 || d == 30 ) && m == Month.September && y == 2017 ) - || ( ( d == 18 || d == 19 ) && m == Month.September && y == 2018 ) - || ( ( d == 8 || d == 9 ) && m == Month.October && y == 2019 ) - || ( ( d == 27 || d == 28 ) && m == Month.September && y == 2020 ) - || ( ( d == 15 || d == 16 ) && m == Month.September && y == 2021 ) - || ( ( d == 4 || d == 5 ) && m == Month.October && y == 2022 ) - || ( ( d == 24 || d == 25 ) && m == Month.September && y == 2023 ) - || ( ( d == 11 || d == 12 ) && m == Month.October && y == 2024 ) - || ( ( d == 1 || d == 2 ) && m == Month.October && y == 2025 ) - || ( ( d == 20 || d == 21 ) && m == Month.September && y == 2026 ) - || ( ( d == 10 || d == 11 ) && m == Month.October && y == 2027 ) - || ( ( d == 29 || d == 30 ) && m == Month.September && y == 2028 ) - || ( ( d == 18 || d == 19 ) && m == Month.September && y == 2029 ) - || ( ( d == 6 || d == 7 ) && m == Month.October && y == 2030 ) - || ( ( d == 26 || d == 27 ) && m == Month.September && y == 2031 ) - || ( ( d == 14 || d == 15 ) && m == Month.September && y == 2032 ) - || ( ( d == 2 || d == 3 ) && m == Month.October && y == 2033 ) - || ( ( d == 22 || d == 23 ) && m == Month.September && y == 2034 ) - || ( ( d == 12 || d == 13 ) && m == Month.October && y == 2035 ) - || ( ( ( d == 30 && m == Month.September ) || ( d == 01 && m == Month.October ) ) && y == 2036 ) - || ( ( d == 18 || d == 19 ) && m == Month.September && y == 2037 ) - || ( ( d == 8 || d == 9 ) && m == Month.October && y == 2038 ) - || ( ( d == 27 || d == 28 ) && m == Month.September && y == 2039 ) - || ( ( d == 16 || d == 17 ) && m == Month.September && y == 2040 ) - || ( ( d == 4 || d == 5 ) && m == Month.October && y == 2041 ) - || ( ( d == 23 || d == 24 ) && m == Month.September && y == 2042 ) - || ( ( d == 13 || d == 14 ) && m == Month.October && y == 2043 ) - || ( ( ( d == 30 && m == Month.September ) || ( d == 01 && m == Month.October ) ) && y == 2044 ) - //Sukkoth - || ( ( d == 18 || d == 19 ) && m == Month.September && y == 2013 ) - || ( ( d == 8 || d == 9 ) && m == Month.October && y == 2014 ) - || ( ( d == 27 || d == 28 ) && m == Month.September && y == 2015 ) - || ( ( d == 16 || d == 17 ) && m == Month.October && y == 2016 ) - || ( ( d == 4 || d == 5 ) && m == Month.October && y == 2017 ) - || ( ( d == 23 || d == 24 ) && m == Month.September && y == 2018 ) - || ( ( d == 13 || d == 14 ) && m == Month.October && y == 2019 ) - || ( ( d == 2 || d == 3 ) && m == Month.October && y == 2020 ) - || ( ( d == 20 || d == 21 ) && m == Month.September && y == 2021 ) - || ( ( d == 9 || d == 10 ) && m == Month.October && y == 2022 ) - || ( ( d == 29 || d == 30 ) && m == Month.September && y == 2023 ) - || ( ( d == 16 || d == 17 ) && m == Month.October && y == 2024 ) - || ( ( d == 6 || d == 7 ) && m == Month.October && y == 2025 ) - || ( ( d == 25 || d == 26 ) && m == Month.September && y == 2026 ) - || ( ( d == 15 || d == 16 ) && m == Month.October && y == 2027 ) - || ( ( d == 4 || d == 5 ) && m == Month.October && y == 2028 ) - || ( ( d == 23 || d == 24 ) && m == Month.September && y == 2029 ) - || ( ( d == 11 || d == 12 ) && m == Month.October && y == 2030 ) - || ( ( d == 1 || d == 2 ) && m == Month.October && y == 2031 ) - || ( ( d == 19 || d == 20 ) && m == Month.September && y == 2032 ) - || ( ( d == 7 || d == 8 ) && m == Month.October && y == 2033 ) - || ( ( d == 27 || d == 28 ) && m == Month.September && y == 2034 ) - || ( ( d == 17 || d == 18 ) && m == Month.October && y == 2035 ) - || ( ( d == 5 || d == 6 ) && m == Month.October && y == 2036 ) - || ( ( d == 23 || d == 24 ) && m == Month.September && y == 2037 ) - || ( ( d == 13 || d == 14 ) && m == Month.October && y == 2038 ) - || ( ( d == 2 || d == 3 ) && m == Month.October && y == 2039 ) - || ( ( d == 21 || d == 22 ) && m == Month.September && y == 2040 ) - || ( ( d == 9 || d == 10 ) && m == Month.October && y == 2041 ) - || ( ( d == 28 || d == 29 ) && m == Month.September && y == 2042 ) - || ( ( d == 18 || d == 19 ) && m == Month.October && y == 2043 ) - || ( ( d == 5 || d == 6 ) && m == Month.October && y == 2044 ) - //Simchat Tora - || ( ( d == 25 || d == 26 ) && m == Month.September && y == 2013 ) - || ( ( d == 15 || d == 16 ) && m == Month.October && y == 2014 ) - || ( ( d == 4 || d == 5 ) && m == Month.October && y == 2015 ) - || ( ( d == 23 || d == 24 ) && m == Month.October && y == 2016 ) - || ( ( d == 11 || d == 12 ) && m == Month.October && y == 2017 ) - || ( ( ( d == 30 && m == Month.September ) || ( d == 1 && m == Month.October ) ) && y == 2018 ) - || ( ( d == 20 || d == 21 ) && m == Month.October && y == 2019 ) - || ( ( d == 9 || d == 10 ) && m == Month.October && y == 2020 ) - || ( ( d == 27 || d == 28 ) && m == Month.September && y == 2021 ) - || ( ( d == 16 || d == 17 ) && m == Month.October && y == 2022 ) - || ( ( d == 6 || d == 7 ) && m == Month.October && y == 2023 ) - || ( ( d == 23 || d == 24 ) && m == Month.October && y == 2024 ) - || ( ( d == 13 || d == 14 ) && m == Month.October && y == 2025 ) - || ( ( d == 2 || d == 3 ) && m == Month.October && y == 2026 ) - || ( ( d == 22 || d == 23 ) && m == Month.October && y == 2027 ) - || ( ( d == 11 || d == 12 ) && m == Month.October && y == 2028 ) - || ( ( ( d == 30 && m == Month.September ) || ( d == 1 && m == Month.October ) ) && y == 2029 ) - || ( ( d == 18 || d == 19 ) && m == Month.October && y == 2030 ) - || ( ( d == 8 || d == 9 ) && m == Month.October && y == 2031 ) - || ( ( d == 26 || d == 27 ) && m == Month.September && y == 2032 ) - || ( ( d == 14 || d == 15 ) && m == Month.October && y == 2033 ) - || ( ( d == 4 || d == 5 ) && m == Month.October && y == 2034 ) - || ( ( d == 24 || d == 25 ) && m == Month.October && y == 2035 ) - || ( ( d == 12 || d == 13 ) && m == Month.October && y == 2036 ) - || ( ( ( d == 30 && m == Month.September ) || ( d == 1 && m == Month.October ) ) && y == 2037 ) - || ( ( d == 20 || d == 21 ) && m == Month.October && y == 2038 ) - || ( ( d == 9 || d == 10 ) && m == Month.October && y == 2039 ) - || ( ( d == 28 || d == 29 ) && m == Month.September && y == 2040 ) - || ( ( d == 16 || d == 17 ) && m == Month.October && y == 2041 ) - || ( ( d == 5 || d == 6 ) && m == Month.October && y == 2042 ) - || ( ( d == 25 || d == 26 ) && m == Month.October && y == 2043 ) - || ( ( d == 12 || d == 13 ) && m == Month.October && y == 2044 ) ) + if (isWeekend(w) + //Purim + || (d == 24 && m == Month.February && y == 2013) + || (d == 16 && m == Month.March && y == 2014) + || (d == 05 && m == Month.March && y == 2015) + || (d == 24 && m == Month.March && y == 2016) + || (d == 12 && m == Month.March && y == 2017) + || (d == 1 && m == Month.March && y == 2018) + || (d == 21 && m == Month.March && y == 2019) + || (d == 10 && m == Month.March && y == 2020) + || (d == 26 && m == Month.February && y == 2021) + || (d == 17 && m == Month.March && y == 2022) + || (d == 7 && m == Month.March && y == 2023) + || (d == 24 && m == Month.March && y == 2024) + || (d == 14 && m == Month.March && y == 2025) + || (d == 3 && m == Month.March && y == 2026) + || (d == 23 && m == Month.March && y == 2027) + || (d == 12 && m == Month.March && y == 2028) + || (d == 1 && m == Month.March && y == 2029) + || (d == 19 && m == Month.March && y == 2030) + || (d == 9 && m == Month.March && y == 2031) + || (d == 26 && m == Month.February && y == 2032) + || (d == 15 && m == Month.March && y == 2033) + || (d == 5 && m == Month.March && y == 2034) + || (d == 25 && m == Month.March && y == 2035) + || (d == 13 && m == Month.March && y == 2036) + || (d == 1 && m == Month.March && y == 2037) + || (d == 21 && m == Month.March && y == 2038) + || (d == 10 && m == Month.March && y == 2039) + || (d == 28 && m == Month.February && y == 2040) + || (d == 17 && m == Month.March && y == 2041) + || (d == 6 && m == Month.March && y == 2042) + || (d == 26 && m == Month.March && y == 2043) + || (d == 13 && m == Month.March && y == 2044) + //Passover I and Passover VII + || ((((d == 25 || d == 26 || d == 31) && m == Month.March) || (d == 1 && m == Month.April)) && y == 2013) + || ((d == 14 || d == 15 || d == 20 || d == 21) && m == Month.April && y == 2014) + || ((d == 3 || d == 4 || d == 9 || d == 10) && m == Month.April && y == 2015) + || ((d == 22 || d == 23 || d == 28 || d == 29) && m == Month.April && y == 2016) + || ((d == 10 || d == 11 || d == 16 || d == 17) && m == Month.April && y == 2017) + || (((d == 31 && m == Month.March) || ((d == 5 || d == 6) && m == Month.April)) && y == 2018) + || ((d == 20 || d == 25 || d == 26) && m == Month.April && y == 2019) + || ((d == 8 || d == 9 || d == 14 || d == 15) && m == Month.April && y == 2020) + || (((d == 28 && m == Month.March) || (d == 3 && m == Month.April)) && y == 2021) + || ((d == 16 || d == 22) && m == Month.April && y == 2022) + || ((d == 6 || d == 12) && m == Month.April && y == 2023) + || ((d == 23 || d == 29) && m == Month.April && y == 2024) + || ((d == 13 || d == 19) && m == Month.April && y == 2025) + || ((d == 2 || d == 8) && m == Month.April && y == 2026) + || ((d == 22 || d == 28) && m == Month.April && y == 2027) + || ((d == 11 || d == 17) && m == Month.April && y == 2028) + || (((d == 31 && m == Month.March) || (d == 6 && m == Month.April)) && y == 2029) + || ((d == 18 || d == 24) && m == Month.April && y == 2030) + || ((d == 8 || d == 14) && m == Month.April && y == 2031) + || (((d == 27 && m == Month.March) || (d == 2 && m == Month.April)) && y == 2032) + || ((d == 14 || d == 20) && m == Month.April && y == 2033) + || ((d == 4 || d == 10) && m == Month.April && y == 2034) + || ((d == 24 || d == 30) && m == Month.April && y == 2035) + || ((d == 12 || d == 18) && m == Month.April && y == 2036) + || (((d == 31 && m == Month.March) || (d == 6 && m == Month.April)) && y == 2037) + || ((d == 20 || d == 26) && m == Month.April && y == 2038) + || ((d == 9 || d == 15) && m == Month.April && y == 2039) + || (((d == 29 && m == Month.March) || (d == 4 && m == Month.April)) && y == 2040) + || ((d == 16 || d == 22) && m == Month.April && y == 2041) + || ((d == 5 || d == 11) && m == Month.April && y == 2042) + || (((d == 25 && m == Month.April) || (d == 1 && m == Month.May)) && y == 2043) + || ((d == 12 || d == 18) && m == Month.April && y == 2044) + //Memorial and Indipendence Day + || ((d == 15 || d == 16) && m == Month.April && y == 2013) + || ((d == 5 || d == 6) && m == Month.May && y == 2014) + || ((d == 22 || d == 23) && m == Month.April && y == 2015) + || ((d == 11 || d == 12) && m == Month.May && y == 2016) + || ((d == 1 || d == 2) && m == Month.May && y == 2017) + || ((d == 18 || d == 19) && m == Month.April && y == 2018) + || ((d == 8 || d == 9) && m == Month.May && y == 2019) + || ((d == 28 || d == 29) && m == Month.April && y == 2020) + || ((d == 14 || d == 15) && m == Month.April && y == 2021) + || ((d == 4 || d == 5) && m == Month.May && y == 2022) + || ((d == 25 || d == 26) && m == Month.April && y == 2023) + || ((d == 13 || d == 14) && m == Month.May && y == 2024) + || (((d == 30 && m == Month.April) || (d == 1 && m == Month.May)) && y == 2025) + || ((d == 21 || d == 22) && m == Month.April && y == 2026) + || ((d == 11 || d == 12) && m == Month.May && y == 2027) + || ((d == 1 || d == 2) && m == Month.May && y == 2028) + || ((d == 18 || d == 19) && m == Month.April && y == 2029) + || ((d == 7 || d == 8) && m == Month.May && y == 2030) + || ((d == 28 || d == 29) && m == Month.April && y == 2031) + || ((d == 14 || d == 15) && m == Month.April && y == 2032) + || ((d == 3 || d == 4) && m == Month.May && y == 2033) + || ((d == 24 || d == 25) && m == Month.April && y == 2034) + || ((d == 14 || d == 15) && m == Month.May && y == 2035) + || (((d == 30 && m == Month.April) || (d == 1 && m == Month.May)) && y == 2036) + || ((d == 20 || d == 21) && m == Month.April && y == 2037) + || ((d == 9 || d == 10) && m == Month.May && y == 2038) + || ((d == 27 || d == 28) && m == Month.April && y == 2039) + || ((d == 17 || d == 18) && m == Month.April && y == 2040) + || ((d == 6 || d == 7) && m == Month.May && y == 2041) + || ((d == 23 || d == 24) && m == Month.April && y == 2042) + || ((d == 13 || d == 14) && m == Month.May && y == 2043) + || ((d == 2 || d == 3) && m == Month.May && y == 2044) + //Pentecost (Shavuot) + || ((d == 14 || d == 15) && m == Month.May && y == 2013) + || ((d == 3 || d == 4) && m == Month.June && y == 2014) + || ((d == 23 || d == 24) && m == Month.May && y == 2015) + || ((d == 11 || d == 12) && m == Month.June && y == 2016) + || ((d == 30 || d == 31) && m == Month.May && y == 2017) + || ((d == 19 || d == 20) && m == Month.May && y == 2018) + || ((d == 8 || d == 9) && m == Month.June && y == 2019) + || ((d == 28 || d == 29) && m == Month.May && y == 2020) + || (d == 17 && m == Month.May && y == 2021) + || (d == 5 && m == Month.June && y == 2022) + || (d == 26 && m == Month.May && y == 2023) + || (d == 12 && m == Month.June && y == 2024) + || (d == 2 && m == Month.June && y == 2025) + || (d == 22 && m == Month.May && y == 2026) + || (d == 11 && m == Month.June && y == 2027) + || (d == 31 && m == Month.May && y == 2028) + || (d == 20 && m == Month.May && y == 2029) + || (d == 7 && m == Month.June && y == 2030) + || (d == 28 && m == Month.May && y == 2031) + || (d == 16 && m == Month.May && y == 2032) + || (d == 3 && m == Month.June && y == 2033) + || (d == 24 && m == Month.May && y == 2034) + || (d == 13 && m == Month.June && y == 2035) + || (d == 1 && m == Month.June && y == 2036) + || (d == 20 && m == Month.May && y == 2037) + || (d == 9 && m == Month.June && y == 2038) + || (d == 29 && m == Month.May && y == 2039) + || (d == 18 && m == Month.May && y == 2040) + || (d == 5 && m == Month.June && y == 2041) + || (d == 25 && m == Month.May && y == 2042) + || (d == 14 && m == Month.June && y == 2043) + || (d == 1 && m == Month.June && y == 2044) + //Fast Day + || (d == 16 && m == Month.July && y == 2013) + || (d == 5 && m == Month.August && y == 2014) + || (d == 26 && m == Month.July && y == 2015) + || (d == 14 && m == Month.August && y == 2016) + || (d == 1 && m == Month.August && y == 2017) + || (d == 22 && m == Month.July && y == 2018) + || (d == 11 && m == Month.August && y == 2019) + || (d == 30 && m == Month.July && y == 2020) + || (d == 18 && m == Month.July && y == 2021) + || (d == 7 && m == Month.August && y == 2022) + || (d == 27 && m == Month.July && y == 2023) + || (d == 13 && m == Month.August && y == 2024) + || (d == 3 && m == Month.August && y == 2025) + || (d == 23 && m == Month.July && y == 2026) + || (d == 12 && m == Month.August && y == 2027) + || (d == 1 && m == Month.August && y == 2028) + || (d == 22 && m == Month.July && y == 2029) + || (d == 8 && m == Month.August && y == 2030) + || (d == 29 && m == Month.July && y == 2031) + || (d == 18 && m == Month.July && y == 2032) + || (d == 4 && m == Month.August && y == 2033) + || (d == 25 && m == Month.July && y == 2034) + || (d == 14 && m == Month.August && y == 2035) + || (d == 3 && m == Month.August && y == 2036) + || (d == 21 && m == Month.July && y == 2037) + || (d == 10 && m == Month.August && y == 2038) + || (d == 31 && m == Month.July && y == 2039) + || (d == 19 && m == Month.July && y == 2040) + || (d == 6 && m == Month.August && y == 2041) + || (d == 27 && m == Month.July && y == 2042) + || (d == 16 && m == Month.August && y == 2043) + || (d == 2 && m == Month.August && y == 2044) + //Jewish New Year + || ((d == 4 || d == 5 || d == 6) && m == Month.September && y == 2013) + || ((d == 24 || d == 25 || d == 26) && m == Month.September && y == 2014) + || ((d == 13 || d == 14 || d == 15) && m == Month.September && y == 2015) + || ((d == 2 || d == 3 || d == 4) && m == Month.October && y == 2016) + || ((d == 20 || d == 21 || d == 22) && m == Month.September && y == 2017) + || ((d == 9 || d == 10 || d == 11) && m == Month.September && y == 2018) + || ((((d == 29 || d == 30) && m == Month.September) || (d == 1 && m == Month.October)) && y == 2019) + || ((d == 19 || d == 20) && m == Month.September && y == 2020) + || ((d == 7 || d == 8) && m == Month.September && y == 2021) + || ((d == 26 || d == 27) && m == Month.September && y == 2022) + || ((d == 16 || d == 17) && m == Month.September && y == 2023) + || ((d == 3 || d == 4) && m == Month.October && y == 2024) + || ((d == 23 || d == 24) && m == Month.September && y == 2025) + || ((d == 12 || d == 13) && m == Month.September && y == 2026) + || ((d == 2 || d == 3) && m == Month.October && y == 2027) + || ((d == 21 || d == 22) && m == Month.September && y == 2028) + || ((d == 10 || d == 11) && m == Month.September && y == 2029) + || ((d == 28 || d == 29) && m == Month.September && y == 2030) + || ((d == 18 || d == 19) && m == Month.September && y == 2031) + || ((d == 6 || d == 7) && m == Month.September && y == 2032) + || ((d == 24 || d == 25) && m == Month.September && y == 2033) + || ((d == 14 || d == 15) && m == Month.September && y == 2034) + || ((d == 4 || d == 5) && m == Month.October && y == 2035) + || ((d == 22 || d == 23) && m == Month.September && y == 2036) + || ((d == 10 || d == 11) && m == Month.September && y == 2037) + || (((d == 30 && m == Month.September) || (d == 01 && m == Month.October)) && y == 2038) + || ((d == 19 || d == 20) && m == Month.September && y == 2039) + || ((d == 8 || d == 9) && m == Month.September && y == 2040) + || ((d == 26 || d == 27) && m == Month.September && y == 2041) + || ((d == 15 || d == 16) && m == Month.September && y == 2042) + || ((d == 5 || d == 6) && m == Month.October && y == 2043) + || ((d == 22 || d == 23) && m == Month.September && y == 2044) + //Yom Kippur + || ((d == 13 || d == 14) && m == Month.September && y == 2013) + || ((d == 3 || d == 4) && m == Month.October && y == 2014) + || ((d == 22 || d == 23) && m == Month.September && y == 2015) + || ((d == 11 || d == 12) && m == Month.October && y == 2016) + || ((d == 29 || d == 30) && m == Month.September && y == 2017) + || ((d == 18 || d == 19) && m == Month.September && y == 2018) + || ((d == 8 || d == 9) && m == Month.October && y == 2019) + || ((d == 27 || d == 28) && m == Month.September && y == 2020) + || ((d == 15 || d == 16) && m == Month.September && y == 2021) + || ((d == 4 || d == 5) && m == Month.October && y == 2022) + || ((d == 24 || d == 25) && m == Month.September && y == 2023) + || ((d == 11 || d == 12) && m == Month.October && y == 2024) + || ((d == 1 || d == 2) && m == Month.October && y == 2025) + || ((d == 20 || d == 21) && m == Month.September && y == 2026) + || ((d == 10 || d == 11) && m == Month.October && y == 2027) + || ((d == 29 || d == 30) && m == Month.September && y == 2028) + || ((d == 18 || d == 19) && m == Month.September && y == 2029) + || ((d == 6 || d == 7) && m == Month.October && y == 2030) + || ((d == 26 || d == 27) && m == Month.September && y == 2031) + || ((d == 14 || d == 15) && m == Month.September && y == 2032) + || ((d == 2 || d == 3) && m == Month.October && y == 2033) + || ((d == 22 || d == 23) && m == Month.September && y == 2034) + || ((d == 12 || d == 13) && m == Month.October && y == 2035) + || (((d == 30 && m == Month.September) || (d == 01 && m == Month.October)) && y == 2036) + || ((d == 18 || d == 19) && m == Month.September && y == 2037) + || ((d == 8 || d == 9) && m == Month.October && y == 2038) + || ((d == 27 || d == 28) && m == Month.September && y == 2039) + || ((d == 16 || d == 17) && m == Month.September && y == 2040) + || ((d == 4 || d == 5) && m == Month.October && y == 2041) + || ((d == 23 || d == 24) && m == Month.September && y == 2042) + || ((d == 13 || d == 14) && m == Month.October && y == 2043) + || (((d == 30 && m == Month.September) || (d == 01 && m == Month.October)) && y == 2044) + //Sukkoth + || ((d == 18 || d == 19) && m == Month.September && y == 2013) + || ((d == 8 || d == 9) && m == Month.October && y == 2014) + || ((d == 27 || d == 28) && m == Month.September && y == 2015) + || ((d == 16 || d == 17) && m == Month.October && y == 2016) + || ((d == 4 || d == 5) && m == Month.October && y == 2017) + || ((d == 23 || d == 24) && m == Month.September && y == 2018) + || ((d == 13 || d == 14) && m == Month.October && y == 2019) + || ((d == 2 || d == 3) && m == Month.October && y == 2020) + || ((d == 20 || d == 21) && m == Month.September && y == 2021) + || ((d == 9 || d == 10) && m == Month.October && y == 2022) + || ((d == 29 || d == 30) && m == Month.September && y == 2023) + || ((d == 16 || d == 17) && m == Month.October && y == 2024) + || ((d == 6 || d == 7) && m == Month.October && y == 2025) + || ((d == 25 || d == 26) && m == Month.September && y == 2026) + || ((d == 15 || d == 16) && m == Month.October && y == 2027) + || ((d == 4 || d == 5) && m == Month.October && y == 2028) + || ((d == 23 || d == 24) && m == Month.September && y == 2029) + || ((d == 11 || d == 12) && m == Month.October && y == 2030) + || ((d == 1 || d == 2) && m == Month.October && y == 2031) + || ((d == 19 || d == 20) && m == Month.September && y == 2032) + || ((d == 7 || d == 8) && m == Month.October && y == 2033) + || ((d == 27 || d == 28) && m == Month.September && y == 2034) + || ((d == 17 || d == 18) && m == Month.October && y == 2035) + || ((d == 5 || d == 6) && m == Month.October && y == 2036) + || ((d == 23 || d == 24) && m == Month.September && y == 2037) + || ((d == 13 || d == 14) && m == Month.October && y == 2038) + || ((d == 2 || d == 3) && m == Month.October && y == 2039) + || ((d == 21 || d == 22) && m == Month.September && y == 2040) + || ((d == 9 || d == 10) && m == Month.October && y == 2041) + || ((d == 28 || d == 29) && m == Month.September && y == 2042) + || ((d == 18 || d == 19) && m == Month.October && y == 2043) + || ((d == 5 || d == 6) && m == Month.October && y == 2044) + //Simchat Tora + || ((d == 25 || d == 26) && m == Month.September && y == 2013) + || ((d == 15 || d == 16) && m == Month.October && y == 2014) + || ((d == 4 || d == 5) && m == Month.October && y == 2015) + || ((d == 23 || d == 24) && m == Month.October && y == 2016) + || ((d == 11 || d == 12) && m == Month.October && y == 2017) + || (((d == 30 && m == Month.September) || (d == 1 && m == Month.October)) && y == 2018) + || ((d == 20 || d == 21) && m == Month.October && y == 2019) + || ((d == 9 || d == 10) && m == Month.October && y == 2020) + || ((d == 27 || d == 28) && m == Month.September && y == 2021) + || ((d == 16 || d == 17) && m == Month.October && y == 2022) + || ((d == 6 || d == 7) && m == Month.October && y == 2023) + || ((d == 23 || d == 24) && m == Month.October && y == 2024) + || ((d == 13 || d == 14) && m == Month.October && y == 2025) + || ((d == 2 || d == 3) && m == Month.October && y == 2026) + || ((d == 22 || d == 23) && m == Month.October && y == 2027) + || ((d == 11 || d == 12) && m == Month.October && y == 2028) + || (((d == 30 && m == Month.September) || (d == 1 && m == Month.October)) && y == 2029) + || ((d == 18 || d == 19) && m == Month.October && y == 2030) + || ((d == 8 || d == 9) && m == Month.October && y == 2031) + || ((d == 26 || d == 27) && m == Month.September && y == 2032) + || ((d == 14 || d == 15) && m == Month.October && y == 2033) + || ((d == 4 || d == 5) && m == Month.October && y == 2034) + || ((d == 24 || d == 25) && m == Month.October && y == 2035) + || ((d == 12 || d == 13) && m == Month.October && y == 2036) + || (((d == 30 && m == Month.September) || (d == 1 && m == Month.October)) && y == 2037) + || ((d == 20 || d == 21) && m == Month.October && y == 2038) + || ((d == 9 || d == 10) && m == Month.October && y == 2039) + || ((d == 28 || d == 29) && m == Month.September && y == 2040) + || ((d == 16 || d == 17) && m == Month.October && y == 2041) + || ((d == 5 || d == 6) && m == Month.October && y == 2042) + || ((d == 25 || d == 26) && m == Month.October && y == 2043) + || ((d == 12 || d == 13) && m == Month.October && y == 2044)) return false; return true; } - + } } diff --git a/src/QLNet/Time/Calendars/Italy.cs b/src/QLNet/Time/Calendars/Italy.cs new file mode 100644 index 000000000..fa71d96b9 --- /dev/null +++ b/src/QLNet/Time/Calendars/Italy.cs @@ -0,0 +1,174 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! Italian calendars + /*! Public holidays: +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st
  • +
  • Epiphany, January 6th
  • +
  • Easter Monday
  • +
  • Liberation Day, April 25th
  • +
  • Labour Day, May 1st
  • +
  • Republic Day, June 2nd (since 2000)
  • +
  • Assumption, August 15th
  • +
  • All Saint's Day, November 1st
  • +
  • Immaculate Conception Day, December 8th
  • +
  • Christmas Day, December 25th
  • +
  • St. Stephen's Day, December 26th
  • +
+ + Holidays for the stock exchange (data from http://www.borsaitalia.it): +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st
  • +
  • Good Friday
  • +
  • Easter Monday
  • +
  • Labour Day, May 1st
  • +
  • Assumption, August 15th
  • +
  • Christmas' Eve, December 24th
  • +
  • Christmas, December 25th
  • +
  • St. Stephen, December 26th
  • +
  • New Year's Eve, December 31st
  • +
+ + \ingroup calendars + + \test the correctness of the returned results is tested against a + list of known holidays. + */ + public class Italy : Calendar + { + //! Italian calendars + public enum Market + { + Settlement, //!< generic settlement calendar + Exchange //!< Milan stock-exchange calendar + } + + public Italy() : this(Market.Settlement) { } + public Italy(Market m) + : base() + { + // all calendar instances on the same market share the same + // implementation instance + switch (m) + { + case Market.Settlement: + calendar_ = Settlement.Singleton; + break; + case Market.Exchange: + calendar_ = Exchange.Singleton; + break; + default: + throw new ArgumentException("Unknown market: " + m); + } + } + + + class Settlement : Calendar.WesternImpl + { + public static readonly Settlement Singleton = new Settlement(); + private Settlement() { } + + public override string name() { return "Italian settlement"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Epiphany + || (d == 6 && m == Month.January) + // Easter Monday + || (dd == em) + // Liberation Day + || (d == 25 && m == Month.April) + // Labour Day + || (d == 1 && m == Month.May) + // Republic Day + || (d == 2 && m == Month.June && y >= 2000) + // Assumption + || (d == 15 && m == Month.August) + // All Saints' Day + || (d == 1 && m == Month.November) + // Immaculate Conception + || (d == 8 && m == Month.December) + // Christmas + || (d == 25 && m == Month.December) + // St. Stephen + || (d == 26 && m == Month.December) + // December 31st, 1999 only + || (d == 31 && m == Month.December && y == 1999)) + return false; + return true; + } + } + + class Exchange : Calendar.WesternImpl + { + public static readonly Exchange Singleton = new Exchange(); + private Exchange() { } + + public override string name() { return "Milan stock exchange"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // Labour Day + || (d == 1 && m == Month.May) + // Assumption + || (d == 15 && m == Month.August) + // Christmas' Eve + || (d == 24 && m == Month.December) + // Christmas + || (d == 25 && m == Month.December) + // St. Stephen + || (d == 26 && m == Month.December) + // New Year's Eve + || (d == 31 && m == Month.December)) + return false; + return true; + } + } + } + +} diff --git a/src/QLNet/Time/Calendars/Japan.cs b/src/QLNet/Time/Calendars/Japan.cs new file mode 100644 index 000000000..c7017dbc4 --- /dev/null +++ b/src/QLNet/Time/Calendars/Japan.cs @@ -0,0 +1,164 @@ +/* + Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! Japanese calendar + /*! Holidays: +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st
  • +
  • Bank Holiday, January 2nd
  • +
  • Bank Holiday, January 3rd
  • +
  • Coming of Age Day, 2nd Monday in January
  • +
  • National Foundation Day, February 11th
  • +
  • Vernal Equinox
  • +
  • Greenery Day, April 29th
  • +
  • Constitution Memorial Day, May 3rd
  • +
  • Holiday for a Nation, May 4th
  • +
  • Children's Day, May 5th
  • +
  • Marine Day, 3rd Monday in July
  • +
  • Mountain Day, August 11th (from 2016 onwards)
  • +
  • Respect for the Aged Day, 3rd Monday in September
  • +
  • Autumnal Equinox
  • +
  • Health and Sports Day, 2nd Monday in October
  • +
  • National Culture Day, November 3rd
  • +
  • Labor Thanksgiving Day, November 23rd
  • +
  • Emperor's Birthday, December 23rd
  • +
  • Bank Holiday, December 31st
  • +
  • a few one-shot holidays
  • +
+ Holidays falling on a Sunday are observed on the Monday following + except for the bank holidays associated with the new year. + + \ingroup calendars + */ + public class Japan : Calendar + { + public Japan() : base(Impl.Singleton) { } + + class Impl : Calendar + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Japan"; } + public override bool isWeekend(DayOfWeek w) + { + return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; + } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + + // equinox calculation + double exact_vernal_equinox_time = 20.69115; + double exact_autumnal_equinox_time = 23.09; + double diff_per_year = 0.242194; + double moving_amount = (y - 2000) * diff_per_year; + int number_of_leap_years = (y - 2000) / 4 + (y - 2000) / 100 - (y - 2000) / 400; + int ve = (int)(exact_vernal_equinox_time + moving_amount - number_of_leap_years); // vernal equinox day + int ae = (int)(exact_autumnal_equinox_time + moving_amount - number_of_leap_years); // autumnal equinox day + // checks + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Bank Holiday + || (d == 2 && m == Month.January) + // Bank Holiday + || (d == 3 && m == Month.January) + // Coming of Age Day (2nd Monday in January), + // was January 15th until 2000 + || (w == DayOfWeek.Monday && (d >= 8 && d <= 14) && m == Month.January + && y >= 2000) + || ((d == 15 || (d == 16 && w == DayOfWeek.Monday)) && m == Month.January + && y < 2000) + // National Foundation Day + || ((d == 11 || (d == 12 && w == DayOfWeek.Monday)) && m == Month.February) + // Vernal Equinox + || ((d == ve || (d == ve + 1 && w == DayOfWeek.Monday)) && m == Month.March) + // Greenery Day + || ((d == 29 || (d == 30 && w == DayOfWeek.Monday)) && m == Month.April) + // Constitution Memorial Day + || (d == 3 && m == Month.May) + // Holiday for a Nation + || (d == 4 && m == Month.May) + // Children's Day + || (d == 5 && m == Month.May) + // any of the three above observed later if on Saturday or Sunday + || (d == 6 && m == Month.May && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday || w == DayOfWeek.Wednesday)) + // Marine Day (3rd Monday in July), + // was July 20th until 2003, not a holiday before 1996 + || (w == DayOfWeek.Monday && (d >= 15 && d <= 21) && m == Month.July + && y >= 2003) + || ((d == 20 || (d == 21 && w == DayOfWeek.Monday)) && m == Month.July + && y >= 1996 && y < 2003) + // Mountain Day (from 2016) + || ((d == 11 || (d == 12 && w == DayOfWeek.Monday)) && m == Month.August && y >= 2016) + // Respect for the Aged Day (3rd Monday in September), + // was September 15th until 2003 + || (w == DayOfWeek.Monday && (d >= 15 && d <= 21) && m == Month.September + && y >= 2003) + || ((d == 15 || (d == 16 && w == DayOfWeek.Monday)) && m == Month.September + && y < 2003) + // If a single day falls between Respect for the Aged Day + // and the Autumnal Equinox, it is holiday + || (w == DayOfWeek.Tuesday && d + 1 == ae && d >= 16 && d <= 22 + && m == Month.September && y >= 2003) + // Autumnal Equinox + || ((d == ae || (d == ae + 1 && w == DayOfWeek.Monday)) && m == Month.September) + // Health and Sports Day (2nd Monday in October), + // was October 10th until 2000 + || (w == DayOfWeek.Monday && (d >= 8 && d <= 14) && m == Month.October + && y >= 2000) + || ((d == 10 || (d == 11 && w == DayOfWeek.Monday)) && m == Month.October + && y < 2000) + // National Culture Day + || ((d == 3 || (d == 4 && w == DayOfWeek.Monday)) && m == Month.November) + // Labor Thanksgiving Day + || ((d == 23 || (d == 24 && w == DayOfWeek.Monday)) && m == Month.November) + // Emperor's Birthday + || ((d == 23 || (d == 24 && w == DayOfWeek.Monday)) && m == Month.December + && y >= 1989) + // Bank Holiday + || (d == 31 && m == Month.December) + // one-shot holidays + // Marriage of Prince Akihito + || (d == 10 && m == Month.April && y == 1959) + // Rites of Imperial Funeral + || (d == 24 && m == Month.February && y == 1989) + // Enthronement Ceremony + || (d == 12 && m == Month.November && y == 1990) + // Marriage of Prince Naruhito + || (d == 9 && m == Month.June && y == 1993)) + return false; + return true; + } + } + } +} + diff --git a/src/QLNet/Time/Calendars/JointCalendar.cs b/src/QLNet/Time/Calendars/JointCalendar.cs index b2d3d31c9..7771ac10d 100644 --- a/src/QLNet/Time/Calendars/JointCalendar.cs +++ b/src/QLNet/Time/Calendars/JointCalendar.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,112 +20,127 @@ under the terms of the QLNet license. You should have received a using System.Collections.Generic; using System.Linq; -namespace QLNet { - public class JointCalendar : Calendar { - //! rules for joining calendars - public enum JointCalendarRule { - JoinHolidays, /*!< A date is a holiday for the joint calendar if it is a holiday +namespace QLNet +{ + public class JointCalendar : Calendar + { + //! rules for joining calendars + public enum JointCalendarRule + { + JoinHolidays, /*!< A date is a holiday for the joint calendar if it is a holiday for any of the given calendars */ - JoinBusinessDays /*!< A date is a business day for the joint calendar if it is a business day + JoinBusinessDays /*!< A date is a business day for the joint calendar if it is a business day for any of the given calendars */ - }; + } - private class Impl : Calendar { - private JointCalendarRule rule_; - private List calendars_ = new List(); + private class Impl : Calendar + { + private JointCalendarRule rule_; + private List calendars_ = new List(); - public Impl(Calendar c1, Calendar c2, JointCalendarRule r) { - rule_ = r; - calendars_.Add(c1); - calendars_.Add(c2); - } - public Impl(Calendar c1, Calendar c2, Calendar c3, JointCalendarRule r) { - rule_ = r; - calendars_.Add(c1); - calendars_.Add(c2); - calendars_.Add(c3); - } - public Impl(Calendar c1, Calendar c2, Calendar c3, Calendar c4, JointCalendarRule r) { - rule_ = r; - calendars_.Add(c1); - calendars_.Add(c2); - calendars_.Add(c3); - calendars_.Add(c4); - } + public Impl(Calendar c1, Calendar c2, JointCalendarRule r) + { + rule_ = r; + calendars_.Add(c1); + calendars_.Add(c2); + } + public Impl(Calendar c1, Calendar c2, Calendar c3, JointCalendarRule r) + { + rule_ = r; + calendars_.Add(c1); + calendars_.Add(c2); + calendars_.Add(c3); + } + public Impl(Calendar c1, Calendar c2, Calendar c3, Calendar c4, JointCalendarRule r) + { + rule_ = r; + calendars_.Add(c1); + calendars_.Add(c2); + calendars_.Add(c3); + calendars_.Add(c4); + } - public override string name() { - string result = ""; - switch (rule_) { - case JointCalendarRule.JoinHolidays: - result += "JoinHolidays("; - break; - case JointCalendarRule.JoinBusinessDays: - result += "JoinBusinessDays("; - break; - default: - Utils.QL_FAIL("unknown joint calendar rule"); - break; - } - result += calendars_.First().name(); - for(int i = 1; i < calendars_.Count; i++) - result += ", " + calendars_[i].name(); - result += ")"; - return result; + public override string name() + { + string result = ""; + switch (rule_) + { + case JointCalendarRule.JoinHolidays: + result += "JoinHolidays("; + break; + case JointCalendarRule.JoinBusinessDays: + result += "JoinBusinessDays("; + break; + default: + Utils.QL_FAIL("unknown joint calendar rule"); + break; } + result += calendars_.First().name(); + for (int i = 1; i < calendars_.Count; i++) + result += ", " + calendars_[i].name(); + result += ")"; + return result; + } - public override bool isWeekend(DayOfWeek w) { - switch (rule_) { - case JointCalendarRule.JoinHolidays: - foreach(Calendar c in calendars_) - if (c.isWeekend(w)) return true; - return false; - case JointCalendarRule.JoinBusinessDays: - foreach(Calendar c in calendars_) - if (c.isWeekend(w)) return false; + public override bool isWeekend(DayOfWeek w) + { + switch (rule_) + { + case JointCalendarRule.JoinHolidays: + foreach (Calendar c in calendars_) + if (c.isWeekend(w)) return true; - default: - Utils.QL_FAIL("unknown joint calendar rule"); + return false; + case JointCalendarRule.JoinBusinessDays: + foreach (Calendar c in calendars_) + if (c.isWeekend(w)) return false; - } + return true; + default: + Utils.QL_FAIL("unknown joint calendar rule"); + return false; } + } - public override bool isBusinessDay(Date date) { - switch (rule_) { - case JointCalendarRule.JoinHolidays: - foreach (Calendar c in calendars_) - if (c.isHoliday(date)) - return false; - return true; - case JointCalendarRule.JoinBusinessDays: - foreach (Calendar c in calendars_) - if (c.isBusinessDay(date)) - return true; + public override bool isBusinessDay(Date date) + { + switch (rule_) + { + case JointCalendarRule.JoinHolidays: + foreach (Calendar c in calendars_) + if (c.isHoliday(date)) return false; - default: - Utils.QL_FAIL("unknown joint calendar rule"); - return false; - } + return true; + case JointCalendarRule.JoinBusinessDays: + foreach (Calendar c in calendars_) + if (c.isBusinessDay(date)) + return true; + return false; + default: + Utils.QL_FAIL("unknown joint calendar rule"); + return false; } - } + } + } - //! Joint calendar - /*! Depending on the chosen rule, this calendar has a set of business days given by either the union or the intersection - of the sets of business days of the given calendars. - \test the correctness of the returned results is tested by reproducing the calculations. */ - public JointCalendar(Calendar c1, Calendar c2) - : this(c1, c2, JointCalendarRule.JoinHolidays) { } - public JointCalendar(Calendar c1, Calendar c2, JointCalendarRule r) - : base(new Impl(c1,c2,r)) { } + //! Joint calendar + /*! Depending on the chosen rule, this calendar has a set of business days given by either the union or the intersection + of the sets of business days of the given calendars. + \test the correctness of the returned results is tested by reproducing the calculations. */ + public JointCalendar(Calendar c1, Calendar c2) + : this(c1, c2, JointCalendarRule.JoinHolidays) { } + public JointCalendar(Calendar c1, Calendar c2, JointCalendarRule r) + : base(new Impl(c1, c2, r)) { } - public JointCalendar(Calendar c1, Calendar c2, Calendar c3) - : this(c1, c2, c3, JointCalendarRule.JoinHolidays) { } - public JointCalendar(Calendar c1, Calendar c2, Calendar c3, JointCalendarRule r) - : base(new Impl(c1,c2,c3,r)) { } + public JointCalendar(Calendar c1, Calendar c2, Calendar c3) + : this(c1, c2, c3, JointCalendarRule.JoinHolidays) { } + public JointCalendar(Calendar c1, Calendar c2, Calendar c3, JointCalendarRule r) + : base(new Impl(c1, c2, c3, r)) { } - public JointCalendar(Calendar c1, Calendar c2, Calendar c3, Calendar c4) - : this(c1, c2, c3, c4, JointCalendarRule.JoinHolidays) { } - public JointCalendar(Calendar c1, Calendar c2, Calendar c3, Calendar c4, JointCalendarRule r) - : base(new Impl(c1,c2,c3,c4,r)) { } - } + public JointCalendar(Calendar c1, Calendar c2, Calendar c3, Calendar c4) + : this(c1, c2, c3, c4, JointCalendarRule.JoinHolidays) { } + public JointCalendar(Calendar c1, Calendar c2, Calendar c3, Calendar c4, JointCalendarRule r) + : base(new Impl(c1, c2, c3, c4, r)) { } + } } diff --git a/src/QLNet/Time/Calendars/Mexico.cs b/src/QLNet/Time/Calendars/Mexico.cs new file mode 100644 index 000000000..90c285166 --- /dev/null +++ b/src/QLNet/Time/Calendars/Mexico.cs @@ -0,0 +1,92 @@ +/* + Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! %Mexican calendars + /*! Holidays for the Mexican stock exchange + (data from ): +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st
  • +
  • Constitution Day, first Monday in February (February 5th before 2006)
  • +
  • Birthday of Benito Juarez, third Monday in February (March 21st before 2006)
  • +
  • Holy Thursday
  • +
  • Good Friday
  • +
  • Labour Day, May 1st
  • +
  • National Day, September 16th
  • +
  • Revolution Day, third Monday in November (November 20th before 2006)
  • +
  • Our Lady of Guadalupe, December 12th
  • +
  • Christmas, December 25th
  • +
+ + \ingroup calendars + */ + public class Mexico : Calendar + { + public Mexico() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Mexican stock exchange"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Constitution Day + || (y <= 2005 && d == 5 && m == Month.February) + || (y >= 2006 && d <= 7 && w == DayOfWeek.Monday && m == Month.February) + // Birthday of Benito Juarez + || (y <= 2005 && d == 21 && m == Month.March) + || (y >= 2006 && (d >= 15 && d <= 21) && w == DayOfWeek.Monday && m == Month.March) + // Holy Thursday + || (dd == em - 4) + // Good Friday + || (dd == em - 3) + // Labour Day + || (d == 1 && m == Month.May) + // National Day + || (d == 16 && m == Month.September) + // Revolution Day + || (y <= 2005 && d == 20 && m == Month.November) + || (y >= 2006 && (d >= 15 && d <= 21) && w == DayOfWeek.Monday && m == Month.November) + // Our Lady of Guadalupe + || (d == 12 && m == Month.December) + // Christmas + || (d == 25 && m == Month.December)) + return false; + return true; + } + } + } +} \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/NewZealand.cs b/src/QLNet/Time/Calendars/NewZealand.cs new file mode 100644 index 000000000..a0b1e4047 --- /dev/null +++ b/src/QLNet/Time/Calendars/NewZealand.cs @@ -0,0 +1,100 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Andrea Maggiulli + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! New Zealand calendar + /*! Holidays: +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st (possibly moved to Monday or + Tuesday)
  • +
  • Day after New Year's Day, January 2st (possibly moved to + Monday or Tuesday)
  • +
  • Anniversary Day, Monday nearest January 22nd
  • +
  • Waitangi Day. February 6th
  • +
  • Good Friday
  • +
  • Easter Monday
  • +
  • ANZAC Day. April 25th
  • +
  • Queen's Birthday, first Monday in June
  • +
  • Labour Day, fourth Monday in October
  • +
  • Christmas, December 25th (possibly moved to Monday or Tuesday)
  • +
  • Boxing Day, December 26th (possibly moved to Monday or + Tuesday)
  • +
+ \note The holiday rules for New Zealand were documented by + David Gilbert for IDB (http://www.jrefinery.com/ibd/) + + \ingroup calendars + */ + public class NewZealand : Calendar + { + public NewZealand() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "New Zealand"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + if (isWeekend(w) + // New Year's Day (possibly moved to Monday or Tuesday) + || ((d == 1 || (d == 3 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) && + m == Month.January) + // Day after New Year's Day (possibly moved to Mon or Tuesday) + || ((d == 2 || (d == 4 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) && + m == Month.January) + // Anniversary Day, Monday nearest January 22nd + || ((d >= 19 && d <= 25) && w == DayOfWeek.Monday && m == Month.January) + // Waitangi Day. February 6th + || (d == 6 && m == Month.February) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // ANZAC Day. April 25th + || (d == 25 && m == Month.April) + // Queen's Birthday, first Monday in June + || (d <= 7 && w == DayOfWeek.Monday && m == Month.June) + // Labour Day, fourth Monday in October + || ((d >= 22 && d <= 28) && w == DayOfWeek.Monday && m == Month.October) + // Christmas, December 25th (possibly Monday or Tuesday) + || ((d == 25 || (d == 27 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) + && m == Month.December) + // Boxing Day, December 26th (possibly Monday or Tuesday) + || ((d == 26 || (d == 28 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) + && m == Month.December)) + return false; + return true; + } + } + } +} \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/Norway.cs b/src/QLNet/Time/Calendars/Norway.cs new file mode 100644 index 000000000..e34eab96d --- /dev/null +++ b/src/QLNet/Time/Calendars/Norway.cs @@ -0,0 +1,90 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Andrea Maggiulli + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! Norwegian calendar + /*! Holidays: +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • Holy Thursday
  • +
  • Good Friday
  • +
  • Easter Monday
  • +
  • Ascension
  • +
  • Whit(Pentecost) Monday
  • +
  • New Year's Day, January 1st
  • +
  • May Day, May 1st
  • +
  • National Independence Day, May 17st
  • +
  • Christmas, December 25th
  • +
  • Boxing Day, December 26th
  • +
+ + \ingroup calendars + */ + public class Norway : Calendar + { + public Norway() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Norway"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // Holy Thursday + || (dd == em - 4) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // Ascension Thursday + || (dd == em + 38) + // Whit Monday + || (dd == em + 49) + // New Year's Day + || (d == 1 && m == Month.January) + // May Day + || (d == 1 && m == Month.May) + // National Independence Day + || (d == 17 && m == Month.May) + // Christmas + || (d == 25 && m == Month.December) + // Boxing Day + || (d == 26 && m == Month.December)) + return false; + return true; + } + } + } +} + diff --git a/src/QLNet/Time/Calendars/NullCalendar.cs b/src/QLNet/Time/Calendars/NullCalendar.cs new file mode 100644 index 000000000..43553bcfe --- /dev/null +++ b/src/QLNet/Time/Calendars/NullCalendar.cs @@ -0,0 +1,39 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! %Calendar for reproducing theoretical calculations. + /*! This calendar has no holidays. It ensures that dates at whole-month distances have the same day of month. */ + public class NullCalendar : Calendar + { + public NullCalendar() : base(Impl.Singleton) { } + + class Impl : Calendar + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Null calendar"; } + public override bool isWeekend(DayOfWeek w) { return false; } + public override bool isBusinessDay(Date d) { return true; } + } + } +} \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/Poland.cs b/src/QLNet/Time/Calendars/Poland.cs new file mode 100644 index 000000000..4458d8ef3 --- /dev/null +++ b/src/QLNet/Time/Calendars/Poland.cs @@ -0,0 +1,93 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Andrea Maggiulli + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! Polish calendar + /*! Holidays: +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • Easter Monday
  • +
  • Corpus Christi
  • +
  • New Year's Day, January 1st
  • +
  • Epiphany, January 6th (since 2011)
  • +
  • May Day, May 1st
  • +
  • Constitution Day, May 3rd
  • +
  • Assumption of the Blessed Virgin Mary, August 15th
  • +
  • All Saints Day, November 1st
  • +
  • Independence Day, November 11th
  • +
  • Christmas, December 25th
  • +
  • 2nd Day of Christmas, December 26th
  • +
+ + \ingroup calendars + */ + public class Poland : Calendar + { + public Poland() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Poland"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // Easter Monday + || (dd == em) + // Corpus Christi + || (dd == em + 59) + // New Year's Day + || (d == 1 && m == Month.January) + // Epiphany + || (d == 6 && m == Month.January && y >= 2011) + // May Day + || (d == 1 && m == Month.May) + // Constitution Day + || (d == 3 && m == Month.May) + // Assumption of the Blessed Virgin Mary + || (d == 15 && m == Month.August) + // All Saints Day + || (d == 1 && m == Month.November) + // Independence Day + || (d == 11 && m == Month.November) + // Christmas + || (d == 25 && m == Month.December) + // 2nd Day of Christmas + || (d == 26 && m == Month.December)) + return false; + return true; + } + } + } +} + diff --git a/src/QLNet/Time/Calendars/Romania.cs b/src/QLNet/Time/Calendars/Romania.cs index aefd1e2ae..9b2f86e26 100644 --- a/src/QLNet/Time/Calendars/Romania.cs +++ b/src/QLNet/Time/Calendars/Romania.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -27,7 +27,7 @@ namespace QLNet
  • Unification Day, January 24th
  • Orthodox Easter (only Sunday and Monday)
  • Labour Day, May 1st
  • -
  • Pentecost with Monday (50th and 51st days after the +
  • Pentecost with Monday (50th and 51st days after the Othodox Easter)
  • St Marys Day, August 15th
  • Feast of St Andrew, November 30th
  • @@ -35,20 +35,20 @@ namespace QLNet
  • Christmas, December 25th
  • 2nd Day of Christmas, December 26th
  • - + \ingroup calendars */ - public class Romania : Calendar + public class Romania : Calendar { public Romania() : base(Impl.Singleton) { } - class Impl : Calendar.OrthodoxImpl + class Impl : Calendar.OrthodoxImpl { public static readonly Impl Singleton = new Impl(); private Impl() { } public override string name() { return "Romania"; } - public override bool isBusinessDay(Date date) + public override bool isBusinessDay(Date date) { DayOfWeek w = date.DayOfWeek; int d = date.Day, dd = date.DayOfYear; @@ -56,28 +56,28 @@ public override bool isBusinessDay(Date date) int y = date.Year; int em = easterMonday(y); if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Day after New Year's Day - || (d == 2 && m == Month.January) - // Unification Day - || (d == 24 && m == Month.January) - // Orthodox Easter Monday - || (dd == em) - // Labour Day - || (d == 1 && m == Month.May) - // Pentecost - || (dd == em+49) - // St Marys Day - || (d == 15 && m == Month.August) - // Feast of St Andrew - || (d == 30 && m == Month.November) - // National Day - || (d == 1 && m == Month.December) - // Christmas - || (d == 25 && m == Month.December) - // 2nd Day of Chritsmas - || (d == 26 && m == Month.December)) + // New Year's Day + || (d == 1 && m == Month.January) + // Day after New Year's Day + || (d == 2 && m == Month.January) + // Unification Day + || (d == 24 && m == Month.January) + // Orthodox Easter Monday + || (dd == em) + // Labour Day + || (d == 1 && m == Month.May) + // Pentecost + || (dd == em + 49) + // St Marys Day + || (d == 15 && m == Month.August) + // Feast of St Andrew + || (d == 30 && m == Month.November) + // National Day + || (d == 1 && m == Month.December) + // Christmas + || (d == 25 && m == Month.December) + // 2nd Day of Chritsmas + || (d == 26 && m == Month.December)) return false; return true; } diff --git a/src/QLNet/Time/Calendars/russia.cs b/src/QLNet/Time/Calendars/Russia.cs similarity index 51% rename from src/QLNet/Time/Calendars/russia.cs rename to src/QLNet/Time/Calendars/Russia.cs index 4e08eccbc..02a1da78f 100644 --- a/src/QLNet/Time/Calendars/russia.cs +++ b/src/QLNet/Time/Calendars/Russia.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -35,16 +35,16 @@ namespace QLNet
  • Russia Day, June 12th (possibly moved to Monday)
  • Unity Day, November 4th (possibly moved to Monday)
  • - + Holidays for the Moscow Exchange (MOEX) taken from and related pages. These holidays are not consistent year-to-year, may or may not correlate to public holidays, and are only available for dates since the introduction of the MOEX 'brand' (a merger of the stock and futures markets). - + \ingroup calendars - */ + */ public class Russia : Calendar { public enum Market @@ -53,12 +53,12 @@ public enum Market MOEX //!< Moscow Exchange calendar } - public Russia() : this( Market.Settlement ) { } + public Russia() : this(Market.Settlement) { } - public Russia( Market m ) + public Russia(Market m) : base() { - switch (m) + switch (m) { case Market.Settlement: calendar_ = SettlementImpl.Singleton; @@ -67,7 +67,7 @@ public Russia( Market m ) calendar_ = ExchangeImpl.Singleton; break; default: - throw new ArgumentException("Unknown market: " + m); + throw new ArgumentException("Unknown market: " + m); } } @@ -86,28 +86,28 @@ public override bool isBusinessDay(Date date) int em = easterMonday(y); if (isWeekend(w) - // New Year's holidays - || (d >= 1 && d <= 8 && m == Month.January) - // Defender of the Fatherland Day (possibly moved to Monday) - || ((d == 23 || ((d == 24 || d == 25) && w == DayOfWeek.Monday)) && - m == Month.February) - // International Women's Day (possibly moved to Monday) - || ((d == 8 || ((d == 9 || d == 10) && w == DayOfWeek.Monday)) && - m == Month.March) - // Labour Day (possibly moved to Monday) - || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) && - m == Month.May) - // Victory Day (possibly moved to Monday) - || ((d == 9 || ((d == 10 || d == 11) && w == DayOfWeek.Monday)) && - m == Month.May) - // Russia Day (possibly moved to Monday) - || ((d == 12 || ((d == 13 || d == 14) && w == DayOfWeek.Monday)) && - m == Month.June) - // Unity Day (possibly moved to Monday) - || ((d == 4 || ((d == 5 || d == 6) && w == DayOfWeek.Monday)) && - m == Month.November)) - return false; - + // New Year's holidays + || (d >= 1 && d <= 8 && m == Month.January) + // Defender of the Fatherland Day (possibly moved to Monday) + || ((d == 23 || ((d == 24 || d == 25) && w == DayOfWeek.Monday)) && + m == Month.February) + // International Women's Day (possibly moved to Monday) + || ((d == 8 || ((d == 9 || d == 10) && w == DayOfWeek.Monday)) && + m == Month.March) + // Labour Day (possibly moved to Monday) + || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) && + m == Month.May) + // Victory Day (possibly moved to Monday) + || ((d == 9 || ((d == 10 || d == 11) && w == DayOfWeek.Monday)) && + m == Month.May) + // Russia Day (possibly moved to Monday) + || ((d == 12 || ((d == 13 || d == 14) && w == DayOfWeek.Monday)) && + m == Month.June) + // Unity Day (possibly moved to Monday) + || ((d == 4 || ((d == 5 || d == 6) && w == DayOfWeek.Monday)) && + m == Month.November)) + return false; + return true; } } @@ -117,12 +117,12 @@ class ExchangeImpl : Calendar.OrthodoxImpl public static readonly ExchangeImpl Singleton = new ExchangeImpl(); private ExchangeImpl() { } - private bool isWorkingWeekend( int d, Month month, int year ) + private bool isWorkingWeekend(int d, Month month, int year) { - switch ( year ) + switch (year) { case 2012: - switch ( month ) + switch (month) { case Month.March: return d == 11; case Month.April: return d == 28; @@ -134,47 +134,47 @@ private bool isWorkingWeekend( int d, Month month, int year ) return false; } } - private bool isExtraHoliday(int d, Month month, int year) + private bool isExtraHoliday(int d, Month month, int year) { - switch (year) + switch (year) { - case 2012: - switch (month) - { - case Month.January: return d == 2; - case Month.March: return d == 9; - case Month.April: return d == 30; - case Month.June: return d == 12; - default: return false; - } - case 2013: - switch (month) - { - case Month.January: return d == 1 || d == 2 || d == 3 - || d == 4 || d == 7; - default: return false; - } - case 2014: - switch (month) - { - case Month.January: return d == 1 || d == 2 || d == 3 || d == 7; - default: return false; - } - case 2015: - switch (month) - { - case Month.January: return d == 1 || d == 2 || d == 7; - case Month.May: return d == 4; - default: return false; - } - default: - return false; + case 2012: + switch (month) + { + case Month.January: return d == 2; + case Month.March: return d == 9; + case Month.April: return d == 30; + case Month.June: return d == 12; + default: return false; + } + case 2013: + switch (month) + { + case Month.January: return d == 1 || d == 2 || d == 3 + || d == 4 || d == 7; + default: return false; + } + case 2014: + switch (month) + { + case Month.January: return d == 1 || d == 2 || d == 3 || d == 7; + default: return false; + } + case 2015: + switch (month) + { + case Month.January: return d == 1 || d == 2 || d == 7; + case Month.May: return d == 4; + default: return false; + } + default: + return false; } - } + } public override string name() { return "Moscow exchange"; } - public override bool isBusinessDay( Date date ) + public override bool isBusinessDay(Date date) { DayOfWeek w = date.DayOfWeek; @@ -184,32 +184,32 @@ public override bool isBusinessDay( Date date ) // the exchange was formally established in 2011, so data are only // available from 2012 to present - if ( y < 2012 ) - Utils.QL_FAIL( "MOEX calendar for the year " + y + " does not exist." ); + if (y < 2012) + Utils.QL_FAIL("MOEX calendar for the year " + y + " does not exist."); - if ( isWorkingWeekend( d, m, y ) ) + if (isWorkingWeekend(d, m, y)) return true; // Known holidays - if ( isWeekend( w ) - // Defender of the Fatherland Day - || ( d == 23 && m == Month.February ) - // International Women's Day (possibly moved to Monday) - || ( ( d == 8 || ( ( d == 9 || d == 10 ) && w == DayOfWeek.Monday ) ) && m == Month.March ) - // Labour Day - || ( d == 1 && m == Month.May ) - // Victory Day (possibly moved to Monday) - || ( ( d == 9 || ( ( d == 10 || d == 11 ) && w == DayOfWeek.Monday ) ) && m == Month.May ) - // Russia Day - || ( d == 12 && m == Month.June ) - // Unity Day (possibly moved to Monday) - || ( ( d == 4 || ( ( d == 5 || d == 6 ) && w == DayOfWeek.Monday ) ) - && m == Month.November ) - // New Years Eve - || ( d == 31 && m == Month.December ) ) + if (isWeekend(w) + // Defender of the Fatherland Day + || (d == 23 && m == Month.February) + // International Women's Day (possibly moved to Monday) + || ((d == 8 || ((d == 9 || d == 10) && w == DayOfWeek.Monday)) && m == Month.March) + // Labour Day + || (d == 1 && m == Month.May) + // Victory Day (possibly moved to Monday) + || ((d == 9 || ((d == 10 || d == 11) && w == DayOfWeek.Monday)) && m == Month.May) + // Russia Day + || (d == 12 && m == Month.June) + // Unity Day (possibly moved to Monday) + || ((d == 4 || ((d == 5 || d == 6) && w == DayOfWeek.Monday)) + && m == Month.November) + // New Years Eve + || (d == 31 && m == Month.December)) return false; - if ( isExtraHoliday( d, m, y ) ) + if (isExtraHoliday(d, m, y)) return false; return true; diff --git a/src/QLNet/Time/Calendars/SaudiArabia.cs b/src/QLNet/Time/Calendars/SaudiArabia.cs new file mode 100644 index 000000000..d06b559ab --- /dev/null +++ b/src/QLNet/Time/Calendars/SaudiArabia.cs @@ -0,0 +1,89 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + Copyright (C) 2008, 2009 , 2010, 2011 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! Saudi Arabian calendar + /*! Holidays for the Tadawul financial market + (data from ): +
      +
    • Thursdays
    • +
    • Fridays
    • +
    • National Day of Saudi Arabia, September 23rd
    • +
    + + Other holidays for which no rule is given + (data available for 2004-2011 only:) +
      +
    • Eid Al-Adha
    • +
    • Eid Al-Fitr
    • +
    + + \ingroup calendars + */ + public class SaudiArabia : Calendar + { + public SaudiArabia() : base(Impl.Singleton) { } + + class Impl : Calendar + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Tadawul"; } + public override bool isWeekend(DayOfWeek w) + { + return w == DayOfWeek.Thursday || w == DayOfWeek.Friday; + } + + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + + if (isWeekend(w) + // National Day + || (d == 23 && m == Month.September) + // Eid Al-Adha + || (d >= 1 && d <= 6 && m == Month.February && y == 2004) + || (d >= 21 && d <= 25 && m == Month.January && y == 2005) + || (d >= 26 && m == Month.November && y == 2009) + || (d <= 4 && m == Month.December && y == 2009) + || (d >= 11 && d <= 19 && m == Month.November && y == 2010) + // Eid Al-Fitr + || (d >= 25 && d <= 29 && m == Month.November && y == 2004) + || (d >= 14 && d <= 18 && m == Month.November && y == 2005) + || (d >= 25 && m == Month.August && y == 2011) + || (d <= 2 && m == Month.September && y == 2011) + // other one-shot holidays + || (d == 26 && m == Month.February && y == 2011) + || (d == 19 && m == Month.March && y == 2011) + ) + return false; + return true; + } + } + } +} \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/Singapore.cs b/src/QLNet/Time/Calendars/Singapore.cs new file mode 100644 index 000000000..d755c957e --- /dev/null +++ b/src/QLNet/Time/Calendars/Singapore.cs @@ -0,0 +1,152 @@ +/* + Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! %Singapore calendars + /*! Holidays for the Singapore exchange + (data from ): +
      +
    • Saturdays
    • +
    • Sundays
    • +
    • New Year's day, January 1st
    • +
    • Good Friday
    • +
    • Labour Day, May 1st
    • +
    • National Day, August 9th
    • +
    • Christmas, December 25th
    • +
    + + Other holidays for which no rule is given + (data available for 2004-2010, 2012-2013 only:) +
      +
    • Chinese New Year
    • +
    • Hari Raya Haji
    • +
    • Vesak Poya Day
    • +
    • Deepavali
    • +
    • Diwali
    • +
    • Hari Raya Puasa
    • +
    + + \ingroup calendars + */ + public class Singapore : Calendar + { + public Singapore() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Singapore exchange"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day + || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) && m == Month.January) + // Good Friday + || (dd == em - 3) + // Labor Day + || (d == 1 && m == Month.May) + // National Day + || ((d == 9 || (d == 10 && w == DayOfWeek.Monday)) && m == Month.August) + // Christmas Day + || (d == 25 && m == Month.December) + + // Chinese New Year + || ((d == 22 || d == 23) && m == Month.January && y == 2004) + || ((d == 9 || d == 10) && m == Month.February && y == 2005) + || ((d == 30 || d == 31) && m == Month.January && y == 2006) + || ((d == 19 || d == 20) && m == Month.February && y == 2007) + || ((d == 7 || d == 8) && m == Month.February && y == 2008) + || ((d == 26 || d == 27) && m == Month.January && y == 2009) + || ((d == 15 || d == 16) && m == Month.January && y == 2010) + || ((d == 23 || d == 24) && m == Month.January && y == 2012) + || ((d == 11 || d == 12) && m == Month.February && y == 2013) + || (d == 31 && m == Month.January && y == 2014) + || (d == 1 && m == Month.February && y == 2014) + + // Hari Raya Haji + || ((d == 1 || d == 2) && m == Month.February && y == 2004) + || (d == 21 && m == Month.January && y == 2005) + || (d == 10 && m == Month.January && y == 2006) + || (d == 2 && m == Month.January && y == 2007) + || (d == 20 && m == Month.December && y == 2007) + || (d == 8 && m == Month.December && y == 2008) + || (d == 27 && m == Month.November && y == 2009) + || (d == 17 && m == Month.November && y == 2010) + || (d == 26 && m == Month.October && y == 2012) + || (d == 15 && m == Month.October && y == 2013) + || (d == 6 && m == Month.October && y == 2014) + + // Vesak Poya Day + || (d == 2 && m == Month.June && y == 2004) + || (d == 22 && m == Month.May && y == 2005) + || (d == 12 && m == Month.May && y == 2006) + || (d == 31 && m == Month.May && y == 2007) + || (d == 18 && m == Month.May && y == 2008) + || (d == 9 && m == Month.May && y == 2009) + || (d == 28 && m == Month.May && y == 2010) + || (d == 5 && m == Month.May && y == 2012) + || (d == 24 && m == Month.May && y == 2013) + || (d == 13 && m == Month.May && y == 2014) + + // Deepavali + || (d == 11 && m == Month.November && y == 2004) + || (d == 8 && m == Month.November && y == 2007) + || (d == 28 && m == Month.October && y == 2008) + || (d == 16 && m == Month.November && y == 2009) + || (d == 5 && m == Month.November && y == 2010) + || (d == 13 && m == Month.November && y == 2012) + || (d == 2 && m == Month.November && y == 2013) + || (d == 23 && m == Month.October && y == 2014) + + // Diwali + || (d == 1 && m == Month.November && y == 2005) + + // Hari Raya Puasa + || ((d == 14 || d == 15) && m == Month.November && y == 2004) + || (d == 3 && m == Month.November && y == 2005) + || (d == 24 && m == Month.October && y == 2006) + || (d == 13 && m == Month.October && y == 2007) + || (d == 1 && m == Month.October && y == 2008) + || (d == 21 && m == Month.September && y == 2009) + || (d == 10 && m == Month.September && y == 2010) + || (d == 20 && m == Month.August && y == 2012) + || (d == 8 && m == Month.August && y == 2013) + || (d == 28 && m == Month.July && y == 2014) + ) + return false; + return true; + } + } + } +} + + diff --git a/src/QLNet/Time/Calendars/Slovakia.cs b/src/QLNet/Time/Calendars/Slovakia.cs new file mode 100644 index 000000000..457d23f9d --- /dev/null +++ b/src/QLNet/Time/Calendars/Slovakia.cs @@ -0,0 +1,105 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + //! Slovak calendars + /*! Holidays for the Bratislava stock exchange + (data from ): +
      +
    • Saturdays
    • +
    • Sundays
    • +
    • New Year's Day, January 1st
    • +
    • Epiphany, January 6th
    • +
    • Good Friday
    • +
    • Easter Monday
    • +
    • May Day, May 1st
    • +
    • Liberation of the Republic, May 8th
    • +
    • SS. Cyril and Methodius, July 5th
    • +
    • Slovak National Uprising, August 29th
    • +
    • Constitution of the Slovak Republic, September 1st
    • +
    • Our Lady of the Seven Sorrows, September 15th
    • +
    • All Saints Day, November 1st
    • +
    • Freedom and Democracy of the Slovak Republic, November 17th
    • +
    • Christmas Eve, December 24th
    • +
    • Christmas, December 25th
    • +
    • St. Stephen, December 26th
    • +
    + + \ingroup calendars + */ + public class Slovakia : Calendar + { + public Slovakia() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Bratislava stock exchange"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Epiphany + || (d == 6 && m == Month.January) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // May Day + || (d == 1 && m == Month.May) + // Liberation of the Republic + || (d == 8 && m == Month.May) + // SS. Cyril and Methodius + || (d == 5 && m == Month.July) + // Slovak National Uprising + || (d == 29 && m == Month.August) + // Constitution of the Slovak Republic + || (d == 1 && m == Month.September) + // Our Lady of the Seven Sorrows + || (d == 15 && m == Month.September) + // All Saints Day + || (d == 1 && m == Month.November) + // Freedom and Democracy of the Slovak Republic + || (d == 17 && m == Month.November) + // Christmas Eve + || (d == 24 && m == Month.December) + // Christmas + || (d == 25 && m == Month.December) + // St. Stephen + || (d == 26 && m == Month.December) + // unidentified closing days for stock exchange + || (d >= 24 && d <= 31 && m == Month.December && y == 2004) + || (d >= 24 && d <= 31 && m == Month.December && y == 2005)) + return false; + return true; + } + } + } +} diff --git a/src/QLNet/Time/Calendars/SouthAfrica.cs b/src/QLNet/Time/Calendars/SouthAfrica.cs new file mode 100644 index 000000000..bc023429e --- /dev/null +++ b/src/QLNet/Time/Calendars/SouthAfrica.cs @@ -0,0 +1,111 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Andrea Maggiulli + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + + //! South-African calendar + /*! Holidays: +
      +
    • Saturdays
    • +
    • Sundays
    • +
    • New Year's Day, January 1st (possibly moved to Monday)
    • +
    • Good Friday
    • +
    • Family Day, Easter Monday
    • +
    • Human Rights Day, March 21st (possibly moved to Monday)
    • +
    • Freedom Day, April 27th (possibly moved to Monday)
    • +
    • Workers Day, May 1st (possibly moved to Monday)
    • +
    • Youth Day, June 16th (possibly moved to Monday)
    • +
    • National Women's Day, August 9th + (possibly moved to Monday)
    • +
    • Heritage Day, September 24th (possibly moved to Monday)
    • +
    • Day of Reconciliation, December 16th + (possibly moved to Monday)
    • +
    • Christmas December 25th
    • +
    • Day of Goodwill December 26th (possibly moved to Monday)
    • +
    + + \ingroup calendars + */ + public class SouthAfrica : Calendar + { + public SouthAfrica() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "South Africa"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day (possibly moved to Monday) + || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) && m == Month.January) + // Good Friday + || (dd == em - 3) + // Family Day + || (dd == em) + // Human Rights Day, March 21st (possibly moved to Monday) + || ((d == 21 || (d == 22 && w == DayOfWeek.Monday)) + && m == Month.March) + // Freedom Day, April 27th (possibly moved to Monday) + || ((d == 27 || (d == 28 && w == DayOfWeek.Monday)) + && m == Month.April) + // Election Day, April 14th 2004 + || (d == 14 && m == Month.April && y == 2004) + // Workers Day, May 1st (possibly moved to Monday) + || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) + && m == Month.May) + // Youth Day, June 16th (possibly moved to Monday) + || ((d == 16 || (d == 17 && w == DayOfWeek.Monday)) + && m == Month.June) + // National Women's Day, August 9th (possibly moved to Monday) + || ((d == 9 || (d == 10 && w == DayOfWeek.Monday)) + && m == Month.August) + // Heritage Day, September 24th (possibly moved to Monday) + || ((d == 24 || (d == 25 && w == DayOfWeek.Monday)) + && m == Month.September) + // Day of Reconciliation, December 16th + // (possibly moved to Monday) + || ((d == 16 || (d == 17 && w == DayOfWeek.Monday)) + && m == Month.December) + // Christmas + || (d == 25 && m == Month.December) + // Day of Goodwill (possibly moved to Monday) + || ((d == 26 || (d == 27 && w == DayOfWeek.Monday)) + && m == Month.December) + ) + return false; + return true; + } + } + } +} + diff --git a/src/QLNet/Time/Calendars/SouthKorea.cs b/src/QLNet/Time/Calendars/SouthKorea.cs new file mode 100644 index 000000000..fcba5cdc4 --- /dev/null +++ b/src/QLNet/Time/Calendars/SouthKorea.cs @@ -0,0 +1,271 @@ +/* + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! South Korean calendars + /*! Public holidays: +
      +
    • Saturdays
    • +
    • Sundays
    • +
    • New Year's Day, January 1st
    • +
    • Independence Day, March 1st
    • +
    • Arbour Day, April 5th (until 2005)
    • +
    • Labour Day, May 1st
    • +
    • Children's Day, May 5th
    • +
    • Memorial Day, June 6th
    • +
    • Constitution Day, July 17th (until 2007)
    • +
    • Liberation Day, August 15th
    • +
    • National Fondation Day, October 3th
    • +
    • Christmas Day, December 25th
    • +
    + + Other holidays for which no rule is given + (data available for 2004-2032 only:) +
      +
    • Lunar New Year, the last day of the previous lunar year
    • +
    • Election Days
    • +
    • National Assemblies
    • +
    • Presidency
    • +
    • Regional Election Days
    • +
    • Buddha's birthday
    • +
    • Harvest Moon Day
    • +
    + + Holidays for the Korea exchange + (data from or + ): +
      +
    • Public holidays as listed above
    • +
    • Year-end closing
    • +
    + + \ingroup calendars + */ + public class SouthKorea : Calendar + { + public enum Market { Settlement, //!< Public holidays + KRX //!< Korea exchange + } + + public SouthKorea() : this(Market.KRX) { } + public SouthKorea(Market m) + : base() + { + // all calendar instances on the same market share the same + // implementation instance + switch (m) + { + case Market.Settlement: + calendar_ = Settlement.Singleton; + break; + case Market.KRX: + calendar_ = KRX.Singleton; + break; + default: + throw new ArgumentException("Unknown market: " + m); + } + } + + class Settlement : Calendar + { + public static readonly Settlement Singleton = new Settlement(); + + public override string name() { return "South-Korean settlement"; } + public override bool isWeekend(DayOfWeek w) + { + return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; + } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Independence Day + || (d == 1 && m == Month.March) + // Arbour Day + || (d == 5 && m == Month.April && y <= 2005) + // Labour Day + || (d == 1 && m == Month.May) + // Children's Day + || (d == 5 && m == Month.May) + // Memorial Day + || (d == 6 && m == Month.June) + // Constitution Day + || (d == 17 && m == Month.July && y <= 2007) + // Liberation Day + || (d == 15 && m == Month.August) + // National Foundation Day + || (d == 3 && m == Month.October) + // Christmas Day + || (d == 25 && m == Month.December) + + // Lunar New Year + || ((d == 21 || d == 22 || d == 23) && m == Month.January && y == 2004) + || ((d == 8 || d == 9 || d == 10) && m == Month.February && y == 2005) + || ((d == 28 || d == 29 || d == 30) && m == Month.January && y == 2006) + || (d == 19 && m == Month.February && y == 2007) + || ((d == 6 || d == 7 || d == 8) && m == Month.February && y == 2008) + || ((d == 25 || d == 26 || d == 27) && m == Month.January && y == 2009) + || ((d == 13 || d == 14 || d == 15) && m == Month.February && y == 2010) + || ((d == 2 || d == 3 || d == 4) && m == Month.February && y == 2011) + || ((d == 23 || d == 24) && m == Month.January && y == 2012) + || (d == 11 && m == Month.February && y == 2013) + || ((d == 30 || d == 31) && m == Month.January && y == 2014) + || ((d == 18 || d == 19 || d == 20) && m == Month.February && y == 2015) + || ((d == 7 || d == 8 || d == 9) && m == Month.February && y == 2016) + || ((d == 27 || d == 28 || d == 29) && m == Month.January && y == 2017) + || ((d == 15 || d == 16 || d == 17) && m == Month.February && y == 2018) + || ((d == 4 || d == 5 || d == 6) && m == Month.February && y == 2019) + || ((d == 24 || d == 25 || d == 26) && m == Month.January && y == 2020) + || ((d == 11 || d == 12 || d == 13) && m == Month.February && y == 2021) + || (((d == 31 && m == Month.January) || ((d == 1 || d == 2) + && m == Month.February)) && y == 2022) + || ((d == 21 || d == 22 || d == 23) && m == Month.January && y == 2023) + || ((d == 9 || d == 10 || d == 11) && m == Month.February && y == 2024) + || ((d == 28 || d == 29 || d == 30) && m == Month.January && y == 2025) + || ((d == 28 || d == 29 || d == 30) && m == Month.January && y == 2025) + || ((d == 16 || d == 17 || d == 18) && m == Month.February && y == 2026) + || ((d == 5 || d == 6 || d == 7) && m == Month.February && y == 2027) + || ((d == 25 || d == 26 || d == 27) && m == Month.January && y == 2028) + || ((d == 12 || d == 13 || d == 14) && m == Month.February && y == 2029) + || ((d == 2 || d == 3 || d == 4) && m == Month.February && y == 2030) + || ((d == 22 || d == 23 || d == 24) && m == Month.January && y == 2031) + || ((d == 10 || d == 11 || d == 12) && m == Month.February && y == 2032) + // Election Days + || (d == 15 && m == Month.April && y == 2004) // National Assembly + || (d == 31 && m == Month.May && y == 2006) // Regional election + || (d == 19 && m == Month.December && y == 2007) // Presidency + || (d == 9 && m == Month.April && y == 2008) // National Assembly + || (d == 2 && m == Month.June && y == 2010) // Local election + || (d == 11 && m == Month.April && y == 2012) // National Assembly + || (d == 19 && m == Month.December && y == 2012) // Presidency + || (d == 4 && m == Month.June && y == 2014) // Local election + || (d == 13 && m == Month.April && y == 2016) // National Assembly + // Buddha's birthday + || (d == 26 && m == Month.May && y == 2004) + || (d == 15 && m == Month.May && y == 2005) + || (d == 24 && m == Month.May && y == 2007) + || (d == 12 && m == Month.May && y == 2008) + || (d == 2 && m == Month.May && y == 2009) + || (d == 21 && m == Month.May && y == 2010) + || (d == 10 && m == Month.May && y == 2011) + || (d == 28 && m == Month.May && y == 2012) + || (d == 17 && m == Month.May && y == 2013) + || (d == 6 && m == Month.May && y == 2014) + || (d == 25 && m == Month.May && y == 2015) + || (d == 14 && m == Month.May && y == 2016) + || (d == 3 && m == Month.May && y == 2017) + || (d == 22 && m == Month.May && y == 2018) + || (d == 12 && m == Month.May && y == 2019) + || (d == 30 && m == Month.April && y == 2020) + || (d == 19 && m == Month.May && y == 2021) + || (d == 8 && m == Month.May && y == 2022) + || (d == 26 && m == Month.May && y == 2023) + || (d == 15 && m == Month.May && y == 2024) + || (d == 5 && m == Month.May && y == 2025) + || (d == 24 && m == Month.May && y == 2026) + || (d == 13 && m == Month.May && y == 2027) + || (d == 2 && m == Month.May && y == 2028) + || (d == 20 && m == Month.May && y == 2029) + || (d == 9 && m == Month.May && y == 2030) + || (d == 28 && m == Month.May && y == 2031) + || (d == 16 && m == Month.May && y == 2032) + // Special holiday: 70 years from Independence Day + || (d == 14 && m == Month.August && y == 2015) + // Harvest Moon Day + || ((d == 27 || d == 28 || d == 29) && m == Month.September && y == 2004) + || ((d == 17 || d == 18 || d == 19) && m == Month.September && y == 2005) + || ((d == 5 || d == 6 || d == 7) && m == Month.October && y == 2006) + || ((d == 24 || d == 25 || d == 26) && m == Month.September && y == 2007) + || ((d == 13 || d == 14 || d == 15) && m == Month.September && y == 2008) + || ((d == 2 || d == 3 || d == 4) && m == Month.October && y == 2009) + || ((d == 21 || d == 22 || d == 23) && m == Month.September && y == 2010) + || ((d == 12 || d == 13) && m == Month.September && y == 2011) + || (d == 1 && m == Month.October && y == 2012) + || ((d == 18 || d == 19 || d == 20) && m == Month.September && y == 2013) + || ((d == 8 || d == 9 || d == 10) && m == Month.September && y == 2014) + || ((d == 28 || d == 29) && m == Month.September && y == 2015) + || ((d == 14 || d == 15 || d == 16) && m == Month.September && y == 2016) + || ((d == 3 || d == 4 || d == 5) && m == Month.October && y == 2017) + || ((d == 23 || d == 24 || d == 25) && m == Month.September && y == 2018) + || ((d == 12 || d == 13 || d == 14) && m == Month.September && y == 2019) + || (((d == 30 && m == Month.September) || ((d == 1 || d == 2) + && m == Month.October)) && y == 2020) + || ((d == 20 || d == 21 || d == 22) && m == Month.September && y == 2021) + || ((d == 9 || d == 10 || d == 11) && m == Month.September && y == 2022) + || ((d == 28 || d == 29 || d == 30) && m == Month.September && y == 2023) + || ((d == 16 || d == 17 || d == 18) && m == Month.September && y == 2024) + || ((d == 5 || d == 6 || d == 7) && m == Month.October && y == 2025) + || ((d == 24 || d == 25 || d == 26) && m == Month.September && y == 2026) + || ((d == 14 || d == 15 || d == 16) && m == Month.September && y == 2027) + || ((d == 2 || d == 3 || d == 4) && m == Month.October && y == 2028) + || ((d == 21 || d == 22 || d == 23) && m == Month.September && y == 2029) + || ((d == 11 || d == 12 || d == 13) && m == Month.September && y == 2030) + || (((d == 30 && m == Month.September) || ((d == 1 || d == 2) + && m == Month.October)) && y == 2031) + || ((d == 18 || d == 19 || d == 20) && m == Month.September && y == 2032) + // Hangul Proclamation of Korea + || (d == 9 && m == Month.October && y >= 2013) + ) + return false; + + return true; + } + } + + class KRX : Settlement + { + public new static readonly KRX Singleton = new KRX(); + + public override string name() { return "South-Korea exchange"; } + public override bool isBusinessDay(Date date) + { + // public holidays + if (!base.isBusinessDay(date)) + return false; + + int d = date.Day; + DayOfWeek w = date.DayOfWeek; + Month m = (Month)date.Month; + + if ( // Year-end closing + ((((d == 29 || d == 30) && w == DayOfWeek.Friday) || d == 31) + && m == Month.December) + ) + return false; + + return true; + } + } + } +} + + + + diff --git a/src/QLNet/Time/Calendars/Sweden.cs b/src/QLNet/Time/Calendars/Sweden.cs new file mode 100644 index 000000000..b517f6fb6 --- /dev/null +++ b/src/QLNet/Time/Calendars/Sweden.cs @@ -0,0 +1,101 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Andrea Maggiulli + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! Swedish calendar + /*! Holidays: +
      +
    • Saturdays
    • +
    • Sundays
    • +
    • New Year's Day, January 1st
    • +
    • Epiphany, January 6th
    • +
    • Good Friday
    • +
    • Easter Monday
    • +
    • Ascension
    • +
    • Whit(Pentecost) Monday
    • +
    • May Day, May 1st
    • +
    • National Day, June 6th
    • +
    • Midsummer Eve (Friday between June 19-25)
    • +
    • Christmas Eve, December 24th
    • +
    • Christmas Day, December 25th
    • +
    • Boxing Day, December 26th
    • +
    • New Year's Eve, December 31th
    • +
    + + \ingroup calendars + */ + public class Sweden : Calendar + { + public Sweden() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Sweden"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + if (isWeekend(w) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // Ascension Thursday + || (dd == em + 38) + // Whit Monday + || (dd == em + 49) + // New Year's Day + || (d == 1 && m == Month.January) + // Epiphany + || (d == 6 && m == Month.January) + // May Day + || (d == 1 && m == Month.May) + // June 6 id National Day but is not a holiday. + // It has been debated wheter or not this day should be + // declared as a holiday. + // As of 2002 the Stockholmborsen is open that day + // || (d == 6 && m == June) + // Midsummer Eve (Friday between June 19-25) + || (w == DayOfWeek.Friday && (d >= 19 && d <= 25) && m == Month.June) + // Christmas Eve + || (d == 24 && m == Month.December) + // Christmas Day + || (d == 25 && m == Month.December) + // Boxing Day + || (d == 26 && m == Month.December) + // New Year's Eve + || (d == 31 && m == Month.December)) + return false; + return true; + } + } + } +} + diff --git a/src/QLNet/Time/Calendars/Switzerland.cs b/src/QLNet/Time/Calendars/Switzerland.cs new file mode 100644 index 000000000..fb52227fa --- /dev/null +++ b/src/QLNet/Time/Calendars/Switzerland.cs @@ -0,0 +1,92 @@ +/* + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Andrea Maggiulli + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + + //! Swiss calendar + /*! Holidays: +
      +
    • Saturdays
    • +
    • Sundays
    • +
    • New Year's Day, January 1st
    • +
    • Berchtoldstag, January 2nd
    • +
    • Good Friday
    • +
    • Easter Monday
    • +
    • Ascension Day
    • +
    • Whit Monday
    • +
    • Labour Day, May 1st
    • +
    • National Day, August 1st
    • +
    • Christmas, December 25th
    • +
    • St. Stephen's Day, December 26th
    • +
    + + \ingroup calendars + */ + public class Switzerland : Calendar + { + public Switzerland() : base(Impl.Singleton) { } + + class Impl : Calendar.WesternImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Switzerland"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Berchtoldstag + || (d == 2 && m == Month.January) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // Ascension Day + || (dd == em + 38) + // Whit Monday + || (dd == em + 49) + // Labour Day + || (d == 1 && m == Month.May) + // National Day + || (d == 1 && m == Month.August) + // Christmas + || (d == 25 && m == Month.December) + // St. Stephen's Day + || (d == 26 && m == Month.December)) + return false; + return true; + } + } + } +} + + diff --git a/src/QLNet/Time/Calendars/TARGET.cs b/src/QLNet/Time/Calendars/TARGET.cs index c711be147..fb6fe1658 100644 --- a/src/QLNet/Time/Calendars/TARGET.cs +++ b/src/QLNet/Time/Calendars/TARGET.cs @@ -1,72 +1,76 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - //! %TARGET calendar - /*! Holidays (see http://www.ecb.int): -
      -
    • Saturdays
    • -
    • Sundays
    • -
    • New Year's Day, January 1st
    • -
    • Good Friday (since 2000)
    • -
    • Easter Monday (since 2000)
    • -
    • Labour Day, May 1st (since 2000)
    • -
    • Christmas, December 25th
    • -
    • Day of Goodwill, December 26th (since 2000)
    • -
    • December 31st (1998, 1999, and 2001)
    • -
    - */ - public class TARGET : Calendar { - public TARGET() : base(Impl.Singleton) {} +namespace QLNet +{ + //! %TARGET calendar + /*! Holidays (see http://www.ecb.int): +
      +
    • Saturdays
    • +
    • Sundays
    • +
    • New Year's Day, January 1st
    • +
    • Good Friday (since 2000)
    • +
    • Easter Monday (since 2000)
    • +
    • Labour Day, May 1st (since 2000)
    • +
    • Christmas, December 25th
    • +
    • Day of Goodwill, December 26th (since 2000)
    • +
    • December 31st (1998, 1999, and 2001)
    • +
    + */ + public class TARGET : Calendar + { + public TARGET() : base(Impl.Singleton) {} - class Impl : Calendar.WesternImpl { - internal static readonly Impl Singleton = new Impl(); - private Impl() {} + class Impl : Calendar.WesternImpl + { + internal static readonly Impl Singleton = new Impl(); + private Impl() {} - public override string name() { return "TARGET calendar"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); + public override string name() { return "TARGET calendar"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Good Friday - || (dd == em - 3 && y >= 2000) - // Easter Monday - || (dd == em && y >= 2000) - // Labour Day - || (d == 1 && m == Month.May && y >= 2000) - // Christmas - || (d == 25 && m == Month.December) - // Day of Goodwill - || (d == 26 && m == Month.December && y >= 2000) - // December 31st, 1998, 1999, and 2001 only - || (d == 31 && m == Month.December && (y == 1998 || y == 1999 || y == 2001))) - return false; - return true; - } + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Good Friday + || (dd == em - 3 && y >= 2000) + // Easter Monday + || (dd == em && y >= 2000) + // Labour Day + || (d == 1 && m == Month.May && y >= 2000) + // Christmas + || (d == 25 && m == Month.December) + // Day of Goodwill + || (d == 26 && m == Month.December && y >= 2000) + // December 31st, 1998, 1999, and 2001 only + || (d == 31 && m == Month.December && (y == 1998 || y == 1999 || y == 2001))) + return false; + return true; + } - } - } + } + } } \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/Taiwan.cs b/src/QLNet/Time/Calendars/Taiwan.cs new file mode 100644 index 000000000..12e30570e --- /dev/null +++ b/src/QLNet/Time/Calendars/Taiwan.cs @@ -0,0 +1,290 @@ +/* + Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! Taiwanese calendars + /*! Holidays for the Taiwan stock exchange + (data from ): +
      +
    • Saturdays
    • +
    • Sundays
    • +
    • New Year's Day, January 1st
    • +
    • Peace Memorial Day, February 28
    • +
    • Labor Day, May 1st
    • +
    • Double Tenth National Day, October 10th
    • +
    + + Other holidays for which no rule is given + (data available for 2002-2013 only:) +
      +
    • Chinese Lunar New Year
    • +
    • Tomb Sweeping Day
    • +
    • Dragon Boat Festival
    • +
    • Moon Festival
    • +
    + + \ingroup calendars + */ + public class Taiwan : Calendar + { + public Taiwan() : base(Impl.Singleton) { } + + class Impl : Calendar + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Taiwan stock exchange"; } + public override bool isWeekend(DayOfWeek w) + { + return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; + } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // Peace Memorial Day + || (d == 28 && m == Month.February) + // Labor Day + || (d == 1 && m == Month.May) + // Double Tenth + || (d == 10 && m == Month.October) + ) + return false; + + if (y == 2002) + { + // Dragon Boat Festival and Moon Festival fall on Saturday + if (// Chinese Lunar New Year + (d >= 9 && d <= 17 && m == Month.February) + // Tomb Sweeping Day + || (d == 5 && m == Month.April) + ) + return false; + } + + if (y == 2003) + { + // Tomb Sweeping Day falls on Saturday + if (// Chinese Lunar New Year + ((d >= 31 && m == Month.January) || (d <= 5 && m == Month.February)) + // Dragon Boat Festival + || (d == 4 && m == Month.June) + // Moon Festival + || (d == 11 && m == Month.September) + ) + return false; + } + + if (y == 2004) + { + // Tomb Sweeping Day falls on Sunday + if (// Chinese Lunar New Year + (d >= 21 && d <= 26 && m == Month.January) + // Dragon Boat Festival + || (d == 22 && m == Month.June) + // Moon Festival + || (d == 28 && m == Month.September) + ) + return false; + } + + if (y == 2005) + { + // Dragon Boat and Moon Festival fall on Saturday or Sunday + if (// Chinese Lunar New Year + (d >= 6 && d <= 13 && m == Month.February) + // Tomb Sweeping Day + || (d == 5 && m == Month.April) + // make up for Labor Day, not seen in other years + || (d == 2 && m == Month.May) + ) + return false; + } + + if (y == 2006) + { + // Dragon Boat and Moon Festival fall on Saturday or Sunday + if (// Chinese Lunar New Year + ((d >= 28 && m == Month.January) || (d <= 5 && m == Month.February)) + // Tomb Sweeping Day + || (d == 5 && m == Month.April) + // Dragon Boat Festival + || (d == 31 && m == Month.May) + // Moon Festival + || (d == 6 && m == Month.October) + ) + return false; + } + + if (y == 2007) + { + if (// Chinese Lunar New Year + (d >= 17 && d <= 25 && m == Month.February) + // Tomb Sweeping Day + || (d == 5 && m == Month.April) + // adjusted holidays + || (d == 6 && m == Month.April) + || (d == 18 && m == Month.June) + // Dragon Boat Festival + || (d == 19 && m == Month.June) + // adjusted holiday + || (d == 24 && m == Month.September) + // Moon Festival + || (d == 25 && m == Month.September) + ) + return false; + } + + if (y == 2008) + { + if (// Chinese Lunar New Year + (d >= 4 && d <= 11 && m == Month.February) + // Tomb Sweeping Day + || (d == 4 && m == Month.April) + ) + return false; + } + + if (y == 2009) + { + if (// Public holiday + (d == 2 && m == Month.January) + // Chinese Lunar New Year + || (d >= 24 && m == Month.January) + // Tomb Sweeping Day + || (d == 4 && m == Month.April) + // Dragon Boat Festival + || ((d == 28 || d == 29) && m == Month.May) + // Moon Festival + || (d == 3 && m == Month.October) + ) + return false; + } + + if (y == 2010) + { + if (// Chinese Lunar New Year + (d >= 13 && d <= 21 && m == Month.January) + // Tomb Sweeping Day + || (d == 5 && m == Month.April) + // Dragon Boat Festival + || (d == 16 && m == Month.May) + // Moon Festival + || (d == 22 && m == Month.September) + ) + return false; + } + + if (y == 2011) + { + if (// Spring Festival + (d >= 2 && d <= 7 && m == Month.February) + // Children's Day + || (d == 4 && m == Month.April) + // Tomb Sweeping Day + || (d == 5 && m == Month.April) + // Labour Day + || (d == 2 && m == Month.May) + // Dragon Boat Festival + || (d == 6 && m == Month.June) + // Mid-Autumn Festival + || (d == 12 && m == Month.September) + ) + return false; + } + + if (y == 2012) + { + if (// Spring Festival + (d >= 23 && d <= 27 && m == Month.January) + // Peace Memorial Day + || (d == 27 && m == Month.February) + // Children's Day + // Tomb Sweeping Day + || (d == 4 && m == Month.April) + // Labour Day + || (d == 1 && m == Month.May) + // Dragon Boat Festival + || (d == 23 && m == Month.June) + // Mid-Autumn Festival + || (d == 30 && m == Month.September) + // Memorial Day: + // Founding of the Republic of China + || (d == 31 && m == Month.December) + ) + return false; + } + + if (y == 2013) + { + if (// Spring Festival + (d >= 10 && d <= 15 && m == Month.February) + // Children's Day + || (d == 4 && m == Month.April) + // Tomb Sweeping Day + || (d == 5 && m == Month.April) + // Labour Day + || (d == 1 && m == Month.May) + // Dragon Boat Festival + || (d == 12 && m == Month.June) + // Mid-Autumn Festival + || (d >= 19 && d <= 20 && m == Month.September) + ) + return false; + } + + if (y == 2014) + { + if (// Lunar New Year + (d >= 28 && d <= 30 && m == Month.January) + // Spring Festival + || ((d == 31 && m == Month.January) || (d <= 4 && m == Month.February)) + // Children's Day + || (d == 4 && m == Month.April) + // Tomb Sweeping Day + || (d == 5 && m == Month.April) + // Labour Day + || (d == 1 && m == Month.May) + // Dragon Boat Festival + || (d == 2 && m == Month.June) + // Mid-Autumn Festival + || (d == 8 && m == Month.September) + ) + return false; + } + + return true; + } + } + + } + +} \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/Turkey.cs b/src/QLNet/Time/Calendars/Turkey.cs new file mode 100644 index 000000000..a494882b6 --- /dev/null +++ b/src/QLNet/Time/Calendars/Turkey.cs @@ -0,0 +1,182 @@ +/* + Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; + +namespace QLNet +{ + //! Turkish calendar + /*! Holidays for the Istanbul Stock Exchange: + (data from ): +
      +
    • Saturdays
    • +
    • Sundays
    • +
    • New Year's Day, January 1st
    • +
    • National Sovereignty and Children’s Day, April 23rd
    • +
    • Youth and Sports Day, May 19th
    • +
    • Victory Day, August 30th
    • +
    • Republic Day, October 29th
    • +
    • Local Holidays (Kurban, Ramadan; 2004 to 2013 only)
    • +
    + + \ingroup calendars + */ + public class Turkey : Calendar + { + public Turkey() : base(Impl.Singleton) { } + + class Impl : Calendar + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Turkey"; } + public override bool isWeekend(DayOfWeek w) + { + return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; + } + + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + + if (isWeekend(w) + // New Year's Day + || (d == 1 && m == Month.January) + // 23 nisan / National Holiday + || (d == 23 && m == Month.April) + // 19 may/ National Holiday + || (d == 19 && m == Month.May) + // 30 aug/ National Holiday + || (d == 30 && m == Month.August) + ///29 ekim National Holiday + || (d == 29 && m == Month.October)) + return false; + + // Local Holidays + if (y == 2004) + { + // Kurban + if ((m == Month.February && d <= 4) + // Ramadan + || (m == Month.November && d >= 14 && d <= 16)) + return false; + } + else if (y == 2005) + { + // Kurban + if ((m == Month.January && d >= 19 && d <= 21) + // Ramadan + || (m == Month.November && d >= 2 && d <= 5)) + return false; + } + else if (y == 2006) + { + // Kurban + if ((m == Month.January && d >= 10 && d <= 13) + // Ramadan + || (m == Month.October && d >= 23 && d <= 25) + // Kurban + || (m == Month.December && d == 31)) + return false; + } + else if (y == 2007) + { + // Kurban + if ((m == Month.January && d <= 3) + // Ramadan + || (m == Month.October && d >= 12 && d <= 14) + // Kurban + || (m == Month.December && d >= 20 && d <= 23)) + return false; + } + else if (y == 2008) + { + // Ramadan + if ((m == Month.September && d == 30) + || (m == Month.October && d <= 2) + // Kurban + || (m == Month.December && d >= 8 && d <= 11)) + return false; + } + else if (y == 2009) + { + // Ramadan + if ((m == Month.September && d >= 20 && d <= 22) + // Kurban + || (m == Month.November && d >= 27 && d <= 30)) + return false; + } + else if (y == 2010) + { + // Ramadan + if ((m == Month.September && d >= 9 && d <= 11) + // Kurban + || (m == Month.November && d >= 16 && d <= 19)) + return false; + } + else if (y == 2011) + { + // not clear from borsainstanbul.com + if ((m == Month.October && d == 1) + || (m == Month.November && d >= 9 && d <= 13)) + return false; + } + else if (y == 2012) + { + // Ramadan + if ((m == Month.August && d >= 18 && d <= 21) + // Kurban + || (m == Month.October && d >= 24 && d <= 28)) + return false; + } + else if (y == 2013) + { + // Ramadan + if ((m == Month.August && d >= 7 && d <= 10) + // Kurban + || (m == Month.October && d >= 14 && d <= 18) + // additional holiday for Republic Day + || (m == Month.October && d == 28)) + return false; + } + else if (y == 2014) + { + // Ramadan + if ((m == Month.July && d >= 27 && d <= 30) + // Kurban + || (m == Month.October && d >= 4 && d <= 7) + // additional holiday for Republic Day + || (m == Month.October && d == 29)) + return false; + } + return true; + } + } + } +} + + + + diff --git a/src/QLNet/Time/Calendars/Ukraine.cs b/src/QLNet/Time/Calendars/Ukraine.cs index 714280eec..03117520c 100644 --- a/src/QLNet/Time/Calendars/Ukraine.cs +++ b/src/QLNet/Time/Calendars/Ukraine.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -44,22 +44,22 @@ following Monday. */ public class Ukraine : Calendar { - public Ukraine(Market m = Market.USE ) + public Ukraine(Market m = Market.USE) { // all calendar instances on the same market share the same implementation instance - switch ( m ) + switch (m) { case Market.USE: calendar_ = Impl.Singleton; break; default: - Utils.QL_FAIL( "unknown market" ); + Utils.QL_FAIL("unknown market"); break; } } public enum Market { USE //!< Ukrainian stock exchange - }; + } class Impl : Calendar.OrthodoxImpl { @@ -67,41 +67,41 @@ class Impl : Calendar.OrthodoxImpl private Impl() { } public override string name() { return "Ukrainian stock exchange"; } - public override bool isBusinessDay( Date date ) + public override bool isBusinessDay(Date date) { DayOfWeek w = date.DayOfWeek; int d = date.Day, dd = date.DayOfYear; Month m = (Month)date.Month; int y = date.Year; - int em = easterMonday( y ); + int em = easterMonday(y); - if ( isWeekend( w ) - // New Year's Day (possibly moved to Monday) - || ( ( d == 1 || ( ( d == 2 || d == 3 ) && w == DayOfWeek.Monday ) ) - && m == Month.January ) - // Orthodox Christmas - || ( ( d == 7 || ( ( d == 8 || d == 9 ) && w == DayOfWeek.Monday ) ) - && m == Month.January ) - // Women's Day - || ( ( d == 8 || ( ( d == 9 || d == 10 ) && w == DayOfWeek.Monday ) ) - && m == Month.March ) - // Orthodox Easter Monday - || ( dd == em ) - // Holy Trinity Day - || ( dd == em + 49 ) - // Workers' Solidarity Days - || ( ( d == 1 || d == 2 || ( d == 3 && w == DayOfWeek.Monday ) ) && m == Month.May ) - // Victory Day - || ( ( d == 9 || ( ( d == 10 || d == 11 ) && w == DayOfWeek.Monday ) ) && m == Month.May ) - // Constitution Day - || ( d == 28 && m == Month.June ) - // Independence Day - || ( d == 24 && m == Month.August ) - // Defender's Day (since 2015) - || ( d == 14 && m == Month.October && y >= 2015 ) ) + if (isWeekend(w) + // New Year's Day (possibly moved to Monday) + || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) + && m == Month.January) + // Orthodox Christmas + || ((d == 7 || ((d == 8 || d == 9) && w == DayOfWeek.Monday)) + && m == Month.January) + // Women's Day + || ((d == 8 || ((d == 9 || d == 10) && w == DayOfWeek.Monday)) + && m == Month.March) + // Orthodox Easter Monday + || (dd == em) + // Holy Trinity Day + || (dd == em + 49) + // Workers' Solidarity Days + || ((d == 1 || d == 2 || (d == 3 && w == DayOfWeek.Monday)) && m == Month.May) + // Victory Day + || ((d == 9 || ((d == 10 || d == 11) && w == DayOfWeek.Monday)) && m == Month.May) + // Constitution Day + || (d == 28 && m == Month.June) + // Independence Day + || (d == 24 && m == Month.August) + // Defender's Day (since 2015) + || (d == 14 && m == Month.October && y >= 2015)) return false; return true; } - }; + } } } diff --git a/src/QLNet/Time/Calendars/UnitedKingdom.cs b/src/QLNet/Time/Calendars/UnitedKingdom.cs index 50ebdfa16..3bdebff76 100644 --- a/src/QLNet/Time/Calendars/UnitedKingdom.cs +++ b/src/QLNet/Time/Calendars/UnitedKingdom.cs @@ -1,209 +1,219 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Andrea Maggiulli - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - //! United Kingdom calendars - /*! Public holidays (data from http://www.dti.gov.uk/er/bankhol.htm): -
      -
    • Saturdays
    • -
    • Sundays
    • -
    • New Year's Day, January 1st (possibly moved to Monday)
    • -
    • Good Friday
    • -
    • Easter Monday
    • -
    • Early May Bank Holiday, first Monday of May
    • -
    • Spring Bank Holiday, last Monday of May
    • -
    • Summer Bank Holiday, last Monday of August
    • -
    • Christmas Day, December 25th (possibly moved to Monday or - Tuesday)
    • -
    • Boxing Day, December 26th (possibly moved to Monday or - Tuesday)
    • -
    +namespace QLNet +{ + //! United Kingdom calendars + /*! Public holidays (data from http://www.dti.gov.uk/er/bankhol.htm): +
      +
    • Saturdays
    • +
    • Sundays
    • +
    • New Year's Day, January 1st (possibly moved to Monday)
    • +
    • Good Friday
    • +
    • Easter Monday
    • +
    • Early May Bank Holiday, first Monday of May
    • +
    • Spring Bank Holiday, last Monday of May
    • +
    • Summer Bank Holiday, last Monday of August
    • +
    • Christmas Day, December 25th (possibly moved to Monday or + Tuesday)
    • +
    • Boxing Day, December 26th (possibly moved to Monday or + Tuesday)
    • +
    + + Holidays for the stock exchange: +
      +
    • Saturdays
    • +
    • Sundays
    • +
    • New Year's Day, January 1st (possibly moved to Monday)
    • +
    • Good Friday
    • +
    • Easter Monday
    • +
    • Early May Bank Holiday, first Monday of May
    • +
    • Spring Bank Holiday, last Monday of May
    • +
    • Summer Bank Holiday, last Monday of August
    • +
    • Christmas Day, December 25th (possibly moved to Monday or + Tuesday)
    • +
    • Boxing Day, December 26th (possibly moved to Monday or + Tuesday)
    • +
    + + Holidays for the metals exchange: +
      +
    • Saturdays
    • +
    • Sundays
    • +
    • New Year's Day, January 1st (possibly moved to Monday)
    • +
    • Good Friday
    • +
    • Easter Monday
    • +
    • Early May Bank Holiday, first Monday of May
    • +
    • Spring Bank Holiday, last Monday of May
    • +
    • Summer Bank Holiday, last Monday of August
    • +
    • Christmas Day, December 25th (possibly moved to Monday or + Tuesday)
    • +
    • Boxing Day, December 26th (possibly moved to Monday or + Tuesday)
    • +
    + + \todo add LIFFE + \test the correctness of the returned results is tested against a list of known holidays. + */ - Holidays for the stock exchange: -
      -
    • Saturdays
    • -
    • Sundays
    • -
    • New Year's Day, January 1st (possibly moved to Monday)
    • -
    • Good Friday
    • -
    • Easter Monday
    • -
    • Early May Bank Holiday, first Monday of May
    • -
    • Spring Bank Holiday, last Monday of May
    • -
    • Summer Bank Holiday, last Monday of August
    • -
    • Christmas Day, December 25th (possibly moved to Monday or - Tuesday)
    • -
    • Boxing Day, December 26th (possibly moved to Monday or - Tuesday)
    • -
    + public class UnitedKingdom : Calendar + { + public enum Market { Settlement, Exchange, Metals } - Holidays for the metals exchange: -
      -
    • Saturdays
    • -
    • Sundays
    • -
    • New Year's Day, January 1st (possibly moved to Monday)
    • -
    • Good Friday
    • -
    • Easter Monday
    • -
    • Early May Bank Holiday, first Monday of May
    • -
    • Spring Bank Holiday, last Monday of May
    • -
    • Summer Bank Holiday, last Monday of August
    • -
    • Christmas Day, December 25th (possibly moved to Monday or - Tuesday)
    • -
    • Boxing Day, December 26th (possibly moved to Monday or - Tuesday)
    • -
    + public UnitedKingdom() : this(Market.Settlement) { } + public UnitedKingdom(Market m) : base() + { + switch (m) + { + case Market.Settlement: + calendar_ = Settlement.Singleton; + break; + case Market.Exchange: + calendar_ = Exchange.Singleton; + break; + case Market.Metals: + calendar_ = Metals.Singleton; + break; + default: + throw new ArgumentException("Unknown market: " + m); + } + } - \todo add LIFFE - \test the correctness of the returned results is tested against a list of known holidays. - */ + private class Settlement : Calendar.WesternImpl + { + public static readonly Settlement Singleton = new Settlement(); + private Settlement() { } - public class UnitedKingdom : Calendar { - public enum Market { Settlement, Exchange, Metals } + public override string name() { return "UK settlement"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); - public UnitedKingdom() : this(Market.Settlement) { } - public UnitedKingdom(Market m) : base() { - switch (m) { - case Market.Settlement: - calendar_ = Settlement.Singleton; - break; - case Market.Exchange: - calendar_ = Exchange.Singleton; - break; - case Market.Metals: - calendar_ = Metals.Singleton; - break; - default: - throw new ArgumentException("Unknown market: " + m); - } - } + if (isWeekend(w) + // New Year's Day (possibly moved to Monday) + || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) && m == Month.January) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // first Monday of May (Early May Bank Holiday) + || (d <= 7 && w == DayOfWeek.Monday && m == Month.May) + // last Monday of May (Spring Bank Holiday) + || (d >= 25 && w == DayOfWeek.Monday && m == Month.May && y != 2002) + // last Monday of August (Summer Bank Holiday) + || (d >= 25 && w == DayOfWeek.Monday && m == Month.August) + // Christmas (possibly moved to Monday or Tuesday) + || ((d == 25 || (d == 27 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) && m == Month.December) + // Boxing Day (possibly moved to Monday or Tuesday) + || ((d == 26 || (d == 28 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) && m == Month.December) + // June 3rd, 2002 only (Golden Jubilee Bank Holiday) + // June 4rd, 2002 only (special Spring Bank Holiday) + || ((d == 3 || d == 4) && m == Month.June && y == 2002) + // December 31st, 1999 only + || (d == 31 && m == Month.December && y == 1999)) + return false; + return true; + } + } + private class Exchange : Calendar.WesternImpl + { + internal static readonly Exchange Singleton = new Exchange(); + private Exchange() { } - private class Settlement : Calendar.WesternImpl { - public static readonly Settlement Singleton = new Settlement(); - private Settlement() { } + public override string name() { return "London stock exchange"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + if (isWeekend(w) + // New Year's Day (possibly moved to Monday) + || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) && m == Month.January) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // first Monday of May (Early May Bank Holiday) + || (d <= 7 && w == DayOfWeek.Monday && m == Month.May) + // last Monday of May (Spring Bank Holiday) + || (d >= 25 && w == DayOfWeek.Monday && m == Month.May && y != 2002) + // last Monday of August (Summer Bank Holiday) + || (d >= 25 && w == DayOfWeek.Monday && m == Month.August) + // Christmas (possibly moved to Monday or Tuesday) + || ((d == 25 || (d == 27 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) && m == Month.December) + // Boxing Day (possibly moved to Monday or Tuesday) + || ((d == 26 || (d == 28 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) && m == Month.December) + // June 3rd, 2002 only (Golden Jubilee Bank Holiday) + // June 4rd, 2002 only (special Spring Bank Holiday) + || ((d == 3 || d == 4) && m == Month.June && y == 2002) + // December 31st, 1999 only + || (d == 31 && m == Month.December && y == 1999)) + return false; + return true; + } + } + private class Metals : Calendar.WesternImpl + { + internal static readonly Metals Singleton = new Metals(); + private Metals() { } - public override string name() { return "UK settlement"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day (possibly moved to Monday) - || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) && m == Month.January) - // Good Friday - || (dd == em-3) - // Easter Monday - || (dd == em) - // first Monday of May (Early May Bank Holiday) - || (d <= 7 && w == DayOfWeek.Monday && m == Month.May) - // last Monday of May (Spring Bank Holiday) - || (d >= 25 && w == DayOfWeek.Monday && m == Month.May && y != 2002) - // last Monday of August (Summer Bank Holiday) - || (d >= 25 && w == DayOfWeek.Monday && m == Month.August) - // Christmas (possibly moved to Monday or Tuesday) - || ((d == 25 || (d == 27 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) && m == Month.December) - // Boxing Day (possibly moved to Monday or Tuesday) - || ((d == 26 || (d == 28 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) && m == Month.December) - // June 3rd, 2002 only (Golden Jubilee Bank Holiday) - // June 4rd, 2002 only (special Spring Bank Holiday) - || ((d == 3 || d == 4) && m == Month.June && y == 2002) - // December 31st, 1999 only - || (d == 31 && m == Month.December && y == 1999)) - return false; - return true; - } - } - private class Exchange : Calendar.WesternImpl { - internal static readonly Exchange Singleton = new Exchange(); - private Exchange() { } - - public override string name() { return "London stock exchange"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - if (isWeekend(w) - // New Year's Day (possibly moved to Monday) - || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) && m == Month.January) - // Good Friday - || (dd == em-3) - // Easter Monday - || (dd == em) - // first Monday of May (Early May Bank Holiday) - || (d <= 7 && w == DayOfWeek.Monday && m == Month.May) - // last Monday of May (Spring Bank Holiday) - || (d >= 25 && w == DayOfWeek.Monday && m == Month.May && y != 2002) - // last Monday of August (Summer Bank Holiday) - || (d >= 25 && w == DayOfWeek.Monday && m == Month.August) - // Christmas (possibly moved to Monday or Tuesday) - || ((d == 25 || (d == 27 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) && m == Month.December) - // Boxing Day (possibly moved to Monday or Tuesday) - || ((d == 26 || (d == 28 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) && m == Month.December) - // June 3rd, 2002 only (Golden Jubilee Bank Holiday) - // June 4rd, 2002 only (special Spring Bank Holiday) - || ((d == 3 || d == 4) && m == Month.June && y == 2002) - // December 31st, 1999 only - || (d == 31 && m == Month.December && y == 1999)) - return false; - return true; - } - } - private class Metals : Calendar.WesternImpl { - internal static readonly Metals Singleton = new Metals(); - private Metals() { } - - public override string name() { return "London metals exchange"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - if (isWeekend(w) - // New Year's Day (possibly moved to Monday) - || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) && m == Month.January) - // Good Friday - || (dd == em-3) - // Easter Monday - || (dd == em) - // first Monday of May (Early May Bank Holiday) - || (d <= 7 && w == DayOfWeek.Monday && m == Month.May) - // last Monday of May (Spring Bank Holiday) - || (d >= 25 && w == DayOfWeek.Monday && m == Month.May && y != 2002) - // last Monday of August (Summer Bank Holiday) - || (d >= 25 && w == DayOfWeek.Monday && m == Month.August) - // Christmas (possibly moved to Monday or Tuesday) - || ((d == 25 || (d == 27 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) && m == Month.December) - // Boxing Day (possibly moved to Monday or Tuesday) - || ((d == 26 || (d == 28 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) && m == Month.December) - // June 3rd, 2002 only (Golden Jubilee Bank Holiday) - // June 4rd, 2002 only (special Spring Bank Holiday) - || ((d == 3 || d == 4) && m == Month.June && y == 2002) - // December 31st, 1999 only - || (d == 31 && m == Month.December && y == 1999)) - return false; - return true; - } - } - } + public override string name() { return "London metals exchange"; } + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + if (isWeekend(w) + // New Year's Day (possibly moved to Monday) + || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) && m == Month.January) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // first Monday of May (Early May Bank Holiday) + || (d <= 7 && w == DayOfWeek.Monday && m == Month.May) + // last Monday of May (Spring Bank Holiday) + || (d >= 25 && w == DayOfWeek.Monday && m == Month.May && y != 2002) + // last Monday of August (Summer Bank Holiday) + || (d >= 25 && w == DayOfWeek.Monday && m == Month.August) + // Christmas (possibly moved to Monday or Tuesday) + || ((d == 25 || (d == 27 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) && m == Month.December) + // Boxing Day (possibly moved to Monday or Tuesday) + || ((d == 26 || (d == 28 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) && m == Month.December) + // June 3rd, 2002 only (Golden Jubilee Bank Holiday) + // June 4rd, 2002 only (special Spring Bank Holiday) + || ((d == 3 || d == 4) && m == Month.June && y == 2002) + // December 31st, 1999 only + || (d == 31 && m == Month.December && y == 1999)) + return false; + return true; + } + } + } } diff --git a/src/QLNet/Time/Calendars/UnitedStates.cs b/src/QLNet/Time/Calendars/UnitedStates.cs index 824317a04..631545929 100644 --- a/src/QLNet/Time/Calendars/UnitedStates.cs +++ b/src/QLNet/Time/Calendars/UnitedStates.cs @@ -1,25 +1,26 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - //! United States calendars +namespace QLNet +{ + //! United States calendars /*! Public holidays (see: http://www.opm.gov/fedhol/):
    • Saturdays
    • @@ -106,27 +107,27 @@ third Monday in February against a list of known holidays. */ - public class UnitedStates : Calendar + public class UnitedStates : Calendar { // a few rules used by multiple calendars - protected static bool isWashingtonBirthday( int d, Month m, int y, DayOfWeek w ) + protected static bool isWashingtonBirthday(int d, Month m, int y, DayOfWeek w) { - if ( y >= 1971 ) + if (y >= 1971) { // third Monday in February - return ( d >= 15 && d <= 21 ) && w == DayOfWeek.Monday && m == Month.February; + return (d >= 15 && d <= 21) && w == DayOfWeek.Monday && m == Month.February; } else { // February 22nd, possily adjusted - return ( d == 22 || ( d == 23 && w == DayOfWeek.Monday ) - || ( d == 21 && w == DayOfWeek.Friday ) ) && m == Month.February; + return (d == 22 || (d == 23 && w == DayOfWeek.Monday) + || (d == 21 && w == DayOfWeek.Friday)) && m == Month.February; } } - protected static bool isMemorialDay( int d, Month m, int y, DayOfWeek w ) + protected static bool isMemorialDay(int d, Month m, int y, DayOfWeek w) { - if ( y >= 1971 ) + if (y >= 1971) { // last Monday in May return d >= 25 && w == DayOfWeek.Monday && m == Month.May; @@ -134,190 +135,198 @@ protected static bool isMemorialDay( int d, Month m, int y, DayOfWeek w ) else { // May 30th, possibly adjusted - return ( d == 30 || ( d == 31 && w == DayOfWeek.Monday ) - || ( d == 29 && w == DayOfWeek.Friday ) ) && m == Month.May; + return (d == 30 || (d == 31 && w == DayOfWeek.Monday) + || (d == 29 && w == DayOfWeek.Friday)) && m == Month.May; } } - protected static bool isLaborDay( int d, Month m, int y, DayOfWeek w ) + protected static bool isLaborDay(int d, Month m, int y, DayOfWeek w) { // first Monday in September return d <= 7 && w == DayOfWeek.Monday && m == Month.September; } - protected static bool isColumbusDay( int d, Month m, int y, DayOfWeek w ) + protected static bool isColumbusDay(int d, Month m, int y, DayOfWeek w) { // second Monday in October - return ( d >= 8 && d <= 14 ) && w == DayOfWeek.Monday && m == Month.October - && y >= 1971; + return (d >= 8 && d <= 14) && w == DayOfWeek.Monday && m == Month.October + && y >= 1971; } - protected static bool isVeteransDay( int d, Month m, int y, DayOfWeek w ) + protected static bool isVeteransDay(int d, Month m, int y, DayOfWeek w) { - if ( y <= 1970 || y >= 1978 ) + if (y <= 1970 || y >= 1978) { // November 11th, adjusted - return ( d == 11 || ( d == 12 && w == DayOfWeek.Monday ) || - ( d == 10 && w == DayOfWeek.Friday ) ) && m == Month.November; + return (d == 11 || (d == 12 && w == DayOfWeek.Monday) || + (d == 10 && w == DayOfWeek.Friday)) && m == Month.November; } else { // fourth Monday in October - return ( d >= 22 && d <= 28 ) && w == DayOfWeek.Monday && m == Month.October; + return (d >= 22 && d <= 28) && w == DayOfWeek.Monday && m == Month.October; } } //! US calendars - public enum Market { + public enum Market + { Settlement, //!< generic settlement calendar NYSE, //!< New York stock exchange calendar GovernmentBond, //!< government-bond calendar NERC //!< off-peak days for NERC - }; + } public UnitedStates() : this(Market.Settlement) { } - public UnitedStates(Market m) : base() { - switch (m) { - case Market.Settlement: - calendar_ = Settlement.Singleton; - break; - case Market.NYSE: - calendar_ = NYSE.Singleton; - break; - case Market.GovernmentBond: - calendar_ = GovernmentBond.Singleton; - break; - case Market.NERC: - calendar_ = NERC.Singleton; - break; - default: - throw new ArgumentException("Unknown market: " + m); + public UnitedStates(Market m) : base() + { + switch (m) + { + case Market.Settlement: + calendar_ = Settlement.Singleton; + break; + case Market.NYSE: + calendar_ = NYSE.Singleton; + break; + case Market.GovernmentBond: + calendar_ = GovernmentBond.Singleton; + break; + case Market.NERC: + calendar_ = NERC.Singleton; + break; + default: + throw new ArgumentException("Unknown market: " + m); } } - private class Settlement : Calendar.WesternImpl { + private class Settlement : Calendar.WesternImpl + { public static readonly Settlement Singleton = new Settlement(); private Settlement() { } public override string name() { return "US settlement"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day; - Month m = (Month)date.Month; - int y = date.Year; - if (isWeekend(w) - // New Year's Day (possibly moved to Monday if on Sunday) - || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) && m == Month.January) - // (or to Friday if on Saturday) - || (d == 31 && w == DayOfWeek.Friday && m == Month.December) - // Martin Luther King's birthday (third Monday in January) - || ((d >= 15 && d <= 21) && w == DayOfWeek.Monday && m == Month.January && y >= 1983) - // Washington's birthday (third Monday in February) - || isWashingtonBirthday( d, m, y, w ) - // Memorial Day (last Monday in May) - || isMemorialDay( d, m, y, w ) - // Independence Day (Monday if Sunday or Friday if Saturday) - || ((d == 4 || (d == 5 && w == DayOfWeek.Monday) || - (d == 3 && w == DayOfWeek.Friday)) && m == Month.July) - // Labor Day (first Monday in September) - || isLaborDay( d, m, y, w ) - // Columbus Day (second Monday in October) - || isColumbusDay( d, m, y, w ) - // Veteran's Day (Monday if Sunday or Friday if Saturday) - || isVeteransDay( d, m, y, w ) - // Thanksgiving Day (fourth Thursday in November) - || ((d >= 22 && d <= 28) && w == DayOfWeek.Thursday && m == Month.November) - // Christmas (Monday if Sunday or Friday if Saturday) - || ((d == 25 || (d == 26 && w == DayOfWeek.Monday) || - (d == 24 && w == DayOfWeek.Friday)) && m == Month.December)) - return false; - return true; + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day; + Month m = (Month)date.Month; + int y = date.Year; + if (isWeekend(w) + // New Year's Day (possibly moved to Monday if on Sunday) + || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) && m == Month.January) + // (or to Friday if on Saturday) + || (d == 31 && w == DayOfWeek.Friday && m == Month.December) + // Martin Luther King's birthday (third Monday in January) + || ((d >= 15 && d <= 21) && w == DayOfWeek.Monday && m == Month.January && y >= 1983) + // Washington's birthday (third Monday in February) + || isWashingtonBirthday(d, m, y, w) + // Memorial Day (last Monday in May) + || isMemorialDay(d, m, y, w) + // Independence Day (Monday if Sunday or Friday if Saturday) + || ((d == 4 || (d == 5 && w == DayOfWeek.Monday) || + (d == 3 && w == DayOfWeek.Friday)) && m == Month.July) + // Labor Day (first Monday in September) + || isLaborDay(d, m, y, w) + // Columbus Day (second Monday in October) + || isColumbusDay(d, m, y, w) + // Veteran's Day (Monday if Sunday or Friday if Saturday) + || isVeteransDay(d, m, y, w) + // Thanksgiving Day (fourth Thursday in November) + || ((d >= 22 && d <= 28) && w == DayOfWeek.Thursday && m == Month.November) + // Christmas (Monday if Sunday or Friday if Saturday) + || ((d == 25 || (d == 26 && w == DayOfWeek.Monday) || + (d == 24 && w == DayOfWeek.Friday)) && m == Month.December)) + return false; + return true; } } - private class NYSE : Calendar.WesternImpl { + private class NYSE : Calendar.WesternImpl + { public static readonly NYSE Singleton = new NYSE(); private NYSE() { } - + public override string name() { return "New York stock exchange"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - if (isWeekend(w) - // New Year's Day (possibly moved to Monday if on Sunday) - || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) && m == Month.January) - // Washington's birthday (third Monday in February) - || isWashingtonBirthday( d, m, y, w ) - // Good Friday - || (dd == em - 3) - // Memorial Day (last Monday in May) - || isMemorialDay( d, m, y, w ) - // Independence Day (Monday if Sunday or Friday if Saturday) - || ((d == 4 || (d == 5 && w == DayOfWeek.Monday) || - (d == 3 && w == DayOfWeek.Friday)) && m == Month.July) - // Labor Day (first Monday in September) - || isLaborDay( d, m, y, w ) - // Thanksgiving Day (fourth Thursday in November) - || ((d >= 22 && d <= 28) && w == DayOfWeek.Thursday && m == Month.November) - // Christmas (Monday if Sunday or Friday if Saturday) - || ((d == 25 || (d == 26 && w == DayOfWeek.Monday) || - (d == 24 && w == DayOfWeek.Friday)) && m == Month.December) - ) return false; + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + if (isWeekend(w) + // New Year's Day (possibly moved to Monday if on Sunday) + || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) && m == Month.January) + // Washington's birthday (third Monday in February) + || isWashingtonBirthday(d, m, y, w) + // Good Friday + || (dd == em - 3) + // Memorial Day (last Monday in May) + || isMemorialDay(d, m, y, w) + // Independence Day (Monday if Sunday or Friday if Saturday) + || ((d == 4 || (d == 5 && w == DayOfWeek.Monday) || + (d == 3 && w == DayOfWeek.Friday)) && m == Month.July) + // Labor Day (first Monday in September) + || isLaborDay(d, m, y, w) + // Thanksgiving Day (fourth Thursday in November) + || ((d >= 22 && d <= 28) && w == DayOfWeek.Thursday && m == Month.November) + // Christmas (Monday if Sunday or Friday if Saturday) + || ((d == 25 || (d == 26 && w == DayOfWeek.Monday) || + (d == 24 && w == DayOfWeek.Friday)) && m == Month.December) + ) + return false; - if ( y >= 1998 && ( d >= 15 && d <= 21 ) && w == DayOfWeek.Monday && m == Month.January ) - // Martin Luther King's birthday (third Monday in January) - return false; + if (y >= 1998 && (d >= 15 && d <= 21) && w == DayOfWeek.Monday && m == Month.January) + // Martin Luther King's birthday (third Monday in January) + return false; - if ( ( y <= 1968 || ( y <= 1980 && y % 4 == 0 ) ) && m == Month.November - && d <= 7 && w == DayOfWeek.Tuesday ) - // Presidential election days - return false; + if ((y <= 1968 || (y <= 1980 && y % 4 == 0)) && m == Month.November + && d <= 7 && w == DayOfWeek.Tuesday) + // Presidential election days + return false; // Special closings if ( // Hurricane Sandy - (y == 2012 && m == Month.October && (d == 29 || d == 30)) - // President Ford's funeral - || (y == 2007 && m == Month.January && d == 2) - // President Reagan's funeral - || (y == 2004 && m == Month.June && d == 11) - // September 11-14, 2001 - || (y == 2001 && m == Month.September && (11 <= d && d <= 14)) - // President Nixon's funeral - || (y == 1994 && m == Month.April && d == 27) - // Hurricane Gloria - || (y == 1985 && m == Month.September && d == 27) - // 1977 Blackout - || (y == 1977 && m == Month.July && d == 14) - // Funeral of former President Lyndon B. Johnson. - || (y == 1973 && m == Month.January && d == 25) - // Funeral of former President Harry S. Truman - || (y == 1972 && m == Month.December && d == 28) - // National Day of Participation for the lunar exploration. - || (y == 1969 && m == Month.July && d == 21) - // Funeral of former President Eisenhower. - || (y == 1969 && m == Month.March && d == 31) - // Closed all day - heavy snow. - || (y == 1969 && m == Month.February && d == 10) - // Day after Independence Day. - || (y == 1968 && m == Month.July && d == 5) - // June 12-Dec. 31, 1968 - // Four day week (closed on Wednesdays) - Paperwork Crisis - || (y == 1968 && dd >= 163 && w == DayOfWeek.Wednesday) - // Day of mourning for Martin Luther King Jr. - || (y == 1968 && m == Month.April && d == 9) - // Funeral of President Kennedy - || (y == 1963 && m == Month.November && d == 25) - // Day before Decoration Day - || (y == 1961 && m == Month.May && d == 29) - // Day after Christmas - || (y == 1958 && m == Month.December && d == 26) - // Christmas Eve - || ((y == 1954 || y == 1956 || y == 1965) - && m == Month.December && d == 24) - ) + (y == 2012 && m == Month.October && (d == 29 || d == 30)) + // President Ford's funeral + || (y == 2007 && m == Month.January && d == 2) + // President Reagan's funeral + || (y == 2004 && m == Month.June && d == 11) + // September 11-14, 2001 + || (y == 2001 && m == Month.September && (11 <= d && d <= 14)) + // President Nixon's funeral + || (y == 1994 && m == Month.April && d == 27) + // Hurricane Gloria + || (y == 1985 && m == Month.September && d == 27) + // 1977 Blackout + || (y == 1977 && m == Month.July && d == 14) + // Funeral of former President Lyndon B. Johnson. + || (y == 1973 && m == Month.January && d == 25) + // Funeral of former President Harry S. Truman + || (y == 1972 && m == Month.December && d == 28) + // National Day of Participation for the lunar exploration. + || (y == 1969 && m == Month.July && d == 21) + // Funeral of former President Eisenhower. + || (y == 1969 && m == Month.March && d == 31) + // Closed all day - heavy snow. + || (y == 1969 && m == Month.February && d == 10) + // Day after Independence Day. + || (y == 1968 && m == Month.July && d == 5) + // June 12-Dec. 31, 1968 + // Four day week (closed on Wednesdays) - Paperwork Crisis + || (y == 1968 && dd >= 163 && w == DayOfWeek.Wednesday) + // Day of mourning for Martin Luther King Jr. + || (y == 1968 && m == Month.April && d == 9) + // Funeral of President Kennedy + || (y == 1963 && m == Month.November && d == 25) + // Day before Decoration Day + || (y == 1961 && m == Month.May && d == 29) + // Day after Christmas + || (y == 1958 && m == Month.December && d == 26) + // Christmas Eve + || ((y == 1954 || y == 1956 || y == 1965) + && m == Month.December && d == 24) + ) { return false; } @@ -325,72 +334,76 @@ public override bool isBusinessDay(Date date) { return true; } } - private class GovernmentBond : Calendar.WesternImpl { + private class GovernmentBond : Calendar.WesternImpl + { public static readonly GovernmentBond Singleton = new GovernmentBond(); private GovernmentBond() { } public override string name() { return "US government bond market"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - if (isWeekend(w) - // New Year's Day (possibly moved to Monday if on Sunday) - || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) && m == Month.January) - // Martin Luther King's birthday (third Monday in January) - || ( ( d >= 15 && d <= 21 ) && w == DayOfWeek.Monday && m == Month.January && y >= 1983 ) - // Washington's birthday (third Monday in February) - || isWashingtonBirthday( d, m, y, w ) - // Good Friday - || (dd == em - 3) - // Memorial Day (last Monday in May) - || isMemorialDay( d, m, y, w ) - // Independence Day (Monday if Sunday or Friday if Saturday) - || ((d == 4 || (d == 5 && w == DayOfWeek.Monday) || - (d == 3 && w == DayOfWeek.Friday)) && m == Month.July) - // Labor Day (first Monday in September) - || isLaborDay( d, m, y, w ) - // Columbus Day (second Monday in October) - || isColumbusDay( d, m, y, w ) - // Veteran's Day (Monday if Sunday or Friday if Saturday) - || isVeteransDay( d, m, y, w ) - // Thanksgiving Day (fourth Thursday in November) - || ((d >= 22 && d <= 28) && w == DayOfWeek.Thursday && m == Month.November) - // Christmas (Monday if Sunday or Friday if Saturday) - || ((d == 25 || (d == 26 && w == DayOfWeek.Monday) || - (d == 24 && w == DayOfWeek.Friday)) && m == Month.December)) - return false; - return true; + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday(y); + if (isWeekend(w) + // New Year's Day (possibly moved to Monday if on Sunday) + || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) && m == Month.January) + // Martin Luther King's birthday (third Monday in January) + || ((d >= 15 && d <= 21) && w == DayOfWeek.Monday && m == Month.January && y >= 1983) + // Washington's birthday (third Monday in February) + || isWashingtonBirthday(d, m, y, w) + // Good Friday + || (dd == em - 3) + // Memorial Day (last Monday in May) + || isMemorialDay(d, m, y, w) + // Independence Day (Monday if Sunday or Friday if Saturday) + || ((d == 4 || (d == 5 && w == DayOfWeek.Monday) || + (d == 3 && w == DayOfWeek.Friday)) && m == Month.July) + // Labor Day (first Monday in September) + || isLaborDay(d, m, y, w) + // Columbus Day (second Monday in October) + || isColumbusDay(d, m, y, w) + // Veteran's Day (Monday if Sunday or Friday if Saturday) + || isVeteransDay(d, m, y, w) + // Thanksgiving Day (fourth Thursday in November) + || ((d >= 22 && d <= 28) && w == DayOfWeek.Thursday && m == Month.November) + // Christmas (Monday if Sunday or Friday if Saturday) + || ((d == 25 || (d == 26 && w == DayOfWeek.Monday) || + (d == 24 && w == DayOfWeek.Friday)) && m == Month.December)) + return false; + return true; } } - private class NERC : Calendar.WesternImpl { + private class NERC : Calendar.WesternImpl + { public static readonly NERC Singleton = new NERC(); private NERC() { } public override string name() { return "North American Energy Reliability Council"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day; - Month m = (Month)date.Month; - int y = date.Year; - if (isWeekend(w) - // New Year's Day (possibly moved to Monday if on Sunday) - || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) && m == Month.January) - // Memorial Day (last Monday in May) - || isMemorialDay( d, m, y, w ) - // Independence Day (Monday if Sunday) - || ((d == 4 || (d == 5 && w == DayOfWeek.Monday)) && m == Month.July) - // Labor Day (first Monday in September) - || isLaborDay( d, m, y, w ) - // Thanksgiving Day (fourth Thursday in November) - || ((d >= 22 && d <= 28) && w == DayOfWeek.Thursday && m == Month.November) - // Christmas (Monday if Sunday) - || ((d == 25 || (d == 26 && w == DayOfWeek.Monday)) && m == Month.December)) - return false; - return true; + public override bool isBusinessDay(Date date) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day; + Month m = (Month)date.Month; + int y = date.Year; + if (isWeekend(w) + // New Year's Day (possibly moved to Monday if on Sunday) + || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) && m == Month.January) + // Memorial Day (last Monday in May) + || isMemorialDay(d, m, y, w) + // Independence Day (Monday if Sunday) + || ((d == 4 || (d == 5 && w == DayOfWeek.Monday)) && m == Month.July) + // Labor Day (first Monday in September) + || isLaborDay(d, m, y, w) + // Thanksgiving Day (fourth Thursday in November) + || ((d >= 22 && d <= 28) && w == DayOfWeek.Thursday && m == Month.November) + // Christmas (Monday if Sunday) + || ((d == 25 || (d == 26 && w == DayOfWeek.Monday)) && m == Month.December)) + return false; + return true; } } - } + } } diff --git a/src/QLNet/Time/Calendars/WeekendsOnly.cs b/src/QLNet/Time/Calendars/WeekendsOnly.cs index d2c60f90c..77b2c16eb 100644 --- a/src/QLNet/Time/Calendars/WeekendsOnly.cs +++ b/src/QLNet/Time/Calendars/WeekendsOnly.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Time/Calendars/argentina.cs b/src/QLNet/Time/Calendars/argentina.cs deleted file mode 100644 index 9023ff1f1..000000000 --- a/src/QLNet/Time/Calendars/argentina.cs +++ /dev/null @@ -1,93 +0,0 @@ -/* - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! Argentinian calendars - /*! Holidays for the Buenos Aires stock exchange - (data from ): -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Holy Thursday
      • -
      • Good Friday
      • -
      • Labour Day, May 1st
      • -
      • May Revolution, May 25th
      • -
      • Death of General Manuel Belgrano, third Monday of June
      • -
      • Independence Day, July 9th
      • -
      • Death of General José de San Martín, third Monday of August
      • -
      • Columbus Day, October 12th (moved to preceding Monday if - on Tuesday or Wednesday and to following if on Thursday - or Friday)
      • -
      • Immaculate Conception, December 8th
      • -
      • Christmas Eve, December 24th
      • -
      • New Year's Eve, December 31th
      • -
      - - \ingroup calendars - */ - public class Argentina : Calendar { - public Argentina() : base(Impl.Singleton) { } - - class Impl : Calendar.WesternImpl { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Buenos Aires stock exchange"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Holy Thursday - || (dd == em-4) - // Good Friday - || (dd == em-3) - // Labour Day - || (d == 1 && m == Month.May) - // May Revolution - || (d == 25 && m == Month.May) - // Death of General Manuel Belgrano - || (d >= 15 && d <= 21 && w == DayOfWeek.Monday && m == Month.June) - // Independence Day - || (d == 9 && m == Month.July) - // Death of General José de San Martín - || (d >= 15 && d <= 21 && w == DayOfWeek.Monday && m == Month.August) - // Columbus Day - || ((d == 10 || d == 11 || d == 12 || d == 15 || d == 16) - && w == DayOfWeek.Monday && m == Month.October) - // Immaculate Conception - || (d == 8 && m == Month.December) - // Christmas Eve - || (d == 24 && m == Month.December) - // New Year's Eve - || ((d == 31 || (d == 30 && w == DayOfWeek.Friday)) && m == Month.December)) - return false; - return true; - } - }; - }; -} diff --git a/src/QLNet/Time/Calendars/australia.cs b/src/QLNet/Time/Calendars/australia.cs deleted file mode 100644 index f618b8b71..000000000 --- a/src/QLNet/Time/Calendars/australia.cs +++ /dev/null @@ -1,94 +0,0 @@ -/* - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Andrea Maggiulli - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - //! Australian calendar - /*! Holidays: -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Australia Day, January 26th (possibly moved to Monday)
      • -
      • Good Friday
      • -
      • Easter Monday
      • -
      • ANZAC Day. April 25th (possibly moved to Monday)
      • -
      • Queen's Birthday, second Monday in June
      • -
      • Bank Holiday, first Monday in August
      • -
      • Labour Day, first Monday in October
      • -
      • Christmas, December 25th (possibly moved to Monday or Tuesday)
      • -
      • Boxing Day, December 26th (possibly moved to Monday or - Tuesday)
      • -
      - - \ingroup calendars - */ - public class Australia : Calendar { - public Australia() : base(Impl.Singleton) { } - - class Impl : Calendar.WesternImpl { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Australia"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day (possibly moved to Monday) - || (d == 1 && m == Month.January) - // Australia Day, January 26th (possibly moved to Monday) - || ((d == 26 || ((d == 27 || d == 28) && w == DayOfWeek.Monday)) && - m == Month.January) - // Good Friday - || (dd == em-3) - // Easter Monday - || (dd == em) - // ANZAC Day, April 25th (possibly moved to Monday) - || ((d == 25 || (d == 26 && w == DayOfWeek.Monday)) && m == Month.April) - // Queen's Birthday, second Monday in June - || ((d > 7 && d <= 14) && w == DayOfWeek.Monday && m == Month.June) - // Bank Holiday, first Monday in August - || (d <= 7 && w == DayOfWeek.Monday && m == Month.August) - // Labour Day, first Monday in October - || (d <= 7 && w == DayOfWeek.Monday && m == Month.October) - // Christmas, December 25th (possibly Monday or Tuesday) - || ((d == 25 || (d == 27 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) - && m == Month.December) - // Boxing Day, December 26th (possibly Monday or Tuesday) - || ((d == 26 || (d == 28 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) - && m == Month.December)) - return false; - return true; - } - }; - }; - -} - - - - diff --git a/src/QLNet/Time/Calendars/bespokecalendar.cs b/src/QLNet/Time/Calendars/bespokecalendar.cs deleted file mode 100644 index f7b415854..000000000 --- a/src/QLNet/Time/Calendars/bespokecalendar.cs +++ /dev/null @@ -1,61 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet { - //! Bespoke calendar - /*! This calendar has no predefined set of business days. Holidays - and weekdays can be defined by means of the provided - interface. Instances constructed by copying remain linked to - the original one; adding a new holiday or weekday will affect - all linked instances. - - \ingroup calendars - */ - public class BespokeCalendar : Calendar { - private string name_; - public override string name() { return name_; } - - /*! \warning different bespoke calendars created with the same - name (or different bespoke calendars created with - no name) will compare as equal. - */ - public BespokeCalendar() : this("") { } - public BespokeCalendar(string name) : base(new Impl()) { - name_ = name; - } - - //! marks the passed day as part of the weekend - public void addWeekend(DayOfWeek w) - { - Impl impl = calendar_ as Impl; - if (impl != null) impl.addWeekend(w); - } - - // here implementation does not follow a singleton pattern - class Impl : Calendar.WesternImpl { - public override bool isWeekend(DayOfWeek w) { return (weekend_.Contains(w)); } - public override bool isBusinessDay(Date date) { return !isWeekend(date.DayOfWeek); } - public void addWeekend(DayOfWeek w) { weekend_.Add(w); } - - private List weekend_ = new List(); - } - } -} diff --git a/src/QLNet/Time/Calendars/brazil.cs b/src/QLNet/Time/Calendars/brazil.cs deleted file mode 100644 index 753517b25..000000000 --- a/src/QLNet/Time/Calendars/brazil.cs +++ /dev/null @@ -1,185 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! Brazilian calendar - /*! Banking holidays: -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Tiradentes's Day, April 21th
      • -
      • Labour Day, May 1st
      • -
      • Independence Day, September 7th
      • -
      • Nossa Sra. Aparecida Day, October 12th
      • -
      • All Souls Day, November 2nd
      • -
      • Republic Day, November 15th
      • -
      • Christmas, December 25th
      • -
      • Passion of Christ
      • -
      • Carnival
      • -
      • Corpus Christi
      • -
      - - Holidays for the Bovespa stock exchange -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Sao Paulo City Day, January 25th
      • -
      • Tiradentes's Day, April 21th
      • -
      • Labour Day, May 1st
      • -
      • Revolution Day, July 9th
      • -
      • Independence Day, September 7th
      • -
      • Nossa Sra. Aparecida Day, October 12th
      • -
      • All Souls Day, November 2nd
      • -
      • Republic Day, November 15th
      • -
      • Black Consciousness Day, November 20th (since 2007)
      • -
      • Christmas Eve, December 24th
      • -
      • Christmas, December 25th
      • -
      • Passion of Christ
      • -
      • Carnival
      • -
      • Corpus Christi
      • -
      • the last business day of the year
      • -
      - - \ingroup calendars - - \test the correctness of the returned results is tested - against a list of known holidays. - */ - public class Brazil : Calendar { - //! Brazilian calendars - public enum Market { Settlement, //!< generic settlement calendar - Exchange //!< BOVESPA calendar - } - - public Brazil() : this(Market.Settlement) { } - public Brazil(Market market) { - // all calendar instances on the same market share the same implementation instance - switch (market) { - case Market.Settlement: - calendar_ = SettlementImpl.Singleton; - break; - case Market.Exchange: - calendar_ = ExchangeImpl.Singleton; - break; - default: - Utils.QL_FAIL("unknown market"); - break; - } - } - - - private class SettlementImpl : Calendar.WesternImpl { - public static readonly SettlementImpl Singleton = new SettlementImpl(); - private SettlementImpl() { } - - public override string name() { return "Brazil"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day; - Month m = (Month)date.Month; - int y = date.Year; - int dd = date.DayOfYear; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Tiradentes Day - || (d == 21 && m == Month.April) - // Labor Day - || (d == 1 && m == Month.May) - // Independence Day - || (d == 7 && m == Month.September) - // Nossa Sra. Aparecida Day - || (d == 12 && m == Month.October) - // All Souls Day - || (d == 2 && m == Month.November) - // Republic Day - || (d == 15 && m == Month.November) - // Christmas - || (d == 25 && m == Month.December) - // Passion of Christ - || (dd == em-3) - // Carnival - || (dd == em-49 || dd == em-48) - // Corpus Christi - || (dd == em+59) - ) - return false; - return true; - } - } - - private class ExchangeImpl : Calendar.WesternImpl { - public static readonly ExchangeImpl Singleton = new ExchangeImpl(); - private ExchangeImpl() { } - - public override string name() { return "BOVESPA"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day; - Month m = (Month)date.Month; - int y = date.Year; - int dd = date.DayOfYear; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Sao Paulo City Day - || (d == 25 && m == Month.January) - // Tiradentes Day - || (d == 21 && m == Month.April) - // Labor Day - || (d == 1 && m == Month.May) - // Revolution Day - || (d == 9 && m == Month.July) - // Independence Day - || (d == 7 && m == Month.September) - // Nossa Sra. Aparecida Day - || (d == 12 && m == Month.October) - // All Souls Day - || (d == 2 && m == Month.November) - // Republic Day - || (d == 15 && m == Month.November) - // Black Consciousness Day - || (d == 20 && m == Month.November && y >= 2007) - // Christmas Eve - || ( d == 24 && m == Month.December ) - // Christmas - || (d == 25 && m == Month.December) - // Passion of Christ - || (dd == em-3) - // Carnival - || (dd == em-49 || dd == em-48) - // Corpus Christi - || (dd == em+59) - // last business day of the year - || (m == Month.December && (d == 31 || (d >= 29 && w == DayOfWeek.Friday))) - ) - return false; - return true; - } - } - - } -} diff --git a/src/QLNet/Time/Calendars/canada.cs b/src/QLNet/Time/Calendars/canada.cs deleted file mode 100644 index 90fb58388..000000000 --- a/src/QLNet/Time/Calendars/canada.cs +++ /dev/null @@ -1,177 +0,0 @@ -/* - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! Canadian calendar - /*! Banking holidays: -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st (possibly moved to Monday)
      • -
      • Family Day, third Monday of February (since 2008)
      • -
      • Good Friday
      • -
      • Easter Monday
      • -
      • Victoria Day, The Monday on or preceding 24 May
      • -
      • Canada Day, July 1st (possibly moved to Monday)
      • -
      • Provincial Holiday, first Monday of August
      • -
      • Labour Day, first Monday of September
      • -
      • Thanksgiving Day, second Monday of October
      • -
      • Remembrance Day, November 11th (possibly moved to Monday)
      • -
      • Christmas, December 25th (possibly moved to Monday or Tuesday)
      • -
      • Boxing Day, December 26th (possibly moved to Monday or - Tuesday)
      • -
      - - Holidays for the Toronto stock exchange (TSX): -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st (possibly moved to Monday)
      • -
      • Family Day, third Monday of February (since 2008)
      • -
      • Good Friday
      • -
      • Easter Monday
      • -
      • Victoria Day, The Monday on or preceding 24 May
      • -
      • Canada Day, July 1st (possibly moved to Monday)
      • -
      • Provincial Holiday, first Monday of August
      • -
      • Labour Day, first Monday of September
      • -
      • Thanksgiving Day, second Monday of October
      • -
      • Christmas, December 25th (possibly moved to Monday or Tuesday)
      • -
      • Boxing Day, December 26th (possibly moved to Monday or - Tuesday)
      • -
      - - \ingroup calendars - */ - public class Canada : Calendar { - public enum Market { - Settlement, //!< generic settlement calendar - TSX //!< Toronto stock exchange calendar - }; - - public Canada() : this(Market.Settlement) { } - public Canada(Market m) - : base() { - // all calendar instances on the same market share the same - // implementation instance - switch (m) { - case Market.Settlement: - calendar_ = Settlement.Singleton; - break; - case Market.TSX: - calendar_ = TSX.Singleton; - break; - default: - throw new ArgumentException("Unknown market: " + m); - } - } - - class Settlement : Calendar.WesternImpl { - public static readonly Settlement Singleton = new Settlement(); - private Settlement() { } - - public override string name() { return "Canada"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day (possibly moved to Monday) - || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) && m == Month.January) - // Family Day (third Monday in February, since 2008) - || ((d >= 15 && d <= 21) && w == DayOfWeek.Monday && m == Month.February - && y >= 2008) - // Good Friday - || (dd == em - 3) - // Easter Monday - || (dd == em) - // The Monday on or preceding 24 May (Victoria Day) - || (d > 17 && d <= 24 && w == DayOfWeek.Monday && m == Month.May) - // July 1st, possibly moved to Monday (Canada Day) - || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) && m == Month.July) - // first Monday of August (Provincial Holiday) - || (d <= 7 && w == DayOfWeek.Monday && m == Month.August) - // first Monday of September (Labor Day) - || (d <= 7 && w == DayOfWeek.Monday && m == Month.September) - // second Monday of October (Thanksgiving Day) - || (d > 7 && d <= 14 && w == DayOfWeek.Monday && m == Month.October) - // November 11th (possibly moved to Monday) - || ((d == 11 || ((d == 12 || d == 13) && w == DayOfWeek.Monday)) - && m == Month.November) - // Christmas (possibly moved to Monday or Tuesday) - || ((d == 25 || (d == 27 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) - && m == Month.December) - // Boxing Day (possibly moved to Monday or Tuesday) - || ((d == 26 || (d == 28 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) - && m == Month.December) - ) - return false; - return true; - } - } - - class TSX : Calendar.WesternImpl { - public static readonly TSX Singleton = new TSX(); - private TSX() { } - - public override string name() { return "TSX"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day (possibly moved to Monday) - || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) && m == Month.January) - // Family Day (third Monday in February, since 2008) - || ((d >= 15 && d <= 21) && w == DayOfWeek.Monday && m == Month.February - && y >= 2008) - // Good Friday - || (dd == em - 3) - // Easter Monday - || (dd == em) - // The Monday on or preceding 24 May (Victoria Day) - || (d > 17 && d <= 24 && w == DayOfWeek.Monday && m == Month.May) - // July 1st, possibly moved to Monday (Canada Day) - || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) && m == Month.July) - // first Monday of August (Provincial Holiday) - || (d <= 7 && w == DayOfWeek.Monday && m == Month.August) - // first Monday of September (Labor Day) - || (d <= 7 && w == DayOfWeek.Monday && m == Month.September) - // second Monday of October (Thanksgiving Day) - || (d > 7 && d <= 14 && w == DayOfWeek.Monday && m == Month.October) - // Christmas (possibly moved to Monday or Tuesday) - || ((d == 25 || (d == 27 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) - && m == Month.December) - // Boxing Day (possibly moved to Monday or Tuesday) - || ((d == 26 || (d == 28 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) - && m == Month.December) - ) - return false; - return true; - } - } - } -} \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/china.cs b/src/QLNet/Time/Calendars/china.cs deleted file mode 100644 index d8289e05a..000000000 --- a/src/QLNet/Time/Calendars/china.cs +++ /dev/null @@ -1,309 +0,0 @@ -/* - Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; -using System.Collections.Generic; - -namespace QLNet -{ - //! Chinese calendar - /*! Holidays: -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's day, January 1st (possibly followed by one or - two more holidays)
      • -
      • Labour Day, first week in May
      • -
      • National Day, one week from October 1st
      • -
      - - Other holidays for which no rule is given (data available for - 2004-2015 only): -
        -
      • Chinese New Year
      • -
      • Ching Ming Festival
      • -
      • Tuen Ng Festival
      • -
      • Mid-Autumn Festival
      • -
      • 70th anniversary of the victory of anti-Japaneses war
      • -
      - - SSE data from - IB data from - - \ingroup calendars - */ - public class China : Calendar - { - public enum Market - { - SSE, //!< Shanghai stock exchange - IB //!< Interbank calendar - }; - - public China( Market market = Market.SSE ) - { - - // all calendar instances on the same market share the same implementation instance - switch ( market ) - { - case Market.SSE: - calendar_ = SseImpl.Singleton; - break; - case Market.IB: - calendar_ = IbImpl.Singleton; - break; - default: - Utils.QL_FAIL( "unknown market" ); - break; - } - } - - private class SseImpl : Calendar - { - public static readonly SseImpl Singleton = new SseImpl(); - private SseImpl() { } - public override string name() { return "Shanghai stock exchange"; } - - public override bool isWeekend( DayOfWeek w ) - { - return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; - } - - public override bool isBusinessDay( Date date ) - { - DayOfWeek w = date.DayOfWeek; - int d = date.Day; - Month m = (Month)date.Month; - int y = date.Year; - - if ( isWeekend( w ) - // New Year's Day - || ( d == 1 && m == Month.January ) - || ( y == 2005 && d == 3 && m == Month.January ) - || ( y == 2006 && ( d == 2 || d == 3 ) && m == Month.January ) - || ( y == 2007 && d <= 3 && m == Month.January ) - || ( y == 2007 && d == 31 && m == Month.December ) - || ( y == 2009 && d == 2 && m == Month.January ) - || ( y == 2011 && d == 3 && m == Month.January ) - || ( y == 2012 && ( d == 2 || d == 3 ) && m == Month.January ) - || ( y == 2013 && d <= 3 && m == Month.January ) - || ( y == 2014 && d == 1 && m == Month.January ) - || ( y == 2015 && d <= 3 && m == Month.January ) - // Chinese New Year - || ( y == 2004 && d >= 19 && d <= 28 && m == Month.January ) - || ( y == 2005 && d >= 7 && d <= 15 && m == Month.February ) - || ( y == 2006 && ( ( d >= 26 && m == Month.January ) || - ( d <= 3 && m == Month.February ) ) ) - || ( y == 2007 && d >= 17 && d <= 25 && m == Month.February ) - || ( y == 2008 && d >= 6 && d <= 12 && m == Month.February ) - || ( y == 2009 && d >= 26 && d <= 30 && m == Month.January ) - || ( y == 2010 && d >= 15 && d <= 19 && m == Month.February ) - || ( y == 2011 && d >= 2 && d <= 8 && m == Month.February ) - || ( y == 2012 && d >= 23 && d <= 28 && m == Month.January ) - || ( y == 2013 && d >= 11 && d <= 15 && m == Month.February ) - || ( y == 2014 && d >= 31 && m == Month.January ) - || ( y == 2014 && d <= 6 && m == Month.February ) - || ( y == 2015 && d >= 18 && d <= 24 && m == Month.February ) - || ( y == 2016 && d >= 8 && d <= 12 && m == Month.February ) - // Ching Ming Festival - || ( y <= 2008 && d == 4 && m == Month.April ) - || ( y == 2009 && d == 6 && m == Month.April ) - || ( y == 2010 && d == 5 && m == Month.April ) - || ( y == 2011 && d >= 3 && d <= 5 && m == Month.April ) - || ( y == 2012 && d >= 2 && d <= 4 && m == Month.April ) - || ( y == 2013 && d >= 4 && d <= 5 && m == Month.April ) - || ( y == 2014 && d == 7 && m == Month.April ) - || ( y == 2015 && d >= 5 && d <= 6 && m == Month.April ) - || ( y == 2016 && d == 4 && m == Month.April ) - // Labor Day - || ( y <= 2007 && d >= 1 && d <= 7 && m == Month.May ) - || ( y == 2008 && d >= 1 && d <= 2 && m == Month.May ) - || ( y == 2009 && d == 1 && m == Month.May ) - || ( y == 2010 && d == 3 && m == Month.May ) - || ( y == 2011 && d == 2 && m == Month.May ) - || ( y == 2012 && ( ( d == 30 && m == Month.April ) || - ( d == 1 && m == Month.May ) ) ) - || ( y == 2013 && ( ( d >= 29 && m == Month.April ) || - ( d == 1 && m == Month.May ) ) ) - || ( y == 2014 && d >= 1 && d <= 3 && m == Month.May ) - || ( y == 2015 && d == 1 && m == Month.May ) - || ( y == 2016 && d >= 1 && d <= 2 && m == Month.May ) - // Tuen Ng Festival - || ( y <= 2008 && d == 9 && m == Month.June ) - || ( y == 2009 && ( d == 28 || d == 29 ) && m == Month.May ) - || ( y == 2010 && d >= 14 && d <= 16 && m == Month.June ) - || ( y == 2011 && d >= 4 && d <= 6 && m == Month.June ) - || ( y == 2012 && d >= 22 && d <= 24 && m == Month.June ) - || ( y == 2013 && d >= 10 && d <= 12 && m == Month.June ) - || ( y == 2014 && d == 2 && m == Month.June ) - || ( y == 2015 && d == 22 && m == Month.June ) - || ( y == 2016 && d >= 9 && d <= 10 && m == Month.June ) - // Mid-Autumn Festival - || ( y <= 2008 && d == 15 && m == Month.September ) - || ( y == 2010 && d >= 22 && d <= 24 && m == Month.September ) - || ( y == 2011 && d >= 10 && d <= 12 && m == Month.September ) - || ( y == 2012 && d == 30 && m == Month.September ) - || ( y == 2013 && d >= 19 && d <= 20 && m == Month.September ) - || ( y == 2014 && d == 8 && m == Month.September ) - || ( y == 2015 && d == 27 && m == Month.September ) - || ( y == 2016 && d >= 15 && d <= 16 && m == Month.September ) - // National Day - || ( y <= 2007 && d >= 1 && d <= 7 && m == Month.October ) - || ( y == 2008 && ( ( d >= 29 && m == Month.September ) || - ( d <= 3 && m == Month.October ) ) ) - || ( y == 2009 && d >= 1 && d <= 8 && m == Month.October ) - || ( y == 2010 && d >= 1 && d <= 7 && m == Month.October ) - || ( y == 2011 && d >= 1 && d <= 7 && m == Month.October ) - || ( y == 2012 && d >= 1 && d <= 7 && m == Month.October ) - || ( y == 2013 && d >= 1 && d <= 7 && m == Month.October ) - || ( y == 2014 && d >= 1 && d <= 7 && m == Month.October ) - || ( y == 2015 && d >= 1 && d <= 7 && m == Month.October ) - || ( y == 2016 && d >= 3 && d <= 7 && m == Month.October ) - // 70th anniversary of the victory of anti-Japaneses war - || ( y == 2015 && d >= 3 && d <= 4 && m == Month.September ) - ) - return false; - return true; - - } - } - - private class IbImpl : Calendar - { - public static readonly IbImpl Singleton = new IbImpl(); - - public IbImpl() - { - sseImpl = new China( Market.SSE ); - } - - public override string name() { return "China inter bank market"; } - - public override bool isWeekend( DayOfWeek w ) { return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; } - public override bool isBusinessDay( Date date ) - { - - List working_weekends = new List{ - // 2005 - new Date(5, Month.February, 2005), - new Date(6, Month.February, 2005), - new Date(30, Month.April, 2005), - new Date(8, Month.May, 2005), - new Date(8, Month.October, 2005), - new Date(9, Month.October, 2005), - new Date(31, Month.December, 2005), - //2006 - new Date(28, Month.January, 2006), - new Date(29, Month.April, 2006), - new Date(30, Month.April, 2006), - new Date(30, Month.September, 2006), - new Date(30, Month.December, 2006), - new Date(31, Month.December, 2006), - // 2007 - new Date(17, Month.February, 2007), - new Date(25, Month.February, 2007), - new Date(28, Month.April, 2007), - new Date(29, Month.April, 2007), - new Date(29, Month.September, 2007), - new Date(30, Month.September, 2007), - new Date(29, Month.December, 2007), - // 2008 - new Date(2, Month.February, 2008), - new Date(3, Month.February, 2008), - new Date(4, Month.May, 2008), - new Date(27, Month.September, 2008), - new Date(28, Month.September, 2008), - // 2009 - new Date(4, Month.January, 2009), - new Date(24, Month.January, 2009), - new Date(1, Month.February, 2009), - new Date(31, Month.May, 2009), - new Date(27, Month.September, 2009), - new Date(10, Month.October, 2009), - // 2010 - new Date(20, Month.February, 2010), - new Date(21, Month.February, 2010), - new Date(12, Month.June, 2010), - new Date(13, Month.June, 2010), - new Date(19, Month.September, 2010), - new Date(25, Month.September, 2010), - new Date(26, Month.September, 2010), - new Date(9, Month.October, 2010), - // 2011 - new Date(30, Month.January, 2011), - new Date(12, Month.February, 2011), - new Date(2, Month.April, 2011), - new Date(8, Month.October, 2011), - new Date(9, Month.October, 2011), - new Date(31, Month.December, 2011), - // 2012 - new Date(21, Month.January, 2012), - new Date(29, Month.January, 2012), - new Date(31, Month.March, 2012), - new Date(1, Month.April, 2012), - new Date(28, Month.April, 2012), - new Date(29, Month.September, 2012), - // 2013 - new Date(5,Month.January,2013), - new Date(6,Month.January,2013), - new Date(16,Month.February,2013), - new Date(17,Month.February,2013), - new Date(7,Month.April,2013), - new Date(27,Month.April,2013), - new Date(28,Month.April,2013), - new Date(8,Month.June,2013), - new Date(9,Month.June,2013), - new Date(22,Month.September,2013), - new Date(29,Month.September,2013), - new Date(12,Month.October,2013), - // 2014 - new Date(26,Month.January,2014), - new Date(8,Month.February,2014), - new Date(4,Month.May,2014), - new Date(28,Month.September,2014), - new Date(11,Month.October,2014), - // 2015 - new Date(4,Month.January,2015), - new Date(15,Month.February,2015), - new Date(28,Month.February,2015), - new Date(6,Month.September,2015), - new Date(10,Month.October,2015), - // 2016 - new Date(6,Month.February,2016), - new Date(14,Month.February,2016), - new Date(12,Month.June,2016), - new Date(18,Month.September,2016), - new Date(8,Month.October,2016), - new Date(9,Month.October,2016) - }; - - // If it is already a SSE business day, it must be a IB business day - return sseImpl.isBusinessDay( date ) || working_weekends.Contains( date ); - - } - - private Calendar sseImpl; - - }; - - } -} - diff --git a/src/QLNet/Time/Calendars/czechrepublic.cs b/src/QLNet/Time/Calendars/czechrepublic.cs deleted file mode 100644 index 6700f7358..000000000 --- a/src/QLNet/Time/Calendars/czechrepublic.cs +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! Czech calendars - /*! Holidays for the Prague stock exchange (see http://www.pse.cz/): -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Easter Monday
      • -
      • Labour Day, May 1st
      • -
      • Liberation Day, May 8th
      • -
      • SS. Cyril and Methodius, July 5th
      • -
      • Jan Hus Day, July 6th
      • -
      • Czech Statehood Day, September 28th
      • -
      • Independence Day, October 28th
      • -
      • Struggle for Freedom and Democracy Day, November 17th
      • -
      • Christmas Eve, December 24th
      • -
      • Christmas, December 25th
      • -
      • St. Stephen, December 26th
      • -
      - - \ingroup calendars - */ - public class CzechRepublic : Calendar { - public CzechRepublic() : base(Impl.Singleton) { } - - class Impl : Calendar.WesternImpl { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Prague stock exchange"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Easter Monday - || (dd == em) - // Labour Day - || (d == 1 && m == Month.May) - // Liberation Day - || (d == 8 && m == Month.May) - // SS. Cyril and Methodius - || (d == 5 && m == Month.July) - // Jan Hus Day - || (d == 6 && m == Month.July) - // Czech Statehood Day - || (d == 28 && m == Month.September) - // Independence Day - || (d == 28 && m == Month.October) - // Struggle for Freedom and Democracy Day - || (d == 17 && m == Month.November) - // Christmas Eve - || (d == 24 && m == Month.December) - // Christmas - || (d == 25 && m == Month.December) - // St. Stephen - || (d == 26 && m == Month.December) - // unidentified closing days for stock exchange - || (d == 2 && m == Month.January && y == 2004) - || (d == 31 && m == Month.December && y == 2004)) - return false; - return true; - } - } - } -} diff --git a/src/QLNet/Time/Calendars/denmark.cs b/src/QLNet/Time/Calendars/denmark.cs deleted file mode 100644 index e6135a4b5..000000000 --- a/src/QLNet/Time/Calendars/denmark.cs +++ /dev/null @@ -1,85 +0,0 @@ -/* - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Andrea Maggiulli - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - //! Danish calendar - /*! Holidays: -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • Maunday Thursday
      • -
      • Good Friday
      • -
      • Easter Monday
      • -
      • General Prayer Day, 25 days after Easter Monday
      • -
      • Ascension
      • -
      • Whit (Pentecost) Monday
      • -
      • New Year's Day, January 1st
      • -
      • Constitution Day, June 5th
      • -
      • Christmas, December 25th
      • -
      • Boxing Day, December 26th
      • -
      - - \ingroup calendars - */ - public class Denmark : Calendar { - public Denmark() : base(Impl.Singleton) { } - - class Impl : Calendar.WesternImpl { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Denmark"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - if (isWeekend(w) - // Maunday Thursday - || (dd == em - 4) - // Good Friday - || (dd == em - 3) - // Easter Monday - || (dd == em) - // General Prayer Day - || (dd == em + 25) - // Ascension - || (dd == em + 38) - // Whit Monday - || (dd == em + 49) - // New Year's Day - || (d == 1 && m == Month.January) - // Constitution Day, June 5th - || (d == 5 && m == Month.June) - // Christmas - || (d == 25 && m == Month.December) - // Boxing Day - || (d == 26 && m == Month.December)) - return false; - return true; - } - } - } -} - diff --git a/src/QLNet/Time/Calendars/finland.cs b/src/QLNet/Time/Calendars/finland.cs deleted file mode 100644 index 6f5001529..000000000 --- a/src/QLNet/Time/Calendars/finland.cs +++ /dev/null @@ -1,89 +0,0 @@ -/* - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Andrea Maggiulli - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - //! Finnish calendar - /*! Holidays: -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Epiphany, January 6th
      • -
      • Good Friday
      • -
      • Easter Monday
      • -
      • Ascension Thursday
      • -
      • Labour Day, May 1st
      • -
      • Midsummer Eve (Friday between June 18-24)
      • -
      • Independence Day, December 6th
      • -
      • Christmas Eve, December 24th
      • -
      • Christmas, December 25th
      • -
      • Boxing Day, December 26th
      • -
      - - \ingroup calendars - */ - public class Finland : Calendar { - public Finland() : base(Impl.Singleton) { } - - class Impl : Calendar.WesternImpl { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Finland"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Epiphany - || (d == 6 && m == Month.January) - // Good Friday - || (dd == em - 3) - // Easter Monday - || (dd == em) - // Ascension Thursday - || (dd == em + 38) - // Labour Day - || (d == 1 && m == Month.May) - // Midsummer Eve (Friday between June 18-24) - || (w == DayOfWeek.Friday && (d >= 18 && d <= 24) && m == Month.June) - // Independence Day - || (d == 6 && m == Month.December) - // Christmas Eve - || (d == 24 && m == Month.December) - // Christmas - || (d == 25 && m == Month.December) - // Boxing Day - || (d == 26 && m == Month.December)) - return false; - return true; - } - } - } -} - diff --git a/src/QLNet/Time/Calendars/germany.cs b/src/QLNet/Time/Calendars/germany.cs deleted file mode 100644 index 68f5e91d1..000000000 --- a/src/QLNet/Time/Calendars/germany.cs +++ /dev/null @@ -1,320 +0,0 @@ -/* - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! German calendars - /*! Public holidays: -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Good Friday
      • -
      • Easter Monday
      • -
      • Ascension Thursday
      • -
      • Whit Monday
      • -
      • Corpus Christi
      • -
      • Labour Day, May 1st
      • -
      • National Day, October 3rd
      • -
      • Christmas Eve, December 24th
      • -
      • Christmas, December 25th
      • -
      • Boxing Day, December 26th
      • -
      • New Year's Eve, December 31st
      • -
      - - Holidays for the Frankfurt Stock exchange - (data from http://deutsche-boerse.com/): -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Good Friday
      • -
      • Easter Monday
      • -
      • Labour Day, May 1st
      • -
      • Christmas' Eve, December 24th
      • -
      • Christmas, December 25th
      • -
      • Christmas Holiday, December 26th
      • -
      • New Year's Eve, December 31st
      • -
      - - Holidays for the Xetra exchange - (data from http://deutsche-boerse.com/): -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Good Friday
      • -
      • Easter Monday
      • -
      • Labour Day, May 1st
      • -
      • Christmas' Eve, December 24th
      • -
      • Christmas, December 25th
      • -
      • Christmas Holiday, December 26th
      • -
      • New Year's Eve, December 31st
      • -
      - - Holidays for the Eurex exchange - (data from http://www.eurexchange.com/index.html): -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Good Friday
      • -
      • Easter Monday
      • -
      • Labour Day, May 1st
      • -
      • Christmas' Eve, December 24th
      • -
      • Christmas, December 25th
      • -
      • Christmas Holiday, December 26th
      • -
      • New Year's Eve, December 31st
      • -
      - - Holidays for the Euwax exchange - (data from http://www.boerse-stuttgart.de): -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Good Friday
      • -
      • Easter Monday
      • -
      • Labour Day, May 1st
      • -
      • Whit Monday
      • -
      • Christmas' Eve, December 24th
      • -
      • Christmas, December 25th
      • -
      • Christmas Holiday, December 26th
      • -
      • New Year's Eve, December 31st
      • -
      - - \ingroup calendars - - \test the correctness of the returned results is tested - against a list of known holidays. - */ - public class Germany : Calendar { - //! German calendars - public enum Market { - Settlement, //!< generic settlement calendar - FrankfurtStockExchange, //!< Frankfurt stock-exchange - Xetra, //!< Xetra - Eurex, //!< Eurex - Euwax //!< Euwax - }; - - public Germany() : this(Market.FrankfurtStockExchange) { } - public Germany(Market m) - : base() { - // all calendar instances on the same market share the same - // implementation instance - switch (m) { - case Market.Settlement: - calendar_ = Settlement.Singleton; - break; - case Market.FrankfurtStockExchange: - calendar_ = FrankfurtStockExchange.Singleton; - break; - case Market.Xetra: - calendar_ = Xetra.Singleton; - break; - case Market.Eurex: - calendar_ = Eurex.Singleton; - break; - case Market.Euwax: - calendar_ = Euwax.Singleton; - break; - default: - throw new ArgumentException("Unknown market: " + m); - } - } - - class Settlement : Calendar.WesternImpl { - public static readonly Settlement Singleton = new Settlement(); - private Settlement() { } - - public override string name() { return "German settlement"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Good Friday - || (dd == em-3) - // Easter Monday - || (dd == em) - // Ascension Thursday - || (dd == em+38) - // Whit Monday - || (dd == em+49) - // Corpus Christi - || (dd == em+59) - // Labour Day - || (d == 1 && m == Month.May) - // National Day - || (d == 3 && m == Month.October) - // Christmas Eve - || (d == 24 && m == Month.December) - // Christmas - || (d == 25 && m == Month.December) - // Boxing Day - || (d == 26 && m == Month.December) - // New Year's Eve - || (d == 31 && m == Month.December)) - return false; - return true; - } - } - class FrankfurtStockExchange : Calendar.WesternImpl { - public static readonly FrankfurtStockExchange Singleton = new FrankfurtStockExchange(); - private FrankfurtStockExchange() { } - - public override string name() { return "Frankfurt stock exchange"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Good Friday - || (dd == em-3) - // Easter Monday - || (dd == em) - // Labour Day - || (d == 1 && m == Month.May) - // Christmas' Eve - || (d == 24 && m == Month.December) - // Christmas - || (d == 25 && m == Month.December) - // Christmas Day - || (d == 26 && m == Month.December) - // New Year's Eve - || (d == 31 && m == Month.December)) - return false; - return true; - } - } - class Xetra : Calendar.WesternImpl { - public static readonly Xetra Singleton = new Xetra(); - private Xetra() { } - - public override string name() { return "Xetra"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Good Friday - || (dd == em-3) - // Easter Monday - || (dd == em) - // Labour Day - || (d == 1 && m == Month.May) - // Christmas' Eve - || (d == 24 && m == Month.December) - // Christmas - || (d == 25 && m == Month.December) - // Christmas Day - || (d == 26 && m == Month.December) - // New Year's Eve - || (d == 31 && m == Month.December)) - return false; - return true; - } - } - class Eurex : Calendar.WesternImpl { - public static readonly Eurex Singleton = new Eurex(); - private Eurex() { } - - public override string name() { return "Eurex"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Good Friday - || (dd == em-3) - // Easter Monday - || (dd == em) - // Labour Day - || (d == 1 && m == Month.May) - // Christmas' Eve - || (d == 24 && m == Month.December) - // Christmas - || (d == 25 && m == Month.December) - // Christmas Day - || (d == 26 && m == Month.December) - // New Year's Eve - || (d == 31 && m == Month.December)) - return false; - return true; - } - }; - class Euwax : Calendar.WesternImpl { - public static readonly Euwax Singleton = new Euwax(); - private Euwax() { } - - public override string name() { return "Euwax"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if ((w == DayOfWeek.Saturday || w == DayOfWeek.Sunday) - // New Year's Day - || (d == 1 && m == Month.January) - // Good Friday - || (dd == em - 3) - // Easter Monday - || (dd == em) - // Labour Day - || (d == 1 && m == Month.May) - // Whit Monday - || (dd == em + 49) - // Christmas' Eve - || (d == 24 && m == Month.December) - // Christmas - || (d == 25 && m == Month.December) - // Christmas Day - || (d == 26 && m == Month.December) - // New Year's Eve - || (d == 31 && m == Month.December)) - return false; - return true; - } - }; - } -} \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/hongkong.cs b/src/QLNet/Time/Calendars/hongkong.cs deleted file mode 100644 index 3d15eb296..000000000 --- a/src/QLNet/Time/Calendars/hongkong.cs +++ /dev/null @@ -1,287 +0,0 @@ -/* - Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - //! Hong Kong calendars - /*! Holidays: -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st (possibly moved to Monday)
      • -
      • Good Friday
      • -
      • Easter Monday
      • -
      • Labor Day, May 1st (possibly moved to Monday)
      • -
      • SAR Establishment Day, July 1st (possibly moved to Monday)
      • -
      • National Day, October 1st (possibly moved to Monday)
      • -
      • Christmas, December 25th
      • -
      • Boxing Day, December 26th
      • -
      - - Other holidays for which no rule is given - (data available for 2004-2013 only:) -
        -
      • Lunar New Year
      • -
      • Chinese New Year
      • -
      • Ching Ming Festival
      • -
      • Buddha's birthday
      • -
      • Tuen NG Festival
      • -
      • Mid-autumn Festival
      • -
      • Chung Yeung Festival
      • -
      - - Data from - - \ingroup calendars - */ - public class HongKong : Calendar { - public HongKong() : base(Impl.Singleton) { } - - class Impl : Calendar.WesternImpl { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Hong Kong stock exchange"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day - || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) - && m == Month.January) - // Good Friday - || (dd == em-3) - // Easter Monday - || (dd == em) - // Labor Day - || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) && m == Month.May) - // SAR Establishment Day - || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) && m == Month.July) - // National Day - || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) - && m == Month.October) - // Christmas Day - || (d == 25 && m == Month.December) - // Boxing Day - || (d == 26 && m == Month.December)) - return false; - - if (y == 2004) { - if (// Lunar New Year - ((d==22 || d==23 || d==24) && m == Month.January) - // Ching Ming Festival - || (d == 5 && m == Month.April) - // Buddha's birthday - || (d == 26 && m == Month.May) - // Tuen NG festival - || (d == 22 && m == Month.June) - // Mid-autumn festival - || (d == 29 && m == Month.September) - // Chung Yeung - || (d == 29 && m == Month.September)) - return false; - } - - if (y == 2005) { - if (// Lunar New Year - ((d==9 || d==10 || d==11) && m == Month.February) - // Ching Ming Festival - || (d == 5 && m == Month.April) - // Buddha's birthday - || (d == 16 && m == Month.May) - // Tuen NG festival - || (d == 11 && m == Month.June) - // Mid-autumn festival - || (d == 19 && m == Month.September) - // Chung Yeung festival - || (d == 11 && m == Month.October)) - return false; - } - - if (y == 2006) { - if (// Lunar New Year - ((d >= 28 && d <= 31) && m == Month.January) - // Ching Ming Festival - || (d == 5 && m == Month.April) - // Buddha's birthday - || (d == 5 && m == Month.May) - // Tuen NG festival - || (d == 31 && m == Month.May) - // Mid-autumn festival - || (d == 7 && m == Month.October) - // Chung Yeung festival - || (d == 30 && m == Month.October)) - return false; - } - - if (y == 2007) { - if (// Lunar New Year - ((d >= 17 && d <= 20) && m == Month.February) - // Ching Ming Festival - || (d == 5 && m == Month.April) - // Buddha's birthday - || (d == 24 && m == Month.May) - // Tuen NG festival - || (d == 19 && m == Month.June) - // Mid-autumn festival - || (d == 26 && m == Month.September) - // Chung Yeung festival - || (d == 19 && m == Month.October)) - return false; - } - - if (y == 2008) { - if (// Lunar New Year - ((d >= 7 && d <= 9) && m == Month.February) - // Ching Ming Festival - || (d == 4 && m == Month.April) - // Buddha's birthday - || (d == 12 && m == Month.May) - // Tuen NG festival - || (d == 9 && m == Month.June) - // Mid-autumn festival - || (d == 15 && m == Month.September) - // Chung Yeung festival - || (d == 7 && m == Month.October)) - return false; - } - - if (y == 2009) { - if (// Lunar New Year - ((d >= 26 && d <= 28) && m == Month.January) - // Ching Ming Festival - || (d == 4 && m == Month.April) - // Buddha's birthday - || (d == 2 && m == Month.May) - // Tuen NG festival - || (d == 28 && m == Month.May) - // Mid-autumn festival - || (d == 3 && m == Month.October) - // Chung Yeung festival - || (d == 26 && m == Month.October)) - return false; - } - - if (y == 2010) - { - if (// Lunar New Year - ((d == 15 || d == 16) && m == Month.February) - // Ching Ming Festival - || (d == 6 && m == Month.April) - // Buddha's birthday - || (d == 21 && m == Month.May) - // Tuen NG festival - || (d == 16 && m == Month.June) - // Mid-autumn festival - || (d == 23 && m == Month.September)) - return false; - } - - - if (y == 2011) { - if (// Lunar New Year - ((d == 3 || d == 4) && m == Month.February) - // Ching Ming Festival - || (d == 5 && m == Month.April) - // Buddha's birthday - || (d == 10 && m == Month.May) - // Tuen NG festival - || (d == 6 && m == Month.June) - // Mid-autumn festival - || (d == 13 && m == Month.September) - // Chung Yeung festival - || (d == 5 && m == Month.October) - // Second day after Christmas - || (d == 27 && m == Month.December)) - return false; - } - - if (y == 2012) { - if (// Lunar New Year - (d >= 23 && d <= 25 && m == Month.January) - // Ching Ming Festival - || (d == 4 && m == Month.April) - // Buddha's birthday - || (d == 10 && m == Month.May) - // Mid-autumn festival - || (d == 1 && m == Month.October) - // Chung Yeung festival - || (d == 23 && m == Month.October)) - return false; - } - - if (y == 2013) { - if (// Lunar New Year - (d >= 11 && d <= 13 && m == Month.February) - // Ching Ming Festival - || (d == 4 && m == Month.April) - // Buddha's birthday - || (d == 17 && m == Month.May) - // Tuen Ng festival - || (d == 12 && m == Month.June) - // Mid-autumn festival - || (d == 20 && m == Month.September) - // Chung Yeung festival - || (d == 14 && m == Month.October)) - return false; - } - - if ( y == 2014 ) - { - if (// Lunar New Year - ( ( d == 31 && m == Month.January ) || ( d <= 3 && m == Month.February ) ) - // Buddha's birthday - || ( d == 6 && m == Month.May ) - // Tuen Ng festival - || ( d == 2 && m == Month.June ) - // Mid-autumn festival - || ( d == 9 && m == Month.September ) - // Chung Yeung festival - || ( d == 2 && m == Month.October ) ) - return false; - } - - if ( y == 2015 ) - { - if (// Lunar New Year - ( ( d == 19 && m == Month.February ) || ( d == 20 && m == Month.February ) ) - // The day following Easter Monday - || ( d == 7 && m == Month.April ) - // Buddha's birthday - || ( d == 25 && m == Month.May ) - // Tuen Ng festival - || ( d == 20 && m == Month.June ) - // Mid-autumn festival - || ( d == 28 && m == Month.September ) - // Chung Yeung festival - || ( d == 21 && m == Month.October ) ) - return false; - } - return true; - } - } - } -} \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/hungary.cs b/src/QLNet/Time/Calendars/hungary.cs deleted file mode 100644 index b8546db1c..000000000 --- a/src/QLNet/Time/Calendars/hungary.cs +++ /dev/null @@ -1,84 +0,0 @@ -/* - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Andrea Maggiulli - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - //! Hungarian calendar - /*! Holidays: -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • Easter Monday
      • -
      • Whit(Pentecost) Monday
      • -
      • New Year's Day, January 1st
      • -
      • National Day, March 15th
      • -
      • Labour Day, May 1st
      • -
      • Constitution Day, August 20th
      • -
      • Republic Day, October 23rd
      • -
      • All Saints Day, November 1st
      • -
      • Christmas, December 25th
      • -
      • 2nd Day of Christmas, December 26th
      • -
      - - \ingroup calendars - */ - public class Hungary : Calendar { - public Hungary() : base(Impl.Singleton) { } - - class Impl : Calendar.WesternImpl { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Hungary"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - if (isWeekend(w) - // Easter Monday - || (dd == em) - // Whit Monday - || (dd == em+49) - // New Year's Day - || (d == 1 && m == Month.January) - // National Day - || (d == 15 && m == Month.March) - // Labour Day - || (d == 1 && m == Month.May) - // Constitution Day - || (d == 20 && m == Month.August) - // Republic Day - || (d == 23 && m == Month.October) - // All Saints Day - || (d == 1 && m == Month.November) - // Christmas - || (d == 25 && m == Month.December) - // 2nd Day of Christmas - || (d == 26 && m == Month.December)) - return false; - return true; - } - } - } -} \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/iceland.cs b/src/QLNet/Time/Calendars/iceland.cs deleted file mode 100644 index 3fba75b4f..000000000 --- a/src/QLNet/Time/Calendars/iceland.cs +++ /dev/null @@ -1,91 +0,0 @@ -/* - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! Icelandic calendars - /*! Holidays for the Iceland stock exchange - (data from ): -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st (possibly moved to Monday)
      • -
      • Holy Thursday
      • -
      • Good Friday
      • -
      • Easter Monday
      • -
      • First day of Summer (third or fourth Thursday in April)
      • -
      • Labour Day, May 1st
      • -
      • Ascension Thursday
      • -
      • Pentecost Monday
      • -
      • Independence Day, June 17th
      • -
      • Commerce Day, first Monday in August
      • -
      • Christmas, December 25th
      • -
      • Boxing Day, December 26th
      • -
      - - \ingroup calendars - */ - public class Iceland : Calendar { - public Iceland() : base(Impl.Singleton) { } - - class Impl : Calendar.WesternImpl { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Iceland stock exchange"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day (possibly moved to Monday) - || ((d == 1 || ((d == 2 || d == 3) && w == DayOfWeek.Monday)) - && m == Month.January) - // Holy Thursday - || (dd == em-4) - // Good Friday - || (dd == em-3) - // Easter Monday - || (dd == em) - // First day of Summer - || (d >= 19 && d <= 25 && w == DayOfWeek.Thursday && m == Month.April) - // Ascension Thursday - || (dd == em+38) - // Pentecost Monday - || (dd == em+49) - // Labour Day - || (d == 1 && m == Month.May) - // Independence Day - || (d == 17 && m == Month.June) - // Commerce Day - || (d <= 7 && w == DayOfWeek.Monday && m == Month.August) - // Christmas - || (d == 25 && m == Month.December) - // Boxing Day - || (d == 26 && m == Month.December)) - return false; - return true; - } - } - } -} diff --git a/src/QLNet/Time/Calendars/india.cs b/src/QLNet/Time/Calendars/india.cs deleted file mode 100644 index 57de09c04..000000000 --- a/src/QLNet/Time/Calendars/india.cs +++ /dev/null @@ -1,338 +0,0 @@ -/* - Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - //! Indian calendars - /*! Holidays for the National Stock Exchange - (data from ): -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • Republic Day, January 26th
      • -
      • Good Friday
      • -
      • Ambedkar Jayanti, April 14th
      • -
      • May Day, May 1st
      • -
      • Independence Day, August 15th
      • -
      • Gandhi Jayanti, October 2nd
      • -
      • Christmas, December 25th
      • -
      - - Other holidays for which no rule is given - (data available for 2005-2013 only:) -
        -
      • Bakri Id
      • -
      • Moharram
      • -
      • Mahashivratri
      • -
      • Holi
      • -
      • Ram Navami
      • -
      • Mahavir Jayanti
      • -
      • Id-E-Milad
      • -
      • Maharashtra Day
      • -
      • Buddha Pournima
      • -
      • Ganesh Chaturthi
      • -
      • Dasara
      • -
      • Laxmi Puja
      • -
      • Bhaubeej
      • -
      • Ramzan Id
      • -
      • Guru Nanak Jayanti
      • -
      - - \ingroup calendars - */ - public class India : Calendar { - public India() : base(Impl.Singleton) { } - - class Impl : Calendar.WesternImpl { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "National Stock Exchange of India"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // Republic Day - || (d == 26 && m == Month.January) - // Good Friday - || (dd == em - 3) - // Ambedkar Jayanti - || (d == 14 && m == Month.April) - // May Day - || (d == 1 && m == Month.May) - // Independence Day - || (d == 15 && m == Month.August) - // Gandhi Jayanti - || (d == 2 && m == Month.October) - // Christmas - || (d == 25 && m == Month.December) - ) - return false; - - if (y == 2005) { - // Moharram, Holi, Maharashtra Day, and Ramzan Id fall - // on Saturday or Sunday in 2005 - if (// Bakri Id - (d == 21 && m == Month.January) - // Ganesh Chaturthi - || (d == 7 && m == Month.September) - // Dasara - || (d == 12 && m == Month.October) - // Laxmi Puja - || (d == 1 && m == Month.November) - // Bhaubeej - || (d == 3 && m == Month.November) - // Guru Nanak Jayanti - || (d == 15 && m == Month.November) - ) - return false; - } - - if (y == 2006) { - if (// Bakri Id - (d == 11 && m == Month.January) - // Moharram - || (d == 9 && m == Month.February) - // Holi - || (d == 15 && m == Month.March) - // Ram Navami - || (d == 6 && m == Month.April) - // Mahavir Jayanti - || (d == 11 && m == Month.April) - // Maharashtra Day - || (d == 1 && m == Month.May) - // Bhaubeej - || (d == 24 && m == Month.October) - // Ramzan Id - || (d == 25 && m == Month.October) - ) - return false; - } - - if (y == 2007) { - if (// Bakri Id - (d == 1 && m == Month.January) - // Moharram - || (d == 30 && m == Month.January) - // Mahashivratri - || (d == 16 && m == Month.February) - // Ram Navami - || (d == 27 && m == Month.March) - // Maharashtra Day - || (d == 1 && m == Month.May) - // Buddha Pournima - || (d == 2 && m == Month.May) - // Laxmi Puja - || (d == 9 && m == Month.November) - // Bakri Id (again) - || (d == 21 && m == Month.December) - ) - return false; - } - - if (y == 2008) { - if (// Mahashivratri - (d == 6 && m == Month.March) - // Id-E-Milad - || (d == 20 && m == Month.March) - // Mahavir Jayanti - || (d == 18 && m == Month.April) - // Maharashtra Day - || (d == 1 && m == Month.May) - // Buddha Pournima - || (d == 19 && m == Month.May) - // Ganesh Chaturthi - || (d == 3 && m == Month.September) - // Ramzan Id - || (d == 2 && m == Month.October) - // Dasara - || (d == 9 && m == Month.October) - // Laxmi Puja - || (d == 28 && m == Month.October) - // Bhau bhij - || (d == 30 && m == Month.October) - // Gurunanak Jayanti - || (d == 13 && m == Month.November) - // Bakri Id - || (d == 9 && m == Month.December) - ) - return false; - } - - if (y == 2009) { - if (// Moharram - (d == 8 && m == Month.January) - // Mahashivratri - || (d == 23 && m == Month.February) - // Id-E-Milad - || (d == 10 && m == Month.March) - // Holi - || (d == 11 && m == Month.March) - // Ram Navmi - || (d == 3 && m == Month.April) - // Mahavir Jayanti - || (d == 7 && m == Month.April) - // Maharashtra Day - || (d == 1 && m == Month.May) - // Ramzan Id - || (d == 21 && m == Month.September) - // Dasara - || (d == 28 && m == Month.September) - // Bhau Bhij - || (d == 19 && m == Month.October) - // Gurunanak Jayanti - || (d == 2 && m == Month.November) - // Moharram (again) - || (d == 28 && m == Month.December) - ) - return false; - } - - if (y == 2010) - { - if (// New Year's Day - (d == 1 && m == Month.January) - // Mahashivratri - || (d == 12 && m == Month.February) - // Holi - || (d == 1 && m == Month.March) - // Ram Navmi - || (d == 24 && m == Month.March) - // Ramzan Id - || (d == 10 && m == Month.September) - // Laxmi Puja - || (d == 5 && m == Month.November) - // Bakri Id - || (d == 17 && m == Month.November) - // Moharram - || (d == 17 && m == Month.December) - ) - return false; - } - - if (y == 2011) { - if (// Mahashivratri - (d == 2 && m == Month.March) - // Ram Navmi - || (d == 12 && m == Month.April) - // Ramzan Id - || (d == 31 && m == Month.August) - // Ganesh Chaturthi - || (d == 1 && m == Month.September) - // Dasara - || (d == 6 && m == Month.October) - // Laxmi Puja - || (d == 26 && m == Month.October) - // Diwali - Balipratipada - || (d == 27 && m == Month.October) - // Bakri Id - || (d == 7 && m == Month.November) - // Gurunanak Jayanti - || (d == 10 && m == Month.November) - // Moharram - || (d == 6 && m == Month.December) - ) - return false; - } - - if (y == 2012) { - if (// Mahashivratri - (d == 20 && m == Month.February) - // Holi - || (d == 8 && m == Month.March) - // Mahavir Jayanti - || (d == 5 && m == Month.April) - // Ramzan Id - || (d == 20 && m == Month.August) - // Ganesh Chaturthi - || (d == 19 && m == Month.September) - // Dasara - || (d == 24 && m == Month.October) - // Diwali - Balipratipada - || (d == 14 && m == Month.November) - // Gurunanak Jayanti - || (d == 28 && m == Month.November) - ) - return false; - } - - if ( y == 2013 ) - { - if (// Holi - ( d == 27 && m == Month.March ) - // Ram Navmi - || ( d == 19 && m == Month.April ) - // Mahavir Jayanti - || ( d == 24 && m == Month.April ) - // Ramzan Id - || ( d == 9 && m == Month.August ) - // Ganesh Chaturthi - || ( d == 9 && m == Month.September ) - // Bakri Id - || ( d == 16 && m == Month.October ) - // Diwali - Balipratipada - || ( d == 4 && m == Month.November ) - // Moharram - || ( d == 14 && m == Month.November ) - ) - return false; - } - - if ( y == 2014 ) - { - if (// Mahashivratri - ( d == 27 && m == Month.February ) - // Holi - || ( d == 17 && m == Month.March ) - // Ram Navmi - || ( d == 8 && m == Month.April ) - // Ramzan Id - || ( d == 29 && m == Month.July ) - // Ganesh Chaturthi - || ( d == 29 && m == Month.August ) - // Dasera - || ( d == 3 && m == Month.October ) - // Bakri Id - || ( d == 6 && m == Month.October ) - // Diwali - Balipratipada - || ( d == 24 && m == Month.October ) - // Moharram - || ( d == 4 && m == Month.November ) - // Gurunank Jayanti - || ( d == 6 && m == Month.November ) - ) - return false; - } - return true; - } - } - } -} - - - - - \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/indonesia.cs b/src/QLNet/Time/Calendars/indonesia.cs deleted file mode 100644 index 4c61b5463..000000000 --- a/src/QLNet/Time/Calendars/indonesia.cs +++ /dev/null @@ -1,314 +0,0 @@ -/* - Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - //! %Indonesian calendars - /*! Holidays for the Indonesia stock exchange - (data from ): -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Good Friday
      • -
      • Ascension of Jesus Christ
      • -
      • Independence Day, August 17th
      • -
      • Christmas, December 25th
      • -
      - - Other holidays for which no rule is given - (data available for 2005-2013 only:) -
        -
      • Idul Adha
      • -
      • Ied Adha
      • -
      • Imlek
      • -
      • Moslem's New Year Day
      • -
      • Chinese New Year
      • -
      • Nyepi (Saka's New Year)
      • -
      • Birthday of Prophet Muhammad SAW
      • -
      • Waisak
      • -
      • Ascension of Prophet Muhammad SAW
      • -
      • Idul Fitri
      • -
      • Ied Fitri
      • -
      • Other national leaves
      • -
      - \ingroup calendars - */ - public class Indonesia : Calendar { - public enum Market { - BEJ, //!< Jakarta stock exchange (merged into IDX) - JSX, //!< Jakarta stock exchange (merged into IDX) - IDX //!< Indonesia stock exchange - }; - - public Indonesia() : this(Market.IDX) { } - public Indonesia(Market m) - : base() { - // all calendar instances on the same market share the same - // implementation instance - switch (m) { - case Market.BEJ: - case Market.JSX: - case Market.IDX: - calendar_ = BEJ.Singleton; - break; - default: - throw new ArgumentException("Unknown market: " + m); - } - } - - class BEJ : Calendar.WesternImpl { - public static readonly BEJ Singleton = new BEJ(); - private BEJ() { } - - public override string name() { return "Jakarta stock exchange"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Good Friday - || (dd == em - 3) - // Ascension Thursday - || (dd == em + 38) - // Independence Day - || (d == 17 && m == Month.August) - // Christmas - || (d == 25 && m == Month.December) - ) - return false; - - if (y == 2005) { - if (// Idul Adha - (d == 21 && m == Month.January) - // Imlek - || (d == 9 && m == Month.February) - // Moslem's New Year Day - || (d == 10 && m == Month.February) - // Nyepi - || (d == 11 && m == Month.March) - // Birthday of Prophet Muhammad SAW - || (d == 22 && m == Month.April) - // Waisak - || (d == 24 && m == Month.May) - // Ascension of Prophet Muhammad SAW - || (d == 2 && m == Month.September) - // Idul Fitri - || ((d == 3 || d == 4) && m == Month.November) - // National leaves - || ((d == 2 || d == 7 || d == 8) && m == Month.November) - || (d == 26 && m == Month.December) - ) - return false; - } - - if (y == 2006) { - if (// Idul Adha - (d == 10 && m == Month.January) - // Moslem's New Year Day - || (d == 31 && m == Month.January) - // Nyepi - || (d == 30 && m == Month.March) - // Birthday of Prophet Muhammad SAW - || (d == 10 && m == Month.April) - // Ascension of Prophet Muhammad SAW - || (d == 21 && m == Month.August) - // Idul Fitri - || ((d == 24 || d == 25) && m == Month.October) - // National leaves - || ((d == 23 || d == 26 || d == 27) && m == Month.October) - ) - return false; - } - - if (y == 2007) { - if (// Nyepi - (d == 19 && m == Month.March) - // Waisak - || (d == 1 && m == Month.June) - // Ied Adha - || (d == 20 && m == Month.December) - // National leaves - || (d == 18 && m == Month.May) - || ((d == 12 || d == 15 || d == 16) && m == Month.October) - || ((d == 21 || d == 24) && m == Month.October) - ) - return false; - } - - if (y == 2008) { - if (// Islamic New Year - ((d == 10 || d == 11) && m == Month.January) - // Chinese New Year - || ((d == 7 || d == 8) && m == Month.February) - // Saka's New Year - || (d == 7 && m == Month.March) - // Birthday of the prophet Muhammad SAW - || (d == 20 && m == Month.March) - // Vesak Day - || (d == 20 && m == Month.May) - // Isra' Mi'raj of the prophet Muhammad SAW - || (d == 30 && m == Month.July) - // National leave - || (d == 18 && m == Month.August) - // Ied Fitr - || (d == 30 && m == Month.September) - || ((d == 1 || d == 2 || d == 3) && m == Month.October) - // Ied Adha - || (d == 8 && m == Month.December) - // Islamic New Year - || (d == 29 && m == Month.December) - // New Year's Eve - || (d == 31 && m == Month.December) - ) - return false; - } - - if (y == 2009) { - if (// Public holiday - (d == 2 && m == Month.January) - // Chinese New Year - || (d == 26 && m == Month.January) - // Birthday of the prophet Muhammad SAW - || (d == 9 && m == Month.March) - // Saka's New Year - || (d == 26 && m == Month.March) - // National leave - || (d == 9 && m == Month.April) - // Isra' Mi'raj of the prophet Muhammad SAW - || (d == 20 && m == Month.July) - // Ied Fitr - || (d >= 18 && d <= 23 && m == Month.September) - // Ied Adha - || (d == 27 && m == Month.November) - // Islamic New Year - || (d == 18 && m == Month.December) - // Public Holiday - || (d == 24 && m == Month.December) - // Trading holiday - || (d == 31 && m == Month.December) - ) - return false; - } - - if (y == 2010) - { - if (// Birthday of the prophet Muhammad SAW - (d == 26 && m == Month.February) - // Saka's New Year - || (d == 16 && m == Month.March) - // Birth of Buddha - || (d == 28 && m == Month.May) - // Ied Fitr - || (d >= 8 && d <= 14 && m == Month.September) - // Ied Adha - || (d == 17 && m == Month.November) - // Islamic New Year - || (d == 7 && m == Month.December) - // Public Holiday - || (d == 24 && m == Month.December) - // Trading holiday - || (d == 31 && m == Month.December) - ) - return false; - } - - if (y == 2011) { - if (// Chinese New Year - (d == 3 && m == Month.February) - // Birthday of the prophet Muhammad SAW - || (d == 15 && m == Month.February) - // Birth of Buddha - || (d == 17 && m == Month.May) - // Isra' Mi'raj of the prophet Muhammad SAW - || (d == 29 && m == Month.June) - // Ied Fitr - || (d >= 29 && m == Month.August) - || (d <= 2 && m == Month.September) - // Public Holiday - || (d == 26 && m == Month.December) - ) - return false; - } - - if (y == 2012) { - if (// Chinese New Year - (d == 23 && m == Month.January) - // Saka New Year - || (d == 23 && m == Month.March) - // Ied ul-Fitr - || (d >= 20 && d <= 22 && m == Month.August) - // Eid ul-Adha - || (d == 26 && m == Month.October) - // Islamic New Year - || (d >= 15 && d <= 16 && m == Month.November) - // Public Holiday - || (d == 24 && m == Month.December) - // Trading Holiday - || (d == 31 && m == Month.December) - ) - return false; - } - - if (y == 2013) { - if (// Birthday of the prophet Muhammad SAW - (d == 24 && m == Month.January) - // Saka New Year - || (d == 12 && m == Month.March) - // Isra' Mi'raj of the prophet Muhammad SAW - || (d == 6 && m == Month.June) - // Ied ul-Fitr - || (d >= 5 && d <= 9 && m == Month.August) - // Eid ul-Adha - || (d >= 14 && d <= 15 && m == Month.October) - // Islamic New Year - || (d == 5 && m == Month.November) - // Public Holiday - || (d == 26 && m == Month.December) - // Trading Holiday - || (d == 31 && m == Month.December) - ) - return false; - } - if (y == 2014) { - if (// Lunar New Year - ( ( d == 31 && m == Month.January ) || ( d <= 3 && m == Month.February ) ) - // Buddha's birthday - || ( d == 6 && m == Month.May ) - // Tuen Ng festival - || ( d == 2 && m == Month.June ) - // Mid-autumn festival - || ( d == 9 && m == Month.September ) - // Chung Yeung festival - || ( d == 2 && m == Month.October ) ) - return false; - } - return true; - } - } - } -} diff --git a/src/QLNet/Time/Calendars/italy.cs b/src/QLNet/Time/Calendars/italy.cs deleted file mode 100644 index 2d26a07c7..000000000 --- a/src/QLNet/Time/Calendars/italy.cs +++ /dev/null @@ -1,165 +0,0 @@ -/* - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! Italian calendars - /*! Public holidays: -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Epiphany, January 6th
      • -
      • Easter Monday
      • -
      • Liberation Day, April 25th
      • -
      • Labour Day, May 1st
      • -
      • Republic Day, June 2nd (since 2000)
      • -
      • Assumption, August 15th
      • -
      • All Saint's Day, November 1st
      • -
      • Immaculate Conception Day, December 8th
      • -
      • Christmas Day, December 25th
      • -
      • St. Stephen's Day, December 26th
      • -
      - - Holidays for the stock exchange (data from http://www.borsaitalia.it): -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Good Friday
      • -
      • Easter Monday
      • -
      • Labour Day, May 1st
      • -
      • Assumption, August 15th
      • -
      • Christmas' Eve, December 24th
      • -
      • Christmas, December 25th
      • -
      • St. Stephen, December 26th
      • -
      • New Year's Eve, December 31st
      • -
      - - \ingroup calendars - - \test the correctness of the returned results is tested against a - list of known holidays. - */ - public class Italy : Calendar { - //! Italian calendars - public enum Market { - Settlement, //!< generic settlement calendar - Exchange //!< Milan stock-exchange calendar - }; - - public Italy() : this(Market.Settlement) { } - public Italy(Market m) - : base() { - // all calendar instances on the same market share the same - // implementation instance - switch (m) { - case Market.Settlement: - calendar_ = Settlement.Singleton; - break; - case Market.Exchange: - calendar_ = Exchange.Singleton; - break; - default: - throw new ArgumentException("Unknown market: " + m); - } - } - - - class Settlement : Calendar.WesternImpl { - public static readonly Settlement Singleton = new Settlement(); - private Settlement() { } - - public override string name() { return "Italian settlement"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Epiphany - || (d == 6 && m == Month.January) - // Easter Monday - || (dd == em) - // Liberation Day - || (d == 25 && m == Month.April) - // Labour Day - || (d == 1 && m == Month.May) - // Republic Day - || (d == 2 && m == Month.June && y >= 2000) - // Assumption - || (d == 15 && m == Month.August) - // All Saints' Day - || (d == 1 && m == Month.November) - // Immaculate Conception - || (d == 8 && m == Month.December) - // Christmas - || (d == 25 && m == Month.December) - // St. Stephen - || (d == 26 && m == Month.December) - // December 31st, 1999 only - || (d == 31 && m == Month.December && y == 1999)) - return false; - return true; - } - } - - class Exchange : Calendar.WesternImpl { - public static readonly Exchange Singleton = new Exchange(); - private Exchange() { } - - public override string name() { return "Milan stock exchange"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Good Friday - || (dd == em-3) - // Easter Monday - || (dd == em) - // Labour Day - || (d == 1 && m == Month.May) - // Assumption - || (d == 15 && m == Month.August) - // Christmas' Eve - || (d == 24 && m == Month.December) - // Christmas - || (d == 25 && m == Month.December) - // St. Stephen - || (d == 26 && m == Month.December) - // New Year's Eve - || (d == 31 && m == Month.December)) - return false; - return true; - } - }; - }; - -} diff --git a/src/QLNet/Time/Calendars/japan.cs b/src/QLNet/Time/Calendars/japan.cs deleted file mode 100644 index 35f73ee3f..000000000 --- a/src/QLNet/Time/Calendars/japan.cs +++ /dev/null @@ -1,159 +0,0 @@ -/* - Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - //! Japanese calendar - /*! Holidays: -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Bank Holiday, January 2nd
      • -
      • Bank Holiday, January 3rd
      • -
      • Coming of Age Day, 2nd Monday in January
      • -
      • National Foundation Day, February 11th
      • -
      • Vernal Equinox
      • -
      • Greenery Day, April 29th
      • -
      • Constitution Memorial Day, May 3rd
      • -
      • Holiday for a Nation, May 4th
      • -
      • Children's Day, May 5th
      • -
      • Marine Day, 3rd Monday in July
      • -
      • Mountain Day, August 11th (from 2016 onwards)
      • -
      • Respect for the Aged Day, 3rd Monday in September
      • -
      • Autumnal Equinox
      • -
      • Health and Sports Day, 2nd Monday in October
      • -
      • National Culture Day, November 3rd
      • -
      • Labor Thanksgiving Day, November 23rd
      • -
      • Emperor's Birthday, December 23rd
      • -
      • Bank Holiday, December 31st
      • -
      • a few one-shot holidays
      • -
      - Holidays falling on a Sunday are observed on the Monday following - except for the bank holidays associated with the new year. - - \ingroup calendars - */ - public class Japan : Calendar { - public Japan() : base(Impl.Singleton) { } - - class Impl : Calendar { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Japan"; } - public override bool isWeekend(DayOfWeek w) { - return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; - } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - - // equinox calculation - double exact_vernal_equinox_time = 20.69115; - double exact_autumnal_equinox_time = 23.09; - double diff_per_year = 0.242194; - double moving_amount = (y - 2000) * diff_per_year; - int number_of_leap_years = (y-2000)/4+(y-2000)/100-(y-2000)/400; - int ve = (int)( exact_vernal_equinox_time + moving_amount - number_of_leap_years);// vernal equinox day - int ae = (int)( exact_autumnal_equinox_time + moving_amount - number_of_leap_years ); // autumnal equinox day - // checks - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Bank Holiday - || (d == 2 && m == Month.January) - // Bank Holiday - || (d == 3 && m == Month.January) - // Coming of Age Day (2nd Monday in January), - // was January 15th until 2000 - || (w == DayOfWeek.Monday && (d >= 8 && d <= 14) && m == Month.January - && y >= 2000) - || ((d == 15 || (d == 16 && w == DayOfWeek.Monday)) && m == Month.January - && y < 2000) - // National Foundation Day - || ((d == 11 || (d == 12 && w == DayOfWeek.Monday)) && m == Month.February) - // Vernal Equinox - || ((d == ve || (d == ve + 1 && w == DayOfWeek.Monday)) && m == Month.March) - // Greenery Day - || ((d == 29 || (d == 30 && w == DayOfWeek.Monday)) && m == Month.April) - // Constitution Memorial Day - || (d == 3 && m == Month.May) - // Holiday for a Nation - || (d == 4 && m == Month.May) - // Children's Day - || (d == 5 && m == Month.May) - // any of the three above observed later if on Saturday or Sunday - || (d == 6 && m == Month.May && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday || w == DayOfWeek.Wednesday)) - // Marine Day (3rd Monday in July), - // was July 20th until 2003, not a holiday before 1996 - || (w == DayOfWeek.Monday && (d >= 15 && d <= 21) && m == Month.July - && y >= 2003) - || ((d == 20 || (d == 21 && w == DayOfWeek.Monday)) && m == Month.July - && y >= 1996 && y < 2003) - // Mountain Day (from 2016) - || ( ( d == 11 || ( d == 12 && w == DayOfWeek.Monday ) ) && m == Month.August && y >= 2016 ) - // Respect for the Aged Day (3rd Monday in September), - // was September 15th until 2003 - || (w == DayOfWeek.Monday && (d >= 15 && d <= 21) && m == Month.September - && y >= 2003) - || ((d == 15 || (d == 16 && w == DayOfWeek.Monday)) && m == Month.September - && y < 2003) - // If a single day falls between Respect for the Aged Day - // and the Autumnal Equinox, it is holiday - || (w == DayOfWeek.Tuesday && d + 1 == ae && d >= 16 && d <= 22 - && m == Month.September && y >= 2003) - // Autumnal Equinox - || ((d == ae || (d == ae + 1 && w == DayOfWeek.Monday)) && m == Month.September) - // Health and Sports Day (2nd Monday in October), - // was October 10th until 2000 - || (w == DayOfWeek.Monday && (d >= 8 && d <= 14) && m == Month.October - && y >= 2000) - || ((d == 10 || (d == 11 && w == DayOfWeek.Monday)) && m == Month.October - && y < 2000) - // National Culture Day - || ((d == 3 || (d == 4 && w == DayOfWeek.Monday)) && m == Month.November) - // Labor Thanksgiving Day - || ((d == 23 || (d == 24 && w == DayOfWeek.Monday)) && m == Month.November) - // Emperor's Birthday - || ((d == 23 || (d == 24 && w == DayOfWeek.Monday)) && m == Month.December - && y >= 1989) - // Bank Holiday - || (d == 31 && m == Month.December) - // one-shot holidays - // Marriage of Prince Akihito - || (d == 10 && m == Month.April && y == 1959) - // Rites of Imperial Funeral - || (d == 24 && m == Month.February && y == 1989) - // Enthronement Ceremony - || (d == 12 && m == Month.November && y == 1990) - // Marriage of Prince Naruhito - || (d == 9 && m == Month.June && y == 1993)) - return false; - return true; - } - }; - }; -} - diff --git a/src/QLNet/Time/Calendars/mexico.cs b/src/QLNet/Time/Calendars/mexico.cs deleted file mode 100644 index cc2c4430c..000000000 --- a/src/QLNet/Time/Calendars/mexico.cs +++ /dev/null @@ -1,88 +0,0 @@ -/* - Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - //! %Mexican calendars - /*! Holidays for the Mexican stock exchange - (data from ): -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Constitution Day, first Monday in February (February 5th before 2006)
      • -
      • Birthday of Benito Juarez, third Monday in February (March 21st before 2006)
      • -
      • Holy Thursday
      • -
      • Good Friday
      • -
      • Labour Day, May 1st
      • -
      • National Day, September 16th
      • -
      • Revolution Day, third Monday in November (November 20th before 2006)
      • -
      • Our Lady of Guadalupe, December 12th
      • -
      • Christmas, December 25th
      • -
      - - \ingroup calendars - */ - public class Mexico : Calendar { - public Mexico() : base(Impl.Singleton) { } - - class Impl : Calendar.WesternImpl { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Mexican stock exchange"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Constitution Day - || (y <= 2005 && d == 5 && m == Month.February) - || (y >= 2006 && d <= 7 && w == DayOfWeek.Monday && m == Month.February) - // Birthday of Benito Juarez - || (y <= 2005 && d == 21 && m == Month.March) - || (y >= 2006 && (d >= 15 && d <= 21) && w == DayOfWeek.Monday && m == Month.March) - // Holy Thursday - || (dd == em-4) - // Good Friday - || (dd == em-3) - // Labour Day - || (d == 1 && m == Month.May) - // National Day - || (d == 16 && m == Month.September) - // Revolution Day - || (y <= 2005 && d == 20 && m == Month.November) - || (y >= 2006 && (d >= 15 && d <= 21) && w == DayOfWeek.Monday && m == Month.November) - // Our Lady of Guadalupe - || (d == 12 && m == Month.December) - // Christmas - || (d == 25 && m == Month.December)) - return false; - return true; - } - } - } -} \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/newzealand.cs b/src/QLNet/Time/Calendars/newzealand.cs deleted file mode 100644 index 4da8e3a29..000000000 --- a/src/QLNet/Time/Calendars/newzealand.cs +++ /dev/null @@ -1,96 +0,0 @@ -/* - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Andrea Maggiulli - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - //! New Zealand calendar - /*! Holidays: -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st (possibly moved to Monday or - Tuesday)
      • -
      • Day after New Year's Day, January 2st (possibly moved to - Monday or Tuesday)
      • -
      • Anniversary Day, Monday nearest January 22nd
      • -
      • Waitangi Day. February 6th
      • -
      • Good Friday
      • -
      • Easter Monday
      • -
      • ANZAC Day. April 25th
      • -
      • Queen's Birthday, first Monday in June
      • -
      • Labour Day, fourth Monday in October
      • -
      • Christmas, December 25th (possibly moved to Monday or Tuesday)
      • -
      • Boxing Day, December 26th (possibly moved to Monday or - Tuesday)
      • -
      - \note The holiday rules for New Zealand were documented by - David Gilbert for IDB (http://www.jrefinery.com/ibd/) - - \ingroup calendars - */ - public class NewZealand : Calendar { - public NewZealand() : base(Impl.Singleton) { } - - class Impl : Calendar.WesternImpl { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "New Zealand"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - if (isWeekend(w) - // New Year's Day (possibly moved to Monday or Tuesday) - || ((d == 1 || (d == 3 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) && - m == Month.January) - // Day after New Year's Day (possibly moved to Mon or Tuesday) - || ((d == 2 || (d == 4 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) && - m == Month.January) - // Anniversary Day, Monday nearest January 22nd - || ((d >= 19 && d <= 25) && w == DayOfWeek.Monday && m == Month.January) - // Waitangi Day. February 6th - || (d == 6 && m == Month.February) - // Good Friday - || (dd == em-3) - // Easter Monday - || (dd == em) - // ANZAC Day. April 25th - || (d == 25 && m == Month.April) - // Queen's Birthday, first Monday in June - || (d <= 7 && w == DayOfWeek.Monday && m == Month.June) - // Labour Day, fourth Monday in October - || ((d >= 22 && d <= 28) && w == DayOfWeek.Monday && m == Month.October) - // Christmas, December 25th (possibly Monday or Tuesday) - || ((d == 25 || (d == 27 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) - && m == Month.December) - // Boxing Day, December 26th (possibly Monday or Tuesday) - || ((d == 26 || (d == 28 && (w == DayOfWeek.Monday || w == DayOfWeek.Tuesday))) - && m == Month.December)) - return false; - return true; - } - } - } -} \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/norway.cs b/src/QLNet/Time/Calendars/norway.cs deleted file mode 100644 index d7b304f4d..000000000 --- a/src/QLNet/Time/Calendars/norway.cs +++ /dev/null @@ -1,86 +0,0 @@ -/* - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Andrea Maggiulli - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - //! Norwegian calendar - /*! Holidays: -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • Holy Thursday
      • -
      • Good Friday
      • -
      • Easter Monday
      • -
      • Ascension
      • -
      • Whit(Pentecost) Monday
      • -
      • New Year's Day, January 1st
      • -
      • May Day, May 1st
      • -
      • National Independence Day, May 17st
      • -
      • Christmas, December 25th
      • -
      • Boxing Day, December 26th
      • -
      - - \ingroup calendars - */ - public class Norway : Calendar { - public Norway() : base(Impl.Singleton) { } - - class Impl : Calendar.WesternImpl { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Norway"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // Holy Thursday - || (dd == em-4) - // Good Friday - || (dd == em-3) - // Easter Monday - || (dd == em) - // Ascension Thursday - || (dd == em+38) - // Whit Monday - || (dd == em+49) - // New Year's Day - || (d == 1 && m == Month.January) - // May Day - || (d == 1 && m == Month.May) - // National Independence Day - || (d == 17 && m == Month.May) - // Christmas - || (d == 25 && m == Month.December) - // Boxing Day - || (d == 26 && m == Month.December)) - return false; - return true; - } - } - } -} - diff --git a/src/QLNet/Time/Calendars/nullcalendar.cs b/src/QLNet/Time/Calendars/nullcalendar.cs deleted file mode 100644 index eb59d6656..000000000 --- a/src/QLNet/Time/Calendars/nullcalendar.cs +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! %Calendar for reproducing theoretical calculations. - /*! This calendar has no holidays. It ensures that dates at whole-month distances have the same day of month. */ - public class NullCalendar : Calendar { - public NullCalendar() : base(Impl.Singleton) { } - - class Impl : Calendar { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Null calendar"; } - public override bool isWeekend(DayOfWeek w) { return false; } - public override bool isBusinessDay(Date d) { return true; } - } - } -} \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/poland.cs b/src/QLNet/Time/Calendars/poland.cs deleted file mode 100644 index 108ee56e8..000000000 --- a/src/QLNet/Time/Calendars/poland.cs +++ /dev/null @@ -1,89 +0,0 @@ -/* - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Andrea Maggiulli - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - //! Polish calendar - /*! Holidays: -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • Easter Monday
      • -
      • Corpus Christi
      • -
      • New Year's Day, January 1st
      • -
      • Epiphany, January 6th (since 2011)
      • -
      • May Day, May 1st
      • -
      • Constitution Day, May 3rd
      • -
      • Assumption of the Blessed Virgin Mary, August 15th
      • -
      • All Saints Day, November 1st
      • -
      • Independence Day, November 11th
      • -
      • Christmas, December 25th
      • -
      • 2nd Day of Christmas, December 26th
      • -
      - - \ingroup calendars - */ - public class Poland : Calendar { - public Poland() : base(Impl.Singleton) { } - - class Impl : Calendar.WesternImpl { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Poland"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // Easter Monday - || (dd == em) - // Corpus Christi - || (dd == em+59) - // New Year's Day - || (d == 1 && m == Month.January) - // Epiphany - || (d == 6 && m == Month.January && y >= 2011) - // May Day - || (d == 1 && m == Month.May) - // Constitution Day - || (d == 3 && m == Month.May) - // Assumption of the Blessed Virgin Mary - || (d == 15 && m == Month.August) - // All Saints Day - || (d == 1 && m == Month.November) - // Independence Day - || (d ==11 && m == Month.November) - // Christmas - || (d == 25 && m == Month.December) - // 2nd Day of Christmas - || (d == 26 && m == Month.December)) - return false; - return true; - } - } - } -} - diff --git a/src/QLNet/Time/Calendars/saudiarabia.cs b/src/QLNet/Time/Calendars/saudiarabia.cs deleted file mode 100644 index 4dab22abe..000000000 --- a/src/QLNet/Time/Calendars/saudiarabia.cs +++ /dev/null @@ -1,84 +0,0 @@ -/* - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - Copyright (C) 2008, 2009 , 2010, 2011 Andrea Maggiulli (a.maggiulli@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - //! Saudi Arabian calendar - /*! Holidays for the Tadawul financial market - (data from ): -
        -
      • Thursdays
      • -
      • Fridays
      • -
      • National Day of Saudi Arabia, September 23rd
      • -
      - - Other holidays for which no rule is given - (data available for 2004-2011 only:) -
        -
      • Eid Al-Adha
      • -
      • Eid Al-Fitr
      • -
      - - \ingroup calendars - */ - public class SaudiArabia : Calendar { - public SaudiArabia() : base(Impl.Singleton) { } - - class Impl : Calendar { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Tadawul"; } - public override bool isWeekend(DayOfWeek w) { - return w == DayOfWeek.Thursday || w == DayOfWeek.Friday; - } - - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - - if (isWeekend(w) - // National Day - || (d == 23 && m == Month.September) - // Eid Al-Adha - || (d >= 1 && d <= 6 && m == Month.February && y==2004) - || (d >= 21 && d <= 25 && m == Month.January && y==2005) - || (d >= 26 && m == Month.November && y == 2009) - || (d <= 4 && m == Month.December && y == 2009) - || (d >= 11 && d <= 19 && m == Month.November && y == 2010) - // Eid Al-Fitr - || (d >= 25 && d <= 29 && m == Month.November && y==2004) - || (d >= 14 && d <= 18 && m == Month.November && y==2005) - || (d >= 25 && m == Month.August && y == 2011) - || (d <= 2 && m == Month.September && y == 2011) - // other one-shot holidays - || (d == 26 && m == Month.February && y == 2011) - || (d == 19 && m == Month.March && y == 2011) - ) - return false; - return true; - } - } - } -} \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/singapore.cs b/src/QLNet/Time/Calendars/singapore.cs deleted file mode 100644 index 9118865e4..000000000 --- a/src/QLNet/Time/Calendars/singapore.cs +++ /dev/null @@ -1,148 +0,0 @@ -/* - Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - //! %Singapore calendars - /*! Holidays for the Singapore exchange - (data from ): -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's day, January 1st
      • -
      • Good Friday
      • -
      • Labour Day, May 1st
      • -
      • National Day, August 9th
      • -
      • Christmas, December 25th
      • -
      - - Other holidays for which no rule is given - (data available for 2004-2010, 2012-2013 only:) -
        -
      • Chinese New Year
      • -
      • Hari Raya Haji
      • -
      • Vesak Poya Day
      • -
      • Deepavali
      • -
      • Diwali
      • -
      • Hari Raya Puasa
      • -
      - - \ingroup calendars - */ - public class Singapore : Calendar { - public Singapore() : base(Impl.Singleton) { } - - class Impl : Calendar.WesternImpl { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Singapore exchange"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day - || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) && m == Month.January) - // Good Friday - || (dd == em - 3) - // Labor Day - || (d == 1 && m == Month.May) - // National Day - || ((d == 9 || (d == 10 && w == DayOfWeek.Monday)) && m == Month.August) - // Christmas Day - || (d == 25 && m == Month.December) - - // Chinese New Year - || ((d == 22 || d == 23) && m == Month.January && y == 2004) - || ((d == 9 || d == 10) && m == Month.February && y == 2005) - || ((d == 30 || d == 31) && m == Month.January && y == 2006) - || ((d == 19 || d == 20) && m == Month.February && y == 2007) - || ((d == 7 || d == 8) && m == Month.February && y == 2008) - || ((d == 26 || d == 27) && m == Month.January && y == 2009) - || ((d == 15 || d == 16) && m == Month.January && y == 2010) - || ((d == 23 || d == 24) && m == Month.January && y == 2012) - || ((d == 11 || d == 12) && m == Month.February && y == 2013) - || ( d == 31 && m == Month.January && y == 2014 ) - || ( d == 1 && m == Month.February && y == 2014 ) - - // Hari Raya Haji - || ((d == 1 || d == 2) && m == Month.February && y == 2004) - || (d == 21 && m == Month.January && y == 2005) - || (d == 10 && m == Month.January && y == 2006) - || (d == 2 && m == Month.January && y == 2007) - || (d == 20 && m == Month.December && y == 2007) - || (d == 8 && m == Month.December && y == 2008) - || (d == 27 && m == Month.November && y == 2009) - || (d == 17 && m == Month.November && y == 2010) - || (d == 26 && m == Month.October && y == 2012) - || (d == 15 && m == Month.October && y == 2013) - || ( d == 6 && m == Month.October && y == 2014 ) - - // Vesak Poya Day - || (d == 2 && m == Month.June && y == 2004) - || (d == 22 && m == Month.May && y == 2005) - || (d == 12 && m == Month.May && y == 2006) - || (d == 31 && m == Month.May && y == 2007) - || (d == 18 && m == Month.May && y == 2008) - || (d == 9 && m == Month.May && y == 2009) - || (d == 28 && m == Month.May && y == 2010) - || (d == 5 && m == Month.May && y == 2012) - || (d == 24 && m == Month.May && y == 2013) - || ( d == 13 && m == Month.May && y == 2014 ) - - // Deepavali - || (d == 11 && m == Month.November && y == 2004) - || (d == 8 && m == Month.November && y == 2007) - || (d == 28 && m == Month.October && y == 2008) - || (d == 16 && m == Month.November && y == 2009) - || (d == 5 && m == Month.November && y == 2010) - || (d == 13 && m == Month.November && y == 2012) - || (d == 2 && m == Month.November && y == 2013) - || ( d == 23 && m == Month.October && y == 2014 ) - - // Diwali - || (d == 1 && m == Month.November && y == 2005) - - // Hari Raya Puasa - || ((d == 14 || d == 15) && m == Month.November && y == 2004) - || (d == 3 && m == Month.November && y == 2005) - || (d == 24 && m == Month.October && y == 2006) - || (d == 13 && m == Month.October && y == 2007) - || (d == 1 && m == Month.October && y == 2008) - || (d == 21 && m == Month.September && y == 2009) - || (d == 10 && m == Month.September && y == 2010) - || (d == 20 && m == Month.August && y == 2012) - || (d == 8 && m == Month.August && y == 2013) - || ( d == 28 && m == Month.July && y == 2014 ) - ) - return false; - return true; - } - } - } -} - - diff --git a/src/QLNet/Time/Calendars/slovakia.cs b/src/QLNet/Time/Calendars/slovakia.cs deleted file mode 100644 index c8eb9d336..000000000 --- a/src/QLNet/Time/Calendars/slovakia.cs +++ /dev/null @@ -1,101 +0,0 @@ -/* - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! Slovak calendars - /*! Holidays for the Bratislava stock exchange - (data from ): -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Epiphany, January 6th
      • -
      • Good Friday
      • -
      • Easter Monday
      • -
      • May Day, May 1st
      • -
      • Liberation of the Republic, May 8th
      • -
      • SS. Cyril and Methodius, July 5th
      • -
      • Slovak National Uprising, August 29th
      • -
      • Constitution of the Slovak Republic, September 1st
      • -
      • Our Lady of the Seven Sorrows, September 15th
      • -
      • All Saints Day, November 1st
      • -
      • Freedom and Democracy of the Slovak Republic, November 17th
      • -
      • Christmas Eve, December 24th
      • -
      • Christmas, December 25th
      • -
      • St. Stephen, December 26th
      • -
      - - \ingroup calendars - */ - public class Slovakia : Calendar { - public Slovakia() : base(Impl.Singleton) { } - - class Impl : Calendar.WesternImpl { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Bratislava stock exchange"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Epiphany - || (d == 6 && m == Month.January) - // Good Friday - || (dd == em-3) - // Easter Monday - || (dd == em) - // May Day - || (d == 1 && m == Month.May) - // Liberation of the Republic - || (d == 8 && m == Month.May) - // SS. Cyril and Methodius - || (d == 5 && m == Month.July) - // Slovak National Uprising - || (d == 29 && m == Month.August) - // Constitution of the Slovak Republic - || (d == 1 && m == Month.September) - // Our Lady of the Seven Sorrows - || (d == 15 && m == Month.September) - // All Saints Day - || (d == 1 && m == Month.November) - // Freedom and Democracy of the Slovak Republic - || (d == 17 && m == Month.November) - // Christmas Eve - || (d == 24 && m == Month.December) - // Christmas - || (d == 25 && m == Month.December) - // St. Stephen - || (d == 26 && m == Month.December) - // unidentified closing days for stock exchange - || (d >= 24 && d <= 31 && m == Month.December && y == 2004) - || (d >= 24 && d <= 31 && m == Month.December && y == 2005)) - return false; - return true; - } - } - } -} diff --git a/src/QLNet/Time/Calendars/southafrica.cs b/src/QLNet/Time/Calendars/southafrica.cs deleted file mode 100644 index 04f81f3d0..000000000 --- a/src/QLNet/Time/Calendars/southafrica.cs +++ /dev/null @@ -1,108 +0,0 @@ -/* - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Andrea Maggiulli - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet -{ - - //! South-African calendar - /*! Holidays: -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st (possibly moved to Monday)
      • -
      • Good Friday
      • -
      • Family Day, Easter Monday
      • -
      • Human Rights Day, March 21st (possibly moved to Monday)
      • -
      • Freedom Day, April 27th (possibly moved to Monday)
      • -
      • Workers Day, May 1st (possibly moved to Monday)
      • -
      • Youth Day, June 16th (possibly moved to Monday)
      • -
      • National Women's Day, August 9th - (possibly moved to Monday)
      • -
      • Heritage Day, September 24th (possibly moved to Monday)
      • -
      • Day of Reconciliation, December 16th - (possibly moved to Monday)
      • -
      • Christmas December 25th
      • -
      • Day of Goodwill December 26th (possibly moved to Monday)
      • -
      - - \ingroup calendars - */ - public class SouthAfrica : Calendar { - public SouthAfrica() : base(Impl.Singleton) { } - - class Impl : Calendar.WesternImpl { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "South Africa"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day (possibly moved to Monday) - || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) && m == Month.January) - // Good Friday - || (dd == em-3) - // Family Day - || (dd == em) - // Human Rights Day, March 21st (possibly moved to Monday) - || ((d == 21 || (d == 22 && w == DayOfWeek.Monday)) - && m == Month.March) - // Freedom Day, April 27th (possibly moved to Monday) - || ((d == 27 || (d == 28 && w == DayOfWeek.Monday)) - && m == Month.April) - // Election Day, April 14th 2004 - || (d == 14 && m == Month.April && y == 2004) - // Workers Day, May 1st (possibly moved to Monday) - || ((d == 1 || (d == 2 && w == DayOfWeek.Monday)) - && m == Month.May) - // Youth Day, June 16th (possibly moved to Monday) - || ((d == 16 || (d == 17 && w == DayOfWeek.Monday)) - && m == Month.June) - // National Women's Day, August 9th (possibly moved to Monday) - || ((d == 9 || (d == 10 && w == DayOfWeek.Monday)) - && m == Month.August) - // Heritage Day, September 24th (possibly moved to Monday) - || ((d == 24 || (d == 25 && w == DayOfWeek.Monday)) - && m == Month.September) - // Day of Reconciliation, December 16th - // (possibly moved to Monday) - || ((d == 16 || (d == 17 && w == DayOfWeek.Monday)) - && m == Month.December) - // Christmas - || (d == 25 && m == Month.December) - // Day of Goodwill (possibly moved to Monday) - || ((d == 26 || (d == 27 && w == DayOfWeek.Monday)) - && m == Month.December) - ) - return false; - return true; - } - } - } -} - diff --git a/src/QLNet/Time/Calendars/southkorea.cs b/src/QLNet/Time/Calendars/southkorea.cs deleted file mode 100644 index a5a80cf78..000000000 --- a/src/QLNet/Time/Calendars/southkorea.cs +++ /dev/null @@ -1,262 +0,0 @@ -/* - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - //! South Korean calendars - /*! Public holidays: -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Independence Day, March 1st
      • -
      • Arbour Day, April 5th (until 2005)
      • -
      • Labour Day, May 1st
      • -
      • Children's Day, May 5th
      • -
      • Memorial Day, June 6th
      • -
      • Constitution Day, July 17th (until 2007)
      • -
      • Liberation Day, August 15th
      • -
      • National Fondation Day, October 3th
      • -
      • Christmas Day, December 25th
      • -
      - - Other holidays for which no rule is given - (data available for 2004-2032 only:) -
        -
      • Lunar New Year, the last day of the previous lunar year
      • -
      • Election Days
      • -
      • National Assemblies
      • -
      • Presidency
      • -
      • Regional Election Days
      • -
      • Buddha's birthday
      • -
      • Harvest Moon Day
      • -
      - - Holidays for the Korea exchange - (data from or - ): -
        -
      • Public holidays as listed above
      • -
      • Year-end closing
      • -
      - - \ingroup calendars - */ - public class SouthKorea : Calendar { - public enum Market { Settlement, //!< Public holidays - KRX //!< Korea exchange - } - - public SouthKorea() : this(Market.KRX) { } - public SouthKorea(Market m) - : base() { - // all calendar instances on the same market share the same - // implementation instance - switch (m) { - case Market.Settlement: - calendar_ = Settlement.Singleton; - break; - case Market.KRX: - calendar_ = KRX.Singleton; - break; - default: - throw new ArgumentException("Unknown market: " + m); - } - } - - class Settlement : Calendar { - public static readonly Settlement Singleton = new Settlement(); - - public override string name() { return "South-Korean settlement"; } - public override bool isWeekend(DayOfWeek w) { - return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; - } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Independence Day - || (d == 1 && m == Month.March) - // Arbour Day - || (d == 5 && m == Month.April && y <= 2005) - // Labour Day - || (d == 1 && m == Month.May) - // Children's Day - || (d == 5 && m == Month.May) - // Memorial Day - || (d == 6 && m == Month.June) - // Constitution Day - || (d == 17 && m == Month.July && y <= 2007) - // Liberation Day - || (d == 15 && m == Month.August) - // National Foundation Day - || (d == 3 && m == Month.October) - // Christmas Day - || (d == 25 && m == Month.December) - - // Lunar New Year - || ((d == 21 || d == 22 || d == 23) && m == Month.January && y == 2004) - || ((d == 8 || d == 9 || d == 10) && m == Month.February && y == 2005) - || ((d == 28 || d == 29 || d == 30) && m == Month.January && y == 2006) - || (d == 19 && m == Month.February && y == 2007) - || ((d == 6 || d == 7 || d == 8) && m == Month.February && y == 2008) - || ((d == 25 || d == 26 || d == 27) && m == Month.January && y == 2009) - || ((d == 13 || d == 14 || d == 15) && m == Month.February && y == 2010) - || ((d == 2 || d == 3 || d == 4) && m == Month.February && y == 2011) - || ((d == 23 || d == 24) && m == Month.January && y == 2012) - || (d == 11 && m == Month.February && y == 2013) - || ( ( d == 30 || d == 31 ) && m == Month.January && y == 2014 ) - || ( ( d == 18 || d == 19 || d == 20 ) && m == Month.February && y == 2015 ) - || ( ( d == 7 || d == 8 || d == 9 ) && m == Month.February && y == 2016 ) - || ( ( d == 27 || d == 28 || d == 29 ) && m == Month.January && y == 2017 ) - || ( ( d == 15 || d == 16 || d == 17 ) && m == Month.February && y == 2018 ) - || ( ( d == 4 || d == 5 || d == 6 ) && m == Month.February && y == 2019 ) - || ( ( d == 24 || d == 25 || d == 26 ) && m == Month.January && y == 2020 ) - || ( ( d == 11 || d == 12 || d == 13 ) && m == Month.February && y == 2021 ) - || ( ( ( d == 31 && m == Month.January ) || ( ( d == 1 || d == 2 ) - && m == Month.February ) ) && y == 2022 ) - || ( ( d == 21 || d == 22 || d == 23 ) && m == Month.January && y == 2023 ) - || ( ( d == 9 || d == 10 || d == 11 ) && m == Month.February && y == 2024 ) - || ( ( d == 28 || d == 29 || d == 30 ) && m == Month.January && y == 2025 ) - || ( ( d == 28 || d == 29 || d == 30 ) && m == Month.January && y == 2025 ) - || ( ( d == 16 || d == 17 || d == 18 ) && m == Month.February && y == 2026 ) - || ( ( d == 5 || d == 6 || d == 7 ) && m == Month.February && y == 2027 ) - || ( ( d == 25 || d == 26 || d == 27 ) && m == Month.January && y == 2028 ) - || ( ( d == 12 || d == 13 || d == 14 ) && m == Month.February && y == 2029 ) - || ( ( d == 2 || d == 3 || d == 4 ) && m == Month.February && y == 2030 ) - || ( ( d == 22 || d == 23 || d == 24 ) && m == Month.January && y == 2031 ) - || ( ( d == 10 || d == 11 || d == 12 ) && m == Month.February && y == 2032 ) - // Election Days - || (d == 15 && m == Month.April && y == 2004) // National Assembly - || (d == 31 && m == Month.May && y == 2006) // Regional election - || (d == 19 && m == Month.December && y == 2007) // Presidency - || (d == 9 && m == Month.April && y == 2008) // National Assembly - || (d == 2 && m == Month.June && y == 2010) // Local election - || (d == 11 && m == Month.April && y == 2012) // National Assembly - || (d == 19 && m == Month.December && y == 2012) // Presidency - || ( d == 4 && m == Month.June && y == 2014 ) // Local election - || ( d == 13 && m == Month.April && y == 2016 ) // National Assembly - // Buddha's birthday - || (d == 26 && m == Month.May && y == 2004) - || (d == 15 && m == Month.May && y == 2005) - || (d == 24 && m == Month.May && y == 2007) - || (d == 12 && m == Month.May && y == 2008) - || (d == 2 && m == Month.May && y == 2009) - || (d == 21 && m == Month.May && y == 2010) - || (d == 10 && m == Month.May && y == 2011) - || (d == 28 && m == Month.May && y == 2012) - || (d == 17 && m == Month.May && y == 2013) - || ( d == 6 && m == Month.May && y == 2014) - || ( d == 25 && m == Month.May && y == 2015 ) - || ( d == 14 && m == Month.May && y == 2016 ) - || ( d == 3 && m == Month.May && y == 2017 ) - || ( d == 22 && m == Month.May && y == 2018 ) - || ( d == 12 && m == Month.May && y == 2019 ) - || ( d == 30 && m == Month.April && y == 2020 ) - || ( d == 19 && m == Month.May && y == 2021 ) - || ( d == 8 && m == Month.May && y == 2022 ) - || ( d == 26 && m == Month.May && y == 2023 ) - || ( d == 15 && m == Month.May && y == 2024 ) - || ( d == 5 && m == Month.May && y == 2025 ) - || ( d == 24 && m == Month.May && y == 2026 ) - || ( d == 13 && m == Month.May && y == 2027 ) - || ( d == 2 && m == Month.May && y == 2028 ) - || ( d == 20 && m == Month.May && y == 2029 ) - || ( d == 9 && m == Month.May && y == 2030 ) - || ( d == 28 && m == Month.May && y == 2031 ) - || ( d == 16 && m == Month.May && y == 2032 ) - // Special holiday: 70 years from Independence Day - || ( d == 14 && m == Month.August && y == 2015 ) - // Harvest Moon Day - || ((d == 27 || d == 28 || d == 29) && m == Month.September && y == 2004) - || ((d == 17 || d == 18 || d == 19) && m == Month.September && y == 2005) - || ((d == 5 || d == 6 || d == 7) && m == Month.October && y == 2006) - || ((d == 24 || d == 25 || d == 26) && m == Month.September && y == 2007) - || ((d == 13 || d == 14 || d == 15) && m == Month.September && y == 2008) - || ((d == 2 || d == 3 || d == 4) && m == Month.October && y == 2009) - || ((d == 21 || d == 22 || d == 23) && m == Month.September && y == 2010) - || ((d == 12 || d == 13) && m == Month.September && y == 2011) - || (d == 1 && m == Month.October && y == 2012) - || ((d == 18 || d == 19 || d == 20) && m == Month.September && y == 2013) - || ( ( d == 8 || d == 9 || d == 10 ) && m == Month.September && y == 2014 ) - || ( ( d == 28 || d == 29 ) && m == Month.September && y == 2015 ) - || ( ( d == 14 || d == 15 || d == 16 ) && m == Month.September && y == 2016 ) - || ( ( d == 3 || d == 4 || d == 5 ) && m == Month.October && y == 2017 ) - || ( ( d == 23 || d == 24 || d == 25 ) && m == Month.September && y == 2018 ) - || ( ( d == 12 || d == 13 || d == 14 ) && m == Month.September && y == 2019 ) - || ( ( ( d == 30 && m == Month.September ) || ( ( d == 1 || d == 2 ) - && m == Month.October ) ) && y == 2020 ) - || ( ( d == 20 || d == 21 || d == 22 ) && m == Month.September && y == 2021 ) - || ( ( d == 9 || d == 10 || d == 11 ) && m == Month.September && y == 2022 ) - || ( ( d == 28 || d == 29 || d == 30 ) && m == Month.September && y == 2023 ) - || ( ( d == 16 || d == 17 || d == 18 ) && m == Month.September && y == 2024 ) - || ( ( d == 5 || d == 6 || d == 7 ) && m == Month.October && y == 2025 ) - || ( ( d == 24 || d == 25 || d == 26 ) && m == Month.September && y == 2026 ) - || ( ( d == 14 || d == 15 || d == 16 ) && m == Month.September && y == 2027 ) - || ( ( d == 2 || d == 3 || d == 4 ) && m == Month.October && y == 2028 ) - || ( ( d == 21 || d == 22 || d == 23 ) && m == Month.September && y == 2029 ) - || ( ( d == 11 || d == 12 || d == 13 ) && m == Month.September && y == 2030 ) - || ( ( ( d == 30 && m == Month.September ) || ( ( d == 1 || d == 2 ) - && m == Month.October ) ) && y == 2031 ) - || ( ( d == 18 || d == 19 || d == 20 ) && m == Month.September && y == 2032 ) - // Hangul Proclamation of Korea - || (d == 9 && m == Month.October && y >= 2013) - ) - return false; - - return true; - } - } - - class KRX : Settlement { - public new static readonly KRX Singleton = new KRX(); - - public override string name() { return "South-Korea exchange"; } - public override bool isBusinessDay(Date date) { - // public holidays - if ( !base.isBusinessDay(date) ) - return false; - - int d = date.Day; - DayOfWeek w = date.DayOfWeek; - Month m = (Month)date.Month; - - if ( // Year-end closing - ((((d == 29 || d == 30) && w == DayOfWeek.Friday) || d == 31) - && m == Month.December) - ) - return false; - - return true; - } - } - } -} - - - - diff --git a/src/QLNet/Time/Calendars/sweden.cs b/src/QLNet/Time/Calendars/sweden.cs deleted file mode 100644 index 39d3bc611..000000000 --- a/src/QLNet/Time/Calendars/sweden.cs +++ /dev/null @@ -1,97 +0,0 @@ -/* - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Andrea Maggiulli - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - //! Swedish calendar - /*! Holidays: -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Epiphany, January 6th
      • -
      • Good Friday
      • -
      • Easter Monday
      • -
      • Ascension
      • -
      • Whit(Pentecost) Monday
      • -
      • May Day, May 1st
      • -
      • National Day, June 6th
      • -
      • Midsummer Eve (Friday between June 19-25)
      • -
      • Christmas Eve, December 24th
      • -
      • Christmas Day, December 25th
      • -
      • Boxing Day, December 26th
      • -
      • New Year's Eve, December 31th
      • -
      - - \ingroup calendars - */ - public class Sweden : Calendar { - public Sweden() : base(Impl.Singleton) { } - - class Impl : Calendar.WesternImpl { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Sweden"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - if (isWeekend(w) - // Good Friday - || (dd == em-3) - // Easter Monday - || (dd == em) - // Ascension Thursday - || (dd == em+38) - // Whit Monday - || (dd == em+49) - // New Year's Day - || (d == 1 && m == Month.January) - // Epiphany - || (d == 6 && m == Month.January) - // May Day - || (d == 1 && m == Month.May) - // June 6 id National Day but is not a holiday. - // It has been debated wheter or not this day should be - // declared as a holiday. - // As of 2002 the Stockholmborsen is open that day - // || (d == 6 && m == June) - // Midsummer Eve (Friday between June 19-25) - || (w == DayOfWeek.Friday && (d >= 19 && d <= 25) && m == Month.June) - // Christmas Eve - || (d == 24 && m == Month.December) - // Christmas Day - || (d == 25 && m == Month.December) - // Boxing Day - || (d == 26 && m == Month.December) - // New Year's Eve - || (d == 31 && m == Month.December)) - return false; - return true; - } - } - } -} - diff --git a/src/QLNet/Time/Calendars/switzerland.cs b/src/QLNet/Time/Calendars/switzerland.cs deleted file mode 100644 index a55f87fd9..000000000 --- a/src/QLNet/Time/Calendars/switzerland.cs +++ /dev/null @@ -1,88 +0,0 @@ -/* - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Andrea Maggiulli - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - - //! Swiss calendar - /*! Holidays: -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Berchtoldstag, January 2nd
      • -
      • Good Friday
      • -
      • Easter Monday
      • -
      • Ascension Day
      • -
      • Whit Monday
      • -
      • Labour Day, May 1st
      • -
      • National Day, August 1st
      • -
      • Christmas, December 25th
      • -
      • St. Stephen's Day, December 26th
      • -
      - - \ingroup calendars - */ - public class Switzerland : Calendar { - public Switzerland() : base(Impl.Singleton) { } - - class Impl : Calendar.WesternImpl { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Switzerland"; } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - int em = easterMonday(y); - - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Berchtoldstag - || (d == 2 && m == Month.January) - // Good Friday - || (dd == em-3) - // Easter Monday - || (dd == em) - // Ascension Day - || (dd == em+38) - // Whit Monday - || (dd == em+49) - // Labour Day - || (d == 1 && m == Month.May) - // National Day - || (d == 1 && m == Month.August) - // Christmas - || (d == 25 && m == Month.December) - // St. Stephen's Day - || (d == 26 && m == Month.December)) - return false; - return true; - } - }; - }; -} - - diff --git a/src/QLNet/Time/Calendars/taiwan.cs b/src/QLNet/Time/Calendars/taiwan.cs deleted file mode 100644 index b60c70ce6..000000000 --- a/src/QLNet/Time/Calendars/taiwan.cs +++ /dev/null @@ -1,274 +0,0 @@ -/* - Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - //! Taiwanese calendars - /*! Holidays for the Taiwan stock exchange - (data from ): -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • Peace Memorial Day, February 28
      • -
      • Labor Day, May 1st
      • -
      • Double Tenth National Day, October 10th
      • -
      - - Other holidays for which no rule is given - (data available for 2002-2013 only:) -
        -
      • Chinese Lunar New Year
      • -
      • Tomb Sweeping Day
      • -
      • Dragon Boat Festival
      • -
      • Moon Festival
      • -
      - - \ingroup calendars - */ - public class Taiwan : Calendar { - public Taiwan() : base(Impl.Singleton) { } - - class Impl : Calendar { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Taiwan stock exchange"; } - public override bool isWeekend(DayOfWeek w) { - return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; - } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // Peace Memorial Day - || (d == 28 && m == Month.February) - // Labor Day - || (d == 1 && m == Month.May) - // Double Tenth - || (d == 10 && m == Month.October) - ) - return false; - - if (y == 2002) { - // Dragon Boat Festival and Moon Festival fall on Saturday - if (// Chinese Lunar New Year - (d >= 9 && d <= 17 && m == Month.February) - // Tomb Sweeping Day - || (d == 5 && m == Month.April) - ) - return false; - } - - if (y == 2003) { - // Tomb Sweeping Day falls on Saturday - if (// Chinese Lunar New Year - ((d >= 31 && m == Month.January) || (d <= 5 && m == Month.February)) - // Dragon Boat Festival - || (d == 4 && m == Month.June) - // Moon Festival - || (d == 11 && m == Month.September) - ) - return false; - } - - if (y == 2004) { - // Tomb Sweeping Day falls on Sunday - if (// Chinese Lunar New Year - (d >= 21 && d <= 26 && m == Month.January) - // Dragon Boat Festival - || (d == 22 && m == Month.June) - // Moon Festival - || (d == 28 && m == Month.September) - ) - return false; - } - - if (y == 2005) { - // Dragon Boat and Moon Festival fall on Saturday or Sunday - if (// Chinese Lunar New Year - (d >= 6 && d <= 13 && m == Month.February) - // Tomb Sweeping Day - || (d == 5 && m == Month.April) - // make up for Labor Day, not seen in other years - || (d == 2 && m == Month.May) - ) - return false; - } - - if (y == 2006) { - // Dragon Boat and Moon Festival fall on Saturday or Sunday - if (// Chinese Lunar New Year - ((d >= 28 && m == Month.January) || (d <= 5 && m == Month.February)) - // Tomb Sweeping Day - || (d == 5 && m == Month.April) - // Dragon Boat Festival - || (d == 31 && m == Month.May) - // Moon Festival - || (d == 6 && m == Month.October) - ) - return false; - } - - if (y == 2007) { - if (// Chinese Lunar New Year - (d >= 17 && d <= 25 && m == Month.February) - // Tomb Sweeping Day - || (d == 5 && m == Month.April) - // adjusted holidays - || (d == 6 && m == Month.April) - || (d == 18 && m == Month.June) - // Dragon Boat Festival - || (d == 19 && m == Month.June) - // adjusted holiday - || (d == 24 && m == Month.September) - // Moon Festival - || (d == 25 && m == Month.September) - ) - return false; - } - - if (y == 2008) { - if (// Chinese Lunar New Year - (d >= 4 && d <= 11 && m == Month.February) - // Tomb Sweeping Day - || (d == 4 && m == Month.April) - ) - return false; - } - - if (y == 2009) { - if (// Public holiday - (d == 2 && m == Month.January) - // Chinese Lunar New Year - || (d >= 24 && m == Month.January) - // Tomb Sweeping Day - || (d == 4 && m == Month.April) - // Dragon Boat Festival - || ((d == 28 || d == 29) && m == Month.May) - // Moon Festival - || (d == 3 && m == Month.October) - ) - return false; - } - - if (y == 2010) - { - if (// Chinese Lunar New Year - (d >= 13 && d <= 21 && m == Month.January) - // Tomb Sweeping Day - || (d == 5 && m == Month.April) - // Dragon Boat Festival - || (d == 16 && m == Month.May) - // Moon Festival - || (d == 22 && m == Month.September) - ) - return false; - } - - if (y == 2011) { - if (// Spring Festival - (d >= 2 && d <= 7 && m == Month.February) - // Children's Day - || (d == 4 && m == Month.April) - // Tomb Sweeping Day - || (d == 5 && m == Month.April) - // Labour Day - || (d == 2 && m == Month.May) - // Dragon Boat Festival - || (d == 6 && m == Month.June) - // Mid-Autumn Festival - || (d == 12 && m == Month.September) - ) - return false; - } - - if (y == 2012) { - if (// Spring Festival - (d >= 23 && d <= 27 && m == Month.January) - // Peace Memorial Day - || (d == 27 && m == Month.February) - // Children's Day - // Tomb Sweeping Day - || (d == 4 && m == Month.April) - // Labour Day - || (d == 1 && m == Month.May) - // Dragon Boat Festival - || (d == 23 && m == Month.June) - // Mid-Autumn Festival - || (d == 30 && m == Month.September) - // Memorial Day: - // Founding of the Republic of China - || (d == 31 && m == Month.December) - ) - return false; - } - - if (y == 2013) { - if (// Spring Festival - (d >= 10 && d <= 15 && m == Month.February) - // Children's Day - || (d == 4 && m == Month.April) - // Tomb Sweeping Day - || (d == 5 && m == Month.April) - // Labour Day - || (d == 1 && m == Month.May) - // Dragon Boat Festival - || (d == 12 && m == Month.June) - // Mid-Autumn Festival - || (d >= 19 && d <= 20 && m == Month.September) - ) - return false; - } - - if ( y == 2014 ) - { - if (// Lunar New Year - ( d >= 28 && d <= 30 && m == Month.January ) - // Spring Festival - || ( ( d == 31 && m == Month.January ) || ( d <= 4 && m == Month.February ) ) - // Children's Day - || ( d == 4 && m == Month.April ) - // Tomb Sweeping Day - || ( d == 5 && m == Month.April ) - // Labour Day - || ( d == 1 && m == Month.May ) - // Dragon Boat Festival - || ( d == 2 && m == Month.June ) - // Mid-Autumn Festival - || ( d == 8 && m == Month.September ) - ) - return false; - } - - return true; - } - }; - - }; - -} \ No newline at end of file diff --git a/src/QLNet/Time/Calendars/turkey.cs b/src/QLNet/Time/Calendars/turkey.cs deleted file mode 100644 index 8daf235f0..000000000 --- a/src/QLNet/Time/Calendars/turkey.cs +++ /dev/null @@ -1,168 +0,0 @@ -/* - Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; - -namespace QLNet { - //! Turkish calendar - /*! Holidays for the Istanbul Stock Exchange: - (data from ): -
        -
      • Saturdays
      • -
      • Sundays
      • -
      • New Year's Day, January 1st
      • -
      • National Sovereignty and Children’s Day, April 23rd
      • -
      • Youth and Sports Day, May 19th
      • -
      • Victory Day, August 30th
      • -
      • Republic Day, October 29th
      • -
      • Local Holidays (Kurban, Ramadan; 2004 to 2013 only)
      • -
      - - \ingroup calendars - */ - public class Turkey : Calendar { - public Turkey() : base(Impl.Singleton) { } - - class Impl : Calendar { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Turkey"; } - public override bool isWeekend(DayOfWeek w) { - return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; - } - - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day, dd = date.DayOfYear; - Month m = (Month)date.Month; - int y = date.Year; - - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - // 23 nisan / National Holiday - || (d == 23 && m == Month.April) - // 19 may/ National Holiday - || (d == 19 && m == Month.May) - // 30 aug/ National Holiday - || (d == 30 && m == Month.August) - ///29 ekim National Holiday - || (d == 29 && m == Month.October)) - return false; - - // Local Holidays - if (y == 2004) { - // Kurban - if ((m == Month.February && d <= 4) - // Ramadan - || (m == Month.November && d >= 14 && d <= 16)) - return false; - } else if (y == 2005) { - // Kurban - if ((m == Month.January && d >= 19 && d <= 21) - // Ramadan - || (m == Month.November && d >= 2 && d <= 5)) - return false; - } else if (y == 2006) { - // Kurban - if ((m == Month.January && d >= 10 && d <= 13) - // Ramadan - || (m == Month.October && d >= 23 && d <= 25) - // Kurban - || (m == Month.December && d == 31)) - return false; - } else if (y == 2007) { - // Kurban - if ((m == Month.January && d <= 3) - // Ramadan - || (m == Month.October && d >= 12 && d <= 14) - // Kurban - || (m == Month.December && d >= 20 && d <= 23)) - return false; - } else if (y == 2008) { - // Ramadan - if ((m == Month.September && d == 30) - || (m == Month.October && d <= 2) - // Kurban - || (m == Month.December && d >= 8 && d <= 11)) - return false; - } - else if (y == 2009) - { - // Ramadan - if ((m == Month.September && d >= 20 && d <= 22) - // Kurban - || (m == Month.November && d >= 27 && d <= 30)) - return false; - } - else if (y == 2010) - { - // Ramadan - if ((m == Month.September && d >= 9 && d <= 11) - // Kurban - || (m == Month.November && d >= 16 && d <= 19)) - return false; - } - else if (y == 2011) - { - // not clear from borsainstanbul.com - if ((m == Month.October && d == 1) - || (m == Month.November && d >= 9 && d <= 13)) - return false; - } - else if (y == 2012) - { - // Ramadan - if ((m == Month.August && d >= 18 && d <= 21) - // Kurban - || (m == Month.October && d >= 24 && d <= 28)) - return false; - } - else if (y == 2013) - { - // Ramadan - if ((m == Month.August && d >= 7 && d <= 10) - // Kurban - || (m == Month.October && d >= 14 && d <= 18) - // additional holiday for Republic Day - || (m == Month.October && d == 28)) - return false; - } - else if ( y == 2014 ) - { - // Ramadan - if ( ( m == Month.July && d >= 27 && d <= 30 ) - // Kurban - || ( m == Month.October && d >= 4 && d <= 7 ) - // additional holiday for Republic Day - || ( m == Month.October && d == 29 ) ) - return false; - } - return true; - } - }; - } -} - - - - diff --git a/src/QLNet/Time/Date.cs b/src/QLNet/Time/Date.cs index 40a57c719..3290d07b6 100644 --- a/src/QLNet/Time/Date.cs +++ b/src/QLNet/Time/Date.cs @@ -2,18 +2,18 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -29,8 +29,8 @@ public class Date : IComparable //! Default constructor returning a null date. public Date() - {} - //! Constructor taking a serial number as given by Excel. + {} + //! Constructor taking a serial number as given by Excel. // Serial numbers in Excel have a known problem with leap year 1900 public Date(int serialNumber) { @@ -45,7 +45,7 @@ public Date(int d, int m, int y) : //! More traditional constructor. this(new DateTime(y, m, d)) {} - public Date(int d, int m, int y, int h , int mi , int s , int ms ) : //! More traditional constructor. + public Date(int d, int m, int y, int h, int mi, int s, int ms) : //! More traditional constructor. this(new DateTime(y, m, d, h, mi, s, ms)) {} @@ -88,8 +88,8 @@ public int weekday() public int hours { get { return date.Hour; } } public int minutes { get { return date.Minute; } } public int seconds { get { return date.Second; } } - public int milliseconds { get { return date.Millisecond; } } - public double fractionOfSecond { get { return (double)date.Millisecond/1000; } } + public int milliseconds { get { return date.Millisecond; } } + public double fractionOfSecond { get { return (double)date.Millisecond / 1000; } } public double fractionOfDay() { @@ -107,7 +107,7 @@ public static Date maxDate() return new Date(31, 12, 2199); } - public static Date Today { get { return new Date( DateTime.Today ); } } + public static Date Today { get { return new Date(DateTime.Today); } } public static bool IsLeapYear(int y) { @@ -144,8 +144,8 @@ public static Date nextWeekday(Date d, DayOfWeek dayOfWeek) //! n-th given weekday in the given month and year, e.g., the 4th Thursday of March, 1998 was March 26th, 1998. public static Date nthWeekday(int nth, DayOfWeek dayOfWeek, int m, int y) { - Utils.QL_REQUIRE(nth > 0,()=> "zeroth day of week in a given (month, year) is undefined"); - Utils.QL_REQUIRE(nth < 6,()=> "no more than 5 weekday in a given (month, year)"); + Utils.QL_REQUIRE(nth > 0, () => "zeroth day of week in a given (month, year) is undefined"); + Utils.QL_REQUIRE(nth < 6, () => "no more than 5 weekday in a given (month, year)"); DayOfWeek first = new DateTime(y, m, 1).DayOfWeek; int skip = nth - (dayOfWeek >= first ? 1 : 0); return new Date(1, m, y) + (dayOfWeek - first + skip * 7); @@ -259,8 +259,8 @@ public static implicit operator Date(DateTime d) public static bool operator ==(Date d1, Date d2) { return ((Object)d1 == null || (Object)d2 == null) ? - ((Object)d1 == null && (Object)d2 == null) : - d1.date == d2.date; + ((Object)d1 == null && (Object)d2 == null) : + d1.date == d2.date; } public static bool operator !=(Date d1, Date d2) diff --git a/src/QLNet/Time/DayCounter.cs b/src/QLNet/Time/DayCounter.cs index aa644b34c..f59b771b4 100644 --- a/src/QLNet/Time/DayCounter.cs +++ b/src/QLNet/Time/DayCounter.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,58 +20,65 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - // This class provides methods for determining the length of a time period according to given market convention, - // both as a number of days and as a year fraction. - public class DayCounter - { - // this is a placeholder for actual day counters for Singleton pattern use - protected DayCounter dayCounter_; - public DayCounter dayCounter - { - get { return dayCounter_; } - set { dayCounter_ = value; } - } + // This class provides methods for determining the length of a time period according to given market convention, + // both as a number of days and as a year fraction. + public class DayCounter + { + // this is a placeholder for actual day counters for Singleton pattern use + protected DayCounter dayCounter_; + public DayCounter dayCounter + { + get + { + return dayCounter_; + } + set + { + dayCounter_ = value; + } + } - // constructors - /*! The default constructor returns a day counter with a null implementation, which is therefore unusable except as a - placeholder. */ - public DayCounter() { } - public DayCounter(DayCounter d) { dayCounter_ = d; } + // constructors + /*! The default constructor returns a day counter with a null implementation, which is therefore unusable except as a + placeholder. */ + public DayCounter() { } + public DayCounter(DayCounter d) { dayCounter_ = d; } - // comparison based on name - // Returns true iff the two day counters belong to the same derived class. - public static bool operator ==(DayCounter d1, DayCounter d2) - { - return ((Object)d1 == null || (Object)d2 == null) ? - ((Object)d1 == null && (Object)d2 == null) : - (d1.empty() && d2.empty()) || (!d1.empty() && !d2.empty() && d1.name() == d2.name()); - } - public static bool operator !=(DayCounter d1, DayCounter d2) { return !(d1 == d2); } + // comparison based on name + // Returns true iff the two day counters belong to the same derived class. + public static bool operator ==(DayCounter d1, DayCounter d2) + { + return ((Object)d1 == null || (Object)d2 == null) ? + ((Object)d1 == null && (Object)d2 == null) : + (d1.empty() && d2.empty()) || (!d1.empty() && !d2.empty() && d1.name() == d2.name()); + } + public static bool operator !=(DayCounter d1, DayCounter d2) { return !(d1 == d2); } - public bool empty() { return dayCounter_ == null; } + public bool empty() { return dayCounter_ == null; } - public virtual string name() - { - if (empty()) return "No implementation provided"; - return dayCounter_.name(); - } + public virtual string name() + { + if (empty()) + return "No implementation provided"; + return dayCounter_.name(); + } - public virtual int dayCount(Date d1, Date d2) - { - Utils.QL_REQUIRE(!empty(), () => "No implementation provided"); - return dayCounter_.dayCount(d1, d2); - } + public virtual int dayCount(Date d1, Date d2) + { + Utils.QL_REQUIRE(!empty(), () => "No implementation provided"); + return dayCounter_.dayCount(d1, d2); + } - public double yearFraction(Date d1, Date d2) { return yearFraction(d1, d2, d1, d2); } - public virtual double yearFraction(Date d1, Date d2, Date refPeriodStart, Date refPeriodEnd) - { - Utils.QL_REQUIRE(!empty(), () => "No implementation provided"); - return dayCounter_.yearFraction(d1, d2, refPeriodStart, refPeriodEnd); - } + public double yearFraction(Date d1, Date d2) { return yearFraction(d1, d2, d1, d2); } + public virtual double yearFraction(Date d1, Date d2, Date refPeriodStart, Date refPeriodEnd) + { + Utils.QL_REQUIRE(!empty(), () => "No implementation provided"); + return dayCounter_.yearFraction(d1, d2, refPeriodStart, refPeriodEnd); + } - public override bool Equals(object o) { return this == (DayCounter)o; } - public override int GetHashCode() { return 0; } - public override string ToString() { return this.name(); } - } + public override bool Equals(object o) { return this == (DayCounter)o; } + public override int GetHashCode() { return 0; } + public override string ToString() { return this.name(); } + } } \ No newline at end of file diff --git a/src/QLNet/Time/DayCounters/Actual360.cs b/src/QLNet/Time/DayCounters/Actual360.cs index 8f0d290ce..fc55769b7 100644 --- a/src/QLNet/Time/DayCounters/Actual360.cs +++ b/src/QLNet/Time/DayCounters/Actual360.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,7 +24,7 @@ namespace QLNet /*! Actual/360 day count convention, also known as "Act/360", or "A/360". */ public class Actual360 : DayCounter { - public enum Actual360Convention { excludeLastDay, includeLastDay }; + public enum Actual360Convention { excludeLastDay, includeLastDay } public Actual360(bool c = false) : base(conventions(c)) { } diff --git a/src/QLNet/Time/DayCounters/Actual365Fixed.cs b/src/QLNet/Time/DayCounters/Actual365Fixed.cs index 77eca85a8..efbc6c164 100644 --- a/src/QLNet/Time/DayCounters/Actual365Fixed.cs +++ b/src/QLNet/Time/DayCounters/Actual365Fixed.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,26 +19,26 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - /* "Actual/365 (Fixed)" day count convention, also know as "Act/365 (Fixed)", "A/365 (Fixed)", or "A/365F". - According to ISDA, "Actual/365" (without "Fixed") is an alias for "Actual/Actual (ISDA)" (see ActualActual.) - * If Actual/365 is not explicitly specified as fixed in an instrument specification, - * you might want to double-check its meaning. */ - public class Actual365Fixed : DayCounter - { - public Actual365Fixed() : base(Impl.Singleton) { } - - class Impl : DayCounter - { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Actual/365 (Fixed)"; } - public override int dayCount(Date d1, Date d2) { return (d2 - d1); } - public override double yearFraction(Date d1, Date d2, Date refPeriodStart, Date refPeriodEnd) - { - return Date.daysBetween( d1, d2 ) / 365.0; - } - - } - } + /* "Actual/365 (Fixed)" day count convention, also know as "Act/365 (Fixed)", "A/365 (Fixed)", or "A/365F". + According to ISDA, "Actual/365" (without "Fixed") is an alias for "Actual/Actual (ISDA)" (see ActualActual.) + * If Actual/365 is not explicitly specified as fixed in an instrument specification, + * you might want to double-check its meaning. */ + public class Actual365Fixed : DayCounter + { + public Actual365Fixed() : base(Impl.Singleton) { } + + class Impl : DayCounter + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Actual/365 (Fixed)"; } + public override int dayCount(Date d1, Date d2) { return (d2 - d1); } + public override double yearFraction(Date d1, Date d2, Date refPeriodStart, Date refPeriodEnd) + { + return Date.daysBetween(d1, d2) / 365.0; + } + + } + } } \ No newline at end of file diff --git a/src/QLNet/Time/DayCounters/Actual365NoLeap.cs b/src/QLNet/Time/DayCounters/Actual365NoLeap.cs index f35d7bc09..ca91d8152 100644 --- a/src/QLNet/Time/DayCounters/Actual365NoLeap.cs +++ b/src/QLNet/Time/DayCounters/Actual365NoLeap.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,49 +19,49 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! Actual/365 (No Leap) day count convention + //! Actual/365 (No Leap) day count convention /*! "Actual/365 (No Leap)" day count convention, also known as "Act/365 (NL)", "NL/365", or "Actual/365 (JGB)". \ingroup daycounters */ - public class Actual365NoLeap : DayCounter - { - public Actual365NoLeap() : base(Impl.Singleton) { } - - class Impl : DayCounter - { - public static readonly Impl Singleton = new Impl(); - private static int[] MonthOffset = { 0, 31, 59, 90, 120, 151, // Jan - Jun - 181, 212, 243, 273, 304, 334 // Jun - Dec - }; - private Impl() { } + public class Actual365NoLeap : DayCounter + { + public Actual365NoLeap() : base(Impl.Singleton) { } - public override string name() { return "Actual/365 (NL)"; } - public override int dayCount(Date d1, Date d2) - { - - int s1, s2; + class Impl : DayCounter + { + public static readonly Impl Singleton = new Impl(); + private static int[] MonthOffset = { 0, 31, 59, 90, 120, 151, // Jan - Jun + 181, 212, 243, 273, 304, 334 // Jun - Dec + }; + private Impl() { } - s1 = d1.Day + MonthOffset[d1.month()-1] + (d1.year() * 365); - s2 = d2.Day + MonthOffset[d2.month()-1] + (d2.year() * 365); + public override string name() { return "Actual/365 (NL)"; } + public override int dayCount(Date d1, Date d2) + { - if (d1.month() == (int)Month.Feb && d1.Day == 29) - { - --s1; - } + int s1, s2; - if (d2.month() == (int)Month.Feb && d2.Day == 29) - { - --s2; - } + s1 = d1.Day + MonthOffset[d1.month() - 1] + (d1.year() * 365); + s2 = d2.Day + MonthOffset[d2.month() - 1] + (d2.year() * 365); - return s2 - s1; - } - public override double yearFraction(Date d1, Date d2, Date refPeriodStart, Date refPeriodEnd) + if (d1.month() == (int)Month.Feb && d1.Day == 29) { - return dayCount(d1, d2)/365.0; + --s1; } - } - } + + if (d2.month() == (int)Month.Feb && d2.Day == 29) + { + --s2; + } + + return s2 - s1; + } + public override double yearFraction(Date d1, Date d2, Date refPeriodStart, Date refPeriodEnd) + { + return dayCount(d1, d2) / 365.0; + } + } + } } diff --git a/src/QLNet/Time/DayCounters/ActualActual.cs b/src/QLNet/Time/DayCounters/ActualActual.cs index d4e68607a..54a829994 100644 --- a/src/QLNet/Time/DayCounters/ActualActual.cs +++ b/src/QLNet/Time/DayCounters/ActualActual.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,207 +20,213 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! Actual/Actual day count - /*! The day count can be calculated according to: - - the ISDA convention, also known as "Actual/Actual (Historical)", "Actual/Actual", "Act/Act", - and according to ISDA also "Actual/365", "Act/365", and "A/365" - - the ISMA and US Treasury convention, also known as "Actual/Actual (Bond)"; - - the AFB convention, also known as "Actual/Actual (Euro)". - For more details, refer to http://www.isda.org/publications/pdf/Day-Count-Fracation1999.pdf */ - public class ActualActual : DayCounter - { - public enum Convention { ISMA, Bond, ISDA, Historical, Actual365, AFB, Euro }; - - public ActualActual() : base(ISDA_Impl.Singleton) { } - public ActualActual(Convention c) : base(conventions(c)) { } - - private static DayCounter conventions(Convention c) - { - switch (c) + //! Actual/Actual day count + /*! The day count can be calculated according to: + - the ISDA convention, also known as "Actual/Actual (Historical)", "Actual/Actual", "Act/Act", + and according to ISDA also "Actual/365", "Act/365", and "A/365" + - the ISMA and US Treasury convention, also known as "Actual/Actual (Bond)"; + - the AFB convention, also known as "Actual/Actual (Euro)". + For more details, refer to http://www.isda.org/publications/pdf/Day-Count-Fracation1999.pdf */ + public class ActualActual : DayCounter + { + public enum Convention { ISMA, Bond, ISDA, Historical, Actual365, AFB, Euro } + + public ActualActual() : base(ISDA_Impl.Singleton) { } + public ActualActual(Convention c) : base(conventions(c)) { } + + private static DayCounter conventions(Convention c) + { + switch (c) + { + case Convention.ISMA: + case Convention.Bond: + return ISMA_Impl.Singleton; + case Convention.ISDA: + case Convention.Historical: + case Convention.Actual365: + return ISDA_Impl.Singleton; + case Convention.AFB: + case Convention.Euro: + return AFB_Impl.Singleton; + default: + throw new ArgumentException("Unknown day count convention: " + c); + } + } + + private class ISMA_Impl : DayCounter + { + public static readonly ISMA_Impl Singleton = new ISMA_Impl(); + private ISMA_Impl() { } + + public override string name() { return "Actual/Actual (ISMA)"; } + + public override int dayCount(Date d1, Date d2) { return (d2 - d1); } + + public override double yearFraction(Date d1, Date d2, Date d3, Date d4) + { + if (d1 == d2) + return 0; + if (d1 > d2) + return -yearFraction(d2, d1, d3, d4); + + // when the reference period is not specified, try taking it equal to (d1,d2) + Date refPeriodStart = (d3 ?? d1); + Date refPeriodEnd = (d4 ?? d2); + + Utils.QL_REQUIRE(refPeriodEnd > refPeriodStart && refPeriodEnd > d1, () => + "Invalid reference period: date 1: " + d1 + ", date 2: " + d2 + + ", reference period start: " + refPeriodStart + ", reference period end: " + refPeriodEnd); + + // estimate roughly the length in months of a period + int months = (int)(0.5 + 12 * (refPeriodEnd - refPeriodStart) / 365.0); + + // for short periods... + if (months == 0) { - case Convention.ISMA: - case Convention.Bond: - return ISMA_Impl.Singleton; - case Convention.ISDA: - case Convention.Historical: - case Convention.Actual365: - return ISDA_Impl.Singleton; - case Convention.AFB: - case Convention.Euro: - return AFB_Impl.Singleton; - default: - throw new ArgumentException("Unknown day count convention: " + c); + // ...take the reference period as 1 year from d1 + refPeriodStart = d1; + refPeriodEnd = d1 + TimeUnit.Years; + months = 12; } - } - - private class ISMA_Impl : DayCounter - { - public static readonly ISMA_Impl Singleton = new ISMA_Impl(); - private ISMA_Impl() { } - - public override string name() { return "Actual/Actual (ISMA)"; } - public override int dayCount(Date d1, Date d2) { return (d2 - d1); } + double period = months / 12.0; - public override double yearFraction(Date d1, Date d2, Date d3, Date d4) + if (d2 <= refPeriodEnd) { - if (d1 == d2) return 0; - if (d1 > d2) return -yearFraction(d2, d1, d3, d4); - - // when the reference period is not specified, try taking it equal to (d1,d2) - Date refPeriodStart = (d3 ?? d1); - Date refPeriodEnd = (d4 ?? d2); - - Utils.QL_REQUIRE(refPeriodEnd > refPeriodStart && refPeriodEnd > d1,()=> - "Invalid reference period: date 1: " + d1 + ", date 2: " + d2 + - ", reference period start: " + refPeriodStart + ", reference period end: " + refPeriodEnd); - - // estimate roughly the length in months of a period - int months = (int)(0.5 + 12 * (refPeriodEnd - refPeriodStart) / 365.0); - - // for short periods... - if (months == 0) - { - // ...take the reference period as 1 year from d1 - refPeriodStart = d1; - refPeriodEnd = d1 + TimeUnit.Years; - months = 12; - } - - double period = months / 12.0; - - if (d2 <= refPeriodEnd) - { - // here refPeriodEnd is a future (notional?) payment date - if (d1 >= refPeriodStart) - { - // here refPeriodStart is the last (maybe notional) payment date. - // refPeriodStart <= d1 <= d2 <= refPeriodEnd - // [maybe the equality should be enforced, since refPeriodStart < d1 <= d2 < refPeriodEnd could give wrong results] ??? - return period * Date.daysBetween( d1, d2 ) / Date.daysBetween( refPeriodStart, refPeriodEnd ); - } - else - { - // here refPeriodStart is the next (maybe notional) payment date and refPeriodEnd is the second next (maybe notional) payment date. - // d1 < refPeriodStart < refPeriodEnd - // AND d2 <= refPeriodEnd - // this case is long first coupon - - // the last notional payment date - Date previousRef = refPeriodStart - new Period(months, TimeUnit.Months); - if (d2 > refPeriodStart) - return yearFraction(d1, refPeriodStart, previousRef, refPeriodStart) + - yearFraction(refPeriodStart, d2, refPeriodStart, refPeriodEnd); - else - return yearFraction(d1, d2, previousRef, refPeriodStart); - } - } - else - { - // here refPeriodEnd is the last (notional?) payment date - // d1 < refPeriodEnd < d2 AND refPeriodStart < refPeriodEnd - Utils.QL_REQUIRE(refPeriodStart<=d1, ()=> "invalid dates: d1 < refPeriodStart < refPeriodEnd < d2"); - - // now it is: refPeriodStart <= d1 < refPeriodEnd < d2 - - // the part from d1 to refPeriodEnd - double sum = yearFraction(d1, refPeriodEnd, refPeriodStart, refPeriodEnd); - - // the part from refPeriodEnd to d2 - // count how many regular periods are in [refPeriodEnd, d2], then add the remaining time - int i = 0; - Date newRefStart, newRefEnd; - for(;;) - { - newRefStart = refPeriodEnd + new Period(months * i, TimeUnit.Months); - newRefEnd = refPeriodEnd + new Period(months * (i + 1), TimeUnit.Months); - if (d2 < newRefEnd) - { - break; - } - else - { - sum += period; - i++; - } - } - sum += yearFraction(newRefStart, d2, newRefStart, newRefEnd); - return sum; - } + // here refPeriodEnd is a future (notional?) payment date + if (d1 >= refPeriodStart) + { + // here refPeriodStart is the last (maybe notional) payment date. + // refPeriodStart <= d1 <= d2 <= refPeriodEnd + // [maybe the equality should be enforced, since refPeriodStart < d1 <= d2 < refPeriodEnd could give wrong results] ??? + return period * Date.daysBetween(d1, d2) / Date.daysBetween(refPeriodStart, refPeriodEnd); + } + else + { + // here refPeriodStart is the next (maybe notional) payment date and refPeriodEnd is the second next (maybe notional) payment date. + // d1 < refPeriodStart < refPeriodEnd + // AND d2 <= refPeriodEnd + // this case is long first coupon + + // the last notional payment date + Date previousRef = refPeriodStart - new Period(months, TimeUnit.Months); + if (d2 > refPeriodStart) + return yearFraction(d1, refPeriodStart, previousRef, refPeriodStart) + + yearFraction(refPeriodStart, d2, refPeriodStart, refPeriodEnd); + else + return yearFraction(d1, d2, previousRef, refPeriodStart); + } } - }; - - private class ISDA_Impl : DayCounter - { - public static readonly ISDA_Impl Singleton = new ISDA_Impl(); - private ISDA_Impl() { } - - public override string name() { return "Actual/Actual (ISDA)"; } - - public override int dayCount(Date d1, Date d2) { return (d2 - d1); } - - public override double yearFraction(Date d1, Date d2, Date refPeriodStart, Date refPeriodEnd) + else { - if (d1 == d2) return 0; - if (d1 > d2) return -yearFraction(d2, d1, null, null); - - int y1 = d1.Year, y2 = d2.Year; - double dib1 = (Date.IsLeapYear(y1) ? 366 : 365), - dib2 = (Date.IsLeapYear(y2) ? 366 : 365); - - double sum = y2 - y1 - 1; - sum += Date.daysBetween( d1, new Date( 1, Month.January, y1 + 1 ) ) / dib1; - sum += Date.daysBetween( new Date( 1, Month.January, y2 ), d2 ) / dib2; - return sum; + // here refPeriodEnd is the last (notional?) payment date + // d1 < refPeriodEnd < d2 AND refPeriodStart < refPeriodEnd + Utils.QL_REQUIRE(refPeriodStart <= d1, () => "invalid dates: d1 < refPeriodStart < refPeriodEnd < d2"); + + // now it is: refPeriodStart <= d1 < refPeriodEnd < d2 + + // the part from d1 to refPeriodEnd + double sum = yearFraction(d1, refPeriodEnd, refPeriodStart, refPeriodEnd); + + // the part from refPeriodEnd to d2 + // count how many regular periods are in [refPeriodEnd, d2], then add the remaining time + int i = 0; + Date newRefStart, newRefEnd; + for (;;) + { + newRefStart = refPeriodEnd + new Period(months * i, TimeUnit.Months); + newRefEnd = refPeriodEnd + new Period(months * (i + 1), TimeUnit.Months); + if (d2 < newRefEnd) + { + break; + } + else + { + sum += period; + i++; + } + } + sum += yearFraction(newRefStart, d2, newRefStart, newRefEnd); + return sum; + } + } + } + + private class ISDA_Impl : DayCounter + { + public static readonly ISDA_Impl Singleton = new ISDA_Impl(); + private ISDA_Impl() { } + + public override string name() { return "Actual/Actual (ISDA)"; } + + public override int dayCount(Date d1, Date d2) { return (d2 - d1); } + + public override double yearFraction(Date d1, Date d2, Date refPeriodStart, Date refPeriodEnd) + { + if (d1 == d2) + return 0; + if (d1 > d2) + return -yearFraction(d2, d1, null, null); + + int y1 = d1.Year, y2 = d2.Year; + double dib1 = (Date.IsLeapYear(y1) ? 366 : 365), + dib2 = (Date.IsLeapYear(y2) ? 366 : 365); + + double sum = y2 - y1 - 1; + sum += Date.daysBetween(d1, new Date(1, Month.January, y1 + 1)) / dib1; + sum += Date.daysBetween(new Date(1, Month.January, y2), d2) / dib2; + return sum; + } + } + + private class AFB_Impl : DayCounter + { + public static readonly AFB_Impl Singleton = new AFB_Impl(); + private AFB_Impl() { } + + public override string name() { return "Actual/Actual (AFB)"; } + + public override int dayCount(Date d1, Date d2) { return (d2 - d1); } + + public override double yearFraction(Date d1, Date d2, Date refPeriodStart, Date refPeriodEnd) + { + if (d1 == d2) + return 0; + if (d1 > d2) + return -yearFraction(d2, d1, null, null); + + Date newD2 = d2, temp = d2; + double sum = 0; + while (temp > d1) + { + temp = newD2 - TimeUnit.Years; + if (temp.Day == 28 && temp.Month == 2 && Date.IsLeapYear(temp.Year)) + temp += 1; + if (temp >= d1) + { + sum += 1; + newD2 = temp; + } } - }; - - private class AFB_Impl : DayCounter - { - public static readonly AFB_Impl Singleton = new AFB_Impl(); - private AFB_Impl() { } - - public override string name() { return "Actual/Actual (AFB)"; } - public override int dayCount(Date d1, Date d2) { return (d2 - d1); } + double den = 365; - public override double yearFraction(Date d1, Date d2, Date refPeriodStart, Date refPeriodEnd) + if (Date.IsLeapYear(newD2.Year)) + { + temp = new Date(29, Month.February, newD2.Year); + if (newD2 > temp && d1 <= temp) + den += 1; + } + else if (Date.IsLeapYear(d1.Year)) { - if (d1 == d2) return 0; - if (d1 > d2) return -yearFraction(d2, d1, null, null); - - Date newD2 = d2, temp = d2; - double sum = 0; - while (temp > d1) - { - temp = newD2 - TimeUnit.Years; - if (temp.Day == 28 && temp.Month == 2 && Date.IsLeapYear(temp.Year)) - temp += 1; - if (temp >= d1) - { - sum += 1; - newD2 = temp; - } - } - - double den = 365; - - if (Date.IsLeapYear(newD2.Year)) - { - temp = new Date(29, Month.February, newD2.Year); - if (newD2 > temp && d1 <= temp) - den += 1; - } - else if (Date.IsLeapYear(d1.Year)) - { - temp = new Date(29, Month.February, d1.Year); - if (newD2 > temp && d1 <= temp) - den += 1; - } - - return sum + Date.daysBetween( d1, newD2 ) / den; + temp = new Date(29, Month.February, d1.Year); + if (newD2 > temp && d1 <= temp) + den += 1; } - }; - } + return sum + Date.daysBetween(d1, newD2) / den; + } + } + + } } \ No newline at end of file diff --git a/src/QLNet/Time/DayCounters/Business252.cs b/src/QLNet/Time/DayCounters/Business252.cs index 58baccc60..d10ae0cfd 100644 --- a/src/QLNet/Time/DayCounters/Business252.cs +++ b/src/QLNet/Time/DayCounters/Business252.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/Time/DayCounters/OneDayCounter.cs b/src/QLNet/Time/DayCounters/OneDayCounter.cs index 895496799..3111818eb 100644 --- a/src/QLNet/Time/DayCounters/OneDayCounter.cs +++ b/src/QLNet/Time/DayCounters/OneDayCounter.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,27 +19,27 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! 1/1 day count convention - public class OneDayCounter : DayCounter - { - public OneDayCounter() : base(Impl.Singleton) { } - - class Impl : DayCounter - { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "1/1"; } - public override int dayCount(Date d1, Date d2) - { - // the sign is all we need - return (d2 >= d1 ? 1 : -1); - } - - public override double yearFraction(Date d1, Date d2, Date refPeriodStart, Date refPeriodEnd) - { - return dayCount(d1, d2); - } - } - } + //! 1/1 day count convention + public class OneDayCounter : DayCounter + { + public OneDayCounter() : base(Impl.Singleton) { } + + class Impl : DayCounter + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "1/1"; } + public override int dayCount(Date d1, Date d2) + { + // the sign is all we need + return (d2 >= d1 ? 1 : -1); + } + + public override double yearFraction(Date d1, Date d2, Date refPeriodStart, Date refPeriodEnd) + { + return dayCount(d1, d2); + } + } + } } \ No newline at end of file diff --git a/src/QLNet/Time/DayCounters/SimpleDayCounter.cs b/src/QLNet/Time/DayCounters/SimpleDayCounter.cs index 31b292220..cdd0a596c 100644 --- a/src/QLNet/Time/DayCounters/SimpleDayCounter.cs +++ b/src/QLNet/Time/DayCounters/SimpleDayCounter.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,37 +19,37 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! Simple day counter for reproducing theoretical calculations. - /*! This day counter tries to ensure that whole-month distances are returned as a simple fraction, i.e., 1 year = 1.0, 6 months = 0.5, 3 months = 0.25 and so forth. - this day counter should be used together with NullCalendar, which ensures that dates at whole-month distances share the same day of month. It is not guaranteed to work with any other calendar. */ - public class SimpleDayCounter : DayCounter - { - public SimpleDayCounter() : base(Impl.Singleton) { } - - class Impl : DayCounter - { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Simple"; } - public override int dayCount(Date d1, Date d2) { return Thirty360.US_Impl.Singleton.dayCount(d1, d2); } - public override double yearFraction(Date d1, Date d2, Date d3, Date d4) + //! Simple day counter for reproducing theoretical calculations. + /*! This day counter tries to ensure that whole-month distances are returned as a simple fraction, i.e., 1 year = 1.0, 6 months = 0.5, 3 months = 0.25 and so forth. + this day counter should be used together with NullCalendar, which ensures that dates at whole-month distances share the same day of month. It is not guaranteed to work with any other calendar. */ + public class SimpleDayCounter : DayCounter + { + public SimpleDayCounter() : base(Impl.Singleton) { } + + class Impl : DayCounter + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Simple"; } + public override int dayCount(Date d1, Date d2) { return Thirty360.US_Impl.Singleton.dayCount(d1, d2); } + public override double yearFraction(Date d1, Date d2, Date d3, Date d4) + { + int dm1 = d1.Day, + dm2 = d2.Day; + + if (dm1 == dm2 || + // e.g., Aug 30 -> Feb 28 ? + (dm1 > dm2 && Date.isEndOfMonth(d2)) || + // e.g., Feb 28 -> Aug 30 ? + (dm1 < dm2 && Date.isEndOfMonth(d1))) { - int dm1 = d1.Day, - dm2 = d2.Day; - - if (dm1 == dm2 || - // e.g., Aug 30 -> Feb 28 ? - (dm1 > dm2 && Date.isEndOfMonth(d2)) || - // e.g., Feb 28 -> Aug 30 ? - (dm1 < dm2 && Date.isEndOfMonth(d1))) - { - - return (d2.Year - d1.Year) + (d2.Month - d1.Month) / 12.0; - } - else - return Thirty360.US_Impl.Singleton.yearFraction(d1, d2, d3, d4); + + return (d2.Year - d1.Year) + (d2.Month - d1.Month) / 12.0; } - } - } + else + return Thirty360.US_Impl.Singleton.yearFraction(d1, d2, d3, d4); + } + } + } } \ No newline at end of file diff --git a/src/QLNet/Time/DayCounters/Thirty360.cs b/src/QLNet/Time/DayCounters/Thirty360.cs index 7b3060b43..c75b271e7 100644 --- a/src/QLNet/Time/DayCounters/Thirty360.cs +++ b/src/QLNet/Time/DayCounters/Thirty360.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,99 +20,105 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! 30/360 day count convention - /*! The 30/360 day count can be calculated according to US, European, or Italian conventions. - US (NASD) convention: if the starting date is the 31st of a month, it becomes equal to the 30th of the same month. If the ending date is the 31st of a month and the starting - date is earlier than the 30th of a month, the ending date becomes equal to the 1st of the next month, otherwise the ending date becomes equal to the 30th of the same month. - Also known as "30/360", "360/360", or "Bond Basis" - - European convention: starting dates or ending dates that occur on the 31st of a month become equal to the 30th of the same month. Also known as "30E/360", or "Eurobond Basis" - - Italian convention: starting dates or ending dates that occur on February and are grater than 27 become equal to 30 for computational sake. */ - - public class Thirty360 : DayCounter - { - - public enum Thirty360Convention { USA, BondBasis, European, EurobondBasis, Italian }; - - public Thirty360() : base(US_Impl.Singleton) { } - public Thirty360(Thirty360Convention c) : base(conventions(c)) { } - - private static DayCounter conventions(Thirty360Convention c) - { - switch (c) + //! 30/360 day count convention + /*! The 30/360 day count can be calculated according to US, European, or Italian conventions. + US (NASD) convention: if the starting date is the 31st of a month, it becomes equal to the 30th of the same month. If the ending date is the 31st of a month and the starting + date is earlier than the 30th of a month, the ending date becomes equal to the 1st of the next month, otherwise the ending date becomes equal to the 30th of the same month. + Also known as "30/360", "360/360", or "Bond Basis" + + European convention: starting dates or ending dates that occur on the 31st of a month become equal to the 30th of the same month. Also known as "30E/360", or "Eurobond Basis" + + Italian convention: starting dates or ending dates that occur on February and are grater than 27 become equal to 30 for computational sake. */ + + public class Thirty360 : DayCounter + { + + public enum Thirty360Convention { USA, BondBasis, European, EurobondBasis, Italian } + + public Thirty360() : base(US_Impl.Singleton) { } + public Thirty360(Thirty360Convention c) : base(conventions(c)) { } + + private static DayCounter conventions(Thirty360Convention c) + { + switch (c) + { + case Thirty360Convention.USA: + case Thirty360Convention.BondBasis: + return US_Impl.Singleton; + case Thirty360Convention.European: + case Thirty360Convention.EurobondBasis: + return EU_Impl.Singleton; + case Thirty360Convention.Italian: + return IT_Impl.Singleton; + default: + throw new ArgumentException("Unknown 30/360 convention: " + c); + } + } + + public class US_Impl : DayCounter + { + public static readonly US_Impl Singleton = new US_Impl(); + private US_Impl() { } + + public override string name() { return "30/360 (Bond Basis)"; } + public override int dayCount(Date d1, Date d2) + { + int dd1 = d1.Day, dd2 = d2.Day; + int mm1 = d1.Month, mm2 = d2.Month; + int yy1 = d1.Year, yy2 = d2.Year; + + if (dd2 == 31 && dd1 < 30) { - case Thirty360Convention.USA: - case Thirty360Convention.BondBasis: - return US_Impl.Singleton; - case Thirty360Convention.European: - case Thirty360Convention.EurobondBasis: - return EU_Impl.Singleton; - case Thirty360Convention.Italian: - return IT_Impl.Singleton; - default: - throw new ArgumentException("Unknown 30/360 convention: " + c); + dd2 = 1; + mm2++; } - } - public class US_Impl : DayCounter - { - public static readonly US_Impl Singleton = new US_Impl(); - private US_Impl() { } + return 360 * (yy2 - yy1) + 30 * (mm2 - mm1 - 1) + System.Math.Max(0, 30 - dd1) + System.Math.Min(30, dd2); + } - public override string name() { return "30/360 (Bond Basis)"; } - public override int dayCount(Date d1, Date d2) - { - int dd1 = d1.Day, dd2 = d2.Day; - int mm1 = d1.Month, mm2 = d2.Month; - int yy1 = d1.Year, yy2 = d2.Year; + public override double yearFraction(Date d1, Date d2, Date d3, Date d4) { return dayCount(d1, d2) / 360.0; } + } - if (dd2 == 31 && dd1 < 30) { dd2 = 1; mm2++; } + private class EU_Impl : DayCounter + { + public static readonly EU_Impl Singleton = new EU_Impl(); + private EU_Impl() { } - return 360 * (yy2 - yy1) + 30 * (mm2 - mm1 - 1) + System.Math.Max(0, 30 - dd1) + System.Math.Min(30, dd2); - } + public override string name() { return "30E/360 (Eurobond Basis)"; } + public override int dayCount(Date d1, Date d2) + { + int dd1 = d1.Day, dd2 = d2.Day; + int mm1 = d1.Month, mm2 = d2.Month; + int yy1 = d1.Year, yy2 = d2.Year; - public override double yearFraction(Date d1, Date d2, Date d3, Date d4) { return dayCount(d1, d2) / 360.0; } - }; + return 360 * (yy2 - yy1) + 30 * (mm2 - mm1 - 1) + System.Math.Max(0, 30 - dd1) + System.Math.Min(30, dd2); + } - private class EU_Impl : DayCounter - { - public static readonly EU_Impl Singleton = new EU_Impl(); - private EU_Impl() { } + public override double yearFraction(Date d1, Date d2, Date d3, Date d4) { return dayCount(d1, d2) / 360.0; } + } - public override string name() { return "30E/360 (Eurobond Basis)"; } - public override int dayCount(Date d1, Date d2) - { - int dd1 = d1.Day, dd2 = d2.Day; - int mm1 = d1.Month, mm2 = d2.Month; - int yy1 = d1.Year, yy2 = d2.Year; - - return 360 * (yy2 - yy1) + 30 * (mm2 - mm1 - 1) + System.Math.Max(0, 30 - dd1) + System.Math.Min(30, dd2); - } + private class IT_Impl : DayCounter + { + public static readonly IT_Impl Singleton = new IT_Impl(); + private IT_Impl() { } - public override double yearFraction(Date d1, Date d2, Date d3, Date d4) { return dayCount(d1, d2) / 360.0; } - }; + public override string name() { return "30/360 (Italian)"; } + public override int dayCount(Date d1, Date d2) + { + int dd1 = d1.Day, dd2 = d2.Day; + int mm1 = d1.Month, mm2 = d2.Month; + int yy1 = d1.Year, yy2 = d2.Year; - private class IT_Impl : DayCounter - { - public static readonly IT_Impl Singleton = new IT_Impl(); - private IT_Impl() { } + if (mm1 == 2 && dd1 > 27) + dd1 = 30; + if (mm2 == 2 && dd2 > 27) + dd2 = 30; - public override string name() { return "30/360 (Italian)"; } - public override int dayCount(Date d1, Date d2) - { - int dd1 = d1.Day, dd2 = d2.Day; - int mm1 = d1.Month, mm2 = d2.Month; - int yy1 = d1.Year, yy2 = d2.Year; - - if (mm1 == 2 && dd1 > 27) dd1 = 30; - if (mm2 == 2 && dd2 > 27) dd2 = 30; - - return 360 * (yy2 - yy1) + 30 * (mm2 - mm1 - 1) + System.Math.Max(0, 30 - dd1) + System.Math.Min(30, dd2); - } + return 360 * (yy2 - yy1) + 30 * (mm2 - mm1 - 1) + System.Math.Max(0, 30 - dd1) + System.Math.Min(30, dd2); + } - public override double yearFraction(Date d1, Date d2, Date d3, Date d4) { return dayCount(d1, d2) / 360.0; } - }; + public override double yearFraction(Date d1, Date d2, Date d3, Date d4) { return dayCount(d1, d2) / 360.0; } + } - } + } } \ No newline at end of file diff --git a/src/QLNet/Time/ECB.cs b/src/QLNet/Time/ECB.cs index 532a49f90..7571c6fb2 100644 --- a/src/QLNet/Time/ECB.cs +++ b/src/QLNet/Time/ECB.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,15 +23,15 @@ under the terms of the QLNet license. You should have received a namespace QLNet { //! European Central Bank reserve maintenance dates - public struct ECB + public struct ECB { static List knownDateSet = new List(); public static List knownDates() { // one-off inizialization - int[] knownDatesArray = + int[] knownDatesArray = { - 38371, 38391, 38420, 38455, 38483, 38511, 38546, 38574, 38602, 38637, 38665, 38692 // 2005 + 38371, 38391, 38420, 38455, 38483, 38511, 38546, 38574, 38602, 38637, 38665, 38692 // 2005 , 38735, 38756, 38784, 38819, 38847, 38883, 38910, 38938, 38966, 39001, 39029, 39064 // 2006 , 39099, 39127, 39155, 39190, 39217, 39246, 39274, 39302, 39337, 39365, 39400, 39428 // 2007 , 39463, 39491, 39519, 39554, 39582, 39610, 39638, 39673, 39701, 39729, 39764, 39792 // 2008 @@ -47,36 +47,36 @@ public static List knownDates() , 42032, 42074, 42116, 42165, 42207, 42256, 42305, 42347// 2015 // https://www.ecb.europa.eu/press/pr/date/2015/html/pr150622.en.html , 42396, 42445, 42487, 42529, 42578, 42627, 42669, 42718 // 2016 - , 42760 , /*source ICAP */ 42802, 42844, 42893, 42942 // 2017 + , 42760, /*source ICAP */ 42802, 42844, 42893, 42942 // 2017 }; - - if (knownDateSet.empty()) + + if (knownDateSet.empty()) { - for ( int i = 0; i < knownDatesArray.Length; ++i ) + for (int i = 0; i < knownDatesArray.Length; ++i) { - knownDateSet.Add(new Date(knownDatesArray[i])); + knownDateSet.Add(new Date(knownDatesArray[i])); } - } + } - return knownDateSet; + return knownDateSet; } - public static void addDate( Date d ) + public static void addDate(Date d) { knownDates(); // just to ensure inizialization - knownDateSet.Add( d ); + knownDateSet.Add(d); knownDateSet.Sort(); } - public static void removeDate( Date d ) + public static void removeDate(Date d) { knownDates(); // just to ensure inizialization - knownDateSet.Remove( d ); + knownDateSet.Remove(d); } //! maintenance period start date in the given month/year - public static Date date( Month m, int y ) { return nextDate( new Date( 1, m, y ) - 1 ); } + public static Date date(Month m, int y) { return nextDate(new Date(1, m, y) - 1); } /*! returns the ECB date for the given ECB code (e.g. March xxth, 2013 for MAR10). @@ -84,36 +84,49 @@ public static void removeDate( Date d ) \warning It raises an exception if the input string is not an ECB code */ - public static Date date( string ecbCode, Date refDate = null ) + public static Date date(string ecbCode, Date refDate = null) { - Utils.QL_REQUIRE(isECBcode(ecbCode),() => ecbCode + " is not a valid ECB code"); + Utils.QL_REQUIRE(isECBcode(ecbCode), () => ecbCode + " is not a valid ECB code"); string code = ecbCode.ToUpper(); string monthString = code.Substring(0, 3); Month m = Month.Jan; - if (monthString=="JAN") m = Month.January; - else if (monthString=="FEB") m = Month.February; - else if (monthString=="MAR") m = Month.March; - else if (monthString=="APR") m = Month.April; - else if (monthString=="MAY") m = Month.May; - else if (monthString=="JUN") m = Month.June; - else if (monthString=="JUL") m = Month.July; - else if (monthString=="AUG") m = Month.August; - else if (monthString=="SEP") m = Month.September; - else if (monthString=="OCT") m = Month.October; - else if (monthString=="NOV") m = Month.November; - else if (monthString=="DEC") m = Month.December; - else Utils.QL_FAIL("not an ECB month (and it should have been)"); - - // lexical_cast causes compilation errors with x64 - int y = int.Parse(code.Substring(3, 2)); - Date referenceDate = (refDate ?? new Date(Settings.evaluationDate())); - int referenceYear = (referenceDate.year() % 100); - y += referenceDate.year() - referenceYear; - if (y ecbDate + " is not a valid ECB date"); + Utils.QL_REQUIRE(isECBdate(ecbDate), () => ecbDate + " is not a valid ECB date"); - string ECBcode = string.Empty; - int y = ecbDate.year() % 100; - string padding = string.Empty; - if (y < 10) + string ECBcode = string.Empty; + int y = ecbDate.year() % 100; + string padding = string.Empty; + if (y < 10) padding = "0"; - switch(ecbDate.month()) { - case (int)Month.January: - ECBcode += "JAN" + padding + y; - break; - case (int)Month.February: - ECBcode += "FEB" + padding + y; - break; - case (int)Month.March: - ECBcode += "MAR" + padding + y; - break; - case (int)Month.April: - ECBcode += "APR" + padding + y; - break; - case (int)Month.May: - ECBcode += "MAY" + padding + y; - break; - case (int)Month.June: - ECBcode += "JUN" + padding + y; - break; - case (int)Month.July: - ECBcode += "JUL" + padding + y; - break; - case (int)Month.August: - ECBcode += "AUG" + padding + y; - break; - case (int)Month.September: - ECBcode += "SEP" + padding + y; - break; - case (int)Month.October: - ECBcode += "OCT" + padding + y; - break; - case (int)Month.November: - ECBcode += "NOV" + padding + y; - break; - case (int)Month.December: - ECBcode += "DEC" + padding + y; - break; - default: - Utils.QL_FAIL("not an ECB month (and it should have been)"); - break; - } - - #if(QL_EXTRA_SAFETY_CHECKS) - QL_ENSURE(isECBcode(ECBcode.str()), - "the result " << ECBcode.str() << - " is an invalid ECB code"); - #endif - return ECBcode; + switch (ecbDate.month()) + { + case (int)Month.January: + ECBcode += "JAN" + padding + y; + break; + case (int)Month.February: + ECBcode += "FEB" + padding + y; + break; + case (int)Month.March: + ECBcode += "MAR" + padding + y; + break; + case (int)Month.April: + ECBcode += "APR" + padding + y; + break; + case (int)Month.May: + ECBcode += "MAY" + padding + y; + break; + case (int)Month.June: + ECBcode += "JUN" + padding + y; + break; + case (int)Month.July: + ECBcode += "JUL" + padding + y; + break; + case (int)Month.August: + ECBcode += "AUG" + padding + y; + break; + case (int)Month.September: + ECBcode += "SEP" + padding + y; + break; + case (int)Month.October: + ECBcode += "OCT" + padding + y; + break; + case (int)Month.November: + ECBcode += "NOV" + padding + y; + break; + case (int)Month.December: + ECBcode += "DEC" + padding + y; + break; + default: + Utils.QL_FAIL("not an ECB month (and it should have been)"); + break; + } + +#if(QL_EXTRA_SAFETY_CHECKS) + QL_ENSURE(isECBcode(ECBcode.str()), + "the result " << ECBcode.str() << + " is an invalid ECB code"); +#endif + return ECBcode; } //! next maintenance period start date following the given date - public static Date nextDate( Date date = null ) + public static Date nextDate(Date date = null) { Date d = (date ?? Settings.evaluationDate()); - int i = knownDates().FindIndex( x => x > d ); + int i = knownDates().FindIndex(x => x > d); - Utils.QL_REQUIRE(i!=-1,() => - "ECB dates after " + knownDates().Last() + " are unknown"); - return knownDates()[i]; + Utils.QL_REQUIRE(i != -1, () => + "ECB dates after " + knownDates().Last() + " are unknown"); + return knownDates()[i]; } //! next maintenance period start date following the given ECB code - public static Date nextDate( string ecbCode, Date referenceDate = null ) + public static Date nextDate(string ecbCode, Date referenceDate = null) { return nextDate(date(ecbCode, referenceDate)); } //! next maintenance period start dates following the given date - public static List nextDates( Date date = null ) + public static List nextDates(Date date = null) { Date d = (date ?? Settings.evaluationDate()); - int i = knownDates(). FindIndex(x => x > d ); + int i = knownDates(). FindIndex(x => x > d); + + Utils.QL_REQUIRE(i != -1, () => + "ECB dates after " + knownDates().Last() + " are unknown"); - Utils.QL_REQUIRE(i != -1 ,() => - "ECB dates after " + knownDates().Last() + " are unknown"); - - return new List(knownDates().GetRange(i, knownDates().Count - i )); + return new List(knownDates().GetRange(i, knownDates().Count - i)); } //! next maintenance period start dates following the given code - public static List nextDates( string ecbCode, Date referenceDate = null ) + public static List nextDates(string ecbCode, Date referenceDate = null) { return nextDates(date(ecbCode, referenceDate)); } /*! returns whether or not the given date is a maintenance period start date */ - public static bool isECBdate( Date d ) + public static bool isECBdate(Date d) { - Date date = nextDate(d-1); - return d==date; + Date date = nextDate(d - 1); + return d == date; } //! returns whether or not the given string is an ECB code - public static bool isECBcode( String ecbCode ) + public static bool isECBcode(String ecbCode) { if (ecbCode.Length != 5) return false; - String code = ecbCode.ToUpper(); + String code = ecbCode.ToUpper(); - String str1 = "0123456789"; - if ( !str1.Contains(code.Substring(3, 1))) + String str1 = "0123456789"; + if (!str1.Contains(code.Substring(3, 1))) return false; - if (!str1.Contains(code.Substring(4, 1))) + if (!str1.Contains(code.Substring(4, 1))) return false; - string monthString = code.Substring(0, 3); - if (monthString=="JAN") return true; - else if (monthString=="FEB") return true; - else if (monthString=="MAR") return true; - else if (monthString=="APR") return true; - else if (monthString=="MAY") return true; - else if (monthString=="JUN") return true; - else if (monthString=="JUL") return true; - else if (monthString=="AUG") return true; - else if (monthString=="SEP") return true; - else if (monthString=="OCT") return true; - else if (monthString=="NOV") return true; - else if (monthString=="DEC") return true; - else return false; + string monthString = code.Substring(0, 3); + if (monthString == "JAN") + return true; + else if (monthString == "FEB") + return true; + else if (monthString == "MAR") + return true; + else if (monthString == "APR") + return true; + else if (monthString == "MAY") + return true; + else if (monthString == "JUN") + return true; + else if (monthString == "JUL") + return true; + else if (monthString == "AUG") + return true; + else if (monthString == "SEP") + return true; + else if (monthString == "OCT") + return true; + else if (monthString == "NOV") + return true; + else if (monthString == "DEC") + return true; + else + return false; } //! next ECB code following the given date - public static string nextCode(Date d = null) { + public static string nextCode(Date d = null) + { return code(nextDate(d)); } //! next ECB code following the given code - public static string nextCode( String ecbCode ) + public static string nextCode(String ecbCode) { - Utils.QL_REQUIRE(isECBcode(ecbCode),() => - ecbCode + " is not a valid ECB code"); - - String code = ecbCode.ToUpper(); - String result = String.Empty; - - string monthString = code.Substring(0, 3); - if (monthString=="JAN") result += "FEB" + code.Substring(3, 2); - else if (monthString=="FEB") result += "MAR" + code.Substring(3, 2); - else if (monthString=="MAR") result += "APR" + code.Substring(3, 2); - else if (monthString=="APR") result += "MAY" + code.Substring(3, 2); - else if (monthString=="MAY") result += "JUN" + code.Substring(3, 2); - else if (monthString=="JUN") result += "JUL" + code.Substring(3, 2); - else if (monthString=="JUL") result += "AUG" + code.Substring(3, 2); - else if (monthString=="AUG") result += "SEP" + code.Substring(3, 2); - else if (monthString=="SEP") result += "OCT" + code.Substring(3, 2); - else if (monthString=="OCT") result += "NOV" + code.Substring(3, 2); - else if (monthString=="NOV") result += "DEC" + code.Substring(3, 2); - else if (monthString=="DEC") { + Utils.QL_REQUIRE(isECBcode(ecbCode), () => + ecbCode + " is not a valid ECB code"); + + String code = ecbCode.ToUpper(); + String result = String.Empty; + + string monthString = code.Substring(0, 3); + if (monthString == "JAN") + result += "FEB" + code.Substring(3, 2); + else if (monthString == "FEB") + result += "MAR" + code.Substring(3, 2); + else if (monthString == "MAR") + result += "APR" + code.Substring(3, 2); + else if (monthString == "APR") + result += "MAY" + code.Substring(3, 2); + else if (monthString == "MAY") + result += "JUN" + code.Substring(3, 2); + else if (monthString == "JUN") + result += "JUL" + code.Substring(3, 2); + else if (monthString == "JUL") + result += "AUG" + code.Substring(3, 2); + else if (monthString == "AUG") + result += "SEP" + code.Substring(3, 2); + else if (monthString == "SEP") + result += "OCT" + code.Substring(3, 2); + else if (monthString == "OCT") + result += "NOV" + code.Substring(3, 2); + else if (monthString == "NOV") + result += "DEC" + code.Substring(3, 2); + else if (monthString == "DEC") + { int y = (int.Parse(code.Substring(3, 2)) + 1) % 100; String padding = String.Empty; if (y < 10) - padding = "0"; + padding = "0"; result += "JAN" + padding + y; - } else Utils.QL_FAIL("not an ECB month (and it should have been)"); + } + else + Utils.QL_FAIL("not an ECB month (and it should have been)"); - #if QL_EXTRA_SAFETY_CHECKS - QL_ENSURE(isECBcode(result.str()), - "the result " << result.str() << - " is an invalid ECB code"); - #endif - return result; +#if QL_EXTRA_SAFETY_CHECKS + QL_ENSURE(isECBcode(result.str()), + "the result " << result.str() << + " is an invalid ECB code"); +#endif + return result; } - }; + } } diff --git a/src/QLNet/Time/Imm.cs b/src/QLNet/Time/Imm.cs index 9a9d0a9db..6e1af9db5 100644 --- a/src/QLNet/Time/Imm.cs +++ b/src/QLNet/Time/Imm.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,145 +19,167 @@ under the terms of the QLNet license. You should have received a using System; using System.Linq; -namespace QLNet { - //! Main cycle of the International %Money Market (a.k.a. %IMM) months - public struct IMM { - enum Month { - F = 1, G = 2, H = 3, - J = 4, K = 5, M = 6, - N = 7, Q = 8, U = 9, - V = 10, X = 11, Z = 12 - } - - //! returns whether or not the given date is an IMM date - public static bool isIMMdate(Date date) { return isIMMdate(date, true); } - public static bool isIMMdate(Date date, bool mainCycle) { - if (date.DayOfWeek != DayOfWeek.Wednesday) - return false; - - if (date.Day < 15 || date.Day > 21) - return false; - - if (!mainCycle) return true; - - switch ((QLNet.Month)date.Month) { - case QLNet.Month.March: - case QLNet.Month.June: - case QLNet.Month.September: - case QLNet.Month.December: - return true; - default: - return false; - } - } - - //! returns whether or not the given string is an IMM code - public static bool isIMMcode(string s) { return isIMMcode(s, true); } - public static bool isIMMcode(string s, bool mainCycle) { - if (s.Length != 2) - return false; - - string str1 = "0123456789"; - if (!str1.Contains(s[1].ToString())) - return false; - - if (mainCycle) str1 = "hmzuHMZU"; - else str1 = "fghjkmnquvxzFGHJKMNQUVXZ"; - if (!str1.Contains(s[0].ToString())) - return false; - +namespace QLNet +{ + //! Main cycle of the International %Money Market (a.k.a. %IMM) months + public struct IMM + { + enum Month + { + F = 1, G = 2, H = 3, + J = 4, K = 5, M = 6, + N = 7, Q = 8, U = 9, + V = 10, X = 11, Z = 12 + } + + //! returns whether or not the given date is an IMM date + public static bool isIMMdate(Date date) { return isIMMdate(date, true); } + public static bool isIMMdate(Date date, bool mainCycle) + { + if (date.DayOfWeek != DayOfWeek.Wednesday) + return false; + + if (date.Day < 15 || date.Day > 21) + return false; + + if (!mainCycle) return true; - } - - // returns the IMM code for the given date (e.g. H3 for March 20th, 2013). - public static string code(Date immDate) { - if (!isIMMdate(immDate, false)) throw new ArgumentException(immDate + " is not an IMM date"); - return "FGHJKMNQUVXZ"[immDate.Month-1] + (immDate.Year % 10).ToString(); - } - - // returns the IMM date for the given IMM code (e.g. March 20th, 2013 for H3). - public static Date date(string immCode) { return date(immCode, null); } - public static Date date(string immCode, Date refDate) { - if (!isIMMcode(immCode, false)) throw new ArgumentException(immCode + " is not a valid IMM code"); - - Date referenceDate = (refDate ?? Settings.evaluationDate()); - - int m = "FGHJKMNQUVXZ".IndexOf(immCode.ToUpper()[0]) + 1; - if (m == 0) - throw new ArgumentException("invalid IMM month letter"); - - if (!Char.IsDigit(immCode[1])) - throw new ArgumentException(immCode + " is not a valid IMM code"); - int y = immCode[1] - '0'; - - y += referenceDate.Year - (referenceDate.Year % 10); - - /* year<10 are not valid years: to avoid a run-time - exception in few lines below we need to add 10 years right away */ - if (y == 0 && referenceDate.Year <= 1909) y += 10; - - Date result = IMM.nextDate(new Date(1, m, y), false); - if (result 21) { - skipMonths += m; - if (skipMonths<=12) { - m = skipMonths; - } else { - m = skipMonths-12; - y += 1; - } - } - Date result = Date.nthWeekday(3, DayOfWeek.Wednesday, m, y); - if (result<=refDate) - result = nextDate(new Date(22, m, y), mainCycle); - return result; - } - - //! next IMM date following the given IMM code - /*! returns the 1st delivery date for next contract listed in the - International Money Market section of the Chicago Mercantile Exchange. */ - public static Date nextDate(string immCode) { return nextDate(immCode, true, null); } - public static Date nextDate(string immCode, bool mainCycle) { return nextDate(immCode, mainCycle, null); } - public static Date nextDate(string immCode, bool mainCycle, Date referenceDate) { - Date immDate = date(immCode, referenceDate); - return nextDate(immDate+1, mainCycle); - } - - /*! returns the IMM code for next contract listed in the - International Money Market section of the Chicago Mercantile Exchange.*/ - public static string nextCode() { return nextCode((Date)null, true); } - public static string nextCode(Date d) { return nextCode(d, true); } - public static string nextCode(Date d, bool mainCycle) { - Date date = nextDate(d, mainCycle); - return code(date); - } - - /*! returns the IMM code for next contract listed in the - International Money Market section of the Chicago Mercantile Exchange. */ - public static string nextCode(string immCode) { return nextCode(immCode, true, null); } - public static string nextCode(string immCode, bool mainCycle) { return nextCode(immCode, mainCycle, null); } - public static string nextCode(string immCode, bool mainCycle, Date referenceDate) { - Date date = nextDate(immCode, mainCycle, referenceDate); - return code(date); - } - } + switch ((QLNet.Month)date.Month) + { + case QLNet.Month.March: + case QLNet.Month.June: + case QLNet.Month.September: + case QLNet.Month.December: + return true; + default: + return false; + } + } + + //! returns whether or not the given string is an IMM code + public static bool isIMMcode(string s) { return isIMMcode(s, true); } + public static bool isIMMcode(string s, bool mainCycle) + { + if (s.Length != 2) + return false; + + string str1 = "0123456789"; + if (!str1.Contains(s[1].ToString())) + return false; + + if (mainCycle) + str1 = "hmzuHMZU"; + else + str1 = "fghjkmnquvxzFGHJKMNQUVXZ"; + if (!str1.Contains(s[0].ToString())) + return false; + + return true; + } + + // returns the IMM code for the given date (e.g. H3 for March 20th, 2013). + public static string code(Date immDate) + { + if (!isIMMdate(immDate, false)) + throw new ArgumentException(immDate + " is not an IMM date"); + return "FGHJKMNQUVXZ"[immDate.Month - 1] + (immDate.Year % 10).ToString(); + } + + // returns the IMM date for the given IMM code (e.g. March 20th, 2013 for H3). + public static Date date(string immCode) { return date(immCode, null); } + public static Date date(string immCode, Date refDate) + { + if (!isIMMcode(immCode, false)) + throw new ArgumentException(immCode + " is not a valid IMM code"); + + Date referenceDate = (refDate ?? Settings.evaluationDate()); + + int m = "FGHJKMNQUVXZ".IndexOf(immCode.ToUpper()[0]) + 1; + if (m == 0) + throw new ArgumentException("invalid IMM month letter"); + + if (!Char.IsDigit(immCode[1])) + throw new ArgumentException(immCode + " is not a valid IMM code"); + int y = immCode[1] - '0'; + + y += referenceDate.Year - (referenceDate.Year % 10); + + /* year<10 are not valid years: to avoid a run-time + exception in few lines below we need to add 10 years right away */ + if (y == 0 && referenceDate.Year <= 1909) + y += 10; + + Date result = IMM.nextDate(new Date(1, m, y), false); + if (result < referenceDate) + result = IMM.nextDate(new Date(1, m, y + 10), false); + + return result; + } + + //! next IMM date following the given date + /*! returns the 1st delivery date for next contract listed in the + International Money Market section of the Chicago Mercantile Exchange. */ + public static Date nextDate() { return nextDate((Date)null, true); } + public static Date nextDate(Date d) { return nextDate(d, true); } + public static Date nextDate(Date date, bool mainCycle) + { + Date refDate = (date ?? Settings.evaluationDate()); + + int y = refDate.Year; + int m = refDate.Month; + + int offset = mainCycle ? 3 : 1; + int skipMonths = offset - (m % offset); + if (skipMonths != offset || refDate.Day > 21) + { + skipMonths += m; + if (skipMonths <= 12) + { + m = skipMonths; + } + else + { + m = skipMonths - 12; + y += 1; + } + } + + Date result = Date.nthWeekday(3, DayOfWeek.Wednesday, m, y); + if (result <= refDate) + result = nextDate(new Date(22, m, y), mainCycle); + return result; + } + + //! next IMM date following the given IMM code + /*! returns the 1st delivery date for next contract listed in the + International Money Market section of the Chicago Mercantile Exchange. */ + public static Date nextDate(string immCode) { return nextDate(immCode, true, null); } + public static Date nextDate(string immCode, bool mainCycle) { return nextDate(immCode, mainCycle, null); } + public static Date nextDate(string immCode, bool mainCycle, Date referenceDate) + { + Date immDate = date(immCode, referenceDate); + return nextDate(immDate + 1, mainCycle); + } + + /*! returns the IMM code for next contract listed in the + International Money Market section of the Chicago Mercantile Exchange.*/ + public static string nextCode() { return nextCode((Date)null, true); } + public static string nextCode(Date d) { return nextCode(d, true); } + public static string nextCode(Date d, bool mainCycle) + { + Date date = nextDate(d, mainCycle); + return code(date); + } + + /*! returns the IMM code for next contract listed in the + International Money Market section of the Chicago Mercantile Exchange. */ + public static string nextCode(string immCode) { return nextCode(immCode, true, null); } + public static string nextCode(string immCode, bool mainCycle) { return nextCode(immCode, mainCycle, null); } + public static string nextCode(string immCode, bool mainCycle, Date referenceDate) + { + Date date = nextDate(immCode, mainCycle, referenceDate); + return code(date); + } + } } diff --git a/src/QLNet/Time/Period.cs b/src/QLNet/Time/Period.cs index 7b12f8de7..6866ac712 100644 --- a/src/QLNet/Time/Period.cs +++ b/src/QLNet/Time/Period.cs @@ -1,359 +1,386 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - public class Period : IComparable { - private int length_; - private TimeUnit unit_; +namespace QLNet +{ + public class Period : IComparable + { + private int length_; + private TimeUnit unit_; - // properties - public int length() { return length_; } - public TimeUnit units() { return unit_; } + // properties + public int length() { return length_; } + public TimeUnit units() { return unit_; } - public Period() { length_ = 0; unit_ = TimeUnit.Days; } - public Period(int n, TimeUnit u) { length_ = n; unit_ = u; } - public Period(Frequency f) { - switch (f) { - case Frequency.NoFrequency: - unit_ = TimeUnit.Days; // same as Period() - length_ = 0; - break; - case Frequency.Once: - unit_ = TimeUnit.Years; - length_ = 0; - break; - case Frequency.Annual: - unit_ = TimeUnit.Years; - length_ = 1; - break; - case Frequency.Semiannual: - case Frequency.EveryFourthMonth: - case Frequency.Quarterly: - case Frequency.Bimonthly: - case Frequency.Monthly: - unit_ = TimeUnit.Months; - length_ = 12 / (int)f; - break; - case Frequency.EveryFourthWeek: - case Frequency.Biweekly: - case Frequency.Weekly: - unit_ = TimeUnit.Weeks; - length_ = 52 / (int)f; - break; - case Frequency.Daily: - unit_ = TimeUnit.Days; - length_ = 1; - break; - case Frequency.OtherFrequency: - Utils.QL_FAIL("unknown frequency"); - break; - default: - Utils.QL_FAIL("unknown frequency (" + f + ")"); - break; - } - } + public Period() { length_ = 0; unit_ = TimeUnit.Days; } + public Period(int n, TimeUnit u) { length_ = n; unit_ = u; } + public Period(Frequency f) + { + switch (f) + { + case Frequency.NoFrequency: + unit_ = TimeUnit.Days; // same as Period() + length_ = 0; + break; + case Frequency.Once: + unit_ = TimeUnit.Years; + length_ = 0; + break; + case Frequency.Annual: + unit_ = TimeUnit.Years; + length_ = 1; + break; + case Frequency.Semiannual: + case Frequency.EveryFourthMonth: + case Frequency.Quarterly: + case Frequency.Bimonthly: + case Frequency.Monthly: + unit_ = TimeUnit.Months; + length_ = 12 / (int)f; + break; + case Frequency.EveryFourthWeek: + case Frequency.Biweekly: + case Frequency.Weekly: + unit_ = TimeUnit.Weeks; + length_ = 52 / (int)f; + break; + case Frequency.Daily: + unit_ = TimeUnit.Days; + length_ = 1; + break; + case Frequency.OtherFrequency: + Utils.QL_FAIL("unknown frequency"); + break; + default: + Utils.QL_FAIL("unknown frequency (" + f + ")"); + break; + } + } + + // Create from a string like "1M", "2Y"... + public Period(string periodString) + { + periodString = periodString.ToUpper(); + length_ = int.Parse(periodString.Substring(0, periodString.Length - 1)); + string freq = periodString.Substring(periodString.Length - 1, 1); + switch (freq) + { + case "D": + unit_ = TimeUnit.Days; + break; + case "W": + unit_ = TimeUnit.Weeks; + break; + case "M": + unit_ = TimeUnit.Months; + break; + case "Y": + unit_ = TimeUnit.Years; + break; + default: + throw new ArgumentException("Unknown TimeUnit: " + freq); + } + } - // Create from a string like "1M", "2Y"... - public Period(string periodString) - { - periodString = periodString.ToUpper(); - length_ = int.Parse(periodString.Substring(0, periodString.Length - 1)); - string freq = periodString.Substring(periodString.Length - 1, 1); - switch (freq) - { - case "D": - unit_ = TimeUnit.Days; - break; - case "W": - unit_ = TimeUnit.Weeks; - break; - case "M": - unit_ = TimeUnit.Months; - break; - case "Y": - unit_ = TimeUnit.Years; - break; - default: - throw new ArgumentException("Unknown TimeUnit: " + freq); - } - } + public Frequency frequency() + { + int length = System.Math.Abs(length_); // unsigned version - public Frequency frequency() { - int length = System.Math.Abs(length_); // unsigned version + if (length == 0) + { + if (unit_ == TimeUnit.Years) + return Frequency.Once; + return Frequency.NoFrequency; + } + switch (unit_) + { + case TimeUnit.Years: + return (length == 1) ? Frequency.Annual : Frequency.OtherFrequency; + case TimeUnit.Months: + if (12 % length == 0 && length <= 12) + return (Frequency)(12 / length); + else + return Frequency.OtherFrequency; + case TimeUnit.Weeks: + if (length == 1) + return Frequency.Weekly; + else if (length == 2) + return Frequency.Biweekly; + else if (length == 4) + return Frequency.EveryFourthWeek; + else + return Frequency.OtherFrequency; + case TimeUnit.Days: + return (length == 1) ? Frequency.Daily : Frequency.OtherFrequency; + default: + throw new ArgumentException("Unknown TimeUnit: " + unit_); + } + } - if (length == 0) + public void normalize() + { + if (length_ != 0) + switch (unit_) { - if (unit_ == TimeUnit.Years) return Frequency.Once; - return Frequency.NoFrequency; - } - switch (unit_) { - case TimeUnit.Years: - return (length == 1) ? Frequency.Annual : Frequency.OtherFrequency; - case TimeUnit.Months: - if (12 % length == 0 && length <= 12) - return (Frequency)(12 / length); - else - return Frequency.OtherFrequency; - case TimeUnit.Weeks: - if (length == 1) - return Frequency.Weekly; - else if (length == 2) - return Frequency.Biweekly; - else if (length == 4) - return Frequency.EveryFourthWeek; - else - return Frequency.OtherFrequency; - case TimeUnit.Days: - return (length == 1) ? Frequency.Daily : Frequency.OtherFrequency; - default: - throw new ArgumentException("Unknown TimeUnit: " + unit_); + case TimeUnit.Days: + if ((length_ % 7) == 0) + { + length_ /= 7; + unit_ = TimeUnit.Weeks; + } + break; + case TimeUnit.Months: + if ((length_ % 12) == 0) + { + length_ /= 12; + unit_ = TimeUnit.Years; + } + break; + case TimeUnit.Weeks: + case TimeUnit.Years: + break; + default: + throw new ArgumentException("Unknown TimeUnit: " + unit_); } - } + } - public void normalize() { - if (length_ != 0) - switch (unit_) { - case TimeUnit.Days: - if ((length_ % 7) == 0) { - length_ /= 7; - unit_ = TimeUnit.Weeks; - } + public static Period operator+(Period p1, Period p2) + { + int length_ = p1.length(); + TimeUnit units_ = p1.units(); + + if (length_ == 0) + { + length_ = p2.length(); + units_ = p2.units(); + } + else if (units_ == p2.units()) + { + // no conversion needed + length_ += p2.length(); + } + else + { + switch (units_) + { + case TimeUnit.Years: + switch (p2.units()) + { + case TimeUnit.Months: + units_ = TimeUnit.Months; + length_ = length_ * 12 + p2.length(); break; - case TimeUnit.Months: - if ((length_ % 12) == 0) { - length_ /= 12; - unit_ = TimeUnit.Years; - } + case TimeUnit.Weeks: + case TimeUnit.Days: + Utils.QL_REQUIRE(p1.length() == 0, () => "impossible addition between " + p1 + " and " + p2); break; - case TimeUnit.Weeks: - case TimeUnit.Years: + default: + Utils.QL_FAIL("unknown time unit (" + p2.units() + ")"); break; - default: - throw new ArgumentException("Unknown TimeUnit: " + unit_); - } - } - - public static Period operator+(Period p1,Period p2) - { - int length_ = p1.length(); - TimeUnit units_ = p1.units(); - - if (length_==0) - { - length_ = p2.length(); - units_ = p2.units(); - } - else if (units_== p2.units()) - { - // no conversion needed - length_ += p2.length(); - } - else - { - switch (units_) - { - case TimeUnit.Years: - switch (p2.units()) - { - case TimeUnit.Months: - units_ = TimeUnit.Months; - length_ = length_*12 + p2.length(); - break; - case TimeUnit.Weeks: - case TimeUnit.Days: - Utils.QL_REQUIRE( p1.length() == 0 ,()=> "impossible addition between " + p1 + " and " + p2); - break; - default: - Utils.QL_FAIL("unknown time unit (" + p2.units() + ")"); - break; - } - break; + } + break; - case TimeUnit.Months: - switch (p2.units()) - { - case TimeUnit.Years: - length_ += p2.length()*12; - break; - case TimeUnit.Weeks: - case TimeUnit.Days: - Utils.QL_REQUIRE(p1.length() == 0,()=> "impossible addition between " + p1 + " and " + p2); - break; - default: - Utils.QL_FAIL("unknown time unit (" + p2.units() + ")"); - break; - } - break; + case TimeUnit.Months: + switch (p2.units()) + { + case TimeUnit.Years: + length_ += p2.length() * 12; + break; + case TimeUnit.Weeks: + case TimeUnit.Days: + Utils.QL_REQUIRE(p1.length() == 0, () => "impossible addition between " + p1 + " and " + p2); + break; + default: + Utils.QL_FAIL("unknown time unit (" + p2.units() + ")"); + break; + } + break; - case TimeUnit.Weeks: - switch (p2.units()) - { - case TimeUnit.Days: - units_ = TimeUnit.Days; - length_ = length_*7 + p2.length(); - break; - case TimeUnit.Years: - case TimeUnit.Months: - Utils.QL_REQUIRE(p1.length() == 0,()=> "impossible addition between " + p1 + " and " + p2); - break; - default: - Utils.QL_FAIL("unknown time unit (" + p2.units() + ")"); - break; - } - break; + case TimeUnit.Weeks: + switch (p2.units()) + { + case TimeUnit.Days: + units_ = TimeUnit.Days; + length_ = length_ * 7 + p2.length(); + break; + case TimeUnit.Years: + case TimeUnit.Months: + Utils.QL_REQUIRE(p1.length() == 0, () => "impossible addition between " + p1 + " and " + p2); + break; + default: + Utils.QL_FAIL("unknown time unit (" + p2.units() + ")"); + break; + } + break; - case TimeUnit.Days: - switch (p2.units()) - { - case TimeUnit.Weeks: - length_ += p2.length()*7; - break; - case TimeUnit.Years: - case TimeUnit.Months: - Utils.QL_REQUIRE(p1.length() == 0,()=> "impossible addition between " + p1 + " and " + p2); - break; - default: - Utils.QL_FAIL("unknown time unit (" + p2.units() + ")"); - break; - } - break; + case TimeUnit.Days: + switch (p2.units()) + { + case TimeUnit.Weeks: + length_ += p2.length() * 7; + break; + case TimeUnit.Years: + case TimeUnit.Months: + Utils.QL_REQUIRE(p1.length() == 0, () => "impossible addition between " + p1 + " and " + p2); + break; + default: + Utils.QL_FAIL("unknown time unit (" + p2.units() + ")"); + break; + } + break; - default: - Utils.QL_FAIL("unknown time unit (" + units_ + ")"); - break; - } - } - return new Period(length_,units_); - } - public static Period operator -(Period p1, Period p2) - { - return p1 +(-p2); - } + default: + Utils.QL_FAIL("unknown time unit (" + units_ + ")"); + break; + } + } + return new Period(length_, units_); + } + public static Period operator -(Period p1, Period p2) + { + return p1 + (-p2); + } - public static Period operator -(Period p) { return new Period(-p.length(), p.units()); } - public static Period operator *(int n, Period p) { return new Period(n * p.length(), p.units()); } - public static Period operator *(Period p, int n) { return new Period(n * p.length(), p.units()); } + public static Period operator -(Period p) { return new Period(-p.length(), p.units()); } + public static Period operator *(int n, Period p) { return new Period(n * p.length(), p.units()); } + public static Period operator *(Period p, int n) { return new Period(n * p.length(), p.units()); } - public static bool operator ==(Period p1, Period p2) - { - if ((object) p1 == null && (object) p2 == null) - return true; + public static bool operator ==(Period p1, Period p2) + { + if ((object) p1 == null && (object) p2 == null) + return true; - if ((object) p1 == null || (object) p2 == null) - return false; + if ((object) p1 == null || (object) p2 == null) + return false; - return !(p1 < p2 || p2 < p1); - } - public static bool operator !=(Period p1, Period p2) { return !(p1 == p2); } - public static bool operator <=(Period p1, Period p2) { return !(p1 > p2); } - public static bool operator >=(Period p1, Period p2) { return !(p1 < p2); } - public static bool operator >(Period p1, Period p2) { return p2 < p1; } - public static bool operator <(Period p1, Period p2) { - // special cases - if (p1.length() == 0) return (p2.length() > 0); - if (p2.length() == 0) return (p1.length() < 0); + return !(p1 < p2 || p2 < p1); + } + public static bool operator !=(Period p1, Period p2) { return !(p1 == p2); } + public static bool operator <=(Period p1, Period p2) { return !(p1 > p2); } + public static bool operator >=(Period p1, Period p2) { return !(p1 < p2); } + public static bool operator >(Period p1, Period p2) { return p2 < p1; } + public static bool operator <(Period p1, Period p2) + { + // special cases + if (p1.length() == 0) + return (p2.length() > 0); + if (p2.length() == 0) + return (p1.length() < 0); - // exact comparisons - if (p1.units() == p2.units()) return p1.length() < p2.length(); - if (p1.units() == TimeUnit.Months && p2.units() == TimeUnit.Years) return p1.length() < 12 * p2.length(); - if (p1.units() == TimeUnit.Years && p2.units() == TimeUnit.Months) return 12 * p1.length() < p2.length(); - if (p1.units() == TimeUnit.Days && p2.units() == TimeUnit.Weeks) return p1.length() < 7 * p2.length(); - if (p1.units() == TimeUnit.Weeks && p2.units() == TimeUnit.Days) return 7 * p1.length() < p2.length(); + // exact comparisons + if (p1.units() == p2.units()) + return p1.length() < p2.length(); + if (p1.units() == TimeUnit.Months && p2.units() == TimeUnit.Years) + return p1.length() < 12 * p2.length(); + if (p1.units() == TimeUnit.Years && p2.units() == TimeUnit.Months) + return 12 * p1.length() < p2.length(); + if (p1.units() == TimeUnit.Days && p2.units() == TimeUnit.Weeks) + return p1.length() < 7 * p2.length(); + if (p1.units() == TimeUnit.Weeks && p2.units() == TimeUnit.Days) + return 7 * p1.length() < p2.length(); - // inexact comparisons (handled by converting to days and using limits) - pair p1lim = new pair(p1), p2lim = new pair(p2); - if (p1lim.hi < p2lim.lo || p2lim.hi < p1lim.lo) - return p1lim.hi < p2lim.lo; - Utils.QL_FAIL("Undecidable comparison between " + p1.ToString() + " and " + p2.ToString()); - return false; - } + // inexact comparisons (handled by converting to days and using limits) + pair p1lim = new pair(p1), p2lim = new pair(p2); + if (p1lim.hi < p2lim.lo || p2lim.hi < p1lim.lo) + return p1lim.hi < p2lim.lo; + Utils.QL_FAIL("Undecidable comparison between " + p1.ToString() + " and " + p2.ToString()); + return false; + } - // required by operator < - struct pair { - public int lo, hi; - public pair(Period p) { - switch (p.units()) { - case TimeUnit.Days: - lo = hi = p.length(); break; - case TimeUnit.Weeks: - lo = hi = 7 * p.length(); break; - case TimeUnit.Months: - lo = 28 * p.length(); hi = 31 * p.length(); break; - case TimeUnit.Years: - lo = 365 * p.length(); hi = 366 * p.length(); break; - default: - Utils.QL_FAIL("Unknown TimeUnit: " + p.units()); - lo = hi = 0; - break; - } + // required by operator < + struct pair + { + public int lo, hi; + public pair(Period p) + { + switch (p.units()) + { + case TimeUnit.Days: + lo = hi = p.length(); break; + case TimeUnit.Weeks: + lo = hi = 7 * p.length(); break; + case TimeUnit.Months: + lo = 28 * p.length(); hi = 31 * p.length(); break; + case TimeUnit.Years: + lo = 365 * p.length(); hi = 366 * p.length(); break; + default: + Utils.QL_FAIL("Unknown TimeUnit: " + p.units()); + lo = hi = 0; + break; } - } + } + } - public override bool Equals(object o) { return this == (Period)o; } - public override int GetHashCode() { return 0; } - public override string ToString() { - return "TimeUnit: " + unit_.ToString() + ", length: " + length_.ToString(); - } - public string ToShortString() { - string result = ""; - int n = length(); - int m = 0; - switch (units()) { - case TimeUnit.Days: - if (n >= 7) { - m = n / 7; - result += m + "W"; - n = n % 7; - } - if (n != 0 || m == 0) - return result + n + "D"; - else - return result; - case TimeUnit.Weeks: - return result + n + "W"; - case TimeUnit.Months: - if (n >= 12) { - m = n / 12; - result += n / 12 + "Y"; - n = n % 12; - } - if (n != 0 || m == 0) - return result + n + "M"; - else - return result; - case TimeUnit.Years: - return result + n + "Y"; - default: - Utils.QL_FAIL("unknown time unit (" + units() + ")"); - return result; - } - } + public override bool Equals(object o) { return this == (Period)o; } + public override int GetHashCode() { return 0; } + public override string ToString() + { + return "TimeUnit: " + unit_.ToString() + ", length: " + length_.ToString(); + } + public string ToShortString() + { + string result = ""; + int n = length(); + int m = 0; + switch (units()) + { + case TimeUnit.Days: + if (n >= 7) + { + m = n / 7; + result += m + "W"; + n = n % 7; + } + if (n != 0 || m == 0) + return result + n + "D"; + else + return result; + case TimeUnit.Weeks: + return result + n + "W"; + case TimeUnit.Months: + if (n >= 12) + { + m = n / 12; + result += n / 12 + "Y"; + n = n % 12; + } + if (n != 0 || m == 0) + return result + n + "M"; + else + return result; + case TimeUnit.Years: + return result + n + "Y"; + default: + Utils.QL_FAIL("unknown time unit (" + units() + ")"); + return result; + } + } - public int CompareTo( object obj ) - { - if ( this < (Period)obj ) - return -1; - if ( this == (Period)obj ) - return 0; - return 1; - } - } + public int CompareTo(object obj) + { + if (this < (Period)obj) + return -1; + if (this == (Period)obj) + return 0; + return 1; + } + } } diff --git a/src/QLNet/Time/Schedule.cs b/src/QLNet/Time/Schedule.cs index 3c2719ff9..942cd4b01 100644 --- a/src/QLNet/Time/Schedule.cs +++ b/src/QLNet/Time/Schedule.cs @@ -8,7 +8,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -68,8 +68,8 @@ public Schedule(List dates, endOfMonth_ = (tenor != null && !allowsEndOfMonth(tenor)) ? false : endOfMonth; dates_ = dates; - Utils.QL_REQUIRE( isRegular_.Count == 0 || isRegular_.Count == dates.Count - 1,()=> - string.Format("isRegular size ({0}) must be zero or equal to the number of dates minus 1 ({1})", isRegular_.Count, dates.Count - 1)); + Utils.QL_REQUIRE(isRegular_.Count == 0 || isRegular_.Count == dates.Count - 1, () => + string.Format("isRegular size ({0}) must be zero or equal to the number of dates minus 1 ({1})", isRegular_.Count, dates.Count - 1)); } /// @@ -108,39 +108,44 @@ public Schedule(Date effectiveDate, endOfMonth_ = allowsEndOfMonth(tenor) && endOfMonth; // sanity checks - Utils.QL_REQUIRE( terminationDate != null, () => "null termination date" ); + Utils.QL_REQUIRE(terminationDate != null, () => "null termination date"); // in many cases (e.g. non-expired bonds) the effective date is not // really necessary. In these cases a decent placeholder is enough - if ( effectiveDate == null && firstDate == null && rule== DateGeneration.Rule.Backward) + if (effectiveDate == null && firstDate == null && rule == DateGeneration.Rule.Backward) { Date evalDate = Settings.evaluationDate(); - Utils.QL_REQUIRE( evalDate < terminationDate, () => "null effective date" ); + Utils.QL_REQUIRE(evalDate < terminationDate, () => "null effective date"); int y; if (nextToLastDate != null) { - y = (nextToLastDate - evalDate)/366 + 1; - effectiveDate = nextToLastDate - new Period(y,TimeUnit.Years); + y = (nextToLastDate - evalDate) / 366 + 1; + effectiveDate = nextToLastDate - new Period(y, TimeUnit.Years); } else { y = (terminationDate - evalDate) / 366 + 1; - effectiveDate = terminationDate - new Period(y , TimeUnit.Years); + effectiveDate = terminationDate - new Period(y, TimeUnit.Years); } + // More accurate , is the previous coupon date + if (effectiveDate > evalDate) + effectiveDate = effectiveDate - new Period(tenor_.length(), TimeUnit.Months); + else if (effectiveDate + new Period(tenor_.length(), TimeUnit.Months) < evalDate) + effectiveDate = effectiveDate + new Period(tenor_.length(), TimeUnit.Months); } else - Utils.QL_REQUIRE( effectiveDate != null, () => "null effective date" ); + Utils.QL_REQUIRE(effectiveDate != null, () => "null effective date"); Utils.QL_REQUIRE(effectiveDate < terminationDate, () => - "effective date (" + effectiveDate + - ") later than or equal to termination date (" + - terminationDate + ")" - ); + "effective date (" + effectiveDate + + ") later than or equal to termination date (" + + terminationDate + ")" + ); if (tenor_.length() == 0) rule_ = DateGeneration.Rule.Zero; else - Utils.QL_REQUIRE( tenor.length() > 0, () => "non positive tenor (" + tenor + ") not allowed" ); + Utils.QL_REQUIRE(tenor.length() > 0, () => "non positive tenor (" + tenor + ") not allowed"); if (firstDate_ != null) { @@ -155,7 +160,7 @@ public Schedule(Date effectiveDate, // we should ensure that the above condition is still verified after adjustment break; case DateGeneration.Rule.ThirdWednesday: - Utils.QL_REQUIRE( IMM.isIMMdate( firstDate_, false ), () => "first date (" + firstDate_ + ") is not an IMM date" ); + Utils.QL_REQUIRE(IMM.isIMMdate(firstDate_, false), () => "first date (" + firstDate_ + ") is not an IMM date"); break; case DateGeneration.Rule.Zero: case DateGeneration.Rule.Twentieth: @@ -177,14 +182,14 @@ public Schedule(Date effectiveDate, { case DateGeneration.Rule.Backward: case DateGeneration.Rule.Forward: - Utils.QL_REQUIRE( nextToLastDate_ > effectiveDate && nextToLastDate_ < terminationDate, () => + Utils.QL_REQUIRE(nextToLastDate_ > effectiveDate&& nextToLastDate_ < terminationDate, () => "next to last date (" + nextToLastDate_ + ") out of effective-termination date range (" + effectiveDate + ", " + terminationDate + "]"); // we should ensure that the above condition is still verified after adjustment break; case DateGeneration.Rule.ThirdWednesday: - Utils.QL_REQUIRE( IMM.isIMMdate( nextToLastDate_, false ), () => "next-to-last date (" + nextToLastDate_ + - ") is not an IMM date"); + Utils.QL_REQUIRE(IMM.isIMMdate(nextToLastDate_, false), () => "next-to-last date (" + nextToLastDate_ + + ") is not an IMM date"); break; case DateGeneration.Rule.Zero: case DateGeneration.Rule.Twentieth: @@ -203,7 +208,7 @@ public Schedule(Date effectiveDate, // calendar needed for endOfMonth adjustment Calendar nullCalendar = new NullCalendar(); int periods = 1; - Date seed = new Date() , exitDate = new Date(); + Date seed = new Date(), exitDate = new Date(); switch (rule_.Value) { case DateGeneration.Rule.Zero: @@ -220,7 +225,7 @@ public Schedule(Date effectiveDate, if (nextToLastDate_ != null) { dates_.Insert(0, nextToLastDate_); - Date temp = nullCalendar.advance(seed, -periods * tenor_, convention_, endOfMonth_.Value); + Date temp = nullCalendar.advance(seed, -periods* tenor_, convention_, endOfMonth_.Value); if (temp != nextToLastDate_) isRegular_.Insert(0, false); else @@ -233,11 +238,11 @@ public Schedule(Date effectiveDate, while (true) { - Date temp = nullCalendar.advance(seed, -periods * tenor_, convention_, endOfMonth_.Value); + Date temp = nullCalendar.advance(seed, -periods* tenor_, convention_, endOfMonth_.Value); if (temp < exitDate) { if (firstDate_ != null && (calendar_.adjust(dates_.First(), convention_) != - calendar_.adjust(firstDate_, convention_))) + calendar_.adjust(firstDate_, convention_))) { dates_.Insert(0, firstDate_); isRegular_.Insert(0, false); @@ -271,8 +276,8 @@ public Schedule(Date effectiveDate, case DateGeneration.Rule.OldCDS: case DateGeneration.Rule.CDS: case DateGeneration.Rule.CDS2015: - Utils.QL_REQUIRE( !endOfMonth, () => "endOfMonth convention incompatible with " + rule_.Value + " date generation rule" ); - goto case DateGeneration.Rule.Forward; // fall through + Utils.QL_REQUIRE(!endOfMonth, () => "endOfMonth convention incompatible with " + rule_.Value + " date generation rule"); + goto case DateGeneration.Rule.Forward; // fall through case DateGeneration.Rule.Forward: if (rule_.Value == DateGeneration.Rule.CDS || @@ -289,7 +294,7 @@ public Schedule(Date effectiveDate, if (firstDate_ != null) { dates_.Add(firstDate_); - Date temp = nullCalendar.advance(seed, periods * tenor_, convention_, endOfMonth_.Value); + Date temp = nullCalendar.advance(seed, periods* tenor_, convention_, endOfMonth_.Value); if (temp != firstDate_) isRegular_.Add(false); else @@ -325,14 +330,14 @@ public Schedule(Date effectiveDate, if (nextToLastDate_ != null) exitDate = nextToLastDate_; if (rule_ == DateGeneration.Rule.CDS2015 - && nextTwentieth(terminationDate, rule_.Value) == terminationDate - && terminationDate.month() % 2 == 1) + && nextTwentieth(terminationDate, rule_.Value) == terminationDate + && terminationDate.month() % 2 == 1) { exitDate = nextTwentieth(terminationDate + 1, rule_.Value); } while (true) { - Date temp = nullCalendar.advance(seed, periods * tenor_, convention_, endOfMonth_.Value); + Date temp = nullCalendar.advance(seed, periods* tenor_, convention_, endOfMonth_.Value); if (temp > exitDate) { if (nextToLastDate_ != null && @@ -391,7 +396,7 @@ public Schedule(Date effectiveDate, // adjustments if (rule_ == DateGeneration.Rule.ThirdWednesday) - for (int i = 1; i < dates_.Count-1; ++i) + for (int i = 1; i < dates_.Count - 1; ++i) dates_[i] = Date.nthWeekday(3, DayOfWeek.Wednesday, dates_[i].Month, dates_[i].Year); if (endOfMonth && calendar_.isEndOfMonth(seed)) @@ -399,12 +404,12 @@ public Schedule(Date effectiveDate, // adjust to end of month if (convention_ == BusinessDayConvention.Unadjusted) { - for (int i = 1; i < dates_.Count-1; ++i) + for (int i = 1; i < dates_.Count - 1; ++i) dates_[i] = Date.endOfMonth(dates_[i]); } else { - for (int i = 1; i < dates_.Count-1; ++i) + for (int i = 1; i < dates_.Count - 1; ++i) dates_[i] = calendar_.endOfMonth(dates_[i]); } if (terminationDateConvention_ != BusinessDayConvention.Unadjusted) @@ -427,7 +432,7 @@ public Schedule(Date effectiveDate, // first date not adjusted for CDS schedules if (rule_ != DateGeneration.Rule.OldCDS) dates_[0] = calendar_.adjust(dates_[0], convention_); - for (int i = 1; i < dates_.Count-1; ++i) + for (int i = 1; i < dates_.Count - 1; ++i) dates_[i] = calendar_.adjust(dates_[i], convention_); // termination date is NOT adjusted as per ISDA specifications, unless otherwise specified in the @@ -460,15 +465,15 @@ public Schedule(Date effectiveDate, } Utils.QL_REQUIRE(dates_.Count > 1, - () => "degenerate single date (" + dates_[0] + ") schedule" + - "\n seed date: " + seed + - "\n exit date: " + exitDate + - "\n effective date: " + effectiveDate + - "\n first date: " + firstDate + - "\n next to last date: " + nextToLastDate + - "\n termination date: " + terminationDate + - "\n generation rule: " + rule_.Value + - "\n end of month: " + endOfMonth_.Value); + () => "degenerate single date (" + dates_[0] + ") schedule" + + "\n seed date: " + seed + + "\n exit date: " + exitDate + + "\n effective date: " + effectiveDate + + "\n first date: " + firstDate + + "\n next to last date: " + nextToLastDate + + "\n termination date: " + terminationDate + + "\n generation rule: " + rule_.Value + + "\n end of month: " + endOfMonth_.Value); } #endregion @@ -498,7 +503,7 @@ public Date previousDate(Date d) public Date nextDate(Date d) { int i = dates_.BinarySearch(d); - if (i < 0 || i == dates_.Count-1) + if (i < 0 || i == dates_.Count - 1) return null; else return dates_[i + 1]; @@ -507,7 +512,7 @@ public Date nextDate(Date d) public bool isRegular(int i) { Utils.QL_REQUIRE(isRegular_.Count > 0, () => "full interface (isRegular) not available"); - Utils.QL_REQUIRE( i <= isRegular_.Count && i > 0, () => "index (" + i + ") must be in [1, " + isRegular_.Count + "]" ); + Utils.QL_REQUIRE(i <= isRegular_.Count && i > 0, () => "index (" + i + ") must be in [1, " + isRegular_.Count + "]"); return isRegular_[i - 1]; } public IList isRegular() @@ -521,23 +526,28 @@ public IList isRegular() public Calendar calendar() { return calendar_; } public Date startDate() { return dates_.First(); } public Date endDate() { return dates_.Last(); } - public Period tenor() { - Utils.QL_REQUIRE( tenor_ != null, () => "full interface (tenor) not available" ); + public Period tenor() + { + Utils.QL_REQUIRE(tenor_ != null, () => "full interface (tenor) not available"); return tenor_; } - public BusinessDayConvention businessDayConvention() { + public BusinessDayConvention businessDayConvention() + { return convention_; } - public BusinessDayConvention terminationDateBusinessDayConvention() { - Utils.QL_REQUIRE(terminationDateConvention_.HasValue, () => "full interface (termination date business day convention) not available" ); + public BusinessDayConvention terminationDateBusinessDayConvention() + { + Utils.QL_REQUIRE(terminationDateConvention_.HasValue, () => "full interface (termination date business day convention) not available"); return terminationDateConvention_.Value; } - public DateGeneration.Rule rule() { - Utils.QL_REQUIRE( rule_.HasValue, () => "full interface (rule) not available" ); + public DateGeneration.Rule rule() + { + Utils.QL_REQUIRE(rule_.HasValue, () => "full interface (rule) not available"); return rule_.Value; } - public bool endOfMonth() { - Utils.QL_REQUIRE( endOfMonth_.HasValue, () => "full interface (end of month) not available" ); + public bool endOfMonth() + { + Utils.QL_REQUIRE(endOfMonth_.HasValue, () => "full interface (end of month) not available"); return endOfMonth_.Value; } @@ -546,10 +556,10 @@ public Schedule until(Date truncationDate) { Schedule result = (Schedule)this.MemberwiseClone(); - Utils.QL_REQUIRE( truncationDate > result.dates_[0], () => - "truncation date " + truncationDate + - " must be later than schedule first date " + - result.dates_[0]); + Utils.QL_REQUIRE(truncationDate > result.dates_[0], () => + "truncation date " + truncationDate + + " must be later than schedule first date " + + result.dates_[0]); if (truncationDate < result.dates_.Last()) { @@ -595,7 +605,8 @@ private Date nextTwentieth(Date d, DateGeneration.Rule rule) { int m = result.month(); if (m % 3 != 0) - { // not a main IMM nmonth + { + // not a main IMM nmonth int skip = 3 - m % 3; result += new Period(skip, TimeUnit.Months); } @@ -614,7 +625,8 @@ private Date previousTwentieth(Date d, DateGeneration.Rule rule) { int m = result.month(); if (m % 3 != 0) - { // not a main IMM nmonth + { + // not a main IMM nmonth int skip = m % 3; result -= new Period(skip, TimeUnit.Months); } @@ -624,7 +636,7 @@ private Date previousTwentieth(Date d, DateGeneration.Rule rule) private bool allowsEndOfMonth(Period tenor) { return (tenor.units() == TimeUnit.Months || tenor.units() == TimeUnit.Years) - && tenor >= new Period(1,TimeUnit.Months); + && tenor >= new Period(1, TimeUnit.Months); } private Period tenor_; @@ -728,9 +740,9 @@ public Schedule value() { // check for mandatory arguments - Utils.QL_REQUIRE(effectiveDate_ != null,()=> "effective date not provided"); - Utils.QL_REQUIRE(terminationDate_ != null,()=> "termination date not provided"); - Utils.QL_REQUIRE((object)tenor_ != null,()=> "tenor/frequency not provided"); + Utils.QL_REQUIRE(effectiveDate_ != null, () => "effective date not provided"); + Utils.QL_REQUIRE(terminationDate_ != null, () => "termination date not provided"); + Utils.QL_REQUIRE((object)tenor_ != null, () => "tenor/frequency not provided"); // if no calendar was set... if (calendar_ == null) @@ -742,7 +754,7 @@ public Schedule value() // set dynamic defaults: BusinessDayConvention convention; // if a convention was set, we use it. - if (convention_ != null ) + if (convention_ != null) { convention = convention_.Value; } @@ -762,7 +774,7 @@ public Schedule value() BusinessDayConvention terminationDateConvention; // if set explicitly, we use it; - if (terminationDateConvention_ != null ) + if (terminationDateConvention_ != null) { terminationDateConvention = terminationDateConvention_.Value; } @@ -773,8 +785,8 @@ public Schedule value() } return new Schedule(effectiveDate_, terminationDate_, tenor_, calendar_, - convention, terminationDateConvention, - rule_, endOfMonth_, firstDate_, nextToLastDate_); + convention, terminationDateConvention, + rule_, endOfMonth_, firstDate_, nextToLastDate_); } private Calendar calendar_; diff --git a/src/QLNet/timegrid.cs b/src/QLNet/TimeGrid.cs similarity index 88% rename from src/QLNet/timegrid.cs rename to src/QLNet/TimeGrid.cs index ce78df922..99b8f408d 100644 --- a/src/QLNet/timegrid.cs +++ b/src/QLNet/TimeGrid.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -35,7 +35,10 @@ public class TimeGrid public double this[int i] { - get { return times_[i]; } + get + { + return times_[i]; + } } private List dt_; @@ -139,7 +142,7 @@ public TimeGrid(List times, int offset, int steps) if (periodEnd.IsNotEqual(0.0)) { // the nearest integer - int nSteps = (int) ((periodEnd - periodBegin) / dtMax + 0.5); + int nSteps = (int)((periodEnd - periodBegin) / dtMax + 0.5); // at least one time step! nSteps = (nSteps != 0 ? nSteps : 1); dt = (periodEnd - periodBegin) / nSteps; @@ -162,12 +165,12 @@ public int index(double t) { return i; } - Utils.QL_REQUIRE(t >= times_.First(),()=> - "using inadequate time grid: all nodes are later than the required time t = " - + t + " (earliest node is t1 = " + times_.First() + ")"); - Utils.QL_REQUIRE(t <= times_.Last(),()=> - "using inadequate time grid: all nodes are earlier than the required time t = " - + t + " (latest node is t1 = " + times_.Last() + ")"); + Utils.QL_REQUIRE(t >= times_.First(), () => + "using inadequate time grid: all nodes are later than the required time t = " + + t + " (earliest node is t1 = " + times_.First() + ")"); + Utils.QL_REQUIRE(t <= times_.Last(), () => + "using inadequate time grid: all nodes are earlier than the required time t = " + + t + " (latest node is t1 = " + times_.Last() + ")"); int j, k; if (t > times_[i]) { @@ -180,7 +183,7 @@ public int index(double t) k = i; } Utils.QL_FAIL("using inadequate time grid: the nodes closest to the required time t = " - + t + " are t1 = " + times_[j] + " and t2 = " + times_[k]); + + t + " are t1 = " + times_[j] + " and t2 = " + times_[k]); return 0; } @@ -190,9 +193,9 @@ public int closestIndex(double t) int result = times_.BinarySearch(t); if (result < 0) //Lower_bound is a version of binary search: it attempts to find the element value in an ordered range [first, last) - // [1]. Specifically, it returns the first position where value could be inserted without violating the ordering. + // [1]. Specifically, it returns the first position where value could be inserted without violating the ordering. // [2] The first version of lower_bound uses operator< for comparison, and the second uses the function object comp. - // lower_bound returns the furthermost iterator i in [first, last) such that, for every iterator j in [first, i), *j < value. + // lower_bound returns the furthermost iterator i in [first, last) such that, for every iterator j in [first, i), *j < value. result = ~result; if (result == 0) diff --git a/src/QLNet/Types.cs b/src/QLNet/Types.cs index bfda42242..18886a91e 100644 --- a/src/QLNet/Types.cs +++ b/src/QLNet/Types.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -98,7 +98,10 @@ public bool Remove(KeyValuePair item) public int Count { get { return backingDictionary_.Count; } } public bool IsReadOnly { - get { return false; } + get + { + return false; + } } public bool ContainsKey(Date key) @@ -108,7 +111,7 @@ public bool ContainsKey(Date key) public void Add(Date key, T value) { - backingDictionary_.Add(key,value); + backingDictionary_.Add(key, value); } public bool Remove(Date key) @@ -131,7 +134,10 @@ public T this[Date key] } return default(T); } - set { backingDictionary_[key] = value; } + set + { + backingDictionary_[key] = value; + } } public ICollection Keys { get { return backingDictionary_.Keys; } } @@ -140,13 +146,13 @@ public T this[Date key] public struct Duration { - public enum Type { Simple, Macaulay, Modified } + public enum Type { Simple, Macaulay, Modified } } - public struct Position + public struct Position { - public enum Type { Long, Short } - } + public enum Type { Long, Short } + } public enum InterestRateType { Fixed, Floating } //! Interest rate coumpounding rule @@ -157,8 +163,8 @@ public enum Compounding Continuous = 2, //!< \f$ e^{rt} \f$ SimpleThenCompounded //!< Simple up to the first period then Compounded } - - public enum Month + + public enum Month { January = 1, February = 2, @@ -185,7 +191,7 @@ public enum Month Dec = 12 } - public enum BusinessDayConvention + public enum BusinessDayConvention { // ISDA Following, /*!< Choose the first business day after @@ -210,7 +216,7 @@ the given holiday unless that day end of month, in which case choose the first business day before the holiday. */ - Nearest /*!< Choose the nearest business day + Nearest /*!< Choose the nearest business day to the given holiday. If both the preceding and following business days are equally far away, default @@ -257,7 +263,7 @@ public enum Rule date is also modified. */ TwentiethIMM, /*!< All dates but the effective date are taken to be the twentieth of an IMM month (used for CDS schedules.) The termination date is also modified. */ - OldCDS, /*!< Same as TwentiethIMM with unrestricted date ends and log/short stub + OldCDS, /*!< Same as TwentiethIMM with unrestricted date ends and log/short stub coupon period (old CDS convention). */ CDS, /*!< Credit derivatives standard rule since 'Big Bang' changes in 2009. */ CDS2015 /*!< Credit derivatives standard rule since December 20th, 2015. */ diff --git a/src/QLNet/Utils.cs b/src/QLNet/Utils.cs index 23e100840..6678af5db 100644 --- a/src/QLNet/Utils.cs +++ b/src/QLNet/Utils.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,133 +21,156 @@ under the terms of the QLNet license. You should have received a using System.Linq; using System.Reflection; -namespace QLNet +namespace QLNet { - // here are extensions to IList to accomodate some QL functionality as well as have useful things for .net - public static partial class Utils { - public static bool empty(this IList items) { return items.Count == 0; } - - // equivalent of ForEach but with the index - public static void ForEach(this IList items, Action action) { - if (items != null && action != null) - for (int idx = 0; idx < items.Count; idx++) - action(idx, items[idx]); - } - - // this is a version of element retrieval with some logic for default values - public static T Get(this List v, int i) - { - return Get(v, i, default(T)); - } - public static T Get(this List v, int i, T defval) - { - if (v == null || v.Count == 0) return defval; - else if (i >= v.Count) return v.Last(); - else return v[i]; - } - public static Nullable Get(this List> v, int i) - where T : struct - { - return Get(v, i, null); - } - public static Nullable Get(this List> v, int i, Nullable defval) - where T : struct - { - if (v == null || v.Count == 0) return defval; - else if (i >= v.Count) return v.Last(); - else return v[i]; - } - } - - - public static partial class Utils { - public static double effectiveFixedRate(List spreads, List caps, List floors, int i) { - double result = Get(spreads, i); - double? floor = Get(floors, i); - double? cap = Get(caps, i); - if (floor != null) result = Math.Max(Convert.ToDouble(floor), result); - if (cap != null) result = Math.Min(Convert.ToDouble(cap), result); - return result; - } - - public static bool noOption(List caps, List floors, int i) { - return Get(caps, i) == null && Get(floors, i) == null; - } - - public static void swap(ref double a1, ref double a2) { swap(ref a1, ref a2); } - public static void swap(ref T a1, ref T a2) { - T t = a2; - a2 = a1; - a1 = t; - } - - // this is the overload for Pow with int power: much faster and more precise - public static double Pow(double x, int y) { - int n = Math.Abs(y); - double retval = 1; - for (; ; x *= x) { - if ((n & 1) != 0) retval *= x; - if ((n >>= 1) == 0) return y < 0 ? 1 / retval : retval; - } - } - - public static void QL_REQUIRE( bool condition, Func message ) - { - if ( !condition ) - throw new ArgumentException( message.Invoke() ); - } - public static void QL_FAIL(string message) - { - throw new ArgumentException(message); - } - - public static bool is_QL_NEGATIVE_RATES() - { - #if QL_NEGATIVE_RATES - return true; - #else - return false; - #endif - } - - public static MethodInfo GetMethodInfo(Object t, String function , Type[] types = null ) - { - MethodInfo methodInfo; - if (types == null) types = new Type[0]; - #if NET40 || NET45 - methodInfo = t.GetType().GetMethod(function, types); - #else - methodInfo = t.GetType().GetRuntimeMethod( function, types ); - #endif - - return methodInfo; - } - } - - // this is a redefined collection class to emulate array-type behaviour at initialisation - // if T is a class then the list is initilized with default constructors instead of null - public class InitializedList : List where T : new() { - public InitializedList() : base() { } - public InitializedList(int size) : base(size) { - for (int i = 0; i < this.Capacity; i++) - this.Add(default(T) == null ? FastActivator.Create() : default(T)); - } - public InitializedList(int size, T value) : base(size) { - for (int i = 0; i < this.Capacity; i++) - this.Add(value); - } - - // erases the contents without changing the size - public void Erase() { - for (int i = 0; i < this.Count; i++) - this[i] = default(T); // do we need to use "new T()" instead of default(T) when T is class? - } - } - - #if !(NET40 || NET45) - public interface ICloneable - { - object Clone(); - } - #endif + // here are extensions to IList to accomodate some QL functionality as well as have useful things for .net + public static partial class Utils + { + public static bool empty(this IList items) { return items.Count == 0; } + + // equivalent of ForEach but with the index + public static void ForEach(this IList items, Action action) + { + if (items != null && action != null) + for (int idx = 0; idx < items.Count; idx++) + action(idx, items[idx]); + } + + // this is a version of element retrieval with some logic for default values + public static T Get(this List v, int i) + { + return Get(v, i, default(T)); + } + public static T Get(this List v, int i, T defval) + { + if (v == null || v.Count == 0) + return defval; + else if (i >= v.Count) + return v.Last(); + else + return v[i]; + } + public static Nullable Get(this List> v, int i) + where T : struct + { + return Get(v, i, null); + } + public static Nullable Get(this List> v, int i, Nullable defval) + where T : struct + { + if (v == null || v.Count == 0) + return defval; + else if (i >= v.Count) + return v.Last(); + else + return v[i]; + } + } + + + public static partial class Utils + { + public static double effectiveFixedRate(List spreads, List < double? > caps, List < double? > floors, int i) + { + double result = Get(spreads, i); + double? floor = Get(floors, i); + double? cap = Get(caps, i); + if (floor != null) + result = Math.Max(Convert.ToDouble(floor), result); + if (cap != null) + result = Math.Min(Convert.ToDouble(cap), result); + return result; + } + + public static bool noOption(List < double? > caps, List < double? > floors, int i) + { + return Get(caps, i) == null && Get(floors, i) == null; + } + + public static void swap(ref double a1, ref double a2) { swap(ref a1, ref a2); } + public static void swap(ref T a1, ref T a2) + { + T t = a2; + a2 = a1; + a1 = t; + } + + // this is the overload for Pow with int power: much faster and more precise + public static double Pow(double x, int y) + { + int n = Math.Abs(y); + double retval = 1; + for (; ; x *= x) + { + if ((n & 1) != 0) + retval *= x; + if ((n >>= 1) == 0) + return y < 0 ? 1 / retval : retval; + } + } + + public static void QL_REQUIRE(bool condition, Func message) + { + if (!condition) + throw new ArgumentException(message.Invoke()); + } + public static void QL_FAIL(string message) + { + throw new ArgumentException(message); + } + + public static bool is_QL_NEGATIVE_RATES() + { +#if QL_NEGATIVE_RATES + return true; +#else + return false; +#endif + } + + public static MethodInfo GetMethodInfo(Object t, String function, Type[] types = null) + { + MethodInfo methodInfo; + if (types == null) + types = new Type[0]; +#if NET40 || NET45 + methodInfo = t.GetType().GetMethod(function, types); +#else + methodInfo = t.GetType().GetRuntimeMethod(function, types); +#endif + + return methodInfo; + } + } + + // this is a redefined collection class to emulate array-type behaviour at initialisation + // if T is a class then the list is initilized with default constructors instead of null + public class InitializedList : List where T : new () + { + public InitializedList() : base() { } + public InitializedList(int size) : base(size) + { + for (int i = 0; i < this.Capacity; i++) + this.Add(default(T) == null ? FastActivator.Create() : default(T)); + } + public InitializedList(int size, T value) : base(size) + { + for (int i = 0; i < this.Capacity; i++) + this.Add(value); + } + + // erases the contents without changing the size + public void Erase() + { + for (int i = 0; i < this.Count; i++) + this[i] = default(T); // do we need to use "new T()" instead of default(T) when T is class? + } + } + +#if !(NET40 || NET45) + public interface ICloneable + { + object Clone(); + } +#endif } diff --git a/src/QLNet/grid.cs b/src/QLNet/grid.cs deleted file mode 100644 index 543fc70ff..000000000 --- a/src/QLNet/grid.cs +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - public partial class Utils { - - public static Vector CenteredGrid(double center, double dx, int steps) { - Vector result = new Vector(steps+1); - for (int i=0; i. - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/legacy/libormarketmodels/LfmCovarianceProxy.cs b/src/QLNet/legacy/libormarketmodels/LfmCovarianceProxy.cs new file mode 100644 index 000000000..49fd2d005 --- /dev/null +++ b/src/QLNet/legacy/libormarketmodels/LfmCovarianceProxy.cs @@ -0,0 +1,158 @@ +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; + +namespace QLNet +{ + public class LfmCovarianceProxy : LfmCovarianceParameterization + { + public LmVolatilityModel volaModel { get; set; } + public LmCorrelationModel corrModel { get; set; } + public LmVolatilityModel volaModel_ { get; set; } + public LmCorrelationModel corrModel_ { get; set; } + + public LfmCovarianceProxy(LmVolatilityModel volaModel, + LmCorrelationModel corrModel) + : base(corrModel.size(), corrModel.factors()) + { + volaModel_ = volaModel; + corrModel_ = corrModel ; + + Utils.QL_REQUIRE(volaModel_.size() == corrModel_.size(), () => + "different size for the volatility (" + volaModel_.size() + ") and correlation (" + corrModel_.size() + ") models"); + } + + public LmVolatilityModel volatilityModel() + { + return volaModel_; + } + + public LmCorrelationModel correlationModel() + { + return corrModel_; + } + + public override Matrix diffusion(double t) + { + return diffusion(t, null); + } + + public override Matrix diffusion(double t, Vector x) + { + Matrix pca = corrModel_.pseudoSqrt(t, x); + Vector vol = volaModel_.volatility(t, x); + for (int i = 0; i < size_; ++i) + { + for (int j = 0; j < size_; ++j) + pca[i, j] = pca[i, j] * vol[i]; + } + return pca; + } + + public override Matrix covariance(double t, Vector x) + { + Vector volatility = volaModel_.volatility(t, x); + Matrix correlation = corrModel_.correlation(t, x); + + Matrix tmp = new Matrix(size_, size_); + for (int i = 0; i < size_; ++i) + { + for (int j = 0; j < size_; ++j) + { + tmp[i, j] = volatility[i] * correlation[i, j] * volatility[j]; + } + } + return tmp; + } + + public double integratedCovariance(int i, int j, double t) + { + return integratedCovariance(i, j, t, new Vector()); + } + + public double integratedCovariance(int i, int j, double t, Vector x) + { + if (corrModel_.isTimeIndependent()) + { + try + { + // if all objects support these methods + // thats by far the fastest way to get the + // integrated covariance + return corrModel_.correlation(i, j, 0.0, x) + * volaModel_.integratedVariance(j, i, t, x); + //verifier la methode integratedVariance, qui bdoit etre implémenté + } + catch (System.Exception) + { + // okay proceed with the + // slow numerical integration routine + } + } + + try + { + Utils.QL_REQUIRE(x.empty() != false, () => "can not handle given x here"); + } + catch //OK x empty + { + } + + double tmp = 0.0; + VarProxy_Helper helper = new VarProxy_Helper(this, i, j); + + GaussKronrodAdaptive integrator = new GaussKronrodAdaptive(1e-10, 10000); + for (int k = 0; k < 64; ++k) + { + tmp += integrator.value(helper.value, k * t / 64.0, (k + 1) * t / 64.0); + } + return tmp; + } + } + + public class VarProxy_Helper + { + private int i_, j_; + public LmVolatilityModel volaModel_ { get; set; } + public LmCorrelationModel corrModel_ { get; set; } + + public VarProxy_Helper(LfmCovarianceProxy proxy, int i, int j) + { + i_ = i; + j_ = j; + volaModel_ = proxy.volaModel_; + corrModel_ = proxy.corrModel_; + } + + public double value(double t) + { + double v1, v2; + if (i_ == j_) + { + v1 = v2 = volaModel_.volatility(i_, t, null); + } + else + { + v1 = volaModel_.volatility(i_, t, null); + v2 = volaModel_.volatility(j_, t, null); + } + return v1 * corrModel_.correlation(i_, j_, t, null) * v2; + } + } +} diff --git a/src/QLNet/legacy/libormarketmodels/LfmHullWhiteParam.cs b/src/QLNet/legacy/libormarketmodels/LfmHullWhiteParam.cs new file mode 100644 index 000000000..6dc80ce46 --- /dev/null +++ b/src/QLNet/legacy/libormarketmodels/LfmHullWhiteParam.cs @@ -0,0 +1,182 @@ +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QLNet +{ + public class LfmHullWhiteParameterization : LfmCovarianceParameterization + { + protected Matrix diffusion_, covariance_; + protected List fixingTimes_; + + public LfmHullWhiteParameterization( + LiborForwardModelProcess process, + OptionletVolatilityStructure capletVol, + Matrix correlation, int factors) + : base(process.size(), factors) + { + diffusion_ = new Matrix(size_ - 1, factors_); + fixingTimes_ = process.fixingTimes(); + + Matrix sqrtCorr = new Matrix(size_ - 1, factors_, 1.0); + if (correlation.empty()) + { + Utils.QL_REQUIRE(factors_ == 1, () => "correlation matrix must be given for multi factor models"); + } + else + { + Utils.QL_REQUIRE(correlation.rows() == size_ - 1 && + correlation.rows() == correlation.columns(), () => "wrong dimesion of the correlation matrix"); + + Utils.QL_REQUIRE(factors_ <= size_ - 1, () => "too many factors for given LFM process"); + + Matrix tmpSqrtCorr = MatrixUtilitites.pseudoSqrt(correlation, + MatrixUtilitites.SalvagingAlgorithm.Spectral); + + // reduce to n factor model + // "Reconstructing a valid correlation matrix from invalid data" + // () + for (int i = 0; i < size_ - 1; ++i) + { + double d = 0; + tmpSqrtCorr.row(i).GetRange(0, factors_).ForEach((ii, vv) => d += vv * tmpSqrtCorr.row(i)[ii]); + for (int k = 0; k < factors_; ++k) + { + sqrtCorr[i, k] = tmpSqrtCorr.row(i).GetRange(0, factors_)[k] / Math.Sqrt(d); + } + } + } + List lambda = new List(); + DayCounter dayCounter = process.index().dayCounter(); + List fixingTimes = process.fixingTimes(); + List fixingDates = process.fixingDates(); + + for (int i = 1; i < size_; ++i) + { + double cumVar = 0.0; + for (int j = 1; j < i; ++j) + { + cumVar += lambda[i - j - 1] * lambda[i - j - 1] + * (fixingTimes[j + 1] - fixingTimes[j]); + } + + double vol = capletVol.volatility(fixingDates[i], 0.0, false); + double var = vol * vol + * capletVol.dayCounter().yearFraction(fixingDates[0], + fixingDates[i]); + lambda.Add(Math.Sqrt((var - cumVar) + / (fixingTimes[1] - fixingTimes[0]))); + for (int q = 0; q < factors_; ++q) + { + diffusion_[i - 1, q] = sqrtCorr[i - 1, q] * lambda.Last() ; + } + } + covariance_ = diffusion_ * Matrix.transpose(diffusion_); + } + + public LfmHullWhiteParameterization( + LiborForwardModelProcess process, + OptionletVolatilityStructure capletVol) + : this(process, capletVol, new Matrix(), 1) { } + + public override Matrix diffusion(double t) + { + return diffusion(t, null); + } + + public override Matrix diffusion(double t, Vector x) + { + Matrix tmp = new Matrix(size_, factors_, 0.0); + int m = nextIndexReset(t); + + for (int k = m; k < size_; ++k) + { + for (int q = 0; q < factors_; ++q) + { + tmp[k, q] = diffusion_[k - m, q]; + } + } + return tmp; + } + + public override Matrix covariance(double t) + { + return covariance(t, null); + } + + public override Matrix covariance(double t, Vector x) + { + Matrix tmp = new Matrix(size_, size_, 0.0); + int m = nextIndexReset(t); + + for (int k = m; k < size_; ++k) + { + for (int i = m; i < size_; ++i) + { + tmp[k, i] = covariance_[k - m, i - m]; + } + } + return tmp; + } + + + public override Matrix integratedCovariance(double t, Vector x = null) + { + Matrix tmp = new Matrix(size_, size_, 0.0); + int last = fixingTimes_.BinarySearch(t); + if (last < 0) + //Lower_bound is a version of binary search: it attempts to find the element value in an ordered range [first, last) + // [1]. Specifically, it returns the first position where value could be inserted without violating the ordering. + // [2] The first version of lower_bound uses operator< for comparison, and the second uses the function object comp. + // lower_bound returns the furthermost iterator i in [first, last) such that, for every iterator j in [first, i), *j < value. + last = ~last; + + for (int i = 0; i <= last; ++i) + { + double dt = ((i < last) ? fixingTimes_[i + 1] : t) + - fixingTimes_[i]; + + for (int k = i; k < size_ - 1; ++k) + { + for (int l = i; l < size_ - 1; ++l) + { + tmp[k + 1, l + 1] += covariance_[k - i, l - i] * dt; + } + } + } + return tmp; + } + + protected int nextIndexReset(double t) + { + int result = fixingTimes_.BinarySearch(t); + if (result < 0) + // The upper_bound() algorithm finds the last position in a sequence that value can occupy + // without violating the sequence's ordering + // if BinarySearch does not find value the value, the index of the next larger item is returned + result = ~result - 1; + + // impose limits. we need the one before last at max or the first at min + result = Math.Max(Math.Min(result, fixingTimes_.Count - 2), 0); + return result + 1; + } + } +} diff --git a/src/QLNet/legacy/libormarketmodels/LfmProcess.cs b/src/QLNet/legacy/libormarketmodels/LfmProcess.cs new file mode 100644 index 000000000..f8bd4f44e --- /dev/null +++ b/src/QLNet/legacy/libormarketmodels/LfmProcess.cs @@ -0,0 +1,258 @@ +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + public class LiborForwardModelProcess : StochasticProcess + { + public int size_ { get; set; } + public IborIndex index_ { get; set; } + public LfmCovarianceParameterization lfmParam_ { get; set; } + public List initialValues_ { get; set; } + public List fixingTimes_ { get; set; } + public List fixingDates_ { get; set; } + public List accrualStartTimes_ { get; set; } + private List accrualEndTimes_; + public List accrualPeriod_ { get; set; } + + private Vector m1; + private Vector m2; + + public LiborForwardModelProcess(int size, IborIndex index, IDiscretization disc) + : base(disc) + { + size_ = size; + index_ = index; + initialValues_ = new InitializedList(size_); + fixingTimes_ = new InitializedList(size); + fixingDates_ = new InitializedList(size_); + accrualStartTimes_ = new InitializedList(size); + accrualEndTimes_ = new InitializedList(size); + accrualPeriod_ = new InitializedList(size_); + m1 = new Vector(size_); + m2 = new Vector(size_); + DayCounter dayCounter = index.dayCounter(); + IList flows = cashFlows(1); + + Utils.QL_REQUIRE(size_ == flows.Count, () => "wrong number of cashflows"); + + Date settlement = index_.forwardingTermStructure().link.referenceDate(); + Date startDate; + IborCoupon iborcoupon = (IborCoupon)flows[0]; + startDate = iborcoupon.fixingDate(); + + for (int i = 0; i < size_; ++i) + { + IborCoupon coupon = (IborCoupon)flows[i]; + + Utils.QL_REQUIRE(coupon.date() == coupon.accrualEndDate(), () => "irregular coupon types are not suppported"); + + initialValues_[i] = coupon.rate(); + accrualPeriod_[i] = coupon.accrualPeriod(); + + fixingDates_[i] = coupon.fixingDate(); + fixingTimes_[i] = dayCounter.yearFraction(startDate, coupon.fixingDate()); + accrualStartTimes_[i] = dayCounter.yearFraction(settlement, coupon.accrualStartDate()); + accrualEndTimes_[i] = dayCounter.yearFraction(settlement, coupon.accrualEndDate()); + } + } + + public LiborForwardModelProcess(int size, IborIndex index) + : this(size, index, new EulerDiscretization()) {} + + public override Vector drift(double t, Vector x) + { + Vector f = new Vector(size_, 0.0); + Matrix covariance = lfmParam_.covariance(t, x); + int m = nextIndexReset(t); + + for (int k = m; k < size_; ++k) + { + m1[k] = accrualPeriod_[k] * x[k] / (1 + accrualPeriod_[k] * x[k]); + double inner_product = 0; + m1.GetRange(m, k + 1 - m).ForEach( + (ii, vv) => inner_product += vv * + covariance.column(k).GetRange(m, covariance.rows() - m)[ii]); + + f[k] = inner_product - 0.5 * covariance[k, k]; + } + return f; + } + + public override Matrix diffusion(double t, Vector x) + { + return lfmParam_.diffusion(t, x); + } + + public override Matrix covariance(double t, Vector x, double dt) + { + return lfmParam_.covariance(t, x) * dt; + } + + public override Vector apply(Vector x0, Vector dx) + { + Vector tmp = new Vector(size_); + for (int k = 0; k < size_; ++k) + { + tmp[k] = x0[k] * Math.Exp(dx[k]); + } + return tmp; + } + + public override Vector evolve(double t0, Vector x0, double dt, Vector dw) + { + // predictor-corrector step to reduce discretization errors. + + int m = nextIndexReset(t0); + double sdt = Math.Sqrt(dt); + + Vector f = new Vector(x0); + Matrix diff = lfmParam_.diffusion(t0, x0); + Matrix covariance = lfmParam_.covariance(t0, x0); + + for (int k = m; k < size_; ++k) + { + double y = accrualPeriod_[k] * x0[k]; + m1[k] = y / (1 + y); + + double d = 0; + m1.GetRange(m, k + 1 - m).ForEach( + (ii, vv) => d += vv * + covariance.column(k).GetRange(m, covariance.rows() - m)[ii]); + d = (d - 0.5 * covariance[k, k]) * dt; + + double r = 0; + diff.row(k).ForEach((kk, vv) => r += vv * dw[kk]); + r *= sdt; + + double x = y * Math.Exp(d + r); + m2[k] = x / (1 + x); + + double inner_product = 0; + m2.GetRange(m, k + 1 - m).ForEach( + (ii, vv) => inner_product += vv * + covariance.column(k).GetRange(m, covariance.rows() - m)[ii]); + f[k] = x0[k] * Math.Exp(0.5 * (d + (inner_product - 0.5 * covariance[k, k]) * dt) + r); + } + + return f; + } + + public override Vector initialValues() + { + Vector tmp = new Vector(size()); + for (int i = 0; i < size(); ++i) + tmp[i] = initialValues_[i]; + return tmp; + } + + public void setCovarParam(LfmCovarianceParameterization param) + { + lfmParam_ = param; + } + + public LfmCovarianceParameterization covarParam() + { + return lfmParam_; + } + + public IborIndex index() + { + return index_; + } + + public List cashFlows() + { + return cashFlows(1); + } + + public List cashFlows(double amount) + { + Date refDate = index_.forwardingTermStructure().link.referenceDate(); + + Schedule schedule = new Schedule(refDate, + refDate + new Period(index_.tenor().length() * size_, + index_.tenor().units()), + index_.tenor(), index_.fixingCalendar(), + index_.businessDayConvention(), + index_.businessDayConvention(), + DateGeneration.Rule.Forward, false); + + IborLeg cashflows = (IborLeg) new IborLeg(schedule, index_) + .withFixingDays(index_.fixingDays()) + .withPaymentDayCounter(index_.dayCounter()) + .withNotionals(amount) + .withPaymentAdjustment(index_.businessDayConvention()); + return cashflows.value(); + } + + public override int size() { return size_; } + + public override int factors() + { + return lfmParam_.factors(); + } + + public List fixingTimes() + { + return fixingTimes_; + } + + public List fixingDates() + { + return fixingDates_; + } + + public List accrualStartTimes() + { + return accrualStartTimes_; + } + + public List accrualEndTimes() + { + return accrualEndTimes_; + } + + public int nextIndexReset(double t) + { + int result = fixingTimes_.FindIndex(x => x > t); + if (result < 0) + result = ~result - 1; + // impose limits. we need the one before last at max or the first at min + result = Math.Max(Math.Min(result, fixingTimes_.Count - 1), 0); + return result; + } + + public List discountBond(List rates) + { + + List discountFactors = new InitializedList(size_); + discountFactors[0] = 1.0 / (1.0 + rates[0] * accrualPeriod_[0]); + + for (int i = 1; i < size_; ++i) + { + discountFactors[i] = + discountFactors[i - 1] / (1.0 + rates[i] * accrualPeriod_[i]); + } + return discountFactors; + } + } +} diff --git a/src/QLNet/legacy/libormarketmodels/LfmSwaptionEngine.cs b/src/QLNet/legacy/libormarketmodels/LfmSwaptionEngine.cs new file mode 100644 index 000000000..b2edeba7b --- /dev/null +++ b/src/QLNet/legacy/libormarketmodels/LfmSwaptionEngine.cs @@ -0,0 +1,78 @@ +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Linq; + +namespace QLNet +{ + //! %Libor forward model swaption engine based on Black formula + /*! \ingroup swaptionengines */ + public class LfmSwaptionEngine : GenericModelEngine + { + private Handle discountCurve_; + + public LfmSwaptionEngine(LiborForwardModel model, + Handle discountCurve) + : base(model) + { + discountCurve_ = discountCurve; + discountCurve_.registerWith(update); + } + + public override void calculate() + { + Utils.QL_REQUIRE(arguments_.settlementType == Settlement.Type.Physical, () => + "cash-settled swaptions not priced with Lfm engine"); + + double basisPoint = 1.0e-4; + + VanillaSwap swap = arguments_.swap; + IPricingEngine pe = new DiscountingSwapEngine(discountCurve_); + swap.setPricingEngine(pe); + + double correction = swap.spread * + Math.Abs(swap.floatingLegBPS() / swap.fixedLegBPS()); + double fixedRate = swap.fixedRate - correction; + double fairRate = swap.fairRate() - correction; + + SwaptionVolatilityMatrix volatility = + model_.link.getSwaptionVolatilityMatrix(); + + Date referenceDate = volatility.referenceDate(); + DayCounter dayCounter = volatility.dayCounter(); + + double exercise = dayCounter.yearFraction(referenceDate, + arguments_.exercise.date(0)); + double swapLength = + dayCounter.yearFraction(referenceDate, + arguments_.fixedPayDates.Last()) + - dayCounter.yearFraction(referenceDate, + arguments_.fixedResetDates[0]); + + Option.Type w = arguments_.type == VanillaSwap.Type.Payer ? + Option.Type.Call : Option.Type.Put; + double vol = volatility.volatility(exercise, swapLength, + fairRate, true); + results_.value = (swap.fixedLegBPS() / basisPoint) * + Utils.blackFormula(w, fixedRate, fairRate, vol * Math.Sqrt(exercise)); + } + } +} diff --git a/src/QLNet/legacy/libormarketmodels/LiborForwardModel.cs b/src/QLNet/legacy/libormarketmodels/LiborForwardModel.cs new file mode 100644 index 000000000..6a01c9de3 --- /dev/null +++ b/src/QLNet/legacy/libormarketmodels/LiborForwardModel.cs @@ -0,0 +1,237 @@ +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QLNet +{ + public class LiborForwardModel : CalibratedModel, IAffineModel + { + List f_; + List accrualPeriod_; + + LfmCovarianceProxy covarProxy_; + LiborForwardModelProcess process_; + SwaptionVolatilityMatrix swaptionVola; + + public LiborForwardModel(LiborForwardModelProcess process, + LmVolatilityModel volaModel, + LmCorrelationModel corrModel) + : base(volaModel.parameters().Count + corrModel.parameters().Count) + { + + f_ = new InitializedList(process.size()); + accrualPeriod_ = new InitializedList(process.size()); + covarProxy_ = new LfmCovarianceProxy(volaModel, corrModel); + process_ = process; + + int k = volaModel.parameters().Count; + for (int j = 0; j < k; j++) + arguments_[j] = volaModel.parameters()[j]; + for (int j = 0; j < corrModel.parameters().Count; j++) + arguments_[j + k] = corrModel.parameters()[j]; + + for (int i = 0; i < process.size(); ++i) + { + accrualPeriod_[i] = process.accrualEndTimes()[i] + - process.accrualStartTimes()[i]; + f_[i] = 1.0 / (1.0 + accrualPeriod_[i] * process_.initialValues()[i]); + } + } + + + + public override void setParams(Vector parameters) + { + base.setParams(parameters); + + int k = covarProxy_.volatilityModel().parameters().Count; + + covarProxy_.volatilityModel().setParams(new List(arguments_.GetRange(0, k))); + covarProxy_.correlationModel().setParams(new List(arguments_.GetRange(k, arguments_.Count - k))); + + swaptionVola = null; + } + + + public double discountBondOption(Option.Type type, + double strike, double maturity, + double bondMaturity) + { + + List accrualStartTimes + = process_.accrualStartTimes(); + List accrualEndTimes + = process_.accrualEndTimes(); + + Utils.QL_REQUIRE(accrualStartTimes.First() <= maturity && accrualStartTimes.Last() >= maturity, () => + "capet maturity does not fit to the process"); + + int i = accrualStartTimes.BinarySearch(maturity); + if (i < 0) + // The lower_bound() algorithm finds the first position in a sequence that value can occupy + // without violating the sequence's ordering + // if BinarySearch does not find value the value, the index of the prev minor item is returned + i = ~i + 1; + + // impose limits. we need the one before last at max or the first at min + i = Math.Max(Math.Min(i, accrualStartTimes.Count - 1), 0); + + Utils.QL_REQUIRE(i < process_.size() + && Math.Abs(maturity - accrualStartTimes[i]) < 100 * Const.QL_EPSILON + && Math.Abs(bondMaturity - accrualEndTimes[i]) < 100 * Const.QL_EPSILON, () => + "irregular fixings are not (yet) supported"); + + double tenor = accrualEndTimes[i] - accrualStartTimes[i]; + double forward = process_.initialValues()[i]; + double capRate = (1.0 / strike - 1.0) / tenor; + double var = covarProxy_.integratedCovariance(i, i, process_.fixingTimes()[i]); + double dis = process_.index().forwardingTermStructure().link.discount(bondMaturity); + + double black = Utils.blackFormula( + (type == Option.Type.Put ? Option.Type.Call : Option.Type.Put), + capRate, forward, Math.Sqrt(var)); + + double npv = dis* tenor* black; + + return npv / (1.0 + capRate* tenor); + } + + public double discount(double t) + { + return process_.index().forwardingTermStructure().link.discount(t); + } + + public double discountBond(double t, double maturity, Vector v) + { + return discount(maturity); + } + + public Vector w_0(int alpha, int beta) + { + Vector omega = new Vector(beta + 1, 0.0); + Utils.QL_REQUIRE(alpha "alpha needs to be smaller than beta"); + + double s = 0.0; + for (int k = alpha + 1; k <= beta; ++k) + { + double b = accrualPeriod_[k]; + for (int j = alpha + 1; j <= k; ++j) + { + b *= f_[j]; + } + s += b; + } + + for (int i = alpha + 1; i <= beta; ++i) + { + double a = accrualPeriod_[i]; + for (int j = alpha + 1; j <= i; ++j) + { + a *= f_[j]; + } + omega[i] = a / s; + } + return omega; + } + + public double S_0(int alpha, int beta) + { + Vector w = w_0(alpha, beta); + Vector f = process_.initialValues(); + + double fwdRate = 0.0; + for (int i = alpha + 1; i <= beta; ++i) + { + fwdRate += w[i]*f[i]; + } + return fwdRate; + } + + + // calculating swaption volatility matrix using + // Rebonatos approx. formula. Be aware that this + // matrix is valid only for regular fixings and + // assumes that the fix and floating leg have the + // same frequency + public SwaptionVolatilityMatrix getSwaptionVolatilityMatrix() + { + if (swaptionVola != null) + { + return swaptionVola; + } + + IborIndex index = process_.index(); + Date today = process_.fixingDates()[0]; + + int size = process_.size() / 2; + Matrix volatilities = new Matrix(size, size); + + List exercises = new InitializedList(size); + for (int i = 0; i < size; ++i) + { + exercises[i] = process_.fixingDates()[i + 1]; + } + + List lengths = new InitializedList(size); + for (int i = 0; i < size; ++i) + { + lengths[i] = (i + 1) * index.tenor(); + } + + Vector f = process_.initialValues(); + for (int k = 0; k < size; ++k) + { + int alpha = k; + double t_alpha = process_.fixingTimes()[alpha + 1]; + + Matrix var = new Matrix(size, size); + for (int i = alpha + 1; i <= k + size; ++i) + { + for (int j = i; j <= k + size; ++j) + { + var[i - alpha - 1, j - alpha - 1] = var[j - alpha - 1, i - alpha - 1] = + covarProxy_.integratedCovariance(i, j, t_alpha, null); + } + } + + for (int l = 1; l <= size; ++l) + { + int beta = l + k; + Vector w = w_0(alpha, beta); + + double sum = 0.0; + for (int i = alpha + 1; i <= beta; ++i) + { + for (int j = alpha + 1; j <= beta; ++j) + { + sum += w[i] * w[j] * f[i] * f[j] * var[i - alpha - 1, j - alpha - 1]; + } + } + volatilities[k, l - 1] = + Math.Sqrt(sum / t_alpha) / S_0(alpha, beta); + } + } + + return swaptionVola = new SwaptionVolatilityMatrix(today, exercises, lengths, + volatilities, index.dayCounter()); + } + } +} diff --git a/src/QLNet/legacy/libormarketmodels/lmconstwrappercorrmodel.cs b/src/QLNet/legacy/libormarketmodels/LmConstWrapperCorrModel.cs similarity index 95% rename from src/QLNet/legacy/libormarketmodels/lmconstwrappercorrmodel.cs rename to src/QLNet/legacy/libormarketmodels/LmConstWrapperCorrModel.cs index 518a9239f..1aff8e61e 100644 --- a/src/QLNet/legacy/libormarketmodels/lmconstwrappercorrmodel.cs +++ b/src/QLNet/legacy/libormarketmodels/LmConstWrapperCorrModel.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/legacy/libormarketmodels/lmconstwrappervolmodel.cs b/src/QLNet/legacy/libormarketmodels/LmConstWrapperVolModel.cs similarity index 95% rename from src/QLNet/legacy/libormarketmodels/lmconstwrappervolmodel.cs rename to src/QLNet/legacy/libormarketmodels/LmConstWrapperVolModel.cs index 2e0bed333..555d3c129 100644 --- a/src/QLNet/legacy/libormarketmodels/lmconstwrappervolmodel.cs +++ b/src/QLNet/legacy/libormarketmodels/LmConstWrapperVolModel.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/legacy/libormarketmodels/lmcorrmodel.cs b/src/QLNet/legacy/libormarketmodels/LmCorrModel.cs similarity index 92% rename from src/QLNet/legacy/libormarketmodels/lmcorrmodel.cs rename to src/QLNet/legacy/libormarketmodels/LmCorrModel.cs index 4ac1325fb..8170211d3 100644 --- a/src/QLNet/legacy/libormarketmodels/lmcorrmodel.cs +++ b/src/QLNet/legacy/libormarketmodels/LmCorrModel.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -53,7 +53,7 @@ public void setParams(List arguments) public abstract Matrix correlation(double t, Vector x = null); - public virtual double correlation(int i, int j, double t, Vector x = null ) + public virtual double correlation(int i, int j, double t, Vector x = null) { // inefficient implementation, please overload in derived classes return correlation(t, x)[i, j]; @@ -62,7 +62,7 @@ public virtual double correlation(int i, int j, double t, Vector x = null ) public virtual Matrix pseudoSqrt(double t, Vector x = null) { return MatrixUtilitites.pseudoSqrt(this.correlation(t, x), - MatrixUtilitites.SalvagingAlgorithm.Spectral); + MatrixUtilitites.SalvagingAlgorithm.Spectral); } public virtual bool isTimeIndependent() diff --git a/src/QLNet/legacy/libormarketmodels/lmexpcorrmodel.cs b/src/QLNet/legacy/libormarketmodels/LmExpCorrModel.cs similarity index 97% rename from src/QLNet/legacy/libormarketmodels/lmexpcorrmodel.cs rename to src/QLNet/legacy/libormarketmodels/LmExpCorrModel.cs index 0d91c3974..5fb0c6ba9 100644 --- a/src/QLNet/legacy/libormarketmodels/lmexpcorrmodel.cs +++ b/src/QLNet/legacy/libormarketmodels/LmExpCorrModel.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/legacy/libormarketmodels/lmextlinexpvolmodel.cs b/src/QLNet/legacy/libormarketmodels/LmExtLinExpVolModel.cs similarity index 75% rename from src/QLNet/legacy/libormarketmodels/lmextlinexpvolmodel.cs rename to src/QLNet/legacy/libormarketmodels/LmExtLinExpVolModel.cs index 9f3b64f3a..bf301532c 100644 --- a/src/QLNet/legacy/libormarketmodels/lmextlinexpvolmodel.cs +++ b/src/QLNet/legacy/libormarketmodels/LmExtLinExpVolModel.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,24 +21,24 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - //! extended linear exponential volatility model - /*! This class describes an extended linear-exponential volatility model + //! extended linear exponential volatility model + /*! This class describes an extended linear-exponential volatility model - \f[ - \sigma_i(t)=k_i*((a*(T_{i}-t)+d)*e^{-b(T_{i}-t)}+c) - \f] + \f[ + \sigma_i(t)=k_i*((a*(T_{i}-t)+d)*e^{-b(T_{i}-t)}+c) + \f] - References: + References: - Damiano Brigo, Fabio Mercurio, Massimo Morini, 2003, - Different Covariance Parameterizations of Libor Market Model and Joint - Caps/Swaptions Calibration, - () - */ + Damiano Brigo, Fabio Mercurio, Massimo Morini, 2003, + Different Covariance Parameterizations of Libor Market Model and Joint + Caps/Swaptions Calibration, + () + */ public class LmExtLinearExponentialVolModel : LmLinearExponentialVolatilityModel { - public LmExtLinearExponentialVolModel(List fixingTimes,double a, double b, double c, double d) + public LmExtLinearExponentialVolModel(List fixingTimes, double a, double b, double c, double d) : base(fixingTimes, a, b, c, d) { arguments_.Capacity += size_; diff --git a/src/QLNet/legacy/libormarketmodels/lmfixedvolmodel.cs b/src/QLNet/legacy/libormarketmodels/LmFixedVolModel.cs similarity index 83% rename from src/QLNet/legacy/libormarketmodels/lmfixedvolmodel.cs rename to src/QLNet/legacy/libormarketmodels/LmFixedVolModel.cs index 2bac932b3..13548f4a1 100644 --- a/src/QLNet/legacy/libormarketmodels/lmfixedvolmodel.cs +++ b/src/QLNet/legacy/libormarketmodels/LmFixedVolModel.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -31,26 +31,26 @@ public LmFixedVolatilityModel(Vector volatilities, List startTimes) volatilities_ = volatilities; startTimes_ = startTimes; - Utils.QL_REQUIRE(startTimes_.Count > 1,()=> "too few dates"); + Utils.QL_REQUIRE(startTimes_.Count > 1, () => "too few dates"); - Utils.QL_REQUIRE(volatilities_.size() == startTimes_.Count,()=> - "volatility array and fixing time array have to have the same size"); + Utils.QL_REQUIRE(volatilities_.size() == startTimes_.Count, () => + "volatility array and fixing time array have to have the same size"); for (int i = 1; i < startTimes_.Count; i++) { - Utils.QL_REQUIRE(startTimes_[i] > startTimes_[i - 1],()=> - "invalid time (" + startTimes_[i] + ", vs " + startTimes_[i - 1] + ")"); + Utils.QL_REQUIRE(startTimes_[i] > startTimes_[i - 1], () => + "invalid time (" + startTimes_[i] + ", vs " + startTimes_[i - 1] + ")"); } } public override Vector volatility(double t, Vector x = null) { - Utils.QL_REQUIRE(t >= startTimes_.First() && t <= startTimes_.Last(),()=> - "invalid time given for volatility model"); + Utils.QL_REQUIRE(t >= startTimes_.First() && t <= startTimes_.Last(), () => + "invalid time given for volatility model"); int ti = startTimes_.GetRange(0, startTimes_.Count - 1).BinarySearch(t); if (ti < 0) - // The upper_bound() algorithm finds the last position in a sequence that value can occupy + // The upper_bound() algorithm finds the last position in a sequence that value can occupy // without violating the sequence's ordering // if BinarySearch does not find value the value, the index of the next larger item is returned ti = ~ti - 1; @@ -70,12 +70,12 @@ public override Vector volatility(double t, Vector x = null) public override double volatility(int i, double t, Vector x = null) { - Utils.QL_REQUIRE(t >= startTimes_.First() && t <= startTimes_.Last(),()=> - "invalid time given for volatility model"); + Utils.QL_REQUIRE(t >= startTimes_.First() && t <= startTimes_.Last(), () => + "invalid time given for volatility model"); int ti = startTimes_.GetRange(0, startTimes_.Count - 1).BinarySearch(t); if (ti < 0) - // The upper_bound() algorithm finds the last position in a sequence that value can occupy + // The upper_bound() algorithm finds the last position in a sequence that value can occupy // without violating the sequence's ordering // if BinarySearch does not find value the value, the index of the next larger item is returned ti = ~ti - 1; diff --git a/src/QLNet/legacy/libormarketmodels/lmlinexpcorrmodel.cs b/src/QLNet/legacy/libormarketmodels/LmLinExpCorrModel.cs similarity index 89% rename from src/QLNet/legacy/libormarketmodels/lmlinexpcorrmodel.cs rename to src/QLNet/legacy/libormarketmodels/LmLinExpCorrModel.cs index fb601c207..8e98d1749 100644 --- a/src/QLNet/legacy/libormarketmodels/lmlinexpcorrmodel.cs +++ b/src/QLNet/legacy/libormarketmodels/LmLinExpCorrModel.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -33,8 +33,8 @@ Different Covariance Parameterizations of Libor Market Model and Joint */ public class LmLinearExponentialCorrelationModel : LmCorrelationModel { - public LmLinearExponentialCorrelationModel(int size, double rho, double beta,int? factors = null ) - : base(size, 2) + public LmLinearExponentialCorrelationModel(int size, double rho, double beta, int? factors = null) + : base(size, 2) { corrMatrix_ = new Matrix(size, size); factors_ = factors ?? size; @@ -43,19 +43,19 @@ public LmLinearExponentialCorrelationModel(int size, double rho, double beta,int generateArguments(); } - public override Matrix correlation(double t, Vector x = null ) + public override Matrix correlation(double t, Vector x = null) { Matrix tmp = new Matrix(corrMatrix_); return tmp; } - public override Matrix pseudoSqrt(double t, Vector x = null ) + public override Matrix pseudoSqrt(double t, Vector x = null) { Matrix tmp = new Matrix(pseudoSqrt_); return tmp; } - public override double correlation(int i, int j, double t, Vector x = null ) + public override double correlation(int i, int j, double t, Vector x = null) { return corrMatrix_[i, j]; } @@ -77,15 +77,15 @@ protected override void generateArguments() for (int j = i; j < size_; ++j) { corrMatrix_[i, j] = corrMatrix_[j, i] - = rho + (1 - rho) * Math.Exp(-beta * Math.Abs((double) i - (double) j)); + = rho + (1 - rho) * Math.Exp(-beta * Math.Abs((double) i - (double) j)); } } - pseudoSqrt_ = MatrixUtilitites.rankReducedSqrt(corrMatrix_, factors_,1.0, MatrixUtilitites.SalvagingAlgorithm.None); + pseudoSqrt_ = MatrixUtilitites.rankReducedSqrt(corrMatrix_, factors_, 1.0, MatrixUtilitites.SalvagingAlgorithm.None); corrMatrix_ = pseudoSqrt_ * Matrix.transpose(pseudoSqrt_); } private Matrix corrMatrix_, pseudoSqrt_; private int factors_; - } -} + } +} diff --git a/src/QLNet/legacy/libormarketmodels/lmlinexpvolmodel.cs b/src/QLNet/legacy/libormarketmodels/LmLinExpVolModel.cs similarity index 97% rename from src/QLNet/legacy/libormarketmodels/lmlinexpvolmodel.cs rename to src/QLNet/legacy/libormarketmodels/LmLinExpVolModel.cs index c85736df7..2982f182f 100644 --- a/src/QLNet/legacy/libormarketmodels/lmlinexpvolmodel.cs +++ b/src/QLNet/legacy/libormarketmodels/LmLinExpVolModel.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -103,7 +103,7 @@ public override double integratedVariance(int i, int j, double u, Vector x = nul - 2 * c * (k3 * (1 + b * S) + k2 * (1 + b * T) - k1 * k3 * (1 + b * (S - u)) - k1 * k2 * (1 + b * (T - u))) - ) + ) ) / (4 * b * b * b * k2 * k3); } diff --git a/src/QLNet/legacy/libormarketmodels/lmvolmodel.cs b/src/QLNet/legacy/libormarketmodels/LmVolModel.cs similarity index 96% rename from src/QLNet/legacy/libormarketmodels/lmvolmodel.cs rename to src/QLNet/legacy/libormarketmodels/LmVolModel.cs index c5102ae1a..ac007cc08 100644 --- a/src/QLNet/legacy/libormarketmodels/lmvolmodel.cs +++ b/src/QLNet/legacy/libormarketmodels/LmVolModel.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. diff --git a/src/QLNet/legacy/libormarketmodels/lfmcovarproxy.cs b/src/QLNet/legacy/libormarketmodels/lfmcovarproxy.cs deleted file mode 100644 index be17e8480..000000000 --- a/src/QLNet/legacy/libormarketmodels/lfmcovarproxy.cs +++ /dev/null @@ -1,136 +0,0 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet -{ - public class LfmCovarianceProxy : LfmCovarianceParameterization - { - public LmVolatilityModel volaModel { get; set; } - public LmCorrelationModel corrModel { get; set; } - public LmVolatilityModel volaModel_ { get; set; } - public LmCorrelationModel corrModel_ { get; set; } - - public LfmCovarianceProxy(LmVolatilityModel volaModel, - LmCorrelationModel corrModel) - : base(corrModel.size(), corrModel.factors()){ - volaModel_=volaModel; - corrModel_=corrModel ; - - Utils.QL_REQUIRE(volaModel_.size() == corrModel_.size(),()=> - "different size for the volatility (" + volaModel_.size() + ") and correlation (" + corrModel_.size() + ") models"); - } - - public LmVolatilityModel volatilityModel() { - return volaModel_; - } - - public LmCorrelationModel correlationModel() { - return corrModel_; - } - - public override Matrix diffusion(double t){ - return diffusion(t, null); - } - - public override Matrix diffusion(double t, Vector x) { - Matrix pca = corrModel_.pseudoSqrt(t, x); - Vector vol = volaModel_.volatility(t, x); - for (int i=0; i "can not handle given x here"); - } - catch { //OK x empty - } - - double tmp=0.0; - VarProxy_Helper helper = new VarProxy_Helper(this, i, j); - - GaussKronrodAdaptive integrator=new GaussKronrodAdaptive(1e-10, 10000); - for (int k=0; k<64; ++k) { - tmp+=integrator.value(helper.value, k*t/64.0, (k+1)*t/64.0); - } - return tmp; - } - } - - public class VarProxy_Helper - { - private int i_, j_; - public LmVolatilityModel volaModel_{ get; set; } - public LmCorrelationModel corrModel_{ get; set; } - - public VarProxy_Helper(LfmCovarianceProxy proxy, int i, int j) { - i_=i; - j_=j; - volaModel_=proxy.volaModel_; - corrModel_=proxy.corrModel_; - } - - public double value(double t) { - double v1, v2; - if (i_ == j_) { - v1 = v2 = volaModel_.volatility(i_, t,null); - } - else { - v1 = volaModel_.volatility(i_, t, null); - v2 = volaModel_.volatility(j_, t, null); - } - return v1 * corrModel_.correlation(i_, j_, t, null) * v2; - } - } -} diff --git a/src/QLNet/legacy/libormarketmodels/lfmhullwhiteparam.cs b/src/QLNet/legacy/libormarketmodels/lfmhullwhiteparam.cs deleted file mode 100644 index 8300116d4..000000000 --- a/src/QLNet/legacy/libormarketmodels/lfmhullwhiteparam.cs +++ /dev/null @@ -1,161 +0,0 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace QLNet -{ - public class LfmHullWhiteParameterization : LfmCovarianceParameterization - { - protected Matrix diffusion_, covariance_; - protected List fixingTimes_; - - public LfmHullWhiteParameterization( - LiborForwardModelProcess process, - OptionletVolatilityStructure capletVol, - Matrix correlation, int factors) - : base(process.size(), factors) - { - diffusion_ = new Matrix(size_-1, factors_); - fixingTimes_= process.fixingTimes(); - - Matrix sqrtCorr = new Matrix(size_ - 1, factors_, 1.0); - if (correlation.empty()) { - Utils.QL_REQUIRE(factors_ == 1,()=> "correlation matrix must be given for multi factor models"); - } else { - Utils.QL_REQUIRE(correlation.rows() == size_-1 && - correlation.rows() == correlation.columns(),()=> "wrong dimesion of the correlation matrix"); - - Utils.QL_REQUIRE(factors_ <= size_-1,()=> "too many factors for given LFM process"); - - Matrix tmpSqrtCorr =MatrixUtilitites.pseudoSqrt(correlation, - MatrixUtilitites.SalvagingAlgorithm.Spectral); - - // reduce to n factor model - // "Reconstructing a valid correlation matrix from invalid data" - // () - for (int i=0; i < size_-1; ++i) { - double d = 0; - tmpSqrtCorr.row(i).GetRange(0, factors_).ForEach((ii, vv) => d += vv*tmpSqrtCorr.row(i)[ii]); - for (int k = 0; k < factors_; ++k){ - sqrtCorr[i, k] = tmpSqrtCorr.row(i).GetRange(0, factors_)[k] / Math.Sqrt(d); - } - } - } - List lambda=new List(); - DayCounter dayCounter = process.index().dayCounter(); - List fixingTimes = process.fixingTimes(); - List fixingDates = process.fixingDates(); - - for (int i = 1; i < size_; ++i) { - double cumVar = 0.0; - for (int j = 1; j < i; ++j) { - cumVar += lambda[i-j-1] * lambda[i-j-1] - * (fixingTimes[j+1] - fixingTimes[j]); - } - - double vol = capletVol.volatility(fixingDates[i], 0.0,false); - double var = vol * vol - * capletVol.dayCounter().yearFraction(fixingDates[0], - fixingDates[i]); - lambda.Add(Math.Sqrt( (var - cumVar) - / (fixingTimes[1] - fixingTimes[0])) ); - for (int q=0; q. - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet -{ - public class LiborForwardModelProcess : StochasticProcess - { - public int size_ { get; set; } - public IborIndex index_ { get; set; } - public LfmCovarianceParameterization lfmParam_ { get; set; } - public List initialValues_ { get; set; } - public List fixingTimes_ { get; set; } - public List fixingDates_ { get; set; } - public List accrualStartTimes_ { get; set; } - private List accrualEndTimes_; - public List accrualPeriod_ { get; set; } - - private Vector m1; - private Vector m2; - - public LiborForwardModelProcess(int size, IborIndex index, IDiscretization disc) - : base(disc ) - { - size_ = size; - index_ = index; - initialValues_ = new InitializedList(size_); - fixingTimes_ = new InitializedList(size); - fixingDates_ = new InitializedList(size_); - accrualStartTimes_ = new InitializedList(size); - accrualEndTimes_ = new InitializedList(size); - accrualPeriod_ = new InitializedList(size_); - m1 = new Vector(size_); - m2 = new Vector(size_); - DayCounter dayCounter = index.dayCounter(); - IList flows = cashFlows(1); - - Utils.QL_REQUIRE(size_ == flows.Count,()=> "wrong number of cashflows"); - - Date settlement = index_.forwardingTermStructure().link.referenceDate(); - Date startDate; - IborCoupon iborcoupon = (IborCoupon)flows[0]; - startDate = iborcoupon.fixingDate(); - - for (int i = 0; i < size_; ++i) - { - IborCoupon coupon = (IborCoupon)flows[i]; - - Utils.QL_REQUIRE(coupon.date() == coupon.accrualEndDate(),()=> "irregular coupon types are not suppported"); - - initialValues_[i]=coupon.rate(); - accrualPeriod_[i]=coupon.accrualPeriod(); - - fixingDates_[i]=coupon.fixingDate(); - fixingTimes_[i]=dayCounter.yearFraction(startDate, coupon.fixingDate()); - accrualStartTimes_[i]=dayCounter.yearFraction(settlement, coupon.accrualStartDate()); - accrualEndTimes_[i]=dayCounter.yearFraction(settlement, coupon.accrualEndDate()); - } - } - - public LiborForwardModelProcess(int size, IborIndex index) - : this( size, index,new EulerDiscretization()){} - - public override Vector drift(double t, Vector x) { - Vector f = new Vector(size_, 0.0); - Matrix covariance = lfmParam_.covariance(t, x); - int m = nextIndexReset(t); - - for (int k = m; k < size_; ++k) - { - m1[k] = accrualPeriod_[k] * x[k] / (1 + accrualPeriod_[k] * x[k]); - double inner_product = 0; - m1.GetRange(m, k + 1 - m).ForEach( - (ii, vv) => inner_product += vv * - covariance.column(k).GetRange(m, covariance.rows() - m)[ii]); - - f[k] = inner_product - 0.5 * covariance[k, k]; - } - return f; - } - - public override Matrix diffusion(double t, Vector x) { - return lfmParam_.diffusion(t, x); - } - - public override Matrix covariance(double t, Vector x, double dt) { - return lfmParam_.covariance(t, x) * dt; - } - - public override Vector apply(Vector x0, Vector dx) { - Vector tmp = new Vector(size_); - for (int k = 0; k < size_; ++k) { - tmp[k] = x0[k] * Math.Exp(dx[k]); - } - return tmp; - } - - public override Vector evolve(double t0, Vector x0, double dt, Vector dw) { - // predictor-corrector step to reduce discretization errors. - - int m = nextIndexReset(t0); - double sdt = Math.Sqrt(dt); - - Vector f = new Vector(x0); - Matrix diff = lfmParam_.diffusion(t0, x0); - Matrix covariance = lfmParam_.covariance(t0, x0); - - for (int k = m; k < size_; ++k) - { - double y = accrualPeriod_[k] * x0[k]; - m1[k] = y / (1 + y); - - double d = 0; - m1.GetRange(m, k + 1 - m).ForEach( - (ii, vv) => d += vv * - covariance.column(k).GetRange(m, covariance.rows()-m)[ii]); - d=(d -0.5 * covariance[k, k]) * dt; - - double r = 0; - diff.row(k).ForEach((kk, vv) => r += vv * dw[kk]); - r *= sdt; - - double x = y * Math.Exp(d + r); - m2[k] = x / (1 + x); - - double inner_product = 0; - m2.GetRange(m, k + 1 - m).ForEach( - (ii, vv) => inner_product += vv * - covariance.column(k).GetRange(m, covariance.rows() - m)[ii]); - f[k] = x0[k] * Math.Exp(0.5 * (d + (inner_product-0.5 * covariance[k, k]) * dt) + r); - } - - return f; - } - - public override Vector initialValues() { - Vector tmp = new Vector(size()); - for (int i = 0; i < size(); ++i) - tmp[i] = initialValues_[i]; - return tmp; - } - - public void setCovarParam(LfmCovarianceParameterization param) { - lfmParam_ = param; - } - - public LfmCovarianceParameterization covarParam() { - return lfmParam_; - } - - public IborIndex index() { - return index_; - } - - public List cashFlows(){ - return cashFlows(1); - } - - public List cashFlows(double amount) - { - Date refDate = index_.forwardingTermStructure().link.referenceDate(); - - Schedule schedule = new Schedule(refDate, - refDate + new Period(index_.tenor().length() * size_, - index_.tenor().units()), - index_.tenor(), index_.fixingCalendar(), - index_.businessDayConvention(), - index_.businessDayConvention(), - DateGeneration.Rule.Forward, false); - - IborLeg cashflows = (IborLeg) new IborLeg(schedule, index_) - .withFixingDays(index_.fixingDays()) - .withPaymentDayCounter(index_.dayCounter()) - .withNotionals(amount) - .withPaymentAdjustment(index_.businessDayConvention()); - return cashflows.value(); - } - - public override int size() { return size_; } - - public override int factors() { - return lfmParam_.factors(); - } - - public List fixingTimes() { - return fixingTimes_; - } - - public List fixingDates() { - return fixingDates_; - } - - public List accrualStartTimes(){ - return accrualStartTimes_; - } - - public List accrualEndTimes(){ - return accrualEndTimes_; - } - - public int nextIndexReset(double t) { - int result = fixingTimes_.FindIndex(x => x>t); - if (result < 0) - result = ~result - 1; - // impose limits. we need the one before last at max or the first at min - result = Math.Max(Math.Min(result, fixingTimes_.Count - 1),0); - return result; - } - - public List discountBond(List rates) { - - List discountFactors = new InitializedList(size_); - discountFactors[0] = 1.0 / (1.0 + rates[0] * accrualPeriod_[0]); - - for (int i = 1; i < size_; ++i) { - discountFactors[i] = - discountFactors[i - 1] / (1.0 + rates[i] * accrualPeriod_[i]); - } - return discountFactors; - } - } -} diff --git a/src/QLNet/legacy/libormarketmodels/lfmswaptionengine.cs b/src/QLNet/legacy/libormarketmodels/lfmswaptionengine.cs deleted file mode 100644 index e1bfd0600..000000000 --- a/src/QLNet/legacy/libormarketmodels/lfmswaptionengine.cs +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Linq; - -namespace QLNet -{ - //! %Libor forward model swaption engine based on Black formula - /*! \ingroup swaptionengines */ - public class LfmSwaptionEngine : GenericModelEngine - { - private Handle discountCurve_; - - public LfmSwaptionEngine(LiborForwardModel model, - Handle discountCurve) - : base(model) { - discountCurve_=discountCurve; - discountCurve_.registerWith(update); - } - - public override void calculate() - { - Utils.QL_REQUIRE(arguments_.settlementType == Settlement.Type.Physical,()=> - "cash-settled swaptions not priced with Lfm engine"); - - double basisPoint = 1.0e-4; - - VanillaSwap swap = arguments_.swap; - IPricingEngine pe=new DiscountingSwapEngine(discountCurve_); - swap.setPricingEngine(pe); - - double correction = swap.spread * - Math.Abs(swap.floatingLegBPS()/swap.fixedLegBPS()); - double fixedRate = swap.fixedRate - correction; - double fairRate = swap.fairRate() - correction; - - SwaptionVolatilityMatrix volatility = - model_.link.getSwaptionVolatilityMatrix(); - - Date referenceDate = volatility.referenceDate(); - DayCounter dayCounter = volatility.dayCounter(); - - double exercise = dayCounter.yearFraction(referenceDate, - arguments_.exercise.date(0)); - double swapLength = - dayCounter.yearFraction(referenceDate, - arguments_.fixedPayDates.Last()) - - dayCounter.yearFraction(referenceDate, - arguments_.fixedResetDates[0]); - - Option.Type w = arguments_.type==VanillaSwap.Type.Payer ? - Option.Type.Call : Option.Type.Put; - double vol = volatility.volatility(exercise, swapLength, - fairRate, true); - results_.value = (swap.fixedLegBPS()/basisPoint) * - Utils.blackFormula(w, fixedRate, fairRate, vol * Math.Sqrt(exercise)); - } - } -} diff --git a/src/QLNet/legacy/libormarketmodels/liborforwardmodel.cs b/src/QLNet/legacy/libormarketmodels/liborforwardmodel.cs deleted file mode 100644 index 72a957445..000000000 --- a/src/QLNet/legacy/libormarketmodels/liborforwardmodel.cs +++ /dev/null @@ -1,216 +0,0 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace QLNet -{ - public class LiborForwardModel : CalibratedModel, IAffineModel - { - List f_; - List accrualPeriod_; - - LfmCovarianceProxy covarProxy_; - LiborForwardModelProcess process_; - SwaptionVolatilityMatrix swaptionVola; - - public LiborForwardModel(LiborForwardModelProcess process, - LmVolatilityModel volaModel, - LmCorrelationModel corrModel) - : base(volaModel.parameters().Count + corrModel.parameters().Count) { - - f_ = new InitializedList(process.size()); - accrualPeriod_ = new InitializedList(process.size()); - covarProxy_=new LfmCovarianceProxy(volaModel, corrModel); - process_=process; - - int k=volaModel.parameters().Count; - for (int j = 0; j < k; j++) - arguments_[j] = volaModel.parameters()[j]; - for (int j = 0; j < corrModel.parameters().Count; j++) - arguments_[j+k] = corrModel.parameters()[j]; - - for (int i=0; i < process.size(); ++i) { - accrualPeriod_[i] = process.accrualEndTimes()[i] - - process.accrualStartTimes()[i]; - f_[i] = 1.0/(1.0+accrualPeriod_[i]*process_.initialValues()[i]); - } - } - - - - public override void setParams( Vector parameters) { - base.setParams(parameters); - - int k=covarProxy_.volatilityModel().parameters().Count; - - covarProxy_.volatilityModel().setParams(new List(arguments_.GetRange(0, k))); - covarProxy_.correlationModel().setParams(new List(arguments_.GetRange(k, arguments_.Count-k))); - - swaptionVola = null; - } - - - public double discountBondOption(Option.Type type, - double strike, double maturity, - double bondMaturity) { - - List accrualStartTimes - = process_.accrualStartTimes(); - List accrualEndTimes - = process_.accrualEndTimes(); - - Utils.QL_REQUIRE(accrualStartTimes.First() <= maturity && accrualStartTimes.Last() >= maturity,()=> - "capet maturity does not fit to the process"); - - int i = accrualStartTimes.BinarySearch(maturity); - if (i < 0) - // The lower_bound() algorithm finds the first position in a sequence that value can occupy - // without violating the sequence's ordering - // if BinarySearch does not find value the value, the index of the prev minor item is returned - i = ~i + 1; - - // impose limits. we need the one before last at max or the first at min - i = Math.Max(Math.Min(i, accrualStartTimes.Count - 1), 0); - - Utils.QL_REQUIRE(i - "irregular fixings are not (yet) supported"); - - double tenor = accrualEndTimes[i] - accrualStartTimes[i]; - double forward = process_.initialValues()[i]; - double capRate = (1.0/strike - 1.0)/tenor; - double var = covarProxy_.integratedCovariance(i, i, process_.fixingTimes()[i] ); - double dis = process_.index().forwardingTermStructure().link.discount(bondMaturity); - - double black = Utils.blackFormula( - (type == Option.Type.Put ? Option.Type.Call : Option.Type.Put), - capRate, forward, Math.Sqrt(var)); - - double npv = dis * tenor * black; - - return npv / (1.0 + capRate*tenor); - } - - public double discount(double t) { - return process_.index().forwardingTermStructure().link.discount(t); - } - - public double discountBond(double t,double maturity,Vector v) { - return discount(maturity); - } - - public Vector w_0(int alpha, int beta) -{ - Vector omega = new Vector(beta + 1, 0.0); - Utils.QL_REQUIRE(alpha "alpha needs to be smaller than beta"); - - double s=0.0; - for (int k=alpha+1; k<=beta; ++k) { - double b = accrualPeriod_[k]; - for (int j=alpha+1; j<=k; ++j) { - b*=f_[j]; - } - s+=b; - } - - for (int i = alpha + 1; i <= beta; ++i){ - double a = accrualPeriod_[i]; - for (int j = alpha + 1; j <= i; ++j){ - a*=f_[j]; - } - omega[i] = a/s; - } - return omega; - } - - public double S_0(int alpha, int beta) { - Vector w = w_0(alpha, beta); - Vector f = process_.initialValues(); - - double fwdRate=0.0; - for (int i=alpha+1; i <=beta; ++i) { - fwdRate+=w[i]*f[i]; - } - return fwdRate; - } - - - // calculating swaption volatility matrix using - // Rebonatos approx. formula. Be aware that this - // matrix is valid only for regular fixings and - // assumes that the fix and floating leg have the - // same frequency - public SwaptionVolatilityMatrix getSwaptionVolatilityMatrix() - { - if (swaptionVola!=null) { - return swaptionVola; - } - - IborIndex index = process_.index(); - Date today = process_.fixingDates()[0]; - - int size=process_.size()/2; - Matrix volatilities=new Matrix(size, size); - - List exercises = new InitializedList(size); - for (int i = 0; i < size; ++i){ - exercises[i]=process_.fixingDates()[i+1]; - } - - List lengths = new InitializedList(size); - for (int i=0; i < size; ++i) { - lengths[i] = (i+1)*index.tenor(); - } - - Vector f = process_.initialValues(); - for (int k=0; k < size; ++k) { - int alpha =k; - double t_alpha=process_.fixingTimes()[alpha+1]; - - Matrix var=new Matrix(size, size); - for (int i=alpha+1; i <= k+size; ++i) { - for (int j=i; j <= k+size; ++j) { - var[i-alpha-1,j-alpha-1] = var[j-alpha-1,i-alpha-1] = - covarProxy_.integratedCovariance(i, j, t_alpha,null); - } - } - - for (int l=1; l <= size; ++l) { - int beta =l + k; - Vector w = w_0(alpha, beta); - - double sum=0.0; - for (int i=alpha+1; i <= beta; ++i) { - for (int j=alpha+1; j <= beta; ++j) { - sum+=w[i]*w[j]*f[i]*f[j]*var[i-alpha-1,j-alpha-1]; - } - } - volatilities[k,l-1] = - Math.Sqrt(sum/t_alpha)/S_0(alpha, beta); - } - } - - return swaptionVola = new SwaptionVolatilityMatrix( today, exercises, lengths, - volatilities,index.dayCounter()); - } - } -} diff --git a/src/QLNet/payoff.cs b/src/QLNet/payoff.cs deleted file mode 100644 index 8f887138c..000000000 --- a/src/QLNet/payoff.cs +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; - -namespace QLNet { - //! Abstract base class for option payoffs - public class Payoff { - // Payoff interface - /*! \warning This method is used for output and comparison between - payoffs. It is not meant to be used for writing - switch-on-type code. - */ - public virtual string name() { throw new NotImplementedException(); } - public virtual string description() { throw new NotImplementedException(); } - public virtual double value(double price) { throw new NotImplementedException(); } - - public virtual void accept(IAcyclicVisitor v) { - if (v != null) - v.visit(this); - else - Utils.QL_FAIL("not an event visitor"); - } - } -} diff --git a/src/QLNet/processes/BlackScholesProcess.cs b/src/QLNet/processes/BlackScholesProcess.cs index d7d53ba8d..d4bab3a00 100644 --- a/src/QLNet/processes/BlackScholesProcess.cs +++ b/src/QLNet/processes/BlackScholesProcess.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -36,9 +36,9 @@ the internal calculations work on \f$ ln S \f$. public class GeneralizedBlackScholesProcess : StochasticProcess1D { - public GeneralizedBlackScholesProcess( Handle x0, Handle dividendTS, - Handle riskFreeTS, Handle blackVolTS, IDiscretization1D disc = null ) - : base( disc ?? new EulerDiscretization() ) + public GeneralizedBlackScholesProcess(Handle x0, Handle dividendTS, + Handle riskFreeTS, Handle blackVolTS, IDiscretization1D disc = null) + : base(disc ?? new EulerDiscretization()) { x0_ = x0; riskFreeRate_ = riskFreeTS; @@ -46,30 +46,30 @@ public GeneralizedBlackScholesProcess( Handle x0, Handle x0, Handle dividendTS, - Handle riskFreeTS, Handle blackVolTS, - RelinkableHandle localVolTS, IDiscretization1D disc = null) - : base(disc ?? new EulerDiscretization()) + Handle riskFreeTS, Handle blackVolTS, + RelinkableHandle localVolTS, IDiscretization1D disc = null) + : base(disc ?? new EulerDiscretization()) { - x0_ = x0; - riskFreeRate_ = riskFreeTS; - dividendYield_ = dividendTS; - blackVolatility_ = blackVolTS; - localVolatility_ = localVolTS != null ? (localVolTS.empty() ? new RelinkableHandle() : localVolTS) - : new RelinkableHandle(); - updated_ = !localVolatility_.empty(); - - x0_.registerWith(update); - riskFreeRate_.registerWith(update); - dividendYield_.registerWith(update); - blackVolatility_.registerWith(update); - localVolatility_.registerWith(update); + x0_ = x0; + riskFreeRate_ = riskFreeTS; + dividendYield_ = dividendTS; + blackVolatility_ = blackVolTS; + localVolatility_ = localVolTS != null ? (localVolTS.empty() ? new RelinkableHandle() : localVolTS) + : new RelinkableHandle(); + updated_ = !localVolatility_.empty(); + + x0_.registerWith(update); + riskFreeRate_.registerWith(update); + dividendYield_.registerWith(update); + blackVolatility_.registerWith(update); + localVolatility_.registerWith(update); } public override double x0() @@ -78,96 +78,96 @@ public override double x0() } /*! \todo revise extrapolation */ - public override double drift( double t, double x ) + public override double drift(double t, double x) { - double sigma = diffusion( t, x ); + double sigma = diffusion(t, x); // we could be more anticipatory if we know the right dt for which the drift will be used double t1 = t + 0.0001; - return riskFreeRate_.link.forwardRate( t, t1, Compounding.Continuous, Frequency.NoFrequency, true ).rate() - - dividendYield_.link.forwardRate( t, t1, Compounding.Continuous, Frequency.NoFrequency, true ).rate() + return riskFreeRate_.link.forwardRate(t, t1, Compounding.Continuous, Frequency.NoFrequency, true).rate() + - dividendYield_.link.forwardRate(t, t1, Compounding.Continuous, Frequency.NoFrequency, true).rate() - 0.5 * sigma * sigma; } /*! \todo revise extrapolation */ - public override double diffusion( double t, double x ) + public override double diffusion(double t, double x) { - return localVolatility().link.localVol( t, x, true ); + return localVolatility().link.localVol(t, x, true); } - public override double apply( double x0, double dx ) + public override double apply(double x0, double dx) { - return x0 * Math.Exp( dx ); + return x0 * Math.Exp(dx); } /*! \warning raises a "not implemented" exception. It should be rewritten to return the expectation E(S) of the process, not exp(E(log S)). */ - public override double expectation( double t0, double x0, double dt ) + public override double expectation(double t0, double x0, double dt) { localVolatility(); // trigger update - if ( isStrikeIndependent_ ) + if (isStrikeIndependent_) { // exact value for curves return x0 * - Math.Exp( dt * ( riskFreeRate_.link.forwardRate( t0, t0 + dt, Compounding.Continuous, - Frequency.NoFrequency, true ).value() - - dividendYield_.link.forwardRate( - t0, t0 + dt, Compounding.Continuous, Frequency.NoFrequency, true ).value() ) ); + Math.Exp(dt * (riskFreeRate_.link.forwardRate(t0, t0 + dt, Compounding.Continuous, + Frequency.NoFrequency, true).value() - + dividendYield_.link.forwardRate( + t0, t0 + dt, Compounding.Continuous, Frequency.NoFrequency, true).value())); } else { - Utils.QL_FAIL( "not implemented" ); + Utils.QL_FAIL("not implemented"); return 0; } } public override double stdDeviation(double t0, double x0, double dt) { localVolatility(); // trigger update - if(isStrikeIndependent_) + if (isStrikeIndependent_) { // exact value for curves - return Math.Sqrt(variance(t0,x0,dt)); + return Math.Sqrt(variance(t0, x0, dt)); } else { - return discretization_.diffusion(this,t0,x0,dt); + return discretization_.diffusion(this, t0, x0, dt); } - } + } public override double variance(double t0, double x0, double dt) { localVolatility(); // trigger update - if ( isStrikeIndependent_ ) + if (isStrikeIndependent_) { // exact value for curves - return blackVolatility_.link.blackVariance( t0 + dt, 0.01 ) - - blackVolatility_.link.blackVariance( t0, 0.01 ); + return blackVolatility_.link.blackVariance(t0 + dt, 0.01) - + blackVolatility_.link.blackVariance(t0, 0.01); } else { - return discretization_.variance( this, t0, x0, dt ); + return discretization_.variance(this, t0, x0, dt); } } public override double evolve(double t0, double x0, double dt, double dw) { localVolatility(); // trigger update - if (isStrikeIndependent_) + if (isStrikeIndependent_) { // exact value for curves double var = variance(t0, x0, dt); double drift = (riskFreeRate_.link.forwardRate(t0, t0 + dt, Compounding.Continuous, - Frequency.NoFrequency, true).value() - - dividendYield_.link.forwardRate(t0, t0 + dt, Compounding.Continuous, - Frequency.NoFrequency, true).value()) * - dt - 0.5 * var; + Frequency.NoFrequency, true).value() - + dividendYield_.link.forwardRate(t0, t0 + dt, Compounding.Continuous, + Frequency.NoFrequency, true).value()) * + dt - 0.5 * var; return apply(x0, Math.Sqrt(var) * dw + drift); - } + } else - return apply(x0, discretization_.drift(this, t0, x0, dt) + stdDeviation(t0, x0, dt) * dw); + return apply(x0, discretization_.drift(this, t0, x0, dt) + stdDeviation(t0, x0, dt) * dw); } - public override double time( Date d ) + public override double time(Date d) { - return riskFreeRate_.link.dayCounter().yearFraction( riskFreeRate_.link.referenceDate(), d ); + return riskFreeRate_.link.dayCounter().yearFraction(riskFreeRate_.link.referenceDate(), d); } public override void update() { @@ -192,35 +192,35 @@ public Handle blackVolatility() } public Handle localVolatility() { - if ( !updated_ ) + if (!updated_) { isStrikeIndependent_ = true; // constant Black vol? BlackConstantVol constVol = blackVolatility().link as BlackConstantVol; - if ( constVol != null ) + if (constVol != null) { // ok, the local vol is constant too. - localVolatility_.linkTo( new LocalConstantVol( constVol.referenceDate(), - constVol.blackVol( 0.0, x0_.link.value() ), - constVol.dayCounter() ) ); + localVolatility_.linkTo(new LocalConstantVol(constVol.referenceDate(), + constVol.blackVol(0.0, x0_.link.value()), + constVol.dayCounter())); updated_ = true; return localVolatility_; } // ok, so it's not constant. Maybe it's strike-independent? BlackVarianceCurve volCurve = blackVolatility().link as BlackVarianceCurve; - if ( volCurve != null ) + if (volCurve != null) { // ok, we can use the optimized algorithm - localVolatility_.linkTo( new LocalVolCurve( new Handle( volCurve ) ) ); + localVolatility_.linkTo(new LocalVolCurve(new Handle(volCurve))); updated_ = true; return localVolatility_; } // ok, so it's strike-dependent. Never mind. - localVolatility_.linkTo( new LocalVolSurface( blackVolatility_, riskFreeRate_, dividendYield_, - x0_.link.value() ) ); + localVolatility_.linkTo(new LocalVolSurface(blackVolatility_, riskFreeRate_, dividendYield_, + x0_.link.value())); updated_ = true; isStrikeIndependent_ = false; return localVolatility_; @@ -230,7 +230,7 @@ public Handle localVolatility() return localVolatility_; } } - + private Handle x0_; private Handle riskFreeRate_, dividendYield_; private Handle blackVolatility_; @@ -250,19 +250,19 @@ public Handle localVolatility() public class BlackScholesProcess : GeneralizedBlackScholesProcess { public BlackScholesProcess(Handle x0, - Handle riskFreeTS, - Handle blackVolTS) + Handle riskFreeTS, + Handle blackVolTS) : this(x0, riskFreeTS, blackVolTS, new EulerDiscretization()) {} public BlackScholesProcess(Handle x0, - Handle riskFreeTS, - Handle blackVolTS, - IDiscretization1D d) + Handle riskFreeTS, + Handle blackVolTS, + IDiscretization1D d) : base(x0, - // no dividend yield - new Handle(new FlatForward(0, new NullCalendar(), 0.0, new Actual365Fixed())), - riskFreeTS, blackVolTS, d) + // no dividend yield + new Handle(new FlatForward(0, new NullCalendar(), 0.0, new Actual365Fixed())), + riskFreeTS, blackVolTS, d) {} } @@ -280,17 +280,17 @@ stock index paying a continuous dividend yield given by public class BlackScholesMertonProcess : GeneralizedBlackScholesProcess { public BlackScholesMertonProcess(Handle x0, - Handle dividendTS, - Handle riskFreeTS, - Handle blackVolTS) + Handle dividendTS, + Handle riskFreeTS, + Handle blackVolTS) : this(x0, dividendTS, riskFreeTS, blackVolTS, new EulerDiscretization()) {} public BlackScholesMertonProcess(Handle x0, - Handle dividendTS, - Handle riskFreeTS, - Handle blackVolTS, - IDiscretization1D d) + Handle dividendTS, + Handle riskFreeTS, + Handle blackVolTS, + IDiscretization1D d) : base(x0, dividendTS, riskFreeTS, blackVolTS, d) {} } @@ -308,15 +308,15 @@ futures contract given by public class BlackProcess : GeneralizedBlackScholesProcess { public BlackProcess(Handle x0, - Handle riskFreeTS, - Handle blackVolTS) + Handle riskFreeTS, + Handle blackVolTS) : this(x0, riskFreeTS, blackVolTS, new EulerDiscretization()) {} public BlackProcess(Handle x0, - Handle riskFreeTS, - Handle blackVolTS, - IDiscretization1D d) + Handle riskFreeTS, + Handle blackVolTS, + IDiscretization1D d) : base(x0, riskFreeTS, riskFreeTS, blackVolTS, d) {} } @@ -335,23 +335,23 @@ rate given by public class GarmanKohlagenProcess : GeneralizedBlackScholesProcess { public GarmanKohlagenProcess(Handle x0, - Handle foreignRiskFreeTS, - Handle domesticRiskFreeTS, - Handle blackVolTS) + Handle foreignRiskFreeTS, + Handle domesticRiskFreeTS, + Handle blackVolTS) : this(x0, foreignRiskFreeTS, domesticRiskFreeTS, blackVolTS, new EulerDiscretization()) {} public GarmanKohlagenProcess(Handle x0, Handle foreignRiskFreeTS, - Handle domesticRiskFreeTS, - Handle blackVolTS, IDiscretization1D d) + Handle domesticRiskFreeTS, + Handle blackVolTS, IDiscretization1D d) : base(x0, foreignRiskFreeTS, domesticRiskFreeTS, blackVolTS, d) {} - public GarmanKohlagenProcess(Handle x0, Handle foreignRiskFreeTS, - Handle domesticRiskFreeTS, - Handle blackVolTS, - RelinkableHandle localVolTS, - IDiscretization1D d = null) + public GarmanKohlagenProcess(Handle x0, Handle foreignRiskFreeTS, + Handle domesticRiskFreeTS, + Handle blackVolTS, + RelinkableHandle localVolTS, + IDiscretization1D d = null) : base(x0, foreignRiskFreeTS, domesticRiskFreeTS, blackVolTS, localVolTS, d) {} diff --git a/src/QLNet/processes/Defaultable.cs b/src/QLNet/processes/Defaultable.cs index fabb57566..c2c0c4e93 100644 --- a/src/QLNet/processes/Defaultable.cs +++ b/src/QLNet/processes/Defaultable.cs @@ -1,79 +1,80 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { +namespace QLNet +{ - public abstract class Defaultable - { - public abstract double defaultRecovery(double t, double underlying); - public abstract double hazardRate(double t, double underlying); - } + public abstract class Defaultable + { + public abstract double defaultRecovery(double t, double underlying); + public abstract double hazardRate(double t, double underlying); + } - public class NegativePowerDefaultIntensity : Defaultable - { - private double alpha_; - private double p_; - private double recovery_; - public NegativePowerDefaultIntensity(double alpha, double p) : this(alpha, p, 0.0) - { - } + public class NegativePowerDefaultIntensity : Defaultable + { + private double alpha_; + private double p_; + private double recovery_; + public NegativePowerDefaultIntensity(double alpha, double p) : this(alpha, p, 0.0) + { + } - public NegativePowerDefaultIntensity(double alpha, double p, double recovery) - { - alpha_ = alpha; - p_ = p; - recovery_ = recovery; - } - public override double hazardRate(double t, double s) - { - if (s <= 0.0) - return 0.0; + public NegativePowerDefaultIntensity(double alpha, double p, double recovery) + { + alpha_ = alpha; + p_ = p; + recovery_ = recovery; + } + public override double hazardRate(double t, double s) + { + if (s <= 0.0) + return 0.0; - return alpha_ * Math.Pow(s, -p_); - } - public override double defaultRecovery(double t, double s) - { - return recovery_; - } - } + return alpha_ * Math.Pow(s, -p_); + } + public override double defaultRecovery(double t, double s) + { + return recovery_; + } + } - public class ConstantDefaultIntensity : Defaultable - { - private double constant_; - private double recovery_; - public ConstantDefaultIntensity(double constant) : this(constant, 0.0) - { - } - public ConstantDefaultIntensity(double constant, double recovery) - { - constant_ = constant; - recovery_ = recovery; - } - public override double hazardRate(double t, double s) - { - return constant_; - } - public override double defaultRecovery(double t, double s) - { - return recovery_; - } - } + public class ConstantDefaultIntensity : Defaultable + { + private double constant_; + private double recovery_; + public ConstantDefaultIntensity(double constant) : this(constant, 0.0) + { + } + public ConstantDefaultIntensity(double constant, double recovery) + { + constant_ = constant; + recovery_ = recovery; + } + public override double hazardRate(double t, double s) + { + return constant_; + } + public override double defaultRecovery(double t, double s) + { + return recovery_; + } + } } diff --git a/src/QLNet/processes/EulerDiscretization.cs b/src/QLNet/processes/EulerDiscretization.cs index a6a16e8e0..9069e84ab 100644 --- a/src/QLNet/processes/EulerDiscretization.cs +++ b/src/QLNet/processes/EulerDiscretization.cs @@ -1,63 +1,71 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { - //! Euler discretization for stochastic processes - public class EulerDiscretization : IDiscretization, IDiscretization1D { - /*! Returns an approximation of the drift defined as - \f$ \mu(t_0, \mathbf{x}_0) \Delta t \f$. */ - public Vector drift(StochasticProcess process, double t0, Vector x0, double dt) { - return process.drift(t0, x0)*dt; - } - - /*! Returns an approximation of the drift defined as - \f$ \mu(t_0, x_0) \Delta t \f$. */ - public double drift(StochasticProcess1D process, double t0, double x0, double dt) { - return process.drift(t0, x0)*dt; - } - - /*! Returns an approximation of the diffusion defined as - \f$ \sigma(t_0, \mathbf{x}_0) \sqrt{\Delta t} \f$. */ - public Matrix diffusion(StochasticProcess process, double t0, Vector x0, double dt) { - return process.diffusion(t0, x0) * Math.Sqrt(dt); - } - - /*! Returns an approximation of the diffusion defined as - \f$ \sigma(t_0, x_0) \sqrt{\Delta t} \f$. */ - public double diffusion(StochasticProcess1D process, double t0, double x0, double dt) { - return process.diffusion(t0, x0) * Math.Sqrt(dt); - } - - /*! Returns an approximation of the covariance defined as - \f$ \sigma(t_0, \mathbf{x}_0)^2 \Delta t \f$. */ - public Matrix covariance(StochasticProcess process, double t0, Vector x0, double dt) { - Matrix sigma = process.diffusion(t0, x0); - Matrix result = sigma * Matrix.transpose(sigma) * dt; - return result; - } - - /*! Returns an approximation of the variance defined as - \f$ \sigma(t_0, x_0)^2 \Delta t \f$. */ - public double variance(StochasticProcess1D process, double t0, double x0, double dt) { - double sigma = process.diffusion(t0, x0); - return sigma*sigma*dt; - } - } +namespace QLNet +{ + //! Euler discretization for stochastic processes + public class EulerDiscretization : IDiscretization, IDiscretization1D + { + /*! Returns an approximation of the drift defined as + \f$ \mu(t_0, \mathbf{x}_0) \Delta t \f$. */ + public Vector drift(StochasticProcess process, double t0, Vector x0, double dt) + { + return process.drift(t0, x0) * dt; + } + + /*! Returns an approximation of the drift defined as + \f$ \mu(t_0, x_0) \Delta t \f$. */ + public double drift(StochasticProcess1D process, double t0, double x0, double dt) + { + return process.drift(t0, x0) * dt; + } + + /*! Returns an approximation of the diffusion defined as + \f$ \sigma(t_0, \mathbf{x}_0) \sqrt{\Delta t} \f$. */ + public Matrix diffusion(StochasticProcess process, double t0, Vector x0, double dt) + { + return process.diffusion(t0, x0) * Math.Sqrt(dt); + } + + /*! Returns an approximation of the diffusion defined as + \f$ \sigma(t_0, x_0) \sqrt{\Delta t} \f$. */ + public double diffusion(StochasticProcess1D process, double t0, double x0, double dt) + { + return process.diffusion(t0, x0) * Math.Sqrt(dt); + } + + /*! Returns an approximation of the covariance defined as + \f$ \sigma(t_0, \mathbf{x}_0)^2 \Delta t \f$. */ + public Matrix covariance(StochasticProcess process, double t0, Vector x0, double dt) + { + Matrix sigma = process.diffusion(t0, x0); + Matrix result = sigma * Matrix.transpose(sigma) * dt; + return result; + } + + /*! Returns an approximation of the variance defined as + \f$ \sigma(t_0, x_0)^2 \Delta t \f$. */ + public double variance(StochasticProcess1D process, double t0, double x0, double dt) + { + double sigma = process.diffusion(t0, x0); + return sigma * sigma * dt; + } + } } diff --git a/src/QLNet/processes/ForwardMeasureProcess.cs b/src/QLNet/processes/ForwardMeasureProcess.cs index dda3f0b50..f83cf4b33 100644 --- a/src/QLNet/processes/ForwardMeasureProcess.cs +++ b/src/QLNet/processes/ForwardMeasureProcess.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -31,14 +31,14 @@ public virtual void setForwardMeasureTime(double T) notifyObservers(); } public double getForwardMeasureTime() { return T_; } - + protected ForwardMeasureProcess() {} protected ForwardMeasureProcess(double T) { T_ = T; } protected ForwardMeasureProcess(IDiscretization disc) - :base(disc) + : base(disc) {} protected double T_; @@ -69,26 +69,26 @@ forward measure. \ingroup processes */ - public class ForwardMeasureProcess1D :StochasticProcess1D + public class ForwardMeasureProcess1D : StochasticProcess1D { - public virtual void setForwardMeasureTime(double T ) + public virtual void setForwardMeasureTime(double T) { T_ = T; - notifyObservers(); + notifyObservers(); } public double getForwardMeasureTime() { return T_; } - + protected ForwardMeasureProcess1D() {} protected ForwardMeasureProcess1D(double T) { T_ = T; } protected ForwardMeasureProcess1D(IDiscretization1D disc) - :base(disc) {} - + : base(disc) {} + protected double T_; public override double x0() { diff --git a/src/QLNet/processes/GeometricBrownianMotionProcess.cs b/src/QLNet/processes/GeometricBrownianMotionProcess.cs index 471b04313..6d06488e8 100644 --- a/src/QLNet/processes/GeometricBrownianMotionProcess.cs +++ b/src/QLNet/processes/GeometricBrownianMotionProcess.cs @@ -1,53 +1,59 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ -namespace QLNet { - //! Geometric brownian-motion process - /*! This class describes the stochastic process governed by - \f[ - dS(t, S)= \mu S dt + \sigma S dW_t. - \f] - - \ingroup processes - */ - public class GeometricBrownianMotionProcess : StochasticProcess1D { - protected double initialValue_; - protected double mue_; - protected double sigma_; - - public GeometricBrownianMotionProcess(double initialValue, double mue, double sigma) - : base(new EulerDiscretization()) { - initialValue_ = initialValue; - mue_ = mue; - sigma_ = sigma; - } - - public override double x0() { - return initialValue_; - } - - public override double drift(double t, double x) { - return mue_ * x; - } - - public override double diffusion(double t, double x) { - return sigma_ * x; - } - } +namespace QLNet +{ + //! Geometric brownian-motion process + /*! This class describes the stochastic process governed by + \f[ + dS(t, S)= \mu S dt + \sigma S dW_t. + \f] + + \ingroup processes + */ + public class GeometricBrownianMotionProcess : StochasticProcess1D + { + protected double initialValue_; + protected double mue_; + protected double sigma_; + + public GeometricBrownianMotionProcess(double initialValue, double mue, double sigma) + : base(new EulerDiscretization()) + { + initialValue_ = initialValue; + mue_ = mue; + sigma_ = sigma; + } + + public override double x0() + { + return initialValue_; + } + + public override double drift(double t, double x) + { + return mue_ * x; + } + + public override double diffusion(double t, double x) + { + return sigma_ * x; + } + } } diff --git a/src/QLNet/processes/HestonProcess.cs b/src/QLNet/processes/HestonProcess.cs index 5619c60df..5608f0bb7 100644 --- a/src/QLNet/processes/HestonProcess.cs +++ b/src/QLNet/processes/HestonProcess.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -30,37 +30,38 @@ public enum Discretization { PartialTruncation, QuadraticExponentialMartingale, BroadieKayaExactSchemeLobatto, BroadieKayaExactSchemeLaguerre, - BroadieKayaExactSchemeTrapezoidal } - - public HestonProcess( Handle riskFreeRate, - Handle dividendYield, - Handle s0, - double v0, double kappa, - double theta, double sigma, double rho, - Discretization d = Discretization.QuadraticExponentialMartingale) - :base(new EulerDiscretization()) + BroadieKayaExactSchemeTrapezoidal + } + + public HestonProcess(Handle riskFreeRate, + Handle dividendYield, + Handle s0, + double v0, double kappa, + double theta, double sigma, double rho, + Discretization d = Discretization.QuadraticExponentialMartingale) + : base(new EulerDiscretization()) { - riskFreeRate_ = riskFreeRate; - dividendYield_ = dividendYield; + riskFreeRate_ = riskFreeRate; + dividendYield_ = dividendYield; s0_ = s0; - v0_ = v0; - kappa_ = kappa; - theta_ = theta; - sigma_ = sigma; + v0_ = v0; + kappa_ = kappa; + theta_ = theta; + sigma_ = sigma; rho_ = rho; discretization_ = d; riskFreeRate_.registerWith(update); - dividendYield_.registerWith( update ) ; - s0_.registerWith( update ) ; + dividendYield_.registerWith(update) ; + s0_.registerWith(update) ; } public override int size() { return 2; } public override int factors() { - return ( discretization_ == Discretization.BroadieKayaExactSchemeLobatto - || discretization_ == Discretization.BroadieKayaExactSchemeTrapezoidal - || discretization_ == Discretization.BroadieKayaExactSchemeLaguerre ) ? 3 : 2; + return (discretization_ == Discretization.BroadieKayaExactSchemeLobatto + || discretization_ == Discretization.BroadieKayaExactSchemeTrapezoidal + || discretization_ == Discretization.BroadieKayaExactSchemeLaguerre) ? 3 : 2; } public override Vector initialValues() @@ -68,22 +69,22 @@ public override Vector initialValues() Vector tmp = new Vector(2); tmp[0] = s0_.link.value(); tmp[1] = v0_; - return tmp; + return tmp; } public override Vector drift(double t, Vector x) { Vector tmp = new Vector(2); double vol = (x[1] > 0.0) ? Math.Sqrt(x[1]) - : (discretization_ == Discretization.Reflection) ? - Math.Sqrt(-x[1]) - : 0.0; + : (discretization_ == Discretization.Reflection) ? - Math.Sqrt(-x[1]) + : 0.0; - tmp[0] = riskFreeRate_.link.forwardRate(t, t, Compounding.Continuous).value() - - dividendYield_.link.forwardRate( t, t, Compounding.Continuous ).value() - - 0.5 * vol * vol; + tmp[0] = riskFreeRate_.link.forwardRate(t, t, Compounding.Continuous).value() + - dividendYield_.link.forwardRate(t, t, Compounding.Continuous).value() + - 0.5 * vol * vol; - tmp[1] = kappa_* ( theta_ - ( ( discretization_ == Discretization.PartialTruncation ) ? x[1] : vol * vol ) ); - return tmp; + tmp[1] = kappa_ * (theta_ - ((discretization_ == Discretization.PartialTruncation) ? x[1] : vol * vol)); + return tmp; } public override Matrix diffusion(double t, Vector x) @@ -95,26 +96,26 @@ whose square root (which is used here) is | 1 0 | | rho sqrt(1-rho^2) | */ - Matrix tmp = new Matrix(2,2); + Matrix tmp = new Matrix(2, 2); double vol = (x[1] > 0.0) ? Math.Sqrt(x[1]) - : (discretization_ == Discretization.Reflection) ? -Math.Sqrt(-x[1]) - : 1e-8; // set vol to (almost) zero but still - // expose some correlation information + : (discretization_ == Discretization.Reflection) ? -Math.Sqrt(-x[1]) + : 1e-8; // set vol to (almost) zero but still + // expose some correlation information double sigma2 = sigma_ * vol; - double sqrhov = Math.Sqrt(1.0 - rho_*rho_); + double sqrhov = Math.Sqrt(1.0 - rho_ * rho_); - tmp[0,0] = vol; tmp[0,1] = 0.0; - tmp[1,0] = rho_*sigma2; tmp[1,1] = sqrhov*sigma2; + tmp[0, 0] = vol; tmp[0, 1] = 0.0; + tmp[1, 0] = rho_ * sigma2; tmp[1, 1] = sqrhov * sigma2; return tmp; - + } - public override Vector apply( Vector x0, Vector dx) + public override Vector apply(Vector x0, Vector dx) { Vector tmp = new Vector(2); tmp[0] = x0[0] * Math.Exp(dx[0]); tmp[1] = x0[1] + dx[1]; - return tmp; + return tmp; } public override Vector evolve(double t0, Vector x0, double dt, Vector dw) @@ -123,9 +124,9 @@ public override Vector evolve(double t0, Vector x0, double dt, Vector dw) double vol, vol2, mu, nu, dy; double sdt = Math.Sqrt(dt); - double sqrhov = Math.Sqrt(1.0 - rho_*rho_); + double sqrhov = Math.Sqrt(1.0 - rho_ * rho_); - switch (discretization_) + switch (discretization_) { // For the definition of PartialTruncation, FullTruncation // and Reflection see Lord, R., R. Koekkoek and D. van Dijk (2006), @@ -135,36 +136,36 @@ public override Vector evolve(double t0, Vector x0, double dt, Vector dw) case Discretization.PartialTruncation: vol = (x0[1] > 0.0) ? Math.Sqrt(x0[1]) : 0.0; vol2 = sigma_ * vol; - mu = riskFreeRate_.link.forwardRate(t0, t0+dt, Compounding.Continuous).value() - - dividendYield_.link.forwardRate(t0, t0+dt, Compounding.Continuous).value() - - 0.5 * vol * vol; - nu = kappa_*(theta_ - x0[1]); + mu = riskFreeRate_.link.forwardRate(t0, t0 + dt, Compounding.Continuous).value() + - dividendYield_.link.forwardRate(t0, t0 + dt, Compounding.Continuous).value() + - 0.5 * vol * vol; + nu = kappa_ * (theta_ - x0[1]); - retVal[0] = x0[0] * Math.Exp(mu*dt+vol*dw[0]*sdt); - retVal[1] = x0[1] + nu*dt + vol2*sdt*(rho_*dw[0] + sqrhov*dw[1]); + retVal[0] = x0[0] * Math.Exp(mu * dt + vol * dw[0] * sdt); + retVal[1] = x0[1] + nu * dt + vol2 * sdt * (rho_ * dw[0] + sqrhov * dw[1]); break; case Discretization.FullTruncation: vol = (x0[1] > 0.0) ? Math.Sqrt(x0[1]) : 0.0; vol2 = sigma_ * vol; - mu = riskFreeRate_.link.forwardRate(t0, t0+dt, Compounding.Continuous).value() - - dividendYield_.link.forwardRate(t0, t0+dt, Compounding.Continuous).value() - - 0.5 * vol * vol; - nu = kappa_*(theta_ - vol*vol); + mu = riskFreeRate_.link.forwardRate(t0, t0 + dt, Compounding.Continuous).value() + - dividendYield_.link.forwardRate(t0, t0 + dt, Compounding.Continuous).value() + - 0.5 * vol * vol; + nu = kappa_ * (theta_ - vol * vol); - retVal[0] = x0[0] * Math.Exp(mu*dt+vol*dw[0]*sdt); - retVal[1] = x0[1] + nu*dt + vol2*sdt*(rho_*dw[0] + sqrhov*dw[1]); + retVal[0] = x0[0] * Math.Exp(mu * dt + vol * dw[0] * sdt); + retVal[1] = x0[1] + nu * dt + vol2 * sdt * (rho_ * dw[0] + sqrhov * dw[1]); break; case Discretization.Reflection: vol = Math.Sqrt(Math.Abs(x0[1])); vol2 = sigma_ * vol; - mu = riskFreeRate_.link.forwardRate(t0, t0+dt, Compounding.Continuous).value() - - dividendYield_.link.forwardRate(t0, t0+dt, Compounding.Continuous).value() - - 0.5 * vol*vol; - nu = kappa_*(theta_ - vol*vol); - - retVal[0] = x0[0]*Math.Exp(mu*dt+vol*dw[0]*sdt); - retVal[1] = vol*vol - +nu*dt + vol2*sdt*(rho_*dw[0] + sqrhov*dw[1]); + mu = riskFreeRate_.link.forwardRate(t0, t0 + dt, Compounding.Continuous).value() + - dividendYield_.link.forwardRate(t0, t0 + dt, Compounding.Continuous).value() + - 0.5 * vol * vol; + nu = kappa_ * (theta_ - vol * vol); + + retVal[0] = x0[0] * Math.Exp(mu * dt + vol * dw[0] * sdt); + retVal[1] = vol * vol + + nu * dt + vol2 * sdt * (rho_ * dw[0] + sqrhov * dw[1]); break; case Discretization.NonCentralChiSquareVariance: // use Alan Lewis trick to decorrelate the equity and the variance @@ -173,15 +174,15 @@ public override Vector evolve(double t0, Vector x0, double dt, Vector dw) // process. For further details please read the Wilmott thread // "QuantLib code is very high quality" vol = (x0[1] > 0.0) ? Math.Sqrt(x0[1]) : 0.0; - mu = riskFreeRate_.link.forwardRate(t0, t0+dt, Compounding.Continuous).value() - - dividendYield_.link.forwardRate(t0, t0+dt, Compounding.Continuous).value() - - 0.5 * vol*vol; + mu = riskFreeRate_.link.forwardRate(t0, t0 + dt, Compounding.Continuous).value() + - dividendYield_.link.forwardRate(t0, t0 + dt, Compounding.Continuous).value() + - 0.5 * vol * vol; retVal[1] = varianceDistribution(x0[1], dw[1], dt); - dy = (mu - rho_/sigma_*kappa_ - *(theta_-vol*vol)) * dt + vol*sqrhov*dw[0]*sdt; + dy = (mu - rho_ / sigma_ * kappa_ + * (theta_ - vol * vol)) * dt + vol * sqrhov * dw[0] * sdt; - retVal[0] = x0[0]*Math.Exp(dy + rho_/sigma_*(retVal[1]-x0[1])); + retVal[0] = x0[0] * Math.Exp(dy + rho_ / sigma_ * (retVal[1] - x0[1])); break; case Discretization.QuadraticExponential: case Discretization.QuadraticExponentialMartingale: @@ -189,58 +190,58 @@ public override Vector evolve(double t0, Vector x0, double dt, Vector dw) // for details of the quadratic exponential discretization scheme // see Leif Andersen, // Efficient Simulation of the Heston Stochastic Volatility Model - double ex = Math.Exp(-kappa_*dt); + double ex = Math.Exp(-kappa_ * dt); - double m = theta_+(x0[1]-theta_)*ex; - double s2 = x0[1]*sigma_*sigma_*ex/kappa_*(1-ex) - + theta_*sigma_*sigma_/(2*kappa_)*(1-ex)*(1-ex); - double psi = s2/(m*m); + double m = theta_ + (x0[1] - theta_) * ex; + double s2 = x0[1] * sigma_ * sigma_ * ex / kappa_ * (1 - ex) + + theta_ * sigma_ * sigma_ / (2 * kappa_) * (1 - ex) * (1 - ex); + double psi = s2 / (m * m); double g1 = 0.5; double g2 = 0.5; - double k0 = -rho_*kappa_*theta_*dt/sigma_; - double k1 = g1*dt*(kappa_*rho_/sigma_-0.5)-rho_/sigma_; - double k2 = g2*dt*(kappa_*rho_/sigma_-0.5)+rho_/sigma_; - double k3 = g1*dt*(1-rho_*rho_); - double k4 = g2*dt*(1-rho_*rho_); - double A = k2+0.5*k4; - - if (psi < 1.5) + double k0 = -rho_ * kappa_ * theta_ * dt / sigma_; + double k1 = g1 * dt * (kappa_ * rho_ / sigma_ - 0.5) - rho_ / sigma_; + double k2 = g2 * dt * (kappa_ * rho_ / sigma_ - 0.5) + rho_ / sigma_; + double k3 = g1 * dt * (1 - rho_ * rho_); + double k4 = g2 * dt * (1 - rho_ * rho_); + double A = k2 + 0.5 * k4; + + if (psi < 1.5) { - double b2 = 2/psi-1+Math.Sqrt(2/psi*(2/psi-1)); + double b2 = 2 / psi - 1 + Math.Sqrt(2 / psi * (2 / psi - 1)); double b = Math.Sqrt(b2); - double a = m/(1+b2); + double a = m / (1 + b2); - if (discretization_ == Discretization.QuadraticExponentialMartingale) + if (discretization_ == Discretization.QuadraticExponentialMartingale) { // martingale correction - Utils.QL_REQUIRE(A < 1/(2*a),()=> "illegal value"); - k0 = -A*b2*a/(1-2*A*a)+0.5*Math.Log(1-2*A*a) - -(k1+0.5*k3)*x0[1]; + Utils.QL_REQUIRE(A < 1 / (2 * a), () => "illegal value"); + k0 = -A * b2 * a / (1 - 2 * A * a) + 0.5 * Math.Log(1 - 2 * A * a) + - (k1 + 0.5 * k3) * x0[1]; } - retVal[1] = a*(b+dw[1])*(b+dw[1]); + retVal[1] = a * (b + dw[1]) * (b + dw[1]); } - else + else { - double p = (psi-1)/(psi+1); - double beta = (1-p)/m; + double p = (psi - 1) / (psi + 1); + double beta = (1 - p) / m; double u = new CumulativeNormalDistribution().value(dw[1]); - if (discretization_ == Discretization.QuadraticExponentialMartingale) + if (discretization_ == Discretization.QuadraticExponentialMartingale) { // martingale correction - Utils.QL_REQUIRE(A < beta,()=> "illegal value"); - k0 = -Math.Log(p+beta*(1-p)/(beta-A))-(k1+0.5*k3)*x0[1]; + Utils.QL_REQUIRE(A < beta, () => "illegal value"); + k0 = -Math.Log(p + beta*(1 - p) / (beta - A)) - (k1 + 0.5 * k3)*x0[1]; } - retVal[1] = ((u <= p) ? 0.0 : Math.Log((1-p)/(1-u))/beta); + retVal[1] = ((u <= p) ? 0.0 : Math.Log((1 - p) / (1 - u)) / beta); } - mu = riskFreeRate_.link.forwardRate(t0, t0+dt, Compounding.Continuous).value() - - dividendYield_.link.forwardRate(t0, t0+dt, Compounding.Continuous).value(); + mu = riskFreeRate_.link.forwardRate(t0, t0 + dt, Compounding.Continuous).value() + - dividendYield_.link.forwardRate(t0, t0 + dt, Compounding.Continuous).value(); - retVal[0] = x0[0]*Math.Exp(mu*dt + k0 + k1*x0[1] + k2*retVal[1] - +Math.Sqrt(k3*x0[1]+k4*retVal[1])*dw[0]); + retVal[0] = x0[0]*Math.Exp(mu* dt + k0 + k1* x0[1] + k2* retVal[1] + + Math.Sqrt(k3* x0[1] + k4* retVal[1])*dw[0]); } break; case Discretization.BroadieKayaExactSchemeLobatto: @@ -250,25 +251,25 @@ public override Vector evolve(double t0, Vector x0, double dt, Vector dw) double nu_0 = x0[1]; double nu_t = varianceDistribution(nu_0, dw[1], dt); - double x = Math.Min(1.0-Const.QL_EPSILON, + double x = Math.Min(1.0 - Const.QL_EPSILON, Math.Max(0.0, new CumulativeNormalDistribution().value(dw[2]))); - cdf_nu_ds f = new cdf_nu_ds( this, nu_0, nu_t, dt, discretization_ ); - double vds = new Brent().solve( f, 1e-5, -x, theta_ * dt, 0.1 * theta_ * dt ); + cdf_nu_ds f = new cdf_nu_ds(this, nu_0, nu_t, dt, discretization_); + double vds = new Brent().solve(f, 1e-5, -x, theta_ * dt, 0.1 * theta_ * dt); - double vdw = (nu_t - nu_0 - kappa_*theta_*dt + kappa_*vds)/sigma_; + double vdw = (nu_t - nu_0 - kappa_*theta_*dt + kappa_*vds) / sigma_; - mu = ( riskFreeRate_.link.forwardRate(t0, t0+dt, Compounding.Continuous).value() - -dividendYield_.link.forwardRate(t0, t0+dt, Compounding.Continuous).value())*dt - - 0.5*vds + rho_*vdw; + mu = (riskFreeRate_.link.forwardRate(t0, t0 + dt, Compounding.Continuous).value() + - dividendYield_.link.forwardRate(t0, t0 + dt, Compounding.Continuous).value())*dt + - 0.5 * vds + rho_*vdw; - double sig = Math.Sqrt((1-rho_*rho_)*vds); - double s = x0[0]*Math.Exp(mu + sig*dw[0]); + double sig = Math.Sqrt((1 - rho_*rho_)*vds); + double s = x0[0]*Math.Exp(mu + sig* dw[0]); retVal[0] = s; retVal[1] = nu_t; - } - break; + } + break; default: Utils.QL_FAIL("unknown discretization schema"); break; @@ -287,22 +288,22 @@ public override Vector evolve(double t0, Vector x0, double dt, Vector dw) public Handle dividendYield() { return dividendYield_; } public Handle riskFreeRate() { return riskFreeRate_; } - public override double time( Date d ) + public override double time(Date d) { - return riskFreeRate_.link.dayCounter().yearFraction(riskFreeRate_.link.referenceDate(), d ); + return riskFreeRate_.link.dayCounter().yearFraction(riskFreeRate_.link.referenceDate(), d); } private double varianceDistribution(double v, double dw, double dt) { - double df = 4*theta_*kappa_/(sigma_*sigma_); - double ncp = 4*kappa_*Math.Exp(-kappa_*dt) - /(sigma_*sigma_*(1-Math.Exp(-kappa_*dt)))*v; + double df = 4 * theta_ * kappa_ / (sigma_ * sigma_); + double ncp = 4 * kappa_ * Math.Exp(-kappa_ * dt) + / (sigma_ * sigma_ * (1 - Math.Exp(-kappa_ * dt))) * v; - double p = Math.Min(1.0-Const.QL_EPSILON, - Math.Max(0.0, new CumulativeNormalDistribution().value(dw))); + double p = Math.Min(1.0 - Const.QL_EPSILON, + Math.Max(0.0, new CumulativeNormalDistribution().value(dw))); - return sigma_*sigma_*(1-Math.Exp(-kappa_*dt))/(4*kappa_) - * new InverseNonCentralChiSquareDistribution(df, ncp, 100).value(p); + return sigma_ * sigma_ * (1 - Math.Exp(-kappa_ * dt)) / (4 * kappa_) + * new InverseNonCentralChiSquareDistribution(df, ncp, 100).value(p); } private Handle riskFreeRate_, dividendYield_; @@ -328,63 +329,63 @@ private class cdf_nu_ds : ISolver1d // For details please see: // Roger Lord, "Efficient Pricing Algorithms for exotic Derivatives", // http://repub.eur.nl/pub/13917/LordR-Thesis.pdf - Complex Phi( HestonProcess process, Complex a, double nu_0, double nu_t, double dt ) + Complex Phi(HestonProcess process, Complex a, double nu_0, double nu_t, double dt) { double theta = process.theta(); double kappa = process.kappa(); double sigma = process.sigma(); double sigma2 = sigma * sigma; - Complex ga = Complex.Sqrt( kappa * kappa - 2 * sigma2 * a * new Complex( 0.0, 1.0 ) ); + Complex ga = Complex.Sqrt(kappa * kappa - 2 * sigma2 * a * new Complex(0.0, 1.0)); double d = 4 * theta * kappa / sigma2; double nu = 0.5 * d - 1; - Complex z = ga * Complex.Exp( -0.5 * ga * dt ) / ( 1.0 - Complex.Exp( -ga * dt ) ); - Complex log_z = -0.5 * ga * dt + Complex.Log( ga / ( 1.0 - Complex.Exp( -ga * dt ) ) ); - - Complex alpha = 4.0 * ga * Complex.Exp( -0.5 * ga * dt ) / ( sigma2 * ( 1.0 - Complex.Exp( -ga * dt ) ) ); - Complex beta = 4.0 * kappa * Complex.Exp( -0.5 * kappa * dt ) / ( sigma2 * ( 1.0 - Complex.Exp( -kappa * dt ) ) ); - - return ga * Complex.Exp( -0.5 * ( ga - kappa ) * dt ) * ( 1 - Complex.Exp( -kappa * dt ) ) - / ( kappa * ( 1.0 - Complex.Exp( -ga * dt ) ) ) - * Complex.Exp( ( nu_0 + nu_t ) / sigma2 * ( - kappa * ( 1.0 + Complex.Exp( -kappa * dt ) ) / ( 1.0 - Complex.Exp( -kappa * dt ) ) - - ga * ( 1.0 + Complex.Exp( -ga * dt ) ) / ( 1.0 - Complex.Exp( -ga * dt ) ) ) ) - * Complex.Exp( nu * log_z ) / Complex.Pow( z, nu ) - * ( ( nu_t > 1e-8 ) - ? Utils.modifiedBesselFunction_i( nu, Complex.Sqrt( nu_0 * nu_t ) * alpha ) - / Utils.modifiedBesselFunction_i( nu, Complex.Sqrt( nu_0 * nu_t ) * beta ) - : Complex.Pow( alpha / beta, nu ) + Complex z = ga * Complex.Exp(-0.5 * ga * dt) / (1.0 - Complex.Exp(-ga * dt)); + Complex log_z = -0.5 * ga * dt + Complex.Log(ga / (1.0 - Complex.Exp(-ga * dt))); + + Complex alpha = 4.0 * ga * Complex.Exp(-0.5 * ga * dt) / (sigma2 * (1.0 - Complex.Exp(-ga * dt))); + Complex beta = 4.0 * kappa * Complex.Exp(-0.5 * kappa * dt) / (sigma2 * (1.0 - Complex.Exp(-kappa * dt))); + + return ga * Complex.Exp(-0.5 * (ga - kappa) * dt) * (1 - Complex.Exp(-kappa * dt)) + / (kappa * (1.0 - Complex.Exp(-ga * dt))) + * Complex.Exp((nu_0 + nu_t) / sigma2 * ( + kappa * (1.0 + Complex.Exp(-kappa * dt)) / (1.0 - Complex.Exp(-kappa * dt)) + - ga * (1.0 + Complex.Exp(-ga * dt)) / (1.0 - Complex.Exp(-ga * dt)))) + * Complex.Exp(nu * log_z) / Complex.Pow(z, nu) + * ((nu_t > 1e-8) + ? Utils.modifiedBesselFunction_i(nu, Complex.Sqrt(nu_0 * nu_t) * alpha) + / Utils.modifiedBesselFunction_i(nu, Complex.Sqrt(nu_0 * nu_t) * beta) + : Complex.Pow(alpha / beta, nu) ); } - private double cornishFisherEps( HestonProcess process, double nu_0, double nu_t, double dt, double eps ) + private double cornishFisherEps(HestonProcess process, double nu_0, double nu_t, double dt, double eps) { // use moment generating function to get the // first,second, third and fourth moment of the distribution double d = 1e-2; - double p2 = Phi( process, new Complex( 0, -2 * d ), nu_0, nu_t, dt ).Real; - double p1 = Phi( process, new Complex( 0, -d ), nu_0, nu_t, dt ).Real; - double p0 = Phi( process, new Complex( 0, 0 ), nu_0, nu_t, dt ).Real; - double pm1 = Phi( process, new Complex( 0, d ), nu_0, nu_t, dt ).Real; - double pm2 = Phi( process, new Complex( 0, 2 * d ), nu_0, nu_t, dt ).Real; - - double avg = ( pm2 - 8 * pm1 + 8 * p1 - p2 ) / ( 12 * d ); - double m2 = ( -pm2 + 16 * pm1 - 30 * p0 + 16 * p1 - p2 ) / ( 12 * d * d ); + double p2 = Phi(process, new Complex(0, -2 * d), nu_0, nu_t, dt).Real; + double p1 = Phi(process, new Complex(0, -d), nu_0, nu_t, dt).Real; + double p0 = Phi(process, new Complex(0, 0), nu_0, nu_t, dt).Real; + double pm1 = Phi(process, new Complex(0, d), nu_0, nu_t, dt).Real; + double pm2 = Phi(process, new Complex(0, 2 * d), nu_0, nu_t, dt).Real; + + double avg = (pm2 - 8 * pm1 + 8 * p1 - p2) / (12 * d); + double m2 = (-pm2 + 16 * pm1 - 30 * p0 + 16 * p1 - p2) / (12 * d * d); double var = m2 - avg * avg; - double stdDev = Math.Sqrt( var ); + double stdDev = Math.Sqrt(var); - double m3 = ( -0.5 * pm2 + pm1 - p1 + 0.5 * p2 ) / ( d * d * d ); - double skew = ( m3 - 3 * var * avg - avg * avg * avg ) / ( var * stdDev ); + double m3 = (-0.5 * pm2 + pm1 - p1 + 0.5 * p2) / (d * d * d); + double skew = (m3 - 3 * var * avg - avg * avg * avg) / (var * stdDev); - double m4 = ( pm2 - 4 * pm1 + 6 * p0 - 4 * p1 + p2 ) / ( d * d * d * d ); - double kurt = ( m4 - 4 * m3 * avg + 6 * m2 * avg * avg - 3 * avg * avg * avg * avg ) / ( var * var ); + double m4 = (pm2 - 4 * pm1 + 6 * p0 - 4 * p1 + p2) / (d * d * d * d); + double kurt = (m4 - 4 * m3 * avg + 6 * m2 * avg * avg - 3 * avg * avg * avg * avg) / (var * var); // Cornish-Fisher relation to come up with an improved // estimate of 1-F(u_\eps) < \eps - double q = new InverseCumulativeNormal().value( 1 - eps ); - double w = q + ( q * q - 1 ) / 6 * skew + ( q * q * q - 3 * q ) / 24 * ( kurt - 3 ) - - ( 2 * q * q * q - 5 * q ) / 36 * skew * skew; + double q = new InverseCumulativeNormal().value(1 - eps); + double w = q + (q * q - 1) / 6 * skew + (q * q * q - 3 * q) / 24 * (kurt - 3) + - (2 * q * q * q - 5 * q) / 36 * skew * skew; return avg + w * stdDev; @@ -392,62 +393,74 @@ private double cornishFisherEps( HestonProcess process, double nu_0, double nu_t // For the definition of the Pade approximation please see e.g. // http://wikipedia.org/wiki/Sine_integral#Sine_integral - private double Si( double x ) + private double Si(double x) { - if ( x <= 4.0 ) + if (x <= 4.0) { double[] n = - { -4.54393409816329991e-2,1.15457225751016682e-3, - -1.41018536821330254e-5,9.43280809438713025e-8, - -3.53201978997168357e-10,7.08240282274875911e-13, - -6.05338212010422477e-16 }; + { + -4.54393409816329991e-2, 1.15457225751016682e-3, + -1.41018536821330254e-5, 9.43280809438713025e-8, + -3.53201978997168357e-10, 7.08240282274875911e-13, + -6.05338212010422477e-16 + }; double[] d = - { 1.01162145739225565e-2,4.99175116169755106e-5, - 1.55654986308745614e-7,3.28067571055789734e-10, - 4.5049097575386581e-13,3.21107051193712168e-16, - 0.0 }; + { + 1.01162145739225565e-2, 4.99175116169755106e-5, + 1.55654986308745614e-7, 3.28067571055789734e-10, + 4.5049097575386581e-13, 3.21107051193712168e-16, + 0.0 + }; - return x * pade( x * x, n, d, n.Length ); // TODO sizeof(n)/sizeof(Real) + return x * pade(x * x, n, d, n.Length); // TODO sizeof(n)/sizeof(Real) } else { - double y = 1 / ( x * x ); + double y = 1 / (x * x); double[] fn = - { 7.44437068161936700618e2,1.96396372895146869801e5, - 2.37750310125431834034e7,1.43073403821274636888e9, - 4.33736238870432522765e10,6.40533830574022022911e11, - 4.20968180571076940208e12,1.00795182980368574617e13, - 4.94816688199951963482e12,-4.94701168645415959931e11 }; + { + 7.44437068161936700618e2, 1.96396372895146869801e5, + 2.37750310125431834034e7, 1.43073403821274636888e9, + 4.33736238870432522765e10, 6.40533830574022022911e11, + 4.20968180571076940208e12, 1.00795182980368574617e13, + 4.94816688199951963482e12, -4.94701168645415959931e11 + }; double[] fd = - { 7.46437068161927678031e2,1.97865247031583951450e5, - 2.41535670165126845144e7,1.47478952192985464958e9, - 4.58595115847765779830e10,7.08501308149515401563e11, - 5.06084464593475076774e12,1.43468549171581016479e13, - 1.11535493509914254097e13, 0.0 }; - double f = pade( y, fn, fd, 10 ) / x; + { + 7.46437068161927678031e2, 1.97865247031583951450e5, + 2.41535670165126845144e7, 1.47478952192985464958e9, + 4.58595115847765779830e10, 7.08501308149515401563e11, + 5.06084464593475076774e12, 1.43468549171581016479e13, + 1.11535493509914254097e13, 0.0 + }; + double f = pade(y, fn, fd, 10) / x; double[] gn = - { 8.1359520115168615e2,2.35239181626478200e5, - 3.12557570795778731e7,2.06297595146763354e9, - 6.83052205423625007e10,1.09049528450362786e12, - 7.57664583257834349e12,1.81004487464664575e13, - 6.43291613143049485e12,-1.36517137670871689e12 }; + { + 8.1359520115168615e2, 2.35239181626478200e5, + 3.12557570795778731e7, 2.06297595146763354e9, + 6.83052205423625007e10, 1.09049528450362786e12, + 7.57664583257834349e12, 1.81004487464664575e13, + 6.43291613143049485e12, -1.36517137670871689e12 + }; double[] gd = - { 8.19595201151451564e2,2.40036752835578777e5, - 3.26026661647090822e7,2.23355543278099360e9, - 7.87465017341829930e10,1.39866710696414565e12, - 1.17164723371736605e13,4.01839087307656620e13, - 3.99653257887490811e13, 0.0}; - double g = y * pade( y, gn, gd, 10 ); + { + 8.19595201151451564e2, 2.40036752835578777e5, + 3.26026661647090822e7, 2.23355543278099360e9, + 7.87465017341829930e10, 1.39866710696414565e12, + 1.17164723371736605e13, 4.01839087307656620e13, + 3.99653257887490811e13, 0.0 + }; + double g = y * pade(y, gn, gd, 10); - return Const.M_PI_2 - f * Math.Cos( x ) - g * Math.Sin( x ); + return Const.M_PI_2 - f * Math.Cos(x) - g * Math.Sin(x); } } public cdf_nu_ds(HestonProcess _process, double _nu_0, double _nu_t, double _dt, - Discretization _discretization) + Discretization _discretization) { process = _process; nu_0 = _nu_0; @@ -456,93 +469,93 @@ public cdf_nu_ds(HestonProcess _process, double _nu_0, double _nu_t, double _dt, discretization = _discretization; } - private double pade( double x, double[] nominator, double[] denominator, int m ) + private double pade(double x, double[] nominator, double[] denominator, int m) { double n = 0.0, d = 0.0; - for ( int i = m - 1; i >= 0; --i ) + for (int i = m - 1; i >= 0; --i) { - n = ( n + nominator[i] ) * x; - d = ( d + denominator[i] ) * x; + n = (n + nominator[i]) * x; + d = (d + denominator[i]) * x; } - return ( 1 + n ) / ( 1 + d ); + return (1 + n) / (1 + d); } public override double value(double x) { double eps = 1e-4; - double u_eps = Math.Min( 100.0, - Math.Max( 0.1, cornishFisherEps( process, nu_0, nu_t, dt, eps ) ) ); + double u_eps = Math.Min(100.0, + Math.Max(0.1, cornishFisherEps(process, nu_0, nu_t, dt, eps))); - switch ( discretization ) + switch (discretization) { case Discretization.BroadieKayaExactSchemeLaguerre: - { - GaussLaguerreIntegration gaussLaguerreIntegration = new GaussLaguerreIntegration( 128 ); + { + GaussLaguerreIntegration gaussLaguerreIntegration = new GaussLaguerreIntegration(128); - // get the upper bound for the integration - double upper = u_eps / 2.0; - while ( Complex.Abs( Phi( process, upper, nu_0, nu_t, dt ) / upper ) > eps ) - upper *= 2.0; + // get the upper bound for the integration + double upper = u_eps / 2.0; + while (Complex.Abs(Phi(process, upper, nu_0, nu_t, dt) / upper) > eps) + upper *= 2.0; - return ( x < upper ) - ? Math.Max( 0.0, Math.Min( 1.0, - gaussLaguerreIntegration.value( new ch( process, x, nu_0, nu_t, dt ).value ) ) ) - : 1.0; - } + return (x < upper) + ? Math.Max(0.0, Math.Min(1.0, + gaussLaguerreIntegration.value(new ch(process, x, nu_0, nu_t, dt).value))) + : 1.0; + } case Discretization.BroadieKayaExactSchemeLobatto: - { - // get the upper bound for the integration - double upper = u_eps / 2.0; - while ( Complex.Abs( Phi( process, upper, nu_0, nu_t, dt ) / upper ) > eps ) - upper *= 2.0; - - return x < upper ? - Math.Max( 0.0, Math.Min( 1.0, - new GaussLobattoIntegral( default(int), eps ).value( new ch( process, x, nu_0, nu_t, dt ).value, Const.QL_EPSILON, upper ) ) ) - : 1.0; + { + // get the upper bound for the integration + double upper = u_eps / 2.0; + while (Complex.Abs(Phi(process, upper, nu_0, nu_t, dt) / upper) > eps) + upper *= 2.0; + + return x < upper ? + Math.Max(0.0, Math.Min(1.0, + new GaussLobattoIntegral(default(int), eps).value(new ch(process, x, nu_0, nu_t, dt).value, Const.QL_EPSILON, upper))) + : 1.0; } case Discretization.BroadieKayaExactSchemeTrapezoidal: + { + double h = 0.05; + + double si = Si(0.5 * h * x); + double s = Const.M_2_PI * si; + Complex f = new Complex(); + int j = 0; + do { - double h = 0.05; - - double si = Si( 0.5 * h * x ); - double s = Const.M_2_PI * si; - Complex f = new Complex(); - int j = 0; - do - { - ++j; - double u = h * j; - double si_n = Si( x * ( u + 0.5 * h ) ); - - f = Phi( process, u, nu_0, nu_t, dt ); - s += Const.M_2_PI * f.Real * ( si_n - si ); - si = si_n; - } - while ( Const.M_2_PI * Complex.Abs( f ) / j > eps ); - - return s; + ++j; + double u = h * j; + double si_n = Si(x * (u + 0.5 * h)); + + f = Phi(process, u, nu_0, nu_t, dt); + s += Const.M_2_PI * f.Real * (si_n - si); + si = si_n; } + while (Const.M_2_PI * Complex.Abs(f) / j > eps); + + return s; + } default: - Utils.QL_FAIL( "unknown integration method" ); + Utils.QL_FAIL("unknown integration method"); break; } return 0; - + } } - private class ch + private class ch { private HestonProcess process; private double x, nu_0, nu_t; private double dt; - - public ch(HestonProcess _process,double _x, double _nu_0, double _nu_t, double _dt) + + public ch(HestonProcess _process, double _x, double _nu_0, double _nu_t, double _dt) { process = _process; x = _x; @@ -552,36 +565,36 @@ public ch(HestonProcess _process,double _x, double _nu_0, double _nu_t, double _ } public double value(double u) { - return Const.M_2_PI*Math.Sin(u*x)/u * Phi(process, u, nu_0, nu_t, dt).Real; + return Const.M_2_PI * Math.Sin(u * x) / u * Phi(process, u, nu_0, nu_t, dt).Real; } - private Complex Phi( HestonProcess process, Complex a, double nu_0, double nu_t, double dt ) + private Complex Phi(HestonProcess process, Complex a, double nu_0, double nu_t, double dt) { double theta = process.theta(); double kappa = process.kappa(); double sigma = process.sigma(); double sigma2 = sigma * sigma; - Complex ga = Complex.Sqrt( kappa * kappa - 2 * sigma2 * a * new Complex( 0.0, 1.0 ) ); + Complex ga = Complex.Sqrt(kappa * kappa - 2 * sigma2 * a * new Complex(0.0, 1.0)); double d = 4 * theta * kappa / sigma2; double nu = 0.5 * d - 1; - Complex z = ga * Complex.Exp( -0.5 * ga * dt ) / ( 1.0 - Complex.Exp( -ga * dt ) ); - Complex log_z = -0.5 * ga * dt + Complex.Log( ga / ( 1.0 - Complex.Exp( -ga * dt ) ) ); - - Complex alpha = 4.0 * ga * Complex.Exp( -0.5 * ga * dt ) / ( sigma2 * ( 1.0 - Complex.Exp( -ga * dt ) ) ); - Complex beta = 4.0 * kappa * Complex.Exp( -0.5 * kappa * dt ) / ( sigma2 * ( 1.0 - Complex.Exp( -kappa * dt ) ) ); - - return ga * Complex.Exp( -0.5 * ( ga - kappa ) * dt ) * ( 1 - Complex.Exp( -kappa * dt ) ) - / ( kappa * ( 1.0 - Complex.Exp( -ga * dt ) ) ) - * Complex.Exp( ( nu_0 + nu_t ) / sigma2 * ( - kappa * ( 1.0 + Complex.Exp( -kappa * dt ) ) / ( 1.0 - Complex.Exp( -kappa * dt ) ) - - ga * ( 1.0 + Complex.Exp( -ga * dt ) ) / ( 1.0 - Complex.Exp( -ga * dt ) ) ) ) - * Complex.Exp( nu * log_z ) / Complex.Pow( z, nu ) - * ( ( nu_t > 1e-8 ) - ? Utils.modifiedBesselFunction_i( nu, Complex.Sqrt( nu_0 * nu_t ) * alpha ) - / Utils.modifiedBesselFunction_i( nu, Complex.Sqrt( nu_0 * nu_t ) * beta ) - : Complex.Pow( alpha / beta, nu ) + Complex z = ga * Complex.Exp(-0.5 * ga * dt) / (1.0 - Complex.Exp(-ga * dt)); + Complex log_z = -0.5 * ga * dt + Complex.Log(ga / (1.0 - Complex.Exp(-ga * dt))); + + Complex alpha = 4.0 * ga * Complex.Exp(-0.5 * ga * dt) / (sigma2 * (1.0 - Complex.Exp(-ga * dt))); + Complex beta = 4.0 * kappa * Complex.Exp(-0.5 * kappa * dt) / (sigma2 * (1.0 - Complex.Exp(-kappa * dt))); + + return ga * Complex.Exp(-0.5 * (ga - kappa) * dt) * (1 - Complex.Exp(-kappa * dt)) + / (kappa * (1.0 - Complex.Exp(-ga * dt))) + * Complex.Exp((nu_0 + nu_t) / sigma2 * ( + kappa * (1.0 + Complex.Exp(-kappa * dt)) / (1.0 - Complex.Exp(-kappa * dt)) + - ga * (1.0 + Complex.Exp(-ga * dt)) / (1.0 - Complex.Exp(-ga * dt)))) + * Complex.Exp(nu * log_z) / Complex.Pow(z, nu) + * ((nu_t > 1e-8) + ? Utils.modifiedBesselFunction_i(nu, Complex.Sqrt(nu_0 * nu_t) * alpha) + / Utils.modifiedBesselFunction_i(nu, Complex.Sqrt(nu_0 * nu_t) * beta) + : Complex.Pow(alpha / beta, nu) ); } } diff --git a/src/QLNet/processes/HullWhiteProcess.cs b/src/QLNet/processes/HullWhiteProcess.cs index e6dadba5e..8337ebd9d 100644 --- a/src/QLNet/processes/HullWhiteProcess.cs +++ b/src/QLNet/processes/HullWhiteProcess.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,50 +20,50 @@ namespace QLNet //! Hull-White stochastic process public class HullWhiteProcess : StochasticProcess1D { - public HullWhiteProcess(Handle h,double a,double sigma) + public HullWhiteProcess(Handle h, double a, double sigma) { - process_ = new OrnsteinUhlenbeckProcess(a, sigma, h.link.forwardRate(0.0,0.0,Compounding.Continuous,Frequency.NoFrequency).value()); + process_ = new OrnsteinUhlenbeckProcess(a, sigma, h.link.forwardRate(0.0, 0.0, Compounding.Continuous, Frequency.NoFrequency).value()); h_ = h; a_ = a; sigma_ = sigma; - Utils.QL_REQUIRE( a_ >= 0.0,()=> "negative a given" ); - Utils.QL_REQUIRE( sigma_ >= 0.0,()=> "negative sigma given" ); + Utils.QL_REQUIRE(a_ >= 0.0, () => "negative a given"); + Utils.QL_REQUIRE(sigma_ >= 0.0, () => "negative sigma given"); } // StochasticProcess1D interface public override double x0() { return process_.x0(); } public override double drift(double t, double x) { - double alpha_drift = sigma_*sigma_/(2*a_)*(1-Math.Exp(-2*a_*t)); + double alpha_drift = sigma_ * sigma_ / (2 * a_) * (1 - Math.Exp(-2 * a_ * t)); double shift = 0.0001; double f = h_.link.forwardRate(t, t, Compounding.Continuous, Frequency.NoFrequency).value(); - double fup = h_.link.forwardRate(t+shift, t+shift, Compounding.Continuous, Frequency.NoFrequency).value(); - double f_prime = (fup-f)/shift; - alpha_drift += a_*f+f_prime; + double fup = h_.link.forwardRate(t + shift, t + shift, Compounding.Continuous, Frequency.NoFrequency).value(); + double f_prime = (fup - f) / shift; + alpha_drift += a_ * f + f_prime; return process_.drift(t, x) + alpha_drift; } - public override double diffusion( double t, double x ) { return process_.diffusion( t, x ); } + public override double diffusion(double t, double x) { return process_.diffusion(t, x); } public override double expectation(double t0, double x0, double dt) { - return process_.expectation(t0, x0, dt) - + alpha(t0 + dt) - alpha(t0)*Math.Exp(-a_*dt); + return process_.expectation(t0, x0, dt) + + alpha(t0 + dt) - alpha(t0) * Math.Exp(-a_ * dt); } - public override double stdDeviation( double t0, double x0, double dt ) { return process_.stdDeviation( t0, x0, dt ); } - public override double variance( double t0, double x0, double dt ) { return process_.variance( t0, x0, dt ); } + public override double stdDeviation(double t0, double x0, double dt) { return process_.stdDeviation(t0, x0, dt); } + public override double variance(double t0, double x0, double dt) { return process_.variance(t0, x0, dt); } public double a() { return a_; } public double sigma() { return sigma_; } public double alpha(double t) { double alfa = a_ > Const.QL_EPSILON ? - (sigma_/a_)*(1 - Math.Exp(-a_*t)) : - sigma_*t; - alfa *= 0.5*alfa; + (sigma_ / a_) * (1 - Math.Exp(-a_ * t)) : + sigma_ * t; + alfa *= 0.5 * alfa; alfa += h_.link.forwardRate(t, t, Compounding.Continuous, Frequency.NoFrequency).value(); return alfa; } - + protected OrnsteinUhlenbeckProcess process_; protected Handle h_; protected double a_, sigma_; @@ -71,12 +71,12 @@ public double alpha(double t) //! %Forward Hull-White stochastic process /*! \ingroup processes */ - public class HullWhiteForwardProcess: ForwardMeasureProcess1D + public class HullWhiteForwardProcess: ForwardMeasureProcess1D { - public HullWhiteForwardProcess(Handle h,double a,double sigma) + public HullWhiteForwardProcess(Handle h, double a, double sigma) { - process_ = new OrnsteinUhlenbeckProcess(a, sigma, h.link.forwardRate(0.0,0.0, - Compounding.Continuous,Frequency.NoFrequency).value()); + process_ = new OrnsteinUhlenbeckProcess(a, sigma, h.link.forwardRate(0.0, 0.0, + Compounding.Continuous, Frequency.NoFrequency).value()); h_ = h; a_ = a; sigma_ = sigma; @@ -85,62 +85,62 @@ public HullWhiteForwardProcess(Handle h,double a,double sigm public override double x0() { return process_.x0(); } public override double drift(double t, double x) { - double alpha_drift = sigma_*sigma_/(2*a_)*(1-Math.Exp(-2*a_*t)); + double alpha_drift = sigma_ * sigma_ / (2 * a_) * (1 - Math.Exp(-2 * a_ * t)); double shift = 0.0001; double f = h_.link.forwardRate(t, t, Compounding.Continuous, Frequency.NoFrequency).value(); - double fup = h_.link.forwardRate(t+shift, t+shift, Compounding.Continuous, Frequency.NoFrequency).value(); - double f_prime = (fup-f)/shift; - alpha_drift += a_*f+f_prime; - return process_.drift(t, x) + alpha_drift - B(t, T_)*sigma_*sigma_; + double fup = h_.link.forwardRate(t + shift, t + shift, Compounding.Continuous, Frequency.NoFrequency).value(); + double f_prime = (fup - f) / shift; + alpha_drift += a_ * f + f_prime; + return process_.drift(t, x) + alpha_drift - B(t, T_) * sigma_ * sigma_; } - public override double diffusion( double t, double x ) { return process_.diffusion( t, x ); } + public override double diffusion(double t, double x) { return process_.diffusion(t, x); } public override double expectation(double t0, double x0, double dt) { return process_.expectation(t0, x0, dt) - + alpha(t0 + dt) - alpha(t0)*Math.Exp(-a_*dt) - - M_T(t0, t0+dt, T_); + + alpha(t0 + dt) - alpha(t0) * Math.Exp(-a_ * dt) + - M_T(t0, t0 + dt, T_); } - public override double stdDeviation( double t0, double x0, double dt ) { return process_.stdDeviation( t0, x0, dt ); } - public override double variance( double t0, double x0, double dt ) { return process_.variance( t0, x0, dt ); } + public override double stdDeviation(double t0, double x0, double dt) { return process_.stdDeviation(t0, x0, dt); } + public override double variance(double t0, double x0, double dt) { return process_.variance(t0, x0, dt); } public double a() { return a_; } public double sigma() { return sigma_; } public double alpha(double t) { double alfa = a_ > Const.QL_EPSILON ? - (sigma_/a_)*(1 - Math.Exp(-a_*t)) : - sigma_*t; - alfa *= 0.5*alfa; + (sigma_ / a_) * (1 - Math.Exp(-a_ * t)) : + sigma_ * t; + alfa *= 0.5 * alfa; alfa += h_.link.forwardRate(t, t, Compounding.Continuous, Frequency.NoFrequency).value(); return alfa; } public double M_T(double s, double t, double T) { - if (a_ > Const.QL_EPSILON) + if (a_ > Const.QL_EPSILON) { - double coeff = (sigma_*sigma_)/(a_*a_); - double exp1 = Math.Exp(-a_*(t-s)); - double exp2 = Math.Exp(-a_*(T-t)); - double exp3 = Math.Exp(-a_*(T+t-2.0*s)); - return coeff*(1-exp1)-0.5*coeff*(exp2-exp3); - } - else + double coeff = (sigma_ * sigma_) / (a_ * a_); + double exp1 = Math.Exp(-a_ * (t - s)); + double exp2 = Math.Exp(-a_ * (T - t)); + double exp3 = Math.Exp(-a_ * (T + t - 2.0 * s)); + return coeff * (1 - exp1) - 0.5 * coeff * (exp2 - exp3); + } + else { // low-a algebraic limit - double coeff = (sigma_*sigma_)/2.0; - return coeff*(t-s)*(2.0*T-t-s); + double coeff = (sigma_ * sigma_) / 2.0; + return coeff * (t - s) * (2.0 * T - t - s); } } public double B(double t, double T) { return a_ > Const.QL_EPSILON ? - 1/a_ * (1-Math.Exp(-a_*(T-t))) : - T-t; + 1 / a_ * (1 - Math.Exp(-a_ * (T - t))) : + T - t; } - + protected OrnsteinUhlenbeckProcess process_; protected Handle h_; - protected double a_, sigma_; + protected double a_, sigma_; } } diff --git a/src/QLNet/processes/HybridHestonHullWhiteProcess.cs b/src/QLNet/processes/HybridHestonHullWhiteProcess.cs index 2e9f89184..e1b3d82cc 100644 --- a/src/QLNet/processes/HybridHestonHullWhiteProcess.cs +++ b/src/QLNet/processes/HybridHestonHullWhiteProcess.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -27,12 +27,12 @@ its functionality... work in progress */ public class HybridHestonHullWhiteProcess : StochasticProcess { - public enum Discretization { Euler, BSMHullWhite }; + public enum Discretization { Euler, BSMHullWhite } - public HybridHestonHullWhiteProcess( HestonProcess hestonProcess, - HullWhiteForwardProcess hullWhiteProcess, - double corrEquityShortRate, - Discretization discretization = Discretization.BSMHullWhite) + public HybridHestonHullWhiteProcess(HestonProcess hestonProcess, + HullWhiteForwardProcess hullWhiteProcess, + double corrEquityShortRate, + Discretization discretization = Discretization.BSMHullWhite) { hestonProcess_ = hestonProcess; hullWhiteProcess_ = hullWhiteProcess; @@ -41,18 +41,18 @@ public HybridHestonHullWhiteProcess( HestonProcess hestonProcess, hullWhiteProcess.sigma()); corrEquityShortRate_ = corrEquityShortRate; disc_ = discretization; - maxRho_ = Math.Sqrt(1 - hestonProcess.rho()*hestonProcess.rho()) - - Math.Sqrt(Const.QL_EPSILON) /* reserve for rounding errors */; + maxRho_ = Math.Sqrt(1 - hestonProcess.rho() * hestonProcess.rho()) + - Math.Sqrt(Const.QL_EPSILON) /* reserve for rounding errors */; T_ = hullWhiteProcess.getForwardMeasureTime(); endDiscount_ = hestonProcess.riskFreeRate().link.discount(T_); - Utils.QL_REQUIRE( corrEquityShortRate * corrEquityShortRate - + hestonProcess.rho() * hestonProcess.rho() <= 1.0,()=> - "correlation matrix is not positive definite" ); + Utils.QL_REQUIRE(corrEquityShortRate * corrEquityShortRate + + hestonProcess.rho() * hestonProcess.rho() <= 1.0, () => + "correlation matrix is not positive definite"); - Utils.QL_REQUIRE( hullWhiteProcess.sigma() > 0.0,()=> - "positive vol of Hull White process is required" ); + Utils.QL_REQUIRE(hullWhiteProcess.sigma() > 0.0, () => + "positive vol of Hull White process is required"); } public override int size() { return 3; } @@ -62,56 +62,56 @@ public override Vector initialValues() retVal[0] = hestonProcess_.s0().link.value(); retVal[1] = hestonProcess_.v0(); retVal[2] = hullWhiteProcess_.x0(); - + return retVal; } public override Vector drift(double t, Vector x) { Vector retVal = new Vector(3), x0 = new Vector(2); - + x0[0] = x[0]; x0[1] = x[1]; Vector y0 = hestonProcess_.drift(t, x0); - + retVal[0] = y0[0]; retVal[1] = y0[1]; retVal[2] = hullWhiteProcess_.drift(t, x[2]); - + return retVal; } public override Matrix diffusion(double t, Vector x) { - Matrix retVal = new Matrix(3,3); + Matrix retVal = new Matrix(3, 3); - Vector xt = new Vector(2); - xt[0] = x[0]; + Vector xt = new Vector(2); + xt[0] = x[0]; xt[1] = x[1]; Matrix m = hestonProcess_.diffusion(t, xt); - retVal[0,0] = m[0,0]; retVal[0,1] = 0.0; retVal[0,2] = 0.0; - retVal[1,0] = m[1,0]; retVal[1,1] = m[1,1]; retVal[1,2] = 0.0; - + retVal[0, 0] = m[0, 0]; retVal[0, 1] = 0.0; retVal[0, 2] = 0.0; + retVal[1, 0] = m[1, 0]; retVal[1, 1] = m[1, 1]; retVal[1, 2] = 0.0; + double sigma = hullWhiteProcess_.sigma(); - retVal[2,0] = corrEquityShortRate_ * sigma; - retVal[2,1] = - retVal[2,0]*retVal[1,0] / retVal[1,1]; - retVal[2,2] = Math.Sqrt( sigma*sigma - retVal[2,1]*retVal[2,1] - - retVal[2,0]*retVal[2,0] ); - + retVal[2, 0] = corrEquityShortRate_ * sigma; + retVal[2, 1] = - retVal[2, 0] * retVal[1, 0] / retVal[1, 1]; + retVal[2, 2] = Math.Sqrt(sigma * sigma - retVal[2, 1] * retVal[2, 1] + - retVal[2, 0] * retVal[2, 0]); + return retVal; } public override Vector apply(Vector x0, Vector dx) { - Vector retVal = new Vector(3), xt= new Vector(2), dxt = new Vector(2); - + Vector retVal = new Vector(3), xt = new Vector(2), dxt = new Vector(2); + xt[0] = x0[0]; xt[1] = x0[1]; dxt[0] = dx[0]; dxt[1] = dx[1]; - Vector yt = hestonProcess_.apply( xt, dxt ); - + Vector yt = hestonProcess_.apply(xt, dxt); + retVal[0] = yt[0]; retVal[1] = yt[1]; retVal[2] = hullWhiteProcess_.apply(x0[2], dx[2]); - + return retVal; } - public override Vector evolve(double t0, Vector x0,double dt, Vector dw) + public override Vector evolve(double t0, Vector x0, double dt, Vector dw) { double r = x0[2]; double a = hullWhiteProcess_.a(); @@ -122,72 +122,72 @@ public override Vector evolve(double t0, Vector x0,double dt, Vector dw) double s = t0; double t = t0 + dt; double T = T_; - double dy = hestonProcess_.dividendYield().link.forwardRate(s, t, Compounding.Continuous,Frequency.NoFrequency).value(); + double dy = hestonProcess_.dividendYield().link.forwardRate(s, t, Compounding.Continuous, Frequency.NoFrequency).value(); double df = Math.Log(hestonProcess_.riskFreeRate().link.discount(t) - /hestonProcess_.riskFreeRate().link.discount(s)); + / hestonProcess_.riskFreeRate().link.discount(s)); - double eaT = Math.Exp(-a*T); - double eat = Math.Exp(-a*t); - double eas = Math.Exp(-a*s); - double iat = 1.0/eat; - double ias = 1.0/eas; + double eaT = Math.Exp(-a * T); + double eat = Math.Exp(-a * t); + double eas = Math.Exp(-a * s); + double iat = 1.0 / eat; + double ias = 1.0 / eas; - double m1 = -(dy + 0.5*eta*eta)*dt - df; + double m1 = -(dy + 0.5 * eta * eta) * dt - df; - double m2 = -rho*sigma*eta/a*(dt - 1/a*eaT*(iat - ias)); + double m2 = -rho * sigma * eta / a * (dt - 1 / a * eaT * (iat - ias)); double m3 = (r - hullWhiteProcess_.alpha(s)) - *hullWhiteProcess_.B(s, t); + * hullWhiteProcess_.B(s, t); - double m4 = sigma*sigma/(2*a*a) *(dt + 2/a*(eat - eas) - 1/(2*a)*(eat*eat - eas*eas)); + double m4 = sigma * sigma / (2 * a * a) * (dt + 2 / a * (eat - eas) - 1 / (2 * a) * (eat * eat - eas * eas)); - double m5 = -sigma*sigma/(a*a) *(dt - 1/a*(1 - eat*ias) - 1/(2*a)*eaT*(iat - 2*ias + eat*ias*ias)); + double m5 = -sigma * sigma / (a * a) * (dt - 1 / a * (1 - eat * ias) - 1 / (2 * a) * eaT * (iat - 2 * ias + eat * ias * ias)); double mu = m1 + m2 + m3 + m4 + m5; - Vector retVal= new Vector(3); + Vector retVal = new Vector(3); - double eta2 = hestonProcess_.sigma()*eta; - double nu = hestonProcess_.kappa()*(hestonProcess_.theta() - eta*eta); + double eta2 = hestonProcess_.sigma() * eta; + double nu = hestonProcess_.kappa() * (hestonProcess_.theta() - eta * eta); - retVal[1] = x0[1] + nu*dt + eta2*Math.Sqrt(dt) - *(xi*dw[0] + Math.Sqrt(1 - xi*xi)*dw[1]); + retVal[1] = x0[1] + nu * dt + eta2 * Math.Sqrt(dt) + * (xi * dw[0] + Math.Sqrt(1 - xi * xi) * dw[1]); if (disc_ == Discretization.BSMHullWhite) { - double v1 = eta*eta*dt + sigma*sigma/(a*a)*(dt - 2/a*(1 - eat*ias) - + 1/(2*a)*(1 - eat*eat*ias*ias)) - + 2*sigma*eta/a*rho*(dt - 1/a*(1 - eat*ias)); + double v1 = eta * eta * dt + sigma * sigma / (a * a) * (dt - 2 / a * (1 - eat * ias) + + 1 / (2 * a) * (1 - eat * eat * ias * ias)) + + 2 * sigma * eta / a * rho * (dt - 1 / a * (1 - eat * ias)); double v2 = hullWhiteProcess_.variance(t0, r, dt); - double v12 = (1 - eat*ias)*(sigma*eta/a*rho + sigma*sigma/(a*a)) - - sigma*sigma/(2*a*a)*(1 - eat*eat*ias*ias); + double v12 = (1 - eat * ias) * (sigma * eta / a * rho + sigma * sigma / (a * a)) + - sigma * sigma / (2 * a * a) * (1 - eat * eat * ias * ias); - Utils.QL_REQUIRE(v1 > 0.0 && v2 > 0.0,()=> "zero or negative variance given"); + Utils.QL_REQUIRE(v1 > 0.0 && v2 > 0.0, () => "zero or negative variance given"); // terminal rho must be between -maxRho and +maxRho - double rhoT = Math.Min(maxRho_, Math.Max(-maxRho_, v12/Math.Sqrt(v1*v2))); + double rhoT = Math.Min(maxRho_, Math.Max(-maxRho_, v12 / Math.Sqrt(v1 * v2))); Utils.QL_REQUIRE(rhoT <= 1.0 && rhoT >= -1.0 - && 1 - rhoT*rhoT/(1 - xi*xi) >= 0.0,()=> "invalid terminal correlation"); + && 1 - rhoT * rhoT / (1 - xi * xi) >= 0.0, () => "invalid terminal correlation"); double dw_0 = dw[0]; - double dw_2 = rhoT*dw[0] - rhoT*xi/Math.Sqrt(1 - xi*xi)*dw[1] - + Math.Sqrt(1 - rhoT*rhoT/(1 - xi*xi))*dw[2]; + double dw_2 = rhoT * dw[0] - rhoT * xi / Math.Sqrt(1 - xi * xi) * dw[1] + + Math.Sqrt(1 - rhoT * rhoT / (1 - xi * xi)) * dw[2]; retVal[2] = hullWhiteProcess_.evolve(t0, r, dt, dw_2); - double vol = Math.Sqrt(v1)*dw_0; - retVal[0] = x0[0]*Math.Exp(mu + vol); + double vol = Math.Sqrt(v1) * dw_0; + retVal[0] = x0[0] * Math.Exp(mu + vol); } else if (disc_ == Discretization.Euler) { - double dw_2 = rho*dw[0] - rho*xi/Math.Sqrt(1 - xi*xi)*dw[1] - + Math.Sqrt(1 - rho*rho/(1 - xi*xi))*dw[2]; + double dw_2 = rho * dw[0] - rho * xi / Math.Sqrt(1 - xi * xi) * dw[1] + + Math.Sqrt(1 - rho * rho / (1 - xi * xi)) * dw[2]; retVal[2] = hullWhiteProcess_.evolve(t0, r, dt, dw_2); - double vol = eta*Math.Sqrt(dt)*dw[0]; - retVal[0] = x0[0]*Math.Exp(mu + vol); + double vol = eta * Math.Sqrt(dt) * dw[0]; + retVal[0] = x0[0] * Math.Exp(mu + vol); } else Utils.QL_FAIL("unknown discretization scheme"); @@ -197,20 +197,20 @@ public override Vector evolve(double t0, Vector x0,double dt, Vector dw) public double numeraire(double t, Vector x) { - return hullWhiteModel_.discountBond( t, T_, x[2] ) / endDiscount_; + return hullWhiteModel_.discountBond(t, T_, x[2]) / endDiscount_; } public HestonProcess hestonProcess() { return hestonProcess_; } public HullWhiteForwardProcess hullWhiteProcess() { return hullWhiteProcess_; } public double eta() { return corrEquityShortRate_; } - public override double time( Date date ) { return hestonProcess_.time( date ); } + public override double time(Date date) { return hestonProcess_.time(date); } public Discretization discretization() { return disc_; } - public override void update() { endDiscount_ = hestonProcess_.riskFreeRate().link.discount( T_ ); } + public override void update() { endDiscount_ = hestonProcess_.riskFreeRate().link.discount(T_); } protected HestonProcess hestonProcess_; protected HullWhiteForwardProcess hullWhiteProcess_; - + //model is used to calculate P(t,T) protected HullWhite hullWhiteModel_; diff --git a/src/QLNet/processes/Ornsteinuhlenbeckprocess.cs b/src/QLNet/processes/Ornsteinuhlenbeckprocess.cs index 02d9dee5c..2937b6b0f 100644 --- a/src/QLNet/processes/Ornsteinuhlenbeckprocess.cs +++ b/src/QLNet/processes/Ornsteinuhlenbeckprocess.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -27,18 +27,18 @@ namespace QLNet \f] \ingroup processes - */ + */ public class OrnsteinUhlenbeckProcess : StochasticProcess1D { - public OrnsteinUhlenbeckProcess( double speed, double vol, double x0 = 0.0, double level = 0.0 ) + public OrnsteinUhlenbeckProcess(double speed, double vol, double x0 = 0.0, double level = 0.0) { x0_ = x0; speed_ = speed; level_ = level; volatility_ = vol; - Utils.QL_REQUIRE( speed_ >= 0.0,()=> "negative speed given" ); + Utils.QL_REQUIRE(speed_ >= 0.0, () => "negative speed given"); - Utils.QL_REQUIRE( volatility_ >= 0.0,()=> "negative volatility given" ); + Utils.QL_REQUIRE(volatility_ >= 0.0, () => "negative volatility given"); } // StochasticProcess interface public override double x0() @@ -57,32 +57,32 @@ public double level() { return level_; } - public override double drift( double UnnamedParameter1, double x ) + public override double drift(double UnnamedParameter1, double x) { - return speed_ * ( level_ - x ); + return speed_ * (level_ - x); } - public override double diffusion( double UnnamedParameter1, double UnnamedParameter2 ) + public override double diffusion(double UnnamedParameter1, double UnnamedParameter2) { return volatility_; } - public override double expectation( double UnnamedParameter1, double x0, double dt ) + public override double expectation(double UnnamedParameter1, double x0, double dt) { - return level_ + ( x0 - level_ ) * Math.Exp( -speed_ * dt ); + return level_ + (x0 - level_) * Math.Exp(-speed_ * dt); } - public override double stdDeviation( double t, double x0, double dt ) + public override double stdDeviation(double t, double x0, double dt) { - return Math.Sqrt( variance( t, x0, dt ) ); + return Math.Sqrt(variance(t, x0, dt)); } - public override double variance( double UnnamedParameter1, double UnnamedParameter2, double dt ) + public override double variance(double UnnamedParameter1, double UnnamedParameter2, double dt) { - if ( speed_ < Math.Sqrt( ( ( Const.QL_EPSILON ) ) ) ) + if (speed_ < Math.Sqrt(((Const.QL_EPSILON)))) { // algebraic limit for small speed return volatility_ * volatility_ * dt; } else { - return 0.5 * volatility_ * volatility_ / speed_ * ( 1.0 - Math.Exp( -2.0 * speed_ * dt ) ); + return 0.5 * volatility_ * volatility_ / speed_ * (1.0 - Math.Exp(-2.0 * speed_ * dt)); } } diff --git a/src/QLNet/processes/Squarerootprocess.cs b/src/QLNet/processes/Squarerootprocess.cs index 55f15ac2b..f6c8255fa 100644 --- a/src/QLNet/processes/Squarerootprocess.cs +++ b/src/QLNet/processes/Squarerootprocess.cs @@ -1,67 +1,68 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; -namespace QLNet { +namespace QLNet +{ - //! Square-root process class + //! Square-root process class // ! This class describes a square-root process governed by // \f[ // dx = a (b - x_t) dt + \sigma \sqrt{x_t} dW_t. // \f] // // \ingroup processes -// - public class SquareRootProcess : StochasticProcess1D - { - private double x0_; - private double mean_; - private double speed_; - private double volatility_; +// + public class SquareRootProcess : StochasticProcess1D + { + private double x0_; + private double mean_; + private double speed_; + private double volatility_; - public SquareRootProcess(double b, double a, double sigma, double x0) : this(b, a, sigma, x0, new EulerDiscretization()) - { - } - public SquareRootProcess(double b, double a, double sigma) : this(b, a, sigma, 0.0, new EulerDiscretization()) - { - } - public SquareRootProcess(double b, double a, double sigma, double x0, IDiscretization1D disc) - : base(disc) - { - x0_ = x0; - mean_ = b; - speed_ = a; - volatility_ = sigma; - } - // StochasticProcess interface - public override double x0() - { - return x0_; - } - public override double drift(double UnnamedParameter1, double x) - { - return speed_*(mean_ - x); - } - public override double diffusion(double UnnamedParameter1, double x) - { - return volatility_ *Math.Sqrt(x); - } - } + public SquareRootProcess(double b, double a, double sigma, double x0) : this(b, a, sigma, x0, new EulerDiscretization()) + { + } + public SquareRootProcess(double b, double a, double sigma) : this(b, a, sigma, 0.0, new EulerDiscretization()) + { + } + public SquareRootProcess(double b, double a, double sigma, double x0, IDiscretization1D disc) + : base(disc) + { + x0_ = x0; + mean_ = b; + speed_ = a; + volatility_ = sigma; + } + // StochasticProcess interface + public override double x0() + { + return x0_; + } + public override double drift(double UnnamedParameter1, double x) + { + return speed_ * (mean_ - x); + } + public override double diffusion(double UnnamedParameter1, double x) + { + return volatility_ * Math.Sqrt(x); + } + } } diff --git a/src/QLNet/processes/StochasticProcessArray.cs b/src/QLNet/processes/StochasticProcessArray.cs new file mode 100644 index 000000000..3fe8ba675 --- /dev/null +++ b/src/QLNet/processes/StochasticProcessArray.cs @@ -0,0 +1,129 @@ +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; + +namespace QLNet +{ + //! %Array of correlated 1-D stochastic processes + /*! \ingroup processes */ + public class StochasticProcessArray : StochasticProcess + { + protected List processes_; + protected Matrix sqrtCorrelation_; + + public StochasticProcessArray(List processes, Matrix correlation) + { + processes_ = processes; + sqrtCorrelation_ = MatrixUtilitites.pseudoSqrt(correlation, MatrixUtilitites.SalvagingAlgorithm.Spectral); + + Utils.QL_REQUIRE(processes.Count != 0, () => "no processes given"); + Utils.QL_REQUIRE(correlation.rows() == processes.Count, () => + "mismatch between number of processes and size of correlation matrix"); + for (int i = 0; i < processes_.Count; i++) + processes_[i].registerWith(update); + } + + + // stochastic process interface + public override int size() { return processes_.Count; } + + public override Vector initialValues() + { + Vector tmp = new Vector(size()); + for (int i = 0; i < size(); ++i) + tmp[i] = processes_[i].x0(); + return tmp; + } + + public override Vector drift(double t, Vector x) + { + Vector tmp = new Vector(size()); + for (int i = 0; i < size(); ++i) + tmp[i] = processes_[i].drift(t, x[i]); + return tmp; + } + + public override Vector expectation(double t0, Vector x0, double dt) + { + Vector tmp = new Vector(size()); + for (int i = 0; i < size(); ++i) + tmp[i] = processes_[i].expectation(t0, x0[i], dt); + return tmp; + } + + public override Matrix diffusion(double t, Vector x) + { + Matrix tmp = sqrtCorrelation_; + for (int i = 0; i < size(); ++i) + { + double sigma = processes_[i].diffusion(t, x[i]); + for (int j = 0; j < tmp.columns(); j++) + { + tmp[i, j] *= sigma; + } + } + return tmp; + } + + public override Matrix covariance(double t0, Vector x0, double dt) + { + Matrix tmp = stdDeviation(t0, x0, dt); + return tmp * Matrix.transpose(tmp); + } + + public override Matrix stdDeviation(double t0, Vector x0, double dt) + { + Matrix tmp = sqrtCorrelation_; + for (int i = 0; i < size(); ++i) + { + double sigma = processes_[i].stdDeviation(t0, x0[i], dt); + for (int j = 0; j < tmp.columns(); j++) + { + tmp[i, j] *= sigma; + } + } + return tmp; + } + + public override Vector apply(Vector x0, Vector dx) + { + Vector tmp = new Vector(size()); + for (int i = 0; i < size(); ++i) + tmp[i] = processes_[i].apply(x0[i], dx[i]); + return tmp; + } + + public override Vector evolve(double t0, Vector x0, double dt, Vector dw) + { + Vector dz = sqrtCorrelation_ * dw; + + Vector tmp = new Vector(size()); + for (int i = 0; i < size(); ++i) + tmp[i] = processes_[i].evolve(t0, x0[i], dt, dz[i]); + return tmp; + } + + public override double time(Date d) { return processes_[0].time(d); } + + // inspectors + public StochasticProcess1D process(int i) { return processes_[i]; } + public Matrix correlation() { return sqrtCorrelation_ * Matrix.transpose(sqrtCorrelation_); } + } +} diff --git a/src/QLNet/processes/stochasticprocessarray.cs b/src/QLNet/processes/stochasticprocessarray.cs deleted file mode 100644 index 3cd39b94e..000000000 --- a/src/QLNet/processes/stochasticprocessarray.cs +++ /dev/null @@ -1,114 +0,0 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; - -namespace QLNet { - //! %Array of correlated 1-D stochastic processes - /*! \ingroup processes */ - public class StochasticProcessArray : StochasticProcess { - protected List processes_; - protected Matrix sqrtCorrelation_; - - public StochasticProcessArray(List processes, Matrix correlation) { - processes_ = processes; - sqrtCorrelation_ = MatrixUtilitites.pseudoSqrt(correlation, MatrixUtilitites.SalvagingAlgorithm.Spectral); - - Utils.QL_REQUIRE(processes.Count != 0,()=> "no processes given"); - Utils.QL_REQUIRE(correlation.rows() == processes.Count,()=> - "mismatch between number of processes and size of correlation matrix"); - for (int i=0; i. - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,152 +22,155 @@ under the terms of the QLNet license. You should have received a using System.Text; using QLNet; -namespace Repo { - public class Repo { - static void Main(string[] args) { - DateTime timer = DateTime.Now; - - Date repoSettlementDate = new Date(14,Month.February,2000);; - Date repoDeliveryDate = new Date(15,Month.August,2000); - double repoRate = 0.05; - DayCounter repoDayCountConvention = new Actual360(); - int repoSettlementDays = 0; - Compounding repoCompounding = Compounding.Simple; - Frequency repoCompoundFreq = Frequency.Annual; - - // assume a ten year bond- this is irrelevant - Date bondIssueDate = new Date(15,Month.September,1995); - Date bondDatedDate = new Date(15,Month.September,1995); - Date bondMaturityDate = new Date(15,Month.September,2005); - double bondCoupon = 0.08; - Frequency bondCouponFrequency = Frequency.Semiannual; - // unknown what calendar fincad is using - Calendar bondCalendar = new NullCalendar(); - DayCounter bondDayCountConvention = new Thirty360(Thirty360.Thirty360Convention.BondBasis); - // unknown what fincad is using. this may affect accrued calculation - int bondSettlementDays = 0; - BusinessDayConvention bondBusinessDayConvention = BusinessDayConvention.Unadjusted; - double bondCleanPrice = 89.97693786; - double bondRedemption = 100.0; - double faceAmount = 100.0; - - - Settings.setEvaluationDate(repoSettlementDate); - - RelinkableHandle bondCurve = new RelinkableHandle(); - bondCurve.linkTo(new FlatForward(repoSettlementDate, - .01, // dummy rate - bondDayCountConvention, - Compounding.Compounded, - bondCouponFrequency)); - - /* - boost::shared_ptr bond( - new FixedRateBond(faceAmount, - bondIssueDate, - bondDatedDate, - bondMaturityDate, - bondSettlementDays, - std::vector(1,bondCoupon), - bondCouponFrequency, - bondCalendar, - bondDayCountConvention, - bondBusinessDayConvention, - bondBusinessDayConvention, - bondRedemption, - bondCurve)); - */ - - Schedule bondSchedule = new Schedule(bondDatedDate, bondMaturityDate, - new Period(bondCouponFrequency), - bondCalendar,bondBusinessDayConvention, - bondBusinessDayConvention, - DateGeneration.Rule.Backward,false); - FixedRateBond bond = new FixedRateBond(bondSettlementDays, - faceAmount, - bondSchedule, - new List() { bondCoupon }, - bondDayCountConvention, - bondBusinessDayConvention, - bondRedemption, - bondIssueDate); - bond.setPricingEngine(new DiscountingBondEngine(bondCurve)); - - bondCurve.linkTo(new FlatForward(repoSettlementDate, - bond.yield(bondCleanPrice, - bondDayCountConvention, - Compounding.Compounded, - bondCouponFrequency), - bondDayCountConvention, - Compounding.Compounded, - bondCouponFrequency)); - - Position.Type fwdType = Position.Type.Long; - double dummyStrike = 91.5745; - - RelinkableHandle repoCurve = new RelinkableHandle(); - repoCurve.linkTo(new FlatForward(repoSettlementDate, - repoRate, - repoDayCountConvention, - repoCompounding, - repoCompoundFreq)); - - - FixedRateBondForward bondFwd = new FixedRateBondForward(repoSettlementDate, - repoDeliveryDate, - fwdType, - dummyStrike, - repoSettlementDays, - repoDayCountConvention, - bondCalendar, - bondBusinessDayConvention, - bond, - repoCurve, - repoCurve); - - - Console.WriteLine("Underlying bond clean price: " + bond.cleanPrice()); - Console.WriteLine("Underlying bond dirty price: " + bond.dirtyPrice()); - Console.WriteLine("Underlying bond accrued at settlement: " - + bond.accruedAmount(repoSettlementDate)); - Console.WriteLine("Underlying bond accrued at delivery: " - + bond.accruedAmount(repoDeliveryDate)); - Console.WriteLine("Underlying bond spot income: " - + bondFwd.spotIncome(repoCurve)); - Console.WriteLine("Underlying bond fwd income: " - + bondFwd.spotIncome(repoCurve)/ - repoCurve.link.discount(repoDeliveryDate)); - Console.WriteLine("Repo strike: " + dummyStrike); - Console.WriteLine("Repo NPV: " + bondFwd.NPV()); - Console.WriteLine("Repo clean forward price: " - + bondFwd.cleanForwardPrice()); - Console.WriteLine("Repo dirty forward price: " - + bondFwd.forwardPrice()); - Console.WriteLine("Repo implied yield: " - + bondFwd.impliedYield(bond.dirtyPrice(), - dummyStrike, - repoSettlementDate, - repoCompounding, - repoDayCountConvention)); - Console.WriteLine("Market repo rate: " - + repoCurve.link.zeroRate(repoDeliveryDate, - repoDayCountConvention, - repoCompounding, - repoCompoundFreq)); - - Console.WriteLine("\nCompare with example given at \n" - + "http://www.fincad.com/support/developerFunc/mathref/BFWD.htm"); - Console.WriteLine("Clean forward price = 88.2408"); - Console.WriteLine("\nIn that example, it is unknown what bond calendar they are\n" - + "using, as well as settlement Days. For that reason, I have\n" - + "made the simplest possible assumptions here: NullCalendar\n" - + "and 0 settlement days.\n"); - - - Console.WriteLine("nRun completed in {0}", DateTime.Now - timer); - - Console.Write("Press any key to continue ..."); - Console.ReadKey(); - } - } +namespace Repo +{ + public class Repo + { + static void Main(string[] args) + { + DateTime timer = DateTime.Now; + + Date repoSettlementDate = new Date(14, Month.February, 2000);; + Date repoDeliveryDate = new Date(15, Month.August, 2000); + double repoRate = 0.05; + DayCounter repoDayCountConvention = new Actual360(); + int repoSettlementDays = 0; + Compounding repoCompounding = Compounding.Simple; + Frequency repoCompoundFreq = Frequency.Annual; + + // assume a ten year bond- this is irrelevant + Date bondIssueDate = new Date(15, Month.September, 1995); + Date bondDatedDate = new Date(15, Month.September, 1995); + Date bondMaturityDate = new Date(15, Month.September, 2005); + double bondCoupon = 0.08; + Frequency bondCouponFrequency = Frequency.Semiannual; + // unknown what calendar fincad is using + Calendar bondCalendar = new NullCalendar(); + DayCounter bondDayCountConvention = new Thirty360(Thirty360.Thirty360Convention.BondBasis); + // unknown what fincad is using. this may affect accrued calculation + int bondSettlementDays = 0; + BusinessDayConvention bondBusinessDayConvention = BusinessDayConvention.Unadjusted; + double bondCleanPrice = 89.97693786; + double bondRedemption = 100.0; + double faceAmount = 100.0; + + + Settings.setEvaluationDate(repoSettlementDate); + + RelinkableHandle bondCurve = new RelinkableHandle(); + bondCurve.linkTo(new FlatForward(repoSettlementDate, + .01, // dummy rate + bondDayCountConvention, + Compounding.Compounded, + bondCouponFrequency)); + + /* + boost::shared_ptr bond( + new FixedRateBond(faceAmount, + bondIssueDate, + bondDatedDate, + bondMaturityDate, + bondSettlementDays, + std::vector(1,bondCoupon), + bondCouponFrequency, + bondCalendar, + bondDayCountConvention, + bondBusinessDayConvention, + bondBusinessDayConvention, + bondRedemption, + bondCurve)); + */ + + Schedule bondSchedule = new Schedule(bondDatedDate, bondMaturityDate, + new Period(bondCouponFrequency), + bondCalendar, bondBusinessDayConvention, + bondBusinessDayConvention, + DateGeneration.Rule.Backward, false); + FixedRateBond bond = new FixedRateBond(bondSettlementDays, + faceAmount, + bondSchedule, + new List() { bondCoupon }, + bondDayCountConvention, + bondBusinessDayConvention, + bondRedemption, + bondIssueDate); + bond.setPricingEngine(new DiscountingBondEngine(bondCurve)); + + bondCurve.linkTo(new FlatForward(repoSettlementDate, + bond.yield(bondCleanPrice, + bondDayCountConvention, + Compounding.Compounded, + bondCouponFrequency), + bondDayCountConvention, + Compounding.Compounded, + bondCouponFrequency)); + + Position.Type fwdType = Position.Type.Long; + double dummyStrike = 91.5745; + + RelinkableHandle repoCurve = new RelinkableHandle(); + repoCurve.linkTo(new FlatForward(repoSettlementDate, + repoRate, + repoDayCountConvention, + repoCompounding, + repoCompoundFreq)); + + + FixedRateBondForward bondFwd = new FixedRateBondForward(repoSettlementDate, + repoDeliveryDate, + fwdType, + dummyStrike, + repoSettlementDays, + repoDayCountConvention, + bondCalendar, + bondBusinessDayConvention, + bond, + repoCurve, + repoCurve); + + + Console.WriteLine("Underlying bond clean price: " + bond.cleanPrice()); + Console.WriteLine("Underlying bond dirty price: " + bond.dirtyPrice()); + Console.WriteLine("Underlying bond accrued at settlement: " + + bond.accruedAmount(repoSettlementDate)); + Console.WriteLine("Underlying bond accrued at delivery: " + + bond.accruedAmount(repoDeliveryDate)); + Console.WriteLine("Underlying bond spot income: " + + bondFwd.spotIncome(repoCurve)); + Console.WriteLine("Underlying bond fwd income: " + + bondFwd.spotIncome(repoCurve) / + repoCurve.link.discount(repoDeliveryDate)); + Console.WriteLine("Repo strike: " + dummyStrike); + Console.WriteLine("Repo NPV: " + bondFwd.NPV()); + Console.WriteLine("Repo clean forward price: " + + bondFwd.cleanForwardPrice()); + Console.WriteLine("Repo dirty forward price: " + + bondFwd.forwardPrice()); + Console.WriteLine("Repo implied yield: " + + bondFwd.impliedYield(bond.dirtyPrice(), + dummyStrike, + repoSettlementDate, + repoCompounding, + repoDayCountConvention)); + Console.WriteLine("Market repo rate: " + + repoCurve.link.zeroRate(repoDeliveryDate, + repoDayCountConvention, + repoCompounding, + repoCompoundFreq)); + + Console.WriteLine("\nCompare with example given at \n" + + "http://www.fincad.com/support/developerFunc/mathref/BFWD.htm"); + Console.WriteLine("Clean forward price = 88.2408"); + Console.WriteLine("\nIn that example, it is unknown what bond calendar they are\n" + + "using, as well as settlement Days. For that reason, I have\n" + + "made the simplest possible assumptions here: NullCalendar\n" + + "and 0 settlement days.\n"); + + + Console.WriteLine("nRun completed in {0}", DateTime.Now - timer); + + Console.Write("Press any key to continue ..."); + Console.ReadKey(); + } + } } diff --git a/src/Repo/Repo.csproj b/src/Repo/Repo.csproj index 36d7d9d11..f150e5fdf 100644 --- a/src/Repo/Repo.csproj +++ b/src/Repo/Repo.csproj @@ -1,7 +1,7 @@  - 1.10.0 + 1.11.0 net45 $(DefineConstants);QL_NEGATIVE_RATES Repo diff --git a/src/Swap/Swap.csproj b/src/Swap/Swap.csproj index dedb30c1b..088120bd6 100644 --- a/src/Swap/Swap.csproj +++ b/src/Swap/Swap.csproj @@ -1,7 +1,7 @@  - 1.10.0 + 1.11.0 net45 $(DefineConstants);QL_NEGATIVE_RATES Swap diff --git a/src/Swap/swapvaluation.cs b/src/Swap/swapvaluation.cs index a55da26f4..1210dbadb 100644 --- a/src/Swap/swapvaluation.cs +++ b/src/Swap/swapvaluation.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project http://qlnet.sourceforge.net/ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,554 +23,557 @@ under the terms of the QLNet license. You should have received a using System.Text; using QLNet; -namespace Swap { - /* This example shows how to set up a Term Structure and then price a simple swap */ - class SwapValuation { - static void Main(string[] args) { - - DateTime timer = DateTime.Now; - - /********************* - *** MARKET DATA *** - *********************/ - - Calendar calendar = new TARGET(); - - Date settlementDate = new Date(22, Month.September, 2004); - // must be a business day - settlementDate = calendar.adjust(settlementDate); - - int fixingDays = 2; - Date todaysDate = calendar.advance(settlementDate, -fixingDays, TimeUnit.Days); - // nothing to do with Date::todaysDate - Settings.setEvaluationDate(todaysDate); - - - todaysDate = Settings.evaluationDate(); - Console.WriteLine("Today: {0}, {1}", todaysDate.DayOfWeek, todaysDate); - Console.WriteLine("Settlement date: {0}, {1}", settlementDate.DayOfWeek, settlementDate); - - - // deposits - double d1wQuote = 0.0382; - double d1mQuote = 0.0372; - double d3mQuote = 0.0363; - double d6mQuote = 0.0353; - double d9mQuote = 0.0348; - double d1yQuote = 0.0345; - // FRAs - double fra3x6Quote = 0.037125; - double fra6x9Quote = 0.037125; - double fra6x12Quote = 0.037125; - // futures - double fut1Quote = 96.2875; - double fut2Quote = 96.7875; - double fut3Quote = 96.9875; - double fut4Quote = 96.6875; - double fut5Quote = 96.4875; - double fut6Quote = 96.3875; - double fut7Quote = 96.2875; - double fut8Quote = 96.0875; - // swaps - double s2yQuote = 0.037125; - double s3yQuote = 0.0398; - double s5yQuote = 0.0443; - double s10yQuote = 0.05165; - double s15yQuote = 0.055175; - - - /******************** - *** QUOTES *** - ********************/ - - // SimpleQuote stores a value which can be manually changed; - // other Quote subclasses could read the value from a database - // or some kind of data feed. - - // deposits - Quote d1wRate = new SimpleQuote(d1wQuote); - Quote d1mRate = new SimpleQuote(d1mQuote); - Quote d3mRate = new SimpleQuote(d3mQuote); - Quote d6mRate = new SimpleQuote(d6mQuote); - Quote d9mRate = new SimpleQuote(d9mQuote); - Quote d1yRate = new SimpleQuote(d1yQuote); - // FRAs - Quote fra3x6Rate = new SimpleQuote(fra3x6Quote); - Quote fra6x9Rate = new SimpleQuote(fra6x9Quote); - Quote fra6x12Rate = new SimpleQuote(fra6x12Quote); - // futures - Quote fut1Price = new SimpleQuote(fut1Quote); - Quote fut2Price = new SimpleQuote(fut2Quote); - Quote fut3Price = new SimpleQuote(fut3Quote); - Quote fut4Price = new SimpleQuote(fut4Quote); - Quote fut5Price = new SimpleQuote(fut5Quote); - Quote fut6Price = new SimpleQuote(fut6Quote); - Quote fut7Price = new SimpleQuote(fut7Quote); - Quote fut8Price = new SimpleQuote(fut8Quote); - // swaps - Quote s2yRate = new SimpleQuote(s2yQuote); - Quote s3yRate = new SimpleQuote(s3yQuote); - Quote s5yRate = new SimpleQuote(s5yQuote); - Quote s10yRate = new SimpleQuote(s10yQuote); - Quote s15yRate = new SimpleQuote(s15yQuote); - - - /********************* - *** RATE HELPERS *** - *********************/ - - // RateHelpers are built from the above quotes together with - // other instrument dependant infos. Quotes are passed in - // relinkable handles which could be relinked to some other - // data source later. - - // deposits - DayCounter depositDayCounter = new Actual360(); - - RateHelper d1w = new DepositRateHelper(new Handle(d1wRate), new Period(1, TimeUnit.Weeks), - fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); - RateHelper d1m = new DepositRateHelper(new Handle(d1mRate), new Period(1, TimeUnit.Months), - fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); - RateHelper d3m = new DepositRateHelper(new Handle(d3mRate), new Period(3, TimeUnit.Months), - fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); - RateHelper d6m = new DepositRateHelper(new Handle(d6mRate), new Period(6, TimeUnit.Months), - fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); - RateHelper d9m = new DepositRateHelper(new Handle(d9mRate), new Period(9, TimeUnit.Months), - fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); - RateHelper d1y = new DepositRateHelper(new Handle(d1yRate), new Period(1, TimeUnit.Years), - fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); - - // setup FRAs - RateHelper fra3x6 = new FraRateHelper(new Handle(fra3x6Rate), 3, 6, fixingDays, calendar, - BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); - RateHelper fra6x9 = new FraRateHelper(new Handle(fra6x9Rate), 6, 9, fixingDays, calendar, - BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); - RateHelper fra6x12 = new FraRateHelper(new Handle(fra6x12Rate), 6, 12, fixingDays, calendar, - BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); - - - // setup futures - // Handle convexityAdjustment = new Handle(new SimpleQuote(0.0)); - int futMonths = 3; - Date imm = IMM.nextDate(settlementDate); - - RateHelper fut1 = new FuturesRateHelper(new Handle(fut1Price), imm, futMonths, calendar, - BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); - - imm = IMM.nextDate(imm + 1); - RateHelper fut2 = new FuturesRateHelper(new Handle(fut2Price), imm, futMonths, calendar, - BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); - - imm = IMM.nextDate(imm + 1); - RateHelper fut3 = new FuturesRateHelper(new Handle(fut3Price), imm, futMonths, calendar, - BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); - - imm = IMM.nextDate(imm + 1); - RateHelper fut4 = new FuturesRateHelper(new Handle(fut4Price), imm, futMonths, calendar, - BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); - - imm = IMM.nextDate(imm + 1); - RateHelper fut5 = new FuturesRateHelper(new Handle(fut5Price), imm, futMonths, calendar, - BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); - - imm = IMM.nextDate(imm + 1); - RateHelper fut6 = new FuturesRateHelper(new Handle(fut6Price), imm, futMonths, calendar, - BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); - - imm = IMM.nextDate(imm + 1); - RateHelper fut7 = new FuturesRateHelper(new Handle(fut7Price), imm, futMonths, calendar, - BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); - - imm = IMM.nextDate(imm + 1); - RateHelper fut8 = new FuturesRateHelper(new Handle(fut8Price), imm, futMonths, calendar, - BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); - - - // setup swaps - Frequency swFixedLegFrequency = Frequency.Annual; - BusinessDayConvention swFixedLegConvention = BusinessDayConvention.Unadjusted; - DayCounter swFixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European); - - IborIndex swFloatingLegIndex = new Euribor6M(); - - RateHelper s2y = new SwapRateHelper(new Handle(s2yRate), new Period(2, TimeUnit.Years), - calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex); - RateHelper s3y = new SwapRateHelper(new Handle(s3yRate), new Period(3, TimeUnit.Years), - calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex); - RateHelper s5y = new SwapRateHelper(new Handle(s5yRate), new Period(5, TimeUnit.Years), - calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex); - RateHelper s10y = new SwapRateHelper(new Handle(s10yRate), new Period(10, TimeUnit.Years), - calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex); - RateHelper s15y = new SwapRateHelper(new Handle(s15yRate), new Period(15, TimeUnit.Years), - calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex); - - - - /********************* - ** CURVE BUILDING ** - *********************/ - - // Any DayCounter would be fine. - // ActualActual::ISDA ensures that 30 years is 30.0 - DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA); - - double tolerance = 1.0e-15; - - // A depo-swap curve - List depoSwapInstruments = new List(); - depoSwapInstruments.Add(d1w); - depoSwapInstruments.Add(d1m); - depoSwapInstruments.Add(d3m); - depoSwapInstruments.Add(d6m); - depoSwapInstruments.Add(d9m); - depoSwapInstruments.Add(d1y); - depoSwapInstruments.Add(s2y); - depoSwapInstruments.Add(s3y); - depoSwapInstruments.Add(s5y); - depoSwapInstruments.Add(s10y); - depoSwapInstruments.Add(s15y); - YieldTermStructure depoSwapTermStructure = new PiecewiseYieldCurve( - settlementDate, depoSwapInstruments, termStructureDayCounter, new List>(), new List(), tolerance); - - - // A depo-futures-swap curve - List depoFutSwapInstruments = new List(); - depoFutSwapInstruments.Add(d1w); - depoFutSwapInstruments.Add(d1m); - depoFutSwapInstruments.Add(fut1); - depoFutSwapInstruments.Add(fut2); - depoFutSwapInstruments.Add(fut3); - depoFutSwapInstruments.Add(fut4); - depoFutSwapInstruments.Add(fut5); - depoFutSwapInstruments.Add(fut6); - depoFutSwapInstruments.Add(fut7); - depoFutSwapInstruments.Add(fut8); - depoFutSwapInstruments.Add(s3y); - depoFutSwapInstruments.Add(s5y); - depoFutSwapInstruments.Add(s10y); - depoFutSwapInstruments.Add(s15y); - YieldTermStructure depoFutSwapTermStructure = new PiecewiseYieldCurve( - settlementDate, depoFutSwapInstruments, termStructureDayCounter, new List>(), new List(), tolerance); - - - // A depo-FRA-swap curve - List depoFRASwapInstruments = new List(); - depoFRASwapInstruments.Add(d1w); - depoFRASwapInstruments.Add(d1m); - depoFRASwapInstruments.Add(d3m); - depoFRASwapInstruments.Add(fra3x6); - depoFRASwapInstruments.Add(fra6x9); - depoFRASwapInstruments.Add(fra6x12); - depoFRASwapInstruments.Add(s2y); - depoFRASwapInstruments.Add(s3y); - depoFRASwapInstruments.Add(s5y); - depoFRASwapInstruments.Add(s10y); - depoFRASwapInstruments.Add(s15y); - YieldTermStructure depoFRASwapTermStructure = new PiecewiseYieldCurve( - settlementDate, depoFRASwapInstruments, termStructureDayCounter, new List>(), new List(), tolerance); - - // Term structures that will be used for pricing: - // the one used for discounting cash flows - RelinkableHandle discountingTermStructure = new RelinkableHandle(); - // the one used for forward rate forecasting - RelinkableHandle forecastingTermStructure = new RelinkableHandle(); - - - /********************* - * SWAPS TO BE PRICED * - **********************/ - - // constant nominal 1,000,000 Euro - double nominal = 1000000.0; - // fixed leg - Frequency fixedLegFrequency = Frequency.Annual; - BusinessDayConvention fixedLegConvention = BusinessDayConvention.Unadjusted; - BusinessDayConvention floatingLegConvention = BusinessDayConvention.ModifiedFollowing; - DayCounter fixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European); - double fixedRate = 0.04; - DayCounter floatingLegDayCounter = new Actual360(); - - // floating leg - Frequency floatingLegFrequency = Frequency.Semiannual; - IborIndex euriborIndex = new Euribor6M(forecastingTermStructure); - double spread = 0.0; - - int lenghtInYears = 5; - VanillaSwap.Type swapType = VanillaSwap.Type.Payer; - - Date maturity = settlementDate + new Period(lenghtInYears, TimeUnit.Years); - Schedule fixedSchedule = new Schedule(settlementDate, maturity, new Period(fixedLegFrequency), - calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false); - Schedule floatSchedule = new Schedule(settlementDate, maturity, new Period(floatingLegFrequency), - calendar, floatingLegConvention, floatingLegConvention, DateGeneration.Rule.Forward, false); - VanillaSwap spot5YearSwap = new VanillaSwap(swapType, nominal, fixedSchedule, fixedRate, fixedLegDayCounter, - floatSchedule, euriborIndex, spread, floatingLegDayCounter); - - Date fwdStart = calendar.advance(settlementDate, 1, TimeUnit.Years); - Date fwdMaturity = fwdStart + new Period(lenghtInYears, TimeUnit.Years); - Schedule fwdFixedSchedule = new Schedule(fwdStart, fwdMaturity, new Period(fixedLegFrequency), - calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false); - Schedule fwdFloatSchedule = new Schedule(fwdStart, fwdMaturity, new Period(floatingLegFrequency), - calendar, floatingLegConvention, floatingLegConvention, DateGeneration.Rule.Forward, false); - VanillaSwap oneYearForward5YearSwap = new VanillaSwap(swapType, nominal, fwdFixedSchedule, fixedRate, fixedLegDayCounter, - fwdFloatSchedule, euriborIndex, spread, floatingLegDayCounter); - - - /*************** - * SWAP PRICING * - ****************/ - - // utilities for reporting - List headers = new List(); - headers.Add("term structure"); - headers.Add("net present value"); - headers.Add("fair spread"); - headers.Add("fair fixed rate"); - string separator = " | "; - int width = headers[0].Length + separator.Length - + headers[1].Length + separator.Length - + headers[2].Length + separator.Length - + headers[3].Length + separator.Length - 1; - string rule = string.Format("").PadLeft(width, '-'), dblrule = string.Format("").PadLeft(width, '='); - string tab = string.Format("").PadLeft(8, ' '); - - // calculations - - Console.WriteLine(dblrule); - Console.WriteLine("5-year market swap-rate = {0:0.00%}", s5yRate.value()); - Console.WriteLine(dblrule); - - Console.WriteLine(tab + "5-years swap paying {0:0.00%}", fixedRate); - Console.WriteLine(headers[0] + separator - + headers[1] + separator - + headers[2] + separator - + headers[3] + separator); - Console.WriteLine(rule); - - double NPV; - double fairRate; - double fairSpread; - - IPricingEngine swapEngine = new DiscountingSwapEngine(discountingTermStructure); - - spot5YearSwap.setPricingEngine(swapEngine); - oneYearForward5YearSwap.setPricingEngine(swapEngine); - - // Of course, you're not forced to really use different curves - forecastingTermStructure.linkTo(depoSwapTermStructure); - discountingTermStructure.linkTo(depoSwapTermStructure); - - NPV = spot5YearSwap.NPV(); - fairSpread = spot5YearSwap.fairSpread(); - fairRate = spot5YearSwap.fairRate(); - - Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap"); - Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); - Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); - Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); - - // let's check that the 5 years swap has been correctly re-priced - if (!(Math.Abs(fairRate-s5yQuote)<1e-8)) - throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate-s5yQuote)); - - - forecastingTermStructure.linkTo(depoFutSwapTermStructure); - discountingTermStructure.linkTo(depoFutSwapTermStructure); - - NPV = spot5YearSwap.NPV(); - fairSpread = spot5YearSwap.fairSpread(); - fairRate = spot5YearSwap.fairRate(); - - Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap"); - Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); - Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); - Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); - - if (!(Math.Abs(fairRate-s5yQuote)<1e-8)) - throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate-s5yQuote)); - - forecastingTermStructure.linkTo(depoFRASwapTermStructure); - discountingTermStructure.linkTo(depoFRASwapTermStructure); - - NPV = spot5YearSwap.NPV(); - fairSpread = spot5YearSwap.fairSpread(); - fairRate = spot5YearSwap.fairRate(); - - Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap"); - Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); - Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); - Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); - - if (!(Math.Abs(fairRate-s5yQuote)<1e-8)) - throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate-s5yQuote)); - - Console.WriteLine(rule); - - // now let's price the 1Y forward 5Y swap - Console.WriteLine(tab + "5-years, 1-year forward swap paying {0:0.00%}", fixedRate); - Console.WriteLine(headers[0] + separator - + headers[1] + separator - + headers[2] + separator - + headers[3] + separator); - Console.WriteLine(rule); - - forecastingTermStructure.linkTo(depoSwapTermStructure); - discountingTermStructure.linkTo(depoSwapTermStructure); - - NPV = oneYearForward5YearSwap.NPV(); - fairSpread = oneYearForward5YearSwap.fairSpread(); - fairRate = oneYearForward5YearSwap.fairRate(); - - Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap"); - Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); - Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); - Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); - - forecastingTermStructure.linkTo(depoFutSwapTermStructure); - discountingTermStructure.linkTo(depoFutSwapTermStructure); - - NPV = oneYearForward5YearSwap.NPV(); - fairSpread = oneYearForward5YearSwap.fairSpread(); - fairRate = oneYearForward5YearSwap.fairRate(); +namespace Swap +{ + /* This example shows how to set up a Term Structure and then price a simple swap */ + class SwapValuation + { + static void Main(string[] args) + { + + DateTime timer = DateTime.Now; + + /********************* + *** MARKET DATA *** + *********************/ + + Calendar calendar = new TARGET(); + + Date settlementDate = new Date(22, Month.September, 2004); + // must be a business day + settlementDate = calendar.adjust(settlementDate); + + int fixingDays = 2; + Date todaysDate = calendar.advance(settlementDate, -fixingDays, TimeUnit.Days); + // nothing to do with Date::todaysDate + Settings.setEvaluationDate(todaysDate); + + + todaysDate = Settings.evaluationDate(); + Console.WriteLine("Today: {0}, {1}", todaysDate.DayOfWeek, todaysDate); + Console.WriteLine("Settlement date: {0}, {1}", settlementDate.DayOfWeek, settlementDate); + + + // deposits + double d1wQuote = 0.0382; + double d1mQuote = 0.0372; + double d3mQuote = 0.0363; + double d6mQuote = 0.0353; + double d9mQuote = 0.0348; + double d1yQuote = 0.0345; + // FRAs + double fra3x6Quote = 0.037125; + double fra6x9Quote = 0.037125; + double fra6x12Quote = 0.037125; + // futures + double fut1Quote = 96.2875; + double fut2Quote = 96.7875; + double fut3Quote = 96.9875; + double fut4Quote = 96.6875; + double fut5Quote = 96.4875; + double fut6Quote = 96.3875; + double fut7Quote = 96.2875; + double fut8Quote = 96.0875; + // swaps + double s2yQuote = 0.037125; + double s3yQuote = 0.0398; + double s5yQuote = 0.0443; + double s10yQuote = 0.05165; + double s15yQuote = 0.055175; + + + /******************** + *** QUOTES *** + ********************/ + + // SimpleQuote stores a value which can be manually changed; + // other Quote subclasses could read the value from a database + // or some kind of data feed. + + // deposits + Quote d1wRate = new SimpleQuote(d1wQuote); + Quote d1mRate = new SimpleQuote(d1mQuote); + Quote d3mRate = new SimpleQuote(d3mQuote); + Quote d6mRate = new SimpleQuote(d6mQuote); + Quote d9mRate = new SimpleQuote(d9mQuote); + Quote d1yRate = new SimpleQuote(d1yQuote); + // FRAs + Quote fra3x6Rate = new SimpleQuote(fra3x6Quote); + Quote fra6x9Rate = new SimpleQuote(fra6x9Quote); + Quote fra6x12Rate = new SimpleQuote(fra6x12Quote); + // futures + Quote fut1Price = new SimpleQuote(fut1Quote); + Quote fut2Price = new SimpleQuote(fut2Quote); + Quote fut3Price = new SimpleQuote(fut3Quote); + Quote fut4Price = new SimpleQuote(fut4Quote); + Quote fut5Price = new SimpleQuote(fut5Quote); + Quote fut6Price = new SimpleQuote(fut6Quote); + Quote fut7Price = new SimpleQuote(fut7Quote); + Quote fut8Price = new SimpleQuote(fut8Quote); + // swaps + Quote s2yRate = new SimpleQuote(s2yQuote); + Quote s3yRate = new SimpleQuote(s3yQuote); + Quote s5yRate = new SimpleQuote(s5yQuote); + Quote s10yRate = new SimpleQuote(s10yQuote); + Quote s15yRate = new SimpleQuote(s15yQuote); + + + /********************* + *** RATE HELPERS *** + *********************/ + + // RateHelpers are built from the above quotes together with + // other instrument dependant infos. Quotes are passed in + // relinkable handles which could be relinked to some other + // data source later. + + // deposits + DayCounter depositDayCounter = new Actual360(); + + RateHelper d1w = new DepositRateHelper(new Handle(d1wRate), new Period(1, TimeUnit.Weeks), + fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); + RateHelper d1m = new DepositRateHelper(new Handle(d1mRate), new Period(1, TimeUnit.Months), + fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); + RateHelper d3m = new DepositRateHelper(new Handle(d3mRate), new Period(3, TimeUnit.Months), + fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); + RateHelper d6m = new DepositRateHelper(new Handle(d6mRate), new Period(6, TimeUnit.Months), + fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); + RateHelper d9m = new DepositRateHelper(new Handle(d9mRate), new Period(9, TimeUnit.Months), + fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); + RateHelper d1y = new DepositRateHelper(new Handle(d1yRate), new Period(1, TimeUnit.Years), + fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); + + // setup FRAs + RateHelper fra3x6 = new FraRateHelper(new Handle(fra3x6Rate), 3, 6, fixingDays, calendar, + BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); + RateHelper fra6x9 = new FraRateHelper(new Handle(fra6x9Rate), 6, 9, fixingDays, calendar, + BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); + RateHelper fra6x12 = new FraRateHelper(new Handle(fra6x12Rate), 6, 12, fixingDays, calendar, + BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); + + + // setup futures + // Handle convexityAdjustment = new Handle(new SimpleQuote(0.0)); + int futMonths = 3; + Date imm = IMM.nextDate(settlementDate); + + RateHelper fut1 = new FuturesRateHelper(new Handle(fut1Price), imm, futMonths, calendar, + BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); + + imm = IMM.nextDate(imm + 1); + RateHelper fut2 = new FuturesRateHelper(new Handle(fut2Price), imm, futMonths, calendar, + BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); + + imm = IMM.nextDate(imm + 1); + RateHelper fut3 = new FuturesRateHelper(new Handle(fut3Price), imm, futMonths, calendar, + BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); + + imm = IMM.nextDate(imm + 1); + RateHelper fut4 = new FuturesRateHelper(new Handle(fut4Price), imm, futMonths, calendar, + BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); + + imm = IMM.nextDate(imm + 1); + RateHelper fut5 = new FuturesRateHelper(new Handle(fut5Price), imm, futMonths, calendar, + BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); + + imm = IMM.nextDate(imm + 1); + RateHelper fut6 = new FuturesRateHelper(new Handle(fut6Price), imm, futMonths, calendar, + BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); + + imm = IMM.nextDate(imm + 1); + RateHelper fut7 = new FuturesRateHelper(new Handle(fut7Price), imm, futMonths, calendar, + BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); + + imm = IMM.nextDate(imm + 1); + RateHelper fut8 = new FuturesRateHelper(new Handle(fut8Price), imm, futMonths, calendar, + BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); + + + // setup swaps + Frequency swFixedLegFrequency = Frequency.Annual; + BusinessDayConvention swFixedLegConvention = BusinessDayConvention.Unadjusted; + DayCounter swFixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European); + + IborIndex swFloatingLegIndex = new Euribor6M(); + + RateHelper s2y = new SwapRateHelper(new Handle(s2yRate), new Period(2, TimeUnit.Years), + calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex); + RateHelper s3y = new SwapRateHelper(new Handle(s3yRate), new Period(3, TimeUnit.Years), + calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex); + RateHelper s5y = new SwapRateHelper(new Handle(s5yRate), new Period(5, TimeUnit.Years), + calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex); + RateHelper s10y = new SwapRateHelper(new Handle(s10yRate), new Period(10, TimeUnit.Years), + calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex); + RateHelper s15y = new SwapRateHelper(new Handle(s15yRate), new Period(15, TimeUnit.Years), + calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex); + + + + /********************* + ** CURVE BUILDING ** + *********************/ + + // Any DayCounter would be fine. + // ActualActual::ISDA ensures that 30 years is 30.0 + DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA); + + double tolerance = 1.0e-15; + + // A depo-swap curve + List depoSwapInstruments = new List(); + depoSwapInstruments.Add(d1w); + depoSwapInstruments.Add(d1m); + depoSwapInstruments.Add(d3m); + depoSwapInstruments.Add(d6m); + depoSwapInstruments.Add(d9m); + depoSwapInstruments.Add(d1y); + depoSwapInstruments.Add(s2y); + depoSwapInstruments.Add(s3y); + depoSwapInstruments.Add(s5y); + depoSwapInstruments.Add(s10y); + depoSwapInstruments.Add(s15y); + YieldTermStructure depoSwapTermStructure = new PiecewiseYieldCurve( + settlementDate, depoSwapInstruments, termStructureDayCounter, new List>(), new List(), tolerance); + + + // A depo-futures-swap curve + List depoFutSwapInstruments = new List(); + depoFutSwapInstruments.Add(d1w); + depoFutSwapInstruments.Add(d1m); + depoFutSwapInstruments.Add(fut1); + depoFutSwapInstruments.Add(fut2); + depoFutSwapInstruments.Add(fut3); + depoFutSwapInstruments.Add(fut4); + depoFutSwapInstruments.Add(fut5); + depoFutSwapInstruments.Add(fut6); + depoFutSwapInstruments.Add(fut7); + depoFutSwapInstruments.Add(fut8); + depoFutSwapInstruments.Add(s3y); + depoFutSwapInstruments.Add(s5y); + depoFutSwapInstruments.Add(s10y); + depoFutSwapInstruments.Add(s15y); + YieldTermStructure depoFutSwapTermStructure = new PiecewiseYieldCurve( + settlementDate, depoFutSwapInstruments, termStructureDayCounter, new List>(), new List(), tolerance); + + + // A depo-FRA-swap curve + List depoFRASwapInstruments = new List(); + depoFRASwapInstruments.Add(d1w); + depoFRASwapInstruments.Add(d1m); + depoFRASwapInstruments.Add(d3m); + depoFRASwapInstruments.Add(fra3x6); + depoFRASwapInstruments.Add(fra6x9); + depoFRASwapInstruments.Add(fra6x12); + depoFRASwapInstruments.Add(s2y); + depoFRASwapInstruments.Add(s3y); + depoFRASwapInstruments.Add(s5y); + depoFRASwapInstruments.Add(s10y); + depoFRASwapInstruments.Add(s15y); + YieldTermStructure depoFRASwapTermStructure = new PiecewiseYieldCurve( + settlementDate, depoFRASwapInstruments, termStructureDayCounter, new List>(), new List(), tolerance); + + // Term structures that will be used for pricing: + // the one used for discounting cash flows + RelinkableHandle discountingTermStructure = new RelinkableHandle(); + // the one used for forward rate forecasting + RelinkableHandle forecastingTermStructure = new RelinkableHandle(); + + + /********************* + * SWAPS TO BE PRICED * + **********************/ + + // constant nominal 1,000,000 Euro + double nominal = 1000000.0; + // fixed leg + Frequency fixedLegFrequency = Frequency.Annual; + BusinessDayConvention fixedLegConvention = BusinessDayConvention.Unadjusted; + BusinessDayConvention floatingLegConvention = BusinessDayConvention.ModifiedFollowing; + DayCounter fixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European); + double fixedRate = 0.04; + DayCounter floatingLegDayCounter = new Actual360(); + + // floating leg + Frequency floatingLegFrequency = Frequency.Semiannual; + IborIndex euriborIndex = new Euribor6M(forecastingTermStructure); + double spread = 0.0; + + int lenghtInYears = 5; + VanillaSwap.Type swapType = VanillaSwap.Type.Payer; + + Date maturity = settlementDate + new Period(lenghtInYears, TimeUnit.Years); + Schedule fixedSchedule = new Schedule(settlementDate, maturity, new Period(fixedLegFrequency), + calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false); + Schedule floatSchedule = new Schedule(settlementDate, maturity, new Period(floatingLegFrequency), + calendar, floatingLegConvention, floatingLegConvention, DateGeneration.Rule.Forward, false); + VanillaSwap spot5YearSwap = new VanillaSwap(swapType, nominal, fixedSchedule, fixedRate, fixedLegDayCounter, + floatSchedule, euriborIndex, spread, floatingLegDayCounter); + + Date fwdStart = calendar.advance(settlementDate, 1, TimeUnit.Years); + Date fwdMaturity = fwdStart + new Period(lenghtInYears, TimeUnit.Years); + Schedule fwdFixedSchedule = new Schedule(fwdStart, fwdMaturity, new Period(fixedLegFrequency), + calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false); + Schedule fwdFloatSchedule = new Schedule(fwdStart, fwdMaturity, new Period(floatingLegFrequency), + calendar, floatingLegConvention, floatingLegConvention, DateGeneration.Rule.Forward, false); + VanillaSwap oneYearForward5YearSwap = new VanillaSwap(swapType, nominal, fwdFixedSchedule, fixedRate, fixedLegDayCounter, + fwdFloatSchedule, euriborIndex, spread, floatingLegDayCounter); + + + /*************** + * SWAP PRICING * + ****************/ + + // utilities for reporting + List headers = new List(); + headers.Add("term structure"); + headers.Add("net present value"); + headers.Add("fair spread"); + headers.Add("fair fixed rate"); + string separator = " | "; + int width = headers[0].Length + separator.Length + + headers[1].Length + separator.Length + + headers[2].Length + separator.Length + + headers[3].Length + separator.Length - 1; + string rule = string.Format("").PadLeft(width, '-'), dblrule = string.Format("").PadLeft(width, '='); + string tab = string.Format("").PadLeft(8, ' '); + + // calculations + + Console.WriteLine(dblrule); + Console.WriteLine("5-year market swap-rate = {0:0.00%}", s5yRate.value()); + Console.WriteLine(dblrule); + + Console.WriteLine(tab + "5-years swap paying {0:0.00%}", fixedRate); + Console.WriteLine(headers[0] + separator + + headers[1] + separator + + headers[2] + separator + + headers[3] + separator); + Console.WriteLine(rule); + + double NPV; + double fairRate; + double fairSpread; + + IPricingEngine swapEngine = new DiscountingSwapEngine(discountingTermStructure); + + spot5YearSwap.setPricingEngine(swapEngine); + oneYearForward5YearSwap.setPricingEngine(swapEngine); + + // Of course, you're not forced to really use different curves + forecastingTermStructure.linkTo(depoSwapTermStructure); + discountingTermStructure.linkTo(depoSwapTermStructure); + + NPV = spot5YearSwap.NPV(); + fairSpread = spot5YearSwap.fairSpread(); + fairRate = spot5YearSwap.fairRate(); + + Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap"); + Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); + Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); + Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); + + // let's check that the 5 years swap has been correctly re-priced + if (!(Math.Abs(fairRate - s5yQuote) < 1e-8)) + throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate - s5yQuote)); + + + forecastingTermStructure.linkTo(depoFutSwapTermStructure); + discountingTermStructure.linkTo(depoFutSwapTermStructure); + + NPV = spot5YearSwap.NPV(); + fairSpread = spot5YearSwap.fairSpread(); + fairRate = spot5YearSwap.fairRate(); + + Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap"); + Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); + Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); + Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); + + if (!(Math.Abs(fairRate - s5yQuote) < 1e-8)) + throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate - s5yQuote)); + + forecastingTermStructure.linkTo(depoFRASwapTermStructure); + discountingTermStructure.linkTo(depoFRASwapTermStructure); + + NPV = spot5YearSwap.NPV(); + fairSpread = spot5YearSwap.fairSpread(); + fairRate = spot5YearSwap.fairRate(); + + Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap"); + Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); + Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); + Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); + + if (!(Math.Abs(fairRate - s5yQuote) < 1e-8)) + throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate - s5yQuote)); + + Console.WriteLine(rule); + + // now let's price the 1Y forward 5Y swap + Console.WriteLine(tab + "5-years, 1-year forward swap paying {0:0.00%}", fixedRate); + Console.WriteLine(headers[0] + separator + + headers[1] + separator + + headers[2] + separator + + headers[3] + separator); + Console.WriteLine(rule); + + forecastingTermStructure.linkTo(depoSwapTermStructure); + discountingTermStructure.linkTo(depoSwapTermStructure); + + NPV = oneYearForward5YearSwap.NPV(); + fairSpread = oneYearForward5YearSwap.fairSpread(); + fairRate = oneYearForward5YearSwap.fairRate(); + + Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap"); + Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); + Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); + Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); + + forecastingTermStructure.linkTo(depoFutSwapTermStructure); + discountingTermStructure.linkTo(depoFutSwapTermStructure); + + NPV = oneYearForward5YearSwap.NPV(); + fairSpread = oneYearForward5YearSwap.fairSpread(); + fairRate = oneYearForward5YearSwap.fairRate(); - Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap"); - Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); - Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); - Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); + Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap"); + Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); + Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); + Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); - forecastingTermStructure.linkTo(depoFRASwapTermStructure); - discountingTermStructure.linkTo(depoFRASwapTermStructure); - - NPV = oneYearForward5YearSwap.NPV(); - fairSpread = oneYearForward5YearSwap.fairSpread(); - fairRate = oneYearForward5YearSwap.fairRate(); + forecastingTermStructure.linkTo(depoFRASwapTermStructure); + discountingTermStructure.linkTo(depoFRASwapTermStructure); + + NPV = oneYearForward5YearSwap.NPV(); + fairSpread = oneYearForward5YearSwap.fairSpread(); + fairRate = oneYearForward5YearSwap.fairRate(); - Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap"); - Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); - Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); - Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); + Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap"); + Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); + Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); + Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); - // now let's say that the 5-years swap rate goes up to 4.60%. - // A smarter market element--say, connected to a data source-- would - // notice the change itself. Since we're using SimpleQuotes, - // we'll have to change the value manually--which forces us to - // downcast the handle and use the SimpleQuote - // interface. In any case, the point here is that a change in the - // value contained in the Quote triggers a new bootstrapping - // of the curve and a repricing of the swap. + // now let's say that the 5-years swap rate goes up to 4.60%. + // A smarter market element--say, connected to a data source-- would + // notice the change itself. Since we're using SimpleQuotes, + // we'll have to change the value manually--which forces us to + // downcast the handle and use the SimpleQuote + // interface. In any case, the point here is that a change in the + // value contained in the Quote triggers a new bootstrapping + // of the curve and a repricing of the swap. - SimpleQuote fiveYearsRate = s5yRate as SimpleQuote; - fiveYearsRate.setValue(0.0460); + SimpleQuote fiveYearsRate = s5yRate as SimpleQuote; + fiveYearsRate.setValue(0.0460); - Console.WriteLine(dblrule); - Console.WriteLine("5-year market swap-rate = {0:0.00%}", s5yRate.value()); - Console.WriteLine(dblrule); + Console.WriteLine(dblrule); + Console.WriteLine("5-year market swap-rate = {0:0.00%}", s5yRate.value()); + Console.WriteLine(dblrule); - Console.WriteLine(tab + "5-years swap paying {0:0.00%}", fixedRate); - Console.WriteLine(headers[0] + separator - + headers[1] + separator - + headers[2] + separator - + headers[3] + separator); - Console.WriteLine(rule); + Console.WriteLine(tab + "5-years swap paying {0:0.00%}", fixedRate); + Console.WriteLine(headers[0] + separator + + headers[1] + separator + + headers[2] + separator + + headers[3] + separator); + Console.WriteLine(rule); - // now get the updated results - forecastingTermStructure.linkTo(depoSwapTermStructure); - discountingTermStructure.linkTo(depoSwapTermStructure); + // now get the updated results + forecastingTermStructure.linkTo(depoSwapTermStructure); + discountingTermStructure.linkTo(depoSwapTermStructure); - NPV = spot5YearSwap.NPV(); - fairSpread = spot5YearSwap.fairSpread(); - fairRate = spot5YearSwap.fairRate(); + NPV = spot5YearSwap.NPV(); + fairSpread = spot5YearSwap.fairSpread(); + fairRate = spot5YearSwap.fairRate(); - Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap"); - Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); - Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); - Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); + Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap"); + Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); + Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); + Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); - if (!(Math.Abs(fairRate-s5yRate.value())<1e-8)) - throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate-s5yRate.value())); + if (!(Math.Abs(fairRate - s5yRate.value()) < 1e-8)) + throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate - s5yRate.value())); - forecastingTermStructure.linkTo(depoFutSwapTermStructure); - discountingTermStructure.linkTo(depoFutSwapTermStructure); + forecastingTermStructure.linkTo(depoFutSwapTermStructure); + discountingTermStructure.linkTo(depoFutSwapTermStructure); - NPV = spot5YearSwap.NPV(); - fairSpread = spot5YearSwap.fairSpread(); - fairRate = spot5YearSwap.fairRate(); + NPV = spot5YearSwap.NPV(); + fairSpread = spot5YearSwap.fairSpread(); + fairRate = spot5YearSwap.fairRate(); - Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap"); - Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); - Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); - Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); + Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap"); + Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); + Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); + Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); - if (!(Math.Abs(fairRate-s5yRate.value())<1e-8)) - throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate-s5yRate.value())); + if (!(Math.Abs(fairRate - s5yRate.value()) < 1e-8)) + throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate - s5yRate.value())); - forecastingTermStructure.linkTo(depoFRASwapTermStructure); - discountingTermStructure.linkTo(depoFRASwapTermStructure); - - NPV = spot5YearSwap.NPV(); - fairSpread = spot5YearSwap.fairSpread(); - fairRate = spot5YearSwap.fairRate(); + forecastingTermStructure.linkTo(depoFRASwapTermStructure); + discountingTermStructure.linkTo(depoFRASwapTermStructure); + + NPV = spot5YearSwap.NPV(); + fairSpread = spot5YearSwap.fairSpread(); + fairRate = spot5YearSwap.fairRate(); - Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap"); - Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); - Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); - Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); + Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap"); + Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); + Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); + Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); - if (!(Math.Abs(fairRate-s5yRate.value())<1e-8)) - throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate-s5yRate.value())); + if (!(Math.Abs(fairRate - s5yRate.value()) < 1e-8)) + throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate - s5yRate.value())); - Console.WriteLine(rule); + Console.WriteLine(rule); - // the 1Y forward 5Y swap changes as well + // the 1Y forward 5Y swap changes as well - Console.WriteLine(tab + "5-years, 1-year forward swap paying {0:0.00%}", fixedRate); - Console.WriteLine(headers[0] + separator - + headers[1] + separator - + headers[2] + separator - + headers[3] + separator); - Console.WriteLine(rule); - - forecastingTermStructure.linkTo(depoSwapTermStructure); - discountingTermStructure.linkTo(depoSwapTermStructure); + Console.WriteLine(tab + "5-years, 1-year forward swap paying {0:0.00%}", fixedRate); + Console.WriteLine(headers[0] + separator + + headers[1] + separator + + headers[2] + separator + + headers[3] + separator); + Console.WriteLine(rule); + + forecastingTermStructure.linkTo(depoSwapTermStructure); + discountingTermStructure.linkTo(depoSwapTermStructure); - NPV = oneYearForward5YearSwap.NPV(); - fairSpread = oneYearForward5YearSwap.fairSpread(); - fairRate = oneYearForward5YearSwap.fairRate(); + NPV = oneYearForward5YearSwap.NPV(); + fairSpread = oneYearForward5YearSwap.fairSpread(); + fairRate = oneYearForward5YearSwap.fairRate(); - Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap"); - Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); - Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); - Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); - - forecastingTermStructure.linkTo(depoFutSwapTermStructure); - discountingTermStructure.linkTo(depoFutSwapTermStructure); + Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap"); + Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); + Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); + Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); + + forecastingTermStructure.linkTo(depoFutSwapTermStructure); + discountingTermStructure.linkTo(depoFutSwapTermStructure); - NPV = oneYearForward5YearSwap.NPV(); - fairSpread = oneYearForward5YearSwap.fairSpread(); - fairRate = oneYearForward5YearSwap.fairRate(); + NPV = oneYearForward5YearSwap.NPV(); + fairSpread = oneYearForward5YearSwap.fairSpread(); + fairRate = oneYearForward5YearSwap.fairRate(); - Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap"); - Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); - Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); - Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); + Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap"); + Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); + Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); + Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); - forecastingTermStructure.linkTo(depoFRASwapTermStructure); - discountingTermStructure.linkTo(depoFRASwapTermStructure); + forecastingTermStructure.linkTo(depoFRASwapTermStructure); + discountingTermStructure.linkTo(depoFRASwapTermStructure); - NPV = oneYearForward5YearSwap.NPV(); - fairSpread = oneYearForward5YearSwap.fairSpread(); - fairRate = oneYearForward5YearSwap.fairRate(); + NPV = oneYearForward5YearSwap.NPV(); + fairSpread = oneYearForward5YearSwap.fairSpread(); + fairRate = oneYearForward5YearSwap.fairRate(); - Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap"); - Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); - Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); - Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); + Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap"); + Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); + Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); + Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); - Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); + Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); - Console.Write("Press any key to continue ..."); - Console.ReadKey(); - } - } + Console.Write("Press any key to continue ..."); + Console.ReadKey(); + } + } } diff --git a/tests/QLNet.Tests.Old/AssemblyInfo.cs b/tests/QLNet.Tests.Old/AssemblyInfo.cs index 33e20df50..ccbc4ecf0 100644 --- a/tests/QLNet.Tests.Old/AssemblyInfo.cs +++ b/tests/QLNet.Tests.Old/AssemblyInfo.cs @@ -6,7 +6,7 @@ [assembly: CollectionBehavior(DisableTestParallelization = true)] #endif -// Le informazioni generali relative a un assembly sono controllate dal seguente +// Le informazioni generali relative a un assembly sono controllate dal seguente // insieme di attributi. Per modificare le informazioni associate a un assembly // è necessario modificare i valori di questi attributi. [assembly: AssemblyTitle("Test")] @@ -14,12 +14,12 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Test")] -[assembly: AssemblyCopyright( "Copyright (c) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com)" )] +[assembly: AssemblyCopyright("Copyright (c) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com)")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili -// ai componenti COM. Se è necessario accedere a un tipo in questo assembly da +// Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili +// ai componenti COM. Se è necessario accedere a un tipo in questo assembly da // COM, impostare su true l'attributo ComVisible per tale tipo. [assembly: ComVisible(false)] @@ -29,11 +29,11 @@ // Le informazioni sulla versione di un assembly sono costituite dai seguenti quattro valori: // // Numero di versione principale -// Numero di versione secondario +// Numero di versione secondario // Numero build // Revisione // -// È possibile specificare tutti i valori oppure impostare i valori predefiniti per i numeri relativi alla build e alla revisione +// È possibile specificare tutti i valori oppure impostare i valori predefiniti per i numeri relativi alla build e alla revisione // utilizzando l'asterisco (*) come descritto di seguito: -[assembly: AssemblyVersion( "1.10.0.0" )] -[assembly: AssemblyFileVersion( "1.10.0.0" )] +[assembly: AssemblyVersion("1.10.0.0")] +[assembly: AssemblyFileVersion("1.10.0.0")] diff --git a/tests/QLNet.Tests/T_AmericanOption.cs b/tests/QLNet.Tests/T_AmericanOption.cs index 8ad65db57..c1c4714fe 100644 --- a/tests/QLNet.Tests/T_AmericanOption.cs +++ b/tests/QLNet.Tests/T_AmericanOption.cs @@ -7,7 +7,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -22,14 +22,16 @@ under the terms of the QLNet license. You should have received a using System.Collections.Generic; using System.Linq; #if NET40 || NET45 - using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; -namespace TestSuite { - public struct AmericanOptionData { +namespace TestSuite +{ + public struct AmericanOptionData + { public Option.Type type; public double strike; public double s; // spot @@ -40,16 +42,16 @@ public struct AmericanOptionData { public double result; // expected result public AmericanOptionData(Option.Type type_, - double strike_, - double s_, - double q_, - double r_, - double t_, - double v_, - double result_) + double strike_, + double s_, + double q_, + double r_, + double t_, + double v_, + double result_) { type = type_; - strike= strike_; + strike = strike_; s = s_; q = q_; r = r_; @@ -58,317 +60,401 @@ public AmericanOptionData(Option.Type type_, result = result_; } } - #if NET40 || NET45 - [TestClass()] - #endif - public class T_AmericanOption { - - /* The data below are from - An Approximate Formula for Pricing American Options - Journal of Derivatives Winter 1999 - Ju, N. - */ - AmericanOptionData[] juValues = new AmericanOptionData[] { - // type, strike, spot, q, r, t, vol, value, tol - // These values are from Exhibit 3 - Short dated Put Options - new AmericanOptionData( Option.Type.Put, 35.00, 40.00, 0.0, 0.0488, 0.0833, 0.2, 0.006 ), - new AmericanOptionData( Option.Type.Put, 35.00, 40.00, 0.0, 0.0488, 0.3333, 0.2, 0.201 ), - new AmericanOptionData( Option.Type.Put, 35.00, 40.00, 0.0, 0.0488, 0.5833, 0.2, 0.433 ), - - new AmericanOptionData( Option.Type.Put, 40.00, 40.00, 0.0, 0.0488, 0.0833, 0.2, 0.851 ), - new AmericanOptionData( Option.Type.Put, 40.00, 40.00, 0.0, 0.0488, 0.3333, 0.2, 1.576 ), - new AmericanOptionData( Option.Type.Put, 40.00, 40.00, 0.0, 0.0488, 0.5833, 0.2, 1.984 ), - - new AmericanOptionData( Option.Type.Put, 45.00, 40.00, 0.0, 0.0488, 0.0833, 0.2, 5.000 ), - new AmericanOptionData( Option.Type.Put, 45.00, 40.00, 0.0, 0.0488, 0.3333, 0.2, 5.084 ), - new AmericanOptionData( Option.Type.Put, 45.00, 40.00, 0.0, 0.0488, 0.5833, 0.2, 5.260 ), - - new AmericanOptionData( Option.Type.Put, 35.00, 40.00, 0.0, 0.0488, 0.0833, 0.3, 0.078 ), - new AmericanOptionData( Option.Type.Put, 35.00, 40.00, 0.0, 0.0488, 0.3333, 0.3, 0.697 ), - new AmericanOptionData( Option.Type.Put, 35.00, 40.00, 0.0, 0.0488, 0.5833, 0.3, 1.218 ), - - new AmericanOptionData( Option.Type.Put, 40.00, 40.00, 0.0, 0.0488, 0.0833, 0.3, 1.309 ), - new AmericanOptionData( Option.Type.Put, 40.00, 40.00, 0.0, 0.0488, 0.3333, 0.3, 2.477 ), - new AmericanOptionData( Option.Type.Put, 40.00, 40.00, 0.0, 0.0488, 0.5833, 0.3, 3.161 ), - - new AmericanOptionData( Option.Type.Put, 45.00, 40.00, 0.0, 0.0488, 0.0833, 0.3, 5.059 ), - new AmericanOptionData( Option.Type.Put, 45.00, 40.00, 0.0, 0.0488, 0.3333, 0.3, 5.699 ), - new AmericanOptionData( Option.Type.Put, 45.00, 40.00, 0.0, 0.0488, 0.5833, 0.3, 6.231 ), - - new AmericanOptionData( Option.Type.Put, 35.00, 40.00, 0.0, 0.0488, 0.0833, 0.4, 0.247 ), - new AmericanOptionData( Option.Type.Put, 35.00, 40.00, 0.0, 0.0488, 0.3333, 0.4, 1.344 ), - new AmericanOptionData( Option.Type.Put, 35.00, 40.00, 0.0, 0.0488, 0.5833, 0.4, 2.150 ), - - new AmericanOptionData( Option.Type.Put, 40.00, 40.00, 0.0, 0.0488, 0.0833, 0.4, 1.767 ), - new AmericanOptionData( Option.Type.Put, 40.00, 40.00, 0.0, 0.0488, 0.3333, 0.4, 3.381 ), - new AmericanOptionData( Option.Type.Put, 40.00, 40.00, 0.0, 0.0488, 0.5833, 0.4, 4.342 ), - - new AmericanOptionData( Option.Type.Put, 45.00, 40.00, 0.0, 0.0488, 0.0833, 0.4, 5.288 ), - new AmericanOptionData( Option.Type.Put, 45.00, 40.00, 0.0, 0.0488, 0.3333, 0.4, 6.501 ), - new AmericanOptionData( Option.Type.Put, 45.00, 40.00, 0.0, 0.0488, 0.5833, 0.4, 7.367 ), - - // Type in Exhibits 4 and 5 if you have some spare time ;-) - - // type, strike, spot, q, r, t, vol, value, tol - // values from Exhibit 6 - Long dated Call Options with dividends - new AmericanOptionData( Option.Type.Call, 100.00, 80.00, 0.07, 0.03, 3.0, 0.2, 2.605 ), - new AmericanOptionData( Option.Type.Call, 100.00, 90.00, 0.07, 0.03, 3.0, 0.2, 5.182 ), - new AmericanOptionData( Option.Type.Call, 100.00, 100.00, 0.07, 0.03, 3.0, 0.2, 9.065 ), - new AmericanOptionData( Option.Type.Call, 100.00, 110.00, 0.07, 0.03, 3.0, 0.2, 14.430 ), - new AmericanOptionData( Option.Type.Call, 100.00, 120.00, 0.07, 0.03, 3.0, 0.2, 21.398 ), - - new AmericanOptionData( Option.Type.Call, 100.00, 80.00, 0.07, 0.03, 3.0, 0.4, 11.336 ), - new AmericanOptionData( Option.Type.Call, 100.00, 90.00, 0.07, 0.03, 3.0, 0.4, 15.711 ), - new AmericanOptionData( Option.Type.Call, 100.00, 100.00, 0.07, 0.03, 3.0, 0.4, 20.760 ), - new AmericanOptionData( Option.Type.Call, 100.00, 110.00, 0.07, 0.03, 3.0, 0.4, 26.440 ), - new AmericanOptionData( Option.Type.Call, 100.00, 120.00, 0.07, 0.03, 3.0, 0.4, 32.709 ), - - new AmericanOptionData( Option.Type.Call, 100.00, 80.00, 0.07, 0.00001, 3.0, 0.3, 5.552 ), - new AmericanOptionData( Option.Type.Call, 100.00, 90.00, 0.07, 0.00001, 3.0, 0.3, 8.868 ), - new AmericanOptionData( Option.Type.Call, 100.00, 100.00, 0.07, 0.00001, 3.0, 0.3, 13.158 ), - new AmericanOptionData( Option.Type.Call, 100.00, 110.00, 0.07, 0.00001, 3.0, 0.3, 18.458 ), - new AmericanOptionData( Option.Type.Call, 100.00, 120.00, 0.07, 0.00001, 3.0, 0.3, 24.786 ), - - new AmericanOptionData( Option.Type.Call, 100.00, 80.00, 0.03, 0.07, 3.0, 0.3, 12.177 ), - new AmericanOptionData( Option.Type.Call, 100.00, 90.00, 0.03, 0.07, 3.0, 0.3, 17.411 ), - new AmericanOptionData( Option.Type.Call, 100.00, 100.00, 0.03, 0.07, 3.0, 0.3, 23.402 ), - new AmericanOptionData( Option.Type.Call, 100.00, 110.00, 0.03, 0.07, 3.0, 0.3, 30.028 ), - new AmericanOptionData( Option.Type.Call, 100.00, 120.00, 0.03, 0.07, 3.0, 0.3, 37.177 ) - }; - -#if NET40 || NET45 - [TestMethod()] -#else - [Fact] +#if NET40 || NET45 + [TestClass()] #endif - public void testBaroneAdesiWhaleyValues() { - // ("Testing Barone-Adesi and Whaley approximation for American options..."); - - /* The data below are from - "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 pag 24 - - The following values were replicated only up to the second digit - by the VB code provided by Haug, which was used as base for the - C++ implementation - - */ - AmericanOptionData[] values = { - new AmericanOptionData(Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.10, 0.15, 0.0206) , - new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.10, 0.15, 1.8771) , - new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.10, 0.15, 10.0089) , - new AmericanOptionData(Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.10, 0.25, 0.3159) , - new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.10, 0.25, 3.1280) , - new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.10, 0.25, 10.3919) , - new AmericanOptionData(Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.10, 0.35, 0.9495) , - new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.10, 0.35, 4.3777) , - new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.10, 0.35, 11.1679) , - new AmericanOptionData(Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.50, 0.15, 0.8208) , - new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.50, 0.15, 4.0842) , - new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.50, 0.15, 10.8087) , - new AmericanOptionData(Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.50, 0.25, 2.7437) , - new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.50, 0.25, 6.8015) , - new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.50, 0.25, 13.0170) , - new AmericanOptionData(Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.50, 0.35, 5.0063) , - new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.50, 0.35, 9.5106) , - new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.50, 0.35, 15.5689) , - new AmericanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.10, 0.15, 10.0000) , - new AmericanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.10, 0.15, 1.8770) , - new AmericanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.10, 0.15, 0.0410) , - new AmericanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.10, 0.25, 10.2533) , - new AmericanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.10, 0.25, 3.1277) , - new AmericanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.10, 0.25, 0.4562) , - new AmericanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.10, 0.35, 10.8787) , - new AmericanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.10, 0.35, 4.3777) , - new AmericanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.10, 0.35, 1.2402) , - new AmericanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.50, 0.15, 10.5595) , - new AmericanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.50, 0.15, 4.0842) , - new AmericanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.50, 0.15, 1.0822) , - new AmericanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.50, 0.25, 12.4419) , - new AmericanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.50, 0.25, 6.8014) , - new AmericanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.50, 0.25, 3.3226) , - new AmericanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.50, 0.35, 14.6945) , - new AmericanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.50, 0.35, 9.5104) , - new AmericanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.50, 0.35, 5.8823), - new AmericanOptionData(Option.Type.Put, 100.00, 100.00, 0.00, 0.00, 0.50, 0.15, 4.22949)}; - - Date today = Date.Today; - DayCounter dc = new Actual360(); - SimpleQuote spot = new SimpleQuote(0.0); - SimpleQuote qRate = new SimpleQuote(0.0); - YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc); - - SimpleQuote rRate = new SimpleQuote(0.0); - YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc); - SimpleQuote vol = new SimpleQuote(0.0); - BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - - double tolerance = 3.0e-3; - - for (int i=0; i(spot), - new Handle(qTS), - new Handle(rTS), - new Handle(volTS)); - - IPricingEngine engine = new BaroneAdesiWhaleyApproximationEngine(stochProcess); + public class T_AmericanOption + { + + /* The data below are from + An Approximate Formula for Pricing American Options + Journal of Derivatives Winter 1999 + Ju, N. + */ + AmericanOptionData[] juValues = new AmericanOptionData[] + { + // type, strike, spot, q, r, t, vol, value, tol + // These values are from Exhibit 3 - Short dated Put Options + new AmericanOptionData(Option.Type.Put, 35.00, 40.00, 0.0, 0.0488, 0.0833, 0.2, 0.006), + new AmericanOptionData(Option.Type.Put, 35.00, 40.00, 0.0, 0.0488, 0.3333, 0.2, 0.201), + new AmericanOptionData(Option.Type.Put, 35.00, 40.00, 0.0, 0.0488, 0.5833, 0.2, 0.433), + + new AmericanOptionData(Option.Type.Put, 40.00, 40.00, 0.0, 0.0488, 0.0833, 0.2, 0.851), + new AmericanOptionData(Option.Type.Put, 40.00, 40.00, 0.0, 0.0488, 0.3333, 0.2, 1.576), + new AmericanOptionData(Option.Type.Put, 40.00, 40.00, 0.0, 0.0488, 0.5833, 0.2, 1.984), + + new AmericanOptionData(Option.Type.Put, 45.00, 40.00, 0.0, 0.0488, 0.0833, 0.2, 5.000), + new AmericanOptionData(Option.Type.Put, 45.00, 40.00, 0.0, 0.0488, 0.3333, 0.2, 5.084), + new AmericanOptionData(Option.Type.Put, 45.00, 40.00, 0.0, 0.0488, 0.5833, 0.2, 5.260), + + new AmericanOptionData(Option.Type.Put, 35.00, 40.00, 0.0, 0.0488, 0.0833, 0.3, 0.078), + new AmericanOptionData(Option.Type.Put, 35.00, 40.00, 0.0, 0.0488, 0.3333, 0.3, 0.697), + new AmericanOptionData(Option.Type.Put, 35.00, 40.00, 0.0, 0.0488, 0.5833, 0.3, 1.218), + + new AmericanOptionData(Option.Type.Put, 40.00, 40.00, 0.0, 0.0488, 0.0833, 0.3, 1.309), + new AmericanOptionData(Option.Type.Put, 40.00, 40.00, 0.0, 0.0488, 0.3333, 0.3, 2.477), + new AmericanOptionData(Option.Type.Put, 40.00, 40.00, 0.0, 0.0488, 0.5833, 0.3, 3.161), + + new AmericanOptionData(Option.Type.Put, 45.00, 40.00, 0.0, 0.0488, 0.0833, 0.3, 5.059), + new AmericanOptionData(Option.Type.Put, 45.00, 40.00, 0.0, 0.0488, 0.3333, 0.3, 5.699), + new AmericanOptionData(Option.Type.Put, 45.00, 40.00, 0.0, 0.0488, 0.5833, 0.3, 6.231), + + new AmericanOptionData(Option.Type.Put, 35.00, 40.00, 0.0, 0.0488, 0.0833, 0.4, 0.247), + new AmericanOptionData(Option.Type.Put, 35.00, 40.00, 0.0, 0.0488, 0.3333, 0.4, 1.344), + new AmericanOptionData(Option.Type.Put, 35.00, 40.00, 0.0, 0.0488, 0.5833, 0.4, 2.150), + + new AmericanOptionData(Option.Type.Put, 40.00, 40.00, 0.0, 0.0488, 0.0833, 0.4, 1.767), + new AmericanOptionData(Option.Type.Put, 40.00, 40.00, 0.0, 0.0488, 0.3333, 0.4, 3.381), + new AmericanOptionData(Option.Type.Put, 40.00, 40.00, 0.0, 0.0488, 0.5833, 0.4, 4.342), + + new AmericanOptionData(Option.Type.Put, 45.00, 40.00, 0.0, 0.0488, 0.0833, 0.4, 5.288), + new AmericanOptionData(Option.Type.Put, 45.00, 40.00, 0.0, 0.0488, 0.3333, 0.4, 6.501), + new AmericanOptionData(Option.Type.Put, 45.00, 40.00, 0.0, 0.0488, 0.5833, 0.4, 7.367), + + // Type in Exhibits 4 and 5 if you have some spare time ;-) + + // type, strike, spot, q, r, t, vol, value, tol + // values from Exhibit 6 - Long dated Call Options with dividends + new AmericanOptionData(Option.Type.Call, 100.00, 80.00, 0.07, 0.03, 3.0, 0.2, 2.605), + new AmericanOptionData(Option.Type.Call, 100.00, 90.00, 0.07, 0.03, 3.0, 0.2, 5.182), + new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.07, 0.03, 3.0, 0.2, 9.065), + new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.07, 0.03, 3.0, 0.2, 14.430), + new AmericanOptionData(Option.Type.Call, 100.00, 120.00, 0.07, 0.03, 3.0, 0.2, 21.398), + + new AmericanOptionData(Option.Type.Call, 100.00, 80.00, 0.07, 0.03, 3.0, 0.4, 11.336), + new AmericanOptionData(Option.Type.Call, 100.00, 90.00, 0.07, 0.03, 3.0, 0.4, 15.711), + new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.07, 0.03, 3.0, 0.4, 20.760), + new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.07, 0.03, 3.0, 0.4, 26.440), + new AmericanOptionData(Option.Type.Call, 100.00, 120.00, 0.07, 0.03, 3.0, 0.4, 32.709), + + new AmericanOptionData(Option.Type.Call, 100.00, 80.00, 0.07, 0.00001, 3.0, 0.3, 5.552), + new AmericanOptionData(Option.Type.Call, 100.00, 90.00, 0.07, 0.00001, 3.0, 0.3, 8.868), + new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.07, 0.00001, 3.0, 0.3, 13.158), + new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.07, 0.00001, 3.0, 0.3, 18.458), + new AmericanOptionData(Option.Type.Call, 100.00, 120.00, 0.07, 0.00001, 3.0, 0.3, 24.786), + + new AmericanOptionData(Option.Type.Call, 100.00, 80.00, 0.03, 0.07, 3.0, 0.3, 12.177), + new AmericanOptionData(Option.Type.Call, 100.00, 90.00, 0.03, 0.07, 3.0, 0.3, 17.411), + new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.03, 0.07, 3.0, 0.3, 23.402), + new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.03, 0.07, 3.0, 0.3, 30.028), + new AmericanOptionData(Option.Type.Call, 100.00, 120.00, 0.03, 0.07, 3.0, 0.3, 37.177) + }; - VanillaOption option = new VanillaOption(payoff, exercise); - option.setPricingEngine(engine); +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testBaroneAdesiWhaleyValues() + { + // ("Testing Barone-Adesi and Whaley approximation for American options..."); + + /* The data below are from + "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 pag 24 + + The following values were replicated only up to the second digit + by the VB code provided by Haug, which was used as base for the + C++ implementation + + */ + AmericanOptionData[] values = + { + new AmericanOptionData(Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.10, 0.15, 0.0206), + new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.10, 0.15, 1.8771), + new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.10, 0.15, 10.0089), + new AmericanOptionData(Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.10, 0.25, 0.3159), + new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.10, 0.25, 3.1280), + new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.10, 0.25, 10.3919), + new AmericanOptionData(Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.10, 0.35, 0.9495), + new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.10, 0.35, 4.3777), + new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.10, 0.35, 11.1679), + new AmericanOptionData(Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.50, 0.15, 0.8208), + new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.50, 0.15, 4.0842), + new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.50, 0.15, 10.8087), + new AmericanOptionData(Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.50, 0.25, 2.7437), + new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.50, 0.25, 6.8015), + new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.50, 0.25, 13.0170), + new AmericanOptionData(Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.50, 0.35, 5.0063), + new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.50, 0.35, 9.5106), + new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.50, 0.35, 15.5689), + new AmericanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.10, 0.15, 10.0000), + new AmericanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.10, 0.15, 1.8770), + new AmericanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.10, 0.15, 0.0410), + new AmericanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.10, 0.25, 10.2533), + new AmericanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.10, 0.25, 3.1277), + new AmericanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.10, 0.25, 0.4562), + new AmericanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.10, 0.35, 10.8787), + new AmericanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.10, 0.35, 4.3777), + new AmericanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.10, 0.35, 1.2402), + new AmericanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.50, 0.15, 10.5595), + new AmericanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.50, 0.15, 4.0842), + new AmericanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.50, 0.15, 1.0822), + new AmericanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.50, 0.25, 12.4419), + new AmericanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.50, 0.25, 6.8014), + new AmericanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.50, 0.25, 3.3226), + new AmericanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.50, 0.35, 14.6945), + new AmericanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.50, 0.35, 9.5104), + new AmericanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.50, 0.35, 5.8823), + new AmericanOptionData(Option.Type.Put, 100.00, 100.00, 0.00, 0.00, 0.50, 0.15, 4.22949) + }; + + Date today = Date.Today; + DayCounter dc = new Actual360(); + SimpleQuote spot = new SimpleQuote(0.0); + SimpleQuote qRate = new SimpleQuote(0.0); + YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc); + + SimpleQuote rRate = new SimpleQuote(0.0); + YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc); + SimpleQuote vol = new SimpleQuote(0.0); + BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); + + double tolerance = 3.0e-3; + + for (int i = 0; i < values.Length; i++) + { + + StrikedTypePayoff payoff = new PlainVanillaPayoff(values[i].type, values[i].strike); + Date exDate = today + Convert.ToInt32(values[i].t * 360 + 0.5); + Exercise exercise = new AmericanExercise(today, exDate); + + spot .setValue(values[i].s); + qRate.setValue(values[i].q); + rRate.setValue(values[i].r); + vol .setValue(values[i].v); + + BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); + + IPricingEngine engine = new BaroneAdesiWhaleyApproximationEngine(stochProcess); + + VanillaOption option = new VanillaOption(payoff, exercise); + option.setPricingEngine(engine); + + double calculated = option.NPV(); + double error = Math.Abs(calculated - values[i].result); + if (error > tolerance) + { + REPORT_FAILURE("value", payoff, exercise, values[i].s, values[i].q, + values[i].r, today, values[i].v, values[i].result, + calculated, error, tolerance); + } + } + } - double calculated = option.NPV(); - double error = Math.Abs(calculated-values[i].result); - if (error > tolerance) { - REPORT_FAILURE("value", payoff, exercise, values[i].s, values[i].q, - values[i].r, today, values[i].v, values[i].result, - calculated, error, tolerance); - } +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testBjerksundStenslandValues() + { + // ("Testing Bjerksund and Stensland approximation for American options..."); + + AmericanOptionData[] values = new AmericanOptionData[] + { + // type, strike, spot, q, r, t, vol, value, tol + // from "Option pricing formulas", Haug, McGraw-Hill 1998, pag 27 + new AmericanOptionData(Option.Type.Call, 40.00, 42.00, 0.08, 0.04, 0.75, 0.35, 5.2704), + // from "Option pricing formulas", Haug, McGraw-Hill 1998, VBA code + new AmericanOptionData(Option.Type.Put, 40.00, 36.00, 0.00, 0.06, 1.00, 0.20, 4.4531), + // ATM option with very small volatility, reference value taken from R + new AmericanOptionData(Option.Type.Call, 100, 100, 0.05, 0.05, 1.0, 0.0021, 0.08032314), + // ATM option with very small volatility, + // reference value taken from Barone-Adesi and Whaley Approximation + new AmericanOptionData(Option.Type.Call, 100, 100, 0.05, 0.05, 1.0, 0.0001, 0.003860656), + new AmericanOptionData(Option.Type.Call, 100, 99.99, 0.05, 0.05, 1.0, 0.0001, 0.00081), + // ITM option with a very small volatility + new AmericanOptionData(Option.Type.Call, 100, 110, 0.05, 0.05, 1.0, 0.0001, 10.0), + new AmericanOptionData(Option.Type.Put, 110, 100, 0.05, 0.05, 1.0, 0.0001, 10.0), + // ATM option with a very large volatility + new AmericanOptionData(Option.Type.Put, 100, 110, 0.05, 0.05, 1.0, 10, 94.89543) + }; + + Date today = Date.Today; + DayCounter dc = new Actual360(); + SimpleQuote spot = new SimpleQuote(0.0); + SimpleQuote qRate = new SimpleQuote(0.0); + YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc); + + SimpleQuote rRate = new SimpleQuote(0.0); + YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc); + SimpleQuote vol = new SimpleQuote(0.0); + BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); + + double tolerance = 5.0e-5; + + for (int i = 0; i < values.Length; i++) + { + + StrikedTypePayoff payoff = new PlainVanillaPayoff(values[i].type, values[i].strike); + Date exDate = today + Convert.ToInt32(values[i].t * 360 + 0.5); + Exercise exercise = new AmericanExercise(today, exDate); + + spot .setValue(values[i].s); + qRate.setValue(values[i].q); + rRate.setValue(values[i].r); + vol .setValue(values[i].v); + + BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); + + IPricingEngine engine = new BjerksundStenslandApproximationEngine(stochProcess); + + VanillaOption option = new VanillaOption(payoff, exercise); + option.setPricingEngine(engine); + + double calculated = option.NPV(); + double error = Math.Abs(calculated - values[i].result); + if (error > tolerance) + { + REPORT_FAILURE("value", payoff, exercise, values[i].s, values[i].q, + values[i].r, today, values[i].v, values[i].result, + calculated, error, tolerance); } - } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testBjerksundStenslandValues() { - // ("Testing Bjerksund and Stensland approximation for American options..."); - - AmericanOptionData[] values = new AmericanOptionData[] { - // type, strike, spot, q, r, t, vol, value, tol - // from "Option pricing formulas", Haug, McGraw-Hill 1998, pag 27 - new AmericanOptionData(Option.Type.Call, 40.00, 42.00, 0.08, 0.04, 0.75, 0.35, 5.2704), - // from "Option pricing formulas", Haug, McGraw-Hill 1998, VBA code - new AmericanOptionData(Option.Type.Put, 40.00, 36.00, 0.00, 0.06, 1.00, 0.20, 4.4531), - // ATM option with very small volatility, reference value taken from R - new AmericanOptionData( Option.Type.Call, 100, 100, 0.05, 0.05, 1.0, 0.0021, 0.08032314 ), - // ATM option with very small volatility, - // reference value taken from Barone-Adesi and Whaley Approximation - new AmericanOptionData( Option.Type.Call, 100, 100, 0.05, 0.05, 1.0, 0.0001, 0.003860656 ), - new AmericanOptionData( Option.Type.Call, 100, 99.99, 0.05, 0.05, 1.0, 0.0001, 0.00081 ), - // ITM option with a very small volatility - new AmericanOptionData( Option.Type.Call, 100, 110, 0.05, 0.05, 1.0, 0.0001, 10.0 ), - new AmericanOptionData( Option.Type.Put, 110, 100, 0.05, 0.05, 1.0, 0.0001, 10.0 ), - // ATM option with a very large volatility - new AmericanOptionData( Option.Type.Put, 100, 110, 0.05, 0.05, 1.0, 10, 94.89543 ) - }; + public void testJuValues() + { - Date today = Date.Today; - DayCounter dc = new Actual360(); - SimpleQuote spot = new SimpleQuote(0.0); - SimpleQuote qRate = new SimpleQuote(0.0); - YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc); + // ("Testing Ju approximation for American options..."); - SimpleQuote rRate = new SimpleQuote(0.0); - YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc); - SimpleQuote vol = new SimpleQuote(0.0); - BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); + Date today = Date.Today; + DayCounter dc = new Actual360(); + SimpleQuote spot = new SimpleQuote(0.0); + SimpleQuote qRate = new SimpleQuote(0.0); + YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc); + + SimpleQuote rRate = new SimpleQuote(0.0); + YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc); + SimpleQuote vol = new SimpleQuote(0.0); + BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - double tolerance = 5.0e-5; + double tolerance = 1.0e-3; - for (int i=0; i(spot), - new Handle(qTS), - new Handle(rTS), - new Handle(volTS)); + BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); - IPricingEngine engine = new BjerksundStenslandApproximationEngine(stochProcess); + IPricingEngine engine = new JuQuadraticApproximationEngine(stochProcess); - VanillaOption option = new VanillaOption(payoff, exercise); - option.setPricingEngine(engine); + VanillaOption option = new VanillaOption(payoff, exercise); + option.setPricingEngine(engine); - double calculated = option.NPV(); - double error = Math.Abs(calculated-values[i].result); - if (error > tolerance) { - REPORT_FAILURE("value", payoff, exercise, values[i].s, values[i].q, - values[i].r, today, values[i].v, values[i].result, - calculated, error, tolerance); - } + double calculated = option.NPV(); + double error = Math.Abs(calculated - juValues[i].result); + if (error > tolerance) + { + REPORT_FAILURE("value", payoff, exercise, juValues[i].s, juValues[i].q, + juValues[i].r, today, juValues[i].v, juValues[i].result, + calculated, error, tolerance); } - } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testJuValues() { + public void testFdValues() + { - // ("Testing Ju approximation for American options..."); + //("Testing finite-difference engine for American options..."); - Date today = Date.Today; - DayCounter dc = new Actual360(); - SimpleQuote spot = new SimpleQuote(0.0); - SimpleQuote qRate = new SimpleQuote(0.0); - YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc); + Date today = Date.Today; + DayCounter dc = new Actual360(); + SimpleQuote spot = new SimpleQuote(0.0); + SimpleQuote qRate = new SimpleQuote(0.0); + YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc); - SimpleQuote rRate = new SimpleQuote(0.0); - YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc); - SimpleQuote vol = new SimpleQuote(0.0); - BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); + SimpleQuote rRate = new SimpleQuote(0.0); + YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc); + SimpleQuote vol = new SimpleQuote(0.0); + BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - double tolerance = 1.0e-3; + double tolerance = 8.0e-2; - for (int i = 0; i < juValues.Length; i++) { + for (int i = 0; i < juValues.Length; i++) + { - StrikedTypePayoff payoff = new PlainVanillaPayoff(juValues[i].type, juValues[i].strike); - Date exDate = today + Convert.ToInt32(juValues[i].t*360+0.5); - Exercise exercise = new AmericanExercise(today, exDate); + StrikedTypePayoff payoff = new PlainVanillaPayoff(juValues[i].type, juValues[i].strike); + Date exDate = today + Convert.ToInt32(juValues[i].t * 360 + 0.5); + Exercise exercise = new AmericanExercise(today, exDate); - spot .setValue(juValues[i].s); - qRate.setValue(juValues[i].q); - rRate.setValue(juValues[i].r); - vol .setValue(juValues[i].v); + spot .setValue(juValues[i].s); + qRate.setValue(juValues[i].q); + rRate.setValue(juValues[i].r); + vol .setValue(juValues[i].v); - BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), - new Handle(qTS), - new Handle(rTS), - new Handle(volTS)); + BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); - IPricingEngine engine = new JuQuadraticApproximationEngine(stochProcess); + IPricingEngine engine = new FDAmericanEngine(stochProcess, 100, 100); - VanillaOption option = new VanillaOption(payoff, exercise); - option.setPricingEngine(engine); + VanillaOption option = new VanillaOption(payoff, exercise); + option.setPricingEngine(engine); - double calculated = option.NPV(); - double error = Math.Abs(calculated - juValues[i].result); - if (error > tolerance) { - REPORT_FAILURE("value", payoff, exercise, juValues[i].s, juValues[i].q, - juValues[i].r, today, juValues[i].v, juValues[i].result, - calculated, error, tolerance); - } + double calculated = option.NPV(); + double error = Math.Abs(calculated - juValues[i].result); + if (error > tolerance) + { + REPORT_FAILURE("value", payoff, exercise, juValues[i].s, juValues[i].q, + juValues[i].r, today, juValues[i].v, juValues[i].result, + calculated, error, tolerance); } - } + } + } -#if NET40 || NET45 - [TestMethod()] -#else - [Fact] -#endif - public void testFdValues() { + public void testFdGreeks() where Engine : IFDEngine, new () + { + using (SavedSettings backup = new SavedSettings()) + { + + Dictionary calculated = new Dictionary(), + expected = new Dictionary(), + tolerance = new Dictionary(); + + tolerance.Add("delta", 7.0e-4); + tolerance.Add("gamma", 2.0e-4); + //tolerance["theta"] = 1.0e-4; - //("Testing finite-difference engine for American options..."); + Option.Type[] types = new Option.Type[] { Option.Type.Call, Option.Type.Put }; + double[] strikes = { 50.0, 99.5, 100.0, 100.5, 150.0 }; + double[] underlyings = { 100.0 }; + double[] qRates = { 0.04, 0.05, 0.06 }; + double[] rRates = { 0.01, 0.05, 0.15 }; + int[] years = { 1, 2 }; + double[] vols = { 0.11, 0.50, 1.20 }; Date today = Date.Today; + Settings.setEvaluationDate(today); + DayCounter dc = new Actual360(); SimpleQuote spot = new SimpleQuote(0.0); SimpleQuote qRate = new SimpleQuote(0.0); @@ -379,238 +465,174 @@ public void testFdValues() { SimpleQuote vol = new SimpleQuote(0.0); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - double tolerance = 8.0e-2; - - for (int i = 0; i < juValues.Length; i++) { - - StrikedTypePayoff payoff = new PlainVanillaPayoff(juValues[i].type, juValues[i].strike); - Date exDate = today + Convert.ToInt32(juValues[i].t*360+0.5); - Exercise exercise = new AmericanExercise(today, exDate); - - spot .setValue(juValues[i].s); - qRate.setValue(juValues[i].q); - rRate.setValue(juValues[i].r); - vol .setValue(juValues[i].v); - - BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), - new Handle(qTS), - new Handle(rTS), - new Handle(volTS)); - - IPricingEngine engine = new FDAmericanEngine(stochProcess, 100,100); - - VanillaOption option = new VanillaOption(payoff, exercise); - option.setPricingEngine(engine); - - double calculated = option.NPV(); - double error = Math.Abs(calculated - juValues[i].result); - if (error > tolerance) { - REPORT_FAILURE("value", payoff, exercise, juValues[i].s, juValues[i].q, - juValues[i].r, today, juValues[i].v, juValues[i].result, - calculated, error, tolerance); - } - } - } - - public void testFdGreeks() where Engine : IFDEngine, new() - { - using ( SavedSettings backup = new SavedSettings() ) - { - - Dictionary calculated = new Dictionary(), - expected = new Dictionary(), - tolerance = new Dictionary(); - - tolerance.Add( "delta", 7.0e-4 ); - tolerance.Add( "gamma", 2.0e-4 ); - //tolerance["theta"] = 1.0e-4; - - Option.Type[] types = new Option.Type[] { Option.Type.Call, Option.Type.Put }; - double[] strikes = { 50.0, 99.5, 100.0, 100.5, 150.0 }; - double[] underlyings = { 100.0 }; - double[] qRates = { 0.04, 0.05, 0.06 }; - double[] rRates = { 0.01, 0.05, 0.15 }; - int[] years = { 1, 2 }; - double[] vols = { 0.11, 0.50, 1.20 }; - - Date today = Date.Today; - Settings.setEvaluationDate( today ); - - DayCounter dc = new Actual360(); - SimpleQuote spot = new SimpleQuote( 0.0 ); - SimpleQuote qRate = new SimpleQuote( 0.0 ); - YieldTermStructure qTS = Utilities.flatRate( today, qRate, dc ); - - SimpleQuote rRate = new SimpleQuote( 0.0 ); - YieldTermStructure rTS = Utilities.flatRate( today, rRate, dc ); - SimpleQuote vol = new SimpleQuote( 0.0 ); - BlackVolTermStructure volTS = Utilities.flatVol( today, vol, dc ); - - for ( int i = 0; i < types.Length; i++ ) - { - for ( int j = 0; j < strikes.Length; j++ ) - { - for ( int k = 0; k < years.Length; k++ ) - { - Date exDate = today + new Period( years[k], TimeUnit.Years ); - Exercise exercise = new AmericanExercise( today, exDate ); - StrikedTypePayoff payoff = new PlainVanillaPayoff( types[i], strikes[j] ); - BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess( new Handle( spot ), - new Handle( qTS ), - new Handle( rTS ), - new Handle( volTS ) ); - - IPricingEngine engine = FastActivator.Create().factory( stochProcess ); - - VanillaOption option = new VanillaOption( payoff, exercise ); - option.setPricingEngine( engine ); - - for ( int l = 0; l < underlyings.Length; l++ ) - { - for ( int m = 0; m < qRates.Length; m++ ) - { - for ( int n = 0; n < rRates.Length; n++ ) - { - for ( int p = 0; p < vols.Length; p++ ) - { - double u = underlyings[l]; - double q = qRates[m], + for (int i = 0; i < types.Length; i++) + { + for (int j = 0; j < strikes.Length; j++) + { + for (int k = 0; k < years.Length; k++) + { + Date exDate = today + new Period(years[k], TimeUnit.Years); + Exercise exercise = new AmericanExercise(today, exDate); + StrikedTypePayoff payoff = new PlainVanillaPayoff(types[i], strikes[j]); + BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); + + IPricingEngine engine = FastActivator.Create().factory(stochProcess); + + VanillaOption option = new VanillaOption(payoff, exercise); + option.setPricingEngine(engine); + + for (int l = 0; l < underlyings.Length; l++) + { + for (int m = 0; m < qRates.Length; m++) + { + for (int n = 0; n < rRates.Length; n++) + { + for (int p = 0; p < vols.Length; p++) + { + double u = underlyings[l]; + double q = qRates[m], r = rRates[n]; - double v = vols[p]; - spot.setValue( u ); - qRate.setValue( q ); - rRate.setValue( r ); - vol.setValue( v ); - - double value = option.NPV(); - calculated.Add( "delta", option.delta() ); - calculated.Add( "gamma", option.gamma() ); - //calculated["theta"] = option.theta(); - - if ( value > spot.value() * 1.0e-5 ) - { - // perturb spot and get delta and gamma - double du = u * 1.0e-4; - spot.setValue( u + du ); - double value_p = option.NPV(), + double v = vols[p]; + spot.setValue(u); + qRate.setValue(q); + rRate.setValue(r); + vol.setValue(v); + + double value = option.NPV(); + calculated.Add("delta", option.delta()); + calculated.Add("gamma", option.gamma()); + //calculated["theta"] = option.theta(); + + if (value > spot.value() * 1.0e-5) + { + // perturb spot and get delta and gamma + double du = u * 1.0e-4; + spot.setValue(u + du); + double value_p = option.NPV(), delta_p = option.delta(); - spot.setValue( u - du ); - double value_m = option.NPV(), + spot.setValue(u - du); + double value_m = option.NPV(), delta_m = option.delta(); - spot.setValue( u ); - expected.Add( "delta", ( value_p - value_m ) / ( 2 * du ) ); - expected.Add( "gamma", ( delta_p - delta_m ) / ( 2 * du ) ); - - /* - // perturb date and get theta - Time dT = dc.yearFraction(today-1, today+1); - Settings::instance().setEvaluationDate(today-1); - value_m = option.NPV(); - Settings::instance().setEvaluationDate(today+1); - value_p = option.NPV(); - Settings::instance().setEvaluationDate(today); - expected["theta"] = (value_p - value_m)/dT; - */ - - // compare - foreach ( string greek in calculated.Keys ) - { - double expct = expected[greek], - calcl = calculated[greek], - tol = tolerance[greek]; - double error = Utilities.relativeError( expct, calcl, u ); - if ( error > tol ) - { - REPORT_FAILURE( greek, payoff, exercise, - u, q, r, today, v, - expct, calcl, error, tol ); - } - } - } - calculated.Clear(); - expected.Clear(); - } - } - } - } - } - } - } - } - } + spot.setValue(u); + expected.Add("delta", (value_p - value_m) / (2 * du)); + expected.Add("gamma", (delta_p - delta_m) / (2 * du)); + + /* + // perturb date and get theta + Time dT = dc.yearFraction(today-1, today+1); + Settings::instance().setEvaluationDate(today-1); + value_m = option.NPV(); + Settings::instance().setEvaluationDate(today+1); + value_p = option.NPV(); + Settings::instance().setEvaluationDate(today); + expected["theta"] = (value_p - value_m)/dT; + */ + + // compare + foreach (string greek in calculated.Keys) + { + double expct = expected[greek], + calcl = calculated[greek], + tol = tolerance[greek]; + double error = Utilities.relativeError(expct, calcl, u); + if (error > tol) + { + REPORT_FAILURE(greek, payoff, exercise, + u, q, r, today, v, + expct, calcl, error, tol); + } + } + } + calculated.Clear(); + expected.Clear(); + } + } + } + } + } + } + } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testFdAmericanGreeks() { - //("Testing finite-differences American option greeks..."); - testFdGreeks(); - } + public void testFdAmericanGreeks() + { + //("Testing finite-differences American option greeks..."); + testFdGreeks(); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testFdShoutGreeks() { - // ("Testing finite-differences shout option greeks..."); - testFdGreeks(); - } - - void REPORT_FAILURE(string greekName, StrikedTypePayoff payoff, Exercise exercise, double s, double q, double r, - Date today, double v, double expected, double calculated, double error, double tolerance) { - QAssert.Fail(exercise + " " - + payoff.optionType() + " option with " - + payoff + " payoff:\n" - + " spot value: " + s + "\n" - + " strike: " + payoff.strike() + "\n" - + " dividend yield: " + q + "\n" - + " risk-free rate: " + r + "\n" - + " reference date: " + today + "\n" - + " maturity: " + exercise.lastDate() + "\n" - + " volatility: " + v + "\n\n" - + " expected " + greekName + ": " + expected + "\n" - + " calculated " + greekName + ": " + calculated + "\n" - + " error: " + error + "\n" - + " tolerance: " + tolerance); - } + public void testFdShoutGreeks() + { + // ("Testing finite-differences shout option greeks..."); + testFdGreeks(); + } + + void REPORT_FAILURE(string greekName, StrikedTypePayoff payoff, Exercise exercise, double s, double q, double r, + Date today, double v, double expected, double calculated, double error, double tolerance) + { + QAssert.Fail(exercise + " " + + payoff.optionType() + " option with " + + payoff + " payoff:\n" + + " spot value: " + s + "\n" + + " strike: " + payoff.strike() + "\n" + + " dividend yield: " + q + "\n" + + " risk-free rate: " + r + "\n" + + " reference date: " + today + "\n" + + " maturity: " + exercise.lastDate() + "\n" + + " volatility: " + v + "\n\n" + + " expected " + greekName + ": " + expected + "\n" + + " calculated " + greekName + ": " + calculated + "\n" + + " error: " + error + "\n" + + " tolerance: " + tolerance); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testFdImpliedVol() - { - var settlementDate = new Date(26, 2, 2015); - Settings.setEvaluationDate(settlementDate); - - var calendar = new TARGET(); - var dayCounter = new Actual365Fixed(); - - const double volatility = 0.5; - var underlyingQuote = new Handle(new SimpleQuote(3227)); - var flatTermStructure = new Handle(new FlatForward(settlementDate, 0.05, dayCounter)); - var flatDividendYield = new Handle(new FlatForward(settlementDate, 0, dayCounter)); - var flatVolatility = new Handle(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter)); - var process = new BlackScholesMertonProcess(underlyingQuote, flatDividendYield, flatTermStructure, flatVolatility); - var exercise = new AmericanExercise(new Date(1, 12, 2015)); - var pricingEngine = new FDDividendAmericanEngine(process); - var payoff = new PlainVanillaPayoff(Option.Type.Put, 3200); - var dividendDates = new[] { new Date(1, 3, 2015) }; - var dividendAmounts = new[] {10d}; - var option = new DividendVanillaOption(payoff, exercise, dividendDates.ToList(), dividendAmounts.ToList()); - option.setPricingEngine(pricingEngine); - - var npv = option.NPV(); - var impliedVol = option.impliedVolatility(npv, process); - - const double tolerance = 3.0e-3; - - if (Math.Abs(impliedVol - volatility) > tolerance) - QAssert.Fail(string.Format("Implied volatility calculation failed. Expected {0}. Actual {1}", volatility, impliedVol)); - } + public void testFdImpliedVol() + { + var settlementDate = new Date(26, 2, 2015); + Settings.setEvaluationDate(settlementDate); + + var calendar = new TARGET(); + var dayCounter = new Actual365Fixed(); + + const double volatility = 0.5; + var underlyingQuote = new Handle(new SimpleQuote(3227)); + var flatTermStructure = new Handle(new FlatForward(settlementDate, 0.05, dayCounter)); + var flatDividendYield = new Handle(new FlatForward(settlementDate, 0, dayCounter)); + var flatVolatility = new Handle(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter)); + var process = new BlackScholesMertonProcess(underlyingQuote, flatDividendYield, flatTermStructure, flatVolatility); + var exercise = new AmericanExercise(new Date(1, 12, 2015)); + var pricingEngine = new FDDividendAmericanEngine(process); + var payoff = new PlainVanillaPayoff(Option.Type.Put, 3200); + var dividendDates = new[] { new Date(1, 3, 2015) }; + var dividendAmounts = new[] {10d}; + var option = new DividendVanillaOption(payoff, exercise, dividendDates.ToList(), dividendAmounts.ToList()); + option.setPricingEngine(pricingEngine); + + var npv = option.NPV(); + var impliedVol = option.impliedVolatility(npv, process); + + const double tolerance = 3.0e-3; + + if (Math.Abs(impliedVol - volatility) > tolerance) + QAssert.Fail(string.Format("Implied volatility calculation failed. Expected {0}. Actual {1}", volatility, impliedVol)); + } } } diff --git a/tests/QLNet.Tests/T_AsianOptions.cs b/tests/QLNet.Tests/T_AsianOptions.cs index aaf1700fa..d05bf0b05 100644 --- a/tests/QLNet.Tests/T_AsianOptions.cs +++ b/tests/QLNet.Tests/T_AsianOptions.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,65 +24,65 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; namespace TestSuite { - #if NET40 || NET45 +#if NET40 || NET45 [TestClass()] - #endif +#endif public class T_AsianOptions { - public void REPORT_FAILURE( string greekName, Average.Type averageType, - double? runningAccumulator, int? pastFixings, - List fixingDates, StrikedTypePayoff payoff, - Exercise exercise, double s, double q, double r, - Date today, double v, double expected, - double calculated, double tolerance ) + public void REPORT_FAILURE(string greekName, Average.Type averageType, + double? runningAccumulator, int? pastFixings, + List fixingDates, StrikedTypePayoff payoff, + Exercise exercise, double s, double q, double r, + Date today, double v, double expected, + double calculated, double tolerance) { - QAssert.Fail( exercise + " " - + exercise - + " Asian option with " - + averageType + " and " - + payoff + " payoff:\n" - + " running variable: " - + runningAccumulator + "\n" - + " past fixings: " - + pastFixings + "\n" - + " future fixings: " + fixingDates.Count() + "\n" - + " underlying value: " + s + "\n" - + " strike: " + payoff.strike() + "\n" - + " dividend yield: " + q + "\n" - + " risk-free rate: " + r + "\n" - + " reference date: " + today + "\n" - + " maturity: " + exercise.lastDate() + "\n" - + " volatility: " + v + "\n\n" - + " expected " + greekName + ": " + expected + "\n" - + " calculated " + greekName + ": " + calculated + "\n" - + " error: " + Math.Abs( expected - calculated ) - + "\n" - + " tolerance: " + tolerance ); + QAssert.Fail(exercise + " " + + exercise + + " Asian option with " + + averageType + " and " + + payoff + " payoff:\n" + + " running variable: " + + runningAccumulator + "\n" + + " past fixings: " + + pastFixings + "\n" + + " future fixings: " + fixingDates.Count() + "\n" + + " underlying value: " + s + "\n" + + " strike: " + payoff.strike() + "\n" + + " dividend yield: " + q + "\n" + + " risk-free rate: " + r + "\n" + + " reference date: " + today + "\n" + + " maturity: " + exercise.lastDate() + "\n" + + " volatility: " + v + "\n\n" + + " expected " + greekName + ": " + expected + "\n" + + " calculated " + greekName + ": " + calculated + "\n" + + " error: " + Math.Abs(expected - calculated) + + "\n" + + " tolerance: " + tolerance); } - public string averageTypeToString( Average.Type averageType ) + public string averageTypeToString(Average.Type averageType) { - if ( averageType == Average.Type.Geometric ) + if (averageType == Average.Type.Geometric) return "Geometric Averaging"; - else if ( averageType == Average.Type.Arithmetic ) + else if (averageType == Average.Type.Arithmetic) return "Arithmetic Averaging"; else - Utils.QL_FAIL( "unknown averaging" ); + Utils.QL_FAIL("unknown averaging"); return String.Empty; } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testAnalyticContinuousGeometricAveragePrice() { @@ -92,22 +92,22 @@ public void testAnalyticContinuousGeometricAveragePrice() DayCounter dc = new Actual360(); Date today = Date.Today; - SimpleQuote spot = new SimpleQuote( 80.0 ); - SimpleQuote qRate = new SimpleQuote( -0.03 ); - YieldTermStructure qTS = Utilities.flatRate( today, qRate, dc ); - SimpleQuote rRate = new SimpleQuote( 0.05 ); - YieldTermStructure rTS = Utilities.flatRate( today, rRate, dc ); - SimpleQuote vol = new SimpleQuote( 0.20 ); - BlackVolTermStructure volTS = Utilities.flatVol( today, vol, dc ); + SimpleQuote spot = new SimpleQuote(80.0); + SimpleQuote qRate = new SimpleQuote(-0.03); + YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc); + SimpleQuote rRate = new SimpleQuote(0.05); + YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc); + SimpleQuote vol = new SimpleQuote(0.20); + BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); BlackScholesMertonProcess stochProcess = new - BlackScholesMertonProcess( new Handle( spot ), - new Handle( qTS ), - new Handle( rTS ), - new Handle( volTS ) ); + BlackScholesMertonProcess(new Handle(spot), + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); IPricingEngine engine = new - AnalyticContinuousGeometricAveragePriceAsianEngine( stochProcess ); + AnalyticContinuousGeometricAveragePriceAsianEngine(stochProcess); Average.Type averageType = Average.Type.Geometric; Option.Type type = Option.Type.Put; @@ -115,57 +115,57 @@ public void testAnalyticContinuousGeometricAveragePrice() Date exerciseDate = today + 90; int? pastFixings = null; - double? runningAccumulator = null; + double? runningAccumulator = null; - StrikedTypePayoff payoff = new PlainVanillaPayoff( type, strike ); + StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike); - Exercise exercise = new EuropeanExercise( exerciseDate ); + Exercise exercise = new EuropeanExercise(exerciseDate); - ContinuousAveragingAsianOption option = new ContinuousAveragingAsianOption( averageType, payoff, exercise ); - option.setPricingEngine( engine ); + ContinuousAveragingAsianOption option = new ContinuousAveragingAsianOption(averageType, payoff, exercise); + option.setPricingEngine(engine); double calculated = option.NPV(); double expected = 4.6922; double tolerance = 1.0e-4; - if ( Math.Abs( calculated - expected ) > tolerance ) + if (Math.Abs(calculated - expected) > tolerance) { - REPORT_FAILURE( "value", averageType, runningAccumulator, pastFixings, + REPORT_FAILURE("value", averageType, runningAccumulator, pastFixings, new List(), payoff, exercise, spot.value(), qRate.value(), rRate.value(), today, - vol.value(), expected, calculated, tolerance ); + vol.value(), expected, calculated, tolerance); } // trying to approximate the continuous version with the discrete version runningAccumulator = 1.0; pastFixings = 0; - List fixingDates = new InitializedList( exerciseDate - today + 1 ); - for ( int i = 0; i < fixingDates.Count; i++ ) + List fixingDates = new InitializedList(exerciseDate - today + 1); + for (int i = 0; i < fixingDates.Count; i++) { fixingDates[i] = today + i; } - IPricingEngine engine2 = new AnalyticDiscreteGeometricAveragePriceAsianEngine( stochProcess ); + IPricingEngine engine2 = new AnalyticDiscreteGeometricAveragePriceAsianEngine(stochProcess); + + DiscreteAveragingAsianOption option2 = new DiscreteAveragingAsianOption(averageType, runningAccumulator, + pastFixings, fixingDates, payoff, exercise); - DiscreteAveragingAsianOption option2 = new DiscreteAveragingAsianOption( averageType,runningAccumulator, - pastFixings,fixingDates,payoff,exercise ); - - option2.setPricingEngine( engine2 ); + option2.setPricingEngine(engine2); calculated = option2.NPV(); tolerance = 3.0e-3; if (Math.Abs(calculated - expected) > tolerance) { - REPORT_FAILURE("value", averageType, runningAccumulator, pastFixings, - fixingDates, payoff, exercise, spot.value(), - qRate.value(), rRate.value(), today, - vol.value(), expected, calculated, tolerance); + REPORT_FAILURE("value", averageType, runningAccumulator, pastFixings, + fixingDates, payoff, exercise, spot.value(), + qRate.value(), rRate.value(), today, + vol.value(), expected, calculated, tolerance); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testAnalyticContinuousGeometricAveragePriceGreeks() { @@ -173,9 +173,9 @@ public void testAnalyticContinuousGeometricAveragePriceGreeks() using (SavedSettings backup = new SavedSettings()) { Dictionary calculated, expected, tolerance; - calculated = new Dictionary( 6 ); - expected = new Dictionary( 6 ); - tolerance = new Dictionary( 6 ); + calculated = new Dictionary(6); + expected = new Dictionary(6); + tolerance = new Dictionary(6); tolerance["delta"] = 1.0e-5; tolerance["gamma"] = 1.0e-5; tolerance["theta"] = 1.0e-5; @@ -193,53 +193,53 @@ public void testAnalyticContinuousGeometricAveragePriceGreeks() DayCounter dc = new Actual360(); Date today = Date.Today; - Settings.setEvaluationDate( today ); + Settings.setEvaluationDate(today); - SimpleQuote spot = new SimpleQuote( 0.0 ); - SimpleQuote qRate = new SimpleQuote( 0.0 ); - Handle qTS = new Handle( Utilities.flatRate( qRate, dc ) ); - SimpleQuote rRate = new SimpleQuote( 0.0 ); - Handle rTS = new Handle( Utilities.flatRate( rRate, dc ) ); - SimpleQuote vol = new SimpleQuote( 0.0 ); - Handle volTS = new Handle( Utilities.flatVol( vol, dc ) ); + SimpleQuote spot = new SimpleQuote(0.0); + SimpleQuote qRate = new SimpleQuote(0.0); + Handle qTS = new Handle(Utilities.flatRate(qRate, dc)); + SimpleQuote rRate = new SimpleQuote(0.0); + Handle rTS = new Handle(Utilities.flatRate(rRate, dc)); + SimpleQuote vol = new SimpleQuote(0.0); + Handle volTS = new Handle(Utilities.flatVol(vol, dc)); - BlackScholesMertonProcess process = new BlackScholesMertonProcess( new Handle( spot ), qTS, rTS, volTS ); + BlackScholesMertonProcess process = new BlackScholesMertonProcess(new Handle(spot), qTS, rTS, volTS); - for ( int i = 0; i < types.Length; i++ ) + for (int i = 0; i < types.Length; i++) { - for ( int j = 0; j < strikes.Length; j++ ) + for (int j = 0; j < strikes.Length; j++) { - for ( int k = 0; k < lengths.Length; k++ ) + for (int k = 0; k < lengths.Length; k++) { - EuropeanExercise maturity = new EuropeanExercise( today + new Period( lengths[k], TimeUnit.Years ) ); - PlainVanillaPayoff payoff = new PlainVanillaPayoff( types[i], strikes[j] ); + EuropeanExercise maturity = new EuropeanExercise(today + new Period(lengths[k], TimeUnit.Years)); + PlainVanillaPayoff payoff = new PlainVanillaPayoff(types[i], strikes[j]); - IPricingEngine engine = new AnalyticContinuousGeometricAveragePriceAsianEngine( process ); + IPricingEngine engine = new AnalyticContinuousGeometricAveragePriceAsianEngine(process); - ContinuousAveragingAsianOption option = new ContinuousAveragingAsianOption( Average.Type.Geometric, - payoff, maturity ); - option.setPricingEngine( engine ); + ContinuousAveragingAsianOption option = new ContinuousAveragingAsianOption(Average.Type.Geometric, + payoff, maturity); + option.setPricingEngine(engine); int? pastFixings = null; double? runningAverage = null; - for ( int l = 0; l < underlyings.Length; l++ ) + for (int l = 0; l < underlyings.Length; l++) { - for ( int m = 0; m < qRates.Length; m++ ) + for (int m = 0; m < qRates.Length; m++) { - for ( int n = 0; n < rRates.Length; n++ ) + for (int n = 0; n < rRates.Length; n++) { - for ( int p = 0; p < vols.Length; p++ ) + for (int p = 0; p < vols.Length; p++) { double u = underlyings[l]; double q = qRates[m], r = rRates[n]; double v = vols[p]; - spot.setValue( u ); - qRate.setValue( q ); - rRate.setValue( r ); - vol.setValue( v ); + spot.setValue(u); + qRate.setValue(q); + rRate.setValue(r); + vol.setValue(v); double value = option.NPV(); calculated["delta"] = option.delta(); @@ -249,71 +249,71 @@ public void testAnalyticContinuousGeometricAveragePriceGreeks() calculated["divRho"] = option.dividendRho(); calculated["vega"] = option.vega(); - if ( value > spot.value() * 1.0e-5 ) + if (value > spot.value() * 1.0e-5) { // perturb spot and get delta and gamma double du = u * 1.0e-4; - spot.setValue( u + du ); + spot.setValue(u + du); double value_p = option.NPV(), delta_p = option.delta(); - spot.setValue( u - du ); + spot.setValue(u - du); double value_m = option.NPV(), - delta_m = option.delta(); - spot.setValue( u ); - expected["delta"] = ( value_p - value_m ) / ( 2 * du ); - expected["gamma"] = ( delta_p - delta_m ) / ( 2 * du ); + delta_m = option.delta(); + spot.setValue(u); + expected["delta"] = (value_p - value_m) / (2 * du); + expected["gamma"] = (delta_p - delta_m) / (2 * du); // perturb rates and get rho and dividend rho double dr = r * 1.0e-4; - rRate.setValue( r + dr ); + rRate.setValue(r + dr); value_p = option.NPV(); - rRate.setValue( r - dr ); + rRate.setValue(r - dr); value_m = option.NPV(); - rRate.setValue( r ); - expected["rho"] = ( value_p - value_m ) / ( 2 * dr ); + rRate.setValue(r); + expected["rho"] = (value_p - value_m) / (2 * dr); double dq = q * 1.0e-4; - qRate.setValue( q + dq ); + qRate.setValue(q + dq); value_p = option.NPV(); - qRate.setValue( q - dq ); + qRate.setValue(q - dq); value_m = option.NPV(); - qRate.setValue( q ); - expected["divRho"] = ( value_p - value_m ) / ( 2 * dq ); + qRate.setValue(q); + expected["divRho"] = (value_p - value_m) / (2 * dq); // perturb volatility and get vega double dv = v * 1.0e-4; - vol.setValue( v + dv ); + vol.setValue(v + dv); value_p = option.NPV(); - vol.setValue( v - dv ); + vol.setValue(v - dv); value_m = option.NPV(); - vol.setValue( v ); - expected["vega"] = ( value_p - value_m ) / ( 2 * dv ); + vol.setValue(v); + expected["vega"] = (value_p - value_m) / (2 * dv); // perturb date and get theta - double dT = dc.yearFraction( today - 1, today + 1 ); - Settings.setEvaluationDate( today - 1 ); + double dT = dc.yearFraction(today - 1, today + 1); + Settings.setEvaluationDate(today - 1); value_m = option.NPV(); - Settings.setEvaluationDate( today + 1 ); + Settings.setEvaluationDate(today + 1); value_p = option.NPV(); - Settings.setEvaluationDate( today ); - expected["theta"] = ( value_p - value_m ) / dT; + Settings.setEvaluationDate(today); + expected["theta"] = (value_p - value_m) / dT; // compare - foreach ( KeyValuePair kvp in calculated ) + foreach (KeyValuePair kvp in calculated) { string greek = kvp.Key; double expct = expected[greek], calcl = calculated[greek], tol = tolerance[greek]; - double error = Utilities.relativeError( expct, calcl, u ); - if ( error > tol ) + double error = Utilities.relativeError(expct, calcl, u); + if (error > tol) { - REPORT_FAILURE( greek, Average.Type.Geometric, + REPORT_FAILURE(greek, Average.Type.Geometric, runningAverage, pastFixings, new List(), payoff, maturity, u, q, r, today, v, - expct, calcl, tol ); + expct, calcl, tol); } } } @@ -328,9 +328,9 @@ public void testAnalyticContinuousGeometricAveragePriceGreeks() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testAnalyticDiscreteGeometricAveragePrice() { @@ -341,21 +341,21 @@ public void testAnalyticDiscreteGeometricAveragePrice() DayCounter dc = new Actual360(); Date today = Date.Today; - SimpleQuote spot = new SimpleQuote( 100.0 ); - SimpleQuote qRate = new SimpleQuote( 0.03 ); - YieldTermStructure qTS = Utilities.flatRate( today, qRate, dc ); - SimpleQuote rRate = new SimpleQuote( 0.06 ); - YieldTermStructure rTS = Utilities.flatRate( today, rRate, dc ); - SimpleQuote vol = new SimpleQuote( 0.20 ); - BlackVolTermStructure volTS = Utilities.flatVol( today, vol, dc ); + SimpleQuote spot = new SimpleQuote(100.0); + SimpleQuote qRate = new SimpleQuote(0.03); + YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc); + SimpleQuote rRate = new SimpleQuote(0.06); + YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc); + SimpleQuote vol = new SimpleQuote(0.20); + BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); BlackScholesMertonProcess stochProcess = new - BlackScholesMertonProcess( new Handle( spot ), - new Handle( qTS ), - new Handle( rTS ), - new Handle( volTS ) ); + BlackScholesMertonProcess(new Handle(spot), + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); - IPricingEngine engine = new AnalyticDiscreteGeometricAveragePriceAsianEngine( stochProcess ); + IPricingEngine engine = new AnalyticDiscreteGeometricAveragePriceAsianEngine(stochProcess); Average.Type averageType = Average.Type.Geometric; double runningAccumulator = 1.0; @@ -363,39 +363,39 @@ public void testAnalyticDiscreteGeometricAveragePrice() int futureFixings = 10; Option.Type type = Option.Type.Call; double strike = 100.0; - StrikedTypePayoff payoff = new PlainVanillaPayoff( type, strike ); + StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike); Date exerciseDate = today + 360; - Exercise exercise = new EuropeanExercise( exerciseDate ); + Exercise exercise = new EuropeanExercise(exerciseDate); - List fixingDates = new InitializedList( futureFixings ); - int dt = (int)( 360 / futureFixings + 0.5 ); + List fixingDates = new InitializedList(futureFixings); + int dt = (int)(360 / futureFixings + 0.5); fixingDates[0] = today + dt; - for ( int j = 1; j < futureFixings; j++ ) + for (int j = 1; j < futureFixings; j++) fixingDates[j] = fixingDates[j - 1] + dt; - DiscreteAveragingAsianOption option = new DiscreteAveragingAsianOption( averageType, runningAccumulator, - pastFixings, fixingDates, payoff, exercise ); - option.setPricingEngine( engine ); + DiscreteAveragingAsianOption option = new DiscreteAveragingAsianOption(averageType, runningAccumulator, + pastFixings, fixingDates, payoff, exercise); + option.setPricingEngine(engine); double calculated = option.NPV(); double expected = 5.3425606635; double tolerance = 1e-10; - if ( Math.Abs( calculated - expected ) > tolerance ) + if (Math.Abs(calculated - expected) > tolerance) { - REPORT_FAILURE( "value", averageType, runningAccumulator, pastFixings, + REPORT_FAILURE("value", averageType, runningAccumulator, pastFixings, fixingDates, payoff, exercise, spot.value(), qRate.value(), rRate.value(), today, - vol.value(), expected, calculated, tolerance ); + vol.value(), expected, calculated, tolerance); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testAnalyticDiscreteGeometricAverageStrike() + public void testAnalyticDiscreteGeometricAverageStrike() { // Testing analytic discrete geometric average-strike Asians @@ -411,9 +411,9 @@ public void testAnalyticDiscreteGeometricAverageStrike() BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), - new Handle(qTS), - new Handle(rTS), - new Handle(volTS)); + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); IPricingEngine engine = new AnalyticDiscreteGeometricAverageStrikeAsianEngine(stochProcess); @@ -429,26 +429,26 @@ public void testAnalyticDiscreteGeometricAverageStrike() Exercise exercise = new EuropeanExercise(exerciseDate); List fixingDates = new InitializedList(futureFixings); - int dt = (int)(360/futureFixings+0.5); + int dt = (int)(360 / futureFixings + 0.5); fixingDates[0] = today + dt; - for (int j=1; j tolerance) + if (Math.Abs(calculated - expected) > tolerance) { REPORT_FAILURE("value", averageType, runningAccumulator, pastFixings, fixingDates, payoff, exercise, spot.value(), qRate.value(), rRate.value(), today, vol.value(), expected, calculated, tolerance); } - + } //[TestMethod()] @@ -461,28 +461,28 @@ public void testMCDiscreteGeometricAveragePrice() DayCounter dc = new Actual360(); Date today = Date.Today; - SimpleQuote spot = new SimpleQuote( 100.0 ); - SimpleQuote qRate = new SimpleQuote( 0.03 ); - YieldTermStructure qTS = Utilities.flatRate( today, qRate, dc ); - SimpleQuote rRate = new SimpleQuote( 0.06 ); - YieldTermStructure rTS = Utilities.flatRate( today, rRate, dc ); - SimpleQuote vol = new SimpleQuote( 0.20 ); - BlackVolTermStructure volTS = Utilities.flatVol( today, vol, dc ); + SimpleQuote spot = new SimpleQuote(100.0); + SimpleQuote qRate = new SimpleQuote(0.03); + YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc); + SimpleQuote rRate = new SimpleQuote(0.06); + YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc); + SimpleQuote vol = new SimpleQuote(0.20); + BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); BlackScholesMertonProcess stochProcess = - new BlackScholesMertonProcess( new Handle( spot ), - new Handle( qTS ), - new Handle( rTS ), - new Handle( volTS ) ); + new BlackScholesMertonProcess(new Handle(spot), + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); double tolerance = 4.0e-3; IPricingEngine engine = - new MakeMCDiscreteGeometricAPEngine - ( stochProcess ) - .withStepsPerYear( 1 ) - .withSamples( 8191 ) - .value(); + new MakeMCDiscreteGeometricAPEngine + (stochProcess) + .withStepsPerYear(1) + .withSamples(8191) + .value(); Average.Type averageType = Average.Type.Geometric; double runningAccumulator = 1.0; @@ -490,42 +490,42 @@ public void testMCDiscreteGeometricAveragePrice() int futureFixings = 10; Option.Type type = Option.Type.Call; double strike = 100.0; - StrikedTypePayoff payoff = new PlainVanillaPayoff( type, strike ); + StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike); Date exerciseDate = today + 360; - Exercise exercise = new EuropeanExercise( exerciseDate ); + Exercise exercise = new EuropeanExercise(exerciseDate); - List fixingDates = new InitializedList( futureFixings ); - int dt = (int)( 360 / futureFixings + 0.5 ); + List fixingDates = new InitializedList(futureFixings); + int dt = (int)(360 / futureFixings + 0.5); fixingDates[0] = today + dt; - for ( int j = 1; j < futureFixings; j++ ) + for (int j = 1; j < futureFixings; j++) fixingDates[j] = fixingDates[j - 1] + dt; DiscreteAveragingAsianOption option = - new DiscreteAveragingAsianOption( averageType, runningAccumulator, - pastFixings, fixingDates, - payoff, exercise ); - option.setPricingEngine( engine ); + new DiscreteAveragingAsianOption(averageType, runningAccumulator, + pastFixings, fixingDates, + payoff, exercise); + option.setPricingEngine(engine); double calculated = option.NPV(); - IPricingEngine engine2 = new AnalyticDiscreteGeometricAveragePriceAsianEngine( stochProcess ); - option.setPricingEngine( engine2 ); + IPricingEngine engine2 = new AnalyticDiscreteGeometricAveragePriceAsianEngine(stochProcess); + option.setPricingEngine(engine2); double expected = option.NPV(); - if ( Math.Abs( calculated - expected ) > tolerance ) + if (Math.Abs(calculated - expected) > tolerance) { - REPORT_FAILURE( "value", averageType, runningAccumulator, pastFixings, + REPORT_FAILURE("value", averageType, runningAccumulator, pastFixings, fixingDates, payoff, exercise, spot.value(), qRate.value(), rRate.value(), today, - vol.value(), expected, calculated, tolerance ); + vol.value(), expected, calculated, tolerance); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testAnalyticDiscreteGeometricAveragePriceGreeks() { @@ -534,9 +534,9 @@ public void testAnalyticDiscreteGeometricAveragePriceGreeks() using (SavedSettings backup = new SavedSettings()) { Dictionary calculated, expected, tolerance; - calculated = new Dictionary( 6 ); - expected = new Dictionary( 6 ); - tolerance = new Dictionary( 6 ); + calculated = new Dictionary(6); + expected = new Dictionary(6); + tolerance = new Dictionary(6); tolerance["delta"] = 1.0e-5; tolerance["gamma"] = 1.0e-5; tolerance["theta"] = 1.0e-5; @@ -554,62 +554,62 @@ public void testAnalyticDiscreteGeometricAveragePriceGreeks() DayCounter dc = new Actual360(); Date today = Date.Today; - Settings.setEvaluationDate( today ); + Settings.setEvaluationDate(today); - SimpleQuote spot = new SimpleQuote( 0.0 ); - SimpleQuote qRate = new SimpleQuote( 0.0 ); - Handle qTS = new Handle( Utilities.flatRate( qRate, dc ) ); - SimpleQuote rRate = new SimpleQuote( 0.0 ); - Handle rTS = new Handle( Utilities.flatRate( rRate, dc ) ); - SimpleQuote vol = new SimpleQuote( 0.0 ); - Handle volTS = new Handle( Utilities.flatVol( vol, dc ) ); + SimpleQuote spot = new SimpleQuote(0.0); + SimpleQuote qRate = new SimpleQuote(0.0); + Handle qTS = new Handle(Utilities.flatRate(qRate, dc)); + SimpleQuote rRate = new SimpleQuote(0.0); + Handle rTS = new Handle(Utilities.flatRate(rRate, dc)); + SimpleQuote vol = new SimpleQuote(0.0); + Handle volTS = new Handle(Utilities.flatVol(vol, dc)); - BlackScholesMertonProcess process = new BlackScholesMertonProcess( new Handle( spot ), qTS, rTS, volTS ); + BlackScholesMertonProcess process = new BlackScholesMertonProcess(new Handle(spot), qTS, rTS, volTS); - for ( int i = 0; i < types.Length; i++ ) + for (int i = 0; i < types.Length; i++) { - for ( int j = 0; j < strikes.Length; j++ ) + for (int j = 0; j < strikes.Length; j++) { - for ( int k = 0; k < lengths.Length; k++ ) + for (int k = 0; k < lengths.Length; k++) { - EuropeanExercise maturity = new EuropeanExercise(today + new Period( lengths[k], TimeUnit.Years ) ); + EuropeanExercise maturity = new EuropeanExercise(today + new Period(lengths[k], TimeUnit.Years)); - PlainVanillaPayoff payoff = new PlainVanillaPayoff( types[i], strikes[j] ); + PlainVanillaPayoff payoff = new PlainVanillaPayoff(types[i], strikes[j]); double runningAverage = 120; int pastFixings = 1; List fixingDates = new List(); - for ( Date d = today + new Period( 3, TimeUnit.Months ); - d <= maturity.lastDate(); - d += new Period( 3, TimeUnit.Months ) ) - fixingDates.Add( d ); + for (Date d = today + new Period(3, TimeUnit.Months); + d <= maturity.lastDate(); + d += new Period(3, TimeUnit.Months)) + fixingDates.Add(d); - IPricingEngine engine = new AnalyticDiscreteGeometricAveragePriceAsianEngine( process ); + IPricingEngine engine = new AnalyticDiscreteGeometricAveragePriceAsianEngine(process); - DiscreteAveragingAsianOption option = new DiscreteAveragingAsianOption( Average.Type.Geometric, - runningAverage, pastFixings,fixingDates, payoff, maturity ); + DiscreteAveragingAsianOption option = new DiscreteAveragingAsianOption(Average.Type.Geometric, + runningAverage, pastFixings, fixingDates, payoff, maturity); - option.setPricingEngine( engine ); + option.setPricingEngine(engine); - for ( int l = 0; l < underlyings.Length; l++ ) + for (int l = 0; l < underlyings.Length; l++) { - for ( int m = 0; m < qRates.Length; m++ ) + for (int m = 0; m < qRates.Length; m++) { - for ( int n = 0; n < rRates.Length; n++ ) + for (int n = 0; n < rRates.Length; n++) { - for ( int p = 0; p < vols.Length; p++ ) + for (int p = 0; p < vols.Length; p++) { double u = underlyings[l]; double q = qRates[m], r = rRates[n]; double v = vols[p]; - spot.setValue( u ); - qRate.setValue( q ); - rRate.setValue( r ); - vol.setValue( v ); + spot.setValue(u); + qRate.setValue(q); + rRate.setValue(r); + vol.setValue(v); double value = option.NPV(); calculated["delta"] = option.delta(); @@ -619,71 +619,71 @@ public void testAnalyticDiscreteGeometricAveragePriceGreeks() calculated["divRho"] = option.dividendRho(); calculated["vega"] = option.vega(); - if ( value > spot.value() * 1.0e-5 ) + if (value > spot.value() * 1.0e-5) { // perturb spot and get delta and gamma double du = u * 1.0e-4; - spot.setValue( u + du ); + spot.setValue(u + du); double value_p = option.NPV(), delta_p = option.delta(); - spot.setValue( u - du ); + spot.setValue(u - du); double value_m = option.NPV(), delta_m = option.delta(); - spot.setValue( u ); - expected["delta"] = ( value_p - value_m ) / ( 2 * du ); - expected["gamma"] = ( delta_p - delta_m ) / ( 2 * du ); + spot.setValue(u); + expected["delta"] = (value_p - value_m) / (2 * du); + expected["gamma"] = (delta_p - delta_m) / (2 * du); // perturb rates and get rho and dividend rho double dr = r * 1.0e-4; - rRate.setValue( r + dr ); + rRate.setValue(r + dr); value_p = option.NPV(); - rRate.setValue( r - dr ); + rRate.setValue(r - dr); value_m = option.NPV(); - rRate.setValue( r ); - expected["rho"] = ( value_p - value_m ) / ( 2 * dr ); + rRate.setValue(r); + expected["rho"] = (value_p - value_m) / (2 * dr); double dq = q * 1.0e-4; - qRate.setValue( q + dq ); + qRate.setValue(q + dq); value_p = option.NPV(); - qRate.setValue( q - dq ); + qRate.setValue(q - dq); value_m = option.NPV(); - qRate.setValue( q ); - expected["divRho"] = ( value_p - value_m ) / ( 2 * dq ); + qRate.setValue(q); + expected["divRho"] = (value_p - value_m) / (2 * dq); // perturb volatility and get vega double dv = v * 1.0e-4; - vol.setValue( v + dv ); + vol.setValue(v + dv); value_p = option.NPV(); - vol.setValue( v - dv ); + vol.setValue(v - dv); value_m = option.NPV(); - vol.setValue( v ); - expected["vega"] = ( value_p - value_m ) / ( 2 * dv ); + vol.setValue(v); + expected["vega"] = (value_p - value_m) / (2 * dv); // perturb date and get theta - double dT = dc.yearFraction( today - 1, today + 1 ); - Settings.setEvaluationDate( today - 1 ); + double dT = dc.yearFraction(today - 1, today + 1); + Settings.setEvaluationDate(today - 1); value_m = option.NPV(); - Settings.setEvaluationDate( today + 1 ); + Settings.setEvaluationDate(today + 1); value_p = option.NPV(); - Settings.setEvaluationDate( today ); - expected["theta"] = ( value_p - value_m ) / dT; + Settings.setEvaluationDate(today); + expected["theta"] = (value_p - value_m) / dT; // compare - foreach ( KeyValuePair kvp in calculated ) + foreach (KeyValuePair kvp in calculated) { string greek = kvp.Key; double expct = expected[greek], calcl = calculated[greek], tol = tolerance[greek]; - double error = Utilities.relativeError( expct, calcl, u ); - if ( error > tol ) + double error = Utilities.relativeError(expct, calcl, u); + if (error > tol) { - REPORT_FAILURE( greek, Average.Type.Geometric, + REPORT_FAILURE(greek, Average.Type.Geometric, runningAverage, pastFixings, new List(), payoff, maturity, u, q, r, today, v, - expct, calcl, tol ); + expct, calcl, tol); } } } @@ -704,10 +704,10 @@ public void testIssue115() // set up dates Calendar calendar = new TARGET(); - Date todaysDate = new Date( 1, Month.January, 2017 ); - Date settlementDate = new Date( 1, Month.January, 2017 ); - Date maturity = new Date( 17, Month.May, 2018 ); - Settings.setEvaluationDate( todaysDate ); + Date todaysDate = new Date(1, Month.January, 2017); + Date settlementDate = new Date(1, Month.January, 2017); + Date maturity = new Date(17, Month.May, 2018); + Settings.setEvaluationDate(todaysDate); // our options Option.Type type = Option.Type.Call; @@ -718,32 +718,32 @@ public void testIssue115() double volatility = 0.20; DayCounter dayCounter = new Actual365Fixed(); - Exercise europeanExercise = new EuropeanExercise( maturity ); + Exercise europeanExercise = new EuropeanExercise(maturity); double? accumulator = underlying; int? pastfixingcount = 1; List fixings = new List(); - fixings.Add( new Date( 1, 1, 2018 ) ); + fixings.Add(new Date(1, 1, 2018)); - Handle underlyingH = new Handle( new SimpleQuote( underlying ) ); + Handle underlyingH = new Handle(new SimpleQuote(underlying)); // bootstrap the yield/dividend/vol curves - var flatTermStructure = new Handle( new FlatForward( settlementDate, riskFreeRate, dayCounter ) ); - var flatDividendTS = new Handle( new FlatForward( settlementDate, dividendYield, dayCounter ) ); - var flatVolTS = new Handle( new BlackConstantVol( settlementDate, calendar, volatility, dayCounter ) ); - StrikedTypePayoff payoff = new PlainVanillaPayoff( type, strike ); - var bsmProcess = new BlackScholesMertonProcess( underlyingH, flatDividendTS, flatTermStructure, flatVolTS ); + var flatTermStructure = new Handle(new FlatForward(settlementDate, riskFreeRate, dayCounter)); + var flatDividendTS = new Handle(new FlatForward(settlementDate, dividendYield, dayCounter)); + var flatVolTS = new Handle(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter)); + StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike); + var bsmProcess = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS); // options - VanillaOption europeanOption = new VanillaOption( payoff, europeanExercise ); - PlainVanillaPayoff callpayoff = new PlainVanillaPayoff( type, strike ); + VanillaOption europeanOption = new VanillaOption(payoff, europeanExercise); + PlainVanillaPayoff callpayoff = new PlainVanillaPayoff(type, strike); DiscreteAveragingAsianOption asianoption = new DiscreteAveragingAsianOption( - Average.Type.Arithmetic, - accumulator, - pastfixingcount, - fixings, - callpayoff, - europeanExercise ); + Average.Type.Arithmetic, + accumulator, + pastfixingcount, + fixings, + callpayoff, + europeanExercise); int minSamples = 10000; int maxSamples = 10000; @@ -751,17 +751,17 @@ public void testIssue115() double tolerance = 1.0; var pricingengine = new MCDiscreteArithmeticAPEngine( - bsmProcess, - 252, - false, - false, - false, - minSamples, - tolerance, - maxSamples, - seed ); - - asianoption.setPricingEngine( pricingengine ); + bsmProcess, + 252, + false, + false, + false, + minSamples, + tolerance, + maxSamples, + seed); + + asianoption.setPricingEngine(pricingengine); double price = asianoption.NPV(); } @@ -969,14 +969,14 @@ public void testIssue115() // timeIncrements[i] = i*dt + cases4[l].first; // fixingDates[i] = today + (int)(timeIncrements[i]*360+0.5); // } - // Exercise exercise = new EuropeanExercise(fixingDates[cases4[l].fixings-1]); + // Exercise exercise = new EuropeanExercise(fixingDates[cases4[l].fixings-1]); // spot.setValue(cases4[l].underlying); // qRate.setValue(cases4[l].dividendYield); // rRate.setValue(cases4[l].riskFreeRate); // vol.setValue(cases4[l].volatility); - // BlackScholesMertonProcess stochProcess = + // BlackScholesMertonProcess stochProcess = // new BlackScholesMertonProcess(new Handle(spot), // new Handle(qTS), // new Handle(rTS), @@ -995,7 +995,7 @@ public void testIssue115() // .withSamples(2047) // .withControlVariate() // .value(); - // DiscreteAveragingAsianOption option= + // DiscreteAveragingAsianOption option= // new DiscreteAveragingAsianOption(averageType, runningSum, // pastFixings, fixingDates, // payoff, exercise); @@ -1102,7 +1102,7 @@ public void testIssue115() // int pastFixings = 0; // for (int l=0; l(spot), // new Handle(qTS), // new Handle(rTS), @@ -1133,7 +1133,7 @@ public void testIssue115() // .withSamples(1023) // .value() ; - // DiscreteAveragingAsianOption option = + // DiscreteAveragingAsianOption option = // new DiscreteAveragingAsianOption(averageType, runningSum, // pastFixings, fixingDates, // payoff, exercise); @@ -1172,7 +1172,7 @@ public void testIssue115() // Exercise exercise = new EuropeanExercise(today + new Period(1,TimeUnit.Years)); - // BlackScholesMertonProcess stochProcess = + // BlackScholesMertonProcess stochProcess = // new BlackScholesMertonProcess(new Handle(spot), // new Handle(qTS), // new Handle(rTS), @@ -1185,7 +1185,7 @@ public void testIssue115() // for (int i=0; i<=12; ++i) // fixingDates1.Add(today + new Period(i,TimeUnit.Months)); - // DiscreteAveragingAsianOption option1 = + // DiscreteAveragingAsianOption option1 = // new DiscreteAveragingAsianOption(Average.Type.Arithmetic, runningSum, // pastFixings, fixingDates1, // payoff, exercise); @@ -1196,7 +1196,7 @@ public void testIssue115() // for (int i=-2; i<=12; ++i) // fixingDates2.Add(today + new Period(i,TimeUnit.Months)); - // DiscreteAveragingAsianOption option2 = + // DiscreteAveragingAsianOption option2 = // new DiscreteAveragingAsianOption(Average.Type.Arithmetic, runningSum, // pastFixings, fixingDates2, // payoff, exercise); @@ -1221,7 +1221,7 @@ public void testIssue115() // } // // MC arithmetic average-strike - // engine = new MakeMCDiscreteArithmeticASEngine(stochProcess) + // engine = new MakeMCDiscreteArithmeticASEngine(stochProcess) // .withSamples(2047) // .value(); @@ -1242,7 +1242,7 @@ public void testIssue115() // double runningProduct = 1.0; // pastFixings = 0; - // DiscreteAveragingAsianOption option3 = + // DiscreteAveragingAsianOption option3 = // new DiscreteAveragingAsianOption(Average.Type.Geometric, runningProduct, // pastFixings, fixingDates1, // payoff, exercise); @@ -1250,7 +1250,7 @@ public void testIssue115() // pastFixings = 2; // runningProduct = spot.value() * spot.value(); - // DiscreteAveragingAsianOption option4 = + // DiscreteAveragingAsianOption option4 = // new DiscreteAveragingAsianOption(Average.Type.Geometric, runningProduct, // pastFixings, fixingDates2, // payoff, exercise); @@ -1303,4 +1303,4 @@ public void testIssue115() // } } -} \ No newline at end of file +} diff --git a/tests/QLNet.Tests/T_AssetSwap.cs b/tests/QLNet.Tests/T_AssetSwap.cs index d506fcdf6..d005eed6d 100644 --- a/tests/QLNet.Tests/T_AssetSwap.cs +++ b/tests/QLNet.Tests/T_AssetSwap.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,41 +21,41 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; namespace TestSuite { - #if NET40 || NET45 +#if NET40 || NET45 [TestClass()] - #endif +#endif public class T_AssetSwap : IDisposable { #region Initialize&Cleanup private SavedSettings backup; private IndexHistoryCleaner cleaner; - #if NET40 || NET45 +#if NET40 || NET45 [TestInitialize] public void testInitialize() { - #else +#else public T_AssetSwap() { - #endif +#endif backup = new SavedSettings(); cleaner = new IndexHistoryCleaner(); } - #if NET40 || NET45 +#if NET40 || NET45 [TestCleanup] - #endif +#endif public void testCleanup() { Dispose(); } public void Dispose() { - backup.Dispose(); + backup.Dispose(); cleaner.Dispose(); } #endregion @@ -71,10 +71,10 @@ class CommonVars public double nonnullspread; public double faceAmount; public Compounding compounding; - public RelinkableHandle termStructure = new RelinkableHandle(); + public RelinkableHandle termStructure = new RelinkableHandle(); // initial setup - public CommonVars() + public CommonVars() { termStructure = new RelinkableHandle(); int swapSettlementDays = 2; @@ -85,32 +85,32 @@ public CommonVars() Frequency floatingFrequency = Frequency.Semiannual; iborIndex = new Euribor(new Period(floatingFrequency), termStructure); Calendar calendar = iborIndex.fixingCalendar(); - swapIndex= new SwapIndex("EuriborSwapIsdaFixA", new Period(10,TimeUnit.Years), swapSettlementDays, - iborIndex.currency(), calendar, - new Period(fixedFrequency), fixedConvention, - iborIndex.dayCounter(), iborIndex); + swapIndex = new SwapIndex("EuriborSwapIsdaFixA", new Period(10, TimeUnit.Years), swapSettlementDays, + iborIndex.currency(), calendar, + new Period(fixedFrequency), fixedConvention, + iborIndex.dayCounter(), iborIndex); spread = 0.0; nonnullspread = 0.003; - Date today = new Date(24,Month.April,2007); + Date today = new Date(24, Month.April, 2007); Settings.setEvaluationDate(today); //Date today = Settings::instance().evaluationDate(); termStructure.linkTo(Utilities.flatRate(today, 0.05, new Actual365Fixed())); - + pricer = new BlackIborCouponPricer(); - Handle swaptionVolatilityStructure = - new Handle(new ConstantSwaptionVolatility(today, - new NullCalendar(),BusinessDayConvention.Following, 0.2, new Actual365Fixed())); - + Handle swaptionVolatilityStructure = + new Handle(new ConstantSwaptionVolatility(today, + new NullCalendar(), BusinessDayConvention.Following, 0.2, new Actual365Fixed())); + Handle meanReversionQuote = new Handle(new SimpleQuote(0.01)); cmspricer = new AnalyticHaganPricer(swaptionVolatilityStructure, GFunctionFactory.YieldCurveModel.Standard, meanReversionQuote); - } + } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testConsistency() { @@ -130,10 +130,10 @@ public void testConsistency() BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); Bond bond = new FixedRateBond(settlementDays, vars.faceAmount, - bondSchedule, new List() { 0.04 }, - new ActualActual(ActualActual.Convention.ISDA), - BusinessDayConvention.Following, - 100.0, new Date(4, Month.January, 2005)); + bondSchedule, new List() { 0.04 }, + new ActualActual(ActualActual.Convention.ISDA), + BusinessDayConvention.Following, + 100.0, new Date(4, Month.January, 2005)); bool payFixedRate = true; double bondPrice = 95.0; @@ -159,26 +159,26 @@ public void testConsistency() if (Math.Abs(assetSwap2.NPV()) > tolerance) { QAssert.Fail("npar asset swap fair clean price doesn't zero the NPV: " + - "\n clean price: " + bondPrice + - "\n fair clean price: " + fairCleanPrice + - "\n NPV: " + assetSwap2.NPV() + - "\n tolerance: " + tolerance); + "\n clean price: " + bondPrice + + "\n fair clean price: " + fairCleanPrice + + "\n NPV: " + assetSwap2.NPV() + + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap2.fairCleanPrice() - fairCleanPrice) > tolerance) { QAssert.Fail("\npar asset swap fair clean price doesn't equal input clean price at zero NPV: " + - "\n input clean price: " + fairCleanPrice + - "\n fair clean price: " + assetSwap2.fairCleanPrice() + - "\n NPV: " + assetSwap2.NPV() + - "\n tolerance: " + tolerance); + "\n input clean price: " + fairCleanPrice + + "\n fair clean price: " + assetSwap2.fairCleanPrice() + + "\n NPV: " + assetSwap2.NPV() + + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap2.fairSpread() - vars.spread) > tolerance) { QAssert.Fail("\npar asset swap fair spread doesn't equal input spread at zero NPV: " + - "\n input spread: " + vars.spread + - "\n fair spread: " + assetSwap2.fairSpread() + - "\n NPV: " + assetSwap2.NPV() + - "\n tolerance: " + tolerance); + "\n input spread: " + vars.spread + + "\n fair spread: " + assetSwap2.fairSpread() + + "\n NPV: " + assetSwap2.NPV() + + "\n tolerance: " + tolerance); } AssetSwap assetSwap3 = new AssetSwap(payFixedRate, bond, bondPrice, vars.iborIndex, fairSpread, @@ -188,26 +188,26 @@ public void testConsistency() if (Math.Abs(assetSwap3.NPV()) > tolerance) { QAssert.Fail("\npar asset swap fair spread doesn't zero the NPV: " + - "\n spread: " + vars.spread + - "\n fair spread: " + fairSpread + - "\n NPV: " + assetSwap3.NPV() + - "\n tolerance: " + tolerance); + "\n spread: " + vars.spread + + "\n fair spread: " + fairSpread + + "\n NPV: " + assetSwap3.NPV() + + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap3.fairCleanPrice() - bondPrice) > tolerance) { QAssert.Fail("\npar asset swap fair clean price doesn't equal input clean price at zero NPV: " + - "\n input clean price: " + bondPrice + - "\n fair clean price: " + assetSwap3.fairCleanPrice() + - "\n NPV: " + assetSwap3.NPV() + - "\n tolerance: " + tolerance); + "\n input clean price: " + bondPrice + + "\n fair clean price: " + assetSwap3.fairCleanPrice() + + "\n NPV: " + assetSwap3.NPV() + + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap3.fairSpread() - fairSpread) > tolerance) { QAssert.Fail("\npar asset swap fair spread doesn't equal input spread at zero NPV: " + - "\n input spread: " + fairSpread + - "\n fair spread: " + assetSwap3.fairSpread() + - "\n NPV: " + assetSwap3.NPV() + - "\n tolerance: " + tolerance); + "\n input spread: " + fairSpread + + "\n fair spread: " + assetSwap3.fairSpread() + + "\n NPV: " + assetSwap3.NPV() + + "\n tolerance: " + tolerance); } // let's change the npv date @@ -218,16 +218,16 @@ public void testConsistency() if (Math.Abs(parAssetSwap.fairCleanPrice() - fairCleanPrice) > tolerance) { QAssert.Fail("\npar asset swap fair clean price changed with NpvDate:" + - "\n expected clean price: " + fairCleanPrice + - "\n fair clean price: " + parAssetSwap.fairCleanPrice() + - "\n tolerance: " + tolerance); + "\n expected clean price: " + fairCleanPrice + + "\n fair clean price: " + parAssetSwap.fairCleanPrice() + + "\n tolerance: " + tolerance); } if (Math.Abs(parAssetSwap.fairSpread() - fairSpread) > tolerance) { QAssert.Fail("\npar asset swap fair spread changed with NpvDate:" + - "\n expected spread: " + fairSpread + - "\n fair spread: " + parAssetSwap.fairSpread() + - "\n tolerance: " + tolerance); + "\n expected spread: " + fairSpread + + "\n fair spread: " + parAssetSwap.fairSpread() + + "\n tolerance: " + tolerance); } assetSwap2 = new AssetSwap(payFixedRate, bond, fairCleanPrice, vars.iborIndex, vars.spread, @@ -236,26 +236,26 @@ public void testConsistency() if (Math.Abs(assetSwap2.NPV()) > tolerance) { QAssert.Fail("\npar asset swap fair clean price doesn't zero the NPV: " + - "\n clean price: " + bondPrice + - "\n fair clean price: " + fairCleanPrice + - "\n NPV: " + assetSwap2.NPV() + - "\n tolerance: " + tolerance); + "\n clean price: " + bondPrice + + "\n fair clean price: " + fairCleanPrice + + "\n NPV: " + assetSwap2.NPV() + + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap2.fairCleanPrice() - fairCleanPrice) > tolerance) { QAssert.Fail("\npar asset swap fair clean price doesn't equal input clean price at zero NPV: " + - "\n input clean price: " + fairCleanPrice + - "\n fair clean price: " + assetSwap2.fairCleanPrice() + - "\n NPV: " + assetSwap2.NPV() + - "\n tolerance: " + tolerance); + "\n input clean price: " + fairCleanPrice + + "\n fair clean price: " + assetSwap2.fairCleanPrice() + + "\n NPV: " + assetSwap2.NPV() + + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap2.fairSpread() - vars.spread) > tolerance) { QAssert.Fail("\npar asset swap fair spread doesn't equal input spread at zero NPV: " + - "\n input spread: " + vars.spread + - "\n fair spread: " + assetSwap2.fairSpread() + - "\n NPV: " + assetSwap2.NPV() + - "\n tolerance: " + tolerance); + "\n input spread: " + vars.spread + + "\n fair spread: " + assetSwap2.fairSpread() + + "\n NPV: " + assetSwap2.NPV() + + "\n tolerance: " + tolerance); } assetSwap3 = new AssetSwap(payFixedRate, bond, bondPrice, vars.iborIndex, fairSpread, @@ -264,26 +264,26 @@ public void testConsistency() if (Math.Abs(assetSwap3.NPV()) > tolerance) { QAssert.Fail("\npar asset swap fair spread doesn't zero the NPV: " + - "\n spread: " + vars.spread + - "\n fair spread: " + fairSpread + - "\n NPV: " + assetSwap3.NPV() + - "\n tolerance: " + tolerance); + "\n spread: " + vars.spread + + "\n fair spread: " + fairSpread + + "\n NPV: " + assetSwap3.NPV() + + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap3.fairCleanPrice() - bondPrice) > tolerance) { QAssert.Fail("\npar asset swap fair clean price doesn't equal input clean price at zero NPV: " + - "\n input clean price: " + bondPrice + - "\n fair clean price: " + assetSwap3.fairCleanPrice() + - "\n NPV: " + assetSwap3.NPV() + - "\n tolerance: " + tolerance); + "\n input clean price: " + bondPrice + + "\n fair clean price: " + assetSwap3.fairCleanPrice() + + "\n NPV: " + assetSwap3.NPV() + + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap3.fairSpread() - fairSpread) > tolerance) { QAssert.Fail("\npar asset swap fair spread doesn't equal input spread at zero NPV: " + - "\n input spread: " + fairSpread + - "\n fair spread: " + assetSwap3.fairSpread() + - "\n NPV: " + assetSwap3.NPV() + - "\n tolerance: " + tolerance); + "\n input spread: " + fairSpread + + "\n fair spread: " + assetSwap3.fairSpread() + + "\n NPV: " + assetSwap3.NPV() + + "\n tolerance: " + tolerance); } @@ -305,26 +305,26 @@ public void testConsistency() if (Math.Abs(assetSwap4.NPV()) > tolerance) { QAssert.Fail("\nmarket asset swap fair clean price doesn't zero the NPV: " + - "\n clean price: " + bondPrice + - "\n fair clean price: " + fairCleanPrice + - "\n NPV: " + assetSwap4.NPV() + - "\n tolerance: " + tolerance); + "\n clean price: " + bondPrice + + "\n fair clean price: " + fairCleanPrice + + "\n NPV: " + assetSwap4.NPV() + + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap4.fairCleanPrice() - fairCleanPrice) > tolerance) { QAssert.Fail("\nmarket asset swap fair clean price doesn't equal input clean price at zero NPV: " + - "\n input clean price: " + fairCleanPrice + - "\n fair clean price: " + assetSwap4.fairCleanPrice() + - "\n NPV: " + assetSwap4.NPV() + - "\n tolerance: " + tolerance); + "\n input clean price: " + fairCleanPrice + + "\n fair clean price: " + assetSwap4.fairCleanPrice() + + "\n NPV: " + assetSwap4.NPV() + + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap4.fairSpread() - vars.spread) > tolerance) { QAssert.Fail("\nmarket asset swap fair spread doesn't equal input spread at zero NPV: " + - "\n input spread: " + vars.spread + - "\n fair spread: " + assetSwap4.fairSpread() + - "\n NPV: " + assetSwap4.NPV() + - "\n tolerance: " + tolerance); + "\n input spread: " + vars.spread + + "\n fair spread: " + assetSwap4.fairSpread() + + "\n NPV: " + assetSwap4.NPV() + + "\n tolerance: " + tolerance); } AssetSwap assetSwap5 = new AssetSwap(payFixedRate, bond, bondPrice, vars.iborIndex, fairSpread, @@ -333,26 +333,26 @@ public void testConsistency() if (Math.Abs(assetSwap5.NPV()) > tolerance) { QAssert.Fail("\nmarket asset swap fair spread doesn't zero the NPV: " + - "\n spread: " + vars.spread + - "\n fair spread: " + fairSpread + - "\n NPV: " + assetSwap5.NPV() + - "\n tolerance: " + tolerance); + "\n spread: " + vars.spread + + "\n fair spread: " + fairSpread + + "\n NPV: " + assetSwap5.NPV() + + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap5.fairCleanPrice() - bondPrice) > tolerance) { QAssert.Fail("\nmarket asset swap fair clean price doesn't equal input clean price at zero NPV: " + - "\n input clean price: " + bondPrice + - "\n fair clean price: " + assetSwap5.fairCleanPrice() + - "\n NPV: " + assetSwap5.NPV() + - "\n tolerance: " + tolerance); + "\n input clean price: " + bondPrice + + "\n fair clean price: " + assetSwap5.fairCleanPrice() + + "\n NPV: " + assetSwap5.NPV() + + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap5.fairSpread() - fairSpread) > tolerance) { QAssert.Fail("\nmarket asset swap fair spread doesn't equal input spread at zero NPV: " + - "\n input spread: " + fairSpread + - "\n fair spread: " + assetSwap5.fairSpread() + - "\n NPV: " + assetSwap5.NPV() + - "\n tolerance: " + tolerance); + "\n input spread: " + fairSpread + + "\n fair spread: " + assetSwap5.fairSpread() + + "\n NPV: " + assetSwap5.NPV() + + "\n tolerance: " + tolerance); } // let's change the npv date @@ -363,16 +363,16 @@ public void testConsistency() if (Math.Abs(mktAssetSwap.fairCleanPrice() - fairCleanPrice) > tolerance) { QAssert.Fail("\nmarket asset swap fair clean price changed with NpvDate:" + - "\n expected clean price: " + fairCleanPrice + - "\n fair clean price: " + mktAssetSwap.fairCleanPrice() + - "\n tolerance: " + tolerance); + "\n expected clean price: " + fairCleanPrice + + "\n fair clean price: " + mktAssetSwap.fairCleanPrice() + + "\n tolerance: " + tolerance); } if (Math.Abs(mktAssetSwap.fairSpread() - fairSpread) > tolerance) { QAssert.Fail("\nmarket asset swap fair spread changed with NpvDate:" + - "\n expected spread: " + fairSpread + - "\n fair spread: " + mktAssetSwap.fairSpread() + - "\n tolerance: " + tolerance); + "\n expected spread: " + fairSpread + + "\n fair spread: " + mktAssetSwap.fairSpread() + + "\n tolerance: " + tolerance); } assetSwap4 = new AssetSwap(payFixedRate, bond, fairCleanPrice, vars.iborIndex, vars.spread, @@ -381,26 +381,26 @@ public void testConsistency() if (Math.Abs(assetSwap4.NPV()) > tolerance) { QAssert.Fail("\nmarket asset swap fair clean price doesn't zero the NPV: " + - "\n clean price: " + bondPrice + - "\n fair clean price: " + fairCleanPrice + - "\n NPV: " + assetSwap4.NPV() + - "\n tolerance: " + tolerance); + "\n clean price: " + bondPrice + + "\n fair clean price: " + fairCleanPrice + + "\n NPV: " + assetSwap4.NPV() + + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap4.fairCleanPrice() - fairCleanPrice) > tolerance) { QAssert.Fail("\nmarket asset swap fair clean price doesn't equal input clean price at zero NPV: " + - "\n input clean price: " + fairCleanPrice + - "\n fair clean price: " + assetSwap4.fairCleanPrice() + - "\n NPV: " + assetSwap4.NPV() + - "\n tolerance: " + tolerance); + "\n input clean price: " + fairCleanPrice + + "\n fair clean price: " + assetSwap4.fairCleanPrice() + + "\n NPV: " + assetSwap4.NPV() + + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap4.fairSpread() - vars.spread) > tolerance) { QAssert.Fail("\nmarket asset swap fair spread doesn't equal input spread at zero NPV: " + - "\n input spread: " + vars.spread + - "\n fair spread: " + assetSwap4.fairSpread() + - "\n NPV: " + assetSwap4.NPV() + - "\n tolerance: " + tolerance); + "\n input spread: " + vars.spread + + "\n fair spread: " + assetSwap4.fairSpread() + + "\n NPV: " + assetSwap4.NPV() + + "\n tolerance: " + tolerance); } assetSwap5 = new AssetSwap(payFixedRate, bond, bondPrice, vars.iborIndex, fairSpread, @@ -409,35 +409,35 @@ public void testConsistency() if (Math.Abs(assetSwap5.NPV()) > tolerance) { QAssert.Fail("\nmarket asset swap fair spread doesn't zero the NPV: " + - "\n spread: " + vars.spread + - "\n fair spread: " + fairSpread + - "\n NPV: " + assetSwap5.NPV() + - "\n tolerance: " + tolerance); + "\n spread: " + vars.spread + + "\n fair spread: " + fairSpread + + "\n NPV: " + assetSwap5.NPV() + + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap5.fairCleanPrice() - bondPrice) > tolerance) { QAssert.Fail("\nmarket asset swap fair clean price doesn't equal input clean price at zero NPV: " + - "\n input clean price: " + bondPrice + - "\n fair clean price: " + assetSwap5.fairCleanPrice() + - "\n NPV: " + assetSwap5.NPV() + - "\n tolerance: " + tolerance); + "\n input clean price: " + bondPrice + + "\n fair clean price: " + assetSwap5.fairCleanPrice() + + "\n NPV: " + assetSwap5.NPV() + + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap5.fairSpread() - fairSpread) > tolerance) { QAssert.Fail("\nmarket asset swap fair spread doesn't equal input spread at zero NPV: " + - "\n input spread: " + fairSpread + - "\n fair spread: " + assetSwap5.fairSpread() + - "\n NPV: " + assetSwap5.NPV() + - "\n tolerance: " + tolerance); + "\n input spread: " + fairSpread + + "\n fair spread: " + assetSwap5.fairSpread() + + "\n NPV: " + assetSwap5.NPV() + + "\n tolerance: " + tolerance); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testImpliedValue() + public void testImpliedValue() { // Testing implied bond value against asset-swap fair price with null spread CommonVars vars = new CommonVars(); @@ -452,17 +452,17 @@ public void testImpliedValue() // Fixed Underlying bond (Isin: DE0001135275 DBR 4 01/04/37) // maturity doesn't occur on a business day - Schedule fixedBondSchedule1 = new Schedule( new Date(4,Month.January,2005), - new Date(4,Month.January,2037), - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Schedule fixedBondSchedule1 = new Schedule(new Date(4, Month.January, 2005), + new Date(4, Month.January, 2037), + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); Bond fixedBond1 = new FixedRateBond(settlementDays, vars.faceAmount, - fixedBondSchedule1, - new List(){0.04}, - new ActualActual(ActualActual.Convention.ISDA), - BusinessDayConvention.Following, - 100.0, new Date(4,Month.January,2005)); + fixedBondSchedule1, + new List() {0.04}, + new ActualActual(ActualActual.Convention.ISDA), + BusinessDayConvention.Following, + 100.0, new Date(4, Month.January, 2005)); IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure); IPricingEngine swapEngine = new DiscountingSwapEngine(vars.termStructure); @@ -474,30 +474,31 @@ public void testImpliedValue() fixedBondAssetSwap1.setPricingEngine(swapEngine); double fixedBondAssetSwapPrice1 = fixedBondAssetSwap1.fairCleanPrice(); double tolerance = 1.0e-13; - double error1 = Math.Abs(fixedBondAssetSwapPrice1-fixedBondPrice1); + double error1 = Math.Abs(fixedBondAssetSwapPrice1 - fixedBondPrice1); - if (error1>tolerance) { + if (error1 > tolerance) + { QAssert.Fail("wrong zero spread asset swap price for fixed bond:" + - "\n bond's clean price: " + fixedBondPrice1 + - "\n asset swap fair price: " + fixedBondAssetSwapPrice1 + - "\n error: " + error1 + - "\n tolerance: " + tolerance); + "\n bond's clean price: " + fixedBondPrice1 + + "\n asset swap fair price: " + fixedBondAssetSwapPrice1 + + "\n error: " + error1 + + "\n tolerance: " + tolerance); } // Fixed Underlying bond (Isin: IT0006527060 IBRD 5 02/05/19) // maturity occurs on a business day - Schedule fixedBondSchedule2 = new Schedule( new Date(5,Month.February,2005), - new Date(5,Month.February,2019), - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Schedule fixedBondSchedule2 = new Schedule(new Date(5, Month.February, 2005), + new Date(5, Month.February, 2019), + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); Bond fixedBond2 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule2, - new List(){0.05}, - new Thirty360(Thirty360.Thirty360Convention.BondBasis), - BusinessDayConvention.Following, - 100.0, new Date(5,Month.February,2005)); + new List() {0.05}, + new Thirty360(Thirty360.Thirty360Convention.BondBasis), + BusinessDayConvention.Following, + 100.0, new Date(5, Month.February, 2005)); fixedBond2.setPricingEngine(bondEngine); @@ -506,237 +507,245 @@ public void testImpliedValue() null, vars.iborIndex.dayCounter(), parAssetSwap); fixedBondAssetSwap2.setPricingEngine(swapEngine); double fixedBondAssetSwapPrice2 = fixedBondAssetSwap2.fairCleanPrice(); - double error2 = Math.Abs(fixedBondAssetSwapPrice2-fixedBondPrice2); + double error2 = Math.Abs(fixedBondAssetSwapPrice2 - fixedBondPrice2); - if (error2>tolerance) { + if (error2 > tolerance) + { QAssert.Fail("wrong zero spread asset swap price for fixed bond:" + - "\n bond's clean price: " + fixedBondPrice2 + - "\n asset swap fair price: " + fixedBondAssetSwapPrice2 + - "\n error: " + error2 + - "\n tolerance: " + tolerance); + "\n bond's clean price: " + fixedBondPrice2 + + "\n asset swap fair price: " + fixedBondAssetSwapPrice2 + + "\n error: " + error2 + + "\n tolerance: " + tolerance); } // FRN Underlying bond (Isin: IT0003543847 ISPIM 0 09/29/13) // maturity doesn't occur on a business day - Schedule floatingBondSchedule1 = new Schedule( new Date(29,Month.September,2003), - new Date(29,Month.September,2013), - new Period(Frequency.Semiannual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Schedule floatingBondSchedule1 = new Schedule(new Date(29, Month.September, 2003), + new Date(29, Month.September, 2013), + new Period(Frequency.Semiannual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); Bond floatingBond1 = new FloatingRateBond(settlementDays, vars.faceAmount, floatingBondSchedule1, vars.iborIndex, new Actual360(), BusinessDayConvention.Following, fixingDays, - new List(){1}, - new List(){0.0056}, - new List(), - new List(), - inArrears, - 100.0, new Date(29,Month.September,2003)); + new List() {1}, + new List() {0.0056}, + new List < double? >(), + new List < double? >(), + inArrears, + 100.0, new Date(29, Month.September, 2003)); floatingBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer); - vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402); + vars.iborIndex.addFixing(new Date(27, Month.March, 2007), 0.0402); double floatingBondPrice1 = floatingBond1.cleanPrice(); AssetSwap floatingBondAssetSwap1 = new AssetSwap(payFixedRate, floatingBond1, floatingBondPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); floatingBondAssetSwap1.setPricingEngine(swapEngine); double floatingBondAssetSwapPrice1 = floatingBondAssetSwap1.fairCleanPrice(); - double error3 = Math.Abs(floatingBondAssetSwapPrice1-floatingBondPrice1); + double error3 = Math.Abs(floatingBondAssetSwapPrice1 - floatingBondPrice1); - if (error3>tolerance) { + if (error3 > tolerance) + { QAssert.Fail("wrong zero spread asset swap price for floater:" + - "\n bond's clean price: " + floatingBondPrice1 + - "\n asset swap fair price: " + floatingBondAssetSwapPrice1 + - "\n error: " + error3 + - "\n tolerance: " + tolerance); + "\n bond's clean price: " + floatingBondPrice1 + + "\n asset swap fair price: " + floatingBondAssetSwapPrice1 + + "\n error: " + error3 + + "\n tolerance: " + tolerance); } // FRN Underlying bond (Isin: XS0090566539 COE 0 09/24/18) // maturity occurs on a business day - Schedule floatingBondSchedule2 = new Schedule( new Date(24,Month.September,2004), - new Date(24,Month.September,2018), - new Period(Frequency.Semiannual), bondCalendar, - BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, - DateGeneration.Rule.Backward, false); - Bond floatingBond2 = new FloatingRateBond( settlementDays, vars.faceAmount, - floatingBondSchedule2, - vars.iborIndex, new Actual360(), - BusinessDayConvention.ModifiedFollowing, fixingDays, - new List(){1}, - new List(){0.0025}, - new List(), - new List(), - inArrears, - 100.0, new Date(24,Month.September,2004)); + Schedule floatingBondSchedule2 = new Schedule(new Date(24, Month.September, 2004), + new Date(24, Month.September, 2018), + new Period(Frequency.Semiannual), bondCalendar, + BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, + DateGeneration.Rule.Backward, false); + Bond floatingBond2 = new FloatingRateBond(settlementDays, vars.faceAmount, + floatingBondSchedule2, + vars.iborIndex, new Actual360(), + BusinessDayConvention.ModifiedFollowing, fixingDays, + new List() {1}, + new List() {0.0025}, + new List < double? >(), + new List < double? >(), + inArrears, + 100.0, new Date(24, Month.September, 2004)); floatingBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer); - vars.iborIndex.addFixing( new Date(22,Month.March,2007), 0.04013); - double currentCoupon=0.04013+0.0025; - double floatingCurrentCoupon= floatingBond2.nextCouponRate(); - double error4= Math.Abs(floatingCurrentCoupon-currentCoupon); - if (error4>tolerance) { + vars.iborIndex.addFixing(new Date(22, Month.March, 2007), 0.04013); + double currentCoupon = 0.04013 + 0.0025; + double floatingCurrentCoupon = floatingBond2.nextCouponRate(); + double error4 = Math.Abs(floatingCurrentCoupon - currentCoupon); + if (error4 > tolerance) + { QAssert.Fail("wrong current coupon is returned for floater bond:" + - "\n bond's calculated current coupon: " + - currentCoupon + - "\n current coupon asked to the bond: " + - floatingCurrentCoupon + - "\n error: " + error4 + - "\n tolerance: " + tolerance); + "\n bond's calculated current coupon: " + + currentCoupon + + "\n current coupon asked to the bond: " + + floatingCurrentCoupon + + "\n error: " + error4 + + "\n tolerance: " + tolerance); } double floatingBondPrice2 = floatingBond2.cleanPrice(); - AssetSwap floatingBondAssetSwap2 = new AssetSwap(payFixedRate,floatingBond2, floatingBondPrice2, vars.iborIndex, vars.spread, + AssetSwap floatingBondAssetSwap2 = new AssetSwap(payFixedRate, floatingBond2, floatingBondPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); floatingBondAssetSwap2.setPricingEngine(swapEngine); double floatingBondAssetSwapPrice2 = floatingBondAssetSwap2.fairCleanPrice(); - double error5 = Math.Abs(floatingBondAssetSwapPrice2-floatingBondPrice2); + double error5 = Math.Abs(floatingBondAssetSwapPrice2 - floatingBondPrice2); - if (error5>tolerance) { + if (error5 > tolerance) + { QAssert.Fail("wrong zero spread asset swap price for floater:" + - "\n bond's clean price: " + floatingBondPrice2 + - "\n asset swap fair price: " + floatingBondAssetSwapPrice2 + - "\n error: " + error5 + - "\n tolerance: " + tolerance); + "\n bond's clean price: " + floatingBondPrice2 + + "\n asset swap fair price: " + floatingBondAssetSwapPrice2 + + "\n error: " + error5 + + "\n tolerance: " + tolerance); } // CMS Underlying bond (Isin: XS0228052402 CRDIT 0 8/22/20) // maturity doesn't occur on a business day - Schedule cmsBondSchedule1 = new Schedule( new Date(22,Month.August,2005), - new Date(22,Month.August,2020), - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Schedule cmsBondSchedule1 = new Schedule(new Date(22, Month.August, 2005), + new Date(22, Month.August, 2020), + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); Bond cmsBond1 = new CmsRateBond(settlementDays, vars.faceAmount, - cmsBondSchedule1, - vars.swapIndex, new Thirty360(), - BusinessDayConvention.Following, fixingDays, - new List(){1.0}, - new List(){0.0}, - new List(){0.055}, - new List(){0.025}, - inArrears, - 100.0, new Date(22,Month.August,2005)); + cmsBondSchedule1, + vars.swapIndex, new Thirty360(), + BusinessDayConvention.Following, fixingDays, + new List() {1.0}, + new List() {0.0}, + new List < double? >() {0.055}, + new List < double? >() {0.025}, + inArrears, + 100.0, new Date(22, Month.August, 2005)); cmsBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer); - vars.swapIndex.addFixing( new Date(18,Month.August,2006), 0.04158); + vars.swapIndex.addFixing(new Date(18, Month.August, 2006), 0.04158); double cmsBondPrice1 = cmsBond1.cleanPrice(); AssetSwap cmsBondAssetSwap1 = new AssetSwap(payFixedRate, cmsBond1, cmsBondPrice1, vars.iborIndex, vars.spread, - null,vars.iborIndex.dayCounter(), parAssetSwap); + null, vars.iborIndex.dayCounter(), parAssetSwap); cmsBondAssetSwap1.setPricingEngine(swapEngine); double cmsBondAssetSwapPrice1 = cmsBondAssetSwap1.fairCleanPrice(); - double error6 = Math.Abs(cmsBondAssetSwapPrice1-cmsBondPrice1); + double error6 = Math.Abs(cmsBondAssetSwapPrice1 - cmsBondPrice1); - if (error6>tolerance) { + if (error6 > tolerance) + { QAssert.Fail("wrong zero spread asset swap price for cms bond:" + - "\n bond's clean price: " + cmsBondPrice1 + - "\n asset swap fair price: " + cmsBondAssetSwapPrice1 + - "\n error: " + error6 + - "\n tolerance: " + tolerance); + "\n bond's clean price: " + cmsBondPrice1 + + "\n asset swap fair price: " + cmsBondAssetSwapPrice1 + + "\n error: " + error6 + + "\n tolerance: " + tolerance); } // CMS Underlying bond (Isin: XS0218766664 ISPIM 0 5/6/15) // maturity occurs on a business day - Schedule cmsBondSchedule2 = new Schedule( new Date(06,Month.May,2005), - new Date(06,Month.May,2015), - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); - Bond cmsBond2 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule2, - vars.swapIndex, new Thirty360(), - BusinessDayConvention.Following, fixingDays, - new List(){0.84}, new List(){0.0}, - new List(), new List(), - inArrears, - 100.0, new Date(06,Month.May,2005)); + Schedule cmsBondSchedule2 = new Schedule(new Date(06, Month.May, 2005), + new Date(06, Month.May, 2015), + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); + Bond cmsBond2 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule2, + vars.swapIndex, new Thirty360(), + BusinessDayConvention.Following, fixingDays, + new List() {0.84}, new List() {0.0}, + new List < double? >(), new List < double? >(), + inArrears, + 100.0, new Date(06, Month.May, 2005)); cmsBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer); - vars.swapIndex.addFixing( new Date(04,Month.May,2006), 0.04217); + vars.swapIndex.addFixing(new Date(04, Month.May, 2006), 0.04217); double cmsBondPrice2 = cmsBond2.cleanPrice(); - AssetSwap cmsBondAssetSwap2 = new AssetSwap(payFixedRate,cmsBond2, cmsBondPrice2, vars.iborIndex, vars.spread, + AssetSwap cmsBondAssetSwap2 = new AssetSwap(payFixedRate, cmsBond2, cmsBondPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); cmsBondAssetSwap2.setPricingEngine(swapEngine); double cmsBondAssetSwapPrice2 = cmsBondAssetSwap2.fairCleanPrice(); - double error7 = Math.Abs(cmsBondAssetSwapPrice2-cmsBondPrice2); + double error7 = Math.Abs(cmsBondAssetSwapPrice2 - cmsBondPrice2); - if (error7>tolerance) { + if (error7 > tolerance) + { QAssert.Fail("wrong zero spread asset swap price for cms bond:" + - "\n bond's clean price: " + cmsBondPrice2 + - "\n asset swap fair price: " + cmsBondAssetSwapPrice2 + - "\n error: " + error7 + - "\n tolerance: " + tolerance); + "\n bond's clean price: " + cmsBondPrice2 + + "\n asset swap fair price: " + cmsBondAssetSwapPrice2 + + "\n error: " + error7 + + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15) // maturity doesn't occur on a business day Bond zeroCpnBond1 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount, - new Date(20,Month.December,2015), + new Date(20, Month.December, 2015), BusinessDayConvention.Following, - 100.0, new Date(19,Month.December,1985)); + 100.0, new Date(19, Month.December, 1985)); zeroCpnBond1.setPricingEngine(bondEngine); double zeroCpnBondPrice1 = zeroCpnBond1.cleanPrice(); - AssetSwap zeroCpnAssetSwap1 = new AssetSwap(payFixedRate,zeroCpnBond1, zeroCpnBondPrice1, vars.iborIndex, vars.spread, + AssetSwap zeroCpnAssetSwap1 = new AssetSwap(payFixedRate, zeroCpnBond1, zeroCpnBondPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); zeroCpnAssetSwap1.setPricingEngine(swapEngine); double zeroCpnBondAssetSwapPrice1 = zeroCpnAssetSwap1.fairCleanPrice(); - double error8 = Math.Abs(cmsBondAssetSwapPrice1-cmsBondPrice1); + double error8 = Math.Abs(cmsBondAssetSwapPrice1 - cmsBondPrice1); - if (error8>tolerance) { + if (error8 > tolerance) + { QAssert.Fail("wrong zero spread asset swap price for zero cpn bond:" + - "\n bond's clean price: " + zeroCpnBondPrice1 + - "\n asset swap fair price: " + zeroCpnBondAssetSwapPrice1 + - "\n error: " + error8 + - "\n tolerance: " + tolerance); + "\n bond's clean price: " + zeroCpnBondPrice1 + + "\n asset swap fair price: " + zeroCpnBondAssetSwapPrice1 + + "\n error: " + error8 + + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28) // maturity occurs on a business day Bond zeroCpnBond2 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount, - new Date(17,Month.February,2028), - BusinessDayConvention.Following, - 100.0, new Date(17,Month.February,1998)); + new Date(17, Month.February, 2028), + BusinessDayConvention.Following, + 100.0, new Date(17, Month.February, 1998)); zeroCpnBond2.setPricingEngine(bondEngine); double zeroCpnBondPrice2 = zeroCpnBond2.cleanPrice(); AssetSwap zeroCpnAssetSwap2 = new AssetSwap(payFixedRate, zeroCpnBond2, zeroCpnBondPrice2, vars.iborIndex, vars.spread, - null,vars.iborIndex.dayCounter(), parAssetSwap); + null, vars.iborIndex.dayCounter(), parAssetSwap); zeroCpnAssetSwap2.setPricingEngine(swapEngine); double zeroCpnBondAssetSwapPrice2 = zeroCpnAssetSwap2.fairCleanPrice(); - double error9 = Math.Abs(cmsBondAssetSwapPrice2-cmsBondPrice2); + double error9 = Math.Abs(cmsBondAssetSwapPrice2 - cmsBondPrice2); - if (error9>tolerance) { + if (error9 > tolerance) + { QAssert.Fail("wrong zero spread asset swap price for zero cpn bond:" + - "\n bond's clean price: " + zeroCpnBondPrice2 + - "\n asset swap fair price: " + zeroCpnBondAssetSwapPrice2 + - "\n error: " + error9 + - "\n tolerance: " + tolerance); + "\n bond's clean price: " + zeroCpnBondPrice2 + + "\n asset swap fair price: " + zeroCpnBondAssetSwapPrice2 + + "\n error: " + error9 + + "\n tolerance: " + tolerance); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testMarketASWSpread() + public void testMarketASWSpread() { // Testing relationship between market asset swap and par asset swap... CommonVars vars = new CommonVars(); @@ -752,341 +761,348 @@ public void testMarketASWSpread() // Fixed Underlying bond (Isin: DE0001135275 DBR 4 01/04/37) // maturity doesn't occur on a business day - Schedule fixedBondSchedule1 = new Schedule(new Date(4,Month.January,2005), - new Date(4,Month.January,2037), - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Schedule fixedBondSchedule1 = new Schedule(new Date(4, Month.January, 2005), + new Date(4, Month.January, 2037), + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); Bond fixedBond1 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule1, - new List{0.04}, - new ActualActual(ActualActual.Convention.ISDA),BusinessDayConvention.Following, - 100.0, new Date(4,Month.January,2005)); + new List {0.04}, + new ActualActual(ActualActual.Convention.ISDA), BusinessDayConvention.Following, + 100.0, new Date(4, Month.January, 2005)); IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure); IPricingEngine swapEngine = new DiscountingSwapEngine(vars.termStructure); fixedBond1.setPricingEngine(bondEngine); double fixedBondMktPrice1 = 89.22 ; // market price observed on 7th June 2007 - double fixedBondMktFullPrice1=fixedBondMktPrice1+fixedBond1.accruedAmount(); + double fixedBondMktFullPrice1 = fixedBondMktPrice1 + fixedBond1.accruedAmount(); AssetSwap fixedBondParAssetSwap1 = new AssetSwap(payFixedRate, - fixedBond1, fixedBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + fixedBond1, fixedBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); fixedBondParAssetSwap1.setPricingEngine(swapEngine); double fixedBondParAssetSwapSpread1 = fixedBondParAssetSwap1.fairSpread(); AssetSwap fixedBondMktAssetSwap1 = new AssetSwap(payFixedRate, - fixedBond1, fixedBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - mktAssetSwap); + fixedBond1, fixedBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + mktAssetSwap); fixedBondMktAssetSwap1.setPricingEngine(swapEngine); double fixedBondMktAssetSwapSpread1 = fixedBondMktAssetSwap1.fairSpread(); double tolerance = 1.0e-13; - double error1 = Math.Abs(fixedBondMktAssetSwapSpread1- 100*fixedBondParAssetSwapSpread1/fixedBondMktFullPrice1); + double error1 = Math.Abs(fixedBondMktAssetSwapSpread1 - 100 * fixedBondParAssetSwapSpread1 / fixedBondMktFullPrice1); - if (error1>tolerance) { + if (error1 > tolerance) + { QAssert.Fail("wrong asset swap spreads for fixed bond:" + - "\n market ASW spread: " + fixedBondMktAssetSwapSpread1 + - "\n par ASW spread: " + fixedBondParAssetSwapSpread1 + - "\n error: " + error1 + - "\n tolerance: " + tolerance); + "\n market ASW spread: " + fixedBondMktAssetSwapSpread1 + + "\n par ASW spread: " + fixedBondParAssetSwapSpread1 + + "\n error: " + error1 + + "\n tolerance: " + tolerance); } // Fixed Underlying bond (Isin: IT0006527060 IBRD 5 02/05/19) // maturity occurs on a business day - Schedule fixedBondSchedule2 = new Schedule(new Date(5,Month.February,2005), - new Date(5,Month.February,2019), - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Schedule fixedBondSchedule2 = new Schedule(new Date(5, Month.February, 2005), + new Date(5, Month.February, 2019), + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); Bond fixedBond2 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule2, - new List{ 0.05}, - new Thirty360(Thirty360.Thirty360Convention.BondBasis), BusinessDayConvention.Following, - 100.0, new Date(5,Month.February,2005)); + new List { 0.05}, + new Thirty360(Thirty360.Thirty360Convention.BondBasis), BusinessDayConvention.Following, + 100.0, new Date(5, Month.February, 2005)); fixedBond2.setPricingEngine(bondEngine); double fixedBondMktPrice2 = 99.98 ; // market price observed on 7th June 2007 - double fixedBondMktFullPrice2=fixedBondMktPrice2+fixedBond2.accruedAmount(); + double fixedBondMktFullPrice2 = fixedBondMktPrice2 + fixedBond2.accruedAmount(); AssetSwap fixedBondParAssetSwap2 = new AssetSwap(payFixedRate, - fixedBond2, fixedBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + fixedBond2, fixedBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); fixedBondParAssetSwap2.setPricingEngine(swapEngine); double fixedBondParAssetSwapSpread2 = fixedBondParAssetSwap2.fairSpread(); AssetSwap fixedBondMktAssetSwap2 = new AssetSwap(payFixedRate, - fixedBond2, fixedBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - mktAssetSwap); + fixedBond2, fixedBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + mktAssetSwap); fixedBondMktAssetSwap2.setPricingEngine(swapEngine); double fixedBondMktAssetSwapSpread2 = fixedBondMktAssetSwap2.fairSpread(); - double error2 = Math.Abs(fixedBondMktAssetSwapSpread2- - 100*fixedBondParAssetSwapSpread2/fixedBondMktFullPrice2); + double error2 = Math.Abs(fixedBondMktAssetSwapSpread2 - + 100 * fixedBondParAssetSwapSpread2 / fixedBondMktFullPrice2); - if (error2>tolerance) { + if (error2 > tolerance) + { QAssert.Fail("wrong asset swap spreads for fixed bond:" + - "\n market ASW spread: " + fixedBondMktAssetSwapSpread2 + - "\n par ASW spread: " + fixedBondParAssetSwapSpread2 + - "\n error: " + error2 + - "\n tolerance: " + tolerance); + "\n market ASW spread: " + fixedBondMktAssetSwapSpread2 + + "\n par ASW spread: " + fixedBondParAssetSwapSpread2 + + "\n error: " + error2 + + "\n tolerance: " + tolerance); } // FRN Underlying bond (Isin: IT0003543847 ISPIM 0 09/29/13) // maturity doesn't occur on a business day - Schedule floatingBondSchedule1 = new Schedule( new Date(29,Month.September,2003), - new Date(29,Month.September,2013), - new Period(Frequency.Semiannual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Schedule floatingBondSchedule1 = new Schedule(new Date(29, Month.September, 2003), + new Date(29, Month.September, 2013), + new Period(Frequency.Semiannual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); Bond floatingBond1 = new FloatingRateBond(settlementDays, vars.faceAmount, - floatingBondSchedule1, - vars.iborIndex, new Actual360(), - BusinessDayConvention.Following, fixingDays, - new List{1}, new List{0.0056}, - new List(), new List(), - inArrears, - 100.0, new Date(29,Month.September,2003)); + floatingBondSchedule1, + vars.iborIndex, new Actual360(), + BusinessDayConvention.Following, fixingDays, + new List {1}, new List {0.0056}, + new List < double? >(), new List < double? >(), + inArrears, + 100.0, new Date(29, Month.September, 2003)); floatingBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer); - vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402); + vars.iborIndex.addFixing(new Date(27, Month.March, 2007), 0.0402); // market price observed on 7th June 2007 double floatingBondMktPrice1 = 101.64 ; - double floatingBondMktFullPrice1 = floatingBondMktPrice1+floatingBond1.accruedAmount(); + double floatingBondMktFullPrice1 = floatingBondMktPrice1 + floatingBond1.accruedAmount(); AssetSwap floatingBondParAssetSwap1 = new AssetSwap(payFixedRate, - floatingBond1, floatingBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + floatingBond1, floatingBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); floatingBondParAssetSwap1.setPricingEngine(swapEngine); double floatingBondParAssetSwapSpread1 = floatingBondParAssetSwap1.fairSpread(); - AssetSwap floatingBondMktAssetSwap1= new AssetSwap(payFixedRate, - floatingBond1, floatingBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - mktAssetSwap); + AssetSwap floatingBondMktAssetSwap1 = new AssetSwap(payFixedRate, + floatingBond1, floatingBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + mktAssetSwap); floatingBondMktAssetSwap1.setPricingEngine(swapEngine); double floatingBondMktAssetSwapSpread1 = floatingBondMktAssetSwap1.fairSpread(); - double error3 = Math.Abs(floatingBondMktAssetSwapSpread1- - 100*floatingBondParAssetSwapSpread1/floatingBondMktFullPrice1); + double error3 = Math.Abs(floatingBondMktAssetSwapSpread1 - + 100 * floatingBondParAssetSwapSpread1 / floatingBondMktFullPrice1); - if (error3>tolerance) { + if (error3 > tolerance) + { QAssert.Fail("wrong asset swap spreads for floating bond:" + - "\n market ASW spread: " + floatingBondMktAssetSwapSpread1 + - "\n par ASW spread: " + floatingBondParAssetSwapSpread1 + - "\n error: " + error3 + - "\n tolerance: " + tolerance); + "\n market ASW spread: " + floatingBondMktAssetSwapSpread1 + + "\n par ASW spread: " + floatingBondParAssetSwapSpread1 + + "\n error: " + error3 + + "\n tolerance: " + tolerance); } // FRN Underlying bond (Isin: XS0090566539 COE 0 09/24/18) // maturity occurs on a business day - Schedule floatingBondSchedule2 = new Schedule( new Date(24,Month.September,2004), - new Date(24,Month.September,2018), - new Period(Frequency.Semiannual), bondCalendar, - BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, - DateGeneration.Rule.Backward, false); + Schedule floatingBondSchedule2 = new Schedule(new Date(24, Month.September, 2004), + new Date(24, Month.September, 2018), + new Period(Frequency.Semiannual), bondCalendar, + BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, + DateGeneration.Rule.Backward, false); Bond floatingBond2 = new FloatingRateBond(settlementDays, vars.faceAmount, - floatingBondSchedule2, - vars.iborIndex, new Actual360(), - BusinessDayConvention.ModifiedFollowing, fixingDays, - new List{1}, new List{0.0025}, - new List(), new List(), - inArrears, - 100.0, new Date(24,Month.September,2004)); + floatingBondSchedule2, + vars.iborIndex, new Actual360(), + BusinessDayConvention.ModifiedFollowing, fixingDays, + new List {1}, new List {0.0025}, + new List < double? >(), new List < double? >(), + inArrears, + 100.0, new Date(24, Month.September, 2004)); floatingBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer); - vars.iborIndex.addFixing(new Date(22,Month.March,2007), 0.04013); + vars.iborIndex.addFixing(new Date(22, Month.March, 2007), 0.04013); // market price observed on 7th June 2007 double floatingBondMktPrice2 = 101.248 ; - double floatingBondMktFullPrice2 = floatingBondMktPrice2+floatingBond2.accruedAmount(); - AssetSwap floatingBondParAssetSwap2= new AssetSwap(payFixedRate, - floatingBond2, floatingBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + double floatingBondMktFullPrice2 = floatingBondMktPrice2 + floatingBond2.accruedAmount(); + AssetSwap floatingBondParAssetSwap2 = new AssetSwap(payFixedRate, + floatingBond2, floatingBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); floatingBondParAssetSwap2.setPricingEngine(swapEngine); double floatingBondParAssetSwapSpread2 = floatingBondParAssetSwap2.fairSpread(); AssetSwap floatingBondMktAssetSwap2 = new AssetSwap(payFixedRate, - floatingBond2, floatingBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - mktAssetSwap); + floatingBond2, floatingBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + mktAssetSwap); floatingBondMktAssetSwap2.setPricingEngine(swapEngine); double floatingBondMktAssetSwapSpread2 = floatingBondMktAssetSwap2.fairSpread(); - double error4 = Math.Abs(floatingBondMktAssetSwapSpread2- - 100*floatingBondParAssetSwapSpread2/floatingBondMktFullPrice2); + double error4 = Math.Abs(floatingBondMktAssetSwapSpread2 - + 100 * floatingBondParAssetSwapSpread2 / floatingBondMktFullPrice2); - if (error4>tolerance) { + if (error4 > tolerance) + { QAssert.Fail("wrong asset swap spreads for floating bond:" + - "\n market ASW spread: " + floatingBondMktAssetSwapSpread2 + - "\n par ASW spread: " + floatingBondParAssetSwapSpread2 + - "\n error: " + error4 + - "\n tolerance: " + tolerance); + "\n market ASW spread: " + floatingBondMktAssetSwapSpread2 + + "\n par ASW spread: " + floatingBondParAssetSwapSpread2 + + "\n error: " + error4 + + "\n tolerance: " + tolerance); } // CMS Underlying bond (Isin: XS0228052402 CRDIT 0 8/22/20) // maturity doesn't occur on a business day - Schedule cmsBondSchedule1 = new Schedule( new Date(22,Month.August,2005), - new Date(22,Month.August,2020), - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Schedule cmsBondSchedule1 = new Schedule(new Date(22, Month.August, 2005), + new Date(22, Month.August, 2020), + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); Bond cmsBond1 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule1, - vars.swapIndex, new Thirty360(), - BusinessDayConvention.Following, fixingDays, - new List{1.0}, new List{0.0}, - new List{0.055}, new List{0.025}, - inArrears, - 100.0, new Date(22,Month.August,2005)); + vars.swapIndex, new Thirty360(), + BusinessDayConvention.Following, fixingDays, + new List {1.0}, new List {0.0}, + new List < double? > {0.055}, new List < double? > {0.025}, + inArrears, + 100.0, new Date(22, Month.August, 2005)); cmsBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer); - vars.swapIndex.addFixing(new Date(18,Month.August,2006), 0.04158); + vars.swapIndex.addFixing(new Date(18, Month.August, 2006), 0.04158); double cmsBondMktPrice1 = 88.45 ; // market price observed on 7th June 2007 - double cmsBondMktFullPrice1 = cmsBondMktPrice1+cmsBond1.accruedAmount(); + double cmsBondMktFullPrice1 = cmsBondMktPrice1 + cmsBond1.accruedAmount(); AssetSwap cmsBondParAssetSwap1 = new AssetSwap(payFixedRate, - cmsBond1, cmsBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + cmsBond1, cmsBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); cmsBondParAssetSwap1.setPricingEngine(swapEngine); double cmsBondParAssetSwapSpread1 = cmsBondParAssetSwap1.fairSpread(); AssetSwap cmsBondMktAssetSwap1 = new AssetSwap(payFixedRate, - cmsBond1, cmsBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - mktAssetSwap); + cmsBond1, cmsBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + mktAssetSwap); cmsBondMktAssetSwap1.setPricingEngine(swapEngine); double cmsBondMktAssetSwapSpread1 = cmsBondMktAssetSwap1.fairSpread(); - double error5 = Math.Abs(cmsBondMktAssetSwapSpread1- - 100*cmsBondParAssetSwapSpread1/cmsBondMktFullPrice1); + double error5 = Math.Abs(cmsBondMktAssetSwapSpread1 - + 100 * cmsBondParAssetSwapSpread1 / cmsBondMktFullPrice1); - if (error5>tolerance) { + if (error5 > tolerance) + { QAssert.Fail("wrong asset swap spreads for cms bond:" + - "\n market ASW spread: " + cmsBondMktAssetSwapSpread1 + - "\n par ASW spread: " + cmsBondParAssetSwapSpread1 + - "\n error: " + error5 + - "\n tolerance: " + tolerance); + "\n market ASW spread: " + cmsBondMktAssetSwapSpread1 + + "\n par ASW spread: " + cmsBondParAssetSwapSpread1 + + "\n error: " + error5 + + "\n tolerance: " + tolerance); } // CMS Underlying bond (Isin: XS0218766664 ISPIM 0 5/6/15) // maturity occurs on a business day - Schedule cmsBondSchedule2 = new Schedule(new Date(06,Month.May,2005), - new Date(06,Month.May,2015), - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Schedule cmsBondSchedule2 = new Schedule(new Date(06, Month.May, 2005), + new Date(06, Month.May, 2015), + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); Bond cmsBond2 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule2, - vars.swapIndex, new Thirty360(), - BusinessDayConvention.Following, fixingDays, - new List{0.84}, new List{0.0}, - new List(), new List(), - inArrears, - 100.0, new Date(06,Month.May,2005)); + vars.swapIndex, new Thirty360(), + BusinessDayConvention.Following, fixingDays, + new List {0.84}, new List {0.0}, + new List < double? >(), new List < double? >(), + inArrears, + 100.0, new Date(06, Month.May, 2005)); cmsBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer); - vars.swapIndex.addFixing(new Date(04,Month.May,2006), 0.04217); + vars.swapIndex.addFixing(new Date(04, Month.May, 2006), 0.04217); double cmsBondMktPrice2 = 94.08 ; // market price observed on 7th June 2007 - double cmsBondMktFullPrice2 = cmsBondMktPrice2+cmsBond2.accruedAmount(); + double cmsBondMktFullPrice2 = cmsBondMktPrice2 + cmsBond2.accruedAmount(); AssetSwap cmsBondParAssetSwap2 = new AssetSwap(payFixedRate, - cmsBond2, cmsBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + cmsBond2, cmsBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); cmsBondParAssetSwap2.setPricingEngine(swapEngine); double cmsBondParAssetSwapSpread2 = cmsBondParAssetSwap2.fairSpread(); AssetSwap cmsBondMktAssetSwap2 = new AssetSwap(payFixedRate, - cmsBond2, cmsBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - mktAssetSwap); + cmsBond2, cmsBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + mktAssetSwap); cmsBondMktAssetSwap2.setPricingEngine(swapEngine); double cmsBondMktAssetSwapSpread2 = cmsBondMktAssetSwap2.fairSpread(); - double error6 = Math.Abs(cmsBondMktAssetSwapSpread2- - 100*cmsBondParAssetSwapSpread2/cmsBondMktFullPrice2); + double error6 = Math.Abs(cmsBondMktAssetSwapSpread2 - + 100 * cmsBondParAssetSwapSpread2 / cmsBondMktFullPrice2); - if (error6>tolerance) { + if (error6 > tolerance) + { QAssert.Fail("wrong asset swap spreads for cms bond:" + - "\n market ASW spread: " + cmsBondMktAssetSwapSpread2 + - "\n par ASW spread: " + cmsBondParAssetSwapSpread2 + - "\n error: " + error6 + - "\n tolerance: " + tolerance); + "\n market ASW spread: " + cmsBondMktAssetSwapSpread2 + + "\n par ASW spread: " + cmsBondParAssetSwapSpread2 + + "\n error: " + error6 + + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15) // maturity doesn't occur on a business day Bond zeroCpnBond1 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount, - new Date(20,Month.December,2015), BusinessDayConvention.Following, - 100.0, new Date(19,Month.December,1985)); + new Date(20, Month.December, 2015), BusinessDayConvention.Following, + 100.0, new Date(19, Month.December, 1985)); zeroCpnBond1.setPricingEngine(bondEngine); // market price observed on 12th June 2007 double zeroCpnBondMktPrice1 = 70.436 ; - double zeroCpnBondMktFullPrice1 = zeroCpnBondMktPrice1+zeroCpnBond1.accruedAmount(); - AssetSwap zeroCpnBondParAssetSwap1 = new AssetSwap(payFixedRate,zeroCpnBond1, - zeroCpnBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + double zeroCpnBondMktFullPrice1 = zeroCpnBondMktPrice1 + zeroCpnBond1.accruedAmount(); + AssetSwap zeroCpnBondParAssetSwap1 = new AssetSwap(payFixedRate, zeroCpnBond1, + zeroCpnBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); zeroCpnBondParAssetSwap1.setPricingEngine(swapEngine); double zeroCpnBondParAssetSwapSpread1 = zeroCpnBondParAssetSwap1.fairSpread(); - AssetSwap zeroCpnBondMktAssetSwap1 = new AssetSwap(payFixedRate,zeroCpnBond1, - zeroCpnBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - mktAssetSwap); + AssetSwap zeroCpnBondMktAssetSwap1 = new AssetSwap(payFixedRate, zeroCpnBond1, + zeroCpnBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + mktAssetSwap); zeroCpnBondMktAssetSwap1.setPricingEngine(swapEngine); double zeroCpnBondMktAssetSwapSpread1 = zeroCpnBondMktAssetSwap1.fairSpread(); - double error7 = Math.Abs(zeroCpnBondMktAssetSwapSpread1- - 100*zeroCpnBondParAssetSwapSpread1/zeroCpnBondMktFullPrice1); + double error7 = Math.Abs(zeroCpnBondMktAssetSwapSpread1 - + 100 * zeroCpnBondParAssetSwapSpread1 / zeroCpnBondMktFullPrice1); - if (error7>tolerance) { + if (error7 > tolerance) + { QAssert.Fail("wrong asset swap spreads for zero cpn bond:" + - "\n market ASW spread: " + zeroCpnBondMktAssetSwapSpread1 + - "\n par ASW spread: " + zeroCpnBondParAssetSwapSpread1 + - "\n error: " + error7 + - "\n tolerance: " + tolerance); + "\n market ASW spread: " + zeroCpnBondMktAssetSwapSpread1 + + "\n par ASW spread: " + zeroCpnBondParAssetSwapSpread1 + + "\n error: " + error7 + + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28) // maturity occurs on a business day Bond zeroCpnBond2 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount, - new Date(17,Month.February,2028), - BusinessDayConvention.Following, - 100.0, new Date(17,Month.February,1998)); + new Date(17, Month.February, 2028), + BusinessDayConvention.Following, + 100.0, new Date(17, Month.February, 1998)); zeroCpnBond2.setPricingEngine(bondEngine); @@ -1094,41 +1110,42 @@ public void testMarketASWSpread() // market price observed on 12th June 2007 double zeroCpnBondMktPrice2 = 35.160 ; - double zeroCpnBondMktFullPrice2 = zeroCpnBondMktPrice2+zeroCpnBond2.accruedAmount(); - AssetSwap zeroCpnBondParAssetSwap2 = new AssetSwap(payFixedRate,zeroCpnBond2, - zeroCpnBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + double zeroCpnBondMktFullPrice2 = zeroCpnBondMktPrice2 + zeroCpnBond2.accruedAmount(); + AssetSwap zeroCpnBondParAssetSwap2 = new AssetSwap(payFixedRate, zeroCpnBond2, + zeroCpnBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); zeroCpnBondParAssetSwap2.setPricingEngine(swapEngine); double zeroCpnBondParAssetSwapSpread2 = zeroCpnBondParAssetSwap2.fairSpread(); - AssetSwap zeroCpnBondMktAssetSwap2 = new AssetSwap(payFixedRate,zeroCpnBond2, - zeroCpnBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - mktAssetSwap); + AssetSwap zeroCpnBondMktAssetSwap2 = new AssetSwap(payFixedRate, zeroCpnBond2, + zeroCpnBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + mktAssetSwap); zeroCpnBondMktAssetSwap2.setPricingEngine(swapEngine); double zeroCpnBondMktAssetSwapSpread2 = zeroCpnBondMktAssetSwap2.fairSpread(); - double error8 = Math.Abs(zeroCpnBondMktAssetSwapSpread2- - 100*zeroCpnBondParAssetSwapSpread2/zeroCpnBondMktFullPrice2); + double error8 = Math.Abs(zeroCpnBondMktAssetSwapSpread2 - + 100 * zeroCpnBondParAssetSwapSpread2 / zeroCpnBondMktFullPrice2); - if (error8>tolerance) { + if (error8 > tolerance) + { QAssert.Fail("wrong asset swap spreads for zero cpn bond:" + - "\n market ASW spread: " + zeroCpnBondMktAssetSwapSpread2 + - "\n par ASW spread: " + zeroCpnBondParAssetSwapSpread2 + - "\n error: " + error8 + - "\n tolerance: " + tolerance); + "\n market ASW spread: " + zeroCpnBondMktAssetSwapSpread2 + + "\n par ASW spread: " + zeroCpnBondParAssetSwapSpread2 + + "\n error: " + error8 + + "\n tolerance: " + tolerance); } - } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testZSpread() + public void testZSpread() { // Testing clean and dirty price with null Z-spread against theoretical prices... CommonVars vars = new CommonVars(); @@ -1141,269 +1158,277 @@ public void testZSpread() // Fixed bond (Isin: DE0001135275 DBR 4 01/04/37) // maturity doesn't occur on a business day - Schedule fixedBondSchedule1 = new Schedule(new Date(4,Month.January,2005), - new Date(4,Month.January,2037), - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Schedule fixedBondSchedule1 = new Schedule(new Date(4, Month.January, 2005), + new Date(4, Month.January, 2037), + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); Bond fixedBond1 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule1, - new List{0.04}, - new ActualActual(ActualActual.Convention.ISDA), BusinessDayConvention.Following, - 100.0, new Date(4,Month.January,2005)); + new List {0.04}, + new ActualActual(ActualActual.Convention.ISDA), BusinessDayConvention.Following, + 100.0, new Date(4, Month.January, 2005)); IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure); fixedBond1.setPricingEngine(bondEngine); double fixedBondImpliedValue1 = fixedBond1.cleanPrice(); - Date fixedBondSettlementDate1= fixedBond1.settlementDate(); + Date fixedBondSettlementDate1 = fixedBond1.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YC... - double fixedBondCleanPrice1 = BondFunctions.cleanPrice( fixedBond1, vars.termStructure, vars.spread, - new Actual365Fixed(), vars.compounding, Frequency.Annual, fixedBondSettlementDate1); + double fixedBondCleanPrice1 = BondFunctions.cleanPrice(fixedBond1, vars.termStructure, vars.spread, + new Actual365Fixed(), vars.compounding, Frequency.Annual, fixedBondSettlementDate1); double tolerance = 1.0e-13; - double error1 = Math.Abs(fixedBondImpliedValue1-fixedBondCleanPrice1); - if (error1>tolerance) { + double error1 = Math.Abs(fixedBondImpliedValue1 - fixedBondCleanPrice1); + if (error1 > tolerance) + { QAssert.Fail("wrong clean price for fixed bond:" + - "\n market asset swap spread: " + - fixedBondImpliedValue1 + - "\n par asset swap spread: " + fixedBondCleanPrice1 + - "\n error: " + error1 + - "\n tolerance: " + tolerance); + "\n market asset swap spread: " + + fixedBondImpliedValue1 + + "\n par asset swap spread: " + fixedBondCleanPrice1 + + "\n error: " + error1 + + "\n tolerance: " + tolerance); } // Fixed bond (Isin: IT0006527060 IBRD 5 02/05/19) // maturity occurs on a business day - Schedule fixedBondSchedule2 = new Schedule(new Date(5,Month.February,2005), - new Date(5,Month.February,2019), - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Schedule fixedBondSchedule2 = new Schedule(new Date(5, Month.February, 2005), + new Date(5, Month.February, 2019), + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); Bond fixedBond2 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule2, - new List{0.05}, - new Thirty360(Thirty360.Thirty360Convention.BondBasis), BusinessDayConvention.Following, - 100.0, new Date(5,Month.February,2005)); + new List {0.05}, + new Thirty360(Thirty360.Thirty360Convention.BondBasis), BusinessDayConvention.Following, + 100.0, new Date(5, Month.February, 2005)); fixedBond2.setPricingEngine(bondEngine); double fixedBondImpliedValue2 = fixedBond2.cleanPrice(); - Date fixedBondSettlementDate2= fixedBond2.settlementDate(); + Date fixedBondSettlementDate2 = fixedBond2.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double fixedBondCleanPrice2 = BondFunctions.cleanPrice(fixedBond2, vars.termStructure, vars.spread, - new Actual365Fixed(), vars.compounding, Frequency.Annual, fixedBondSettlementDate2); - double error3 = Math.Abs(fixedBondImpliedValue2-fixedBondCleanPrice2); - if (error3>tolerance) { + new Actual365Fixed(), vars.compounding, Frequency.Annual, fixedBondSettlementDate2); + double error3 = Math.Abs(fixedBondImpliedValue2 - fixedBondCleanPrice2); + if (error3 > tolerance) + { QAssert.Fail("wrong clean price for fixed bond:" + - "\n market asset swap spread: " + - fixedBondImpliedValue2 + - "\n par asset swap spread: " + fixedBondCleanPrice2 + - "\n error: " + error3 + - "\n tolerance: " + tolerance); + "\n market asset swap spread: " + + fixedBondImpliedValue2 + + "\n par asset swap spread: " + fixedBondCleanPrice2 + + "\n error: " + error3 + + "\n tolerance: " + tolerance); } // FRN bond (Isin: IT0003543847 ISPIM 0 09/29/13) // maturity doesn't occur on a business day - Schedule floatingBondSchedule1 = new Schedule(new Date(29,Month.September,2003), - new Date(29,Month.September,2013), - new Period(Frequency.Semiannual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Schedule floatingBondSchedule1 = new Schedule(new Date(29, Month.September, 2003), + new Date(29, Month.September, 2013), + new Period(Frequency.Semiannual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); Bond floatingBond1 = new FloatingRateBond(settlementDays, vars.faceAmount, - floatingBondSchedule1, - vars.iborIndex, new Actual360(), - BusinessDayConvention.Following, fixingDays, - new List{1}, new List{0.0056}, - new List(), new List(), - inArrears, - 100.0, new Date(29,Month.September,2003)); + floatingBondSchedule1, + vars.iborIndex, new Actual360(), + BusinessDayConvention.Following, fixingDays, + new List {1}, new List {0.0056}, + new List < double? >(), new List < double? >(), + inArrears, + 100.0, new Date(29, Month.September, 2003)); floatingBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer); - vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402); + vars.iborIndex.addFixing(new Date(27, Month.March, 2007), 0.0402); double floatingBondImpliedValue1 = floatingBond1.cleanPrice(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double floatingBondCleanPrice1 = BondFunctions.cleanPrice(floatingBond1, vars.termStructure, vars.spread, - new Actual365Fixed(), vars.compounding, Frequency.Semiannual, fixedBondSettlementDate1); - double error5 = Math.Abs(floatingBondImpliedValue1-floatingBondCleanPrice1); - if (error5>tolerance) { + new Actual365Fixed(), vars.compounding, Frequency.Semiannual, fixedBondSettlementDate1); + double error5 = Math.Abs(floatingBondImpliedValue1 - floatingBondCleanPrice1); + if (error5 > tolerance) + { QAssert.Fail("wrong clean price for fixed bond:" + - "\n market asset swap spread: " + - floatingBondImpliedValue1 + - "\n par asset swap spread: " + floatingBondCleanPrice1 + - "\n error: " + error5 + - "\n tolerance: " + tolerance); + "\n market asset swap spread: " + + floatingBondImpliedValue1 + + "\n par asset swap spread: " + floatingBondCleanPrice1 + + "\n error: " + error5 + + "\n tolerance: " + tolerance); } // FRN bond (Isin: XS0090566539 COE 0 09/24/18) // maturity occurs on a business day - Schedule floatingBondSchedule2 = new Schedule(new Date(24,Month.September,2004), - new Date(24,Month.September,2018), - new Period(Frequency.Semiannual), bondCalendar, - BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, - DateGeneration.Rule.Backward, false); + Schedule floatingBondSchedule2 = new Schedule(new Date(24, Month.September, 2004), + new Date(24, Month.September, 2018), + new Period(Frequency.Semiannual), bondCalendar, + BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, + DateGeneration.Rule.Backward, false); Bond floatingBond2 = new FloatingRateBond(settlementDays, vars.faceAmount, - floatingBondSchedule2, - vars.iborIndex, new Actual360(), - BusinessDayConvention.ModifiedFollowing, fixingDays, - new List{1}, new List{0.0025}, - new List(), new List(), - inArrears, - 100.0, new Date(24,Month.September,2004)); + floatingBondSchedule2, + vars.iborIndex, new Actual360(), + BusinessDayConvention.ModifiedFollowing, fixingDays, + new List {1}, new List {0.0025}, + new List < double? >(), new List < double? >(), + inArrears, + 100.0, new Date(24, Month.September, 2004)); floatingBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer); - vars.iborIndex.addFixing(new Date(22,Month.March,2007), 0.04013); + vars.iborIndex.addFixing(new Date(22, Month.March, 2007), 0.04013); double floatingBondImpliedValue2 = floatingBond2.cleanPrice(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double floatingBondCleanPrice2 = BondFunctions.cleanPrice(floatingBond2, vars.termStructure, - vars.spread, new Actual365Fixed(), vars.compounding, Frequency.Semiannual, fixedBondSettlementDate1); - double error7 = Math.Abs(floatingBondImpliedValue2-floatingBondCleanPrice2); - if (error7>tolerance) { + vars.spread, new Actual365Fixed(), vars.compounding, Frequency.Semiannual, fixedBondSettlementDate1); + double error7 = Math.Abs(floatingBondImpliedValue2 - floatingBondCleanPrice2); + if (error7 > tolerance) + { QAssert.Fail("wrong clean price for fixed bond:" - + "\n market asset swap spread: " + - floatingBondImpliedValue2 - + "\n par asset swap spread: " + floatingBondCleanPrice2 - + "\n error: " + error7 - + "\n tolerance: " + tolerance); + + "\n market asset swap spread: " + + floatingBondImpliedValue2 + + "\n par asset swap spread: " + floatingBondCleanPrice2 + + "\n error: " + error7 + + "\n tolerance: " + tolerance); } //// CMS bond (Isin: XS0228052402 CRDIT 0 8/22/20) //// maturity doesn't occur on a business day - Schedule cmsBondSchedule1 = new Schedule(new Date(22,Month.August,2005), - new Date(22,Month.August,2020), - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Schedule cmsBondSchedule1 = new Schedule(new Date(22, Month.August, 2005), + new Date(22, Month.August, 2020), + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); Bond cmsBond1 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule1, - vars.swapIndex, new Thirty360(), - BusinessDayConvention.Following, fixingDays, - new List{1.0}, new List{0.0}, - new List{0.055}, new List{0.025}, - inArrears, - 100.0, new Date(22,Month.August,2005)); + vars.swapIndex, new Thirty360(), + BusinessDayConvention.Following, fixingDays, + new List {1.0}, new List {0.0}, + new List < double? > {0.055}, new List < double? > {0.025}, + inArrears, + 100.0, new Date(22, Month.August, 2005)); cmsBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer); - vars.swapIndex.addFixing(new Date(18,Month.August,2006), 0.04158); + vars.swapIndex.addFixing(new Date(18, Month.August, 2006), 0.04158); double cmsBondImpliedValue1 = cmsBond1.cleanPrice(); - Date cmsBondSettlementDate1= cmsBond1.settlementDate(); + Date cmsBondSettlementDate1 = cmsBond1.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double cmsBondCleanPrice1 = BondFunctions.cleanPrice(cmsBond1, vars.termStructure, vars.spread, - new Actual365Fixed(), vars.compounding, Frequency.Annual, cmsBondSettlementDate1); - double error9 = Math.Abs(cmsBondImpliedValue1-cmsBondCleanPrice1); - if (error9>tolerance) { + new Actual365Fixed(), vars.compounding, Frequency.Annual, cmsBondSettlementDate1); + double error9 = Math.Abs(cmsBondImpliedValue1 - cmsBondCleanPrice1); + if (error9 > tolerance) + { QAssert.Fail("wrong clean price for fixed bond:" - + "\n market asset swap spread: " + cmsBondImpliedValue1 - + "\n par asset swap spread: " + cmsBondCleanPrice1 - + "\n error: " + error9 - + "\n tolerance: " + tolerance); + + "\n market asset swap spread: " + cmsBondImpliedValue1 + + "\n par asset swap spread: " + cmsBondCleanPrice1 + + "\n error: " + error9 + + "\n tolerance: " + tolerance); } // CMS bond (Isin: XS0218766664 ISPIM 0 5/6/15) // maturity occurs on a business day - Schedule cmsBondSchedule2 = new Schedule(new Date(06,Month.May,2005), - new Date(06,Month.May,2015), - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Schedule cmsBondSchedule2 = new Schedule(new Date(06, Month.May, 2005), + new Date(06, Month.May, 2015), + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); Bond cmsBond2 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule2, - vars.swapIndex, new Thirty360(), - BusinessDayConvention.Following, fixingDays, - new List{0.84}, new List{0.0}, - new List(), new List(), - inArrears, - 100.0, new Date(06,Month.May,2005)); + vars.swapIndex, new Thirty360(), + BusinessDayConvention.Following, fixingDays, + new List {0.84}, new List {0.0}, + new List < double? >(), new List < double? >(), + inArrears, + 100.0, new Date(06, Month.May, 2005)); cmsBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer); - vars.swapIndex.addFixing(new Date(04,Month.May,2006), 0.04217); + vars.swapIndex.addFixing(new Date(04, Month.May, 2006), 0.04217); double cmsBondImpliedValue2 = cmsBond2.cleanPrice(); - Date cmsBondSettlementDate2= cmsBond2.settlementDate(); + Date cmsBondSettlementDate2 = cmsBond2.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double cmsBondCleanPrice2 = BondFunctions.cleanPrice(cmsBond2, vars.termStructure, vars.spread, - new Actual365Fixed(), vars.compounding, Frequency.Annual, cmsBondSettlementDate2); - double error11 = Math.Abs(cmsBondImpliedValue2-cmsBondCleanPrice2); - if (error11>tolerance) { + new Actual365Fixed(), vars.compounding, Frequency.Annual, cmsBondSettlementDate2); + double error11 = Math.Abs(cmsBondImpliedValue2 - cmsBondCleanPrice2); + if (error11 > tolerance) + { QAssert.Fail("wrong clean price for fixed bond:" - + "\n market asset swap spread: " + cmsBondImpliedValue2 - + "\n par asset swap spread: " + cmsBondCleanPrice2 - + "\n error: " + error11 - + "\n tolerance: " + tolerance); + + "\n market asset swap spread: " + cmsBondImpliedValue2 + + "\n par asset swap spread: " + cmsBondCleanPrice2 + + "\n error: " + error11 + + "\n tolerance: " + tolerance); } // Zero-Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15) // maturity doesn't occur on a business day Bond zeroCpnBond1 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount, - new Date(20,Month.December,2015), - BusinessDayConvention.Following, - 100.0, new Date(19,Month.December,1985)); + new Date(20, Month.December, 2015), + BusinessDayConvention.Following, + 100.0, new Date(19, Month.December, 1985)); zeroCpnBond1.setPricingEngine(bondEngine); double zeroCpnBondImpliedValue1 = zeroCpnBond1.cleanPrice(); - Date zeroCpnBondSettlementDate1= zeroCpnBond1.settlementDate(); + Date zeroCpnBondSettlementDate1 = zeroCpnBond1.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve - double zeroCpnBondCleanPrice1 = BondFunctions.cleanPrice(zeroCpnBond1,vars.termStructure, vars.spread, - new Actual365Fixed(), vars.compounding, Frequency.Annual, zeroCpnBondSettlementDate1); - double error13 = Math.Abs(zeroCpnBondImpliedValue1-zeroCpnBondCleanPrice1); - if (error13>tolerance) { + double zeroCpnBondCleanPrice1 = BondFunctions.cleanPrice(zeroCpnBond1, vars.termStructure, vars.spread, + new Actual365Fixed(), vars.compounding, Frequency.Annual, zeroCpnBondSettlementDate1); + double error13 = Math.Abs(zeroCpnBondImpliedValue1 - zeroCpnBondCleanPrice1); + if (error13 > tolerance) + { QAssert.Fail("wrong clean price for zero coupon bond:" - + "\n zero cpn implied value: " + - zeroCpnBondImpliedValue1 - + "\n zero cpn price: " + zeroCpnBondCleanPrice1 - + "\n error: " + error13 - + "\n tolerance: " + tolerance); + + "\n zero cpn implied value: " + + zeroCpnBondImpliedValue1 + + "\n zero cpn price: " + zeroCpnBondCleanPrice1 + + "\n error: " + error13 + + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28) // maturity doesn't occur on a business day Bond zeroCpnBond2 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount, - new Date(17,Month.February,2028), - BusinessDayConvention.Following, - 100.0, new Date(17,Month.February,1998)); + new Date(17, Month.February, 2028), + BusinessDayConvention.Following, + 100.0, new Date(17, Month.February, 1998)); zeroCpnBond2.setPricingEngine(bondEngine); double zeroCpnBondImpliedValue2 = zeroCpnBond2.cleanPrice(); - Date zeroCpnBondSettlementDate2= zeroCpnBond2.settlementDate(); + Date zeroCpnBondSettlementDate2 = zeroCpnBond2.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve - double zeroCpnBondCleanPrice2 = BondFunctions.cleanPrice(zeroCpnBond2,vars.termStructure, vars.spread, - new Actual365Fixed(), vars.compounding, Frequency.Annual, zeroCpnBondSettlementDate2); - double error15 = Math.Abs(zeroCpnBondImpliedValue2-zeroCpnBondCleanPrice2); - if (error15>tolerance) { + double zeroCpnBondCleanPrice2 = BondFunctions.cleanPrice(zeroCpnBond2, vars.termStructure, vars.spread, + new Actual365Fixed(), vars.compounding, Frequency.Annual, zeroCpnBondSettlementDate2); + double error15 = Math.Abs(zeroCpnBondImpliedValue2 - zeroCpnBondCleanPrice2); + if (error15 > tolerance) + { QAssert.Fail("wrong clean price for zero coupon bond:" - + "\n zero cpn implied value: " + - zeroCpnBondImpliedValue2 - + "\n zero cpn price: " + zeroCpnBondCleanPrice2 - + "\n error: " + error15 - + "\n tolerance: " + tolerance); + + "\n zero cpn implied value: " + + zeroCpnBondImpliedValue2 + + "\n zero cpn price: " + zeroCpnBondCleanPrice2 + + "\n error: " + error15 + + "\n tolerance: " + tolerance); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testGenericBondImplied() + public void testGenericBondImplied() { // Testing implied generic-bond value against asset-swap fair price with null spread... @@ -1419,334 +1444,343 @@ public void testGenericBondImplied() // Fixed Underlying bond (Isin: DE0001135275 DBR 4 01/04/37) // maturity doesn't occur on a business day - Date fixedBondStartDate1 =new Date(4,Month.January,2005); - Date fixedBondMaturityDate1 =new Date(4,Month.January,2037); + Date fixedBondStartDate1 = new Date(4, Month.January, 2005); + Date fixedBondMaturityDate1 = new Date(4, Month.January, 2037); Schedule fixedBondSchedule1 = new Schedule(fixedBondStartDate1, - fixedBondMaturityDate1, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + fixedBondMaturityDate1, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List fixedBondLeg1 = new FixedRateLeg(fixedBondSchedule1) - .withCouponRates(0.04, new ActualActual(ActualActual.Convention.ISDA)) - .withNotionals(vars.faceAmount); + .withCouponRates(0.04, new ActualActual(ActualActual.Convention.ISDA)) + .withNotionals(vars.faceAmount); Date fixedbondRedemption1 = bondCalendar.adjust(fixedBondMaturityDate1, BusinessDayConvention.Following); fixedBondLeg1.Add((new SimpleCashFlow(100.0, fixedbondRedemption1))); Bond fixedBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - fixedBondMaturityDate1, fixedBondStartDate1, fixedBondLeg1); + fixedBondMaturityDate1, fixedBondStartDate1, fixedBondLeg1); IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure); - IPricingEngine swapEngine= new DiscountingSwapEngine(vars.termStructure); + IPricingEngine swapEngine = new DiscountingSwapEngine(vars.termStructure); fixedBond1.setPricingEngine(bondEngine); double fixedBondPrice1 = fixedBond1.cleanPrice(); AssetSwap fixedBondAssetSwap1 = new AssetSwap(payFixeddouble, - fixedBond1, fixedBondPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + fixedBond1, fixedBondPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); fixedBondAssetSwap1.setPricingEngine(swapEngine); double fixedBondAssetSwapPrice1 = fixedBondAssetSwap1.fairCleanPrice(); double tolerance = 1.0e-13; - double error1 = Math.Abs(fixedBondAssetSwapPrice1-fixedBondPrice1); + double error1 = Math.Abs(fixedBondAssetSwapPrice1 - fixedBondPrice1); - if (error1>tolerance) { + if (error1 > tolerance) + { QAssert.Fail("wrong zero spread asset swap price for fixed bond:" - + "\n bond's clean price: " + fixedBondPrice1 - + "\n asset swap fair price: " + fixedBondAssetSwapPrice1 - + "\n error: " + error1 - + "\n tolerance: " + tolerance); + + "\n bond's clean price: " + fixedBondPrice1 + + "\n asset swap fair price: " + fixedBondAssetSwapPrice1 + + "\n error: " + error1 + + "\n tolerance: " + tolerance); } // Fixed Underlying bond (Isin: IT0006527060 IBRD 5 02/05/19) // maturity occurs on a business day - Date fixedBondStartDate2 =new Date(5,Month.February,2005); - Date fixedBondMaturityDate2 =new Date(5,Month.February,2019); - Schedule fixedBondSchedule2= new Schedule(fixedBondStartDate2, - fixedBondMaturityDate2, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date fixedBondStartDate2 = new Date(5, Month.February, 2005); + Date fixedBondMaturityDate2 = new Date(5, Month.February, 2019); + Schedule fixedBondSchedule2 = new Schedule(fixedBondStartDate2, + fixedBondMaturityDate2, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List fixedBondLeg2 = new FixedRateLeg(fixedBondSchedule2) - .withCouponRates(0.05, new Thirty360(Thirty360.Thirty360Convention.BondBasis)) - .withNotionals(vars.faceAmount); - Date fixedbondRedemption2 = bondCalendar.adjust(fixedBondMaturityDate2,BusinessDayConvention.Following); + .withCouponRates(0.05, new Thirty360(Thirty360.Thirty360Convention.BondBasis)) + .withNotionals(vars.faceAmount); + Date fixedbondRedemption2 = bondCalendar.adjust(fixedBondMaturityDate2, BusinessDayConvention.Following); fixedBondLeg2.Add(new SimpleCashFlow(100.0, fixedbondRedemption2)); Bond fixedBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - fixedBondMaturityDate2, fixedBondStartDate2, fixedBondLeg2); + fixedBondMaturityDate2, fixedBondStartDate2, fixedBondLeg2); fixedBond2.setPricingEngine(bondEngine); double fixedBondPrice2 = fixedBond2.cleanPrice(); - AssetSwap fixedBondAssetSwap2= new AssetSwap(payFixeddouble, - fixedBond2, fixedBondPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap fixedBondAssetSwap2 = new AssetSwap(payFixeddouble, + fixedBond2, fixedBondPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); fixedBondAssetSwap2.setPricingEngine(swapEngine); double fixedBondAssetSwapPrice2 = fixedBondAssetSwap2.fairCleanPrice(); - double error2 = Math.Abs(fixedBondAssetSwapPrice2-fixedBondPrice2); + double error2 = Math.Abs(fixedBondAssetSwapPrice2 - fixedBondPrice2); - if (error2>tolerance) { + if (error2 > tolerance) + { QAssert.Fail("wrong zero spread asset swap price for fixed bond:" - + "\n bond's clean price: " + fixedBondPrice2 - + "\n asset swap fair price: " + fixedBondAssetSwapPrice2 - + "\n error: " + error2 - + "\n tolerance: " + tolerance); + + "\n bond's clean price: " + fixedBondPrice2 + + "\n asset swap fair price: " + fixedBondAssetSwapPrice2 + + "\n error: " + error2 + + "\n tolerance: " + tolerance); } // FRN Underlying bond (Isin: IT0003543847 ISPIM 0 09/29/13) // maturity doesn't occur on a business day - Date floatingBondStartDate1 =new Date(29,Month.September,2003); - Date floatingBondMaturityDate1 =new Date(29,Month.September,2013); + Date floatingBondStartDate1 = new Date(29, Month.September, 2003); + Date floatingBondMaturityDate1 = new Date(29, Month.September, 2013); Schedule floatingBondSchedule1 = new Schedule(floatingBondStartDate1, - floatingBondMaturityDate1, - new Period(Frequency.Semiannual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + floatingBondMaturityDate1, + new Period(Frequency.Semiannual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List floatingBondLeg1 = new IborLeg(floatingBondSchedule1, vars.iborIndex) - .withPaymentDayCounter(new Actual360()) - .withFixingDays(fixingDays) - .withSpreads(0.0056) - .inArrears(inArrears) - .withNotionals(vars.faceAmount); + .withPaymentDayCounter(new Actual360()) + .withFixingDays(fixingDays) + .withSpreads(0.0056) + .inArrears(inArrears) + .withNotionals(vars.faceAmount); Date floatingbondRedemption1 = bondCalendar.adjust(floatingBondMaturityDate1, BusinessDayConvention.Following); floatingBondLeg1.Add(new SimpleCashFlow(100.0, floatingbondRedemption1)); Bond floatingBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - floatingBondMaturityDate1, floatingBondStartDate1, floatingBondLeg1); + floatingBondMaturityDate1, floatingBondStartDate1, floatingBondLeg1); floatingBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer); - vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402); + vars.iborIndex.addFixing(new Date(27, Month.March, 2007), 0.0402); double floatingBondPrice1 = floatingBond1.cleanPrice(); - AssetSwap floatingBondAssetSwap1= new AssetSwap(payFixeddouble, - floatingBond1, floatingBondPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap floatingBondAssetSwap1 = new AssetSwap(payFixeddouble, + floatingBond1, floatingBondPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); floatingBondAssetSwap1.setPricingEngine(swapEngine); double floatingBondAssetSwapPrice1 = floatingBondAssetSwap1.fairCleanPrice(); - double error3 = Math.Abs(floatingBondAssetSwapPrice1-floatingBondPrice1); + double error3 = Math.Abs(floatingBondAssetSwapPrice1 - floatingBondPrice1); - if (error3>tolerance) { + if (error3 > tolerance) + { QAssert.Fail("wrong zero spread asset swap price for floater:" - + "\n bond's clean price: " + floatingBondPrice1 - + "\n asset swap fair price: " + - floatingBondAssetSwapPrice1 - + "\n error: " + error3 - + "\n tolerance: " + tolerance); + + "\n bond's clean price: " + floatingBondPrice1 + + "\n asset swap fair price: " + + floatingBondAssetSwapPrice1 + + "\n error: " + error3 + + "\n tolerance: " + tolerance); } // FRN Underlying bond (Isin: XS0090566539 COE 0 09/24/18) // maturity occurs on a business day - Date floatingBondStartDate2 =new Date(24,Month.September,2004); - Date floatingBondMaturityDate2 =new Date(24,Month.September,2018); + Date floatingBondStartDate2 = new Date(24, Month.September, 2004); + Date floatingBondMaturityDate2 = new Date(24, Month.September, 2018); Schedule floatingBondSchedule2 = new Schedule(floatingBondStartDate2, - floatingBondMaturityDate2, - new Period(Frequency.Semiannual), bondCalendar, - BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, - DateGeneration.Rule.Backward, false); + floatingBondMaturityDate2, + new Period(Frequency.Semiannual), bondCalendar, + BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, + DateGeneration.Rule.Backward, false); List floatingBondLeg2 = new IborLeg(floatingBondSchedule2, vars.iborIndex) - .withPaymentDayCounter(new Actual360()) - .withFixingDays(fixingDays) - .withSpreads(0.0025) - .inArrears(inArrears) - .withNotionals(vars.faceAmount) - .withPaymentAdjustment(BusinessDayConvention.ModifiedFollowing); + .withPaymentDayCounter(new Actual360()) + .withFixingDays(fixingDays) + .withSpreads(0.0025) + .inArrears(inArrears) + .withNotionals(vars.faceAmount) + .withPaymentAdjustment(BusinessDayConvention.ModifiedFollowing); Date floatingbondRedemption2 = bondCalendar.adjust(floatingBondMaturityDate2, BusinessDayConvention.ModifiedFollowing); floatingBondLeg2.Add(new SimpleCashFlow(100.0, floatingbondRedemption2)); Bond floatingBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - floatingBondMaturityDate2, floatingBondStartDate2, floatingBondLeg2); + floatingBondMaturityDate2, floatingBondStartDate2, floatingBondLeg2); floatingBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer); - vars.iborIndex.addFixing(new Date(22,Month.March,2007), 0.04013); - double currentCoupon=0.04013+0.0025; - double floatingCurrentCoupon= floatingBond2.nextCouponRate(); - double error4= Math.Abs(floatingCurrentCoupon-currentCoupon); - if (error4>tolerance) { + vars.iborIndex.addFixing(new Date(22, Month.March, 2007), 0.04013); + double currentCoupon = 0.04013 + 0.0025; + double floatingCurrentCoupon = floatingBond2.nextCouponRate(); + double error4 = Math.Abs(floatingCurrentCoupon - currentCoupon); + if (error4 > tolerance) + { QAssert.Fail("wrong current coupon is returned for floater bond:" - + "\n bond's calculated current coupon: " + - currentCoupon - + "\n current coupon asked to the bond: " + - floatingCurrentCoupon - + "\n error: " + error4 - + "\n tolerance: " + tolerance); + + "\n bond's calculated current coupon: " + + currentCoupon + + "\n current coupon asked to the bond: " + + floatingCurrentCoupon + + "\n error: " + error4 + + "\n tolerance: " + tolerance); } double floatingBondPrice2 = floatingBond2.cleanPrice(); - AssetSwap floatingBondAssetSwap2= new AssetSwap(payFixeddouble, - floatingBond2, floatingBondPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap floatingBondAssetSwap2 = new AssetSwap(payFixeddouble, + floatingBond2, floatingBondPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); floatingBondAssetSwap2.setPricingEngine(swapEngine); double floatingBondAssetSwapPrice2 = floatingBondAssetSwap2.fairCleanPrice(); - double error5 = Math.Abs(floatingBondAssetSwapPrice2-floatingBondPrice2); + double error5 = Math.Abs(floatingBondAssetSwapPrice2 - floatingBondPrice2); - if (error5>tolerance) { + if (error5 > tolerance) + { QAssert.Fail("wrong zero spread asset swap price for floater:" - + "\n bond's clean price: " + floatingBondPrice2 - + "\n asset swap fair price: " + - floatingBondAssetSwapPrice2 - + "\n error: " + error5 - + "\n tolerance: " + tolerance); + + "\n bond's clean price: " + floatingBondPrice2 + + "\n asset swap fair price: " + + floatingBondAssetSwapPrice2 + + "\n error: " + error5 + + "\n tolerance: " + tolerance); } // CMS Underlying bond (Isin: XS0228052402 CRDIT 0 8/22/20) // maturity doesn't occur on a business day - Date cmsBondStartDate1 =new Date(22,Month.August,2005); - Date cmsBondMaturityDate1 =new Date(22,Month.August,2020); - Schedule cmsBondSchedule1= new Schedule(cmsBondStartDate1, - cmsBondMaturityDate1, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date cmsBondStartDate1 = new Date(22, Month.August, 2005); + Date cmsBondMaturityDate1 = new Date(22, Month.August, 2020); + Schedule cmsBondSchedule1 = new Schedule(cmsBondStartDate1, + cmsBondMaturityDate1, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List cmsBondLeg1 = new CmsLeg(cmsBondSchedule1, vars.swapIndex) - .withFixingDays(fixingDays) - .withPaymentDayCounter(new Thirty360()) - .withCaps(0.055) - .withFloors(0.025) - .inArrears(inArrears) - .withNotionals(vars.faceAmount); + .withFixingDays(fixingDays) + .withPaymentDayCounter(new Thirty360()) + .withCaps(0.055) + .withFloors(0.025) + .inArrears(inArrears) + .withNotionals(vars.faceAmount); Date cmsbondRedemption1 = bondCalendar.adjust(cmsBondMaturityDate1, BusinessDayConvention.Following); - cmsBondLeg1.Add( new SimpleCashFlow(100.0, cmsbondRedemption1)); + cmsBondLeg1.Add(new SimpleCashFlow(100.0, cmsbondRedemption1)); Bond cmsBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - cmsBondMaturityDate1, cmsBondStartDate1, cmsBondLeg1); + cmsBondMaturityDate1, cmsBondStartDate1, cmsBondLeg1); cmsBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer); - vars.swapIndex.addFixing(new Date(18,Month.August,2006), 0.04158); + vars.swapIndex.addFixing(new Date(18, Month.August, 2006), 0.04158); double cmsBondPrice1 = cmsBond1.cleanPrice(); AssetSwap cmsBondAssetSwap1 = new AssetSwap(payFixeddouble, - cmsBond1, cmsBondPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + cmsBond1, cmsBondPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); cmsBondAssetSwap1.setPricingEngine(swapEngine); double cmsBondAssetSwapPrice1 = cmsBondAssetSwap1.fairCleanPrice(); - double error6 = Math.Abs(cmsBondAssetSwapPrice1-cmsBondPrice1); + double error6 = Math.Abs(cmsBondAssetSwapPrice1 - cmsBondPrice1); - if (error6>tolerance) { + if (error6 > tolerance) + { QAssert.Fail("wrong zero spread asset swap price for cms bond:" - + "\n bond's clean price: " + cmsBondPrice1 - + "\n asset swap fair price: " + cmsBondAssetSwapPrice1 - + "\n error: " + error6 - + "\n tolerance: " + tolerance); + + "\n bond's clean price: " + cmsBondPrice1 + + "\n asset swap fair price: " + cmsBondAssetSwapPrice1 + + "\n error: " + error6 + + "\n tolerance: " + tolerance); } // CMS Underlying bond (Isin: XS0218766664 ISPIM 0 5/6/15) // maturity occurs on a business day - Date cmsBondStartDate2 =new Date(06,Month.May,2005); - Date cmsBondMaturityDate2 =new Date(06,Month.May,2015); - Schedule cmsBondSchedule2= new Schedule(cmsBondStartDate2, - cmsBondMaturityDate2, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date cmsBondStartDate2 = new Date(06, Month.May, 2005); + Date cmsBondMaturityDate2 = new Date(06, Month.May, 2015); + Schedule cmsBondSchedule2 = new Schedule(cmsBondStartDate2, + cmsBondMaturityDate2, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List cmsBondLeg2 = new CmsLeg(cmsBondSchedule2, vars.swapIndex) - .withFixingDays(fixingDays) - .withGearings(0.84) - .inArrears(inArrears) - .withPaymentDayCounter(new Thirty360()) - .withNotionals(vars.faceAmount); - Date cmsbondRedemption2 = bondCalendar.adjust(cmsBondMaturityDate2,BusinessDayConvention.Following); + .withFixingDays(fixingDays) + .withGearings(0.84) + .inArrears(inArrears) + .withPaymentDayCounter(new Thirty360()) + .withNotionals(vars.faceAmount); + Date cmsbondRedemption2 = bondCalendar.adjust(cmsBondMaturityDate2, BusinessDayConvention.Following); cmsBondLeg2.Add(new SimpleCashFlow(100.0, cmsbondRedemption2)); Bond cmsBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - cmsBondMaturityDate2, cmsBondStartDate2, cmsBondLeg2); + cmsBondMaturityDate2, cmsBondStartDate2, cmsBondLeg2); cmsBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer); - vars.swapIndex.addFixing(new Date(04,Month.May,2006), 0.04217); + vars.swapIndex.addFixing(new Date(04, Month.May, 2006), 0.04217); double cmsBondPrice2 = cmsBond2.cleanPrice(); - AssetSwap cmsBondAssetSwap2= new AssetSwap(payFixeddouble, - cmsBond2, cmsBondPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap cmsBondAssetSwap2 = new AssetSwap(payFixeddouble, + cmsBond2, cmsBondPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); cmsBondAssetSwap2.setPricingEngine(swapEngine); double cmsBondAssetSwapPrice2 = cmsBondAssetSwap2.fairCleanPrice(); - double error7 = Math.Abs(cmsBondAssetSwapPrice2-cmsBondPrice2); + double error7 = Math.Abs(cmsBondAssetSwapPrice2 - cmsBondPrice2); - if (error7>tolerance) { + if (error7 > tolerance) + { QAssert.Fail("wrong zero spread asset swap price for cms bond:" - + "\n bond's clean price: " + cmsBondPrice2 - + "\n asset swap fair price: " + cmsBondAssetSwapPrice2 - + "\n error: " + error7 - + "\n tolerance: " + tolerance); + + "\n bond's clean price: " + cmsBondPrice2 + + "\n asset swap fair price: " + cmsBondAssetSwapPrice2 + + "\n error: " + error7 + + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15) // maturity doesn't occur on a business day - Date zeroCpnBondStartDate1 =new Date(19,Month.December,1985); - Date zeroCpnBondMaturityDate1 =new Date(20,Month.December,2015); - Date zeroCpnBondRedemption1 = bondCalendar.adjust(zeroCpnBondMaturityDate1,BusinessDayConvention.Following); - ListzeroCpnBondLeg1 = new List{new SimpleCashFlow(100.0, zeroCpnBondRedemption1)}; + Date zeroCpnBondStartDate1 = new Date(19, Month.December, 1985); + Date zeroCpnBondMaturityDate1 = new Date(20, Month.December, 2015); + Date zeroCpnBondRedemption1 = bondCalendar.adjust(zeroCpnBondMaturityDate1, BusinessDayConvention.Following); + ListzeroCpnBondLeg1 = new List {new SimpleCashFlow(100.0, zeroCpnBondRedemption1)}; Bond zeroCpnBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - zeroCpnBondMaturityDate1, zeroCpnBondStartDate1, zeroCpnBondLeg1); + zeroCpnBondMaturityDate1, zeroCpnBondStartDate1, zeroCpnBondLeg1); zeroCpnBond1.setPricingEngine(bondEngine); double zeroCpnBondPrice1 = zeroCpnBond1.cleanPrice(); AssetSwap zeroCpnAssetSwap1 = new AssetSwap(payFixeddouble, - zeroCpnBond1, zeroCpnBondPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + zeroCpnBond1, zeroCpnBondPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); zeroCpnAssetSwap1.setPricingEngine(swapEngine); double zeroCpnBondAssetSwapPrice1 = zeroCpnAssetSwap1.fairCleanPrice(); - double error8 = Math.Abs(zeroCpnBondAssetSwapPrice1-zeroCpnBondPrice1); + double error8 = Math.Abs(zeroCpnBondAssetSwapPrice1 - zeroCpnBondPrice1); - if (error8>tolerance) { + if (error8 > tolerance) + { QAssert.Fail("wrong zero spread asset swap price for zero cpn bond:" - + "\n bond's clean price: " + zeroCpnBondPrice1 - + "\n asset swap fair price: " + zeroCpnBondAssetSwapPrice1 - + "\n error: " + error8 - + "\n tolerance: " + tolerance); + + "\n bond's clean price: " + zeroCpnBondPrice1 + + "\n asset swap fair price: " + zeroCpnBondAssetSwapPrice1 + + "\n error: " + error8 + + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28) // maturity occurs on a business day - Date zeroCpnBondStartDate2 =new Date(17,Month.February,1998); - Date zeroCpnBondMaturityDate2 =new Date(17,Month.February,2028); - Date zerocpbondRedemption2 = bondCalendar.adjust(zeroCpnBondMaturityDate2,BusinessDayConvention.Following); - ListzeroCpnBondLeg2 = new List{new SimpleCashFlow(100.0, zerocpbondRedemption2)}; + Date zeroCpnBondStartDate2 = new Date(17, Month.February, 1998); + Date zeroCpnBondMaturityDate2 = new Date(17, Month.February, 2028); + Date zerocpbondRedemption2 = bondCalendar.adjust(zeroCpnBondMaturityDate2, BusinessDayConvention.Following); + ListzeroCpnBondLeg2 = new List {new SimpleCashFlow(100.0, zerocpbondRedemption2)}; Bond zeroCpnBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - zeroCpnBondMaturityDate2, zeroCpnBondStartDate2, zeroCpnBondLeg2); + zeroCpnBondMaturityDate2, zeroCpnBondStartDate2, zeroCpnBondLeg2); zeroCpnBond2.setPricingEngine(bondEngine); double zeroCpnBondPrice2 = zeroCpnBond2.cleanPrice(); - AssetSwap zeroCpnAssetSwap2= new AssetSwap(payFixeddouble, - zeroCpnBond2, zeroCpnBondPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap zeroCpnAssetSwap2 = new AssetSwap(payFixeddouble, + zeroCpnBond2, zeroCpnBondPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); zeroCpnAssetSwap2.setPricingEngine(swapEngine); double zeroCpnBondAssetSwapPrice2 = zeroCpnAssetSwap2.fairCleanPrice(); - double error9 = Math.Abs(cmsBondAssetSwapPrice2-cmsBondPrice2); + double error9 = Math.Abs(cmsBondAssetSwapPrice2 - cmsBondPrice2); - if (error9>tolerance) { + if (error9 > tolerance) + { QAssert.Fail("wrong zero spread asset swap price for zero cpn bond:" - + "\n bond's clean price: " + zeroCpnBondPrice2 - + "\n asset swap fair price: " + zeroCpnBondAssetSwapPrice2 - + "\n error: " + error9 - + "\n tolerance: " + tolerance); + + "\n bond's clean price: " + zeroCpnBondPrice2 + + "\n asset swap fair price: " + zeroCpnBondAssetSwapPrice2 + + "\n error: " + error9 + + "\n tolerance: " + tolerance); } - } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testMASWWithGenericBond() + public void testMASWWithGenericBond() { // Testing market asset swap against par asset swap with generic bond... @@ -1763,418 +1797,418 @@ public void testMASWWithGenericBond() // Fixed Underlying bond (Isin: DE0001135275 DBR 4 01/04/37) // maturity doesn't occur on a business day - Date fixedBondStartDate1 = new Date(4,Month.January,2005); - Date fixedBondMaturityDate1 = new Date(4,Month.January,2037); + Date fixedBondStartDate1 = new Date(4, Month.January, 2005); + Date fixedBondMaturityDate1 = new Date(4, Month.January, 2037); Schedule fixedBondSchedule1 = new Schedule(fixedBondStartDate1, - fixedBondMaturityDate1, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + fixedBondMaturityDate1, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List fixedBondLeg1 = new FixedRateLeg(fixedBondSchedule1) - .withCouponRates(0.04, new ActualActual(ActualActual.Convention.ISDA)) - .withNotionals(vars.faceAmount); + .withCouponRates(0.04, new ActualActual(ActualActual.Convention.ISDA)) + .withNotionals(vars.faceAmount); Date fixedbondRedemption1 = bondCalendar.adjust(fixedBondMaturityDate1, BusinessDayConvention.Following); fixedBondLeg1.Add(new SimpleCashFlow(100.0, fixedbondRedemption1)); - Bond fixedBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, fixedBondMaturityDate1, - fixedBondStartDate1, fixedBondLeg1); + Bond fixedBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, fixedBondMaturityDate1, + fixedBondStartDate1, fixedBondLeg1); IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure); IPricingEngine swapEngine = new DiscountingSwapEngine(vars.termStructure); fixedBond1.setPricingEngine(bondEngine); double fixedBondMktPrice1 = 89.22 ; // market price observed on 7th June 2007 - double fixedBondMktFullPrice1=fixedBondMktPrice1+fixedBond1.accruedAmount(); - AssetSwap fixedBondParAssetSwap1= new AssetSwap(payFixedRate, - fixedBond1, fixedBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + double fixedBondMktFullPrice1 = fixedBondMktPrice1 + fixedBond1.accruedAmount(); + AssetSwap fixedBondParAssetSwap1 = new AssetSwap(payFixedRate, + fixedBond1, fixedBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); fixedBondParAssetSwap1.setPricingEngine(swapEngine); double fixedBondParAssetSwapSpread1 = fixedBondParAssetSwap1.fairSpread(); AssetSwap fixedBondMktAssetSwap1 = new AssetSwap(payFixedRate, - fixedBond1, fixedBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - mktAssetSwap); + fixedBond1, fixedBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + mktAssetSwap); fixedBondMktAssetSwap1.setPricingEngine(swapEngine); double fixedBondMktAssetSwapSpread1 = fixedBondMktAssetSwap1.fairSpread(); double tolerance = 1.0e-13; double error1 = - Math.Abs(fixedBondMktAssetSwapSpread1- - 100*fixedBondParAssetSwapSpread1/fixedBondMktFullPrice1); + Math.Abs(fixedBondMktAssetSwapSpread1 - + 100 * fixedBondParAssetSwapSpread1 / fixedBondMktFullPrice1); - if (error1>tolerance) + if (error1 > tolerance) QAssert.Fail("wrong asset swap spreads for fixed bond:" + - "\n market asset swap spread: " + fixedBondMktAssetSwapSpread1 + - "\n par asset swap spread: " + fixedBondParAssetSwapSpread1 + - "\n error: " + error1 + - "\n tolerance: " + tolerance); + "\n market asset swap spread: " + fixedBondMktAssetSwapSpread1 + + "\n par asset swap spread: " + fixedBondParAssetSwapSpread1 + + "\n error: " + error1 + + "\n tolerance: " + tolerance); // Fixed Underlying bond (Isin: IT0006527060 IBRD 5 02/05/19) // maturity occurs on a business day - Date fixedBondStartDate2 = new Date(5,Month.February,2005); - Date fixedBondMaturityDate2 = new Date(5,Month.February,2019); + Date fixedBondStartDate2 = new Date(5, Month.February, 2005); + Date fixedBondMaturityDate2 = new Date(5, Month.February, 2019); Schedule fixedBondSchedule2 = new Schedule(fixedBondStartDate2, - fixedBondMaturityDate2, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + fixedBondMaturityDate2, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List fixedBondLeg2 = new FixedRateLeg(fixedBondSchedule2) - .withCouponRates(0.05, new Thirty360(Thirty360.Thirty360Convention.BondBasis)) - .withNotionals(vars.faceAmount); + .withCouponRates(0.05, new Thirty360(Thirty360.Thirty360Convention.BondBasis)) + .withNotionals(vars.faceAmount); Date fixedbondRedemption2 = bondCalendar.adjust(fixedBondMaturityDate2, BusinessDayConvention.Following); fixedBondLeg2.Add(new SimpleCashFlow(100.0, fixedbondRedemption2)); - Bond fixedBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, fixedBondMaturityDate2, fixedBondStartDate2, - fixedBondLeg2); + Bond fixedBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, fixedBondMaturityDate2, fixedBondStartDate2, + fixedBondLeg2); fixedBond2.setPricingEngine(bondEngine); double fixedBondMktPrice2 = 99.98 ; // market price observed on 7th June 2007 - double fixedBondMktFullPrice2=fixedBondMktPrice2+fixedBond2.accruedAmount(); - AssetSwap fixedBondParAssetSwap2= new AssetSwap(payFixedRate, - fixedBond2, fixedBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + double fixedBondMktFullPrice2 = fixedBondMktPrice2 + fixedBond2.accruedAmount(); + AssetSwap fixedBondParAssetSwap2 = new AssetSwap(payFixedRate, + fixedBond2, fixedBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); fixedBondParAssetSwap2.setPricingEngine(swapEngine); double fixedBondParAssetSwapSpread2 = fixedBondParAssetSwap2.fairSpread(); - AssetSwap fixedBondMktAssetSwap2= new AssetSwap(payFixedRate, - fixedBond2, fixedBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - mktAssetSwap); + AssetSwap fixedBondMktAssetSwap2 = new AssetSwap(payFixedRate, + fixedBond2, fixedBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + mktAssetSwap); fixedBondMktAssetSwap2.setPricingEngine(swapEngine); double fixedBondMktAssetSwapSpread2 = fixedBondMktAssetSwap2.fairSpread(); - double error2 = Math.Abs(fixedBondMktAssetSwapSpread2- - 100*fixedBondParAssetSwapSpread2/fixedBondMktFullPrice2); + double error2 = Math.Abs(fixedBondMktAssetSwapSpread2 - + 100 * fixedBondParAssetSwapSpread2 / fixedBondMktFullPrice2); - if (error2>tolerance) + if (error2 > tolerance) QAssert.Fail("wrong asset swap spreads for fixed bond:" + - "\n market asset swap spread: " + fixedBondMktAssetSwapSpread2 + - "\n par asset swap spread: " + fixedBondParAssetSwapSpread2 + - "\n error: " + error2 + - "\n tolerance: " + tolerance); + "\n market asset swap spread: " + fixedBondMktAssetSwapSpread2 + + "\n par asset swap spread: " + fixedBondParAssetSwapSpread2 + + "\n error: " + error2 + + "\n tolerance: " + tolerance); // FRN Underlying bond (Isin: IT0003543847 ISPIM 0 09/29/13) // maturity doesn't occur on a business day - Date floatingBondStartDate1 = new Date(29,Month.September,2003); - Date floatingBondMaturityDate1 = new Date(29,Month.September,2013); - Schedule floatingBondSchedule1= new Schedule(floatingBondStartDate1, - floatingBondMaturityDate1, - new Period(Frequency.Semiannual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date floatingBondStartDate1 = new Date(29, Month.September, 2003); + Date floatingBondMaturityDate1 = new Date(29, Month.September, 2013); + Schedule floatingBondSchedule1 = new Schedule(floatingBondStartDate1, + floatingBondMaturityDate1, + new Period(Frequency.Semiannual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List floatingBondLeg1 = new IborLeg(floatingBondSchedule1, vars.iborIndex) - .withPaymentDayCounter(new Actual360()) - .withFixingDays(fixingDays) - .withSpreads(0.0056) - .inArrears(inArrears) - .withNotionals(vars.faceAmount); + .withPaymentDayCounter(new Actual360()) + .withFixingDays(fixingDays) + .withSpreads(0.0056) + .inArrears(inArrears) + .withNotionals(vars.faceAmount); Date floatingbondRedemption1 = bondCalendar.adjust(floatingBondMaturityDate1, BusinessDayConvention.Following); floatingBondLeg1.Add(new SimpleCashFlow(100.0, floatingbondRedemption1)); - Bond floatingBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, floatingBondMaturityDate1, - floatingBondStartDate1, floatingBondLeg1); + Bond floatingBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, floatingBondMaturityDate1, + floatingBondStartDate1, floatingBondLeg1); floatingBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer); - vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402); + vars.iborIndex.addFixing(new Date(27, Month.March, 2007), 0.0402); // market price observed on 7th June 2007 double floatingBondMktPrice1 = 101.64 ; double floatingBondMktFullPrice1 = - floatingBondMktPrice1+floatingBond1.accruedAmount(); + floatingBondMktPrice1 + floatingBond1.accruedAmount(); AssetSwap floatingBondParAssetSwap1 = new AssetSwap(payFixedRate, - floatingBond1, floatingBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + floatingBond1, floatingBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); floatingBondParAssetSwap1.setPricingEngine(swapEngine); double floatingBondParAssetSwapSpread1 = floatingBondParAssetSwap1.fairSpread(); AssetSwap floatingBondMktAssetSwap1 = new AssetSwap(payFixedRate, - floatingBond1, floatingBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - mktAssetSwap); + floatingBond1, floatingBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + mktAssetSwap); floatingBondMktAssetSwap1.setPricingEngine(swapEngine); double floatingBondMktAssetSwapSpread1 = floatingBondMktAssetSwap1.fairSpread(); - double error3 = Math.Abs(floatingBondMktAssetSwapSpread1- - 100*floatingBondParAssetSwapSpread1/floatingBondMktFullPrice1); + double error3 = Math.Abs(floatingBondMktAssetSwapSpread1 - + 100 * floatingBondParAssetSwapSpread1 / floatingBondMktFullPrice1); - if (error3>tolerance) + if (error3 > tolerance) QAssert.Fail("wrong asset swap spreads for floating bond:" + - "\n market asset swap spread: " + floatingBondMktAssetSwapSpread1 + - "\n par asset swap spread: " + floatingBondParAssetSwapSpread1 + - "\n error: " + error3 + - "\n tolerance: " + tolerance); + "\n market asset swap spread: " + floatingBondMktAssetSwapSpread1 + + "\n par asset swap spread: " + floatingBondParAssetSwapSpread1 + + "\n error: " + error3 + + "\n tolerance: " + tolerance); // FRN Underlying bond (Isin: XS0090566539 COE 0 09/24/18) // maturity occurs on a business day - Date floatingBondStartDate2 = new Date(24,Month.September,2004); - Date floatingBondMaturityDate2 = new Date(24,Month.September,2018); + Date floatingBondStartDate2 = new Date(24, Month.September, 2004); + Date floatingBondMaturityDate2 = new Date(24, Month.September, 2018); Schedule floatingBondSchedule2 = new Schedule(floatingBondStartDate2, - floatingBondMaturityDate2, - new Period(Frequency.Semiannual), bondCalendar, - BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, - DateGeneration.Rule.Backward, false); + floatingBondMaturityDate2, + new Period(Frequency.Semiannual), bondCalendar, + BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, + DateGeneration.Rule.Backward, false); List floatingBondLeg2 = new IborLeg(floatingBondSchedule2, vars.iborIndex) - .withFixingDays(fixingDays) - .withSpreads(0.0025) - .inArrears(inArrears) - .withPaymentDayCounter(new Actual360()) - .withPaymentAdjustment(BusinessDayConvention.ModifiedFollowing) - .withNotionals(vars.faceAmount); + .withFixingDays(fixingDays) + .withSpreads(0.0025) + .inArrears(inArrears) + .withPaymentDayCounter(new Actual360()) + .withPaymentAdjustment(BusinessDayConvention.ModifiedFollowing) + .withNotionals(vars.faceAmount); Date floatingbondRedemption2 = bondCalendar.adjust(floatingBondMaturityDate2, BusinessDayConvention.ModifiedFollowing); floatingBondLeg2.Add(new - SimpleCashFlow(100.0, floatingbondRedemption2)); - Bond floatingBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, floatingBondMaturityDate2, - floatingBondStartDate2, floatingBondLeg2); + SimpleCashFlow(100.0, floatingbondRedemption2)); + Bond floatingBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, floatingBondMaturityDate2, + floatingBondStartDate2, floatingBondLeg2); floatingBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer); - vars.iborIndex.addFixing(new Date(22,Month.March,2007), 0.04013); + vars.iborIndex.addFixing(new Date(22, Month.March, 2007), 0.04013); // market price observed on 7th June 2007 double floatingBondMktPrice2 = 101.248 ; double floatingBondMktFullPrice2 = - floatingBondMktPrice2+floatingBond2.accruedAmount(); + floatingBondMktPrice2 + floatingBond2.accruedAmount(); AssetSwap floatingBondParAssetSwap2 = new AssetSwap(payFixedRate, - floatingBond2, floatingBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + floatingBond2, floatingBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); floatingBondParAssetSwap2.setPricingEngine(swapEngine); double floatingBondParAssetSwapSpread2 = floatingBondParAssetSwap2.fairSpread(); AssetSwap floatingBondMktAssetSwap2 = new AssetSwap(payFixedRate, - floatingBond2, floatingBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - mktAssetSwap); + floatingBond2, floatingBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + mktAssetSwap); floatingBondMktAssetSwap2.setPricingEngine(swapEngine); double floatingBondMktAssetSwapSpread2 = floatingBondMktAssetSwap2.fairSpread(); - double error4 = Math.Abs(floatingBondMktAssetSwapSpread2- - 100*floatingBondParAssetSwapSpread2/floatingBondMktFullPrice2); + double error4 = Math.Abs(floatingBondMktAssetSwapSpread2 - + 100 * floatingBondParAssetSwapSpread2 / floatingBondMktFullPrice2); - if (error4>tolerance) + if (error4 > tolerance) QAssert.Fail("wrong asset swap spreads for floating bond:" + - "\n market asset swap spread: " + floatingBondMktAssetSwapSpread2 + - "\n par asset swap spread: " + floatingBondParAssetSwapSpread2 + - "\n error: " + error4 + - "\n tolerance: " + tolerance); + "\n market asset swap spread: " + floatingBondMktAssetSwapSpread2 + + "\n par asset swap spread: " + floatingBondParAssetSwapSpread2 + + "\n error: " + error4 + + "\n tolerance: " + tolerance); // CMS Underlying bond (Isin: XS0228052402 CRDIT 0 8/22/20) // maturity doesn't occur on a business day - Date cmsBondStartDate1 = new Date(22,Month.August,2005); - Date cmsBondMaturityDate1 = new Date(22,Month.August,2020); - Schedule cmsBondSchedule1= new Schedule(cmsBondStartDate1, - cmsBondMaturityDate1, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date cmsBondStartDate1 = new Date(22, Month.August, 2005); + Date cmsBondMaturityDate1 = new Date(22, Month.August, 2020); + Schedule cmsBondSchedule1 = new Schedule(cmsBondStartDate1, + cmsBondMaturityDate1, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List cmsBondLeg1 = new CmsLeg(cmsBondSchedule1, vars.swapIndex) - .withPaymentDayCounter(new Thirty360()) - .withFixingDays(fixingDays) - .withCaps(0.055) - .withFloors(0.025) - .inArrears(inArrears) - .withNotionals(vars.faceAmount); + .withPaymentDayCounter(new Thirty360()) + .withFixingDays(fixingDays) + .withCaps(0.055) + .withFloors(0.025) + .inArrears(inArrears) + .withNotionals(vars.faceAmount); Date cmsbondRedemption1 = bondCalendar.adjust(cmsBondMaturityDate1, BusinessDayConvention.Following); cmsBondLeg1.Add(new SimpleCashFlow(100.0, cmsbondRedemption1)); - Bond cmsBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, cmsBondMaturityDate1, cmsBondStartDate1, - cmsBondLeg1); + Bond cmsBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, cmsBondMaturityDate1, cmsBondStartDate1, + cmsBondLeg1); cmsBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer); - vars.swapIndex.addFixing(new Date(18,Month.August,2006), 0.04158); + vars.swapIndex.addFixing(new Date(18, Month.August, 2006), 0.04158); double cmsBondMktPrice1 = 88.45 ; // market price observed on 7th June 2007 - double cmsBondMktFullPrice1 = cmsBondMktPrice1+cmsBond1.accruedAmount(); + double cmsBondMktFullPrice1 = cmsBondMktPrice1 + cmsBond1.accruedAmount(); AssetSwap cmsBondParAssetSwap1 = new AssetSwap(payFixedRate, - cmsBond1, cmsBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + cmsBond1, cmsBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); cmsBondParAssetSwap1.setPricingEngine(swapEngine); double cmsBondParAssetSwapSpread1 = cmsBondParAssetSwap1.fairSpread(); AssetSwap cmsBondMktAssetSwap1 = new AssetSwap(payFixedRate, - cmsBond1, cmsBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - mktAssetSwap); + cmsBond1, cmsBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + mktAssetSwap); cmsBondMktAssetSwap1.setPricingEngine(swapEngine); double cmsBondMktAssetSwapSpread1 = cmsBondMktAssetSwap1.fairSpread(); double error5 = - Math.Abs(cmsBondMktAssetSwapSpread1- - 100*cmsBondParAssetSwapSpread1/cmsBondMktFullPrice1); + Math.Abs(cmsBondMktAssetSwapSpread1 - + 100 * cmsBondParAssetSwapSpread1 / cmsBondMktFullPrice1); - if (error5>tolerance) + if (error5 > tolerance) QAssert.Fail("wrong asset swap spreads for cms bond:" + - "\n market asset swap spread: " + cmsBondMktAssetSwapSpread1 + - "\n par asset swap spread: " + cmsBondParAssetSwapSpread1 + - "\n error: " + error5 + - "\n tolerance: " + tolerance); + "\n market asset swap spread: " + cmsBondMktAssetSwapSpread1 + + "\n par asset swap spread: " + cmsBondParAssetSwapSpread1 + + "\n error: " + error5 + + "\n tolerance: " + tolerance); // CMS Underlying bond (Isin: XS0218766664 ISPIM 0 5/6/15) // maturity occurs on a business day - Date cmsBondStartDate2 = new Date(06,Month.May,2005); - Date cmsBondMaturityDate2 = new Date(06,Month.May,2015); - Schedule cmsBondSchedule2= new Schedule(cmsBondStartDate2, - cmsBondMaturityDate2, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date cmsBondStartDate2 = new Date(06, Month.May, 2005); + Date cmsBondMaturityDate2 = new Date(06, Month.May, 2015); + Schedule cmsBondSchedule2 = new Schedule(cmsBondStartDate2, + cmsBondMaturityDate2, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List cmsBondLeg2 = new CmsLeg(cmsBondSchedule2, vars.swapIndex) - .withPaymentDayCounter(new Thirty360()) - .withFixingDays(fixingDays) - .withGearings(0.84) - .inArrears(inArrears) - .withNotionals(vars.faceAmount); + .withPaymentDayCounter(new Thirty360()) + .withFixingDays(fixingDays) + .withGearings(0.84) + .inArrears(inArrears) + .withNotionals(vars.faceAmount); Date cmsbondRedemption2 = bondCalendar.adjust(cmsBondMaturityDate2, BusinessDayConvention.Following); cmsBondLeg2.Add(new SimpleCashFlow(100.0, cmsbondRedemption2)); - Bond cmsBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, cmsBondMaturityDate2, cmsBondStartDate2, - cmsBondLeg2); + Bond cmsBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, cmsBondMaturityDate2, cmsBondStartDate2, + cmsBondLeg2); cmsBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer); - vars.swapIndex.addFixing(new Date(04,Month.May,2006), 0.04217); + vars.swapIndex.addFixing(new Date(04, Month.May, 2006), 0.04217); double cmsBondMktPrice2 = 94.08 ; // market price observed on 7th June 2007 - double cmsBondMktFullPrice2 = cmsBondMktPrice2+cmsBond2.accruedAmount(); + double cmsBondMktFullPrice2 = cmsBondMktPrice2 + cmsBond2.accruedAmount(); AssetSwap cmsBondParAssetSwap2 = new AssetSwap(payFixedRate, - cmsBond2, cmsBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + cmsBond2, cmsBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); cmsBondParAssetSwap2.setPricingEngine(swapEngine); double cmsBondParAssetSwapSpread2 = cmsBondParAssetSwap2.fairSpread(); AssetSwap cmsBondMktAssetSwap2 = new AssetSwap(payFixedRate, - cmsBond2, cmsBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - mktAssetSwap); + cmsBond2, cmsBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + mktAssetSwap); cmsBondMktAssetSwap2.setPricingEngine(swapEngine); double cmsBondMktAssetSwapSpread2 = cmsBondMktAssetSwap2.fairSpread(); double error6 = - Math.Abs(cmsBondMktAssetSwapSpread2- - 100*cmsBondParAssetSwapSpread2/cmsBondMktFullPrice2); + Math.Abs(cmsBondMktAssetSwapSpread2 - + 100 * cmsBondParAssetSwapSpread2 / cmsBondMktFullPrice2); - if (error6>tolerance) + if (error6 > tolerance) QAssert.Fail("wrong asset swap spreads for cms bond:" + - "\n market asset swap spread: " + cmsBondMktAssetSwapSpread2 + - "\n par asset swap spread: " + cmsBondParAssetSwapSpread2 + - "\n error: " + error6 + - "\n tolerance: " + tolerance); + "\n market asset swap spread: " + cmsBondMktAssetSwapSpread2 + + "\n par asset swap spread: " + cmsBondParAssetSwapSpread2 + + "\n error: " + error6 + + "\n tolerance: " + tolerance); // Zero Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15) // maturity doesn't occur on a business day - Date zeroCpnBondStartDate1 = new Date(19,Month.December,1985); - Date zeroCpnBondMaturityDate1 = new Date(20,Month.December,2015); + Date zeroCpnBondStartDate1 = new Date(19, Month.December, 1985); + Date zeroCpnBondMaturityDate1 = new Date(20, Month.December, 2015); Date zeroCpnBondRedemption1 = bondCalendar.adjust(zeroCpnBondMaturityDate1, - BusinessDayConvention.Following); - List zeroCpnBondLeg1 = new List{new SimpleCashFlow(100.0, zeroCpnBondRedemption1)}; - Bond zeroCpnBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, zeroCpnBondMaturityDate1, - zeroCpnBondStartDate1, zeroCpnBondLeg1); + BusinessDayConvention.Following); + List zeroCpnBondLeg1 = new List {new SimpleCashFlow(100.0, zeroCpnBondRedemption1)}; + Bond zeroCpnBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, zeroCpnBondMaturityDate1, + zeroCpnBondStartDate1, zeroCpnBondLeg1); zeroCpnBond1.setPricingEngine(bondEngine); // market price observed on 12th June 2007 double zeroCpnBondMktPrice1 = 70.436 ; double zeroCpnBondMktFullPrice1 = - zeroCpnBondMktPrice1+zeroCpnBond1.accruedAmount(); - AssetSwap zeroCpnBondParAssetSwap1 = new AssetSwap(payFixedRate,zeroCpnBond1, - zeroCpnBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + zeroCpnBondMktPrice1 + zeroCpnBond1.accruedAmount(); + AssetSwap zeroCpnBondParAssetSwap1 = new AssetSwap(payFixedRate, zeroCpnBond1, + zeroCpnBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); zeroCpnBondParAssetSwap1.setPricingEngine(swapEngine); double zeroCpnBondParAssetSwapSpread1 = zeroCpnBondParAssetSwap1.fairSpread(); - AssetSwap zeroCpnBondMktAssetSwap1 = new AssetSwap(payFixedRate,zeroCpnBond1, - zeroCpnBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - mktAssetSwap); + AssetSwap zeroCpnBondMktAssetSwap1 = new AssetSwap(payFixedRate, zeroCpnBond1, + zeroCpnBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + mktAssetSwap); zeroCpnBondMktAssetSwap1.setPricingEngine(swapEngine); double zeroCpnBondMktAssetSwapSpread1 = zeroCpnBondMktAssetSwap1.fairSpread(); double error7 = - Math.Abs(zeroCpnBondMktAssetSwapSpread1- - 100*zeroCpnBondParAssetSwapSpread1/zeroCpnBondMktFullPrice1); + Math.Abs(zeroCpnBondMktAssetSwapSpread1 - + 100 * zeroCpnBondParAssetSwapSpread1 / zeroCpnBondMktFullPrice1); - if (error7>tolerance) + if (error7 > tolerance) QAssert.Fail("wrong asset swap spreads for zero cpn bond:" + - "\n market asset swap spread: " + zeroCpnBondMktAssetSwapSpread1 + - "\n par asset swap spread: " + zeroCpnBondParAssetSwapSpread1 + - "\n error: " + error7 + - "\n tolerance: " + tolerance); + "\n market asset swap spread: " + zeroCpnBondMktAssetSwapSpread1 + + "\n par asset swap spread: " + zeroCpnBondParAssetSwapSpread1 + + "\n error: " + error7 + + "\n tolerance: " + tolerance); // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28) // maturity occurs on a business day - Date zeroCpnBondStartDate2 = new Date(17,Month.February,1998); - Date zeroCpnBondMaturityDate2 = new Date(17,Month.February,2028); + Date zeroCpnBondStartDate2 = new Date(17, Month.February, 1998); + Date zeroCpnBondMaturityDate2 = new Date(17, Month.February, 2028); Date zerocpbondRedemption2 = bondCalendar.adjust(zeroCpnBondMaturityDate2, - BusinessDayConvention.Following); - List zeroCpnBondLeg2 = new List{new SimpleCashFlow(100.0, zerocpbondRedemption2)}; + BusinessDayConvention.Following); + List zeroCpnBondLeg2 = new List {new SimpleCashFlow(100.0, zerocpbondRedemption2)}; Bond zeroCpnBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - zeroCpnBondMaturityDate2, zeroCpnBondStartDate2, zeroCpnBondLeg2); + zeroCpnBondMaturityDate2, zeroCpnBondStartDate2, zeroCpnBondLeg2); zeroCpnBond2.setPricingEngine(bondEngine); // double zeroCpnBondPrice2 = zeroCpnBond2.cleanPrice(); // market price observed on 12th June 2007 double zeroCpnBondMktPrice2 = 35.160 ; double zeroCpnBondMktFullPrice2 = - zeroCpnBondMktPrice2+zeroCpnBond2.accruedAmount(); - AssetSwap zeroCpnBondParAssetSwap2 = new AssetSwap(payFixedRate,zeroCpnBond2, - zeroCpnBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + zeroCpnBondMktPrice2 + zeroCpnBond2.accruedAmount(); + AssetSwap zeroCpnBondParAssetSwap2 = new AssetSwap(payFixedRate, zeroCpnBond2, + zeroCpnBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); zeroCpnBondParAssetSwap2.setPricingEngine(swapEngine); double zeroCpnBondParAssetSwapSpread2 = zeroCpnBondParAssetSwap2.fairSpread(); - AssetSwap zeroCpnBondMktAssetSwap2 = new AssetSwap(payFixedRate,zeroCpnBond2, - zeroCpnBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - mktAssetSwap); + AssetSwap zeroCpnBondMktAssetSwap2 = new AssetSwap(payFixedRate, zeroCpnBond2, + zeroCpnBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + mktAssetSwap); zeroCpnBondMktAssetSwap2.setPricingEngine(swapEngine); double zeroCpnBondMktAssetSwapSpread2 = zeroCpnBondMktAssetSwap2.fairSpread(); double error8 = - Math.Abs(zeroCpnBondMktAssetSwapSpread2- - 100*zeroCpnBondParAssetSwapSpread2/zeroCpnBondMktFullPrice2); + Math.Abs(zeroCpnBondMktAssetSwapSpread2 - + 100 * zeroCpnBondParAssetSwapSpread2 / zeroCpnBondMktFullPrice2); - if (error8>tolerance) + if (error8 > tolerance) QAssert.Fail("wrong asset swap spreads for zero cpn bond:" + - "\n market asset swap spread: " + zeroCpnBondMktAssetSwapSpread2 + - "\n par asset swap spread: " + zeroCpnBondParAssetSwapSpread2 + - "\n error: " + error8 + - "\n tolerance: " + tolerance); - } + "\n market asset swap spread: " + zeroCpnBondMktAssetSwapSpread2 + + "\n par asset swap spread: " + zeroCpnBondParAssetSwapSpread2 + + "\n error: " + error8 + + "\n tolerance: " + tolerance); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testZSpreadWithGenericBond() + public void testZSpreadWithGenericBond() { // Testing clean and dirty price with null Z-spread against theoretical prices... @@ -2188,312 +2222,320 @@ public void testZSpreadWithGenericBond() // Fixed Underlying bond (Isin: DE0001135275 DBR 4 01/04/37) // maturity doesn't occur on a business day - Date fixedBondStartDate1 = new Date(4,Month.January,2005); - Date fixedBondMaturityDate1 = new Date(4,Month.January,2037); - Schedule fixedBondSchedule1= new Schedule(fixedBondStartDate1, - fixedBondMaturityDate1, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date fixedBondStartDate1 = new Date(4, Month.January, 2005); + Date fixedBondMaturityDate1 = new Date(4, Month.January, 2037); + Schedule fixedBondSchedule1 = new Schedule(fixedBondStartDate1, + fixedBondMaturityDate1, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List fixedBondLeg1 = new FixedRateLeg(fixedBondSchedule1) - .withCouponRates(0.04, new ActualActual(ActualActual.Convention.ISDA)) - .withNotionals(vars.faceAmount); + .withCouponRates(0.04, new ActualActual(ActualActual.Convention.ISDA)) + .withNotionals(vars.faceAmount); Date fixedbondRedemption1 = bondCalendar.adjust(fixedBondMaturityDate1, BusinessDayConvention.Following); fixedBondLeg1.Add(new SimpleCashFlow(100.0, fixedbondRedemption1)); Bond fixedBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, fixedBondMaturityDate1, fixedBondStartDate1, - fixedBondLeg1); + fixedBondLeg1); IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure); fixedBond1.setPricingEngine(bondEngine); double fixedBondImpliedValue1 = fixedBond1.cleanPrice(); - Date fixedBondSettlementDate1= fixedBond1.settlementDate(); + Date fixedBondSettlementDate1 = fixedBond1.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double fixedBondCleanPrice1 = BondFunctions.cleanPrice(fixedBond1, vars.termStructure, vars.spread, - new Actual365Fixed(), vars.compounding, Frequency.Annual, fixedBondSettlementDate1); + new Actual365Fixed(), vars.compounding, Frequency.Annual, fixedBondSettlementDate1); double tolerance = 1.0e-13; - double error1 = Math.Abs(fixedBondImpliedValue1-fixedBondCleanPrice1); - if (error1>tolerance) { + double error1 = Math.Abs(fixedBondImpliedValue1 - fixedBondCleanPrice1); + if (error1 > tolerance) + { QAssert.Fail("wrong clean price for fixed bond:" - + "\n market asset swap spread: " - + fixedBondImpliedValue1 - + "\n par asset swap spread: " + fixedBondCleanPrice1 - + "\n error: " + error1 - + "\n tolerance: " + tolerance); + + "\n market asset swap spread: " + + fixedBondImpliedValue1 + + "\n par asset swap spread: " + fixedBondCleanPrice1 + + "\n error: " + error1 + + "\n tolerance: " + tolerance); } // Fixed Underlying bond (Isin: IT0006527060 IBRD 5 02/05/19) // maturity occurs on a business day - Date fixedBondStartDate2 = new Date(5,Month.February,2005); - Date fixedBondMaturityDate2 = new Date(5,Month.February,2019); - Schedule fixedBondSchedule2= new Schedule(fixedBondStartDate2, - fixedBondMaturityDate2, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date fixedBondStartDate2 = new Date(5, Month.February, 2005); + Date fixedBondMaturityDate2 = new Date(5, Month.February, 2019); + Schedule fixedBondSchedule2 = new Schedule(fixedBondStartDate2, + fixedBondMaturityDate2, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List fixedBondLeg2 = new FixedRateLeg(fixedBondSchedule2) - .withCouponRates(0.05, new Thirty360(Thirty360.Thirty360Convention.BondBasis)) - .withNotionals(vars.faceAmount); + .withCouponRates(0.05, new Thirty360(Thirty360.Thirty360Convention.BondBasis)) + .withNotionals(vars.faceAmount); Date fixedbondRedemption2 = bondCalendar.adjust(fixedBondMaturityDate2, BusinessDayConvention.Following); fixedBondLeg2.Add(new SimpleCashFlow(100.0, fixedbondRedemption2)); Bond fixedBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - fixedBondMaturityDate2, fixedBondStartDate2, fixedBondLeg2); + fixedBondMaturityDate2, fixedBondStartDate2, fixedBondLeg2); fixedBond2.setPricingEngine(bondEngine); double fixedBondImpliedValue2 = fixedBond2.cleanPrice(); - Date fixedBondSettlementDate2= fixedBond2.settlementDate(); + Date fixedBondSettlementDate2 = fixedBond2.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double fixedBondCleanPrice2 = BondFunctions.cleanPrice(fixedBond2, vars.termStructure, vars.spread, - new Actual365Fixed(), vars.compounding, Frequency.Annual, fixedBondSettlementDate2); - double error3 = Math.Abs(fixedBondImpliedValue2-fixedBondCleanPrice2); - if (error3>tolerance) { + new Actual365Fixed(), vars.compounding, Frequency.Annual, fixedBondSettlementDate2); + double error3 = Math.Abs(fixedBondImpliedValue2 - fixedBondCleanPrice2); + if (error3 > tolerance) + { QAssert.Fail("wrong clean price for fixed bond:" - + "\n market asset swap spread: " - + fixedBondImpliedValue2 - + "\n par asset swap spread: " + fixedBondCleanPrice2 - + "\n error: " + error3 - + "\n tolerance: " + tolerance); + + "\n market asset swap spread: " + + fixedBondImpliedValue2 + + "\n par asset swap spread: " + fixedBondCleanPrice2 + + "\n error: " + error3 + + "\n tolerance: " + tolerance); } // FRN Underlying bond (Isin: IT0003543847 ISPIM 0 09/29/13) // maturity doesn't occur on a business day - Date floatingBondStartDate1 = new Date(29,Month.September,2003); - Date floatingBondMaturityDate1 = new Date(29,Month.September,2013); - Schedule floatingBondSchedule1= new Schedule(floatingBondStartDate1, - floatingBondMaturityDate1, - new Period(Frequency.Semiannual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date floatingBondStartDate1 = new Date(29, Month.September, 2003); + Date floatingBondMaturityDate1 = new Date(29, Month.September, 2013); + Schedule floatingBondSchedule1 = new Schedule(floatingBondStartDate1, + floatingBondMaturityDate1, + new Period(Frequency.Semiannual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List floatingBondLeg1 = new IborLeg(floatingBondSchedule1, vars.iborIndex) - .withPaymentDayCounter(new Actual360()) - .withFixingDays(fixingDays) - .withSpreads(0.0056) - .inArrears(inArrears) - .withNotionals(vars.faceAmount); + .withPaymentDayCounter(new Actual360()) + .withFixingDays(fixingDays) + .withSpreads(0.0056) + .inArrears(inArrears) + .withNotionals(vars.faceAmount); Date floatingbondRedemption1 = bondCalendar.adjust(floatingBondMaturityDate1, BusinessDayConvention.Following); floatingBondLeg1.Add(new SimpleCashFlow(100.0, floatingbondRedemption1)); Bond floatingBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - floatingBondMaturityDate1, floatingBondStartDate1, - floatingBondLeg1); + floatingBondMaturityDate1, floatingBondStartDate1, + floatingBondLeg1); floatingBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer); - vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402); + vars.iborIndex.addFixing(new Date(27, Month.March, 2007), 0.0402); double floatingBondImpliedValue1 = floatingBond1.cleanPrice(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve - double floatingBondCleanPrice1 = BondFunctions.cleanPrice(floatingBond1, vars.termStructure, vars.spread, - new Actual365Fixed(), vars.compounding, Frequency.Semiannual, fixedBondSettlementDate1); - double error5 = Math.Abs(floatingBondImpliedValue1-floatingBondCleanPrice1); - if (error5>tolerance) { + double floatingBondCleanPrice1 = BondFunctions.cleanPrice(floatingBond1, vars.termStructure, vars.spread, + new Actual365Fixed(), vars.compounding, Frequency.Semiannual, fixedBondSettlementDate1); + double error5 = Math.Abs(floatingBondImpliedValue1 - floatingBondCleanPrice1); + if (error5 > tolerance) + { QAssert.Fail("wrong clean price for fixed bond:" - + "\n market asset swap spread: " + - floatingBondImpliedValue1 - + "\n par asset swap spread: " + floatingBondCleanPrice1 - + "\n error: " + error5 - + "\n tolerance: " + tolerance); + + "\n market asset swap spread: " + + floatingBondImpliedValue1 + + "\n par asset swap spread: " + floatingBondCleanPrice1 + + "\n error: " + error5 + + "\n tolerance: " + tolerance); } // FRN Underlying bond (Isin: XS0090566539 COE 0 09/24/18) // maturity occurs on a business day - Date floatingBondStartDate2 = new Date(24,Month.September,2004); - Date floatingBondMaturityDate2 = new Date(24,Month.September,2018); + Date floatingBondStartDate2 = new Date(24, Month.September, 2004); + Date floatingBondMaturityDate2 = new Date(24, Month.September, 2018); Schedule floatingBondSchedule2 = new Schedule(floatingBondStartDate2, - floatingBondMaturityDate2, - new Period(Frequency.Semiannual), bondCalendar, - BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, - DateGeneration.Rule.Backward, false); + floatingBondMaturityDate2, + new Period(Frequency.Semiannual), bondCalendar, + BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, + DateGeneration.Rule.Backward, false); List floatingBondLeg2 = new IborLeg(floatingBondSchedule2, vars.iborIndex) - .withFixingDays(fixingDays) - .withSpreads(0.0025) - .withPaymentDayCounter(new Actual360()) - .inArrears(inArrears) - .withPaymentAdjustment(BusinessDayConvention.ModifiedFollowing) - .withNotionals(vars.faceAmount); + .withFixingDays(fixingDays) + .withSpreads(0.0025) + .withPaymentDayCounter(new Actual360()) + .inArrears(inArrears) + .withPaymentAdjustment(BusinessDayConvention.ModifiedFollowing) + .withNotionals(vars.faceAmount); Date floatingbondRedemption2 = bondCalendar.adjust(floatingBondMaturityDate2, BusinessDayConvention.ModifiedFollowing); floatingBondLeg2.Add(new SimpleCashFlow(100.0, floatingbondRedemption2)); - Bond floatingBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, floatingBondMaturityDate2, - floatingBondStartDate2, floatingBondLeg2); + Bond floatingBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, floatingBondMaturityDate2, + floatingBondStartDate2, floatingBondLeg2); floatingBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer); - vars.iborIndex.addFixing(new Date(22,Month.March,2007), 0.04013); + vars.iborIndex.addFixing(new Date(22, Month.March, 2007), 0.04013); double floatingBondImpliedValue2 = floatingBond2.cleanPrice(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve - double floatingBondCleanPrice2 = BondFunctions.cleanPrice(floatingBond2, vars.termStructure, vars.spread, - new Actual365Fixed(), vars.compounding, Frequency.Semiannual, fixedBondSettlementDate1); - double error7 = Math.Abs(floatingBondImpliedValue2-floatingBondCleanPrice2); - if (error7>tolerance) { + double floatingBondCleanPrice2 = BondFunctions.cleanPrice(floatingBond2, vars.termStructure, vars.spread, + new Actual365Fixed(), vars.compounding, Frequency.Semiannual, fixedBondSettlementDate1); + double error7 = Math.Abs(floatingBondImpliedValue2 - floatingBondCleanPrice2); + if (error7 > tolerance) + { QAssert.Fail("wrong clean price for fixed bond:" - + "\n market asset swap spread: " + - floatingBondImpliedValue2 - + "\n par asset swap spread: " + floatingBondCleanPrice2 - + "\n error: " + error7 - + "\n tolerance: " + tolerance); + + "\n market asset swap spread: " + + floatingBondImpliedValue2 + + "\n par asset swap spread: " + floatingBondCleanPrice2 + + "\n error: " + error7 + + "\n tolerance: " + tolerance); } // CMS Underlying bond (Isin: XS0228052402 CRDIT 0 8/22/20) // maturity doesn't occur on a business day - Date cmsBondStartDate1 = new Date(22,Month.August,2005); - Date cmsBondMaturityDate1 = new Date(22,Month.August,2020); - Schedule cmsBondSchedule1= new Schedule(cmsBondStartDate1, - cmsBondMaturityDate1, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date cmsBondStartDate1 = new Date(22, Month.August, 2005); + Date cmsBondMaturityDate1 = new Date(22, Month.August, 2020); + Schedule cmsBondSchedule1 = new Schedule(cmsBondStartDate1, + cmsBondMaturityDate1, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List cmsBondLeg1 = new CmsLeg(cmsBondSchedule1, vars.swapIndex) - .withPaymentDayCounter(new Thirty360()) - .withFixingDays(fixingDays) - .withCaps(0.055) - .withFloors(0.025) - .inArrears(inArrears) - .withNotionals(vars.faceAmount); + .withPaymentDayCounter(new Thirty360()) + .withFixingDays(fixingDays) + .withCaps(0.055) + .withFloors(0.025) + .inArrears(inArrears) + .withNotionals(vars.faceAmount); Date cmsbondRedemption1 = bondCalendar.adjust(cmsBondMaturityDate1, BusinessDayConvention.Following); cmsBondLeg1.Add(new SimpleCashFlow(100.0, cmsbondRedemption1)); - Bond cmsBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, cmsBondMaturityDate1, cmsBondStartDate1, - cmsBondLeg1); + Bond cmsBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, cmsBondMaturityDate1, cmsBondStartDate1, + cmsBondLeg1); cmsBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer); - vars.swapIndex.addFixing(new Date(18,Month.August,2006), 0.04158); + vars.swapIndex.addFixing(new Date(18, Month.August, 2006), 0.04158); double cmsBondImpliedValue1 = cmsBond1.cleanPrice(); - Date cmsBondSettlementDate1= cmsBond1.settlementDate(); + Date cmsBondSettlementDate1 = cmsBond1.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double cmsBondCleanPrice1 = BondFunctions.cleanPrice(cmsBond1, vars.termStructure, vars.spread, - new Actual365Fixed(), vars.compounding, Frequency.Annual, - cmsBondSettlementDate1); - double error9 = Math.Abs(cmsBondImpliedValue1-cmsBondCleanPrice1); - if (error9>tolerance) { + new Actual365Fixed(), vars.compounding, Frequency.Annual, + cmsBondSettlementDate1); + double error9 = Math.Abs(cmsBondImpliedValue1 - cmsBondCleanPrice1); + if (error9 > tolerance) + { QAssert.Fail("wrong clean price for fixed bond:" - + "\n market asset swap spread: " + cmsBondImpliedValue1 - + "\n par asset swap spread: " + cmsBondCleanPrice1 - + "\n error: " + error9 - + "\n tolerance: " + tolerance); + + "\n market asset swap spread: " + cmsBondImpliedValue1 + + "\n par asset swap spread: " + cmsBondCleanPrice1 + + "\n error: " + error9 + + "\n tolerance: " + tolerance); } // CMS Underlying bond (Isin: XS0218766664 ISPIM 0 5/6/15) // maturity occurs on a business day - Date cmsBondStartDate2 = new Date(06,Month.May,2005); - Date cmsBondMaturityDate2 = new Date(06,Month.May,2015); - Schedule cmsBondSchedule2= new Schedule(cmsBondStartDate2, - cmsBondMaturityDate2, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date cmsBondStartDate2 = new Date(06, Month.May, 2005); + Date cmsBondMaturityDate2 = new Date(06, Month.May, 2015); + Schedule cmsBondSchedule2 = new Schedule(cmsBondStartDate2, + cmsBondMaturityDate2, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List cmsBondLeg2 = new CmsLeg(cmsBondSchedule2, vars.swapIndex) - .withPaymentDayCounter(new Thirty360()) - .withFixingDays(fixingDays) - .withGearings(0.84) - .inArrears(inArrears) - .withNotionals(vars.faceAmount); + .withPaymentDayCounter(new Thirty360()) + .withFixingDays(fixingDays) + .withGearings(0.84) + .inArrears(inArrears) + .withNotionals(vars.faceAmount); Date cmsbondRedemption2 = bondCalendar.adjust(cmsBondMaturityDate2, BusinessDayConvention.Following); cmsBondLeg2.Add(new SimpleCashFlow(100.0, cmsbondRedemption2)); Bond cmsBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - cmsBondMaturityDate2, cmsBondStartDate2, cmsBondLeg2); + cmsBondMaturityDate2, cmsBondStartDate2, cmsBondLeg2); cmsBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer); - vars.swapIndex.addFixing(new Date(04,Month.May,2006), 0.04217); + vars.swapIndex.addFixing(new Date(04, Month.May, 2006), 0.04217); double cmsBondImpliedValue2 = cmsBond2.cleanPrice(); - Date cmsBondSettlementDate2= cmsBond2.settlementDate(); + Date cmsBondSettlementDate2 = cmsBond2.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double cmsBondCleanPrice2 = BondFunctions.cleanPrice(cmsBond2, vars.termStructure, vars.spread, - new Actual365Fixed(), vars.compounding, Frequency.Annual, - cmsBondSettlementDate2); - double error11 = Math.Abs(cmsBondImpliedValue2-cmsBondCleanPrice2); - if (error11>tolerance) { + new Actual365Fixed(), vars.compounding, Frequency.Annual, + cmsBondSettlementDate2); + double error11 = Math.Abs(cmsBondImpliedValue2 - cmsBondCleanPrice2); + if (error11 > tolerance) + { QAssert.Fail("wrong clean price for fixed bond:" - + "\n market asset swap spread: " + cmsBondImpliedValue2 - + "\n par asset swap spread: " + cmsBondCleanPrice2 - + "\n error: " + error11 - + "\n tolerance: " + tolerance); + + "\n market asset swap spread: " + cmsBondImpliedValue2 + + "\n par asset swap spread: " + cmsBondCleanPrice2 + + "\n error: " + error11 + + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15) // maturity doesn't occur on a business day - Date zeroCpnBondStartDate1 = new Date(19,Month.December,1985); - Date zeroCpnBondMaturityDate1 = new Date(20,Month.December,2015); + Date zeroCpnBondStartDate1 = new Date(19, Month.December, 1985); + Date zeroCpnBondMaturityDate1 = new Date(20, Month.December, 2015); Date zeroCpnBondRedemption1 = bondCalendar.adjust(zeroCpnBondMaturityDate1, - BusinessDayConvention.Following); - List zeroCpnBondLeg1 = new List{new SimpleCashFlow(100.0, zeroCpnBondRedemption1)}; + BusinessDayConvention.Following); + List zeroCpnBondLeg1 = new List {new SimpleCashFlow(100.0, zeroCpnBondRedemption1)}; Bond zeroCpnBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - zeroCpnBondMaturityDate1, zeroCpnBondStartDate1, zeroCpnBondLeg1); + zeroCpnBondMaturityDate1, zeroCpnBondStartDate1, zeroCpnBondLeg1); zeroCpnBond1.setPricingEngine(bondEngine); double zeroCpnBondImpliedValue1 = zeroCpnBond1.cleanPrice(); - Date zeroCpnBondSettlementDate1= zeroCpnBond1.settlementDate(); + Date zeroCpnBondSettlementDate1 = zeroCpnBond1.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double zeroCpnBondCleanPrice1 = BondFunctions.cleanPrice(zeroCpnBond1, - vars.termStructure, - vars.spread, - new Actual365Fixed(), - vars.compounding, Frequency.Annual, - zeroCpnBondSettlementDate1); - double error13 = Math.Abs(zeroCpnBondImpliedValue1-zeroCpnBondCleanPrice1); - if (error13>tolerance) { + vars.termStructure, + vars.spread, + new Actual365Fixed(), + vars.compounding, Frequency.Annual, + zeroCpnBondSettlementDate1); + double error13 = Math.Abs(zeroCpnBondImpliedValue1 - zeroCpnBondCleanPrice1); + if (error13 > tolerance) + { QAssert.Fail("wrong clean price for zero coupon bond:" - + "\n zero cpn implied value: " + - zeroCpnBondImpliedValue1 - + "\n zero cpn price: " + zeroCpnBondCleanPrice1 - + "\n error: " + error13 - + "\n tolerance: " + tolerance); + + "\n zero cpn implied value: " + + zeroCpnBondImpliedValue1 + + "\n zero cpn price: " + zeroCpnBondCleanPrice1 + + "\n error: " + error13 + + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28) // maturity occurs on a business day - Date zeroCpnBondStartDate2 = new Date(17,Month.February,1998); - Date zeroCpnBondMaturityDate2 = new Date(17,Month.February,2028); + Date zeroCpnBondStartDate2 = new Date(17, Month.February, 1998); + Date zeroCpnBondMaturityDate2 = new Date(17, Month.February, 2028); Date zerocpbondRedemption2 = bondCalendar.adjust(zeroCpnBondMaturityDate2, - BusinessDayConvention.Following); - List zeroCpnBondLeg2 = new List{new SimpleCashFlow(100.0, zerocpbondRedemption2)}; + BusinessDayConvention.Following); + List zeroCpnBondLeg2 = new List {new SimpleCashFlow(100.0, zerocpbondRedemption2)}; Bond zeroCpnBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - zeroCpnBondMaturityDate2, zeroCpnBondStartDate2, zeroCpnBondLeg2); + zeroCpnBondMaturityDate2, zeroCpnBondStartDate2, zeroCpnBondLeg2); zeroCpnBond2.setPricingEngine(bondEngine); double zeroCpnBondImpliedValue2 = zeroCpnBond2.cleanPrice(); - Date zeroCpnBondSettlementDate2= zeroCpnBond2.settlementDate(); + Date zeroCpnBondSettlementDate2 = zeroCpnBond2.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double zeroCpnBondCleanPrice2 = BondFunctions.cleanPrice(zeroCpnBond2, - vars.termStructure, - vars.spread, - new Actual365Fixed(), - vars.compounding, Frequency.Annual, - zeroCpnBondSettlementDate2); - double error15 = Math.Abs(zeroCpnBondImpliedValue2-zeroCpnBondCleanPrice2); - if (error15>tolerance) { + vars.termStructure, + vars.spread, + new Actual365Fixed(), + vars.compounding, Frequency.Annual, + zeroCpnBondSettlementDate2); + double error15 = Math.Abs(zeroCpnBondImpliedValue2 - zeroCpnBondCleanPrice2); + if (error15 > tolerance) + { QAssert.Fail("wrong clean price for zero coupon bond:" - + "\n zero cpn implied value: " + - zeroCpnBondImpliedValue2 - + "\n zero cpn price: " + zeroCpnBondCleanPrice2 - + "\n error: " + error15 - + "\n tolerance: " + tolerance); + + "\n zero cpn implied value: " + + zeroCpnBondImpliedValue2 + + "\n zero cpn price: " + zeroCpnBondCleanPrice2 + + "\n error: " + error15 + + "\n tolerance: " + tolerance); } - } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testSpecializedBondVsGenericBond() + public void testSpecializedBondVsGenericBond() { // Testing clean and dirty prices for specialized bond against equivalent generic bond... CommonVars vars = new CommonVars(); @@ -2505,398 +2547,410 @@ public void testSpecializedBondVsGenericBond() // Fixed Underlying bond (Isin: DE0001135275 DBR 4 01/04/37) // maturity doesn't occur on a business day - Date fixedBondStartDate1 = new Date(4,Month.January,2005); - Date fixedBondMaturityDate1 = new Date(4,Month.January,2037); - Schedule fixedBondSchedule1= new Schedule(fixedBondStartDate1, - fixedBondMaturityDate1, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date fixedBondStartDate1 = new Date(4, Month.January, 2005); + Date fixedBondMaturityDate1 = new Date(4, Month.January, 2037); + Schedule fixedBondSchedule1 = new Schedule(fixedBondStartDate1, + fixedBondMaturityDate1, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List fixedBondLeg1 = new FixedRateLeg(fixedBondSchedule1) - .withCouponRates(0.04, new ActualActual(ActualActual.Convention.ISDA)) - .withNotionals(vars.faceAmount); + .withCouponRates(0.04, new ActualActual(ActualActual.Convention.ISDA)) + .withNotionals(vars.faceAmount); Date fixedbondRedemption1 = bondCalendar.adjust(fixedBondMaturityDate1, BusinessDayConvention.Following); fixedBondLeg1.Add(new SimpleCashFlow(100.0, fixedbondRedemption1)); // generic bond Bond fixedBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - fixedBondMaturityDate1, fixedBondStartDate1, fixedBondLeg1); + fixedBondMaturityDate1, fixedBondStartDate1, fixedBondLeg1); IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure); fixedBond1.setPricingEngine(bondEngine); // equivalent specialized fixed rate bond Bond fixedSpecializedBond1 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule1, - new List{0.04}, - new ActualActual(ActualActual.Convention.ISDA), BusinessDayConvention.Following, - 100.0, new Date(4,Month.January,2005) ); + new List {0.04}, + new ActualActual(ActualActual.Convention.ISDA), BusinessDayConvention.Following, + 100.0, new Date(4, Month.January, 2005)); fixedSpecializedBond1.setPricingEngine(bondEngine); double fixedBondTheoValue1 = fixedBond1.cleanPrice(); double fixedSpecializedBondTheoValue1 = fixedSpecializedBond1.cleanPrice(); double tolerance = 1.0e-13; - double error1 = Math.Abs(fixedBondTheoValue1-fixedSpecializedBondTheoValue1); - if (error1>tolerance) { + double error1 = Math.Abs(fixedBondTheoValue1 - fixedSpecializedBondTheoValue1); + if (error1 > tolerance) + { QAssert.Fail("wrong clean price for fixed bond:" - + "\n specialized fixed rate bond's theo clean price: " - + fixedBondTheoValue1 - + "\n generic equivalent bond's theo clean price: " - + fixedSpecializedBondTheoValue1 - + "\n error: " + error1 - + "\n tolerance: " + tolerance); - } - double fixedBondTheoDirty1 = fixedBondTheoValue1+fixedBond1.accruedAmount(); - double fixedSpecializedTheoDirty1 = fixedSpecializedBondTheoValue1+ - fixedSpecializedBond1.accruedAmount(); - double error2 = Math.Abs(fixedBondTheoDirty1-fixedSpecializedTheoDirty1); - if (error2>tolerance) { + + "\n specialized fixed rate bond's theo clean price: " + + fixedBondTheoValue1 + + "\n generic equivalent bond's theo clean price: " + + fixedSpecializedBondTheoValue1 + + "\n error: " + error1 + + "\n tolerance: " + tolerance); + } + double fixedBondTheoDirty1 = fixedBondTheoValue1 + fixedBond1.accruedAmount(); + double fixedSpecializedTheoDirty1 = fixedSpecializedBondTheoValue1 + + fixedSpecializedBond1.accruedAmount(); + double error2 = Math.Abs(fixedBondTheoDirty1 - fixedSpecializedTheoDirty1); + if (error2 > tolerance) + { QAssert.Fail("wrong dirty price for fixed bond:" - + "\n specialized fixed rate bond's theo dirty price: " - + fixedBondTheoDirty1 - + "\n generic equivalent bond's theo dirty price: " - + fixedSpecializedTheoDirty1 - + "\n error: " + error2 - + "\n tolerance: " + tolerance); + + "\n specialized fixed rate bond's theo dirty price: " + + fixedBondTheoDirty1 + + "\n generic equivalent bond's theo dirty price: " + + fixedSpecializedTheoDirty1 + + "\n error: " + error2 + + "\n tolerance: " + tolerance); } // Fixed Underlying bond (Isin: IT0006527060 IBRD 5 02/05/19) // maturity occurs on a business day - Date fixedBondStartDate2 = new Date(5,Month.February,2005); - Date fixedBondMaturityDate2 = new Date(5,Month.February,2019); - Schedule fixedBondSchedule2= new Schedule(fixedBondStartDate2, - fixedBondMaturityDate2, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date fixedBondStartDate2 = new Date(5, Month.February, 2005); + Date fixedBondMaturityDate2 = new Date(5, Month.February, 2019); + Schedule fixedBondSchedule2 = new Schedule(fixedBondStartDate2, + fixedBondMaturityDate2, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List fixedBondLeg2 = new FixedRateLeg(fixedBondSchedule2) - .withCouponRates(0.05, new Thirty360(Thirty360.Thirty360Convention.BondBasis)) - .withNotionals(vars.faceAmount); + .withCouponRates(0.05, new Thirty360(Thirty360.Thirty360Convention.BondBasis)) + .withNotionals(vars.faceAmount); Date fixedbondRedemption2 = bondCalendar.adjust(fixedBondMaturityDate2, BusinessDayConvention.Following); fixedBondLeg2.Add(new SimpleCashFlow(100.0, fixedbondRedemption2)); // generic bond Bond fixedBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - fixedBondMaturityDate2, fixedBondStartDate2, fixedBondLeg2); + fixedBondMaturityDate2, fixedBondStartDate2, fixedBondLeg2); fixedBond2.setPricingEngine(bondEngine); // equivalent specialized fixed rate bond Bond fixedSpecializedBond2 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule2, - new List{0.05}, - new Thirty360(Thirty360.Thirty360Convention.BondBasis), BusinessDayConvention.Following, - 100.0, new Date(5,Month.February,2005)); + new List {0.05}, + new Thirty360(Thirty360.Thirty360Convention.BondBasis), BusinessDayConvention.Following, + 100.0, new Date(5, Month.February, 2005)); fixedSpecializedBond2.setPricingEngine(bondEngine); double fixedBondTheoValue2 = fixedBond2.cleanPrice(); double fixedSpecializedBondTheoValue2 = fixedSpecializedBond2.cleanPrice(); - double error3 = Math.Abs(fixedBondTheoValue2-fixedSpecializedBondTheoValue2); - if (error3>tolerance) { + double error3 = Math.Abs(fixedBondTheoValue2 - fixedSpecializedBondTheoValue2); + if (error3 > tolerance) + { QAssert.Fail("wrong clean price for fixed bond:" - + "\n specialized fixed rate bond's theo clean price: " - + fixedBondTheoValue2 - + "\n generic equivalent bond's theo clean price: " - + fixedSpecializedBondTheoValue2 - + "\n error: " + error3 - + "\n tolerance: " + tolerance); - } - double fixedBondTheoDirty2 = fixedBondTheoValue2+ - fixedBond2.accruedAmount(); - double fixedSpecializedBondTheoDirty2 = fixedSpecializedBondTheoValue2+ - fixedSpecializedBond2.accruedAmount(); - - double error4 = Math.Abs(fixedBondTheoDirty2-fixedSpecializedBondTheoDirty2); - if (error4>tolerance) { + + "\n specialized fixed rate bond's theo clean price: " + + fixedBondTheoValue2 + + "\n generic equivalent bond's theo clean price: " + + fixedSpecializedBondTheoValue2 + + "\n error: " + error3 + + "\n tolerance: " + tolerance); + } + double fixedBondTheoDirty2 = fixedBondTheoValue2 + + fixedBond2.accruedAmount(); + double fixedSpecializedBondTheoDirty2 = fixedSpecializedBondTheoValue2 + + fixedSpecializedBond2.accruedAmount(); + + double error4 = Math.Abs(fixedBondTheoDirty2 - fixedSpecializedBondTheoDirty2); + if (error4 > tolerance) + { QAssert.Fail("wrong dirty price for fixed bond:" - + "\n specialized fixed rate bond's dirty clean price: " - + fixedBondTheoDirty2 - + "\n generic equivalent bond's theo dirty price: " - + fixedSpecializedBondTheoDirty2 - + "\n error: " + error4 - + "\n tolerance: " + tolerance); + + "\n specialized fixed rate bond's dirty clean price: " + + fixedBondTheoDirty2 + + "\n generic equivalent bond's theo dirty price: " + + fixedSpecializedBondTheoDirty2 + + "\n error: " + error4 + + "\n tolerance: " + tolerance); } // FRN Underlying bond (Isin: IT0003543847 ISPIM 0 09/29/13) // maturity doesn't occur on a business day - Date floatingBondStartDate1 = new Date(29,Month.September,2003); - Date floatingBondMaturityDate1 = new Date(29,Month.September,2013); - Schedule floatingBondSchedule1= new Schedule(floatingBondStartDate1, - floatingBondMaturityDate1, - new Period(Frequency.Semiannual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date floatingBondStartDate1 = new Date(29, Month.September, 2003); + Date floatingBondMaturityDate1 = new Date(29, Month.September, 2013); + Schedule floatingBondSchedule1 = new Schedule(floatingBondStartDate1, + floatingBondMaturityDate1, + new Period(Frequency.Semiannual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List floatingBondLeg1 = new IborLeg(floatingBondSchedule1, vars.iborIndex) - .withPaymentDayCounter(new Actual360()) - .withFixingDays(fixingDays) - .withSpreads(0.0056) - .inArrears(inArrears) - .withNotionals(vars.faceAmount); + .withPaymentDayCounter(new Actual360()) + .withFixingDays(fixingDays) + .withSpreads(0.0056) + .inArrears(inArrears) + .withNotionals(vars.faceAmount); Date floatingbondRedemption1 = bondCalendar.adjust(floatingBondMaturityDate1, BusinessDayConvention.Following); floatingBondLeg1.Add(new SimpleCashFlow(100.0, floatingbondRedemption1)); // generic bond Bond floatingBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - floatingBondMaturityDate1, floatingBondStartDate1, floatingBondLeg1); + floatingBondMaturityDate1, floatingBondStartDate1, floatingBondLeg1); floatingBond1.setPricingEngine(bondEngine); // equivalent specialized floater - Bond floatingSpecializedBond1= new FloatingRateBond(settlementDays, vars.faceAmount, - floatingBondSchedule1, - vars.iborIndex, new Actual360(), - BusinessDayConvention.Following, fixingDays, - new List{1}, - new List{0.0056}, - new List(), new List(), - inArrears, - 100.0, new Date(29,Month.September,2003)); + Bond floatingSpecializedBond1 = new FloatingRateBond(settlementDays, vars.faceAmount, + floatingBondSchedule1, + vars.iborIndex, new Actual360(), + BusinessDayConvention.Following, fixingDays, + new List {1}, + new List {0.0056}, + new List < double? >(), new List < double? >(), + inArrears, + 100.0, new Date(29, Month.September, 2003)); floatingSpecializedBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer); Utils.setCouponPricer(floatingSpecializedBond1.cashflows(), vars.pricer); - vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402); + vars.iborIndex.addFixing(new Date(27, Month.March, 2007), 0.0402); double floatingBondTheoValue1 = floatingBond1.cleanPrice(); double floatingSpecializedBondTheoValue1 = floatingSpecializedBond1.cleanPrice(); - double error5 = Math.Abs(floatingBondTheoValue1- - floatingSpecializedBondTheoValue1); - if (error5>tolerance) { + double error5 = Math.Abs(floatingBondTheoValue1 - + floatingSpecializedBondTheoValue1); + if (error5 > tolerance) + { QAssert.Fail("wrong clean price for fixed bond:" - + "\n generic fixed rate bond's theo clean price: " - + floatingBondTheoValue1 - + "\n equivalent specialized bond's theo clean price: " - + floatingSpecializedBondTheoValue1 - + "\n error: " + error5 - + "\n tolerance: " + tolerance); - } - double floatingBondTheoDirty1 = floatingBondTheoValue1+ - floatingBond1.accruedAmount(); + + "\n generic fixed rate bond's theo clean price: " + + floatingBondTheoValue1 + + "\n equivalent specialized bond's theo clean price: " + + floatingSpecializedBondTheoValue1 + + "\n error: " + error5 + + "\n tolerance: " + tolerance); + } + double floatingBondTheoDirty1 = floatingBondTheoValue1 + + floatingBond1.accruedAmount(); double floatingSpecializedBondTheoDirty1 = - floatingSpecializedBondTheoValue1+ + floatingSpecializedBondTheoValue1 + floatingSpecializedBond1.accruedAmount(); - double error6 = Math.Abs(floatingBondTheoDirty1- - floatingSpecializedBondTheoDirty1); - if (error6>tolerance) { + double error6 = Math.Abs(floatingBondTheoDirty1 - + floatingSpecializedBondTheoDirty1); + if (error6 > tolerance) + { QAssert.Fail("wrong dirty price for frn bond:" - + "\n generic frn bond's dirty clean price: " - + floatingBondTheoDirty1 - + "\n equivalent specialized bond's theo dirty price: " - + floatingSpecializedBondTheoDirty1 - + "\n error: " + error6 - + "\n tolerance: " + tolerance); + + "\n generic frn bond's dirty clean price: " + + floatingBondTheoDirty1 + + "\n equivalent specialized bond's theo dirty price: " + + floatingSpecializedBondTheoDirty1 + + "\n error: " + error6 + + "\n tolerance: " + tolerance); } // FRN Underlying bond (Isin: XS0090566539 COE 0 09/24/18) // maturity occurs on a business day - Date floatingBondStartDate2 = new Date(24,Month.September,2004); - Date floatingBondMaturityDate2 = new Date(24,Month.September,2018); + Date floatingBondStartDate2 = new Date(24, Month.September, 2004); + Date floatingBondMaturityDate2 = new Date(24, Month.September, 2018); Schedule floatingBondSchedule2 = new Schedule(floatingBondStartDate2, - floatingBondMaturityDate2, - new Period(Frequency.Semiannual), bondCalendar, - BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, - DateGeneration.Rule.Backward, false); + floatingBondMaturityDate2, + new Period(Frequency.Semiannual), bondCalendar, + BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, + DateGeneration.Rule.Backward, false); List floatingBondLeg2 = new IborLeg(floatingBondSchedule2, vars.iborIndex) - .withPaymentDayCounter(new Actual360()) - .withFixingDays(fixingDays) - .withSpreads(0.0025) - .inArrears(inArrears) - .withPaymentAdjustment(BusinessDayConvention.ModifiedFollowing) - .withNotionals(vars.faceAmount); + .withPaymentDayCounter(new Actual360()) + .withFixingDays(fixingDays) + .withSpreads(0.0025) + .inArrears(inArrears) + .withPaymentAdjustment(BusinessDayConvention.ModifiedFollowing) + .withNotionals(vars.faceAmount); Date floatingbondRedemption2 = bondCalendar.adjust(floatingBondMaturityDate2, BusinessDayConvention.ModifiedFollowing); floatingBondLeg2.Add(new SimpleCashFlow(100.0, floatingbondRedemption2)); // generic bond Bond floatingBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - floatingBondMaturityDate2, floatingBondStartDate2, floatingBondLeg2); + floatingBondMaturityDate2, floatingBondStartDate2, floatingBondLeg2); floatingBond2.setPricingEngine(bondEngine); // equivalent specialized floater Bond floatingSpecializedBond2 = new FloatingRateBond(settlementDays, vars.faceAmount, - floatingBondSchedule2, - vars.iborIndex, new Actual360(), - BusinessDayConvention.ModifiedFollowing, fixingDays, - new List{1}, - new List{0.0025}, - new List(), new List(), - inArrears, - 100.0, new Date(24,Month.September,2004)); + floatingBondSchedule2, + vars.iborIndex, new Actual360(), + BusinessDayConvention.ModifiedFollowing, fixingDays, + new List {1}, + new List {0.0025}, + new List < double? >(), new List < double? >(), + inArrears, + 100.0, new Date(24, Month.September, 2004)); floatingSpecializedBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer); Utils.setCouponPricer(floatingSpecializedBond2.cashflows(), vars.pricer); - vars.iborIndex.addFixing(new Date(22,Month.March,2007), 0.04013); + vars.iborIndex.addFixing(new Date(22, Month.March, 2007), 0.04013); double floatingBondTheoValue2 = floatingBond2.cleanPrice(); double floatingSpecializedBondTheoValue2 = floatingSpecializedBond2.cleanPrice(); double error7 = - Math.Abs(floatingBondTheoValue2-floatingSpecializedBondTheoValue2); - if (error7>tolerance) { + Math.Abs(floatingBondTheoValue2 - floatingSpecializedBondTheoValue2); + if (error7 > tolerance) + { QAssert.Fail("wrong clean price for floater bond:" - + "\n generic floater bond's theo clean price: " - + floatingBondTheoValue2 - + "\n equivalent specialized bond's theo clean price: " - + floatingSpecializedBondTheoValue2 - + "\n error: " + error7 - + "\n tolerance: " + tolerance); - } - double floatingBondTheoDirty2 = floatingBondTheoValue2+ - floatingBond2.accruedAmount(); - double floatingSpecializedTheoDirty2 = floatingSpecializedBondTheoValue2+ - floatingSpecializedBond2.accruedAmount(); + + "\n generic floater bond's theo clean price: " + + floatingBondTheoValue2 + + "\n equivalent specialized bond's theo clean price: " + + floatingSpecializedBondTheoValue2 + + "\n error: " + error7 + + "\n tolerance: " + tolerance); + } + double floatingBondTheoDirty2 = floatingBondTheoValue2 + + floatingBond2.accruedAmount(); + double floatingSpecializedTheoDirty2 = floatingSpecializedBondTheoValue2 + + floatingSpecializedBond2.accruedAmount(); double error8 = - Math.Abs(floatingBondTheoDirty2-floatingSpecializedTheoDirty2); - if (error8>tolerance) { + Math.Abs(floatingBondTheoDirty2 - floatingSpecializedTheoDirty2); + if (error8 > tolerance) + { QAssert.Fail("wrong dirty price for floater bond:" - + "\n generic floater bond's theo dirty price: " - + floatingBondTheoDirty2 - + "\n equivalent specialized bond's theo dirty price: " - + floatingSpecializedTheoDirty2 - + "\n error: " + error8 - + "\n tolerance: " + tolerance); + + "\n generic floater bond's theo dirty price: " + + floatingBondTheoDirty2 + + "\n equivalent specialized bond's theo dirty price: " + + floatingSpecializedTheoDirty2 + + "\n error: " + error8 + + "\n tolerance: " + tolerance); } // CMS Underlying bond (Isin: XS0228052402 CRDIT 0 8/22/20) // maturity doesn't occur on a business day - Date cmsBondStartDate1 = new Date(22,Month.August,2005); - Date cmsBondMaturityDate1 = new Date(22,Month.August,2020); - Schedule cmsBondSchedule1= new Schedule(cmsBondStartDate1, - cmsBondMaturityDate1, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date cmsBondStartDate1 = new Date(22, Month.August, 2005); + Date cmsBondMaturityDate1 = new Date(22, Month.August, 2020); + Schedule cmsBondSchedule1 = new Schedule(cmsBondStartDate1, + cmsBondMaturityDate1, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List cmsBondLeg1 = new CmsLeg(cmsBondSchedule1, vars.swapIndex) - .withPaymentDayCounter(new Thirty360()) - .withFixingDays(fixingDays) - .withCaps(0.055) - .withFloors(0.025) - .inArrears(inArrears) - .withNotionals(vars.faceAmount); + .withPaymentDayCounter(new Thirty360()) + .withFixingDays(fixingDays) + .withCaps(0.055) + .withFloors(0.025) + .inArrears(inArrears) + .withNotionals(vars.faceAmount); Date cmsbondRedemption1 = bondCalendar.adjust(cmsBondMaturityDate1, BusinessDayConvention.Following); cmsBondLeg1.Add(new SimpleCashFlow(100.0, cmsbondRedemption1)); // generic cms bond Bond cmsBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - cmsBondMaturityDate1, cmsBondStartDate1, cmsBondLeg1); + cmsBondMaturityDate1, cmsBondStartDate1, cmsBondLeg1); cmsBond1.setPricingEngine(bondEngine); // equivalent specialized cms bond Bond cmsSpecializedBond1 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule1, - vars.swapIndex, new Thirty360(), - BusinessDayConvention.Following, fixingDays, - new List{1.0}, new List{0.0}, - new List{0.055}, new List{0.025}, - inArrears, - 100.0, new Date(22,Month.August,2005)); + vars.swapIndex, new Thirty360(), + BusinessDayConvention.Following, fixingDays, + new List {1.0}, new List {0.0}, + new List < double? > {0.055}, new List < double? > {0.025}, + inArrears, + 100.0, new Date(22, Month.August, 2005)); cmsSpecializedBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer); Utils.setCouponPricer(cmsSpecializedBond1.cashflows(), vars.cmspricer); - vars.swapIndex.addFixing(new Date(18,Month.August,2006), 0.04158); + vars.swapIndex.addFixing(new Date(18, Month.August, 2006), 0.04158); double cmsBondTheoValue1 = cmsBond1.cleanPrice(); double cmsSpecializedBondTheoValue1 = cmsSpecializedBond1.cleanPrice(); - double error9 = Math.Abs(cmsBondTheoValue1-cmsSpecializedBondTheoValue1); - if (error9>tolerance) { + double error9 = Math.Abs(cmsBondTheoValue1 - cmsSpecializedBondTheoValue1); + if (error9 > tolerance) + { QAssert.Fail("wrong clean price for cms bond:" - + "\n generic cms bond's theo clean price: " - + cmsBondTheoValue1 - + "\n equivalent specialized bond's theo clean price: " - + cmsSpecializedBondTheoValue1 - + "\n error: " + error9 - + "\n tolerance: " + tolerance); - } - double cmsBondTheoDirty1 = cmsBondTheoValue1+cmsBond1.accruedAmount(); - double cmsSpecializedBondTheoDirty1 = cmsSpecializedBondTheoValue1+ - cmsSpecializedBond1.accruedAmount(); - double error10 = Math.Abs(cmsBondTheoDirty1-cmsSpecializedBondTheoDirty1); - if (error10>tolerance) { + + "\n generic cms bond's theo clean price: " + + cmsBondTheoValue1 + + "\n equivalent specialized bond's theo clean price: " + + cmsSpecializedBondTheoValue1 + + "\n error: " + error9 + + "\n tolerance: " + tolerance); + } + double cmsBondTheoDirty1 = cmsBondTheoValue1 + cmsBond1.accruedAmount(); + double cmsSpecializedBondTheoDirty1 = cmsSpecializedBondTheoValue1 + + cmsSpecializedBond1.accruedAmount(); + double error10 = Math.Abs(cmsBondTheoDirty1 - cmsSpecializedBondTheoDirty1); + if (error10 > tolerance) + { QAssert.Fail("wrong dirty price for cms bond:" - + "\n generic cms bond's theo dirty price: " - + cmsBondTheoDirty1 - + "\n specialized cms bond's theo dirty price: " - + cmsSpecializedBondTheoDirty1 - + "\n error: " + error10 - + "\n tolerance: " + tolerance); + + "\n generic cms bond's theo dirty price: " + + cmsBondTheoDirty1 + + "\n specialized cms bond's theo dirty price: " + + cmsSpecializedBondTheoDirty1 + + "\n error: " + error10 + + "\n tolerance: " + tolerance); } // CMS Underlying bond (Isin: XS0218766664 ISPIM 0 5/6/15) // maturity occurs on a business day - Date cmsBondStartDate2 = new Date(06,Month.May,2005); - Date cmsBondMaturityDate2 = new Date(06,Month.May,2015); + Date cmsBondStartDate2 = new Date(06, Month.May, 2005); + Date cmsBondMaturityDate2 = new Date(06, Month.May, 2015); Schedule cmsBondSchedule2 = new Schedule(cmsBondStartDate2, - cmsBondMaturityDate2, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + cmsBondMaturityDate2, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List cmsBondLeg2 = new CmsLeg(cmsBondSchedule2, vars.swapIndex) - .withPaymentDayCounter(new Thirty360()) - .withFixingDays(fixingDays) - .withGearings(0.84) - .inArrears(inArrears) - .withNotionals(vars.faceAmount); + .withPaymentDayCounter(new Thirty360()) + .withFixingDays(fixingDays) + .withGearings(0.84) + .inArrears(inArrears) + .withNotionals(vars.faceAmount); Date cmsbondRedemption2 = bondCalendar.adjust(cmsBondMaturityDate2, BusinessDayConvention.Following); cmsBondLeg2.Add(new SimpleCashFlow(100.0, cmsbondRedemption2)); // generic bond Bond cmsBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - cmsBondMaturityDate2, cmsBondStartDate2, cmsBondLeg2); + cmsBondMaturityDate2, cmsBondStartDate2, cmsBondLeg2); cmsBond2.setPricingEngine(bondEngine); // equivalent specialized cms bond Bond cmsSpecializedBond2 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule2, - vars.swapIndex, new Thirty360(), - BusinessDayConvention.Following, fixingDays, - new List{0.84}, new List{0.0}, - new List(), new List(), - inArrears, 100.0, new Date(06,Month.May,2005)); + vars.swapIndex, new Thirty360(), + BusinessDayConvention.Following, fixingDays, + new List {0.84}, new List {0.0}, + new List < double? >(), new List < double? >(), + inArrears, 100.0, new Date(06, Month.May, 2005)); cmsSpecializedBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer); Utils.setCouponPricer(cmsSpecializedBond2.cashflows(), vars.cmspricer); - vars.swapIndex.addFixing(new Date(04,Month.May,2006), 0.04217); + vars.swapIndex.addFixing(new Date(04, Month.May, 2006), 0.04217); double cmsBondTheoValue2 = cmsBond2.cleanPrice(); double cmsSpecializedBondTheoValue2 = cmsSpecializedBond2.cleanPrice(); - double error11 = Math.Abs(cmsBondTheoValue2-cmsSpecializedBondTheoValue2); - if (error11>tolerance) { + double error11 = Math.Abs(cmsBondTheoValue2 - cmsSpecializedBondTheoValue2); + if (error11 > tolerance) + { QAssert.Fail("wrong clean price for cms bond:" - + "\n generic cms bond's theo clean price: " - + cmsBondTheoValue2 - + "\n cms bond's theo clean price: " - + cmsSpecializedBondTheoValue2 - + "\n error: " + error11 - + "\n tolerance: " + tolerance); - } - double cmsBondTheoDirty2 = cmsBondTheoValue2+cmsBond2.accruedAmount(); + + "\n generic cms bond's theo clean price: " + + cmsBondTheoValue2 + + "\n cms bond's theo clean price: " + + cmsSpecializedBondTheoValue2 + + "\n error: " + error11 + + "\n tolerance: " + tolerance); + } + double cmsBondTheoDirty2 = cmsBondTheoValue2 + cmsBond2.accruedAmount(); double cmsSpecializedBondTheoDirty2 = - cmsSpecializedBondTheoValue2+cmsSpecializedBond2.accruedAmount(); - double error12 = Math.Abs(cmsBondTheoDirty2-cmsSpecializedBondTheoDirty2); - if (error12>tolerance) { + cmsSpecializedBondTheoValue2 + cmsSpecializedBond2.accruedAmount(); + double error12 = Math.Abs(cmsBondTheoDirty2 - cmsSpecializedBondTheoDirty2); + if (error12 > tolerance) + { QAssert.Fail("wrong dirty price for cms bond:" - + "\n generic cms bond's dirty price: " - + cmsBondTheoDirty2 - + "\n specialized cms bond's theo dirty price: " - + cmsSpecializedBondTheoDirty2 - + "\n error: " + error12 - + "\n tolerance: " + tolerance); + + "\n generic cms bond's dirty price: " + + cmsBondTheoDirty2 + + "\n specialized cms bond's theo dirty price: " + + cmsSpecializedBondTheoDirty2 + + "\n error: " + error12 + + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15) // maturity doesn't occur on a business day - Date zeroCpnBondStartDate1 = new Date(19,Month.December,1985); - Date zeroCpnBondMaturityDate1 = new Date(20,Month.December,2015); + Date zeroCpnBondStartDate1 = new Date(19, Month.December, 1985); + Date zeroCpnBondMaturityDate1 = new Date(20, Month.December, 2015); Date zeroCpnBondRedemption1 = bondCalendar.adjust(zeroCpnBondMaturityDate1, - BusinessDayConvention.Following); - List zeroCpnBondLeg1 = new List{new SimpleCashFlow(100.0, zeroCpnBondRedemption1)}; + BusinessDayConvention.Following); + List zeroCpnBondLeg1 = new List {new SimpleCashFlow(100.0, zeroCpnBondRedemption1)}; // generic bond - Bond zeroCpnBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, zeroCpnBondMaturityDate1, - zeroCpnBondStartDate1, zeroCpnBondLeg1); + Bond zeroCpnBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, zeroCpnBondMaturityDate1, + zeroCpnBondStartDate1, zeroCpnBondLeg1); zeroCpnBond1.setPricingEngine(bondEngine); // specialized zerocpn bond Bond zeroCpnSpecializedBond1 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount, - new Date(20,Month.December,2015), - BusinessDayConvention.Following, - 100.0, new Date(19,Month.December,1985)); + new Date(20, Month.December, 2015), + BusinessDayConvention.Following, + 100.0, new Date(19, Month.December, 1985)); zeroCpnSpecializedBond1.setPricingEngine(bondEngine); double zeroCpnBondTheoValue1 = zeroCpnBond1.cleanPrice(); @@ -2904,50 +2958,52 @@ public void testSpecializedBondVsGenericBond() zeroCpnSpecializedBond1.cleanPrice(); double error13 = - Math.Abs(zeroCpnBondTheoValue1-zeroCpnSpecializedBondTheoValue1); - if (error13>tolerance) { + Math.Abs(zeroCpnBondTheoValue1 - zeroCpnSpecializedBondTheoValue1); + if (error13 > tolerance) + { QAssert.Fail("wrong clean price for zero coupon bond:" - + "\n generic zero bond's clean price: " - + zeroCpnBondTheoValue1 - + "\n specialized zero bond's clean price: " - + zeroCpnSpecializedBondTheoValue1 - + "\n error: " + error13 - + "\n tolerance: " + tolerance); - } - double zeroCpnBondTheoDirty1 = zeroCpnBondTheoValue1+ - zeroCpnBond1.accruedAmount(); + + "\n generic zero bond's clean price: " + + zeroCpnBondTheoValue1 + + "\n specialized zero bond's clean price: " + + zeroCpnSpecializedBondTheoValue1 + + "\n error: " + error13 + + "\n tolerance: " + tolerance); + } + double zeroCpnBondTheoDirty1 = zeroCpnBondTheoValue1 + + zeroCpnBond1.accruedAmount(); double zeroCpnSpecializedBondTheoDirty1 = - zeroCpnSpecializedBondTheoValue1+ + zeroCpnSpecializedBondTheoValue1 + zeroCpnSpecializedBond1.accruedAmount(); double error14 = - Math.Abs(zeroCpnBondTheoDirty1-zeroCpnSpecializedBondTheoDirty1); - if (error14>tolerance) { + Math.Abs(zeroCpnBondTheoDirty1 - zeroCpnSpecializedBondTheoDirty1); + if (error14 > tolerance) + { QAssert.Fail("wrong dirty price for zero bond:" - + "\n generic zerocpn bond's dirty price: " - + zeroCpnBondTheoDirty1 - + "\n specialized zerocpn bond's clean price: " - + zeroCpnSpecializedBondTheoDirty1 - + "\n error: " + error14 - + "\n tolerance: " + tolerance); + + "\n generic zerocpn bond's dirty price: " + + zeroCpnBondTheoDirty1 + + "\n specialized zerocpn bond's clean price: " + + zeroCpnSpecializedBondTheoDirty1 + + "\n error: " + error14 + + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28) // maturity occurs on a business day - Date zeroCpnBondStartDate2 = new Date(17,Month.February,1998); - Date zeroCpnBondMaturityDate2 = new Date(17,Month.February,2028); + Date zeroCpnBondStartDate2 = new Date(17, Month.February, 1998); + Date zeroCpnBondMaturityDate2 = new Date(17, Month.February, 2028); Date zerocpbondRedemption2 = bondCalendar.adjust(zeroCpnBondMaturityDate2, - BusinessDayConvention.Following); - List zeroCpnBondLeg2 = new List{new SimpleCashFlow(100.0, zerocpbondRedemption2)}; + BusinessDayConvention.Following); + List zeroCpnBondLeg2 = new List {new SimpleCashFlow(100.0, zerocpbondRedemption2)}; // generic bond Bond zeroCpnBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - zeroCpnBondMaturityDate2, zeroCpnBondStartDate2, zeroCpnBondLeg2); + zeroCpnBondMaturityDate2, zeroCpnBondStartDate2, zeroCpnBondLeg2); zeroCpnBond2.setPricingEngine(bondEngine); // specialized zerocpn bond Bond zeroCpnSpecializedBond2 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount, - new Date(17,Month.February,2028), - BusinessDayConvention.Following, - 100.0, new Date(17,Month.February,1998)); + new Date(17, Month.February, 2028), + BusinessDayConvention.Following, + 100.0, new Date(17, Month.February, 1998)); zeroCpnSpecializedBond2.setPricingEngine(bondEngine); double zeroCpnBondTheoValue2 = zeroCpnBond2.cleanPrice(); @@ -2955,42 +3011,44 @@ public void testSpecializedBondVsGenericBond() zeroCpnSpecializedBond2.cleanPrice(); double error15 = - Math.Abs(zeroCpnBondTheoValue2 -zeroCpnSpecializedBondTheoValue2); - if (error15>tolerance) { + Math.Abs(zeroCpnBondTheoValue2 - zeroCpnSpecializedBondTheoValue2); + if (error15 > tolerance) + { QAssert.Fail("wrong clean price for zero coupon bond:" - + "\n generic zerocpn bond's clean price: " - + zeroCpnBondTheoValue2 - + "\n specialized zerocpn bond's clean price: " - + zeroCpnSpecializedBondTheoValue2 - + "\n error: " + error15 - + "\n tolerance: " + tolerance); + + "\n generic zerocpn bond's clean price: " + + zeroCpnBondTheoValue2 + + "\n specialized zerocpn bond's clean price: " + + zeroCpnSpecializedBondTheoValue2 + + "\n error: " + error15 + + "\n tolerance: " + tolerance); } - double zeroCpnBondTheoDirty2 = zeroCpnBondTheoValue2+ - zeroCpnBond2.accruedAmount(); + double zeroCpnBondTheoDirty2 = zeroCpnBondTheoValue2 + + zeroCpnBond2.accruedAmount(); double zeroCpnSpecializedBondTheoDirty2 = - zeroCpnSpecializedBondTheoValue2+ + zeroCpnSpecializedBondTheoValue2 + zeroCpnSpecializedBond2.accruedAmount(); double error16 = - Math.Abs(zeroCpnBondTheoDirty2-zeroCpnSpecializedBondTheoDirty2); - if (error16>tolerance) { + Math.Abs(zeroCpnBondTheoDirty2 - zeroCpnSpecializedBondTheoDirty2); + if (error16 > tolerance) + { QAssert.Fail("wrong dirty price for zero coupon bond:" - + "\n generic zerocpn bond's dirty price: " - + zeroCpnBondTheoDirty2 - + "\n specialized zerocpn bond's dirty price: " - + zeroCpnSpecializedBondTheoDirty2 - + "\n error: " + error16 - + "\n tolerance: " + tolerance); + + "\n generic zerocpn bond's dirty price: " + + zeroCpnBondTheoDirty2 + + "\n specialized zerocpn bond's dirty price: " + + zeroCpnSpecializedBondTheoDirty2 + + "\n error: " + error16 + + "\n tolerance: " + tolerance); } - } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testSpecializedBondVsGenericBondUsingAsw() + public void testSpecializedBondVsGenericBondUsingAsw() { // Testing asset-swap prices and spreads for specialized bond against equivalent generic bond... CommonVars vars = new CommonVars(); @@ -3004,752 +3062,768 @@ public void testSpecializedBondVsGenericBondUsingAsw() // Fixed bond (Isin: DE0001135275 DBR 4 01/04/37) // maturity doesn't occur on a business day - Date fixedBondStartDate1 = new Date(4,Month.January,2005); - Date fixedBondMaturityDate1 = new Date(4,Month.January,2037); + Date fixedBondStartDate1 = new Date(4, Month.January, 2005); + Date fixedBondMaturityDate1 = new Date(4, Month.January, 2037); Schedule fixedBondSchedule1 = new Schedule(fixedBondStartDate1, - fixedBondMaturityDate1, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + fixedBondMaturityDate1, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List fixedBondLeg1 = new FixedRateLeg(fixedBondSchedule1) - .withCouponRates(0.04, new ActualActual(ActualActual.Convention.ISDA)) - .withNotionals(vars.faceAmount); + .withCouponRates(0.04, new ActualActual(ActualActual.Convention.ISDA)) + .withNotionals(vars.faceAmount); Date fixedbondRedemption1 = bondCalendar.adjust(fixedBondMaturityDate1, BusinessDayConvention.Following); fixedBondLeg1.Add(new SimpleCashFlow(100.0, fixedbondRedemption1)); // generic bond Bond fixedBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - fixedBondMaturityDate1, fixedBondStartDate1, fixedBondLeg1); + fixedBondMaturityDate1, fixedBondStartDate1, fixedBondLeg1); IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure); IPricingEngine swapEngine = new DiscountingSwapEngine(vars.termStructure); fixedBond1.setPricingEngine(bondEngine); // equivalent specialized fixed rate bond Bond fixedSpecializedBond1 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule1, - new List{0.04}, - new ActualActual(ActualActual.Convention.ISDA), BusinessDayConvention.Following, - 100.0, new Date(4,Month.January,2005)); + new List {0.04}, + new ActualActual(ActualActual.Convention.ISDA), BusinessDayConvention.Following, + 100.0, new Date(4, Month.January, 2005)); fixedSpecializedBond1.setPricingEngine(bondEngine); double fixedBondPrice1 = fixedBond1.cleanPrice(); double fixedSpecializedBondPrice1 = fixedSpecializedBond1.cleanPrice(); AssetSwap fixedBondAssetSwap1 = new AssetSwap(payFixedRate, - fixedBond1, fixedBondPrice1, - vars.iborIndex, vars.nonnullspread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + fixedBond1, fixedBondPrice1, + vars.iborIndex, vars.nonnullspread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); fixedBondAssetSwap1.setPricingEngine(swapEngine); AssetSwap fixedSpecializedBondAssetSwap1 = new AssetSwap(payFixedRate, - fixedSpecializedBond1, - fixedSpecializedBondPrice1, - vars.iborIndex, - vars.nonnullspread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + fixedSpecializedBond1, + fixedSpecializedBondPrice1, + vars.iborIndex, + vars.nonnullspread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); fixedSpecializedBondAssetSwap1.setPricingEngine(swapEngine); double fixedBondAssetSwapPrice1 = fixedBondAssetSwap1.fairCleanPrice(); double fixedSpecializedBondAssetSwapPrice1 = fixedSpecializedBondAssetSwap1.fairCleanPrice(); double tolerance = 1.0e-13; double error1 = - Math.Abs(fixedBondAssetSwapPrice1-fixedSpecializedBondAssetSwapPrice1); - if (error1>tolerance) { + Math.Abs(fixedBondAssetSwapPrice1 - fixedSpecializedBondAssetSwapPrice1); + if (error1 > tolerance) + { QAssert.Fail("wrong clean price for fixed bond:" - + "\n generic fixed rate bond's clean price: " - + fixedBondAssetSwapPrice1 - + "\n equivalent specialized bond's clean price: " - + fixedSpecializedBondAssetSwapPrice1 - + "\n error: " + error1 - + "\n tolerance: " + tolerance); + + "\n generic fixed rate bond's clean price: " + + fixedBondAssetSwapPrice1 + + "\n equivalent specialized bond's clean price: " + + fixedSpecializedBondAssetSwapPrice1 + + "\n error: " + error1 + + "\n tolerance: " + tolerance); } // market executable price as of 4th sept 2007 - double fixedBondMktPrice1= 91.832; + double fixedBondMktPrice1 = 91.832; AssetSwap fixedBondASW1 = new AssetSwap(payFixedRate, - fixedBond1, fixedBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + fixedBond1, fixedBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); fixedBondASW1.setPricingEngine(swapEngine); AssetSwap fixedSpecializedBondASW1 = new AssetSwap(payFixedRate, - fixedSpecializedBond1, - fixedBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + fixedSpecializedBond1, + fixedBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); fixedSpecializedBondASW1.setPricingEngine(swapEngine); double fixedBondASWSpread1 = fixedBondASW1.fairSpread(); double fixedSpecializedBondASWSpread1 = fixedSpecializedBondASW1.fairSpread(); - double error2 = Math.Abs(fixedBondASWSpread1-fixedSpecializedBondASWSpread1); - if (error2>tolerance) { + double error2 = Math.Abs(fixedBondASWSpread1 - fixedSpecializedBondASWSpread1); + if (error2 > tolerance) + { QAssert.Fail("wrong asw spread for fixed bond:" - + "\n generic fixed rate bond's asw spread: " - + fixedBondASWSpread1 - + "\n equivalent specialized bond's asw spread: " - + fixedSpecializedBondASWSpread1 - + "\n error: " + error2 - + "\n tolerance: " + tolerance); + + "\n generic fixed rate bond's asw spread: " + + fixedBondASWSpread1 + + "\n equivalent specialized bond's asw spread: " + + fixedSpecializedBondASWSpread1 + + "\n error: " + error2 + + "\n tolerance: " + tolerance); } //Fixed bond (Isin: IT0006527060 IBRD 5 02/05/19) //maturity occurs on a business day - Date fixedBondStartDate2 = new Date(5,Month.February,2005); - Date fixedBondMaturityDate2 = new Date(5,Month.February,2019); - Schedule fixedBondSchedule2= new Schedule(fixedBondStartDate2, - fixedBondMaturityDate2, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date fixedBondStartDate2 = new Date(5, Month.February, 2005); + Date fixedBondMaturityDate2 = new Date(5, Month.February, 2019); + Schedule fixedBondSchedule2 = new Schedule(fixedBondStartDate2, + fixedBondMaturityDate2, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List fixedBondLeg2 = new FixedRateLeg(fixedBondSchedule2) - .withCouponRates(0.05, new Thirty360(Thirty360.Thirty360Convention.BondBasis)) - .withNotionals(vars.faceAmount); + .withCouponRates(0.05, new Thirty360(Thirty360.Thirty360Convention.BondBasis)) + .withNotionals(vars.faceAmount); Date fixedbondRedemption2 = bondCalendar.adjust(fixedBondMaturityDate2, BusinessDayConvention.Following); fixedBondLeg2.Add(new SimpleCashFlow(100.0, fixedbondRedemption2)); // generic bond Bond fixedBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - fixedBondMaturityDate2, fixedBondStartDate2, fixedBondLeg2); + fixedBondMaturityDate2, fixedBondStartDate2, fixedBondLeg2); fixedBond2.setPricingEngine(bondEngine); // equivalent specialized fixed rate bond Bond fixedSpecializedBond2 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule2, - new List{ 0.05}, - new Thirty360(Thirty360.Thirty360Convention.BondBasis), BusinessDayConvention.Following, - 100.0, new Date(5,Month.February,2005)); + new List { 0.05}, + new Thirty360(Thirty360.Thirty360Convention.BondBasis), BusinessDayConvention.Following, + 100.0, new Date(5, Month.February, 2005)); fixedSpecializedBond2.setPricingEngine(bondEngine); double fixedBondPrice2 = fixedBond2.cleanPrice(); double fixedSpecializedBondPrice2 = fixedSpecializedBond2.cleanPrice(); AssetSwap fixedBondAssetSwap2 = new AssetSwap(payFixedRate, - fixedBond2, fixedBondPrice2, - vars.iborIndex, vars.nonnullspread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + fixedBond2, fixedBondPrice2, + vars.iborIndex, vars.nonnullspread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); fixedBondAssetSwap2.setPricingEngine(swapEngine); AssetSwap fixedSpecializedBondAssetSwap2 = new AssetSwap(payFixedRate, - fixedSpecializedBond2, - fixedSpecializedBondPrice2, - vars.iborIndex, - vars.nonnullspread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + fixedSpecializedBond2, + fixedSpecializedBondPrice2, + vars.iborIndex, + vars.nonnullspread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); fixedSpecializedBondAssetSwap2.setPricingEngine(swapEngine); double fixedBondAssetSwapPrice2 = fixedBondAssetSwap2.fairCleanPrice(); double fixedSpecializedBondAssetSwapPrice2 = fixedSpecializedBondAssetSwap2.fairCleanPrice(); - double error3 = Math.Abs(fixedBondAssetSwapPrice2-fixedSpecializedBondAssetSwapPrice2); - if (error3>tolerance) { + double error3 = Math.Abs(fixedBondAssetSwapPrice2 - fixedSpecializedBondAssetSwapPrice2); + if (error3 > tolerance) + { QAssert.Fail("wrong clean price for fixed bond:" - + "\n generic fixed rate bond's clean price: " - + fixedBondAssetSwapPrice2 - + "\n equivalent specialized bond's clean price: " - + fixedSpecializedBondAssetSwapPrice2 - + "\n error: " + error3 - + "\n tolerance: " + tolerance); + + "\n generic fixed rate bond's clean price: " + + fixedBondAssetSwapPrice2 + + "\n equivalent specialized bond's clean price: " + + fixedSpecializedBondAssetSwapPrice2 + + "\n error: " + error3 + + "\n tolerance: " + tolerance); } // market executable price as of 4th sept 2007 - double fixedBondMktPrice2= 102.178; + double fixedBondMktPrice2 = 102.178; AssetSwap fixedBondASW2 = new AssetSwap(payFixedRate, - fixedBond2, fixedBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + fixedBond2, fixedBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); fixedBondASW2.setPricingEngine(swapEngine); AssetSwap fixedSpecializedBondASW2 = new AssetSwap(payFixedRate, - fixedSpecializedBond2, - fixedBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + fixedSpecializedBond2, + fixedBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); fixedSpecializedBondASW2.setPricingEngine(swapEngine); double fixedBondASWSpread2 = fixedBondASW2.fairSpread(); double fixedSpecializedBondASWSpread2 = fixedSpecializedBondASW2.fairSpread(); - double error4 = Math.Abs(fixedBondASWSpread2-fixedSpecializedBondASWSpread2); - if (error4>tolerance) { + double error4 = Math.Abs(fixedBondASWSpread2 - fixedSpecializedBondASWSpread2); + if (error4 > tolerance) + { QAssert.Fail("wrong asw spread for fixed bond:" - + "\n generic fixed rate bond's asw spread: " - + fixedBondASWSpread2 - + "\n equivalent specialized bond's asw spread: " - + fixedSpecializedBondASWSpread2 - + "\n error: " + error4 - + "\n tolerance: " + tolerance); + + "\n generic fixed rate bond's asw spread: " + + fixedBondASWSpread2 + + "\n equivalent specialized bond's asw spread: " + + fixedSpecializedBondASWSpread2 + + "\n error: " + error4 + + "\n tolerance: " + tolerance); } //FRN bond (Isin: IT0003543847 ISPIM 0 09/29/13) //maturity doesn't occur on a business day - Date floatingBondStartDate1 = new Date(29,Month.September,2003); - Date floatingBondMaturityDate1 = new Date(29,Month.September,2013); - Schedule floatingBondSchedule1= new Schedule(floatingBondStartDate1, - floatingBondMaturityDate1, - new Period(Frequency.Semiannual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date floatingBondStartDate1 = new Date(29, Month.September, 2003); + Date floatingBondMaturityDate1 = new Date(29, Month.September, 2013); + Schedule floatingBondSchedule1 = new Schedule(floatingBondStartDate1, + floatingBondMaturityDate1, + new Period(Frequency.Semiannual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List floatingBondLeg1 = new IborLeg(floatingBondSchedule1, vars.iborIndex) - .withPaymentDayCounter(new Actual360()) - .withFixingDays(fixingDays) - .withSpreads(0.0056) - .inArrears(inArrears) - .withNotionals(vars.faceAmount); + .withPaymentDayCounter(new Actual360()) + .withFixingDays(fixingDays) + .withSpreads(0.0056) + .inArrears(inArrears) + .withNotionals(vars.faceAmount); Date floatingbondRedemption1 = bondCalendar.adjust(floatingBondMaturityDate1, BusinessDayConvention.Following); floatingBondLeg1.Add(new SimpleCashFlow(100.0, floatingbondRedemption1)); // generic bond Bond floatingBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - floatingBondMaturityDate1, floatingBondStartDate1, floatingBondLeg1); + floatingBondMaturityDate1, floatingBondStartDate1, floatingBondLeg1); floatingBond1.setPricingEngine(bondEngine); // equivalent specialized floater Bond floatingSpecializedBond1 = new FloatingRateBond(settlementDays, vars.faceAmount, - floatingBondSchedule1, - vars.iborIndex, new Actual360(), - BusinessDayConvention.Following, fixingDays, - new List{1}, - new List{0.0056}, - new List(), new List(), - inArrears, - 100.0, new Date(29,Month.September,2003)); + floatingBondSchedule1, + vars.iborIndex, new Actual360(), + BusinessDayConvention.Following, fixingDays, + new List {1}, + new List {0.0056}, + new List < double? >(), new List < double? >(), + inArrears, + 100.0, new Date(29, Month.September, 2003)); floatingSpecializedBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer); Utils.setCouponPricer(floatingSpecializedBond1.cashflows(), vars.pricer); - vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402); + vars.iborIndex.addFixing(new Date(27, Month.March, 2007), 0.0402); double floatingBondPrice1 = floatingBond1.cleanPrice(); - double floatingSpecializedBondPrice1= floatingSpecializedBond1.cleanPrice(); - AssetSwap floatingBondAssetSwap1= new AssetSwap(payFixedRate, - floatingBond1, floatingBondPrice1, - vars.iborIndex, vars.nonnullspread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + double floatingSpecializedBondPrice1 = floatingSpecializedBond1.cleanPrice(); + AssetSwap floatingBondAssetSwap1 = new AssetSwap(payFixedRate, + floatingBond1, floatingBondPrice1, + vars.iborIndex, vars.nonnullspread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); floatingBondAssetSwap1.setPricingEngine(swapEngine); - AssetSwap floatingSpecializedBondAssetSwap1= new AssetSwap(payFixedRate, - floatingSpecializedBond1, - floatingSpecializedBondPrice1, - vars.iborIndex, - vars.nonnullspread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap floatingSpecializedBondAssetSwap1 = new AssetSwap(payFixedRate, + floatingSpecializedBond1, + floatingSpecializedBondPrice1, + vars.iborIndex, + vars.nonnullspread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); floatingSpecializedBondAssetSwap1.setPricingEngine(swapEngine); double floatingBondAssetSwapPrice1 = floatingBondAssetSwap1.fairCleanPrice(); double floatingSpecializedBondAssetSwapPrice1 = floatingSpecializedBondAssetSwap1.fairCleanPrice(); double error5 = - Math.Abs(floatingBondAssetSwapPrice1-floatingSpecializedBondAssetSwapPrice1); - if (error5>tolerance) { + Math.Abs(floatingBondAssetSwapPrice1 - floatingSpecializedBondAssetSwapPrice1); + if (error5 > tolerance) + { QAssert.Fail("wrong clean price for frnbond:" - + "\n generic frn rate bond's clean price: " - + floatingBondAssetSwapPrice1 - + "\n equivalent specialized bond's price: " - + floatingSpecializedBondAssetSwapPrice1 - + "\n error: " + error5 - + "\n tolerance: " + tolerance); + + "\n generic frn rate bond's clean price: " + + floatingBondAssetSwapPrice1 + + "\n equivalent specialized bond's price: " + + floatingSpecializedBondAssetSwapPrice1 + + "\n error: " + error5 + + "\n tolerance: " + tolerance); } // market executable price as of 4th sept 2007 - double floatingBondMktPrice1= 101.33; - AssetSwap floatingBondASW1= new AssetSwap(payFixedRate, - floatingBond1, floatingBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + double floatingBondMktPrice1 = 101.33; + AssetSwap floatingBondASW1 = new AssetSwap(payFixedRate, + floatingBond1, floatingBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); floatingBondASW1.setPricingEngine(swapEngine); - AssetSwap floatingSpecializedBondASW1= new AssetSwap(payFixedRate, - floatingSpecializedBond1, - floatingBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap floatingSpecializedBondASW1 = new AssetSwap(payFixedRate, + floatingSpecializedBond1, + floatingBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); floatingSpecializedBondASW1.setPricingEngine(swapEngine); double floatingBondASWSpread1 = floatingBondASW1.fairSpread(); double floatingSpecializedBondASWSpread1 = floatingSpecializedBondASW1.fairSpread(); double error6 = - Math.Abs(floatingBondASWSpread1-floatingSpecializedBondASWSpread1); - if (error6>tolerance) { + Math.Abs(floatingBondASWSpread1 - floatingSpecializedBondASWSpread1); + if (error6 > tolerance) + { QAssert.Fail("wrong asw spread for fixed bond:" - + "\n generic frn rate bond's asw spread: " - + floatingBondASWSpread1 - + "\n equivalent specialized bond's asw spread: " - + floatingSpecializedBondASWSpread1 - + "\n error: " + error6 - + "\n tolerance: " + tolerance); + + "\n generic frn rate bond's asw spread: " + + floatingBondASWSpread1 + + "\n equivalent specialized bond's asw spread: " + + floatingSpecializedBondASWSpread1 + + "\n error: " + error6 + + "\n tolerance: " + tolerance); } //FRN bond (Isin: XS0090566539 COE 0 09/24/18) //maturity occurs on a business day - Date floatingBondStartDate2 = new Date(24,Month.September,2004); - Date floatingBondMaturityDate2 = new Date(24,Month.September,2018); - Schedule floatingBondSchedule2= new Schedule(floatingBondStartDate2, - floatingBondMaturityDate2, - new Period(Frequency.Semiannual), bondCalendar, - BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, - DateGeneration.Rule.Backward, false); + Date floatingBondStartDate2 = new Date(24, Month.September, 2004); + Date floatingBondMaturityDate2 = new Date(24, Month.September, 2018); + Schedule floatingBondSchedule2 = new Schedule(floatingBondStartDate2, + floatingBondMaturityDate2, + new Period(Frequency.Semiannual), bondCalendar, + BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, + DateGeneration.Rule.Backward, false); List floatingBondLeg2 = new IborLeg(floatingBondSchedule2, vars.iborIndex) - .withPaymentDayCounter(new Actual360()) - .withFixingDays(fixingDays) - .withSpreads(0.0025) - .inArrears(inArrears) - .withPaymentAdjustment(BusinessDayConvention.ModifiedFollowing) - .withNotionals(vars.faceAmount); + .withPaymentDayCounter(new Actual360()) + .withFixingDays(fixingDays) + .withSpreads(0.0025) + .inArrears(inArrears) + .withPaymentAdjustment(BusinessDayConvention.ModifiedFollowing) + .withNotionals(vars.faceAmount); Date floatingbondRedemption2 = bondCalendar.adjust(floatingBondMaturityDate2, BusinessDayConvention.ModifiedFollowing); floatingBondLeg2.Add(new SimpleCashFlow(100.0, floatingbondRedemption2)); // generic bond Bond floatingBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - floatingBondMaturityDate2, floatingBondStartDate2,floatingBondLeg2); + floatingBondMaturityDate2, floatingBondStartDate2, floatingBondLeg2); floatingBond2.setPricingEngine(bondEngine); // equivalent specialized floater Bond floatingSpecializedBond2 = new FloatingRateBond(settlementDays, vars.faceAmount, - floatingBondSchedule2, - vars.iborIndex, new Actual360(), - BusinessDayConvention.ModifiedFollowing, fixingDays, - new List{1}, - new List{0.0025}, - new List(), new List(), - inArrears, - 100.0, new Date(24,Month.September,2004)); + floatingBondSchedule2, + vars.iborIndex, new Actual360(), + BusinessDayConvention.ModifiedFollowing, fixingDays, + new List {1}, + new List {0.0025}, + new List < double? >(), new List < double? >(), + inArrears, + 100.0, new Date(24, Month.September, 2004)); floatingSpecializedBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer); Utils.setCouponPricer(floatingSpecializedBond2.cashflows(), vars.pricer); - vars.iborIndex.addFixing(new Date(22,Month.March,2007), 0.04013); + vars.iborIndex.addFixing(new Date(22, Month.March, 2007), 0.04013); double floatingBondPrice2 = floatingBond2.cleanPrice(); - double floatingSpecializedBondPrice2= floatingSpecializedBond2.cleanPrice(); - AssetSwap floatingBondAssetSwap2= new AssetSwap(payFixedRate, - floatingBond2, floatingBondPrice2, - vars.iborIndex, vars.nonnullspread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + double floatingSpecializedBondPrice2 = floatingSpecializedBond2.cleanPrice(); + AssetSwap floatingBondAssetSwap2 = new AssetSwap(payFixedRate, + floatingBond2, floatingBondPrice2, + vars.iborIndex, vars.nonnullspread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); floatingBondAssetSwap2.setPricingEngine(swapEngine); - AssetSwap floatingSpecializedBondAssetSwap2= new AssetSwap(payFixedRate, - floatingSpecializedBond2, - floatingSpecializedBondPrice2, - vars.iborIndex, - vars.nonnullspread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap floatingSpecializedBondAssetSwap2 = new AssetSwap(payFixedRate, + floatingSpecializedBond2, + floatingSpecializedBondPrice2, + vars.iborIndex, + vars.nonnullspread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); floatingSpecializedBondAssetSwap2.setPricingEngine(swapEngine); double floatingBondAssetSwapPrice2 = floatingBondAssetSwap2.fairCleanPrice(); double floatingSpecializedBondAssetSwapPrice2 = floatingSpecializedBondAssetSwap2.fairCleanPrice(); double error7 = - Math.Abs(floatingBondAssetSwapPrice2-floatingSpecializedBondAssetSwapPrice2); - if (error7>tolerance) { + Math.Abs(floatingBondAssetSwapPrice2 - floatingSpecializedBondAssetSwapPrice2); + if (error7 > tolerance) + { QAssert.Fail("wrong clean price for frnbond:" - + "\n generic frn rate bond's clean price: " - + floatingBondAssetSwapPrice2 - + "\n equivalent specialized frn bond's price: " - + floatingSpecializedBondAssetSwapPrice2 - + "\n error: " + error7 - + "\n tolerance: " + tolerance); + + "\n generic frn rate bond's clean price: " + + floatingBondAssetSwapPrice2 + + "\n equivalent specialized frn bond's price: " + + floatingSpecializedBondAssetSwapPrice2 + + "\n error: " + error7 + + "\n tolerance: " + tolerance); } // market executable price as of 4th sept 2007 double floatingBondMktPrice2 = 101.26; - AssetSwap floatingBondASW2= new AssetSwap(payFixedRate, - floatingBond2, floatingBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap floatingBondASW2 = new AssetSwap(payFixedRate, + floatingBond2, floatingBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); floatingBondASW2.setPricingEngine(swapEngine); - AssetSwap floatingSpecializedBondASW2= new AssetSwap(payFixedRate, - floatingSpecializedBond2, - floatingBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap floatingSpecializedBondASW2 = new AssetSwap(payFixedRate, + floatingSpecializedBond2, + floatingBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); floatingSpecializedBondASW2.setPricingEngine(swapEngine); double floatingBondASWSpread2 = floatingBondASW2.fairSpread(); double floatingSpecializedBondASWSpread2 = floatingSpecializedBondASW2.fairSpread(); double error8 = - Math.Abs(floatingBondASWSpread2-floatingSpecializedBondASWSpread2); - if (error8>tolerance) { + Math.Abs(floatingBondASWSpread2 - floatingSpecializedBondASWSpread2); + if (error8 > tolerance) + { QAssert.Fail("wrong asw spread for frn bond:" - + "\n generic frn rate bond's asw spread: " - + floatingBondASWSpread2 - + "\n equivalent specialized bond's asw spread: " - + floatingSpecializedBondASWSpread2 - + "\n error: " + error8 - + "\n tolerance: " + tolerance); + + "\n generic frn rate bond's asw spread: " + + floatingBondASWSpread2 + + "\n equivalent specialized bond's asw spread: " + + floatingSpecializedBondASWSpread2 + + "\n error: " + error8 + + "\n tolerance: " + tolerance); } // CMS bond (Isin: XS0228052402 CRDIT 0 8/22/20) // maturity doesn't occur on a business day - Date cmsBondStartDate1 = new Date(22,Month.August,2005); - Date cmsBondMaturityDate1 = new Date(22,Month.August,2020); - Schedule cmsBondSchedule1= new Schedule(cmsBondStartDate1, - cmsBondMaturityDate1, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date cmsBondStartDate1 = new Date(22, Month.August, 2005); + Date cmsBondMaturityDate1 = new Date(22, Month.August, 2020); + Schedule cmsBondSchedule1 = new Schedule(cmsBondStartDate1, + cmsBondMaturityDate1, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List cmsBondLeg1 = new CmsLeg(cmsBondSchedule1, vars.swapIndex) - .withPaymentDayCounter(new Thirty360()) - .withFixingDays(fixingDays) - .withCaps(0.055) - .withFloors(0.025) - .inArrears(inArrears) - .withNotionals(vars.faceAmount); + .withPaymentDayCounter(new Thirty360()) + .withFixingDays(fixingDays) + .withCaps(0.055) + .withFloors(0.025) + .inArrears(inArrears) + .withNotionals(vars.faceAmount); Date cmsbondRedemption1 = bondCalendar.adjust(cmsBondMaturityDate1, BusinessDayConvention.Following); cmsBondLeg1.Add(new SimpleCashFlow(100.0, cmsbondRedemption1)); // generic cms bond Bond cmsBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - cmsBondMaturityDate1, cmsBondStartDate1, cmsBondLeg1); + cmsBondMaturityDate1, cmsBondStartDate1, cmsBondLeg1); cmsBond1.setPricingEngine(bondEngine); // equivalent specialized cms bond Bond cmsSpecializedBond1 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule1, - vars.swapIndex, new Thirty360(), - BusinessDayConvention.Following, fixingDays, - new List{1.0}, new List{0.0}, - new List{0.055}, new List{0.025}, - inArrears, - 100.0, new Date(22,Month.August,2005)); + vars.swapIndex, new Thirty360(), + BusinessDayConvention.Following, fixingDays, + new List {1.0}, new List {0.0}, + new List < double? > {0.055}, new List < double? > {0.025}, + inArrears, + 100.0, new Date(22, Month.August, 2005)); cmsSpecializedBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer); Utils.setCouponPricer(cmsSpecializedBond1.cashflows(), vars.cmspricer); - vars.swapIndex.addFixing(new Date(18,Month.August,2006), 0.04158); + vars.swapIndex.addFixing(new Date(18, Month.August, 2006), 0.04158); double cmsBondPrice1 = cmsBond1.cleanPrice(); double cmsSpecializedBondPrice1 = cmsSpecializedBond1.cleanPrice(); - AssetSwap cmsBondAssetSwap1= new AssetSwap(payFixedRate,cmsBond1, cmsBondPrice1, - vars.iborIndex, vars.nonnullspread, - null,vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap cmsBondAssetSwap1 = new AssetSwap(payFixedRate, cmsBond1, cmsBondPrice1, + vars.iborIndex, vars.nonnullspread, + null, vars.iborIndex.dayCounter(), + parAssetSwap); cmsBondAssetSwap1.setPricingEngine(swapEngine); - AssetSwap cmsSpecializedBondAssetSwap1= new AssetSwap(payFixedRate,cmsSpecializedBond1, - cmsSpecializedBondPrice1, - vars.iborIndex, - vars.nonnullspread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap cmsSpecializedBondAssetSwap1 = new AssetSwap(payFixedRate, cmsSpecializedBond1, + cmsSpecializedBondPrice1, + vars.iborIndex, + vars.nonnullspread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); cmsSpecializedBondAssetSwap1.setPricingEngine(swapEngine); double cmsBondAssetSwapPrice1 = cmsBondAssetSwap1.fairCleanPrice(); double cmsSpecializedBondAssetSwapPrice1 = cmsSpecializedBondAssetSwap1.fairCleanPrice(); double error9 = - Math.Abs(cmsBondAssetSwapPrice1-cmsSpecializedBondAssetSwapPrice1); - if (error9>tolerance) { + Math.Abs(cmsBondAssetSwapPrice1 - cmsSpecializedBondAssetSwapPrice1); + if (error9 > tolerance) + { QAssert.Fail("wrong clean price for cmsbond:" - + "\n generic bond's clean price: " - + cmsBondAssetSwapPrice1 - + "\n equivalent specialized cms rate bond's price: " - + cmsSpecializedBondAssetSwapPrice1 - + "\n error: " + error9 - + "\n tolerance: " + tolerance); + + "\n generic bond's clean price: " + + cmsBondAssetSwapPrice1 + + "\n equivalent specialized cms rate bond's price: " + + cmsSpecializedBondAssetSwapPrice1 + + "\n error: " + error9 + + "\n tolerance: " + tolerance); } double cmsBondMktPrice1 = 87.02;// market executable price as of 4th sept 2007 - AssetSwap cmsBondASW1= new AssetSwap(payFixedRate, - cmsBond1, cmsBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap cmsBondASW1 = new AssetSwap(payFixedRate, + cmsBond1, cmsBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); cmsBondASW1.setPricingEngine(swapEngine); - AssetSwap cmsSpecializedBondASW1= new AssetSwap(payFixedRate, - cmsSpecializedBond1, - cmsBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap cmsSpecializedBondASW1 = new AssetSwap(payFixedRate, + cmsSpecializedBond1, + cmsBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); cmsSpecializedBondASW1.setPricingEngine(swapEngine); double cmsBondASWSpread1 = cmsBondASW1.fairSpread(); double cmsSpecializedBondASWSpread1 = cmsSpecializedBondASW1.fairSpread(); - double error10 = Math.Abs(cmsBondASWSpread1-cmsSpecializedBondASWSpread1); - if (error10>tolerance) { + double error10 = Math.Abs(cmsBondASWSpread1 - cmsSpecializedBondASWSpread1); + if (error10 > tolerance) + { QAssert.Fail("wrong asw spread for cm bond:" - + "\n generic cms rate bond's asw spread: " - + cmsBondASWSpread1 - + "\n equivalent specialized bond's asw spread: " - + cmsSpecializedBondASWSpread1 - + "\n error: " + error10 - + "\n tolerance: " + tolerance); + + "\n generic cms rate bond's asw spread: " + + cmsBondASWSpread1 + + "\n equivalent specialized bond's asw spread: " + + cmsSpecializedBondASWSpread1 + + "\n error: " + error10 + + "\n tolerance: " + tolerance); } //CMS bond (Isin: XS0218766664 ISPIM 0 5/6/15) //maturity occurs on a business day - Date cmsBondStartDate2 = new Date(06,Month.May,2005); - Date cmsBondMaturityDate2 = new Date(06,Month.May,2015); - Schedule cmsBondSchedule2= new Schedule(cmsBondStartDate2, - cmsBondMaturityDate2, - new Period(Frequency.Annual), bondCalendar, - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Date cmsBondStartDate2 = new Date(06, Month.May, 2005); + Date cmsBondMaturityDate2 = new Date(06, Month.May, 2015); + Schedule cmsBondSchedule2 = new Schedule(cmsBondStartDate2, + cmsBondMaturityDate2, + new Period(Frequency.Annual), bondCalendar, + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); List cmsBondLeg2 = new CmsLeg(cmsBondSchedule2, vars.swapIndex) - .withPaymentDayCounter(new Thirty360()) - .withFixingDays(fixingDays) - .withGearings(0.84) - .inArrears(inArrears) - .withNotionals(vars.faceAmount); + .withPaymentDayCounter(new Thirty360()) + .withFixingDays(fixingDays) + .withGearings(0.84) + .inArrears(inArrears) + .withNotionals(vars.faceAmount); Date cmsbondRedemption2 = bondCalendar.adjust(cmsBondMaturityDate2, - BusinessDayConvention.Following); + BusinessDayConvention.Following); cmsBondLeg2.Add(new SimpleCashFlow(100.0, cmsbondRedemption2)); // generic bond Bond cmsBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - cmsBondMaturityDate2, cmsBondStartDate2, cmsBondLeg2); + cmsBondMaturityDate2, cmsBondStartDate2, cmsBondLeg2); cmsBond2.setPricingEngine(bondEngine); // equivalent specialized cms bond Bond cmsSpecializedBond2 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule2, - vars.swapIndex, new Thirty360(), - BusinessDayConvention.Following, fixingDays, - new List{0.84}, new List{0.0}, - new List(), new List(), - inArrears, - 100.0, new Date(06,Month.May,2005)); + vars.swapIndex, new Thirty360(), + BusinessDayConvention.Following, fixingDays, + new List {0.84}, new List {0.0}, + new List < double? >(), new List < double? >(), + inArrears, + 100.0, new Date(06, Month.May, 2005)); cmsSpecializedBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer); Utils.setCouponPricer(cmsSpecializedBond2.cashflows(), vars.cmspricer); - vars.swapIndex.addFixing(new Date(04,Month.May,2006), 0.04217); + vars.swapIndex.addFixing(new Date(04, Month.May, 2006), 0.04217); double cmsBondPrice2 = cmsBond2.cleanPrice(); double cmsSpecializedBondPrice2 = cmsSpecializedBond2.cleanPrice(); - AssetSwap cmsBondAssetSwap2= new AssetSwap(payFixedRate,cmsBond2, cmsBondPrice2, - vars.iborIndex, vars.nonnullspread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap cmsBondAssetSwap2 = new AssetSwap(payFixedRate, cmsBond2, cmsBondPrice2, + vars.iborIndex, vars.nonnullspread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); cmsBondAssetSwap2.setPricingEngine(swapEngine); - AssetSwap cmsSpecializedBondAssetSwap2= new AssetSwap(payFixedRate,cmsSpecializedBond2, - cmsSpecializedBondPrice2, - vars.iborIndex, - vars.nonnullspread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap cmsSpecializedBondAssetSwap2 = new AssetSwap(payFixedRate, cmsSpecializedBond2, + cmsSpecializedBondPrice2, + vars.iborIndex, + vars.nonnullspread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); cmsSpecializedBondAssetSwap2.setPricingEngine(swapEngine); double cmsBondAssetSwapPrice2 = cmsBondAssetSwap2.fairCleanPrice(); double cmsSpecializedBondAssetSwapPrice2 = cmsSpecializedBondAssetSwap2.fairCleanPrice(); double error11 = - Math.Abs(cmsBondAssetSwapPrice2-cmsSpecializedBondAssetSwapPrice2); - if (error11>tolerance) { + Math.Abs(cmsBondAssetSwapPrice2 - cmsSpecializedBondAssetSwapPrice2); + if (error11 > tolerance) + { QAssert.Fail("wrong clean price for cmsbond:" - + "\n generic bond's clean price: " - + cmsBondAssetSwapPrice2 - + "\n equivalent specialized cms rate bond's price: " - + cmsSpecializedBondAssetSwapPrice2 - + "\n error: " + error11 - + "\n tolerance: " + tolerance); + + "\n generic bond's clean price: " + + cmsBondAssetSwapPrice2 + + "\n equivalent specialized cms rate bond's price: " + + cmsSpecializedBondAssetSwapPrice2 + + "\n error: " + error11 + + "\n tolerance: " + tolerance); } double cmsBondMktPrice2 = 94.35;// market executable price as of 4th sept 2007 - AssetSwap cmsBondASW2= new AssetSwap(payFixedRate, - cmsBond2, cmsBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap cmsBondASW2 = new AssetSwap(payFixedRate, + cmsBond2, cmsBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); cmsBondASW2.setPricingEngine(swapEngine); - AssetSwap cmsSpecializedBondASW2= new AssetSwap(payFixedRate, - cmsSpecializedBond2, - cmsBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap cmsSpecializedBondASW2 = new AssetSwap(payFixedRate, + cmsSpecializedBond2, + cmsBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); cmsSpecializedBondASW2.setPricingEngine(swapEngine); double cmsBondASWSpread2 = cmsBondASW2.fairSpread(); double cmsSpecializedBondASWSpread2 = cmsSpecializedBondASW2.fairSpread(); - double error12 = Math.Abs(cmsBondASWSpread2-cmsSpecializedBondASWSpread2); - if (error12>tolerance) { + double error12 = Math.Abs(cmsBondASWSpread2 - cmsSpecializedBondASWSpread2); + if (error12 > tolerance) + { QAssert.Fail("wrong asw spread for cm bond:" - + "\n generic cms rate bond's asw spread: " - + cmsBondASWSpread2 - + "\n equivalent specialized bond's asw spread: " - + cmsSpecializedBondASWSpread2 - + "\n error: " + error12 - + "\n tolerance: " + tolerance); + + "\n generic cms rate bond's asw spread: " + + cmsBondASWSpread2 + + "\n equivalent specialized bond's asw spread: " + + cmsSpecializedBondASWSpread2 + + "\n error: " + error12 + + "\n tolerance: " + tolerance); } - // Zero-Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15) - // maturity doesn't occur on a business day - Date zeroCpnBondStartDate1 = new Date(19,Month.December,1985); - Date zeroCpnBondMaturityDate1 = new Date(20,Month.December,2015); + // Zero-Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15) + // maturity doesn't occur on a business day + Date zeroCpnBondStartDate1 = new Date(19, Month.December, 1985); + Date zeroCpnBondMaturityDate1 = new Date(20, Month.December, 2015); Date zeroCpnBondRedemption1 = bondCalendar.adjust(zeroCpnBondMaturityDate1, - BusinessDayConvention.Following); - List zeroCpnBondLeg1 = new List{new SimpleCashFlow(100.0, zeroCpnBondRedemption1)}; + BusinessDayConvention.Following); + List zeroCpnBondLeg1 = new List {new SimpleCashFlow(100.0, zeroCpnBondRedemption1)}; // generic bond Bond zeroCpnBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - zeroCpnBondMaturityDate1, zeroCpnBondStartDate1, zeroCpnBondLeg1); + zeroCpnBondMaturityDate1, zeroCpnBondStartDate1, zeroCpnBondLeg1); zeroCpnBond1.setPricingEngine(bondEngine); // specialized zerocpn bond - Bond zeroCpnSpecializedBond1= new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount, - new Date(20,Month.December,2015), - BusinessDayConvention.Following, - 100.0, new Date(19,Month.December,1985)); + Bond zeroCpnSpecializedBond1 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount, + new Date(20, Month.December, 2015), + BusinessDayConvention.Following, + 100.0, new Date(19, Month.December, 1985)); zeroCpnSpecializedBond1.setPricingEngine(bondEngine); double zeroCpnBondPrice1 = zeroCpnBond1.cleanPrice(); double zeroCpnSpecializedBondPrice1 = zeroCpnSpecializedBond1.cleanPrice(); - AssetSwap zeroCpnBondAssetSwap1= new AssetSwap(payFixedRate,zeroCpnBond1, - zeroCpnBondPrice1, - vars.iborIndex, vars.nonnullspread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap zeroCpnBondAssetSwap1 = new AssetSwap(payFixedRate, zeroCpnBond1, + zeroCpnBondPrice1, + vars.iborIndex, vars.nonnullspread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); zeroCpnBondAssetSwap1.setPricingEngine(swapEngine); - AssetSwap zeroCpnSpecializedBondAssetSwap1= new AssetSwap(payFixedRate, - zeroCpnSpecializedBond1, - zeroCpnSpecializedBondPrice1, - vars.iborIndex, - vars.nonnullspread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap zeroCpnSpecializedBondAssetSwap1 = new AssetSwap(payFixedRate, + zeroCpnSpecializedBond1, + zeroCpnSpecializedBondPrice1, + vars.iborIndex, + vars.nonnullspread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); zeroCpnSpecializedBondAssetSwap1.setPricingEngine(swapEngine); double zeroCpnBondAssetSwapPrice1 = zeroCpnBondAssetSwap1.fairCleanPrice(); double zeroCpnSpecializedBondAssetSwapPrice1 = zeroCpnSpecializedBondAssetSwap1.fairCleanPrice(); double error13 = - Math.Abs(zeroCpnBondAssetSwapPrice1-zeroCpnSpecializedBondAssetSwapPrice1); - if (error13>tolerance) { + Math.Abs(zeroCpnBondAssetSwapPrice1 - zeroCpnSpecializedBondAssetSwapPrice1); + if (error13 > tolerance) + { QAssert.Fail("wrong clean price for zerocpn bond:" - + "\n generic zero cpn bond's clean price: " - + zeroCpnBondAssetSwapPrice1 - + "\n specialized equivalent bond's price: " - + zeroCpnSpecializedBondAssetSwapPrice1 - + "\n error: " + error13 - + "\n tolerance: " + tolerance); + + "\n generic zero cpn bond's clean price: " + + zeroCpnBondAssetSwapPrice1 + + "\n specialized equivalent bond's price: " + + zeroCpnSpecializedBondAssetSwapPrice1 + + "\n error: " + error13 + + "\n tolerance: " + tolerance); } // market executable price as of 4th sept 2007 double zeroCpnBondMktPrice1 = 72.277; - AssetSwap zeroCpnBondASW1= new AssetSwap(payFixedRate, - zeroCpnBond1,zeroCpnBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap zeroCpnBondASW1 = new AssetSwap(payFixedRate, + zeroCpnBond1, zeroCpnBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); zeroCpnBondASW1.setPricingEngine(swapEngine); - AssetSwap zeroCpnSpecializedBondASW1= new AssetSwap(payFixedRate, - zeroCpnSpecializedBond1, - zeroCpnBondMktPrice1, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap zeroCpnSpecializedBondASW1 = new AssetSwap(payFixedRate, + zeroCpnSpecializedBond1, + zeroCpnBondMktPrice1, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); zeroCpnSpecializedBondASW1.setPricingEngine(swapEngine); double zeroCpnBondASWSpread1 = zeroCpnBondASW1.fairSpread(); double zeroCpnSpecializedBondASWSpread1 = zeroCpnSpecializedBondASW1.fairSpread(); double error14 = - Math.Abs(zeroCpnBondASWSpread1-zeroCpnSpecializedBondASWSpread1); - if (error14>tolerance) { + Math.Abs(zeroCpnBondASWSpread1 - zeroCpnSpecializedBondASWSpread1); + if (error14 > tolerance) + { QAssert.Fail("wrong asw spread for zeroCpn bond:" - + "\n generic zeroCpn bond's asw spread: " - + zeroCpnBondASWSpread1 - + "\n equivalent specialized bond's asw spread: " - + zeroCpnSpecializedBondASWSpread1 - + "\n error: " + error14 - + "\n tolerance: " + tolerance); + + "\n generic zeroCpn bond's asw spread: " + + zeroCpnBondASWSpread1 + + "\n equivalent specialized bond's asw spread: " + + zeroCpnSpecializedBondASWSpread1 + + "\n error: " + error14 + + "\n tolerance: " + tolerance); } - // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28) - // maturity doesn't occur on a business day - Date zeroCpnBondStartDate2 = new Date(17,Month.February,1998); - Date zeroCpnBondMaturityDate2 = new Date(17,Month.February,2028); + // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28) + // maturity doesn't occur on a business day + Date zeroCpnBondStartDate2 = new Date(17, Month.February, 1998); + Date zeroCpnBondMaturityDate2 = new Date(17, Month.February, 2028); Date zerocpbondRedemption2 = bondCalendar.adjust(zeroCpnBondMaturityDate2, - BusinessDayConvention.Following); - List zeroCpnBondLeg2 = new List{new SimpleCashFlow(100.0, zerocpbondRedemption2)}; + BusinessDayConvention.Following); + List zeroCpnBondLeg2 = new List {new SimpleCashFlow(100.0, zerocpbondRedemption2)}; // generic bond Bond zeroCpnBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, - zeroCpnBondMaturityDate2, zeroCpnBondStartDate2, zeroCpnBondLeg2); + zeroCpnBondMaturityDate2, zeroCpnBondStartDate2, zeroCpnBondLeg2); zeroCpnBond2.setPricingEngine(bondEngine); // specialized zerocpn bond Bond zeroCpnSpecializedBond2 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount, - new Date(17,Month.February,2028), - BusinessDayConvention.Following, - 100.0, new Date(17,Month.February,1998)); + new Date(17, Month.February, 2028), + BusinessDayConvention.Following, + 100.0, new Date(17, Month.February, 1998)); zeroCpnSpecializedBond2.setPricingEngine(bondEngine); double zeroCpnBondPrice2 = zeroCpnBond2.cleanPrice(); double zeroCpnSpecializedBondPrice2 = zeroCpnSpecializedBond2.cleanPrice(); - AssetSwap zeroCpnBondAssetSwap2= new AssetSwap(payFixedRate,zeroCpnBond2, - zeroCpnBondPrice2, - vars.iborIndex, vars.nonnullspread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap zeroCpnBondAssetSwap2 = new AssetSwap(payFixedRate, zeroCpnBond2, + zeroCpnBondPrice2, + vars.iborIndex, vars.nonnullspread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); zeroCpnBondAssetSwap2.setPricingEngine(swapEngine); - AssetSwap zeroCpnSpecializedBondAssetSwap2= new AssetSwap(payFixedRate, - zeroCpnSpecializedBond2, - zeroCpnSpecializedBondPrice2, - vars.iborIndex, - vars.nonnullspread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap zeroCpnSpecializedBondAssetSwap2 = new AssetSwap(payFixedRate, + zeroCpnSpecializedBond2, + zeroCpnSpecializedBondPrice2, + vars.iborIndex, + vars.nonnullspread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); zeroCpnSpecializedBondAssetSwap2.setPricingEngine(swapEngine); double zeroCpnBondAssetSwapPrice2 = zeroCpnBondAssetSwap2.fairCleanPrice(); double zeroCpnSpecializedBondAssetSwapPrice2 = - zeroCpnSpecializedBondAssetSwap2.fairCleanPrice(); + zeroCpnSpecializedBondAssetSwap2.fairCleanPrice(); double error15 = Math.Abs(zeroCpnBondAssetSwapPrice2 - -zeroCpnSpecializedBondAssetSwapPrice2); - if (error15>tolerance) { + - zeroCpnSpecializedBondAssetSwapPrice2); + if (error15 > tolerance) + { QAssert.Fail("wrong clean price for zerocpn bond:" - + "\n generic zero cpn bond's clean price: " - + zeroCpnBondAssetSwapPrice2 - + "\n equivalent specialized bond's price: " - + zeroCpnSpecializedBondAssetSwapPrice2 - + "\n error: " + error15 - + "\n tolerance: " + tolerance); + + "\n generic zero cpn bond's clean price: " + + zeroCpnBondAssetSwapPrice2 + + "\n equivalent specialized bond's price: " + + zeroCpnSpecializedBondAssetSwapPrice2 + + "\n error: " + error15 + + "\n tolerance: " + tolerance); } // market executable price as of 4th sept 2007 double zeroCpnBondMktPrice2 = 72.277; - AssetSwap zeroCpnBondASW2= new AssetSwap(payFixedRate, - zeroCpnBond2,zeroCpnBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap zeroCpnBondASW2 = new AssetSwap(payFixedRate, + zeroCpnBond2, zeroCpnBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); zeroCpnBondASW2.setPricingEngine(swapEngine); - AssetSwap zeroCpnSpecializedBondASW2= new AssetSwap(payFixedRate, - zeroCpnSpecializedBond2, - zeroCpnBondMktPrice2, - vars.iborIndex, vars.spread, - null, - vars.iborIndex.dayCounter(), - parAssetSwap); + AssetSwap zeroCpnSpecializedBondASW2 = new AssetSwap(payFixedRate, + zeroCpnSpecializedBond2, + zeroCpnBondMktPrice2, + vars.iborIndex, vars.spread, + null, + vars.iborIndex.dayCounter(), + parAssetSwap); zeroCpnSpecializedBondASW2.setPricingEngine(swapEngine); double zeroCpnBondASWSpread2 = zeroCpnBondASW2.fairSpread(); double zeroCpnSpecializedBondASWSpread2 = zeroCpnSpecializedBondASW2.fairSpread(); double error16 = - Math.Abs(zeroCpnBondASWSpread2-zeroCpnSpecializedBondASWSpread2); - if (error16>tolerance) { + Math.Abs(zeroCpnBondASWSpread2 - zeroCpnSpecializedBondASWSpread2); + if (error16 > tolerance) + { QAssert.Fail("wrong asw spread for zeroCpn bond:" - + "\n generic zeroCpn bond's asw spread: " - + zeroCpnBondASWSpread2 - + "\n equivalent specialized bond's asw spread: " - + zeroCpnSpecializedBondASWSpread2 - + "\n error: " + error16 - + "\n tolerance: " + tolerance); + + "\n generic zeroCpn bond's asw spread: " + + zeroCpnBondASWSpread2 + + "\n equivalent specialized bond's asw spread: " + + zeroCpnSpecializedBondASWSpread2 + + "\n error: " + error16 + + "\n tolerance: " + tolerance); } - } + } - -} + + } } diff --git a/tests/QLNet.Tests/T_BarrierOption.cs b/tests/QLNet.Tests/T_BarrierOption.cs index 645033076..69cd2d203 100644 --- a/tests/QLNet.Tests/T_BarrierOption.cs +++ b/tests/QLNet.Tests/T_BarrierOption.cs @@ -1,16 +1,16 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) // Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,99 +19,99 @@ #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; namespace TestSuite { - #if NET40 || NET45 - [TestClass()] - #endif +#if NET40 || NET45 + [TestClass()] +#endif public class T_BarrierOption { - private void REPORT_FAILURE( string greekName, - Barrier.Type barrierType, - double barrier, - double rebate, - StrikedTypePayoff payoff, - Exercise exercise, - double s, - double q, - double r, - Date today, - double v, - double expected, - double calculated, - double error, - double tolerance ) + private void REPORT_FAILURE(string greekName, + Barrier.Type barrierType, + double barrier, + double rebate, + StrikedTypePayoff payoff, + Exercise exercise, + double s, + double q, + double r, + Date today, + double v, + double expected, + double calculated, + double error, + double tolerance) { - QAssert.Fail( barrierType + " " - + exercise + " " - + payoff.optionType() + " option with " - + payoff + " payoff:\n" - + " underlying value: " + s + "\n" - + " strike: " + payoff.strike() + "\n" - + " barrier: " + barrier + "\n" - + " rebate: " + rebate + "\n" - + " dividend yield: " + q + "\n" - + " risk-free rate: " + r + "\n" - + " reference date: " + today + "\n" - + " maturity: " + exercise.lastDate() + "\n" - + " volatility: " + v + "\n\n" - + " expected " + greekName + ": " + expected + "\n" - + " calculated " + greekName + ": " + calculated + "\n" - + " error: " + error + "\n" - + " tolerance: " + tolerance ); + QAssert.Fail(barrierType + " " + + exercise + " " + + payoff.optionType() + " option with " + + payoff + " payoff:\n" + + " underlying value: " + s + "\n" + + " strike: " + payoff.strike() + "\n" + + " barrier: " + barrier + "\n" + + " rebate: " + rebate + "\n" + + " dividend yield: " + q + "\n" + + " risk-free rate: " + r + "\n" + + " reference date: " + today + "\n" + + " maturity: " + exercise.lastDate() + "\n" + + " volatility: " + v + "\n\n" + + " expected " + greekName + ": " + expected + "\n" + + " calculated " + greekName + ": " + calculated + "\n" + + " error: " + error + "\n" + + " tolerance: " + tolerance); } - private void REPORT_FX_FAILURE( string greekName, - Barrier.Type barrierType, - double barrier, - double rebate, - StrikedTypePayoff payoff, - Exercise exercise, - double s, - double q, - double r, - Date today, - double vol25Put, - double atmVol, - double vol25Call, - double v, - double expected, - double calculated, - double error, - double tolerance ) + private void REPORT_FX_FAILURE(string greekName, + Barrier.Type barrierType, + double barrier, + double rebate, + StrikedTypePayoff payoff, + Exercise exercise, + double s, + double q, + double r, + Date today, + double vol25Put, + double atmVol, + double vol25Call, + double v, + double expected, + double calculated, + double error, + double tolerance) { - QAssert.Fail( barrierType + " " - + exercise + " " - + payoff.optionType() + " option with " - + payoff + " payoff:\n" - + " underlying value: " + s + "\n" - + " strike: " + payoff.strike() + "\n" - + " barrier: " + barrier + "\n" - + " rebate: " + rebate + "\n" - + " dividend yield: " + q + "\n" - + " risk-free rate: " + r + "\n" - + " reference date: " + today + "\n" - + " maturity: " + exercise.lastDate() + "\n" - + " 25PutVol: " + vol25Put + "\n" - + " atmVol: " + atmVol + "\n" - + " 25CallVol: " + vol25Call + "\n" - + " volatility: " + v + "\n\n" - + " expected " + greekName + ": " + expected + "\n" - + " calculated " + greekName + ": " + calculated + "\n" - + " error: " + error + "\n" - + " tolerance: " + tolerance ); + QAssert.Fail(barrierType + " " + + exercise + " " + + payoff.optionType() + " option with " + + payoff + " payoff:\n" + + " underlying value: " + s + "\n" + + " strike: " + payoff.strike() + "\n" + + " barrier: " + barrier + "\n" + + " rebate: " + rebate + "\n" + + " dividend yield: " + q + "\n" + + " risk-free rate: " + r + "\n" + + " reference date: " + today + "\n" + + " maturity: " + exercise.lastDate() + "\n" + + " 25PutVol: " + vol25Put + "\n" + + " atmVol: " + atmVol + "\n" + + " 25CallVol: " + vol25Call + "\n" + + " volatility: " + v + "\n\n" + + " expected " + greekName + ": " + expected + "\n" + + " calculated " + greekName + ": " + calculated + "\n" + + " error: " + error + "\n" + + " tolerance: " + tolerance); } private struct BarrierOptionData { - public BarrierOptionData(Barrier.Type type_,double volatility_,double strike_,double barrier_,double callValue_, - double putValue_) + public BarrierOptionData(Barrier.Type type_, double volatility_, double strike_, double barrier_, double callValue_, + double putValue_) { - type=type_; + type = type_; volatility = volatility_; strike = strike_; barrier = barrier_; @@ -129,9 +129,9 @@ public BarrierOptionData(Barrier.Type type_,double volatility_,double strike_,do private struct NewBarrierOptionData { - public NewBarrierOptionData( Barrier.Type barrierType_,double barrier_,double rebate_,Option.Type type_, - Exercise.Type exType_,double strike_,double s_,double q_,double r_,double t_,double v_,double result_, - double tol_) + public NewBarrierOptionData(Barrier.Type barrierType_, double barrier_, double rebate_, Option.Type type_, + Exercise.Type exType_, double strike_, double s_, double q_, double r_, double t_, double v_, double result_, + double tol_) { barrierType = barrierType_; barrier = barrier_; @@ -139,13 +139,13 @@ public NewBarrierOptionData( Barrier.Type barrierType_,double barrier_,double re type = type_; exType = exType_; strike = strike_; - s = s_; - q = q_; - r = r_; - t = t_; - v = v_; - result = result_; - tol = tol_; + s = s_; + q = q_; + r = r_; + t = t_; + v = v_; + result = result_; + tol = tol_; } public Barrier.Type barrierType; @@ -182,8 +182,8 @@ private struct BarrierFxOptionData public double tol; // tolerance public BarrierFxOptionData(Barrier.Type barrierType, double barrier, double rebate, Option.Type type, - double strike, double s, double q, double r, double t, double vol25Put, double volAtm, double vol25Call, - double v, double result, double tol) : this() + double strike, double s, double q, double r, double t, double vol25Put, double volAtm, double vol25Call, + double v, double result, double tol) : this() { this.barrierType = barrierType; this.barrier = barrier; @@ -203,133 +203,134 @@ public BarrierFxOptionData(Barrier.Type barrierType, double barrier, double reba } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testHaugValues() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testHaugValues() { // Testing barrier options against Haug's values Exercise.Type european = Exercise.Type.European; Exercise.Type american = Exercise.Type.American; - NewBarrierOptionData[] values = { + NewBarrierOptionData[] values = + { /* The data below are from "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 pag. 72 */ // barrierType, barrier, rebate, type, exercise, strk, s, q, r, t, v, result, tol - new NewBarrierOptionData( Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 9.0246, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 6.7924, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 4.8759, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 2.6789, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 2.3580, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 2.3453, 1.0e-4), - - new NewBarrierOptionData( Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 7.7627, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 4.0109, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 2.0576, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 13.8333, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 7.8494, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 3.9795, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 14.1112, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 8.4482, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 4.5910, 1.0e-4), - - new NewBarrierOptionData( Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 8.8334, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 7.0285, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 5.4137, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 3.0000, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 3.0000, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 3.0000, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 2.6341, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 2.4389, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 2.4315, 1.0e-4), - - new NewBarrierOptionData( Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 9.0093, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 5.1370, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 2.8517, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 14.8816, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 9.2045, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 5.3043, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 15.2098, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 9.7278, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 5.8350, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 9.0246, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 6.7924, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 4.8759, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 2.6789, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 2.3580, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 2.3453, 1.0e-4), + + new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 7.7627, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 4.0109, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 2.0576, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 13.8333, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 7.8494, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 3.9795, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 14.1112, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 8.4482, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 4.5910, 1.0e-4), + + new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 8.8334, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 7.0285, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 5.4137, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 3.0000, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 3.0000, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 3.0000, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 2.6341, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 2.4389, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 2.4315, 1.0e-4), + + new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 9.0093, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 5.1370, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 2.8517, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 14.8816, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 9.2045, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 5.3043, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 15.2098, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 9.7278, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 5.8350, 1.0e-4), // barrierType, barrier, rebate, type, exercise, strk, s, q, r, t, v, result, tol - new NewBarrierOptionData( Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 2.2798, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 2.2947, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 2.6252, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 3.7760, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 5.4932, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 7.5187, 1.0e-4 ), - - new NewBarrierOptionData( Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 2.9586, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 6.5677, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 11.9752, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 2.2845, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 5.9085, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 11.6465, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 1.4653, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.3721, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 7.0846, 1.0e-4 ), - - new NewBarrierOptionData( Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 2.4170, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 2.4258, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 2.6246, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 3.0000, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 3.0000, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 3.0000, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 4.2293, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 5.8032, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 7.5649, 1.0e-4 ), - - new NewBarrierOptionData( Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 3.8769, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 7.7989, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 13.3078, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 3.3328, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 7.2636, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 12.9713, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 2.0658, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 4.4226, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 8.3686, 1.0e-4 ), + new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 2.2798, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 2.2947, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 2.6252, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 3.7760, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 5.4932, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 7.5187, 1.0e-4), + + new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 2.9586, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 6.5677, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 11.9752, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 2.2845, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 5.9085, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 11.6465, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 1.4653, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.3721, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 7.0846, 1.0e-4), + + new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 2.4170, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 2.4258, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 2.6246, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 3.0000, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 3.0000, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 3.0000, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 4.2293, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 5.8032, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 7.5649, 1.0e-4), + + new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 3.8769, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 7.7989, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 13.3078, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 3.3328, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 7.2636, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 12.9713, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, european, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 2.0658, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, european, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 4.4226, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, european, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 8.3686, 1.0e-4), // Options with american exercise: values computed with 400 steps of Haug's VBA code (handles only out options) // barrierType, barrier, rebate, type, exercise, strk, s, q, r, t, v, result, tol - new NewBarrierOptionData( Barrier.Type.DownOut, 95.0, 0.0, Option.Type.Call, american, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 10.4655, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownOut, 95.0, 0.0, Option.Type.Call, american, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 4.5159, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownOut, 95.0, 0.0, Option.Type.Call, american, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 2.5971, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, american, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, american, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, american, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.UpOut, 105.0, 0.0, Option.Type.Call, american, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 11.8076, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.UpOut, 105.0, 0.0, Option.Type.Call, american, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.3993, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, american, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 2.3457, 1.0e-4), - - new NewBarrierOptionData( Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, american, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 2.2795, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownOut, 95.0, 0.0, Option.Type.Put, american, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.3512, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownOut, 95.0, 0.0, Option.Type.Put, american, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 11.5773, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, american, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, american, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, american, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.UpOut, 105.0, 0.0, Option.Type.Put, american, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 1.4763, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.UpOut, 105.0, 0.0, Option.Type.Put, american, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.3001, 1.0e-4 ), - new NewBarrierOptionData( Barrier.Type.UpOut, 105.0, 0.0, Option.Type.Put, american, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 10.0000, 1.0e-4 ), - - // some american in-options - results (roughly) verified with other numerical methods + new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 0.0, Option.Type.Call, american, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 10.4655, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 0.0, Option.Type.Call, american, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 4.5159, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 0.0, Option.Type.Call, american, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 2.5971, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, american, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, american, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, american, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 0.0, Option.Type.Call, american, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 11.8076, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 0.0, Option.Type.Call, american, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.3993, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, american, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 2.3457, 1.0e-4), + + new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, american, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 2.2795, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 0.0, Option.Type.Put, american, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.3512, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 0.0, Option.Type.Put, american, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 11.5773, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, american, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, american, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, american, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 0.0, Option.Type.Put, american, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 1.4763, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 0.0, Option.Type.Put, american, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.3001, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 0.0, Option.Type.Put, american, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 10.0000, 1.0e-4), + + // some american in-options - results (roughly) verified with other numerical methods // barrierType, barrier, rebate, type, exercise, strk, s, q, r, t, v, result, tol - new NewBarrierOptionData( Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, american, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 7.7615, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, american, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 4.0118, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, american, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 2.0544, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, american, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 13.8308, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, american, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 14.1150, 1.0e-4), - new NewBarrierOptionData( Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, american, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 4.5900, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, american, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 7.7615, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, american, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 4.0118, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, american, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 2.0544, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, american, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 13.8308, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, american, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 14.1150, 1.0e-4), + new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, american, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 4.5900, 1.0e-4), /* Data from "Going to Extreme: Correcting Simulation Bias in Exotic @@ -355,20 +356,20 @@ Option Valuation" SimpleQuote vol = new SimpleQuote(0.0); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - for (int i=0; i< values.Length; i++) + for (int i = 0; i < values.Length; i++) { - Date exDate = today + Convert.ToInt32(values[i].t*360+0.5); + Date exDate = today + Convert.ToInt32(values[i].t * 360 + 0.5); spot .setValue(values[i].s); qRate.setValue(values[i].q); rRate.setValue(values[i].r); vol .setValue(values[i].v); - StrikedTypePayoff payoff = new PlainVanillaPayoff(values[i].type,values[i].strike); + StrikedTypePayoff payoff = new PlainVanillaPayoff(values[i].type, values[i].strike); - BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess( new Handle(spot), - new Handle(qTS),new Handle(rTS), - new Handle(volTS)); + BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), + new Handle(qTS), new Handle(rTS), + new Handle(volTS)); Exercise exercise; if (values[i].exType == Exercise.Type.European) @@ -376,14 +377,14 @@ Option Valuation" else exercise = new AmericanExercise(exDate); - BarrierOption barrierOption = new BarrierOption(values[i].barrierType,values[i].barrier,values[i].rebate, - payoff,exercise); + BarrierOption barrierOption = new BarrierOption(values[i].barrierType, values[i].barrier, values[i].rebate, + payoff, exercise); IPricingEngine engine; double calculated; double expected; double error; - if (values[i].exType == Exercise.Type.European) + if (values[i].exType == Exercise.Type.European) { // these engines support only european options engine = new AnalyticBarrierEngine(stochProcess); @@ -392,8 +393,9 @@ Option Valuation" calculated = barrierOption.NPV(); expected = values[i].result; - error = Math.Abs(calculated-expected); - if (error>values[i].tol) { + error = Math.Abs(calculated - expected); + if (error > values[i].tol) + { REPORT_FAILURE("value", values[i].barrierType, values[i].barrier, values[i].rebate, payoff, exercise, values[i].s, values[i].q, values[i].r, today, values[i].v, @@ -405,8 +407,9 @@ Option Valuation" calculated = barrierOption.NPV(); expected = values[i].result; - error = Math.Abs(calculated-expected); - if (error>5.0e-3) { + error = Math.Abs(calculated - expected); + if (error > 5.0e-3) + { REPORT_FAILURE("fd value", values[i].barrierType, values[i].barrier, values[i].rebate, payoff, exercise, values[i].s, values[i].q, values[i].r, today, values[i].v, @@ -416,52 +419,53 @@ Option Valuation" engine = new BinomialBarrierEngine( (d, end, steps, strike) => new CoxRossRubinstein(d, end, steps, strike), - (args, process, grid) => new DiscretizedBarrierOption(args, process, grid), - stochProcess, 400 ); + (args, process, grid) => new DiscretizedBarrierOption(args, process, grid), + stochProcess, 400); barrierOption.setPricingEngine(engine); calculated = barrierOption.NPV(); expected = values[i].result; - error = Math.Abs(calculated-expected); + error = Math.Abs(calculated - expected); double tol = 1.1e-2; - if (error>tol) { + if (error > tol) + { REPORT_FAILURE("Binomial (Boyle-lau) value", values[i].barrierType, values[i].barrier, values[i].rebate, payoff, exercise, values[i].s, values[i].q, values[i].r, today, values[i].v, expected, calculated, error, tol); } - // Note: here, to test Derman convergence, we force maxTimeSteps to + // Note: here, to test Derman convergence, we force maxTimeSteps to // timeSteps, effectively disabling Boyle-Lau barrier adjustment. // Production code should always enable Boyle-Lau. In most cases it // gives very good convergence with only a modest timeStep increment. engine = new BinomialBarrierEngine( - ( d, end, steps, strike ) => new CoxRossRubinstein( d, end, steps, strike ), - ( args, process, grid ) => new DiscretizedDermanKaniBarrierOption( args, process, grid ), - stochProcess, 400 ); - barrierOption.setPricingEngine( engine ); + (d, end, steps, strike) => new CoxRossRubinstein(d, end, steps, strike), + (args, process, grid) => new DiscretizedDermanKaniBarrierOption(args, process, grid), + stochProcess, 400); + barrierOption.setPricingEngine(engine); calculated = barrierOption.NPV(); expected = values[i].result; - error = Math.Abs( calculated - expected ); + error = Math.Abs(calculated - expected); tol = 4e-2; - if ( error > tol ) + if (error > tol) { - REPORT_FAILURE( "Binomial (Derman) value", values[i].barrierType, values[i].barrier, + REPORT_FAILURE("Binomial (Derman) value", values[i].barrierType, values[i].barrier, values[i].rebate, payoff, exercise, values[i].s, values[i].q, values[i].r, today, values[i].v, - expected, calculated, error, tol ); + expected, calculated, error, tol); } } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testBabsiriValues() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testBabsiriValues() { // Testing barrier options against Babsiri's values @@ -471,17 +475,18 @@ Data from - M. El Babsiri and G. Noel Journal of Derivatives; Winter 1998; 6, 2 */ - BarrierOptionData[] values = { - new BarrierOptionData( Barrier.Type.DownIn, 0.10, 100, 90, 0.07187, 0.0 ), - new BarrierOptionData( Barrier.Type.DownIn, 0.15, 100, 90, 0.60638, 0.0 ), - new BarrierOptionData( Barrier.Type.DownIn, 0.20, 100, 90, 1.64005, 0.0 ), - new BarrierOptionData( Barrier.Type.DownIn, 0.25, 100, 90, 2.98495, 0.0 ), - new BarrierOptionData( Barrier.Type.DownIn, 0.30, 100, 90, 4.50952, 0.0 ), - new BarrierOptionData( Barrier.Type.UpIn, 0.10, 100, 110, 4.79148, 0.0 ), - new BarrierOptionData( Barrier.Type.UpIn, 0.15, 100, 110, 7.08268, 0.0 ), - new BarrierOptionData( Barrier.Type.UpIn, 0.20, 100, 110, 9.11008, 0.0 ), - new BarrierOptionData( Barrier.Type.UpIn, 0.25, 100, 110, 11.06148, 0.0 ), - new BarrierOptionData( Barrier.Type.UpIn, 0.30, 100, 110, 12.98351, 0.0 ) + BarrierOptionData[] values = + { + new BarrierOptionData(Barrier.Type.DownIn, 0.10, 100, 90, 0.07187, 0.0), + new BarrierOptionData(Barrier.Type.DownIn, 0.15, 100, 90, 0.60638, 0.0), + new BarrierOptionData(Barrier.Type.DownIn, 0.20, 100, 90, 1.64005, 0.0), + new BarrierOptionData(Barrier.Type.DownIn, 0.25, 100, 90, 2.98495, 0.0), + new BarrierOptionData(Barrier.Type.DownIn, 0.30, 100, 90, 4.50952, 0.0), + new BarrierOptionData(Barrier.Type.UpIn, 0.10, 100, 110, 4.79148, 0.0), + new BarrierOptionData(Barrier.Type.UpIn, 0.15, 100, 110, 7.08268, 0.0), + new BarrierOptionData(Barrier.Type.UpIn, 0.20, 100, 110, 9.11008, 0.0), + new BarrierOptionData(Barrier.Type.UpIn, 0.25, 100, 110, 11.06148, 0.0), + new BarrierOptionData(Barrier.Type.UpIn, 0.30, 100, 110, 12.98351, 0.0) }; double underlyingPrice = 100.0; @@ -502,14 +507,14 @@ Data from SimpleQuote volatility = new SimpleQuote(0.10); BlackVolTermStructure volTS = Utilities.flatVol(today, volatility, dc); - Date exDate = today+360; + Date exDate = today + 360; Exercise exercise = new EuropeanExercise(exDate); - for (int i=0; i< values.Length; i++) + for (int i = 0; i < values.Length; i++) { volatility.setValue(values[i].volatility); - StrikedTypePayoff callPayoff = new PlainVanillaPayoff(Option.Type.Call,values[i].strike); + StrikedTypePayoff callPayoff = new PlainVanillaPayoff(Option.Type.Call, values[i].strike); BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess( new Handle(underlying), @@ -521,13 +526,13 @@ Data from IPricingEngine engine = new AnalyticBarrierEngine(stochProcess); // analytic - BarrierOption barrierCallOption = new BarrierOption(values[i].type,values[i].barrier,rebate,callPayoff,exercise); + BarrierOption barrierCallOption = new BarrierOption(values[i].type, values[i].barrier, rebate, callPayoff, exercise); barrierCallOption.setPricingEngine(engine); double calculated = barrierCallOption.NPV(); double expected = values[i].callValue; - double error = Math.Abs(calculated-expected); + double error = Math.Abs(calculated - expected); double maxErrorAllowed = 1.0e-5; - if (error>maxErrorAllowed) + if (error > maxErrorAllowed) { REPORT_FAILURE("value", values[i].type, values[i].barrier, rebate, callPayoff, exercise, underlyingPrice, @@ -558,15 +563,15 @@ Data from //} } - + } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testBeagleholeValues() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testBeagleholeValues() { // Testing barrier options against Beaglehole's values @@ -578,8 +583,9 @@ Option Valuation" - D.R. Beaglehole, P.H. Dybvig and G. Zhou Financial Analysts Journal; Jan / Feb 1997; 53, 1 */ - BarrierOptionData[] values = { - new BarrierOptionData( Barrier.Type.DownOut, 0.50, 50, 45, 5.477, 0.0) + BarrierOptionData[] values = + { + new BarrierOptionData(Barrier.Type.DownOut, 0.50, 50, 45, 5.477, 0.0) }; double underlyingPrice = 50.0; @@ -602,14 +608,14 @@ Option Valuation" BlackVolTermStructure volTS = Utilities.flatVol(today, volatility, dc); - Date exDate = today+360; + Date exDate = today + 360; Exercise exercise = new EuropeanExercise(exDate); - for (int i=0; i(underlying), @@ -619,13 +625,13 @@ Option Valuation" IPricingEngine engine = new AnalyticBarrierEngine(stochProcess); - BarrierOption barrierCallOption = new BarrierOption(values[i].type,values[i].barrier,rebate,callPayoff,exercise); + BarrierOption barrierCallOption = new BarrierOption(values[i].type, values[i].barrier, rebate, callPayoff, exercise); barrierCallOption.setPricingEngine(engine); double calculated = barrierCallOption.NPV(); double expected = values[i].callValue; double maxErrorAllowed = 1.0e-3; - double error = Math.Abs(calculated-expected); - if (error > maxErrorAllowed) + double error = Math.Abs(calculated - expected); + if (error > maxErrorAllowed) { REPORT_FAILURE("value", values[i].type, values[i].barrier, rebate, callPayoff, exercise, underlyingPrice, @@ -646,7 +652,7 @@ Option Valuation" //barrierCallOption.setPricingEngine(mcEngine); //calculated = barrierCallOption.NPV(); //error = Math.Abs(calculated-expected)/expected; - //if (error>maxMcRelativeErrorAllowed) + //if (error>maxMcRelativeErrorAllowed) //{ // REPORT_FAILURE("value", values[i].type, values[i].barrier, // rebate, callPayoff, exercise, underlyingPrice, @@ -657,12 +663,12 @@ Option Valuation" } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testLocalVolAndHestonComparison() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testLocalVolAndHestonComparison() { // Testing local volatility and Heston FD engines for barrier options SavedSettings backup = new SavedSettings(); @@ -674,27 +680,29 @@ public void testLocalVolAndHestonComparison() Calendar calendar = new TARGET(); int[] t = { 13, 41, 75, 165, 256, 345, 524, 703 }; - double[] r = { 0.0357,0.0349,0.0341,0.0355,0.0359,0.0368,0.0386,0.0401 }; + double[] r = { 0.0357, 0.0349, 0.0341, 0.0355, 0.0359, 0.0368, 0.0386, 0.0401 }; List rates = new InitializedList(1, 0.0357); List dates = new InitializedList(1, settlementDate); - for (int i = 0; i < 8; ++i) + for (int i = 0; i < 8; ++i) { dates.Add(settlementDate + t[i]); rates.Add(r[i]); } - - Handle rTS = new Handle( new InterpolatedZeroCurve(dates, rates, dayCounter)); + + Handle rTS = new Handle(new InterpolatedZeroCurve(dates, rates, dayCounter)); Handle qTS = new Handle(Utilities.flatRate(settlementDate, 0.0, dayCounter)); Handle s0 = new Handle(new SimpleQuote(4500.00)); - - double[] tmp = { 100 ,500 ,2000,3400,3600,3800,4000,4200,4400,4500, - 4600,4800,5000,5200,5400,5600,7500,10000,20000,30000 }; + + double[] tmp = { 100, 500, 2000, 3400, 3600, 3800, 4000, 4200, 4400, 4500, + 4600, 4800, 5000, 5200, 5400, 5600, 7500, 10000, 20000, 30000 + }; List strikes = new List(tmp); - + double[] v = - { 1.015873, 1.015873, 1.015873, 0.89729, 0.796493, 0.730914, 0.631335, 0.568895, + { + 1.015873, 1.015873, 1.015873, 0.89729, 0.796493, 0.730914, 0.631335, 0.568895, 0.711309, 0.711309, 0.711309, 0.641309, 0.635593, 0.583653, 0.508045, 0.463182, 0.516034, 0.500534, 0.500534, 0.500534, 0.448706, 0.416661, 0.375470, 0.353442, 0.516034, 0.482263, 0.447713, 0.387703, 0.355064, 0.337438, 0.316966, 0.306859, @@ -713,46 +721,47 @@ public void testLocalVolAndHestonComparison() 0.399925, 0.369232, 0.338895, 0.289042, 0.265509, 0.255589, 0.249308, 0.249665, 0.423432, 0.406891, 0.373720, 0.314667, 0.281009, 0.263281, 0.246451, 0.242166, 0.453704, 0.453704, 0.453704, 0.381255, 0.334578, 0.305527, 0.268909, 0.251367, - 0.517748, 0.517748, 0.517748, 0.416577, 0.364770, 0.331595, 0.287423, 0.264285 }; - - Matrix blackVolMatrix = new Matrix(strikes.Count, dates.Count-1); - for (int i=0; i < strikes.Count; ++i) - for (int j=1; j < dates.Count; ++j) + 0.517748, 0.517748, 0.517748, 0.416577, 0.364770, 0.331595, 0.287423, 0.264285 + }; + + Matrix blackVolMatrix = new Matrix(strikes.Count, dates.Count - 1); + for (int i = 0; i < strikes.Count; ++i) + for (int j = 1; j < dates.Count; ++j) { - blackVolMatrix[i,j-1] = v[i*(dates.Count-1)+j-1]; + blackVolMatrix[i, j - 1] = v[i * (dates.Count - 1) + j - 1]; } - + BlackVarianceSurface volTS = new BlackVarianceSurface(settlementDate, calendar, - dates.GetRange(1, dates.Count - 1),strikes, blackVolMatrix,dayCounter); + dates.GetRange(1, dates.Count - 1), strikes, blackVolMatrix, dayCounter); volTS.setInterpolation(); - GeneralizedBlackScholesProcess localVolProcess = new BlackScholesMertonProcess(s0, qTS, rTS, - new Handle(volTS)); - + GeneralizedBlackScholesProcess localVolProcess = new BlackScholesMertonProcess(s0, qTS, rTS, + new Handle(volTS)); + double v0 = 0.195662; double kappa = 5.6628; double theta = 0.0745911; double sigma = 1.1619; double rho = -0.511493; - HestonProcess hestonProcess = new HestonProcess(rTS, qTS, s0, v0,kappa, theta, sigma, rho); + HestonProcess hestonProcess = new HestonProcess(rTS, qTS, s0, v0, kappa, theta, sigma, rho); HestonModel hestonModel = new HestonModel(hestonProcess); // TODO FdHestonBarrierEngine //IPricingEngine fdHestonEngine = new FdHestonBarrierEngine(hestonModel, 100, 400, 50); - IPricingEngine fdLocalVolEngine = new FdBlackScholesBarrierEngine(localVolProcess,100, 400, 0,new FdmSchemeDesc().Douglas(), true, 0.35); - + IPricingEngine fdLocalVolEngine = new FdBlackScholesBarrierEngine(localVolProcess, 100, 400, 0, new FdmSchemeDesc().Douglas(), true, 0.35); + double strike = s0.link.value(); double barrier = 3000; double rebate = 100; Date exDate = settlementDate + new Period(20, TimeUnit.Months); - + StrikedTypePayoff payoff = new PlainVanillaPayoff(Option.Type.Put, strike); Exercise exercise = new EuropeanExercise(exDate); - BarrierOption barrierOption = new BarrierOption(Barrier.Type.DownOut,barrier, rebate, payoff, exercise); + BarrierOption barrierOption = new BarrierOption(Barrier.Type.DownOut, barrier, rebate, payoff, exercise); // TODO FdHestonBarrierEngine //barrierOption.setPricingEngine(fdHestonEngine); @@ -762,11 +771,11 @@ public void testLocalVolAndHestonComparison() barrierOption.setPricingEngine(fdLocalVolEngine); double expectedLocalVolNPV = 132.8; double calculatedLocalVolNPV = barrierOption.NPV(); - + double tol = 0.01; /* TODO FdHestonBarrierEngine - if (Math.Abs(expectedHestonNPV - calculatedHestonNPV) > tol*expectedHestonNPV) + if (Math.Abs(expectedHestonNPV - calculatedHestonNPV) > tol*expectedHestonNPV) { QAssert.Fail("Failed to reproduce Heston barrier price for " + "\n strike: " + payoff.strike() @@ -775,173 +784,174 @@ public void testLocalVolAndHestonComparison() + "\n calculated: " + calculatedHestonNPV + "\n expected: " + expectedHestonNPV); }*/ - if (Math.Abs(expectedLocalVolNPV - calculatedLocalVolNPV) > tol*expectedLocalVolNPV) + if (Math.Abs(expectedLocalVolNPV - calculatedLocalVolNPV) > tol * expectedLocalVolNPV) { QAssert.Fail("Failed to reproduce Heston barrier price for " - + "\n strike: " + payoff.strike() - + "\n barrier: " + barrier - + "\n maturity: " + exDate - + "\n calculated: " + calculatedLocalVolNPV - + "\n expected: " + expectedLocalVolNPV); + + "\n strike: " + payoff.strike() + + "\n barrier: " + barrier + + "\n maturity: " + exDate + + "\n calculated: " + calculatedLocalVolNPV + + "\n expected: " + expectedLocalVolNPV); } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testVannaVolgaSimpleBarrierValues() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testVannaVolgaSimpleBarrierValues() { // Testing barrier FX options against Vanna/Volga values SavedSettings backup = new SavedSettings(); - BarrierFxOptionData[] values = { + BarrierFxOptionData[] values = + { //barrierType,barrier,rebate,type,strike,s,q,r,t,vol25Put,volAtm,vol25Call,vol, result, tol - new BarrierFxOptionData( Barrier.Type.UpOut,1.5,0, Option.Type.Call,1.13321,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.11638,0.148127, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpOut,1.5,0, Option.Type.Call,1.22687,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.10088,0.075943, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpOut,1.5,0, Option.Type.Call,1.31179,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08925,0.0274771, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpOut,1.5,0, Option.Type.Call,1.38843,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08463,0.00573, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpOut,1.5,0, Option.Type.Call,1.46047,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08412,0.00012, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.UpOut,1.5,0, Option.Type.Put,1.13321,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.11638,0.00697606, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpOut,1.5,0, Option.Type.Put,1.22687,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.10088,0.020078, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpOut,1.5,0, Option.Type.Put,1.31179,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08925,0.0489395, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpOut,1.5,0, Option.Type.Put,1.38843,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08463,0.0969877, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpOut,1.5,0, Option.Type.Put,1.46047,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08412,0.157, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.UpIn,1.5,0, Option.Type.Call,1.13321,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.11638,0.0322202, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpIn,1.5,0, Option.Type.Call,1.22687,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.10088,0.0241491, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpIn,1.5,0, Option.Type.Call,1.31179,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08925,0.0164275, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpIn,1.5,0, Option.Type.Call,1.38843,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08463,0.01, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpIn,1.5,0, Option.Type.Call,1.46047,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08412,0.00489, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.UpIn,1.5,0, Option.Type.Put,1.13321,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.11638,0.000560713, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpIn,1.5,0, Option.Type.Put,1.22687,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.10088,0.000546804, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpIn,1.5,0, Option.Type.Put,1.31179,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08925,0.000130649, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpIn,1.5,0, Option.Type.Put,1.38843,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08463,0.000300828, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpIn,1.5,0, Option.Type.Put,1.46047,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08412,0.00135, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.DownOut,1.1,0, Option.Type.Call,1.13321,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.11638,0.17746, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.1,0, Option.Type.Call,1.22687,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.10088,0.0994142, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.1,0, Option.Type.Call,1.31179,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08925,0.0439, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.1,0, Option.Type.Call,1.38843,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08463,0.01574, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.1,0, Option.Type.Call,1.46047,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08412,0.00501, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Call,1.13321,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.11638,0.00612, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Call,1.22687,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.10088,0.00426, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Call,1.31179,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08925,0.00257, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Call,1.38843,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08463,0.00122, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Call,1.46047,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08412,0.00045, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.DownOut,1.1,0, Option.Type.Put,1.13321,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.11638,0.00022, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.1,0, Option.Type.Put,1.22687,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.10088,0.00284, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.1,0, Option.Type.Put,1.31179,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08925,0.02032, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.1,0, Option.Type.Put,1.38843,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08463,0.058235, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.1,0, Option.Type.Put,1.46047,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08412,0.109432, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Put,1.13321,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.11638,0, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Put,1.22687,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.10088,0, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Put,1.31179,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08925,0, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Put,1.38843,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08463,0.00017, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Put,1.46047,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08412,0.00083, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.DownIn,1.1,0, Option.Type.Call,1.13321,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.11638,0.00289, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.1,0, Option.Type.Call,1.22687,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.10088,0.00067784, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.1,0, Option.Type.Call,1.31179,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08925,0, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.1,0, Option.Type.Call,1.38843,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08463,0, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.1,0, Option.Type.Call,1.46047,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08412,0, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Call,1.13321,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.11638,0.17423, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Call,1.22687,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.10088,0.09584, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Call,1.31179,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08925,0.04133, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Call,1.38843,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08463,0.01452, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Call,1.46047,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08412,0.00456, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.DownIn,1.1,0, Option.Type.Put,1.13321,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.11638,0.00732, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.1,0, Option.Type.Put,1.22687,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.10088,0.01778, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.1,0, Option.Type.Put,1.31179,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08925,0.02875, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.1,0, Option.Type.Put,1.38843,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08463,0.0390535, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.1,0, Option.Type.Put,1.46047,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08412,0.0489236, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Put,1.13321,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.11638,0.00753, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Put,1.22687,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.10088,0.02062, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Put,1.31179,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08925,0.04907, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Put,1.38843,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08463,0.09711, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Put,1.46047,1.30265,0.0003541,0.0033871,1,0.10087,0.08925,0.08463,0.08412,0.15752, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.UpOut,1.6,0, Option.Type.Call,1.06145,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.12511,0.20493, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpOut,1.6,0, Option.Type.Call,1.19545,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.1089,0.105577, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpOut,1.6,0, Option.Type.Call,1.32238,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09444,0.0358872, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpOut,1.6,0, Option.Type.Call,1.44298,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09197,0.00634958, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpOut,1.6,0, Option.Type.Call,1.56345,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09261,0, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.UpOut,1.6,0, Option.Type.Put,1.06145,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.12511,0.0108218, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpOut,1.6,0, Option.Type.Put,1.19545,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.1089,0.0313339, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpOut,1.6,0, Option.Type.Put,1.32238,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09444,0.0751237, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpOut,1.6,0, Option.Type.Put,1.44298,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09197,0.153407, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpOut,1.6,0, Option.Type.Put,1.56345,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09261,0.253767, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.UpIn,1.6,0, Option.Type.Call,1.06145,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.12511,0.05402, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpIn,1.6,0, Option.Type.Call,1.19545,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.1089,0.0410069, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpIn,1.6,0, Option.Type.Call,1.32238,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09444,0.0279562, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpIn,1.6,0, Option.Type.Call,1.44298,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09197,0.0173055, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpIn,1.6,0, Option.Type.Call,1.56345,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09261,0.00764, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.UpIn,1.6,0, Option.Type.Put,1.06145,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.12511,0.000962737, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpIn,1.6,0, Option.Type.Put,1.19545,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.1089,0.00102637, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpIn,1.6,0, Option.Type.Put,1.32238,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09444,0.000419834, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpIn,1.6,0, Option.Type.Put,1.44298,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09197,0.00159277, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.UpIn,1.6,0, Option.Type.Put,1.56345,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09261,0.00473629, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.DownOut,1,0, Option.Type.Call,1.06145,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.12511,0.255098, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1,0, Option.Type.Call,1.19545,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.1089,0.145701, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1,0, Option.Type.Call,1.32238,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09444,0.06384, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1,0, Option.Type.Call,1.44298,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09197,0.02366, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1,0, Option.Type.Call,1.56345,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09261,0.00764, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Call,1.06145,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.12511,0.00592, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Call,1.19545,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.1089,0.00421, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Call,1.32238,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09444,0.00256, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Call,1.44298,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09197,0.0012, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Call,1.56345,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09261,0.0004, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.DownOut,1,0, Option.Type.Put,1.06145,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.12511,0, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1,0, Option.Type.Put,1.19545,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.1089,0.00280549, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1,0, Option.Type.Put,1.32238,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09444,0.0279945, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1,0, Option.Type.Put,1.44298,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09197,0.0896352, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1,0, Option.Type.Put,1.56345,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09261,0.175182, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Put,1.06145,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.12511, 0.00000, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Put,1.19545,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.1089, 0.00000, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Put,1.32238,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09444, 0.00000, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Put,1.44298,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09197,0.0002, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownOut,1.3,0, Option.Type.Put,1.56345,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09261,0.00096, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.DownIn,1,0, Option.Type.Call,1.06145,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.12511,0.00384783, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1,0, Option.Type.Call,1.19545,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.1089,0.000883232, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1,0, Option.Type.Call,1.32238,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09444,0, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1,0, Option.Type.Call,1.44298,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09197, 0.00000, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1,0, Option.Type.Call,1.56345,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09261, 0.00000, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Call,1.06145,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.12511,0.25302, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Call,1.19545,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.1089,0.14238, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Call,1.32238,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09444,0.06128, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Call,1.44298,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09197,0.02245, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Call,1.56345,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09261,0.00725, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.DownIn,1,0, Option.Type.Put,1.06145,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.12511,0.01178, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1,0, Option.Type.Put,1.19545,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.1089,0.0295548, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1,0, Option.Type.Put,1.32238,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09444,0.047549, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1,0, Option.Type.Put,1.44298,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09197,0.0653642, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1,0, Option.Type.Put,1.56345,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09261,0.0833221, 1.0e-4), - - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Put,1.06145,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.12511,0.01178, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Put,1.19545,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.1089,0.03236, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Put,1.32238,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09444,0.07554, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Put,1.44298,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09197,0.15479, 1.0e-4), - new BarrierFxOptionData( Barrier.Type.DownIn,1.3,0, Option.Type.Put,1.56345,1.30265,0.0009418,0.0039788,2,0.10891,0.09525,0.09197,0.09261,0.25754, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpOut, 1.5, 0, Option.Type.Call, 1.13321, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.11638, 0.148127, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpOut, 1.5, 0, Option.Type.Call, 1.22687, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.10088, 0.075943, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpOut, 1.5, 0, Option.Type.Call, 1.31179, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08925, 0.0274771, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpOut, 1.5, 0, Option.Type.Call, 1.38843, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08463, 0.00573, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpOut, 1.5, 0, Option.Type.Call, 1.46047, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08412, 0.00012, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.UpOut, 1.5, 0, Option.Type.Put, 1.13321, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.11638, 0.00697606, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpOut, 1.5, 0, Option.Type.Put, 1.22687, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.10088, 0.020078, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpOut, 1.5, 0, Option.Type.Put, 1.31179, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08925, 0.0489395, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpOut, 1.5, 0, Option.Type.Put, 1.38843, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08463, 0.0969877, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpOut, 1.5, 0, Option.Type.Put, 1.46047, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08412, 0.157, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.UpIn, 1.5, 0, Option.Type.Call, 1.13321, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.11638, 0.0322202, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpIn, 1.5, 0, Option.Type.Call, 1.22687, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.10088, 0.0241491, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpIn, 1.5, 0, Option.Type.Call, 1.31179, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08925, 0.0164275, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpIn, 1.5, 0, Option.Type.Call, 1.38843, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08463, 0.01, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpIn, 1.5, 0, Option.Type.Call, 1.46047, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08412, 0.00489, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.UpIn, 1.5, 0, Option.Type.Put, 1.13321, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.11638, 0.000560713, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpIn, 1.5, 0, Option.Type.Put, 1.22687, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.10088, 0.000546804, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpIn, 1.5, 0, Option.Type.Put, 1.31179, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08925, 0.000130649, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpIn, 1.5, 0, Option.Type.Put, 1.38843, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08463, 0.000300828, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpIn, 1.5, 0, Option.Type.Put, 1.46047, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08412, 0.00135, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.DownOut, 1.1, 0, Option.Type.Call, 1.13321, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.11638, 0.17746, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.1, 0, Option.Type.Call, 1.22687, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.10088, 0.0994142, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.1, 0, Option.Type.Call, 1.31179, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08925, 0.0439, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.1, 0, Option.Type.Call, 1.38843, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08463, 0.01574, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.1, 0, Option.Type.Call, 1.46047, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08412, 0.00501, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Call, 1.13321, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.11638, 0.00612, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Call, 1.22687, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.10088, 0.00426, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Call, 1.31179, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08925, 0.00257, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Call, 1.38843, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08463, 0.00122, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Call, 1.46047, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08412, 0.00045, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.DownOut, 1.1, 0, Option.Type.Put, 1.13321, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.11638, 0.00022, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.1, 0, Option.Type.Put, 1.22687, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.10088, 0.00284, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.1, 0, Option.Type.Put, 1.31179, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08925, 0.02032, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.1, 0, Option.Type.Put, 1.38843, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08463, 0.058235, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.1, 0, Option.Type.Put, 1.46047, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08412, 0.109432, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Put, 1.13321, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.11638, 0, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Put, 1.22687, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.10088, 0, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Put, 1.31179, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08925, 0, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Put, 1.38843, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08463, 0.00017, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Put, 1.46047, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08412, 0.00083, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.DownIn, 1.1, 0, Option.Type.Call, 1.13321, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.11638, 0.00289, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.1, 0, Option.Type.Call, 1.22687, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.10088, 0.00067784, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.1, 0, Option.Type.Call, 1.31179, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08925, 0, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.1, 0, Option.Type.Call, 1.38843, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08463, 0, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.1, 0, Option.Type.Call, 1.46047, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08412, 0, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Call, 1.13321, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.11638, 0.17423, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Call, 1.22687, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.10088, 0.09584, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Call, 1.31179, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08925, 0.04133, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Call, 1.38843, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08463, 0.01452, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Call, 1.46047, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08412, 0.00456, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.DownIn, 1.1, 0, Option.Type.Put, 1.13321, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.11638, 0.00732, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.1, 0, Option.Type.Put, 1.22687, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.10088, 0.01778, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.1, 0, Option.Type.Put, 1.31179, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08925, 0.02875, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.1, 0, Option.Type.Put, 1.38843, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08463, 0.0390535, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.1, 0, Option.Type.Put, 1.46047, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08412, 0.0489236, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Put, 1.13321, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.11638, 0.00753, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Put, 1.22687, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.10088, 0.02062, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Put, 1.31179, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08925, 0.04907, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Put, 1.38843, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08463, 0.09711, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Put, 1.46047, 1.30265, 0.0003541, 0.0033871, 1, 0.10087, 0.08925, 0.08463, 0.08412, 0.15752, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.UpOut, 1.6, 0, Option.Type.Call, 1.06145, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.12511, 0.20493, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpOut, 1.6, 0, Option.Type.Call, 1.19545, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.1089, 0.105577, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpOut, 1.6, 0, Option.Type.Call, 1.32238, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09444, 0.0358872, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpOut, 1.6, 0, Option.Type.Call, 1.44298, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09197, 0.00634958, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpOut, 1.6, 0, Option.Type.Call, 1.56345, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09261, 0, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.UpOut, 1.6, 0, Option.Type.Put, 1.06145, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.12511, 0.0108218, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpOut, 1.6, 0, Option.Type.Put, 1.19545, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.1089, 0.0313339, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpOut, 1.6, 0, Option.Type.Put, 1.32238, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09444, 0.0751237, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpOut, 1.6, 0, Option.Type.Put, 1.44298, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09197, 0.153407, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpOut, 1.6, 0, Option.Type.Put, 1.56345, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09261, 0.253767, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.UpIn, 1.6, 0, Option.Type.Call, 1.06145, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.12511, 0.05402, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpIn, 1.6, 0, Option.Type.Call, 1.19545, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.1089, 0.0410069, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpIn, 1.6, 0, Option.Type.Call, 1.32238, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09444, 0.0279562, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpIn, 1.6, 0, Option.Type.Call, 1.44298, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09197, 0.0173055, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpIn, 1.6, 0, Option.Type.Call, 1.56345, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09261, 0.00764, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.UpIn, 1.6, 0, Option.Type.Put, 1.06145, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.12511, 0.000962737, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpIn, 1.6, 0, Option.Type.Put, 1.19545, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.1089, 0.00102637, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpIn, 1.6, 0, Option.Type.Put, 1.32238, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09444, 0.000419834, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpIn, 1.6, 0, Option.Type.Put, 1.44298, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09197, 0.00159277, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.UpIn, 1.6, 0, Option.Type.Put, 1.56345, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09261, 0.00473629, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.DownOut, 1, 0, Option.Type.Call, 1.06145, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.12511, 0.255098, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1, 0, Option.Type.Call, 1.19545, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.1089, 0.145701, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1, 0, Option.Type.Call, 1.32238, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09444, 0.06384, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1, 0, Option.Type.Call, 1.44298, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09197, 0.02366, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1, 0, Option.Type.Call, 1.56345, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09261, 0.00764, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Call, 1.06145, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.12511, 0.00592, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Call, 1.19545, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.1089, 0.00421, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Call, 1.32238, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09444, 0.00256, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Call, 1.44298, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09197, 0.0012, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Call, 1.56345, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09261, 0.0004, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.DownOut, 1, 0, Option.Type.Put, 1.06145, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.12511, 0, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1, 0, Option.Type.Put, 1.19545, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.1089, 0.00280549, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1, 0, Option.Type.Put, 1.32238, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09444, 0.0279945, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1, 0, Option.Type.Put, 1.44298, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09197, 0.0896352, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1, 0, Option.Type.Put, 1.56345, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09261, 0.175182, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Put, 1.06145, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.12511, 0.00000, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Put, 1.19545, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.1089, 0.00000, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Put, 1.32238, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09444, 0.00000, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Put, 1.44298, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09197, 0.0002, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownOut, 1.3, 0, Option.Type.Put, 1.56345, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09261, 0.00096, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.DownIn, 1, 0, Option.Type.Call, 1.06145, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.12511, 0.00384783, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1, 0, Option.Type.Call, 1.19545, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.1089, 0.000883232, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1, 0, Option.Type.Call, 1.32238, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09444, 0, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1, 0, Option.Type.Call, 1.44298, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09197, 0.00000, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1, 0, Option.Type.Call, 1.56345, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09261, 0.00000, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Call, 1.06145, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.12511, 0.25302, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Call, 1.19545, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.1089, 0.14238, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Call, 1.32238, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09444, 0.06128, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Call, 1.44298, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09197, 0.02245, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Call, 1.56345, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09261, 0.00725, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.DownIn, 1, 0, Option.Type.Put, 1.06145, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.12511, 0.01178, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1, 0, Option.Type.Put, 1.19545, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.1089, 0.0295548, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1, 0, Option.Type.Put, 1.32238, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09444, 0.047549, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1, 0, Option.Type.Put, 1.44298, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09197, 0.0653642, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1, 0, Option.Type.Put, 1.56345, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09261, 0.0833221, 1.0e-4), + + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Put, 1.06145, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.12511, 0.01178, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Put, 1.19545, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.1089, 0.03236, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Put, 1.32238, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09444, 0.07554, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Put, 1.44298, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09197, 0.15479, 1.0e-4), + new BarrierFxOptionData(Barrier.Type.DownIn, 1.3, 0, Option.Type.Put, 1.56345, 1.30265, 0.0009418, 0.0039788, 2, 0.10891, 0.09525, 0.09197, 0.09261, 0.25754, 1.0e-4), }; @@ -958,7 +968,7 @@ public void testVannaVolgaSimpleBarrierValues() SimpleQuote volAtm = new SimpleQuote(0.0); SimpleQuote vol25Call = new SimpleQuote(0.0); - for (int i=0; i< values.Length; i++) + for (int i = 0; i < values.Length; i++) { spot.setValue(values[i].s); qRate.setValue(values[i].q); @@ -967,52 +977,52 @@ public void testVannaVolgaSimpleBarrierValues() volAtm.setValue(values[i].volAtm); vol25Call.setValue(values[i].vol25Call); - StrikedTypePayoff payoff = new PlainVanillaPayoff(values[i].type,values[i].strike); - Date exDate = today + (int)(values[i].t*365+0.5); + StrikedTypePayoff payoff = new PlainVanillaPayoff(values[i].type, values[i].strike); + Date exDate = today + (int)(values[i].t * 365 + 0.5); Exercise exercise = new EuropeanExercise(exDate); Handle volAtmQuote = new Handle( - new DeltaVolQuote( new Handle(volAtm), - DeltaVolQuote.DeltaType.Fwd, - values[i].t, - DeltaVolQuote.AtmType.AtmDeltaNeutral)); + new DeltaVolQuote(new Handle(volAtm), + DeltaVolQuote.DeltaType.Fwd, + values[i].t, + DeltaVolQuote.AtmType.AtmDeltaNeutral)); Handle vol25PutQuote = new Handle( - new DeltaVolQuote( -0.25, - new Handle(vol25Put), - values[i].t, - DeltaVolQuote.DeltaType.Fwd)); + new DeltaVolQuote(-0.25, + new Handle(vol25Put), + values[i].t, + DeltaVolQuote.DeltaType.Fwd)); Handle vol25CallQuote = new Handle( - new DeltaVolQuote( 0.25, - new Handle(vol25Call), - values[i].t, - DeltaVolQuote.DeltaType.Fwd)); + new DeltaVolQuote(0.25, + new Handle(vol25Call), + values[i].t, + DeltaVolQuote.DeltaType.Fwd)); - BarrierOption barrierOption = new BarrierOption(values[i].barrierType,values[i].barrier,values[i].rebate, - payoff,exercise); + BarrierOption barrierOption = new BarrierOption(values[i].barrierType, values[i].barrier, values[i].rebate, + payoff, exercise); double bsVanillaPrice = Utils.blackFormula(values[i].type, values[i].strike, - spot.value()*qTS.discount(values[i].t)/rTS.discount(values[i].t), - values[i].v * Math.Sqrt(values[i].t), rTS.discount(values[i].t)); - IPricingEngine vannaVolgaEngine = new VannaVolgaBarrierEngine( volAtmQuote, vol25PutQuote, vol25CallQuote, - new Handle (spot), - new Handle (rTS), - new Handle (qTS), - true, - bsVanillaPrice); + spot.value() * qTS.discount(values[i].t) / rTS.discount(values[i].t), + values[i].v * Math.Sqrt(values[i].t), rTS.discount(values[i].t)); + IPricingEngine vannaVolgaEngine = new VannaVolgaBarrierEngine(volAtmQuote, vol25PutQuote, vol25CallQuote, + new Handle (spot), + new Handle (rTS), + new Handle (qTS), + true, + bsVanillaPrice); barrierOption.setPricingEngine(vannaVolgaEngine); double calculated = barrierOption.NPV(); double expected = values[i].result; - double error = Math.Abs(calculated-expected); - if (error>values[i].tol) + double error = Math.Abs(calculated - expected); + if (error > values[i].tol) { - REPORT_FX_FAILURE( "value", values[i].barrierType, values[i].barrier, - values[i].rebate, payoff, exercise, values[i].s, - values[i].q, values[i].r, today, values[i].vol25Put, - values[i].volAtm, values[i].vol25Call, values[i].v, - expected, calculated, error, values[i].tol); + REPORT_FX_FAILURE("value", values[i].barrierType, values[i].barrier, + values[i].rebate, payoff, exercise, values[i].s, + values[i].q, values[i].r, today, values[i].vol25Put, + values[i].volAtm, values[i].vol25Call, values[i].v, + expected, calculated, error, values[i].tol); } } } diff --git a/tests/QLNet.Tests/T_BasketOption.cs b/tests/QLNet.Tests/T_BasketOption.cs index fcef50e8b..d0d9bfb4d 100644 --- a/tests/QLNet.Tests/T_BasketOption.cs +++ b/tests/QLNet.Tests/T_BasketOption.cs @@ -1,16 +1,16 @@ /* Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,7 +21,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -33,26 +33,26 @@ namespace TestSuite #endif public class T_BasketOption { - public enum BasketType { MinBasket, MaxBasket, SpreadBasket }; + public enum BasketType { MinBasket, MaxBasket, SpreadBasket } public struct BasketOptionTwoData { - public BasketOptionTwoData( BasketType _basketType,Option.Type _type,double _strike,double _s1,double _s2,double _q1, - double _q2,double _r,double _t,double _v1,double _v2,double _rho,double _result,double _tol) + public BasketOptionTwoData(BasketType _basketType, Option.Type _type, double _strike, double _s1, double _s2, double _q1, + double _q2, double _r, double _t, double _v1, double _v2, double _rho, double _result, double _tol) { - - basketType=_basketType; - type= _type; - strike=_strike; - s1=_s1; - s2=_s2; - q1=_q1; - q2=_q2; + + basketType = _basketType; + type = _type; + strike = _strike; + s1 = _s1; + s2 = _s2; + q1 = _q1; + q2 = _q2; r = _r; t = _t; // years - v1=_v1; - v2=_v2; - rho=_rho; - result= _result; + v1 = _v1; + v2 = _v2; + rho = _rho; + result = _result; tol = _tol; } @@ -70,66 +70,67 @@ public BasketOptionTwoData( BasketType _basketType,Option.Type _type,double _str public double rho; public double result; public double tol; - }; - public BasketPayoff basketTypeToPayoff(BasketType basketType,Payoff p) + } + public BasketPayoff basketTypeToPayoff(BasketType basketType, Payoff p) { - switch (basketType) { - case BasketType.MinBasket: - return new MinBasketPayoff(p); - case BasketType.MaxBasket: - return new MaxBasketPayoff(p); - case BasketType.SpreadBasket: - return new SpreadBasketPayoff(p); - } - Utils.QL_FAIL("unknown basket option type"); + switch (basketType) + { + case BasketType.MinBasket: + return new MinBasketPayoff(p); + case BasketType.MaxBasket: + return new MaxBasketPayoff(p); + case BasketType.SpreadBasket: + return new SpreadBasketPayoff(p); + } + Utils.QL_FAIL("unknown basket option type"); return null; } - public string basketTypeToString(BasketType basketType) + public string basketTypeToString(BasketType basketType) { - switch (basketType) - { - case BasketType.MinBasket: - return "MinBasket"; - case BasketType.MaxBasket: - return "MaxBasket"; - case BasketType.SpreadBasket: - return "Spread"; - } - Utils.QL_FAIL("unknown basket option type"); - return String.Empty; + switch (basketType) + { + case BasketType.MinBasket: + return "MinBasket"; + case BasketType.MaxBasket: + return "MaxBasket"; + case BasketType.SpreadBasket: + return "Spread"; + } + Utils.QL_FAIL("unknown basket option type"); + return String.Empty; } - public void REPORT_FAILURE_2(String greekName, BasketType basketType, PlainVanillaPayoff payoff, Exercise exercise, - double s1, double s2, double q1, double q2, double r, Date today, double v1, double v2, double rho, - double expected, double calculated, double error, double tolerance) + public void REPORT_FAILURE_2(String greekName, BasketType basketType, PlainVanillaPayoff payoff, Exercise exercise, + double s1, double s2, double q1, double q2, double r, Date today, double v1, double v2, double rho, + double expected, double calculated, double error, double tolerance) { - QAssert.Fail( Utilities.exerciseTypeToString(exercise) + " " - + payoff.optionType() + " option on " - + basketTypeToString(basketType) - + " with " + Utilities.payoffTypeToString(payoff) + " payoff:\n" - + "1st underlying value: " + s1 + "\n" - + "2nd underlying value: " + s2 + "\n" - + " strike: " + payoff.strike() + "\n" - + " 1st dividend yield: " + q1 + "\n" - + " 2nd dividend yield: " + q2 + "\n" - + " risk-free rate: " + r + "\n" - + " reference date: " + today + "\n" - + " maturity: " + exercise.lastDate() + "\n" - + "1st asset volatility: " + v1 + "\n" - + "2nd asset volatility: " + v2 + "\n" - + " correlation: " + rho + "\n\n" - + " expected " + greekName + ": " + expected + "\n" + QAssert.Fail(Utilities.exerciseTypeToString(exercise) + " " + + payoff.optionType() + " option on " + + basketTypeToString(basketType) + + " with " + Utilities.payoffTypeToString(payoff) + " payoff:\n" + + "1st underlying value: " + s1 + "\n" + + "2nd underlying value: " + s2 + "\n" + + " strike: " + payoff.strike() + "\n" + + " 1st dividend yield: " + q1 + "\n" + + " 2nd dividend yield: " + q2 + "\n" + + " risk-free rate: " + r + "\n" + + " reference date: " + today + "\n" + + " maturity: " + exercise.lastDate() + "\n" + + "1st asset volatility: " + v1 + "\n" + + "2nd asset volatility: " + v2 + "\n" + + " correlation: " + rho + "\n\n" + + " expected " + greekName + ": " + expected + "\n" + " calculated " + greekName + ": " + calculated + "\n" - + " error: " + error + "\n" + + " error: " + error + "\n" + " tolerance: " + tolerance); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testEuroTwoValues() + public void testEuroTwoValues() { // Testing two-asset European basket options... @@ -140,7 +141,7 @@ Excel spreadsheet www.maths.ox.ac.uk/~firth/computing/excel.shtml "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 pag 56-58 European two asset max basket options */ - BasketOptionTwoData[] values = + BasketOptionTwoData[] values = { // basketType, optionType, strike, s1, s2, q1, q2, r, t, v1, v2, rho, result, tol // data from http://www.maths.ox.ac.uk/~firth/computing/excel.shtml @@ -204,20 +205,20 @@ European two asset max basket options new BasketOptionTwoData(BasketType.SpreadBasket, Option.Type.Call, 3.0, 122.0, 120.0, 0.0, 0.0, 0.10, 0.1, 0.20, 0.25, -0.5, 5.4061, 1.0e-3), new BasketOptionTwoData(BasketType.SpreadBasket, Option.Type.Call, 3.0, 122.0, 120.0, 0.0, 0.0, 0.10, 0.1, 0.20, 0.25, 0.0, 4.3451, 1.0e-3), new BasketOptionTwoData(BasketType.SpreadBasket, Option.Type.Call, 3.0, 122.0, 120.0, 0.0, 0.0, 0.10, 0.1, 0.20, 0.25, 0.5, 2.9723, 1.0e-3), - new BasketOptionTwoData(BasketType.SpreadBasket, Option.Type.Call, 3.0, 122.0, 120.0, 0.0, 0.0, 0.10, 0.5, 0.20, 0.20, -0.5,10.7517, 1.0e-3), + new BasketOptionTwoData(BasketType.SpreadBasket, Option.Type.Call, 3.0, 122.0, 120.0, 0.0, 0.0, 0.10, 0.5, 0.20, 0.20, -0.5, 10.7517, 1.0e-3), new BasketOptionTwoData(BasketType.SpreadBasket, Option.Type.Call, 3.0, 122.0, 120.0, 0.0, 0.0, 0.10, 0.5, 0.20, 0.20, 0.0, 8.7020, 1.0e-3), new BasketOptionTwoData(BasketType.SpreadBasket, Option.Type.Call, 3.0, 122.0, 120.0, 0.0, 0.0, 0.10, 0.5, 0.20, 0.20, 0.5, 6.0257, 1.0e-3), - new BasketOptionTwoData(BasketType.SpreadBasket, Option.Type.Call, 3.0, 122.0, 120.0, 0.0, 0.0, 0.10, 0.5, 0.25, 0.20, -0.5,12.1941, 1.0e-3), + new BasketOptionTwoData(BasketType.SpreadBasket, Option.Type.Call, 3.0, 122.0, 120.0, 0.0, 0.0, 0.10, 0.5, 0.25, 0.20, -0.5, 12.1941, 1.0e-3), new BasketOptionTwoData(BasketType.SpreadBasket, Option.Type.Call, 3.0, 122.0, 120.0, 0.0, 0.0, 0.10, 0.5, 0.25, 0.20, 0.0, 9.9340, 1.0e-3), new BasketOptionTwoData(BasketType.SpreadBasket, Option.Type.Call, 3.0, 122.0, 120.0, 0.0, 0.0, 0.10, 0.5, 0.25, 0.20, 0.5, 7.0067, 1.0e-3), - new BasketOptionTwoData(BasketType.SpreadBasket, Option.Type.Call, 3.0, 122.0, 120.0, 0.0, 0.0, 0.10, 0.5, 0.20, 0.25, -0.5,12.1483, 1.0e-3), + new BasketOptionTwoData(BasketType.SpreadBasket, Option.Type.Call, 3.0, 122.0, 120.0, 0.0, 0.0, 0.10, 0.5, 0.20, 0.25, -0.5, 12.1483, 1.0e-3), new BasketOptionTwoData(BasketType.SpreadBasket, Option.Type.Call, 3.0, 122.0, 120.0, 0.0, 0.0, 0.10, 0.5, 0.20, 0.25, 0.0, 9.8780, 1.0e-3), new BasketOptionTwoData(BasketType.SpreadBasket, Option.Type.Call, 3.0, 122.0, 120.0, 0.0, 0.0, 0.10, 0.5, 0.20, 0.25, 0.5, 6.9284, 1.0e-3) }; DayCounter dc = new Actual360(); - - + + Date today = Date.Today; SimpleQuote spot1 = new SimpleQuote(0.0); @@ -239,50 +240,50 @@ European two asset max basket options //double mcRelativeErrorTolerance = 0.01; //double fdRelativeErrorTolerance = 0.01; - for (int i=0; i(spot1), - new Handle(qTS1), - new Handle(rTS), - new Handle(volTS1)); - p2 = new BlackScholesMertonProcess( new Handle(spot2), - new Handle(qTS2), - new Handle(rTS), - new Handle(volTS2)); - analyticEngine= new StulzEngine(p1, p2, values[i].rho); + p1 = new BlackScholesMertonProcess(new Handle(spot1), + new Handle(qTS1), + new Handle(rTS), + new Handle(volTS1)); + p2 = new BlackScholesMertonProcess(new Handle(spot2), + new Handle(qTS2), + new Handle(rTS), + new Handle(volTS2)); + analyticEngine = new StulzEngine(p1, p2, values[i].rho); break; - + case BasketType.SpreadBasket: - p1 = new BlackProcess( new Handle(spot1), - new Handle(rTS), - new Handle(volTS1)); - p2 = new BlackProcess( new Handle(spot2), - new Handle(rTS), - new Handle(volTS2)); - - analyticEngine= new KirkEngine((BlackProcess)p1, (BlackProcess)p2, values[i].rho); + p1 = new BlackProcess(new Handle(spot1), + new Handle(rTS), + new Handle(volTS1)); + p2 = new BlackProcess(new Handle(spot2), + new Handle(rTS), + new Handle(volTS2)); + + analyticEngine = new KirkEngine((BlackProcess)p1, (BlackProcess)p2, values[i].rho); break; default: @@ -293,65 +294,66 @@ European two asset max basket options List procs = new List {p1, p2}; - Matrix correlationMatrix = new Matrix(2,2, values[i].rho); - for (int j=0; j < 2; j++) + Matrix correlationMatrix = new Matrix(2, 2, values[i].rho); + for (int j = 0; j < 2; j++) { - correlationMatrix[j,j] = 1.0; + correlationMatrix[j, j] = 1.0; } - StochasticProcessArray process = new StochasticProcessArray(procs,correlationMatrix); + StochasticProcessArray process = new StochasticProcessArray(procs, correlationMatrix); //IPricingEngine mcEngine = MakeMCEuropeanBasketEngine(process) // .withStepsPerYear(1) // .withSamples(10000) // .withSeed(42); - + //IPricingEngine fdEngine = new Fd2dBlackScholesVanillaEngine(p1, p2, values[i].rho, 50, 50, 15); - - BasketOption basketOption = new BasketOption(basketTypeToPayoff(values[i].basketType,payoff),exercise); + + BasketOption basketOption = new BasketOption(basketTypeToPayoff(values[i].basketType, payoff), exercise); // analytic engine basketOption.setPricingEngine(analyticEngine); double calculated = basketOption.NPV(); double expected = values[i].result; - double error = Math.Abs(calculated-expected); - if (error > values[i].tol) { + double error = Math.Abs(calculated - expected); + if (error > values[i].tol) + { REPORT_FAILURE_2("value", values[i].basketType, payoff, exercise, - values[i].s1, values[i].s2, values[i].q1, - values[i].q2, values[i].r, today, values[i].v1, - values[i].v2, values[i].rho, values[i].result, - calculated, error, values[i].tol); + values[i].s1, values[i].s2, values[i].q1, + values[i].q2, values[i].r, today, values[i].v1, + values[i].v2, values[i].rho, values[i].result, + calculated, error, values[i].tol); } - // // fd engine - // basketOption.setPricingEngine(fdEngine); - // calculated = basketOption.NPV(); - // double relError = relativeError(calculated, expected, expected); - // if (relError > mcRelativeErrorTolerance ) - // { - // REPORT_FAILURE_2("FD value", values[i].basketType, payoff, - // exercise, values[i].s1, values[i].s2, - // values[i].q1, values[i].q2, values[i].r, - // today, values[i].v1, values[i].v2, values[i].rho, - // values[i].result, calculated, relError, - // fdRelativeErrorTolerance); - // } - - //// mc engine - //basketOption.setPricingEngine(mcEngine); - //calculated = basketOption.NPV(); - //relError = relativeError(calculated, expected, values[i].s1); - //if (relError > mcRelativeErrorTolerance ) - //{ - // REPORT_FAILURE_2("MC value", values[i].basketType, payoff, - // exercise, values[i].s1, values[i].s2, - // values[i].q1, values[i].q2, values[i].r, - // today, values[i].v1, values[i].v2, values[i].rho, - // values[i].result, calculated, relError, - // mcRelativeErrorTolerance); - //} + // // fd engine + // basketOption.setPricingEngine(fdEngine); + // calculated = basketOption.NPV(); + // double relError = relativeError(calculated, expected, expected); + // if (relError > mcRelativeErrorTolerance ) + // { + // REPORT_FAILURE_2("FD value", values[i].basketType, payoff, + // exercise, values[i].s1, values[i].s2, + // values[i].q1, values[i].q2, values[i].r, + // today, values[i].v1, values[i].v2, values[i].rho, + // values[i].result, calculated, relError, + // fdRelativeErrorTolerance); + // } + + //// mc engine + //basketOption.setPricingEngine(mcEngine); + //calculated = basketOption.NPV(); + //relError = relativeError(calculated, expected, values[i].s1); + //if (relError > mcRelativeErrorTolerance ) + //{ + // REPORT_FAILURE_2("MC value", values[i].basketType, payoff, + // exercise, values[i].s1, values[i].s2, + // values[i].q1, values[i].q2, values[i].r, + // today, values[i].v1, values[i].v2, values[i].rho, + // values[i].result, calculated, relError, + // mcRelativeErrorTolerance); + //} } } } diff --git a/tests/QLNet.Tests/T_Bermudanswaption.cs b/tests/QLNet.Tests/T_Bermudanswaption.cs index 44e0489c6..60dddd5e5 100644 --- a/tests/QLNet.Tests/T_Bermudanswaption.cs +++ b/tests/QLNet.Tests/T_Bermudanswaption.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,7 +22,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -32,221 +32,223 @@ namespace TestSuite [TestClass()] #endif public class T_Bermudanswaption : IDisposable - { - #region Initialize&Cleanup - private SavedSettings backup; - #if NET40 || NET45 - [TestInitialize] - public void testInitialize() - { - #else - public T_Bermudanswaption() - { - #endif - backup = new SavedSettings(); - } - #if NET40 || NET45 - [TestCleanup] - #endif - public void testCleanup() - { - Dispose(); - } - public void Dispose() - { - backup.Dispose(); - } - #endregion - - public class CommonVars - { - // global data - public Date today, settlement; - public Calendar calendar; - - // underlying swap parameters - public int startYears, length; - public VanillaSwap.Type type; - public double nominal; - public BusinessDayConvention fixedConvention, floatingConvention; - public Frequency fixedFrequency, floatingFrequency; - public DayCounter fixedDayCount; - public IborIndex index; - public int settlementDays; - - public RelinkableHandle termStructure; - - // setup - public CommonVars() - { - startYears = 1; - length = 5; - type = VanillaSwap.Type.Payer; - nominal = 1000.0; - settlementDays = 2; - fixedConvention = BusinessDayConvention.Unadjusted; - floatingConvention = BusinessDayConvention.ModifiedFollowing; - fixedFrequency = Frequency.Annual; - floatingFrequency = Frequency.Semiannual; - fixedDayCount = new Thirty360(); - - termStructure = new RelinkableHandle(); - termStructure.linkTo(Utilities.flatRate(new Date(19, Month.February, 2002), 0.04875825, new Actual365Fixed())); - - index = new Euribor6M(termStructure); - calendar = index.fixingCalendar(); - today = calendar.adjust(Date.Today); - settlement = calendar.advance(today, settlementDays, TimeUnit.Days); - } - - // utilities - public VanillaSwap makeSwap(double fixedRate) - { - Date start = calendar.advance(settlement, startYears, TimeUnit.Years); - Date maturity = calendar.advance(start, length, TimeUnit.Years); - Schedule fixedSchedule = new Schedule(start, maturity, - new Period(fixedFrequency), - calendar, - fixedConvention, - fixedConvention, - DateGeneration.Rule.Forward, false); - Schedule floatSchedule = new Schedule(start, maturity, - new Period(floatingFrequency), - calendar, - floatingConvention, - floatingConvention, - DateGeneration.Rule.Forward, false); - VanillaSwap swap = - new VanillaSwap(type, nominal, - fixedSchedule, fixedRate, fixedDayCount, - floatSchedule, index, 0.0, - index.dayCounter()); - swap.setPricingEngine((IPricingEngine)(new DiscountingSwapEngine(termStructure))); - return swap; - } - } + { + #region Initialize&Cleanup + private SavedSettings backup; +#if NET40 || NET45 + [TestInitialize] + public void testInitialize() + { +#else + public T_Bermudanswaption() + { +#endif + backup = new SavedSettings(); + } +#if NET40 || NET45 + [TestCleanup] +#endif + public void testCleanup() + { + Dispose(); + } + public void Dispose() + { + backup.Dispose(); + } + #endregion + + public class CommonVars + { + // global data + public Date today, settlement; + public Calendar calendar; + + // underlying swap parameters + public int startYears, length; + public VanillaSwap.Type type; + public double nominal; + public BusinessDayConvention fixedConvention, floatingConvention; + public Frequency fixedFrequency, floatingFrequency; + public DayCounter fixedDayCount; + public IborIndex index; + public int settlementDays; + + public RelinkableHandle termStructure; + + // setup + public CommonVars() + { + startYears = 1; + length = 5; + type = VanillaSwap.Type.Payer; + nominal = 1000.0; + settlementDays = 2; + fixedConvention = BusinessDayConvention.Unadjusted; + floatingConvention = BusinessDayConvention.ModifiedFollowing; + fixedFrequency = Frequency.Annual; + floatingFrequency = Frequency.Semiannual; + fixedDayCount = new Thirty360(); + + termStructure = new RelinkableHandle(); + termStructure.linkTo(Utilities.flatRate(new Date(19, Month.February, 2002), 0.04875825, new Actual365Fixed())); + + index = new Euribor6M(termStructure); + calendar = index.fixingCalendar(); + today = calendar.adjust(Date.Today); + settlement = calendar.advance(today, settlementDays, TimeUnit.Days); + } + + // utilities + public VanillaSwap makeSwap(double fixedRate) + { + Date start = calendar.advance(settlement, startYears, TimeUnit.Years); + Date maturity = calendar.advance(start, length, TimeUnit.Years); + Schedule fixedSchedule = new Schedule(start, maturity, + new Period(fixedFrequency), + calendar, + fixedConvention, + fixedConvention, + DateGeneration.Rule.Forward, false); + Schedule floatSchedule = new Schedule(start, maturity, + new Period(floatingFrequency), + calendar, + floatingConvention, + floatingConvention, + DateGeneration.Rule.Forward, false); + VanillaSwap swap = + new VanillaSwap(type, nominal, + fixedSchedule, fixedRate, fixedDayCount, + floatSchedule, index, 0.0, + index.dayCounter()); + swap.setPricingEngine((IPricingEngine)(new DiscountingSwapEngine(termStructure))); + return swap; + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testCachedValues() { - - //("Testing Bermudan swaption against cached values..."); - - CommonVars vars = new CommonVars(); - - vars.today = new Date(15, Month.February, 2002); - - Settings.setEvaluationDate(vars.today); - - vars.settlement = new Date(19, Month.February, 2002); - // flat yield term structure impling 1x5 swap at 5% - vars.termStructure.linkTo(Utilities.flatRate(vars.settlement, - 0.04875825, - new Actual365Fixed())); - - double atmRate = vars.makeSwap(0.0).fairRate(); - - VanillaSwap itmSwap = vars.makeSwap(0.8*atmRate); - VanillaSwap atmSwap = vars.makeSwap(atmRate); - VanillaSwap otmSwap = vars.makeSwap(1.2*atmRate); - - double a = 0.048696, sigma = 0.0058904; - ShortRateModel model=new HullWhite(vars.termStructure,a, sigma); - List exerciseDates= new List(); - List leg = atmSwap.fixedLeg(); - - for (int i=0; i tolerance) - QAssert.Fail("failed to reproduce cached in-the-money swaption value:\n" - + "calculated: " + swaption.NPV() + "\n" - + "expected: " + itmValue); - - swaption.setPricingEngine(fdmEngine); - if (Math.Abs(swaption.NPV() - itmValueFdm) > tolerance) - QAssert.Fail("failed to reproduce cached in-the-money swaption value:\n" - + "calculated: " + swaption.NPV() + "\n" - + "expected: " + itmValueFdm); - - swaption = new Swaption(atmSwap, exercise); - swaption.setPricingEngine(treeEngine); - if (Math.Abs(swaption.NPV()-atmValue) > tolerance) - QAssert.Fail("failed to reproduce cached at-the-money swaption value:\n" - + "calculated: " + swaption.NPV() + "\n" - + "expected: " + atmValue); - swaption.setPricingEngine(fdmEngine); - if (Math.Abs(swaption.NPV() - atmValueFdm) > tolerance) - QAssert.Fail("failed to reproduce cached at-the-money swaption value:\n" - + "calculated: " + swaption.NPV() + "\n" - + "expected: " + atmValueFdm); - - swaption = new Swaption(otmSwap, exercise); - swaption.setPricingEngine(treeEngine); - if (Math.Abs(swaption.NPV()-otmValue) > tolerance) - QAssert.Fail("failed to reproduce cached out-of-the-money " - + "swaption value:\n" - + "calculated: " + swaption.NPV() + "\n" - + "expected: " + otmValue); - swaption.setPricingEngine(fdmEngine); - if (Math.Abs(swaption.NPV() - otmValueFdm) > tolerance) - QAssert.Fail("failed to reproduce cached out-of-the-money " - + "swaption value:\n" - + "calculated: " + swaption.NPV() + "\n" - + "expected: " + otmValueFdm); - - for (int j=0; j tolerance) - QAssert.Fail("failed to reproduce cached in-the-money swaption value:\n" - + "calculated: " + swaption.NPV() + "\n" - + "expected: " + itmValue); - - swaption = new Swaption(atmSwap, exercise); - swaption.setPricingEngine(treeEngine); - if (Math.Abs(swaption.NPV()-atmValue) > tolerance) - QAssert.Fail("failed to reproduce cached at-the-money swaption value:\n" - + "calculated: " + swaption.NPV() + "\n" - + "expected: " + atmValue); - - swaption = new Swaption(otmSwap, exercise); - swaption.setPricingEngine(treeEngine); - if (Math.Abs(swaption.NPV()-otmValue) > tolerance) - QAssert.Fail("failed to reproduce cached out-of-the-money " - + "swaption value:\n" - + "calculated: " + swaption.NPV() + "\n" - + "expected: " + otmValue); - } - } -} \ No newline at end of file + public void testCachedValues() + { + + //("Testing Bermudan swaption against cached values..."); + + CommonVars vars = new CommonVars(); + + vars.today = new Date(15, Month.February, 2002); + + Settings.setEvaluationDate(vars.today); + + vars.settlement = new Date(19, Month.February, 2002); + // flat yield term structure impling 1x5 swap at 5% + vars.termStructure.linkTo(Utilities.flatRate(vars.settlement, + 0.04875825, + new Actual365Fixed())); + + double atmRate = vars.makeSwap(0.0).fairRate(); + + VanillaSwap itmSwap = vars.makeSwap(0.8 * atmRate); + VanillaSwap atmSwap = vars.makeSwap(atmRate); + VanillaSwap otmSwap = vars.makeSwap(1.2 * atmRate); + + double a = 0.048696, sigma = 0.0058904; + ShortRateModel model = new HullWhite(vars.termStructure, a, sigma); + List exerciseDates = new List(); + List leg = atmSwap.fixedLeg(); + + for (int i = 0; i < leg.Count; i++) + { + Coupon coupon = (Coupon)(leg[i]); + exerciseDates.Add(coupon.accrualStartDate()); + } + + Exercise exercise = new BermudanExercise(exerciseDates); + IPricingEngine treeEngine = new TreeSwaptionEngine(model, 50); + IPricingEngine fdmEngine = new FdHullWhiteSwaptionEngine(model as HullWhite); + +#if QL_USE_INDEXED_COUPON + double itmValue = 42.2413, atmValue = 12.8789, otmValue = 2.4759; + double itmValueFdm = 42.2111, atmValueFdm = 12.8879, otmValueFdm = 2.44443; +#else + double itmValue = 42.2470, atmValue = 12.8826, otmValue = 2.4769; + double itmValueFdm = 42.2091, atmValueFdm = 12.8864, otmValueFdm = 2.4437; +#endif + + double tolerance = 1.0e-4; + + Swaption swaption = new Swaption(itmSwap, exercise); + swaption.setPricingEngine(treeEngine); + if (Math.Abs(swaption.NPV() - itmValue) > tolerance) + QAssert.Fail("failed to reproduce cached in-the-money swaption value:\n" + + "calculated: " + swaption.NPV() + "\n" + + "expected: " + itmValue); + + swaption.setPricingEngine(fdmEngine); + if (Math.Abs(swaption.NPV() - itmValueFdm) > tolerance) + QAssert.Fail("failed to reproduce cached in-the-money swaption value:\n" + + "calculated: " + swaption.NPV() + "\n" + + "expected: " + itmValueFdm); + + swaption = new Swaption(atmSwap, exercise); + swaption.setPricingEngine(treeEngine); + if (Math.Abs(swaption.NPV() - atmValue) > tolerance) + QAssert.Fail("failed to reproduce cached at-the-money swaption value:\n" + + "calculated: " + swaption.NPV() + "\n" + + "expected: " + atmValue); + swaption.setPricingEngine(fdmEngine); + if (Math.Abs(swaption.NPV() - atmValueFdm) > tolerance) + QAssert.Fail("failed to reproduce cached at-the-money swaption value:\n" + + "calculated: " + swaption.NPV() + "\n" + + "expected: " + atmValueFdm); + + swaption = new Swaption(otmSwap, exercise); + swaption.setPricingEngine(treeEngine); + if (Math.Abs(swaption.NPV() - otmValue) > tolerance) + QAssert.Fail("failed to reproduce cached out-of-the-money " + + "swaption value:\n" + + "calculated: " + swaption.NPV() + "\n" + + "expected: " + otmValue); + swaption.setPricingEngine(fdmEngine); + if (Math.Abs(swaption.NPV() - otmValueFdm) > tolerance) + QAssert.Fail("failed to reproduce cached out-of-the-money " + + "swaption value:\n" + + "calculated: " + swaption.NPV() + "\n" + + "expected: " + otmValueFdm); + + for (int j = 0; j < exerciseDates.Count; j++) + exerciseDates[j] = vars.calendar.adjust(exerciseDates[j] - 10); + exercise = new BermudanExercise(exerciseDates); + +#if QL_USE_INDEXED_COUPON + itmValue = 42.1917; atmValue = 12.7788; otmValue = 2.4388; +#else + itmValue = 42.1974; atmValue = 12.7825; otmValue = 2.4399; +#endif + + swaption = new Swaption(itmSwap, exercise); + swaption.setPricingEngine(treeEngine); + if (Math.Abs(swaption.NPV() - itmValue) > tolerance) + QAssert.Fail("failed to reproduce cached in-the-money swaption value:\n" + + "calculated: " + swaption.NPV() + "\n" + + "expected: " + itmValue); + + swaption = new Swaption(atmSwap, exercise); + swaption.setPricingEngine(treeEngine); + if (Math.Abs(swaption.NPV() - atmValue) > tolerance) + QAssert.Fail("failed to reproduce cached at-the-money swaption value:\n" + + "calculated: " + swaption.NPV() + "\n" + + "expected: " + atmValue); + + swaption = new Swaption(otmSwap, exercise); + swaption.setPricingEngine(treeEngine); + if (Math.Abs(swaption.NPV() - otmValue) > tolerance) + QAssert.Fail("failed to reproduce cached out-of-the-money " + + "swaption value:\n" + + "calculated: " + swaption.NPV() + "\n" + + "expected: " + otmValue); + } + } +} diff --git a/tests/QLNet.Tests/T_BinaryOption.cs b/tests/QLNet.Tests/T_BinaryOption.cs index 27e24978c..6de7578db 100644 --- a/tests/QLNet.Tests/T_BinaryOption.cs +++ b/tests/QLNet.Tests/T_BinaryOption.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -18,49 +18,49 @@ #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; namespace TestSuite { - #if NET40 || NET45 - [TestClass()] - #endif +#if NET40 || NET45 + [TestClass()] +#endif public class T_BinaryOption { - private void REPORT_FAILURE( string greekName, - StrikedTypePayoff payoff, - Exercise exercise, - Barrier.Type barrierType, - double barrier, - double s, - double q, - double r, - Date today, - double v, - double expected, - double calculated, - double error, - double tolerance ) + private void REPORT_FAILURE(string greekName, + StrikedTypePayoff payoff, + Exercise exercise, + Barrier.Type barrierType, + double barrier, + double s, + double q, + double r, + Date today, + double v, + double expected, + double calculated, + double error, + double tolerance) { - QAssert.Fail( payoff.optionType() + " option with " - + barrierType + " barrier type:\n" - + " barrier: " + barrier + "\n" - + payoff + " payoff:\n" - + exercise + " " - + payoff.optionType() - + " spot value: " + s + "\n" - + " strike: " + payoff.strike() + "\n" - + " dividend yield: " + q + "\n" - + " risk-free rate: " + r + "\n" - + " reference date: " + today + "\n" - + " maturity: " + exercise.lastDate() + "\n" - + " volatility: " + v + "\n\n" - + " expected " + greekName + ": " + expected + "\n" - + " calculated " + greekName + ": " + calculated + "\n" - + " error: " + error + "\n" - + " tolerance: " + tolerance ); + QAssert.Fail(payoff.optionType() + " option with " + + barrierType + " barrier type:\n" + + " barrier: " + barrier + "\n" + + payoff + " payoff:\n" + + exercise + " " + + payoff.optionType() + + " spot value: " + s + "\n" + + " strike: " + payoff.strike() + "\n" + + " dividend yield: " + q + "\n" + + " risk-free rate: " + r + "\n" + + " reference date: " + today + "\n" + + " maturity: " + exercise.lastDate() + "\n" + + " volatility: " + v + "\n\n" + + " expected " + greekName + ": " + expected + "\n" + + " calculated " + greekName + ": " + calculated + "\n" + + " error: " + error + "\n" + + " tolerance: " + tolerance); } private struct BinaryOptionData @@ -79,7 +79,7 @@ private struct BinaryOptionData public double tol; // tolerance public BinaryOptionData(Barrier.Type barrierType, double barrier, double cash, Option.Type type, double strike, - double s, double q, double r, double t, double v, double result, double tol) : this() + double s, double q, double r, double t, double v, double result, double tol) : this() { this.barrierType = barrierType; this.barrier = barrier; @@ -96,58 +96,59 @@ public BinaryOptionData(Barrier.Type barrierType, double barrier, double cash, O } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testCashOrNothingHaugValues() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testCashOrNothingHaugValues() { // Testing cash-or-nothing barrier options against Haug's values - BinaryOptionData[] values = { + BinaryOptionData[] values = + { /* The data below are from "Option pricing formulas 2nd Ed.", E.G. Haug, McGraw-Hill 2007 pag. 180 - cases 13,14,17,18,21,22,25,26 Note: q is the dividend rate, while the book gives b, the cost of carry (q=r-b) */ // barrierType, barrier, cash, type, strike, spot, q, r, t, vol, value, tol - new BinaryOptionData( Barrier.Type.DownIn, 100.00, 15.00, Option.Type.Call, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 4.9289, 1e-4 ), - new BinaryOptionData( Barrier.Type.DownIn, 100.00, 15.00, Option.Type.Call, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 6.2150, 1e-4 ), - // following value is wrong in book. - new BinaryOptionData( Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Call, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 5.8926, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Call, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 7.4519, 1e-4 ), + new BinaryOptionData(Barrier.Type.DownIn, 100.00, 15.00, Option.Type.Call, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 4.9289, 1e-4), + new BinaryOptionData(Barrier.Type.DownIn, 100.00, 15.00, Option.Type.Call, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 6.2150, 1e-4), + // following value is wrong in book. + new BinaryOptionData(Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Call, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 5.8926, 1e-4), + new BinaryOptionData(Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Call, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 7.4519, 1e-4), // 17,18 - new BinaryOptionData( Barrier.Type.DownIn, 100.00, 15.00, Option.Type.Put, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 4.4314, 1e-4 ), - new BinaryOptionData( Barrier.Type.DownIn, 100.00, 15.00, Option.Type.Put, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 3.1454, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Put, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 5.3297, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Put, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 3.7704, 1e-4 ), + new BinaryOptionData(Barrier.Type.DownIn, 100.00, 15.00, Option.Type.Put, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 4.4314, 1e-4), + new BinaryOptionData(Barrier.Type.DownIn, 100.00, 15.00, Option.Type.Put, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 3.1454, 1e-4), + new BinaryOptionData(Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Put, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 5.3297, 1e-4), + new BinaryOptionData(Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Put, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 3.7704, 1e-4), // 21,22 - new BinaryOptionData( Barrier.Type.DownOut, 100.00, 15.00, Option.Type.Call, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 4.8758, 1e-4 ), - new BinaryOptionData( Barrier.Type.DownOut, 100.00, 15.00, Option.Type.Call, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 4.9081, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpOut, 100.00, 15.00, Option.Type.Call, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpOut, 100.00, 15.00, Option.Type.Call, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 0.0407, 1e-4 ), + new BinaryOptionData(Barrier.Type.DownOut, 100.00, 15.00, Option.Type.Call, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 4.8758, 1e-4), + new BinaryOptionData(Barrier.Type.DownOut, 100.00, 15.00, Option.Type.Call, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 4.9081, 1e-4), + new BinaryOptionData(Barrier.Type.UpOut, 100.00, 15.00, Option.Type.Call, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4), + new BinaryOptionData(Barrier.Type.UpOut, 100.00, 15.00, Option.Type.Call, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 0.0407, 1e-4), // 25,26 - new BinaryOptionData( Barrier.Type.DownOut, 100.00, 15.00, Option.Type.Put, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 0.0323, 1e-4 ), - new BinaryOptionData( Barrier.Type.DownOut, 100.00, 15.00, Option.Type.Put, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpOut, 100.00, 15.00, Option.Type.Put, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 3.0461, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpOut, 100.00, 15.00, Option.Type.Put, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 3.0054, 1e-4 ), + new BinaryOptionData(Barrier.Type.DownOut, 100.00, 15.00, Option.Type.Put, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 0.0323, 1e-4), + new BinaryOptionData(Barrier.Type.DownOut, 100.00, 15.00, Option.Type.Put, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4), + new BinaryOptionData(Barrier.Type.UpOut, 100.00, 15.00, Option.Type.Put, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 3.0461, 1e-4), + new BinaryOptionData(Barrier.Type.UpOut, 100.00, 15.00, Option.Type.Put, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 3.0054, 1e-4), // other values calculated with book vba - new BinaryOptionData( Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Call, 102.00, 95.00,-0.14, 0.10, 0.5, 0.20, 8.6806, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Call, 102.00, 95.00, 0.03, 0.10, 0.5, 0.20, 5.3112, 1e-4 ), + new BinaryOptionData(Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Call, 102.00, 95.00, -0.14, 0.10, 0.5, 0.20, 8.6806, 1e-4), + new BinaryOptionData(Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Call, 102.00, 95.00, 0.03, 0.10, 0.5, 0.20, 5.3112, 1e-4), // degenerate conditions (barrier touched) - new BinaryOptionData( Barrier.Type.DownIn, 100.00, 15.00, Option.Type.Call, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 7.4926, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Call, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 11.1231, 1e-4 ), + new BinaryOptionData(Barrier.Type.DownIn, 100.00, 15.00, Option.Type.Call, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 7.4926, 1e-4), + new BinaryOptionData(Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Call, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 11.1231, 1e-4), // 17,18 - new BinaryOptionData( Barrier.Type.DownIn, 100.00, 15.00, Option.Type.Put, 102.00, 98.00, 0.00, 0.10, 0.5, 0.20, 7.1344, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Put, 102.00, 101.00, 0.00, 0.10, 0.5, 0.20, 5.9299, 1e-4 ), + new BinaryOptionData(Barrier.Type.DownIn, 100.00, 15.00, Option.Type.Put, 102.00, 98.00, 0.00, 0.10, 0.5, 0.20, 7.1344, 1e-4), + new BinaryOptionData(Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Put, 102.00, 101.00, 0.00, 0.10, 0.5, 0.20, 5.9299, 1e-4), // 21,22 - new BinaryOptionData( Barrier.Type.DownOut, 100.00, 15.00, Option.Type.Call, 98.00, 99.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpOut, 100.00, 15.00, Option.Type.Call, 98.00, 101.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4 ), + new BinaryOptionData(Barrier.Type.DownOut, 100.00, 15.00, Option.Type.Call, 98.00, 99.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4), + new BinaryOptionData(Barrier.Type.UpOut, 100.00, 15.00, Option.Type.Call, 98.00, 101.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4), // 25,26 - new BinaryOptionData( Barrier.Type.DownOut, 100.00, 15.00, Option.Type.Put, 98.00, 99.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpOut, 100.00, 15.00, Option.Type.Put, 98.00, 101.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4 ), + new BinaryOptionData(Barrier.Type.DownOut, 100.00, 15.00, Option.Type.Put, 98.00, 99.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4), + new BinaryOptionData(Barrier.Type.UpOut, 100.00, 15.00, Option.Type.Put, 98.00, 101.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4), }; DayCounter dc = new Actual360(); @@ -161,12 +162,12 @@ public void testCashOrNothingHaugValues() SimpleQuote vol = new SimpleQuote(0.25); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - for (int i=0; i(qTS), new Handle(rTS), new Handle(volTS)); - + IPricingEngine engine = new AnalyticBinaryBarrierEngine(stochProcess); - BarrierOption opt = new BarrierOption(values[i].barrierType,values[i].barrier, 0,payoff,amExercise); + BarrierOption opt = new BarrierOption(values[i].barrierType, values[i].barrier, 0, payoff, amExercise); opt.setPricingEngine(engine); double calculated = opt.NPV(); - double error = Math.Abs(calculated-values[i].result); - if (error > values[i].tol) { - REPORT_FAILURE("value", payoff, amExercise, values[i].barrierType, + double error = Math.Abs(calculated - values[i].result); + if (error > values[i].tol) + { + REPORT_FAILURE("value", payoff, amExercise, values[i].barrierType, values[i].barrier, values[i].s, values[i].q, values[i].r, today, values[i].v, values[i].result, calculated, error, values[i].tol); @@ -196,42 +198,43 @@ public void testCashOrNothingHaugValues() } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testAssetOrNothingHaugValues() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testAssetOrNothingHaugValues() { // Testing asset-or-nothing barrier options against Haug's values - BinaryOptionData[] values = { + BinaryOptionData[] values = + { /* The data below are from "Option pricing formulas 2nd Ed.", E.G. Haug, McGraw-Hill 2007 pag. 180 - cases 15,16,19,20,23,24,27,28 Note: q is the dividend rate, while the book gives b, the cost of carry (q=r-b) */ // barrierType, barrier, cash, type, strike, spot, q, r, t, vol, value, tol - new BinaryOptionData( Barrier.Type.DownIn, 100.00, 0.00, Option.Type.Call, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 37.2782, 1e-4 ), - new BinaryOptionData( Barrier.Type.DownIn, 100.00, 0.00, Option.Type.Call, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 45.8530, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpIn, 100.00, 0.00, Option.Type.Call, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 44.5294, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpIn, 100.00, 0.00, Option.Type.Call, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 54.9262, 1e-4 ), + new BinaryOptionData(Barrier.Type.DownIn, 100.00, 0.00, Option.Type.Call, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 37.2782, 1e-4), + new BinaryOptionData(Barrier.Type.DownIn, 100.00, 0.00, Option.Type.Call, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 45.8530, 1e-4), + new BinaryOptionData(Barrier.Type.UpIn, 100.00, 0.00, Option.Type.Call, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 44.5294, 1e-4), + new BinaryOptionData(Barrier.Type.UpIn, 100.00, 0.00, Option.Type.Call, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 54.9262, 1e-4), // 19,20 - new BinaryOptionData( Barrier.Type.DownIn, 100.00, 0.00, Option.Type.Put, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 27.5644, 1e-4 ), - new BinaryOptionData( Barrier.Type.DownIn, 100.00, 0.00, Option.Type.Put, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 18.9896, 1e-4 ), - // following value is wrong in book. - new BinaryOptionData( Barrier.Type.UpIn, 100.00, 0.00, Option.Type.Put, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 33.1723, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpIn, 100.00, 0.00, Option.Type.Put, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 22.7755, 1e-4 ), + new BinaryOptionData(Barrier.Type.DownIn, 100.00, 0.00, Option.Type.Put, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 27.5644, 1e-4), + new BinaryOptionData(Barrier.Type.DownIn, 100.00, 0.00, Option.Type.Put, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 18.9896, 1e-4), + // following value is wrong in book. + new BinaryOptionData(Barrier.Type.UpIn, 100.00, 0.00, Option.Type.Put, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 33.1723, 1e-4), + new BinaryOptionData(Barrier.Type.UpIn, 100.00, 0.00, Option.Type.Put, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 22.7755, 1e-4), // 23,24 - new BinaryOptionData( Barrier.Type.DownOut, 100.00, 0.00, Option.Type.Call, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 39.9391, 1e-4 ), - new BinaryOptionData( Barrier.Type.DownOut, 100.00, 0.00, Option.Type.Call, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 40.1574, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpOut, 100.00, 0.00, Option.Type.Call, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpOut, 100.00, 0.00, Option.Type.Call, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 0.2676, 1e-4 ), + new BinaryOptionData(Barrier.Type.DownOut, 100.00, 0.00, Option.Type.Call, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 39.9391, 1e-4), + new BinaryOptionData(Barrier.Type.DownOut, 100.00, 0.00, Option.Type.Call, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 40.1574, 1e-4), + new BinaryOptionData(Barrier.Type.UpOut, 100.00, 0.00, Option.Type.Call, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4), + new BinaryOptionData(Barrier.Type.UpOut, 100.00, 0.00, Option.Type.Call, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 0.2676, 1e-4), // 27,28 - new BinaryOptionData( Barrier.Type.DownOut, 100.00, 0.00, Option.Type.Put, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 0.2183, 1e-4 ), - new BinaryOptionData( Barrier.Type.DownOut, 100.00, 0.00, Option.Type.Put, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpOut, 100.00, 0.00, Option.Type.Put, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 17.2983, 1e-4 ), - new BinaryOptionData( Barrier.Type.UpOut, 100.00, 0.00, Option.Type.Put, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 17.0306, 1e-4 ), + new BinaryOptionData(Barrier.Type.DownOut, 100.00, 0.00, Option.Type.Put, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 0.2183, 1e-4), + new BinaryOptionData(Barrier.Type.DownOut, 100.00, 0.00, Option.Type.Put, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4), + new BinaryOptionData(Barrier.Type.UpOut, 100.00, 0.00, Option.Type.Put, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 17.2983, 1e-4), + new BinaryOptionData(Barrier.Type.UpOut, 100.00, 0.00, Option.Type.Put, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 17.0306, 1e-4), }; DayCounter dc = new Actual360(); @@ -245,11 +248,11 @@ public void testAssetOrNothingHaugValues() SimpleQuote vol = new SimpleQuote(0.25); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - for (int i=0; i(qTS), new Handle(rTS), new Handle(volTS)); - + IPricingEngine engine = new AnalyticBinaryBarrierEngine(stochProcess); - BarrierOption opt = new BarrierOption(values[i].barrierType,values[i].barrier, 0,payoff,amExercise); + BarrierOption opt = new BarrierOption(values[i].barrierType, values[i].barrier, 0, payoff, amExercise); opt.setPricingEngine(engine); double calculated = opt.NPV(); - double error = Math.Abs(calculated-values[i].result); - if (error > values[i].tol) + double error = Math.Abs(calculated - values[i].result); + if (error > values[i].tol) { - REPORT_FAILURE("value", payoff, amExercise, values[i].barrierType, + REPORT_FAILURE("value", payoff, amExercise, values[i].barrierType, values[i].barrier, values[i].s, values[i].q, values[i].r, today, values[i].v, values[i].result, calculated, error, values[i].tol); } } - } + } } } diff --git a/tests/QLNet.Tests/T_BlackDeltaCalculator.cs b/tests/QLNet.Tests/T_BlackDeltaCalculator.cs index c9c1660f5..bc9bdbd44 100644 --- a/tests/QLNet.Tests/T_BlackDeltaCalculator.cs +++ b/tests/QLNet.Tests/T_BlackDeltaCalculator.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -18,21 +18,21 @@ #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; namespace TestSuite { #if NET40 || NET45 - [TestClass()] + [TestClass()] #endif public class T_BlackDeltaCalculator { - private int timeToDays( double t ) + private int timeToDays(double t) { // FLOATING_POINT_EXCEPTION - return (int)( t * 360 + 0.5 ); + return (int)(t * 360 + 0.5); } private struct DeltaData @@ -46,8 +46,8 @@ private struct DeltaData public double strike; public double value; - public DeltaData(Option.Type ot, DeltaVolQuote.DeltaType dt, double spot, double dDf, double fDf, - double stdDev, double strike, double value) : this() + public DeltaData(Option.Type ot, DeltaVolQuote.DeltaType dt, double spot, double dDf, double fDf, + double stdDev, double strike, double value) : this() { this.ot = ot; this.dt = dt; @@ -72,8 +72,8 @@ private struct EuropeanOptionData public double result; // expected result public double tol; // tolerance - public EuropeanOptionData(Option.Type type, double strike, double s, double q, double r, double t, - double v, double result, double tol) : this() + public EuropeanOptionData(Option.Type type, double strike, double s, double q, double r, double t, + double v, double result, double tol) : this() { this.type = type; this.strike = strike; @@ -87,25 +87,26 @@ public EuropeanOptionData(Option.Type type, double strike, double s, double q, d } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif public void testDeltaValues() { // Testing delta calculator values - DeltaData[] values = { + DeltaData[] values = + { // Values taken from parallel implementation in R new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.Spot, 1.421, 0.997306, 0.992266, 0.1180654, 1.608080, 0.15), new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.PaSpot, 1.421, 0.997306, 0.992266, 0.1180654, 1.600545, 0.15), new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.Fwd, 1.421, 0.997306, 0.992266, 0.1180654, 1.609029, 0.15), new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.PaFwd, 1.421, 0.997306, 0.992266, 0.1180654, 1.601550, 0.15), - new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.Spot, 122.121, 0.9695434,0.9872347, 0.0887676, 119.8031, 0.67), - new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.PaSpot, 122.121, 0.9695434,0.9872347, 0.0887676, 117.7096, 0.67), - new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.Fwd, 122.121, 0.9695434,0.9872347, 0.0887676, 120.0592, 0.67), - new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.PaFwd, 122.121, 0.9695434,0.9872347, 0.0887676, 118.0532, 0.67), + new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.Spot, 122.121, 0.9695434, 0.9872347, 0.0887676, 119.8031, 0.67), + new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.PaSpot, 122.121, 0.9695434, 0.9872347, 0.0887676, 117.7096, 0.67), + new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.Fwd, 122.121, 0.9695434, 0.9872347, 0.0887676, 120.0592, 0.67), + new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.PaFwd, 122.121, 0.9695434, 0.9872347, 0.0887676, 118.0532, 0.67), new DeltaData(Option.Type.Put, DeltaVolQuote.DeltaType.Spot, 3.4582, 0.99979, 0.9250616, 0.3199034, 4.964924, -0.821), new DeltaData(Option.Type.Put, DeltaVolQuote.DeltaType.PaSpot, 3.4582, 0.99979, 0.9250616, 0.3199034, 3.778327, -0.821), new DeltaData(Option.Type.Put, DeltaVolQuote.DeltaType.Fwd, 3.4582, 0.99979, 0.9250616, 0.3199034, 4.51896, -0.821), @@ -128,60 +129,60 @@ public void testDeltaValues() double error; double tolerance; - for (int i=0; itolerance) + if (error > tolerance) { QAssert.Fail("\n Delta-from-strike calculation failed for delta. \n" - + "Iteration: "+ i + "\n" - + "Calculated Strike:" + calculated + "\n" - + "Expected Strike:" + expected + "\n" - + "Error: " + error); + + "Iteration: " + i + "\n" + + "Calculated Strike:" + calculated + "\n" + + "Expected Strike:" + expected + "\n" + + "Error: " + error); } - tolerance=1.0e-2; + tolerance = 1.0e-2; // tolerance not that small, but sufficient for strikes in // particular since they might be results of a numerical // procedure - expected =currStrike; - calculated =myCalc.strikeFromDelta(currDelta); - error =Math.Abs(calculated-expected); + expected = currStrike; + calculated = myCalc.strikeFromDelta(currDelta); + error = Math.Abs(calculated - expected); - if (error>tolerance) + if (error > tolerance) { QAssert.Fail("\n Strike-from-delta calculation failed for delta. \n" - + "Iteration: "+ i + "\n" - + "Calculated Strike:" + calculated + "\n" - + "Expected Strike:" + expected + "\n" - + "Error: " + error); + + "Iteration: " + i + "\n" + + "Calculated Strike:" + calculated + "\n" + + "Expected Strike:" + expected + "\n" + + "Error: " + error); } } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testDeltaPriceConsistency() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testDeltaPriceConsistency() { // Testing premium-adjusted delta price consistency @@ -192,32 +193,33 @@ public void testDeltaPriceConsistency() SavedSettings backup = new SavedSettings(); // actually, value and tol won't be needed for testing - EuropeanOptionData[] values = { - // type, strike, spot, rd, rf, t, vol, value, tol - new EuropeanOptionData( Option.Type.Call, 0.9123, 1.2212, 0.0231, 0.0000, 0.25, 0.301, 0.0, 0.0), - new EuropeanOptionData( Option.Type.Call, 0.9234, 1.2212, 0.0231, 0.0000, 0.35, 0.111, 0.0, 0.0), - new EuropeanOptionData( Option.Type.Call, 0.9783, 1.2212, 0.0231, 0.0000, 0.45, 0.071, 0.0, 0.0), - new EuropeanOptionData( Option.Type.Call, 1.0000, 1.2212, 0.0231, 0.0000, 0.55, 0.082, 0.0, 0.0), - new EuropeanOptionData( Option.Type.Call, 1.1230, 1.2212, 0.0231, 0.0000, 0.65, 0.012, 0.0, 0.0), - new EuropeanOptionData( Option.Type.Call, 1.2212, 1.2212, 0.0231, 0.0000, 0.75, 0.129, 0.0, 0.0), - new EuropeanOptionData( Option.Type.Call, 1.3212, 1.2212, 0.0231, 0.0000, 0.85, 0.034, 0.0, 0.0), - new EuropeanOptionData( Option.Type.Call, 1.3923, 1.2212, 0.0131, 0.2344, 0.95, 0.001, 0.0, 0.0), - new EuropeanOptionData( Option.Type.Call, 1.3455, 1.2212, 0.0000, 0.0000, 1.00, 0.127, 0.0, 0.0), - new EuropeanOptionData( Option.Type.Put, 0.9123, 1.2212, 0.0231, 0.0000, 0.25, 0.301, 0.0, 0.0), - new EuropeanOptionData( Option.Type.Put, 0.9234, 1.2212, 0.0231, 0.0000, 0.35, 0.111, 0.0, 0.0), - new EuropeanOptionData( Option.Type.Put, 0.9783, 1.2212, 0.0231, 0.0000, 0.45, 0.071, 0.0, 0.0), - new EuropeanOptionData( Option.Type.Put, 1.0000, 1.2212, 0.0231, 0.0000, 0.55, 0.082, 0.0, 0.0), - new EuropeanOptionData( Option.Type.Put, 1.1230, 1.2212, 0.0231, 0.0000, 0.65, 0.012, 0.0, 0.0), - new EuropeanOptionData( Option.Type.Put, 1.2212, 1.2212, 0.0231, 0.0000, 0.75, 0.129, 0.0, 0.0), - new EuropeanOptionData( Option.Type.Put, 1.3212, 1.2212, 0.0231, 0.0000, 0.85, 0.034, 0.0, 0.0), - new EuropeanOptionData( Option.Type.Put, 1.3923, 1.2212, 0.0131, 0.2344, 0.95, 0.001, 0.0, 0.0), - new EuropeanOptionData( Option.Type.Put, 1.3455, 1.2212, 0.0000, 0.0000, 1.00, 0.127, 0.0, 0.0), - // extreme case: zero vol - new EuropeanOptionData( Option.Type.Put, 1.3455, 1.2212, 0.0000, 0.0000, 0.50, 0.000, 0.0, 0.0), - // extreme case: zero strike - new EuropeanOptionData( Option.Type.Put, 0.0000, 1.2212, 0.0000, 0.0000, 1.50, 0.133, 0.0, 0.0), - // extreme case: zero strike+zero vol - new EuropeanOptionData( Option.Type.Put, 0.0000, 1.2212, 0.0000, 0.0000, 1.00, 0.133, 0.0, 0.0), + EuropeanOptionData[] values = + { + // type, strike, spot, rd, rf, t, vol, value, tol + new EuropeanOptionData(Option.Type.Call, 0.9123, 1.2212, 0.0231, 0.0000, 0.25, 0.301, 0.0, 0.0), + new EuropeanOptionData(Option.Type.Call, 0.9234, 1.2212, 0.0231, 0.0000, 0.35, 0.111, 0.0, 0.0), + new EuropeanOptionData(Option.Type.Call, 0.9783, 1.2212, 0.0231, 0.0000, 0.45, 0.071, 0.0, 0.0), + new EuropeanOptionData(Option.Type.Call, 1.0000, 1.2212, 0.0231, 0.0000, 0.55, 0.082, 0.0, 0.0), + new EuropeanOptionData(Option.Type.Call, 1.1230, 1.2212, 0.0231, 0.0000, 0.65, 0.012, 0.0, 0.0), + new EuropeanOptionData(Option.Type.Call, 1.2212, 1.2212, 0.0231, 0.0000, 0.75, 0.129, 0.0, 0.0), + new EuropeanOptionData(Option.Type.Call, 1.3212, 1.2212, 0.0231, 0.0000, 0.85, 0.034, 0.0, 0.0), + new EuropeanOptionData(Option.Type.Call, 1.3923, 1.2212, 0.0131, 0.2344, 0.95, 0.001, 0.0, 0.0), + new EuropeanOptionData(Option.Type.Call, 1.3455, 1.2212, 0.0000, 0.0000, 1.00, 0.127, 0.0, 0.0), + new EuropeanOptionData(Option.Type.Put, 0.9123, 1.2212, 0.0231, 0.0000, 0.25, 0.301, 0.0, 0.0), + new EuropeanOptionData(Option.Type.Put, 0.9234, 1.2212, 0.0231, 0.0000, 0.35, 0.111, 0.0, 0.0), + new EuropeanOptionData(Option.Type.Put, 0.9783, 1.2212, 0.0231, 0.0000, 0.45, 0.071, 0.0, 0.0), + new EuropeanOptionData(Option.Type.Put, 1.0000, 1.2212, 0.0231, 0.0000, 0.55, 0.082, 0.0, 0.0), + new EuropeanOptionData(Option.Type.Put, 1.1230, 1.2212, 0.0231, 0.0000, 0.65, 0.012, 0.0, 0.0), + new EuropeanOptionData(Option.Type.Put, 1.2212, 1.2212, 0.0231, 0.0000, 0.75, 0.129, 0.0, 0.0), + new EuropeanOptionData(Option.Type.Put, 1.3212, 1.2212, 0.0231, 0.0000, 0.85, 0.034, 0.0, 0.0), + new EuropeanOptionData(Option.Type.Put, 1.3923, 1.2212, 0.0131, 0.2344, 0.95, 0.001, 0.0, 0.0), + new EuropeanOptionData(Option.Type.Put, 1.3455, 1.2212, 0.0000, 0.0000, 1.00, 0.127, 0.0, 0.0), + // extreme case: zero vol + new EuropeanOptionData(Option.Type.Put, 1.3455, 1.2212, 0.0000, 0.0000, 0.50, 0.000, 0.0, 0.0), + // extreme case: zero strike + new EuropeanOptionData(Option.Type.Put, 0.0000, 1.2212, 0.0000, 0.0000, 1.50, 0.133, 0.0, 0.0), + // extreme case: zero strike+zero vol + new EuropeanOptionData(Option.Type.Put, 0.0000, 1.2212, 0.0000, 0.0000, 1.00, 0.133, 0.0, 0.0), }; DayCounter dc = new Actual360(); @@ -226,12 +228,12 @@ public void testDeltaPriceConsistency() // Start setup of market data - double discFor =0.0; - double discDom =0.0; - double implVol =0.0; - double expectedVal =0.0; - double calculatedVal =0.0; - double error =0.0; + double discFor = 0.0; + double discDom = 0.0; + double implVol = 0.0; + double expectedVal = 0.0; + double calculatedVal = 0.0; + double error = 0.0; SimpleQuote spotQuote = new SimpleQuote(0.0); Handle spotHandle = new Handle(spotQuote); @@ -255,9 +257,9 @@ public void testDeltaPriceConsistency() Exercise exercise; // Setup of market data finished - double tolerance=1.0e-10; + double tolerance = 1.0e-10; - for(int i=0; i(qTS), - new Handle(rTS), - new Handle(volTS)); + stochProcess = new BlackScholesMertonProcess(spotHandle, + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); engine = new AnalyticEuropeanEngine(stochProcess); EuropeanOption option = new EuropeanOption(payoff, exercise); option.setPricingEngine(engine); - calculatedVal=myCalc.deltaFromStrike(values[i].strike); - expectedVal=option.delta()-option.NPV()/spotQuote.value(); - error=Math.Abs(expectedVal-calculatedVal); + calculatedVal = myCalc.deltaFromStrike(values[i].strike); + expectedVal = option.delta() - option.NPV() / spotQuote.value(); + error = Math.Abs(expectedVal - calculatedVal); - if(error>tolerance) + if (error > tolerance) { - QAssert.Fail("\n Premium-adjusted spot delta test failed. \n" - + "Calculated Delta: " + calculatedVal + "\n" - + "Expected Value: " + expectedVal + "\n" - + "Error: "+ error); + QAssert.Fail("\n Premium-adjusted spot delta test failed. \n" + + "Calculated Delta: " + calculatedVal + "\n" + + "Expected Value: " + expectedVal + "\n" + + "Error: " + error); } myCalc.setDeltaType(DeltaVolQuote.DeltaType.PaFwd); - calculatedVal=myCalc.deltaFromStrike(values[i].strike); - expectedVal=expectedVal/discFor; // Premium adjusted Fwd Delta is PA spot without discount - error=Math.Abs(expectedVal-calculatedVal); + calculatedVal = myCalc.deltaFromStrike(values[i].strike); + expectedVal = expectedVal / discFor; // Premium adjusted Fwd Delta is PA spot without discount + error = Math.Abs(expectedVal - calculatedVal); - if(error>tolerance) + if (error > tolerance) { QAssert.Fail("\n Premium-adjusted forward delta test failed. \n" - + "Calculated Delta: " + calculatedVal + "\n" - + "Expected Value: " + expectedVal + "\n" - + "Error: "+ error); + + "Calculated Delta: " + calculatedVal + "\n" + + "Expected Value: " + expectedVal + "\n" + + "Error: " + error); } // Test consistency with BlackScholes Calculator for Spot Delta myCalc.setDeltaType(DeltaVolQuote.DeltaType.Spot); - calculatedVal=myCalc.deltaFromStrike(values[i].strike); - expectedVal=option.delta(); - error=Math.Abs(calculatedVal-expectedVal); + calculatedVal = myCalc.deltaFromStrike(values[i].strike); + expectedVal = option.delta(); + error = Math.Abs(calculatedVal - expectedVal); - if(error>tolerance) + if (error > tolerance) { QAssert.Fail("\n spot delta in BlackDeltaCalculator differs from delta in BlackScholesCalculator. \n" - + "Calculated Value: " + calculatedVal + "\n" - + "Expected Value: " + expectedVal + "\n" - + "Error: " + error); + + "Calculated Value: " + calculatedVal + "\n" + + "Expected Value: " + expectedVal + "\n" + + "Error: " + error); } } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif public void testPutCallParity() { // Testing put-call parity for deltas @@ -348,69 +350,70 @@ public void testPutCallParity() pag 11-16 */ - EuropeanOptionData[] values = { - // pag 2-8 - // type, strike, spot, q, r, t, vol, value, tol - new EuropeanOptionData( Option.Type.Call, 65.00, 60.00, 0.00, 0.08, 0.25, 0.30, 2.1334, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 95.00, 100.00, 0.05, 0.10, 0.50, 0.20, 2.4648, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 19.00, 19.00, 0.10, 0.10, 0.75, 0.28, 1.7011, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 19.00, 19.00, 0.10, 0.10, 0.75, 0.28, 1.7011, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 1.60, 1.56, 0.08, 0.06, 0.50, 0.12, 0.0291, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 70.00, 75.00, 0.05, 0.10, 0.50, 0.35, 4.0870, 1.0e-4), - // pag 24 - new EuropeanOptionData( Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.10, 0.15, 0.0205, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.10, 0.15, 1.8734, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.10, 0.15, 9.9413, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.10, 0.25, 0.3150, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.10, 0.25, 3.1217, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.10, 0.25, 10.3556, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.10, 0.35, 0.9474, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.10, 0.35, 4.3693, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.10, 0.35, 11.1381, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.50, 0.15, 0.8069, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.50, 0.15, 4.0232, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.50, 0.15, 10.5769, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.50, 0.25, 2.7026, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.50, 0.25, 6.6997, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.50, 0.25, 12.7857, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.50, 0.35, 4.9329, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.50, 0.35, 9.3679, 1.0e-4), - new EuropeanOptionData( Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.50, 0.35, 15.3086, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.10, 0.15, 9.9210, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.10, 0.15, 1.8734, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.10, 0.15, 0.0408, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.10, 0.25, 10.2155, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.10, 0.25, 3.1217, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.10, 0.25, 0.4551, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.10, 0.35, 10.8479, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.10, 0.35, 4.3693, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.10, 0.35, 1.2376, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.50, 0.15, 10.3192, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.50, 0.15, 4.0232, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.50, 0.15, 1.0646, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.50, 0.25, 12.2149, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.50, 0.25, 6.6997, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.50, 0.25, 3.2734, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.50, 0.35, 14.4452, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.50, 0.35, 9.3679, 1.0e-4), - new EuropeanOptionData( Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.50, 0.35, 5.7963, 1.0e-4), - // pag 27 - new EuropeanOptionData( Option.Type.Call, 40.00, 42.00, 0.08, 0.04, 0.75, 0.35, 5.0975, 1.0e-4) + EuropeanOptionData[] values = + { + // pag 2-8 + // type, strike, spot, q, r, t, vol, value, tol + new EuropeanOptionData(Option.Type.Call, 65.00, 60.00, 0.00, 0.08, 0.25, 0.30, 2.1334, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 95.00, 100.00, 0.05, 0.10, 0.50, 0.20, 2.4648, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 19.00, 19.00, 0.10, 0.10, 0.75, 0.28, 1.7011, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 19.00, 19.00, 0.10, 0.10, 0.75, 0.28, 1.7011, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 1.60, 1.56, 0.08, 0.06, 0.50, 0.12, 0.0291, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 70.00, 75.00, 0.05, 0.10, 0.50, 0.35, 4.0870, 1.0e-4), + // pag 24 + new EuropeanOptionData(Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.10, 0.15, 0.0205, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.10, 0.15, 1.8734, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.10, 0.15, 9.9413, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.10, 0.25, 0.3150, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.10, 0.25, 3.1217, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.10, 0.25, 10.3556, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.10, 0.35, 0.9474, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.10, 0.35, 4.3693, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.10, 0.35, 11.1381, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.50, 0.15, 0.8069, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.50, 0.15, 4.0232, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.50, 0.15, 10.5769, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.50, 0.25, 2.7026, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.50, 0.25, 6.6997, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.50, 0.25, 12.7857, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 100.00, 90.00, 0.10, 0.10, 0.50, 0.35, 4.9329, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.50, 0.35, 9.3679, 1.0e-4), + new EuropeanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.50, 0.35, 15.3086, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.10, 0.15, 9.9210, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.10, 0.15, 1.8734, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.10, 0.15, 0.0408, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.10, 0.25, 10.2155, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.10, 0.25, 3.1217, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.10, 0.25, 0.4551, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.10, 0.35, 10.8479, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.10, 0.35, 4.3693, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.10, 0.35, 1.2376, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.50, 0.15, 10.3192, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.50, 0.15, 4.0232, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.50, 0.15, 1.0646, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.50, 0.25, 12.2149, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.50, 0.25, 6.6997, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.50, 0.25, 3.2734, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.50, 0.35, 14.4452, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.50, 0.35, 9.3679, 1.0e-4), + new EuropeanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.50, 0.35, 5.7963, 1.0e-4), + // pag 27 + new EuropeanOptionData(Option.Type.Call, 40.00, 42.00, 0.08, 0.04, 0.75, 0.35, 5.0975, 1.0e-4) }; DayCounter dc = new Actual360(); Calendar calendar = new TARGET(); Date today = Date.Today; - double discFor =0.0; - double discDom =0.0; - double implVol =0.0; - double deltaCall =0.0; - double deltaPut =0.0; - double expectedDiff =0.0; - double calculatedDiff =0.0; - double error =0.0; - double forward =0.0; + double discFor = 0.0; + double discDom = 0.0; + double implVol = 0.0; + double deltaCall = 0.0; + double deltaPut = 0.0; + double expectedDiff = 0.0; + double calculatedDiff = 0.0; + double error = 0.0; + double forward = 0.0; SimpleQuote spotQuote = new SimpleQuote(0.0); @@ -430,9 +433,9 @@ pag 11-16 Date exDate; Exercise exercise; - double tolerance=1.0e-10; + double tolerance = 1.0e-10; - for(int i=0; itolerance) + if (error > tolerance) { QAssert.Fail("\n Put-call parity failed for spot delta. \n" - + "Calculated Call Delta: " + deltaCall + "\n" - + "Calculated Put Delta: " + deltaPut + "\n" - + "Expected Difference: " + expectedDiff + "\n" - + "Calculated Difference: " + calculatedDiff); + + "Calculated Call Delta: " + deltaCall + "\n" + + "Calculated Put Delta: " + deltaPut + "\n" + + "Expected Difference: " + expectedDiff + "\n" + + "Calculated Difference: " + calculatedDiff); } myCalc.setDeltaType(DeltaVolQuote.DeltaType.Fwd); - deltaCall=myCalc.deltaFromStrike(values[i].strike); + deltaCall = myCalc.deltaFromStrike(values[i].strike); myCalc.setOptionType(Option.Type.Put); - deltaPut=myCalc.deltaFromStrike(values[i].strike); + deltaPut = myCalc.deltaFromStrike(values[i].strike); myCalc.setOptionType(Option.Type.Call); - expectedDiff=1.0; - calculatedDiff=deltaCall-deltaPut; - error=Math.Abs(expectedDiff-calculatedDiff); + expectedDiff = 1.0; + calculatedDiff = deltaCall - deltaPut; + error = Math.Abs(expectedDiff - calculatedDiff); - if(error>tolerance) + if (error > tolerance) { QAssert.Fail("\n Put-call parity failed for forward delta. \n" - + "Calculated Call Delta: " + deltaCall + "\n" - + "Calculated Put Delta: " + deltaPut + "\n" - + "Expected Difference: " + expectedDiff + "\n" - + "Calculated Difference: " + calculatedDiff ); + + "Calculated Call Delta: " + deltaCall + "\n" + + "Calculated Put Delta: " + deltaPut + "\n" + + "Expected Difference: " + expectedDiff + "\n" + + "Calculated Difference: " + calculatedDiff); } myCalc.setDeltaType(DeltaVolQuote.DeltaType.PaSpot); - deltaCall=myCalc.deltaFromStrike(values[i].strike); + deltaCall = myCalc.deltaFromStrike(values[i].strike); myCalc.setOptionType(Option.Type.Put); - deltaPut=myCalc.deltaFromStrike(values[i].strike); + deltaPut = myCalc.deltaFromStrike(values[i].strike); myCalc.setOptionType(Option.Type.Call); - expectedDiff=discFor*values[i].strike/forward; - calculatedDiff=deltaCall-deltaPut; - error=Math.Abs(expectedDiff-calculatedDiff); + expectedDiff = discFor * values[i].strike / forward; + calculatedDiff = deltaCall - deltaPut; + error = Math.Abs(expectedDiff - calculatedDiff); - if(error>tolerance) + if (error > tolerance) { QAssert.Fail("\n Put-call parity failed for premium-adjusted spot delta. \n" - + "Calculated Call Delta: " + deltaCall + "\n" - + "Calculated Put Delta: " + deltaPut + "\n" - + "Expected Difference: " + expectedDiff + "\n" - + "Calculated Difference: " + calculatedDiff); + + "Calculated Call Delta: " + deltaCall + "\n" + + "Calculated Put Delta: " + deltaPut + "\n" + + "Expected Difference: " + expectedDiff + "\n" + + "Calculated Difference: " + calculatedDiff); } myCalc.setDeltaType(DeltaVolQuote.DeltaType.PaFwd); - deltaCall=myCalc.deltaFromStrike(values[i].strike); + deltaCall = myCalc.deltaFromStrike(values[i].strike); myCalc.setOptionType(Option.Type.Put); - deltaPut=myCalc.deltaFromStrike(values[i].strike); + deltaPut = myCalc.deltaFromStrike(values[i].strike); myCalc.setOptionType(Option.Type.Call); - expectedDiff = values[i].strike/forward; - calculatedDiff=deltaCall-deltaPut; - error=Math.Abs(expectedDiff-calculatedDiff); + expectedDiff = values[i].strike / forward; + calculatedDiff = deltaCall - deltaPut; + error = Math.Abs(expectedDiff - calculatedDiff); - if(error>tolerance) + if (error > tolerance) { QAssert.Fail("\n Put-call parity failed for premium-adjusted forward delta. \n" - + "Calculated Call Delta: " + deltaCall + "\n" - + "Calculated Put Delta: " + deltaPut + "\n" - + "Expected Difference: " + expectedDiff + "\n" - + "Calculated Difference: " + calculatedDiff); + + "Calculated Call Delta: " + deltaCall + "\n" + + "Calculated Put Delta: " + deltaPut + "\n" + + "Expected Difference: " + expectedDiff + "\n" + + "Calculated Difference: " + calculatedDiff); } } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif public void testAtmCalcs() { // Testing delta-neutral ATM quotations SavedSettings backup = new SavedSettings(); - DeltaData[] values = { + DeltaData[] values = + { new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.Spot, 1.421, 0.997306, 0.992266, 0.1180654, 1.608080, 0.15), new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.PaSpot, 1.421, 0.997306, 0.992266, 0.1180654, 1.600545, 0.15), new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.Fwd, 1.421, 0.997306, 0.992266, 0.1180654, 1.609029, 0.15), new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.PaFwd, 1.421, 0.997306, 0.992266, 0.1180654, 1.601550, 0.15), - new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.Spot, 122.121, 0.9695434,0.9872347, 0.0887676, 119.8031, 0.67), - new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.PaSpot, 122.121, 0.9695434,0.9872347, 0.0887676, 117.7096, 0.67), - new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.Fwd, 122.121, 0.9695434,0.9872347, 0.0887676, 120.0592, 0.67), - new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.PaFwd, 122.121, 0.9695434,0.9872347, 0.0887676, 118.0532, 0.67), + new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.Spot, 122.121, 0.9695434, 0.9872347, 0.0887676, 119.8031, 0.67), + new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.PaSpot, 122.121, 0.9695434, 0.9872347, 0.0887676, 117.7096, 0.67), + new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.Fwd, 122.121, 0.9695434, 0.9872347, 0.0887676, 120.0592, 0.67), + new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.PaFwd, 122.121, 0.9695434, 0.9872347, 0.0887676, 118.0532, 0.67), new DeltaData(Option.Type.Put, DeltaVolQuote.DeltaType.Spot, 3.4582, 0.99979, 0.9250616, 0.3199034, 4.964924, -0.821), new DeltaData(Option.Type.Put, DeltaVolQuote.DeltaType.PaSpot, 3.4582, 0.99979, 0.9250616, 0.3199034, 3.778327, -0.821), new DeltaData(Option.Type.Put, DeltaVolQuote.DeltaType.Fwd, 3.4582, 0.99979, 0.9250616, 0.3199034, 4.51896, -0.821), @@ -556,8 +560,8 @@ public void testAtmCalcs() new DeltaData(Option.Type.Put, DeltaVolQuote.DeltaType.Spot, 103.00, 0.99482, 0.98508, 0.07247845, 97.47, -0.25), new DeltaData(Option.Type.Put, DeltaVolQuote.DeltaType.PaSpot, 103.00, 0.99482, 0.98508, 0.07247845, 97.22, -0.25), // Extreme case: zero vol, ATM Fwd strike - new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.Fwd, 103.00, 0.99482, 0.98508, 0.0, 101.0013,0.5), - new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.Spot, 103.00, 0.99482, 0.98508, 0.0, 101.0013,0.99482*0.5) + new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.Fwd, 103.00, 0.99482, 0.98508, 0.0, 101.0013, 0.5), + new DeltaData(Option.Type.Call, DeltaVolQuote.DeltaType.Spot, 103.00, 0.99482, 0.98508, 0.0, 101.0013, 0.99482 * 0.5) }; DeltaVolQuote.DeltaType currDt; @@ -568,132 +572,132 @@ public void testAtmCalcs() double expected; double calculated; double error; - double tolerance=1.0e-2; // not that small, but sufficient for strikes + double tolerance = 1.0e-2; // not that small, but sufficient for strikes double currAtmStrike; double currCallDelta; double currPutDelta; double currFwd; - for (int i=0; i< values.Length; i++) + for (int i = 0; i < values.Length; i++) { - currDt =values[i].dt; - currSpot =values[i].spot; - currdDf =values[i].dDf; - currfDf =values[i].fDf; - currStdDev =values[i].stdDev; - currFwd =currSpot*currfDf/currdDf; + currDt = values[i].dt; + currSpot = values[i].spot; + currdDf = values[i].dDf; + currfDf = values[i].fDf; + currStdDev = values[i].stdDev; + currFwd = currSpot * currfDf / currdDf; BlackDeltaCalculator myCalc = new BlackDeltaCalculator(Option.Type.Call, currDt, currSpot, currdDf, - currfDf, currStdDev); + currfDf, currStdDev); - currAtmStrike=myCalc.atmStrike(DeltaVolQuote.AtmType.AtmDeltaNeutral); - currCallDelta=myCalc.deltaFromStrike(currAtmStrike); + currAtmStrike = myCalc.atmStrike(DeltaVolQuote.AtmType.AtmDeltaNeutral); + currCallDelta = myCalc.deltaFromStrike(currAtmStrike); myCalc.setOptionType(Option.Type.Put); - currPutDelta=myCalc.deltaFromStrike(currAtmStrike); + currPutDelta = myCalc.deltaFromStrike(currAtmStrike); myCalc.setOptionType(Option.Type.Call); - expected =0.0; - calculated =currCallDelta+currPutDelta; - error =Math.Abs(calculated-expected); + expected = 0.0; + calculated = currCallDelta + currPutDelta; + error = Math.Abs(calculated - expected); - if(error>tolerance) + if (error > tolerance) { QAssert.Fail("\n Delta neutrality failed for spot delta in Delta Calculator. \n" - + "Iteration: "+ i + "\n" - + "Calculated Delta Sum: " + calculated + "\n" - + "Expected Delta Sum: " + expected + "\n" - + "Error: " + error); + + "Iteration: " + i + "\n" + + "Calculated Delta Sum: " + calculated + "\n" + + "Expected Delta Sum: " + expected + "\n" + + "Error: " + error); } myCalc.setDeltaType(DeltaVolQuote.DeltaType.Fwd); - currAtmStrike=myCalc.atmStrike(DeltaVolQuote.AtmType.AtmDeltaNeutral); - currCallDelta=myCalc.deltaFromStrike(currAtmStrike); + currAtmStrike = myCalc.atmStrike(DeltaVolQuote.AtmType.AtmDeltaNeutral); + currCallDelta = myCalc.deltaFromStrike(currAtmStrike); myCalc.setOptionType(Option.Type.Put); - currPutDelta=myCalc.deltaFromStrike(currAtmStrike); + currPutDelta = myCalc.deltaFromStrike(currAtmStrike); myCalc.setOptionType(Option.Type.Call); - expected =0.0; - calculated =currCallDelta+currPutDelta; - error =Math.Abs(calculated-expected); + expected = 0.0; + calculated = currCallDelta + currPutDelta; + error = Math.Abs(calculated - expected); - if(error>tolerance) + if (error > tolerance) { QAssert.Fail("\n Delta neutrality failed for forward delta in Delta Calculator. \n" - + "Iteration: " + i + "\n" - + "Calculated Delta Sum: " + calculated + "\n" - + "Expected Delta Sum: " + expected + "\n" - + "Error: " + error); + + "Iteration: " + i + "\n" + + "Calculated Delta Sum: " + calculated + "\n" + + "Expected Delta Sum: " + expected + "\n" + + "Error: " + error); } myCalc.setDeltaType(DeltaVolQuote.DeltaType.PaSpot); - currAtmStrike=myCalc.atmStrike(DeltaVolQuote.AtmType.AtmDeltaNeutral); - currCallDelta=myCalc.deltaFromStrike(currAtmStrike); + currAtmStrike = myCalc.atmStrike(DeltaVolQuote.AtmType.AtmDeltaNeutral); + currCallDelta = myCalc.deltaFromStrike(currAtmStrike); myCalc.setOptionType(Option.Type.Put); - currPutDelta=myCalc.deltaFromStrike(currAtmStrike); + currPutDelta = myCalc.deltaFromStrike(currAtmStrike); myCalc.setOptionType(Option.Type.Call); - expected =0.0; - calculated =currCallDelta+currPutDelta; - error =Math.Abs(calculated-expected); + expected = 0.0; + calculated = currCallDelta + currPutDelta; + error = Math.Abs(calculated - expected); - if(error>tolerance) + if (error > tolerance) { QAssert.Fail("\n Delta neutrality failed for premium-adjusted spot delta in Delta Calculator. \n" - + "Iteration: " + i + "\n" - + "Calculated Delta Sum: " + calculated + "\n" - + "Expected Delta Sum: " + expected + "\n" - + "Error: " + error); + + "Iteration: " + i + "\n" + + "Calculated Delta Sum: " + calculated + "\n" + + "Expected Delta Sum: " + expected + "\n" + + "Error: " + error); } myCalc.setDeltaType(DeltaVolQuote.DeltaType.PaFwd); - currAtmStrike=myCalc.atmStrike(DeltaVolQuote.AtmType.AtmDeltaNeutral); - currCallDelta=myCalc.deltaFromStrike(currAtmStrike); + currAtmStrike = myCalc.atmStrike(DeltaVolQuote.AtmType.AtmDeltaNeutral); + currCallDelta = myCalc.deltaFromStrike(currAtmStrike); myCalc.setOptionType(Option.Type.Put); - currPutDelta=myCalc.deltaFromStrike(currAtmStrike); + currPutDelta = myCalc.deltaFromStrike(currAtmStrike); myCalc.setOptionType(Option.Type.Call); - expected =0.0; - calculated =currCallDelta+currPutDelta; - error =Math.Abs(calculated-expected); + expected = 0.0; + calculated = currCallDelta + currPutDelta; + error = Math.Abs(calculated - expected); - if(error>tolerance) + if (error > tolerance) { QAssert.Fail("\n Delta neutrality failed for premium-adjusted forward delta in Delta Calculator. \n" - + "Iteration: " + i + "\n" - + "Calculated Delta Sum: " + calculated + "\n" - + "Expected Delta Sum: " + expected + "\n" - + "Error: " + error); + + "Iteration: " + i + "\n" + + "Calculated Delta Sum: " + calculated + "\n" + + "Expected Delta Sum: " + expected + "\n" + + "Error: " + error); } // Test ATM forward Calculations - calculated=myCalc.atmStrike(DeltaVolQuote.AtmType.AtmFwd); - expected=currFwd; - error=Math.Abs(expected-calculated); + calculated = myCalc.atmStrike(DeltaVolQuote.AtmType.AtmFwd); + expected = currFwd; + error = Math.Abs(expected - calculated); - if(error>tolerance) + if (error > tolerance) { QAssert.Fail("\n Atm forward test failed. \n" - + "Calculated Value: " + calculated + "\n" - + "Expected Value: " + expected + "\n" - + "Error: " + error); + + "Calculated Value: " + calculated + "\n" + + "Expected Value: " + expected + "\n" + + "Error: " + error); } // Test ATM 0.50 delta calculations myCalc.setDeltaType(DeltaVolQuote.DeltaType.Fwd); - double atmFiftyStrike=myCalc.atmStrike(DeltaVolQuote.AtmType.AtmPutCall50); - calculated=Math.Abs(myCalc.deltaFromStrike(atmFiftyStrike)); - expected=0.50; - error=Math.Abs(expected-calculated); + double atmFiftyStrike = myCalc.atmStrike(DeltaVolQuote.AtmType.AtmPutCall50); + calculated = Math.Abs(myCalc.deltaFromStrike(atmFiftyStrike)); + expected = 0.50; + error = Math.Abs(expected - calculated); - if(error>tolerance) + if (error > tolerance) { QAssert.Fail("\n Atm 0.50 delta strike test failed. \n" - + "Iteration:" + i + "\n" - + "Calculated Value: " + calculated + "\n" - + "Expected Value: " + expected + "\n" - + "Error: " + error); + + "Iteration:" + i + "\n" + + "Calculated Value: " + calculated + "\n" + + "Expected Value: " + expected + "\n" + + "Error: " + error); } } } diff --git a/tests/QLNet.Tests/T_BlackFormula.cs b/tests/QLNet.Tests/T_BlackFormula.cs index a8a2fd817..d8caa45fb 100644 --- a/tests/QLNet.Tests/T_BlackFormula.cs +++ b/tests/QLNet.Tests/T_BlackFormula.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,7 +20,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -29,98 +29,99 @@ namespace TestSuite #if NET40 || NET45 [TestClass()] #endif - public class T_BlackFormula - { + public class T_BlackFormula + { #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testBachelierImpliedVol() - { - // Testing Bachelier implied vol... + public void testBachelierImpliedVol() + { + // Testing Bachelier implied vol... - double forward = 1.0; - double bpvol = 0.01; - double tte = 10.0; - double stdDev = bpvol*Math.Sqrt(tte); - Option.Type optionType = Option.Type.Call; - double discount = 0.95; + double forward = 1.0; + double bpvol = 0.01; + double tte = 10.0; + double stdDev = bpvol * Math.Sqrt(tte); + Option.Type optionType = Option.Type.Call; + double discount = 0.95; - double[] d = {-3.0, -2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0, 3.0}; - for(int i=0;i 1.0e-12) + { + QAssert.Fail("Failed, expected " + bpvol + " realised " + impliedBpVol); + } + } + return; + } - if (Math.Abs(bpvol-impliedBpVol)>1.0e-12) - { - QAssert.Fail("Failed, expected " + bpvol + " realised " + impliedBpVol ); - } - } - return; - } - - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testChambersImpliedVol() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testChambersImpliedVol() { // Testing Chambers-Nawalkha implied vol approximation Option.Type[] types = {Option.Type.Call, Option.Type.Put}; double[] displacements = {0.0000, 0.0010, 0.0050, 0.0100, 0.0200}; double[] forwards = {-0.0010, 0.0000, 0.0050, 0.0100, 0.0200, 0.0500}; - double[] strikes = {-0.0100, -0.0050, -0.0010, 0.0000, 0.0010, 0.0050,0.0100, 0.0200, 0.0500, 0.1000}; - double[] stdDevs = {0.10, 0.15, 0.20, 0.30, 0.50, 0.60, 0.70,0.80, 1.00, 1.50, 2.00}; + double[] strikes = {-0.0100, -0.0050, -0.0010, 0.0000, 0.0010, 0.0050, 0.0100, 0.0200, 0.0500, 0.1000}; + double[] stdDevs = {0.10, 0.15, 0.20, 0.30, 0.50, 0.60, 0.70, 0.80, 1.00, 1.50, 2.00}; double[] discounts = {1.00, 0.95, 0.80, 1.10}; double tol = 5.0E-4; - for (int i1 = 0; i1 < types.Length; ++i1) + for (int i1 = 0; i1 < types.Length; ++i1) { - for (int i2 = 0; i2 < displacements.Length; ++i2) + for (int i2 = 0; i2 < displacements.Length; ++i2) { - for (int i3 = 0; i3 < forwards.Length; ++i3) + for (int i3 = 0; i3 < forwards.Length; ++i3) { - for (int i4 = 0; i4 < strikes.Length; ++i4) + for (int i4 = 0; i4 < strikes.Length; ++i4) { - for (int i5 = 0; i5 < stdDevs.Length; ++i5) + for (int i5 = 0; i5 < stdDevs.Length; ++i5) { - for (int i6 = 0; i6 < discounts.Length; ++i6) + for (int i6 = 0; i6 < discounts.Length; ++i6) { if (forwards[i3] + displacements[i2] > 0.0 && - strikes[i4] + displacements[i2] > 0.0) + strikes[i4] + displacements[i2] > 0.0) { double premium = Utils.blackFormula( - types[i1], strikes[i4], forwards[i3], - stdDevs[i5], discounts[i6], - displacements[i2]); - double atmPremium = Utils.blackFormula( - types[i1], forwards[i3], forwards[i3], + types[i1], strikes[i4], forwards[i3], stdDevs[i5], discounts[i6], displacements[i2]); + double atmPremium = Utils.blackFormula( + types[i1], forwards[i3], forwards[i3], + stdDevs[i5], discounts[i6], + displacements[i2]); double iStdDev = Utils.blackFormulaImpliedStdDevChambers( - types[i1], strikes[i4], forwards[i3], - premium, atmPremium, discounts[i6], - displacements[i2]); + types[i1], strikes[i4], forwards[i3], + premium, atmPremium, discounts[i6], + displacements[i2]); double moneyness = (strikes[i4] + displacements[i2]) / (forwards[i3] + displacements[i2]); - if(moneyness > 1.0) moneyness = 1.0 / moneyness; + if (moneyness > 1.0) + moneyness = 1.0 / moneyness; double error = (iStdDev - stdDevs[i5]) / stdDevs[i5] * moneyness; - if(error > tol) + if (error > tol) QAssert.Fail("Failed to verify Chambers-Nawalkha approximation for " - + types[i1] - + " displacement=" + displacements[i2] - + " forward=" + forwards[i3] - + " strike=" + strikes[i4] - + " discount=" + discounts[i6] - + " stddev=" + stdDevs[i5] - + " result=" + iStdDev - + " exceeds maximum error tolerance"); + + types[i1] + + " displacement=" + displacements[i2] + + " forward=" + forwards[i3] + + " strike=" + strikes[i4] + + " discount=" + discounts[i6] + + " stddev=" + stdDevs[i5] + + " result=" + iStdDev + + " exceeds maximum error tolerance"); } } } @@ -129,5 +130,5 @@ public void testChambersImpliedVol() } } } - } + } } diff --git a/tests/QLNet.Tests/T_Bonds.cs b/tests/QLNet.Tests/T_Bonds.cs index 7ca9a190d..1d041757a 100644 --- a/tests/QLNet.Tests/T_Bonds.cs +++ b/tests/QLNet.Tests/T_Bonds.cs @@ -7,7 +7,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -23,7 +23,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -36,19 +36,19 @@ public class T_Bonds : IDisposable { #region Initialize&Cleanup private SavedSettings backup; - #if NET40 || NET45 +#if NET40 || NET45 [TestInitialize] public void testInitialize() { - #else +#else public T_Bonds() { - #endif - backup = new SavedSettings(); - } - #if NET40 || NET45 +#endif + backup = new SavedSettings(); + } +#if NET40 || NET45 [TestCleanup] - #endif +#endif public void testCleanup() { Dispose(); @@ -77,9 +77,9 @@ public CommonVars() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testYield() { @@ -123,9 +123,9 @@ public void testYield() accrualConvention, accrualConvention, DateGeneration.Rule.Backward, false); FixedRateBond bond = new FixedRateBond(settlementDays, vars.faceAmount, sch, - new List() { coupons[k] }, - bondDayCount, paymentConvention, - redemption, issue); + new List() { coupons[k] }, + bondDayCount, paymentConvention, + redemption, issue); for (int m = 0; m < yields.Length; m++) { @@ -141,15 +141,15 @@ public void testYield() if (Math.Abs(price - price2) / price > tolerance) { QAssert.Fail("yield recalculation failed:\n" - + " issue: " + issue + "\n" - + " maturity: " + maturity + "\n" - + " coupon: " + coupons[k] + "\n" - + " frequency: " + frequencies[l] + "\n\n" - + " yield: " + yields[m] + " " - + (compounding[n] == Compounding.Compounded ? "compounded" : "continuous") + "\n" - + " price: " + price + "\n" - + " yield': " + calculated + "\n" - + " price': " + price2); + + " issue: " + issue + "\n" + + " maturity: " + maturity + "\n" + + " coupon: " + coupons[k] + "\n" + + " frequency: " + frequencies[l] + "\n\n" + + " yield: " + yields[m] + " " + + (compounding[n] == Compounding.Compounded ? "compounded" : "continuous") + "\n" + + " price: " + price + "\n" + + " yield': " + calculated + "\n" + + " price': " + price2); } } } @@ -160,9 +160,9 @@ public void testYield() } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testTheoretical() { @@ -202,7 +202,7 @@ public void testTheoretical() accrualConvention, accrualConvention, DateGeneration.Rule.Backward, false); FixedRateBond bond = new FixedRateBond(settlementDays, vars.faceAmount, sch, new List() { coupons[k] }, - bondDayCount, paymentConvention, redemption, issue); + bondDayCount, paymentConvention, redemption, issue); IPricingEngine bondEngine = new DiscountingBondEngine(discountCurve); bond.setPricingEngine(bondEngine); @@ -218,28 +218,28 @@ public void testTheoretical() if (Math.Abs(price - calculatedPrice) > tolerance) { QAssert.Fail("price calculation failed:" - + "\n issue: " + issue - + "\n maturity: " + maturity - + "\n coupon: " + coupons[k] - + "\n frequency: " + frequencies[l] + "\n" - + "\n yield: " + yields[m] - + "\n expected: " + price - + "\n calculated': " + calculatedPrice - + "\n error': " + (price - calculatedPrice)); + + "\n issue: " + issue + + "\n maturity: " + maturity + + "\n coupon: " + coupons[k] + + "\n frequency: " + frequencies[l] + "\n" + + "\n yield: " + yields[m] + + "\n expected: " + price + + "\n calculated': " + calculatedPrice + + "\n error': " + (price - calculatedPrice)); } double calculatedYield = bond.yield(bondDayCount, Compounding.Continuous, frequencies[l], - tolerance, maxEvaluations); + tolerance, maxEvaluations); if (Math.Abs(yields[m] - calculatedYield) > tolerance) { QAssert.Fail("yield calculation failed:" - + "\n issue: " + issue - + "\n maturity: " + maturity - + "\n coupon: " + coupons[k] - + "\n frequency: " + frequencies[l] + "\n" - + "\n yield: " + yields[m] - + "\n price: " + price - + "\n yield': " + calculatedYield); + + "\n issue: " + issue + + "\n maturity: " + maturity + + "\n coupon: " + coupons[k] + + "\n frequency: " + frequencies[l] + "\n" + + "\n yield: " + yields[m] + + "\n price: " + price + + "\n yield': " + calculatedYield); } } } @@ -247,9 +247,9 @@ public void testTheoretical() } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testCached() { @@ -274,7 +274,7 @@ public void testCached() DateGeneration.Rule.Backward, false); FixedRateBond bond1 = new FixedRateBond(settlementDays, vars.faceAmount, sch1, new List() { 0.025 }, - bondDayCount, BusinessDayConvention.ModifiedFollowing, 100.0, new Date(1, Month.November, 2004)); + bondDayCount, BusinessDayConvention.ModifiedFollowing, 100.0, new Date(1, Month.November, 2004)); IPricingEngine bondEngine = new DiscountingBondEngine(discountCurve); bond1.setPricingEngine(bondEngine); @@ -287,8 +287,8 @@ public void testCached() DateGeneration.Rule.Backward, false); FixedRateBond bond2 = new FixedRateBond(settlementDays, vars.faceAmount, sch2, new List() { 0.035 }, - bondDayCount, BusinessDayConvention.ModifiedFollowing, - 100.0, new Date(15, Month.November, 2004)); + bondDayCount, BusinessDayConvention.ModifiedFollowing, + 100.0, new Date(15, Month.November, 2004)); bond2.setPricingEngine(bondEngine); @@ -310,50 +310,50 @@ public void testCached() if (Math.Abs(price - cachedPrice1a) > tolerance) { QAssert.Fail("failed to reproduce cached price:" - + "\n calculated: " + price - + "\n expected: " + cachedPrice1a - + "\n tolerance: " + tolerance - + "\n error: " + (price - cachedPrice1a)); + + "\n calculated: " + price + + "\n expected: " + cachedPrice1a + + "\n tolerance: " + tolerance + + "\n error: " + (price - cachedPrice1a)); } price = bond1.cleanPrice(); if (Math.Abs(price - cachedPrice1b) > tolerance) { QAssert.Fail("failed to reproduce cached price:" - + "\n calculated: " + price - + "\n expected: " + cachedPrice1b - + "\n tolerance: " + tolerance - + "\n error: " + (price - cachedPrice1b)); + + "\n calculated: " + price + + "\n expected: " + cachedPrice1b + + "\n tolerance: " + tolerance + + "\n error: " + (price - cachedPrice1b)); } yield = bond1.yield(marketPrice1, bondDayCount, Compounding.Compounded, freq); if (Math.Abs(yield - cachedYield1a) > tolerance) { QAssert.Fail("failed to reproduce cached compounded yield:" - + "\n calculated: " + yield - + "\n expected: " + cachedYield1a - + "\n tolerance: " + tolerance - + "\n error: " + (yield - cachedYield1a)); + + "\n calculated: " + yield + + "\n expected: " + cachedYield1a + + "\n tolerance: " + tolerance + + "\n error: " + (yield - cachedYield1a)); } yield = bond1.yield(marketPrice1, bondDayCount, Compounding.Continuous, freq); if (Math.Abs(yield - cachedYield1b) > tolerance) { QAssert.Fail("failed to reproduce cached continuous yield:" - + "\n calculated: " + yield - + "\n expected: " + cachedYield1b - + "\n tolerance: " + tolerance - + "\n error: " + (yield - cachedYield1b)); + + "\n calculated: " + yield + + "\n expected: " + cachedYield1b + + "\n tolerance: " + tolerance + + "\n error: " + (yield - cachedYield1b)); } yield = bond1.yield(bondDayCount, Compounding.Continuous, freq); if (Math.Abs(yield - cachedYield1c) > tolerance) { QAssert.Fail("failed to reproduce cached continuous yield:" - + "\n calculated: " + yield - + "\n expected: " + cachedYield1c - + "\n tolerance: " + tolerance - + "\n error: " + (yield - cachedYield1c)); + + "\n calculated: " + yield + + "\n expected: " + cachedYield1c + + "\n tolerance: " + tolerance + + "\n error: " + (yield - cachedYield1c)); } @@ -361,50 +361,50 @@ public void testCached() if (Math.Abs(price - cachedPrice2a) > tolerance) { QAssert.Fail("failed to reproduce cached price:" - + "\n calculated: " + price - + "\n expected: " + cachedPrice2a - + "\n tolerance: " + tolerance - + "\n error: " + (price - cachedPrice2a)); + + "\n calculated: " + price + + "\n expected: " + cachedPrice2a + + "\n tolerance: " + tolerance + + "\n error: " + (price - cachedPrice2a)); } price = bond2.cleanPrice(); if (Math.Abs(price - cachedPrice2b) > tolerance) { QAssert.Fail("failed to reproduce cached price:" - + "\n calculated: " + price - + "\n expected: " + cachedPrice2b - + "\n tolerance: " + tolerance - + "\n error: " + (price - cachedPrice2b)); + + "\n calculated: " + price + + "\n expected: " + cachedPrice2b + + "\n tolerance: " + tolerance + + "\n error: " + (price - cachedPrice2b)); } yield = bond2.yield(marketPrice2, bondDayCount, Compounding.Compounded, freq); if (Math.Abs(yield - cachedYield2a) > tolerance) { QAssert.Fail("failed to reproduce cached compounded yield:" - + "\n calculated: " + yield - + "\n expected: " + cachedYield2a - + "\n tolerance: " + tolerance - + "\n error: " + (yield - cachedYield2a)); + + "\n calculated: " + yield + + "\n expected: " + cachedYield2a + + "\n tolerance: " + tolerance + + "\n error: " + (yield - cachedYield2a)); } yield = bond2.yield(marketPrice2, bondDayCount, Compounding.Continuous, freq); if (Math.Abs(yield - cachedYield2b) > tolerance) { QAssert.Fail("failed to reproduce cached continuous yield:" - + "\n calculated: " + yield - + "\n expected: " + cachedYield2b - + "\n tolerance: " + tolerance - + "\n error: " + (yield - cachedYield2b)); + + "\n calculated: " + yield + + "\n expected: " + cachedYield2b + + "\n tolerance: " + tolerance + + "\n error: " + (yield - cachedYield2b)); } yield = bond2.yield(bondDayCount, Compounding.Continuous, freq); if (Math.Abs(yield - cachedYield2c) > tolerance) { QAssert.Fail("failed to reproduce cached continuous yield:" - + "\n calculated: " + yield - + "\n expected: " + cachedYield2c - + "\n tolerance: " + tolerance - + "\n error: " + (yield - cachedYield2c)); + + "\n calculated: " + yield + + "\n expected: " + cachedYield2c + + "\n tolerance: " + tolerance + + "\n error: " + (yield - cachedYield2c)); } // with explicit settlement date: @@ -413,8 +413,8 @@ public void testCached() BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); FixedRateBond bond3 = new FixedRateBond(settlementDays, vars.faceAmount, sch3, new List() { 0.02875 }, - new ActualActual(ActualActual.Convention.ISMA), - BusinessDayConvention.ModifiedFollowing, 100.0, new Date(30, Month.November, 2004)); + new ActualActual(ActualActual.Convention.ISMA), + BusinessDayConvention.ModifiedFollowing, 100.0, new Date(30, Month.November, 2004)); bond3.setPricingEngine(bondEngine); @@ -427,9 +427,9 @@ public void testCached() if (Math.Abs(price - cachedPrice3) > tolerance) { QAssert.Fail("failed to reproduce cached price:" - + "\n calculated: " + price + "" - + "\n expected: " + cachedPrice3 + "" - + "\n error: " + (price - cachedPrice3)); + + "\n calculated: " + price + "" + + "\n expected: " + cachedPrice3 + "" + + "\n error: " + (price - cachedPrice3)); } // this should give the same result since the issue date is the @@ -440,15 +440,15 @@ public void testCached() if (Math.Abs(price - cachedPrice3) > tolerance) { QAssert.Fail("failed to reproduce cached price:" - + "\n calculated: " + price + "" - + "\n expected: " + cachedPrice3 + "" - + "\n error: " + (price - cachedPrice3)); + + "\n calculated: " + price + "" + + "\n expected: " + cachedPrice3 + "" + + "\n error: " + (price - cachedPrice3)); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testCachedZero() { @@ -467,8 +467,8 @@ public void testCachedZero() // plain ZeroCouponBond bond1 = new ZeroCouponBond(settlementDays, new UnitedStates(UnitedStates.Market.GovernmentBond), - vars.faceAmount, new Date(30, Month.November, 2008), BusinessDayConvention.ModifiedFollowing, - 100.0, new Date(30, Month.November, 2004)); + vars.faceAmount, new Date(30, Month.November, 2008), BusinessDayConvention.ModifiedFollowing, + 100.0, new Date(30, Month.November, 2004)); IPricingEngine bondEngine = new DiscountingBondEngine(discountCurve); bond1.setPricingEngine(bondEngine); @@ -479,14 +479,14 @@ public void testCachedZero() if (Math.Abs(price - cachedPrice1) > tolerance) { QAssert.Fail("failed to reproduce cached price:\n" - + " calculated: " + price + "\n" - + " expected: " + cachedPrice1 + "\n" - + " error: " + (price - cachedPrice1)); + + " calculated: " + price + "\n" + + " expected: " + cachedPrice1 + "\n" + + " error: " + (price - cachedPrice1)); } ZeroCouponBond bond2 = new ZeroCouponBond(settlementDays, new UnitedStates(UnitedStates.Market.GovernmentBond), - vars.faceAmount, new Date(30, Month.November, 2007), BusinessDayConvention.ModifiedFollowing, - 100.0, new Date(30, Month.November, 2004)); + vars.faceAmount, new Date(30, Month.November, 2007), BusinessDayConvention.ModifiedFollowing, + 100.0, new Date(30, Month.November, 2004)); bond2.setPricingEngine(bondEngine); @@ -496,14 +496,14 @@ public void testCachedZero() if (Math.Abs(price - cachedPrice2) > tolerance) { QAssert.Fail("failed to reproduce cached price:\n" - + " calculated: " + price + "\n" - + " expected: " + cachedPrice2 + "\n" - + " error: " + (price - cachedPrice2)); + + " calculated: " + price + "\n" + + " expected: " + cachedPrice2 + "\n" + + " error: " + (price - cachedPrice2)); } ZeroCouponBond bond3 = new ZeroCouponBond(settlementDays, new UnitedStates(UnitedStates.Market.GovernmentBond), - vars.faceAmount, new Date(30, Month.November, 2006), BusinessDayConvention.ModifiedFollowing, - 100.0, new Date(30, Month.November, 2004)); + vars.faceAmount, new Date(30, Month.November, 2006), BusinessDayConvention.ModifiedFollowing, + 100.0, new Date(30, Month.November, 2004)); bond3.setPricingEngine(bondEngine); @@ -513,15 +513,15 @@ public void testCachedZero() if (Math.Abs(price - cachedPrice3) > tolerance) { QAssert.Fail("failed to reproduce cached price:\n" - + " calculated: " + price + "\n" - + " expected: " + cachedPrice3 + "\n" - + " error: " + (price - cachedPrice3)); + + " calculated: " + price + "\n" + + " expected: " + cachedPrice3 + "\n" + + " error: " + (price - cachedPrice3)); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testCachedFixed() { @@ -540,13 +540,13 @@ public void testCachedFixed() // plain Schedule sch = new Schedule(new Date(30, Month.November, 2004), - new Date(30, Month.November, 2008), new Period(Frequency.Semiannual), - new UnitedStates(UnitedStates.Market.GovernmentBond), - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); + new Date(30, Month.November, 2008), new Period(Frequency.Semiannual), + new UnitedStates(UnitedStates.Market.GovernmentBond), + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); FixedRateBond bond1 = new FixedRateBond(settlementDays, vars.faceAmount, sch, new List() { 0.02875 }, - new ActualActual(ActualActual.Convention.ISMA), BusinessDayConvention.ModifiedFollowing, - 100.0, new Date(30, Month.November, 2004)); + new ActualActual(ActualActual.Convention.ISMA), BusinessDayConvention.ModifiedFollowing, + 100.0, new Date(30, Month.November, 2004)); IPricingEngine bondEngine = new DiscountingBondEngine(discountCurve); bond1.setPricingEngine(bondEngine); @@ -557,9 +557,9 @@ public void testCachedFixed() if (Math.Abs(price - cachedPrice1) > tolerance) { QAssert.Fail("failed to reproduce cached price:\n" - + " calculated: " + price + "\n" - + " expected: " + cachedPrice1 + "\n" - + " error: " + (price - cachedPrice1)); + + " calculated: " + price + "\n" + + " expected: " + cachedPrice1 + "\n" + + " error: " + (price - cachedPrice1)); } // varying coupons @@ -570,9 +570,9 @@ public void testCachedFixed() couponRates[3] = 0.0325; FixedRateBond bond2 = new FixedRateBond(settlementDays, vars.faceAmount, sch, couponRates, - new ActualActual(ActualActual.Convention.ISMA), - BusinessDayConvention.ModifiedFollowing, - 100.0, new Date(30, Month.November, 2004)); + new ActualActual(ActualActual.Convention.ISMA), + BusinessDayConvention.ModifiedFollowing, + 100.0, new Date(30, Month.November, 2004)); bond2.setPricingEngine(bondEngine); @@ -582,22 +582,22 @@ public void testCachedFixed() if (Math.Abs(price - cachedPrice2) > tolerance) { QAssert.Fail("failed to reproduce cached price:\n" - + " calculated: " + price + "\n" - + " expected: " + cachedPrice2 + "\n" - + " error: " + (price - cachedPrice2)); + + " calculated: " + price + "\n" + + " expected: " + cachedPrice2 + "\n" + + " error: " + (price - cachedPrice2)); } // stub date Schedule sch3 = new Schedule(new Date(30, Month.November, 2004), - new Date(30, Month.March, 2009), new Period(Frequency.Semiannual), - new UnitedStates(UnitedStates.Market.GovernmentBond), - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false, - null, new Date(30, Month.November, 2008)); + new Date(30, Month.March, 2009), new Period(Frequency.Semiannual), + new UnitedStates(UnitedStates.Market.GovernmentBond), + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false, + null, new Date(30, Month.November, 2008)); FixedRateBond bond3 = new FixedRateBond(settlementDays, vars.faceAmount, sch3, - couponRates, new ActualActual(ActualActual.Convention.ISMA), - BusinessDayConvention.ModifiedFollowing, - 100.0, new Date(30, Month.November, 2004)); + couponRates, new ActualActual(ActualActual.Convention.ISMA), + BusinessDayConvention.ModifiedFollowing, + 100.0, new Date(30, Month.November, 2004)); bond3.setPricingEngine(bondEngine); @@ -607,15 +607,15 @@ public void testCachedFixed() if (Math.Abs(price - cachedPrice3) > tolerance) { QAssert.Fail("failed to reproduce cached price:\n" - + " calculated: " + price + "\n" - + " expected: " + cachedPrice3 + "\n" - + " error: " + (price - cachedPrice3)); + + " calculated: " + price + "\n" + + " expected: " + cachedPrice3 + "\n" + + " error: " + (price - cachedPrice3)); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testCachedFloating() { @@ -645,12 +645,12 @@ public void testCachedFloating() DateGeneration.Rule.Backward, false); FloatingRateBond bond1 = new FloatingRateBond(settlementDays, vars.faceAmount, sch, - index, new ActualActual(ActualActual.Convention.ISMA), - BusinessDayConvention.ModifiedFollowing, fixingDays, - new List(), new List(), - new List(), new List(), - false, - 100.0, new Date(30, Month.November, 2004)); + index, new ActualActual(ActualActual.Convention.ISMA), + BusinessDayConvention.ModifiedFollowing, fixingDays, + new List(), new List(), + new List < double? >(), new List < double? >(), + false, + 100.0, new Date(30, Month.November, 2004)); IPricingEngine bondEngine = new DiscountingBondEngine(riskFreeRate); bond1.setPricingEngine(bondEngine); @@ -658,7 +658,7 @@ public void testCachedFloating() Utils.setCouponPricer(bond1.cashflows(), pricer); #if QL_USE_INDEXED_COUPON - double cachedPrice1 = 99.874645; + double cachedPrice1 = 99.874645; #else double cachedPrice1 = 99.874646; #endif @@ -668,19 +668,19 @@ public void testCachedFloating() if (Math.Abs(price - cachedPrice1) > tolerance) { QAssert.Fail("failed to reproduce cached price:\n" - + " calculated: " + price + "\n" - + " expected: " + cachedPrice1 + "\n" - + " error: " + (price - cachedPrice1)); + + " calculated: " + price + "\n" + + " expected: " + cachedPrice1 + "\n" + + " error: " + (price - cachedPrice1)); } // different risk-free and discount curve FloatingRateBond bond2 = new FloatingRateBond(settlementDays, vars.faceAmount, sch, - index, new ActualActual(ActualActual.Convention.ISMA), - BusinessDayConvention.ModifiedFollowing, fixingDays, - new List(), new List(), - new List(), new List(), - false, - 100.0, new Date(30, Month.November, 2004)); + index, new ActualActual(ActualActual.Convention.ISMA), + BusinessDayConvention.ModifiedFollowing, fixingDays, + new List(), new List(), + new List < double? >(), new List < double? >(), + false, + 100.0, new Date(30, Month.November, 2004)); IPricingEngine bondEngine2 = new DiscountingBondEngine(discountCurve); bond2.setPricingEngine(bondEngine2); @@ -688,7 +688,7 @@ public void testCachedFloating() Utils.setCouponPricer(bond2.cashflows(), pricer); #if QL_USE_INDEXED_COUPON - double cachedPrice2 = 97.955904; + double cachedPrice2 = 97.955904; #else double cachedPrice2 = 97.955904; #endif @@ -697,9 +697,9 @@ public void testCachedFloating() if (Math.Abs(price - cachedPrice2) > tolerance) { QAssert.Fail("failed to reproduce cached price:\n" - + " calculated: " + price + "\n" - + " expected: " + cachedPrice2 + "\n" - + " error: " + (price - cachedPrice2)); + + " calculated: " + price + "\n" + + " expected: " + cachedPrice2 + "\n" + + " error: " + (price - cachedPrice2)); } // varying spread @@ -710,19 +710,19 @@ public void testCachedFloating() spreads[3] = 0.0016; FloatingRateBond bond3 = new FloatingRateBond(settlementDays, vars.faceAmount, sch, - index, new ActualActual(ActualActual.Convention.ISMA), - BusinessDayConvention.ModifiedFollowing, fixingDays, - new List(), spreads, - new List(), new List(), - false, - 100.0, new Date(30, Month.November, 2004)); + index, new ActualActual(ActualActual.Convention.ISMA), + BusinessDayConvention.ModifiedFollowing, fixingDays, + new List(), spreads, + new List < double? >(), new List < double? >(), + false, + 100.0, new Date(30, Month.November, 2004)); bond3.setPricingEngine(bondEngine2); Utils.setCouponPricer(bond3.cashflows(), pricer); #if QL_USE_INDEXED_COUPON - double cachedPrice3 = 98.495458; + double cachedPrice3 = 98.495458; #else double cachedPrice3 = 98.495459; #endif @@ -731,15 +731,15 @@ public void testCachedFloating() if (Math.Abs(price - cachedPrice3) > tolerance) { QAssert.Fail("failed to reproduce cached price:\n" - + " calculated: " + price + "\n" - + " expected: " + cachedPrice3 + "\n" - + " error: " + (price - cachedPrice3)); + + " calculated: " + price + "\n" + + " expected: " + cachedPrice3 + "\n" + + " error: " + (price - cachedPrice3)); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testBrazilianCached() { @@ -798,10 +798,10 @@ public void testBrazilianCached() Compounding.Compounded, Frequency.Annual); Schedule schedule = new Schedule(new Date(1, Month.January, 2007), - maturityDates[bondIndex], new Period(Frequency.Semiannual), - new Brazil(Brazil.Market.Settlement), - BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + maturityDates[bondIndex], new Period(Frequency.Semiannual), + new Brazil(Brazil.Market.Settlement), + BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); FixedRateBond bond = new FixedRateBond(settlementDays, @@ -815,25 +815,25 @@ public void testBrazilianCached() double cachedPrice = prices[bondIndex]; double price = vars.faceAmount * (bond.cleanPrice(yield.rate(), - yield.dayCounter(), - yield.compounding(), - yield.frequency(), - today) + bond.accruedAmount(today)) / 100; + yield.dayCounter(), + yield.compounding(), + yield.frequency(), + today) + bond.accruedAmount(today)) / 100; if (Math.Abs(price - cachedPrice) > tolerance) { QAssert.Fail("failed to reproduce cached price:\n" - + " calculated: " + price + "\n" - + " expected: " + cachedPrice + "\n" - + " error: " + (price - cachedPrice) + "\n" + + " calculated: " + price + "\n" + + " expected: " + cachedPrice + "\n" + + " error: " + (price - cachedPrice) + "\n" ); } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testAmortizingFixedBond() { @@ -855,8 +855,9 @@ public void testAmortizingFixedBond() int totCashflow = 24; int totNotionals = 13; double PVDifference = 13118862.59; - double[] notionals = {400000000,367573428,334984723,302233075,269317669,236237685,202992302,169580691,136002023, - 102255461,68340166,34255295,0 }; + double[] notionals = {400000000, 367573428, 334984723, 302233075, 269317669, 236237685, 202992302, 169580691, 136002023, + 102255461, 68340166, 34255295, 0 + }; // test total cashflow count QAssert.AreEqual(bond.cashflows().Count, totCashflow, "Cashflow size different"); @@ -878,9 +879,9 @@ public void testAmortizingFixedBond() #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testMBSFixedBondCached() { @@ -890,127 +891,131 @@ public void testMBSFixedBondCached() // pag 58,61,63 #region Cached Values - double[] OutstandingBalance = {400000000,399396651,398724866,397984841,397176808,396301034,395357823,394347512,393270474, - 392127117,390917882,389643247,388303720,386899847,385432204,383901402,382308084,380652925, - 378936631,377159941,375323622,373428474,371475324,369465030,367398478,365276580,363100276, - 360870534,358588346,356317966,354059336,351812393,349577078,347353331,345141093,342940305, - 340750907,338572840,336406048,334250471,332106052,329972733,327850458,325739170,323638812, - 321549327,319470661,317402757,315345560,313299014,311263066,309237660,307222743,305218260, - 303224158,301240383,299266882,297303602,295350492,293407497,291474567,289551650,287638694, - 285735647,283842460,281959081,280085459,278221545,276367288,274522640,272687550,270861969, - 269045848,267239140,265441794,263653764,261875001,260105457,258345086,256593839,254851671, - 253118533,251394381,249679167,247972846,246275371,244586698,242906782,241235576,239573036, - 237919118,236273777,234636970,233008651,231388779,229777308,228174197,226579401,224992878, - 223414586,221844483,220282525,218728672,217182881,215645111,214115321,212593469,211079516, - 209573419,208075140,206584637,205101871,203626802,202159389,200699595,199247379,197802703, - 196365528,194935815,193513525,192098622,190691066,189290820,187897846,186512107,185133566, - 183762186,182397929,181040759,179690640,178347535,177011409,175682225,174359947,173044541, - 171735971,170434201,169139197,167850924,166569347,165294431,164026143,162764449,161509314, - 160260704,159018587,157782929,156553696,155330855,154114374,152904220,151700360,150502762, - 149311394,148126224,146947219,145774348,144607580,143446882,142292225,141143576,140000905, - 138864182,137733374,136608453,135489388,134376148,133268704,132167026,131071083,129980848, - 128896290,127817380,126744089,125676388,124614249,123557642,122506539,121460913,120420734, - 119385975,118356608,117332605,116313939,115300582,114292506,113289685,112292092,111299699, - 110312480,109330408,108353458,107381601,106414813,105453067,104496337,103544598,102597823, - 101655987,100719066,99787032 ,98859862 ,97937530 ,97020012 ,96107282 ,95199317 ,94296091 , - 93397579 ,92503759 ,91614606 ,90730095 ,89850202 ,88974905 ,88104180 ,87238002 ,86376348 , - 85519196 ,84666522 ,83818303 ,82974516 ,82135138 ,81300146 ,80469519 ,79643233 ,78821266 , - 78003597 ,77190202 ,76381060 ,75576149 ,74775447 ,73978932 ,73186584 ,72398380 ,71614300 , - 70834321 ,70058424 ,69286586 ,68518787 ,67755007 ,66995224 ,66239418 ,65487568 ,64739655 , - 63995657 ,63255556 ,62519330 ,61786959 ,61058425 ,60333707 ,59612785 ,58895641 ,58182253 , - 57472605 ,56766675 ,56064445 ,55365895 ,54671008 ,53979764 ,53292143 ,52608129 ,51927702 , - 51250843 ,50577534 ,49907758 ,49241495 ,48578728 ,47919438 ,47263609 ,46611221 ,45962258 , - 45316701 ,44674534 ,44035738 ,43400297 ,42768192 ,42139408 ,41513926 ,40891731 ,40272804 , - 39657129 ,39044690 ,38435469 ,37829450 ,37226618 ,36626954 ,36030443 ,35437069 ,34846816 , - 34259667 ,33675607 ,33094619 ,32516689 ,31941799 ,31369935 ,30801080 ,30235220 ,29672339 , - 29112422 ,28555453 ,28001417 ,27450300 ,26902085 ,26356759 ,25814305 ,25274711 ,24737960 , - 24204038 ,23672931 ,23144624 ,22619103 ,22096353 ,21576360 ,21059110 ,20544589 ,20032782 , - 19523677 ,19017258 ,18513512 ,18012425 ,17513984 ,17018175 ,16524985 ,16034399 ,15546405 , - 15060989 ,14578138 ,14097838 ,13620077 ,13144842 ,12672119 ,12201896 ,11734160 ,11268897 , - 10806096 ,10345743 ,9887826 ,9432332 ,8979249 ,8528565 ,8080267 ,7634342 ,7190780 , - 6749566 ,6310691 ,5874140 ,5439903 ,5007967 ,4578321 ,4150953 ,3725851 ,3303003 , - 2882398 ,2464024 ,2047870 ,1633925 ,1222176 ,812614 ,405225 }; - double[] Prepayments = { 200350,266975,333463,399780,465892,531764,597362,662652,727600,792172,856336,920057,983303, - 1046041,1108239,1169864,1230887,1291274,1350996,1410023,1468325,1525872,1582637,1638590,1693706,1747956, - 1801315,1853758,1842021,1830345,1818729,1807174,1795678,1784241,1772864,1761546,1750286,1739085,1727941, - 1716855,1705827,1694856,1683941,1673083,1662281,1651536,1640845,1630210,1619631,1609106,1598635,1588219, - 1577856,1567548,1557292,1547090,1536941,1526844,1516799,1506807,1496866,1486977,1477139,1467352,1457616, - 1447930,1438294,1428708,1419172,1409686,1400248,1390859,1381519,1372228,1362985,1353789,1344641,1335541, - 1326488,1317481,1308522,1299608,1290741,1281920,1273145,1264415,1255731,1247091,1238497,1229947,1221441, - 1212979,1204562,1196187,1187857,1179569,1171325,1163123,1154964,1146847,1138773,1130740,1122749,1114799, - 1106891,1099023,1091197,1083411,1075665,1067960,1060295,1052669,1045083,1037537,1030029,1022561,1015131, - 1007740,1000388,993073,985797,978558,971357,964193,957067,949977,942924,935908,928929,921985,915078, - 908207,901371,894571,887806,881077,874382,867722,861097,854506,847950,841427,834939,828484,822063, - 815675,809320,802998,796710,790454,784230,778039,771880,765753,759658,753595,747563,741563,735594, - 729656,723749,717872,712026,706211,700426,694671,688946,683251,677585,671949,666342,660765,655216, - 649697,644206,638744,633310,627904,622527,617178,611856,606563,601297,596058,590847,585662,580505, - 575375,570271,565194,560144,555120,550122,545150,540204,535284,530390,525521,520677,515859,511066, - 506298,501555,496836,492142,487473,482828,478207,473611,469038,464490,459965,455463,450986,446531, - 442100,437692,433307,428945,424606,420289,415995,411724,407474,403247,399042,394860,390698,386559, - 382442,378345,374271,370217,366185,362174,358184,354215,350266,346339,342431,338545,334678,330832, - 327006,323200,319414,315648,311901,308174,304467,300779,297110,293461,289831,286220,282627,279054, - 275499,271963,268445,264946,261466,258003,254559,251133,247724,244334,240961,237606,234269,230949, - 227647,224362,221094,217844,214610,211394,208194,205012,201845,198696,195563,192447,189347,186263, - 183195,180144,177109,174089,171086,168098,165126,162170,159229,156304,153394,150500,147620,144756, - 141907,139073,136254,133450,130660,127885,125125,122380,119648,116932,114229,111541,108867,106207, - 103561,100930,98312,95707,93117,90540,87977,85428,82891,80369,77859,75363,72880,70410,67954,65510, - 63079,60661,58256,55863,53483,51116,48761,46419,44089,41772,39466,37173,34893,32624,30367,28122, - 25889,23668,21459,19261,17075,14901,12738,10587,8447,6318,4201,2095,0}; - double[] NetInterest = { 1833333,1830568,1827489,1824097,1820394,1816380,1812057,1807426,1802490,1797249,1791707,1785865, - 1779725,1773291,1766564,1759548,1752245,1744659,1736793,1728650,1720233,1711547,1702595,1693381, - 1683910,1674184,1664210,1653990,1643530,1633124,1622772,1612473,1602228,1592036,1581897,1571810, - 1561775,1551792,1541861,1531981,1522153,1512375,1502648,1492971,1483345,1473768,1464241,1454763, - 1445334,1435954,1426622,1417339,1408104,1398917,1389777,1380685,1371640,1362642,1353690,1344784, - 1335925,1327112,1318344,1309622,1300945,1292312,1283725,1275182,1266683,1258229,1249818,1241451, - 1233127,1224846,1216608,1208413,1200260,1192150,1184082,1176055,1168070,1160127,1152224,1144363, - 1136542,1128762,1121022,1113323,1105663,1098043,1090463,1082921,1075419,1067956,1060532,1053146, - 1045798,1038489,1031217,1023984,1016787,1009628,1002506,995422,988373,981362,974387,967448,960545, - 953678,946846,940050,933290,926564,919873,913217,906596,900009,893456,886937,880452,874001,867583, - 861198,854847,848529,842243,835991,829770,823582,817426,811302,805210,799150,793121,787123,781157, - 775221,769317,763443,757599,751786,746004,740251,734528,728835,723172,717538,711933,706358,700811, - 695293,689804,684344,678912,673508,668132,662785,657465,652173,646908,641671,636461,631278,626122, - 620993,615891,610815,605766,600742,595746,590775,585830,580910,576017,571149,566306,561488,556696, - 551928,547186,542468,537774,533106,528461,523841,519244,514672,510124,505599,501098,496620,492166, - 487735,483327,478942,474579,470240,465923,461629,457357,453108,448880,444675,440492,436330,432190, - 428072,423976,419900,415846,411813,407802,403811,399841,395892,391963,388055,384167,380300,376453, - 372626,368819,365031,361264,357516,353788,350080,346391,342721,339070,335439,331826,328232,324657, - 321101,317564,314044,310544,307061,303597,300151,296723,293313,289921,286547,283190,279851,276529, - 273225,269938,266669,263416,260181,256962,253760,250575,247407,244256,241121,238002,234900,231814, - 228744,225690,222653,219631,216625,213635,210660,207702,204758,201830,198918,196021,193139,190272, - 187420,184584,181762,178955,176163,173385,170622,167874,165140,162420,159715,157023,154347,151684, - 149035,146400,143779,141172,138578,135998,133432,130879,128340,125814,123301,120802,118316,115842, - 113382,110935,108501,106080,103671,101275,98892,96521,94163,91817,89484,87162,84854,82557,80272, - 78000,75740,73491,71254,69030,66816,64615,62425,60247,58081,55925,53782,51649,49528,47418,45319, - 43232,41155,39089,37035,34991,32958,30936,28924,26923,24933,22953,20984,19025,17077,15139,13211, - 11293,9386,7489,5602,3724,1857}; - double[] ScheduledPrincipal = { 402998,404810,406562,408253,409882,411447,412949,414386,415758,417063,418300,419470,420571, - 421602,422563,423454,424273,425020,425694,426296,426824,427278,427657,427962,428192,428347, - 428427,428430,428358,428286,428213,428141,428069,427997,427924,427852,427780,427708,427636, - 427564,427491,427419,427347,427275,427203,427131,427059,426987,426915,426843,426771,426699, - 426627,426555,426483,426411,426339,426267,426195,426123,426051,425979,425907,425835,425764, - 425692,425620,425548,425476,425405,425333,425261,425189,425118,425046,424974,424902,424831, - 424759,424687,424616,424544,424472,424401,424329,424258,424186,424114,424043,423971,423900, - 423828,423757,423685,423614,423542,423471,423399,423328,423256,423185,423114,423042,422971, - 422900,422828,422757,422685,422614,422543,422472,422400,422329,422258,422187,422115,422044, - 421973,421902,421830,421759,421688,421617,421546,421475,421404,421332,421261,421190,421119, - 421048,420977,420906,420835,420764,420693,420622,420551,420480,420409,420338,420267,420196, - 420126,420055,419984,419913,419842,419771,419700,419630,419559,419488,419417,419346,419276, - 419205,419134,419064,418993,418922,418851,418781,418710,418639,418569,418498,418428,418357, - 418286,418216,418145,418075,418004,417934,417863,417793,417722,417652,417581,417511,417440, - 417370,417299,417229,417159,417088,417018,416947,416877,416807,416736,416666,416596,416526, - 416455,416385,416315,416245,416174,416104,416034,415964,415893,415823,415753,415683,415613, - 415543,415473,415403,415332,415262,415192,415122,415052,414982,414912,414842,414772,414702, - 414632,414562,414492,414422,414352,414282,414213,414143,414073,414003,413933,413863,413793, - 413724,413654,413584,413514,413444,413375,413305,413235,413165,413096,413026,412956,412887, - 412817,412747,412678,412608,412538,412469,412399,412330,412260,412191,412121,412051,411982, - 411912,411843,411773,411704,411635,411565,411496,411426,411357,411287,411218,411149,411079, - 411010,410941,410871,410802,410733,410663,410594,410525,410455,410386,410317,410248,410178, - 410109,410040,409971,409902,409833,409763,409694,409625,409556,409487,409418,409349,409280, - 409211,409142,409073,409003,408934,408865,408796,408728,408659,408590,408521,408452,408383, - 408314,408245,408176,408107,408038,407970,407901,407832,407763,407694,407625,407557,407488, - 407419,407350,407282,407213,407144,407076,407007,406938,406870,406801,406732,406664,406595, - 406526,406458,406389,406321,406252,406184,406115,406047,405978,405910,405841,405773,405704, - 405636,405567,405499,405430,405362,405294,405225}; + double[] OutstandingBalance = {400000000, 399396651, 398724866, 397984841, 397176808, 396301034, 395357823, 394347512, 393270474, + 392127117, 390917882, 389643247, 388303720, 386899847, 385432204, 383901402, 382308084, 380652925, + 378936631, 377159941, 375323622, 373428474, 371475324, 369465030, 367398478, 365276580, 363100276, + 360870534, 358588346, 356317966, 354059336, 351812393, 349577078, 347353331, 345141093, 342940305, + 340750907, 338572840, 336406048, 334250471, 332106052, 329972733, 327850458, 325739170, 323638812, + 321549327, 319470661, 317402757, 315345560, 313299014, 311263066, 309237660, 307222743, 305218260, + 303224158, 301240383, 299266882, 297303602, 295350492, 293407497, 291474567, 289551650, 287638694, + 285735647, 283842460, 281959081, 280085459, 278221545, 276367288, 274522640, 272687550, 270861969, + 269045848, 267239140, 265441794, 263653764, 261875001, 260105457, 258345086, 256593839, 254851671, + 253118533, 251394381, 249679167, 247972846, 246275371, 244586698, 242906782, 241235576, 239573036, + 237919118, 236273777, 234636970, 233008651, 231388779, 229777308, 228174197, 226579401, 224992878, + 223414586, 221844483, 220282525, 218728672, 217182881, 215645111, 214115321, 212593469, 211079516, + 209573419, 208075140, 206584637, 205101871, 203626802, 202159389, 200699595, 199247379, 197802703, + 196365528, 194935815, 193513525, 192098622, 190691066, 189290820, 187897846, 186512107, 185133566, + 183762186, 182397929, 181040759, 179690640, 178347535, 177011409, 175682225, 174359947, 173044541, + 171735971, 170434201, 169139197, 167850924, 166569347, 165294431, 164026143, 162764449, 161509314, + 160260704, 159018587, 157782929, 156553696, 155330855, 154114374, 152904220, 151700360, 150502762, + 149311394, 148126224, 146947219, 145774348, 144607580, 143446882, 142292225, 141143576, 140000905, + 138864182, 137733374, 136608453, 135489388, 134376148, 133268704, 132167026, 131071083, 129980848, + 128896290, 127817380, 126744089, 125676388, 124614249, 123557642, 122506539, 121460913, 120420734, + 119385975, 118356608, 117332605, 116313939, 115300582, 114292506, 113289685, 112292092, 111299699, + 110312480, 109330408, 108353458, 107381601, 106414813, 105453067, 104496337, 103544598, 102597823, + 101655987, 100719066, 99787032, 98859862, 97937530, 97020012, 96107282, 95199317, 94296091, + 93397579, 92503759, 91614606, 90730095, 89850202, 88974905, 88104180, 87238002, 86376348, + 85519196, 84666522, 83818303, 82974516, 82135138, 81300146, 80469519, 79643233, 78821266, + 78003597, 77190202, 76381060, 75576149, 74775447, 73978932, 73186584, 72398380, 71614300, + 70834321, 70058424, 69286586, 68518787, 67755007, 66995224, 66239418, 65487568, 64739655, + 63995657, 63255556, 62519330, 61786959, 61058425, 60333707, 59612785, 58895641, 58182253, + 57472605, 56766675, 56064445, 55365895, 54671008, 53979764, 53292143, 52608129, 51927702, + 51250843, 50577534, 49907758, 49241495, 48578728, 47919438, 47263609, 46611221, 45962258, + 45316701, 44674534, 44035738, 43400297, 42768192, 42139408, 41513926, 40891731, 40272804, + 39657129, 39044690, 38435469, 37829450, 37226618, 36626954, 36030443, 35437069, 34846816, + 34259667, 33675607, 33094619, 32516689, 31941799, 31369935, 30801080, 30235220, 29672339, + 29112422, 28555453, 28001417, 27450300, 26902085, 26356759, 25814305, 25274711, 24737960, + 24204038, 23672931, 23144624, 22619103, 22096353, 21576360, 21059110, 20544589, 20032782, + 19523677, 19017258, 18513512, 18012425, 17513984, 17018175, 16524985, 16034399, 15546405, + 15060989, 14578138, 14097838, 13620077, 13144842, 12672119, 12201896, 11734160, 11268897, + 10806096, 10345743, 9887826, 9432332, 8979249, 8528565, 8080267, 7634342, 7190780, + 6749566, 6310691, 5874140, 5439903, 5007967, 4578321, 4150953, 3725851, 3303003, + 2882398, 2464024, 2047870, 1633925, 1222176, 812614, 405225 + }; + double[] Prepayments = { 200350, 266975, 333463, 399780, 465892, 531764, 597362, 662652, 727600, 792172, 856336, 920057, 983303, + 1046041, 1108239, 1169864, 1230887, 1291274, 1350996, 1410023, 1468325, 1525872, 1582637, 1638590, 1693706, 1747956, + 1801315, 1853758, 1842021, 1830345, 1818729, 1807174, 1795678, 1784241, 1772864, 1761546, 1750286, 1739085, 1727941, + 1716855, 1705827, 1694856, 1683941, 1673083, 1662281, 1651536, 1640845, 1630210, 1619631, 1609106, 1598635, 1588219, + 1577856, 1567548, 1557292, 1547090, 1536941, 1526844, 1516799, 1506807, 1496866, 1486977, 1477139, 1467352, 1457616, + 1447930, 1438294, 1428708, 1419172, 1409686, 1400248, 1390859, 1381519, 1372228, 1362985, 1353789, 1344641, 1335541, + 1326488, 1317481, 1308522, 1299608, 1290741, 1281920, 1273145, 1264415, 1255731, 1247091, 1238497, 1229947, 1221441, + 1212979, 1204562, 1196187, 1187857, 1179569, 1171325, 1163123, 1154964, 1146847, 1138773, 1130740, 1122749, 1114799, + 1106891, 1099023, 1091197, 1083411, 1075665, 1067960, 1060295, 1052669, 1045083, 1037537, 1030029, 1022561, 1015131, + 1007740, 1000388, 993073, 985797, 978558, 971357, 964193, 957067, 949977, 942924, 935908, 928929, 921985, 915078, + 908207, 901371, 894571, 887806, 881077, 874382, 867722, 861097, 854506, 847950, 841427, 834939, 828484, 822063, + 815675, 809320, 802998, 796710, 790454, 784230, 778039, 771880, 765753, 759658, 753595, 747563, 741563, 735594, + 729656, 723749, 717872, 712026, 706211, 700426, 694671, 688946, 683251, 677585, 671949, 666342, 660765, 655216, + 649697, 644206, 638744, 633310, 627904, 622527, 617178, 611856, 606563, 601297, 596058, 590847, 585662, 580505, + 575375, 570271, 565194, 560144, 555120, 550122, 545150, 540204, 535284, 530390, 525521, 520677, 515859, 511066, + 506298, 501555, 496836, 492142, 487473, 482828, 478207, 473611, 469038, 464490, 459965, 455463, 450986, 446531, + 442100, 437692, 433307, 428945, 424606, 420289, 415995, 411724, 407474, 403247, 399042, 394860, 390698, 386559, + 382442, 378345, 374271, 370217, 366185, 362174, 358184, 354215, 350266, 346339, 342431, 338545, 334678, 330832, + 327006, 323200, 319414, 315648, 311901, 308174, 304467, 300779, 297110, 293461, 289831, 286220, 282627, 279054, + 275499, 271963, 268445, 264946, 261466, 258003, 254559, 251133, 247724, 244334, 240961, 237606, 234269, 230949, + 227647, 224362, 221094, 217844, 214610, 211394, 208194, 205012, 201845, 198696, 195563, 192447, 189347, 186263, + 183195, 180144, 177109, 174089, 171086, 168098, 165126, 162170, 159229, 156304, 153394, 150500, 147620, 144756, + 141907, 139073, 136254, 133450, 130660, 127885, 125125, 122380, 119648, 116932, 114229, 111541, 108867, 106207, + 103561, 100930, 98312, 95707, 93117, 90540, 87977, 85428, 82891, 80369, 77859, 75363, 72880, 70410, 67954, 65510, + 63079, 60661, 58256, 55863, 53483, 51116, 48761, 46419, 44089, 41772, 39466, 37173, 34893, 32624, 30367, 28122, + 25889, 23668, 21459, 19261, 17075, 14901, 12738, 10587, 8447, 6318, 4201, 2095, 0 + }; + double[] NetInterest = { 1833333, 1830568, 1827489, 1824097, 1820394, 1816380, 1812057, 1807426, 1802490, 1797249, 1791707, 1785865, + 1779725, 1773291, 1766564, 1759548, 1752245, 1744659, 1736793, 1728650, 1720233, 1711547, 1702595, 1693381, + 1683910, 1674184, 1664210, 1653990, 1643530, 1633124, 1622772, 1612473, 1602228, 1592036, 1581897, 1571810, + 1561775, 1551792, 1541861, 1531981, 1522153, 1512375, 1502648, 1492971, 1483345, 1473768, 1464241, 1454763, + 1445334, 1435954, 1426622, 1417339, 1408104, 1398917, 1389777, 1380685, 1371640, 1362642, 1353690, 1344784, + 1335925, 1327112, 1318344, 1309622, 1300945, 1292312, 1283725, 1275182, 1266683, 1258229, 1249818, 1241451, + 1233127, 1224846, 1216608, 1208413, 1200260, 1192150, 1184082, 1176055, 1168070, 1160127, 1152224, 1144363, + 1136542, 1128762, 1121022, 1113323, 1105663, 1098043, 1090463, 1082921, 1075419, 1067956, 1060532, 1053146, + 1045798, 1038489, 1031217, 1023984, 1016787, 1009628, 1002506, 995422, 988373, 981362, 974387, 967448, 960545, + 953678, 946846, 940050, 933290, 926564, 919873, 913217, 906596, 900009, 893456, 886937, 880452, 874001, 867583, + 861198, 854847, 848529, 842243, 835991, 829770, 823582, 817426, 811302, 805210, 799150, 793121, 787123, 781157, + 775221, 769317, 763443, 757599, 751786, 746004, 740251, 734528, 728835, 723172, 717538, 711933, 706358, 700811, + 695293, 689804, 684344, 678912, 673508, 668132, 662785, 657465, 652173, 646908, 641671, 636461, 631278, 626122, + 620993, 615891, 610815, 605766, 600742, 595746, 590775, 585830, 580910, 576017, 571149, 566306, 561488, 556696, + 551928, 547186, 542468, 537774, 533106, 528461, 523841, 519244, 514672, 510124, 505599, 501098, 496620, 492166, + 487735, 483327, 478942, 474579, 470240, 465923, 461629, 457357, 453108, 448880, 444675, 440492, 436330, 432190, + 428072, 423976, 419900, 415846, 411813, 407802, 403811, 399841, 395892, 391963, 388055, 384167, 380300, 376453, + 372626, 368819, 365031, 361264, 357516, 353788, 350080, 346391, 342721, 339070, 335439, 331826, 328232, 324657, + 321101, 317564, 314044, 310544, 307061, 303597, 300151, 296723, 293313, 289921, 286547, 283190, 279851, 276529, + 273225, 269938, 266669, 263416, 260181, 256962, 253760, 250575, 247407, 244256, 241121, 238002, 234900, 231814, + 228744, 225690, 222653, 219631, 216625, 213635, 210660, 207702, 204758, 201830, 198918, 196021, 193139, 190272, + 187420, 184584, 181762, 178955, 176163, 173385, 170622, 167874, 165140, 162420, 159715, 157023, 154347, 151684, + 149035, 146400, 143779, 141172, 138578, 135998, 133432, 130879, 128340, 125814, 123301, 120802, 118316, 115842, + 113382, 110935, 108501, 106080, 103671, 101275, 98892, 96521, 94163, 91817, 89484, 87162, 84854, 82557, 80272, + 78000, 75740, 73491, 71254, 69030, 66816, 64615, 62425, 60247, 58081, 55925, 53782, 51649, 49528, 47418, 45319, + 43232, 41155, 39089, 37035, 34991, 32958, 30936, 28924, 26923, 24933, 22953, 20984, 19025, 17077, 15139, 13211, + 11293, 9386, 7489, 5602, 3724, 1857 + }; + double[] ScheduledPrincipal = { 402998, 404810, 406562, 408253, 409882, 411447, 412949, 414386, 415758, 417063, 418300, 419470, 420571, + 421602, 422563, 423454, 424273, 425020, 425694, 426296, 426824, 427278, 427657, 427962, 428192, 428347, + 428427, 428430, 428358, 428286, 428213, 428141, 428069, 427997, 427924, 427852, 427780, 427708, 427636, + 427564, 427491, 427419, 427347, 427275, 427203, 427131, 427059, 426987, 426915, 426843, 426771, 426699, + 426627, 426555, 426483, 426411, 426339, 426267, 426195, 426123, 426051, 425979, 425907, 425835, 425764, + 425692, 425620, 425548, 425476, 425405, 425333, 425261, 425189, 425118, 425046, 424974, 424902, 424831, + 424759, 424687, 424616, 424544, 424472, 424401, 424329, 424258, 424186, 424114, 424043, 423971, 423900, + 423828, 423757, 423685, 423614, 423542, 423471, 423399, 423328, 423256, 423185, 423114, 423042, 422971, + 422900, 422828, 422757, 422685, 422614, 422543, 422472, 422400, 422329, 422258, 422187, 422115, 422044, + 421973, 421902, 421830, 421759, 421688, 421617, 421546, 421475, 421404, 421332, 421261, 421190, 421119, + 421048, 420977, 420906, 420835, 420764, 420693, 420622, 420551, 420480, 420409, 420338, 420267, 420196, + 420126, 420055, 419984, 419913, 419842, 419771, 419700, 419630, 419559, 419488, 419417, 419346, 419276, + 419205, 419134, 419064, 418993, 418922, 418851, 418781, 418710, 418639, 418569, 418498, 418428, 418357, + 418286, 418216, 418145, 418075, 418004, 417934, 417863, 417793, 417722, 417652, 417581, 417511, 417440, + 417370, 417299, 417229, 417159, 417088, 417018, 416947, 416877, 416807, 416736, 416666, 416596, 416526, + 416455, 416385, 416315, 416245, 416174, 416104, 416034, 415964, 415893, 415823, 415753, 415683, 415613, + 415543, 415473, 415403, 415332, 415262, 415192, 415122, 415052, 414982, 414912, 414842, 414772, 414702, + 414632, 414562, 414492, 414422, 414352, 414282, 414213, 414143, 414073, 414003, 413933, 413863, 413793, + 413724, 413654, 413584, 413514, 413444, 413375, 413305, 413235, 413165, 413096, 413026, 412956, 412887, + 412817, 412747, 412678, 412608, 412538, 412469, 412399, 412330, 412260, 412191, 412121, 412051, 411982, + 411912, 411843, 411773, 411704, 411635, 411565, 411496, 411426, 411357, 411287, 411218, 411149, 411079, + 411010, 410941, 410871, 410802, 410733, 410663, 410594, 410525, 410455, 410386, 410317, 410248, 410178, + 410109, 410040, 409971, 409902, 409833, 409763, 409694, 409625, 409556, 409487, 409418, 409349, 409280, + 409211, 409142, 409073, 409003, 408934, 408865, 408796, 408728, 408659, 408590, 408521, 408452, 408383, + 408314, 408245, 408176, 408107, 408038, 407970, 407901, 407832, 407763, 407694, 407625, 407557, 407488, + 407419, 407350, 407282, 407213, 407144, 407076, 407007, 406938, 406870, 406801, 406732, 406664, 406595, + 406526, 406458, 406389, 406321, 406252, 406184, 406115, 406047, 405978, 405910, 405841, 405773, 405704, + 405636, 405567, 405499, 405430, 405362, 405294, 405225 + }; #endregion Date startDate = new Date(1, 2, 2007); @@ -1030,14 +1035,14 @@ public void testMBSFixedBondCached() // 400 Million Pass-Through with a 5.5% Pass-through Rate, a WAC of 6.0%, and a WAM of 358 Months, // Assuming 100% PSA MBSFixedRateBond bond = BondFactory.makeMBSFixedBond(startDate, - bondLength, - originalLenght, - dCounter, - payFrequency, - amount, - WACrate, - PassThroughRate, - psa100); + bondLength, + originalLenght, + dCounter, + payFrequency, + amount, + WACrate, + PassThroughRate, + psa100); IPricingEngine bondEngine = new DiscountingBondEngine(discountCurve); bond.setPricingEngine(bondEngine); @@ -1095,9 +1100,9 @@ public void testMBSFixedBondCached() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testAmortizingBond1() { @@ -1113,7 +1118,7 @@ public void testAmortizingBond1() // Build Bond AmortizingBond bond = BondFactory.makeAmortizingBond(faceValue, marketValue, couponRate, - issueDate, maturirtyDate, tradeDate, paymentFrequency, dc, AmortizingMethod.EffectiveInterestRate); + issueDate, maturirtyDate, tradeDate, paymentFrequency, dc, AmortizingMethod.EffectiveInterestRate); // Amortizing Yield ( Effective Rate ) double y1 = bond.Yield(); @@ -1130,9 +1135,9 @@ public void testAmortizingBond1() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testAmortizingBond2() { @@ -1157,7 +1162,7 @@ public void testAmortizingBond2() // Build Bond AmortizingBond bond = BondFactory.makeAmortizingBond(faceValue, marketValue, couponRate, - issueDate, maturirtyDate, tradeDate, paymentFrequency, dc, AmortizingMethod.EffectiveInterestRate); + issueDate, maturirtyDate, tradeDate, paymentFrequency, dc, AmortizingMethod.EffectiveInterestRate); // Amortizing Yield ( Effective Rate ) double y1 = bond.Yield(); @@ -1174,9 +1179,9 @@ public void testAmortizingBond2() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testAmortizingFixedRateBond() { @@ -1190,7 +1195,8 @@ public void testAmortizingFixedRateBond() double[] amounts = {0.277777778, 0.321639520, 0.369619473, 0.421604034, 0.477415295, 0.536821623, 0.599550525, 0.665302495, 0.733764574, 0.804622617, - 0.877571570, 0.952323396, 1.028612597}; + 0.877571570, 0.952323396, 1.028612597 + }; Frequency freq = Frequency.Monthly; @@ -1201,7 +1207,7 @@ public void testAmortizingFixedRateBond() for (int i = 0; i < rates.Length; ++i) { AmortizingFixedRateBond myBond = new AmortizingFixedRateBond(0, - new NullCalendar(), 100.0, refDate, new Period(30, TimeUnit.Years), freq, rates[i], new ActualActual(ActualActual.Convention.ISMA)); + new NullCalendar(), 100.0, refDate, new Period(30, TimeUnit.Years), freq, rates[i], new ActualActual(ActualActual.Convention.ISMA)); List cashflows = myBond.cashflows(); @@ -1219,10 +1225,10 @@ public void testAmortizingFixedRateBond() if (error > tolerance) { QAssert.Fail(" Rate: " + rates[i] + - " " + k + "th cash flow " + - " Failed!" + - " Expected Amount: " + amounts[i] + - " Calculated Amount: " + totalAmount); + " " + k + "th cash flow " + + " Failed!" + + " Expected Amount: " + amounts[i] + + " Calculated Amount: " + totalAmount); } // Check the coupon result @@ -1248,9 +1254,9 @@ public void testAmortizingFixedRateBond() /// with a custom date vector /// #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testBondFromScheduleWithDateVector() { @@ -1286,8 +1292,8 @@ public void testBondFromScheduleWithDateVector() // actually pays coupons on 28 Feb, regardsless of whether // it is a leap year or not. Schedule schedule = new Schedule(issueDate, maturityDate, tenor, - new NullCalendar(), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, true); + new NullCalendar(), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, true); // Adjust the 29 Feb's to 28 Feb List dates = new List(); @@ -1301,17 +1307,17 @@ public void testBondFromScheduleWithDateVector() } schedule = new Schedule(dates, - schedule.calendar(), - schedule.businessDayConvention(), - schedule.terminationDateBusinessDayConvention(), - schedule.tenor(), - schedule.rule(), - schedule.endOfMonth(), - schedule.isRegular()); - - FixedRateBond bond = new FixedRateBond(0,100.0,schedule,new List() {coupon},dc, - BusinessDayConvention.Following, 100.0,issueDate, calendar,exCouponPeriod, calendar, - BusinessDayConvention.Unadjusted, false); + schedule.calendar(), + schedule.businessDayConvention(), + schedule.terminationDateBusinessDayConvention(), + schedule.tenor(), + schedule.rule(), + schedule.endOfMonth(), + schedule.isRegular()); + + FixedRateBond bond = new FixedRateBond(0, 100.0, schedule, new List() {coupon}, dc, + BusinessDayConvention.Following, 100.0, issueDate, calendar, exCouponPeriod, calendar, + BusinessDayConvention.Unadjusted, false); double calculatedPrice = BondFunctions.dirtyPrice(bond, yield, settlementDate); double expectedPrice = 95.75706; @@ -1319,9 +1325,28 @@ public void testBondFromScheduleWithDateVector() if (Math.Abs(calculatedPrice - expectedPrice) > tolerance) { QAssert.Fail(string.Format("failed to reproduce R2048 dirty price\nexpected: {0}\ncalculated: {1}", - expectedPrice, calculatedPrice)); + expectedPrice, calculatedPrice)); } } + +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testWeightedAverageLife() + { + // Test against know data + DateTime today = new Date(5, Month.Jun, 2018); + List amounts = new List { 5080, 35255, 8335 }; + List < DateTime > schedule = new List { new Date(1, 8, 2035), + new Date(1, 8, 2036), new Date(1, 8, 2037) + }; + + DateTime wal = BondFunctions.WeightedAverageLife(today, amounts, schedule); + QAssert.IsTrue(wal == new DateTime(2036, 08, 25)); + } + } - + } diff --git a/tests/QLNet.Tests/T_BusinessDayConvention.cs b/tests/QLNet.Tests/T_BusinessDayConvention.cs index c45d142c0..d2fbf9a86 100644 --- a/tests/QLNet.Tests/T_BusinessDayConvention.cs +++ b/tests/QLNet.Tests/T_BusinessDayConvention.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,7 +19,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -30,20 +30,20 @@ namespace TestSuite #endif public class T_BusinessDayConvention { - struct SingleCase + struct SingleCase { - public SingleCase( Calendar calendar_, - BusinessDayConvention convention_, - Date start_, - Period period_, - bool endOfMonth_, - Date result_) + public SingleCase(Calendar calendar_, + BusinessDayConvention convention_, + Date start_, + Period period_, + bool endOfMonth_, + Date result_) { - calendar = calendar_; - convention = convention_; - start = start_; - period = period_; - endOfMonth = endOfMonth_; + calendar = calendar_; + convention = convention_; + start = start_; + period = period_; + endOfMonth = endOfMonth_; result = result_; } public Calendar calendar; @@ -55,81 +55,81 @@ public SingleCase( Calendar calendar_, } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testConventions() + public void testConventions() { // Testing business day conventions... - SingleCase[] testCases = + SingleCase[] testCases = { - // Following - new SingleCase(new SouthAfrica(), BusinessDayConvention.Following, new Date(3,Month.February,2015), new Period(1,TimeUnit.Months), false, new Date(3,Month.March,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.Following, new Date(3,Month.February,2015), new Period(4,TimeUnit.Days), false, new Date(9,Month.February,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.Following, new Date(31,Month.January,2015), new Period(1,TimeUnit.Months), true, new Date(27,Month.February,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.Following, new Date(31,Month.January,2015), new Period(1,TimeUnit.Months), false, new Date(2,Month.March,2015)), - - //ModifiedFollowing - new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedFollowing, new Date(3,Month.February,2015), new Period(1,TimeUnit.Months), false, new Date(3,Month.March,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedFollowing, new Date(3,Month.February,2015), new Period(4,TimeUnit.Days), false, new Date(9,Month.February,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedFollowing, new Date(31,Month.January,2015), new Period(1,TimeUnit.Months), true, new Date(27,Month.February,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedFollowing, new Date(31,Month.January,2015), new Period(1,TimeUnit.Months), false, new Date(27,Month.February,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedFollowing, new Date(25,Month.March,2015), new Period(1,TimeUnit.Months), false, new Date(28,Month.April,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedFollowing, new Date(7,Month.February,2015), new Period(1,TimeUnit.Months), false, new Date(9,Month.March,2015)), - - //Preceding - new SingleCase(new SouthAfrica(), BusinessDayConvention.Preceding, new Date(3,Month.March,2015), new Period(-1,TimeUnit.Months), false, new Date(3,Month.February,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.Preceding, new Date(3,Month.February,2015), new Period(-2,TimeUnit.Days), false, new Date(30,Month.January,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.Preceding, new Date(1,Month.March,2015), new Period(-1,TimeUnit.Months), true, new Date(30,Month.January,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.Preceding, new Date(1,Month.March,2015), new Period(-1,TimeUnit.Months), false, new Date(30,Month.January,2015)), - - //ModifiedPreceding - new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedPreceding, new Date(3,Month.March,2015), new Period(-1,TimeUnit.Months), false, new Date(3,Month.February,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedPreceding, new Date(3,Month.February,2015), new Period(-2,TimeUnit.Days), false, new Date(30,Month.January,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedPreceding, new Date(1,Month.March,2015), new Period(-1,TimeUnit.Months), true, new Date(2,Month.February,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedPreceding, new Date(1,Month.March,2015), new Period(-1,TimeUnit.Months), false, new Date(2,Month.February,2015)), - - //Unadjusted - new SingleCase(new SouthAfrica(), BusinessDayConvention.Unadjusted, new Date(3,Month.February,2015), new Period(1,TimeUnit.Months), false, new Date(3,Month.March,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.Unadjusted, new Date(3,Month.February,2015), new Period(4,TimeUnit.Days), false, new Date(9,Month.February,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.Unadjusted, new Date(31,Month.January,2015), new Period(1,TimeUnit.Months), true, new Date(27,Month.February,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.Unadjusted, new Date(31,Month.January,2015), new Period(1,TimeUnit.Months), false, new Date(28,Month.February,2015)), - - //HalfMonthModifiedFollowing - new SingleCase(new SouthAfrica(), BusinessDayConvention.HalfMonthModifiedFollowing, new Date(3,Month.February,2015), new Period(1,TimeUnit.Months), false, new Date(3,Month.March,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.HalfMonthModifiedFollowing, new Date(3,Month.February,2015), new Period(4,TimeUnit.Days), false, new Date(9,Month.February,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.HalfMonthModifiedFollowing, new Date(31,Month.January,2015), new Period(1,TimeUnit.Months), true, new Date(27,Month.February,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.HalfMonthModifiedFollowing, new Date(31,Month.January,2015), new Period(1,TimeUnit.Months), false, new Date(27,Month.February,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.HalfMonthModifiedFollowing, new Date(3,Month.January,2015), new Period(1,TimeUnit.Weeks), false, new Date(12,Month.January,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.HalfMonthModifiedFollowing, new Date(21,Month.March,2015), new Period(1,TimeUnit.Weeks), false, new Date(30,Month.March,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.HalfMonthModifiedFollowing, new Date(7,Month.February,2015), new Period(1,TimeUnit.Months), false, new Date(9,Month.March,2015)), - - //Nearest - new SingleCase(new SouthAfrica(), BusinessDayConvention.Nearest, new Date(3,Month.February,2015), new Period(1,TimeUnit.Months), false, new Date(3,Month.March,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.Nearest, new Date(3,Month.February,2015), new Period(4,TimeUnit.Days), false, new Date(9,Month.February,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.Nearest, new Date(16,Month.April,2015), new Period(1,TimeUnit.Months), false, new Date(15,Month.May,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.Nearest, new Date(17,Month.April,2015), new Period(1,TimeUnit.Months), false, new Date(18,Month.May,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.Nearest, new Date(4,Month.March,2015), new Period(1,TimeUnit.Months), false, new Date(2,Month.April,2015)), - new SingleCase(new SouthAfrica(), BusinessDayConvention.Nearest, new Date(2,Month.April,2015), new Period(1,TimeUnit.Months), false, new Date(4,Month.May,2015)) - }; - - int n = testCases.Length; - for (int i=0; i. -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -18,7 +18,7 @@ #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -34,7 +34,7 @@ internal struct Datum public Date date; public double rate; - public Datum( Date d, double r ) + public Datum(Date d, double r) { date = d; rate = r; @@ -43,20 +43,20 @@ public Datum( Date d, double r ) private class CommonVars { - private List> makeHelpers( Datum[] iiData, int N, - ZeroInflationIndex ii, Period observationLag, - Calendar calendar, - BusinessDayConvention bdc, - DayCounter dc ) + private List> makeHelpers(Datum[] iiData, int N, + ZeroInflationIndex ii, Period observationLag, + Calendar calendar, + BusinessDayConvention bdc, + DayCounter dc) { List> instruments = new List>(); - for ( int i = 0; i < N; i++ ) + for (int i = 0; i < N; i++) { Date maturity = iiData[i].date; - Handle quote = new Handle( new SimpleQuote( iiData[i].rate / 100.0 ) ); - BootstrapHelper anInstrument = new ZeroCouponInflationSwapHelper( quote, observationLag, maturity, - calendar, bdc, dc, ii ); - instruments.Add( anInstrument ); + Handle quote = new Handle(new SimpleQuote(iiData[i].rate / 100.0)); + BootstrapHelper anInstrument = new ZeroCouponInflationSwapHelper(quote, observationLag, maturity, + calendar, bdc, dc, ii); + instruments.Add(anInstrument); } return instruments; } @@ -105,7 +105,7 @@ public CommonVars() zciisR = new List(); hii = new RelinkableHandle(); - nominals = new InitializedList( 1, 1000000 ); + nominals = new InitializedList(1, 1000000); // option variables frequency = Frequency.Annual; // usual setup @@ -113,143 +113,145 @@ public CommonVars() length = 7; calendar = new UnitedKingdom(); convention = BusinessDayConvention.ModifiedFollowing; - Date today = new Date( 25, Month.November, 2009 ); - evaluationDate = calendar.adjust( today ); - Settings.setEvaluationDate( evaluationDate ); + Date today = new Date(25, Month.November, 2009); + evaluationDate = calendar.adjust(today); + Settings.setEvaluationDate(evaluationDate); settlementDays = 0; fixingDays = 0; - settlement = calendar.advance( today, settlementDays, TimeUnit.Days ); + settlement = calendar.advance(today, settlementDays, TimeUnit.Days); startDate = settlement; dcZCIIS = new ActualActual(); dcNominal = new ActualActual(); // uk rpi index // fixing data - Date from = new Date( 20, Month.July, 2007 ); - Date to = new Date( 20, Month.November, 2009 ); - Schedule rpiSchedule = new MakeSchedule().from( from ).to( to ) - .withTenor( new Period( 1, TimeUnit.Months ) ) - .withCalendar( new UnitedKingdom() ) - .withConvention( BusinessDayConvention.ModifiedFollowing ).value(); - double[] fixData = { - 206.1, 207.3, 208.0, 208.9, 209.7, 210.9, - 209.8, 211.4, 212.1, 214.0, 215.1, 216.8, - 216.5, 217.2, 218.4, 217.7, 216, - 212.9, 210.1, 211.4, 211.3, 211.5, - 212.8, 213.4, 213.4, 213.4, 214.4, - -999.0, -999.0}; + Date from = new Date(20, Month.July, 2007); + Date to = new Date(20, Month.November, 2009); + Schedule rpiSchedule = new MakeSchedule().from(from).to(to) + .withTenor(new Period(1, TimeUnit.Months)) + .withCalendar(new UnitedKingdom()) + .withConvention(BusinessDayConvention.ModifiedFollowing).value(); + double[] fixData = + { + 206.1, 207.3, 208.0, 208.9, 209.7, 210.9, + 209.8, 211.4, 212.1, 214.0, 215.1, 216.8, + 216.5, 217.2, 218.4, 217.7, 216, + 212.9, 210.1, 211.4, 211.3, 211.5, + 212.8, 213.4, 213.4, 213.4, 214.4, + -999.0, -999.0 + }; // link from cpi index to cpi TS bool interp = false;// this MUST be false because the observation lag is only 2 months // for ZCIIS; but not for contract if the contract uses a bigger lag. - ii = new UKRPI( interp, hcpi ); - for ( int i = 0; i < rpiSchedule.Count; i++ ) + ii = new UKRPI(interp, hcpi); + for (int i = 0; i < rpiSchedule.Count; i++) { - ii.addFixing( rpiSchedule[i], fixData[i], true );// force overwrite in case multiple use + ii.addFixing(rpiSchedule[i], fixData[i], true); // force overwrite in case multiple use } - Datum[] nominalData = + Datum[] nominalData = { - new Datum( new Date(26, Month.November, 2009), 0.475 ), - new Datum( new Date(2, Month.December, 2009), 0.47498 ), - new Datum( new Date(29, Month.December, 2009), 0.49988 ), - new Datum( new Date(25, Month.February, 2010), 0.59955) , - new Datum( new Date(18, Month.March, 2010), 0.65361), - new Datum( new Date(25, Month.May, 2010), 0.82830 ), - new Datum( new Date(17, Month.June, 2010), 0.7 ), - new Datum( new Date(16, Month.September, 2010), 0.78960), - new Datum( new Date(16, Month.December, 2010), 0.93762 ), - new Datum( new Date(17, Month.March, 2011), 1.12037 ), - new Datum( new Date(22, Month.September, 2011),1.52011), - new Datum( new Date(25, Month.November, 2011), 1.78399), - new Datum( new Date(26, Month.November, 2012), 2.41170), - new Datum( new Date(25, Month.November, 2013), 2.83935), - new Datum( new Date(25, Month.November, 2014), 3.12888), - new Datum( new Date(25, Month.November, 2015), 3.34298), - new Datum( new Date(25, Month.November, 2016), 3.50632), - new Datum( new Date(27, Month.November, 2017), 3.63666), - new Datum( new Date(26, Month.November, 2018), 3.74723), - new Datum( new Date(25, Month.November, 2019), 3.83988), - new Datum( new Date(25, Month.November, 2021), 4.00508), - new Datum( new Date(25, Month.November, 2024), 4.16042), - new Datum( new Date(26, Month.November, 2029), 4.15577), - new Datum( new Date(27, Month.November, 2034), 4.04933), - new Datum( new Date(25, Month.November, 2039), 3.95217), - new Datum( new Date(25, Month.November, 2049), 3.80932), - new Datum( new Date(25, Month.November, 2059), 3.80849), - new Datum( new Date(25, Month.November, 2069), 3.72677), - new Datum( new Date(27, Month.November, 2079), 3.63082 ) + new Datum(new Date(26, Month.November, 2009), 0.475), + new Datum(new Date(2, Month.December, 2009), 0.47498), + new Datum(new Date(29, Month.December, 2009), 0.49988), + new Datum(new Date(25, Month.February, 2010), 0.59955), + new Datum(new Date(18, Month.March, 2010), 0.65361), + new Datum(new Date(25, Month.May, 2010), 0.82830), + new Datum(new Date(17, Month.June, 2010), 0.7), + new Datum(new Date(16, Month.September, 2010), 0.78960), + new Datum(new Date(16, Month.December, 2010), 0.93762), + new Datum(new Date(17, Month.March, 2011), 1.12037), + new Datum(new Date(22, Month.September, 2011), 1.52011), + new Datum(new Date(25, Month.November, 2011), 1.78399), + new Datum(new Date(26, Month.November, 2012), 2.41170), + new Datum(new Date(25, Month.November, 2013), 2.83935), + new Datum(new Date(25, Month.November, 2014), 3.12888), + new Datum(new Date(25, Month.November, 2015), 3.34298), + new Datum(new Date(25, Month.November, 2016), 3.50632), + new Datum(new Date(27, Month.November, 2017), 3.63666), + new Datum(new Date(26, Month.November, 2018), 3.74723), + new Datum(new Date(25, Month.November, 2019), 3.83988), + new Datum(new Date(25, Month.November, 2021), 4.00508), + new Datum(new Date(25, Month.November, 2024), 4.16042), + new Datum(new Date(26, Month.November, 2029), 4.15577), + new Datum(new Date(27, Month.November, 2034), 4.04933), + new Datum(new Date(25, Month.November, 2039), 3.95217), + new Datum(new Date(25, Month.November, 2049), 3.80932), + new Datum(new Date(25, Month.November, 2059), 3.80849), + new Datum(new Date(25, Month.November, 2069), 3.72677), + new Datum(new Date(27, Month.November, 2079), 3.63082) }; int nominalDataLength = 30 - 1; List nomD = new List(); List nomR = new List(); - for ( int i = 0; i < nominalDataLength; i++ ) + for (int i = 0; i < nominalDataLength; i++) { - nomD.Add( nominalData[i].date ); - nomR.Add( nominalData[i].rate / 100.0 ); + nomD.Add(nominalData[i].date); + nomR.Add(nominalData[i].rate / 100.0); } - YieldTermStructure nominal = new InterpolatedZeroCurve( nomD, nomR, dcNominal ); - nominalUK.linkTo( nominal ); + YieldTermStructure nominal = new InterpolatedZeroCurve(nomD, nomR, dcNominal); + nominalUK.linkTo(nominal); // now build the zero inflation curve - observationLag = new Period( 2, TimeUnit.Months ); - contractObservationLag = new Period( 3, TimeUnit.Months ); + observationLag = new Period(2, TimeUnit.Months); + contractObservationLag = new Period(3, TimeUnit.Months); contractObservationInterpolation = InterpolationType.Flat; - Datum[] zciisData = + Datum[] zciisData = { - new Datum( new Date(25, Month.November, 2010), 3.0495 ), - new Datum( new Date(25, Month.November, 2011), 2.93 ), - new Datum( new Date(26, Month.November, 2012), 2.9795 ), - new Datum( new Date(25, Month.November, 2013), 3.029 ), - new Datum( new Date(25, Month.November, 2014), 3.1425 ), - new Datum( new Date(25, Month.November, 2015), 3.211 ), - new Datum( new Date(25, Month.November, 2016), 3.2675 ), - new Datum( new Date(25, Month.November, 2017), 3.3625 ), - new Datum( new Date(25, Month.November, 2018), 3.405 ), - new Datum( new Date(25, Month.November, 2019), 3.48 ), - new Datum( new Date(25, Month.November, 2021), 3.576 ), - new Datum( new Date(25, Month.November, 2024), 3.649 ), - new Datum( new Date(26, Month.November, 2029), 3.751 ), - new Datum( new Date(27, Month.November, 2034), 3.77225 ), - new Datum( new Date(25, Month.November, 2039), 3.77 ), - new Datum( new Date(25, Month.November, 2049), 3.734 ), - new Datum( new Date(25, Month.November, 2059), 3.714 ) + new Datum(new Date(25, Month.November, 2010), 3.0495), + new Datum(new Date(25, Month.November, 2011), 2.93), + new Datum(new Date(26, Month.November, 2012), 2.9795), + new Datum(new Date(25, Month.November, 2013), 3.029), + new Datum(new Date(25, Month.November, 2014), 3.1425), + new Datum(new Date(25, Month.November, 2015), 3.211), + new Datum(new Date(25, Month.November, 2016), 3.2675), + new Datum(new Date(25, Month.November, 2017), 3.3625), + new Datum(new Date(25, Month.November, 2018), 3.405), + new Datum(new Date(25, Month.November, 2019), 3.48), + new Datum(new Date(25, Month.November, 2021), 3.576), + new Datum(new Date(25, Month.November, 2024), 3.649), + new Datum(new Date(26, Month.November, 2029), 3.751), + new Datum(new Date(27, Month.November, 2034), 3.77225), + new Datum(new Date(25, Month.November, 2039), 3.77), + new Datum(new Date(25, Month.November, 2049), 3.734), + new Datum(new Date(25, Month.November, 2059), 3.714) }; zciisDataLength = 17; - for ( int i = 0; i < zciisDataLength; i++ ) + for (int i = 0; i < zciisDataLength; i++) { - zciisD.Add( zciisData[i].date ); - zciisR.Add( zciisData[i].rate ); + zciisD.Add(zciisData[i].date); + zciisR.Add(zciisData[i].rate); } // now build the helpers ... - List> helpers = makeHelpers( zciisData, zciisDataLength, ii, - observationLag, calendar, convention, dcZCIIS ); + List> helpers = makeHelpers(zciisData, zciisDataLength, ii, + observationLag, calendar, convention, dcZCIIS); // we can use historical or first ZCIIS for this // we know historical is WAY off market-implied, so use market implied flat. double baseZeroRate = zciisData[0].rate / 100.0; PiecewiseZeroInflationCurve pCPIts = new PiecewiseZeroInflationCurve( evaluationDate, calendar, dcZCIIS, observationLag, ii.frequency(), ii.interpolated(), baseZeroRate, - new Handle( nominalUK ), helpers ); + new Handle(nominalUK), helpers); pCPIts.recalculate(); - cpiUK.linkTo( pCPIts ); + cpiUK.linkTo(pCPIts); // make sure that the index has the latest zero inflation term structure - hcpi.linkTo( pCPIts ); + hcpi.linkTo(pCPIts); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void consistency() + public void consistency() { // check inflation leg vs calculation directly from inflation TS CommonVars common = new CommonVars(); @@ -263,7 +265,7 @@ public void consistency() DayCounter floatDayCount = new Actual365Fixed(); BusinessDayConvention floatPaymentConvention = BusinessDayConvention.ModifiedFollowing; int fixingDays = 0; - IborIndex floatIndex = new GBPLibor(new Period(6,TimeUnit.Months),common.nominalUK); + IborIndex floatIndex = new GBPLibor(new Period(6, TimeUnit.Months), common.nominalUK); // fixed x inflation leg double fixedRate = 0.1;//1% would be 0.01 @@ -279,40 +281,40 @@ public void consistency() Date startDate = new Date(2, Month.October, 2007); Date endDate = new Date(2, Month.October, 2052); Schedule floatSchedule = new MakeSchedule().from(startDate).to(endDate) - .withTenor(new Period(6,TimeUnit.Months)) + .withTenor(new Period(6, TimeUnit.Months)) .withCalendar(new UnitedKingdom()) .withConvention(floatPaymentConvention) .backwards().value(); Schedule fixedSchedule = new MakeSchedule().from(startDate).to(endDate) - .withTenor(new Period(6,TimeUnit.Months)) + .withTenor(new Period(6, TimeUnit.Months)) .withCalendar(new UnitedKingdom()) .withConvention(BusinessDayConvention.Unadjusted) .backwards().value(); CPISwap zisV = new CPISwap(type, nominal, subtractInflationNominal, - spread, floatDayCount, floatSchedule, - floatPaymentConvention, fixingDays, floatIndex, - fixedRate, baseCPI, fixedDayCount, fixedSchedule, - fixedPaymentConvention, contractObservationLag, - fixedIndex, observationInterpolation); + spread, floatDayCount, floatSchedule, + floatPaymentConvention, fixingDays, floatIndex, + fixedRate, baseCPI, fixedDayCount, fixedSchedule, + fixedPaymentConvention, contractObservationLag, + fixedIndex, observationInterpolation); Date asofDate = Settings.evaluationDate(); - double[] floatFix = {0.06255,0.05975,0.0637,0.018425,0.0073438,-1,-1}; - double[] cpiFix = {211.4,217.2,211.4,213.4,-2,-2}; - for(int i=0;i asofDate) + if (zicPayDate > asofDate) { - testInfLegNPV += (zisV.leg(0))[i].amount()*common.nominalUK.link.discount(zicPayDate); + testInfLegNPV += (zisV.leg(0))[i].amount() * common.nominalUK.link.discount(zicPayDate); } CPICoupon zicV = zisV.cpiLeg()[i] as CPICoupon; if (zicV != null) { - diff = Math.Abs( zicV.rate() - (fixedRate*(zicV.indexFixing()/baseCPI)) ); - QAssert.IsTrue(diff<1e-8, "failed "+i+"th coupon reconstruction as " - + (fixedRate*(zicV.indexFixing()/baseCPI)) + " vs rate = " - +zicV.rate() + ", with difference: " + diff); + diff = Math.Abs(zicV.rate() - (fixedRate * (zicV.indexFixing() / baseCPI))); + QAssert.IsTrue(diff < 1e-8, "failed " + i + "th coupon reconstruction as " + + (fixedRate * (zicV.indexFixing() / baseCPI)) + " vs rate = " + + zicV.rate() + ", with difference: " + diff); } } double error = Math.Abs(testInfLegNPV - zisV.legNPV(0).Value); - QAssert.IsTrue( error < 1e-5, "failed manual inf leg NPV calc vs pricing engine: " + testInfLegNPV + " vs " + - zisV.legNPV(0)); + QAssert.IsTrue(error < 1e-5, "failed manual inf leg NPV calc vs pricing engine: " + testInfLegNPV + " vs " + + zisV.legNPV(0)); - diff = Math.Abs(1-zisV.NPV()/4191660.0); - #if QL_USE_INDEXED_COUPON + diff = Math.Abs(1 - zisV.NPV() / 4191660.0); +#if QL_USE_INDEXED_COUPON double max_diff = 1e-5; - #else +#else double max_diff = 3e-5; - #endif - QAssert.IsTrue( diff < max_diff, "failed stored consistency value test, ratio = " + diff ); +#endif + QAssert.IsTrue(diff < max_diff, "failed stored consistency value test, ratio = " + diff); // remove circular refernce common.hcpi.linkTo(null); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void zciisconsistency() + public void zciisconsistency() { CommonVars common = new CommonVars(); @@ -375,17 +377,17 @@ public void zciisconsistency() Calendar cal = new UnitedKingdom(); BusinessDayConvention paymentConvention = BusinessDayConvention.ModifiedFollowing; DayCounter dummyDC = null, dc = new ActualActual(); - Period observationLag = new Period(2,TimeUnit.Months); + Period observationLag = new Period(2, TimeUnit.Months); double quote = 0.03714; ZeroCouponInflationSwap zciis = new ZeroCouponInflationSwap(ztype, nominal, startDate, endDate, cal, - paymentConvention, dc, quote, common.ii, observationLag); + paymentConvention, dc, quote, common.ii, observationLag); // simple structure so simple pricing engine - most work done by index DiscountingSwapEngine dse = new DiscountingSwapEngine(common.nominalUK); zciis.setPricingEngine(dse); - QAssert.IsTrue(Math.Abs(zciis.NPV())<1e-3,"zciis does not reprice to zero"); + QAssert.IsTrue(Math.Abs(zciis.NPV()) < 1e-3, "zciis does not reprice to zero"); List oneDate = new List(); oneDate.Add(endDate); @@ -393,9 +395,9 @@ public void zciisconsistency() CPISwap.Type stype = CPISwap.Type.Payer; double inflationNominal = nominal; - double floatNominal = inflationNominal * Math.Pow(1.0+quote,50); + double floatNominal = inflationNominal * Math.Pow(1.0 + quote, 50); bool subtractInflationNominal = true; - double dummySpread=0.0, dummyFixedRate=0.0; + double dummySpread = 0.0, dummyFixedRate = 0.0; int fixingDays = 0; Date baseDate = startDate - observationLag; double baseCPI = common.ii.fixing(baseDate); @@ -403,29 +405,29 @@ public void zciisconsistency() IborIndex dummyFloatIndex = new IborIndex(); CPISwap cS = new CPISwap(stype, floatNominal, subtractInflationNominal, dummySpread, dummyDC, schOneDate, - paymentConvention, fixingDays, dummyFloatIndex, - dummyFixedRate, baseCPI, dummyDC, schOneDate, paymentConvention, observationLag, - common.ii, InterpolationType.AsIndex, inflationNominal); + paymentConvention, fixingDays, dummyFloatIndex, + dummyFixedRate, baseCPI, dummyDC, schOneDate, paymentConvention, observationLag, + common.ii, InterpolationType.AsIndex, inflationNominal); cS.setPricingEngine(dse); - QAssert.IsTrue(Math.Abs(cS.NPV())<1e-3,"CPISwap as ZCIIS does not reprice to zero"); + QAssert.IsTrue(Math.Abs(cS.NPV()) < 1e-3, "CPISwap as ZCIIS does not reprice to zero"); - for (int i=0; i<2; i++) + for (int i = 0; i < 2; i++) { double cs = cS.legNPV(i).GetValueOrDefault(); double z = zciis.legNPV(i).GetValueOrDefault(); - QAssert.IsTrue(Math.Abs(cs - z)<1e-3, "zciis leg does not equal CPISwap leg"); + QAssert.IsTrue(Math.Abs(cs - z) < 1e-3, "zciis leg does not equal CPISwap leg"); } // remove circular refernce common.hcpi.linkTo(null); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void cpibondconsistency() + public void cpibondconsistency() { CommonVars common = new CommonVars(); @@ -439,7 +441,7 @@ public void cpibondconsistency() DayCounter floatDayCount = new Actual365Fixed(); BusinessDayConvention floatPaymentConvention = BusinessDayConvention.ModifiedFollowing; int fixingDays = 0; - IborIndex floatIndex = new GBPLibor(new Period(6,TimeUnit.Months),common.nominalUK); + IborIndex floatIndex = new GBPLibor(new Period(6, TimeUnit.Months), common.nominalUK); // fixed x inflation leg double fixedRate = 0.1;//1% would be 0.01 @@ -455,38 +457,38 @@ public void cpibondconsistency() Date startDate = new Date(2, Month.October, 2007); Date endDate = new Date(2, Month.October, 2052); Schedule floatSchedule = new MakeSchedule().from(startDate).to(endDate) - .withTenor(new Period(6,TimeUnit.Months)) + .withTenor(new Period(6, TimeUnit.Months)) .withCalendar(new UnitedKingdom()) .withConvention(floatPaymentConvention) .backwards().value(); Schedule fixedSchedule = new MakeSchedule().from(startDate).to(endDate) - .withTenor(new Period(6,TimeUnit.Months)) + .withTenor(new Period(6, TimeUnit.Months)) .withCalendar(new UnitedKingdom()) .withConvention(BusinessDayConvention.Unadjusted) .backwards().value(); CPISwap zisV = new CPISwap(type, nominal, subtractInflationNominal, - spread, floatDayCount, floatSchedule, - floatPaymentConvention, fixingDays, floatIndex, - fixedRate, baseCPI, fixedDayCount, fixedSchedule, - fixedPaymentConvention, contractObservationLag, - fixedIndex, observationInterpolation); - - double[] floatFix = {0.06255,0.05975,0.0637,0.018425,0.0073438,-1,-1}; - double[] cpiFix = {211.4,217.2,211.4,213.4,-2,-2}; - for(int i=0;i fixedRates = new InitializedList(1,fixedRate); + List fixedRates = new InitializedList(1, fixedRate); int settlementDays = 1;// cannot be zero! bool growthOnly = true; CPIBond cpiB = new CPIBond(settlementDays, nominal, growthOnly, - baseCPI, contractObservationLag, fixedIndex, - observationInterpolation, fixedSchedule, - fixedRates, fixedDayCount, fixedPaymentConvention); + baseCPI, contractObservationLag, fixedIndex, + observationInterpolation, fixedSchedule, + fixedRates, fixedDayCount, fixedPaymentConvention); DiscountingBondEngine dbe = new DiscountingBondEngine(common.nominalUK); cpiB.setPricingEngine(dbe); - QAssert.IsTrue(Math.Abs(cpiB.NPV() - zisV.legNPV(0).GetValueOrDefault())<1e-5, - "cpi bond does not equal equivalent cpi swap leg"); + QAssert.IsTrue(Math.Abs(cpiB.NPV() - zisV.legNPV(0).GetValueOrDefault()) < 1e-5, + "cpi bond does not equal equivalent cpi swap leg"); // remove circular refernce common.hcpi.linkTo(null); - } + } } } diff --git a/tests/QLNet.Tests/T_Calendars.cs b/tests/QLNet.Tests/T_Calendars.cs index c25ceda5f..ab05162b1 100644 --- a/tests/QLNet.Tests/T_Calendars.cs +++ b/tests/QLNet.Tests/T_Calendars.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,1310 +23,1351 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; using System.Diagnostics; -namespace TestSuite { +namespace TestSuite +{ #if NET40 || NET45 [TestClass()] #endif - public class T_Calendars { + public class T_Calendars + { #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testModifiedCalendars() { - Calendar c1 = new TARGET(); - Calendar c2 = new UnitedStates(UnitedStates.Market.NYSE); - Date d1 = new Date(1, Month.May, 2004); // holiday for both calendars - Date d2 = new Date(26, Month.April, 2004); // business day + public void testModifiedCalendars() + { + Calendar c1 = new TARGET(); + Calendar c2 = new UnitedStates(UnitedStates.Market.NYSE); + Date d1 = new Date(1, Month.May, 2004); // holiday for both calendars + Date d2 = new Date(26, Month.April, 2004); // business day - QAssert.IsTrue(c1.isHoliday(d1), "wrong assumption---correct the test"); - QAssert.IsTrue(c1.isBusinessDay(d2), "wrong assumption---correct the test"); + QAssert.IsTrue(c1.isHoliday(d1), "wrong assumption---correct the test"); + QAssert.IsTrue(c1.isBusinessDay(d2), "wrong assumption---correct the test"); - QAssert.IsTrue(c2.isHoliday(d1), "wrong assumption---correct the test"); - QAssert.IsTrue(c2.isBusinessDay(d2), "wrong assumption---correct the test"); + QAssert.IsTrue(c2.isHoliday(d1), "wrong assumption---correct the test"); + QAssert.IsTrue(c2.isBusinessDay(d2), "wrong assumption---correct the test"); - // modify the TARGET calendar - c1.removeHoliday(d1); - c1.addHoliday(d2); + // modify the TARGET calendar + c1.removeHoliday(d1); + c1.addHoliday(d2); - // test - QAssert.IsFalse(c1.isHoliday(d1), d1 + " still a holiday for original TARGET instance"); - QAssert.IsFalse(c1.isBusinessDay(d2), d2 + " still a business day for original TARGET instance"); + // test + QAssert.IsFalse(c1.isHoliday(d1), d1 + " still a holiday for original TARGET instance"); + QAssert.IsFalse(c1.isBusinessDay(d2), d2 + " still a business day for original TARGET instance"); - // any instance of TARGET should be modified... - Calendar c3 = new TARGET(); - QAssert.IsFalse(c3.isHoliday(d1), d1 + " still a holiday for generic TARGET instance"); - QAssert.IsFalse(c3.isBusinessDay(d2), d2 + " still a business day for generic TARGET instance"); + // any instance of TARGET should be modified... + Calendar c3 = new TARGET(); + QAssert.IsFalse(c3.isHoliday(d1), d1 + " still a holiday for generic TARGET instance"); + QAssert.IsFalse(c3.isBusinessDay(d2), d2 + " still a business day for generic TARGET instance"); - // ...but not other calendars - QAssert.IsFalse(c2.isBusinessDay(d1), d1 + " business day for New York"); - QAssert.IsFalse(c2.isHoliday(d2), d2 + " holiday for New York"); + // ...but not other calendars + QAssert.IsFalse(c2.isBusinessDay(d1), d1 + " business day for New York"); + QAssert.IsFalse(c2.isHoliday(d2), d2 + " holiday for New York"); - // restore original holiday set---test the other way around - c3.addHoliday(d1); - c3.removeHoliday(d2); + // restore original holiday set---test the other way around + c3.addHoliday(d1); + c3.removeHoliday(d2); - QAssert.IsFalse(c1.isBusinessDay(d1), d1 + " still a business day"); - QAssert.IsFalse(c1.isHoliday(d2), d2 + " still a holiday"); - } + QAssert.IsFalse(c1.isBusinessDay(d1), d1 + " still a business day"); + QAssert.IsFalse(c1.isHoliday(d2), d2 + " still a holiday"); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testJointCalendars() { - Calendar c1 = new TARGET(), - c2 = new UnitedKingdom(), - c3 = new UnitedStates(UnitedStates.Market.NYSE), - c4 = new Japan(); - - Calendar c12h = new JointCalendar(c1, c2, JointCalendar.JointCalendarRule.JoinHolidays), - c12b = new JointCalendar(c1,c2,JointCalendar.JointCalendarRule.JoinBusinessDays), - c123h = new JointCalendar(c1,c2,c3,JointCalendar.JointCalendarRule.JoinHolidays), - c123b = new JointCalendar(c1,c2,c3,JointCalendar.JointCalendarRule.JoinBusinessDays), - c1234h = new JointCalendar(c1,c2,c3,c4,JointCalendar.JointCalendarRule.JoinHolidays), - c1234b = new JointCalendar(c1,c2,c3,c4,JointCalendar.JointCalendarRule.JoinBusinessDays); - - // test one year, starting today - Date firstDate = Date.Today, - endDate = firstDate + new Period(1, TimeUnit.Years); - - for (Date d = firstDate; d < endDate; d++) { - - bool b1 = c1.isBusinessDay(d), - b2 = c2.isBusinessDay(d), - b3 = c3.isBusinessDay(d), - b4 = c4.isBusinessDay(d); - - if ((b1 && b2) != c12h.isBusinessDay(d)) - QAssert.Fail("At date " + d + ":\n" - + " inconsistency between joint calendar " - + c12h.name() + " (joining holidays)\n" - + " and its components"); - - if ((b1 || b2) != c12b.isBusinessDay(d)) - QAssert.Fail("At date " + d + ":\n" - + " inconsistency between joint calendar " - + c12b.name() + " (joining business days)\n" - + " and its components"); - - if ((b1 && b2 && b3) != c123h.isBusinessDay(d)) - QAssert.Fail("At date " + d + ":\n" - + " inconsistency between joint calendar " - + c123h.name() + " (joining holidays)\n" - + " and its components"); - - if ((b1 || b2 || b3) != c123b.isBusinessDay(d)) - QAssert.Fail("At date " + d + ":\n" - + " inconsistency between joint calendar " - + c123b.name() + " (joining business days)\n" - + " and its components"); - - if ((b1 && b2 && b3 && b4) != c1234h.isBusinessDay(d)) - QAssert.Fail("At date " + d + ":\n" - + " inconsistency between joint calendar " - + c1234h.name() + " (joining holidays)\n" - + " and its components"); - - if ((b1 || b2 || b3 || b4) != c1234b.isBusinessDay(d)) - QAssert.Fail("At date " + d + ":\n" - + " inconsistency between joint calendar " - + c1234b.name() + " (joining business days)\n" - + " and its components"); + public void testJointCalendars() + { + Calendar c1 = new TARGET(), + c2 = new UnitedKingdom(), + c3 = new UnitedStates(UnitedStates.Market.NYSE), + c4 = new Japan(); + + Calendar c12h = new JointCalendar(c1, c2, JointCalendar.JointCalendarRule.JoinHolidays), + c12b = new JointCalendar(c1, c2, JointCalendar.JointCalendarRule.JoinBusinessDays), + c123h = new JointCalendar(c1, c2, c3, JointCalendar.JointCalendarRule.JoinHolidays), + c123b = new JointCalendar(c1, c2, c3, JointCalendar.JointCalendarRule.JoinBusinessDays), + c1234h = new JointCalendar(c1, c2, c3, c4, JointCalendar.JointCalendarRule.JoinHolidays), + c1234b = new JointCalendar(c1, c2, c3, c4, JointCalendar.JointCalendarRule.JoinBusinessDays); + + // test one year, starting today + Date firstDate = Date.Today, + endDate = firstDate + new Period(1, TimeUnit.Years); + + for (Date d = firstDate; d < endDate; d++) + { - } - } + bool b1 = c1.isBusinessDay(d), + b2 = c2.isBusinessDay(d), + b3 = c3.isBusinessDay(d), + b4 = c4.isBusinessDay(d); + + if ((b1 && b2) != c12h.isBusinessDay(d)) + QAssert.Fail("At date " + d + ":\n" + + " inconsistency between joint calendar " + + c12h.name() + " (joining holidays)\n" + + " and its components"); + + if ((b1 || b2) != c12b.isBusinessDay(d)) + QAssert.Fail("At date " + d + ":\n" + + " inconsistency between joint calendar " + + c12b.name() + " (joining business days)\n" + + " and its components"); + + if ((b1 && b2 && b3) != c123h.isBusinessDay(d)) + QAssert.Fail("At date " + d + ":\n" + + " inconsistency between joint calendar " + + c123h.name() + " (joining holidays)\n" + + " and its components"); + + if ((b1 || b2 || b3) != c123b.isBusinessDay(d)) + QAssert.Fail("At date " + d + ":\n" + + " inconsistency between joint calendar " + + c123b.name() + " (joining business days)\n" + + " and its components"); + + if ((b1 && b2 && b3 && b4) != c1234h.isBusinessDay(d)) + QAssert.Fail("At date " + d + ":\n" + + " inconsistency between joint calendar " + + c1234h.name() + " (joining holidays)\n" + + " and its components"); + + if ((b1 || b2 || b3 || b4) != c1234b.isBusinessDay(d)) + QAssert.Fail("At date " + d + ":\n" + + " inconsistency between joint calendar " + + c1234b.name() + " (joining business days)\n" + + " and its components"); + + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testUSSettlement() { - // Testing US settlement holiday list - List expectedHol = new List(); - - expectedHol.Add(new Date(1, Month.January, 2004)); - expectedHol.Add(new Date(19, Month.January, 2004)); - expectedHol.Add(new Date(16, Month.February, 2004)); - expectedHol.Add(new Date(31, Month.May, 2004)); - expectedHol.Add(new Date(5, Month.July, 2004)); - expectedHol.Add(new Date(6, Month.September, 2004)); - expectedHol.Add(new Date(11, Month.October, 2004)); - expectedHol.Add(new Date(11, Month.November, 2004)); - expectedHol.Add(new Date(25, Month.November, 2004)); - expectedHol.Add(new Date(24, Month.December, 2004)); - - expectedHol.Add(new Date(31, Month.December, 2004)); - expectedHol.Add(new Date(17, Month.January, 2005)); - expectedHol.Add(new Date(21, Month.February, 2005)); - expectedHol.Add(new Date(30, Month.May, 2005)); - expectedHol.Add(new Date(4, Month.July, 2005)); - expectedHol.Add(new Date(5, Month.September, 2005)); - expectedHol.Add(new Date(10, Month.October, 2005)); - expectedHol.Add(new Date(11, Month.November, 2005)); - expectedHol.Add(new Date(24, Month.November, 2005)); - expectedHol.Add(new Date(26, Month.December, 2005)); - - Calendar c = new UnitedStates(UnitedStates.Market.Settlement); - List hol = Calendar.holidayList(c, new Date(1, Month.January, 2004), - new Date(31, Month.December, 2005)); - if ( hol.Count != expectedHol.Count ) - QAssert.Fail( "there were " + expectedHol.Count - + " expected holidays, while there are " + hol.Count - + " calculated holidays" ); - - for (int i = 0; i (); - expectedHol.Add(new Date(2,Month.January,1961)); - expectedHol.Add(new Date(22,Month.February,1961)); - expectedHol.Add(new Date(30,Month.May,1961)); - expectedHol.Add(new Date(4,Month.July,1961)); - expectedHol.Add(new Date(4,Month.September,1961)); - expectedHol.Add(new Date(10,Month.November,1961)); - expectedHol.Add(new Date(23,Month.November,1961)); - expectedHol.Add(new Date(25,Month.December,1961)); - - hol = Calendar.holidayList( c, new Date( 1, Month.January, 1961 ), new Date( 31, Month.December, 1961 ) ); - - if (hol.Count != expectedHol.Count) - QAssert.Fail("there were " + expectedHol.Count + - " expected holidays, while there are " + hol.Count + - " calculated holidays"); - - for ( int i = 0; i < hol.Count; i++ ) - { - if ( hol[i] != expectedHol[i] ) - QAssert.Fail( "expected holiday was " + expectedHol[i] - + " while calculated holiday is " + hol[i] ); - } - } + public void testUSSettlement() + { + // Testing US settlement holiday list + List expectedHol = new List(); + + expectedHol.Add(new Date(1, Month.January, 2004)); + expectedHol.Add(new Date(19, Month.January, 2004)); + expectedHol.Add(new Date(16, Month.February, 2004)); + expectedHol.Add(new Date(31, Month.May, 2004)); + expectedHol.Add(new Date(5, Month.July, 2004)); + expectedHol.Add(new Date(6, Month.September, 2004)); + expectedHol.Add(new Date(11, Month.October, 2004)); + expectedHol.Add(new Date(11, Month.November, 2004)); + expectedHol.Add(new Date(25, Month.November, 2004)); + expectedHol.Add(new Date(24, Month.December, 2004)); + + expectedHol.Add(new Date(31, Month.December, 2004)); + expectedHol.Add(new Date(17, Month.January, 2005)); + expectedHol.Add(new Date(21, Month.February, 2005)); + expectedHol.Add(new Date(30, Month.May, 2005)); + expectedHol.Add(new Date(4, Month.July, 2005)); + expectedHol.Add(new Date(5, Month.September, 2005)); + expectedHol.Add(new Date(10, Month.October, 2005)); + expectedHol.Add(new Date(11, Month.November, 2005)); + expectedHol.Add(new Date(24, Month.November, 2005)); + expectedHol.Add(new Date(26, Month.December, 2005)); + + Calendar c = new UnitedStates(UnitedStates.Market.Settlement); + List hol = Calendar.holidayList(c, new Date(1, Month.January, 2004), + new Date(31, Month.December, 2005)); + if (hol.Count != expectedHol.Count) + QAssert.Fail("there were " + expectedHol.Count + + " expected holidays, while there are " + hol.Count + + " calculated holidays"); + + for (int i = 0; i < hol.Count; i++) + { + if (hol[i] != expectedHol[i]) + QAssert.Fail("expected holiday was " + expectedHol[i] + " while calculated holiday is " + hol[i]); + } + + // before Uniform Monday Holiday Act + expectedHol = new List(); + expectedHol.Add(new Date(2, Month.January, 1961)); + expectedHol.Add(new Date(22, Month.February, 1961)); + expectedHol.Add(new Date(30, Month.May, 1961)); + expectedHol.Add(new Date(4, Month.July, 1961)); + expectedHol.Add(new Date(4, Month.September, 1961)); + expectedHol.Add(new Date(10, Month.November, 1961)); + expectedHol.Add(new Date(23, Month.November, 1961)); + expectedHol.Add(new Date(25, Month.December, 1961)); + + hol = Calendar.holidayList(c, new Date(1, Month.January, 1961), new Date(31, Month.December, 1961)); + + if (hol.Count != expectedHol.Count) + QAssert.Fail("there were " + expectedHol.Count + + " expected holidays, while there are " + hol.Count + + " calculated holidays"); + + for (int i = 0; i < hol.Count; i++) + { + if (hol[i] != expectedHol[i]) + QAssert.Fail("expected holiday was " + expectedHol[i] + + " while calculated holiday is " + hol[i]); + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testUSGovernmentBondMarket() { - - List expectedHol = new List(); - expectedHol.Add(new Date(1, Month.January, 2004)); - expectedHol.Add(new Date(19, Month.January, 2004)); - expectedHol.Add(new Date(16, Month.February, 2004)); - expectedHol.Add(new Date(9, Month.April, 2004)); - expectedHol.Add(new Date(31, Month.May, 2004)); - expectedHol.Add(new Date(5, Month.July, 2004)); - expectedHol.Add(new Date(6, Month.September, 2004)); - expectedHol.Add(new Date(11, Month.October, 2004)); - expectedHol.Add(new Date(11, Month.November, 2004)); - expectedHol.Add(new Date(25, Month.November, 2004)); - expectedHol.Add(new Date(24, Month.December, 2004)); - - Calendar c = new UnitedStates(UnitedStates.Market.GovernmentBond); - List hol = Calendar.holidayList(c, new Date(1, Month.January, 2004), new Date(31, Month.December, 2004)); - - for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) { - if (hol[i] != expectedHol[i]) - QAssert.Fail("expected holiday was " + expectedHol[i] + " while calculated holiday is " + hol[i]); - } - if (hol.Count != expectedHol.Count) - QAssert.Fail("there were " + expectedHol.Count + - " expected holidays, while there are " + hol.Count + - " calculated holidays"); - } + public void testUSGovernmentBondMarket() + { + + List expectedHol = new List(); + expectedHol.Add(new Date(1, Month.January, 2004)); + expectedHol.Add(new Date(19, Month.January, 2004)); + expectedHol.Add(new Date(16, Month.February, 2004)); + expectedHol.Add(new Date(9, Month.April, 2004)); + expectedHol.Add(new Date(31, Month.May, 2004)); + expectedHol.Add(new Date(5, Month.July, 2004)); + expectedHol.Add(new Date(6, Month.September, 2004)); + expectedHol.Add(new Date(11, Month.October, 2004)); + expectedHol.Add(new Date(11, Month.November, 2004)); + expectedHol.Add(new Date(25, Month.November, 2004)); + expectedHol.Add(new Date(24, Month.December, 2004)); + + Calendar c = new UnitedStates(UnitedStates.Market.GovernmentBond); + List hol = Calendar.holidayList(c, new Date(1, Month.January, 2004), new Date(31, Month.December, 2004)); + + for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) + { + if (hol[i] != expectedHol[i]) + QAssert.Fail("expected holiday was " + expectedHol[i] + " while calculated holiday is " + hol[i]); + } + if (hol.Count != expectedHol.Count) + QAssert.Fail("there were " + expectedHol.Count + + " expected holidays, while there are " + hol.Count + + " calculated holidays"); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testUSNewYorkStockExchange() { - - List expectedHol = new List(); - expectedHol.Add(new Date(1, Month.January, 2004)); - expectedHol.Add(new Date(19, Month.January, 2004)); - expectedHol.Add(new Date(16, Month.February, 2004)); - expectedHol.Add(new Date(9, Month.April, 2004)); - expectedHol.Add(new Date(31, Month.May, 2004)); - expectedHol.Add(new Date(11, Month.June, 2004)); - expectedHol.Add(new Date(5, Month.July, 2004)); - expectedHol.Add(new Date(6, Month.September, 2004)); - expectedHol.Add(new Date(25, Month.November, 2004)); - expectedHol.Add(new Date(24, Month.December, 2004)); - - expectedHol.Add(new Date(17, Month.January, 2005)); - expectedHol.Add(new Date(21, Month.February, 2005)); - expectedHol.Add(new Date(25, Month.March, 2005)); - expectedHol.Add(new Date(30, Month.May, 2005)); - expectedHol.Add(new Date(4, Month.July, 2005)); - expectedHol.Add(new Date(5, Month.September, 2005)); - expectedHol.Add(new Date(24, Month.November, 2005)); - expectedHol.Add(new Date(26, Month.December, 2005)); - - expectedHol.Add(new Date(2, Month.January, 2006)); - expectedHol.Add(new Date(16, Month.January, 2006)); - expectedHol.Add(new Date(20, Month.February, 2006)); - expectedHol.Add(new Date(14, Month.April, 2006)); - expectedHol.Add(new Date(29, Month.May, 2006)); - expectedHol.Add(new Date(4, Month.July, 2006)); - expectedHol.Add(new Date(4, Month.September, 2006)); - expectedHol.Add(new Date(23, Month.November, 2006)); - expectedHol.Add(new Date(25, Month.December, 2006)); - - Calendar c = new UnitedStates(UnitedStates.Market.NYSE); - List hol = Calendar.holidayList(c, new Date(1, Month.January, 2004), new Date(31, Month.December, 2006)); - - int i; - for (i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) { - if (hol[i] != expectedHol[i]) - QAssert.Fail("expected holiday was " + expectedHol[i] + " while calculated holiday is " + hol[i]); - } - if (hol.Count != expectedHol.Count) - QAssert.Fail("there were " + expectedHol.Count + - " expected holidays, while there are " + hol.Count + - " calculated holidays"); - - List histClose = new List(); - histClose.Add(new Date(30, Month.October, 2012)); // Hurricane Sandy - histClose.Add(new Date(29, Month.October, 2012)); // Hurricane Sandy - histClose.Add(new Date(11, Month.June, 2004)); // Reagan's funeral - histClose.Add(new Date(14, Month.September, 2001));// September 11, 2001 - histClose.Add(new Date(13, Month.September, 2001));// September 11, 2001 - histClose.Add(new Date(12, Month.September, 2001));// September 11, 2001 - histClose.Add(new Date(11, Month.September, 2001));// September 11, 2001 - histClose.Add(new Date(27, Month.April, 1994 ) ); // Nixon's funeral. - histClose.Add(new Date(27, Month.September,1985)); // Hurricane Gloria - histClose.Add(new Date(14, Month.July, 1977)); // 1977 Blackout - histClose.Add(new Date(25, Month.January, 1973)); // Johnson's funeral. - histClose.Add(new Date(28, Month.December, 1972)); // Truman's funeral - histClose.Add(new Date(21, Month.July, 1969)); // Lunar exploration nat. day - histClose.Add(new Date(31, Month.March, 1969)); // Eisenhower's funeral - histClose.Add(new Date(10, Month.February, 1969)); // heavy snow - histClose.Add(new Date(5, Month.July, 1968)); // Day after Independence Day - histClose.Add( new Date( 9, Month.April, 1968 ) ); // Mourning for MLK - histClose.Add( new Date( 24, Month.December, 1965 ) ); // Christmas Eve - histClose.Add( new Date( 25, Month.November, 1963 ) ); // Kennedy's funeral - histClose.Add( new Date( 29, Month.May, 1961 ) ); // Day before Decoration Day - histClose.Add( new Date( 26, Month.December, 1958 ) ); // Day after Christmas - histClose.Add( new Date( 24, Month.December, 1956 ) ); // Christmas Eve - histClose.Add( new Date( 24, Month.December, 1954 ) ); // Christmas Eve - // June 12-Dec. 31, 1968 - // Four day week (closed on Wednesdays) - Paperwork Crisis - histClose.Add(new Date(12, Month.Jun, 1968)); - histClose.Add(new Date(19, Month.Jun, 1968)); - histClose.Add(new Date(26, Month.Jun, 1968)); - histClose.Add(new Date(3, Month.Jul, 1968)); - histClose.Add(new Date(10, Month.Jul, 1968)); - histClose.Add(new Date(17, Month.Jul, 1968)); - histClose.Add(new Date(20, Month.Nov, 1968)); - histClose.Add(new Date(27, Month.Nov, 1968)); - histClose.Add(new Date(4, Month.Dec, 1968)); - histClose.Add(new Date(11, Month.Dec, 1968)); - histClose.Add(new Date(18, Month.Dec, 1968)); - // Presidential election days - histClose.Add(new Date(4, Month.Nov, 1980)); - histClose.Add(new Date(2, Month.Nov, 1976)); - histClose.Add(new Date(7, Month.Nov, 1972)); - histClose.Add(new Date(5, Month.Nov, 1968)); - histClose.Add(new Date(3, Month.Nov, 1964)); - - for (i = 0; i < histClose.Count; i++) { - if (!c.isHoliday(histClose[i])) - QAssert.Fail(histClose[i] + " should be holiday (historical close)"); - } + public void testUSNewYorkStockExchange() + { + + List expectedHol = new List(); + expectedHol.Add(new Date(1, Month.January, 2004)); + expectedHol.Add(new Date(19, Month.January, 2004)); + expectedHol.Add(new Date(16, Month.February, 2004)); + expectedHol.Add(new Date(9, Month.April, 2004)); + expectedHol.Add(new Date(31, Month.May, 2004)); + expectedHol.Add(new Date(11, Month.June, 2004)); + expectedHol.Add(new Date(5, Month.July, 2004)); + expectedHol.Add(new Date(6, Month.September, 2004)); + expectedHol.Add(new Date(25, Month.November, 2004)); + expectedHol.Add(new Date(24, Month.December, 2004)); + + expectedHol.Add(new Date(17, Month.January, 2005)); + expectedHol.Add(new Date(21, Month.February, 2005)); + expectedHol.Add(new Date(25, Month.March, 2005)); + expectedHol.Add(new Date(30, Month.May, 2005)); + expectedHol.Add(new Date(4, Month.July, 2005)); + expectedHol.Add(new Date(5, Month.September, 2005)); + expectedHol.Add(new Date(24, Month.November, 2005)); + expectedHol.Add(new Date(26, Month.December, 2005)); + + expectedHol.Add(new Date(2, Month.January, 2006)); + expectedHol.Add(new Date(16, Month.January, 2006)); + expectedHol.Add(new Date(20, Month.February, 2006)); + expectedHol.Add(new Date(14, Month.April, 2006)); + expectedHol.Add(new Date(29, Month.May, 2006)); + expectedHol.Add(new Date(4, Month.July, 2006)); + expectedHol.Add(new Date(4, Month.September, 2006)); + expectedHol.Add(new Date(23, Month.November, 2006)); + expectedHol.Add(new Date(25, Month.December, 2006)); + + Calendar c = new UnitedStates(UnitedStates.Market.NYSE); + List hol = Calendar.holidayList(c, new Date(1, Month.January, 2004), new Date(31, Month.December, 2006)); + + int i; + for (i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) + { + if (hol[i] != expectedHol[i]) + QAssert.Fail("expected holiday was " + expectedHol[i] + " while calculated holiday is " + hol[i]); + } + if (hol.Count != expectedHol.Count) + QAssert.Fail("there were " + expectedHol.Count + + " expected holidays, while there are " + hol.Count + + " calculated holidays"); + + List histClose = new List(); + histClose.Add(new Date(30, Month.October, 2012)); // Hurricane Sandy + histClose.Add(new Date(29, Month.October, 2012)); // Hurricane Sandy + histClose.Add(new Date(11, Month.June, 2004)); // Reagan's funeral + histClose.Add(new Date(14, Month.September, 2001));// September 11, 2001 + histClose.Add(new Date(13, Month.September, 2001));// September 11, 2001 + histClose.Add(new Date(12, Month.September, 2001));// September 11, 2001 + histClose.Add(new Date(11, Month.September, 2001));// September 11, 2001 + histClose.Add(new Date(27, Month.April, 1994)); // Nixon's funeral. + histClose.Add(new Date(27, Month.September, 1985)); // Hurricane Gloria + histClose.Add(new Date(14, Month.July, 1977)); // 1977 Blackout + histClose.Add(new Date(25, Month.January, 1973)); // Johnson's funeral. + histClose.Add(new Date(28, Month.December, 1972)); // Truman's funeral + histClose.Add(new Date(21, Month.July, 1969)); // Lunar exploration nat. day + histClose.Add(new Date(31, Month.March, 1969)); // Eisenhower's funeral + histClose.Add(new Date(10, Month.February, 1969)); // heavy snow + histClose.Add(new Date(5, Month.July, 1968)); // Day after Independence Day + histClose.Add(new Date(9, Month.April, 1968)); // Mourning for MLK + histClose.Add(new Date(24, Month.December, 1965)); // Christmas Eve + histClose.Add(new Date(25, Month.November, 1963)); // Kennedy's funeral + histClose.Add(new Date(29, Month.May, 1961)); // Day before Decoration Day + histClose.Add(new Date(26, Month.December, 1958)); // Day after Christmas + histClose.Add(new Date(24, Month.December, 1956)); // Christmas Eve + histClose.Add(new Date(24, Month.December, 1954)); // Christmas Eve + // June 12-Dec. 31, 1968 + // Four day week (closed on Wednesdays) - Paperwork Crisis + histClose.Add(new Date(12, Month.Jun, 1968)); + histClose.Add(new Date(19, Month.Jun, 1968)); + histClose.Add(new Date(26, Month.Jun, 1968)); + histClose.Add(new Date(3, Month.Jul, 1968)); + histClose.Add(new Date(10, Month.Jul, 1968)); + histClose.Add(new Date(17, Month.Jul, 1968)); + histClose.Add(new Date(20, Month.Nov, 1968)); + histClose.Add(new Date(27, Month.Nov, 1968)); + histClose.Add(new Date(4, Month.Dec, 1968)); + histClose.Add(new Date(11, Month.Dec, 1968)); + histClose.Add(new Date(18, Month.Dec, 1968)); + // Presidential election days + histClose.Add(new Date(4, Month.Nov, 1980)); + histClose.Add(new Date(2, Month.Nov, 1976)); + histClose.Add(new Date(7, Month.Nov, 1972)); + histClose.Add(new Date(5, Month.Nov, 1968)); + histClose.Add(new Date(3, Month.Nov, 1964)); + + for (i = 0; i < histClose.Count; i++) + { + if (!c.isHoliday(histClose[i])) + QAssert.Fail(histClose[i] + " should be holiday (historical close)"); + } - } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testTARGET() { - List expectedHol = new List(); - expectedHol.Add(new Date(1,Month.January,1999)); - expectedHol.Add(new Date(31, Month.December, 1999)); - - expectedHol.Add(new Date(21, Month.April, 2000)); - expectedHol.Add(new Date(24, Month.April, 2000)); - expectedHol.Add(new Date(1, Month.May, 2000)); - expectedHol.Add(new Date(25, Month.December, 2000)); - expectedHol.Add(new Date(26, Month.December, 2000)); - - expectedHol.Add(new Date(1, Month.January, 2001)); - expectedHol.Add(new Date(13, Month.April, 2001)); - expectedHol.Add(new Date(16, Month.April, 2001)); - expectedHol.Add(new Date(1, Month.May, 2001)); - expectedHol.Add(new Date(25, Month.December, 2001)); - expectedHol.Add(new Date(26, Month.December, 2001)); - expectedHol.Add(new Date(31, Month.December, 2001)); - - expectedHol.Add(new Date(1, Month.January, 2002)); - expectedHol.Add(new Date(29, Month.March, 2002)); - expectedHol.Add(new Date(1, Month.April, 2002)); - expectedHol.Add(new Date(1, Month.May, 2002)); - expectedHol.Add(new Date(25, Month.December, 2002)); - expectedHol.Add(new Date(26, Month.December, 2002)); - - expectedHol.Add(new Date(1, Month.January, 2003)); - expectedHol.Add(new Date(18, Month.April, 2003)); - expectedHol.Add(new Date(21, Month.April, 2003)); - expectedHol.Add(new Date(1, Month.May, 2003)); - expectedHol.Add(new Date(25, Month.December, 2003)); - expectedHol.Add(new Date(26, Month.December, 2003)); - - expectedHol.Add(new Date(1, Month.January, 2004)); - expectedHol.Add(new Date(9, Month.April, 2004)); - expectedHol.Add(new Date(12, Month.April, 2004)); - - expectedHol.Add(new Date(25, Month.March, 2005)); - expectedHol.Add(new Date(28, Month.March, 2005)); - expectedHol.Add(new Date(26, Month.December, 2005)); - - expectedHol.Add(new Date(14, Month.April, 2006)); - expectedHol.Add(new Date(17, Month.April, 2006)); - expectedHol.Add(new Date(1, Month.May, 2006)); - expectedHol.Add(new Date(25, Month.December, 2006)); - expectedHol.Add(new Date(26, Month.December, 2006)); - - Calendar c = new TARGET(); - List hol = Calendar.holidayList(c, new Date(1, Month.January, 1999), new Date(31, Month.December, 2006)); - - for (int i=0; i expectedHol = new List(); + expectedHol.Add(new Date(1, Month.January, 1999)); + expectedHol.Add(new Date(31, Month.December, 1999)); + + expectedHol.Add(new Date(21, Month.April, 2000)); + expectedHol.Add(new Date(24, Month.April, 2000)); + expectedHol.Add(new Date(1, Month.May, 2000)); + expectedHol.Add(new Date(25, Month.December, 2000)); + expectedHol.Add(new Date(26, Month.December, 2000)); + + expectedHol.Add(new Date(1, Month.January, 2001)); + expectedHol.Add(new Date(13, Month.April, 2001)); + expectedHol.Add(new Date(16, Month.April, 2001)); + expectedHol.Add(new Date(1, Month.May, 2001)); + expectedHol.Add(new Date(25, Month.December, 2001)); + expectedHol.Add(new Date(26, Month.December, 2001)); + expectedHol.Add(new Date(31, Month.December, 2001)); + + expectedHol.Add(new Date(1, Month.January, 2002)); + expectedHol.Add(new Date(29, Month.March, 2002)); + expectedHol.Add(new Date(1, Month.April, 2002)); + expectedHol.Add(new Date(1, Month.May, 2002)); + expectedHol.Add(new Date(25, Month.December, 2002)); + expectedHol.Add(new Date(26, Month.December, 2002)); + + expectedHol.Add(new Date(1, Month.January, 2003)); + expectedHol.Add(new Date(18, Month.April, 2003)); + expectedHol.Add(new Date(21, Month.April, 2003)); + expectedHol.Add(new Date(1, Month.May, 2003)); + expectedHol.Add(new Date(25, Month.December, 2003)); + expectedHol.Add(new Date(26, Month.December, 2003)); + + expectedHol.Add(new Date(1, Month.January, 2004)); + expectedHol.Add(new Date(9, Month.April, 2004)); + expectedHol.Add(new Date(12, Month.April, 2004)); + + expectedHol.Add(new Date(25, Month.March, 2005)); + expectedHol.Add(new Date(28, Month.March, 2005)); + expectedHol.Add(new Date(26, Month.December, 2005)); + + expectedHol.Add(new Date(14, Month.April, 2006)); + expectedHol.Add(new Date(17, Month.April, 2006)); + expectedHol.Add(new Date(1, Month.May, 2006)); + expectedHol.Add(new Date(25, Month.December, 2006)); + expectedHol.Add(new Date(26, Month.December, 2006)); + + Calendar c = new TARGET(); + List hol = Calendar.holidayList(c, new Date(1, Month.January, 1999), new Date(31, Month.December, 2006)); + + for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) + { + if (hol[i] != expectedHol[i]) + QAssert.Fail("expected holiday was " + expectedHol[i] + + " while calculated holiday is " + hol[i]); + } + if (hol.Count != expectedHol.Count) + QAssert.Fail("there were " + expectedHol.Count + + " expected holidays, while there are " + hol.Count + + " calculated holidays"); - } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testGermanyFrankfurt() { - List expectedHol = new List(); - - expectedHol.Add(new Date(1, Month.January,2003)); - expectedHol.Add(new Date(18,Month.April,2003)); - expectedHol.Add(new Date(21,Month.April,2003)); - expectedHol.Add(new Date(1,Month.May,2003)); - expectedHol.Add(new Date(24,Month.December,2003)); - expectedHol.Add(new Date(25,Month.December,2003)); - expectedHol.Add(new Date(26,Month.December,2003)); - expectedHol.Add(new Date(31,Month.December,2003)); - - expectedHol.Add(new Date(1,Month.January,2004)); - expectedHol.Add(new Date(9,Month.April,2004)); - expectedHol.Add(new Date(12,Month.April,2004)); - expectedHol.Add(new Date(24,Month.December,2004)); - expectedHol.Add(new Date(31,Month.December,2004)); - - Calendar c = new Germany(Germany.Market.FrankfurtStockExchange); - List hol = Calendar.holidayList(c, new Date(1,Month.January,2003), new Date(31,Month.December,2004)); - for (int i=0; i expectedHol = new List(); + + expectedHol.Add(new Date(1, Month.January, 2003)); + expectedHol.Add(new Date(18, Month.April, 2003)); + expectedHol.Add(new Date(21, Month.April, 2003)); + expectedHol.Add(new Date(1, Month.May, 2003)); + expectedHol.Add(new Date(24, Month.December, 2003)); + expectedHol.Add(new Date(25, Month.December, 2003)); + expectedHol.Add(new Date(26, Month.December, 2003)); + expectedHol.Add(new Date(31, Month.December, 2003)); + + expectedHol.Add(new Date(1, Month.January, 2004)); + expectedHol.Add(new Date(9, Month.April, 2004)); + expectedHol.Add(new Date(12, Month.April, 2004)); + expectedHol.Add(new Date(24, Month.December, 2004)); + expectedHol.Add(new Date(31, Month.December, 2004)); + + Calendar c = new Germany(Germany.Market.FrankfurtStockExchange); + List hol = Calendar.holidayList(c, new Date(1, Month.January, 2003), new Date(31, Month.December, 2004)); + for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) + { + if (hol[i] != expectedHol[i]) + QAssert.Fail("expected holiday was " + expectedHol[i] + + " while calculated holiday is " + hol[i]); + } + if (hol.Count != expectedHol.Count) + QAssert.Fail("there were " + expectedHol.Count + + " expected holidays, while there are " + hol.Count + + " calculated holidays"); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testGermanyEurex() { - List expectedHol = new List(); - - expectedHol.Add(new Date(1,Month.January,2003)); - expectedHol.Add(new Date(18,Month.April,2003)); - expectedHol.Add(new Date(21,Month.April,2003)); - expectedHol.Add(new Date(1,Month.May,2003)); - expectedHol.Add(new Date(24,Month.December,2003)); - expectedHol.Add(new Date(25,Month.December,2003)); - expectedHol.Add(new Date(26,Month.December,2003)); - expectedHol.Add(new Date(31,Month.December,2003)); - - expectedHol.Add(new Date(1,Month.January,2004)); - expectedHol.Add(new Date(9,Month.April,2004)); - expectedHol.Add(new Date(12,Month.April,2004)); - expectedHol.Add(new Date(24,Month.December,2004)); - expectedHol.Add(new Date(31,Month.December,2004)); - - Calendar c = new Germany(Germany.Market.Eurex); - List hol = Calendar.holidayList(c, new Date(1,Month.January,2003), - new Date(31,Month.December,2004)); - for (int i=0; i expectedHol = new List(); + + expectedHol.Add(new Date(1, Month.January, 2003)); + expectedHol.Add(new Date(18, Month.April, 2003)); + expectedHol.Add(new Date(21, Month.April, 2003)); + expectedHol.Add(new Date(1, Month.May, 2003)); + expectedHol.Add(new Date(24, Month.December, 2003)); + expectedHol.Add(new Date(25, Month.December, 2003)); + expectedHol.Add(new Date(26, Month.December, 2003)); + expectedHol.Add(new Date(31, Month.December, 2003)); + + expectedHol.Add(new Date(1, Month.January, 2004)); + expectedHol.Add(new Date(9, Month.April, 2004)); + expectedHol.Add(new Date(12, Month.April, 2004)); + expectedHol.Add(new Date(24, Month.December, 2004)); + expectedHol.Add(new Date(31, Month.December, 2004)); + + Calendar c = new Germany(Germany.Market.Eurex); + List hol = Calendar.holidayList(c, new Date(1, Month.January, 2003), + new Date(31, Month.December, 2004)); + for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) + { + if (hol[i] != expectedHol[i]) + QAssert.Fail("expected holiday was " + expectedHol[i] + + " while calculated holiday is " + hol[i]); + } + if (hol.Count != expectedHol.Count) + QAssert.Fail("there were " + expectedHol.Count + + " expected holidays, while there are " + hol.Count + + " calculated holidays"); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testGermanyXetra() { - List expectedHol = new List(); - - expectedHol.Add(new Date(1,Month.January,2003)); - expectedHol.Add(new Date(18,Month.April,2003)); - expectedHol.Add(new Date(21,Month.April,2003)); - expectedHol.Add(new Date(1,Month.May,2003)); - expectedHol.Add(new Date(24,Month.December,2003)); - expectedHol.Add(new Date(25,Month.December,2003)); - expectedHol.Add(new Date(26,Month.December,2003)); - expectedHol.Add(new Date(31,Month.December,2003)); - - expectedHol.Add(new Date(1,Month.January,2004)); - expectedHol.Add(new Date(9,Month.April,2004)); - expectedHol.Add(new Date(12,Month.April,2004)); - expectedHol.Add(new Date(24,Month.December,2004)); - expectedHol.Add(new Date(31,Month.December,2004)); - - Calendar c = new Germany(Germany.Market.Xetra); - List hol = Calendar.holidayList(c, new Date(1,Month.January,2003), new Date(31,Month.December,2004)); - for (int i=0; i expectedHol = new List(); + + expectedHol.Add(new Date(1, Month.January, 2003)); + expectedHol.Add(new Date(18, Month.April, 2003)); + expectedHol.Add(new Date(21, Month.April, 2003)); + expectedHol.Add(new Date(1, Month.May, 2003)); + expectedHol.Add(new Date(24, Month.December, 2003)); + expectedHol.Add(new Date(25, Month.December, 2003)); + expectedHol.Add(new Date(26, Month.December, 2003)); + expectedHol.Add(new Date(31, Month.December, 2003)); + + expectedHol.Add(new Date(1, Month.January, 2004)); + expectedHol.Add(new Date(9, Month.April, 2004)); + expectedHol.Add(new Date(12, Month.April, 2004)); + expectedHol.Add(new Date(24, Month.December, 2004)); + expectedHol.Add(new Date(31, Month.December, 2004)); + + Calendar c = new Germany(Germany.Market.Xetra); + List hol = Calendar.holidayList(c, new Date(1, Month.January, 2003), new Date(31, Month.December, 2004)); + for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) + { + if (hol[i] != expectedHol[i]) + QAssert.Fail("expected holiday was " + expectedHol[i] + " while calculated holiday is " + hol[i]); + } + if (hol.Count != expectedHol.Count) + QAssert.Fail("there were " + expectedHol.Count + + " expected holidays, while there are " + hol.Count + + " calculated holidays"); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testUKSettlement() { - //BOOST_MESSAGE("Testing UK settlement holiday list..."); - - List expectedHol = new List(); - - expectedHol.Add(new Date(1,Month.January,2004)); - expectedHol.Add(new Date(9,Month.April,2004)); - expectedHol.Add(new Date(12,Month.April,2004)); - expectedHol.Add(new Date(3,Month.May,2004)); - expectedHol.Add(new Date(31,Month.May,2004)); - expectedHol.Add(new Date(30,Month.August,2004)); - expectedHol.Add(new Date(27,Month.December,2004)); - expectedHol.Add(new Date(28,Month.December,2004)); - - expectedHol.Add(new Date(3,Month.January,2005)); - expectedHol.Add(new Date(25,Month.March,2005)); - expectedHol.Add(new Date(28,Month.March,2005)); - expectedHol.Add(new Date(2,Month.May,2005)); - expectedHol.Add(new Date(30,Month.May,2005)); - expectedHol.Add(new Date(29,Month.August,2005)); - expectedHol.Add(new Date(26,Month.December,2005)); - expectedHol.Add(new Date(27,Month.December,2005)); - - expectedHol.Add(new Date(2,Month.January,2006)); - expectedHol.Add(new Date(14,Month.April,2006)); - expectedHol.Add(new Date(17,Month.April,2006)); - expectedHol.Add(new Date(1,Month.May,2006)); - expectedHol.Add(new Date(29,Month.May,2006)); - expectedHol.Add(new Date(28,Month.August,2006)); - expectedHol.Add(new Date(25,Month.December,2006)); - expectedHol.Add(new Date(26,Month.December,2006)); - - expectedHol.Add(new Date(1,Month.January,2007)); - expectedHol.Add(new Date(6,Month.April,2007)); - expectedHol.Add(new Date(9,Month.April,2007)); - expectedHol.Add(new Date(7,Month.May,2007)); - expectedHol.Add(new Date(28,Month.May,2007)); - expectedHol.Add(new Date(27,Month.August,2007)); - expectedHol.Add(new Date(25,Month.December,2007)); - expectedHol.Add(new Date(26,Month.December,2007)); - - Calendar c = new UnitedKingdom(UnitedKingdom.Market.Settlement); - List hol = Calendar.holidayList(c, new Date(1,Month.January,2004), new Date(31,Month.December,2007)); - for (int i=0; i expectedHol = new List(); + + expectedHol.Add(new Date(1, Month.January, 2004)); + expectedHol.Add(new Date(9, Month.April, 2004)); + expectedHol.Add(new Date(12, Month.April, 2004)); + expectedHol.Add(new Date(3, Month.May, 2004)); + expectedHol.Add(new Date(31, Month.May, 2004)); + expectedHol.Add(new Date(30, Month.August, 2004)); + expectedHol.Add(new Date(27, Month.December, 2004)); + expectedHol.Add(new Date(28, Month.December, 2004)); + + expectedHol.Add(new Date(3, Month.January, 2005)); + expectedHol.Add(new Date(25, Month.March, 2005)); + expectedHol.Add(new Date(28, Month.March, 2005)); + expectedHol.Add(new Date(2, Month.May, 2005)); + expectedHol.Add(new Date(30, Month.May, 2005)); + expectedHol.Add(new Date(29, Month.August, 2005)); + expectedHol.Add(new Date(26, Month.December, 2005)); + expectedHol.Add(new Date(27, Month.December, 2005)); + + expectedHol.Add(new Date(2, Month.January, 2006)); + expectedHol.Add(new Date(14, Month.April, 2006)); + expectedHol.Add(new Date(17, Month.April, 2006)); + expectedHol.Add(new Date(1, Month.May, 2006)); + expectedHol.Add(new Date(29, Month.May, 2006)); + expectedHol.Add(new Date(28, Month.August, 2006)); + expectedHol.Add(new Date(25, Month.December, 2006)); + expectedHol.Add(new Date(26, Month.December, 2006)); + + expectedHol.Add(new Date(1, Month.January, 2007)); + expectedHol.Add(new Date(6, Month.April, 2007)); + expectedHol.Add(new Date(9, Month.April, 2007)); + expectedHol.Add(new Date(7, Month.May, 2007)); + expectedHol.Add(new Date(28, Month.May, 2007)); + expectedHol.Add(new Date(27, Month.August, 2007)); + expectedHol.Add(new Date(25, Month.December, 2007)); + expectedHol.Add(new Date(26, Month.December, 2007)); + + Calendar c = new UnitedKingdom(UnitedKingdom.Market.Settlement); + List hol = Calendar.holidayList(c, new Date(1, Month.January, 2004), new Date(31, Month.December, 2007)); + for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) + { + if (hol[i] != expectedHol[i]) + QAssert.Fail("expected holiday was " + expectedHol[i] + + " while calculated holiday is " + hol[i]); + } + if (hol.Count != expectedHol.Count) + QAssert.Fail("there were " + expectedHol.Count + + " expected holidays, while there are " + hol.Count + + " calculated holidays"); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testUKExchange() { - //BOOST_MESSAGE("Testing London Stock Exchange holiday list..."); - - List expectedHol = new List(); - - expectedHol.Add(new Date(1,Month.January,2004)); - expectedHol.Add(new Date(9,Month.April,2004)); - expectedHol.Add(new Date(12,Month.April,2004)); - expectedHol.Add(new Date(3,Month.May,2004)); - expectedHol.Add(new Date(31,Month.May,2004)); - expectedHol.Add(new Date(30,Month.August,2004)); - expectedHol.Add(new Date(27,Month.December,2004)); - expectedHol.Add(new Date(28,Month.December,2004)); - - expectedHol.Add(new Date(3,Month.January,2005)); - expectedHol.Add(new Date(25,Month.March,2005)); - expectedHol.Add(new Date(28,Month.March,2005)); - expectedHol.Add(new Date(2,Month.May,2005)); - expectedHol.Add(new Date(30,Month.May,2005)); - expectedHol.Add(new Date(29,Month.August,2005)); - expectedHol.Add(new Date(26,Month.December,2005)); - expectedHol.Add(new Date(27,Month.December,2005)); - - expectedHol.Add(new Date(2,Month.January,2006)); - expectedHol.Add(new Date(14,Month.April,2006)); - expectedHol.Add(new Date(17,Month.April,2006)); - expectedHol.Add(new Date(1,Month.May,2006)); - expectedHol.Add(new Date(29,Month.May,2006)); - expectedHol.Add(new Date(28,Month.August,2006)); - expectedHol.Add(new Date(25,Month.December,2006)); - expectedHol.Add(new Date(26,Month.December,2006)); - - expectedHol.Add(new Date(1,Month.January,2007)); - expectedHol.Add(new Date(6,Month.April,2007)); - expectedHol.Add(new Date(9,Month.April,2007)); - expectedHol.Add(new Date(7,Month.May,2007)); - expectedHol.Add(new Date(28,Month.May,2007)); - expectedHol.Add(new Date(27,Month.August,2007)); - expectedHol.Add(new Date(25,Month.December,2007)); - expectedHol.Add(new Date(26,Month.December,2007)); - - Calendar c = new UnitedKingdom(UnitedKingdom.Market.Exchange); - List hol = Calendar.holidayList(c, new Date(1,Month.January,2004), new Date(31,Month.December,2007)); - for (int i=0; i expectedHol = new List(); + + expectedHol.Add(new Date(1, Month.January, 2004)); + expectedHol.Add(new Date(9, Month.April, 2004)); + expectedHol.Add(new Date(12, Month.April, 2004)); + expectedHol.Add(new Date(3, Month.May, 2004)); + expectedHol.Add(new Date(31, Month.May, 2004)); + expectedHol.Add(new Date(30, Month.August, 2004)); + expectedHol.Add(new Date(27, Month.December, 2004)); + expectedHol.Add(new Date(28, Month.December, 2004)); + + expectedHol.Add(new Date(3, Month.January, 2005)); + expectedHol.Add(new Date(25, Month.March, 2005)); + expectedHol.Add(new Date(28, Month.March, 2005)); + expectedHol.Add(new Date(2, Month.May, 2005)); + expectedHol.Add(new Date(30, Month.May, 2005)); + expectedHol.Add(new Date(29, Month.August, 2005)); + expectedHol.Add(new Date(26, Month.December, 2005)); + expectedHol.Add(new Date(27, Month.December, 2005)); + + expectedHol.Add(new Date(2, Month.January, 2006)); + expectedHol.Add(new Date(14, Month.April, 2006)); + expectedHol.Add(new Date(17, Month.April, 2006)); + expectedHol.Add(new Date(1, Month.May, 2006)); + expectedHol.Add(new Date(29, Month.May, 2006)); + expectedHol.Add(new Date(28, Month.August, 2006)); + expectedHol.Add(new Date(25, Month.December, 2006)); + expectedHol.Add(new Date(26, Month.December, 2006)); + + expectedHol.Add(new Date(1, Month.January, 2007)); + expectedHol.Add(new Date(6, Month.April, 2007)); + expectedHol.Add(new Date(9, Month.April, 2007)); + expectedHol.Add(new Date(7, Month.May, 2007)); + expectedHol.Add(new Date(28, Month.May, 2007)); + expectedHol.Add(new Date(27, Month.August, 2007)); + expectedHol.Add(new Date(25, Month.December, 2007)); + expectedHol.Add(new Date(26, Month.December, 2007)); + + Calendar c = new UnitedKingdom(UnitedKingdom.Market.Exchange); + List hol = Calendar.holidayList(c, new Date(1, Month.January, 2004), new Date(31, Month.December, 2007)); + for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) + { + if (hol[i] != expectedHol[i]) + QAssert.Fail("expected holiday was " + expectedHol[i] + + " while calculated holiday is " + hol[i]); + } + if (hol.Count != expectedHol.Count) + QAssert.Fail("there were " + expectedHol.Count + + " expected holidays, while there are " + hol.Count + + " calculated holidays"); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testUKMetals() { - //BOOST_MESSAGE("Testing London Metals Exchange holiday list..."); - - List expectedHol = new List(); - - expectedHol.Add(new Date(1,Month.January,2004)); - expectedHol.Add(new Date(9,Month.April,2004)); - expectedHol.Add(new Date(12,Month.April,2004)); - expectedHol.Add(new Date(3,Month.May,2004)); - expectedHol.Add(new Date(31,Month.May,2004)); - expectedHol.Add(new Date(30,Month.August,2004)); - expectedHol.Add(new Date(27,Month.December,2004)); - expectedHol.Add(new Date(28,Month.December,2004)); - - expectedHol.Add(new Date(3,Month.January,2005)); - expectedHol.Add(new Date(25,Month.March,2005)); - expectedHol.Add(new Date(28,Month.March,2005)); - expectedHol.Add(new Date(2,Month.May,2005)); - expectedHol.Add(new Date(30,Month.May,2005)); - expectedHol.Add(new Date(29,Month.August,2005)); - expectedHol.Add(new Date(26,Month.December,2005)); - expectedHol.Add(new Date(27,Month.December,2005)); - - expectedHol.Add(new Date(2,Month.January,2006)); - expectedHol.Add(new Date(14,Month.April,2006)); - expectedHol.Add(new Date(17,Month.April,2006)); - expectedHol.Add(new Date(1,Month.May,2006)); - expectedHol.Add(new Date(29,Month.May,2006)); - expectedHol.Add(new Date(28,Month.August,2006)); - expectedHol.Add(new Date(25,Month.December,2006)); - expectedHol.Add(new Date(26,Month.December,2006)); - - expectedHol.Add(new Date(1,Month.January,2007)); - expectedHol.Add(new Date(6,Month.April,2007)); - expectedHol.Add(new Date(9,Month.April,2007)); - expectedHol.Add(new Date(7,Month.May,2007)); - expectedHol.Add(new Date(28,Month.May,2007)); - expectedHol.Add(new Date(27,Month.August,2007)); - expectedHol.Add(new Date(25,Month.December,2007)); - expectedHol.Add(new Date(26,Month.December,2007)); - - Calendar c = new UnitedKingdom(UnitedKingdom.Market.Metals); - List hol = Calendar.holidayList(c, new Date(1,Month.January,2004), new Date(31,Month.December,2007)); - for (int i=0; i expectedHol = new List(); + + expectedHol.Add(new Date(1, Month.January, 2004)); + expectedHol.Add(new Date(9, Month.April, 2004)); + expectedHol.Add(new Date(12, Month.April, 2004)); + expectedHol.Add(new Date(3, Month.May, 2004)); + expectedHol.Add(new Date(31, Month.May, 2004)); + expectedHol.Add(new Date(30, Month.August, 2004)); + expectedHol.Add(new Date(27, Month.December, 2004)); + expectedHol.Add(new Date(28, Month.December, 2004)); + + expectedHol.Add(new Date(3, Month.January, 2005)); + expectedHol.Add(new Date(25, Month.March, 2005)); + expectedHol.Add(new Date(28, Month.March, 2005)); + expectedHol.Add(new Date(2, Month.May, 2005)); + expectedHol.Add(new Date(30, Month.May, 2005)); + expectedHol.Add(new Date(29, Month.August, 2005)); + expectedHol.Add(new Date(26, Month.December, 2005)); + expectedHol.Add(new Date(27, Month.December, 2005)); + + expectedHol.Add(new Date(2, Month.January, 2006)); + expectedHol.Add(new Date(14, Month.April, 2006)); + expectedHol.Add(new Date(17, Month.April, 2006)); + expectedHol.Add(new Date(1, Month.May, 2006)); + expectedHol.Add(new Date(29, Month.May, 2006)); + expectedHol.Add(new Date(28, Month.August, 2006)); + expectedHol.Add(new Date(25, Month.December, 2006)); + expectedHol.Add(new Date(26, Month.December, 2006)); + + expectedHol.Add(new Date(1, Month.January, 2007)); + expectedHol.Add(new Date(6, Month.April, 2007)); + expectedHol.Add(new Date(9, Month.April, 2007)); + expectedHol.Add(new Date(7, Month.May, 2007)); + expectedHol.Add(new Date(28, Month.May, 2007)); + expectedHol.Add(new Date(27, Month.August, 2007)); + expectedHol.Add(new Date(25, Month.December, 2007)); + expectedHol.Add(new Date(26, Month.December, 2007)); + + Calendar c = new UnitedKingdom(UnitedKingdom.Market.Metals); + List hol = Calendar.holidayList(c, new Date(1, Month.January, 2004), new Date(31, Month.December, 2007)); + for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) + { + if (hol[i] != expectedHol[i]) + QAssert.Fail("expected holiday was " + expectedHol[i] + + " while calculated holiday is " + hol[i]); + } + if (hol.Count != expectedHol.Count) + QAssert.Fail("there were " + expectedHol.Count + + " expected holidays, while there are " + hol.Count + + " calculated holidays"); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testItalyExchange() { - //BOOST_MESSAGE("Testing Milan Stock Exchange holiday list..."); - - List expectedHol = new List(); - - expectedHol.Add(new Date(1,Month.January,2002)); - expectedHol.Add(new Date(29,Month.March,2002)); - expectedHol.Add(new Date(1,Month.April,2002)); - expectedHol.Add(new Date(1,Month.May,2002)); - expectedHol.Add(new Date(15,Month.August,2002)); - expectedHol.Add(new Date(24,Month.December,2002)); - expectedHol.Add(new Date(25,Month.December,2002)); - expectedHol.Add(new Date(26,Month.December,2002)); - expectedHol.Add(new Date(31,Month.December,2002)); - - expectedHol.Add(new Date(1,Month.January,2003)); - expectedHol.Add(new Date(18,Month.April,2003)); - expectedHol.Add(new Date(21,Month.April,2003)); - expectedHol.Add(new Date(1,Month.May,2003)); - expectedHol.Add(new Date(15,Month.August,2003)); - expectedHol.Add(new Date(24,Month.December,2003)); - expectedHol.Add(new Date(25,Month.December,2003)); - expectedHol.Add(new Date(26,Month.December,2003)); - expectedHol.Add(new Date(31,Month.December,2003)); - - expectedHol.Add(new Date(1,Month.January,2004)); - expectedHol.Add(new Date(9,Month.April,2004)); - expectedHol.Add(new Date(12,Month.April,2004)); - expectedHol.Add(new Date(24,Month.December,2004)); - expectedHol.Add(new Date(31,Month.December,2004)); - - Calendar c = new Italy(Italy.Market.Exchange); - List hol = Calendar.holidayList(c, new Date(1,Month.January,2002), new Date(31,Month.December,2004)); - for (int i=0; i expectedHol = new List(); + + expectedHol.Add(new Date(1, Month.January, 2002)); + expectedHol.Add(new Date(29, Month.March, 2002)); + expectedHol.Add(new Date(1, Month.April, 2002)); + expectedHol.Add(new Date(1, Month.May, 2002)); + expectedHol.Add(new Date(15, Month.August, 2002)); + expectedHol.Add(new Date(24, Month.December, 2002)); + expectedHol.Add(new Date(25, Month.December, 2002)); + expectedHol.Add(new Date(26, Month.December, 2002)); + expectedHol.Add(new Date(31, Month.December, 2002)); + + expectedHol.Add(new Date(1, Month.January, 2003)); + expectedHol.Add(new Date(18, Month.April, 2003)); + expectedHol.Add(new Date(21, Month.April, 2003)); + expectedHol.Add(new Date(1, Month.May, 2003)); + expectedHol.Add(new Date(15, Month.August, 2003)); + expectedHol.Add(new Date(24, Month.December, 2003)); + expectedHol.Add(new Date(25, Month.December, 2003)); + expectedHol.Add(new Date(26, Month.December, 2003)); + expectedHol.Add(new Date(31, Month.December, 2003)); + + expectedHol.Add(new Date(1, Month.January, 2004)); + expectedHol.Add(new Date(9, Month.April, 2004)); + expectedHol.Add(new Date(12, Month.April, 2004)); + expectedHol.Add(new Date(24, Month.December, 2004)); + expectedHol.Add(new Date(31, Month.December, 2004)); + + Calendar c = new Italy(Italy.Market.Exchange); + List hol = Calendar.holidayList(c, new Date(1, Month.January, 2002), new Date(31, Month.December, 2004)); + for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) + { + if (hol[i] != expectedHol[i]) + QAssert.Fail("expected holiday was " + expectedHol[i] + + " while calculated holiday is " + hol[i]); + } + if (hol.Count != expectedHol.Count) + QAssert.Fail("there were " + expectedHol.Count + + " expected holidays, while there are " + hol.Count + + " calculated holidays"); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testBrazil() { - //BOOST_MESSAGE("Testing Brazil holiday list..."); - - List expectedHol = new List(); - - //expectedHol.Add(new Date(1,January,2005)); // Saturday - expectedHol.Add(new Date(7,Month.February,2005)); - expectedHol.Add(new Date(8,Month.February,2005)); - expectedHol.Add(new Date(25,Month.March,2005)); - expectedHol.Add(new Date(21,Month.April,2005)); - //expectedHol.Add(new Date(1,May,2005)); // Sunday - expectedHol.Add(new Date(26,Month.May,2005)); - expectedHol.Add(new Date(7,Month.September,2005)); - expectedHol.Add(new Date(12,Month.October,2005)); - expectedHol.Add(new Date(2,Month.November,2005)); - expectedHol.Add(new Date(15,Month.November,2005)); - //expectedHol.Add(new Date(25,December,2005)); // Sunday - - //expectedHol.Add(new Date(1,January,2006)); // Sunday - expectedHol.Add(new Date(27,Month.February,2006)); - expectedHol.Add(new Date(28,Month.February,2006)); - expectedHol.Add(new Date(14,Month.April,2006)); - expectedHol.Add(new Date(21,Month.April,2006)); - expectedHol.Add(new Date(1,Month.May,2006)); - expectedHol.Add(new Date(15,Month.June,2006)); - expectedHol.Add(new Date(7,Month.September,2006)); - expectedHol.Add(new Date(12,Month.October,2006)); - expectedHol.Add(new Date(2,Month.November,2006)); - expectedHol.Add(new Date(15,Month.November,2006)); - expectedHol.Add(new Date(25,Month.December,2006)); - - Calendar c = new Brazil(); - List hol = Calendar.holidayList(c, new Date(1,Month.January,2005), new Date(31,Month.December,2006)); - for (int i=0; i expectedHol = new List(); + + //expectedHol.Add(new Date(1,January,2005)); // Saturday + expectedHol.Add(new Date(7, Month.February, 2005)); + expectedHol.Add(new Date(8, Month.February, 2005)); + expectedHol.Add(new Date(25, Month.March, 2005)); + expectedHol.Add(new Date(21, Month.April, 2005)); + //expectedHol.Add(new Date(1,May,2005)); // Sunday + expectedHol.Add(new Date(26, Month.May, 2005)); + expectedHol.Add(new Date(7, Month.September, 2005)); + expectedHol.Add(new Date(12, Month.October, 2005)); + expectedHol.Add(new Date(2, Month.November, 2005)); + expectedHol.Add(new Date(15, Month.November, 2005)); + //expectedHol.Add(new Date(25,December,2005)); // Sunday + + //expectedHol.Add(new Date(1,January,2006)); // Sunday + expectedHol.Add(new Date(27, Month.February, 2006)); + expectedHol.Add(new Date(28, Month.February, 2006)); + expectedHol.Add(new Date(14, Month.April, 2006)); + expectedHol.Add(new Date(21, Month.April, 2006)); + expectedHol.Add(new Date(1, Month.May, 2006)); + expectedHol.Add(new Date(15, Month.June, 2006)); + expectedHol.Add(new Date(7, Month.September, 2006)); + expectedHol.Add(new Date(12, Month.October, 2006)); + expectedHol.Add(new Date(2, Month.November, 2006)); + expectedHol.Add(new Date(15, Month.November, 2006)); + expectedHol.Add(new Date(25, Month.December, 2006)); + + Calendar c = new Brazil(); + List hol = Calendar.holidayList(c, new Date(1, Month.January, 2005), new Date(31, Month.December, 2006)); + for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) + { + if (hol[i] != expectedHol[i]) + QAssert.Fail("expected holiday was " + expectedHol[i] + + " while calculated holiday is " + hol[i]); + } + if (hol.Count != expectedHol.Count) + QAssert.Fail("there were " + expectedHol.Count + + " expected holidays, while there are " + hol.Count + + " calculated holidays"); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testSouthKoreanSettlement() { - //("Testing South-Korean settlement holiday list..."); - - List expectedHol = new List(); - expectedHol.Add(new Date(1, Month.January, 2004)); - expectedHol.Add(new Date(21, Month.January, 2004)); - expectedHol.Add(new Date(22, Month.January, 2004)); - expectedHol.Add(new Date(23, Month.January, 2004)); - expectedHol.Add(new Date(1, Month.March, 2004)); - expectedHol.Add(new Date(5, Month.April, 2004)); - expectedHol.Add(new Date(15, Month.April, 2004)); // election day - // expectedHol.Add(new Date(1, Month.May,2004)); // Saturday - expectedHol.Add(new Date(5, Month.May, 2004)); - expectedHol.Add(new Date(26, Month.May, 2004)); - // expectedHol.Add(new Date(6, Month.June,2004)); // Sunday - // expectedHol.Add(new Date(17, Month.July,2004)); // Saturday - // expectedHol.Add(new Date(15, Month.August,2004)); // Sunday - expectedHol.Add(new Date(27, Month.September, 2004)); - expectedHol.Add(new Date(28, Month.September, 2004)); - expectedHol.Add(new Date(29, Month.September, 2004)); - // expectedHol.Add(new Date(3, Month.October,2004)); // Sunday - // expectedHol.Add(new Date(25,December,2004)); // Saturday - - // expectedHol.Add(new Date(1, Month.January,2005)); // Saturday - expectedHol.Add(new Date(8, Month.February, 2005)); - expectedHol.Add(new Date(9, Month.February, 2005)); - expectedHol.Add(new Date(10, Month.February, 2005)); - expectedHol.Add(new Date(1, Month.March, 2005)); - expectedHol.Add(new Date(5, Month.April, 2005)); - expectedHol.Add(new Date(5, Month.May, 2005)); - // expectedHol.Add(new Date(15, Month.May,2005)); // Sunday - expectedHol.Add(new Date(6, Month.June, 2005)); - // expectedHol.Add(new Date(17, Month.July,2005)); // Sunday - expectedHol.Add(new Date(15, Month.August, 2005)); - // expectedHol.Add(new Date(17, Month.September,2005)); // Saturday - // expectedHol.Add(new Date(18, Month.September,2005)); // Sunday - expectedHol.Add(new Date(19, Month.September, 2005)); - expectedHol.Add(new Date(3, Month.October, 2005)); - // expectedHol.Add(new Date(25,December,2005)); // Sunday - - // expectedHol.Add(new Date(1, Month.January,2006)); // Sunday - // expectedHol.Add(new Date(28, Month.January,2006)); // Saturday - // expectedHol.Add(new Date(29, Month.January,2006)); // Sunday - expectedHol.Add(new Date(30, Month.January, 2006)); - expectedHol.Add(new Date(1, Month.March, 2006)); - expectedHol.Add(new Date(1, Month.May, 2006)); - expectedHol.Add(new Date(5, Month.May, 2006)); - expectedHol.Add(new Date(31, Month.May, 2006)); // election - expectedHol.Add(new Date(6, Month.June, 2006)); - expectedHol.Add(new Date(17, Month.July, 2006)); - expectedHol.Add(new Date(15, Month.August, 2006)); - expectedHol.Add(new Date(3, Month.October, 2006)); - expectedHol.Add(new Date(5, Month.October, 2006)); - expectedHol.Add(new Date(6, Month.October, 2006)); - // expectedHol.Add(new Date(7, Month.October,2006)); // Saturday - expectedHol.Add(new Date(25, Month.December, 2006)); - - expectedHol.Add(new Date(1, Month.January, 2007)); - // expectedHol.Add(new Date(17, Month.February,2007)); // Saturday - // expectedHol.Add(new Date(18, Month.February,2007)); // Sunday - expectedHol.Add(new Date(19, Month.February, 2007)); - expectedHol.Add(new Date(1, Month.March, 2007)); - expectedHol.Add(new Date(1, Month.May, 2007)); - // expectedHol.Add(new Date(5, Month.May,2007)); // Saturday - expectedHol.Add(new Date(24, Month.May, 2007)); - expectedHol.Add(new Date(6, Month.June, 2007)); - expectedHol.Add(new Date(17, Month.July, 2007)); - expectedHol.Add(new Date(15, Month.August, 2007)); - expectedHol.Add(new Date(24, Month.September, 2007)); - expectedHol.Add(new Date(25, Month.September, 2007)); - expectedHol.Add(new Date(26, Month.September, 2007)); - expectedHol.Add(new Date(3, Month.October, 2007)); - expectedHol.Add(new Date(19, Month.December, 2007)); // election - expectedHol.Add(new Date(25, Month.December, 2007)); - - Calendar c = new SouthKorea(SouthKorea.Market.Settlement); - List hol = Calendar.holidayList(c, new Date(1, Month.January, 2004), - new Date(31, Month.December, 2007)); - for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) { - if (hol[i] != expectedHol[i]) - QAssert.Fail("expected holiday was " + expectedHol[i] + " while calculated holiday is " + hol[i]); - } - if (hol.Count != expectedHol.Count) - QAssert.Fail("there were " + expectedHol.Count - + " expected holidays, while there are " + hol.Count - + " calculated holidays"); - } + public void testSouthKoreanSettlement() + { + //("Testing South-Korean settlement holiday list..."); + + List expectedHol = new List(); + expectedHol.Add(new Date(1, Month.January, 2004)); + expectedHol.Add(new Date(21, Month.January, 2004)); + expectedHol.Add(new Date(22, Month.January, 2004)); + expectedHol.Add(new Date(23, Month.January, 2004)); + expectedHol.Add(new Date(1, Month.March, 2004)); + expectedHol.Add(new Date(5, Month.April, 2004)); + expectedHol.Add(new Date(15, Month.April, 2004)); // election day + // expectedHol.Add(new Date(1, Month.May,2004)); // Saturday + expectedHol.Add(new Date(5, Month.May, 2004)); + expectedHol.Add(new Date(26, Month.May, 2004)); + // expectedHol.Add(new Date(6, Month.June,2004)); // Sunday + // expectedHol.Add(new Date(17, Month.July,2004)); // Saturday + // expectedHol.Add(new Date(15, Month.August,2004)); // Sunday + expectedHol.Add(new Date(27, Month.September, 2004)); + expectedHol.Add(new Date(28, Month.September, 2004)); + expectedHol.Add(new Date(29, Month.September, 2004)); + // expectedHol.Add(new Date(3, Month.October,2004)); // Sunday + // expectedHol.Add(new Date(25,December,2004)); // Saturday + + // expectedHol.Add(new Date(1, Month.January,2005)); // Saturday + expectedHol.Add(new Date(8, Month.February, 2005)); + expectedHol.Add(new Date(9, Month.February, 2005)); + expectedHol.Add(new Date(10, Month.February, 2005)); + expectedHol.Add(new Date(1, Month.March, 2005)); + expectedHol.Add(new Date(5, Month.April, 2005)); + expectedHol.Add(new Date(5, Month.May, 2005)); + // expectedHol.Add(new Date(15, Month.May,2005)); // Sunday + expectedHol.Add(new Date(6, Month.June, 2005)); + // expectedHol.Add(new Date(17, Month.July,2005)); // Sunday + expectedHol.Add(new Date(15, Month.August, 2005)); + // expectedHol.Add(new Date(17, Month.September,2005)); // Saturday + // expectedHol.Add(new Date(18, Month.September,2005)); // Sunday + expectedHol.Add(new Date(19, Month.September, 2005)); + expectedHol.Add(new Date(3, Month.October, 2005)); + // expectedHol.Add(new Date(25,December,2005)); // Sunday + + // expectedHol.Add(new Date(1, Month.January,2006)); // Sunday + // expectedHol.Add(new Date(28, Month.January,2006)); // Saturday + // expectedHol.Add(new Date(29, Month.January,2006)); // Sunday + expectedHol.Add(new Date(30, Month.January, 2006)); + expectedHol.Add(new Date(1, Month.March, 2006)); + expectedHol.Add(new Date(1, Month.May, 2006)); + expectedHol.Add(new Date(5, Month.May, 2006)); + expectedHol.Add(new Date(31, Month.May, 2006)); // election + expectedHol.Add(new Date(6, Month.June, 2006)); + expectedHol.Add(new Date(17, Month.July, 2006)); + expectedHol.Add(new Date(15, Month.August, 2006)); + expectedHol.Add(new Date(3, Month.October, 2006)); + expectedHol.Add(new Date(5, Month.October, 2006)); + expectedHol.Add(new Date(6, Month.October, 2006)); + // expectedHol.Add(new Date(7, Month.October,2006)); // Saturday + expectedHol.Add(new Date(25, Month.December, 2006)); + + expectedHol.Add(new Date(1, Month.January, 2007)); + // expectedHol.Add(new Date(17, Month.February,2007)); // Saturday + // expectedHol.Add(new Date(18, Month.February,2007)); // Sunday + expectedHol.Add(new Date(19, Month.February, 2007)); + expectedHol.Add(new Date(1, Month.March, 2007)); + expectedHol.Add(new Date(1, Month.May, 2007)); + // expectedHol.Add(new Date(5, Month.May,2007)); // Saturday + expectedHol.Add(new Date(24, Month.May, 2007)); + expectedHol.Add(new Date(6, Month.June, 2007)); + expectedHol.Add(new Date(17, Month.July, 2007)); + expectedHol.Add(new Date(15, Month.August, 2007)); + expectedHol.Add(new Date(24, Month.September, 2007)); + expectedHol.Add(new Date(25, Month.September, 2007)); + expectedHol.Add(new Date(26, Month.September, 2007)); + expectedHol.Add(new Date(3, Month.October, 2007)); + expectedHol.Add(new Date(19, Month.December, 2007)); // election + expectedHol.Add(new Date(25, Month.December, 2007)); + + Calendar c = new SouthKorea(SouthKorea.Market.Settlement); + List hol = Calendar.holidayList(c, new Date(1, Month.January, 2004), + new Date(31, Month.December, 2007)); + for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) + { + if (hol[i] != expectedHol[i]) + QAssert.Fail("expected holiday was " + expectedHol[i] + " while calculated holiday is " + hol[i]); + } + if (hol.Count != expectedHol.Count) + QAssert.Fail("there were " + expectedHol.Count + + " expected holidays, while there are " + hol.Count + + " calculated holidays"); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testKoreaStockExchange() { - //("Testing Korea Stock Exchange holiday list..."); - - List expectedHol = new List(); - expectedHol.Add(new Date(1, Month.January, 2004)); - expectedHol.Add(new Date(21, Month.January, 2004)); - expectedHol.Add(new Date(22, Month.January, 2004)); - expectedHol.Add(new Date(23, Month.January, 2004)); - expectedHol.Add(new Date(1, Month.March, 2004)); - expectedHol.Add(new Date(5, Month.April, 2004)); - expectedHol.Add(new Date(15, Month.April, 2004)); //election day - // expectedHol.Add(new Date(1, Month.May,2004)); // Saturday - expectedHol.Add(new Date(5, Month.May, 2004)); - expectedHol.Add(new Date(26, Month.May, 2004)); - // expectedHol.Add(new Date(6, Month.June,2004)); // Sunday - // expectedHol.Add(new Date(17, Month.July,2004)); // Saturday - // expectedHol.Add(new Date(15, Month.August,2004)); // Sunday - expectedHol.Add(new Date(27, Month.September, 2004)); - expectedHol.Add(new Date(28, Month.September, 2004)); - expectedHol.Add(new Date(29, Month.September, 2004)); - // expectedHol.Add(new Date(3, Month.October,2004)); // Sunday - // expectedHol.Add(new Date(25,December,2004)); // Saturday - expectedHol.Add(new Date(31, Month.December, 2004)); - - // expectedHol.Add(new Date(1, Month.January,2005)); // Saturday - expectedHol.Add(new Date(8, Month.February, 2005)); - expectedHol.Add(new Date(9, Month.February, 2005)); - expectedHol.Add(new Date(10, Month.February, 2005)); - expectedHol.Add(new Date(1, Month.March, 2005)); - expectedHol.Add(new Date(5, Month.April, 2005)); - expectedHol.Add(new Date(5, Month.May, 2005)); - // expectedHol.Add(new Date(15, Month.May,2005)); // Sunday - expectedHol.Add(new Date(6, Month.June, 2005)); - // expectedHol.Add(new Date(17, Month.July,2005)); // Sunday - expectedHol.Add(new Date(15, Month.August, 2005)); - // expectedHol.Add(new Date(17, Month.September,2005)); // Saturday - // expectedHol.Add(new Date(18, Month.September,2005)); // Sunday - expectedHol.Add(new Date(19, Month.September, 2005)); - expectedHol.Add(new Date(3, Month.October, 2005)); - // expectedHol.Add(new Date(25,December,2005)); // Sunday - expectedHol.Add(new Date(30, Month.December, 2005)); - - // expectedHol.Add(new Date(1, Month.January,2006)); // Sunday - // expectedHol.Add(new Date(28, Month.January,2006)); // Saturday - // expectedHol.Add(new Date(29, Month.January,2006)); // Sunday - expectedHol.Add(new Date(30, Month.January, 2006)); - expectedHol.Add(new Date(1, Month.March, 2006)); - expectedHol.Add(new Date(1, Month.May, 2006)); - expectedHol.Add(new Date(5, Month.May, 2006)); - expectedHol.Add(new Date(31, Month.May, 2006)); // election - expectedHol.Add(new Date(6, Month.June, 2006)); - expectedHol.Add(new Date(17, Month.July, 2006)); - expectedHol.Add(new Date(15, Month.August, 2006)); - expectedHol.Add(new Date(3, Month.October, 2006)); - expectedHol.Add(new Date(5, Month.October, 2006)); - expectedHol.Add(new Date(6, Month.October, 2006)); - // expectedHol.Add(new Date(7, Month.October,2006)); // Saturday - expectedHol.Add(new Date(25, Month.December, 2006)); - expectedHol.Add(new Date(29, Month.December, 2006)); - - expectedHol.Add(new Date(1, Month.January, 2007)); - // expectedHol.Add(new Date(17, Month.February,2007)); // Saturday - // expectedHol.Add(new Date(18, Month.February,2007)); // Sunday - expectedHol.Add(new Date(19, Month.February, 2007)); - expectedHol.Add(new Date(1, Month.March, 2007)); - expectedHol.Add(new Date(1, Month.May, 2007)); - // expectedHol.Add(new Date(5, Month.May,2007)); // Saturday - expectedHol.Add(new Date(24, Month.May, 2007)); - expectedHol.Add(new Date(6, Month.June, 2007)); - expectedHol.Add(new Date(17, Month.July, 2007)); - expectedHol.Add(new Date(15, Month.August, 2007)); - expectedHol.Add(new Date(24, Month.September, 2007)); - expectedHol.Add(new Date(25, Month.September, 2007)); - expectedHol.Add(new Date(26, Month.September, 2007)); - expectedHol.Add(new Date(3, Month.October, 2007)); - expectedHol.Add(new Date(19, Month.December, 2007)); // election - expectedHol.Add(new Date(25, Month.December, 2007)); - expectedHol.Add(new Date(31, Month.December, 2007)); - - Calendar c = new SouthKorea(SouthKorea.Market.KRX); - List hol = Calendar.holidayList(c, new Date(1, Month.January, 2004), - new Date(31, Month.December, 2007)); - - for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) { - if (hol[i] != expectedHol[i]) - QAssert.Fail("expected holiday was " + expectedHol[i] - + " while calculated holiday is " + hol[i]); - } - if (hol.Count != expectedHol.Count) - QAssert.Fail("there were " + expectedHol.Count - + " expected holidays, while there are " + hol.Count - + " calculated holidays"); - } + public void testKoreaStockExchange() + { + //("Testing Korea Stock Exchange holiday list..."); + + List expectedHol = new List(); + expectedHol.Add(new Date(1, Month.January, 2004)); + expectedHol.Add(new Date(21, Month.January, 2004)); + expectedHol.Add(new Date(22, Month.January, 2004)); + expectedHol.Add(new Date(23, Month.January, 2004)); + expectedHol.Add(new Date(1, Month.March, 2004)); + expectedHol.Add(new Date(5, Month.April, 2004)); + expectedHol.Add(new Date(15, Month.April, 2004)); //election day + // expectedHol.Add(new Date(1, Month.May,2004)); // Saturday + expectedHol.Add(new Date(5, Month.May, 2004)); + expectedHol.Add(new Date(26, Month.May, 2004)); + // expectedHol.Add(new Date(6, Month.June,2004)); // Sunday + // expectedHol.Add(new Date(17, Month.July,2004)); // Saturday + // expectedHol.Add(new Date(15, Month.August,2004)); // Sunday + expectedHol.Add(new Date(27, Month.September, 2004)); + expectedHol.Add(new Date(28, Month.September, 2004)); + expectedHol.Add(new Date(29, Month.September, 2004)); + // expectedHol.Add(new Date(3, Month.October,2004)); // Sunday + // expectedHol.Add(new Date(25,December,2004)); // Saturday + expectedHol.Add(new Date(31, Month.December, 2004)); + + // expectedHol.Add(new Date(1, Month.January,2005)); // Saturday + expectedHol.Add(new Date(8, Month.February, 2005)); + expectedHol.Add(new Date(9, Month.February, 2005)); + expectedHol.Add(new Date(10, Month.February, 2005)); + expectedHol.Add(new Date(1, Month.March, 2005)); + expectedHol.Add(new Date(5, Month.April, 2005)); + expectedHol.Add(new Date(5, Month.May, 2005)); + // expectedHol.Add(new Date(15, Month.May,2005)); // Sunday + expectedHol.Add(new Date(6, Month.June, 2005)); + // expectedHol.Add(new Date(17, Month.July,2005)); // Sunday + expectedHol.Add(new Date(15, Month.August, 2005)); + // expectedHol.Add(new Date(17, Month.September,2005)); // Saturday + // expectedHol.Add(new Date(18, Month.September,2005)); // Sunday + expectedHol.Add(new Date(19, Month.September, 2005)); + expectedHol.Add(new Date(3, Month.October, 2005)); + // expectedHol.Add(new Date(25,December,2005)); // Sunday + expectedHol.Add(new Date(30, Month.December, 2005)); + + // expectedHol.Add(new Date(1, Month.January,2006)); // Sunday + // expectedHol.Add(new Date(28, Month.January,2006)); // Saturday + // expectedHol.Add(new Date(29, Month.January,2006)); // Sunday + expectedHol.Add(new Date(30, Month.January, 2006)); + expectedHol.Add(new Date(1, Month.March, 2006)); + expectedHol.Add(new Date(1, Month.May, 2006)); + expectedHol.Add(new Date(5, Month.May, 2006)); + expectedHol.Add(new Date(31, Month.May, 2006)); // election + expectedHol.Add(new Date(6, Month.June, 2006)); + expectedHol.Add(new Date(17, Month.July, 2006)); + expectedHol.Add(new Date(15, Month.August, 2006)); + expectedHol.Add(new Date(3, Month.October, 2006)); + expectedHol.Add(new Date(5, Month.October, 2006)); + expectedHol.Add(new Date(6, Month.October, 2006)); + // expectedHol.Add(new Date(7, Month.October,2006)); // Saturday + expectedHol.Add(new Date(25, Month.December, 2006)); + expectedHol.Add(new Date(29, Month.December, 2006)); + + expectedHol.Add(new Date(1, Month.January, 2007)); + // expectedHol.Add(new Date(17, Month.February,2007)); // Saturday + // expectedHol.Add(new Date(18, Month.February,2007)); // Sunday + expectedHol.Add(new Date(19, Month.February, 2007)); + expectedHol.Add(new Date(1, Month.March, 2007)); + expectedHol.Add(new Date(1, Month.May, 2007)); + // expectedHol.Add(new Date(5, Month.May,2007)); // Saturday + expectedHol.Add(new Date(24, Month.May, 2007)); + expectedHol.Add(new Date(6, Month.June, 2007)); + expectedHol.Add(new Date(17, Month.July, 2007)); + expectedHol.Add(new Date(15, Month.August, 2007)); + expectedHol.Add(new Date(24, Month.September, 2007)); + expectedHol.Add(new Date(25, Month.September, 2007)); + expectedHol.Add(new Date(26, Month.September, 2007)); + expectedHol.Add(new Date(3, Month.October, 2007)); + expectedHol.Add(new Date(19, Month.December, 2007)); // election + expectedHol.Add(new Date(25, Month.December, 2007)); + expectedHol.Add(new Date(31, Month.December, 2007)); + + Calendar c = new SouthKorea(SouthKorea.Market.KRX); + List hol = Calendar.holidayList(c, new Date(1, Month.January, 2004), + new Date(31, Month.December, 2007)); + + for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) + { + if (hol[i] != expectedHol[i]) + QAssert.Fail("expected holiday was " + expectedHol[i] + + " while calculated holiday is " + hol[i]); + } + if (hol.Count != expectedHol.Count) + QAssert.Fail("there were " + expectedHol.Count + + " expected holidays, while there are " + hol.Count + + " calculated holidays"); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testChinaSSE() - { - // Testing China Shanghai Stock Exchange holiday list - - List expectedHol = new List(); - - // China Shanghai Securities Exchange holiday list in the year 2014 - expectedHol.Add(new Date(1, Month.Jan, 2014)); - expectedHol.Add(new Date(31, Month.Jan, 2014)); - expectedHol.Add(new Date(3, Month.Feb, 2014)); - expectedHol.Add(new Date(4, Month.Feb, 2014)); - expectedHol.Add(new Date(5, Month.Feb, 2014)); - expectedHol.Add(new Date(6, Month.Feb, 2014)); - expectedHol.Add(new Date(7, Month.Apr, 2014)); - expectedHol.Add(new Date(1, Month.May, 2014)); - expectedHol.Add(new Date(2, Month.May, 2014)); - expectedHol.Add(new Date(2, Month.Jun, 2014)); - expectedHol.Add(new Date(8, Month.Sep, 2014)); - expectedHol.Add(new Date(1, Month.Oct, 2014)); - expectedHol.Add(new Date(2, Month.Oct, 2014)); - expectedHol.Add(new Date(3, Month.Oct, 2014)); - expectedHol.Add(new Date(6, Month.Oct, 2014)); - expectedHol.Add(new Date(7, Month.Oct, 2014)); - - // China Shanghai Securities Exchange holiday list in the year 2015 - expectedHol.Add(new Date(1, Month.Jan, 2015)); - expectedHol.Add(new Date(2, Month.Jan, 2015)); - expectedHol.Add(new Date(18,Month.Feb, 2015)); - expectedHol.Add(new Date(19,Month.Feb, 2015)); - expectedHol.Add(new Date(20,Month.Feb, 2015)); - expectedHol.Add(new Date(23,Month.Feb, 2015)); - expectedHol.Add(new Date(24,Month.Feb, 2015)); - expectedHol.Add(new Date(6, Month.Apr, 2015)); - expectedHol.Add(new Date(1, Month.May, 2015)); - expectedHol.Add(new Date(22,Month.Jun, 2015)); - expectedHol.Add(new Date(3, Month.Sep, 2015)); - expectedHol.Add(new Date(4, Month.Sep, 2015)); - expectedHol.Add(new Date(1, Month.Oct, 2015)); - expectedHol.Add(new Date(2, Month.Oct, 2015)); - expectedHol.Add(new Date(5, Month.Oct, 2015)); - expectedHol.Add(new Date(6, Month.Oct, 2015)); - expectedHol.Add(new Date(7, Month.Oct, 2015)); - - // China Shanghai Securities Exchange holiday list in the year 2016 - expectedHol.Add(new Date(1, Month.Jan, 2016)); - expectedHol.Add(new Date(8, Month.Feb, 2016)); - expectedHol.Add(new Date(9, Month.Feb, 2016)); - expectedHol.Add(new Date(10,Month.Feb, 2016)); - expectedHol.Add(new Date(11,Month.Feb, 2016)); - expectedHol.Add(new Date(12,Month.Feb, 2016)); - expectedHol.Add(new Date(4, Month.Apr, 2016)); - expectedHol.Add(new Date(2, Month.May, 2016)); - expectedHol.Add(new Date(9, Month.Jun, 2016)); - expectedHol.Add(new Date(10,Month.Jun, 2016)); - expectedHol.Add(new Date(15,Month.Sep, 2016)); - expectedHol.Add(new Date(16,Month.Sep, 2016)); - expectedHol.Add(new Date(3, Month.Oct, 2016)); - expectedHol.Add(new Date(4, Month.Oct, 2016)); - expectedHol.Add(new Date(5, Month.Oct, 2016)); - expectedHol.Add(new Date(6, Month.Oct, 2016)); - expectedHol.Add(new Date(7, Month.Oct, 2016)); - - - Calendar c = new China(China.Market.SSE); - List hol = Calendar.holidayList(c, new Date(1, Month.January, 2014), - new Date(31, Month.December, 2016)); - - for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) + public void testChinaSSE() { - if (hol[i] != expectedHol[i]) + // Testing China Shanghai Stock Exchange holiday list + + List expectedHol = new List(); + + // China Shanghai Securities Exchange holiday list in the year 2014 + expectedHol.Add(new Date(1, Month.Jan, 2014)); + expectedHol.Add(new Date(31, Month.Jan, 2014)); + expectedHol.Add(new Date(3, Month.Feb, 2014)); + expectedHol.Add(new Date(4, Month.Feb, 2014)); + expectedHol.Add(new Date(5, Month.Feb, 2014)); + expectedHol.Add(new Date(6, Month.Feb, 2014)); + expectedHol.Add(new Date(7, Month.Apr, 2014)); + expectedHol.Add(new Date(1, Month.May, 2014)); + expectedHol.Add(new Date(2, Month.May, 2014)); + expectedHol.Add(new Date(2, Month.Jun, 2014)); + expectedHol.Add(new Date(8, Month.Sep, 2014)); + expectedHol.Add(new Date(1, Month.Oct, 2014)); + expectedHol.Add(new Date(2, Month.Oct, 2014)); + expectedHol.Add(new Date(3, Month.Oct, 2014)); + expectedHol.Add(new Date(6, Month.Oct, 2014)); + expectedHol.Add(new Date(7, Month.Oct, 2014)); + + // China Shanghai Securities Exchange holiday list in the year 2015 + expectedHol.Add(new Date(1, Month.Jan, 2015)); + expectedHol.Add(new Date(2, Month.Jan, 2015)); + expectedHol.Add(new Date(18, Month.Feb, 2015)); + expectedHol.Add(new Date(19, Month.Feb, 2015)); + expectedHol.Add(new Date(20, Month.Feb, 2015)); + expectedHol.Add(new Date(23, Month.Feb, 2015)); + expectedHol.Add(new Date(24, Month.Feb, 2015)); + expectedHol.Add(new Date(6, Month.Apr, 2015)); + expectedHol.Add(new Date(1, Month.May, 2015)); + expectedHol.Add(new Date(22, Month.Jun, 2015)); + expectedHol.Add(new Date(3, Month.Sep, 2015)); + expectedHol.Add(new Date(4, Month.Sep, 2015)); + expectedHol.Add(new Date(1, Month.Oct, 2015)); + expectedHol.Add(new Date(2, Month.Oct, 2015)); + expectedHol.Add(new Date(5, Month.Oct, 2015)); + expectedHol.Add(new Date(6, Month.Oct, 2015)); + expectedHol.Add(new Date(7, Month.Oct, 2015)); + + // China Shanghai Securities Exchange holiday list in the year 2016 + expectedHol.Add(new Date(1, Month.Jan, 2016)); + expectedHol.Add(new Date(8, Month.Feb, 2016)); + expectedHol.Add(new Date(9, Month.Feb, 2016)); + expectedHol.Add(new Date(10, Month.Feb, 2016)); + expectedHol.Add(new Date(11, Month.Feb, 2016)); + expectedHol.Add(new Date(12, Month.Feb, 2016)); + expectedHol.Add(new Date(4, Month.Apr, 2016)); + expectedHol.Add(new Date(2, Month.May, 2016)); + expectedHol.Add(new Date(9, Month.Jun, 2016)); + expectedHol.Add(new Date(10, Month.Jun, 2016)); + expectedHol.Add(new Date(15, Month.Sep, 2016)); + expectedHol.Add(new Date(16, Month.Sep, 2016)); + expectedHol.Add(new Date(3, Month.Oct, 2016)); + expectedHol.Add(new Date(4, Month.Oct, 2016)); + expectedHol.Add(new Date(5, Month.Oct, 2016)); + expectedHol.Add(new Date(6, Month.Oct, 2016)); + expectedHol.Add(new Date(7, Month.Oct, 2016)); + + + Calendar c = new China(China.Market.SSE); + List hol = Calendar.holidayList(c, new Date(1, Month.January, 2014), + new Date(31, Month.December, 2016)); + + for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) + { + if (hol[i] != expectedHol[i]) QAssert.Fail("expected holiday was " + expectedHol[i] - + " while calculated holiday is " + hol[i]); - } - if (hol.Count != expectedHol.Count) + + " while calculated holiday is " + hol[i]); + } + if (hol.Count != expectedHol.Count) QAssert.Fail("there were " + expectedHol.Count - + " expected holidays, while there are " + hol.Count - + " calculated holidays"); -} + + " expected holidays, while there are " + hol.Count + + " calculated holidays"); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testChinaIB() - { - // Testing China Inter Bank working weekends list - List expectedWorkingWeekEnds = new List(); - - // China Inter Bank working weekends list in the year 2014 - expectedWorkingWeekEnds.Add(new Date(26,Month. Jan, 2014)); - expectedWorkingWeekEnds.Add(new Date(8, Month.Feb, 2014)); - expectedWorkingWeekEnds.Add(new Date(4, Month.May, 2014)); - expectedWorkingWeekEnds.Add(new Date(28,Month. Sep, 2014)); - expectedWorkingWeekEnds.Add(new Date(11,Month. Oct, 2014)); - - // China Inter Bank working weekends list in the year 2015 - expectedWorkingWeekEnds.Add(new Date(4, Month.Jan, 2015)); - expectedWorkingWeekEnds.Add(new Date(15,Month. Feb, 2015)); - expectedWorkingWeekEnds.Add(new Date(28,Month. Feb, 2015)); - expectedWorkingWeekEnds.Add(new Date(6, Month.Sep, 2015)); - expectedWorkingWeekEnds.Add(new Date(10,Month. Oct, 2015)); - - // China Inter Bank working weekends list in the year 2016 - expectedWorkingWeekEnds.Add(new Date(6, Month.Feb, 2016)); - expectedWorkingWeekEnds.Add(new Date(14,Month. Feb, 2016)); - expectedWorkingWeekEnds.Add(new Date(12,Month. Jun, 2016)); - expectedWorkingWeekEnds.Add(new Date(18,Month. Sep, 2016)); - expectedWorkingWeekEnds.Add(new Date(8, Month.Oct, 2016)); - expectedWorkingWeekEnds.Add(new Date(9, Month.Oct, 2016)); - - Calendar c = new China(China.Market.IB); - Date start = new Date(1, Month.Jan, 2014); - Date end = new Date(31, Month.Dec, 2016); - - int k = 0; - - while (start <= end) + public void testChinaIB() { - if (c.isBusinessDay(start) && c.isWeekend(start.DayOfWeek)) + // Testing China Inter Bank working weekends list + List expectedWorkingWeekEnds = new List(); + + // China Inter Bank working weekends list in the year 2014 + expectedWorkingWeekEnds.Add(new Date(26, Month. Jan, 2014)); + expectedWorkingWeekEnds.Add(new Date(8, Month.Feb, 2014)); + expectedWorkingWeekEnds.Add(new Date(4, Month.May, 2014)); + expectedWorkingWeekEnds.Add(new Date(28, Month. Sep, 2014)); + expectedWorkingWeekEnds.Add(new Date(11, Month. Oct, 2014)); + + // China Inter Bank working weekends list in the year 2015 + expectedWorkingWeekEnds.Add(new Date(4, Month.Jan, 2015)); + expectedWorkingWeekEnds.Add(new Date(15, Month. Feb, 2015)); + expectedWorkingWeekEnds.Add(new Date(28, Month. Feb, 2015)); + expectedWorkingWeekEnds.Add(new Date(6, Month.Sep, 2015)); + expectedWorkingWeekEnds.Add(new Date(10, Month. Oct, 2015)); + + // China Inter Bank working weekends list in the year 2016 + expectedWorkingWeekEnds.Add(new Date(6, Month.Feb, 2016)); + expectedWorkingWeekEnds.Add(new Date(14, Month. Feb, 2016)); + expectedWorkingWeekEnds.Add(new Date(12, Month. Jun, 2016)); + expectedWorkingWeekEnds.Add(new Date(18, Month. Sep, 2016)); + expectedWorkingWeekEnds.Add(new Date(8, Month.Oct, 2016)); + expectedWorkingWeekEnds.Add(new Date(9, Month.Oct, 2016)); + + Calendar c = new China(China.Market.IB); + Date start = new Date(1, Month.Jan, 2014); + Date end = new Date(31, Month.Dec, 2016); + + int k = 0; + + while (start <= end) { - if (expectedWorkingWeekEnds[k] != start) + if (c.isBusinessDay(start) && c.isWeekend(start.DayOfWeek)) + { + if (expectedWorkingWeekEnds[k] != start) QAssert.Fail("expected working weekend was " + expectedWorkingWeekEnds[k] - + " while calculated working weekend is " + start); - ++k; + + " while calculated working weekend is " + start); + ++k; + } + ++start; } - ++start; + + if (k != (expectedWorkingWeekEnds.Count)) + QAssert.Fail("there were " + expectedWorkingWeekEnds.Count + + " expected working weekends, while there are " + k + + " calculated holidays"); } - - if (k != (expectedWorkingWeekEnds.Count)) - QAssert.Fail("there were " + expectedWorkingWeekEnds.Count - + " expected working weekends, while there are " + k - + " calculated holidays"); -} #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testEndOfMonth() { - //BOOST_MESSAGE("Testing end-of-month calculation..."); - - Calendar c = new TARGET(); // any calendar would be OK - - Date eom, counter = Date.minDate(); - Date last = Date.maxDate() - new Period(2, TimeUnit.Months); - - while (counter<=last) { - eom = c.endOfMonth(counter); - // check that eom is eom - if (!c.isEndOfMonth(eom)) - QAssert.Fail("\n " - + eom.weekday() + " " + eom - + " is not the last business day in " - + eom.month() + " " + eom.year() - + " according to " + c.name()); - // check that eom is in the same month as counter - if (eom.month()!=counter.month()) - QAssert.Fail("\n " - + eom - + " is not in the same month as " - + counter); - counter = counter + 1; - } - } + public void testEndOfMonth() + { + //BOOST_MESSAGE("Testing end-of-month calculation..."); + + Calendar c = new TARGET(); // any calendar would be OK + + Date eom, counter = Date.minDate(); + Date last = Date.maxDate() - new Period(2, TimeUnit.Months); + + while (counter <= last) + { + eom = c.endOfMonth(counter); + // check that eom is eom + if (!c.isEndOfMonth(eom)) + QAssert.Fail("\n " + + eom.weekday() + " " + eom + + " is not the last business day in " + + eom.month() + " " + eom.year() + + " according to " + c.name()); + // check that eom is in the same month as counter + if (eom.month() != counter.month()) + QAssert.Fail("\n " + + eom + + " is not in the same month as " + + counter); + counter = counter + 1; + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testBusinessDaysBetween() { - - // Testing calculation of business days between dates - - List testDates = new List(); - testDates.Add(new Date(1,Month.February,2002)); - testDates.Add(new Date(4,Month.February,2002)); - testDates.Add(new Date(16,Month.May,2003)); - testDates.Add(new Date(17,Month.December,2003)); - testDates.Add(new Date(17,Month.December,2004)); - testDates.Add(new Date(19,Month.December,2005)); - testDates.Add(new Date(2,Month.January,2006)); - testDates.Add(new Date(13,Month.March,2006)); - testDates.Add(new Date(15,Month.May,2006)); - testDates.Add(new Date(17,Month.March,2006)); - testDates.Add(new Date(15,Month.May,2006)); - testDates.Add(new Date(26,Month.July,2006)); - - long[] expected = { - 1, - 321, - 152, - 251, - 252, - 10, - 48, - 42, - -38, - 38, - 51 - }; - - Calendar calendar = new Brazil(); - - for (int i=1; i testDates = new List(); + testDates.Add(new Date(1, Month.February, 2002)); + testDates.Add(new Date(4, Month.February, 2002)); + testDates.Add(new Date(16, Month.May, 2003)); + testDates.Add(new Date(17, Month.December, 2003)); + testDates.Add(new Date(17, Month.December, 2004)); + testDates.Add(new Date(19, Month.December, 2005)); + testDates.Add(new Date(2, Month.January, 2006)); + testDates.Add(new Date(13, Month.March, 2006)); + testDates.Add(new Date(15, Month.May, 2006)); + testDates.Add(new Date(17, Month.March, 2006)); + testDates.Add(new Date(15, Month.May, 2006)); + testDates.Add(new Date(26, Month.July, 2006)); + + long[] expected = + { + 1, + 321, + 152, + 251, + 252, + 10, + 48, + 42, + -38, + 38, + 51 + }; + + Calendar calendar = new Brazil(); + + for (int i = 1; i < testDates.Count; i++) + { + int calculated = calendar.businessDaysBetween(testDates[i - 1], testDates[i]); + if (calculated != expected[i - 1]) + { + QAssert.Fail("from " + testDates[i - 1] + + " to " + testDates[i] + ":\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected[i - 1]); } - } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testBespokeCalendars() { - - // Testing bespoke calendars - - BespokeCalendar a1 = new BespokeCalendar(); - BespokeCalendar b1 = new BespokeCalendar(); - - Date testDate1 = new Date(4, Month.October, 2008); // Saturday - Date testDate2 = new Date(5, Month.October, 2008); // Sunday - Date testDate3 = new Date(6, Month.October, 2008); // Monday - Date testDate4 = new Date(7, Month.October, 2008); // Tuesday - - if (!a1.isBusinessDay(testDate1)) - QAssert.Fail(testDate1 + " erroneously detected as holiday"); - if (!a1.isBusinessDay(testDate2)) - QAssert.Fail(testDate2 + " erroneously detected as holiday"); - if (!a1.isBusinessDay(testDate3)) - QAssert.Fail(testDate3 + " erroneously detected as holiday"); - if (!a1.isBusinessDay(testDate4)) - QAssert.Fail(testDate4 + " erroneously detected as holiday"); - - if (!b1.isBusinessDay(testDate1)) - QAssert.Fail(testDate1 + " erroneously detected as holiday"); - if (!b1.isBusinessDay(testDate2)) - QAssert.Fail(testDate2 + " erroneously detected as holiday"); - if (!b1.isBusinessDay(testDate3)) - QAssert.Fail(testDate3 + " erroneously detected as holiday"); - if (!b1.isBusinessDay(testDate4)) - QAssert.Fail(testDate4 + " erroneously detected as holiday"); - - a1.addWeekend(DayOfWeek.Sunday); - - if (!a1.isBusinessDay(testDate1)) - QAssert.Fail(testDate1 + " erroneously detected as holiday"); - if (a1.isBusinessDay(testDate2)) - QAssert.Fail(testDate2 + " (Sunday) not detected as weekend"); - if (!a1.isBusinessDay(testDate3)) - QAssert.Fail(testDate3 + " erroneously detected as holiday"); - if (!a1.isBusinessDay(testDate4)) - QAssert.Fail(testDate4 + " erroneously detected as holiday"); - - if (!b1.isBusinessDay(testDate1)) - QAssert.Fail(testDate1 + " erroneously detected as holiday"); - if (!b1.isBusinessDay(testDate2)) - QAssert.Fail(testDate2 + " erroneously detected as holiday"); - if (!b1.isBusinessDay(testDate3)) - QAssert.Fail(testDate3 + " erroneously detected as holiday"); - if (!b1.isBusinessDay(testDate4)) - QAssert.Fail(testDate4 + " erroneously detected as holiday"); - - a1.addHoliday(testDate3); - - if (!a1.isBusinessDay(testDate1)) - QAssert.Fail(testDate1 + " erroneously detected as holiday"); - if (a1.isBusinessDay(testDate2)) - QAssert.Fail(testDate2 + " (Sunday) not detected as weekend"); - if (a1.isBusinessDay(testDate3)) - QAssert.Fail(testDate3 + " (marked as holiday) not detected"); - if (!a1.isBusinessDay(testDate4)) - QAssert.Fail(testDate4 + " erroneously detected as holiday"); - - if (!b1.isBusinessDay(testDate1)) - QAssert.Fail(testDate1 + " erroneously detected as holiday"); - if (!b1.isBusinessDay(testDate2)) - QAssert.Fail(testDate2 + " erroneously detected as holiday"); - if (!b1.isBusinessDay(testDate3)) - QAssert.Fail(testDate3 + " erroneously detected as holiday"); - if (!b1.isBusinessDay(testDate4)) - QAssert.Fail(testDate4 + " erroneously detected as holiday"); - - BespokeCalendar a2 = a1; // linked to a1 - - a2.addWeekend(DayOfWeek.Saturday); - - if (a1.isBusinessDay(testDate1)) - QAssert.Fail(testDate1 + " (Saturday) not detected as weekend"); - if (a1.isBusinessDay(testDate2)) - QAssert.Fail(testDate2 + " (Sunday) not detected as weekend"); - if (a1.isBusinessDay(testDate3)) - QAssert.Fail(testDate3 + " (marked as holiday) not detected"); - if (!a1.isBusinessDay(testDate4)) - QAssert.Fail(testDate4 + " erroneously detected as holiday"); - - if (a2.isBusinessDay(testDate1)) - QAssert.Fail(testDate1 + " (Saturday) not detected as weekend"); - if (a2.isBusinessDay(testDate2)) - QAssert.Fail(testDate2 + " (Sunday) not detected as weekend"); - if (a2.isBusinessDay(testDate3)) - QAssert.Fail(testDate3 + " (marked as holiday) not detected"); - if (!a2.isBusinessDay(testDate4)) - QAssert.Fail(testDate4 + " erroneously detected as holiday"); - - a2.addHoliday(testDate4); - - if (a1.isBusinessDay(testDate1)) - QAssert.Fail(testDate1 + " (Saturday) not detected as weekend"); - if (a1.isBusinessDay(testDate2)) - QAssert.Fail(testDate2 + " (Sunday) not detected as weekend"); - if (a1.isBusinessDay(testDate3)) - QAssert.Fail(testDate3 + " (marked as holiday) not detected"); - if (a1.isBusinessDay(testDate4)) - QAssert.Fail(testDate4 + " (marked as holiday) not detected"); - - if (a2.isBusinessDay(testDate1)) - QAssert.Fail(testDate1 + " (Saturday) not detected as weekend"); - if (a2.isBusinessDay(testDate2)) - QAssert.Fail(testDate2 + " (Sunday) not detected as weekend"); - if (a2.isBusinessDay(testDate3)) - QAssert.Fail(testDate3 + " (marked as holiday) not detected"); - if (a2.isBusinessDay(testDate4)) - QAssert.Fail(testDate4 + " (marked as holiday) not detected"); - } - } + public void testBespokeCalendars() + { + + // Testing bespoke calendars + + BespokeCalendar a1 = new BespokeCalendar(); + BespokeCalendar b1 = new BespokeCalendar(); + + Date testDate1 = new Date(4, Month.October, 2008); // Saturday + Date testDate2 = new Date(5, Month.October, 2008); // Sunday + Date testDate3 = new Date(6, Month.October, 2008); // Monday + Date testDate4 = new Date(7, Month.October, 2008); // Tuesday + + if (!a1.isBusinessDay(testDate1)) + QAssert.Fail(testDate1 + " erroneously detected as holiday"); + if (!a1.isBusinessDay(testDate2)) + QAssert.Fail(testDate2 + " erroneously detected as holiday"); + if (!a1.isBusinessDay(testDate3)) + QAssert.Fail(testDate3 + " erroneously detected as holiday"); + if (!a1.isBusinessDay(testDate4)) + QAssert.Fail(testDate4 + " erroneously detected as holiday"); + + if (!b1.isBusinessDay(testDate1)) + QAssert.Fail(testDate1 + " erroneously detected as holiday"); + if (!b1.isBusinessDay(testDate2)) + QAssert.Fail(testDate2 + " erroneously detected as holiday"); + if (!b1.isBusinessDay(testDate3)) + QAssert.Fail(testDate3 + " erroneously detected as holiday"); + if (!b1.isBusinessDay(testDate4)) + QAssert.Fail(testDate4 + " erroneously detected as holiday"); + + a1.addWeekend(DayOfWeek.Sunday); + + if (!a1.isBusinessDay(testDate1)) + QAssert.Fail(testDate1 + " erroneously detected as holiday"); + if (a1.isBusinessDay(testDate2)) + QAssert.Fail(testDate2 + " (Sunday) not detected as weekend"); + if (!a1.isBusinessDay(testDate3)) + QAssert.Fail(testDate3 + " erroneously detected as holiday"); + if (!a1.isBusinessDay(testDate4)) + QAssert.Fail(testDate4 + " erroneously detected as holiday"); + + if (!b1.isBusinessDay(testDate1)) + QAssert.Fail(testDate1 + " erroneously detected as holiday"); + if (!b1.isBusinessDay(testDate2)) + QAssert.Fail(testDate2 + " erroneously detected as holiday"); + if (!b1.isBusinessDay(testDate3)) + QAssert.Fail(testDate3 + " erroneously detected as holiday"); + if (!b1.isBusinessDay(testDate4)) + QAssert.Fail(testDate4 + " erroneously detected as holiday"); + + a1.addHoliday(testDate3); + + if (!a1.isBusinessDay(testDate1)) + QAssert.Fail(testDate1 + " erroneously detected as holiday"); + if (a1.isBusinessDay(testDate2)) + QAssert.Fail(testDate2 + " (Sunday) not detected as weekend"); + if (a1.isBusinessDay(testDate3)) + QAssert.Fail(testDate3 + " (marked as holiday) not detected"); + if (!a1.isBusinessDay(testDate4)) + QAssert.Fail(testDate4 + " erroneously detected as holiday"); + + if (!b1.isBusinessDay(testDate1)) + QAssert.Fail(testDate1 + " erroneously detected as holiday"); + if (!b1.isBusinessDay(testDate2)) + QAssert.Fail(testDate2 + " erroneously detected as holiday"); + if (!b1.isBusinessDay(testDate3)) + QAssert.Fail(testDate3 + " erroneously detected as holiday"); + if (!b1.isBusinessDay(testDate4)) + QAssert.Fail(testDate4 + " erroneously detected as holiday"); + + BespokeCalendar a2 = a1; // linked to a1 + + a2.addWeekend(DayOfWeek.Saturday); + + if (a1.isBusinessDay(testDate1)) + QAssert.Fail(testDate1 + " (Saturday) not detected as weekend"); + if (a1.isBusinessDay(testDate2)) + QAssert.Fail(testDate2 + " (Sunday) not detected as weekend"); + if (a1.isBusinessDay(testDate3)) + QAssert.Fail(testDate3 + " (marked as holiday) not detected"); + if (!a1.isBusinessDay(testDate4)) + QAssert.Fail(testDate4 + " erroneously detected as holiday"); + + if (a2.isBusinessDay(testDate1)) + QAssert.Fail(testDate1 + " (Saturday) not detected as weekend"); + if (a2.isBusinessDay(testDate2)) + QAssert.Fail(testDate2 + " (Sunday) not detected as weekend"); + if (a2.isBusinessDay(testDate3)) + QAssert.Fail(testDate3 + " (marked as holiday) not detected"); + if (!a2.isBusinessDay(testDate4)) + QAssert.Fail(testDate4 + " erroneously detected as holiday"); + + a2.addHoliday(testDate4); + + if (a1.isBusinessDay(testDate1)) + QAssert.Fail(testDate1 + " (Saturday) not detected as weekend"); + if (a1.isBusinessDay(testDate2)) + QAssert.Fail(testDate2 + " (Sunday) not detected as weekend"); + if (a1.isBusinessDay(testDate3)) + QAssert.Fail(testDate3 + " (marked as holiday) not detected"); + if (a1.isBusinessDay(testDate4)) + QAssert.Fail(testDate4 + " (marked as holiday) not detected"); + + if (a2.isBusinessDay(testDate1)) + QAssert.Fail(testDate1 + " (Saturday) not detected as weekend"); + if (a2.isBusinessDay(testDate2)) + QAssert.Fail(testDate2 + " (Sunday) not detected as weekend"); + if (a2.isBusinessDay(testDate3)) + QAssert.Fail(testDate3 + " (marked as holiday) not detected"); + if (a2.isBusinessDay(testDate4)) + QAssert.Fail(testDate4 + " (marked as holiday) not detected"); + } + } } diff --git a/tests/QLNet.Tests/T_CapFloor.cs b/tests/QLNet.Tests/T_CapFloor.cs index 643cabf32..fef943c0e 100644 --- a/tests/QLNet.Tests/T_CapFloor.cs +++ b/tests/QLNet.Tests/T_CapFloor.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Andrea Maggiulli - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,519 +22,569 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; -namespace TestSuite { +namespace TestSuite +{ #if NET40 || NET45 [TestClass()] #endif public class T_CapFloor : IDisposable - { - - #region Initialize&Cleanup - private SavedSettings backup; - #if NET40 || NET45 - [TestInitialize] - public void testInitialize() - { - #else - public T_CapFloor() - { - #endif - backup = new SavedSettings(); - } - #if NET40 || NET45 - [TestCleanup] - #endif - public void testCleanup() - { - Dispose(); - } - public void Dispose() - { - backup.Dispose(); - } - #endregion - - class CommonVars { - // common data - public Date settlement; - public List nominals; - public BusinessDayConvention convention; - public Frequency frequency; - public IborIndex index; - public Calendar calendar; - public int fixingDays; - public RelinkableHandle termStructure = new RelinkableHandle(); - - // setup - public CommonVars() { - nominals = new List() { 100 }; - frequency = Frequency.Semiannual; - index = (IborIndex)new Euribor6M(termStructure); - calendar = index.fixingCalendar(); - convention = BusinessDayConvention.ModifiedFollowing; - Date today = calendar.adjust(Date.Today); - Settings.setEvaluationDate(today); - int settlementDays = 2; - fixingDays = 2; - settlement = calendar.advance(today, settlementDays, TimeUnit.Days); - termStructure.linkTo(Utilities.flatRate(settlement, 0.05, - new ActualActual(ActualActual.Convention.ISDA))); - - } - - // utilities - public List makeLeg(Date startDate, int length) { - Date endDate = calendar.advance(startDate, new Period(length, TimeUnit.Years), convention); - Schedule schedule = new Schedule(startDate, endDate, new Period(frequency), calendar, - convention, convention, DateGeneration.Rule.Forward, - false); - return new IborLeg(schedule, index) - .withPaymentDayCounter(index.dayCounter()) - .withFixingDays(fixingDays) - .withNotionals(nominals) - .withPaymentAdjustment(convention); - } - - public IPricingEngine makeEngine(double volatility) { - Handle vol = new Handle(new SimpleQuote(volatility)); - - return (IPricingEngine)new BlackCapFloorEngine(termStructure, vol); - - } - - public CapFloor makeCapFloor(CapFloorType type, - List leg, - double strike, - double volatility) { - CapFloor result; - switch (type) { - case CapFloorType.Cap: - result = (CapFloor)new Cap(leg, new List() { strike }); - break; - case CapFloorType.Floor: - result = (CapFloor)new Floor(leg, new List() { strike }); - break; - default: - throw new ArgumentException("unknown cap/floor type"); - } - result.setPricingEngine(makeEngine(volatility)); - return result; - } + { - } - - bool checkAbsError(double x1, double x2, double tolerance) { - return Math.Abs(x1 - x2) < tolerance; - } - - string typeToString(CapFloorType type) { - switch (type) { - case CapFloorType.Cap: - return "cap"; - case CapFloorType.Floor: - return "floor"; - case CapFloorType.Collar: - return "collar"; - default: - throw new ArgumentException("unknown cap/floor type"); + #region Initialize&Cleanup + private SavedSettings backup; +#if NET40 || NET45 + [TestInitialize] + public void testInitialize() + { +#else + public T_CapFloor() + { +#endif + backup = new SavedSettings(); + } +#if NET40 || NET45 + [TestCleanup] +#endif + public void testCleanup() + { + Dispose(); + } + public void Dispose() + { + backup.Dispose(); + } + #endregion + + class CommonVars + { + // common data + public Date settlement; + public List nominals; + public BusinessDayConvention convention; + public Frequency frequency; + public IborIndex index; + public Calendar calendar; + public int fixingDays; + public RelinkableHandle termStructure = new RelinkableHandle(); + + // setup + public CommonVars() + { + nominals = new List() { 100 }; + frequency = Frequency.Semiannual; + index = (IborIndex)new Euribor6M(termStructure); + calendar = index.fixingCalendar(); + convention = BusinessDayConvention.ModifiedFollowing; + Date today = calendar.adjust(Date.Today); + Settings.setEvaluationDate(today); + int settlementDays = 2; + fixingDays = 2; + settlement = calendar.advance(today, settlementDays, TimeUnit.Days); + termStructure.linkTo(Utilities.flatRate(settlement, 0.05, + new ActualActual(ActualActual.Convention.ISDA))); + + } + + // utilities + public List makeLeg(Date startDate, int length) + { + Date endDate = calendar.advance(startDate, new Period(length, TimeUnit.Years), convention); + Schedule schedule = new Schedule(startDate, endDate, new Period(frequency), calendar, + convention, convention, DateGeneration.Rule.Forward, + false); + return new IborLeg(schedule, index) + .withPaymentDayCounter(index.dayCounter()) + .withFixingDays(fixingDays) + .withNotionals(nominals) + .withPaymentAdjustment(convention); + } + + public IPricingEngine makeEngine(double volatility) + { + Handle vol = new Handle(new SimpleQuote(volatility)); + + return (IPricingEngine)new BlackCapFloorEngine(termStructure, vol); + + } + + public CapFloor makeCapFloor(CapFloorType type, + List leg, + double strike, + double volatility) + { + CapFloor result; + switch (type) + { + case CapFloorType.Cap: + result = (CapFloor)new Cap(leg, new List() { strike }); + break; + case CapFloorType.Floor: + result = (CapFloor)new Floor(leg, new List() { strike }); + break; + default: + throw new ArgumentException("unknown cap/floor type"); } - - } + result.setPricingEngine(makeEngine(volatility)); + return result; + } + + } + + bool checkAbsError(double x1, double x2, double tolerance) + { + return Math.Abs(x1 - x2) < tolerance; + } + + string typeToString(CapFloorType type) + { + switch (type) + { + case CapFloorType.Cap: + return "cap"; + case CapFloorType.Floor: + return "floor"; + case CapFloorType.Collar: + return "collar"; + default: + throw new ArgumentException("unknown cap/floor type"); + } + + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testVega() { - CommonVars vars = new CommonVars(); - - int[] lengths = { 1, 2, 3, 4, 5, 6, 7, 10, 15, 20, 30 }; - double[] vols = { 0.01, 0.05, 0.10, 0.15, 0.20 }; - double[] strikes = { 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09 }; - CapFloorType[] types = { CapFloorType.Cap, CapFloorType.Floor }; - - Date startDate = vars.termStructure.link.referenceDate(); - double shift = 1e-8; - double tolerance = 0.005; - - for (int i = 0; i < lengths.Length; i++) { - for (int j = 0; j < vols.Length; j++) { - for (int k = 0; k < strikes.Length; k++) { - for (int h = 0; h < types.Length; h++) { - List leg = vars.makeLeg(startDate, lengths[i]); - CapFloor capFloor = vars.makeCapFloor(types[h], leg, strikes[k], vols[j]); - CapFloor shiftedCapFloor2 = vars.makeCapFloor(types[h], leg, strikes[k], vols[j] + shift); - CapFloor shiftedCapFloor1 = vars.makeCapFloor(types[h], leg, strikes[k], vols[j] - shift); - - double value1 = shiftedCapFloor1.NPV(); - double value2 = shiftedCapFloor2.NPV(); - - double numericalVega = (value2 - value1) / (2 * shift); - - - if (numericalVega > 1.0e-4) { - double analyticalVega = (double)capFloor.result("vega"); - double discrepancy = Math.Abs(numericalVega - analyticalVega); - discrepancy /= numericalVega; - if (discrepancy > tolerance) - QAssert.Fail( - "failed to compute cap/floor vega:" + - "\n lengths: " + new Period(lengths[j], TimeUnit.Years) + - "\n strike: " + strikes[k] + - "\n types: " + types[h] + - "\n calculated: " + analyticalVega + - "\n expected: " + numericalVega + - "\n discrepancy: " + discrepancy + - "\n tolerance: " + tolerance); - - } - } - } - } + public void testVega() + { + CommonVars vars = new CommonVars(); + + int[] lengths = { 1, 2, 3, 4, 5, 6, 7, 10, 15, 20, 30 }; + double[] vols = { 0.01, 0.05, 0.10, 0.15, 0.20 }; + double[] strikes = { 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09 }; + CapFloorType[] types = { CapFloorType.Cap, CapFloorType.Floor }; + + Date startDate = vars.termStructure.link.referenceDate(); + double shift = 1e-8; + double tolerance = 0.005; + + for (int i = 0; i < lengths.Length; i++) + { + for (int j = 0; j < vols.Length; j++) + { + for (int k = 0; k < strikes.Length; k++) + { + for (int h = 0; h < types.Length; h++) + { + List leg = vars.makeLeg(startDate, lengths[i]); + CapFloor capFloor = vars.makeCapFloor(types[h], leg, strikes[k], vols[j]); + CapFloor shiftedCapFloor2 = vars.makeCapFloor(types[h], leg, strikes[k], vols[j] + shift); + CapFloor shiftedCapFloor1 = vars.makeCapFloor(types[h], leg, strikes[k], vols[j] - shift); + + double value1 = shiftedCapFloor1.NPV(); + double value2 = shiftedCapFloor2.NPV(); + + double numericalVega = (value2 - value1) / (2 * shift); + + + if (numericalVega > 1.0e-4) + { + double analyticalVega = (double)capFloor.result("vega"); + double discrepancy = Math.Abs(numericalVega - analyticalVega); + discrepancy /= numericalVega; + if (discrepancy > tolerance) + QAssert.Fail( + "failed to compute cap/floor vega:" + + "\n lengths: " + new Period(lengths[j], TimeUnit.Years) + + "\n strike: " + strikes[k] + + "\n types: " + types[h] + + "\n calculated: " + analyticalVega + + "\n expected: " + numericalVega + + "\n discrepancy: " + discrepancy + + "\n tolerance: " + tolerance); + + } + } + } } - } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testStrikeDependency() { - - CommonVars vars = new CommonVars(); - - int[] lengths = { 1, 2, 3, 5, 7, 10, 15, 20 }; - double[] vols = { 0.01, 0.05, 0.10, 0.15, 0.20 }; - double[] strikes = { 0.03, 0.04, 0.05, 0.06, 0.07 }; - - Date startDate = vars.termStructure.link.referenceDate(); - - for (int i = 0; i < lengths.Length; i++) { - for (int j = 0; j < vols.Length; j++) { - // store the results for different strikes... - List cap_values = new List(), floor_values = new List(); - - for (int k = 0; k < strikes.Length; k++) { - List leg = vars.makeLeg(startDate, lengths[i]); - Instrument cap = vars.makeCapFloor(CapFloorType.Cap, leg, - strikes[k], vols[j]); - cap_values.Add(cap.NPV()); - Instrument floor = vars.makeCapFloor(CapFloorType.Floor, leg, - strikes[k], vols[j]); - floor_values.Add(floor.NPV()); - } - // and check that they go the right way - for (int k = 0; k < cap_values.Count - 1; k++) { - if (cap_values[k] < cap_values[k + 1]) - QAssert.Fail( - "NPV is increasing with the strike in a cap: \n" - + " length: " + lengths[i] + " years\n" - + " volatility: " + vols[j] + "\n" - + " value: " + cap_values[k] - + " at strike: " + strikes[k] + "\n" - + " value: " + cap_values[k + 1] - + " at strike: " + strikes[k + 1]); - } - - // same for floors - for (int k = 0; k < floor_values.Count - 1; k++) { - if (floor_values[k] > floor_values[k + 1]) - QAssert.Fail( - "NPV is decreasing with the strike in a floor: \n" - + " length: " + lengths[i] + " years\n" - + " volatility: " + vols[j] + "\n" - + " value: " + floor_values[k] - + " at strike: " + strikes[k] + "\n" - + " value: " + floor_values[k + 1] - + " at strike: " + strikes[k + 1]); - } - } + public void testStrikeDependency() + { + + CommonVars vars = new CommonVars(); + + int[] lengths = { 1, 2, 3, 5, 7, 10, 15, 20 }; + double[] vols = { 0.01, 0.05, 0.10, 0.15, 0.20 }; + double[] strikes = { 0.03, 0.04, 0.05, 0.06, 0.07 }; + + Date startDate = vars.termStructure.link.referenceDate(); + + for (int i = 0; i < lengths.Length; i++) + { + for (int j = 0; j < vols.Length; j++) + { + // store the results for different strikes... + List cap_values = new List(), floor_values = new List(); + + for (int k = 0; k < strikes.Length; k++) + { + List leg = vars.makeLeg(startDate, lengths[i]); + Instrument cap = vars.makeCapFloor(CapFloorType.Cap, leg, + strikes[k], vols[j]); + cap_values.Add(cap.NPV()); + Instrument floor = vars.makeCapFloor(CapFloorType.Floor, leg, + strikes[k], vols[j]); + floor_values.Add(floor.NPV()); + } + // and check that they go the right way + for (int k = 0; k < cap_values.Count - 1; k++) + { + if (cap_values[k] < cap_values[k + 1]) + QAssert.Fail( + "NPV is increasing with the strike in a cap: \n" + + " length: " + lengths[i] + " years\n" + + " volatility: " + vols[j] + "\n" + + " value: " + cap_values[k] + + " at strike: " + strikes[k] + "\n" + + " value: " + cap_values[k + 1] + + " at strike: " + strikes[k + 1]); + } + + // same for floors + for (int k = 0; k < floor_values.Count - 1; k++) + { + if (floor_values[k] > floor_values[k + 1]) + QAssert.Fail( + "NPV is decreasing with the strike in a floor: \n" + + " length: " + lengths[i] + " years\n" + + " volatility: " + vols[j] + "\n" + + " value: " + floor_values[k] + + " at strike: " + strikes[k] + "\n" + + " value: " + floor_values[k + 1] + + " at strike: " + strikes[k + 1]); + } } - } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testConsistency() { - CommonVars vars = new CommonVars(); - - int[] lengths = { 1, 2, 3, 5, 7, 10, 15, 20 }; - double[] cap_rates = { 0.03, 0.04, 0.05, 0.06, 0.07 }; - double[] floor_rates = { 0.03, 0.04, 0.05, 0.06, 0.07 }; - double[] vols = { 0.01, 0.05, 0.10, 0.15, 0.20 }; - - Date startDate = vars.termStructure.link.referenceDate(); - - for (int i = 0; i < lengths.Length; i++) { - for (int j = 0; j < cap_rates.Length; j++) { - for (int k = 0; k < floor_rates.Length; k++) { - for (int l = 0; l < vols.Length; l++) { - - List leg = vars.makeLeg(startDate, lengths[i]); - Instrument cap = vars.makeCapFloor(CapFloorType.Cap, leg, - cap_rates[j], vols[l]); - Instrument floor = vars.makeCapFloor(CapFloorType.Floor, leg, - floor_rates[k], vols[l]); - Collar collar = new Collar(leg, new InitializedList(1, cap_rates[j]), - new InitializedList(1, floor_rates[k])); - collar.setPricingEngine(vars.makeEngine(vols[l])); - - if (Math.Abs((cap.NPV() - floor.NPV()) - collar.NPV()) > 1e-10) { - QAssert.Fail( - "inconsistency between cap, floor and collar:\n" - + " length: " + lengths[i] + " years\n" - + " volatility: " + vols[l] + "\n" - + " cap value: " + cap.NPV() - + " at strike: " + cap_rates[j] + "\n" - + " floor value: " + floor.NPV() - + " at strike: " + floor_rates[k] + "\n" - + " collar value: " + collar.NPV()); - } - } - } - } + public void testConsistency() + { + CommonVars vars = new CommonVars(); + + int[] lengths = { 1, 2, 3, 5, 7, 10, 15, 20 }; + double[] cap_rates = { 0.03, 0.04, 0.05, 0.06, 0.07 }; + double[] floor_rates = { 0.03, 0.04, 0.05, 0.06, 0.07 }; + double[] vols = { 0.01, 0.05, 0.10, 0.15, 0.20 }; + + Date startDate = vars.termStructure.link.referenceDate(); + + for (int i = 0; i < lengths.Length; i++) + { + for (int j = 0; j < cap_rates.Length; j++) + { + for (int k = 0; k < floor_rates.Length; k++) + { + for (int l = 0; l < vols.Length; l++) + { + + List leg = vars.makeLeg(startDate, lengths[i]); + Instrument cap = vars.makeCapFloor(CapFloorType.Cap, leg, + cap_rates[j], vols[l]); + Instrument floor = vars.makeCapFloor(CapFloorType.Floor, leg, + floor_rates[k], vols[l]); + Collar collar = new Collar(leg, new InitializedList(1, cap_rates[j]), + new InitializedList(1, floor_rates[k])); + collar.setPricingEngine(vars.makeEngine(vols[l])); + + if (Math.Abs((cap.NPV() - floor.NPV()) - collar.NPV()) > 1e-10) + { + QAssert.Fail( + "inconsistency between cap, floor and collar:\n" + + " length: " + lengths[i] + " years\n" + + " volatility: " + vols[l] + "\n" + + " cap value: " + cap.NPV() + + " at strike: " + cap_rates[j] + "\n" + + " floor value: " + floor.NPV() + + " at strike: " + floor_rates[k] + "\n" + + " collar value: " + collar.NPV()); + } + } + } } - } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testParity() { - CommonVars vars = new CommonVars(); - - int[] lengths = { 1, 2, 3, 5, 7, 10, 15, 20 }; - double[] strikes = { 0.0, 0.03, 0.04, 0.05, 0.06, 0.07 }; - double[] vols = { 0.01, 0.05, 0.10, 0.15, 0.20 }; - - Date startDate = vars.termStructure.link.referenceDate(); - - for (int i = 0; i < lengths.Length; i++) { - for (int j = 0; j < strikes.Length; j++) { - for (int k = 0; k < vols.Length; k++) { - - List leg = vars.makeLeg(startDate, lengths[i]); - Instrument cap = vars.makeCapFloor(CapFloorType.Cap, leg, strikes[j], vols[k]); - Instrument floor = vars.makeCapFloor(CapFloorType.Floor, leg, strikes[j], vols[k]); - Date maturity = vars.calendar.advance(startDate, lengths[i], TimeUnit.Years, vars.convention); - Schedule schedule = new Schedule(startDate, maturity, - new Period(vars.frequency), vars.calendar, - vars.convention, vars.convention, - DateGeneration.Rule.Forward, false); - VanillaSwap swap = new VanillaSwap(VanillaSwap.Type.Payer, vars.nominals[0], - schedule, strikes[j], vars.index.dayCounter(), - schedule, vars.index, 0.0, - vars.index.dayCounter()); - swap.setPricingEngine((IPricingEngine)new DiscountingSwapEngine(vars.termStructure)); - // FLOATING_POINT_EXCEPTION - if (Math.Abs((cap.NPV() - floor.NPV()) - swap.NPV()) > 1.0e-10) { - QAssert.Fail( - "put/call parity violated:\n" - + " length: " + lengths[i] + " years\n" - + " volatility: " + vols[k] + "\n" - + " strike: " + strikes[j] + "\n" - + " cap value: " + cap.NPV() + "\n" - + " floor value: " + floor.NPV() + "\n" - + " swap value: " + swap.NPV()); - } - } - } + public void testParity() + { + CommonVars vars = new CommonVars(); + + int[] lengths = { 1, 2, 3, 5, 7, 10, 15, 20 }; + double[] strikes = { 0.0, 0.03, 0.04, 0.05, 0.06, 0.07 }; + double[] vols = { 0.01, 0.05, 0.10, 0.15, 0.20 }; + + Date startDate = vars.termStructure.link.referenceDate(); + + for (int i = 0; i < lengths.Length; i++) + { + for (int j = 0; j < strikes.Length; j++) + { + for (int k = 0; k < vols.Length; k++) + { + + List leg = vars.makeLeg(startDate, lengths[i]); + Instrument cap = vars.makeCapFloor(CapFloorType.Cap, leg, strikes[j], vols[k]); + Instrument floor = vars.makeCapFloor(CapFloorType.Floor, leg, strikes[j], vols[k]); + Date maturity = vars.calendar.advance(startDate, lengths[i], TimeUnit.Years, vars.convention); + Schedule schedule = new Schedule(startDate, maturity, + new Period(vars.frequency), vars.calendar, + vars.convention, vars.convention, + DateGeneration.Rule.Forward, false); + VanillaSwap swap = new VanillaSwap(VanillaSwap.Type.Payer, vars.nominals[0], + schedule, strikes[j], vars.index.dayCounter(), + schedule, vars.index, 0.0, + vars.index.dayCounter()); + swap.setPricingEngine((IPricingEngine)new DiscountingSwapEngine(vars.termStructure)); + // FLOATING_POINT_EXCEPTION + if (Math.Abs((cap.NPV() - floor.NPV()) - swap.NPV()) > 1.0e-10) + { + QAssert.Fail( + "put/call parity violated:\n" + + " length: " + lengths[i] + " years\n" + + " volatility: " + vols[k] + "\n" + + " strike: " + strikes[j] + "\n" + + " cap value: " + cap.NPV() + "\n" + + " floor value: " + floor.NPV() + "\n" + + " swap value: " + swap.NPV()); + } + } } - } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testATMRate() { - CommonVars vars = new CommonVars(); - - int[] lengths = { 1, 2, 3, 5, 7, 10, 15, 20 }; - double[] strikes = { 0.0, 0.03, 0.04, 0.05, 0.06, 0.07 }; - double[] vols = { 0.01, 0.05, 0.10, 0.15, 0.20 }; - - Date startDate = vars.termStructure.link.referenceDate(); - - for (int i = 0; i < lengths.Length; i++) { - List leg = vars.makeLeg(startDate, lengths[i]); - Date maturity = vars.calendar.advance(startDate, lengths[i], TimeUnit.Years, vars.convention); - Schedule schedule = new Schedule(startDate, maturity, - new Period(vars.frequency), vars.calendar, - vars.convention, vars.convention, - DateGeneration.Rule.Forward, false); - - for (int j = 0; j < strikes.Length; j++) { - for (int k = 0; k < vols.Length; k++) { - - CapFloor cap = vars.makeCapFloor(CapFloorType.Cap, leg, strikes[j], vols[k]); - CapFloor floor = vars.makeCapFloor(CapFloorType.Floor, leg, strikes[j], vols[k]); - double capATMRate = cap.atmRate(vars.termStructure); - double floorATMRate = floor.atmRate(vars.termStructure); - - if (!checkAbsError(floorATMRate, capATMRate, 1.0e-10)) - QAssert.Fail( - "Cap ATM Rate and floor ATM Rate should be equal :\n" - + " length: " + lengths[i] + " years\n" - + " volatility: " + vols[k] + "\n" - + " strike: " + strikes[j] + "\n" - + " cap ATM rate: " + capATMRate + "\n" - + " floor ATM rate:" + floorATMRate + "\n" - + " relative Error:" - + Utilities.relativeError(capATMRate, floorATMRate, capATMRate) * 100 + "%"); - VanillaSwap swap = new VanillaSwap(VanillaSwap.Type.Payer, vars.nominals[0], - schedule, floorATMRate, - vars.index.dayCounter(), - schedule, vars.index, 0.0, - vars.index.dayCounter()); - swap.setPricingEngine((IPricingEngine)( - new DiscountingSwapEngine(vars.termStructure))); - double swapNPV = swap.NPV(); - if (!checkAbsError(swapNPV, 0, 1.0e-10)) - QAssert.Fail( - "the NPV of a Swap struck at ATM rate " - + "should be equal to 0:\n" - + " length: " + lengths[i] + " years\n" - + " volatility: " + vols[k] + "\n" - + " ATM rate: " + floorATMRate + "\n" - + " swap NPV: " + swapNPV); - - } - } + public void testATMRate() + { + CommonVars vars = new CommonVars(); + + int[] lengths = { 1, 2, 3, 5, 7, 10, 15, 20 }; + double[] strikes = { 0.0, 0.03, 0.04, 0.05, 0.06, 0.07 }; + double[] vols = { 0.01, 0.05, 0.10, 0.15, 0.20 }; + + Date startDate = vars.termStructure.link.referenceDate(); + + for (int i = 0; i < lengths.Length; i++) + { + List leg = vars.makeLeg(startDate, lengths[i]); + Date maturity = vars.calendar.advance(startDate, lengths[i], TimeUnit.Years, vars.convention); + Schedule schedule = new Schedule(startDate, maturity, + new Period(vars.frequency), vars.calendar, + vars.convention, vars.convention, + DateGeneration.Rule.Forward, false); + + for (int j = 0; j < strikes.Length; j++) + { + for (int k = 0; k < vols.Length; k++) + { + + CapFloor cap = vars.makeCapFloor(CapFloorType.Cap, leg, strikes[j], vols[k]); + CapFloor floor = vars.makeCapFloor(CapFloorType.Floor, leg, strikes[j], vols[k]); + double capATMRate = cap.atmRate(vars.termStructure); + double floorATMRate = floor.atmRate(vars.termStructure); + + if (!checkAbsError(floorATMRate, capATMRate, 1.0e-10)) + QAssert.Fail( + "Cap ATM Rate and floor ATM Rate should be equal :\n" + + " length: " + lengths[i] + " years\n" + + " volatility: " + vols[k] + "\n" + + " strike: " + strikes[j] + "\n" + + " cap ATM rate: " + capATMRate + "\n" + + " floor ATM rate:" + floorATMRate + "\n" + + " relative Error:" + + Utilities.relativeError(capATMRate, floorATMRate, capATMRate) * 100 + "%"); + VanillaSwap swap = new VanillaSwap(VanillaSwap.Type.Payer, vars.nominals[0], + schedule, floorATMRate, + vars.index.dayCounter(), + schedule, vars.index, 0.0, + vars.index.dayCounter()); + swap.setPricingEngine((IPricingEngine)( + new DiscountingSwapEngine(vars.termStructure))); + double swapNPV = swap.NPV(); + if (!checkAbsError(swapNPV, 0, 1.0e-10)) + QAssert.Fail( + "the NPV of a Swap struck at ATM rate " + + "should be equal to 0:\n" + + " length: " + lengths[i] + " years\n" + + " volatility: " + vols[k] + "\n" + + " ATM rate: " + floorATMRate + "\n" + + " swap NPV: " + swapNPV); + + } } - } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testImpliedVolatility() { - CommonVars vars = new CommonVars(); - - int maxEvaluations = 100; - double tolerance = 1.0e-6; - - CapFloorType[] types = { CapFloorType.Cap, CapFloorType.Floor }; - double[] strikes = { 0.02, 0.03, 0.04 }; - int[] lengths = { 1, 5, 10 }; - - // test data - double[] rRates = { 0.02, 0.03, 0.04 }; - double[] vols = { 0.01, 0.20, 0.30, 0.70, 0.90 }; - - for (int k = 0; k < lengths.Length; k++) { - List leg = vars.makeLeg(vars.settlement, lengths[k]); - - for (int i = 0; i < types.Length; i++) { - for (int j = 0; j < strikes.Length; j++) { - CapFloor capfloor = vars.makeCapFloor(types[i], leg, strikes[j], 0.0); - - for (int n = 0; n < rRates.Length; n++) { - for (int m = 0; m < vols.Length; m++) { - double r = rRates[n]; - double v = vols[m]; - vars.termStructure.linkTo(Utilities.flatRate(vars.settlement, r, new Actual360())); - capfloor.setPricingEngine(vars.makeEngine(v)); - - double value = capfloor.NPV(); - double implVol = 0.0; - - try { - implVol = capfloor.impliedVolatility(value, - vars.termStructure, - 0.10, - tolerance, - maxEvaluations); - } catch (Exception e) { - // couldn't bracket? - capfloor.setPricingEngine(vars.makeEngine(0.0)); - double value2 = capfloor.NPV(); - if (Math.Abs(value - value2) < tolerance) { - // ok, just skip: - continue; - } - - // otherwise, report error - QAssert.Fail("implied vol failure: " + typeToString(types[i]) + + public void testImpliedVolatility() + { + CommonVars vars = new CommonVars(); + + int maxEvaluations = 100; + double tolerance = 1.0e-6; + + CapFloorType[] types = { CapFloorType.Cap, CapFloorType.Floor }; + double[] strikes = { 0.02, 0.03, 0.04 }; + int[] lengths = { 1, 5, 10 }; + + // test data + double[] rRates = { 0.02, 0.03, 0.04 }; + double[] vols = { 0.01, 0.20, 0.30, 0.70, 0.90 }; + + for (int k = 0; k < lengths.Length; k++) + { + List leg = vars.makeLeg(vars.settlement, lengths[k]); + + for (int i = 0; i < types.Length; i++) + { + for (int j = 0; j < strikes.Length; j++) + { + CapFloor capfloor = vars.makeCapFloor(types[i], leg, strikes[j], 0.0); + + for (int n = 0; n < rRates.Length; n++) + { + for (int m = 0; m < vols.Length; m++) + { + double r = rRates[n]; + double v = vols[m]; + vars.termStructure.linkTo(Utilities.flatRate(vars.settlement, r, new Actual360())); + capfloor.setPricingEngine(vars.makeEngine(v)); + + double value = capfloor.NPV(); + double implVol = 0.0; + + try + { + implVol = capfloor.impliedVolatility(value, + vars.termStructure, + 0.10, + tolerance, + maxEvaluations); + } + catch (Exception e) + { + // couldn't bracket? + capfloor.setPricingEngine(vars.makeEngine(0.0)); + double value2 = capfloor.NPV(); + if (Math.Abs(value - value2) < tolerance) + { + // ok, just skip: + continue; + } + + // otherwise, report error + QAssert.Fail("implied vol failure: " + typeToString(types[i]) + " strike: " + strikes[j] + " risk-free: " + r + " length: " + lengths[k] + "Y" + " volatility: " + v + e.Message); - } - if (Math.Abs(implVol - v) > tolerance) { - // the difference might not matter - capfloor.setPricingEngine(vars.makeEngine(implVol)); - double value2 = capfloor.NPV(); - if (Math.Abs(value - value2) > tolerance) { - QAssert.Fail( - typeToString(types[i]) + ":" - + " strike: " - + strikes[j] + "\n" - + " risk-free rate: " - + r + "\n" - + " length: " - + lengths[k] + " years\n\n" - + " original volatility: " - + v + "\n" - + " price: " - + value + "\n" - + " implied volatility: " - + implVol + "\n" - + " corresponding price: " + value2); - } - } - } } - } - } + if (Math.Abs(implVol - v) > tolerance) + { + // the difference might not matter + capfloor.setPricingEngine(vars.makeEngine(implVol)); + double value2 = capfloor.NPV(); + if (Math.Abs(value - value2) > tolerance) + { + QAssert.Fail( + typeToString(types[i]) + ":" + + " strike: " + + strikes[j] + "\n" + + " risk-free rate: " + + r + "\n" + + " length: " + + lengths[k] + " years\n\n" + + " original volatility: " + + v + "\n" + + " price: " + + value + "\n" + + " implied volatility: " + + implVol + "\n" + + " corresponding price: " + value2); + } + } + } + } + } } - } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testCachedValue() { - CommonVars vars = new CommonVars(); - - Date cachedToday = new Date(14, Month.March, 2002), - cachedSettlement = new Date(18, Month.March, 2002); - Settings.setEvaluationDate(cachedToday); - vars.termStructure.linkTo(Utilities.flatRate(cachedSettlement, 0.05, new Actual360())); - Date startDate = vars.termStructure.link.referenceDate(); - List leg = vars.makeLeg(startDate, 20); - Instrument cap = vars.makeCapFloor(CapFloorType.Cap, leg, 0.07, 0.20); - Instrument floor = vars.makeCapFloor(CapFloorType.Floor, leg, 0.03, 0.20); - - // par coupon price - double cachedCapNPV = 6.87570026732, - cachedFloorNPV = 2.65812927959; - - // index fixing price - //Real cachedCapNPV = 6.87630307745, - // cachedFloorNPV = 2.65796764715; - - // test Black cap price against cached value - if (Math.Abs(cap.NPV() - cachedCapNPV) > 1.0e-11) - QAssert.Fail("failed to reproduce cached cap value:\n" - + " calculated: " + cap.NPV() + "\n" - + " expected: " + cachedCapNPV); - - // test Black floor price against cached value - if (Math.Abs(floor.NPV() - cachedFloorNPV) > 1.0e-11) - QAssert.Fail("failed to reproduce cached floor value:\n" - + " calculated: " + floor.NPV() + "\n" - + " expected: " + cachedFloorNPV); - } - } + public void testCachedValue() + { + CommonVars vars = new CommonVars(); + + Date cachedToday = new Date(14, Month.March, 2002), + cachedSettlement = new Date(18, Month.March, 2002); + Settings.setEvaluationDate(cachedToday); + vars.termStructure.linkTo(Utilities.flatRate(cachedSettlement, 0.05, new Actual360())); + Date startDate = vars.termStructure.link.referenceDate(); + List leg = vars.makeLeg(startDate, 20); + Instrument cap = vars.makeCapFloor(CapFloorType.Cap, leg, 0.07, 0.20); + Instrument floor = vars.makeCapFloor(CapFloorType.Floor, leg, 0.03, 0.20); + + // par coupon price + double cachedCapNPV = 6.87570026732, + cachedFloorNPV = 2.65812927959; + + // index fixing price + //Real cachedCapNPV = 6.87630307745, + // cachedFloorNPV = 2.65796764715; + + // test Black cap price against cached value + if (Math.Abs(cap.NPV() - cachedCapNPV) > 1.0e-11) + QAssert.Fail("failed to reproduce cached cap value:\n" + + " calculated: " + cap.NPV() + "\n" + + " expected: " + cachedCapNPV); + + // test Black floor price against cached value + if (Math.Abs(floor.NPV() - cachedFloorNPV) > 1.0e-11) + QAssert.Fail("failed to reproduce cached floor value:\n" + + " calculated: " + floor.NPV() + "\n" + + " expected: " + cachedFloorNPV); + } + } } diff --git a/tests/QLNet.Tests/T_CapFlooredCoupon.cs b/tests/QLNet.Tests/T_CapFlooredCoupon.cs index 34eb60002..577db47ff 100644 --- a/tests/QLNet.Tests/T_CapFlooredCoupon.cs +++ b/tests/QLNet.Tests/T_CapFlooredCoupon.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -18,15 +18,15 @@ #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; namespace TestSuite { - #if NET40 || NET45 - [TestClass()] - #endif +#if NET40 || NET45 + [TestClass()] +#endif public class T_CapFlooredCoupon { private class CommonVars @@ -50,14 +50,14 @@ private class CommonVars SavedSettings backup; // setup - public CommonVars() + public CommonVars() { termStructure = new RelinkableHandle(); backup = new SavedSettings(); length = 20; //years volatility = 0.20; nominal = 100.0; - nominals = new InitializedList(length,nominal); + nominals = new InitializedList(length, nominal); frequency = Frequency.Annual; index = new Euribor1Y(termStructure); calendar = index.fixingCalendar(); @@ -66,75 +66,75 @@ public CommonVars() Settings.setEvaluationDate(today); settlementDays = 2; fixingDays = 2; - settlement = calendar.advance(today,settlementDays,TimeUnit.Days); + settlement = calendar.advance(today, settlementDays, TimeUnit.Days); startDate = settlement; - termStructure.linkTo(Utilities.flatRate(settlement,0.05, new ActualActual(ActualActual.Convention.ISDA))); + termStructure.linkTo(Utilities.flatRate(settlement, 0.05, new ActualActual(ActualActual.Convention.ISDA))); } // utilities - public List makeFixedLeg( Date sDate,int len) + public List makeFixedLeg(Date sDate, int len) { - Date endDate = calendar.advance( sDate, len, TimeUnit.Years, convention ); - Schedule schedule = new Schedule( sDate, endDate, new Period( frequency ), calendar, - convention, convention, DateGeneration.Rule.Forward, false); + Date endDate = calendar.advance(sDate, len, TimeUnit.Years, convention); + Schedule schedule = new Schedule(sDate, endDate, new Period(frequency), calendar, + convention, convention, DateGeneration.Rule.Forward, false); List coupons = new InitializedList(len, 0.0); return new FixedRateLeg(schedule) - .withCouponRates(coupons, new Thirty360()) - .withNotionals(nominals); + .withCouponRates(coupons, new Thirty360()) + .withNotionals(nominals); } - public List makeFloatingLeg( Date sDate, int len, double gearing = 1.0, double spread = 0.0 ) + public List makeFloatingLeg(Date sDate, int len, double gearing = 1.0, double spread = 0.0) { - Date endDate = calendar.advance( sDate, len, TimeUnit.Years, convention ); - Schedule schedule = new Schedule( sDate, endDate, new Period( frequency ), calendar, - convention,convention,DateGeneration.Rule.Forward,false); + Date endDate = calendar.advance(sDate, len, TimeUnit.Years, convention); + Schedule schedule = new Schedule(sDate, endDate, new Period(frequency), calendar, + convention, convention, DateGeneration.Rule.Forward, false); List gearingVector = new InitializedList(len, gearing); List spreadVector = new InitializedList(len, spread); return new IborLeg(schedule, index) - .withPaymentDayCounter(index.dayCounter()) - .withFixingDays(fixingDays) - .withGearings(gearingVector) - .withSpreads(spreadVector) - .withNotionals(nominals) - .withPaymentAdjustment(convention); + .withPaymentDayCounter(index.dayCounter()) + .withFixingDays(fixingDays) + .withGearings(gearingVector) + .withSpreads(spreadVector) + .withNotionals(nominals) + .withPaymentAdjustment(convention); } - public List makeCapFlooredLeg( Date sDate, int len, List caps, List floors, - double volatility,double gearing = 1.0,double spread = 0.0) + public List makeCapFlooredLeg(Date sDate, int len, List < double? > caps, List < double? > floors, + double volatility, double gearing = 1.0, double spread = 0.0) { - Date endDate = calendar.advance( sDate, len, TimeUnit.Years, convention ); - Schedule schedule = new Schedule( sDate, endDate, new Period( frequency ), calendar, - convention,convention,DateGeneration.Rule.Forward,false); + Date endDate = calendar.advance(sDate, len, TimeUnit.Years, convention); + Schedule schedule = new Schedule(sDate, endDate, new Period(frequency), calendar, + convention, convention, DateGeneration.Rule.Forward, false); Handle vol = new Handle(new - ConstantOptionletVolatility(0, calendar, BusinessDayConvention.Following, volatility,new Actual365Fixed())); + ConstantOptionletVolatility(0, calendar, BusinessDayConvention.Following, volatility, new Actual365Fixed())); IborCouponPricer pricer = new BlackIborCouponPricer(vol); List gearingVector = new InitializedList(len, gearing); List spreadVector = new InitializedList(len, spread); List iborLeg = new IborLeg(schedule, index) - .withFloors(floors) - .withPaymentDayCounter(index.dayCounter()) - .withFixingDays(fixingDays) - .withGearings(gearingVector) - .withSpreads(spreadVector) - .withCaps(caps) - .withNotionals(nominals) - .withPaymentAdjustment(convention); + .withFloors(floors) + .withPaymentDayCounter(index.dayCounter()) + .withFixingDays(fixingDays) + .withGearings(gearingVector) + .withSpreads(spreadVector) + .withCaps(caps) + .withNotionals(nominals) + .withPaymentAdjustment(convention); Utils.setCouponPricer(iborLeg, pricer); return iborLeg; } - public IPricingEngine makeEngine(double vols) + public IPricingEngine makeEngine(double vols) { Handle vol = new Handle(new SimpleQuote(vols)); return new BlackCapFloorEngine(termStructure, vol); } - public CapFloor makeCapFloor(CapFloorType type,List leg,double capStrike, - double floorStrike,double vol) + public CapFloor makeCapFloor(CapFloorType type, List leg, double capStrike, + double floorStrike, double vol) { CapFloor result = null; - switch (type) + switch (type) { case CapFloorType.Cap: result = new Cap(leg, new InitializedList(1, capStrike)); @@ -143,8 +143,8 @@ public CapFloor makeCapFloor(CapFloorType type,List leg,double capStri result = new Floor(leg, new InitializedList(1, floorStrike)); break; case CapFloorType.Collar: - result = new Collar(leg,new InitializedList(1, capStrike), - new InitializedList(1, floorStrike)); + result = new Collar(leg, new InitializedList(1, capStrike), + new InitializedList(1, floorStrike)); break; default: Utils.QL_FAIL("unknown cap/floor type"); @@ -152,16 +152,16 @@ public CapFloor makeCapFloor(CapFloorType type,List leg,double capStri } result.setPricingEngine(makeEngine(vol)); return result; - } - + } + } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testLargeRates() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testLargeRates() { // Testing degenerate collared coupon @@ -172,74 +172,74 @@ equal to 100 and floor equal to 0 must have (about) the same NPV (depending on variance: option expiry and volatility) */ - List caps = new InitializedList(vars.length,100.0); - List floors = new InitializedList(vars.length,0.0); + List < double? > caps = new InitializedList < double? >(vars.length, 100.0); + List < double? > floors = new InitializedList < double? >(vars.length, 0.0); double tolerance = 1e-10; // fixed leg with zero rate - List fixedLeg = vars.makeFixedLeg(vars.startDate,vars.length); - List floatLeg = vars.makeFloatingLeg(vars.startDate,vars.length); - List collaredLeg = vars.makeCapFlooredLeg(vars.startDate,vars.length,caps,floors,vars.volatility); + List fixedLeg = vars.makeFixedLeg(vars.startDate, vars.length); + List floatLeg = vars.makeFloatingLeg(vars.startDate, vars.length); + List collaredLeg = vars.makeCapFlooredLeg(vars.startDate, vars.length, caps, floors, vars.volatility); IPricingEngine engine = new DiscountingSwapEngine(vars.termStructure); - Swap vanillaLeg = new Swap(fixedLeg,floatLeg); - Swap collarLeg = new Swap(fixedLeg,collaredLeg); + Swap vanillaLeg = new Swap(fixedLeg, floatLeg); + Swap collarLeg = new Swap(fixedLeg, collaredLeg); vanillaLeg.setPricingEngine(engine); collarLeg.setPricingEngine(engine); double npvVanilla = vanillaLeg.NPV(); double npvCollar = collarLeg.NPV(); - if ( Math.Abs( npvVanilla - npvCollar ) > tolerance ) + if (Math.Abs(npvVanilla - npvCollar) > tolerance) { QAssert.Fail("Lenght: " + vars.length + " y" + "\n" + - "Volatility: " + vars.volatility*100 + "%\n" + - "Notional: " + vars.nominal + "\n" + - "Vanilla floating leg NPV: " + vanillaLeg.NPV() - + "\n" + - "Collared floating leg NPV (strikes 0 and 100): " - + collarLeg.NPV() - + "\n" + - "Diff: " + Math.Abs(vanillaLeg.NPV()-collarLeg.NPV())); + "Volatility: " + vars.volatility * 100 + "%\n" + + "Notional: " + vars.nominal + "\n" + + "Vanilla floating leg NPV: " + vanillaLeg.NPV() + + "\n" + + "Collared floating leg NPV (strikes 0 and 100): " + + collarLeg.NPV() + + "\n" + + "Diff: " + Math.Abs(vanillaLeg.NPV() - collarLeg.NPV())); } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testDecomposition() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testDecomposition() { // Testing collared coupon against its decomposition CommonVars vars = new CommonVars(); double tolerance = 1e-12; - double npvVanilla,npvCappedLeg,npvFlooredLeg,npvCollaredLeg,npvCap,npvFloor,npvCollar; + double npvVanilla, npvCappedLeg, npvFlooredLeg, npvCollaredLeg, npvCap, npvFloor, npvCollar; double error; double floorstrike = 0.05; double capstrike = 0.10; - List caps = new InitializedList(vars.length,capstrike); - List caps0 = new List(); - List floors = new InitializedList(vars.length,floorstrike); - List floors0 = new List(); + List < double? > caps = new InitializedList < double? >(vars.length, capstrike); + List < double? > caps0 = new List < double? >(); + List < double? > floors = new InitializedList < double? >(vars.length, floorstrike); + List < double? > floors0 = new List < double? >(); double gearing_p = 0.5; double spread_p = 0.002; double gearing_n = -1.5; double spread_n = 0.12; // fixed leg with zero rate - List fixedLeg = vars.makeFixedLeg(vars.startDate,vars.length); + List fixedLeg = vars.makeFixedLeg(vars.startDate, vars.length); // floating leg with gearing=1 and spread=0 - List floatLeg = vars.makeFloatingLeg(vars.startDate,vars.length); + List floatLeg = vars.makeFloatingLeg(vars.startDate, vars.length); // floating leg with positive gearing (gearing_p) and spread<>0 - List floatLeg_p = vars.makeFloatingLeg(vars.startDate,vars.length,gearing_p,spread_p); + List floatLeg_p = vars.makeFloatingLeg(vars.startDate, vars.length, gearing_p, spread_p); // floating leg with negative gearing (gearing_n) and spread<>0 - List floatLeg_n = vars.makeFloatingLeg(vars.startDate,vars.length,gearing_n,spread_n); + List floatLeg_n = vars.makeFloatingLeg(vars.startDate, vars.length, gearing_n, spread_n); // Swap with null fixed leg and floating leg with gearing=1 and spread=0 - Swap vanillaLeg = new Swap(fixedLeg,floatLeg); + Swap vanillaLeg = new Swap(fixedLeg, floatLeg); // Swap with null fixed leg and floating leg with positive gearing and spread<>0 - Swap vanillaLeg_p = new Swap(fixedLeg,floatLeg_p); + Swap vanillaLeg_p = new Swap(fixedLeg, floatLeg_p); // Swap with null fixed leg and floating leg with negative gearing and spread<>0 - Swap vanillaLeg_n = new Swap(fixedLeg,floatLeg_n); + Swap vanillaLeg_n = new Swap(fixedLeg, floatLeg_n); IPricingEngine engine = new DiscountingSwapEngine(vars.termStructure); vanillaLeg.setPricingEngine(engine); @@ -254,22 +254,22 @@ public void testDecomposition() */ // Case gearing = 1 and spread = 0 - List cappedLeg = vars.makeCapFlooredLeg(vars.startDate,vars.length,caps,floors0,vars.volatility); - Swap capLeg = new Swap(fixedLeg,cappedLeg); + List cappedLeg = vars.makeCapFlooredLeg(vars.startDate, vars.length, caps, floors0, vars.volatility); + Swap capLeg = new Swap(fixedLeg, cappedLeg); capLeg.setPricingEngine(engine); Cap cap = new Cap(floatLeg, new InitializedList(1, capstrike)); cap.setPricingEngine(vars.makeEngine(vars.volatility)); npvVanilla = vanillaLeg.NPV(); npvCappedLeg = capLeg.NPV(); npvCap = cap.NPV(); - error = Math.Abs(npvCappedLeg - (npvVanilla-npvCap)); - if (error>tolerance) + error = Math.Abs(npvCappedLeg - (npvVanilla - npvCap)); + if (error > tolerance) { - QAssert.Fail("\nCapped Leg: gearing=1, spread=0%, strike=" + capstrike*100 + - "%\n" + - " Capped Floating Leg NPV: " + npvCappedLeg + "\n" + - " Floating Leg NPV - Cap NPV: " + (npvVanilla - npvCap) + "\n" + - " Diff: " + error ); + QAssert.Fail("\nCapped Leg: gearing=1, spread=0%, strike=" + capstrike * 100 + + "%\n" + + " Capped Floating Leg NPV: " + npvCappedLeg + "\n" + + " Floating Leg NPV - Cap NPV: " + (npvVanilla - npvCap) + "\n" + + " Diff: " + error); } /* gearing = 1 and spread = 0 @@ -280,21 +280,21 @@ FLOORED coupon - Decomposition of payoff = VanillaFloatingLeg + Put */ - List flooredLeg = vars.makeCapFlooredLeg(vars.startDate,vars.length,caps0,floors,vars.volatility); - Swap floorLeg = new Swap(fixedLeg,flooredLeg); + List flooredLeg = vars.makeCapFlooredLeg(vars.startDate, vars.length, caps0, floors, vars.volatility); + Swap floorLeg = new Swap(fixedLeg, flooredLeg); floorLeg.setPricingEngine(engine); Floor floor = new Floor(floatLeg, new InitializedList(1, floorstrike)); floor.setPricingEngine(vars.makeEngine(vars.volatility)); npvFlooredLeg = floorLeg.NPV(); npvFloor = floor.NPV(); - error = Math.Abs(npvFlooredLeg-(npvVanilla + npvFloor)); - if (error>tolerance) + error = Math.Abs(npvFlooredLeg - (npvVanilla + npvFloor)); + if (error > tolerance) { - QAssert.Fail("Floored Leg: gearing=1, spread=0%, strike=" + floorstrike *100 + - "%\n" + - " Floored Floating Leg NPV: " + npvFlooredLeg + "\n" + - " Floating Leg NPV + Floor NPV: " + (npvVanilla + npvFloor) + "\n" + - " Diff: " + error ); + QAssert.Fail("Floored Leg: gearing=1, spread=0%, strike=" + floorstrike * 100 + + "%\n" + + " Floored Floating Leg NPV: " + npvFlooredLeg + "\n" + + " Floating Leg NPV + Floor NPV: " + (npvVanilla + npvFloor) + "\n" + + " Diff: " + error); } /* gearing = 1 and spread = 0 @@ -303,22 +303,22 @@ COLLARED coupon - Decomposition of payoff = VanillaFloatingLeg - Collar */ - List collaredLeg = vars.makeCapFlooredLeg(vars.startDate,vars.length,caps,floors,vars.volatility); - Swap collarLeg = new Swap(fixedLeg,collaredLeg); + List collaredLeg = vars.makeCapFlooredLeg(vars.startDate, vars.length, caps, floors, vars.volatility); + Swap collarLeg = new Swap(fixedLeg, collaredLeg); collarLeg.setPricingEngine(engine); - Collar collar = new Collar(floatLeg,new InitializedList(1, capstrike), - new InitializedList(1, floorstrike)); + Collar collar = new Collar(floatLeg, new InitializedList(1, capstrike), + new InitializedList(1, floorstrike)); collar.setPricingEngine(vars.makeEngine(vars.volatility)); npvCollaredLeg = collarLeg.NPV(); npvCollar = collar.NPV(); - error = Math.Abs(npvCollaredLeg -(npvVanilla - npvCollar)); - if (error>tolerance) + error = Math.Abs(npvCollaredLeg - (npvVanilla - npvCollar)); + if (error > tolerance) { QAssert.Fail("\nCollared Leg: gearing=1, spread=0%, strike=" + - floorstrike*100 + "% and " + capstrike*100 + "%\n" + - " Collared Floating Leg NPV: " + npvCollaredLeg + "\n" + - " Floating Leg NPV - Collar NPV: " + (npvVanilla - npvCollar) + "\n" + - " Diff: " + error ); + floorstrike * 100 + "% and " + capstrike * 100 + "%\n" + + " Collared Floating Leg NPV: " + npvCollaredLeg + "\n" + + " Floating Leg NPV - Collar NPV: " + (npvVanilla - npvCollar) + "\n" + + " Diff: " + error); } /* gearing = a and spread = b @@ -335,53 +335,53 @@ CAPPED coupon - Decomposition of payoff */ // Positive gearing - List cappedLeg_p = vars.makeCapFlooredLeg(vars.startDate,vars.length,caps,floors0, - vars.volatility,gearing_p,spread_p); - Swap capLeg_p = new Swap(fixedLeg,cappedLeg_p); + List cappedLeg_p = vars.makeCapFlooredLeg(vars.startDate, vars.length, caps, floors0, + vars.volatility, gearing_p, spread_p); + Swap capLeg_p = new Swap(fixedLeg, cappedLeg_p); capLeg_p.setPricingEngine(engine); - Cap cap_p = new Cap(floatLeg_p, new InitializedList(1,capstrike)); + Cap cap_p = new Cap(floatLeg_p, new InitializedList(1, capstrike)); cap_p.setPricingEngine(vars.makeEngine(vars.volatility)); npvVanilla = vanillaLeg_p.NPV(); npvCappedLeg = capLeg_p.NPV(); npvCap = cap_p.NPV(); - error = Math.Abs(npvCappedLeg - (npvVanilla-npvCap)); - if (error>tolerance) + error = Math.Abs(npvCappedLeg - (npvVanilla - npvCap)); + if (error > tolerance) { QAssert.Fail("\nCapped Leg: gearing=" + gearing_p + ", " + - "spread= " + spread_p *100 + - "%, strike=" + capstrike*100 + "%, " + - "effective strike= " + (capstrike-spread_p)/gearing_p*100 + - "%\n" + - " Capped Floating Leg NPV: " + npvCappedLeg + "\n" + - " Vanilla Leg NPV: " + npvVanilla + "\n" + - " Cap NPV: " + npvCap + "\n" + - " Floating Leg NPV - Cap NPV: " + (npvVanilla - npvCap) + "\n" + - " Diff: " + error ); + "spread= " + spread_p * 100 + + "%, strike=" + capstrike * 100 + "%, " + + "effective strike= " + (capstrike - spread_p) / gearing_p * 100 + + "%\n" + + " Capped Floating Leg NPV: " + npvCappedLeg + "\n" + + " Vanilla Leg NPV: " + npvVanilla + "\n" + + " Cap NPV: " + npvCap + "\n" + + " Floating Leg NPV - Cap NPV: " + (npvVanilla - npvCap) + "\n" + + " Diff: " + error); } // Negative gearing - List cappedLeg_n = vars.makeCapFlooredLeg(vars.startDate,vars.length,caps,floors0, - vars.volatility,gearing_n,spread_n); - Swap capLeg_n = new Swap(fixedLeg,cappedLeg_n); + List cappedLeg_n = vars.makeCapFlooredLeg(vars.startDate, vars.length, caps, floors0, + vars.volatility, gearing_n, spread_n); + Swap capLeg_n = new Swap(fixedLeg, cappedLeg_n); capLeg_n.setPricingEngine(engine); - Floor floor_n = new Floor(floatLeg, new InitializedList(1,(capstrike-spread_n)/gearing_n)); + Floor floor_n = new Floor(floatLeg, new InitializedList(1, (capstrike - spread_n) / gearing_n)); floor_n.setPricingEngine(vars.makeEngine(vars.volatility)); npvVanilla = vanillaLeg_n.NPV(); npvCappedLeg = capLeg_n.NPV(); npvFloor = floor_n.NPV(); - error = Math.Abs(npvCappedLeg - (npvVanilla+ gearing_n*npvFloor)); - if (error>tolerance) + error = Math.Abs(npvCappedLeg - (npvVanilla + gearing_n * npvFloor)); + if (error > tolerance) { QAssert.Fail("\nCapped Leg: gearing=" + gearing_n + ", " + - "spread= " + spread_n *100 + - "%, strike=" + capstrike*100 + "%, " + - "effective strike= " + (capstrike-spread_n)/gearing_n*100 + - "%\n" + - " Capped Floating Leg NPV: " + npvCappedLeg + "\n" + - " npv Vanilla: " + npvVanilla + "\n" + - " npvFloor: " + npvFloor + "\n" + - " Floating Leg NPV - Cap NPV: " + (npvVanilla + gearing_n*npvFloor) + "\n" + - " Diff: " + error ); + "spread= " + spread_n * 100 + + "%, strike=" + capstrike * 100 + "%, " + + "effective strike= " + (capstrike - spread_n) / gearing_n * 100 + + "%\n" + + " Capped Floating Leg NPV: " + npvCappedLeg + "\n" + + " npv Vanilla: " + npvVanilla + "\n" + + " npvFloor: " + npvFloor + "\n" + + " Floating Leg NPV - Cap NPV: " + (npvVanilla + gearing_n * npvFloor) + "\n" + + " Diff: " + error); } /* gearing = a and spread = b @@ -398,49 +398,49 @@ FLOORED coupon - Decomposition of payoff */ // Positive gearing - List flooredLeg_p1 = vars.makeCapFlooredLeg(vars.startDate,vars.length,caps0,floors, - vars.volatility,gearing_p,spread_p); - Swap floorLeg_p1 = new Swap(fixedLeg,flooredLeg_p1); + List flooredLeg_p1 = vars.makeCapFlooredLeg(vars.startDate, vars.length, caps0, floors, + vars.volatility, gearing_p, spread_p); + Swap floorLeg_p1 = new Swap(fixedLeg, flooredLeg_p1); floorLeg_p1.setPricingEngine(engine); - Floor floor_p1 = new Floor(floatLeg_p, new InitializedList(1,floorstrike)); + Floor floor_p1 = new Floor(floatLeg_p, new InitializedList(1, floorstrike)); floor_p1.setPricingEngine(vars.makeEngine(vars.volatility)); npvVanilla = vanillaLeg_p.NPV(); npvFlooredLeg = floorLeg_p1.NPV(); npvFloor = floor_p1.NPV(); - error = Math.Abs(npvFlooredLeg - (npvVanilla+npvFloor)); - if (error>tolerance) + error = Math.Abs(npvFlooredLeg - (npvVanilla + npvFloor)); + if (error > tolerance) { QAssert.Fail("\nFloored Leg: gearing=" + gearing_p + ", " - + "spread= " + spread_p *100+ "%, strike=" + floorstrike *100 + "%, " - + "effective strike= " + (floorstrike-spread_p)/gearing_p*100 - + "%\n" + - " Floored Floating Leg NPV: " + npvFlooredLeg - + "\n" + - " Floating Leg NPV + Floor NPV: " + (npvVanilla + npvFloor) - + "\n" + - " Diff: " + error ); + + "spread= " + spread_p * 100 + "%, strike=" + floorstrike * 100 + "%, " + + "effective strike= " + (floorstrike - spread_p) / gearing_p * 100 + + "%\n" + + " Floored Floating Leg NPV: " + npvFlooredLeg + + "\n" + + " Floating Leg NPV + Floor NPV: " + (npvVanilla + npvFloor) + + "\n" + + " Diff: " + error); } // Negative gearing - List flooredLeg_n = vars.makeCapFlooredLeg(vars.startDate,vars.length,caps0,floors, - vars.volatility,gearing_n,spread_n); - Swap floorLeg_n = new Swap(fixedLeg,flooredLeg_n); + List flooredLeg_n = vars.makeCapFlooredLeg(vars.startDate, vars.length, caps0, floors, + vars.volatility, gearing_n, spread_n); + Swap floorLeg_n = new Swap(fixedLeg, flooredLeg_n); floorLeg_n.setPricingEngine(engine); - Cap cap_n = new Cap(floatLeg, new InitializedList(1,(floorstrike-spread_n)/gearing_n)); + Cap cap_n = new Cap(floatLeg, new InitializedList(1, (floorstrike - spread_n) / gearing_n)); cap_n.setPricingEngine(vars.makeEngine(vars.volatility)); npvVanilla = vanillaLeg_n.NPV(); npvFlooredLeg = floorLeg_n.NPV(); npvCap = cap_n.NPV(); - error = Math.Abs(npvFlooredLeg - (npvVanilla - gearing_n*npvCap)); - if (error>tolerance) + error = Math.Abs(npvFlooredLeg - (npvVanilla - gearing_n * npvCap)); + if (error > tolerance) { QAssert.Fail("\nCapped Leg: gearing=" + gearing_n + ", " + - "spread= " + spread_n *100 + - "%, strike=" + floorstrike*100 + "%, " + - "effective strike= " + (floorstrike-spread_n)/gearing_n*100 + - "%\n" + - " Capped Floating Leg NPV: " + npvFlooredLeg + "\n" + - " Floating Leg NPV - Cap NPV: " + (npvVanilla - gearing_n*npvCap) + "\n" + - " Diff: " + error ); + "spread= " + spread_n * 100 + + "%, strike=" + floorstrike * 100 + "%, " + + "effective strike= " + (floorstrike - spread_n) / gearing_n * 100 + + "%\n" + + " Capped Floating Leg NPV: " + npvFlooredLeg + "\n" + + " Floating Leg NPV - Cap NPV: " + (npvVanilla - gearing_n * npvCap) + "\n" + + " Diff: " + error); } /* gearing = a and spread = b COLLARED coupon - Decomposition of payoff @@ -451,58 +451,58 @@ COLLARED coupon - Decomposition of payoff Payoff = VanillaFloatingLeg + Collar(|a|*rate+b, caprate, floorrate) */ // Positive gearing - List collaredLeg_p = vars.makeCapFlooredLeg(vars.startDate,vars.length,caps,floors, - vars.volatility,gearing_p,spread_p); - Swap collarLeg_p1 = new Swap(fixedLeg,collaredLeg_p); + List collaredLeg_p = vars.makeCapFlooredLeg(vars.startDate, vars.length, caps, floors, + vars.volatility, gearing_p, spread_p); + Swap collarLeg_p1 = new Swap(fixedLeg, collaredLeg_p); collarLeg_p1.setPricingEngine(engine); - Collar collar_p = new Collar(floatLeg_p,new InitializedList(1,capstrike), - new InitializedList(1,floorstrike)); + Collar collar_p = new Collar(floatLeg_p, new InitializedList(1, capstrike), + new InitializedList(1, floorstrike)); collar_p.setPricingEngine(vars.makeEngine(vars.volatility)); npvVanilla = vanillaLeg_p.NPV(); npvCollaredLeg = collarLeg_p1.NPV(); npvCollar = collar_p.NPV(); error = Math.Abs(npvCollaredLeg - (npvVanilla - npvCollar)); - if (error>tolerance) + if (error > tolerance) { QAssert.Fail("\nCollared Leg: gearing=" + gearing_p + ", " - + "spread= " + spread_p*100 + "%, strike=" - + floorstrike*100 + "% and " + capstrike*100 - + "%, " - + "effective strike=" + (floorstrike-spread_p)/gearing_p*100 - + "% and " + (capstrike-spread_p)/gearing_p*100 - + "%\n" + - " Collared Floating Leg NPV: " + npvCollaredLeg - + "\n" + - " Floating Leg NPV - Collar NPV: " + (npvVanilla - npvCollar) - + "\n" + - " Diff: " + error ); + + "spread= " + spread_p * 100 + "%, strike=" + + floorstrike * 100 + "% and " + capstrike * 100 + + "%, " + + "effective strike=" + (floorstrike - spread_p) / gearing_p * 100 + + "% and " + (capstrike - spread_p) / gearing_p * 100 + + "%\n" + + " Collared Floating Leg NPV: " + npvCollaredLeg + + "\n" + + " Floating Leg NPV - Collar NPV: " + (npvVanilla - npvCollar) + + "\n" + + " Diff: " + error); } // Negative gearing - List collaredLeg_n = vars.makeCapFlooredLeg(vars.startDate,vars.length,caps,floors, - vars.volatility,gearing_n,spread_n); - Swap collarLeg_n1 = new Swap(fixedLeg,collaredLeg_n); + List collaredLeg_n = vars.makeCapFlooredLeg(vars.startDate, vars.length, caps, floors, + vars.volatility, gearing_n, spread_n); + Swap collarLeg_n1 = new Swap(fixedLeg, collaredLeg_n); collarLeg_n1.setPricingEngine(engine); - Collar collar_n = new Collar(floatLeg,new InitializedList(1,(floorstrike-spread_n)/gearing_n), - new InitializedList(1,(capstrike-spread_n)/gearing_n)); + Collar collar_n = new Collar(floatLeg, new InitializedList(1, (floorstrike - spread_n) / gearing_n), + new InitializedList(1, (capstrike - spread_n) / gearing_n)); collar_n.setPricingEngine(vars.makeEngine(vars.volatility)); npvVanilla = vanillaLeg_n.NPV(); npvCollaredLeg = collarLeg_n1.NPV(); npvCollar = collar_n.NPV(); - error = Math.Abs(npvCollaredLeg - (npvVanilla - gearing_n*npvCollar)); - if (error>tolerance) + error = Math.Abs(npvCollaredLeg - (npvVanilla - gearing_n * npvCollar)); + if (error > tolerance) { QAssert.Fail("\nCollared Leg: gearing=" + gearing_n + ", " - + "spread= " + spread_n*100 + "%, strike=" - + floorstrike*100 + "% and " + capstrike*100 - + "%, " - + "effective strike=" + (floorstrike-spread_n)/gearing_n*100 - + "% and " + (capstrike-spread_n)/gearing_n*100 - + "%\n" + - " Collared Floating Leg NPV: " + npvCollaredLeg - + "\n" + - " Floating Leg NPV - Collar NPV: " + (npvVanilla - gearing_n*npvCollar) - + "\n" + - " Diff: " + error ); + + "spread= " + spread_n * 100 + "%, strike=" + + floorstrike * 100 + "% and " + capstrike * 100 + + "%, " + + "effective strike=" + (floorstrike - spread_n) / gearing_n * 100 + + "% and " + (capstrike - spread_n) / gearing_n * 100 + + "%\n" + + " Collared Floating Leg NPV: " + npvCollaredLeg + + "\n" + + " Floating Leg NPV - Collar NPV: " + (npvVanilla - gearing_n * npvCollar) + + "\n" + + " Diff: " + error); } } } diff --git a/tests/QLNet.Tests/T_CashFlows.cs b/tests/QLNet.Tests/T_CashFlows.cs index 861c30e98..eaf71356d 100644 --- a/tests/QLNet.Tests/T_CashFlows.cs +++ b/tests/QLNet.Tests/T_CashFlows.cs @@ -6,7 +6,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -20,7 +20,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; using System; @@ -38,8 +38,8 @@ private void CHECK_INCLUSION(int n, int days, bool expected, List leg, if ((!leg[n].hasOccurred(today + days)) != expected) { QAssert.Fail("cashflow at T+" + n + " " - + (expected ? "not" : "") + "included" - + " at T+" + days); + + (expected ? "not" : "") + "included" + + " at T+" + days); } } @@ -51,17 +51,17 @@ private void CHECK_NPV(bool includeRef, double expected, InterestRate no_discoun if (Math.Abs(NPV - expected) > 1e-6) { QAssert.Fail("NPV mismatch:\n" - + " calculated: " + NPV + "\n" - + " expected: " + expected); + + " calculated: " + NPV + "\n" + + " expected: " + expected); } } while (false); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testSettings() { @@ -179,9 +179,9 @@ public void testSettings() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testAccessViolation() { @@ -212,8 +212,8 @@ public void testAccessViolation() Date endDate = new Date(20, Month.December, 2013); double spread = 0.0115; IborCouponPricer pricer = new BlackIborCouponPricer(vol); - FloatingRateCoupon coupon = new FloatingRateCoupon( payDate, 100, startDate, endDate, 2, - index3m, 1.0, spread / 100); + FloatingRateCoupon coupon = new FloatingRateCoupon(payDate, 100, startDate, endDate, 2, + index3m, 1.0, spread / 100); coupon.setPricer(pricer); try @@ -229,27 +229,27 @@ public void testAccessViolation() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testDefaultSettlementDate() { // Testing default evaluation date in cashflows methods... Date today = Settings.evaluationDate(); Schedule schedule = new - MakeSchedule() - .from(today - new Period(2, TimeUnit.Months)).to(today + new Period(4, TimeUnit.Months)) - .withFrequency(Frequency.Semiannual) - .withCalendar(new TARGET()) - .withConvention(BusinessDayConvention.Unadjusted) - .backwards().value(); + MakeSchedule() + .from(today - new Period(2, TimeUnit.Months)).to(today + new Period(4, TimeUnit.Months)) + .withFrequency(Frequency.Semiannual) + .withCalendar(new TARGET()) + .withConvention(BusinessDayConvention.Unadjusted) + .backwards().value(); List leg = new FixedRateLeg(schedule) - .withCouponRates(0.03, new Actual360()) - .withPaymentCalendar(new TARGET()) - .withNotionals(100.0) - .withPaymentAdjustment(BusinessDayConvention.Following); + .withCouponRates(0.03, new Actual360()) + .withPaymentCalendar(new TARGET()) + .withNotionals(100.0) + .withPaymentAdjustment(BusinessDayConvention.Following); double accruedPeriod = CashFlows.accruedPeriod(leg, false); if (accruedPeriod == 0.0) @@ -265,28 +265,28 @@ public void testDefaultSettlementDate() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testNullFixingDays() { // Testing ibor leg construction with null fixing days... Date today = Settings.evaluationDate(); Schedule schedule = new - MakeSchedule() - .from(today - new Period(2, TimeUnit.Months)).to(today + new Period(4, TimeUnit.Months)) - .withFrequency(Frequency.Semiannual) - .withCalendar(new TARGET()) - .withConvention(BusinessDayConvention.Following) - .backwards().value(); + MakeSchedule() + .from(today - new Period(2, TimeUnit.Months)).to(today + new Period(4, TimeUnit.Months)) + .withFrequency(Frequency.Semiannual) + .withCalendar(new TARGET()) + .withConvention(BusinessDayConvention.Following) + .backwards().value(); IborIndex index = new USDLibor(new Period(6, TimeUnit.Months)); List leg = new IborLeg(schedule, index) - // this can happen with default values, and caused an - // exception when the null was not managed properly - .withFixingDays(null) - .withNotionals(100.0); + // this can happen with default values, and caused an + // exception when the null was not managed properly + .withFixingDays(null) + .withNotionals(100.0); } } } diff --git a/tests/QLNet.Tests/T_CliquetOption.cs b/tests/QLNet.Tests/T_CliquetOption.cs index 18b967e2f..3fec7058e 100644 --- a/tests/QLNet.Tests/T_CliquetOption.cs +++ b/tests/QLNet.Tests/T_CliquetOption.cs @@ -1,22 +1,22 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; using System; @@ -29,39 +29,39 @@ namespace TestSuite #endif public class T_CliquetOption { - private void REPORT_FAILURE( string greekName, - StrikedTypePayoff payoff, - Exercise exercise, - double s, - double q, - double r, - Date today, - double v, - double expected, - double calculated, - double error, - double tolerance ) + private void REPORT_FAILURE(string greekName, + StrikedTypePayoff payoff, + Exercise exercise, + double s, + double q, + double r, + Date today, + double v, + double expected, + double calculated, + double error, + double tolerance) { - QAssert.Fail( payoff.optionType() + " option :\n" - + " spot value: " + s + "\n" - + " moneyness: " + payoff.strike() + "\n" - + " dividend yield: " + q + "\n" - + " risk-free rate: " + r + "\n" - + " reference date: " + today + "\n" - + " maturity: " + exercise.lastDate() + "\n" - + " volatility: " + v + "\n\n" - + " expected " + greekName + ": " + expected + "\n" - + " calculated " + greekName + ": " + calculated + "\n" - + " error: " + error + "\n" - + " tolerance: " + tolerance ); + QAssert.Fail(payoff.optionType() + " option :\n" + + " spot value: " + s + "\n" + + " moneyness: " + payoff.strike() + "\n" + + " dividend yield: " + q + "\n" + + " risk-free rate: " + r + "\n" + + " reference date: " + today + "\n" + + " maturity: " + exercise.lastDate() + "\n" + + " volatility: " + v + "\n\n" + + " expected " + greekName + ": " + expected + "\n" + + " calculated " + greekName + ": " + calculated + "\n" + + " error: " + error + "\n" + + " tolerance: " + tolerance); } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testValues() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testValues() { // Testing Cliquet option values @@ -97,37 +97,37 @@ public void testValues() double calculated = option.NPV(); double expected = 4.4064; // Haug, p.37 - double error = Math.Abs(calculated-expected); + double error = Math.Abs(calculated - expected); double tolerance = 1e-4; - if (error > tolerance) + if (error > tolerance) { REPORT_FAILURE("value", payoff, exercise, spot.value(), - qRate.value(), rRate.value(), today, - vol.value(), expected, calculated, - error, tolerance); + qRate.value(), rRate.value(), today, + vol.value(), expected, calculated, + error, tolerance); } } - - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testGreeks() + +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testGreeks() { // Testing Cliquet option greek - testOptionGreeks( process => new AnalyticCliquetEngine( process ) ); + testOptionGreeks(process => new AnalyticCliquetEngine(process)); } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif public void testPerformanceGreeks() { // Testing Performance option greek - testOptionGreeks( process => new AnalyticPerformanceEngine( process ) ); + testOptionGreeks(process => new AnalyticPerformanceEngine(process)); } private void testOptionGreeks(ForwardVanillaEngine.GetOriginalEngine getEngine) @@ -135,9 +135,9 @@ private void testOptionGreeks(ForwardVanillaEngine.GetOriginalEngine getEngine) SavedSettings backup = new SavedSettings(); - Dictionary calculated = new Dictionary(), - expected = new Dictionary(), - tolerance = new Dictionary(); + Dictionary calculated = new Dictionary(), + expected = new Dictionary(), + tolerance = new Dictionary(); tolerance["delta"] = 1.0e-5; tolerance["gamma"] = 1.0e-5; tolerance["theta"] = 1.0e-5; @@ -166,19 +166,19 @@ private void testOptionGreeks(ForwardVanillaEngine.GetOriginalEngine getEngine) SimpleQuote vol = new SimpleQuote(0.0); Handle volTS = new Handle(Utilities.flatVol(vol, dc)); - BlackScholesMertonProcess process = new BlackScholesMertonProcess(new Handle(spot),qTS, rTS, volTS); + BlackScholesMertonProcess process = new BlackScholesMertonProcess(new Handle(spot), qTS, rTS, volTS); - for (int i=0; i reset = new List(); for (Date d = today + new Period(frequencies[kk]); @@ -186,18 +186,18 @@ private void testOptionGreeks(ForwardVanillaEngine.GetOriginalEngine getEngine) d += new Period(frequencies[kk])) reset.Add(d); - IPricingEngine engine = getEngine( process ); + IPricingEngine engine = getEngine(process); CliquetOption option = new CliquetOption(payoff, maturity, reset); option.setPricingEngine(engine); - for (int l=0; l spot.value()*1.0e-5) + if (value > spot.value() * 1.0e-5) { // perturb spot and get delta and gamma - double du = u*1.0e-4; - spot.setValue(u+du); + double du = u * 1.0e-4; + spot.setValue(u + du); double value_p = option.NPV(), - delta_p = option.delta(); - spot.setValue(u-du); + delta_p = option.delta(); + spot.setValue(u - du); double value_m = option.NPV(), - delta_m = option.delta(); + delta_m = option.delta(); spot.setValue(u); - expected["delta"] = (value_p - value_m)/(2*du); - expected["gamma"] = (delta_p - delta_m)/(2*du); + expected["delta"] = (value_p - value_m) / (2 * du); + expected["gamma"] = (delta_p - delta_m) / (2 * du); // perturb rates and get rho and dividend rho - double dr = r*1.0e-4; - rRate.setValue(r+dr); + double dr = r * 1.0e-4; + rRate.setValue(r + dr); value_p = option.NPV(); - rRate.setValue(r-dr); + rRate.setValue(r - dr); value_m = option.NPV(); rRate.setValue(r); - expected["rho"] = (value_p - value_m)/(2*dr); + expected["rho"] = (value_p - value_m) / (2 * dr); - double dq = q*1.0e-4; - qRate.setValue(q+dq); + double dq = q * 1.0e-4; + qRate.setValue(q + dq); value_p = option.NPV(); - qRate.setValue(q-dq); + qRate.setValue(q - dq); value_m = option.NPV(); qRate.setValue(q); - expected["divRho"] = (value_p - value_m)/(2*dq); + expected["divRho"] = (value_p - value_m) / (2 * dq); // perturb volatility and get vega - double dv = v*1.0e-4; - vol.setValue(v+dv); + double dv = v * 1.0e-4; + vol.setValue(v + dv); value_p = option.NPV(); - vol.setValue(v-dv); + vol.setValue(v - dv); value_m = option.NPV(); vol.setValue(v); - expected["vega"] = (value_p - value_m)/(2*dv); + expected["vega"] = (value_p - value_m) / (2 * dv); // perturb date and get theta - double dT = dc.yearFraction(today-1, today+1); - Settings.setEvaluationDate(today-1); + double dT = dc.yearFraction(today - 1, today + 1); + Settings.setEvaluationDate(today - 1); value_m = option.NPV(); - Settings.setEvaluationDate(today+1); + Settings.setEvaluationDate(today + 1); value_p = option.NPV(); Settings.setEvaluationDate(today); - expected["theta"] = (value_p - value_m)/dT; + expected["theta"] = (value_p - value_m) / dT; // compare foreach (var it in calculated) { String greek = it.Key; double expct = expected [greek], - calcl = calculated[greek], - tol = tolerance [greek]; - double error = Utilities.relativeError(expct,calcl,u); - if (error>tol) + calcl = calculated[greek], + tol = tolerance [greek]; + double error = Utilities.relativeError(expct, calcl, u); + if (error > tol) { REPORT_FAILURE(greek, payoff, maturity, u, q, r, today, v, diff --git a/tests/QLNet.Tests/T_Cms.cs b/tests/QLNet.Tests/T_Cms.cs index 02870cb91..bc4d969f4 100644 --- a/tests/QLNet.Tests/T_Cms.cs +++ b/tests/QLNet.Tests/T_Cms.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -18,7 +18,7 @@ #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -54,28 +54,28 @@ public CommonVars() Calendar calendar = new TARGET(); - Date referenceDate = calendar.adjust( Date.Today ); - Settings.setEvaluationDate( referenceDate ); + Date referenceDate = calendar.adjust(Date.Today); + Settings.setEvaluationDate(referenceDate); termStructure = new RelinkableHandle(); - termStructure.linkTo( Utilities.flatRate( referenceDate, 0.05, new Actual365Fixed() ) ); + termStructure.linkTo(Utilities.flatRate(referenceDate, 0.05, new Actual365Fixed())); // ATM Volatility structure List atmOptionTenors = new List(); - atmOptionTenors.Add( new Period( 1, TimeUnit.Months ) ); - atmOptionTenors.Add( new Period( 6, TimeUnit.Months ) ); - atmOptionTenors.Add( new Period( 1, TimeUnit.Years ) ); - atmOptionTenors.Add( new Period( 5, TimeUnit.Years ) ); - atmOptionTenors.Add( new Period( 10, TimeUnit.Years ) ); - atmOptionTenors.Add( new Period( 30, TimeUnit.Years ) ); + atmOptionTenors.Add(new Period(1, TimeUnit.Months)); + atmOptionTenors.Add(new Period(6, TimeUnit.Months)); + atmOptionTenors.Add(new Period(1, TimeUnit.Years)); + atmOptionTenors.Add(new Period(5, TimeUnit.Years)); + atmOptionTenors.Add(new Period(10, TimeUnit.Years)); + atmOptionTenors.Add(new Period(30, TimeUnit.Years)); List atmSwapTenors = new List(); - atmSwapTenors.Add( new Period( 1, TimeUnit.Years ) ); - atmSwapTenors.Add( new Period( 5, TimeUnit.Years ) ); - atmSwapTenors.Add( new Period( 10, TimeUnit.Years ) ); - atmSwapTenors.Add( new Period( 30, TimeUnit.Years ) ); + atmSwapTenors.Add(new Period(1, TimeUnit.Years)); + atmSwapTenors.Add(new Period(5, TimeUnit.Years)); + atmSwapTenors.Add(new Period(10, TimeUnit.Years)); + atmSwapTenors.Add(new Period(30, TimeUnit.Years)); - Matrix m = new Matrix( atmOptionTenors.Count, atmSwapTenors.Count ); + Matrix m = new Matrix(atmOptionTenors.Count, atmSwapTenors.Count); m[0, 0] = 0.1300; m[0, 1] = 0.1560; m[0, 2] = 0.1390; m[0, 3] = 0.1220; m[1, 0] = 0.1440; m[1, 1] = 0.1580; m[1, 2] = 0.1460; m[1, 3] = 0.1260; m[2, 0] = 0.1600; m[2, 1] = 0.1590; m[2, 2] = 0.1470; m[2, 3] = 0.1290; @@ -84,30 +84,30 @@ public CommonVars() m[5, 0] = 0.1130; m[5, 1] = 0.1090; m[5, 2] = 0.1070; m[5, 3] = 0.0930; atmVol = new Handle( - new SwaptionVolatilityMatrix( calendar, BusinessDayConvention.Following, atmOptionTenors, - atmSwapTenors, m, new Actual365Fixed() ) ); + new SwaptionVolatilityMatrix(calendar, BusinessDayConvention.Following, atmOptionTenors, + atmSwapTenors, m, new Actual365Fixed())); // Vol cubes List optionTenors = new List(); - optionTenors.Add( new Period( 1, TimeUnit.Years ) ); - optionTenors.Add( new Period( 10, TimeUnit.Years ) ); - optionTenors.Add( new Period( 30, TimeUnit.Years ) ); + optionTenors.Add(new Period(1, TimeUnit.Years)); + optionTenors.Add(new Period(10, TimeUnit.Years)); + optionTenors.Add(new Period(30, TimeUnit.Years)); List swapTenors = new List(); - swapTenors.Add( new Period( 2, TimeUnit.Years ) ); - swapTenors.Add( new Period( 10, TimeUnit.Years ) ); - swapTenors.Add( new Period( 30, TimeUnit.Years ) ); + swapTenors.Add(new Period(2, TimeUnit.Years)); + swapTenors.Add(new Period(10, TimeUnit.Years)); + swapTenors.Add(new Period(30, TimeUnit.Years)); List strikeSpreads = new List(); - strikeSpreads.Add( -0.020 ); - strikeSpreads.Add( -0.005 ); - strikeSpreads.Add( +0.000 ); - strikeSpreads.Add( +0.005 ); - strikeSpreads.Add( +0.020 ); + strikeSpreads.Add(-0.020); + strikeSpreads.Add(-0.005); + strikeSpreads.Add(+0.000); + strikeSpreads.Add(+0.005); + strikeSpreads.Add(+0.020); int nRows = optionTenors.Count * swapTenors.Count; int nCols = strikeSpreads.Count; - Matrix volSpreadsMatrix = new Matrix( nRows, nCols ); + Matrix volSpreadsMatrix = new Matrix(nRows, nCols); volSpreadsMatrix[0, 0] = 0.0599; volSpreadsMatrix[0, 1] = 0.0049; volSpreadsMatrix[0, 2] = 0.0000; @@ -162,50 +162,50 @@ public CommonVars() volSpreadsMatrix[8, 3] = -0.0042; volSpreadsMatrix[8, 4] = -0.0020; - List>> volSpreads = new InitializedList>>( nRows ); - for ( int i = 0; i < nRows; ++i ) + List>> volSpreads = new InitializedList>>(nRows); + for (int i = 0; i < nRows; ++i) { - volSpreads[i] = new InitializedList>( nCols ); - for ( int j = 0; j < nCols; ++j ) + volSpreads[i] = new InitializedList>(nCols); + for (int j = 0; j < nCols; ++j) { - volSpreads[i][j] = new Handle( new SimpleQuote( volSpreadsMatrix[i, j] ) ); + volSpreads[i][j] = new Handle(new SimpleQuote(volSpreadsMatrix[i, j])); } } - iborIndex = new Euribor6M( termStructure ); - SwapIndex swapIndexBase = new EuriborSwapIsdaFixA( new Period( 10, TimeUnit.Years ), termStructure ); - SwapIndex shortSwapIndexBase = new EuriborSwapIsdaFixA( new Period( 2, TimeUnit.Years ), termStructure ); + iborIndex = new Euribor6M(termStructure); + SwapIndex swapIndexBase = new EuriborSwapIsdaFixA(new Period(10, TimeUnit.Years), termStructure); + SwapIndex shortSwapIndexBase = new EuriborSwapIsdaFixA(new Period(2, TimeUnit.Years), termStructure); bool vegaWeightedSmileFit = false; SabrVolCube2 = new Handle( - new SwaptionVolCube2( atmVol, - optionTenors, - swapTenors, - strikeSpreads, - volSpreads, - swapIndexBase, - shortSwapIndexBase, - vegaWeightedSmileFit ) ); + new SwaptionVolCube2(atmVol, + optionTenors, + swapTenors, + strikeSpreads, + volSpreads, + swapIndexBase, + shortSwapIndexBase, + vegaWeightedSmileFit)); SabrVolCube2.link.enableExtrapolation(); - List>> guess = new InitializedList>>( nRows ); - for ( int i = 0; i < nRows; ++i ) + List>> guess = new InitializedList>>(nRows); + for (int i = 0; i < nRows; ++i) { - guess[i] = new InitializedList>( 4 ); - guess[i][0] = new Handle( new SimpleQuote( 0.2 ) ); - guess[i][1] = new Handle( new SimpleQuote( 0.5 ) ); - guess[i][2] = new Handle( new SimpleQuote( 0.4 ) ); - guess[i][3] = new Handle( new SimpleQuote( 0.0 ) ); + guess[i] = new InitializedList>(4); + guess[i][0] = new Handle(new SimpleQuote(0.2)); + guess[i][1] = new Handle(new SimpleQuote(0.5)); + guess[i][2] = new Handle(new SimpleQuote(0.4)); + guess[i][3] = new Handle(new SimpleQuote(0.0)); } - List isParameterFixed = new InitializedList( 4, false ); + List isParameterFixed = new InitializedList(4, false); isParameterFixed[1] = true; // FIXME bool isAtmCalibrated = false; SabrVolCube1 = new Handle( - new SwaptionVolCube1x( atmVol, + new SwaptionVolCube1x(atmVol, optionTenors, swapTenors, strikeSpreads, @@ -215,72 +215,72 @@ public CommonVars() vegaWeightedSmileFit, guess, isParameterFixed, - isAtmCalibrated ) ); + isAtmCalibrated)); SabrVolCube1.link.enableExtrapolation(); yieldCurveModels = new List(); - yieldCurveModels.Add( GFunctionFactory.YieldCurveModel.Standard ); - yieldCurveModels.Add( GFunctionFactory.YieldCurveModel.ExactYield ); - yieldCurveModels.Add( GFunctionFactory.YieldCurveModel.ParallelShifts ); - yieldCurveModels.Add( GFunctionFactory.YieldCurveModel.NonParallelShifts ); - yieldCurveModels.Add( GFunctionFactory.YieldCurveModel.NonParallelShifts ); // for linear tsr model + yieldCurveModels.Add(GFunctionFactory.YieldCurveModel.Standard); + yieldCurveModels.Add(GFunctionFactory.YieldCurveModel.ExactYield); + yieldCurveModels.Add(GFunctionFactory.YieldCurveModel.ParallelShifts); + yieldCurveModels.Add(GFunctionFactory.YieldCurveModel.NonParallelShifts); + yieldCurveModels.Add(GFunctionFactory.YieldCurveModel.NonParallelShifts); // for linear tsr model - Handle zeroMeanRev = new Handle( new SimpleQuote( 0.0 ) ); + Handle zeroMeanRev = new Handle(new SimpleQuote(0.0)); numericalPricers = new List(); analyticPricers = new List(); - for ( int j = 0; j < yieldCurveModels.Count; ++j ) + for (int j = 0; j < yieldCurveModels.Count; ++j) { - if ( j < yieldCurveModels.Count - 1 ) - numericalPricers.Add( new NumericHaganPricer( atmVol, yieldCurveModels[j], zeroMeanRev ) ); + if (j < yieldCurveModels.Count - 1) + numericalPricers.Add(new NumericHaganPricer(atmVol, yieldCurveModels[j], zeroMeanRev)); else - numericalPricers.Add( new LinearTsrPricer( atmVol, zeroMeanRev ) ); + numericalPricers.Add(new LinearTsrPricer(atmVol, zeroMeanRev)); - analyticPricers.Add( new AnalyticHaganPricer( atmVol, yieldCurveModels[j], zeroMeanRev ) ); + analyticPricers.Add(new AnalyticHaganPricer(atmVol, yieldCurveModels[j], zeroMeanRev)); } } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testFairRate() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testFairRate() { // Testing Hagan-pricer flat-vol equivalence for coupons CommonVars vars = new CommonVars(); SwapIndex swapIndex = new SwapIndex("EuriborSwapIsdaFixA", - new Period(10,TimeUnit.Years), + new Period(10, TimeUnit.Years), vars.iborIndex.fixingDays(), vars.iborIndex.currency(), vars.iborIndex.fixingCalendar(), - new Period(1,TimeUnit.Years), - BusinessDayConvention.Unadjusted, + new Period(1, TimeUnit.Years), + BusinessDayConvention.Unadjusted, vars.iborIndex.dayCounter(),//?? vars.iborIndex); - + // FIXME //shared_ptr swapIndex(new // EuriborSwapIsdaFixA(10*Years, vars.iborIndex->termStructure())); - Date startDate = vars.termStructure.link.referenceDate() + new Period(20,TimeUnit.Years); - Date paymentDate = startDate + new Period(1,TimeUnit.Years); + Date startDate = vars.termStructure.link.referenceDate() + new Period(20, TimeUnit.Years); + Date paymentDate = startDate + new Period(1, TimeUnit.Years); Date endDate = paymentDate; double nominal = 1.0; double? infiniteCap = null; double? infiniteFloor = null; double gearing = 1.0; double spread = 0.0; - CappedFlooredCmsCoupon coupon = new CappedFlooredCmsCoupon(nominal ,paymentDate, - startDate, endDate, - swapIndex.fixingDays(), swapIndex, - gearing, spread, - infiniteCap, infiniteFloor, - startDate, endDate, - vars.iborIndex.dayCounter()); - - for (int j=0; j tol) QAssert.Fail("\nCoupon payment date: " + paymentDate + - "\nCoupon start date: " + startDate + - "\nCoupon floor: " + (infiniteFloor) + - "\nCoupon gearing: " + (gearing) + - "\nCoupon swap index: " + swapIndex.name() + - "\nCoupon spread: " + (spread) + - "\nCoupon cap: " + (infiniteCap) + - "\nCoupon DayCounter: " + vars.iborIndex.dayCounter()+ - "\nYieldCurve Model: " + vars.yieldCurveModels[j] + - "\nNumerical Pricer: " + (rate0) + (linearTsr ? " (Linear TSR Model)" : "") + - "\nAnalytic Pricer: " + (rate1) + - "\ndifference: " + (difference) + - "\ntolerance: " + (tol)); - } + "\nCoupon start date: " + startDate + + "\nCoupon floor: " + (infiniteFloor) + + "\nCoupon gearing: " + (gearing) + + "\nCoupon swap index: " + swapIndex.name() + + "\nCoupon spread: " + (spread) + + "\nCoupon cap: " + (infiniteCap) + + "\nCoupon DayCounter: " + vars.iborIndex.dayCounter() + + "\nYieldCurve Model: " + vars.yieldCurveModels[j] + + "\nNumerical Pricer: " + (rate0) + (linearTsr ? " (Linear TSR Model)" : "") + + "\nAnalytic Pricer: " + (rate1) + + "\ndifference: " + (difference) + + "\ntolerance: " + (tol)); + } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testCmsSwap() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testCmsSwap() { // Testing Hagan-pricer flat-vol equivalence for swaps CommonVars vars = new CommonVars(); SwapIndex swapIndex = new SwapIndex("EuriborSwapIsdaFixA", - new Period(10,TimeUnit.Years), + new Period(10, TimeUnit.Years), vars.iborIndex.fixingDays(), vars.iborIndex.currency(), vars.iborIndex.fixingCalendar(), - new Period(1,TimeUnit.Years), - BusinessDayConvention.Unadjusted, + new Period(1, TimeUnit.Years), + BusinessDayConvention.Unadjusted, vars.iborIndex.dayCounter(),//?? vars.iborIndex); // FIXME @@ -341,48 +341,48 @@ public void testCmsSwap() swapLengths.Add(10); int n = swapLengths.Count; List cms = new List(n); - for (int i=0; i tol) QAssert.Fail("\nLength in Years: " + swapLengths[sl] + - "\nswap index: " + swapIndex.name() + - "\nibor index: " + vars.iborIndex.name() + - "\nspread: " + (spread) + - "\nYieldCurve Model: " + vars.yieldCurveModels[j] + - "\nNumerical Pricer: " + (priceNum) + (linearTsr ? " (Linear TSR Model)" : "") + - "\nAnalytic Pricer: " + (priceAn) + - "\ndifference: " + (difference) + - "\ntolerance: " + (tol)); + "\nswap index: " + swapIndex.name() + + "\nibor index: " + vars.iborIndex.name() + + "\nspread: " + (spread) + + "\nYieldCurve Model: " + vars.yieldCurveModels[j] + + "\nNumerical Pricer: " + (priceNum) + (linearTsr ? " (Linear TSR Model)" : "") + + "\nAnalytic Pricer: " + (priceAn) + + "\ndifference: " + (difference) + + "\ntolerance: " + (tol)); } } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testParity() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testParity() { // Testing put-call parity for capped-floored CMS coupons @@ -393,10 +393,10 @@ public void testParity() swaptionVols.Add(vars.SabrVolCube1); swaptionVols.Add(vars.SabrVolCube2); - SwapIndex swapIndex = new EuriborSwapIsdaFixA(new Period(10,TimeUnit.Years), - vars.iborIndex.forwardingTermStructure()); - Date startDate = vars.termStructure.link.referenceDate() + new Period(20,TimeUnit.Years); - Date paymentDate = startDate + new Period(1,TimeUnit.Years); + SwapIndex swapIndex = new EuriborSwapIsdaFixA(new Period(10, TimeUnit.Years), + vars.iborIndex.forwardingTermStructure()); + Date startDate = vars.termStructure.link.referenceDate() + new Period(20, TimeUnit.Years); + Date paymentDate = startDate + new Period(1, TimeUnit.Years); Date endDate = paymentDate; double nominal = 1.0; double? infiniteCap = null; @@ -404,63 +404,63 @@ public void testParity() double gearing = 1.0; double spread = 0.0; double discount = vars.termStructure.link.discount(paymentDate); - CappedFlooredCmsCoupon swaplet = new CappedFlooredCmsCoupon(nominal , paymentDate, - startDate, endDate,swapIndex.fixingDays(),swapIndex,gearing, spread,infiniteCap, infiniteFloor, - startDate, endDate,vars.iborIndex.dayCounter()); - for (double strike = .02; strike<.12; strike+=0.05) + CappedFlooredCmsCoupon swaplet = new CappedFlooredCmsCoupon(nominal, paymentDate, + startDate, endDate, swapIndex.fixingDays(), swapIndex, gearing, spread, infiniteCap, infiniteFloor, + startDate, endDate, vars.iborIndex.dayCounter()); + for (double strike = .02; strike < .12; strike += 0.05) { - CappedFlooredCmsCoupon caplet = new CappedFlooredCmsCoupon(nominal ,paymentDate, - startDate, endDate,swapIndex.fixingDays(),swapIndex,gearing, spread,strike, infiniteFloor, - startDate, endDate,vars.iborIndex.dayCounter()); - CappedFlooredCmsCoupon floorlet = new CappedFlooredCmsCoupon(nominal , paymentDate, - startDate, endDate,swapIndex.fixingDays(),swapIndex,gearing, spread,infiniteCap, strike, - startDate, endDate,vars.iborIndex.dayCounter()); - - for (int i=0; i pricers = new List(2); pricers.Add(vars.numericalPricers[j]); pricers.Add(vars.analyticPricers[j]); - for (int k=0; k tol) QAssert.Fail("\nCoupon payment date: " + paymentDate + - "\nCoupon start date: " + startDate + - "\nCoupon gearing: " + (gearing) + - "\nCoupon swap index: " + swapIndex.name() + - "\nCoupon spread: " + (spread) + - "\nstrike: " + (strike) + - "\nCoupon DayCounter: " + vars.iborIndex.dayCounter() + - "\nYieldCurve Model: " + vars.yieldCurveModels[j] + - (k==0 ? "\nNumerical Pricer" : "\nAnalytic Pricer") + - (linearTsr ? " (Linear TSR Model)" : "") + - "\nSwaplet price: " + (swapletPrice) + - "\nCaplet price: " + (capletPrice) + - "\nFloorlet price: " + (floorletPrice) + - "\ndifference: " + difference + - "\ntolerance: " + (tol)); - + "\nCoupon start date: " + startDate + + "\nCoupon gearing: " + (gearing) + + "\nCoupon swap index: " + swapIndex.name() + + "\nCoupon spread: " + (spread) + + "\nstrike: " + (strike) + + "\nCoupon DayCounter: " + vars.iborIndex.dayCounter() + + "\nYieldCurve Model: " + vars.yieldCurveModels[j] + + (k == 0 ? "\nNumerical Pricer" : "\nAnalytic Pricer") + + (linearTsr ? " (Linear TSR Model)" : "") + + "\nSwaplet price: " + (swapletPrice) + + "\nCaplet price: " + (capletPrice) + + "\nFloorlet price: " + (floorletPrice) + + "\ndifference: " + difference + + "\ntolerance: " + (tol)); + } } - + } - + } } } diff --git a/tests/QLNet.Tests/T_CreditDefaultSwap.cs b/tests/QLNet.Tests/T_CreditDefaultSwap.cs index 0d174ce74..aa4acecde 100644 --- a/tests/QLNet.Tests/T_CreditDefaultSwap.cs +++ b/tests/QLNet.Tests/T_CreditDefaultSwap.cs @@ -6,7 +6,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -20,7 +20,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; using System; @@ -34,9 +34,9 @@ namespace TestSuite public class T_CreditDefaultSwap { #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testCachedValue() { @@ -65,7 +65,7 @@ public void testCachedValue() BusinessDayConvention convention = BusinessDayConvention.ModifiedFollowing; Schedule schedule = new Schedule(issueDate, maturity, new Period(frequency), calendar, - convention, convention, DateGeneration.Rule.Forward, false); + convention, convention, DateGeneration.Rule.Forward, false); // Build the CDS double fixedRate = 0.0120; @@ -74,7 +74,7 @@ public void testCachedValue() double recoveryRate = 0.4; CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate, - schedule, convention, dayCount, true, true); + schedule, convention, dayCount, true, true); cds.setPricingEngine(new MidPointCdsEngine(probabilityCurve, recoveryRate, discountCurve)); double npv = 295.0153398; @@ -97,7 +97,7 @@ public void testCachedValue() + " expected fair rate: " + fairRate); cds.setPricingEngine(new IntegralCdsEngine(new Period(1, TimeUnit.Days), probabilityCurve, - recoveryRate, discountCurve)); + recoveryRate, discountCurve)); calculatedNpv = cds.NPV(); calculatedFairRate = cds.fairSpread(); @@ -140,9 +140,9 @@ public void testCachedValue() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testCachedMarketValue() { @@ -254,7 +254,7 @@ public void testCachedMarketValue() double cdsNotional = 100.0; CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, cdsNotional, fixedRate, - schedule, cdsConvention, dayCount, true, true); + schedule, cdsConvention, dayCount, true, true); cds.setPricingEngine(new MidPointCdsEngine(piecewiseFlatHazardRate, recoveryRate, discountCurve)); double calculatedNpv = cds.NPV(); @@ -273,15 +273,15 @@ public void testCachedMarketValue() if (Math.Abs(fairRate - calculatedFairRate) > tolerance) QAssert.Fail("Failed to reproduce the fair rate for the given credit-default swap\n" - + " computed fair rate: " + calculatedFairRate + "\n" - + " Given fair rate: " + fairRate); + + " computed fair rate: " + calculatedFairRate + "\n" + + " Given fair rate: " + fairRate); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testImpliedHazardRate() { @@ -312,8 +312,8 @@ public void testImpliedHazardRate() RelinkableHandle probabilityCurve = new RelinkableHandle(); probabilityCurve.linkTo(new InterpolatedHazardRateCurve(dates, - hazardRates, - dayCounter)); + hazardRates, + dayCounter)); RelinkableHandle discountCurve = new RelinkableHandle(); discountCurve.linkTo(new FlatForward(today, 0.03, new Actual360())); @@ -332,33 +332,33 @@ public void testImpliedHazardRate() { Date maturity = calendar.advance(issueDate, n, TimeUnit.Years); Schedule schedule = new Schedule(issueDate, maturity, new Period(frequency), calendar, - convention, convention, - DateGeneration.Rule.Forward, false); + convention, convention, + DateGeneration.Rule.Forward, false); CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate, - schedule, convention, cdsDayCount, true, true); + schedule, convention, cdsDayCount, true, true); cds.setPricingEngine(new MidPointCdsEngine(probabilityCurve, recoveryRate, discountCurve)); double NPV = cds.NPV(); double flatRate = cds.impliedHazardRate(NPV, discountCurve, - dayCounter, - recoveryRate); + dayCounter, + recoveryRate); if (flatRate < h1 || flatRate > h2) { QAssert.Fail("implied hazard rate outside expected range\n" - + " maturity: " + n + " years\n" - + " expected minimum: " + h1 + "\n" - + " expected maximum: " + h2 + "\n" - + " implied rate: " + flatRate); + + " maturity: " + n + " years\n" + + " expected minimum: " + h1 + "\n" + + " expected maximum: " + h2 + "\n" + + " implied rate: " + flatRate); } if (n > 6 && flatRate < latestRate) { QAssert.Fail("implied hazard rate decreasing with swap maturity\n" - + " maturity: " + n + " years\n" - + " previous rate: " + latestRate + "\n" - + " implied rate: " + flatRate); + + " maturity: " + n + " years\n" + + " previous rate: " + latestRate + "\n" + + " implied rate: " + flatRate); } latestRate = flatRate; @@ -367,7 +367,7 @@ public void testImpliedHazardRate() probability.linkTo(new FlatHazardRate(today, new Handle(new SimpleQuote(flatRate)), dayCounter)); CreditDefaultSwap cds2 = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate, - schedule, convention, cdsDayCount, true, true); + schedule, convention, cdsDayCount, true, true); cds2.setPricingEngine(new MidPointCdsEngine(probability, recoveryRate, discountCurve)); double NPV2 = cds2.NPV(); @@ -375,17 +375,17 @@ public void testImpliedHazardRate() if (Math.Abs(NPV - NPV2) > tolerance) { QAssert.Fail("failed to reproduce NPV with implied rate\n" - + " expected: " + NPV + "\n" - + " calculated: " + NPV2); + + " expected: " + NPV + "\n" + + " calculated: " + NPV2); } } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testFairSpread() { @@ -415,11 +415,11 @@ public void testFairSpread() Schedule schedule = new MakeSchedule().from(issueDate) - .to(maturity) - .withFrequency(Frequency.Quarterly) - .withCalendar(calendar) - .withTerminationDateConvention(convention) - .withRule(DateGeneration.Rule.TwentiethIMM).value(); + .to(maturity) + .withFrequency(Frequency.Quarterly) + .withCalendar(calendar) + .withTerminationDateConvention(convention) + .withRule(DateGeneration.Rule.TwentiethIMM).value(); // Build the CDS double fixedRate = 0.001; @@ -430,13 +430,13 @@ public void testFairSpread() IPricingEngine engine = new MidPointCdsEngine(probabilityCurve, recoveryRate, discountCurve); CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate, - schedule, convention, dayCount, true, true); + schedule, convention, dayCount, true, true); cds.setPricingEngine(engine); double fairRate = cds.fairSpread(); CreditDefaultSwap fairCds = new CreditDefaultSwap(Protection.Side.Seller, notional, fairRate, - schedule, convention, dayCount, true, true); + schedule, convention, dayCount, true, true); fairCds.setPricingEngine(engine); double fairNPV = fairCds.NPV(); @@ -451,9 +451,9 @@ public void testFairSpread() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testFairUpfront() { @@ -482,11 +482,11 @@ public void testFairUpfront() Schedule schedule = new MakeSchedule().from(issueDate) - .to(maturity) - .withFrequency(Frequency.Quarterly) - .withCalendar(calendar) - .withTerminationDateConvention(convention) - .withRule(DateGeneration.Rule.TwentiethIMM).value(); + .to(maturity) + .withFrequency(Frequency.Quarterly) + .withCalendar(calendar) + .withTerminationDateConvention(convention) + .withRule(DateGeneration.Rule.TwentiethIMM).value(); // Build the CDS double fixedRate = 0.05; @@ -498,13 +498,13 @@ public void testFairUpfront() IPricingEngine engine = new MidPointCdsEngine(probabilityCurve, recoveryRate, discountCurve, true); CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, notional, upfront, fixedRate, - schedule, convention, dayCount, true, true); + schedule, convention, dayCount, true, true); cds.setPricingEngine(engine); double fairUpfront = cds.fairUpfront(); CreditDefaultSwap fairCds = new CreditDefaultSwap(Protection.Side.Seller, notional, - fairUpfront, fixedRate, schedule, convention, dayCount, true, true); + fairUpfront, fixedRate, schedule, convention, dayCount, true, true); fairCds.setPricingEngine(engine); double fairNPV = fairCds.NPV(); @@ -519,13 +519,13 @@ public void testFairUpfront() // same with null upfront to begin with upfront = 0.0; CreditDefaultSwap cds2 = new CreditDefaultSwap(Protection.Side.Seller, notional, upfront, fixedRate, - schedule, convention, dayCount, true, true); + schedule, convention, dayCount, true, true); cds2.setPricingEngine(engine); fairUpfront = cds2.fairUpfront(); CreditDefaultSwap fairCds2 = new CreditDefaultSwap(Protection.Side.Seller, notional, - fairUpfront, fixedRate, schedule, convention, dayCount, true, true); + fairUpfront, fixedRate, schedule, convention, dayCount, true, true); fairCds2.setPricingEngine(engine); fairNPV = fairCds2.NPV(); @@ -541,7 +541,7 @@ public void testFairUpfront() #if NET40 || NET45 [TestMethod()] #else - [Fact] + [Fact] #endif public void testIsdaEngine() { @@ -562,13 +562,14 @@ public void testIsdaEngine() 0.007163, 0.012413, 0.014, - 0.015488}; + 0.015488 + }; for (int i = 0; i < dep_tenors.Length ; i++) { - isdaRateHelpers.Add( new DepositRateHelper(dep_quotes[i], new Period(dep_tenors[i] , TimeUnit.Months), 2, - new WeekendsOnly(), BusinessDayConvention.ModifiedFollowing,false, new Actual360()) - ); + isdaRateHelpers.Add(new DepositRateHelper(dep_quotes[i], new Period(dep_tenors[i], TimeUnit.Months), 2, + new WeekendsOnly(), BusinessDayConvention.ModifiedFollowing, false, new Actual360()) + ); } int[] swap_tenors = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20, 25, 30 }; double[] swap_quotes = {0.011907, @@ -584,51 +585,54 @@ public void testIsdaEngine() 0.036217, 0.036981, 0.037246, - 0.037605}; + 0.037605 + }; - IborIndex isda_ibor = new IborIndex("IsdaIbor", new Period(3 , TimeUnit.Months), 2, new USDCurrency(), - new WeekendsOnly(),BusinessDayConvention.ModifiedFollowing, false, new Actual360()); + IborIndex isda_ibor = new IborIndex("IsdaIbor", new Period(3, TimeUnit.Months), 2, new USDCurrency(), + new WeekendsOnly(), BusinessDayConvention.ModifiedFollowing, false, new Actual360()); for (int i = 0; i < swap_tenors.Length ; i++) { - isdaRateHelpers.Add(new SwapRateHelper(swap_quotes[i], new Period(swap_tenors[i] ,TimeUnit.Years), - new WeekendsOnly(),Frequency.Semiannual,BusinessDayConvention.ModifiedFollowing, new Thirty360(), - isda_ibor)); + isdaRateHelpers.Add(new SwapRateHelper(swap_quotes[i], new Period(swap_tenors[i], TimeUnit.Years), + new WeekendsOnly(), Frequency.Semiannual, BusinessDayConvention.ModifiedFollowing, new Thirty360(), + isda_ibor)); } RelinkableHandle discountCurve = new RelinkableHandle(); discountCurve.linkTo(new PiecewiseYieldCurve(0, new WeekendsOnly(), isdaRateHelpers, - new Actual365Fixed())); + new Actual365Fixed())); RelinkableHandle probabilityCurve = new RelinkableHandle(); Date[] termDates = { new Date(20, Month.June, 2010), - new Date(20, Month.June, 2011), - new Date(20, Month.June, 2012), - new Date(20, Month.June, 2016), - new Date(20, Month.June, 2019)}; + new Date(20, Month.June, 2011), + new Date(20, Month.June, 2012), + new Date(20, Month.June, 2016), + new Date(20, Month.June, 2019) + }; double[] spreads = { 0.001, 0.1 }; double[] recoveries = { 0.2, 0.4 }; double[] markitValues = {97798.29358, //0.001 97776.11889, //0.001 - -914971.5977, //0.1 - -894985.6298, //0.1 + -914971.5977, //0.1 + -894985.6298, //0.1 186921.3594, //0.001 186839.8148, //0.001 - -1646623.672, //0.1 - -1579803.626, //0.1 + -1646623.672, //0.1 + -1579803.626, //0.1 274298.9203, 274122.4725, - -2279730.93, - -2147972.527, + -2279730.93, + -2147972.527, 592420.2297, 591571.2294, - -3993550.206, - -3545843.418, + -3993550.206, + -3545843.418, 797501.1422, 795915.9787, - -4702034.688, - -4042340.999}; + -4702034.688, + -4042340.999 + }; #if !QL_USE_INDEXED_COUPON double tolerance = 1.0e-2; //TODO Check calculation , tolerance must be 1.0e-6; #else @@ -648,22 +652,22 @@ altogether and rely on running them with indexed coupons { CreditDefaultSwap quotedTrade = new MakeCreditDefaultSwap(termDates[i], spreads[j]) - .withNominal(10000000.0).value(); + .withNominal(10000000.0).value(); double h = quotedTrade.impliedHazardRate(0.0, - discountCurve, - new Actual365Fixed(), - recoveries[k], - 1e-10, - PricingModel.ISDA); + discountCurve, + new Actual365Fixed(), + recoveries[k], + 1e-10, + PricingModel.ISDA); - probabilityCurve.linkTo( new FlatHazardRate(0, new WeekendsOnly(), h, new Actual365Fixed())); + probabilityCurve.linkTo(new FlatHazardRate(0, new WeekendsOnly(), h, new Actual365Fixed())); IsdaCdsEngine engine = new IsdaCdsEngine(probabilityCurve, recoveries[k], discountCurve); CreditDefaultSwap conventionalTrade = new MakeCreditDefaultSwap(termDates[i], 0.01) - .withNominal(10000000.0) - .withPricingEngine(engine).value(); + .withNominal(10000000.0) + .withPricingEngine(engine).value(); double x = conventionalTrade.notional().Value; double y = conventionalTrade.fairUpfront(); diff --git a/tests/QLNet.Tests/T_Dates.cs b/tests/QLNet.Tests/T_Dates.cs index c29cd728c..38e1154d4 100644 --- a/tests/QLNet.Tests/T_Dates.cs +++ b/tests/QLNet.Tests/T_Dates.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,7 +23,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -35,9 +35,9 @@ namespace TestSuite public class T_Dates { #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testECBDates() { @@ -48,42 +48,42 @@ public void testECBDates() QAssert.Fail("Empty EBC date vector"); int n = ECB.nextDates(Date.minDate()).Count; - + if (n != knownDates.Count) QAssert.Fail("NextDates(minDate) returns " + n + - " instead of " + knownDates.Count + " dates"); + " instead of " + knownDates.Count + " dates"); Date previousEcbDate = Date.minDate(), - currentEcbDate, ecbDateMinusOne; - - for (int i=0; i IMM.nextDate(counter, true)) QAssert.Fail(imm.DayOfWeek + " " + imm - + " is not less than or equal to the next future in the main cycle " - + IMM.nextDate(counter, true)); + + " is not less than or equal to the next future in the main cycle " + + IMM.nextDate(counter, true)); //// check that if counter is an IMM date, then imm==counter //if (IMM::isIMMdate(counter, false) && (imm!=counter)) @@ -149,16 +150,16 @@ public void testIMMDates() // check that for every date IMMdate is the inverse of IMMcode if (IMM.date(IMM.code(imm), counter) != imm) QAssert.Fail(IMM.code(imm) - + " at calendar day " + counter - + " is not the IMM code matching " + imm); + + " at calendar day " + counter + + " is not the IMM code matching " + imm); // check that for every date the 120 IMM codes refer to future dates for (int i = 0; i < 40; ++i) { if (IMM.date(IMMcodes[i], counter) < counter) QAssert.Fail(IMM.date(IMMcodes[i], counter) - + " is wrong for " + IMMcodes[i] - + " at reference date " + counter); + + " is wrong for " + IMMcodes[i] + + " at reference date " + counter); } counter = counter + 1; @@ -166,22 +167,22 @@ public void testIMMDates() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testConsistency() { //("Testing dates..."); int minDate = Date.minDate().serialNumber() + 1, - maxDate = Date.maxDate().serialNumber(); + maxDate = Date.maxDate().serialNumber(); int dyold = new Date(minDate - 1).DayOfYear, - dold = new Date(minDate - 1).Day, - mold = new Date(minDate - 1).Month, - yold = new Date(minDate - 1).Year, - wdold = new Date(minDate - 1).weekday(); + dold = new Date(minDate - 1).Day, + mold = new Date(minDate - 1).Month, + yold = new Date(minDate - 1).Year, + wdold = new Date(minDate - 1).weekday(); for (int i = minDate; i <= maxDate; i++) { @@ -191,9 +192,9 @@ public void testConsistency() // check serial number consistency if (serial != i) QAssert.Fail("inconsistent serial number:\n" - + " original: " + i + "\n" - + " date: " + t + "\n" - + " serial number: " + serial); + + " original: " + i + "\n" + + " date: " + t + "\n" + + " serial number: " + serial); int dy = t.DayOfYear, d = t.Day, @@ -206,33 +207,33 @@ public void testConsistency() (dy == 1 && dyold == 365 && !Date.IsLeapYear(yold)) || (dy == 1 && dyold == 366 && Date.IsLeapYear(yold)))) QAssert.Fail("wrong day of year increment: \n" - + " date: " + t + "\n" - + " day of year: " + dy + "\n" - + " previous: " + dyold); + + " date: " + t + "\n" + + " day of year: " + dy + "\n" + + " previous: " + dyold); dyold = dy; if (!((d == dold + 1 && m == mold && y == yold) || (d == 1 && m == mold + 1 && y == yold) || (d == 1 && m == 1 && y == yold + 1))) QAssert.Fail("wrong day,month,year increment: \n" - + " date: " + t + "\n" - + " day,month,year: " - + d + "," + m + "," + y + "\n" - + " previous: " - + dold + "," + mold + "," + yold); + + " date: " + t + "\n" + + " day,month,year: " + + d + "," + m + "," + y + "\n" + + " previous: " + + dold + "," + mold + "," + yold); dold = d; mold = m; yold = y; // check month definition if (m < 1 || m > 12) QAssert.Fail("invalid month: \n" - + " date: " + t + "\n" - + " month: " + m); + + " date: " + t + "\n" + + " month: " + m); // check day definition if (d < 1) QAssert.Fail("invalid day of month: \n" - + " date: " + t + "\n" - + " day: " + d); + + " date: " + t + "\n" + + " day: " + d); if (!((m == 1 && d <= 31) || (m == 2 && d <= 28) || (m == 2 && d == 29 && Date.IsLeapYear(y)) || @@ -247,16 +248,16 @@ public void testConsistency() (m == 11 && d <= 30) || (m == 12 && d <= 31))) QAssert.Fail("invalid day of month: \n" - + " date: " + t + "\n" - + " day: " + d); + + " date: " + t + "\n" + + " day: " + d); // check weekday definition if (!((wd == wdold + 1) || (wd == 1 && wdold == 7))) QAssert.Fail("invalid weekday: \n" - + " date: " + t + "\n" - + " weekday: " + wd + "\n" - + " previous: " + wdold); + + " date: " + t + "\n" + + " weekday: " + wd + "\n" + + " previous: " + wdold); wdold = wd; // create the same date with a different constructor @@ -265,74 +266,76 @@ public void testConsistency() serial = s.serialNumber(); if (serial != i) QAssert.Fail("inconsistent serial number:\n" - + " date: " + t + "\n" - + " serial number: " + i + "\n" - + " cloned date: " + s + "\n" - + " serial number: " + serial); + + " date: " + t + "\n" + + " serial number: " + i + "\n" + + " cloned date: " + s + "\n" + + " serial number: " + serial); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testASXDates() { //Testing ASX dates..."); - String[] ASXcodes = { - "F0", "G0", "H0", "J0", "K0", "M0", "N0", "Q0", "U0", "V0", "X0", "Z0", - "F1", "G1", "H1", "J1", "K1", "M1", "N1", "Q1", "U1", "V1", "X1", "Z1", - "F2", "G2", "H2", "J2", "K2", "M2", "N2", "Q2", "U2", "V2", "X2", "Z2", - "F3", "G3", "H3", "J3", "K3", "M3", "N3", "Q3", "U3", "V3", "X3", "Z3", - "F4", "G4", "H4", "J4", "K4", "M4", "N4", "Q4", "U4", "V4", "X4", "Z4", - "F5", "G5", "H5", "J5", "K5", "M5", "N5", "Q5", "U5", "V5", "X5", "Z5", - "F6", "G6", "H6", "J6", "K6", "M6", "N6", "Q6", "U6", "V6", "X6", "Z6", - "F7", "G7", "H7", "J7", "K7", "M7", "N7", "Q7", "U7", "V7", "X7", "Z7", - "F8", "G8", "H8", "J8", "K8", "M8", "N8", "Q8", "U8", "V8", "X8", "Z8", - "F9", "G9", "H9", "J9", "K9", "M9", "N9", "Q9", "U9", "V9", "X9", "Z9" }; + String[] ASXcodes = + { + "F0", "G0", "H0", "J0", "K0", "M0", "N0", "Q0", "U0", "V0", "X0", "Z0", + "F1", "G1", "H1", "J1", "K1", "M1", "N1", "Q1", "U1", "V1", "X1", "Z1", + "F2", "G2", "H2", "J2", "K2", "M2", "N2", "Q2", "U2", "V2", "X2", "Z2", + "F3", "G3", "H3", "J3", "K3", "M3", "N3", "Q3", "U3", "V3", "X3", "Z3", + "F4", "G4", "H4", "J4", "K4", "M4", "N4", "Q4", "U4", "V4", "X4", "Z4", + "F5", "G5", "H5", "J5", "K5", "M5", "N5", "Q5", "U5", "V5", "X5", "Z5", + "F6", "G6", "H6", "J6", "K6", "M6", "N6", "Q6", "U6", "V6", "X6", "Z6", + "F7", "G7", "H7", "J7", "K7", "M7", "N7", "Q7", "U7", "V7", "X7", "Z7", + "F8", "G8", "H8", "J8", "K8", "M8", "N8", "Q8", "U8", "V8", "X8", "Z8", + "F9", "G9", "H9", "J9", "K9", "M9", "N9", "Q9", "U9", "V9", "X9", "Z9" + }; Date counter = Date.minDate(); // 10 years of futures must not exceed Date::maxDate - Date last = Date.maxDate() - new Period(121 , TimeUnit.Months); + Date last = Date.maxDate() - new Period(121, TimeUnit.Months); Date asx; - while (counter <= last) + while (counter <= last) { asx = ASX.nextDate(counter, false); // check that asx is greater than counter if (asx <= counter) - QAssert.Fail( asx.weekday() + " " + asx + QAssert.Fail(asx.weekday() + " " + asx + " is not greater than " + counter.weekday() + " " + counter); // check that asx is an ASX date if (!ASX.isASXdate(asx, false)) - QAssert.Fail( asx.weekday() + " " + asx + QAssert.Fail(asx.weekday() + " " + asx + " is not an ASX date (calculated from " + counter.weekday() + " " + counter + ")"); // check that asx is <= to the next ASX date in the main cycle if (asx > ASX.nextDate(counter, true)) - QAssert.Fail( asx.weekday() + " " + asx - + " is not less than or equal to the next future in the main cycle " - + ASX.nextDate(counter, true)); + QAssert.Fail(asx.weekday() + " " + asx + + " is not less than or equal to the next future in the main cycle " + + ASX.nextDate(counter, true)); // check that for every date ASXdate is the inverse of ASXcode if (ASX.date(ASX.code(asx), counter) != asx) - QAssert.Fail( ASX.code(asx) + QAssert.Fail(ASX.code(asx) + " at calendar day " + counter + " is not the ASX code matching " + asx); // check that for every date the 120 ASX codes refer to future dates - for (int i = 0; i<120; ++i) + for (int i = 0; i < 120; ++i) { - if (ASX.date(ASXcodes[i], counter). - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,7 +22,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -61,93 +61,93 @@ public SingleCase(ActualActual.Convention convention, Date start, Date end, doub public double _result; } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testActualActual() { - SingleCase[] testCases = + SingleCase[] testCases = { // first example new SingleCase(ActualActual.Convention.ISDA, - new Date(1,Month.November,2003), new Date(1,Month.May,2004), + new Date(1, Month.November, 2003), new Date(1, Month.May, 2004), 0.497724380567), new SingleCase(ActualActual.Convention.ISMA, - new Date(1,Month.November,2003), new Date(1,Month.May,2004), - new Date(1,Month.November,2003), new Date(1,Month.May,2004), + new Date(1, Month.November, 2003), new Date(1, Month.May, 2004), + new Date(1, Month.November, 2003), new Date(1, Month.May, 2004), 0.500000000000), new SingleCase(ActualActual.Convention.AFB, - new Date(1,Month.November,2003), new Date(1,Month.May,2004), + new Date(1, Month.November, 2003), new Date(1, Month.May, 2004), 0.497267759563), // short first calculation period (first period) new SingleCase(ActualActual.Convention.ISDA, - new Date(1,Month.February,1999), new Date(1,Month.July,1999), + new Date(1, Month.February, 1999), new Date(1, Month.July, 1999), 0.410958904110), new SingleCase(ActualActual.Convention.ISMA, - new Date(1,Month.February,1999), new Date(1,Month.July,1999), - new Date(1,Month.July,1998), new Date(1,Month.July,1999), - 0.410958904110), + new Date(1, Month.February, 1999), new Date(1, Month.July, 1999), + new Date(1, Month.July, 1998), new Date(1, Month.July, 1999), + 0.410958904110), new SingleCase(ActualActual.Convention.AFB, - new Date(1,Month.February,1999), new Date(1,Month.July,1999), - 0.410958904110), + new Date(1, Month.February, 1999), new Date(1, Month.July, 1999), + 0.410958904110), // short first calculation period (second period) new SingleCase(ActualActual.Convention.ISDA, - new Date(1,Month.July,1999), new Date(1,Month.July,2000), - 1.001377348600), + new Date(1, Month.July, 1999), new Date(1, Month.July, 2000), + 1.001377348600), new SingleCase(ActualActual.Convention.ISMA, - new Date(1,Month.July,1999), new Date(1,Month.July,2000), - new Date(1,Month.July,1999), new Date(1,Month.July,2000), - 1.000000000000), + new Date(1, Month.July, 1999), new Date(1, Month.July, 2000), + new Date(1, Month.July, 1999), new Date(1, Month.July, 2000), + 1.000000000000), new SingleCase(ActualActual.Convention.AFB, - new Date(1,Month.July,1999), new Date(1,Month.July,2000), - 1.000000000000), + new Date(1, Month.July, 1999), new Date(1, Month.July, 2000), + 1.000000000000), // long first calculation period (first period) new SingleCase(ActualActual.Convention.ISDA, - new Date(15,Month.August,2002), new Date(15,Month.July,2003), - 0.915068493151), + new Date(15, Month.August, 2002), new Date(15, Month.July, 2003), + 0.915068493151), new SingleCase(ActualActual.Convention.ISMA, - new Date(15,Month.August,2002), new Date(15,Month.July,2003), - new Date(15,Month.January,2003), new Date(15,Month.July,2003), - 0.915760869565), + new Date(15, Month.August, 2002), new Date(15, Month.July, 2003), + new Date(15, Month.January, 2003), new Date(15, Month.July, 2003), + 0.915760869565), new SingleCase(ActualActual.Convention.AFB, - new Date(15,Month.August,2002), new Date(15,Month.July,2003), - 0.915068493151), + new Date(15, Month.August, 2002), new Date(15, Month.July, 2003), + 0.915068493151), // long first calculation period (second period) /* Warning: the ISDA case is in disagreement with mktc1198.pdf */ new SingleCase(ActualActual.Convention.ISDA, - new Date(15,Month.July,2003), new Date(15,Month.January,2004), - 0.504004790778), + new Date(15, Month.July, 2003), new Date(15, Month.January, 2004), + 0.504004790778), new SingleCase(ActualActual.Convention.ISMA, - new Date(15,Month.July,2003), new Date(15,Month.January,2004), - new Date(15,Month.July,2003), new Date(15,Month.January,2004), - 0.500000000000), + new Date(15, Month.July, 2003), new Date(15, Month.January, 2004), + new Date(15, Month.July, 2003), new Date(15, Month.January, 2004), + 0.500000000000), new SingleCase(ActualActual.Convention.AFB, - new Date(15,Month.July,2003), new Date(15,Month.January,2004), - 0.504109589041), + new Date(15, Month.July, 2003), new Date(15, Month.January, 2004), + 0.504109589041), // short final calculation period (penultimate period) new SingleCase(ActualActual.Convention.ISDA, - new Date(30,Month.July,1999), new Date(30,Month.January,2000), - 0.503892506924), + new Date(30, Month.July, 1999), new Date(30, Month.January, 2000), + 0.503892506924), new SingleCase(ActualActual.Convention.ISMA, - new Date(30,Month.July,1999), new Date(30,Month.January,2000), - new Date(30,Month.July,1999), new Date(30,Month.January,2000), - 0.500000000000), + new Date(30, Month.July, 1999), new Date(30, Month.January, 2000), + new Date(30, Month.July, 1999), new Date(30, Month.January, 2000), + 0.500000000000), new SingleCase(ActualActual.Convention.AFB, - new Date(30,Month.July,1999), new Date(30,Month.January,2000), - 0.504109589041), + new Date(30, Month.July, 1999), new Date(30, Month.January, 2000), + 0.504109589041), // short final calculation period (final period) new SingleCase(ActualActual.Convention.ISDA, - new Date(30,Month.January,2000), new Date(30,Month.June,2000), - 0.415300546448), + new Date(30, Month.January, 2000), new Date(30, Month.June, 2000), + 0.415300546448), new SingleCase(ActualActual.Convention.ISMA, - new Date(30,Month.January,2000), new Date(30,Month.June,2000), - new Date(30,Month.January,2000), new Date(30,Month.July,2000), - 0.417582417582), + new Date(30, Month.January, 2000), new Date(30, Month.June, 2000), + new Date(30, Month.January, 2000), new Date(30, Month.July, 2000), + 0.417582417582), new SingleCase(ActualActual.Convention.AFB, - new Date(30,Month.January,2000), new Date(30,Month.June,2000), - 0.41530054644) - }; + new Date(30, Month.January, 2000), new Date(30, Month.June, 2000), + 0.41530054644) + }; int n = testCases.Length; /// sizeof(SingleCase); for (int i = 0; i < n; i++) @@ -162,15 +162,15 @@ public void testActualActual() if (Math.Abs(calculated - testCases[i]._result) > 1.0e-10) { QAssert.Fail(dayCounter.name() + "period: " + d1 + " to " + d2 + - " calculated: " + calculated + " expected: " + testCases[i]._result); + " calculated: " + calculated + " expected: " + testCases[i]._result); } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testSimple() { @@ -179,85 +179,86 @@ public void testSimple() int n = p.Length; // 4 years should be enough - Date first= new Date(1,Month.January,2002), last = new Date(31,Month.December,2005); + Date first = new Date(1, Month.January, 2002), last = new Date(31, Month.December, 2005); DayCounter dayCounter = new SimpleDayCounter(); - for (Date start = first; start <= last; start++) - { - for (int i=0; i 1.0e-12) - { - QAssert.Fail ("from " + start + " to " + end + - "Calculated: " + calculated + - "Expected: " + expected[i]); - } - } - } + for (Date start = first; start <= last; start++) + { + for (int i = 0; i < n; i++) + { + Date end = start + p[i]; + double calculated = dayCounter.yearFraction(start, end, null, null); + if (Math.Abs(calculated - expected[i]) > 1.0e-12) + { + QAssert.Fail("from " + start + " to " + end + + "Calculated: " + calculated + + "Expected: " + expected[i]); + } + } + } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testOne() { - Period[] p = { new Period(3,TimeUnit.Months), new Period(6,TimeUnit.Months), new Period(1,TimeUnit.Years) }; - double[] expected = { 1.0, 1.0, 1.0 }; - int n = p.Length; - - // 1 years should be enough - Date first = new Date(1,Month.January,2004), last= new Date (31,Month.December,2004); - DayCounter dayCounter = new OneDayCounter(); - - for (Date start = first; start <= last; start++) - { - for (int i=0; i 1.0e-12) - { - QAssert.Fail("from " + start + " to " + end + - "Calculated: " + calculated + - "Expected: " + expected[i]); - } - } - } + Period[] p = { new Period(3, TimeUnit.Months), new Period(6, TimeUnit.Months), new Period(1, TimeUnit.Years) }; + double[] expected = { 1.0, 1.0, 1.0 }; + int n = p.Length; + + // 1 years should be enough + Date first = new Date(1, Month.January, 2004), last = new Date(31, Month.December, 2004); + DayCounter dayCounter = new OneDayCounter(); + + for (Date start = first; start <= last; start++) + { + for (int i = 0; i < n; i++) + { + Date end = start + p[i]; + double calculated = dayCounter.yearFraction(start, end, null, null); + if (Math.Abs(calculated - expected[i]) > 1.0e-12) + { + QAssert.Fail("from " + start + " to " + end + + "Calculated: " + calculated + + "Expected: " + expected[i]); + } + } + } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testBusiness252() + public void testBusiness252() { // Testing business/252 day counter List testDates = new List(); - testDates.Add(new Date(1,Month.February,2002)); - testDates.Add(new Date(4,Month.February,2002)); - testDates.Add(new Date(16,Month.May,2003)); - testDates.Add(new Date(17,Month.December,2003)); - testDates.Add(new Date(17,Month.December,2004)); - testDates.Add(new Date(19,Month.December,2005)); - testDates.Add(new Date(2,Month.January,2006)); - testDates.Add(new Date(13,Month.March,2006)); - testDates.Add(new Date(15,Month.May,2006)); - testDates.Add(new Date(17,Month.March,2006)); - testDates.Add(new Date(15,Month.May,2006)); - testDates.Add(new Date(26,Month.July,2006)); - testDates.Add(new Date(28,Month.June,2007)); - testDates.Add(new Date(16,Month.September,2009)); - testDates.Add(new Date(26,Month.July,2016)); - - double[] expected = { + testDates.Add(new Date(1, Month.February, 2002)); + testDates.Add(new Date(4, Month.February, 2002)); + testDates.Add(new Date(16, Month.May, 2003)); + testDates.Add(new Date(17, Month.December, 2003)); + testDates.Add(new Date(17, Month.December, 2004)); + testDates.Add(new Date(19, Month.December, 2005)); + testDates.Add(new Date(2, Month.January, 2006)); + testDates.Add(new Date(13, Month.March, 2006)); + testDates.Add(new Date(15, Month.May, 2006)); + testDates.Add(new Date(17, Month.March, 2006)); + testDates.Add(new Date(15, Month.May, 2006)); + testDates.Add(new Date(26, Month.July, 2006)); + testDates.Add(new Date(28, Month.June, 2007)); + testDates.Add(new Date(16, Month.September, 2009)); + testDates.Add(new Date(26, Month.July, 2016)); + + double[] expected = + { 0.0039682539683, 1.2738095238095, 0.6031746031746, @@ -272,46 +273,46 @@ public void testBusiness252() 0.912698412698, 2.214285714286, 6.84126984127 - }; + }; DayCounter dayCounter1 = new Business252(new Brazil()); double calculated; - for (int i=1; i 1.0e-12) + calculated = dayCounter1.yearFraction(testDates[i - 1], testDates[i]); + if (Math.Abs(calculated - expected[i - 1]) > 1.0e-12) { - QAssert.Fail("from " + testDates[i-1] - + " to " + testDates[i] + ":\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected[i-1]); + QAssert.Fail("from " + testDates[i - 1] + + " to " + testDates[i] + ":\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected[i - 1]); } } DayCounter dayCounter2 = new Business252(); - for (int i=1; i 1.0e-12) + calculated = dayCounter2.yearFraction(testDates[i - 1], testDates[i]); + if (Math.Abs(calculated - expected[i - 1]) > 1.0e-12) { - QAssert.Fail("from " + testDates[i-1] - + " to " + testDates[i] + ":\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected[i-1]); - + QAssert.Fail("from " + testDates[i - 1] + + " to " + testDates[i] + ":\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected[i - 1]); + } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testThirty360_BondBasis() + public void testThirty360_BondBasis() { // Testing thirty/360 day counter (Bond Basis) // http://www.isda.org/c_and_a/docs/30-360-2006ISDADefs.xls @@ -338,7 +339,7 @@ public void testThirty360_BondBasis() testStartDates.Add(new Date(29, Month.February, 2008)); testEndDates.Add(new Date(31, Month.August, 2008)); testStartDates.Add(new Date(31, Month.August, 2008)); testEndDates.Add(new Date(28, Month.February, 2009)); testStartDates.Add(new Date(28, Month.February, 2009)); testEndDates.Add(new Date(31, Month.August, 2009)); - + //// ISDA - Example 3: Miscellaneous calculations testStartDates.Add(new Date(31, Month.January, 2006)); testEndDates.Add(new Date(28, Month.February, 2006)); testStartDates.Add(new Date(30, Month.January, 2006)); testEndDates.Add(new Date(28, Month.February, 2006)); @@ -357,30 +358,31 @@ public void testThirty360_BondBasis() testStartDates.Add(new Date(28, Month.February, 2008)); testEndDates.Add(new Date(31, Month.March, 2008)); int[] expected = { 180, 180, 180, 180, 180, 180, - 178, 183, 179, 182, 178, 183, - 28, 28, 5, 14, 30, 28, - 178, 180, 182, 183, 362, 363, - 359, 32, 33}; + 178, 183, 179, 182, 178, 183, + 28, 28, 5, 14, 30, 28, + 178, 180, 182, 183, 362, 363, + 359, 32, 33 + }; - for (int i = 0; i < testStartDates.Count; i++) + for (int i = 0; i < testStartDates.Count; i++) { calculated = dayCounter.dayCount(testStartDates[i], testEndDates[i]); - if (calculated != expected[i]) + if (calculated != expected[i]) { QAssert.Fail("from " + testStartDates[i] - + " to " + testEndDates[i] + ":\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected[i]); + + " to " + testEndDates[i] + ":\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected[i]); } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testThirty360_EurobondBasis() + public void testThirty360_EurobondBasis() { // Testing thirty/360 day counter (Eurobond Basis) // Source: ISDA 2006 Definitions 4.16 (g) @@ -432,53 +434,54 @@ public void testThirty360_EurobondBasis() testStartDates.Add(new Date(28, Month.February, 2008)); testEndDates.Add(new Date(31, Month.March, 2008)); int[] expected = { 180, 180, 180, 180, 180, 180, - 182, 178, 182, 179, 181, 178, - 182, 178, 182, 178, 182, 179, - 28, 28, 5, 14, 30, 28, - 178, 180, 182, 182, 362, 363, - 359, 32, 32 }; - - for (int i = 0; i < testStartDates.Count; i++) + 182, 178, 182, 179, 181, 178, + 182, 178, 182, 178, 182, 179, + 28, 28, 5, 14, 30, 28, + 178, 180, 182, 182, 362, 363, + 359, 32, 32 + }; + + for (int i = 0; i < testStartDates.Count; i++) { calculated = dayCounter.dayCount(testStartDates[i], testEndDates[i]); - if (calculated != expected[i]) + if (calculated != expected[i]) { QAssert.Fail("from " + testStartDates[i] - + " to " + testEndDates[i] + ":\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected[i]); + + " to " + testEndDates[i] + ":\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected[i]); } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testIntraday() + public void testIntraday() { // Testing intraday behavior of day counter Date d1 = new Date(12, Month.February, 2015); Date d2 = new Date(14, Month.February, 2015, 12, 34, 17, 1); - double tol = 100*Const.QL_EPSILON; + double tol = 100 * Const.QL_EPSILON; DayCounter[] dayCounters = { new ActualActual(), new Actual365Fixed(), new Actual360() }; - for (int i=0; i < dayCounters.Length; ++i) + for (int i = 0; i < dayCounters.Length; ++i) { DayCounter dc = dayCounters[i]; - double expected = ((12*60 + 34)*60 + 17 + 0.001) - * dc.yearFraction(d1, d1+1)/86400 - + dc.yearFraction(d1, d1+2); + double expected = ((12 * 60 + 34) * 60 + 17 + 0.001) + * dc.yearFraction(d1, d1 + 1) / 86400 + + dc.yearFraction(d1, d1 + 2); - QAssert.IsTrue( Math.Abs(dc.yearFraction(d1, d2) - expected) < tol, + QAssert.IsTrue(Math.Abs(dc.yearFraction(d1, d2) - expected) < tol, "can not reproduce result for day counter " + dc.name()); - QAssert.IsTrue( Math.Abs(dc.yearFraction(d2, d1) + expected) < tol, + QAssert.IsTrue(Math.Abs(dc.yearFraction(d2, d1) + expected) < tol, "can not reproduce result for day counter " + dc.name()); } } diff --git a/tests/QLNet.Tests/T_DefaultProbabilityCurves.cs b/tests/QLNet.Tests/T_DefaultProbabilityCurves.cs index 934f219c4..95fbf9fc0 100644 --- a/tests/QLNet.Tests/T_DefaultProbabilityCurves.cs +++ b/tests/QLNet.Tests/T_DefaultProbabilityCurves.cs @@ -5,13 +5,13 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,7 +20,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -32,11 +32,11 @@ namespace TestSuite public class T_DefaultProbabilityCurves { #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testDefaultProbability() + public void testDefaultProbability() { // Testing default-probability structure... @@ -53,7 +53,7 @@ public void testDefaultProbability() FlatHazardRate flatHazardRate = new FlatHazardRate(startDate, hazardRateQuote, dayCounter); - for(int i=0; i tolerance) - QAssert.Fail( "Failed to reproduce probability(d1, d2) " + QAssert.Fail("Failed to reproduce probability(d1, d2) " + "for default probability structure\n" + " calculated probability: " + pBetweenComputed + "\n" + " expected probability: " + pBetween); @@ -78,28 +78,28 @@ public void testDefaultProbability() flatHazardRate.defaultProbability(endDate); if (Math.Abs(timeProbability - dateProbability) > tolerance) - QAssert.Fail( "single-time probability and single-date probability do not match\n" - + " time probability: " + timeProbability + "\n" - + " date probability: " + dateProbability); + QAssert.Fail("single-time probability and single-date probability do not match\n" + + " time probability: " + timeProbability + "\n" + + " date probability: " + dateProbability); double t1 = dayCounter.yearFraction(today, startDate); timeProbability = flatHazardRate.defaultProbability(t1, t2); dateProbability = flatHazardRate.defaultProbability(startDate, endDate); if (Math.Abs(timeProbability - dateProbability) > tolerance) - QAssert.Fail( "double-time probability and double-date probability do not match\n" + QAssert.Fail("double-time probability and double-date probability do not match\n" + " time probability: " + timeProbability + "\n" + " date probability: " + dateProbability); - + } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testFlatHazardRate() + public void testFlatHazardRate() { // Testing flat hazard rate... @@ -117,7 +117,7 @@ public void testFlatHazardRate() FlatHazardRate flatHazardRate = new FlatHazardRate(today, hazardRateQuote, dayCounter); - for(int i=0; i tolerance) - QAssert.Fail( "Failed to reproduce probability for flat hazard rate\n" + QAssert.Fail("Failed to reproduce probability for flat hazard rate\n" + " calculated probability: " + computedProbability + "\n" + " expected probability: " + probability); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testFlatHazardConsistency() + public void testFlatHazardConsistency() { // Testing piecewise-flat hazard-rate consistency... //testBootstrapFromSpread(); diff --git a/tests/QLNet.Tests/T_DigitalCoupon.cs b/tests/QLNet.Tests/T_DigitalCoupon.cs index fbce4a36d..19ccc681c 100644 --- a/tests/QLNet.Tests/T_DigitalCoupon.cs +++ b/tests/QLNet.Tests/T_DigitalCoupon.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -18,7 +18,7 @@ #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -45,7 +45,7 @@ private class CommonVars SavedSettings backup; // setup - public CommonVars() + public CommonVars() { backup = new SavedSettings(); termStructure = new RelinkableHandle(); @@ -55,19 +55,19 @@ public CommonVars() calendar = index.fixingCalendar(); today = calendar.adjust(Settings.evaluationDate()); Settings.setEvaluationDate(today); - settlement = calendar.advance(today,fixingDays,TimeUnit.Days); - termStructure.linkTo(Utilities.flatRate(settlement,0.05,new Actual365Fixed())); + settlement = calendar.advance(today, fixingDays, TimeUnit.Days); + termStructure.linkTo(Utilities.flatRate(settlement, 0.05, new Actual365Fixed())); optionTolerance = 1.0e-04; blackTolerance = 1e-10; } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testAssetOrNothing() + public void testAssetOrNothing() { // Testing European asset-or-nothing digital coupon @@ -90,33 +90,33 @@ public void testAssetOrNothing() double gap = 1e-7; /* low, in order to compare digital option value with black formula result */ DigitalReplication replication = new DigitalReplication(Replication.Type.Central, gap); - for (int i = 0; i< vols.Length; i++) + for (int i = 0; i < vols.Length; i++) { double capletVol = vols[i]; RelinkableHandle vol = new RelinkableHandle(); - vol.linkTo(new ConstantOptionletVolatility(vars.today,vars.calendar, BusinessDayConvention.Following, - capletVol, new Actual360())); - for (int j=0; jvars.optionTolerance) + if (error > vars.optionTolerance) QAssert.Fail("\nDigital Call Option:" + - "\nVolatility = " + (capletVol) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nOption price by replication = " + optionPrice + - "\nOption price by Cox-Rubinstein formula = " + nd1Price + - "\nError " + error); + "\nVolatility = " + (capletVol) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nOption price by replication = " + optionPrice + + "\nOption price by Cox-Rubinstein formula = " + nd1Price + + "\nError " + error); // Check digital option price vs N(d1) price using Vanilla Option class - if (spread==0.0) + if (spread == 0.0) { Exercise exercise = new EuropeanExercise(exerciseDate); double discountAtFixing = vars.termStructure.link.discount(exerciseDate); - SimpleQuote fwd = new SimpleQuote(effFwd*discountAtFixing); + SimpleQuote fwd = new SimpleQuote(effFwd * discountAtFixing); SimpleQuote qRate = new SimpleQuote(0.0); YieldTermStructure qTS = Utilities.flatRate(vars.today, qRate, new Actual360()); SimpleQuote vol1 = new SimpleQuote(0.0); BlackVolTermStructure volTS = Utilities.flatVol(vars.today, capletVol, new Actual360()); - StrikedTypePayoff callPayoff = new AssetOrNothingPayoff(Option.Type.Call,effStrike); + StrikedTypePayoff callPayoff = new AssetOrNothingPayoff(Option.Type.Call, effStrike); BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess( new Handle(fwd), new Handle(qTS), @@ -167,74 +167,74 @@ with black formula result */ VanillaOption callOpt = new VanillaOption(callPayoff, exercise); callOpt.setPricingEngine(engine); double callVO = vars.nominal * gearing - * accrualPeriod * callOpt.NPV() - * discount / discountAtFixing - * forward / effFwd; + * accrualPeriod * callOpt.NPV() + * discount / discountAtFixing + * forward / effFwd; error = Math.Abs(nd1Price - callVO); - if (error>vars.blackTolerance) + if (error > vars.blackTolerance) QAssert.Fail("\nDigital Call Option:" + - "\nVolatility = " + (capletVol) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nOption price by Black asset-ot-nothing payoff = " + callVO + - "\nOption price by Cox-Rubinstein = " + nd1Price + - "\nError " + error ); - } - - // Floating Rate Coupon + Put Digital option - DigitalCoupon digitalFlooredCoupon = new DigitalCoupon(underlying,nullstrike, Position.Type.Long, - false, nullstrike,strike, Position.Type.Long, false, nullstrike,replication); - digitalFlooredCoupon.setPricer(pricer); - - // Check digital option price vs N(d1) price - N_d1 = phi.value(-d1); - N_d2 = phi.value(-d2); - nd1Price = (gearing * effFwd * N_d1 + spread * N_d2) - * vars.nominal * accrualPeriod * discount; - optionPrice = digitalFlooredCoupon.putOptionRate() * - vars.nominal * accrualPeriod * discount; - error = Math.Abs(nd1Price - optionPrice); - if (error>vars.optionTolerance) + "\nVolatility = " + (capletVol) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nOption price by Black asset-ot-nothing payoff = " + callVO + + "\nOption price by Cox-Rubinstein = " + nd1Price + + "\nError " + error); + } + + // Floating Rate Coupon + Put Digital option + DigitalCoupon digitalFlooredCoupon = new DigitalCoupon(underlying, nullstrike, Position.Type.Long, + false, nullstrike, strike, Position.Type.Long, false, nullstrike, replication); + digitalFlooredCoupon.setPricer(pricer); + + // Check digital option price vs N(d1) price + N_d1 = phi.value(-d1); + N_d2 = phi.value(-d2); + nd1Price = (gearing * effFwd * N_d1 + spread * N_d2) + * vars.nominal * accrualPeriod * discount; + optionPrice = digitalFlooredCoupon.putOptionRate() * + vars.nominal * accrualPeriod * discount; + error = Math.Abs(nd1Price - optionPrice); + if (error > vars.optionTolerance) + QAssert.Fail("\nDigital Put Option:" + + "\nVolatility = " + (capletVol) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nOption price by replication = " + optionPrice + + "\nOption price by Cox-Rubinstein = " + nd1Price + + "\nError " + error); + + // Check digital option price vs N(d1) price using Vanilla Option class + if (spread == 0.0) + { + Exercise exercise = new EuropeanExercise(exerciseDate); + double discountAtFixing = vars.termStructure.link.discount(exerciseDate); + SimpleQuote fwd = new SimpleQuote(effFwd * discountAtFixing); + SimpleQuote qRate = new SimpleQuote(0.0); + YieldTermStructure qTS = Utilities.flatRate(vars.today, qRate, new Actual360()); + //SimpleQuote vol = new SimpleQuote(0.0); + BlackVolTermStructure volTS = Utilities.flatVol(vars.today, capletVol, new Actual360()); + BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess( + new Handle(fwd), + new Handle(qTS), + new Handle(vars.termStructure), + new Handle(volTS)); + StrikedTypePayoff putPayoff = new AssetOrNothingPayoff(Option.Type.Put, effStrike); + IPricingEngine engine = new AnalyticEuropeanEngine(stochProcess); + VanillaOption putOpt = new VanillaOption(putPayoff, exercise); + putOpt.setPricingEngine(engine); + double putVO = vars.nominal * gearing + * accrualPeriod * putOpt.NPV() + * discount / discountAtFixing + * forward / effFwd; + error = Math.Abs(nd1Price - putVO); + if (error > vars.blackTolerance) QAssert.Fail("\nDigital Put Option:" + - "\nVolatility = " + (capletVol) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nOption price by replication = " + optionPrice + - "\nOption price by Cox-Rubinstein = " + nd1Price + - "\nError " + error ); - - // Check digital option price vs N(d1) price using Vanilla Option class - if (spread==0.0) - { - Exercise exercise = new EuropeanExercise(exerciseDate); - double discountAtFixing = vars.termStructure.link.discount(exerciseDate); - SimpleQuote fwd = new SimpleQuote(effFwd*discountAtFixing); - SimpleQuote qRate = new SimpleQuote(0.0); - YieldTermStructure qTS = Utilities.flatRate(vars.today, qRate, new Actual360()); - //SimpleQuote vol = new SimpleQuote(0.0); - BlackVolTermStructure volTS = Utilities.flatVol(vars.today, capletVol, new Actual360()); - BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess( - new Handle(fwd), - new Handle(qTS), - new Handle(vars.termStructure), - new Handle(volTS)); - StrikedTypePayoff putPayoff = new AssetOrNothingPayoff(Option.Type.Put, effStrike); - IPricingEngine engine = new AnalyticEuropeanEngine(stochProcess); - VanillaOption putOpt = new VanillaOption(putPayoff, exercise); - putOpt.setPricingEngine(engine); - double putVO = vars.nominal * gearing - * accrualPeriod * putOpt.NPV() - * discount / discountAtFixing - * forward / effFwd; - error = Math.Abs(nd1Price - putVO); - if (error>vars.blackTolerance) - QAssert.Fail("\nDigital Put Option:" + - "\nVolatility = " + (capletVol) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nOption price by Black asset-ot-nothing payoff = " + putVO + - "\nOption price by Cox-Rubinstein = " + nd1Price + - "\nError " + error ); + "\nVolatility = " + (capletVol) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nOption price by Black asset-ot-nothing payoff = " + putVO + + "\nOption price by Cox-Rubinstein = " + nd1Price + + "\nError " + error); } } } @@ -243,11 +243,11 @@ with black formula result */ } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testAssetOrNothingDeepInTheMoney() + public void testAssetOrNothingDeepInTheMoney() { // Testing European deep in-the-money asset-or-nothing digital coupon CommonVars vars = new CommonVars(); @@ -257,26 +257,26 @@ public void testAssetOrNothingDeepInTheMoney() double capletVolatility = 0.0001; RelinkableHandle volatility = new RelinkableHandle(); - volatility.linkTo(new ConstantOptionletVolatility(vars.today, vars.calendar, BusinessDayConvention.Following, - capletVolatility, new Actual360())); + volatility.linkTo(new ConstantOptionletVolatility(vars.today, vars.calendar, BusinessDayConvention.Following, + capletVolatility, new Actual360())); double gap = 1e-4; DigitalReplication replication = new DigitalReplication(Replication.Type.Central, gap); - for (int k = 0; k<10; k++) - { + for (int k = 0; k < 10; k++) + { // Loop on start and end dates - Date startDate = vars.calendar.advance(vars.settlement,new Period(k+1,TimeUnit.Years)); - Date endDate = vars.calendar.advance(vars.settlement,new Period(k+2,TimeUnit.Years)); + Date startDate = vars.calendar.advance(vars.settlement, new Period(k + 1, TimeUnit.Years)); + Date endDate = vars.calendar.advance(vars.settlement, new Period(k + 2, TimeUnit.Years)); double? nullstrike = null; Date paymentDate = endDate; - FloatingRateCoupon underlying = new IborCoupon(paymentDate, vars.nominal,startDate, endDate, - vars.fixingDays, vars.index, gearing, spread); + FloatingRateCoupon underlying = new IborCoupon(paymentDate, vars.nominal, startDate, endDate, + vars.fixingDays, vars.index, gearing, spread); // Floating Rate Coupon - Deep-in-the-money Call Digital option double strike = 0.001; - DigitalCoupon digitalCappedCoupon = new DigitalCoupon(underlying,strike, Position.Type.Short, false, - nullstrike,nullstrike, Position.Type.Short, false, nullstrike,replication); + DigitalCoupon digitalCappedCoupon = new DigitalCoupon(underlying, strike, Position.Type.Short, false, + nullstrike, nullstrike, Position.Type.Short, false, nullstrike, replication); IborCouponPricer pricer = new BlackIborCouponPricer(volatility); digitalCappedCoupon.setPricer(pricer); @@ -289,33 +289,33 @@ public void testAssetOrNothingDeepInTheMoney() double digitalPrice = digitalCappedCoupon.price(vars.termStructure); double error = Math.Abs(targetPrice - digitalPrice); double tolerance = 1e-08; - if (error>tolerance) + if (error > tolerance) QAssert.Fail("\nFloating Coupon - Digital Call Option:" + - "\nVolatility = " + (capletVolatility) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nCoupon Price = " + digitalPrice + - "\nTarget price = " + targetPrice + - "\nError = " + error ); + "\nVolatility = " + (capletVolatility) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nCoupon Price = " + digitalPrice + + "\nTarget price = " + targetPrice + + "\nError = " + error); // Check digital option price double replicationOptionPrice = digitalCappedCoupon.callOptionRate() * - vars.nominal * accrualPeriod * discount; + vars.nominal * accrualPeriod * discount; error = Math.Abs(targetOptionPrice - replicationOptionPrice); double optionTolerance = 1e-08; - if (error>optionTolerance) + if (error > optionTolerance) QAssert.Fail("\nDigital Call Option:" + - "\nVolatility = " + +(capletVolatility) + - "\nStrike = " + +(strike) + - "\nExercise = " + k+1 + " years" + - "\nPrice by replication = " + replicationOptionPrice + - "\nTarget price = " + targetOptionPrice + - "\nError = " + error); + "\nVolatility = " + +(capletVolatility) + + "\nStrike = " + +(strike) + + "\nExercise = " + k + 1 + " years" + + "\nPrice by replication = " + replicationOptionPrice + + "\nTarget price = " + targetOptionPrice + + "\nError = " + error); // Floating Rate Coupon + Deep-in-the-money Put Digital option strike = 0.99; - DigitalCoupon digitalFlooredCoupon = new DigitalCoupon(underlying,nullstrike, Position.Type.Long, false, - nullstrike,strike, Position.Type.Long, false, nullstrike,replication); + DigitalCoupon digitalFlooredCoupon = new DigitalCoupon(underlying, nullstrike, Position.Type.Long, false, + nullstrike, strike, Position.Type.Long, false, nullstrike, replication); digitalFlooredCoupon.setPricer(pricer); // Check price vs its target price @@ -324,37 +324,37 @@ public void testAssetOrNothingDeepInTheMoney() digitalPrice = digitalFlooredCoupon.price(vars.termStructure); error = Math.Abs(targetPrice - digitalPrice); tolerance = 2.5e-06; - if (error>tolerance) + if (error > tolerance) QAssert.Fail("\nFloating Coupon + Digital Put Option:" + - "\nVolatility = " + (capletVolatility) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nDigital coupon price = " + digitalPrice + - "\nTarget price = " + targetPrice + - "\nError " + error); + "\nVolatility = " + (capletVolatility) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nDigital coupon price = " + digitalPrice + + "\nTarget price = " + targetPrice + + "\nError " + error); // Check digital option replicationOptionPrice = digitalFlooredCoupon.putOptionRate() * - vars.nominal * accrualPeriod * discount; + vars.nominal * accrualPeriod * discount; error = Math.Abs(targetOptionPrice - replicationOptionPrice); optionTolerance = 2.5e-06; - if (error>optionTolerance) + if (error > optionTolerance) QAssert.Fail("\nDigital Put Option:" + - "\nVolatility = " + (capletVolatility) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nPrice by replication = " + replicationOptionPrice + - "\nTarget price = " + targetOptionPrice + - "\nError " + error); + "\nVolatility = " + (capletVolatility) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nPrice by replication = " + replicationOptionPrice + + "\nTarget price = " + targetOptionPrice + + "\nError " + error); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testAssetOrNothingDeepOutTheMoney() + public void testAssetOrNothingDeepOutTheMoney() { // Testing European deep out-the-money asset-or-nothing digital coupon CommonVars vars = new CommonVars(); @@ -364,26 +364,26 @@ public void testAssetOrNothingDeepOutTheMoney() double capletVolatility = 0.0001; RelinkableHandle volatility = new RelinkableHandle(); - volatility.linkTo(new ConstantOptionletVolatility(vars.today, vars.calendar, BusinessDayConvention.Following, - capletVolatility, new Actual360())); + volatility.linkTo(new ConstantOptionletVolatility(vars.today, vars.calendar, BusinessDayConvention.Following, + capletVolatility, new Actual360())); double gap = 1e-4; DigitalReplication replication = new DigitalReplication(Replication.Type.Central, gap); - for (int k = 0; k<10; k++) - { + for (int k = 0; k < 10; k++) + { // loop on start and end dates - Date startDate = vars.calendar.advance(vars.settlement,new Period(k+1,TimeUnit.Years)); - Date endDate = vars.calendar.advance(vars.settlement,new Period(k+2,TimeUnit.Years)); + Date startDate = vars.calendar.advance(vars.settlement, new Period(k + 1, TimeUnit.Years)); + Date endDate = vars.calendar.advance(vars.settlement, new Period(k + 2, TimeUnit.Years)); double? nullstrike = null; Date paymentDate = endDate; - FloatingRateCoupon underlying = new IborCoupon(paymentDate, vars.nominal,startDate, endDate, - vars.fixingDays, vars.index, gearing, spread); + FloatingRateCoupon underlying = new IborCoupon(paymentDate, vars.nominal, startDate, endDate, + vars.fixingDays, vars.index, gearing, spread); // Floating Rate Coupon - Deep-out-of-the-money Call Digital option double strike = 0.99; - DigitalCoupon digitalCappedCoupon = new DigitalCoupon(underlying,strike, Position.Type.Short, false, - nullstrike,nullstrike, Position.Type.Long, false, nullstrike,replication/*Replication::Central, gap*/); + DigitalCoupon digitalCappedCoupon = new DigitalCoupon(underlying, strike, Position.Type.Short, false, + nullstrike, nullstrike, Position.Type.Long, false, nullstrike, replication/*Replication::Central, gap*/); IborCouponPricer pricer = new BlackIborCouponPricer(volatility); digitalCappedCoupon.setPricer(pricer); @@ -395,34 +395,34 @@ public void testAssetOrNothingDeepOutTheMoney() double digitalPrice = digitalCappedCoupon.price(vars.termStructure); double error = Math.Abs(targetPrice - digitalPrice); double tolerance = 1e-10; - if (error>tolerance) + if (error > tolerance) QAssert.Fail("\nFloating Coupon - Digital Call Option :" + - "\nVolatility = " + (capletVolatility) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nCoupon price = " + digitalPrice + - "\nTarget price = " + targetPrice + - "\nError = " + error ); + "\nVolatility = " + (capletVolatility) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nCoupon price = " + digitalPrice + + "\nTarget price = " + targetPrice + + "\nError = " + error); // Check digital option price double targetOptionPrice = 0.0; double replicationOptionPrice = digitalCappedCoupon.callOptionRate() * - vars.nominal * accrualPeriod * discount; + vars.nominal * accrualPeriod * discount; error = Math.Abs(targetOptionPrice - replicationOptionPrice); double optionTolerance = 1e-08; - if (error>optionTolerance) + if (error > optionTolerance) QAssert.Fail("\nDigital Call Option:" + - "\nVolatility = " + (capletVolatility) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nPrice by replication = " + replicationOptionPrice + - "\nTarget price = " + targetOptionPrice + - "\nError = " + error ); + "\nVolatility = " + (capletVolatility) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nPrice by replication = " + replicationOptionPrice + + "\nTarget price = " + targetOptionPrice + + "\nError = " + error); // Floating Rate Coupon - Deep-out-of-the-money Put Digital option strike = 0.01; - DigitalCoupon digitalFlooredCoupon = new DigitalCoupon(underlying,nullstrike, Position.Type.Long, false, - nullstrike,strike, Position.Type.Long, false, nullstrike,replication); + DigitalCoupon digitalFlooredCoupon = new DigitalCoupon(underlying, nullstrike, Position.Type.Long, false, + nullstrike, strike, Position.Type.Long, false, nullstrike, replication); digitalFlooredCoupon.setPricer(pricer); // Check price vs its target @@ -430,37 +430,37 @@ public void testAssetOrNothingDeepOutTheMoney() digitalPrice = digitalFlooredCoupon.price(vars.termStructure); tolerance = 1e-08; error = Math.Abs(targetPrice - digitalPrice); - if (error>tolerance) + if (error > tolerance) QAssert.Fail("\nFloating Coupon + Digital Put Coupon:" + - "\nVolatility = " + (capletVolatility) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nCoupon price = " + digitalPrice + - "\nTarget price = " + targetPrice + - "\nError = " + error ); + "\nVolatility = " + (capletVolatility) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nCoupon price = " + digitalPrice + + "\nTarget price = " + targetPrice + + "\nError = " + error); // Check digital option targetOptionPrice = 0.0; replicationOptionPrice = digitalFlooredCoupon.putOptionRate() * - vars.nominal * accrualPeriod * discount; + vars.nominal * accrualPeriod * discount; error = Math.Abs(targetOptionPrice - replicationOptionPrice); - if (error>optionTolerance) + if (error > optionTolerance) QAssert.Fail("\nDigital Put Coupon:" + - "\nVolatility = " + (capletVolatility) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nPrice by replication = " + replicationOptionPrice + - "\nTarget price = " + targetOptionPrice + - "\nError = " + error ); + "\nVolatility = " + (capletVolatility) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nPrice by replication = " + replicationOptionPrice + + "\nTarget price = " + targetOptionPrice + + "\nError = " + error); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testCashOrNothing() + public void testCashOrNothing() { // Testing European cash-or-nothing digital coupon @@ -485,56 +485,56 @@ with black formula result */ DigitalReplication replication = new DigitalReplication(Replication.Type.Central, gap); RelinkableHandle vol = new RelinkableHandle(); - for (int i = 0; i< vols.Length; i++) + for (int i = 0; i < vols.Length; i++) { double capletVol = vols[i]; - vol.linkTo(new ConstantOptionletVolatility(vars.today,vars.calendar, BusinessDayConvention.Following, - capletVol, new Actual360())); - for (int j = 0; j< strikes.Length; j++) + vol.linkTo(new ConstantOptionletVolatility(vars.today, vars.calendar, BusinessDayConvention.Following, + capletVol, new Actual360())); + for (int j = 0; j < strikes.Length; j++) { double strike = strikes[j]; - for (int k = 0; k<10; k++) + for (int k = 0; k < 10; k++) { - Date startDate = vars.calendar.advance(vars.settlement,new Period(k+1,TimeUnit.Years)); - Date endDate = vars.calendar.advance(vars.settlement,new Period(k+2,TimeUnit.Years)); + Date startDate = vars.calendar.advance(vars.settlement, new Period(k + 1, TimeUnit.Years)); + Date endDate = vars.calendar.advance(vars.settlement, new Period(k + 2, TimeUnit.Years)); double? nullstrike = null; double cashRate = 0.01; Date paymentDate = endDate; - FloatingRateCoupon underlying = new IborCoupon(paymentDate, vars.nominal,startDate, endDate, - vars.fixingDays, vars.index,gearing, spread); + FloatingRateCoupon underlying = new IborCoupon(paymentDate, vars.nominal, startDate, endDate, + vars.fixingDays, vars.index, gearing, spread); // Floating Rate Coupon - Call Digital option - DigitalCoupon digitalCappedCoupon = new DigitalCoupon(underlying,strike, Position.Type.Short, false, - cashRate,nullstrike, Position.Type.Short, false, nullstrike,replication); + DigitalCoupon digitalCappedCoupon = new DigitalCoupon(underlying, strike, Position.Type.Short, false, + cashRate, nullstrike, Position.Type.Short, false, nullstrike, replication); IborCouponPricer pricer = new BlackIborCouponPricer(vol); digitalCappedCoupon.setPricer(pricer); // Check digital option price vs N(d2) price Date exerciseDate = underlying.fixingDate(); double forward = underlying.rate(); - double effFwd = (forward-spread)/gearing; - double effStrike = (strike-spread)/gearing; + double effFwd = (forward - spread) / gearing; + double effStrike = (strike - spread) / gearing; double accrualPeriod = underlying.accrualPeriod(); double discount = vars.termStructure.link.discount(endDate); double stdDev = Math.Sqrt(vol.link.blackVariance(exerciseDate, effStrike)); - double ITM = Utils.blackFormulaCashItmProbability(Option.Type.Call, effStrike,effFwd, stdDev); + double ITM = Utils.blackFormulaCashItmProbability(Option.Type.Call, effStrike, effFwd, stdDev); double nd2Price = ITM * vars.nominal * accrualPeriod * discount * cashRate; double optionPrice = digitalCappedCoupon.callOptionRate() * - vars.nominal * accrualPeriod * discount; + vars.nominal * accrualPeriod * discount; double error = Math.Abs(nd2Price - optionPrice); - if (error>vars.optionTolerance) + if (error > vars.optionTolerance) QAssert.Fail("\nDigital Call Option:" + - "\nVolatility = " + (capletVol) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nPrice by replication = " + optionPrice + - "\nPrice by Reiner-Rubinstein = " + nd2Price + - "\nError = " + error ); + "\nVolatility = " + (capletVol) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nPrice by replication = " + optionPrice + + "\nPrice by Reiner-Rubinstein = " + nd2Price + + "\nError = " + error); // Check digital option price vs N(d2) price using Vanilla Option class Exercise exercise = new EuropeanExercise(exerciseDate); double discountAtFixing = vars.termStructure.link.discount(exerciseDate); - SimpleQuote fwd = new SimpleQuote(effFwd*discountAtFixing); + SimpleQuote fwd = new SimpleQuote(effFwd * discountAtFixing); SimpleQuote qRate = new SimpleQuote(0.0); YieldTermStructure qTS = Utilities.flatRate(vars.today, qRate, new Actual360()); //SimpleQuote vol = new SimpleQuote(0.0); @@ -549,64 +549,64 @@ with black formula result */ VanillaOption callOpt = new VanillaOption(callPayoff, exercise); callOpt.setPricingEngine(engine); double callVO = vars.nominal * accrualPeriod * callOpt.NPV() - * discount / discountAtFixing; + * discount / discountAtFixing; error = Math.Abs(nd2Price - callVO); - if (error>vars.blackTolerance) + if (error > vars.blackTolerance) QAssert.Fail("\nDigital Call Option:" + - "\nVolatility = " + (capletVol) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nOption price by Black asset-ot-nothing payoff = " + callVO + - "\nOption price by Reiner-Rubinstein = " + nd2Price + - "\nError " + error ); + "\nVolatility = " + (capletVol) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nOption price by Black asset-ot-nothing payoff = " + callVO + + "\nOption price by Reiner-Rubinstein = " + nd2Price + + "\nError " + error); // Floating Rate Coupon + Put Digital option - DigitalCoupon digitalFlooredCoupon = new DigitalCoupon(underlying,nullstrike, Position.Type.Long, false, - nullstrike,strike, Position.Type.Long, false, cashRate,replication); + DigitalCoupon digitalFlooredCoupon = new DigitalCoupon(underlying, nullstrike, Position.Type.Long, false, + nullstrike, strike, Position.Type.Long, false, cashRate, replication); digitalFlooredCoupon.setPricer(pricer); // Check digital option price vs N(d2) price - ITM = Utils.blackFormulaCashItmProbability(Option.Type.Put,effStrike,effFwd,stdDev); + ITM = Utils.blackFormulaCashItmProbability(Option.Type.Put, effStrike, effFwd, stdDev); nd2Price = ITM * vars.nominal * accrualPeriod * discount * cashRate; optionPrice = digitalFlooredCoupon.putOptionRate() * - vars.nominal * accrualPeriod * discount; + vars.nominal * accrualPeriod * discount; error = Math.Abs(nd2Price - optionPrice); - if (error>vars.optionTolerance) + if (error > vars.optionTolerance) QAssert.Fail("\nPut Digital Option:" + - "\nVolatility = " + (capletVol) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nPrice by replication = " + optionPrice + - "\nPrice by Reiner-Rubinstein = " + nd2Price + - "\nError = " + error ); + "\nVolatility = " + (capletVol) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nPrice by replication = " + optionPrice + + "\nPrice by Reiner-Rubinstein = " + nd2Price + + "\nError = " + error); // Check digital option price vs N(d2) price using Vanilla Option class StrikedTypePayoff putPayoff = new CashOrNothingPayoff(Option.Type.Put, effStrike, cashRate); VanillaOption putOpt = new VanillaOption(putPayoff, exercise); putOpt.setPricingEngine(engine); double putVO = vars.nominal * accrualPeriod * putOpt.NPV() - * discount / discountAtFixing; + * discount / discountAtFixing; error = Math.Abs(nd2Price - putVO); - if (error>vars.blackTolerance) + if (error > vars.blackTolerance) QAssert.Fail("\nDigital Put Option:" + - "\nVolatility = " + (capletVol) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nOption price by Black asset-ot-nothing payoff = " + putVO + - "\nOption price by Reiner-Rubinstein = " + nd2Price + - "\nError " + error ); + "\nVolatility = " + (capletVol) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nOption price by Black asset-ot-nothing payoff = " + putVO + + "\nOption price by Reiner-Rubinstein = " + nd2Price + + "\nError " + error); } } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testCashOrNothingDeepInTheMoney() + public void testCashOrNothingDeepInTheMoney() { // Testing European deep in-the-money cash-or-nothing digital coupon CommonVars vars = new CommonVars(); @@ -616,26 +616,26 @@ public void testCashOrNothingDeepInTheMoney() double capletVolatility = 0.0001; RelinkableHandle volatility = new RelinkableHandle(); - volatility.linkTo(new ConstantOptionletVolatility(vars.today, vars.calendar, BusinessDayConvention.Following, - capletVolatility, new Actual360())); + volatility.linkTo(new ConstantOptionletVolatility(vars.today, vars.calendar, BusinessDayConvention.Following, + capletVolatility, new Actual360())); - for (int k = 0; k<10; k++) - { + for (int k = 0; k < 10; k++) + { // Loop on start and end dates - Date startDate = vars.calendar.advance(vars.settlement,new Period(k+1,TimeUnit.Years)); - Date endDate = vars.calendar.advance(vars.settlement,new Period(k+2,TimeUnit.Years)); + Date startDate = vars.calendar.advance(vars.settlement, new Period(k + 1, TimeUnit.Years)); + Date endDate = vars.calendar.advance(vars.settlement, new Period(k + 2, TimeUnit.Years)); double? nullstrike = null; double cashRate = 0.01; double gap = 1e-4; DigitalReplication replication = new DigitalReplication(Replication.Type.Central, gap); Date paymentDate = endDate; - FloatingRateCoupon underlying = new IborCoupon(paymentDate, vars.nominal,startDate, endDate, - vars.fixingDays, vars.index,gearing, spread); + FloatingRateCoupon underlying = new IborCoupon(paymentDate, vars.nominal, startDate, endDate, + vars.fixingDays, vars.index, gearing, spread); // Floating Rate Coupon - Deep-in-the-money Call Digital option double strike = 0.001; - DigitalCoupon digitalCappedCoupon = new DigitalCoupon(underlying,strike, Position.Type.Short, false, - cashRate,nullstrike, Position.Type.Short, false, nullstrike,replication); + DigitalCoupon digitalCappedCoupon = new DigitalCoupon(underlying, strike, Position.Type.Short, false, + cashRate, nullstrike, Position.Type.Short, false, nullstrike, replication); IborCouponPricer pricer = new BlackIborCouponPricer(volatility); digitalCappedCoupon.setPricer(pricer); @@ -649,69 +649,69 @@ public void testCashOrNothingDeepInTheMoney() double error = Math.Abs(targetPrice - digitalPrice); double tolerance = 1e-07; - if (error>tolerance) + if (error > tolerance) QAssert.Fail("\nFloating Coupon - Digital Call Coupon:" + - "\nVolatility = " + (capletVolatility) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nCoupon price = " + digitalPrice + - "\nTarget price = " + targetPrice + - "\nError " + error ); + "\nVolatility = " + (capletVolatility) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nCoupon price = " + digitalPrice + + "\nTarget price = " + targetPrice + + "\nError " + error); // Check digital option price double replicationOptionPrice = digitalCappedCoupon.callOptionRate() * - vars.nominal * accrualPeriod * discount; + vars.nominal * accrualPeriod * discount; error = Math.Abs(targetOptionPrice - replicationOptionPrice); double optionTolerance = 1e-07; - if (error>optionTolerance) + if (error > optionTolerance) QAssert.Fail("\nDigital Call Option:" + - "\nVolatility = " + (capletVolatility) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nPrice by replication = " + replicationOptionPrice + - "\nTarget price = " + targetOptionPrice + - "\nError = " + error); + "\nVolatility = " + (capletVolatility) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nPrice by replication = " + replicationOptionPrice + + "\nTarget price = " + targetOptionPrice + + "\nError = " + error); // Floating Rate Coupon + Deep-in-the-money Put Digital option strike = 0.99; - DigitalCoupon digitalFlooredCoupon = new DigitalCoupon(underlying,nullstrike, Position.Type.Long, false, - nullstrike,strike, Position.Type.Long, false, cashRate,replication); + DigitalCoupon digitalFlooredCoupon = new DigitalCoupon(underlying, nullstrike, Position.Type.Long, false, + nullstrike, strike, Position.Type.Long, false, cashRate, replication); digitalFlooredCoupon.setPricer(pricer); // Check price vs its target targetPrice = underlying.price(vars.termStructure) + targetOptionPrice; digitalPrice = digitalFlooredCoupon.price(vars.termStructure); error = Math.Abs(targetPrice - digitalPrice); - if (error>tolerance) + if (error > tolerance) QAssert.Fail("\nFloating Coupon + Digital Put Option:" + - "\nVolatility = " + (capletVolatility) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nCoupon price = " + digitalPrice + - "\nTarget price = " + targetPrice + - "\nError = " + error ); + "\nVolatility = " + (capletVolatility) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nCoupon price = " + digitalPrice + + "\nTarget price = " + targetPrice + + "\nError = " + error); // Check digital option replicationOptionPrice = digitalFlooredCoupon.putOptionRate() * - vars.nominal * accrualPeriod * discount; + vars.nominal * accrualPeriod * discount; error = Math.Abs(targetOptionPrice - replicationOptionPrice); - if (error>optionTolerance) + if (error > optionTolerance) QAssert.Fail("\nDigital Put Coupon:" + - "\nVolatility = " + (capletVolatility) + - "\nStrike = " + +(strike) + - "\nExercise = " + k+1 + " years" + - "\nPrice by replication = " + replicationOptionPrice + - "\nTarget price = " + targetOptionPrice + - "\nError = " + error ); + "\nVolatility = " + (capletVolatility) + + "\nStrike = " + +(strike) + + "\nExercise = " + k + 1 + " years" + + "\nPrice by replication = " + replicationOptionPrice + + "\nTarget price = " + targetOptionPrice + + "\nError = " + error); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testCashOrNothingDeepOutTheMoney() + public void testCashOrNothingDeepOutTheMoney() { // Testing European deep out-the-money cash-or-nothing digital coupon CommonVars vars = new CommonVars(); @@ -721,26 +721,26 @@ public void testCashOrNothingDeepOutTheMoney() double capletVolatility = 0.0001; RelinkableHandle volatility = new RelinkableHandle(); - volatility.linkTo(new ConstantOptionletVolatility(vars.today, vars.calendar, BusinessDayConvention.Following, - capletVolatility, new Actual360())); + volatility.linkTo(new ConstantOptionletVolatility(vars.today, vars.calendar, BusinessDayConvention.Following, + capletVolatility, new Actual360())); - for (int k = 0; k<10; k++) - { + for (int k = 0; k < 10; k++) + { // loop on start and end dates - Date startDate = vars.calendar.advance(vars.settlement,new Period(k+1,TimeUnit.Years)); - Date endDate = vars.calendar.advance(vars.settlement,new Period(k+2,TimeUnit.Years)); + Date startDate = vars.calendar.advance(vars.settlement, new Period(k + 1, TimeUnit.Years)); + Date endDate = vars.calendar.advance(vars.settlement, new Period(k + 2, TimeUnit.Years)); double? nullstrike = null; double cashRate = 0.01; double gap = 1e-4; DigitalReplication replication = new DigitalReplication(Replication.Type.Central, gap); Date paymentDate = endDate; - FloatingRateCoupon underlying = new IborCoupon(paymentDate, vars.nominal,startDate, endDate, - vars.fixingDays, vars.index,gearing, spread); + FloatingRateCoupon underlying = new IborCoupon(paymentDate, vars.nominal, startDate, endDate, + vars.fixingDays, vars.index, gearing, spread); // Deep out-of-the-money Capped Digital Coupon double strike = 0.99; - DigitalCoupon digitalCappedCoupon = new DigitalCoupon(underlying,strike, Position.Type.Short, false, - cashRate,nullstrike, Position.Type.Short, false, nullstrike,replication); + DigitalCoupon digitalCappedCoupon = new DigitalCoupon(underlying, strike, Position.Type.Short, false, + cashRate, nullstrike, Position.Type.Short, false, nullstrike, replication); IborCouponPricer pricer = new BlackIborCouponPricer(volatility); digitalCappedCoupon.setPricer(pricer); @@ -753,34 +753,34 @@ public void testCashOrNothingDeepOutTheMoney() double digitalPrice = digitalCappedCoupon.price(vars.termStructure); double error = Math.Abs(targetPrice - digitalPrice); double tolerance = 1e-10; - if (error>tolerance) + if (error > tolerance) QAssert.Fail("\nFloating Coupon + Digital Call Option:" + - "\nVolatility = " + +(capletVolatility) + - "\nStrike = " + +(strike) + - "\nExercise = " + k+1 + " years" + - "\nCoupon price = " + digitalPrice + - "\nTarget price = " + targetPrice + - "\nError = " + error ); + "\nVolatility = " + +(capletVolatility) + + "\nStrike = " + +(strike) + + "\nExercise = " + k + 1 + " years" + + "\nCoupon price = " + digitalPrice + + "\nTarget price = " + targetPrice + + "\nError = " + error); // Check digital option price double targetOptionPrice = 0.0; double replicationOptionPrice = digitalCappedCoupon.callOptionRate() * - vars.nominal * accrualPeriod * discount; + vars.nominal * accrualPeriod * discount; error = Math.Abs(targetOptionPrice - replicationOptionPrice); double optionTolerance = 1e-10; - if (error>optionTolerance) + if (error > optionTolerance) QAssert.Fail("\nDigital Call Option:" + - "\nVolatility = " + +(capletVolatility) + - "\nStrike = " + +(strike) + - "\nExercise = " + k+1 + " years" + - "\nPrice by replication = " + replicationOptionPrice + - "\nTarget price = " + targetOptionPrice + - "\nError = " + error ); + "\nVolatility = " + +(capletVolatility) + + "\nStrike = " + +(strike) + + "\nExercise = " + k + 1 + " years" + + "\nPrice by replication = " + replicationOptionPrice + + "\nTarget price = " + targetOptionPrice + + "\nError = " + error); // Deep out-of-the-money Floored Digital Coupon strike = 0.01; - DigitalCoupon digitalFlooredCoupon = new DigitalCoupon(underlying,nullstrike, Position.Type.Long, false, - nullstrike,strike, Position.Type.Long, false, cashRate,replication); + DigitalCoupon digitalFlooredCoupon = new DigitalCoupon(underlying, nullstrike, Position.Type.Long, false, + nullstrike, strike, Position.Type.Long, false, cashRate, replication); digitalFlooredCoupon.setPricer(pricer); // Check price vs its target @@ -788,37 +788,37 @@ public void testCashOrNothingDeepOutTheMoney() digitalPrice = digitalFlooredCoupon.price(vars.termStructure); tolerance = 1e-09; error = Math.Abs(targetPrice - digitalPrice); - if (error>tolerance) + if (error > tolerance) QAssert.Fail("\nDigital Floored Coupon:" + - "\nVolatility = " + +(capletVolatility) + - "\nStrike = " + +(strike) + - "\nExercise = " + k+1 + " years" + - "\nCoupon price = " + digitalPrice + - "\nTarget price = " + targetPrice + - "\nError = " + error ); + "\nVolatility = " + +(capletVolatility) + + "\nStrike = " + +(strike) + + "\nExercise = " + k + 1 + " years" + + "\nCoupon price = " + digitalPrice + + "\nTarget price = " + targetPrice + + "\nError = " + error); // Check digital option targetOptionPrice = 0.0; replicationOptionPrice = digitalFlooredCoupon.putOptionRate() * - vars.nominal * accrualPeriod * discount; + vars.nominal * accrualPeriod * discount; error = Math.Abs(targetOptionPrice - replicationOptionPrice); - if (error>optionTolerance) + if (error > optionTolerance) QAssert.Fail("\nDigital Put Option:" + - "\nVolatility = " + +(capletVolatility) + - "\nStrike = " + +(strike) + - "\nExercise = " + k+1 + " years" + - "\nPrice by replication " + replicationOptionPrice + - "\nTarget price " + targetOptionPrice + - "\nError " + error ); + "\nVolatility = " + +(capletVolatility) + + "\nStrike = " + +(strike) + + "\nExercise = " + k + 1 + " years" + + "\nPrice by replication " + replicationOptionPrice + + "\nTarget price " + targetOptionPrice + + "\nError " + error); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testCallPutParity() + public void testCallPutParity() { // Testing call/put parity for European digital coupon CommonVars vars = new CommonVars(); @@ -832,35 +832,35 @@ public void testCallPutParity() double gap = 1e-04; DigitalReplication replication = new DigitalReplication(Replication.Type.Central, gap); - for (int i = 0; i< vols.Length; i++) + for (int i = 0; i < vols.Length; i++) { double capletVolatility = vols[i]; RelinkableHandle volatility = new RelinkableHandle(); - volatility.linkTo(new ConstantOptionletVolatility(vars.today, vars.calendar, BusinessDayConvention.Following, - capletVolatility, new Actual360())); - for (int j = 0; j< strikes.Length; j++) + volatility.linkTo(new ConstantOptionletVolatility(vars.today, vars.calendar, BusinessDayConvention.Following, + capletVolatility, new Actual360())); + for (int j = 0; j < strikes.Length; j++) { double strike = strikes[j]; - for (int k = 0; k<10; k++) + for (int k = 0; k < 10; k++) { - Date startDate = vars.calendar.advance(vars.settlement,new Period(k+1,TimeUnit.Years)); - Date endDate = vars.calendar.advance(vars.settlement,new Period(k+2,TimeUnit.Years)); + Date startDate = vars.calendar.advance(vars.settlement, new Period(k + 1, TimeUnit.Years)); + Date endDate = vars.calendar.advance(vars.settlement, new Period(k + 2, TimeUnit.Years)); double? nullstrike = null; Date paymentDate = endDate; - FloatingRateCoupon underlying = new IborCoupon(paymentDate, vars.nominal,startDate, endDate, - vars.fixingDays, vars.index,gearing, spread); + FloatingRateCoupon underlying = new IborCoupon(paymentDate, vars.nominal, startDate, endDate, + vars.fixingDays, vars.index, gearing, spread); // Cash-or-Nothing double cashRate = 0.01; // Floating Rate Coupon + Call Digital option - DigitalCoupon cash_digitalCallCoupon = new DigitalCoupon(underlying,strike, Position.Type.Long, false, - cashRate,nullstrike, Position.Type.Long, false, nullstrike,replication); + DigitalCoupon cash_digitalCallCoupon = new DigitalCoupon(underlying, strike, Position.Type.Long, false, + cashRate, nullstrike, Position.Type.Long, false, nullstrike, replication); IborCouponPricer pricer = new BlackIborCouponPricer(volatility); cash_digitalCallCoupon.setPricer(pricer); // Floating Rate Coupon - Put Digital option - DigitalCoupon cash_digitalPutCoupon = new DigitalCoupon(underlying,nullstrike, Position.Type.Long, - false, nullstrike,strike, Position.Type.Short, false, cashRate,replication); + DigitalCoupon cash_digitalPutCoupon = new DigitalCoupon(underlying, nullstrike, Position.Type.Long, + false, nullstrike, strike, Position.Type.Short, false, cashRate, replication); cash_digitalPutCoupon.setPricer(pricer); double digitalPrice = cash_digitalCallCoupon.price(vars.termStructure) - @@ -872,23 +872,23 @@ public void testCallPutParity() double error = Math.Abs(targetPrice - digitalPrice); double tolerance = 1.0e-08; - if (error>tolerance) + if (error > tolerance) QAssert.Fail("\nCash-or-nothing:" + - "\nVolatility = " + +(capletVolatility) + - "\nStrike = " + +(strike) + - "\nExercise = " + k+1 + " years" + - "\nPrice = " + digitalPrice + - "\nTarget Price = " + targetPrice + - "\nError = " + error ); + "\nVolatility = " + +(capletVolatility) + + "\nStrike = " + +(strike) + + "\nExercise = " + k + 1 + " years" + + "\nPrice = " + digitalPrice + + "\nTarget Price = " + targetPrice + + "\nError = " + error); // Asset-or-Nothing // Floating Rate Coupon + Call Digital option - DigitalCoupon asset_digitalCallCoupon = new DigitalCoupon(underlying,strike, Position.Type.Long, false, - nullstrike,nullstrike, Position.Type.Long, false, nullstrike,replication); + DigitalCoupon asset_digitalCallCoupon = new DigitalCoupon(underlying, strike, Position.Type.Long, false, + nullstrike, nullstrike, Position.Type.Long, false, nullstrike, replication); asset_digitalCallCoupon.setPricer(pricer); // Floating Rate Coupon - Put Digital option - DigitalCoupon asset_digitalPutCoupon = new DigitalCoupon(underlying,nullstrike, Position.Type.Long, - false, nullstrike,strike, Position.Type.Short, false, nullstrike,replication); + DigitalCoupon asset_digitalPutCoupon = new DigitalCoupon(underlying, nullstrike, Position.Type.Long, + false, nullstrike, strike, Position.Type.Short, false, nullstrike, replication); asset_digitalPutCoupon.setPricer(pricer); digitalPrice = asset_digitalCallCoupon.price(vars.termStructure) - asset_digitalPutCoupon.price(vars.termStructure); @@ -896,25 +896,25 @@ public void testCallPutParity() targetPrice = vars.nominal * accrualPeriod * discount * underlying.rate(); error = Math.Abs(targetPrice - digitalPrice); tolerance = 1.0e-07; - if (error>tolerance) + if (error > tolerance) QAssert.Fail("\nAsset-or-nothing:" + - "\nVolatility = " + (capletVolatility) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nPrice = " + digitalPrice + - "\nTarget Price = " + targetPrice + - "\nError = " + error ); + "\nVolatility = " + (capletVolatility) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nPrice = " + digitalPrice + + "\nTarget Price = " + targetPrice + + "\nError = " + error); } } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testReplicationType() + public void testReplicationType() { // Testing replication type for European digital coupon CommonVars vars = new CommonVars(); @@ -930,35 +930,35 @@ public void testReplicationType() DigitalReplication centralReplication = new DigitalReplication(Replication.Type.Central, gap); DigitalReplication superReplication = new DigitalReplication(Replication.Type.Super, gap); - for (int i = 0; i< vols.Length; i++) + for (int i = 0; i < vols.Length; i++) { double capletVolatility = vols[i]; RelinkableHandle volatility = new RelinkableHandle(); - volatility.linkTo(new ConstantOptionletVolatility(vars.today, vars.calendar, BusinessDayConvention.Following, - capletVolatility, new Actual360())); - for (int j = 0; j< strikes.Length; j++) + volatility.linkTo(new ConstantOptionletVolatility(vars.today, vars.calendar, BusinessDayConvention.Following, + capletVolatility, new Actual360())); + for (int j = 0; j < strikes.Length; j++) { double strike = strikes[j]; - for (int k = 0; k<10; k++) + for (int k = 0; k < 10; k++) { - Date startDate = vars.calendar.advance(vars.settlement,new Period(k+1,TimeUnit.Years)); - Date endDate = vars.calendar.advance(vars.settlement,new Period(k+2,TimeUnit.Years)); + Date startDate = vars.calendar.advance(vars.settlement, new Period(k + 1, TimeUnit.Years)); + Date endDate = vars.calendar.advance(vars.settlement, new Period(k + 2, TimeUnit.Years)); double? nullstrike = null; Date paymentDate = endDate; - FloatingRateCoupon underlying = new IborCoupon(paymentDate, vars.nominal,startDate, endDate, - vars.fixingDays, vars.index,gearing, spread); + FloatingRateCoupon underlying = new IborCoupon(paymentDate, vars.nominal, startDate, endDate, + vars.fixingDays, vars.index, gearing, spread); // Cash-or-Nothing double cashRate = 0.005; // Floating Rate Coupon + Call Digital option - DigitalCoupon sub_cash_longDigitalCallCoupon = new DigitalCoupon(underlying,strike, Position.Type.Long, - false, cashRate,nullstrike, Position.Type.Long, false, nullstrike,subReplication); - DigitalCoupon central_cash_longDigitalCallCoupon = new DigitalCoupon(underlying,strike, - Position.Type.Long, false, cashRate,nullstrike, Position.Type.Long, false, nullstrike, - centralReplication); - DigitalCoupon over_cash_longDigitalCallCoupon = new DigitalCoupon(underlying,strike, Position.Type.Long, - false, cashRate,nullstrike, Position.Type.Long, false, nullstrike,superReplication); + DigitalCoupon sub_cash_longDigitalCallCoupon = new DigitalCoupon(underlying, strike, Position.Type.Long, + false, cashRate, nullstrike, Position.Type.Long, false, nullstrike, subReplication); + DigitalCoupon central_cash_longDigitalCallCoupon = new DigitalCoupon(underlying, strike, + Position.Type.Long, false, cashRate, nullstrike, Position.Type.Long, false, nullstrike, + centralReplication); + DigitalCoupon over_cash_longDigitalCallCoupon = new DigitalCoupon(underlying, strike, Position.Type.Long, + false, cashRate, nullstrike, Position.Type.Long, false, nullstrike, superReplication); IborCouponPricer pricer = new BlackIborCouponPricer(volatility); sub_cash_longDigitalCallCoupon.setPricer(pricer); central_cash_longDigitalCallCoupon.setPricer(pricer); @@ -967,100 +967,100 @@ public void testReplicationType() double central_digitalPrice = central_cash_longDigitalCallCoupon.price(vars.termStructure); double over_digitalPrice = over_cash_longDigitalCallCoupon.price(vars.termStructure); double tolerance = 1.0e-09; - if ( ( (sub_digitalPrice > central_digitalPrice) && - Math.Abs(central_digitalPrice - sub_digitalPrice)>tolerance ) || - ( (central_digitalPrice>over_digitalPrice) && - Math.Abs(central_digitalPrice - over_digitalPrice)>tolerance ) ) + if (((sub_digitalPrice > central_digitalPrice) && + Math.Abs(central_digitalPrice - sub_digitalPrice) > tolerance) || + ((central_digitalPrice > over_digitalPrice) && + Math.Abs(central_digitalPrice - over_digitalPrice) > tolerance)) { QAssert.Fail("\nCash-or-nothing: Floating Rate Coupon + Call Digital option" + - "\nVolatility = " + +(capletVolatility) + - "\nStrike = " + +(strike) + - "\nExercise = " + k+1 + " years" + - "\nSub-Replication Price = " + sub_digitalPrice + - "\nCentral-Replication Price = " + central_digitalPrice + - "\nOver-Replication Price = " + over_digitalPrice); + "\nVolatility = " + +(capletVolatility) + + "\nStrike = " + +(strike) + + "\nExercise = " + k + 1 + " years" + + "\nSub-Replication Price = " + sub_digitalPrice + + "\nCentral-Replication Price = " + central_digitalPrice + + "\nOver-Replication Price = " + over_digitalPrice); } // Floating Rate Coupon - Call Digital option - DigitalCoupon sub_cash_shortDigitalCallCoupon = new DigitalCoupon(underlying,strike, Position.Type.Short, - false, cashRate,nullstrike, Position.Type.Long, false, nullstrike,subReplication); - DigitalCoupon central_cash_shortDigitalCallCoupon = new DigitalCoupon(underlying,strike, - Position.Type.Short, false, cashRate,nullstrike, Position.Type.Long, false, nullstrike, - centralReplication); - DigitalCoupon over_cash_shortDigitalCallCoupon = new DigitalCoupon(underlying,strike, - Position.Type.Short, false, cashRate,nullstrike, Position.Type.Long, false, nullstrike, - superReplication); + DigitalCoupon sub_cash_shortDigitalCallCoupon = new DigitalCoupon(underlying, strike, Position.Type.Short, + false, cashRate, nullstrike, Position.Type.Long, false, nullstrike, subReplication); + DigitalCoupon central_cash_shortDigitalCallCoupon = new DigitalCoupon(underlying, strike, + Position.Type.Short, false, cashRate, nullstrike, Position.Type.Long, false, nullstrike, + centralReplication); + DigitalCoupon over_cash_shortDigitalCallCoupon = new DigitalCoupon(underlying, strike, + Position.Type.Short, false, cashRate, nullstrike, Position.Type.Long, false, nullstrike, + superReplication); sub_cash_shortDigitalCallCoupon.setPricer(pricer); central_cash_shortDigitalCallCoupon.setPricer(pricer); over_cash_shortDigitalCallCoupon.setPricer(pricer); sub_digitalPrice = sub_cash_shortDigitalCallCoupon.price(vars.termStructure); central_digitalPrice = central_cash_shortDigitalCallCoupon.price(vars.termStructure); over_digitalPrice = over_cash_shortDigitalCallCoupon.price(vars.termStructure); - if ( ( (sub_digitalPrice > central_digitalPrice) && - Math.Abs(central_digitalPrice - sub_digitalPrice)>tolerance ) || - ( (central_digitalPrice>over_digitalPrice) && - Math.Abs(central_digitalPrice - over_digitalPrice)>tolerance ) ) + if (((sub_digitalPrice > central_digitalPrice) && + Math.Abs(central_digitalPrice - sub_digitalPrice) > tolerance) || + ((central_digitalPrice > over_digitalPrice) && + Math.Abs(central_digitalPrice - over_digitalPrice) > tolerance)) { QAssert.Fail("\nCash-or-nothing: Floating Rate Coupon - Call Digital option" + - "\nVolatility = " + +(capletVolatility) + - "\nStrike = " + +(strike) + - "\nExercise = " + k+1 + " years" + - "\nSub-Replication Price = " + sub_digitalPrice + - "\nCentral-Replication Price = " + central_digitalPrice + - "\nOver-Replication Price = " + over_digitalPrice); + "\nVolatility = " + +(capletVolatility) + + "\nStrike = " + +(strike) + + "\nExercise = " + k + 1 + " years" + + "\nSub-Replication Price = " + sub_digitalPrice + + "\nCentral-Replication Price = " + central_digitalPrice + + "\nOver-Replication Price = " + over_digitalPrice); } // Floating Rate Coupon + Put Digital option - DigitalCoupon sub_cash_longDigitalPutCoupon = new DigitalCoupon(underlying,nullstrike, - Position.Type.Long, false, nullstrike,strike, Position.Type.Long, false, cashRate,subReplication); - DigitalCoupon central_cash_longDigitalPutCoupon = new DigitalCoupon(underlying,nullstrike, - Position.Type.Long, false, nullstrike,strike, Position.Type.Long, false, cashRate,centralReplication); - DigitalCoupon over_cash_longDigitalPutCoupon= new DigitalCoupon(underlying,nullstrike, - Position.Type.Long, false, nullstrike,strike, Position.Type.Long, false, cashRate,superReplication); + DigitalCoupon sub_cash_longDigitalPutCoupon = new DigitalCoupon(underlying, nullstrike, + Position.Type.Long, false, nullstrike, strike, Position.Type.Long, false, cashRate, subReplication); + DigitalCoupon central_cash_longDigitalPutCoupon = new DigitalCoupon(underlying, nullstrike, + Position.Type.Long, false, nullstrike, strike, Position.Type.Long, false, cashRate, centralReplication); + DigitalCoupon over_cash_longDigitalPutCoupon = new DigitalCoupon(underlying, nullstrike, + Position.Type.Long, false, nullstrike, strike, Position.Type.Long, false, cashRate, superReplication); sub_cash_longDigitalPutCoupon.setPricer(pricer); central_cash_longDigitalPutCoupon.setPricer(pricer); over_cash_longDigitalPutCoupon.setPricer(pricer); sub_digitalPrice = sub_cash_longDigitalPutCoupon.price(vars.termStructure); central_digitalPrice = central_cash_longDigitalPutCoupon.price(vars.termStructure); over_digitalPrice = over_cash_longDigitalPutCoupon.price(vars.termStructure); - if ( ( (sub_digitalPrice > central_digitalPrice) && - Math.Abs(central_digitalPrice - sub_digitalPrice)>tolerance ) || - ( (central_digitalPrice>over_digitalPrice) && - Math.Abs(central_digitalPrice - over_digitalPrice)>tolerance ) ) + if (((sub_digitalPrice > central_digitalPrice) && + Math.Abs(central_digitalPrice - sub_digitalPrice) > tolerance) || + ((central_digitalPrice > over_digitalPrice) && + Math.Abs(central_digitalPrice - over_digitalPrice) > tolerance)) { QAssert.Fail("\nCash-or-nothing: Floating Rate Coupon + Put Digital option" + - "\nVolatility = " + (capletVolatility) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nSub-Replication Price = " + sub_digitalPrice + - "\nCentral-Replication Price = " + central_digitalPrice + - "\nOver-Replication Price = " + over_digitalPrice); + "\nVolatility = " + (capletVolatility) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nSub-Replication Price = " + sub_digitalPrice + + "\nCentral-Replication Price = " + central_digitalPrice + + "\nOver-Replication Price = " + over_digitalPrice); } // Floating Rate Coupon - Put Digital option - DigitalCoupon sub_cash_shortDigitalPutCoupon = new DigitalCoupon(underlying,nullstrike, - Position.Type.Long, false, nullstrike,strike, Position.Type.Short, false, cashRate,subReplication); - DigitalCoupon central_cash_shortDigitalPutCoupon= new DigitalCoupon(underlying,nullstrike, - Position.Type.Long, false, nullstrike,strike, Position.Type.Short, false, cashRate,centralReplication); - DigitalCoupon over_cash_shortDigitalPutCoupon = new DigitalCoupon(underlying,nullstrike, - Position.Type.Long, false, nullstrike,strike, Position.Type.Short, false, cashRate,superReplication); + DigitalCoupon sub_cash_shortDigitalPutCoupon = new DigitalCoupon(underlying, nullstrike, + Position.Type.Long, false, nullstrike, strike, Position.Type.Short, false, cashRate, subReplication); + DigitalCoupon central_cash_shortDigitalPutCoupon = new DigitalCoupon(underlying, nullstrike, + Position.Type.Long, false, nullstrike, strike, Position.Type.Short, false, cashRate, centralReplication); + DigitalCoupon over_cash_shortDigitalPutCoupon = new DigitalCoupon(underlying, nullstrike, + Position.Type.Long, false, nullstrike, strike, Position.Type.Short, false, cashRate, superReplication); sub_cash_shortDigitalPutCoupon.setPricer(pricer); central_cash_shortDigitalPutCoupon.setPricer(pricer); over_cash_shortDigitalPutCoupon.setPricer(pricer); sub_digitalPrice = sub_cash_shortDigitalPutCoupon.price(vars.termStructure); central_digitalPrice = central_cash_shortDigitalPutCoupon.price(vars.termStructure); over_digitalPrice = over_cash_shortDigitalPutCoupon.price(vars.termStructure); - if ( ( (sub_digitalPrice > central_digitalPrice) && - Math.Abs(central_digitalPrice - sub_digitalPrice)>tolerance ) || - ( (central_digitalPrice>over_digitalPrice) && - Math.Abs(central_digitalPrice - over_digitalPrice)>tolerance ) ) + if (((sub_digitalPrice > central_digitalPrice) && + Math.Abs(central_digitalPrice - sub_digitalPrice) > tolerance) || + ((central_digitalPrice > over_digitalPrice) && + Math.Abs(central_digitalPrice - over_digitalPrice) > tolerance)) { QAssert.Fail("\nCash-or-nothing: Floating Rate Coupon + Call Digital option" + - "\nVolatility = " + (capletVolatility) + - "\nStrike = " + (strike) + - "\nExercise = " + k+1 + " years" + - "\nSub-Replication Price = " + sub_digitalPrice + - "\nCentral-Replication Price = " + central_digitalPrice + - "\nOver-Replication Price = " + over_digitalPrice); + "\nVolatility = " + (capletVolatility) + + "\nStrike = " + (strike) + + "\nExercise = " + k + 1 + " years" + + "\nSub-Replication Price = " + sub_digitalPrice + + "\nCentral-Replication Price = " + central_digitalPrice + + "\nOver-Replication Price = " + over_digitalPrice); } } } diff --git a/tests/QLNet.Tests/T_DigitalOption.cs b/tests/QLNet.Tests/T_DigitalOption.cs index a255392ea..8c47d310d 100644 --- a/tests/QLNet.Tests/T_DigitalOption.cs +++ b/tests/QLNet.Tests/T_DigitalOption.cs @@ -4,7 +4,7 @@ // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a // copy of the license along with this program; if not, license is -// available online at . +// available at . // // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ @@ -19,7 +19,7 @@ #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -42,8 +42,8 @@ struct DigitalOptionData public double result; // expected result public double tol; // tolerance public bool knockin; // true if knock-in - public DigitalOptionData( Option.Type type_, double strike_, double s_, double q_, double r_, double t_, double v_, - double result_, double tol_, bool knockin_ ) + public DigitalOptionData(Option.Type type_, double strike_, double s_, double q_, double r_, double t_, double v_, + double result_, double tol_, bool knockin_) { type = type_; strike = strike_; @@ -58,92 +58,93 @@ public DigitalOptionData( Option.Type type_, double strike_, double s_, double q } } - void REPORT_FAILURE( string greekName, StrikedTypePayoff payoff, Exercise exercise, double s, double q, double r, - Date today, double v, double expected, double calculated, double error, double tolerance, - bool knockin ) + void REPORT_FAILURE(string greekName, StrikedTypePayoff payoff, Exercise exercise, double s, double q, double r, + Date today, double v, double expected, double calculated, double error, double tolerance, + bool knockin) { - QAssert.Fail( exercise + " " - + payoff.optionType() + " option with " - + payoff + " payoff:\n" - + " spot value: " + s + "\n" - + " strike: " + payoff.strike() + "\n" - + " dividend yield: " + q + "\n" - + " risk-free rate: " + r + "\n" - + " reference date: " + today + "\n" - + " maturity: " + exercise.lastDate() + "\n" - + " volatility: " + v + "\n\n" - + " expected " + greekName + ": " + expected + "\n" - + " calculated " + greekName + ": " + calculated + "\n" - + " error: " + error + "\n" - + " tolerance: " + tolerance + "\n" - + " knock_in: " + knockin ); + QAssert.Fail(exercise + " " + + payoff.optionType() + " option with " + + payoff + " payoff:\n" + + " spot value: " + s + "\n" + + " strike: " + payoff.strike() + "\n" + + " dividend yield: " + q + "\n" + + " risk-free rate: " + r + "\n" + + " reference date: " + today + "\n" + + " maturity: " + exercise.lastDate() + "\n" + + " volatility: " + v + "\n\n" + + " expected " + greekName + ": " + expected + "\n" + + " calculated " + greekName + ": " + calculated + "\n" + + " error: " + error + "\n" + + " tolerance: " + tolerance + "\n" + + " knock_in: " + knockin); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testCashOrNothingEuropeanValues() { // Testing European cash-or-nothing digital option - DigitalOptionData[] values = { - // "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 - pag 88 - // type, strike, spot, q, r, t, vol, value, tol - new DigitalOptionData(Option.Type.Put, 80.00, 100.0, 0.06, 0.06, 0.75, 0.35, 2.6710, 1e-4, true) + DigitalOptionData[] values = + { + // "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 - pag 88 + // type, strike, spot, q, r, t, vol, value, tol + new DigitalOptionData(Option.Type.Put, 80.00, 100.0, 0.06, 0.06, 0.75, 0.35, 2.6710, 1e-4, true) }; DayCounter dc = new Actual360(); Date today = Date.Today; - SimpleQuote spot = new SimpleQuote( 0.0 ); - SimpleQuote qRate = new SimpleQuote( 0.0 ); - YieldTermStructure qTS = Utilities.flatRate( today, qRate, dc ); - SimpleQuote rRate = new SimpleQuote( 0.0 ); - YieldTermStructure rTS = Utilities.flatRate( today, rRate, dc ); - SimpleQuote vol = new SimpleQuote( 0.0 ); - BlackVolTermStructure volTS = Utilities.flatVol( today, vol, dc ); + SimpleQuote spot = new SimpleQuote(0.0); + SimpleQuote qRate = new SimpleQuote(0.0); + YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc); + SimpleQuote rRate = new SimpleQuote(0.0); + YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc); + SimpleQuote vol = new SimpleQuote(0.0); + BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - for ( int i = 0; i < values.Length; i++ ) + for (int i = 0; i < values.Length; i++) { - StrikedTypePayoff payoff = new CashOrNothingPayoff( values[i].type, values[i].strike, 10.0 ); + StrikedTypePayoff payoff = new CashOrNothingPayoff(values[i].type, values[i].strike, 10.0); - Date exDate = today + Convert.ToInt32( values[i].t * 360 + 0.5 ); - Exercise exercise = new EuropeanExercise( exDate ); + Date exDate = today + Convert.ToInt32(values[i].t * 360 + 0.5); + Exercise exercise = new EuropeanExercise(exDate); - spot.setValue( values[i].s ); - qRate.setValue( values[i].q ); - rRate.setValue( values[i].r ); - vol.setValue( values[i].v ); + spot.setValue(values[i].s); + qRate.setValue(values[i].q); + rRate.setValue(values[i].r); + vol.setValue(values[i].v); - BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess( new Handle( spot ), - new Handle( qTS ), - new Handle( rTS ), - new Handle( volTS ) ); + BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); - IPricingEngine engine = new AnalyticEuropeanEngine( stochProcess ); + IPricingEngine engine = new AnalyticEuropeanEngine(stochProcess); - VanillaOption opt = new VanillaOption( payoff, exercise ); - opt.setPricingEngine( engine ); + VanillaOption opt = new VanillaOption(payoff, exercise); + opt.setPricingEngine(engine); double calculated = opt.NPV(); - double error = Math.Abs( calculated - values[i].result ); - if ( error > values[i].tol ) + double error = Math.Abs(calculated - values[i].result); + if (error > values[i].tol) { - REPORT_FAILURE( "value", payoff, exercise, values[i].s, values[i].q, + REPORT_FAILURE("value", payoff, exercise, values[i].s, values[i].q, values[i].r, today, values[i].v, values[i].result, - calculated, error, values[i].tol, values[i].knockin ); + calculated, error, values[i].tol, values[i].knockin); } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testAssetOrNothingEuropeanValues() { @@ -151,28 +152,29 @@ public void testAssetOrNothingEuropeanValues() // Testing European asset-or-nothing digital option // "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 - pag 90 - DigitalOptionData[] values = { + DigitalOptionData[] values = + { // type, strike, spot, q, r, t, vol, value, tol - new DigitalOptionData(Option.Type.Put, 65.00, 70.0, 0.05, 0.07, 0.50, 0.27, 20.2069, 1e-4, true ), + new DigitalOptionData(Option.Type.Put, 65.00, 70.0, 0.05, 0.07, 0.50, 0.27, 20.2069, 1e-4, true), }; DayCounter dc = new Actual360(); Date today = Date.Today; - SimpleQuote spot=new SimpleQuote(0.0); - SimpleQuote qRate=new SimpleQuote(0.0); + SimpleQuote spot = new SimpleQuote(0.0); + SimpleQuote qRate = new SimpleQuote(0.0); YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc); - SimpleQuote rRate=new SimpleQuote(0.0); + SimpleQuote rRate = new SimpleQuote(0.0); YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc); - SimpleQuote vol=new SimpleQuote(0.0); + SimpleQuote vol = new SimpleQuote(0.0); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - for (int i=0; i(spot), - new Handle(qTS), - new Handle(rTS), - new Handle(volTS)); + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); - IPricingEngine engine=new AnalyticEuropeanEngine(stochProcess); + IPricingEngine engine = new AnalyticEuropeanEngine(stochProcess); VanillaOption opt = new VanillaOption(payoff, exercise); opt.setPricingEngine(engine); double calculated = opt.NPV(); - double error = Math.Abs(calculated-values[i].result); + double error = Math.Abs(calculated - values[i].result); if (error > values[i].tol) { REPORT_FAILURE("value", payoff, exercise, values[i].s, values[i].q, @@ -201,18 +203,19 @@ public void testAssetOrNothingEuropeanValues() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testGapEuropeanValues() { // Testing European gap digital option // "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 - pag 88 - DigitalOptionData[] values = { + DigitalOptionData[] values = + { // type, strike, spot, q, r, t, vol, value, tol - new DigitalOptionData( Option.Type.Call, 50.00, 50.0, 0.00, 0.09, 0.50, 0.20, -0.0053, 1e-4, true ), + new DigitalOptionData(Option.Type.Call, 50.00, 50.0, 0.00, 0.09, 0.50, 0.20, -0.0053, 1e-4, true), }; DayCounter dc = new Actual360(); @@ -226,11 +229,11 @@ public void testGapEuropeanValues() SimpleQuote vol = new SimpleQuote(0.0); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - for (int i=0; i(spot), - new Handle(qTS), - new Handle(rTS), - new Handle(volTS)); + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); IPricingEngine engine = new AnalyticEuropeanEngine(stochProcess); @@ -249,7 +252,7 @@ public void testGapEuropeanValues() opt.setPricingEngine(engine); double calculated = opt.NPV(); - double error = Math.Abs(calculated-values[i].result); + double error = Math.Abs(calculated - values[i].result); if (error > values[i].tol) { REPORT_FAILURE("value", payoff, exercise, values[i].s, values[i].q, @@ -260,29 +263,30 @@ public void testGapEuropeanValues() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testCashAtHitOrNothingAmericanValues() { // Testing American cash-(at-hit)-or-nothing digital option - DigitalOptionData[] values = { - // type, strike, spot, q, r, t, vol, value, tol - // "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 - pag 95, case 1,2 - new DigitalOptionData( Option.Type.Put, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 9.7264, 1e-4, true), - new DigitalOptionData( Option.Type.Call, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 11.6553, 1e-4, true), - - // the following cases are not taken from a reference paper or book - // in the money options (guaranteed immediate payoff) - new DigitalOptionData( Option.Type.Call, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 15.0000, 1e-16, true), - new DigitalOptionData( Option.Type.Put, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 15.0000, 1e-16, true), - // non null dividend (cross-tested with MC simulation) - new DigitalOptionData( Option.Type.Put, 100.00, 105.00, 0.20, 0.10, 0.5, 0.20, 12.2715, 1e-4, true), - new DigitalOptionData( Option.Type.Call, 100.00, 95.00, 0.20, 0.10, 0.5, 0.20, 8.9109, 1e-4, true), - new DigitalOptionData( Option.Type.Call, 100.00, 105.00, 0.20, 0.10, 0.5, 0.20, 15.0000, 1e-16, true), - new DigitalOptionData( Option.Type.Put, 100.00, 95.00, 0.20, 0.10, 0.5, 0.20, 15.0000, 1e-16, true) + DigitalOptionData[] values = + { + // type, strike, spot, q, r, t, vol, value, tol + // "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 - pag 95, case 1,2 + new DigitalOptionData(Option.Type.Put, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 9.7264, 1e-4, true), + new DigitalOptionData(Option.Type.Call, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 11.6553, 1e-4, true), + + // the following cases are not taken from a reference paper or book + // in the money options (guaranteed immediate payoff) + new DigitalOptionData(Option.Type.Call, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 15.0000, 1e-16, true), + new DigitalOptionData(Option.Type.Put, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 15.0000, 1e-16, true), + // non null dividend (cross-tested with MC simulation) + new DigitalOptionData(Option.Type.Put, 100.00, 105.00, 0.20, 0.10, 0.5, 0.20, 12.2715, 1e-4, true), + new DigitalOptionData(Option.Type.Call, 100.00, 95.00, 0.20, 0.10, 0.5, 0.20, 8.9109, 1e-4, true), + new DigitalOptionData(Option.Type.Call, 100.00, 105.00, 0.20, 0.10, 0.5, 0.20, 15.0000, 1e-16, true), + new DigitalOptionData(Option.Type.Put, 100.00, 95.00, 0.20, 0.10, 0.5, 0.20, 15.0000, 1e-16, true) }; DayCounter dc = new Actual360(); @@ -296,22 +300,22 @@ public void testCashAtHitOrNothingAmericanValues() SimpleQuote vol = new SimpleQuote(0.0); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - for (int i=0; i(spot), - new Handle(qTS), - new Handle(rTS), - new Handle(volTS)); + BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); IPricingEngine engine = new AnalyticDigitalAmericanEngine(stochProcess); @@ -319,7 +323,7 @@ public void testCashAtHitOrNothingAmericanValues() opt.setPricingEngine(engine); double calculated = opt.NPV(); - double error = Math.Abs(calculated-values[i].result); + double error = Math.Abs(calculated - values[i].result); if (error > values[i].tol) { REPORT_FAILURE("value", payoff, amExercise, values[i].s, @@ -330,27 +334,28 @@ public void testCashAtHitOrNothingAmericanValues() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testAssetAtHitOrNothingAmericanValues() { // Testing American asset-(at-hit)-or-nothing "digital option - DigitalOptionData[] values = { - // type, strike, spot, q, r, t, vol, value, tol - // "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 - pag 95, case 3,4 - new DigitalOptionData( Option.Type.Put, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 64.8426, 1e-04, true ), // Haug value is wrong here, Haug VBA code is right - new DigitalOptionData( Option.Type.Call, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 77.7017, 1e-04, true ), // Haug value is wrong here, Haug VBA code is right - // data from Haug VBA code results - new DigitalOptionData( Option.Type.Put, 100.00, 105.00, 0.01, 0.10, 0.5, 0.20, 65.7811, 1e-04, true ), - new DigitalOptionData( Option.Type.Call, 100.00, 95.00, 0.01, 0.10, 0.5, 0.20, 76.8858, 1e-04, true ), - // in the money options (guaranteed immediate payoff = spot) - new DigitalOptionData( Option.Type.Call, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20,105.0000, 1e-16, true ), - new DigitalOptionData( Option.Type.Put, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 95.0000, 1e-16, true ), - new DigitalOptionData( Option.Type.Call, 100.00, 105.00, 0.01, 0.10, 0.5, 0.20,105.0000, 1e-16, true ), - new DigitalOptionData( Option.Type.Put, 100.00, 95.00, 0.01, 0.10, 0.5, 0.20, 95.0000, 1e-16, true ) + DigitalOptionData[] values = + { + // type, strike, spot, q, r, t, vol, value, tol + // "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 - pag 95, case 3,4 + new DigitalOptionData(Option.Type.Put, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 64.8426, 1e-04, true), // Haug value is wrong here, Haug VBA code is right + new DigitalOptionData(Option.Type.Call, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 77.7017, 1e-04, true), // Haug value is wrong here, Haug VBA code is right + // data from Haug VBA code results + new DigitalOptionData(Option.Type.Put, 100.00, 105.00, 0.01, 0.10, 0.5, 0.20, 65.7811, 1e-04, true), + new DigitalOptionData(Option.Type.Call, 100.00, 95.00, 0.01, 0.10, 0.5, 0.20, 76.8858, 1e-04, true), + // in the money options (guaranteed immediate payoff = spot) + new DigitalOptionData(Option.Type.Call, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 105.0000, 1e-16, true), + new DigitalOptionData(Option.Type.Put, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 95.0000, 1e-16, true), + new DigitalOptionData(Option.Type.Call, 100.00, 105.00, 0.01, 0.10, 0.5, 0.20, 105.0000, 1e-16, true), + new DigitalOptionData(Option.Type.Put, 100.00, 95.00, 0.01, 0.10, 0.5, 0.20, 95.0000, 1e-16, true) }; DayCounter dc = new Actual360(); @@ -364,12 +369,12 @@ public void testAssetAtHitOrNothingAmericanValues() SimpleQuote vol = new SimpleQuote(0.25); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - for (int i=0; i< values.Length; i++) + for (int i = 0; i < values.Length; i++) { StrikedTypePayoff payoff = new AssetOrNothingPayoff(values[i].type, values[i].strike); - Date exDate = today + Convert.ToInt32(values[i].t*360+0.5); - Exercise amExercise = new AmericanExercise(today,exDate); + Date exDate = today + Convert.ToInt32(values[i].t * 360 + 0.5); + Exercise amExercise = new AmericanExercise(today, exDate); spot .setValue(values[i].s); qRate.setValue(values[i].q); @@ -377,9 +382,9 @@ public void testAssetAtHitOrNothingAmericanValues() vol .setValue(values[i].v); BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), - new Handle(qTS), - new Handle(rTS), - new Handle(volTS)); + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); IPricingEngine engine = new AnalyticDigitalAmericanEngine(stochProcess); @@ -387,7 +392,7 @@ public void testAssetAtHitOrNothingAmericanValues() opt.setPricingEngine(engine); double calculated = opt.NPV(); - double error = Math.Abs(calculated-values[i].result); + double error = Math.Abs(calculated - values[i].result); if (error > values[i].tol) { REPORT_FAILURE("value", payoff, amExercise, values[i].s, @@ -398,26 +403,27 @@ public void testAssetAtHitOrNothingAmericanValues() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testCashAtExpiryOrNothingAmericanValues() { // Testing American cash-(at-expiry)-or-nothing digital option - DigitalOptionData[] values = { - // type, strike, spot, q, r, t, vol, value, tol - // "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 - pag 95, case 5,6,9,10 - new DigitalOptionData( Option.Type.Put, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 9.3604, 1e-4, true ), - new DigitalOptionData( Option.Type.Call, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 11.2223, 1e-4, true ), - new DigitalOptionData( Option.Type.Put, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 4.9081, 1e-4, false ), - new DigitalOptionData( Option.Type.Call, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 3.0461, 1e-4, false ), - // in the money options (guaranteed discounted payoff) - new DigitalOptionData( Option.Type.Call, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 15.0000*Math.Exp(-0.05), 1e-12, true ), - new DigitalOptionData( Option.Type.Put, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 15.0000*Math.Exp(-0.05), 1e-12, true ), - // out of bonds case - new DigitalOptionData( Option.Type.Call, 2.37, 2.33, 0.07, 0.43,0.19,0.005, 0.0000, 1e-4, false ), + DigitalOptionData[] values = + { + // type, strike, spot, q, r, t, vol, value, tol + // "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 - pag 95, case 5,6,9,10 + new DigitalOptionData(Option.Type.Put, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 9.3604, 1e-4, true), + new DigitalOptionData(Option.Type.Call, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 11.2223, 1e-4, true), + new DigitalOptionData(Option.Type.Put, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 4.9081, 1e-4, false), + new DigitalOptionData(Option.Type.Call, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 3.0461, 1e-4, false), + // in the money options (guaranteed discounted payoff) + new DigitalOptionData(Option.Type.Call, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 15.0000 * Math.Exp(-0.05), 1e-12, true), + new DigitalOptionData(Option.Type.Put, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 15.0000 * Math.Exp(-0.05), 1e-12, true), + // out of bonds case + new DigitalOptionData(Option.Type.Call, 2.37, 2.33, 0.07, 0.43, 0.19, 0.005, 0.0000, 1e-4, false), }; DayCounter dc = new Actual360(); @@ -431,12 +437,12 @@ public void testCashAtExpiryOrNothingAmericanValues() SimpleQuote vol = new SimpleQuote(0.25); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - for (int i=0; i(spot), - new Handle(qTS), - new Handle(rTS), - new Handle(volTS)); + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); IPricingEngine engine; if (values[i].knockin) @@ -458,7 +464,7 @@ public void testCashAtExpiryOrNothingAmericanValues() opt.setPricingEngine(engine); double calculated = opt.NPV(); - double error = Math.Abs(calculated-values[i].result); + double error = Math.Abs(calculated - values[i].result); if (error > values[i].tol) { REPORT_FAILURE("value", payoff, amExercise, values[i].s, @@ -469,31 +475,32 @@ public void testCashAtExpiryOrNothingAmericanValues() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testAssetAtExpiryOrNothingAmericanValues() { // Testing American asset-(at-expiry)-or-nothing digital option - DigitalOptionData[] values = { - // type, strike, spot, q, r, t, vol, value, tol - // "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 - pag 95, case 7,8,11,12 - new DigitalOptionData( Option.Type.Put, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 64.8426, 1e-04, true ), - new DigitalOptionData( Option.Type.Call, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 77.7017, 1e-04, true ), - new DigitalOptionData( Option.Type.Put, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 40.1574, 1e-04, false ), - new DigitalOptionData( Option.Type.Call, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 17.2983, 1e-04, false ), - // data from Haug VBA code results - new DigitalOptionData( Option.Type.Put, 100.00, 105.00, 0.01, 0.10, 0.5, 0.20, 65.5291, 1e-04, true ), - new DigitalOptionData( Option.Type.Call, 100.00, 95.00, 0.01, 0.10, 0.5, 0.20, 76.5951, 1e-04, true ), - // in the money options (guaranteed discounted payoff = forward * riskFreeDiscount - // = spot * dividendDiscount) - new DigitalOptionData( Option.Type.Call, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20,105.0000, 1e-12, true ), - new DigitalOptionData( Option.Type.Put, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 95.0000, 1e-12, true ), - new DigitalOptionData( Option.Type.Call, 100.00, 105.00, 0.01, 0.10, 0.5, 0.20,105.0000*Math.Exp(-0.005), 1e-12, true ), - new DigitalOptionData( Option.Type.Put, 100.00, 95.00, 0.01, 0.10, 0.5, 0.20, 95.0000*Math.Exp(-0.005), 1e-12, true ) + DigitalOptionData[] values = + { + // type, strike, spot, q, r, t, vol, value, tol + // "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 - pag 95, case 7,8,11,12 + new DigitalOptionData(Option.Type.Put, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 64.8426, 1e-04, true), + new DigitalOptionData(Option.Type.Call, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 77.7017, 1e-04, true), + new DigitalOptionData(Option.Type.Put, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 40.1574, 1e-04, false), + new DigitalOptionData(Option.Type.Call, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 17.2983, 1e-04, false), + // data from Haug VBA code results + new DigitalOptionData(Option.Type.Put, 100.00, 105.00, 0.01, 0.10, 0.5, 0.20, 65.5291, 1e-04, true), + new DigitalOptionData(Option.Type.Call, 100.00, 95.00, 0.01, 0.10, 0.5, 0.20, 76.5951, 1e-04, true), + // in the money options (guaranteed discounted payoff = forward * riskFreeDiscount + // = spot * dividendDiscount) + new DigitalOptionData(Option.Type.Call, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 105.0000, 1e-12, true), + new DigitalOptionData(Option.Type.Put, 100.00, 95.00, 0.00, 0.10, 0.5, 0.20, 95.0000, 1e-12, true), + new DigitalOptionData(Option.Type.Call, 100.00, 105.00, 0.01, 0.10, 0.5, 0.20, 105.0000 * Math.Exp(-0.005), 1e-12, true), + new DigitalOptionData(Option.Type.Put, 100.00, 95.00, 0.01, 0.10, 0.5, 0.20, 95.0000 * Math.Exp(-0.005), 1e-12, true) }; DayCounter dc = new Actual360(); @@ -507,13 +514,13 @@ public void testAssetAtExpiryOrNothingAmericanValues() SimpleQuote vol = new SimpleQuote(0.25); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - for (int i=0; i< values.Length; i++) + for (int i = 0; i < values.Length; i++) { StrikedTypePayoff payoff = new AssetOrNothingPayoff(values[i].type, values[i].strike); - Date exDate = today + Convert.ToInt32(values[i].t*360+0.5); - Exercise amExercise = new AmericanExercise(today,exDate,true); + Date exDate = today + Convert.ToInt32(values[i].t * 360 + 0.5); + Exercise amExercise = new AmericanExercise(today, exDate, true); spot .setValue(values[i].s); qRate.setValue(values[i].q); @@ -521,9 +528,9 @@ public void testAssetAtExpiryOrNothingAmericanValues() vol .setValue(values[i].v); BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), - new Handle(qTS), - new Handle(rTS), - new Handle(volTS)); + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); IPricingEngine engine; if (values[i].knockin) @@ -535,7 +542,7 @@ public void testAssetAtExpiryOrNothingAmericanValues() opt.setPricingEngine(engine); double calculated = opt.NPV(); - double error = Math.Abs(calculated-values[i].result); + double error = Math.Abs(calculated - values[i].result); if (error > values[i].tol) { REPORT_FAILURE("value", payoff, amExercise, values[i].s, @@ -546,9 +553,9 @@ public void testAssetAtExpiryOrNothingAmericanValues() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testCashAtHitOrNothingAmericanGreeks() { @@ -557,9 +564,9 @@ public void testCashAtHitOrNothingAmericanGreeks() using (SavedSettings backup = new SavedSettings()) { - SortedDictionary calculated = new SortedDictionary(); - SortedDictionary expected = new SortedDictionary(); - SortedDictionary tolerance = new SortedDictionary(); // std::map calculated, expected, tolerance; + SortedDictionary calculated = new SortedDictionary(); + SortedDictionary expected = new SortedDictionary(); + SortedDictionary tolerance = new SortedDictionary(); // std::map calculated, expected, tolerance; tolerance["delta"] = 5.0e-5; tolerance["gamma"] = 5.0e-5; @@ -579,7 +586,7 @@ public void testCashAtHitOrNothingAmericanGreeks() SimpleQuote spot = new SimpleQuote(0.0); SimpleQuote qRate = new SimpleQuote(0.0); - Handle qTS = new Handle( Utilities.flatRate(qRate, dc)); + Handle qTS = new Handle(Utilities.flatRate(qRate, dc)); SimpleQuote rRate = new SimpleQuote(0.0); Handle rTS = new Handle(Utilities.flatRate(rRate, dc)); SimpleQuote vol = new SimpleQuote(0.0); @@ -588,10 +595,10 @@ public void testCashAtHitOrNothingAmericanGreeks() // there is no cycling on different residual times Date exDate = today + 360; Exercise exercise = new EuropeanExercise(exDate); - Exercise amExercise = new AmericanExercise(today,exDate,false); + Exercise amExercise = new AmericanExercise(today, exDate, false); Exercise[] exercises = { exercise, amExercise }; - BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot),qTS, rTS, volTS); + BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), qTS, rTS, volTS); IPricingEngine euroEngine = new AnalyticEuropeanEngine(stochProcess); @@ -599,25 +606,25 @@ public void testCashAtHitOrNothingAmericanGreeks() IPricingEngine[] engines = { euroEngine, amEngine }; - bool knockin=true; - for (int j=0; j 1.0e-6) { // perturb spot and get delta and gamma - double du = u*1.0e-4; - spot.setValue(u+du); + double du = u * 1.0e-4; + spot.setValue(u + du); double value_p = opt.NPV(), delta_p = opt.delta(); - spot.setValue(u-du); + spot.setValue(u - du); double value_m = opt.NPV(), delta_m = opt.delta(); spot.setValue(u); - expected["delta"] = (value_p - value_m)/(2*du); - expected["gamma"] = (delta_p - delta_m)/(2*du); + expected["delta"] = (value_p - value_m) / (2 * du); + expected["gamma"] = (delta_p - delta_m) / (2 * du); // perturb rates and get rho and dividend rho - double dr = r*1.0e-4; - rRate.setValue(r+dr); + double dr = r * 1.0e-4; + rRate.setValue(r + dr); value_p = opt.NPV(); - rRate.setValue(r-dr); + rRate.setValue(r - dr); value_m = opt.NPV(); rRate.setValue(r); - expected["rho"] = (value_p - value_m)/(2*dr); + expected["rho"] = (value_p - value_m) / (2 * dr); // check //std::map::iterator it; @@ -669,7 +676,7 @@ public void testCashAtHitOrNothingAmericanGreeks() double expct = expected [greek], calcl = calculated[greek], tol = tolerance [greek]; - double error = Utilities.relativeError( expct, calcl, value ); + double error = Utilities.relativeError(expct, calcl, value); if (error > tol) { REPORT_FAILURE(greek, payoff, exercise, diff --git a/tests/QLNet.Tests/T_DividendOption.cs b/tests/QLNet.Tests/T_DividendOption.cs index 32d77ab83..79a71f39e 100644 --- a/tests/QLNet.Tests/T_DividendOption.cs +++ b/tests/QLNet.Tests/T_DividendOption.cs @@ -6,7 +6,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -20,7 +20,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; using System; @@ -38,26 +38,26 @@ public void REPORT_FAILURE(string greekName, StrikedTypePayoff payoff, Exercise double tolerance) { QAssert.Fail(exercise + " " - + payoff.optionType() + " option with " - + payoff + " payoff:\n" - + " spot value: " + s + "\n" - + " strike: " + payoff.strike() + "\n" - + " dividend yield: " + q + "\n" - + " risk-free rate: " + r + "\n" - + " reference date: " + today + "\n" - + " maturity: " + exercise.lastDate() + "\n" - + " volatility: " + v + "\n\n" - + " expected " + greekName + ": " + expected + "\n" - + " calculated " + greekName + ": " + calculated + "\n" - + " error: " + error + "\n" - + " tolerance: " + tolerance); + + payoff.optionType() + " option with " + + payoff + " payoff:\n" + + " spot value: " + s + "\n" + + " strike: " + payoff.strike() + "\n" + + " dividend yield: " + q + "\n" + + " risk-free rate: " + r + "\n" + + " reference date: " + today + "\n" + + " maturity: " + exercise.lastDate() + "\n" + + " volatility: " + v + "\n\n" + + " expected " + greekName + ": " + expected + "\n" + + " calculated " + greekName + ": " + calculated + "\n" + + " error: " + error + "\n" + + " tolerance: " + tolerance); } - private void testFdGreeks(Date today, Exercise exercise) where Engine : IFDEngine, new() + private void testFdGreeks(Date today, Exercise exercise) where Engine : IFDEngine, new () { Dictionary calculated = new Dictionary(), - expected = new Dictionary(), - tolerance = new Dictionary(); + expected = new Dictionary(), + tolerance = new Dictionary(); tolerance.Add("delta", 5.0e-3); tolerance.Add("gamma", 7.0e-3); // tolerance["theta"] = 1.0e-2; @@ -86,8 +86,8 @@ public void REPORT_FAILURE(string greekName, StrikedTypePayoff payoff, Exercise List dividendDates = new List(); List dividends = new List(); for (Date d = today + new Period(3, TimeUnit.Months); - d < exercise.lastDate(); - d += new Period(6, TimeUnit.Months)) + d < exercise.lastDate(); + d += new Period(6, TimeUnit.Months)) { dividendDates.Add(d); dividends.Add(5.0); @@ -173,7 +173,7 @@ public void REPORT_FAILURE(string greekName, StrikedTypePayoff payoff, Exercise } } - private void testFdDegenerate(Date today, Exercise exercise) where Engine : IFDEngine, new() + private void testFdDegenerate(Date today, Exercise exercise) where Engine : IFDEngine, new () { DayCounter dc = new Actual360(); SimpleQuote spot = new SimpleQuote(54.625); @@ -213,16 +213,16 @@ public void REPORT_FAILURE(string greekName, StrikedTypePayoff payoff, Exercise if (Math.Abs(refValue - value) > tolerance) QAssert.Fail("NPV changed by null dividend :\n" - + " previous value: " + value + "\n" - + " current value: " + refValue + "\n" - + " change: " + (value - refValue)); + + " previous value: " + value + "\n" + + " current value: " + refValue + "\n" + + " change: " + (value - refValue)); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testEuropeanValues() { @@ -263,8 +263,8 @@ public void testEuropeanValues() List dividendDates = new List(); List dividends = new List(); for (Date d = today + new Period(3, TimeUnit.Months); - d < exercise.lastDate(); - d += new Period(6, TimeUnit.Months)) + d < exercise.lastDate(); + d += new Period(6, TimeUnit.Months)) { dividendDates.Add(d); @@ -274,7 +274,7 @@ public void testEuropeanValues() StrikedTypePayoff payoff = new PlainVanillaPayoff(types[i], strikes[j]); BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), - qTS, rTS, volTS); + qTS, rTS, volTS); IPricingEngine ref_engine = new AnalyticEuropeanEngine(stochProcess); @@ -296,7 +296,7 @@ public void testEuropeanValues() { double u = underlyings[l]; double q = qRates[m], - r = rRates[n]; + r = rRates[n]; double v = vols[p]; spot.setValue(u); qRate.setValue(q); @@ -360,7 +360,7 @@ private void testEuropeanKnownValue() StrikedTypePayoff payoff = new PlainVanillaPayoff(Option.Type.Call, 40.0); BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), - qTS, rTS, volTS); + qTS, rTS, volTS); IPricingEngine engine = new AnalyticDividendEuropeanEngine(stochProcess); @@ -389,9 +389,9 @@ private void testEuropeanKnownValue() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testEuropeanStartLimit() { @@ -460,7 +460,7 @@ public void testEuropeanStartLimit() { double u = underlyings[l]; double q = qRates[m], - r = rRates[n]; + r = rRates[n]; double v = vols[p]; spot.setValue(u); qRate.setValue(q); @@ -489,9 +489,9 @@ public void testEuropeanStartLimit() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testEuropeanGreeks() { @@ -499,8 +499,8 @@ public void testEuropeanGreeks() using (SavedSettings backup = new SavedSettings()) { Dictionary calculated = new Dictionary(), - expected = new Dictionary(), - tolerance = new Dictionary(); + expected = new Dictionary(), + tolerance = new Dictionary(); tolerance["delta"] = 1.0e-5; tolerance["gamma"] = 1.0e-5; tolerance["theta"] = 1.0e-5; @@ -567,7 +567,7 @@ public void testEuropeanGreeks() { double u = underlyings[l]; double q = qRates[m], - r = rRates[n]; + r = rRates[n]; double v = vols[p]; spot.setValue(u); qRate.setValue(q); @@ -587,10 +587,10 @@ public void testEuropeanGreeks() double du = u * 1.0e-4; spot.setValue(u + du); double value_p = option.NPV(), - delta_p = option.delta(); + delta_p = option.delta(); spot.setValue(u - du); double value_m = option.NPV(), - delta_m = option.delta(); + delta_m = option.delta(); spot.setValue(u); expected["delta"] = (value_p - value_m) / (2 * du); expected["gamma"] = (delta_p - delta_m) / (2 * du); @@ -649,9 +649,9 @@ public void testEuropeanGreeks() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testFdEuropeanValues() { @@ -759,9 +759,9 @@ public void testFdEuropeanValues() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testFdEuropeanGreeks() { @@ -782,9 +782,9 @@ public void testFdEuropeanGreeks() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testFdAmericanGreeks() { @@ -805,9 +805,9 @@ public void testFdAmericanGreeks() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testFdEuropeanDegenerate() { @@ -825,9 +825,9 @@ public void testFdEuropeanDegenerate() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testFdAmericanDegenerate() { @@ -844,4 +844,4 @@ public void testFdAmericanDegenerate() } } } -} \ No newline at end of file +} diff --git a/tests/QLNet.Tests/T_DoubleBarrierOption.cs b/tests/QLNet.Tests/T_DoubleBarrierOption.cs index 805fc28d0..dd7576a14 100644 --- a/tests/QLNet.Tests/T_DoubleBarrierOption.cs +++ b/tests/QLNet.Tests/T_DoubleBarrierOption.cs @@ -1,22 +1,22 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; using System; @@ -29,54 +29,54 @@ namespace TestSuite #endif public class T_DoubleBarrierOption { - public void REPORT_FAILURE( string greekName, DoubleBarrier.Type barrierType, double barrierlo, double barrierhi, + public void REPORT_FAILURE(string greekName, DoubleBarrier.Type barrierType, double barrierlo, double barrierhi, StrikedTypePayoff payoff, Exercise exercise, double s, double q, double r, Date today, double v, double expected, double calculated, double error, - double tolerance ) + double tolerance) { - QAssert.Fail( barrierType + " " + exercise + " " - + payoff.optionType() + " option with " - + payoff + " payoff:\n" - + " underlying value: " + s + "\n" - + " strike: " + payoff.strike() + "\n" - + " barrier low: " + barrierlo + "\n" - + " barrier high: " + barrierhi + "\n" - + " dividend yield: " + q + "\n" - + " risk-free rate: " + r + "\n" - + " reference date: " + today + "\n" - + " maturity: " + exercise.lastDate() + "\n" - + " volatility: " + v + "\n\n" - + " expected " + greekName + ": " + expected + "\n" - + " calculated " + greekName + ": " + calculated + "\n" - + " error: " + error + "\n" - + " tolerance: " + tolerance ); + QAssert.Fail(barrierType + " " + exercise + " " + + payoff.optionType() + " option with " + + payoff + " payoff:\n" + + " underlying value: " + s + "\n" + + " strike: " + payoff.strike() + "\n" + + " barrier low: " + barrierlo + "\n" + + " barrier high: " + barrierhi + "\n" + + " dividend yield: " + q + "\n" + + " risk-free rate: " + r + "\n" + + " reference date: " + today + "\n" + + " maturity: " + exercise.lastDate() + "\n" + + " volatility: " + v + "\n\n" + + " expected " + greekName + ": " + expected + "\n" + + " calculated " + greekName + ": " + calculated + "\n" + + " error: " + error + "\n" + + " tolerance: " + tolerance); } - public void REPORT_FAILURE_VANNAVOLGA( string greekName, DoubleBarrier.Type barrierType, - double barrier1, double barrier2,double rebate, - StrikedTypePayoff payoff, Exercise exercise, double s, double q, - double r, Date today, double vol25Put, double atmVol, double vol25Call, double v, - double expected, double calculated, double error, double tolerance ) + public void REPORT_FAILURE_VANNAVOLGA(string greekName, DoubleBarrier.Type barrierType, + double barrier1, double barrier2, double rebate, + StrikedTypePayoff payoff, Exercise exercise, double s, double q, + double r, Date today, double vol25Put, double atmVol, double vol25Call, double v, + double expected, double calculated, double error, double tolerance) { - QAssert.Fail( "Double Barrier Option " + barrierType + " " + exercise + " " - + payoff.optionType() + " option with " - + payoff + " payoff:\n" - + " underlying value: " + s + "\n" - + " strike: " + payoff.strike() + "\n" - + " barrier 1: " + barrier1 + "\n" - + " barrier 2: " + barrier2 + "\n" - + " rebate : " + rebate + "\n" - + " dividend yield: " + q + "\n" - + " risk-free rate: " + r + "\n" - + " reference date: " + today + "\n" - + " maturity: " + exercise.lastDate() + "\n" - + " 25PutVol: " + +(vol25Put) + "\n" - + " atmVol: " + (atmVol) + "\n" - + " 25CallVol: " + (vol25Call) + "\n" - + " volatility: " + v + "\n\n" - + " expected " + greekName + ": " + expected + "\n" - + " calculated " + greekName + ": " + calculated + "\n" - + " error: " + error + "\n" - + " tolerance: " + tolerance ); + QAssert.Fail("Double Barrier Option " + barrierType + " " + exercise + " " + + payoff.optionType() + " option with " + + payoff + " payoff:\n" + + " underlying value: " + s + "\n" + + " strike: " + payoff.strike() + "\n" + + " barrier 1: " + barrier1 + "\n" + + " barrier 2: " + barrier2 + "\n" + + " rebate : " + rebate + "\n" + + " dividend yield: " + q + "\n" + + " risk-free rate: " + r + "\n" + + " reference date: " + today + "\n" + + " maturity: " + exercise.lastDate() + "\n" + + " 25PutVol: " + +(vol25Put) + "\n" + + " atmVol: " + (atmVol) + "\n" + + " 25CallVol: " + (vol25Call) + "\n" + + " volatility: " + v + "\n\n" + + " expected " + greekName + ": " + expected + "\n" + + " calculated " + greekName + ": " + calculated + "\n" + + " error: " + error + "\n" + + " tolerance: " + tolerance); } private class NewBarrierOptionData @@ -154,131 +154,131 @@ public DoubleBarrierFxOptionData(DoubleBarrier.Type barrierType, double barrier1 } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testEuropeanHaugValues() + public void testEuropeanHaugValues() { // Testing double barrier european options against Haug's values Exercise.Type european = Exercise.Type.European; - NewBarrierOptionData[] values = + NewBarrierOptionData[] values = { /* The data below are from - "The complete guide to option pricing formulas 2nd Ed",E.G. Haug, McGraw-Hill, p.156 and following. + "The complete guide to option pricing formulas 2nd Ed",E.G. Haug, McGraw-Hill, p.156 and following. Note: The book uses b instead of q (q=r-b) */ // BarrierType, barr.lo, barr.hi, type, exercise,strk, s, q, r, t, v, result, tol - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 4.3515, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 6.1644, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 7.0373, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 6.9853, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 7.9336, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 6.5088, 1.0e-4), - - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 4.3505, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 5.8500, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 5.7726, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 6.8082, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 6.3383, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 4.3841, 1.0e-4), - - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 4.3139, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 4.8293, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 3.7765, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 5.9697, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 4.0004, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 2.2563, 1.0e-4), - - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 3.7516, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 2.6387, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 1.4903, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 3.5805, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 1.5098, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 0.5635, 1.0e-4), - - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 1.2055, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 0.3098, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 0.0477, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 0.5537, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 0.0441, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 0.0011, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 4.3515, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 6.1644, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 7.0373, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 6.9853, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 7.9336, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 6.5088, 1.0e-4), + + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 4.3505, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 5.8500, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 5.7726, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 6.8082, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 6.3383, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 4.3841, 1.0e-4), + + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 4.3139, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 4.8293, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 3.7765, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 5.9697, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 4.0004, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 2.2563, 1.0e-4), + + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 3.7516, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 2.6387, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 1.4903, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 3.5805, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 1.5098, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 0.5635, 1.0e-4), + + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 1.2055, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 0.3098, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 0.0477, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 0.5537, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 0.0441, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 0.0011, 1.0e-4), // BarrierType, barr.lo, barr.hi, type, exercise,strk, s, q, r, t, v, result, tol - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 1.8825, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 3.7855, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 5.7191, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 2.1374, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 4.7033, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 7.1683, 1.0e-4), - - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 1.8825, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 3.7845, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 5.6060, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 2.1374, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 4.6236, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 6.1062, 1.0e-4), - - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 1.8825, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 3.7014, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 4.6472, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 2.1325, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 3.8944, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 3.5868, 1.0e-4), - - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 1.8600, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 2.6866, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 2.0719, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 1.8883, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 1.7851, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 0.8244, 1.0e-4), - - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 0.9473, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 0.3449, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 0.0578, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 0.4555, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 0.0491, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 0.0013, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 1.8825, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 3.7855, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 5.7191, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 2.1374, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 4.7033, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 7.1683, 1.0e-4), + + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 1.8825, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 3.7845, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 5.6060, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 2.1374, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 4.6236, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 6.1062, 1.0e-4), + + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 1.8825, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 3.7014, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 4.6472, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 2.1325, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 3.8944, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 3.5868, 1.0e-4), + + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 1.8600, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 2.6866, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 2.0719, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 1.8883, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 1.7851, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 0.8244, 1.0e-4), + + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 0.9473, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 0.3449, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 0.0578, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 0.4555, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 0.0491, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 0.0013, 1.0e-4), // BarrierType, barr.lo, barr.hi, type, strk, s, q, r, t, v, result, tol - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 0.0000, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 0.0900, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 1.1537, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 0.0292, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 1.6487, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 5.7321, 1.0e-4), - - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 0.0010, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 0.4045, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 2.4184, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 0.2062, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 3.2439, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 7.8569, 1.0e-4), - - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 0.0376, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 1.4252, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 4.4145, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 1.0447, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 5.5818, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 9.9846, 1.0e-4), - - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 0.5999, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 3.6158, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 6.7007, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 3.4340, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 8.0724, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 11.6774, 1.0e-4), - - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 3.1460, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 5.9447, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 8.1432, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 6.4608, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 9.5382, 1.0e-4), - new NewBarrierOptionData( DoubleBarrier.Type.KnockIn, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 12.2398, 1.0e-4), - + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 0.0000, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 0.0900, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 1.1537, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 0.0292, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 1.6487, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 5.7321, 1.0e-4), + + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 0.0010, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 0.4045, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 2.4184, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 0.2062, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 3.2439, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 7.8569, 1.0e-4), + + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 0.0376, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 1.4252, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 4.4145, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 1.0447, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 5.5818, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 9.9846, 1.0e-4), + + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 0.5999, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 3.6158, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 6.7007, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 3.4340, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 8.0724, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 11.6774, 1.0e-4), + + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 3.1460, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 5.9447, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 8.1432, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 6.4608, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 9.5382, 1.0e-4), + new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 12.2398, 1.0e-4), + }; DayCounter dc = new Actual360(); @@ -292,13 +292,13 @@ The book uses b instead of q (q=r-b) SimpleQuote vol = new SimpleQuote(0.0); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - for (int i=0; i(rTS), new Handle(volTS)); - DoubleBarrierOption opt = new DoubleBarrierOption(values[i].barrierType,values[i].barrierlo, - values[i].barrierhi,0, // no rebate - payoff, exercise); + DoubleBarrierOption opt = new DoubleBarrierOption(values[i].barrierType, values[i].barrierlo, + values[i].barrierhi, 0, // no rebate + payoff, exercise); // Ikeda/Kunitomo engine IPricingEngine engine = new AnalyticDoubleBarrierEngine(stochProcess); @@ -320,8 +320,8 @@ The book uses b instead of q (q=r-b) double calculated = opt.NPV(); double expected = values[i].result; - double error = Math.Abs(calculated-expected); - if (error>values[i].tol) + double error = Math.Abs(calculated - expected); + if (error > values[i].tol) { REPORT_FAILURE("Ikeda/Kunitomo value", values[i].barrierType, values[i].barrierlo, values[i].barrierhi, payoff, exercise, values[i].s, @@ -330,83 +330,59 @@ The book uses b instead of q (q=r-b) } // Wulin Suo/Yong Wang engine - engine = new WulinYongDoubleBarrierEngine( stochProcess ); - opt.setPricingEngine( engine ); + engine = new WulinYongDoubleBarrierEngine(stochProcess); + opt.setPricingEngine(engine); calculated = opt.NPV(); expected = values[i].result; - error = Math.Abs( calculated - expected ); - if ( error > values[i].tol ) + error = Math.Abs(calculated - expected); + if (error > values[i].tol) { - REPORT_FAILURE( "Wulin/Yong value", values[i].barrierType, values[i].barrierlo, + REPORT_FAILURE("Wulin/Yong value", values[i].barrierType, values[i].barrierlo, values[i].barrierhi, payoff, exercise, values[i].s, values[i].q, values[i].r, today, values[i].v, - expected, calculated, error, values[i].tol ); + expected, calculated, error, values[i].tol); } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testVannaVolgaDoubleBarrierValues() + public void testVannaVolgaDoubleBarrierValues() { // Testing double-barrier FX options against Vanna/Volga values SavedSettings backup = new SavedSettings(); - DoubleBarrierFxOptionData[] values = + DoubleBarrierFxOptionData[] values = { // BarrierType, barr.1, barr.2, rebate, type, strike, s, q, r, t, vol25Put, volAtm,vol25Call, vol, result, tol - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Call, 1.13321, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.11638, 0.14413, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Call, 1.22687, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.10088, 0.07456, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Call, 1.31179, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08925, 0.02710, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Call, 1.38843, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08463, 0.00569, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Call, 1.46047, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08412, 0.00013, 1.0e-4), - - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Put, 1.13321, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.11638, 0.00017, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Put, 1.22687, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.10088, 0.00353, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Put, 1.31179, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08925, 0.02221, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Put, 1.38843, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08463, 0.06049, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Put, 1.46047, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08412, 0.11103, 1.0e-4), - - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.1, 1.5, 0.0, Option.Type.Call, 1.13321, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.11638, 0.14486, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.1, 1.5, 0.0, Option.Type.Call, 1.22687, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.10088, 0.07534, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.1, 1.5, 0.0, Option.Type.Call, 1.31179, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08925, 0.02707, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.1, 1.5, 0.0, Option.Type.Call, 1.38843, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08463, 0.00536, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.1, 1.5, 0.0, Option.Type.Call, 1.46047, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08412, 4.14862e-005, 1.0e-4), - - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.1, 1.5, 0.0, Option.Type.Put, 1.13321, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.11638, 0.00095, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.1, 1.5, 0.0, Option.Type.Put, 1.22687, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.10088, 0.00437, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.1, 1.5, 0.0, Option.Type.Put, 1.31179, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08925, 0.02224, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.1, 1.5, 0.0, Option.Type.Put, 1.38843, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08463, 0.06021, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.1, 1.5, 0.0, Option.Type.Put, 1.46047, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08412, 0.11100, 1.0e-4), - - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Call, 1.06145, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.12511, 0.19981, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Call, 1.19545, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.10890, 0.10389, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Call, 1.32238, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09444, 0.03555, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Call, 1.44298, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09197, 0.00634, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Call, 1.56345, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09261, 0.00000, 1.0e-4), - - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Put, 1.06145, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.12511, 0.00000, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Put, 1.19545, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.10890, 0.00436, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Put, 1.32238, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09444, 0.03173, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Put, 1.44298, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09197, 0.09346, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Put, 1.56345, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09261, 0.17704, 1.0e-4), - - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.0, 1.6, 0.0, Option.Type.Call, 1.06145, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.12511, 0.20202, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.0, 1.6, 0.0, Option.Type.Call, 1.19545, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.10890, 0.10521, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.0, 1.6, 0.0, Option.Type.Call, 1.32238, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09444, 0.03589, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.0, 1.6, 0.0, Option.Type.Call, 1.44298, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09197, 0.00601, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.0, 1.6, 0.0, Option.Type.Call, 1.56345, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09261, 0.00000, 1.0e-4), - - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.0, 1.6, 0.0, Option.Type.Put, 1.06145, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.12511, 0.00153, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.0, 1.6, 0.0, Option.Type.Put, 1.19545, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.10890, 0.00578, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.0, 1.6, 0.0, Option.Type.Put, 1.32238, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09444, 0.03218, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.0, 1.6, 0.0, Option.Type.Put, 1.44298, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09197, 0.09325, 1.0e-4), - new DoubleBarrierFxOptionData( DoubleBarrier.Type.KnockIn, 1.0, 1.6, 0.0, Option.Type.Put, 1.56345, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09261, 0.17804, 1.0e-4) + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Call, 1.13321, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.11638, 0.14413, 1.0e-4), + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Call, 1.22687, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.10088, 0.07456, 1.0e-4), + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Call, 1.31179, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08925, 0.02710, 1.0e-4), + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Call, 1.38843, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08463, 0.00569, 1.0e-4), + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Call, 1.46047, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08412, 0.00013, 1.0e-4), + + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Put, 1.13321, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.11638, 0.00017, 1.0e-4), + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Put, 1.22687, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.10088, 0.00353, 1.0e-4), + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Put, 1.31179, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08925, 0.02221, 1.0e-4), + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Put, 1.38843, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08463, 0.06049, 1.0e-4), + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Put, 1.46047, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08412, 0.11103, 1.0e-4), + + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Call, 1.06145, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.12511, 0.19981, 1.0e-4), + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Call, 1.19545, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.10890, 0.10389, 1.0e-4), + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Call, 1.32238, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09444, 0.03555, 1.0e-4), + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Call, 1.44298, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09197, 0.00634, 1.0e-4), + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Call, 1.56345, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09261, 0.00000, 1.0e-4), + + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Put, 1.06145, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.12511, 0.00000, 1.0e-4), + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Put, 1.19545, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.10890, 0.00436, 1.0e-4), + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Put, 1.32238, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09444, 0.03173, 1.0e-4), + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Put, 1.44298, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09197, 0.09346, 1.0e-4), + new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Put, 1.56345, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09261, 0.17704, 1.0e-4), }; @@ -423,83 +399,91 @@ public void testVannaVolgaDoubleBarrierValues() SimpleQuote volAtm = new SimpleQuote(0.0); SimpleQuote vol25Call = new SimpleQuote(0.0); - for (int i=0; i volAtmQuote = new Handle( - new DeltaVolQuote( new Handle(volAtm),DeltaVolQuote.DeltaType.Fwd,values[i].t, - DeltaVolQuote.AtmType.AtmDeltaNeutral)); + Handle volAtmQuote = new Handle( + new DeltaVolQuote(new Handle(volAtm), DeltaVolQuote.DeltaType.Fwd, values[i].t, + DeltaVolQuote.AtmType.AtmDeltaNeutral)); - //always delta neutral atm - Handle vol25PutQuote = new Handle(new DeltaVolQuote(-0.25, - new Handle(vol25Put),values[i].t,DeltaVolQuote.DeltaType.Fwd)); + //always delta neutral atm + Handle vol25PutQuote = new Handle(new DeltaVolQuote(-0.25, + new Handle(vol25Put), values[i].t, DeltaVolQuote.DeltaType.Fwd)); - Handle vol25CallQuote = new Handle(new DeltaVolQuote(0.25, - new Handle(vol25Call),values[i].t,DeltaVolQuote.DeltaType.Fwd)); + Handle vol25CallQuote = new Handle(new DeltaVolQuote(0.25, + new Handle(vol25Call), values[i].t, DeltaVolQuote.DeltaType.Fwd)); - DoubleBarrierOption doubleBarrierOption = new DoubleBarrierOption(values[i].barrierType, - values[i].barrier1,values[i].barrier2,values[i].rebate,payoff,exercise); + DoubleBarrierOption doubleBarrierOption = new DoubleBarrierOption(barrierType, + values[i].barrier1, values[i].barrier2, values[i].rebate, payoff, exercise); - double bsVanillaPrice = Utils.blackFormula(values[i].type, values[i].strike, - spot.value()*qTS.discount(values[i].t)/rTS.discount(values[i].t), - values[i].v * Math.Sqrt(values[i].t), rTS.discount(values[i].t)); + double bsVanillaPrice = Utils.blackFormula(values[i].type, values[i].strike, + spot.value() * qTS.discount(values[i].t) / rTS.discount(values[i].t), + values[i].v * Math.Sqrt(values[i].t), rTS.discount(values[i].t)); - IPricingEngine vannaVolgaEngine; + IPricingEngine vannaVolgaEngine; - vannaVolgaEngine = new VannaVolgaDoubleBarrierEngine( volAtmQuote, vol25PutQuote, vol25CallQuote, - new Handle( spot ), - new Handle( rTS ), - new Handle( qTS ), - ( process, series ) => new WulinYongDoubleBarrierEngine( process, series ), + vannaVolgaEngine = new VannaVolgaDoubleBarrierEngine(volAtmQuote, vol25PutQuote, vol25CallQuote, + new Handle(spot), + new Handle(rTS), + new Handle(qTS), + (process, series) => new WulinYongDoubleBarrierEngine(process, series), true, - bsVanillaPrice ); - doubleBarrierOption.setPricingEngine( vannaVolgaEngine ); - - double calculated = doubleBarrierOption.NPV(); - double expected = values[i].result; - double error = Math.Abs( calculated - expected ); - if ( error > values[i].tol ) - { - REPORT_FAILURE_VANNAVOLGA( "value", values[i].barrierType, - values[i].barrier1, values[i].barrier2, - values[i].rebate, payoff, exercise, values[i].s, - values[i].q, values[i].r, today, values[i].vol25Put, - values[i].volAtm, values[i].vol25Call, values[i].v, - expected, calculated, error, values[i].tol ); - } - - vannaVolgaEngine = new VannaVolgaDoubleBarrierEngine(volAtmQuote,vol25PutQuote,vol25CallQuote, - new Handle (spot), - new Handle (rTS), - new Handle (qTS), - (process,series) => new AnalyticDoubleBarrierEngine(process,series), - true, - bsVanillaPrice); - doubleBarrierOption.setPricingEngine(vannaVolgaEngine); - - calculated = doubleBarrierOption.NPV(); - expected = values[i].result; - error = Math.Abs( calculated - expected ); - double maxtol = 5.0e-3; // different engines have somewhat different results - if (error>maxtol) - { - REPORT_FAILURE_VANNAVOLGA( "value", values[i].barrierType, - values[i].barrier1, values[i].barrier2, - values[i].rebate, payoff, exercise, values[i].s, - values[i].q, values[i].r, today, values[i].vol25Put, - values[i].volAtm, values[i].vol25Call, values[i].v, - expected, calculated, error, values[i].tol); + bsVanillaPrice); + doubleBarrierOption.setPricingEngine(vannaVolgaEngine); + + double expected = 0; + if (barrierType == DoubleBarrier.Type.KnockOut) + expected = values[i].result; + else if (barrierType == DoubleBarrier.Type.KnockIn) + expected = (bsVanillaPrice - values[i].result); + + double calculated = doubleBarrierOption.NPV(); + double error = Math.Abs(calculated - expected); + if (error > values[i].tol) + { + REPORT_FAILURE_VANNAVOLGA("value", values[i].barrierType, + values[i].barrier1, values[i].barrier2, + values[i].rebate, payoff, exercise, values[i].s, + values[i].q, values[i].r, today, values[i].vol25Put, + values[i].volAtm, values[i].vol25Call, values[i].v, + expected, calculated, error, values[i].tol); + } + + vannaVolgaEngine = new VannaVolgaDoubleBarrierEngine(volAtmQuote, vol25PutQuote, vol25CallQuote, + new Handle(spot), + new Handle(rTS), + new Handle(qTS), + (process, series) => new AnalyticDoubleBarrierEngine(process, series), + true, + bsVanillaPrice); + doubleBarrierOption.setPricingEngine(vannaVolgaEngine); + + calculated = doubleBarrierOption.NPV(); + error = Math.Abs(calculated - expected); + double maxtol = 5.0e-3; // different engines have somewhat different results + if (error > maxtol) + { + REPORT_FAILURE_VANNAVOLGA("value", values[i].barrierType, + values[i].barrier1, values[i].barrier2, + values[i].rebate, payoff, exercise, values[i].s, + values[i].q, values[i].r, today, values[i].vol25Put, + values[i].volAtm, values[i].vol25Call, values[i].v, + expected, calculated, error, values[i].tol); + } } } } diff --git a/tests/QLNet.Tests/T_DoubleBinaryOption.cs b/tests/QLNet.Tests/T_DoubleBinaryOption.cs index e3fbad8b8..b433dfc31 100644 --- a/tests/QLNet.Tests/T_DoubleBinaryOption.cs +++ b/tests/QLNet.Tests/T_DoubleBinaryOption.cs @@ -1,16 +1,16 @@ // Copyright (C) 2015 Thema Consulting SA // Copyright (C) 2017 Jean-Camille Tournier (jean-camille.tournier@avivainvestors.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,51 +19,51 @@ #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; namespace TestSuite { - #if NET40 || NET45 - [TestClass()] - #endif +#if NET40 || NET45 + [TestClass()] +#endif public class T_DoubleBinaryOption { - private void REPORT_FAILURE( string greekName, - StrikedTypePayoff payoff, - Exercise exercise, - DoubleBarrier.Type barrierType, - double barrier_lo, - double barrier_hi, - double s, - double q, - double r, - Date today, - double v, - double expected, - double calculated, - double error, - double tolerance ) + private void REPORT_FAILURE(string greekName, + StrikedTypePayoff payoff, + Exercise exercise, + DoubleBarrier.Type barrierType, + double barrier_lo, + double barrier_hi, + double s, + double q, + double r, + Date today, + double v, + double expected, + double calculated, + double error, + double tolerance) { - QAssert.Fail( payoff.optionType() + " option with " - + barrierType + " barrier type:\n" - + " barrier_lo: " + barrier_lo + "\n" - + " barrier_hi: " + barrier_hi + "\n" - + payoff + " payoff:\n" - + exercise + " " - + payoff.optionType() - + " spot value: " + s + "\n" - + " strike: " + payoff.strike() + "\n" - + " dividend yield: " + q + "\n" - + " risk-free rate: " + r + "\n" - + " reference date: " + today + "\n" - + " maturity: " + exercise.lastDate() + "\n" - + " volatility: " + v + "\n\n" - + " expected " + greekName + ": " + expected + "\n" - + " calculated " + greekName + ": " + calculated + "\n" - + " error: " + error + "\n" - + " tolerance: " + tolerance ); + QAssert.Fail(payoff.optionType() + " option with " + + barrierType + " barrier type:\n" + + " barrier_lo: " + barrier_lo + "\n" + + " barrier_hi: " + barrier_hi + "\n" + + payoff + " payoff:\n" + + exercise + " " + + payoff.optionType() + + " spot value: " + s + "\n" + + " strike: " + payoff.strike() + "\n" + + " dividend yield: " + q + "\n" + + " risk-free rate: " + r + "\n" + + " reference date: " + today + "\n" + + " maturity: " + exercise.lastDate() + "\n" + + " volatility: " + v + "\n\n" + + " expected " + greekName + ": " + expected + "\n" + + " calculated " + greekName + ": " + calculated + "\n" + + " error: " + error + "\n" + + " tolerance: " + tolerance); } private struct DoubleBinaryOptionData @@ -78,13 +78,13 @@ private struct DoubleBinaryOptionData public double t; // time to maturity public double v; // volatility public double result; // expected result - public double tol; // tolerance - + public double tol; // tolerance + public DoubleBinaryOptionData(DoubleBarrier.Type barrierType, double barrier_lo, double barrier_hi, double cash, double s, double q, double r, double t, double v, double result, double tol) : this() { this.barrierType = barrierType; - this.barrier_lo = barrier_lo; + this.barrier_lo = barrier_lo; this.barrier_hi = barrier_hi; this.cash = cash; this.s = s; @@ -97,111 +97,112 @@ public DoubleBinaryOptionData(DoubleBarrier.Type barrierType, double barrier_lo, } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testHaugValues() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testHaugValues() { - // Testing cash-or-nothing double barrier options against Haug's values - - DoubleBinaryOptionData[] values = { + // Testing cash-or-nothing double barrier options against Haug's values + + DoubleBinaryOptionData[] values = + { /* The data below are from "Option pricing formulas 2nd Ed.", E.G. Haug, McGraw-Hill 2007 pag. 181 Note: book uses cost of carry b, instead of dividend rate q */ // barrierType, bar_lo, bar_hi, cash, spot, q, r, t, vol, value, tol - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockOut, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 9.8716, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockOut, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 8.9307, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockOut, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 6.3272, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockOut, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 1.9094, 1e-4 ), - - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockOut, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 9.7961, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockOut, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 7.2300, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockOut, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 3.7100, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockOut, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 0.4271, 1e-4 ), - - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockOut, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 8.9054, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockOut, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 3.6752, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockOut, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 0.7960, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockOut, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 0.0059, 1e-4 ), - - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockOut, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 3.6323, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockOut, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 0.0911, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockOut, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 0.0002, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockOut, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 0.0000, 1e-4 ), - - new DoubleBinaryOptionData( DoubleBarrier.Type.KIKO, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.0000, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KIKO, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 0.2402, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KIKO, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 1.4076, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KIKO, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 3.8160, 1e-4 ), - - new DoubleBinaryOptionData( DoubleBarrier.Type.KIKO, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.0075, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KIKO, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 0.9910, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KIKO, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 2.8098, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KIKO, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 4.6612, 1e-4 ), - - new DoubleBinaryOptionData( DoubleBarrier.Type.KIKO, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.2656, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KIKO, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 2.7954, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KIKO, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 4.4024, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KIKO, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 4.9266, 1e-4 ), - - new DoubleBinaryOptionData( DoubleBarrier.Type.KIKO, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 2.6285, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KIKO, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 4.7523, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KIKO, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 4.9096, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KIKO, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 4.9675, 1e-4 ), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 9.8716, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 8.9307, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 6.3272, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 1.9094, 1e-4), + + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 9.7961, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 7.2300, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 3.7100, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 0.4271, 1e-4), + + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 8.9054, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 3.6752, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 0.7960, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 0.0059, 1e-4), + + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 3.6323, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 0.0911, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 0.0002, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 0.0000, 1e-4), + + new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.0000, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 0.2402, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 1.4076, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 3.8160, 1e-4), + + new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.0075, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 0.9910, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 2.8098, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 4.6612, 1e-4), + + new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.2656, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 2.7954, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 4.4024, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 4.9266, 1e-4), + + new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 2.6285, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 4.7523, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 4.9096, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 4.9675, 1e-4), // following values calculated with haug's VBA code - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockIn, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.0042, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockIn, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 0.9450, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockIn, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 3.5486, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockIn, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 7.9663, 1e-4 ), - - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockIn, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.0797, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockIn, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 2.6458, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockIn, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 6.1658, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockIn, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 9.4486, 1e-4 ), - - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockIn, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.9704, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockIn, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 6.2006, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockIn, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 9.0798, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockIn, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 9.8699, 1e-4 ), - - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockIn, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 6.2434, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockIn, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 9.7847, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockIn, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 9.8756, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockIn, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 9.8758, 1e-4 ), - - new DoubleBinaryOptionData( DoubleBarrier.Type.KOKI, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.0041, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KOKI, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 0.7080, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KOKI, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 2.1581, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KOKI, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 4.2061, 1e-4 ), - - new DoubleBinaryOptionData( DoubleBarrier.Type.KOKI, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.0723, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KOKI, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 1.6663, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KOKI, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 3.3930, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KOKI, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 4.8679, 1e-4 ), - - new DoubleBinaryOptionData( DoubleBarrier.Type.KOKI, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.7080, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KOKI, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 3.4424, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KOKI, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 4.7496, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KOKI, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 5.0475, 1e-4 ), - - new DoubleBinaryOptionData( DoubleBarrier.Type.KOKI, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 3.6524, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KOKI, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 5.1256, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KOKI, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 5.0763, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KOKI, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 5.0275, 1e-4 ), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.0042, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 0.9450, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 3.5486, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 7.9663, 1e-4), + + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.0797, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 2.6458, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 6.1658, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 9.4486, 1e-4), + + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.9704, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 6.2006, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 9.0798, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 9.8699, 1e-4), + + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 6.2434, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 9.7847, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 9.8756, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 9.8758, 1e-4), + + new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.0041, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 0.7080, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 2.1581, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 4.2061, 1e-4), + + new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.0723, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 1.6663, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 3.3930, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 4.8679, 1e-4), + + new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.7080, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 3.4424, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 4.7496, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 5.0475, 1e-4), + + new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 3.6524, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 5.1256, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 5.0763, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 5.0275, 1e-4), // degenerate cases - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockOut, 95.00, 105.00, 10.00, 80.00, 0.02, 0.05, 0.25, 0.10, 0.0000, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockOut, 95.00, 105.00, 10.00, 110.00, 0.02, 0.05, 0.25, 0.10, 0.0000, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockIn, 95.00, 105.00, 10.00, 80.00, 0.02, 0.05, 0.25, 0.10, 10.0000, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KnockIn, 95.00, 105.00, 10.00, 110.00, 0.02, 0.05, 0.25, 0.10, 10.0000, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KIKO, 95.00, 105.00, 10.00, 80.00, 0.02, 0.05, 0.25, 0.10, 10.0000, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KIKO, 95.00, 105.00, 10.00, 110.00, 0.02, 0.05, 0.25, 0.10, 0.0000, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KOKI, 95.00, 105.00, 10.00, 80.00, 0.02, 0.05, 0.25, 0.10, 0.0000, 1e-4 ), - new DoubleBinaryOptionData( DoubleBarrier.Type.KOKI, 95.00, 105.00, 10.00, 110.00, 0.02, 0.05, 0.25, 0.10, 10.0000, 1e-4 ), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 95.00, 105.00, 10.00, 80.00, 0.02, 0.05, 0.25, 0.10, 0.0000, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 95.00, 105.00, 10.00, 110.00, 0.02, 0.05, 0.25, 0.10, 0.0000, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 95.00, 105.00, 10.00, 80.00, 0.02, 0.05, 0.25, 0.10, 10.0000, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 95.00, 105.00, 10.00, 110.00, 0.02, 0.05, 0.25, 0.10, 10.0000, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 95.00, 105.00, 10.00, 80.00, 0.02, 0.05, 0.25, 0.10, 10.0000, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 95.00, 105.00, 10.00, 110.00, 0.02, 0.05, 0.25, 0.10, 0.0000, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 95.00, 105.00, 10.00, 80.00, 0.02, 0.05, 0.25, 0.10, 0.0000, 1e-4), + new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 95.00, 105.00, 10.00, 110.00, 0.02, 0.05, 0.25, 0.10, 10.0000, 1e-4), }; DayCounter dc = new Actual360(); @@ -215,17 +216,17 @@ public void testHaugValues() SimpleQuote vol = new SimpleQuote(0.25); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - for (int i=0; i(spot), new Handle(qTS), new Handle(rTS), - new Handle(volTS)); - - IPricingEngine engine = new AnalyticDoubleBarrierBinaryEngine(stochProcess); - - DoubleBarrierOption opt = new DoubleBarrierOption(values[i].barrierType, - values[i].barrier_lo, - values[i].barrier_hi, - 0, - payoff, + new Handle(volTS)); + + IPricingEngine engine = new AnalyticDoubleBarrierBinaryEngine(stochProcess); + + DoubleBarrierOption opt = new DoubleBarrierOption(values[i].barrierType, + values[i].barrier_lo, + values[i].barrier_hi, + 0, + payoff, exercise); opt.setPricingEngine(engine); double calculated = opt.NPV(); double expected = values[i].result; - double error = Math.Abs(calculated-values[i].result); - if (error > values[i].tol) { - REPORT_FAILURE("value", payoff, exercise, values[i].barrierType, + double error = Math.Abs(calculated - values[i].result); + if (error > values[i].tol) + { + REPORT_FAILURE("value", payoff, exercise, values[i].barrierType, values[i].barrier_lo, values[i].barrier_hi, values[i].s, values[i].q, values[i].r, today, values[i].v, values[i].result, calculated, error, values[i].tol); } int steps = 500; - // checking with binomial engine - engine = new BinomialDoubleBarrierEngine( - (d, end, step, strike) => new CoxRossRubinstein(d, end, step, strike), - (args, process, grid) => new DiscretizedDoubleBarrierOption(args, process, grid), - stochProcess, steps); + // checking with binomial engine + engine = new BinomialDoubleBarrierEngine( + (d, end, step, strike) => new CoxRossRubinstein(d, end, step, strike), + (args, process, grid) => new DiscretizedDoubleBarrierOption(args, process, grid), + stochProcess, steps); opt.setPricingEngine(engine); calculated = opt.NPV(); expected = values[i].result; - error = Math.Abs(calculated-expected); + error = Math.Abs(calculated - expected); double tol = 0.22; - if (error>tol) { - REPORT_FAILURE("Binomial value", payoff, exercise, values[i].barrierType, - values[i].barrier_lo, values[i].barrier_hi, values[i].s, - values[i].q, values[i].r, today, values[i].v, - values[i].result, calculated, error, tol); + if (error > tol) + { + REPORT_FAILURE("Binomial value", payoff, exercise, values[i].barrierType, + values[i].barrier_lo, values[i].barrier_hi, values[i].s, + values[i].q, values[i].r, today, values[i].v, + values[i].result, calculated, error, tol); } } } diff --git a/tests/QLNet.Tests/T_EuropeanOption.cs b/tests/QLNet.Tests/T_EuropeanOption.cs index 9573f55f1..93526fd20 100644 --- a/tests/QLNet.Tests/T_EuropeanOption.cs +++ b/tests/QLNet.Tests/T_EuropeanOption.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,7 +21,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -34,22 +34,22 @@ public class T_EuropeanOption : IDisposable { #region Initialize&Cleanup private SavedSettings backup; - #if NET40 || NET45 +#if NET40 || NET45 [TestInitialize] public void testInitialize() { - #else +#else public T_EuropeanOption() { - #endif +#endif backup = new SavedSettings(); } - #if NET40 || NET45 +#if NET40 || NET45 [TestCleanup] - #endif +#endif public void testCleanup() { - Dispose(); + Dispose(); } public void Dispose() { @@ -64,13 +64,13 @@ enum EngineType FiniteDifferences, Integral, PseudoMonteCarlo, QuasiMonteCarlo - }; + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testJRBinomialEngines() { @@ -86,9 +86,9 @@ public void testJRBinomialEngines() testEngineConsistency(engine, steps, samples, relativeTol, true); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testCRRBinomialEngines() { @@ -104,9 +104,9 @@ public void testCRRBinomialEngines() testEngineConsistency(engine, steps, samples, relativeTol, true); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testEQPBinomialEngines() { @@ -122,9 +122,9 @@ public void testEQPBinomialEngines() testEngineConsistency(engine, steps, samples, relativeTol, true); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testTGEOBinomialEngines() { @@ -140,9 +140,9 @@ public void testTGEOBinomialEngines() testEngineConsistency(engine, steps, samples, relativeTol, true); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testTIANBinomialEngines() { @@ -158,9 +158,9 @@ public void testTIANBinomialEngines() testEngineConsistency(engine, steps, samples, relativeTol, true); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testLRBinomialEngines() { @@ -176,9 +176,9 @@ public void testLRBinomialEngines() testEngineConsistency(engine, steps, samples, relativeTol, true); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testJOSHIBinomialEngines() { @@ -196,9 +196,9 @@ public void testJOSHIBinomialEngines() #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testFdEngines() { @@ -227,7 +227,7 @@ GeneralizedBlackScholesProcess makeProcess(Quote u, YieldTermStructure q, YieldT VanillaOption makeOption(StrikedTypePayoff payoff, Exercise exercise, Quote u, YieldTermStructure q, - YieldTermStructure r, BlackVolTermStructure vol, EngineType engineType, int binomialSteps, int samples) + YieldTermStructure r, BlackVolTermStructure vol, EngineType engineType, int binomialSteps, int samples) { GeneralizedBlackScholesProcess stochProcess = makeProcess(u, q, r, vol); @@ -327,10 +327,10 @@ void testEngineConsistency(EngineType engine, int binomialSteps, int samples, Di StrikedTypePayoff payoff = new PlainVanillaPayoff(types[i], strikes[j]); // reference option VanillaOption refOption = makeOption(payoff, exercise, spot, qTS, rTS, volTS, - EngineType.Analytic, 0, 0); + EngineType.Analytic, 0, 0); // option to check VanillaOption option = makeOption(payoff, exercise, spot, qTS, rTS, volTS, - engine, binomialSteps, samples); + engine, binomialSteps, samples); for (int l = 0; l < underlyings.Length; l++) { @@ -342,7 +342,7 @@ void testEngineConsistency(EngineType engine, int binomialSteps, int samples, Di { double u = underlyings[l]; double q = qRates[m], - r = rRates[n]; + r = rRates[n]; double v = vols[p]; spot.setValue(u); qRate.setValue(q); @@ -368,8 +368,8 @@ void testEngineConsistency(EngineType engine, int binomialSteps, int samples, Di foreach (string greek in calculated.Keys) { double expct = expected[greek], - calcl = calculated[greek], - tol = tolerance[greek]; + calcl = calculated[greek], + tol = tolerance[greek]; double error = Utilities.relativeError(expct, calcl, u); if (error > tol) { @@ -390,22 +390,22 @@ void testEngineConsistency(EngineType engine, int binomialSteps, int samples, Di void REPORT_FAILURE(string greekName, StrikedTypePayoff payoff, Exercise exercise, double s, double q, double r, - Date today, double v, double expected, double calculated, double error, double tolerance) + Date today, double v, double expected, double calculated, double error, double tolerance) { QAssert.Fail(exercise + " " - + payoff.optionType() + " option with " - + payoff + " payoff:\n" - + " spot value: " + s + "\n" - + " strike: " + payoff.strike() + "\n" - + " dividend yield: " + q + "\n" - + " risk-free rate: " + r + "\n" - + " reference date: " + today + "\n" - + " maturity: " + exercise.lastDate() + "\n" - + " volatility: " + v + "\n\n" - + " expected " + greekName + ": " + expected + "\n" - + " calculated " + greekName + ": " + calculated + "\n" - + " error: " + error + "\n" - + " tolerance: " + tolerance); + + payoff.optionType() + " option with " + + payoff + " payoff:\n" + + " spot value: " + s + "\n" + + " strike: " + payoff.strike() + "\n" + + " dividend yield: " + q + "\n" + + " risk-free rate: " + r + "\n" + + " reference date: " + today + "\n" + + " maturity: " + exercise.lastDate() + "\n" + + " volatility: " + v + "\n\n" + + " expected " + greekName + ": " + expected + "\n" + + " calculated " + greekName + ": " + calculated + "\n" + + " error: " + error + "\n" + + " tolerance: " + tolerance); } } } diff --git a/tests/QLNet.Tests/T_ExchangeRate.cs b/tests/QLNet.Tests/T_ExchangeRate.cs index 58b352b10..375554e3f 100644 --- a/tests/QLNet.Tests/T_ExchangeRate.cs +++ b/tests/QLNet.Tests/T_ExchangeRate.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Andrea Maggiulli - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,7 +19,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -31,11 +31,11 @@ namespace TestSuite public class T_ExchangeRate { #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] -#endif - public void testDirect() + [Fact] +#endif + public void testDirect() { Currency EUR = new EURCurrency(), USD = new USDCurrency(); @@ -48,31 +48,31 @@ public void testDirect() Money.conversionType = Money.ConversionType.NoConversion; Money calculated = eur_usd.exchange(m1); - Money expected = new Money(m1.value*eur_usd.rate, USD); + Money expected = new Money(m1.value * eur_usd.rate, USD); if (!Utils.close(calculated, expected)) { - QAssert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated); + QAssert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated); } calculated = eur_usd.exchange(m2); - expected = new Money(m2.value/eur_usd.rate, EUR); + expected = new Money(m2.value / eur_usd.rate, EUR); if (!Utils.close(calculated, expected)) { - QAssert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated); + QAssert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated); } } - + /// /// Testing derived exchange rates /// #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testDerived() + public void testDerived() { Currency EUR = new EURCurrency(), USD = new USDCurrency(), GBP = new GBPCurrency(); @@ -88,17 +88,17 @@ public void testDerived() Money.conversionType = Money.ConversionType.NoConversion; Money calculated = derived.exchange(m1); - Money expected = new Money(m1.value*eur_usd.rate/eur_gbp.rate, USD); + Money expected = new Money(m1.value * eur_usd.rate / eur_gbp.rate, USD); - if (!Utils.close(calculated, expected)) + if (!Utils.close(calculated, expected)) { QAssert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated); } calculated = derived.exchange(m2); - expected = new Money(m2.value*eur_gbp.rate/eur_usd.rate, GBP); + expected = new Money(m2.value * eur_gbp.rate / eur_usd.rate, GBP); - if (!Utils.close(calculated, expected)) + if (!Utils.close(calculated, expected)) { QAssert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated); } @@ -108,11 +108,11 @@ public void testDerived() /// Testing lookup of direct exchange rates ///
    #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testDirectLookup() + public void testDirectLookup() { ExchangeRateManager rateManager = ExchangeRateManager.Instance; rateManager.clear(); @@ -120,49 +120,49 @@ public void testDirectLookup() Currency EUR = new EURCurrency(), USD = new USDCurrency(); ExchangeRate eur_usd1 = new ExchangeRate(EUR, USD, 1.1983); - ExchangeRate eur_usd2 = new ExchangeRate(USD, EUR, 1.0/1.2042); - rateManager.add(eur_usd1, new Date(4,Month.August,2004)); - rateManager.add(eur_usd2, new Date(5,Month.August,2004)); + ExchangeRate eur_usd2 = new ExchangeRate(USD, EUR, 1.0 / 1.2042); + rateManager.add(eur_usd1, new Date(4, Month.August, 2004)); + rateManager.add(eur_usd2, new Date(5, Month.August, 2004)); Money m1 = 50000.0 * EUR; Money m2 = 100000.0 * USD; Money.conversionType = Money.ConversionType.NoConversion; - ExchangeRate eur_usd = rateManager.lookup(EUR, USD,new Date(4,Month.August,2004),ExchangeRate.Type.Direct); + ExchangeRate eur_usd = rateManager.lookup(EUR, USD, new Date(4, Month.August, 2004), ExchangeRate.Type.Direct); Money calculated = eur_usd.exchange(m1); - Money expected = new Money(m1.value*eur_usd1.rate, USD); + Money expected = new Money(m1.value * eur_usd1.rate, USD); - if (!Utils.close(calculated, expected)) + if (!Utils.close(calculated, expected)) { QAssert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated); } - eur_usd = rateManager.lookup(EUR, USD,new Date(5,Month.August,2004),ExchangeRate.Type.Direct); + eur_usd = rateManager.lookup(EUR, USD, new Date(5, Month.August, 2004), ExchangeRate.Type.Direct); calculated = eur_usd.exchange(m1); - expected = new Money(m1.value/eur_usd2.rate, USD); + expected = new Money(m1.value / eur_usd2.rate, USD); - if (!Utils.close(calculated, expected)) + if (!Utils.close(calculated, expected)) { QAssert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated); } - ExchangeRate usd_eur = rateManager.lookup(USD, EUR,new Date(4,Month.August,2004),ExchangeRate.Type.Direct); + ExchangeRate usd_eur = rateManager.lookup(USD, EUR, new Date(4, Month.August, 2004), ExchangeRate.Type.Direct); calculated = usd_eur.exchange(m2); - expected = new Money(m2.value/eur_usd1.rate, EUR); + expected = new Money(m2.value / eur_usd1.rate, EUR); - if (!Utils.close(calculated, expected)) + if (!Utils.close(calculated, expected)) { QAssert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated); } - usd_eur = rateManager.lookup(USD, EUR,new Date(5,Month.August,2004),ExchangeRate.Type.Direct); + usd_eur = rateManager.lookup(USD, EUR, new Date(5, Month.August, 2004), ExchangeRate.Type.Direct); calculated = usd_eur.exchange(m2); - expected = new Money(m2.value*eur_usd2.rate, EUR); + expected = new Money(m2.value * eur_usd2.rate, EUR); - if (!Utils.close(calculated, expected)) + if (!Utils.close(calculated, expected)) { QAssert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated); } @@ -172,11 +172,11 @@ public void testDirectLookup() /// Testing lookup of triangulated exchange rates ///
    #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testTriangulatedLookup() + public void testTriangulatedLookup() { ExchangeRateManager rateManager = ExchangeRateManager.Instance; @@ -186,26 +186,26 @@ public void testTriangulatedLookup() ExchangeRate eur_usd1 = new ExchangeRate(EUR, USD, 1.1983); ExchangeRate eur_usd2 = new ExchangeRate(EUR, USD, 1.2042); - rateManager.add(eur_usd1, new Date(4,Month.August,2004)); - rateManager.add(eur_usd2, new Date(5,Month.August,2004)); + rateManager.add(eur_usd1, new Date(4, Month.August, 2004)); + rateManager.add(eur_usd2, new Date(5, Month.August, 2004)); Money m1 = 50000000.0 * ITL; Money m2 = 100000.0 * USD; Money.conversionType = Money.ConversionType.NoConversion; - ExchangeRate itl_usd = rateManager.lookup(ITL, USD,new Date(4,Month.August,2004)); + ExchangeRate itl_usd = rateManager.lookup(ITL, USD, new Date(4, Month.August, 2004)); Money calculated = itl_usd.exchange(m1); - Money expected = new Money(m1.value*eur_usd1.rate/1936.27, USD); + Money expected = new Money(m1.value * eur_usd1.rate / 1936.27, USD); if (!Utils.close(calculated, expected)) { QAssert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated); } - itl_usd = rateManager.lookup(ITL, USD,new Date(5,Month.August,2004)); + itl_usd = rateManager.lookup(ITL, USD, new Date(5, Month.August, 2004)); calculated = itl_usd.exchange(m1); - expected = new Money(m1.value*eur_usd2.rate/1936.27, USD); + expected = new Money(m1.value * eur_usd2.rate / 1936.27, USD); if (!Utils.close(calculated, expected)) { @@ -215,7 +215,7 @@ public void testTriangulatedLookup() ExchangeRate usd_itl = rateManager.lookup(USD, ITL, new Date(4, Month.August, 2004)); calculated = usd_itl.exchange(m2); - expected = new Money(m2.value*1936.27/eur_usd1.rate, ITL); + expected = new Money(m2.value * 1936.27 / eur_usd1.rate, ITL); if (!Utils.close(calculated, expected)) { @@ -225,7 +225,7 @@ public void testTriangulatedLookup() usd_itl = rateManager.lookup(USD, ITL, new Date(5, Month.August, 2004)); calculated = usd_itl.exchange(m2); - expected = new Money(m2.value*1936.27/eur_usd2.rate, ITL); + expected = new Money(m2.value * 1936.27 / eur_usd2.rate, ITL); if (!Utils.close(calculated, expected)) { @@ -237,43 +237,43 @@ public void testTriangulatedLookup() /// Testing lookup of derived exchange rates ///
    #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testSmartLookup() + public void testSmartLookup() { Currency EUR = new EURCurrency(), USD = new USDCurrency(), GBP = new GBPCurrency(), - CHF = new CHFCurrency(), SEK = new SEKCurrency(), JPY = new JPYCurrency(); + CHF = new CHFCurrency(), SEK = new SEKCurrency(), JPY = new JPYCurrency(); ExchangeRateManager rateManager = ExchangeRateManager.Instance; rateManager.clear(); ExchangeRate eur_usd1 = new ExchangeRate(EUR, USD, 1.1983); - ExchangeRate eur_usd2 = new ExchangeRate(USD, EUR, 1.0/1.2042); - rateManager.add(eur_usd1, new Date(4,Month.August,2004)); - rateManager.add(eur_usd2, new Date(5,Month.August,2004)); + ExchangeRate eur_usd2 = new ExchangeRate(USD, EUR, 1.0 / 1.2042); + rateManager.add(eur_usd1, new Date(4, Month.August, 2004)); + rateManager.add(eur_usd2, new Date(5, Month.August, 2004)); ExchangeRate eur_gbp1 = new ExchangeRate(GBP, EUR, 1.0 / 0.6596); ExchangeRate eur_gbp2 = new ExchangeRate(EUR, GBP, 0.6612); - rateManager.add(eur_gbp1, new Date(4,Month.August,2004)); - rateManager.add(eur_gbp2, new Date(5,Month.August,2004)); + rateManager.add(eur_gbp1, new Date(4, Month.August, 2004)); + rateManager.add(eur_gbp2, new Date(5, Month.August, 2004)); ExchangeRate usd_chf1 = new ExchangeRate(USD, CHF, 1.2847); ExchangeRate usd_chf2 = new ExchangeRate(CHF, USD, 1.0 / 1.2774); - rateManager.add(usd_chf1, new Date(4,Month.August,2004)); - rateManager.add(usd_chf2, new Date(5,Month.August,2004)); + rateManager.add(usd_chf1, new Date(4, Month.August, 2004)); + rateManager.add(usd_chf2, new Date(5, Month.August, 2004)); ExchangeRate chf_sek1 = new ExchangeRate(SEK, CHF, 0.1674); ExchangeRate chf_sek2 = new ExchangeRate(CHF, SEK, 1.0 / 0.1677); - rateManager.add(chf_sek1, new Date(4,Month.August,2004)); - rateManager.add(chf_sek2, new Date(5,Month.August,2004)); + rateManager.add(chf_sek1, new Date(4, Month.August, 2004)); + rateManager.add(chf_sek2, new Date(5, Month.August, 2004)); ExchangeRate jpy_sek1 = new ExchangeRate(SEK, JPY, 14.5450); ExchangeRate jpy_sek2 = new ExchangeRate(JPY, SEK, 1.0 / 14.6110); - rateManager.add(jpy_sek1, new Date(4,Month.August,2004)); - rateManager.add(jpy_sek2, new Date(5,Month.August,2004)); + rateManager.add(jpy_sek1, new Date(4, Month.August, 2004)); + rateManager.add(jpy_sek2, new Date(5, Month.August, 2004)); Money m1 = 100000.0 * USD; Money m2 = 100000.0 * EUR; @@ -286,18 +286,18 @@ public void testSmartLookup() // two-rate chain - ExchangeRate usd_sek = rateManager.lookup(USD, SEK, new Date(4,Month.August,2004)); + ExchangeRate usd_sek = rateManager.lookup(USD, SEK, new Date(4, Month.August, 2004)); Money calculated = usd_sek.exchange(m1); - Money expected = new Money(m1.value*usd_chf1.rate/chf_sek1.rate, SEK); + Money expected = new Money(m1.value * usd_chf1.rate / chf_sek1.rate, SEK); if (!Utils.close(calculated, expected)) { QAssert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated); } - usd_sek = rateManager.lookup(SEK, USD, new Date(5,Month.August,2004)); + usd_sek = rateManager.lookup(SEK, USD, new Date(5, Month.August, 2004)); calculated = usd_sek.exchange(m5); - expected = new Money(m5.value*usd_chf2.rate/chf_sek2.rate, USD); + expected = new Money(m5.value * usd_chf2.rate / chf_sek2.rate, USD); if (!Utils.close(calculated, expected)) { @@ -306,18 +306,18 @@ public void testSmartLookup() // three-rate chain - ExchangeRate eur_sek = rateManager.lookup(EUR, SEK,new Date(4,Month.August,2004)); + ExchangeRate eur_sek = rateManager.lookup(EUR, SEK, new Date(4, Month.August, 2004)); calculated = eur_sek.exchange(m2); - expected = new Money(m2.value*eur_usd1.rate*usd_chf1.rate/chf_sek1.rate, SEK); + expected = new Money(m2.value * eur_usd1.rate * usd_chf1.rate / chf_sek1.rate, SEK); if (!Utils.close(calculated, expected)) { QAssert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated); } - eur_sek = rateManager.lookup(SEK, EUR, new Date(5,Month.August,2004)); + eur_sek = rateManager.lookup(SEK, EUR, new Date(5, Month.August, 2004)); calculated = eur_sek.exchange(m5); - expected = new Money(m5.value*eur_usd2.rate*usd_chf2.rate/chf_sek2.rate, EUR); + expected = new Money(m5.value * eur_usd2.rate * usd_chf2.rate / chf_sek2.rate, EUR); if (!Utils.close(calculated, expected)) { @@ -326,18 +326,18 @@ public void testSmartLookup() // four-rate chain - ExchangeRate eur_jpy = rateManager.lookup(EUR, JPY,new Date(4,Month.August,2004)); + ExchangeRate eur_jpy = rateManager.lookup(EUR, JPY, new Date(4, Month.August, 2004)); calculated = eur_jpy.exchange(m2); - expected = new Money(m2.value*eur_usd1.rate*usd_chf1.rate*jpy_sek1.rate/chf_sek1.rate, JPY); + expected = new Money(m2.value * eur_usd1.rate * usd_chf1.rate * jpy_sek1.rate / chf_sek1.rate, JPY); if (!Utils.close(calculated, expected)) { QAssert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated); } - eur_jpy = rateManager.lookup(JPY, EUR, new Date(5,Month.August,2004)); + eur_jpy = rateManager.lookup(JPY, EUR, new Date(5, Month.August, 2004)); calculated = eur_jpy.exchange(m6); - expected = new Money(m6.value*jpy_sek2.rate*eur_usd2.rate*usd_chf2.rate/chf_sek2.rate, EUR); + expected = new Money(m6.value * jpy_sek2.rate * eur_usd2.rate * usd_chf2.rate / chf_sek2.rate, EUR); if (!Utils.close(calculated, expected)) { @@ -346,18 +346,18 @@ public void testSmartLookup() // five-rate chain - ExchangeRate gbp_jpy = rateManager.lookup(GBP, JPY,new Date(4,Month.August,2004)); + ExchangeRate gbp_jpy = rateManager.lookup(GBP, JPY, new Date(4, Month.August, 2004)); calculated = gbp_jpy.exchange(m3); - expected = new Money(m3.value*eur_gbp1.rate*eur_usd1.rate*usd_chf1.rate*jpy_sek1.rate/chf_sek1.rate, JPY); + expected = new Money(m3.value * eur_gbp1.rate * eur_usd1.rate * usd_chf1.rate * jpy_sek1.rate / chf_sek1.rate, JPY); if (!Utils.close(calculated, expected)) { QAssert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated); } - gbp_jpy = rateManager.lookup(JPY, GBP, new Date(5,Month.August,2004)); + gbp_jpy = rateManager.lookup(JPY, GBP, new Date(5, Month.August, 2004)); calculated = gbp_jpy.exchange(m6); - expected = new Money(m6.value*jpy_sek2.rate*eur_usd2.rate*usd_chf2.rate*eur_gbp2.rate/chf_sek2.rate, GBP); + expected = new Money(m6.value * jpy_sek2.rate * eur_usd2.rate * usd_chf2.rate * eur_gbp2.rate / chf_sek2.rate, GBP); if (!Utils.close(calculated, expected)) { diff --git a/tests/QLNet.Tests/T_FdmLinearOp.cs b/tests/QLNet.Tests/T_FdmLinearOp.cs index 8044a206f..6d355a31a 100644 --- a/tests/QLNet.Tests/T_FdmLinearOp.cs +++ b/tests/QLNet.Tests/T_FdmLinearOp.cs @@ -1,827 +1,920 @@ -using System; +/* + Copyright (C) 2008 Andrea Maggiulli + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; using System.Collections.Generic; using System.Linq; #if NET40 || NET45 - using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; namespace TestSuite { - #if NET40 || NET45 - [TestClass()] - #endif - public class T_FdmLinearOp - { - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testFdmLinearOpLayout() { - - int[] dims = new int[] {5,7,8}; - List dim = new List(dims); - - FdmLinearOpLayout layout = new FdmLinearOpLayout(dim); - - int calculatedDim = layout.dim().Count; - int expectedDim = dim.Count; - if (calculatedDim != expectedDim) { - QAssert.Fail("index.dimensions() should be " + expectedDim - + ", but is " + calculatedDim); - } - - int calculatedSize = layout.size(); - int expectedSize = dim.accumulate(0, 3, 1, (x,y) => (x*y)); - - if (calculatedSize != expectedSize) { - QAssert.Fail("index.size() should be " - + expectedSize + ", but is " + calculatedSize); - } - - for (int k=0; k < dim[0]; ++k) { - for (int l=0; l < dim[1]; ++l) { - for (int m=0; m < dim[2]; ++m) { - List tmp = new InitializedList(3); - tmp[0] = k; tmp[1] = l; tmp[2] = m; - - int calculatedIndex = layout.index(tmp); - int expectedIndex = k + l*dim[0] + m*dim[0]*dim[1]; - - if (expectedIndex != layout.index(tmp)) { - QAssert.Fail("index.size() should be " + expectedIndex - + ", but is " + calculatedIndex); - } - } - } - } - - FdmLinearOpIterator iter = layout.begin(); - - for (int m=0; m < dim[2]; ++m) { - for (int l=0; l < dim[1]; ++l) { - for (int k=0; k < dim[0]; ++k, ++iter) { - for (int n=1; n < 4; ++n) { - int nn = layout.neighbourhood(iter, 1, n); - int calculatedIndex = k + m*dim[0]*dim[1] - + ((l < dim[1]-n)? l+n - : dim[1]-1-(l+n-(dim[1]-1)))*dim[0]; - - if (nn != calculatedIndex) { - QAssert.Fail("next neighbourhood index is " + nn - + " but should be " + calculatedIndex); - } - } - - for (int n=1; n < 7; ++n) { - int nn = layout.neighbourhood(iter, 2, - n); - int calculatedIndex = k + l*dim[0] - + ((m < n) ? n-m : m-n)*dim[0]*dim[1]; - if (nn != calculatedIndex) { - QAssert.Fail("next neighbourhood index is " + nn - + " but should be " + calculatedIndex); - } - } - } - } - } +#if NET40 || NET45 + [TestClass()] +#endif + public class T_FdmLinearOp + { +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testFdmLinearOpLayout() + { + + int[] dims = new int[] {5, 7, 8}; + List dim = new List(dims); + + FdmLinearOpLayout layout = new FdmLinearOpLayout(dim); + + int calculatedDim = layout.dim().Count; + int expectedDim = dim.Count; + if (calculatedDim != expectedDim) + { + QAssert.Fail("index.dimensions() should be " + expectedDim + + ", but is " + calculatedDim); + } + + int calculatedSize = layout.size(); + int expectedSize = dim.accumulate(0, 3, 1, (x, y) => (x * y)); + + if (calculatedSize != expectedSize) + { + QAssert.Fail("index.size() should be " + + expectedSize + ", but is " + calculatedSize); + } + + for (int k = 0; k < dim[0]; ++k) + { + for (int l = 0; l < dim[1]; ++l) + { + for (int m = 0; m < dim[2]; ++m) + { + List tmp = new InitializedList(3); + tmp[0] = k; tmp[1] = l; tmp[2] = m; + + int calculatedIndex = layout.index(tmp); + int expectedIndex = k + l * dim[0] + m * dim[0] * dim[1]; + + if (expectedIndex != layout.index(tmp)) + { + QAssert.Fail("index.size() should be " + expectedIndex + + ", but is " + calculatedIndex); + } + } + } + } + + FdmLinearOpIterator iter = layout.begin(); + + for (int m = 0; m < dim[2]; ++m) + { + for (int l = 0; l < dim[1]; ++l) + { + for (int k = 0; k < dim[0]; ++k, ++iter) + { + for (int n = 1; n < 4; ++n) + { + int nn = layout.neighbourhood(iter, 1, n); + int calculatedIndex = k + m * dim[0] * dim[1] + + ((l < dim[1] - n)? l + n + : dim[1] - 1 - (l + n - (dim[1] - 1))) * dim[0]; + + if (nn != calculatedIndex) + { + QAssert.Fail("next neighbourhood index is " + nn + + " but should be " + calculatedIndex); + } + } + + for (int n = 1; n < 7; ++n) + { + int nn = layout.neighbourhood(iter, 2, - n); + int calculatedIndex = k + l * dim[0] + + ((m < n) ? n - m : m - n) * dim[0] * dim[1]; + if (nn != calculatedIndex) + { + QAssert.Fail("next neighbourhood index is " + nn + + " but should be " + calculatedIndex); + } + } + } } + } + } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testUniformGridMesher() { - int[] dims = new int[] {5,7,8}; - List dim = new List(dims); - - FdmLinearOpLayout layout = new FdmLinearOpLayout(dim); - List> boundaries = new List>();; - boundaries.Add(new Pair(-5, 10)); - boundaries.Add(new Pair( 5, 100)); - boundaries.Add(new Pair( 10, 20)); - - UniformGridMesher mesher = new UniformGridMesher(layout, boundaries); - - double dx1 = 15.0/(dim[0]-1); - double dx2 = 95.0/(dim[1]-1); - double dx3 = 10.0/(dim[2]-1); - - double tol = 100*Const.QL_EPSILON; - if (Math.Abs(dx1 - mesher.dminus(layout.begin(), 0).Value) > tol - || Math.Abs(dx1 - mesher.dplus(layout.begin(), 0).Value) > tol - || Math.Abs(dx2 - mesher.dminus(layout.begin(), 1).Value) > tol - || Math.Abs(dx2 - mesher.dplus(layout.begin(), 1).Value) > tol - || Math.Abs(dx3 - mesher.dminus(layout.begin(), 2).Value) > tol - || Math.Abs(dx3 - mesher.dplus(layout.begin(), 2).Value) > tol) - { - QAssert.Fail("inconsistent uniform mesher object"); - } +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testUniformGridMesher() + { + int[] dims = new int[] {5, 7, 8}; + List dim = new List(dims); + + FdmLinearOpLayout layout = new FdmLinearOpLayout(dim); + List < Pair < double?, double? >> boundaries = new List < Pair < double?, double? >> ();; + boundaries.Add(new Pair < double?, double? >(-5, 10)); + boundaries.Add(new Pair < double?, double? >(5, 100)); + boundaries.Add(new Pair < double?, double? >(10, 20)); + + UniformGridMesher mesher = new UniformGridMesher(layout, boundaries); + + double dx1 = 15.0 / (dim[0] - 1); + double dx2 = 95.0 / (dim[1] - 1); + double dx3 = 10.0 / (dim[2] - 1); + + double tol = 100 * Const.QL_EPSILON; + if (Math.Abs(dx1 - mesher.dminus(layout.begin(), 0).Value) > tol + || Math.Abs(dx1 - mesher.dplus(layout.begin(), 0).Value) > tol + || Math.Abs(dx2 - mesher.dminus(layout.begin(), 1).Value) > tol + || Math.Abs(dx2 - mesher.dplus(layout.begin(), 1).Value) > tol + || Math.Abs(dx3 - mesher.dminus(layout.begin(), 2).Value) > tol + || Math.Abs(dx3 - mesher.dplus(layout.begin(), 2).Value) > tol) + { + QAssert.Fail("inconsistent uniform mesher object"); + } + } + +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testFirstDerivativesMapApply() + { + int[] dims = new int[] {400, 100, 50}; + List dim = new List(dims); + + FdmLinearOpLayout index = new FdmLinearOpLayout(dim); + + List < Pair < double?, double? > > boundaries = new List < Pair < double?, double? >> (); + boundaries.Add(new Pair < double?, double? >(-5, 5)); + boundaries.Add(new Pair < double?, double? >(0, 10)); + boundaries.Add(new Pair < double?, double? >(5, 15)); + + FdmMesher mesher = new UniformGridMesher(index, boundaries); + + FirstDerivativeOp map = new FirstDerivativeOp(2, mesher); + + Vector r = new Vector(mesher.layout().size()); + FdmLinearOpIterator endIter = index.end(); + + for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) + { + r[iter.index()] = Math.Sin(mesher.location(iter, 0)) + + Math.Cos(mesher.location(iter, 2)); + } + + Vector t = map.apply(r); + double dz = (boundaries[2].second.Value - boundaries[2].first.Value) / (dims[2] - 1); + for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) + { + int z = iter.coordinates()[2]; + + int z0 = (z > 0) ? z - 1 : 1; + int z2 = (z < dims[2] - 1) ? z + 1 : dims[2] - 2; + double lz0 = boundaries[2].first.Value + z0 * dz; + double lz2 = boundaries[2].first.Value + z2 * dz; + + double expected; + if (z == 0) + { + expected = (Math.Cos(boundaries[2].first.Value + dz) + - Math.Cos(boundaries[2].first.Value)) / dz; + } + else if (z == dim[2] - 1) + { + expected = (Math.Cos(boundaries[2].second.Value) + - Math.Cos(boundaries[2].second.Value - dz)) / dz; + } + else + { + expected = (Math.Cos(lz2) - Math.Cos(lz0)) / (2 * dz); } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testFirstDerivativesMapApply() { - int[] dims = new int[] {400, 100, 50}; - List dim = new List(dims); - - FdmLinearOpLayout index = new FdmLinearOpLayout(dim); - - List > boundaries = new List>(); - boundaries.Add(new Pair(-5, 5)); - boundaries.Add(new Pair( 0, 10)); - boundaries.Add(new Pair( 5, 15)); - - FdmMesher mesher = new UniformGridMesher(index, boundaries); - - FirstDerivativeOp map = new FirstDerivativeOp(2, mesher); - - Vector r = new Vector(mesher.layout().size()); - FdmLinearOpIterator endIter = index.end(); - - for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) { - r[iter.index()] = Math.Sin(mesher.location(iter, 0)) - + Math.Cos(mesher.location(iter, 2)); - } - - Vector t = map.apply(r); - double dz = (boundaries[2].second.Value-boundaries[2].first.Value)/(dims[2]-1); - for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) { - int z = iter.coordinates()[2]; - - int z0 = (z > 0) ? z-1 : 1; - int z2 = (z < dims[2]-1) ? z+1 : dims[2]-2; - double lz0 = boundaries[2].first.Value + z0*dz; - double lz2 = boundaries[2].first.Value + z2*dz; - - double expected; - if (z == 0) { - expected = (Math.Cos(boundaries[2].first.Value+dz) - - Math.Cos(boundaries[2].first.Value))/dz; - } - else if (z == dim[2]-1) { - expected = (Math.Cos(boundaries[2].second.Value) - - Math.Cos(boundaries[2].second.Value-dz))/dz; - } - else { - expected = (Math.Cos(lz2)-Math.Cos(lz0))/(2*dz); - } - - double calculated = t[iter.index()]; - if (Math.Abs(calculated - expected) > 1e-10) { - QAssert.Fail("first derivative calculation failed." - + "\n calculated: " + calculated - + "\n expected: " + expected); - } - } + double calculated = t[iter.index()]; + if (Math.Abs(calculated - expected) > 1e-10) + { + QAssert.Fail("first derivative calculation failed." + + "\n calculated: " + calculated + + "\n expected: " + expected); } + } + } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testSecondDerivativesMapApply() { - int[] dims = new int[] {50, 50, 50}; - List dim = new List(dims); +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testSecondDerivativesMapApply() + { + int[] dims = new int[] {50, 50, 50}; + List dim = new List(dims); + + FdmLinearOpLayout index = new FdmLinearOpLayout(dim); + + List < Pair < double?, double? > > boundaries = new List < Pair < double?, double? >> (); + boundaries.Add(new Pair < double?, double? >(0, 0.5)); + boundaries.Add(new Pair < double?, double? >(0, 0.5)); + boundaries.Add(new Pair < double?, double? >(0, 0.5)); + + FdmMesher mesher = new UniformGridMesher(index, boundaries); + + Vector r = new Vector(mesher.layout().size()); + FdmLinearOpIterator endIter = index.end(); + + for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) + { + double x = mesher.location(iter, 0); + double y = mesher.location(iter, 1); + double z = mesher.location(iter, 2); + + r[iter.index()] = Math.Sin(x) * Math.Cos(y) * Math.Exp(z); + } + + Vector t = new SecondDerivativeOp(0, mesher).apply(r); + + double tol = 5e-2; + for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) + { + int i = iter.index(); + double x = mesher.location(iter, 0); + double y = mesher.location(iter, 1); + double z = mesher.location(iter, 2); + + double d = -Math.Sin(x) * Math.Cos(y) * Math.Exp(z); + if (iter.coordinates()[0] == 0 || iter.coordinates()[0] == dims[0] - 1) + { + d = 0; + } - FdmLinearOpLayout index = new FdmLinearOpLayout(dim); + if (Math.Abs(d - t[i]) > tol) + { + QAssert.Fail("numerical derivative in dx^2 deviation is too big" + + "\n found at " + x + " " + y + " " + z); + } + } + + t = new SecondDerivativeOp(1, mesher).apply(r); + for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) + { + int i = iter.index(); + double x = mesher.location(iter, 0); + double y = mesher.location(iter, 1); + double z = mesher.location(iter, 2); + + double d = -Math.Sin(x) * Math.Cos(y) * Math.Exp(z); + if (iter.coordinates()[1] == 0 || iter.coordinates()[1] == dims[1] - 1) + { + d = 0; + } - List > boundaries = new List>(); - boundaries.Add(new Pair( 0, 0.5)); - boundaries.Add(new Pair( 0, 0.5)); - boundaries.Add(new Pair( 0, 0.5)); + if (Math.Abs(d - t[i]) > tol) + { + QAssert.Fail("numerical derivative in dy^2 deviation is too big" + + "\n found at " + x + " " + y + " " + z); + } + } + + t = new SecondDerivativeOp(2, mesher).apply(r); + for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) + { + int i = iter.index(); + double x = mesher.location(iter, 0); + double y = mesher.location(iter, 1); + double z = mesher.location(iter, 2); + + double d = Math.Sin(x) * Math.Cos(y) * Math.Exp(z); + if (iter.coordinates()[2] == 0 || iter.coordinates()[2] == dims[2] - 1) + { + d = 0; + } - FdmMesher mesher = new UniformGridMesher(index, boundaries); + if (Math.Abs(d - t[i]) > tol) + { + QAssert.Fail("numerical derivative in dz^2 deviation is too big" + + "\n found at " + x + " " + y + " " + z); + } + } + } - Vector r = new Vector(mesher.layout().size()); - FdmLinearOpIterator endIter = index.end(); +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testDerivativeWeightsOnNonUniformGrids() + { + Fdm1dMesher mesherX = + new Concentrating1dMesher(-2.0, 3.0, 50, new Pair < double?, double? >(0.5, 0.01)); + Fdm1dMesher mesherY = + new Concentrating1dMesher(0.5, 5.0, 25, new Pair < double?, double? >(0.5, 0.1)); + Fdm1dMesher mesherZ = + new Concentrating1dMesher(-1.0, 2.0, 31, new Pair < double?, double? >(1.5, 0.01)); + + FdmMesher meshers = + new FdmMesherComposite(mesherX, mesherY, mesherZ); + + FdmLinearOpLayout layout = meshers.layout(); + FdmLinearOpIterator endIter = layout.end(); + + double tol = 1e-13; + for (int direction = 0; direction < 3; ++direction) + { + + SparseMatrix dfdx + = new FirstDerivativeOp(direction, meshers).toMatrix(); + SparseMatrix d2fdx2 + = new SecondDerivativeOp(direction, meshers).toMatrix(); + + Vector gridPoints = meshers.locations(direction); + + for (FdmLinearOpIterator iter = layout.begin(); + iter != endIter; ++iter) + { + + int c = iter.coordinates()[direction]; + int index = iter.index(); + int indexM1 = layout.neighbourhood(iter, direction, -1); + int indexP1 = layout.neighbourhood(iter, direction, +1); + + // test only if not on the boundary + if (c == 0) + { + Vector twoPoints = new Vector(2); + twoPoints[0] = 0.0; + twoPoints[1] = gridPoints[indexP1] - gridPoints[index]; + + Vector ndWeights1st = new NumericalDifferentiation(x => x, 1, twoPoints).weights(); + + double beta1 = dfdx[index, index]; + double gamma1 = dfdx[index, indexP1]; + if (Math.Abs((beta1 - ndWeights1st[0]) / beta1) > tol + || Math.Abs((gamma1 - ndWeights1st[1]) / gamma1) > tol) + { + QAssert.Fail("can not reproduce the weights of the " + + "first order derivative operator " + + "on the lower boundary" + + "\n expected beta: " + ndWeights1st[0] + + "\n calculated beta: " + beta1 + + "\n difference beta: " + + (beta1 - ndWeights1st[0]) + + "\n expected gamma: " + ndWeights1st[1] + + "\n calculated gamma: " + gamma1 + + "\n difference gamma: " + + (gamma1 - ndWeights1st[1])); + } + + // free boundary condition by default + double beta2 = d2fdx2[index, index]; + double gamma2 = d2fdx2[index, indexP1]; + + if (Math.Abs(beta2) > Const.QL_EPSILON + || Math.Abs(gamma2) > Const.QL_EPSILON) + { + QAssert.Fail("can not reproduce the weights of the " + + "second order derivative operator " + + "on the lower boundary" + + "\n expected beta: " + 0.0 + + "\n calculated beta: " + beta2 + + "\n expected gamma: " + 0.0 + + "\n calculated gamma: " + gamma2); + } + } + else if (c == layout.dim()[direction] - 1) + { + Vector twoPoints = new Vector(2); + twoPoints[0] = gridPoints[indexM1] - gridPoints[index]; + twoPoints[1] = 0.0; + + Vector ndWeights1st = new NumericalDifferentiation(x => x, 1, twoPoints).weights(); + + double alpha1 = dfdx[index, indexM1]; + double beta1 = dfdx[index, index]; + if (Math.Abs((alpha1 - ndWeights1st[0]) / alpha1) > tol + || Math.Abs((beta1 - ndWeights1st[1]) / beta1) > tol) + { + QAssert.Fail("can not reproduce the weights of the " + + "first order derivative operator " + + "on the upper boundary" + + "\n expected alpha: " + ndWeights1st[0] + + "\n calculated alpha: " + alpha1 + + "\n difference alpha: " + + (alpha1 - ndWeights1st[0]) + + "\n expected beta: " + ndWeights1st[1] + + "\n calculated beta: " + beta1 + + "\n difference beta: " + + (beta1 - ndWeights1st[1])); + } + + // free boundary condition by default + double alpha2 = d2fdx2[index, indexM1]; + double beta2 = d2fdx2[index, index]; + + if (Math.Abs(alpha2) > Const.QL_EPSILON + || Math.Abs(beta2) > Const.QL_EPSILON) + { + QAssert.Fail("can not reproduce the weights of the " + + "second order derivative operator " + + "on the upper boundary" + + "\n expected alpha: " + 0.0 + + "\n calculated alpha: " + alpha2 + + "\n expected beta: " + 0.0 + + "\n calculated beta: " + beta2); + } + } + else + { + Vector threePoints = new Vector(3); + threePoints[0] = gridPoints[indexM1] - gridPoints[index]; + threePoints[1] = 0.0; + threePoints[2] = gridPoints[indexP1] - gridPoints[index]; + + Vector ndWeights1st = new NumericalDifferentiation(x => x, 1, threePoints).weights(); + + double alpha1 = dfdx[index, indexM1]; + double beta1 = dfdx[index, index]; + double gamma1 = dfdx[index, indexP1]; + + if (Math.Abs((alpha1 - ndWeights1st[0]) / alpha1) > tol + || Math.Abs((beta1 - ndWeights1st[1]) / beta1) > tol + || Math.Abs((gamma1 - ndWeights1st[2]) / gamma1) > tol) + { + QAssert.Fail("can not reproduce the weights of the " + + "first order derivative operator" + + "\n expected alpha: " + ndWeights1st[0] + + "\n calculated alpha: " + alpha1 + + "\n difference alpha: " + + (alpha1 - ndWeights1st[0]) + + "\n expected beta: " + ndWeights1st[1] + + "\n calculated beta: " + beta1 + + "\n difference beta: " + + (beta1 - ndWeights1st[1]) + + "\n expected gamma: " + ndWeights1st[2] + + "\n calculated gamma: " + gamma1 + + "\n difference gamma: " + + (gamma1 - ndWeights1st[2])); + } + + Vector ndWeights2nd = new NumericalDifferentiation(x => x, 2, threePoints).weights(); + + double alpha2 = d2fdx2[index, indexM1]; + double beta2 = d2fdx2[index, index]; + double gamma2 = d2fdx2[index, indexP1]; + if (Math.Abs((alpha2 - ndWeights2nd[0]) / alpha2) > tol + || Math.Abs((beta2 - ndWeights2nd[1]) / beta2) > tol + || Math.Abs((gamma2 - ndWeights2nd[2]) / gamma2) > tol) + { + QAssert.Fail("can not reproduce the weights of the " + + "second order derivative operator" + + "\n expected alpha: " + ndWeights2nd[0] + + "\n calculated alpha: " + alpha2 + + "\n difference alpha: " + + (alpha2 - ndWeights2nd[0]) + + "\n expected beta: " + ndWeights2nd[1] + + "\n calculated beta: " + beta2 + + "\n difference beta: " + + (beta2 - ndWeights2nd[1]) + + "\n expected gamma: " + ndWeights2nd[2] + + "\n calculated gamma: " + gamma2 + + "\n difference gamma: " + + (gamma2 - ndWeights2nd[2])); + } + } + } + } + } - for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) { - double x = mesher.location(iter, 0); - double y = mesher.location(iter, 1); - double z = mesher.location(iter, 2); +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testSecondOrderMixedDerivativesMapApply() + { + int[] dims = new int[] {50, 50, 50}; + List dim = new List(dims); - r[iter.index()] = Math.Sin(x)*Math.Cos(y)*Math.Exp(z); - } + FdmLinearOpLayout index = new FdmLinearOpLayout(dim); - Vector t = new SecondDerivativeOp(0, mesher).apply(r); + List < Pair < double?, double? >> boundaries = new List < Pair < double?, double? >> (); + boundaries.Add(new Pair < double?, double? >(0, 0.5)); + boundaries.Add(new Pair < double?, double? >(0, 0.5)); + boundaries.Add(new Pair < double?, double? >(0, 0.5)); - double tol = 5e-2; - for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) { - int i = iter.index(); - double x = mesher.location(iter, 0); - double y = mesher.location(iter, 1); - double z = mesher.location(iter, 2); + FdmMesher mesher = new UniformGridMesher(index, boundaries); - double d = -Math.Sin(x)*Math.Cos(y)*Math.Exp(z); - if (iter.coordinates()[0] == 0 || iter.coordinates()[0] == dims[0]-1) { - d = 0; - } + Vector r = new Vector(mesher.layout().size()); + FdmLinearOpIterator endIter = index.end(); - if (Math.Abs(d - t[i]) > tol) { - QAssert.Fail("numerical derivative in dx^2 deviation is too big" - + "\n found at " + x + " " + y + " " + z); - } - } - - t = new SecondDerivativeOp(1, mesher).apply(r); - for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) { - int i = iter.index(); - double x = mesher.location(iter, 0); - double y = mesher.location(iter, 1); - double z = mesher.location(iter, 2); - - double d = -Math.Sin(x)*Math.Cos(y)*Math.Exp(z); - if (iter.coordinates()[1] == 0 || iter.coordinates()[1] == dims[1]-1) { - d = 0; - } - - if (Math.Abs(d - t[i]) > tol) { - QAssert.Fail("numerical derivative in dy^2 deviation is too big" - + "\n found at " + x + " " + y + " " + z); - } - } - - t = new SecondDerivativeOp(2, mesher).apply(r); - for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) { - int i = iter.index(); - double x = mesher.location(iter, 0); - double y = mesher.location(iter, 1); - double z = mesher.location(iter, 2); - - double d = Math.Sin(x)*Math.Cos(y)*Math.Exp(z); - if (iter.coordinates()[2] == 0 || iter.coordinates()[2] == dims[2]-1) { - d = 0; - } - - if (Math.Abs(d - t[i]) > tol) { - QAssert.Fail("numerical derivative in dz^2 deviation is too big" + for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) + { + double x = mesher.location(iter, 0); + double y = mesher.location(iter, 1); + double z = mesher.location(iter, 2); + + r[iter.index()] = Math.Sin(x) * Math.Cos(y) * Math.Exp(z); + } + + Vector t = new SecondOrderMixedDerivativeOp(0, 1, mesher).apply(r); + Vector u = new SecondOrderMixedDerivativeOp(1, 0, mesher).apply(r); + + double tol = 5e-2; + for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) + { + int i = iter.index(); + double x = mesher.location(iter, 0); + double y = mesher.location(iter, 1); + double z = mesher.location(iter, 2); + + double d = -Math.Cos(x) * Math.Sin(y) * Math.Exp(z); + + if (Math.Abs(d - t[i]) > tol) + { + QAssert.Fail("numerical derivative in dxdy deviation is too big" + "\n found at " + x + " " + y + " " + z); - } - } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testDerivativeWeightsOnNonUniformGrids() { - Fdm1dMesher mesherX = - new Concentrating1dMesher(-2.0, 3.0, 50, new Pair(0.5, 0.01)); - Fdm1dMesher mesherY = - new Concentrating1dMesher(0.5, 5.0, 25, new Pair(0.5, 0.1)); - Fdm1dMesher mesherZ = - new Concentrating1dMesher(-1.0, 2.0, 31, new Pair(1.5, 0.01)); - - FdmMesher meshers = - new FdmMesherComposite(mesherX, mesherY, mesherZ); - - FdmLinearOpLayout layout = meshers.layout(); - FdmLinearOpIterator endIter = layout.end(); - - double tol = 1e-13; - for (int direction=0; direction < 3; ++direction) { - - SparseMatrix dfdx - = new FirstDerivativeOp(direction, meshers).toMatrix(); - SparseMatrix d2fdx2 - = new SecondDerivativeOp(direction, meshers).toMatrix(); - - Vector gridPoints = meshers.locations(direction); - - for (FdmLinearOpIterator iter=layout.begin(); - iter != endIter; ++iter) { - - int c = iter.coordinates()[direction]; - int index = iter.index(); - int indexM1 = layout.neighbourhood(iter,direction,-1); - int indexP1 = layout.neighbourhood(iter,direction,+1); - - // test only if not on the boundary - if (c == 0) { - Vector twoPoints = new Vector(2); - twoPoints[0] = 0.0; - twoPoints[1] = gridPoints[indexP1]-gridPoints[index]; - - Vector ndWeights1st = new NumericalDifferentiation(x => x, 1 , twoPoints).weights(); - - double beta1 = dfdx[index, index]; - double gamma1 = dfdx[index, indexP1]; - if ( Math.Abs((beta1 - ndWeights1st[0])/beta1) > tol - || Math.Abs((gamma1 - ndWeights1st[1])/gamma1) > tol) { - QAssert.Fail("can not reproduce the weights of the " - + "first order derivative operator " - + "on the lower boundary" - + "\n expected beta: " + ndWeights1st[0] - + "\n calculated beta: " + beta1 - + "\n difference beta: " - + (beta1 - ndWeights1st[0]) - + "\n expected gamma: " + ndWeights1st[1] - + "\n calculated gamma: " + gamma1 - + "\n difference gamma: " - + (gamma1 - ndWeights1st[1])); - } - - // free boundary condition by default - double beta2 = d2fdx2[index, index]; - double gamma2 = d2fdx2[index, indexP1]; - - if ( Math.Abs(beta2) > Const.QL_EPSILON - || Math.Abs(gamma2) > Const.QL_EPSILON) { - QAssert.Fail("can not reproduce the weights of the " - + "second order derivative operator " - + "on the lower boundary" - + "\n expected beta: " + 0.0 - + "\n calculated beta: " + beta2 - + "\n expected gamma: " + 0.0 - + "\n calculated gamma: " + gamma2); - } - } - else if (c == layout.dim()[direction]-1) { - Vector twoPoints = new Vector(2); - twoPoints[0] = gridPoints[indexM1]-gridPoints[index]; - twoPoints[1] = 0.0; - - Vector ndWeights1st = new NumericalDifferentiation(x => x, 1 , twoPoints).weights(); - - double alpha1 = dfdx[index, indexM1]; - double beta1 = dfdx[index, index]; - if ( Math.Abs((alpha1 - ndWeights1st[0])/alpha1) > tol - || Math.Abs((beta1 - ndWeights1st[1])/beta1) > tol) { - QAssert.Fail("can not reproduce the weights of the " - + "first order derivative operator " - + "on the upper boundary" - + "\n expected alpha: " + ndWeights1st[0] - + "\n calculated alpha: " + alpha1 - + "\n difference alpha: " - + (alpha1 - ndWeights1st[0]) - + "\n expected beta: " + ndWeights1st[1] - + "\n calculated beta: " + beta1 - + "\n difference beta: " - + (beta1 - ndWeights1st[1])); - } - - // free boundary condition by default - double alpha2 = d2fdx2[index, indexM1]; - double beta2 = d2fdx2[index, index]; - - if ( Math.Abs(alpha2) > Const.QL_EPSILON - || Math.Abs(beta2) > Const.QL_EPSILON) { - QAssert.Fail("can not reproduce the weights of the " - + "second order derivative operator " - + "on the upper boundary" - + "\n expected alpha: " + 0.0 - + "\n calculated alpha: " + alpha2 - + "\n expected beta: " + 0.0 - + "\n calculated beta: " + beta2); - } - } - else { - Vector threePoints = new Vector(3); - threePoints[0] = gridPoints[indexM1]-gridPoints[index]; - threePoints[1] = 0.0; - threePoints[2] = gridPoints[indexP1]-gridPoints[index]; - - Vector ndWeights1st = new NumericalDifferentiation(x => x, 1 , threePoints).weights(); - - double alpha1 = dfdx[index, indexM1]; - double beta1 = dfdx[index, index]; - double gamma1 = dfdx[index, indexP1]; - - if ( Math.Abs((alpha1 - ndWeights1st[0])/alpha1) > tol - || Math.Abs((beta1 - ndWeights1st[1])/beta1) > tol - || Math.Abs((gamma1 - ndWeights1st[2])/gamma1) > tol) { - QAssert.Fail("can not reproduce the weights of the " - + "first order derivative operator" - + "\n expected alpha: " + ndWeights1st[0] - + "\n calculated alpha: " + alpha1 - + "\n difference alpha: " - + (alpha1 - ndWeights1st[0]) - + "\n expected beta: " + ndWeights1st[1] - + "\n calculated beta: " + beta1 - + "\n difference beta: " - + (beta1 - ndWeights1st[1]) - + "\n expected gamma: " + ndWeights1st[2] - + "\n calculated gamma: " + gamma1 - + "\n difference gamma: " - + (gamma1 - ndWeights1st[2])); - } - - Vector ndWeights2nd = new NumericalDifferentiation(x => x, 2 , threePoints).weights(); - - double alpha2 = d2fdx2[index, indexM1]; - double beta2 = d2fdx2[index, index]; - double gamma2 = d2fdx2[index, indexP1]; - if ( Math.Abs((alpha2 - ndWeights2nd[0])/alpha2) > tol - || Math.Abs((beta2 - ndWeights2nd[1])/beta2) > tol - || Math.Abs((gamma2 - ndWeights2nd[2])/gamma2) > tol) { - QAssert.Fail("can not reproduce the weights of the " - + "second order derivative operator" - + "\n expected alpha: " + ndWeights2nd[0] - + "\n calculated alpha: " + alpha2 - + "\n difference alpha: " - + (alpha2 - ndWeights2nd[0]) - + "\n expected beta: " + ndWeights2nd[1] - + "\n calculated beta: " + beta2 - + "\n difference beta: " - + (beta2 - ndWeights2nd[1]) - + "\n expected gamma: " + ndWeights2nd[2] - + "\n calculated gamma: " + gamma2 - + "\n difference gamma: " - + (gamma2 - ndWeights2nd[2])); - } - } - } - } + if (Math.Abs(t[i] - u[i]) > 1e5 * Const.QL_EPSILON) + { + QAssert.Fail("numerical derivative in dxdy not equal to dydx" + + "\n found at " + x + " " + y + " " + z + + "\n value " + Math.Abs(t[i] - u[i])); } - - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testSecondOrderMixedDerivativesMapApply() { - int[] dims = new int[] {50, 50, 50}; - List dim = new List(dims); - - FdmLinearOpLayout index = new FdmLinearOpLayout(dim); - - List> boundaries = new List>(); - boundaries.Add(new Pair( 0, 0.5)); - boundaries.Add(new Pair( 0, 0.5)); - boundaries.Add(new Pair( 0, 0.5)); - - FdmMesher mesher = new UniformGridMesher(index, boundaries); - - Vector r = new Vector(mesher.layout().size()); - FdmLinearOpIterator endIter = index.end(); - - for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) { - double x = mesher.location(iter, 0); - double y = mesher.location(iter, 1); - double z = mesher.location(iter, 2); - - r[iter.index()] = Math.Sin(x)*Math.Cos(y)*Math.Exp(z); - } - - Vector t = new SecondOrderMixedDerivativeOp(0, 1, mesher).apply(r); - Vector u = new SecondOrderMixedDerivativeOp(1, 0, mesher).apply(r); - - double tol = 5e-2; - for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) { - int i = iter.index(); - double x = mesher.location(iter, 0); - double y = mesher.location(iter, 1); - double z = mesher.location(iter, 2); - - double d = -Math.Cos(x)*Math.Sin(y)*Math.Exp(z); - - if (Math.Abs(d - t[i]) > tol) { - QAssert.Fail("numerical derivative in dxdy deviation is too big" - + "\n found at " + x + " " + y + " " + z); - } - - if (Math.Abs(t[i]-u[i]) > 1e5*Const.QL_EPSILON) { - QAssert.Fail("numerical derivative in dxdy not equal to dydx" - + "\n found at " + x + " " + y + " " + z - + "\n value " + Math.Abs(t[i]-u[i])); - } - } - - t = new SecondOrderMixedDerivativeOp(0, 2, mesher).apply(r); - u = new SecondOrderMixedDerivativeOp(2, 0, mesher).apply(r); - for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) { - int i = iter.index(); - double x = mesher.location(iter, 0); - double y = mesher.location(iter, 1); - double z = mesher.location(iter, 2); - - double d = Math.Cos(x)*Math.Cos(y)*Math.Exp(z); - - if (Math.Abs(d - t[i]) > tol) { - QAssert.Fail("numerical derivative in dxdy deviation is too big" + } + + t = new SecondOrderMixedDerivativeOp(0, 2, mesher).apply(r); + u = new SecondOrderMixedDerivativeOp(2, 0, mesher).apply(r); + for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) + { + int i = iter.index(); + double x = mesher.location(iter, 0); + double y = mesher.location(iter, 1); + double z = mesher.location(iter, 2); + + double d = Math.Cos(x) * Math.Cos(y) * Math.Exp(z); + + if (Math.Abs(d - t[i]) > tol) + { + QAssert.Fail("numerical derivative in dxdy deviation is too big" + "\n found at " + x + " " + y + " " + z); - } + } - if (Math.Abs(t[i] - u[i]) > 1e5 * Const.QL_EPSILON) - { - QAssert.Fail("numerical derivative in dxdz not equal to dzdx" + if (Math.Abs(t[i] - u[i]) > 1e5 * Const.QL_EPSILON) + { + QAssert.Fail("numerical derivative in dxdz not equal to dzdx" + "\n found at " + x + " " + y + " " + z - + "\n value " + Math.Abs(t[i]-u[i])); - } - } - - t = new SecondOrderMixedDerivativeOp(1, 2, mesher).apply(r); - u = new SecondOrderMixedDerivativeOp(2, 1, mesher).apply(r); - for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) { - int i = iter.index(); - double x = mesher.location(iter, 0); - double y = mesher.location(iter, 1); - double z = mesher.location(iter, 2); - - double d = -Math.Sin(x)*Math.Sin(y)*Math.Exp(z); - - if (Math.Abs(d - t[i]) > tol) { - QAssert.Fail("numerical derivative in dydz deviation is too big" + + "\n value " + Math.Abs(t[i] - u[i])); + } + } + + t = new SecondOrderMixedDerivativeOp(1, 2, mesher).apply(r); + u = new SecondOrderMixedDerivativeOp(2, 1, mesher).apply(r); + for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter) + { + int i = iter.index(); + double x = mesher.location(iter, 0); + double y = mesher.location(iter, 1); + double z = mesher.location(iter, 2); + + double d = -Math.Sin(x) * Math.Sin(y) * Math.Exp(z); + + if (Math.Abs(d - t[i]) > tol) + { + QAssert.Fail("numerical derivative in dydz deviation is too big" + "\n found at " + x + " " + y + " " + z); - } + } - if (Math.Abs(t[i] - u[i]) > 1e5 * Const.QL_EPSILON) - { - QAssert.Fail("numerical derivative in dydz not equal to dzdy" + if (Math.Abs(t[i] - u[i]) > 1e5 * Const.QL_EPSILON) + { + QAssert.Fail("numerical derivative in dydz not equal to dzdy" + "\n found at " + x + " " + y + " " + z - + "\n value " + Math.Abs(t[i]-u[i])); - } - } + + "\n value " + Math.Abs(t[i] - u[i])); + } + } + + + } + +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testTripleBandMapSolve() + { + int[] dims = new int[] {100, 400}; + List dim = new List(dims); + + FdmLinearOpLayout layout = new FdmLinearOpLayout(dim); + + List < Pair < double?, double? >> boundaries = new List < Pair < double?, double? >> (); + boundaries.Add(new Pair < double?, double? >(0, 1.0)); + boundaries.Add(new Pair < double?, double? >(0, 1.0)); + + FdmMesher mesher = new UniformGridMesher(layout, boundaries); + FirstDerivativeOp dy = new FirstDerivativeOp(1, mesher); + dy.axpyb(new Vector(1, 2.0), dy, dy, new Vector(1, 1.0)); + // check copy constructor + FirstDerivativeOp copyOfDy = new FirstDerivativeOp(dy); + + Vector u = new Vector(layout.size()); + for (int i = 0; i < layout.size(); ++i) + u[i] = Math.Sin(0.1 * i) + Math.Cos(0.35 * i); + + Vector t = new Vector(dy.solve_splitting(copyOfDy.apply(u), 1.0, 0.0)); + for (int i = 0; i < u.size(); ++i) + { + if (Math.Abs(u[i] - t[i]) > 1e-6) + { + QAssert.Fail("solve and apply are not consistent " + + "\n expected : " + u[i] + + "\n calculated : " + t[i]); } + } + + FirstDerivativeOp dx = new FirstDerivativeOp(0, mesher); + dx.axpyb(new Vector(), dx, dx, new Vector(1, 1.0)); - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testTripleBandMapSolve() { - int[] dims = new int[] {100, 400}; - List dim = new List(dims); - - FdmLinearOpLayout layout = new FdmLinearOpLayout(dim); - - List> boundaries = new List>(); - boundaries.Add(new Pair( 0, 1.0)); - boundaries.Add(new Pair( 0, 1.0)); - - FdmMesher mesher = new UniformGridMesher(layout, boundaries); - - FirstDerivativeOp dy = new FirstDerivativeOp(1, mesher); - dy.axpyb(new Vector(1, 2.0), dy, dy, new Vector(1, 1.0)); - - // check copy constructor - FirstDerivativeOp copyOfDy = new FirstDerivativeOp(dy); - - Vector u = new Vector(layout.size()); - for (int i=0; i < layout.size(); ++i) - u[i] = Math.Sin(0.1*i)+Math.Cos(0.35*i); - - Vector t = new Vector(dy.solve_splitting(copyOfDy.apply(u), 1.0, 0.0)); - for (int i=0; i < u.size(); ++i) { - if (Math.Abs(u[i] - t[i]) > 1e-6) { - QAssert.Fail("solve and apply are not consistent " - + "\n expected : " + u[i] - + "\n calculated : " + t[i]); - } - } - - FirstDerivativeOp dx= new FirstDerivativeOp(0, mesher); - dx.axpyb(new Vector(), dx, dx, new Vector(1, 1.0)); - - FirstDerivativeOp copyOfDx = new FirstDerivativeOp(0, mesher); - // check assignment - copyOfDx = dx; - - t = dx.solve_splitting(copyOfDx.apply(u), 1.0, 0.0); - for (int i=0; i < u.size(); ++i) { - if (Math.Abs(u[i] - t[i]) > 1e-6) { - QAssert.Fail("solve and apply are not consistent " + FirstDerivativeOp copyOfDx = new FirstDerivativeOp(0, mesher); + // check assignment + copyOfDx = dx; + + t = dx.solve_splitting(copyOfDx.apply(u), 1.0, 0.0); + for (int i = 0; i < u.size(); ++i) + { + if (Math.Abs(u[i] - t[i]) > 1e-6) + { + QAssert.Fail("solve and apply are not consistent " + "\n expected : " + u[i] + "\n calculated : " + t[i]); - } - } + } + } - SecondDerivativeOp dxx = new SecondDerivativeOp(0, mesher); - dxx.axpyb(new Vector(1, 0.5), dxx, dx, new Vector(1, 1.0)); + SecondDerivativeOp dxx = new SecondDerivativeOp(0, mesher); + dxx.axpyb(new Vector(1, 0.5), dxx, dx, new Vector(1, 1.0)); - // check of copy constructor - SecondDerivativeOp copyOfDxx = new SecondDerivativeOp(dxx); + // check of copy constructor + SecondDerivativeOp copyOfDxx = new SecondDerivativeOp(dxx); - t = dxx.solve_splitting(copyOfDxx.apply(u), 1.0, 0.0); + t = dxx.solve_splitting(copyOfDxx.apply(u), 1.0, 0.0); - for (int i=0; i < u.size(); ++i) { - if (Math.Abs(u[i] - t[i]) > 1e-6) { - QAssert.Fail("solve and apply are not consistent " + for (int i = 0; i < u.size(); ++i) + { + if (Math.Abs(u[i] - t[i]) > 1e-6) + { + QAssert.Fail("solve and apply are not consistent " + "\n expected : " + u[i] + "\n calculated : " + t[i]); - } - } + } + } - //check assignment operator - copyOfDxx.add(new SecondDerivativeOp(1, mesher)); - copyOfDxx = dxx; + //check assignment operator + copyOfDxx.add(new SecondDerivativeOp(1, mesher)); + copyOfDxx = dxx; - t = dxx.solve_splitting(copyOfDxx.apply(u), 1.0, 0.0); + t = dxx.solve_splitting(copyOfDxx.apply(u), 1.0, 0.0); - for (int i=0; i < u.size(); ++i) { - if (Math.Abs(u[i] - t[i]) > 1e-6) { - QAssert.Fail("solve and apply are not consistent " + for (int i = 0; i < u.size(); ++i) + { + if (Math.Abs(u[i] - t[i]) > 1e-6) + { + QAssert.Fail("solve and apply are not consistent " + "\n expected : " + u[i] + "\n calculated : " + t[i]); - } - } } + } + } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testCrankNicolsonWithDamping() { - SavedSettings backup = new SavedSettings(); - - DayCounter dc = new Actual360(); - Date today = Date.Today; - - SimpleQuote spot = new SimpleQuote(100.0); - YieldTermStructure qTS = Utilities.flatRate(today, 0.06, dc); - YieldTermStructure rTS = Utilities.flatRate(today, 0.06, dc); - BlackVolTermStructure volTS = Utilities.flatVol(today, 0.35, dc); - - StrikedTypePayoff payoff = - new CashOrNothingPayoff(Option.Type.Put, 100, 10.0); - - double maturity = 0.75; - Date exDate = today + Convert.ToInt32(maturity*360+0.5); - Exercise exercise = new EuropeanExercise(exDate); - - BlackScholesMertonProcess process = new - BlackScholesMertonProcess(new Handle(spot), - new Handle(qTS), - new Handle(rTS), - new Handle(volTS)); - IPricingEngine engine = - new AnalyticEuropeanEngine(process); - - VanillaOption opt = new VanillaOption(payoff, exercise); - opt.setPricingEngine(engine); - double expectedPV = opt.NPV(); - double expectedGamma = opt.gamma(); - - // fd pricing using implicit damping steps and Crank Nicolson - int csSteps = 25, dampingSteps = 3, xGrid = 400; - List dim = new InitializedList(1, xGrid); - - FdmLinearOpLayout layout = new FdmLinearOpLayout(dim); - Fdm1dMesher equityMesher = - new FdmBlackScholesMesher( - dim[0], process, maturity, payoff.strike(), - null, null, 0.0001, 1.5, - new Pair(payoff.strike(), 0.01)); - - FdmMesher mesher = - new FdmMesherComposite(equityMesher); - - FdmBlackScholesOp map = - new FdmBlackScholesOp(mesher, process, payoff.strike()); - - FdmInnerValueCalculator calculator = - new FdmLogInnerValue(payoff, mesher, 0); - - object rhs = new Vector(layout.size()); - Vector x = new Vector(layout.size()); - FdmLinearOpIterator endIter = layout.end(); - - for (FdmLinearOpIterator iter = layout.begin(); iter != endIter; - ++iter) { - (rhs as Vector)[iter.index()] = calculator.avgInnerValue(iter, maturity); - x[iter.index()] = mesher.location(iter, 0); - } - - FdmBackwardSolver solver = new FdmBackwardSolver(map, new FdmBoundaryConditionSet(), - new FdmStepConditionComposite(), - new FdmSchemeDesc().Douglas()); - solver.rollback(ref rhs, maturity, 0.0, csSteps, dampingSteps); - - MonotonicCubicNaturalSpline spline = new MonotonicCubicNaturalSpline(x, x.Count, rhs as Vector); - - double s = spot.value(); - double calculatedPV = spline.value(Math.Log(s)); - double calculatedGamma = (spline.secondDerivative(Math.Log(s)) - - spline.derivative(Math.Log(s)) )/(s*s); - - double relTol = 2e-3; - - if (Math.Abs(calculatedPV - expectedPV) > relTol*expectedPV) { - QAssert.Fail("Error calculating the PV of the digital option" + - "\n rel. tolerance: " + relTol + - "\n expected: " + expectedPV + - "\n calculated: " + calculatedPV); - } - if (Math.Abs(calculatedGamma - expectedGamma) > relTol * expectedGamma) - { - QAssert.Fail("Error calculating the Gamma of the digital option" + - "\n rel. tolerance: " + relTol + - "\n expected: " + expectedGamma + - "\n calculated: " + calculatedGamma); - } - } +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testCrankNicolsonWithDamping() + { + SavedSettings backup = new SavedSettings(); + + DayCounter dc = new Actual360(); + Date today = Date.Today; + + SimpleQuote spot = new SimpleQuote(100.0); + YieldTermStructure qTS = Utilities.flatRate(today, 0.06, dc); + YieldTermStructure rTS = Utilities.flatRate(today, 0.06, dc); + BlackVolTermStructure volTS = Utilities.flatVol(today, 0.35, dc); + + StrikedTypePayoff payoff = + new CashOrNothingPayoff(Option.Type.Put, 100, 10.0); + + double maturity = 0.75; + Date exDate = today + Convert.ToInt32(maturity * 360 + 0.5); + Exercise exercise = new EuropeanExercise(exDate); + + BlackScholesMertonProcess process = new + BlackScholesMertonProcess(new Handle(spot), + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); + IPricingEngine engine = + new AnalyticEuropeanEngine(process); + + VanillaOption opt = new VanillaOption(payoff, exercise); + opt.setPricingEngine(engine); + double expectedPV = opt.NPV(); + double expectedGamma = opt.gamma(); + + // fd pricing using implicit damping steps and Crank Nicolson + int csSteps = 25, dampingSteps = 3, xGrid = 400; + List dim = new InitializedList(1, xGrid); + + FdmLinearOpLayout layout = new FdmLinearOpLayout(dim); + Fdm1dMesher equityMesher = + new FdmBlackScholesMesher( + dim[0], process, maturity, payoff.strike(), + null, null, 0.0001, 1.5, + new Pair < double?, double? >(payoff.strike(), 0.01)); + + FdmMesher mesher = + new FdmMesherComposite(equityMesher); + + FdmBlackScholesOp map = + new FdmBlackScholesOp(mesher, process, payoff.strike()); + + FdmInnerValueCalculator calculator = + new FdmLogInnerValue(payoff, mesher, 0); + + object rhs = new Vector(layout.size()); + Vector x = new Vector(layout.size()); + FdmLinearOpIterator endIter = layout.end(); + + for (FdmLinearOpIterator iter = layout.begin(); iter != endIter; + ++iter) + { + (rhs as Vector)[iter.index()] = calculator.avgInnerValue(iter, maturity); + x[iter.index()] = mesher.location(iter, 0); + } + + FdmBackwardSolver solver = new FdmBackwardSolver(map, new FdmBoundaryConditionSet(), + new FdmStepConditionComposite(), + new FdmSchemeDesc().Douglas()); + solver.rollback(ref rhs, maturity, 0.0, csSteps, dampingSteps); + + MonotonicCubicNaturalSpline spline = new MonotonicCubicNaturalSpline(x, x.Count, rhs as Vector); + + double s = spot.value(); + double calculatedPV = spline.value(Math.Log(s)); + double calculatedGamma = (spline.secondDerivative(Math.Log(s)) + - spline.derivative(Math.Log(s))) / (s * s); + + double relTol = 2e-3; + + if (Math.Abs(calculatedPV - expectedPV) > relTol * expectedPV) + { + QAssert.Fail("Error calculating the PV of the digital option" + + "\n rel. tolerance: " + relTol + + "\n expected: " + expectedPV + + "\n calculated: " + calculatedPV); + } + if (Math.Abs(calculatedGamma - expectedGamma) > relTol * expectedGamma) + { + QAssert.Fail("Error calculating the Gamma of the digital option" + + "\n rel. tolerance: " + relTol + + "\n expected: " + expectedGamma + + "\n calculated: " + calculatedGamma); + } + } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testSpareMatrixReference() { - int rows = 10; - int columns = 10; - int nMatrices = 5; - int nElements = 50; - - MersenneTwisterUniformRng rng = new MersenneTwisterUniformRng(1234); - - SparseMatrix expected = new SparseMatrix(rows, columns); - List refs = new List(); - - for (int i = 0; i < nMatrices; ++i) - { - SparseMatrix m = new SparseMatrix(rows, columns); - for (int j=0; j < nElements; ++j) { - int row = Convert.ToInt32(rng.next().value*rows); - int column = Convert.ToInt32(rng.next().value*columns); - - double value = rng.next().value; - m[row, column] += value; - expected[row, column] += value; - } - - refs.Add(m); - } - - SparseMatrix calculated = refs.accumulate(1, refs.Count, refs[0], (a, b) => a + b); - - for (int i=0; i < rows; ++i) { - for (int j=0; j < columns; ++j) { - if (Math.Abs(calculated[i,j] - expected[i,j]) > 100*Const.QL_EPSILON) { - QAssert.Fail("Error using sparse matrix references in " + - "Element (" + i + ", " + j + ")" + - "\n expected : " + expected[i, j] + - "\n calculated: " + calculated[i, j]); - } - } - } +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testSpareMatrixReference() + { + int rows = 10; + int columns = 10; + int nMatrices = 5; + int nElements = 50; + + MersenneTwisterUniformRng rng = new MersenneTwisterUniformRng(1234); + + SparseMatrix expected = new SparseMatrix(rows, columns); + List refs = new List(); + + for (int i = 0; i < nMatrices; ++i) + { + SparseMatrix m = new SparseMatrix(rows, columns); + for (int j = 0; j < nElements; ++j) + { + int row = Convert.ToInt32(rng.next().value * rows); + int column = Convert.ToInt32(rng.next().value * columns); + + double value = rng.next().value; + m[row, column] += value; + expected[row, column] += value; } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testFdmMesherIntegral() { - FdmMesherComposite mesher = - new FdmMesherComposite( - new Concentrating1dMesher(-1, 1.6, 21, new Pair(0, 0.1)), - new Concentrating1dMesher(-3, 4, 11, new Pair(1, 0.01)), - new Concentrating1dMesher(-2, 1, 5, new Pair(0.5, 0.1))); - - FdmLinearOpLayout layout = mesher.layout(); - - Vector f = new Vector(mesher.layout().size()); - for (FdmLinearOpIterator iter = layout.begin(); - iter != layout.end(); ++iter) { - double x = mesher.location(iter, 0); - double y = mesher.location(iter, 1); - double z = mesher.location(iter, 2); - - f[iter.index()] = x*x + 3*y*y - 3*z*z - + 2*x*y - x*z - 3*y*z - + 4*x - y - 3*z + 2 ; - } - - double tol = 1e-12; - - // Simpson's rule has to be exact here, Mathematica code gives - // Integrate[x*x+3*y*y-3*z*z+2*x*y-x*z-3*y*z+4*x-y-3*z+2, - // {x, -1, 16/10}, {y, -3, 4}, {z, -2, 1}] - double expectedSimpson = 876.512; - double calculatedSimpson - = new FdmMesherIntegral(mesher, new DiscreteSimpsonIntegral().value).integrate(f); - - if (Math.Abs(calculatedSimpson - expectedSimpson) > tol*expectedSimpson) { - QAssert.Fail("discrete mesher integration using Simpson's rule failed: " - + "\n calculated: " + calculatedSimpson - + "\n expected: " + expectedSimpson); - } - - double expectedTrapezoid = 917.0148209153263; - double calculatedTrapezoid - = new FdmMesherIntegral(mesher, new DiscreteTrapezoidIntegral().value).integrate(f); - - if (Math.Abs(calculatedTrapezoid - expectedTrapezoid) - > tol*expectedTrapezoid) { - QAssert.Fail("discrete mesher integration using Trapezoid rule failed: " - + "\n calculated: " + calculatedTrapezoid - + "\n expected: " + expectedTrapezoid); - } + refs.Add(m); + } + + SparseMatrix calculated = refs.accumulate(1, refs.Count, refs[0], (a, b) => a + b); + + for (int i = 0; i < rows; ++i) + { + for (int j = 0; j < columns; ++j) + { + if (Math.Abs(calculated[i, j] - expected[i, j]) > 100 * Const.QL_EPSILON) + { + QAssert.Fail("Error using sparse matrix references in " + + "Element (" + i + ", " + j + ")" + + "\n expected : " + expected[i, j] + + "\n calculated: " + calculated[i, j]); + } } - } -} \ No newline at end of file + } + } + +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testFdmMesherIntegral() + { + FdmMesherComposite mesher = + new FdmMesherComposite( + new Concentrating1dMesher(-1, 1.6, 21, new Pair < double?, double? >(0, 0.1)), + new Concentrating1dMesher(-3, 4, 11, new Pair < double?, double? >(1, 0.01)), + new Concentrating1dMesher(-2, 1, 5, new Pair < double?, double? >(0.5, 0.1))); + + FdmLinearOpLayout layout = mesher.layout(); + + Vector f = new Vector(mesher.layout().size()); + for (FdmLinearOpIterator iter = layout.begin(); + iter != layout.end(); ++iter) + { + double x = mesher.location(iter, 0); + double y = mesher.location(iter, 1); + double z = mesher.location(iter, 2); + + f[iter.index()] = x * x + 3 * y * y - 3 * z * z + + 2 * x * y - x * z - 3 * y * z + + 4 * x - y - 3 * z + 2 ; + } + + double tol = 1e-12; + + // Simpson's rule has to be exact here, Mathematica code gives + // Integrate[x*x+3*y*y-3*z*z+2*x*y-x*z-3*y*z+4*x-y-3*z+2, + // {x, -1, 16/10}, {y, -3, 4}, {z, -2, 1}] + double expectedSimpson = 876.512; + double calculatedSimpson + = new FdmMesherIntegral(mesher, new DiscreteSimpsonIntegral().value).integrate(f); + + if (Math.Abs(calculatedSimpson - expectedSimpson) > tol * expectedSimpson) + { + QAssert.Fail("discrete mesher integration using Simpson's rule failed: " + + "\n calculated: " + calculatedSimpson + + "\n expected: " + expectedSimpson); + } + + double expectedTrapezoid = 917.0148209153263; + double calculatedTrapezoid + = new FdmMesherIntegral(mesher, new DiscreteTrapezoidIntegral().value).integrate(f); + + if (Math.Abs(calculatedTrapezoid - expectedTrapezoid) + > tol * expectedTrapezoid) + { + QAssert.Fail("discrete mesher integration using Trapezoid rule failed: " + + "\n calculated: " + calculatedTrapezoid + + "\n expected: " + expectedTrapezoid); + } + } + } +} diff --git a/tests/QLNet.Tests/T_ForwardOption.cs b/tests/QLNet.Tests/T_ForwardOption.cs index f0867253c..bae20ea1d 100644 --- a/tests/QLNet.Tests/T_ForwardOption.cs +++ b/tests/QLNet.Tests/T_ForwardOption.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -18,42 +18,42 @@ #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; namespace TestSuite { - #if NET40 || NET45 - [TestClass()] - #endif +#if NET40 || NET45 + [TestClass()] +#endif public class T_ForwardOption { - void REPORT_FAILURE( string greekName, - StrikedTypePayoff payoff, - Exercise exercise, - double s, - double q, - double r, - Date today, - double v, - double moneyness, - Date reset, - double expected, - double calculated, - double error, - double tolerance) + void REPORT_FAILURE(string greekName, + StrikedTypePayoff payoff, + Exercise exercise, + double s, + double q, + double r, + Date today, + double v, + double moneyness, + Date reset, + double expected, + double calculated, + double error, + double tolerance) { - QAssert.Fail("Forward " +exercise + " " + QAssert.Fail("Forward " + exercise + " " + payoff.optionType() + " option with " + payoff + " payoff:\n" + " spot value: " + s + "\n" + " strike: " + payoff.strike() + "\n" - + " moneyness: " + moneyness + "\n" + + " moneyness: " + moneyness + "\n" + " dividend yield: " + q + "\n" + " risk-free rate: " + r + "\n" + " reference date: " + today + "\n" - + " reset date: " + reset + "\n" + + " reset date: " + reset + "\n" + " maturity: " + exercise.lastDate() + "\n" + " volatility: " + v + "\n\n" + " expected " + greekName + ": " + expected + "\n" @@ -65,8 +65,8 @@ void REPORT_FAILURE( string greekName, public class ForwardOptionData { - public ForwardOptionData(Option.Type type_,double moneyness_,double s_,double q_,double r_,double start_, - double t_,double v_,double result_,double tol_) + public ForwardOptionData(Option.Type type_, double moneyness_, double s_, double q_, double r_, double start_, + double t_, double v_, double result_, double tol_) { type = type_; moneyness = moneyness_; @@ -91,13 +91,13 @@ public ForwardOptionData(Option.Type type_,double moneyness_,double s_,double q_ public double result; // expected result public double tol; // tolerance } - - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testValues() + +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testValues() { // Testing forward option values... @@ -125,31 +125,31 @@ public void testValues() Handle volTS = new Handle(Utilities.flatVol(today, vol, dc)); BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), - new Handle(qTS),new Handle(rTS), - new Handle(volTS)); + new Handle(qTS), new Handle(rTS), + new Handle(volTS)); - IPricingEngine engine = new ForwardVanillaEngine( stochProcess, process => new AnalyticEuropeanEngine(process)); // AnalyticEuropeanEngine + IPricingEngine engine = new ForwardVanillaEngine(stochProcess, process => new AnalyticEuropeanEngine(process)); // AnalyticEuropeanEngine - for (int i=0; i< values.Length; i++) + for (int i = 0; i < values.Length; i++) { StrikedTypePayoff payoff = new PlainVanillaPayoff(values[i].type, 0.0); - Date exDate = today + Convert.ToInt32(values[i].t*360+0.5); + Date exDate = today + Convert.ToInt32(values[i].t * 360 + 0.5); Exercise exercise = new EuropeanExercise(exDate); - Date reset = today + Convert.ToInt32(values[i].start*360+0.5); + Date reset = today + Convert.ToInt32(values[i].start * 360 + 0.5); spot .setValue(values[i].s); qRate.setValue(values[i].q); rRate.setValue(values[i].r); vol .setValue(values[i].v); - ForwardVanillaOption option = new ForwardVanillaOption(values[i].moneyness, reset,payoff, exercise); + ForwardVanillaOption option = new ForwardVanillaOption(values[i].moneyness, reset, payoff, exercise); option.setPricingEngine(engine); double calculated = option.NPV(); - double error = Math.Abs(calculated-values[i].result); + double error = Math.Abs(calculated - values[i].result); double tolerance = 1e-4; - if (error>tolerance) + if (error > tolerance) { REPORT_FAILURE("value", payoff, exercise, values[i].s, values[i].q, values[i].r, today, @@ -160,12 +160,12 @@ public void testValues() } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testPerformanceValues() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testPerformanceValues() { // Testing forward performance option values... @@ -173,10 +173,11 @@ public void testPerformanceValues() forward options tested above and taken from "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 */ - ForwardOptionData[] values = { + ForwardOptionData[] values = + { // type, moneyness, spot, div, rate,start, maturity, vol, result, tol - new ForwardOptionData(Option.Type.Call, 1.1, 60.0, 0.04, 0.08, 0.25, 1.0, 0.30, 4.4064/60*Math.Exp(-0.04*0.25), 1.0e-4 ), - new ForwardOptionData(Option.Type.Put, 1.1, 60.0, 0.04, 0.08, 0.25, 1.0, 0.30, 8.2971/60*Math.Exp(-0.04*0.25), 1.0e-4 ) + new ForwardOptionData(Option.Type.Call, 1.1, 60.0, 0.04, 0.08, 0.25, 1.0, 0.30, 4.4064 / 60 * Math.Exp(-0.04 * 0.25), 1.0e-4), + new ForwardOptionData(Option.Type.Put, 1.1, 60.0, 0.04, 0.08, 0.25, 1.0, 0.30, 8.2971 / 60 * Math.Exp(-0.04 * 0.25), 1.0e-4) }; DayCounter dc = new Actual360(); @@ -190,31 +191,31 @@ forward options tested above and taken from SimpleQuote vol = new SimpleQuote(0.0); Handle volTS = new Handle(Utilities.flatVol(today, vol, dc)); - BlackScholesMertonProcess stochProcess= new BlackScholesMertonProcess(new Handle(spot), - new Handle(qTS),new Handle(rTS), - new Handle(volTS)); + BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), + new Handle(qTS), new Handle(rTS), + new Handle(volTS)); - IPricingEngine engine = new ForwardPerformanceVanillaEngine( stochProcess, process => new AnalyticEuropeanEngine( process ) ); // AnalyticEuropeanEngine + IPricingEngine engine = new ForwardPerformanceVanillaEngine(stochProcess, process => new AnalyticEuropeanEngine(process)); // AnalyticEuropeanEngine - for (int i=0; itolerance) + if (error > tolerance) { REPORT_FAILURE("value", payoff, exercise, values[i].s, values[i].q, values[i].r, today, @@ -225,11 +226,11 @@ forward options tested above and taken from } } - private void testForwardGreeks(Type engine_type) + private void testForwardGreeks(Type engine_type) { - Dictionary calculated = new Dictionary(), - expected = new Dictionary(), - tolerance = new Dictionary(); + Dictionary calculated = new Dictionary(), + expected = new Dictionary(), + tolerance = new Dictionary(); tolerance["delta"] = 1.0e-5; tolerance["gamma"] = 1.0e-5; tolerance["theta"] = 1.0e-5; @@ -260,35 +261,35 @@ private void testForwardGreeks(Type engine_type) BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), qTS, rTS, volTS); - IPricingEngine engine = engine_type == typeof( ForwardVanillaEngine ) ? new ForwardVanillaEngine( stochProcess, process => new AnalyticEuropeanEngine( process ) ) : - new ForwardPerformanceVanillaEngine( stochProcess, process => new AnalyticEuropeanEngine( process ) ); + IPricingEngine engine = engine_type == typeof(ForwardVanillaEngine) ? new ForwardVanillaEngine(stochProcess, process => new AnalyticEuropeanEngine(process)) : + new ForwardPerformanceVanillaEngine(stochProcess, process => new AnalyticEuropeanEngine(process)); - for (int i=0; i spot.value()*1.0e-5) + if (value > spot.value() * 1.0e-5) { // perturb spot and get delta and gamma - double du = u*1.0e-4; - spot.setValue(u+du); + double du = u * 1.0e-4; + spot.setValue(u + du); double value_p = option.NPV(), delta_p = option.delta(); - spot.setValue(u-du); + spot.setValue(u - du); double value_m = option.NPV(), delta_m = option.delta(); spot.setValue(u); - expected["delta"] = (value_p - value_m)/(2*du); - expected["gamma"] = (delta_p - delta_m)/(2*du); + expected["delta"] = (value_p - value_m) / (2 * du); + expected["gamma"] = (delta_p - delta_m) / (2 * du); // perturb rates and get rho and dividend rho - double dr = r*1.0e-4; - rRate.setValue(r+dr); + double dr = r * 1.0e-4; + rRate.setValue(r + dr); value_p = option.NPV(); - rRate.setValue(r-dr); + rRate.setValue(r - dr); value_m = option.NPV(); rRate.setValue(r); - expected["rho"] = (value_p - value_m)/(2*dr); + expected["rho"] = (value_p - value_m) / (2 * dr); - double dq = q*1.0e-4; - qRate.setValue(q+dq); + double dq = q * 1.0e-4; + qRate.setValue(q + dq); value_p = option.NPV(); - qRate.setValue(q-dq); + qRate.setValue(q - dq); value_m = option.NPV(); qRate.setValue(q); - expected["divRho"] = (value_p - value_m)/(2*dq); + expected["divRho"] = (value_p - value_m) / (2 * dq); // perturb volatility and get vega - double dv = v*1.0e-4; - vol.setValue(v+dv); + double dv = v * 1.0e-4; + vol.setValue(v + dv); value_p = option.NPV(); - vol.setValue(v-dv); + vol.setValue(v - dv); value_m = option.NPV(); vol.setValue(v); - expected["vega"] = (value_p - value_m)/(2*dv); + expected["vega"] = (value_p - value_m) / (2 * dv); // perturb date and get theta - double dT = dc.yearFraction(today-1, today+1); - Settings.setEvaluationDate(today-1); + double dT = dc.yearFraction(today - 1, today + 1); + Settings.setEvaluationDate(today - 1); value_m = option.NPV(); - Settings.setEvaluationDate(today+1); + Settings.setEvaluationDate(today + 1); value_p = option.NPV(); Settings.setEvaluationDate(today); - expected["theta"] = (value_p - value_m)/dT; + expected["theta"] = (value_p - value_m) / dT; // compare //std::map::iterator it; @@ -364,13 +365,13 @@ private void testForwardGreeks(Type engine_type) double expct = expected [greek], calcl = calculated[greek], tol = tolerance [greek]; - double error = Utilities.relativeError(expct,calcl,u); - if (error>tol) + double error = Utilities.relativeError(expct, calcl, u); + if (error > tol) { REPORT_FAILURE(greek, payoff, exercise, - u, q, r, today, v, - moneyness[j], reset, - expct, calcl, error, tol); + u, q, r, today, v, + moneyness[j], reset, + expct, calcl, error, tol); } } } @@ -384,12 +385,12 @@ private void testForwardGreeks(Type engine_type) } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testGreeks() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testGreeks() { // Testing forward option greeks SavedSettings backup = new SavedSettings(); @@ -397,12 +398,12 @@ public void testGreeks() testForwardGreeks(typeof(ForwardVanillaEngine)); } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testPerformanceGreeks() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testPerformanceGreeks() { // Testing forward performance option greeks SavedSettings backup = new SavedSettings(); @@ -413,17 +414,17 @@ public void testPerformanceGreeks() class TestBinomialEngine : BinomialVanillaEngine { public TestBinomialEngine(GeneralizedBlackScholesProcess process): - base(process, 300) // fixed steps + base(process, 300) // fixed steps {} } // verify than if engine - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testGreeksInitialization() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testGreeksInitialization() { // Testing forward option greeks initialization DayCounter dc = new Actual360(); @@ -436,15 +437,15 @@ public void testGreeksInitialization() Handle qTS = new Handle(Utilities.flatRate(qRate, dc)); SimpleQuote rRate = new SimpleQuote(0.01); Handle rTS = new Handle(Utilities.flatRate(rRate, dc)); - SimpleQuote vol=new SimpleQuote(0.11); + SimpleQuote vol = new SimpleQuote(0.11); Handle volTS = new Handle(Utilities.flatVol(vol, dc)); BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle(spot), qTS, rTS, volTS); - IPricingEngine engine = new ForwardVanillaEngine( stochProcess, process => new TestBinomialEngine( process ) ); - Date exDate = today + new Period(1,TimeUnit.Years); + IPricingEngine engine = new ForwardVanillaEngine(stochProcess, process => new TestBinomialEngine(process)); + Date exDate = today + new Period(1, TimeUnit.Years); Exercise exercise = new EuropeanExercise(exDate); - Date reset = today + new Period(6,TimeUnit.Months); + Date reset = today + new Period(6, TimeUnit.Months); StrikedTypePayoff payoff = new PlainVanillaPayoff(Option.Type.Call, 0.0); ForwardVanillaOption option = new ForwardVanillaOption(0.9, reset, payoff, exercise); @@ -459,7 +460,7 @@ public void testGreeksInitialization() { delta = ctrloption.delta(); } - catch (Exception) + catch (Exception) { // if normal option can't calculate delta, // nor should forward @@ -467,11 +468,11 @@ public void testGreeksInitialization() { delta = option.delta(); } - catch (Exception) + catch (Exception) { delta = null; } - Utils.QL_REQUIRE(delta == null,()=> "Forward delta invalid"); + Utils.QL_REQUIRE(delta == null, () => "Forward delta invalid"); } double? rho = 0; @@ -479,7 +480,7 @@ public void testGreeksInitialization() { rho = ctrloption.rho(); } - catch (Exception) + catch (Exception) { // if normal option can't calculate rho, // nor should forward @@ -487,11 +488,11 @@ public void testGreeksInitialization() { rho = option.rho(); } - catch (Exception) + catch (Exception) { rho = null; } - Utils.QL_REQUIRE(rho == null,()=> "Forward rho invalid"); + Utils.QL_REQUIRE(rho == null, () => "Forward rho invalid"); } double? divRho = 0; @@ -499,7 +500,7 @@ public void testGreeksInitialization() { divRho = ctrloption.dividendRho(); } - catch (Exception) + catch (Exception) { // if normal option can't calculate divRho, // nor should forward @@ -507,11 +508,11 @@ public void testGreeksInitialization() { divRho = option.dividendRho(); } - catch (Exception) + catch (Exception) { divRho = null; } - Utils.QL_REQUIRE(divRho == null,()=> "Forward dividendRho invalid"); + Utils.QL_REQUIRE(divRho == null, () => "Forward dividendRho invalid"); } double? vega = 0; @@ -519,7 +520,7 @@ public void testGreeksInitialization() { vega = ctrloption.vega(); } - catch (Exception) + catch (Exception) { // if normal option can't calculate vega, // nor should forward @@ -527,11 +528,11 @@ public void testGreeksInitialization() { vega = option.vega(); } - catch (Exception) + catch (Exception) { vega = null; } - Utils.QL_REQUIRE(vega == null,()=> "Forward vega invalid"); + Utils.QL_REQUIRE(vega == null, () => "Forward vega invalid"); } } } diff --git a/tests/QLNet.Tests/T_Functions.cs b/tests/QLNet.Tests/T_Functions.cs index 2dd1d6931..cbf58e797 100644 --- a/tests/QLNet.Tests/T_Functions.cs +++ b/tests/QLNet.Tests/T_Functions.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2015 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,7 +20,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; using System.Numerics; @@ -33,38 +33,38 @@ namespace TestSuite public class T_Functions { #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testFactorial() + public void testFactorial() { // Testing factorial numbers double expected = 1.0; double calculated = Factorial.get(0); - if (calculated!=expected) + if (calculated != expected) QAssert.Fail("Factorial(0) = " + calculated); - for (uint i=1; i<171; ++i) + for (uint i = 1; i < 171; ++i) { expected *= i; calculated = Factorial.get(i); - if (Math.Abs(calculated-expected)/expected > 1.0e-9) + if (Math.Abs(calculated - expected) / expected > 1.0e-9) QAssert.Fail("Factorial(" + i + ")" + - "\n calculated: " + calculated + - "\n expected: " + expected + - "\n rel. error: " + - Math.Abs(calculated-expected)/expected); + "\n calculated: " + calculated + + "\n expected: " + expected + + "\n rel. error: " + + Math.Abs(calculated - expected) / expected); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testGammaFunction() + public void testGammaFunction() { // Testing Gamma function @@ -72,70 +72,71 @@ public void testGammaFunction() double calculated = GammaFunction.logValue(1); if (Math.Abs(calculated) > 1.0e-15) QAssert.Fail("GammaFunction(1)\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected); + + " calculated: " + calculated + "\n" + + " expected: " + expected); - for (int i=2; i<9000; i++) + for (int i = 2; i < 9000; i++) { expected += Math.Log(i); - calculated = GammaFunction.logValue((i+1)); - if (Math.Abs(calculated-expected)/expected > 1.0e-9) + calculated = GammaFunction.logValue((i + 1)); + if (Math.Abs(calculated - expected) / expected > 1.0e-9) QAssert.Fail("GammaFunction(" + i + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " rel. error: " - + Math.Abs(calculated-expected)/expected); + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " rel. error: " + + Math.Abs(calculated - expected) / expected); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testGammaValues() + public void testGammaValues() { // Testing Gamma values // reference results are calculated with R - double[][] tasks = { - new double[3] { 0.0001, 9999.422883231624, 1e3}, - new double[3] { 1.2, 0.9181687423997607, 1e3}, - new double[3] { 7.3, 1271.4236336639089586, 1e3}, - new double[3] {-1.1, 9.7148063829028946, 1e3}, - new double[3] {-4.001,-41.6040228304425312, 1e3}, - new double[3] {-4.999, -8.347576090315059, 1e3}, - new double[3] {-19.000001, 8.220610833201313e-12, 1e8}, - new double[3] {-19.5, 5.811045977502255e-18, 1e3}, - new double[3] {-21.000001, 1.957288098276488e-14, 1e8}, - new double[3] {-21.5, 1.318444918321553e-20, 1e6} + double[][] tasks = + { + new double[3] { 0.0001, 9999.422883231624, 1e3}, + new double[3] { 1.2, 0.9181687423997607, 1e3}, + new double[3] { 7.3, 1271.4236336639089586, 1e3}, + new double[3] {-1.1, 9.7148063829028946, 1e3}, + new double[3] {-4.001, -41.6040228304425312, 1e3}, + new double[3] {-4.999, -8.347576090315059, 1e3}, + new double[3] {-19.000001, 8.220610833201313e-12, 1e8}, + new double[3] {-19.5, 5.811045977502255e-18, 1e3}, + new double[3] {-21.000001, 1.957288098276488e-14, 1e8}, + new double[3] {-21.5, 1.318444918321553e-20, 1e6} }; - for (int i=0; i < tasks.Length; ++i) + for (int i = 0; i < tasks.Length; ++i) { double x = tasks[i][0]; double expected = tasks[i][1]; double calculated = GammaFunction.value(x); - double tol = tasks[i][2] * Const.QL_EPSILON*Math.Abs(expected); + double tol = tasks[i][2] * Const.QL_EPSILON * Math.Abs(expected); - if (Math.Abs(calculated - expected) > tol) + if (Math.Abs(calculated - expected) > tol) { QAssert.Fail("GammaFunction(" + x + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " rel. error: " - + Math.Abs(calculated-expected)/expected); - + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " rel. error: " + + Math.Abs(calculated - expected) / expected); + } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testModifiedBesselFunctions() + public void testModifiedBesselFunctions() { // Testing modified Bessel function of first and second kind @@ -143,7 +144,8 @@ public void testModifiedBesselFunctions() * http://cran.r-project.org/web/packages/Bessel */ - double[][] r = { + double[][] r = + { new double[4] {-1.3, 2.0, 1.2079888436539505, 0.1608243636110430}, new double[4] { 1.3, 2.0, 1.2908192151358788, 0.1608243636110430}, new double[4] { 0.001, 2.0, 2.2794705965773794, 0.1138938963603362}, @@ -153,136 +155,140 @@ public void testModifiedBesselFunctions() new double[4] {-10.0001, 1.1, 13857.7715614282552, 69288858.9474423379} }; - for (int i=0; i < r.Length; ++i) + for (int i = 0; i < r.Length; ++i) { double nu = r[i][0]; double x = r[i][1]; double expected_i = r[i][2]; double expected_k = r[i][3]; - double tol_i = 5e4 * Const.QL_EPSILON*Math.Abs(expected_i); - double tol_k = 5e4 * Const.QL_EPSILON*Math.Abs(expected_k); + double tol_i = 5e4 * Const.QL_EPSILON * Math.Abs(expected_i); + double tol_k = 5e4 * Const.QL_EPSILON * Math.Abs(expected_k); double calculated_i = Utils.modifiedBesselFunction_i(nu, x); double calculated_k = Utils.modifiedBesselFunction_k(nu, x); - if (Math.Abs(expected_i - calculated_i) > tol_i) { + if (Math.Abs(expected_i - calculated_i) > tol_i) + { QAssert.Fail("failed to reproduce modified Bessel " - + "function of first kind" - + "\n order : " + nu - + "\n argument : " + x - + "\n calculated: " + calculated_i - + "\n expected : " + expected_i); + + "function of first kind" + + "\n order : " + nu + + "\n argument : " + x + + "\n calculated: " + calculated_i + + "\n expected : " + expected_i); } - if (Math.Abs(expected_k - calculated_k) > tol_k) { + if (Math.Abs(expected_k - calculated_k) > tol_k) + { QAssert.Fail("failed to reproduce modified Bessel " - + "function of second kind" - + "\n order : " + nu - + "\n argument : " + x - + "\n calculated: " + calculated_k - + "\n expected : " + expected_k); + + "function of second kind" + + "\n order : " + nu + + "\n argument : " + x + + "\n calculated: " + calculated_k + + "\n expected : " + expected_k); } } - double[][] c = { + double[][] c = + { new double[7] {-1.3, 2.0, 0.0, 1.2079888436539505, 0.0, 0.1608243636110430, 0.0}, new double[7] { 1.2, 1.5, 0.3, 0.7891550871263575, 0.2721408731632123, 0.275126507673411, -0.1316314405663727}, - new double[7] { 1.2, -1.5,0.0,-0.6650597524355781, -0.4831941938091643, -0.251112360556051, -2.400130904230102}, - new double[7] {-11.2, 1.5, 0.3,12780719.20252659, 16401053.26770633, -34155172.65672453, -43830147.36759921}, - new double[7] { 1.2, -1.5,2.0,-0.3869803778520574, 0.9756701796853728, -3.111629716783005, 0.6307859871879062}, - new double[7] { 1.2, 0.0, 9.9999,-0.03507838078252647, 0.1079601550451466, -0.05979939995451453, 0.3929814473878203}, + new double[7] { 1.2, -1.5, 0.0, -0.6650597524355781, -0.4831941938091643, -0.251112360556051, -2.400130904230102}, + new double[7] {-11.2, 1.5, 0.3, 12780719.20252659, 16401053.26770633, -34155172.65672453, -43830147.36759921}, + new double[7] { 1.2, -1.5, 2.0, -0.3869803778520574, 0.9756701796853728, -3.111629716783005, 0.6307859871879062}, + new double[7] { 1.2, 0.0, 9.9999, -0.03507838078252647, 0.1079601550451466, -0.05979939995451453, 0.3929814473878203}, new double[7] { 1.2, 0.0, 10.1, -0.02782046891519293, 0.08562259917678558, -0.02035685034691133, 0.3949834389686676}, new double[7] { 1.2, 0.0, 12.1, 0.07092110620741207, -0.2182727210128104, 0.3368505862966958, -0.1299038064313366}, - new double[7] { 1.2, 0.0, 14.1,-0.03014378676768797, 0.09277303628303372, -0.237531022649052, -0.2351923034581644}, - new double[7] { 1.2, 0.0, 16.1,-0.03823210284792657, 0.1176663135266562, -0.1091239402448228, 0.2930535651966139}, - new double[7] { 1.2, 0.0, 18.1,0.05626742394733754, -0.173173324361983, 0.2941636588154642, -0.02023355577954348}, - new double[7] { 1.2, 0.0, 180.1,-0.001230682086826484, 0.003787649998122361,0.02284509628723454, 0.09055419580980778}, - new double[7] { 1.2, 0.0, 21.0,-0.04746415965014021, 0.1460796627610969,-0.2693825171336859, -0.04830804448126782}, + new double[7] { 1.2, 0.0, 14.1, -0.03014378676768797, 0.09277303628303372, -0.237531022649052, -0.2351923034581644}, + new double[7] { 1.2, 0.0, 16.1, -0.03823210284792657, 0.1176663135266562, -0.1091239402448228, 0.2930535651966139}, + new double[7] { 1.2, 0.0, 18.1, 0.05626742394733754, -0.173173324361983, 0.2941636588154642, -0.02023355577954348}, + new double[7] { 1.2, 0.0, 180.1, -0.001230682086826484, 0.003787649998122361, 0.02284509628723454, 0.09055419580980778}, + new double[7] { 1.2, 0.0, 21.0, -0.04746415965014021, 0.1460796627610969, -0.2693825171336859, -0.04830804448126782}, new double[7] { 1.2, 10.0, 0.0, 2609.784936867044, 0, 1.904394919838336e-05, 0}, new double[7] { 1.2, 14.0, 0.0, 122690.4873454286, 0, 2.902060692576643e-07, 0}, new double[7] { 1.2, 20.0, 10.0, -37452017.91168936, -13917587.22151363, -3.821534367487143e-10, 4.083211255351664e-10}, new double[7] { 1.2, 9.0, 9.0, -621.7335051293694, 618.1455736670332, -4.480795479964915e-05, -3.489034389148745e-08} }; - for (int i=0; i < c.Length; ++i) + for (int i = 0; i < c.Length; ++i) { double nu = c[i][0]; Complex z = new Complex(c[i][1], c[i][2]); - Complex expected_i = new Complex(c[i][3],c[i][4]); - Complex expected_k = new Complex(c[i][5],c[i][6]); + Complex expected_i = new Complex(c[i][3], c[i][4]); + Complex expected_k = new Complex(c[i][5], c[i][6]); - double tol_i = 5e4*Const.QL_EPSILON*Complex.Abs(expected_i); - double tol_k = 1e6*Const.QL_EPSILON*Complex.Abs(expected_k); + double tol_i = 5e4 * Const.QL_EPSILON * Complex.Abs(expected_i); + double tol_k = 1e6 * Const.QL_EPSILON * Complex.Abs(expected_k); - Complex calculated_i= Utils.modifiedBesselFunction_i(nu, z); - Complex calculated_k= Utils.modifiedBesselFunction_k(nu, z); + Complex calculated_i = Utils.modifiedBesselFunction_i(nu, z); + Complex calculated_k = Utils.modifiedBesselFunction_k(nu, z); - if (Complex.Abs(expected_i - calculated_i) > tol_i) + if (Complex.Abs(expected_i - calculated_i) > tol_i) { QAssert.Fail("failed to reproduce modified Bessel " - + "function of first kind" - + "\n order : " + nu - + "\n argument : " + z - + "\n calculated: " + calculated_i - + "\n expected : " + expected_i); + + "function of first kind" + + "\n order : " + nu + + "\n argument : " + z + + "\n calculated: " + calculated_i + + "\n expected : " + expected_i); } - - if ( Complex.Abs(expected_k) > 1e-4 // do not check small values - && Complex.Abs(expected_k - calculated_k) > tol_k) + + if (Complex.Abs(expected_k) > 1e-4 // do not check small values + && Complex.Abs(expected_k - calculated_k) > tol_k) { QAssert.Fail("failed to reproduce modified Bessel " - + "function of second kind" - + "\n order : " + nu - + "\n argument : " + z - + "\n diff : " + (calculated_k-expected_k) - + "\n calculated: " + calculated_k - + "\n expected : " + expected_k); + + "function of second kind" + + "\n order : " + nu + + "\n argument : " + z + + "\n diff : " + (calculated_k - expected_k) + + "\n calculated: " + calculated_k + + "\n expected : " + expected_k); } } - } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testWeightedModifiedBesselFunctions() + public void testWeightedModifiedBesselFunctions() { // Testing weighted modified Bessel functions double nu = -5.0; - while (nu <= 5.0) + while (nu <= 5.0) { double x = 0.1; - while (x <= 15.0) + while (x <= 15.0) { double vi = Utils.modifiedBesselFunction_i_exponentiallyWeighted(nu, x); double wi = Utils.modifiedBesselFunction_i(nu, x) * Math.Exp(-x); double vk = Utils.modifiedBesselFunction_k_exponentiallyWeighted(nu, x); - double wk = Const.M_PI_2 * (Utils.modifiedBesselFunction_i(-nu,x)*Math.Exp(-x)- - Utils.modifiedBesselFunction_i(nu,x)*Math.Exp(-x)) / Math.Sin(Const.M_PI*nu); + double wk = Const.M_PI_2 * (Utils.modifiedBesselFunction_i(-nu, x) * Math.Exp(-x) - + Utils.modifiedBesselFunction_i(nu, x) * Math.Exp(-x)) / Math.Sin(Const.M_PI * nu); if (Math.Abs((vi - wi) / (Math.Max(Math.Exp(x), 1.0) * vi)) > 1E3 * Const.QL_EPSILON) - QAssert.Fail("failed to verify exponentially weighted" - + "modified Bessel function of first kind" - + "\n order : " + nu + "\n argument : " - + x + "\n calcuated : " + vi - + "\n expecetd : " + wi); + QAssert.Fail("failed to verify exponentially weighted" + + "modified Bessel function of first kind" + + "\n order : " + nu + "\n argument : " + + x + "\n calcuated : " + vi + + "\n expecetd : " + wi); if (Math.Abs((vk - wk) / (Math.Max(Math.Exp(x), 1.0) * vk)) > 1E3 * Const.QL_EPSILON) - QAssert.Fail("failed to verify exponentially weighted" - + "modified Bessel function of second kind" - + "\n order : " + nu + "\n argument : " - + x + "\n calcuated : " + vk - + "\n expecetd : " + wk); + QAssert.Fail("failed to verify exponentially weighted" + + "modified Bessel function of second kind" + + "\n order : " + nu + "\n argument : " + + x + "\n calcuated : " + vk + + "\n expecetd : " + wk); x += 0.5; } nu += 0.5; } nu = -5.0; - while (nu <= 5.0) + while (nu <= 5.0) { double x = -5.0; - while (x <= 5.0) { + while (x <= 5.0) + { double y = -5.0; - while (y <= 5.0) + while (y <= 5.0) { Complex z = new Complex(x, y); Complex vi = Utils.modifiedBesselFunction_i_exponentiallyWeighted(nu, z); @@ -293,25 +299,25 @@ public void testWeightedModifiedBesselFunctions() Math.Sin(Const.M_PI * nu); if (Complex.Abs((vi - wi) / vi) > 1E3 * Const.QL_EPSILON) QAssert.Fail("failed to verify exponentially weighted" - + "modified Bessel function of first kind" - + "\n order : " + nu - + "\n argument : " + z + - "\n calcuated: " - + vi + "\n expecetd : " + wi); + + "modified Bessel function of first kind" + + "\n order : " + nu + + "\n argument : " + z + + "\n calcuated: " + + vi + "\n expecetd : " + wi); if (Complex.Abs((vk - wk) / vk) > 1E3 * Const.QL_EPSILON) QAssert.Fail("failed to verify exponentially weighted" - + "modified Bessel function of second kind" - + "\n order : " + nu - + "\n argument : " + z + - "\n calcuated: " - + vk + "\n expecetd : " + wk); + + "modified Bessel function of second kind" + + "\n order : " + nu + + "\n argument : " + z + + "\n calcuated: " + + vk + "\n expecetd : " + wk); y += 0.5; } x += 0.5; } nu += 0.5; } - + } } diff --git a/tests/QLNet.Tests/T_HestonModel.cs b/tests/QLNet.Tests/T_HestonModel.cs index be0594b87..cb6c863bb 100644 --- a/tests/QLNet.Tests/T_HestonModel.cs +++ b/tests/QLNet.Tests/T_HestonModel.cs @@ -4,7 +4,7 @@ // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a // copy of the license along with this program; if not, license is -// available online at . +// available at . // // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ @@ -18,7 +18,7 @@ #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -35,7 +35,7 @@ struct CalibrationMarketData public Handle riskFreeTS, dividendYield; public List options; public CalibrationMarketData(Handle _s0, Handle _riskFreeTS, - Handle _dividendYield, List _options) + Handle _dividendYield, List _options) { s0 = _s0; riskFreeTS = _riskFreeTS; @@ -58,7 +58,7 @@ Pricing European-Style Options under Jump Diffusion Processes Calendar calendar = new TARGET(); int[] t = { 13, 41, 75, 165, 256, 345, 524, 703 }; - double[] r = { 0.0357,0.0349,0.0341,0.0355,0.0359,0.0368,0.0386,0.0401 }; + double[] r = { 0.0357, 0.0349, 0.0341, 0.0355, 0.0359, 0.0368, 0.0386, 0.0401 }; List dates = new List(); List rates = new List(); @@ -78,23 +78,26 @@ Pricing European-Style Options under Jump Diffusion Processes Handle dividendYield = new Handle(Utilities.flatRate(settlementDate, 0.0, dayCounter)); double[] v = - { 0.6625,0.4875,0.4204,0.3667,0.3431,0.3267,0.3121,0.3121, - 0.6007,0.4543,0.3967,0.3511,0.3279,0.3154,0.2984,0.2921, - 0.5084,0.4221,0.3718,0.3327,0.3155,0.3027,0.2919,0.2889, - 0.4541,0.3869,0.3492,0.3149,0.2963,0.2926,0.2819,0.2800, - 0.4060,0.3607,0.3330,0.2999,0.2887,0.2811,0.2751,0.2775, - 0.3726,0.3396,0.3108,0.2781,0.2788,0.2722,0.2661,0.2686, - 0.3550,0.3277,0.3012,0.2781,0.2781,0.2661,0.2661,0.2681, - 0.3428,0.3209,0.2958,0.2740,0.2688,0.2627,0.2580,0.2620, - 0.3302,0.3062,0.2799,0.2631,0.2573,0.2533,0.2504,0.2544, - 0.3343,0.2959,0.2705,0.2540,0.2504,0.2464,0.2448,0.2462, - 0.3460,0.2845,0.2624,0.2463,0.2425,0.2385,0.2373,0.2422, - 0.3857,0.2860,0.2578,0.2399,0.2357,0.2327,0.2312,0.2351, - 0.3976,0.2860,0.2607,0.2356,0.2297,0.2268,0.2241,0.2320 }; + { + 0.6625, 0.4875, 0.4204, 0.3667, 0.3431, 0.3267, 0.3121, 0.3121, + 0.6007, 0.4543, 0.3967, 0.3511, 0.3279, 0.3154, 0.2984, 0.2921, + 0.5084, 0.4221, 0.3718, 0.3327, 0.3155, 0.3027, 0.2919, 0.2889, + 0.4541, 0.3869, 0.3492, 0.3149, 0.2963, 0.2926, 0.2819, 0.2800, + 0.4060, 0.3607, 0.3330, 0.2999, 0.2887, 0.2811, 0.2751, 0.2775, + 0.3726, 0.3396, 0.3108, 0.2781, 0.2788, 0.2722, 0.2661, 0.2686, + 0.3550, 0.3277, 0.3012, 0.2781, 0.2781, 0.2661, 0.2661, 0.2681, + 0.3428, 0.3209, 0.2958, 0.2740, 0.2688, 0.2627, 0.2580, 0.2620, + 0.3302, 0.3062, 0.2799, 0.2631, 0.2573, 0.2533, 0.2504, 0.2544, + 0.3343, 0.2959, 0.2705, 0.2540, 0.2504, 0.2464, 0.2448, 0.2462, + 0.3460, 0.2845, 0.2624, 0.2463, 0.2425, 0.2385, 0.2373, 0.2422, + 0.3857, 0.2860, 0.2578, 0.2399, 0.2357, 0.2327, 0.2312, 0.2351, + 0.3976, 0.2860, 0.2607, 0.2356, 0.2297, 0.2268, 0.2241, 0.2320 + }; Handle s0 = new Handle(new SimpleQuote(4468.17)); - double[] strike = { 3400,3600,3800,4000,4200,4400, - 4500,4600,4800,5000,5200,5400,5600 }; + double[] strike = { 3400, 3600, 3800, 4000, 4200, 4400, + 4500, 4600, 4800, 5000, 5200, 5400, 5600 + }; List options = new List(); @@ -102,23 +105,23 @@ Pricing European-Style Options under Jump Diffusion Processes { for (int m = 0; m < 8; ++m) { - Handle vol = new Handle(new SimpleQuote(v[s*8+m])); + Handle vol = new Handle(new SimpleQuote(v[s * 8 + m])); - Period maturity = new Period((int)((t[m]+3)/7.0), TimeUnit.Weeks); // round to weeks - options.Add( new HestonModelHelper(maturity, calendar,s0, strike[s], vol,riskFreeTS, dividendYield, - CalibrationHelper.CalibrationErrorType.ImpliedVolError)); + Period maturity = new Period((int)((t[m] + 3) / 7.0), TimeUnit.Weeks); // round to weeks + options.Add(new HestonModelHelper(maturity, calendar, s0, strike[s], vol, riskFreeTS, dividendYield, + CalibrationHelper.CalibrationErrorType.ImpliedVolError)); } } - CalibrationMarketData marketData = new CalibrationMarketData( s0, riskFreeTS, dividendYield, options ); + CalibrationMarketData marketData = new CalibrationMarketData(s0, riskFreeTS, dividendYield, options); return marketData; - } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testBlackCalibration() { @@ -158,26 +161,26 @@ In addition theta and v0 should be equal to the constant variance */ for (double moneyness = -1.0; moneyness < 2.0; moneyness += 1.0) { // FLOATING_POINT_EXCEPTION - double tau = dayCounter.yearFraction( riskFreeTS.link.referenceDate(), - calendar.advance(riskFreeTS.link.referenceDate(), - optionMaturities[i])); - double fwdPrice = s0.link.value()*dividendTS.link.discount(tau) + double tau = dayCounter.yearFraction(riskFreeTS.link.referenceDate(), + calendar.advance(riskFreeTS.link.referenceDate(), + optionMaturities[i])); + double fwdPrice = s0.link.value() * dividendTS.link.discount(tau) / riskFreeTS.link.discount(tau); double strikePrice = fwdPrice * Math.Exp(-moneyness * volatility * Math.Sqrt(tau)); - options.Add( new HestonModelHelper(optionMaturities[i], calendar,s0, strikePrice, vol, - riskFreeTS, dividendTS)); + options.Add(new HestonModelHelper(optionMaturities[i], calendar, s0, strikePrice, vol, + riskFreeTS, dividendTS)); } } for (double sigma = 0.1; sigma < 0.7; sigma += 0.2) { - double v0=0.01; - double kappa=0.2; - double theta=0.02; - double rho=-0.75; + double v0 = 0.01; + double kappa = 0.2; + double theta = 0.02; + double rho = -0.75; - HestonProcess process = new HestonProcess(riskFreeTS, dividendTS,s0, v0, kappa, theta, sigma, rho); + HestonProcess process = new HestonProcess(riskFreeTS, dividendTS, s0, v0, kappa, theta, sigma, rho); HestonModel model = new HestonModel(process); IPricingEngine engine = new AnalyticHestonEngine(model, 96); @@ -186,39 +189,39 @@ In addition theta and v0 should be equal to the constant variance */ options[i].setPricingEngine(engine); LevenbergMarquardt om = new LevenbergMarquardt(1e-8, 1e-8, 1e-8); - model.calibrate(options, om, new EndCriteria(400, 40, 1.0e-8,1.0e-8, 1.0e-8)); + model.calibrate(options, om, new EndCriteria(400, 40, 1.0e-8, 1.0e-8, 1.0e-8)); double tolerance = 3.0e-3; if (model.sigma() > tolerance) { QAssert.Fail("Failed to reproduce expected sigma" - + "\n calculated: " + model.sigma() - + "\n expected: " + 0.0 - + "\n tolerance: " + tolerance); + + "\n calculated: " + model.sigma() + + "\n expected: " + 0.0 + + "\n tolerance: " + tolerance); } - if (Math.Abs(model.kappa() *(model.theta()-volatility*volatility)) > tolerance) + if (Math.Abs(model.kappa() * (model.theta() - volatility * volatility)) > tolerance) { QAssert.Fail("Failed to reproduce expected theta" - + "\n calculated: " + model.theta() - + "\n expected: " + volatility*volatility); + + "\n calculated: " + model.theta() + + "\n expected: " + volatility * volatility); } - if (Math.Abs(model.v0()-volatility*volatility) > tolerance) + if (Math.Abs(model.v0() - volatility * volatility) > tolerance) { QAssert.Fail("Failed to reproduce expected v0" - + "\n calculated: " + model.v0() - + "\n expected: " + volatility*volatility); + + "\n calculated: " + model.v0() + + "\n expected: " + volatility * volatility); } } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testDAXCalibration() { @@ -252,21 +255,21 @@ public void testDAXCalibration() for (int i = 0; i < options.Count; ++i) options[i].setPricingEngine(engine); - LevenbergMarquardt om = new LevenbergMarquardt(1e-8,1e-8,1e-8); + LevenbergMarquardt om = new LevenbergMarquardt(1e-8, 1e-8, 1e-8); model.calibrate(options, om, new EndCriteria(400, 40, 1.0e-8, 1.0e-8, 1.0e-8)); double sse = 0; - for (int i = 0; i < 13*8; ++i) + for (int i = 0; i < 13 * 8; ++i) { - double diff = options[i].calibrationError()*100.0; - sse += diff*diff; + double diff = options[i].calibrationError() * 100.0; + sse += diff * diff; } double expected = 177.2; //see article by A. Sepp. if (Math.Abs(sse - expected) > 1.0) { QAssert.Fail("Failed to reproduce calibration error" - + "\n calculated: " + sse - + "\n expected: " + expected); + + "\n calculated: " + sse + + "\n expected: " + expected); } } } @@ -339,9 +342,9 @@ public void testAnalyticVsBlack() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testAnalyticVsCached() { @@ -349,10 +352,10 @@ public void testAnalyticVsCached() using (SavedSettings backup = new SavedSettings()) { - Date settlementDate = new Date(27,Month.December,2004); + Date settlementDate = new Date(27, Month.December, 2004); Settings.setEvaluationDate(settlementDate); DayCounter dayCounter = new ActualActual(); - Date exerciseDate = new Date(28,Month.March,2005); + Date exerciseDate = new Date(28, Month.March, 2005); StrikedTypePayoff payoff = new PlainVanillaPayoff(Option.Type.Call, 1.05); Exercise exercise = new EuropeanExercise(exerciseDate); @@ -382,8 +385,8 @@ public void testAnalyticVsCached() if (Math.Abs(calculated1 - expected1) > tolerance) { QAssert.Fail("Failed to reproduce cached analytic price" - + "\n calculated: " + calculated1 - + "\n expected: " + expected1); + + "\n calculated: " + calculated1 + + "\n expected: " + expected1); } // reference values from www.wilmott.com, technical forum @@ -396,15 +399,15 @@ public void testAnalyticVsCached() int i; for (i = 0; i < 6; ++i) { - Date exerciseDate2 = new Date(8 + i/3,Month.September,2005); + Date exerciseDate2 = new Date(8 + i / 3, Month.September, 2005); - StrikedTypePayoff payoff2 = new PlainVanillaPayoff(Option.Type.Call, K[i%3]); + StrikedTypePayoff payoff2 = new PlainVanillaPayoff(Option.Type.Call, K[i % 3]); Exercise exercise2 = new EuropeanExercise(exerciseDate2); Handle riskFreeTS2 = new Handle(Utilities.flatRate(0.05, dayCounter)); Handle dividendTS2 = new Handle(Utilities.flatRate(0.02, dayCounter)); - double s = riskFreeTS2.link.discount(0.7)/dividendTS2.link.discount(0.7); + double s = riskFreeTS2.link.discount(0.7) / dividendTS2.link.discount(0.7); Handle s02 = new Handle(new SimpleQuote(s)); HestonProcess process2 = new HestonProcess(riskFreeTS2, dividendTS2, s02, 0.09, 1.2, 0.08, 1.8, -0.45); @@ -423,33 +426,33 @@ public void testAnalyticVsCached() for (i = 0; i < 3; ++i) { - double interpolated = calculated2[i] + (calculated2[i + 3] - calculated2[i])/(t2 - t1)*(0.7 - t1); + double interpolated = calculated2[i] + (calculated2[i + 3] - calculated2[i]) / (t2 - t1) * (0.7 - t1); - if (Math.Abs(interpolated - expected2[i]) > 100*tolerance) + if (Math.Abs(interpolated - expected2[i]) > 100 * tolerance) { QAssert.Fail("Failed to reproduce cached analytic prices:" - + "\n calculated: " + interpolated - + "\n expected: " + expected2[i]); + + "\n calculated: " + interpolated + + "\n expected: " + expected2[i]); } } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testMcVsCached() { // Testing Monte Carlo Heston engine against cached values using (SavedSettings backup = new SavedSettings()) { - Date settlementDate = new Date(27,Month.December,2004); + Date settlementDate = new Date(27, Month.December, 2004); Settings.setEvaluationDate(settlementDate); DayCounter dayCounter = new ActualActual(); - Date exerciseDate = new Date(28,Month.March,2005); + Date exerciseDate = new Date(28, Month.March, 2005); StrikedTypePayoff payoff = new PlainVanillaPayoff(Option.Type.Put, 1.05); Exercise exercise = new EuropeanExercise(exerciseDate); @@ -463,11 +466,11 @@ public void testMcVsCached() VanillaOption option = new VanillaOption(payoff, exercise); - IPricingEngine engine = new MakeMCEuropeanHestonEngine( process ) - .withStepsPerYear(11) - .withAntitheticVariate() - .withSamples(50000) - .withSeed(1234).getAsPricingEngine(); + IPricingEngine engine = new MakeMCEuropeanHestonEngine(process) + .withStepsPerYear(11) + .withAntitheticVariate() + .withSamples(50000) + .withSeed(1234).getAsPricingEngine(); option.setPricingEngine(engine); @@ -476,19 +479,19 @@ public void testMcVsCached() double errorEstimate = option.errorEstimate(); double tolerance = 7.5e-4; - if (Math.Abs(calculated - expected) > 2.34*errorEstimate) + if (Math.Abs(calculated - expected) > 2.34 * errorEstimate) { QAssert.Fail("Failed to reproduce cached price" - + "\n calculated: " + calculated - + "\n expected: " + expected - + " +/- " + errorEstimate); + + "\n calculated: " + calculated + + "\n expected: " + expected + + " +/- " + errorEstimate); } if (errorEstimate > tolerance) { QAssert.Fail("failed to reproduce error estimate" - + "\n calculated: " + errorEstimate - + "\n expected: " + tolerance); + + "\n calculated: " + errorEstimate + + "\n expected: " + tolerance); } } } @@ -496,168 +499,168 @@ public void testMcVsCached() //[TestMethod()] public void testFdBarrierVsCached() { - // // Testing FD barrier Heston engine against cached values - - // using (SavedSettings backup = new SavedSettings()) - // { - - // DayCounter dc = new Actual360(); - // Date today = Date.Today; - - // Handle s0 = new Handle(new SimpleQuote(100.0)); - // Handle rTS = new Handle(Utilities.flatRate(today, 0.08, dc)); - // Handle qTS = new Handle(Utilities.flatRate(today, 0.04, dc)); - - // Date exDate = today + (int)(0.5*360 + 0.5); - // Exercise exercise = new EuropeanExercise(exDate); - - // StrikedTypePayoff payoff = new PlainVanillaPayoff(Option.Type.Call, 90.0); - - // HestonProcess process = new HestonProcess(rTS, qTS, s0, 0.25*0.25, 1.0, 0.25*0.25, 0.001, 0.0); - - // IPricingEngine engine = new FdHestonBarrierEngine(new HestonModel(process),200, 400, 100); - - // BarrierOption option = new BarrierOption(Barrier.Type.DownOut,95.0,3.0,payoff,exercise); - // option.setPricingEngine(engine); - - // double calculated = option.NPV(); - // double expected = 9.0246; - // double error = Math.Abs(calculated - expected); - // if (error > 1.0e-3) - // { - // QAssert.Fail("failed to reproduce cached price with FD Barrier engine" - // + "\n calculated: " + calculated - // + "\n expected: " + expected - // + "\n error: " + error); - // } - - // option = new BarrierOption(Barrier.Type.DownIn, 95.0, 3.0, payoff, exercise); - // option.setPricingEngine(engine); - - // calculated = option.NPV(); - // expected = 7.7627; - // error = Math.Abs(calculated - expected); - // if (error > 1.0e-3) - // { - // QAssert.Fail("failed to reproduce cached price with FD Barrier engine" - // + "\n calculated: " + calculated - // + "\n expected: " + expected - // + "\n error: " + error); - // } - //} + // // Testing FD barrier Heston engine against cached values + + // using (SavedSettings backup = new SavedSettings()) + // { + + // DayCounter dc = new Actual360(); + // Date today = Date.Today; + + // Handle s0 = new Handle(new SimpleQuote(100.0)); + // Handle rTS = new Handle(Utilities.flatRate(today, 0.08, dc)); + // Handle qTS = new Handle(Utilities.flatRate(today, 0.04, dc)); + + // Date exDate = today + (int)(0.5*360 + 0.5); + // Exercise exercise = new EuropeanExercise(exDate); + + // StrikedTypePayoff payoff = new PlainVanillaPayoff(Option.Type.Call, 90.0); + + // HestonProcess process = new HestonProcess(rTS, qTS, s0, 0.25*0.25, 1.0, 0.25*0.25, 0.001, 0.0); + + // IPricingEngine engine = new FdHestonBarrierEngine(new HestonModel(process),200, 400, 100); + + // BarrierOption option = new BarrierOption(Barrier.Type.DownOut,95.0,3.0,payoff,exercise); + // option.setPricingEngine(engine); + + // double calculated = option.NPV(); + // double expected = 9.0246; + // double error = Math.Abs(calculated - expected); + // if (error > 1.0e-3) + // { + // QAssert.Fail("failed to reproduce cached price with FD Barrier engine" + // + "\n calculated: " + calculated + // + "\n expected: " + expected + // + "\n error: " + error); + // } + + // option = new BarrierOption(Barrier.Type.DownIn, 95.0, 3.0, payoff, exercise); + // option.setPricingEngine(engine); + + // calculated = option.NPV(); + // expected = 7.7627; + // error = Math.Abs(calculated - expected); + // if (error > 1.0e-3) + // { + // QAssert.Fail("failed to reproduce cached price with FD Barrier engine" + // + "\n calculated: " + calculated + // + "\n expected: " + expected + // + "\n error: " + error); + // } + //} } //[TestMethod()] public void testFdVanillaVsCached() { - // // Testing FD vanilla Heston engine against cached values - - // using (SavedSettings backup = new SavedSettings()) - //{ - - // Date settlementDate = new Date(27,Month.December,2004); - // Settings.setEvaluationDate(settlementDate); - - // DayCounter dayCounter = new ActualActual(); - // Date exerciseDate = new Date(28,Month.March,2005); - - // StrikedTypePayoff payoff = new PlainVanillaPayoff(Option.Type.Put, 1.05); - // Exercise exercise = new EuropeanExercise(exerciseDate); - - // Handle riskFreeTS = new Handle(Utilities.flatRate(0.7, dayCounter)); - // Handle dividendTS = new Handle(Utilities.flatRate(0.4, dayCounter)); - - // Handle s0 = new Handle(new SimpleQuote(1.05)); - - // VanillaOption option = new VanillaOption(payoff, exercise); - - // HestonProcess process = new HestonProcess(riskFreeTS, dividendTS, s0, 0.3, 1.16, 0.2, 0.8, 0.8); - - // IPricingEngine engine = new FdHestonVanillaEngine(new HestonModel(process),100, 200, 100); - // option.setPricingEngine(engine); - - // double expected = 0.06325; - // double calculated = option.NPV(); - // double error = Math.Abs(calculated - expected); - // double tolerance = 1.0e-4; - - // if (error > tolerance) - // { - // QAssert.Fail("failed to reproduce cached price with FD engine" - // + "\n calculated: " + calculated - // + "\n expected: " + expected - // + "\n error: " + error); - // } - - // // Testing FD vanilla Heston engine for discrete dividends - - // payoff = new PlainVanillaPayoff(Option.Type.Call, 95.0); - // s0 = new Handle(new SimpleQuote(100.0)); - - // riskFreeTS = new Handle(Utilities.flatRate(0.05, dayCounter)); - // dividendTS = new Handle(Utilities.flatRate(0.0, dayCounter)); - - // exerciseDate = new Date(28, Month.March, 2006); - // exercise = new EuropeanExercise(exerciseDate); - - // List dividendDates = new List(); - // List dividends = new List(); - // for (Date d = settlementDate + new Period(3,TimeUnit.Months); - // d < exercise.lastDate(); - // d += new Period(6,TimeUnit.Months)) - // { - // dividendDates.Add(d); - // dividends.Add(1.0); - // } - - // DividendVanillaOption divOption = new DividendVanillaOption(payoff, exercise,dividendDates, dividends); - // process = new HestonProcess(riskFreeTS, dividendTS, s0, 0.04, 1.0, 0.04, 0.001, 0.0); - // engine = new FdHestonVanillaEngine(new HestonModel(process),200, 400, 100); - // divOption.setPricingEngine(engine); - // calculated = divOption.NPV(); - // // Value calculated with an independent FD framework, validated with - // // an independent MC framework - // expected = 12.946; - // error = Math.Abs(calculated - expected); - // tolerance = 5.0e-3; - - // if (error > tolerance) - // { - // QAssert.Fail("failed to reproduce discrete dividend price with FD engine" - // + "\n calculated: " + calculated - // + "\n expected: " + expected - // + "\n error: " + error); - // } - - // // Testing FD vanilla Heston engine for american exercise - - // dividendTS = new Handle(Utilities.flatRate(0.03, dayCounter)); - // process = new HestonProcess(riskFreeTS, dividendTS, s0, 0.04, 1.0, 0.04, 0.001, 0.0); - // engine = new FdHestonVanillaEngine(new HestonModel(process),200, 400, 100); - // payoff = new PlainVanillaPayoff(Option.Type.Put, 95.0); - // exercise = new AmericanExercise(settlementDate, exerciseDate); - // option = new VanillaOption(payoff, exercise); - // option.setPricingEngine(engine); - // calculated = option.NPV(); - - // Handle volTS = new Handle(Utilities.flatVol(settlementDate, 0.2, - // dayCounter)); - // BlackScholesMertonProcess ref_process = new BlackScholesMertonProcess(s0, dividendTS, riskFreeTS, volTS); - // IPricingEngine ref_engine = new FDAmericanEngine(ref_process, 200, 400); - // option.setPricingEngine(ref_engine); - // expected = option.NPV(); - - // error = Math.Abs(calculated - expected); - // tolerance = 1.0e-3; - - // if (error > tolerance) - // { - // QAssert.Fail("failed to reproduce american option price with FD engine" - // + "\n calculated: " + calculated - // + "\n expected: " + expected - // + "\n error: " + error); - // } - //} + // // Testing FD vanilla Heston engine against cached values + + // using (SavedSettings backup = new SavedSettings()) + //{ + + // Date settlementDate = new Date(27,Month.December,2004); + // Settings.setEvaluationDate(settlementDate); + + // DayCounter dayCounter = new ActualActual(); + // Date exerciseDate = new Date(28,Month.March,2005); + + // StrikedTypePayoff payoff = new PlainVanillaPayoff(Option.Type.Put, 1.05); + // Exercise exercise = new EuropeanExercise(exerciseDate); + + // Handle riskFreeTS = new Handle(Utilities.flatRate(0.7, dayCounter)); + // Handle dividendTS = new Handle(Utilities.flatRate(0.4, dayCounter)); + + // Handle s0 = new Handle(new SimpleQuote(1.05)); + + // VanillaOption option = new VanillaOption(payoff, exercise); + + // HestonProcess process = new HestonProcess(riskFreeTS, dividendTS, s0, 0.3, 1.16, 0.2, 0.8, 0.8); + + // IPricingEngine engine = new FdHestonVanillaEngine(new HestonModel(process),100, 200, 100); + // option.setPricingEngine(engine); + + // double expected = 0.06325; + // double calculated = option.NPV(); + // double error = Math.Abs(calculated - expected); + // double tolerance = 1.0e-4; + + // if (error > tolerance) + // { + // QAssert.Fail("failed to reproduce cached price with FD engine" + // + "\n calculated: " + calculated + // + "\n expected: " + expected + // + "\n error: " + error); + // } + + // // Testing FD vanilla Heston engine for discrete dividends + + // payoff = new PlainVanillaPayoff(Option.Type.Call, 95.0); + // s0 = new Handle(new SimpleQuote(100.0)); + + // riskFreeTS = new Handle(Utilities.flatRate(0.05, dayCounter)); + // dividendTS = new Handle(Utilities.flatRate(0.0, dayCounter)); + + // exerciseDate = new Date(28, Month.March, 2006); + // exercise = new EuropeanExercise(exerciseDate); + + // List dividendDates = new List(); + // List dividends = new List(); + // for (Date d = settlementDate + new Period(3,TimeUnit.Months); + // d < exercise.lastDate(); + // d += new Period(6,TimeUnit.Months)) + // { + // dividendDates.Add(d); + // dividends.Add(1.0); + // } + + // DividendVanillaOption divOption = new DividendVanillaOption(payoff, exercise,dividendDates, dividends); + // process = new HestonProcess(riskFreeTS, dividendTS, s0, 0.04, 1.0, 0.04, 0.001, 0.0); + // engine = new FdHestonVanillaEngine(new HestonModel(process),200, 400, 100); + // divOption.setPricingEngine(engine); + // calculated = divOption.NPV(); + // // Value calculated with an independent FD framework, validated with + // // an independent MC framework + // expected = 12.946; + // error = Math.Abs(calculated - expected); + // tolerance = 5.0e-3; + + // if (error > tolerance) + // { + // QAssert.Fail("failed to reproduce discrete dividend price with FD engine" + // + "\n calculated: " + calculated + // + "\n expected: " + expected + // + "\n error: " + error); + // } + + // // Testing FD vanilla Heston engine for american exercise + + // dividendTS = new Handle(Utilities.flatRate(0.03, dayCounter)); + // process = new HestonProcess(riskFreeTS, dividendTS, s0, 0.04, 1.0, 0.04, 0.001, 0.0); + // engine = new FdHestonVanillaEngine(new HestonModel(process),200, 400, 100); + // payoff = new PlainVanillaPayoff(Option.Type.Put, 95.0); + // exercise = new AmericanExercise(settlementDate, exerciseDate); + // option = new VanillaOption(payoff, exercise); + // option.setPricingEngine(engine); + // calculated = option.NPV(); + + // Handle volTS = new Handle(Utilities.flatVol(settlementDate, 0.2, + // dayCounter)); + // BlackScholesMertonProcess ref_process = new BlackScholesMertonProcess(s0, dividendTS, riskFreeTS, volTS); + // IPricingEngine ref_engine = new FDAmericanEngine(ref_process, 200, 400); + // option.setPricingEngine(ref_engine); + // expected = option.NPV(); + + // error = Math.Abs(calculated - expected); + // tolerance = 1.0e-3; + + // if (error > tolerance) + // { + // QAssert.Fail("failed to reproduce american option price with FD engine" + // + "\n calculated: " + calculated + // + "\n expected: " + expected + // + "\n error: " + error); + // } + //} } // [TestMethod()] @@ -784,9 +787,9 @@ public HestonParameter(double _v0, double _kappa, double _theta, double _sigma, } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testDifferentIntegrals() { @@ -794,7 +797,7 @@ public void testDifferentIntegrals() using (SavedSettings backup = new SavedSettings()) { - Date settlementDate = new Date(27,Month.December,2004); + Date settlementDate = new Date(27, Month.December, 2004); Settings.setEvaluationDate(settlementDate); DayCounter dayCounter = new ActualActual(); @@ -802,15 +805,15 @@ public void testDifferentIntegrals() Handle riskFreeTS = new Handle(Utilities.flatRate(0.05, dayCounter)); Handle dividendTS = new Handle(Utilities.flatRate(0.03, dayCounter)); - double[] strikes = {0.5,0.7,1.0,1.25,1.5,2.0}; - int[] maturities = {1,2,3,12,60,120,360}; - Option.Type[] types = { Option.Type.Put,Option.Type.Call}; + double[] strikes = {0.5, 0.7, 1.0, 1.25, 1.5, 2.0}; + int[] maturities = {1, 2, 3, 12, 60, 120, 360}; + Option.Type[] types = { Option.Type.Put, Option.Type.Call}; - HestonParameter equityfx = new HestonParameter(0.07,2.0,0.04,0.55,-0.8); - HestonParameter highCorr = new HestonParameter(0.07,1.0,0.04,0.55,0.995); - HestonParameter lowVolOfVol = new HestonParameter(0.07,1.0,0.04,0.025,-0.75); - HestonParameter highVolOfVol = new HestonParameter(0.07,1.0,0.04,5.0,-0.75); - HestonParameter kappaEqSigRho = new HestonParameter(0.07,0.4,0.04,0.5,0.8); + HestonParameter equityfx = new HestonParameter(0.07, 2.0, 0.04, 0.55, -0.8); + HestonParameter highCorr = new HestonParameter(0.07, 1.0, 0.04, 0.55, 0.995); + HestonParameter lowVolOfVol = new HestonParameter(0.07, 1.0, 0.04, 0.025, -0.75); + HestonParameter highVolOfVol = new HestonParameter(0.07, 1.0, 0.04, 5.0, -0.75); + HestonParameter kappaEqSigRho = new HestonParameter(0.07, 0.4, 0.04, 0.5, 0.8); List parameters = new List(); parameters.Add(equityfx); @@ -819,24 +822,24 @@ public void testDifferentIntegrals() parameters.Add(highVolOfVol); parameters.Add(kappaEqSigRho); - double[] tol = {1e-3,1e-3,0.2,0.01,1e-3}; + double[] tol = {1e-3, 1e-3, 0.2, 0.01, 1e-3}; int count = 0; foreach (var iter in parameters) { Handle s0 = new Handle(new SimpleQuote(1.0)); - HestonProcess process = new HestonProcess(riskFreeTS, dividendTS,s0, iter.v0, iter.kappa, - iter.theta, iter.sigma, iter.rho); + HestonProcess process = new HestonProcess(riskFreeTS, dividendTS, s0, iter.v0, iter.kappa, + iter.theta, iter.sigma, iter.rho); HestonModel model = new HestonModel(process); - AnalyticHestonEngine lobattoEngine = new AnalyticHestonEngine(model, 1e-10,1000000); + AnalyticHestonEngine lobattoEngine = new AnalyticHestonEngine(model, 1e-10, 1000000); AnalyticHestonEngine laguerreEngine = new AnalyticHestonEngine(model, 128); AnalyticHestonEngine legendreEngine = new AnalyticHestonEngine(model, - AnalyticHestonEngine.ComplexLogFormula.Gatheral, AnalyticHestonEngine.Integration.gaussLegendre(512)); + AnalyticHestonEngine.ComplexLogFormula.Gatheral, AnalyticHestonEngine.Integration.gaussLegendre(512)); AnalyticHestonEngine chebyshevEngine = new AnalyticHestonEngine(model, - AnalyticHestonEngine.ComplexLogFormula.Gatheral,AnalyticHestonEngine.Integration.gaussChebyshev(512)); + AnalyticHestonEngine.ComplexLogFormula.Gatheral, AnalyticHestonEngine.Integration.gaussChebyshev(512)); AnalyticHestonEngine chebyshev2ndEngine = new AnalyticHestonEngine(model, - AnalyticHestonEngine.ComplexLogFormula.Gatheral,AnalyticHestonEngine.Integration.gaussChebyshev2nd(512)); + AnalyticHestonEngine.ComplexLogFormula.Gatheral, AnalyticHestonEngine.Integration.gaussChebyshev2nd(512)); double maxLegendreDiff = 0.0; double maxChebyshevDiff = 0.0; @@ -871,20 +874,20 @@ public void testDifferentIntegrals() maxLaguerreDiff = Math.Max(maxLaguerreDiff, Math.Abs(lobattoNPV - laguerre)); maxLegendreDiff = Math.Max(maxLegendreDiff, Math.Abs(lobattoNPV - legendre)); - maxChebyshevDiff = Math.Max(maxChebyshevDiff,Math.Abs(lobattoNPV - chebyshev)); - maxChebyshev2ndDiff = Math.Max(maxChebyshev2ndDiff,Math.Abs(lobattoNPV - chebyshev2nd)); + maxChebyshevDiff = Math.Max(maxChebyshevDiff, Math.Abs(lobattoNPV - chebyshev)); + maxChebyshev2ndDiff = Math.Max(maxChebyshev2ndDiff, Math.Abs(lobattoNPV - chebyshev2nd)); } } } - double maxDiff = Math.Max(Math.Max(Math.Max(maxLaguerreDiff, maxLegendreDiff),maxChebyshevDiff), - maxChebyshev2ndDiff); + double maxDiff = Math.Max(Math.Max(Math.Max(maxLaguerreDiff, maxLegendreDiff), maxChebyshevDiff), + maxChebyshev2ndDiff); double tr = tol[count++]; if (maxDiff > tr) { QAssert.Fail("Failed to reproduce Heston pricing values within given tolerance" - + "\n maxDifference: " + maxDiff - + "\n tolerance: " + tr); + + "\n maxDifference: " + maxDiff + + "\n tolerance: " + tr); } } } @@ -977,9 +980,9 @@ public void testMultipleStrikesEngine() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testAnalyticPiecewiseTimeDependent() { @@ -987,10 +990,10 @@ public void testAnalyticPiecewiseTimeDependent() using (SavedSettings backup = new SavedSettings()) { - Date settlementDate = new Date(27,Month.December,2004); + Date settlementDate = new Date(27, Month.December, 2004); Settings.setEvaluationDate(settlementDate); DayCounter dayCounter = new ActualActual(); - Date exerciseDate = new Date(28,Month.March,2005); + Date exerciseDate = new Date(28, Month.March, 2005); StrikedTypePayoff payoff = new PlainVanillaPayoff(Option.Type.Call, 1.0); Exercise exercise = new EuropeanExercise(exerciseDate); @@ -1002,32 +1005,32 @@ public void testAnalyticPiecewiseTimeDependent() irates.Add(0.0); irates.Add(0.2); Handle riskFreeTS = new Handle( - new InterpolatedZeroCurve( dates, irates, dayCounter ) ); + new InterpolatedZeroCurve(dates, irates, dayCounter)); List qrates = new List(); qrates.Add(0.0); qrates.Add(0.3); Handle dividendTS = new Handle( - new InterpolatedZeroCurve( dates, qrates, dayCounter ) ); + new InterpolatedZeroCurve(dates, qrates, dayCounter)); double v0 = 0.1; Handle s0 = new Handle(new SimpleQuote(1.0)); - ConstantParameter theta = new ConstantParameter(0.09,new PositiveConstraint()); - ConstantParameter kappa = new ConstantParameter(3.16,new PositiveConstraint()); - ConstantParameter sigma = new ConstantParameter(4.40,new PositiveConstraint()); - ConstantParameter rho = new ConstantParameter(-0.8,new BoundaryConstraint(-1.0, 1.0)); + ConstantParameter theta = new ConstantParameter(0.09, new PositiveConstraint()); + ConstantParameter kappa = new ConstantParameter(3.16, new PositiveConstraint()); + ConstantParameter sigma = new ConstantParameter(4.40, new PositiveConstraint()); + ConstantParameter rho = new ConstantParameter(-0.8, new BoundaryConstraint(-1.0, 1.0)); PiecewiseTimeDependentHestonModel model = new PiecewiseTimeDependentHestonModel(riskFreeTS, dividendTS, - s0, v0, theta, kappa,sigma, rho, new TimeGrid(20.0, 2)); + s0, v0, theta, kappa, sigma, rho, new TimeGrid(20.0, 2)); VanillaOption option = new VanillaOption(payoff, exercise); option.setPricingEngine(new AnalyticPTDHestonEngine(model)); double calculated = option.NPV(); HestonProcess hestonProcess = new HestonProcess(riskFreeTS, dividendTS, s0, v0, - kappa.value(0.0), theta.value(0.0), sigma.value(0.0), rho.value(0.0)); + kappa.value(0.0), theta.value(0.0), sigma.value(0.0), rho.value(0.0)); HestonModel hestonModel = new HestonModel(hestonProcess); option.setPricingEngine(new AnalyticHestonEngine(hestonModel)); @@ -1036,16 +1039,16 @@ public void testAnalyticPiecewiseTimeDependent() if (Math.Abs(calculated - expected) > 1e-12) { QAssert.Fail("failed to reproduce heston prices " - + "\n calculated: " + calculated - + "\n expected: " + expected); + + "\n calculated: " + calculated + + "\n expected: " + expected); } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testDAXCalibrationOfTimeDependentModel() { @@ -1053,7 +1056,7 @@ public void testDAXCalibrationOfTimeDependentModel() using (SavedSettings backup = new SavedSettings()) { - Date settlementDate = new Date(5,Month.July,2002); + Date settlementDate = new Date(5, Month.July, 2002); Settings.setEvaluationDate(settlementDate); CalibrationMarketData marketData = getDAXCalibrationMarketData(); @@ -1067,15 +1070,15 @@ public void testDAXCalibrationOfTimeDependentModel() List modelTimes = new List(); modelTimes.Add(0.25); modelTimes.Add(10.0); - TimeGrid modelGrid = new TimeGrid(modelTimes,modelTimes.Count); + TimeGrid modelGrid = new TimeGrid(modelTimes, modelTimes.Count); double v0 = 0.1; - ConstantParameter sigma = new ConstantParameter(0.5,new PositiveConstraint()); - ConstantParameter theta = new ConstantParameter(0.1,new PositiveConstraint()); - ConstantParameter rho = new ConstantParameter(-0.5,new BoundaryConstraint(-1.0, 1.0)); + ConstantParameter sigma = new ConstantParameter(0.5, new PositiveConstraint()); + ConstantParameter theta = new ConstantParameter(0.1, new PositiveConstraint()); + ConstantParameter rho = new ConstantParameter(-0.5, new BoundaryConstraint(-1.0, 1.0)); - List pTimes = new InitializedList(1,0.25); - PiecewiseConstantParameter kappa = new PiecewiseConstantParameter(pTimes, new PositiveConstraint ()); + List pTimes = new InitializedList(1, 0.25); + PiecewiseConstantParameter kappa = new PiecewiseConstantParameter(pTimes, new PositiveConstraint()); for (int i = 0; i < pTimes.Count + 1; ++i) { @@ -1083,36 +1086,36 @@ public void testDAXCalibrationOfTimeDependentModel() } PiecewiseTimeDependentHestonModel model = new PiecewiseTimeDependentHestonModel(riskFreeTS, dividendTS, - s0, v0, theta, kappa,sigma, rho, modelGrid); + s0, v0, theta, kappa, sigma, rho, modelGrid); IPricingEngine engine = new AnalyticPTDHestonEngine(model); for (int i = 0; i < options.Count; ++i) options[i].setPricingEngine(engine); - LevenbergMarquardt om = new LevenbergMarquardt(1e-8,1e-8,1e-8); + LevenbergMarquardt om = new LevenbergMarquardt(1e-8, 1e-8, 1e-8); model.calibrate(options, om, new EndCriteria(400, 40, 1.0e-8, 1.0e-8, 1.0e-8)); double sse = 0; - for (int i = 0; i < 13*8; ++i) + for (int i = 0; i < 13 * 8; ++i) { - double diff = options[i].calibrationError()*100.0; - sse += diff*diff; + double diff = options[i].calibrationError() * 100.0; + sse += diff * diff; } double expected = 74.4; if (Math.Abs(sse - expected) > 1.0) { QAssert.Fail("Failed to reproduce calibration error" - + "\n calculated: " + sse - + "\n expected: " + expected); + + "\n calculated: " + sse + + "\n expected: " + expected); } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testAlanLewisReferencePrices() { @@ -1125,10 +1128,10 @@ public void testAlanLewisReferencePrices() using (SavedSettings backup = new SavedSettings()) { - Date settlementDate = new Date(5,Month.July,2002); + Date settlementDate = new Date(5, Month.July, 2002); Settings.setEvaluationDate(settlementDate); - Date maturityDate = new Date(5,Month.July,2003); + Date maturityDate = new Date(5, Month.July, 2003); Exercise exercise = new EuropeanExercise(maturityDate); DayCounter dayCounter = new Actual365Fixed(); @@ -1146,26 +1149,36 @@ public void testAlanLewisReferencePrices() HestonProcess process = new HestonProcess(riskFreeTS, dividendTS, s0, v0, kappa, theta, sigma, rho); HestonModel model = new HestonModel(process); - IPricingEngine laguerreEngine= new AnalyticHestonEngine(model, 128); + IPricingEngine laguerreEngine = new AnalyticHestonEngine(model, 128); IPricingEngine gaussLobattoEngine = new AnalyticHestonEngine(model, Const.QL_EPSILON, 100000); - double[] strikes = {80,90,100,110,120}; - Option.Type[] types = {Option.Type.Put,Option.Type.Call}; - IPricingEngine[] engines = {laguerreEngine,gaussLobattoEngine}; + double[] strikes = {80, 90, 100, 110, 120}; + Option.Type[] types = {Option.Type.Put, Option.Type.Call}; + IPricingEngine[] engines = {laguerreEngine, gaussLobattoEngine}; double[][] expectedResults = { - new double[2]{ 7.958878113256768285213263077598987193482161301733, - 26.774758743998854221382195325726949201687074848341}, - new double[2]{ 12.017966707346304987709573290236471654992071308187, - 20.933349000596710388139445766564068085476194042256}, - new double[2]{ 17.055270961270109413522653999411000974895436309183, - 16.070154917028834278213466703938231827658768230714}, - new double[2]{ 23.017825898442800538908781834822560777763225722188, - 12.132211516709844867860534767549426052805766831181}, - new double[2]{ 29.811026202682471843340682293165857439167301370697, - 9.024913483457835636553375454092357136489051667150} + new double[2]{ + 7.958878113256768285213263077598987193482161301733, + 26.774758743998854221382195325726949201687074848341 + }, + new double[2]{ + 12.017966707346304987709573290236471654992071308187, + 20.933349000596710388139445766564068085476194042256 + }, + new double[2]{ + 17.055270961270109413522653999411000974895436309183, + 16.070154917028834278213466703938231827658768230714 + }, + new double[2]{ + 23.017825898442800538908781834822560777763225722188, + 12.132211516709844867860534767549426052805766831181 + }, + new double[2]{ + 29.811026202682471843340682293165857439167301370697, + 9.024913483457835636553375454092357136489051667150 + } }; double tol = 1e-12; // 3e-15 works on linux/ia32, @@ -1190,15 +1203,15 @@ public void testAlanLewisReferencePrices() double expected = expectedResults[i][j]; double calculated = option.NPV(); - double relError = Math.Abs(calculated - expected)/expected; + double relError = Math.Abs(calculated - expected) / expected; if (relError > tol) { QAssert.Fail("failed to reproduce Alan Lewis Reference prices " - + "\n strike : " + strike - + "\n option type: " + type - + "\n engine type: " + k - + "\n rel. error : " + relError); + + "\n strike : " + strike + + "\n option type: " + type + + "\n engine type: " + k + + "\n rel. error : " + relError); } } } @@ -1207,20 +1220,20 @@ public void testAlanLewisReferencePrices() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testExpansionOnAlanLewisReference() { - // Testing expansion on Alan Lewis reference prices + // Testing expansion on Alan Lewis reference prices using (SavedSettings backup = new SavedSettings()) { - Date settlementDate = new Date(5,Month.July,2002); + Date settlementDate = new Date(5, Month.July, 2002); Settings.setEvaluationDate(settlementDate); - Date maturityDate = new Date(5,Month.July,2003); + Date maturityDate = new Date(5, Month.July, 2003); Exercise exercise = new EuropeanExercise(maturityDate); DayCounter dayCounter = new Actual365Fixed(); @@ -1235,32 +1248,42 @@ public void testExpansionOnAlanLewisReference() double kappa = 4.0; double theta = 0.25; - HestonProcess process = new HestonProcess(riskFreeTS, dividendTS, s0, v0,kappa, theta, sigma, rho); + HestonProcess process = new HestonProcess(riskFreeTS, dividendTS, s0, v0, kappa, theta, sigma, rho); HestonModel model = new HestonModel(process); - IPricingEngine lpp2Engine = new HestonExpansionEngine(model,HestonExpansionEngine.HestonExpansionFormula.LPP2); + IPricingEngine lpp2Engine = new HestonExpansionEngine(model, HestonExpansionEngine.HestonExpansionFormula.LPP2); //don't test Forde as it does not behave well on this example - IPricingEngine lpp3Engine = new HestonExpansionEngine(model,HestonExpansionEngine.HestonExpansionFormula.LPP3); + IPricingEngine lpp3Engine = new HestonExpansionEngine(model, HestonExpansionEngine.HestonExpansionFormula.LPP3); - double[] strikes = {80,90,100,110,120}; - Option.Type[] types = {Option.Type.Put,Option.Type.Call}; - IPricingEngine[] engines = {lpp2Engine,lpp3Engine}; + double[] strikes = {80, 90, 100, 110, 120}; + Option.Type[] types = {Option.Type.Put, Option.Type.Call}; + IPricingEngine[] engines = {lpp2Engine, lpp3Engine}; double[][] expectedResults = { - new double[2] { 7.958878113256768285213263077598987193482161301733, - 26.774758743998854221382195325726949201687074848341}, - new double[2] { 12.017966707346304987709573290236471654992071308187, - 20.933349000596710388139445766564068085476194042256}, - new double[2] { 17.055270961270109413522653999411000974895436309183, - 16.070154917028834278213466703938231827658768230714}, - new double[2] { 23.017825898442800538908781834822560777763225722188, - 12.132211516709844867860534767549426052805766831181}, - new double[2] { 29.811026202682471843340682293165857439167301370697, - 9.024913483457835636553375454092357136489051667150} + new double[2] { + 7.958878113256768285213263077598987193482161301733, + 26.774758743998854221382195325726949201687074848341 + }, + new double[2] { + 12.017966707346304987709573290236471654992071308187, + 20.933349000596710388139445766564068085476194042256 + }, + new double[2] { + 17.055270961270109413522653999411000974895436309183, + 16.070154917028834278213466703938231827658768230714 + }, + new double[2] { + 23.017825898442800538908781834822560777763225722188, + 12.132211516709844867860534767549426052805766831181 + }, + new double[2] { + 29.811026202682471843340682293165857439167301370697, + 9.024913483457835636553375454092357136489051667150 + } }; - double[] tol = {1.003e-2,3.645e-3}; + double[] tol = {1.003e-2, 3.645e-3}; for (int i = 0; i < strikes.Length; ++i) { @@ -1281,15 +1304,15 @@ public void testExpansionOnAlanLewisReference() double expected = expectedResults[i][j]; double calculated = option.NPV(); - double relError = Math.Abs(calculated - expected)/expected; + double relError = Math.Abs(calculated - expected) / expected; if (relError > tol[k]) { - QAssert.Fail( "failed to reproduce Alan Lewis Reference prices " - + "\n strike : " + strike - + "\n option type: " + type - + "\n engine type: " + k - + "\n rel. error : " + relError); + QAssert.Fail("failed to reproduce Alan Lewis Reference prices " + + "\n strike : " + strike + + "\n option type: " + type + + "\n engine type: " + k + + "\n rel. error : " + relError); } } } @@ -1298,9 +1321,9 @@ public void testExpansionOnAlanLewisReference() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testExpansionOnFordeReference() { @@ -1315,80 +1338,100 @@ public void testExpansionOnFordeReference() double kappa = 1.15; double theta = 0.04; - double[] terms = {0.1,1.0,5.0,10.0}; - double[] strikes = {60,80,90,100,110,120,140}; + double[] terms = {0.1, 1.0, 5.0, 10.0}; + double[] strikes = {60, 80, 90, 100, 110, 120, 140}; double[][] referenceVols = { - new double[7] { 0.27284673574924445, - 0.22360758200372477, - 0.21023988547031242, - 0.1990674789471587, - 0.19118230678920461, - 0.18721342919371017, - 0.1899869903378507 }, - new double[7] { 0.25200775151345, - 0.2127275920953156, - 0.20286528150874591, - 0.19479398358151515, - 0.18872591728967686, - 0.18470857955411824, - 0.18204457060905446 }, - new double[7] { 0.21637821506229973, - 0.20077227130455172, - 0.19721753043236154, - 0.1942233023784151, - 0.191693211401571, - 0.18955229722896752, - 0.18491727548069495 }, - new double[7] { 0.20672925973965342, - 0.198583062164427, - 0.19668274423922746, - 0.1950420231354201, - 0.193610364344706, - 0.1923502827886502, - 0.18934360917857015 } + new double[7] { + 0.27284673574924445, + 0.22360758200372477, + 0.21023988547031242, + 0.1990674789471587, + 0.19118230678920461, + 0.18721342919371017, + 0.1899869903378507 + }, + new double[7] { + 0.25200775151345, + 0.2127275920953156, + 0.20286528150874591, + 0.19479398358151515, + 0.18872591728967686, + 0.18470857955411824, + 0.18204457060905446 + }, + new double[7] { + 0.21637821506229973, + 0.20077227130455172, + 0.19721753043236154, + 0.1942233023784151, + 0.191693211401571, + 0.18955229722896752, + 0.18491727548069495 + }, + new double[7] { + 0.20672925973965342, + 0.198583062164427, + 0.19668274423922746, + 0.1950420231354201, + 0.193610364344706, + 0.1923502827886502, + 0.18934360917857015 + } }; double[][] tol = { - new double[4] { 0.06, - 0.03, - 0.03, - 0.02 }, - new double[4] { 0.15, - 0.08, - 0.04, - 0.02 }, - new double[4] { 0.06, - 0.08, - 1.0, - 1.0 } //forde breaks down for long maturities + new double[4] { + 0.06, + 0.03, + 0.03, + 0.02 + }, + new double[4] { + 0.15, + 0.08, + 0.04, + 0.02 + }, + new double[4] { + 0.06, + 0.08, + 1.0, + 1.0 + } //forde breaks down for long maturities }; double[][] tolAtm = { - new double[4] { 4e-6, - 7e-4, - 2e-3, - 9e-4 }, - new double[4] { 7e-6, - 4e-4, - 9e-4, - 4e-4 }, - new double[4] { 4e-4, - 3e-2, - 0.28, - 1.0 } + new double[4] { + 4e-6, + 7e-4, + 2e-3, + 9e-4 + }, + new double[4] { + 7e-6, + 4e-4, + 9e-4, + 4e-4 + }, + new double[4] { + 4e-4, + 3e-2, + 0.28, + 1.0 + } }; for (int j = 0; j < terms.Length; ++j) { double term = terms[j]; - HestonExpansion lpp2 = new LPP2HestonExpansion(kappa, theta, sigma,v0, rho, term); - HestonExpansion lpp3 = new LPP3HestonExpansion(kappa, theta, sigma,v0, rho, term); - HestonExpansion forde = new FordeHestonExpansion(kappa, theta, sigma,v0, rho, term); - HestonExpansion[] expansions = {lpp2,lpp3,forde}; + HestonExpansion lpp2 = new LPP2HestonExpansion(kappa, theta, sigma, v0, rho, term); + HestonExpansion lpp3 = new LPP3HestonExpansion(kappa, theta, sigma, v0, rho, term); + HestonExpansion forde = new FordeHestonExpansion(kappa, theta, sigma, v0, rho, term); + HestonExpansion[] expansions = {lpp2, lpp3, forde}; for (int i = 0; i < strikes.Length; ++i) { @@ -1399,14 +1442,14 @@ public void testExpansionOnFordeReference() double expected = referenceVols[j][i]; double calculated = expansion.impliedVolatility(strike, forward); - double relError = Math.Abs(calculated - expected)/expected; + double relError = Math.Abs(calculated - expected) / expected; double refTol = strike == forward ? tolAtm[k][j] : tol[k][j]; if (relError > refTol) { - QAssert.Fail( "failed to reproduce Forde reference vols " - + "\n strike : " + strike - + "\n expansion type: " + k - + "\n rel. error : " + relError); + QAssert.Fail("failed to reproduce Forde reference vols " + + "\n strike : " + strike + + "\n expansion type: " + k + + "\n rel. error : " + relError); } } } diff --git a/tests/QLNet.Tests/T_HybridHestonHullWhiteProcess.cs b/tests/QLNet.Tests/T_HybridHestonHullWhiteProcess.cs index 0b43f889e..1ffe7eb93 100644 --- a/tests/QLNet.Tests/T_HybridHestonHullWhiteProcess.cs +++ b/tests/QLNet.Tests/T_HybridHestonHullWhiteProcess.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,7 +19,7 @@ #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -32,20 +32,20 @@ public class T_HybridHestonHullWhiteProcess : IDisposable { #region Initialize&Cleanup private SavedSettings backup; - #if NET40 || NET45 +#if NET40 || NET45 [TestInitialize] public void testInitialize() { - #else +#else public T_HybridHestonHullWhiteProcess() { - #endif +#endif backup = new SavedSettings(); } - #if NET40 || NET45 +#if NET40 || NET45 [TestCleanup] - #endif +#endif public void testCleanup() { Dispose(); @@ -57,9 +57,9 @@ public void Dispose() #endregion #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testBsmHullWhiteEngine() { @@ -86,18 +86,18 @@ public void testBsmHullWhiteEngine() Exercise exercise = new EuropeanExercise(maturity); - double fwd = spot.link.value()*qTS.link.discount(maturity)/rTS.link.discount(maturity); + double fwd = spot.link.value() * qTS.link.discount(maturity) / rTS.link.discount(maturity); StrikedTypePayoff payoff = new PlainVanillaPayoff(Option.Type.Call, fwd); EuropeanOption option = new EuropeanOption(payoff, exercise); double tol = 1e-8; - double[] corr = {-0.75,-0.25,0.0,0.25,0.75}; - double[] expectedVol = {0.217064577,0.243995801,0.256402830,0.268236596,0.290461343}; + double[] corr = {-0.75, -0.25, 0.0, 0.25, 0.75}; + double[] expectedVol = {0.217064577, 0.243995801, 0.256402830, 0.268236596, 0.290461343}; for (int i = 0; i < corr.Length; ++i) { - IPricingEngine bsmhwEngine = new AnalyticBSMHullWhiteEngine(corr[i], stochProcess,hullWhiteModel); + IPricingEngine bsmhwEngine = new AnalyticBSMHullWhiteEngine(corr[i], stochProcess, hullWhiteModel); option.setPricingEngine(bsmhwEngine); double npv = option.NPV(); @@ -116,48 +116,48 @@ public void testBsmHullWhiteEngine() if (Math.Abs(impliedVol - expectedVol[i]) > tol) { QAssert.Fail("Failed to reproduce implied volatility" - + "\n calculated: " + impliedVol - + "\n expected : " + expectedVol[i]); + + "\n calculated: " + impliedVol + + "\n expected : " + expectedVol[i]); } - if (Math.Abs((comp.NPV() - npv)/npv) > tol) + if (Math.Abs((comp.NPV() - npv) / npv) > tol) { QAssert.Fail("Failed to reproduce NPV" - + "\n calculated: " + npv - + "\n expected : " + comp.NPV()); + + "\n calculated: " + npv + + "\n expected : " + comp.NPV()); } if (Math.Abs(comp.delta() - option.delta()) > tol) { QAssert.Fail("Failed to reproduce NPV" - + "\n calculated: " + npv - + "\n expected : " + comp.NPV()); + + "\n calculated: " + npv + + "\n expected : " + comp.NPV()); } - if (Math.Abs((comp.gamma() - option.gamma())/npv) > tol) + if (Math.Abs((comp.gamma() - option.gamma()) / npv) > tol) { QAssert.Fail("Failed to reproduce NPV" - + "\n calculated: " + npv - + "\n expected : " + comp.NPV()); + + "\n calculated: " + npv + + "\n expected : " + comp.NPV()); } - if (Math.Abs((comp.theta() - option.theta())/npv) > tol) + if (Math.Abs((comp.theta() - option.theta()) / npv) > tol) { QAssert.Fail("Failed to reproduce NPV" - + "\n calculated: " + npv - + "\n expected : " + comp.NPV()); + + "\n calculated: " + npv + + "\n expected : " + comp.NPV()); } - if (Math.Abs((comp.vega() - option.vega())/npv) > tol) + if (Math.Abs((comp.vega() - option.vega()) / npv) > tol) { QAssert.Fail("Failed to reproduce NPV" - + "\n calculated: " + npv - + "\n expected : " + comp.NPV()); + + "\n calculated: " + npv + + "\n expected : " + comp.NPV()); } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testCompareBsmHWandHestonHW() + public void testCompareBsmHWandHestonHW() { // Comparing European option pricing for a BSM process with one-factor Hull-White model DayCounter dc = new Actual365Fixed(); @@ -172,8 +172,8 @@ public void testCompareBsmHWandHestonHW() { dates.Add(today + new Period(i, TimeUnit.Years)); // FLOATING_POINT_EXCEPTION - rates.Add(0.01 + 0.0002*Math.Exp(Math.Sin(i/4.0))); - divRates.Add(0.02 + 0.0001*Math.Exp(Math.Sin(i/5.0))); + rates.Add(0.01 + 0.0002 * Math.Exp(Math.Sin(i / 4.0))); + divRates.Add(0.02 + 0.0001 * Math.Exp(Math.Sin(i / 5.0))); } Handle s0 = new Handle(new SimpleQuote(100)); @@ -188,7 +188,7 @@ public void testCompareBsmHWandHestonHW() BlackScholesMertonProcess bsmProcess = new BlackScholesMertonProcess(spot, qTS, rTS, volTS); HestonProcess hestonProcess = new HestonProcess(rTS, qTS, spot, - vol.value()*vol.value(), 1.0, vol.value()*vol.value(), 1e-4, 0.0); + vol.value()*vol.value(), 1.0, vol.value()*vol.value(), 1e-4, 0.0); HestonModel hestonModel = new HestonModel(hestonProcess); @@ -199,9 +199,9 @@ public void testCompareBsmHWandHestonHW() IPricingEngine hestonHwEngine = new AnalyticHestonHullWhiteEngine(hestonModel, hullWhiteModel, 128); double tol = 1e-5; - double[] strike = {0.25,0.5,0.75,0.8,0.9,1.0,1.1,1.2,1.5,2.0,4.0}; - int[] maturity = {1,2,3,5,10,15,20,25,30}; - Option.Type[] types = {Option.Type.Put,Option.Type.Call}; + double[] strike = {0.25, 0.5, 0.75, 0.8, 0.9, 1.0, 1.1, 1.2, 1.5, 2.0, 4.0}; + int[] maturity = {1, 2, 3, 5, 10, 15, 20, 25, 30}; + Option.Type[] types = {Option.Type.Put, Option.Type.Call}; for (int i = 0; i < types.Length; ++i) { @@ -213,8 +213,8 @@ public void testCompareBsmHWandHestonHW() Exercise exercise = new EuropeanExercise(maturityDate); - double fwd = strike[j]*spot.link.value() - * qTS.link.discount(maturityDate)/rTS.link.discount(maturityDate); + double fwd = strike[j] * spot.link.value() + * qTS.link.discount(maturityDate) / rTS.link.discount(maturityDate); StrikedTypePayoff payoff = new PlainVanillaPayoff(types[i], fwd); @@ -226,16 +226,16 @@ public void testCompareBsmHWandHestonHW() option.setPricingEngine(hestonHwEngine); double expected = option.NPV(); - if (Math.Abs(calculated - expected) > calculated*tol && + if (Math.Abs(calculated - expected) > calculated * tol && Math.Abs(calculated - expected) > tol) { QAssert.Fail("Failed to reproduce npvs" - + "\n calculated: " + calculated - + "\n expected : " + expected - + "\n strike : " + strike[j] - + "\n maturity : " + maturity[l] - + "\n type : " - + ((types[i] == QLNet.Option.Type.Put) ? "Put" : "Call")); + + "\n calculated: " + calculated + + "\n expected : " + expected + + "\n strike : " + strike[j] + + "\n maturity : " + maturity[l] + + "\n type : " + + ((types[i] == QLNet.Option.Type.Put) ? "Put" : "Call")); } } } @@ -243,11 +243,11 @@ public void testCompareBsmHWandHestonHW() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testZeroBondPricing() + public void testZeroBondPricing() { // Testing Monte-Carlo zero bond pricing @@ -269,7 +269,7 @@ public void testZeroBondPricing() for (int i = 120; i < 240; ++i) { dates.Add(today + new Period(i, TimeUnit.Months)); - rates.Add(0.02 + 0.0002*Math.Exp(Math.Sin(i/8.0))); + rates.Add(0.02 + 0.0002 * Math.Exp(Math.Sin(i / 8.0))); times.Add(dc.yearFraction(today, dates.Last())); } @@ -290,7 +290,7 @@ public void testZeroBondPricing() HybridHestonHullWhiteProcess jointProcess = new HybridHestonHullWhiteProcess(hestonProcess, hwProcess, -0.4); - TimeGrid grid = new TimeGrid(times,times.Count - 1); + TimeGrid grid = new TimeGrid(times, times.Count - 1); int factors = jointProcess.factors(); int steps = grid.size() - 1; @@ -310,7 +310,7 @@ public void testZeroBondPricing() { Sample path = generator.next(); MultiPath value = path.value as MultiPath; - Utils.QL_REQUIRE( value != null, () => "Invalid Path" ); + Utils.QL_REQUIRE(value != null, () => "Invalid Path"); for (int j = 1; j < m; ++j) { @@ -327,7 +327,7 @@ public void testZeroBondPricing() } double zeroBond - = 1.0/jointProcess.numeraire(t, states); + = 1.0 / jointProcess.numeraire(t, states); double zeroOption = zeroBond * Math.Max(0.0, hwModel.discountBond(t, T, states[2]) - strike); zeroStat[j].add(zeroBond); @@ -344,9 +344,9 @@ double zeroBond if (Math.Abs(calculated - expected) > 0.03) { QAssert.Fail("Failed to reproduce expected zero bond prices" - + "\n t: " + t - + "\n calculated: " + calculated - + "\n expected: " + expected); + + "\n t: " + t + + "\n calculated: " + calculated + + "\n expected: " + expected); } double T = grid[j + optionTenor]; @@ -357,22 +357,22 @@ double zeroBond if (Math.Abs(calculated - expected) > 0.0035) { QAssert.Fail("Failed to reproduce expected zero bond option prices" - + "\n t: " + t - + "\n T: " + T - + "\n calculated: " + calculated - + "\n expected: " + expected); + + "\n t: " + t + + "\n T: " + T + + "\n calculated: " + calculated + + "\n expected: " + expected); } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testMcVanillaPricing() + public void testMcVanillaPricing() { - // Testing Monte-Carlo vanilla option pricing + // Testing Monte-Carlo vanilla option pricing DayCounter dc = new Actual360(); Date today = Date.Today; @@ -389,18 +389,18 @@ public void testMcVanillaPricing() { dates.Add(today + new Period(i, TimeUnit.Years)); // FLOATING_POINT_EXCEPTION - rates.Add(0.03 + 0.0003*Math.Exp(Math.Sin(i/4.0))); - divRates.Add(0.02 + 0.0001*Math.Exp(Math.Sin(i/5.0))); + rates.Add(0.03 + 0.0003 * Math.Exp(Math.Sin(i / 4.0))); + divRates.Add(0.02 + 0.0001 * Math.Exp(Math.Sin(i / 5.0))); times.Add(dc.yearFraction(today, dates.Last())); } Date maturity = today + new Period(20, TimeUnit.Years); Handle s0 = new Handle(new SimpleQuote(100)); - Handle rTS = new Handle( new InterpolatedZeroCurve( dates, - rates, dc ) ); - Handle qTS = new Handle( new InterpolatedZeroCurve( dates, - divRates, dc ) ); + Handle rTS = new Handle(new InterpolatedZeroCurve(dates, + rates, dc)); + Handle qTS = new Handle(new InterpolatedZeroCurve(dates, + divRates, dc)); SimpleQuote vol = new SimpleQuote(0.25); Handle volTS = new Handle(Utilities.flatVol(today, vol, dc)); @@ -410,7 +410,7 @@ public void testMcVanillaPricing() hwProcess.setForwardMeasureTime(dc.yearFraction(today, maturity)); double tol = 0.05; - double[] corr = {-0.9,-0.5,0.0,0.5,0.9}; + double[] corr = {-0.9, -0.5, 0.0, 0.5, 0.9}; double[] strike = {100}; for (int i = 0; i < corr.Length; ++i) @@ -418,51 +418,51 @@ public void testMcVanillaPricing() for (int j = 0; j < strike.Length; ++j) { HybridHestonHullWhiteProcess jointProcess = new HybridHestonHullWhiteProcess(hestonProcess, - hwProcess, corr[i]); + hwProcess, corr[i]); StrikedTypePayoff payoff = new PlainVanillaPayoff(Option.Type.Put, strike[j]); Exercise exercise = new EuropeanExercise(maturity); VanillaOption optionHestonHW = new VanillaOption(payoff, exercise); - IPricingEngine engine = new MakeMCHestonHullWhiteEngine( jointProcess ) - .withSteps(1) - .withAntitheticVariate() - .withControlVariate() - .withAbsoluteTolerance(tol) - .withSeed( 42 ).getAsPricingEngine(); + IPricingEngine engine = new MakeMCHestonHullWhiteEngine(jointProcess) + .withSteps(1) + .withAntitheticVariate() + .withControlVariate() + .withAbsoluteTolerance(tol) + .withSeed(42).getAsPricingEngine(); optionHestonHW.setPricingEngine(engine); HullWhite hwModel = new HullWhite(new Handle(rTS), - hwProcess.a(), hwProcess.sigma()); + hwProcess.a(), hwProcess.sigma()); VanillaOption optionBsmHW = new VanillaOption(payoff, exercise); - optionBsmHW.setPricingEngine( new AnalyticBSMHullWhiteEngine(corr[i], bsmProcess,hwModel)); + optionBsmHW.setPricingEngine(new AnalyticBSMHullWhiteEngine(corr[i], bsmProcess, hwModel)); double calculated = optionHestonHW.NPV(); double error = optionHestonHW.errorEstimate(); double expected = optionBsmHW.NPV(); - if ((corr[i] != 0.0 && Math.Abs(calculated - expected) > 3*error) + if ((corr[i] != 0.0 && Math.Abs(calculated - expected) > 3 * error) || (corr[i] == 0.0 && Math.Abs(calculated - expected) > 1e-4)) { QAssert.Fail("Failed to reproduce BSM-HW vanilla prices" - + "\n corr: " + corr[i] - + "\n strike: " + strike[j] - + "\n calculated: " + calculated - + "\n error: " + error - + "\n expected: " + expected); + + "\n corr: " + corr[i] + + "\n strike: " + strike[j] + + "\n calculated: " + calculated + + "\n error: " + error + + "\n expected: " + expected); } } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testMcPureHestonPricing() + public void testMcPureHestonPricing() { // Testing Monte-Carlo Heston option pricing DayCounter dc = new Actual360(); @@ -481,8 +481,8 @@ public void testMcPureHestonPricing() { dates.Add(today + new Period(i, TimeUnit.Months)); // FLOATING_POINT_EXCEPTION - rates.Add(0.02 + 0.0002*Math.Exp(Math.Sin(i/10.0))); - divRates.Add(0.02 + 0.0001*Math.Exp(Math.Sin(i/20.0))); + rates.Add(0.02 + 0.0002 * Math.Exp(Math.Sin(i / 10.0))); + divRates.Add(0.02 + 0.0001 * Math.Exp(Math.Sin(i / 20.0))); times.Add(dc.yearFraction(today, dates.Last())); } @@ -497,15 +497,15 @@ public void testMcPureHestonPricing() hwProcess.setForwardMeasureTime(dc.yearFraction(today, maturity + new Period(1, TimeUnit.Years))); double tol = 0.001; - double[] corr = {-0.45,0.45,0.25}; - double[] strike = {100,75,50,150}; + double[] corr = {-0.45, 0.45, 0.25}; + double[] strike = {100, 75, 50, 150}; for (int i = 0; i < corr.Length; ++i) { for (int j = 0; j < strike.Length; ++j) { - HybridHestonHullWhiteProcess jointProcess = new HybridHestonHullWhiteProcess( hestonProcess, hwProcess, - corr[i], HybridHestonHullWhiteProcess.Discretization.Euler); + HybridHestonHullWhiteProcess jointProcess = new HybridHestonHullWhiteProcess(hestonProcess, hwProcess, + corr[i], HybridHestonHullWhiteProcess.Discretization.Euler); StrikedTypePayoff payoff = new PlainVanillaPayoff(Option.Type.Put, strike[j]); Exercise exercise = new EuropeanExercise(maturity); @@ -517,36 +517,36 @@ public void testMcPureHestonPricing() double expected = optionPureHeston.NPV(); optionHestonHW.setPricingEngine( - new MakeMCHestonHullWhiteEngine(jointProcess) - .withSteps(2) - .withAntitheticVariate() - .withControlVariate() - .withAbsoluteTolerance(tol) - .withSeed(42).getAsPricingEngine()); + new MakeMCHestonHullWhiteEngine(jointProcess) + .withSteps(2) + .withAntitheticVariate() + .withControlVariate() + .withAbsoluteTolerance(tol) + .withSeed(42).getAsPricingEngine()); double calculated = optionHestonHW.NPV(); double error = optionHestonHW.errorEstimate(); - if (Math.Abs(calculated - expected) > 3*error + if (Math.Abs(calculated - expected) > 3 * error && Math.Abs(calculated - expected) > tol) { QAssert.Fail("Failed to reproduce pure heston vanilla prices" - + "\n corr: " + corr[i] - + "\n strike: " + strike[j] - + "\n calculated: " + calculated - + "\n error: " + error - + "\n expected: " + expected); + + "\n corr: " + corr[i] + + "\n strike: " + strike[j] + + "\n calculated: " + calculated + + "\n error: " + error + + "\n expected: " + expected); } } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testAnalyticHestonHullWhitePricing() + public void testAnalyticHestonHullWhitePricing() { // Testing analytic Heston Hull-White option pricing DayCounter dc = new Actual360(); @@ -565,8 +565,8 @@ public void testAnalyticHestonHullWhitePricing() { dates.Add(today + new Period(i, TimeUnit.Years)); // FLOATING_POINT_EXCEPTION - rates.Add(0.03 + 0.0001*Math.Exp(Math.Sin(i/4.0))); - divRates.Add(0.02 + 0.0002*Math.Exp(Math.Sin(i/3.0))); + rates.Add(0.03 + 0.0001 * Math.Exp(Math.Sin(i / 4.0))); + divRates.Add(0.02 + 0.0002 * Math.Exp(Math.Sin(i / 3.0))); times.Add(dc.yearFraction(today, dates.Last())); } @@ -583,53 +583,53 @@ public void testAnalyticHestonHullWhitePricing() HullWhite hullWhiteModel = new HullWhite(rTS, hwFwdProcess.a(), hwFwdProcess.sigma()); double tol = 0.002; - double[] strike = {80,120}; - Option.Type[] types = {Option.Type.Put,Option.Type.Call}; + double[] strike = {80, 120}; + Option.Type[] types = {Option.Type.Put, Option.Type.Call}; for (int i = 0; i < types.Length; ++i) { for (int j = 0; j < strike.Length; ++j) { - HybridHestonHullWhiteProcess jointProcess = new HybridHestonHullWhiteProcess(hestonProcess, - hwFwdProcess, 0.0,HybridHestonHullWhiteProcess.Discretization.Euler); + HybridHestonHullWhiteProcess jointProcess = new HybridHestonHullWhiteProcess(hestonProcess, + hwFwdProcess, 0.0, HybridHestonHullWhiteProcess.Discretization.Euler); StrikedTypePayoff payoff = new PlainVanillaPayoff(types[i], strike[j]); Exercise exercise = new EuropeanExercise(maturity); VanillaOption optionHestonHW = new VanillaOption(payoff, exercise); - optionHestonHW.setPricingEngine( new MakeMCHestonHullWhiteEngine(jointProcess) - .withSteps(1) - .withAntitheticVariate() - .withControlVariate() - .withAbsoluteTolerance(tol) - .withSeed(42).getAsPricingEngine()); + optionHestonHW.setPricingEngine(new MakeMCHestonHullWhiteEngine(jointProcess) + .withSteps(1) + .withAntitheticVariate() + .withControlVariate() + .withAbsoluteTolerance(tol) + .withSeed(42).getAsPricingEngine()); VanillaOption optionPureHeston = new VanillaOption(payoff, exercise); - optionPureHeston.setPricingEngine(new AnalyticHestonHullWhiteEngine(hestonModel,hullWhiteModel, 128)); + optionPureHeston.setPricingEngine(new AnalyticHestonHullWhiteEngine(hestonModel, hullWhiteModel, 128)); double calculated = optionHestonHW.NPV(); double error = optionHestonHW.errorEstimate(); double expected = optionPureHeston.NPV(); - if (Math.Abs(calculated - expected) > 3*error + if (Math.Abs(calculated - expected) > 3 * error && Math.Abs(calculated - expected) > tol) { QAssert.Fail("Failed to reproduce hw heston vanilla prices" - + "\n strike: " + strike[j] - + "\n calculated: " + calculated - + "\n error: " + error - + "\n expected: " + expected); + + "\n strike: " + strike[j] + + "\n calculated: " + calculated + + "\n error: " + error + + "\n expected: " + expected); } } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testCallableEquityPricing() + public void testCallableEquityPricing() { // Testing the pricing of a callable equity product @@ -653,33 +653,33 @@ Stochastic Interest Rates . SimpleQuote rRate = new SimpleQuote(0.04); Handle rTS = new Handle(Utilities.flatRate(today, rRate, dc)); - HestonProcess hestonProcess = new HestonProcess(rTS, qTS, spot, 0.0625, 1.0, 0.24*0.24, 1e-4, 0.0); + HestonProcess hestonProcess = new HestonProcess(rTS, qTS, spot, 0.0625, 1.0, 0.24 * 0.24, 1e-4, 0.0); // FLOATING_POINT_EXCEPTION HullWhiteForwardProcess hwProcess = new HullWhiteForwardProcess(rTS, 0.00883, 0.00526); hwProcess.setForwardMeasureTime(dc.yearFraction(today, today + new Period(maturity + 1, TimeUnit.Years))); HybridHestonHullWhiteProcess jointProcess = new HybridHestonHullWhiteProcess(hestonProcess, hwProcess, -0.4); - Schedule schedule = new Schedule(today, today + new Period(maturity, TimeUnit.Years),new Period(1, TimeUnit.Years), - new TARGET(),BusinessDayConvention.Following, BusinessDayConvention.Following, DateGeneration.Rule.Forward,false); + Schedule schedule = new Schedule(today, today + new Period(maturity, TimeUnit.Years), new Period(1, TimeUnit.Years), + new TARGET(), BusinessDayConvention.Following, BusinessDayConvention.Following, DateGeneration.Rule.Forward, false); List times = new InitializedList(maturity + 1); for (int i = 0; i <= maturity; ++i) times[i] = i; - TimeGrid grid = new TimeGrid(times,times.Count); + TimeGrid grid = new TimeGrid(times, times.Count); List redemption = new InitializedList(maturity); for (int i = 0; i < maturity; ++i) { - redemption[i] = 1.07 + 0.03*i; + redemption[i] = 1.07 + 0.03 * i; } ulong seed = 42; IRNG rsg = (InverseCumulativeRsg - ,InverseCumulativeNormal>) - new PseudoRandom().make_sequence_generator(jointProcess.factors()*(grid.size() - 1), seed); + , InverseCumulativeNormal>) + new PseudoRandom().make_sequence_generator(jointProcess.factors() * (grid.size() - 1), seed); MultiPathGenerator generator = new MultiPathGenerator(jointProcess, grid, rsg, false); GeneralStatistics stat = new GeneralStatistics(); @@ -688,11 +688,11 @@ Stochastic Interest Rates . int nrTrails = 40000; for (int i = 0; i < nrTrails; ++i) { - bool antithetic = (i%2) != 0; + bool antithetic = (i % 2) != 0; Sample path = antithetic ? generator.antithetic() : generator.next(); MultiPath value = path.value as MultiPath; - Utils.QL_REQUIRE( value != null, () => "Invalid Path" ); + Utils.QL_REQUIRE(value != null, () => "Invalid Path"); double payoff = 0; for (int j = 1; j <= maturity; ++j) @@ -714,13 +714,13 @@ Stochastic Interest Rates . { states[k] = value[k][j]; } - payoff = 1.0/jointProcess.numeraire(grid[j], states); + payoff = 1.0 / jointProcess.numeraire(grid[j], states); } } if (antithetic) { - stat.add(0.5*(antitheticPayoff + payoff)); + stat.add(0.5 * (antitheticPayoff + payoff)); } else { @@ -732,21 +732,21 @@ Stochastic Interest Rates . double calculated = stat.mean(); double error = stat.errorEstimate(); - if (Math.Abs(expected - calculated) > 3*error) + if (Math.Abs(expected - calculated) > 3 * error) { QAssert.Fail("Failed to reproduce auto-callable equity structure price" - + "\n calculated: " + calculated - + "\n error: " + error - + "\n expected: " + expected); + + "\n calculated: " + calculated + + "\n error: " + error + + "\n expected: " + expected); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testDiscretizationError() + public void testDiscretizationError() { // Testing the discretization error of the Heston Hull-White process DayCounter dc = new Actual360(); @@ -765,8 +765,8 @@ public void testDiscretizationError() { dates.Add(today + new Period(i, TimeUnit.Years)); // FLOATING_POINT_EXCEPTION - rates.Add(0.04 + 0.0001*Math.Exp(Math.Sin(i))); - divRates.Add(0.04 + 0.0001*Math.Exp(Math.Sin(i))); + rates.Add(0.04 + 0.0001 * Math.Exp(Math.Sin(i))); + divRates.Add(0.04 + 0.0001 * Math.Exp(Math.Sin(i))); times.Add(dc.yearFraction(today, dates.Last())); } @@ -781,14 +781,14 @@ public void testDiscretizationError() BlackScholesMertonProcess bsmProcess = new BlackScholesMertonProcess(s0, qTS, rTS, volTS); - HestonProcess hestonProcess = new HestonProcess(rTS, qTS, s0, v*v, 1, v*v, 1e-6, -0.4); + HestonProcess hestonProcess = new HestonProcess(rTS, qTS, s0, v * v, 1, v * v, 1e-6, -0.4); HullWhiteForwardProcess hwProcess = new HullWhiteForwardProcess(rTS, 0.01, 0.01); hwProcess.setForwardMeasureTime(20.1472222222222222); double tol = 0.05; - double[] corr = {-0.85,0.5}; - double[] strike = {50,100,125}; + double[] corr = {-0.85, 0.5}; + double[] strike = {50, 100, 125}; for (int i = 0; i < corr.Length; ++i) { @@ -799,43 +799,43 @@ public void testDiscretizationError() VanillaOption optionBsmHW = new VanillaOption(payoff, exercise); HullWhite hwModel = new HullWhite(rTS, hwProcess.a(), hwProcess.sigma()); - optionBsmHW.setPricingEngine( new AnalyticBSMHullWhiteEngine(corr[i], bsmProcess,hwModel)); + optionBsmHW.setPricingEngine(new AnalyticBSMHullWhiteEngine(corr[i], bsmProcess, hwModel)); double expected = optionBsmHW.NPV(); VanillaOption optionHestonHW = new VanillaOption(payoff, exercise); HybridHestonHullWhiteProcess jointProcess = new HybridHestonHullWhiteProcess(hestonProcess, - hwProcess, corr[i]); - optionHestonHW.setPricingEngine( - new MakeMCHestonHullWhiteEngine(jointProcess) - .withSteps(1) - .withAntitheticVariate() - .withAbsoluteTolerance(tol) - .withSeed(42).getAsPricingEngine()); + hwProcess, corr[i]); + optionHestonHW.setPricingEngine( + new MakeMCHestonHullWhiteEngine(jointProcess) + .withSteps(1) + .withAntitheticVariate() + .withAbsoluteTolerance(tol) + .withSeed(42).getAsPricingEngine()); double calculated = optionHestonHW.NPV(); double error = optionHestonHW.errorEstimate(); - if ((Math.Abs(calculated - expected) > 3*error + if ((Math.Abs(calculated - expected) > 3 * error && Math.Abs(calculated - expected) > 1e-5)) { QAssert.Fail("Failed to reproduce discretization error" - + "\n corr: " + corr[i] - + "\n strike: " + strike[j] - + "\n calculated: " + calculated - + "\n error: " + error - + "\n expected: " + expected); + + "\n corr: " + corr[i] + + "\n strike: " + strike[j] + + "\n calculated: " + calculated + + "\n error: " + error + + "\n expected: " + expected); } } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testH1HWPricingEngine() + public void testH1HWPricingEngine() { /* * Example taken from Lech Aleksander Grzelak, @@ -857,7 +857,7 @@ public void testH1HWPricingEngine() double v0 = 0.05; double theta = 0.05; double kappa_v = 0.3; - double[] sigma_v = {0.3,0.6}; + double[] sigma_v = {0.3, 0.6}; double rho_sv = -0.30; double rho_sr = 0.6; double kappa_r = 0.01; @@ -873,16 +873,16 @@ public void testH1HWPricingEngine() HullWhite hullWhiteModel = new HullWhite(new Handle(rTS), kappa_r, sigma_r); double tol = 0.0001; - double[] strikes = {40,80,100,120,180}; + double[] strikes = {40, 80, 100, 120, 180}; double[][] expected = { - new double[] {0.267503,0.235742,0.228223,0.223461,0.217855}, - new double[] {0.263626,0.211625,0.199907,0.193502,0.190025} + new double[] {0.267503, 0.235742, 0.228223, 0.223461, 0.217855}, + new double[] {0.263626, 0.211625, 0.199907, 0.193502, 0.190025} }; for (int j = 0; j < sigma_v.Length; ++j) { - HestonProcess hestonProcess = new HestonProcess(rTS, qTS, s0, v0, kappa_v, theta,sigma_v[j], rho_sv); + HestonProcess hestonProcess = new HestonProcess(rTS, qTS, s0, v0, kappa_v, theta, sigma_v[j], rho_sv); HestonModel hestonModel = new HestonModel(hestonProcess); for (int i = 0; i < strikes.Length; ++i) @@ -891,18 +891,18 @@ public void testH1HWPricingEngine() VanillaOption option = new VanillaOption(payoff, exercise); - IPricingEngine analyticH1HWEngine = new AnalyticH1HWEngine(hestonModel, hullWhiteModel,rho_sr, 144); + IPricingEngine analyticH1HWEngine = new AnalyticH1HWEngine(hestonModel, hullWhiteModel, rho_sr, 144); option.setPricingEngine(analyticH1HWEngine); double impliedH1HW = option.impliedVolatility(option.NPV(), bsProcess); if (Math.Abs(expected[j][i] - impliedH1HW) > tol) { QAssert.Fail("Failed to reproduce H1HW implied volatility" - + "\n expected : " + expected[j][i] - + "\n calculated : " + impliedH1HW - + "\n tol : " + tol - + "\n strike : " + strikes[i] - + "\n sigma : " + sigma_v[j]); + + "\n expected : " + expected[j][i] + + "\n calculated : " + impliedH1HW + + "\n tol : " + tol + + "\n strike : " + strikes[i] + + "\n sigma : " + sigma_v[j]); } } } diff --git a/tests/QLNet.Tests/T_Inflation.cs b/tests/QLNet.Tests/T_Inflation.cs index 9917f6542..7c270e734 100644 --- a/tests/QLNet.Tests/T_Inflation.cs +++ b/tests/QLNet.Tests/T_Inflation.cs @@ -6,7 +6,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -20,7 +20,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; using System; @@ -38,7 +38,7 @@ public Datum(Date d, double r) date = d; rate = r; } - }; + } //=========================================================================================== // zero inflation tests, index, termstructure, and swaps @@ -56,10 +56,10 @@ private YieldTermStructure nominalTermStructure() } private List> makeHelpers(Datum[] iiData, int N, - ZeroInflationIndex ii, Period observationLag, - Calendar calendar, - BusinessDayConvention bdc, - DayCounter dc) + ZeroInflationIndex ii, Period observationLag, + Calendar calendar, + BusinessDayConvention bdc, + DayCounter dc) { List> instruments = new List>(); for (int i = 0; i < N; i++) @@ -67,17 +67,17 @@ private List> makeHelpers(Datum[] ii Date maturity = iiData[i].date; Handle quote = new Handle(new SimpleQuote(iiData[i].rate / 100.0)); BootstrapHelper anInstrument = new ZeroCouponInflationSwapHelper(quote, observationLag, maturity, - calendar, bdc, dc, ii); + calendar, bdc, dc, ii); instruments.Add(anInstrument); } return instruments; } private List> makeHelpers(Datum[] iiData, int N, - YoYInflationIndex ii, Period observationLag, - Calendar calendar, - BusinessDayConvention bdc, - DayCounter dc) + YoYInflationIndex ii, Period observationLag, + Calendar calendar, + BusinessDayConvention bdc, + DayCounter dc) { List> instruments = new List>(); for (int i = 0; i < N; i++) @@ -85,16 +85,16 @@ private List> makeHelpers(Datum[] iiD Date maturity = iiData[i].date; Handle quote = new Handle(new SimpleQuote(iiData[i].rate / 100.0)); BootstrapHelper anInstrument = new YearOnYearInflationSwapHelper(quote, observationLag, maturity, - calendar, bdc, dc, ii); + calendar, bdc, dc, ii); instruments.Add(anInstrument); } return instruments; } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testZeroIndex() { @@ -109,11 +109,11 @@ public void testZeroIndex() || euhicp.availabilityLag() != new Period(1, TimeUnit.Months)) { QAssert.Fail("wrong EU HICP data (" - + euhicp.name() + ", " - + euhicp.frequency() + ", " - + euhicp.revised() + ", " - + euhicp.interpolated() + ", " - + euhicp.availabilityLag() + ")"); + + euhicp.name() + ", " + + euhicp.frequency() + ", " + + euhicp.revised() + ", " + + euhicp.interpolated() + ", " + + euhicp.availabilityLag() + ")"); } UKRPI ukrpi = new UKRPI(false); @@ -124,11 +124,11 @@ public void testZeroIndex() || ukrpi.availabilityLag() != new Period(1, TimeUnit.Months)) { QAssert.Fail("wrong UK RPI data (" - + ukrpi.name() + ", " - + ukrpi.frequency() + ", " - + ukrpi.revised() + ", " - + ukrpi.interpolated() + ", " - + ukrpi.availabilityLag() + ")"); + + ukrpi.name() + ", " + + ukrpi.frequency() + ", " + + ukrpi.revised() + ", " + + ukrpi.interpolated() + ", " + + ukrpi.availabilityLag() + ")"); } // Retrieval test. @@ -142,17 +142,18 @@ public void testZeroIndex() Date from = new Date(1, Month.January, 2005); Date to = new Date(13, Month.August, 2007); Schedule rpiSchedule = new MakeSchedule().from(from).to(to) - .withTenor(new Period(1, TimeUnit.Months)) - .withCalendar(new UnitedKingdom()) - .withConvention(BusinessDayConvention.ModifiedFollowing) - .value(); + .withTenor(new Period(1, TimeUnit.Months)) + .withCalendar(new UnitedKingdom()) + .withConvention(BusinessDayConvention.ModifiedFollowing) + .value(); double[] fixData = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0, 192.2, 192.2, 192.6, 193.1, 193.3, 193.6, 194.1, 193.4, 194.2, 195.0, 196.5, 197.7, 198.5, 198.5, 199.2, 200.1, 200.4, 201.1, 202.7, 201.6, 203.1, 204.4, 205.4, 206.2, - 207.3, 206.1, -999.0 }; + 207.3, 206.1, -999.0 + }; bool interp = false; UKRPI iir = new UKRPI(interp); @@ -173,24 +174,24 @@ public void testZeroIndex() for (int i = 0; i < rpiSchedule.Count - 1; i++) { KeyValuePair lim = Utils.inflationPeriod(rpiSchedule[i], - iir.frequency()); + iir.frequency()); for (Date d = lim.Key; d <= lim.Value; d++) { if (d < Utils.inflationPeriod(todayMinusLag, iir.frequency()).Key) { if (Math.Abs(iir.fixing(d) - fixData[i]) > eps) QAssert.Fail("Fixings not constant within a period: " - + iir.fixing(d) - + ", should be " + fixData[i]); + + iir.fixing(d) + + ", should be " + fixData[i]); } } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testZeroTermStructure() { @@ -210,17 +211,18 @@ public void testZeroTermStructure() Date from = new Date(1, Month.January, 2005); Date to = new Date(13, Month.August, 2007); Schedule rpiSchedule = new MakeSchedule().from(from).to(to) - .withTenor(new Period(1, TimeUnit.Months)) - .withCalendar(new UnitedKingdom()) - .withConvention(BusinessDayConvention.ModifiedFollowing) - .value(); + .withTenor(new Period(1, TimeUnit.Months)) + .withCalendar(new UnitedKingdom()) + .withConvention(BusinessDayConvention.ModifiedFollowing) + .value(); double[] fixData = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0, - 192.2, 192.2, 192.6, 193.1, 193.3, 193.6, - 194.1, 193.4, 194.2, 195.0, 196.5, 197.7, - 198.5, 198.5, 199.2, 200.1, 200.4, 201.1, - 202.7, 201.6, 203.1, 204.4, 205.4, 206.2, - 207.3}; + 192.2, 192.2, 192.6, 193.1, 193.3, 193.6, + 194.1, 193.4, 194.2, 195.0, 196.5, 197.7, + 198.5, 198.5, 199.2, 200.1, 200.4, 201.1, + 202.7, 201.6, 203.1, 204.4, 205.4, 206.2, + 207.3 + }; RelinkableHandle hz = new RelinkableHandle(); bool interp = false; @@ -235,35 +237,37 @@ public void testZeroTermStructure() // now build the zero inflation curve - Datum[] zcData = { - new Datum( new Date(13, Month.August, 2008), 2.93 ), - new Datum( new Date(13, Month.August, 2009), 2.95 ), - new Datum( new Date(13, Month.August, 2010), 2.965 ), - new Datum( new Date(15, Month.August, 2011), 2.98 ), - new Datum( new Date(13, Month.August, 2012), 3.0 ), - new Datum( new Date(13, Month.August, 2014), 3.06 ), - new Datum( new Date(13, Month.August, 2017), 3.175 ), - new Datum( new Date(13, Month.August, 2019), 3.243 ), - new Datum( new Date(15, Month.August, 2022), 3.293 ), - new Datum( new Date(14, Month.August, 2027), 3.338 ), - new Datum( new Date(13, Month.August, 2032), 3.348 ), - new Datum( new Date(15, Month.August, 2037), 3.348 ), - new Datum( new Date(13, Month.August, 2047), 3.308 ), - new Datum( new Date(13, Month.August, 2057), 3.228 )}; + Datum[] zcData = + { + new Datum(new Date(13, Month.August, 2008), 2.93), + new Datum(new Date(13, Month.August, 2009), 2.95), + new Datum(new Date(13, Month.August, 2010), 2.965), + new Datum(new Date(15, Month.August, 2011), 2.98), + new Datum(new Date(13, Month.August, 2012), 3.0), + new Datum(new Date(13, Month.August, 2014), 3.06), + new Datum(new Date(13, Month.August, 2017), 3.175), + new Datum(new Date(13, Month.August, 2019), 3.243), + new Datum(new Date(15, Month.August, 2022), 3.293), + new Datum(new Date(14, Month.August, 2027), 3.338), + new Datum(new Date(13, Month.August, 2032), 3.348), + new Datum(new Date(15, Month.August, 2037), 3.348), + new Datum(new Date(13, Month.August, 2047), 3.308), + new Datum(new Date(13, Month.August, 2057), 3.228) + }; Period observationLag = new Period(2, TimeUnit.Months); DayCounter dc = new Thirty360(); Frequency frequency = Frequency.Monthly; List> helpers = makeHelpers(zcData, zcData.Length, ii, - observationLag, - calendar, bdc, dc); + observationLag, + calendar, bdc, dc); double baseZeroRate = zcData[0].rate / 100.0; PiecewiseZeroInflationCurve pZITS = new PiecewiseZeroInflationCurve( - evaluationDate, calendar, dc, observationLag, - frequency, ii.interpolated(), baseZeroRate, - new Handle(nominalTS), helpers); + evaluationDate, calendar, dc, observationLag, + frequency, ii.interpolated(), baseZeroRate, + new Handle(nominalTS), helpers); pZITS.recalculate(); // first check that the zero rates on the curve match the data @@ -273,18 +277,18 @@ public void testZeroTermStructure() for (int i = 0; i < zcData.Length; i++) { QAssert.IsTrue(Math.Abs(zcData[i].rate / 100.0 - - pZITS.zeroRate(zcData[i].date, observationLag, forceLinearInterpolation)) < eps, - "ZITS zeroRate != instrument " - + pZITS.zeroRate(zcData[i].date, observationLag, forceLinearInterpolation) - + " vs " + zcData[i].rate / 100.0 - + " interpolation: " + ii.interpolated() - + " forceLinearInterpolation " + forceLinearInterpolation); + - pZITS.zeroRate(zcData[i].date, observationLag, forceLinearInterpolation)) < eps, + "ZITS zeroRate != instrument " + + pZITS.zeroRate(zcData[i].date, observationLag, forceLinearInterpolation) + + " vs " + zcData[i].rate / 100.0 + + " interpolation: " + ii.interpolated() + + " forceLinearInterpolation " + forceLinearInterpolation); QAssert.IsTrue(Math.Abs(helpers[i].impliedQuote() - - zcData[i].rate / 100.0) < eps, - "ZITS implied quote != instrument " - + helpers[i].impliedQuote() - + " vs " + zcData[i].rate / 100.0); + - zcData[i].rate / 100.0) < eps, + "ZITS implied quote != instrument " + + helpers[i].impliedQuote() + + " vs " + zcData[i].rate / 100.0); } // now test the forecasting capability of the index. @@ -292,9 +296,9 @@ public void testZeroTermStructure() from = hz.link.baseDate(); to = hz.link.maxDate() - new Period(1, TimeUnit.Months); // a bit of margin for adjustments Schedule testIndex = new MakeSchedule().from(from).to(to) - .withTenor(new Period(1, TimeUnit.Months)) - .withCalendar(new UnitedKingdom()) - .withConvention(BusinessDayConvention.ModifiedFollowing).value(); + .withTenor(new Period(1, TimeUnit.Months)) + .withCalendar(new UnitedKingdom()) + .withConvention(BusinessDayConvention.ModifiedFollowing).value(); // we are testing UKRPI which is not interpolated Date bd = hz.link.baseDate(); @@ -306,17 +310,17 @@ public void testZeroTermStructure() double t = hz.link.dayCounter().yearFraction(bd, d); if (!ii.interpolated()) // because fixing constant over period t = hz.link.dayCounter().yearFraction(bd, - Utils.inflationPeriod(d, ii.frequency()).Key); + Utils.inflationPeriod(d, ii.frequency()).Key); double calc = bf * Math.Pow(1 + z, t); if (t <= 0) calc = ii.fixing(d, false); // still historical if (Math.Abs(calc - ii.fixing(d, true)) / 10000.0 > eps) QAssert.Fail("ZC index does not forecast correctly for date " + d - + " from base date " + bd - + " with fixing " + bf - + ", correct: " + calc - + ", fix: " + ii.fixing(d, true) - + ", t " + t); + + " from base date " + bd + + " with fixing " + bf + + ", correct: " + calc + + ", fix: " + ii.fixing(d, true) + + ", t " + t); } //=========================================================================================== @@ -334,8 +338,8 @@ public void testZeroTermStructure() double correctIndexed = ii.fixing(iicf.fixingDate()) / ii.fixing(iicf.baseDate()); double calculatedIndexed = iicf.amount() / iicf.notional(); QAssert.IsTrue(Math.Abs(correctIndexed - calculatedIndexed) < eps, - "IndexedCashFlow indexing wrong: " + calculatedIndexed + " vs correct = " - + correctIndexed); + "IndexedCashFlow indexing wrong: " + calculatedIndexed + " vs correct = " + + correctIndexed); //=========================================================================================== // Test zero coupon swap @@ -360,12 +364,12 @@ public void testZeroTermStructure() // ... and price it, should be zero QAssert.IsTrue(Math.Abs(nzcis.NPV()) < 0.00001, "ZCIS does not reprice to zero " - + nzcis.NPV() - + evaluationDate + " to " + zcData[6].date + " becoming " + nzcis.maturityDate() - + " rate " + zcData[6].rate - + " fixed leg " + nzcis.legNPV(0) - + " indexed-predicted inflated leg " + nzcis.legNPV(1) - + " discount " + nominalTS.discount(nzcis.maturityDate())); + + nzcis.NPV() + + evaluationDate + " to " + zcData[6].date + " becoming " + nzcis.maturityDate() + + " rate " + zcData[6].rate + + " fixed leg " + nzcis.legNPV(0) + + " indexed-predicted inflated leg " + nzcis.legNPV(1) + + " discount " + nominalTS.discount(nzcis.maturityDate())); //=========================================================================================== // Test multiplicative seasonality in price @@ -399,38 +403,40 @@ public void testZeroTermStructure() new MultiplicativePriceSeasonality(seasonallityBaseDate, Frequency.Monthly, seasonalityFactors); //Testing seasonality correction when seasonality factors are = 1 // - double[] fixing = { - ii.fixing(new Date(14,Month.January ,2013),true), - ii.fixing(new Date(14,Month.February ,2013),true), - ii.fixing(new Date(14,Month.March ,2013),true), - ii.fixing(new Date(14,Month.April ,2013),true), - ii.fixing(new Date(14,Month.May ,2013),true), - ii.fixing(new Date(14,Month.June ,2013),true), - ii.fixing(new Date(14,Month.July ,2013),true), - ii.fixing(new Date(14,Month.August ,2013),true), - ii.fixing(new Date(14,Month.September,2013),true), - ii.fixing(new Date(14,Month.October ,2013),true), - ii.fixing(new Date(14,Month.November ,2013),true), - ii.fixing(new Date(14,Month.December ,2013),true) - }; + double[] fixing = + { + ii.fixing(new Date(14, Month.January, 2013), true), + ii.fixing(new Date(14, Month.February, 2013), true), + ii.fixing(new Date(14, Month.March, 2013), true), + ii.fixing(new Date(14, Month.April, 2013), true), + ii.fixing(new Date(14, Month.May, 2013), true), + ii.fixing(new Date(14, Month.June, 2013), true), + ii.fixing(new Date(14, Month.July, 2013), true), + ii.fixing(new Date(14, Month.August, 2013), true), + ii.fixing(new Date(14, Month.September, 2013), true), + ii.fixing(new Date(14, Month.October, 2013), true), + ii.fixing(new Date(14, Month.November, 2013), true), + ii.fixing(new Date(14, Month.December, 2013), true) + }; hz.link.setSeasonality(seasonality_1); Utils.QL_REQUIRE(hz.link.hasSeasonality(), () => "[44] incorrectly believes NO seasonality correction"); - double[] seasonalityFixing_1 = { - ii.fixing(new Date(14,Month.January ,2013),true), - ii.fixing(new Date(14,Month.February ,2013),true), - ii.fixing(new Date(14,Month.March ,2013),true), - ii.fixing(new Date(14,Month.April ,2013),true), - ii.fixing(new Date(14,Month.May ,2013),true), - ii.fixing(new Date(14,Month.June ,2013),true), - ii.fixing(new Date(14,Month.July ,2013),true), - ii.fixing(new Date(14,Month.August ,2013),true), - ii.fixing(new Date(14,Month.September,2013),true), - ii.fixing(new Date(14,Month.October ,2013),true), - ii.fixing(new Date(14,Month.November ,2013),true), - ii.fixing(new Date(14,Month.December ,2013),true) - }; + double[] seasonalityFixing_1 = + { + ii.fixing(new Date(14, Month.January, 2013), true), + ii.fixing(new Date(14, Month.February, 2013), true), + ii.fixing(new Date(14, Month.March, 2013), true), + ii.fixing(new Date(14, Month.April, 2013), true), + ii.fixing(new Date(14, Month.May, 2013), true), + ii.fixing(new Date(14, Month.June, 2013), true), + ii.fixing(new Date(14, Month.July, 2013), true), + ii.fixing(new Date(14, Month.August, 2013), true), + ii.fixing(new Date(14, Month.September, 2013), true), + ii.fixing(new Date(14, Month.October, 2013), true), + ii.fixing(new Date(14, Month.November, 2013), true), + ii.fixing(new Date(14, Month.December, 2013), true) + }; for (int i = 0; i < 12; i++) { @@ -444,44 +450,46 @@ public void testZeroTermStructure() // //0.998687 is the seasonality factor corresponding to June (the base CPI curve month) // - double[] expectedFixing = { - ii.fixing(new Date(14,Month.January ,2013),true) * 1.003245/0.998687, - ii.fixing(new Date(14,Month.February ,2013),true) * 1.000000/0.998687, - ii.fixing(new Date(14,Month.March ,2013),true) * 0.999715/0.998687, - ii.fixing(new Date(14,Month.April ,2013),true) * 1.000495/0.998687, - ii.fixing(new Date(14,Month.May ,2013),true) * 1.000929/0.998687, - ii.fixing(new Date(14,Month.June ,2013),true) * 0.998687/0.998687, - ii.fixing(new Date(14,Month.July ,2013),true) * 0.995949/0.998687, - ii.fixing(new Date(14,Month.August ,2013),true) * 0.994682/0.998687, - ii.fixing(new Date(14,Month.September,2013),true) * 0.995949/0.998687, - ii.fixing(new Date(14,Month.October ,2013),true) * 1.000519/0.998687, - ii.fixing(new Date(14,Month.November ,2013),true) * 1.003705/0.998687, - ii.fixing(new Date(14,Month.December ,2013),true) * 1.004186/0.998687 - }; + double[] expectedFixing = + { + ii.fixing(new Date(14, Month.January, 2013), true) * 1.003245 / 0.998687, + ii.fixing(new Date(14, Month.February, 2013), true) * 1.000000 / 0.998687, + ii.fixing(new Date(14, Month.March, 2013), true) * 0.999715 / 0.998687, + ii.fixing(new Date(14, Month.April, 2013), true) * 1.000495 / 0.998687, + ii.fixing(new Date(14, Month.May, 2013), true) * 1.000929 / 0.998687, + ii.fixing(new Date(14, Month.June, 2013), true) * 0.998687 / 0.998687, + ii.fixing(new Date(14, Month.July, 2013), true) * 0.995949 / 0.998687, + ii.fixing(new Date(14, Month.August, 2013), true) * 0.994682 / 0.998687, + ii.fixing(new Date(14, Month.September, 2013), true) * 0.995949 / 0.998687, + ii.fixing(new Date(14, Month.October, 2013), true) * 1.000519 / 0.998687, + ii.fixing(new Date(14, Month.November, 2013), true) * 1.003705 / 0.998687, + ii.fixing(new Date(14, Month.December, 2013), true) * 1.004186 / 0.998687 + }; hz.link.setSeasonality(seasonality_real); - double[] seasonalityFixing_real = { - ii.fixing(new Date(14,Month.January ,2013),true), - ii.fixing(new Date(14,Month.February ,2013),true), - ii.fixing(new Date(14,Month.March ,2013),true), - ii.fixing(new Date(14,Month.April ,2013),true), - ii.fixing(new Date(14,Month.May ,2013),true), - ii.fixing(new Date(14,Month.June ,2013),true), - ii.fixing(new Date(14,Month.July ,2013),true), - ii.fixing(new Date(14,Month.August ,2013),true), - ii.fixing(new Date(14,Month.September,2013),true), - ii.fixing(new Date(14,Month.October ,2013),true), - ii.fixing(new Date(14,Month.November ,2013),true), - ii.fixing(new Date(14,Month.December ,2013),true) - }; + double[] seasonalityFixing_real = + { + ii.fixing(new Date(14, Month.January, 2013), true), + ii.fixing(new Date(14, Month.February, 2013), true), + ii.fixing(new Date(14, Month.March, 2013), true), + ii.fixing(new Date(14, Month.April, 2013), true), + ii.fixing(new Date(14, Month.May, 2013), true), + ii.fixing(new Date(14, Month.June, 2013), true), + ii.fixing(new Date(14, Month.July, 2013), true), + ii.fixing(new Date(14, Month.August, 2013), true), + ii.fixing(new Date(14, Month.September, 2013), true), + ii.fixing(new Date(14, Month.October, 2013), true), + ii.fixing(new Date(14, Month.November, 2013), true), + ii.fixing(new Date(14, Month.December, 2013), true) + }; for (int i = 0; i < 12; i++) { if (Math.Abs(expectedFixing[i] - seasonalityFixing_real[i]) > 0.01) { QAssert.Fail("Seasonality doesn't work correctly when considering seasonality factors != 1 " - + expectedFixing[i] + " vs " + seasonalityFixing_real[i]); + + expectedFixing[i] + " vs " + seasonalityFixing_real[i]); } } @@ -491,27 +499,28 @@ public void testZeroTermStructure() hz.link.setSeasonality(); Utils.QL_REQUIRE(!hz.link.hasSeasonality(), () => "[5] incorrectly believes HAS seasonality correction"); - double[] seasonalityFixing_unset = { - ii.fixing(new Date(14,Month.January ,2013),true), - ii.fixing(new Date(14,Month.February ,2013),true), - ii.fixing(new Date(14,Month.March ,2013),true), - ii.fixing(new Date(14,Month.April ,2013),true), - ii.fixing(new Date(14,Month.May ,2013),true), - ii.fixing(new Date(14,Month.June ,2013),true), - ii.fixing(new Date(14,Month.July ,2013),true), - ii.fixing(new Date(14,Month.August ,2013),true), - ii.fixing(new Date(14,Month.September,2013),true), - ii.fixing(new Date(14,Month.October ,2013),true), - ii.fixing(new Date(14,Month.November ,2013),true), - ii.fixing(new Date(14,Month.December ,2013),true) - }; + double[] seasonalityFixing_unset = + { + ii.fixing(new Date(14, Month.January, 2013), true), + ii.fixing(new Date(14, Month.February, 2013), true), + ii.fixing(new Date(14, Month.March, 2013), true), + ii.fixing(new Date(14, Month.April, 2013), true), + ii.fixing(new Date(14, Month.May, 2013), true), + ii.fixing(new Date(14, Month.June, 2013), true), + ii.fixing(new Date(14, Month.July, 2013), true), + ii.fixing(new Date(14, Month.August, 2013), true), + ii.fixing(new Date(14, Month.September, 2013), true), + ii.fixing(new Date(14, Month.October, 2013), true), + ii.fixing(new Date(14, Month.November, 2013), true), + ii.fixing(new Date(14, Month.December, 2013), true) + }; for (int i = 0; i < 12; i++) { if (Math.Abs(seasonalityFixing_unset[i] - seasonalityFixing_1[i]) > eps) { QAssert.Fail("UnsetSeasonality doesn't work correctly " - + seasonalityFixing_unset[i] + " vs " + seasonalityFixing_1[i]); + + seasonalityFixing_unset[i] + " vs " + seasonalityFixing_1[i]); } } @@ -533,13 +542,13 @@ public void testZeroTermStructure() Period observationLagyes = new Period(3, TimeUnit.Months); List> helpersyes = makeHelpers(zcData, zcData.Length, - iiyes, observationLagyes, calendar, bdc, dc); + iiyes, observationLagyes, calendar, bdc, dc); PiecewiseZeroInflationCurve pZITSyes = - new PiecewiseZeroInflationCurve( - evaluationDate, calendar, dc, observationLagyes, - frequency, iiyes.interpolated(), baseZeroRate, - new Handle(nominalTS), helpersyes); + new PiecewiseZeroInflationCurve( + evaluationDate, calendar, dc, observationLagyes, + frequency, iiyes.interpolated(), baseZeroRate, + new Handle(nominalTS), helpersyes); pZITSyes.recalculate(); // first check that the zero rates on the curve match the data @@ -548,18 +557,18 @@ public void testZeroTermStructure() for (int i = 0; i < zcData.Length; i++) { QAssert.IsTrue(Math.Abs(zcData[i].rate / 100.0 - - pZITSyes.zeroRate(zcData[i].date, observationLagyes, forceLinearInterpolation)) < eps, - "ZITS INTERPOLATED zeroRate != instrument " - + pZITSyes.zeroRate(zcData[i].date, observationLagyes, forceLinearInterpolation) - + " date " + zcData[i].date + " observationLagyes " + observationLagyes - + " vs " + zcData[i].rate / 100.0 - + " interpolation: " + iiyes.interpolated() - + " forceLinearInterpolation " + forceLinearInterpolation); + - pZITSyes.zeroRate(zcData[i].date, observationLagyes, forceLinearInterpolation)) < eps, + "ZITS INTERPOLATED zeroRate != instrument " + + pZITSyes.zeroRate(zcData[i].date, observationLagyes, forceLinearInterpolation) + + " date " + zcData[i].date + " observationLagyes " + observationLagyes + + " vs " + zcData[i].rate / 100.0 + + " interpolation: " + iiyes.interpolated() + + " forceLinearInterpolation " + forceLinearInterpolation); QAssert.IsTrue(Math.Abs(helpersyes[i].impliedQuote() - - zcData[i].rate / 100.0) < eps, - "ZITS INTERPOLATED implied quote != instrument " - + helpersyes[i].impliedQuote() - + " vs " + zcData[i].rate / 100.0); + - zcData[i].rate / 100.0) < eps, + "ZITS INTERPOLATED implied quote != instrument " + + helpersyes[i].impliedQuote() + + " vs " + zcData[i].rate / 100.0); } //====================================================================================== @@ -581,15 +590,16 @@ public void testZeroTermStructure() double z = hz.link.zeroRate(d, new Period(0, TimeUnit.Days)); double t = hz.link.dayCounter().yearFraction(bd, d); double calc = bf * Math.Pow(1 + z, t); - if (t <= 0) calc = iiyes.fixing(d); // still historical + if (t <= 0) + calc = iiyes.fixing(d); // still historical if (Math.Abs(calc - iiyes.fixing(d)) > eps) QAssert.Fail("ZC INTERPOLATED index does not forecast correctly for date " + d - + " from base date " + bd - + " with fixing " + bf - + ", correct: " + calc - + ", fix: " + iiyes.fixing(d) - + ", t " + t - + ", zero " + z); + + " from base date " + bd + + " with fixing " + bf + + ", correct: " + calc + + ", fix: " + iiyes.fixing(d) + + ", t " + t + + ", zero " + z); } //=========================================================================================== @@ -598,11 +608,11 @@ public void testZeroTermStructure() ZeroInflationIndex ziiyes = iiyes as ZeroInflationIndex; Utils.QL_REQUIRE(ziiyes != null, () => "dynamic_pointer_cast to ZeroInflationIndex from UKRPI-I failed"); ZeroCouponInflationSwap nzcisyes = new ZeroCouponInflationSwap(ZeroCouponInflationSwap.Type.Payer, - 1000000.0, - evaluationDate, - zcData[6].date, // end date = maturity - calendar, bdc, dc, zcData[6].rate / 100.0, // fixed rate - ziiyes, observationLagyes); + 1000000.0, + evaluationDate, + zcData[6].date, // end date = maturity + calendar, bdc, dc, zcData[6].rate / 100.0, // fixed rate + ziiyes, observationLagyes); // N.B. no coupon pricer because it is not a coupon, effect of inflation curve via // inflation curve attached to the inflation index. @@ -610,13 +620,13 @@ public void testZeroTermStructure() // ... and price it, should be zero QAssert.IsTrue(Math.Abs(nzcisyes.NPV()) < 0.00001, "ZCIS-I does not reprice to zero " - + nzcisyes.NPV() - + evaluationDate + " to " + zcData[6].date + " becoming " + nzcisyes.maturityDate() - + " rate " + zcData[6].rate - + " fixed leg " + nzcisyes.legNPV(0) - + " indexed-predicted inflated leg " + nzcisyes.legNPV(1) - + " discount " + nominalTS.discount(nzcisyes.maturityDate()) - ); + + nzcisyes.NPV() + + evaluationDate + " to " + zcData[6].date + " becoming " + nzcisyes.maturityDate() + + " rate " + zcData[6].rate + + " fixed leg " + nzcisyes.legNPV(0) + + " indexed-predicted inflated leg " + nzcisyes.legNPV(1) + + " discount " + nominalTS.discount(nzcisyes.maturityDate()) + ); // remove circular refernce hz.linkTo(null); @@ -627,9 +637,9 @@ public void testZeroTermStructure() // year on year tests, index, termstructure, and swaps //=========================================================================================== #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testYYIndex() { @@ -641,70 +651,70 @@ public void testYYIndex() YYEUHICP yyeuhicp = new YYEUHICP(true); if (yyeuhicp.name() != "EU YY_HICP" - || yyeuhicp.frequency() != Frequency.Monthly - || yyeuhicp.revised() - || !yyeuhicp.interpolated() - || yyeuhicp.ratio() - || yyeuhicp.availabilityLag() != new Period(1, TimeUnit.Months)) + || yyeuhicp.frequency() != Frequency.Monthly + || yyeuhicp.revised() + || !yyeuhicp.interpolated() + || yyeuhicp.ratio() + || yyeuhicp.availabilityLag() != new Period(1, TimeUnit.Months)) { QAssert.Fail("wrong year-on-year EU HICP data (" - + yyeuhicp.name() + ", " - + yyeuhicp.frequency() + ", " - + yyeuhicp.revised() + ", " - + yyeuhicp.interpolated() + ", " - + yyeuhicp.ratio() + ", " - + yyeuhicp.availabilityLag() + ")"); + + yyeuhicp.name() + ", " + + yyeuhicp.frequency() + ", " + + yyeuhicp.revised() + ", " + + yyeuhicp.interpolated() + ", " + + yyeuhicp.ratio() + ", " + + yyeuhicp.availabilityLag() + ")"); } YYEUHICPr yyeuhicpr = new YYEUHICPr(true); if (yyeuhicpr.name() != "EU YYR_HICP" - || yyeuhicpr.frequency() != Frequency.Monthly - || yyeuhicpr.revised() - || !yyeuhicpr.interpolated() - || !yyeuhicpr.ratio() - || yyeuhicpr.availabilityLag() != new Period(1, TimeUnit.Months)) + || yyeuhicpr.frequency() != Frequency.Monthly + || yyeuhicpr.revised() + || !yyeuhicpr.interpolated() + || !yyeuhicpr.ratio() + || yyeuhicpr.availabilityLag() != new Period(1, TimeUnit.Months)) { QAssert.Fail("wrong year-on-year EU HICPr data (" - + yyeuhicpr.name() + ", " - + yyeuhicpr.frequency() + ", " - + yyeuhicpr.revised() + ", " - + yyeuhicpr.interpolated() + ", " - + yyeuhicpr.ratio() + ", " - + yyeuhicpr.availabilityLag() + ")"); + + yyeuhicpr.name() + ", " + + yyeuhicpr.frequency() + ", " + + yyeuhicpr.revised() + ", " + + yyeuhicpr.interpolated() + ", " + + yyeuhicpr.ratio() + ", " + + yyeuhicpr.availabilityLag() + ")"); } YYUKRPI yyukrpi = new YYUKRPI(false); if (yyukrpi.name() != "UK YY_RPI" - || yyukrpi.frequency() != Frequency.Monthly - || yyukrpi.revised() - || yyukrpi.interpolated() - || yyukrpi.ratio() - || yyukrpi.availabilityLag() != new Period(1, TimeUnit.Months)) + || yyukrpi.frequency() != Frequency.Monthly + || yyukrpi.revised() + || yyukrpi.interpolated() + || yyukrpi.ratio() + || yyukrpi.availabilityLag() != new Period(1, TimeUnit.Months)) { QAssert.Fail("wrong year-on-year UK RPI data (" - + yyukrpi.name() + ", " - + yyukrpi.frequency() + ", " - + yyukrpi.revised() + ", " - + yyukrpi.interpolated() + ", " - + yyukrpi.ratio() + ", " - + yyukrpi.availabilityLag() + ")"); + + yyukrpi.name() + ", " + + yyukrpi.frequency() + ", " + + yyukrpi.revised() + ", " + + yyukrpi.interpolated() + ", " + + yyukrpi.ratio() + ", " + + yyukrpi.availabilityLag() + ")"); } YYUKRPIr yyukrpir = new YYUKRPIr(false); if (yyukrpir.name() != "UK YYR_RPI" - || yyukrpir.frequency() != Frequency.Monthly - || yyukrpir.revised() - || yyukrpir.interpolated() - || !yyukrpir.ratio() - || yyukrpir.availabilityLag() != new Period(1, TimeUnit.Months)) + || yyukrpir.frequency() != Frequency.Monthly + || yyukrpir.revised() + || yyukrpir.interpolated() + || !yyukrpir.ratio() + || yyukrpir.availabilityLag() != new Period(1, TimeUnit.Months)) { QAssert.Fail("wrong year-on-year UK RPIr data (" - + yyukrpir.name() + ", " - + yyukrpir.frequency() + ", " - + yyukrpir.revised() + ", " - + yyukrpir.interpolated() + ", " - + yyukrpir.ratio() + ", " - + yyukrpir.availabilityLag() + ")"); + + yyukrpir.name() + ", " + + yyukrpir.frequency() + ", " + + yyukrpir.revised() + ", " + + yyukrpir.interpolated() + ", " + + yyukrpir.ratio() + ", " + + yyukrpir.availabilityLag() + ")"); } // Retrieval test. @@ -723,11 +733,12 @@ public void testYYIndex() .withConvention(BusinessDayConvention.ModifiedFollowing).value(); double[] fixData = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0, - 192.2, 192.2, 192.6, 193.1, 193.3, 193.6, - 194.1, 193.4, 194.2, 195.0, 196.5, 197.7, - 198.5, 198.5, 199.2, 200.1, 200.4, 201.1, - 202.7, 201.6, 203.1, 204.4, 205.4, 206.2, - 207.3 }; + 192.2, 192.2, 192.6, 193.1, 193.3, 193.6, + 194.1, 193.4, 194.2, 195.0, 196.5, 197.7, + 198.5, 198.5, 199.2, 200.1, 200.4, 201.1, + 202.7, 201.6, 203.1, 204.4, 205.4, 206.2, + 207.3 + }; bool interp = false; YYUKRPIr iir = new YYUKRPIr(interp); @@ -758,32 +769,32 @@ public void testYYIndex() double expected = fixData[i] / fixData[i - 12] - 1.0; double calculated = iir.fixing(d); QAssert.IsTrue(Math.Abs(calculated - expected) < eps, - "Non-interpolated fixings not constant within a period: " - + calculated - + ", should be " - + expected); + "Non-interpolated fixings not constant within a period: " + + calculated + + ", should be " + + expected); double dp = lim.Value + 1 - lim.Key; double dpBef = limBef.Value + 1 - limBef.Key; double dl = d - lim.Key; // potentially does not work on 29th Feb double dlBef = new NullCalendar().advance(d, -new Period(1, TimeUnit.Years), - BusinessDayConvention.ModifiedFollowing) - limBef.Key; + BusinessDayConvention.ModifiedFollowing) - limBef.Key; double linearNow = fixData[i] + (fixData[i + 1] - fixData[i]) * dl / dp; double linearBef = fixData[i - 12] + (fixData[i + 1 - 12] - fixData[i - 12]) * dlBef / dpBef; double expectedYES = linearNow / linearBef - 1.0; double calculatedYES = iirYES.fixing(d); QAssert.IsTrue(Math.Abs(expectedYES - calculatedYES) < eps, - "Error in interpolated fixings: expect " + expectedYES - + " see " + calculatedYES - + " flat " + calculated - + ", data: " + fixData[i - 12] + ", " + fixData[i + 1 - 12] - + ", " + fixData[i] + ", " + fixData[i + 1] - + ", fac: " + dp + ", " + dl - + ", " + dpBef + ", " + dlBef - + ", to: " + linearNow + ", " + linearBef - ); + "Error in interpolated fixings: expect " + expectedYES + + " see " + calculatedYES + + " flat " + calculated + + ", data: " + fixData[i - 12] + ", " + fixData[i + 1 - 12] + + ", " + fixData[i] + ", " + fixData[i + 1] + + ", fac: " + dp + ", " + dl + + ", " + dpBef + ", " + dlBef + + ", to: " + linearNow + ", " + linearBef + ); } } } @@ -792,9 +803,9 @@ public void testYYIndex() #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testYYTermStructure() { @@ -819,11 +830,12 @@ public void testYYTermStructure() .withCalendar(new UnitedKingdom()) .withConvention(BusinessDayConvention.ModifiedFollowing).value(); double[] fixData = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0, - 192.2, 192.2, 192.6, 193.1, 193.3, 193.6, - 194.1, 193.4, 194.2, 195.0, 196.5, 197.7, - 198.5, 198.5, 199.2, 200.1, 200.4, 201.1, - 202.7, 201.6, 203.1, 204.4, 205.4, 206.2, - 207.3 }; + 192.2, 192.2, 192.6, 193.1, 193.3, 193.6, + 194.1, 193.4, 194.2, 195.0, 196.5, 197.7, + 198.5, 198.5, 199.2, 200.1, 200.4, 201.1, + 202.7, 201.6, 203.1, 204.4, 205.4, 206.2, + 207.3 + }; RelinkableHandle hy = new RelinkableHandle(); bool interp = false; @@ -836,36 +848,37 @@ public void testYYTermStructure() YieldTermStructure nominalTS = nominalTermStructure(); // now build the YoY inflation curve - Datum[] yyData = { - new Datum( new Date(13, Month.August, 2008), 2.95 ), - new Datum( new Date(13, Month.August, 2009), 2.95 ), - new Datum( new Date(13, Month.August, 2010), 2.93 ), - new Datum( new Date(15, Month.August, 2011), 2.955 ), - new Datum( new Date(13, Month.August, 2012), 2.945 ), - new Datum( new Date(13, Month.August, 2013), 2.985 ), - new Datum( new Date(13, Month.August, 2014), 3.01 ), - new Datum( new Date(13, Month.August, 2015), 3.035 ), - new Datum( new Date(13, Month.August, 2016), 3.055 ), // note that - new Datum( new Date(13, Month.August, 2017), 3.075 ), // some dates will be on - new Datum( new Date(13, Month.August, 2019), 3.105 ), // holidays but the payment - new Datum( new Date(15, Month.August, 2022), 3.135 ), // calendar will roll them - new Datum( new Date(13, Month.August, 2027), 3.155 ), - new Datum( new Date(13, Month.August, 2032), 3.145 ), - new Datum( new Date(13, Month.August, 2037), 3.145 ) - }; + Datum[] yyData = + { + new Datum(new Date(13, Month.August, 2008), 2.95), + new Datum(new Date(13, Month.August, 2009), 2.95), + new Datum(new Date(13, Month.August, 2010), 2.93), + new Datum(new Date(15, Month.August, 2011), 2.955), + new Datum(new Date(13, Month.August, 2012), 2.945), + new Datum(new Date(13, Month.August, 2013), 2.985), + new Datum(new Date(13, Month.August, 2014), 3.01), + new Datum(new Date(13, Month.August, 2015), 3.035), + new Datum(new Date(13, Month.August, 2016), 3.055), // note that + new Datum(new Date(13, Month.August, 2017), 3.075), // some dates will be on + new Datum(new Date(13, Month.August, 2019), 3.105), // holidays but the payment + new Datum(new Date(15, Month.August, 2022), 3.135), // calendar will roll them + new Datum(new Date(13, Month.August, 2027), 3.155), + new Datum(new Date(13, Month.August, 2032), 3.145), + new Datum(new Date(13, Month.August, 2037), 3.145) + }; Period observationLag = new Period(2, TimeUnit.Months); DayCounter dc = new Thirty360(); // now build the helpers ... List> helpers = - makeHelpers(yyData, yyData.Length, iir, observationLag, calendar, bdc, dc); + makeHelpers(yyData, yyData.Length, iir, observationLag, calendar, bdc, dc); double baseYYRate = yyData[0].rate / 100.0; PiecewiseYoYInflationCurve pYYTS = new PiecewiseYoYInflationCurve( - evaluationDate, calendar, dc, observationLag, - iir.frequency(), iir.interpolated(), baseYYRate, - new Handle(nominalTS), helpers); + evaluationDate, calendar, dc, observationLag, + iir.frequency(), iir.interpolated(), baseYYRate, + new Handle(nominalTS), helpers); pYYTS.recalculate(); // validation @@ -904,13 +917,13 @@ public void testYYTermStructure() yyS2.setPricingEngine(sppe); QAssert.IsTrue(Math.Abs(yyS2.NPV()) < eps, "fresh yoy swap NPV!=0 from TS " - + "swap quote for pt " + j - + ", is " + yyData[j].rate / 100.0 - + " vs YoY rate " + pYYTS.yoyRate(yyData[j].date - observationLag) - + " at quote date " + (yyData[j].date - observationLag) - + ", NPV of a fresh yoy swap is " + yyS2.NPV() - + "\n fair rate " + yyS2.fairRate() - + " payment " + yyS2.paymentConvention()); + + "swap quote for pt " + j + + ", is " + yyData[j].rate / 100.0 + + " vs YoY rate " + pYYTS.yoyRate(yyData[j].date - observationLag) + + " at quote date " + (yyData[j].date - observationLag) + + ", NPV of a fresh yoy swap is " + yyS2.NPV() + + "\n fair rate " + yyS2.fairRate() + + " payment " + yyS2.paymentConvention()); } int jj = 3; @@ -940,10 +953,10 @@ public void testYYTermStructure() yyS3.setPricingEngine(sppe); QAssert.IsTrue(Math.Abs(yyS3.NPV()) < 20000.0, - "unexpected size of aged YoY swap, aged " - + k + " months: YY aged NPV = " + yyS3.NPV() - + ", legs " + yyS3.legNPV(0) + " and " + yyS3.legNPV(1) - ); + "unexpected size of aged YoY swap, aged " + + k + " months: YY aged NPV = " + yyS3.NPV() + + ", legs " + yyS3.legNPV(0) + " and " + yyS3.legNPV(1) + ); } // remove circular refernce hy.linkTo(null); diff --git a/tests/QLNet.Tests/T_InflationCPICapFloor.cs b/tests/QLNet.Tests/T_InflationCPICapFloor.cs index 5e3aa046f..ecc7fdf6a 100644 --- a/tests/QLNet.Tests/T_InflationCPICapFloor.cs +++ b/tests/QLNet.Tests/T_InflationCPICapFloor.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -18,7 +18,7 @@ #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -34,29 +34,29 @@ internal struct Datum public Date date; public double rate; - public Datum( Date d, double r ) + public Datum(Date d, double r) { date = d; rate = r; } } - private class CommonVars + private class CommonVars { - private List> makeHelpers( Datum[] iiData, int N, - ZeroInflationIndex ii, Period observationLag, - Calendar calendar, - BusinessDayConvention bdc, - DayCounter dc ) + private List> makeHelpers(Datum[] iiData, int N, + ZeroInflationIndex ii, Period observationLag, + Calendar calendar, + BusinessDayConvention bdc, + DayCounter dc) { List> instruments = new List>(); - for ( int i = 0; i < N; i++ ) + for (int i = 0; i < N; i++) { Date maturity = iiData[i].date; - Handle quote = new Handle( new SimpleQuote( iiData[i].rate / 100.0 ) ); - BootstrapHelper anInstrument = new ZeroCouponInflationSwapHelper( quote, observationLag, maturity, - calendar, bdc, dc, ii ); - instruments.Add( anInstrument ); + Handle quote = new Handle(new SimpleQuote(iiData[i].rate / 100.0)); + BootstrapHelper anInstrument = new ZeroCouponInflationSwapHelper(quote, observationLag, maturity, + calendar, bdc, dc, ii); + instruments.Add(anInstrument); } return instruments; } @@ -111,7 +111,7 @@ public CommonVars() zciisR = new List(); hii = new RelinkableHandle(); - nominals = new InitializedList(1,1000000); + nominals = new InitializedList(1, 1000000); // option variables frequency = Frequency.Annual; // usual setup @@ -124,7 +124,7 @@ public CommonVars() Settings.setEvaluationDate(evaluationDate); settlementDays = 0; fixingDays = 0; - settlement = calendar.advance(today,settlementDays,TimeUnit.Days); + settlement = calendar.advance(today, settlementDays, TimeUnit.Days); startDate = settlement; dcZCIIS = new ActualActual(); dcNominal = new ActualActual(); @@ -134,102 +134,104 @@ public CommonVars() Date from = new Date(1, Month.July, 2007); Date to = new Date(1, Month.June, 2010); Schedule rpiSchedule = new MakeSchedule().from(from).to(to) - .withTenor(new Period(1,TimeUnit.Months)) + .withTenor(new Period(1, TimeUnit.Months)) .withCalendar(new UnitedKingdom()) .withConvention(BusinessDayConvention.ModifiedFollowing).value(); - double[] fixData = { - 206.1, 207.3, 208.0, 208.9, 209.7, 210.9, - 209.8, 211.4, 212.1, 214.0, 215.1, 216.8, // 2008 - 216.5, 217.2, 218.4, 217.7, 216.0, 212.9, - 210.1, 211.4, 211.3, 211.5, 212.8, 213.4, // 2009 - 213.4, 214.4, 215.3, 216.0, 216.6, 218.0, - 217.9, 219.2, 220.7, 222.8, -999, -999, // 2010 - -999}; + double[] fixData = + { + 206.1, 207.3, 208.0, 208.9, 209.7, 210.9, + 209.8, 211.4, 212.1, 214.0, 215.1, 216.8, // 2008 + 216.5, 217.2, 218.4, 217.7, 216.0, 212.9, + 210.1, 211.4, 211.3, 211.5, 212.8, 213.4, // 2009 + 213.4, 214.4, 215.3, 216.0, 216.6, 218.0, + 217.9, 219.2, 220.7, 222.8, -999, -999, // 2010 + -999 + }; // link from cpi index to cpi TS bool interp = false;// this MUST be false because the observation lag is only 2 months - // for ZCIIS; but not for contract if the contract uses a bigger lag. + // for ZCIIS; but not for contract if the contract uses a bigger lag. ii = new UKRPI(interp, hcpi); - for (int i=0; i nomD = new List(); List nomR = new List(); - for (int i = 0; i < nominalDataLength; i++) + for (int i = 0; i < nominalDataLength; i++) { nomD.Add(nominalData[i].date); - nomR.Add(nominalData[i].rate/100.0); + nomR.Add(nominalData[i].rate / 100.0); } - YieldTermStructure nominalTS = new InterpolatedZeroCurve(nomD,nomR,dcNominal); + YieldTermStructure nominalTS = new InterpolatedZeroCurve(nomD, nomR, dcNominal); nominalUK.linkTo(nominalTS); // now build the zero inflation curve - observationLag = new Period(2,TimeUnit.Months); - contractObservationLag = new Period(3,TimeUnit.Months); + observationLag = new Period(2, TimeUnit.Months); + contractObservationLag = new Period(3, TimeUnit.Months); contractObservationInterpolation = InterpolationType.Flat; - Datum[] zciisData = + Datum[] zciisData = { - new Datum( new Date(1, Month.June, 2011), 3.087 ), - new Datum( new Date(1, Month.June, 2012), 3.12 ), - new Datum( new Date(1, Month.June, 2013), 3.059 ), - new Datum( new Date(1, Month.June, 2014), 3.11 ), - new Datum( new Date(1, Month.June, 2015), 3.15 ), - new Datum( new Date(1, Month.June, 2016), 3.207 ), - new Datum( new Date(1, Month.June, 2017), 3.253 ), - new Datum( new Date(1, Month.June, 2018), 3.288 ), - new Datum( new Date(1, Month.June, 2019), 3.314 ), - new Datum( new Date(1, Month.June, 2020), 3.401 ), - new Datum( new Date(1, Month.June, 2022), 3.458 ), - new Datum( new Date(1, Month.June, 2025), 3.52 ), - new Datum( new Date(1, Month.June, 2030), 3.655 ), - new Datum( new Date(1, Month.June, 2035), 3.668 ), - new Datum( new Date(1, Month.June, 2040), 3.695 ), - new Datum( new Date(1, Month.June, 2050), 3.634 ), - new Datum( new Date(1, Month.June, 2060), 3.629 ), + new Datum(new Date(1, Month.June, 2011), 3.087), + new Datum(new Date(1, Month.June, 2012), 3.12), + new Datum(new Date(1, Month.June, 2013), 3.059), + new Datum(new Date(1, Month.June, 2014), 3.11), + new Datum(new Date(1, Month.June, 2015), 3.15), + new Datum(new Date(1, Month.June, 2016), 3.207), + new Datum(new Date(1, Month.June, 2017), 3.253), + new Datum(new Date(1, Month.June, 2018), 3.288), + new Datum(new Date(1, Month.June, 2019), 3.314), + new Datum(new Date(1, Month.June, 2020), 3.401), + new Datum(new Date(1, Month.June, 2022), 3.458), + new Datum(new Date(1, Month.June, 2025), 3.52), + new Datum(new Date(1, Month.June, 2030), 3.655), + new Datum(new Date(1, Month.June, 2035), 3.668), + new Datum(new Date(1, Month.June, 2040), 3.695), + new Datum(new Date(1, Month.June, 2050), 3.634), + new Datum(new Date(1, Month.June, 2060), 3.629), }; zciisDataLength = 17; - for (int i = 0; i < zciisDataLength; i++) + for (int i = 0; i < zciisDataLength; i++) { zciisD.Add(zciisData[i].date); zciisR.Add(zciisData[i].rate); @@ -237,13 +239,13 @@ public CommonVars() // now build the helpers ... List > helpers = makeHelpers(zciisData, zciisDataLength, ii, - observationLag,calendar, convention, dcZCIIS); + observationLag, calendar, convention, dcZCIIS); // we can use historical or first ZCIIS for this // we know historical is WAY off market-implied, so use market implied flat. - baseZeroRate = zciisData[0].rate/100.0; + baseZeroRate = zciisData[0].rate / 100.0; PiecewiseZeroInflationCurve pCPIts = new PiecewiseZeroInflationCurve( - evaluationDate, calendar, dcZCIIS, observationLag,ii.frequency(),ii.interpolated(), baseZeroRate, + evaluationDate, calendar, dcZCIIS, observationLag, ii.frequency(), ii.interpolated(), baseZeroRate, new Handle(nominalTS), helpers); pCPIts.recalculate(); cpiUK.linkTo(pCPIts); @@ -253,18 +255,19 @@ public CommonVars() hcpi.linkTo(pCPIts); // cpi CF price surf data - Period[] cfMat = {new Period(3,TimeUnit.Years), - new Period(5,TimeUnit.Years), - new Period(7,TimeUnit.Years), - new Period(10,TimeUnit.Years), - new Period(15,TimeUnit.Years), - new Period(20,TimeUnit.Years), - new Period(30,TimeUnit.Years) }; + Period[] cfMat = {new Period(3, TimeUnit.Years), + new Period(5, TimeUnit.Years), + new Period(7, TimeUnit.Years), + new Period(10, TimeUnit.Years), + new Period(15, TimeUnit.Years), + new Period(20, TimeUnit.Years), + new Period(30, TimeUnit.Years) + }; double[] cStrike = {3, 4, 5, 6}; double[] fStrike = {-1, 0, 1, 2}; int ncStrikes = 4, nfStrikes = 4, ncfMaturities = 7; - double[][] cPrice = + double[][] cPrice = { new double[4] {227.6, 100.27, 38.8, 14.94}, new double[4] {345.32, 127.9, 40.59, 14.11}, @@ -275,7 +278,7 @@ public CommonVars() new double[4] {2211.67, 839.24, 184.75, 45.03} }; - double[][] fPrice = + double[][] fPrice = { new double[4] {15.62, 28.38, 53.61, 104.6}, new double[4] {21.45, 36.73, 66.66, 129.6}, @@ -288,36 +291,39 @@ public CommonVars() // now load the data into vector and Matrix classes cStrikesUK = new List(); - fStrikesUK = new List(); + fStrikesUK = new List(); cfMaturitiesUK = new List(); - for(int i = 0; i < ncStrikes; i++) cStrikesUK.Add(cStrike[i]); - for(int i = 0; i < nfStrikes; i++) fStrikesUK.Add(fStrike[i]); - for(int i = 0; i < ncfMaturities; i++) cfMaturitiesUK.Add(cfMat[i]); + for (int i = 0; i < ncStrikes; i++) + cStrikesUK.Add(cStrike[i]); + for (int i = 0; i < nfStrikes; i++) + fStrikesUK.Add(fStrike[i]); + for (int i = 0; i < ncfMaturities; i++) + cfMaturitiesUK.Add(cfMat[i]); cPriceUK = new Matrix(ncStrikes, ncfMaturities); fPriceUK = new Matrix(nfStrikes, ncfMaturities); - for(int i = 0; i < ncStrikes; i++) + for (int i = 0; i < ncStrikes; i++) { - for(int j = 0; j < ncfMaturities; j++) + for (int j = 0; j < ncfMaturities; j++) { - (cPriceUK)[i,j] = cPrice[j][i]/10000.0; + (cPriceUK)[i, j] = cPrice[j][i] / 10000.0; } } - for(int i = 0; i < nfStrikes; i++) + for (int i = 0; i < nfStrikes; i++) { - for(int j = 0; j < ncfMaturities; j++) + for (int j = 0; j < ncfMaturities; j++) { - (fPriceUK)[i,j] = fPrice[j][i]/10000.0; + (fPriceUK)[i, j] = fPrice[j][i] / 10000.0; } } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void cpicapfloorpricesurface() + public void cpicapfloorpricesurface() { // check inflation leg vs calculation directly from inflation TS CommonVars common = new CommonVars(); @@ -339,34 +345,34 @@ public void cpicapfloorpricesurface() common.fPriceUK); // test code - note order of indices - for (int i =0; i "cannot reproduce cpi floor data from surface: " - + a + " vs constructed = " + b); + Utils.QL_REQUIRE(Math.Abs(a - b) < 1e-7, () => "cannot reproduce cpi floor data from surface: " + + a + " vs constructed = " + b); } } - for (int i =0; i. - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,7 +21,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -31,22 +31,22 @@ namespace TestSuite [TestClass()] #endif public class T_InflationCapFloorTest : IDisposable - { + { #region Initialize&Cleanup private SavedSettings backup; - #if NET40 || NET45 +#if NET40 || NET45 [TestInitialize] public void testInitialize() { - #else +#else public T_InflationCapFloorTest() { - #endif +#endif backup = new SavedSettings(); } - #if NET40 || NET45 +#if NET40 || NET45 [TestCleanup] - #endif +#endif public void testCleanup() { Dispose(); @@ -57,483 +57,491 @@ public void Dispose() } #endregion - class CommonVars - { - // common data - - public Frequency frequency; - public List nominals; - public Calendar calendar; - public BusinessDayConvention convention; - public int fixingDays; - public Date evaluationDate; - public int settlementDays; - public Date settlement; - public Period observationLag = new Period(0,TimeUnit.Months); - public DayCounter dc; - public YYUKRPIr iir; - - public RelinkableHandle nominalTS = new RelinkableHandle(); - public YoYInflationTermStructure yoyTS; - public RelinkableHandle hy = new RelinkableHandle(); - - // setup - public CommonVars() - { - // option variables - nominals = new List{1000000}; - frequency = Frequency.Annual; - // usual setup - calendar = new UnitedKingdom(); - convention = BusinessDayConvention.ModifiedFollowing; - Date today = new Date(13, Month.August, 2007); - evaluationDate = calendar.adjust(today); - Settings.setEvaluationDate(evaluationDate); - settlementDays = 0; - fixingDays = 0; - settlement = calendar.advance(today,settlementDays,TimeUnit.Days); - dc = new Thirty360(); - - // yoy index - // fixing data - Date from = new Date(1, Month.January, 2005); - Date to = new Date(13, Month.August, 2007); - Schedule rpiSchedule = new MakeSchedule().from(from).to(to) - .withConvention(BusinessDayConvention.ModifiedFollowing) - .withCalendar(new UnitedKingdom()) - .withTenor(new Period(1,TimeUnit.Months)).value(); - double[] fixData = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0, - 192.2, 192.2, 192.6, 193.1, 193.3, 193.6, - 194.1, 193.4, 194.2, 195.0, 196.5, 197.7, - 198.5, 198.5, 199.2, 200.1, 200.4, 201.1, - 202.7, 201.6, 203.1, 204.4, 205.4, 206.2, - 207.3, -999.0, -999 }; - // link from yoy index to yoy TS - bool interp = false; - iir = new YYUKRPIr(interp, hy); - for (int i=0; i> helpers = - makeHelpers(yyData, yyData.Length, iir, - observationLag, - calendar, convention, dc); - - double baseYYRate = yyData[0].rate/100.0; - PiecewiseYoYInflationCurve pYYTS = - new PiecewiseYoYInflationCurve( - evaluationDate, calendar, dc, observationLag, - iir.frequency(),iir.interpolated(), baseYYRate, - new Handle(nominalTS), helpers); - pYYTS.recalculate(); - yoyTS = pYYTS as YoYInflationTermStructure; - - - // make sure that the index has the latest yoy term structure - hy.linkTo(pYYTS); - } - - // utilities - public List makeYoYLeg(Date startDate, int length) - { - YoYInflationIndex ii = iir as YoYInflationIndex; - Date endDate = calendar.advance(startDate,new Period(length,TimeUnit.Years),BusinessDayConvention.Unadjusted); - Schedule schedule = new Schedule(startDate, endDate, new Period(frequency), calendar, - BusinessDayConvention.Unadjusted, - BusinessDayConvention.Unadjusted,// ref periods & acc periods - DateGeneration.Rule.Forward, false); - return new yoyInflationLeg( schedule, calendar, ii, observationLag ) - .withPaymentDayCounter(dc) - .withNotionals(nominals) - .withPaymentAdjustment(convention); - } - - - public IPricingEngine makeEngine(double volatility,int which) - { - - YoYInflationIndex yyii = iir as YoYInflationIndex; - - Handle vol = - new Handle(new ConstantYoYOptionletVolatility(volatility, - settlementDays, - calendar, - convention, - dc, - observationLag, - frequency, - iir.interpolated())); - - - switch (which) { - case 0: - return new YoYInflationBlackCapFloorEngine(iir, vol); - //break; - case 1: - return new YoYInflationUnitDisplacedBlackCapFloorEngine(iir, vol); - //break; - case 2: - return new YoYInflationBachelierCapFloorEngine(iir, vol); - //break; - default: - QAssert.Fail("unknown engine request: which = "+which - +"should be 0=Black,1=DD,2=Bachelier"); - break; - } - // make compiler happy - Utils.QL_FAIL("never get here - no engine resolution"); - return null; - } - - - public YoYInflationCapFloor makeYoYCapFloor(CapFloorType type, - List leg, - double strike, - double volatility, - int which) - { - YoYInflationCapFloor result = null; - switch (type) - { - case CapFloorType.Cap: - result = new YoYInflationCap(leg, new List(){strike}); - break; - case CapFloorType.Floor: - result = new YoYInflationFloor( leg, new List() { strike } ); - break; - default: - Utils.QL_FAIL("unknown YoYInflation cap/floor type"); - break; - } - result.setPricingEngine(makeEngine(volatility, which)); - return result; - } - - - private List> makeHelpers( Datum[] iiData, int N, - YoYInflationIndex ii, Period observationLag, - Calendar calendar, - BusinessDayConvention bdc, - DayCounter dc ) - { - List> instruments = new List>(); - for ( int i = 0; i < N; i++ ) - { - Date maturity = iiData[i].date; - Handle quote = new Handle( new SimpleQuote( iiData[i].rate / 100.0 ) ); - BootstrapHelper anInstrument = new YearOnYearInflationSwapHelper( quote, observationLag, maturity, - calendar, bdc, dc, ii ); - instruments.Add( anInstrument ); - } - return instruments; - } - } + class CommonVars + { + // common data + + public Frequency frequency; + public List nominals; + public Calendar calendar; + public BusinessDayConvention convention; + public int fixingDays; + public Date evaluationDate; + public int settlementDays; + public Date settlement; + public Period observationLag = new Period(0, TimeUnit.Months); + public DayCounter dc; + public YYUKRPIr iir; + + public RelinkableHandle nominalTS = new RelinkableHandle(); + public YoYInflationTermStructure yoyTS; + public RelinkableHandle hy = new RelinkableHandle(); + + // setup + public CommonVars() + { + // option variables + nominals = new List {1000000}; + frequency = Frequency.Annual; + // usual setup + calendar = new UnitedKingdom(); + convention = BusinessDayConvention.ModifiedFollowing; + Date today = new Date(13, Month.August, 2007); + evaluationDate = calendar.adjust(today); + Settings.setEvaluationDate(evaluationDate); + settlementDays = 0; + fixingDays = 0; + settlement = calendar.advance(today, settlementDays, TimeUnit.Days); + dc = new Thirty360(); + + // yoy index + // fixing data + Date from = new Date(1, Month.January, 2005); + Date to = new Date(13, Month.August, 2007); + Schedule rpiSchedule = new MakeSchedule().from(from).to(to) + .withConvention(BusinessDayConvention.ModifiedFollowing) + .withCalendar(new UnitedKingdom()) + .withTenor(new Period(1, TimeUnit.Months)).value(); + double[] fixData = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0, + 192.2, 192.2, 192.6, 193.1, 193.3, 193.6, + 194.1, 193.4, 194.2, 195.0, 196.5, 197.7, + 198.5, 198.5, 199.2, 200.1, 200.4, 201.1, + 202.7, 201.6, 203.1, 204.4, 205.4, 206.2, + 207.3, -999.0, -999 + }; + // link from yoy index to yoy TS + bool interp = false; + iir = new YYUKRPIr(interp, hy); + for (int i = 0; i < rpiSchedule.Count; i++) + { + iir.addFixing(rpiSchedule[i], fixData[i]); + } + + YieldTermStructure nominalFF = new FlatForward(evaluationDate, 0.05, new ActualActual()); + nominalTS.linkTo(nominalFF); + + // now build the YoY inflation curve + Period observationLag = new Period(2, TimeUnit.Months); + + Datum[] yyData = + { + new Datum(new Date(13, Month.August, 2008), 2.95), + new Datum(new Date(13, Month.August, 2009), 2.95), + new Datum(new Date(13, Month.August, 2010), 2.93), + new Datum(new Date(15, Month.August, 2011), 2.955), + new Datum(new Date(13, Month.August, 2012), 2.945), + new Datum(new Date(13, Month.August, 2013), 2.985), + new Datum(new Date(13, Month.August, 2014), 3.01), + new Datum(new Date(13, Month.August, 2015), 3.035), + new Datum(new Date(13, Month.August, 2016), 3.055), // note that + new Datum(new Date(13, Month.August, 2017), 3.075), // some dates will be on + new Datum(new Date(13, Month.August, 2019), 3.105), // holidays but the payment + new Datum(new Date(15, Month.August, 2022), 3.135), // calendar will roll them + new Datum(new Date(13, Month.August, 2027), 3.155), + new Datum(new Date(13, Month.August, 2032), 3.145), + new Datum(new Date(13, Month.August, 2037), 3.145) + }; + + // now build the helpers ... + List> helpers = + makeHelpers(yyData, yyData.Length, iir, + observationLag, + calendar, convention, dc); + + double baseYYRate = yyData[0].rate / 100.0; + PiecewiseYoYInflationCurve pYYTS = + new PiecewiseYoYInflationCurve( + evaluationDate, calendar, dc, observationLag, + iir.frequency(), iir.interpolated(), baseYYRate, + new Handle(nominalTS), helpers); + pYYTS.recalculate(); + yoyTS = pYYTS as YoYInflationTermStructure; + + + // make sure that the index has the latest yoy term structure + hy.linkTo(pYYTS); + } + + // utilities + public List makeYoYLeg(Date startDate, int length) + { + YoYInflationIndex ii = iir as YoYInflationIndex; + Date endDate = calendar.advance(startDate, new Period(length, TimeUnit.Years), BusinessDayConvention.Unadjusted); + Schedule schedule = new Schedule(startDate, endDate, new Period(frequency), calendar, + BusinessDayConvention.Unadjusted, + BusinessDayConvention.Unadjusted,// ref periods & acc periods + DateGeneration.Rule.Forward, false); + return new yoyInflationLeg(schedule, calendar, ii, observationLag) + .withPaymentDayCounter(dc) + .withNotionals(nominals) + .withPaymentAdjustment(convention); + } + + + public IPricingEngine makeEngine(double volatility, int which) + { + + YoYInflationIndex yyii = iir as YoYInflationIndex; + + Handle vol = + new Handle(new ConstantYoYOptionletVolatility(volatility, + settlementDays, + calendar, + convention, + dc, + observationLag, + frequency, + iir.interpolated())); + + + switch (which) + { + case 0: + return new YoYInflationBlackCapFloorEngine(iir, vol); + //break; + case 1: + return new YoYInflationUnitDisplacedBlackCapFloorEngine(iir, vol); + //break; + case 2: + return new YoYInflationBachelierCapFloorEngine(iir, vol); + //break; + default: + QAssert.Fail("unknown engine request: which = " + which + + "should be 0=Black,1=DD,2=Bachelier"); + break; + } + // make compiler happy + Utils.QL_FAIL("never get here - no engine resolution"); + return null; + } + + + public YoYInflationCapFloor makeYoYCapFloor(CapFloorType type, + List leg, + double strike, + double volatility, + int which) + { + YoYInflationCapFloor result = null; + switch (type) + { + case CapFloorType.Cap: + result = new YoYInflationCap(leg, new List() {strike}); + break; + case CapFloorType.Floor: + result = new YoYInflationFloor(leg, new List() { strike }); + break; + default: + Utils.QL_FAIL("unknown YoYInflation cap/floor type"); + break; + } + result.setPricingEngine(makeEngine(volatility, which)); + return result; + } + + + private List> makeHelpers(Datum[] iiData, int N, + YoYInflationIndex ii, Period observationLag, + Calendar calendar, + BusinessDayConvention bdc, + DayCounter dc) + { + List> instruments = new List>(); + for (int i = 0; i < N; i++) + { + Date maturity = iiData[i].date; + Handle quote = new Handle(new SimpleQuote(iiData[i].rate / 100.0)); + BootstrapHelper anInstrument = new YearOnYearInflationSwapHelper(quote, observationLag, maturity, + calendar, bdc, dc, ii); + instruments.Add(anInstrument); + } + return instruments; + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testConsistency() - { - // Testing consistency between yoy inflation cap,floor and collar... - CommonVars vars = new CommonVars(); - - int[] lengths = { 1, 2, 3, 5, 7, 10, 15, 20 }; - double[] cap_rates = { 0.01, 0.025, 0.029, 0.03, 0.031, 0.035, 0.07 }; - double[] floor_rates = { 0.01, 0.025, 0.029, 0.03, 0.031, 0.035, 0.07 }; - double[] vols = { 0.001, 0.005, 0.010, 0.015, 0.020 }; - - for (int whichPricer = 0; whichPricer < 3; whichPricer++) - { - for (int i=0; i leg = vars.makeYoYLeg(vars.evaluationDate,lengths[i]); - - YoYInflationCapFloor cap = vars.makeYoYCapFloor(CapFloorType.Cap, - leg, cap_rates[j], vols[l], whichPricer); - - YoYInflationCapFloor floor = vars.makeYoYCapFloor(CapFloorType.Floor, - leg, floor_rates[k], vols[l], whichPricer); - - YoYInflationCollar collar = new YoYInflationCollar(leg,new List(){cap_rates[j]}, - new List(){floor_rates[k]}); - - collar.setPricingEngine(vars.makeEngine(vols[l], whichPricer)); - - if (Math.Abs((cap.NPV()-floor.NPV())-collar.NPV()) > 1e-6) - { - QAssert.Fail( - "inconsistency between cap, floor and collar:\n" - + " length: " + lengths[i] + " years\n" - + " volatility: " + "\n" - + " cap value: " + cap.NPV() - + " at strike: " + "\n" - + " floor value: " + floor.NPV() - + " at strike: " + "\n" - + " collar value: " + collar.NPV()); - - } - // test re-composition by optionlets, N.B. ONE per year - double capletsNPV = 0.0; - List caplets = new List(); - for (int m=0; m 1e-6) - { - QAssert.Fail( - "sum of caplet NPVs does not equal cap NPV:\n" - + " length: " + lengths[i] + " years\n" - + " volatility: " + "\n" - + " cap value: " + cap.NPV() - + " at strike: " + "\n" - + " sum of caplets value: " + capletsNPV - + " at strike (first): " + caplets[0].capRates()[0] + "\n" - ); - } - - double floorletsNPV = 0.0; - List floorlets = new List(); - for (int m=0; m 1e-6) - { - QAssert.Fail( - "sum of floorlet NPVs does not equal floor NPV:\n" - + " length: " + lengths[i] + " years\n" - + " volatility: " + "\n" - + " cap value: " + floor.NPV() - + " at strike: " + floor_rates[j] + "\n" - + " sum of floorlets value: " + floorletsNPV - + " at strike (first): " + floorlets[0].floorRates()[0] + "\n" - ); - } - - double collarletsNPV = 0.0; - List collarlets = new List(); - for (int m=0; m 1e-6) - { - QAssert.Fail( - "sum of collarlet NPVs does not equal floor NPV:\n" - + " length: " + lengths[i] + " years\n" - + " volatility: " + vols[l] + "\n" - + " cap value: " + collar.NPV() - + " at strike floor: " + floor_rates[j] - + " at strike cap: " + cap_rates[j] + "\n" - + " sum of collarlets value: " + collarletsNPV - + " at strike floor (first): " + collarlets[0].floorRates()[0] - + " at strike cap (first): " + collarlets[0].capRates()[0] + "\n" - ); - } - } - } - } - } - } // pricer loop - // remove circular refernce - vars.hy.linkTo(null); - } - - // Test inflation cap/floor parity, i.e. that cap-floor = swap, note that this - // is different from nominal because in nominal world standard cap/floors do - // not have the first optionlet. This is because they set in advance so - // there is no point. However, yoy inflation generally sets in arrears, - // (actually in arrears with a lag of a few months) thus the first optionlet - // is relevant. Hence we can do a parity test without a special definition - // of the YoY cap/floor instrument. + public void testConsistency() + { + // Testing consistency between yoy inflation cap,floor and collar... + CommonVars vars = new CommonVars(); + + int[] lengths = { 1, 2, 3, 5, 7, 10, 15, 20 }; + double[] cap_rates = { 0.01, 0.025, 0.029, 0.03, 0.031, 0.035, 0.07 }; + double[] floor_rates = { 0.01, 0.025, 0.029, 0.03, 0.031, 0.035, 0.07 }; + double[] vols = { 0.001, 0.005, 0.010, 0.015, 0.020 }; + + for (int whichPricer = 0; whichPricer < 3; whichPricer++) + { + for (int i = 0; i < lengths.Length; i++) + { + for (int j = 0; j < cap_rates.Length; j++) + { + for (int k = 0; k < floor_rates.Length; k++) + { + for (int l = 0; l < vols.Length; l++) + { + + List leg = vars.makeYoYLeg(vars.evaluationDate, lengths[i]); + + YoYInflationCapFloor cap = vars.makeYoYCapFloor(CapFloorType.Cap, + leg, cap_rates[j], vols[l], whichPricer); + + YoYInflationCapFloor floor = vars.makeYoYCapFloor(CapFloorType.Floor, + leg, floor_rates[k], vols[l], whichPricer); + + YoYInflationCollar collar = new YoYInflationCollar(leg, new List() {cap_rates[j]}, + new List() {floor_rates[k]}); + + collar.setPricingEngine(vars.makeEngine(vols[l], whichPricer)); + + if (Math.Abs((cap.NPV() - floor.NPV()) - collar.NPV()) > 1e-6) + { + QAssert.Fail( + "inconsistency between cap, floor and collar:\n" + + " length: " + lengths[i] + " years\n" + + " volatility: " + "\n" + + " cap value: " + cap.NPV() + + " at strike: " + "\n" + + " floor value: " + floor.NPV() + + " at strike: " + "\n" + + " collar value: " + collar.NPV()); + + } + // test re-composition by optionlets, N.B. ONE per year + double capletsNPV = 0.0; + List caplets = new List(); + for (int m = 0; m < lengths[i] * 1; m++) + { + caplets.Add(cap.optionlet(m)); + caplets[m].setPricingEngine(vars.makeEngine(vols[l], whichPricer)); + capletsNPV += caplets[m].NPV(); + } + + if (Math.Abs(cap.NPV() - capletsNPV) > 1e-6) + { + QAssert.Fail( + "sum of caplet NPVs does not equal cap NPV:\n" + + " length: " + lengths[i] + " years\n" + + " volatility: " + "\n" + + " cap value: " + cap.NPV() + + " at strike: " + "\n" + + " sum of caplets value: " + capletsNPV + + " at strike (first): " + caplets[0].capRates()[0] + "\n" + ); + } + + double floorletsNPV = 0.0; + List floorlets = new List(); + for (int m = 0; m < lengths[i] * 1; m++) + { + floorlets.Add(floor.optionlet(m)); + floorlets[m].setPricingEngine(vars.makeEngine(vols[l], whichPricer)); + floorletsNPV += floorlets[m].NPV(); + } + + if (Math.Abs(floor.NPV() - floorletsNPV) > 1e-6) + { + QAssert.Fail( + "sum of floorlet NPVs does not equal floor NPV:\n" + + " length: " + lengths[i] + " years\n" + + " volatility: " + "\n" + + " cap value: " + floor.NPV() + + " at strike: " + floor_rates[j] + "\n" + + " sum of floorlets value: " + floorletsNPV + + " at strike (first): " + floorlets[0].floorRates()[0] + "\n" + ); + } + + double collarletsNPV = 0.0; + List collarlets = new List(); + for (int m = 0; m < lengths[i] * 1; m++) + { + collarlets.Add(collar.optionlet(m)); + collarlets[m].setPricingEngine(vars.makeEngine(vols[l], whichPricer)); + collarletsNPV += collarlets[m].NPV(); + } + + if (Math.Abs(collar.NPV() - collarletsNPV) > 1e-6) + { + QAssert.Fail( + "sum of collarlet NPVs does not equal floor NPV:\n" + + " length: " + lengths[i] + " years\n" + + " volatility: " + vols[l] + "\n" + + " cap value: " + collar.NPV() + + " at strike floor: " + floor_rates[j] + + " at strike cap: " + cap_rates[j] + "\n" + + " sum of collarlets value: " + collarletsNPV + + " at strike floor (first): " + collarlets[0].floorRates()[0] + + " at strike cap (first): " + collarlets[0].capRates()[0] + "\n" + ); + } + } + } + } + } + } // pricer loop + // remove circular refernce + vars.hy.linkTo(null); + } + + // Test inflation cap/floor parity, i.e. that cap-floor = swap, note that this + // is different from nominal because in nominal world standard cap/floors do + // not have the first optionlet. This is because they set in advance so + // there is no point. However, yoy inflation generally sets in arrears, + // (actually in arrears with a lag of a few months) thus the first optionlet + // is relevant. Hence we can do a parity test without a special definition + // of the YoY cap/floor instrument. #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testParity() - { - - // Testing yoy inflation cap/floor parity... - - CommonVars vars = new CommonVars(); - - int[] lengths = { 1, 2, 3, 5, 7, 10, 15, 20 }; - // vol is low ... - double[] strikes = { 0.0, 0.025, 0.029, 0.03, 0.031, 0.035, 0.07 }; - // yoy inflation vol is generally very low - double[] vols = { 0.001, 0.005, 0.010, 0.015, 0.020 }; - - // cap-floor-swap parity is model-independent - for (int whichPricer = 0; whichPricer < 3; whichPricer++) { - for (int i=0; i leg = vars.makeYoYLeg(vars.evaluationDate,lengths[i]); - - Instrument cap = vars.makeYoYCapFloor(CapFloorType.Cap, - leg, strikes[j], vols[k], whichPricer); - - Instrument floor = vars.makeYoYCapFloor(CapFloorType.Floor, - leg, strikes[j], vols[k], whichPricer); - - Date from = vars.nominalTS.link.referenceDate(); - Date to = from+new Period(lengths[i],TimeUnit.Years); - Schedule yoySchedule = new MakeSchedule().from(from).to(to) - .withTenor(new Period(1,TimeUnit.Years)) - .withConvention(BusinessDayConvention.Unadjusted) - .withCalendar(new UnitedKingdom()).backwards().value(); - - YearOnYearInflationSwap swap = new YearOnYearInflationSwap - (YearOnYearInflationSwap.Type.Payer, - 1000000.0, - yoySchedule,//fixed schedule, but same as yoy - strikes[j], - vars.dc, - yoySchedule, - vars.iir, - vars.observationLag, - 0.0, //spread on index - vars.dc, - new UnitedKingdom()); - - Handle hTS = new Handle(vars.nominalTS); - IPricingEngine sppe = new DiscountingSwapEngine(hTS); - swap.setPricingEngine(sppe); - - // N.B. nominals are 10e6 - if (Math.Abs((cap.NPV()-floor.NPV()) - swap.NPV()) > 1.0e-6) { - QAssert.Fail( - "put/call parity violated:\n" - + " length: " + lengths[i] + " years\n" - + " volatility: " + vols[k] + "\n" - + " strike: " + strikes[j] + "\n" - + " cap value: " + cap.NPV() + "\n" - + " floor value: " + floor.NPV() + "\n" - + " swap value: " + swap.NPV()); - } - } - } - } - } - // remove circular refernce - vars.hy.linkTo(null); - } + public void testParity() + { + + // Testing yoy inflation cap/floor parity... + + CommonVars vars = new CommonVars(); + + int[] lengths = { 1, 2, 3, 5, 7, 10, 15, 20 }; + // vol is low ... + double[] strikes = { 0.0, 0.025, 0.029, 0.03, 0.031, 0.035, 0.07 }; + // yoy inflation vol is generally very low + double[] vols = { 0.001, 0.005, 0.010, 0.015, 0.020 }; + + // cap-floor-swap parity is model-independent + for (int whichPricer = 0; whichPricer < 3; whichPricer++) + { + for (int i = 0; i < lengths.Length; i++) + { + for (int j = 0; j < strikes.Length; j++) + { + for (int k = 0; k < vols.Length; k++) + { + + List leg = vars.makeYoYLeg(vars.evaluationDate, lengths[i]); + + Instrument cap = vars.makeYoYCapFloor(CapFloorType.Cap, + leg, strikes[j], vols[k], whichPricer); + + Instrument floor = vars.makeYoYCapFloor(CapFloorType.Floor, + leg, strikes[j], vols[k], whichPricer); + + Date from = vars.nominalTS.link.referenceDate(); + Date to = from + new Period(lengths[i], TimeUnit.Years); + Schedule yoySchedule = new MakeSchedule().from(from).to(to) + .withTenor(new Period(1, TimeUnit.Years)) + .withConvention(BusinessDayConvention.Unadjusted) + .withCalendar(new UnitedKingdom()).backwards().value(); + + YearOnYearInflationSwap swap = new YearOnYearInflationSwap + (YearOnYearInflationSwap.Type.Payer, + 1000000.0, + yoySchedule,//fixed schedule, but same as yoy + strikes[j], + vars.dc, + yoySchedule, + vars.iir, + vars.observationLag, + 0.0, //spread on index + vars.dc, + new UnitedKingdom()); + + Handle hTS = new Handle(vars.nominalTS); + IPricingEngine sppe = new DiscountingSwapEngine(hTS); + swap.setPricingEngine(sppe); + + // N.B. nominals are 10e6 + if (Math.Abs((cap.NPV() - floor.NPV()) - swap.NPV()) > 1.0e-6) + { + QAssert.Fail( + "put/call parity violated:\n" + + " length: " + lengths[i] + " years\n" + + " volatility: " + vols[k] + "\n" + + " strike: " + strikes[j] + "\n" + + " cap value: " + cap.NPV() + "\n" + + " floor value: " + floor.NPV() + "\n" + + " swap value: " + swap.NPV()); + } + } + } + } + } + // remove circular refernce + vars.hy.linkTo(null); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testCachedValue() - { - // Testing Black yoy inflation cap/floor price against cached values... - CommonVars vars = new CommonVars(); - - int whichPricer = 0; // black - - double K = 0.0295; // one centi-point is fair rate error i.e. < 1 cp - int j = 2; - List leg = vars.makeYoYLeg(vars.evaluationDate,j); - Instrument cap = vars.makeYoYCapFloor(CapFloorType.Cap,leg, K, 0.01, whichPricer); - - Instrument floor = vars.makeYoYCapFloor(CapFloorType.Floor,leg, K, 0.01, whichPricer); - - - // close to atm prices - double cachedCapNPVblack = 219.452; - double cachedFloorNPVblack = 314.641; - // N.B. notionals are 10e6. - QAssert.IsTrue(Math.Abs(cap.NPV()-cachedCapNPVblack)<0.02,"yoy cap cached NPV wrong " - +cap.NPV()+" should be "+cachedCapNPVblack+" Black pricer" - +" diff was "+(Math.Abs(cap.NPV()-cachedCapNPVblack))); - QAssert.IsTrue(Math.Abs(floor.NPV()-cachedFloorNPVblack)<0.02,"yoy floor cached NPV wrong " - +floor.NPV()+" should be "+cachedFloorNPVblack+" Black pricer" - +" diff was "+(Math.Abs(floor.NPV()-cachedFloorNPVblack))); - - whichPricer = 1; // dd - - cap = vars.makeYoYCapFloor(CapFloorType.Cap,leg, K, 0.01, whichPricer); - floor = vars.makeYoYCapFloor(CapFloorType.Floor,leg, K, 0.01, whichPricer); - - // close to atm prices - double cachedCapNPVdd = 9114.61; - double cachedFloorNPVdd = 9209.8; - // N.B. notionals are 10e6. - QAssert.IsTrue(Math.Abs(cap.NPV()-cachedCapNPVdd)<0.22,"yoy cap cached NPV wrong " - +cap.NPV()+" should be "+cachedCapNPVdd+" dd Black pricer" - +" diff was "+(Math.Abs(cap.NPV()-cachedCapNPVdd))); - QAssert.IsTrue(Math.Abs(floor.NPV()-cachedFloorNPVdd)<0.22,"yoy floor cached NPV wrong " - +floor.NPV()+" should be "+cachedFloorNPVdd+" dd Black pricer" - +" diff was "+(Math.Abs(floor.NPV()-cachedFloorNPVdd))); - - whichPricer = 2; // bachelier - - cap = vars.makeYoYCapFloor(CapFloorType.Cap,leg, K, 0.01, whichPricer); - floor = vars.makeYoYCapFloor(CapFloorType.Floor,leg, K, 0.01, whichPricer); - - // close to atm prices - double cachedCapNPVbac = 8852.4; - double cachedFloorNPVbac = 8947.59; - // N.B. notionals are 10e6. - QAssert.IsTrue(Math.Abs(cap.NPV()-cachedCapNPVbac)<0.22,"yoy cap cached NPV wrong " - +cap.NPV()+" should be "+cachedCapNPVbac+" bac Black pricer" - +" diff was "+(Math.Abs(cap.NPV()-cachedCapNPVbac))); - QAssert.IsTrue(Math.Abs(floor.NPV()-cachedFloorNPVbac)<0.22,"yoy floor cached NPV wrong " - +floor.NPV()+" should be "+cachedFloorNPVbac+" bac Black pricer" - +" diff was "+(Math.Abs(floor.NPV()-cachedFloorNPVbac))); - - // remove circular refernce - vars.hy.linkTo(null); - } - - } + public void testCachedValue() + { + // Testing Black yoy inflation cap/floor price against cached values... + CommonVars vars = new CommonVars(); + + int whichPricer = 0; // black + + double K = 0.0295; // one centi-point is fair rate error i.e. < 1 cp + int j = 2; + List leg = vars.makeYoYLeg(vars.evaluationDate, j); + Instrument cap = vars.makeYoYCapFloor(CapFloorType.Cap, leg, K, 0.01, whichPricer); + + Instrument floor = vars.makeYoYCapFloor(CapFloorType.Floor, leg, K, 0.01, whichPricer); + + + // close to atm prices + double cachedCapNPVblack = 219.452; + double cachedFloorNPVblack = 314.641; + // N.B. notionals are 10e6. + QAssert.IsTrue(Math.Abs(cap.NPV() - cachedCapNPVblack) < 0.02, "yoy cap cached NPV wrong " + + cap.NPV() + " should be " + cachedCapNPVblack + " Black pricer" + + " diff was " + (Math.Abs(cap.NPV() - cachedCapNPVblack))); + QAssert.IsTrue(Math.Abs(floor.NPV() - cachedFloorNPVblack) < 0.02, "yoy floor cached NPV wrong " + + floor.NPV() + " should be " + cachedFloorNPVblack + " Black pricer" + + " diff was " + (Math.Abs(floor.NPV() - cachedFloorNPVblack))); + + whichPricer = 1; // dd + + cap = vars.makeYoYCapFloor(CapFloorType.Cap, leg, K, 0.01, whichPricer); + floor = vars.makeYoYCapFloor(CapFloorType.Floor, leg, K, 0.01, whichPricer); + + // close to atm prices + double cachedCapNPVdd = 9114.61; + double cachedFloorNPVdd = 9209.8; + // N.B. notionals are 10e6. + QAssert.IsTrue(Math.Abs(cap.NPV() - cachedCapNPVdd) < 0.22, "yoy cap cached NPV wrong " + + cap.NPV() + " should be " + cachedCapNPVdd + " dd Black pricer" + + " diff was " + (Math.Abs(cap.NPV() - cachedCapNPVdd))); + QAssert.IsTrue(Math.Abs(floor.NPV() - cachedFloorNPVdd) < 0.22, "yoy floor cached NPV wrong " + + floor.NPV() + " should be " + cachedFloorNPVdd + " dd Black pricer" + + " diff was " + (Math.Abs(floor.NPV() - cachedFloorNPVdd))); + + whichPricer = 2; // bachelier + + cap = vars.makeYoYCapFloor(CapFloorType.Cap, leg, K, 0.01, whichPricer); + floor = vars.makeYoYCapFloor(CapFloorType.Floor, leg, K, 0.01, whichPricer); + + // close to atm prices + double cachedCapNPVbac = 8852.4; + double cachedFloorNPVbac = 8947.59; + // N.B. notionals are 10e6. + QAssert.IsTrue(Math.Abs(cap.NPV() - cachedCapNPVbac) < 0.22, "yoy cap cached NPV wrong " + + cap.NPV() + " should be " + cachedCapNPVbac + " bac Black pricer" + + " diff was " + (Math.Abs(cap.NPV() - cachedCapNPVbac))); + QAssert.IsTrue(Math.Abs(floor.NPV() - cachedFloorNPVbac) < 0.22, "yoy floor cached NPV wrong " + + floor.NPV() + " should be " + cachedFloorNPVbac + " bac Black pricer" + + " diff was " + (Math.Abs(floor.NPV() - cachedFloorNPVbac))); + + // remove circular refernce + vars.hy.linkTo(null); + } + + } } diff --git a/tests/QLNet.Tests/T_InflationCapFlooredCouponTest.cs b/tests/QLNet.Tests/T_InflationCapFlooredCouponTest.cs index 1ddd5a4cf..f30d6db53 100644 --- a/tests/QLNet.Tests/T_InflationCapFlooredCouponTest.cs +++ b/tests/QLNet.Tests/T_InflationCapFlooredCouponTest.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,7 +21,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -31,22 +31,22 @@ namespace TestSuite [TestClass()] #endif public class T_InflationCapFlooredCouponTest : IDisposable - { + { #region Initialize&Cleanup private SavedSettings backup; - #if NET40 || NET45 +#if NET40 || NET45 [TestInitialize] public void testInitialize() { - #else +#else public T_InflationCapFlooredCouponTest() { - #endif +#endif backup = new SavedSettings(); } - #if NET40 || NET45 +#if NET40 || NET45 [TestCleanup] - #endif +#endif public void testCleanup() { Dispose(); @@ -57,10 +57,10 @@ public void Dispose() } #endregion - class CommonVars - { - // common data - public int length; + class CommonVars + { + // common data + public int length; public Date startDate; public double volatility; @@ -72,7 +72,7 @@ class CommonVars public Date evaluationDate; public int settlementDays; public Date settlement; - public Period observationLag = new Period(0,TimeUnit.Months); + public Period observationLag = new Period(0, TimeUnit.Months); public DayCounter dc; public YYUKRPIr iir; @@ -81,10 +81,10 @@ class CommonVars public RelinkableHandle hy = new RelinkableHandle(); // setup - public CommonVars() + public CommonVars() { // option variables - nominals = new List(){1000000}; + nominals = new List() {1000000}; frequency = Frequency.Annual; // usual setup volatility = 0.01; @@ -96,7 +96,7 @@ public CommonVars() Settings.setEvaluationDate(evaluationDate); settlementDays = 0; fixingDays = 0; - settlement = calendar.advance(today,settlementDays,TimeUnit.Days); + settlement = calendar.advance(today, settlementDays, TimeUnit.Days); startDate = settlement; dc = new Thirty360(); @@ -105,19 +105,20 @@ public CommonVars() Date from = new Date(1, Month.January, 2005); Date to = new Date(13, Month.August, 2007); Schedule rpiSchedule = new MakeSchedule().from(from).to(to) - .withTenor(new Period(1,TimeUnit.Months)) + .withTenor(new Period(1, TimeUnit.Months)) .withCalendar(new UnitedKingdom()) .withConvention(BusinessDayConvention.ModifiedFollowing).value(); double[] fixData = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0, - 192.2, 192.2, 192.6, 193.1, 193.3, 193.6, - 194.1, 193.4, 194.2, 195.0, 196.5, 197.7, - 198.5, 198.5, 199.2, 200.1, 200.4, 201.1, - 202.7, 201.6, 203.1, 204.4, 205.4, 206.2, - 207.3, -999.0, -999 }; + 192.2, 192.2, 192.6, 193.1, 193.3, 193.6, + 194.1, 193.4, 194.2, 195.0, 196.5, 197.7, + 198.5, 198.5, 199.2, 200.1, 200.4, 201.1, + 202.7, 201.6, 203.1, 204.4, 205.4, 206.2, + 207.3, -999.0, -999 + }; // link from yoy index to yoy TS bool interp = false; iir = new YYUKRPIr(interp, hy); - for (int i=0; i > helpers = - makeHelpers(yyData, yyData.Length, iir, - observationLag, - calendar, convention, dc); + makeHelpers(yyData, yyData.Length, iir, + observationLag, + calendar, convention, dc); - double baseYYRate = yyData[0].rate/100.0; + double baseYYRate = yyData[0].rate / 100.0; PiecewiseYoYInflationCurve pYYTS = new PiecewiseYoYInflationCurve( - evaluationDate, calendar, dc, observationLag, - iir.frequency(),iir.interpolated(), baseYYRate, - new Handle(nominalTS), helpers); + evaluationDate, calendar, dc, observationLag, + iir.frequency(), iir.interpolated(), baseYYRate, + new Handle(nominalTS), helpers); pYYTS.recalculate(); yoyTS = pYYTS as YoYInflationTermStructure; // make sure that the index has the latest yoy term structure hy.linkTo(pYYTS); - } + } // utilities - public List makeYoYLeg(Date startDate, int length,double gearing = 1.0,double spread = 0.0) + public List makeYoYLeg(Date startDate, int length, double gearing = 1.0, double spread = 0.0) { YoYInflationIndex ii = iir as YoYInflationIndex; - Date endDate = calendar.advance(startDate,new Period(length,TimeUnit.Years),BusinessDayConvention.Unadjusted); + Date endDate = calendar.advance(startDate, new Period(length, TimeUnit.Years), BusinessDayConvention.Unadjusted); Schedule schedule = new Schedule(startDate, endDate, new Period(frequency), calendar, - BusinessDayConvention.Unadjusted, - BusinessDayConvention.Unadjusted,// ref periods & acc periods - DateGeneration.Rule.Forward, false); + BusinessDayConvention.Unadjusted, + BusinessDayConvention.Unadjusted,// ref periods & acc periods + DateGeneration.Rule.Forward, false); List gearingVector = new InitializedList(length, gearing); List spreadVector = new InitializedList(length, spread); return new yoyInflationLeg(schedule, calendar, ii, observationLag) - .withPaymentDayCounter(dc) - .withGearings(gearingVector) - .withSpreads(spreadVector) - .withNotionals(nominals) - .withPaymentAdjustment(convention); - } - - public List makeFixedLeg(Date startDate,int length) + .withPaymentDayCounter(dc) + .withGearings(gearingVector) + .withSpreads(spreadVector) + .withNotionals(nominals) + .withPaymentAdjustment(convention); + } + + public List makeFixedLeg(Date startDate, int length) { Date endDate = calendar.advance(startDate, length, TimeUnit.Years, convention); Schedule schedule = new Schedule(startDate, endDate, new Period(frequency), calendar, - convention, convention, - DateGeneration.Rule.Forward, false); + convention, convention, + DateGeneration.Rule.Forward, false); List coupons = new InitializedList(length, 0.0); return new FixedRateLeg(schedule) - .withCouponRates(coupons, dc) - .withNotionals(nominals); - } - + .withCouponRates(coupons, dc) + .withNotionals(nominals); + } + public List makeYoYCapFlooredLeg(int which, Date startDate, - int length, - List caps, - List floors, - double volatility, - double gearing = 1.0, - double spread = 0.0) + int length, + List < double? > caps, + List < double? > floors, + double volatility, + double gearing = 1.0, + double spread = 0.0) { - + Handle vol = new Handle( new ConstantYoYOptionletVolatility(volatility, - settlementDays, - calendar, - convention, - dc, - observationLag, - frequency, - iir.interpolated())); + settlementDays, + calendar, + convention, + dc, + observationLag, + frequency, + iir.interpolated())); YoYInflationCouponPricer pricer = null; - switch (which) { - case 0: - pricer = new BlackYoYInflationCouponPricer(vol); - break; - case 1: - pricer = new UnitDisplacedBlackYoYInflationCouponPricer(vol); - break; - case 2: - pricer = new BachelierYoYInflationCouponPricer(vol); - break; - default: - QAssert.Fail("unknown coupon pricer request: which = "+which - +"should be 0=Black,1=DD,2=Bachelier"); - break; + switch (which) + { + case 0: + pricer = new BlackYoYInflationCouponPricer(vol); + break; + case 1: + pricer = new UnitDisplacedBlackYoYInflationCouponPricer(vol); + break; + case 2: + pricer = new BachelierYoYInflationCouponPricer(vol); + break; + default: + QAssert.Fail("unknown coupon pricer request: which = " + which + + "should be 0=Black,1=DD,2=Bachelier"); + break; } @@ -239,11 +242,11 @@ public List makeYoYCapFlooredLeg(int which, Date startDate, List spreadVector = new InitializedList(length, spread); YoYInflationIndex ii = iir as YoYInflationIndex; - Date endDate = calendar.advance(startDate,new Period(length,TimeUnit.Years),BusinessDayConvention.Unadjusted); + Date endDate = calendar.advance(startDate, new Period(length, TimeUnit.Years), BusinessDayConvention.Unadjusted); Schedule schedule = new Schedule(startDate, endDate, new Period(frequency), calendar, - BusinessDayConvention.Unadjusted, - BusinessDayConvention.Unadjusted,// ref periods & acc periods - DateGeneration.Rule.Forward, false); + BusinessDayConvention.Unadjusted, + BusinessDayConvention.Unadjusted,// ref periods & acc periods + DateGeneration.Rule.Forward, false); List yoyLeg = new yoyInflationLeg(schedule, calendar, ii, observationLag) .withPaymentDayCounter(dc) @@ -254,136 +257,137 @@ public List makeYoYCapFlooredLeg(int which, Date startDate, .withNotionals(nominals) .withPaymentAdjustment(convention); - for(int i=0; i vol = new Handle( - new ConstantYoYOptionletVolatility(volatility, - settlementDays, - calendar, - convention, - dc, - observationLag, - frequency, - iir.interpolated())); - - - switch (which) { - case 0: - return new YoYInflationBlackCapFloorEngine(iir, vol); - //break; - case 1: - return new YoYInflationUnitDisplacedBlackCapFloorEngine(iir, vol); - //break; - case 2: - return new YoYInflationBachelierCapFloorEngine(iir, vol); - //break; - default: - QAssert.Fail("unknown engine request: which = "+which - +"should be 0=Black,1=DD,2=Bachelier"); - break; + new ConstantYoYOptionletVolatility(volatility, + settlementDays, + calendar, + convention, + dc, + observationLag, + frequency, + iir.interpolated())); + + + switch (which) + { + case 0: + return new YoYInflationBlackCapFloorEngine(iir, vol); + //break; + case 1: + return new YoYInflationUnitDisplacedBlackCapFloorEngine(iir, vol); + //break; + case 2: + return new YoYInflationBachelierCapFloorEngine(iir, vol); + //break; + default: + QAssert.Fail("unknown engine request: which = " + which + + "should be 0=Black,1=DD,2=Bachelier"); + break; } // make compiler happy Utils.QL_FAIL("never get here - no engine resolution"); return null; - } + } public YoYInflationCapFloor makeYoYCapFloor(CapFloorType type, List leg, double strike, double volatility, - int which) + int which) { YoYInflationCapFloor result = null; - switch (type) + switch (type) { - case CapFloorType.Cap: - result = new YoYInflationCap(leg, new List(){strike}); - break; - case CapFloorType.Floor: - result = new YoYInflationFloor(leg, new List(){ strike}); - break; - default: - Utils.QL_FAIL("unknown YoYInflation cap/floor type"); - break; + case CapFloorType.Cap: + result = new YoYInflationCap(leg, new List() {strike}); + break; + case CapFloorType.Floor: + result = new YoYInflationFloor(leg, new List() { strike}); + break; + default: + Utils.QL_FAIL("unknown YoYInflation cap/floor type"); + break; } result.setPricingEngine(makeEngine(volatility, which)); return result; - } + } - private List> makeHelpers( Datum[] iiData, int N, - YoYInflationIndex ii, Period observationLag, - Calendar calendar, - BusinessDayConvention bdc, - DayCounter dc ) + private List> makeHelpers(Datum[] iiData, int N, + YoYInflationIndex ii, Period observationLag, + Calendar calendar, + BusinessDayConvention bdc, + DayCounter dc) { - List> instruments = + List> instruments = new List>(); - for ( int i = 0; i < N; i++ ) + for (int i = 0; i < N; i++) { Date maturity = iiData[i].date; - Handle quote = new Handle( new SimpleQuote( iiData[i].rate / 100.0 ) ); - BootstrapHelper anInstrument = new YearOnYearInflationSwapHelper( quote, observationLag, maturity, - calendar, bdc, dc, ii ); - instruments.Add( anInstrument ); + Handle quote = new Handle(new SimpleQuote(iiData[i].rate / 100.0)); + BootstrapHelper anInstrument = new YearOnYearInflationSwapHelper(quote, observationLag, maturity, + calendar, bdc, dc, ii); + instruments.Add(anInstrument); } return instruments; - + } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testDecomposition() + public void testDecomposition() { // Testing collared coupon against its decomposition... - CommonVars vars= new CommonVars(); + CommonVars vars = new CommonVars(); double tolerance = 1e-10; - double npvVanilla,npvCappedLeg,npvFlooredLeg,npvCollaredLeg,npvCap,npvFloor,npvCollar; + double npvVanilla, npvCappedLeg, npvFlooredLeg, npvCollaredLeg, npvCap, npvFloor, npvCollar; double error; double floorstrike = 0.05; double capstrike = 0.10; - List caps = new InitializedList(vars.length,capstrike); - List caps0 = new List(); - List floors = new InitializedList(vars.length,floorstrike); - List floors0 = new List(); + List < double? > caps = new InitializedList < double? >(vars.length, capstrike); + List < double? > caps0 = new List < double? >(); + List < double? > floors = new InitializedList < double? >(vars.length, floorstrike); + List < double? > floors0 = new List < double? >(); double gearing_p = 0.5; double spread_p = 0.002; double gearing_n = -1.5; double spread_n = 0.12; // fixed leg with zero rate - List fixedLeg = vars.makeFixedLeg(vars.startDate,vars.length); + List fixedLeg = vars.makeFixedLeg(vars.startDate, vars.length); // floating leg with gearing=1 and spread=0 - List floatLeg = vars.makeYoYLeg(vars.startDate,vars.length); + List floatLeg = vars.makeYoYLeg(vars.startDate, vars.length); // floating leg with positive gearing (gearing_p) and spread<>0 - List floatLeg_p = vars.makeYoYLeg(vars.startDate,vars.length,gearing_p,spread_p); + List floatLeg_p = vars.makeYoYLeg(vars.startDate, vars.length, gearing_p, spread_p); // floating leg with negative gearing (gearing_n) and spread<>0 - List floatLeg_n = vars.makeYoYLeg(vars.startDate,vars.length,gearing_n,spread_n); + List floatLeg_n = vars.makeYoYLeg(vars.startDate, vars.length, gearing_n, spread_n); // Swap with null fixed leg and floating leg with gearing=1 and spread=0 - Swap vanillaLeg = new Swap(fixedLeg,floatLeg); + Swap vanillaLeg = new Swap(fixedLeg, floatLeg); // Swap with null fixed leg and floating leg with positive gearing and spread<>0 - Swap vanillaLeg_p = new Swap(fixedLeg,floatLeg_p); + Swap vanillaLeg_p = new Swap(fixedLeg, floatLeg_p); // Swap with null fixed leg and floating leg with negative gearing and spread<>0 - Swap vanillaLeg_n = new Swap(fixedLeg,floatLeg_n); + Swap vanillaLeg_n = new Swap(fixedLeg, floatLeg_n); IPricingEngine engine = new DiscountingSwapEngine(vars.nominalTS); @@ -401,23 +405,23 @@ public void testDecomposition() int whichPricer = 0; // Case gearing = 1 and spread = 0 - List cappedLeg = vars.makeYoYCapFlooredLeg(whichPricer,vars.startDate,vars.length, - caps,floors0,vars.volatility); - Swap capLeg = new Swap(fixedLeg,cappedLeg); + List cappedLeg = vars.makeYoYCapFlooredLeg(whichPricer, vars.startDate, vars.length, + caps, floors0, vars.volatility); + Swap capLeg = new Swap(fixedLeg, cappedLeg); capLeg.setPricingEngine(engine); - YoYInflationCap cap = new YoYInflationCap(floatLeg, new List(){capstrike}); - cap.setPricingEngine(vars.makeEngine(vars.volatility,whichPricer)); + YoYInflationCap cap = new YoYInflationCap(floatLeg, new List() {capstrike}); + cap.setPricingEngine(vars.makeEngine(vars.volatility, whichPricer)); npvVanilla = vanillaLeg.NPV(); npvCappedLeg = capLeg.NPV(); npvCap = cap.NPV(); - error = Math.Abs(npvCappedLeg - (npvVanilla-npvCap)); - if (error>tolerance) + error = Math.Abs(npvCappedLeg - (npvVanilla - npvCap)); + if (error > tolerance) { - QAssert.Fail("\nYoY Capped Leg: gearing=1, spread=0%, strike=" + capstrike*100 + - "%\n" + - " Capped Floating Leg NPV: " + npvCappedLeg + "\n" + - " Floating Leg NPV - Cap NPV: " + (npvVanilla - npvCap) + "\n" + - " Diff: " + error ); + QAssert.Fail("\nYoY Capped Leg: gearing=1, spread=0%, strike=" + capstrike * 100 + + "%\n" + + " Capped Floating Leg NPV: " + npvCappedLeg + "\n" + + " Floating Leg NPV - Cap NPV: " + (npvVanilla - npvCap) + "\n" + + " Diff: " + error); } // gearing = 1 and spread = 0 @@ -428,22 +432,22 @@ public void testDecomposition() // = VanillaFloatingLeg + Put // - List flooredLeg = vars.makeYoYCapFlooredLeg(whichPricer,vars.startDate,vars.length, - caps0,floors,vars.volatility); - Swap floorLeg = new Swap(fixedLeg,flooredLeg); + List flooredLeg = vars.makeYoYCapFlooredLeg(whichPricer, vars.startDate, vars.length, + caps0, floors, vars.volatility); + Swap floorLeg = new Swap(fixedLeg, flooredLeg); floorLeg.setPricingEngine(engine); - YoYInflationFloor floor= new YoYInflationFloor(floatLeg, new List(){floorstrike}); - floor.setPricingEngine(vars.makeEngine(vars.volatility,whichPricer)); + YoYInflationFloor floor = new YoYInflationFloor(floatLeg, new List() {floorstrike}); + floor.setPricingEngine(vars.makeEngine(vars.volatility, whichPricer)); npvFlooredLeg = floorLeg.NPV(); npvFloor = floor.NPV(); - error = Math.Abs(npvFlooredLeg-(npvVanilla + npvFloor)); - if (error>tolerance) + error = Math.Abs(npvFlooredLeg - (npvVanilla + npvFloor)); + if (error > tolerance) { - QAssert.Fail("YoY Floored Leg: gearing=1, spread=0%, strike=" + floorstrike *100 + - "%\n" + - " Floored Floating Leg NPV: " + npvFlooredLeg + "\n" + - " Floating Leg NPV + Floor NPV: " + (npvVanilla + npvFloor) + "\n" + - " Diff: " + error ); + QAssert.Fail("YoY Floored Leg: gearing=1, spread=0%, strike=" + floorstrike * 100 + + "%\n" + + " Floored Floating Leg NPV: " + npvFlooredLeg + "\n" + + " Floating Leg NPV + Floor NPV: " + (npvVanilla + npvFloor) + "\n" + + " Diff: " + error); } // gearing = 1 and spread = 0 @@ -452,24 +456,24 @@ public void testDecomposition() // = VanillaFloatingLeg - Collar // - List collaredLeg = vars.makeYoYCapFlooredLeg(whichPricer,vars.startDate,vars.length, - caps,floors,vars.volatility); - Swap collarLeg = new Swap(fixedLeg,collaredLeg); + List collaredLeg = vars.makeYoYCapFlooredLeg(whichPricer, vars.startDate, vars.length, + caps, floors, vars.volatility); + Swap collarLeg = new Swap(fixedLeg, collaredLeg); collarLeg.setPricingEngine(engine); YoYInflationCollar collar = new YoYInflationCollar(floatLeg, - new List(){capstrike}, - new List(){floorstrike}); - collar.setPricingEngine(vars.makeEngine(vars.volatility,whichPricer)); + new List() {capstrike}, + new List() {floorstrike}); + collar.setPricingEngine(vars.makeEngine(vars.volatility, whichPricer)); npvCollaredLeg = collarLeg.NPV(); npvCollar = collar.NPV(); - error = Math.Abs(npvCollaredLeg -(npvVanilla - npvCollar)); - if (error>tolerance) + error = Math.Abs(npvCollaredLeg - (npvVanilla - npvCollar)); + if (error > tolerance) { QAssert.Fail("\nYoY Collared Leg: gearing=1, spread=0%, strike=" + - floorstrike*100 + "% and " + capstrike*100 + "%\n" + - " Collared Floating Leg NPV: " + npvCollaredLeg + "\n" + - " Floating Leg NPV - Collar NPV: " + (npvVanilla - npvCollar) + "\n" + - " Diff: " + error ); + floorstrike * 100 + "% and " + capstrike * 100 + "%\n" + + " Collared Floating Leg NPV: " + npvCollaredLeg + "\n" + + " Floating Leg NPV - Collar NPV: " + (npvVanilla - npvCollar) + "\n" + + " Diff: " + error); } // gearing = a and spread = b @@ -486,53 +490,53 @@ public void testDecomposition() // // Positive gearing - List cappedLeg_p = vars.makeYoYCapFlooredLeg(whichPricer,vars.startDate,vars.length,caps,floors0, - vars.volatility,gearing_p,spread_p); - Swap capLeg_p = new Swap(fixedLeg,cappedLeg_p); + List cappedLeg_p = vars.makeYoYCapFlooredLeg(whichPricer, vars.startDate, vars.length, caps, floors0, + vars.volatility, gearing_p, spread_p); + Swap capLeg_p = new Swap(fixedLeg, cappedLeg_p); capLeg_p.setPricingEngine(engine); - YoYInflationCap cap_p = new YoYInflationCap(floatLeg_p,new List(){capstrike}); - cap_p.setPricingEngine(vars.makeEngine(vars.volatility,whichPricer)); + YoYInflationCap cap_p = new YoYInflationCap(floatLeg_p, new List() {capstrike}); + cap_p.setPricingEngine(vars.makeEngine(vars.volatility, whichPricer)); npvVanilla = vanillaLeg_p.NPV(); npvCappedLeg = capLeg_p.NPV(); npvCap = cap_p.NPV(); - error = Math.Abs(npvCappedLeg - (npvVanilla-npvCap)); - if (error>tolerance) + error = Math.Abs(npvCappedLeg - (npvVanilla - npvCap)); + if (error > tolerance) { QAssert.Fail("\nYoY Capped Leg: gearing=" + gearing_p + ", " + - "spread= " + spread_p *100 + - "%, strike=" + capstrike*100 + "%, " + - "effective strike= " + (capstrike-spread_p)/gearing_p*100 + - "%\n" + - " Capped Floating Leg NPV: " + npvCappedLeg + "\n" + - " Vanilla Leg NPV: " + npvVanilla + "\n" + - " Cap NPV: " + npvCap + "\n" + - " Floating Leg NPV - Cap NPV: " + (npvVanilla - npvCap) + "\n" + - " Diff: " + error ); + "spread= " + spread_p * 100 + + "%, strike=" + capstrike * 100 + "%, " + + "effective strike= " + (capstrike - spread_p) / gearing_p * 100 + + "%\n" + + " Capped Floating Leg NPV: " + npvCappedLeg + "\n" + + " Vanilla Leg NPV: " + npvVanilla + "\n" + + " Cap NPV: " + npvCap + "\n" + + " Floating Leg NPV - Cap NPV: " + (npvVanilla - npvCap) + "\n" + + " Diff: " + error); } // Negative gearing - List cappedLeg_n = vars.makeYoYCapFlooredLeg(whichPricer,vars.startDate,vars.length,caps,floors0, - vars.volatility,gearing_n,spread_n); - Swap capLeg_n = new Swap(fixedLeg,cappedLeg_n); + List cappedLeg_n = vars.makeYoYCapFlooredLeg(whichPricer, vars.startDate, vars.length, caps, floors0, + vars.volatility, gearing_n, spread_n); + Swap capLeg_n = new Swap(fixedLeg, cappedLeg_n); capLeg_n.setPricingEngine(engine); - YoYInflationFloor floor_n = new YoYInflationFloor(floatLeg,new List(){(capstrike-spread_n)/gearing_n}); - floor_n.setPricingEngine(vars.makeEngine(vars.volatility,whichPricer)); + YoYInflationFloor floor_n = new YoYInflationFloor(floatLeg, new List() {(capstrike - spread_n) / gearing_n}); + floor_n.setPricingEngine(vars.makeEngine(vars.volatility, whichPricer)); npvVanilla = vanillaLeg_n.NPV(); npvCappedLeg = capLeg_n.NPV(); npvFloor = floor_n.NPV(); - error = Math.Abs(npvCappedLeg - (npvVanilla+ gearing_n*npvFloor)); - if (error>tolerance) + error = Math.Abs(npvCappedLeg - (npvVanilla + gearing_n * npvFloor)); + if (error > tolerance) { QAssert.Fail("\nYoY Capped Leg: gearing=" + gearing_n + ", " + - "spread= " + spread_n *100 + - "%, strike=" + capstrike*100 + "%, " + - "effective strike= " + ((capstrike-spread_n)/gearing_n*100) + - "%\n" + - " Capped Floating Leg NPV: " + npvCappedLeg + "\n" + - " npv Vanilla: " + npvVanilla + "\n" + - " npvFloor: " + npvFloor + "\n" + - " Floating Leg NPV - Cap NPV: " + (npvVanilla + gearing_n*npvFloor) + "\n" + - " Diff: " + error ); + "spread= " + spread_n * 100 + + "%, strike=" + capstrike * 100 + "%, " + + "effective strike= " + ((capstrike - spread_n) / gearing_n * 100) + + "%\n" + + " Capped Floating Leg NPV: " + npvCappedLeg + "\n" + + " npv Vanilla: " + npvVanilla + "\n" + + " npvFloor: " + npvFloor + "\n" + + " Floating Leg NPV - Cap NPV: " + (npvVanilla + gearing_n * npvFloor) + "\n" + + " Diff: " + error); } // gearing = a and spread = b @@ -549,49 +553,49 @@ public void testDecomposition() // // Positive gearing - List flooredLeg_p1 = vars.makeYoYCapFlooredLeg(whichPricer,vars.startDate,vars.length,caps0,floors, - vars.volatility,gearing_p,spread_p); - Swap floorLeg_p1 = new Swap(fixedLeg,flooredLeg_p1); + List flooredLeg_p1 = vars.makeYoYCapFlooredLeg(whichPricer, vars.startDate, vars.length, caps0, floors, + vars.volatility, gearing_p, spread_p); + Swap floorLeg_p1 = new Swap(fixedLeg, flooredLeg_p1); floorLeg_p1.setPricingEngine(engine); - YoYInflationFloor floor_p1 = new YoYInflationFloor(floatLeg_p,new List(){floorstrike}); - floor_p1.setPricingEngine(vars.makeEngine(vars.volatility,whichPricer)); + YoYInflationFloor floor_p1 = new YoYInflationFloor(floatLeg_p, new List() {floorstrike}); + floor_p1.setPricingEngine(vars.makeEngine(vars.volatility, whichPricer)); npvVanilla = vanillaLeg_p.NPV(); npvFlooredLeg = floorLeg_p1.NPV(); npvFloor = floor_p1.NPV(); - error = Math.Abs(npvFlooredLeg - (npvVanilla+npvFloor)); - if (error>tolerance) + error = Math.Abs(npvFlooredLeg - (npvVanilla + npvFloor)); + if (error > tolerance) { QAssert.Fail("\nYoY Floored Leg: gearing=" + gearing_p + ", " - + "spread= " + spread_p *100+ "%, strike=" + floorstrike *100 + "%, " - + "effective strike= " + (floorstrike-spread_p)/gearing_p*100 - + "%\n" + - " Floored Floating Leg NPV: " + npvFlooredLeg - + "\n" + - " Floating Leg NPV + Floor NPV: " + (npvVanilla + npvFloor) - + "\n" + - " Diff: " + error ); + + "spread= " + spread_p * 100 + "%, strike=" + floorstrike * 100 + "%, " + + "effective strike= " + (floorstrike - spread_p) / gearing_p * 100 + + "%\n" + + " Floored Floating Leg NPV: " + npvFlooredLeg + + "\n" + + " Floating Leg NPV + Floor NPV: " + (npvVanilla + npvFloor) + + "\n" + + " Diff: " + error); } // Negative gearing - List flooredLeg_n = vars.makeYoYCapFlooredLeg(whichPricer,vars.startDate,vars.length,caps0,floors, - vars.volatility,gearing_n,spread_n); - Swap floorLeg_n = new Swap(fixedLeg,flooredLeg_n); + List flooredLeg_n = vars.makeYoYCapFlooredLeg(whichPricer, vars.startDate, vars.length, caps0, floors, + vars.volatility, gearing_n, spread_n); + Swap floorLeg_n = new Swap(fixedLeg, flooredLeg_n); floorLeg_n.setPricingEngine(engine); - YoYInflationCap cap_n = new YoYInflationCap(floatLeg,new List(){(floorstrike-spread_n)/gearing_n}); - cap_n.setPricingEngine(vars.makeEngine(vars.volatility,whichPricer)); + YoYInflationCap cap_n = new YoYInflationCap(floatLeg, new List() {(floorstrike - spread_n) / gearing_n}); + cap_n.setPricingEngine(vars.makeEngine(vars.volatility, whichPricer)); npvVanilla = vanillaLeg_n.NPV(); npvFlooredLeg = floorLeg_n.NPV(); npvCap = cap_n.NPV(); - error = Math.Abs(npvFlooredLeg - (npvVanilla - gearing_n*npvCap)); - if (error>tolerance) + error = Math.Abs(npvFlooredLeg - (npvVanilla - gearing_n * npvCap)); + if (error > tolerance) { QAssert.Fail("\nYoY Capped Leg: gearing=" + gearing_n + ", " + - "spread= " + spread_n *100 + - "%, strike=" + floorstrike*100 + "%, " + - "effective strike= " + (floorstrike-spread_n)/gearing_n*100 + - "%\n" + - " Capped Floating Leg NPV: " + npvFlooredLeg + "\n" + - " Floating Leg NPV - Cap NPV: " + (npvVanilla - gearing_n*npvCap) + "\n" + - " Diff: " + error ); + "spread= " + spread_n * 100 + + "%, strike=" + floorstrike * 100 + "%, " + + "effective strike= " + (floorstrike - spread_n) / gearing_n * 100 + + "%\n" + + " Capped Floating Leg NPV: " + npvFlooredLeg + "\n" + + " Floating Leg NPV - Cap NPV: " + (npvVanilla - gearing_n * npvCap) + "\n" + + " Diff: " + error); } // gearing = a and spread = b // COLLARED coupon - Decomposition of payoff @@ -602,71 +606,71 @@ public void testDecomposition() // Payoff = VanillaFloatingLeg + Collar(|a|*rate+b, caprate, floorrate) // // Positive gearing - List collaredLeg_p = vars.makeYoYCapFlooredLeg(whichPricer,vars.startDate,vars.length,caps,floors, - vars.volatility,gearing_p,spread_p); - Swap collarLeg_p1 = new Swap(fixedLeg,collaredLeg_p); + List collaredLeg_p = vars.makeYoYCapFlooredLeg(whichPricer, vars.startDate, vars.length, caps, floors, + vars.volatility, gearing_p, spread_p); + Swap collarLeg_p1 = new Swap(fixedLeg, collaredLeg_p); collarLeg_p1.setPricingEngine(engine); YoYInflationCollar collar_p = new YoYInflationCollar(floatLeg_p, - new List(){capstrike}, - new List(){floorstrike}); - collar_p.setPricingEngine(vars.makeEngine(vars.volatility,whichPricer)); + new List() {capstrike}, + new List() {floorstrike}); + collar_p.setPricingEngine(vars.makeEngine(vars.volatility, whichPricer)); npvVanilla = vanillaLeg_p.NPV(); npvCollaredLeg = collarLeg_p1.NPV(); npvCollar = collar_p.NPV(); error = Math.Abs(npvCollaredLeg - (npvVanilla - npvCollar)); - if (error>tolerance) + if (error > tolerance) { QAssert.Fail("\nYoY Collared Leg: gearing=" + gearing_p + ", " - + "spread= " + spread_p*100 + "%, strike=" - + floorstrike*100 + "% and " + capstrike*100 - + "%, " - + "effective strike=" + (floorstrike-spread_p)/gearing_p*100 - + "% and " + (capstrike-spread_p)/gearing_p*100 - + "%\n" + - " Collared Floating Leg NPV: " + npvCollaredLeg - + "\n" + - " Floating Leg NPV - Collar NPV: " + (npvVanilla - npvCollar) - + "\n" + - " Diff: " + error ); + + "spread= " + spread_p * 100 + "%, strike=" + + floorstrike * 100 + "% and " + capstrike * 100 + + "%, " + + "effective strike=" + (floorstrike - spread_p) / gearing_p * 100 + + "% and " + (capstrike - spread_p) / gearing_p * 100 + + "%\n" + + " Collared Floating Leg NPV: " + npvCollaredLeg + + "\n" + + " Floating Leg NPV - Collar NPV: " + (npvVanilla - npvCollar) + + "\n" + + " Diff: " + error); } // Negative gearing - List collaredLeg_n = vars.makeYoYCapFlooredLeg(whichPricer,vars.startDate,vars.length,caps,floors, - vars.volatility,gearing_n,spread_n); - Swap collarLeg_n1 = new Swap(fixedLeg,collaredLeg_n); + List collaredLeg_n = vars.makeYoYCapFlooredLeg(whichPricer, vars.startDate, vars.length, caps, floors, + vars.volatility, gearing_n, spread_n); + Swap collarLeg_n1 = new Swap(fixedLeg, collaredLeg_n); collarLeg_n1.setPricingEngine(engine); YoYInflationCollar collar_n = new YoYInflationCollar(floatLeg, - new List(){(floorstrike-spread_n)/gearing_n}, - new List(){(capstrike-spread_n)/gearing_n}); - collar_n.setPricingEngine(vars.makeEngine(vars.volatility,whichPricer)); + new List() {(floorstrike - spread_n) / gearing_n}, + new List() {(capstrike - spread_n) / gearing_n}); + collar_n.setPricingEngine(vars.makeEngine(vars.volatility, whichPricer)); npvVanilla = vanillaLeg_n.NPV(); npvCollaredLeg = collarLeg_n1.NPV(); npvCollar = collar_n.NPV(); - error = Math.Abs(npvCollaredLeg - (npvVanilla - gearing_n*npvCollar)); - if (error>tolerance) + error = Math.Abs(npvCollaredLeg - (npvVanilla - gearing_n * npvCollar)); + if (error > tolerance) { QAssert.Fail("\nYoY Collared Leg: gearing=" + gearing_n + ", " - + "spread= " + spread_n*100 + "%, strike=" - + floorstrike*100 + "% and " + capstrike*100 - + "%, " - + "effective strike=" + (floorstrike-spread_n)/gearing_n*100 - + "% and " + (capstrike-spread_n)/gearing_n*100 - + "%\n" + - " Collared Floating Leg NPV: " + npvCollaredLeg - + "\n" + - " Floating Leg NPV - Collar NPV: " + (npvVanilla - gearing_n*npvCollar) - + "\n" + - " Diff: " + error ); + + "spread= " + spread_n * 100 + "%, strike=" + + floorstrike * 100 + "% and " + capstrike * 100 + + "%, " + + "effective strike=" + (floorstrike - spread_n) / gearing_n * 100 + + "% and " + (capstrike - spread_n) / gearing_n * 100 + + "%\n" + + " Collared Floating Leg NPV: " + npvCollaredLeg + + "\n" + + " Floating Leg NPV - Collar NPV: " + (npvVanilla - gearing_n * npvCollar) + + "\n" + + " Diff: " + error); } // remove circular refernce vars.hy.linkTo(null); - } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testInstrumentEquality() + public void testInstrumentEquality() { // Testing inflation capped/floored coupon against inflation capfloor instrument... @@ -682,91 +686,95 @@ public void testInstrumentEquality() // this is model independent // capped coupon = fwd - cap, and fwd = swap(0) // floored coupon = fwd + floor - for (int whichPricer = 0; whichPricer < 3; whichPricer++) { - for (int i=0; i leg = vars.makeYoYLeg(vars.evaluationDate,lengths[i]); - - Instrument cap = vars.makeYoYCapFloor(CapFloorType.Cap, - leg, strikes[j], vols[k], whichPricer); - - Instrument floor = vars.makeYoYCapFloor(CapFloorType.Floor, - leg, strikes[j], vols[k], whichPricer); - - Date from = vars.nominalTS.link.referenceDate(); - Date to = from+new Period(lengths[i],TimeUnit.Years); - Schedule yoySchedule = new MakeSchedule().from(from).to(to) - .withTenor(new Period(1,TimeUnit.Years)) - .withCalendar(new UnitedKingdom()) - .withConvention(BusinessDayConvention.Unadjusted) - .backwards().value(); - - YearOnYearInflationSwap swap = new YearOnYearInflationSwap(YearOnYearInflationSwap.Type.Payer, - 1000000.0, - yoySchedule,//fixed schedule, but same as yoy - 0.0,//strikes[j], - vars.dc, - yoySchedule, - vars.iir, - vars.observationLag, - 0.0, //spread on index - vars.dc, - new UnitedKingdom()); - - Handle hTS = new Handle(vars.nominalTS); - IPricingEngine sppe = new DiscountingSwapEngine(hTS); - swap.setPricingEngine(sppe); - - List leg2 = vars.makeYoYCapFlooredLeg(whichPricer, from, - lengths[i], - new InitializedList(lengths[i],strikes[j]),//cap - new List(),//floor - vols[k], - 1.0, // gearing - 0.0);// spread - - List leg3 = vars.makeYoYCapFlooredLeg(whichPricer, from, - lengths[i], - new List(),// cap - new InitializedList(lengths[i],strikes[j]),//floor - vols[k], - 1.0, // gearing - 0.0);// spread - - // N.B. nominals are 10e6 - double capped = CashFlows.npv(leg2,vars.nominalTS,false); - if ( Math.Abs(capped - (swap.NPV() - cap.NPV())) > 1.0e-6) - { - QAssert.Fail( - "capped coupon != swap(0) - cap:\n" - + " length: " + lengths[i] + " years\n" - + " volatility: " + vols[k] + "\n" - + " strike: " + strikes[j] + "\n" - + " cap value: " + cap.NPV() + "\n" - + " swap value: " + swap.NPV() + "\n" - + " capped coupon " + capped); - } - - - // N.B. nominals are 10e6 - double floored = CashFlows.npv(leg3,vars.nominalTS,false); - if ( Math.Abs(floored - (swap.NPV() + floor.NPV())) > 1.0e-6) - { - QAssert.Fail( - "floored coupon != swap(0) + floor :\n" - + " length: " + lengths[i] + " years\n" - + " volatility: " + vols[k] + "\n" - + " strike: " + strikes[j] + "\n" - + " floor value: " + floor.NPV() + "\n" - + " swap value: " + swap.NPV() + "\n" - + " floored coupon " + floored); - } + for (int whichPricer = 0; whichPricer < 3; whichPricer++) + { + for (int i = 0; i < lengths.Length; i++) + { + for (int j = 0; j < strikes.Length; j++) + { + for (int k = 0; k < vols.Length; k++) + { + + List leg = vars.makeYoYLeg(vars.evaluationDate, lengths[i]); + + Instrument cap = vars.makeYoYCapFloor(CapFloorType.Cap, + leg, strikes[j], vols[k], whichPricer); + + Instrument floor = vars.makeYoYCapFloor(CapFloorType.Floor, + leg, strikes[j], vols[k], whichPricer); + + Date from = vars.nominalTS.link.referenceDate(); + Date to = from + new Period(lengths[i], TimeUnit.Years); + Schedule yoySchedule = new MakeSchedule().from(from).to(to) + .withTenor(new Period(1, TimeUnit.Years)) + .withCalendar(new UnitedKingdom()) + .withConvention(BusinessDayConvention.Unadjusted) + .backwards().value(); + + YearOnYearInflationSwap swap = new YearOnYearInflationSwap(YearOnYearInflationSwap.Type.Payer, + 1000000.0, + yoySchedule,//fixed schedule, but same as yoy + 0.0,//strikes[j], + vars.dc, + yoySchedule, + vars.iir, + vars.observationLag, + 0.0, //spread on index + vars.dc, + new UnitedKingdom()); + + Handle hTS = new Handle(vars.nominalTS); + IPricingEngine sppe = new DiscountingSwapEngine(hTS); + swap.setPricingEngine(sppe); + + List leg2 = vars.makeYoYCapFlooredLeg(whichPricer, from, + lengths[i], + new InitializedList < double? >(lengths[i], strikes[j]), //cap + new List < double? >(), //floor + vols[k], + 1.0, // gearing + 0.0);// spread + + List leg3 = vars.makeYoYCapFlooredLeg(whichPricer, from, + lengths[i], + new List < double? >(), // cap + new InitializedList < double? >(lengths[i], strikes[j]), //floor + vols[k], + 1.0, // gearing + 0.0);// spread + + // N.B. nominals are 10e6 + double capped = CashFlows.npv(leg2, vars.nominalTS, false); + if (Math.Abs(capped - (swap.NPV() - cap.NPV())) > 1.0e-6) + { + QAssert.Fail( + "capped coupon != swap(0) - cap:\n" + + " length: " + lengths[i] + " years\n" + + " volatility: " + vols[k] + "\n" + + " strike: " + strikes[j] + "\n" + + " cap value: " + cap.NPV() + "\n" + + " swap value: " + swap.NPV() + "\n" + + " capped coupon " + capped); } + + + // N.B. nominals are 10e6 + double floored = CashFlows.npv(leg3, vars.nominalTS, false); + if (Math.Abs(floored - (swap.NPV() + floor.NPV())) > 1.0e-6) + { + QAssert.Fail( + "floored coupon != swap(0) + floor :\n" + + " length: " + lengths[i] + " years\n" + + " volatility: " + vols[k] + "\n" + + " strike: " + strikes[j] + "\n" + + " floor value: " + floor.NPV() + "\n" + + " swap value: " + swap.NPV() + "\n" + + " floored coupon " + floored); + } + } } } - + } // remove circular refernce vars.hy.linkTo(null); diff --git a/tests/QLNet.Tests/T_Instruments.cs b/tests/QLNet.Tests/T_Instruments.cs index c1592780d..57c7f2e59 100644 --- a/tests/QLNet.Tests/T_Instruments.cs +++ b/tests/QLNet.Tests/T_Instruments.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,7 +20,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -32,9 +32,9 @@ namespace TestSuite public class T_Instruments { #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testObservable() { diff --git a/tests/QLNet.Tests/T_InterestRate.cs b/tests/QLNet.Tests/T_InterestRate.cs index 3914ead67..2e3e61bdb 100644 --- a/tests/QLNet.Tests/T_InterestRate.cs +++ b/tests/QLNet.Tests/T_InterestRate.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Andrea Maggiulli - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,7 +21,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -55,55 +55,56 @@ public InterestRateData(double _r, Compounding _comp, Frequency _freq, double _t precision = _precision; } - }; + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testConversions() { - InterestRateData[] cases = { - // data from "Option Pricing Formulas", Haug, pag.181-182 - // Rate,Compounding, Frequency, Time, Compounding2, Frequency2, Rate2, precision - new InterestRateData(0.0800, Compounding.Compounded, Frequency.Quarterly, 1.00, Compounding.Continuous, Frequency.Annual, 0.0792, 4), - new InterestRateData(0.1200, Compounding.Continuous, Frequency.Annual, 1.00, Compounding.Compounded, Frequency.Annual, 0.1275, 4), - new InterestRateData(0.0800, Compounding.Compounded, Frequency.Quarterly, 1.00, Compounding.Compounded, Frequency.Annual, 0.0824, 4), - new InterestRateData(0.0700, Compounding.Compounded, Frequency.Quarterly, 1.00, Compounding.Compounded, Frequency.Semiannual, 0.0706, 4), - // undocumented, but reasonable :) - new InterestRateData(0.0100, Compounding.Compounded, Frequency.Annual, 1.00, Compounding.Simple, Frequency.Annual, 0.0100, 4), - new InterestRateData(0.0200, Compounding.Simple, Frequency.Annual, 1.00, Compounding.Compounded, Frequency.Annual, 0.0200, 4), - new InterestRateData(0.0300, Compounding.Compounded, Frequency.Semiannual, 0.50, Compounding.Simple, Frequency.Annual, 0.0300, 4), - new InterestRateData(0.0400, Compounding.Simple, Frequency.Annual, 0.50, Compounding.Compounded, Frequency.Semiannual, 0.0400, 4), - new InterestRateData(0.0500, Compounding.Compounded, Frequency.EveryFourthMonth, 1.0/3, Compounding.Simple, Frequency.Annual, 0.0500, 4), - new InterestRateData(0.0600, Compounding.Simple, Frequency.Annual, 1.0/3, Compounding.Compounded, Frequency.EveryFourthMonth, 0.0600, 4), - new InterestRateData(0.0500, Compounding.Compounded, Frequency.Quarterly, 0.25, Compounding.Simple, Frequency.Annual, 0.0500, 4), - new InterestRateData(0.0600, Compounding.Simple, Frequency.Annual, 0.25, Compounding.Compounded, Frequency.Quarterly, 0.0600, 4), - new InterestRateData(0.0700, Compounding.Compounded, Frequency.Bimonthly, 1.0/6, Compounding.Simple, Frequency.Annual, 0.0700, 4), - new InterestRateData(0.0800, Compounding.Simple, Frequency.Annual, 1.0/6, Compounding.Compounded, Frequency.Bimonthly, 0.0800, 4), - new InterestRateData(0.0900, Compounding.Compounded, Frequency.Monthly, 1.0/12, Compounding.Simple, Frequency.Annual, 0.0900, 4), - new InterestRateData(0.1000, Compounding.Simple, Frequency.Annual, 1.0/12, Compounding.Compounded, Frequency.Monthly, 0.1000, 4), - - new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.25, Compounding.Simple, Frequency.Annual, 0.0300, 4), - new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.25, Compounding.Simple, Frequency.Semiannual, 0.0300, 4), - new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.25, Compounding.Simple, Frequency.Quarterly, 0.0300, 4), - new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.50, Compounding.Simple, Frequency.Annual, 0.0300, 4), - new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.50, Compounding.Simple, Frequency.Semiannual, 0.0300, 4), - new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.75, Compounding.Compounded, Frequency.Semiannual, 0.0300, 4), - - new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.25, Compounding.SimpleThenCompounded, Frequency.Quarterly, 0.0400, 4), - new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.25, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.0400, 4), - new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.25, Compounding.SimpleThenCompounded, Frequency.Annual, 0.0400, 4), - - new InterestRateData(0.0400, Compounding.Compounded, Frequency.Quarterly, 0.50, Compounding.SimpleThenCompounded, Frequency.Quarterly, 0.0400, 4), - new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.50, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.0400, 4), - new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.50, Compounding.SimpleThenCompounded, Frequency.Annual, 0.0400, 4), - - new InterestRateData(0.0400, Compounding.Compounded, Frequency.Quarterly, 0.75, Compounding.SimpleThenCompounded, Frequency.Quarterly, 0.0400, 4), - new InterestRateData(0.0400, Compounding.Compounded, Frequency.Semiannual, 0.75, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.0400, 4), - new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.75, Compounding.SimpleThenCompounded, Frequency.Annual, 0.0400, 4) + InterestRateData[] cases = + { + // data from "Option Pricing Formulas", Haug, pag.181-182 + // Rate,Compounding, Frequency, Time, Compounding2, Frequency2, Rate2, precision + new InterestRateData(0.0800, Compounding.Compounded, Frequency.Quarterly, 1.00, Compounding.Continuous, Frequency.Annual, 0.0792, 4), + new InterestRateData(0.1200, Compounding.Continuous, Frequency.Annual, 1.00, Compounding.Compounded, Frequency.Annual, 0.1275, 4), + new InterestRateData(0.0800, Compounding.Compounded, Frequency.Quarterly, 1.00, Compounding.Compounded, Frequency.Annual, 0.0824, 4), + new InterestRateData(0.0700, Compounding.Compounded, Frequency.Quarterly, 1.00, Compounding.Compounded, Frequency.Semiannual, 0.0706, 4), + // undocumented, but reasonable :) + new InterestRateData(0.0100, Compounding.Compounded, Frequency.Annual, 1.00, Compounding.Simple, Frequency.Annual, 0.0100, 4), + new InterestRateData(0.0200, Compounding.Simple, Frequency.Annual, 1.00, Compounding.Compounded, Frequency.Annual, 0.0200, 4), + new InterestRateData(0.0300, Compounding.Compounded, Frequency.Semiannual, 0.50, Compounding.Simple, Frequency.Annual, 0.0300, 4), + new InterestRateData(0.0400, Compounding.Simple, Frequency.Annual, 0.50, Compounding.Compounded, Frequency.Semiannual, 0.0400, 4), + new InterestRateData(0.0500, Compounding.Compounded, Frequency.EveryFourthMonth, 1.0 / 3, Compounding.Simple, Frequency.Annual, 0.0500, 4), + new InterestRateData(0.0600, Compounding.Simple, Frequency.Annual, 1.0 / 3, Compounding.Compounded, Frequency.EveryFourthMonth, 0.0600, 4), + new InterestRateData(0.0500, Compounding.Compounded, Frequency.Quarterly, 0.25, Compounding.Simple, Frequency.Annual, 0.0500, 4), + new InterestRateData(0.0600, Compounding.Simple, Frequency.Annual, 0.25, Compounding.Compounded, Frequency.Quarterly, 0.0600, 4), + new InterestRateData(0.0700, Compounding.Compounded, Frequency.Bimonthly, 1.0 / 6, Compounding.Simple, Frequency.Annual, 0.0700, 4), + new InterestRateData(0.0800, Compounding.Simple, Frequency.Annual, 1.0 / 6, Compounding.Compounded, Frequency.Bimonthly, 0.0800, 4), + new InterestRateData(0.0900, Compounding.Compounded, Frequency.Monthly, 1.0 / 12, Compounding.Simple, Frequency.Annual, 0.0900, 4), + new InterestRateData(0.1000, Compounding.Simple, Frequency.Annual, 1.0 / 12, Compounding.Compounded, Frequency.Monthly, 0.1000, 4), + + new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.25, Compounding.Simple, Frequency.Annual, 0.0300, 4), + new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.25, Compounding.Simple, Frequency.Semiannual, 0.0300, 4), + new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.25, Compounding.Simple, Frequency.Quarterly, 0.0300, 4), + new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.50, Compounding.Simple, Frequency.Annual, 0.0300, 4), + new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.50, Compounding.Simple, Frequency.Semiannual, 0.0300, 4), + new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.75, Compounding.Compounded, Frequency.Semiannual, 0.0300, 4), + + new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.25, Compounding.SimpleThenCompounded, Frequency.Quarterly, 0.0400, 4), + new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.25, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.0400, 4), + new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.25, Compounding.SimpleThenCompounded, Frequency.Annual, 0.0400, 4), + + new InterestRateData(0.0400, Compounding.Compounded, Frequency.Quarterly, 0.50, Compounding.SimpleThenCompounded, Frequency.Quarterly, 0.0400, 4), + new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.50, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.0400, 4), + new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.50, Compounding.SimpleThenCompounded, Frequency.Annual, 0.0400, 4), + + new InterestRateData(0.0400, Compounding.Compounded, Frequency.Quarterly, 0.75, Compounding.SimpleThenCompounded, Frequency.Quarterly, 0.0400, 4), + new InterestRateData(0.0400, Compounding.Compounded, Frequency.Semiannual, 0.75, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.0400, 4), + new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.75, Compounding.SimpleThenCompounded, Frequency.Annual, 0.0400, 4) }; Rounding roundingPrecision; @@ -119,10 +120,10 @@ public void testConversions() double error; double disc; - for (int i = 0; i < cases.Length-1 ; i++) + for (int i = 0; i < cases.Length - 1 ; i++) { ir = new InterestRate(cases[i].r, new Actual360(), cases[i].comp, cases[i].freq); - d2 = d1 + new Period((int)(360 * cases[i].t + 0.5) ,TimeUnit.Days); + d2 = d1 + new Period((int)(360 * cases[i].t + 0.5), TimeUnit.Days); roundingPrecision = new Rounding(cases[i].precision); // check that the compound factor is the inverse of the discount factor @@ -149,7 +150,7 @@ public void testConversions() // check that the equivalent rate with *same* daycounter, // compounding, and frequency is the *same* rate //r2 = ir.equivalentRate(d1, d2, ir.dayCounter(), ir.compounding(), ir.frequency()).rate(); - r2 = ir.equivalentRate(ir.dayCounter(), ir.compounding(), ir.frequency(),d1, d2).value(); + r2 = ir.equivalentRate(ir.dayCounter(), ir.compounding(), ir.frequency(), d1, d2).value(); error = Math.Abs(ir.rate() - r2); if (error > 1e-15) QAssert.Fail("original rate: " + ir + " equivalent rate: " + r2 + " error: " + error); diff --git a/tests/QLNet.Tests/T_Interpolations.cs b/tests/QLNet.Tests/T_Interpolations.cs index 59077434c..55071c8a1 100644 --- a/tests/QLNet.Tests/T_Interpolations.cs +++ b/tests/QLNet.Tests/T_Interpolations.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,17 +23,17 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; -namespace TestSuite +namespace TestSuite { #if NET40 || NET45 [TestClass()] #endif - public class T_Interpolations + public class T_Interpolations { /* See J. M. Hyman, "Accurate monotonicity preserving cubic interpolation" @@ -41,11 +41,11 @@ public class T_Interpolations http://math.lanl.gov/~mac/papers/numerics/H83.pdf */ #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testSplineErrorOnGaussianValues() + public void testSplineErrorOnGaussianValues() { //("Testing spline approximation on Gaussian data sets..."); @@ -68,39 +68,40 @@ public void testSplineErrorOnGaussianValues() // results from the paper double scaleFactor = 1.9; - for (int i=0; i x = xRange(-1.7, 1.9, n); - List y = gaussian(x); - - // Not-a-knot - CubicInterpolation f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.NotAKnot, 0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0); - f.update(); - double result = Math.Sqrt(integral.value(make_error_function(f).value, -1.7, 1.9)); - result /= scaleFactor; - if (Math.Abs(result-tabulatedErrors[i]) > toleranceOnTabErr[i]) - QAssert.Fail("Not-a-knot spline interpolation " - + "\n sample points: " + n - + "\n norm of difference: " + result - + "\n it should be: " + tabulatedErrors[i]); - - // MC not-a-knot - f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.NotAKnot, 0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0); - f.update(); - result = Math.Sqrt(integral.value(make_error_function(f).value, -1.7, 1.9)); - result /= scaleFactor; - if (Math.Abs(result-tabulatedMCErrors[i]) > toleranceOnTabMCErr[i]) - QAssert.Fail("MC Not-a-knot spline interpolation " - + "\n sample points: " + n - + "\n norm of difference: " + result - + "\n it should be: " - + tabulatedMCErrors[i]); + for (int i = 0; i < points.Length; i++) + { + int n = points[i]; + List x = xRange(-1.7, 1.9, n); + List y = gaussian(x); + + // Not-a-knot + CubicInterpolation f = new CubicInterpolation(x, x.Count, y, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.NotAKnot, 0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0); + f.update(); + double result = Math.Sqrt(integral.value(make_error_function(f).value, -1.7, 1.9)); + result /= scaleFactor; + if (Math.Abs(result - tabulatedErrors[i]) > toleranceOnTabErr[i]) + QAssert.Fail("Not-a-knot spline interpolation " + + "\n sample points: " + n + + "\n norm of difference: " + result + + "\n it should be: " + tabulatedErrors[i]); + + // MC not-a-knot + f = new CubicInterpolation(x, x.Count, y, + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.NotAKnot, 0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0); + f.update(); + result = Math.Sqrt(integral.value(make_error_function(f).value, -1.7, 1.9)); + result /= scaleFactor; + if (Math.Abs(result - tabulatedMCErrors[i]) > toleranceOnTabMCErr[i]) + QAssert.Fail("MC Not-a-knot spline interpolation " + + "\n sample points: " + n + + "\n norm of difference: " + result + + "\n it should be: " + + tabulatedMCErrors[i]); } } @@ -109,11 +110,12 @@ public void testSplineErrorOnGaussianValues() http://math.lanl.gov/~mac/papers/numerics/H83.pdf */ #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testSplineOnGaussianValues() { + public void testSplineOnGaussianValues() + { //("Testing spline interpolation on a Gaussian data set..."); @@ -121,57 +123,61 @@ public void testSplineOnGaussianValues() { int n = 5; List x = new InitializedList(n), y = new InitializedList(n); - double x1_bad=-1.7, x2_bad=1.7; - - for (double start = -1.9, j=0; j<2; start+=0.2, j++) { - x = xRange(start, start+3.6, n); - y = gaussian(x); + double x1_bad = -1.7, x2_bad = 1.7; - // Not-a-knot spline - CubicInterpolation f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.NotAKnot, 0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0); - f.update(); - checkValues("Not-a-knot spline", f, x, y); - checkNotAKnotCondition("Not-a-knot spline", f); - // bad performance - interpolated = f.value(x1_bad); - interpolated2= f.value(x2_bad); - if (interpolated>0.0 && interpolated2>0.0 ) { - QAssert.Fail("Not-a-knot spline interpolation " - + "bad performance unverified" - + "\nat x = " + x1_bad - + " interpolated value: " + interpolated - + "\nat x = " + x2_bad - + " interpolated value: " + interpolated - + "\n at least one of them was expected to be < 0.0"); - } + for (double start = -1.9, j = 0; j < 2; start += 0.2, j++) + { + x = xRange(start, start + 3.6, n); + y = gaussian(x); + + // Not-a-knot spline + CubicInterpolation f = new CubicInterpolation(x, x.Count, y, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.NotAKnot, 0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0); + f.update(); + checkValues("Not-a-knot spline", f, x, y); + checkNotAKnotCondition("Not-a-knot spline", f); + // bad performance + interpolated = f.value(x1_bad); + interpolated2 = f.value(x2_bad); + if (interpolated > 0.0 && interpolated2 > 0.0) + { + QAssert.Fail("Not-a-knot spline interpolation " + + "bad performance unverified" + + "\nat x = " + x1_bad + + " interpolated value: " + interpolated + + "\nat x = " + x2_bad + + " interpolated value: " + interpolated + + "\n at least one of them was expected to be < 0.0"); + } - // MC not-a-knot spline - f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.NotAKnot, 0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0); - f.update(); - checkValues("MC not-a-knot spline", f, x, y); - // good performance - interpolated = f.value(x1_bad); - if (interpolated<0.0) { - QAssert.Fail("MC not-a-knot spline interpolation " - + "good performance unverified\n" - + "at x = " + x1_bad - + "\ninterpolated value: " + interpolated - + "\nexpected value > 0.0"); - } - interpolated = f.value(x2_bad); - if (interpolated<0.0) { - QAssert.Fail("MC not-a-knot spline interpolation " - + "good performance unverified\n" - + "at x = " + x2_bad - + "\ninterpolated value: " + interpolated - + "\nexpected value > 0.0"); - } + // MC not-a-knot spline + f = new CubicInterpolation(x, x.Count, y, + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.NotAKnot, 0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0); + f.update(); + checkValues("MC not-a-knot spline", f, x, y); + // good performance + interpolated = f.value(x1_bad); + if (interpolated < 0.0) + { + QAssert.Fail("MC not-a-knot spline interpolation " + + "good performance unverified\n" + + "at x = " + x1_bad + + "\ninterpolated value: " + interpolated + + "\nexpected value > 0.0"); + } + interpolated = f.value(x2_bad); + if (interpolated < 0.0) + { + QAssert.Fail("MC not-a-knot spline interpolation " + + "good performance unverified\n" + + "at x = " + x2_bad + + "\ninterpolated value: " + interpolated + + "\nexpected value > 0.0"); + } } } @@ -180,30 +186,33 @@ public void testSplineOnGaussianValues() { http://math.lanl.gov/~mac/papers/numerics/H83.pdf */ #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testSplineOnRPN15AValues() { + public void testSplineOnRPN15AValues() + { //("Testing spline interpolation on RPN15A data set..."); - List RPN15A_x = new List() { - 7.99, 8.09, 8.19, 8.7, - 9.2, 10.0, 12.0, 15.0, 20.0 + List RPN15A_x = new List() + { + 7.99, 8.09, 8.19, 8.7, + 9.2, 10.0, 12.0, 15.0, 20.0 }; - List RPN15A_y = new List() { - 0.0, 2.76429e-5, 4.37498e-5, 0.169183, - 0.469428, 0.943740, 0.998636, 0.999919, 0.999994 + List RPN15A_y = new List() + { + 0.0, 2.76429e-5, 4.37498e-5, 0.169183, + 0.469428, 0.943740, 0.998636, 0.999919, 0.999994 }; double interpolated; // Natural spline CubicInterpolation f = new CubicInterpolation(RPN15A_x, RPN15A_x.Count, RPN15A_y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0); + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0); f.update(); checkValues("Natural spline", f, RPN15A_x, RPN15A_y); check2ndDerivativeValue("Natural spline", f, RPN15A_x.First(), 0.0); @@ -211,78 +220,82 @@ public void testSplineOnRPN15AValues() { // poor performance double x_bad = 11.0; interpolated = f.value(x_bad); - if (interpolated<1.0) { - QAssert.Fail("Natural spline interpolation " - + "poor performance unverified\n" - + "at x = " + x_bad - + "\ninterpolated value: " + interpolated - + "\nexpected value > 1.0"); + if (interpolated < 1.0) + { + QAssert.Fail("Natural spline interpolation " + + "poor performance unverified\n" + + "at x = " + x_bad + + "\ninterpolated value: " + interpolated + + "\nexpected value > 1.0"); } // Clamped spline f = new CubicInterpolation(RPN15A_x, RPN15A_x.Count, RPN15A_y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.FirstDerivative, 0.0, - CubicInterpolation.BoundaryCondition.FirstDerivative, 0.0); + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.FirstDerivative, 0.0, + CubicInterpolation.BoundaryCondition.FirstDerivative, 0.0); f.update(); checkValues("Clamped spline", f, RPN15A_x, RPN15A_y); check1stDerivativeValue("Clamped spline", f, RPN15A_x.First(), 0.0); check1stDerivativeValue("Clamped spline", f, RPN15A_x.Last(), 0.0); // poor performance interpolated = f.value(x_bad); - if (interpolated<1.0) { - QAssert.Fail("Clamped spline interpolation " - + "poor performance unverified\n" - + "at x = " + x_bad - + "\ninterpolated value: " + interpolated - + "\nexpected value > 1.0"); + if (interpolated < 1.0) + { + QAssert.Fail("Clamped spline interpolation " + + "poor performance unverified\n" + + "at x = " + x_bad + + "\ninterpolated value: " + interpolated + + "\nexpected value > 1.0"); } // Not-a-knot spline f = new CubicInterpolation(RPN15A_x, RPN15A_x.Count, RPN15A_y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.NotAKnot, 0.0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0.0); + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.NotAKnot, 0.0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0.0); f.update(); checkValues("Not-a-knot spline", f, RPN15A_x, RPN15A_y); checkNotAKnotCondition("Not-a-knot spline", f); // poor performance interpolated = f.value(x_bad); - if (interpolated<1.0) { - QAssert.Fail("Not-a-knot spline interpolation " - + "poor performance unverified\n" - + "at x = " + x_bad - + "\ninterpolated value: " + interpolated - + "\nexpected value > 1.0"); + if (interpolated < 1.0) + { + QAssert.Fail("Not-a-knot spline interpolation " + + "poor performance unverified\n" + + "at x = " + x_bad + + "\ninterpolated value: " + interpolated + + "\nexpected value > 1.0"); } // MC natural spline values f = new CubicInterpolation(RPN15A_x, RPN15A_x.Count, RPN15A_y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0); + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0); f.update(); checkValues("MC natural spline", f, RPN15A_x, RPN15A_y); // good performance interpolated = f.value(x_bad); - if (interpolated>1.0) { - QAssert.Fail("MC natural spline interpolation " - + "good performance unverified\n" - + "at x = " + x_bad - + "\ninterpolated value: " + interpolated - + "\nexpected value < 1.0"); + if (interpolated > 1.0) + { + QAssert.Fail("MC natural spline interpolation " + + "good performance unverified\n" + + "at x = " + x_bad + + "\ninterpolated value: " + interpolated + + "\nexpected value < 1.0"); } // MC clamped spline values f = new CubicInterpolation(RPN15A_x, RPN15A_x.Count, RPN15A_y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.FirstDerivative, 0.0, - CubicInterpolation.BoundaryCondition.FirstDerivative, 0.0); + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.FirstDerivative, 0.0, + CubicInterpolation.BoundaryCondition.FirstDerivative, 0.0); f.update(); checkValues("MC clamped spline", f, RPN15A_x, RPN15A_y); check1stDerivativeValue("MC clamped spline", f, RPN15A_x.First(), 0.0); @@ -290,30 +303,32 @@ public void testSplineOnRPN15AValues() { // good performance interpolated = f.value(x_bad); - if (interpolated>1.0) { - QAssert.Fail("MC clamped spline interpolation " - + "good performance unverified\n" - + "at x = " + x_bad - + "\ninterpolated value: " + interpolated - + "\nexpected value < 1.0"); + if (interpolated > 1.0) + { + QAssert.Fail("MC clamped spline interpolation " + + "good performance unverified\n" + + "at x = " + x_bad + + "\ninterpolated value: " + interpolated + + "\nexpected value < 1.0"); } // MC not-a-knot spline values f = new CubicInterpolation(RPN15A_x, RPN15A_x.Count, RPN15A_y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.NotAKnot, 0.0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0.0); + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.NotAKnot, 0.0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0.0); f.update(); checkValues("MC not-a-knot spline", f, RPN15A_x, RPN15A_y); // good performance interpolated = f.value(x_bad); - if (interpolated>1.0) { - QAssert.Fail("MC clamped spline interpolation " - + "good performance unverified\n" - + "at x = " + x_bad - + "\ninterpolated value: " + interpolated - + "\nexpected value < 1.0"); + if (interpolated > 1.0) + { + QAssert.Fail("MC clamped spline interpolation " + + "good performance unverified\n" + + "at x = " + x_bad + + "\ninterpolated value: " + interpolated + + "\nexpected value < 1.0"); } } @@ -322,11 +337,12 @@ Applied Linear Algebra and Numerical Analysis AMATH 352 Lecture Notes http://www.amath.washington.edu/courses/352-winter-2002/spline_note.pdf */ #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testSplineOnGenericValues() { + public void testSplineOnGenericValues() + { //("Testing spline interpolation on generic values..."); @@ -340,24 +356,26 @@ public void testSplineOnGenericValues() { // Natural spline CubicInterpolation f = new CubicInterpolation(generic_x, generic_x.Count, generic_y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, - generic_natural_y2[0], - CubicInterpolation.BoundaryCondition.SecondDerivative, - generic_natural_y2[n-1]); + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, + generic_natural_y2[0], + CubicInterpolation.BoundaryCondition.SecondDerivative, + generic_natural_y2[n - 1]); f.update(); checkValues("Natural spline", f, generic_x, generic_y); // cached second derivative - for (i=0; i3e-16) { - QAssert.Fail("Natural spline interpolation " - + "second derivative failed at x=" + generic_x[i] - + "\ninterpolated value: " + interpolated - + "\nexpected value: " + generic_natural_y2[i] - + "\nerror: " + error); - } + for (i = 0; i < n; i++) + { + interpolated = f.secondDerivative(generic_x[i]); + error = interpolated - generic_natural_y2[i]; + if (Math.Abs(error) > 3e-16) + { + QAssert.Fail("Natural spline interpolation " + + "second derivative failed at x=" + generic_x[i] + + "\ninterpolated value: " + interpolated + + "\nexpected value: " + generic_natural_y2[i] + + "\nerror: " + error); + } } x35[1] = f.value(3.5); @@ -365,9 +383,9 @@ public void testSplineOnGenericValues() { // Clamped spline double y1a = 0.0, y1b = 0.0; f = new CubicInterpolation(generic_x, generic_x.Count, generic_y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.FirstDerivative, y1a, - CubicInterpolation.BoundaryCondition.FirstDerivative, y1b); + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.FirstDerivative, y1a, + CubicInterpolation.BoundaryCondition.FirstDerivative, y1b); f.update(); checkValues("Clamped spline", f, generic_x, generic_y); check1stDerivativeValue("Clamped spline", f, generic_x.First(), 0.0); @@ -377,31 +395,33 @@ public void testSplineOnGenericValues() { // Not-a-knot spline f = new CubicInterpolation(generic_x, generic_x.Count, generic_y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.NotAKnot, 0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0); + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.NotAKnot, 0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0); f.update(); checkValues("Not-a-knot spline", f, generic_x, generic_y); checkNotAKnotCondition("Not-a-knot spline", f); x35[2] = f.value(3.5); - if (x35[0]>x35[1] || x35[1]>x35[2]) { - QAssert.Fail("Spline interpolation failure" - + "\nat x = " + 3.5 - + "\nclamped spline " + x35[0] - + "\nnatural spline " + x35[1] - + "\nnot-a-knot spline " + x35[2] - + "\nvalues should be in increasing order"); + if (x35[0] > x35[1] || x35[1] > x35[2]) + { + QAssert.Fail("Spline interpolation failure" + + "\nat x = " + 3.5 + + "\nclamped spline " + x35[0] + + "\nnatural spline " + x35[1] + + "\nnot-a-knot spline " + x35[2] + + "\nvalues should be in increasing order"); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testSimmetricEndConditions() { + public void testSimmetricEndConditions() + { //("Testing symmetry of spline interpolation end-conditions..."); @@ -413,9 +433,9 @@ public void testSimmetricEndConditions() { // Not-a-knot spline CubicInterpolation f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.NotAKnot, 0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0); + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.NotAKnot, 0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0); f.update(); checkValues("Not-a-knot spline", f, x, y); checkNotAKnotCondition("Not-a-knot spline", f); @@ -424,20 +444,21 @@ public void testSimmetricEndConditions() { // MC not-a-knot spline f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.NotAKnot, 0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0); + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.NotAKnot, 0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0); f.update(); checkValues("MC not-a-knot spline", f, x, y); checkSymmetry("MC not-a-knot spline", f, x[0]); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testDerivativeEndConditions() { + public void testDerivativeEndConditions() + { //("Testing derivative end-conditions for spline interpolation..."); @@ -449,83 +470,83 @@ public void testDerivativeEndConditions() { // Not-a-knot spline CubicInterpolation f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.NotAKnot, 0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0); + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.NotAKnot, 0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0); f.update(); checkValues("Not-a-knot spline", f, x, y); check1stDerivativeValue("Not-a-knot spline", f, x[0], 4.0); - check1stDerivativeValue("Not-a-knot spline", f, x[n-1], -4.0); + check1stDerivativeValue("Not-a-knot spline", f, x[n - 1], -4.0); check2ndDerivativeValue("Not-a-knot spline", f, x[0], -2.0); - check2ndDerivativeValue("Not-a-knot spline", f, x[n-1], -2.0); + check2ndDerivativeValue("Not-a-knot spline", f, x[n - 1], -2.0); // Clamped spline f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.FirstDerivative, 4.0, - CubicInterpolation.BoundaryCondition.FirstDerivative, -4.0); + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.FirstDerivative, 4.0, + CubicInterpolation.BoundaryCondition.FirstDerivative, -4.0); f.update(); checkValues("Clamped spline", f, x, y); check1stDerivativeValue("Clamped spline", f, x[0], 4.0); - check1stDerivativeValue("Clamped spline", f, x[n-1], -4.0); + check1stDerivativeValue("Clamped spline", f, x[n - 1], -4.0); check2ndDerivativeValue("Clamped spline", f, x[0], -2.0); - check2ndDerivativeValue("Clamped spline", f, x[n-1], -2.0); + check2ndDerivativeValue("Clamped spline", f, x[n - 1], -2.0); // SecondDerivative spline f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0); + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0); f.update(); checkValues("SecondDerivative spline", f, x, y); check1stDerivativeValue("SecondDerivative spline", f, x[0], 4.0); - check1stDerivativeValue("SecondDerivative spline", f, x[n-1], -4.0); + check1stDerivativeValue("SecondDerivative spline", f, x[n - 1], -4.0); check2ndDerivativeValue("SecondDerivative spline", f, x[0], -2.0); - check2ndDerivativeValue("SecondDerivative spline", f, x[n-1], -2.0); + check2ndDerivativeValue("SecondDerivative spline", f, x[n - 1], -2.0); // MC Not-a-knot spline f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.NotAKnot, 0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0); + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.NotAKnot, 0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0); f.update(); checkValues("MC Not-a-knot spline", f, x, y); check1stDerivativeValue("MC Not-a-knot spline", f, x[0], 4.0); - check1stDerivativeValue("MC Not-a-knot spline", f, x[n-1], -4.0); + check1stDerivativeValue("MC Not-a-knot spline", f, x[n - 1], -4.0); check2ndDerivativeValue("MC Not-a-knot spline", f, x[0], -2.0); - check2ndDerivativeValue("MC Not-a-knot spline", f, x[n-1], -2.0); + check2ndDerivativeValue("MC Not-a-knot spline", f, x[n - 1], -2.0); // MC Clamped spline f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.FirstDerivative, 4.0, - CubicInterpolation.BoundaryCondition.FirstDerivative, -4.0); + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.FirstDerivative, 4.0, + CubicInterpolation.BoundaryCondition.FirstDerivative, -4.0); f.update(); checkValues("MC Clamped spline", f, x, y); check1stDerivativeValue("MC Clamped spline", f, x[0], 4.0); - check1stDerivativeValue("MC Clamped spline", f, x[n-1], -4.0); + check1stDerivativeValue("MC Clamped spline", f, x[n - 1], -4.0); check2ndDerivativeValue("MC Clamped spline", f, x[0], -2.0); - check2ndDerivativeValue("MC Clamped spline", f, x[n-1], -2.0); + check2ndDerivativeValue("MC Clamped spline", f, x[n - 1], -2.0); // MC SecondDerivative spline f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0); + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0); f.update(); checkValues("MC SecondDerivative spline", f, x, y); check1stDerivativeValue("MC SecondDerivative spline", f, x[0], 4.0); - check1stDerivativeValue("MC SecondDerivative spline", f, x[n-1], -4.0); + check1stDerivativeValue("MC SecondDerivative spline", f, x[n - 1], -4.0); check2ndDerivativeValue("MC SecondDerivative spline", f, x[0], -2.0); - check2ndDerivativeValue("MC SecondDerivative spline", f, x[n-1], -2.0); + check2ndDerivativeValue("MC SecondDerivative spline", f, x[n - 1], -2.0); } /* See R. L. Dougherty, A. Edelman, J. M. Hyman, @@ -534,11 +555,12 @@ Hermite Interpolation" Mathematics Of Computation, v. 52, n. 186, April 1989, pp. 471-494. */ #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testNonRestrictiveHymanFilter() { + public void testNonRestrictiveHymanFilter() + { //("Testing non-restrictive Hyman filter..."); @@ -547,69 +569,72 @@ public void testNonRestrictiveHymanFilter() { List x, y; x = xRange(-2.0, 2.0, n); y = parabolic(x); - double zero=0.0, interpolated, expected=0.0; + double zero = 0.0, interpolated, expected = 0.0; // MC Not-a-knot spline CubicInterpolation f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.NotAKnot, 0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0); + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.NotAKnot, 0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0); f.update(); interpolated = f.value(zero); - if (Math.Abs(interpolated-expected)>1e-15) { - QAssert.Fail("MC not-a-knot spline" - + " interpolation failed at x = " + zero - + "\n interpolated value: " + interpolated - + "\n expected value: " + expected - + "\n error: " - + Math.Abs(interpolated-expected)); + if (Math.Abs(interpolated - expected) > 1e-15) + { + QAssert.Fail("MC not-a-knot spline" + + " interpolation failed at x = " + zero + + "\n interpolated value: " + interpolated + + "\n expected value: " + expected + + "\n error: " + + Math.Abs(interpolated - expected)); } // MC Clamped spline f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.FirstDerivative, 4.0, - CubicInterpolation.BoundaryCondition.FirstDerivative, -4.0); + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.FirstDerivative, 4.0, + CubicInterpolation.BoundaryCondition.FirstDerivative, -4.0); f.update(); interpolated = f.value(zero); - if (Math.Abs(interpolated-expected)>1e-15) { - QAssert.Fail("MC clamped spline" - + " interpolation failed at x = " + zero - + "\n interpolated value: " + interpolated - + "\n expected value: " + expected - + "\n error: " - + Math.Abs(interpolated-expected)); + if (Math.Abs(interpolated - expected) > 1e-15) + { + QAssert.Fail("MC clamped spline" + + " interpolation failed at x = " + zero + + "\n interpolated value: " + interpolated + + "\n expected value: " + expected + + "\n error: " + + Math.Abs(interpolated - expected)); } // MC SecondDerivative spline f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0); + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0); f.update(); interpolated = f.value(zero); - if (Math.Abs(interpolated-expected)>1e-15) { - QAssert.Fail("MC SecondDerivative spline" - + " interpolation failed at x = " + zero - + "\n interpolated value: " + interpolated - + "\n expected value: " + expected - + "\n error: " - + Math.Abs(interpolated-expected)); + if (Math.Abs(interpolated - expected) > 1e-15) + { + QAssert.Fail("MC SecondDerivative spline" + + " interpolation failed at x = " + zero + + "\n interpolated value: " + interpolated + + "\n expected value: " + expected + + "\n error: " + + Math.Abs(interpolated - expected)); } } - + //[TestMethod()] - //public void testMultiSpline() + //public void testMultiSpline() //{ // // Testing N-dimensional cubic spline... // List dim = new List() { 6, 5, 5, 6, 4 }; - // List args = new InitializedList(5), + // List args = new InitializedList(5), // offsets = new List() { 1.005, 14.0, 33.005, 35.025, 19.025 }; // double s = args[0] = offsets[0], @@ -707,11 +732,12 @@ public void testNonRestrictiveHymanFilter() { class NotThrown : Exception { } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testAsFunctor() { + public void testAsFunctor() + { //("Testing use of interpolations as functors..."); @@ -727,42 +753,48 @@ public void testAsFunctor() { double tolerance = 1.0e-12; // case 1: extrapolation not allowed - try { - for ( int xx = 0; xx < x2.Count; xx++) - { - y2[xx] = f.value(x2[xx]); - } - //y2 = x2.ConvertAll(f.value); - throw new NotThrown(); - } catch (NotThrown) { - throw new Exception("failed to throw exception when trying to extrapolate"); - } catch { } + try + { + for (int xx = 0; xx < x2.Count; xx++) + { + y2[xx] = f.value(x2[xx]); + } + //y2 = x2.ConvertAll(f.value); + throw new NotThrown(); + } + catch (NotThrown) + { + throw new Exception("failed to throw exception when trying to extrapolate"); + } + catch { } // case 2: enable extrapolation f.enableExtrapolation(); y2 = new InitializedList(N); - for ( int xx = 0; xx < x2.Count; xx++ ) + for (int xx = 0; xx < x2.Count; xx++) { - y2[xx] = f.value( x2[xx] ); + y2[xx] = f.value(x2[xx]); } //y2 = x2.ConvertAll(f.value); - for (int i=0; i tolerance) - QAssert.Fail( - "failed to reproduce " + (i+1) + " expected datum" - + "\n expected: " + expected - + "\n calculated: " + y2[i] - + "\n error: " + Math.Abs(y2[i]-expected)); + for (int i = 0; i < N; i++) + { + double expected = 5.0 - x2[i]; + if (Math.Abs(y2[i] - expected) > tolerance) + QAssert.Fail( + "failed to reproduce " + (i + 1) + " expected datum" + + "\n expected: " + expected + + "\n calculated: " + y2[i] + + "\n error: " + Math.Abs(y2[i] - expected)); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testBackwardFlat() { + public void testBackwardFlat() + { //("Testing backward-flat interpolation..."); @@ -777,29 +809,31 @@ public void testBackwardFlat() { double tolerance = 1.0e-12, p, calculated, expected; // at original points - for (i=0; i tolerance) - QAssert.Fail( - "failed to reproduce " + (i+1) + " datum" - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); + for (i = 0; i < N; i++) + { + p = x[i]; + calculated = f.value(p); + expected = y[i]; + if (Math.Abs(expected - calculated) > tolerance) + QAssert.Fail( + "failed to reproduce " + (i + 1) + " datum" + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated - expected)); } // at middle points - for (i=0; i tolerance) - QAssert.Fail( - "failed to interpolate correctly at " + p - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); + for (i = 0; i < N - 1; i++) + { + p = (x[i] + x[i + 1]) / 2; + calculated = f.value(p); + expected = y[i + 1]; + if (Math.Abs(expected - calculated) > tolerance) + QAssert.Fail( + "failed to interpolate correctly at " + p + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated - expected)); } // outside the original range @@ -808,70 +842,73 @@ public void testBackwardFlat() { p = x[0] - 0.5; calculated = f.value(p); expected = y[0]; - if (Math.Abs(expected-calculated) > tolerance) - QAssert.Fail( - "failed to extrapolate correctly at " + p - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); - - p = x[N-1] + 0.5; + if (Math.Abs(expected - calculated) > tolerance) + QAssert.Fail( + "failed to extrapolate correctly at " + p + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated - expected)); + + p = x[N - 1] + 0.5; calculated = f.value(p); - expected = y[N-1]; - if (Math.Abs(expected-calculated) > tolerance) - QAssert.Fail( - "failed to extrapolate correctly at " + p - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); + expected = y[N - 1]; + if (Math.Abs(expected - calculated) > tolerance) + QAssert.Fail( + "failed to extrapolate correctly at " + p + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated - expected)); // primitive at original points calculated = f.primitive(x[0]); expected = 0.0; - if (Math.Abs(expected-calculated) > tolerance) + if (Math.Abs(expected - calculated) > tolerance) + QAssert.Fail( + "failed to calculate primitive at " + x[0] + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated - expected)); + + double sum = 0.0; + for (i = 1; i < N; i++) + { + sum += (x[i] - x[i - 1]) * y[i]; + calculated = f.primitive(x[i]); + expected = sum; + if (Math.Abs(expected - calculated) > tolerance) QAssert.Fail( - "failed to calculate primitive at " + x[0] + "failed to calculate primitive at " + x[i] + "\n expected: " + expected + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); - - double sum = 0.0; - for (i=1; i tolerance) - QAssert.Fail( - "failed to calculate primitive at " + x[i] - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); + + "\n error: " + Math.Abs(calculated - expected)); } // primitive at middle points sum = 0.0; - for (i=0; i tolerance) - QAssert.Fail( - "failed to calculate primitive at " + x[i] - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); + for (i = 0; i < N - 1; i++) + { + p = (x[i] + x[i + 1]) / 2; + sum += (x[i + 1] - x[i]) * y[i + 1] / 2; + calculated = f.primitive(p); + expected = sum; + sum += (x[i + 1] - x[i]) * y[i + 1] / 2; + if (Math.Abs(expected - calculated) > tolerance) + QAssert.Fail( + "failed to calculate primitive at " + x[i] + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated - expected)); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testForwardFlat() { + public void testForwardFlat() + { //("Testing forward-flat interpolation..."); @@ -886,29 +923,31 @@ public void testForwardFlat() { double tolerance = 1.0e-12, p, calculated, expected; // at original points - for (i=0; i tolerance) - QAssert.Fail( - "failed to reproduce " + (i+1) + " datum" - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); + for (i = 0; i < N; i++) + { + p = x[i]; + calculated = f.value(p); + expected = y[i]; + if (Math.Abs(expected - calculated) > tolerance) + QAssert.Fail( + "failed to reproduce " + (i + 1) + " datum" + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated - expected)); } // at middle points - for (i=0; i tolerance) - QAssert.Fail( - "failed to interpolate correctly at " + p - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); + for (i = 0; i < N - 1; i++) + { + p = (x[i] + x[i + 1]) / 2; + calculated = f.value(p); + expected = y[i]; + if (Math.Abs(expected - calculated) > tolerance) + QAssert.Fail( + "failed to interpolate correctly at " + p + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated - expected)); } // outside the original range @@ -917,67 +956,69 @@ public void testForwardFlat() { p = x[0] - 0.5; calculated = f.value(p); expected = y[0]; - if (Math.Abs(expected-calculated) > tolerance) - QAssert.Fail( - "failed to extrapolate correctly at " + p - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); - - p = x[N-1] + 0.5; + if (Math.Abs(expected - calculated) > tolerance) + QAssert.Fail( + "failed to extrapolate correctly at " + p + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated - expected)); + + p = x[N - 1] + 0.5; calculated = f.value(p); - expected = y[N-1]; - if (Math.Abs(expected-calculated) > tolerance) - QAssert.Fail( - "failed to extrapolate correctly at " + p - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); + expected = y[N - 1]; + if (Math.Abs(expected - calculated) > tolerance) + QAssert.Fail( + "failed to extrapolate correctly at " + p + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated - expected)); // primitive at original points calculated = f.primitive(x[0]); expected = 0.0; - if (Math.Abs(expected-calculated) > tolerance) + if (Math.Abs(expected - calculated) > tolerance) + QAssert.Fail( + "failed to calculate primitive at " + x[0] + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated - expected)); + + double sum = 0.0; + for (i = 1; i < N; i++) + { + sum += (x[i] - x[i - 1]) * y[i - 1]; + calculated = f.primitive(x[i]); + expected = sum; + if (Math.Abs(expected - calculated) > tolerance) QAssert.Fail( - "failed to calculate primitive at " + x[0] + "failed to calculate primitive at " + x[i] + "\n expected: " + expected + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); - - double sum = 0.0; - for (i=1; i tolerance) - QAssert.Fail( - "failed to calculate primitive at " + x[i] - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); + + "\n error: " + Math.Abs(calculated - expected)); } // primitive at middle points sum = 0.0; - for (i=0; i tolerance) - QAssert.Fail( - "failed to calculate primitive at " + p - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); + for (i = 0; i < N - 1; i++) + { + p = (x[i] + x[i + 1]) / 2; + sum += (x[i + 1] - x[i]) * y[i] / 2; + calculated = f.primitive(p); + expected = sum; + sum += (x[i + 1] - x[i]) * y[i] / 2; + if (Math.Abs(expected - calculated) > tolerance) + QAssert.Fail( + "failed to calculate primitive at " + p + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated - expected)); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testSabrInterpolation() { @@ -986,7 +1027,7 @@ public void testSabrInterpolation() // Test SABR function against input volatilities double tolerance = 1.0e-12; List strikes = new InitializedList(31); - List volatilities = new InitializedList( 31 ); + List volatilities = new InitializedList(31); // input strikes strikes[0] = 0.03 ; strikes[1] = 0.032 ; strikes[2] = 0.034 ; strikes[3] = 0.036 ; strikes[4] = 0.038 ; strikes[5] = 0.04 ; @@ -1020,16 +1061,16 @@ public void testSabrInterpolation() double initialNu = 0.02; double initialRho = 0.01; // calculate SABR vols and compare with input vols - for(int i=0; i< strikes.Count; i++) + for (int i = 0; i < strikes.Count; i++) { double calculatedVol = Utils.sabrVolatility(strikes[i], forward, expiry, - initialAlpha, initialBeta, - initialNu, initialRho); - if (Math.Abs(volatilities[i]-calculatedVol) > tolerance) - QAssert.Fail( "failed to calculate Sabr function at strike " + strikes[i] - + "\n expected: " + volatilities[i] - + "\n calculated: " + calculatedVol - + "\n error: " + Math.Abs(calculatedVol-volatilities[i])); + initialAlpha, initialBeta, + initialNu, initialRho); + if (Math.Abs(volatilities[i] - calculatedVol) > tolerance) + QAssert.Fail("failed to calculate Sabr function at strike " + strikes[i] + + "\n expected: " + volatilities[i] + + "\n calculated: " + calculatedVol + + "\n error: " + Math.Abs(calculatedVol - volatilities[i])); } // Test SABR calibration against input parameters @@ -1042,31 +1083,31 @@ public void testSabrInterpolation() double nuGuess = Math.Sqrt(0.4); double rhoGuess = 0.0; - bool[] vegaWeighted= {true, false}; - bool[] isAlphaFixed= {true, false}; - bool[] isBetaFixed= {true, false}; - bool[] isNuFixed= {true, false}; - bool[] isRhoFixed= {true, false}; + bool[] vegaWeighted = {true, false}; + bool[] isAlphaFixed = {true, false}; + bool[] isBetaFixed = {true, false}; + bool[] isNuFixed = {true, false}; + bool[] isRhoFixed = {true, false}; double calibrationTolerance = 5.0e-8; // initialize optimization methods List methods_ = new List(); - methods_.Add( new Simplex(0.01)); - methods_.Add( new LevenbergMarquardt(1e-8, 1e-8, 1e-8)); + methods_.Add(new Simplex(0.01)); + methods_.Add(new LevenbergMarquardt(1e-8, 1e-8, 1e-8)); // Initialize end criteria EndCriteria endCriteria = new EndCriteria(100000, 100, 1e-8, 1e-8, 1e-8); // Test looping over all possibilities - for (int j=0; j calibrationTolerance) { + error = Math.Abs(initialAlpha - calibratedAlpha); + if (error > calibrationTolerance) + { QAssert.Fail("\nfailed to calibrate alpha Sabr parameter:" + - "\n expected: " + initialAlpha + - "\n calibrated: " + calibratedAlpha + - "\n error: " + error); + "\n expected: " + initialAlpha + + "\n calibrated: " + calibratedAlpha + + "\n error: " + error); failed = true; } // Beta - error = Math.Abs(initialBeta-calibratedBeta); - if (error > calibrationTolerance) { + error = Math.Abs(initialBeta - calibratedBeta); + if (error > calibrationTolerance) + { QAssert.Fail("\nfailed to calibrate beta Sabr parameter:" + - "\n expected: " + initialBeta + - "\n calibrated: " + calibratedBeta + - "\n error: " + error); + "\n expected: " + initialBeta + + "\n calibrated: " + calibratedBeta + + "\n error: " + error); failed = true; } // Nu - error = Math.Abs(initialNu-calibratedNu); - if (error > calibrationTolerance) { + error = Math.Abs(initialNu - calibratedNu); + if (error > calibrationTolerance) + { QAssert.Fail("\nfailed to calibrate nu Sabr parameter:" + - "\n expected: " + initialNu + - "\n calibrated: " + calibratedNu + - "\n error: " + error); + "\n expected: " + initialNu + + "\n calibrated: " + calibratedNu + + "\n error: " + error); failed = true; } // Rho - error = Math.Abs(initialRho-calibratedRho); - if (error > calibrationTolerance) { + error = Math.Abs(initialRho - calibratedRho); + if (error > calibrationTolerance) + { QAssert.Fail("\nfailed to calibrate rho Sabr parameter:" + - "\n expected: " + initialRho + - "\n calibrated: " + calibratedRho + - "\n error: " + error); + "\n expected: " + initialRho + + "\n calibrated: " + calibratedRho + + "\n error: " + error); failed = true; } if (failed) QAssert.Fail("\nSabr calibration failure:" + - "\n isAlphaFixed: " + isAlphaFixed[k_a] + - "\n isBetaFixed: " + isBetaFixed[k_b] + - "\n isNuFixed: " + isNuFixed[k_n] + - "\n isRhoFixed: " + isRhoFixed[k_r] + - "\n vegaWeighted[i]: " + vegaWeighted[i]); + "\n isAlphaFixed: " + isAlphaFixed[k_a] + + "\n isBetaFixed: " + isBetaFixed[k_b] + + "\n isNuFixed: " + isNuFixed[k_n] + + "\n isRhoFixed: " + isRhoFixed[k_r] + + "\n vegaWeighted[i]: " + vegaWeighted[i]); } } } @@ -1145,216 +1190,216 @@ public void testSabrInterpolation() } } - #if NET40 || NET45 - [TestMethod()] +#if NET40 || NET45 + [TestMethod()] #else - [Fact] -#endif - public void testNormalSabrInterpolation() - { - // Testing Sabr interpolation... - - // Test SABR function against input volatilities - double tolerance = 1.0e-12; - List strikes = new InitializedList(31); - List volatilities = new InitializedList(31); - // input strikes - strikes[0] = 0.03; strikes[1] = 0.032; strikes[2] = 0.034; - strikes[3] = 0.036; strikes[4] = 0.038; strikes[5] = 0.04; - strikes[6] = 0.042; strikes[7] = 0.044; strikes[8] = 0.046; - strikes[9] = 0.048; strikes[10] = 0.05; strikes[11] = 0.052; - strikes[12] = 0.054; strikes[13] = 0.056; strikes[14] = 0.058; - strikes[15] = 0.06; strikes[16] = 0.062; strikes[17] = 0.064; - strikes[18] = 0.066; strikes[19] = 0.068; strikes[20] = 0.07; - strikes[21] = 0.072; strikes[22] = 0.074; strikes[23] = 0.076; - strikes[24] = 0.078; strikes[25] = 0.08; strikes[26] = 0.082; - strikes[27] = 0.084; strikes[28] = 0.086; strikes[29] = 0.088; - strikes[30] = 0.09; - // input volatilities - volatilities[0] = 0.00302585323005545; volatilities[1] = 0.00294383987488083; volatilities[2] = 0.00288298622420075; - volatilities[3] = 0.00285179755813925; volatilities[4] = 0.00285792878198394; volatilities[5] = 0.00290512184396261; - volatilities[6] = 0.00299136112388108; volatilities[7] = 0.00311009972637092; volatilities[8] = 0.00325327416236817; - volatilities[9] = 0.00341363771488595; volatilities[10] = 0.0035856197690038; volatilities[11] = 0.00376525972074818; - volatilities[12] = 0.00394983924954725; volatilities[13] = 0.00413751556423761; volatilities[14] = 0.0043270404491738; - volatilities[15] = 0.00451756485802441; volatilities[16] = 0.00470850804875522; volatilities[17] = 0.00489947094428383; - volatilities[18] = 0.00509017869762345; volatilities[19] = 0.00528044232532999; volatilities[20] = 0.00547013280521446; - volatilities[21] = 0.0056591633819362; volatilities[22] = 0.00584747733448256; volatilities[23] = 0.0060350394214727; - volatilities[24] = 0.00622182983342147; volatilities[25] = 0.00640783987460733; volatilities[26] = 0.00659306885217061; - volatilities[27] = 0.0067775218171438; volatilities[28] = 0.00696120791288998; volatilities[29] = 0.00714413916074818; - volatilities[30] = 0.00732632956313855; - - - double expiry = 1.0; - double forward = 0.039; - // input SABR coefficients (corresponding to the vols above) - double initialAlpha = 0.3; - double initialBeta = 0.6; - double initialNu = 0.02; - double initialRho = 0.01; - // calculate SABR vols and compare with input vols - for (int i = 0; i < strikes.Count; i++) - { - double calculatedVol = Utils.shiftedSabrNormalVolatility(strikes[i], forward, expiry, - initialAlpha, initialBeta, - initialNu, initialRho); - if (Math.Abs(volatilities[i] - calculatedVol) > tolerance) - QAssert.Fail("failed to calculate Sabr function at strike " + strikes[i] - + "\n expected: " + volatilities[i] - + "\n calculated: " + calculatedVol - + "\n error: " + Math.Abs(calculatedVol - volatilities[i])); - } - - // Test SABR calibration against input parameters - // Use default values (but not null, since then parameters - // will then not be fixed during optimization, see the - // interpolation constructor, thus rendering the test cases - // with fixed parameters non-sensical) - double alphaGuess = Math.Sqrt(0.2); - double betaGuess = 0.5; - double nuGuess = Math.Sqrt(0.4); - double rhoGuess = 0.0; - - bool[] vegaWeighted = { true, false }; - bool[] isAlphaFixed = { true, false }; - bool[] isBetaFixed = { true, false }; - bool[] isNuFixed = { true, false }; - bool[] isRhoFixed = { true, false }; - - double calibrationTolerance = 5.0e-8; - // initialize optimization methods - List methods_ = new List(); - methods_.Add(new Simplex(0.01)); - methods_.Add(new LevenbergMarquardt(1e-8, 1e-8, 1e-8)); - // Initialize end criteria - EndCriteria endCriteria = new EndCriteria(100000, 100, 1e-8, 1e-8, 1e-8); - // Test looping over all possibilities - for (int j = 0; j < methods_.Count; ++j) - { - for (int i = 0; i < vegaWeighted.Length; ++i) - { - for (int k_a = 0; k_a < isAlphaFixed.Length; ++k_a) - { - for (int k_b = 0; k_b < isBetaFixed.Length; ++k_b) - { - for (int k_n = 0; k_n < isNuFixed.Length; ++k_n) - { - for (int k_r = 0; k_r < isRhoFixed.Length; ++k_r) - { - // to meet the tough calibration tolerance we need to lower the default - // error threshold for accepting a calibration (to be more specific, some - // of the new test cases arising from fixing a subset of the model's - // parameters do not calibrate with the desired error using the initial - // guess (i.e. optimization runs into a local minimum) - then a series of - // random start values for optimization is chosen until our tight custom - // error threshold is satisfied. - SABRInterpolation sabrInterpolation = new SABRInterpolation( - strikes, strikes.Count, volatilities, - expiry, forward, isAlphaFixed[k_a] ? initialAlpha : alphaGuess, - isBetaFixed[k_b] ? initialBeta : betaGuess, - isNuFixed[k_n] ? initialNu : nuGuess, - isRhoFixed[k_r] ? initialRho : rhoGuess, isAlphaFixed[k_a], - isBetaFixed[k_b], isNuFixed[k_n], isRhoFixed[k_r], - vegaWeighted[i], endCriteria, methods_[j], 1E-10, false, 50, 0.0, VolatilityType.Normal); - sabrInterpolation.update(); - - // Recover SABR calibration parameters - bool failed = false; - double calibratedAlpha = sabrInterpolation.alpha(); - double calibratedBeta = sabrInterpolation.beta(); - double calibratedNu = sabrInterpolation.nu(); - double calibratedRho = sabrInterpolation.rho(); - double error; - - // compare results: alpha - error = Math.Abs(initialAlpha - calibratedAlpha); - if (error > calibrationTolerance) - { - QAssert.Fail("\nfailed to calibrate alpha Sabr parameter:" + - "\n expected: " + initialAlpha + - "\n calibrated: " + calibratedAlpha + - "\n error: " + error); - failed = true; - } - // Beta - error = Math.Abs(initialBeta - calibratedBeta); - if (error > calibrationTolerance) - { - QAssert.Fail("\nfailed to calibrate beta Sabr parameter:" + - "\n expected: " + initialBeta + - "\n calibrated: " + calibratedBeta + - "\n error: " + error); - failed = true; - } - // Nu - error = Math.Abs(initialNu - calibratedNu); - if (error > calibrationTolerance) - { - QAssert.Fail("\nfailed to calibrate nu Sabr parameter:" + - "\n expected: " + initialNu + - "\n calibrated: " + calibratedNu + - "\n error: " + error); - failed = true; - } - // Rho - error = Math.Abs(initialRho - calibratedRho); - if (error > calibrationTolerance) - { - QAssert.Fail("\nfailed to calibrate rho Sabr parameter:" + - "\n expected: " + initialRho + - "\n calibrated: " + calibratedRho + - "\n error: " + error); - failed = true; - } - - if (failed) - QAssert.Fail("\nSabr calibration failure:" + - "\n isAlphaFixed: " + isAlphaFixed[k_a] + - "\n isBetaFixed: " + isBetaFixed[k_b] + - "\n isNuFixed: " + isNuFixed[k_n] + - "\n isRhoFixed: " + isRhoFixed[k_r] + - "\n vegaWeighted[i]: " + vegaWeighted[i]); - } - } - } - } - } - } - } + [Fact] +#endif + public void testNormalSabrInterpolation() + { + // Testing Sabr interpolation... + + // Test SABR function against input volatilities + double tolerance = 1.0e-12; + List strikes = new InitializedList(31); + List volatilities = new InitializedList(31); + // input strikes + strikes[0] = 0.03; strikes[1] = 0.032; strikes[2] = 0.034; + strikes[3] = 0.036; strikes[4] = 0.038; strikes[5] = 0.04; + strikes[6] = 0.042; strikes[7] = 0.044; strikes[8] = 0.046; + strikes[9] = 0.048; strikes[10] = 0.05; strikes[11] = 0.052; + strikes[12] = 0.054; strikes[13] = 0.056; strikes[14] = 0.058; + strikes[15] = 0.06; strikes[16] = 0.062; strikes[17] = 0.064; + strikes[18] = 0.066; strikes[19] = 0.068; strikes[20] = 0.07; + strikes[21] = 0.072; strikes[22] = 0.074; strikes[23] = 0.076; + strikes[24] = 0.078; strikes[25] = 0.08; strikes[26] = 0.082; + strikes[27] = 0.084; strikes[28] = 0.086; strikes[29] = 0.088; + strikes[30] = 0.09; + // input volatilities + volatilities[0] = 0.00302585323005545; volatilities[1] = 0.00294383987488083; volatilities[2] = 0.00288298622420075; + volatilities[3] = 0.00285179755813925; volatilities[4] = 0.00285792878198394; volatilities[5] = 0.00290512184396261; + volatilities[6] = 0.00299136112388108; volatilities[7] = 0.00311009972637092; volatilities[8] = 0.00325327416236817; + volatilities[9] = 0.00341363771488595; volatilities[10] = 0.0035856197690038; volatilities[11] = 0.00376525972074818; + volatilities[12] = 0.00394983924954725; volatilities[13] = 0.00413751556423761; volatilities[14] = 0.0043270404491738; + volatilities[15] = 0.00451756485802441; volatilities[16] = 0.00470850804875522; volatilities[17] = 0.00489947094428383; + volatilities[18] = 0.00509017869762345; volatilities[19] = 0.00528044232532999; volatilities[20] = 0.00547013280521446; + volatilities[21] = 0.0056591633819362; volatilities[22] = 0.00584747733448256; volatilities[23] = 0.0060350394214727; + volatilities[24] = 0.00622182983342147; volatilities[25] = 0.00640783987460733; volatilities[26] = 0.00659306885217061; + volatilities[27] = 0.0067775218171438; volatilities[28] = 0.00696120791288998; volatilities[29] = 0.00714413916074818; + volatilities[30] = 0.00732632956313855; + + + double expiry = 1.0; + double forward = 0.039; + // input SABR coefficients (corresponding to the vols above) + double initialAlpha = 0.3; + double initialBeta = 0.6; + double initialNu = 0.02; + double initialRho = 0.01; + // calculate SABR vols and compare with input vols + for (int i = 0; i < strikes.Count; i++) + { + double calculatedVol = Utils.shiftedSabrNormalVolatility(strikes[i], forward, expiry, + initialAlpha, initialBeta, + initialNu, initialRho); + if (Math.Abs(volatilities[i] - calculatedVol) > tolerance) + QAssert.Fail("failed to calculate Sabr function at strike " + strikes[i] + + "\n expected: " + volatilities[i] + + "\n calculated: " + calculatedVol + + "\n error: " + Math.Abs(calculatedVol - volatilities[i])); + } + + // Test SABR calibration against input parameters + // Use default values (but not null, since then parameters + // will then not be fixed during optimization, see the + // interpolation constructor, thus rendering the test cases + // with fixed parameters non-sensical) + double alphaGuess = Math.Sqrt(0.2); + double betaGuess = 0.5; + double nuGuess = Math.Sqrt(0.4); + double rhoGuess = 0.0; + + bool[] vegaWeighted = { true, false }; + bool[] isAlphaFixed = { true, false }; + bool[] isBetaFixed = { true, false }; + bool[] isNuFixed = { true, false }; + bool[] isRhoFixed = { true, false }; + + double calibrationTolerance = 5.0e-8; + // initialize optimization methods + List methods_ = new List(); + methods_.Add(new Simplex(0.01)); + methods_.Add(new LevenbergMarquardt(1e-8, 1e-8, 1e-8)); + // Initialize end criteria + EndCriteria endCriteria = new EndCriteria(100000, 100, 1e-8, 1e-8, 1e-8); + // Test looping over all possibilities + for (int j = 0; j < methods_.Count; ++j) + { + for (int i = 0; i < vegaWeighted.Length; ++i) + { + for (int k_a = 0; k_a < isAlphaFixed.Length; ++k_a) + { + for (int k_b = 0; k_b < isBetaFixed.Length; ++k_b) + { + for (int k_n = 0; k_n < isNuFixed.Length; ++k_n) + { + for (int k_r = 0; k_r < isRhoFixed.Length; ++k_r) + { + // to meet the tough calibration tolerance we need to lower the default + // error threshold for accepting a calibration (to be more specific, some + // of the new test cases arising from fixing a subset of the model's + // parameters do not calibrate with the desired error using the initial + // guess (i.e. optimization runs into a local minimum) - then a series of + // random start values for optimization is chosen until our tight custom + // error threshold is satisfied. + SABRInterpolation sabrInterpolation = new SABRInterpolation( + strikes, strikes.Count, volatilities, + expiry, forward, isAlphaFixed[k_a] ? initialAlpha : alphaGuess, + isBetaFixed[k_b] ? initialBeta : betaGuess, + isNuFixed[k_n] ? initialNu : nuGuess, + isRhoFixed[k_r] ? initialRho : rhoGuess, isAlphaFixed[k_a], + isBetaFixed[k_b], isNuFixed[k_n], isRhoFixed[k_r], + vegaWeighted[i], endCriteria, methods_[j], 1E-10, false, 50, 0.0, VolatilityType.Normal); + sabrInterpolation.update(); + + // Recover SABR calibration parameters + bool failed = false; + double calibratedAlpha = sabrInterpolation.alpha(); + double calibratedBeta = sabrInterpolation.beta(); + double calibratedNu = sabrInterpolation.nu(); + double calibratedRho = sabrInterpolation.rho(); + double error; + + // compare results: alpha + error = Math.Abs(initialAlpha - calibratedAlpha); + if (error > calibrationTolerance) + { + QAssert.Fail("\nfailed to calibrate alpha Sabr parameter:" + + "\n expected: " + initialAlpha + + "\n calibrated: " + calibratedAlpha + + "\n error: " + error); + failed = true; + } + // Beta + error = Math.Abs(initialBeta - calibratedBeta); + if (error > calibrationTolerance) + { + QAssert.Fail("\nfailed to calibrate beta Sabr parameter:" + + "\n expected: " + initialBeta + + "\n calibrated: " + calibratedBeta + + "\n error: " + error); + failed = true; + } + // Nu + error = Math.Abs(initialNu - calibratedNu); + if (error > calibrationTolerance) + { + QAssert.Fail("\nfailed to calibrate nu Sabr parameter:" + + "\n expected: " + initialNu + + "\n calibrated: " + calibratedNu + + "\n error: " + error); + failed = true; + } + // Rho + error = Math.Abs(initialRho - calibratedRho); + if (error > calibrationTolerance) + { + QAssert.Fail("\nfailed to calibrate rho Sabr parameter:" + + "\n expected: " + initialRho + + "\n calibrated: " + calibratedRho + + "\n error: " + error); + failed = true; + } + + if (failed) + QAssert.Fail("\nSabr calibration failure:" + + "\n isAlphaFixed: " + isAlphaFixed[k_a] + + "\n isBetaFixed: " + isBetaFixed[k_b] + + "\n isNuFixed: " + isNuFixed[k_n] + + "\n isRhoFixed: " + isRhoFixed[k_r] + + "\n vegaWeighted[i]: " + vegaWeighted[i]); + } + } + } + } + } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testKernelInterpolation() + public void testKernelInterpolation() { // Testing kernel 1D interpolation List deltaGrid = new InitializedList(5); // x-values, here delta in FX - deltaGrid[0]=0.10; deltaGrid[1]=0.25; deltaGrid[2]=0.50; - deltaGrid[3]=0.75; deltaGrid[4]=0.90; + deltaGrid[0] = 0.10; deltaGrid[1] = 0.25; deltaGrid[2] = 0.50; + deltaGrid[3] = 0.75; deltaGrid[4] = 0.90; - List yd1 = new InitializedList( deltaGrid.Count ); // test y-values 1 - yd1[0]=11.275; yd1[1]=11.125; yd1[2]=11.250; - yd1[3]=11.825; yd1[4]=12.625; + List yd1 = new InitializedList(deltaGrid.Count); // test y-values 1 + yd1[0] = 11.275; yd1[1] = 11.125; yd1[2] = 11.250; + yd1[3] = 11.825; yd1[4] = 12.625; - List yd2 = new InitializedList( deltaGrid.Count ); // test y-values 2 - yd2[0]=16.025; yd2[1]=13.450; yd2[2]=11.350; - yd2[3]=10.150; yd2[4]=10.075; + List yd2 = new InitializedList(deltaGrid.Count); // test y-values 2 + yd2[0] = 16.025; yd2[1] = 13.450; yd2[2] = 11.350; + yd2[3] = 10.150; yd2[4] = 10.075; - List yd3 = new InitializedList( deltaGrid.Count ); // test y-values 3 - yd3[0]=10.3000; yd3[1]=9.6375; yd3[2]=9.2000; - yd3[3]=9.1125; yd3[4]=9.4000; + List yd3 = new InitializedList(deltaGrid.Count); // test y-values 3 + yd3[0] = 10.3000; yd3[1] = 9.6375; yd3[2] = 9.2000; + yd3[3] = 9.1125; yd3[4] = 9.4000; List > yd = new List>(); yd.Add(yd1); yd.Add(yd2); yd.Add(yd3); - List lambdaVec = new InitializedList( 5 ); - lambdaVec[0]=0.05; lambdaVec[1]=0.50; lambdaVec[2]=0.75; - lambdaVec[3]=1.65; lambdaVec[4]=2.55; + List lambdaVec = new InitializedList(5); + lambdaVec[0] = 0.05; lambdaVec[1] = 0.50; lambdaVec[2] = 0.75; + lambdaVec[3] = 1.65; lambdaVec[4] = 2.55; double tolerance = 2.0e-5; @@ -1363,99 +1408,99 @@ public void testKernelInterpolation() // Check that y-values at knots are exactly the feeded y-values, // irrespective of kernel parameters - for (int i=0; i currY = yd[j]; - KernelInterpolation f = new KernelInterpolation(deltaGrid, deltaGrid.Count,currY, myKernel); + KernelInterpolation f = new KernelInterpolation(deltaGrid, deltaGrid.Count, currY, myKernel); f.update(); - for (int dIt=0; dIt< deltaGrid.Count; ++dIt) + for (int dIt = 0; dIt < deltaGrid.Count; ++dIt) { - expectedVal=currY[dIt]; - calcVal=f.value(deltaGrid[dIt]); + expectedVal = currY[dIt]; + calcVal = f.value(deltaGrid[dIt]); - if (Math.Abs(expectedVal-calcVal)>tolerance) + if (Math.Abs(expectedVal - calcVal) > tolerance) { QAssert.Fail("Kernel interpolation failed at x = " - + deltaGrid[dIt] - + "\n interpolated value: " + calcVal - + "\n expected value: " + expectedVal - + "\n error: " - + Math.Abs(expectedVal-calcVal)); - + + deltaGrid[dIt] + + "\n interpolated value: " + calcVal + + "\n expected value: " + expectedVal + + "\n error: " + + Math.Abs(expectedVal - calcVal)); + } } } } - List testDeltaGrid = new InitializedList( deltaGrid.Count ); - testDeltaGrid[0]=0.121; testDeltaGrid[1]=0.279; testDeltaGrid[2]=0.678; - testDeltaGrid[3]=0.790; testDeltaGrid[4]=0.980; + List testDeltaGrid = new InitializedList(deltaGrid.Count); + testDeltaGrid[0] = 0.121; testDeltaGrid[1] = 0.279; testDeltaGrid[2] = 0.678; + testDeltaGrid[3] = 0.790; testDeltaGrid[4] = 0.980; // Gaussian Kernel values for testDeltaGrid with a standard // deviation of 2.05 (the value is arbitrary.) Source: parrallel // implementation in R, no literature sources found - List ytd1 = new InitializedList( testDeltaGrid.Count ); - ytd1[0]=11.23847; ytd1[1]=11.12003; ytd1[2]=11.58932; - ytd1[3]=11.99168; ytd1[4]=13.29650; + List ytd1 = new InitializedList(testDeltaGrid.Count); + ytd1[0] = 11.23847; ytd1[1] = 11.12003; ytd1[2] = 11.58932; + ytd1[3] = 11.99168; ytd1[4] = 13.29650; - List ytd2 = new InitializedList( testDeltaGrid.Count ); - ytd2[0]=15.55922; ytd2[1]=13.11088; ytd2[2]=10.41615; - ytd2[3]=10.05153; ytd2[4]=10.50741; + List ytd2 = new InitializedList(testDeltaGrid.Count); + ytd2[0] = 15.55922; ytd2[1] = 13.11088; ytd2[2] = 10.41615; + ytd2[3] = 10.05153; ytd2[4] = 10.50741; - List ytd3 = new InitializedList( testDeltaGrid.Count ); - ytd3[0]= 10.17473; ytd3[1]= 9.557842; ytd3[2]= 9.09339; - ytd3[3]= 9.149687; ytd3[4]= 9.779971; + List ytd3 = new InitializedList(testDeltaGrid.Count); + ytd3[0] = 10.17473; ytd3[1] = 9.557842; ytd3[2] = 9.09339; + ytd3[3] = 9.149687; ytd3[4] = 9.779971; List > ytd = new List>(); ytd.Add(ytd1); ytd.Add(ytd2); ytd.Add(ytd3); - GaussianKernel myKernel2 = new GaussianKernel(0,2.05); + GaussianKernel myKernel2 = new GaussianKernel(0, 2.05); - for (int j=0; j< ytd.Count; ++j) + for (int j = 0; j < ytd.Count; ++j) { - List currY=yd[j]; - List currTY=ytd[j]; + List currY = yd[j]; + List currTY = ytd[j]; // Build interpolation according to original grid + y-values - KernelInterpolation f = new KernelInterpolation(deltaGrid, deltaGrid.Count,currY, myKernel2); + KernelInterpolation f = new KernelInterpolation(deltaGrid, deltaGrid.Count, currY, myKernel2); f.update(); // test values at test Grid - for (int dIt=0; dIt< testDeltaGrid.Count; ++dIt) + for (int dIt = 0; dIt < testDeltaGrid.Count; ++dIt) { - expectedVal=currTY[dIt]; + expectedVal = currTY[dIt]; f.enableExtrapolation();// allow extrapolation - calcVal=f.value(testDeltaGrid[dIt]); - if (Math.Abs(expectedVal-calcVal)>tolerance) + calcVal = f.value(testDeltaGrid[dIt]); + if (Math.Abs(expectedVal - calcVal) > tolerance) { - QAssert.Fail("Kernel interpolation failed at x = " - + deltaGrid[dIt] - + "\n interpolated value: " + calcVal - + "\n expected value: " + expectedVal - + "\n error: " - + Math.Abs(expectedVal-calcVal)); + QAssert.Fail("Kernel interpolation failed at x = " + + deltaGrid[dIt] + + "\n interpolated value: " + calcVal + + "\n expected value: " + expectedVal + + "\n error: " + + Math.Abs(expectedVal - calcVal)); } } - + } - + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testKernelInterpolation2D() { @@ -1465,47 +1510,50 @@ public void testKernelInterpolation2D() // Testing kernel 2D interpolation... - double mean=0.0, var=0.18; - GaussianKernel myKernel = new GaussianKernel(mean,var); + double mean = 0.0, var = 0.18; + GaussianKernel myKernel = new GaussianKernel(mean, var); List xVec = new InitializedList(10); xVec[0] = 0.10; xVec[1] = 0.20; xVec[2] = 0.30; xVec[3] = 0.40; xVec[4] = 0.50; xVec[5] = 0.60; xVec[6] = 0.70; xVec[7] = 0.80; xVec[8] = 0.90; xVec[9] = 1.00; - List yVec = new InitializedList( 3 ); + List yVec = new InitializedList(3); yVec[0] = 1.0; yVec[1] = 2.0; yVec[2] = 3.5; - Matrix M = new Matrix(xVec.Count,yVec.Count); + Matrix M = new Matrix(xVec.Count, yVec.Count); - M[0,0]=0.25; M[1,0]=0.24; M[2,0]=0.23; M[3,0]=0.20; M[4,0]=0.19; - M[5,0]=0.20; M[6,0]=0.21; M[7,0]=0.22; M[8,0]=0.26; M[9,0]=0.29; - - M[0,1]=0.27; M[1,1]=0.26; M[2,1]=0.25; M[3,1]=0.22; M[4,1]=0.21; - M[5,1]=0.22; M[6,1]=0.23; M[7,1]=0.24; M[8,1]=0.28; M[9,1]=0.31; - - M[0,2]=0.21; M[1,2]=0.22; M[2,2]=0.27; M[3,2]=0.29; M[4,2]=0.24; - M[5,2]=0.28; M[6,2]=0.25; M[7,2]=0.22; M[8,2]=0.29; M[9,2]=0.30; + M[0, 0] = 0.25; M[1, 0] = 0.24; M[2, 0] = 0.23; M[3, 0] = 0.20; M[4, 0] = 0.19; + M[5, 0] = 0.20; M[6, 0] = 0.21; M[7, 0] = 0.22; M[8, 0] = 0.26; M[9, 0] = 0.29; - KernelInterpolation2D kernel2D = new KernelInterpolation2D(xVec,xVec.Count, yVec,yVec.Count,M,myKernel); + M[0, 1] = 0.27; M[1, 1] = 0.26; M[2, 1] = 0.25; M[3, 1] = 0.22; M[4, 1] = 0.21; + M[5, 1] = 0.22; M[6, 1] = 0.23; M[7, 1] = 0.24; M[8, 1] = 0.28; M[9, 1] = 0.31; - double calcVal,expectedVal; + M[0, 2] = 0.21; M[1, 2] = 0.22; M[2, 2] = 0.27; M[3, 2] = 0.29; M[4, 2] = 0.24; + M[5, 2] = 0.28; M[6, 2] = 0.25; M[7, 2] = 0.22; M[8, 2] = 0.29; M[9, 2] = 0.30; + + KernelInterpolation2D kernel2D = new KernelInterpolation2D(xVec, xVec.Count, yVec, yVec.Count, M, myKernel); + + double calcVal, expectedVal; double tolerance = 1.0e-10; - for(int i=0;itolerance){ + if (Math.Abs(expectedVal - calcVal) > tolerance) + { - QAssert.Fail("2D Kernel interpolation failed at x = " + xVec[i] - + ", y = " + yVec[j] - + "\n interpolated value: " + calcVal - + "\n expected value: " + expectedVal - + "\n error: " - + Math.Abs(expectedVal-calcVal)); + QAssert.Fail("2D Kernel interpolation failed at x = " + xVec[i] + + ", y = " + yVec[j] + + "\n interpolated value: " + calcVal + + "\n expected value: " + expectedVal + + "\n error: " + + Math.Abs(expectedVal - calcVal)); } } } @@ -1518,32 +1566,35 @@ public void testKernelInterpolation2D() yVec1[0] = 0.5; yVec1[1] = 0.7; yVec1[2] = 1.0; yVec1[3] = 2.0; yVec1[4] = 3.5; yVec1[5] = 4.5; yVec1[6] = 5.5; yVec1[7] = 6.5; - Matrix M1 = new Matrix(xVec1.Count,yVec1.Count); - M1[0,0]=10.25; M1[1,0]=12.24;M1[2,0]=14.23;M1[3,0]=17.20; - M1[0,1]=12.25; M1[1,1]=15.24;M1[2,1]=16.23;M1[3,1]=16.20; - M1[0,2]=12.25; M1[1,2]=13.24;M1[2,2]=13.23;M1[3,2]=17.20; - M1[0,3]=13.25; M1[1,3]=15.24;M1[2,3]=12.23;M1[3,3]=19.20; - M1[0,4]=14.25; M1[1,4]=16.24;M1[2,4]=13.23;M1[3,4]=12.20; - M1[0,5]=15.25; M1[1,5]=17.24;M1[2,5]=14.23;M1[3,5]=12.20; - M1[0,6]=16.25; M1[1,6]=13.24;M1[2,6]=15.23;M1[3,6]=10.20; - M1[0,7]=14.25; M1[1,7]=14.24;M1[2,7]=16.23;M1[3,7]=19.20; + Matrix M1 = new Matrix(xVec1.Count, yVec1.Count); + M1[0, 0] = 10.25; M1[1, 0] = 12.24; M1[2, 0] = 14.23; M1[3, 0] = 17.20; + M1[0, 1] = 12.25; M1[1, 1] = 15.24; M1[2, 1] = 16.23; M1[3, 1] = 16.20; + M1[0, 2] = 12.25; M1[1, 2] = 13.24; M1[2, 2] = 13.23; M1[3, 2] = 17.20; + M1[0, 3] = 13.25; M1[1, 3] = 15.24; M1[2, 3] = 12.23; M1[3, 3] = 19.20; + M1[0, 4] = 14.25; M1[1, 4] = 16.24; M1[2, 4] = 13.23; M1[3, 4] = 12.20; + M1[0, 5] = 15.25; M1[1, 5] = 17.24; M1[2, 5] = 14.23; M1[3, 5] = 12.20; + M1[0, 6] = 16.25; M1[1, 6] = 13.24; M1[2, 6] = 15.23; M1[3, 6] = 10.20; + M1[0, 7] = 14.25; M1[1, 7] = 14.24; M1[2, 7] = 16.23; M1[3, 7] = 19.20; // test with another kernel - KernelInterpolation2D kernel2DEp = new KernelInterpolation2D( xVec1, xVec1.Count, yVec1, yVec1.Count, M1, new epanechnikovKernel() ); - for(int i=0;itolerance){ + if (Math.Abs(expectedVal - calcVal) > tolerance) + { - QAssert.Fail("2D Epanechnkikov Kernel interpolation failed at x = " + xVec1[i] - + ", y = " + yVec1[j] - + "\n interpolated value: " + calcVal - + "\n expected value: " + expectedVal - + "\n error: " - + Math.Abs(expectedVal-calcVal)); + QAssert.Fail("2D Epanechnkikov Kernel interpolation failed at x = " + xVec1[i] + + ", y = " + yVec1[j] + + "\n interpolated value: " + calcVal + + "\n expected value: " + expectedVal + + "\n error: " + + Math.Abs(expectedVal - calcVal)); } } } @@ -1556,116 +1607,124 @@ public void testKernelInterpolation2D() kernel2DEp.update(); - for(int i=0;itolerance){ + if (Math.Abs(expectedVal - calcVal) > tolerance) + { - QAssert.Fail("2D Epanechnkikov Kernel updated interpolation failed at x = " + xVec1[i] - + ", y = " + yVec1[j] - + "\n interpolated value: " + calcVal - + "\n expected value: " + expectedVal - + "\n error: " - + Math.Abs(expectedVal-calcVal)); + QAssert.Fail("2D Epanechnkikov Kernel updated interpolation failed at x = " + xVec1[i] + + ", y = " + yVec1[j] + + "\n interpolated value: " + calcVal + + "\n expected value: " + expectedVal + + "\n error: " + + Math.Abs(expectedVal - calcVal)); } } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testBicubicDerivatives() + public void testBicubicDerivatives() { // Testing bicubic spline derivatives... List x = new InitializedList(100), y = new InitializedList(100); - for (int i=0; i < 100; ++i) + for (int i = 0; i < 100; ++i) { - x[i] = y[i] = i/20.0; + x[i] = y[i] = i / 20.0; } Matrix f = new Matrix(100, 100); - for (int i=0; i < 100; ++i) - for (int j=0; j < 100; ++j) - f[i,j] = y[i]/10*Math.Sin(x[j])+Math.Cos(y[i]); + for (int i = 0; i < 100; ++i) + for (int j = 0; j < 100; ++j) + f[i, j] = y[i] / 10 * Math.Sin(x[j]) + Math.Cos(y[i]); - double tol=0.005; + double tol = 0.005; BicubicSpline spline = new BicubicSpline(x, x.Count, y, y.Count, f); - for (int i=5; i < 95; i+=10) + for (int i = 5; i < 95; i += 10) { - for (int j=5; j < 95; j+=10) + for (int j = 5; j < 95; j += 10) { - double f_x = spline.derivativeX(x[j],y[i]); - double f_xx = spline.secondDerivativeX(x[j],y[i]); - double f_y = spline.derivativeY(x[j],y[i]); - double f_yy = spline.secondDerivativeY(x[j],y[i]); - double f_xy = spline.derivativeXY(x[j],y[i]); - - if (Math.Abs(f_x - y[i]/10*Math.Cos(x[j])) > tol) { - QAssert.Fail("Failed to reproduce f_x"); + double f_x = spline.derivativeX(x[j], y[i]); + double f_xx = spline.secondDerivativeX(x[j], y[i]); + double f_y = spline.derivativeY(x[j], y[i]); + double f_yy = spline.secondDerivativeY(x[j], y[i]); + double f_xy = spline.derivativeXY(x[j], y[i]); + + if (Math.Abs(f_x - y[i] / 10 * Math.Cos(x[j])) > tol) + { + QAssert.Fail("Failed to reproduce f_x"); } - if (Math.Abs(f_xx + y[i]/10*Math.Sin(x[j])) > tol) { - QAssert.Fail("Failed to reproduce f_xx"); + if (Math.Abs(f_xx + y[i] / 10 * Math.Sin(x[j])) > tol) + { + QAssert.Fail("Failed to reproduce f_xx"); } - if (Math.Abs(f_y - (Math.Sin(x[j])/10-Math.Sin(y[i]))) > tol) { - QAssert.Fail("Failed to reproduce f_y"); + if (Math.Abs(f_y - (Math.Sin(x[j]) / 10 - Math.Sin(y[i]))) > tol) + { + QAssert.Fail("Failed to reproduce f_y"); } - if (Math.Abs(f_yy + Math.Cos(y[i])) > tol) { - QAssert.Fail("Failed to reproduce f_yy"); + if (Math.Abs(f_yy + Math.Cos(y[i])) > tol) + { + QAssert.Fail("Failed to reproduce f_yy"); } - if (Math.Abs(f_xy - Math.Cos(x[j])/10) > tol) { - QAssert.Fail("Failed to reproduce f_xy"); + if (Math.Abs(f_xy - Math.Cos(x[j]) / 10) > tol) + { + QAssert.Fail("Failed to reproduce f_xy"); } + } } } - } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testBicubicUpdate() + public void testBicubicUpdate() { // Testing that bicubic splines actually update... - int N=6; + int N = 6; List x = new InitializedList(N), y = new InitializedList(N); - for (int i=0; i < N; ++i) + for (int i = 0; i < N; ++i) { - x[i] = y[i] = i*0.2; + x[i] = y[i] = i * 0.2; } Matrix f = new Matrix(N, N); - for (int i=0; i < N; ++i) - for (int j=0; j < N; ++j) - f[i,j] = x[j]*(x[j] + y[i]); + for (int i = 0; i < N; ++i) + for (int j = 0; j < N; ++j) + f[i, j] = x[j] * (x[j] + y[i]); - BicubicSpline spline = new BicubicSpline(x, x.Count , y, y.Count, f); + BicubicSpline spline = new BicubicSpline(x, x.Count, y, y.Count, f); - double old_result = spline.value(x[2]+0.1, y[4]); + double old_result = spline.value(x[2] + 0.1, y[4]); // modify input matrix and update. - f[4,3] += 1.0; + f[4, 3] += 1.0; spline.update(); - double new_result = spline.value(x[2]+0.1, y[4]); - if (Math.Abs(old_result-new_result) < 0.5) + double new_result = spline.value(x[2] + 0.1, y[4]); + if (Math.Abs(old_result - new_result) < 0.5) QAssert.Fail("Failed to update bicubic spline"); -} + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testRichardsonExtrapolation() + public void testRichardsonExtrapolation() { // Testing Richardson extrapolation... @@ -1678,9 +1737,9 @@ public void testRichardsonExtrapolation() double stepSize = 0.1; double orderOfConvergence = 1.0; - RichardsonExtrapolation.function f = delegate( double h ) + RichardsonExtrapolation.function f = delegate(double h) { - return Math.Pow( 1.0 + h, 1 / h ); + return Math.Pow(1.0 + h, 1 / h); }; RichardsonExtrapolation extrap = new RichardsonExtrapolation(f, stepSize, orderOfConvergence); @@ -1691,12 +1750,14 @@ public void testRichardsonExtrapolation() double scalingFactor = 2.0; double calculated = extrap.value(scalingFactor); - if (Math.Abs(expected-calculated) > tol) { + if (Math.Abs(expected - calculated) > tol) + { QAssert.Fail("failed to reproduce Richardson extrapolation"); } calculated = extrap.value(); - if (Math.Abs(expected-calculated) > tol) { + if (Math.Abs(expected - calculated) > tol) + { QAssert.Fail("failed to reproduce Richardson extrapolation"); } @@ -1704,181 +1765,203 @@ public void testRichardsonExtrapolation() const double scalingFactor2 = 4.0; calculated = extrap.value(scalingFactor2, scalingFactor); - if (Math.Abs(expected-calculated) > tol) { + if (Math.Abs(expected - calculated) > tol) + { QAssert.Fail("failed to reproduce Richardson extrapolation"); } -} + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testSabrSingleCases() + public void testSabrSingleCases() { // Testing Sabr calibration single cases... - List strikes = new List(){ 0.01, 0.01125, 0.0125, 0.01375, 0.0150}; - List vols = new List(){0.1667, 0.2020, 0.2785, 0.3279, 0.3727}; - + List strikes = new List() { 0.01, 0.01125, 0.0125, 0.01375, 0.0150}; + List vols = new List() {0.1667, 0.2020, 0.2785, 0.3279, 0.3727}; + double tte = 0.3833; double forward = 0.011025; SABRInterpolation s0 = new SABRInterpolation(strikes, strikes.Count, vols, tte, forward, - null, 0.25, null, null, - false, true, false, false); + null, 0.25, null, null, + false, true, false, false); s0.update(); - if (s0.maxError() > 0.01 || s0.rmsError() > 0.01) + if (s0.maxError() > 0.01 || s0.rmsError() > 0.01) { QAssert.Fail("Sabr case #1 failed with max error (" - + s0.maxError() + ") and rms error (" + s0.rmsError() - + "), both should be < 0.01"); - + + s0.maxError() + ") and rms error (" + s0.rmsError() + + "), both should be < 0.01"); + } } #region Functions - List xRange(double start, double finish, int points) { - List x = new InitializedList(points); - double dx = (finish - start) / (points - 1); - for (int i=0; i gaussian(List x) { - List y = new InitializedList(x.Count); - for (int i = 0; i < x.Count; i++) - y[i] = Math.Exp(-x[i]*x[i]); - return y; - } - - List parabolic(List x) { - List y = new InitializedList(x.Count); - for (int i = 0; i < x.Count; i++) - y[i] = -x[i]*x[i]; - return y; - } - - void checkValues(string type, CubicInterpolation cubic, List xBegin, List yBegin) { - double tolerance = 2.0e-15; - for(int i=0; i tolerance) { - QAssert.Fail(type + " interpolation failed at x = " + xBegin[i] - + "\n interpolated value: " + interpolated - + "\n expected value: " + yBegin[i] - + "\n error: " - + Math.Abs(interpolated - yBegin[i])); - } - } - } - - void check1stDerivativeValue(string type, CubicInterpolation cubic, double x, double value) { - double tolerance = 1.0e-14; - double interpolated = cubic.derivative(x); - double error = Math.Abs(interpolated-value); - if (error > tolerance) { - QAssert.Fail(type + " interpolation first derivative failure\n" - + "at x = " + x - + "\n interpolated value: " + interpolated - + "\n expected value: " + value - + "\n error: " + error); - } - } - - void check2ndDerivativeValue(string type, CubicInterpolation cubic, double x, double value) { - double tolerance = 1.0e-13; - double interpolated = cubic.secondDerivative(x); - double error = Math.Abs(interpolated-value); - if (error > tolerance) { - QAssert.Fail(type + " interpolation second derivative failure\n" - + "at x = " + x + List xRange(double start, double finish, int points) + { + List x = new InitializedList(points); + double dx = (finish - start) / (points - 1); + for (int i = 0; i < points - 1; i++) + x[i] = start + i * dx; + x[points - 1] = finish; + return x; + } + + List gaussian(List x) + { + List y = new InitializedList(x.Count); + for (int i = 0; i < x.Count; i++) + y[i] = Math.Exp(-x[i] * x[i]); + return y; + } + + List parabolic(List x) + { + List y = new InitializedList(x.Count); + for (int i = 0; i < x.Count; i++) + y[i] = -x[i] * x[i]; + return y; + } + + void checkValues(string type, CubicInterpolation cubic, List xBegin, List yBegin) + { + double tolerance = 2.0e-15; + for (int i = 0; i < xBegin.Count; i++) + { + double interpolated = cubic.value(xBegin[i]); + if (Math.Abs(interpolated - yBegin[i]) > tolerance) + { + QAssert.Fail(type + " interpolation failed at x = " + xBegin[i] + "\n interpolated value: " + interpolated - + "\n expected value: " + value - + "\n error: " + error); - } - } - - void checkNotAKnotCondition(string type, CubicInterpolation cubic) { - double tolerance = 1.0e-14; - List c = cubic.cCoefficients(); - if (Math.Abs(c[0]-c[1]) > tolerance) { - QAssert.Fail(type + " interpolation failure" - + "\n cubic coefficient of the first" - + " polinomial is " + c[0] - + "\n cubic coefficient of the second" - + " polinomial is " + c[1]); + + "\n expected value: " + yBegin[i] + + "\n error: " + + Math.Abs(interpolated - yBegin[i])); } - int n = c.Count; - if (Math.Abs(c[n - 2] - c[n - 1]) > tolerance) { - QAssert.Fail(type + " interpolation failure" - + "\n cubic coefficient of the 2nd to last" - + " polinomial is " + c[n-2] - + "\n cubic coefficient of the last" - + " polinomial is " + c[n-1]); - } - } - - void checkSymmetry(string type, CubicInterpolation cubic, double xMin) { - double tolerance = 1.0e-15; - for (double x = xMin; x < 0.0; x += 0.1) { - double y1 = cubic.value(x), y2 = cubic.value(-x); - if (Math.Abs(y1-y2) > tolerance) { - QAssert.Fail(type + " interpolation not symmetric" - + "\n x = " + x - + "\n g(x) = " + y1 - + "\n g(-x) = " + y2 - + "\n error: " + Math.Abs(y1 - y2)); - } + } + } + + void check1stDerivativeValue(string type, CubicInterpolation cubic, double x, double value) + { + double tolerance = 1.0e-14; + double interpolated = cubic.derivative(x); + double error = Math.Abs(interpolated - value); + if (error > tolerance) + { + QAssert.Fail(type + " interpolation first derivative failure\n" + + "at x = " + x + + "\n interpolated value: " + interpolated + + "\n expected value: " + value + + "\n error: " + error); + } + } + + void check2ndDerivativeValue(string type, CubicInterpolation cubic, double x, double value) + { + double tolerance = 1.0e-13; + double interpolated = cubic.secondDerivative(x); + double error = Math.Abs(interpolated - value); + if (error > tolerance) + { + QAssert.Fail(type + " interpolation second derivative failure\n" + + "at x = " + x + + "\n interpolated value: " + interpolated + + "\n expected value: " + value + + "\n error: " + error); + } + } + + void checkNotAKnotCondition(string type, CubicInterpolation cubic) + { + double tolerance = 1.0e-14; + List c = cubic.cCoefficients(); + if (Math.Abs(c[0] - c[1]) > tolerance) + { + QAssert.Fail(type + " interpolation failure" + + "\n cubic coefficient of the first" + + " polinomial is " + c[0] + + "\n cubic coefficient of the second" + + " polinomial is " + c[1]); + } + int n = c.Count; + if (Math.Abs(c[n - 2] - c[n - 1]) > tolerance) + { + QAssert.Fail(type + " interpolation failure" + + "\n cubic coefficient of the 2nd to last" + + " polinomial is " + c[n - 2] + + "\n cubic coefficient of the last" + + " polinomial is " + c[n - 1]); + } + } + + void checkSymmetry(string type, CubicInterpolation cubic, double xMin) + { + double tolerance = 1.0e-15; + for (double x = xMin; x < 0.0; x += 0.1) + { + double y1 = cubic.value(x), y2 = cubic.value(-x); + if (Math.Abs(y1 - y2) > tolerance) + { + QAssert.Fail(type + " interpolation not symmetric" + + "\n x = " + x + + "\n g(x) = " + y1 + + "\n g(-x) = " + y2 + + "\n error: " + Math.Abs(y1 - y2)); } - } + } + } - class errorFunction : IValue where F : IValue { - private IValue f_; + class errorFunction : IValue where F : IValue + { + private IValue f_; - public errorFunction(IValue f) { - f_ = f; + public errorFunction(IValue f) + { + f_ = f; + } + public double value(double x) + { + double temp = f_.value(x) - Math.Exp(-x * x); + return temp * temp; + } + } + + errorFunction make_error_function(IValue f) + { + return new errorFunction(f); + } + + double multif(double s, double t, double u, double v, double w) + { + return Math.Sqrt(s * Math.Sinh(Math.Log(t)) + + Math.Exp(Math.Sin(u) * Math.Sin(3 * v)) + + Math.Sinh(Math.Log(v * w))); + } + + // Note : a better solution will be an anonymous type casted to IKernelFunction + class epanechnikovKernel : IKernelFunction + { + public double value(double u) + { + if (Math.Abs(u) <= 1) + { + return (3.0 / 4.0) * (1 - u * u); } - public double value(double x) { - double temp = f_.value(x)-Math.Exp(-x*x); - return temp*temp; + else + { + return 0.0; } - } - - errorFunction make_error_function(IValue f) { - return new errorFunction(f); - } - - double multif(double s, double t, double u, double v, double w) { - return Math.Sqrt(s * Math.Sinh(Math.Log(t)) + - Math.Exp(Math.Sin(u) * Math.Sin(3 * v)) + - Math.Sinh(Math.Log(v * w))); - } - - // Note : a better solution will be an anonymous type casted to IKernelFunction - class epanechnikovKernel : IKernelFunction - { - public double value( double u ) - { - if ( Math.Abs( u ) <= 1 ) - { - return ( 3.0 / 4.0 ) * ( 1 - u * u ); - } - else - { - return 0.0; - } - } - } - - - #endregion - + } + } + + + #endregion + } } diff --git a/tests/QLNet.Tests/T_LiborMarketModel.cs b/tests/QLNet.Tests/T_LiborMarketModel.cs index f6bb6aab5..e6e1e8cdd 100644 --- a/tests/QLNet.Tests/T_LiborMarketModel.cs +++ b/tests/QLNet.Tests/T_LiborMarketModel.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,7 +23,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -33,445 +33,468 @@ namespace TestSuite [TestClass()] #endif public class T_LiborMarketModel : IDisposable - { - #region Initialize&Cleanup - private SavedSettings backup; - #if NET40 || NET45 - [TestInitialize] - public void testInitialize() - { - #else - public T_LiborMarketModel() - { - #endif - backup = new SavedSettings(); - } - #if NET40 || NET45 - [TestCleanup] - #endif - public void testCleanup() - { - Dispose(); - } - public void Dispose() - { - backup.Dispose(); - } - #endregion - - IborIndex makeIndex(List dates, - List rates) - { - DayCounter dayCounter = new Actual360(); - - RelinkableHandle termStructure = new RelinkableHandle(); - IborIndex index = new Euribor6M(termStructure); - - Date todaysDate = + { + #region Initialize&Cleanup + private SavedSettings backup; +#if NET40 || NET45 + [TestInitialize] + public void testInitialize() + { +#else + public T_LiborMarketModel() + { +#endif + backup = new SavedSettings(); + } +#if NET40 || NET45 + [TestCleanup] +#endif + public void testCleanup() + { + Dispose(); + } + public void Dispose() + { + backup.Dispose(); + } + #endregion + + IborIndex makeIndex(List dates, + List rates) + { + DayCounter dayCounter = new Actual360(); + + RelinkableHandle termStructure = new RelinkableHandle(); + IborIndex index = new Euribor6M(termStructure); + + Date todaysDate = index.fixingCalendar().adjust(new Date(4, 9, 2005)); - Settings.setEvaluationDate(todaysDate); + Settings.setEvaluationDate(todaysDate); - dates[0] = index.fixingCalendar().advance(todaysDate, + dates[0] = index.fixingCalendar().advance(todaysDate, index.fixingDays(), TimeUnit.Days); - Linear Interpolator = new Linear(); - termStructure.linkTo(new InterpolatedZeroCurve(dates, rates, dayCounter, Interpolator)); - - return index; - } - - IborIndex makeIndex() - { - List dates=new List(); - List rates = new List(); - dates.Add(new Date(4, 9, 2005)); - dates.Add(new Date(4, 9, 2018)); - rates.Add(0.039); - rates.Add(0.041); - - return makeIndex(dates, rates); - } - - OptionletVolatilityStructure makeCapVolCurve(Date todaysDate) - { - double[] vols = {14.40, 17.15, 16.81, 16.64, 16.17, - 15.78, 15.40, 15.21, 14.86}; - - List dates=new List() ; - List capletVols=new List(); - LiborForwardModelProcess process= - new LiborForwardModelProcess(10, makeIndex()); - - for (int i=0; i < 9; ++i) { - capletVols.Add(vols[i]/100); - dates.Add(process.fixingDates()[i+1]); + Linear Interpolator = new Linear(); + termStructure.linkTo(new InterpolatedZeroCurve(dates, rates, dayCounter, Interpolator)); + + return index; + } + + IborIndex makeIndex() + { + List dates = new List(); + List rates = new List(); + dates.Add(new Date(4, 9, 2005)); + dates.Add(new Date(4, 9, 2018)); + rates.Add(0.039); + rates.Add(0.041); + + return makeIndex(dates, rates); + } + + OptionletVolatilityStructure makeCapVolCurve(Date todaysDate) + { + double[] vols = {14.40, 17.15, 16.81, 16.64, 16.17, + 15.78, 15.40, 15.21, 14.86 + }; + + List dates = new List() ; + List capletVols = new List(); + LiborForwardModelProcess process = + new LiborForwardModelProcess(10, makeIndex()); + + for (int i = 0; i < 9; ++i) + { + capletVols.Add(vols[i] / 100); + dates.Add(process.fixingDates()[i + 1]); + } + + return new CapletVarianceCurve(todaysDate, dates, + capletVols, new Actual360()); + } + +#if NET40 || NET45 + [TestCategory("LongRun"), TestMethod()] +#else + [Fact(Skip = "LongRun")] +#endif + public void testSimpleCovarianceModels() + { + // Testing simple covariance models + const int size = 10; + const double tolerance = 1e-14; + int i; + + LmCorrelationModel corrModel = new LmExponentialCorrelationModel(size, 0.1); + + Matrix recon = corrModel.correlation(0.0, null) + - corrModel.pseudoSqrt(0.0, null) * Matrix.transpose(corrModel.pseudoSqrt(0.0, null)); + + for (i = 0; i < size; ++i) + { + for (int j = 0; j < size; ++j) + { + if (Math.Abs(recon[i, j]) > tolerance) + QAssert.Fail("Failed to reproduce correlation matrix" + + "\n calculated: " + recon[i, j] + + "\n expected: " + 0); } + } + + List fixingTimes = new InitializedList(size); + for (i = 0; i < size; ++i) + { + fixingTimes[i] = 0.5 * i; + } + + const double a = 0.2; + const double b = 0.1; + const double c = 2.1; + const double d = 0.3; + + LmVolatilityModel volaModel = new LmLinearExponentialVolatilityModel(fixingTimes, a, b, c, d); + + LfmCovarianceProxy covarProxy = new LfmCovarianceProxy(volaModel, corrModel); - return new CapletVarianceCurve(todaysDate, dates, - capletVols,new Actual360()); - } - - #if NET40 || NET45 - [TestCategory( "LongRun" ), TestMethod()] - #else - [Fact(Skip = "LongRun")] - #endif - public void testSimpleCovarianceModels() - { - // Testing simple covariance models - const int size = 10; - const double tolerance = 1e-14; - int i; - - LmCorrelationModel corrModel=new LmExponentialCorrelationModel(size, 0.1); - - Matrix recon = corrModel.correlation(0.0,null) - - corrModel.pseudoSqrt(0.0,null)*Matrix.transpose(corrModel.pseudoSqrt(0.0,null)); - - for (i=0; i tolerance) - QAssert.Fail("Failed to reproduce correlation matrix" - + "\n calculated: " + recon[i,j] - + "\n expected: " + 0); - } + LiborForwardModelProcess process = new LiborForwardModelProcess(size, makeIndex()); + + LiborForwardModel liborModel = new LiborForwardModel(process, volaModel, corrModel); + + for (double t = 0; t < 4.6; t += 0.31) + { + recon = covarProxy.covariance(t, null) + - covarProxy.diffusion(t, null) * Matrix.transpose(covarProxy.diffusion(t, null)); + + for (int k = 0; k < size; ++k) + { + for (int j = 0; j < size; ++j) + { + if (Math.Abs(recon[k, j]) > tolerance) + QAssert.Fail("Failed to reproduce correlation matrix" + + "\n calculated: " + recon[k, j] + + "\n expected: " + 0); + } } - List fixingTimes=new InitializedList(size); - for (i=0; i 2 * t) + { + double T = fixingTimes[k]; + expected = (a * (T - t) + d) * Math.Exp(-b * (T - t)) + c; + } + + if (Math.Abs(expected - volatility[k]) > tolerance) + QAssert.Fail("Failed to reproduce volatities" + + "\n calculated: " + volatility[k] + + "\n expected: " + expected); } + } + } + +#if NET40 || NET45 + [TestCategory("LongRun"), TestMethod()] +#else + [Fact(Skip = "LongRun")] +#endif + public void testCapletPricing() + { + // Testing caplet pricing + const int size = 10; +#if QL_USE_INDEXED_COUPON + const double tolerance = 1e-5; +#else + const double tolerance = 1e-12; +#endif - const double a=0.2; - const double b=0.1; - const double c=2.1; - const double d=0.3; + IborIndex index = makeIndex(); + LiborForwardModelProcess process = new LiborForwardModelProcess(size, index); - LmVolatilityModel volaModel=new LmLinearExponentialVolatilityModel(fixingTimes, a, b, c, d); + // set-up pricing engine + OptionletVolatilityStructure capVolCurve = makeCapVolCurve(Settings.evaluationDate()); - LfmCovarianceProxy covarProxy=new LfmCovarianceProxy(volaModel, corrModel); + Vector variances = new LfmHullWhiteParameterization(process, capVolCurve).covariance(0.0, null).diagonal(); - LiborForwardModelProcess process=new LiborForwardModelProcess(size, makeIndex()); + LmVolatilityModel volaModel = new LmFixedVolatilityModel(Vector.Sqrt(variances), process.fixingTimes()); - LiborForwardModel liborModel=new LiborForwardModel(process, volaModel, corrModel); + LmCorrelationModel corrModel = new LmExponentialCorrelationModel(size, 0.3); - for (double t=0; t<4.6; t+=0.31) { - recon = covarProxy.covariance(t,null) - - covarProxy.diffusion(t,null)*Matrix.transpose(covarProxy.diffusion(t,null)); + IAffineModel model = (IAffineModel)(new LiborForwardModel(process, volaModel, corrModel)); - for (int k=0; k tolerance) - QAssert.Fail("Failed to reproduce correlation matrix" - + "\n calculated: " + recon[k,j] - + "\n expected: " + 0); - } - } + Handle termStructure = process.index().forwardingTermStructure(); - Vector volatility = volaModel.volatility(t,null); + AnalyticCapFloorEngine engine1 = new AnalyticCapFloorEngine(model, termStructure); - for (int k=0; k2*t) { - double T = fixingTimes[k]; - expected=(a*(T-t)+d)*Math.Exp(-b*(T-t)) + c; - } + Cap cap1 = new Cap(process.cashFlows(), + new InitializedList(size, 0.04)); + cap1.setPricingEngine(engine1); - if (Math.Abs(expected - volatility[k]) > tolerance) - QAssert.Fail("Failed to reproduce volatities" - + "\n calculated: " + volatility[k] - + "\n expected: " + expected); - } - } - } - - #if NET40 || NET45 - [TestCategory( "LongRun" ), TestMethod()] - #else - [Fact(Skip = "LongRun")] - #endif - public void testCapletPricing() - { - // Testing caplet pricing - const int size = 10; - #if QL_USE_INDEXED_COUPON - const double tolerance = 1e-5; - #else - const double tolerance = 1e-12; - #endif - - IborIndex index = makeIndex(); - LiborForwardModelProcess process=new LiborForwardModelProcess(size, index); - - // set-up pricing engine - OptionletVolatilityStructure capVolCurve = makeCapVolCurve(Settings.evaluationDate()); - - Vector variances = new LfmHullWhiteParameterization(process, capVolCurve).covariance(0.0,null).diagonal(); - - LmVolatilityModel volaModel = new LmFixedVolatilityModel(Vector.Sqrt(variances),process.fixingTimes()); - - LmCorrelationModel corrModel = new LmExponentialCorrelationModel(size, 0.3); - - IAffineModel model = (IAffineModel)(new LiborForwardModel(process, volaModel, corrModel)); - - Handle termStructure = process.index().forwardingTermStructure(); - - AnalyticCapFloorEngine engine1 = new AnalyticCapFloorEngine(model, termStructure); - - Cap cap1 = new Cap( process.cashFlows(), - new InitializedList(size, 0.04)); - cap1.setPricingEngine(engine1); - - const double expected = 0.015853935178; - double calculated = cap1.NPV(); - - if (Math.Abs(expected - calculated) > tolerance) - QAssert.Fail("Failed to reproduce npv" - + "\n calculated: " + calculated - + "\n expected: " + expected); - } - - #if NET40 || NET45 - [TestCategory( "LongRun" ), TestMethod()] - #else - [Fact(Skip = "LongRun")] - #endif - public void testCalibration() - { - // Testing calibration of a Libor forward model - const int size = 14; - const double tolerance = 8e-3; - - double[] capVols = {0.145708,0.158465,0.166248,0.168672, - 0.169007,0.167956,0.166261,0.164239, - 0.162082,0.159923,0.157781,0.155745, - 0.153776,0.151950,0.150189,0.148582, - 0.147034,0.145598,0.144248}; - - double[] swaptionVols = {0.170595, 0.166844, 0.158306, 0.147444, - 0.136930, 0.126833, 0.118135, 0.175963, - 0.166359, 0.155203, 0.143712, 0.132769, - 0.122947, 0.114310, 0.174455, 0.162265, - 0.150539, 0.138734, 0.128215, 0.118470, - 0.110540, 0.169780, 0.156860, 0.144821, - 0.133537, 0.123167, 0.114363, 0.106500, - 0.164521, 0.151223, 0.139670, 0.128632, - 0.119123, 0.110330, 0.103114, 0.158956, - 0.146036, 0.134555, 0.124393, 0.115038, - 0.106996, 0.100064}; - - IborIndex index = makeIndex(); - LiborForwardModelProcess process = new LiborForwardModelProcess(size, index); - Handle termStructure = index.forwardingTermStructure(); - - // set-up the model - LmVolatilityModel volaModel = new LmExtLinearExponentialVolModel(process.fixingTimes(), - 0.5,0.6,0.1,0.1); - - LmCorrelationModel corrModel = new LmLinearExponentialCorrelationModel(size, 0.5, 0.8); - - LiborForwardModel model = new LiborForwardModel(process, volaModel, corrModel); - - int swapVolIndex = 0; - DayCounter dayCounter = index.forwardingTermStructure().link.dayCounter(); - - // set-up calibration helper - List calibrationHelper = new List(); - - int i; - for (i=2; i < size; ++i) { - Period maturity = i*index.tenor(); - Handle capVol = new Handle(new SimpleQuote(capVols[i-2])); - - CalibrationHelper caphelper = new CapHelper(maturity, capVol, index,Frequency.Annual, - index.dayCounter(), true, termStructure, CalibrationHelper.CalibrationErrorType.ImpliedVolError); - - caphelper.setPricingEngine(new AnalyticCapFloorEngine(model, termStructure)); - - calibrationHelper.Add(caphelper); - - if (i<= size/2) { - // add a few swaptions to test swaption calibration as well - for (int j=1; j <= size/2; ++j) { - Period len = j*index.tenor(); - Handle swaptionVol = new Handle( - new SimpleQuote(swaptionVols[swapVolIndex++])); - - CalibrationHelper swaptionHelper = - new SwaptionHelper(maturity, len, swaptionVol, index, - index.tenor(), dayCounter, - index.dayCounter(), - termStructure, CalibrationHelper.CalibrationErrorType.ImpliedVolError ); + const double expected = 0.015853935178; + double calculated = cap1.NPV(); - swaptionHelper.setPricingEngine(new LfmSwaptionEngine(model,termStructure)); - - calibrationHelper.Add(swaptionHelper); - } - } - } + if (Math.Abs(expected - calculated) > tolerance) + QAssert.Fail("Failed to reproduce npv" + + "\n calculated: " + calculated + + "\n expected: " + expected); + } - LevenbergMarquardt om = new LevenbergMarquardt(1e-6, 1e-6, 1e-6); - //ConjugateGradient gc = new ConjugateGradient(); - - model.calibrate(calibrationHelper, - om, - new EndCriteria(2000, 100, 1e-6, 1e-6, 1e-6), - new Constraint(), - new List()); - - // measure the calibration error - double calculated = 0.0; - for (i=0; i termStructure = index.forwardingTermStructure(); + + // set-up the model + LmVolatilityModel volaModel = new LmExtLinearExponentialVolModel(process.fixingTimes(), + 0.5, 0.6, 0.1, 0.1); + + LmCorrelationModel corrModel = new LmLinearExponentialCorrelationModel(size, 0.5, 0.8); + + LiborForwardModel model = new LiborForwardModel(process, volaModel, corrModel); + + int swapVolIndex = 0; + DayCounter dayCounter = index.forwardingTermStructure().link.dayCounter(); + + // set-up calibration helper + List calibrationHelper = new List(); + + int i; + for (i = 2; i < size; ++i) + { + Period maturity = i * index.tenor(); + Handle capVol = new Handle(new SimpleQuote(capVols[i - 2])); + + CalibrationHelper caphelper = new CapHelper(maturity, capVol, index, Frequency.Annual, + index.dayCounter(), true, termStructure, CalibrationHelper.CalibrationErrorType.ImpliedVolError); + + caphelper.setPricingEngine(new AnalyticCapFloorEngine(model, termStructure)); + + calibrationHelper.Add(caphelper); + + if (i <= size / 2) + { + // add a few swaptions to test swaption calibration as well + for (int j = 1; j <= size / 2; ++j) + { + Period len = j * index.tenor(); + Handle swaptionVol = new Handle( + new SimpleQuote(swaptionVols[swapVolIndex++])); + + CalibrationHelper swaptionHelper = + new SwaptionHelper(maturity, len, swaptionVol, index, + index.tenor(), dayCounter, + index.dayCounter(), + termStructure, CalibrationHelper.CalibrationErrorType.ImpliedVolError); + + swaptionHelper.setPricingEngine(new LfmSwaptionEngine(model, termStructure)); + + calibrationHelper.Add(swaptionHelper); + } } + } + + LevenbergMarquardt om = new LevenbergMarquardt(1e-6, 1e-6, 1e-6); + //ConjugateGradient gc = new ConjugateGradient(); + + model.calibrate(calibrationHelper, + om, + new EndCriteria(2000, 100, 1e-6, 1e-6, 1e-6), + new Constraint(), + new List()); + + // measure the calibration error + double calculated = 0.0; + for (i = 0; i < calibrationHelper.Count ; ++i) + { + double diff = calibrationHelper[i].calibrationError(); + calculated += diff * diff; + } + + if (Math.Sqrt(calculated) > tolerance) + QAssert.Fail("Failed to calibrate libor forward model" + + "\n calculated diff: " + Math.Sqrt(calculated) + + "\n expected : smaller than " + tolerance); + } - if (Math.Sqrt(calculated) > tolerance) - QAssert.Fail("Failed to calibrate libor forward model" - + "\n calculated diff: " + Math.Sqrt(calculated) - + "\n expected : smaller than " + tolerance); - } - - #if NET40 || NET45 - [TestCategory( "LongRun" ), TestMethod()] - #else - [Fact(Skip = "LongRun")] - #endif - public void testSwaptionPricing() - { - // Testing forward swap and swaption pricing - const int size = 10; - const int steps = 8*size; - #if QL_USE_INDEXED_COUPON - const double tolerance = 1e-6; - #else - const double tolerance = 1e-12; - #endif - - List dates = new List(); - List rates = new List(); - dates.Add(new Date(4,9,2005)); - dates.Add(new Date(4,9,2011)); - rates.Add(0.04); - rates.Add(0.08); - - IborIndex index = makeIndex(dates, rates); - - LiborForwardModelProcess process = new LiborForwardModelProcess(size, index); - - LmCorrelationModel corrModel = new LmExponentialCorrelationModel(size, 0.5); - - LmVolatilityModel volaModel = new LmLinearExponentialVolatilityModel(process.fixingTimes(), - 0.291, 1.483, 0.116, 0.00001); - - // set-up pricing engine - process.setCovarParam((LfmCovarianceParameterization) - new LfmCovarianceProxy(volaModel, corrModel)); - - // set-up a small Monte-Carlo simulation to price swations - List tmp = process.fixingTimes(); - - TimeGrid grid=new TimeGrid(tmp ,tmp.Count, steps); - - List location=new List(); - for (int i=0; i < tmp.Count; ++i) { - location.Add(grid.index(tmp[i])) ; - } - - ulong seed=42; - const int nrTrails = 5000; - LowDiscrepancy.icInstance = new InverseCumulativeNormal(); - - IRNG rsg = (InverseCumulativeRsg - ,InverseCumulativeNormal>) - new PseudoRandom().make_sequence_generator(process.factors()*(grid.size()-1),seed); - - - - MultiPathGenerator generator=new MultiPathGenerator(process, - grid, - rsg, false); - - LiborForwardModel liborModel = new LiborForwardModel(process, volaModel, corrModel); - - Calendar calendar = index.fixingCalendar(); - DayCounter dayCounter = index.forwardingTermStructure().link.dayCounter(); - BusinessDayConvention convention = index.businessDayConvention(); - - Date settlement = index.forwardingTermStructure().link.referenceDate(); - - SwaptionVolatilityMatrix m = liborModel.getSwaptionVolatilityMatrix(); - - for (int i=1; i < size; ++i) { - for (int j=1; j <= size-i; ++j) { - Date fwdStart = settlement + new Period(6*i, TimeUnit.Months); - Date fwdMaturity = fwdStart + new Period(6*j, TimeUnit.Months); - - Schedule schedule =new Schedule(fwdStart, fwdMaturity, index.tenor(), calendar, - convention, convention, DateGeneration.Rule.Forward, false); - - double swapRate = 0.0404; - VanillaSwap forwardSwap = new VanillaSwap(VanillaSwap.Type.Receiver, 1.0, - schedule, swapRate, dayCounter, - schedule, index, 0.0, index.dayCounter()); - forwardSwap.setPricingEngine(new DiscountingSwapEngine(index.forwardingTermStructure())); - - // check forward pricing first - double expected = forwardSwap.fairRate(); - double calculated = liborModel.S_0(i-1,i+j-1); - - if (Math.Abs(expected - calculated) > tolerance) - QAssert.Fail("Failed to reproduce fair forward swap rate" - + "\n calculated: " + calculated - + "\n expected: " + expected); - - swapRate = forwardSwap.fairRate(); - forwardSwap = - new VanillaSwap(VanillaSwap.Type.Receiver, 1.0, - schedule, swapRate, dayCounter, - schedule, index, 0.0, index.dayCounter()); - forwardSwap.setPricingEngine(new DiscountingSwapEngine(index.forwardingTermStructure())); - - if (i == j && i<=size/2) { - IPricingEngine engine = - new LfmSwaptionEngine(liborModel, index.forwardingTermStructure()); - Exercise exercise = - new EuropeanExercise(process.fixingDates()[i]); - - Swaption swaption = - new Swaption(forwardSwap, exercise); - swaption.setPricingEngine(engine); - - GeneralStatistics stat = new GeneralStatistics(); - - for (int n=0; n path = ( n % 2 != 0 ) ? generator.antithetic() - : generator.next(); - MultiPath value = path.value as MultiPath; - Utils.QL_REQUIRE( value != null, () => "Invalid Path" ); - //Sample path = generator.next(); - List rates_ = new InitializedList(size); - for (int k=0; k dis = process.discountBond(rates_); - - double npv=0.0; - for (int k=i; k < i+j; ++k) { - npv += (swapRate - rates_[k]) - * ( process.accrualEndTimes()[k] - - process.accrualStartTimes()[k])*dis[k]; - } - stat.add(Math.Max(npv, 0.0)); - } - - if (Math.Abs(swaption.NPV() - stat.mean()) - > stat.errorEstimate()*2.35) - QAssert.Fail("Failed to reproduce swaption npv" - + "\n calculated: " + stat.mean() - + "\n expected: " + swaption.NPV()); - } - } +#if NET40 || NET45 + [TestCategory("LongRun"), TestMethod()] +#else + [Fact(Skip = "LongRun")] +#endif + public void testSwaptionPricing() + { + // Testing forward swap and swaption pricing + const int size = 10; + const int steps = 8 * size; +#if QL_USE_INDEXED_COUPON + const double tolerance = 1e-6; +#else + const double tolerance = 1e-12; +#endif + + List dates = new List(); + List rates = new List(); + dates.Add(new Date(4, 9, 2005)); + dates.Add(new Date(4, 9, 2011)); + rates.Add(0.04); + rates.Add(0.08); + + IborIndex index = makeIndex(dates, rates); + + LiborForwardModelProcess process = new LiborForwardModelProcess(size, index); + + LmCorrelationModel corrModel = new LmExponentialCorrelationModel(size, 0.5); + + LmVolatilityModel volaModel = new LmLinearExponentialVolatilityModel(process.fixingTimes(), + 0.291, 1.483, 0.116, 0.00001); + + // set-up pricing engine + process.setCovarParam((LfmCovarianceParameterization) + new LfmCovarianceProxy(volaModel, corrModel)); + + // set-up a small Monte-Carlo simulation to price swations + List tmp = process.fixingTimes(); + + TimeGrid grid = new TimeGrid(tmp, tmp.Count, steps); + + List location = new List(); + for (int i = 0; i < tmp.Count; ++i) + { + location.Add(grid.index(tmp[i])) ; + } + + ulong seed = 42; + const int nrTrails = 5000; + LowDiscrepancy.icInstance = new InverseCumulativeNormal(); + + IRNG rsg = (InverseCumulativeRsg + , InverseCumulativeNormal>) + new PseudoRandom().make_sequence_generator(process.factors() * (grid.size() - 1), seed); + + + + MultiPathGenerator generator = new MultiPathGenerator(process, + grid, + rsg, false); + + LiborForwardModel liborModel = new LiborForwardModel(process, volaModel, corrModel); + + Calendar calendar = index.fixingCalendar(); + DayCounter dayCounter = index.forwardingTermStructure().link.dayCounter(); + BusinessDayConvention convention = index.businessDayConvention(); + + Date settlement = index.forwardingTermStructure().link.referenceDate(); + + SwaptionVolatilityMatrix m = liborModel.getSwaptionVolatilityMatrix(); + + for (int i = 1; i < size; ++i) + { + for (int j = 1; j <= size - i; ++j) + { + Date fwdStart = settlement + new Period(6 * i, TimeUnit.Months); + Date fwdMaturity = fwdStart + new Period(6 * j, TimeUnit.Months); + + Schedule schedule = new Schedule(fwdStart, fwdMaturity, index.tenor(), calendar, + convention, convention, DateGeneration.Rule.Forward, false); + + double swapRate = 0.0404; + VanillaSwap forwardSwap = new VanillaSwap(VanillaSwap.Type.Receiver, 1.0, + schedule, swapRate, dayCounter, + schedule, index, 0.0, index.dayCounter()); + forwardSwap.setPricingEngine(new DiscountingSwapEngine(index.forwardingTermStructure())); + + // check forward pricing first + double expected = forwardSwap.fairRate(); + double calculated = liborModel.S_0(i - 1, i + j - 1); + + if (Math.Abs(expected - calculated) > tolerance) + QAssert.Fail("Failed to reproduce fair forward swap rate" + + "\n calculated: " + calculated + + "\n expected: " + expected); + + swapRate = forwardSwap.fairRate(); + forwardSwap = + new VanillaSwap(VanillaSwap.Type.Receiver, 1.0, + schedule, swapRate, dayCounter, + schedule, index, 0.0, index.dayCounter()); + forwardSwap.setPricingEngine(new DiscountingSwapEngine(index.forwardingTermStructure())); + + if (i == j && i <= size / 2) + { + IPricingEngine engine = + new LfmSwaptionEngine(liborModel, index.forwardingTermStructure()); + Exercise exercise = + new EuropeanExercise(process.fixingDates()[i]); + + Swaption swaption = + new Swaption(forwardSwap, exercise); + swaption.setPricingEngine(engine); + + GeneralStatistics stat = new GeneralStatistics(); + + for (int n = 0; n < nrTrails; ++n) + { + Sample path = (n % 2 != 0) ? generator.antithetic() + : generator.next(); + MultiPath value = path.value as MultiPath; + Utils.QL_REQUIRE(value != null, () => "Invalid Path"); + //Sample path = generator.next(); + List rates_ = new InitializedList(size); + for (int k = 0; k < process.size(); ++k) + { + rates_[k] = value[k][location[i]]; + } + List dis = process.discountBond(rates_); + + double npv = 0.0; + for (int k = i; k < i + j; ++k) + { + npv += (swapRate - rates_[k]) + * (process.accrualEndTimes()[k] + - process.accrualStartTimes()[k]) * dis[k]; + } + stat.add(Math.Max(npv, 0.0)); + } + + if (Math.Abs(swaption.NPV() - stat.mean()) + > stat.errorEstimate() * 2.35) + QAssert.Fail("Failed to reproduce swaption npv" + + "\n calculated: " + stat.mean() + + "\n expected: " + swaption.NPV()); + } } - } - } -} \ No newline at end of file + } + } + } +} diff --git a/tests/QLNet.Tests/T_LiborMarketModelProcess.cs b/tests/QLNet.Tests/T_LiborMarketModelProcess.cs index c4ce73665..ac957e8ba 100644 --- a/tests/QLNet.Tests/T_LiborMarketModelProcess.cs +++ b/tests/QLNet.Tests/T_LiborMarketModelProcess.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,7 +23,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -33,349 +33,369 @@ namespace TestSuite [TestClass()] #endif public class T_LiborMarketModelProcess : IDisposable - { - #region Initialize&Cleanup - private SavedSettings backup; - #if NET40 || NET45 - [TestInitialize] - public void testInitialize() - { - #else - public T_LiborMarketModelProcess() - { - #endif - - backup = new SavedSettings(); - } - #if NET40 || NET45 - [TestCleanup] - #endif - public void testCleanup() - { - Dispose(); - } - public void Dispose() - { - backup.Dispose(); - } - #endregion - - int len = 10; - - IborIndex makeIndex() - { - DayCounter dayCounter = new Actual360(); - List dates = new List(); - List rates = new List(); - dates.Add(new Date(4,9,2005)); - dates.Add(new Date(4,9,2018)); - rates.Add(0.01); - rates.Add(0.08); - Linear Interpolator=new Linear(); - RelinkableHandle termStructure= new RelinkableHandle(); - //termStructure.linkTo(new InterpolatedZeroCurve(dates, rates, dayCounter, Interpolator)); - - IborIndex index = new Euribor1Y(termStructure); - - Date todaysDate = - index.fixingCalendar().adjust(new Date(4,9,2005)); - Settings.setEvaluationDate(todaysDate); + { + #region Initialize&Cleanup + private SavedSettings backup; +#if NET40 || NET45 + [TestInitialize] + public void testInitialize() + { +#else + public T_LiborMarketModelProcess() + { +#endif - dates[0] = index.fixingCalendar().advance(todaysDate, + backup = new SavedSettings(); + } +#if NET40 || NET45 + [TestCleanup] +#endif + public void testCleanup() + { + Dispose(); + } + public void Dispose() + { + backup.Dispose(); + } + #endregion + + int len = 10; + + IborIndex makeIndex() + { + DayCounter dayCounter = new Actual360(); + List dates = new List(); + List rates = new List(); + dates.Add(new Date(4, 9, 2005)); + dates.Add(new Date(4, 9, 2018)); + rates.Add(0.01); + rates.Add(0.08); + Linear Interpolator = new Linear(); + RelinkableHandle termStructure = new RelinkableHandle(); + //termStructure.linkTo(new InterpolatedZeroCurve(dates, rates, dayCounter, Interpolator)); + + IborIndex index = new Euribor1Y(termStructure); + + Date todaysDate = + index.fixingCalendar().adjust(new Date(4, 9, 2005)); + Settings.setEvaluationDate(todaysDate); + + dates[0] = index.fixingCalendar().advance(todaysDate, index.fixingDays(), TimeUnit.Days); - //termStructure.linkTo(new ZeroCurve(dates, rates, dayCounter)); - termStructure.linkTo(new InterpolatedZeroCurve(dates, rates, dayCounter, Interpolator)); + //termStructure.linkTo(new ZeroCurve(dates, rates, dayCounter)); + termStructure.linkTo(new InterpolatedZeroCurve(dates, rates, dayCounter, Interpolator)); + + return index; + } + + CapletVarianceCurve makeCapVolCurve(Date todaysDate) + { + double[] vols = {14.40, 17.15, 16.81, 16.64, 16.17, + 15.78, 15.40, 15.21, 14.86, 14.54 + }; - return index; - } + List dates = new List(); + List capletVols = new List(); + LiborForwardModelProcess process = new LiborForwardModelProcess(len + 1, makeIndex(), null); + + for (int i = 0; i < len; ++i) + { + capletVols.Add(vols[i] / 100); + dates.Add(process.fixingDates()[i + 1]); + } + + return new CapletVarianceCurve(todaysDate, dates, + capletVols, new ActualActual()); + } + + LiborForwardModelProcess makeProcess() + { + Matrix volaComp = new Matrix(); + return makeProcess(volaComp); + } + + LiborForwardModelProcess makeProcess(Matrix volaComp) + { + int factors = (volaComp.empty() ? 1 : volaComp.columns()); + + IborIndex index = makeIndex(); + LiborForwardModelProcess process = new LiborForwardModelProcess(len, index, null); + + LfmCovarianceParameterization fct = new LfmHullWhiteParameterization( + process, + makeCapVolCurve(Settings.evaluationDate()), + volaComp * Matrix.transpose(volaComp), factors); + + process.setCovarParam(fct); + + return process; + } + +#if NET40 || NET45 + [TestCategory("LongRun"), TestMethod()] +#else + [Fact(Skip = "LongRun")] +#endif + public void testInitialisation() + { + // Testing caplet LMM process initialisation + DayCounter dayCounter = new Actual360(); + RelinkableHandle termStructure = new RelinkableHandle(); + termStructure.linkTo(Utilities.flatRate(Date.Today, 0.04, dayCounter)); + + IborIndex index = new Euribor6M(termStructure); + OptionletVolatilityStructure capletVol = new ConstantOptionletVolatility( + termStructure.currentLink().referenceDate(), + termStructure.currentLink().calendar(), + BusinessDayConvention.Following, + 0.2, + termStructure.currentLink().dayCounter()); + + Calendar calendar = index.fixingCalendar(); + + for (int daysOffset = 0; daysOffset < 1825 /* 5 year*/; daysOffset += 8) + { + Date todaysDate = calendar.adjust(Date.Today + daysOffset); + Settings.setEvaluationDate(todaysDate); + Date settlementDate = + calendar.advance(todaysDate, index.fixingDays(), TimeUnit.Days); - CapletVarianceCurve makeCapVolCurve(Date todaysDate) - { - double[] vols = {14.40, 17.15, 16.81, 16.64, 16.17, - 15.78, 15.40, 15.21, 14.86, 14.54}; + termStructure.linkTo(Utilities.flatRate(settlementDate, 0.04, dayCounter)); - List dates = new List(); - List capletVols = new List(); - LiborForwardModelProcess process= new LiborForwardModelProcess(len+1, makeIndex(),null); + LiborForwardModelProcess process = new LiborForwardModelProcess(60, index); - for (int i=0; i < len; ++i) + List fixings = process.fixingTimes(); + for (int i = 1; i < fixings.Count - 1; ++i) { - capletVols.Add(vols[i]/100); - dates.Add(process.fixingDates()[i+1]); + int ileft = process.nextIndexReset(fixings[i] - 0.000001); + int iright = process.nextIndexReset(fixings[i] + 0.000001); + int ii = process.nextIndexReset(fixings[i]); + + if ((ileft != i) || (iright != i + 1) || (ii != i + 1)) + { + QAssert.Fail("Failed to next index resets"); + } } - return new CapletVarianceCurve( todaysDate, dates, - capletVols, new ActualActual()); - } - - LiborForwardModelProcess makeProcess() - { - Matrix volaComp=new Matrix(); - return makeProcess(volaComp); - } - - LiborForwardModelProcess makeProcess(Matrix volaComp) - { - int factors = (volaComp.empty() ? 1 : volaComp.columns()); - - IborIndex index = makeIndex(); - LiborForwardModelProcess process= new LiborForwardModelProcess(len, index,null); - - LfmCovarianceParameterization fct=new LfmHullWhiteParameterization( - process, - makeCapVolCurve(Settings.evaluationDate()), - volaComp * Matrix.transpose(volaComp), factors); - - process.setCovarParam(fct); - - return process; - } - - #if NET40 || NET45 - [TestCategory( "LongRun" ), TestMethod()] - #else - [Fact(Skip = "LongRun")] - #endif - public void testInitialisation() - { - // Testing caplet LMM process initialisation - DayCounter dayCounter = new Actual360(); - RelinkableHandle termStructure= new RelinkableHandle(); - termStructure.linkTo(Utilities.flatRate(Date.Today, 0.04, dayCounter)); - - IborIndex index=new Euribor6M(termStructure); - OptionletVolatilityStructure capletVol = new ConstantOptionletVolatility( - termStructure.currentLink().referenceDate(), - termStructure.currentLink().calendar(), - BusinessDayConvention.Following, - 0.2, - termStructure.currentLink().dayCounter()); - - Calendar calendar = index.fixingCalendar(); - - for (int daysOffset=0; daysOffset < 1825 /* 5 year*/; daysOffset+=8) { - Date todaysDate = calendar.adjust(Date.Today+daysOffset); - Settings.setEvaluationDate(todaysDate); - Date settlementDate = - calendar.advance(todaysDate, index.fixingDays(), TimeUnit.Days); - - termStructure.linkTo(Utilities.flatRate(settlementDate, 0.04, dayCounter)); - - LiborForwardModelProcess process=new LiborForwardModelProcess(60, index); - - List fixings = process.fixingTimes(); - for (int i=1; i < fixings.Count-1; ++i) { - int ileft = process.nextIndexReset(fixings[i]-0.000001); - int iright = process.nextIndexReset(fixings[i]+0.000001); - int ii = process.nextIndexReset(fixings[i]); - - if ((ileft != i) || (iright != i+1) || (ii != i+1)) { - QAssert.Fail("Failed to next index resets"); - } - } + } + } +#if NET40 || NET45 + [TestCategory("LongRun"), TestMethod()] +#else + [Fact(Skip = "LongRun")] +#endif + public void testLambdaBootstrapping() + { + // Testing caplet LMM lambda bootstrapping + double tolerance = 1e-10; + double[] lambdaExpected = {14.3010297550, 19.3821411939, 15.9816590141, + 15.9953118303, 14.0570815635, 13.5687599894, + 12.7477197786, 13.7056638165, 11.6191989567 + }; + + LiborForwardModelProcess process = makeProcess(); + Matrix covar = process.covariance(0.0, null, 1.0); + + for (int i = 0; i < 9; ++i) + { + double calculated = Math.Sqrt(covar[i + 1, i + 1]); + double expected = lambdaExpected[i] / 100; + + if (Math.Abs(calculated - expected) > tolerance) + QAssert.Fail("Failed to reproduce expected lambda values" + + "\n calculated: " + calculated + + "\n expected: " + expected); + } + + LfmCovarianceParameterization param = process.covarParam(); + + List tmp = process.fixingTimes(); + TimeGrid grid = new TimeGrid(tmp.Last(), 14); + + for (int t = 0; t < grid.size(); ++t) + { + //verifier la presence du null + Matrix diff = param.integratedCovariance(grid[t]) + - param.integratedCovariance(grid[t]); + + for (int i = 0; i < diff.rows(); ++i) + { + for (int j = 0; j < diff.columns(); ++j) + { + if (Math.Abs(diff[i, j]) > tolerance) + { + QAssert.Fail("Failed to reproduce integrated covariance" + + "\n calculated: " + diff[i, j] + + "\n expected: " + 0); + } + } } - } - - #if NET40 || NET45 - [TestCategory( "LongRun" ), TestMethod()] - #else - [Fact(Skip = "LongRun")] - #endif - public void testLambdaBootstrapping() - { - // Testing caplet LMM lambda bootstrapping - double tolerance = 1e-10; - double[] lambdaExpected = {14.3010297550, 19.3821411939, 15.9816590141, - 15.9953118303, 14.0570815635, 13.5687599894, - 12.7477197786, 13.7056638165, 11.6191989567}; - - LiborForwardModelProcess process = makeProcess(); - Matrix covar = process.covariance(0.0, null, 1.0); - - for (int i=0; i<9; ++i) { - double calculated = Math.Sqrt(covar[i+1,i+1]); - double expected = lambdaExpected[i]/100; - - if (Math.Abs(calculated - expected) > tolerance) - QAssert.Fail("Failed to reproduce expected lambda values" - + "\n calculated: " + calculated - + "\n expected: " + expected); - } + } + } - LfmCovarianceParameterization param = process.covarParam(); - - List tmp = process.fixingTimes(); - TimeGrid grid= new TimeGrid(tmp.Last(), 14); - - for (int t=0; t tolerance) - { - QAssert.Fail("Failed to reproduce integrated covariance" - + "\n calculated: " + diff[i,j] - + "\n expected: " + 0); - } - } - } +#if NET40 || NET45 + [TestCategory("LongRun"), TestMethod()] +#else + [Fact(Skip = "LongRun")] +#endif + public void testMonteCarloCapletPricing() + { + // Testing caplet LMM Monte-Carlo caplet pricing + + /* factor loadings are taken from Hull & White article + plus extra normalisation to get orthogonal eigenvectors + http://www.rotman.utoronto.ca/~amackay/fin/libormktmodel2.pdf */ + double[] compValues = {0.85549771, 0.46707264, 0.22353259, + 0.91915359, 0.37716089, 0.11360610, + 0.96438280, 0.26413316, -0.01412414, + 0.97939148, 0.13492952, -0.15028753, + 0.95970595, -0.00000000, -0.28100621, + 0.97939148, -0.13492952, -0.15028753, + 0.96438280, -0.26413316, -0.01412414, + 0.91915359, -0.37716089, 0.11360610, + 0.85549771, -0.46707264, 0.22353259 + }; + + Matrix volaComp = new Matrix(9, 3); + List lcompValues = new InitializedList(27, 0); + List ltemp = new InitializedList(3, 0); + lcompValues = compValues.ToList(); + //std::copy(compValues, compValues+9*3, volaComp.begin()); + for (int i = 0; i < 9; i++) + { + ltemp = lcompValues.GetRange(3 * i, 3); + for (int j = 0; j < 3; j++) + volaComp[i, j] = ltemp[j]; + } + LiborForwardModelProcess process1 = makeProcess(); + LiborForwardModelProcess process2 = makeProcess(volaComp); + + List tmp = process1.fixingTimes(); + TimeGrid grid = new TimeGrid(tmp, tmp.Count, 12); + + List location = new List(); + for (int i = 0; i < tmp.Count; ++i) + { + location.Add(grid.index(tmp[i])) ; + } + + // set-up a small Monte-Carlo simulation to price caplets + // and ratchet caps using a one- and a three factor libor market model + + ulong seed = 42; + LowDiscrepancy.icInstance = new InverseCumulativeNormal(); + IRNG rsg1 = (IRNG)new LowDiscrepancy().make_sequence_generator( + process1.factors() * (grid.size() - 1), seed); + IRNG rsg2 = (IRNG)new LowDiscrepancy().make_sequence_generator( + process2.factors() * (grid.size() - 1), seed); + + MultiPathGenerator generator1 = new MultiPathGenerator (process1, grid, rsg1, false); + MultiPathGenerator generator2 = new MultiPathGenerator (process2, grid, rsg2, false); + + const int nrTrails = 250000; + List stat1 = new InitializedList(process1.size()); + List stat2 = new InitializedList(process2.size()); + List stat3 = new InitializedList(process2.size() - 1); + for (int i = 0; i < nrTrails; ++i) + { + Sample path1 = generator1.next(); + Sample path2 = generator2.next(); + MultiPath value1 = path1.value as MultiPath; + Utils.QL_REQUIRE(value1 != null, () => "Invalid Path"); + MultiPath value2 = path2.value as MultiPath; + Utils.QL_REQUIRE(value2 != null, () => "Invalid Path"); + + List rates1 = new InitializedList(len); + List rates2 = new InitializedList(len); + for (int j = 0; j < process1.size(); ++j) + { + rates1[j] = value1[j][location[j]]; + rates2[j] = value2[j][location[j]]; } - } - - #if NET40 || NET45 - [TestCategory( "LongRun" ), TestMethod()] - #else - [Fact(Skip = "LongRun")] - #endif - public void testMonteCarloCapletPricing() - { - // Testing caplet LMM Monte-Carlo caplet pricing - - /* factor loadings are taken from Hull & White article - plus extra normalisation to get orthogonal eigenvectors - http://www.rotman.utoronto.ca/~amackay/fin/libormktmodel2.pdf */ - double[] compValues = {0.85549771, 0.46707264, 0.22353259, - 0.91915359, 0.37716089, 0.11360610, - 0.96438280, 0.26413316,-0.01412414, - 0.97939148, 0.13492952,-0.15028753, - 0.95970595,-0.00000000,-0.28100621, - 0.97939148,-0.13492952,-0.15028753, - 0.96438280,-0.26413316,-0.01412414, - 0.91915359,-0.37716089, 0.11360610, - 0.85549771,-0.46707264, 0.22353259}; - - Matrix volaComp=new Matrix(9,3); - List lcompValues=new InitializedList(27,0); - List ltemp = new InitializedList(3, 0); - lcompValues=compValues.ToList(); - //std::copy(compValues, compValues+9*3, volaComp.begin()); - for (int i = 0; i < 9; i++) + + List dis1 = process1.discountBond(rates1); + List dis2 = process2.discountBond(rates2); + + for (int k = 0; k < process1.size(); ++k) { - ltemp = lcompValues.GetRange(3*i, 3); - for (int j = 0; j < 3; j++) - volaComp[i, j] = ltemp[j]; + double accrualPeriod = process1.accrualEndTimes()[k] + - process1.accrualStartTimes()[k]; + // caplet payoff function, cap rate at 4% + double payoff1 = Math.Max(rates1[k] - 0.04, 0.0) * accrualPeriod; + + double payoff2 = Math.Max(rates2[k] - 0.04, 0.0) * accrualPeriod; + stat1[k].add(dis1[k] * payoff1); + stat2[k].add(dis2[k] * payoff2); + + if (k != 0) + { + // ratchet cap payoff function + double payoff3 = Math.Max(rates2[k] - (rates2[k - 1] + 0.0025), 0.0) + * accrualPeriod; + stat3[k - 1].add(dis2[k] * payoff3); + } } - LiborForwardModelProcess process1 = makeProcess(); - LiborForwardModelProcess process2 = makeProcess(volaComp); - List tmp = process1.fixingTimes(); - TimeGrid grid=new TimeGrid(tmp ,tmp.Count, 12); + } + + double[] capletNpv = {0.000000000000, 0.000002841629, 0.002533279333, + 0.009577143571, 0.017746502618, 0.025216116835, + 0.031608230268, 0.036645683881, 0.039792254012, + 0.041829864365 + }; + + double[] ratchetNpv = {0.0082644895, 0.0082754754, 0.0082159966, + 0.0082982822, 0.0083803357, 0.0084366961, + 0.0084173270, 0.0081803406, 0.0079533814 + }; - List location=new List(); - for (int i=0; i < tmp.Count; ++i) { - location.Add(grid.index(tmp[i])) ; + for (int k = 0; k < process1.size(); ++k) + { + + double calculated1 = stat1[k].mean(); + double tolerance1 = stat1[k].errorEstimate(); + double expected = capletNpv[k]; + + if (Math.Abs(calculated1 - expected) > tolerance1) + { + QAssert.Fail("Failed to reproduce expected caplet NPV" + + "\n calculated: " + calculated1 + + "\n error int: " + tolerance1 + + "\n expected: " + expected); } - // set-up a small Monte-Carlo simulation to price caplets - // and ratchet caps using a one- and a three factor libor market model - - ulong seed = 42; - LowDiscrepancy.icInstance = new InverseCumulativeNormal(); - IRNG rsg1 = (IRNG)new LowDiscrepancy().make_sequence_generator( - process1.factors()*(grid.size()-1), seed); - IRNG rsg2 = (IRNG)new LowDiscrepancy().make_sequence_generator( - process2.factors()*(grid.size()-1), seed); - - MultiPathGenerator generator1=new MultiPathGenerator (process1, grid, rsg1, false); - MultiPathGenerator generator2=new MultiPathGenerator (process2, grid, rsg2, false); - - const int nrTrails = 250000; - List stat1 = new InitializedList(process1.size()); - List stat2 = new InitializedList(process2.size()); - List stat3 = new InitializedList(process2.size() - 1); - for (int i=0; i path1 = generator1.next(); - Sample path2 = generator2.next(); - MultiPath value1 = path1.value as MultiPath; - Utils.QL_REQUIRE( value1 != null, () => "Invalid Path" ); - MultiPath value2 = path2.value as MultiPath; - Utils.QL_REQUIRE( value2 != null, () => "Invalid Path" ); - - List rates1=new InitializedList(len); - List rates2 = new InitializedList(len); - for (int j=0; j dis1 = process1.discountBond(rates1); - List dis2 = process2.discountBond(rates2); - - for (int k=0; k tolerance2) + { + QAssert.Fail("Failed to reproduce expected caplet NPV" + + "\n calculated: " + calculated2 + + "\n error int: " + tolerance2 + + "\n expected: " + expected); } - double[] capletNpv = {0.000000000000, 0.000002841629, 0.002533279333, - 0.009577143571, 0.017746502618, 0.025216116835, - 0.031608230268, 0.036645683881, 0.039792254012, - 0.041829864365}; - - double[] ratchetNpv = {0.0082644895, 0.0082754754, 0.0082159966, - 0.0082982822, 0.0083803357, 0.0084366961, - 0.0084173270, 0.0081803406, 0.0079533814}; - - for (int k=0; k < process1.size(); ++k) { - - double calculated1 = stat1[k].mean(); - double tolerance1 = stat1[k].errorEstimate(); - double expected = capletNpv[k]; - - if (Math.Abs(calculated1 - expected) > tolerance1) { - QAssert.Fail("Failed to reproduce expected caplet NPV" - + "\n calculated: " + calculated1 - + "\n error int: " + tolerance1 - + "\n expected: " + expected); - } - - double calculated2 = stat2[k].mean(); - double tolerance2 = stat2[k].errorEstimate(); - - if (Math.Abs(calculated2 - expected) > tolerance2) { - QAssert.Fail("Failed to reproduce expected caplet NPV" - + "\n calculated: " + calculated2 - + "\n error int: " + tolerance2 - + "\n expected: " + expected); - } - - if (k != 0) { - double calculated3 = stat3[k-1].mean(); - double tolerance3 = stat3[k-1].errorEstimate(); - expected = ratchetNpv[k-1]; - - double refError = 1e-5; // 1e-5. error bars of the reference values - - if (Math.Abs(calculated3 - expected) > tolerance3 + refError) { - QAssert.Fail("Failed to reproduce expected caplet NPV" - + "\n calculated: " + calculated3 - + "\n error int: " + tolerance3 + refError - + "\n expected: " + expected); - } - } + if (k != 0) + { + double calculated3 = stat3[k - 1].mean(); + double tolerance3 = stat3[k - 1].errorEstimate(); + expected = ratchetNpv[k - 1]; + + double refError = 1e-5; // 1e-5. error bars of the reference values + + if (Math.Abs(calculated3 - expected) > tolerance3 + refError) + { + QAssert.Fail("Failed to reproduce expected caplet NPV" + + "\n calculated: " + calculated3 + + "\n error int: " + tolerance3 + refError + + "\n expected: " + expected); + } } - } - } + } + } + } } diff --git a/tests/QLNet.Tests/T_LinearLeastSquaresRegression.cs b/tests/QLNet.Tests/T_LinearLeastSquaresRegression.cs index 82ab5e163..83622e0a1 100644 --- a/tests/QLNet.Tests/T_LinearLeastSquaresRegression.cs +++ b/tests/QLNet.Tests/T_LinearLeastSquaresRegression.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,225 +21,245 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; -namespace TestSuite { - /// - /// Summary description for LinearLeastSquaresRegression - /// - #if NET40 || NET45 +namespace TestSuite +{ + /// + /// Summary description for LinearLeastSquaresRegression + /// +#if NET40 || NET45 [TestClass] - #endif +#endif public class T_LinearLeastSquaresRegression : IDisposable - { - - #region Initialize&Cleanup - private SavedSettings backup; - #if NET40 || NET45 - [TestInitialize] - public void testInitialize() - { - #else - public T_LinearLeastSquaresRegression() - { - #endif - - backup = new SavedSettings(); - } - #if NET40 || NET45 - [TestCleanup] - #endif - public void testCleanup() - { - Dispose(); - } - public void Dispose() - { - backup.Dispose(); - } - #endregion - - const double tolerance = 0.025; + { + #region Initialize&Cleanup + private SavedSettings backup; #if NET40 || NET45 - [TestMethod()] + [TestInitialize] + public void testInitialize() + { #else - [Fact] + public T_LinearLeastSquaresRegression() + { #endif - public void testRegression() - { - // Testing linear least-squares regression - const int nr=100000; - - var rng = new InverseCumulativeRng( - new MersenneTwisterUniformRng(1234u)); - - List> v = new List>(); - v.Add(x => 1.0); - v.Add(x => x); - v.Add(x => x*x); - v.Add(Math.Sin); - - List> w = new List>(v); - w.Add(x => x*x); - - for (int k=0; k<3; ++k) { - int i; - double[] a = { rng.next().value, - rng.next().value, - rng.next().value, - rng.next().value}; - - List x = new InitializedList(nr), y = new InitializedList(nr); - for (i=0; i tolerance) { - QAssert.Fail("Failed to reproduce linear regression coef." - + "\n error: " + m.standardErrors()[i] - + "\n tolerance: " + tolerance); - } - if (Math.Abs(m.coefficients()[i]-a[i]) > 3*m.error()[i]) { - QAssert.Fail("Failed to reproduce linear regression coef." - + "\n calculated: " + m.coefficients()[i] - + "\n error: " + m.standardErrors()[i] - + "\n expected: " + a[i]); - } - } - - m = new LinearLeastSquaresRegression(x, y, w); - - double[] ma = { m.coefficients()[0], m.coefficients()[1], m.coefficients()[2] + m.coefficients()[4], m.coefficients()[3] }; - double[] err = {m.standardErrors()[0], m.standardErrors()[1], - Math.Sqrt( m.standardErrors()[2]*m.standardErrors()[2] - +m.standardErrors()[4]*m.standardErrors()[4]), - m.standardErrors()[3]}; - for (i = 0; i < v.Count; ++i) { - if (Math.Abs(ma[i] - a[i]) > 3 * err[i]) { - QAssert.Fail("Failed to reproduce linear regression coef." - + "\n calculated: " + ma[i] - + "\n error: " + err[i] - + "\n expected: " + a[i]); - } - } + + backup = new SavedSettings(); + } +#if NET40 || NET45 + [TestCleanup] +#endif + public void testCleanup() + { + Dispose(); + } + public void Dispose() + { + backup.Dispose(); + } + #endregion + + const double tolerance = 0.025; + +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testRegression() + { + // Testing linear least-squares regression + const int nr = 100000; + + var rng = new InverseCumulativeRng( + new MersenneTwisterUniformRng(1234u)); + + List> v = new List>(); + v.Add(x => 1.0); + v.Add(x => x); + v.Add(x => x * x); + v.Add(Math.Sin); + + List> w = new List>(v); + w.Add(x => x * x); + + for (int k = 0; k < 3; ++k) + { + int i; + double[] a = { rng.next().value, + rng.next().value, + rng.next().value, + rng.next().value + }; + + List x = new InitializedList(nr), y = new InitializedList(nr); + for (i = 0; i < nr; ++i) + { + x[i] = rng.next().value; + + // regression in y = a_1 + a_2*x + a_3*x^2 + a_4*sin(x) + eps + y[i] = a[0] * v[0](x[i]) + a[1] * v[1](x[i]) + a[2] * v[2](x[i]) + + a[3] * v[3](x[i]) + rng.next().value; + } + + LinearLeastSquaresRegression m = new LinearLeastSquaresRegression(x, y, v); + + for (i = 0; i < v.Count; ++i) + { + if (m.standardErrors()[i] > tolerance) + { + QAssert.Fail("Failed to reproduce linear regression coef." + + "\n error: " + m.standardErrors()[i] + + "\n tolerance: " + tolerance); + } + if (Math.Abs(m.coefficients()[i] - a[i]) > 3 * m.error()[i]) + { + QAssert.Fail("Failed to reproduce linear regression coef." + + "\n calculated: " + m.coefficients()[i] + + "\n error: " + m.standardErrors()[i] + + "\n expected: " + a[i]); + } + } + + m = new LinearLeastSquaresRegression(x, y, w); + + double[] ma = { m.coefficients()[0], m.coefficients()[1], m.coefficients()[2] + m.coefficients()[4], m.coefficients()[3] }; + double[] err = {m.standardErrors()[0], m.standardErrors()[1], + Math.Sqrt(m.standardErrors()[2]*m.standardErrors()[2] + + m.standardErrors()[4]*m.standardErrors()[4]), + m.standardErrors()[3] + }; + for (i = 0; i < v.Count; ++i) + { + if (Math.Abs(ma[i] - a[i]) > 3 * err[i]) + { + QAssert.Fail("Failed to reproduce linear regression coef." + + "\n calculated: " + ma[i] + + "\n error: " + err[i] + + "\n expected: " + a[i]); + } } + } - } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void test1dLinearRegression() - { - // Testing 1d simple linear least-squares regression - - /* Example taken from the QuantLib-User list, see posting - * Multiple linear regression/weighted regression, Boris Skorodumov */ - - List x = new InitializedList(9), - y = new InitializedList(9); - x[0] = 2.4; x[1] = 1.8; x[2] = 2.5; x[3] = 3.0; - x[4] = 2.1; x[5] = 1.2; x[6] = 2.0; x[7] = 2.7; x[8] = 3.6; - - y[0] = 7.8; y[1] = 5.5; y[2] = 8.0; y[3] = 9.0; - y[4] = 6.5; y[5] = 4.0; y[6] = 6.3; y[7] = 8.4; y[8] = 10.2; - - List> v = new List>(); - v.Add(a => 1.0); - v.Add(a => a); - - LinearRegression m = new LinearRegression(x, y); - - const double tol = 0.0002; - double[] coeffExpected = new double[] { 0.9448, 2.6853 }; - double[] errorsExpected = new double[] { 0.3654, 0.1487 }; - - for (int i = 0; i < 2; ++i) { - if (Math.Abs(m.standardErrors()[i] - errorsExpected[i]) > tol) { - QAssert.Fail("Failed to reproduce linear regression standard errors" - + "\n calculated: " + m.standardErrors()[i] - + "\n expected: " + errorsExpected[i] - + "\n tolerance: " + tol); - } - - if (Math.Abs(m.coefficients()[i] - coeffExpected[i]) > tol) { - QAssert.Fail("Failed to reproduce linear regression coef." - + "\n calculated: " + m.coefficients()[i] - + "\n expected: " + coeffExpected[i] - + "\n tolerance: " + tol); - } + public void test1dLinearRegression() + { + // Testing 1d simple linear least-squares regression + + /* Example taken from the QuantLib-User list, see posting + * Multiple linear regression/weighted regression, Boris Skorodumov */ + + List x = new InitializedList(9), + y = new InitializedList(9); + x[0] = 2.4; x[1] = 1.8; x[2] = 2.5; x[3] = 3.0; + x[4] = 2.1; x[5] = 1.2; x[6] = 2.0; x[7] = 2.7; x[8] = 3.6; + + y[0] = 7.8; y[1] = 5.5; y[2] = 8.0; y[3] = 9.0; + y[4] = 6.5; y[5] = 4.0; y[6] = 6.3; y[7] = 8.4; y[8] = 10.2; + + List> v = new List>(); + v.Add(a => 1.0); + v.Add(a => a); + + LinearRegression m = new LinearRegression(x, y); + + const double tol = 0.0002; + double[] coeffExpected = new double[] { 0.9448, 2.6853 }; + double[] errorsExpected = new double[] { 0.3654, 0.1487 }; + + for (int i = 0; i < 2; ++i) + { + if (Math.Abs(m.standardErrors()[i] - errorsExpected[i]) > tol) + { + QAssert.Fail("Failed to reproduce linear regression standard errors" + + "\n calculated: " + m.standardErrors()[i] + + "\n expected: " + errorsExpected[i] + + "\n tolerance: " + tol); } - } + + if (Math.Abs(m.coefficients()[i] - coeffExpected[i]) > tol) + { + QAssert.Fail("Failed to reproduce linear regression coef." + + "\n calculated: " + m.coefficients()[i] + + "\n expected: " + coeffExpected[i] + + "\n tolerance: " + tol); + } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testMultiDimRegression() - { - // Testing linear least-squares regression - const int nr=100000; - const int dims = 4; - const double tolerance = 0.01; - - var rng = new InverseCumulativeRng( - new MersenneTwisterUniformRng(1234u)); - - List> v = new List>(); - v.Add(xx => 1.0); - for (int i = 0; i < dims; ++i) { - int jj = i; // c# delegate work-around vs. boost bind; jj has to be evaluted before add delegate to the list - v.Add(vv => vv[jj]); + public void testMultiDimRegression() + { + // Testing linear least-squares regression + const int nr = 100000; + const int dims = 4; + const double tolerance = 0.01; + + var rng = new InverseCumulativeRng( + new MersenneTwisterUniformRng(1234u)); + + List> v = new List>(); + v.Add(xx => 1.0); + for (int i = 0; i < dims; ++i) + { + int jj = i; // c# delegate work-around vs. boost bind; jj has to be evaluted before add delegate to the list + v.Add(vv => vv[jj]); + } + + Vector coeff = new Vector(v.Count); + for (int i = 0; i < v.Count; ++i) + coeff[i] = rng.next().value; + + List y = new InitializedList(nr, 0.0); + List x = new InitializedList(nr); + for (int i = 0; i < nr; ++i) + { + x[i] = new Vector(dims); + for (int j = 0; j < dims; ++j) + { + x[i][j] = rng.next().value; } - Vector coeff = new Vector(v.Count); - for (int i=0; i < v.Count; ++i) - coeff[i] = rng.next().value; - - List y = new InitializedList(nr, 0.0); - List x = new InitializedList(nr); - for (int i=0; i < nr; ++i) { - x[i] = new Vector(dims); - for (int j = 0; j < dims; ++j) { - x[i][j] = rng.next().value; - } - - for (int j=0; j < v.Count; ++j) { - y[i] += coeff[j]*v[j](x[i]); - } - y[i] += rng.next().value; + for (int j = 0; j < v.Count; ++j) + { + y[i] += coeff[j] * v[j](x[i]); } - - LinearLeastSquaresRegression m = new LinearLeastSquaresRegression(x, y, v); - - for (int i=0; i < v.Count; ++i) { - if (m.standardErrors()[i] > tolerance) { - QAssert.Fail("Failed to reproduce linear regression coef." - + "\n error: " + m.standardErrors()[i] - + "\n tolerance: " + tolerance); - } - - if (Math.Abs(m.coefficients()[i]-coeff[i]) > 3*tolerance) { - QAssert.Fail("Failed to reproduce linear regression coef." - + "\n calculated: " + m.coefficients()[i] - + "\n error: " + m.standardErrors()[i] - + "\n expected: " + coeff[i]); - } + y[i] += rng.next().value; + } + + LinearLeastSquaresRegression m = new LinearLeastSquaresRegression(x, y, v); + + for (int i = 0; i < v.Count; ++i) + { + if (m.standardErrors()[i] > tolerance) + { + QAssert.Fail("Failed to reproduce linear regression coef." + + "\n error: " + m.standardErrors()[i] + + "\n tolerance: " + tolerance); + } + + if (Math.Abs(m.coefficients()[i] - coeff[i]) > 3 * tolerance) + { + QAssert.Fail("Failed to reproduce linear regression coef." + + "\n calculated: " + m.coefficients()[i] + + "\n error: " + m.standardErrors()[i] + + "\n expected: " + coeff[i]); } - } + } + } - } + } } diff --git a/tests/QLNet.Tests/T_LookbackOption.cs b/tests/QLNet.Tests/T_LookbackOption.cs index 5a8066856..4fa9d236f 100644 --- a/tests/QLNet.Tests/T_LookbackOption.cs +++ b/tests/QLNet.Tests/T_LookbackOption.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -17,32 +17,32 @@ #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; namespace TestSuite { - #if NET40 || NET45 +#if NET40 || NET45 [TestClass()] - #endif +#endif public class T_LookbackOption { - void REPORT_FAILURE_FLOATING( string greekName, - double minmax, - FloatingTypePayoff payoff, - Exercise exercise, - double s, - double q, - double r, - Date today, - double v, - double expected, - double calculated, - double error, - double tolerance ) + void REPORT_FAILURE_FLOATING(string greekName, + double minmax, + FloatingTypePayoff payoff, + Exercise exercise, + double s, + double q, + double r, + Date today, + double v, + double expected, + double calculated, + double error, + double tolerance) { - QAssert.Fail( exercise.GetType() + " " + QAssert.Fail(exercise.GetType() + " " + payoff.optionType() + " lookback option with " + payoff + " payoff:\n" + " underlying value " + s + "\n" @@ -54,24 +54,24 @@ void REPORT_FAILURE_FLOATING( string greekName, + " expected " + greekName + ": " + expected + "\n" + " calculated " + greekName + ": " + calculated + "\n" + " error: " + error + "\n" - + " tolerance: " + tolerance ); + + " tolerance: " + tolerance); } - void REPORT_FAILURE_FIXED( string greekName, - double minmax, - StrikedTypePayoff payoff, - Exercise exercise, - double s, - double q, - double r, - Date today, - double v, - double expected, - double calculated, - double error, - double tolerance ) + void REPORT_FAILURE_FIXED(string greekName, + double minmax, + StrikedTypePayoff payoff, + Exercise exercise, + double s, + double q, + double r, + Date today, + double v, + double expected, + double calculated, + double error, + double tolerance) { - QAssert.Fail( exercise.GetType() + " " + QAssert.Fail(exercise.GetType() + " " + payoff.optionType() + " lookback option with " + payoff + " payoff:\n" + " underlying value " + s + "\n" @@ -84,13 +84,13 @@ void REPORT_FAILURE_FIXED( string greekName, + " expected " + greekName + ": " + expected + "\n" + " calculated " + greekName + ": " + calculated + "\n" + " error: " + error + "\n" - + " tolerance: " + tolerance ); + + " tolerance: " + tolerance); } class LookbackOptionData { - public LookbackOptionData(Option.Type type_,double strike_,double minmax_,double s_,double q_,double r_, - double t_,double v_,double l_,double t1_,double result_,double tol_) + public LookbackOptionData(Option.Type type_, double strike_, double minmax_, double s_, double q_, double r_, + double t_, double v_, double l_, double t1_, double result_, double tol_) { type = type_; strike = strike_; @@ -122,12 +122,12 @@ public LookbackOptionData(Option.Type type_,double strike_,double minmax_,double public double tol; // tolerance } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testAnalyticContinuousFloatingLookback() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testAnalyticContinuousFloatingLookback() { // Testing analytic continuous floating-strike lookback options LookbackOptionData[] values = @@ -155,9 +155,9 @@ public void testAnalyticContinuousFloatingLookback() SimpleQuote vol = new SimpleQuote(0.0); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - for (int i=0; ivalues[i].tol) { + double error = Math.Abs(calculated - expected); + if (error > values[i].tol) + { REPORT_FAILURE_FLOATING("value", values[i].minmax, payoff, exercise, values[i].s, values[i].q, values[i].r, today, values[i].v, @@ -193,55 +194,55 @@ public void testAnalyticContinuousFloatingLookback() } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testAnalyticContinuousFixedLookback() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testAnalyticContinuousFixedLookback() { // Testing analytic continuous fixed-strike lookback options - LookbackOptionData[] values = + LookbackOptionData[] values = { // data from "Option Pricing Formulas", Haug, 1998, pg.63-64 //type, strike, minmax, s, q, r, t, v, l, t1, result, tol - new LookbackOptionData( Option.Type.Call, 95, 100, 100.0, 0.00, 0.10, 0.50, 0.10, 0, 0, 13.2687, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 95, 100, 100.0, 0.00, 0.10, 0.50, 0.20, 0, 0, 18.9263, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 95, 100, 100.0, 0.00, 0.10, 0.50, 0.30, 0, 0, 24.9857, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 100, 100, 100.0, 0.00, 0.10, 0.50, 0.10, 0, 0, 8.5126, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 100, 100, 100.0, 0.00, 0.10, 0.50, 0.20, 0, 0, 14.1702, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 100, 100, 100.0, 0.00, 0.10, 0.50, 0.30, 0, 0, 20.2296, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 105, 100, 100.0, 0.00, 0.10, 0.50, 0.10, 0, 0, 4.3908, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 105, 100, 100.0, 0.00, 0.10, 0.50, 0.20, 0, 0, 9.8905, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 105, 100, 100.0, 0.00, 0.10, 0.50, 0.30, 0, 0, 15.8512, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 95, 100, 100.0, 0.00, 0.10, 1.00, 0.10, 0, 0, 18.3241, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 95, 100, 100.0, 0.00, 0.10, 1.00, 0.20, 0, 0, 26.0731, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 95, 100, 100.0, 0.00, 0.10, 1.00, 0.30, 0, 0, 34.7116, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 100, 100, 100.0, 0.00, 0.10, 1.00, 0.10, 0, 0, 13.8000, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 100, 100, 100.0, 0.00, 0.10, 1.00, 0.20, 0, 0, 21.5489, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 100, 100, 100.0, 0.00, 0.10, 1.00, 0.30, 0, 0, 30.1874, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 105, 100, 100.0, 0.00, 0.10, 1.00, 0.10, 0, 0, 9.5445, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 105, 100, 100.0, 0.00, 0.10, 1.00, 0.20, 0, 0, 17.2965, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 105, 100, 100.0, 0.00, 0.10, 1.00, 0.30, 0, 0, 25.9002, 1.0e-4), - - new LookbackOptionData( Option.Type.Put, 95, 100, 100.0, 0.00, 0.10, 0.50, 0.10, 0, 0, 0.6899, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 95, 100, 100.0, 0.00, 0.10, 0.50, 0.20, 0, 0, 4.4448, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 95, 100, 100.0, 0.00, 0.10, 0.50, 0.30, 0, 0, 8.9213, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 100, 100, 100.0, 0.00, 0.10, 0.50, 0.10, 0, 0, 3.3917, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 100, 100, 100.0, 0.00, 0.10, 0.50, 0.20, 0, 0, 8.3177, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 100, 100, 100.0, 0.00, 0.10, 0.50, 0.30, 0, 0, 13.1579, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 105, 100, 100.0, 0.00, 0.10, 0.50, 0.10, 0, 0, 8.1478, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 105, 100, 100.0, 0.00, 0.10, 0.50, 0.20, 0, 0, 13.0739, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 105, 100, 100.0, 0.00, 0.10, 0.50, 0.30, 0, 0, 17.9140, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 95, 100, 100.0, 0.00, 0.10, 1.00, 0.10, 0, 0, 1.0534, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 95, 100, 100.0, 0.00, 0.10, 1.00, 0.20, 0, 0, 6.2813, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 95, 100, 100.0, 0.00, 0.10, 1.00, 0.30, 0, 0, 12.2376, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 100, 100, 100.0, 0.00, 0.10, 1.00, 0.10, 0, 0, 3.8079, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 100, 100, 100.0, 0.00, 0.10, 1.00, 0.20, 0, 0, 10.1294, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 100, 100, 100.0, 0.00, 0.10, 1.00, 0.30, 0, 0, 16.3889, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 105, 100, 100.0, 0.00, 0.10, 1.00, 0.10, 0, 0, 8.3321, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 105, 100, 100.0, 0.00, 0.10, 1.00, 0.20, 0, 0, 14.6536, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 105, 100, 100.0, 0.00, 0.10, 1.00, 0.30, 0, 0, 20.9130, 1.0e-4) + new LookbackOptionData(Option.Type.Call, 95, 100, 100.0, 0.00, 0.10, 0.50, 0.10, 0, 0, 13.2687, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 95, 100, 100.0, 0.00, 0.10, 0.50, 0.20, 0, 0, 18.9263, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 95, 100, 100.0, 0.00, 0.10, 0.50, 0.30, 0, 0, 24.9857, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 100, 100, 100.0, 0.00, 0.10, 0.50, 0.10, 0, 0, 8.5126, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 100, 100, 100.0, 0.00, 0.10, 0.50, 0.20, 0, 0, 14.1702, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 100, 100, 100.0, 0.00, 0.10, 0.50, 0.30, 0, 0, 20.2296, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 105, 100, 100.0, 0.00, 0.10, 0.50, 0.10, 0, 0, 4.3908, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 105, 100, 100.0, 0.00, 0.10, 0.50, 0.20, 0, 0, 9.8905, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 105, 100, 100.0, 0.00, 0.10, 0.50, 0.30, 0, 0, 15.8512, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 95, 100, 100.0, 0.00, 0.10, 1.00, 0.10, 0, 0, 18.3241, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 95, 100, 100.0, 0.00, 0.10, 1.00, 0.20, 0, 0, 26.0731, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 95, 100, 100.0, 0.00, 0.10, 1.00, 0.30, 0, 0, 34.7116, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 100, 100, 100.0, 0.00, 0.10, 1.00, 0.10, 0, 0, 13.8000, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 100, 100, 100.0, 0.00, 0.10, 1.00, 0.20, 0, 0, 21.5489, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 100, 100, 100.0, 0.00, 0.10, 1.00, 0.30, 0, 0, 30.1874, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 105, 100, 100.0, 0.00, 0.10, 1.00, 0.10, 0, 0, 9.5445, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 105, 100, 100.0, 0.00, 0.10, 1.00, 0.20, 0, 0, 17.2965, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 105, 100, 100.0, 0.00, 0.10, 1.00, 0.30, 0, 0, 25.9002, 1.0e-4), + + new LookbackOptionData(Option.Type.Put, 95, 100, 100.0, 0.00, 0.10, 0.50, 0.10, 0, 0, 0.6899, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 95, 100, 100.0, 0.00, 0.10, 0.50, 0.20, 0, 0, 4.4448, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 95, 100, 100.0, 0.00, 0.10, 0.50, 0.30, 0, 0, 8.9213, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 100, 100, 100.0, 0.00, 0.10, 0.50, 0.10, 0, 0, 3.3917, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 100, 100, 100.0, 0.00, 0.10, 0.50, 0.20, 0, 0, 8.3177, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 100, 100, 100.0, 0.00, 0.10, 0.50, 0.30, 0, 0, 13.1579, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 105, 100, 100.0, 0.00, 0.10, 0.50, 0.10, 0, 0, 8.1478, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 105, 100, 100.0, 0.00, 0.10, 0.50, 0.20, 0, 0, 13.0739, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 105, 100, 100.0, 0.00, 0.10, 0.50, 0.30, 0, 0, 17.9140, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 95, 100, 100.0, 0.00, 0.10, 1.00, 0.10, 0, 0, 1.0534, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 95, 100, 100.0, 0.00, 0.10, 1.00, 0.20, 0, 0, 6.2813, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 95, 100, 100.0, 0.00, 0.10, 1.00, 0.30, 0, 0, 12.2376, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 100, 100, 100.0, 0.00, 0.10, 1.00, 0.10, 0, 0, 3.8079, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 100, 100, 100.0, 0.00, 0.10, 1.00, 0.20, 0, 0, 10.1294, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 100, 100, 100.0, 0.00, 0.10, 1.00, 0.30, 0, 0, 16.3889, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 105, 100, 100.0, 0.00, 0.10, 1.00, 0.10, 0, 0, 8.3321, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 105, 100, 100.0, 0.00, 0.10, 1.00, 0.20, 0, 0, 14.6536, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 105, 100, 100.0, 0.00, 0.10, 1.00, 0.30, 0, 0, 20.9130, 1.0e-4) }; @@ -256,9 +257,9 @@ public void testAnalyticContinuousFixedLookback() SimpleQuote vol = new SimpleQuote(0.0); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - for (int i=0; ivalues[i].tol) + double error = Math.Abs(calculated - expected); + if (error > values[i].tol) { REPORT_FAILURE_FIXED("value", values[i].minmax, payoff, exercise, values[i].s, values[i].q, values[i].r, today, @@ -291,18 +292,18 @@ public void testAnalyticContinuousFixedLookback() values[i].tol); } } - + } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testAnalyticContinuousPartialFloatingLookback() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testAnalyticContinuousPartialFloatingLookback() { // Testing analytic continuous partial floating-strike lookback options..."); - LookbackOptionData[] values = + LookbackOptionData[] values = { // data from "Option Pricing Formulas, Second Edition", Haug, 2006, pg.146 @@ -356,9 +357,9 @@ public void testAnalyticContinuousPartialFloatingLookback() SimpleQuote vol = new SimpleQuote(0.0); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - for (int i=0; ivalues[i].tol) + double error = Math.Abs(calculated - expected); + if (error > values[i].tol) { REPORT_FAILURE_FLOATING("value", values[i].minmax, payoff, exercise, values[i].s, values[i].q, @@ -395,54 +396,54 @@ public void testAnalyticContinuousPartialFloatingLookback() } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testAnalyticContinuousPartialFixedLookback() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testAnalyticContinuousPartialFixedLookback() { // Testing analytic continuous fixed-strike lookback options - LookbackOptionData[] values = + LookbackOptionData[] values = { // data from "Option Pricing Formulas, Second Edition", Haug, 2006, pg.148 //type, strike, minmax, s, q, r, t, v, l, t1, result, tol - new LookbackOptionData( Option.Type.Call, 90, 0, 100, 0, 0.06, 1, 0.1, 0, 0.25, 20.2845, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 90, 0, 100, 0, 0.06, 1, 0.1, 0, 0.5, 19.6239, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 90, 0, 100, 0, 0.06, 1, 0.1, 0, 0.75, 18.6244, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 110, 0, 100, 0, 0.06, 1, 0.1, 0, 0.25, 4.0432, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 110, 0, 100, 0, 0.06, 1, 0.1, 0, 0.5, 3.958, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 110, 0, 100, 0, 0.06, 1, 0.1, 0, 0.75, 3.7015, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 90, 0, 100, 0, 0.06, 1, 0.2, 0, 0.25, 27.5385, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 90, 0, 100, 0, 0.06, 1, 0.2, 0, 0.5, 25.8126, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 90, 0, 100, 0, 0.06, 1, 0.2, 0, 0.75, 23.4957, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 110, 0, 100, 0, 0.06, 1, 0.2, 0, 0.25, 11.4895, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 110, 0, 100, 0, 0.06, 1, 0.2, 0, 0.5, 10.8995, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 110, 0, 100, 0, 0.06, 1, 0.2, 0, 0.75, 9.8244, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 90, 0, 100, 0, 0.06, 1, 0.3, 0, 0.25, 35.4578, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 90, 0, 100, 0, 0.06, 1, 0.3, 0, 0.5, 32.7172, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 90, 0, 100, 0, 0.06, 1, 0.3, 0, 0.75, 29.1473, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 110, 0, 100, 0, 0.06, 1, 0.3, 0, 0.25, 19.725, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 110, 0, 100, 0, 0.06, 1, 0.3, 0, 0.5, 18.4025, 1.0e-4), - new LookbackOptionData( Option.Type.Call, 110, 0, 100, 0, 0.06, 1, 0.3, 0, 0.75, 16.2976, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 90, 0, 100, 0, 0.06, 1, 0.1, 0, 0.25, 0.4973, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 90, 0, 100, 0, 0.06, 1, 0.1, 0, 0.5, 0.4632, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 90, 0, 100, 0, 0.06, 1, 0.1, 0, 0.75, 0.3863, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 110, 0, 100, 0, 0.06, 1, 0.1, 0, 0.25, 12.6978, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 110, 0, 100, 0, 0.06, 1, 0.1, 0, 0.5, 10.9492, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 110, 0, 100, 0, 0.06, 1, 0.1, 0, 0.75, 9.1555, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 90, 0, 100, 0, 0.06, 1, 0.2, 0, 0.25, 4.5863, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 90, 0, 100, 0, 0.06, 1, 0.2, 0, 0.5, 4.1925, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 90, 0, 100, 0, 0.06, 1, 0.2, 0, 0.75, 3.5831, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 110, 0, 100, 0, 0.06, 1, 0.2, 0, 0.25, 19.0255, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 110, 0, 100, 0, 0.06, 1, 0.2, 0, 0.5, 16.9433, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 110, 0, 100, 0, 0.06, 1, 0.2, 0, 0.75, 14.6505, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 90, 0, 100, 0, 0.06, 1, 0.3, 0, 0.25, 9.9348, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 90, 0, 100, 0, 0.06, 1, 0.3, 0, 0.5, 9.1111, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 90, 0, 100, 0, 0.06, 1, 0.3, 0, 0.75, 7.9267, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 110, 0, 100, 0, 0.06, 1, 0.3, 0, 0.25, 25.2112, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 110, 0, 100, 0, 0.06, 1, 0.3, 0, 0.5, 22.8217, 1.0e-4), - new LookbackOptionData( Option.Type.Put, 110, 0, 100, 0, 0.06, 1, 0.3, 0, 0.75, 20.0566, 1.0e-4) + new LookbackOptionData(Option.Type.Call, 90, 0, 100, 0, 0.06, 1, 0.1, 0, 0.25, 20.2845, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 90, 0, 100, 0, 0.06, 1, 0.1, 0, 0.5, 19.6239, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 90, 0, 100, 0, 0.06, 1, 0.1, 0, 0.75, 18.6244, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 110, 0, 100, 0, 0.06, 1, 0.1, 0, 0.25, 4.0432, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 110, 0, 100, 0, 0.06, 1, 0.1, 0, 0.5, 3.958, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 110, 0, 100, 0, 0.06, 1, 0.1, 0, 0.75, 3.7015, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 90, 0, 100, 0, 0.06, 1, 0.2, 0, 0.25, 27.5385, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 90, 0, 100, 0, 0.06, 1, 0.2, 0, 0.5, 25.8126, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 90, 0, 100, 0, 0.06, 1, 0.2, 0, 0.75, 23.4957, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 110, 0, 100, 0, 0.06, 1, 0.2, 0, 0.25, 11.4895, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 110, 0, 100, 0, 0.06, 1, 0.2, 0, 0.5, 10.8995, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 110, 0, 100, 0, 0.06, 1, 0.2, 0, 0.75, 9.8244, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 90, 0, 100, 0, 0.06, 1, 0.3, 0, 0.25, 35.4578, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 90, 0, 100, 0, 0.06, 1, 0.3, 0, 0.5, 32.7172, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 90, 0, 100, 0, 0.06, 1, 0.3, 0, 0.75, 29.1473, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 110, 0, 100, 0, 0.06, 1, 0.3, 0, 0.25, 19.725, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 110, 0, 100, 0, 0.06, 1, 0.3, 0, 0.5, 18.4025, 1.0e-4), + new LookbackOptionData(Option.Type.Call, 110, 0, 100, 0, 0.06, 1, 0.3, 0, 0.75, 16.2976, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 90, 0, 100, 0, 0.06, 1, 0.1, 0, 0.25, 0.4973, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 90, 0, 100, 0, 0.06, 1, 0.1, 0, 0.5, 0.4632, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 90, 0, 100, 0, 0.06, 1, 0.1, 0, 0.75, 0.3863, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 110, 0, 100, 0, 0.06, 1, 0.1, 0, 0.25, 12.6978, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 110, 0, 100, 0, 0.06, 1, 0.1, 0, 0.5, 10.9492, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 110, 0, 100, 0, 0.06, 1, 0.1, 0, 0.75, 9.1555, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 90, 0, 100, 0, 0.06, 1, 0.2, 0, 0.25, 4.5863, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 90, 0, 100, 0, 0.06, 1, 0.2, 0, 0.5, 4.1925, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 90, 0, 100, 0, 0.06, 1, 0.2, 0, 0.75, 3.5831, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 110, 0, 100, 0, 0.06, 1, 0.2, 0, 0.25, 19.0255, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 110, 0, 100, 0, 0.06, 1, 0.2, 0, 0.5, 16.9433, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 110, 0, 100, 0, 0.06, 1, 0.2, 0, 0.75, 14.6505, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 90, 0, 100, 0, 0.06, 1, 0.3, 0, 0.25, 9.9348, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 90, 0, 100, 0, 0.06, 1, 0.3, 0, 0.5, 9.1111, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 90, 0, 100, 0, 0.06, 1, 0.3, 0, 0.75, 7.9267, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 110, 0, 100, 0, 0.06, 1, 0.3, 0, 0.25, 25.2112, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 110, 0, 100, 0, 0.06, 1, 0.3, 0, 0.5, 22.8217, 1.0e-4), + new LookbackOptionData(Option.Type.Put, 110, 0, 100, 0, 0.06, 1, 0.3, 0, 0.75, 20.0566, 1.0e-4) }; DayCounter dc = new Actual360(); @@ -456,9 +457,9 @@ public void testAnalyticContinuousPartialFixedLookback() SimpleQuote vol = new SimpleQuote(0.0); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - for (int i=0; ivalues[i].tol) + double error = Math.Abs(calculated - expected); + if (error > values[i].tol) { REPORT_FAILURE_FIXED("value", values[i].minmax, payoff, exercise, values[i].s, values[i].q, values[i].r, today, diff --git a/tests/QLNet.Tests/T_LowDiscrepancySequences.cs b/tests/QLNet.Tests/T_LowDiscrepancySequences.cs index 6f99d7b26..4b2349ed5 100644 --- a/tests/QLNet.Tests/T_LowDiscrepancySequences.cs +++ b/tests/QLNet.Tests/T_LowDiscrepancySequences.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,7 +22,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -51,7 +51,7 @@ public string name() return "Mersenne Twister"; } - }; + } public class SobolFactory : IRNGFactory { @@ -102,7 +102,7 @@ public string name() } private SobolRsg.DirectionIntegers unit_; - }; + } public class HaltonFactory : IRNGFactory { @@ -128,7 +128,7 @@ public string name() } private bool start_, shift_; - }; + } #endregion @@ -145,9 +145,9 @@ public void testSeedGenerator() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testPolynomialsModuloTwo() { @@ -179,7 +179,7 @@ public void testPolynomialsModuloTwo() if (j != jj[i]) { QAssert.Fail("Only " + j + " polynomials in degree " + i + 1 - + " instead of " + jj[i]); + + " instead of " + jj[i]); } } ++j; // Increase index of polynomial in degree i+1 @@ -189,9 +189,9 @@ public void testPolynomialsModuloTwo() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testSobol() { @@ -213,8 +213,8 @@ public void testSobol() if (point.Count != dimensionality) { QAssert.Fail("Sobol sequence generator returns " + - " a sequence of wrong dimensionality: " + point.Count - + " instead of " + dimensionality); + " a sequence of wrong dimensionality: " + point.Count + + " instead of " + dimensionality); } } @@ -228,7 +228,7 @@ public void testSobol() for (int j = 1; j < 5; j++) { // five cycle - points = (int) (Utils.Pow(2.0, j) - 1); // base 2 + points = (int)(Utils.Pow(2.0, j) - 1); // base 2 for (; k < points; k++) { point = rsg.nextSequence().value; @@ -241,12 +241,12 @@ public void testSobol() if (error > tolerance) { QAssert.Fail(i + 1 + " dimension: " - // + QL_FIXED - + "mean (" + mean[i] - + ") at the end of the " + j + 1 - + " cycle in Sobol sequence is not " + 0.5 - //+ QL_SCIENTIFIC - + " (error = " + error + ")"); + // + QL_FIXED + + "mean (" + mean[i] + + ") at the end of the " + j + 1 + + " cycle in Sobol sequence is not " + 0.5 + //+ QL_SCIENTIFIC + + " (error = " + error + ")"); } } } @@ -269,7 +269,7 @@ public void testSobol() dimensionality = 1; rsg = new SobolRsg(dimensionality); - points = (int) (Utils.Pow(2.0, 5)) - 1; // five cycles + points = (int)(Utils.Pow(2.0, 5)) - 1; // five cycles for (i = 0; i < points; i++) { point = rsg.nextSequence().value; @@ -277,171 +277,171 @@ public void testSobol() if (error > tolerance) { QAssert.Fail(i + 1 + " draw (" - //+ QL_FIXED - + point[0] - + ") in 1-D Sobol sequence is not in the " - + "van der Corput sequence modulo two: " - + "it should have been " - + vanderCorputSequenceModuloTwo[i] - //+ QL_SCIENTIFIC - + " (error = " + error + ")"); + //+ QL_FIXED + + point[0] + + ") in 1-D Sobol sequence is not in the " + + "van der Corput sequence modulo two: " + + "it should have been " + + vanderCorputSequenceModuloTwo[i] + //+ QL_SCIENTIFIC + + " (error = " + error + ")"); } } } -/*public void testFaure() { - - //("Testing Faure sequences..."); - - List point; - double tolerance = 1.0e-15; - - // testing "high" dimensionality - int dimensionality = PPMT_MAX_DIM; - FaureRsg rsg(dimensionality); - int points = 100, i; - for (i=0; i tolerance) { - QAssert.Fail(io::ordinal(i+1) + " draw, dimension 1 (" - + QL_FIXED + point[0] - + ") in 3-D Faure sequence should have been " - + vanderCorputSequenceModuloTwo[i] - + QL_SCIENTIFIC - + " (error = " + error + ")"); - } - } - - // 2nd dimension of the 2-dimensional Faure sequence - // (shuffled van der Corput sequence base 2) - // checked with the code provided with "Economic generation of - // low-discrepancy sequences with a b-ary gray code", by E. Thiemard - double FaureDimensionTwoOfTwo[] = { - // first cycle (zero excluded) - 0.50000, - // second cycle - 0.25000, 0.75000, - // third cycle - 0.37500, 0.87500, 0.12500, 0.62500, - // fourth cycle - 0.31250, 0.81250, 0.06250, 0.56250, 0.18750, 0.68750, 0.43750, 0.93750, - // fifth cycle - 0.46875, 0.96875, 0.21875, 0.71875, 0.09375, 0.59375, 0.34375, 0.84375, - 0.15625, 0.65625, 0.40625, 0.90625, 0.28125, 0.78125, 0.03125, 0.53125 - }; - dimensionality = 2; - rsg = FaureRsg(dimensionality); - points = int(std::pow(2.0, 5))-1; // five cycles - for (i=0; i tolerance) { - QAssert.Fail(io::ordinal(i+1) + " draw, dimension 1 (" - + QL_FIXED + point[0] - + ") in 3-D Faure sequence should have been " - + vanderCorputSequenceModuloTwo[i] - + QL_SCIENTIFIC - + " (error = " + error + ")"); - } - error = std::fabs(point[1]-FaureDimensionTwoOfTwo[i]); - if (error > tolerance) { - QAssert.Fail(io::ordinal(i+1) + " draw, dimension 2 (" - + QL_FIXED + point[1] - + ") in 3-D Faure sequence should have been " - + FaureDimensionTwoOfTwo[i] - + QL_SCIENTIFIC - + " (error = " + error + ")"); - } - } - - // 3-dimension Faure sequence (shuffled van der Corput sequence base 3) - // see "Monte Carlo Methods in Financial Engineering," - // by Paul Glasserman, 2004 Springer Verlag, pag. 299 - double FaureDimensionOneOfThree[] = { - // first cycle (zero excluded) - 1.0/3, 2.0/3, - // second cycle - 7.0/9, 1.0/9, 4.0/9, 5.0/9, 8.0/9, 2.0/9 - }; - double FaureDimensionTwoOfThree[] = { - // first cycle (zero excluded) - 1.0/3, 2.0/3, - // second cycle - 1.0/9, 4.0/9, 7.0/9, 2.0/9, 5.0/9, 8.0/9 - }; - double FaureDimensionThreeOfThree[] = { - // first cycle (zero excluded) - 1.0/3, 2.0/3, - // second cycle - 4.0/9, 7.0/9, 1.0/9, 8.0/9, 2.0/9, 5.0/9 - }; - - dimensionality = 3; - rsg = FaureRsg(dimensionality); - points = int(std::pow(3.0, 2))-1; // three cycles - for (i=0; i tolerance) { - QAssert.Fail(io::ordinal(i+1) + " draw, dimension 1 (" - + QL_FIXED + point[0] - + ") in 3-D Faure sequence should have been " - + FaureDimensionOneOfThree[i] - + QL_SCIENTIFIC - + " (error = " + error + ")"); - } - error = std::fabs(point[1]-FaureDimensionTwoOfThree[i]); - if (error > tolerance) { - QAssert.Fail(io::ordinal(i+1) + " draw, dimension 2 (" - + QL_FIXED + point[1] - + ") in 3-D Faure sequence should have been " - + FaureDimensionTwoOfThree[i] - + QL_SCIENTIFIC - + " (error = " + error + ")"); - } - error = std::fabs(point[2]-FaureDimensionThreeOfThree[i]); - if (error > tolerance) { - QAssert.Fail(io::ordinal(i+1) + " draw, dimension 3 (" - + QL_FIXED + point[2] - + ") in 3-D Faure sequence should have been " - + FaureDimensionThreeOfThree[i] - + QL_SCIENTIFIC - + " (error = " + error + ")"); - } - } -}*/ + /*public void testFaure() { + + //("Testing Faure sequences..."); + + List point; + double tolerance = 1.0e-15; + + // testing "high" dimensionality + int dimensionality = PPMT_MAX_DIM; + FaureRsg rsg(dimensionality); + int points = 100, i; + for (i=0; i tolerance) { + QAssert.Fail(io::ordinal(i+1) + " draw, dimension 1 (" + + QL_FIXED + point[0] + + ") in 3-D Faure sequence should have been " + + vanderCorputSequenceModuloTwo[i] + + QL_SCIENTIFIC + + " (error = " + error + ")"); + } + } + + // 2nd dimension of the 2-dimensional Faure sequence + // (shuffled van der Corput sequence base 2) + // checked with the code provided with "Economic generation of + // low-discrepancy sequences with a b-ary gray code", by E. Thiemard + double FaureDimensionTwoOfTwo[] = { + // first cycle (zero excluded) + 0.50000, + // second cycle + 0.25000, 0.75000, + // third cycle + 0.37500, 0.87500, 0.12500, 0.62500, + // fourth cycle + 0.31250, 0.81250, 0.06250, 0.56250, 0.18750, 0.68750, 0.43750, 0.93750, + // fifth cycle + 0.46875, 0.96875, 0.21875, 0.71875, 0.09375, 0.59375, 0.34375, 0.84375, + 0.15625, 0.65625, 0.40625, 0.90625, 0.28125, 0.78125, 0.03125, 0.53125 + }; + dimensionality = 2; + rsg = FaureRsg(dimensionality); + points = int(std::pow(2.0, 5))-1; // five cycles + for (i=0; i tolerance) { + QAssert.Fail(io::ordinal(i+1) + " draw, dimension 1 (" + + QL_FIXED + point[0] + + ") in 3-D Faure sequence should have been " + + vanderCorputSequenceModuloTwo[i] + + QL_SCIENTIFIC + + " (error = " + error + ")"); + } + error = std::fabs(point[1]-FaureDimensionTwoOfTwo[i]); + if (error > tolerance) { + QAssert.Fail(io::ordinal(i+1) + " draw, dimension 2 (" + + QL_FIXED + point[1] + + ") in 3-D Faure sequence should have been " + + FaureDimensionTwoOfTwo[i] + + QL_SCIENTIFIC + + " (error = " + error + ")"); + } + } + + // 3-dimension Faure sequence (shuffled van der Corput sequence base 3) + // see "Monte Carlo Methods in Financial Engineering," + // by Paul Glasserman, 2004 Springer Verlag, pag. 299 + double FaureDimensionOneOfThree[] = { + // first cycle (zero excluded) + 1.0/3, 2.0/3, + // second cycle + 7.0/9, 1.0/9, 4.0/9, 5.0/9, 8.0/9, 2.0/9 + }; + double FaureDimensionTwoOfThree[] = { + // first cycle (zero excluded) + 1.0/3, 2.0/3, + // second cycle + 1.0/9, 4.0/9, 7.0/9, 2.0/9, 5.0/9, 8.0/9 + }; + double FaureDimensionThreeOfThree[] = { + // first cycle (zero excluded) + 1.0/3, 2.0/3, + // second cycle + 4.0/9, 7.0/9, 1.0/9, 8.0/9, 2.0/9, 5.0/9 + }; + + dimensionality = 3; + rsg = FaureRsg(dimensionality); + points = int(std::pow(3.0, 2))-1; // three cycles + for (i=0; i tolerance) { + QAssert.Fail(io::ordinal(i+1) + " draw, dimension 1 (" + + QL_FIXED + point[0] + + ") in 3-D Faure sequence should have been " + + FaureDimensionOneOfThree[i] + + QL_SCIENTIFIC + + " (error = " + error + ")"); + } + error = std::fabs(point[1]-FaureDimensionTwoOfThree[i]); + if (error > tolerance) { + QAssert.Fail(io::ordinal(i+1) + " draw, dimension 2 (" + + QL_FIXED + point[1] + + ") in 3-D Faure sequence should have been " + + FaureDimensionTwoOfThree[i] + + QL_SCIENTIFIC + + " (error = " + error + ")"); + } + error = std::fabs(point[2]-FaureDimensionThreeOfThree[i]); + if (error > tolerance) { + QAssert.Fail(io::ordinal(i+1) + " draw, dimension 3 (" + + QL_FIXED + point[2] + + ") in 3-D Faure sequence should have been " + + FaureDimensionThreeOfThree[i] + + QL_SCIENTIFIC + + " (error = " + error + ")"); + } + } + }*/ #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testHalton() { @@ -461,9 +461,9 @@ public void testHalton() if (point.Count != dimensionality) { QAssert.Fail("Halton sequence generator returns " + - " a sequence of wrong dimensionality: " + point.Count - + " instead of " + dimensionality) - ; + " a sequence of wrong dimensionality: " + point.Count + + " instead of " + dimensionality) + ; } } @@ -488,7 +488,7 @@ public void testHalton() dimensionality = 1; rsg = new HaltonRsg(dimensionality, 0, false, false); - points = (int) (Math.Pow(2.0, 5)) - 1; // five cycles + points = (int)(Math.Pow(2.0, 5)) - 1; // five cycles for (i = 0; i < points; i++) { point = rsg.nextSequence().value; @@ -496,31 +496,31 @@ public void testHalton() if (error > tolerance) { QAssert.Fail(i + 1 + " draw (" - + /*QL_FIXED*/ +point[0] - + ") in 1-D Halton sequence is not in the " - + "van der Corput sequence modulo two: " - + "it should have been " - + vanderCorputSequenceModuloTwo[i] - //+ QL_SCIENTIFIC - + " (error = " + error + ")"); + + /*QL_FIXED*/ +point[0] + + ") in 1-D Halton sequence is not in the " + + "van der Corput sequence modulo two: " + + "it should have been " + + vanderCorputSequenceModuloTwo[i] + //+ QL_SCIENTIFIC + + " (error = " + error + ")"); } } double[] vanderCorputSequenceModuloThree = { // first cycle (zero excluded) - 1.0/3, 2.0/3, + 1.0 / 3, 2.0 / 3, // second cycle - 1.0/9, 4.0/9, 7.0/9, 2.0/9, 5.0/9, 8.0/9, + 1.0 / 9, 4.0 / 9, 7.0 / 9, 2.0 / 9, 5.0 / 9, 8.0 / 9, // third cycle - 1.0/27, 10.0/27, 19.0/27, 4.0/27, 13.0/27, 22.0/27, - 7.0/27, 16.0/27, 25.0/27, 2.0/27, 11.0/27, 20.0/27, - 5.0/27, 14.0/27, 23.0/27, 8.0/27, 17.0/27, 26.0/27 + 1.0 / 27, 10.0 / 27, 19.0 / 27, 4.0 / 27, 13.0 / 27, 22.0 / 27, + 7.0 / 27, 16.0 / 27, 25.0 / 27, 2.0 / 27, 11.0 / 27, 20.0 / 27, + 5.0 / 27, 14.0 / 27, 23.0 / 27, 8.0 / 27, 17.0 / 27, 26.0 / 27 }; dimensionality = 2; rsg = new HaltonRsg(dimensionality, 0, false, false); - points = (int) (Math.Pow(3.0, 3)) - 1; // three cycles of the higher dimension + points = (int)(Math.Pow(3.0, 3)) - 1; // three cycles of the higher dimension for (i = 0; i < points; i++) { point = rsg.nextSequence().value; @@ -528,25 +528,25 @@ public void testHalton() if (error > tolerance) { QAssert.Fail("First component of " + i + 1 - + " draw (" + /*QL_FIXED*/ +point[0] - + ") in 2-D Halton sequence is not in the " - + "van der Corput sequence modulo two: " - + "it should have been " - + vanderCorputSequenceModuloTwo[i] - //+ QL_SCIENTIFIC - + " (error = " + error + ")"); + + " draw (" + /*QL_FIXED*/ +point[0] + + ") in 2-D Halton sequence is not in the " + + "van der Corput sequence modulo two: " + + "it should have been " + + vanderCorputSequenceModuloTwo[i] + //+ QL_SCIENTIFIC + + " (error = " + error + ")"); } error = Math.Abs(point[1] - vanderCorputSequenceModuloThree[i]); if (error > tolerance) { QAssert.Fail("Second component of " + i + 1 - + " draw (" + /*QL_FIXED*/ +point[1] - + ") in 2-D Halton sequence is not in the " - + "van der Corput sequence modulo three: " - + "it should have been " - + vanderCorputSequenceModuloThree[i] - //+ QL_SCIENTIFIC - + " (error = " + error + ")"); + + " draw (" + /*QL_FIXED*/ +point[1] + + ") in 2-D Halton sequence is not in the " + + "van der Corput sequence modulo three: " + + "it should have been " + + vanderCorputSequenceModuloThree[i] + //+ QL_SCIENTIFIC + + " (error = " + error + ")"); } } @@ -560,7 +560,7 @@ public void testHalton() for (j = 1; j < 5; j++) { // five cycle - points = (int) (Math.Pow(2.0, j)) - 1; // base 2 + points = (int)(Math.Pow(2.0, j)) - 1; // base 2 for (; k < points; k++) { point = rsg.nextSequence().value; @@ -571,10 +571,10 @@ public void testHalton() if (error > tolerance) { QAssert.Fail("First dimension mean (" + /*QL_FIXED*/ +mean[0] - + ") at the end of the " + j + 1 - + " cycle in Halton sequence is not " + 0.5 - //+ QL_SCIENTIFIC - + " (error = " + error + ")"); + + ") at the end of the " + j + 1 + + " cycle in Halton sequence is not " + 0.5 + //+ QL_SCIENTIFIC + + " (error = " + error + ")"); } } @@ -585,7 +585,7 @@ public void testHalton() for (j = 1; j < 3; j++) { // three cycle - points = (int) (Math.Pow(3.0, j)) - 1; // base 3 + points = (int)(Math.Pow(3.0, j)) - 1; // base 3 for (; k < points; k++) { point = rsg.nextSequence().value; @@ -596,10 +596,10 @@ public void testHalton() if (error > tolerance) { QAssert.Fail("Second dimension mean (" + /*QL_FIXED*/ +mean[1] - + ") at the end of the " + j + 1 - + " cycle in Halton sequence is not " + 0.5 - //+ QL_SCIENTIFIC - + " (error = " + error + ")"); + + ") at the end of the " + j + 1 + + " cycle in Halton sequence is not " + 0.5 + //+ QL_SCIENTIFIC + + " (error = " + error + ")"); } } } @@ -627,7 +627,7 @@ public void testGeneratorDiscrepancy(IRNGFactory generatorFactory, double[][] di for (j = jMin; j < jMin + sampleLoops; j++) { - int points = (int) (Utils.Pow(2.0, (int) (j))) - 1; + int points = (int)(Utils.Pow(2.0, (int)(j))) - 1; for (; k < points; k++) { point = rsg.nextSequence().value; @@ -636,13 +636,13 @@ public void testGeneratorDiscrepancy(IRNGFactory generatorFactory, double[][] di discr = stat.discrepancy(); - if (Math.Abs(discr - discrepancy[i][j - jMin]) > tolerance*discr) + if (Math.Abs(discr - discrepancy[i][j - jMin]) > tolerance * discr) { QAssert.Fail(generatorFactory.name() - + "discrepancy dimension " + dimensionality[i] - + " at " + points + " samples is " - + discr + " instead of " - + discrepancy[i][j - jMin]); + + "discrepancy dimension " + dimensionality[i] + + " at " + points + " samples is " + + discr + " instead of " + + discrepancy[i][j - jMin]); } } } @@ -663,9 +663,9 @@ public void testMersenneTwisterDiscrepancy() }; testGeneratorDiscrepancy(new MersenneFactory(), - discrepancy /*,"MersenneDiscrepancy.txt", + discrepancy /*,"MersenneDiscrepancy.txt", "DiscrMersenneTwis"*/ - ); + ); } #endregion @@ -686,9 +686,9 @@ public void testPlainHaltonDiscrepancy() }; testGeneratorDiscrepancy(new HaltonFactory(false, false), - discrepancy /*,"PlainHaltonDiscrepancy.txt", + discrepancy /*,"PlainHaltonDiscrepancy.txt", "DiscrPlain_Halton"*/ - ); + ); } public void testRandomStartHaltonDiscrepancy() @@ -705,9 +705,9 @@ public void testRandomStartHaltonDiscrepancy() }; testGeneratorDiscrepancy(new HaltonFactory(true, false), - discrepancy /*,"RandomStartHaltonDiscrepancy.txt", + discrepancy /*,"RandomStartHaltonDiscrepancy.txt", "DiscrRStartHalton"*/ - ); + ); } public void testRandomShiftHaltonDiscrepancy() @@ -724,9 +724,9 @@ public void testRandomShiftHaltonDiscrepancy() }; testGeneratorDiscrepancy(new HaltonFactory(false, true), - discrepancy /*,"RandomShiftHaltonDiscrepancy.txt", + discrepancy /*,"RandomShiftHaltonDiscrepancy.txt", "DiscrRShiftHalton"*/ - ); + ); } public void testRandomStartRandomShiftHaltonDiscrepancy() @@ -743,9 +743,9 @@ public void testRandomStartRandomShiftHaltonDiscrepancy() }; testGeneratorDiscrepancy(new HaltonFactory(true, true), - discrepancy /*,"RandomStartRandomShiftHaltonDiscrepancy.txt", + discrepancy /*,"RandomStartRandomShiftHaltonDiscrepancy.txt", "DiscrRStRShHalton"*/ - ); + ); } //[TestMethod()] @@ -774,7 +774,7 @@ public void testJackelSobolDiscrepancy() }; testGeneratorDiscrepancy(new SobolFactory(SobolRsg.DirectionIntegers.Jaeckel), - discrepancy /*,"JackelSobolDiscrepancy.txt","DiscrJackel_Sobol"*/); + discrepancy /*,"JackelSobolDiscrepancy.txt","DiscrJackel_Sobol"*/); } public void testSobolLevitanSobolDiscrepancy() @@ -791,8 +791,8 @@ public void testSobolLevitanSobolDiscrepancy() }; testGeneratorDiscrepancy(new SobolFactory(SobolRsg.DirectionIntegers.SobolLevitan), - discrepancy - /*,"SobolLevitanSobolDiscrepancy.txt", "DiscrSobLev_Sobol"*/); + discrepancy + /*,"SobolLevitanSobolDiscrepancy.txt", "DiscrSobLev_Sobol"*/); } public void testSobolLevitanLemieuxSobolDiscrepancy() @@ -809,10 +809,10 @@ public void testSobolLevitanLemieuxSobolDiscrepancy() }; testGeneratorDiscrepancy(new SobolFactory(SobolRsg.DirectionIntegers.SobolLevitanLemieux), - discrepancy /*, + discrepancy /*, "SobolLevitanLemieuxSobolDiscrepancy.txt", "DiscrSobLevLem_Sobol"*/ - ); + ); } public void testUnitSobolDiscrepancy() @@ -829,9 +829,9 @@ public void testUnitSobolDiscrepancy() }; testGeneratorDiscrepancy(new SobolFactory(SobolRsg.DirectionIntegers.Unit), - discrepancy /*,"UnitSobolDiscrepancy.txt", + discrepancy /*,"UnitSobolDiscrepancy.txt", "Discr__Unit_Sobol"*/ - ); + ); } //[TestMethod()] @@ -846,9 +846,9 @@ public void _testDiscrepancy_Sobol() #endregion #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testSobolSkipping() { @@ -891,12 +891,12 @@ public void testSobolSkipping() if (s1[n] != s2[n]) { QAssert.Fail("Mismatch after skipping:" - + "\n size: " + dimensionality[j] - + "\n integers: " + integers[i] - + "\n skipped: " + skip[k] - + "\n at index: " + n - + "\n expected: " + s1[n] - + "\n found: " + s2[n]); + + "\n size: " + dimensionality[j] + + "\n integers: " + integers[i] + + "\n skipped: " + skip[k] + + "\n at index: " + n + + "\n expected: " + s1[n] + + "\n found: " + s2[n]); } } } diff --git a/tests/QLNet.Tests/T_Matrices.cs b/tests/QLNet.Tests/T_Matrices.cs index 95ac99abc..023625017 100644 --- a/tests/QLNet.Tests/T_Matrices.cs +++ b/tests/QLNet.Tests/T_Matrices.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,223 +22,240 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; -namespace TestSuite { +namespace TestSuite +{ #if NET40 || NET45 [TestClass()] #endif - public class T_Matrices { - - int N; - Matrix M1, M2, M3, M4, M5, M6, M7, I; - - double norm(Vector v) { - return Math.Sqrt(Vector.DotProduct(v,v)); - } - - double norm(Matrix m) { - double sum = 0.0; - for (int i=0; i 1.0e-15) - QAssert.Fail("Eigenvector definition not satisfied"); - // check decreasing ordering - if (eigenValues[i] >= minHolder) { - QAssert.Fail("Eigenvalues not ordered: " + eigenValues); - } else - minHolder = eigenValues[i]; - } - - // check normalization - Matrix m = eigenVectors * Matrix.transpose(eigenVectors); - if (norm(m-I) > 1.0e-15) - QAssert.Fail("Eigenvector not normalized"); + public void testEigenvectors() + { + //("Testing eigenvalues and eigenvectors calculation..."); + + setup(); + + Matrix[] testMatrices = { M1, M2 }; + + for (int k = 0; k < testMatrices.Length; k++) + { + + Matrix M = testMatrices[k]; + SymmetricSchurDecomposition dec = new SymmetricSchurDecomposition(M); + Vector eigenValues = dec.eigenvalues(); + Matrix eigenVectors = dec.eigenvectors(); + double minHolder = double.MaxValue; + + for (int i = 0; i < N; i++) + { + Vector v = new Vector(N); + for (int j = 0; j < N; j++) + v[j] = eigenVectors[j, i]; + // check definition + Vector a = M * v; + Vector b = eigenValues[i] * v; + if (norm(a - b) > 1.0e-15) + QAssert.Fail("Eigenvector definition not satisfied"); + // check decreasing ordering + if (eigenValues[i] >= minHolder) + { + QAssert.Fail("Eigenvalues not ordered: " + eigenValues); + } + else + minHolder = eigenValues[i]; } - } + + // check normalization + Matrix m = eigenVectors * Matrix.transpose(eigenVectors); + if (norm(m - I) > 1.0e-15) + QAssert.Fail("Eigenvector not normalized"); + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testSqrt() { - - //BOOST_MESSAGE("Testing matricial square root..."); - - setup(); - - Matrix m = MatrixUtilitites.pseudoSqrt(M1, MatrixUtilitites.SalvagingAlgorithm.None); - Matrix temp = m*Matrix.transpose(m); - double error = norm(temp - M1); - double tolerance = 1.0e-12; - if (error>tolerance) { - QAssert.Fail("Matrix square root calculation failed\n" - + "original matrix:\n" + M1 - + "pseudoSqrt:\n" + m - + "pseudoSqrt*pseudoSqrt:\n" + temp - + "\nerror: " + error - + "\ntolerance: " + tolerance); - } - } + public void testSqrt() + { + + //BOOST_MESSAGE("Testing matricial square root..."); + + setup(); + + Matrix m = MatrixUtilitites.pseudoSqrt(M1, MatrixUtilitites.SalvagingAlgorithm.None); + Matrix temp = m * Matrix.transpose(m); + double error = norm(temp - M1); + double tolerance = 1.0e-12; + if (error > tolerance) + { + QAssert.Fail("Matrix square root calculation failed\n" + + "original matrix:\n" + M1 + + "pseudoSqrt:\n" + m + + "pseudoSqrt*pseudoSqrt:\n" + temp + + "\nerror: " + error + + "\ntolerance: " + tolerance); + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testHighamSqrt() { - //BOOST_MESSAGE("Testing Higham matricial square root..."); - - setup(); - - Matrix tempSqrt = MatrixUtilitites.pseudoSqrt(M5, MatrixUtilitites.SalvagingAlgorithm.Higham); - Matrix ansSqrt = MatrixUtilitites.pseudoSqrt(M6, MatrixUtilitites.SalvagingAlgorithm.None); - double error = norm(ansSqrt - tempSqrt); - double tolerance = 1.0e-4; - if (error>tolerance) { - QAssert.Fail("Higham matrix correction failed\n" - + "original matrix:\n" + M5 - + "pseudoSqrt:\n" + tempSqrt - + "should be:\n" + ansSqrt - + "\nerror: " + error - + "\ntolerance: " + tolerance); - } - } + public void testHighamSqrt() + { + //BOOST_MESSAGE("Testing Higham matricial square root..."); + + setup(); + + Matrix tempSqrt = MatrixUtilitites.pseudoSqrt(M5, MatrixUtilitites.SalvagingAlgorithm.Higham); + Matrix ansSqrt = MatrixUtilitites.pseudoSqrt(M6, MatrixUtilitites.SalvagingAlgorithm.None); + double error = norm(ansSqrt - tempSqrt); + double tolerance = 1.0e-4; + if (error > tolerance) + { + QAssert.Fail("Higham matrix correction failed\n" + + "original matrix:\n" + M5 + + "pseudoSqrt:\n" + tempSqrt + + "should be:\n" + ansSqrt + + "\nerror: " + error + + "\ntolerance: " + tolerance); + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testSVD() { - - //BOOST_MESSAGE("Testing singular value decomposition..."); - - setup(); - - double tol = 1.0e-12; - Matrix[] testMatrices = { M1, M2, M3, M4 }; - - for (int j = 0; j < testMatrices.Length; j++) { - // m >= n required (rows >= columns) - Matrix A = testMatrices[j]; - SVD svd = new SVD(A); - // U is m x n - Matrix U = svd.U(); - // s is n long - Vector s = svd.singularValues(); - // S is n x n - Matrix S = svd.S(); - // V is n x n - Matrix V = svd.V(); - - for (int i=0; i < S.rows(); i++) { - if (S[i,i] != s[i]) - QAssert.Fail("S not consistent with s"); - } - - // tests - Matrix U_Utranspose = Matrix.transpose(U)*U; - if (norm(U_Utranspose-I) > tol) - QAssert.Fail("U not orthogonal (norm of U^T*U-I = " + norm(U_Utranspose-I) + ")"); - - Matrix V_Vtranspose = Matrix.transpose(V) * V; - if (norm(V_Vtranspose-I) > tol) - QAssert.Fail("V not orthogonal (norm of V^T*V-I = " + norm(V_Vtranspose-I) + ")"); - - Matrix A_reconstructed = U * S * Matrix.transpose(V); - if (norm(A_reconstructed-A) > tol) - QAssert.Fail("Product does not recover A: (norm of U*S*V^T-A = " + norm(A_reconstructed-A) + ")"); + public void testSVD() + { + + //BOOST_MESSAGE("Testing singular value decomposition..."); + + setup(); + + double tol = 1.0e-12; + Matrix[] testMatrices = { M1, M2, M3, M4 }; + + for (int j = 0; j < testMatrices.Length; j++) + { + // m >= n required (rows >= columns) + Matrix A = testMatrices[j]; + SVD svd = new SVD(A); + // U is m x n + Matrix U = svd.U(); + // s is n long + Vector s = svd.singularValues(); + // S is n x n + Matrix S = svd.S(); + // V is n x n + Matrix V = svd.V(); + + for (int i = 0; i < S.rows(); i++) + { + if (S[i, i] != s[i]) + QAssert.Fail("S not consistent with s"); } - } + + // tests + Matrix U_Utranspose = Matrix.transpose(U) * U; + if (norm(U_Utranspose - I) > tol) + QAssert.Fail("U not orthogonal (norm of U^T*U-I = " + norm(U_Utranspose - I) + ")"); + + Matrix V_Vtranspose = Matrix.transpose(V) * V; + if (norm(V_Vtranspose - I) > tol) + QAssert.Fail("V not orthogonal (norm of V^T*V-I = " + norm(V_Vtranspose - I) + ")"); + + Matrix A_reconstructed = U * S * Matrix.transpose(V); + if (norm(A_reconstructed - A) > tol) + QAssert.Fail("Product does not recover A: (norm of U*S*V^T-A = " + norm(A_reconstructed - A) + ")"); + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testQRDecomposition() - { + public void testQRDecomposition() + { // Testing QR decomposition... @@ -246,119 +263,123 @@ public void testQRDecomposition() double tol = 1.0e-12; Matrix[] testMatrices = { M1, M2, I, - M3, Matrix.transpose(M3), M4, Matrix.transpose(M4), M5 }; + M3, Matrix.transpose(M3), M4, Matrix.transpose(M4), M5 + }; - for (int j = 0; j < testMatrices.Length; j++) { - Matrix Q = new Matrix(), R = new Matrix(); - bool pivot = true; - Matrix A = testMatrices[j]; - List ipvt = MatrixUtilities.qrDecomposition(A, ref Q, ref R, pivot); + for (int j = 0; j < testMatrices.Length; j++) + { + Matrix Q = new Matrix(), R = new Matrix(); + bool pivot = true; + Matrix A = testMatrices[j]; + List ipvt = MatrixUtilities.qrDecomposition(A, ref Q, ref R, pivot); - Matrix P = new Matrix(A.columns(), A.columns(), 0.0); + Matrix P = new Matrix(A.columns(), A.columns(), 0.0); - // reverse column pivoting - for (int i=0; i < P.columns(); ++i) { - P[ipvt[i],i] = 1.0; - } + // reverse column pivoting + for (int i = 0; i < P.columns(); ++i) + { + P[ipvt[i], i] = 1.0; + } + + if (norm(Q * R - A * P) > tol) + QAssert.Fail("Q*R does not match matrix A*P (norm = " + + norm(Q * R - A * P) + ")"); - if (norm(Q*R - A*P) > tol) - QAssert.Fail("Q*R does not match matrix A*P (norm = " - + norm(Q*R-A*P) + ")"); + pivot = false; + MatrixUtilities.qrDecomposition(A, ref Q, ref R, pivot); - pivot = false; - MatrixUtilities.qrDecomposition(A, ref Q, ref R, pivot); + if (norm(Q * R - A) > tol) + QAssert.Fail("Q*R does not match matrix A (norm = " + + norm(Q * R - A) + ")"); - if (norm(Q*R - A) > tol) - QAssert.Fail("Q*R does not match matrix A (norm = " - + norm(Q*R-A) + ")"); - } - } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testQRSolve() - { - // Testing QR solve... - setup(); - - double tol = 1.0e-12; - MersenneTwisterUniformRng rng = new MersenneTwisterUniformRng( 1234 ); - Matrix bigM = new Matrix( 50, 100, 0.0 ); - for ( int i = 0; i < Math.Min( bigM.rows(), bigM.columns() ); ++i ) - { - bigM[i, i] = i + 1.0; - } - Matrix[] testMatrices = { M1, M2, M3, Matrix.transpose(M3), - M4, Matrix.transpose(M4), M5, I, M7, bigM, Matrix.transpose(bigM) }; - - for ( int j = 0; j < testMatrices.Length; j++ ) - { - Matrix A = testMatrices[j]; - Vector b = new Vector( A.rows() ); - - for ( int k = 0; k < 10; ++k ) - { - for ( int i = 0; i < b.Count; ++i ) - { - b[i] = rng.next().value; - } - Vector x = MatrixUtilities.qrSolve( A, b, true ); - - if ( A.columns() >= A.rows() ) - { - if ( norm( A * x - b ) > tol ) - QAssert.Fail( "A*x does not match vector b (norm = " - + norm( A * x - b ) + ")" ); - } - else - { - // use the SVD to calculate the reference values - int n = A.columns(); - Vector xr = new Vector( n, 0.0 ); - - SVD svd = new SVD( A ); - Matrix V = svd.V(); - Matrix U = svd.U(); - Vector w = svd.singularValues(); - double threshold = n * Const.QL_EPSILON; - - for ( int i = 0; i < n; ++i ) - { - if ( w[i] > threshold ) - { - double u = 0; - int zero = 0; - for ( int kk = 0; kk < U.rows(); kk++ ) - u += ( U[kk, i] * b[zero++] ) / w[i]; - - for ( int jj = 0; jj < n; ++jj ) - { - xr[jj] += u * V[jj, i]; - } - } - } - - if ( norm( xr - x ) > tol ) - { - QAssert.Fail( "least square solution does not match (norm = " - + norm( x - xr ) + ")" ); - - } - } - } - } - } + public void testQRSolve() + { + // Testing QR solve... + setup(); + + double tol = 1.0e-12; + MersenneTwisterUniformRng rng = new MersenneTwisterUniformRng(1234); + Matrix bigM = new Matrix(50, 100, 0.0); + for (int i = 0; i < Math.Min(bigM.rows(), bigM.columns()); ++i) + { + bigM[i, i] = i + 1.0; + } + Matrix[] testMatrices = { M1, M2, M3, Matrix.transpose(M3), + M4, Matrix.transpose(M4), M5, I, M7, bigM, Matrix.transpose(bigM) + }; + + for (int j = 0; j < testMatrices.Length; j++) + { + Matrix A = testMatrices[j]; + Vector b = new Vector(A.rows()); + + for (int k = 0; k < 10; ++k) + { + for (int i = 0; i < b.Count; ++i) + { + b[i] = rng.next().value; + } + Vector x = MatrixUtilities.qrSolve(A, b, true); + + if (A.columns() >= A.rows()) + { + if (norm(A * x - b) > tol) + QAssert.Fail("A*x does not match vector b (norm = " + + norm(A * x - b) + ")"); + } + else + { + // use the SVD to calculate the reference values + int n = A.columns(); + Vector xr = new Vector(n, 0.0); + + SVD svd = new SVD(A); + Matrix V = svd.V(); + Matrix U = svd.U(); + Vector w = svd.singularValues(); + double threshold = n * Const.QL_EPSILON; + + for (int i = 0; i < n; ++i) + { + if (w[i] > threshold) + { + double u = 0; + int zero = 0; + for (int kk = 0; kk < U.rows(); kk++) + u += (U[kk, i] * b[zero++]) / w[i]; + + for (int jj = 0; jj < n; ++jj) + { + xr[jj] += u * V[jj, i]; + } + } + } + + if (norm(xr - x) > tol) + { + QAssert.Fail("least square solution does not match (norm = " + + norm(x - xr) + ")"); + + } + } + } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testInverse() + public void testInverse() { // Testing LU inverse calculation @@ -367,24 +388,25 @@ public void testInverse() double tol = 1.0e-12; Matrix[] testMatrices = { M1, M2, I, M5 }; - for (int j = 0; j < testMatrices.Length; j++) + for (int j = 0; j < testMatrices.Length; j++) { Matrix A = testMatrices[j]; Matrix invA = Matrix.inverse(A); - Matrix I1 = invA*A; - Matrix I2 = A*invA; + Matrix I1 = invA * A; + Matrix I2 = A * invA; Matrix eins = new Matrix(A.rows(), A.rows(), 0.0); - for (int i=0; i < A.rows(); ++i) eins[i,i] = 1.0; + for (int i = 0; i < A.rows(); ++i) + eins[i, i] = 1.0; if (norm(I1 - eins) > tol) QAssert.Fail("inverse(A)*A does not recover unit matrix (norm = " - + norm(I1-eins) + ")"); + + norm(I1 - eins) + ")"); if (norm(I2 - eins) > tol) QAssert.Fail("A*inverse(A) does not recover unit matrix (norm = " - + norm(I1-eins) + ")"); + + norm(I1 - eins) + ")"); } } } diff --git a/tests/QLNet.Tests/T_Mclongstaffschwartzengine.cs b/tests/QLNet.Tests/T_Mclongstaffschwartzengine.cs index 6a3e102f8..143d17a7b 100644 --- a/tests/QLNet.Tests/T_Mclongstaffschwartzengine.cs +++ b/tests/QLNet.Tests/T_Mclongstaffschwartzengine.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,63 +21,71 @@ under the terms of the QLNet license. You should have received a using System.Linq; using QLNet; -namespace TestSuite { - class T_Mclongstaffschwartzengine { +namespace TestSuite +{ + class T_Mclongstaffschwartzengine + { - class AmericanMaxPathPricer : IEarlyExercisePathPricer { - protected Payoff payoff_; + class AmericanMaxPathPricer : IEarlyExercisePathPricer + { + protected Payoff payoff_; - public AmericanMaxPathPricer(Payoff payoff) { - payoff_ = payoff; - } + public AmericanMaxPathPricer(Payoff payoff) + { + payoff_ = payoff; + } - public Vector state(MultiPath path, int t) { - Vector tmp = new Vector(path.assetNumber()); - for (int i = 0; i < path.assetNumber(); ++i) { - tmp[i] = path[i][t]; - } - return tmp; + public Vector state(MultiPath path, int t) + { + Vector tmp = new Vector(path.assetNumber()); + for (int i = 0; i < path.assetNumber(); ++i) + { + tmp[i] = path[i][t]; } + return tmp; + } - public double value(MultiPath path, int t) { - Vector tmp = (Vector)state(path, t); - return payoff_.value(tmp.Max()); - } + public double value(MultiPath path, int t) + { + Vector tmp = (Vector)state(path, t); + return payoff_.value(tmp.Max()); + } - public List> basisSystem() { - return LsmBasisSystem.multiPathBasisSystem(2, 2, LsmBasisSystem.PolynomType.Monomial); - } - } - - //class MCAmericanMaxEngine : MCLongstaffSchwartzEngine - // where RNG : IRSG, new() { - - // //public MCAmericanMaxEngine(StochasticProcessArray processes, int timeSteps, int timeStepsPerYear, - // // bool brownianbridge, bool antitheticVariate, bool controlVariate, - // // int requiredSamples, double requiredTolerance, int maxSamples, - // // ulong seed, int nCalibrationSamples = Null()) - // public MCAmericanMaxEngine(StochasticProcessArray processes, int timeSteps, int timeStepsPerYear, - // bool brownianbridge, bool antitheticVariate, bool controlVariate, - // int requiredSamples, double requiredTolerance, int maxSamples, - // ulong seed, int nCalibrationSamples) - // : base(processes, timeSteps, timeStepsPerYear, brownianbridge, antitheticVariate, controlVariate, - // requiredSamples, requiredTolerance, maxSamples, seed, nCalibrationSamples) - // { } - - // protected override LongstaffSchwartzPathPricer lsmPathPricer() { - // StochasticProcessArray processArray = process_ as StochasticProcessArray; - // if (processArray == null || processArray.size() == 0) - // throw new Exception("Stochastic process array required"); - - // GeneralizedBlackScholesProcess process = processArray.process(0) as GeneralizedBlackScholesProcess; - // if (process == null) - // throw new Exception("generalized Black-Scholes proces required"); - - // AmericanMaxPathPricer earlyExercisePathPricer = new AmericanMaxPathPricer(arguments_.payoff); - - // return new LongstaffSchwartzPathPricer(timeGrid(), earlyExercisePathPricer, - // process.riskFreeRate().currentLink()); - // } - //} - } + public List> basisSystem() + { + return LsmBasisSystem.multiPathBasisSystem(2, 2, LsmBasisSystem.PolynomType.Monomial); + } + } + + //class MCAmericanMaxEngine : MCLongstaffSchwartzEngine + // where RNG : IRSG, new() { + + // //public MCAmericanMaxEngine(StochasticProcessArray processes, int timeSteps, int timeStepsPerYear, + // // bool brownianbridge, bool antitheticVariate, bool controlVariate, + // // int requiredSamples, double requiredTolerance, int maxSamples, + // // ulong seed, int nCalibrationSamples = Null()) + // public MCAmericanMaxEngine(StochasticProcessArray processes, int timeSteps, int timeStepsPerYear, + // bool brownianbridge, bool antitheticVariate, bool controlVariate, + // int requiredSamples, double requiredTolerance, int maxSamples, + // ulong seed, int nCalibrationSamples) + // : base(processes, timeSteps, timeStepsPerYear, brownianbridge, antitheticVariate, controlVariate, + // requiredSamples, requiredTolerance, maxSamples, seed, nCalibrationSamples) + // { } + + // protected override LongstaffSchwartzPathPricer lsmPathPricer() { + // StochasticProcessArray processArray = process_ as StochasticProcessArray; + // if (processArray == null || processArray.size() == 0) + // throw new Exception("Stochastic process array required"); + + // GeneralizedBlackScholesProcess process = processArray.process(0) as GeneralizedBlackScholesProcess; + // if (process == null) + // throw new Exception("generalized Black-Scholes proces required"); + + // AmericanMaxPathPricer earlyExercisePathPricer = new AmericanMaxPathPricer(arguments_.payoff); + + // return new LongstaffSchwartzPathPricer(timeGrid(), earlyExercisePathPricer, + // process.riskFreeRate().currentLink()); + // } + //} + } } diff --git a/tests/QLNet.Tests/T_Money.cs b/tests/QLNet.Tests/T_Money.cs index 1ecea032b..284e01d9e 100644 --- a/tests/QLNet.Tests/T_Money.cs +++ b/tests/QLNet.Tests/T_Money.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Andrea Maggiulli - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,7 +20,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -32,9 +32,9 @@ namespace TestSuite public class T_Money { #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testNone() { @@ -55,9 +55,9 @@ public void testNone() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testBaseCurrency() { @@ -80,7 +80,7 @@ public void testBaseCurrency() Rounding round = Money.baseCurrency.rounding; double x = round.Round(m1.value * 3.0 / eur_gbp.rate) + 2.5 * m2.value - - round.Round(m3.value / (5.0 * eur_usd.rate)); + - round.Round(m3.value / (5.0 * eur_usd.rate)); Money expected = new Money(x, EUR); Money.conversionType = Money.ConversionType.NoConversion; @@ -92,11 +92,11 @@ public void testBaseCurrency() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testAutomated() + public void testAutomated() { Currency EUR = new EURCurrency(), GBP = new GBPCurrency(), USD = new USDCurrency(); @@ -112,16 +112,16 @@ public void testAutomated() Money.conversionType = Money.ConversionType.AutomatedConversion; - Money calculated = (m1*3.0 + 2.5*m2) - m3/5.0; + Money calculated = (m1 * 3.0 + 2.5 * m2) - m3 / 5.0; Rounding round = m1.currency.rounding; - double x = m1.value*3.0 + round.Round(2.5*m2.value*eur_gbp.rate) - - round.Round((m3.value/5.0)*eur_gbp.rate/eur_usd.rate); + double x = m1.value * 3.0 + round.Round(2.5 * m2.value * eur_gbp.rate) + - round.Round((m3.value / 5.0) * eur_gbp.rate / eur_usd.rate); Money expected = new Money(x, GBP); Money.conversionType = Money.ConversionType.NoConversion; - if (calculated != expected) + if (calculated != expected) { QAssert.Fail("Wrong result: " + "expected: " + expected + " calculated: " + calculated); } diff --git a/tests/QLNet.Tests/T_Operators.cs b/tests/QLNet.Tests/T_Operators.cs index 0d524ac19..f6a57a11e 100644 --- a/tests/QLNet.Tests/T_Operators.cs +++ b/tests/QLNet.Tests/T_Operators.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,7 +20,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -34,9 +34,9 @@ public class T_Operators public const double average = 0.0, sigma = 1.0; #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testOperatorConsistency() { @@ -47,16 +47,16 @@ public void testOperatorConsistency() CumulativeNormalDistribution cum = new CumulativeNormalDistribution(average, sigma); double xMin = average - 4 * sigma, - xMax = average + 4 * sigma; + xMax = average + 4 * sigma; int N = 10001; double h = (xMax - xMin) / (N - 1); Vector x = new Vector(N), - y = new Vector(N), - yi = new Vector(N), - yd = new Vector(N), - temp = new Vector(N), - diff = new Vector(N); + y = new Vector(N), + yi = new Vector(N), + yd = new Vector(N), + temp = new Vector(N), + diff = new Vector(N); for (int i = 0; i < N; i++) x[i] = xMin + h * i; @@ -98,9 +98,9 @@ public void testOperatorConsistency() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testBSMOperatorConsistency() { @@ -132,10 +132,10 @@ public void testBSMOperatorConsistency() YieldTermStructure rTS = Utilities.flatRate(today, r, dc); BlackVolTermStructure volTS = Utilities.flatVol(today, sigma, dc); GeneralizedBlackScholesProcess stochProcess = new GeneralizedBlackScholesProcess( - new Handle(spot), - new Handle(qTS), - new Handle(rTS), - new Handle(volTS)); + new Handle(spot), + new Handle(qTS), + new Handle(rTS), + new Handle(volTS)); BSMOperator op1 = new BSMOperator(grid, stochProcess, residualTime); PdeOperator op2 = new PdeOperator(grid, stochProcess, residualTime); @@ -151,15 +151,15 @@ public void testBSMOperatorConsistency() Math.Abs(uderror[i]) > tolerance) { QAssert.Fail("inconsistency between BSM operators:\n" - + i + " row:\n" - + "expected: " - + refer.lowerDiagonal()[i] + ", " - + refer.diagonal()[i] + ", " - + refer.upperDiagonal()[i] + "\n" - + "calculated: " - + op1.lowerDiagonal()[i] + ", " - + op1.diagonal()[i] + ", " - + op1.upperDiagonal()[i]); + + i + " row:\n" + + "expected: " + + refer.lowerDiagonal()[i] + ", " + + refer.diagonal()[i] + ", " + + refer.upperDiagonal()[i] + "\n" + + "calculated: " + + op1.lowerDiagonal()[i] + ", " + + op1.diagonal()[i] + ", " + + op1.upperDiagonal()[i]); } } lderror = refer.lowerDiagonal() - op2.lowerDiagonal(); @@ -173,15 +173,15 @@ public void testBSMOperatorConsistency() Math.Abs(uderror[i]) > tolerance) { QAssert.Fail("inconsistency between BSM operators:\n" - + i + " row:\n" - + "expected: " - + refer.lowerDiagonal()[i] + ", " - + refer.diagonal()[i] + ", " - + refer.upperDiagonal()[i] + "\n" - + "calculated: " - + op2.lowerDiagonal()[i] + ", " - + op2.diagonal()[i] + ", " - + op2.upperDiagonal()[i]); + + i + " row:\n" + + "expected: " + + refer.lowerDiagonal()[i] + ", " + + refer.diagonal()[i] + ", " + + refer.upperDiagonal()[i] + "\n" + + "calculated: " + + op2.lowerDiagonal()[i] + ", " + + op2.diagonal()[i] + ", " + + op2.upperDiagonal()[i]); } } } diff --git a/tests/QLNet.Tests/T_Optimizers.cs b/tests/QLNet.Tests/T_Optimizers.cs index 6a952a7dd..1be9bf636 100644 --- a/tests/QLNet.Tests/T_Optimizers.cs +++ b/tests/QLNet.Tests/T_Optimizers.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,293 +22,522 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; -namespace TestSuite { +namespace TestSuite +{ #if NET40 || NET45 [TestClass()] #endif - public class T_Optimizers { - List costFunctions_ = new List(); - List constraints_ = new List(); - List initialValues_ = new List(); - List maxIterations_ = new List(), maxStationaryStateIterations_ = new List(); - List rootEpsilons_ = new List(), - functionEpsilons_ = new List(), - gradientNormEpsilons_ = new List(); - List endCriterias_ = new List(); - List> optimizationMethods_ = new List>(); - List xMinExpected_ = new List(), yMinExpected_ = new List(); - - struct NamedOptimizationMethod { - public OptimizationMethod optimizationMethod; - public string name; - } - - enum OptimizationMethodType { - simplex, - levenbergMarquardt, - levenbergMarquardt2, - conjugateGradient, - conjugateGradient_goldstein, - steepestDescent, - steepestDescent_goldstein, - bfgs, - bfgs_goldstein - } + public class T_Optimizers + { + List costFunctions_ = new List(); + List constraints_ = new List(); + List initialValues_ = new List(); + List maxIterations_ = new List(), maxStationaryStateIterations_ = new List(); + List rootEpsilons_ = new List(), + functionEpsilons_ = new List(), + gradientNormEpsilons_ = new List(); + List endCriterias_ = new List(); + List> optimizationMethods_ = new List>(); + List xMinExpected_ = new List(), yMinExpected_ = new List(); + + struct NamedOptimizationMethod + { + public OptimizationMethod optimizationMethod; + public string name; + } + + enum OptimizationMethodType + { + simplex, + levenbergMarquardt, + levenbergMarquardt2, + conjugateGradient, + conjugateGradient_goldstein, + steepestDescent, + steepestDescent_goldstein, + bfgs, + bfgs_goldstein + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void OptimizersTest() { - //("Testing optimizers..."); - - setup(); - - // Loop over problems (currently there is only 1 problem) - for (int i=0; i 0 - const double b = 1; - const double c = 1; - Vector coefficients = new Vector() { c, b, a }; - - costFunctions_.Add(new OneDimensionalPolynomialDegreeN(coefficients)); - // Set constraint for optimizers: unconstrained problem - constraints_.Add(new NoConstraint()); - // Set initial guess for optimizer - Vector initialValue = new Vector(1); - initialValue[0] = -100; - initialValues_.Add(initialValue); - // Set end criteria for optimizer - maxIterations_.Add(10000); // maxIterations - maxStationaryStateIterations_.Add(100); // MaxStationaryStateIterations - rootEpsilons_.Add(1e-8); // rootEpsilon - functionEpsilons_.Add(1e-8); // functionEpsilon - gradientNormEpsilons_.Add(1e-8); // gradientNormEpsilon - endCriterias_.Add(new EndCriteria(maxIterations_.Last(), maxStationaryStateIterations_.Last(), - rootEpsilons_.Last(), functionEpsilons_.Last(), - gradientNormEpsilons_.Last())); - - // Set optimization methods for optimizer - OptimizationMethodType[] optimizationMethodTypes = { - OptimizationMethodType.simplex, - OptimizationMethodType.levenbergMarquardt, - OptimizationMethodType.levenbergMarquardt2, - OptimizationMethodType.conjugateGradient/*, steepestDescent*/, - OptimizationMethodType.conjugateGradient_goldstein, - OptimizationMethodType.steepestDescent_goldstein, - OptimizationMethodType.bfgs, - OptimizationMethodType.bfgs_goldstein - }; - - double simplexLambda = 0.1; // characteristic search length for simplex - double levenbergMarquardtEpsfcn = 1.0e-8; // parameters specific for Levenberg-Marquardt - double levenbergMarquardtXtol = 1.0e-8; // - double levenbergMarquardtGtol = 1.0e-8; // - optimizationMethods_.Add(makeOptimizationMethods( - optimizationMethodTypes, optimizationMethodTypes.Length, - simplexLambda, levenbergMarquardtEpsfcn, levenbergMarquardtXtol, - levenbergMarquardtGtol)); - // Set expected results for optimizer - Vector xMinExpected = new Vector(1), yMinExpected = new Vector(1); - xMinExpected[0] = -b/(2.0*a); - yMinExpected[0] = -(b*b-4.0*a*c)/(4.0*a); - xMinExpected_.Add(xMinExpected); - yMinExpected_.Add(yMinExpected); - } - - - OptimizationMethod makeOptimizationMethod(OptimizationMethodType optimizationMethodType, + public void testDifferentialEvolution() + { + //BOOST_TEST_MESSAGE("Testing differential evolution..."); + + /* Note: + * + * The "ModFourthDeJong" doesn't have a well defined optimum because + * of its noisy part. It just has to be <= 15 in our example. + * The concrete value might differ for a different input and + * different random numbers. + * + * The "Griewangk" function is an example where the adaptive + * version of DifferentialEvolution turns out to be more successful. + */ + + DifferentialEvolution.Configuration conf = + new DifferentialEvolution.Configuration() + .withStepsizeWeight(0.4) + .withBounds() + .withCrossoverProbability(0.35) + .withPopulationMembers(500) + .withStrategy(DifferentialEvolution.Strategy.BestMemberWithJitter) + .withCrossoverType(DifferentialEvolution.CrossoverType.Normal) + .withAdaptiveCrossover() + .withSeed(3242); + + DifferentialEvolution.Configuration conf2 = + new DifferentialEvolution.Configuration() + .withStepsizeWeight(1.8) + .withBounds() + .withCrossoverProbability(0.9) + .withPopulationMembers(1000) + .withStrategy(DifferentialEvolution.Strategy.Rand1SelfadaptiveWithRotation) + .withCrossoverType(DifferentialEvolution.CrossoverType.Normal) + .withAdaptiveCrossover() + .withSeed(3242); + DifferentialEvolution deOptim2 = new DifferentialEvolution(conf2); + + List diffEvolOptimisers = new List(); + diffEvolOptimisers.Add(new DifferentialEvolution(conf)); + diffEvolOptimisers.Add(new DifferentialEvolution(conf)); + diffEvolOptimisers.Add(new DifferentialEvolution(conf)); + diffEvolOptimisers.Add(new DifferentialEvolution(conf)); + diffEvolOptimisers.Add(deOptim2); + + List costFunctions = new List(); + costFunctions.Add(new FirstDeJong()); + costFunctions.Add(new SecondDeJong()); + costFunctions.Add(new ModThirdDeJong()); + costFunctions.Add(new ModFourthDeJong()); + costFunctions.Add(new Griewangk()); + + List constraints = new List(); + constraints.Add(new BoundaryConstraint(-10.0, 10.0)); + constraints.Add(new BoundaryConstraint(-10.0, 10.0)); + constraints.Add(new BoundaryConstraint(-10.0, 10.0)); + constraints.Add(new BoundaryConstraint(-10.0, 10.0)); + constraints.Add(new BoundaryConstraint(-600.0, 600.0)); + + List initialValues = new List(); + initialValues.Add(new Vector(3, 5.0)); + initialValues.Add(new Vector(2, 5.0)); + initialValues.Add(new Vector(5, 5.0)); + initialValues.Add(new Vector(30, 5.0)); + initialValues.Add(new Vector(10, 100.0)); + + List endCriteria = new List(); + endCriteria.Add(new EndCriteria(100, 10, 1e-10, 1e-8, null)); + endCriteria.Add(new EndCriteria(100, 10, 1e-10, 1e-8, null)); + endCriteria.Add(new EndCriteria(100, 10, 1e-10, 1e-8, null)); + endCriteria.Add(new EndCriteria(500, 100, 1e-10, 1e-8, null)); + endCriteria.Add(new EndCriteria(1000, 800, 1e-12, 1e-10, null)); + + List minima = new List(); + minima.Add(0.0); + minima.Add(0.0); + minima.Add(0.0); + minima.Add(10.9639796558); + minima.Add(0.0); + + for (int i = 0; i < costFunctions.Count; ++i) + { + Problem problem = new Problem(costFunctions[i], constraints[i], initialValues[i]); + diffEvolOptimisers[i].minimize(problem, endCriteria[i]); + + if (i != 3) + { + // stable + if (Math.Abs(problem.functionValue() - minima[i]) > 1e-8) + { + QAssert.Fail("costFunction # " + i + + "\ncalculated: " + problem.functionValue() + + "\nexpected: " + minima[i]); + } + } + else + { + // this case is unstable due to randomness; we're good as + // long as the result is below 15 + if (problem.functionValue() > 15) + { + QAssert.Fail("costFunction # " + i + + "\ncalculated: " + problem.functionValue() + + "\nexpected: " + "less than 15"); + } + } + } + } + + + // Set up, for each cost function, all the ingredients for optimization: + // constraint, initial guess, end criteria, optimization methods. + void setup() + { + + // Cost function n. 1: 1D polynomial of degree 2 (parabolic function y=a*x^2+b*x+c) + const double a = 1; // required a > 0 + const double b = 1; + const double c = 1; + Vector coefficients = new Vector() { c, b, a }; + + costFunctions_.Add(new OneDimensionalPolynomialDegreeN(coefficients)); + // Set constraint for optimizers: unconstrained problem + constraints_.Add(new NoConstraint()); + // Set initial guess for optimizer + Vector initialValue = new Vector(1); + initialValue[0] = -100; + initialValues_.Add(initialValue); + // Set end criteria for optimizer + maxIterations_.Add(10000); // maxIterations + maxStationaryStateIterations_.Add(100); // MaxStationaryStateIterations + rootEpsilons_.Add(1e-8); // rootEpsilon + functionEpsilons_.Add(1e-8); // functionEpsilon + gradientNormEpsilons_.Add(1e-8); // gradientNormEpsilon + endCriterias_.Add(new EndCriteria(maxIterations_.Last(), maxStationaryStateIterations_.Last(), + rootEpsilons_.Last(), functionEpsilons_.Last(), + gradientNormEpsilons_.Last())); + + // Set optimization methods for optimizer + OptimizationMethodType[] optimizationMethodTypes = + { + OptimizationMethodType.simplex, + OptimizationMethodType.levenbergMarquardt, + OptimizationMethodType.levenbergMarquardt2, + OptimizationMethodType.conjugateGradient/*, steepestDescent*/, + OptimizationMethodType.conjugateGradient_goldstein, + OptimizationMethodType.steepestDescent_goldstein, + OptimizationMethodType.bfgs, + OptimizationMethodType.bfgs_goldstein + }; + + double simplexLambda = 0.1; // characteristic search length for simplex + double levenbergMarquardtEpsfcn = 1.0e-8; // parameters specific for Levenberg-Marquardt + double levenbergMarquardtXtol = 1.0e-8; // + double levenbergMarquardtGtol = 1.0e-8; // + optimizationMethods_.Add(makeOptimizationMethods( + optimizationMethodTypes, optimizationMethodTypes.Length, + simplexLambda, levenbergMarquardtEpsfcn, levenbergMarquardtXtol, + levenbergMarquardtGtol)); + // Set expected results for optimizer + Vector xMinExpected = new Vector(1), yMinExpected = new Vector(1); + xMinExpected[0] = -b / (2.0 * a); + yMinExpected[0] = -(b * b - 4.0 * a * c) / (4.0 * a); + xMinExpected_.Add(xMinExpected); + yMinExpected_.Add(yMinExpected); + } + + + OptimizationMethod makeOptimizationMethod(OptimizationMethodType optimizationMethodType, double simplexLambda, double levenbergMarquardtEpsfcn, double levenbergMarquardtXtol, - double levenbergMarquardtGtol) { - switch (optimizationMethodType) { - case OptimizationMethodType.simplex: - return new Simplex(simplexLambda); - case OptimizationMethodType.levenbergMarquardt: - return new LevenbergMarquardt(levenbergMarquardtEpsfcn, levenbergMarquardtXtol, levenbergMarquardtGtol); - case OptimizationMethodType.levenbergMarquardt2: - return new LevenbergMarquardt( levenbergMarquardtEpsfcn, levenbergMarquardtXtol, levenbergMarquardtGtol,true ); - case OptimizationMethodType.conjugateGradient: - return new ConjugateGradient(); - case OptimizationMethodType.steepestDescent: - return new SteepestDescent(); - case OptimizationMethodType.bfgs: - return new BFGS(); - case OptimizationMethodType.conjugateGradient_goldstein: - return new ConjugateGradient(new GoldsteinLineSearch()); - case OptimizationMethodType.steepestDescent_goldstein: - return new SteepestDescent(new GoldsteinLineSearch()); - case OptimizationMethodType.bfgs_goldstein: - return new BFGS(new GoldsteinLineSearch()); - default: - throw new Exception("unknown OptimizationMethod type"); - } - } - - List makeOptimizationMethods(OptimizationMethodType[] optimizationMethodTypes, - int optimizationMethodNb, - double simplexLambda, - double levenbergMarquardtEpsfcn, - double levenbergMarquardtXtol, - double levenbergMarquardtGtol) { - List results = new List(optimizationMethodNb); - for (int i = 0; i < optimizationMethodNb; ++i) { - NamedOptimizationMethod namedOptimizationMethod; - namedOptimizationMethod.optimizationMethod = makeOptimizationMethod(optimizationMethodTypes[i], - simplexLambda, - levenbergMarquardtEpsfcn, - levenbergMarquardtXtol, - levenbergMarquardtGtol); - namedOptimizationMethod.name = optimizationMethodTypeToString(optimizationMethodTypes[i]); - results.Add(namedOptimizationMethod); - } - return results; - } - - string optimizationMethodTypeToString(OptimizationMethodType type) { - switch (type) { - case OptimizationMethodType.simplex: - return "Simplex"; - case OptimizationMethodType.levenbergMarquardt: - return "Levenberg Marquardt"; - case OptimizationMethodType.levenbergMarquardt2: - return "Levenberg Marquardt (cost function's jacbobian)"; - case OptimizationMethodType.conjugateGradient: - return "Conjugate Gradient"; - case OptimizationMethodType.steepestDescent: - return "Steepest Descent"; - case OptimizationMethodType.bfgs: - return "BFGS"; - case OptimizationMethodType.conjugateGradient_goldstein: - return "Conjugate Gradient (Goldstein line search)"; - case OptimizationMethodType.steepestDescent_goldstein: - return "Steepest Descent (Goldstein line search)"; - case OptimizationMethodType.bfgs_goldstein: - return "BFGS (Goldstein line search)"; - default: - throw new Exception("unknown OptimizationMethod type"); - } - } - } - - class OneDimensionalPolynomialDegreeN : CostFunction { - private Vector coefficients_; - private int polynomialDegree_; - - public OneDimensionalPolynomialDegreeN(Vector coefficients) { - coefficients_ = new Vector(coefficients); - polynomialDegree_ = coefficients.size()-1; - } - - public override double value(Vector x) { - if(x.size()!=1) throw new Exception("independent variable must be 1 dimensional"); - double y = 0; - for (int i=0; i<=polynomialDegree_; ++i) - y += coefficients_[i]*Utils.Pow(x[0],i); - return y; - } - - public override Vector values(Vector x) { - if(x.size()!=1) throw new Exception("independent variable must be 1 dimensional"); - Vector y = new Vector(1); - y[0] = value(x); - return y; - } - } - - // The goal of this cost function is simply to call another optimization inside - // in order to test nested optimizations - class OptimizationBasedCostFunction : CostFunction { - public override double value(Vector x) { return 1.0; } - - public override Vector values(Vector x) { - // dummy nested optimization - Vector coefficients = new Vector(3, 1.0); - OneDimensionalPolynomialDegreeN oneDimensionalPolynomialDegreeN = new OneDimensionalPolynomialDegreeN(coefficients); - NoConstraint constraint = new NoConstraint(); - Vector initialValues = new Vector(1, 100.0); - Problem problem = new Problem(oneDimensionalPolynomialDegreeN, constraint, initialValues); - LevenbergMarquardt optimizationMethod = new LevenbergMarquardt(); - //Simplex optimizationMethod(0.1); - //ConjugateGradient optimizationMethod; - //SteepestDescent optimizationMethod; - EndCriteria endCriteria = new EndCriteria(1000, 100, 1e-5, 1e-5, 1e-5); - optimizationMethod.minimize(problem, endCriteria); - // return dummy result - Vector dummy = new Vector(1,0); - return dummy; - } - } + double levenbergMarquardtGtol) + { + switch (optimizationMethodType) + { + case OptimizationMethodType.simplex: + return new Simplex(simplexLambda); + case OptimizationMethodType.levenbergMarquardt: + return new LevenbergMarquardt(levenbergMarquardtEpsfcn, levenbergMarquardtXtol, levenbergMarquardtGtol); + case OptimizationMethodType.levenbergMarquardt2: + return new LevenbergMarquardt(levenbergMarquardtEpsfcn, levenbergMarquardtXtol, levenbergMarquardtGtol, true); + case OptimizationMethodType.conjugateGradient: + return new ConjugateGradient(); + case OptimizationMethodType.steepestDescent: + return new SteepestDescent(); + case OptimizationMethodType.bfgs: + return new BFGS(); + case OptimizationMethodType.conjugateGradient_goldstein: + return new ConjugateGradient(new GoldsteinLineSearch()); + case OptimizationMethodType.steepestDescent_goldstein: + return new SteepestDescent(new GoldsteinLineSearch()); + case OptimizationMethodType.bfgs_goldstein: + return new BFGS(new GoldsteinLineSearch()); + default: + throw new Exception("unknown OptimizationMethod type"); + } + } + + List makeOptimizationMethods(OptimizationMethodType[] optimizationMethodTypes, + int optimizationMethodNb, + double simplexLambda, + double levenbergMarquardtEpsfcn, + double levenbergMarquardtXtol, + double levenbergMarquardtGtol) + { + List results = new List(optimizationMethodNb); + for (int i = 0; i < optimizationMethodNb; ++i) + { + NamedOptimizationMethod namedOptimizationMethod; + namedOptimizationMethod.optimizationMethod = makeOptimizationMethod(optimizationMethodTypes[i], + simplexLambda, + levenbergMarquardtEpsfcn, + levenbergMarquardtXtol, + levenbergMarquardtGtol); + namedOptimizationMethod.name = optimizationMethodTypeToString(optimizationMethodTypes[i]); + results.Add(namedOptimizationMethod); + } + return results; + } + + string optimizationMethodTypeToString(OptimizationMethodType type) + { + switch (type) + { + case OptimizationMethodType.simplex: + return "Simplex"; + case OptimizationMethodType.levenbergMarquardt: + return "Levenberg Marquardt"; + case OptimizationMethodType.levenbergMarquardt2: + return "Levenberg Marquardt (cost function's jacbobian)"; + case OptimizationMethodType.conjugateGradient: + return "Conjugate Gradient"; + case OptimizationMethodType.steepestDescent: + return "Steepest Descent"; + case OptimizationMethodType.bfgs: + return "BFGS"; + case OptimizationMethodType.conjugateGradient_goldstein: + return "Conjugate Gradient (Goldstein line search)"; + case OptimizationMethodType.steepestDescent_goldstein: + return "Steepest Descent (Goldstein line search)"; + case OptimizationMethodType.bfgs_goldstein: + return "BFGS (Goldstein line search)"; + default: + throw new Exception("unknown OptimizationMethod type"); + } + } + } + + class OneDimensionalPolynomialDegreeN : CostFunction + { + private Vector coefficients_; + private int polynomialDegree_; + + public OneDimensionalPolynomialDegreeN(Vector coefficients) + { + coefficients_ = new Vector(coefficients); + polynomialDegree_ = coefficients.size() - 1; + } + + public override double value(Vector x) + { + if (x.size() != 1) + throw new Exception("independent variable must be 1 dimensional"); + double y = 0; + for (int i = 0; i <= polynomialDegree_; ++i) + y += coefficients_[i] * Utils.Pow(x[0], i); + return y; + } + + public override Vector values(Vector x) + { + if (x.size() != 1) + throw new Exception("independent variable must be 1 dimensional"); + Vector y = new Vector(1); + y[0] = value(x); + return y; + } + } + + // The goal of this cost function is simply to call another optimization inside + // in order to test nested optimizations + class OptimizationBasedCostFunction : CostFunction + { + public override double value(Vector x) { return 1.0; } + + public override Vector values(Vector x) + { + // dummy nested optimization + Vector coefficients = new Vector(3, 1.0); + OneDimensionalPolynomialDegreeN oneDimensionalPolynomialDegreeN = new OneDimensionalPolynomialDegreeN(coefficients); + NoConstraint constraint = new NoConstraint(); + Vector initialValues = new Vector(1, 100.0); + Problem problem = new Problem(oneDimensionalPolynomialDegreeN, constraint, initialValues); + LevenbergMarquardt optimizationMethod = new LevenbergMarquardt(); + //Simplex optimizationMethod(0.1); + //ConjugateGradient optimizationMethod; + //SteepestDescent optimizationMethod; + EndCriteria endCriteria = new EndCriteria(1000, 100, 1e-5, 1e-5, 1e-5); + optimizationMethod.minimize(problem, endCriteria); + // return dummy result + Vector dummy = new Vector(1, 0); + return dummy; + } + } + + class FirstDeJong : CostFunction + { + public override Vector values(Vector x) + { + Vector retVal = new Vector(x.size(), value(x)); + return retVal; + } + public override double value(Vector x) + { + return Vector.DotProduct(x, x); + } + } + + class SecondDeJong : CostFunction + { + public override Vector values(Vector x) + { + Vector retVal = new Vector(x.size(), value(x)); + return retVal; + } + public override double value(Vector x) + { + return 100.0 * (x[0] * x[0] - x[1]) * (x[0] * x[0] - x[1]) + + (1.0 - x[0]) * (1.0 - x[0]); + } + } + + class ModThirdDeJong : CostFunction + { + public override Vector values(Vector x) + { + Vector retVal = new Vector(x.size(), value(x)); + return retVal; + } + public override double value(Vector x) + { + double fx = 0.0; + for (int i = 0; i < x.size(); ++i) + { + fx += Math.Floor(x[i]) * Math.Floor(x[i]); + } + return fx; + } + } + + class ModFourthDeJong : CostFunction + { + public ModFourthDeJong() + { + uniformRng_ = new MersenneTwisterUniformRng(4711); + } + public override Vector values(Vector x) + { + Vector retVal = new Vector(x.size(), value(x)); + return retVal; + } + public override double value(Vector x) + { + double fx = 0.0; + for (int i = 0; i < x.size(); ++i) + { + fx += (i + 1.0) * Math.Pow(x[i], 4.0) + uniformRng_.nextReal(); + } + return fx; + } + MersenneTwisterUniformRng uniformRng_; + } + class Griewangk : CostFunction + { + public override Vector values(Vector x) + { + Vector retVal = new Vector(x.size(), value(x)); + return retVal; + } + public override double value(Vector x) + { + double fx = 0.0; + for (int i = 0; i < x.size(); ++i) + { + fx += x[i] * x[i] / 4000.0; + } + double p = 1.0; + for (int i = 0; i < x.size(); ++i) + { + p *= Math.Cos(x[i] / Math.Sqrt(i + 1.0)); + } + return fx - p + 1.0; + } + } } diff --git a/tests/QLNet.Tests/T_OptionletStripper.cs b/tests/QLNet.Tests/T_OptionletStripper.cs index c844f808f..3af6dabf7 100644 --- a/tests/QLNet.Tests/T_OptionletStripper.cs +++ b/tests/QLNet.Tests/T_OptionletStripper.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -18,7 +18,7 @@ #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -31,20 +31,20 @@ public class T_OptionletStripper : IDisposable { #region Initialize&Cleanup private SavedSettings backup; - #if NET40 || NET45 +#if NET40 || NET45 [TestInitialize] public void testInitialize() { - #else +#else public T_OptionletStripper() { - #endif +#endif backup = new SavedSettings(); } - #if NET40 || NET45 +#if NET40 || NET45 [TestCleanup] - #endif +#endif public void testCleanup() { Dispose(); @@ -91,49 +91,49 @@ public void setTermStructure() dayCounter = new Actual365Fixed(); double flatFwdRate = 0.04; - yieldTermStructure.linkTo(new FlatForward(0,calendar,flatFwdRate,dayCounter)); - } + yieldTermStructure.linkTo(new FlatForward(0, calendar, flatFwdRate, dayCounter)); + } - public void setFlatTermVolCurve() + public void setFlatTermVolCurve() { setTermStructure(); optionTenors = new InitializedList(10); for (int i = 0; i < optionTenors.Count; ++i) - optionTenors[i] = new Period(i + 1, TimeUnit.Years); + optionTenors[i] = new Period(i + 1, TimeUnit.Years); double flatVol = .18; List > curveVHandle = new InitializedList>(optionTenors.Count); - for (int i=0; i(new SimpleQuote(flatVol)); + for (int i = 0; i < optionTenors.Count; ++i) + curveVHandle[i] = new Handle(new SimpleQuote(flatVol)); flatTermVolCurve = new Handle(new CapFloorTermVolCurve(0, calendar, BusinessDayConvention.Following, optionTenors, - curveVHandle, dayCounter)); + curveVHandle, dayCounter)); } - public void setFlatTermVolSurface() + public void setFlatTermVolSurface() { setTermStructure(); optionTenors = new InitializedList(10); for (int i = 0; i < optionTenors.Count; ++i) - optionTenors[i] = new Period(i + 1, TimeUnit.Years); + optionTenors[i] = new Period(i + 1, TimeUnit.Years); - strikes= new InitializedList(10); + strikes = new InitializedList(10); for (int j = 0; j < strikes.Count; ++j) - strikes[j] = (double)(j + 1) / 100.0; + strikes[j] = (double)(j + 1) / 100.0; double flatVol = .18; termV = new Matrix(optionTenors.Count, strikes.Count, flatVol); - flatTermVolSurface = new CapFloorTermVolSurface(0, calendar, BusinessDayConvention.Following, - optionTenors, strikes,termV, dayCounter); + flatTermVolSurface = new CapFloorTermVolSurface(0, calendar, BusinessDayConvention.Following, + optionTenors, strikes, termV, dayCounter); } - public void setCapFloorTermVolCurve() + public void setCapFloorTermVolCurve() { setTermStructure(); @@ -158,7 +158,7 @@ public void setCapFloorTermVolCurve() optionTenors.Add(new Period(30, TimeUnit.Years)); //atm capfloor vols from mkt vol matrix using flat yield curve - atmTermV = new List(); + atmTermV = new List(); atmTermV.Add(0.090304); atmTermV.Add(0.12180); atmTermV.Add(0.13077); @@ -176,22 +176,22 @@ public void setCapFloorTermVolCurve() atmTermV.Add(0.14175); atmTermV.Add(0.13889); atmTermVolHandle = new InitializedList>(optionTenors.Count); - for (int i=0; i( new SimpleQuote(atmTermV[i])); + atmTermVolHandle[i] = new Handle(new SimpleQuote(atmTermV[i])); } - capFloorVolCurve = new Handle(new CapFloorTermVolCurve(0, calendar, BusinessDayConvention.Following, - optionTenors, atmTermVolHandle,dayCounter)); + capFloorVolCurve = new Handle(new CapFloorTermVolCurve(0, calendar, BusinessDayConvention.Following, + optionTenors, atmTermVolHandle, dayCounter)); - } + } - public void setCapFloorTermVolSurface() + public void setCapFloorTermVolSurface() { setTermStructure(); //cap volatility smile matrix - optionTenors = new List(); + optionTenors = new List(); optionTenors.Add(new Period(1, TimeUnit.Years)); optionTenors.Add(new Period(18, TimeUnit.Months)); optionTenors.Add(new Period(2, TimeUnit.Years)); @@ -225,36 +225,36 @@ public void setCapFloorTermVolSurface() strikes.Add(0.1); termV = new Matrix(optionTenors.Count, strikes.Count); - termV[0,0]=0.287; termV[0,1]=0.274; termV[0,2]=0.256; termV[0,3]=0.245; termV[0,4]=0.227; termV[0,5]=0.148; termV[0,6]=0.096; termV[0,7]=0.09; termV[0,8]=0.11; termV[0,9]=0.139; termV[0,10]=0.166; termV[0,11]=0.19; termV[0,12]=0.214; - termV[1,0]=0.303; termV[1,1]=0.258; termV[1,2]=0.22; termV[1,3]=0.203; termV[1,4]=0.19; termV[1,5]=0.153; termV[1,6]=0.126; termV[1,7]=0.118; termV[1,8]=0.147; termV[1,9]=0.165; termV[1,10]=0.18; termV[1,11]=0.192; termV[1,12]=0.212; - termV[2,0]=0.303; termV[2,1]=0.257; termV[2,2]=0.216; termV[2,3]=0.196; termV[2,4]=0.182; termV[2,5]=0.154; termV[2,6]=0.134; termV[2,7]=0.127; termV[2,8]=0.149; termV[2,9]=0.166; termV[2,10]=0.18; termV[2,11]=0.192; termV[2,12]=0.212; - termV[3,0]=0.305; termV[3,1]=0.266; termV[3,2]=0.226; termV[3,3]=0.203; termV[3,4]=0.19; termV[3,5]=0.167; termV[3,6]=0.151; termV[3,7]=0.144; termV[3,8]=0.16; termV[3,9]=0.172; termV[3,10]=0.183; termV[3,11]=0.193; termV[3,12]=0.209; - termV[4,0]=0.294; termV[4,1]=0.261; termV[4,2]=0.216; termV[4,3]=0.201; termV[4,4]=0.19; termV[4,5]=0.171; termV[4,6]=0.158; termV[4,7]=0.151; termV[4,8]=0.163; termV[4,9]=0.172; termV[4,10]=0.181; termV[4,11]=0.188; termV[4,12]=0.201; - termV[5,0]=0.276; termV[5,1]=0.248; termV[5,2]=0.212; termV[5,3]=0.199; termV[5,4]=0.189; termV[5,5]=0.172; termV[5,6]=0.16; termV[5,7]=0.155; termV[5,8]=0.162; termV[5,9]=0.17; termV[5,10]=0.177; termV[5,11]=0.183; termV[5,12]=0.195; - termV[6,0]=0.26; termV[6,1]=0.237; termV[6,2]=0.21; termV[6,3]=0.198; termV[6,4]=0.188; termV[6,5]=0.172; termV[6,6]=0.161; termV[6,7]=0.156; termV[6,8]=0.161; termV[6,9]=0.167; termV[6,10]=0.173; termV[6,11]=0.179; termV[6,12]=0.19; - termV[7,0]=0.25; termV[7,1]=0.231; termV[7,2]=0.208; termV[7,3]=0.196; termV[7,4]=0.187; termV[7,5]=0.172; termV[7,6]=0.162; termV[7,7]=0.156; termV[7,8]=0.16; termV[7,9]=0.165; termV[7,10]=0.17; termV[7,11]=0.175; termV[7,12]=0.185; - termV[8,0]=0.244; termV[8,1]=0.226; termV[8,2]=0.206; termV[8,3]=0.195; termV[8,4]=0.186; termV[8,5]=0.171; termV[8,6]=0.161; termV[8,7]=0.156; termV[8,8]=0.158; termV[8,9]=0.162; termV[8,10]=0.166; termV[8,11]=0.171; termV[8,12]=0.18; - termV[9,0]=0.239; termV[9,1]=0.222; termV[9,2]=0.204; termV[9,3]=0.193; termV[9,4]=0.185; termV[9,5]=0.17; termV[9,6]=0.16; termV[9,7]=0.155; termV[9,8]=0.156; termV[9,9]=0.159; termV[9,10]=0.163; termV[9,11]=0.168; termV[9,12]=0.177; - termV[10,0]=0.235; termV[10,1]=0.219; termV[10,2]=0.202; termV[10,3]=0.192; termV[10,4]=0.183; termV[10,5]=0.169; termV[10,6]=0.159; termV[10,7]=0.154; termV[10,8]=0.154; termV[10,9]=0.156; termV[10,10]=0.16; termV[10,11]=0.164; termV[10,12]=0.173; - termV[11,0]=0.227; termV[11,1]=0.212; termV[11,2]=0.197; termV[11,3]=0.187; termV[11,4]=0.179; termV[11,5]=0.166; termV[11,6]=0.156; termV[11,7]=0.151; termV[11,8]=0.149; termV[11,9]=0.15; termV[11,10]=0.153; termV[11,11]=0.157; termV[11,12]=0.165; - termV[12,0]=0.22; termV[12,1]=0.206; termV[12,2]=0.192; termV[12,3]=0.183; termV[12,4]=0.175; termV[12,5]=0.162; termV[12,6]=0.153; termV[12,7]=0.147; termV[12,8]=0.144; termV[12,9]=0.144; termV[12,10]=0.147; termV[12,11]=0.151; termV[12,12]=0.158; - termV[13,0]=0.211; termV[13,1]=0.197; termV[13,2]=0.185; termV[13,3]=0.176; termV[13,4]=0.168; termV[13,5]=0.156; termV[13,6]=0.147; termV[13,7]=0.142; termV[13,8]=0.138; termV[13,9]=0.138; termV[13,10]=0.14; termV[13,11]=0.144; termV[13,12]=0.151; - termV[14,0]=0.204; termV[14,1]=0.192; termV[14,2]=0.18; termV[14,3]=0.171; termV[14,4]=0.164; termV[14,5]=0.152; termV[14,6]=0.143; termV[14,7]=0.138; termV[14,8]=0.134; termV[14,9]=0.134; termV[14,10]=0.137; termV[14,11]=0.14; termV[14,12]=0.148; - termV[15,0]=0.2; termV[15,1]=0.187; termV[15,2]=0.176; termV[15,3]=0.167; termV[15,4]=0.16; termV[15,5]=0.148; termV[15,6]=0.14; termV[15,7]=0.135; termV[15,8]=0.131; termV[15,9]=0.132; termV[15,10]=0.135; termV[15,11]=0.139; termV[15,12]=0.146; + termV[0, 0] = 0.287; termV[0, 1] = 0.274; termV[0, 2] = 0.256; termV[0, 3] = 0.245; termV[0, 4] = 0.227; termV[0, 5] = 0.148; termV[0, 6] = 0.096; termV[0, 7] = 0.09; termV[0, 8] = 0.11; termV[0, 9] = 0.139; termV[0, 10] = 0.166; termV[0, 11] = 0.19; termV[0, 12] = 0.214; + termV[1, 0] = 0.303; termV[1, 1] = 0.258; termV[1, 2] = 0.22; termV[1, 3] = 0.203; termV[1, 4] = 0.19; termV[1, 5] = 0.153; termV[1, 6] = 0.126; termV[1, 7] = 0.118; termV[1, 8] = 0.147; termV[1, 9] = 0.165; termV[1, 10] = 0.18; termV[1, 11] = 0.192; termV[1, 12] = 0.212; + termV[2, 0] = 0.303; termV[2, 1] = 0.257; termV[2, 2] = 0.216; termV[2, 3] = 0.196; termV[2, 4] = 0.182; termV[2, 5] = 0.154; termV[2, 6] = 0.134; termV[2, 7] = 0.127; termV[2, 8] = 0.149; termV[2, 9] = 0.166; termV[2, 10] = 0.18; termV[2, 11] = 0.192; termV[2, 12] = 0.212; + termV[3, 0] = 0.305; termV[3, 1] = 0.266; termV[3, 2] = 0.226; termV[3, 3] = 0.203; termV[3, 4] = 0.19; termV[3, 5] = 0.167; termV[3, 6] = 0.151; termV[3, 7] = 0.144; termV[3, 8] = 0.16; termV[3, 9] = 0.172; termV[3, 10] = 0.183; termV[3, 11] = 0.193; termV[3, 12] = 0.209; + termV[4, 0] = 0.294; termV[4, 1] = 0.261; termV[4, 2] = 0.216; termV[4, 3] = 0.201; termV[4, 4] = 0.19; termV[4, 5] = 0.171; termV[4, 6] = 0.158; termV[4, 7] = 0.151; termV[4, 8] = 0.163; termV[4, 9] = 0.172; termV[4, 10] = 0.181; termV[4, 11] = 0.188; termV[4, 12] = 0.201; + termV[5, 0] = 0.276; termV[5, 1] = 0.248; termV[5, 2] = 0.212; termV[5, 3] = 0.199; termV[5, 4] = 0.189; termV[5, 5] = 0.172; termV[5, 6] = 0.16; termV[5, 7] = 0.155; termV[5, 8] = 0.162; termV[5, 9] = 0.17; termV[5, 10] = 0.177; termV[5, 11] = 0.183; termV[5, 12] = 0.195; + termV[6, 0] = 0.26; termV[6, 1] = 0.237; termV[6, 2] = 0.21; termV[6, 3] = 0.198; termV[6, 4] = 0.188; termV[6, 5] = 0.172; termV[6, 6] = 0.161; termV[6, 7] = 0.156; termV[6, 8] = 0.161; termV[6, 9] = 0.167; termV[6, 10] = 0.173; termV[6, 11] = 0.179; termV[6, 12] = 0.19; + termV[7, 0] = 0.25; termV[7, 1] = 0.231; termV[7, 2] = 0.208; termV[7, 3] = 0.196; termV[7, 4] = 0.187; termV[7, 5] = 0.172; termV[7, 6] = 0.162; termV[7, 7] = 0.156; termV[7, 8] = 0.16; termV[7, 9] = 0.165; termV[7, 10] = 0.17; termV[7, 11] = 0.175; termV[7, 12] = 0.185; + termV[8, 0] = 0.244; termV[8, 1] = 0.226; termV[8, 2] = 0.206; termV[8, 3] = 0.195; termV[8, 4] = 0.186; termV[8, 5] = 0.171; termV[8, 6] = 0.161; termV[8, 7] = 0.156; termV[8, 8] = 0.158; termV[8, 9] = 0.162; termV[8, 10] = 0.166; termV[8, 11] = 0.171; termV[8, 12] = 0.18; + termV[9, 0] = 0.239; termV[9, 1] = 0.222; termV[9, 2] = 0.204; termV[9, 3] = 0.193; termV[9, 4] = 0.185; termV[9, 5] = 0.17; termV[9, 6] = 0.16; termV[9, 7] = 0.155; termV[9, 8] = 0.156; termV[9, 9] = 0.159; termV[9, 10] = 0.163; termV[9, 11] = 0.168; termV[9, 12] = 0.177; + termV[10, 0] = 0.235; termV[10, 1] = 0.219; termV[10, 2] = 0.202; termV[10, 3] = 0.192; termV[10, 4] = 0.183; termV[10, 5] = 0.169; termV[10, 6] = 0.159; termV[10, 7] = 0.154; termV[10, 8] = 0.154; termV[10, 9] = 0.156; termV[10, 10] = 0.16; termV[10, 11] = 0.164; termV[10, 12] = 0.173; + termV[11, 0] = 0.227; termV[11, 1] = 0.212; termV[11, 2] = 0.197; termV[11, 3] = 0.187; termV[11, 4] = 0.179; termV[11, 5] = 0.166; termV[11, 6] = 0.156; termV[11, 7] = 0.151; termV[11, 8] = 0.149; termV[11, 9] = 0.15; termV[11, 10] = 0.153; termV[11, 11] = 0.157; termV[11, 12] = 0.165; + termV[12, 0] = 0.22; termV[12, 1] = 0.206; termV[12, 2] = 0.192; termV[12, 3] = 0.183; termV[12, 4] = 0.175; termV[12, 5] = 0.162; termV[12, 6] = 0.153; termV[12, 7] = 0.147; termV[12, 8] = 0.144; termV[12, 9] = 0.144; termV[12, 10] = 0.147; termV[12, 11] = 0.151; termV[12, 12] = 0.158; + termV[13, 0] = 0.211; termV[13, 1] = 0.197; termV[13, 2] = 0.185; termV[13, 3] = 0.176; termV[13, 4] = 0.168; termV[13, 5] = 0.156; termV[13, 6] = 0.147; termV[13, 7] = 0.142; termV[13, 8] = 0.138; termV[13, 9] = 0.138; termV[13, 10] = 0.14; termV[13, 11] = 0.144; termV[13, 12] = 0.151; + termV[14, 0] = 0.204; termV[14, 1] = 0.192; termV[14, 2] = 0.18; termV[14, 3] = 0.171; termV[14, 4] = 0.164; termV[14, 5] = 0.152; termV[14, 6] = 0.143; termV[14, 7] = 0.138; termV[14, 8] = 0.134; termV[14, 9] = 0.134; termV[14, 10] = 0.137; termV[14, 11] = 0.14; termV[14, 12] = 0.148; + termV[15, 0] = 0.2; termV[15, 1] = 0.187; termV[15, 2] = 0.176; termV[15, 3] = 0.167; termV[15, 4] = 0.16; termV[15, 5] = 0.148; termV[15, 6] = 0.14; termV[15, 7] = 0.135; termV[15, 8] = 0.131; termV[15, 9] = 0.132; termV[15, 10] = 0.135; termV[15, 11] = 0.139; termV[15, 12] = 0.146; capFloorVolSurface = new CapFloorTermVolSurface(0, calendar, BusinessDayConvention.Following, optionTenors, strikes, - termV, dayCounter); - } + termV, dayCounter); + } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testFlatTermVolatilityStripping1() + public void testFlatTermVolatilityStripping1() { - // Testing forward/forward vol stripping from flat term vol + // Testing forward/forward vol stripping from flat term vol // surface using OptionletStripper1 class... CommonVars vars = new CommonVars(); @@ -265,7 +265,7 @@ public void testFlatTermVolatilityStripping1() IborIndex iborIndex = new Euribor6M(vars.yieldTermStructure); OptionletStripper optionletStripper1 = new OptionletStripper1(vars.flatTermVolSurface, - iborIndex,null,vars.accuracy); + iborIndex, null, vars.accuracy); StrippedOptionletAdapter strippedOptionletAdapter = new StrippedOptionletAdapter(optionletStripper1); @@ -273,45 +273,45 @@ public void testFlatTermVolatilityStripping1() vol.link.enableExtrapolation(); - BlackCapFloorEngine strippedVolEngine = new BlackCapFloorEngine(vars.yieldTermStructure,vol); + BlackCapFloorEngine strippedVolEngine = new BlackCapFloorEngine(vars.yieldTermStructure, vol); CapFloor cap; - for (int tenorIndex=0; tenorIndexvars.tolerance) - QAssert.Fail("\noption tenor: " + vars.optionTenors[tenorIndex] + - "\nstrike: " + vars.strikes[strikeIndex] + - "\nstripped vol price: " + priceFromStrippedVolatility + - "\nconstant vol price: " + priceFromConstantVolatility + - "\nerror: " + error + - "\ntolerance: " + vars.tolerance); + if (error > vars.tolerance) + QAssert.Fail("\noption tenor: " + vars.optionTenors[tenorIndex] + + "\nstrike: " + vars.strikes[strikeIndex] + + "\nstripped vol price: " + priceFromStrippedVolatility + + "\nconstant vol price: " + priceFromConstantVolatility + + "\nerror: " + error + + "\ntolerance: " + vars.tolerance); } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testTermVolatilityStripping1() + public void testTermVolatilityStripping1() { - // Testing forward/forward vol stripping from non-flat term + // Testing forward/forward vol stripping from non-flat term // vol surface using OptionletStripper1 class CommonVars vars = new CommonVars(); @@ -321,7 +321,7 @@ public void testTermVolatilityStripping1() IborIndex iborIndex = new Euribor6M(vars.yieldTermStructure); - OptionletStripper optionletStripper1 = new OptionletStripper1(vars.capFloorVolSurface,iborIndex,null,vars.accuracy); + OptionletStripper optionletStripper1 = new OptionletStripper1(vars.capFloorVolSurface, iborIndex, null, vars.accuracy); StrippedOptionletAdapter strippedOptionletAdapter = new StrippedOptionletAdapter(optionletStripper1); @@ -329,46 +329,46 @@ public void testTermVolatilityStripping1() vol.link.enableExtrapolation(); - BlackCapFloorEngine strippedVolEngine = new BlackCapFloorEngine(vars.yieldTermStructure,vol); + BlackCapFloorEngine strippedVolEngine = new BlackCapFloorEngine(vars.yieldTermStructure, vol); CapFloor cap; - - for (int tenorIndex=0; tenorIndexvars.tolerance) + if (error > vars.tolerance) QAssert.Fail("\noption tenor: " + vars.optionTenors[tenorIndex] + - "\nstrike: " + vars.strikes[strikeIndex] + - "\nstripped vol price: " + priceFromStrippedVolatility + - "\nconstant vol price: " + priceFromConstantVolatility + - "\nerror: " + error + - "\ntolerance: " + vars.tolerance); + "\nstrike: " + vars.strikes[strikeIndex] + + "\nstripped vol price: " + priceFromStrippedVolatility + + "\nconstant vol price: " + priceFromConstantVolatility + + "\nerror: " + error + + "\ntolerance: " + vars.tolerance); } - } -} + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testFlatTermVolatilityStripping2() + public void testFlatTermVolatilityStripping2() { - // Testing forward/forward vol stripping from flat term vol + // Testing forward/forward vol stripping from flat term vol // surface using OptionletStripper2 class..."); CommonVars vars = new CommonVars(); @@ -381,7 +381,7 @@ public void testFlatTermVolatilityStripping2() // optionletstripper1 OptionletStripper1 optionletStripper1 = new OptionletStripper1(vars.flatTermVolSurface, - iborIndex,null,vars.accuracy); + iborIndex, null, vars.accuracy); StrippedOptionletAdapter strippedOptionletAdapter1 = new StrippedOptionletAdapter(optionletStripper1); @@ -399,84 +399,84 @@ public void testFlatTermVolatilityStripping2() vol2.link.enableExtrapolation(); // consistency check: diff(stripped vol1-stripped vol2) - for (int strikeIndex=0; strikeIndexvars.tolerance) + double error = Math.Abs(strippedVol1 - strippedVol2); + if (error > vars.tolerance) QAssert.Fail("\noption tenor: " + vars.optionTenors[tenorIndex] + - "\nstrike: " + vars.strikes[strikeIndex] + - "\nstripped vol1: " + strippedVol1 + - "\nstripped vol2: " + strippedVol2 + - "\nflat vol: " + flatVol + - "\nerror: " + error + - "\ntolerance: " + vars.tolerance); + "\nstrike: " + vars.strikes[strikeIndex] + + "\nstripped vol1: " + strippedVol1 + + "\nstripped vol2: " + strippedVol2 + + "\nflat vol: " + flatVol + + "\nerror: " + error + + "\ntolerance: " + vars.tolerance); } } -} + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testTermVolatilityStripping2() + public void testTermVolatilityStripping2() { // Testing forward/forward vol stripping from non-flat term vol " // surface using OptionletStripper2 class..."); - CommonVars vars = new CommonVars(); - Settings.setEvaluationDate(Date.Today); + CommonVars vars = new CommonVars(); + Settings.setEvaluationDate(Date.Today); - vars.setCapFloorTermVolCurve(); - vars.setCapFloorTermVolSurface(); + vars.setCapFloorTermVolCurve(); + vars.setCapFloorTermVolSurface(); - IborIndex iborIndex = new Euribor6M(vars.yieldTermStructure); + IborIndex iborIndex = new Euribor6M(vars.yieldTermStructure); - // optionletstripper1 - OptionletStripper1 optionletStripper1 = new OptionletStripper1(vars.capFloorVolSurface,iborIndex,null,vars.accuracy); - StrippedOptionletAdapter strippedOptionletAdapter1 = new StrippedOptionletAdapter(optionletStripper1); - Handle vol1 = new Handle(strippedOptionletAdapter1); - vol1.link.enableExtrapolation(); + // optionletstripper1 + OptionletStripper1 optionletStripper1 = new OptionletStripper1(vars.capFloorVolSurface, iborIndex, null, vars.accuracy); + StrippedOptionletAdapter strippedOptionletAdapter1 = new StrippedOptionletAdapter(optionletStripper1); + Handle vol1 = new Handle(strippedOptionletAdapter1); + vol1.link.enableExtrapolation(); - // optionletstripper2 - OptionletStripper optionletStripper2 = new OptionletStripper2(optionletStripper1,vars.capFloorVolCurve); - StrippedOptionletAdapter strippedOptionletAdapter2 = new StrippedOptionletAdapter(optionletStripper2); - Handle vol2 = new Handle(strippedOptionletAdapter2); - vol2.link.enableExtrapolation(); + // optionletstripper2 + OptionletStripper optionletStripper2 = new OptionletStripper2(optionletStripper1, vars.capFloorVolCurve); + StrippedOptionletAdapter strippedOptionletAdapter2 = new StrippedOptionletAdapter(optionletStripper2); + Handle vol2 = new Handle(strippedOptionletAdapter2); + vol2.link.enableExtrapolation(); - // consistency check: diff(stripped vol1-stripped vol2) - for (int strikeIndex=0; strikeIndexvars.tolerance) - QAssert.Fail("\noption tenor: " + vars.optionTenors[tenorIndex] + - "\nstrike: " + (vars.strikes[strikeIndex]) + - "\nstripped vol1: " + (strippedVol1) + - "\nstripped vol2: " + (strippedVol2) + - "\nflat vol: " + (flatVol) + - "\nerror: " + (error) + - "\ntolerance: " + (vars.tolerance)); - } - } -} + double flatVol = vars.capFloorVolSurface.volatility(vars.optionTenors[tenorIndex], vars.strikes[strikeIndex], true); + + double error = Math.Abs(strippedVol1 - strippedVol2); + if (error > vars.tolerance) + QAssert.Fail("\noption tenor: " + vars.optionTenors[tenorIndex] + + "\nstrike: " + (vars.strikes[strikeIndex]) + + "\nstripped vol1: " + (strippedVol1) + + "\nstripped vol2: " + (strippedVol2) + + "\nflat vol: " + (flatVol) + + "\nerror: " + (error) + + "\ntolerance: " + (vars.tolerance)); + } + } + } } } diff --git a/tests/QLNet.Tests/T_OvernightIndexedSwap.cs b/tests/QLNet.Tests/T_OvernightIndexedSwap.cs index 76800cfe6..2c6be40dc 100644 --- a/tests/QLNet.Tests/T_OvernightIndexedSwap.cs +++ b/tests/QLNet.Tests/T_OvernightIndexedSwap.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - * + * This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,7 +21,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -34,20 +34,20 @@ public class T_OvernightIndexedSwap : IDisposable { #region Initialize&Cleanup private SavedSettings backup; - #if NET40 || NET45 +#if NET40 || NET45 [TestInitialize] public void testInitialize() { - #else +#else public T_OvernightIndexedSwap() { - #endif +#endif backup = new SavedSettings(); } - #if NET40 || NET45 +#if NET40 || NET45 [TestCleanup] - #endif +#endif public void testCleanup() { Dispose(); @@ -64,7 +64,7 @@ public struct Datum public int n; public TimeUnit unit; public double rate; - }; + } public struct FraDatum { @@ -80,7 +80,7 @@ public FraDatum(int settlementDays_, int nExpiry_, int nMaturity_, double rate_) rate = rate_; } - }; + } public struct SwapDatum { @@ -100,81 +100,85 @@ public SwapDatum(int settlementDays_, int nIndexUnits_, TimeUnit indexUnit_, int rate = rate_; } - }; + } - Datum[] depositData = new Datum[] { - new Datum{ settlementDays = 0, n = 1, unit = TimeUnit.Days, rate = 1.10 }, - new Datum{ settlementDays = 1, n = 1, unit = TimeUnit.Days, rate = 1.10 }, - new Datum{ settlementDays = 2, n = 1, unit = TimeUnit.Weeks, rate = 1.40 }, - new Datum{ settlementDays = 2, n = 2, unit = TimeUnit.Weeks, rate = 1.50 }, - new Datum{ settlementDays = 2, n = 1, unit = TimeUnit.Months, rate = 1.70 }, - new Datum{ settlementDays = 2, n = 2, unit = TimeUnit.Months, rate = 1.90 }, - new Datum{ settlementDays = 2, n = 3, unit = TimeUnit.Months, rate = 2.05 }, - new Datum{ settlementDays = 2, n = 4, unit = TimeUnit.Months, rate = 2.08 }, - new Datum{ settlementDays = 2, n = 5, unit = TimeUnit.Months, rate = 2.11 }, - new Datum{ settlementDays = 2, n = 6, unit = TimeUnit.Months, rate = 2.13 } + Datum[] depositData = new Datum[] + { + new Datum{ settlementDays = 0, n = 1, unit = TimeUnit.Days, rate = 1.10 }, + new Datum{ settlementDays = 1, n = 1, unit = TimeUnit.Days, rate = 1.10 }, + new Datum{ settlementDays = 2, n = 1, unit = TimeUnit.Weeks, rate = 1.40 }, + new Datum{ settlementDays = 2, n = 2, unit = TimeUnit.Weeks, rate = 1.50 }, + new Datum{ settlementDays = 2, n = 1, unit = TimeUnit.Months, rate = 1.70 }, + new Datum{ settlementDays = 2, n = 2, unit = TimeUnit.Months, rate = 1.90 }, + new Datum{ settlementDays = 2, n = 3, unit = TimeUnit.Months, rate = 2.05 }, + new Datum{ settlementDays = 2, n = 4, unit = TimeUnit.Months, rate = 2.08 }, + new Datum{ settlementDays = 2, n = 5, unit = TimeUnit.Months, rate = 2.11 }, + new Datum{ settlementDays = 2, n = 6, unit = TimeUnit.Months, rate = 2.13 } }; - Datum[] eoniaSwapData = new Datum[]{ - new Datum{ settlementDays = 2, n = 1, unit = TimeUnit.Weeks, rate = 1.245 }, - new Datum{ settlementDays = 2,n = 2, unit = TimeUnit.Weeks, rate = 1.269 }, - new Datum{ settlementDays = 2,n = 3, unit = TimeUnit.Weeks, rate = 1.277 }, - new Datum{ settlementDays = 2,n = 1, unit = TimeUnit.Months, rate = 1.281 }, - new Datum{ settlementDays = 2,n = 2, unit = TimeUnit.Months, rate = 1.18 }, - new Datum{ settlementDays = 2,n = 3, unit = TimeUnit.Months, rate = 1.143 }, - new Datum{ settlementDays = 2,n = 4, unit = TimeUnit.Months, rate = 1.125 }, - new Datum{ settlementDays = 2,n = 5, unit = TimeUnit.Months, rate = 1.116 }, - new Datum{ settlementDays = 2,n = 6, unit = TimeUnit.Months, rate = 1.111 }, - new Datum{ settlementDays = 2,n = 7, unit = TimeUnit.Months, rate = 1.109 }, - new Datum{ settlementDays = 2,n = 8, unit = TimeUnit.Months, rate = 1.111 }, - new Datum{ settlementDays = 2,n = 9, unit = TimeUnit.Months, rate = 1.117 }, - new Datum{ settlementDays = 2,n = 10, unit = TimeUnit.Months, rate = 1.129 }, - new Datum{ settlementDays = 2,n = 11, unit = TimeUnit.Months, rate = 1.141 }, - new Datum{ settlementDays = 2,n = 12, unit = TimeUnit.Months, rate = 1.153 }, - new Datum{ settlementDays = 2,n = 15, unit = TimeUnit.Months, rate = 1.218 }, - new Datum{ settlementDays = 2,n = 18, unit = TimeUnit.Months, rate = 1.308 }, - new Datum{ settlementDays = 2,n = 21, unit = TimeUnit.Months, rate = 1.407 }, - new Datum{ settlementDays = 2,n = 2, unit = TimeUnit.Years, rate = 1.510 }, - new Datum{ settlementDays = 2,n = 3, unit = TimeUnit.Years, rate = 1.916 }, - new Datum{ settlementDays = 2,n = 4, unit = TimeUnit.Years, rate = 2.254 }, - new Datum{ settlementDays = 2,n = 5, unit = TimeUnit.Years, rate = 2.523 }, - new Datum{ settlementDays = 2,n = 6, unit = TimeUnit.Years, rate = 2.746 }, - new Datum{ settlementDays = 2,n = 7, unit = TimeUnit.Years, rate = 2.934 }, - new Datum{ settlementDays = 2,n = 8, unit = TimeUnit.Years, rate = 3.092 }, - new Datum{ settlementDays = 2,n = 9, unit = TimeUnit.Years, rate = 3.231 }, - new Datum{ settlementDays = 2,n = 10, unit = TimeUnit.Years, rate = 3.380 }, - new Datum{ settlementDays = 2,n = 11, unit = TimeUnit.Years, rate = 3.457 }, - new Datum{ settlementDays = 2,n = 12, unit = TimeUnit.Years, rate = 3.544 }, - new Datum{ settlementDays = 2,n = 15, unit = TimeUnit.Years, rate = 3.702 }, - new Datum{ settlementDays = 2,n = 20, unit = TimeUnit.Years, rate = 3.703 }, - new Datum{ settlementDays = 2,n = 25, unit = TimeUnit.Years, rate = 3.541 }, - new Datum{ settlementDays = 2,n = 30, unit = TimeUnit.Years, rate = 3.369 } + Datum[] eoniaSwapData = new Datum[] + { + new Datum{ settlementDays = 2, n = 1, unit = TimeUnit.Weeks, rate = 1.245 }, + new Datum{ settlementDays = 2, n = 2, unit = TimeUnit.Weeks, rate = 1.269 }, + new Datum{ settlementDays = 2, n = 3, unit = TimeUnit.Weeks, rate = 1.277 }, + new Datum{ settlementDays = 2, n = 1, unit = TimeUnit.Months, rate = 1.281 }, + new Datum{ settlementDays = 2, n = 2, unit = TimeUnit.Months, rate = 1.18 }, + new Datum{ settlementDays = 2, n = 3, unit = TimeUnit.Months, rate = 1.143 }, + new Datum{ settlementDays = 2, n = 4, unit = TimeUnit.Months, rate = 1.125 }, + new Datum{ settlementDays = 2, n = 5, unit = TimeUnit.Months, rate = 1.116 }, + new Datum{ settlementDays = 2, n = 6, unit = TimeUnit.Months, rate = 1.111 }, + new Datum{ settlementDays = 2, n = 7, unit = TimeUnit.Months, rate = 1.109 }, + new Datum{ settlementDays = 2, n = 8, unit = TimeUnit.Months, rate = 1.111 }, + new Datum{ settlementDays = 2, n = 9, unit = TimeUnit.Months, rate = 1.117 }, + new Datum{ settlementDays = 2, n = 10, unit = TimeUnit.Months, rate = 1.129 }, + new Datum{ settlementDays = 2, n = 11, unit = TimeUnit.Months, rate = 1.141 }, + new Datum{ settlementDays = 2, n = 12, unit = TimeUnit.Months, rate = 1.153 }, + new Datum{ settlementDays = 2, n = 15, unit = TimeUnit.Months, rate = 1.218 }, + new Datum{ settlementDays = 2, n = 18, unit = TimeUnit.Months, rate = 1.308 }, + new Datum{ settlementDays = 2, n = 21, unit = TimeUnit.Months, rate = 1.407 }, + new Datum{ settlementDays = 2, n = 2, unit = TimeUnit.Years, rate = 1.510 }, + new Datum{ settlementDays = 2, n = 3, unit = TimeUnit.Years, rate = 1.916 }, + new Datum{ settlementDays = 2, n = 4, unit = TimeUnit.Years, rate = 2.254 }, + new Datum{ settlementDays = 2, n = 5, unit = TimeUnit.Years, rate = 2.523 }, + new Datum{ settlementDays = 2, n = 6, unit = TimeUnit.Years, rate = 2.746 }, + new Datum{ settlementDays = 2, n = 7, unit = TimeUnit.Years, rate = 2.934 }, + new Datum{ settlementDays = 2, n = 8, unit = TimeUnit.Years, rate = 3.092 }, + new Datum{ settlementDays = 2, n = 9, unit = TimeUnit.Years, rate = 3.231 }, + new Datum{ settlementDays = 2, n = 10, unit = TimeUnit.Years, rate = 3.380 }, + new Datum{ settlementDays = 2, n = 11, unit = TimeUnit.Years, rate = 3.457 }, + new Datum{ settlementDays = 2, n = 12, unit = TimeUnit.Years, rate = 3.544 }, + new Datum{ settlementDays = 2, n = 15, unit = TimeUnit.Years, rate = 3.702 }, + new Datum{ settlementDays = 2, n = 20, unit = TimeUnit.Years, rate = 3.703 }, + new Datum{ settlementDays = 2, n = 25, unit = TimeUnit.Years, rate = 3.541 }, + new Datum{ settlementDays = 2, n = 30, unit = TimeUnit.Years, rate = 3.369 } }; - FraDatum[] fraData = { - new FraDatum( 2, 3, 6, 1.728 ), - new FraDatum( 2, 6, 9, 1.702 ) + FraDatum[] fraData = + { + new FraDatum(2, 3, 6, 1.728), + new FraDatum(2, 6, 9, 1.702) }; - SwapDatum[] swapData = { - new SwapDatum( 2, 3, TimeUnit.Months, 1, TimeUnit.Years, 1.867 ), - new SwapDatum( 2, 3, TimeUnit.Months, 15, TimeUnit.Months, 1.879 ), - new SwapDatum( 2, 3, TimeUnit.Months, 18, TimeUnit.Months, 1.934 ), - new SwapDatum( 2, 3, TimeUnit.Months, 21, TimeUnit.Months, 2.005 ), - new SwapDatum( 2, 3, TimeUnit.Months, 2, TimeUnit.Years, 2.091 ), - new SwapDatum( 2, 3, TimeUnit.Months, 3, TimeUnit.Years, 2.435 ), - new SwapDatum( 2, 3, TimeUnit.Months, 4, TimeUnit.Years, 2.733 ), - new SwapDatum( 2, 3, TimeUnit.Months, 5, TimeUnit.Years, 2.971 ), - new SwapDatum( 2, 3, TimeUnit.Months, 6, TimeUnit.Years, 3.174 ), - new SwapDatum( 2, 3, TimeUnit.Months, 7, TimeUnit.Years, 3.345 ), - new SwapDatum( 2, 3, TimeUnit.Months, 8, TimeUnit.Years, 3.491 ), - new SwapDatum( 2, 3, TimeUnit.Months, 9, TimeUnit.Years, 3.620 ), - new SwapDatum( 2, 3, TimeUnit.Months, 10, TimeUnit.Years, 3.733 ), - new SwapDatum( 2, 3, TimeUnit.Months, 12, TimeUnit.Years, 3.910 ), - new SwapDatum( 2, 3, TimeUnit.Months, 15, TimeUnit.Years, 4.052 ), - new SwapDatum( 2, 3, TimeUnit.Months, 20, TimeUnit.Years, 4.073 ), - new SwapDatum( 2, 3, TimeUnit.Months, 25, TimeUnit.Years, 3.844 ), - new SwapDatum( 2, 3, TimeUnit.Months, 30, TimeUnit.Years, 3.687 ) + SwapDatum[] swapData = + { + new SwapDatum(2, 3, TimeUnit.Months, 1, TimeUnit.Years, 1.867), + new SwapDatum(2, 3, TimeUnit.Months, 15, TimeUnit.Months, 1.879), + new SwapDatum(2, 3, TimeUnit.Months, 18, TimeUnit.Months, 1.934), + new SwapDatum(2, 3, TimeUnit.Months, 21, TimeUnit.Months, 2.005), + new SwapDatum(2, 3, TimeUnit.Months, 2, TimeUnit.Years, 2.091), + new SwapDatum(2, 3, TimeUnit.Months, 3, TimeUnit.Years, 2.435), + new SwapDatum(2, 3, TimeUnit.Months, 4, TimeUnit.Years, 2.733), + new SwapDatum(2, 3, TimeUnit.Months, 5, TimeUnit.Years, 2.971), + new SwapDatum(2, 3, TimeUnit.Months, 6, TimeUnit.Years, 3.174), + new SwapDatum(2, 3, TimeUnit.Months, 7, TimeUnit.Years, 3.345), + new SwapDatum(2, 3, TimeUnit.Months, 8, TimeUnit.Years, 3.491), + new SwapDatum(2, 3, TimeUnit.Months, 9, TimeUnit.Years, 3.620), + new SwapDatum(2, 3, TimeUnit.Months, 10, TimeUnit.Years, 3.733), + new SwapDatum(2, 3, TimeUnit.Months, 12, TimeUnit.Years, 3.910), + new SwapDatum(2, 3, TimeUnit.Months, 15, TimeUnit.Years, 4.052), + new SwapDatum(2, 3, TimeUnit.Months, 20, TimeUnit.Years, 4.073), + new SwapDatum(2, 3, TimeUnit.Months, 25, TimeUnit.Years, 3.844), + new SwapDatum(2, 3, TimeUnit.Months, 30, TimeUnit.Years, 3.687) }; public class CommonVars @@ -200,17 +204,17 @@ public class CommonVars // utilities public OvernightIndexedSwap makeSwap(Period length, - double fixedRate, - double spread) + double fixedRate, + double spread) { return new MakeOIS(length, eoniaIndex, fixedRate) - .withEffectiveDate(settlement) - .withOvernightLegSpread(spread) - .withNominal(nominal) - .withDiscountingTermStructure(eoniaTermStructure); + .withEffectiveDate(settlement) + .withOvernightLegSpread(spread) + .withNominal(nominal) + .withDiscountingTermStructure(eoniaTermStructure); } - - public CommonVars() + + public CommonVars() { type = OvernightIndexedSwap.Type.Payer; settlementDays = 2; @@ -229,16 +233,16 @@ public CommonVars() today = new Date(5, Month.February, 2009); //today = calendar.adjust(Date::todaysDate()); Settings.setEvaluationDate(today); - settlement = calendar.advance(today,new Period(settlementDays,TimeUnit.Days),BusinessDayConvention.Following); - eoniaTermStructure.linkTo(Utilities.flatRate(settlement, 0.05,new Actual365Fixed())); - } + settlement = calendar.advance(today, new Period(settlementDays, TimeUnit.Days), BusinessDayConvention.Following); + eoniaTermStructure.linkTo(Utilities.flatRate(settlement, 0.05, new Actual365Fixed())); + } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testFairRate() { @@ -261,10 +265,10 @@ public void testFairRate() { QAssert.Fail("recalculating with implied rate:\n" - + " length: " + lengths[i] + " \n" - + " floating spread: " - + (spreads[j]) + "\n" - + " swap value: " + swap.NPV()); + + " length: " + lengths[i] + " \n" + + " floating spread: " + + (spreads[j]) + "\n" + + " swap value: " + swap.NPV()); } } @@ -272,33 +276,34 @@ public void testFairRate() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testFairSpread() + public void testFairSpread() { // Testing Eonia-swap calculation of fair floating spread... CommonVars vars = new CommonVars(); - Period[] lengths = { new Period(1,TimeUnit.Years), - new Period(2,TimeUnit.Years), - new Period(5,TimeUnit.Years), - new Period(10,TimeUnit.Years), - new Period(20,TimeUnit.Years) }; + Period[] lengths = { new Period(1, TimeUnit.Years), + new Period(2, TimeUnit.Years), + new Period(5, TimeUnit.Years), + new Period(10, TimeUnit.Years), + new Period(20, TimeUnit.Years) + }; double[] rates = { 0.04, 0.05, 0.06, 0.07 }; - for (int i=0; i 1.0e-10) + if (Math.Abs(swap.NPV()) > 1.0e-10) { - QAssert.Fail("Recalculating with implied spread:" + + QAssert.Fail("Recalculating with implied spread:" + "\n length: " + lengths[i] + "\n fixed rate: " + rates[j] + "\nfair spread: " + fairSpread + @@ -309,37 +314,37 @@ public void testFairSpread() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testCachedValue() + public void testCachedValue() { // Testing Eonia-swap calculation against cached value... CommonVars vars = new CommonVars(); Settings.setEvaluationDate(vars.today); - vars.settlement = vars.calendar.advance(vars.today,vars.settlementDays,TimeUnit.Days); + vars.settlement = vars.calendar.advance(vars.today, vars.settlementDays, TimeUnit.Days); double flat = 0.05; - vars.eoniaTermStructure.linkTo(Utilities.flatRate(vars.settlement,flat,new Actual360())); + vars.eoniaTermStructure.linkTo(Utilities.flatRate(vars.settlement, flat, new Actual360())); double fixedRate = Math.Exp(flat) - 1; - OvernightIndexedSwap swap = vars.makeSwap(new Period(1,TimeUnit.Years), fixedRate, 0.0); + OvernightIndexedSwap swap = vars.makeSwap(new Period(1, TimeUnit.Years), fixedRate, 0.0); double cachedNPV = 0.001730450147; double tolerance = 1.0e-11; - - if (Math.Abs(swap.NPV()-cachedNPV) > tolerance) + + if (Math.Abs(swap.NPV() - cachedNPV) > tolerance) QAssert.Fail("\nfailed to reproduce cached swap value:" + - "\ncalculated: " + swap.NPV() + - "\n expected: " + cachedNPV + - "\n tolerance:" + tolerance); + "\ncalculated: " + swap.NPV() + + "\n expected: " + cachedNPV + + "\n tolerance:" + tolerance); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testBootstrap() + public void testBootstrap() { // Testing Eonia-swap curve building... CommonVars vars = new CommonVars(); @@ -350,106 +355,106 @@ public void testBootstrap() IborIndex euribor3m = new Euribor3M(); Eonia eonia = new Eonia(); - for (int i = 0; i < depositData.Length; i++) + for (int i = 0; i < depositData.Length; i++) { double rate = 0.01 * depositData[i].rate; SimpleQuote simple = new SimpleQuote(rate); Handle quote = new Handle(simple); - Period term = new Period(depositData[i].n , depositData[i].unit); + Period term = new Period(depositData[i].n, depositData[i].unit); RateHelper helper = new DepositRateHelper(quote, - term, - depositData[i].settlementDays, - euribor3m.fixingCalendar(), - euribor3m.businessDayConvention(), - euribor3m.endOfMonth(), - euribor3m.dayCounter()); - - - if (term <= new Period(2,TimeUnit.Days)) + term, + depositData[i].settlementDays, + euribor3m.fixingCalendar(), + euribor3m.businessDayConvention(), + euribor3m.endOfMonth(), + euribor3m.dayCounter()); + + + if (term <= new Period(2, TimeUnit.Days)) eoniaHelpers.Add(helper); - if (term <= new Period(3,TimeUnit.Months)) + if (term <= new Period(3, TimeUnit.Months)) swap3mHelpers.Add(helper); } - for (int i = 0; i < fraData.Length; i++) + for (int i = 0; i < fraData.Length; i++) { - + double rate = 0.01 * fraData[i].rate; SimpleQuote simple = new SimpleQuote(rate); Handle quote = new Handle(simple); RateHelper helper = new FraRateHelper(quote, - fraData[i].nExpiry, - fraData[i].nMaturity, - fraData[i].settlementDays, - euribor3m.fixingCalendar(), - euribor3m.businessDayConvention(), - euribor3m.endOfMonth(), - euribor3m.dayCounter()); + fraData[i].nExpiry, + fraData[i].nMaturity, + fraData[i].settlementDays, + euribor3m.fixingCalendar(), + euribor3m.businessDayConvention(), + euribor3m.endOfMonth(), + euribor3m.dayCounter()); swap3mHelpers.Add(helper); } - for (int i = 0; i < eoniaSwapData.Length; i++) + for (int i = 0; i < eoniaSwapData.Length; i++) { - + double rate = 0.01 * eoniaSwapData[i].rate; SimpleQuote simple = new SimpleQuote(rate); Handle quote = new Handle(simple); - Period term = new Period(eoniaSwapData[i].n , eoniaSwapData[i].unit); + Period term = new Period(eoniaSwapData[i].n, eoniaSwapData[i].unit); RateHelper helper = new OISRateHelper(eoniaSwapData[i].settlementDays, - term, - quote, - eonia); + term, + quote, + eonia); eoniaHelpers.Add(helper); } - for (int i = 0; i < swapData.Length; i++) + for (int i = 0; i < swapData.Length; i++) { double rate = 0.01 * swapData[i].rate; SimpleQuote simple = new SimpleQuote(rate); Handle quote = new Handle(simple); - Period tenor = new Period(swapData[i].nIndexUnits , swapData[i].indexUnit); - Period term = new Period(swapData[i].nTermUnits , swapData[i].termUnit); + Period tenor = new Period(swapData[i].nIndexUnits, swapData[i].indexUnit); + Period term = new Period(swapData[i].nTermUnits, swapData[i].termUnit); RateHelper helper = new SwapRateHelper(quote, - term, - vars.calendar, - vars.fixedSwapFrequency, - vars.fixedSwapConvention, - vars.fixedSwapDayCount, - euribor3m); - if (tenor == new Period(3,TimeUnit.Months)) + term, + vars.calendar, + vars.fixedSwapFrequency, + vars.fixedSwapConvention, + vars.fixedSwapDayCount, + euribor3m); + if (tenor == new Period(3, TimeUnit.Months)) swap3mHelpers.Add(helper); } - PiecewiseYieldCurve eoniaTS = new PiecewiseYieldCurve(vars.today, - eoniaHelpers, - new Actual365Fixed()); + PiecewiseYieldCurve eoniaTS = new PiecewiseYieldCurve(vars.today, + eoniaHelpers, + new Actual365Fixed()); - PiecewiseYieldCurve swapTS = new PiecewiseYieldCurve(vars.today, - swap3mHelpers, - new Actual365Fixed()); + PiecewiseYieldCurve swapTS = new PiecewiseYieldCurve(vars.today, + swap3mHelpers, + new Actual365Fixed()); vars.eoniaTermStructure.linkTo(eoniaTS); // test curve consistency double tolerance = 1.0e-10; - for (int i = 0; i < eoniaSwapData.Length; i++) + for (int i = 0; i < eoniaSwapData.Length; i++) { - + double expected = eoniaSwapData[i].rate; - Period term = new Period(eoniaSwapData[i].n , eoniaSwapData[i].unit); + Period term = new Period(eoniaSwapData[i].n, eoniaSwapData[i].unit); OvernightIndexedSwap swap = vars.makeSwap(term, 0.0, 0.0); double? calculated = 100.0 * swap.fairRate(); - if (Math.Abs(expected-calculated.Value) > tolerance) + if (Math.Abs(expected - calculated.Value) > tolerance) QAssert.Fail("curve inconsistency:\n" - + " swap length: " + term + "\n" - + " quoted rate: " + expected + "\n" - + " calculated rate: " + calculated); + + " swap length: " + term + "\n" + + " quoted rate: " + expected + "\n" + + " calculated rate: " + calculated); } } } diff --git a/tests/QLNet.Tests/T_PSACurve.cs b/tests/QLNet.Tests/T_PSACurve.cs index b127ee68b..d0f40b95e 100644 --- a/tests/QLNet.Tests/T_PSACurve.cs +++ b/tests/QLNet.Tests/T_PSACurve.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,7 +19,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -31,9 +31,9 @@ namespace TestSuite public class T_PSACurve { #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testCashedValues() { @@ -41,25 +41,26 @@ public void testCashedValues() Date startDate = new Date(01, 03, 2007); Period period = new Period(360, TimeUnit.Months); Calendar calendar = new TARGET(); - Date endDate = calendar.advance(startDate,period,BusinessDayConvention.Unadjusted); + Date endDate = calendar.advance(startDate, period, BusinessDayConvention.Unadjusted); - Schedule schedule = new Schedule( startDate, endDate, new Period(1,TimeUnit.Months), calendar, - BusinessDayConvention.Unadjusted, - BusinessDayConvention.Unadjusted, - DateGeneration.Rule.Backward, false); + Schedule schedule = new Schedule(startDate, endDate, new Period(1, TimeUnit.Months), calendar, + BusinessDayConvention.Unadjusted, + BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, false); // PSA 100% PSACurve psa100 = new PSACurve(startDate); - double[] listCPR = {0.2000,0.4000,0.6000,0.8000,1.0000,1.2000,1.4000,1.6000,1.8000,2.0000,2.2000,2.4000,2.6000,2.8000, - 3.0000,3.2000,3.4000,3.6000,3.8000,4.0000,4.2000,4.4000,4.6000,4.8000,5.0000,5.2000,5.4000,5.6000, - 5.8000,6.0000}; + double[] listCPR = {0.2000, 0.4000, 0.6000, 0.8000, 1.0000, 1.2000, 1.4000, 1.6000, 1.8000, 2.0000, 2.2000, 2.4000, 2.6000, 2.8000, + 3.0000, 3.2000, 3.4000, 3.6000, 3.8000, 4.0000, 4.2000, 4.4000, 4.6000, 4.8000, 5.0000, 5.2000, 5.4000, 5.6000, + 5.8000, 6.0000 + }; for (int i = 0; i < schedule.Count; i++) { - if ( i <= 29 ) - QAssert.AreEqual(listCPR[i], psa100.getCPR(schedule[i])*100,0.001); + if (i <= 29) + QAssert.AreEqual(listCPR[i], psa100.getCPR(schedule[i]) * 100, 0.001); else - QAssert.AreEqual(6.0000, psa100.getCPR(schedule[i])*100); + QAssert.AreEqual(6.0000, psa100.getCPR(schedule[i]) * 100); } diff --git a/tests/QLNet.Tests/T_PathGenerator.cs b/tests/QLNet.Tests/T_PathGenerator.cs index 58750f17b..c8dd34184 100644 --- a/tests/QLNet.Tests/T_PathGenerator.cs +++ b/tests/QLNet.Tests/T_PathGenerator.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,7 +22,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -32,290 +32,310 @@ namespace TestSuite [TestClass()] #endif public class T_Pathgenerator : IDisposable - { - #region Initialize&Cleanup - private SavedSettings backup; - #if NET40 || NET45 - [TestInitialize] - public void testInitialize() - { - #else - public T_Pathgenerator() - { - #endif - - backup = new SavedSettings(); - } - #if NET40 || NET45 - [TestCleanup] - #endif - public void testCleanup() - { - Dispose(); - } - public void Dispose() - { - backup.Dispose(); - } - #endregion - - public void testSingle(StochasticProcess1D process, - string tag, - bool brownianBridge, - double expected, - double antithetic) - { - ulong seed = 42; - double length = 10; - int timeSteps = 12; - - var rsg = (InverseCumulativeRsg - ,InverseCumulativeNormal>) - new PseudoRandom().make_sequence_generator(timeSteps, seed); - - - - PathGenerator generator = new PathGenerator(process, - length, - timeSteps, - rsg, - brownianBridge); - int i; - for (i=0; i<100; i++) - generator.next(); - - Sample sample = generator.next(); - Path value = sample.value as Path; - Utils.QL_REQUIRE(value != null ,()=> "Invalid Path"); - double calculated = value.back(); - double error = Math.Abs(calculated-expected); - double tolerance = 2.0e-8; - if (error > tolerance) + { + #region Initialize&Cleanup + private SavedSettings backup; +#if NET40 || NET45 + [TestInitialize] + public void testInitialize() + { +#else + public T_Pathgenerator() + { +#endif + + backup = new SavedSettings(); + } +#if NET40 || NET45 + [TestCleanup] +#endif + public void testCleanup() + { + Dispose(); + } + public void Dispose() + { + backup.Dispose(); + } + #endregion + + public void testSingle(StochasticProcess1D process, + string tag, + bool brownianBridge, + double expected, + double antithetic) + { + ulong seed = 42; + double length = 10; + int timeSteps = 12; + + var rsg = (InverseCumulativeRsg + , InverseCumulativeNormal>) + new PseudoRandom().make_sequence_generator(timeSteps, seed); + + + + PathGenerator generator = new PathGenerator(process, + length, + timeSteps, + rsg, + brownianBridge); + int i; + for (i = 0; i < 100; i++) + generator.next(); + + Sample sample = generator.next(); + Path value = sample.value as Path; + Utils.QL_REQUIRE(value != null, () => "Invalid Path"); + double calculated = value.back(); + double error = Math.Abs(calculated - expected); + double tolerance = 2.0e-8; + if (error > tolerance) + { + QAssert.Fail("using " + tag + " process " + + (brownianBridge ? "with " : "without ") + + "brownian bridge:\n" + //+ std::setprecision(13) + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " error: " + error + "\n" + + " tolerance: " + tolerance); + } + + sample = generator.antithetic(); + value = sample.value as Path; + Utils.QL_REQUIRE(value != null, () => "Invalid Path"); + calculated = value.back(); + error = Math.Abs(calculated - antithetic); + tolerance = 2.0e-7; + if (error > tolerance) + { + QAssert.Fail("using " + tag + " process " + + (brownianBridge ? "with " : "without ") + + "brownian bridge:\n" + + "antithetic sample:\n" + //+ setprecision(13) + + " calculated: " + calculated + "\n" + + " expected: " + antithetic + "\n" + + " error: " + error + "\n" + + " tolerance: " + tolerance); + } + } + + public void testMultiple(StochasticProcess process, + string tag, + double[] expected, + double[] antithetic) + { + + + ulong seed = 42; + double length = 10; + int timeSteps = 12; + int assets = process.size(); + + var rsg = (InverseCumulativeRsg + , InverseCumulativeNormal>) + new PseudoRandom().make_sequence_generator(timeSteps * assets, seed); + + MultiPathGenerator generator = new MultiPathGenerator(process, + new TimeGrid(length, timeSteps), + rsg, false); + int i; + for (i = 0; i < 100; i++) + generator.next(); + + Sample sample = generator.next(); + MultiPath value = sample.value as MultiPath; + Utils.QL_REQUIRE(value != null, () => "Invalid Path"); + Vector calculated = new Vector(assets); + double error, tolerance = 2.0e-7; + + for (int j = 0; j < assets; j++) + calculated[j] = value[j].back() ; + + for (int j = 0; j < assets; j++) + { + error = Math.Abs(calculated[j] - expected[j]); + if (error > tolerance) { - QAssert.Fail("using " + tag + " process " - + (brownianBridge ? "with " : "without ") - + "brownian bridge:\n" + QAssert.Fail("using " + tag + " process " + + "(" + j + 1 + " asset:)\n" //+ std::setprecision(13) - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" + + " calculated: " + calculated[j] + "\n" + + " expected: " + expected[j] + "\n" + " error: " + error + "\n" + " tolerance: " + tolerance); } + } - sample = generator.antithetic(); - value = sample.value as Path; - Utils.QL_REQUIRE( value != null, () => "Invalid Path" ); - calculated = value.back(); - error = Math.Abs(calculated-antithetic); - tolerance = 2.0e-7; - if (error > tolerance) + sample = generator.antithetic(); + value = sample.value as MultiPath; + Utils.QL_REQUIRE(value != null, () => "Invalid Path"); + for (int j = 0; j < assets; j++) + calculated[j] = value[j].back(); + for (int j = 0; j < assets; j++) + { + error = Math.Abs(calculated[j] - antithetic[j]); + if (error > tolerance) { - QAssert.Fail("using " + tag + " process " - + (brownianBridge ? "with " : "without ") - + "brownian bridge:\n" - + "antithetic sample:\n" - //+ setprecision(13) - + " calculated: " + calculated + "\n" - + " expected: " + antithetic + "\n" - + " error: " + error + "\n" - + " tolerance: " + tolerance); - } - } - - public void testMultiple(StochasticProcess process, - string tag, - double[] expected, - double[] antithetic ) - { - - - ulong seed = 42; - double length = 10; - int timeSteps = 12; - int assets = process.size(); - - var rsg = (InverseCumulativeRsg - ,InverseCumulativeNormal>) - new PseudoRandom().make_sequence_generator(timeSteps*assets, seed); - - MultiPathGenerator generator=new MultiPathGenerator(process, - new TimeGrid(length, timeSteps), - rsg, false); - int i; - for (i=0; i<100; i++) - generator.next(); - - Sample sample = generator.next(); - MultiPath value = sample.value as MultiPath; - Utils.QL_REQUIRE( value != null, () => "Invalid Path" ); - Vector calculated = new Vector(assets); - double error, tolerance = 2.0e-7; - - for (int j=0; j tolerance) { - QAssert.Fail("using " + tag + " process " - + "(" + j+1 + " asset:)\n" - //+ std::setprecision(13) - + " calculated: " + calculated[j] + "\n" - + " expected: " + expected[j] + "\n" - + " error: " + error + "\n" - + " tolerance: " + tolerance); - } + QAssert.Fail("using " + tag + " process " + + "(" + j + 1 + " asset:)\n" + + "antithetic sample:\n" + //+ std::setprecision(13) + + " calculated: " + calculated[j] + "\n" + + " expected: " + antithetic[j] + "\n" + + " error: " + error + "\n" + + " tolerance: " + tolerance); } + } + } - sample = generator.antithetic(); - value = sample.value as MultiPath; - Utils.QL_REQUIRE( value != null, () => "Invalid Path" ); - for (int j=0; j tolerance) { - QAssert.Fail("using " + tag + " process " - + "(" + j+1 + " asset:)\n" - + "antithetic sample:\n" - //+ std::setprecision(13) - + " calculated: " + calculated[j] + "\n" - + " expected: " + antithetic[j] + "\n" - + " error: " + error + "\n" - + " tolerance: " + tolerance); - } - } - } - - #if NET40 || NET45 - [TestCategory( "LongRun" ), TestMethod()] - #else - [Fact(Skip = "LongRun")] - #endif - public void testPathGenerator() - { - // Testing 1-D path generation against cached values - Settings.setEvaluationDate(new Date(26,4,2005)); - - Handle x0=new Handle (new SimpleQuote(100.0)); - Handle r =new Handle (Utilities.flatRate(0.05, new Actual360())); - Handle q=new Handle (Utilities.flatRate(0.02, new Actual360())); - Handle sigma = new Handle(Utilities.flatVol(0.20, new Actual360())); - // commented values must be used when Halley's correction is enabled - testSingle( new BlackScholesMertonProcess(x0,q,r,sigma), - "Black-Scholes", false, 26.13784357783, 467.2928561411); - // 26.13784357783, 467.2928562519); - //Error make the borwnian bridge test first - testSingle(new BlackScholesMertonProcess(x0,q,r,sigma), - "Black-Scholes", true, 60.28215549393, 202.6143139999); - // 60.28215551021, 202.6143139437); - - testSingle(new GeometricBrownianMotionProcess(100.0, 0.03, 0.20), - "geometric Brownian", false, 27.62223714065, 483.6026514084); - // 27.62223714065, 483.602651493); - - testSingle(new OrnsteinUhlenbeckProcess(0.1, 0.20), - "Ornstein-Uhlenbeck", false, -0.8372003433557, 0.8372003433557); - - testSingle(new SquareRootProcess(0.1, 0.1, 0.20, 10.0), - "square-root", false, 1.70608664108, 6.024200546031); - } - - #if NET40 || NET45 - [TestCategory( "LongRun" ), TestMethod()] - #else - [Fact(Skip = "LongRun")] - #endif - public void testMultiPathGenerator() - { - // Testing n-D path generation against cached values - Settings.setEvaluationDate(new Date(26,4,2005)); - - Handle x0=new Handle (new SimpleQuote(100.0)); - Handle r =new Handle (Utilities.flatRate(0.05, new Actual360())); - Handle q=new Handle (Utilities.flatRate(0.02, new Actual360())); - Handle sigma=new Handle (Utilities.flatVol(0.20, new Actual360())); - - Matrix correlation=new Matrix(3,3); - correlation[0,0] = 1.0; correlation[0,1] = 0.9; correlation[0,2] = 0.7; - correlation[1,0] = 0.9; correlation[1,1] = 1.0; correlation[1,2] = 0.4; - correlation[2,0] = 0.7; correlation[2,1] = 0.4; correlation[2,2] = 1.0; - - List processes = new List(3); - StochasticProcess process; - - processes.Add(new BlackScholesMertonProcess(x0,q,r,sigma)); - processes.Add(new BlackScholesMertonProcess(x0,q,r,sigma)); - processes.Add(new BlackScholesMertonProcess(x0,q,r,sigma)); - process = new StochasticProcessArray(processes,correlation); - // commented values must be used when Halley's correction is enabled - double[] result1 = { - 188.2235868185, - 270.6713069569, - 113.0431145652 }; - // Real result1[] = { - // 188.2235869273, - // 270.6713071508, - // 113.0431145652 }; - double[] result1a = { - 64.89105742957, - 45.12494404804, - 108.0475146914 }; - // Real result1a[] = { - // 64.89105739157, - // 45.12494401537, - // 108.0475146914 }; - testMultiple(process, "Black-Scholes", result1, result1a); - - processes[0] = new GeometricBrownianMotionProcess(100.0, 0.03, 0.20); - processes[1] = new GeometricBrownianMotionProcess(100.0, 0.03, 0.20); - processes[2] = new GeometricBrownianMotionProcess(100.0, 0.03, 0.20); - process = new StochasticProcessArray(processes,correlation); - double[] result2 = { - 174.8266131680, - 237.2692443633, - 119.1168555440 }; - // Real result2[] = { - // 174.8266132344, - // 237.2692444869, - // 119.1168555605 }; - double[] result2a = { - 57.69082393020, - 38.50016862915, - 116.4056510107 }; - // Real result2a[] = { - // 57.69082387657, - // 38.50016858691, - // 116.4056510107 }; - testMultiple(process, "geometric Brownian", result2, result2a); - - processes[0] = new OrnsteinUhlenbeckProcess(0.1, 0.20); - processes[1] = new OrnsteinUhlenbeckProcess(0.1, 0.20); - processes[2] = new OrnsteinUhlenbeckProcess(0.1, 0.20); - process = new StochasticProcessArray(processes,correlation); - double[] result3 = { - 0.2942058437284, - 0.5525006418386, - 0.02650931054575 }; - double[] result3a = { - -0.2942058437284, - -0.5525006418386, - -0.02650931054575 }; - testMultiple(process, "Ornstein-Uhlenbeck", result3, result3a); - - processes[0] = new SquareRootProcess(0.1, 0.1, 0.20, 10.0); - processes[1] = new SquareRootProcess(0.1, 0.1, 0.20, 10.0); - processes[2] = new SquareRootProcess(0.1, 0.1, 0.20, 10.0); - process = new StochasticProcessArray(processes,correlation); - double[] result4 = { - 4.279510844897, - 4.943783503533, - 3.590930385958 }; - double[] result4a = { - 2.763967737724, - 2.226487196647, - 3.503859264341 }; - testMultiple(process, "square-root", result4, result4a); - } - } +#if NET40 || NET45 + [TestCategory("LongRun"), TestMethod()] +#else + [Fact(Skip = "LongRun")] +#endif + public void testPathGenerator() + { + // Testing 1-D path generation against cached values + Settings.setEvaluationDate(new Date(26, 4, 2005)); + + Handle x0 = new Handle (new SimpleQuote(100.0)); + Handle r = new Handle (Utilities.flatRate(0.05, new Actual360())); + Handle q = new Handle (Utilities.flatRate(0.02, new Actual360())); + Handle sigma = new Handle(Utilities.flatVol(0.20, new Actual360())); + // commented values must be used when Halley's correction is enabled + testSingle(new BlackScholesMertonProcess(x0, q, r, sigma), + "Black-Scholes", false, 26.13784357783, 467.2928561411); + // 26.13784357783, 467.2928562519); + //Error make the borwnian bridge test first + testSingle(new BlackScholesMertonProcess(x0, q, r, sigma), + "Black-Scholes", true, 60.28215549393, 202.6143139999); + // 60.28215551021, 202.6143139437); + + testSingle(new GeometricBrownianMotionProcess(100.0, 0.03, 0.20), + "geometric Brownian", false, 27.62223714065, 483.6026514084); + // 27.62223714065, 483.602651493); + + testSingle(new OrnsteinUhlenbeckProcess(0.1, 0.20), + "Ornstein-Uhlenbeck", false, -0.8372003433557, 0.8372003433557); + + testSingle(new SquareRootProcess(0.1, 0.1, 0.20, 10.0), + "square-root", false, 1.70608664108, 6.024200546031); + } + +#if NET40 || NET45 + [TestCategory("LongRun"), TestMethod()] +#else + [Fact(Skip = "LongRun")] +#endif + public void testMultiPathGenerator() + { + // Testing n-D path generation against cached values + Settings.setEvaluationDate(new Date(26, 4, 2005)); + + Handle x0 = new Handle (new SimpleQuote(100.0)); + Handle r = new Handle (Utilities.flatRate(0.05, new Actual360())); + Handle q = new Handle (Utilities.flatRate(0.02, new Actual360())); + Handle sigma = new Handle (Utilities.flatVol(0.20, new Actual360())); + + Matrix correlation = new Matrix(3, 3); + correlation[0, 0] = 1.0; correlation[0, 1] = 0.9; correlation[0, 2] = 0.7; + correlation[1, 0] = 0.9; correlation[1, 1] = 1.0; correlation[1, 2] = 0.4; + correlation[2, 0] = 0.7; correlation[2, 1] = 0.4; correlation[2, 2] = 1.0; + + List processes = new List(3); + StochasticProcess process; + + processes.Add(new BlackScholesMertonProcess(x0, q, r, sigma)); + processes.Add(new BlackScholesMertonProcess(x0, q, r, sigma)); + processes.Add(new BlackScholesMertonProcess(x0, q, r, sigma)); + process = new StochasticProcessArray(processes, correlation); + // commented values must be used when Halley's correction is enabled + double[] result1 = + { + 188.2235868185, + 270.6713069569, + 113.0431145652 + }; + // Real result1[] = { + // 188.2235869273, + // 270.6713071508, + // 113.0431145652 }; + double[] result1a = + { + 64.89105742957, + 45.12494404804, + 108.0475146914 + }; + // Real result1a[] = { + // 64.89105739157, + // 45.12494401537, + // 108.0475146914 }; + testMultiple(process, "Black-Scholes", result1, result1a); + + processes[0] = new GeometricBrownianMotionProcess(100.0, 0.03, 0.20); + processes[1] = new GeometricBrownianMotionProcess(100.0, 0.03, 0.20); + processes[2] = new GeometricBrownianMotionProcess(100.0, 0.03, 0.20); + process = new StochasticProcessArray(processes, correlation); + double[] result2 = + { + 174.8266131680, + 237.2692443633, + 119.1168555440 + }; + // Real result2[] = { + // 174.8266132344, + // 237.2692444869, + // 119.1168555605 }; + double[] result2a = + { + 57.69082393020, + 38.50016862915, + 116.4056510107 + }; + // Real result2a[] = { + // 57.69082387657, + // 38.50016858691, + // 116.4056510107 }; + testMultiple(process, "geometric Brownian", result2, result2a); + + processes[0] = new OrnsteinUhlenbeckProcess(0.1, 0.20); + processes[1] = new OrnsteinUhlenbeckProcess(0.1, 0.20); + processes[2] = new OrnsteinUhlenbeckProcess(0.1, 0.20); + process = new StochasticProcessArray(processes, correlation); + double[] result3 = + { + 0.2942058437284, + 0.5525006418386, + 0.02650931054575 + }; + double[] result3a = + { + -0.2942058437284, + -0.5525006418386, + -0.02650931054575 + }; + testMultiple(process, "Ornstein-Uhlenbeck", result3, result3a); + + processes[0] = new SquareRootProcess(0.1, 0.1, 0.20, 10.0); + processes[1] = new SquareRootProcess(0.1, 0.1, 0.20, 10.0); + processes[2] = new SquareRootProcess(0.1, 0.1, 0.20, 10.0); + process = new StochasticProcessArray(processes, correlation); + double[] result4 = + { + 4.279510844897, + 4.943783503533, + 3.590930385958 + }; + double[] result4a = + { + 2.763967737724, + 2.226487196647, + 3.503859264341 + }; + testMultiple(process, "square-root", result4, result4a); + } + } } diff --git a/tests/QLNet.Tests/T_PiecewiseZeroSpreadedTermStructure.cs b/tests/QLNet.Tests/T_PiecewiseZeroSpreadedTermStructure.cs index 960011dc5..50525da42 100644 --- a/tests/QLNet.Tests/T_PiecewiseZeroSpreadedTermStructure.cs +++ b/tests/QLNet.Tests/T_PiecewiseZeroSpreadedTermStructure.cs @@ -1,17 +1,17 @@ /* - Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,7 +23,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -79,9 +79,9 @@ public CommonVars() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testFlatInterpolationLeft() { @@ -102,9 +102,9 @@ public void testFlatInterpolationLeft() Date interpolationDate = vars.calendar.advance(vars.today, 6, TimeUnit.Months); ZeroYieldStructure spreadedTermStructure = - new PiecewiseZeroSpreadedTermStructure( - new Handle(vars.termStructure), - spreads, spreadDates); + new PiecewiseZeroSpreadedTermStructure( + new Handle(vars.termStructure), + spreads, spreadDates); double t = vars.dayCount.yearFraction(vars.today, interpolationDate); double interpolatedZeroRate = spreadedTermStructure.zeroRate(t, vars.compounding).value(); @@ -114,14 +114,14 @@ public void testFlatInterpolationLeft() if (Math.Abs(interpolatedZeroRate - expectedRate) > tolerance) QAssert.Fail("unable to reproduce interpolated rate\n" - + " calculated: " + interpolatedZeroRate + "\n" - + " expected: " + expectedRate); + + " calculated: " + interpolatedZeroRate + "\n" + + " expected: " + expectedRate); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testFlatInterpolationRight() { @@ -142,9 +142,9 @@ public void testFlatInterpolationRight() Date interpolationDate = vars.calendar.advance(vars.today, 20, TimeUnit.Months); ZeroYieldStructure spreadedTermStructure = - new PiecewiseZeroSpreadedTermStructure( - new Handle(vars.termStructure), - spreads, spreadDates); + new PiecewiseZeroSpreadedTermStructure( + new Handle(vars.termStructure), + spreads, spreadDates); spreadedTermStructure.enableExtrapolation(); double t = vars.dayCount.yearFraction(vars.today, interpolationDate); @@ -155,14 +155,14 @@ public void testFlatInterpolationRight() if (Math.Abs(interpolatedZeroRate - expectedRate) > tolerance) QAssert.Fail("unable to reproduce interpolated rate\n" - + " calculated: " + interpolatedZeroRate + "\n" - + " expected: " + expectedRate); + + " calculated: " + interpolatedZeroRate + "\n" + + " expected: " + expectedRate); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testLinearInterpolationMultipleSpreads() { @@ -189,29 +189,29 @@ public void testLinearInterpolationMultipleSpreads() Date interpolationDate = vars.calendar.advance(vars.today, 120, TimeUnit.Days); ZeroYieldStructure spreadedTermStructure = - new PiecewiseZeroSpreadedTermStructure( - new Handle(vars.termStructure), - spreads, spreadDates); + new PiecewiseZeroSpreadedTermStructure( + new Handle(vars.termStructure), + spreads, spreadDates); double t = vars.dayCount.yearFraction(vars.today, interpolationDate); double interpolatedZeroRate = spreadedTermStructure.zeroRate(t, vars.compounding).value(); double tolerance = 1e-9; double expectedRate = vars.termStructure.zeroRate(t, vars.compounding).value() + - spread1.value(); + spread1.value(); if (Math.Abs(interpolatedZeroRate - expectedRate) > tolerance) QAssert.Fail( - "unable to reproduce interpolated rate\n" + "unable to reproduce interpolated rate\n" - + " calculated: " + interpolatedZeroRate + "\n" - + " expected: " + expectedRate); + + " calculated: " + interpolatedZeroRate + "\n" + + " expected: " + expectedRate); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testLinearInterpolation() { @@ -232,9 +232,9 @@ public void testLinearInterpolation() Date interpolationDate = vars.calendar.advance(vars.today, 120, TimeUnit.Days); ZeroYieldStructure spreadedTermStructure = - new InterpolatedPiecewiseZeroSpreadedTermStructure( - new Handle(vars.termStructure), - spreads, spreadDates); + new InterpolatedPiecewiseZeroSpreadedTermStructure( + new Handle(vars.termStructure), + spreads, spreadDates); Date d0 = vars.calendar.advance(vars.today, 100, TimeUnit.Days); Date d1 = vars.calendar.advance(vars.today, 150, TimeUnit.Days); @@ -250,15 +250,15 @@ public void testLinearInterpolation() if (Math.Abs(interpolatedZeroRate - expectedRate) > tolerance) QAssert.Fail( - "unable to reproduce interpolated rate\n" - + " calculated: " + interpolatedZeroRate + "\n" - + " expected: " + expectedRate); + "unable to reproduce interpolated rate\n" + + " calculated: " + interpolatedZeroRate + "\n" + + " expected: " + expectedRate); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testForwardFlatInterpolation() { @@ -279,28 +279,28 @@ public void testForwardFlatInterpolation() Date interpolationDate = vars.calendar.advance(vars.today, 100, TimeUnit.Days); ZeroYieldStructure spreadedTermStructure = - new InterpolatedPiecewiseZeroSpreadedTermStructure( - new Handle(vars.termStructure), - spreads, spreadDates); + new InterpolatedPiecewiseZeroSpreadedTermStructure( + new Handle(vars.termStructure), + spreads, spreadDates); double t = vars.dayCount.yearFraction(vars.today, interpolationDate); double interpolatedZeroRate = spreadedTermStructure.zeroRate(t, vars.compounding).value(); double tolerance = 1e-9; double expectedRate = vars.termStructure.zeroRate(t, vars.compounding).value() + - spread1.value(); + spread1.value(); if (Math.Abs(interpolatedZeroRate - expectedRate) > tolerance) QAssert.Fail( - "unable to reproduce interpolated rate\n" - + " calculated: " + interpolatedZeroRate + "\n" - + " expected: " + expectedRate); + "unable to reproduce interpolated rate\n" + + " calculated: " + interpolatedZeroRate + "\n" + + " expected: " + expectedRate); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testBackwardFlatInterpolation() { @@ -324,29 +324,29 @@ public void testBackwardFlatInterpolation() Date interpolationDate = vars.calendar.advance(vars.today, 110, TimeUnit.Days); ZeroYieldStructure spreadedTermStructure = - new InterpolatedPiecewiseZeroSpreadedTermStructure( - new Handle(vars.termStructure), - spreads, spreadDates); + new InterpolatedPiecewiseZeroSpreadedTermStructure( + new Handle(vars.termStructure), + spreads, spreadDates); double t = vars.dayCount.yearFraction(vars.today, interpolationDate); double interpolatedZeroRate = spreadedTermStructure.zeroRate(t, vars.compounding).value(); double tolerance = 1e-9; double expectedRate = vars.termStructure.zeroRate(t, vars.compounding).value() + - spread2.value(); + spread2.value(); if (Math.Abs(interpolatedZeroRate - expectedRate) > tolerance) QAssert.Fail( - "unable to reproduce interpolated rate\n" - + " calculated: " + interpolatedZeroRate + "\n" - + " expected: " + expectedRate); + "unable to reproduce interpolated rate\n" + + " calculated: " + interpolatedZeroRate + "\n" + + " expected: " + expectedRate); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testDefaultInterpolation() { @@ -367,28 +367,28 @@ public void testDefaultInterpolation() Date interpolationDate = vars.calendar.advance(vars.today, 100, TimeUnit.Days); ZeroYieldStructure spreadedTermStructure = - new PiecewiseZeroSpreadedTermStructure( - new Handle(vars.termStructure), - spreads, spreadDates); + new PiecewiseZeroSpreadedTermStructure( + new Handle(vars.termStructure), + spreads, spreadDates); double t = vars.dayCount.yearFraction(vars.today, interpolationDate); double interpolatedZeroRate = spreadedTermStructure.zeroRate(t, vars.compounding).value(); double tolerance = 1e-9; double expectedRate = vars.termStructure.zeroRate(t, vars.compounding).value() + - spread1.value(); + spread1.value(); if (Math.Abs(interpolatedZeroRate - expectedRate) > tolerance) QAssert.Fail( - "unable to reproduce interpolated rate\n" - + " calculated: " + interpolatedZeroRate + "\n" - + " expected: " + expectedRate); + "unable to reproduce interpolated rate\n" + + " calculated: " + interpolatedZeroRate + "\n" + + " expected: " + expectedRate); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testSetInterpolationFactory() { @@ -421,29 +421,29 @@ public void testSetInterpolationFactory() CubicInterpolation.BoundaryCondition.SecondDerivative, 0); spreadedTermStructure = - new InterpolatedPiecewiseZeroSpreadedTermStructure( - new Handle(vars.termStructure), - spreads, spreadDates, vars.compounding, - freq, vars.dayCount, factory); + new InterpolatedPiecewiseZeroSpreadedTermStructure( + new Handle(vars.termStructure), + spreads, spreadDates, vars.compounding, + freq, vars.dayCount, factory); double t = vars.dayCount.yearFraction(vars.today, interpolationDate); double interpolatedZeroRate = spreadedTermStructure.zeroRate(t, vars.compounding).value(); double tolerance = 1e-9; double expectedRate = vars.termStructure.zeroRate(t, vars.compounding).value() + - 0.026065770863; + 0.026065770863; if (Math.Abs(interpolatedZeroRate - expectedRate) > tolerance) QAssert.Fail( - "unable to reproduce interpolated rate\n" - + " calculated: " + interpolatedZeroRate + "\n" - + " expected: " + expectedRate); + "unable to reproduce interpolated rate\n" + + " calculated: " + interpolatedZeroRate + "\n" + + " expected: " + expectedRate); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testMaxDate() { @@ -462,9 +462,9 @@ public void testMaxDate() spreadDates.Add(vars.calendar.advance(vars.today, 15, TimeUnit.Months)); ZeroYieldStructure spreadedTermStructure = - new PiecewiseZeroSpreadedTermStructure( - new Handle(vars.termStructure), - spreads, spreadDates); + new PiecewiseZeroSpreadedTermStructure( + new Handle(vars.termStructure), + spreads, spreadDates); Date maxDate = spreadedTermStructure.maxDate(); @@ -472,15 +472,15 @@ public void testMaxDate() if (maxDate != expectedDate) QAssert.Fail( - "unable to reproduce max date\n" - + " calculated: " + maxDate + "\n" - + " expected: " + expectedDate); + "unable to reproduce max date\n" + + " calculated: " + maxDate + "\n" + + " expected: " + expectedDate); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testQuoteChanging() { @@ -501,21 +501,21 @@ public void testQuoteChanging() Date interpolationDate = vars.calendar.advance(vars.today, 120, TimeUnit.Days); ZeroYieldStructure spreadedTermStructure = - new InterpolatedPiecewiseZeroSpreadedTermStructure( - new Handle(vars.termStructure), - spreads, spreadDates); + new InterpolatedPiecewiseZeroSpreadedTermStructure( + new Handle(vars.termStructure), + spreads, spreadDates); double t = vars.dayCount.yearFraction(vars.settlementDate, interpolationDate); double interpolatedZeroRate = spreadedTermStructure.zeroRate(t, vars.compounding).value(); double tolerance = 1e-9; double expectedRate = vars.termStructure.zeroRate(t, vars.compounding).value() + - 0.03; + 0.03; if (Math.Abs(interpolatedZeroRate - expectedRate) > tolerance) QAssert.Fail( - "unable to reproduce interpolated rate\n" - + " calculated: " + interpolatedZeroRate + "\n" - + " expected: " + expectedRate); + "unable to reproduce interpolated rate\n" + + " calculated: " + interpolatedZeroRate + "\n" + + " expected: " + expectedRate); spread2.setValue(0.025); @@ -525,9 +525,9 @@ public void testQuoteChanging() if (Math.Abs(interpolatedZeroRate - expectedRate) > tolerance) QAssert.Fail( - "unable to reproduce interpolated rate\n" - + " calculated: " + interpolatedZeroRate + "\n" - + " expected: " + expectedRate); + "unable to reproduce interpolated rate\n" + + " calculated: " + interpolatedZeroRate + "\n" + + " expected: " + expectedRate); } } } diff --git a/tests/QLNet.Tests/T_Piecewiseyieldcurve.cs b/tests/QLNet.Tests/T_Piecewiseyieldcurve.cs index 410a10bb6..b5e7cadaf 100644 --- a/tests/QLNet.Tests/T_Piecewiseyieldcurve.cs +++ b/tests/QLNet.Tests/T_Piecewiseyieldcurve.cs @@ -7,7 +7,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -22,904 +22,963 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; -namespace TestSuite { +namespace TestSuite +{ #if NET40 || NET45 [TestClass()] #endif public class T_PiecewiseyieldCurve : IDisposable { - public class CommonVars { - #region Values - public struct Datum { - public int n; - public TimeUnit units; - public double rate; - }; - public struct BondDatum { - public int n; - public TimeUnit units; - public int length; - public Frequency frequency; - public double coupon; - public double price; - }; - - public Datum[] depositData = new Datum[] { - new Datum { n = 1, units = TimeUnit.Weeks, rate = 4.559 }, - new Datum { n = 1, units = TimeUnit.Months, rate = 4.581 }, - new Datum { n = 2, units = TimeUnit.Months, rate = 4.573 }, - new Datum { n = 3, units = TimeUnit.Months, rate = 4.557 }, - new Datum { n = 6, units = TimeUnit.Months, rate = 4.496 }, - new Datum { n = 9, units = TimeUnit.Months, rate = 4.490 } - }; - - public Datum[] fraData = new Datum[] { - new Datum { n = 1, units = TimeUnit.Months, rate = 4.581 }, - new Datum { n = 2, units = TimeUnit.Months, rate = 4.573 }, - new Datum { n = 3, units = TimeUnit.Months, rate = 4.557 }, - new Datum { n = 6, units = TimeUnit.Months, rate = 4.496 }, - new Datum { n = 9, units = TimeUnit.Months, rate = 4.490 } - }; - - public Datum[] swapData = new Datum[] { - new Datum { n = 1, units = TimeUnit.Years, rate = 4.54 }, - new Datum { n = 2, units = TimeUnit.Years, rate = 4.63 }, - new Datum { n = 3, units = TimeUnit.Years, rate = 4.75 }, - new Datum { n = 4, units = TimeUnit.Years, rate = 4.86 }, - new Datum { n = 5, units = TimeUnit.Years, rate = 4.99 }, - new Datum { n = 6, units = TimeUnit.Years, rate = 5.11 }, - new Datum { n = 7, units = TimeUnit.Years, rate = 5.23 }, - new Datum { n = 8, units = TimeUnit.Years, rate = 5.33 }, - new Datum { n = 9, units = TimeUnit.Years, rate = 5.41 }, - new Datum { n = 10, units = TimeUnit.Years, rate = 5.47 }, - new Datum { n = 12, units = TimeUnit.Years, rate = 5.60 }, - new Datum { n = 15, units = TimeUnit.Years, rate = 5.75 }, - new Datum { n = 20, units = TimeUnit.Years, rate = 5.89 }, - new Datum { n = 25, units = TimeUnit.Years, rate = 5.95 }, - new Datum { n = 30, units = TimeUnit.Years, rate = 5.96 } - }; - - public BondDatum[] bondData = new BondDatum[] { - new BondDatum { n = 6, units = TimeUnit.Months, length = 5, frequency = Frequency.Semiannual, coupon = 4.75, price = 101.320 }, - new BondDatum { n = 1, units = TimeUnit.Years, length = 3, frequency = Frequency.Semiannual, coupon = 2.75, price = 100.590 }, - new BondDatum { n = 2, units = TimeUnit.Years, length = 5, frequency = Frequency.Semiannual, coupon = 5.00, price = 105.650 }, - new BondDatum { n = 5, units = TimeUnit.Years, length = 11, frequency = Frequency.Semiannual, coupon = 5.50, price = 113.610 }, - new BondDatum { n = 10, units = TimeUnit.Years, length = 11, frequency = Frequency.Semiannual, coupon = 3.75, price = 104.070 } - }; - - public Datum[] bmaData = new Datum[] { - new Datum { n = 1, units = TimeUnit.Years, rate = 67.56 }, - new Datum { n = 2, units = TimeUnit.Years, rate = 68.00 }, - new Datum { n = 3, units = TimeUnit.Years, rate = 68.25 }, - new Datum { n = 4, units = TimeUnit.Years, rate = 68.50 }, - new Datum { n = 5, units = TimeUnit.Years, rate = 68.81 }, - new Datum { n = 7, units = TimeUnit.Years, rate = 69.50 }, - new Datum { n = 10, units = TimeUnit.Years, rate = 70.44 }, - new Datum { n = 15, units = TimeUnit.Years, rate = 71.69 }, - new Datum { n = 20, units = TimeUnit.Years, rate = 72.69 }, - new Datum { n = 30, units = TimeUnit.Years, rate = 73.81 } - }; - #endregion - - // global variables - public Calendar calendar; - public int settlementDays; - public Date today, settlement; - public BusinessDayConvention fixedLegConvention; - public Frequency fixedLegFrequency; - public DayCounter fixedLegDayCounter; - public int bondSettlementDays; - public DayCounter bondDayCounter; - public BusinessDayConvention bondConvention; - public double bondRedemption; - public Frequency bmaFrequency; - public BusinessDayConvention bmaConvention; - public DayCounter bmaDayCounter; - - public int deposits, fras, swaps, bonds, bmas; - public List rates, fraRates, prices, fractions; - public List instruments, fraHelpers, bondHelpers, bmaHelpers; - public List schedules; - public YieldTermStructure termStructure; - - // setup - public CommonVars() { - - // data - calendar = new TARGET(); - settlementDays = 2; - today = calendar.adjust(Date.Today); - Settings.setEvaluationDate(today); - settlement = calendar.advance(today, settlementDays, TimeUnit.Days); - fixedLegConvention = BusinessDayConvention.Unadjusted; - fixedLegFrequency = Frequency.Annual; - fixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European); - bondSettlementDays = 3; - bondDayCounter = new ActualActual(); - bondConvention = BusinessDayConvention.Following; - bondRedemption = 100.0; - bmaFrequency = Frequency.Quarterly; - bmaConvention = BusinessDayConvention.Following; - bmaDayCounter = new ActualActual(); - - deposits = depositData.Length; - fras = fraData.Length; - swaps = swapData.Length; - bonds = bondData.Length; - bmas = bmaData.Length; - - // market elements - rates = new List(deposits + swaps); - fraRates = new List(fras); - prices = new List(bonds); - fractions = new List(bmas); - for (int i = 0; i < deposits; i++) { - rates.Add(new SimpleQuote(depositData[i].rate / 100)); - } - for (int i = 0; i < swaps; i++) { - rates.Add(new SimpleQuote(swapData[i].rate / 100)); - } - for (int i = 0; i < fras; i++) { - fraRates.Add(new SimpleQuote(fraData[i].rate / 100)); - } - for (int i = 0; i < bonds; i++) { - prices.Add(new SimpleQuote(bondData[i].price)); - } - for (int i = 0; i < bmas; i++) { - fractions.Add(new SimpleQuote(bmaData[i].rate / 100)); - } - - // rate helpers - instruments = new List(deposits + swaps); - fraHelpers = new List(fras); - bondHelpers = new List(bonds); - schedules = new List(bonds); - bmaHelpers = new List(bmas); - - IborIndex euribor6m = new Euribor6M(); - for (int i = 0; i < deposits; i++) { - Handle r = new Handle(rates[i]); - instruments.Add(new DepositRateHelper(r, new Period(depositData[i].n, depositData[i].units), - euribor6m.fixingDays(), calendar, - euribor6m.businessDayConvention(), - euribor6m.endOfMonth(), - euribor6m.dayCounter())); - } - for (int i = 0; i < swaps; i++) { - Handle r = new Handle(rates[i + deposits]); - instruments.Add(new SwapRateHelper(r, new Period(swapData[i].n, swapData[i].units), calendar, - fixedLegFrequency, fixedLegConvention, fixedLegDayCounter, euribor6m)); - } - - Euribor3M euribor3m = new Euribor3M(); - for (int i = 0; i < fras; i++) { - Handle r = new Handle(fraRates[i]); - fraHelpers.Add(new FraRateHelper(r, fraData[i].n, fraData[i].n + 3, - euribor3m.fixingDays(), - euribor3m.fixingCalendar(), - euribor3m.businessDayConvention(), - euribor3m.endOfMonth(), - euribor3m.dayCounter())); - } - - for (int i = 0; i < bonds; i++) { - Handle p = new Handle(prices[i]); - Date maturity = calendar.advance(today, bondData[i].n, bondData[i].units); - Date issue = calendar.advance(maturity, -bondData[i].length, TimeUnit.Years); - List coupons = new List() { bondData[i].coupon / 100.0 }; - schedules.Add(new Schedule(issue, maturity, new Period(bondData[i].frequency), calendar, - bondConvention, bondConvention, DateGeneration.Rule.Backward, false)); - bondHelpers.Add(new FixedRateBondHelper(p, bondSettlementDays, bondRedemption, schedules[i], - coupons, bondDayCounter, bondConvention, bondRedemption, issue)); - } + public class CommonVars + { + #region Values + public struct Datum + { + public int n; + public TimeUnit units; + public double rate; + } + public struct BondDatum + { + public int n; + public TimeUnit units; + public int length; + public Frequency frequency; + public double coupon; + public double price; + } + + public Datum[] depositData = new Datum[] + { + new Datum { n = 1, units = TimeUnit.Weeks, rate = 4.559 }, + new Datum { n = 1, units = TimeUnit.Months, rate = 4.581 }, + new Datum { n = 2, units = TimeUnit.Months, rate = 4.573 }, + new Datum { n = 3, units = TimeUnit.Months, rate = 4.557 }, + new Datum { n = 6, units = TimeUnit.Months, rate = 4.496 }, + new Datum { n = 9, units = TimeUnit.Months, rate = 4.490 } + }; + + public Datum[] fraData = new Datum[] + { + new Datum { n = 1, units = TimeUnit.Months, rate = 4.581 }, + new Datum { n = 2, units = TimeUnit.Months, rate = 4.573 }, + new Datum { n = 3, units = TimeUnit.Months, rate = 4.557 }, + new Datum { n = 6, units = TimeUnit.Months, rate = 4.496 }, + new Datum { n = 9, units = TimeUnit.Months, rate = 4.490 } + }; + + public Datum[] swapData = new Datum[] + { + new Datum { n = 1, units = TimeUnit.Years, rate = 4.54 }, + new Datum { n = 2, units = TimeUnit.Years, rate = 4.63 }, + new Datum { n = 3, units = TimeUnit.Years, rate = 4.75 }, + new Datum { n = 4, units = TimeUnit.Years, rate = 4.86 }, + new Datum { n = 5, units = TimeUnit.Years, rate = 4.99 }, + new Datum { n = 6, units = TimeUnit.Years, rate = 5.11 }, + new Datum { n = 7, units = TimeUnit.Years, rate = 5.23 }, + new Datum { n = 8, units = TimeUnit.Years, rate = 5.33 }, + new Datum { n = 9, units = TimeUnit.Years, rate = 5.41 }, + new Datum { n = 10, units = TimeUnit.Years, rate = 5.47 }, + new Datum { n = 12, units = TimeUnit.Years, rate = 5.60 }, + new Datum { n = 15, units = TimeUnit.Years, rate = 5.75 }, + new Datum { n = 20, units = TimeUnit.Years, rate = 5.89 }, + new Datum { n = 25, units = TimeUnit.Years, rate = 5.95 }, + new Datum { n = 30, units = TimeUnit.Years, rate = 5.96 } + }; + + public BondDatum[] bondData = new BondDatum[] + { + new BondDatum { n = 6, units = TimeUnit.Months, length = 5, frequency = Frequency.Semiannual, coupon = 4.75, price = 101.320 }, + new BondDatum { n = 1, units = TimeUnit.Years, length = 3, frequency = Frequency.Semiannual, coupon = 2.75, price = 100.590 }, + new BondDatum { n = 2, units = TimeUnit.Years, length = 5, frequency = Frequency.Semiannual, coupon = 5.00, price = 105.650 }, + new BondDatum { n = 5, units = TimeUnit.Years, length = 11, frequency = Frequency.Semiannual, coupon = 5.50, price = 113.610 }, + new BondDatum { n = 10, units = TimeUnit.Years, length = 11, frequency = Frequency.Semiannual, coupon = 3.75, price = 104.070 } + }; + + public Datum[] bmaData = new Datum[] + { + new Datum { n = 1, units = TimeUnit.Years, rate = 67.56 }, + new Datum { n = 2, units = TimeUnit.Years, rate = 68.00 }, + new Datum { n = 3, units = TimeUnit.Years, rate = 68.25 }, + new Datum { n = 4, units = TimeUnit.Years, rate = 68.50 }, + new Datum { n = 5, units = TimeUnit.Years, rate = 68.81 }, + new Datum { n = 7, units = TimeUnit.Years, rate = 69.50 }, + new Datum { n = 10, units = TimeUnit.Years, rate = 70.44 }, + new Datum { n = 15, units = TimeUnit.Years, rate = 71.69 }, + new Datum { n = 20, units = TimeUnit.Years, rate = 72.69 }, + new Datum { n = 30, units = TimeUnit.Years, rate = 73.81 } + }; + #endregion + + // global variables + public Calendar calendar; + public int settlementDays; + public Date today, settlement; + public BusinessDayConvention fixedLegConvention; + public Frequency fixedLegFrequency; + public DayCounter fixedLegDayCounter; + public int bondSettlementDays; + public DayCounter bondDayCounter; + public BusinessDayConvention bondConvention; + public double bondRedemption; + public Frequency bmaFrequency; + public BusinessDayConvention bmaConvention; + public DayCounter bmaDayCounter; + + public int deposits, fras, swaps, bonds, bmas; + public List rates, fraRates, prices, fractions; + public List instruments, fraHelpers, bondHelpers, bmaHelpers; + public List schedules; + public YieldTermStructure termStructure; + + // setup + public CommonVars() + { + + // data + calendar = new TARGET(); + settlementDays = 2; + today = calendar.adjust(Date.Today); + Settings.setEvaluationDate(today); + settlement = calendar.advance(today, settlementDays, TimeUnit.Days); + fixedLegConvention = BusinessDayConvention.Unadjusted; + fixedLegFrequency = Frequency.Annual; + fixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European); + bondSettlementDays = 3; + bondDayCounter = new ActualActual(); + bondConvention = BusinessDayConvention.Following; + bondRedemption = 100.0; + bmaFrequency = Frequency.Quarterly; + bmaConvention = BusinessDayConvention.Following; + bmaDayCounter = new ActualActual(); + + deposits = depositData.Length; + fras = fraData.Length; + swaps = swapData.Length; + bonds = bondData.Length; + bmas = bmaData.Length; + + // market elements + rates = new List(deposits + swaps); + fraRates = new List(fras); + prices = new List(bonds); + fractions = new List(bmas); + for (int i = 0; i < deposits; i++) + { + rates.Add(new SimpleQuote(depositData[i].rate / 100)); + } + for (int i = 0; i < swaps; i++) + { + rates.Add(new SimpleQuote(swapData[i].rate / 100)); + } + for (int i = 0; i < fras; i++) + { + fraRates.Add(new SimpleQuote(fraData[i].rate / 100)); + } + for (int i = 0; i < bonds; i++) + { + prices.Add(new SimpleQuote(bondData[i].price)); + } + for (int i = 0; i < bmas; i++) + { + fractions.Add(new SimpleQuote(bmaData[i].rate / 100)); } - } - - #region Initialize&Cleanup - private SavedSettings backup; - private IndexHistoryCleaner cleaner; - #if NET40 || NET45 - [TestInitialize] - public void testInitialize() - { - #else - public T_PiecewiseyieldCurve() - { - #endif - backup = new SavedSettings(); - cleaner = new IndexHistoryCleaner(); - } - #if NET40 || NET45 - [TestCleanup] - #endif - public void testCleanup() - { - Dispose(); - } - public void Dispose() - { - backup.Dispose(); - cleaner.Dispose(); - } - #endregion - - //[TestMethod()] - public void testLogCubicDiscountConsistency() { - // "Testing consistency of piecewise-log-cubic discount curve..."); - CommonVars vars = new CommonVars(); + // rate helpers + instruments = new List(deposits + swaps); + fraHelpers = new List(fras); + bondHelpers = new List(bonds); + schedules = new List(bonds); + bmaHelpers = new List(bmas); + + IborIndex euribor6m = new Euribor6M(); + for (int i = 0; i < deposits; i++) + { + Handle r = new Handle(rates[i]); + instruments.Add(new DepositRateHelper(r, new Period(depositData[i].n, depositData[i].units), + euribor6m.fixingDays(), calendar, + euribor6m.businessDayConvention(), + euribor6m.endOfMonth(), + euribor6m.dayCounter())); + } + for (int i = 0; i < swaps; i++) + { + Handle r = new Handle(rates[i + deposits]); + instruments.Add(new SwapRateHelper(r, new Period(swapData[i].n, swapData[i].units), calendar, + fixedLegFrequency, fixedLegConvention, fixedLegDayCounter, euribor6m)); + } - testCurveConsistency( vars, - new LogCubic(CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); - testBMACurveConsistency( vars, - new LogCubic(CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); - } + Euribor3M euribor3m = new Euribor3M(); + for (int i = 0; i < fras; i++) + { + Handle r = new Handle(fraRates[i]); + fraHelpers.Add(new FraRateHelper(r, fraData[i].n, fraData[i].n + 3, + euribor3m.fixingDays(), + euribor3m.fixingCalendar(), + euribor3m.businessDayConvention(), + euribor3m.endOfMonth(), + euribor3m.dayCounter())); + } + + for (int i = 0; i < bonds; i++) + { + Handle p = new Handle(prices[i]); + Date maturity = calendar.advance(today, bondData[i].n, bondData[i].units); + Date issue = calendar.advance(maturity, -bondData[i].length, TimeUnit.Years); + List coupons = new List() { bondData[i].coupon / 100.0 }; + schedules.Add(new Schedule(issue, maturity, new Period(bondData[i].frequency), calendar, + bondConvention, bondConvention, DateGeneration.Rule.Backward, false)); + bondHelpers.Add(new FixedRateBondHelper(p, bondSettlementDays, bondRedemption, schedules[i], + coupons, bondDayCounter, bondConvention, bondRedemption, issue)); + } + } + } + #region Initialize&Cleanup + private SavedSettings backup; + private IndexHistoryCleaner cleaner; #if NET40 || NET45 - [TestMethod()] + [TestInitialize] + public void testInitialize() + { #else - [Fact] + public T_PiecewiseyieldCurve() + { #endif - public void testLogLinearDiscountConsistency() { - // "Testing consistency of piecewise-log-linear discount curve..."); + backup = new SavedSettings(); + cleaner = new IndexHistoryCleaner(); + } +#if NET40 || NET45 + [TestCleanup] +#endif + public void testCleanup() + { + Dispose(); + } + public void Dispose() + { + backup.Dispose(); + cleaner.Dispose(); + } + #endregion + + //[TestMethod()] + public void testLogCubicDiscountConsistency() + { + // "Testing consistency of piecewise-log-cubic discount curve..."); + + CommonVars vars = new CommonVars(); + + testCurveConsistency(vars, + new LogCubic(CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); + testBMACurveConsistency(vars, + new LogCubic(CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); + } - CommonVars vars = new CommonVars(); +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testLogLinearDiscountConsistency() + { + // "Testing consistency of piecewise-log-linear discount curve..."); + + CommonVars vars = new CommonVars(); - testCurveConsistency( vars ); - testBMACurveConsistency( vars ); - } + testCurveConsistency(vars); + testBMACurveConsistency(vars); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testLinearDiscountConsistency() { - // "Testing consistency of piecewise-linear discount curve..." + public void testLinearDiscountConsistency() + { + // "Testing consistency of piecewise-linear discount curve..." - CommonVars vars = new CommonVars(); + CommonVars vars = new CommonVars(); - testCurveConsistency( vars ); - testBMACurveConsistency( vars ); - } + testCurveConsistency(vars); + testBMACurveConsistency(vars); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testLogLinearZeroConsistency() { - // "Testing consistency of piecewise-log-linear zero-yield curve..."); - - // if rates can be negative it makes no sense to interpolate loglinearly - if ( Utils.is_QL_NEGATIVE_RATES() ) - return; - else - { + public void testLogLinearZeroConsistency() + { + // "Testing consistency of piecewise-log-linear zero-yield curve..."); + + // if rates can be negative it makes no sense to interpolate loglinearly + if (Utils.is_QL_NEGATIVE_RATES()) + return; + else + { CommonVars vars = new CommonVars(); - testCurveConsistency( vars ); - testBMACurveConsistency( vars ); - } - } + testCurveConsistency(vars); + testBMACurveConsistency(vars); + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testLinearZeroConsistency() { - // "Testing consistency of piecewise-linear zero-yield curve..."); + public void testLinearZeroConsistency() + { + // "Testing consistency of piecewise-linear zero-yield curve..."); - CommonVars vars = new CommonVars(); + CommonVars vars = new CommonVars(); - testCurveConsistency( vars ); - testBMACurveConsistency( vars ); - } + testCurveConsistency(vars); + testBMACurveConsistency(vars); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testSplineZeroConsistency() { + public void testSplineZeroConsistency() + { - //"Testing consistency of piecewise-cubic zero-yield curve..."); + //"Testing consistency of piecewise-cubic zero-yield curve..."); - CommonVars vars = new CommonVars(); + CommonVars vars = new CommonVars(); - testCurveConsistency( - vars, - new Cubic(CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); - testBMACurveConsistency( - vars, - new Cubic(CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); - } + testCurveConsistency( + vars, + new Cubic(CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); + testBMACurveConsistency( + vars, + new Cubic(CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testLinearForwardConsistency() { - // "Testing consistency of piecewise-linear forward-rate curve..."); + public void testLinearForwardConsistency() + { + // "Testing consistency of piecewise-linear forward-rate curve..."); - CommonVars vars = new CommonVars(); + CommonVars vars = new CommonVars(); - testCurveConsistency( vars ); - testBMACurveConsistency( vars ); - } + testCurveConsistency(vars); + testBMACurveConsistency(vars); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testFlatForwardConsistency() { + public void testFlatForwardConsistency() + { - //"Testing consistency of piecewise-flat forward-rate curve..."); + //"Testing consistency of piecewise-flat forward-rate curve..."); - CommonVars vars = new CommonVars(); + CommonVars vars = new CommonVars(); - testCurveConsistency( vars ); - testBMACurveConsistency( vars ); - } + testCurveConsistency(vars); + testBMACurveConsistency(vars); + } - //[TestMethod()] - public void testSplineForwardConsistency() { + //[TestMethod()] + public void testSplineForwardConsistency() + { - //"Testing consistency of piecewise-cubic forward-rate curve..."); + //"Testing consistency of piecewise-cubic forward-rate curve..."); - CommonVars vars = new CommonVars(); + CommonVars vars = new CommonVars(); - testCurveConsistency( - vars, - new Cubic(CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); - testBMACurveConsistency( - vars, - new Cubic(CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); - } + testCurveConsistency( + vars, + new Cubic(CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); + testBMACurveConsistency( + vars, + new Cubic(CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testConvexMonotoneForwardConsistency() { - //"Testing consistency of convex monotone forward-rate curve..."); + public void testConvexMonotoneForwardConsistency() + { + //"Testing consistency of convex monotone forward-rate curve..."); - CommonVars vars = new CommonVars(); + CommonVars vars = new CommonVars(); - testCurveConsistency( vars ); - testBMACurveConsistency(vars); - } + testCurveConsistency(vars); + testBMACurveConsistency(vars); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testLocalBootstrapConsistency() { - //"Testing consistency of local-bootstrap algorithm..."); + public void testLocalBootstrapConsistency() + { + //"Testing consistency of local-bootstrap algorithm..."); - CommonVars vars = new CommonVars(); - testCurveConsistency( vars, new ConvexMonotone(), 1.0e-7 ); - testBMACurveConsistency( vars, new ConvexMonotone(), 1.0e-9 ); - } + CommonVars vars = new CommonVars(); + testCurveConsistency(vars, new ConvexMonotone(), 1.0e-7); + testBMACurveConsistency(vars, new ConvexMonotone(), 1.0e-9); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testObservability() { - // "Testing observability of piecewise yield curve..."); + public void testObservability() + { + // "Testing observability of piecewise yield curve..."); - CommonVars vars = new CommonVars(); + CommonVars vars = new CommonVars(); - vars.termStructure = new PiecewiseYieldCurve(vars.settlementDays, - vars.calendar, vars.instruments, new Actual360()); - Flag f = new Flag(); - vars.termStructure.registerWith(f.update); - - for (int i = 0; i < vars.deposits + vars.swaps; i++) { - double testTime = new Actual360().yearFraction(vars.settlement, vars.instruments[i].latestDate()); - double discount = vars.termStructure.discount(testTime); - f.lower(); - vars.rates[i].setValue(vars.rates[i].value() * 1.01); - if (!f.isUp()) - QAssert.Fail("Observer was not notified of underlying rate change"); - double discount_new = vars.termStructure.discount(testTime, true); - if (discount_new == discount) - QAssert.Fail("rate change did not trigger recalculation"); - vars.rates[i].setValue(vars.rates[i].value() / 1.01); - } + vars.termStructure = new PiecewiseYieldCurve(vars.settlementDays, + vars.calendar, vars.instruments, new Actual360()); + Flag f = new Flag(); + vars.termStructure.registerWith(f.update); + for (int i = 0; i < vars.deposits + vars.swaps; i++) + { + double testTime = new Actual360().yearFraction(vars.settlement, vars.instruments[i].latestDate()); + double discount = vars.termStructure.discount(testTime); f.lower(); - Settings.setEvaluationDate(vars.calendar.advance(vars.today, 15, TimeUnit.Days)); + vars.rates[i].setValue(vars.rates[i].value() * 1.01); if (!f.isUp()) - QAssert.Fail("Observer was not notified of date change"); - } + QAssert.Fail("Observer was not notified of underlying rate change"); + double discount_new = vars.termStructure.discount(testTime, true); + if (discount_new == discount) + QAssert.Fail("rate change did not trigger recalculation"); + vars.rates[i].setValue(vars.rates[i].value() / 1.01); + } + + f.lower(); + Settings.setEvaluationDate(vars.calendar.advance(vars.today, 15, TimeUnit.Days)); + if (!f.isUp()) + QAssert.Fail("Observer was not notified of date change"); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testLiborFixing() { - - // "Testing use of today's LIBOR fixings in swap curve..."); - - CommonVars vars = new CommonVars(); - - var swapHelpers = new InitializedList(); - IborIndex euribor6m = new Euribor6M(); - - for (int i=0; i r = new Handle(vars.rates[i+vars.deposits]); - swapHelpers.Add(new SwapRateHelper(r, new Period(vars.swapData[i].n, vars.swapData[i].units), - vars.calendar, - vars.fixedLegFrequency, vars.fixedLegConvention, - vars.fixedLegDayCounter, euribor6m)); - } - - vars.termStructure = new PiecewiseYieldCurve(vars.settlement, swapHelpers, new Actual360()); - - Handle curveHandle = new Handle(vars.termStructure); - - IborIndex index = new Euribor6M(curveHandle); - for (int i=0; i tolerance) { - QAssert.Fail("before LIBOR fixing:\n" - + vars.swapData[i].n + " year(s) swap:\n" - + " estimated rate: " - + (estimatedRate) + "\n" - + " expected rate: " - + (expectedRate)); - } + public void testLiborFixing() + { + + // "Testing use of today's LIBOR fixings in swap curve..."); + + CommonVars vars = new CommonVars(); + + var swapHelpers = new InitializedList(); + IborIndex euribor6m = new Euribor6M(); + + for (int i = 0; i < vars.swaps; i++) + { + Handle r = new Handle(vars.rates[i + vars.deposits]); + swapHelpers.Add(new SwapRateHelper(r, new Period(vars.swapData[i].n, vars.swapData[i].units), + vars.calendar, + vars.fixedLegFrequency, vars.fixedLegConvention, + vars.fixedLegDayCounter, euribor6m)); + } + + vars.termStructure = new PiecewiseYieldCurve(vars.settlement, swapHelpers, new Actual360()); + + Handle curveHandle = new Handle(vars.termStructure); + + IborIndex index = new Euribor6M(curveHandle); + for (int i = 0; i < vars.swaps; i++) + { + Period tenor = new Period(vars.swapData[i].n, vars.swapData[i].units); + + VanillaSwap swap = new MakeVanillaSwap(tenor, index, 0.0) + .withEffectiveDate(vars.settlement) + .withFixedLegDayCount(vars.fixedLegDayCounter) + .withFixedLegTenor(new Period(vars.fixedLegFrequency)) + .withFixedLegConvention(vars.fixedLegConvention) + .withFixedLegTerminationDateConvention(vars.fixedLegConvention) + .value(); + + double expectedRate = vars.swapData[i].rate / 100, + estimatedRate = swap.fairRate(); + double tolerance = 1.0e-9; + if (Math.Abs(expectedRate - estimatedRate) > tolerance) + { + QAssert.Fail("before LIBOR fixing:\n" + + vars.swapData[i].n + " year(s) swap:\n" + + " estimated rate: " + + (estimatedRate) + "\n" + + " expected rate: " + + (expectedRate)); } - - Flag f = new Flag(); - vars.termStructure.registerWith(f.update); - f.lower(); - - index.addFixing(vars.today, 0.0425); - - if (!f.isUp()) - QAssert.Fail("Observer was not notified of rate fixing"); - - for (int i=0; i tolerance) { - QAssert.Fail("after LIBOR fixing:\n" - + vars.swapData[i].n + " year(s) swap:\n" - + " estimated rate: " - + (estimatedRate) + "\n" - + " expected rate: " - + (expectedRate)); - } + } + + Flag f = new Flag(); + vars.termStructure.registerWith(f.update); + f.lower(); + + index.addFixing(vars.today, 0.0425); + + if (!f.isUp()) + QAssert.Fail("Observer was not notified of rate fixing"); + + for (int i = 0; i < vars.swaps; i++) + { + Period tenor = new Period(vars.swapData[i].n, vars.swapData[i].units); + + VanillaSwap swap = new MakeVanillaSwap(tenor, index, 0.0) + .withEffectiveDate(vars.settlement) + .withFixedLegDayCount(vars.fixedLegDayCounter) + .withFixedLegTenor(new Period(vars.fixedLegFrequency)) + .withFixedLegConvention(vars.fixedLegConvention) + .withFixedLegTerminationDateConvention(vars.fixedLegConvention) + .value(); + + double expectedRate = vars.swapData[i].rate / 100, + estimatedRate = swap.fairRate(); + double tolerance = 1.0e-9; + if (Math.Abs(expectedRate - estimatedRate) > tolerance) + { + QAssert.Fail("after LIBOR fixing:\n" + + vars.swapData[i].n + " year(s) swap:\n" + + " estimated rate: " + + (estimatedRate) + "\n" + + " expected rate: " + + (expectedRate)); } - } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testForwardRateDayCounter() { + public void testForwardRateDayCounter() + { - CommonVars vars = new CommonVars(); - DayCounter d = new ActualActual(); - DayCounter d1 = new Actual360(); + CommonVars vars = new CommonVars(); + DayCounter d = new ActualActual(); + DayCounter d1 = new Actual360(); - vars.termStructure = new PiecewiseYieldCurve(vars.settlementDays, - vars.calendar, vars.instruments, d); + vars.termStructure = new PiecewiseYieldCurve(vars.settlementDays, + vars.calendar, vars.instruments, d); - InterestRate ir = vars.termStructure.forwardRate(vars.settlement, vars.settlement + 30, d1, Compounding.Simple); + InterestRate ir = vars.termStructure.forwardRate(vars.settlement, vars.settlement + 30, d1, Compounding.Simple); - if (ir.dayCounter().name() != d1.name()) - QAssert.Fail("PiecewiseYieldCurve forwardRate dayCounter error" + - " Actual daycounter : " + vars.termStructure.dayCounter().name() + - " Expetced DayCounter : " + d1.name()); + if (ir.dayCounter().name() != d1.name()) + QAssert.Fail("PiecewiseYieldCurve forwardRate dayCounter error" + + " Actual daycounter : " + vars.termStructure.dayCounter().name() + + " Expetced DayCounter : " + d1.name()); - } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testJpyLibor() { - //"Testing bootstrap over JPY LIBOR swaps..."); - - CommonVars vars = new CommonVars(); - - vars.today = new Date(4, Month.October, 2007); - Settings.setEvaluationDate(vars.today); - - vars.calendar = new Japan(); - vars.settlement = vars.calendar.advance(vars.today,vars.settlementDays, TimeUnit.Days); - - // market elements - vars.rates = new InitializedList(vars.swaps); - for (int i=0; i(vars.swaps); - - IborIndex index = new JPYLibor(new Period(6, TimeUnit.Months)); - for (int i=0; i r = new Handle(vars.rates[i]); - vars.instruments[i] = new SwapRateHelper(r, new Period(vars.swapData[i].n, vars.swapData[i].units), - vars.calendar, - vars.fixedLegFrequency, vars.fixedLegConvention, - vars.fixedLegDayCounter, index); - } - - vars.termStructure = new PiecewiseYieldCurve( - vars.settlement, vars.instruments, - new Actual360(), - new List>(), - new List(), - 1.0e-12); - - RelinkableHandle curveHandle = new RelinkableHandle(); - curveHandle.linkTo(vars.termStructure); - - // check swaps - IborIndex jpylibor6m = new JPYLibor(new Period(6, TimeUnit.Months),curveHandle); - for (int i=0; i tolerance) { - QAssert.Fail(vars.swapData[i].n + " year(s) swap:\n" - + "\n estimated rate: " + (estimatedRate) - + "\n expected rate: " + (expectedRate) - + "\n error: " + (error) - + "\n tolerance: " + (tolerance)); - } + public void testJpyLibor() + { + //"Testing bootstrap over JPY LIBOR swaps..."); + + CommonVars vars = new CommonVars(); + + vars.today = new Date(4, Month.October, 2007); + Settings.setEvaluationDate(vars.today); + + vars.calendar = new Japan(); + vars.settlement = vars.calendar.advance(vars.today, vars.settlementDays, TimeUnit.Days); + + // market elements + vars.rates = new InitializedList(vars.swaps); + for (int i = 0; i < vars.swaps; i++) + { + vars.rates[i] = new SimpleQuote(vars.swapData[i].rate / 100); + } + + // rate helpers + vars.instruments = new InitializedList(vars.swaps); + + IborIndex index = new JPYLibor(new Period(6, TimeUnit.Months)); + for (int i = 0; i < vars.swaps; i++) + { + Handle r = new Handle(vars.rates[i]); + vars.instruments[i] = new SwapRateHelper(r, new Period(vars.swapData[i].n, vars.swapData[i].units), + vars.calendar, + vars.fixedLegFrequency, vars.fixedLegConvention, + vars.fixedLegDayCounter, index); + } + + vars.termStructure = new PiecewiseYieldCurve( + vars.settlement, vars.instruments, + new Actual360(), + new List>(), + new List(), + 1.0e-12); + + RelinkableHandle curveHandle = new RelinkableHandle(); + curveHandle.linkTo(vars.termStructure); + + // check swaps + IborIndex jpylibor6m = new JPYLibor(new Period(6, TimeUnit.Months), curveHandle); + for (int i = 0; i < vars.swaps; i++) + { + Period tenor = new Period(vars.swapData[i].n, vars.swapData[i].units); + + VanillaSwap swap = new MakeVanillaSwap(tenor, jpylibor6m, 0.0) + .withEffectiveDate(vars.settlement) + .withFixedLegDayCount(vars.fixedLegDayCounter) + .withFixedLegTenor(new Period(vars.fixedLegFrequency)) + .withFixedLegConvention(vars.fixedLegConvention) + .withFixedLegTerminationDateConvention(vars.fixedLegConvention) + .withFixedLegCalendar(vars.calendar) + .withFloatingLegCalendar(vars.calendar) + .value(); + + double expectedRate = vars.swapData[i].rate / 100, + estimatedRate = swap.fairRate(); + double error = Math.Abs(expectedRate - estimatedRate); + double tolerance = 1.0e-9; + + if (error > tolerance) + { + QAssert.Fail(vars.swapData[i].n + " year(s) swap:\n" + + "\n estimated rate: " + (estimatedRate) + + "\n expected rate: " + (expectedRate) + + "\n error: " + (error) + + "\n tolerance: " + (tolerance)); } - } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testDiscountCopy() { - //BOOST_MESSAGE("Testing copying of discount curve..."); + public void testDiscountCopy() + { + //BOOST_MESSAGE("Testing copying of discount curve..."); - CommonVars vars = new CommonVars(); - testCurveCopy(vars); - } + CommonVars vars = new CommonVars(); + testCurveCopy(vars); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testForwardCopy() { - //BOOST_MESSAGE("Testing copying of forward-rate curve..."); + public void testForwardCopy() + { + //BOOST_MESSAGE("Testing copying of forward-rate curve..."); - CommonVars vars = new CommonVars(); - testCurveCopy(vars); - } + CommonVars vars = new CommonVars(); + testCurveCopy(vars); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testZeroCopy() { - //BOOST_MESSAGE("Testing copying of zero-rate curve..."); - - CommonVars vars = new CommonVars(); - testCurveCopy(vars); - } - - - public void testCurveConsistency(CommonVars vars) - where T : ITraits, new() - where I : IInterpolationFactory, new() - where B : IBootStrap, new() { testCurveConsistency( vars, FastActivator.Create(), 1.0e-9 ); } - public void testCurveConsistency(CommonVars vars, I interpolator) - where T : ITraits, new() - where I : IInterpolationFactory, new() - where B : IBootStrap, new() { testCurveConsistency( vars, FastActivator.Create(), 1.0e-9 ); } - public void testCurveConsistency(CommonVars vars, I interpolator, double tolerance) - where T : ITraits, new() - where I : IInterpolationFactory, new() - where B : IBootStrap, new() - { - - vars.termStructure = new PiecewiseYieldCurve(vars.settlement, vars.instruments, - new Actual360(), new List>(), new List(), 1.0e-12, interpolator); - - RelinkableHandle curveHandle = new RelinkableHandle(); - curveHandle.linkTo(vars.termStructure); - - // check deposits - for (int i = 0; i < vars.deposits; i++) { - Euribor index = new Euribor(new Period(vars.depositData[i].n, vars.depositData[i].units), curveHandle); - double expectedRate = vars.depositData[i].rate / 100, - estimatedRate = index.fixing(vars.today); - QAssert.IsTrue(Math.Abs(expectedRate - estimatedRate) < tolerance, - vars.depositData[i].n + " " - + (vars.depositData[i].units == TimeUnit.Weeks ? "week(s)" : "month(s)") - + " deposit:" - + "\n estimated rate: " + estimatedRate - + "\n expected rate: " + expectedRate); - } - - // check swaps - IborIndex euribor6m = new Euribor6M(curveHandle); - for (int i = 0; i < vars.swaps; i++) { - Period tenor = new Period(vars.swapData[i].n, vars.swapData[i].units); - - VanillaSwap swap = new MakeVanillaSwap(tenor, euribor6m, 0.0) - .withEffectiveDate(vars.settlement) - .withFixedLegDayCount(vars.fixedLegDayCounter) - .withFixedLegTenor(new Period(vars.fixedLegFrequency)) - .withFixedLegConvention(vars.fixedLegConvention) - .withFixedLegTerminationDateConvention(vars.fixedLegConvention); - - double expectedRate = vars.swapData[i].rate / 100, - estimatedRate = swap.fairRate(); - double error = Math.Abs(expectedRate - estimatedRate); - QAssert.IsTrue(error < tolerance, - vars.swapData[i].n + " year(s) swap:\n" - + "\n estimated rate: " + estimatedRate - + "\n expected rate: " + expectedRate - + "\n error: " + error - + "\n tolerance: " + tolerance); - } - - // check bonds - vars.termStructure = new PiecewiseYieldCurve(vars.settlement, vars.bondHelpers, - new Actual360(), new List>(), new List(), 1.0e-12, interpolator); - curveHandle.linkTo(vars.termStructure); - - for (int i = 0; i < vars.bonds; i++) { - Date maturity = vars.calendar.advance(vars.today, vars.bondData[i].n, vars.bondData[i].units); - Date issue = vars.calendar.advance(maturity, -vars.bondData[i].length, TimeUnit.Years); - List coupons = new List() { vars.bondData[i].coupon / 100.0 }; - - FixedRateBond bond = new FixedRateBond(vars.bondSettlementDays, 100.0, - vars.schedules[i], coupons, - vars.bondDayCounter, vars.bondConvention, - vars.bondRedemption, issue); - - IPricingEngine bondEngine = new DiscountingBondEngine(curveHandle); - bond.setPricingEngine(bondEngine); - - double expectedPrice = vars.bondData[i].price, - estimatedPrice = bond.cleanPrice(); - QAssert.IsTrue(Math.Abs(expectedPrice - estimatedPrice) < tolerance, - i + 1 + " bond failure:" + - "\n estimated price: " + estimatedPrice + - "\n expected price: " + expectedPrice); - } - - // check FRA - vars.termStructure = new PiecewiseYieldCurve(vars.settlement, vars.fraHelpers, - new Actual360(), new List>(), new List(), 1.0e-12, interpolator); - curveHandle.linkTo(vars.termStructure); - - IborIndex euribor3m = new Euribor3M(curveHandle); - for (int i = 0; i < vars.fras; i++) { - Date start = vars.calendar.advance(vars.settlement, - vars.fraData[i].n, - vars.fraData[i].units, - euribor3m.businessDayConvention(), - euribor3m.endOfMonth()); - Date end = vars.calendar.advance(start, 3, TimeUnit.Months, - euribor3m.businessDayConvention(), - euribor3m.endOfMonth()); - - ForwardRateAgreement fra = new ForwardRateAgreement(start, end, Position.Type.Long, vars.fraData[i].rate / 100, - 100.0, euribor3m, curveHandle); - double expectedRate = vars.fraData[i].rate / 100, - estimatedRate = fra.forwardRate().rate(); - QAssert.IsTrue(Math.Abs(expectedRate - estimatedRate) < tolerance, - i + 1 + " FRA failure:" + - "\n estimated rate: " + estimatedRate + - "\n expected rate: " + expectedRate); - } - } - - public void testBMACurveConsistency(CommonVars vars) - where T : ITraits, new() - where I : IInterpolationFactory, new() - where B : IBootStrap, new() { testBMACurveConsistency( vars, FastActivator.Create(), 1.0e-7 ); } - public void testBMACurveConsistency(CommonVars vars, I interpolator) - where T : ITraits, new() - where I : IInterpolationFactory, new() - where B : IBootStrap, new() { testBMACurveConsistency( vars, interpolator, 1.0e-7 ); } - public void testBMACurveConsistency(CommonVars vars, I interpolator, double tolerance) - where T : ITraits, new() - where I : IInterpolationFactory, new() - where B : IBootStrap, new() - { - - // readjust settlement - vars.calendar = new JointCalendar(new BMAIndex().fixingCalendar(), - new USDLibor(new Period(3, TimeUnit.Months)).fixingCalendar(), - JointCalendar.JointCalendarRule.JoinHolidays); - vars.today = vars.calendar.adjust(Date.Today); - Settings.setEvaluationDate(vars.today); - vars.settlement = vars.calendar.advance(vars.today, vars.settlementDays, TimeUnit.Days); - - Handle riskFreeCurve = new Handle( - new FlatForward(vars.settlement, 0.04, new Actual360())); - - BMAIndex bmaIndex = new BMAIndex(); - IborIndex liborIndex = new USDLibor(new Period(3, TimeUnit.Months), riskFreeCurve); - for (int i = 0; i < vars.bmas; ++i) { - Handle f = new Handle(vars.fractions[i]); - vars.bmaHelpers.Add(new BMASwapRateHelper(f, new Period(vars.bmaData[i].n, vars.bmaData[i].units), - vars.settlementDays, - vars.calendar, - new Period(vars.bmaFrequency), - vars.bmaConvention, - vars.bmaDayCounter, - bmaIndex, - liborIndex)); - } - - int w = vars.today.weekday(); - Date lastWednesday = (w >= 4) ? vars.today - (w - 4) : vars.today + (4 - w - 7); - Date lastFixing = bmaIndex.fixingCalendar().adjust(lastWednesday); - bmaIndex.addFixing(lastFixing, 0.03); - - vars.termStructure = new PiecewiseYieldCurve(vars.settlement, vars.bmaHelpers, - new Actual360(), new List>(), new List(), 1.0e-12, interpolator); - - RelinkableHandle curveHandle = new RelinkableHandle(); - curveHandle.linkTo(vars.termStructure); - - // check BMA swaps - BMAIndex bma = new BMAIndex(curveHandle); - IborIndex libor3m = new USDLibor(new Period(3, TimeUnit.Months), riskFreeCurve); - for (int i = 0; i < vars.bmas; i++) { - Period tenor = new Period(vars.bmaData[i].n, vars.bmaData[i].units); - - Schedule bmaSchedule = new MakeSchedule().from(vars.settlement) - .to(vars.settlement + tenor) - .withFrequency(vars.bmaFrequency) - .withCalendar(bma.fixingCalendar()) - .withConvention(vars.bmaConvention) - .backwards() - .value(); - - Schedule liborSchedule = new MakeSchedule().from(vars.settlement) - .to(vars.settlement + tenor) - .withTenor(libor3m.tenor()) - .withCalendar(libor3m.fixingCalendar()) - .withConvention(libor3m.businessDayConvention()) - .endOfMonth(libor3m.endOfMonth()) - .backwards() - .value(); - - BMASwap swap = new BMASwap(BMASwap.Type.Payer, 100.0, liborSchedule, 0.75, 0.0, - libor3m, libor3m.dayCounter(), bmaSchedule, bma, vars.bmaDayCounter); - swap.setPricingEngine(new DiscountingSwapEngine(libor3m.forwardingTermStructure())); - - double expectedFraction = vars.bmaData[i].rate / 100, - estimatedFraction = swap.fairLiborFraction(); - double error = Math.Abs(expectedFraction - estimatedFraction); - QAssert.IsTrue(error < tolerance, - vars.bmaData[i].n + " year(s) BMA swap:\n" - + "\n estimated libor fraction: " + estimatedFraction - + "\n expected libor fraction: " + expectedFraction - + "\n error: " + error - + "\n tolerance: " + tolerance); - } - - // this is a workaround for grabage collection - // garbage collection needs a proper solution - IndexManager.instance().clearHistories(); - } - - public void testCurveCopy(CommonVars vars) - where T : ITraits, new() - where I : IInterpolationFactory, new() { - testCurveCopy(vars, FastActivator.Create()); - } - public void testCurveCopy(CommonVars vars, I interpolator) - where T : ITraits, new() - where I : IInterpolationFactory, new() { - - PiecewiseYieldCurve curve = new PiecewiseYieldCurve(vars.settlement, vars.instruments, - new Actual360(), - new List>(), - new List(), - 1.0e-12, - interpolator); - // necessary to trigger bootstrap - curve.recalculate(); - - PiecewiseYieldCurve copiedCurve = curve.Clone() as PiecewiseYieldCurve; - - // the two curves should be the same. - double t = 2.718; - var r1 = curve.zeroRate(t, Compounding.Continuous).value(); - var r2 = copiedCurve.zeroRate(t, Compounding.Continuous).value(); - if (!Utils.close(r1, r2)) { - QAssert.Fail("failed to link original and copied curve"); - } - - for (int i=0; i(vars); + } + + + public void testCurveConsistency(CommonVars vars) + where T : ITraits, new () + where I : IInterpolationFactory, new () + where B : IBootStrap, new () { testCurveConsistency(vars, FastActivator.Create(), 1.0e-9); } + public void testCurveConsistency(CommonVars vars, I interpolator) + where T : ITraits, new () + where I : IInterpolationFactory, new () + where B : IBootStrap, new () { testCurveConsistency(vars, FastActivator.Create(), 1.0e-9); } + public void testCurveConsistency(CommonVars vars, I interpolator, double tolerance) + where T : ITraits, new () + where I : IInterpolationFactory, new () + where B : IBootStrap, new () + { + + vars.termStructure = new PiecewiseYieldCurve(vars.settlement, vars.instruments, + new Actual360(), new List>(), new List(), 1.0e-12, interpolator); + + RelinkableHandle curveHandle = new RelinkableHandle(); + curveHandle.linkTo(vars.termStructure); + + // check deposits + for (int i = 0; i < vars.deposits; i++) + { + Euribor index = new Euribor(new Period(vars.depositData[i].n, vars.depositData[i].units), curveHandle); + double expectedRate = vars.depositData[i].rate / 100, + estimatedRate = index.fixing(vars.today); + QAssert.IsTrue(Math.Abs(expectedRate - estimatedRate) < tolerance, + vars.depositData[i].n + " " + + (vars.depositData[i].units == TimeUnit.Weeks ? "week(s)" : "month(s)") + + " deposit:" + + "\n estimated rate: " + estimatedRate + + "\n expected rate: " + expectedRate); + } + + // check swaps + IborIndex euribor6m = new Euribor6M(curveHandle); + for (int i = 0; i < vars.swaps; i++) + { + Period tenor = new Period(vars.swapData[i].n, vars.swapData[i].units); + + VanillaSwap swap = new MakeVanillaSwap(tenor, euribor6m, 0.0) + .withEffectiveDate(vars.settlement) + .withFixedLegDayCount(vars.fixedLegDayCounter) + .withFixedLegTenor(new Period(vars.fixedLegFrequency)) + .withFixedLegConvention(vars.fixedLegConvention) + .withFixedLegTerminationDateConvention(vars.fixedLegConvention); + + double expectedRate = vars.swapData[i].rate / 100, + estimatedRate = swap.fairRate(); + double error = Math.Abs(expectedRate - estimatedRate); + QAssert.IsTrue(error < tolerance, + vars.swapData[i].n + " year(s) swap:\n" + + "\n estimated rate: " + estimatedRate + + "\n expected rate: " + expectedRate + + "\n error: " + error + + "\n tolerance: " + tolerance); + } + + // check bonds + vars.termStructure = new PiecewiseYieldCurve(vars.settlement, vars.bondHelpers, + new Actual360(), new List>(), new List(), 1.0e-12, interpolator); + curveHandle.linkTo(vars.termStructure); + + for (int i = 0; i < vars.bonds; i++) + { + Date maturity = vars.calendar.advance(vars.today, vars.bondData[i].n, vars.bondData[i].units); + Date issue = vars.calendar.advance(maturity, -vars.bondData[i].length, TimeUnit.Years); + List coupons = new List() { vars.bondData[i].coupon / 100.0 }; + + FixedRateBond bond = new FixedRateBond(vars.bondSettlementDays, 100.0, + vars.schedules[i], coupons, + vars.bondDayCounter, vars.bondConvention, + vars.bondRedemption, issue); + + IPricingEngine bondEngine = new DiscountingBondEngine(curveHandle); + bond.setPricingEngine(bondEngine); + + double expectedPrice = vars.bondData[i].price, + estimatedPrice = bond.cleanPrice(); + QAssert.IsTrue(Math.Abs(expectedPrice - estimatedPrice) < tolerance, + i + 1 + " bond failure:" + + "\n estimated price: " + estimatedPrice + + "\n expected price: " + expectedPrice); + } + + // check FRA + vars.termStructure = new PiecewiseYieldCurve(vars.settlement, vars.fraHelpers, + new Actual360(), new List>(), new List(), 1.0e-12, interpolator); + curveHandle.linkTo(vars.termStructure); + + IborIndex euribor3m = new Euribor3M(curveHandle); + for (int i = 0; i < vars.fras; i++) + { + Date start = vars.calendar.advance(vars.settlement, + vars.fraData[i].n, + vars.fraData[i].units, + euribor3m.businessDayConvention(), + euribor3m.endOfMonth()); + Date end = vars.calendar.advance(start, 3, TimeUnit.Months, + euribor3m.businessDayConvention(), + euribor3m.endOfMonth()); + + ForwardRateAgreement fra = new ForwardRateAgreement(start, end, Position.Type.Long, vars.fraData[i].rate / 100, + 100.0, euribor3m, curveHandle); + double expectedRate = vars.fraData[i].rate / 100, + estimatedRate = fra.forwardRate().rate(); + QAssert.IsTrue(Math.Abs(expectedRate - estimatedRate) < tolerance, + i + 1 + " FRA failure:" + + "\n estimated rate: " + estimatedRate + + "\n expected rate: " + expectedRate); + } + } + + public void testBMACurveConsistency(CommonVars vars) + where T : ITraits, new () + where I : IInterpolationFactory, new () + where B : IBootStrap, new () { testBMACurveConsistency(vars, FastActivator.Create(), 1.0e-7); } + public void testBMACurveConsistency(CommonVars vars, I interpolator) + where T : ITraits, new () + where I : IInterpolationFactory, new () + where B : IBootStrap, new () { testBMACurveConsistency(vars, interpolator, 1.0e-7); } + public void testBMACurveConsistency(CommonVars vars, I interpolator, double tolerance) + where T : ITraits, new () + where I : IInterpolationFactory, new () + where B : IBootStrap, new () + { + + // readjust settlement + vars.calendar = new JointCalendar(new BMAIndex().fixingCalendar(), + new USDLibor(new Period(3, TimeUnit.Months)).fixingCalendar(), + JointCalendar.JointCalendarRule.JoinHolidays); + vars.today = vars.calendar.adjust(Date.Today); + Settings.setEvaluationDate(vars.today); + vars.settlement = vars.calendar.advance(vars.today, vars.settlementDays, TimeUnit.Days); + + Handle riskFreeCurve = new Handle( + new FlatForward(vars.settlement, 0.04, new Actual360())); + + BMAIndex bmaIndex = new BMAIndex(); + IborIndex liborIndex = new USDLibor(new Period(3, TimeUnit.Months), riskFreeCurve); + for (int i = 0; i < vars.bmas; ++i) + { + Handle f = new Handle(vars.fractions[i]); + vars.bmaHelpers.Add(new BMASwapRateHelper(f, new Period(vars.bmaData[i].n, vars.bmaData[i].units), + vars.settlementDays, + vars.calendar, + new Period(vars.bmaFrequency), + vars.bmaConvention, + vars.bmaDayCounter, + bmaIndex, + liborIndex)); + } + + int w = vars.today.weekday(); + Date lastWednesday = (w >= 4) ? vars.today - (w - 4) : vars.today + (4 - w - 7); + Date lastFixing = bmaIndex.fixingCalendar().adjust(lastWednesday); + bmaIndex.addFixing(lastFixing, 0.03); + + vars.termStructure = new PiecewiseYieldCurve(vars.settlement, vars.bmaHelpers, + new Actual360(), new List>(), new List(), 1.0e-12, interpolator); + + RelinkableHandle curveHandle = new RelinkableHandle(); + curveHandle.linkTo(vars.termStructure); + + // check BMA swaps + BMAIndex bma = new BMAIndex(curveHandle); + IborIndex libor3m = new USDLibor(new Period(3, TimeUnit.Months), riskFreeCurve); + for (int i = 0; i < vars.bmas; i++) + { + Period tenor = new Period(vars.bmaData[i].n, vars.bmaData[i].units); + + Schedule bmaSchedule = new MakeSchedule().from(vars.settlement) + .to(vars.settlement + tenor) + .withFrequency(vars.bmaFrequency) + .withCalendar(bma.fixingCalendar()) + .withConvention(vars.bmaConvention) + .backwards() + .value(); + + Schedule liborSchedule = new MakeSchedule().from(vars.settlement) + .to(vars.settlement + tenor) + .withTenor(libor3m.tenor()) + .withCalendar(libor3m.fixingCalendar()) + .withConvention(libor3m.businessDayConvention()) + .endOfMonth(libor3m.endOfMonth()) + .backwards() + .value(); + + BMASwap swap = new BMASwap(BMASwap.Type.Payer, 100.0, liborSchedule, 0.75, 0.0, + libor3m, libor3m.dayCounter(), bmaSchedule, bma, vars.bmaDayCounter); + swap.setPricingEngine(new DiscountingSwapEngine(libor3m.forwardingTermStructure())); + + double expectedFraction = vars.bmaData[i].rate / 100, + estimatedFraction = swap.fairLiborFraction(); + double error = Math.Abs(expectedFraction - estimatedFraction); + QAssert.IsTrue(error < tolerance, + vars.bmaData[i].n + " year(s) BMA swap:\n" + + "\n estimated libor fraction: " + estimatedFraction + + "\n expected libor fraction: " + expectedFraction + + "\n error: " + error + + "\n tolerance: " + tolerance); + } + + // this is a workaround for grabage collection + // garbage collection needs a proper solution + IndexManager.instance().clearHistories(); + } + + public void testCurveCopy(CommonVars vars) + where T : ITraits, new () + where I : IInterpolationFactory, new () + { + testCurveCopy(vars, FastActivator.Create()); + } + public void testCurveCopy(CommonVars vars, I interpolator) + where T : ITraits, new () + where I : IInterpolationFactory, new () + { + + PiecewiseYieldCurve curve = new PiecewiseYieldCurve(vars.settlement, vars.instruments, + new Actual360(), + new List>(), + new List(), + 1.0e-12, + interpolator); + // necessary to trigger bootstrap + curve.recalculate(); + + PiecewiseYieldCurve copiedCurve = curve.Clone() as PiecewiseYieldCurve; + + // the two curves should be the same. + double t = 2.718; + var r1 = curve.zeroRate(t, Compounding.Continuous).value(); + var r2 = copiedCurve.zeroRate(t, Compounding.Continuous).value(); + if (!Utils.close(r1, r2)) + { + QAssert.Fail("failed to link original and copied curve"); + } + + for (int i = 0; i < vars.rates.Count; ++i) + { + vars.rates[i].setValue(vars.rates[i].value() + 0.001); + } + + // now the original curve should have changed; the copied + // curve should not. + double r3 = curve.zeroRate(t, Compounding.Continuous).value(); + double r4 = copiedCurve.zeroRate(t, Compounding.Continuous).value(); + if (Utils.close(r1, r3)) + { + QAssert.Fail("failed to modify original curve"); + } + if (!Utils.close(r2, r4)) + { + QAssert.Fail("failed to break link between original and copied curve"); + } + } } } diff --git a/tests/QLNet.Tests/T_Quotes.cs b/tests/QLNet.Tests/T_Quotes.cs index 0f0029a14..b52444090 100644 --- a/tests/QLNet.Tests/T_Quotes.cs +++ b/tests/QLNet.Tests/T_Quotes.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008-2009 Andrea Maggiulli - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -19,9 +19,9 @@ under the terms of the QLNet license. You should have received a using System; #if NET40 || NET45 - using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -37,14 +37,15 @@ public class T_Quotes double mul10(double x) { return x * 10; } double sub10(double x) { return x - 10; } - double add(double x, double y) { return x + y; } + double add + (double x, double y) { return x + y; } double mul(double x, double y) { return x * y; } double sub(double x, double y) { return x - y; } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testObservable() { @@ -61,11 +62,11 @@ public void testObservable() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testObservableHandle() + public void testObservableHandle() { // Testing observability of quote handles @@ -78,71 +79,71 @@ public void testObservableHandle() h.registerWith(f.update); me1.setValue(3.14); - + if (!f.isUp()) - QAssert.Fail("Observer was not notified of quote change"); + QAssert.Fail("Observer was not notified of quote change"); f.lower(); SimpleQuote me2 = new SimpleQuote(0.0); h.linkTo(me2); if (!f.isUp()) - QAssert.Fail("Observer was not notified of quote change"); + QAssert.Fail("Observer was not notified of quote change"); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testDerived() + public void testDerived() { // Testing derived quotes - Func[] f = {add10,mul10,sub10}; + Func[] f = {add10, mul10, sub10}; Quote me = new SimpleQuote(17.0); Handle h = new Handle(me); - for (int i=0; i<3; i++) + for (int i = 0; i < 3; i++) { - DerivedQuote derived = new DerivedQuote(h,f[i]); - double x = derived.value(), - y = f[i](me.value()); - if (Math.Abs(x-y) > 1.0e-10) + DerivedQuote derived = new DerivedQuote(h, f[i]); + double x = derived.value(), + y = f[i](me.value()); + if (Math.Abs(x - y) > 1.0e-10) QAssert.Fail("derived quote yields " + x + "function result is " + y); } - + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testComposite() + public void testComposite() { // Testing composite quotes - Func[] f = { add, mul, sub }; + Func[] f = { add, mul, sub }; Quote me1 = new SimpleQuote(12.0), - me2 = new SimpleQuote(13.0); - Handle h1 = new Handle(me1), - h2 = new Handle(me2); + me2 = new SimpleQuote(13.0); + Handle h1 = new Handle(me1), + h2 = new Handle(me2); - for (int i=0; i<3; i++) + for (int i = 0; i < 3; i++) { - CompositeQuote composite = new CompositeQuote(h1,h2,f[i]); + CompositeQuote composite = new CompositeQuote(h1, h2, f[i]); double x = composite.value(), - y = f[i](me1.value(),me2.value()); - if (Math.Abs(x-y) > 1.0e-10) + y = f[i](me1.value(), me2.value()); + if (Math.Abs(x - y) > 1.0e-10) QAssert.Fail("composite quote yields " + x + "function result is " + y); } } - + } } diff --git a/tests/QLNet.Tests/T_RNGTraits.cs b/tests/QLNet.Tests/T_RNGTraits.cs index 3e2f4fc2d..79a2ba8d0 100644 --- a/tests/QLNet.Tests/T_RNGTraits.cs +++ b/tests/QLNet.Tests/T_RNGTraits.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,7 +21,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -33,16 +33,16 @@ namespace TestSuite public class T_RNGTraits { #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testGaussian() { //("Testing Gaussian pseudo-random number generation..."); var rsg = (InverseCumulativeRsg, InverseCumulativeNormal>) - new PseudoRandom().make_sequence_generator(100, 1234); + new PseudoRandom().make_sequence_generator(100, 1234); List values = rsg.nextSequence().value; double sum = 0.0; @@ -53,14 +53,14 @@ public void testGaussian() double tolerance = 1.0e-5; if (Math.Abs(sum - stored) > tolerance) QAssert.Fail("the sum of the samples does not match the stored value\n" - + " calculated: " + sum + "\n" - + " expected: " + stored); + + " calculated: " + sum + "\n" + + " expected: " + stored); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testDefaultPoisson() { @@ -78,14 +78,14 @@ public void testDefaultPoisson() double stored = 108.0; if (!Utils.close(sum, stored)) QAssert.Fail("the sum of the samples does not match the stored value\n" - + " calculated: " + sum + "\n" - + " expected: " + stored); + + " calculated: " + sum + "\n" + + " expected: " + stored); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testCustomPoisson() { @@ -103,8 +103,8 @@ public void testCustomPoisson() double stored = 409.0; if (!Utils.close(sum, stored)) QAssert.Fail("the sum of the samples does not match the stored value\n" - + " calculated: " + sum + "\n" - + " expected: " + stored); + + " calculated: " + sum + "\n" + + " expected: " + stored); } } } diff --git a/tests/QLNet.Tests/T_RangeAccrual.cs b/tests/QLNet.Tests/T_RangeAccrual.cs new file mode 100644 index 000000000..df7a58de1 --- /dev/null +++ b/tests/QLNet.Tests/T_RangeAccrual.cs @@ -0,0 +1,1584 @@ +// Copyright (C) 2008-2018 Andrea Maggiulli (a.maggiulli@gmail.com) +// +// This file is part of QLNet Project https://github.com/amaggiulli/qlnet +// QLNet is free software: you can redistribute it and/or modify it +// under the terms of the QLNet license. You should have received a +// copy of the license along with this program; if not, license is +// available at . +// +// QLNet is a based on QuantLib, a free-software/open-source library +// for financial quantitative analysts and developers - http://quantlib.org/ +// The QuantLib license is available online at http://quantlib.org/license.shtml. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the license for more details. + +using System; +using System.Collections.Generic; +#if NET40 || NET45 +using Microsoft.VisualStudio.TestTools.UnitTesting; +#else +using Xunit; +#endif +using QLNet; + +namespace TestSuite +{ +#if NET40 || NET45 + [TestClass()] +#endif + public class T_RangeAccrual + { + private class CommonVars + { + // General settings + public Date referenceDate, today, settlement; + public Calendar calendar; + + // Volatility Stuctures + public List> swaptionVolatilityStructures; + public Handle atmVol; + public Handle flatSwaptionVolatilityCube1; + public Handle flatSwaptionVolatilityCube2; + public Handle swaptionVolatilityCubeBySabr; + + public List atmOptionTenors, optionTenors; + public List atmSwapTenors, swapTenors; + public List strikeSpreads; + + public Matrix atmVolMatrix, volSpreadsMatrix; + public List>> volSpreads; + + public DayCounter dayCounter; + public BusinessDayConvention optionBDC; + public int swapSettlementDays; + public bool vegaWeightedSmileFit; + + // Range Accrual valuation + public double infiniteLowerStrike, infiniteUpperStrike; + public double gearing, correlation; + public double spread; + public Date startDate; + public Date endDate; + public Date paymentDate; + public int fixingDays; + public DayCounter rangeCouponDayCount; + public Schedule observationSchedule; + // Observation Schedule conventions + public Frequency observationsFrequency; + public BusinessDayConvention observationsConvention; + + // Term Structure + public RelinkableHandle termStructure = new RelinkableHandle(); + + // indices and index conventions + public Frequency fixedLegFrequency; + public BusinessDayConvention fixedLegConvention; + public DayCounter fixedLegDayCounter; + public IborIndex iborIndex; + + // Range accrual pricers properties + public List byCallSpread; + public double flatVol; + public List smilesOnExpiry; + public List smilesOnPayment; + + //test parameters + public double rateTolerance; + public double priceTolerance; + + + // cleanup + SavedSettings backup = new SavedSettings(); + + public void createYieldCurve() + { + + // Yield Curve + List dates = new List(); + dates.Add(new Date(39147)); dates.Add(new Date(39148)); dates.Add(new Date(39151)); + dates.Add(new Date(39153)); dates.Add(new Date(39159)); dates.Add(new Date(39166)); + dates.Add(new Date(39183)); dates.Add(new Date(39294)); dates.Add(new Date(39384)); + dates.Add(new Date(39474)); dates.Add(new Date(39567)); dates.Add(new Date(39658)); + dates.Add(new Date(39748)); dates.Add(new Date(39839)); dates.Add(new Date(39931)); + dates.Add(new Date(40250)); dates.Add(new Date(40614)); dates.Add(new Date(40978)); + dates.Add(new Date(41344)); dates.Add(new Date(41709)); dates.Add(new Date(42074)); + dates.Add(new Date(42441)); dates.Add(new Date(42805)); dates.Add(new Date(43170)); + dates.Add(new Date(43535)); dates.Add(new Date(43900)); dates.Add(new Date(44268)); + dates.Add(new Date(44632)); dates.Add(new Date(44996)); dates.Add(new Date(45361)); + dates.Add(new Date(45727)); dates.Add(new Date(46092)); dates.Add(new Date(46459)); + dates.Add(new Date(46823)); dates.Add(new Date(47188)); dates.Add(new Date(47553)); + dates.Add(new Date(47918)); dates.Add(new Date(48283)); dates.Add(new Date(48650)); + dates.Add(new Date(49014)); dates.Add(new Date(49379)); dates.Add(new Date(49744)); + dates.Add(new Date(50110)); dates.Add(new Date(53762)); dates.Add(new Date(57415)); + dates.Add(new Date(61068)); + + List zeroRates = new List(); + zeroRates.Add(0.02676568527); zeroRates.Add(0.02676568527); + zeroRates.Add(0.02676333038); zeroRates.Add(0.02682286201); + zeroRates.Add(0.02682038347); zeroRates.Add(0.02683030208); + zeroRates.Add(0.02700136766); zeroRates.Add(0.02932526033); + zeroRates.Add(0.03085568949); zeroRates.Add(0.03216370631); + zeroRates.Add(0.03321234116); zeroRates.Add(0.03404978072); + zeroRates.Add(0.03471117149); zeroRates.Add(0.03527141916); + zeroRates.Add(0.03574660393); zeroRates.Add(0.03691715582); + zeroRates.Add(0.03796468718); zeroRates.Add(0.03876457629); + zeroRates.Add(0.03942029708); zeroRates.Add(0.03999925325); + zeroRates.Add(0.04056663618); zeroRates.Add(0.04108743922); + zeroRates.Add(0.04156156761); zeroRates.Add(0.0419979179); + zeroRates.Add(0.04239486483); zeroRates.Add(0.04273799032); + zeroRates.Add(0.04305531203); zeroRates.Add(0.04336417578); + zeroRates.Add(0.04364017665); zeroRates.Add(0.04388153459); + zeroRates.Add(0.04408005012); zeroRates.Add(0.04424764425); + zeroRates.Add(0.04437504759); zeroRates.Add(0.04447696334); + zeroRates.Add(0.04456212318); zeroRates.Add(0.04464090072); + zeroRates.Add(0.0447068707); zeroRates.Add(0.04475921774); + zeroRates.Add(0.04477418345); zeroRates.Add(0.04477880755); + zeroRates.Add(0.04476692489); zeroRates.Add(0.04473779454); + zeroRates.Add(0.04468646066); zeroRates.Add(0.04430951558); + zeroRates.Add(0.04363922313); zeroRates.Add(0.04363601992); + + termStructure.linkTo(new InterpolatedZeroCurve(dates, zeroRates, new Actual365Fixed())); + } + + public void createVolatilityStructures() + { + + // ATM swaptionvol matrix + optionBDC = BusinessDayConvention.Following; + + atmOptionTenors = new List(); + atmOptionTenors.Add(new Period(1, TimeUnit.Months)); + atmOptionTenors.Add(new Period(6, TimeUnit.Months)); + atmOptionTenors.Add(new Period(1, TimeUnit.Years)); + atmOptionTenors.Add(new Period(5, TimeUnit.Years)); + atmOptionTenors.Add(new Period(10, TimeUnit.Years)); + atmOptionTenors.Add(new Period(30, TimeUnit.Years)); + + atmSwapTenors = new List(); + atmSwapTenors.Add(new Period(1, TimeUnit.Years)); + atmSwapTenors.Add(new Period(5, TimeUnit.Years)); + atmSwapTenors.Add(new Period(10, TimeUnit.Years)); + atmSwapTenors.Add(new Period(30, TimeUnit.Years)); + + atmVolMatrix = new Matrix(atmOptionTenors.Count, atmSwapTenors.Count); + + atmVolMatrix[0, 0] = flatVol; atmVolMatrix[0, 1] = flatVol; atmVolMatrix[0, 2] = flatVol; atmVolMatrix[0, 3] = flatVol; + atmVolMatrix[1, 0] = flatVol; atmVolMatrix[1, 1] = flatVol; atmVolMatrix[1, 2] = flatVol; atmVolMatrix[1, 3] = flatVol; + atmVolMatrix[2, 0] = flatVol; atmVolMatrix[2, 1] = flatVol; atmVolMatrix[2, 2] = flatVol; atmVolMatrix[2, 3] = flatVol; + atmVolMatrix[3, 0] = flatVol; atmVolMatrix[3, 1] = flatVol; atmVolMatrix[3, 2] = flatVol; atmVolMatrix[3, 3] = flatVol; + atmVolMatrix[4, 0] = flatVol; atmVolMatrix[4, 1] = flatVol; atmVolMatrix[4, 2] = flatVol; atmVolMatrix[4, 3] = flatVol; + atmVolMatrix[5, 0] = flatVol; atmVolMatrix[5, 1] = flatVol; atmVolMatrix[5, 2] = flatVol; atmVolMatrix[5, 3] = flatVol; + + int nRowsAtmVols = atmVolMatrix.rows(); + int nColsAtmVols = atmVolMatrix.columns(); + + + //swaptionvolcube + optionTenors = new List(); + optionTenors.Add(new Period(1, TimeUnit.Years)); + optionTenors.Add(new Period(10, TimeUnit.Years)); + optionTenors.Add(new Period(30, TimeUnit.Years)); + + swapTenors = new List(); + swapTenors.Add(new Period(2, TimeUnit.Years)); + swapTenors.Add(new Period(10, TimeUnit.Years)); + swapTenors.Add(new Period(30, TimeUnit.Years)); + + strikeSpreads = new List(); + strikeSpreads.Add(-0.020); + strikeSpreads.Add(-0.005); + strikeSpreads.Add(+0.000); + strikeSpreads.Add(+0.005); + strikeSpreads.Add(+0.020); + + int nRows = optionTenors.Count * swapTenors.Count; + int nCols = strikeSpreads.Count; + volSpreadsMatrix = new Matrix(nRows, nCols); + volSpreadsMatrix[0, 0] = 0.0599; volSpreadsMatrix[0, 1] = 0.0049; + volSpreadsMatrix[0, 2] = 0.0000; + volSpreadsMatrix[0, 3] = -0.0001; volSpreadsMatrix[0, 4] = 0.0127; + + volSpreadsMatrix[1, 0] = 0.0729; volSpreadsMatrix[1, 1] = 0.0086; + volSpreadsMatrix[1, 2] = 0.0000; + volSpreadsMatrix[1, 3] = -0.0024; volSpreadsMatrix[1, 4] = 0.0098; + + volSpreadsMatrix[2, 0] = 0.0738; volSpreadsMatrix[2, 1] = 0.0102; + volSpreadsMatrix[2, 2] = 0.0000; + volSpreadsMatrix[2, 3] = -0.0039; volSpreadsMatrix[2, 4] = 0.0065; + + volSpreadsMatrix[3, 0] = 0.0465; volSpreadsMatrix[3, 1] = 0.0063; + volSpreadsMatrix[3, 2] = 0.0000; + volSpreadsMatrix[3, 3] = -0.0032; volSpreadsMatrix[3, 4] = -0.0010; + + volSpreadsMatrix[4, 0] = 0.0558; volSpreadsMatrix[4, 1] = 0.0084; + volSpreadsMatrix[4, 2] = 0.0000; + volSpreadsMatrix[4, 3] = -0.0050; volSpreadsMatrix[4, 4] = -0.0057; + + volSpreadsMatrix[5, 0] = 0.0576; volSpreadsMatrix[5, 1] = 0.0083; + volSpreadsMatrix[5, 2] = 0.0000; + volSpreadsMatrix[5, 3] = -0.0043; volSpreadsMatrix[5, 4] = -0.0014; + + volSpreadsMatrix[6, 0] = 0.0437; volSpreadsMatrix[6, 1] = 0.0059; + volSpreadsMatrix[6, 2] = 0.0000; + volSpreadsMatrix[6, 3] = -0.0030; volSpreadsMatrix[6, 4] = -0.0006; + + volSpreadsMatrix[7, 0] = 0.0533; volSpreadsMatrix[7, 1] = 0.0078; + volSpreadsMatrix[7, 2] = 0.0000; + volSpreadsMatrix[7, 3] = -0.0045; volSpreadsMatrix[7, 4] = -0.0046; + + volSpreadsMatrix[8, 0] = 0.0545; volSpreadsMatrix[8, 1] = 0.0079; + volSpreadsMatrix[8, 2] = 0.0000; + volSpreadsMatrix[8, 3] = -0.0042; volSpreadsMatrix[8, 4] = -0.0020; + + + swapSettlementDays = 2; + fixedLegFrequency = Frequency.Annual; + fixedLegConvention = BusinessDayConvention.Unadjusted; + fixedLegDayCounter = new Thirty360(); + SwapIndex swapIndexBase = new EuriborSwapIsdaFixA(new Period(2, TimeUnit.Years), termStructure); + + SwapIndex shortSwapIndexBase = new EuriborSwapIsdaFixA(new Period(1, TimeUnit.Years), termStructure); + + vegaWeightedSmileFit = false; + + // ATM Volatility structure + List>> atmVolsHandle; + atmVolsHandle = new InitializedList>>(nRowsAtmVols); + int i; + for (i = 0; i < nRowsAtmVols; i++) + { + atmVolsHandle[i] = new InitializedList>(nColsAtmVols); + for (int j = 0; j < nColsAtmVols; j++) + { + atmVolsHandle[i][j] = new Handle(new SimpleQuote(atmVolMatrix[i, j])); + } + } + + dayCounter = new Actual365Fixed(); + + atmVol = new Handle(new SwaptionVolatilityMatrix(calendar, + optionBDC, atmOptionTenors, atmSwapTenors, atmVolsHandle, dayCounter)); + + // Volatility Cube without smile + List>> parametersGuess = new InitializedList>>(optionTenors.Count * swapTenors.Count); + for (i = 0; i < optionTenors.Count * swapTenors.Count; i++) + { + parametersGuess[i] = new InitializedList>(4); + parametersGuess[i][0] = new Handle(new SimpleQuote(0.2)); + parametersGuess[i][1] = new Handle(new SimpleQuote(0.5)); + parametersGuess[i][2] = new Handle(new SimpleQuote(0.4)); + parametersGuess[i][3] = new Handle(new SimpleQuote(0.0)); + } + List isParameterFixed = new InitializedList(4, false); + isParameterFixed[1] = true; + + List>> nullVolSpreads = new InitializedList>>(nRows); + for (i = 0; i < optionTenors.Count * swapTenors.Count; i++) + { + nullVolSpreads[i] = new InitializedList>(nCols); + for (int j = 0; j < strikeSpreads.Count; j++) + { + nullVolSpreads[i][j] = new Handle(new SimpleQuote(0.0)); + } + } + + SwaptionVolCube1x flatSwaptionVolatilityCube1ptr = new SwaptionVolCube1x( + atmVol, optionTenors, swapTenors, strikeSpreads, nullVolSpreads, swapIndexBase, + shortSwapIndexBase, vegaWeightedSmileFit, parametersGuess, isParameterFixed, + false); + flatSwaptionVolatilityCube1 = new Handle(flatSwaptionVolatilityCube1ptr); + flatSwaptionVolatilityCube1.link.enableExtrapolation(); + + SwaptionVolCube2 flatSwaptionVolatilityCube2ptr = new SwaptionVolCube2(atmVol, + optionTenors, swapTenors, strikeSpreads, nullVolSpreads, swapIndexBase, + shortSwapIndexBase, vegaWeightedSmileFit); + flatSwaptionVolatilityCube2 = new Handle(flatSwaptionVolatilityCube2ptr); + flatSwaptionVolatilityCube2.link.enableExtrapolation(); + + + // Volatility Cube with smile + volSpreads = new InitializedList>>(nRows); + for (i = 0; i < optionTenors.Count * swapTenors.Count; i++) + { + volSpreads[i] = new InitializedList>(nCols); + for (int j = 0; j < strikeSpreads.Count; j++) + { + volSpreads[i][j] = new Handle(new SimpleQuote(volSpreadsMatrix[i, j])); + } + } + + SwaptionVolCube1x swaptionVolatilityCubeBySabrPtr = new SwaptionVolCube1x( + atmVol, + optionTenors, + swapTenors, + strikeSpreads, + volSpreads, + swapIndexBase, + shortSwapIndexBase, + vegaWeightedSmileFit, + parametersGuess, + isParameterFixed, + false); + swaptionVolatilityCubeBySabr = new Handle(swaptionVolatilityCubeBySabrPtr); + swaptionVolatilityCubeBySabr.link.enableExtrapolation(); + + swaptionVolatilityStructures = new List>(); + swaptionVolatilityStructures.Add(flatSwaptionVolatilityCube2); + swaptionVolatilityStructures.Add(swaptionVolatilityCubeBySabr); + } + + public void createSmileSections() + { + List strikes = new List(), stdDevsOnExpiry = new List(), stdDevsOnPayment = new List(); + strikes.Add(0.003); stdDevsOnExpiry.Add(2.45489828353233); stdDevsOnPayment.Add(1.66175264544155); + strikes.Add(0.004); stdDevsOnExpiry.Add(2.10748097295326); stdDevsOnPayment.Add(1.46691241671427); + strikes.Add(0.005); stdDevsOnExpiry.Add(1.87317517200074); stdDevsOnPayment.Add(1.32415790098009); + strikes.Add(0.006); stdDevsOnExpiry.Add(1.69808302023488); stdDevsOnPayment.Add(1.21209617319357); + strikes.Add(0.007); stdDevsOnExpiry.Add(1.55911989073644); stdDevsOnPayment.Add(1.12016686638666); + strikes.Add(0.008); stdDevsOnExpiry.Add(1.44436083444893); stdDevsOnPayment.Add(1.04242066059821); + strikes.Add(0.009); stdDevsOnExpiry.Add(1.34687413874126); stdDevsOnPayment.Add(0.975173254741177); + strikes.Add(0.01); stdDevsOnExpiry.Add(1.26228953588707); stdDevsOnPayment.Add(0.916013813275761); + strikes.Add(0.011); stdDevsOnExpiry.Add(1.18769456816136); stdDevsOnPayment.Add(0.863267064731419); + strikes.Add(0.012); stdDevsOnExpiry.Add(1.12104324191799); stdDevsOnPayment.Add(0.815743793189994); + strikes.Add(0.013); stdDevsOnExpiry.Add(1.06085561121201); stdDevsOnPayment.Add(0.772552896805455); + strikes.Add(0.014); stdDevsOnExpiry.Add(1.00603120341767); stdDevsOnPayment.Add(0.733033340026564); + strikes.Add(0.015); stdDevsOnExpiry.Add(0.955725690399709); stdDevsOnPayment.Add(0.696673144338147); + strikes.Add(0.016); stdDevsOnExpiry.Add(0.909281318404816); stdDevsOnPayment.Add(0.663070503816902); + strikes.Add(0.017); stdDevsOnExpiry.Add(0.866185798452041); stdDevsOnPayment.Add(0.631911102538957); + strikes.Add(0.018); stdDevsOnExpiry.Add(0.826018547612582); stdDevsOnPayment.Add(0.602948672357772); + strikes.Add(0.019); stdDevsOnExpiry.Add(0.788447526732122); stdDevsOnPayment.Add(0.575982310311697); + strikes.Add(0.02); stdDevsOnExpiry.Add(0.753200779931885); stdDevsOnPayment.Add(0.550849997883271); + strikes.Add(0.021); stdDevsOnExpiry.Add(0.720053785498); stdDevsOnPayment.Add(0.527428600999225); + strikes.Add(0.022); stdDevsOnExpiry.Add(0.688823131326177); stdDevsOnPayment.Add(0.505604706697337); + strikes.Add(0.023); stdDevsOnExpiry.Add(0.659357028088728); stdDevsOnPayment.Add(0.485294065348527); + strikes.Add(0.024); stdDevsOnExpiry.Add(0.631532146956907); stdDevsOnPayment.Add(0.466418908064414); + strikes.Add(0.025); stdDevsOnExpiry.Add(0.605247295045587); stdDevsOnPayment.Add(0.448904706326966); + strikes.Add(0.026); stdDevsOnExpiry.Add(0.580413928580285); stdDevsOnPayment.Add(0.432686652729201); + strikes.Add(0.027); stdDevsOnExpiry.Add(0.556962477452476); stdDevsOnPayment.Add(0.417699939864133); + strikes.Add(0.028); stdDevsOnExpiry.Add(0.534829696108958); stdDevsOnPayment.Add(0.403876519954429); + strikes.Add(0.029); stdDevsOnExpiry.Add(0.513968150384827); stdDevsOnPayment.Add(0.391145104852406); + strikes.Add(0.03); stdDevsOnExpiry.Add(0.494330406115181); stdDevsOnPayment.Add(0.379434406410383); + strikes.Add(0.031); stdDevsOnExpiry.Add(0.475869029135118); stdDevsOnPayment.Add(0.368669896110328); + strikes.Add(0.032); stdDevsOnExpiry.Add(0.458549234390376); stdDevsOnPayment.Add(0.358777045434208); + strikes.Add(0.033); stdDevsOnExpiry.Add(0.442329912271372); stdDevsOnPayment.Add(0.349678085493644); + strikes.Add(0.034); stdDevsOnExpiry.Add(0.427163628613205); stdDevsOnPayment.Add(0.341304968511301); + strikes.Add(0.035); stdDevsOnExpiry.Add(0.413009273806291); stdDevsOnPayment.Add(0.333586406339497); + strikes.Add(0.036); stdDevsOnExpiry.Add(0.399819413685729); stdDevsOnPayment.Add(0.326457591571248); + strikes.Add(0.037); stdDevsOnExpiry.Add(0.387546614086615); stdDevsOnPayment.Add(0.31985630909585); + strikes.Add(0.038); stdDevsOnExpiry.Add(0.376137116288728); stdDevsOnPayment.Add(0.313728768765505); + strikes.Add(0.039); stdDevsOnExpiry.Add(0.365540323849504); stdDevsOnPayment.Add(0.308024420802767); + strikes.Add(0.04); stdDevsOnExpiry.Add(0.35570564032638); stdDevsOnPayment.Add(0.30269822405978); + strikes.Add(0.041); stdDevsOnExpiry.Add(0.346572982443814); stdDevsOnPayment.Add(0.297710321981251); + strikes.Add(0.042); stdDevsOnExpiry.Add(0.338091753759242); stdDevsOnPayment.Add(0.293025394530372); + strikes.Add(0.043); stdDevsOnExpiry.Add(0.330211357830103); stdDevsOnPayment.Add(0.288612334151791); + strikes.Add(0.044); stdDevsOnExpiry.Add(0.322881198213832); stdDevsOnPayment.Add(0.284443273660505); + strikes.Add(0.045); stdDevsOnExpiry.Add(0.316056686795423); stdDevsOnPayment.Add(0.280494558352965); + strikes.Add(0.046); stdDevsOnExpiry.Add(0.309691654321036); stdDevsOnPayment.Add(0.276744153710797); + strikes.Add(0.047); stdDevsOnExpiry.Add(0.303745307408855); stdDevsOnPayment.Add(0.273174237697079); + strikes.Add(0.048); stdDevsOnExpiry.Add(0.298180014954725); stdDevsOnPayment.Add(0.269767960385995); + strikes.Add(0.049); stdDevsOnExpiry.Add(0.292961308132149); stdDevsOnPayment.Add(0.266511064148011); + strikes.Add(0.05); stdDevsOnExpiry.Add(0.288057880392292); stdDevsOnPayment.Add(0.263391235575797); + strikes.Add(0.051); stdDevsOnExpiry.Add(0.283441587463978); stdDevsOnPayment.Add(0.260399077595342); + strikes.Add(0.052); stdDevsOnExpiry.Add(0.279088079809224); stdDevsOnPayment.Add(0.257518712391935); + strikes.Add(0.053); stdDevsOnExpiry.Add(0.274968896929089); stdDevsOnPayment.Add(0.254747223632261); + strikes.Add(0.054); stdDevsOnExpiry.Add(0.271067594979739); stdDevsOnPayment.Add(0.252074566168237); + strikes.Add(0.055); stdDevsOnExpiry.Add(0.267364567839682); stdDevsOnPayment.Add(0.249494259259166); + strikes.Add(0.056); stdDevsOnExpiry.Add(0.263842422981787); stdDevsOnPayment.Add(0.246999498127314); + strikes.Add(0.057); stdDevsOnExpiry.Add(0.26048629770105); stdDevsOnPayment.Add(0.244584774143087); + strikes.Add(0.058); stdDevsOnExpiry.Add(0.257282594203533); stdDevsOnPayment.Add(0.242244902713927); + strikes.Add(0.059); stdDevsOnExpiry.Add(0.254218979606362); stdDevsOnPayment.Add(0.23997567135838); + strikes.Add(0.06); stdDevsOnExpiry.Add(0.251284385937726); stdDevsOnPayment.Add(0.237772543557956); + strikes.Add(0.061); stdDevsOnExpiry.Add(0.248469326364644); stdDevsOnPayment.Add(0.235632278942307); + strikes.Add(0.062); stdDevsOnExpiry.Add(0.245764630281902); stdDevsOnPayment.Add(0.233550665029978); + strikes.Add(0.063); stdDevsOnExpiry.Add(0.243162391995349); stdDevsOnPayment.Add(0.231525109524691); + strikes.Add(0.064); stdDevsOnExpiry.Add(0.240655338266368); stdDevsOnPayment.Add(0.22955269609313); + strikes.Add(0.065); stdDevsOnExpiry.Add(0.238237144539637); stdDevsOnPayment.Add(0.227630508401982); + strikes.Add(0.066); stdDevsOnExpiry.Add(0.235901802487603); stdDevsOnPayment.Add(0.225756278192003); + strikes.Add(0.067); stdDevsOnExpiry.Add(0.233643936238243); stdDevsOnPayment.Add(0.223927413166912); + strikes.Add(0.068); stdDevsOnExpiry.Add(0.2314584861473); stdDevsOnPayment.Add(0.222142617178571); + strikes.Add(0.069); stdDevsOnExpiry.Add(0.229341341253818); stdDevsOnPayment.Add(0.220398973893664); + strikes.Add(0.07); stdDevsOnExpiry.Add(0.22728807436907); stdDevsOnPayment.Add(0.218695187164053); + strikes.Add(0.071); stdDevsOnExpiry.Add(0.225295206987632); stdDevsOnPayment.Add(0.217029636804562); + strikes.Add(0.072); stdDevsOnExpiry.Add(0.223359576831843); stdDevsOnPayment.Add(0.215400702630017); + strikes.Add(0.073); stdDevsOnExpiry.Add(0.221477389168511); stdDevsOnPayment.Add(0.213806764455244); + strikes.Add(0.074); stdDevsOnExpiry.Add(0.219646430403273); stdDevsOnPayment.Add(0.212246202095067); + strikes.Add(0.075); stdDevsOnExpiry.Add(0.21786353825847); stdDevsOnPayment.Add(0.210718367475417); + strikes.Add(0.076); stdDevsOnExpiry.Add(0.21612649913974); stdDevsOnPayment.Add(0.20922164041112); + strikes.Add(0.077); stdDevsOnExpiry.Add(0.214433415680486); stdDevsOnPayment.Add(0.20775504879107); + strikes.Add(0.078); stdDevsOnExpiry.Add(0.212781441830814); stdDevsOnPayment.Add(0.206317296467129); + strikes.Add(0.079); stdDevsOnExpiry.Add(0.21116931267966); stdDevsOnPayment.Add(0.20490741132819); + strikes.Add(0.08); stdDevsOnExpiry.Add(0.209594814632662); stdDevsOnPayment.Add(0.203524745300185); + strikes.Add(0.081); stdDevsOnExpiry.Add(0.20805636655099); stdDevsOnPayment.Add(0.202168002234973); + strikes.Add(0.082); stdDevsOnExpiry.Add(0.20655270352358); stdDevsOnPayment.Add(0.20083621002145); + strikes.Add(0.083); stdDevsOnExpiry.Add(0.20508161195607); stdDevsOnPayment.Add(0.199529044622581); + strikes.Add(0.084); stdDevsOnExpiry.Add(0.203642775620693); stdDevsOnPayment.Add(0.198245209890227); + strikes.Add(0.085); stdDevsOnExpiry.Add(0.202233980923088); stdDevsOnPayment.Add(0.196984381787351); + strikes.Add(0.086); stdDevsOnExpiry.Add(0.200854279179957); stdDevsOnPayment.Add(0.195745912239886); + strikes.Add(0.087); stdDevsOnExpiry.Add(0.199503037935767); stdDevsOnPayment.Add(0.19452850509969); + strikes.Add(0.088); stdDevsOnExpiry.Add(0.198178676051688); stdDevsOnPayment.Add(0.193332160366764); + strikes.Add(0.089); stdDevsOnExpiry.Add(0.196880244844423); stdDevsOnPayment.Add(0.192155905930003); + strikes.Add(0.09); stdDevsOnExpiry.Add(0.195606795630673); stdDevsOnPayment.Add(0.190999417752372); + strikes.Add(0.091); stdDevsOnExpiry.Add(0.194357695954907); stdDevsOnPayment.Add(0.189861723722766); + strikes.Add(0.092); stdDevsOnExpiry.Add(0.19313168090606); stdDevsOnPayment.Add(0.188742823841186); + strikes.Add(0.093); stdDevsOnExpiry.Add(0.191928434256365); stdDevsOnPayment.Add(0.187641745996527); + strikes.Add(0.094); stdDevsOnExpiry.Add(0.190746691094761); stdDevsOnPayment.Add(0.186558166151753); + strikes.Add(0.095); stdDevsOnExpiry.Add(0.189586451421245); stdDevsOnPayment.Add(0.185491436232795); + strikes.Add(0.096); stdDevsOnExpiry.Add(0.188446134096988); stdDevsOnPayment.Add(0.184441556239653); + strikes.Add(0.097); stdDevsOnExpiry.Add(0.18732573912199); stdDevsOnPayment.Add(0.183407878098257); + strikes.Add(0.098); stdDevsOnExpiry.Add(0.186224317812954); stdDevsOnPayment.Add(0.182390725845642); + strikes.Add(0.099); stdDevsOnExpiry.Add(0.185141553942112); stdDevsOnPayment.Add(0.181386859111458); + strikes.Add(0.1); stdDevsOnExpiry.Add(0.184076498826167); stdDevsOnPayment.Add(0.180399194229021); + strikes.Add(0.101); stdDevsOnExpiry.Add(0.18302915246512); stdDevsOnPayment.Add(0.17942643505019); + strikes.Add(0.102); stdDevsOnExpiry.Add(0.181999514858969); stdDevsOnPayment.Add(0.178466637352756); + strikes.Add(0.103); stdDevsOnExpiry.Add(0.180984739957821); stdDevsOnPayment.Add(0.177521421321893); + strikes.Add(0.104); stdDevsOnExpiry.Add(0.179986725128272); stdDevsOnPayment.Add(0.176590462920567); + strikes.Add(0.105); stdDevsOnExpiry.Add(0.179004521687023); stdDevsOnPayment.Add(0.175677650593196); + strikes.Add(0.106); stdDevsOnExpiry.Add(0.178041924367268); stdDevsOnPayment.Add(0.17476516230286); + strikes.Add(0.107); stdDevsOnExpiry.Add(0.177083754236237); stdDevsOnPayment.Add(0.173873088345724); + strikes.Add(0.108); stdDevsOnExpiry.Add(0.176145822682231); stdDevsOnPayment.Add(0.173000456610684); + strikes.Add(0.109); stdDevsOnExpiry.Add(0.175227181021952); stdDevsOnPayment.Add(0.172122316246049); + strikes.Add(0.11); stdDevsOnExpiry.Add(0.174309488044971); stdDevsOnPayment.Add(0.171266858473859); + strikes.Add(0.111); stdDevsOnExpiry.Add(0.173412982328314); stdDevsOnPayment.Add(0.170434407331149); + strikes.Add(0.112); stdDevsOnExpiry.Add(0.172536715188681); stdDevsOnPayment.Add(0.169585106262623); + strikes.Add(0.113); stdDevsOnExpiry.Add(0.171706301075121); stdDevsOnPayment.Add(0.168765292564274); + strikes.Add(0.114); stdDevsOnExpiry.Add(0.17079651379229); stdDevsOnPayment.Add(0.167976586421278); + strikes.Add(0.115); stdDevsOnExpiry.Add(0.169963569856602); stdDevsOnPayment.Add(0.167267917425907); + strikes.Add(0.116); stdDevsOnExpiry.Add(0.169192922790819); stdDevsOnPayment.Add(0.166364178135514); + strikes.Add(0.117); stdDevsOnExpiry.Add(0.168289776291075); stdDevsOnPayment.Add(0.165629586177349); + strikes.Add(0.118); stdDevsOnExpiry.Add(0.167505847659119); stdDevsOnPayment.Add(0.165014239848036); + strikes.Add(0.119); stdDevsOnExpiry.Add(0.166813308851542); stdDevsOnPayment.Add(0.164618590628398); + strikes.Add(0.12); stdDevsOnExpiry.Add(0.166305130831553); stdDevsOnPayment.Add(0.164530452554899); + strikes.Add(0.121); stdDevsOnExpiry.Add(0.166077130612255); stdDevsOnPayment.Add(0.162925173083904); + strikes.Add(0.122); stdDevsOnExpiry.Add(0.164586116695486); stdDevsOnPayment.Add(0.162717141307485); + strikes.Add(0.123); stdDevsOnExpiry.Add(0.164242693341591); stdDevsOnPayment.Add(0.162840275380755); + strikes.Add(0.124); stdDevsOnExpiry.Add(0.164213284159352); stdDevsOnPayment.Add(0.163289714748189); + strikes.Add(0.125); stdDevsOnExpiry.Add(0.164516546586962); stdDevsOnPayment.Add(0.16401944615083); + strikes.Add(0.126); stdDevsOnExpiry.Add(0.165118644253458); stdDevsOnPayment.Add(0.164961421811344); + strikes.Add(0.127); stdDevsOnExpiry.Add(0.165959810111063); stdDevsOnPayment.Add(0.166058935248619); + strikes.Add(0.128); stdDevsOnExpiry.Add(0.166976798606573); stdDevsOnPayment.Add(0.16725625209265); + strikes.Add(0.129); stdDevsOnExpiry.Add(0.168115851019766); stdDevsOnPayment.Add(0.16851675615849); + strikes.Add(0.13); stdDevsOnExpiry.Add(0.169332063007866); stdDevsOnPayment.Add(0.16981808889073); + strikes.Add(0.131); stdDevsOnExpiry.Add(0.170600136349594); stdDevsOnPayment.Add(0.171139511919136); + strikes.Add(0.132); stdDevsOnExpiry.Add(0.171891926773773); stdDevsOnPayment.Add(0.172468711836379); + strikes.Add(0.133); stdDevsOnExpiry.Add(0.173201742180614); stdDevsOnPayment.Add(0.173801476161007); + strikes.Add(0.134); stdDevsOnExpiry.Add(0.17451282249852); stdDevsOnPayment.Add(0.175129703967145); + strikes.Add(0.135); stdDevsOnExpiry.Add(0.175823902816426); stdDevsOnPayment.Add(0.17645371929183); + strikes.Add(0.136); stdDevsOnExpiry.Add(0.177132453312204); stdDevsOnPayment.Add(0.177767365431397); + strikes.Add(0.137); stdDevsOnExpiry.Add(0.178433098113831); stdDevsOnPayment.Add(0.179076475052476); + strikes.Add(0.138); stdDevsOnExpiry.Add(0.17972646967684); stdDevsOnPayment.Add(0.180372947229192); + strikes.Add(0.139); stdDevsOnExpiry.Add(0.181011935545698); stdDevsOnPayment.Add(0.181660994443001); + strikes.Add(0.14); stdDevsOnExpiry.Add(0.182286965898278); stdDevsOnPayment.Add(0.182938996508727); + strikes.Add(0.141); stdDevsOnExpiry.Add(0.18355314187341); stdDevsOnPayment.Add(0.18420889764858); + strikes.Add(0.142); stdDevsOnExpiry.Add(0.184810147243326); stdDevsOnPayment.Add(0.185468105566281); + strikes.Add(0.143); stdDevsOnExpiry.Add(0.186056717096965); stdDevsOnPayment.Add(0.186718888521073); + strikes.Add(0.144); stdDevsOnExpiry.Add(0.187295381256453); stdDevsOnPayment.Add(0.187958006142609); + strikes.Add(0.145); stdDevsOnExpiry.Add(0.188523609899662); stdDevsOnPayment.Add(0.189190318986411); + strikes.Add(0.146); stdDevsOnExpiry.Add(0.189745197759785); stdDevsOnPayment.Add(0.190412586682131); + strikes.Add(0.147); stdDevsOnExpiry.Add(0.190955085192566); stdDevsOnPayment.Add(0.191624809229768); + strikes.Add(0.148); stdDevsOnExpiry.Add(0.186502914474815); stdDevsOnPayment.Add(0.192830226999672); + strikes.Add(0.149); stdDevsOnExpiry.Add(0.187658094504074); stdDevsOnPayment.Add(0.194024951547423); + strikes.Add(0.15); stdDevsOnExpiry.Add(0.188817069266526); stdDevsOnPayment.Add(0.195212547280407); + strikes.Add(0.151); stdDevsOnExpiry.Add(0.189958019046315); stdDevsOnPayment.Add(0.196391394013447); + strikes.Add(0.152); stdDevsOnExpiry.Add(0.191090746904187); stdDevsOnPayment.Add(0.197560195598405); + strikes.Add(0.153); stdDevsOnExpiry.Add(0.192215885295675); stdDevsOnPayment.Add(0.19871895203528); + strikes.Add(0.154); stdDevsOnExpiry.Add(0.193335331587374); stdDevsOnPayment.Add(0.199872523879597); + strikes.Add(0.155); stdDevsOnExpiry.Add(0.194446555957158); stdDevsOnPayment.Add(0.195112095799581); + strikes.Add(0.156); stdDevsOnExpiry.Add(0.195547028582896); stdDevsOnPayment.Add(0.196220302459009); + strikes.Add(0.157); stdDevsOnExpiry.Add(0.196646236297571); stdDevsOnPayment.Add(0.197317167822215); + strikes.Add(0.158); stdDevsOnExpiry.Add(0.197736589634797); stdDevsOnPayment.Add(0.198405608222512); + strikes.Add(0.159); stdDevsOnExpiry.Add(0.198811131583722); stdDevsOnPayment.Add(0.19949340054874); + strikes.Add(0.16); stdDevsOnExpiry.Add(0.199887570899243); stdDevsOnPayment.Add(0.200565963134326); + strikes.Add(0.161); stdDevsOnExpiry.Add(0.20095167733189); stdDevsOnPayment.Add(0.201636905534738); + strikes.Add(0.162); stdDevsOnExpiry.Add(0.20200756184262); stdDevsOnPayment.Add(0.202695534527823); + strikes.Add(0.163); stdDevsOnExpiry.Add(0.203061232758988); stdDevsOnPayment.Add(0.203753839483873); + strikes.Add(0.164); stdDevsOnExpiry.Add(0.204112690080994); stdDevsOnPayment.Add(0.204791730106723); + strikes.Add(0.165); stdDevsOnExpiry.Add(0.205146754875869); stdDevsOnPayment.Add(0.205839341840621); + strikes.Add(0.166); stdDevsOnExpiry.Add(0.206178289848616); stdDevsOnPayment.Add(0.206869779611668); + strikes.Add(0.167); stdDevsOnExpiry.Add(0.207207294999235); stdDevsOnPayment.Add(0.207893412604981); + strikes.Add(0.168); stdDevsOnExpiry.Add(0.208224599722511); stdDevsOnPayment.Add(0.208916397524225); + strikes.Add(0.169); stdDevsOnExpiry.Add(0.209234947434935); stdDevsOnPayment.Add(0.209924476739862); + strikes.Add(0.17); stdDevsOnExpiry.Add(0.210235175858846); stdDevsOnPayment.Add(0.210934824214744); + strikes.Add(0.171); stdDevsOnExpiry.Add(0.211231609549565); stdDevsOnPayment.Add(0.211933506356369); + strikes.Add(0.172); stdDevsOnExpiry.Add(0.212231205517945); stdDevsOnPayment.Add(0.212931216386889); + strikes.Add(0.173); stdDevsOnExpiry.Add(0.213219101058981); stdDevsOnPayment.Add(0.213916613010082); + strikes.Add(0.174); stdDevsOnExpiry.Add(0.214192133895015); stdDevsOnPayment.Add(0.2149003894481); + strikes.Add(0.175); stdDevsOnExpiry.Add(0.215167064097645); stdDevsOnPayment.Add(0.215876064960245); + strikes.Add(0.176); stdDevsOnExpiry.Add(0.216146105261233); stdDevsOnPayment.Add(0.216845259731692); + strikes.Add(0.177); stdDevsOnExpiry.Add(0.217099215748008); stdDevsOnPayment.Add(0.217806029540231); + strikes.Add(0.178); stdDevsOnExpiry.Add(0.218056437195741); stdDevsOnPayment.Add(0.218763558978421); + strikes.Add(0.179); stdDevsOnExpiry.Add(0.219005120493791); stdDevsOnPayment.Add(0.219722060527715); + strikes.Add(0.18); stdDevsOnExpiry.Add(0.219951273969714); stdDevsOnPayment.Add(0.220671489040032); + strikes.Add(0.181); stdDevsOnExpiry.Add(0.220885410790527); stdDevsOnPayment.Add(0.221608280107987); + strikes.Add(0.182); stdDevsOnExpiry.Add(0.221831248038684); stdDevsOnPayment.Add(0.222542154842628); + strikes.Add(0.183); stdDevsOnExpiry.Add(0.222757162937581); stdDevsOnPayment.Add(0.223469224799535); + strikes.Add(0.184); stdDevsOnExpiry.Add(0.223673907231264); stdDevsOnPayment.Add(0.224396942830512); + strikes.Add(0.185); stdDevsOnExpiry.Add(0.224599189674629); stdDevsOnPayment.Add(0.225315911861546); + strikes.Add(0.186); stdDevsOnExpiry.Add(0.225503601085437); stdDevsOnPayment.Add(0.226230992448161); + strikes.Add(0.187); stdDevsOnExpiry.Add(0.226412755912736); stdDevsOnPayment.Add(0.227133759627449); + strikes.Add(0.188); stdDevsOnExpiry.Add(0.227313372590352); stdDevsOnPayment.Add(0.228049488288135); + strikes.Add(0.189); stdDevsOnExpiry.Add(0.228216519090096); stdDevsOnPayment.Add(0.228941886282305); + strikes.Add(0.19); stdDevsOnExpiry.Add(0.229108597618029); stdDevsOnPayment.Add(0.229833312165371); + strikes.Add(0.191); stdDevsOnExpiry.Add(0.229988343263088); stdDevsOnPayment.Add(0.230724738048437); + strikes.Add(0.192); stdDevsOnExpiry.Add(0.230883267840916); stdDevsOnPayment.Add(0.231599638042722); + strikes.Add(0.193); stdDevsOnExpiry.Add(0.231748467008738); stdDevsOnPayment.Add(0.232481018777706); + strikes.Add(0.194); stdDevsOnExpiry.Add(0.232617460909752); stdDevsOnPayment.Add(0.233360131253445); + strikes.Add(0.195); stdDevsOnExpiry.Add(0.233487087266298); stdDevsOnPayment.Add(0.234224662062612); + strikes.Add(0.196); stdDevsOnExpiry.Add(0.234348491700928); stdDevsOnPayment.Add(0.235093405353234); + strikes.Add(0.197); stdDevsOnExpiry.Add(0.2352057851746); stdDevsOnPayment.Add(0.235946918903214); + strikes.Add(0.198); stdDevsOnExpiry.Add(0.236064976014868); stdDevsOnPayment.Add(0.236808209342033); + strikes.Add(0.199); stdDevsOnExpiry.Add(0.236907723011302); stdDevsOnPayment.Add(0.237655242151315); + strikes.Add(0.2); stdDevsOnExpiry.Add(0.237747940185609); stdDevsOnPayment.Add(0.238496766331003); + strikes.Add(0.201); stdDevsOnExpiry.Add(0.238590687182044); stdDevsOnPayment.Add(0.239337318399586); + strikes.Add(0.202); stdDevsOnExpiry.Add(0.239419203929008); stdDevsOnPayment.Add(0.24017916661631); + strikes.Add(0.203); stdDevsOnExpiry.Add(0.240250882953632); stdDevsOnPayment.Add(0.241003840870182); + strikes.Add(0.204); stdDevsOnExpiry.Add(0.241075604967404); stdDevsOnPayment.Add(0.241832727605508); + strikes.Add(0.205); stdDevsOnExpiry.Add(0.24190317303107); stdDevsOnPayment.Add(0.242654809563101); + strikes.Add(0.206); stdDevsOnExpiry.Add(0.24272251917282); stdDevsOnPayment.Add(0.243478511705869); + strikes.Add(0.207); stdDevsOnExpiry.Add(0.243530164887227); stdDevsOnPayment.Add(0.244289576404275); + strikes.Add(0.208); stdDevsOnExpiry.Add(0.24434287024589); stdDevsOnPayment.Add(0.245096752658261); + strikes.Add(0.209); stdDevsOnExpiry.Add(0.245145772543807); stdDevsOnPayment.Add(0.245903280838178); + strikes.Add(0.21); stdDevsOnExpiry.Add(0.245951204663852); stdDevsOnPayment.Add(0.246714021499549); + strikes.Add(0.211); stdDevsOnExpiry.Add(0.246737030662404); stdDevsOnPayment.Add(0.247507912235104); + strikes.Add(0.212); stdDevsOnExpiry.Add(0.247526967621914); stdDevsOnPayment.Add(0.248306663526183); + strikes.Add(0.213); stdDevsOnExpiry.Add(0.24831563967036); stdDevsOnPayment.Add(0.2490927773729); + strikes.Add(0.214); stdDevsOnExpiry.Add(0.249111584957424); stdDevsOnPayment.Add(0.249878243145547); + strikes.Add(0.215); stdDevsOnExpiry.Add(0.249880650884377); stdDevsOnPayment.Add(0.250649127251622); + strikes.Add(0.216); stdDevsOnExpiry.Add(0.250656357594417); stdDevsOnPayment.Add(0.251433620913165); + strikes.Add(0.217); stdDevsOnExpiry.Add(0.251434594126584); stdDevsOnPayment.Add(0.25220580116738); + strikes.Add(0.218); stdDevsOnExpiry.Add(0.252199549092579); stdDevsOnPayment.Add(0.252970852606827); + strikes.Add(0.219); stdDevsOnExpiry.Add(0.252961025553147); stdDevsOnPayment.Add(0.253737200194414); + strikes.Add(0.22); stdDevsOnExpiry.Add(0.253727877885738); stdDevsOnPayment.Add(0.254501279522756); + strikes.Add(0.221); stdDevsOnExpiry.Add(0.254480499968858); stdDevsOnPayment.Add(0.255269571332552); + strikes.Add(0.222); stdDevsOnExpiry.Add(0.25523533564634); stdDevsOnPayment.Add(0.256016476698044); + strikes.Add(0.223); stdDevsOnExpiry.Add(0.255984162996268); stdDevsOnPayment.Add(0.256770834915338); + strikes.Add(0.224); stdDevsOnExpiry.Add(0.25673583639609); stdDevsOnPayment.Add(0.257510611466062); + strikes.Add(0.225); stdDevsOnExpiry.Add(0.257477706735166); stdDevsOnPayment.Add(0.258255572609344); + strikes.Add(0.226); stdDevsOnExpiry.Add(0.258220525757539); stdDevsOnPayment.Add(0.25900280201187); + strikes.Add(0.227); stdDevsOnExpiry.Add(0.258953541719166); stdDevsOnPayment.Add(0.259739986266314); + strikes.Add(0.228); stdDevsOnExpiry.Add(0.259691301097284); stdDevsOnPayment.Add(0.260471337854129); + strikes.Add(0.229); stdDevsOnExpiry.Add(0.260414197770398); stdDevsOnPayment.Add(0.26120171733084); + strikes.Add(0.23); stdDevsOnExpiry.Add(0.261138359354577); stdDevsOnPayment.Add(0.26193598525197); + strikes.Add(0.231); stdDevsOnExpiry.Add(0.261857461294499); stdDevsOnPayment.Add(0.262664096469436); + strikes.Add(0.232); stdDevsOnExpiry.Add(0.262581939106444); stdDevsOnPayment.Add(0.263373413538876); + strikes.Add(0.233); stdDevsOnExpiry.Add(0.263292502896683); stdDevsOnPayment.Add(0.264094071904539); + strikes.Add(0.234); stdDevsOnExpiry.Add(0.264006545192349); stdDevsOnPayment.Add(0.26480533319619); + strikes.Add(0.235); stdDevsOnExpiry.Add(0.264707305921843); stdDevsOnPayment.Add(0.265520482932259); + strikes.Add(0.236); stdDevsOnExpiry.Add(0.265417869712082); stdDevsOnPayment.Add(0.266215866409198); + strikes.Add(0.237); stdDevsOnExpiry.Add(0.266128433502322); stdDevsOnPayment.Add(0.266921619071255); + strikes.Add(0.238); stdDevsOnExpiry.Add(0.266818442487771); stdDevsOnPayment.Add(0.267621215029648); + strikes.Add(0.239); stdDevsOnExpiry.Add(0.267506237878858); stdDevsOnPayment.Add(0.268319190802866); + strikes.Add(0.24); stdDevsOnExpiry.Add(0.268213955619203); stdDevsOnPayment.Add(0.269024295390853); + strikes.Add(0.241); stdDevsOnExpiry.Add(0.268901118554758); stdDevsOnPayment.Add(0.269714494275234); + strikes.Add(0.242); stdDevsOnExpiry.Add(0.269581956934992); stdDevsOnPayment.Add(0.270383630752344); + strikes.Add(0.243); stdDevsOnExpiry.Add(0.270257103215438); stdDevsOnPayment.Add(0.271079662303353); + strikes.Add(0.244); stdDevsOnExpiry.Add(0.270943317467695); stdDevsOnPayment.Add(0.271764028521105); + strikes.Add(0.245); stdDevsOnExpiry.Add(0.271623207164631); stdDevsOnPayment.Add(0.272445154368508); + strikes.Add(0.246); stdDevsOnExpiry.Add(0.272295191167417); stdDevsOnPayment.Add(0.273122067734456); + strikes.Add(0.247); stdDevsOnExpiry.Add(0.272981721647439); stdDevsOnPayment.Add(0.273801573396684); + strikes.Add(0.248); stdDevsOnExpiry.Add(0.2736334670732); stdDevsOnPayment.Add(0.274467145466411); + strikes.Add(0.249); stdDevsOnExpiry.Add(0.274298494065133); stdDevsOnPayment.Add(0.275112951277007); + strikes.Add(0.25); stdDevsOnExpiry.Add(0.274975221484409); stdDevsOnPayment.Add(0.275792456939235); + strikes.Add(0.251); stdDevsOnExpiry.Add(0.275627599365702); stdDevsOnPayment.Add(0.276450252120124); + strikes.Add(0.252); stdDevsOnExpiry.Add(0.276287250485613); stdDevsOnPayment.Add(0.277106427115838); + strikes.Add(0.253); stdDevsOnExpiry.Add(0.27693614986148); stdDevsOnPayment.Add(0.277760009815272); + strikes.Add(0.254); stdDevsOnExpiry.Add(0.277595168525859); stdDevsOnPayment.Add(0.278409055996218); + strikes.Add(0.255); stdDevsOnExpiry.Add(0.278247230179386); stdDevsOnPayment.Add(0.279076248251119); + strikes.Add(0.256); stdDevsOnExpiry.Add(0.27889233482206); stdDevsOnPayment.Add(0.27972043387654); + strikes.Add(0.257); stdDevsOnExpiry.Add(0.279533328503776); stdDevsOnPayment.Add(0.280366887761207); + strikes.Add(0.258); stdDevsOnExpiry.Add(0.280163886669214); stdDevsOnPayment.Add(0.281011073386628); + strikes.Add(0.259); stdDevsOnExpiry.Add(0.280801401845504); stdDevsOnPayment.Add(0.281636464864025); + strikes.Add(0.26); stdDevsOnExpiry.Add(0.281444609121582); stdDevsOnPayment.Add(0.282278058193167); + strikes.Add(0.261); stdDevsOnExpiry.Add(0.282062518176379); stdDevsOnPayment.Add(0.2829177073001); + strikes.Add(0.262); stdDevsOnExpiry.Add(0.282703195630329); stdDevsOnPayment.Add(0.28354990355523); + strikes.Add(0.263); stdDevsOnExpiry.Add(0.283321420912892); stdDevsOnPayment.Add(0.284173026773382); + strikes.Add(0.264); stdDevsOnExpiry.Add(0.283962098366842); stdDevsOnPayment.Add(0.284814296065489); + strikes.Add(0.265); stdDevsOnExpiry.Add(0.284589810482385); stdDevsOnPayment.Add(0.285413116506022); + strikes.Add(0.266); stdDevsOnExpiry.Add(0.285200130070798); stdDevsOnPayment.Add(0.286036563761209); + strikes.Add(0.267); stdDevsOnExpiry.Add(0.285821833858787); stdDevsOnPayment.Add(0.286665843683024); + strikes.Add(0.268); stdDevsOnExpiry.Add(0.286418239425495); stdDevsOnPayment.Add(0.287277625604954); + strikes.Add(0.269); stdDevsOnExpiry.Add(0.287055438374019); stdDevsOnPayment.Add(0.28788454697136); + strikes.Add(0.27); stdDevsOnExpiry.Add(0.287650895257428); stdDevsOnPayment.Add(0.288504105782127); + strikes.Add(0.271); stdDevsOnExpiry.Add(0.288259001251479); stdDevsOnPayment.Add(0.289124960741035); + strikes.Add(0.272); stdDevsOnExpiry.Add(0.288866474789997); stdDevsOnPayment.Add(0.289720216774184); + strikes.Add(0.273); stdDevsOnExpiry.Add(0.289457504484683); stdDevsOnPayment.Add(0.29032389777024); + strikes.Add(0.274); stdDevsOnExpiry.Add(0.290065294250967); stdDevsOnPayment.Add(0.290925958581123); + strikes.Add(0.275); stdDevsOnExpiry.Add(0.290661383589909); stdDevsOnPayment.Add(0.291521538651306); + strikes.Add(0.276); stdDevsOnExpiry.Add(0.291270122039491); stdDevsOnPayment.Add(0.292117442758525); + strikes.Add(0.277); stdDevsOnExpiry.Add(0.291862732873007); stdDevsOnPayment.Add(0.292714643013883); + strikes.Add(0.278); stdDevsOnExpiry.Add(0.292448070467904); stdDevsOnPayment.Add(0.293307306750752); + strikes.Add(0.279); stdDevsOnExpiry.Add(0.293031826923971); stdDevsOnPayment.Add(0.293893489746923); + strikes.Add(0.28); stdDevsOnExpiry.Add(0.293630129857275); stdDevsOnPayment.Add(0.294490365965247); + strikes.Add(0.281); stdDevsOnExpiry.Add(0.294205348163659); stdDevsOnPayment.Add(0.295054514443043); + strikes.Add(0.282); stdDevsOnExpiry.Add(0.294780250242278); stdDevsOnPayment.Add(0.295640697439214); + strikes.Add(0.283); stdDevsOnExpiry.Add(0.295369066342601); stdDevsOnPayment.Add(0.296229796768699); + strikes.Add(0.284); stdDevsOnExpiry.Add(0.295941122371326); stdDevsOnPayment.Add(0.296821812431499); + strikes.Add(0.285); stdDevsOnExpiry.Add(0.296506537616964); stdDevsOnPayment.Add(0.297392117612959); + strikes.Add(0.286); stdDevsOnExpiry.Add(0.297095986172819); stdDevsOnPayment.Add(0.297958858387035); + strikes.Add(0.287); stdDevsOnExpiry.Add(0.297663931240585); stdDevsOnPayment.Add(0.298539532753612); + strikes.Add(0.288); stdDevsOnExpiry.Add(0.298226500436329); stdDevsOnPayment.Add(0.299106597564723); + strikes.Add(0.289); stdDevsOnExpiry.Add(0.298813735397823); stdDevsOnPayment.Add(0.299686299820195); + strikes.Add(0.29); stdDevsOnExpiry.Add(0.299351322600051); stdDevsOnPayment.Add(0.3002384589277); + strikes.Add(0.291); stdDevsOnExpiry.Add(0.299931284322926); stdDevsOnPayment.Add(0.300800663183287); + strikes.Add(0.292); stdDevsOnExpiry.Add(0.300491639924308); stdDevsOnPayment.Add(0.301358978994454); + strikes.Add(0.293); stdDevsOnExpiry.Add(0.30104408983154); stdDevsOnPayment.Add(0.30192507169446); + strikes.Add(0.294); stdDevsOnExpiry.Add(0.30161646208803); stdDevsOnPayment.Add(0.30247496254272); + strikes.Add(0.295); stdDevsOnExpiry.Add(0.302157527795685); stdDevsOnPayment.Add(0.303038462946447); + strikes.Add(0.296); stdDevsOnExpiry.Add(0.302717883397067); stdDevsOnPayment.Add(0.303587057646567); + strikes.Add(0.297); stdDevsOnExpiry.Add(0.303255786827061); stdDevsOnPayment.Add(0.304149261902154); + strikes.Add(0.298); stdDevsOnExpiry.Add(0.303781989829713); stdDevsOnPayment.Add(0.304700124861519); + strikes.Add(0.299); stdDevsOnExpiry.Add(0.304330645003752); stdDevsOnPayment.Add(0.305239646524661); + strikes.Add(0.3); stdDevsOnExpiry.Add(0.304881197544388); stdDevsOnPayment.Add(0.305780140298908); + strikes.Add(0.301); stdDevsOnExpiry.Add(0.305453569800878); stdDevsOnPayment.Add(0.306327114813854); + strikes.Add(0.302); stdDevsOnExpiry.Add(0.305970602198316); stdDevsOnPayment.Add(0.306869876847346); + strikes.Add(0.303); stdDevsOnExpiry.Add(0.306495540289904); stdDevsOnPayment.Add(0.307408102362348); + strikes.Add(0.304); stdDevsOnExpiry.Add(0.307054947207988); stdDevsOnPayment.Add(0.307955400914329); + strikes.Add(0.305); stdDevsOnExpiry.Add(0.307578936616277); stdDevsOnPayment.Add(0.308478072651655); + strikes.Add(0.306); stdDevsOnExpiry.Add(0.308105139618929); stdDevsOnPayment.Add(0.30902828753695); + strikes.Add(0.307); stdDevsOnExpiry.Add(0.308639564543498); stdDevsOnPayment.Add(0.309550959274277); + strikes.Add(0.308); stdDevsOnExpiry.Add(0.30916892982381); stdDevsOnPayment.Add(0.310072982937534); + strikes.Add(0.309); stdDevsOnExpiry.Add(0.309708414392635); stdDevsOnPayment.Add(0.310612504600676); + strikes.Add(0.31); stdDevsOnExpiry.Add(0.310226711701136); stdDevsOnPayment.Add(0.311149433967539); + strikes.Add(0.311); stdDevsOnExpiry.Add(0.310757025664747); stdDevsOnPayment.Add(0.311663356704923); + strikes.Add(0.312); stdDevsOnExpiry.Add(0.311267733506864); stdDevsOnPayment.Add(0.312172742923818); + strikes.Add(0.313); stdDevsOnExpiry.Add(0.31179520142058); stdDevsOnPayment.Add(0.312693470438935); + strikes.Add(0.314); stdDevsOnExpiry.Add(0.312293892607588); stdDevsOnPayment.Add(0.313225215213239); + strikes.Add(0.315); stdDevsOnExpiry.Add(0.312807130271834); stdDevsOnPayment.Add(0.313724880321086); + strikes.Add(0.316); stdDevsOnExpiry.Add(0.313339025374274); stdDevsOnPayment.Add(0.314244311688064); + strikes.Add(0.317); stdDevsOnExpiry.Add(0.313838981472347); stdDevsOnPayment.Add(0.31478739775859); + strikes.Add(0.318); stdDevsOnExpiry.Add(0.314357595008614); stdDevsOnPayment.Add(0.315282202310914); + strikes.Add(0.319); stdDevsOnExpiry.Add(0.314857234878921); stdDevsOnPayment.Add(0.315793208714983); + strikes.Add(0.32); stdDevsOnExpiry.Add(0.315366361582208); stdDevsOnPayment.Add(0.316289633452481); + strikes.Add(0.321); stdDevsOnExpiry.Add(0.315885291346242); stdDevsOnPayment.Add(0.31680258407876); + strikes.Add(0.322); stdDevsOnExpiry.Add(0.316385879899846); stdDevsOnPayment.Add(0.317304193408817); + strikes.Add(0.323); stdDevsOnExpiry.Add(0.316888682047813); stdDevsOnPayment.Add(0.317796729701896); + strikes.Add(0.324); stdDevsOnExpiry.Add(0.317366185974499); stdDevsOnPayment.Add(0.318296394809743); + strikes.Add(0.325); stdDevsOnExpiry.Add(0.317897448621407); stdDevsOnPayment.Add(0.318796059917591); + strikes.Add(0.326); stdDevsOnExpiry.Add(0.318374952548092); stdDevsOnPayment.Add(0.319321972025266); + strikes.Add(0.327); stdDevsOnExpiry.Add(0.318880916973719); stdDevsOnPayment.Add(0.319809971799856); + strikes.Add(0.328); stdDevsOnExpiry.Add(0.319367907733385); stdDevsOnPayment.Add(0.320308988833634); + strikes.Add(0.329); stdDevsOnExpiry.Add(0.319854898493051); stdDevsOnPayment.Add(0.320818051015494); + strikes.Add(0.33); stdDevsOnExpiry.Add(0.320354538363358); stdDevsOnPayment.Add(0.321299570049386); + strikes.Add(0.331); stdDevsOnExpiry.Add(0.320847853678344); stdDevsOnPayment.Add(0.321782061194382); + strikes.Add(0.332); stdDevsOnExpiry.Add(0.321319033049709); stdDevsOnPayment.Add(0.322270709043042); + strikes.Add(0.333); stdDevsOnExpiry.Add(0.321799699254055); stdDevsOnPayment.Add(0.322769726076819); + strikes.Add(0.334); stdDevsOnExpiry.Add(0.322302501402021); stdDevsOnPayment.Add(0.323246384555187); + strikes.Add(0.335); stdDevsOnExpiry.Add(0.322783167606367); stdDevsOnPayment.Add(0.323742809292685); + strikes.Add(0.336); stdDevsOnExpiry.Add(0.323279645199013); stdDevsOnPayment.Add(0.324182851586107); + strikes.Add(0.337); stdDevsOnExpiry.Add(0.323735013182078); stdDevsOnPayment.Add(0.324681868619885); + strikes.Add(0.338); stdDevsOnExpiry.Add(0.324212517108763); stdDevsOnPayment.Add(0.325174404912964); + strikes.Add(0.339); stdDevsOnExpiry.Add(0.324693183313109); stdDevsOnPayment.Add(0.325647498983947); + strikes.Add(0.34); stdDevsOnExpiry.Add(0.325170687239794); stdDevsOnPayment.Add(0.326114112314233); + strikes.Add(0.341); stdDevsOnExpiry.Add(0.325638704333499); stdDevsOnPayment.Add(0.326590446755566); + strikes.Add(0.342); stdDevsOnExpiry.Add(0.326132019648485); stdDevsOnPayment.Add(0.327066781196899); + strikes.Add(0.343); stdDevsOnExpiry.Add(0.326571576243249); stdDevsOnPayment.Add(0.327536634897533); + strikes.Add(0.344); stdDevsOnExpiry.Add(0.327049080169934); stdDevsOnPayment.Add(0.328019450079565); + strikes.Add(0.345); stdDevsOnExpiry.Add(0.327507610430659); stdDevsOnPayment.Add(0.32848606340985); + strikes.Add(0.346); stdDevsOnExpiry.Add(0.327997763467985); stdDevsOnPayment.Add(0.328949436369786); + strikes.Add(0.347); stdDevsOnExpiry.Add(0.328443644618068); stdDevsOnPayment.Add(0.329409568959373); + strikes.Add(0.348); stdDevsOnExpiry.Add(0.328933797655394); stdDevsOnPayment.Add(0.329876182289659); + strikes.Add(0.349); stdDevsOnExpiry.Add(0.329363867417177); stdDevsOnPayment.Add(0.330346035990293); + strikes.Add(0.35); stdDevsOnExpiry.Add(0.329841371343863); stdDevsOnPayment.Add(0.330799687839182); + strikes.Add(0.351); stdDevsOnExpiry.Add(0.330284090216286); stdDevsOnPayment.Add(0.331279262650864); + strikes.Add(0.352); stdDevsOnExpiry.Add(0.330755269587652); stdDevsOnPayment.Add(0.331723193388705); + strikes.Add(0.353); stdDevsOnExpiry.Add(0.331204313015395); stdDevsOnPayment.Add(0.332163883756196); + strikes.Add(0.354); stdDevsOnExpiry.Add(0.331647031887819); stdDevsOnPayment.Add(0.332624016345783); + strikes.Add(0.355); stdDevsOnExpiry.Add(0.332140347202805); stdDevsOnPayment.Add(0.333093870046418); + strikes.Add(0.356); stdDevsOnExpiry.Add(0.332579903797569); stdDevsOnPayment.Add(0.333560483376703); + strikes.Add(0.357); stdDevsOnExpiry.Add(0.333022622669992); stdDevsOnPayment.Add(0.334001173744195); + strikes.Add(0.358); stdDevsOnExpiry.Add(0.333474828375396); stdDevsOnPayment.Add(0.334464546704131); + strikes.Add(0.359); stdDevsOnExpiry.Add(0.33392387180314); stdDevsOnPayment.Add(0.334889035219877); + strikes.Add(0.36); stdDevsOnExpiry.Add(0.334341292454282); stdDevsOnPayment.Add(0.335342687068766); + strikes.Add(0.361); stdDevsOnExpiry.Add(0.334799822715007); stdDevsOnPayment.Add(0.335793098547305); + strikes.Add(0.362); stdDevsOnExpiry.Add(0.335271002086372); stdDevsOnPayment.Add(0.336246750396193); + strikes.Add(0.363); stdDevsOnExpiry.Add(0.335701071848155); stdDevsOnPayment.Add(0.33666799854159); + strikes.Add(0.364); stdDevsOnExpiry.Add(0.336159602108879); stdDevsOnPayment.Add(0.337144332982923); + strikes.Add(0.365); stdDevsOnExpiry.Add(0.336583347315342); stdDevsOnPayment.Add(0.337555860017272); + strikes.Add(0.366); stdDevsOnExpiry.Add(0.336994443411164); stdDevsOnPayment.Add(0.337993310014414); + strikes.Add(0.367); stdDevsOnExpiry.Add(0.337459298227208); stdDevsOnPayment.Add(0.338440481122604); + strikes.Add(0.368); stdDevsOnExpiry.Add(0.337892530266652); stdDevsOnPayment.Add(0.33886496963835); + strikes.Add(0.369); stdDevsOnExpiry.Add(0.338335249139075); stdDevsOnPayment.Add(0.339331582968636); + strikes.Add(0.37); stdDevsOnExpiry.Add(0.338768481178518); stdDevsOnPayment.Add(0.339749590743683); + strikes.Add(0.371); stdDevsOnExpiry.Add(0.339163765886039); stdDevsOnPayment.Add(0.340180560000127); + strikes.Add(0.372); stdDevsOnExpiry.Add(0.339634945257404); stdDevsOnPayment.Add(0.340601808145523); + strikes.Add(0.373); stdDevsOnExpiry.Add(0.340039716797906); stdDevsOnPayment.Add(0.341058700364761); + strikes.Add(0.374); stdDevsOnExpiry.Add(0.34048559794799); stdDevsOnPayment.Add(0.341473467769459); + strikes.Add(0.375); stdDevsOnExpiry.Add(0.340896694043811); stdDevsOnPayment.Add(0.341897956285205); + strikes.Add(0.376); stdDevsOnExpiry.Add(0.341336250638575); stdDevsOnPayment.Add(0.342348367763744); + strikes.Add(0.377); stdDevsOnExpiry.Add(0.341753671289717); stdDevsOnPayment.Add(0.34277285627949); + strikes.Add(0.378); stdDevsOnExpiry.Add(0.34217741649618); stdDevsOnPayment.Add(0.343174662202791); + strikes.Add(0.379); stdDevsOnExpiry.Add(0.342604323980302); stdDevsOnPayment.Add(0.343608871829585); + strikes.Add(0.38); stdDevsOnExpiry.Add(0.343021744631445); stdDevsOnPayment.Add(0.344000956641838); + strikes.Add(0.381); stdDevsOnExpiry.Add(0.343404380228325); stdDevsOnPayment.Add(0.344428685527933); + strikes.Add(0.382); stdDevsOnExpiry.Add(0.343843936823088); stdDevsOnPayment.Add(0.344875856636123); + strikes.Add(0.383); stdDevsOnExpiry.Add(0.344277168862531); stdDevsOnPayment.Add(0.34525822033733); + strikes.Add(0.384); stdDevsOnExpiry.Add(0.344700914068994); stdDevsOnPayment.Add(0.34570215107517); + strikes.Add(0.385); stdDevsOnExpiry.Add(0.345121496997796); stdDevsOnPayment.Add(0.346139601072313); + strikes.Add(0.386); stdDevsOnExpiry.Add(0.345538917648939); stdDevsOnPayment.Add(0.346502522551424); + strikes.Add(0.387); stdDevsOnExpiry.Add(0.345912066412839); stdDevsOnPayment.Add(0.346956174400312); + strikes.Add(0.388); stdDevsOnExpiry.Add(0.346354785285262); stdDevsOnPayment.Add(0.34737418217536); + strikes.Add(0.389); stdDevsOnExpiry.Add(0.346746907715123); stdDevsOnPayment.Add(0.347756545876566); + strikes.Add(0.39); stdDevsOnExpiry.Add(0.347151679255625); stdDevsOnPayment.Add(0.348171313281264); + strikes.Add(0.391); stdDevsOnExpiry.Add(0.347562775351446); stdDevsOnPayment.Add(0.348576359574914); + strikes.Add(0.392); stdDevsOnExpiry.Add(0.347986520557909); stdDevsOnPayment.Add(0.348968444387168); + strikes.Add(0.393); stdDevsOnExpiry.Add(0.348407103486711); stdDevsOnPayment.Add(0.349415615495358); + strikes.Add(0.394); stdDevsOnExpiry.Add(0.348773927695291); stdDevsOnPayment.Add(0.349820661789009); + strikes.Add(0.395); stdDevsOnExpiry.Add(0.349203997457074); stdDevsOnPayment.Add(0.350232188823358); + strikes.Add(0.396); stdDevsOnExpiry.Add(0.349624580385876); stdDevsOnPayment.Add(0.350637235117008); + strikes.Add(0.397); stdDevsOnExpiry.Add(0.349981917761475); stdDevsOnPayment.Add(0.351029319929262); + strikes.Add(0.398); stdDevsOnExpiry.Add(0.350396176134957); stdDevsOnPayment.Add(0.351434366222912); + strikes.Add(0.399); stdDevsOnExpiry.Add(0.350797785397799); stdDevsOnPayment.Add(0.351803768442721); + strikes.Add(0.4); stdDevsOnExpiry.Add(0.351174096439359); stdDevsOnPayment.Add(0.352250939550912); + strikes.Add(0.401); stdDevsOnExpiry.Add(0.351597841645821); stdDevsOnPayment.Add(0.352620341770721); + strikes.Add(0.402); stdDevsOnExpiry.Add(0.351986801798022); stdDevsOnPayment.Add(0.35303186880507); + strikes.Add(0.403); stdDevsOnExpiry.Add(0.352356788284262); stdDevsOnPayment.Add(0.353407751765577); + strikes.Add(0.404); stdDevsOnExpiry.Add(0.352793182601365); stdDevsOnPayment.Add(0.353799836577831); + strikes.Add(0.405); stdDevsOnExpiry.Add(0.353194791864206); stdDevsOnPayment.Add(0.354208123241831); + strikes.Add(0.406); stdDevsOnExpiry.Add(0.353548966962145); stdDevsOnPayment.Add(0.354587246572688); + strikes.Add(0.407); stdDevsOnExpiry.Add(0.353953738502647); stdDevsOnPayment.Add(0.354995533236687); + strikes.Add(0.408); stdDevsOnExpiry.Add(0.354333211821867); stdDevsOnPayment.Add(0.355374656567544); + strikes.Add(0.409); stdDevsOnExpiry.Add(0.354725334251728); stdDevsOnPayment.Add(0.355776462490846); + strikes.Add(0.41); stdDevsOnExpiry.Add(0.355104807570948); stdDevsOnPayment.Add(0.356129662858909); + strikes.Add(0.411); stdDevsOnExpiry.Add(0.355503254556129); stdDevsOnPayment.Add(0.356554151374654); + strikes.Add(0.412); stdDevsOnExpiry.Add(0.355863754209388); stdDevsOnPayment.Add(0.356910592113067); + strikes.Add(0.413); stdDevsOnExpiry.Add(0.35627168802755); stdDevsOnPayment.Add(0.357279994332876); + strikes.Add(0.414); stdDevsOnExpiry.Add(0.356660648179751); stdDevsOnPayment.Add(0.357691521367225); + strikes.Add(0.415); stdDevsOnExpiry.Add(0.357036959221311); stdDevsOnPayment.Add(0.358080365809129); + strikes.Add(0.416); stdDevsOnExpiry.Add(0.35740062115223); stdDevsOnPayment.Add(0.358472450621383); + strikes.Add(0.417); stdDevsOnExpiry.Add(0.357795905859751); stdDevsOnPayment.Add(0.358838612470843); + strikes.Add(0.418); stdDevsOnExpiry.Add(0.35815008095769); stdDevsOnPayment.Add(0.359211255061002); + strikes.Add(0.419); stdDevsOnExpiry.Add(0.358561177053512); stdDevsOnPayment.Add(0.359635743576747); + strikes.Add(0.42); stdDevsOnExpiry.Add(0.358915352151451); stdDevsOnPayment.Add(0.35999218431516); + strikes.Add(0.421); stdDevsOnExpiry.Add(0.359313799136632); stdDevsOnPayment.Add(0.360361586534969); + strikes.Add(0.422); stdDevsOnExpiry.Add(0.359674298789891); stdDevsOnPayment.Add(0.360756911717572); + strikes.Add(0.423); stdDevsOnExpiry.Add(0.36002847388783); stdDevsOnPayment.Add(0.361116592826334); + strikes.Add(0.424); stdDevsOnExpiry.Add(0.360455381371953); stdDevsOnPayment.Add(0.361502196897889); + strikes.Add(0.425); stdDevsOnExpiry.Add(0.360809556469892); stdDevsOnPayment.Add(0.361891041339793); + strikes.Add(0.426); stdDevsOnExpiry.Add(0.361141595624209); stdDevsOnPayment.Add(0.362260443559603); + strikes.Add(0.427); stdDevsOnExpiry.Add(0.361562178553012); stdDevsOnPayment.Add(0.362594201705571); + strikes.Add(0.428); stdDevsOnExpiry.Add(0.361922678206271); stdDevsOnPayment.Add(0.363021930591666); + strikes.Add(0.429); stdDevsOnExpiry.Add(0.36227369102655); stdDevsOnPayment.Add(0.363358929107983); + strikes.Add(0.43); stdDevsOnExpiry.Add(0.362637352957469); stdDevsOnPayment.Add(0.363741292809189); + strikes.Add(0.431); stdDevsOnExpiry.Add(0.362994690333068); stdDevsOnPayment.Add(0.364075050955157); + strikes.Add(0.432); stdDevsOnExpiry.Add(0.363342540875687); stdDevsOnPayment.Add(0.364473616508109); + strikes.Add(0.433); stdDevsOnExpiry.Add(0.363737825583208); stdDevsOnPayment.Add(0.364820336135474); + strikes.Add(0.434); stdDevsOnExpiry.Add(0.364095162958807); stdDevsOnPayment.Add(0.365186497984934); + strikes.Add(0.435); stdDevsOnExpiry.Add(0.364455662612066); stdDevsOnPayment.Add(0.365562380945441); + strikes.Add(0.436); stdDevsOnExpiry.Add(0.364866758707888); stdDevsOnPayment.Add(0.365889658350711); + strikes.Add(0.437); stdDevsOnExpiry.Add(0.365208284695186); stdDevsOnPayment.Add(0.366291464274012); + strikes.Add(0.438); stdDevsOnExpiry.Add(0.365584595736746); stdDevsOnPayment.Add(0.366657626123472); + strikes.Add(0.439); stdDevsOnExpiry.Add(0.365907148058083); stdDevsOnPayment.Add(0.367001105380488); + strikes.Add(0.44); stdDevsOnExpiry.Add(0.366270809989003); stdDevsOnPayment.Add(0.367380228711345); + strikes.Add(0.441); stdDevsOnExpiry.Add(0.366612335976301); stdDevsOnPayment.Add(0.367710746486964); + strikes.Add(0.442); stdDevsOnExpiry.Add(0.366998133850841); stdDevsOnPayment.Add(0.368083389077122); + strikes.Add(0.443); stdDevsOnExpiry.Add(0.367333335282819); stdDevsOnPayment.Add(0.368452791296931); + strikes.Add(0.444); stdDevsOnExpiry.Add(0.367693834936078); stdDevsOnPayment.Add(0.368793030183598); + strikes.Add(0.445); stdDevsOnExpiry.Add(0.368073308255299); stdDevsOnPayment.Add(0.369162432403407); + strikes.Add(0.446); stdDevsOnExpiry.Add(0.368440132463878); stdDevsOnPayment.Add(0.369492950179026); + strikes.Add(0.447); stdDevsOnExpiry.Add(0.368765847062875); stdDevsOnPayment.Add(0.369878554250581); + strikes.Add(0.448); stdDevsOnExpiry.Add(0.369104210772513); stdDevsOnPayment.Add(0.370196110544803); + strikes.Add(0.449); stdDevsOnExpiry.Add(0.369490008647054); stdDevsOnPayment.Add(0.370559032023914); + strikes.Add(0.45); stdDevsOnExpiry.Add(0.369825210079032); stdDevsOnPayment.Add(0.370896030540231); + strikes.Add(0.451); stdDevsOnExpiry.Add(0.370204683398252); stdDevsOnPayment.Add(0.371278394241437); + strikes.Add(0.452); stdDevsOnExpiry.Add(0.370514586608948); stdDevsOnPayment.Add(0.37159271016531); + strikes.Add(0.453); stdDevsOnExpiry.Add(0.370856112596247); stdDevsOnPayment.Add(0.371968593125818); + strikes.Add(0.454); stdDevsOnExpiry.Add(0.371197638583545); stdDevsOnPayment.Add(0.37232503386423); + strikes.Add(0.455); stdDevsOnExpiry.Add(0.371586598735746); stdDevsOnPayment.Add(0.372665272750896); + strikes.Add(0.456); stdDevsOnExpiry.Add(0.371874366002821); stdDevsOnPayment.Add(0.373002271267214); + strikes.Add(0.457); stdDevsOnExpiry.Add(0.37222854110076); stdDevsOnPayment.Add(0.373358712005626); + strikes.Add(0.458); stdDevsOnExpiry.Add(0.372579553921038); stdDevsOnPayment.Add(0.373685989410896); + strikes.Add(0.459); stdDevsOnExpiry.Add(0.372917917630676); stdDevsOnPayment.Add(0.374045670519657); + strikes.Add(0.46); stdDevsOnExpiry.Add(0.373332176004159); stdDevsOnPayment.Add(0.374382669035975); + strikes.Add(0.461); stdDevsOnExpiry.Add(0.373597807327613); stdDevsOnPayment.Add(0.374748830885435); + strikes.Add(0.462); stdDevsOnExpiry.Add(0.373977280646833); stdDevsOnPayment.Add(0.375095550512799); + strikes.Add(0.463); stdDevsOnExpiry.Add(0.374287183857529); stdDevsOnPayment.Add(0.375406626066323); + strikes.Add(0.464); stdDevsOnExpiry.Add(0.374616060734187); stdDevsOnPayment.Add(0.375727422730894); + strikes.Add(0.465); stdDevsOnExpiry.Add(0.375001858608727); stdDevsOnPayment.Add(0.376096824950703); + strikes.Add(0.466); stdDevsOnExpiry.Add(0.375311761819424); stdDevsOnPayment.Add(0.376420861985624); + strikes.Add(0.467); stdDevsOnExpiry.Add(0.375599529086499); stdDevsOnPayment.Add(0.376754620131592); + strikes.Add(0.468); stdDevsOnExpiry.Add(0.376004300627001); stdDevsOnPayment.Add(0.377098099388607); + strikes.Add(0.469); stdDevsOnExpiry.Add(0.376292067894076); stdDevsOnPayment.Add(0.377425376793877); + strikes.Add(0.47); stdDevsOnExpiry.Add(0.376646242992015); stdDevsOnPayment.Add(0.377755894569496); + strikes.Add(0.471); stdDevsOnExpiry.Add(0.376952983925051); stdDevsOnPayment.Add(0.378079931604416); + strikes.Add(0.472); stdDevsOnExpiry.Add(0.377332457244272); stdDevsOnPayment.Add(0.378449333824225); + strikes.Add(0.473); stdDevsOnExpiry.Add(0.377661334120929); stdDevsOnPayment.Add(0.378776611229495); + strikes.Add(0.474); stdDevsOnExpiry.Add(0.377999697830567); stdDevsOnPayment.Add(0.379113609745812); + strikes.Add(0.475); stdDevsOnExpiry.Add(0.378277978264662); stdDevsOnPayment.Add(0.379463569743526); + strikes.Add(0.476); stdDevsOnExpiry.Add(0.378635315640261); stdDevsOnPayment.Add(0.379761683815653); + strikes.Add(0.477); stdDevsOnExpiry.Add(0.378948381128618); stdDevsOnPayment.Add(0.380095441961621); + strikes.Add(0.478); stdDevsOnExpiry.Add(0.379264608894634); stdDevsOnPayment.Add(0.380471324922129); + strikes.Add(0.479); stdDevsOnExpiry.Add(0.379574512105331); stdDevsOnPayment.Add(0.380779160105303); + strikes.Add(0.48); stdDevsOnExpiry.Add(0.379900226704328); stdDevsOnPayment.Add(0.381122639362319); + strikes.Add(0.481); stdDevsOnExpiry.Add(0.380276537745888); stdDevsOnPayment.Add(0.381414272693747); + strikes.Add(0.482); stdDevsOnExpiry.Add(0.380605414622546); stdDevsOnPayment.Add(0.381773953802509); + strikes.Add(0.483); stdDevsOnExpiry.Add(0.380896344167281); stdDevsOnPayment.Add(0.382068827504286); + strikes.Add(0.484); stdDevsOnExpiry.Add(0.381234707876919); stdDevsOnPayment.Add(0.382405826020603); + strikes.Add(0.485); stdDevsOnExpiry.Add(0.381595207530179); stdDevsOnPayment.Add(0.382716901574127); + strikes.Add(0.486); stdDevsOnExpiry.Add(0.381835540632351); stdDevsOnPayment.Add(0.383031217498); + strikes.Add(0.487); stdDevsOnExpiry.Add(0.382139119287727); stdDevsOnPayment.Add(0.38331637008873); + strikes.Add(0.488); stdDevsOnExpiry.Add(0.382486969830346); stdDevsOnPayment.Add(0.383685772308539); + strikes.Add(0.489); stdDevsOnExpiry.Add(0.382847469483605); stdDevsOnPayment.Add(0.383964444158571); + strikes.Add(0.49); stdDevsOnExpiry.Add(0.38313207447302); stdDevsOnPayment.Add(0.384301442674888); + strikes.Add(0.491); stdDevsOnExpiry.Add(0.383479925015639); stdDevsOnPayment.Add(0.384661123783649); + strikes.Add(0.492); stdDevsOnExpiry.Add(0.383796152781656); stdDevsOnPayment.Add(0.384917113041236); + strikes.Add(0.493); stdDevsOnExpiry.Add(0.384106055992352); stdDevsOnPayment.Add(0.385280034520347); + strikes.Add(0.494); stdDevsOnExpiry.Add(0.384457068812631); stdDevsOnPayment.Add(0.38559435044422); + strikes.Add(0.495); stdDevsOnExpiry.Add(0.384744836079706); stdDevsOnPayment.Add(0.385931348960537); + strikes.Add(0.496); stdDevsOnExpiry.Add(0.385048414735082); stdDevsOnPayment.Add(0.386222982291966); + strikes.Add(0.497); stdDevsOnExpiry.Add(0.38537412933408); stdDevsOnPayment.Add(0.386559980808283); + strikes.Add(0.498); stdDevsOnExpiry.Add(0.385709330766058); stdDevsOnPayment.Add(0.386848373769362); + strikes.Add(0.499); stdDevsOnExpiry.Add(0.386038207642715); stdDevsOnPayment.Add(0.387146487841489); + strikes.Add(0.5); stdDevsOnExpiry.Add(0.386338624020431); stdDevsOnPayment.Add(0.387460803765362); + strikes.Add(0.501); stdDevsOnExpiry.Add(0.386623229009846); stdDevsOnPayment.Add(0.387765398578187); + strikes.Add(0.502); stdDevsOnExpiry.Add(0.386952105886504); stdDevsOnPayment.Add(0.388108877835202); + strikes.Add(0.503); stdDevsOnExpiry.Add(0.38724935998656); stdDevsOnPayment.Add(0.388374588203837); + strikes.Add(0.504); stdDevsOnExpiry.Add(0.387584561418537); stdDevsOnPayment.Add(0.388718067460853); + strikes.Add(0.505); stdDevsOnExpiry.Add(0.387856517297312); stdDevsOnPayment.Add(0.388980537459138); + strikes.Add(0.506); stdDevsOnExpiry.Add(0.388213854672911); stdDevsOnPayment.Add(0.3893402185679); + strikes.Add(0.507); stdDevsOnExpiry.Add(0.388514271050627); stdDevsOnPayment.Add(0.389605928936535); + strikes.Add(0.508); stdDevsOnExpiry.Add(0.388748279597479); stdDevsOnPayment.Add(0.389994773378439); + strikes.Add(0.509); stdDevsOnExpiry.Add(0.389073994196477); stdDevsOnPayment.Add(0.390247522265677); + strikes.Add(0.51); stdDevsOnExpiry.Add(0.389431331572076); stdDevsOnPayment.Add(0.39056183818955); + strikes.Add(0.511); stdDevsOnExpiry.Add(0.389643204175307); stdDevsOnPayment.Add(0.390882634854121); + strikes.Add(0.512); stdDevsOnExpiry.Add(0.390025839772187); stdDevsOnPayment.Add(0.391193710407644); + strikes.Add(0.513); stdDevsOnExpiry.Add(0.390351554371185); stdDevsOnPayment.Add(0.391491824479771); + strikes.Add(0.514); stdDevsOnExpiry.Add(0.390607698861658); stdDevsOnPayment.Add(0.391828822996088); + strikes.Add(0.515); stdDevsOnExpiry.Add(0.390901790684054); stdDevsOnPayment.Add(0.392081571883326); + strikes.Add(0.516); stdDevsOnExpiry.Add(0.391218018450071); stdDevsOnPayment.Add(0.392399128177548); + strikes.Add(0.517); stdDevsOnExpiry.Add(0.391524759383107); stdDevsOnPayment.Add(0.392726405582818); + strikes.Add(0.518); stdDevsOnExpiry.Add(0.391809364372522); stdDevsOnPayment.Add(0.393034240765992); + strikes.Add(0.519); stdDevsOnExpiry.Add(0.392093969361938); stdDevsOnPayment.Add(0.393261066690437); + strikes.Add(0.52); stdDevsOnExpiry.Add(0.392419683960935); stdDevsOnPayment.Add(0.393617507428849); + strikes.Add(0.521); stdDevsOnExpiry.Add(0.392723262616311); stdDevsOnPayment.Add(0.393948025204468); + strikes.Add(0.522); stdDevsOnExpiry.Add(0.393001543050406); stdDevsOnPayment.Add(0.39422345668415); + strikes.Add(0.523); stdDevsOnExpiry.Add(0.393336744482384); stdDevsOnPayment.Add(0.394476205571388); + strikes.Add(0.524); stdDevsOnExpiry.Add(0.393611862638818); stdDevsOnPayment.Add(0.394813204087705); + strikes.Add(0.525); stdDevsOnExpiry.Add(0.393940739515476); stdDevsOnPayment.Add(0.395075674085991); + strikes.Add(0.526); stdDevsOnExpiry.Add(0.394168423507008); stdDevsOnPayment.Add(0.395435355194752); + strikes.Add(0.527); stdDevsOnExpiry.Add(0.394459353051744); stdDevsOnPayment.Add(0.39568810408199); + strikes.Add(0.528); stdDevsOnExpiry.Add(0.394800879039042); stdDevsOnPayment.Add(0.396012141116911); + strikes.Add(0.529); stdDevsOnExpiry.Add(0.395025400752914); stdDevsOnPayment.Add(0.396274611115196); + strikes.Add(0.53); stdDevsOnExpiry.Add(0.395347953074251); stdDevsOnPayment.Add(0.396572725187323); + strikes.Add(0.531); stdDevsOnExpiry.Add(0.395613584397705); stdDevsOnPayment.Add(0.396893521851894); + strikes.Add(0.532); stdDevsOnExpiry.Add(0.395951948107343); stdDevsOnPayment.Add(0.397162472590878); + strikes.Add(0.533); stdDevsOnExpiry.Add(0.39626817587336); stdDevsOnPayment.Add(0.397483269255449); + strikes.Add(0.534); stdDevsOnExpiry.Add(0.396505346697872); stdDevsOnPayment.Add(0.397774902586878); + strikes.Add(0.535); stdDevsOnExpiry.Add(0.39683106129687); stdDevsOnPayment.Add(0.398034132214814); + strikes.Add(0.536); stdDevsOnExpiry.Add(0.397137802229906); stdDevsOnPayment.Add(0.398329005916591); + strikes.Add(0.537); stdDevsOnExpiry.Add(0.39739078444272); stdDevsOnPayment.Add(0.398656283321861); + strikes.Add(0.538); stdDevsOnExpiry.Add(0.397672227154475); stdDevsOnPayment.Add(0.39890579183875); + strikes.Add(0.539); stdDevsOnExpiry.Add(0.397931533922608); stdDevsOnPayment.Add(0.399184463688781); + strikes.Add(0.54); stdDevsOnExpiry.Add(0.398269897632246); stdDevsOnPayment.Add(0.399463135538813); + strikes.Add(0.541); stdDevsOnExpiry.Add(0.398484932513138); stdDevsOnPayment.Add(0.399770970721987); + strikes.Add(0.542); stdDevsOnExpiry.Add(0.398826458500436); stdDevsOnPayment.Add(0.400023719609225); + strikes.Add(0.543); stdDevsOnExpiry.Add(0.399126874878152); stdDevsOnPayment.Add(0.400334795162749); + strikes.Add(0.544); stdDevsOnExpiry.Add(0.399398830756927); stdDevsOnPayment.Add(0.400603745901733); + strikes.Add(0.545); stdDevsOnExpiry.Add(0.399680273468682); stdDevsOnPayment.Add(0.400914821455256); + strikes.Add(0.546); stdDevsOnExpiry.Add(0.399917444293194); stdDevsOnPayment.Add(0.40122589700878); + strikes.Add(0.547); stdDevsOnExpiry.Add(0.400274781668793); stdDevsOnPayment.Add(0.401465684414621); + strikes.Add(0.548); stdDevsOnExpiry.Add(0.400543575269907); stdDevsOnPayment.Add(0.401812404041986); + strikes.Add(0.549); stdDevsOnExpiry.Add(0.400828180259323); stdDevsOnPayment.Add(0.402016547373986); + strikes.Add(0.55); stdDevsOnExpiry.Add(0.401103298415757); stdDevsOnPayment.Add(0.402347065149604); + strikes.Add(0.551); stdDevsOnExpiry.Add(0.401356280628571); stdDevsOnPayment.Add(0.402612775518239); + strikes.Add(0.552); stdDevsOnExpiry.Add(0.401666183839267); stdDevsOnPayment.Add(0.402875245516525); + strikes.Add(0.553); stdDevsOnExpiry.Add(0.401874894164838); stdDevsOnPayment.Add(0.403186321070048); + strikes.Add(0.554); stdDevsOnExpiry.Add(0.402238556095758); stdDevsOnPayment.Add(0.403468233290429); + strikes.Add(0.555); stdDevsOnExpiry.Add(0.40246624008729); stdDevsOnPayment.Add(0.403714501436968); + strikes.Add(0.556); stdDevsOnExpiry.Add(0.402747682799045); stdDevsOnPayment.Add(0.403989932916651); + strikes.Add(0.557); stdDevsOnExpiry.Add(0.403070235120382); stdDevsOnPayment.Add(0.404297768099825); + strikes.Add(0.558); stdDevsOnExpiry.Add(0.403326379610856); stdDevsOnPayment.Add(0.404589401431253); + strikes.Add(0.559); stdDevsOnExpiry.Add(0.403535089936427); stdDevsOnPayment.Add(0.404884275133031); + strikes.Add(0.56); stdDevsOnExpiry.Add(0.403797558982221); stdDevsOnPayment.Add(0.405104620316777); + strikes.Add(0.561); stdDevsOnExpiry.Add(0.404126435858878); stdDevsOnPayment.Add(0.405393013277856); + strikes.Add(0.562); stdDevsOnExpiry.Add(0.404423689958934); stdDevsOnPayment.Add(0.405668444757538); + strikes.Add(0.563); stdDevsOnExpiry.Add(0.404733593169631); stdDevsOnPayment.Add(0.405901751422681); + strikes.Add(0.564); stdDevsOnExpiry.Add(0.404977088549464); stdDevsOnPayment.Add(0.406203105865157); + strikes.Add(0.565); stdDevsOnExpiry.Add(0.405220583929296); stdDevsOnPayment.Add(0.406510941048331); + strikes.Add(0.566); stdDevsOnExpiry.Add(0.405533649417653); stdDevsOnPayment.Add(0.406741007343125); + strikes.Add(0.567); stdDevsOnExpiry.Add(0.405742359743224); stdDevsOnPayment.Add(0.407042361785601); + strikes.Add(0.568); stdDevsOnExpiry.Add(0.406083885730522); stdDevsOnPayment.Add(0.407295110672839); + strikes.Add(0.569); stdDevsOnExpiry.Add(0.406295758333754); stdDevsOnPayment.Add(0.407593224744966); + strikes.Add(0.57); stdDevsOnExpiry.Add(0.406643608876372); stdDevsOnPayment.Add(0.40786217548395); + strikes.Add(0.571); stdDevsOnExpiry.Add(0.406814371870021); stdDevsOnPayment.Add(0.408082520667695); + strikes.Add(0.572); stdDevsOnExpiry.Add(0.407114788247737); stdDevsOnPayment.Add(0.408416278813663); + strikes.Add(0.573); stdDevsOnExpiry.Add(0.407434178291414); stdDevsOnPayment.Add(0.408636623997409); + strikes.Add(0.574); stdDevsOnExpiry.Add(0.407623914951024); stdDevsOnPayment.Add(0.40891853621779); + strikes.Add(0.575); stdDevsOnExpiry.Add(0.407936980439381); stdDevsOnPayment.Add(0.409252294363758); + strikes.Add(0.576); stdDevsOnExpiry.Add(0.408265857316039); stdDevsOnPayment.Add(0.409449956955059); + strikes.Add(0.577); stdDevsOnExpiry.Add(0.408496703585231); stdDevsOnPayment.Add(0.409748071027186); + strikes.Add(0.578); stdDevsOnExpiry.Add(0.408774984019326); stdDevsOnPayment.Add(0.410000819914424); + strikes.Add(0.579); stdDevsOnExpiry.Add(0.409024803954479); stdDevsOnPayment.Add(0.410295693616202); + strikes.Add(0.58); stdDevsOnExpiry.Add(0.409261974778992); stdDevsOnPayment.Add(0.410567884725535); + strikes.Add(0.581); stdDevsOnExpiry.Add(0.409518119269465); stdDevsOnPayment.Add(0.410755826205789); + strikes.Add(0.582); stdDevsOnExpiry.Add(0.409831184757822); stdDevsOnPayment.Add(0.411125228425598); + strikes.Add(0.583); stdDevsOnExpiry.Add(0.410109465191917); stdDevsOnPayment.Add(0.411394179164582); + strikes.Add(0.584); stdDevsOnExpiry.Add(0.41034979829409); stdDevsOnPayment.Add(0.411614524348328); + strikes.Add(0.585); stdDevsOnExpiry.Add(0.410583806840942); stdDevsOnPayment.Add(0.411867273235566); + strikes.Add(0.586); stdDevsOnExpiry.Add(0.410931657383561); stdDevsOnPayment.Add(0.412171868048391); + strikes.Add(0.587); stdDevsOnExpiry.Add(0.41109925809955); stdDevsOnPayment.Add(0.41237925175074); + strikes.Add(0.588); stdDevsOnExpiry.Add(0.411374376255984); stdDevsOnPayment.Add(0.412670885082168); + strikes.Add(0.589); stdDevsOnExpiry.Add(0.411690604022001); stdDevsOnPayment.Add(0.41294631656185); + strikes.Add(0.59); stdDevsOnExpiry.Add(0.411943586234814); stdDevsOnPayment.Add(0.413215267300834); + strikes.Add(0.591); stdDevsOnExpiry.Add(0.412215542113589); stdDevsOnPayment.Add(0.413458295077025); + strikes.Add(0.592); stdDevsOnExpiry.Add(0.412348357775316); stdDevsOnPayment.Add(0.413707803593913); + strikes.Add(0.593); stdDevsOnExpiry.Add(0.412677234651974); stdDevsOnPayment.Add(0.413931389148008); + strikes.Add(0.594); stdDevsOnExpiry.Add(0.412908080921166); stdDevsOnPayment.Add(0.4141679361835); + strikes.Add(0.595); stdDevsOnExpiry.Add(0.41318003679994); stdDevsOnPayment.Add(0.414479011737024); + strikes.Add(0.596); stdDevsOnExpiry.Add(0.413382422570191); stdDevsOnPayment.Add(0.414747962476008); + strikes.Add(0.597); stdDevsOnExpiry.Add(0.413701812613868); stdDevsOnPayment.Add(0.415000711363246); + strikes.Add(0.598); stdDevsOnExpiry.Add(0.413954794826682); stdDevsOnPayment.Add(0.415282623583626); + strikes.Add(0.599); stdDevsOnExpiry.Add(0.414229912983116); stdDevsOnPayment.Add(0.415538612841214); + strikes.Add(0.6); stdDevsOnExpiry.Add(0.414508193417211); stdDevsOnPayment.Add(0.415778400247055); + strikes.Add(0.601); stdDevsOnExpiry.Add(0.414748526519384); stdDevsOnPayment.Add(0.416005226171499); + strikes.Add(0.602); stdDevsOnExpiry.Add(0.415020482398158); stdDevsOnPayment.Add(0.41632602283607); + strikes.Add(0.603); stdDevsOnExpiry.Add(0.415276626888632); stdDevsOnPayment.Add(0.416513964316324); + strikes.Add(0.604); stdDevsOnExpiry.Add(0.415583367821668); stdDevsOnPayment.Add(0.416795876536705); + strikes.Add(0.605); stdDevsOnExpiry.Add(0.415731994871696); stdDevsOnPayment.Add(0.417119913571625); + strikes.Add(0.606); stdDevsOnExpiry.Add(0.416060871748354); stdDevsOnPayment.Add(0.417217124682101); + strikes.Add(0.607); stdDevsOnExpiry.Add(0.416335989904788); stdDevsOnPayment.Add(0.417550882828069); + strikes.Add(0.608); stdDevsOnExpiry.Add(0.416532051119719); stdDevsOnPayment.Add(0.417861958381593); + strikes.Add(0.609); stdDevsOnExpiry.Add(0.416772384221892); stdDevsOnPayment.Add(0.41811794763918); + strikes.Add(0.61); stdDevsOnExpiry.Add(0.417028528712365); stdDevsOnPayment.Add(0.418286446897339); + strikes.Add(0.611); stdDevsOnExpiry.Add(0.417281510925179); stdDevsOnPayment.Add(0.418587801339814); + strikes.Add(0.612); stdDevsOnExpiry.Add(0.417455436196488); stdDevsOnPayment.Add(0.418817867634608); + strikes.Add(0.613); stdDevsOnExpiry.Add(0.417721067519942); stdDevsOnPayment.Add(0.419047933929401); + strikes.Add(0.614); stdDevsOnExpiry.Add(0.418068918062561); stdDevsOnPayment.Add(0.419313644298036); + strikes.Add(0.615); stdDevsOnExpiry.Add(0.418204896001948); stdDevsOnPayment.Add(0.41962471985156); + strikes.Add(0.616); stdDevsOnExpiry.Add(0.418533772878605); stdDevsOnPayment.Add(0.419812661331814); + strikes.Add(0.617); stdDevsOnExpiry.Add(0.418770943703118); stdDevsOnPayment.Add(0.420036246885909); + strikes.Add(0.618); stdDevsOnExpiry.Add(0.419042899581892); stdDevsOnPayment.Add(0.420282515032448); + strikes.Add(0.619); stdDevsOnExpiry.Add(0.419229473963842); stdDevsOnPayment.Add(0.420596830956321); + strikes.Add(0.62); stdDevsOnExpiry.Add(0.419529890341558); stdDevsOnPayment.Add(0.420807455029019); + strikes.Add(0.621); stdDevsOnExpiry.Add(0.41974492522245); stdDevsOnPayment.Add(0.421037521323813); + strikes.Add(0.622); stdDevsOnExpiry.Add(0.420026367934205); stdDevsOnPayment.Add(0.421335635395939); + strikes.Add(0.623); stdDevsOnExpiry.Add(0.420282512424678); stdDevsOnPayment.Add(0.421523576876193); + strikes.Add(0.624); stdDevsOnExpiry.Add(0.420427977197046); stdDevsOnPayment.Add(0.421857335022161); + strikes.Add(0.625); stdDevsOnExpiry.Add(0.420658823466239); stdDevsOnPayment.Add(0.422061478354161); + strikes.Add(0.626); stdDevsOnExpiry.Add(0.421019323119498); stdDevsOnPayment.Add(0.422259140945463); + strikes.Add(0.627); stdDevsOnExpiry.Add(0.421193248390807); stdDevsOnPayment.Add(0.422589658721081); + strikes.Add(0.628); stdDevsOnExpiry.Add(0.421395634161058); stdDevsOnPayment.Add(0.422774359830986); + strikes.Add(0.629); stdDevsOnExpiry.Add(0.421702375094094); stdDevsOnPayment.Add(0.423036829829271); + strikes.Add(0.63); stdDevsOnExpiry.Add(0.421882624920724); stdDevsOnPayment.Add(0.423273376864763); + strikes.Add(0.631); stdDevsOnExpiry.Add(0.422176716743119); stdDevsOnPayment.Add(0.423493722048509); + strikes.Add(0.632); stdDevsOnExpiry.Add(0.422401238456991); stdDevsOnPayment.Add(0.423720547972953); + strikes.Add(0.633); stdDevsOnExpiry.Add(0.422651058392145); stdDevsOnPayment.Add(0.423931172045652); + strikes.Add(0.634); stdDevsOnExpiry.Add(0.434664551223124); stdDevsOnPayment.Add(0.424248728339874); + strikes.Add(0.635); stdDevsOnExpiry.Add(0.434920695713598); stdDevsOnPayment.Add(0.424478794634667); + strikes.Add(0.636); stdDevsOnExpiry.Add(0.423403680475265); stdDevsOnPayment.Add(0.424715341670159); + strikes.Add(0.637); stdDevsOnExpiry.Add(0.435432984694545); stdDevsOnPayment.Add(0.424990773149841); + strikes.Add(0.638); stdDevsOnExpiry.Add(0.423846399347688); stdDevsOnPayment.Add(0.425172233889397); + strikes.Add(0.639); stdDevsOnExpiry.Add(0.435910488621231); stdDevsOnPayment.Add(0.425428223146984); + strikes.Add(0.64); stdDevsOnExpiry.Add(0.436163470834044); stdDevsOnPayment.Add(0.425645327960381); + strikes.Add(0.641); stdDevsOnExpiry.Add(0.436413290769197); stdDevsOnPayment.Add(0.425894836477269); + strikes.Add(0.642); stdDevsOnExpiry.Add(0.43664413703839); stdDevsOnPayment.Add(0.42617674869765); + strikes.Add(0.643); stdDevsOnExpiry.Add(0.436897119251203); stdDevsOnPayment.Add(0.426361449807555); + strikes.Add(0.644); stdDevsOnExpiry.Add(0.437159588296997); stdDevsOnPayment.Add(0.426607717954094); + strikes.Add(0.645); stdDevsOnExpiry.Add(0.437358811789588); stdDevsOnPayment.Add(0.42678917869365); + strikes.Add(0.646); stdDevsOnExpiry.Add(0.437602307169421); stdDevsOnPayment.Add(0.427165061654157); + strikes.Add(0.647); stdDevsOnExpiry.Add(0.437852127104574); stdDevsOnPayment.Add(0.427340041653014); + strikes.Add(0.648); stdDevsOnExpiry.Add(0.438076648818446); stdDevsOnPayment.Add(0.427608992391998); + strikes.Add(0.649); stdDevsOnExpiry.Add(0.43833279330892); stdDevsOnPayment.Add(0.427780732020506); + strikes.Add(0.65); stdDevsOnExpiry.Add(0.438569964133432); stdDevsOnPayment.Add(0.428033480907744); + strikes.Add(0.651); stdDevsOnExpiry.Add(0.438810297235605); stdDevsOnPayment.Add(0.428308912387426); + strikes.Add(0.652); stdDevsOnExpiry.Add(0.439056954893098); stdDevsOnPayment.Add(0.428548699793267); + strikes.Add(0.653); stdDevsOnExpiry.Add(0.43927831432931); stdDevsOnPayment.Add(0.428713958681077); + strikes.Add(0.654); stdDevsOnExpiry.Add(0.439534458819784); stdDevsOnPayment.Add(0.429012072753204); + strikes.Add(0.655); stdDevsOnExpiry.Add(0.439765305088976); stdDevsOnPayment.Add(0.429193533492759); + strikes.Add(0.656); stdDevsOnExpiry.Add(0.440015125024129); stdDevsOnPayment.Add(0.429443042009648); + strikes.Add(0.657); stdDevsOnExpiry.Add(0.440264944959282); stdDevsOnPayment.Add(0.429686069785838); + strikes.Add(0.658); stdDevsOnExpiry.Add(0.440454681618893); stdDevsOnPayment.Add(0.429857809414346); + strikes.Add(0.659); stdDevsOnExpiry.Add(0.440723475220007); stdDevsOnPayment.Add(0.430185086819615); + strikes.Add(0.66); stdDevsOnExpiry.Add(0.440957483766859); stdDevsOnPayment.Add(0.430402191633012); + strikes.Add(0.661); stdDevsOnExpiry.Add(0.441210465979673); stdDevsOnPayment.Add(0.43057393126152); + strikes.Add(0.662); stdDevsOnExpiry.Add(0.441403364916943); stdDevsOnPayment.Add(0.430758632371424); + strikes.Add(0.663); stdDevsOnExpiry.Add(0.441681645351038); stdDevsOnPayment.Add(0.431076188665647); + strikes.Add(0.664); stdDevsOnExpiry.Add(0.441858732900007); stdDevsOnPayment.Add(0.431290053108694); + strikes.Add(0.665); stdDevsOnExpiry.Add(0.44209590372452); stdDevsOnPayment.Add(0.431484475329646); + strikes.Add(0.666); stdDevsOnExpiry.Add(0.442374184158615); stdDevsOnPayment.Add(0.431721022365138); + strikes.Add(0.667); stdDevsOnExpiry.Add(0.442592381317166); stdDevsOnPayment.Add(0.432022376807614); + strikes.Add(0.668); stdDevsOnExpiry.Add(0.442813740753378); stdDevsOnPayment.Add(0.432194116436122); + strikes.Add(0.669); stdDevsOnExpiry.Add(0.443076209799172); stdDevsOnPayment.Add(0.432417701990217); + strikes.Add(0.67); stdDevsOnExpiry.Add(0.443275433291763); stdDevsOnPayment.Add(0.432644527914661); + strikes.Add(0.671); stdDevsOnExpiry.Add(0.443531577782236); stdDevsOnPayment.Add(0.43293616124609); + strikes.Add(0.672); stdDevsOnExpiry.Add(0.443705503053546); stdDevsOnPayment.Add(0.433030131986216); + strikes.Add(0.673); stdDevsOnExpiry.Add(0.443964809821679); stdDevsOnPayment.Add(0.433376851613581); + strikes.Add(0.674); stdDevsOnExpiry.Add(0.444183006980231); stdDevsOnPayment.Add(0.433603677538025); + strikes.Add(0.675); stdDevsOnExpiry.Add(0.444439151470705); stdDevsOnPayment.Add(0.433772176796184); + strikes.Add(0.676); stdDevsOnExpiry.Add(0.444676322295217); stdDevsOnPayment.Add(0.434083252349708); + strikes.Add(0.677); stdDevsOnExpiry.Add(0.44491665539739); stdDevsOnPayment.Add(0.434290636052057); + strikes.Add(0.678); stdDevsOnExpiry.Add(0.44510322977934); stdDevsOnPayment.Add(0.43440080864393); + strikes.Add(0.679); stdDevsOnExpiry.Add(0.445324589215552); stdDevsOnPayment.Add(0.43464383642012); + strikes.Add(0.68); stdDevsOnExpiry.Add(0.445602869649647); stdDevsOnPayment.Add(0.434909546788755); + strikes.Add(0.681); stdDevsOnExpiry.Add(0.445757821254995); stdDevsOnPayment.Add(0.435084526787612); + strikes.Add(0.682); stdDevsOnExpiry.Add(0.446029777133769); stdDevsOnPayment.Add(0.43537616011904); + strikes.Add(0.683); stdDevsOnExpiry.Add(0.446282759346583); stdDevsOnPayment.Add(0.435567341969643); + strikes.Add(0.684); stdDevsOnExpiry.Add(0.446478820561513); stdDevsOnPayment.Add(0.435719639376056); + strikes.Add(0.685); stdDevsOnExpiry.Add(0.446655908110483); stdDevsOnPayment.Add(0.435969147892944); + strikes.Add(0.686); stdDevsOnExpiry.Add(0.446940513099898); stdDevsOnPayment.Add(0.43627050233542); + strikes.Add(0.687); stdDevsOnExpiry.Add(0.44716187253611); stdDevsOnPayment.Add(0.448587150032745); + strikes.Add(0.688); stdDevsOnExpiry.Add(0.447424341581904); stdDevsOnPayment.Add(0.436633423814531); + strikes.Add(0.689); stdDevsOnExpiry.Add(0.447604591408533); stdDevsOnPayment.Add(0.436827846035483); + strikes.Add(0.69); stdDevsOnExpiry.Add(0.447800652623464); stdDevsOnPayment.Add(0.44929679113922); + strikes.Add(0.691); stdDevsOnExpiry.Add(0.448085257612879); stdDevsOnPayment.Add(0.449510655582268); + strikes.Add(0.692); stdDevsOnExpiry.Add(0.44830029249377); stdDevsOnPayment.Add(0.449750442988109); + strikes.Add(0.693); stdDevsOnExpiry.Add(0.448505840541681); stdDevsOnPayment.Add(0.449986990023601); + strikes.Add(0.694); stdDevsOnExpiry.Add(0.448708226311932); stdDevsOnPayment.Add(0.450226777429442); + strikes.Add(0.695); stdDevsOnExpiry.Add(0.448935910303464); stdDevsOnPayment.Add(0.450447122613188); + strikes.Add(0.696); stdDevsOnExpiry.Add(0.449141458351375); stdDevsOnPayment.Add(0.450638304463791); + strikes.Add(0.697); stdDevsOnExpiry.Add(0.449365980065247); stdDevsOnPayment.Add(0.450878091869632); + strikes.Add(0.698); stdDevsOnExpiry.Add(0.449565203557838); stdDevsOnPayment.Add(0.451091956312679); + strikes.Add(0.699); stdDevsOnExpiry.Add(0.449871944490874); stdDevsOnPayment.Add(0.451296099644679); + strikes.Add(0.7); stdDevsOnExpiry.Add(0.450061681150484); stdDevsOnPayment.Add(0.451519685198774); + strikes.Add(0.701); stdDevsOnExpiry.Add(0.450229281866473); stdDevsOnPayment.Add(0.45174003038252); + strikes.Add(0.702); stdDevsOnExpiry.Add(0.450472777246306); stdDevsOnPayment.Add(0.451979817788361); + strikes.Add(0.703); stdDevsOnExpiry.Add(0.45073208401444); stdDevsOnPayment.Add(0.452222845564551); + strikes.Add(0.704); stdDevsOnExpiry.Add(0.450940794340011); stdDevsOnPayment.Add(0.452436710007599); + strikes.Add(0.705); stdDevsOnExpiry.Add(0.451162153776223); stdDevsOnPayment.Add(0.452653814820995); + strikes.Add(0.706); stdDevsOnExpiry.Add(0.451374026379454); stdDevsOnPayment.Add(0.452848237041948); + strikes.Add(0.707); stdDevsOnExpiry.Add(0.451570087594384); stdDevsOnPayment.Add(0.453094505188487); + strikes.Add(0.708); stdDevsOnExpiry.Add(0.451813582974217); stdDevsOnPayment.Add(0.453292167779789); + strikes.Add(0.709); stdDevsOnExpiry.Add(0.452028617855109); stdDevsOnPayment.Add(0.453525474444931); + strikes.Add(0.71); stdDevsOnExpiry.Add(0.45223416590302); stdDevsOnPayment.Add(0.453729617776931); + strikes.Add(0.711); stdDevsOnExpiry.Add(0.45243338939561); stdDevsOnPayment.Add(0.453959684071725); + strikes.Add(0.712); stdDevsOnExpiry.Add(0.452635775165861); stdDevsOnPayment.Add(0.454212432958962); + strikes.Add(0.713); stdDevsOnExpiry.Add(0.452869783712714); stdDevsOnPayment.Add(0.454390653328169); + strikes.Add(0.714); stdDevsOnExpiry.Add(0.453056358094664); stdDevsOnPayment.Add(0.454617479252613); + strikes.Add(0.715); stdDevsOnExpiry.Add(0.453274555253215); stdDevsOnPayment.Add(0.454837824436359); + strikes.Add(0.716); stdDevsOnExpiry.Add(0.453578133908591); stdDevsOnPayment.Add(0.455019285175914); + strikes.Add(0.717); stdDevsOnExpiry.Add(0.453761546012881); stdDevsOnPayment.Add(0.455252591841057); + strikes.Add(0.718); stdDevsOnExpiry.Add(0.453970256338452); stdDevsOnPayment.Add(0.455479417765501); + strikes.Add(0.719); stdDevsOnExpiry.Add(0.454156830720402); stdDevsOnPayment.Add(0.455657638134707); + strikes.Add(0.72); stdDevsOnExpiry.Add(0.454346567380012); stdDevsOnPayment.Add(0.45589094479985); + strikes.Add(0.721); stdDevsOnExpiry.Add(0.454590062759845); stdDevsOnPayment.Add(0.456098328502199); + strikes.Add(0.722); stdDevsOnExpiry.Add(0.454795610807756); stdDevsOnPayment.Add(0.45634135627839); + strikes.Add(0.723); stdDevsOnExpiry.Add(0.455032781632269); stdDevsOnPayment.Add(0.45654225924004); + strikes.Add(0.724); stdDevsOnExpiry.Add(0.455257303346141); stdDevsOnPayment.Add(0.45674640257204); + strikes.Add(0.725); stdDevsOnExpiry.Add(0.455469175949372); stdDevsOnPayment.Add(0.456960267015087); + strikes.Add(0.726); stdDevsOnExpiry.Add(0.455684210830264); stdDevsOnPayment.Add(0.457200054420929); + strikes.Add(0.727); stdDevsOnExpiry.Add(0.455908732544135); stdDevsOnPayment.Add(0.457378274790135); + strikes.Add(0.728); stdDevsOnExpiry.Add(0.456054197316503); stdDevsOnPayment.Add(0.457621302566325); + strikes.Add(0.729); stdDevsOnExpiry.Add(0.456281881308035); stdDevsOnPayment.Add(0.457835167009372); + strikes.Add(0.73); stdDevsOnExpiry.Add(0.456525376687868); stdDevsOnPayment.Add(0.458039310341372); + strikes.Add(0.731); stdDevsOnExpiry.Add(0.456683490570877); stdDevsOnPayment.Add(0.458233732562325); + strikes.Add(0.732); stdDevsOnExpiry.Add(0.45693647278369); stdDevsOnPayment.Add(0.458467039227467); + strikes.Add(0.733); stdDevsOnExpiry.Add(0.45712937172096); stdDevsOnPayment.Add(0.458671182559467); + strikes.Add(0.734); stdDevsOnExpiry.Add(0.457322270658231); stdDevsOnPayment.Add(0.458907729594959); + strikes.Add(0.735); stdDevsOnExpiry.Add(0.457521494150821); stdDevsOnPayment.Add(0.459079469223467); + strikes.Add(0.736); stdDevsOnExpiry.Add(0.457736529031713); stdDevsOnPayment.Add(0.459299814407213); + strikes.Add(0.737); stdDevsOnExpiry.Add(0.457970537578565); stdDevsOnPayment.Add(0.459481275146768); + strikes.Add(0.738); stdDevsOnExpiry.Add(0.458141300572214); stdDevsOnPayment.Add(0.459701620330514); + strikes.Add(0.739); stdDevsOnExpiry.Add(0.458406931895669); stdDevsOnPayment.Add(0.459931686625307); + strikes.Add(0.74); stdDevsOnExpiry.Add(0.458587181722298); stdDevsOnPayment.Add(0.460116387735212); + strikes.Add(0.741); stdDevsOnExpiry.Add(0.458846488490432); stdDevsOnPayment.Add(0.460317290696863); + strikes.Add(0.742); stdDevsOnExpiry.Add(0.459045711983022); stdDevsOnPayment.Add(0.460534395510259); + strikes.Add(0.743); stdDevsOnExpiry.Add(0.459216474976672); stdDevsOnPayment.Add(0.460757981064355); + strikes.Add(0.744); stdDevsOnExpiry.Add(0.459412536191602); stdDevsOnPayment.Add(0.46098156661845); + strikes.Add(0.745); stdDevsOnExpiry.Add(0.459656031571435); stdDevsOnPayment.Add(0.461156546617307); + strikes.Add(0.746); stdDevsOnExpiry.Add(0.459829956842744); stdDevsOnPayment.Add(0.461370411060354); + strikes.Add(0.747); stdDevsOnExpiry.Add(0.460054478556616); stdDevsOnPayment.Add(0.461545391059211); + strikes.Add(0.748); stdDevsOnExpiry.Add(0.460244215216226); stdDevsOnPayment.Add(0.46179165920575); + strikes.Add(0.749); stdDevsOnExpiry.Add(0.460396004543914); stdDevsOnPayment.Add(0.461966639204608); + strikes.Add(0.75); stdDevsOnExpiry.Add(0.460671122700349); stdDevsOnPayment.Add(0.462212907351147); + strikes.Add(0.751); stdDevsOnExpiry.Add(0.460857697082299); stdDevsOnPayment.Add(0.462378166238956); + strikes.Add(0.752); stdDevsOnExpiry.Add(0.461028460075948); stdDevsOnPayment.Add(0.462598511422702); + strikes.Add(0.753); stdDevsOnExpiry.Add(0.461215034457898); stdDevsOnPayment.Add(0.462792933643655); + strikes.Add(0.754); stdDevsOnExpiry.Add(0.461458529837731); stdDevsOnPayment.Add(0.4630132788274); + strikes.Add(0.755); stdDevsOnExpiry.Add(0.461657753330322); stdDevsOnPayment.Add(0.4632174221594); + strikes.Add(0.756); stdDevsOnExpiry.Add(0.461869625933553); stdDevsOnPayment.Add(0.463411844380352); + strikes.Add(0.757); stdDevsOnExpiry.Add(0.462122608146366); stdDevsOnPayment.Add(0.463632189564098); + strikes.Add(0.758); stdDevsOnExpiry.Add(0.462264910641074); stdDevsOnPayment.Add(0.463820131044352); + strikes.Add(0.759); stdDevsOnExpiry.Add(0.462470458688985); stdDevsOnPayment.Add(0.464014553265304); + strikes.Add(0.76); stdDevsOnExpiry.Add(0.462676006736896); stdDevsOnPayment.Add(0.464254340671146); + strikes.Add(0.761); stdDevsOnExpiry.Add(0.462910015283748); stdDevsOnPayment.Add(0.464432561040352); + strikes.Add(0.762); stdDevsOnExpiry.Add(0.463087102832718); stdDevsOnPayment.Add(0.464646425483399); + strikes.Add(0.763); stdDevsOnExpiry.Add(0.463245216715726); stdDevsOnPayment.Add(0.464850568815399); + strikes.Add(0.764); stdDevsOnExpiry.Add(0.463482387540239); stdDevsOnPayment.Add(0.464999625851462); + strikes.Add(0.765); stdDevsOnExpiry.Add(0.46369109786581); stdDevsOnPayment.Add(0.465281538071843); + strikes.Add(0.766); stdDevsOnExpiry.Add(0.463909295024361); stdDevsOnPayment.Add(0.465443556589303); + strikes.Add(0.767); stdDevsOnExpiry.Add(0.46407373346269); stdDevsOnPayment.Add(0.465650940291652); + strikes.Add(0.768); stdDevsOnExpiry.Add(0.464285606065922); stdDevsOnPayment.Add(0.465861564364351); + strikes.Add(0.769); stdDevsOnExpiry.Add(0.464475342725532); stdDevsOnPayment.Add(0.466036544363208); + strikes.Add(0.77); stdDevsOnExpiry.Add(0.464668241662802); stdDevsOnPayment.Add(0.466218005102763); + strikes.Add(0.771); stdDevsOnExpiry.Add(0.464845329211771); stdDevsOnPayment.Add(0.466483715471398); + strikes.Add(0.772); stdDevsOnExpiry.Add(0.465031903593721); stdDevsOnPayment.Add(0.466632772507461); + strikes.Add(0.773); stdDevsOnExpiry.Add(0.465256425307593); stdDevsOnPayment.Add(0.466807752506318); + strikes.Add(0.774); stdDevsOnExpiry.Add(0.465427188301242); stdDevsOnPayment.Add(0.467060501393556); + strikes.Add(0.775); stdDevsOnExpiry.Add(0.465645385459794); stdDevsOnPayment.Add(0.467229000651715); + strikes.Add(0.776); stdDevsOnExpiry.Add(0.465806661620462); stdDevsOnPayment.Add(0.467416942131968); + strikes.Add(0.777); stdDevsOnExpiry.Add(0.466021696501354); stdDevsOnPayment.Add(0.467591922130826); + strikes.Add(0.778); stdDevsOnExpiry.Add(0.466255705048206); stdDevsOnPayment.Add(0.467815507684921); + strikes.Add(0.779); stdDevsOnExpiry.Add(0.466489713595059); stdDevsOnPayment.Add(0.467996968424476); + strikes.Add(0.78); stdDevsOnExpiry.Add(0.466676287977009); stdDevsOnPayment.Add(0.468188150275079); + strikes.Add(0.781); stdDevsOnExpiry.Add(0.466843888692998); stdDevsOnPayment.Add(0.468395533977428); + strikes.Add(0.782); stdDevsOnExpiry.Add(0.466992515743026); stdDevsOnPayment.Add(0.468576994716984); + strikes.Add(0.783); stdDevsOnExpiry.Add(0.467213875179237); stdDevsOnPayment.Add(0.468823262863523); + strikes.Add(0.784); stdDevsOnExpiry.Add(0.467470019669711); stdDevsOnPayment.Add(0.469017685084475); + strikes.Add(0.785); stdDevsOnExpiry.Add(0.467656594051661); stdDevsOnPayment.Add(0.469228309157174); + strikes.Add(0.786); stdDevsOnExpiry.Add(0.467811545657009); stdDevsOnPayment.Add(0.46944541397057); + strikes.Add(0.787); stdDevsOnExpiry.Add(0.467938036763416); stdDevsOnPayment.Add(0.46956854804384); + strikes.Add(0.788); stdDevsOnExpiry.Add(0.468172045310268); stdDevsOnPayment.Add(0.469788893227586); + strikes.Add(0.789); stdDevsOnExpiry.Add(0.468374431080519); stdDevsOnPayment.Add(0.470035161374125); + strikes.Add(0.79); stdDevsOnExpiry.Add(0.468595790516731); stdDevsOnPayment.Add(0.470200420261935); + strikes.Add(0.791); stdDevsOnExpiry.Add(0.468801338564642); stdDevsOnPayment.Add(0.470407803964284); + strikes.Add(0.792); stdDevsOnExpiry.Add(0.468972101558291); stdDevsOnPayment.Add(0.470514736185807); + strikes.Add(0.793); stdDevsOnExpiry.Add(0.46913970227428); stdDevsOnPayment.Add(0.470770725443395); + strikes.Add(0.794); stdDevsOnExpiry.Add(0.469307302990269); stdDevsOnPayment.Add(0.470974868775394); + strikes.Add(0.795); stdDevsOnExpiry.Add(0.469550798370102); stdDevsOnPayment.Add(0.471127166181807); + strikes.Add(0.796); stdDevsOnExpiry.Add(0.46970891225311); stdDevsOnPayment.Add(0.471337790254505); + strikes.Add(0.797); stdDevsOnExpiry.Add(0.469952407632943); stdDevsOnPayment.Add(0.47156461617895); + strikes.Add(0.798); stdDevsOnExpiry.Add(0.470151631125534); stdDevsOnPayment.Add(0.471733115437108); + strikes.Add(0.799); stdDevsOnExpiry.Add(0.47026231084364); stdDevsOnPayment.Add(0.471937258769108); + strikes.Add(0.8); stdDevsOnExpiry.Add(0.470499481668152); stdDevsOnPayment.Add(0.47205067173133); + strikes.Add(0.801); stdDevsOnExpiry.Add(0.470670244661801); stdDevsOnPayment.Add(0.472283978396473); + strikes.Add(0.802); stdDevsOnExpiry.Add(0.470878954987373); stdDevsOnPayment.Add(0.472442756543584); + strikes.Add(0.803); stdDevsOnExpiry.Add(0.4710275820374); stdDevsOnPayment.Add(0.472737630245361); + strikes.Add(0.804); stdDevsOnExpiry.Add(0.471220480974671); stdDevsOnPayment.Add(0.472880206540726); + strikes.Add(0.805); stdDevsOnExpiry.Add(0.471432353577902); stdDevsOnPayment.Add(0.473081109502377); + strikes.Add(0.806); stdDevsOnExpiry.Add(0.471615765682192); stdDevsOnPayment.Add(0.473246368390186); + strikes.Add(0.807); stdDevsOnExpiry.Add(0.471837125118404); stdDevsOnPayment.Add(0.473450511722186); + strikes.Add(0.808); stdDevsOnExpiry.Add(0.472026861778014); stdDevsOnPayment.Add(0.473625491721043); + strikes.Add(0.809); stdDevsOnExpiry.Add(0.472184975661022); stdDevsOnPayment.Add(0.4738004717199); + strikes.Add(0.81); stdDevsOnExpiry.Add(0.472346251821691); stdDevsOnPayment.Add(0.473991653570503); + strikes.Add(0.811); stdDevsOnExpiry.Add(0.472573935813223); stdDevsOnPayment.Add(0.474179595050757); + strikes.Add(0.812); stdDevsOnExpiry.Add(0.47271307603027); stdDevsOnPayment.Add(0.474377257642059); + strikes.Add(0.813); stdDevsOnExpiry.Add(0.472940760021802); stdDevsOnPayment.Add(0.474513353196725); + strikes.Add(0.814); stdDevsOnExpiry.Add(0.473168444013335); stdDevsOnPayment.Add(0.474730458010122); + strikes.Add(0.815); stdDevsOnExpiry.Add(0.473310746508042); stdDevsOnPayment.Add(0.474931360971772); + strikes.Add(0.816); stdDevsOnExpiry.Add(0.473528943666594); stdDevsOnPayment.Add(0.475148465785169); + strikes.Add(0.817); stdDevsOnExpiry.Add(0.473658597050661); stdDevsOnPayment.Add(0.475359089857867); + strikes.Add(0.818); stdDevsOnExpiry.Add(0.473857820543251); stdDevsOnPayment.Add(0.475485464301486); + strikes.Add(0.819); stdDevsOnExpiry.Add(0.474012772148599); stdDevsOnPayment.Add(0.475702569114883); + strikes.Add(0.82); stdDevsOnExpiry.Add(0.474291052582694); stdDevsOnPayment.Add(0.475906712446883); + strikes.Add(0.821); stdDevsOnExpiry.Add(0.474436517355062); stdDevsOnPayment.Add(0.476046048371899); + strikes.Add(0.822); stdDevsOnExpiry.Add(0.474661039068934); stdDevsOnPayment.Add(0.476269633925994); + strikes.Add(0.823); stdDevsOnExpiry.Add(0.474765394231719); stdDevsOnPayment.Add(0.476399248739962); + strikes.Add(0.824); stdDevsOnExpiry.Add(0.475027863277513); stdDevsOnPayment.Add(0.476626074664406); + strikes.Add(0.825); stdDevsOnExpiry.Add(0.475198626271162); stdDevsOnPayment.Add(0.476807535403962); + strikes.Add(0.826); stdDevsOnExpiry.Add(0.475321955099909); stdDevsOnPayment.Add(0.476953352069676); + strikes.Add(0.827); stdDevsOnExpiry.Add(0.475552801369101); stdDevsOnPayment.Add(0.477144533920279); + strikes.Add(0.828); stdDevsOnExpiry.Add(0.475685617030829); stdDevsOnPayment.Add(0.477355157992977); + strikes.Add(0.829); stdDevsOnExpiry.Add(0.47590065191172); stdDevsOnPayment.Add(0.477539859102882); + strikes.Add(0.83); stdDevsOnExpiry.Add(0.476074577183029); stdDevsOnPayment.Add(0.477718079472088); + strikes.Add(0.831); stdDevsOnExpiry.Add(0.476201068289436); stdDevsOnPayment.Add(0.477876857619199); + strikes.Add(0.832); stdDevsOnExpiry.Add(0.47645721277991); stdDevsOnPayment.Add(0.478097202802945); + strikes.Add(0.833); stdDevsOnExpiry.Add(0.476593190719297); stdDevsOnPayment.Add(0.478281903912849); + strikes.Add(0.834); stdDevsOnExpiry.Add(0.476861984320411); stdDevsOnPayment.Add(0.478489287615198); + strikes.Add(0.835); stdDevsOnExpiry.Add(0.476975826316177); stdDevsOnPayment.Add(0.478589739096024); + strikes.Add(0.836); stdDevsOnExpiry.Add(0.477203510307709); stdDevsOnPayment.Add(0.478803603539071); + strikes.Add(0.837); stdDevsOnExpiry.Add(0.477323676858796); stdDevsOnPayment.Add(0.478991545019325); + strikes.Add(0.838); stdDevsOnExpiry.Add(0.477538711739687); stdDevsOnPayment.Add(0.479166525018182); + strikes.Add(0.839); stdDevsOnExpiry.Add(0.477722123843977); stdDevsOnPayment.Add(0.479399831683325); + strikes.Add(0.84); stdDevsOnExpiry.Add(0.477946645557849); stdDevsOnPayment.Add(0.479503523534499); + strikes.Add(0.841); stdDevsOnExpiry.Add(0.478098434885537); stdDevsOnPayment.Add(0.479688224644404); + strikes.Add(0.842); stdDevsOnExpiry.Add(0.478291333822807); stdDevsOnPayment.Add(0.479979857975832); + strikes.Add(0.843); stdDevsOnExpiry.Add(0.478370390764311); stdDevsOnPayment.Add(0.480073828715959); + strikes.Add(0.844); stdDevsOnExpiry.Add(0.478550640590941); stdDevsOnPayment.Add(0.48027473167761); + strikes.Add(0.845); stdDevsOnExpiry.Add(0.478797298248434); stdDevsOnPayment.Add(0.480427029084022); + strikes.Add(0.846); stdDevsOnExpiry.Add(0.478987034908044); stdDevsOnPayment.Add(0.480624691675324); + strikes.Add(0.847); stdDevsOnExpiry.Add(0.479119850569771); stdDevsOnPayment.Add(0.48080291204453); + strikes.Add(0.848); stdDevsOnExpiry.Add(0.479338047728323); stdDevsOnPayment.Add(0.48096493056199); + strikes.Add(0.849); stdDevsOnExpiry.Add(0.479568893997515); stdDevsOnPayment.Add(0.481162593153292); + strikes.Add(0.85); stdDevsOnExpiry.Add(0.479749143824145); stdDevsOnPayment.Add(0.48137321722599); + strikes.Add(0.851); stdDevsOnExpiry.Add(0.47985033670927); stdDevsOnPayment.Add(0.481509312780656); + strikes.Add(0.852); stdDevsOnExpiry.Add(0.480043235646541); stdDevsOnPayment.Add(0.481719936853355); + strikes.Add(0.853); stdDevsOnExpiry.Add(0.48022348547317); stdDevsOnPayment.Add(0.481875474630116); + strikes.Add(0.854); stdDevsOnExpiry.Add(0.480324678358296); stdDevsOnPayment.Add(0.48210554092491); + strikes.Add(0.855); stdDevsOnExpiry.Add(0.48060295879239); stdDevsOnPayment.Add(0.48226755944237); + strikes.Add(0.856); stdDevsOnExpiry.Add(0.480716800788156); stdDevsOnPayment.Add(0.482432818330179); + strikes.Add(0.857); stdDevsOnExpiry.Add(0.480988756666931); stdDevsOnPayment.Add(0.482607798329037); + strikes.Add(0.858); stdDevsOnExpiry.Add(0.481096274107377); stdDevsOnPayment.Add(0.482773057216846); + strikes.Add(0.859); stdDevsOnExpiry.Add(0.481238576602084); stdDevsOnPayment.Add(0.482977200548846); + strikes.Add(0.86); stdDevsOnExpiry.Add(0.481456773760636); stdDevsOnPayment.Add(0.48316190165875); + strikes.Add(0.861); stdDevsOnExpiry.Add(0.481573778034062); stdDevsOnPayment.Add(0.483278554991322); + strikes.Add(0.862); stdDevsOnExpiry.Add(0.481833084802196); stdDevsOnPayment.Add(0.483495659804718); + strikes.Add(0.863); stdDevsOnExpiry.Add(0.481978549574564); stdDevsOnPayment.Add(0.483647957211131); + strikes.Add(0.864); stdDevsOnExpiry.Add(0.482136663457572); stdDevsOnPayment.Add(0.483819696839639); + strikes.Add(0.865); stdDevsOnExpiry.Add(0.482345373783143); stdDevsOnPayment.Add(0.484001157579194); + strikes.Add(0.866); stdDevsOnExpiry.Add(0.482462378056569); stdDevsOnPayment.Add(0.484208541281543); + strikes.Add(0.867); stdDevsOnExpiry.Add(0.482705873436402); stdDevsOnPayment.Add(0.484289550540273); + strikes.Add(0.868); stdDevsOnExpiry.Add(0.482908259206653); stdDevsOnPayment.Add(0.48454878016821); + strikes.Add(0.869); stdDevsOnExpiry.Add(0.483072697644982); stdDevsOnPayment.Add(0.484769125351956); + strikes.Add(0.87); stdDevsOnExpiry.Add(0.483180215085428); stdDevsOnPayment.Add(0.484911701647321); + strikes.Add(0.871); stdDevsOnExpiry.Add(0.483461657797183); stdDevsOnPayment.Add(0.485086681646178); + strikes.Add(0.872); stdDevsOnExpiry.Add(0.483537552461027); stdDevsOnPayment.Add(0.485219536830495); + strikes.Add(0.873); stdDevsOnExpiry.Add(0.483692504066375); stdDevsOnPayment.Add(0.485446362754939); + strikes.Add(0.874); stdDevsOnExpiry.Add(0.483831644283422); stdDevsOnPayment.Add(0.485559775717161); + strikes.Add(0.875); stdDevsOnExpiry.Add(0.484037192331333); stdDevsOnPayment.Add(0.485760678678812); + strikes.Add(0.876); stdDevsOnExpiry.Add(0.484242740379244); stdDevsOnPayment.Add(0.485987504603256); + strikes.Add(0.877); stdDevsOnExpiry.Add(0.484366069207991); stdDevsOnPayment.Add(0.486104157935828); + strikes.Add(0.878); stdDevsOnExpiry.Add(0.484596915477183); stdDevsOnPayment.Add(0.486282378305034); + strikes.Add(0.879); stdDevsOnExpiry.Add(0.484707595195289); stdDevsOnPayment.Add(0.486489762007383); + strikes.Add(0.88); stdDevsOnExpiry.Add(0.484849897689996); stdDevsOnPayment.Add(0.486612896080653); + strikes.Add(0.881); stdDevsOnExpiry.Add(0.48509655534749); stdDevsOnPayment.Add(0.486758712746367); + strikes.Add(0.882); stdDevsOnExpiry.Add(0.485254669230498); stdDevsOnPayment.Add(0.486956375337668); + strikes.Add(0.883); stdDevsOnExpiry.Add(0.485498164610331); stdDevsOnPayment.Add(0.48715403792897); + strikes.Add(0.884); stdDevsOnExpiry.Add(0.485574059274175); stdDevsOnPayment.Add(0.487290133483636); + strikes.Add(0.885); stdDevsOnExpiry.Add(0.485691063547601); stdDevsOnPayment.Add(0.487416507927255); + strikes.Add(0.886); stdDevsOnExpiry.Add(0.485899773873172); stdDevsOnPayment.Add(0.487610930148207); + strikes.Add(0.887); stdDevsOnExpiry.Add(0.486171729751947); stdDevsOnPayment.Add(0.487782669776715); + strikes.Add(0.888); stdDevsOnExpiry.Add(0.486307707691334); stdDevsOnPayment.Add(0.488009495701159); + strikes.Add(0.889); stdDevsOnExpiry.Add(0.486519580294565); stdDevsOnPayment.Add(0.488165033477921); + strikes.Add(0.89); stdDevsOnExpiry.Add(0.486627097735011); stdDevsOnPayment.Add(0.488314090513985); + strikes.Add(0.891); stdDevsOnExpiry.Add(0.486769400229719); stdDevsOnPayment.Add(0.488476109031445); + strikes.Add(0.892); stdDevsOnExpiry.Add(0.486943325501028); stdDevsOnPayment.Add(0.488631646808207); + strikes.Add(0.893); stdDevsOnExpiry.Add(0.487107763939357); stdDevsOnPayment.Add(0.488829309399508); + strikes.Add(0.894); stdDevsOnExpiry.Add(0.487297500598967); stdDevsOnPayment.Add(0.488962164583825); + strikes.Add(0.895); stdDevsOnExpiry.Add(0.487420829427713); stdDevsOnPayment.Add(0.489172788656524); + strikes.Add(0.896); stdDevsOnExpiry.Add(0.487642188863925); stdDevsOnPayment.Add(0.489318605322238); + strikes.Add(0.897); stdDevsOnExpiry.Add(0.487809789579914); stdDevsOnPayment.Add(0.489493585321095); + strikes.Add(0.898); stdDevsOnExpiry.Add(0.487952092074622); stdDevsOnPayment.Add(0.489655603838555); + strikes.Add(0.899); stdDevsOnExpiry.Add(0.48810388140231); stdDevsOnPayment.Add(0.48987918939265); + strikes.Add(0.9); stdDevsOnExpiry.Add(0.488334727671502); stdDevsOnPayment.Add(0.49000232346592); + strikes.Add(0.901); stdDevsOnExpiry.Add(0.48847703016621); stdDevsOnPayment.Add(0.490232389760713); + strikes.Add(0.902); stdDevsOnExpiry.Add(0.488660442270499); stdDevsOnPayment.Add(0.490349043093285); + strikes.Add(0.903); stdDevsOnExpiry.Add(0.488847016652449); stdDevsOnPayment.Add(0.490475417536904); + strikes.Add(0.904); stdDevsOnExpiry.Add(0.488938722704594); stdDevsOnPayment.Add(0.490699003090999); + strikes.Add(0.905); stdDevsOnExpiry.Add(0.48904624014504); stdDevsOnPayment.Add(0.490838339016015); + strikes.Add(0.906); stdDevsOnExpiry.Add(0.489264437303591); stdDevsOnPayment.Add(0.491026280496268); + strikes.Add(0.907); stdDevsOnExpiry.Add(0.489409902075959); stdDevsOnPayment.Add(0.491175337532332); + strikes.Add(0.908); stdDevsOnExpiry.Add(0.489647072900472); stdDevsOnPayment.Add(0.491392442345728); + strikes.Add(0.909); stdDevsOnExpiry.Add(0.489760914896238); stdDevsOnPayment.Add(0.491515576418998); + strikes.Add(0.91); stdDevsOnExpiry.Add(0.48999492344309); stdDevsOnPayment.Add(0.491658152714363); + strikes.Add(0.911); stdDevsOnExpiry.Add(0.49018149782504); stdDevsOnPayment.Add(0.491872017157411); + strikes.Add(0.912); stdDevsOnExpiry.Add(0.490190984658021); stdDevsOnPayment.Add(0.491975709008585); + strikes.Add(0.913); stdDevsOnExpiry.Add(0.490466102814455); stdDevsOnPayment.Add(0.492170131229537); + strikes.Add(0.914); stdDevsOnExpiry.Add(0.490611567586823); stdDevsOnPayment.Add(0.49236131308014); + strikes.Add(0.915); stdDevsOnExpiry.Add(0.490785492858132); stdDevsOnPayment.Add(0.492529812338299); + strikes.Add(0.916); stdDevsOnExpiry.Add(0.490908821686879); stdDevsOnPayment.Add(0.492701551966807); + strikes.Add(0.917); stdDevsOnExpiry.Add(0.491032150515626); stdDevsOnPayment.Add(0.492831166780775); + strikes.Add(0.918); stdDevsOnExpiry.Add(0.491244023118857); stdDevsOnPayment.Add(0.492983464187188); + strikes.Add(0.919); stdDevsOnExpiry.Add(0.491373676502924); stdDevsOnPayment.Add(0.493194088259886); + strikes.Add(0.92); stdDevsOnExpiry.Add(0.491534952663592); stdDevsOnPayment.Add(0.493245934185473); + strikes.Add(0.921); stdDevsOnExpiry.Add(0.491737338433843); stdDevsOnPayment.Add(0.493557009738997); + strikes.Add(0.922); stdDevsOnExpiry.Add(0.491952373314735); stdDevsOnPayment.Add(0.493641259368076); + strikes.Add(0.923); stdDevsOnExpiry.Add(0.49205672847752); stdDevsOnPayment.Add(0.493845402700076); + strikes.Add(0.924); stdDevsOnExpiry.Add(0.492227491471169); stdDevsOnPayment.Add(0.493978257884393); + strikes.Add(0.925); stdDevsOnExpiry.Add(0.492376118521197); stdDevsOnPayment.Add(0.494130555290806); + strikes.Add(0.926); stdDevsOnExpiry.Add(0.492569017458467); stdDevsOnPayment.Add(0.49431849677106); + strikes.Add(0.927); stdDevsOnExpiry.Add(0.492682859454234); stdDevsOnPayment.Add(0.494457832696075); + strikes.Add(0.928); stdDevsOnExpiry.Add(0.492882082946824); stdDevsOnPayment.Add(0.494665216398424); + strikes.Add(0.929); stdDevsOnExpiry.Add(0.49298643810961); stdDevsOnPayment.Add(0.494749466027504); + strikes.Add(0.93); stdDevsOnExpiry.Add(0.493214122101142); stdDevsOnPayment.Add(0.494986013062996); + strikes.Add(0.931); stdDevsOnExpiry.Add(0.493350100040529); stdDevsOnPayment.Add(0.495105906765916); + strikes.Add(0.932); stdDevsOnExpiry.Add(0.493524025311838); stdDevsOnPayment.Add(0.495329492320011); + strikes.Add(0.933); stdDevsOnExpiry.Add(0.493713761971448); stdDevsOnPayment.Add(0.495446145652583); + strikes.Add(0.934); stdDevsOnExpiry.Add(0.493887687242758); stdDevsOnPayment.Add(0.495562798985154); + strikes.Add(0.935); stdDevsOnExpiry.Add(0.494052125681086); stdDevsOnPayment.Add(0.495763701946804); + strikes.Add(0.936); stdDevsOnExpiry.Add(0.494143831733231); stdDevsOnPayment.Add(0.495948403056709); + strikes.Add(0.937); stdDevsOnExpiry.Add(0.494355704336463); stdDevsOnPayment.Add(0.496084498611376); + strikes.Add(0.938); stdDevsOnExpiry.Add(0.494539116440752); stdDevsOnPayment.Add(0.496282161202677); + strikes.Add(0.939); stdDevsOnExpiry.Add(0.494615011104596); stdDevsOnPayment.Add(0.496437698979439); + strikes.Add(0.94); stdDevsOnExpiry.Add(0.494782611820585); stdDevsOnPayment.Add(0.496599717496899); + strikes.Add(0.941); stdDevsOnExpiry.Add(0.494886966983371); stdDevsOnPayment.Add(0.496790899347502); + strikes.Add(0.942); stdDevsOnExpiry.Add(0.495174734250446); stdDevsOnPayment.Add(0.496878389346931); + strikes.Add(0.943); stdDevsOnExpiry.Add(0.495323361300474); stdDevsOnPayment.Add(0.497037167494042); + strikes.Add(0.944); stdDevsOnExpiry.Add(0.495459339239861); stdDevsOnPayment.Add(0.497176503419057); + strikes.Add(0.945); stdDevsOnExpiry.Add(0.495519422515405); stdDevsOnPayment.Add(0.497338521936518); + strikes.Add(0.946); stdDevsOnExpiry.Add(0.495721808285655); stdDevsOnPayment.Add(0.497562107490613); + strikes.Add(0.947); stdDevsOnExpiry.Add(0.495921031778246); stdDevsOnPayment.Add(0.497701443415628); + strikes.Add(0.948); stdDevsOnExpiry.Add(0.496066496550614); stdDevsOnPayment.Add(0.497837538970295); + strikes.Add(0.949); stdDevsOnExpiry.Add(0.496218285878302); stdDevsOnPayment.Add(0.49801899970985); + strikes.Add(0.95); stdDevsOnExpiry.Add(0.496385886594291); stdDevsOnPayment.Add(0.498219902671501); + strikes.Add(0.951); stdDevsOnExpiry.Add(0.496525026811338); stdDevsOnPayment.Add(0.498268508226739); + strikes.Add(0.952); stdDevsOnExpiry.Add(0.496676816139026); stdDevsOnPayment.Add(0.498498574521533); + strikes.Add(0.953); stdDevsOnExpiry.Add(0.496793820412452); stdDevsOnPayment.Add(0.498628189335501); + strikes.Add(0.954); stdDevsOnExpiry.Add(0.497049964902926); stdDevsOnPayment.Add(0.498812890445405); + strikes.Add(0.955); stdDevsOnExpiry.Add(0.497189105119973); stdDevsOnPayment.Add(0.499013793407056); + strikes.Add(0.956); stdDevsOnExpiry.Add(0.497347219002982); stdDevsOnPayment.Add(0.499172571554167); + strikes.Add(0.957); stdDevsOnExpiry.Add(0.497476872387049); stdDevsOnPayment.Add(0.49924385970185); + strikes.Add(0.958); stdDevsOnExpiry.Add(0.4976792581573); stdDevsOnPayment.Add(0.499503089329786); + strikes.Add(0.959); stdDevsOnExpiry.Add(0.497770964209444); stdDevsOnPayment.Add(0.499593819699564); + strikes.Add(0.96); stdDevsOnExpiry.Add(0.497998648200977); stdDevsOnPayment.Add(0.499726674883881); + strikes.Add(0.961); stdDevsOnExpiry.Add(0.498042920088219); stdDevsOnPayment.Add(0.499937298956579); + strikes.Add(0.962); stdDevsOnExpiry.Add(0.498204196248888); stdDevsOnPayment.Add(0.500031269696706); + strikes.Add(0.963); stdDevsOnExpiry.Add(0.49842871796276); stdDevsOnPayment.Add(0.500203009325214); + strikes.Add(0.964); stdDevsOnExpiry.Add(0.498517261737244); stdDevsOnPayment.Add(0.500345585620579); + strikes.Add(0.965); stdDevsOnExpiry.Add(0.498672213342592); stdDevsOnPayment.Add(0.500436315990357); + strikes.Add(0.966); stdDevsOnExpiry.Add(0.49881767811496); stdDevsOnPayment.Add(0.500689064877594); + strikes.Add(0.967); stdDevsOnExpiry.Add(0.499076984883094); stdDevsOnPayment.Add(0.500792756728769); + strikes.Add(0.968); stdDevsOnExpiry.Add(0.499200313711841); stdDevsOnPayment.Add(0.501006621171816); + strikes.Add(0.969); stdDevsOnExpiry.Add(0.499415348592732); stdDevsOnPayment.Add(0.50107466894915); + strikes.Add(0.97); stdDevsOnExpiry.Add(0.499513379200197); stdDevsOnPayment.Add(0.501343619688134); + strikes.Add(0.971); stdDevsOnExpiry.Add(0.499665168527885); stdDevsOnPayment.Add(0.501431109687562); + strikes.Add(0.972); stdDevsOnExpiry.Add(0.499769523690671); stdDevsOnPayment.Add(0.50160284931607); + strikes.Add(0.973); stdDevsOnExpiry.Add(0.499911826185378); stdDevsOnPayment.Add(0.50172598338934); + strikes.Add(0.974); stdDevsOnExpiry.Add(0.500098400567328); stdDevsOnPayment.Add(0.501894482647498); + strikes.Add(0.975); stdDevsOnExpiry.Add(0.500281812671618); stdDevsOnPayment.Add(0.502037058942863); + strikes.Add(0.976); stdDevsOnExpiry.Add(0.500370356446103); stdDevsOnPayment.Add(0.502263884867308); + strikes.Add(0.977); stdDevsOnExpiry.Add(0.50050000983017); stdDevsOnPayment.Add(0.502344894126038); + strikes.Add(0.978); stdDevsOnExpiry.Add(0.500702395600421); stdDevsOnPayment.Add(0.502506912643498); + strikes.Add(0.979); stdDevsOnExpiry.Add(0.500844698095128); stdDevsOnPayment.Add(0.502568479680133); + strikes.Add(0.98); stdDevsOnExpiry.Add(0.501091355752621); stdDevsOnPayment.Add(0.502827709308069); + strikes.Add(0.981); stdDevsOnExpiry.Add(0.501129303084543); stdDevsOnPayment.Add(0.502980006714482); + strikes.Add(0.982); stdDevsOnExpiry.Add(0.501338013410114); stdDevsOnPayment.Add(0.503096660047053); + strikes.Add(0.983); stdDevsOnExpiry.Add(0.501540399180365); stdDevsOnPayment.Add(0.503375331897085); + strikes.Add(0.984); stdDevsOnExpiry.Add(0.501644754343151); stdDevsOnPayment.Add(0.503423937452323); + strikes.Add(0.985); stdDevsOnExpiry.Add(0.501720649006995); stdDevsOnPayment.Add(0.503621600043624); + strikes.Add(0.986); stdDevsOnExpiry.Add(0.501954657553847); stdDevsOnPayment.Add(0.503806301153529); + strikes.Add(0.987); stdDevsOnExpiry.Add(0.502096960048555); stdDevsOnPayment.Add(0.503929435226798); + strikes.Add(0.988); stdDevsOnExpiry.Add(0.502210802044321); stdDevsOnPayment.Add(0.504078492262862); + strikes.Add(0.989); stdDevsOnExpiry.Add(0.502406863259251); stdDevsOnPayment.Add(0.504175703373338); + strikes.Add(0.99); stdDevsOnExpiry.Add(0.502596599918861); stdDevsOnPayment.Add(0.50437012559429); + strikes.Add(0.991); stdDevsOnExpiry.Add(0.502659845472065); stdDevsOnPayment.Add(0.504447894482671); + strikes.Add(0.992); stdDevsOnExpiry.Add(0.502811634799753); stdDevsOnPayment.Add(0.504713604851306); + strikes.Add(0.993); stdDevsOnExpiry.Add(0.502903340851898); stdDevsOnPayment.Add(0.504713604851306); + strikes.Add(0.994); stdDevsOnExpiry.Add(0.503083590678527); stdDevsOnPayment.Add(0.504924228924004); + strikes.Add(0.995); stdDevsOnExpiry.Add(0.503304950114739); stdDevsOnPayment.Add(0.505095968552512); + strikes.Add(0.996); stdDevsOnExpiry.Add(0.503384007056243); stdDevsOnPayment.Add(0.505189939292639); + strikes.Add(0.997); stdDevsOnExpiry.Add(0.503529471828611); stdDevsOnPayment.Add(0.505390842254289); + strikes.Add(0.998); stdDevsOnExpiry.Add(0.503712883932901); stdDevsOnPayment.Add(0.505611187438035); + strikes.Add(0.999); stdDevsOnExpiry.Add(0.503858348705269); stdDevsOnPayment.Add(0.505695437067115); + strikes.Add(1); stdDevsOnExpiry.Add(0.504029111698918); stdDevsOnPayment.Add(0.505818571140384); + strikes.Add(1.001); stdDevsOnExpiry.Add(0.504127142306383); stdDevsOnPayment.Add(0.505964387806099); + strikes.Add(1.002); stdDevsOnExpiry.Add(0.504301067577692); stdDevsOnPayment.Add(0.506139367804955); + + //Create smiles on Expiry Date + smilesOnExpiry = new List(); + smilesOnExpiry.Add(new FlatSmileSection(startDate, flatVol, rangeCouponDayCount)); + double dummyAtmLevel = 0; + smilesOnExpiry.Add(new InterpolatedSmileSection(startDate, + strikes, stdDevsOnExpiry, dummyAtmLevel, rangeCouponDayCount)); + //Create smiles on Payment Date + smilesOnPayment = new List(); + smilesOnPayment.Add(new FlatSmileSection(endDate, flatVol, rangeCouponDayCount)); + smilesOnPayment.Add(new InterpolatedSmileSection(endDate, + strikes, stdDevsOnPayment, dummyAtmLevel, rangeCouponDayCount, new Linear())); + + Utils.QL_REQUIRE(smilesOnExpiry.Count == smilesOnPayment.Count, () => + "smilesOnExpiry.size()!=smilesOnPayment.size()"); + } + + public CommonVars() + { + + //General Settings + calendar = new TARGET(); + today = new Date(39147); // 6 Mar 2007 + Settings.setEvaluationDate(today); + settlement = today; + //create Yield Curve + createYieldCurve(); + referenceDate = termStructure.link.referenceDate(); + // Ibor index + iborIndex = new Euribor6M(termStructure); + + // create Volatility Structures + flatVol = 0.1; + createVolatilityStructures(); + + // Range Accrual valuation + gearing = 1.0; + spread = 0.0; + infiniteLowerStrike = 1.0e-9; + infiniteUpperStrike = 1.0; + correlation = 1.0; + + startDate = new Date(42800); //6 Mar 2017 + endDate = new Date(42984); //6 Sep 2017 + paymentDate = endDate; //6 Sep 2017 + fixingDays = 2; + rangeCouponDayCount = iborIndex.dayCounter(); + + // observations schedule + observationsConvention = BusinessDayConvention.ModifiedFollowing; + observationsFrequency = Frequency.Daily; + observationSchedule = new Schedule(startDate, endDate, + new Period(observationsFrequency), calendar, observationsConvention, observationsConvention, + DateGeneration.Rule.Forward, false); + // Range accrual pricers properties + byCallSpread = new List(); + byCallSpread.Add(true); + byCallSpread.Add(false); + + //Create smiles sections + createSmileSections(); + + //test parameters + rateTolerance = 2.0e-8; + priceTolerance = 2.0e-4; + } + } + +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testInfiniteRange() + { + // Testing infinite range accrual floaters + CommonVars vars = new CommonVars(); + + //Coupon + RangeAccrualFloatersCoupon coupon = new RangeAccrualFloatersCoupon(vars.paymentDate, + 1.0, + vars.iborIndex, + vars.startDate, + vars.endDate, + vars.fixingDays, + vars.rangeCouponDayCount, + vars.gearing, vars.spread, + vars.startDate, vars.endDate, + vars.observationSchedule, + vars.infiniteLowerStrike, + vars.infiniteUpperStrike); + Date fixingDate = coupon.fixingDate(); + + for (int z = 0; z < vars.smilesOnPayment.Count; z++) + { + for (int i = 0; i < vars.byCallSpread.Count; i++) + { + RangeAccrualPricer bgmPricer = new RangeAccrualPricerByBgm(vars.correlation, + vars.smilesOnExpiry[z], vars.smilesOnPayment[z], + true, vars.byCallSpread[i]); + + coupon.setPricer(bgmPricer); + + //Computation + double rate = coupon.rate(); + double indexfixing = vars.iborIndex.fixing(fixingDate); + double difference = rate - indexfixing; + + if (Math.Abs(difference) > vars.rateTolerance) + { + QAssert.Fail("\n" + + "i:\t" + i + "\n" + + "fixingDate:\t" + fixingDate + "\n" + + "startDate:\t" + vars.startDate + "\n" + + "range accrual rate:\t" + rate + "\n" + + "index fixing:\t" + indexfixing + "\n" + + "difference:\t" + difference + "\n" + + "tolerance: \t" + vars.rateTolerance); + } + + } + } + } + +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testPriceMonotonicityWithRespectToLowerStrike() + { + // Testing price monotonicity with respect to the lower strike + CommonVars vars = new CommonVars(); + + for (int z = 0; z < vars.smilesOnPayment.Count; z++) + { + for (int i = 0; i < vars.byCallSpread.Count; i++) + { + RangeAccrualPricer bgmPricer = new RangeAccrualPricerByBgm(vars.correlation, + vars.smilesOnExpiry[z], + vars.smilesOnPayment[z], + true, + vars.byCallSpread[i]); + + double effectiveLowerStrike; + double previousPrice = 100.0; + + for (int k = 1; k < 100; k++) + { + effectiveLowerStrike = 0.005 + k * 0.001; + RangeAccrualFloatersCoupon coupon = new RangeAccrualFloatersCoupon( + vars.paymentDate, + 1.0, + vars.iborIndex, + vars.startDate, + vars.endDate, + vars.fixingDays, + vars.rangeCouponDayCount, + vars.gearing, vars.spread, + vars.startDate, vars.endDate, + vars.observationSchedule, + effectiveLowerStrike, + vars.infiniteUpperStrike); + + coupon.setPricer(bgmPricer); + + //Computation + double price = coupon.price(vars.termStructure); + + if (previousPrice <= price) + { + QAssert.Fail("\n" + + "i:\t" + i + "\n" + + "k:\t" + k + "\n" + + "Price at lower strike\t" + (effectiveLowerStrike - 0.001) + + ": \t" + previousPrice + "\n" + + "Price at lower strike\t" + effectiveLowerStrike + + ": \t" + price + "\n"); + } + + previousPrice = price; + } + } + } + } + +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testPriceMonotonicityWithRespectToUpperStrike() + { + + // Testing price monotonicity with respect to the upper strike + + CommonVars vars = new CommonVars(); + + for (int z = 0; z < vars.smilesOnPayment.Count; z++) + { + for (int i = 0; i < vars.byCallSpread.Count; i++) + { + RangeAccrualPricer bgmPricer = new RangeAccrualPricerByBgm(vars.correlation, + vars.smilesOnExpiry[z], + vars.smilesOnPayment[z], + true, + vars.byCallSpread[i]); + + double effectiveUpperStrike; + double previousPrice = 0.0; + + for (int k = 1; k < 95; k++) + { + effectiveUpperStrike = 0.006 + k * 0.001; + RangeAccrualFloatersCoupon coupon = new RangeAccrualFloatersCoupon( + vars.paymentDate, + 1.0, + vars.iborIndex, + vars.startDate, + vars.endDate, + vars.fixingDays, + vars.rangeCouponDayCount, + vars.gearing, vars.spread, + vars.startDate, vars.endDate, + vars.observationSchedule, + .004, + effectiveUpperStrike); + + coupon.setPricer(bgmPricer); + + //Computation + double price = coupon.price(vars.termStructure); + + if (previousPrice > price) + { + Assert.Fail("\n" + + "i:\t" + i + "\n" + + "k:\t" + k + "\n" + + "Price at upper strike\t" + (effectiveUpperStrike - 0.001) + + ": \t" + previousPrice + "\n" + + "Price at upper strike\t" + effectiveUpperStrike + + ": \t" + price + "\n"); + } + previousPrice = price; + } + } + } + } + } +} diff --git a/tests/QLNet.Tests/T_RiskStats.cs b/tests/QLNet.Tests/T_RiskStats.cs index 0286a1a75..2ff8f02f4 100644 --- a/tests/QLNet.Tests/T_RiskStats.cs +++ b/tests/QLNet.Tests/T_RiskStats.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,7 +22,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -39,9 +39,9 @@ class IncrementalGaussianStatistics : GenericGaussianStatistics tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong sum of weights\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong sum of weights\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.weightSum(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong sum of weights\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); // min @@ -119,17 +119,17 @@ public void RiskStatisticsTest() calculated = igs.min(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong minimum value\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong minimum value\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.min(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: " - + "wrong minimum value\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong minimum value\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); // max @@ -137,40 +137,40 @@ public void RiskStatisticsTest() calculated = igs.max(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong maximum value\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong maximum value\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.max(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: " - + "wrong maximum value\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong maximum value\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); // mean expected = averages[i]; tolerance = (expected == 0.0 ? 1.0e-13 : - Math.Abs(expected) * 1.0e-13); + Math.Abs(expected) * 1.0e-13); calculated = igs.mean(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong mean value" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong mean value" + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.mean(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong mean value" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); // variance @@ -179,20 +179,20 @@ public void RiskStatisticsTest() calculated = igs.variance(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong variance" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong variance" + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.variance(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong variance" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); // standardDeviation @@ -201,20 +201,20 @@ public void RiskStatisticsTest() calculated = igs.standardDeviation(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong standard deviation" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong standard deviation" + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.standardDeviation(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong standard deviation" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); // missing errorEstimate() test @@ -225,20 +225,20 @@ public void RiskStatisticsTest() calculated = igs.skewness(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong skewness" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong skewness" + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.skewness(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong skewness" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); // kurtosis @@ -247,87 +247,87 @@ public void RiskStatisticsTest() calculated = igs.kurtosis(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong kurtosis" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong kurtosis" + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.kurtosis(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong kurtosis" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); // percentile expected = averages[i]; tolerance = (expected == 0.0 ? 1.0e-3 : - Math.Abs(expected * 1.0e-3)); + Math.Abs(expected * 1.0e-3)); calculated = igs.gaussianPercentile(0.5); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong Gaussian percentile" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong Gaussian percentile" + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.gaussianPercentile(0.5); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong Gaussian percentile" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.percentile(0.5); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong percentile" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); // potential upside double upper_tail = averages[i] + 2.0 * sigmas[j], - lower_tail = averages[i] - 2.0 * sigmas[j]; + lower_tail = averages[i] - 2.0 * sigmas[j]; double twoSigma = cumulative.value(upper_tail); expected = Math.Max(upper_tail, 0.0); tolerance = (expected == 0.0 ? 1.0e-3 : - Math.Abs(expected * 1.0e-3)); + Math.Abs(expected * 1.0e-3)); calculated = igs.gaussianPotentialUpside(twoSigma); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong Gaussian potential upside" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong Gaussian potential upside" + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.gaussianPotentialUpside(twoSigma); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong Gaussian potential upside" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.potentialUpside(twoSigma); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong potential upside" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); // just to check that GaussianStatistics does work @@ -337,39 +337,39 @@ public void RiskStatisticsTest() calculated = test.gaussianPotentialUpside(twoSigma); if (calculated != expected) QAssert.Fail("GenericGaussianStatistics fails" - + "\n calculated: " + calculated - + "\n expected: " + expected); + + "\n calculated: " + calculated + + "\n expected: " + expected); // value-at-risk expected = -Math.Min(lower_tail, 0.0); tolerance = (expected == 0.0 ? 1.0e-3 : - Math.Abs(expected * 1.0e-3)); + Math.Abs(expected * 1.0e-3)); calculated = igs.gaussianValueAtRisk(twoSigma); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong Gaussian value-at-risk" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong Gaussian value-at-risk" + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.gaussianValueAtRisk(twoSigma); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong Gaussian value-at-risk" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.valueAtRisk(twoSigma); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong value-at-risk" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); if (averages[i] > 0.0 && sigmas[j] < averages[i]) { @@ -383,67 +383,67 @@ public void RiskStatisticsTest() // expected shortfall expected = -Math.Min(averages[i] - - sigmas[j] * sigmas[j] - * normal.value(lower_tail) / (1.0 - twoSigma), - 0.0); + - sigmas[j] * sigmas[j] + * normal.value(lower_tail) / (1.0 - twoSigma), + 0.0); tolerance = (expected == 0.0 ? 1.0e-4 - : Math.Abs(expected) * 1.0e-2); + : Math.Abs(expected) * 1.0e-2); calculated = igs.gaussianExpectedShortfall(twoSigma); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong Gaussian expected shortfall" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong Gaussian expected shortfall" + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.gaussianExpectedShortfall(twoSigma); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong Gaussian expected shortfall" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.expectedShortfall(twoSigma); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong expected shortfall" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); // shortfall expected = 0.5; tolerance = (expected == 0.0 ? 1.0e-3 : - Math.Abs(expected * 1.0e-3)); + Math.Abs(expected * 1.0e-3)); calculated = igs.gaussianShortfall(averages[i]); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong Gaussian shortfall" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong Gaussian shortfall" + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.gaussianShortfall(averages[i]); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong Gaussian shortfall" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.shortfall(averages[i]); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong shortfall" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); // average shortfall @@ -452,28 +452,28 @@ public void RiskStatisticsTest() calculated = igs.gaussianAverageShortfall(averages[i]); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong Gaussian average shortfall" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong Gaussian average shortfall" + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.gaussianAverageShortfall(averages[i]); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong Gaussian average shortfall" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.averageShortfall(averages[i]); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong average shortfall" - + " for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + " for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); // regret @@ -482,54 +482,54 @@ public void RiskStatisticsTest() calculated = igs.gaussianRegret(averages[i]); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong Gaussian regret(" + averages[i] + ") " - + "for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong Gaussian regret(" + averages[i] + ") " + + "for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.gaussianRegret(averages[i]); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: " - + "wrong Gaussian regret(" + averages[i] + ") " - + "for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong Gaussian regret(" + averages[i] + ") " + + "for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.regret(averages[i]); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: " - + "wrong regret(" + averages[i] + ") " - + "for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong regret(" + averages[i] + ") " + + "for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); // downsideVariance expected = s.downsideVariance(); tolerance = (expected == 0.0 ? 1.0e-3 : - Math.Abs(expected * 1.0e-3)); + Math.Abs(expected * 1.0e-3)); calculated = igs.downsideVariance(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong downside variance" - + "for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong downside variance" + + "for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = igs.gaussianDownsideVariance(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong Gaussian downside variance" - + "for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong Gaussian downside variance" + + "for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); // downsideVariance if (averages[i] == 0.0) @@ -539,37 +539,37 @@ public void RiskStatisticsTest() calculated = igs.downsideVariance(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong downside variance" - + "for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong downside variance" + + "for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = igs.gaussianDownsideVariance(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("IncrementalGaussianStatistics: " - + "wrong Gaussian downside variance" - + "for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "wrong Gaussian downside variance" + + "for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.downsideVariance(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong downside variance" - + "for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); calculated = s.gaussianDownsideVariance(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail("RiskStatistics: wrong Gaussian downside variance" - + "for N(" + averages[i] + ", " - + sigmas[j] + ")\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected + "\n" - + " tolerance: " + tolerance); + + "for N(" + averages[i] + ", " + + sigmas[j] + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " tolerance: " + tolerance); } igs.reset(); diff --git a/tests/QLNet.Tests/T_Rounding.cs b/tests/QLNet.Tests/T_Rounding.cs index 3681e8d4e..6fa01f463 100644 --- a/tests/QLNet.Tests/T_Rounding.cs +++ b/tests/QLNet.Tests/T_Rounding.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Andrea Maggiulli - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,7 +20,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -54,33 +54,34 @@ public TestCase(double x, int precision, double closest, double up, double down, } - public static TestCase[] testData = { - new TestCase( 0.86313513, 5, 0.86314, 0.86314, 0.86313, 0.86314, 0.86313 ), - new TestCase( -7.64555346, 1, -7.6, -7.7, -7.6, -7.6, -7.6 ), - new TestCase(0.13961605, 2, 0.14, 0.14, 0.13, 0.14, 0.13 ), - new TestCase(0.14344179, 4, 0.1434, 0.1435, 0.1434, 0.1434, 0.1434 ), - new TestCase(-4.74315016, 2, -4.74, -4.75, -4.74, -4.74, -4.74 ), - new TestCase(-7.82772074, 5, -7.82772, -7.82773, -7.82772, -7.82772, -7.82772 ), - new TestCase( 2.74137947, 3, 2.741, 2.742, 2.741, 2.741, 2.741 ), - new TestCase(2.13056714, 1, 2.1, 2.2, 2.1, 2.1, 2.1 ), - new TestCase(-1.06228670, 1, -1.1, -1.1, -1.0, -1.0, -1.1 ), - new TestCase(8.29234094, 4, 8.2923, 8.2924, 8.2923, 8.2923, 8.2923 ), - new TestCase(7.90185598, 2, 7.90, 7.91, 7.90, 7.90, 7.90 ), - new TestCase(-0.26738058, 1, -0.3, -0.3, -0.2, -0.2, -0.3 ), - new TestCase(1.78128713, 1, 1.8, 1.8, 1.7, 1.8, 1.7 ), - new TestCase(4.23537260, 1, 4.2, 4.3, 4.2, 4.2, 4.2 ), - new TestCase(3.64369953, 4, 3.6437, 3.6437, 3.6436, 3.6437, 3.6436 ), - new TestCase(6.34542470, 2, 6.35, 6.35, 6.34, 6.35, 6.34 ), - new TestCase(-0.84754962, 4, -0.8475, -0.8476, -0.8475, -0.8475, -0.8475 ), - new TestCase(4.60998652, 1, 4.6, 4.7, 4.6, 4.6, 4.6 ), - new TestCase(6.28794223, 3, 6.288, 6.288, 6.287, 6.288, 6.287 ), - new TestCase(7.89428221, 2, 7.89, 7.90, 7.89, 7.89, 7.89 ) - }; + public static TestCase[] testData = + { + new TestCase(0.86313513, 5, 0.86314, 0.86314, 0.86313, 0.86314, 0.86313), + new TestCase(-7.64555346, 1, -7.6, -7.7, -7.6, -7.6, -7.6), + new TestCase(0.13961605, 2, 0.14, 0.14, 0.13, 0.14, 0.13), + new TestCase(0.14344179, 4, 0.1434, 0.1435, 0.1434, 0.1434, 0.1434), + new TestCase(-4.74315016, 2, -4.74, -4.75, -4.74, -4.74, -4.74), + new TestCase(-7.82772074, 5, -7.82772, -7.82773, -7.82772, -7.82772, -7.82772), + new TestCase(2.74137947, 3, 2.741, 2.742, 2.741, 2.741, 2.741), + new TestCase(2.13056714, 1, 2.1, 2.2, 2.1, 2.1, 2.1), + new TestCase(-1.06228670, 1, -1.1, -1.1, -1.0, -1.0, -1.1), + new TestCase(8.29234094, 4, 8.2923, 8.2924, 8.2923, 8.2923, 8.2923), + new TestCase(7.90185598, 2, 7.90, 7.91, 7.90, 7.90, 7.90), + new TestCase(-0.26738058, 1, -0.3, -0.3, -0.2, -0.2, -0.3), + new TestCase(1.78128713, 1, 1.8, 1.8, 1.7, 1.8, 1.7), + new TestCase(4.23537260, 1, 4.2, 4.3, 4.2, 4.2, 4.2), + new TestCase(3.64369953, 4, 3.6437, 3.6437, 3.6436, 3.6437, 3.6436), + new TestCase(6.34542470, 2, 6.35, 6.35, 6.34, 6.35, 6.34), + new TestCase(-0.84754962, 4, -0.8475, -0.8476, -0.8475, -0.8475, -0.8475), + new TestCase(4.60998652, 1, 4.6, 4.7, 4.6, 4.6, 4.6), + new TestCase(6.28794223, 3, 6.288, 6.288, 6.287, 6.288, 6.287), + new TestCase(7.89428221, 2, 7.89, 7.90, 7.89, 7.89, 7.89) + }; #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testClosest() { @@ -95,9 +96,9 @@ public void testClosest() } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testUp() { @@ -113,9 +114,9 @@ public void testUp() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testDown() { @@ -131,9 +132,9 @@ public void testDown() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testFloor() { @@ -149,9 +150,9 @@ public void testFloor() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testCeiling() { diff --git a/tests/QLNet.Tests/T_SVI.cs b/tests/QLNet.Tests/T_SVI.cs index 5cf32c3cd..7c9b215f3 100644 --- a/tests/QLNet.Tests/T_SVI.cs +++ b/tests/QLNet.Tests/T_SVI.cs @@ -1,20 +1,20 @@ -/* - Copyright (C) 2008-2009 Andrea Maggiulli - - This file is part of QLNet Project https://github.com/amaggiulli/qlnet - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. +/* + Copyright (C) 2008-2009 Andrea Maggiulli + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; @@ -23,8 +23,8 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; -#else - using Xunit; +#else +using Xunit; #endif using QLNet; @@ -32,94 +32,95 @@ namespace TestSuite { #if NET40 || NET45 - [TestClass()] + [TestClass()] #endif - public class T_SVI - { - double add10(double x) { return x + 10; } - double mul10(double x) { return x * 10; } - double sub10(double x) { return x - 10; } + public class T_SVI + { + double add10(double x) { return x + 10; } + double mul10(double x) { return x * 10; } + double sub10(double x) { return x - 10; } - double add(double x, double y) { return x + y; } - double mul(double x, double y) { return x * y; } - double sub(double x, double y) { return x - y; } + double add + (double x, double y) { return x + y; } + double mul(double x, double y) { return x * y; } + double sub(double x, double y) { return x - y; } #if NET40 || NET45 - [TestMethod()] -#else - [Fact] + [TestMethod()] +#else + [Fact] #endif - public void testCalibration() - { - double forward = 0.03; - double tau = 1.0; - - //Real a = 0.04; - //Real b = 0.1; - //Real rho = -0.5; - //Real sigma = 0.1; - //Real m = 0.0; - double a = 0.1; - double b = 0.06; - double rho = -0.9; - double m = 0.24; - double sigma = 0.06; - - List strikes = new List(); - strikes.Add(0.01); - strikes.Add(0.015); - strikes.Add(0.02); - strikes.Add(0.025); - strikes.Add(0.03); - strikes.Add(0.035); - strikes.Add(0.04); - strikes.Add(0.045); - strikes.Add(0.05); - - List vols = new InitializedList(strikes.Count, 0.20); //dummy vols (we do not calibrate here) - - SviInterpolation svi = new SviInterpolation(strikes, strikes.Count, vols, tau, - forward, a, b, sigma, rho, m, true, true, true, - true, true); - - svi.enableExtrapolation(); - - List sviVols = new InitializedList(strikes.Count, 0.0); - for (int i = 0; i < strikes.Count; ++i) - sviVols[i] = svi.value(strikes[i]); - - SviInterpolation svi2 = new SviInterpolation(strikes, strikes.Count, sviVols, tau, - forward, null, null, null, - null, null, false, false, false, - false, false, false, null, - null, 1E-8, false, - 0); //don't allow for random start values - - svi2.enableExtrapolation(); - svi2.update(); - - Console.WriteLine("a=" + svi2.a()); - if (!Utils.close_enough(a, svi2.a(), 100)) - QAssert.Fail("error in a coefficient estimation"); - - Console.WriteLine("b=" + svi2.b()); - if (!Utils.close_enough(b, svi2.b(), 100)) - QAssert.Fail("error in b coefficient estimation"); - - Console.WriteLine("sigma=" + svi2.sigma()); - if (!Utils.close_enough(sigma, svi2.sigma(), 100)) - QAssert.Fail("error in sigma coefficient estimation"); - - Console.WriteLine("rho=" + svi2.rho()); - if (!Utils.close_enough(rho, svi2.rho(), 100)) - QAssert.Fail("error in rho coefficient estimation"); - - Console.WriteLine("m=" + svi2.m()); - if (!Utils.close_enough(m, svi2.m(), 100)) - QAssert.Fail("error in m coefficient estimation"); - - Console.WriteLine("error=" + svi2.rmsError()); - } - - } + public void testCalibration() + { + double forward = 0.03; + double tau = 1.0; + + //Real a = 0.04; + //Real b = 0.1; + //Real rho = -0.5; + //Real sigma = 0.1; + //Real m = 0.0; + double a = 0.1; + double b = 0.06; + double rho = -0.9; + double m = 0.24; + double sigma = 0.06; + + List strikes = new List(); + strikes.Add(0.01); + strikes.Add(0.015); + strikes.Add(0.02); + strikes.Add(0.025); + strikes.Add(0.03); + strikes.Add(0.035); + strikes.Add(0.04); + strikes.Add(0.045); + strikes.Add(0.05); + + List vols = new InitializedList(strikes.Count, 0.20); //dummy vols (we do not calibrate here) + + SviInterpolation svi = new SviInterpolation(strikes, strikes.Count, vols, tau, + forward, a, b, sigma, rho, m, true, true, true, + true, true); + + svi.enableExtrapolation(); + + List sviVols = new InitializedList(strikes.Count, 0.0); + for (int i = 0; i < strikes.Count; ++i) + sviVols[i] = svi.value(strikes[i]); + + SviInterpolation svi2 = new SviInterpolation(strikes, strikes.Count, sviVols, tau, + forward, null, null, null, + null, null, false, false, false, + false, false, false, null, + null, 1E-8, false, + 0); //don't allow for random start values + + svi2.enableExtrapolation(); + svi2.update(); + + Console.WriteLine("a=" + svi2.a()); + if (!Utils.close_enough(a, svi2.a(), 100)) + QAssert.Fail("error in a coefficient estimation"); + + Console.WriteLine("b=" + svi2.b()); + if (!Utils.close_enough(b, svi2.b(), 100)) + QAssert.Fail("error in b coefficient estimation"); + + Console.WriteLine("sigma=" + svi2.sigma()); + if (!Utils.close_enough(sigma, svi2.sigma(), 100)) + QAssert.Fail("error in sigma coefficient estimation"); + + Console.WriteLine("rho=" + svi2.rho()); + if (!Utils.close_enough(rho, svi2.rho(), 100)) + QAssert.Fail("error in rho coefficient estimation"); + + Console.WriteLine("m=" + svi2.m()); + if (!Utils.close_enough(m, svi2.m(), 100)) + QAssert.Fail("error in m coefficient estimation"); + + Console.WriteLine("error=" + svi2.rmsError()); + } + + } } diff --git a/tests/QLNet.Tests/T_SampledCurve.cs b/tests/QLNet.Tests/T_SampledCurve.cs index c47112209..fe70a86de 100644 --- a/tests/QLNet.Tests/T_SampledCurve.cs +++ b/tests/QLNet.Tests/T_SampledCurve.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,7 +20,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -38,9 +38,9 @@ class FSquared } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testConstruction() { @@ -89,9 +89,9 @@ public void testConstruction() if (Math.Abs(v - exp) > tolerance) { QAssert.Fail("sample curve regriding failed" + - "\n at " + (i + 1) + " point " + "(x = " + grid + ")" + - "\n grid value: " + v + - "\n expected: " + exp); + "\n at " + (i + 1) + " point " + "(x = " + grid + ")" + + "\n grid value: " + v + + "\n expected: " + exp); } } } diff --git a/tests/QLNet.Tests/T_Schedule.cs b/tests/QLNet.Tests/T_Schedule.cs index e82df1d40..022e8606f 100644 --- a/tests/QLNet.Tests/T_Schedule.cs +++ b/tests/QLNet.Tests/T_Schedule.cs @@ -6,7 +6,7 @@ QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -20,7 +20,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -49,9 +49,9 @@ void check_dates(Schedule s, List expected) } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testDailySchedule() { @@ -60,9 +60,9 @@ public void testDailySchedule() Date startDate = new Date(17, Month.January, 2012); Schedule s = new MakeSchedule().from(startDate).to(startDate + 7) - .withCalendar(new TARGET()) - .withConvention(BusinessDayConvention.Preceding) - .withFrequency(Frequency.Daily).value(); + .withCalendar(new TARGET()) + .withConvention(BusinessDayConvention.Preceding) + .withFrequency(Frequency.Daily).value(); List expected = new List(6); // The schedule should skip Saturday 21st and Sunday 22rd. @@ -79,22 +79,22 @@ public void testDailySchedule() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testEndDateWithEomAdjustment() { // Testing end date for schedule with end-of-month adjustment Schedule s = new MakeSchedule().from(new Date(30, Month.September, 2009)) - .to(new Date(15, Month.June, 2012)) - .withCalendar(new Japan()) - .withTenor(new Period(6, TimeUnit.Months)) - .withConvention(BusinessDayConvention.Following) - .withTerminationDateConvention(BusinessDayConvention.Following) - .forwards() - .endOfMonth().value(); + .to(new Date(15, Month.June, 2012)) + .withCalendar(new Japan()) + .withTenor(new Period(6, TimeUnit.Months)) + .withConvention(BusinessDayConvention.Following) + .withTerminationDateConvention(BusinessDayConvention.Following) + .forwards() + .endOfMonth().value(); List expected = new List(); // The end date is adjusted, so it should also be moved to the end @@ -111,13 +111,13 @@ public void testEndDateWithEomAdjustment() // now with unadjusted termination date... s = new MakeSchedule().from(new Date(30, Month.September, 2009)) - .to(new Date(15, Month.June, 2012)) - .withCalendar(new Japan()) - .withTenor(new Period(6, TimeUnit.Months)) - .withConvention(BusinessDayConvention.Following) - .withTerminationDateConvention(BusinessDayConvention.Unadjusted) - .forwards() - .endOfMonth().value(); + .to(new Date(15, Month.June, 2012)) + .withCalendar(new Japan()) + .withTenor(new Period(6, TimeUnit.Months)) + .withConvention(BusinessDayConvention.Following) + .withTerminationDateConvention(BusinessDayConvention.Unadjusted) + .forwards() + .endOfMonth().value(); // ...which should leave it alone. expected[6] = new Date(15, Month.June, 2012); @@ -125,21 +125,21 @@ public void testEndDateWithEomAdjustment() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testDatesPastEndDateWithEomAdjustment() { Schedule s = new MakeSchedule().from(new Date(28, Month.March, 2013)) - .to(new Date(30, Month.March, 2015)) - .withCalendar(new TARGET()) - .withTenor(new Period(1, TimeUnit.Years)) - .withConvention(BusinessDayConvention.Unadjusted) - .withTerminationDateConvention(BusinessDayConvention.Unadjusted) - .forwards() - .endOfMonth().value(); + .to(new Date(30, Month.March, 2015)) + .withCalendar(new TARGET()) + .withTenor(new Period(1, TimeUnit.Years)) + .withConvention(BusinessDayConvention.Unadjusted) + .withTerminationDateConvention(BusinessDayConvention.Unadjusted) + .forwards() + .endOfMonth().value(); List expected = new List(); expected.Add(new Date(31, Month.March, 2013)); @@ -152,23 +152,23 @@ public void testDatesPastEndDateWithEomAdjustment() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testDatesSameAsEndDateWithEomAdjustment() { // Testing that next-to-last date same as end date is removed... Schedule s = new MakeSchedule().from(new Date(28, Month.March, 2013)) - .to(new Date(31, Month.March, 2015)) - .withCalendar(new TARGET()) - .withTenor(new Period(1, TimeUnit.Years)) - .withConvention(BusinessDayConvention.Unadjusted) - .withTerminationDateConvention(BusinessDayConvention.Unadjusted) - .forwards() - .endOfMonth() - .value(); + .to(new Date(31, Month.March, 2015)) + .withCalendar(new TARGET()) + .withTenor(new Period(1, TimeUnit.Years)) + .withConvention(BusinessDayConvention.Unadjusted) + .withTerminationDateConvention(BusinessDayConvention.Unadjusted) + .forwards() + .endOfMonth() + .value(); List expected = new List(3); expected.Add(new Date(31, Month.March, 2013)); @@ -186,22 +186,22 @@ public void testDatesSameAsEndDateWithEomAdjustment() #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testForwardDatesWithEomAdjustment() { // Testing that the last date is not adjusted for EOM when termination date convention is unadjusted Schedule s = new MakeSchedule().from(new Date(31, Month.August, 1996)) - .to(new Date(15, Month.September, 1997)) - .withCalendar(new UnitedStates(UnitedStates.Market.GovernmentBond)) - .withTenor(new Period(6, TimeUnit.Months)) - .withConvention(BusinessDayConvention.Unadjusted) - .withTerminationDateConvention(BusinessDayConvention.Unadjusted) - .forwards() - .endOfMonth().value(); + .to(new Date(15, Month.September, 1997)) + .withCalendar(new UnitedStates(UnitedStates.Market.GovernmentBond)) + .withTenor(new Period(6, TimeUnit.Months)) + .withConvention(BusinessDayConvention.Unadjusted) + .withTerminationDateConvention(BusinessDayConvention.Unadjusted) + .forwards() + .endOfMonth().value(); List expected = new List(); expected.Add(new Date(31, Month.August, 1996)); @@ -213,22 +213,22 @@ public void testForwardDatesWithEomAdjustment() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testBackwardDatesWithEomAdjustment() { // Testing that the first date is not adjusted for EOM going backward when termination date convention is unadjusted Schedule s = new MakeSchedule().from(new Date(22, Month.August, 1996)) - .to(new Date(31, Month.August, 1997)) - .withCalendar(new UnitedStates(UnitedStates.Market.GovernmentBond)) - .withTenor(new Period(6, TimeUnit.Months)) - .withConvention(BusinessDayConvention.Unadjusted) - .withTerminationDateConvention(BusinessDayConvention.Unadjusted) - .backwards() - .endOfMonth().value(); + .to(new Date(31, Month.August, 1997)) + .withCalendar(new UnitedStates(UnitedStates.Market.GovernmentBond)) + .withTenor(new Period(6, TimeUnit.Months)) + .withConvention(BusinessDayConvention.Unadjusted) + .withTerminationDateConvention(BusinessDayConvention.Unadjusted) + .backwards() + .endOfMonth().value(); List expected = new List(); expected.Add(new Date(22, Month.August, 1996)); @@ -240,22 +240,22 @@ public void testBackwardDatesWithEomAdjustment() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testDoubleFirstDateWithEomAdjustment() { // Testing that the first date is not duplicated due to EOM convention when going backwards Schedule s = new MakeSchedule().from(new Date(22, Month.August, 1996)) - .to(new Date(31, Month.August, 1997)) - .withCalendar(new UnitedStates(UnitedStates.Market.GovernmentBond)) - .withTenor(new Period(6, TimeUnit.Months)) - .withConvention(BusinessDayConvention.Following) - .withTerminationDateConvention(BusinessDayConvention.Following) - .backwards() - .endOfMonth().value(); + .to(new Date(31, Month.August, 1997)) + .withCalendar(new UnitedStates(UnitedStates.Market.GovernmentBond)) + .withTenor(new Period(6, TimeUnit.Months)) + .withConvention(BusinessDayConvention.Following) + .withTerminationDateConvention(BusinessDayConvention.Following) + .backwards() + .endOfMonth().value(); List expected = new List(); expected.Add(new Date(30, Month.August, 1996)); @@ -268,7 +268,7 @@ public void testDoubleFirstDateWithEomAdjustment() #if NET40 || NET45 [TestMethod()] #else - [Fact] + [Fact] #endif public void testCDS2015Convention() { @@ -276,32 +276,32 @@ public void testCDS2015Convention() //From September 20th 2016 to March 19th 2017 of the next Year, //end date is December 20th 2021 for a 5 year Swap Schedule s1 = new MakeSchedule().from(new Date(12, Month.December, 2016)) - .to(new Date(12, Month.December, 2016) + new Period(5, TimeUnit.Years)) - .withCalendar(new WeekendsOnly()) - .withTenor(new Period(3 , TimeUnit.Months)) - .withConvention(BusinessDayConvention.ModifiedFollowing) - .withTerminationDateConvention(BusinessDayConvention.Unadjusted) - .withRule(DateGeneration.Rule.CDS2015).value(); + .to(new Date(12, Month.December, 2016) + new Period(5, TimeUnit.Years)) + .withCalendar(new WeekendsOnly()) + .withTenor(new Period(3, TimeUnit.Months)) + .withConvention(BusinessDayConvention.ModifiedFollowing) + .withTerminationDateConvention(BusinessDayConvention.Unadjusted) + .withRule(DateGeneration.Rule.CDS2015).value(); QAssert.IsTrue(s1.startDate() == new Date(20, Month.September, 2016)); QAssert.IsTrue(s1.endDate() == new Date(20, Month.December, 2021)); Schedule s2 = new MakeSchedule().from(new Date(1, Month.March, 2017)) - .to(new Date(1, Month.March, 2017) + new Period(5, TimeUnit.Years)) - .withCalendar(new WeekendsOnly()) - .withTenor(new Period(3 , TimeUnit.Months)) - .withConvention(BusinessDayConvention.ModifiedFollowing) - .withTerminationDateConvention(BusinessDayConvention.Unadjusted) - .withRule(DateGeneration.Rule.CDS2015).value(); + .to(new Date(1, Month.March, 2017) + new Period(5, TimeUnit.Years)) + .withCalendar(new WeekendsOnly()) + .withTenor(new Period(3, TimeUnit.Months)) + .withConvention(BusinessDayConvention.ModifiedFollowing) + .withTerminationDateConvention(BusinessDayConvention.Unadjusted) + .withRule(DateGeneration.Rule.CDS2015).value(); QAssert.IsTrue(s2.startDate() == new Date(20, Month.December, 2016)); QAssert.IsTrue(s2.endDate() == new Date(20, Month.December, 2021)); //From March 20th 2017 to September 19th 2017 //end date is June 20th 2022 for a 5 year Swap Schedule s3 = new MakeSchedule().from(new Date(20, Month.March, 2017)) - .to(new Date(20, Month.March, 2017) + new Period(5, TimeUnit.Years)) - .withCalendar(new WeekendsOnly()) - .withTenor(new Period(3 , TimeUnit.Months)) - .withConvention(BusinessDayConvention.ModifiedFollowing) - .withTerminationDateConvention(BusinessDayConvention.Unadjusted) - .withRule(DateGeneration.Rule.CDS2015).value(); + .to(new Date(20, Month.March, 2017) + new Period(5, TimeUnit.Years)) + .withCalendar(new WeekendsOnly()) + .withTenor(new Period(3, TimeUnit.Months)) + .withConvention(BusinessDayConvention.ModifiedFollowing) + .withTerminationDateConvention(BusinessDayConvention.Unadjusted) + .withRule(DateGeneration.Rule.CDS2015).value(); QAssert.IsTrue(s3.startDate() == new Date(20, Month.March, 2017)); QAssert.IsTrue(s3.endDate() == new Date(20, Month.June, 2022)); @@ -310,7 +310,7 @@ public void testCDS2015Convention() #if NET40 || NET45 [TestMethod()] #else - [Fact] + [Fact] #endif public void testDateConstructor() { @@ -325,14 +325,14 @@ public void testDateConstructor() // schedule without any additional information Schedule schedule1 = new Schedule(dates); if (schedule1.Count != dates.Count) - QAssert.Fail( "schedule1 has size " + schedule1.Count + ", expected " + dates.Count ); + QAssert.Fail("schedule1 has size " + schedule1.Count + ", expected " + dates.Count); for (int i = 0; i < dates.Count; ++i) if (schedule1[i] != dates[i]) - QAssert.Fail("schedule1 has "+schedule1[i]+" at position "+i+", expected "+ dates[i]); + QAssert.Fail("schedule1 has " + schedule1[i] + " at position " + i + ", expected " + dates[i]); if (schedule1.calendar() != new NullCalendar()) - QAssert.Fail("schedule1 has calendar "+schedule1.calendar().name()+", expected null calendar"); + QAssert.Fail("schedule1 has calendar " + schedule1.calendar().name() + ", expected null calendar"); if (schedule1.businessDayConvention() != BusinessDayConvention.Unadjusted) - QAssert.Fail( "schedule1 has convention " + schedule1.businessDayConvention() + ", expected unadjusted" ); + QAssert.Fail("schedule1 has convention " + schedule1.businessDayConvention() + ", expected unadjusted"); // schedule with metadata List regular = new List(); @@ -341,20 +341,20 @@ public void testDateConstructor() regular.Add(false); Schedule schedule2 = new Schedule(dates, new TARGET(), BusinessDayConvention.Following, BusinessDayConvention.ModifiedPreceding, new Period(1, TimeUnit.Years), - DateGeneration.Rule.Backward, true, regular); + DateGeneration.Rule.Backward, true, regular); for (int i = 1; i < dates.Count; ++i) if (schedule2.isRegular(i) != regular[i - 1]) - QAssert.Fail( "schedule2 has a " + ( schedule2.isRegular( i ) ? "regular" : "irregular" ) + " period at position " + i + ", expected " + ( regular[i - 1] ? "regular" : "irregular" ) ); + QAssert.Fail("schedule2 has a " + (schedule2.isRegular(i) ? "regular" : "irregular") + " period at position " + i + ", expected " + (regular[i - 1] ? "regular" : "irregular")); if (schedule2.calendar() != new TARGET()) - QAssert.Fail( "schedule1 has calendar " + schedule2.calendar().name() + ", expected TARGET" ); + QAssert.Fail("schedule1 has calendar " + schedule2.calendar().name() + ", expected TARGET"); if (schedule2.businessDayConvention() != BusinessDayConvention.Following) - QAssert.Fail( "schedule2 has convention " + schedule2.businessDayConvention() + ", expected Following" ); + QAssert.Fail("schedule2 has convention " + schedule2.businessDayConvention() + ", expected Following"); if (schedule2.terminationDateBusinessDayConvention() != BusinessDayConvention.ModifiedPreceding) - QAssert.Fail( "schedule2 has convention " + schedule2.terminationDateBusinessDayConvention() + ", expected Modified Preceding" ); + QAssert.Fail("schedule2 has convention " + schedule2.terminationDateBusinessDayConvention() + ", expected Modified Preceding"); if (schedule2.tenor() != new Period(1, TimeUnit.Years)) - QAssert.Fail( "schedule2 has tenor " + schedule2.tenor() + ", expected 1Y" ); + QAssert.Fail("schedule2 has tenor " + schedule2.tenor() + ", expected 1Y"); if (schedule2.rule() != DateGeneration.Rule.Backward) - QAssert.Fail( "schedule2 has rule " + schedule2.rule() + ", expected Backward" ); + QAssert.Fail("schedule2 has rule " + schedule2.rule() + ", expected Backward"); if (schedule2.endOfMonth() != true) QAssert.Fail("schedule2 has end of month flag false, expected true"); } diff --git a/tests/QLNet.Tests/T_ShortRateModels.cs b/tests/QLNet.Tests/T_ShortRateModels.cs index ae745de55..edc633df7 100644 --- a/tests/QLNet.Tests/T_ShortRateModels.cs +++ b/tests/QLNet.Tests/T_ShortRateModels.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,7 +24,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -33,256 +33,266 @@ namespace TestSuite #if NET40 || NET45 [TestClass()] #endif - public class T_ShortRateModels - { - - public class CalibrationData - { - public int start; - public int length; - public double volatility; - public CalibrationData(int s, int l, double v) - { - start = s; - length = l; - volatility = v; - } - } + public class T_ShortRateModels + { + + public class CalibrationData + { + public int start; + public int length; + public double volatility; + public CalibrationData(int s, int l, double v) + { + start = s; + length = l; + volatility = v; + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testCachedHullWhite() { + public void testCachedHullWhite() + { //("Testing Hull-White calibration against cached values..."); - Date today=new Date(15, Month.February, 2002); - Date settlement=new Date(19, Month.February, 2002); + Date today = new Date(15, Month.February, 2002); + Date settlement = new Date(19, Month.February, 2002); Settings.setEvaluationDate(today); - Handle termStructure= - new Handle(Utilities.flatRate(settlement, 0.04875825, new Actual365Fixed())); + Handle termStructure = + new Handle(Utilities.flatRate(settlement, 0.04875825, new Actual365Fixed())); //termStructure.link - HullWhite model=new HullWhite(termStructure); - - CalibrationData[] data = { new CalibrationData( 1, 5, 0.1148 ), - new CalibrationData( 2, 4, 0.1108 ), - new CalibrationData( 3, 3, 0.1070 ), - new CalibrationData( 4, 2, 0.1021 ), - new CalibrationData( 5, 1, 0.1000 )}; + HullWhite model = new HullWhite(termStructure); + + CalibrationData[] data = { new CalibrationData(1, 5, 0.1148), + new CalibrationData(2, 4, 0.1108), + new CalibrationData(3, 3, 0.1070), + new CalibrationData(4, 2, 0.1021), + new CalibrationData(5, 1, 0.1000) + }; IborIndex index = new Euribor6M(termStructure); IPricingEngine engine = new JamshidianSwaptionEngine(model); List swaptions = new List(); - for (int i=0; i(vol), - index, - new Period(1, TimeUnit.Years), - new Thirty360(), - new Actual360(), - termStructure); - helper.setPricingEngine(engine); - swaptions.Add(helper); + for (int i = 0; i < data.Length; i++) + { + Quote vol = new SimpleQuote(data[i].volatility); + CalibrationHelper helper = + new SwaptionHelper(new Period(data[i].start, TimeUnit.Years), + new Period(data[i].length, TimeUnit.Years), + new Handle(vol), + index, + new Period(1, TimeUnit.Years), + new Thirty360(), + new Actual360(), + termStructure); + helper.setPricingEngine(engine); + swaptions.Add(helper); } // Set up the optimization problem // Real simplexLambda = 0.1; // Simplex optimizationMethod(simplexLambda); - LevenbergMarquardt optimizationMethod = new LevenbergMarquardt(1.0e-8,1.0e-8,1.0e-8); + LevenbergMarquardt optimizationMethod = new LevenbergMarquardt(1.0e-8, 1.0e-8, 1.0e-8); EndCriteria endCriteria = new EndCriteria(10000, 100, 1e-6, 1e-8, 1e-8); //Optimize - model.calibrate(swaptions, optimizationMethod, endCriteria, new Constraint(),new List()); + model.calibrate(swaptions, optimizationMethod, endCriteria, new Constraint(), new List()); EndCriteria.Type ecType = model.endCriteria(); // Check and print out results - #if QL_USE_INDEXED_COUPON +#if QL_USE_INDEXED_COUPON double cachedA = 0.0488199, cachedSigma = 0.00593579; - #else +#else double cachedA = 0.0488565, cachedSigma = 0.00593662; - #endif +#endif double tolerance = 1.120e-5; //double tolerance = 1.0e-6; Vector xMinCalculated = model.parameters(); double yMinCalculated = model.value(xMinCalculated, swaptions); Vector xMinExpected = new Vector(2); - xMinExpected[0]= cachedA; - xMinExpected[1]= cachedSigma; + xMinExpected[0] = cachedA; + xMinExpected[1] = cachedSigma; double yMinExpected = model.value(xMinExpected, swaptions); - if (Math.Abs(xMinCalculated[0]-cachedA) > tolerance - || Math.Abs(xMinCalculated[1]-cachedSigma) > tolerance) { - QAssert.Fail ("Failed to reproduce cached calibration results:\n" - + "calculated: a = " + xMinCalculated[0] + ", " - + "sigma = " + xMinCalculated[1] + ", " - + "f(a) = " + yMinCalculated + ",\n" - + "expected: a = " + xMinExpected[0] + ", " - + "sigma = " + xMinExpected[1] + ", " - + "f(a) = " + yMinExpected + ",\n" - + "difference: a = " + (xMinCalculated[0]-xMinExpected[0]) + ", " - + "sigma = " + (xMinCalculated[1]-xMinExpected[1]) + ", " - + "f(a) = " + (yMinCalculated - yMinExpected) + ",\n" - + "end criteria = " + ecType ); + if (Math.Abs(xMinCalculated[0] - cachedA) > tolerance + || Math.Abs(xMinCalculated[1] - cachedSigma) > tolerance) + { + QAssert.Fail("Failed to reproduce cached calibration results:\n" + + "calculated: a = " + xMinCalculated[0] + ", " + + "sigma = " + xMinCalculated[1] + ", " + + "f(a) = " + yMinCalculated + ",\n" + + "expected: a = " + xMinExpected[0] + ", " + + "sigma = " + xMinExpected[1] + ", " + + "f(a) = " + yMinExpected + ",\n" + + "difference: a = " + (xMinCalculated[0] - xMinExpected[0]) + ", " + + "sigma = " + (xMinCalculated[1] - xMinExpected[1]) + ", " + + "f(a) = " + (yMinCalculated - yMinExpected) + ",\n" + + "end criteria = " + ecType); } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testSwaps() { - //BOOST_MESSAGE("Testing Hull-White swap pricing against known values..."); - - Date today; //=Settings::instance().evaluationDate();; - - Calendar calendar = new TARGET(); - today = calendar.adjust(Date.Today); - Settings.setEvaluationDate(today); - - Date settlement = calendar.advance(today, 2, TimeUnit.Days); - - Date[] dates = { - settlement, - calendar.advance(settlement,1,TimeUnit.Weeks), - calendar.advance(settlement,1,TimeUnit.Months), - calendar.advance(settlement,3,TimeUnit.Months), - calendar.advance(settlement,6,TimeUnit.Months), - calendar.advance(settlement,9,TimeUnit.Months), - calendar.advance(settlement,1,TimeUnit.Years), - calendar.advance(settlement,2,TimeUnit.Years), - calendar.advance(settlement,3,TimeUnit.Years), - calendar.advance(settlement,5,TimeUnit.Years), - calendar.advance(settlement,10,TimeUnit.Years), - calendar.advance(settlement,15,TimeUnit.Years) - }; - double[] discounts = { - 1.0, - 0.999258, - 0.996704, - 0.990809, - 0.981798, - 0.972570, - 0.963430, - 0.929532, - 0.889267, - 0.803693, - 0.596903, - 0.433022 - }; - - //for (int i = 0; i < dates.Length; i++) - // dates[i] + dates.Length; - - LogLinear Interpolator = new LogLinear(); - - Handle termStructure = - new Handle( - new InterpolatedDiscountCurve( - dates.ToList(), - discounts.ToList(), - new Actual365Fixed(),new Calendar(), null, null , Interpolator) - ); - - HullWhite model = new HullWhite(termStructure); - - int[] start = { -3, 0, 3 }; - int[] length = { 2, 5, 10 }; - double[] rates = { 0.02, 0.04, 0.06 }; - IborIndex euribor = new Euribor6M(termStructure); - - IPricingEngine engine = new TreeVanillaSwapEngine(model, 120, termStructure); - - #if QL_USE_INDEXED_COUPON - double tolerance = 4.0e-3; - #else - double tolerance = 1.0e-8; - #endif - - for (int i=0; i pastFixings; - ObservableValue> pastFixings = new ObservableValue>(); - pastFixings.value()[fixingDate] = 0.03; - IndexManager.instance().setHistory(euribor.name(), - pastFixings); - } - - for (int j=0; j tolerance) { - QAssert.Fail("Failed to reproduce swap NPV:" - //+ QL_FIXED << std::setprecision(9) - + "\n calculated: " + calculated - + "\n expected: " + expected - //+ QL_SCIENTIFIC - + "\n rel. error: " + error); - } - } - } - } - } + public void testSwaps() + { + //BOOST_MESSAGE("Testing Hull-White swap pricing against known values..."); -#if NET40 || NET45 - [TestMethod()] -#else - [Fact] -#endif - public void testFuturesConvexityBias() - { - //BOOST_MESSAGE("Testing Hull-White futures convexity bias..."); + Date today; //=Settings::instance().evaluationDate();; - // G. Kirikos, D. Novak, "Convexity Conundrums", Risk Magazine, March 1997 - double futureQuote = 94.0; - double a = 0.03; - double sigma = 0.015; - double t = 5.0; - double T = 5.25; + Calendar calendar = new TARGET(); + today = calendar.adjust(Date.Today); + Settings.setEvaluationDate(today); - double expectedForward = 0.0573037; - double tolerance = 0.0000001; + Date settlement = calendar.advance(today, 2, TimeUnit.Days); + + Date[] dates = + { + settlement, + calendar.advance(settlement, 1, TimeUnit.Weeks), + calendar.advance(settlement, 1, TimeUnit.Months), + calendar.advance(settlement, 3, TimeUnit.Months), + calendar.advance(settlement, 6, TimeUnit.Months), + calendar.advance(settlement, 9, TimeUnit.Months), + calendar.advance(settlement, 1, TimeUnit.Years), + calendar.advance(settlement, 2, TimeUnit.Years), + calendar.advance(settlement, 3, TimeUnit.Years), + calendar.advance(settlement, 5, TimeUnit.Years), + calendar.advance(settlement, 10, TimeUnit.Years), + calendar.advance(settlement, 15, TimeUnit.Years) + }; + double[] discounts = + { + 1.0, + 0.999258, + 0.996704, + 0.990809, + 0.981798, + 0.972570, + 0.963430, + 0.929532, + 0.889267, + 0.803693, + 0.596903, + 0.433022 + }; + + //for (int i = 0; i < dates.Length; i++) + // dates[i] + dates.Length; + + LogLinear Interpolator = new LogLinear(); + + Handle termStructure = + new Handle( + new InterpolatedDiscountCurve( + dates.ToList(), + discounts.ToList(), + new Actual365Fixed(), new Calendar(), null, null, Interpolator) + ); + + HullWhite model = new HullWhite(termStructure); + + int[] start = { -3, 0, 3 }; + int[] length = { 2, 5, 10 }; + double[] rates = { 0.02, 0.04, 0.06 }; + IborIndex euribor = new Euribor6M(termStructure); + + IPricingEngine engine = new TreeVanillaSwapEngine(model, 120, termStructure); + +#if QL_USE_INDEXED_COUPON + double tolerance = 4.0e-3; +#else + double tolerance = 1.0e-8; +#endif - double futureImpliedRate = (100.0 - futureQuote) / 100.0; - double calculatedForward = - futureImpliedRate - HullWhite.convexityBias(futureQuote, t, T, sigma, a); + for (int i = 0; i < start.Length; i++) + { - double error = Math.Abs(calculatedForward - expectedForward); + Date startDate = calendar.advance(settlement, start[i], TimeUnit.Months); + if (startDate < today) + { + Date fixingDate = calendar.advance(startDate, -2, TimeUnit.Days); + TimeSeries < double? > pastFixings = new TimeSeries < double? >(); + pastFixings[fixingDate] = 0.03; + IndexManager.instance().setHistory(euribor.name(), pastFixings); + } - if (error > tolerance) + for (int j = 0; j < length.Length; j++) { - QAssert.Fail("Failed to reproduce convexity bias:" - + "\ncalculated: " + calculatedForward - + "\n expected: " + expectedForward - //+ QL_SCIENTIFIC - + "\n error: " + error - + "\n tolerance: " + tolerance); + + Date maturity = calendar.advance(startDate, length[i], TimeUnit.Years); + Schedule fixedSchedule = new Schedule(startDate, maturity, new Period(Frequency.Annual), + calendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Forward, false); + Schedule floatSchedule = new Schedule(startDate, maturity, new Period(Frequency.Semiannual), + calendar, BusinessDayConvention.Following, BusinessDayConvention.Following, + DateGeneration.Rule.Forward, false); + for (int k = 0; k < rates.Length; k++) + { + + VanillaSwap swap = new VanillaSwap(VanillaSwap.Type.Payer, 1000000.0, + fixedSchedule, rates[k], new Thirty360(), + floatSchedule, euribor, 0.0, new Actual360()); + swap.setPricingEngine(new DiscountingSwapEngine(termStructure)); + double expected = swap.NPV(); + swap.setPricingEngine(engine); + double calculated = swap.NPV(); + + double error = Math.Abs((expected - calculated) / expected); + if (error > tolerance) + { + QAssert.Fail("Failed to reproduce swap NPV:" + //+ QL_FIXED << std::setprecision(9) + + "\n calculated: " + calculated + + "\n expected: " + expected + //+ QL_SCIENTIFIC + + "\n rel. error: " + error); + } + } } + } + } - } - } -} \ No newline at end of file +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testFuturesConvexityBias() + { + //BOOST_MESSAGE("Testing Hull-White futures convexity bias..."); + + // G. Kirikos, D. Novak, "Convexity Conundrums", Risk Magazine, March 1997 + double futureQuote = 94.0; + double a = 0.03; + double sigma = 0.015; + double t = 5.0; + double T = 5.25; + + double expectedForward = 0.0573037; + double tolerance = 0.0000001; + + double futureImpliedRate = (100.0 - futureQuote) / 100.0; + double calculatedForward = + futureImpliedRate - HullWhite.convexityBias(futureQuote, t, T, sigma, a); + + double error = Math.Abs(calculatedForward - expectedForward); + + if (error > tolerance) + { + QAssert.Fail("Failed to reproduce convexity bias:" + + "\ncalculated: " + calculatedForward + + "\n expected: " + expectedForward + //+ QL_SCIENTIFIC + + "\n error: " + error + + "\n tolerance: " + tolerance); + } + + } + } +} diff --git a/tests/QLNet.Tests/T_Solvers.cs b/tests/QLNet.Tests/T_Solvers.cs index 195a507a9..a7eccad51 100644 --- a/tests/QLNet.Tests/T_Solvers.cs +++ b/tests/QLNet.Tests/T_Solvers.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,7 +21,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -36,7 +36,7 @@ class Foo : ISolver1d { public override double value(double x) { return x * x - 1.0; } public override double derivative(double x) { return 2.0 * x; } - }; + } public void test(Solver1D solver, string name) { @@ -48,70 +48,70 @@ public void test(Solver1D solver, string name) if (Math.Abs(root - expected) > accuracy[i]) { QAssert.Fail(name + " solver:\n" - + " expected: " + expected + "\n" - + " calculated: " + root + "\n" - + " accuracy: " + accuracy[i]); + + " expected: " + expected + "\n" + + " calculated: " + root + "\n" + + " accuracy: " + accuracy[i]); } root = solver.solve(new Foo(), accuracy[i], 1.5, 0.0, 1.0); if (Math.Abs(root - expected) > accuracy[i]) { QAssert.Fail(name + " solver (bracketed):\n" - + " expected: " + expected + "\n" - + " calculated: " + root + "\n" - + " accuracy: " + accuracy[i]); + + " expected: " + expected + "\n" + + " calculated: " + root + "\n" + + " accuracy: " + accuracy[i]); } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testBrent() { test(new Brent(), "Brent"); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testNewton() { test(new Newton(), "Newton"); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testFalsePosition() { test(new FalsePosition(), "FalsePosition"); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testBisection() { test(new Bisection(), "Bisection"); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testRidder() { test(new Ridder(), "Ridder"); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testSecant() { diff --git a/tests/QLNet.Tests/T_SpreadOption.cs b/tests/QLNet.Tests/T_SpreadOption.cs new file mode 100644 index 000000000..921461908 --- /dev/null +++ b/tests/QLNet.Tests/T_SpreadOption.cs @@ -0,0 +1,189 @@ +// Copyright (C) 2008-2018 Andrea Maggiulli (a.maggiulli@gmail.com) +// +// This file is part of QLNet Project https://github.com/amaggiulli/qlnet +// QLNet is free software: you can redistribute it and/or modify it +// under the terms of the QLNet license. You should have received a +// copy of the license along with this program; if not, license is +// available at . +// +// QLNet is a based on QuantLib, a free-software/open-source library +// for financial quantitative analysts and developers - http://quantlib.org/ +// The QuantLib license is available online at http://quantlib.org/license.shtml. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the license for more details. +using System; +#if NET40 || NET45 +using Microsoft.VisualStudio.TestTools.UnitTesting; +#else +using Xunit; +#endif +using QLNet; + +namespace TestSuite +{ +#if NET40 || NET45 + [TestClass()] +#endif + public class T_SpreadOption + { + private void REPORT_FAILURE(string greekName, + StrikedTypePayoff payoff, + Exercise exercise, + double expected, + double calculated, + double tolerance, + Date today) + { + QAssert.Fail(exercise + " " + + "Spread option with " + + payoff + " payoff:\n" + + " strike: " + payoff.strike() + "\n" + + " reference date: " + today + "\n" + + " maturity: " + exercise.lastDate() + "\n" + + " expected " + greekName + ": " + expected + "\n" + + " calculated " + greekName + ": " + calculated + "\n" + + " error: " + Math.Abs(expected - calculated) + "\n" + + " tolerance: " + tolerance); + } + + private struct Case + { + public double F1; + public double F2; + public double X; + public double r; + public double sigma1; + public double sigma2; + public double rho; + public int length; + public double value; + public double theta; + + public Case(double f1, double f2, double x, double r, double sigma1, + double sigma2, double rho, int length, double value, double theta) + { + F1 = f1; + F2 = f2; + X = x; + this.r = r; + this.sigma1 = sigma1; + this.sigma2 = sigma2; + this.rho = rho; + this.length = length; + this.value = value; + this.theta = theta; + } + } +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testKirkEngine() + { + // Testing Kirk approximation for spread options + + /* The example data below are from "complete guide to option + pricing formulas", Espen Gaarder Haug, p 60 + + Expected values of option theta were calculated using automatic + differentiation of the pricing function. The engine uses closed-form + formula */ + + Case[] cases = + { + new Case(28.0, 20.0, 7.0, 0.05, 0.29, 0.36, 0.42, 90, 2.1670, 3.0431), + new Case(122.0, 120.0, 3.0, 0.10, 0.20, 0.20, -0.5, 36, 4.7530, 25.5905), + new Case(122.0, 120.0, 3.0, 0.10, 0.20, 0.20, 0.0, 36, 3.7970, 20.8841), + new Case(122.0, 120.0, 3.0, 0.10, 0.20, 0.20, 0.5, 36, 2.5537, 14.7260), + new Case(122.0, 120.0, 3.0, 0.10, 0.20, 0.20, -0.5, 180, 10.7517, 10.0847), + new Case(122.0, 120.0, 3.0, 0.10, 0.20, 0.20, 0.0, 180, 8.7020, 8.2619), + new Case(122.0, 120.0, 3.0, 0.10, 0.20, 0.20, 0.5, 180, 6.0257, 5.8661), + new Case(122.0, 120.0, 3.0, 0.10, 0.25, 0.20, -0.5, 36, 5.4275, 28.9013), + new Case(122.0, 120.0, 3.0, 0.10, 0.25, 0.20, 0.0, 36, 4.3712, 23.7133), + new Case(122.0, 120.0, 3.0, 0.10, 0.25, 0.20, 0.5, 36, 3.0086, 16.9864), + new Case(122.0, 120.0, 3.0, 0.10, 0.25, 0.20, -0.5, 180, 12.1941, 11.3603), + new Case(122.0, 120.0, 3.0, 0.10, 0.25, 0.20, 0.0, 180, 9.9340, 9.3589), + new Case(122.0, 120.0, 3.0, 0.10, 0.25, 0.20, 0.5, 180, 7.0067, 6.7463), + new Case(122.0, 120.0, 3.0, 0.10, 0.20, 0.25, -0.5, 36, 5.4061, 28.7963), + new Case(122.0, 120.0, 3.0, 0.10, 0.20, 0.25, 0.0, 36, 4.3451, 23.5848), + new Case(122.0, 120.0, 3.0, 0.10, 0.20, 0.25, 0.5, 36, 2.9723, 16.8060), + new Case(122.0, 120.0, 3.0, 0.10, 0.20, 0.25, -0.5, 180, 12.1483, 11.3200), + new Case(122.0, 120.0, 3.0, 0.10, 0.20, 0.25, 0.0, 180, 9.8780, 9.3091), + new Case(122.0, 120.0, 3.0, 0.10, 0.20, 0.25, 0.5, 180, 6.9284, 6.6761) + }; + + for (int i = 0; i < cases.Length; ++i) + { + + // First step: preparing the test values + // Useful dates + DayCounter dc = new Actual360(); + Date today = Date.Today; + Date exerciseDate = today + cases[i].length; + + // Futures values + SimpleQuote F1 = new SimpleQuote(cases[i].F1); + SimpleQuote F2 = new SimpleQuote(cases[i].F2); + + // Risk-free interest rate + double riskFreeRate = cases[i].r; + YieldTermStructure forwardRate = Utilities.flatRate(today, riskFreeRate, dc); + + // Correlation + Quote rho = new SimpleQuote(cases[i].rho); + + // Volatilities + double vol1 = cases[i].sigma1; + double vol2 = cases[i].sigma2; + BlackVolTermStructure volTS1 = Utilities.flatVol(today, vol1, dc); + BlackVolTermStructure volTS2 = Utilities.flatVol(today, vol2, dc); + + // Black-Scholes Processes + // The BlackProcess is the relevant class for futures contracts + BlackProcess stochProcess1 = new BlackProcess(new Handle(F1), + new Handle(forwardRate), + new Handle(volTS1)); + + BlackProcess stochProcess2 = new BlackProcess(new Handle(F2), + new Handle(forwardRate), + new Handle(volTS2)); + + // Creating the pricing engine + IPricingEngine engine = new KirkSpreadOptionEngine(stochProcess1, + stochProcess2, new Handle(rho)); + + // Finally, create the option: + Option.Type type = Option.Type.Call; + double strike = cases[i].X; + PlainVanillaPayoff payoff = new PlainVanillaPayoff(type, strike); + Exercise exercise = new EuropeanExercise(exerciseDate); + + SpreadOption option = new SpreadOption(payoff, exercise); + option.setPricingEngine(engine); + + // And test the data + double value = option.NPV(); + double theta = option.theta(); + double tolerance = 1e-4; + + if (Math.Abs(value - cases[i].value) > tolerance) + { + REPORT_FAILURE("value", + payoff, exercise, + cases[i].value, value, tolerance, today); + } + + if (Math.Abs(theta - cases[i].theta) > tolerance) + { + REPORT_FAILURE("theta", + payoff, exercise, + cases[i].theta, theta, tolerance, today); + } + } + } + } + +} diff --git a/tests/QLNet.Tests/T_Stats.cs b/tests/QLNet.Tests/T_Stats.cs index e2b2ae836..9b7bf2a7a 100644 --- a/tests/QLNet.Tests/T_Stats.cs +++ b/tests/QLNet.Tests/T_Stats.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,7 +22,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -38,9 +38,9 @@ public class T_Stats double[] weights = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 }; #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testStatistics() { @@ -49,9 +49,9 @@ public void testStatistics() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testSequenceStatistics() { @@ -62,9 +62,9 @@ public void testSequenceStatistics() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testConvergenceStatistics() { @@ -76,11 +76,11 @@ public void testConvergenceStatistics() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testIncrementalStatistics() + public void testIncrementalStatistics() { // Testing incremental statistics @@ -88,37 +88,37 @@ public void testIncrementalStatistics() IncrementalStatistics stat = new IncrementalStatistics(); - for ( int i = 0; i < 500000; ++i ) + for (int i = 0; i < 500000; ++i) { - double x = 2.0 * ( mt.nextReal() - 0.5 ) * 1234.0; + double x = 2.0 * (mt.nextReal() - 0.5) * 1234.0; double w = mt.nextReal(); - stat.add( x, w ); + stat.add(x, w); } - if ( stat.samples() != 500000 ) - QAssert.Fail( "stat.samples() (" + stat.samples() + ") can not be reproduced against cached result (" + 500000 + ")" ); + if (stat.samples() != 500000) + QAssert.Fail("stat.samples() (" + stat.samples() + ") can not be reproduced against cached result (" + 500000 + ")"); - TEST_INC_STAT( stat.weightSum(), 2.5003623600676749e+05 ); - TEST_INC_STAT( stat.mean(), 4.9122325964293845e-01 ); - TEST_INC_STAT( stat.variance(), 5.0706503959683329e+05 ); - TEST_INC_STAT( stat.standardDeviation(), 7.1208499464378076e+02 ); - TEST_INC_STAT( stat.errorEstimate(), 1.0070402569876076e+00 ); - TEST_INC_STAT( stat.skewness(), -1.7360169326720038e-03 ); - TEST_INC_STAT( stat.kurtosis(), -1.1990742562085395e+00 ); - TEST_INC_STAT( stat.min(), -1.2339945045639761e+03 ); - TEST_INC_STAT( stat.max(), 1.2339958308008499e+03 ); - TEST_INC_STAT( stat.downsideVariance(), 5.0786776146975247e+05 ); - TEST_INC_STAT( stat.downsideDeviation(), 7.1264841364431061e+02 ); + TEST_INC_STAT(stat.weightSum(), 2.5003623600676749e+05); + TEST_INC_STAT(stat.mean(), 4.9122325964293845e-01); + TEST_INC_STAT(stat.variance(), 5.0706503959683329e+05); + TEST_INC_STAT(stat.standardDeviation(), 7.1208499464378076e+02); + TEST_INC_STAT(stat.errorEstimate(), 1.0070402569876076e+00); + TEST_INC_STAT(stat.skewness(), -1.7360169326720038e-03); + TEST_INC_STAT(stat.kurtosis(), -1.1990742562085395e+00); + TEST_INC_STAT(stat.min(), -1.2339945045639761e+03); + TEST_INC_STAT(stat.max(), 1.2339958308008499e+03); + TEST_INC_STAT(stat.downsideVariance(), 5.0786776146975247e+05); + TEST_INC_STAT(stat.downsideDeviation(), 7.1264841364431061e+02); // This is a test for numerical stability, actual implementation fails - //InverseCumulativeRng normal_gen = + //InverseCumulativeRng normal_gen = // new InverseCumulativeRng(mt); //IncrementalStatistics stat2 = new IncrementalStatistics(); - //for (int i = 0; i < 500000; ++i) + //for (int i = 0; i < 500000; ++i) //{ // double x = normal_gen.next().value * 1E-1 + 1E8; // double w = 1.0; @@ -134,11 +134,11 @@ public void testIncrementalStatistics() public void TEST_INC_STAT(double expr, double expected) { - if (!Utils.close_enough(expr, expected)) - QAssert.Fail( " (" + expr + ") can not be reproduced against cached result ("+ expected + ")"); - - } - void check(string name) where S : IGeneralStatistics, new() + if (!Utils.close_enough(expr, expected)) + QAssert.Fail(" (" + expr + ") can not be reproduced against cached result (" + expected + ")"); + + } + void check(string name) where S : IGeneralStatistics, new () { S s = FastActivator.Create(); @@ -150,68 +150,68 @@ public void TEST_INC_STAT(double expr, double expected) if (s.samples() != data.Length) QAssert.Fail(name + ": wrong number of samples\n" - + " calculated: " + s.samples() + "\n" - + " expected: " + data.Length); + + " calculated: " + s.samples() + "\n" + + " expected: " + data.Length); expected = weights.Sum(); calculated = s.weightSum(); if (calculated != expected) QAssert.Fail(name + ": wrong sum of weights\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected); + + " calculated: " + calculated + "\n" + + " expected: " + expected); expected = data.Min(); calculated = s.min(); if (calculated != expected) QAssert.Fail(name + ": wrong minimum value\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected); + + " calculated: " + calculated + "\n" + + " expected: " + expected); expected = data.Max(); calculated = s.max(); if (calculated != expected) QAssert.Fail(name + ": wrong maximum value\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected); + + " calculated: " + calculated + "\n" + + " expected: " + expected); expected = 4.3; tolerance = 1.0e-9; calculated = s.mean(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail(name + ": wrong mean value\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected); + + " calculated: " + calculated + "\n" + + " expected: " + expected); expected = 2.23333333333; calculated = s.variance(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail(name + ": wrong variance\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected); + + " calculated: " + calculated + "\n" + + " expected: " + expected); expected = 1.4944341181; calculated = s.standardDeviation(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail(name + ": wrong standard deviation\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected); + + " calculated: " + calculated + "\n" + + " expected: " + expected); expected = 0.359543071407; calculated = s.skewness(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail(name + ": wrong skewness\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected); + + " calculated: " + calculated + "\n" + + " expected: " + expected); expected = -0.151799637209; calculated = s.kurtosis(); if (Math.Abs(calculated - expected) > tolerance) QAssert.Fail(name + ": wrong kurtosis\n" - + " calculated: " + calculated + "\n" - + " expected: " + expected); + + " calculated: " + calculated + "\n" + + " expected: " + expected); } - void checkSequence(string name, int dimension) where S : IGeneralStatistics, new() + void checkSequence(string name, int dimension) where S : IGeneralStatistics, new () { GenericSequenceStatistics ss = new GenericSequenceStatistics(dimension); @@ -227,16 +227,16 @@ public void TEST_INC_STAT(double expr, double expected) if (ss.samples() != data.Length) QAssert.Fail("SequenceStatistics<" + name + ">: " - + "wrong number of samples\n" - + " calculated: " + ss.samples() + "\n" - + " expected: " + data.Length); + + "wrong number of samples\n" + + " calculated: " + ss.samples() + "\n" + + " expected: " + data.Length); expected = weights.Sum(); if (ss.weightSum() != expected) QAssert.Fail("SequenceStatistics<" + name + ">: " - + "wrong sum of weights\n" - + " calculated: " + ss.weightSum() + "\n" - + " expected: " + expected); + + "wrong sum of weights\n" + + " calculated: " + ss.weightSum() + "\n" + + " expected: " + expected); expected = data.Min(); calculated = ss.min(); @@ -244,10 +244,10 @@ public void TEST_INC_STAT(double expr, double expected) { if (calculated[i] != expected) QAssert.Fail("SequenceStatistics<" + name + ">: " - + (i + 1) + " dimension: " - + "wrong minimum value\n" - + " calculated: " + calculated[i] + "\n" - + " expected: " + expected); + + (i + 1) + " dimension: " + + "wrong minimum value\n" + + " calculated: " + calculated[i] + "\n" + + " expected: " + expected); } expected = data.Max(); @@ -256,10 +256,10 @@ public void TEST_INC_STAT(double expr, double expected) { if (calculated[i] != expected) QAssert.Fail("SequenceStatistics<" + name + ">: " - + (i + 1) + " dimension: " - + "wrong maximun value\n" - + " calculated: " + calculated[i] + "\n" - + " expected: " + expected); + + (i + 1) + " dimension: " + + "wrong maximun value\n" + + " calculated: " + calculated[i] + "\n" + + " expected: " + expected); } expected = 4.3; @@ -269,10 +269,10 @@ public void TEST_INC_STAT(double expr, double expected) { if (Math.Abs(calculated[i] - expected) > tolerance) QAssert.Fail("SequenceStatistics<" + name + ">: " - + (i + 1) + " dimension: " - + "wrong mean value\n" - + " calculated: " + calculated[i] + "\n" - + " expected: " + expected); + + (i + 1) + " dimension: " + + "wrong mean value\n" + + " calculated: " + calculated[i] + "\n" + + " expected: " + expected); } expected = 2.23333333333; @@ -281,10 +281,10 @@ public void TEST_INC_STAT(double expr, double expected) { if (Math.Abs(calculated[i] - expected) > tolerance) QAssert.Fail("SequenceStatistics<" + name + ">: " - + (i + 1) + " dimension: " - + "wrong variance\n" - + " calculated: " + calculated[i] + "\n" - + " expected: " + expected); + + (i + 1) + " dimension: " + + "wrong variance\n" + + " calculated: " + calculated[i] + "\n" + + " expected: " + expected); } expected = 1.4944341181; @@ -293,10 +293,10 @@ public void TEST_INC_STAT(double expr, double expected) { if (Math.Abs(calculated[i] - expected) > tolerance) QAssert.Fail("SequenceStatistics<" + name + ">: " - + (i + 1) + " dimension: " - + "wrong standard deviation\n" - + " calculated: " + calculated[i] + "\n" - + " expected: " + expected); + + (i + 1) + " dimension: " + + "wrong standard deviation\n" + + " calculated: " + calculated[i] + "\n" + + " expected: " + expected); } expected = 0.359543071407; @@ -305,10 +305,10 @@ public void TEST_INC_STAT(double expr, double expected) { if (Math.Abs(calculated[i] - expected) > tolerance) QAssert.Fail("SequenceStatistics<" + name + ">: " - + (i + 1) + " dimension: " - + "wrong skewness\n" - + " calculated: " + calculated[i] + "\n" - + " expected: " + expected); + + (i + 1) + " dimension: " + + "wrong skewness\n" + + " calculated: " + calculated[i] + "\n" + + " expected: " + expected); } expected = -0.151799637209; @@ -317,14 +317,14 @@ public void TEST_INC_STAT(double expr, double expected) { if (Math.Abs(calculated[i] - expected) > tolerance) QAssert.Fail("SequenceStatistics<" + name + ">: " - + (i + 1) + " dimension: " - + "wrong kurtosis\n" - + " calculated: " + calculated[i] + "\n" - + " expected: " + expected); + + (i + 1) + " dimension: " + + "wrong kurtosis\n" + + " calculated: " + calculated[i] + "\n" + + " expected: " + expected); } } - void checkConvergence(string name) where S : IGeneralStatistics, new() + void checkConvergence(string name) where S : IGeneralStatistics, new () { ConvergenceStatistics stats = new ConvergenceStatistics(); @@ -342,24 +342,24 @@ public void TEST_INC_STAT(double expr, double expected) int calculatedSize = stats.convergenceTable().Count; if (calculatedSize != expectedSize1) QAssert.Fail("ConvergenceStatistics<" + name + ">: " - + "\nwrong convergence-table size" - + "\n calculated: " + calculatedSize - + "\n expected: " + expectedSize1); + + "\nwrong convergence-table size" + + "\n calculated: " + calculatedSize + + "\n expected: " + expectedSize1); const double expectedValue1 = 4.0; const double tolerance = 1.0e-9; double calculatedValue = stats.convergenceTable().Last().Value; if (Math.Abs(calculatedValue - expectedValue1) > tolerance) QAssert.Fail("wrong last value in convergence table" - + "\n calculated: " + calculatedValue - + "\n expected: " + expectedValue1); + + "\n calculated: " + calculatedValue + + "\n expected: " + expectedValue1); const int expectedSampleSize1 = 7; int calculatedSamples = stats.convergenceTable().Last().Key; if (calculatedSamples != expectedSampleSize1) QAssert.Fail("wrong number of samples in convergence table" - + "\n calculated: " + calculatedSamples - + "\n expected: " + expectedSampleSize1); + + "\n calculated: " + calculatedSamples + + "\n expected: " + expectedSampleSize1); stats.reset(); stats.add(1.0); @@ -371,22 +371,22 @@ public void TEST_INC_STAT(double expr, double expected) calculatedSize = stats.convergenceTable().Count; if (calculatedSize != expectedSize2) QAssert.Fail("wrong convergence-table size" - + "\n calculated: " + calculatedSize - + "\n expected: " + expectedSize2); + + "\n calculated: " + calculatedSize + + "\n expected: " + expectedSize2); const double expectedValue2 = 2.0; calculatedValue = stats.convergenceTable().Last().Value; if (Math.Abs(calculatedValue - expectedValue2) > tolerance) QAssert.Fail("wrong last value in convergence table" - + "\n calculated: " + calculatedValue - + "\n expected: " + expectedValue2); + + "\n calculated: " + calculatedValue + + "\n expected: " + expectedValue2); const int expectedSampleSize2 = 3; calculatedSamples = stats.convergenceTable().Last().Key; if (calculatedSamples != expectedSampleSize2) QAssert.Fail("wrong number of samples in convergence table" - + "\n calculated: " + calculatedSamples - + "\n expected: " + expectedSampleSize2); + + "\n calculated: " + calculatedSamples + + "\n expected: " + expectedSampleSize2); } } } diff --git a/tests/QLNet.Tests/T_Swaps.cs b/tests/QLNet.Tests/T_Swaps.cs index 268e74bbb..328c8be93 100644 --- a/tests/QLNet.Tests/T_Swaps.cs +++ b/tests/QLNet.Tests/T_Swaps.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -22,7 +22,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -35,19 +35,19 @@ public class T_Swaps : IDisposable { #region Initialize&Cleanup private SavedSettings backup; - #if NET40 || NET45 +#if NET40 || NET45 [TestInitialize] public void testInitialize() { - #else +#else public T_Swaps() { - #endif +#endif backup = new SavedSettings(); } - #if NET40 || NET45 +#if NET40 || NET45 [TestCleanup] - #endif +#endif public void testCleanup() { Dispose(); @@ -77,9 +77,9 @@ public VanillaSwap makeSwap(int length, double fixedRate, double floatingSpread) { Date maturity = calendar.advance(settlement, length, TimeUnit.Years, floatingConvention); Schedule fixedSchedule = new Schedule(settlement, maturity, new Period(fixedFrequency), - calendar, fixedConvention, fixedConvention, DateGeneration.Rule.Forward, false); + calendar, fixedConvention, fixedConvention, DateGeneration.Rule.Forward, false); Schedule floatSchedule = new Schedule(settlement, maturity, new Period(floatingFrequency), - calendar, floatingConvention, floatingConvention, DateGeneration.Rule.Forward, false); + calendar, floatingConvention, floatingConvention, DateGeneration.Rule.Forward, false); VanillaSwap swap = new VanillaSwap(type, nominal, fixedSchedule, fixedRate, fixedDayCount, floatSchedule, index, floatingSpread, index.dayCounter()); swap.setPricingEngine(new DiscountingSwapEngine(termStructure)); @@ -109,9 +109,9 @@ public CommonVars() } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testFairRate() { @@ -132,18 +132,18 @@ public void testFairRate() if (Math.Abs(swap.NPV()) > 1.0e-10) { QAssert.Fail("recalculating with implied rate:\n" - + " length: " + lengths[i] + " years\n" - + " floating spread: " - + spreads[j] + "\n" - + " swap value: " + swap.NPV()); + + " length: " + lengths[i] + " years\n" + + " floating spread: " + + spreads[j] + "\n" + + " swap value: " + swap.NPV()); } } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testFairSpread() { @@ -163,18 +163,18 @@ public void testFairSpread() if (Math.Abs(swap.NPV()) > 1.0e-10) { QAssert.Fail("recalculating with implied spread:\n" - + " length: " + lengths[i] + " years\n" - + " fixed rate: " - + rates[j] + "\n" - + " swap value: " + swap.NPV()); + + " length: " + lengths[i] + " years\n" + + " fixed rate: " + + rates[j] + "\n" + + " swap value: " + swap.NPV()); } } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testRateDependency() { @@ -203,20 +203,20 @@ public void testRateDependency() { if (swap_values[z] < swap_values[z + 1]) QAssert.Fail( - "NPV is increasing with the fixed rate in a swap: \n" - + " length: " + lengths[i] + " years\n" - + " value: " + swap_values[z] - + " paying fixed rate: " + rates[z] + "\n" - + " value: " + swap_values[z + 1] - + " paying fixed rate: " + rates[z + 1]); + "NPV is increasing with the fixed rate in a swap: \n" + + " length: " + lengths[i] + " years\n" + + " value: " + swap_values[z] + + " paying fixed rate: " + rates[z] + "\n" + + " value: " + swap_values[z + 1] + + " paying fixed rate: " + rates[z + 1]); } } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testSpreadDependency() { @@ -245,20 +245,20 @@ public void testSpreadDependency() { if (swap_values[z] > swap_values[z + 1]) QAssert.Fail( - "NPV is decreasing with the floating spread in a swap: \n" - + " length: " + lengths[i] + " years\n" - + " value: " + swap_values[z] - + " receiving spread: " + rates[z] + "\n" - + " value: " + swap_values[z + 1] - + " receiving spread: " + rates[z + 1]); + "NPV is decreasing with the floating spread in a swap: \n" + + " length: " + lengths[i] + " years\n" + + " value: " + swap_values[z] + + " receiving spread: " + rates[z] + "\n" + + " value: " + swap_values[z + 1] + + " receiving spread: " + rates[z + 1]); } } } } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testInArrears() { @@ -284,8 +284,8 @@ public void testInArrears() List coupons = new List() { oneYear }; List fixedLeg = new FixedRateLeg(schedule) - .withCouponRates(coupons, dayCounter) - .withNotionals(nominals); + .withCouponRates(coupons, dayCounter) + .withNotionals(nominals); List gearings = new List(); List spreads = new List(); @@ -293,17 +293,17 @@ public void testInArrears() double capletVolatility = 0.22; var vol = new Handle( - new ConstantOptionletVolatility(vars.today, new NullCalendar(), - BusinessDayConvention.Following, capletVolatility, dayCounter)); + new ConstantOptionletVolatility(vars.today, new NullCalendar(), + BusinessDayConvention.Following, capletVolatility, dayCounter)); IborCouponPricer pricer = new BlackIborCouponPricer(vol); List floatingLeg = new IborLeg(schedule, index) - .withPaymentDayCounter(dayCounter) - .withFixingDays(fixingDays) - .withGearings(gearings) - .withSpreads(spreads) - .inArrears() - .withNotionals(nominals); + .withPaymentDayCounter(dayCounter) + .withFixingDays(fixingDays) + .withGearings(gearings) + .withSpreads(spreads) + .inArrears() + .withNotionals(nominals); Utils.setCouponPricer(floatingLeg, pricer); Swap swap = new Swap(floatingLeg, fixedLeg); @@ -314,13 +314,13 @@ public void testInArrears() if (Math.Abs(swap.NPV() - storedValue) > tolerance) QAssert.Fail("Wrong NPV calculation:\n" - + " expected: " + storedValue + "\n" - + " calculated: " + swap.NPV()); + + " expected: " + storedValue + "\n" + + " calculated: " + swap.NPV()); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testCachedValue() { @@ -334,66 +334,66 @@ public void testCachedValue() VanillaSwap swap = vars.makeSwap(10, 0.06, 0.001); #if QL_USE_INDEXED_COUPON - double cachedNPV = -5.872342992212; + double cachedNPV = -5.872342992212; #else double cachedNPV = -5.872863313209; #endif if (Math.Abs(swap.NPV() - cachedNPV) > 1.0e-11) QAssert.Fail("failed to reproduce cached swap value:\n" - + " calculated: " + swap.NPV() + "\n" - + " expected: " + cachedNPV); + + " calculated: " + swap.NPV() + "\n" + + " expected: " + cachedNPV); } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif public void testFixing() { - Date tradeDate = new Date( 17, Month.April, 2015 ); + Date tradeDate = new Date(17, Month.April, 2015); Calendar calendar = new UnitedKingdom(); - Date settlementDate = calendar.advance( tradeDate, 2, TimeUnit.Days, BusinessDayConvention.Following ); - Date maturityDate = calendar.advance( settlementDate, 5, TimeUnit.Years, BusinessDayConvention.Following ); + Date settlementDate = calendar.advance(tradeDate, 2, TimeUnit.Days, BusinessDayConvention.Following); + Date maturityDate = calendar.advance(settlementDate, 5, TimeUnit.Years, BusinessDayConvention.Following); - Date valueDate = new Date( 20, Month.April, 2015 ); - Settings.setEvaluationDate( valueDate ); + Date valueDate = new Date(20, Month.April, 2015); + Settings.setEvaluationDate(valueDate); List dates = new List(); - dates.Add( valueDate ); - dates.Add( valueDate + new Period( 1, TimeUnit.Years ) ); - dates.Add( valueDate + new Period( 2, TimeUnit.Years ) ); - dates.Add( valueDate + new Period( 5, TimeUnit.Years ) ); - dates.Add( valueDate + new Period( 10, TimeUnit.Years ) ); - dates.Add( valueDate + new Period( 20, TimeUnit.Years ) ); + dates.Add(valueDate); + dates.Add(valueDate + new Period(1, TimeUnit.Years)); + dates.Add(valueDate + new Period(2, TimeUnit.Years)); + dates.Add(valueDate + new Period(5, TimeUnit.Years)); + dates.Add(valueDate + new Period(10, TimeUnit.Years)); + dates.Add(valueDate + new Period(20, TimeUnit.Years)); List rates = new List(); - rates.Add( 0.01 ); - rates.Add( 0.01 ); - rates.Add( 0.01 ); - rates.Add( 0.01 ); - rates.Add( 0.01 ); - rates.Add( 0.01 ); + rates.Add(0.01); + rates.Add(0.01); + rates.Add(0.01); + rates.Add(0.01); + rates.Add(0.01); + rates.Add(0.01); var discountCurveHandle = new RelinkableHandle(); var forecastCurveHandle = new RelinkableHandle(); - GBPLibor index = new GBPLibor( new Period( 6, TimeUnit.Months ), forecastCurveHandle ); - InterpolatedZeroCurve zeroCurve = new InterpolatedZeroCurve( dates, rates, new Actual360(), new Linear() ); - var fixedSchedule = new Schedule( settlementDate, maturityDate, new Period( 1, TimeUnit.Years ), calendar, BusinessDayConvention.Following, BusinessDayConvention.Following, DateGeneration.Rule.Forward, false ); - var floatSchedule = new Schedule( settlementDate, maturityDate, index.tenor(), calendar, BusinessDayConvention.Following, BusinessDayConvention.Following, DateGeneration.Rule.Forward, false ); - VanillaSwap swap = new VanillaSwap( VanillaSwap.Type.Payer, 1000000, fixedSchedule, 0.01, new Actual360(), floatSchedule, index, 0, new Actual360() ); - discountCurveHandle.linkTo( zeroCurve ); - forecastCurveHandle.linkTo( zeroCurve ); - var swapEngine = new DiscountingSwapEngine( discountCurveHandle, false, null ); - swap.setPricingEngine( swapEngine ); + GBPLibor index = new GBPLibor(new Period(6, TimeUnit.Months), forecastCurveHandle); + InterpolatedZeroCurve zeroCurve = new InterpolatedZeroCurve(dates, rates, new Actual360(), new Linear()); + var fixedSchedule = new Schedule(settlementDate, maturityDate, new Period(1, TimeUnit.Years), calendar, BusinessDayConvention.Following, BusinessDayConvention.Following, DateGeneration.Rule.Forward, false); + var floatSchedule = new Schedule(settlementDate, maturityDate, index.tenor(), calendar, BusinessDayConvention.Following, BusinessDayConvention.Following, DateGeneration.Rule.Forward, false); + VanillaSwap swap = new VanillaSwap(VanillaSwap.Type.Payer, 1000000, fixedSchedule, 0.01, new Actual360(), floatSchedule, index, 0, new Actual360()); + discountCurveHandle.linkTo(zeroCurve); + forecastCurveHandle.linkTo(zeroCurve); + var swapEngine = new DiscountingSwapEngine(discountCurveHandle, false, null); + swap.setPricingEngine(swapEngine); try { double npv = swap.NPV(); } - catch ( Exception ex ) + catch (Exception ex) { - QAssert.Fail( ex.Message ); + QAssert.Fail(ex.Message); } } diff --git a/tests/QLNet.Tests/T_Swaption.cs b/tests/QLNet.Tests/T_Swaption.cs index c1c1d59df..5cfc56331 100644 --- a/tests/QLNet.Tests/T_Swaption.cs +++ b/tests/QLNet.Tests/T_Swaption.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -21,7 +21,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -31,161 +31,169 @@ namespace TestSuite [TestClass()] #endif public class T_Swaption : IDisposable - { - #region Initialize&Cleanup - private SavedSettings backup; - #if NET40 || NET45 - [TestInitialize] - public void testInitialize() - { - #else - public T_Swaption() - { - #endif - backup = new SavedSettings(); - } - #if NET40 || NET45 - [TestCleanup] - #endif - public void testCleanup() - { - Dispose(); - } - public void Dispose() - { - backup.Dispose(); - } - #endregion - - public Period[] exercises = new Period[] { new Period(1, TimeUnit.Years), - new Period(2, TimeUnit.Years), - new Period(3, TimeUnit.Years), - new Period(5, TimeUnit.Years), - new Period(7, TimeUnit.Years), - new Period(10, TimeUnit.Years) }; - - public Period[] lengths = new Period[] { new Period(1, TimeUnit.Years), - new Period(2, TimeUnit.Years), - new Period(3, TimeUnit.Years), - new Period(5, TimeUnit.Years), - new Period(7, TimeUnit.Years), - new Period(10, TimeUnit.Years), - new Period(15, TimeUnit.Years), - new Period(20, TimeUnit.Years) }; - - public VanillaSwap.Type[] type = new VanillaSwap.Type[] { VanillaSwap.Type.Receiver, VanillaSwap.Type.Payer }; - - - public class CommonVars - { - // global data - public Date today, settlement; - public double nominal; - public Calendar calendar; - public BusinessDayConvention fixedConvention, floatingConvention; - public Frequency fixedFrequency; - public DayCounter fixedDayCount; - public Period floatingTenor; - public IborIndex index; - public int settlementDays; - public RelinkableHandle termStructure = new RelinkableHandle(); - - // utilities - public Swaption makeSwaption(VanillaSwap swap,Date exercise,double volatility, - Settlement.Type settlementType = Settlement.Type.Physical, - BlackStyleSwaptionEngine.CashAnnuityModel model = BlackStyleSwaptionEngine.CashAnnuityModel.SwapRate) - { - Handle vol=new Handle (new SimpleQuote(volatility)); - IPricingEngine engine = new BlackSwaptionEngine(termStructure, vol, new Actual365Fixed(), 0.0, model); - Swaption result=new Swaption(swap,new EuropeanExercise(exercise),settlementType); - result.setPricingEngine(engine); - return result; - } - - public IPricingEngine makeEngine(double volatility, - BlackStyleSwaptionEngine.CashAnnuityModel model = BlackStyleSwaptionEngine.CashAnnuityModel.SwapRate) - { - Handle h = new Handle < Quote >( new SimpleQuote(volatility)); - return (IPricingEngine)(new BlackSwaptionEngine(termStructure, h, new Actual365Fixed(), 0.0, model)); - } - - public CommonVars() - { - settlementDays = 2; - nominal = 1000000.0; - fixedConvention = BusinessDayConvention.Unadjusted; - - fixedFrequency = Frequency.Annual; - fixedDayCount = new Thirty360(); - - index =new Euribor6M(termStructure); - floatingConvention = index.businessDayConvention(); - floatingTenor = index.tenor(); - calendar = index.fixingCalendar(); - today = calendar.adjust(Date.Today); - Settings.setEvaluationDate(today); - settlement = calendar.advance(today, settlementDays, TimeUnit.Days); - - termStructure.linkTo(Utilities.flatRate(settlement, 0.05, new Actual365Fixed())); - } - } + { + #region Initialize&Cleanup + private SavedSettings backup; +#if NET40 || NET45 + [TestInitialize] + public void testInitialize() + { +#else + public T_Swaption() + { +#endif + backup = new SavedSettings(); + } +#if NET40 || NET45 + [TestCleanup] +#endif + public void testCleanup() + { + Dispose(); + } + public void Dispose() + { + backup.Dispose(); + } + #endregion + + public Period[] exercises = new Period[] { new Period(1, TimeUnit.Years), + new Period(2, TimeUnit.Years), + new Period(3, TimeUnit.Years), + new Period(5, TimeUnit.Years), + new Period(7, TimeUnit.Years), + new Period(10, TimeUnit.Years) + }; + + public Period[] lengths = new Period[] { new Period(1, TimeUnit.Years), + new Period(2, TimeUnit.Years), + new Period(3, TimeUnit.Years), + new Period(5, TimeUnit.Years), + new Period(7, TimeUnit.Years), + new Period(10, TimeUnit.Years), + new Period(15, TimeUnit.Years), + new Period(20, TimeUnit.Years) + }; + + public VanillaSwap.Type[] type = new VanillaSwap.Type[] { VanillaSwap.Type.Receiver, VanillaSwap.Type.Payer }; + + + public class CommonVars + { + // global data + public Date today, settlement; + public double nominal; + public Calendar calendar; + public BusinessDayConvention fixedConvention, floatingConvention; + public Frequency fixedFrequency; + public DayCounter fixedDayCount; + public Period floatingTenor; + public IborIndex index; + public int settlementDays; + public RelinkableHandle termStructure = new RelinkableHandle(); + + // utilities + public Swaption makeSwaption(VanillaSwap swap, Date exercise, double volatility, + Settlement.Type settlementType = Settlement.Type.Physical, + BlackStyleSwaptionEngine.CashAnnuityModel model = BlackStyleSwaptionEngine.CashAnnuityModel.SwapRate) + { + Handle vol = new Handle (new SimpleQuote(volatility)); + IPricingEngine engine = new BlackSwaptionEngine(termStructure, vol, new Actual365Fixed(), 0.0, model); + Swaption result = new Swaption(swap, new EuropeanExercise(exercise), settlementType); + result.setPricingEngine(engine); + return result; + } + + public IPricingEngine makeEngine(double volatility, + BlackStyleSwaptionEngine.CashAnnuityModel model = BlackStyleSwaptionEngine.CashAnnuityModel.SwapRate) + { + Handle h = new Handle < Quote >(new SimpleQuote(volatility)); + return (IPricingEngine)(new BlackSwaptionEngine(termStructure, h, new Actual365Fixed(), 0.0, model)); + } + + public CommonVars() + { + settlementDays = 2; + nominal = 1000000.0; + fixedConvention = BusinessDayConvention.Unadjusted; + + fixedFrequency = Frequency.Annual; + fixedDayCount = new Thirty360(); + + index = new Euribor6M(termStructure); + floatingConvention = index.businessDayConvention(); + floatingTenor = index.tenor(); + calendar = index.fixingCalendar(); + today = calendar.adjust(Date.Today); + Settings.setEvaluationDate(today); + settlement = calendar.advance(today, settlementDays, TimeUnit.Days); + + termStructure.linkTo(Utilities.flatRate(settlement, 0.05, new Actual365Fixed())); + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testStrikeDependency() - { - // Testing swaption dependency on strike - CommonVars vars = new CommonVars(); - double[] strikes = new double[] { 0.03, 0.04, 0.05, 0.06, 0.07 }; - - for (int i = 0; i < exercises.Length; i++) { - for (int j = 0; j < lengths.Length; j++) { - for (int k=0; k < type.Length ; k++) { - Date exerciseDate = vars.calendar.advance(vars.today, - exercises[i]); - Date startDate = vars.calendar.advance(exerciseDate, - vars.settlementDays, TimeUnit.Days); - // store the results for different rates... - List values = new InitializedList(strikes.Length); - List values_cash = new InitializedList(strikes.Length); - double vol = 0.20; - - for (int l=0; l< strikes.Length ; l++) { - VanillaSwap swap = new MakeVanillaSwap(lengths[j], vars.index, strikes[l]) - .withEffectiveDate(startDate) - .withFloatingLegSpread(0.0) - .withType(type[k]); - Swaption swaption = vars.makeSwaption(swap,exerciseDate,vol); - // FLOATING_POINT_EXCEPTION - values[l]=swaption.NPV(); - Swaption swaption_cash = vars.makeSwaption( swap,exerciseDate,vol, - Settlement.Type.Cash); - values_cash[l]=swaption_cash.NPV(); + public void testStrikeDependency() + { + // Testing swaption dependency on strike + CommonVars vars = new CommonVars(); + double[] strikes = new double[] { 0.03, 0.04, 0.05, 0.06, 0.07 }; + + for (int i = 0; i < exercises.Length; i++) + { + for (int j = 0; j < lengths.Length; j++) + { + for (int k = 0; k < type.Length ; k++) + { + Date exerciseDate = vars.calendar.advance(vars.today, + exercises[i]); + Date startDate = vars.calendar.advance(exerciseDate, + vars.settlementDays, TimeUnit.Days); + // store the results for different rates... + List values = new InitializedList(strikes.Length); + List values_cash = new InitializedList(strikes.Length); + double vol = 0.20; + + for (int l = 0; l < strikes.Length ; l++) + { + VanillaSwap swap = new MakeVanillaSwap(lengths[j], vars.index, strikes[l]) + .withEffectiveDate(startDate) + .withFloatingLegSpread(0.0) + .withType(type[k]); + Swaption swaption = vars.makeSwaption(swap, exerciseDate, vol); + // FLOATING_POINT_EXCEPTION + values[l] = swaption.NPV(); + Swaption swaption_cash = vars.makeSwaption(swap, exerciseDate, vol, + Settlement.Type.Cash); + values_cash[l] = swaption_cash.NPV(); + } + + // and check that they go the right way + if (type[k] == VanillaSwap.Type.Payer) + { + for (int z = 0; z < values.Count - 1; z++) + { + if (values[z] < values[z + 1]) + { + QAssert.Fail("NPV of Payer swaption with delivery settlement" + + "is increasing with the strike:" + + "\noption tenor: " + exercises[i] + + "\noption date: " + exerciseDate + + "\nvolatility: " + vol + + "\nswap tenor: " + lengths[j] + + "\nvalue: " + values[z ] + " at strike: " + strikes[z ] + + "\nvalue: " + values[z + 1] + " at strike: " + strikes[z + 1]); } - - // and check that they go the right way - if (type[k]==VanillaSwap.Type.Payer) { - for (int z = 0; z < values.Count - 1; z++) - { - if( values[z] values[z+1]){ - QAssert.Fail("NPV of Receiver swaption with delivery settlement" + - "is increasing with the strike:" + - "\noption tenor: " + exercises[i] + - "\noption date: " + exerciseDate + - "\nvolatility: " + vol + - "\nswap tenor: " + lengths[j] + - "\nvalue: " + values[z] + " at strike: " + strikes[z] + - "\nvalue: " + values[z + 1] + " at strike: " + strikes[z + 1]); - } - } - for (int z = 0; z < values_cash.Count - 1; z++) - { - if (values[z] > values[z+1]) - { - QAssert.Fail("NPV of Receiver swaption with cash settlement" + + } + } + else + { + for (int z = 0; z < values.Count - 1; z++) + { + if (values[z] > values[z + 1]) + { + QAssert.Fail("NPV of Receiver swaption with delivery settlement" + + "is increasing with the strike:" + + "\noption tenor: " + exercises[i] + + "\noption date: " + exerciseDate + + "\nvolatility: " + vol + + "\nswap tenor: " + lengths[j] + + "\nvalue: " + values[z] + " at strike: " + strikes[z] + + "\nvalue: " + values[z + 1] + " at strike: " + strikes[z + 1]); + } + } + for (int z = 0; z < values_cash.Count - 1; z++) + { + if (values[z] > values[z + 1]) + { + QAssert.Fail("NPV of Receiver swaption with cash settlement" + "is increasing with the strike:" + "\noption tenor: " + exercises[i] + "\noption date: " + exerciseDate + @@ -221,712 +232,738 @@ public void testStrikeDependency() "\nswap tenor: " + lengths[j] + "\nvalue: " + values_cash[z] + " at strike: " + strikes[z] + "\nvalue: " + values_cash[z + 1] + " at strike: " + strikes[z + 1]); - } - } } - } - } + } + } + } } - } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testSpreadDependency() - { - // Testing swaption dependency on spread - CommonVars vars = new CommonVars(); - - double[] spreads = { -0.002, -0.001, 0.0, 0.001, 0.002 }; - - for (int i=0; i values=new InitializedList(spreads.Length); - List values_cash = new InitializedList(spreads.Length); - for (int l=0; l values[n + 1]) - QAssert.Fail("NPV is decreasing with the spread " + + public void testSpreadDependency() + { + // Testing swaption dependency on spread + CommonVars vars = new CommonVars(); + + double[] spreads = { -0.002, -0.001, 0.0, 0.001, 0.002 }; + + for (int i = 0; i < exercises.Length ; i++) + { + for (int j = 0; j < lengths.Length ; j++) + { + for (int k = 0; k < type.Length ; k++) + { + Date exerciseDate = vars.calendar.advance(vars.today, + exercises[i]); + Date startDate = + vars.calendar.advance(exerciseDate, + vars.settlementDays, TimeUnit.Days); + // store the results for different rates... + List values = new InitializedList(spreads.Length); + List values_cash = new InitializedList(spreads.Length); + for (int l = 0; l < spreads.Length; l++) + { + VanillaSwap swap = + new MakeVanillaSwap(lengths[j], vars.index, 0.06) + .withEffectiveDate(startDate) + .withFloatingLegSpread(spreads[l]) + .withType(type[k]); + Swaption swaption = + vars.makeSwaption(swap, exerciseDate, 0.20); + // FLOATING_POINT_EXCEPTION + values[l] = swaption.NPV(); + Swaption swaption_cash = + vars.makeSwaption(swap, exerciseDate, 0.20, + Settlement.Type.Cash); + values_cash[l] = swaption_cash.NPV(); + } + // and check that they go the right way + if (type[k] == VanillaSwap.Type.Payer) + { + for (int n = 0; n < spreads.Length - 1; n++) + { + if (values[n] > values[n + 1]) + QAssert.Fail("NPV is decreasing with the spread " + "in a payer swaption (physical delivered):" + "\nexercise date: " + exerciseDate + "\nlength: " + lengths[j] + "\nvalue: " + values[n] + " for spread: " + spreads[n] + "\nvalue: " + values[n + 1] + " for spread: " + spreads[n + 1]); - - if (values_cash[n] > values_cash[n + 1]) - QAssert.Fail("NPV is decreasing with the spread " + + + if (values_cash[n] > values_cash[n + 1]) + QAssert.Fail("NPV is decreasing with the spread " + "in a payer swaption (cash delivered):" + "\nexercise date: " + exerciseDate + "\nlength: " + lengths[j] + "\nvalue: " + values_cash[n] + " for spread: " + spreads[n] + "\nvalue: " + values_cash[n + 1] + " for spread: " + spreads[n + 1]); - } - } - else - { - for (int n = 0; n < spreads.Length - 1; n++) - { - if (values[n] < values[n + 1]) - QAssert.Fail("NPV is increasing with the spread " + + } + } + else + { + for (int n = 0; n < spreads.Length - 1; n++) + { + if (values[n] < values[n + 1]) + QAssert.Fail("NPV is increasing with the spread " + "in a receiver swaption (physical delivered):" + "\nexercise date: " + exerciseDate + "\nlength: " + lengths[j] + "\nvalue: " + values[n] + " for spread: " + spreads[n] + "\nvalue: " + values[n + 1] + " for spread: " + spreads[n + 1]); - - if (values_cash[n] < values_cash[n+1]) - QAssert.Fail("NPV is increasing with the spread " + - "in a receiver swaption (cash delivered):" + - "\nexercise date: " + exerciseDate + - "\nlength: " + lengths[j] + - "\nvalue: " + values_cash[n ] + " for spread: " + spreads[n] + - "\nvalue: " + values_cash[n+1] + " for spread: " + spreads[n+1]); - } - } - } - } + + if (values_cash[n] < values_cash[n + 1]) + QAssert.Fail("NPV is increasing with the spread " + + "in a receiver swaption (cash delivered):" + + "\nexercise date: " + exerciseDate + + "\nlength: " + lengths[j] + + "\nvalue: " + values_cash[n ] + " for spread: " + spreads[n] + + "\nvalue: " + values_cash[n + 1] + " for spread: " + spreads[n + 1]); + } + } + } } - } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testSpreadTreatment() - { - // Testing swaption treatment of spread - CommonVars vars = new CommonVars(); - - double[] spreads = { -0.002, -0.001, 0.0, 0.001, 0.002 }; - - for (int i=0; i 1.0e-6) - QAssert.Fail("wrong spread treatment:" + - "\nexercise: " + exerciseDate + - "\nlength: " + lengths[j] + - "\ntype " + type[k] + - "\nspread: " + spreads[l] + - "\noriginal swaption value: " + swaption1.NPV() + - "\nequivalent swaption value: " + swaption2.NPV()); - - if (Math.Abs(swaption1_cash.NPV()-swaption2_cash.NPV()) > 1.0e-6) - QAssert.Fail("wrong spread treatment:" + - "\nexercise date: " + exerciseDate + - "\nlength: " + lengths[j] + - //"\npay " + (type[k] ? "fixed" : "floating") + - "\nspread: " + spreads[l] + - "\nvalue of original swaption: " + swaption1_cash.NPV() + - "\nvalue of equivalent swaption: " + swaption2_cash.NPV()); - } - } - } + public void testSpreadTreatment() + { + // Testing swaption treatment of spread + CommonVars vars = new CommonVars(); + + double[] spreads = { -0.002, -0.001, 0.0, 0.001, 0.002 }; + + for (int i = 0; i < exercises.Length; i++) + { + for (int j = 0; j < lengths.Length ; j++) + { + for (int k = 0; k < type.Length ; k++) + { + Date exerciseDate = vars.calendar.advance(vars.today, + exercises[i]); + Date startDate = + vars.calendar.advance(exerciseDate, + vars.settlementDays, TimeUnit.Days); + for (int l = 0; l < spreads.Length ; l++) + { + VanillaSwap swap = + new MakeVanillaSwap(lengths[j], vars.index, 0.06) + .withEffectiveDate(startDate) + .withFloatingLegSpread(spreads[l]) + .withType(type[k]); + // FLOATING_POINT_EXCEPTION + double correction = spreads[l] * + swap.floatingLegBPS() / + swap.fixedLegBPS(); + VanillaSwap equivalentSwap = + new MakeVanillaSwap(lengths[j], vars.index, 0.06 + correction) + .withEffectiveDate(startDate) + .withFloatingLegSpread(0.0) + .withType(type[k]); + Swaption swaption1 = + vars.makeSwaption(swap, exerciseDate, 0.20); + Swaption swaption2 = + vars.makeSwaption(equivalentSwap, exerciseDate, 0.20); + Swaption swaption1_cash = + vars.makeSwaption(swap, exerciseDate, 0.20, + Settlement.Type.Cash); + Swaption swaption2_cash = + vars.makeSwaption(equivalentSwap, exerciseDate, 0.20, + Settlement.Type.Cash); + if (Math.Abs(swaption1.NPV() - swaption2.NPV()) > 1.0e-6) + QAssert.Fail("wrong spread treatment:" + + "\nexercise: " + exerciseDate + + "\nlength: " + lengths[j] + + "\ntype " + type[k] + + "\nspread: " + spreads[l] + + "\noriginal swaption value: " + swaption1.NPV() + + "\nequivalent swaption value: " + swaption2.NPV()); + + if (Math.Abs(swaption1_cash.NPV() - swaption2_cash.NPV()) > 1.0e-6) + QAssert.Fail("wrong spread treatment:" + + "\nexercise date: " + exerciseDate + + "\nlength: " + lengths[j] + + //"\npay " + (type[k] ? "fixed" : "floating") + + "\nspread: " + spreads[l] + + "\nvalue of original swaption: " + swaption1_cash.NPV() + + "\nvalue of equivalent swaption: " + swaption2_cash.NPV()); + } + } } - } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testCachedValue() - { - // Testing swaption value against cached value - CommonVars vars = new CommonVars(); - - vars.today = new Date(13, 3, 2002); - vars.settlement = new Date(15, 3, 2002); - Settings.setEvaluationDate( vars.today); - vars.termStructure.linkTo(Utilities.flatRate(vars.settlement, 0.05, new Actual365Fixed())); - Date exerciseDate = vars.calendar.advance(vars.settlement, new Period(5,TimeUnit.Years)); - Date startDate = vars.calendar.advance(exerciseDate, - vars.settlementDays,TimeUnit.Days); - VanillaSwap swap = - new MakeVanillaSwap(new Period(10,TimeUnit.Years), vars.index, 0.06) - .withEffectiveDate(startDate); - - Swaption swaption = - vars.makeSwaption(swap, exerciseDate, 0.20); - //#if QL_USE_INDEXED_COUPON - double cachedNPV = 0.036418158579; - //#else - // double cachedNPV = 0.036421429684; - //#endif - - // FLOATING_POINT_EXCEPTION - if (Math.Abs(swaption.NPV()-cachedNPV) > 1.0e-12) - QAssert.Fail ("failed to reproduce cached swaption value:\n" + - //QL_FIXED + std::setprecision(12) + - "\ncalculated: " + swaption.NPV() + - "\nexpected: " + cachedNPV); - } + public void testCachedValue() + { + // Testing swaption value against cached value + CommonVars vars = new CommonVars(); + + vars.today = new Date(13, 3, 2002); + vars.settlement = new Date(15, 3, 2002); + Settings.setEvaluationDate(vars.today); + vars.termStructure.linkTo(Utilities.flatRate(vars.settlement, 0.05, new Actual365Fixed())); + Date exerciseDate = vars.calendar.advance(vars.settlement, new Period(5, TimeUnit.Years)); + Date startDate = vars.calendar.advance(exerciseDate, + vars.settlementDays, TimeUnit.Days); + VanillaSwap swap = + new MakeVanillaSwap(new Period(10, TimeUnit.Years), vars.index, 0.06) + .withEffectiveDate(startDate); + + Swaption swaption = + vars.makeSwaption(swap, exerciseDate, 0.20); + //#if QL_USE_INDEXED_COUPON + double cachedNPV = 0.036418158579; + //#else + // double cachedNPV = 0.036421429684; + //#endif + + // FLOATING_POINT_EXCEPTION + if (Math.Abs(swaption.NPV() - cachedNPV) > 1.0e-12) + QAssert.Fail("failed to reproduce cached swaption value:\n" + + //QL_FIXED + std::setprecision(12) + + "\ncalculated: " + swaption.NPV() + + "\nexpected: " + cachedNPV); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testVega() - { - // Testing swaption vega - CommonVars vars = new CommonVars(); - - Settlement.Type[] types = { Settlement.Type.Physical, Settlement.Type.Cash }; - double[] strikes = { 0.03, 0.04, 0.05, 0.06, 0.07 }; - double[] vols = { 0.01, 0.20, 0.30, 0.70, 0.90 }; - double shift = 1e-8; - for (int i=0; i1.0e-7) { - double analyticalVegaPerPoint = - (double)swaption.result("vega")/100.0; - double discrepancy = Math.Abs(analyticalVegaPerPoint - - numericalVegaPerPoint); - discrepancy /= numericalVegaPerPoint; - double tolerance = 0.015; - if (discrepancy > tolerance) - QAssert.Fail ("failed to compute swaption vega:" + - "\n option tenor: " + exercises[i] + - "\n volatility: " + vols[u] + - "\n option type: " + swaption.type() + - "\n swap tenor: " + lengths[j] + - "\n strike: " + strikes[t] + - "\n settlement: " + types[h] + - "\n nominal: " + swaption.underlyingSwap().nominal + - "\n npv: " + swaptionNPV + - "\n calculated vega: " + analyticalVegaPerPoint + - "\n expected vega: " + numericalVegaPerPoint + - "\n discrepancy: " + discrepancy + - "\n tolerance: " + tolerance); - } - } + for (int j = 0; j < lengths.Length ; j++) + { + for (int t = 0; t < strikes.Length ; t++) + { + for (int h = 0; h < type.Length ; h++) + { + VanillaSwap swap = + new MakeVanillaSwap(lengths[j], vars.index, strikes[t]) + .withEffectiveDate(startDate) + .withFloatingLegSpread(0.0) + .withType(type[h]); + for (int u = 0; u < vols.Length ; u++) + { + Swaption swaption = + vars.makeSwaption(swap, exerciseDate, + vols[u], types[h]); + // FLOATING_POINT_EXCEPTION + Swaption swaption1 = + vars.makeSwaption(swap, exerciseDate, + vols[u] - shift, types[h]); + Swaption swaption2 = + vars.makeSwaption(swap, exerciseDate, + vols[u] + shift, types[h]); + + double swaptionNPV = swaption.NPV(); + double numericalVegaPerPoint = + (swaption2.NPV() - swaption1.NPV()) / (200.0 * shift); + // check only relevant vega + if (numericalVegaPerPoint / swaptionNPV > 1.0e-7) + { + double analyticalVegaPerPoint = + (double)swaption.result("vega") / 100.0; + double discrepancy = Math.Abs(analyticalVegaPerPoint + - numericalVegaPerPoint); + discrepancy /= numericalVegaPerPoint; + double tolerance = 0.015; + if (discrepancy > tolerance) + QAssert.Fail("failed to compute swaption vega:" + + "\n option tenor: " + exercises[i] + + "\n volatility: " + vols[u] + + "\n option type: " + swaption.type() + + "\n swap tenor: " + lengths[j] + + "\n strike: " + strikes[t] + + "\n settlement: " + types[h] + + "\n nominal: " + swaption.underlyingSwap().nominal + + "\n npv: " + swaptionNPV + + "\n calculated vega: " + analyticalVegaPerPoint + + "\n expected vega: " + numericalVegaPerPoint + + "\n discrepancy: " + discrepancy + + "\n tolerance: " + tolerance); } - } - } + } + } + } } - } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testCashSettledSwaptions() { - - CommonVars vars = new CommonVars(); - - double strike = 0.05; - - for (int i=0; i swapFixedLeg_u360 = swap_u360.fixedLeg(); - List swapFixedLeg_a360 = swap_a360.fixedLeg(); - List swapFixedLeg_u365 = swap_u365.fixedLeg(); - List swapFixedLeg_a365 = swap_a365.fixedLeg(); - - // FlatForward curves - // FLOATING_POINT_EXCEPTION - Handle termStructure_u360 = new Handle( - new FlatForward(vars.settlement,swap_u360.fairRate(), - new Thirty360(),Compounding.Compounded, - vars.fixedFrequency)); - Handle termStructure_a360 = new Handle( - new FlatForward(vars.settlement,swap_a360.fairRate(), - new Thirty360(),Compounding.Compounded, - vars.fixedFrequency)); - Handle termStructure_u365 = new Handle( - new FlatForward(vars.settlement,swap_u365.fairRate(), - new Actual365Fixed(),Compounding.Compounded, - vars.fixedFrequency)); - Handle termStructure_a365 = new Handle( - new FlatForward(vars.settlement,swap_a365.fairRate(), - new Actual365Fixed(),Compounding.Compounded, - vars.fixedFrequency)); - - // Annuity calculated by swap method fixedLegBPS(). - // Fixed leg conventions: Unadjusted, 30/360 - double annuity_u360 = swap_u360.fixedLegBPS() / 0.0001; - annuity_u360 = swap_u360.swapType==VanillaSwap.Type.Payer ? - -annuity_u360 : annuity_u360; - // Fixed leg conventions: ModifiedFollowing, act/365 - double annuity_a365 = swap_a365.fixedLegBPS() / 0.0001; - annuity_a365 = swap_a365.swapType==VanillaSwap.Type.Payer ? - -annuity_a365 : annuity_a365; - // Fixed leg conventions: ModifiedFollowing, 30/360 - double annuity_a360 = swap_a360.fixedLegBPS() / 0.0001; - annuity_a360 = swap_a360.swapType==VanillaSwap.Type.Payer ? - -annuity_a360 : annuity_a360; - // Fixed leg conventions: Unadjusted, act/365 - double annuity_u365 = swap_u365.fixedLegBPS() / 0.0001; - annuity_u365 = swap_u365.swapType==VanillaSwap.Type.Payer ? - -annuity_u365 : annuity_u365; - - // Calculation of Modified Annuity (cash settlement) - // Fixed leg conventions of swap: unadjusted, 30/360 - double cashannuity_u360 = 0.0; - int k; - for (k=0; k swapFixedLeg_u360 = swap_u360.fixedLeg(); + List swapFixedLeg_a360 = swap_a360.fixedLeg(); + List swapFixedLeg_u365 = swap_u365.fixedLeg(); + List swapFixedLeg_a365 = swap_a365.fixedLeg(); + + // FlatForward curves + // FLOATING_POINT_EXCEPTION + Handle termStructure_u360 = new Handle( + new FlatForward(vars.settlement, swap_u360.fairRate(), + new Thirty360(), Compounding.Compounded, + vars.fixedFrequency)); + Handle termStructure_a360 = new Handle( + new FlatForward(vars.settlement, swap_a360.fairRate(), + new Thirty360(), Compounding.Compounded, + vars.fixedFrequency)); + Handle termStructure_u365 = new Handle( + new FlatForward(vars.settlement, swap_u365.fairRate(), + new Actual365Fixed(), Compounding.Compounded, + vars.fixedFrequency)); + Handle termStructure_a365 = new Handle( + new FlatForward(vars.settlement, swap_a365.fairRate(), + new Actual365Fixed(), Compounding.Compounded, + vars.fixedFrequency)); + + // Annuity calculated by swap method fixedLegBPS(). + // Fixed leg conventions: Unadjusted, 30/360 + double annuity_u360 = swap_u360.fixedLegBPS() / 0.0001; + annuity_u360 = swap_u360.swapType == VanillaSwap.Type.Payer ? + -annuity_u360 : annuity_u360; + // Fixed leg conventions: ModifiedFollowing, act/365 + double annuity_a365 = swap_a365.fixedLegBPS() / 0.0001; + annuity_a365 = swap_a365.swapType == VanillaSwap.Type.Payer ? + -annuity_a365 : annuity_a365; + // Fixed leg conventions: ModifiedFollowing, 30/360 + double annuity_a360 = swap_a360.fixedLegBPS() / 0.0001; + annuity_a360 = swap_a360.swapType == VanillaSwap.Type.Payer ? + -annuity_a360 : annuity_a360; + // Fixed leg conventions: Unadjusted, act/365 + double annuity_u365 = swap_u365.fixedLegBPS() / 0.0001; + annuity_u365 = swap_u365.swapType == VanillaSwap.Type.Payer ? + -annuity_u365 : annuity_u365; + + // Calculation of Modified Annuity (cash settlement) + // Fixed leg conventions of swap: unadjusted, 30/360 + double cashannuity_u360 = 0.0; + int k; + for (k = 0; k < swapFixedLeg_u360.Count; k++) + { + cashannuity_u360 += swapFixedLeg_u360[k].amount() / strike * termStructure_u360.currentLink().discount( - swapFixedLeg_u360[k].date()); - } - // Fixed leg conventions of swap: unadjusted, act/365 - double cashannuity_u365 = 0.0; - for (k=0; k1e-10 ) { - QAssert.Fail("\n" + - " The npv's ratio must be equal to " + - " annuities ratio" + "\n" + - " Swaption " + - exercises[i].units() + "y x " + lengths[j].units() + "y" + - " (underlying swap fixed leg Unadjusted, 30/360)" + "\n" + - " Today : " + - vars.today + "\n" + - " Settlement date : " + - vars.settlement + "\n" + - " Exercise date : " + - exerciseDate + "\n" + - " Swap start date : " + - startDate + "\n" + - " Swap end date : " + - maturity + "\n" + - " physical delivered swaption npv : " + - value_p_u360 + "\t\t\t" + - " annuity : " + - annuity_u360 + "\n" + - " cash delivered swaption npv : " + - value_c_u360 + "\t\t\t" + - " annuity : " + - cashannuity_u360 + "\n" + - " npv ratio : " + - npv_ratio_u360 + "\n" + - " annuity ratio : " + - annuity_ratio_u360 + "\n" + - " difference : " + - (annuity_ratio_u360-npv_ratio_u360) ); - } - if (Math.Abs(annuity_ratio_a365-npv_ratio_a365)>1e-10) { - QAssert.Fail("\n" + - " The npv's ratio must be equal to " + - " annuities ratio" + "\n" + - " Swaption " + - exercises[i].units() + "y x " + lengths[j].units() + "y" + - " (underlying swap fixed leg Modified Following, act/365" + "\n" + - " Today : " + - vars.today + "\n" + - " Settlement date : " + - vars.settlement + "\n" + - " Exercise date : " + - exerciseDate + "\n" + - " Swap start date : " + - startDate + "\n" + - " Swap end date : " + - maturity + "\n" + - " physical delivered swaption npv : " + - value_p_a365 + "\t\t\t" + - " annuity : " + - annuity_a365 + "\n" + - " cash delivered swaption npv : " + - value_c_a365 + "\t\t\t" + - " annuity : " + - cashannuity_a365 + "\n" + - " npv ratio : " + - npv_ratio_a365 + "\n" + - " annuity ratio : " + - annuity_ratio_a365 + "\n" + - " difference : " + - (annuity_ratio_a365-npv_ratio_a365) ); - } - if (Math.Abs(annuity_ratio_a360-npv_ratio_a360)>1e-10) { - QAssert.Fail("\n" + - " The npv's ratio must be equal to " + - " annuities ratio" + "\n" + - " Swaption " + - exercises[i].units() + "y x " + lengths[j].units() + "y" + - " (underlying swap fixed leg Unadjusted, 30/360)" + "\n" + - " Today : " + - vars.today + "\n" + - " Settlement date : " + - vars.settlement + "\n" + - " Exercise date : " + - exerciseDate + "\n" + - " Swap start date : " + - startDate + "\n" + - " Swap end date : " + - maturity + "\n" + - " physical delivered swaption npv : " + - value_p_a360 + "\t\t\t" + - " annuity : " + - annuity_a360 + "\n" + - " cash delivered swaption npv : " + - value_c_a360 + "\t\t\t" + - " annuity : " + - cashannuity_a360 + "\n" + - " npv ratio : " + - npv_ratio_a360 + "\n" + - " annuity ratio : " + - annuity_ratio_a360 + "\n" + - " difference : " + - (annuity_ratio_a360-npv_ratio_a360) ); - } - if (Math.Abs(annuity_ratio_u365-npv_ratio_u365)>1e-10) { - QAssert.Fail("\n" + - " The npv's ratio must be equal to " + - " annuities ratio" + "\n" + - " Swaption " + - exercises[i].units() + "y x " + lengths[j].units() + "y" + - " (underlying swap fixed leg Unadjusted, act/365)" + "\n" + - " Today : " + - vars.today + "\n" + - " Settlement date : " + - vars.settlement + "\n" + - " Exercise date : " + - exerciseDate + "\n" + - " Swap start date : " + - startDate + "\n" + - " Swap end date : " + - maturity + "\n" + - " physical delivered swaption npv : " + - value_p_u365 + "\t\t\t" + - " annuity : " + - annuity_u365 + "\n" + - " cash delivered swaption npv : " + - value_c_u365 + "\t\t\t" + - " annuity : " + - cashannuity_u365 + "\n" + - " npv ratio : " + - npv_ratio_u365 + "\n" + - " annuity ratio : " + - annuity_ratio_u365 + "\n" + - " difference : " + - (annuity_ratio_u365-npv_ratio_u365) ); - } + swapFixedLeg_a365[k].date()); + } + + // Swaptions: underlying swap fixed leg conventions: + // unadjusted, 30/360 + + // Physical settled swaption + Swaption swaption_p_u360 = + vars.makeSwaption(swap_u360, exerciseDate, 0.20); + double value_p_u360 = swaption_p_u360.NPV(); + // Cash settled swaption + Swaption swaption_c_u360 = + vars.makeSwaption(swap_u360, exerciseDate, 0.20, + Settlement.Type.Cash); + double value_c_u360 = swaption_c_u360.NPV(); + // the NPV's ratio must be equal to annuities ratio + double npv_ratio_u360 = value_c_u360 / value_p_u360; + double annuity_ratio_u360 = cashannuity_u360 / annuity_u360; + + // Swaptions: underlying swap fixed leg conventions: + // modified following, act/365 + + // Physical settled swaption + Swaption swaption_p_a365 = + vars.makeSwaption(swap_a365, exerciseDate, 0.20); + double value_p_a365 = swaption_p_a365.NPV(); + // Cash settled swaption + Swaption swaption_c_a365 = + vars.makeSwaption(swap_a365, exerciseDate, 0.20, + Settlement.Type.Cash); + double value_c_a365 = swaption_c_a365.NPV(); + // the NPV's ratio must be equal to annuities ratio + double npv_ratio_a365 = value_c_a365 / value_p_a365; + double annuity_ratio_a365 = cashannuity_a365 / annuity_a365; + + // Swaptions: underlying swap fixed leg conventions: + // modified following, 30/360 + + // Physical settled swaption + Swaption swaption_p_a360 = + vars.makeSwaption(swap_a360, exerciseDate, 0.20); + double value_p_a360 = swaption_p_a360.NPV(); + // Cash settled swaption + Swaption swaption_c_a360 = + vars.makeSwaption(swap_a360, exerciseDate, 0.20, + Settlement.Type.Cash); + double value_c_a360 = swaption_c_a360.NPV(); + // the NPV's ratio must be equal to annuities ratio + double npv_ratio_a360 = value_c_a360 / value_p_a360; + double annuity_ratio_a360 = cashannuity_a360 / annuity_a360; + + // Swaptions: underlying swap fixed leg conventions: + // unadjusted, act/365 + + // Physical settled swaption + Swaption swaption_p_u365 = + vars.makeSwaption(swap_u365, exerciseDate, 0.20); + double value_p_u365 = swaption_p_u365.NPV(); + // Cash settled swaption + Swaption swaption_c_u365 = + vars.makeSwaption(swap_u365, exerciseDate, 0.20, + Settlement.Type.Cash); + double value_c_u365 = swaption_c_u365.NPV(); + // the NPV's ratio must be equal to annuities ratio + double npv_ratio_u365 = value_c_u365 / value_p_u365; + double annuity_ratio_u365 = cashannuity_u365 / annuity_u365; + + if (Math.Abs(annuity_ratio_u360 - npv_ratio_u360) > 1e-10) + { + QAssert.Fail("\n" + + " The npv's ratio must be equal to " + + " annuities ratio" + "\n" + + " Swaption " + + exercises[i].units() + "y x " + lengths[j].units() + "y" + + " (underlying swap fixed leg Unadjusted, 30/360)" + "\n" + + " Today : " + + vars.today + "\n" + + " Settlement date : " + + vars.settlement + "\n" + + " Exercise date : " + + exerciseDate + "\n" + + " Swap start date : " + + startDate + "\n" + + " Swap end date : " + + maturity + "\n" + + " physical delivered swaption npv : " + + value_p_u360 + "\t\t\t" + + " annuity : " + + annuity_u360 + "\n" + + " cash delivered swaption npv : " + + value_c_u360 + "\t\t\t" + + " annuity : " + + cashannuity_u360 + "\n" + + " npv ratio : " + + npv_ratio_u360 + "\n" + + " annuity ratio : " + + annuity_ratio_u360 + "\n" + + " difference : " + + (annuity_ratio_u360 - npv_ratio_u360)); + } + if (Math.Abs(annuity_ratio_a365 - npv_ratio_a365) > 1e-10) + { + QAssert.Fail("\n" + + " The npv's ratio must be equal to " + + " annuities ratio" + "\n" + + " Swaption " + + exercises[i].units() + "y x " + lengths[j].units() + "y" + + " (underlying swap fixed leg Modified Following, act/365" + "\n" + + " Today : " + + vars.today + "\n" + + " Settlement date : " + + vars.settlement + "\n" + + " Exercise date : " + + exerciseDate + "\n" + + " Swap start date : " + + startDate + "\n" + + " Swap end date : " + + maturity + "\n" + + " physical delivered swaption npv : " + + value_p_a365 + "\t\t\t" + + " annuity : " + + annuity_a365 + "\n" + + " cash delivered swaption npv : " + + value_c_a365 + "\t\t\t" + + " annuity : " + + cashannuity_a365 + "\n" + + " npv ratio : " + + npv_ratio_a365 + "\n" + + " annuity ratio : " + + annuity_ratio_a365 + "\n" + + " difference : " + + (annuity_ratio_a365 - npv_ratio_a365)); + } + if (Math.Abs(annuity_ratio_a360 - npv_ratio_a360) > 1e-10) + { + QAssert.Fail("\n" + + " The npv's ratio must be equal to " + + " annuities ratio" + "\n" + + " Swaption " + + exercises[i].units() + "y x " + lengths[j].units() + "y" + + " (underlying swap fixed leg Unadjusted, 30/360)" + "\n" + + " Today : " + + vars.today + "\n" + + " Settlement date : " + + vars.settlement + "\n" + + " Exercise date : " + + exerciseDate + "\n" + + " Swap start date : " + + startDate + "\n" + + " Swap end date : " + + maturity + "\n" + + " physical delivered swaption npv : " + + value_p_a360 + "\t\t\t" + + " annuity : " + + annuity_a360 + "\n" + + " cash delivered swaption npv : " + + value_c_a360 + "\t\t\t" + + " annuity : " + + cashannuity_a360 + "\n" + + " npv ratio : " + + npv_ratio_a360 + "\n" + + " annuity ratio : " + + annuity_ratio_a360 + "\n" + + " difference : " + + (annuity_ratio_a360 - npv_ratio_a360)); + } + if (Math.Abs(annuity_ratio_u365 - npv_ratio_u365) > 1e-10) + { + QAssert.Fail("\n" + + " The npv's ratio must be equal to " + + " annuities ratio" + "\n" + + " Swaption " + + exercises[i].units() + "y x " + lengths[j].units() + "y" + + " (underlying swap fixed leg Unadjusted, act/365)" + "\n" + + " Today : " + + vars.today + "\n" + + " Settlement date : " + + vars.settlement + "\n" + + " Exercise date : " + + exerciseDate + "\n" + + " Swap start date : " + + startDate + "\n" + + " Swap end date : " + + maturity + "\n" + + " physical delivered swaption npv : " + + value_p_u365 + "\t\t\t" + + " annuity : " + + annuity_u365 + "\n" + + " cash delivered swaption npv : " + + value_c_u365 + "\t\t\t" + + " annuity : " + + cashannuity_u365 + "\n" + + " npv ratio : " + + npv_ratio_u365 + "\n" + + " annuity ratio : " + + annuity_ratio_u365 + "\n" + + " difference : " + + (annuity_ratio_u365 - npv_ratio_u365)); + } } - } - } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testImpliedVolatility() - { - // Testing implied volatility for swaptions - CommonVars vars=new CommonVars(); - - int maxEvaluations = 100; - double tolerance = 1.0e-08; - - Settlement.Type[] types = { Settlement.Type.Physical, Settlement.Type.Cash }; - // test data - double[] strikes = { 0.02, 0.03, 0.04, 0.05, 0.06, 0.07 }; - double[] vols = { 0.01, 0.05, 0.10, 0.20, 0.30, 0.70, 0.90 }; - - for (int i = 0; i < exercises.Length; i++) + public void testImpliedVolatility() + { + // Testing implied volatility for swaptions + CommonVars vars = new CommonVars(); + + int maxEvaluations = 100; + double tolerance = 1.0e-08; + + Settlement.Type[] types = { Settlement.Type.Physical, Settlement.Type.Cash }; + // test data + double[] strikes = { 0.02, 0.03, 0.04, 0.05, 0.06, 0.07 }; + double[] vols = { 0.01, 0.05, 0.10, 0.20, 0.30, 0.70, 0.90 }; + + for (int i = 0; i < exercises.Length; i++) + { + for (int j = 0; j < lengths.Length; j++) { - for (int j = 0; j < lengths.Length; j++) - { - Date exerciseDate = vars.calendar.advance(vars.today, exercises[i]); - Date startDate = vars.calendar.advance(exerciseDate, - vars.settlementDays, TimeUnit.Days); - Date maturity = vars.calendar.advance(startDate, lengths[j], - vars.floatingConvention); - for (int t = 0; t < strikes.Length; t++) - { - for (int k = 0; k < type.Length; k++) + Date exerciseDate = vars.calendar.advance(vars.today, exercises[i]); + Date startDate = vars.calendar.advance(exerciseDate, + vars.settlementDays, TimeUnit.Days); + Date maturity = vars.calendar.advance(startDate, lengths[j], + vars.floatingConvention); + for (int t = 0; t < strikes.Length; t++) + { + for (int k = 0; k < type.Length; k++) + { + VanillaSwap swap = new MakeVanillaSwap(lengths[j], vars.index, strikes[t]) + .withEffectiveDate(startDate) + .withFloatingLegSpread(0.0) + .withType(type[k]); + for (int h = 0; h < types.Length; h++) + { + for (int u = 0; u < vols.Length; u++) { - VanillaSwap swap = new MakeVanillaSwap(lengths[j], vars.index, strikes[t]) - .withEffectiveDate(startDate) - .withFloatingLegSpread(0.0) - .withType(type[k]); - for (int h = 0; h < types.Length; h++) - { - for (int u = 0; u < vols.Length; u++) - { - Swaption swaption = vars.makeSwaption(swap, exerciseDate, - vols[u], types[h], - BlackStyleSwaptionEngine.CashAnnuityModel.DiscountCurve); - // Black price - double value = swaption.NPV(); - double implVol = 0.0; - try - { - implVol = - swaption.impliedVolatility(value, - vars.termStructure, - 0.10, - tolerance, - maxEvaluations); - } - catch (System.Exception e) - { - // couldn't bracket? - swaption.setPricingEngine(vars.makeEngine(0.0, BlackStyleSwaptionEngine.CashAnnuityModel.DiscountCurve)); - double value2 = swaption.NPV(); - if (Math.Abs(value - value2) < tolerance) - { - // ok, just skip: - continue; - } - // otherwise, report error - QAssert.Fail("implied vol failure: " + - exercises[i] + "x" + lengths[j] + " " + type[k] + - "\nsettlement: " + types[h] + - "\nstrike " + strikes[t] + - "\natm level: " + swap.fairRate() + - "\nvol: " + vols[u] + - "\nprice: " + value + - "\n" + e.Message.ToString()); - } - if (Math.Abs(implVol - vols[u]) > tolerance) - { - // the difference might not matter - swaption.setPricingEngine(vars.makeEngine(implVol, BlackStyleSwaptionEngine.CashAnnuityModel.DiscountCurve)); - double value2 = swaption.NPV(); - if (Math.Abs(value - value2) > tolerance) - { - QAssert.Fail("implied vol failure: " + - exercises[i] + "x" + lengths[j] + " " + type[k] + - "\nsettlement: " + types[h] + - "\nstrike " + strikes[t] + - "\natm level: " + swap.fairRate() + - "\nvol: " + vols[u] + - "\nprice: " + value + - "\nimplied vol: " + implVol + - "\nimplied price: " + value2); - } - } - } - } + Swaption swaption = vars.makeSwaption(swap, exerciseDate, + vols[u], types[h], + BlackStyleSwaptionEngine.CashAnnuityModel.DiscountCurve); + // Black price + double value = swaption.NPV(); + double implVol = 0.0; + try + { + implVol = + swaption.impliedVolatility(value, + vars.termStructure, + 0.10, + tolerance, + maxEvaluations); + } + catch (System.Exception e) + { + // couldn't bracket? + swaption.setPricingEngine(vars.makeEngine(0.0, BlackStyleSwaptionEngine.CashAnnuityModel.DiscountCurve)); + double value2 = swaption.NPV(); + if (Math.Abs(value - value2) < tolerance) + { + // ok, just skip: + continue; + } + // otherwise, report error + QAssert.Fail("implied vol failure: " + + exercises[i] + "x" + lengths[j] + " " + type[k] + + "\nsettlement: " + types[h] + + "\nstrike " + strikes[t] + + "\natm level: " + swap.fairRate() + + "\nvol: " + vols[u] + + "\nprice: " + value + + "\n" + e.Message.ToString()); + } + if (Math.Abs(implVol - vols[u]) > tolerance) + { + // the difference might not matter + swaption.setPricingEngine(vars.makeEngine(implVol, BlackStyleSwaptionEngine.CashAnnuityModel.DiscountCurve)); + double value2 = swaption.NPV(); + if (Math.Abs(value - value2) > tolerance) + { + QAssert.Fail("implied vol failure: " + + exercises[i] + "x" + lengths[j] + " " + type[k] + + "\nsettlement: " + types[h] + + "\nstrike " + strikes[t] + + "\natm level: " + swap.fairRate() + + "\nvol: " + vols[u] + + "\nprice: " + value + + "\nimplied vol: " + implVol + + "\nimplied price: " + value2); + } + } } - } - } + } + } + } } - } - } + } + } + } } diff --git a/tests/QLNet.Tests/T_SwaptionVolatilityCube.cs b/tests/QLNet.Tests/T_SwaptionVolatilityCube.cs index 820415491..b7a597b1d 100644 --- a/tests/QLNet.Tests/T_SwaptionVolatilityCube.cs +++ b/tests/QLNet.Tests/T_SwaptionVolatilityCube.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -18,7 +18,7 @@ #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -29,7 +29,7 @@ namespace TestSuite #endif public class T_SwaptionVolatilityCube { - public class CommonVars + public class CommonVars { // global data public SwaptionMarketConventions conventions = new SwaptionMarketConventions(); @@ -41,65 +41,65 @@ public class CommonVars public bool vegaWeighedSmileFit; // cleanup - //public SavedSettings backup = new SavedSettings(); + //public SavedSettings backup = new SavedSettings(); // utilities - public void makeAtmVolTest( SwaptionVolatilityCube volCube, double tolerance ) + public void makeAtmVolTest(SwaptionVolatilityCube volCube, double tolerance) { - for (int i=0; itolerance) + double error = Math.Abs(expVol - actVol); + if (error > tolerance) QAssert.Fail("recovery of atm vols failed:" + - "\nexpiry time = " + atm.tenors.options[i] + - "\nswap length = " + atm.tenors.swaps[j] + - "\n atm strike = " + strike + - "\n exp. vol = " + expVol + - "\n actual vol = " + actVol + - "\n error = " + error + - "\n tolerance = " + tolerance); + "\nexpiry time = " + atm.tenors.options[i] + + "\nswap length = " + atm.tenors.swaps[j] + + "\n atm strike = " + strike + + "\n exp. vol = " + expVol + + "\n actual vol = " + actVol + + "\n error = " + error + + "\n tolerance = " + tolerance); } } } - public void makeVolSpreadsTest(SwaptionVolatilityCube volCube,double tolerance) + public void makeVolSpreadsTest(SwaptionVolatilityCube volCube, double tolerance) { - for (int i=0; itolerance) + double atmStrike = volCube.atmStrike(cube.tenors.options[i], cube.tenors.swaps[j]); + double atmVol = atmVolMatrix.link.volatility(cube.tenors.options[i], cube.tenors.swaps[j], + atmStrike, true); + double vol = volCube.volatility(cube.tenors.options[i], cube.tenors.swaps[j], + atmStrike + cube.strikeSpreads[k], true); + double spread = vol - atmVol; + double expVolSpread = cube.volSpreads[i * cube.tenors.swaps.Count + j, k]; + double error = Math.Abs(expVolSpread - spread); + if (error > tolerance) QAssert.Fail("\nrecovery of smile vol spreads failed:" + - "\n option tenor = " + cube.tenors.options[i] + - "\n swap tenor = " + cube.tenors.swaps[j] + - "\n atm strike = " + atmStrike + - "\n strike spread = " + cube.strikeSpreads[k] + - "\n atm vol = " + atmVol + - "\n smiled vol = " + vol + - "\n vol spread = " + spread + - "\n exp. vol spread = " + expVolSpread + - "\n error = " + error + - "\n tolerance = " + tolerance); + "\n option tenor = " + cube.tenors.options[i] + + "\n swap tenor = " + cube.tenors.swaps[j] + + "\n atm strike = " + atmStrike + + "\n strike spread = " + cube.strikeSpreads[k] + + "\n atm vol = " + atmVol + + "\n smiled vol = " + vol + + "\n vol spread = " + spread + + "\n exp. vol spread = " + expVolSpread + + "\n error = " + error + + "\n tolerance = " + tolerance); } } } } - public CommonVars() + public CommonVars() { Settings.setEvaluationDate(new Date(16, Month.September, 2015)); conventions.setConventions(); @@ -108,26 +108,26 @@ public CommonVars() atm.setMarketData(); atmVolMatrix = new RelinkableHandle( - new SwaptionVolatilityMatrix( conventions.calendar,conventions.optionBdc,atm.tenors.options, - atm.tenors.swaps,atm.volsHandle,conventions.dayCounter)); + new SwaptionVolatilityMatrix(conventions.calendar, conventions.optionBdc, atm.tenors.options, + atm.tenors.swaps, atm.volsHandle, conventions.dayCounter)); // Swaptionvolcube cube.setMarketData(); termStructure.linkTo(Utilities.flatRate(0.05, new Actual365Fixed())); - swapIndexBase = new EuriborSwapIsdaFixA(new Period(2,TimeUnit.Years), termStructure); - shortSwapIndexBase = new EuriborSwapIsdaFixA(new Period(1,TimeUnit.Years), termStructure); + swapIndexBase = new EuriborSwapIsdaFixA(new Period(2, TimeUnit.Years), termStructure); + shortSwapIndexBase = new EuriborSwapIsdaFixA(new Period(1, TimeUnit.Years), termStructure); - vegaWeighedSmileFit=false; + vegaWeighedSmileFit = false; } } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testAtmVols() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testAtmVols() { // Testing swaption volatility cube (atm vols) @@ -144,14 +144,14 @@ public void testAtmVols() double tolerance = 1.0e-16; vars.makeAtmVolTest(volCube, tolerance); -} + } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testSmile() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testSmile() { // Testing swaption volatility cube (smile) CommonVars vars = new CommonVars(); @@ -169,53 +169,53 @@ public void testSmile() vars.makeVolSpreadsTest(volCube, tolerance); } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testSabrVols() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testSabrVols() { // Testing swaption volatility cube (sabr interpolation) CommonVars vars = new CommonVars(); List > > parametersGuess = new InitializedList>>( - vars.cube.tenors.options.Count*vars.cube.tenors.swaps.Count); - for (int i=0; i >(4); parametersGuess[i][0] = new Handle(new SimpleQuote(0.2)); parametersGuess[i][1] = new Handle(new SimpleQuote(0.5)); parametersGuess[i][2] = new Handle(new SimpleQuote(0.4)); parametersGuess[i][3] = new Handle(new SimpleQuote(0.0)); - } - List isParameterFixed = new InitializedList(4, false); - - SwaptionVolCube1x volCube = new SwaptionVolCube1x - ( vars.atmVolMatrix,vars.cube.tenors.options,vars.cube.tenors.swaps,vars.cube.strikeSpreads, - vars.cube.volSpreadsHandle,vars.swapIndexBase,vars.shortSwapIndexBase,vars.vegaWeighedSmileFit, - parametersGuess,isParameterFixed,true); - double tolerance = 3.0e-4; - vars.makeAtmVolTest(volCube, tolerance); - - tolerance = 12.0e-4; - vars.makeVolSpreadsTest(volCube, tolerance); + } + List isParameterFixed = new InitializedList(4, false); + + SwaptionVolCube1x volCube = new SwaptionVolCube1x + (vars.atmVolMatrix, vars.cube.tenors.options, vars.cube.tenors.swaps, vars.cube.strikeSpreads, + vars.cube.volSpreadsHandle, vars.swapIndexBase, vars.shortSwapIndexBase, vars.vegaWeighedSmileFit, + parametersGuess, isParameterFixed, true); + double tolerance = 3.0e-4; + vars.makeAtmVolTest(volCube, tolerance); + + tolerance = 12.0e-4; + vars.makeVolSpreadsTest(volCube, tolerance); } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testSpreadedCube() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testSpreadedCube() { // Testing spreaded swaption volatility cube CommonVars vars = new CommonVars(); - List > > parametersGuess = - new InitializedList>>(vars.cube.tenors.options.Count*vars.cube.tenors.swaps.Count); - for (int i=0; i > > parametersGuess = + new InitializedList>>(vars.cube.tenors.options.Count * vars.cube.tenors.swaps.Count); + for (int i = 0; i < vars.cube.tenors.options.Count * vars.cube.tenors.swaps.Count; i++) { parametersGuess[i] = new InitializedList>(4); parametersGuess[i][0] = new Handle(new SimpleQuote(0.2)); @@ -225,7 +225,7 @@ public void testSpreadedCube() } List isParameterFixed = new InitializedList(4, false); - Handle volCube = new Handle( + Handle volCube = new Handle( new SwaptionVolCube1x(vars.atmVolMatrix, vars.cube.tenors.options, vars.cube.tenors.swaps, @@ -242,37 +242,37 @@ public void testSpreadedCube() Handle spreadHandle = new Handle(spread); SwaptionVolatilityStructure spreadedVolCube = new SpreadedSwaptionVolatility(volCube, spreadHandle); List strikes = new List(); - for (int k=1; k<100; k++) - strikes.Add(k*.01); - for (int i=0; i1e-16) + - volCube.link.volatility(vars.cube.tenors.options[i], vars.cube.tenors.swaps[j], strike); + if (Math.Abs(diff - spread.value()) > 1e-16) QAssert.Fail("\ndiff!=spread in volatility method:" + - "\nexpiry time = " + vars.cube.tenors.options[i] + - "\nswap length = " + vars.cube.tenors.swaps[j] + - "\n atm strike = " + (strike) + - "\ndiff = " + diff + - "\nspread = " + spread.value()); + "\nexpiry time = " + vars.cube.tenors.options[i] + + "\nswap length = " + vars.cube.tenors.swaps[j] + + "\n atm strike = " + (strike) + + "\ndiff = " + diff + + "\nspread = " + spread.value()); diff = smileSectionBySpreadedCube.volatility(strike) - smileSectionByCube.volatility(strike); - if (Math.Abs(diff-spread.value())>1e-16) + if (Math.Abs(diff - spread.value()) > 1e-16) QAssert.Fail("\ndiff!=spread in smile section method:" + - "\nexpiry time = " + vars.cube.tenors.options[i] + - "\nswap length = " + vars.cube.tenors.swaps[j] + - "\n atm strike = " + (strike) + - "\ndiff = " + diff + - "\nspread = " + spread.value()); + "\nexpiry time = " + vars.cube.tenors.options[i] + + "\nswap length = " + vars.cube.tenors.swaps[j] + + "\n atm strike = " + (strike) + + "\ndiff = " + diff + + "\nspread = " + spread.value()); } } } @@ -281,28 +281,28 @@ public void testSpreadedCube() Flag f = new Flag(); spreadedVolCube.registerWith(f.update); volCube.link.update(); - if(!f.isUp()) + if (!f.isUp()) QAssert.Fail("SpreadedSwaptionVolatilityStructure does not propagate notifications"); - + f.lower(); spread.setValue(.001); - if(!f.isUp()) + if (!f.isUp()) QAssert.Fail("SpreadedSwaptionVolatilityStructure does not propagate notifications"); } - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif - public void testObservability() +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif + public void testObservability() { // Testing volatility cube observability CommonVars vars = new CommonVars(); - List > > parametersGuess = - new InitializedList>>(vars.cube.tenors.options.Count*vars.cube.tenors.swaps.Count); - for (int i=0; i > > parametersGuess = + new InitializedList>>(vars.cube.tenors.options.Count * vars.cube.tenors.swaps.Count); + for (int i = 0; i < vars.cube.tenors.options.Count * vars.cube.tenors.swaps.Count; i++) { parametersGuess[i] = new InitializedList>(4); parametersGuess[i][0] = new Handle(new SimpleQuote(0.2)); @@ -328,7 +328,7 @@ public void testObservability() Date referenceDate = Settings.evaluationDate(); Settings.setEvaluationDate(vars.conventions.calendar.advance(referenceDate, new Period(1, TimeUnit.Days), - vars.conventions.optionBdc)); + vars.conventions.optionBdc)); // VolCube created after change of reference date volCube1_1 = new SwaptionVolCube1x(vars.atmVolMatrix, @@ -343,11 +343,11 @@ public void testObservability() isParameterFixed, true); double dummyStrike = 0.03; - for (int i=0;i 1e-14) + if (Math.Abs(v0 - v1) > 1e-14) QAssert.Fail(" option tenor = " + vars.cube.tenors.options[i] + - " swap tenor = " + vars.cube.tenors.swaps[j] + - " strike = " + (dummyStrike+vars.cube.strikeSpreads[k])+ - " v0 = " + (v0) + - " v1 = " + (v1) + - " error = " + Math.Abs(v1-v0)); + " swap tenor = " + vars.cube.tenors.swaps[j] + + " strike = " + (dummyStrike + vars.cube.strikeSpreads[k]) + + " v0 = " + (v0) + + " v1 = " + (v1) + + " error = " + Math.Abs(v1 - v0)); } } } @@ -381,7 +381,7 @@ public void testObservability() vars.shortSwapIndexBase, vars.vegaWeighedSmileFit); Settings.setEvaluationDate(vars.conventions.calendar.advance(referenceDate, new Period(1, TimeUnit.Days), - vars.conventions.optionBdc)); + vars.conventions.optionBdc)); // VolCube created after change of reference date volCube2_1 = new SwaptionVolCube2(vars.atmVolMatrix, @@ -393,11 +393,11 @@ public void testObservability() vars.shortSwapIndexBase, vars.vegaWeighedSmileFit); - for (int i=0;i 1e-14) QAssert.Fail(" option tenor = " + vars.cube.tenors.options[i] + - " swap tenor = " + vars.cube.tenors.swaps[j] + - " strike = " + (dummyStrike+vars.cube.strikeSpreads[k])+ - " v0 = " + (v0) + - " v1 = " + (v1) + - " error = " + Math.Abs(v1-v0)); + " swap tenor = " + vars.cube.tenors.swaps[j] + + " strike = " + (dummyStrike + vars.cube.strikeSpreads[k]) + + " v0 = " + (v0) + + " v1 = " + (v1) + + " error = " + Math.Abs(v1 - v0)); } } } diff --git a/tests/QLNet.Tests/T_SwaptionVolatilitymatrix.cs b/tests/QLNet.Tests/T_SwaptionVolatilitymatrix.cs index 6046fda8b..012082b83 100644 --- a/tests/QLNet.Tests/T_SwaptionVolatilitymatrix.cs +++ b/tests/QLNet.Tests/T_SwaptionVolatilitymatrix.cs @@ -1,17 +1,17 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -23,7 +23,7 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -33,432 +33,435 @@ namespace TestSuite [TestClass()] #endif public class T_SwaptionVolatilityMatrix : IDisposable - { - #region Initialize&Cleanup - private SavedSettings backup; - #if NET40 || NET45 - [TestInitialize] - public void testInitialize() - { - #else - public T_SwaptionVolatilityMatrix() - { - #endif - backup = new SavedSettings(); - } - #if NET40 || NET45 - [TestCleanup] - #endif - public void testCleanup() - { - Dispose(); - } - public void Dispose() - { - backup.Dispose(); - } - #endregion - - public class SwaptionTenors - { - public List options; - public List swaps; - } - - public class SwaptionMarketConventions - { - public Calendar calendar; - public BusinessDayConvention optionBdc; - public DayCounter dayCounter; - public void setConventions() + { + #region Initialize&Cleanup + private SavedSettings backup; +#if NET40 || NET45 + [TestInitialize] + public void testInitialize() + { +#else + public T_SwaptionVolatilityMatrix() + { +#endif + backup = new SavedSettings(); + } +#if NET40 || NET45 + [TestCleanup] +#endif + public void testCleanup() + { + Dispose(); + } + public void Dispose() + { + backup.Dispose(); + } + #endregion + + public class SwaptionTenors + { + public List options; + public List swaps; + } + + public class SwaptionMarketConventions + { + public Calendar calendar; + public BusinessDayConvention optionBdc; + public DayCounter dayCounter; + public void setConventions() + { + calendar = new TARGET(); + Date today = calendar.adjust(Date.Today); + Settings.setEvaluationDate(today); + optionBdc = BusinessDayConvention.ModifiedFollowing; + dayCounter = new Actual365Fixed(); + } + } + + public class AtmVolatility + { + public SwaptionTenors tenors; + public Matrix vols; + public List>> volsHandle; + + public void setMarketData() + { + tenors = new SwaptionTenors(); + //tenors.options.resize(6); + tenors.options = new InitializedList(6); + tenors.options[0] = new Period(1, TimeUnit.Months); + tenors.options[1] = new Period(6, TimeUnit.Months); + tenors.options[2] = new Period(1, TimeUnit.Years); + tenors.options[3] = new Period(5, TimeUnit.Years); + tenors.options[4] = new Period(10, TimeUnit.Years); + tenors.options[5] = new Period(30, TimeUnit.Years); + //tenors.swaps.resize(4); + tenors.swaps = new InitializedList(4); + tenors.swaps[0] = new Period(1, TimeUnit.Years); + tenors.swaps[1] = new Period(5, TimeUnit.Years); + tenors.swaps[2] = new Period(10, TimeUnit.Years); + tenors.swaps[3] = new Period(30, TimeUnit.Years); + + vols = new Matrix(tenors.options.Count, tenors.swaps.Count); + vols[0, 0] = 0.1300; vols[0, 1] = 0.1560; vols[0, 2] = 0.1390; vols[0, 3] = 0.1220; + vols[1, 0] = 0.1440; vols[1, 1] = 0.1580; vols[1, 2] = 0.1460; vols[1, 3] = 0.1260; + vols[2, 0] = 0.1600; vols[2, 1] = 0.1590; vols[2, 2] = 0.1470; vols[2, 3] = 0.1290; + vols[3, 0] = 0.1640; vols[3, 1] = 0.1470; vols[3, 2] = 0.1370; vols[3, 3] = 0.1220; + vols[4, 0] = 0.1400; vols[4, 1] = 0.1300; vols[4, 2] = 0.1250; vols[4, 3] = 0.1100; + vols[5, 0] = 0.1130; vols[5, 1] = 0.1090; vols[5, 2] = 0.1070; vols[5, 3] = 0.0930; + volsHandle = new InitializedList>>(tenors.options.Count); + + for (int i = 0; i < tenors.options.Count; i++) { - calendar = new TARGET(); - Date today = calendar.adjust(Date.Today); - Settings.setEvaluationDate(today); - optionBdc = BusinessDayConvention.ModifiedFollowing; - dayCounter = new Actual365Fixed(); + volsHandle[i] = new InitializedList>(tenors.swaps.Count); + for (int j = 0; j < tenors.swaps.Count; j++) + // every handle must be reassigned, as the ones created by + // default are all linked together. + volsHandle[i][j] = new Handle(new SimpleQuote(vols[i, j])); } - } - - public class AtmVolatility - { - public SwaptionTenors tenors; - public Matrix vols; - public List>> volsHandle; + } + } + + class CommonVars + { + // global data + public SwaptionMarketConventions conventions; + public AtmVolatility atm; + public RelinkableHandle termStructure; + public RelinkableHandle atmVolMatrix; + + // setup + public CommonVars() + { + conventions = new SwaptionMarketConventions(); + conventions.setConventions(); + atm = new AtmVolatility(); + atm.setMarketData(); + atmVolMatrix = new RelinkableHandle (new + SwaptionVolatilityMatrix(conventions.calendar, + conventions.optionBdc, + atm.tenors.options, + atm.tenors.swaps, + atm.volsHandle, + conventions.dayCounter)); + termStructure = new RelinkableHandle(); + termStructure.linkTo((new FlatForward(0, conventions.calendar, + 0.05, new Actual365Fixed()))); + } + + // utilities + public void makeObservabilityTest(string description, + SwaptionVolatilityStructure vol, + bool mktDataFloating, + bool referenceDateFloating) + { + double dummyStrike = .02; + Date referenceDate = Settings.evaluationDate(); + double initialVol = vol.volatility( + referenceDate + atm.tenors.options[0], + atm.tenors.swaps[0], dummyStrike, false); + // testing evaluation date change ... + Settings.setEvaluationDate(referenceDate - new Period(1, TimeUnit.Years)); + double newVol = vol.volatility( + referenceDate + atm.tenors.options[0], + atm.tenors.swaps[0], dummyStrike, false); + + Settings.setEvaluationDate(referenceDate); + if (referenceDateFloating && (initialVol == newVol)) + QAssert.Fail(description + + " the volatility should change when the reference date is changed !"); + if (!referenceDateFloating && (initialVol != newVol)) + QAssert.Fail(description + + " the volatility should not change when the reference date is changed !"); - public void setMarketData() + // test market data change... + if (mktDataFloating) { - tenors = new SwaptionTenors(); - //tenors.options.resize(6); - tenors.options = new InitializedList(6); - tenors.options[0] = new Period(1, TimeUnit.Months); - tenors.options[1] = new Period(6, TimeUnit.Months); - tenors.options[2] = new Period(1, TimeUnit.Years); - tenors.options[3] = new Period(5, TimeUnit.Years); - tenors.options[4] = new Period(10, TimeUnit.Years); - tenors.options[5] = new Period(30, TimeUnit.Years); - //tenors.swaps.resize(4); - tenors.swaps = new InitializedList(4); - tenors.swaps[0] = new Period(1, TimeUnit.Years); - tenors.swaps[1] = new Period(5, TimeUnit.Years); - tenors.swaps[2] = new Period(10, TimeUnit.Years); - tenors.swaps[3] = new Period(30, TimeUnit.Years); - - vols = new Matrix(tenors.options.Count, tenors.swaps.Count); - vols[0, 0] = 0.1300; vols[0, 1] = 0.1560; vols[0, 2] = 0.1390; vols[0, 3] = 0.1220; - vols[1, 0] = 0.1440; vols[1, 1] = 0.1580; vols[1, 2] = 0.1460; vols[1, 3] = 0.1260; - vols[2, 0] = 0.1600; vols[2, 1] = 0.1590; vols[2, 2] = 0.1470; vols[2, 3] = 0.1290; - vols[3, 0] = 0.1640; vols[3, 1] = 0.1470; vols[3, 2] = 0.1370; vols[3, 3] = 0.1220; - vols[4, 0] = 0.1400; vols[4, 1] = 0.1300; vols[4, 2] = 0.1250; vols[4, 3] = 0.1100; - vols[5, 0] = 0.1130; vols[5, 1] = 0.1090; vols[5, 2] = 0.1070; vols[5, 3] = 0.0930; - volsHandle = new InitializedList>>(tenors.options.Count); - - for (int i = 0; i < tenors.options.Count; i++) - { - volsHandle[i] = new InitializedList>(tenors.swaps.Count); - for (int j = 0; j < tenors.swaps.Count; j++) - // every handle must be reassigned, as the ones created by - // default are all linked together. - volsHandle[i][j] = new Handle(new SimpleQuote(vols[i, j])); - } + double initialVolatility = atm.volsHandle[0][0].link.value(); + + SimpleQuote sq = (SimpleQuote)(atm.volsHandle[0][0].currentLink()); + sq.setValue(10); + + newVol = vol.volatility(referenceDate + atm.tenors.options[0], + atm.tenors.swaps[0], dummyStrike, false); + sq.setValue(initialVolatility); + + if (initialVol == newVol) + QAssert.Fail(description + " the volatility should change when" + + " the market data is changed !"); } - } - - class CommonVars - { - // global data - public SwaptionMarketConventions conventions; - public AtmVolatility atm; - public RelinkableHandle termStructure; - public RelinkableHandle atmVolMatrix; - - // setup - public CommonVars() + } + + public void makeCoherenceTest(string description, + SwaptionVolatilityDiscrete vol) + { + + for (int i = 0; i < atm.tenors.options.Count; ++i) { - conventions = new SwaptionMarketConventions(); - conventions.setConventions(); - atm = new AtmVolatility(); - atm.setMarketData(); - atmVolMatrix = new RelinkableHandle (new - SwaptionVolatilityMatrix(conventions.calendar, - conventions.optionBdc, - atm.tenors.options, - atm.tenors.swaps, - atm.volsHandle, - conventions.dayCounter)); - termStructure=new RelinkableHandle(); - termStructure.linkTo((new FlatForward(0, conventions.calendar, - 0.05, new Actual365Fixed()))); + Date optionDate = + vol.optionDateFromTenor(atm.tenors.options[i]); + if (optionDate != vol.optionDates()[i]) + QAssert.Fail( + "optionDateFromTenor failure for " + + description + ":" + + "\n option tenor: " + atm.tenors.options[i] + + "\nactual option date : " + optionDate + + "\n exp. option date : " + vol.optionDates()[i]); + double optionTime = vol.timeFromReference(optionDate); + if (optionTime != vol.optionTimes()[i]) + QAssert.Fail( + "timeFromReference failure for " + + description + ":" + + "\n option tenor: " + atm.tenors.options[i] + + "\n option date : " + optionDate + + "\nactual option time : " + optionTime + + "\n exp. option time : " + vol.optionTimes()[i]); } - - // utilities - public void makeObservabilityTest( string description, - SwaptionVolatilityStructure vol, - bool mktDataFloating, - bool referenceDateFloating) - { - double dummyStrike = .02; - Date referenceDate = Settings.evaluationDate(); - double initialVol = vol.volatility( - referenceDate + atm.tenors.options[0], - atm.tenors.swaps[0], dummyStrike, false); - // testing evaluation date change ... - Settings.setEvaluationDate(referenceDate - new Period(1, TimeUnit.Years)); - double newVol = vol.volatility( - referenceDate + atm.tenors.options[0], - atm.tenors.swaps[0], dummyStrike, false); - - Settings.setEvaluationDate(referenceDate); - if (referenceDateFloating && (initialVol == newVol)) - QAssert.Fail(description + - " the volatility should change when the reference date is changed !"); - if (!referenceDateFloating && (initialVol != newVol)) - QAssert.Fail(description + - " the volatility should not change when the reference date is changed !"); - // test market data change... - if (mktDataFloating) - { - double initialVolatility = atm.volsHandle[0][0].link.value(); - - SimpleQuote sq=(SimpleQuote)(atm.volsHandle[0][0].currentLink()); - sq.setValue(10); - - newVol = vol.volatility(referenceDate + atm.tenors.options[0], - atm.tenors.swaps[0], dummyStrike, false); - sq.setValue(initialVolatility); - - if (initialVol == newVol) - QAssert.Fail(description + " the volatility should change when"+ - " the market data is changed !"); - } - } + BlackSwaptionEngine engine = new BlackSwaptionEngine( + termStructure, + new Handle(vol)); - public void makeCoherenceTest( string description, - SwaptionVolatilityDiscrete vol) + for (int j = 0; j < atm.tenors.swaps.Count; j++) { - - for (int i=0; i(vol)); - - for (int j=0; jtolerance) - QAssert.Fail( - "recovery of atm vols failed for " + - description + ":"+ - "\noption tenor = " + atm.tenors.options[i] + - "\n swap length = " + atm.tenors.swaps[j] + - "\nexpected vol = " + expVol + - "\n actual vol = " + actVol + - "\n error = " + error + - "\n tolerance = " + tolerance); - - Date optionDate = - vol.optionDateFromTenor(atm.tenors.options[i]); - actVol = vol.volatility(optionDate, - atm.tenors.swaps[j], 0.05, true); - error = Math.Abs(expVol-actVol); - if (error>tolerance) - QAssert.Fail( - "recovery of atm vols failed for " + - description + ":"+ - "\noption tenor: " + atm.tenors.options[i] + - "\noption date : " + optionDate + - "\n swap tenor: " + atm.tenors.swaps[j] + - "\n exp. vol: " + expVol + - "\n actual vol: " + actVol + - "\n error: " + error + - "\n tolerance: " + tolerance); - - double optionTime = vol.timeFromReference(optionDate); - actVol = vol.volatility(optionTime, swapLength, - 0.05, true); - error = Math.Abs(expVol-actVol); - if (error>tolerance) - QAssert.Fail( - "recovery of atm vols failed for " + - description + ":"+ - "\noption tenor: " + atm.tenors.options[i] + - "\noption time : " + optionTime + - "\n swap tenor: " + atm.tenors.swaps[j] + - "\n swap length: " + swapLength + - "\n exp. vol: " + expVol + - "\n actual vol: " + actVol + - "\n error: " + error + - "\n tolerance: " + tolerance); - - // ATM swaption - Swaption swaption = new MakeSwaption( - swapIndex, atm.tenors.options[i]) - .withPricingEngine(engine) - .value(); - - Date exerciseDate = swaption.exercise().dates().First(); - if (exerciseDate!=vol.optionDates()[i]) - QAssert.Fail( - "optionDateFromTenor mismatch for " + - description + ":"+ - "\n option tenor: " + atm.tenors.options[i] + - "\nactual option date: " + exerciseDate + - "\n exp. option date: " + vol.optionDates()[i]); - - Date start = swaption.underlyingSwap().startDate(); - Date end = swaption.underlyingSwap().maturityDate(); - double swapLength2 = vol.swapLength(start, end); - if (swapLength2!=swapLength) - QAssert.Fail( - "swapLength failure for " + - description + ":"+ - "\n swap tenor : " + atm.tenors.swaps[j] + - "\n actual swap length: " + swapLength2 + - "\n exp. swap length: " + swapLength); - - double npv = swaption.NPV(); - actVol = swaption.impliedVolatility(npv, termStructure, - expVol*0.98, 1e-6); - error = Math.Abs(expVol-actVol); - // TO BE FIXED - // double tolerance2 = 0.000001; - // if (error > tolerance2 & i != 0)//NOK for i=0 -> to debug - // QAssert.Fail( - // "recovery of atm vols through BlackSwaptionEngine failed for " + - // description + ":"+ - // "\noption tenor: " + atm.tenors.options[i] + - // "\noption time : " + optionTime + - // "\n swap tenor: " + atm.tenors.swaps[j] + - // "\n swap length: " + swapLength + - // "\n exp. vol: " + expVol + - // "\n actual vol: " + actVol + - // "\n error: " + error + - // "\n tolerance: " + tolerance2); - } - } + double swapLength = vol.swapLength(atm.tenors.swaps[j]); + + if (swapLength != atm.tenors.swaps[j].length()) + QAssert.Fail("convertSwapTenor failure for " + + description + ":" + + "\n swap tenor : " + atm.tenors.swaps[j] + + "\n actual swap length: " + swapLength + + "\n exp. swap length: " + atm.tenors.swaps[j].length()); + + SwapIndex swapIndex = new EuriborSwapIsdaFixA(atm.tenors.swaps[j], termStructure); + + for (int i = 0; i < atm.tenors.options.Count; ++i) + { + double error, tolerance = 1.0e-16; + double actVol, expVol = atm.vols[i, j]; + + actVol = vol.volatility(atm.tenors.options[i], + atm.tenors.swaps[j], 0.05, true); + error = Math.Abs(expVol - actVol); + if (error > tolerance) + QAssert.Fail( + "recovery of atm vols failed for " + + description + ":" + + "\noption tenor = " + atm.tenors.options[i] + + "\n swap length = " + atm.tenors.swaps[j] + + "\nexpected vol = " + expVol + + "\n actual vol = " + actVol + + "\n error = " + error + + "\n tolerance = " + tolerance); + + Date optionDate = + vol.optionDateFromTenor(atm.tenors.options[i]); + actVol = vol.volatility(optionDate, + atm.tenors.swaps[j], 0.05, true); + error = Math.Abs(expVol - actVol); + if (error > tolerance) + QAssert.Fail( + "recovery of atm vols failed for " + + description + ":" + + "\noption tenor: " + atm.tenors.options[i] + + "\noption date : " + optionDate + + "\n swap tenor: " + atm.tenors.swaps[j] + + "\n exp. vol: " + expVol + + "\n actual vol: " + actVol + + "\n error: " + error + + "\n tolerance: " + tolerance); + + double optionTime = vol.timeFromReference(optionDate); + actVol = vol.volatility(optionTime, swapLength, + 0.05, true); + error = Math.Abs(expVol - actVol); + if (error > tolerance) + QAssert.Fail( + "recovery of atm vols failed for " + + description + ":" + + "\noption tenor: " + atm.tenors.options[i] + + "\noption time : " + optionTime + + "\n swap tenor: " + atm.tenors.swaps[j] + + "\n swap length: " + swapLength + + "\n exp. vol: " + expVol + + "\n actual vol: " + actVol + + "\n error: " + error + + "\n tolerance: " + tolerance); + + // ATM swaption + Swaption swaption = new MakeSwaption( + swapIndex, atm.tenors.options[i]) + .withPricingEngine(engine) + .value(); + + Date exerciseDate = swaption.exercise().dates().First(); + if (exerciseDate != vol.optionDates()[i]) + QAssert.Fail( + "optionDateFromTenor mismatch for " + + description + ":" + + "\n option tenor: " + atm.tenors.options[i] + + "\nactual option date: " + exerciseDate + + "\n exp. option date: " + vol.optionDates()[i]); + + Date start = swaption.underlyingSwap().startDate(); + Date end = swaption.underlyingSwap().maturityDate(); + double swapLength2 = vol.swapLength(start, end); + if (swapLength2 != swapLength) + QAssert.Fail( + "swapLength failure for " + + description + ":" + + "\n swap tenor : " + atm.tenors.swaps[j] + + "\n actual swap length: " + swapLength2 + + "\n exp. swap length: " + swapLength); + + double npv = swaption.NPV(); + actVol = swaption.impliedVolatility(npv, termStructure, + expVol * 0.98, 1e-6); + error = Math.Abs(expVol - actVol); + // TO BE FIXED + // double tolerance2 = 0.000001; + // if (error > tolerance2 & i != 0)//NOK for i=0 -> to debug + // QAssert.Fail( + // "recovery of atm vols through BlackSwaptionEngine failed for " + + // description + ":"+ + // "\noption tenor: " + atm.tenors.options[i] + + // "\noption time : " + optionTime + + // "\n swap tenor: " + atm.tenors.swaps[j] + + // "\n swap length: " + swapLength + + // "\n exp. vol: " + expVol + + // "\n actual vol: " + actVol + + // "\n error: " + error + + // "\n tolerance: " + tolerance2); + } } - } + } + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testSwaptionVolMatrixCoherence() - { - // Testing swaption volatility matrix - CommonVars vars = new CommonVars(); - - SwaptionVolatilityMatrix vol; - string description; - - //floating reference date, floating market data - description = "floating reference date, floating market data"; - vol = new SwaptionVolatilityMatrix(vars.conventions.calendar, - vars.conventions.optionBdc, - vars.atm.tenors.options, - vars.atm.tenors.swaps, - vars.atm.volsHandle, - vars.conventions.dayCounter); - - vars.makeCoherenceTest(description, vol); - - //fixed reference date, floating market data - description = "fixed reference date, floating market data"; - vol = new SwaptionVolatilityMatrix(Settings.evaluationDate(), - vars.conventions.calendar, - vars.conventions.optionBdc, - vars.atm.tenors.options, - vars.atm.tenors.swaps, - vars.atm.volsHandle, - vars.conventions.dayCounter); - - vars.makeCoherenceTest(description, vol); - - // floating reference date, fixed market data - description = "floating reference date, fixed market data"; - vol = new SwaptionVolatilityMatrix(vars.conventions.calendar, - vars.conventions.optionBdc, - vars.atm.tenors.options, - vars.atm.tenors.swaps, - vars.atm.volsHandle, - vars.conventions.dayCounter); - - vars.makeCoherenceTest(description, vol); - - // fixed reference date, fixed market data - description = "fixed reference date, fixed market data"; - vol = new SwaptionVolatilityMatrix(Settings.evaluationDate(), - vars.conventions.calendar, - vars.conventions.optionBdc, - vars.atm.tenors.options, - vars.atm.tenors.swaps, - vars.atm.volsHandle, - vars.conventions.dayCounter); - - vars.makeCoherenceTest(description, vol); - } + public void testSwaptionVolMatrixCoherence() + { + // Testing swaption volatility matrix + CommonVars vars = new CommonVars(); + + SwaptionVolatilityMatrix vol; + string description; + + //floating reference date, floating market data + description = "floating reference date, floating market data"; + vol = new SwaptionVolatilityMatrix(vars.conventions.calendar, + vars.conventions.optionBdc, + vars.atm.tenors.options, + vars.atm.tenors.swaps, + vars.atm.volsHandle, + vars.conventions.dayCounter); + + vars.makeCoherenceTest(description, vol); + + //fixed reference date, floating market data + description = "fixed reference date, floating market data"; + vol = new SwaptionVolatilityMatrix(Settings.evaluationDate(), + vars.conventions.calendar, + vars.conventions.optionBdc, + vars.atm.tenors.options, + vars.atm.tenors.swaps, + vars.atm.volsHandle, + vars.conventions.dayCounter); + + vars.makeCoherenceTest(description, vol); + + // floating reference date, fixed market data + description = "floating reference date, fixed market data"; + vol = new SwaptionVolatilityMatrix(vars.conventions.calendar, + vars.conventions.optionBdc, + vars.atm.tenors.options, + vars.atm.tenors.swaps, + vars.atm.volsHandle, + vars.conventions.dayCounter); + + vars.makeCoherenceTest(description, vol); + + // fixed reference date, fixed market data + description = "fixed reference date, fixed market data"; + vol = new SwaptionVolatilityMatrix(Settings.evaluationDate(), + vars.conventions.calendar, + vars.conventions.optionBdc, + vars.atm.tenors.options, + vars.atm.tenors.swaps, + vars.atm.volsHandle, + vars.conventions.dayCounter); + + vars.makeCoherenceTest(description, vol); + } #if NET40 || NET45 - [TestMethod()] + [TestMethod()] #else - [Fact] + [Fact] #endif - public void testSwaptionVolMatrixObservability() - { - // Testing swaption volatility matrix observability - CommonVars vars=new CommonVars(); - - SwaptionVolatilityMatrix vol; - string description; - - //floating reference date, floating market data - description = "floating reference date, floating market data"; - vol = new SwaptionVolatilityMatrix( vars.conventions.calendar, - vars.conventions.optionBdc, - vars.atm.tenors.options, - vars.atm.tenors.swaps, - vars.atm.volsHandle, - vars.conventions.dayCounter); - - vars.makeObservabilityTest(description, vol, true, true); - - //fixed reference date, floating market data - description = "fixed reference date, floating market data"; - vol = new SwaptionVolatilityMatrix( Settings.evaluationDate(), - vars.conventions.calendar, - vars.conventions.optionBdc, - vars.atm.tenors.options, - vars.atm.tenors.swaps, - vars.atm.volsHandle, - vars.conventions.dayCounter); - vars.makeObservabilityTest(description, vol, true, false); - - // floating reference date, fixed market data - description = "floating reference date, fixed market data"; - vol = new SwaptionVolatilityMatrix( vars.conventions.calendar, - vars.conventions.optionBdc, - vars.atm.tenors.options, - vars.atm.tenors.swaps, - vars.atm.volsHandle, - vars.conventions.dayCounter); - vars.makeObservabilityTest(description, vol, false, true); - - // fixed reference date, fixed market data - description = "fixed reference date, fixed market data"; - vol = new SwaptionVolatilityMatrix( Settings.evaluationDate(), - vars.conventions.calendar, - vars.conventions.optionBdc, - vars.atm.tenors.options, - vars.atm.tenors.swaps, - vars.atm.volsHandle, - vars.conventions.dayCounter); - vars.makeObservabilityTest(description, vol, false, false); - - // fixed reference date and fixed market data, option dates - //SwaptionVolatilityMatrix(const Date& referenceDate, - // const std::vector& exerciseDates, - // const std::vector& swapTenors, - // const Matrix& volatilities, - // const DayCounter& dayCounter); - } - } + public void testSwaptionVolMatrixObservability() + { + // Testing swaption volatility matrix observability + CommonVars vars = new CommonVars(); + + SwaptionVolatilityMatrix vol; + string description; + + //floating reference date, floating market data + description = "floating reference date, floating market data"; + vol = new SwaptionVolatilityMatrix(vars.conventions.calendar, + vars.conventions.optionBdc, + vars.atm.tenors.options, + vars.atm.tenors.swaps, + vars.atm.volsHandle, + vars.conventions.dayCounter); + + vars.makeObservabilityTest(description, vol, true, true); + + //fixed reference date, floating market data + description = "fixed reference date, floating market data"; + vol = new SwaptionVolatilityMatrix(Settings.evaluationDate(), + vars.conventions.calendar, + vars.conventions.optionBdc, + vars.atm.tenors.options, + vars.atm.tenors.swaps, + vars.atm.volsHandle, + vars.conventions.dayCounter); + vars.makeObservabilityTest(description, vol, true, false); + + // floating reference date, fixed market data + description = "floating reference date, fixed market data"; + vol = new SwaptionVolatilityMatrix(vars.conventions.calendar, + vars.conventions.optionBdc, + vars.atm.tenors.options, + vars.atm.tenors.swaps, + vars.atm.volsHandle, + vars.conventions.dayCounter); + vars.makeObservabilityTest(description, vol, false, true); + + // fixed reference date, fixed market data + description = "fixed reference date, fixed market data"; + vol = new SwaptionVolatilityMatrix(Settings.evaluationDate(), + vars.conventions.calendar, + vars.conventions.optionBdc, + vars.atm.tenors.options, + vars.atm.tenors.swaps, + vars.atm.volsHandle, + vars.conventions.dayCounter); + vars.makeObservabilityTest(description, vol, false, false); + + // fixed reference date and fixed market data, option dates + //SwaptionVolatilityMatrix(const Date& referenceDate, + // const std::vector& exerciseDates, + // const std::vector& swapTenors, + // const Matrix& volatilities, + // const DayCounter& dayCounter); + } + } } diff --git a/tests/QLNet.Tests/T_TermStructures.cs b/tests/QLNet.Tests/T_TermStructures.cs index 883202542..744793a42 100644 --- a/tests/QLNet.Tests/T_TermStructures.cs +++ b/tests/QLNet.Tests/T_TermStructures.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -20,48 +20,63 @@ under the terms of the QLNet license. You should have received a using System; using System.Collections.Generic; + #if NET40 || NET45 + using Microsoft.VisualStudio.TestTools.UnitTesting; + #else - using Xunit; +using Xunit; #endif + using QLNet; namespace TestSuite { #if NET40 || NET45 + [TestClass()] #endif public class T_TermStructures : IDisposable { + private double sub(double x, double y) + { return x - y; } + #region Initialize&Cleanup + private SavedSettings backup; - #if NET40 || NET45 +#if NET40 || NET45 + [TestInitialize] public void testInitialize() { - #else +#else public T_TermStructures() { - #endif +#endif backup = new SavedSettings(); } - #if NET40 || NET45 + +#if NET40 || NET45 + [TestCleanup] - #endif +#endif public void testCleanup() { Dispose(); } + public void Dispose() { backup.Dispose(); } - #endregion + + #endregion Initialize&Cleanup public class CommonVars { #region Values + public struct Datum { public int n; @@ -69,25 +84,29 @@ public struct Datum public double rate; } - public Datum[] depositData = new Datum[] { - new Datum { n = 1, units = TimeUnit.Months, rate = 4.581 }, - new Datum { n = 2, units = TimeUnit.Months, rate = 4.573 }, - new Datum { n = 3, units = TimeUnit.Months, rate = 4.557 }, - new Datum { n = 6, units = TimeUnit.Months, rate = 4.496 }, - new Datum { n = 9, units = TimeUnit.Months, rate = 4.490 } - }; + public Datum[] depositData = new Datum[] + { + new Datum { n = 1, units = TimeUnit.Months, rate = 4.581 }, + new Datum { n = 2, units = TimeUnit.Months, rate = 4.573 }, + new Datum { n = 3, units = TimeUnit.Months, rate = 4.557 }, + new Datum { n = 6, units = TimeUnit.Months, rate = 4.496 }, + new Datum { n = 9, units = TimeUnit.Months, rate = 4.490 } + }; - public Datum[] swapData = new Datum[] { - new Datum { n = 1, units = TimeUnit.Years, rate = 4.54 }, - new Datum { n = 5, units = TimeUnit.Years, rate = 4.99 }, - new Datum { n = 10, units = TimeUnit.Years, rate = 5.47 }, - new Datum { n = 20, units = TimeUnit.Years, rate = 5.89 }, - new Datum { n = 30, units = TimeUnit.Years, rate = 5.96 } - }; - #endregion + public Datum[] swapData = new Datum[] + { + new Datum { n = 1, units = TimeUnit.Years, rate = 4.54 }, + new Datum { n = 5, units = TimeUnit.Years, rate = 4.99 }, + new Datum { n = 10, units = TimeUnit.Years, rate = 5.47 }, + new Datum { n = 20, units = TimeUnit.Years, rate = 5.89 }, + new Datum { n = 30, units = TimeUnit.Years, rate = 5.96 } + }; + + #endregion Values // common data public Calendar calendar; + public int settlementDays; public YieldTermStructure termStructure; public YieldTermStructure dummyTermStructure; @@ -108,7 +127,7 @@ public CommonVars() for (int i = 0; i < deposits; i++) { instruments.Add(new DepositRateHelper(depositData[i].rate / 100, new Period(depositData[i].n, depositData[i].units), - settlementDays, calendar, BusinessDayConvention.ModifiedFollowing, true, new Actual360())); + settlementDays, calendar, BusinessDayConvention.ModifiedFollowing, true, new Actual360())); } IborIndex index = new IborIndex("dummy", new Period(6, TimeUnit.Months), settlementDays, new Currency(), @@ -116,7 +135,7 @@ public CommonVars() for (int i = 0; i < swaps; ++i) { instruments.Add(new SwapRateHelper(swapData[i].rate / 100, new Period(swapData[i].n, swapData[i].units), - calendar, Frequency.Annual, BusinessDayConvention.Unadjusted, new Thirty360(), index)); + calendar, Frequency.Annual, BusinessDayConvention.Unadjusted, new Thirty360(), index)); } termStructure = new PiecewiseYieldCurve(settlement, instruments, new Actual360()); dummyTermStructure = new PiecewiseYieldCurve(settlement, instruments, new Actual360()); @@ -124,9 +143,10 @@ public CommonVars() } #if NET40 || NET45 - [TestMethod()] + + [TestMethod()] #else - [Fact] + [Fact] #endif public void testReferenceChange() { @@ -154,15 +174,16 @@ public void testReferenceChange() { if (!Utils.close(expected[i], calculated[i])) QAssert.Fail("\n Discount at " + days[i] + " days:\n" - + " before date change: " + expected[i] + "\n" - + " after date change: " + calculated[i]); + + " before date change: " + expected[i] + "\n" + + " after date change: " + calculated[i]); } } #if NET40 || NET45 - [TestMethod()] + + [TestMethod()] #else - [Fact] + [Fact] #endif public void testImplied() { @@ -180,14 +201,15 @@ public void testImplied() double impliedDiscount = implied.discount(testDate); if (Math.Abs(discount - baseDiscount * impliedDiscount) > tolerance) QAssert.Fail("unable to reproduce discount from implied curve\n" - + " calculated: " + baseDiscount * impliedDiscount + "\n" - + " expected: " + discount); + + " calculated: " + baseDiscount * impliedDiscount + "\n" + + " expected: " + discount); } #if NET40 || NET45 - [TestMethod()] + + [TestMethod()] #else - [Fact] + [Fact] #endif public void testImpliedObs() { @@ -207,9 +229,10 @@ public void testImpliedObs() } #if NET40 || NET45 - [TestMethod()] + + [TestMethod()] #else - [Fact] + [Fact] #endif public void testFSpreaded() { @@ -226,18 +249,19 @@ public void testFSpreaded() double forward = vars.termStructure.forwardRate(testDate, testDate, tsdc, Compounding.Continuous, Frequency.NoFrequency).rate(); double spreadedForward = spreaded.forwardRate(testDate, testDate, sprdc, Compounding.Continuous, - Frequency.NoFrequency).rate(); + Frequency.NoFrequency).rate(); if (Math.Abs(forward - (spreadedForward - me.value())) > tolerance) QAssert.Fail("unable to reproduce forward from spreaded curve\n" - + " calculated: " - + (spreadedForward - me.value()) + "\n" - + " expected: " + forward); + + " calculated: " + + (spreadedForward - me.value()) + "\n" + + " expected: " + forward); } #if NET40 || NET45 - [TestMethod()] + + [TestMethod()] #else - [Fact] + [Fact] #endif public void testFSpreadedObs() { @@ -260,9 +284,10 @@ public void testFSpreadedObs() } #if NET40 || NET45 - [TestMethod()] + + [TestMethod()] #else - [Fact] + [Fact] #endif public void testZSpreaded() { @@ -279,14 +304,15 @@ public void testZSpreaded() double spreadedZero = spreaded.zeroRate(testDate, rfdc, Compounding.Continuous, Frequency.NoFrequency).rate(); if (Math.Abs(zero - (spreadedZero - me.value())) > tolerance) QAssert.Fail("unable to reproduce zero yield from spreaded curve\n" - + " calculated: " + (spreadedZero - me.value()) + "\n" - + " expected: " + zero); + + " calculated: " + (spreadedZero - me.value()) + "\n" + + " expected: " + zero); } #if NET40 || NET45 - [TestMethod()] + + [TestMethod()] #else - [Fact] + [Fact] #endif public void testZSpreadedObs() { @@ -310,60 +336,194 @@ public void testZSpreadedObs() } #if NET40 || NET45 - [TestMethod()] + + [TestMethod()] +#else + [Fact] +#endif + public void testCompositeZeroYieldStructures() + { + // Testing composite zero yield structures... + + Settings.setEvaluationDate(new Date(10, Month.Nov, 2017)); + + // First curve + var dates = new List + { + new Date(10, Month.Nov, 2017), + new Date(13, Month.Nov, 2017), + new Date(12, Month.Feb, 2018), + new Date(10, Month.May, 2018), + new Date(10, Month.Aug, 2018), + new Date(12, Month.Nov, 2018), + new Date(21, Month.Dec, 2018), + new Date(15, Month.Jan, 2020), + new Date(31, Month.Mar, 2021), + new Date(28, Month.Feb, 2023), + new Date(21, Month.Dec, 2026), + new Date(31, Month.Jan, 2030), + new Date(28, Month.Feb, 2031), + new Date(31, Month.Mar, 2036), + new Date(28, Month.Feb, 2041), + new Date(28, Month.Feb, 2048), + new Date(31, Month.Dec, 2141) + }; + + var rates = new List + { + 0.0655823213132524, + 0.0655823213132524, + 0.0699455024156877, + 0.0799107139233497, + 0.0813931951022577, + 0.0841615820666691, + 0.0501297919004145, + 0.0823483583439658, + 0.0860720030924466, + 0.0922887604375688, + 0.10588902278996, + 0.117021968693922, + 0.109824660896137, + 0.109231572878364, + 0.119218123236241, + 0.128647300167664, + 0.0506086995288751 + }; + + var termStructure1 = new InterpolatedForwardCurve(dates, rates, new Actual365Fixed(), new NullCalendar()); + + // Second curve + dates = new List(); + rates = new List(); + + dates.Add(new Date(10, Month.Nov, 2017)); + dates.Add(new Date(13, Month.Nov, 2017)); + dates.Add(new Date(11, Month.Dec, 2017)); + dates.Add(new Date(12, Month.Feb, 2018)); + dates.Add(new Date(10, Month.May, 2018)); + dates.Add(new Date(31, Month.Jan, 2022)); + dates.Add(new Date(7, Month.Dec, 2023)); + dates.Add(new Date(31, Month.Jan, 2025)); + dates.Add(new Date(31, Month.Mar, 2028)); + dates.Add(new Date(7, Month.Dec, 2033)); + dates.Add(new Date(1, Month.Feb, 2038)); + dates.Add(new Date(2, Month.Apr, 2046)); + dates.Add(new Date(2, Month.Jan, 2051)); + dates.Add(new Date(31, Month.Dec, 2141)); + + rates.Add(0.056656806197189); + rates.Add(0.056656806197189); + rates.Add(0.0419541633454473); + rates.Add(0.0286681050019797); + rates.Add(0.0148840226959593); + rates.Add(0.0246680238374363); + rates.Add(0.0255349067810599); + rates.Add(0.0298907184711927); + rates.Add(0.0263943927922053); + rates.Add(0.0291924526539802); + rates.Add(0.0270049276163556); + rates.Add(0.028775807327614); + rates.Add(0.0293567711641792); + rates.Add(0.010518655099659); + + var termStructure2 = new InterpolatedForwardCurve(dates, rates, new Actual365Fixed(), new NullCalendar()); + + var compoundCurve = new CompositeZeroYieldStructure + ( + new Handle(termStructure1), + new Handle(termStructure2), + sub + ); + + // Expected values + dates = new List(); + rates = new List(); + + dates.Add(new Date(10, Month.Nov, 2017)); + dates.Add(new Date(15, Month.Dec, 2017)); + dates.Add(new Date(15, Month.Jun, 2018)); + dates.Add(new Date(15, Month.Sep, 2029)); + dates.Add(new Date(15, Month.Sep, 2038)); + dates.Add(new Date(15, Month.Mar, 2046)); + dates.Add(new Date(15, Month.Dec, 2141)); + + rates.Add(0.00892551511527986); + rates.Add(0.0278755322562788); + rates.Add(0.0512001768603456); + rates.Add(0.0729941474263546); + rates.Add(0.0778333309498459); + rates.Add(0.0828451659139004); + rates.Add(0.0503573807521742); + + double tolerance = 1.0e-10; + for (var i = 0; i < dates.Count; ++i) + { + double actual = compoundCurve.zeroRate(dates[i], new Actual365Fixed(), Compounding.Continuous).rate(); + double expected = rates[i]; + + QAssert.IsTrue(Math.Abs(actual - expected) <= tolerance, + "unable to reproduce zero yield rate from composite input curve\n" + + " calculated: " + actual + "\n" + + " expected: " + expected); + } + } + +#if NET40 || NET45 + + [TestMethod()] #else - [Fact] + [Fact] #endif public void testInterpolatedZeroCurveWithRefDateAndTenorDates() { CommonVars vars = new CommonVars(); // Create the interpolated curve - var refDate = new Date( 1, 10, 2015 ); + var refDate = new Date(1, 10, 2015); var dates = new List() { new Date(30, 12, 2015), - new Date(30, 3, 2016), - new Date(30, 9, 2016), - new Date(29, 9, 2017), - new Date(28, 9, 2018), - new Date(30, 9, 2019), - new Date(30, 9, 2020), - new Date(30, 9, 2021), - new Date(30, 9, 2022), - new Date(29, 9, 2023), - new Date(30, 9, 2024), - new Date(30, 9, 2025), - new Date(30, 9, 2030), - new Date(28, 9, 2035), - new Date(29, 9, 2045), + new Date(30, 3, 2016), + new Date(30, 9, 2016), + new Date(29, 9, 2017), + new Date(28, 9, 2018), + new Date(30, 9, 2019), + new Date(30, 9, 2020), + new Date(30, 9, 2021), + new Date(30, 9, 2022), + new Date(29, 9, 2023), + new Date(30, 9, 2024), + new Date(30, 9, 2025), + new Date(30, 9, 2030), + new Date(28, 9, 2035), + new Date(29, 9, 2045), }; var yields = new List() { -0.002558362, - -0.002478462, - -0.00248845, - -0.002498437, - -0.00196903, - -0.001219628, - -0.000209989, - 0.000940221, - 0.00220121, - 0.003493045, - 0.004785712, - 0.00602906, - 0.010909594, - 0.013132837, - 0.01403893 - }; + -0.002478462, + -0.00248845, + -0.002498437, + -0.00196903, + -0.001219628, + -0.000209989, + 0.000940221, + 0.00220121, + 0.003493045, + 0.004785712, + 0.00602906, + 0.010909594, + 0.013132837, + 0.01403893 + }; - var curve = new InterpolatedZeroCurve( dates, - yields, - new ActualActual( ActualActual.Convention.ISMA ), - new Linear(), - Compounding.Continuous, - Frequency.Annual, refDate ); + var curve = new InterpolatedZeroCurve(dates, + yields, + new ActualActual(ActualActual.Convention.ISMA), + new Linear(), + Compounding.Continuous, + Frequency.Annual, refDate); Dictionary tenors2 = new Dictionary { @@ -387,12 +547,12 @@ public void testInterpolatedZeroCurveWithRefDateAndTenorDates() // Make sure the points come back as expected var tenors = new[] { 0.25, 0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 15.0, 20.0, 30.0 }; - for ( int i = 0; i < tenors.Length; i++ ) + for (int i = 0; i < tenors.Length; i++) { - var test = curve.interpolation_.value( tenors[i],true ); - QAssert.AreEqual( yields[i], test ); + var test = curve.interpolation_.value(tenors[i], true); + QAssert.AreEqual(yields[i], test); } - QAssert.AreNotEqual( yields[0], curve.interpolation_.value( 0.0,true ) ); - } + QAssert.AreNotEqual(yields[0], curve.interpolation_.value(0.0, true)); + } } } diff --git a/tests/QLNet.Tests/T_Vector.cs b/tests/QLNet.Tests/T_Vector.cs index d47d6a599..ddd4285c8 100644 --- a/tests/QLNet.Tests/T_Vector.cs +++ b/tests/QLNet.Tests/T_Vector.cs @@ -1,15 +1,15 @@ // Copyright (C) 2008-2017 Andrea Maggiulli (a.maggiulli@gmail.com) -// +// // This file is part of QLNet Project https://github.com/amaggiulli/qlnet // QLNet is free software: you can redistribute it and/or modify it // under the terms of the QLNet license. You should have received a -// copy of the license along with this program; if not, license is -// available online at . -// +// copy of the license along with this program; if not, license is +// available at . +// // QLNet is a based on QuantLib, a free-software/open-source library // for financial quantitative analysts and developers - http://quantlib.org/ // The QuantLib license is available online at http://quantlib.org/license.shtml. -// +// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the license for more details. @@ -18,7 +18,7 @@ #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; @@ -32,16 +32,16 @@ public class T_Vector /// /// Sample values. /// - protected readonly List Data = new List(){ 1, 2, 3, 4, 5 }; + protected readonly List Data = new List() { 1, 2, 3, 4, 5 }; /// /// Test vector clone /// - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif public void testClone() { Vector vector = new Vector(Data); @@ -58,11 +58,11 @@ public void testClone() /// /// Test clone a vector using IClonable interface method. /// - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif public void testCloneICloneable() { Vector vector = new Vector(Data); @@ -78,11 +78,11 @@ public void testCloneICloneable() /// /// Test vectors equality. /// - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif public void testEquals() { Vector vector1 = new Vector(Data); @@ -98,17 +98,17 @@ public void testEquals() /// /// Test Vector hash code. /// - #if NET40 || NET45 - [TestMethod()] - #else - [Fact] - #endif +#if NET40 || NET45 + [TestMethod()] +#else + [Fact] +#endif public void testHashCode() { Vector vector = new Vector(Data); QAssert.AreEqual(vector.GetHashCode(), vector.GetHashCode()); - QAssert.AreEqual(vector.GetHashCode(), - new Vector(new List() { 1, 2, 3, 4,5 }).GetHashCode()); + QAssert.AreEqual(vector.GetHashCode(), + new Vector(new List() { 1, 2, 3, 4, 5 }).GetHashCode()); QAssert.AreNotEqual(vector.GetHashCode(), new Vector(new List() { 1 }).GetHashCode()); } } diff --git a/tests/QLNet.Tests/Utilities.cs b/tests/QLNet.Tests/Utilities.cs index a8c1b1a86..6abcaee1f 100644 --- a/tests/QLNet.Tests/Utilities.cs +++ b/tests/QLNet.Tests/Utilities.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2016 Andrea Maggiulli (a.maggiulli@gmail.com) - + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - + copy of the license along with this program; if not, license is + available at . + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -25,259 +25,269 @@ under the terms of the QLNet license. You should have received a #if NET40 || NET45 using Microsoft.VisualStudio.TestTools.UnitTesting; #else - using Xunit; +using Xunit; #endif using QLNet; -namespace TestSuite { - public class Flag : IObserver { - private bool up_; - - public Flag() { - up_ = false; - } - - public void raise() { up_ = true; } - public void lower() { up_ = false; } - public bool isUp() { return up_; } - public void update() { raise(); } - }; - - public static class Utilities { - public static YieldTermStructure flatRate(Date today, double forward, DayCounter dc) { - return new FlatForward(today, new SimpleQuote(forward), dc); - } - - public static YieldTermStructure flatRate(Date today, Quote forward, DayCounter dc) { - return new FlatForward(today, forward, dc); - } - - //philippe2009_17 - public static YieldTermStructure flatRate(double forward, DayCounter dc) - { - return flatRate(new SimpleQuote(forward), dc); - } - - public static YieldTermStructure flatRate(Quote forward, DayCounter dc) - { - return new FlatForward(0, new NullCalendar(), forward, dc); - } - - public static BlackVolTermStructure flatVol(Date today, double vol, DayCounter dc) { - return flatVol(today, new SimpleQuote(vol), dc); - } - - public static BlackVolTermStructure flatVol(Date today, Quote vol, DayCounter dc) { - return new BlackConstantVol(today, new NullCalendar(), new Handle(vol), dc); - } - //philippe2009_17 - public static BlackVolTermStructure flatVol(Quote vol, DayCounter dc) - { - return new BlackConstantVol(0, new NullCalendar(), new Handle(vol), dc); - } - - public static BlackVolTermStructure flatVol(double vol, DayCounter dc) - { - return flatVol(new SimpleQuote(vol), dc); - } - - public static double norm(Vector v, int size, double h) { - // squared values - List f2 = new InitializedList(size); - - for (int i = 0; i < v.Count; i++) - f2[i] = v[i] * v[i]; - - // numeric integral of f^2 - double I = h * (f2.Sum() - 0.5 * f2.First() - 0.5 * f2.Last()); - return Math.Sqrt(I); - } - - public static double relativeError(double x1, double x2, double reference) { - if (reference.IsNotEqual(0.0)) - return Math.Abs(x1 - x2) / reference; - else - // fall back to absolute error - return Math.Abs(x1 - x2); - } - - public static String exerciseTypeToString(Exercise h) - { - object hd = null; - - hd = h as EuropeanExercise; - if (hd != null) - return "European"; - - hd = h as AmericanExercise; - if ( hd != null ) - return "American"; - - hd = h as BermudanExercise; - if ( hd != null ) - return "Bermudan"; - - Utils.QL_FAIL("unknown exercise type"); - return String.Empty; - } - - public static String payoffTypeToString(Payoff h) - { - object hd = null; - hd = h as PlainVanillaPayoff; - if (hd != null) - return "plain-vanilla"; - hd = h as CashOrNothingPayoff; - if (hd != null) - return "cash-or-nothing"; - hd = h as AssetOrNothingPayoff; - if (hd != null) - return "asset-or-nothing"; - hd = h as SuperSharePayoff; - if (hd != null) - return "super-share"; - hd = h as SuperFundPayoff; - if (hd != null) - return "super-fund"; - hd = h as PercentageStrikePayoff; - if (hd != null) - return"percentage-strike"; - hd = h as GapPayoff; - if (hd != null) - return "gap"; - hd = h as FloatingTypePayoff; - if (hd != null) - return "floating-type"; - - Utils.QL_FAIL("unknown payoff type"); - return String.Empty; - } - } - - // this cleans up index-fixing histories when disposed - public class IndexHistoryCleaner : IDisposable - { - public void Dispose() { IndexManager.instance().clearHistories(); } - }; +namespace TestSuite +{ + public class Flag : IObserver + { + private bool up_; + + public Flag() + { + up_ = false; + } + + public void raise() { up_ = true; } + public void lower() { up_ = false; } + public bool isUp() { return up_; } + public void update() { raise(); } + } + + public static class Utilities + { + public static YieldTermStructure flatRate(Date today, double forward, DayCounter dc) + { + return new FlatForward(today, new SimpleQuote(forward), dc); + } + + public static YieldTermStructure flatRate(Date today, Quote forward, DayCounter dc) + { + return new FlatForward(today, forward, dc); + } + + //philippe2009_17 + public static YieldTermStructure flatRate(double forward, DayCounter dc) + { + return flatRate(new SimpleQuote(forward), dc); + } + + public static YieldTermStructure flatRate(Quote forward, DayCounter dc) + { + return new FlatForward(0, new NullCalendar(), forward, dc); + } + + public static BlackVolTermStructure flatVol(Date today, double vol, DayCounter dc) + { + return flatVol(today, new SimpleQuote(vol), dc); + } + + public static BlackVolTermStructure flatVol(Date today, Quote vol, DayCounter dc) + { + return new BlackConstantVol(today, new NullCalendar(), new Handle(vol), dc); + } + //philippe2009_17 + public static BlackVolTermStructure flatVol(Quote vol, DayCounter dc) + { + return new BlackConstantVol(0, new NullCalendar(), new Handle(vol), dc); + } + + public static BlackVolTermStructure flatVol(double vol, DayCounter dc) + { + return flatVol(new SimpleQuote(vol), dc); + } + + public static double norm(Vector v, int size, double h) + { + // squared values + List f2 = new InitializedList(size); + + for (int i = 0; i < v.Count; i++) + f2[i] = v[i] * v[i]; + + // numeric integral of f^2 + double I = h * (f2.Sum() - 0.5 * f2.First() - 0.5 * f2.Last()); + return Math.Sqrt(I); + } + + public static double relativeError(double x1, double x2, double reference) + { + if (reference.IsNotEqual(0.0)) + return Math.Abs(x1 - x2) / reference; + else + // fall back to absolute error + return Math.Abs(x1 - x2); + } + + public static String exerciseTypeToString(Exercise h) + { + object hd = null; + + hd = h as EuropeanExercise; + if (hd != null) + return "European"; + + hd = h as AmericanExercise; + if (hd != null) + return "American"; + + hd = h as BermudanExercise; + if (hd != null) + return "Bermudan"; + + Utils.QL_FAIL("unknown exercise type"); + return String.Empty; + } + + public static String payoffTypeToString(Payoff h) + { + object hd = null; + hd = h as PlainVanillaPayoff; + if (hd != null) + return "plain-vanilla"; + hd = h as CashOrNothingPayoff; + if (hd != null) + return "cash-or-nothing"; + hd = h as AssetOrNothingPayoff; + if (hd != null) + return "asset-or-nothing"; + hd = h as SuperSharePayoff; + if (hd != null) + return "super-share"; + hd = h as SuperFundPayoff; + if (hd != null) + return "super-fund"; + hd = h as PercentageStrikePayoff; + if (hd != null) + return"percentage-strike"; + hd = h as GapPayoff; + if (hd != null) + return "gap"; + hd = h as FloatingTypePayoff; + if (hd != null) + return "floating-type"; + + Utils.QL_FAIL("unknown payoff type"); + return String.Empty; + } + } + + // this cleans up index-fixing histories when disposed + public class IndexHistoryCleaner : IDisposable + { + public void Dispose() { IndexManager.instance().clearHistories(); } + } public static partial class QAssert { public static void CollectionAreEqual(ICollection expected, ICollection actual) { - #if NET40 || NET45 - CollectionAssert.AreEqual(expected, actual); - #else - Assert.AreEqual(expected,actual); - #endif +#if NET40 || NET45 + CollectionAssert.AreEqual(expected, actual); +#else + Assert.AreEqual(expected, actual); +#endif } public static void CollectionAreNotEqual(ICollection notExpected, ICollection actual) { - #if NET40 || NET45 - CollectionAssert.AreNotEqual(notExpected, actual); - #else - Assert.AreNotEqual(notExpected,actual); - #endif +#if NET40 || NET45 + CollectionAssert.AreNotEqual(notExpected, actual); +#else + Assert.AreNotEqual(notExpected, actual); +#endif } public static void AreNotSame(object notExpected, object actual) { - #if NET40 || NET45 - Assert.AreNotSame(notExpected, actual); - #else - Assert.NotSame(notExpected,actual); - #endif +#if NET40 || NET45 + Assert.AreNotSame(notExpected, actual); +#else + Assert.NotSame(notExpected, actual); +#endif } public static void Fail(string message) { - #if NET40 || NET45 - Assert.Fail(message); - #else - Assert.True(false,message); - #endif +#if NET40 || NET45 + Assert.Fail(message); +#else + Assert.True(false, message); +#endif } - public static void AreEqual( double expected, double actual, double delta ) + public static void AreEqual(double expected, double actual, double delta) { - #if NET40 || NET45 - Assert.AreEqual( expected, actual, delta ); - #else - Assert.True(Math.Abs(expected- actual) <= delta); - #endif +#if NET40 || NET45 + Assert.AreEqual(expected, actual, delta); +#else + Assert.True(Math.Abs(expected - actual) <= delta); +#endif } public static void AreEqual(double expected, double actual, double delta, string message) { - #if NET40 || NET45 - Assert.AreEqual(expected, actual, delta, message); - #else - Assert.True(Math.Abs(expected- actual) <= delta,message); - #endif +#if NET40 || NET45 + Assert.AreEqual(expected, actual, delta, message); +#else + Assert.True(Math.Abs(expected - actual) <= delta, message); +#endif } - public static void AreEqual( T expected, T actual ) + public static void AreEqual(T expected, T actual) { - - #if NET40 || NET45 - Assert.AreEqual( expected, actual ); - #else - Assert.Equal(expected, actual); - #endif + +#if NET40 || NET45 + Assert.AreEqual(expected, actual); +#else + Assert.Equal(expected, actual); +#endif } - public static void AreEqual( T expected, T actual, string message ) + public static void AreEqual(T expected, T actual, string message) { - #if NET40 || NET45 - Assert.AreEqual( expected, actual, message ); - #else - Assert.Equal(expected, actual); - #endif +#if NET40 || NET45 + Assert.AreEqual(expected, actual, message); +#else + Assert.Equal(expected, actual); +#endif } public static void AreNotEqual(T expected, T actual) { - #if NET40 || NET45 - Assert.AreNotEqual( expected, actual ); - #else - Assert.NotEqual(expected, actual); - #endif +#if NET40 || NET45 + Assert.AreNotEqual(expected, actual); +#else + Assert.NotEqual(expected, actual); +#endif } public static void IsTrue(bool condition) { - #if NET40 || NET45 - Assert.IsTrue(condition); - #else - Assert.True(condition); - #endif +#if NET40 || NET45 + Assert.IsTrue(condition); +#else + Assert.True(condition); +#endif } - public static void IsTrue( bool condition, string message ) + public static void IsTrue(bool condition, string message) { - #if NET40 || NET45 - Assert.IsTrue( condition, message); - #else - Assert.True( condition, message); - #endif +#if NET40 || NET45 + Assert.IsTrue(condition, message); +#else + Assert.True(condition, message); +#endif } public static void IsFalse(bool condition) { - #if NET40 || NET45 - Assert.IsFalse(condition); - #else - Assert.False( condition); - #endif +#if NET40 || NET45 + Assert.IsFalse(condition); +#else + Assert.False(condition); +#endif } - public static void IsFalse( bool condition, string message ) + public static void IsFalse(bool condition, string message) { - #if NET40 || NET45 - Assert.IsFalse( condition, message ); - #else - Assert.False( condition, message); - #endif +#if NET40 || NET45 + Assert.IsFalse(condition, message); +#else + Assert.False(condition, message); +#endif } //public static void IsTrue( bool condition, string message, params object[] parameters ) //{ @@ -303,104 +313,104 @@ public void setConventions() dayCounter = new Actual365Fixed(); } } - - public struct AtmVolatility + + public struct AtmVolatility { public SwaptionTenors tenors; public Matrix vols; public List > > volsHandle; - public void setMarketData() + public void setMarketData() { - tenors.options = new InitializedList(6); - tenors.options[0] = new Period(1, TimeUnit.Months); - tenors.options[1] = new Period(6, TimeUnit.Months); - tenors.options[2] = new Period(1, TimeUnit.Years); - tenors.options[3] = new Period(5, TimeUnit.Years); - tenors.options[4] = new Period(10, TimeUnit.Years); - tenors.options[5] = new Period(30, TimeUnit.Years); - tenors.swaps = new InitializedList(4); - tenors.swaps[0] = new Period(1, TimeUnit.Years); - tenors.swaps[1] = new Period(5, TimeUnit.Years); - tenors.swaps[2] = new Period(10, TimeUnit.Years); - tenors.swaps[3] = new Period(30, TimeUnit.Years); - vols = new Matrix(tenors.options.Count, tenors.swaps.Count); - vols[0,0]=0.1300; vols[0,1]=0.1560; vols[0,2]=0.1390; vols[0,3]=0.1220; - vols[1,0]=0.1440; vols[1,1]=0.1580; vols[1,2]=0.1460; vols[1,3]=0.1260; - vols[2,0]=0.1600; vols[2,1]=0.1590; vols[2,2]=0.1470; vols[2,3]=0.1290; - vols[3,0]=0.1640; vols[3,1]=0.1470; vols[3,2]=0.1370; vols[3,3]=0.1220; - vols[4,0]=0.1400; vols[4,1]=0.1300; vols[4,2]=0.1250; vols[4,3]=0.1100; - vols[5,0]=0.1130; vols[5,1]=0.1090; vols[5,2]=0.1070; vols[5,3]=0.0930; - volsHandle= new InitializedList>>(tenors.options.Count); - for (int i=0; i>(tenors.swaps.Count); - for (int j=0; j(new SimpleQuote(vols[i,j])); - } - } - } + tenors.options = new InitializedList(6); + tenors.options[0] = new Period(1, TimeUnit.Months); + tenors.options[1] = new Period(6, TimeUnit.Months); + tenors.options[2] = new Period(1, TimeUnit.Years); + tenors.options[3] = new Period(5, TimeUnit.Years); + tenors.options[4] = new Period(10, TimeUnit.Years); + tenors.options[5] = new Period(30, TimeUnit.Years); + tenors.swaps = new InitializedList(4); + tenors.swaps[0] = new Period(1, TimeUnit.Years); + tenors.swaps[1] = new Period(5, TimeUnit.Years); + tenors.swaps[2] = new Period(10, TimeUnit.Years); + tenors.swaps[3] = new Period(30, TimeUnit.Years); + vols = new Matrix(tenors.options.Count, tenors.swaps.Count); + vols[0, 0] = 0.1300; vols[0, 1] = 0.1560; vols[0, 2] = 0.1390; vols[0, 3] = 0.1220; + vols[1, 0] = 0.1440; vols[1, 1] = 0.1580; vols[1, 2] = 0.1460; vols[1, 3] = 0.1260; + vols[2, 0] = 0.1600; vols[2, 1] = 0.1590; vols[2, 2] = 0.1470; vols[2, 3] = 0.1290; + vols[3, 0] = 0.1640; vols[3, 1] = 0.1470; vols[3, 2] = 0.1370; vols[3, 3] = 0.1220; + vols[4, 0] = 0.1400; vols[4, 1] = 0.1300; vols[4, 2] = 0.1250; vols[4, 3] = 0.1100; + vols[5, 0] = 0.1130; vols[5, 1] = 0.1090; vols[5, 2] = 0.1070; vols[5, 3] = 0.0930; + volsHandle = new InitializedList>>(tenors.options.Count); + for (int i = 0; i < tenors.options.Count; i++) + { + volsHandle[i] = new InitializedList>(tenors.swaps.Count); + for (int j = 0; j < tenors.swaps.Count; j++) + // every handle must be reassigned, as the ones created by + // default are all linked together. + volsHandle[i][j] = new Handle(new SimpleQuote(vols[i, j])); + } + } + } - public struct VolatilityCube + public struct VolatilityCube { public SwaptionTenors tenors; public Matrix volSpreads; public List > > volSpreadsHandle; public List strikeSpreads; - public void setMarketData() + public void setMarketData() { - tenors.options=new InitializedList(3); + tenors.options = new InitializedList(3); tenors.options[0] = new Period(1, TimeUnit.Years); tenors.options[1] = new Period(10, TimeUnit.Years); tenors.options[2] = new Period(30, TimeUnit.Years); - tenors.swaps= new InitializedList(3); + tenors.swaps = new InitializedList(3); tenors.swaps[0] = new Period(2, TimeUnit.Years); tenors.swaps[1] = new Period(10, TimeUnit.Years); tenors.swaps[2] = new Period(30, TimeUnit.Years); - strikeSpreads=new InitializedList(5); + strikeSpreads = new InitializedList(5); strikeSpreads[0] = -0.020; strikeSpreads[1] = -0.005; strikeSpreads[2] = +0.000; strikeSpreads[3] = +0.005; strikeSpreads[4] = +0.020; - volSpreads = new Matrix(tenors.options.Count*tenors.swaps.Count, strikeSpreads.Count); - volSpreads[0,0] = 0.0599; volSpreads[0,1] = 0.0049; - volSpreads[0,2] = 0.0000; - volSpreads[0,3] =-0.0001; volSpreads[0,4] = 0.0127; - volSpreads[1,0] = 0.0729; volSpreads[1,1] = 0.0086; - volSpreads[1,2] = 0.0000; - volSpreads[1,3] =-0.0024; volSpreads[1,4] = 0.0098; - volSpreads[2,0] = 0.0738; volSpreads[2,1] = 0.0102; - volSpreads[2,2] = 0.0000; - volSpreads[2,3] =-0.0039; volSpreads[2,4] = 0.0065; - volSpreads[3,0] = 0.0465; volSpreads[3,1] = 0.0063; - volSpreads[3,2] = 0.0000; - volSpreads[3,3] =-0.0032; volSpreads[3,4] =-0.0010; - volSpreads[4,0] = 0.0558; volSpreads[4,1] = 0.0084; - volSpreads[4,2] = 0.0000; - volSpreads[4,3] =-0.0050; volSpreads[4,4] =-0.0057; - volSpreads[5,0] = 0.0576; volSpreads[5,1] = 0.0083; - volSpreads[5,2] = 0.0000; - volSpreads[5,3] =-0.0043; volSpreads[5,4] = -0.0014; - volSpreads[6,0] = 0.0437; volSpreads[6,1] = 0.0059; - volSpreads[6,2] = 0.0000; - volSpreads[6,3] =-0.0030; volSpreads[6,4] =-0.0006; - volSpreads[7,0] = 0.0533; volSpreads[7,1] = 0.0078; - volSpreads[7,2] = 0.0000; - volSpreads[7,3] =-0.0045; volSpreads[7,4] =-0.0046; - volSpreads[8,0] = 0.0545; volSpreads[8,1] = 0.0079; - volSpreads[8,2] = 0.0000; - volSpreads[8,3] =-0.0042; volSpreads[8,4] =-0.0020; - volSpreadsHandle = new InitializedList>>(tenors.options.Count*tenors.swaps.Count); - for (int i=0; i>>(tenors.options.Count * tenors.swaps.Count); + for (int i = 0; i < tenors.options.Count * tenors.swaps.Count; i++) { volSpreadsHandle[i] = new InitializedList>(strikeSpreads.Count); - for (int j=0; j(new SimpleQuote(volSpreads[i,j])); + volSpreadsHandle[i][j] = new Handle(new SimpleQuote(volSpreads[i, j])); } } } diff --git a/tools/AStyle.exe b/tools/AStyle.exe new file mode 100644 index 000000000..2dc842c25 Binary files /dev/null and b/tools/AStyle.exe differ